aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rwxr-xr-xarch/arm/Kconfig2101
-rw-r--r--arch/arm/Kconfig-nommu52
-rw-r--r--arch/arm/Kconfig.debug132
-rw-r--r--arch/arm/Makefile307
-rw-r--r--arch/arm/boot/.gitignore5
-rw-r--r--arch/arm/boot/Makefile119
-rw-r--r--arch/arm/boot/bootp/Makefile27
-rw-r--r--arch/arm/boot/bootp/bootp.lds30
-rw-r--r--arch/arm/boot/bootp/init.S88
-rw-r--r--arch/arm/boot/bootp/initrd.S6
-rw-r--r--arch/arm/boot/bootp/kernel.S6
-rw-r--r--arch/arm/boot/compressed/.gitignore7
-rw-r--r--arch/arm/boot/compressed/Makefile152
-rw-r--r--arch/arm/boot/compressed/big-endian.S13
-rw-r--r--arch/arm/boot/compressed/decompress.c50
-rw-r--r--arch/arm/boot/compressed/head-sa1100.S47
-rw-r--r--arch/arm/boot/compressed/head-shark.S139
-rw-r--r--arch/arm/boot/compressed/head-sharpsl.S150
-rw-r--r--arch/arm/boot/compressed/head-shmobile.S83
-rw-r--r--arch/arm/boot/compressed/head-vt8500.S46
-rw-r--r--arch/arm/boot/compressed/head-xscale.S41
-rw-r--r--arch/arm/boot/compressed/head.S1121
-rw-r--r--arch/arm/boot/compressed/ll_char_wr.S134
-rw-r--r--arch/arm/boot/compressed/misc.c194
-rw-r--r--arch/arm/boot/compressed/mmcif-sh7372.c88
-rw-r--r--arch/arm/boot/compressed/ofw-shark.c260
-rw-r--r--arch/arm/boot/compressed/piggy.gzip.S6
-rw-r--r--arch/arm/boot/compressed/piggy.lzma.S6
-rw-r--r--arch/arm/boot/compressed/piggy.lzo.S6
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in68
-rw-r--r--arch/arm/boot/install.sh52
-rw-r--r--arch/arm/common/Kconfig91
-rw-r--r--arch/arm/common/Makefile21
-rw-r--r--arch/arm/common/dmabounce.c559
-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.c522
-rw-r--r--arch/arm/common/icst.c100
-rw-r--r--arch/arm/common/it8152.c359
-rw-r--r--arch/arm/common/locomo.c914
-rw-r--r--arch/arm/common/pl330.c1965
-rw-r--r--arch/arm/common/sa1111.c1361
-rw-r--r--arch/arm/common/scoop.c283
-rw-r--r--arch/arm/common/sharpsl_param.c62
-rw-r--r--arch/arm/common/time-acorn.c95
-rw-r--r--arch/arm/common/timer-sp.c172
-rw-r--r--arch/arm/common/uengine.c507
-rw-r--r--arch/arm/common/via82c505.c92
-rw-r--r--arch/arm/common/vic.c379
-rw-r--r--arch/arm/configs/acs5k_defconfig86
-rw-r--r--arch/arm/configs/acs5k_tiny_defconfig80
-rw-r--r--arch/arm/configs/afeb9260_defconfig107
-rw-r--r--arch/arm/configs/ag5evm_defconfig83
-rw-r--r--arch/arm/configs/am200epdkit_defconfig108
-rw-r--r--arch/arm/configs/android_common_defconfig153
-rw-r--r--arch/arm/configs/ap4evb_defconfig57
-rw-r--r--arch/arm/configs/assabet_defconfig60
-rw-r--r--arch/arm/configs/at91cap9adk_defconfig115
-rw-r--r--arch/arm/configs/at91rm9200_defconfig341
-rw-r--r--arch/arm/configs/at91sam9260ek_defconfig83
-rw-r--r--arch/arm/configs/at91sam9261_defconfig158
-rw-r--r--arch/arm/configs/at91sam9263_defconfig168
-rw-r--r--arch/arm/configs/at91sam9g20ek_defconfig123
-rw-r--r--arch/arm/configs/at91sam9rlek_defconfig84
-rw-r--r--arch/arm/configs/at91x40_defconfig48
-rw-r--r--arch/arm/configs/badge4_defconfig122
-rw-r--r--arch/arm/configs/bcmring_defconfig79
-rw-r--r--arch/arm/configs/cam60_defconfig174
-rw-r--r--arch/arm/configs/cerfcube_defconfig75
-rw-r--r--arch/arm/configs/cm_x2xx_defconfig189
-rw-r--r--arch/arm/configs/cm_x300_defconfig188
-rw-r--r--arch/arm/configs/cns3420vb_defconfig72
-rw-r--r--arch/arm/configs/colibri_pxa270_defconfig180
-rw-r--r--arch/arm/configs/colibri_pxa300_defconfig73
-rw-r--r--arch/arm/configs/collie_defconfig94
-rw-r--r--arch/arm/configs/corgi_defconfig274
-rw-r--r--arch/arm/configs/cpu9260_defconfig116
-rw-r--r--arch/arm/configs/cpu9g20_defconfig116
-rw-r--r--arch/arm/configs/da8xx_omapl_defconfig129
-rw-r--r--arch/arm/configs/davinci_all_defconfig194
-rw-r--r--arch/arm/configs/dove_defconfig127
-rw-r--r--arch/arm/configs/ebsa110_defconfig75
-rw-r--r--arch/arm/configs/edb7211_defconfig27
-rw-r--r--arch/arm/configs/em_x270_defconfig194
-rw-r--r--arch/arm/configs/ep93xx_defconfig124
-rw-r--r--arch/arm/configs/eseries_pxa_defconfig118
-rw-r--r--arch/arm/configs/exynos4_defconfig72
-rw-r--r--arch/arm/configs/ezx_defconfig420
-rw-r--r--arch/arm/configs/footbridge_defconfig127
-rw-r--r--arch/arm/configs/fortunet_defconfig28
-rw-r--r--arch/arm/configs/g3evm_defconfig57
-rw-r--r--arch/arm/configs/g4evm_defconfig57
-rw-r--r--arch/arm/configs/h3600_defconfig79
-rw-r--r--arch/arm/configs/h5000_defconfig82
-rw-r--r--arch/arm/configs/h7201_defconfig27
-rw-r--r--arch/arm/configs/h7202_defconfig48
-rw-r--r--arch/arm/configs/hackkit_defconfig49
-rw-r--r--arch/arm/configs/imote2_defconfig392
-rwxr-xr-xarch/arm/configs/imx5_defconfig2429
-rw-r--r--arch/arm/configs/imx6_android_defconfig2982
-rw-r--r--arch/arm/configs/imx6_defconfig2709
-rw-r--r--arch/arm/configs/imx6_updater_defconfig2400
-rw-r--r--arch/arm/configs/imx6s_android_defconfig2977
-rw-r--r--arch/arm/configs/imx6s_defconfig2680
-rw-r--r--arch/arm/configs/imx6s_ntx_alyssum_defconfig2137
-rw-r--r--arch/arm/configs/imx6s_ntx_android_defconfig2784
-rw-r--r--arch/arm/configs/imx6s_ntx_defconfig2204
-rw-r--r--arch/arm/configs/imx6s_updater_defconfig2387
-rw-r--r--arch/arm/configs/integrator_defconfig71
-rw-r--r--arch/arm/configs/iop13xx_defconfig124
-rw-r--r--arch/arm/configs/iop32x_defconfig135
-rw-r--r--arch/arm/configs/iop33x_defconfig91
-rw-r--r--arch/arm/configs/ixp2000_defconfig99
-rw-r--r--arch/arm/configs/ixp23xx_defconfig105
-rw-r--r--arch/arm/configs/ixp4xx_defconfig205
-rw-r--r--arch/arm/configs/jornada720_defconfig112
-rw-r--r--arch/arm/configs/kirkwood_defconfig186
-rw-r--r--arch/arm/configs/ks8695_defconfig75
-rw-r--r--arch/arm/configs/lart_defconfig75
-rw-r--r--arch/arm/configs/loki_defconfig120
-rw-r--r--arch/arm/configs/lpd270_defconfig65
-rw-r--r--arch/arm/configs/lubbock_defconfig56
-rw-r--r--arch/arm/configs/mackerel_defconfig138
-rw-r--r--arch/arm/configs/magician_defconfig182
-rw-r--r--arch/arm/configs/mainstone_defconfig55
-rw-r--r--arch/arm/configs/mini2440_defconfig384
-rw-r--r--arch/arm/configs/mmp2_defconfig88
-rw-r--r--arch/arm/configs/msm_defconfig72
-rw-r--r--arch/arm/configs/mv78xx0_defconfig140
-rw-r--r--arch/arm/configs/mx1_defconfig91
-rw-r--r--arch/arm/configs/mx21_defconfig97
-rw-r--r--arch/arm/configs/mx27_defconfig130
-rw-r--r--arch/arm/configs/mx3_defconfig124
-rw-r--r--arch/arm/configs/mx51_defconfig169
-rw-r--r--arch/arm/configs/mxs_defconfig129
-rw-r--r--arch/arm/configs/neponset_defconfig90
-rw-r--r--arch/arm/configs/netwinder_defconfig87
-rw-r--r--arch/arm/configs/netx_defconfig86
-rw-r--r--arch/arm/configs/nhk8815_defconfig132
-rw-r--r--arch/arm/configs/nuc910_defconfig60
-rw-r--r--arch/arm/configs/nuc950_defconfig76
-rw-r--r--arch/arm/configs/nuc960_defconfig66
-rw-r--r--arch/arm/configs/omap1_defconfig286
-rw-r--r--arch/arm/configs/omap2plus_defconfig236
-rw-r--r--arch/arm/configs/orion5x_defconfig179
-rw-r--r--arch/arm/configs/palmz72_defconfig85
-rw-r--r--arch/arm/configs/pcm027_defconfig102
-rw-r--r--arch/arm/configs/pcontrol_g20_defconfig175
-rw-r--r--arch/arm/configs/pleb_defconfig57
-rw-r--r--arch/arm/configs/pnx4008_defconfig472
-rw-r--r--arch/arm/configs/pxa168_defconfig70
-rw-r--r--arch/arm/configs/pxa255-idp_defconfig59
-rw-r--r--arch/arm/configs/pxa3xx_defconfig134
-rw-r--r--arch/arm/configs/pxa910_defconfig70
-rw-r--r--arch/arm/configs/qil-a9260_defconfig115
-rw-r--r--arch/arm/configs/raumfeld_defconfig208
-rw-r--r--arch/arm/configs/realview-smp_defconfig101
-rw-r--r--arch/arm/configs/realview_defconfig100
-rw-r--r--arch/arm/configs/rpc_defconfig135
-rw-r--r--arch/arm/configs/s3c2410_defconfig489
-rw-r--r--arch/arm/configs/s3c6400_defconfig93
-rw-r--r--arch/arm/configs/s5p64x0_defconfig68
-rw-r--r--arch/arm/configs/s5pc100_defconfig49
-rw-r--r--arch/arm/configs/s5pv210_defconfig73
-rw-r--r--arch/arm/configs/sam9_l9260_defconfig148
-rw-r--r--arch/arm/configs/shannon_defconfig48
-rw-r--r--arch/arm/configs/shark_defconfig81
-rw-r--r--arch/arm/configs/simpad_defconfig111
-rw-r--r--arch/arm/configs/spear3xx_defconfig53
-rw-r--r--arch/arm/configs/spear6xx_defconfig49
-rw-r--r--arch/arm/configs/spitz_defconfig275
-rw-r--r--arch/arm/configs/stamp9g20_defconfig129
-rw-r--r--arch/arm/configs/tct_hammer_defconfig70
-rw-r--r--arch/arm/configs/tegra_defconfig146
-rw-r--r--arch/arm/configs/trizeps4_defconfig226
-rw-r--r--arch/arm/configs/u300_defconfig74
-rw-r--r--arch/arm/configs/u8500_defconfig105
-rw-r--r--arch/arm/configs/usb-a9260_defconfig106
-rw-r--r--arch/arm/configs/versatile_defconfig84
-rw-r--r--arch/arm/configs/vexpress_defconfig140
-rw-r--r--arch/arm/configs/viper_defconfig174
-rw-r--r--arch/arm/configs/xcep_defconfig99
-rw-r--r--arch/arm/configs/zeus_defconfig189
-rw-r--r--arch/arm/include/asm/Kbuild3
-rw-r--r--arch/arm/include/asm/a.out-core.h45
-rw-r--r--arch/arm/include/asm/a.out.h34
-rw-r--r--arch/arm/include/asm/asm-offsets.h1
-rw-r--r--arch/arm/include/asm/assembler.h310
-rw-r--r--arch/arm/include/asm/atomic.h468
-rw-r--r--arch/arm/include/asm/auxvec.h4
-rw-r--r--arch/arm/include/asm/bitops.h320
-rw-r--r--arch/arm/include/asm/bitsperlong.h1
-rw-r--r--arch/arm/include/asm/bug.h24
-rw-r--r--arch/arm/include/asm/bugs.h21
-rw-r--r--arch/arm/include/asm/byteorder.h25
-rw-r--r--arch/arm/include/asm/cache.h28
-rw-r--r--arch/arm/include/asm/cacheflush.h347
-rw-r--r--arch/arm/include/asm/cachetype.h56
-rw-r--r--arch/arm/include/asm/checksum.h139
-rw-r--r--arch/arm/include/asm/clkdev.h24
-rw-r--r--arch/arm/include/asm/cpu.h26
-rw-r--r--arch/arm/include/asm/cputime.h6
-rw-r--r--arch/arm/include/asm/cputype.h99
-rw-r--r--arch/arm/include/asm/current.h15
-rw-r--r--arch/arm/include/asm/delay.h44
-rw-r--r--arch/arm/include/asm/device.h18
-rw-r--r--arch/arm/include/asm/div64.h227
-rw-r--r--arch/arm/include/asm/dma-mapping.h568
-rw-r--r--arch/arm/include/asm/dma.h151
-rw-r--r--arch/arm/include/asm/domain.h105
-rw-r--r--arch/arm/include/asm/ecard.h219
-rw-r--r--arch/arm/include/asm/elf.h137
-rw-r--r--arch/arm/include/asm/emergency-restart.h6
-rw-r--r--arch/arm/include/asm/entry-macro-multi.S46
-rw-r--r--arch/arm/include/asm/entry-macro-vic2.S57
-rw-r--r--arch/arm/include/asm/errno.h6
-rw-r--r--arch/arm/include/asm/fb.h19
-rw-r--r--arch/arm/include/asm/fcntl.h11
-rw-r--r--arch/arm/include/asm/fiq.h56
-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/fixmap.h41
-rw-r--r--arch/arm/include/asm/flat.h16
-rw-r--r--arch/arm/include/asm/floppy.h148
-rw-r--r--arch/arm/include/asm/fncpy.h94
-rw-r--r--arch/arm/include/asm/fpstate.h93
-rw-r--r--arch/arm/include/asm/ftrace.h67
-rw-r--r--arch/arm/include/asm/futex.h168
-rw-r--r--arch/arm/include/asm/glue-cache.h146
-rw-r--r--arch/arm/include/asm/glue-df.h110
-rw-r--r--arch/arm/include/asm/glue-pf.h57
-rw-r--r--arch/arm/include/asm/glue-proc.h264
-rw-r--r--arch/arm/include/asm/glue.h25
-rw-r--r--arch/arm/include/asm/gpio.h7
-rw-r--r--arch/arm/include/asm/hardirq.h52
-rw-r--r--arch/arm/include/asm/hardware/arm_timer.h30
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h82
-rw-r--r--arch/arm/include/asm/hardware/cache-tauros2.h11
-rw-r--r--arch/arm/include/asm/hardware/clps7111.h184
-rw-r--r--arch/arm/include/asm/hardware/coresight.h185
-rw-r--r--arch/arm/include/asm/hardware/cs89712.h49
-rw-r--r--arch/arm/include/asm/hardware/debug-8250.S29
-rw-r--r--arch/arm/include/asm/hardware/debug-pl01x.S29
-rw-r--r--arch/arm/include/asm/hardware/dec21285.h147
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-gic.S75
-rw-r--r--arch/arm/include/asm/hardware/entry-macro-iomd.S139
-rw-r--r--arch/arm/include/asm/hardware/ep7211.h40
-rw-r--r--arch/arm/include/asm/hardware/ep7212.h83
-rw-r--r--arch/arm/include/asm/hardware/gic.h77
-rw-r--r--arch/arm/include/asm/hardware/icst.h59
-rw-r--r--arch/arm/include/asm/hardware/ioc.h72
-rw-r--r--arch/arm/include/asm/hardware/iomd.h185
-rw-r--r--arch/arm/include/asm/hardware/iop3xx-adma.h962
-rw-r--r--arch/arm/include/asm/hardware/iop3xx-gpio.h73
-rw-r--r--arch/arm/include/asm/hardware/iop3xx.h329
-rw-r--r--arch/arm/include/asm/hardware/iop_adma.h125
-rw-r--r--arch/arm/include/asm/hardware/it8152.h112
-rw-r--r--arch/arm/include/asm/hardware/linkup-l1110.h48
-rw-r--r--arch/arm/include/asm/hardware/locomo.h221
-rw-r--r--arch/arm/include/asm/hardware/memc.h26
-rw-r--r--arch/arm/include/asm/hardware/pci_v3.h186
-rw-r--r--arch/arm/include/asm/hardware/pl080.h140
-rw-r--r--arch/arm/include/asm/hardware/pl330.h217
-rw-r--r--arch/arm/include/asm/hardware/sa1111.h585
-rw-r--r--arch/arm/include/asm/hardware/scoop.h72
-rw-r--r--arch/arm/include/asm/hardware/sp810.h68
-rw-r--r--arch/arm/include/asm/hardware/ssp.h28
-rw-r--r--arch/arm/include/asm/hardware/timer-sp.h2
-rw-r--r--arch/arm/include/asm/hardware/uengine.h62
-rw-r--r--arch/arm/include/asm/hardware/vic.h47
-rw-r--r--arch/arm/include/asm/highmem.h66
-rw-r--r--arch/arm/include/asm/hw_breakpoint.h133
-rw-r--r--arch/arm/include/asm/hw_irq.h21
-rw-r--r--arch/arm/include/asm/hwcap.h33
-rw-r--r--arch/arm/include/asm/i8253.h15
-rw-r--r--arch/arm/include/asm/ide.h23
-rw-r--r--arch/arm/include/asm/io.h317
-rw-r--r--arch/arm/include/asm/ioctl.h1
-rw-r--r--arch/arm/include/asm/ioctls.h8
-rw-r--r--arch/arm/include/asm/ipcbuf.h29
-rw-r--r--arch/arm/include/asm/irq.h35
-rw-r--r--arch/arm/include/asm/irq_regs.h1
-rw-r--r--arch/arm/include/asm/irqflags.h155
-rw-r--r--arch/arm/include/asm/kdebug.h1
-rw-r--r--arch/arm/include/asm/kexec.h60
-rw-r--r--arch/arm/include/asm/kgdb.h105
-rw-r--r--arch/arm/include/asm/kmap_types.h33
-rw-r--r--arch/arm/include/asm/kprobes.h81
-rw-r--r--arch/arm/include/asm/leds.h50
-rw-r--r--arch/arm/include/asm/limits.h11
-rw-r--r--arch/arm/include/asm/linkage.h11
-rw-r--r--arch/arm/include/asm/local.h1
-rw-r--r--arch/arm/include/asm/local64.h1
-rw-r--r--arch/arm/include/asm/localtimer.h57
-rw-r--r--arch/arm/include/asm/locks.h274
-rw-r--r--arch/arm/include/asm/mach-types.h1
-rw-r--r--arch/arm/include/asm/mach/arch.h73
-rw-r--r--arch/arm/include/asm/mach/dma.h54
-rw-r--r--arch/arm/include/asm/mach/flash.h39
-rw-r--r--arch/arm/include/asm/mach/irda.h20
-rw-r--r--arch/arm/include/asm/mach/irq.h68
-rw-r--r--arch/arm/include/asm/mach/map.h45
-rw-r--r--arch/arm/include/asm/mach/mmc.h28
-rw-r--r--arch/arm/include/asm/mach/pci.h84
-rw-r--r--arch/arm/include/asm/mach/serial_at91.h33
-rw-r--r--arch/arm/include/asm/mach/serial_sa1100.h31
-rw-r--r--arch/arm/include/asm/mach/sharpsl_param.h37
-rw-r--r--arch/arm/include/asm/mach/time.h47
-rw-r--r--arch/arm/include/asm/mach/udc_pxa2xx.h26
-rw-r--r--arch/arm/include/asm/mc146818rtc.h28
-rw-r--r--arch/arm/include/asm/memblock.h9
-rw-r--r--arch/arm/include/asm/memory.h306
-rw-r--r--arch/arm/include/asm/mman.h4
-rw-r--r--arch/arm/include/asm/mmu.h37
-rw-r--r--arch/arm/include/asm/mmu_context.h164
-rw-r--r--arch/arm/include/asm/module.h55
-rw-r--r--arch/arm/include/asm/msgbuf.h31
-rw-r--r--arch/arm/include/asm/mtd-xip.h23
-rw-r--r--arch/arm/include/asm/mutex.h127
-rw-r--r--arch/arm/include/asm/nwflash.h9
-rw-r--r--arch/arm/include/asm/outercache.h102
-rw-r--r--arch/arm/include/asm/page-nommu.h46
-rw-r--r--arch/arm/include/asm/page.h214
-rw-r--r--arch/arm/include/asm/param.h31
-rw-r--r--arch/arm/include/asm/parport.h18
-rw-r--r--arch/arm/include/asm/pci.h80
-rw-r--r--arch/arm/include/asm/percpu.h6
-rw-r--r--arch/arm/include/asm/perf_event.h36
-rw-r--r--arch/arm/include/asm/pgalloc.h140
-rw-r--r--arch/arm/include/asm/pgtable-hwdef.h90
-rw-r--r--arch/arm/include/asm/pgtable-nommu.h119
-rw-r--r--arch/arm/include/asm/pgtable.h487
-rw-r--r--arch/arm/include/asm/pmu.h91
-rw-r--r--arch/arm/include/asm/poll.h1
-rw-r--r--arch/arm/include/asm/posix_types.h77
-rw-r--r--arch/arm/include/asm/proc-fns.h115
-rw-r--r--arch/arm/include/asm/processor.h128
-rw-r--r--arch/arm/include/asm/procinfo.h49
-rw-r--r--arch/arm/include/asm/prom.h37
-rw-r--r--arch/arm/include/asm/ptrace.h243
-rw-r--r--arch/arm/include/asm/resource.h6
-rw-r--r--arch/arm/include/asm/scatterlist.h8
-rw-r--r--arch/arm/include/asm/sched_clock.h120
-rw-r--r--arch/arm/include/asm/seccomp.h11
-rw-r--r--arch/arm/include/asm/sections.h1
-rw-r--r--arch/arm/include/asm/segment.h11
-rw-r--r--arch/arm/include/asm/sembuf.h25
-rw-r--r--arch/arm/include/asm/serial.h19
-rw-r--r--arch/arm/include/asm/setup.h226
-rw-r--r--arch/arm/include/asm/shmbuf.h42
-rw-r--r--arch/arm/include/asm/shmparam.h16
-rw-r--r--arch/arm/include/asm/sigcontext.h34
-rw-r--r--arch/arm/include/asm/siginfo.h6
-rw-r--r--arch/arm/include/asm/signal.h164
-rw-r--r--arch/arm/include/asm/sizes.h21
-rw-r--r--arch/arm/include/asm/smp.h98
-rw-r--r--arch/arm/include/asm/smp_plat.h46
-rw-r--r--arch/arm/include/asm/smp_scu.h14
-rw-r--r--arch/arm/include/asm/smp_twd.h28
-rw-r--r--arch/arm/include/asm/socket.h65
-rw-r--r--arch/arm/include/asm/sockios.h13
-rw-r--r--arch/arm/include/asm/sparsemem.h24
-rw-r--r--arch/arm/include/asm/spinlock.h268
-rw-r--r--arch/arm/include/asm/spinlock_types.h20
-rw-r--r--arch/arm/include/asm/stackprotector.h38
-rw-r--r--arch/arm/include/asm/stacktrace.h15
-rw-r--r--arch/arm/include/asm/stat.h87
-rw-r--r--arch/arm/include/asm/statfs.h12
-rw-r--r--arch/arm/include/asm/string.h41
-rw-r--r--arch/arm/include/asm/swab.h69
-rw-r--r--arch/arm/include/asm/system.h542
-rw-r--r--arch/arm/include/asm/tcm.h31
-rw-r--r--arch/arm/include/asm/termbits.h198
-rw-r--r--arch/arm/include/asm/termios.h92
-rw-r--r--arch/arm/include/asm/therm.h28
-rw-r--r--arch/arm/include/asm/thread_info.h165
-rw-r--r--arch/arm/include/asm/thread_notify.h49
-rw-r--r--arch/arm/include/asm/timex.h24
-rw-r--r--arch/arm/include/asm/tlb.h211
-rw-r--r--arch/arm/include/asm/tlbflush.h587
-rw-r--r--arch/arm/include/asm/tls.h49
-rw-r--r--arch/arm/include/asm/topology.h6
-rw-r--r--arch/arm/include/asm/traps.h52
-rw-r--r--arch/arm/include/asm/types.h22
-rw-r--r--arch/arm/include/asm/uaccess.h450
-rw-r--r--arch/arm/include/asm/ucontext.h102
-rw-r--r--arch/arm/include/asm/unaligned.h19
-rw-r--r--arch/arm/include/asm/unified.h130
-rw-r--r--arch/arm/include/asm/unistd.h485
-rw-r--r--arch/arm/include/asm/unwind.h69
-rw-r--r--arch/arm/include/asm/user.h103
-rw-r--r--arch/arm/include/asm/vfp.h84
-rw-r--r--arch/arm/include/asm/vfpmacros.h65
-rw-r--r--arch/arm/include/asm/vga.h12
-rw-r--r--arch/arm/include/asm/xor.h141
-rw-r--r--arch/arm/kernel/.gitignore1
-rw-r--r--arch/arm/kernel/Makefile73
-rw-r--r--arch/arm/kernel/armksyms.c170
-rw-r--r--arch/arm/kernel/arthur.c94
-rw-r--r--arch/arm/kernel/asm-offsets.c133
-rw-r--r--arch/arm/kernel/atags.c83
-rw-r--r--arch/arm/kernel/atags.h5
-rw-r--r--arch/arm/kernel/bios32.c681
-rw-r--r--arch/arm/kernel/calls.S394
-rw-r--r--arch/arm/kernel/compat.c219
-rw-r--r--arch/arm/kernel/compat.h11
-rw-r--r--arch/arm/kernel/crash_dump.c57
-rw-r--r--arch/arm/kernel/crunch-bits.S305
-rw-r--r--arch/arm/kernel/crunch.c88
-rw-r--r--arch/arm/kernel/debug.S179
-rw-r--r--arch/arm/kernel/devtree.c148
-rw-r--r--arch/arm/kernel/dma-isa.c222
-rw-r--r--arch/arm/kernel/dma.c302
-rw-r--r--arch/arm/kernel/early_printk.c57
-rw-r--r--arch/arm/kernel/ecard.c1241
-rw-r--r--arch/arm/kernel/ecard.h69
-rw-r--r--arch/arm/kernel/elf.c90
-rw-r--r--arch/arm/kernel/entry-armv.S1242
-rw-r--r--arch/arm/kernel/entry-common.S647
-rw-r--r--arch/arm/kernel/entry-header.S200
-rw-r--r--arch/arm/kernel/etm.c1075
-rw-r--r--arch/arm/kernel/fiq.c146
-rw-r--r--arch/arm/kernel/fiqasm.S49
-rw-r--r--arch/arm/kernel/ftrace.c288
-rw-r--r--arch/arm/kernel/head-common.S204
-rw-r--r--arch/arm/kernel/head-nommu.S90
-rw-r--r--arch/arm/kernel/head.S592
-rw-r--r--arch/arm/kernel/hw_breakpoint.c978
-rw-r--r--arch/arm/kernel/init_task.c37
-rw-r--r--arch/arm/kernel/io.c50
-rw-r--r--arch/arm/kernel/irq.c201
-rw-r--r--arch/arm/kernel/isa.c70
-rw-r--r--arch/arm/kernel/iwmmxt.S346
-rw-r--r--arch/arm/kernel/kgdb.c255
-rw-r--r--arch/arm/kernel/kprobes-decode.c1670
-rw-r--r--arch/arm/kernel/kprobes.c476
-rw-r--r--arch/arm/kernel/leds.c144
-rw-r--r--arch/arm/kernel/machine_kexec.c124
-rw-r--r--arch/arm/kernel/module.c367
-rw-r--r--arch/arm/kernel/perf_event.c775
-rw-r--r--arch/arm/kernel/perf_event_v6.c672
-rw-r--r--arch/arm/kernel/perf_event_v7.c918
-rw-r--r--arch/arm/kernel/perf_event_xscale.c807
-rw-r--r--arch/arm/kernel/pj4-cp0.c94
-rw-r--r--arch/arm/kernel/pmu.c148
-rw-r--r--arch/arm/kernel/process.c626
-rw-r--r--arch/arm/kernel/ptrace.c961
-rw-r--r--arch/arm/kernel/relocate_kernel.S87
-rw-r--r--arch/arm/kernel/return_address.c72
-rw-r--r--arch/arm/kernel/sched_clock.c74
-rw-r--r--arch/arm/kernel/setup.c1068
-rw-r--r--arch/arm/kernel/signal.c796
-rw-r--r--arch/arm/kernel/signal.h14
-rw-r--r--arch/arm/kernel/sleep.S142
-rw-r--r--arch/arm/kernel/smp.c686
-rw-r--r--arch/arm/kernel/smp_scu.c85
-rw-r--r--arch/arm/kernel/smp_tlb.c139
-rw-r--r--arch/arm/kernel/smp_twd.c223
-rw-r--r--arch/arm/kernel/stacktrace.c131
-rw-r--r--arch/arm/kernel/swp_emulate.c267
-rw-r--r--arch/arm/kernel/sys_arm.c133
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c453
-rw-r--r--arch/arm/kernel/tcm.c274
-rw-r--r--arch/arm/kernel/tcm.h17
-rw-r--r--arch/arm/kernel/thumbee.c81
-rw-r--r--arch/arm/kernel/time.c158
-rw-r--r--arch/arm/kernel/traps.c796
-rw-r--r--arch/arm/kernel/unwind.c452
-rw-r--r--arch/arm/kernel/vmlinux.lds.S287
-rw-r--r--arch/arm/kernel/xscale-cp0.c179
-rw-r--r--arch/arm/lib/Makefile47
-rw-r--r--arch/arm/lib/ashldi3.S53
-rw-r--r--arch/arm/lib/ashrdi3.S53
-rw-r--r--arch/arm/lib/backtrace.S158
-rw-r--r--arch/arm/lib/bitops.h77
-rw-r--r--arch/arm/lib/changebit.S17
-rw-r--r--arch/arm/lib/clear_user.S54
-rw-r--r--arch/arm/lib/clearbit.S17
-rw-r--r--arch/arm/lib/copy_from_user.S104
-rw-r--r--arch/arm/lib/copy_page.S47
-rw-r--r--arch/arm/lib/copy_template.S267
-rw-r--r--arch/arm/lib/copy_to_user.S106
-rw-r--r--arch/arm/lib/csumipv6.S33
-rw-r--r--arch/arm/lib/csumpartial.S142
-rw-r--r--arch/arm/lib/csumpartialcopy.S53
-rw-r--r--arch/arm/lib/csumpartialcopygeneric.S332
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S83
-rw-r--r--arch/arm/lib/delay.S69
-rw-r--r--arch/arm/lib/div64.S203
-rw-r--r--arch/arm/lib/ecard.S45
-rw-r--r--arch/arm/lib/findbit.S196
-rw-r--r--arch/arm/lib/floppydma.S32
-rw-r--r--arch/arm/lib/getuser.S73
-rw-r--r--arch/arm/lib/io-acorn.S31
-rw-r--r--arch/arm/lib/io-readsb.S123
-rw-r--r--arch/arm/lib/io-readsl.S79
-rw-r--r--arch/arm/lib/io-readsw-armv3.S107
-rw-r--r--arch/arm/lib/io-readsw-armv4.S131
-rw-r--r--arch/arm/lib/io-shark.c13
-rw-r--r--arch/arm/lib/io-writesb.S94
-rw-r--r--arch/arm/lib/io-writesl.S67
-rw-r--r--arch/arm/lib/io-writesw-armv3.S127
-rw-r--r--arch/arm/lib/io-writesw-armv4.S100
-rw-r--r--arch/arm/lib/lib1funcs.S363
-rw-r--r--arch/arm/lib/lshrdi3.S53
-rw-r--r--arch/arm/lib/memchr.S26
-rw-r--r--arch/arm/lib/memcpy.S63
-rw-r--r--arch/arm/lib/memmove.S199
-rw-r--r--arch/arm/lib/memset.S127
-rw-r--r--arch/arm/lib/memzero.S125
-rw-r--r--arch/arm/lib/muldi3.S47
-rw-r--r--arch/arm/lib/putuser.S92
-rw-r--r--arch/arm/lib/setbit.S17
-rw-r--r--arch/arm/lib/sha1.S211
-rw-r--r--arch/arm/lib/strchr.S27
-rw-r--r--arch/arm/lib/strncpy_from_user.S43
-rw-r--r--arch/arm/lib/strnlen_user.S40
-rw-r--r--arch/arm/lib/strrchr.S26
-rw-r--r--arch/arm/lib/testchangebit.S17
-rw-r--r--arch/arm/lib/testclearbit.S17
-rw-r--r--arch/arm/lib/testsetbit.S17
-rw-r--r--arch/arm/lib/uaccess.S564
-rw-r--r--arch/arm/lib/uaccess_with_memcpy.c234
-rw-r--r--arch/arm/lib/ucmpdi2.S52
-rw-r--r--arch/arm/mach-at91/Kconfig524
-rw-r--r--arch/arm/mach-at91/Makefile93
-rw-r--r--arch/arm/mach-at91/Makefile.boot18
-rw-r--r--arch/arm/mach-at91/at91cap9.c422
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c1259
-rw-r--r--arch/arm/mach-at91/at91rm9200.c396
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c1176
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c209
-rw-r--r--arch/arm/mach-at91/at91sam9260.c434
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c1328
-rw-r--r--arch/arm/mach-at91/at91sam9261.c385
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c1053
-rw-r--r--arch/arm/mach-at91/at91sam9263.c390
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c1434
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c188
-rw-r--r--arch/arm/mach-at91/at91sam9_alt_reset.S48
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c406
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c1591
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c383
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c1210
-rw-r--r--arch/arm/mach-at91/at91x40.c78
-rw-r--r--arch/arm/mach-at91/at91x40_time.c80
-rw-r--r--arch/arm/mach-at91/board-1arm.c104
-rw-r--r--arch/arm/mach-at91/board-afeb-9260v1.c227
-rw-r--r--arch/arm/mach-at91/board-cam60.c206
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c404
-rw-r--r--arch/arm/mach-at91/board-carmeva.c170
-rw-r--r--arch/arm/mach-at91/board-cpu9krea.c383
-rw-r--r--arch/arm/mach-at91/board-cpuat91.c187
-rw-r--r--arch/arm/mach-at91/board-csb337.c265
-rw-r--r--arch/arm/mach-at91/board-csb637.c146
-rw-r--r--arch/arm/mach-at91/board-eb01.c49
-rw-r--r--arch/arm/mach-at91/board-eb9200.c128
-rw-r--r--arch/arm/mach-at91/board-ecbat91.c180
-rw-r--r--arch/arm/mach-at91/board-eco920.c142
-rw-r--r--arch/arm/mach-at91/board-flexibity.c162
-rw-r--r--arch/arm/mach-at91/board-foxg20.c274
-rw-r--r--arch/arm/mach-at91/board-gsia18s.c584
-rw-r--r--arch/arm/mach-at91/board-kafa.c106
-rw-r--r--arch/arm/mach-at91/board-kb9202.c147
-rw-r--r--arch/arm/mach-at91/board-neocore926.c395
-rw-r--r--arch/arm/mach-at91/board-pcontrol-g20.c230
-rw-r--r--arch/arm/mach-at91/board-picotux200.c131
-rw-r--r--arch/arm/mach-at91/board-qil-a9260.c276
-rw-r--r--arch/arm/mach-at91/board-rm9200dk.c235
-rw-r--r--arch/arm/mach-at91/board-rm9200ek.c201
-rw-r--r--arch/arm/mach-at91/board-sam9-l9260.c220
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c361
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c628
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c459
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c420
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c429
-rw-r--r--arch/arm/mach-at91/board-sam9rlek.c337
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c188
-rw-r--r--arch/arm/mach-at91/board-stamp9g20.c315
-rw-r--r--arch/arm/mach-at91/board-usb-a9260.c236
-rw-r--r--arch/arm/mach-at91/board-usb-a9263.c252
-rw-r--r--arch/arm/mach-at91/board-yl-9200.c606
-rw-r--r--arch/arm/mach-at91/clock.c778
-rw-r--r--arch/arm/mach-at91/clock.h47
-rw-r--r--arch/arm/mach-at91/cpuidle.c94
-rw-r--r--arch/arm/mach-at91/generic.h87
-rw-r--r--arch/arm/mach-at91/gpio.c632
-rw-r--r--arch/arm/mach-at91/include/mach/at91_adc.h61
-rw-r--r--arch/arm/mach-at91/include/mach/at91_aic.h53
-rw-r--r--arch/arm/mach-at91/include/mach/at91_dbgu.h66
-rw-r--r--arch/arm/mach-at91/include/mach/at91_mci.h115
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pio.h49
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pit.h32
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc.h133
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rstc.h41
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rtc.h75
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rtt.h35
-rw-r--r--arch/arm/mach-at91/include/mach/at91_shdwc.h38
-rw-r--r--arch/arm/mach-at91/include/mach/at91_spi.h81
-rw-r--r--arch/arm/mach-at91/include/mach/at91_ssc.h106
-rw-r--r--arch/arm/mach-at91/include/mach/at91_st.h49
-rw-r--r--arch/arm/mach-at91/include/mach/at91_tc.h146
-rw-r--r--arch/arm/mach-at91/include/mach/at91_twi.h68
-rw-r--r--arch/arm/mach-at91/include/mach/at91_wdt.h37
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9.h124
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h108
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9_matrix.h137
-rw-r--r--arch/arm/mach-at91/include/mach/at91rm9200.h113
-rw-r--r--arch/arm/mach-at91/include/mach/at91rm9200_emac.h138
-rw-r--r--arch/arm/mach-at91/include/mach/at91rm9200_mc.h160
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9260.h136
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9260_matrix.h80
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9261.h106
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9261_matrix.h64
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9263.h125
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9263_matrix.h129
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h130
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_sdramc.h91
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_smc.h76
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9g45.h151
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h153
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9rl.h113
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h96
-rw-r--r--arch/arm/mach-at91/include/mach/at91x40.h59
-rw-r--r--arch/arm/mach-at91/include/mach/at_hdmac.h102
-rw-r--r--arch/arm/mach-at91/include/mach/atmel-mci.h24
-rw-r--r--arch/arm/mach-at91/include/mach/board.h210
-rw-r--r--arch/arm/mach-at91/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h195
-rw-r--r--arch/arm/mach-at91/include/mach/debug-macro.S37
-rw-r--r--arch/arm/mach-at91/include/mach/entry-macro.S32
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h228
-rw-r--r--arch/arm/mach-at91/include/mach/gsia18s.h33
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h93
-rw-r--r--arch/arm/mach-at91/include/mach/io.h48
-rw-r--r--arch/arm/mach-at91/include/mach/irqs.h48
-rw-r--r--arch/arm/mach-at91/include/mach/memory.h26
-rw-r--r--arch/arm/mach-at91/include/mach/stamp9g20.h7
-rw-r--r--arch/arm/mach-at91/include/mach/system.h59
-rw-r--r--arch/arm/mach-at91/include/mach/system_rev.h25
-rw-r--r--arch/arm/mach-at91/include/mach/timex.h87
-rw-r--r--arch/arm/mach-at91/include/mach/uncompress.h76
-rw-r--r--arch/arm/mach-at91/include/mach/vmalloc.h26
-rw-r--r--arch/arm/mach-at91/irq.c166
-rw-r--r--arch/arm/mach-at91/leds.c197
-rw-r--r--arch/arm/mach-at91/pm.c329
-rw-r--r--arch/arm/mach-at91/pm.h107
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S326
-rw-r--r--arch/arm/mach-at91/sam9_smc.c47
-rw-r--r--arch/arm/mach-at91/sam9_smc.h33
-rw-r--r--arch/arm/mach-bcmring/Kconfig21
-rw-r--r--arch/arm/mach-bcmring/Makefile8
-rw-r--r--arch/arm/mach-bcmring/Makefile.boot6
-rw-r--r--arch/arm/mach-bcmring/arch.c176
-rw-r--r--arch/arm/mach-bcmring/clock.c223
-rw-r--r--arch/arm/mach-bcmring/clock.h33
-rw-r--r--arch/arm/mach-bcmring/core.c248
-rw-r--r--arch/arm/mach-bcmring/core.h31
-rw-r--r--arch/arm/mach-bcmring/csp/Makefile3
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw.c776
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c293
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c124
-rw-r--r--arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c64
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/dmacHw.c917
-rw-r--r--arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c1017
-rw-r--r--arch/arm/mach-bcmring/csp/tmr/Makefile1
-rw-r--r--arch/arm/mach-bcmring/csp/tmr/tmrHw.c576
-rw-r--r--arch/arm/mach-bcmring/dma.c2329
-rw-r--r--arch/arm/mach-bcmring/dma_device.c593
-rw-r--r--arch/arm/mach-bcmring/include/cfg_global.h13
-rw-r--r--arch/arm/mach-bcmring/include/cfg_global_defines.h40
-rw-r--r--arch/arm/mach-bcmring/include/csp/cache.h35
-rw-r--r--arch/arm/mach-bcmring/include/csp/delay.h36
-rw-r--r--arch/arm/mach-bcmring/include/csp/dmacHw.h596
-rw-r--r--arch/arm/mach-bcmring/include/csp/errno.h32
-rw-r--r--arch/arm/mach-bcmring/include/csp/intcHw.h40
-rw-r--r--arch/arm/mach-bcmring/include/csp/module.h32
-rw-r--r--arch/arm/mach-bcmring/include/csp/reg.h114
-rw-r--r--arch/arm/mach-bcmring/include/csp/secHw.h65
-rw-r--r--arch/arm/mach-bcmring/include/csp/stdint.h30
-rw-r--r--arch/arm/mach-bcmring/include/csp/string.h34
-rw-r--r--arch/arm/mach-bcmring/include/csp/tmrHw.h263
-rw-r--r--arch/arm/mach-bcmring/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/cap.h63
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/cap_inline.h409
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h1123
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h1673
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h530
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h872
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h145
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h406
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h73
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h246
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/mm_addr.h101
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/mm_io.h147
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/secHw_def.h100
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h79
-rw-r--r--arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h82
-rw-r--r--arch/arm/mach-bcmring/include/mach/dma.h826
-rw-r--r--arch/arm/mach-bcmring/include/mach/entry-macro.S86
-rw-r--r--arch/arm/mach-bcmring/include/mach/hardware.h60
-rw-r--r--arch/arm/mach-bcmring/include/mach/io.h33
-rw-r--r--arch/arm/mach-bcmring/include/mach/irqs.h132
-rw-r--r--arch/arm/mach-bcmring/include/mach/memory.h33
-rw-r--r--arch/arm/mach-bcmring/include/mach/memory_settings.h67
-rw-r--r--arch/arm/mach-bcmring/include/mach/reg_nand.h66
-rw-r--r--arch/arm/mach-bcmring/include/mach/reg_umi.h237
-rw-r--r--arch/arm/mach-bcmring/include/mach/system.h54
-rw-r--r--arch/arm/mach-bcmring/include/mach/timer.h77
-rw-r--r--arch/arm/mach-bcmring/include/mach/timex.h25
-rw-r--r--arch/arm/mach-bcmring/include/mach/uncompress.h43
-rw-r--r--arch/arm/mach-bcmring/include/mach/vmalloc.h25
-rw-r--r--arch/arm/mach-bcmring/irq.c127
-rw-r--r--arch/arm/mach-bcmring/mm.c56
-rw-r--r--arch/arm/mach-bcmring/timer.c62
-rw-r--r--arch/arm/mach-clps711x/Kconfig77
-rw-r--r--arch/arm/mach-clps711x/Makefile20
-rw-r--r--arch/arm/mach-clps711x/Makefile.boot6
-rw-r--r--arch/arm/mach-clps711x/autcpu12.c72
-rw-r--r--arch/arm/mach-clps711x/cdb89712.c62
-rw-r--r--arch/arm/mach-clps711x/ceiva.c63
-rw-r--r--arch/arm/mach-clps711x/clep7312.c46
-rw-r--r--arch/arm/mach-clps711x/common.h11
-rw-r--r--arch/arm/mach-clps711x/edb7211-arch.c66
-rw-r--r--arch/arm/mach-clps711x/edb7211-mm.c81
-rw-r--r--arch/arm/mach-clps711x/fortunet.c83
-rw-r--r--arch/arm/mach-clps711x/include/mach/autcpu12.h78
-rw-r--r--arch/arm/mach-clps711x/include/mach/debug-macro.S45
-rw-r--r--arch/arm/mach-clps711x/include/mach/entry-macro.S58
-rw-r--r--arch/arm/mach-clps711x/include/mach/hardware.h208
-rw-r--r--arch/arm/mach-clps711x/include/mach/io.h36
-rw-r--r--arch/arm/mach-clps711x/include/mach/irqs.h53
-rw-r--r--arch/arm/mach-clps711x/include/mach/memory.h78
-rw-r--r--arch/arm/mach-clps711x/include/mach/syspld.h121
-rw-r--r--arch/arm/mach-clps711x/include/mach/system.h40
-rw-r--r--arch/arm/mach-clps711x/include/mach/time.h49
-rw-r--r--arch/arm/mach-clps711x/include/mach/timex.h23
-rw-r--r--arch/arm/mach-clps711x/include/mach/uncompress.h59
-rw-r--r--arch/arm/mach-clps711x/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-clps711x/irq.c143
-rw-r--r--arch/arm/mach-clps711x/mm.c48
-rw-r--r--arch/arm/mach-clps711x/p720t-leds.c67
-rw-r--r--arch/arm/mach-clps711x/p720t.c123
-rw-r--r--arch/arm/mach-clps711x/time.c84
-rw-r--r--arch/arm/mach-cns3xxx/Kconfig13
-rw-r--r--arch/arm/mach-cns3xxx/Makefile3
-rw-r--r--arch/arm/mach-cns3xxx/Makefile.boot3
-rw-r--r--arch/arm/mach-cns3xxx/cns3420vb.c204
-rw-r--r--arch/arm/mach-cns3xxx/core.c246
-rw-r--r--arch/arm/mach-cns3xxx/core.h20
-rw-r--r--arch/arm/mach-cns3xxx/devices.c112
-rw-r--r--arch/arm/mach-cns3xxx/devices.h20
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/cns3xxx.h632
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/hardware.h22
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/io.h17
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/irqs.h24
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/memory.h26
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/pm.h23
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/system.h29
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/timex.h12
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/uncompress.h55
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/vmalloc.h11
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c389
-rw-r--r--arch/arm/mach-cns3xxx/pm.c124
-rw-r--r--arch/arm/mach-davinci/Kconfig266
-rw-r--r--arch/arm/mach-davinci/Makefile42
-rw-r--r--arch/arm/mach-davinci/Makefile.boot13
-rw-r--r--arch/arm/mach-davinci/aemif.c133
-rw-r--r--arch/arm/mach-davinci/board-da830-evm.c684
-rw-r--r--arch/arm/mach-davinci/board-da850-evm.c1292
-rw-r--r--arch/arm/mach-davinci/board-dm355-evm.c359
-rw-r--r--arch/arm/mach-davinci/board-dm355-leopard.c278
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c621
-rw-r--r--arch/arm/mach-davinci/board-dm644x-evm.c720
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c814
-rw-r--r--arch/arm/mach-davinci/board-mityomapl138.c574
-rw-r--r--arch/arm/mach-davinci/board-neuros-osd2.c280
-rw-r--r--arch/arm/mach-davinci/board-omapl138-hawk.c346
-rw-r--r--arch/arm/mach-davinci/board-sffsdr.c159
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c285
-rw-r--r--arch/arm/mach-davinci/cdce949.c294
-rw-r--r--arch/arm/mach-davinci/clock.c641
-rw-r--r--arch/arm/mach-davinci/clock.h132
-rw-r--r--arch/arm/mach-davinci/common.c119
-rw-r--r--arch/arm/mach-davinci/cp_intc.c177
-rw-r--r--arch/arm/mach-davinci/cpufreq.c248
-rw-r--r--arch/arm/mach-davinci/cpuidle.c169
-rw-r--r--arch/arm/mach-davinci/da830.c1212
-rw-r--r--arch/arm/mach-davinci/da850.c1139
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c844
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c408
-rw-r--r--arch/arm/mach-davinci/devices.c339
-rw-r--r--arch/arm/mach-davinci/dm355.c892
-rw-r--r--arch/arm/mach-davinci/dm365.c1245
-rw-r--r--arch/arm/mach-davinci/dm644x.c805
-rw-r--r--arch/arm/mach-davinci/dm646x.c921
-rw-r--r--arch/arm/mach-davinci/dma.c1596
-rw-r--r--arch/arm/mach-davinci/gpio-tnetv107x.c205
-rw-r--r--arch/arm/mach-davinci/gpio.c460
-rw-r--r--arch/arm/mach-davinci/include/mach/aemif.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/asp.h137
-rw-r--r--arch/arm/mach-davinci/include/mach/cdce949.h19
-rw-r--r--arch/arm/mach-davinci/include/mach/clkdev.h15
-rw-r--r--arch/arm/mach-davinci/include/mach/clock.h21
-rw-r--r--arch/arm/mach-davinci/include/mach/common.h93
-rw-r--r--arch/arm/mach-davinci/include/mach/cp_intc.h56
-rw-r--r--arch/arm/mach-davinci/include/mach/cpufreq.h26
-rw-r--r--arch/arm/mach-davinci/include/mach/cpuidle.h18
-rw-r--r--arch/arm/mach-davinci/include/mach/cputype.h94
-rw-r--r--arch/arm/mach-davinci/include/mach/da8xx.h130
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S91
-rw-r--r--arch/arm/mach-davinci/include/mach/dm355.h32
-rw-r--r--arch/arm/mach-davinci/include/mach/dm365.h52
-rw-r--r--arch/arm/mach-davinci/include/mach/dm644x.h47
-rw-r--r--arch/arm/mach-davinci/include/mach/dm646x.h94
-rw-r--r--arch/arm/mach-davinci/include/mach/edma.h262
-rw-r--r--arch/arm/mach-davinci/include/mach/entry-macro.S51
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h161
-rw-r--r--arch/arm/mach-davinci/include/mach/hardware.h41
-rw-r--r--arch/arm/mach-davinci/include/mach/i2c.h26
-rw-r--r--arch/arm/mach-davinci/include/mach/io.h32
-rw-r--r--arch/arm/mach-davinci/include/mach/irqs.h506
-rw-r--r--arch/arm/mach-davinci/include/mach/keyscan.h42
-rw-r--r--arch/arm/mach-davinci/include/mach/memory.h51
-rw-r--r--arch/arm/mach-davinci/include/mach/mmc.h36
-rw-r--r--arch/arm/mach-davinci/include/mach/mux.h1207
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h88
-rw-r--r--arch/arm/mach-davinci/include/mach/pm.h54
-rw-r--r--arch/arm/mach-davinci/include/mach/psc.h256
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h57
-rw-r--r--arch/arm/mach-davinci/include/mach/spi.h89
-rw-r--r--arch/arm/mach-davinci/include/mach/sram.h27
-rw-r--r--arch/arm/mach-davinci/include/mach/system.h27
-rw-r--r--arch/arm/mach-davinci/include/mach/time.h35
-rw-r--r--arch/arm/mach-davinci/include/mach/timex.h22
-rw-r--r--arch/arm/mach-davinci/include/mach/tnetv107x.h60
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h101
-rw-r--r--arch/arm/mach-davinci/include/mach/usb.h59
-rw-r--r--arch/arm/mach-davinci/include/mach/vmalloc.h14
-rw-r--r--arch/arm/mach-davinci/io.c48
-rw-r--r--arch/arm/mach-davinci/irq.c117
-rw-r--r--arch/arm/mach-davinci/mux.c113
-rw-r--r--arch/arm/mach-davinci/mux.h51
-rw-r--r--arch/arm/mach-davinci/pm.c159
-rw-r--r--arch/arm/mach-davinci/psc.c100
-rw-r--r--arch/arm/mach-davinci/serial.c115
-rw-r--r--arch/arm/mach-davinci/sleep.S228
-rw-r--r--arch/arm/mach-davinci/sram.c71
-rw-r--r--arch/arm/mach-davinci/time.c474
-rw-r--r--arch/arm/mach-davinci/tnetv107x.c761
-rw-r--r--arch/arm/mach-davinci/usb.c180
-rw-r--r--arch/arm/mach-dove/Kconfig20
-rw-r--r--arch/arm/mach-dove/Makefile4
-rw-r--r--arch/arm/mach-dove/Makefile.boot3
-rw-r--r--arch/arm/mach-dove/addr-map.c149
-rw-r--r--arch/arm/mach-dove/cm-a510.c96
-rw-r--r--arch/arm/mach-dove/common.c297
-rw-r--r--arch/arm/mach-dove/common.h43
-rw-r--r--arch/arm/mach-dove/dove-db-setup.c103
-rw-r--r--arch/arm/mach-dove/include/mach/bridge-regs.h54
-rw-r--r--arch/arm/mach-dove/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h188
-rw-r--r--arch/arm/mach-dove/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-dove/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-dove/include/mach/hardware.h26
-rw-r--r--arch/arm/mach-dove/include/mach/io.h20
-rw-r--r--arch/arm/mach-dove/include/mach/irqs.h96
-rw-r--r--arch/arm/mach-dove/include/mach/memory.h10
-rw-r--r--arch/arm/mach-dove/include/mach/pm.h54
-rw-r--r--arch/arm/mach-dove/include/mach/system.h36
-rw-r--r--arch/arm/mach-dove/include/mach/timex.h9
-rw-r--r--arch/arm/mach-dove/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-dove/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-dove/irq.c129
-rw-r--r--arch/arm/mach-dove/mpp.c161
-rw-r--r--arch/arm/mach-dove/mpp.h196
-rw-r--r--arch/arm/mach-dove/pcie.c238
-rw-r--r--arch/arm/mach-ebsa110/Makefile12
-rw-r--r--arch/arm/mach-ebsa110/Makefile.boot4
-rw-r--r--arch/arm/mach-ebsa110/core.c290
-rw-r--r--arch/arm/mach-ebsa110/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-ebsa110/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-ebsa110/include/mach/hardware.h63
-rw-r--r--arch/arm/mach-ebsa110/include/mach/io.h92
-rw-r--r--arch/arm/mach-ebsa110/include/mach/irqs.h20
-rw-r--r--arch/arm/mach-ebsa110/include/mach/memory.h30
-rw-r--r--arch/arm/mach-ebsa110/include/mach/system.h39
-rw-r--r--arch/arm/mach-ebsa110/include/mach/timex.h19
-rw-r--r--arch/arm/mach-ebsa110/include/mach/uncompress.h45
-rw-r--r--arch/arm/mach-ebsa110/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-ebsa110/io.c419
-rw-r--r--arch/arm/mach-ebsa110/leds.c51
-rw-r--r--arch/arm/mach-ep93xx/Kconfig201
-rw-r--r--arch/arm/mach-ep93xx/Makefile15
-rw-r--r--arch/arm/mach-ep93xx/Makefile.boot14
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c41
-rw-r--r--arch/arm/mach-ep93xx/clock.c562
-rw-r--r--arch/arm/mach-ep93xx/core.c889
-rw-r--r--arch/arm/mach-ep93xx/dma-m2p.c411
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c326
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c41
-rw-r--r--arch/arm/mach-ep93xx/gpio.c410
-rw-r--r--arch/arm/mach-ep93xx/include/mach/clkdev.h11
-rw-r--r--arch/arm/mach-ep93xx/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-ep93xx/include/mach/dma.h157
-rw-r--r--arch/arm/mach-ep93xx/include/mach/entry-macro.S59
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h229
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h35
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h27
-rw-r--r--arch/arm/mach-ep93xx/include/mach/fb.h56
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio.h120
-rw-r--r--arch/arm/mach-ep93xx/include/mach/hardware.h27
-rw-r--r--arch/arm/mach-ep93xx/include/mach/io.h22
-rw-r--r--arch/arm/mach-ep93xx/include/mach/irqs.h78
-rw-r--r--arch/arm/mach-ep93xx/include/mach/memory.h22
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h69
-rw-r--r--arch/arm/mach-ep93xx/include/mach/system.h24
-rw-r--r--arch/arm/mach-ep93xx/include/mach/timex.h5
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ts72xx.h80
-rw-r--r--arch/arm/mach-ep93xx/include/mach/uncompress.h94
-rw-r--r--arch/arm/mach-ep93xx/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-ep93xx/micro9.c119
-rw-r--r--arch/arm/mach-ep93xx/simone.c74
-rw-r--r--arch/arm/mach-ep93xx/snappercl15.c171
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c265
-rw-r--r--arch/arm/mach-exynos4/Kconfig209
-rw-r--r--arch/arm/mach-exynos4/Makefile59
-rw-r--r--arch/arm/mach-exynos4/Makefile.boot2
-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-ahci.c263
-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/headsmp.S41
-rw-r--r--arch/arm/mach-exynos4/hotplug.c130
-rw-r--r--arch/arm/mach-exynos4/include/mach/debug-macro.S35
-rw-r--r--arch/arm/mach-exynos4/include/mach/dma.h26
-rw-r--r--arch/arm/mach-exynos4/include/mach/entry-macro.S84
-rw-r--r--arch/arm/mach-exynos4/include/mach/gpio.h156
-rw-r--r--arch/arm/mach-exynos4/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-exynos4/include/mach/io.h26
-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/memory.h22
-rw-r--r--arch/arm/mach-exynos4/include/mach/pm-core.h49
-rw-r--r--arch/arm/mach-exynos4/include/mach/pwm-clock.h70
-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-irq.h19
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-mct.h52
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-mem.h23
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-pmu.h165
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-sysmmu.h28
-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/include/mach/system.h22
-rw-r--r--arch/arm/mach-exynos4/include/mach/timex.h29
-rw-r--r--arch/arm/mach-exynos4/include/mach/uncompress.h30
-rw-r--r--arch/arm/mach-exynos4/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-exynos4/init.c42
-rw-r--r--arch/arm/mach-exynos4/irq-combiner.c124
-rw-r--r--arch/arm/mach-exynos4/irq-eint.c230
-rw-r--r--arch/arm/mach-exynos4/localtimer.c26
-rw-r--r--arch/arm/mach-exynos4/mach-armlex4210.c215
-rw-r--r--arch/arm/mach-exynos4/mach-nuri.c410
-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/mach-universal_c210.c650
-rw-r--r--arch/arm/mach-exynos4/mct.c421
-rw-r--r--arch/arm/mach-exynos4/platsmp.c175
-rw-r--r--arch/arm/mach-exynos4/pm.c429
-rw-r--r--arch/arm/mach-exynos4/setup-fimc.c44
-rw-r--r--arch/arm/mach-exynos4/setup-i2c0.c26
-rw-r--r--arch/arm/mach-exynos4/setup-i2c1.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c2.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c3.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c4.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c5.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c6.c23
-rw-r--r--arch/arm/mach-exynos4/setup-i2c7.c23
-rw-r--r--arch/arm/mach-exynos4/setup-keypad.c35
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci-gpio.c152
-rw-r--r--arch/arm/mach-exynos4/setup-sdhci.c69
-rw-r--r--arch/arm/mach-exynos4/setup-usb-phy.c136
-rw-r--r--arch/arm/mach-exynos4/sleep.S76
-rw-r--r--arch/arm/mach-exynos4/time.c301
-rw-r--r--arch/arm/mach-footbridge/Kconfig95
-rw-r--r--arch/arm/mach-footbridge/Makefile28
-rw-r--r--arch/arm/mach-footbridge/Makefile.boot4
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c95
-rw-r--r--arch/arm/mach-footbridge/cats-pci.c58
-rw-r--r--arch/arm/mach-footbridge/common.c244
-rw-r--r--arch/arm/mach-footbridge/common.h10
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c113
-rw-r--r--arch/arm/mach-footbridge/dc21285.c388
-rw-r--r--arch/arm/mach-footbridge/dma.c57
-rw-r--r--arch/arm/mach-footbridge/ebsa285-leds.c139
-rw-r--r--arch/arm/mach-footbridge/ebsa285-pci.c48
-rw-r--r--arch/arm/mach-footbridge/ebsa285.c25
-rw-r--r--arch/arm/mach-footbridge/include/mach/debug-macro.S56
-rw-r--r--arch/arm/mach-footbridge/include/mach/entry-macro.S113
-rw-r--r--arch/arm/mach-footbridge/include/mach/hardware.h108
-rw-r--r--arch/arm/mach-footbridge/include/mach/io.h46
-rw-r--r--arch/arm/mach-footbridge/include/mach/irqs.h98
-rw-r--r--arch/arm/mach-footbridge/include/mach/isa-dma.h25
-rw-r--r--arch/arm/mach-footbridge/include/mach/memory.h69
-rw-r--r--arch/arm/mach-footbridge/include/mach/system.h69
-rw-r--r--arch/arm/mach-footbridge/include/mach/timex.h18
-rw-r--r--arch/arm/mach-footbridge/include/mach/uncompress.h38
-rw-r--r--arch/arm/mach-footbridge/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-footbridge/isa-irq.c183
-rw-r--r--arch/arm/mach-footbridge/isa-rtc.c57
-rw-r--r--arch/arm/mach-footbridge/isa-timer.c95
-rw-r--r--arch/arm/mach-footbridge/isa.c101
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c660
-rw-r--r--arch/arm/mach-footbridge/netwinder-leds.c139
-rw-r--r--arch/arm/mach-footbridge/netwinder-pci.c62
-rw-r--r--arch/arm/mach-footbridge/personal-pci.c56
-rw-r--r--arch/arm/mach-footbridge/personal.c23
-rw-r--r--arch/arm/mach-gemini/Kconfig40
-rw-r--r--arch/arm/mach-gemini/Makefile13
-rw-r--r--arch/arm/mach-gemini/Makefile.boot9
-rw-r--r--arch/arm/mach-gemini/board-nas4220b.c110
-rw-r--r--arch/arm/mach-gemini/board-rut1xx.c94
-rw-r--r--arch/arm/mach-gemini/board-wbd111.c137
-rw-r--r--arch/arm/mach-gemini/board-wbd222.c137
-rw-r--r--arch/arm/mach-gemini/common.h29
-rw-r--r--arch/arm/mach-gemini/devices.c118
-rw-r--r--arch/arm/mach-gemini/gpio.c230
-rw-r--r--arch/arm/mach-gemini/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-gemini/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-gemini/include/mach/global_reg.h278
-rw-r--r--arch/arm/mach-gemini/include/mach/gpio.h25
-rw-r--r--arch/arm/mach-gemini/include/mach/hardware.h74
-rw-r--r--arch/arm/mach-gemini/include/mach/io.h18
-rw-r--r--arch/arm/mach-gemini/include/mach/irqs.h53
-rw-r--r--arch/arm/mach-gemini/include/mach/memory.h19
-rw-r--r--arch/arm/mach-gemini/include/mach/system.h37
-rw-r--r--arch/arm/mach-gemini/include/mach/timex.h13
-rw-r--r--arch/arm/mach-gemini/include/mach/uncompress.h44
-rw-r--r--arch/arm/mach-gemini/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-gemini/irq.c102
-rw-r--r--arch/arm/mach-gemini/mm.c82
-rw-r--r--arch/arm/mach-gemini/time.c89
-rw-r--r--arch/arm/mach-h720x/Kconfig40
-rw-r--r--arch/arm/mach-h720x/Makefile16
-rw-r--r--arch/arm/mach-h720x/Makefile.boot2
-rw-r--r--arch/arm/mach-h720x/common.c244
-rw-r--r--arch/arm/mach-h720x/common.h29
-rw-r--r--arch/arm/mach-h720x/cpu-h7201.c60
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c228
-rw-r--r--arch/arm/mach-h720x/h7201-eval.c36
-rw-r--r--arch/arm/mach-h720x/h7202-eval.c79
-rw-r--r--arch/arm/mach-h720x/include/mach/boards.h53
-rw-r--r--arch/arm/mach-h720x/include/mach/debug-macro.S40
-rw-r--r--arch/arm/mach-h720x/include/mach/entry-macro.S66
-rw-r--r--arch/arm/mach-h720x/include/mach/h7201-regs.h67
-rw-r--r--arch/arm/mach-h720x/include/mach/h7202-regs.h155
-rw-r--r--arch/arm/mach-h720x/include/mach/hardware.h190
-rw-r--r--arch/arm/mach-h720x/include/mach/io.h22
-rw-r--r--arch/arm/mach-h720x/include/mach/irqs.h116
-rw-r--r--arch/arm/mach-h720x/include/mach/isa-dma.h19
-rw-r--r--arch/arm/mach-h720x/include/mach/memory.h18
-rw-r--r--arch/arm/mach-h720x/include/mach/system.h33
-rw-r--r--arch/arm/mach-h720x/include/mach/timex.h15
-rw-r--r--arch/arm/mach-h720x/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-h720x/include/mach/vmalloc.h10
-rwxr-xr-xarch/arm/mach-imx/Kconfig608
-rw-r--r--arch/arm/mach-imx/Makefile63
-rw-r--r--arch/arm/mach-imx/Makefile.boot19
-rw-r--r--arch/arm/mach-imx/cache-l2x0.c56
-rw-r--r--arch/arm/mach-imx/clock-imx1.c636
-rw-r--r--arch/arm/mach-imx/clock-imx21.c1239
-rw-r--r--arch/arm/mach-imx/clock-imx25.c334
-rw-r--r--arch/arm/mach-imx/clock-imx27.c763
-rw-r--r--arch/arm/mach-imx/clock-imx31.c629
-rw-r--r--arch/arm/mach-imx/clock-imx35.c549
-rw-r--r--arch/arm/mach-imx/cpu-imx27.c76
-rw-r--r--arch/arm/mach-imx/cpu-imx31.c57
-rw-r--r--arch/arm/mach-imx/cpu-imx35.c44
-rw-r--r--arch/arm/mach-imx/crmregs-imx31.h248
-rw-r--r--arch/arm/mach-imx/devices-imx1.h31
-rw-r--r--arch/arm/mach-imx/devices-imx21.h60
-rw-r--r--arch/arm/mach-imx/devices-imx25.h90
-rw-r--r--arch/arm/mach-imx/devices-imx27.h78
-rw-r--r--arch/arm/mach-imx/devices-imx31.h80
-rw-r--r--arch/arm/mach-imx/devices-imx35.h83
-rw-r--r--arch/arm/mach-imx/dma-v1.c865
-rw-r--r--arch/arm/mach-imx/ehci-imx25.c80
-rw-r--r--arch/arm/mach-imx/ehci-imx27.c82
-rw-r--r--arch/arm/mach-imx/ehci-imx31.c82
-rw-r--r--arch/arm/mach-imx/ehci-imx35.c79
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c381
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c291
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c303
-rw-r--r--arch/arm/mach-imx/include/mach/dma-mx1-mx2.h10
-rw-r--r--arch/arm/mach-imx/include/mach/dma-v1.h103
-rw-r--r--arch/arm/mach-imx/iomux-imx31.c181
-rw-r--r--arch/arm/mach-imx/mach-apf9328.c144
-rw-r--r--arch/arm/mach-imx/mach-armadillo5x0.c565
-rw-r--r--arch/arm/mach-imx/mach-bug.c65
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c318
-rw-r--r--arch/arm/mach-imx/mach-cpuimx35.c201
-rw-r--r--arch/arm/mach-imx/mach-eukrea_cpuimx25.c170
-rw-r--r--arch/arm/mach-imx/mach-imx27_visstrim_m10.c269
-rw-r--r--arch/arm/mach-imx/mach-imx27ipcam.c78
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c84
-rw-r--r--arch/arm/mach-imx/mach-kzm_arm11_01.c278
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c161
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c312
-rw-r--r--arch/arm/mach-imx/mach-mx25_3ds.c258
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c317
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c352
-rw-r--r--arch/arm/mach-imx/mach-mx31_3ds.c772
-rw-r--r--arch/arm/mach-imx/mach-mx31ads.c542
-rw-r--r--arch/arm/mach-imx/mach-mx31lilly.c302
-rw-r--r--arch/arm/mach-imx/mach-mx31lite.c287
-rw-r--r--arch/arm/mach-imx/mach-mx31moboard.c583
-rw-r--r--arch/arm/mach-imx/mach-mx35_3ds.c224
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c274
-rw-r--r--arch/arm/mach-imx/mach-pca100.c442
-rw-r--r--arch/arm/mach-imx/mach-pcm037.c696
-rw-r--r--arch/arm/mach-imx/mach-pcm037_eet.c179
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c356
-rw-r--r--arch/arm/mach-imx/mach-pcm043.c423
-rw-r--r--arch/arm/mach-imx/mach-qong.c269
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c155
-rw-r--r--arch/arm/mach-imx/mach-vpr200.c322
-rw-r--r--arch/arm/mach-imx/mm-imx1.c58
-rw-r--r--arch/arm/mach-imx/mm-imx21.c86
-rw-r--r--arch/arm/mach-imx/mm-imx25.c72
-rw-r--r--arch/arm/mach-imx/mm-imx27.c86
-rw-r--r--arch/arm/mach-imx/mm-imx31.c66
-rw-r--r--arch/arm/mach-imx/mm-imx35.c63
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq-ksym.c18
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq.S35
-rw-r--r--arch/arm/mach-imx/mx31lilly-db.c216
-rw-r--r--arch/arm/mach-imx/mx31lite-db.c203
-rw-r--r--arch/arm/mach-imx/mx31moboard-devboard.c242
-rw-r--r--arch/arm/mach-imx/mx31moboard-marxbot.c366
-rw-r--r--arch/arm/mach-imx/mx31moboard-smartbot.c209
-rw-r--r--arch/arm/mach-imx/pcm037.h11
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c231
-rw-r--r--arch/arm/mach-imx/pm-imx27.c49
-rw-r--r--arch/arm/mach-integrator/Kconfig37
-rw-r--r--arch/arm/mach-integrator/Makefile14
-rw-r--r--arch/arm/mach-integrator/Makefile.boot4
-rw-r--r--arch/arm/mach-integrator/common.h2
-rw-r--r--arch/arm/mach-integrator/core.c236
-rw-r--r--arch/arm/mach-integrator/cpu.c224
-rw-r--r--arch/arm/mach-integrator/impd1.c482
-rw-r--r--arch/arm/mach-integrator/include/mach/bits.h61
-rw-r--r--arch/arm/mach-integrator/include/mach/clkdev.h26
-rw-r--r--arch/arm/mach-integrator/include/mach/cm.h36
-rw-r--r--arch/arm/mach-integrator/include/mach/debug-macro.S20
-rw-r--r--arch/arm/mach-integrator/include/mach/entry-macro.S45
-rw-r--r--arch/arm/mach-integrator/include/mach/hardware.h52
-rw-r--r--arch/arm/mach-integrator/include/mach/impd1.h18
-rw-r--r--arch/arm/mach-integrator/include/mach/io.h36
-rw-r--r--arch/arm/mach-integrator/include/mach/irqs.h82
-rw-r--r--arch/arm/mach-integrator/include/mach/lm.h23
-rw-r--r--arch/arm/mach-integrator/include/mach/memory.h34
-rw-r--r--arch/arm/mach-integrator/include/mach/platform.h414
-rw-r--r--arch/arm/mach-integrator/include/mach/system.h44
-rw-r--r--arch/arm/mach-integrator/include/mach/timex.h26
-rw-r--r--arch/arm/mach-integrator/include/mach/uncompress.h50
-rw-r--r--arch/arm/mach-integrator/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c467
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c502
-rw-r--r--arch/arm/mach-integrator/leds.c91
-rw-r--r--arch/arm/mach-integrator/lm.c99
-rw-r--r--arch/arm/mach-integrator/pci.c124
-rw-r--r--arch/arm/mach-integrator/pci_v3.c609
-rw-r--r--arch/arm/mach-iop13xx/Kconfig20
-rw-r--r--arch/arm/mach-iop13xx/Makefile13
-rw-r--r--arch/arm/mach-iop13xx/Makefile.boot3
-rw-r--r--arch/arm/mach-iop13xx/include/mach/adma.h647
-rw-r--r--arch/arm/mach-iop13xx/include/mach/debug-macro.S24
-rw-r--r--arch/arm/mach-iop13xx/include/mach/entry-macro.S45
-rw-r--r--arch/arm/mach-iop13xx/include/mach/hardware.h28
-rw-r--r--arch/arm/mach-iop13xx/include/mach/io.h41
-rw-r--r--arch/arm/mach-iop13xx/include/mach/iop13xx.h526
-rw-r--r--arch/arm/mach-iop13xx/include/mach/iq81340.h28
-rw-r--r--arch/arm/mach-iop13xx/include/mach/irqs.h196
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h72
-rw-r--r--arch/arm/mach-iop13xx/include/mach/msi.h11
-rw-r--r--arch/arm/mach-iop13xx/include/mach/pci.h57
-rw-r--r--arch/arm/mach-iop13xx/include/mach/system.h27
-rw-r--r--arch/arm/mach-iop13xx/include/mach/time.h123
-rw-r--r--arch/arm/mach-iop13xx/include/mach/timex.h1
-rw-r--r--arch/arm/mach-iop13xx/include/mach/uncompress.h23
-rw-r--r--arch/arm/mach-iop13xx/include/mach/vmalloc.h4
-rw-r--r--arch/arm/mach-iop13xx/io.c113
-rw-r--r--arch/arm/mach-iop13xx/iq81340mc.c99
-rw-r--r--arch/arm/mach-iop13xx/iq81340sc.c101
-rw-r--r--arch/arm/mach-iop13xx/irq.c240
-rw-r--r--arch/arm/mach-iop13xx/msi.c193
-rw-r--r--arch/arm/mach-iop13xx/pci.c1133
-rw-r--r--arch/arm/mach-iop13xx/setup.c608
-rw-r--r--arch/arm/mach-iop13xx/tpmi.c256
-rw-r--r--arch/arm/mach-iop32x/Kconfig46
-rw-r--r--arch/arm/mach-iop32x/Makefile14
-rw-r--r--arch/arm/mach-iop32x/Makefile.boot3
-rw-r--r--arch/arm/mach-iop32x/em7210.c211
-rw-r--r--arch/arm/mach-iop32x/glantank.c215
-rw-r--r--arch/arm/mach-iop32x/include/mach/adma.h5
-rw-r--r--arch/arm/mach-iop32x/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-iop32x/include/mach/entry-macro.S36
-rw-r--r--arch/arm/mach-iop32x/include/mach/glantank.h13
-rw-r--r--arch/arm/mach-iop32x/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-iop32x/include/mach/hardware.h44
-rw-r--r--arch/arm/mach-iop32x/include/mach/io.h27
-rw-r--r--arch/arm/mach-iop32x/include/mach/iop32x.h35
-rw-r--r--arch/arm/mach-iop32x/include/mach/iq31244.h17
-rw-r--r--arch/arm/mach-iop32x/include/mach/iq80321.h17
-rw-r--r--arch/arm/mach-iop32x/include/mach/irqs.h50
-rw-r--r--arch/arm/mach-iop32x/include/mach/memory.h13
-rw-r--r--arch/arm/mach-iop32x/include/mach/n2100.h19
-rw-r--r--arch/arm/mach-iop32x/include/mach/system.h34
-rw-r--r--arch/arm/mach-iop32x/include/mach/time.h4
-rw-r--r--arch/arm/mach-iop32x/include/mach/timex.h6
-rw-r--r--arch/arm/mach-iop32x/include/mach/uncompress.h39
-rw-r--r--arch/arm/mach-iop32x/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-iop32x/iq31244.c335
-rw-r--r--arch/arm/mach-iop32x/iq80321.c194
-rw-r--r--arch/arm/mach-iop32x/irq.c74
-rw-r--r--arch/arm/mach-iop32x/n2100.c335
-rw-r--r--arch/arm/mach-iop33x/Kconfig21
-rw-r--r--arch/arm/mach-iop33x/Makefile11
-rw-r--r--arch/arm/mach-iop33x/Makefile.boot3
-rw-r--r--arch/arm/mach-iop33x/include/mach/adma.h5
-rw-r--r--arch/arm/mach-iop33x/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-iop33x/include/mach/entry-macro.S37
-rw-r--r--arch/arm/mach-iop33x/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-iop33x/include/mach/hardware.h46
-rw-r--r--arch/arm/mach-iop33x/include/mach/io.h27
-rw-r--r--arch/arm/mach-iop33x/include/mach/iop33x.h41
-rw-r--r--arch/arm/mach-iop33x/include/mach/iq80331.h16
-rw-r--r--arch/arm/mach-iop33x/include/mach/iq80332.h16
-rw-r--r--arch/arm/mach-iop33x/include/mach/irqs.h60
-rw-r--r--arch/arm/mach-iop33x/include/mach/memory.h13
-rw-r--r--arch/arm/mach-iop33x/include/mach/system.h23
-rw-r--r--arch/arm/mach-iop33x/include/mach/time.h4
-rw-r--r--arch/arm/mach-iop33x/include/mach/timex.h6
-rw-r--r--arch/arm/mach-iop33x/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-iop33x/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-iop33x/iq80331.c149
-rw-r--r--arch/arm/mach-iop33x/iq80332.c149
-rw-r--r--arch/arm/mach-iop33x/irq.c118
-rw-r--r--arch/arm/mach-iop33x/uart.c104
-rw-r--r--arch/arm/mach-ixp2000/Kconfig72
-rw-r--r--arch/arm/mach-ixp2000/Makefile14
-rw-r--r--arch/arm/mach-ixp2000/Makefile.boot3
-rw-r--r--arch/arm/mach-ixp2000/core.c516
-rw-r--r--arch/arm/mach-ixp2000/enp2611.c263
-rw-r--r--arch/arm/mach-ixp2000/include/mach/debug-macro.S25
-rw-r--r--arch/arm/mach-ixp2000/include/mach/enp2611.h46
-rw-r--r--arch/arm/mach-ixp2000/include/mach/entry-macro.S60
-rw-r--r--arch/arm/mach-ixp2000/include/mach/gpio.h48
-rw-r--r--arch/arm/mach-ixp2000/include/mach/hardware.h44
-rw-r--r--arch/arm/mach-ixp2000/include/mach/io.h134
-rw-r--r--arch/arm/mach-ixp2000/include/mach/irqs.h207
-rw-r--r--arch/arm/mach-ixp2000/include/mach/ixdp2x00.h92
-rw-r--r--arch/arm/mach-ixp2000/include/mach/ixdp2x01.h57
-rw-r--r--arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h451
-rw-r--r--arch/arm/mach-ixp2000/include/mach/memory.h31
-rw-r--r--arch/arm/mach-ixp2000/include/mach/platform.h152
-rw-r--r--arch/arm/mach-ixp2000/include/mach/system.h49
-rw-r--r--arch/arm/mach-ixp2000/include/mach/timex.h13
-rw-r--r--arch/arm/mach-ixp2000/include/mach/uncompress.h47
-rw-r--r--arch/arm/mach-ixp2000/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-ixp2000/ixdp2400.c179
-rw-r--r--arch/arm/mach-ixp2000/ixdp2800.c294
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c307
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c451
-rw-r--r--arch/arm/mach-ixp2000/pci.c246
-rw-r--r--arch/arm/mach-ixp23xx/Kconfig25
-rw-r--r--arch/arm/mach-ixp23xx/Makefile11
-rw-r--r--arch/arm/mach-ixp23xx/Makefile.boot2
-rw-r--r--arch/arm/mach-ixp23xx/core.c446
-rw-r--r--arch/arm/mach-ixp23xx/espresso.c93
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/debug-macro.S25
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/entry-macro.S37
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/hardware.h36
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/io.h52
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/irqs.h223
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/ixdp2351.h89
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/ixp23xx.h298
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/memory.h34
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/platform.h57
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/system.h33
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/time.h3
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/timex.h7
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/uncompress.h40
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-ixp23xx/ixdp2351.c336
-rw-r--r--arch/arm/mach-ixp23xx/pci.c288
-rw-r--r--arch/arm/mach-ixp23xx/roadrunner.c179
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig226
-rw-r--r--arch/arm/mach-ixp4xx/Makefile39
-rw-r--r--arch/arm/mach-ixp4xx/Makefile.boot3
-rw-r--r--arch/arm/mach-ixp4xx/avila-pci.c82
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c189
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c493
-rw-r--r--arch/arm/mach-ixp4xx/common.c502
-rw-r--r--arch/arm/mach-ixp4xx/coyote-pci.c65
-rw-r--r--arch/arm/mach-ixp4xx/coyote-setup.c134
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-pci.c80
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-setup.c287
-rw-r--r--arch/arm/mach-ixp4xx/fsg-pci.c76
-rw-r--r--arch/arm/mach-ixp4xx/fsg-setup.c279
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-setup.c105
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c504
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c85
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-setup.c174
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/cpu.h57
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/debug-macro.S26
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/entry-macro.S47
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/gpio.h76
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/hardware.h43
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/io.h526
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/irqs.h75
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h78
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h660
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/memory.h21
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/npe.h39
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/platform.h173
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/qmgr.h204
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/system.h44
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/timex.h16
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/udc.h8
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/uncompress.h57
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c78
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c295
-rw-r--r--arch/arm/mach-ixp4xx/ixdpg425-pci.c59
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_npe.c735
-rw-r--r--arch/arm/mach-ixp4xx/ixp4xx_qmgr.c382
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-pci.c76
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-setup.c322
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-pci.c72
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-setup.c308
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-pci.c73
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-setup.c244
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-pci.c63
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-setup.c106
-rw-r--r--arch/arm/mach-kirkwood/Kconfig135
-rw-r--r--arch/arm/mach-kirkwood/Makefile22
-rw-r--r--arch/arm/mach-kirkwood/Makefile.boot3
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c153
-rw-r--r--arch/arm/mach-kirkwood/common.c537
-rw-r--r--arch/arm/mach-kirkwood/common.h59
-rw-r--r--arch/arm/mach-kirkwood/cpuidle.c96
-rw-r--r--arch/arm/mach-kirkwood/d2net_v2-setup.c230
-rw-r--r--arch/arm/mach-kirkwood/db88f6281-bp-setup.c106
-rw-r--r--arch/arm/mach-kirkwood/dockstar-setup.c111
-rw-r--r--arch/arm/mach-kirkwood/guruplug-setup.c130
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h64
-rw-r--r--arch/arm/mach-kirkwood/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-kirkwood/include/mach/entry-macro.S40
-rw-r--r--arch/arm/mach-kirkwood/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-kirkwood/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-kirkwood/include/mach/io.h51
-rw-r--r--arch/arm/mach-kirkwood/include/mach/irqs.h65
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h138
-rw-r--r--arch/arm/mach-kirkwood/include/mach/leds-netxbig.h55
-rw-r--r--arch/arm/mach-kirkwood/include/mach/leds-ns2.h26
-rw-r--r--arch/arm/mach-kirkwood/include/mach/memory.h10
-rw-r--r--arch/arm/mach-kirkwood/include/mach/system.h36
-rw-r--r--arch/arm/mach-kirkwood/include/mach/timex.h10
-rw-r--r--arch/arm/mach-kirkwood/include/mach/uncompress.h47
-rw-r--r--arch/arm/mach-kirkwood/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-kirkwood/irq.c49
-rw-r--r--arch/arm/mach-kirkwood/lacie_v2-common.c113
-rw-r--r--arch/arm/mach-kirkwood/lacie_v2-common.h16
-rw-r--r--arch/arm/mach-kirkwood/mpp.c44
-rw-r--r--arch/arm/mach-kirkwood/mpp.h347
-rw-r--r--arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c172
-rw-r--r--arch/arm/mach-kirkwood/netspace_v2-setup.c290
-rw-r--r--arch/arm/mach-kirkwood/netxbig_v2-setup.c420
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c248
-rw-r--r--arch/arm/mach-kirkwood/pcie.c282
-rw-r--r--arch/arm/mach-kirkwood/rd88f6192-nas-setup.c88
-rw-r--r--arch/arm/mach-kirkwood/rd88f6281-setup.c124
-rw-r--r--arch/arm/mach-kirkwood/sheevaplug-setup.c159
-rw-r--r--arch/arm/mach-kirkwood/t5325-setup.c210
-rw-r--r--arch/arm/mach-kirkwood/ts219-setup.c141
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c185
-rw-r--r--arch/arm/mach-kirkwood/tsx1x-common.c113
-rw-r--r--arch/arm/mach-kirkwood/tsx1x-common.h7
-rw-r--r--arch/arm/mach-ks8695/Kconfig26
-rw-r--r--arch/arm/mach-ks8695/Makefile20
-rw-r--r--arch/arm/mach-ks8695/Makefile.boot8
-rw-r--r--arch/arm/mach-ks8695/board-acs5k.c231
-rw-r--r--arch/arm/mach-ks8695/board-dsm320.c129
-rw-r--r--arch/arm/mach-ks8695/board-micrel.c61
-rw-r--r--arch/arm/mach-ks8695/cpu.c73
-rw-r--r--arch/arm/mach-ks8695/devices.c217
-rw-r--r--arch/arm/mach-ks8695/generic.h15
-rw-r--r--arch/arm/mach-ks8695/gpio.c319
-rw-r--r--arch/arm/mach-ks8695/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-ks8695/include/mach/devices.h37
-rw-r--r--arch/arm/mach-ks8695/include/mach/entry-macro.S53
-rw-r--r--arch/arm/mach-ks8695/include/mach/gpio.h57
-rw-r--r--arch/arm/mach-ks8695/include/mach/hardware.h54
-rw-r--r--arch/arm/mach-ks8695/include/mach/io.h19
-rw-r--r--arch/arm/mach-ks8695/include/mach/irqs.h54
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h55
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-gpio.h55
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-hpna.h25
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-irq.h41
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-lan.h65
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-mem.h89
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-misc.h97
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-pci.h53
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-switch.h66
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-sys.h34
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-timer.h40
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-uart.h92
-rw-r--r--arch/arm/mach-ks8695/include/mach/regs-wan.h65
-rw-r--r--arch/arm/mach-ks8695/include/mach/system.h48
-rw-r--r--arch/arm/mach-ks8695/include/mach/timex.h21
-rw-r--r--arch/arm/mach-ks8695/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-ks8695/include/mach/vmalloc.h19
-rw-r--r--arch/arm/mach-ks8695/irq.c177
-rw-r--r--arch/arm/mach-ks8695/leds.c93
-rw-r--r--arch/arm/mach-ks8695/pci.c329
-rw-r--r--arch/arm/mach-ks8695/time.c111
-rw-r--r--arch/arm/mach-l7200/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-loki/Kconfig13
-rw-r--r--arch/arm/mach-loki/Makefile3
-rw-r--r--arch/arm/mach-loki/Makefile.boot3
-rw-r--r--arch/arm/mach-loki/addr-map.c122
-rw-r--r--arch/arm/mach-loki/common.c162
-rw-r--r--arch/arm/mach-loki/common.h37
-rw-r--r--arch/arm/mach-loki/include/mach/bridge-regs.h28
-rw-r--r--arch/arm/mach-loki/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-loki/include/mach/entry-macro.S30
-rw-r--r--arch/arm/mach-loki/include/mach/hardware.h15
-rw-r--r--arch/arm/mach-loki/include/mach/io.h26
-rw-r--r--arch/arm/mach-loki/include/mach/irqs.h58
-rw-r--r--arch/arm/mach-loki/include/mach/loki.h83
-rw-r--r--arch/arm/mach-loki/include/mach/memory.h10
-rw-r--r--arch/arm/mach-loki/include/mach/system.h36
-rw-r--r--arch/arm/mach-loki/include/mach/timex.h11
-rw-r--r--arch/arm/mach-loki/include/mach/uncompress.h47
-rw-r--r--arch/arm/mach-loki/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-loki/irq.c22
-rw-r--r--arch/arm/mach-loki/lb88rc8480-setup.c99
-rw-r--r--arch/arm/mach-lpc32xx/Kconfig33
-rw-r--r--arch/arm/mach-lpc32xx/Makefile8
-rw-r--r--arch/arm/mach-lpc32xx/Makefile.boot4
-rw-r--r--arch/arm/mach-lpc32xx/clock.c1136
-rw-r--r--arch/arm/mach-lpc32xx/clock.h38
-rw-r--r--arch/arm/mach-lpc32xx/common.c271
-rw-r--r--arch/arm/mach-lpc32xx/common.h73
-rw-r--r--arch/arm/mach-lpc32xx/gpiolib.c446
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/clkdev.h25
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/debug-macro.S29
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/entry-macro.S47
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/gpio.h74
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/hardware.h34
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/i2c.h63
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/io.h27
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/irqs.h117
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/memory.h27
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/platform.h694
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/system.h52
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/timex.h28
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/uncompress.h60
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/vmalloc.h24
-rw-r--r--arch/arm/mach-lpc32xx/irq.c447
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c390
-rw-r--r--arch/arm/mach-lpc32xx/pm.c146
-rw-r--r--arch/arm/mach-lpc32xx/serial.c208
-rw-r--r--arch/arm/mach-lpc32xx/suspend.S151
-rw-r--r--arch/arm/mach-lpc32xx/timer.c168
-rw-r--r--arch/arm/mach-mmp/Kconfig99
-rw-r--r--arch/arm/mach-mmp/Makefile21
-rw-r--r--arch/arm/mach-mmp/Makefile.boot1
-rw-r--r--arch/arm/mach-mmp/aspenite.c253
-rw-r--r--arch/arm/mach-mmp/avengers_lite.c48
-rw-r--r--arch/arm/mach-mmp/brownstone.c204
-rw-r--r--arch/arm/mach-mmp/clock.c90
-rw-r--r--arch/arm/mach-mmp/clock.h70
-rw-r--r--arch/arm/mach-mmp/common.c47
-rw-r--r--arch/arm/mach-mmp/common.h8
-rw-r--r--arch/arm/mach-mmp/devices.c69
-rw-r--r--arch/arm/mach-mmp/flint.c124
-rw-r--r--arch/arm/mach-mmp/include/mach/addr-map.h34
-rw-r--r--arch/arm/mach-mmp/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-mmp/include/mach/cputype.h55
-rw-r--r--arch/arm/mach-mmp/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-mmp/include/mach/devices.h53
-rw-r--r--arch/arm/mach-mmp/include/mach/dma.h13
-rw-r--r--arch/arm/mach-mmp/include/mach/entry-macro.S30
-rw-r--r--arch/arm/mach-mmp/include/mach/gpio.h36
-rw-r--r--arch/arm/mach-mmp/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-mmp/include/mach/io.h21
-rw-r--r--arch/arm/mach-mmp/include/mach/irqs.h229
-rw-r--r--arch/arm/mach-mmp/include/mach/memory.h14
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-mmp2.h395
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa168.h308
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp-pxa910.h170
-rw-r--r--arch/arm/mach-mmp/include/mach/mfp.h34
-rw-r--r--arch/arm/mach-mmp/include/mach/mmp2.h89
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa168.h120
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h79
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h121
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apmu.h50
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-icu.h71
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-smc.h37
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-timers.h44
-rw-r--r--arch/arm/mach-mmp/include/mach/system.h26
-rw-r--r--arch/arm/mach-mmp/include/mach/teton_bga.h27
-rw-r--r--arch/arm/mach-mmp/include/mach/timex.h13
-rw-r--r--arch/arm/mach-mmp/include/mach/uncompress.h51
-rw-r--r--arch/arm/mach-mmp/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-mmp/irq-mmp2.c157
-rw-r--r--arch/arm/mach-mmp/irq-pxa168.c54
-rw-r--r--arch/arm/mach-mmp/jasper.c179
-rw-r--r--arch/arm/mach-mmp/mmp2.c229
-rw-r--r--arch/arm/mach-mmp/pxa168.c165
-rw-r--r--arch/arm/mach-mmp/pxa910.c182
-rw-r--r--arch/arm/mach-mmp/tavorevb.c106
-rw-r--r--arch/arm/mach-mmp/teton_bga.c89
-rw-r--r--arch/arm/mach-mmp/time.c189
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c133
-rw-r--r--arch/arm/mach-msm/Kconfig213
-rw-r--r--arch/arm/mach-msm/Makefile39
-rw-r--r--arch/arm/mach-msm/Makefile.boot3
-rw-r--r--arch/arm/mach-msm/acpuclock-arm11.c525
-rw-r--r--arch/arm/mach-msm/acpuclock.h32
-rw-r--r--arch/arm/mach-msm/board-halibut.c102
-rw-r--r--arch/arm/mach-msm/board-mahimahi.c83
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c162
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c130
-rw-r--r--arch/arm/mach-msm/board-msm8960.c91
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c93
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c209
-rw-r--r--arch/arm/mach-msm/board-sapphire.c114
-rw-r--r--arch/arm/mach-msm/board-trout-gpio.c233
-rw-r--r--arch/arm/mach-msm/board-trout-mmc.c186
-rw-r--r--arch/arm/mach-msm/board-trout-panel.c297
-rw-r--r--arch/arm/mach-msm/board-trout.c102
-rw-r--r--arch/arm/mach-msm/board-trout.h162
-rw-r--r--arch/arm/mach-msm/clock-7x30.h155
-rw-r--r--arch/arm/mach-msm/clock-debug.c130
-rw-r--r--arch/arm/mach-msm/clock-pcom.c138
-rw-r--r--arch/arm/mach-msm/clock-pcom.h140
-rw-r--r--arch/arm/mach-msm/clock.c184
-rw-r--r--arch/arm/mach-msm/clock.h72
-rw-r--r--arch/arm/mach-msm/devices-iommu.c911
-rw-r--r--arch/arm/mach-msm/devices-msm7x00.c465
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c210
-rw-r--r--arch/arm/mach-msm/devices-msm8960.c85
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c373
-rw-r--r--arch/arm/mach-msm/devices.h58
-rw-r--r--arch/arm/mach-msm/dma.c271
-rw-r--r--arch/arm/mach-msm/gpio-v2.c433
-rw-r--r--arch/arm/mach-msm/gpio.c376
-rw-r--r--arch/arm/mach-msm/gpio_hw.h278
-rw-r--r--arch/arm/mach-msm/gpiomux-8x50.c51
-rw-r--r--arch/arm/mach-msm/gpiomux-8x60.c19
-rw-r--r--arch/arm/mach-msm/gpiomux-v1.c33
-rw-r--r--arch/arm/mach-msm/gpiomux-v1.h67
-rw-r--r--arch/arm/mach-msm/gpiomux-v2.c25
-rw-r--r--arch/arm/mach-msm/gpiomux-v2.h61
-rw-r--r--arch/arm/mach-msm/gpiomux.c96
-rw-r--r--arch/arm/mach-msm/gpiomux.h114
-rw-r--r--arch/arm/mach-msm/headsmp.S40
-rw-r--r--arch/arm/mach-msm/hotplug.c91
-rw-r--r--arch/arm/mach-msm/idle.S36
-rw-r--r--arch/arm/mach-msm/include/mach/board.h50
-rw-r--r--arch/arm/mach-msm/include/mach/clk.h40
-rw-r--r--arch/arm/mach-msm/include/mach/clkdev.h19
-rw-r--r--arch/arm/mach-msm/include/mach/cpu.h54
-rw-r--r--arch/arm/mach-msm/include/mach/debug-macro.S53
-rw-r--r--arch/arm/mach-msm/include/mach/dma.h177
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro-qgic.S88
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro-vic.S37
-rw-r--r--arch/arm/mach-msm/include/mach/entry-macro.S23
-rw-r--r--arch/arm/mach-msm/include/mach/gpio.h26
-rw-r--r--arch/arm/mach-msm/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-msm/include/mach/io.h36
-rw-r--r--arch/arm/mach-msm/include/mach/iommu.h120
-rw-r--r--arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h1865
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x00.h75
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-7x30.h153
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8960.h277
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x50.h88
-rw-r--r--arch/arm/mach-msm/include/mach/irqs-8x60.h258
-rw-r--r--arch/arm/mach-msm/include/mach/irqs.h42
-rw-r--r--arch/arm/mach-msm/include/mach/memory.h35
-rw-r--r--arch/arm/mach-msm/include/mach/mmc.h37
-rw-r--r--arch/arm/mach-msm/include/mach/msm_fb.h147
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x00.h129
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-7x30.h117
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8960.h48
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x50.h139
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap-8x60.h65
-rw-r--r--arch/arm/mach-msm/include/mach/msm_iomap.h65
-rw-r--r--arch/arm/mach-msm/include/mach/msm_smd.h109
-rw-r--r--arch/arm/mach-msm/include/mach/sirc.h98
-rw-r--r--arch/arm/mach-msm/include/mach/system.h28
-rw-r--r--arch/arm/mach-msm/include/mach/timex.h21
-rw-r--r--arch/arm/mach-msm/include/mach/uncompress.h43
-rw-r--r--arch/arm/mach-msm/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-msm/include/mach/vreg.h29
-rw-r--r--arch/arm/mach-msm/io.c180
-rw-r--r--arch/arm/mach-msm/iommu.c731
-rw-r--r--arch/arm/mach-msm/iommu_dev.c422
-rw-r--r--arch/arm/mach-msm/irq-vic.c363
-rw-r--r--arch/arm/mach-msm/irq.c151
-rw-r--r--arch/arm/mach-msm/last_radio_log.c83
-rw-r--r--arch/arm/mach-msm/platsmp.c168
-rw-r--r--arch/arm/mach-msm/proc_comm.c130
-rw-r--r--arch/arm/mach-msm/proc_comm.h258
-rw-r--r--arch/arm/mach-msm/scm-boot.c39
-rw-r--r--arch/arm/mach-msm/scm-boot.h22
-rw-r--r--arch/arm/mach-msm/scm.c293
-rw-r--r--arch/arm/mach-msm/scm.h25
-rw-r--r--arch/arm/mach-msm/sirc.c172
-rw-r--r--arch/arm/mach-msm/smd.c1041
-rw-r--r--arch/arm/mach-msm/smd_debug.c318
-rw-r--r--arch/arm/mach-msm/smd_private.h403
-rw-r--r--arch/arm/mach-msm/timer.c318
-rw-r--r--arch/arm/mach-msm/vreg.c219
-rw-r--r--arch/arm/mach-mv78xx0/Kconfig25
-rw-r--r--arch/arm/mach-mv78xx0/Makefile4
-rw-r--r--arch/arm/mach-mv78xx0/Makefile.boot3
-rw-r--r--arch/arm/mach-mv78xx0/addr-map.c156
-rw-r--r--arch/arm/mach-mv78xx0/buffalo-wxl-setup.c154
-rw-r--r--arch/arm/mach-mv78xx0/common.c404
-rw-r--r--arch/arm/mach-mv78xx0/common.h53
-rw-r--r--arch/arm/mach-mv78xx0/db78x00-bp-setup.c102
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/bridge-regs.h35
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/debug-macro.S19
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/entry-macro.S47
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/io.h26
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/irqs.h94
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/memory.h10
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/mv78xx0.h121
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/system.h36
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/timex.h9
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/uncompress.h47
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-mv78xx0/irq.c45
-rw-r--r--arch/arm/mach-mv78xx0/mpp.c39
-rw-r--r--arch/arm/mach-mv78xx0/mpp.h341
-rw-r--r--arch/arm/mach-mv78xx0/pcie.c319
-rw-r--r--arch/arm/mach-mv78xx0/rd78x00-masa-setup.c87
-rwxr-xr-xarch/arm/mach-mx5/Kconfig263
-rwxr-xr-xarch/arm/mach-mx5/Makefile28
-rw-r--r--arch/arm/mach-mx5/Makefile.boot9
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51.c304
-rw-r--r--arch/arm/mach-mx5/board-cpuimx51sd.c338
-rwxr-xr-xarch/arm/mach-mx5/board-mx50_rdp.c905
-rw-r--r--arch/arm/mach-mx5/board-mx51_3ds.c196
-rwxr-xr-xarch/arm/mach-mx5/board-mx51_babbage.c832
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikamx.c294
-rw-r--r--arch/arm/mach-mx5/board-mx51_efikasb.c280
-rwxr-xr-xarch/arm/mach-mx5/board-mx53_ard.c520
-rwxr-xr-xarch/arm/mach-mx5/board-mx53_evk.c808
-rwxr-xr-xarch/arm/mach-mx5/board-mx53_loco.c787
-rwxr-xr-xarch/arm/mach-mx5/board-mx53_smd.c855
-rwxr-xr-xarch/arm/mach-mx5/bus_freq.c1064
-rwxr-xr-xarch/arm/mach-mx5/clock-mx51-mx53.c1588
-rwxr-xr-xarch/arm/mach-mx5/clock.c5237
-rwxr-xr-xarch/arm/mach-mx5/clock_mx50.c3608
-rwxr-xr-xarch/arm/mach-mx5/cpu.c292
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx50.c71
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx50.h15
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx51.c96
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx51.h14
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx53.c204
-rwxr-xr-xarch/arm/mach-mx5/cpu_op-mx53.h45
-rw-r--r--arch/arm/mach-mx5/cpu_regulator-mx5.c30
-rwxr-xr-xarch/arm/mach-mx5/crm_regs.h868
-rwxr-xr-xarch/arm/mach-mx5/devices-imx50.h94
-rwxr-xr-xarch/arm/mach-mx5/devices-imx51.h111
-rwxr-xr-xarch/arm/mach-mx5/devices-imx53.h112
-rwxr-xr-xarch/arm/mach-mx5/devices.c283
-rwxr-xr-xarch/arm/mach-mx5/devices.h14
-rw-r--r--arch/arm/mach-mx5/efika.h10
-rw-r--r--arch/arm/mach-mx5/ehci.c156
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c219
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c159
-rwxr-xr-xarch/arm/mach-mx5/imx_bt_rfkill.c169
-rw-r--r--arch/arm/mach-mx5/mm-mx50.c72
-rw-r--r--arch/arm/mach-mx5/mm.c107
-rwxr-xr-xarch/arm/mach-mx5/mx50_ddr_freq.S393
-rwxr-xr-xarch/arm/mach-mx5/mx50_freq.c434
-rw-r--r--arch/arm/mach-mx5/mx50_rdp_pmic_mc13892.c414
-rwxr-xr-xarch/arm/mach-mx5/mx50_suspend.S234
-rwxr-xr-xarch/arm/mach-mx5/mx50_wfi.S132
-rw-r--r--arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c339
-rw-r--r--arch/arm/mach-mx5/mx51_efika.c634
-rwxr-xr-xarch/arm/mach-mx5/mx53_loco_pmic_da9053.c300
-rw-r--r--arch/arm/mach-mx5/mx53_loco_pmic_mc34708.c238
-rwxr-xr-xarch/arm/mach-mx5/mx53_smd_pmic_da9053.c314
-rwxr-xr-xarch/arm/mach-mx5/pm.c281
-rwxr-xr-xarch/arm/mach-mx5/sdram_autogating.c201
-rwxr-xr-xarch/arm/mach-mx5/suspend.S162
-rwxr-xr-xarch/arm/mach-mx5/system.c284
-rwxr-xr-xarch/arm/mach-mx5/usb.h47
-rwxr-xr-xarch/arm/mach-mx5/usb_dr.c352
-rwxr-xr-xarch/arm/mach-mx5/usb_h1.c265
-rwxr-xr-xarch/arm/mach-mx5/usb_h2.c208
-rw-r--r--arch/arm/mach-mx6/Kconfig382
-rw-r--r--arch/arm/mach-mx6/Makefile25
-rw-r--r--arch/arm/mach-mx6/Makefile.boot3
-rw-r--r--arch/arm/mach-mx6/board-mx6dl_arm2.h336
-rw-r--r--arch/arm/mach-mx6/board-mx6dl_hdmidongle.h342
-rw-r--r--arch/arm/mach-mx6/board-mx6dl_sabresd.h406
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c2303
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.h331
-rw-r--r--arch/arm/mach-mx6/board-mx6q_hdmidongle.c800
-rw-r--r--arch/arm/mach-mx6/board-mx6q_hdmidongle.h343
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c1764
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.h376
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabrelite.c1414
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c2046
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.h309
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_arm2.c1313
-rw-r--r--arch/arm/mach-mx6/board-mx6sl_common.h578
-rw-r--r--arch/arm/mach-mx6/board-mx6sl_evk.c1672
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_ntx.c3886
-rwxr-xr-xarch/arm/mach-mx6/board-mx6sl_ntx.h306
-rw-r--r--arch/arm/mach-mx6/board-mx6solo_sabreauto.h377
-rw-r--r--arch/arm/mach-mx6/bus_freq.c842
-rw-r--r--arch/arm/mach-mx6/clock.c5736
-rwxr-xr-xarch/arm/mach-mx6/clock_mx6sl.c4182
-rw-r--r--arch/arm/mach-mx6/cpu.c339
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c371
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.h18
-rw-r--r--arch/arm/mach-mx6/cpu_regulator-mx6.c191
-rw-r--r--arch/arm/mach-mx6/crm_regs.h569
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h265
-rw-r--r--arch/arm/mach-mx6/devices.c91
-rw-r--r--arch/arm/mach-mx6/dummy_gpio.c124
-rw-r--r--arch/arm/mach-mx6/etm.c110
-rw-r--r--arch/arm/mach-mx6/headsmp.S79
-rw-r--r--arch/arm/mach-mx6/irq.c148
-rw-r--r--arch/arm/mach-mx6/localtimer.c35
-rw-r--r--arch/arm/mach-mx6/mm.c145
-rw-r--r--arch/arm/mach-mx6/msi.c151
-rw-r--r--arch/arm/mach-mx6/msi.h26
-rw-r--r--arch/arm/mach-mx6/mx6_anatop_regulator.c615
-rw-r--r--arch/arm/mach-mx6/mx6_ddr_freq.S1010
-rw-r--r--arch/arm/mach-mx6/mx6_fec.c56
-rw-r--r--arch/arm/mach-mx6/mx6_mmdc.c367
-rw-r--r--arch/arm/mach-mx6/mx6_suspend.S1713
-rw-r--r--arch/arm/mach-mx6/mx6_wfi.S156
-rw-r--r--arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c545
-rw-r--r--arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c529
-rw-r--r--arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c531
-rw-r--r--arch/arm/mach-mx6/mx6sl_ddr.S570
-rw-r--r--arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c536
-rwxr-xr-xarch/arm/mach-mx6/mx6sl_ntx_io.c2605
-rwxr-xr-xarch/arm/mach-mx6/mx6sl_ntx_pmic_pfuze100.c471
-rw-r--r--arch/arm/mach-mx6/mx6sl_wfi.S727
-rwxr-xr-xarch/arm/mach-mx6/ntx_hwconfig.h267
-rw-r--r--arch/arm/mach-mx6/pcie.c1161
-rw-r--r--arch/arm/mach-mx6/plat_hotplug.c134
-rw-r--r--arch/arm/mach-mx6/platsmp.c152
-rw-r--r--arch/arm/mach-mx6/pm.c600
-rw-r--r--arch/arm/mach-mx6/regs-anadig.h1011
-rw-r--r--arch/arm/mach-mx6/serial.h76
-rw-r--r--arch/arm/mach-mx6/src-reg.h51
-rw-r--r--arch/arm/mach-mx6/system.c682
-rw-r--r--arch/arm/mach-mx6/usb.h85
-rw-r--r--arch/arm/mach-mx6/usb_dr.c795
-rw-r--r--arch/arm/mach-mx6/usb_h1.c497
-rw-r--r--arch/arm/mach-mx6/usb_h2.c249
-rw-r--r--arch/arm/mach-mx6/usb_h3.c240
-rw-r--r--arch/arm/mach-mxs/Kconfig70
-rw-r--r--arch/arm/mach-mxs/Makefile16
-rw-r--r--arch/arm/mach-mxs/Makefile.boot1
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c560
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c784
-rw-r--r--arch/arm/mach-mxs/clock.c198
-rw-r--r--arch/arm/mach-mxs/devices-mx23.h35
-rw-r--r--arch/arm/mach-mxs/devices-mx28.h51
-rw-r--r--arch/arm/mach-mxs/devices.c90
-rw-r--r--arch/arm/mach-mxs/devices/Kconfig28
-rw-r--r--arch/arm/mach-mxs/devices/Makefile10
-rw-r--r--arch/arm/mach-mxs/devices/amba-duart.c40
-rw-r--r--arch/arm/mach-mxs/devices/platform-auart.c65
-rw-r--r--arch/arm/mach-mxs/devices/platform-dma.c50
-rw-r--r--arch/arm/mach-mxs/devices/platform-fec.c52
-rw-r--r--arch/arm/mach-mxs/devices/platform-flexcan.c51
-rw-r--r--arch/arm/mach-mxs/devices/platform-gpmi-nfc.c90
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-i2c.c52
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c73
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-pwm.c22
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxsfb.c46
-rw-r--r--arch/arm/mach-mxs/gpio.c331
-rw-r--r--arch/arm/mach-mxs/gpio.h34
-rw-r--r--arch/arm/mach-mxs/icoll.c80
-rw-r--r--arch/arm/mach-mxs/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-mxs/include/mach/clock.h62
-rw-r--r--arch/arm/mach-mxs/include/mach/common.h32
-rw-r--r--arch/arm/mach-mxs/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h102
-rw-r--r--arch/arm/mach-mxs/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-mxs/include/mach/gpio.h35
-rw-r--r--arch/arm/mach-mxs/include/mach/gpmi-nfc.h71
-rw-r--r--arch/arm/mach-mxs/include/mach/hardware.h29
-rw-r--r--arch/arm/mach-mxs/include/mach/io.h22
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux-mx23.h355
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux-mx28.h537
-rw-r--r--arch/arm/mach-mxs/include/mach/iomux.h168
-rw-r--r--arch/arm/mach-mxs/include/mach/irqs.h32
-rw-r--r--arch/arm/mach-mxs/include/mach/memory.h24
-rw-r--r--arch/arm/mach-mxs/include/mach/mmc.h18
-rw-r--r--arch/arm/mach-mxs/include/mach/mx23.h169
-rw-r--r--arch/arm/mach-mxs/include/mach/mx28.h225
-rw-r--r--arch/arm/mach-mxs/include/mach/mxs.h111
-rw-r--r--arch/arm/mach-mxs/include/mach/mxsfb.h49
-rw-r--r--arch/arm/mach-mxs/include/mach/system.h27
-rw-r--r--arch/arm/mach-mxs/include/mach/timex.h21
-rw-r--r--arch/arm/mach-mxs/include/mach/uncompress.h77
-rw-r--r--arch/arm/mach-mxs/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-mxs/iomux.c101
-rw-r--r--arch/arm/mach-mxs/mach-mx23evk.c224
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c443
-rw-r--r--arch/arm/mach-mxs/mach-stmp378x_devb.c120
-rw-r--r--arch/arm/mach-mxs/mach-tx28.c183
-rw-r--r--arch/arm/mach-mxs/mm-mx23.c45
-rw-r--r--arch/arm/mach-mxs/mm-mx28.c45
-rw-r--r--arch/arm/mach-mxs/module-tx28.c160
-rw-r--r--arch/arm/mach-mxs/module-tx28.h10
-rw-r--r--arch/arm/mach-mxs/ocotp.c92
-rw-r--r--arch/arm/mach-mxs/pm.c43
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx23.h331
-rw-r--r--arch/arm/mach-mxs/regs-clkctrl-mx28.h486
-rw-r--r--arch/arm/mach-mxs/system.c139
-rw-r--r--arch/arm/mach-mxs/timer.c290
-rw-r--r--arch/arm/mach-netx/Kconfig24
-rw-r--r--arch/arm/mach-netx/Makefile12
-rw-r--r--arch/arm/mach-netx/Makefile.boot2
-rw-r--r--arch/arm/mach-netx/fb.c113
-rw-r--r--arch/arm/mach-netx/fb.h24
-rw-r--r--arch/arm/mach-netx/generic.c189
-rw-r--r--arch/arm/mach-netx/generic.h24
-rw-r--r--arch/arm/mach-netx/include/mach/debug-macro.S36
-rw-r--r--arch/arm/mach-netx/include/mach/entry-macro.S39
-rw-r--r--arch/arm/mach-netx/include/mach/eth.h27
-rw-r--r--arch/arm/mach-netx/include/mach/hardware.h39
-rw-r--r--arch/arm/mach-netx/include/mach/io.h28
-rw-r--r--arch/arm/mach-netx/include/mach/irqs.h70
-rw-r--r--arch/arm/mach-netx/include/mach/memory.h26
-rw-r--r--arch/arm/mach-netx/include/mach/netx-regs.h432
-rw-r--r--arch/arm/mach-netx/include/mach/param.h18
-rw-r--r--arch/arm/mach-netx/include/mach/pfifo.h54
-rw-r--r--arch/arm/mach-netx/include/mach/system.h38
-rw-r--r--arch/arm/mach-netx/include/mach/timex.h20
-rw-r--r--arch/arm/mach-netx/include/mach/uncompress.h76
-rw-r--r--arch/arm/mach-netx/include/mach/vmalloc.h19
-rw-r--r--arch/arm/mach-netx/include/mach/xc.h42
-rw-r--r--arch/arm/mach-netx/nxdb500.c208
-rw-r--r--arch/arm/mach-netx/nxdkn.c101
-rw-r--r--arch/arm/mach-netx/nxeb500hmi.c185
-rw-r--r--arch/arm/mach-netx/pfifo.c68
-rw-r--r--arch/arm/mach-netx/time.c157
-rw-r--r--arch/arm/mach-netx/xc.c257
-rw-r--r--arch/arm/mach-nomadik/Kconfig21
-rw-r--r--arch/arm/mach-nomadik/Makefile19
-rw-r--r--arch/arm/mach-nomadik/Makefile.boot4
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c284
-rw-r--r--arch/arm/mach-nomadik/clock.c75
-rw-r--r--arch/arm/mach-nomadik/clock.h15
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c166
-rw-r--r--arch/arm/mach-nomadik/i2c-8815nhk.c65
-rw-r--r--arch/arm/mach-nomadik/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-nomadik/include/mach/debug-macro.S20
-rw-r--r--arch/arm/mach-nomadik/include/mach/entry-macro.S43
-rw-r--r--arch/arm/mach-nomadik/include/mach/fsmc.h29
-rw-r--r--arch/arm/mach-nomadik/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-nomadik/include/mach/hardware.h90
-rw-r--r--arch/arm/mach-nomadik/include/mach/io.h22
-rw-r--r--arch/arm/mach-nomadik/include/mach/irqs.h82
-rw-r--r--arch/arm/mach-nomadik/include/mach/memory.h28
-rw-r--r--arch/arm/mach-nomadik/include/mach/nand.h16
-rw-r--r--arch/arm/mach-nomadik/include/mach/setup.h22
-rw-r--r--arch/arm/mach-nomadik/include/mach/system.h45
-rw-r--r--arch/arm/mach-nomadik/include/mach/timex.h6
-rw-r--r--arch/arm/mach-nomadik/include/mach/uncompress.h63
-rw-r--r--arch/arm/mach-nomadik/include/mach/vmalloc.h2
-rw-r--r--arch/arm/mach-nuc93x/Kconfig19
-rw-r--r--arch/arm/mach-nuc93x/Makefile14
-rw-r--r--arch/arm/mach-nuc93x/Makefile.boot3
-rw-r--r--arch/arm/mach-nuc93x/clock.c83
-rw-r--r--arch/arm/mach-nuc93x/clock.h36
-rw-r--r--arch/arm/mach-nuc93x/cpu.c135
-rw-r--r--arch/arm/mach-nuc93x/cpu.h48
-rw-r--r--arch/arm/mach-nuc93x/dev.c42
-rw-r--r--arch/arm/mach-nuc93x/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-nuc93x/include/mach/entry-macro.S32
-rw-r--r--arch/arm/mach-nuc93x/include/mach/hardware.h22
-rw-r--r--arch/arm/mach-nuc93x/include/mach/io.h28
-rw-r--r--arch/arm/mach-nuc93x/include/mach/irqs.h59
-rw-r--r--arch/arm/mach-nuc93x/include/mach/map.h139
-rw-r--r--arch/arm/mach-nuc93x/include/mach/memory.h21
-rw-r--r--arch/arm/mach-nuc93x/include/mach/regs-clock.h53
-rw-r--r--arch/arm/mach-nuc93x/include/mach/regs-ebi.h33
-rw-r--r--arch/arm/mach-nuc93x/include/mach/regs-irq.h42
-rw-r--r--arch/arm/mach-nuc93x/include/mach/regs-serial.h52
-rw-r--r--arch/arm/mach-nuc93x/include/mach/regs-timer.h28
-rw-r--r--arch/arm/mach-nuc93x/include/mach/system.h28
-rw-r--r--arch/arm/mach-nuc93x/include/mach/timex.h25
-rw-r--r--arch/arm/mach-nuc93x/include/mach/uncompress.h50
-rw-r--r--arch/arm/mach-nuc93x/include/mach/vmalloc.h23
-rw-r--r--arch/arm/mach-nuc93x/irq.c66
-rw-r--r--arch/arm/mach-nuc93x/mach-nuc932evb.c43
-rw-r--r--arch/arm/mach-nuc93x/nuc932.c65
-rw-r--r--arch/arm/mach-nuc93x/nuc932.h29
-rw-r--r--arch/arm/mach-nuc93x/time.c100
-rw-r--r--arch/arm/mach-omap1/Kconfig245
-rw-r--r--arch/arm/mach-omap1/Makefile67
-rw-r--r--arch/arm/mach-omap1/Makefile.boot3
-rw-r--r--arch/arm/mach-omap1/ams-delta-fiq-handler.S278
-rw-r--r--arch/arm/mach-omap1/ams-delta-fiq.c157
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c398
-rw-r--r--arch/arm/mach-omap1/board-fsample.c398
-rw-r--r--arch/arm/mach-omap1/board-generic.c103
-rw-r--r--arch/arm/mach-omap1/board-h2-mmc.c80
-rw-r--r--arch/arm/mach-omap1/board-h2.c470
-rw-r--r--arch/arm/mach-omap1/board-h2.h38
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c69
-rw-r--r--arch/arm/mach-omap1/board-h3.c458
-rw-r--r--arch/arm/mach-omap1/board-h3.h35
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c620
-rw-r--r--arch/arm/mach-omap1/board-innovator.c468
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c273
-rw-r--r--arch/arm/mach-omap1/board-osk.c592
-rw-r--r--arch/arm/mach-omap1/board-palmte.c284
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c330
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c350
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c359
-rw-r--r--arch/arm/mach-omap1/board-sx1-mmc.c66
-rw-r--r--arch/arm/mach-omap1/board-sx1.c430
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c310
-rw-r--r--arch/arm/mach-omap1/clock.c609
-rw-r--r--arch/arm/mach-omap1/clock.h113
-rw-r--r--arch/arm/mach-omap1/clock_data.c927
-rw-r--r--arch/arm/mach-omap1/devices.c333
-rw-r--r--arch/arm/mach-omap1/dma.c391
-rw-r--r--arch/arm/mach-omap1/flash.c34
-rw-r--r--arch/arm/mach-omap1/fpga.c188
-rw-r--r--arch/arm/mach-omap1/gpio15xx.c99
-rw-r--r--arch/arm/mach-omap1/gpio16xx.c200
-rw-r--r--arch/arm/mach-omap1/gpio7xx.c262
-rw-r--r--arch/arm/mach-omap1/i2c.c35
-rw-r--r--arch/arm/mach-omap1/id.c204
-rw-r--r--arch/arm/mach-omap1/include/mach/ams-delta-fiq.h79
-rw-r--r--arch/arm/mach-omap1/include/mach/camera.h13
-rw-r--r--arch/arm/mach-omap1/include/mach/clkdev.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/debug-macro.S107
-rw-r--r--arch/arm/mach-omap1/include/mach/entry-macro.S46
-rw-r--r--arch/arm/mach-omap1/include/mach/gpio.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/io.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/irqs.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/lcd_dma.h78
-rw-r--r--arch/arm/mach-omap1/include/mach/lcdc.h57
-rw-r--r--arch/arm/mach-omap1/include/mach/memory.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/mtd-xip.h61
-rw-r--r--arch/arm/mach-omap1/include/mach/smp.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/system.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/timex.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/uncompress.h5
-rw-r--r--arch/arm/mach-omap1/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-omap1/io.c183
-rw-r--r--arch/arm/mach-omap1/irq.c247
-rw-r--r--arch/arm/mach-omap1/lcd_dma.c451
-rw-r--r--arch/arm/mach-omap1/leds-h2p2-debug.c167
-rw-r--r--arch/arm/mach-omap1/leds-innovator.c99
-rw-r--r--arch/arm/mach-omap1/leds-osk.c115
-rw-r--r--arch/arm/mach-omap1/leds.c69
-rw-r--r--arch/arm/mach-omap1/leds.h3
-rw-r--r--arch/arm/mach-omap1/mailbox.c198
-rw-r--r--arch/arm/mach-omap1/mcbsp.c410
-rw-r--r--arch/arm/mach-omap1/mux.c471
-rw-r--r--arch/arm/mach-omap1/opp.h28
-rw-r--r--arch/arm/mach-omap1/opp_data.c59
-rw-r--r--arch/arm/mach-omap1/pm.c730
-rw-r--r--arch/arm/mach-omap1/pm.h281
-rw-r--r--arch/arm/mach-omap1/pm_bus.c79
-rw-r--r--arch/arm/mach-omap1/reset.c25
-rw-r--r--arch/arm/mach-omap1/serial.c266
-rw-r--r--arch/arm/mach-omap1/sleep.S366
-rw-r--r--arch/arm/mach-omap1/sram.S58
-rw-r--r--arch/arm/mach-omap1/time.c312
-rw-r--r--arch/arm/mach-omap1/timer32k.c193
-rw-r--r--arch/arm/mach-omap1/usb.c530
-rw-r--r--arch/arm/mach-omap2/Kconfig348
-rw-r--r--arch/arm/mach-omap2/Makefile272
-rw-r--r--arch/arm/mach-omap2/Makefile.boot3
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c266
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c810
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c225
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c774
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c110
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c500
-rw-r--r--arch/arm/mach-omap2/board-apollon.c360
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c652
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c310
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c711
-rw-r--r--arch/arm/mach-omap2/board-flash.c256
-rw-r--r--arch/arm/mach-omap2/board-flash.h30
-rw-r--r--arch/arm/mach-omap2/board-generic.c76
-rw-r--r--arch/arm/mach-omap2/board-h4.c392
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c719
-rw-r--r--arch/arm/mach-omap2/board-ldp.c356
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c725
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c603
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c746
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c230
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c649
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c564
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c453
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c726
-rw-r--r--arch/arm/mach-omap2/board-overo.c621
-rw-r--r--arch/arm/mach-omap2/board-rm680.c169
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c990
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c103
-rw-r--r--arch/arm/mach-omap2/board-rx51.c166
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c62
-rw-r--r--arch/arm/mach-omap2/board-zoom-debugboard.c118
-rw-r--r--arch/arm/mach-omap2/board-zoom-display.c140
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c381
-rw-r--r--arch/arm/mach-omap2/board-zoom.c153
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c146
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpll.c63
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_dpllcore.c173
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_osc.c76
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_sys.c50
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c246
-rw-r--r--arch/arm/mach-omap2/clkt34xx_dpll3m2.c122
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c509
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c340
-rw-r--r--arch/arm/mach-omap2/clkt_iclk.c82
-rw-r--r--arch/arm/mach-omap2/clock.c523
-rw-r--r--arch/arm/mach-omap2/clock.h161
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c1970
-rw-r--r--arch/arm/mach-omap2/clock2430.c59
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c2070
-rw-r--r--arch/arm/mach-omap2/clock2xxx.c73
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h44
-rw-r--r--arch/arm/mach-omap2/clock34xx.c153
-rw-r--r--arch/arm/mach-omap2/clock34xx.h18
-rw-r--r--arch/arm/mach-omap2/clock3517.c126
-rw-r--r--arch/arm/mach-omap2/clock3517.h14
-rw-r--r--arch/arm/mach-omap2/clock36xx.c72
-rw-r--r--arch/arm/mach-omap2/clock36xx.h13
-rw-r--r--arch/arm/mach-omap2/clock3xxx.c101
-rw-r--r--arch/arm/mach-omap2/clock3xxx.h21
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c3576
-rw-r--r--arch/arm/mach-omap2/clock44xx.h20
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c3324
-rw-r--r--arch/arm/mach-omap2/clock_common_data.c45
-rw-r--r--arch/arm/mach-omap2/clockdomain.c890
-rw-r--r--arch/arm/mach-omap2/clockdomain.h197
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c274
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c137
-rw-r--r--arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c868
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c689
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h445
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h812
-rw-r--r--arch/arm/mach-omap2/cm-regbits-44xx.h1524
-rw-r--r--arch/arm/mach-omap2/cm.h25
-rw-r--r--arch/arm/mach-omap2/cm1_44xx.h261
-rw-r--r--arch/arm/mach-omap2/cm2_44xx.h508
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.c557
-rw-r--r--arch/arm/mach-omap2/cm2xxx_3xxx.h155
-rw-r--r--arch/arm/mach-omap2/cm44xx.c52
-rw-r--r--arch/arm/mach-omap2/cm44xx.h32
-rw-r--r--arch/arm/mach-omap2/cminst44xx.c235
-rw-r--r--arch/arm/mach-omap2/cminst44xx.h37
-rw-r--r--arch/arm/mach-omap2/common-board-devices.c163
-rw-r--r--arch/arm/mach-omap2/common-board-devices.h37
-rw-r--r--arch/arm/mach-omap2/common.c142
-rw-r--r--arch/arm/mach-omap2/control.c570
-rw-r--r--arch/arm/mach-omap2/control.h412
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c405
-rw-r--r--arch/arm/mach-omap2/devices.c733
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/mach-omap2/display.c148
-rw-r--r--arch/arm/mach-omap2/dma.c297
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c614
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c84
-rw-r--r--arch/arm/mach-omap2/dsp.c92
-rw-r--r--arch/arm/mach-omap2/emu.c69
-rw-r--r--arch/arm/mach-omap2/gpio.c104
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c126
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c407
-rw-r--r--arch/arm/mach-omap2/gpmc-smc91x.c190
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c107
-rw-r--r--arch/arm/mach-omap2/gpmc.c920
-rw-r--r--arch/arm/mach-omap2/hsmmc.c524
-rw-r--r--arch/arm/mach-omap2/hsmmc.h44
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c63
-rw-r--r--arch/arm/mach-omap2/i2c.c39
-rw-r--r--arch/arm/mach-omap2/id.c559
-rw-r--r--arch/arm/mach-omap2/include/mach/am35xx.h44
-rw-r--r--arch/arm/mach-omap2/include/mach/board-rx51.h11
-rw-r--r--arch/arm/mach-omap2/include/mach/board-zoom.h12
-rw-r--r--arch/arm/mach-omap2/include/mach/clkdev.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h391
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h1409
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h236
-rw-r--r--arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h92
-rw-r--r--arch/arm/mach-omap2/include/mach/debug-macro.S159
-rw-r--r--arch/arm/mach-omap2/include/mach/entry-macro.S170
-rw-r--r--arch/arm/mach-omap2/include/mach/gpio.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/id.h22
-rw-r--r--arch/arm/mach-omap2/include/mach/io.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/irqs.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/memory.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h43
-rw-r--r--arch/arm/mach-omap2/include/mach/smp.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/system.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/timex.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/uncompress.h5
-rw-r--r--arch/arm/mach-omap2/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-omap2/io.c466
-rw-r--r--arch/arm/mach-omap2/io.h7
-rw-r--r--arch/arm/mach-omap2/iommu2.c358
-rw-r--r--arch/arm/mach-omap2/irq.c256
-rw-r--r--arch/arm/mach-omap2/mailbox.c421
-rw-r--r--arch/arm/mach-omap2/mcbsp.c171
-rw-r--r--arch/arm/mach-omap2/mux.c1080
-rw-r--r--arch/arm/mach-omap2/mux.h342
-rw-r--r--arch/arm/mach-omap2/mux2420.c690
-rw-r--r--arch/arm/mach-omap2/mux2420.h282
-rw-r--r--arch/arm/mach-omap2/mux2430.c793
-rw-r--r--arch/arm/mach-omap2/mux2430.h370
-rw-r--r--arch/arm/mach-omap2/mux34xx.c2061
-rw-r--r--arch/arm/mach-omap2/mux34xx.h398
-rw-r--r--arch/arm/mach-omap2/mux44xx.c1356
-rw-r--r--arch/arm/mach-omap2/mux44xx.h298
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S49
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c67
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c165
-rw-r--r--arch/arm/mach-omap2/omap-smp.c143
-rw-r--r--arch/arm/mach-omap2/omap4-common.c113
-rw-r--r--arch/arm/mach-omap2/omap44xx-smc.S57
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c2371
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c2201
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c2741
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c3665
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c5183
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c71
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h25
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.c248
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.h132
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.c299
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.h338
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h96
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c262
-rw-r--r--arch/arm/mach-omap2/omap_twl.c339
-rw-r--r--arch/arm/mach-omap2/opp.c93
-rw-r--r--arch/arm/mach-omap2/opp2420_data.c128
-rw-r--r--arch/arm/mach-omap2/opp2430_data.c133
-rw-r--r--arch/arm/mach-omap2/opp2xxx.h429
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c172
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c105
-rw-r--r--arch/arm/mach-omap2/pm-debug.c655
-rw-r--r--arch/arm/mach-omap2/pm.c270
-rw-r--r--arch/arm/mach-omap2/pm.h143
-rw-r--r--arch/arm/mach-omap2/pm24xx.c524
-rw-r--r--arch/arm/mach-omap2/pm34xx.c970
-rw-r--r--arch/arm/mach-omap2/pm44xx.c121
-rw-r--r--arch/arm/mach-omap2/powerdomain-common.c110
-rw-r--r--arch/arm/mach-omap2/powerdomain.c1001
-rw-r--r--arch/arm/mach-omap2/powerdomain.h230
-rw-r--r--arch/arm/mach-omap2/powerdomain2xxx_3xxx.c241
-rw-r--r--arch/arm/mach-omap2/powerdomain44xx.c225
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c80
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h22
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c123
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c287
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c355
-rw-r--r--arch/arm/mach-omap2/prcm-common.h414
-rw-r--r--arch/arm/mach-omap2/prcm.c167
-rw-r--r--arch/arm/mach-omap2/prcm44xx.h42
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.c45
-rw-r--r--arch/arm/mach-omap2/prcm_mpu44xx.h104
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h283
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h600
-rw-r--r--arch/arm/mach-omap2/prm-regbits-44xx.h2319
-rw-r--r--arch/arm/mach-omap2/prm.h56
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c158
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h429
-rw-r--r--arch/arm/mach-omap2/prm44xx.c195
-rw-r--r--arch/arm/mach-omap2/prm44xx.h778
-rw-r--r--arch/arm/mach-omap2/prminst44xx.c66
-rw-r--r--arch/arm/mach-omap2/prminst44xx.h25
-rw-r--r--arch/arm/mach-omap2/scrm44xx.h175
-rw-r--r--arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h51
-rw-r--r--arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h55
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.c279
-rw-r--r--arch/arm/mach-omap2/sdram-nokia.h12
-rw-r--r--arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h51
-rw-r--r--arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h54
-rw-r--r--arch/arm/mach-omap2/sdrc.c183
-rw-r--r--arch/arm/mach-omap2/sdrc.h77
-rw-r--r--arch/arm/mach-omap2/sdrc2xxx.c170
-rw-r--r--arch/arm/mach-omap2/serial.c877
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S126
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S754
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c59
-rw-r--r--arch/arm/mach-omap2/smartreflex.c1043
-rw-r--r--arch/arm/mach-omap2/smartreflex.h246
-rw-r--r--arch/arm/mach-omap2/sr_device.c147
-rw-r--r--arch/arm/mach-omap2/sram242x.S330
-rw-r--r--arch/arm/mach-omap2/sram243x.S330
-rw-r--r--arch/arm/mach-omap2/sram34xx.S346
-rw-r--r--arch/arm/mach-omap2/timer-gp.c266
-rw-r--r--arch/arm/mach-omap2/timer-gp.h16
-rw-r--r--arch/arm/mach-omap2/timer-mpu.c39
-rw-r--r--arch/arm/mach-omap2/usb-fs.c359
-rw-r--r--arch/arm/mach-omap2/usb-host.c574
-rw-r--r--arch/arm/mach-omap2/usb-musb.c185
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c348
-rw-r--r--arch/arm/mach-omap2/vc.h83
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c63
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c75
-rw-r--r--arch/arm/mach-omap2/voltage.c1106
-rw-r--r--arch/arm/mach-omap2/voltage.h184
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c95
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c102
-rw-r--r--arch/arm/mach-omap2/vp.h143
-rw-r--r--arch/arm/mach-omap2/vp3xxx_data.c82
-rw-r--r--arch/arm/mach-omap2/vp44xx_data.c100
-rw-r--r--arch/arm/mach-omap2/wd_timer.c56
-rw-r--r--arch/arm/mach-omap2/wd_timer.h17
-rw-r--r--arch/arm/mach-orion5x/Kconfig160
-rw-r--r--arch/arm/mach-orion5x/Makefile24
-rw-r--r--arch/arm/mach-orion5x/Makefile.boot3
-rw-r--r--arch/arm/mach-orion5x/addr-map.c206
-rw-r--r--arch/arm/mach-orion5x/common.c325
-rw-r--r--arch/arm/mach-orion5x/common.h63
-rw-r--r--arch/arm/mach-orion5x/d2net-setup.c360
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c367
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c740
-rw-r--r--arch/arm/mach-orion5x/edmini_v2-setup.c261
-rw-r--r--arch/arm/mach-orion5x/include/mach/bridge-regs.h39
-rw-r--r--arch/arm/mach-orion5x/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-orion5x/include/mach/entry-macro.S31
-rw-r--r--arch/arm/mach-orion5x/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-orion5x/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-orion5x/include/mach/io.h58
-rw-r--r--arch/arm/mach-orion5x/include/mach/irqs.h60
-rw-r--r--arch/arm/mach-orion5x/include/mach/memory.h12
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h143
-rw-r--r--arch/arm/mach-orion5x/include/mach/system.h33
-rw-r--r--arch/arm/mach-orion5x/include/mach/timex.h11
-rw-r--r--arch/arm/mach-orion5x/include/mach/uncompress.h49
-rw-r--r--arch/arm/mach-orion5x/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-orion5x/irq.c41
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c403
-rw-r--r--arch/arm/mach-orion5x/ls-chl-setup.c328
-rw-r--r--arch/arm/mach-orion5x/ls_hgl-setup.c275
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c278
-rw-r--r--arch/arm/mach-orion5x/mpp.c45
-rw-r--r--arch/arm/mach-orion5x/mpp.h129
-rw-r--r--arch/arm/mach-orion5x/mss2-setup.c271
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c239
-rw-r--r--arch/arm/mach-orion5x/net2big-setup.c430
-rw-r--r--arch/arm/mach-orion5x/pci.c601
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c179
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c191
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c314
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c132
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c368
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c332
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c321
-rw-r--r--arch/arm/mach-orion5x/ts78xx-fpga.h41
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c630
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.c134
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.h20
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c182
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c270
-rw-r--r--arch/arm/mach-pnx4008/Makefile12
-rw-r--r--arch/arm/mach-pnx4008/Makefile.boot4
-rw-r--r--arch/arm/mach-pnx4008/clock.c1001
-rw-r--r--arch/arm/mach-pnx4008/clock.h43
-rw-r--r--arch/arm/mach-pnx4008/core.c272
-rw-r--r--arch/arm/mach-pnx4008/dma.c1106
-rw-r--r--arch/arm/mach-pnx4008/gpio.c329
-rw-r--r--arch/arm/mach-pnx4008/i2c.c72
-rw-r--r--arch/arm/mach-pnx4008/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-pnx4008/include/mach/clock.h62
-rw-r--r--arch/arm/mach-pnx4008/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-pnx4008/include/mach/dma.h160
-rw-r--r--arch/arm/mach-pnx4008/include/mach/entry-macro.S127
-rw-r--r--arch/arm/mach-pnx4008/include/mach/gpio.h241
-rw-r--r--arch/arm/mach-pnx4008/include/mach/hardware.h32
-rw-r--r--arch/arm/mach-pnx4008/include/mach/i2c.h64
-rw-r--r--arch/arm/mach-pnx4008/include/mach/io.h21
-rw-r--r--arch/arm/mach-pnx4008/include/mach/irq.h42
-rw-r--r--arch/arm/mach-pnx4008/include/mach/irqs.h215
-rw-r--r--arch/arm/mach-pnx4008/include/mach/memory.h21
-rw-r--r--arch/arm/mach-pnx4008/include/mach/param.h21
-rw-r--r--arch/arm/mach-pnx4008/include/mach/platform.h69
-rw-r--r--arch/arm/mach-pnx4008/include/mach/pm.h33
-rw-r--r--arch/arm/mach-pnx4008/include/mach/system.h38
-rw-r--r--arch/arm/mach-pnx4008/include/mach/timex.h19
-rw-r--r--arch/arm/mach-pnx4008/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-pnx4008/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-pnx4008/irq.c122
-rw-r--r--arch/arm/mach-pnx4008/pm.c155
-rw-r--r--arch/arm/mach-pnx4008/serial.c68
-rw-r--r--arch/arm/mach-pnx4008/sleep.S195
-rw-r--r--arch/arm/mach-pnx4008/time.c135
-rw-r--r--arch/arm/mach-pnx4008/time.h70
-rw-r--r--arch/arm/mach-pxa/Kconfig699
-rw-r--r--arch/arm/mach-pxa/Makefile106
-rw-r--r--arch/arm/mach-pxa/Makefile.boot2
-rw-r--r--arch/arm/mach-pxa/am200epd.c387
-rw-r--r--arch/arm/mach-pxa/am300epd.c296
-rw-r--r--arch/arm/mach-pxa/balloon3.c831
-rw-r--r--arch/arm/mach-pxa/capc7117.c156
-rw-r--r--arch/arm/mach-pxa/clock-pxa2xx.c54
-rw-r--r--arch/arm/mach-pxa/clock-pxa3xx.c208
-rw-r--r--arch/arm/mach-pxa/clock.c71
-rw-r--r--arch/arm/mach-pxa/clock.h79
-rw-r--r--arch/arm/mach-pxa/cm-x255.c237
-rw-r--r--arch/arm/mach-pxa/cm-x270.c412
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c197
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.h13
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c521
-rw-r--r--arch/arm/mach-pxa/cm-x300.c865
-rw-r--r--arch/arm/mach-pxa/colibri-evalboard.c119
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270-income.c223
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270.c323
-rw-r--r--arch/arm/mach-pxa/colibri-pxa300.c192
-rw-r--r--arch/arm/mach-pxa/colibri-pxa320.c263
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c151
-rw-r--r--arch/arm/mach-pxa/corgi.c749
-rw-r--r--arch/arm/mach-pxa/corgi_pm.c215
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c494
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c257
-rw-r--r--arch/arm/mach-pxa/csb701.c66
-rw-r--r--arch/arm/mach-pxa/csb726.c281
-rw-r--r--arch/arm/mach-pxa/devices.c1069
-rw-r--r--arch/arm/mach-pxa/devices.h48
-rw-r--r--arch/arm/mach-pxa/em-x270.c1315
-rw-r--r--arch/arm/mach-pxa/eseries.c954
-rw-r--r--arch/arm/mach-pxa/eseries.h16
-rw-r--r--arch/arm/mach-pxa/ezx.c1231
-rw-r--r--arch/arm/mach-pxa/generic.c98
-rw-r--r--arch/arm/mach-pxa/generic.h72
-rw-r--r--arch/arm/mach-pxa/gumstix.c241
-rw-r--r--arch/arm/mach-pxa/h5000.c210
-rw-r--r--arch/arm/mach-pxa/himalaya.c167
-rw-r--r--arch/arm/mach-pxa/hx4700.c879
-rw-r--r--arch/arm/mach-pxa/icontrol.c199
-rw-r--r--arch/arm/mach-pxa/idp.c201
-rw-r--r--arch/arm/mach-pxa/include/mach/addr-map.h48
-rw-r--r--arch/arm/mach-pxa/include/mach/arcom-pcmcia.h11
-rw-r--r--arch/arm/mach-pxa/include/mach/audio.h30
-rw-r--r--arch/arm/mach-pxa/include/mach/balloon3.h183
-rw-r--r--arch/arm/mach-pxa/include/mach/bitfield.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/camera.h44
-rw-r--r--arch/arm/mach-pxa/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-pxa/include/mach/colibri.h69
-rw-r--r--arch/arm/mach-pxa/include/mach/corgi.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/csb726.h26
-rw-r--r--arch/arm/mach-pxa/include/mach/debug-macro.S23
-rw-r--r--arch/arm/mach-pxa/include/mach/dma.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/entry-macro.S51
-rw-r--r--arch/arm/mach-pxa/include/mach/eseries-gpio.h67
-rw-r--r--arch/arm/mach-pxa/include/mach/eseries-irq.h28
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio.h154
-rw-r--r--arch/arm/mach-pxa/include/mach/gumstix.h91
-rw-r--r--arch/arm/mach-pxa/include/mach/h5000.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h346
-rw-r--r--arch/arm/mach-pxa/include/mach/hx4700.h132
-rw-r--r--arch/arm/mach-pxa/include/mach/idp.h199
-rw-r--r--arch/arm/mach-pxa/include/mach/io.h20
-rw-r--r--arch/arm/mach-pxa/include/mach/irda.h25
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h107
-rw-r--r--arch/arm/mach-pxa/include/mach/littleton.h15
-rw-r--r--arch/arm/mach-pxa/include/mach/lpd270.h43
-rw-r--r--arch/arm/mach-pxa/include/mach/lubbock.h53
-rw-r--r--arch/arm/mach-pxa/include/mach/magician.h119
-rw-r--r--arch/arm/mach-pxa/include/mach/mainstone.h139
-rw-r--r--arch/arm/mach-pxa/include/mach/memory.h24
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa25x.h225
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa27x.h465
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h135
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa300.h575
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa320.h461
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h158
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa930.h498
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/mioa701.h72
-rw-r--r--arch/arm/mach-pxa/include/mach/mmc.h28
-rw-r--r--arch/arm/mach-pxa/include/mach/mtd-xip.h36
-rw-r--r--arch/arm/mach-pxa/include/mach/mxm8x10.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/ohci.h36
-rw-r--r--arch/arm/mach-pxa/include/mach/palm27x.h81
-rw-r--r--arch/arm/mach-pxa/include/mach/palmasoc.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/palmld.h109
-rw-r--r--arch/arm/mach-pxa/include/mach/palmt5.h84
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtc.h86
-rw-r--r--arch/arm/mach-pxa/include/mach/palmte2.h68
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtreo.h67
-rw-r--r--arch/arm/mach-pxa/include/mach/palmtx.h112
-rw-r--r--arch/arm/mach-pxa/include/mach/palmz72.h84
-rw-r--r--arch/arm/mach-pxa/include/mach/pata_pxa.h33
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm027.h84
-rw-r--r--arch/arm/mach-pxa/include/mach/pcm990_baseboard.h275
-rw-r--r--arch/arm/mach-pxa/include/mach/pm.h40
-rw-r--r--arch/arm/mach-pxa/include/mach/poodle.h92
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x-udc.h163
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa25x.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x-udc.h257
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x.h22
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-regs.h187
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa300.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa320.h9
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-regs.h205
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h35
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa930.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa930_rotary.h20
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa930_trkball.h10
-rw-r--r--arch/arm/mach-pxa/include/mach/pxafb.h162
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ac97.h101
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-intc.h30
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-lcd.h197
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ost.h34
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-rtc.h23
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-u2d.h200
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-uart.h143
-rw-r--r--arch/arm/mach-pxa/include/mach/reset.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/sharpsl_pm.h113
-rw-r--r--arch/arm/mach-pxa/include/mach/smemc.h74
-rw-r--r--arch/arm/mach-pxa/include/mach/spitz.h189
-rw-r--r--arch/arm/mach-pxa/include/mach/system.h23
-rw-r--r--arch/arm/mach-pxa/include/mach/timex.h34
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h200
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa_bt.h22
-rw-r--r--arch/arm/mach-pxa/include/mach/trizeps4.h162
-rw-r--r--arch/arm/mach-pxa/include/mach/udc.h8
-rw-r--r--arch/arm/mach-pxa/include/mach/uncompress.h79
-rw-r--r--arch/arm/mach-pxa/include/mach/viper.h94
-rw-r--r--arch/arm/mach-pxa/include/mach/vmalloc.h11
-rw-r--r--arch/arm/mach-pxa/include/mach/vpac270.h42
-rw-r--r--arch/arm/mach-pxa/include/mach/z2.h40
-rw-r--r--arch/arm/mach-pxa/include/mach/zeus.h85
-rw-r--r--arch/arm/mach-pxa/include/mach/zylonite.h42
-rw-r--r--arch/arm/mach-pxa/irq.c230
-rw-r--r--arch/arm/mach-pxa/leds-idp.c116
-rw-r--r--arch/arm/mach-pxa/leds-lubbock.c125
-rw-r--r--arch/arm/mach-pxa/leds-mainstone.c120
-rw-r--r--arch/arm/mach-pxa/leds.c32
-rw-r--r--arch/arm/mach-pxa/leds.h13
-rw-r--r--arch/arm/mach-pxa/littleton.c446
-rw-r--r--arch/arm/mach-pxa/lpd270.c508
-rw-r--r--arch/arm/mach-pxa/lubbock.c558
-rw-r--r--arch/arm/mach-pxa/magician.c773
-rw-r--r--arch/arm/mach-pxa/mainstone.c625
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c412
-rw-r--r--arch/arm/mach-pxa/mfp-pxa3xx.c59
-rw-r--r--arch/arm/mach-pxa/mioa701.c799
-rw-r--r--arch/arm/mach-pxa/mioa701_bootresume.S37
-rw-r--r--arch/arm/mach-pxa/mp900.c101
-rw-r--r--arch/arm/mach-pxa/mxm8x10.c474
-rw-r--r--arch/arm/mach-pxa/palm27x.c479
-rw-r--r--arch/arm/mach-pxa/palmld.c350
-rw-r--r--arch/arm/mach-pxa/palmt5.c211
-rw-r--r--arch/arm/mach-pxa/palmtc.c546
-rw-r--r--arch/arm/mach-pxa/palmte2.c364
-rw-r--r--arch/arm/mach-pxa/palmtreo.c458
-rw-r--r--arch/arm/mach-pxa/palmtx.c372
-rw-r--r--arch/arm/mach-pxa/palmz72.c406
-rw-r--r--arch/arm/mach-pxa/pcm027.c267
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c542
-rw-r--r--arch/arm/mach-pxa/pm.c119
-rw-r--r--arch/arm/mach-pxa/poodle.c473
-rw-r--r--arch/arm/mach-pxa/pxa25x.c386
-rw-r--r--arch/arm/mach-pxa/pxa27x.c457
-rw-r--r--arch/arm/mach-pxa/pxa2xx.c55
-rw-r--r--arch/arm/mach-pxa/pxa300.c116
-rw-r--r--arch/arm/mach-pxa/pxa320.c99
-rw-r--r--arch/arm/mach-pxa/pxa3xx-ulpi.c400
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c464
-rw-r--r--arch/arm/mach-pxa/pxa930.c206
-rw-r--r--arch/arm/mach-pxa/pxa95x.c296
-rw-r--r--arch/arm/mach-pxa/raumfeld.c1118
-rw-r--r--arch/arm/mach-pxa/reset.c102
-rw-r--r--arch/arm/mach-pxa/saar.c604
-rw-r--r--arch/arm/mach-pxa/saarb.c113
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c999
-rw-r--r--arch/arm/mach-pxa/sleep.S210
-rw-r--r--arch/arm/mach-pxa/smemc.c58
-rw-r--r--arch/arm/mach-pxa/spitz.c1010
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c260
-rw-r--r--arch/arm/mach-pxa/standby.S114
-rw-r--r--arch/arm/mach-pxa/stargate2.c1019
-rw-r--r--arch/arm/mach-pxa/tavorevb.c497
-rw-r--r--arch/arm/mach-pxa/tavorevb3.c134
-rw-r--r--arch/arm/mach-pxa/time.c178
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c148
-rw-r--r--arch/arm/mach-pxa/tosa.c979
-rw-r--r--arch/arm/mach-pxa/trizeps4.c571
-rw-r--r--arch/arm/mach-pxa/viper.c1000
-rw-r--r--arch/arm/mach-pxa/vpac270.c724
-rw-r--r--arch/arm/mach-pxa/xcep.c190
-rw-r--r--arch/arm/mach-pxa/z2.c709
-rw-r--r--arch/arm/mach-pxa/zeus.c914
-rw-r--r--arch/arm/mach-pxa/zylonite.c431
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa300.c280
-rw-r--r--arch/arm/mach-pxa/zylonite_pxa320.c215
-rw-r--r--arch/arm/mach-realview/Kconfig98
-rw-r--r--arch/arm/mach-realview/Makefile12
-rw-r--r--arch/arm/mach-realview/Makefile.boot9
-rw-r--r--arch/arm/mach-realview/core.c536
-rw-r--r--arch/arm/mach-realview/core.h70
-rw-r--r--arch/arm/mach-realview/hotplug.c127
-rw-r--r--arch/arm/mach-realview/include/mach/barriers.h8
-rw-r--r--arch/arm/mach-realview/include/mach/board-eb.h94
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb1176.h82
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb11mp.h96
-rw-r--r--arch/arm/mach-realview/include/mach/board-pba8.h73
-rw-r--r--arch/arm/mach-realview/include/mach/board-pbx.h108
-rw-r--r--arch/arm/mach-realview/include/mach/clkdev.h16
-rw-r--r--arch/arm/mach-realview/include/mach/debug-macro.S42
-rw-r--r--arch/arm/mach-realview/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-realview/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-realview/include/mach/hardware.h42
-rw-r--r--arch/arm/mach-realview/include/mach/io.h28
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-eb.h129
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-pb1176.h100
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-pb11mp.h122
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-pba8.h94
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-pbx.h109
-rw-r--r--arch/arm/mach-realview/include/mach/irqs.h40
-rw-r--r--arch/arm/mach-realview/include/mach/memory.h75
-rw-r--r--arch/arm/mach-realview/include/mach/platform.h249
-rw-r--r--arch/arm/mach-realview/include/mach/system.h49
-rw-r--r--arch/arm/mach-realview/include/mach/timex.h23
-rw-r--r--arch/arm/mach-realview/include/mach/uncompress.h78
-rw-r--r--arch/arm/mach-realview/include/mach/vmalloc.h21
-rw-r--r--arch/arm/mach-realview/platsmp.c90
-rw-r--r--arch/arm/mach-realview/realview_eb.c473
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c368
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c370
-rw-r--r--arch/arm/mach-realview/realview_pba8.c320
-rw-r--r--arch/arm/mach-realview/realview_pbx.c403
-rw-r--r--arch/arm/mach-rpc/Makefile11
-rw-r--r--arch/arm/mach-rpc/Makefile.boot4
-rw-r--r--arch/arm/mach-rpc/dma.c389
-rw-r--r--arch/arm/mach-rpc/include/mach/acornfb.h140
-rw-r--r--arch/arm/mach-rpc/include/mach/debug-macro.S23
-rw-r--r--arch/arm/mach-rpc/include/mach/entry-macro.S16
-rw-r--r--arch/arm/mach-rpc/include/mach/hardware.h83
-rw-r--r--arch/arm/mach-rpc/include/mach/io.h213
-rw-r--r--arch/arm/mach-rpc/include/mach/irqs.h47
-rw-r--r--arch/arm/mach-rpc/include/mach/isa-dma.h29
-rw-r--r--arch/arm/mach-rpc/include/mach/memory.h40
-rw-r--r--arch/arm/mach-rpc/include/mach/system.h27
-rw-r--r--arch/arm/mach-rpc/include/mach/timex.h17
-rw-r--r--arch/arm/mach-rpc/include/mach/uncompress.h196
-rw-r--r--arch/arm/mach-rpc/include/mach/vmalloc.h10
-rw-r--r--arch/arm/mach-rpc/irq.c162
-rw-r--r--arch/arm/mach-rpc/riscpc.c227
-rw-r--r--arch/arm/mach-s3c2400/Kconfig7
-rw-r--r--arch/arm/mach-s3c2400/Makefile15
-rw-r--r--arch/arm/mach-s3c2400/gpio.c42
-rw-r--r--arch/arm/mach-s3c2400/include/mach/map.h66
-rw-r--r--arch/arm/mach-s3c2400/include/mach/memory.h20
-rw-r--r--arch/arm/mach-s3c2410/Kconfig181
-rw-r--r--arch/arm/mach-s3c2410/Makefile41
-rw-r--r--arch/arm/mach-s3c2410/Makefile.boot7
-rw-r--r--arch/arm/mach-s3c2410/bast-ide.c112
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c166
-rw-r--r--arch/arm/mach-s3c2410/cpu-freq.c159
-rw-r--r--arch/arm/mach-s3c2410/dma.c193
-rw-r--r--arch/arm/mach-s3c2410/gpio.c72
-rw-r--r--arch/arm/mach-s3c2410/h1940-bluetooth.c158
-rw-r--r--arch/arm/mach-s3c2410/include/mach/anubis-cpld.h25
-rw-r--r--arch/arm/mach-s3c2410/include/mach/anubis-irq.h21
-rw-r--r--arch/arm/mach-s3c2410/include/mach/anubis-map.h38
-rw-r--r--arch/arm/mach-s3c2410/include/mach/bast-cpld.h53
-rw-r--r--arch/arm/mach-s3c2410/include/mach/bast-irq.h29
-rw-r--r--arch/arm/mach-s3c2410/include/mach/bast-map.h146
-rw-r--r--arch/arm/mach-s3c2410/include/mach/bast-pmu.h40
-rw-r--r--arch/arm/mach-s3c2410/include/mach/debug-macro.S101
-rw-r--r--arch/arm/mach-s3c2410/include/mach/dma.h204
-rw-r--r--arch/arm/mach-s3c2410/include/mach/entry-macro.S78
-rw-r--r--arch/arm/mach-s3c2410/include/mach/fb.h74
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-fns.h104
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-nrs.h118
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio-track.h33
-rw-r--r--arch/arm/mach-s3c2410/include/mach/gpio.h41
-rw-r--r--arch/arm/mach-s3c2410/include/mach/h1940-latch.h43
-rw-r--r--arch/arm/mach-s3c2410/include/mach/h1940.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/hardware.h42
-rw-r--r--arch/arm/mach-s3c2410/include/mach/idle.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/io.h218
-rw-r--r--arch/arm/mach-s3c2410/include/mach/irqs.h202
-rw-r--r--arch/arm/mach-s3c2410/include/mach/leds-gpio.h28
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h124
-rw-r--r--arch/arm/mach-s3c2410/include/mach/memory.h16
-rw-r--r--arch/arm/mach-s3c2410/include/mach/osiris-cpld.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/osiris-map.h42
-rw-r--r--arch/arm/mach-s3c2410/include/mach/otom-map.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/pm-core.h64
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-clock.h166
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-dsc.h220
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpio.h843
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-gpioj.h70
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-irq.h53
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-lcd.h162
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-mem.h230
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-power.h40
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h48
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h23
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h30
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h192
-rw-r--r--arch/arm/mach-s3c2410/include/mach/regs-sdi.h127
-rw-r--r--arch/arm/mach-s3c2410/include/mach/reset.h22
-rw-r--r--arch/arm/mach-s3c2410/include/mach/spi-gpio.h28
-rw-r--r--arch/arm/mach-s3c2410/include/mach/spi.h38
-rw-r--r--arch/arm/mach-s3c2410/include/mach/system-reset.h32
-rw-r--r--arch/arm/mach-s3c2410/include/mach/system.h58
-rw-r--r--arch/arm/mach-s3c2410/include/mach/tick.h15
-rw-r--r--arch/arm/mach-s3c2410/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s3c2410/include/mach/uncompress.h54
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h18
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vr1000-irq.h26
-rw-r--r--arch/arm/mach-s3c2410/include/mach/vr1000-map.h110
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c244
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c665
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c753
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c604
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c124
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c372
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c121
-rw-r--r--arch/arm/mach-s3c2410/mach-tct_hammer.c154
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c408
-rw-r--r--arch/arm/mach-s3c2410/nor-simtec.c87
-rw-r--r--arch/arm/mach-s3c2410/nor-simtec.h14
-rw-r--r--arch/arm/mach-s3c2410/pll.c95
-rw-r--r--arch/arm/mach-s3c2410/pm-h1940.S33
-rw-r--r--arch/arm/mach-s3c2410/pm.c172
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c183
-rw-r--r--arch/arm/mach-s3c2410/sleep.S68
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c132
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.h16
-rw-r--r--arch/arm/mach-s3c2412/Kconfig99
-rw-r--r--arch/arm/mach-s3c2412/Makefile25
-rw-r--r--arch/arm/mach-s3c2412/clock.c786
-rw-r--r--arch/arm/mach-s3c2412/cpu-freq.c257
-rw-r--r--arch/arm/mach-s3c2412/dma.c195
-rw-r--r--arch/arm/mach-s3c2412/gpio.c62
-rw-r--r--arch/arm/mach-s3c2412/irq.c212
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c677
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c160
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c166
-rw-r--r--arch/arm/mach-s3c2412/pm.c122
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c252
-rw-r--r--arch/arm/mach-s3c2412/sleep.S68
-rw-r--r--arch/arm/mach-s3c2416/Kconfig61
-rw-r--r--arch/arm/mach-s3c2416/Makefile23
-rw-r--r--arch/arm/mach-s3c2416/clock.c143
-rw-r--r--arch/arm/mach-s3c2416/irq.c247
-rw-r--r--arch/arm/mach-s3c2416/mach-smdk2416.c254
-rw-r--r--arch/arm/mach-s3c2416/pm.c81
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c142
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci-gpio.c34
-rw-r--r--arch/arm/mach-s3c2416/setup-sdhci.c61
-rw-r--r--arch/arm/mach-s3c2440/Kconfig206
-rw-r--r--arch/arm/mach-s3c2440/Makefile41
-rw-r--r--arch/arm/mach-s3c2440/clock.c152
-rw-r--r--arch/arm/mach-s3c2440/dma.c211
-rw-r--r--arch/arm/mach-s3c2440/dsc.c54
-rw-r--r--arch/arm/mach-s3c2440/include/mach/gta02.h84
-rw-r--r--arch/arm/mach-s3c2440/irq.c126
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c506
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c241
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c604
-rw-r--r--arch/arm/mach-s3c2440/mach-mini2440.c684
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c159
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris-dvs.c194
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c455
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c834
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c227
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c184
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-cpufreq.c311
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-pll-12000000.c97
-rw-r--r--arch/arm/mach-s3c2440/s3c2440-pll-16934400.c127
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c73
-rw-r--r--arch/arm/mach-s3c2440/s3c2442.c185
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-clock.c138
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-irq.c138
-rw-r--r--arch/arm/mach-s3c2440/s3c244x.c196
-rw-r--r--arch/arm/mach-s3c2443/Kconfig33
-rw-r--r--arch/arm/mach-s3c2443/Makefile20
-rw-r--r--arch/arm/mach-s3c2443/clock.c376
-rw-r--r--arch/arm/mach-s3c2443/dma.c180
-rw-r--r--arch/arm/mach-s3c2443/irq.c278
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c148
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c110
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/debug-macro.S27
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/io.h18
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/irqs.h117
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/map.h86
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/memory.h21
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/regs-clock.h88
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/regs-irq.h25
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/system.h25
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/tick.h15
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/timex.h18
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/vmalloc.h17
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig268
-rw-r--r--arch/arm/mach-s3c64xx/Makefile69
-rw-r--r--arch/arm/mach-s3c64xx/Makefile.boot2
-rw-r--r--arch/arm/mach-s3c64xx/clock.c856
-rw-r--r--arch/arm/mach-s3c64xx/cpu.c167
-rw-r--r--arch/arm/mach-s3c64xx/cpufreq.c270
-rw-r--r--arch/arm/mach-s3c64xx/dev-audio.c317
-rw-r--r--arch/arm/mach-s3c64xx/dev-onenand1.c55
-rw-r--r--arch/arm/mach-s3c64xx/dev-spi.c179
-rw-r--r--arch/arm/mach-s3c64xx/dev-uart.c147
-rw-r--r--arch/arm/mach-s3c64xx/dma.c752
-rw-r--r--arch/arm/mach-s3c64xx/gpiolib.c290
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/debug-macro.S38
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h127
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/entry-macro.S18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/gpio.h100
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/hardware.h16
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/io.h18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/irqs.h220
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h130
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/memory.h20
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pll.h45
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h98
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pwm-clock.h56
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h162
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-fb.h21
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h25
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-gpio.h187
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-irq.h20
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-modem.h31
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-srom.h59
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-sys.h28
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h116
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/s3c6400.h36
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/s3c6410.h29
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/spi-clocks.h18
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/system.h30
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/uncompress.h28
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c213
-rw-r--r--arch/arm/mach-s3c64xx/irq-pm.c111
-rw-r--r--arch/arm/mach-s3c64xx/irq.c64
-rw-r--r--arch/arm/mach-s3c64xx/mach-anw6410.c242
-rw-r--r--arch/arm/mach-s3c64xx/mach-hmt.c273
-rw-r--r--arch/arm/mach-s3c64xx/mach-mini6410.c357
-rw-r--r--arch/arm/mach-s3c64xx/mach-ncp.c105
-rw-r--r--arch/arm/mach-s3c64xx/mach-real6410.c338
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.c399
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq.h20
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq5.c154
-rw-r--r--arch/arm/mach-s3c64xx/mach-smartq7.c170
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6400.c94
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c754
-rw-r--r--arch/arm/mach-s3c64xx/pm.c197
-rw-r--r--arch/arm/mach-s3c64xx/s3c6400.c93
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c98
-rw-r--r--arch/arm/mach-s3c64xx/setup-fb-24bpp.c28
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c0.c28
-rw-r--r--arch/arm/mach-s3c64xx/setup-i2c1.c28
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c43
-rw-r--r--arch/arm/mach-s3c64xx/setup-keypad.c24
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c57
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci.c72
-rw-r--r--arch/arm/mach-s3c64xx/sleep.S95
-rw-r--r--arch/arm/mach-s5p64x0/Kconfig59
-rw-r--r--arch/arm/mach-s5p64x0/Makefile30
-rw-r--r--arch/arm/mach-s5p64x0/Makefile.boot2
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c619
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c666
-rw-r--r--arch/arm/mach-s5p64x0/clock.c235
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c209
-rw-r--r--arch/arm/mach-s5p64x0/dev-audio.c236
-rw-r--r--arch/arm/mach-s5p64x0/dev-spi.c226
-rw-r--r--arch/arm/mach-s5p64x0/dma.c149
-rw-r--r--arch/arm/mach-s5p64x0/gpiolib.c511
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/debug-macro.S33
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/entry-macro.S16
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/gpio.h139
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/i2c.h17
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/io.h25
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h142
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/map.h89
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/memory.h19
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/pwm-clock.h68
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-clock.h65
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-gpio.h37
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h46
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/spi-clocks.h20
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/system.h23
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/timex.h27
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/uncompress.h212
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-s5p64x0/init.c73
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6440.c208
-rw-r--r--arch/arm/mach-s5p64x0/mach-smdk6450.c227
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c0.c38
-rw-r--r--arch/arm/mach-s5p64x0/setup-i2c1.c38
-rw-r--r--arch/arm/mach-s5pc100/Kconfig74
-rw-r--r--arch/arm/mach-s5pc100/Makefile36
-rw-r--r--arch/arm/mach-s5pc100/Makefile.boot2
-rw-r--r--arch/arm/mach-s5pc100/clock.c1398
-rw-r--r--arch/arm/mach-s5pc100/cpu.c169
-rw-r--r--arch/arm/mach-s5pc100/dev-audio.c347
-rw-r--r--arch/arm/mach-s5pc100/dev-spi.c227
-rw-r--r--arch/arm/mach-s5pc100/dma.c167
-rw-r--r--arch/arm/mach-s5pc100/include/mach/debug-macro.S39
-rw-r--r--arch/arm/mach-s5pc100/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pc100/include/mach/entry-macro.S50
-rw-r--r--arch/arm/mach-s5pc100/include/mach/gpio.h151
-rw-r--r--arch/arm/mach-s5pc100/include/mach/hardware.h14
-rw-r--r--arch/arm/mach-s5pc100/include/mach/io.h18
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h115
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h133
-rw-r--r--arch/arm/mach-s5pc100/include/mach/memory.h18
-rw-r--r--arch/arm/mach-s5pc100/include/mach/pwm-clock.h56
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-clock.h80
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-fb.h105
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-gpio.h38
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5pc100/include/mach/spi-clocks.h18
-rw-r--r--arch/arm/mach-s5pc100/include/mach/system.h21
-rw-r--r--arch/arm/mach-s5pc100/include/mach/tick.h29
-rw-r--r--arch/arm/mach-s5pc100/include/mach/timex.h24
-rw-r--r--arch/arm/mach-s5pc100/include/mach/uncompress.h28
-rw-r--r--arch/arm/mach-s5pc100/include/mach/vmalloc.h17
-rw-r--r--arch/arm/mach-s5pc100/init.c24
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c289
-rw-r--r--arch/arm/mach-s5pc100/setup-fb-24bpp.c36
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c0.c28
-rw-r--r--arch/arm/mach-s5pc100/setup-i2c1.c28
-rw-r--r--arch/arm/mach-s5pc100/setup-ide.c57
-rw-r--r--arch/arm/mach-s5pc100/setup-keypad.c23
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci-gpio.c71
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci.c65
-rw-r--r--arch/arm/mach-s5pv210/Kconfig175
-rw-r--r--arch/arm/mach-s5pv210/Makefile40
-rw-r--r--arch/arm/mach-s5pv210/Makefile.boot2
-rw-r--r--arch/arm/mach-s5pv210/clock.c1243
-rw-r--r--arch/arm/mach-s5pv210/cpu.c197
-rw-r--r--arch/arm/mach-s5pv210/cpufreq.c485
-rw-r--r--arch/arm/mach-s5pv210/dev-audio.c363
-rw-r--r--arch/arm/mach-s5pv210/dev-spi.c175
-rw-r--r--arch/arm/mach-s5pv210/dma.c168
-rw-r--r--arch/arm/mach-s5pv210/include/mach/debug-macro.S41
-rw-r--r--arch/arm/mach-s5pv210/include/mach/dma.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/entry-macro.S54
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio.h147
-rw-r--r--arch/arm/mach-s5pv210/include/mach/hardware.h18
-rw-r--r--arch/arm/mach-s5pv210/include/mach/io.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h137
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h135
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h28
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pm-core.h43
-rw-r--r--arch/arm/mach-s5pv210/include/mach/pwm-clock.h70
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-clock.h205
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-fb.h21
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-gpio.h41
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-irq.h19
-rw-r--r--arch/arm/mach-s5pv210/include/mach/regs-sys.h19
-rw-r--r--arch/arm/mach-s5pv210/include/mach/spi-clocks.h17
-rw-r--r--arch/arm/mach-s5pv210/include/mach/system.h23
-rw-r--r--arch/arm/mach-s5pv210/include/mach/tick.h26
-rw-r--r--arch/arm/mach-s5pv210/include/mach/timex.h29
-rw-r--r--arch/arm/mach-s5pv210/include/mach/uncompress.h24
-rw-r--r--arch/arm/mach-s5pv210/include/mach/vmalloc.h22
-rw-r--r--arch/arm/mach-s5pv210/init.c44
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c686
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c896
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c144
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c354
-rw-r--r--arch/arm/mach-s5pv210/mach-torbreck.c133
-rw-r--r--arch/arm/mach-s5pv210/pm.c175
-rw-r--r--arch/arm/mach-s5pv210/setup-fb-24bpp.c50
-rw-r--r--arch/arm/mach-s5pv210/setup-fimc.c43
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c0.c28
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c1.c28
-rw-r--r--arch/arm/mach-s5pv210/setup-i2c2.c28
-rw-r--r--arch/arm/mach-s5pv210/setup-ide.c39
-rw-r--r--arch/arm/mach-s5pv210/setup-keypad.c24
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c104
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci.c63
-rw-r--r--arch/arm/mach-s5pv210/sleep.S73
-rw-r--r--arch/arm/mach-sa1100/Kconfig170
-rw-r--r--arch/arm/mach-sa1100/Makefile56
-rw-r--r--arch/arm/mach-sa1100/Makefile.boot7
-rw-r--r--arch/arm/mach-sa1100/assabet.c456
-rw-r--r--arch/arm/mach-sa1100/badge4.c309
-rw-r--r--arch/arm/mach-sa1100/cerf.c142
-rw-r--r--arch/arm/mach-sa1100/clock.c88
-rw-r--r--arch/arm/mach-sa1100/collie.c389
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c248
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c407
-rw-r--r--arch/arm/mach-sa1100/dma.c348
-rw-r--r--arch/arm/mach-sa1100/generic.c454
-rw-r--r--arch/arm/mach-sa1100/generic.h41
-rw-r--r--arch/arm/mach-sa1100/gpio.c65
-rw-r--r--arch/arm/mach-sa1100/h3100.c93
-rw-r--r--arch/arm/mach-sa1100/h3600.c134
-rw-r--r--arch/arm/mach-sa1100/h3xxx.c313
-rw-r--r--arch/arm/mach-sa1100/hackkit.c203
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1100.h2056
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1101.h925
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1111.h5
-rw-r--r--arch/arm/mach-sa1100/include/mach/assabet.h105
-rw-r--r--arch/arm/mach-sa1100/include/mach/badge4.h75
-rw-r--r--arch/arm/mach-sa1100/include/mach/bitfield.h113
-rw-r--r--arch/arm/mach-sa1100/include/mach/cerf.h28
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h92
-rw-r--r--arch/arm/mach-sa1100/include/mach/debug-macro.S62
-rw-r--r--arch/arm/mach-sa1100/include/mach/dma.h117
-rw-r--r--arch/arm/mach-sa1100/include/mach/entry-macro.S47
-rw-r--r--arch/arm/mach-sa1100/include/mach/gpio.h57
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3xxx.h94
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h87
-rw-r--r--arch/arm/mach-sa1100/include/mach/io.h22
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h92
-rw-r--r--arch/arm/mach-sa1100/include/mach/jornada720.h32
-rw-r--r--arch/arm/mach-sa1100/include/mach/lart.h13
-rw-r--r--arch/arm/mach-sa1100/include/mach/mcp.h22
-rw-r--r--arch/arm/mach-sa1100/include/mach/memory.h45
-rw-r--r--arch/arm/mach-sa1100/include/mach/mtd-xip.h26
-rw-r--r--arch/arm/mach-sa1100/include/mach/nanoengine.h52
-rw-r--r--arch/arm/mach-sa1100/include/mach/neponset.h74
-rw-r--r--arch/arm/mach-sa1100/include/mach/reset.h18
-rw-r--r--arch/arm/mach-sa1100/include/mach/shannon.h43
-rw-r--r--arch/arm/mach-sa1100/include/mach/simpad.h112
-rw-r--r--arch/arm/mach-sa1100/include/mach/system.h22
-rw-r--r--arch/arm/mach-sa1100/include/mach/timex.h12
-rw-r--r--arch/arm/mach-sa1100/include/mach/uncompress.h50
-rw-r--r--arch/arm/mach-sa1100/include/mach/vmalloc.h4
-rw-r--r--arch/arm/mach-sa1100/irq.c343
-rw-r--r--arch/arm/mach-sa1100/jornada720.c372
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c200
-rw-r--r--arch/arm/mach-sa1100/lart.c69
-rw-r--r--arch/arm/mach-sa1100/leds-assabet.c114
-rw-r--r--arch/arm/mach-sa1100/leds-badge4.c111
-rw-r--r--arch/arm/mach-sa1100/leds-cerf.c110
-rw-r--r--arch/arm/mach-sa1100/leds-hackkit.c112
-rw-r--r--arch/arm/mach-sa1100/leds-lart.c101
-rw-r--r--arch/arm/mach-sa1100/leds-simpad.c100
-rw-r--r--arch/arm/mach-sa1100/leds.c52
-rw-r--r--arch/arm/mach-sa1100/leds.h14
-rw-r--r--arch/arm/mach-sa1100/nanoengine.c119
-rw-r--r--arch/arm/mach-sa1100/neponset.c346
-rw-r--r--arch/arm/mach-sa1100/pci-nanoengine.c284
-rw-r--r--arch/arm/mach-sa1100/pleb.c153
-rw-r--r--arch/arm/mach-sa1100/pm.c128
-rw-r--r--arch/arm/mach-sa1100/shannon.c90
-rw-r--r--arch/arm/mach-sa1100/simpad.c236
-rw-r--r--arch/arm/mach-sa1100/sleep.S151
-rw-r--r--arch/arm/mach-sa1100/ssp.c243
-rw-r--r--arch/arm/mach-sa1100/time.c164
-rw-r--r--arch/arm/mach-shark/Makefile12
-rw-r--r--arch/arm/mach-shark/Makefile.boot2
-rw-r--r--arch/arm/mach-shark/core.c159
-rw-r--r--arch/arm/mach-shark/dma.c23
-rw-r--r--arch/arm/mach-shark/include/mach/debug-macro.S33
-rw-r--r--arch/arm/mach-shark/include/mach/entry-macro.S41
-rw-r--r--arch/arm/mach-shark/include/mach/framebuffer.h16
-rw-r--r--arch/arm/mach-shark/include/mach/hardware.h22
-rw-r--r--arch/arm/mach-shark/include/mach/io.h20
-rw-r--r--arch/arm/mach-shark/include/mach/irqs.h13
-rw-r--r--arch/arm/mach-shark/include/mach/isa-dma.h13
-rw-r--r--arch/arm/mach-shark/include/mach/memory.h28
-rw-r--r--arch/arm/mach-shark/include/mach/system.h16
-rw-r--r--arch/arm/mach-shark/include/mach/timex.h7
-rw-r--r--arch/arm/mach-shark/include/mach/uncompress.h51
-rw-r--r--arch/arm/mach-shark/include/mach/vmalloc.h4
-rw-r--r--arch/arm/mach-shark/irq.c108
-rw-r--r--arch/arm/mach-shark/leds.c166
-rw-r--r--arch/arm/mach-shark/pci.c45
-rw-r--r--arch/arm/mach-shmobile/Kconfig134
-rw-r--r--arch/arm/mach-shmobile/Makefile47
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot9
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c598
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c1435
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c372
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c415
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c1608
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c358
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c703
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c369
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c405
-rw-r--r--arch/arm/mach-shmobile/clock.c46
-rw-r--r--arch/arm/mach-shmobile/console.c31
-rw-r--r--arch/arm/mach-shmobile/cpuidle.c92
-rw-r--r--arch/arm/mach-shmobile/entry-gic.S18
-rw-r--r--arch/arm/mach-shmobile/entry-intc.S57
-rw-r--r--arch/arm/mach-shmobile/headsmp.S27
-rw-r--r--arch/arm/mach-shmobile/hotplug.c41
-rw-r--r--arch/arm/mach-shmobile/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h56
-rw-r--r--arch/arm/mach-shmobile/include/mach/dma.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/entry-macro.S34
-rw-r--r--arch/arm/mach-shmobile/include/mach/gpio.h48
-rw-r--r--arch/arm/mach-shmobile/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-ap4evb.txt93
-rw-r--r--arch/arm/mach-shmobile/include/mach/head-mackerel.txt93
-rw-r--r--arch/arm/mach-shmobile/include/mach/io.h9
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h18
-rw-r--r--arch/arm/mach-shmobile/include/mach/memory.h10
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h29
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc-mackerel.h38
-rw-r--r--arch/arm/mach-shmobile/include/mach/mmc.h18
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7367.h332
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h473
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7377.h360
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h497
-rw-r--r--arch/arm/mach-shmobile/include/mach/system.h14
-rw-r--r--arch/arm/mach-shmobile/include/mach/timex.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/uncompress.h21
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h7
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot.h23
-rw-r--r--arch/arm/mach-shmobile/include/mach/zboot_macros.h65
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c440
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c620
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c646
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c274
-rw-r--r--arch/arm/mach-shmobile/localtimer.c26
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7367.c1801
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c1640
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7377.c1767
-rw-r--r--arch/arm/mach-shmobile/pfc-sh73a0.c2746
-rw-r--r--arch/arm/mach-shmobile/platsmp.c73
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c108
-rw-r--r--arch/arm/mach-shmobile/pm_runtime.c58
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c448
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c855
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c469
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c674
-rw-r--r--arch/arm/mach-shmobile/sleep-sh7372.S260
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c98
-rw-r--r--arch/arm/mach-shmobile/suspend.c47
-rw-r--r--arch/arm/mach-shmobile/timer.c46
-rw-r--r--arch/arm/mach-spear3xx/Kconfig43
-rw-r--r--arch/arm/mach-spear3xx/Makefile26
-rw-r--r--arch/arm/mach-spear3xx/Makefile.boot3
-rw-r--r--arch/arm/mach-spear3xx/clock.c759
-rw-r--r--arch/arm/mach-spear3xx/include/mach/clkdev.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/debug-macro.S14
-rw-r--r--arch/arm/mach-spear3xx/include/mach/entry-macro.S45
-rw-r--r--arch/arm/mach-spear3xx/include/mach/generic.h200
-rw-r--r--arch/arm/mach-spear3xx/include/mach/gpio.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/hardware.h23
-rw-r--r--arch/arm/mach-spear3xx/include/mach/io.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/irqs.h154
-rw-r--r--arch/arm/mach-spear3xx/include/mach/memory.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/misc_regs.h164
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear.h81
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear300.h54
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear310.h58
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear320.h67
-rw-r--r--arch/arm/mach-spear3xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/timex.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/uncompress.h19
-rw-r--r--arch/arm/mach-spear3xx/include/mach/vmalloc.h19
-rw-r--r--arch/arm/mach-spear3xx/spear300.c477
-rw-r--r--arch/arm/mach-spear3xx/spear300_evb.c72
-rw-r--r--arch/arm/mach-spear3xx/spear310.c308
-rw-r--r--arch/arm/mach-spear3xx/spear310_evb.c78
-rw-r--r--arch/arm/mach-spear3xx/spear320.c555
-rw-r--r--arch/arm/mach-spear3xx/spear320_evb.c76
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c557
-rw-r--r--arch/arm/mach-spear6xx/Kconfig21
-rw-r--r--arch/arm/mach-spear6xx/Makefile12
-rw-r--r--arch/arm/mach-spear6xx/Makefile.boot3
-rw-r--r--arch/arm/mach-spear6xx/clock.c682
-rw-r--r--arch/arm/mach-spear6xx/include/mach/clkdev.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/debug-macro.S14
-rw-r--r--arch/arm/mach-spear6xx/include/mach/entry-macro.S54
-rw-r--r--arch/arm/mach-spear6xx/include/mach/generic.h46
-rw-r--r--arch/arm/mach-spear6xx/include/mach/gpio.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/hardware.h23
-rw-r--r--arch/arm/mach-spear6xx/include/mach/io.h20
-rw-r--r--arch/arm/mach-spear6xx/include/mach/irqs.h97
-rw-r--r--arch/arm/mach-spear6xx/include/mach/memory.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/misc_regs.h174
-rw-r--r--arch/arm/mach-spear6xx/include/mach/spear.h90
-rw-r--r--arch/arm/mach-spear6xx/include/mach/spear600.h21
-rw-r--r--arch/arm/mach-spear6xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/timex.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/uncompress.h19
-rw-r--r--arch/arm/mach-spear6xx/include/mach/vmalloc.h19
-rw-r--r--arch/arm/mach-spear6xx/spear600.c25
-rw-r--r--arch/arm/mach-spear6xx/spear600_evb.c51
-rw-r--r--arch/arm/mach-spear6xx/spear6xx.c183
-rw-r--r--arch/arm/mach-tcc8k/Kconfig11
-rw-r--r--arch/arm/mach-tcc8k/Makefile9
-rw-r--r--arch/arm/mach-tcc8k/Makefile.boot3
-rw-r--r--arch/arm/mach-tcc8k/board-tcc8000-sdk.c81
-rw-r--r--arch/arm/mach-tcc8k/clock.c580
-rw-r--r--arch/arm/mach-tcc8k/common.h15
-rw-r--r--arch/arm/mach-tcc8k/devices.c239
-rw-r--r--arch/arm/mach-tcc8k/io.c62
-rw-r--r--arch/arm/mach-tcc8k/irq.c111
-rw-r--r--arch/arm/mach-tcc8k/time.c134
-rw-r--r--arch/arm/mach-tegra/Kconfig100
-rw-r--r--arch/arm/mach-tegra/Makefile34
-rw-r--r--arch/arm/mach-tegra/Makefile.boot3
-rw-r--r--arch/arm/mach-tegra/board-harmony-pcie.c79
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c161
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c119
-rw-r--r--arch/arm/mach-tegra/board-harmony.c211
-rw-r--r--arch/arm/mach-tegra/board-harmony.h38
-rw-r--r--arch/arm/mach-tegra/board-paz00-pinmux.c157
-rw-r--r--arch/arm/mach-tegra/board-paz00.c128
-rw-r--r--arch/arm/mach-tegra/board-paz00.h29
-rw-r--r--arch/arm/mach-tegra/board-seaboard-pinmux.c180
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c250
-rw-r--r--arch/arm/mach-tegra/board-seaboard.h41
-rw-r--r--arch/arm/mach-tegra/board-trimslice-pinmux.c154
-rw-r--r--arch/arm/mach-tegra/board-trimslice.c125
-rw-r--r--arch/arm/mach-tegra/board-trimslice.h25
-rw-r--r--arch/arm/mach-tegra/board.h35
-rw-r--r--arch/arm/mach-tegra/clock.c671
-rw-r--r--arch/arm/mach-tegra/clock.h160
-rw-r--r--arch/arm/mach-tegra/common.c83
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c253
-rw-r--r--arch/arm/mach-tegra/devices.c575
-rw-r--r--arch/arm/mach-tegra/devices.h50
-rw-r--r--arch/arm/mach-tegra/dma.c793
-rw-r--r--arch/arm/mach-tegra/fuse.c84
-rw-r--r--arch/arm/mach-tegra/fuse.h24
-rw-r--r--arch/arm/mach-tegra/gpio-names.h247
-rw-r--r--arch/arm/mach-tegra/gpio.c431
-rw-r--r--arch/arm/mach-tegra/headsmp.S61
-rw-r--r--arch/arm/mach-tegra/hotplug.c126
-rw-r--r--arch/arm/mach-tegra/include/mach/barriers.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h31
-rw-r--r--arch/arm/mach-tegra/include/mach/clkdev.h34
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S35
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h155
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S56
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h60
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h28
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h95
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h274
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h183
-rw-r--r--arch/arm/mach-tegra/include/mach/kbc.h60
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h28
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux-t2.h184
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h240
-rw-r--r--arch/arm/mach-tegra/include/mach/powergate.h40
-rw-r--r--arch/arm/mach-tegra/include/mach/sdhci.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/suspend.h38
-rw-r--r--arch/arm/mach-tegra/include/mach/system.h33
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h23
-rw-r--r--arch/arm/mach-tegra/include/mach/timex.h26
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h64
-rw-r--r--arch/arm/mach-tegra/include/mach/usb_phy.h86
-rw-r--r--arch/arm/mach-tegra/include/mach/vmalloc.h28
-rw-r--r--arch/arm/mach-tegra/io.c84
-rw-r--r--arch/arm/mach-tegra/irq.c134
-rw-r--r--arch/arm/mach-tegra/localtimer.c26
-rw-r--r--arch/arm/mach-tegra/pcie.c933
-rw-r--r--arch/arm/mach-tegra/pinmux-t2-tables.c278
-rw-r--r--arch/arm/mach-tegra/pinmux.c825
-rw-r--r--arch/arm/mach-tegra/platsmp.c142
-rw-r--r--arch/arm/mach-tegra/powergate.c212
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c2441
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.c178
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.h27
-rw-r--r--arch/arm/mach-tegra/timer.c262
-rw-r--r--arch/arm/mach-tegra/usb_phy.c795
-rw-r--r--arch/arm/mach-u300/Kconfig117
-rw-r--r--arch/arm/mach-u300/Makefile15
-rw-r--r--arch/arm/mach-u300/Makefile.boot15
-rw-r--r--arch/arm/mach-u300/clock.c1504
-rw-r--r--arch/arm/mach-u300/clock.h50
-rw-r--r--arch/arm/mach-u300/core.c1861
-rw-r--r--arch/arm/mach-u300/dummyspichip.c290
-rw-r--r--arch/arm/mach-u300/i2c.c347
-rw-r--r--arch/arm/mach-u300/i2c.h23
-rw-r--r--arch/arm/mach-u300/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-u300/include/mach/coh901318.h267
-rw-r--r--arch/arm/mach-u300/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-u300/include/mach/dma_channels.h69
-rw-r--r--arch/arm/mach-u300/include/mach/entry-macro.S40
-rw-r--r--arch/arm/mach-u300/include/mach/gpio.h294
-rw-r--r--arch/arm/mach-u300/include/mach/hardware.h5
-rw-r--r--arch/arm/mach-u300/include/mach/io.h20
-rw-r--r--arch/arm/mach-u300/include/mach/irqs.h121
-rw-r--r--arch/arm/mach-u300/include/mach/memory.h42
-rw-r--r--arch/arm/mach-u300/include/mach/platform.h19
-rw-r--r--arch/arm/mach-u300/include/mach/syscon.h750
-rw-r--r--arch/arm/mach-u300/include/mach/system.h42
-rw-r--r--arch/arm/mach-u300/include/mach/timex.h17
-rw-r--r--arch/arm/mach-u300/include/mach/u300-regs.h183
-rw-r--r--arch/arm/mach-u300/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-u300/include/mach/vmalloc.h12
-rw-r--r--arch/arm/mach-u300/mmc.c68
-rw-r--r--arch/arm/mach-u300/mmc.h18
-rw-r--r--arch/arm/mach-u300/padmux.c367
-rw-r--r--arch/arm/mach-u300/padmux.h39
-rw-r--r--arch/arm/mach-u300/regulator.c88
-rw-r--r--arch/arm/mach-u300/spi.c123
-rw-r--r--arch/arm/mach-u300/spi.h26
-rw-r--r--arch/arm/mach-u300/timer.c438
-rw-r--r--arch/arm/mach-u300/u300.c70
-rw-r--r--arch/arm/mach-ux500/Kconfig62
-rw-r--r--arch/arm/mach-ux500/Makefile20
-rw-r--r--arch/arm/mach-ux500/Makefile.boot4
-rw-r--r--arch/arm/mach-ux500/board-mop500-pins.c249
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.c359
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.h22
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c218
-rw-r--r--arch/arm/mach-ux500/board-mop500-stuib.c205
-rw-r--r--arch/arm/mach-ux500/board-mop500-u8500uib.c111
-rw-r--r--arch/arm/mach-ux500/board-mop500-uib.c135
-rw-r--r--arch/arm/mach-ux500/board-mop500.c533
-rw-r--r--arch/arm/mach-ux500/board-mop500.h46
-rw-r--r--arch/arm/mach-ux500/board-u5500-sdi.c74
-rw-r--r--arch/arm/mach-ux500/board-u5500.c44
-rw-r--r--arch/arm/mach-ux500/clock.c790
-rw-r--r--arch/arm/mach-ux500/clock.h151
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c226
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c207
-rw-r--r--arch/arm/mach-ux500/cpu.c171
-rw-r--r--arch/arm/mach-ux500/devices-common.c146
-rw-r--r--arch/arm/mach-ux500/devices-common.h87
-rw-r--r--arch/arm/mach-ux500/devices-db5500.h79
-rw-r--r--arch/arm/mach-ux500/devices-db8500.c197
-rw-r--r--arch/arm/mach-ux500/devices-db8500.h101
-rw-r--r--arch/arm/mach-ux500/devices.c25
-rw-r--r--arch/arm/mach-ux500/dma-db5500.c136
-rw-r--r--arch/arm/mach-ux500/headsmp.S37
-rw-r--r--arch/arm/mach-ux500/hotplug.c59
-rw-r--r--arch/arm/mach-ux500/id.c107
-rw-r--r--arch/arm/mach-ux500/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-ux500/include/mach/db5500-regs.h137
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h169
-rw-r--r--arch/arm/mach-ux500/include/mach/debug-macro.S43
-rw-r--r--arch/arm/mach-ux500/include/mach/devices.h23
-rw-r--r--arch/arm/mach-ux500/include/mach/entry-macro.S20
-rw-r--r--arch/arm/mach-ux500/include/mach/gpio.h12
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h41
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h100
-rw-r--r--arch/arm/mach-ux500/include/mach/io.h22
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-board-mop500.h63
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-board-u5500.h21
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-db5500.h113
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-db8500.h150
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h56
-rw-r--r--arch/arm/mach-ux500/include/mach/mbox-db5500.h88
-rw-r--r--arch/arm/mach-ux500/include/mach/memory.h18
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h53
-rw-r--r--arch/arm/mach-ux500/include/mach/system.h25
-rw-r--r--arch/arm/mach-ux500/include/mach/timex.h6
-rw-r--r--arch/arm/mach-ux500/include/mach/uncompress.h67
-rw-r--r--arch/arm/mach-ux500/include/mach/usb.h25
-rw-r--r--arch/arm/mach-ux500/include/mach/vmalloc.h18
-rw-r--r--arch/arm/mach-ux500/localtimer.c29
-rw-r--r--arch/arm/mach-ux500/mbox-db5500.c565
-rw-r--r--arch/arm/mach-ux500/modem-irq-db5500.c143
-rw-r--r--arch/arm/mach-ux500/pins-db5500.h620
-rw-r--r--arch/arm/mach-ux500/pins-db8500.h742
-rw-r--r--arch/arm/mach-ux500/platsmp.c186
-rw-r--r--arch/arm/mach-ux500/ste-dma40-db5500.h135
-rw-r--r--arch/arm/mach-ux500/ste-dma40-db8500.h144
-rw-r--r--arch/arm/mach-ux500/usb.c160
-rw-r--r--arch/arm/mach-versatile/Kconfig20
-rw-r--r--arch/arm/mach-versatile/Makefile8
-rw-r--r--arch/arm/mach-versatile/Makefile.boot4
-rw-r--r--arch/arm/mach-versatile/core.c758
-rw-r--r--arch/arm/mach-versatile/core.h50
-rw-r--r--arch/arm/mach-versatile/include/mach/clkdev.h16
-rw-r--r--arch/arm/mach-versatile/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-versatile/include/mach/entry-macro.S45
-rw-r--r--arch/arm/mach-versatile/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-versatile/include/mach/hardware.h44
-rw-r--r--arch/arm/mach-versatile/include/mach/io.h28
-rw-r--r--arch/arm/mach-versatile/include/mach/irqs.h134
-rw-r--r--arch/arm/mach-versatile/include/mach/memory.h28
-rw-r--r--arch/arm/mach-versatile/include/mach/platform.h414
-rw-r--r--arch/arm/mach-versatile/include/mach/system.h49
-rw-r--r--arch/arm/mach-versatile/include/mach/timex.h23
-rw-r--r--arch/arm/mach-versatile/include/mach/uncompress.h46
-rw-r--r--arch/arm/mach-versatile/include/mach/vmalloc.h21
-rw-r--r--arch/arm/mach-versatile/pci.c361
-rw-r--r--arch/arm/mach-versatile/versatile_ab.c44
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c112
-rw-r--r--arch/arm/mach-vexpress/Kconfig12
-rw-r--r--arch/arm/mach-vexpress/Makefile8
-rw-r--r--arch/arm/mach-vexpress/Makefile.boot3
-rw-r--r--arch/arm/mach-vexpress/core.h19
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c251
-rw-r--r--arch/arm/mach-vexpress/hotplug.c128
-rw-r--r--arch/arm/mach-vexpress/include/mach/clkdev.h15
-rw-r--r--arch/arm/mach-vexpress/include/mach/ct-ca9x4.h50
-rw-r--r--arch/arm/mach-vexpress/include/mach/debug-macro.S21
-rw-r--r--arch/arm/mach-vexpress/include/mach/entry-macro.S7
-rw-r--r--arch/arm/mach-vexpress/include/mach/hardware.h1
-rw-r--r--arch/arm/mach-vexpress/include/mach/io.h28
-rw-r--r--arch/arm/mach-vexpress/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-vexpress/include/mach/memory.h25
-rw-r--r--arch/arm/mach-vexpress/include/mach/motherboard.h143
-rw-r--r--arch/arm/mach-vexpress/include/mach/system.h37
-rw-r--r--arch/arm/mach-vexpress/include/mach/timex.h23
-rw-r--r--arch/arm/mach-vexpress/include/mach/uncompress.h52
-rw-r--r--arch/arm/mach-vexpress/include/mach/vmalloc.h21
-rw-r--r--arch/arm/mach-vexpress/platsmp.c51
-rw-r--r--arch/arm/mach-vexpress/v2m.c445
-rw-r--r--arch/arm/mach-vt8500/Kconfig73
-rw-r--r--arch/arm/mach-vt8500/Makefile9
-rw-r--r--arch/arm/mach-vt8500/Makefile.boot3
-rw-r--r--arch/arm/mach-vt8500/bv07.c77
-rw-r--r--arch/arm/mach-vt8500/devices-vt8500.c91
-rw-r--r--arch/arm/mach-vt8500/devices-wm8505.c99
-rw-r--r--arch/arm/mach-vt8500/devices.c270
-rw-r--r--arch/arm/mach-vt8500/devices.h88
-rw-r--r--arch/arm/mach-vt8500/gpio.c240
-rw-r--r--arch/arm/mach-vt8500/include/mach/debug-macro.S31
-rw-r--r--arch/arm/mach-vt8500/include/mach/entry-macro.S32
-rw-r--r--arch/arm/mach-vt8500/include/mach/gpio.h6
-rw-r--r--arch/arm/mach-vt8500/include/mach/hardware.h12
-rw-r--r--arch/arm/mach-vt8500/include/mach/i8042.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/io.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/irqs.h22
-rw-r--r--arch/arm/mach-vt8500/include/mach/memory.h28
-rw-r--r--arch/arm/mach-vt8500/include/mach/system.h18
-rw-r--r--arch/arm/mach-vt8500/include/mach/timex.h26
-rw-r--r--arch/arm/mach-vt8500/include/mach/uncompress.h37
-rw-r--r--arch/arm/mach-vt8500/include/mach/vmalloc.h20
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_irqs.h88
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500_regs.h79
-rw-r--r--arch/arm/mach-vt8500/include/mach/vt8500fb.h31
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_irqs.h115
-rw-r--r--arch/arm/mach-vt8500/include/mach/wm8505_regs.h78
-rw-r--r--arch/arm/mach-vt8500/irq.c180
-rw-r--r--arch/arm/mach-vt8500/pwm.c265
-rw-r--r--arch/arm/mach-vt8500/timer.c155
-rw-r--r--arch/arm/mach-vt8500/wm8505_7in.c77
-rw-r--r--arch/arm/mach-w90x900/Kconfig49
-rw-r--r--arch/arm/mach-w90x900/Makefile19
-rw-r--r--arch/arm/mach-w90x900/Makefile.boot3
-rw-r--r--arch/arm/mach-w90x900/clksel.c91
-rw-r--r--arch/arm/mach-w90x900/clock.c92
-rw-r--r--arch/arm/mach-w90x900/clock.h43
-rw-r--r--arch/arm/mach-w90x900/cpu.c224
-rw-r--r--arch/arm/mach-w90x900/cpu.h60
-rw-r--r--arch/arm/mach-w90x900/dev.c538
-rw-r--r--arch/arm/mach-w90x900/gpio.c154
-rw-r--r--arch/arm/mach-w90x900/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-w90x900/include/mach/entry-macro.S34
-rw-r--r--arch/arm/mach-w90x900/include/mach/fb.h83
-rw-r--r--arch/arm/mach-w90x900/include/mach/gpio.h34
-rw-r--r--arch/arm/mach-w90x900/include/mach/hardware.h24
-rw-r--r--arch/arm/mach-w90x900/include/mach/i2c.h9
-rw-r--r--arch/arm/mach-w90x900/include/mach/io.h30
-rw-r--r--arch/arm/mach-w90x900/include/mach/irqs.h86
-rw-r--r--arch/arm/mach-w90x900/include/mach/map.h157
-rw-r--r--arch/arm/mach-w90x900/include/mach/memory.h23
-rw-r--r--arch/arm/mach-w90x900/include/mach/mfp.h24
-rw-r--r--arch/arm/mach-w90x900/include/mach/nuc900_spi.h35
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-clock.h53
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-ebi.h33
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-gcr.h39
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-irq.h51
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-ldm.h253
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-serial.h59
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-timer.h42
-rw-r--r--arch/arm/mach-w90x900/include/mach/regs-usb.h35
-rw-r--r--arch/arm/mach-w90x900/include/mach/system.h41
-rw-r--r--arch/arm/mach-w90x900/include/mach/timex.h25
-rw-r--r--arch/arm/mach-w90x900/include/mach/uncompress.h50
-rw-r--r--arch/arm/mach-w90x900/include/mach/vmalloc.h23
-rw-r--r--arch/arm/mach-w90x900/include/mach/w90p910_keypad.h15
-rw-r--r--arch/arm/mach-w90x900/irq.c214
-rw-r--r--arch/arm/mach-w90x900/mach-nuc910evb.c42
-rw-r--r--arch/arm/mach-w90x900/mach-nuc950evb.c45
-rw-r--r--arch/arm/mach-w90x900/mach-nuc960evb.c42
-rw-r--r--arch/arm/mach-w90x900/mfp.c164
-rw-r--r--arch/arm/mach-w90x900/nuc910.c62
-rw-r--r--arch/arm/mach-w90x900/nuc910.h28
-rw-r--r--arch/arm/mach-w90x900/nuc950.c56
-rw-r--r--arch/arm/mach-w90x900/nuc950.h28
-rw-r--r--arch/arm/mach-w90x900/nuc960.c54
-rw-r--r--arch/arm/mach-w90x900/nuc960.h28
-rw-r--r--arch/arm/mach-w90x900/time.c176
-rw-r--r--arch/arm/mm/Kconfig891
-rw-r--r--arch/arm/mm/Makefile102
-rw-r--r--arch/arm/mm/abort-ev4.S30
-rw-r--r--arch/arm/mm/abort-ev4t.S30
-rw-r--r--arch/arm/mm/abort-ev5t.S31
-rw-r--r--arch/arm/mm/abort-ev5tj.S35
-rw-r--r--arch/arm/mm/abort-ev6.S48
-rw-r--r--arch/arm/mm/abort-ev7.S54
-rw-r--r--arch/arm/mm/abort-lv4t.S225
-rw-r--r--arch/arm/mm/abort-macro.S42
-rw-r--r--arch/arm/mm/abort-nommu.S20
-rw-r--r--arch/arm/mm/alignment.c960
-rw-r--r--arch/arm/mm/cache-fa.S257
-rw-r--r--arch/arm/mm/cache-feroceon-l2.c350
-rw-r--r--arch/arm/mm/cache-l2x0.c395
-rw-r--r--arch/arm/mm/cache-tauros2.c263
-rw-r--r--arch/arm/mm/cache-v3.S144
-rw-r--r--arch/arm/mm/cache-v4.S156
-rw-r--r--arch/arm/mm/cache-v4wb.S268
-rw-r--r--arch/arm/mm/cache-v4wt.S212
-rw-r--r--arch/arm/mm/cache-v6.S362
-rw-r--r--arch/arm/mm/cache-v7.S369
-rw-r--r--arch/arm/mm/cache-xsc3l2.c220
-rw-r--r--arch/arm/mm/context.c157
-rw-r--r--arch/arm/mm/copypage-fa.c86
-rw-r--r--arch/arm/mm/copypage-feroceon.c112
-rw-r--r--arch/arm/mm/copypage-v3.c81
-rw-r--r--arch/arm/mm/copypage-v4mc.c120
-rw-r--r--arch/arm/mm/copypage-v4wb.c95
-rw-r--r--arch/arm/mm/copypage-v4wt.c88
-rw-r--r--arch/arm/mm/copypage-v6.c149
-rw-r--r--arch/arm/mm/copypage-xsc3.c114
-rw-r--r--arch/arm/mm/copypage-xscale.c142
-rw-r--r--arch/arm/mm/dma-mapping.c711
-rw-r--r--arch/arm/mm/extable.c16
-rw-r--r--arch/arm/mm/fault-armv.c271
-rw-r--r--arch/arm/mm/fault.c662
-rw-r--r--arch/arm/mm/fault.h3
-rw-r--r--arch/arm/mm/flush.c346
-rw-r--r--arch/arm/mm/highmem.c142
-rw-r--r--arch/arm/mm/idmap.c90
-rw-r--r--arch/arm/mm/init.c744
-rw-r--r--arch/arm/mm/iomap.c54
-rw-r--r--arch/arm/mm/ioremap.c320
-rw-r--r--arch/arm/mm/mm.h27
-rw-r--r--arch/arm/mm/mmap.c170
-rw-r--r--arch/arm/mm/mmu.c1052
-rw-r--r--arch/arm/mm/nommu.c96
-rw-r--r--arch/arm/mm/pabort-legacy.S19
-rw-r--r--arch/arm/mm/pabort-v6.S19
-rw-r--r--arch/arm/mm/pabort-v7.S20
-rw-r--r--arch/arm/mm/pgd.c115
-rw-r--r--arch/arm/mm/proc-arm1020.S559
-rw-r--r--arch/arm/mm/proc-arm1020e.S524
-rw-r--r--arch/arm/mm/proc-arm1022.S507
-rw-r--r--arch/arm/mm/proc-arm1026.S503
-rw-r--r--arch/arm/mm/proc-arm6_7.S427
-rw-r--r--arch/arm/mm/proc-arm720.S269
-rw-r--r--arch/arm/mm/proc-arm740.S174
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S251
-rw-r--r--arch/arm/mm/proc-arm920.S522
-rw-r--r--arch/arm/mm/proc-arm922.S492
-rw-r--r--arch/arm/mm/proc-arm925.S576
-rw-r--r--arch/arm/mm/proc-arm926.S542
-rw-r--r--arch/arm/mm/proc-arm940.S407
-rw-r--r--arch/arm/mm/proc-arm946.S462
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S136
-rw-r--r--arch/arm/mm/proc-fa526.S247
-rw-r--r--arch/arm/mm/proc-feroceon.S698
-rw-r--r--arch/arm/mm/proc-macros.S256
-rw-r--r--arch/arm/mm/proc-mohawk.S440
-rw-r--r--arch/arm/mm/proc-sa110.S253
-rw-r--r--arch/arm/mm/proc-sa1100.S332
-rw-r--r--arch/arm/mm/proc-syms.c51
-rw-r--r--arch/arm/mm/proc-v6.S320
-rw-r--r--arch/arm/mm/proc-v7.S508
-rw-r--r--arch/arm/mm/proc-xsc3.S594
-rw-r--r--arch/arm/mm/proc-xscale.S1018
-rw-r--r--arch/arm/mm/tlb-fa.S75
-rw-r--r--arch/arm/mm/tlb-v3.S52
-rw-r--r--arch/arm/mm/tlb-v4.S65
-rw-r--r--arch/arm/mm/tlb-v4wb.S77
-rw-r--r--arch/arm/mm/tlb-v4wbi.S68
-rw-r--r--arch/arm/mm/tlb-v6.S98
-rw-r--r--arch/arm/mm/tlb-v7.S94
-rw-r--r--arch/arm/mm/vmregion.c131
-rw-r--r--arch/arm/mm/vmregion.h29
-rw-r--r--arch/arm/nwfpe/ARM-gcc.h120
-rw-r--r--arch/arm/nwfpe/ChangeLog91
-rw-r--r--arch/arm/nwfpe/Makefile12
-rw-r--r--arch/arm/nwfpe/double_cpdo.c167
-rw-r--r--arch/arm/nwfpe/entry.S122
-rw-r--r--arch/arm/nwfpe/extended_cpdo.c154
-rw-r--r--arch/arm/nwfpe/fpa11.c129
-rw-r--r--arch/arm/nwfpe/fpa11.h121
-rw-r--r--arch/arm/nwfpe/fpa11.inl51
-rw-r--r--arch/arm/nwfpe/fpa11_cpdo.c137
-rw-r--r--arch/arm/nwfpe/fpa11_cpdt.c407
-rw-r--r--arch/arm/nwfpe/fpa11_cprt.c373
-rw-r--r--arch/arm/nwfpe/fpmodule.c190
-rw-r--r--arch/arm/nwfpe/fpmodule.h47
-rw-r--r--arch/arm/nwfpe/fpmodule.inl74
-rw-r--r--arch/arm/nwfpe/fpopcode.c89
-rw-r--r--arch/arm/nwfpe/fpopcode.h484
-rw-r--r--arch/arm/nwfpe/fpsr.h108
-rw-r--r--arch/arm/nwfpe/milieu.h48
-rw-r--r--arch/arm/nwfpe/single_cpdo.c124
-rw-r--r--arch/arm/nwfpe/softfloat-macros754
-rw-r--r--arch/arm/nwfpe/softfloat-specialize367
-rw-r--r--arch/arm/nwfpe/softfloat.c3435
-rw-r--r--arch/arm/nwfpe/softfloat.h281
-rw-r--r--arch/arm/oprofile/Makefile13
-rw-r--r--arch/arm/oprofile/common.c122
-rw-r--r--arch/arm/plat-iop/Makefile35
-rw-r--r--arch/arm/plat-iop/adma.c207
-rw-r--r--arch/arm/plat-iop/cp6.c51
-rw-r--r--arch/arm/plat-iop/gpio.c91
-rw-r--r--arch/arm/plat-iop/i2c.c80
-rw-r--r--arch/arm/plat-iop/io.c59
-rw-r--r--arch/arm/plat-iop/pci.c415
-rw-r--r--arch/arm/plat-iop/pmu.c40
-rw-r--r--arch/arm/plat-iop/setup.c39
-rw-r--r--arch/arm/plat-iop/time.c184
-rw-r--r--arch/arm/plat-mxc/3ds_debugboard.c196
-rwxr-xr-xarch/arm/plat-mxc/Kconfig173
-rwxr-xr-xarch/arm/plat-mxc/Makefile40
-rw-r--r--arch/arm/plat-mxc/ahci_sata.c194
-rw-r--r--arch/arm/plat-mxc/audmux-v1.c64
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c234
-rw-r--r--arch/arm/plat-mxc/avic.c158
-rwxr-xr-xarch/arm/plat-mxc/clock.c437
-rwxr-xr-xarch/arm/plat-mxc/cpu.c90
-rwxr-xr-xarch/arm/plat-mxc/cpufreq.c535
-rw-r--r--arch/arm/plat-mxc/devices.c91
-rwxr-xr-xarch/arm/plat-mxc/devices/Kconfig190
-rwxr-xr-xarch/arm/plat-mxc/devices/Makefile70
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-ahci-imx.c63
-rw-r--r--arch/arm/plat-mxc/devices/platform-dma.c41
-rw-r--r--arch/arm/plat-mxc/devices/platform-fec.c83
-rw-r--r--arch/arm/plat-mxc/devices/platform-flexcan.c68
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c90
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c110
-rw-r--r--arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c55
-rw-r--r--arch/arm/plat-mxc/devices/platform-gpio_keys.c27
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-anatop-thermal.c59
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-asrc.c72
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-caam.c107
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-dcp.c71
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-dma.c282
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-elcdif-fb.c58
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c64
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-esai.c75
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-fb.c58
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c55
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c109
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c50
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c33
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-i2c.c130
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-iim.c59
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-keypad.c72
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-mipi_csi2.c49
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-mipi_dsi.c63
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-ocotp.c103
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pcie.c64
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-perfmon.c158
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pm.c52
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pmu.c44
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pxp.c80
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-rngb.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-scc2.c284
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-spdc-fb.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c29
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c70
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-spdif.c69
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-ssi.c128
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-uart.c199
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-vdoa.c60
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-viim.c45
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx2-wdt.c91
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx21-hcd.c41
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_dvfs.c63
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_ipuv3.c239
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx_ldb.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx_snvs_rtc.c53
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_srtc.c63
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_tve.c47
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx_udc.c75
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_vpu.c179
-rw-r--r--arch/arm/plat-mxc/devices/platform-imxdi_rtc.c41
-rw-r--r--arch/arm/plat-mxc/devices/platform-ipu-core.c130
-rw-r--r--arch/arm/plat-mxc/devices/platform-mx1-camera.c42
-rw-r--r--arch/arm/plat-mxc/devices/platform-mx2-camera.c64
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-ehci.c152
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c53
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc-mmc.c73
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-mxc_gpu.c101
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_hdmi.c55
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_mlb.c76
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_nand.c83
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-mxc_pwm.c89
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_rnga.c56
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_rtc.c40
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_w1.c50
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c120
-rw-r--r--arch/arm/plat-mxc/devices/platform-spi_imx.c144
-rw-r--r--arch/arm/plat-mxc/devices/platform-viv_gpu.c127
-rwxr-xr-xarch/arm/plat-mxc/dvfs_core.c1132
-rwxr-xr-xarch/arm/plat-mxc/dvfs_per.c936
-rw-r--r--arch/arm/plat-mxc/epit.c225
-rw-r--r--arch/arm/plat-mxc/fuse.c165
-rwxr-xr-xarch/arm/plat-mxc/gpio.c377
-rw-r--r--arch/arm/plat-mxc/include/mach/3ds_debugboard.h18
-rwxr-xr-xarch/arm/plat-mxc/include/mach/ahci_sata.h62
-rw-r--r--arch/arm/plat-mxc/include/mach/anatop_thermal.h29
-rwxr-xr-xarch/arm/plat-mxc/include/mach/arc_otg.h348
-rw-r--r--arch/arm/plat-mxc/include/mach/audmux.h60
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h33
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lilly.h41
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lite.h42
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31moboard.h43
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm038.h36
-rw-r--r--arch/arm/plat-mxc/include/mach/clkdev.h7
-rwxr-xr-xarch/arm/plat-mxc/include/mach/clock.h85
-rwxr-xr-xarch/arm/plat-mxc/include/mach/common.h98
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S72
-rwxr-xr-xarch/arm/plat-mxc/include/mach/devices-common.h702
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h106
-rwxr-xr-xarch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h169
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S97
-rw-r--r--arch/arm/plat-mxc/include/mach/epdc.h68
-rw-r--r--arch/arm/plat-mxc/include/mach/esai.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/esdhc.h42
-rw-r--r--arch/arm/plat-mxc/include/mach/eukrea-baseboards.h50
-rwxr-xr-xarch/arm/plat-mxc/include/mach/fsl_usb.h107
-rwxr-xr-xarch/arm/plat-mxc/include/mach/fsl_usb_gadget.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/gpio.h67
-rw-r--r--arch/arm/plat-mxc/include/mach/gpmi-nfc.h71
-rwxr-xr-xarch/arm/plat-mxc/include/mach/hardware.h146
-rw-r--r--arch/arm/plat-mxc/include/mach/i2c.h25
-rw-r--r--arch/arm/plat-mxc/include/mach/iim.h77
-rw-r--r--arch/arm/plat-mxc/include/mach/imx-pm.h31
-rw-r--r--arch/arm/plat-mxc/include/mach/imx-uart.h39
-rwxr-xr-xarch/arm/plat-mxc/include/mach/imx_rfkill.h27
-rw-r--r--arch/arm/plat-mxc/include/mach/imxfb.h84
-rw-r--r--arch/arm/plat-mxc/include/mach/io.h49
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx1.h155
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx21.h122
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx25.h520
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx27.h205
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx2x.h230
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx3.h750
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx35.h1267
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx50.h979
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h1567
-rwxr-xr-xarch/arm/plat-mxc/include/mach/iomux-mx53.h2381
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx6dl.h3840
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx6q.h7403
-rwxr-xr-xarch/arm/plat-mxc/include/mach/iomux-mx6sl.h3117
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v1.h105
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v3.h193
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux.h26
-rwxr-xr-xarch/arm/plat-mxc/include/mach/ipu-v3.h765
-rw-r--r--arch/arm/plat-mxc/include/mach/ipu.h181
-rw-r--r--arch/arm/plat-mxc/include/mach/iram.h41
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h91
-rwxr-xr-xarch/arm/plat-mxc/include/mach/memory.h79
-rw-r--r--arch/arm/plat-mxc/include/mach/mipi_csi2.h121
-rw-r--r--arch/arm/plat-mxc/include/mach/mipi_dsi.h225
-rw-r--r--arch/arm/plat-mxc/include/mach/mmc.h39
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1.h173
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1_camera.h35
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21-usbhost.h38
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h188
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h107
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h251
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2_cam.h46
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2x.h144
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h206
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h189
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3_camera.h48
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3fb.h38
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3x.h208
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mx50.h352
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mx51.h382
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mx53.h392
-rw-r--r--arch/arm/plat-mxc/include/mach/mx6.h594
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc.h318
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc91231.h256
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_asrc.h26
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc_dvfs.h277
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc_edid.h105
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_ehci.h57
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_gpu.h24
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_hdmi.h1095
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_nand.h32
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_uart.h267
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc_vpu.h117
-rw-r--r--arch/arm/plat-mxc/include/mach/mxs.h113
-rw-r--r--arch/arm/plat-mxc/include/mach/pcie.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h480
-rw-r--r--arch/arm/plat-mxc/include/mach/regs-usbphy-others.h161
-rw-r--r--arch/arm/plat-mxc/include/mach/sdma.h66
-rwxr-xr-xarch/arm/plat-mxc/include/mach/sdram_autogating.h56
-rw-r--r--arch/arm/plat-mxc/include/mach/smp.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/spi.h27
-rw-r--r--arch/arm/plat-mxc/include/mach/ssi.h21
-rwxr-xr-xarch/arm/plat-mxc/include/mach/system.h48
-rw-r--r--arch/arm/plat-mxc/include/mach/timex.h33
-rw-r--r--arch/arm/plat-mxc/include/mach/ulpi.h16
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h145
-rw-r--r--arch/arm/plat-mxc/include/mach/usb.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/viv_gpu.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/vmalloc.h22
-rw-r--r--arch/arm/plat-mxc/iomux-v1.c220
-rw-r--r--arch/arm/plat-mxc/iomux-v3.c148
-rw-r--r--arch/arm/plat-mxc/iram_alloc.c73
-rw-r--r--arch/arm/plat-mxc/irq-common.c60
-rw-r--r--arch/arm/plat-mxc/irq-common.h29
-rwxr-xr-xarch/arm/plat-mxc/isp1504xc.c275
-rwxr-xr-xarch/arm/plat-mxc/pwm.c343
-rwxr-xr-xarch/arm/plat-mxc/serialxc.c64
-rw-r--r--arch/arm/plat-mxc/ssi-fiq-ksym.c20
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S136
-rw-r--r--arch/arm/plat-mxc/system.c118
-rw-r--r--arch/arm/plat-mxc/time.c343
-rw-r--r--arch/arm/plat-mxc/tzic.c205
-rw-r--r--arch/arm/plat-mxc/ulpi.c118
-rwxr-xr-xarch/arm/plat-mxc/usb_common.c972
-rw-r--r--arch/arm/plat-mxc/usb_hsic_xcvr.c56
-rwxr-xr-xarch/arm/plat-mxc/usb_wakeup.c275
-rwxr-xr-xarch/arm/plat-mxc/utmixc.c91
-rw-r--r--arch/arm/plat-nomadik/Kconfig24
-rw-r--r--arch/arm/plat-nomadik/Makefile5
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h96
-rw-r--r--arch/arm/plat-nomadik/include/plat/i2c.h39
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h54
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h144
-rw-r--r--arch/arm/plat-nomadik/include/plat/ske.h50
-rw-r--r--arch/arm/plat-nomadik/include/plat/ste_dma40.h219
-rw-r--r--arch/arm/plat-nomadik/timer.c174
-rw-r--r--arch/arm/plat-omap/Kconfig224
-rw-r--r--arch/arm/plat-omap/Makefile34
-rw-r--r--arch/arm/plat-omap/clock.c561
-rw-r--r--arch/arm/plat-omap/common.c68
-rw-r--r--arch/arm/plat-omap/counter_32k.c207
-rw-r--r--arch/arm/plat-omap/cpu-omap.c171
-rw-r--r--arch/arm/plat-omap/debug-devices.c96
-rw-r--r--arch/arm/plat-omap/debug-leds.c317
-rw-r--r--arch/arm/plat-omap/devices.c298
-rw-r--r--arch/arm/plat-omap/dma.c2143
-rw-r--r--arch/arm/plat-omap/dmtimer.c797
-rw-r--r--arch/arm/plat-omap/fb.c421
-rw-r--r--arch/arm/plat-omap/fb.h10
-rw-r--r--arch/arm/plat-omap/i2c.c262
-rw-r--r--arch/arm/plat-omap/include/plat/blizzard.h12
-rw-r--r--arch/arm/plat-omap/include/plat/board-ams-delta.h76
-rw-r--r--arch/arm/plat-omap/include/plat/board-sx1.h52
-rw-r--r--arch/arm/plat-omap/include/plat/board-voiceblue.h19
-rw-r--r--arch/arm/plat-omap/include/plat/board.h176
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev.h13
-rw-r--r--arch/arm/plat-omap/include/plat/clkdev_omap.h50
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h314
-rw-r--r--arch/arm/plat-omap/include/plat/common.h100
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h497
-rw-r--r--arch/arm/plat-omap/include/plat/dma-44xx.h147
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h533
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h97
-rw-r--r--arch/arm/plat-omap/include/plat/dsp.h31
-rw-r--r--arch/arm/plat-omap/include/plat/flash.h17
-rw-r--r--arch/arm/plat-omap/include/plat/fpga.h193
-rw-r--r--arch/arm/plat-omap/include/plat/gpio-switch.h54
-rw-r--r--arch/arm/plat-omap/include/plat/gpio.h242
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc-smc91x.h42
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc-smsc911x.h35
-rw-r--r--arch/arm/plat-omap/include/plat/gpmc.h160
-rw-r--r--arch/arm/plat-omap/include/plat/hardware.h291
-rw-r--r--arch/arm/plat-omap/include/plat/hwa742.h8
-rw-r--r--arch/arm/plat-omap/include/plat/i2c.h55
-rw-r--r--arch/arm/plat-omap/include/plat/io.h314
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h189
-rw-r--r--arch/arm/plat-omap/include/plat/iommu2.h96
-rw-r--r--arch/arm/plat-omap/include/plat/iovmm.h89
-rw-r--r--arch/arm/plat-omap/include/plat/irda.h33
-rw-r--r--arch/arm/plat-omap/include/plat/irqs-44xx.h144
-rw-r--r--arch/arm/plat-omap/include/plat/irqs.h446
-rw-r--r--arch/arm/plat-omap/include/plat/keypad.h50
-rw-r--r--arch/arm/plat-omap/include/plat/l3_2xxx.h20
-rw-r--r--arch/arm/plat-omap/include/plat/l3_3xxx.h20
-rw-r--r--arch/arm/plat-omap/include/plat/l4_2xxx.h24
-rw-r--r--arch/arm/plat-omap/include/plat/l4_3xxx.h34
-rw-r--r--arch/arm/plat-omap/include/plat/lcd_mipid.h29
-rw-r--r--arch/arm/plat-omap/include/plat/led.h24
-rw-r--r--arch/arm/plat-omap/include/plat/mailbox.h105
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h545
-rw-r--r--arch/arm/plat-omap/include/plat/mcspi.h26
-rw-r--r--arch/arm/plat-omap/include/plat/memory.h102
-rw-r--r--arch/arm/plat-omap/include/plat/menelaus.h49
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h182
-rw-r--r--arch/arm/plat-omap/include/plat/multi.h102
-rw-r--r--arch/arm/plat-omap/include/plat/mux.h454
-rw-r--r--arch/arm/plat-omap/include/plat/nand.h48
-rw-r--r--arch/arm/plat-omap/include/plat/omap-alsa.h123
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h360
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h116
-rw-r--r--arch/arm/plat-omap/include/plat/omap1510.h50
-rw-r--r--arch/arm/plat-omap/include/plat/omap16xx.h202
-rw-r--r--arch/arm/plat-omap/include/plat/omap24xx.h89
-rw-r--r--arch/arm/plat-omap/include/plat/omap34xx.h99
-rw-r--r--arch/arm/plat-omap/include/plat/omap4-keypad.h14
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h61
-rw-r--r--arch/arm/plat-omap/include/plat/omap730.h102
-rw-r--r--arch/arm/plat-omap/include/plat/omap7xx.h107
-rw-r--r--arch/arm/plat-omap/include/plat/omap850.h102
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h153
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h614
-rw-r--r--arch/arm/plat-omap/include/plat/onenand.h53
-rw-r--r--arch/arm/plat-omap/include/plat/param.h8
-rw-r--r--arch/arm/plat-omap/include/plat/prcm.h37
-rw-r--r--arch/arm/plat-omap/include/plat/sdrc.h165
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h117
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h100
-rw-r--r--arch/arm/plat-omap/include/plat/system.h17
-rw-r--r--arch/arm/plat-omap/include/plat/tc.h106
-rw-r--r--arch/arm/plat-omap/include/plat/ti816x.h27
-rw-r--r--arch/arm/plat-omap/include/plat/timex.h41
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h183
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h296
-rw-r--r--arch/arm/plat-omap/include/plat/vram.h62
-rw-r--r--arch/arm/plat-omap/include/plat/vrfb.h66
-rw-r--r--arch/arm/plat-omap/io.c141
-rw-r--r--arch/arm/plat-omap/iommu-debug.c418
-rw-r--r--arch/arm/plat-omap/iommu.c1102
-rw-r--r--arch/arm/plat-omap/iopgtable.h102
-rw-r--r--arch/arm/plat-omap/iovmm.c907
-rw-r--r--arch/arm/plat-omap/mailbox.c429
-rw-r--r--arch/arm/plat-omap/mcbsp.c1952
-rw-r--r--arch/arm/plat-omap/mux.c87
-rw-r--r--arch/arm/plat-omap/ocpi.c109
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c363
-rw-r--r--arch/arm/plat-omap/omap_device.c867
-rw-r--r--arch/arm/plat-omap/sram.c427
-rw-r--r--arch/arm/plat-omap/sram.h6
-rw-r--r--arch/arm/plat-omap/usb.c143
-rw-r--r--arch/arm/plat-orion/Makefile10
-rw-r--r--arch/arm/plat-orion/common.c956
-rw-r--r--arch/arm/plat-orion/gpio.c477
-rw-r--r--arch/arm/plat-orion/include/plat/audio.h11
-rw-r--r--arch/arm/plat-orion/include/plat/cache-feroceon-l2.h11
-rw-r--r--arch/arm/plat-orion/include/plat/common.h118
-rw-r--r--arch/arm/plat-orion/include/plat/ehci-orion.h27
-rw-r--r--arch/arm/plat-orion/include/plat/gpio.h45
-rw-r--r--arch/arm/plat-orion/include/plat/irq.h17
-rw-r--r--arch/arm/plat-orion/include/plat/mpp.h34
-rw-r--r--arch/arm/plat-orion/include/plat/mv_xor.h30
-rw-r--r--arch/arm/plat-orion/include/plat/mvsdio.h21
-rw-r--r--arch/arm/plat-orion/include/plat/orion_nand.h26
-rw-r--r--arch/arm/plat-orion/include/plat/orion_wdt.h18
-rw-r--r--arch/arm/plat-orion/include/plat/pcie.h35
-rw-r--r--arch/arm/plat-orion/include/plat/time.h20
-rw-r--r--arch/arm/plat-orion/irq.c34
-rw-r--r--arch/arm/plat-orion/mpp.c77
-rw-r--r--arch/arm/plat-orion/pcie.c286
-rw-r--r--arch/arm/plat-orion/time.c244
-rw-r--r--arch/arm/plat-pxa/Kconfig8
-rw-r--r--arch/arm/plat-pxa/Makefile13
-rw-r--r--arch/arm/plat-pxa/dma.c392
-rw-r--r--arch/arm/plat-pxa/gpio.c338
-rw-r--r--arch/arm/plat-pxa/include/plat/dma.h85
-rw-r--r--arch/arm/plat-pxa/include/plat/gpio.h64
-rw-r--r--arch/arm/plat-pxa/include/plat/mfp.h475
-rw-r--r--arch/arm/plat-pxa/include/plat/pxa27x_keypad.h69
-rw-r--r--arch/arm/plat-pxa/include/plat/pxa3xx_nand.h63
-rw-r--r--arch/arm/plat-pxa/include/plat/sdhci.h35
-rw-r--r--arch/arm/plat-pxa/mfp.c285
-rw-r--r--arch/arm/plat-pxa/pwm.c304
-rw-r--r--arch/arm/plat-pxa/ssp.c224
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig166
-rw-r--r--arch/arm/plat-s3c24xx/Makefile52
-rw-r--r--arch/arm/plat-s3c24xx/clock-dclk.c200
-rw-r--r--arch/arm/plat-s3c24xx/clock.c59
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c207
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq-debugfs.c199
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq.c716
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c248
-rw-r--r--arch/arm/plat-s3c24xx/devs.c552
-rw-r--r--arch/arm/plat-s3c24xx/dma.c1470
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c96
-rw-r--r--arch/arm/plat-s3c24xx/gpiolib.c229
-rw-r--r--arch/arm/plat-s3c24xx/include/mach/pwm-clock.h55
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/audio-simtec.h37
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/common-smdk.h15
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h287
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/fiq.h13
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h115
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/map.h100
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/mci.h52
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pll.h62
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-dma.h145
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-iis.h77
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-spi.h82
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/regs-udc.h153
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2400.h31
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2410.h33
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2412.h29
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2416.h31
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2443.h51
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c244x.h42
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/udc.h57
-rw-r--r--arch/arm/plat-s3c24xx/irq-pm.c95
-rw-r--r--arch/arm/plat-s3c24xx/irq.c676
-rw-r--r--arch/arm/plat-s3c24xx/pm-simtec.c67
-rw-r--r--arch/arm/plat-s3c24xx/pm.c149
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-clock.c268
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c64
-rw-r--r--arch/arm/plat-s3c24xx/s3c2410-iotiming.c478
-rw-r--r--arch/arm/plat-s3c24xx/s3c2412-iotiming.c286
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c472
-rw-r--r--arch/arm/plat-s3c24xx/setup-i2c.c27
-rw-r--r--arch/arm/plat-s3c24xx/setup-ts.c34
-rw-r--r--arch/arm/plat-s3c24xx/simtec-audio.c77
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S109
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c36
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c38
-rw-r--r--arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c36
-rw-r--r--arch/arm/plat-s5p/Kconfig96
-rw-r--r--arch/arm/plat-s5p/Makefile37
-rw-r--r--arch/arm/plat-s5p/clock.c193
-rw-r--r--arch/arm/plat-s5p/cpu.c126
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/dev-ehci.c57
-rw-r--r--arch/arm/plat-s5p/dev-fimc0.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc1.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc2.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc3.c43
-rw-r--r--arch/arm/plat-s5p/dev-onenand.c45
-rw-r--r--arch/arm/plat-s5p/dev-pmu.c36
-rw-r--r--arch/arm/plat-s5p/dev-uart.c197
-rw-r--r--arch/arm/plat-s5p/include/plat/camport.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/ehci.h21
-rw-r--r--arch/arm/plat-s5p/include/plat/exynos4.h34
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h115
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h60
-rw-r--r--arch/arm/plat-s5p/include/plat/mipi_csis.h43
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h153
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-s5p/include/plat/reset.h16
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h50
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-time.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6440.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6450.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pc100.h33
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pv210.h33
-rw-r--r--arch/arm/plat-s5p/include/plat/sysmmu.h95
-rw-r--r--arch/arm/plat-s5p/include/plat/system-reset.h31
-rw-r--r--arch/arm/plat-s5p/include/plat/usb-phy.h22
-rw-r--r--arch/arm/plat-s5p/irq-eint.c219
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c209
-rw-r--r--arch/arm/plat-s5p/irq-pm.c90
-rw-r--r--arch/arm/plat-s5p/irq.c70
-rw-r--r--arch/arm/plat-s5p/pm.c41
-rw-r--r--arch/arm/plat-s5p/s5p-time.c424
-rw-r--r--arch/arm/plat-s5p/setup-mipiphy.c63
-rw-r--r--arch/arm/plat-s5p/sysmmu.c312
-rw-r--r--arch/arm/plat-samsung/Kconfig364
-rw-r--r--arch/arm/plat-samsung/Makefile83
-rw-r--r--arch/arm/plat-samsung/adc.c488
-rw-r--r--arch/arm/plat-samsung/clock-clksrc.c212
-rw-r--r--arch/arm/plat-samsung/clock.c541
-rw-r--r--arch/arm/plat-samsung/dev-adc.c46
-rw-r--r--arch/arm/plat-samsung/dev-asocdma.c25
-rw-r--r--arch/arm/plat-samsung/dev-fb.c73
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c79
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c79
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c80
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c83
-rw-r--r--arch/arm/plat-samsung/dev-hwmon.c42
-rw-r--r--arch/arm/plat-samsung/dev-i2c0.c72
-rw-r--r--arch/arm/plat-samsung/dev-i2c1.c69
-rw-r--r--arch/arm/plat-samsung/dev-i2c2.c70
-rw-r--r--arch/arm/plat-samsung/dev-i2c3.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c4.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c5.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c6.c68
-rw-r--r--arch/arm/plat-samsung/dev-i2c7.c68
-rw-r--r--arch/arm/plat-samsung/dev-ide.c44
-rw-r--r--arch/arm/plat-samsung/dev-keypad.c50
-rw-r--r--arch/arm/plat-samsung/dev-nand.c128
-rw-r--r--arch/arm/plat-samsung/dev-onenand.c43
-rw-r--r--arch/arm/plat-samsung/dev-pwm.c53
-rw-r--r--arch/arm/plat-samsung/dev-rtc.c43
-rw-r--r--arch/arm/plat-samsung/dev-ts.c60
-rw-r--r--arch/arm/plat-samsung/dev-uart.c46
-rw-r--r--arch/arm/plat-samsung/dev-usb-hsotg.c48
-rw-r--r--arch/arm/plat-samsung/dev-usb.c70
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c40
-rw-r--r--arch/arm/plat-samsung/dma.c84
-rw-r--r--arch/arm/plat-samsung/gpio-config.c431
-rw-r--r--arch/arm/plat-samsung/gpio.c167
-rw-r--r--arch/arm/plat-samsung/include/plat/adc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/adc.h35
-rw-r--r--arch/arm/plat-samsung/include/plat/ata-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/ata.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/audio.h58
-rw-r--r--arch/arm/plat-samsung/include/plat/clock-clksrc.h83
-rw-r--r--arch/arm/plat-samsung/include/plat/clock.h120
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq.h145
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h94
-rw-r--r--arch/arm/plat-samsung/include/plat/debug-macro.S87
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h167
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-core.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-s3c24xx.h84
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h128
-rw-r--r--arch/arm/plat-samsung/include/plat/fb-core.h29
-rw-r--r--arch/arm/plat-samsung/include/plat/fb.h97
-rw-r--r--arch/arm/plat-samsung/include/plat/fimc-core.h49
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h251
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg.h244
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h171
-rw-r--r--arch/arm/plat-samsung/include/plat/hwmon.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/iic-core.h42
-rw-r--r--arch/arm/plat-samsung/include/plat/iic.h74
-rw-r--r--arch/arm/plat-samsung/include/plat/irq-uart.h20
-rw-r--r--arch/arm/plat-samsung/include/plat/irq-vic-timer.h13
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad-core.h31
-rw-r--r--arch/arm/plat-samsung/include/plat/keypad.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/map-base.h46
-rw-r--r--arch/arm/plat-samsung/include/plat/nand-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/nand.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/onenand-core.h37
-rw-r--r--arch/arm/plat-samsung/include/plat/pd.h30
-rw-r--r--arch/arm/plat-samsung/include/plat/pll6553x.h51
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h185
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-ac97.h67
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-adc.h64
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-ata.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb-v4.h159
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-fb.h386
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-iic.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-irqtype.h21
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-nand.h123
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-onenand.h63
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h68
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-sdhci.h87
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h285
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-timer.h124
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h50
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h379
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-watchdog.h41
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h98
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h32
-rw-r--r--arch/arm/plat-samsung/include/plat/s3c64xx-spi.h75
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h393
-rw-r--r--arch/arm/plat-samsung/include/plat/ts.h25
-rw-r--r--arch/arm/plat-samsung/include/plat/udc-hs.h29
-rw-r--r--arch/arm/plat-samsung/include/plat/uncompress.h184
-rw-r--r--arch/arm/plat-samsung/include/plat/usb-control.h43
-rw-r--r--arch/arm/plat-samsung/include/plat/wakeup-mask.h44
-rw-r--r--arch/arm/plat-samsung/include/plat/watchdog-reset.h49
-rw-r--r--arch/arm/plat-samsung/init.c160
-rw-r--r--arch/arm/plat-samsung/irq-uart.c89
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c77
-rw-r--r--arch/arm/plat-samsung/pd.c95
-rw-r--r--arch/arm/plat-samsung/platformdata.c37
-rw-r--r--arch/arm/plat-samsung/pm-check.c237
-rw-r--r--arch/arm/plat-samsung/pm-gpio.c384
-rw-r--r--arch/arm/plat-samsung/pm.c365
-rw-r--r--arch/arm/plat-samsung/pwm-clock.c455
-rw-r--r--arch/arm/plat-samsung/pwm.c413
-rw-r--r--arch/arm/plat-samsung/s3c-pl330.c1244
-rw-r--r--arch/arm/plat-samsung/time.c285
-rw-r--r--arch/arm/plat-samsung/wakeup-mask.c47
-rw-r--r--arch/arm/plat-spear/Kconfig31
-rw-r--r--arch/arm/plat-spear/Makefile8
-rw-r--r--arch/arm/plat-spear/clock.c1008
-rw-r--r--arch/arm/plat-spear/include/plat/clkdev.h20
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h249
-rw-r--r--arch/arm/plat-spear/include/plat/debug-macro.S36
-rw-r--r--arch/arm/plat-spear/include/plat/gpio.h24
-rw-r--r--arch/arm/plat-spear/include/plat/hardware.h23
-rw-r--r--arch/arm/plat-spear/include/plat/io.h22
-rw-r--r--arch/arm/plat-spear/include/plat/keyboard.h141
-rw-r--r--arch/arm/plat-spear/include/plat/memory.h20
-rw-r--r--arch/arm/plat-spear/include/plat/padmux.h92
-rw-r--r--arch/arm/plat-spear/include/plat/shirq.h73
-rw-r--r--arch/arm/plat-spear/include/plat/system.h41
-rw-r--r--arch/arm/plat-spear/include/plat/timex.h19
-rw-r--r--arch/arm/plat-spear/include/plat/uncompress.h43
-rw-r--r--arch/arm/plat-spear/include/plat/vmalloc.h19
-rw-r--r--arch/arm/plat-spear/padmux.c164
-rw-r--r--arch/arm/plat-spear/shirq.c118
-rw-r--r--arch/arm/plat-spear/time.c237
-rw-r--r--arch/arm/plat-tcc/Kconfig20
-rw-r--r--arch/arm/plat-tcc/Makefile3
-rw-r--r--arch/arm/plat-tcc/clock.c179
-rw-r--r--arch/arm/plat-tcc/include/mach/clkdev.h7
-rw-r--r--arch/arm/plat-tcc/include/mach/clock.h48
-rw-r--r--arch/arm/plat-tcc/include/mach/debug-macro.S32
-rw-r--r--arch/arm/plat-tcc/include/mach/entry-macro.S68
-rw-r--r--arch/arm/plat-tcc/include/mach/hardware.h43
-rw-r--r--arch/arm/plat-tcc/include/mach/io.h23
-rw-r--r--arch/arm/plat-tcc/include/mach/irqs.h83
-rw-r--r--arch/arm/plat-tcc/include/mach/memory.h18
-rw-r--r--arch/arm/plat-tcc/include/mach/system.h31
-rw-r--r--arch/arm/plat-tcc/include/mach/tcc8k-regs.h807
-rw-r--r--arch/arm/plat-tcc/include/mach/timex.h5
-rw-r--r--arch/arm/plat-tcc/include/mach/uncompress.h34
-rw-r--r--arch/arm/plat-tcc/include/mach/vmalloc.h10
-rw-r--r--arch/arm/plat-tcc/system.c25
-rw-r--r--arch/arm/plat-versatile/Kconfig17
-rw-r--r--arch/arm/plat-versatile/Makefile7
-rw-r--r--arch/arm/plat-versatile/clcd.c182
-rw-r--r--arch/arm/plat-versatile/clock.c74
-rw-r--r--arch/arm/plat-versatile/fpga-irq.c72
-rw-r--r--arch/arm/plat-versatile/headsmp.S40
-rw-r--r--arch/arm/plat-versatile/include/plat/clcd.h9
-rw-r--r--arch/arm/plat-versatile/include/plat/clock.h15
-rw-r--r--arch/arm/plat-versatile/include/plat/fpga-irq.h12
-rw-r--r--arch/arm/plat-versatile/include/plat/sched_clock.h6
-rw-r--r--arch/arm/plat-versatile/leds.c103
-rw-r--r--arch/arm/plat-versatile/localtimer.c27
-rw-r--r--arch/arm/plat-versatile/platsmp.c105
-rw-r--r--arch/arm/plat-versatile/sched-clock.c58
-rw-r--r--arch/arm/tools/Makefile10
-rw-r--r--arch/arm/tools/gen-mach-types72
-rw-r--r--arch/arm/tools/mach-types1124
-rw-r--r--arch/arm/vfp/Makefile15
-rw-r--r--arch/arm/vfp/entry.S70
-rw-r--r--arch/arm/vfp/vfp.h380
-rw-r--r--arch/arm/vfp/vfpdouble.c1204
-rw-r--r--arch/arm/vfp/vfphw.S284
-rw-r--r--arch/arm/vfp/vfpinstr.h88
-rw-r--r--arch/arm/vfp/vfpmodule.c613
-rw-r--r--arch/arm/vfp/vfpsingle.c1244
4156 files changed, 833837 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
new file mode 100755
index 00000000..f3e17d9a
--- /dev/null
+++ b/arch/arm/Kconfig
@@ -0,0 +1,2101 @@
+config ARM
+ bool
+ default y
+ select HAVE_AOUT
+ select HAVE_DMA_API_DEBUG
+ select HAVE_IDE
+ select HAVE_MEMBLOCK
+ select RTC_LIB
+ select SYS_SUPPORTS_APM_EMULATION
+ select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
+ select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
+ select HAVE_ARCH_KGDB
+ select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL)
+ select HAVE_KRETPROBES if (HAVE_KPROBES)
+ select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
+ select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
+ select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
+ select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_KERNEL_GZIP
+ select HAVE_KERNEL_LZO
+ select HAVE_KERNEL_LZMA
+ select HAVE_IRQ_WORK
+ select HAVE_PERF_EVENTS
+ select PERF_USE_VMALLOC
+ select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
+ select HAVE_C_RECORDMCOUNT
+ select HAVE_GENERIC_HARDIRQS
+ select HAVE_SPARSE_IRQ
+ select GENERIC_IRQ_SHOW
+ help
+ The ARM series is a line of low-power-consumption RISC chip designs
+ licensed by ARM Ltd and targeted at embedded applications and
+ handhelds such as the Compaq IPAQ. ARM-based PCs are no longer
+ manufactured, but legacy ARM-based PC hardware remains popular in
+ Europe. There is an ARM Linux project with a web page at
+ <http://www.arm.linux.org.uk/>.
+
+config HAVE_PWM
+ bool
+
+config MIGHT_HAVE_PCI
+ bool
+
+config SYS_SUPPORTS_APM_EMULATION
+ bool
+
+config HAVE_SCHED_CLOCK
+ bool
+
+config GENERIC_GPIO
+ bool
+
+config ARCH_USES_GETTIMEOFFSET
+ bool
+ default n
+
+config GENERIC_CLOCKEVENTS
+ bool
+
+config GENERIC_CLOCKEVENTS_BROADCAST
+ bool
+ depends on GENERIC_CLOCKEVENTS
+ default y if SMP
+
+config KTIME_SCALAR
+ bool
+ default y
+
+config HAVE_TCM
+ bool
+ select GENERIC_ALLOCATOR
+
+config HAVE_PROC_CPU
+ bool
+
+config NO_IOPORT
+ bool
+
+config EISA
+ bool
+ ---help---
+ The Extended Industry Standard Architecture (EISA) bus was
+ developed as an open alternative to the IBM MicroChannel bus.
+
+ The EISA bus provided some of the features of the IBM MicroChannel
+ bus while maintaining backward compatibility with cards made for
+ the older ISA bus. The EISA bus saw limited use between 1988 and
+ 1995 when it was made obsolete by the PCI bus.
+
+ Say Y here if you are building a kernel for an EISA-based machine.
+
+ Otherwise, say N.
+
+config SBUS
+ bool
+
+config MCA
+ bool
+ help
+ MicroChannel Architecture is found in some IBM PS/2 machines and
+ laptops. It is a bus system similar to PCI or ISA. See
+ <file:Documentation/mca.txt> (and especially the web page given
+ there) before attempting to build an MCA bus kernel.
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
+config HAVE_LATENCYTOP_SUPPORT
+ bool
+ depends on !SMP
+ default y
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default y
+
+config HARDIRQS_SW_RESEND
+ bool
+ default y
+
+config GENERIC_IRQ_PROBE
+ bool
+ default y
+
+config GENERIC_LOCKBREAK
+ bool
+ default y
+ depends on SMP && PREEMPT
+
+config RWSEM_GENERIC_SPINLOCK
+ bool
+ default y
+
+config RWSEM_XCHGADD_ALGORITHM
+ bool
+
+config ARCH_HAS_ILOG2_U32
+ bool
+
+config ARCH_HAS_ILOG2_U64
+ bool
+
+config ARCH_HAS_CPUFREQ
+ bool
+ help
+ Internal node to signify that the ARCH has CPUFREQ support
+ and that the relevant menu configurations are displayed for
+ it.
+
+config ARCH_HAS_CPU_IDLE_WAIT
+ def_bool y
+
+config GENERIC_HWEIGHT
+ bool
+ default y
+
+config GENERIC_CALIBRATE_DELAY
+ bool
+ default y
+
+config ARCH_MAY_HAVE_PC_FDC
+ bool
+
+config ZONE_DMA
+ bool
+
+config NEED_DMA_MAP_STATE
+ def_bool y
+
+config GENERIC_ISA_DMA
+ bool
+
+config FIQ
+ bool
+
+config ARCH_MTD_XIP
+ bool
+
+config VECTORS_BASE
+ hex
+ default 0xffff0000 if MMU || CPU_HIGH_VECTOR
+ default DRAM_BASE if REMAP_VECTORS_TO_RAM
+ default 0x00000000
+ help
+ The base address of exception vectors.
+
+config ARM_PATCH_PHYS_VIRT
+ bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on !XIP_KERNEL && MMU
+ depends on !ARCH_REALVIEW || !SPARSEMEM
+ help
+ Patch phys-to-virt and virt-to-phys translation functions at
+ boot and module load time according to the position of the
+ kernel in system memory.
+
+ This can only be used with non-XIP MMU kernels where the base
+ of physical memory is at a 16MB boundary, or theoretically 64K
+ for the MSM machine class.
+
+config ARM_PATCH_PHYS_VIRT_16BIT
+ def_bool y
+ depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
+ help
+ This option extends the physical to virtual translation patching
+ to allow physical memory down to a theoretical minimum of 64K
+ boundaries.
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "System Type"
+
+config MMU
+ bool "MMU-based Paged Memory Management Support"
+ default y
+ help
+ Select if you want MMU-based virtualised addressing space
+ support by paged memory management. If unsure, say 'Y'.
+
+#
+# The "ARM system type" choice list is ordered alphabetically by option
+# text. Please add new entries in the option alphabetic order.
+#
+choice
+ prompt "ARM system type"
+ default ARCH_VERSATILE
+
+config ARCH_INTEGRATOR
+ bool "ARM Ltd. Integrator family"
+ select ARM_AMBA
+ select ARCH_HAS_CPUFREQ
+ select CLKDEV_LOOKUP
+ select ICST
+ select GENERIC_CLOCKEVENTS
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_FPGA_IRQ
+ help
+ Support for ARM's Integrator platform.
+
+config ARCH_REALVIEW
+ bool "ARM Ltd. RealView family"
+ select ARM_AMBA
+ select CLKDEV_LOOKUP
+ select ICST
+ select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLCD
+ select ARM_TIMER_SP804
+ select GPIO_PL061 if GPIOLIB
+ help
+ This enables support for ARM Ltd RealView boards.
+
+config ARCH_VERSATILE
+ bool "ARM Ltd. Versatile family"
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKDEV_LOOKUP
+ select ICST
+ select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLCD
+ select PLAT_VERSATILE_FPGA_IRQ
+ select ARM_TIMER_SP804
+ help
+ This enables support for ARM Ltd Versatile board.
+
+config ARCH_VEXPRESS
+ bool "ARM Ltd. Versatile Express family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ select HAVE_PATA_PLATFORM
+ select ICST
+ select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLCD
+ help
+ This enables support for the ARM Ltd Versatile Express boards.
+
+config ARCH_AT91
+ bool "Atmel AT91"
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select CLKDEV_LOOKUP
+ select ARM_PATCH_PHYS_VIRT if MMU
+ help
+ This enables support for systems based on the Atmel AT91RM9200,
+ AT91SAM9 and AT91CAP9 processors.
+
+config ARCH_BCMRING
+ bool "Broadcom BCMRING"
+ depends on MMU
+ select CPU_V6
+ select ARM_AMBA
+ select ARM_TIMER_SP804
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ help
+ Support for Broadcom's BCMRing platform.
+
+config ARCH_CLPS711X
+ bool "Cirrus Logic CLPS711x/EP721x-based"
+ select CPU_ARM720T
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for Cirrus Logic 711x/721x based boards.
+
+config ARCH_CNS3XXX
+ bool "Cavium Networks CNS3XXX family"
+ select CPU_V6
+ select GENERIC_CLOCKEVENTS
+ select ARM_GIC
+ select MIGHT_HAVE_PCI
+ select PCI_DOMAINS if PCI
+ help
+ Support for Cavium Networks CNS3XXX platform.
+
+config ARCH_GEMINI
+ bool "Cortina Systems Gemini"
+ select CPU_FA526
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for the Cortina Systems Gemini family SoCs
+
+config ARCH_EBSA110
+ bool "EBSA-110"
+ select CPU_SA110
+ select ISA
+ select NO_IOPORT
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ This is an evaluation board for the StrongARM processor available
+ from Digital. It has limited hardware on-board, including an
+ Ethernet interface, two PCMCIA sockets, two serial ports and a
+ parallel port.
+
+config ARCH_EP93XX
+ bool "EP93xx-based"
+ select CPU_ARM920T
+ select ARM_AMBA
+ select ARM_VIC
+ select CLKDEV_LOOKUP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ This enables support for the Cirrus EP93xx series of CPUs.
+
+config ARCH_FOOTBRIDGE
+ bool "FootBridge"
+ select CPU_SA110
+ select FOOTBRIDGE
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for systems based on the DC21285 companion chip
+ ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
+
+config ARCH_MXC
+ bool "Freescale MXC/iMX-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select HAVE_SCHED_CLOCK
+ select ZONE_DMA
+ help
+ Support for Freescale MXC/iMX-based family of processors
+
+config ARCH_MXS
+ bool "Freescale MXS-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ help
+ Support for Freescale MXS-based family of processors
+
+config ARCH_NETX
+ bool "Hilscher NetX based"
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select ARM_VIC
+ select GENERIC_CLOCKEVENTS
+ help
+ This enables support for systems based on the Hilscher NetX Soc
+
+config ARCH_H720X
+ bool "Hynix HMS720x-based"
+ select CPU_ARM720T
+ select ISA_DMA_API
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ This enables support for systems based on the Hynix HMS720x
+
+config ARCH_IOP13XX
+ bool "IOP13xx-based"
+ depends on MMU
+ select CPU_XSC3
+ select PLAT_IOP
+ select PCI
+ select ARCH_SUPPORTS_MSI
+ select VMSPLIT_1G
+ help
+ Support for Intel's IOP13XX (XScale) family of processors.
+
+config ARCH_IOP32X
+ bool "IOP32x-based"
+ depends on MMU
+ select CPU_XSCALE
+ select PLAT_IOP
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for Intel's 80219 and IOP32X (XScale) family of
+ processors.
+
+config ARCH_IOP33X
+ bool "IOP33x-based"
+ depends on MMU
+ select CPU_XSCALE
+ select PLAT_IOP
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for Intel's IOP33X (XScale) family of processors.
+
+config ARCH_IXP23XX
+ bool "IXP23XX-based"
+ depends on MMU
+ select CPU_XSC3
+ select PCI
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for Intel's IXP23xx (XScale) family of processors.
+
+config ARCH_IXP2000
+ bool "IXP2400/2800-based"
+ depends on MMU
+ select CPU_XSCALE
+ select PCI
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for Intel's IXP2400/2800 (XScale) family of processors.
+
+config ARCH_IXP4XX
+ bool "IXP4xx-based"
+ depends on MMU
+ select CLKSRC_MMIO
+ select CPU_XSCALE
+ select GENERIC_GPIO
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select MIGHT_HAVE_PCI
+ select DMABOUNCE if PCI
+ help
+ Support for Intel's IXP4XX (XScale) family of processors.
+
+config ARCH_DOVE
+ bool "Marvell Dove"
+ select CPU_V7
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select PLAT_ORION
+ help
+ Support for the Marvell Dove SoC 88AP510
+
+config ARCH_KIRKWOOD
+ bool "Marvell Kirkwood"
+ select CPU_FEROCEON
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select PLAT_ORION
+ help
+ Support for the following Marvell Kirkwood series SoCs:
+ 88F6180, 88F6192 and 88F6281.
+
+config ARCH_LOKI
+ bool "Marvell Loki (88RC8480)"
+ select CPU_FEROCEON
+ select GENERIC_CLOCKEVENTS
+ select PLAT_ORION
+ help
+ Support for the Marvell Loki (88RC8480) SoC.
+
+config ARCH_LPC32XX
+ bool "NXP LPC32XX"
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_IDE
+ select ARM_AMBA
+ select USB_ARCH_HAS_OHCI
+ select CLKDEV_LOOKUP
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for the NXP LPC32XX family of processors
+
+config ARCH_MV78XX0
+ bool "Marvell MV78xx0"
+ select CPU_FEROCEON
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select PLAT_ORION
+ help
+ Support for the following Marvell MV78xx0 series SoCs:
+ MV781x0, MV782x0.
+
+config ARCH_ORION5X
+ bool "Marvell Orion"
+ depends on MMU
+ select CPU_FEROCEON
+ select PCI
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select PLAT_ORION
+ help
+ Support for the following Marvell Orion 5x series SoCs:
+ Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182),
+ Orion-2 (5281), Orion-1-90 (6183).
+
+config ARCH_MMP
+ bool "Marvell PXA168/910/MMP2"
+ depends on MMU
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select TICK_ONESHOT
+ select PLAT_PXA
+ select SPARSE_IRQ
+ help
+ Support for Marvell's PXA168/PXA910(MMP) and MMP2 processor line.
+
+config ARCH_KS8695
+ bool "Micrel/Kendin KS8695"
+ select CPU_ARM922T
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
+ System-on-Chip devices.
+
+config ARCH_W90X900
+ bool "Nuvoton W90X900 CPU"
+ select CPU_ARM926T
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for Nuvoton (Winbond logic dept.) ARM9 processor,
+ At present, the w90x900 has been renamed nuc900, regarding
+ the ARM series product line, you can login the following
+ link address to know more.
+
+ <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
+ ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
+
+config ARCH_NUC93X
+ bool "Nuvoton NUC93X CPU"
+ select CPU_ARM926T
+ select CLKDEV_LOOKUP
+ help
+ Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
+ low-power and high performance MPEG-4/JPEG multimedia controller chip.
+
+config ARCH_TEGRA
+ bool "NVIDIA Tegra"
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select HAVE_SCHED_CLOCK
+ select ARCH_HAS_BARRIERS if CACHE_L2X0
+ select ARCH_HAS_CPUFREQ
+ help
+ This enables support for NVIDIA Tegra based systems (Tegra APX,
+ Tegra 6xx and Tegra 2 series).
+
+config ARCH_PNX4008
+ bool "Philips Nexperia PNX4008 Mobile"
+ select CPU_ARM926T
+ select CLKDEV_LOOKUP
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ This enables support for Philips PNX4008 mobile platform.
+
+config ARCH_PXA
+ bool "PXA2xx/PXA3xx-based"
+ depends on MMU
+ select ARCH_MTD_XIP
+ select ARCH_HAS_CPUFREQ
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select ARCH_REQUIRE_GPIOLIB
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select TICK_ONESHOT
+ select PLAT_PXA
+ select SPARSE_IRQ
+ help
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+
+config ARCH_MSM
+ bool "Qualcomm MSM"
+ select HAVE_CLK
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ help
+ Support for Qualcomm MSM/QSD based systems. This runs on the
+ apps processor of the MSM/QSD and depends on a shared memory
+ interface to the modem processor which runs the baseband
+ stack and controls some vital subsystems
+ (clock and power control, etc).
+
+config ARCH_SHMOBILE
+ bool "Renesas SH-Mobile / R-Mobile"
+ select HAVE_CLK
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select NO_IOPORT
+ select SPARSE_IRQ
+ select MULTI_IRQ_HANDLER
+ help
+ Support for Renesas's SH-Mobile and R-Mobile ARM platforms.
+
+config ARCH_RPC
+ bool "RiscPC"
+ select ARCH_ACORN
+ select FIQ
+ select TIMER_ACORN
+ select ARCH_MAY_HAVE_PC_FDC
+ select HAVE_PATA_PLATFORM
+ select ISA_DMA_API
+ select NO_IOPORT
+ select ARCH_SPARSEMEM_ENABLE
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ On the Acorn Risc-PC, Linux can support the internal IDE disk and
+ CD-ROM interface, serial and parallel port, and the floppy drive.
+
+config ARCH_SA1100
+ bool "SA1100-based"
+ select CLKSRC_MMIO
+ select CPU_SA1100
+ select ISA
+ select ARCH_SPARSEMEM_ENABLE
+ select ARCH_MTD_XIP
+ select ARCH_HAS_CPUFREQ
+ select CPU_FREQ
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ select HAVE_SCHED_CLOCK
+ select TICK_ONESHOT
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for StrongARM 11x0 based boards.
+
+config ARCH_S3C2410
+ bool "Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443, S3C2450"
+ select GENERIC_GPIO
+ select ARCH_HAS_CPUFREQ
+ select HAVE_CLK
+ select ARCH_USES_GETTIMEOFFSET
+ select HAVE_S3C2410_I2C if I2C
+ help
+ Samsung S3C2410X CPU based systems, such as the Simtec Electronics
+ BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
+ the Samsung SMDK2410 development board (and derivatives).
+
+ Note, the S3C2416 and the S3C2450 are so close that they even share
+ the same SoC ID code. This means that there is no separate machine
+ directory (no arch/arm/mach-s3c2450) as the S3C2416 was first.
+
+config ARCH_S3C64XX
+ bool "Samsung S3C64XX"
+ select PLAT_SAMSUNG
+ select CPU_V6
+ select ARM_VIC
+ select HAVE_CLK
+ select NO_IOPORT
+ select ARCH_USES_GETTIMEOFFSET
+ select ARCH_HAS_CPUFREQ
+ select ARCH_REQUIRE_GPIOLIB
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ select SAMSUNG_IRQ_UART
+ select S3C_GPIO_TRACK
+ select S3C_GPIO_PULL_UPDOWN
+ select S3C_GPIO_CFG_S3C24XX
+ select S3C_GPIO_CFG_S3C64XX
+ select S3C_DEV_NAND
+ select USB_ARCH_HAS_OHCI
+ select SAMSUNG_GPIOLIB_4BIT
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ help
+ Samsung S3C64XX series based systems
+
+config ARCH_S5P64X0
+ bool "Samsung S5P6440 S5P6450"
+ select CPU_V6
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C_RTC if RTC_CLASS
+ help
+ Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
+ SMDK6450.
+
+config ARCH_S5PC100
+ bool "Samsung S5PC100"
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select CPU_V7
+ select ARM_L1_CACHE_SHIFT_6
+ select ARCH_USES_GETTIMEOFFSET
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C_RTC if RTC_CLASS
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ help
+ Samsung S5PC100 series based systems
+
+config ARCH_S5PV210
+ bool "Samsung S5PV210/S5PC110"
+ select CPU_V7
+ select ARCH_SPARSEMEM_ENABLE
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select ARM_L1_CACHE_SHIFT_6
+ select ARCH_HAS_CPUFREQ
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select HAVE_S3C2410_I2C if I2C
+ select HAVE_S3C_RTC if RTC_CLASS
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ help
+ Samsung S5PV210/S5PC110 series based systems
+
+config ARCH_EXYNOS4
+ bool "Samsung EXYNOS4"
+ select CPU_V7
+ select ARCH_SPARSEMEM_ENABLE
+ select GENERIC_GPIO
+ select HAVE_CLK
+ 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
+ help
+ Samsung EXYNOS4 series based systems
+
+config ARCH_SHARK
+ bool "Shark"
+ select CPU_SA110
+ select ISA
+ select ISA_DMA
+ select ZONE_DMA
+ select PCI
+ select ARCH_USES_GETTIMEOFFSET
+ help
+ Support for the StrongARM based Digital DNARD machine, also known
+ as "Shark" (<http://www.shark-linux.de/shark.html>).
+
+config ARCH_TCC_926
+ bool "Telechips TCC ARM926-based systems"
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select HAVE_CLK
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ help
+ Support for Telechips TCC ARM926-based systems.
+
+config ARCH_U300
+ bool "ST-Ericsson U300 Series"
+ depends on MMU
+ select CLKSRC_MMIO
+ select CPU_ARM926T
+ select HAVE_SCHED_CLOCK
+ select HAVE_TCM
+ select ARM_AMBA
+ select ARM_VIC
+ select GENERIC_CLOCKEVENTS
+ select CLKDEV_LOOKUP
+ select GENERIC_GPIO
+ help
+ Support for ST-Ericsson U300 series mobile platforms.
+
+config ARCH_U8500
+ bool "ST-Ericsson U8500 Series"
+ select CPU_V7
+ select ARM_AMBA
+ select GENERIC_CLOCKEVENTS
+ select CLKDEV_LOOKUP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_CPUFREQ
+ help
+ Support for ST-Ericsson's Ux500 architecture
+
+config ARCH_NOMADIK
+ bool "STMicroelectronics Nomadik"
+ select ARM_AMBA
+ select ARM_VIC
+ select CPU_ARM926T
+ select CLKDEV_LOOKUP
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for the Nomadik platform by ST-Ericsson
+
+config ARCH_DAVINCI
+ bool "TI DaVinci"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select ZONE_DMA
+ select HAVE_IDE
+ select CLKDEV_LOOKUP
+ select GENERIC_ALLOCATOR
+ select GENERIC_IRQ_CHIP
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ help
+ Support for TI's DaVinci platform.
+
+config ARCH_OMAP
+ bool "TI OMAP"
+ select HAVE_CLK
+ select ARCH_REQUIRE_GPIOLIB
+ select ARCH_HAS_CPUFREQ
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+ select ARCH_HAS_HOLES_MEMORYMODEL
+ help
+ Support for TI's OMAP platform (OMAP1/2/3/4).
+
+config PLAT_SPEAR
+ bool "ST SPEAr"
+ select ARM_AMBA
+ select ARCH_REQUIRE_GPIOLIB
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ select GENERIC_CLOCKEVENTS
+ select HAVE_CLK
+ help
+ Support for ST's SPEAr platform (SPEAr3xx, SPEAr6xx and SPEAr13xx).
+
+config ARCH_VT8500
+ bool "VIA/WonderMedia 85xx"
+ select CPU_ARM926T
+ select GENERIC_GPIO
+ select ARCH_HAS_CPUFREQ
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_PWM
+ help
+ Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
+endchoice
+
+#
+# This is sorted alphabetically by mach-* pathname. However, plat-*
+# Kconfigs may be included either alphabetically (according to the
+# plat- suffix) or along side the corresponding mach-* source.
+#
+source "arch/arm/mach-at91/Kconfig"
+
+source "arch/arm/mach-bcmring/Kconfig"
+
+source "arch/arm/mach-clps711x/Kconfig"
+
+source "arch/arm/mach-cns3xxx/Kconfig"
+
+source "arch/arm/mach-davinci/Kconfig"
+
+source "arch/arm/mach-dove/Kconfig"
+
+source "arch/arm/mach-ep93xx/Kconfig"
+
+source "arch/arm/mach-footbridge/Kconfig"
+
+source "arch/arm/mach-gemini/Kconfig"
+
+source "arch/arm/mach-h720x/Kconfig"
+
+source "arch/arm/mach-integrator/Kconfig"
+
+source "arch/arm/mach-iop32x/Kconfig"
+
+source "arch/arm/mach-iop33x/Kconfig"
+
+source "arch/arm/mach-iop13xx/Kconfig"
+
+source "arch/arm/mach-ixp4xx/Kconfig"
+
+source "arch/arm/mach-ixp2000/Kconfig"
+
+source "arch/arm/mach-ixp23xx/Kconfig"
+
+source "arch/arm/mach-kirkwood/Kconfig"
+
+source "arch/arm/mach-ks8695/Kconfig"
+
+source "arch/arm/mach-loki/Kconfig"
+
+source "arch/arm/mach-lpc32xx/Kconfig"
+
+source "arch/arm/mach-msm/Kconfig"
+
+source "arch/arm/mach-mv78xx0/Kconfig"
+
+source "arch/arm/plat-mxc/Kconfig"
+
+source "arch/arm/mach-mxs/Kconfig"
+
+source "arch/arm/mach-netx/Kconfig"
+
+source "arch/arm/mach-nomadik/Kconfig"
+source "arch/arm/plat-nomadik/Kconfig"
+
+source "arch/arm/mach-nuc93x/Kconfig"
+
+source "arch/arm/plat-omap/Kconfig"
+
+source "arch/arm/mach-omap1/Kconfig"
+
+source "arch/arm/mach-omap2/Kconfig"
+
+source "arch/arm/mach-orion5x/Kconfig"
+
+source "arch/arm/mach-pxa/Kconfig"
+source "arch/arm/plat-pxa/Kconfig"
+
+source "arch/arm/mach-mmp/Kconfig"
+
+source "arch/arm/mach-realview/Kconfig"
+
+source "arch/arm/mach-sa1100/Kconfig"
+
+source "arch/arm/plat-samsung/Kconfig"
+source "arch/arm/plat-s3c24xx/Kconfig"
+source "arch/arm/plat-s5p/Kconfig"
+
+source "arch/arm/plat-spear/Kconfig"
+
+source "arch/arm/plat-tcc/Kconfig"
+
+if ARCH_S3C2410
+source "arch/arm/mach-s3c2400/Kconfig"
+source "arch/arm/mach-s3c2410/Kconfig"
+source "arch/arm/mach-s3c2412/Kconfig"
+source "arch/arm/mach-s3c2416/Kconfig"
+source "arch/arm/mach-s3c2440/Kconfig"
+source "arch/arm/mach-s3c2443/Kconfig"
+endif
+
+if ARCH_S3C64XX
+source "arch/arm/mach-s3c64xx/Kconfig"
+endif
+
+source "arch/arm/mach-s5p64x0/Kconfig"
+
+source "arch/arm/mach-s5pc100/Kconfig"
+
+source "arch/arm/mach-s5pv210/Kconfig"
+
+source "arch/arm/mach-exynos4/Kconfig"
+
+source "arch/arm/mach-shmobile/Kconfig"
+
+source "arch/arm/mach-tegra/Kconfig"
+
+source "arch/arm/mach-u300/Kconfig"
+
+source "arch/arm/mach-ux500/Kconfig"
+
+source "arch/arm/mach-versatile/Kconfig"
+
+source "arch/arm/mach-vexpress/Kconfig"
+source "arch/arm/plat-versatile/Kconfig"
+
+source "arch/arm/mach-vt8500/Kconfig"
+
+source "arch/arm/mach-w90x900/Kconfig"
+
+# Definitions to make life easier
+config ARCH_ACORN
+ bool
+
+config PLAT_IOP
+ bool
+ select GENERIC_CLOCKEVENTS
+ select HAVE_SCHED_CLOCK
+
+config PLAT_ORION
+ bool
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select HAVE_SCHED_CLOCK
+
+config PLAT_PXA
+ bool
+
+config PLAT_VERSATILE
+ bool
+
+config ARM_TIMER_SP804
+ bool
+ select CLKSRC_MMIO
+
+source arch/arm/mm/Kconfig
+
+config IWMMXT
+ bool "Enable iWMMXt support"
+ depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4
+ default y if PXA27x || PXA3xx || PXA95x || ARCH_MMP
+ help
+ Enable support for iWMMXt context switching at run time if
+ running on a CPU that supports it.
+
+# bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
+config XSCALE_PMU
+ bool
+ depends on CPU_XSCALE && !XSCALE_PMU_TIMER
+ default y
+
+config CPU_HAS_PMU
+ depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
+ (!ARCH_OMAP3 || OMAP3_EMU)
+ default y
+ bool
+
+config MULTI_IRQ_HANDLER
+ bool
+ help
+ Allow each machine to specify it's own IRQ handler at run time.
+
+if !MMU
+source "arch/arm/Kconfig-nommu"
+endif
+
+config ARM_ERRATA_411920
+ bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
+ depends on CPU_V6 || CPU_V6K
+ help
+ Invalidation of the Instruction Cache operation can
+ fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
+ It does not affect the MPCore. This option enables the ARM Ltd.
+ recommended workaround.
+
+config ARM_ERRATA_364296
+ bool "Enable partial low interrupt latency mode for ARM1136"
+ depends on CPU_V6 && !SMP
+ default n
+ help
+ This options enables the workaround for the 364296 ARM1136
+ r0pX errata (possible cache data corruption with
+ hit-under-miss enabled). It sets the undocumented bit 31 in
+ the auxiliary control register and the FI bit in the control
+ register, thus disabling hit-under-miss without putting the
+ processor into full low interrupt latency mode. ARM11MPCore
+ is not affected.
+
+config ARM_ERRATA_430973
+ bool "ARM errata: Stale prediction on replaced interworking branch"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 430973 Cortex-A8
+ (r1p0..r1p2) erratum. If a code sequence containing an ARM/Thumb
+ interworking branch is replaced with another code sequence at the
+ same virtual address, whether due to self-modifying code or virtual
+ to physical address re-mapping, Cortex-A8 does not recover from the
+ stale interworking branch prediction. This results in Cortex-A8
+ executing the new code sequence in the incorrect ARM or Thumb state.
+ The workaround enables the BTB/BTAC operations by setting ACTLR.IBE
+ and also flushes the branch target cache at every context switch.
+ Note that setting specific bits in the ACTLR register may not be
+ available in non-secure mode.
+
+config ARM_ERRATA_458693
+ bool "ARM errata: Processor deadlock when a false hazard is created"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 458693 Cortex-A8 (r2p0)
+ erratum. For very specific sequences of memory operations, it is
+ possible for a hazard condition intended for a cache line to instead
+ be incorrectly associated with a different cache line. This false
+ hazard might then cause a processor deadlock. The workaround enables
+ the L1 caching of the NEON accesses and disables the PLD instruction
+ in the ACTLR register. Note that setting specific bits in the ACTLR
+ register may not be available in non-secure mode.
+
+config ARM_ERRATA_460075
+ bool "ARM errata: Data written to the L2 cache can be overwritten with stale data"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 460075 Cortex-A8 (r2p0)
+ erratum. Any asynchronous access to the L2 cache may encounter a
+ situation in which recent store transactions to the L2 cache are lost
+ and overwritten with stale memory contents from external memory. The
+ workaround disables the write-allocate mode for the L2 cache via the
+ ACTLR register. Note that setting specific bits in the ACTLR register
+ may not be available in non-secure mode.
+
+config ARM_ERRATA_742230
+ bool "ARM errata: DMB operation may be faulty"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 742230 Cortex-A9
+ (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction
+ between two write operations may not ensure the correct visibility
+ ordering of the two writes. This workaround sets a specific bit in
+ the diagnostic register of the Cortex-A9 which causes the DMB
+ instruction to behave as a DSB, ensuring the correct behaviour of
+ the two writes.
+
+config ARM_ERRATA_742231
+ bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 742231 Cortex-A9
+ (r2p0..r2p2) erratum. Under certain conditions, specific to the
+ Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode,
+ accessing some data located in the same cache line, may get corrupted
+ data due to bad handling of the address hazard when the line gets
+ replaced from one of the CPUs at the same time as another CPU is
+ accessing it. This workaround sets specific bits in the diagnostic
+ register of the Cortex-A9 which reduces the linefill issuing
+ capabilities of the processor.
+
+config PL310_ERRATA_588369
+ bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
+ depends on CACHE_L2X0
+ help
+ The PL310 L2 cache controller implements three types of Clean &
+ Invalidate maintenance operations: by Physical Address
+ (offset 0x7F0), by Index/Way (0x7F8) and by Way (0x7FC).
+ They are architecturally defined to behave as the execution of a
+ clean operation followed immediately by an invalidate operation,
+ both performing to the same memory location. This functionality
+ is not correctly implemented in PL310 as clean lines are not
+ invalidated as a result of these operations.
+
+config ARM_ERRATA_720789
+ bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 720789 Cortex-A9 (prior to
+ r2p0) erratum. A faulty ASID can be sent to the other CPUs for the
+ broadcasted CP15 TLB maintenance operations TLBIASIDIS and TLBIMVAIS.
+ As a consequence of this erratum, some TLB entries which should be
+ invalidated are not, resulting in an incoherency in the system page
+ tables. The workaround changes the TLB flushing routines to invalidate
+ entries regardless of the ASID.
+
+config PL310_ERRATA_727915
+ bool "Background Clean & Invalidate by Way operation can cause data corruption"
+ depends on CACHE_L2X0
+ help
+ PL310 implements the Clean & Invalidate by Way L2 cache maintenance
+ operation (offset 0x7FC). This operation runs in background so that
+ PL310 can handle normal accesses while it is in progress. Under very
+ rare circumstances, due to this erratum, write data can be lost when
+ PL310 treats a cacheable write transaction during a Clean &
+ Invalidate by Way operation.
+
+config ARM_ERRATA_743622
+ bool "ARM errata: Faulty hazard checking in the Store Buffer may lead to data corruption"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 743622 Cortex-A9
+ (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
+ optimisation, preventing the defect from occurring. This has no
+ visible impact on the overall performance or power consumption of the
+ processor.
+
+config ARM_ERRATA_751472
+ bool "ARM errata: Interrupted ICIALLUIS may prevent completion of broadcasted operation"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 751472 Cortex-A9 (prior
+ to r3p0) erratum. An interrupted ICIALLUIS operation may prevent the
+ completion of a following broadcasted operation if the second
+ operation is received by a CPU before the ICIALLUIS has completed,
+ potentially leading to corrupted entries in the cache or TLB.
+
+config ARM_ERRATA_753970
+ bool "ARM errata: cache sync operation may be faulty"
+ depends on CACHE_PL310
+ help
+ This option enables the workaround for the 753970 PL310 (r3p0) erratum.
+
+ Under some condition the effect of cache sync operation on
+ the store buffer still remains when the operation completes.
+ This means that the store buffer is always asked to drain and
+ this prevents it from merging any further writes. The workaround
+ is to replace the normal offset of cache sync operation (0x730)
+ by another offset targeting an unmapped PL310 register 0x740.
+ This has the same effect as the cache sync operation: store buffer
+ drain and waiting for all buffers empty.
+
+config ARM_ERRATA_754322
+ bool "ARM errata: possible faulty MMU translations following an ASID switch"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 754322 Cortex-A9 (r2p*,
+ r3p*) erratum. A speculative memory access may cause a page table walk
+ which starts prior to an ASID switch but completes afterwards. This
+ can populate the micro-TLB with a stale entry which may be hit with
+ the new ASID. This workaround places two dsb instructions in the mm
+ switching code so that no page table walks can cross the ASID switch.
+
+config ARM_ERRATA_754327
+ bool "ARM errata: no automatic Store Buffer drain"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for the 754327 Cortex-A9 (prior to
+ r2p0) erratum. The Store Buffer does not have any automatic draining
+ mechanism and therefore a livelock may occur if an external agent
+ continuously polls a memory location waiting to observe an update.
+ This workaround defines cpu_relax() as smp_mb(), preventing correctly
+ written polling loops from denying visibility of updates to memory.
+
+config ARM_ERRATA_775420
+ bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
+ depends on CPU_V7
+ help
+ This option enables the workaround for the 775420 Cortex-A9 (r2p2,
+ r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance
+ operation aborts with MMU exception, it might cause the processor
+ to deadlock. This workaround puts DSB before executing ISB if
+ an abort may occur on cache maintenance.
+
+endmenu
+
+source "arch/arm/common/Kconfig"
+
+menu "Bus support"
+
+config ARM_AMBA
+ bool
+
+config ISA
+ bool
+ help
+ Find out whether you have ISA slots on your motherboard. ISA is the
+ name of a bus system, i.e. the way the CPU talks to the other stuff
+ inside your box. Other bus systems are PCI, EISA, MicroChannel
+ (MCA) or VESA. ISA is an older system, now being displaced by PCI;
+ newer boards don't support it. If you have ISA, say Y, otherwise N.
+
+# Select ISA DMA controller support
+config ISA_DMA
+ bool
+ select ISA_DMA_API
+
+# Select ISA DMA interface
+config ISA_DMA_API
+ bool
+
+config PCI
+ bool "PCI support" if MIGHT_HAVE_PCI
+ help
+ Find out whether you have a PCI motherboard. PCI is the name of a
+ bus system, i.e. the way the CPU talks to the other stuff inside
+ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or
+ VESA. If you have PCI, say Y, otherwise N.
+
+config PCI_DOMAINS
+ bool
+ depends on PCI
+
+config PCI_NANOENGINE
+ bool "BSE nanoEngine PCI support"
+ depends on SA1100_NANOENGINE
+ help
+ Enable PCI on the BSE nanoEngine board.
+
+config PCI_SYSCALL
+ def_bool PCI
+
+# Select the host bridge type
+config PCI_HOST_VIA82C505
+ bool
+ depends on PCI && ARCH_SHARK
+ default y
+
+config PCI_HOST_ITE8152
+ bool
+ depends on PCI && MACH_ARMCORE
+ default y
+ select DMABOUNCE
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pcmcia/Kconfig"
+
+config ARM_ERRATA_764369
+ bool "ARM errata: Data cache line maintenance operation by MVA may not succeed"
+ depends on CPU_V7 && SMP
+ help
+ This option enables the workaround for erratum 764369
+ affecting Cortex-A9 MPCore with two or more processors (all
+ current revisions). Under certain timing circumstances, a data
+ cache line maintenance operation by MVA targeting an Inner
+ Shareable memory region may fail to proceed up to either the
+ Point of Coherency or to the Point of Unification of the
+ system. This workaround adds a DSB instruction before the
+ relevant cache maintenance functions and sets a specific bit
+ in the diagnostic control register of the SCU.
+
+config PL310_ERRATA_769419
+ bool "PL310 errata: no automatic Store Buffer drain"
+ depends on CACHE_L2X0
+ help
+ On revisions of the PL310 prior to r3p2, the Store Buffer does
+ not automatically drain. This can cause normal, non-cacheable
+ writes to be retained when the memory system is idle, leading
+ to suboptimal I/O performance for drivers using coherent DMA.
+ This option adds a write barrier to the cpu_idle loop so that,
+ on systems with an outer cache, the store buffer is drained
+ explicitly.
+
+endmenu
+
+menu "Kernel Features"
+
+source "kernel/time/Kconfig"
+
+config SMP
+ bool "Symmetric Multi-Processing"
+ depends on CPU_V6K || CPU_V7
+ 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_MSM_SCORPIONMP || ARCH_SHMOBILE || ARCH_MX6Q
+ select USE_GENERIC_SMP_HELPERS
+ select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
+ help
+ This enables support for systems with more than one CPU. If you have
+ a system with only one CPU, like most personal computers, say N. If
+ you have a system with more than one CPU, say Y.
+
+ If you say N here, the kernel will run on single and multiprocessor
+ machines, but will use only one CPU of a multiprocessor machine. If
+ you say Y here, the kernel will run on many, but not all, single
+ processor machines. On a single processor machine, the kernel will
+ run faster if you say N here.
+
+ See also <file:Documentation/i386/IO-APIC.txt>,
+ <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
+ <http://tldp.org/HOWTO/SMP-HOWTO.html>.
+
+ If you don't know what to do here, say N.
+
+config SMP_ON_UP
+ bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on SMP && !XIP_KERNEL
+ default y
+ help
+ SMP kernels contain instructions which fail on non-SMP processors.
+ Enabling this option allows the kernel to modify itself to make
+ these instructions safe. Disabling it allows about 1K of space
+ savings.
+
+ If you don't know what to do here, say Y.
+
+config HAVE_ARM_SCU
+ bool
+ depends on SMP
+ help
+ This option enables support for the ARM system coherency unit
+
+config HAVE_ARM_TWD
+ bool
+ depends on SMP
+ select TICK_ONESHOT
+ help
+ This options enables support for the ARM timer and watchdog unit
+
+choice
+ prompt "Memory split"
+ default VMSPLIT_3G
+ help
+ Select the desired split between kernel and user memory.
+
+ If you are not absolutely sure what you are doing, leave this
+ option alone!
+
+ config VMSPLIT_3G
+ bool "3G/1G user/kernel split"
+ config VMSPLIT_2G
+ bool "2G/2G user/kernel split"
+ config VMSPLIT_1G
+ bool "1G/3G user/kernel split"
+endchoice
+
+config PAGE_OFFSET
+ hex
+ default 0x40000000 if VMSPLIT_1G
+ default 0x80000000 if VMSPLIT_2G
+ default 0xC0000000
+
+config NR_CPUS
+ int "Maximum number of CPUs (2-32)"
+ range 2 32
+ depends on SMP
+ default "4"
+
+config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
+ depends on SMP && HOTPLUG && EXPERIMENTAL
+ help
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu.
+
+config LOCAL_TIMERS
+ bool "Use local timer interrupts"
+ depends on SMP
+ default y
+ select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
+ help
+ Enable support for local timers on SMP platforms, rather then the
+ legacy IPI broadcast method. Local timers allows the system
+ accounting to be spread across the timer interval, preventing a
+ "thundering herd" at every timer tick.
+
+source kernel/Kconfig.preempt
+
+config HZ
+ int
+ default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
+ ARCH_S5PV210 || ARCH_EXYNOS4
+ 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
+ default 100
+
+config THUMB2_KERNEL
+ bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
+ depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
+ select AEABI
+ select ARM_ASM_UNIFIED
+ help
+ By enabling this option, the kernel will be compiled in
+ Thumb-2 mode. A compiler/assembler that understand the unified
+ ARM-Thumb syntax is needed.
+
+ If unsure, say N.
+
+config THUMB2_AVOID_R_ARM_THM_JUMP11
+ bool "Work around buggy Thumb-2 short branch relocations in gas"
+ depends on THUMB2_KERNEL && MODULES
+ default y
+ help
+ Various binutils versions can resolve Thumb-2 branches to
+ locally-defined, preemptible global symbols as short-range "b.n"
+ branch instructions.
+
+ This is a problem, because there's no guarantee the final
+ destination of the symbol, or any candidate locations for a
+ trampoline, are within range of the branch. For this reason, the
+ kernel does not support fixing up the R_ARM_THM_JUMP11 (102)
+ relocation in modules at all, and it makes little sense to add
+ support.
+
+ The symptom is that the kernel fails with an "unsupported
+ relocation" error when loading some modules.
+
+ Until fixed tools are available, passing
+ -fno-optimize-sibling-calls to gcc should prevent gcc generating
+ code which hits this problem, at the cost of a bit of extra runtime
+ stack usage in some cases.
+
+ The problem is described in more detail at:
+ https://bugs.launchpad.net/binutils-linaro/+bug/725126
+
+ Only Thumb-2 kernels are affected.
+
+ Unless you are sure your tools don't have this problem, say Y.
+
+config ARM_ASM_UNIFIED
+ bool
+
+config AEABI
+ bool "Use the ARM EABI to compile the kernel"
+ help
+ This option allows for the kernel to be compiled using the latest
+ ARM ABI (aka EABI). This is only useful if you are using a user
+ space environment that is also compiled with EABI.
+
+ Since there are major incompatibilities between the legacy ABI and
+ EABI, especially with regard to structure member alignment, this
+ option also changes the kernel syscall calling convention to
+ disambiguate both ABIs and allow for backward compatibility support
+ (selected with CONFIG_OABI_COMPAT).
+
+ To use this you need GCC version 4.0.0 or later.
+
+config OABI_COMPAT
+ bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
+ depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL
+ default y
+ help
+ This option preserves the old syscall interface along with the
+ new (ARM EABI) one. It also provides a compatibility layer to
+ intercept syscalls that have structure arguments which layout
+ in memory differs between the legacy ABI and the new ARM EABI
+ (only for non "thumb" binaries). This option adds a tiny
+ overhead to all syscalls and produces a slightly larger kernel.
+ If you know you'll be using only pure EABI user space then you
+ can say N here. If this option is not selected and you attempt
+ to execute a legacy ABI binary then the result will be
+ UNPREDICTABLE (in fact it can be predicted that it won't work
+ at all). If in doubt say Y.
+
+config ARCH_HAS_HOLES_MEMORYMODEL
+ bool
+
+config ARCH_SPARSEMEM_ENABLE
+ bool
+
+config ARCH_SPARSEMEM_DEFAULT
+ def_bool ARCH_SPARSEMEM_ENABLE
+
+config ARCH_SELECT_MEMORY_MODEL
+ def_bool ARCH_SPARSEMEM_ENABLE
+
+config HAVE_ARCH_PFN_VALID
+ def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
+
+config HIGHMEM
+ bool "High Memory Support"
+ depends on MMU
+ help
+ The address space of ARM processors is only 4 Gigabytes large
+ and it has to accommodate user address space, kernel address
+ space as well as some memory mapped IO. That means that, if you
+ have a large amount of physical memory and/or IO, not all of the
+ memory can be "permanently mapped" by the kernel. The physical
+ memory that is not permanently mapped is called "high memory".
+
+ Depending on the selected kernel/user memory split, minimum
+ vmalloc space and actual amount of RAM, you may not need this
+ option which should result in a slightly faster kernel.
+
+ If unsure, say n.
+
+config HIGHPTE
+ bool "Allocate 2nd-level pagetables from highmem"
+ depends on HIGHMEM
+
+config HW_PERF_EVENTS
+ bool "Enable hardware performance counter support for perf events"
+ depends on PERF_EVENTS && CPU_HAS_PMU
+ default y
+ help
+ Enable hardware performance counter support for perf events. If
+ disabled, perf events will use software events only.
+
+source "mm/Kconfig"
+
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order" if ARCH_SHMOBILE
+ range 11 64 if ARCH_SHMOBILE
+ default "9" if SA1111
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+ blocks into "zones", where each zone is a power of two number of
+ pages. This option selects the largest power of two that the kernel
+ keeps in the memory allocator. If you need to allocate very large
+ blocks of physically contiguous memory, then you may need to
+ increase this value.
+
+ This config option is actually maximum order plus one. For example,
+ a value of 11 means that the largest free memory block is 2^10 pages.
+
+config LEDS
+ bool "Timer and CPU usage LEDs"
+ depends on ARCH_CDB89712 || ARCH_EBSA110 || \
+ ARCH_EBSA285 || ARCH_INTEGRATOR || \
+ ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
+ ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
+ ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
+ ARCH_AT91 || ARCH_DAVINCI || \
+ ARCH_KS8695 || MACH_RD88F5182 || ARCH_REALVIEW
+ help
+ If you say Y here, the LEDs on your machine will be used
+ to provide useful information about your current system status.
+
+ If you are compiling a kernel for a NetWinder or EBSA-285, you will
+ be able to select which LEDs are active using the options below. If
+ you are compiling a kernel for the EBSA-110 or the LART however, the
+ red LED will simply flash regularly to indicate that the system is
+ still functional. It is safe to say Y here if you have a CATS
+ system, but the driver will do nothing.
+
+config LEDS_TIMER
+ bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
+ OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
+ || MACH_OMAP_PERSEUS2
+ depends on LEDS
+ depends on !GENERIC_CLOCKEVENTS
+ default y if ARCH_EBSA110
+ help
+ If you say Y here, one of the system LEDs (the green one on the
+ NetWinder, the amber one on the EBSA285, or the red one on the LART)
+ will flash regularly to indicate that the system is still
+ operational. This is mainly useful to kernel hackers who are
+ debugging unstable kernels.
+
+ The LART uses the same LED for both Timer LED and CPU usage LED
+ functions. You may choose to use both, but the Timer LED function
+ will overrule the CPU usage LED.
+
+config LEDS_CPU
+ bool "CPU usage LED" if (!ARCH_CDB89712 && !ARCH_EBSA110 && \
+ !ARCH_OMAP) \
+ || OMAP_OSK_MISTRAL || MACH_OMAP_H2 \
+ || MACH_OMAP_PERSEUS2
+ depends on LEDS
+ help
+ If you say Y here, the red LED will be used to give a good real
+ time indication of CPU usage, by lighting whenever the idle task
+ is not currently executing.
+
+ The LART uses the same LED for both Timer LED and CPU usage LED
+ functions. You may choose to use both, but the Timer LED function
+ will overrule the CPU usage LED.
+
+config ALIGNMENT_TRAP
+ bool
+ depends on CPU_CP15_MMU
+ default y if !ARCH_EBSA110
+ select HAVE_PROC_CPU if PROC_FS
+ help
+ ARM processors cannot fetch/store information which is not
+ naturally aligned on the bus, i.e., a 4 byte fetch must start at an
+ address divisible by 4. On 32-bit ARM processors, these non-aligned
+ fetch/store instructions will be emulated in software if you say
+ here, which has a severe performance impact. This is necessary for
+ correct operation of some network protocols. With an IP-only
+ configuration it is safe to say N, otherwise say Y.
+
+config UACCESS_WITH_MEMCPY
+ bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)"
+ depends on MMU && EXPERIMENTAL
+ default y if CPU_FEROCEON
+ help
+ Implement faster copy_to_user and clear_user methods for CPU
+ cores where a 8-word STM instruction give significantly higher
+ memory write throughput than a sequence of individual 32bit stores.
+
+ A possible side effect is a slight increase in scheduling latency
+ between threads sharing the same address space if they invoke
+ such copy operations with large buffers.
+
+ However, if the CPU data cache is using a write-allocate mode,
+ this option is unlikely to provide any performance gain.
+
+config SECCOMP
+ bool
+ prompt "Enable seccomp to safely compute untrusted bytecode"
+ ---help---
+ This kernel feature is useful for number crunching applications
+ that may need to compute untrusted bytecode during their
+ execution. By using pipes or other transports made available to
+ the process as file descriptors supporting the read/write
+ syscalls, it's possible to isolate those applications in
+ their own address space using seccomp. Once seccomp is
+ enabled via prctl(PR_SET_SECCOMP), it cannot be disabled
+ and the task is only allowed to execute a few safe syscalls
+ defined by each seccomp mode.
+
+config CC_STACKPROTECTOR
+ bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ This option turns on the -fstack-protector GCC feature. This
+ feature puts, at the beginning of functions, a canary value on
+ the stack just before the return address, and validates
+ the value just before actually returning. Stack based buffer
+ overflows (that need to overwrite this return address) now also
+ overwrite the canary, which gets detected and the attack is then
+ neutralized via a kernel panic.
+ This feature requires gcc version 4.2 or above.
+
+config DEPRECATED_PARAM_STRUCT
+ bool "Provide old way to pass kernel parameters"
+ help
+ 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.
+
+endmenu
+
+menu "Boot options"
+
+config USE_OF
+ bool "Flattened Device Tree support"
+ select OF
+ select OF_EARLY_FLATTREE
+ help
+ Include support for flattened device tree machine descriptions.
+
+# Compressed boot loader in ROM. Yes, we really want to ask about
+# TEXT and BSS so we preserve their values in the config files.
+config ZBOOT_ROM_TEXT
+ hex "Compressed ROM boot loader base address"
+ default "0"
+ help
+ The physical address at which the ROM-able zImage is to be
+ placed in the target. Platforms which normally make use of
+ ROM-able zImage formats normally set this to a suitable
+ value in their defconfig file.
+
+ If ZBOOT_ROM is not enabled, this has no effect.
+
+config ZBOOT_ROM_BSS
+ hex "Compressed ROM boot loader BSS address"
+ default "0"
+ help
+ The base address of an area of read/write memory in the target
+ for the ROM-able zImage which must be available while the
+ decompressor is running. It must be large enough to hold the
+ entire decompressed kernel plus an additional 128 KiB.
+ Platforms which normally make use of ROM-able zImage formats
+ normally set this to a suitable value in their defconfig file.
+
+ If ZBOOT_ROM is not enabled, this has no effect.
+
+config ZBOOT_ROM
+ bool "Compressed boot loader in ROM/flash"
+ depends on ZBOOT_ROM_TEXT != ZBOOT_ROM_BSS
+ help
+ Say Y here if you intend to execute your compressed kernel image
+ (zImage) directly from ROM or flash. If unsure, say N.
+
+config ZBOOT_ROM_MMCIF
+ bool "Include MMCIF loader in zImage (EXPERIMENTAL)"
+ depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL
+ help
+ Say Y here to include experimental MMCIF loading code in the
+ ROM-able zImage. With this enabled it is possible to write the
+ the ROM-able zImage kernel image to an MMC card and boot the
+ kernel straight from the reset vector. At reset the processor
+ Mask ROM will load the first part of the the ROM-able zImage
+ which in turn loads the rest the kernel image to RAM using the
+ MMCIF hardware block.
+
+config CMDLINE
+ string "Default kernel command string"
+ default ""
+ help
+ On some architectures (EBSA110 and CATS), there is currently no way
+ for the boot loader to pass arguments to the kernel. For these
+ architectures, you should supply some command-line options at build
+ time by entering them here. As a minimum, you should specify the
+ memory size and the root device (e.g., mem=64M root=/dev/nfs).
+
+choice
+ prompt "Kernel command line type" if CMDLINE != ""
+ default CMDLINE_FROM_BOOTLOADER
+
+config CMDLINE_FROM_BOOTLOADER
+ bool "Use bootloader kernel arguments if available"
+ help
+ Uses the command-line options passed by the boot loader. If
+ the boot loader doesn't provide any, the default kernel command
+ string provided in CMDLINE will be used.
+
+config CMDLINE_EXTEND
+ bool "Extend bootloader kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to the default kernel command string.
+
+config CMDLINE_FORCE
+ bool "Always use the default kernel command string"
+ help
+ Always use the default kernel command string, even if the boot
+ loader passes other arguments to the kernel.
+ This is useful if you cannot or don't want to change the
+ command-line options your boot loader passes to the kernel.
+endchoice
+
+config XIP_KERNEL
+ bool "Kernel Execute-In-Place from ROM"
+ depends on !ZBOOT_ROM
+ help
+ Execute-In-Place allows the kernel to run from non-volatile storage
+ directly addressable by the CPU, such as NOR flash. This saves RAM
+ space since the text section of the kernel is not loaded from flash
+ to RAM. Read-write sections, such as the data section and stack,
+ are still copied to RAM. The XIP kernel is not compressed since
+ it has to run directly from flash, so it will take more space to
+ store it. The flash address used to link the kernel object files,
+ and for storing it, is configuration dependent. Therefore, if you
+ say Y here, you must know the proper physical address where to
+ store the kernel image depending on your own flash memory usage.
+
+ Also note that the make target becomes "make xipImage" rather than
+ "make zImage" or "make Image". The final kernel binary to put in
+ ROM memory will be arch/arm/boot/xipImage.
+
+ If unsure, say N.
+
+config XIP_PHYS_ADDR
+ hex "XIP Kernel Physical Location"
+ depends on XIP_KERNEL
+ default "0x00080000"
+ help
+ This is the physical address in your flash memory the kernel will
+ be linked for and stored to. This address is dependent on your
+ own flash usage.
+
+config KEXEC
+ bool "Kexec system call (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is independent of the system firmware. And like a reboot
+ you can start any kernel with it, not just Linux.
+
+ It is an ongoing process to be certain the hardware in a machine
+ is properly shutdown, so do not be surprised if this code does not
+ initially work for you. It may help to enable device hotplugging
+ support.
+
+config ATAGS_PROC
+ bool "Export atags in procfs"
+ depends on KEXEC
+ default y
+ help
+ Should the atags used to boot the kernel be exported in an "atags"
+ file in procfs. Useful with kexec.
+
+config CRASH_DUMP
+ bool "Build kdump crash kernel (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ help
+ Generate crash dump after being started by kexec. This should
+ be normally only set in special crash dump kernels which are
+ loaded in the main kernel with kexec-tools into a specially
+ reserved region and then later executed after a crash by
+ kdump/kexec. The crash dump kernel must be compiled to a
+ memory address not used by the main kernel
+
+ For more details see Documentation/kdump/kdump.txt
+
+config AUTO_ZRELADDR
+ bool "Auto calculation of the decompressed kernel image address"
+ depends on !ZBOOT_ROM && !ARCH_U300
+ help
+ ZRELADDR is the physical address where the decompressed kernel
+ image will be placed. If AUTO_ZRELADDR is selected, the address
+ will be determined at run-time by masking the current IP with
+ 0xf8000000. This assumes the zImage being placed in the first 128MB
+ from start of memory.
+
+endmenu
+
+menu "CPU Power Management"
+
+if ARCH_HAS_CPUFREQ
+
+source "drivers/cpufreq/Kconfig"
+
+config CPU_FREQ_IMX
+ tristate "CPUfreq driver for i.MX CPUs"
+ depends on ARCH_MXC && CPU_FREQ
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
+config CPU_FREQ_SA1100
+ bool
+
+config CPU_FREQ_SA1110
+ bool
+
+config CPU_FREQ_INTEGRATOR
+ tristate "CPUfreq driver for ARM Integrator CPUs"
+ depends on ARCH_INTEGRATOR && CPU_FREQ
+ default y
+ help
+ This enables the CPUfreq driver for ARM Integrator CPUs.
+
+ For details, take a look at <file:Documentation/cpu-freq>.
+
+ If in doubt, say Y.
+
+config CPU_FREQ_PXA
+ bool
+ depends on CPU_FREQ && ARCH_PXA && PXA25x
+ default y
+ select CPU_FREQ_DEFAULT_GOV_USERSPACE
+
+config CPU_FREQ_S3C64XX
+ bool "CPUfreq support for Samsung S3C64XX CPUs"
+ depends on CPU_FREQ && CPU_S3C6410
+
+config CPU_FREQ_S3C
+ bool
+ help
+ Internal configuration node for common cpufreq on Samsung SoC
+
+config CPU_FREQ_S3C24XX
+ bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
+ depends on ARCH_S3C2410 && CPU_FREQ && EXPERIMENTAL
+ select CPU_FREQ_S3C
+ help
+ This enables the CPUfreq driver for the Samsung S3C24XX family
+ of CPUs.
+
+ For details, take a look at <file:Documentation/cpu-freq>.
+
+ If in doubt, say N.
+
+config CPU_FREQ_S3C24XX_PLL
+ bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
+ depends on CPU_FREQ_S3C24XX && EXPERIMENTAL
+ help
+ Compile in support for changing the PLL frequency from the
+ S3C24XX series CPUfreq driver. The PLL takes time to settle
+ after a frequency change, so by default it is not enabled.
+
+ This also means that the PLL tables for the selected CPU(s) will
+ be built which may increase the size of the kernel image.
+
+config CPU_FREQ_S3C24XX_DEBUG
+ bool "Debug CPUfreq Samsung driver core"
+ depends on CPU_FREQ_S3C24XX
+ help
+ Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
+
+config CPU_FREQ_S3C24XX_IODEBUG
+ bool "Debug CPUfreq Samsung driver IO timing"
+ depends on CPU_FREQ_S3C24XX
+ help
+ Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
+
+config CPU_FREQ_S3C24XX_DEBUGFS
+ bool "Export debugfs for CPUFreq"
+ depends on CPU_FREQ_S3C24XX && DEBUG_FS
+ help
+ Export status information via debugfs.
+
+endif
+
+source "drivers/cpuidle/Kconfig"
+
+endmenu
+
+menu "Floating point emulation"
+
+comment "At least one emulation must be selected"
+
+config FPE_NWFPE
+ bool "NWFPE math emulation"
+ depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL
+ ---help---
+ Say Y to include the NWFPE floating point emulator in the kernel.
+ This is necessary to run most binaries. Linux does not currently
+ support floating point hardware so you need to say Y here even if
+ your machine has an FPA or floating point co-processor podule.
+
+ You may say N here if you are going to load the Acorn FPEmulator
+ early in the bootup.
+
+config FPE_NWFPE_XP
+ bool "Support extended precision"
+ depends on FPE_NWFPE
+ help
+ Say Y to include 80-bit support in the kernel floating-point
+ emulator. Otherwise, only 32 and 64-bit support is compiled in.
+ Note that gcc does not generate 80-bit operations by default,
+ so in most cases this option only enlarges the size of the
+ floating point emulator without any good reason.
+
+ You almost surely want to say N here.
+
+config FPE_FASTFPE
+ bool "FastFPE math emulation (EXPERIMENTAL)"
+ depends on (!AEABI || OABI_COMPAT) && !CPU_32v3 && EXPERIMENTAL
+ ---help---
+ Say Y here to include the FAST floating point emulator in the kernel.
+ This is an experimental much faster emulator which now also has full
+ precision for the mantissa. It does not support any exceptions.
+ It is very simple, and approximately 3-6 times faster than NWFPE.
+
+ It should be sufficient for most programs. It may be not suitable
+ for scientific calculations, but you have to check this for yourself.
+ If you do not feel you need a faster FP emulation you should better
+ choose NWFPE.
+
+config VFP
+ bool "VFP-format floating point maths"
+ depends on CPU_V6 || CPU_V6K || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
+ help
+ Say Y to include VFP support code in the kernel. This is needed
+ if your hardware includes a VFP unit.
+
+ Please see <file:Documentation/arm/VFP/release-notes.txt> for
+ release notes and additional status information.
+
+ Say N if your target does not have VFP hardware.
+
+config VFPv3
+ bool
+ depends on VFP
+ default y if CPU_V7
+
+config NEON
+ bool "Advanced SIMD (NEON) Extension support"
+ depends on VFPv3 && CPU_V7
+ help
+ Say Y to include support code for NEON, the ARMv7 Advanced SIMD
+ Extension.
+
+endmenu
+
+menu "Userspace binary formats"
+
+source "fs/Kconfig.binfmt"
+
+config ARTHUR
+ tristate "RISC OS personality"
+ depends on !AEABI
+ help
+ Say Y here to include the kernel code necessary if you want to run
+ Acorn RISC OS/Arthur binaries under Linux. This code is still very
+ experimental; if this sounds frightening, say N and sleep in peace.
+ You can also say M here to compile this support as a module (which
+ will be called arthur).
+
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+config ARCH_SUSPEND_POSSIBLE
+ depends on !ARCH_S5P64X0 && !ARCH_S5PC100
+ depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
+ CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
+ def_bool y
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/arm/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
new file mode 100644
index 00000000..2cef8e13
--- /dev/null
+++ b/arch/arm/Kconfig-nommu
@@ -0,0 +1,52 @@
+#
+# Kconfig for uClinux(non-paged MM) depend configurations
+# Hyok S. Choi <hyok.choi@samsung.com>
+#
+
+config SET_MEM_PARAM
+ bool "Set flash/sdram size and base addr"
+ help
+ Say Y to manually set the base addresses and sizes.
+ otherwise, the default values are assigned.
+
+config DRAM_BASE
+ hex '(S)DRAM Base Address' if SET_MEM_PARAM
+ default 0x00800000
+
+config DRAM_SIZE
+ hex '(S)DRAM SIZE' if SET_MEM_PARAM
+ default 0x00800000
+
+config FLASH_MEM_BASE
+ hex 'FLASH Base Address' if SET_MEM_PARAM
+ default 0x00400000
+
+config FLASH_SIZE
+ hex 'FLASH Size' if SET_MEM_PARAM
+ default 0x00400000
+
+config PROCESSOR_ID
+ hex 'Hard wire the processor ID'
+ default 0x00007700
+ depends on !CPU_CP15
+ help
+ If processor has no CP15 register, this processor ID is
+ used instead of the auto-probing which utilizes the register.
+
+config REMAP_VECTORS_TO_RAM
+ bool 'Install vectors to the beginning of RAM' if DRAM_BASE
+ depends on DRAM_BASE
+ help
+ The kernel needs to change the hardware exception vectors.
+ In nommu mode, the hardware exception vectors are normally
+ placed at address 0x00000000. However, this region may be
+ occupied by read-only memory depending on H/W design.
+
+ If the region contains read-write memory, say 'n' here.
+
+ If your CPU provides a remap facility which allows the exception
+ vectors to be mapped to writable memory, say 'n' here.
+
+ Otherwise, say 'y' here. In this case, the kernel will require
+ external support to redirect the hardware exception vectors to
+ the writable versions located at DRAM_BASE.
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
new file mode 100644
index 00000000..81cbe40c
--- /dev/null
+++ b/arch/arm/Kconfig.debug
@@ -0,0 +1,132 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config STRICT_DEVMEM
+ bool "Filter access to /dev/mem"
+ depends on MMU
+ ---help---
+ If this option is disabled, you allow userspace (root) access to all
+ of memory, including kernel and userspace memory. Accidental
+ access to this is obviously disastrous, but specific access can
+ be used by people debugging the kernel.
+
+ If this option is switched on, the /dev/mem file only allows
+ userspace access to memory mapped peripherals.
+
+ If in doubt, say Y.
+
+# RMK wants arm kernels compiled with frame pointers or stack unwinding.
+# If you know what you are doing and are willing to live without stack
+# traces, you can get a slightly smaller kernel by setting this option to
+# n, but then RMK will have to kill you ;).
+config FRAME_POINTER
+ bool
+ depends on !THUMB2_KERNEL
+ default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER
+ help
+ If you say N here, the resulting kernel will be slightly smaller and
+ faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
+ when a problem occurs with the kernel, the information that is
+ reported is severely limited.
+
+config ARM_UNWIND
+ bool "Enable stack unwinding support (EXPERIMENTAL)"
+ depends on AEABI && EXPERIMENTAL
+ default y
+ help
+ This option enables stack unwinding support in the kernel
+ using the information automatically generated by the
+ compiler. The resulting kernel image is slightly bigger but
+ the performance is not affected. Currently, this feature
+ only works with EABI compilers. If unsure say Y.
+
+config OLD_MCOUNT
+ bool
+ depends on FUNCTION_TRACER && FRAME_POINTER
+ default y
+
+config DEBUG_USER
+ bool "Verbose user fault messages"
+ help
+ When a user program crashes due to an exception, the kernel can
+ print a brief message explaining what the problem was. This is
+ sometimes helpful for debugging but serves no purpose on a
+ production system. Most people should say N here.
+
+ In addition, you need to pass user_debug=N on the kernel command
+ line to enable this feature. N consists of the sum of:
+
+ 1 - undefined instruction events
+ 2 - system calls
+ 4 - invalid data aborts
+ 8 - SIGSEGV faults
+ 16 - SIGBUS faults
+
+# These options are only for real kernel hackers who want to get their hands dirty.
+config DEBUG_LL
+ bool "Kernel low-level debugging functions"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here to include definitions of printascii, printch, printhex
+ in the kernel. This is helpful if you are debugging code that
+ executes before the console is initialized.
+
+config EARLY_PRINTK
+ bool "Early printk"
+ depends on DEBUG_LL
+ help
+ Say Y here if you want to have an early console using the
+ kernel low-level debugging functions. Add earlyprintk to your
+ kernel parameters to enable this console.
+
+config DEBUG_ICEDCC
+ bool "Kernel low-level debugging via EmbeddedICE DCC channel"
+ depends on DEBUG_LL
+ help
+ Say Y here if you want the debug print routines to direct their
+ output to the EmbeddedICE macrocell's DCC channel using
+ co-processor 14. This is known to work on the ARM9 style ICE
+ channel and on the XScale with the PEEDI.
+
+ It does include a timeout to ensure that the system does not
+ totally freeze when there is nothing connected to read.
+
+config OC_ETM
+ bool "On-chip ETM and ETB"
+ select ARM_AMBA
+ help
+ Enables the on-chip embedded trace macrocell and embedded trace
+ buffer driver that will allow you to collect traces of the
+ kernel code.
+
+config DEBUG_DC21285_PORT
+ bool "Kernel low-level debugging messages via footbridge serial port"
+ depends on DEBUG_LL && FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct their
+ output to the serial port in the DC21285 (Footbridge). Saying N
+ will cause the debug messages to appear on the first 16550
+ serial port.
+
+config DEBUG_CLPS711X_UART2
+ bool "Kernel low-level debugging messages via UART2"
+ depends on DEBUG_LL && ARCH_CLPS711X
+ help
+ Say Y here if you want the debug print routines to direct their
+ output to the second serial port on these devices. Saying N will
+ cause the debug messages to appear on the first serial port.
+
+config DEBUG_S3C_UART
+ depends on PLAT_SAMSUNG
+ int "S3C UART to use for low-level debug"
+ default "0"
+ help
+ Choice for UART for kernel low-level using S3C UARTS,
+ should be between zero and two. The port must have been
+ initialised by the boot-loader before use.
+
+ The uncompressor code port configuration is now handled
+ by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+endmenu
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
new file mode 100644
index 00000000..9d9d0b19
--- /dev/null
+++ b/arch/arm/Makefile
@@ -0,0 +1,307 @@
+#
+# arch/arm/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2001 by Russell King
+
+LDFLAGS_vmlinux :=-p --no-undefined -X
+ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+LDFLAGS_vmlinux += --be8
+endif
+
+OBJCOPYFLAGS :=-O binary -R .comment -S
+GZFLAGS :=-9
+#KBUILD_CFLAGS +=-pipe
+# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+KBUILD_CFLAGS +=$(call cc-option,-marm,)
+
+# Never generate .eh_frame
+KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
+
+# Do not use arch/arm/defconfig - it's always outdated.
+# Select a platform tht is kept up-to-date
+KBUILD_DEFCONFIG := versatile_defconfig
+
+# defines filename extension depending memory management type.
+ifeq ($(CONFIG_MMU),)
+MMUEXT := -nommu
+endif
+
+ifeq ($(CONFIG_FRAME_POINTER),y)
+KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
+endif
+
+ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
+KBUILD_CFLAGS +=-fstack-protector
+endif
+
+ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
+KBUILD_CPPFLAGS += -mbig-endian
+AS += -EB
+LD += -EB
+else
+KBUILD_CPPFLAGS += -mlittle-endian
+AS += -EL
+LD += -EL
+endif
+
+comma = ,
+
+# This selects which instruction set is used.
+# Note that GCC does not numerically define an architecture version
+# macro, but instead defines a whole series of macros which makes
+# testing for a specific architecture or later rather impossible.
+arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
+arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+# Only override the compiler option if ARMv6. The ARMv6K extensions are
+# always available in ARMv7
+ifeq ($(CONFIG_CPU_32v6),y)
+arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
+endif
+arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
+arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
+arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
+arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
+
+# This selects how we optimise for the processor.
+tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610
+tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710
+tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi
+tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
+tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
+tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
+tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
+tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+tune-$(CONFIG_CPU_V6K) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+
+ifeq ($(CONFIG_AEABI),y)
+CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
+else
+CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
+endif
+
+ifeq ($(CONFIG_ARM_UNWIND),y)
+CFLAGS_ABI +=-funwind-tables
+endif
+
+ifeq ($(CONFIG_THUMB2_KERNEL),y)
+AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
+AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
+CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
+AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
+# Work around buggy relocation from gas if requested:
+ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y)
+CFLAGS_MODULE +=-fno-optimize-sibling-calls
+endif
+endif
+
+# Need -Uarm for gcc < 3.x
+KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
+
+CHECKFLAGS += -D__arm__
+
+#Default value
+head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
+textofs-y := 0x00008000
+textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
+# We don't want the htc bootloader to corrupt kernel during resume
+textofs-$(CONFIG_PM_H1940) := 0x00108000
+# SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
+ifeq ($(CONFIG_ARCH_SA1100),y)
+textofs-$(CONFIG_SA1111) := 0x00208000
+endif
+
+# Machine directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+machine-$(CONFIG_ARCH_AT91) := at91
+machine-$(CONFIG_ARCH_BCMRING) := bcmring
+machine-$(CONFIG_ARCH_CLPS711X) := clps711x
+machine-$(CONFIG_ARCH_CNS3XXX) := cns3xxx
+machine-$(CONFIG_ARCH_DAVINCI) := davinci
+machine-$(CONFIG_ARCH_DOVE) := dove
+machine-$(CONFIG_ARCH_EBSA110) := ebsa110
+machine-$(CONFIG_ARCH_EP93XX) := ep93xx
+machine-$(CONFIG_ARCH_GEMINI) := gemini
+machine-$(CONFIG_ARCH_H720X) := h720x
+machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
+machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
+machine-$(CONFIG_ARCH_IOP32X) := iop32x
+machine-$(CONFIG_ARCH_IOP33X) := iop33x
+machine-$(CONFIG_ARCH_IXP2000) := ixp2000
+machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
+machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
+machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
+machine-$(CONFIG_ARCH_KS8695) := ks8695
+machine-$(CONFIG_ARCH_LOKI) := loki
+machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx
+machine-$(CONFIG_ARCH_MMP) := mmp
+machine-$(CONFIG_ARCH_MSM) := msm
+machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
+machine-$(CONFIG_ARCH_MX1) := imx
+machine-$(CONFIG_ARCH_MX2) := imx
+machine-$(CONFIG_ARCH_MX6) := mx6
+machine-$(CONFIG_ARCH_MX25) := imx
+machine-$(CONFIG_ARCH_MX3) := imx
+machine-$(CONFIG_ARCH_MX5) := mx5
+machine-$(CONFIG_ARCH_MXS) := mxs
+machine-$(CONFIG_ARCH_NETX) := netx
+machine-$(CONFIG_ARCH_NOMADIK) := nomadik
+machine-$(CONFIG_ARCH_OMAP1) := omap1
+machine-$(CONFIG_ARCH_OMAP2) := omap2
+machine-$(CONFIG_ARCH_OMAP3) := omap2
+machine-$(CONFIG_ARCH_OMAP4) := omap2
+machine-$(CONFIG_ARCH_ORION5X) := orion5x
+machine-$(CONFIG_ARCH_PNX4008) := pnx4008
+machine-$(CONFIG_ARCH_PXA) := pxa
+machine-$(CONFIG_ARCH_REALVIEW) := realview
+machine-$(CONFIG_ARCH_RPC) := rpc
+machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
+machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
+machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
+machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
+machine-$(CONFIG_ARCH_S5PC100) := s5pc100
+machine-$(CONFIG_ARCH_S5PV210) := s5pv210
+machine-$(CONFIG_ARCH_EXYNOS4) := exynos4
+machine-$(CONFIG_ARCH_SA1100) := sa1100
+machine-$(CONFIG_ARCH_SHARK) := shark
+machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
+machine-$(CONFIG_ARCH_TCC8K) := tcc8k
+machine-$(CONFIG_ARCH_TEGRA) := tegra
+machine-$(CONFIG_ARCH_U300) := u300
+machine-$(CONFIG_ARCH_U8500) := ux500
+machine-$(CONFIG_ARCH_VERSATILE) := versatile
+machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
+machine-$(CONFIG_ARCH_VT8500) := vt8500
+machine-$(CONFIG_ARCH_W90X900) := w90x900
+machine-$(CONFIG_ARCH_NUC93X) := nuc93x
+machine-$(CONFIG_FOOTBRIDGE) := footbridge
+machine-$(CONFIG_MACH_SPEAR300) := spear3xx
+machine-$(CONFIG_MACH_SPEAR310) := spear3xx
+machine-$(CONFIG_MACH_SPEAR320) := spear3xx
+machine-$(CONFIG_MACH_SPEAR600) := spear6xx
+
+# Platform directory name. This list is sorted alphanumerically
+# by CONFIG_* macro name.
+plat-$(CONFIG_ARCH_MXC) := mxc
+plat-$(CONFIG_ARCH_OMAP) := omap
+plat-$(CONFIG_ARCH_S3C64XX) := samsung
+plat-$(CONFIG_ARCH_TCC_926) := tcc
+plat-$(CONFIG_PLAT_IOP) := iop
+plat-$(CONFIG_PLAT_NOMADIK) := nomadik
+plat-$(CONFIG_PLAT_ORION) := orion
+plat-$(CONFIG_PLAT_PXA) := pxa
+plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung
+plat-$(CONFIG_PLAT_S5P) := s5p samsung
+plat-$(CONFIG_PLAT_SPEAR) := spear
+plat-$(CONFIG_PLAT_VERSATILE) := versatile
+
+ifeq ($(CONFIG_ARCH_EBSA110),y)
+# This is what happens if you forget the IOCS16 line.
+# PCMCIA cards stop working.
+CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL
+export CFLAGS_3c589_cs.o
+endif
+
+# The byte offset of the kernel image in RAM from the start of RAM.
+TEXT_OFFSET := $(textofs-y)
+
+# The first directory contains additional information for the boot setup code
+ifneq ($(machine-y),)
+MACHINE := arch/arm/mach-$(word 1,$(machine-y))/
+else
+MACHINE :=
+endif
+
+machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
+platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
+
+ifeq ($(KBUILD_SRC),)
+KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
+else
+KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
+endif
+
+export TEXT_OFFSET GZFLAGS MMUEXT
+
+# Do we have FASTFPE?
+FASTFPE :=arch/arm/fastfpe
+ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
+FASTFPE_OBJ :=$(FASTFPE)/
+endif
+
+core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
+core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
+core-$(CONFIG_VFP) += arch/arm/vfp/
+
+# If we have a machine-specific directory, then include it in the build.
+core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += $(machdirs) $(platdirs)
+
+drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
+
+libs-y := arch/arm/lib/ $(libs-y)
+
+# Default target when executing plain make
+ifeq ($(CONFIG_XIP_KERNEL),y)
+KBUILD_IMAGE := xipImage
+else
+KBUILD_IMAGE := zImage
+endif
+
+all: $(KBUILD_IMAGE)
+
+boot := arch/arm/boot
+
+archprepare:
+ $(Q)$(MAKE) $(build)=arch/arm/tools include/generated/mach-types.h
+
+# Convert bzImage to zImage
+bzImage: zImage
+
+zImage Image xipImage bootpImage uImage: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
+zinstall uinstall install: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+
+# We use MRPROPER_FILES and CLEAN_FILES now
+archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+# My testing targets (bypasses dependencies)
+bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
+i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
+
+
+define archhelp
+ echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+ echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+ echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
+ echo ' uImage - U-Boot wrapped zImage'
+ echo ' bootpImage - Combined zImage and initial RAM disk'
+ echo ' (supply initrd image via make variable INITRD=<path>)'
+ echo ' install - Install uncompressed kernel'
+ echo ' zinstall - Install compressed kernel'
+ echo ' uinstall - Install U-Boot wrapped compressed kernel'
+ echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or'
+ echo ' (distribution) /sbin/$(INSTALLKERNEL) or'
+ echo ' install to $$(INSTALL_PATH) and run lilo'
+endef
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
new file mode 100644
index 00000000..ce1c5ff7
--- /dev/null
+++ b/arch/arm/boot/.gitignore
@@ -0,0 +1,5 @@
+Image
+zImage
+xipImage
+bootpImage
+uImage
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
new file mode 100644
index 00000000..04d687eb
--- /dev/null
+++ b/arch/arm/boot/Makefile
@@ -0,0 +1,119 @@
+#
+# arch/arm/boot/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995-2002 Russell King
+#
+
+MKIMAGE := $(srctree)/scripts/mkuboot.sh
+
+ifneq ($(MACHINE),)
+include $(srctree)/$(MACHINE)/Makefile.boot
+endif
+
+# Note: the following conditions must always be true:
+# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
+# PARAMS_PHYS must be within 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+ZRELADDR := $(zreladdr-y)
+PARAMS_PHYS := $(params_phys-y)
+INITRD_PHYS := $(initrd_phys-y)
+
+export ZRELADDR INITRD_PHYS PARAMS_PHYS
+
+targets := Image zImage xipImage bootpImage uImage
+
+ifeq ($(CONFIG_XIP_KERNEL),y)
+
+$(obj)/xipImage: vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))'
+
+$(obj)/Image $(obj)/zImage: FORCE
+ @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)'
+ @echo 'Only the xipImage target is available in this case'
+ @false
+
+else
+
+$(obj)/xipImage: FORCE
+ @echo 'Kernel not configured for XIP (CONFIG_XIP_KERNEL!=y)'
+ @false
+
+$(obj)/Image: vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+$(obj)/compressed/vmlinux: $(obj)/Image FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/compressed $@
+
+$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+endif
+
+#quiet_cmd_uimage = UIMAGE $@
+# cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
+# -C none -a $(LOADADDR) -e $(STARTADDR) \
+# -n 'Linux-$(KERNELRELEASE)' -d $< $@
+
+quiet_cmd_uimage = UIMAGE $@
+ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
+ -C none -a $(LOADADDR) -e $(STARTADDR) \
+ -d $< $@
+
+ifeq ($(CONFIG_ZBOOT_ROM),y)
+$(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)
+else
+$(obj)/uImage: LOADADDR=$(ZRELADDR)
+endif
+
+$(obj)/uImage: STARTADDR=$(LOADADDR)
+
+$(obj)/uImage: $(obj)/zImage FORCE
+ $(call if_changed,uimage)
+ @echo ' Image $@ is ready'
+
+$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE
+ $(Q)$(MAKE) $(build)=$(obj)/bootp $@
+ @:
+
+$(obj)/bootpImage: $(obj)/bootp/bootp FORCE
+ $(call if_changed,objcopy)
+ @echo ' Kernel: $@ is ready'
+
+PHONY += initrd FORCE
+initrd:
+ @test "$(INITRD_PHYS)" != "" || \
+ (echo This machine does not support INITRD; exit -1)
+ @test "$(INITRD)" != "" || \
+ (echo You must specify INITRD; exit -1)
+
+install: $(obj)/Image
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/Image System.map "$(INSTALL_PATH)"
+
+zinstall: $(obj)/zImage
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/zImage System.map "$(INSTALL_PATH)"
+
+uinstall: $(obj)/uImage
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/uImage System.map "$(INSTALL_PATH)"
+
+zi:
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/zImage System.map "$(INSTALL_PATH)"
+
+i:
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/Image System.map "$(INSTALL_PATH)"
+
+subdir- := bootp compressed
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
new file mode 100644
index 00000000..c394e305
--- /dev/null
+++ b/arch/arm/boot/bootp/Makefile
@@ -0,0 +1,27 @@
+#
+# linux/arch/arm/boot/bootp/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies.
+#
+
+LDFLAGS_bootp :=-p --no-undefined -X \
+ --defsym initrd_phys=$(INITRD_PHYS) \
+ --defsym params_phys=$(PARAMS_PHYS) -T
+AFLAGS_initrd.o :=-DINITRD=\"$(INITRD)\"
+
+targets := bootp init.o kernel.o initrd.o
+
+# Note that bootp.lds picks up kernel.o and initrd.o
+$(obj)/bootp: $(src)/bootp.lds $(addprefix $(obj)/,init.o kernel.o initrd.o) FORCE
+ $(call if_changed,ld)
+ @:
+
+# kernel.o and initrd.o includes a binary image using
+# .incbin, a dependency which is not tracked automatically
+
+$(obj)/kernel.o: arch/arm/boot/zImage FORCE
+
+$(obj)/initrd.o: $(INITRD) FORCE
+
+PHONY += $(INITRD) FORCE
diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds
new file mode 100644
index 00000000..fc54394f
--- /dev/null
+++ b/arch/arm/boot/bootp/bootp.lds
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/boot/bootp/bootp.lds
+ *
+ * Copyright (C) 2000-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ .text : {
+ _stext = .;
+ *(.start)
+ *(.text)
+ initrd_size = initrd_end - initrd_start;
+ _etext = .;
+ }
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
new file mode 100644
index 00000000..78b50807
--- /dev/null
+++ b/arch/arm/boot/bootp/init.S
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/boot/bootp/init.S
+ *
+ * Copyright (C) 2000-2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * "Header" file for splitting kernel + initrd. Note that we pass
+ * r0 through to r3 straight through.
+ *
+ * This demonstrates how to append code to the start of the kernel
+ * zImage, and boot the kernel without copying it around. This
+ * example would be simpler; if we didn't have an object of unknown
+ * size immediately following the kernel, we could build this into
+ * a binary blob, and concatenate the zImage using the cat command.
+ */
+ .section .start,#alloc,#execinstr
+ .type _start, #function
+ .globl _start
+
+_start: add lr, pc, #-0x8 @ lr = current load addr
+ adr r13, data
+ ldmia r13!, {r4-r6} @ r5 = dest, r6 = length
+ add r4, r4, lr @ r4 = initrd_start + load addr
+ bl move @ move the initrd
+
+/*
+ * Setup the initrd parameters to pass to the kernel. This can only be
+ * passed in via the tagged list.
+ */
+ ldmia r13, {r5-r9} @ get size and addr of initrd
+ @ r5 = ATAG_CORE
+ @ r6 = ATAG_INITRD2
+ @ r7 = initrd start
+ @ r8 = initrd end
+ @ r9 = param_struct address
+
+ ldr r10, [r9, #4] @ get first tag
+ teq r10, r5 @ is it ATAG_CORE?
+/*
+ * If we didn't find a valid tag list, create a dummy ATAG_CORE entry.
+ */
+ movne r10, #0 @ terminator
+ movne r4, #2 @ Size of this entry (2 words)
+ stmneia r9, {r4, r5, r10} @ Size, ATAG_CORE, terminator
+
+/*
+ * find the end of the tag list, and then add an INITRD tag on the end.
+ * If there is already an INITRD tag, then we ignore it; the last INITRD
+ * tag takes precedence.
+ */
+taglist: ldr r10, [r9, #0] @ tag length
+ teq r10, #0 @ last tag (zero length)?
+ addne r9, r9, r10, lsl #2
+ bne taglist
+
+ mov r5, #4 @ Size of initrd tag (4 words)
+ stmia r9, {r5, r6, r7, r8, r10}
+ b kernel_start @ call kernel
+
+/*
+ * Move the block of memory length r6 from address r4 to address r5
+ */
+move: ldmia r4!, {r7 - r10} @ move 32-bytes at a time
+ stmia r5!, {r7 - r10}
+ ldmia r4!, {r7 - r10}
+ stmia r5!, {r7 - r10}
+ subs r6, r6, #8 * 4
+ bcs move
+ mov pc, lr
+
+ .size _start, . - _start
+
+ .align
+
+ .type data,#object
+data: .word initrd_start @ source initrd address
+ .word initrd_phys @ destination initrd address
+ .word initrd_size @ initrd size
+
+ .word 0x54410001 @ r5 = ATAG_CORE
+ .word 0x54420005 @ r6 = ATAG_INITRD2
+ .word initrd_phys @ r7
+ .word initrd_size @ r8
+ .word params_phys @ r9
+ .size data, . - data
diff --git a/arch/arm/boot/bootp/initrd.S b/arch/arm/boot/bootp/initrd.S
new file mode 100644
index 00000000..d81ea183
--- /dev/null
+++ b/arch/arm/boot/bootp/initrd.S
@@ -0,0 +1,6 @@
+ .type initrd_start,#object
+ .globl initrd_start
+initrd_start:
+ .incbin INITRD
+ .globl initrd_end
+initrd_end:
diff --git a/arch/arm/boot/bootp/kernel.S b/arch/arm/boot/bootp/kernel.S
new file mode 100644
index 00000000..b87a25c7
--- /dev/null
+++ b/arch/arm/boot/bootp/kernel.S
@@ -0,0 +1,6 @@
+ .globl kernel_start
+kernel_start:
+ .incbin "arch/arm/boot/zImage"
+ .globl kernel_end
+kernel_end:
+ .align 2
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
new file mode 100644
index 00000000..c6028967
--- /dev/null
+++ b/arch/arm/boot/compressed/.gitignore
@@ -0,0 +1,7 @@
+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
new file mode 100644
index 00000000..23aad072
--- /dev/null
+++ b/arch/arm/boot/compressed/Makefile
@@ -0,0 +1,152 @@
+#
+# linux/arch/arm/boot/compressed/Makefile
+#
+# create a compressed vmlinuz image from the original vmlinux
+#
+
+OBJS =
+
+# Ensure that mmcif loader code appears early in the image
+# to minimise that number of bocks that have to be read in
+# order to load it.
+ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
+ifeq ($(CONFIG_ARCH_SH7372),y)
+OBJS += mmcif-sh7372.o
+endif
+endif
+
+AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
+HEAD = head.o
+OBJS += misc.o decompress.o
+FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
+
+#
+# Architecture dependencies
+#
+ifeq ($(CONFIG_ARCH_ACORN),y)
+OBJS += ll_char_wr.o font.o
+endif
+
+ifeq ($(CONFIG_ARCH_SHARK),y)
+OBJS += head-shark.o ofw-shark.o
+endif
+
+ifeq ($(CONFIG_ARCH_P720T),y)
+# Borrow this code from SA1100
+OBJS += head-sa1100.o
+endif
+
+ifeq ($(CONFIG_ARCH_SA1100),y)
+OBJS += head-sa1100.o
+endif
+
+ifeq ($(CONFIG_ARCH_VT8500),y)
+OBJS += head-vt8500.o
+endif
+
+ifeq ($(CONFIG_CPU_XSCALE),y)
+OBJS += head-xscale.o
+endif
+
+ifeq ($(CONFIG_PXA_SHARPSL_DETECT_MACH_ID),y)
+OBJS += head-sharpsl.o
+endif
+
+ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
+ifeq ($(CONFIG_CPU_CP15),y)
+OBJS += big-endian.o
+else
+# The endian should be set by h/w design.
+endif
+endif
+
+ifeq ($(CONFIG_ARCH_SHMOBILE),y)
+OBJS += head-shmobile.o
+endif
+
+#
+# We now have a PIC decompressor implementation. Decompressors running
+# from RAM should not define ZTEXTADDR. Decompressors running directly
+# from ROM or Flash must define ZTEXTADDR (preferably via the config)
+# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK
+ifeq ($(CONFIG_ZBOOT_ROM),y)
+ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT)
+ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)
+else
+ZTEXTADDR := 0
+ZBSSADDR := ALIGN(8)
+endif
+
+SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
+
+suffix_$(CONFIG_KERNEL_GZIP) = gzip
+suffix_$(CONFIG_KERNEL_LZO) = lzo
+suffix_$(CONFIG_KERNEL_LZMA) = lzma
+
+targets := vmlinux vmlinux.lds \
+ piggy.$(suffix_y) piggy.$(suffix_y).o \
+ font.o font.c head.o misc.o $(OBJS)
+
+# Make sure files are removed during clean
+extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S
+
+ifeq ($(CONFIG_FUNCTION_TRACER),y)
+ORIG_CFLAGS := $(KBUILD_CFLAGS)
+KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+endif
+
+ccflags-y := -fpic -fno-builtin
+asflags-y := -Wa,-march=all
+
+# Supply ZRELADDR to the decompressor via a linker symbol.
+ifneq ($(CONFIG_AUTO_ZRELADDR),y)
+LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
+endif
+ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
+LDFLAGS_vmlinux += --be8
+endif
+# ?
+LDFLAGS_vmlinux += -p
+# Report unresolved symbol references
+LDFLAGS_vmlinux += --no-undefined
+# Delete all temporary local symbols
+LDFLAGS_vmlinux += -X
+# Next argument is a linker script
+LDFLAGS_vmlinux += -T
+
+# For __aeabi_uidivmod
+lib1funcs = $(obj)/lib1funcs.o
+
+$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
+ $(call cmd,shipped)
+
+# We need to prevent any GOTOFF relocs being used with references
+# to symbols in the .bss section since we cannot relocate them
+# independently from the rest at run time. This can be achieved by
+# ensuring that no private .bss symbols exist, as global symbols
+# always have a GOT entry which is what we need.
+# The .data section is already discarded by the linker script so no need
+# to bother about it here.
+check_for_bad_syms = \
+bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
+[ -z "$$bad_syms" ] || \
+ ( echo "following symbols must have non local/private scope:" >&2; \
+ echo "$$bad_syms" >&2; rm -f $@; false )
+
+$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
+ $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
+ $(call if_changed,ld)
+ @$(check_for_bad_syms)
+
+$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
+ $(call if_changed,$(suffix_y))
+
+$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE
+
+CFLAGS_font.o := -Dstatic=
+
+$(obj)/font.c: $(FONTC)
+ $(call cmd,shipped)
+
+$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
+ @sed "$(SEDFLAGS)" < $< > $@
diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S
new file mode 100644
index 00000000..25ab26f1
--- /dev/null
+++ b/arch/arm/boot/compressed/big-endian.S
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/boot/compressed/big-endian.S
+ *
+ * Switch CPU into big endian mode.
+ * Author: Nicolas Pitre
+ */
+
+ .section ".start", #alloc, #execinstr
+
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #(1 << 7) @ enable big endian mode
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+
diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c
new file mode 100644
index 00000000..07be5a2f
--- /dev/null
+++ b/arch/arm/boot/compressed/decompress.c
@@ -0,0 +1,50 @@
+#define _LINUX_STRING_H_
+
+#include <linux/compiler.h> /* for inline */
+#include <linux/types.h> /* for size_t */
+#include <linux/stddef.h> /* for NULL */
+#include <linux/linkage.h>
+#include <asm/string.h>
+
+extern unsigned long free_mem_ptr;
+extern unsigned long free_mem_end_ptr;
+extern void error(char *);
+
+#define STATIC static
+#define STATIC_RW_DATA /* non-static please */
+
+#define ARCH_HAS_DECOMP_WDOG
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifdef CONFIG_KERNEL_GZIP
+#include "../../../../lib/decompress_inflate.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZO
+#include "../../../../lib/decompress_unlzo.c"
+#endif
+
+#ifdef CONFIG_KERNEL_LZMA
+#include "../../../../lib/decompress_unlzma.c"
+#endif
+
+int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
+{
+ return decompress(input, len, NULL, NULL, output, NULL, error);
+}
diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S
new file mode 100644
index 00000000..6179d94d
--- /dev/null
+++ b/arch/arm/boot/compressed/head-sa1100.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/boot/compressed/head-sa1100.S
+ *
+ * Copyright (C) 1999 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * SA1100 specific tweaks. This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+ .section ".start", "ax"
+
+__SA1100_start:
+
+ @ Preserve r8/r7 i.e. kernel entry values
+#ifdef CONFIG_SA1100_COLLIE
+ mov r7, #MACH_TYPE_COLLIE
+#endif
+#ifdef CONFIG_SA1100_SIMPAD
+ @ UNTIL we've something like an open bootldr
+ mov r7, #MACH_TYPE_SIMPAD @should be 87
+#endif
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ ands r0, r0, #0x0d
+ beq 99f
+
+ @ Data cache might be active.
+ @ Be sure to flush kernel binary out of the cache,
+ @ whatever state it is, before it is turned off.
+ @ This is done by fetching through currently executed
+ @ memory to be sure we hit the same cache.
+ bic r2, pc, #0x1f
+ add r3, r2, #0x4000 @ 16 kb is quite enough...
+1: ldr r0, [r2], #32
+ teq r2, r3
+ bne 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
+
+ @ disabling MMU and caches
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ bic r0, r0, #0x0d @ clear WB, DC, MMU
+ bic r0, r0, #0x1000 @ clear Icache
+ mcr p15, 0, r0, c1, c0, 0
+99:
diff --git a/arch/arm/boot/compressed/head-shark.S b/arch/arm/boot/compressed/head-shark.S
new file mode 100644
index 00000000..089c560e
--- /dev/null
+++ b/arch/arm/boot/compressed/head-shark.S
@@ -0,0 +1,139 @@
+/* The head-file for the Shark
+ * by Alexander Schulz
+ *
+ * Does the following:
+ * - get the memory layout from firmware. This can only be done as long as the mmu
+ * is still on.
+ * - switch the mmu off, so we have physical addresses
+ * - copy the kernel to 0x08508000. This is done to have a fixed address where the
+ * C-parts (misc.c) are executed. This address must be known at compile-time,
+ * but the load-address of the kernel depends on how much memory is installed.
+ * - Jump to this location.
+ * - Set r8 with 0, r7 with the architecture ID for head.S
+ */
+
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+
+ .section ".start", "ax"
+
+ b __beginning
+
+__ofw_data: .long 0 @ the number of memory blocks
+ .space 128 @ (startaddr,size) ...
+ .space 128 @ bootargs
+ .align
+
+__beginning: mov r4, r0 @ save the entry to the firmware
+
+ mov r0, #0xC0 @ disable irq and fiq
+ mov r1, r0
+ mrs r3, cpsr
+ bic r2, r3, r0
+ eor r2, r2, r1
+ msr cpsr_c, r2
+
+ mov r0, r4 @ get the Memory layout from firmware
+ adr r1, __ofw_data
+ add r2, r1, #4
+ mov lr, pc
+ b ofw_init
+ mov r1, #0
+
+ adr r2, __mmu_off @ calculate physical address
+ sub r2, r2, #0xf0000000 @ openprom maps us at f000 virt, 0e50 phys
+ adr r0, __ofw_data
+ ldr r0, [r0, #4]
+ add r2, r2, r0
+ add r2, r2, #0x00500000
+
+ mrc p15, 0, r3, c1, c0
+ bic r3, r3, #0xC @ Write Buffer and DCache
+ bic r3, r3, #0x1000 @ ICache
+ mcr p15, 0, r3, c1, c0 @ disabled
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+ mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4
+
+ bic r3, r3, #0x1 @ MMU
+ mcr p15, 0, r3, c1, c0 @ disabled
+
+ mov pc, r2
+
+__copy_target: .long 0x08507FFC
+__copy_end: .long 0x08607FFC
+
+ .word _start
+ .word __bss_start
+
+ .align
+__temp_stack: .space 128
+
+__mmu_off:
+ adr r0, __ofw_data @ read the 1. entry of the memory map
+ ldr r0, [r0, #4]
+ orr r0, r0, #0x00600000
+ sub r0, r0, #4
+
+ ldr r1, __copy_end
+ ldr r3, __copy_target
+
+/* r0 = 0x0e600000 (current end of kernelcode)
+ * r3 = 0x08508000 (where it should begin)
+ * r1 = 0x08608000 (end of copying area, 1MB)
+ * The kernel is compressed, so 1 MB should be enough.
+ * copy the kernel to the beginning of physical memory
+ * We start from the highest address, so we can copy
+ * from 0x08500000 to 0x08508000 if we have only 8MB
+ */
+
+/* As we get more 2.6-kernels it gets more and more
+ * uncomfortable to be bound to kernel images of 1MB only.
+ * So we add a loop here, to be able to copy some more.
+ * Alexander Schulz 2005-07-17
+ */
+
+ mov r4, #3 @ How many megabytes to copy
+
+
+__MoveCode: sub r4, r4, #1
+
+__Copy: ldr r2, [r0], #-4
+ str r2, [r1], #-4
+ teq r1, r3
+ bne __Copy
+
+ /* The firmware maps us in blocks of 1 MB, the next block is
+ _below_ the last one. So our decrementing source pointer
+ ist right here, but the destination pointer must be increased
+ by 2 MB */
+ add r1, r1, #0x00200000
+ add r3, r3, #0x00100000
+
+ teq r4, #0
+ bne __MoveCode
+
+
+ /* and jump to it */
+ adr r2, __go_on @ where we want to jump
+ adr r0, __ofw_data @ read the 1. entry of the memory map
+ ldr r0, [r0, #4]
+ sub r2, r2, r0 @ we are mapped add 0e50 now, sub that (-0e00)
+ sub r2, r2, #0x00500000 @ -0050
+ ldr r0, __copy_target @ and add 0850 8000 instead
+ add r0, r0, #4
+ add r2, r2, r0
+ mov pc, r2 @ and jump there
+
+__go_on:
+ adr sp, __temp_stack
+ add sp, sp, #128
+ adr r0, __ofw_data
+ mov lr, pc
+ b create_params
+
+ mov r8, #0
+ mov r7, #15
diff --git a/arch/arm/boot/compressed/head-sharpsl.S b/arch/arm/boot/compressed/head-sharpsl.S
new file mode 100644
index 00000000..eb0084ea
--- /dev/null
+++ b/arch/arm/boot/compressed/head-sharpsl.S
@@ -0,0 +1,150 @@
+/*
+ * linux/arch/arm/boot/compressed/head-sharpsl.S
+ *
+ * Copyright (C) 2004-2005 Richard Purdie <rpurdie@rpsys.net>
+ *
+ * Sharp's bootloader doesn't pass any kind of machine ID
+ * so we have to figure out the machine for ourselves...
+ *
+ * Support for Poodle, Corgi (SL-C700), Shepherd (SL-C750)
+ * Husky (SL-C760), Tosa (SL-C6000), Spitz (SL-C3000),
+ * Akita (SL-C1000) and Borzoi (SL-C3100).
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+#ifndef CONFIG_PXA_SHARPSL
+#error What am I doing here...
+#endif
+
+ .section ".start", "ax"
+
+__SharpSL_start:
+
+/* Check for TC6393 - if found we have a Tosa */
+ ldr r7, .TOSAID
+ mov r1, #0x10000000 @ Base address of TC6393 chip
+ mov r6, #0x03
+ ldrh r3, [r1, #8] @ Load TC6393XB Revison: This is 0x0003
+ cmp r6, r3
+ beq .SHARPEND @ Success -> tosa
+
+/* Check for pxa270 - if found, branch */
+ mrc p15, 0, r4, c0, c0 @ Get Processor ID
+ and r4, r4, #0xffffff00
+ ldr r3, .PXA270ID
+ cmp r4, r3
+ beq .PXA270
+
+/* Check for w100 - if not found we have a Poodle */
+ ldr r1, .W100ADDR @ Base address of w100 chip + regs offset
+
+ mov r6, #0x31 @ Load Magic Init value
+ str r6, [r1, #0x280] @ to SCRATCH_UMSK
+ mov r5, #0x3000
+.W100LOOP:
+ subs r5, r5, #1
+ bne .W100LOOP
+ mov r6, #0x30 @ Load 2nd Magic Init value
+ str r6, [r1, #0x280] @ to SCRATCH_UMSK
+
+ ldr r6, [r1, #0] @ Load Chip ID
+ ldr r3, .W100ID
+ ldr r7, .POODLEID
+ cmp r6, r3
+ bne .SHARPEND @ We have no w100 - Poodle
+
+/* Check for pxa250 - if found we have a Corgi */
+ ldr r7, .CORGIID
+ ldr r3, .PXA255ID
+ cmp r4, r3
+ blo .SHARPEND @ We have a PXA250 - Corgi
+
+/* Check for 64MiB flash - if found we have a Shepherd */
+ bl get_flash_ids
+ ldr r7, .SHEPHERDID
+ cmp r3, #0x76 @ 64MiB flash
+ beq .SHARPEND @ We have Shepherd
+
+/* Must be a Husky */
+ ldr r7, .HUSKYID @ Must be Husky
+ b .SHARPEND
+
+.PXA270:
+/* Check for 16MiB flash - if found we have Spitz */
+ bl get_flash_ids
+ ldr r7, .SPITZID
+ cmp r3, #0x73 @ 16MiB flash
+ beq .SHARPEND @ We have Spitz
+
+/* Check for a second SCOOP chip - if found we have Borzoi */
+ ldr r1, .SCOOP2ADDR
+ ldr r7, .BORZOIID
+ mov r6, #0x0140
+ strh r6, [r1]
+ ldrh r6, [r1]
+ cmp r6, #0x0140
+ beq .SHARPEND @ We have Borzoi
+
+/* Must be Akita */
+ ldr r7, .AKITAID
+ b .SHARPEND @ We have Borzoi
+
+.PXA255ID:
+ .word 0x69052d00 @ PXA255 Processor ID
+.PXA270ID:
+ .word 0x69054100 @ PXA270 Processor ID
+.W100ID:
+ .word 0x57411002 @ w100 Chip ID
+.W100ADDR:
+ .word 0x08010000 @ w100 Chip ID Reg Address
+.SCOOP2ADDR:
+ .word 0x08800040
+.POODLEID:
+ .word MACH_TYPE_POODLE
+.CORGIID:
+ .word MACH_TYPE_CORGI
+.SHEPHERDID:
+ .word MACH_TYPE_SHEPHERD
+.HUSKYID:
+ .word MACH_TYPE_HUSKY
+.TOSAID:
+ .word MACH_TYPE_TOSA
+.SPITZID:
+ .word MACH_TYPE_SPITZ
+.AKITAID:
+ .word MACH_TYPE_AKITA
+.BORZOIID:
+ .word MACH_TYPE_BORZOI
+
+/*
+ * Return: r2 - NAND Manufacturer ID
+ * r3 - NAND Chip ID
+ * Corrupts: r1
+ */
+get_flash_ids:
+ mov r1, #0x0c000000 @ Base address of NAND chip
+ ldrb r3, [r1, #24] @ Load FLASHCTL
+ bic r3, r3, #0x11 @ SET NCE
+ orr r3, r3, #0x0a @ SET CLR + FLWP
+ strb r3, [r1, #24] @ Save to FLASHCTL
+ mov r2, #0x90 @ Command "readid"
+ strb r2, [r1, #20] @ Save to FLASHIO
+ bic r3, r3, #2 @ CLR CLE
+ orr r3, r3, #4 @ SET ALE
+ strb r3, [r1, #24] @ Save to FLASHCTL
+ mov r2, #0 @ Address 0x00
+ strb r2, [r1, #20] @ Save to FLASHIO
+ bic r3, r3, #4 @ CLR ALE
+ strb r3, [r1, #24] @ Save to FLASHCTL
+.fids1:
+ ldrb r3, [r1, #24] @ Load FLASHCTL
+ tst r3, #32 @ Is chip ready?
+ beq .fids1
+ ldrb r2, [r1, #20] @ NAND Manufacturer ID
+ ldrb r3, [r1, #20] @ NAND Chip ID
+ mov pc, lr
+
+.SHARPEND:
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
new file mode 100644
index 00000000..c943d2e7
--- /dev/null
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -0,0 +1,83 @@
+/*
+ * The head-file for SH-Mobile ARM platforms
+ *
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Simon Horman <horms@verge.net.au>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+#ifdef CONFIG_ZBOOT_ROM
+
+ .section ".start", "ax"
+
+ /* load board-specific initialization code */
+#include <mach/zboot.h>
+
+#ifdef CONFIG_ZBOOT_ROM_MMCIF
+ /* Load image from MMC */
+ adr sp, __tmp_stack + 128
+ ldr r0, __image_start
+ ldr r1, __image_end
+ subs r1, r1, r0
+ ldr r0, __load_base
+ bl mmcif_loader
+
+ /* Jump to loaded code */
+ ldr r0, __loaded
+ ldr r1, __image_start
+ sub r0, r0, r1
+ ldr r1, __load_base
+ add pc, r0, r1
+
+__image_start:
+ .long _start
+__image_end:
+ .long _got_end
+__load_base:
+ .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
+__loaded:
+ .long __continue
+ .align
+__tmp_stack:
+ .space 128
+__continue:
+#endif /* CONFIG_ZBOOT_ROM_MMCIF */
+
+ b 1f
+__atags:@ tag #1
+ .long 12 @ tag->hdr.size = tag_size(tag_core);
+ .long 0x54410001 @ tag->hdr.tag = ATAG_CORE;
+ .long 0 @ tag->u.core.flags = 0;
+ .long 0 @ tag->u.core.pagesize = 0;
+ .long 0 @ tag->u.core.rootdev = 0;
+ @ tag #2
+ .long 8 @ tag->hdr.size = tag_size(tag_mem32);
+ .long 0x54410002 @ tag->hdr.tag = ATAG_MEM;
+ .long CONFIG_MEMORY_SIZE @ tag->u.mem.size = CONFIG_MEMORY_SIZE;
+ .long CONFIG_MEMORY_START @ @ tag->u.mem.start = CONFIG_MEMORY_START;
+ @ tag #3
+ .long 0 @ tag->hdr.size = 0
+ .long 0 @ tag->hdr.tag = ATAG_NONE;
+1:
+
+ /* Set board ID necessary for boot */
+ ldr r7, 1f @ Set machine type register
+ adr r8, __atags @ Set atag register
+ b 2f
+
+1 : .long MACH_TYPE
+2 :
+
+#endif /* CONFIG_ZBOOT_ROM */
diff --git a/arch/arm/boot/compressed/head-vt8500.S b/arch/arm/boot/compressed/head-vt8500.S
new file mode 100644
index 00000000..1dc1e21a
--- /dev/null
+++ b/arch/arm/boot/compressed/head-vt8500.S
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/boot/compressed/head-vt8500.S
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * VIA VT8500 specific tweaks. This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/mach-types.h>
+
+ .section ".start", "ax"
+
+__VT8500_start:
+ @ Compare the SCC ID register against a list of known values
+ ldr r1, .SCCID
+ ldr r3, [r1]
+
+ @ VT8500 override
+ ldr r4, .VT8500SCC
+ cmp r3, r4
+ ldreq r7, .ID_BV07
+ beq .Lendvt8500
+
+ @ WM8505 override
+ ldr r4, .WM8505SCC
+ cmp r3, r4
+ ldreq r7, .ID_8505
+ beq .Lendvt8500
+
+ @ Otherwise, leave the bootloader's machine id untouched
+
+.SCCID:
+ .word 0xd8120000
+.VT8500SCC:
+ .word 0x34000102
+.WM8505SCC:
+ .word 0x34260103
+
+.ID_BV07:
+ .word MACH_TYPE_BV07
+.ID_8505:
+ .word MACH_TYPE_WM8505_7IN_NETBOOK
+
+.Lendvt8500:
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
new file mode 100644
index 00000000..aa5ee49c
--- /dev/null
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -0,0 +1,41 @@
+/*
+ * linux/arch/arm/boot/compressed/head-xscale.S
+ *
+ * XScale specific tweaks. This is merged into head.S by the linker.
+ *
+ */
+
+#include <linux/linkage.h>
+
+ .section ".start", "ax"
+
+__XScale_start:
+
+ @ Preserve r8/r7 i.e. kernel entry values
+
+ @ Data cache might be active.
+ @ Be sure to flush kernel binary out of the cache,
+ @ whatever state it is, before it is turned off.
+ @ This is done by fetching through currently executed
+ @ memory to be sure we hit the same cache.
+ bic r2, pc, #0x1f
+ add r3, r2, #0x10000 @ 64 kb is quite enough...
+1: ldr r0, [r2], #32
+ teq r2, r3
+ bne 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
+
+ @ disabling MMU and caches
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ bic r0, r0, #0x05 @ clear DC, MMU
+ bic r0, r0, #0x1000 @ clear Icache
+ mcr p15, 0, r0, c1, c0, 0
+
+#ifdef CONFIG_ARCH_IXP2000
+ mov r1, #-1
+ mov r0, #0xd6000000
+ str r1, [r0, #0x14]
+ str r1, [r0, #0x18]
+#endif
+
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
new file mode 100644
index 00000000..e58603b0
--- /dev/null
+++ b/arch/arm/boot/compressed/head.S
@@ -0,0 +1,1121 @@
+/*
+ * linux/arch/arm/boot/compressed/head.S
+ *
+ * Copyright (C) 1996-2002 Russell King
+ * Copyright (C) 2004 Hyok S. Choi (MPU 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/linkage.h>
+
+/*
+ * Debugging stuff
+ *
+ * Note that these macros must not contain any code which is not
+ * 100% relocatable. Any attempt to do so will result in a crash.
+ * Please select one of the following when turning on debugging.
+ */
+#ifdef DEBUG
+
+#if defined(CONFIG_DEBUG_ICEDCC)
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
+ .macro loadsp, rb, tmp
+ .endm
+ .macro writeb, ch, rb
+ mcr p14, 0, \ch, c0, c5, 0
+ .endm
+#elif defined(CONFIG_CPU_XSCALE)
+ .macro loadsp, rb, tmp
+ .endm
+ .macro writeb, ch, rb
+ mcr p14, 0, \ch, c8, c0, 0
+ .endm
+#else
+ .macro loadsp, rb, tmp
+ .endm
+ .macro writeb, ch, rb
+ mcr p14, 0, \ch, c1, c0, 0
+ .endm
+#endif
+
+#else
+
+#include <mach/debug-macro.S>
+
+ .macro writeb, ch, rb
+ senduart \ch, \rb
+ .endm
+
+#if defined(CONFIG_ARCH_SA1100)
+ .macro loadsp, rb, tmp
+ mov \rb, #0x80000000 @ physical base address
+#ifdef CONFIG_DEBUG_LL_SER3
+ add \rb, \rb, #0x00050000 @ Ser3
+#else
+ add \rb, \rb, #0x00010000 @ Ser1
+#endif
+ .endm
+#elif defined(CONFIG_ARCH_S3C2410)
+ .macro loadsp, rb, tmp
+ mov \rb, #0x50000000
+ add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT
+ .endm
+#else
+ .macro loadsp, rb, tmp
+ addruart \rb, \tmp
+ .endm
+#endif
+#endif
+#endif
+
+ .macro kputc,val
+ mov r0, \val
+ bl putc
+ .endm
+
+ .macro kphex,val,len
+ mov r0, \val
+ mov r1, #\len
+ bl phex
+ .endm
+
+ .macro debug_reloc_start
+#ifdef DEBUG
+ kputc #'\n'
+ kphex r6, 8 /* processor id */
+ kputc #':'
+ kphex r7, 8 /* architecture id */
+#ifdef CONFIG_CPU_CP15
+ kputc #':'
+ mrc p15, 0, r0, c1, c0
+ kphex r0, 8 /* control reg */
+#endif
+ kputc #'\n'
+ kphex r5, 8 /* decompressed kernel start */
+ kputc #'-'
+ kphex r9, 8 /* decompressed kernel end */
+ kputc #'>'
+ kphex r4, 8 /* kernel execution address */
+ kputc #'\n'
+#endif
+ .endm
+
+ .macro debug_reloc_end
+#ifdef DEBUG
+ kphex r5, 8 /* end of kernel */
+ kputc #'\n'
+ mov r0, r4
+ bl memdump /* dump 256 bytes at start of kernel */
+#endif
+ .endm
+
+ .section ".start", #alloc, #execinstr
+/*
+ * sort out different calling conventions
+ */
+ .align
+ .arm @ Always enter in ARM state
+start:
+ .type start,#function
+ .rept 7
+ mov r0, r0
+ .endr
+ ARM( mov r0, r0 )
+ ARM( b 1f )
+ THUMB( adr r12, BSYM(1f) )
+ THUMB( bx r12 )
+
+ .word 0x016f2818 @ Magic numbers to help the loader
+ .word start @ absolute load/run zImage address
+ .word _edata @ zImage end address
+ THUMB( .thumb )
+1: mov r7, r1 @ save architecture ID
+ mov r8, r2 @ save atags pointer
+
+#ifndef __ARM_ARCH_2__
+ /*
+ * Booting from Angel - need to enter SVC mode and disable
+ * FIQs/IRQs (numeric definitions from angel arm.h source).
+ * We only do this if we were in user mode on entry.
+ */
+ mrs r2, cpsr @ get current mode
+ tst r2, #3 @ not user?
+ bne not_angel
+ mov r0, #0x17 @ angel_SWIreason_EnterSVC
+ ARM( swi 0x123456 ) @ angel_SWI_ARM
+ THUMB( svc 0xab ) @ angel_SWI_THUMB
+not_angel:
+ mrs r2, cpsr @ turn off interrupts to
+ orr r2, r2, #0xc0 @ prevent angel from running
+ msr cpsr_c, r2
+#else
+ teqp pc, #0x0c000003 @ turn off interrupts
+#endif
+
+ /*
+ * Note that some cache flushing and other stuff may
+ * be needed here - is there an Angel SWI call for this?
+ */
+
+ /*
+ * some architecture specific code can be inserted
+ * by the linker here, but it should preserve r7, r8, and r9.
+ */
+
+ .text
+
+#ifdef CONFIG_AUTO_ZRELADDR
+ @ determine final kernel image address
+ mov r4, pc
+ and r4, r4, #0xf8000000
+ add r4, r4, #TEXT_OFFSET
+#else
+ ldr r4, =zreladdr
+#endif
+
+ bl cache_on
+
+restart: adr r0, LC0
+ ldmia r0, {r1, r2, r3, r6, r10, r11, r12}
+ ldr sp, [r0, #28]
+
+ /*
+ * We might be running at a different address. We need
+ * to fix up various pointers.
+ */
+ sub r0, r0, r1 @ calculate the delta offset
+ add r6, r6, r0 @ _edata
+ add r10, r10, r0 @ inflated kernel size location
+
+ /*
+ * The kernel build system appends the size of the
+ * decompressed kernel at the end of the compressed data
+ * in little-endian form.
+ */
+ ldrb r9, [r10, #0]
+ ldrb lr, [r10, #1]
+ orr r9, r9, lr, lsl #8
+ ldrb lr, [r10, #2]
+ ldrb r10, [r10, #3]
+ orr r9, r9, lr, lsl #16
+ orr r9, r9, r10, lsl #24
+
+#ifndef CONFIG_ZBOOT_ROM
+ /* malloc space is above the relocated stack (64k max) */
+ add sp, sp, r0
+ add r10, sp, #0x10000
+#else
+ /*
+ * With ZBOOT_ROM the bss/stack is non relocatable,
+ * but someone could still run this code from RAM,
+ * in which case our reference is _edata.
+ */
+ mov r10, r6
+#endif
+
+/*
+ * Check to see if we will overwrite ourselves.
+ * r4 = final kernel address
+ * r9 = size of decompressed image
+ * r10 = end of this image, including bss/stack/malloc space if non XIP
+ * We basically want:
+ * r4 - 16k page directory >= r10 -> OK
+ * r4 + image length <= current position (pc) -> OK
+ */
+ add r10, r10, #16384
+ cmp r4, r10
+ bhs wont_overwrite
+ add r10, r4, r9
+ ARM( cmp r10, pc )
+ THUMB( mov lr, pc )
+ THUMB( cmp r10, lr )
+ bls wont_overwrite
+
+/*
+ * Relocate ourselves past the end of the decompressed kernel.
+ * r6 = _edata
+ * r10 = end of the decompressed kernel
+ * Because we always copy ahead, we need to do it from the end and go
+ * backward in case the source and destination overlap.
+ */
+ /*
+ * Bump to the next 256-byte boundary with the size of
+ * the relocation code added. This avoids overwriting
+ * ourself when the offset is small.
+ */
+ add r10, r10, #((reloc_code_end - restart + 256) & ~255)
+ bic r10, r10, #255
+
+ /* Get start of code we want to copy and align it down. */
+ adr r5, restart
+ bic r5, r5, #31
+
+ sub r9, r6, r5 @ size to copy
+ add r9, r9, #31 @ rounded up to a multiple
+ bic r9, r9, #31 @ ... of 32 bytes
+ add r6, r9, r5
+ add r9, r9, r10
+
+1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
+ cmp r6, r5
+ stmdb r9!, {r0 - r3, r10 - r12, lr}
+ bhi 1b
+
+ /* Preserve offset to relocated code. */
+ sub r6, r9, r6
+
+#ifndef CONFIG_ZBOOT_ROM
+ /* cache_clean_flush may use the stack, so relocate it */
+ add sp, sp, r6
+#endif
+
+ bl cache_clean_flush
+
+ adr r0, BSYM(restart)
+ add r0, r0, r6
+ mov pc, r0
+
+wont_overwrite:
+/*
+ * If delta is zero, we are running at the address we were linked at.
+ * r0 = delta
+ * r2 = BSS start
+ * r3 = BSS end
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ * r8 = atags pointer
+ * r11 = GOT start
+ * r12 = GOT end
+ * sp = stack pointer
+ */
+ teq r0, #0
+ beq not_relocated
+ add r11, r11, r0
+ add r12, r12, r0
+
+#ifndef CONFIG_ZBOOT_ROM
+ /*
+ * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
+ * we need to fix up pointers into the BSS region.
+ * Note that the stack pointer has already been fixed up.
+ */
+ add r2, r2, r0
+ add r3, r3, r0
+
+ /*
+ * Relocate all entries in the GOT table.
+ */
+1: ldr r1, [r11, #0] @ relocate entries in the GOT
+ add r1, r1, r0 @ table. This fixes up the
+ str r1, [r11], #4 @ C references.
+ cmp r11, r12
+ blo 1b
+#else
+
+ /*
+ * Relocate entries in the GOT table. We only relocate
+ * the entries that are outside the (relocated) BSS region.
+ */
+1: ldr r1, [r11, #0] @ relocate entries in the GOT
+ cmp r1, r2 @ entry < bss_start ||
+ cmphs r3, r1 @ _end < entry
+ addlo r1, r1, r0 @ table. This fixes up the
+ str r1, [r11], #4 @ C references.
+ cmp r11, r12
+ blo 1b
+#endif
+
+not_relocated: mov r0, #0
+1: str r0, [r2], #4 @ clear bss
+ str r0, [r2], #4
+ str r0, [r2], #4
+ str r0, [r2], #4
+ cmp r2, r3
+ blo 1b
+
+/*
+ * The C runtime environment should now be setup sufficiently.
+ * Set up some pointers, and start decompressing.
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ * r8 = atags pointer
+ */
+ mov r0, r4
+ mov r1, sp @ malloc space above stack
+ add r2, sp, #0x10000 @ 64k max
+ mov r3, r7
+ bl decompress_kernel
+ bl cache_clean_flush
+ bl cache_off
+ mov r0, #0 @ must be zero
+ mov r1, r7 @ restore architecture number
+ mov r2, r8 @ restore atags pointer
+ mov pc, r4 @ call kernel
+
+ .align 2
+ .type LC0, #object
+LC0: .word LC0 @ r1
+ .word __bss_start @ r2
+ .word _end @ r3
+ .word _edata @ r6
+ .word input_data_end - 4 @ r10 (inflated size location)
+ .word _got_start @ r11
+ .word _got_end @ ip
+ .word .L_user_stack_end @ sp
+ .size LC0, . - LC0
+
+#ifdef CONFIG_ARCH_RPC
+ .globl params
+params: ldr r0, =0x10000100 @ params_phys for RPC
+ mov pc, lr
+ .ltorg
+ .align
+#endif
+
+/*
+ * Turn on the cache. We need to setup some page tables so that we
+ * can have both the I and D caches on.
+ *
+ * We place the page tables 16k down from the kernel execution address,
+ * and we hope that nothing else is using it. If we're using it, we
+ * will go pop!
+ *
+ * On entry,
+ * r4 = kernel execution address
+ * r7 = architecture number
+ * r8 = atags pointer
+ * On exit,
+ * r0, r1, r2, r3, r9, r10, r12 corrupted
+ * This routine must preserve:
+ * r4, r7, r8
+ */
+ .align 5
+cache_on: mov r3, #8 @ cache_on function
+ b call_cache_fn
+
+/*
+ * Initialize the highest priority protection region, PR7
+ * to cover all 32bit address and cacheable and bufferable.
+ */
+__armv4_mpu_cache_on:
+ mov r0, #0x3f @ 4G, the whole
+ mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
+ mcr p15, 0, r0, c6, c7, 1
+
+ mov r0, #0x80 @ PR7
+ mcr p15, 0, r0, c2, c0, 0 @ D-cache on
+ mcr p15, 0, r0, c2, c0, 1 @ I-cache on
+ mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
+
+ mov r0, #0xc000
+ mcr p15, 0, r0, c5, c0, 1 @ I-access permission
+ mcr p15, 0, r0, c5, c0, 0 @ D-access permission
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
+ mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ @ ...I .... ..D. WC.M
+ orr r0, r0, #0x002d @ .... .... ..1. 11.1
+ orr r0, r0, #0x1000 @ ...1 .... .... ....
+
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache
+ mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache
+ mov pc, lr
+
+__armv3_mpu_cache_on:
+ mov r0, #0x3f @ 4G, the whole
+ mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting
+
+ mov r0, #0x80 @ PR7
+ mcr p15, 0, r0, c2, c0, 0 @ cache on
+ mcr p15, 0, r0, c3, c0, 0 @ write-buffer on
+
+ mov r0, #0xc000
+ mcr p15, 0, r0, c5, c0, 0 @ access permission
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ /*
+ * ?? ARMv3 MMU does not allow reading the control register,
+ * does this really work on ARMv3 MPU?
+ */
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ @ .... .... .... WC.M
+ orr r0, r0, #0x000d @ .... .... .... 11.1
+ /* ?? this overwrites the value constructed above? */
+ mov r0, #0
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+
+ /* ?? invalidate for the second time? */
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mov pc, lr
+
+__setup_mmu: sub r3, r4, #16384 @ Page directory size
+ bic r3, r3, #0xff @ Align the pointer
+ bic r3, r3, #0x3f00
+/*
+ * Initialise the page tables, turning on the cacheable and bufferable
+ * bits for the RAM area only.
+ */
+ mov r0, r3
+ mov r9, r0, lsr #18
+ mov r9, r9, lsl #18 @ start of RAM
+ add r10, r9, #0x10000000 @ a reasonable RAM size
+ mov r1, #0x12
+ orr r1, r1, #3 << 10
+ add r2, r3, #16384
+1: cmp r1, r9 @ if virt > start of RAM
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ orrhs r1, r1, #0x08 @ set cacheable
+#else
+ orrhs r1, r1, #0x0c @ set cacheable, bufferable
+#endif
+ cmp r1, r10 @ if virt > end of RAM
+ bichs r1, r1, #0x0c @ clear cacheable, bufferable
+ str r1, [r0], #4 @ 1:1 mapping
+ add r1, r1, #1048576
+ teq r0, r2
+ bne 1b
+/*
+ * If ever we are running from Flash, then we surely want the cache
+ * to be enabled also for our execution instance... We map 2MB of it
+ * so there is no map overlap problem for up to 1 MB compressed kernel.
+ * If the execution is in RAM then we would only be duplicating the above.
+ */
+ mov r1, #0x1e
+ orr r1, r1, #3 << 10
+ mov r2, pc
+ mov r2, r2, lsr #20
+ orr r1, r1, r2, lsl #20
+ add r0, r3, r2, lsl #2
+ str r1, [r0], #4
+ add r1, r1, #1048576
+ str r1, [r0]
+ mov pc, lr
+ENDPROC(__setup_mmu)
+
+__arm926ejs_mmu_cache_on:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #4 @ put dcache in WT mode
+ mcr p15, 7, r0, c15, c0, 0
+#endif
+
+__armv4_mmu_cache_on:
+ mov r12, lr
+#ifdef CONFIG_MMU
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
+ orr r0, r0, #0x0030
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ orr r0, r0, #1 << 25 @ big-endian page tables
+#endif
+ bl __common_mmu_cache_on
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
+#endif
+ mov pc, r12
+
+__armv7_mmu_cache_on:
+ mov r12, lr
+#ifdef CONFIG_MMU
+ mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
+ tst r11, #0xf @ VMSA
+ blne __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ tst r11, #0xf @ VMSA
+ mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
+#endif
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
+ orr r0, r0, #0x003c @ write buffer
+#ifdef CONFIG_MMU
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ orr r0, r0, #1 << 25 @ big-endian page tables
+#endif
+ orrne r0, r0, #1 @ MMU enabled
+ movne r1, #-1
+ mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
+ mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
+#endif
+ mcr p15, 0, r0, c1, c0, 0 @ load control register
+ mrc p15, 0, r0, c1, c0, 0 @ and read it back
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+ mov pc, r12
+
+__fa526_cache_on:
+ mov r12, lr
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ orr r0, r0, #0x1000 @ I-cache enable
+ bl __common_mmu_cache_on
+ mov r0, #0
+ mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
+ mov pc, r12
+
+__arm6_mmu_cache_on:
+ mov r12, lr
+ bl __setup_mmu
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
+ mov r0, #0x30
+ bl __common_mmu_cache_on
+ mov r0, #0
+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
+ mov pc, r12
+
+__common_mmu_cache_on:
+#ifndef CONFIG_THUMB2_KERNEL
+#ifndef DEBUG
+ orr r0, r0, #0x000d @ Write buffer, mmu
+#endif
+ mov r1, #-1
+ mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c3, c0, 0 @ load domain access control
+ b 1f
+ .align 5 @ cache line aligned
+1: mcr p15, 0, r0, c1, c0, 0 @ load control register
+ mrc p15, 0, r0, c1, c0, 0 @ and read it back to
+ sub pc, lr, r0, lsr #32 @ properly flush pipeline
+#endif
+
+#define PROC_ENTRY_SIZE (4*5)
+
+/*
+ * Here follow the relocatable cache support functions for the
+ * various processors. This is a generic hook for locating an
+ * entry and jumping to an instruction at the specified offset
+ * from the start of the block. Please note this is all position
+ * independent code.
+ *
+ * r1 = corrupted
+ * r2 = corrupted
+ * r3 = block offset
+ * r9 = corrupted
+ * r12 = corrupted
+ */
+
+call_cache_fn: adr r12, proc_types
+#ifdef CONFIG_CPU_CP15
+ mrc p15, 0, r9, c0, c0 @ get processor ID
+#else
+ ldr r9, =CONFIG_PROCESSOR_ID
+#endif
+1: ldr r1, [r12, #0] @ get value
+ ldr r2, [r12, #4] @ get mask
+ eor r1, r1, r9 @ (real ^ match)
+ tst r1, r2 @ & mask
+ ARM( addeq pc, r12, r3 ) @ call cache function
+ THUMB( addeq r12, r3 )
+ THUMB( moveq pc, r12 ) @ call cache function
+ add r12, r12, #PROC_ENTRY_SIZE
+ b 1b
+
+/*
+ * Table for cache operations. This is basically:
+ * - CPU ID match
+ * - CPU ID mask
+ * - 'cache on' method instruction
+ * - 'cache off' method instruction
+ * - 'cache flush' method instruction
+ *
+ * We match an entry using: ((real_id ^ match) & mask) == 0
+ *
+ * Writethrough caches generally only need 'on' and 'off'
+ * methods. Writeback caches _must_ have the flush method
+ * defined.
+ */
+ .align 2
+ .type proc_types,#object
+proc_types:
+ .word 0x41560600 @ ARM6/610
+ .word 0xffffffe0
+ W(b) __arm6_mmu_cache_off @ works, but slow
+ W(b) __arm6_mmu_cache_off
+ mov pc, lr
+ THUMB( nop )
+@ b __arm6_mmu_cache_on @ untested
+@ 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
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+#endif
+
+ .word 0x41007000 @ ARM7/710
+ .word 0xfff8fe00
+ W(b) __arm7_mmu_cache_off
+ W(b) __arm7_mmu_cache_off
+ mov pc, lr
+ THUMB( nop )
+
+ .word 0x41807200 @ ARM720T (writethrough)
+ .word 0xffffff00
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ mov pc, lr
+ THUMB( nop )
+
+ .word 0x41007400 @ ARM74x
+ .word 0xff00ff00
+ W(b) __armv3_mpu_cache_on
+ W(b) __armv3_mpu_cache_off
+ W(b) __armv3_mpu_cache_flush
+
+ .word 0x41009400 @ ARM94x
+ .word 0xff00ff00
+ W(b) __armv4_mpu_cache_on
+ W(b) __armv4_mpu_cache_off
+ W(b) __armv4_mpu_cache_flush
+
+ .word 0x41069260 @ ARM926EJ-S (v5TEJ)
+ .word 0xff0ffff0
+ W(b) __arm926ejs_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv5tej_mmu_cache_flush
+
+ .word 0x00007000 @ ARM7 IDs
+ .word 0x0000f000
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+
+ @ Everything from here on will be the new ID system.
+
+ .word 0x4401a100 @ sa110 / sa1100
+ .word 0xffffffe0
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
+ .word 0x6901b110 @ sa1110
+ .word 0xfffffff0
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
+ .word 0x56056900
+ .word 0xffffff00 @ PXA9xx
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
+ .word 0x56158000 @ PXA168
+ .word 0xfffff000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv5tej_mmu_cache_flush
+
+ .word 0x56050000 @ Feroceon
+ .word 0xff0f0000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv5tej_mmu_cache_flush
+
+#ifdef CONFIG_CPU_FEROCEON_OLD_ID
+ /* this conflicts with the standard ARMv5TE entry */
+ .long 0x41009260 @ Old Feroceon
+ .long 0xff00fff0
+ b __armv4_mmu_cache_on
+ b __armv4_mmu_cache_off
+ b __armv5tej_mmu_cache_flush
+#endif
+
+ .word 0x66015261 @ FA526
+ .word 0xff01fff1
+ W(b) __fa526_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __fa526_cache_flush
+
+ @ These match on the architecture ID
+
+ .word 0x00020000 @ ARMv4T
+ .word 0x000f0000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
+ .word 0x00050000 @ ARMv5TE
+ .word 0x000f0000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv4_mmu_cache_flush
+
+ .word 0x00060000 @ ARMv5TEJ
+ .word 0x000f0000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv5tej_mmu_cache_flush
+
+ .word 0x0007b000 @ ARMv6
+ .word 0x000ff000
+ W(b) __armv4_mmu_cache_on
+ W(b) __armv4_mmu_cache_off
+ W(b) __armv6_mmu_cache_flush
+
+ .word 0x000f0000 @ new CPU Id
+ .word 0x000f0000
+ W(b) __armv7_mmu_cache_on
+ W(b) __armv7_mmu_cache_off
+ W(b) __armv7_mmu_cache_flush
+
+ .word 0 @ unrecognised type
+ .word 0
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+ mov pc, lr
+ THUMB( nop )
+
+ .size proc_types, . - proc_types
+
+ /*
+ * If you get a "non-constant expression in ".if" statement"
+ * error from the assembler on this line, check that you have
+ * not accidentally written a "b" instruction where you should
+ * have written W(b).
+ */
+ .if (. - proc_types) % PROC_ENTRY_SIZE != 0
+ .error "The size of one or more proc_types entries is wrong."
+ .endif
+
+/*
+ * Turn off the Cache and MMU. ARMv3 does not support
+ * reading the control register, but ARMv4 does.
+ *
+ * On exit,
+ * r0, r1, r2, r3, r9, r12 corrupted
+ * This routine must preserve:
+ * r4, r7, r8
+ */
+ .align 5
+cache_off: mov r3, #12 @ cache_off function
+ b call_cache_fn
+
+__armv4_mpu_cache_off:
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0 @ turn MPU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache
+ mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache
+ mov pc, lr
+
+__armv3_mpu_cache_off:
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mov pc, lr
+
+__armv4_mmu_cache_off:
+#ifdef CONFIG_MMU
+ mrc p15, 0, r0, c1, c0
+ bic r0, r0, #0x000d
+ mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4
+ mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4
+#endif
+ mov pc, lr
+
+__armv7_mmu_cache_off:
+ mrc p15, 0, r0, c1, c0
+#ifdef CONFIG_MMU
+ bic r0, r0, #0x000d
+#else
+ bic r0, r0, #0x000c
+#endif
+ mcr p15, 0, r0, c1, c0 @ turn MMU and cache off
+ mov r12, lr
+ bl __armv7_mmu_cache_flush
+ mov r0, #0
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB
+#endif
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC
+ mcr p15, 0, r0, c7, c10, 4 @ DSB
+ mcr p15, 0, r0, c7, c5, 4 @ ISB
+ mov pc, r12
+
+__arm6_mmu_cache_off:
+ mov r0, #0x00000030 @ ARM6 control reg.
+ b __armv3_mmu_cache_off
+
+__arm7_mmu_cache_off:
+ mov r0, #0x00000070 @ ARM7 control reg.
+ b __armv3_mmu_cache_off
+
+__armv3_mmu_cache_off:
+ mcr p15, 0, r0, c1, c0, 0 @ turn MMU and cache off
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
+ mov pc, lr
+
+/*
+ * Clean and flush the cache to maintain consistency.
+ *
+ * On exit,
+ * r1, r2, r3, r9, r10, r11, r12 corrupted
+ * This routine must preserve:
+ * r4, r6, r7, r8
+ */
+ .align 5
+cache_clean_flush:
+ mov r3, #16
+ b call_cache_fn
+
+__armv4_mpu_cache_flush:
+ mov r2, #1
+ mov r3, #0
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+ mov r1, #7 << 5 @ 8 segments
+1: orr r3, r1, #63 << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+
+ teq r2, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__fa526_cache_flush:
+ mov r1, #0
+ mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
+ mcr p15, 0, r1, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__armv6_mmu_cache_flush:
+ mov r1, #0
+ mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB
+ mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__armv7_mmu_cache_flush:
+ mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1
+ tst r10, #0xf << 16 @ hierarchical cache (ARMv7)
+ mov r10, #0
+ beq hierarchical
+ mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D
+ b iflush
+hierarchical:
+ mcr p15, 0, r10, c7, c10, 5 @ DMB
+ stmfd sp!, {r0-r7, r9-r11}
+ 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 finished @ 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
+ mcr p15, 0, r10, c7, c5, 4 @ 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
+ ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
+ THUMB( lsl r6, r9, r5 )
+ THUMB( orr r11, r10, r6 ) @ factor way and cache 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:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt loop1
+finished:
+ ldmfd sp!, {r0-r7, r9-r11}
+ mov r10, #0 @ swith back to cache level 0
+ mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
+iflush:
+ mcr p15, 0, r10, c7, c10, 4 @ DSB
+ mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB
+ mcr p15, 0, r10, c7, c10, 4 @ DSB
+ mcr p15, 0, r10, c7, c5, 4 @ ISB
+ mov pc, lr
+
+__armv5tej_mmu_cache_flush:
+1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache
+ bne 1b
+ mcr p15, 0, r0, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__armv4_mmu_cache_flush:
+ mov r2, #64*1024 @ default: 32K dcache size (*2)
+ mov r11, #32 @ default: 32 byte line size
+ mrc p15, 0, r3, c0, c0, 1 @ read cache type
+ teq r3, r9 @ cache ID register present?
+ beq no_cache_id
+ mov r1, r3, lsr #18
+ and r1, r1, #7
+ mov r2, #1024
+ mov r2, r2, lsl r1 @ base dcache size *2
+ tst r3, #1 << 14 @ test M bit
+ addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1
+ mov r3, r3, lsr #12
+ and r3, r3, #3
+ mov r11, #8
+ mov r11, r11, lsl r3 @ cache line size in bytes
+no_cache_id:
+ mov r1, pc
+ bic r1, r1, #63 @ align to longest cache line
+ add r2, r1, r2
+1:
+ ARM( ldr r3, [r1], r11 ) @ s/w flush D cache
+ THUMB( ldr r3, [r1] ) @ s/w flush D cache
+ THUMB( add r1, r1, r11 )
+ teq r1, r2
+ bne 1b
+
+ mcr p15, 0, r1, c7, c5, 0 @ flush I cache
+ mcr p15, 0, r1, c7, c6, 0 @ flush D cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+__armv3_mmu_cache_flush:
+__armv3_mpu_cache_flush:
+ mov r1, #0
+ mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3
+ mov pc, lr
+
+/*
+ * Various debugging routines for printing hex characters and
+ * memory, which again must be relocatable.
+ */
+#ifdef DEBUG
+ .align 2
+ .type phexbuf,#object
+phexbuf: .space 12
+ .size phexbuf, . - phexbuf
+
+@ phex corrupts {r0, r1, r2, r3}
+phex: adr r3, phexbuf
+ mov r2, #0
+ strb r2, [r3, r1]
+1: subs r1, r1, #1
+ movmi r0, r3
+ bmi puts
+ and r2, r0, #15
+ mov r0, r0, lsr #4
+ cmp r2, #10
+ addge r2, r2, #7
+ add r2, r2, #'0'
+ strb r2, [r3, r1]
+ b 1b
+
+@ puts corrupts {r0, r1, r2, r3}
+puts: loadsp r3, r1
+1: ldrb r2, [r0], #1
+ teq r2, #0
+ moveq pc, lr
+2: writeb r2, r3
+ mov r1, #0x00020000
+3: subs r1, r1, #1
+ bne 3b
+ teq r2, #'\n'
+ moveq r2, #'\r'
+ beq 2b
+ teq r0, #0
+ bne 1b
+ mov pc, lr
+@ putc corrupts {r0, r1, r2, r3}
+putc:
+ mov r2, r0
+ mov r0, #0
+ loadsp r3, r1
+ b 2b
+
+@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr}
+memdump: mov r12, r0
+ mov r10, lr
+ mov r11, #0
+2: mov r0, r11, lsl #2
+ add r0, r0, r12
+ mov r1, #8
+ bl phex
+ mov r0, #':'
+ bl putc
+1: mov r0, #' '
+ bl putc
+ ldr r0, [r12, r11, lsl #2]
+ mov r1, #8
+ bl phex
+ and r0, r11, #7
+ teq r0, #3
+ moveq r0, #' '
+ bleq putc
+ and r0, r11, #7
+ add r11, r11, #1
+ teq r0, #7
+ bne 1b
+ mov r0, #'\n'
+ bl putc
+ cmp r11, #64
+ blt 2b
+ mov pc, r10
+#endif
+
+ .ltorg
+reloc_code_end:
+
+ .align
+ .section ".stack", "aw", %nobits
+.L_user_stack: .space 4096
+.L_user_stack_end:
diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S
new file mode 100644
index 00000000..8517c860
--- /dev/null
+++ b/arch/arm/boot/compressed/ll_char_wr.S
@@ -0,0 +1,134 @@
+/*
+ * linux/arch/arm/lib/ll_char_wr.S
+ *
+ * Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
+ *
+ * 10-04-96 RMK Various cleanups & reduced register usage.
+ * 08-04-98 RMK Shifts re-ordered
+ */
+
+@ Regs: [] = corruptible
+@ {} = used
+@ () = do not use
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+LC0: .word LC0
+ .word bytes_per_char_h
+ .word video_size_row
+ .word acorndata_8x8
+ .word con_charconvtable
+
+/*
+ * r0 = ptr
+ * r1 = char
+ * r2 = white
+ */
+ENTRY(ll_write_char)
+ stmfd sp!, {r4 - r7, lr}
+@
+@ Smashable regs: {r0 - r3}, [r4 - r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+ /*
+ * calculate offset into character table
+ */
+ mov r1, r1, lsl #3
+ /*
+ * calculate offset required for each row.
+ */
+ adr ip, LC0
+ ldmia ip, {r3, r4, r5, r6, lr}
+ sub ip, ip, r3
+ add r6, r6, ip
+ add lr, lr, ip
+ ldr r4, [r4, ip]
+ ldr r5, [r5, ip]
+ /*
+ * Go to resolution-dependent routine...
+ */
+ cmp r4, #4
+ blt Lrow1bpp
+ add r0, r0, r5, lsl #3 @ Move to bottom of character
+ orr r1, r1, #7
+ ldrb r7, [r6, r1]
+ teq r4, #8
+ beq Lrow8bpplp
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+Lrow4bpplp:
+ ldr r7, [lr, r7, lsl #2]
+ mul r7, r2, r7
+ sub r1, r1, #1 @ avoid using r7 directly after
+ str r7, [r0, -r5]!
+ ldrb r7, [r6, r1]
+ ldr r7, [lr, r7, lsl #2]
+ mul r7, r2, r7
+ tst r1, #7 @ avoid using r7 directly after
+ str r7, [r0, -r5]!
+ subne r1, r1, #1
+ ldrneb r7, [r6, r1]
+ bne Lrow4bpplp
+ ldmfd sp!, {r4 - r7, pc}
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5 - r7}, (r8 - fp), [ip], (sp), {lr}, (pc)
+@
+Lrow8bpplp:
+ mov ip, r7, lsr #4
+ ldr ip, [lr, ip, lsl #2]
+ mul r4, r2, ip
+ and ip, r7, #15 @ avoid r4
+ ldr ip, [lr, ip, lsl #2] @ avoid r4
+ mul ip, r2, ip @ avoid r4
+ sub r1, r1, #1 @ avoid ip
+ sub r0, r0, r5 @ avoid ip
+ stmia r0, {r4, ip}
+ ldrb r7, [r6, r1]
+ mov ip, r7, lsr #4
+ ldr ip, [lr, ip, lsl #2]
+ mul r4, r2, ip
+ and ip, r7, #15 @ avoid r4
+ ldr ip, [lr, ip, lsl #2] @ avoid r4
+ mul ip, r2, ip @ avoid r4
+ tst r1, #7 @ avoid ip
+ sub r0, r0, r5 @ avoid ip
+ stmia r0, {r4, ip}
+ subne r1, r1, #1
+ ldrneb r7, [r6, r1]
+ bne Lrow8bpplp
+ ldmfd sp!, {r4 - r7, pc}
+
+@
+@ Smashable regs: {r0 - r3}, [r4], {r5, r6}, [r7], (r8 - fp), [ip], (sp), [lr], (pc)
+@
+Lrow1bpp:
+ add r6, r6, r1
+ ldmia r6, {r4, r7}
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ mov r4, r4, lsr #8
+ strb r4, [r0], r5
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ strb r7, [r0], r5
+ mov r7, r7, lsr #8
+ strb r7, [r0], r5
+ ldmfd sp!, {r4 - r7, pc}
+
+ .bss
+ENTRY(con_charconvtable)
+ .space 1024
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
new file mode 100644
index 00000000..832d3723
--- /dev/null
+++ b/arch/arm/boot/compressed/misc.c
@@ -0,0 +1,194 @@
+/*
+ * misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ *
+ * Modified for ARM Linux by Russell King
+ *
+ * Nicolas Pitre <nico@visuaide.com> 1999/04/14 :
+ * For this code to run directly from Flash, all constant variables must
+ * be marked with 'const' and all other variables initialized at run-time
+ * only. This way all non constant variables will end up in the bss segment,
+ * which should point to addresses in RAM and cleared to 0 on start.
+ * This allows for a much quicker boot time.
+ */
+
+unsigned int __machine_arch_type;
+
+#define _LINUX_STRING_H_
+
+#include <linux/compiler.h> /* for inline */
+#include <linux/types.h> /* for size_t */
+#include <linux/stddef.h> /* for NULL */
+#include <linux/linkage.h>
+#include <asm/string.h>
+
+
+static void putstr(const char *ptr);
+extern void error(char *x);
+
+#include <mach/uncompress.h>
+
+#ifdef CONFIG_DEBUG_ICEDCC
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
+
+static void icedcc_putc(int ch)
+{
+ int status, i = 0x4000000;
+
+ do {
+ if (--i < 0)
+ return;
+
+ asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status));
+ } while (status & (1 << 29));
+
+ asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
+}
+
+
+#elif defined(CONFIG_CPU_XSCALE)
+
+static void icedcc_putc(int ch)
+{
+ int status, i = 0x4000000;
+
+ do {
+ if (--i < 0)
+ return;
+
+ asm volatile ("mrc p14, 0, %0, c14, c0, 0" : "=r" (status));
+ } while (status & (1 << 28));
+
+ asm("mcr p14, 0, %0, c8, c0, 0" : : "r" (ch));
+}
+
+#else
+
+static void icedcc_putc(int ch)
+{
+ int status, i = 0x4000000;
+
+ do {
+ if (--i < 0)
+ return;
+
+ asm volatile ("mrc p14, 0, %0, c0, c0, 0" : "=r" (status));
+ } while (status & 2);
+
+ asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch));
+}
+
+#endif
+
+#define putc(ch) icedcc_putc(ch)
+#endif
+
+static void putstr(const char *ptr)
+{
+ char c;
+
+ while ((c = *ptr++) != '\0') {
+ if (c == '\n')
+ putc('\r');
+ putc(c);
+ }
+
+ flush();
+}
+
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+ int i = 0;
+ unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
+
+ for (i = __n >> 3; i > 0; i--) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 2) {
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1 << 1) {
+ *d++ = *s++;
+ *d++ = *s++;
+ }
+
+ if (__n & 1)
+ *d++ = *s++;
+
+ return __dest;
+}
+
+/*
+ * gzip declarations
+ */
+extern char input_data[];
+extern char input_data_end[];
+
+unsigned char *output_data;
+
+unsigned long free_mem_ptr;
+unsigned long free_mem_end_ptr;
+
+#ifndef arch_error
+#define arch_error(x)
+#endif
+
+void error(char *x)
+{
+ arch_error(x);
+
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System halted");
+
+ while(1); /* Halt */
+}
+
+asmlinkage void __div0(void)
+{
+ error("Attempting division by 0!");
+}
+
+extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
+
+
+void
+decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
+ unsigned long free_mem_ptr_end_p,
+ int arch_id)
+{
+ int ret;
+
+ output_data = (unsigned char *)output_start;
+ free_mem_ptr = free_mem_ptr_p;
+ free_mem_end_ptr = free_mem_ptr_end_p;
+ __machine_arch_type = arch_id;
+
+ arch_decomp_setup();
+
+ putstr("Uncompressing Linux...");
+ ret = do_decompress(input_data, input_data_end - input_data,
+ output_data, error);
+ if (ret)
+ error("decompressor returned an error");
+ else
+ putstr(" done, booting the kernel.\n");
+}
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 00000000..7453c833
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,88 @@
+/*
+ * sh7372 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/boot.h>
+#include <mach/mmc.h>
+
+#define MMCIF_BASE (void __iomem *)0xe6bd0000
+
+#define PORT84CR (void __iomem *)0xe6050054
+#define PORT85CR (void __iomem *)0xe6050055
+#define PORT86CR (void __iomem *)0xe6050056
+#define PORT87CR (void __iomem *)0xe6050057
+#define PORT88CR (void __iomem *)0xe6050058
+#define PORT89CR (void __iomem *)0xe6050059
+#define PORT90CR (void __iomem *)0xe605005a
+#define PORT91CR (void __iomem *)0xe605005b
+#define PORT92CR (void __iomem *)0xe605005c
+#define PORT99CR (void __iomem *)0xe6050063
+
+#define SMSTPCR3 (void __iomem *)0xe615013c
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the zImage from an MMC card starting from block 1.
+ *
+ * The image must be start with a vrl4 header and
+ * the zImage must start at offset 512 of the image. That is,
+ * at block 2 (=byte 1024) on the media
+ *
+ * Use the following line to write the vrl4 formated zImage
+ * to an MMC card
+ * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
+{
+ mmc_init_progress();
+ mmc_update_progress(MMC_PROGRESS_ENTER);
+
+ /* Initialise MMC
+ * registers: PORT84CR-PORT92CR
+ * (MMCD0_0-MMCD0_7,MMCCMD0 Control)
+ * value: 0x04 - select function 4
+ */
+ __raw_writeb(0x04, PORT84CR);
+ __raw_writeb(0x04, PORT85CR);
+ __raw_writeb(0x04, PORT86CR);
+ __raw_writeb(0x04, PORT87CR);
+ __raw_writeb(0x04, PORT88CR);
+ __raw_writeb(0x04, PORT89CR);
+ __raw_writeb(0x04, PORT90CR);
+ __raw_writeb(0x04, PORT91CR);
+ __raw_writeb(0x04, PORT92CR);
+
+ /* Initialise MMC
+ * registers: PORT99CR (MMCCLK0 Control)
+ * value: 0x10 | 0x04 - enable output | select function 4
+ */
+ __raw_writeb(0x14, PORT99CR);
+
+ /* Enable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
+
+ mmc_update_progress(MMC_PROGRESS_INIT);
+
+ /* setup MMCIF hardware */
+ sh_mmcif_boot_init(MMCIF_BASE);
+
+ mmc_update_progress(MMC_PROGRESS_LOAD);
+
+ /* load kernel via MMCIF interface */
+ sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is at block 2 */
+ (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
+
+
+ /* Disable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+ mmc_update_progress(MMC_PROGRESS_DONE);
+}
diff --git a/arch/arm/boot/compressed/ofw-shark.c b/arch/arm/boot/compressed/ofw-shark.c
new file mode 100644
index 00000000..465c54b6
--- /dev/null
+++ b/arch/arm/boot/compressed/ofw-shark.c
@@ -0,0 +1,260 @@
+/*
+ * linux/arch/arm/boot/compressed/ofw-shark.c
+ *
+ * by Alexander Schulz
+ *
+ * This file is used to get some basic information
+ * about the memory layout of the shark we are running
+ * on. Memory is usually divided in blocks a 8 MB.
+ * And bootargs are copied from OpenFirmware.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+
+asmlinkage void
+create_params (unsigned long *buffer)
+{
+ /* Is there a better address? Also change in mach-shark/core.c */
+ struct tag *tag = (struct tag *) 0x08003000;
+ int j,i,m,k,nr_banks,size;
+ unsigned char *c;
+
+ k = 0;
+
+ /* Head of the taglist */
+ tag->hdr.tag = ATAG_CORE;
+ tag->hdr.size = tag_size(tag_core);
+ tag->u.core.flags = 1;
+ tag->u.core.pagesize = PAGE_SIZE;
+ tag->u.core.rootdev = 0;
+
+ /* Build up one tagged block for each memory region */
+ size=0;
+ nr_banks=(unsigned int) buffer[0];
+ for (j=0;j<nr_banks;j++){
+ /* search the lowest address and put it into the next entry */
+ /* not a fast sort algorithm, but there are at most 8 entries */
+ /* and this is used only once anyway */
+ m=0xffffffff;
+ for (i=0;i<(unsigned int) buffer[0];i++){
+ if (buffer[2*i+1]<m) {
+ m=buffer[2*i+1];
+ k=i;
+ }
+ }
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_MEM;
+ tag->hdr.size = tag_size(tag_mem32);
+ tag->u.mem.size = buffer[2*k+2];
+ tag->u.mem.start = buffer[2*k+1];
+
+ size += buffer[2*k+2];
+
+ buffer[2*k+1]=0xffffffff; /* mark as copied */
+ }
+
+ /* The command line */
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_CMDLINE;
+
+ c=(unsigned char *)(&buffer[34]);
+ j=0;
+ while (*c) tag->u.cmdline.cmdline[j++]=*c++;
+
+ tag->u.cmdline.cmdline[j]=0;
+ tag->hdr.size = (j + 7 + sizeof(struct tag_header)) >> 2;
+
+ /* Hardware revision */
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_REVISION;
+ tag->hdr.size = tag_size(tag_revision);
+ tag->u.revision.rev = ((unsigned char) buffer[33])-'0';
+
+ /* End of the taglist */
+ tag = tag_next(tag);
+ tag->hdr.tag = 0;
+ tag->hdr.size = 0;
+}
+
+
+typedef int (*ofw_handle_t)(void *);
+
+/* Everything below is called with a wrong MMU setting.
+ * This means: no string constants, no initialization of
+ * arrays, no global variables! This is ugly but I didn't
+ * want to write this in assembler :-)
+ */
+
+int
+of_decode_int(const unsigned char *p)
+{
+ unsigned int i = *p++ << 8;
+ i = (i + *p++) << 8;
+ i = (i + *p++) << 8;
+ return (i + *p);
+}
+
+int
+OF_finddevice(ofw_handle_t openfirmware, char *name)
+{
+ unsigned int args[8];
+ char service[12];
+
+ service[0]='f';
+ service[1]='i';
+ service[2]='n';
+ service[3]='d';
+ service[4]='d';
+ service[5]='e';
+ service[6]='v';
+ service[7]='i';
+ service[8]='c';
+ service[9]='e';
+ service[10]='\0';
+
+ args[0]=(unsigned int)service;
+ args[1]=1;
+ args[2]=1;
+ args[3]=(unsigned int)name;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[4];
+}
+
+int
+OF_getproplen(ofw_handle_t openfirmware, int handle, char *prop)
+{
+ unsigned int args[8];
+ char service[12];
+
+ service[0]='g';
+ service[1]='e';
+ service[2]='t';
+ service[3]='p';
+ service[4]='r';
+ service[5]='o';
+ service[6]='p';
+ service[7]='l';
+ service[8]='e';
+ service[9]='n';
+ service[10]='\0';
+
+ args[0] = (unsigned int)service;
+ args[1] = 2;
+ args[2] = 1;
+ args[3] = (unsigned int)handle;
+ args[4] = (unsigned int)prop;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[5];
+}
+
+int
+OF_getprop(ofw_handle_t openfirmware, int handle, char *prop, void *buf, unsigned int buflen)
+{
+ unsigned int args[8];
+ char service[8];
+
+ service[0]='g';
+ service[1]='e';
+ service[2]='t';
+ service[3]='p';
+ service[4]='r';
+ service[5]='o';
+ service[6]='p';
+ service[7]='\0';
+
+ args[0] = (unsigned int)service;
+ args[1] = 4;
+ args[2] = 1;
+ args[3] = (unsigned int)handle;
+ args[4] = (unsigned int)prop;
+ args[5] = (unsigned int)buf;
+ args[6] = buflen;
+
+ if (openfirmware(args) == -1)
+ return -1;
+ return args[7];
+}
+
+asmlinkage void ofw_init(ofw_handle_t o, int *nomr, int *pointer)
+{
+ int phandle,i,mem_len,buffer[32];
+ char temp[15];
+
+ temp[0]='/';
+ temp[1]='m';
+ temp[2]='e';
+ temp[3]='m';
+ temp[4]='o';
+ temp[5]='r';
+ temp[6]='y';
+ temp[7]='\0';
+
+ phandle=OF_finddevice(o,temp);
+
+ temp[0]='r';
+ temp[1]='e';
+ temp[2]='g';
+ temp[3]='\0';
+
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ *nomr=mem_len >> 3;
+
+ for (i=0; i<=mem_len/4; i++) pointer[i]=of_decode_int((const unsigned char *)&buffer[i]);
+
+ temp[0]='/';
+ temp[1]='c';
+ temp[2]='h';
+ temp[3]='o';
+ temp[4]='s';
+ temp[5]='e';
+ temp[6]='n';
+ temp[7]='\0';
+
+ phandle=OF_finddevice(o,temp);
+
+ temp[0]='b';
+ temp[1]='o';
+ temp[2]='o';
+ temp[3]='t';
+ temp[4]='a';
+ temp[5]='r';
+ temp[6]='g';
+ temp[7]='s';
+ temp[8]='\0';
+
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ if (mem_len > 128) mem_len=128;
+ for (i=0; i<=mem_len/4; i++) pointer[i+33]=buffer[i];
+ pointer[i+33]=0;
+
+ temp[0]='/';
+ temp[1]='\0';
+ phandle=OF_finddevice(o,temp);
+ temp[0]='b';
+ temp[1]='a';
+ temp[2]='n';
+ temp[3]='n';
+ temp[4]='e';
+ temp[5]='r';
+ temp[6]='-';
+ temp[7]='n';
+ temp[8]='a';
+ temp[9]='m';
+ temp[10]='e';
+ temp[11]='\0';
+ mem_len = OF_getproplen(o,phandle, temp);
+ OF_getprop(o,phandle, temp, buffer, mem_len);
+ * ((unsigned char *) &pointer[32]) = ((unsigned char *) buffer)[mem_len-2];
+}
diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S
new file mode 100644
index 00000000..a68adf91
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.gzip.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy.gzip"
+ .globl input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S
new file mode 100644
index 00000000..d7e69cff
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.lzma.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy.lzma"
+ .globl input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/piggy.lzo.S b/arch/arm/boot/compressed/piggy.lzo.S
new file mode 100644
index 00000000..a425ad95
--- /dev/null
+++ b/arch/arm/boot/compressed/piggy.lzo.S
@@ -0,0 +1,6 @@
+ .section .piggydata,#alloc
+ .globl input_data
+input_data:
+ .incbin "arch/arm/boot/compressed/piggy.lzo"
+ .globl input_data_end
+input_data_end:
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
new file mode 100644
index 00000000..ea80abe7
--- /dev/null
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/boot/compressed/vmlinux.lds.in
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ /DISCARD/ : {
+ *(.ARM.exidx*)
+ *(.ARM.extab*)
+ /*
+ * Discard any r/w data - this produces a link error if we have any,
+ * which is required for PIC decompression. Local data generates
+ * GOTOFF relocations, which prevents it being relocated independently
+ * of the text/got segments.
+ */
+ *(.data)
+ }
+
+ . = TEXT_START;
+ _text = .;
+
+ .text : {
+ _start = .;
+ *(.start)
+ *(.text)
+ *(.text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.piggydata)
+ . = ALIGN(4);
+ }
+
+ _etext = .;
+
+ _got_start = .;
+ .got : { *(.got) }
+ _got_end = .;
+ .got.plt : { *(.got.plt) }
+ _edata = .;
+
+ . = BSS_START;
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+
+ . = ALIGN(8); /* the stack must be 64-bit aligned */
+ .stack : { *(.stack) }
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
+
diff --git a/arch/arm/boot/install.sh b/arch/arm/boot/install.sh
new file mode 100644
index 00000000..06ea7d42
--- /dev/null
+++ b/arch/arm/boot/install.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+#
+# arch/arm/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Russell King
+#
+# "make install" script for arm architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+# User may have a custom install script
+if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi
+if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi
+
+if [ "$(basename $2)" = "zImage" ]; then
+# Compressed install
+ echo "Installing compressed kernel"
+ base=vmlinuz
+else
+# Normal install
+ echo "Installing normal kernel"
+ base=vmlinux
+fi
+
+if [ -f $4/$base-$1 ]; then
+ mv $4/$base-$1 $4/$base-$1.old
+fi
+cat $2 > $4/$base-$1
+
+# Install system map file
+if [ -f $4/System.map-$1 ]; then
+ mv $4/System.map-$1 $4/System.map-$1.old
+fi
+cp $3 $4/System.map-$1
+
+if [ -x /sbin/loadmap ]; then
+ /sbin/loadmap
+else
+ echo "You have to install it yourself"
+fi
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
new file mode 100644
index 00000000..63825660
--- /dev/null
+++ b/arch/arm/common/Kconfig
@@ -0,0 +1,91 @@
+config ARM_GIC
+ bool
+
+config ARM_VIC
+ bool
+
+config ARM_VIC_NR
+ int
+ default 4 if ARCH_S5PV210
+ default 3 if ARCH_S5PC100
+ default 2
+ depends on ARM_VIC
+ help
+ The maximum number of VICs available in the system, for
+ power management.
+
+config ICST
+ bool
+
+config PL330
+ bool
+
+config SA1111
+ bool
+ select DMABOUNCE if !ARCH_PXA
+
+config DMABOUNCE
+ bool
+ select ZONE_DMA
+
+config TIMER_ACORN
+ bool
+
+config SHARP_LOCOMO
+ bool
+
+config SHARP_PARAM
+ bool
+
+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
new file mode 100644
index 00000000..3ab5d765
--- /dev/null
+++ b/arch/arm/common/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-$(CONFIG_ARM_GIC) += gic.o
+obj-$(CONFIG_ARM_VIC) += vic.o
+obj-$(CONFIG_ICST) += icst.o
+obj-$(CONFIG_PL330) += pl330.o
+obj-$(CONFIG_SA1111) += sa1111.o
+obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
+obj-$(CONFIG_DMABOUNCE) += dmabounce.o
+obj-$(CONFIG_TIMER_ACORN) += time-acorn.o
+obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
+obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
+obj-$(CONFIG_SHARP_SCOOP) += scoop.o
+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/dmabounce.c b/arch/arm/common/dmabounce.c
new file mode 100644
index 00000000..841df7d2
--- /dev/null
+++ b/arch/arm/common/dmabounce.c
@@ -0,0 +1,559 @@
+/*
+ * arch/arm/common/dmabounce.c
+ *
+ * Special dma_{map/unmap/dma_sync}_* routines for systems that have
+ * limited DMA windows. These functions utilize bounce buffers to
+ * copy data to/from buffers located outside the DMA region. This
+ * only works for systems in which DMA memory is at the bottom of
+ * RAM, the remainder of memory is at the top and the DMA memory
+ * can be marked as ZONE_DMA. Anything beyond that such as discontiguous
+ * DMA windows will require custom implementations that reserve memory
+ * areas at early bootup.
+ *
+ * Original version by Brad Parker (brad@heeltoe.com)
+ * Re-written by Christopher Hoover <ch@murgatroid.com>
+ * Made generic by Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Hewlett Packard Company.
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/page-flags.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/list.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cacheflush.h>
+
+#undef STATS
+
+#ifdef STATS
+#define DO_STATS(X) do { X ; } while (0)
+#else
+#define DO_STATS(X) do { } while (0)
+#endif
+
+/* ************************************************** */
+
+struct safe_buffer {
+ struct list_head node;
+
+ /* original request */
+ void *ptr;
+ size_t size;
+ int direction;
+
+ /* safe buffer info */
+ struct dmabounce_pool *pool;
+ void *safe;
+ dma_addr_t safe_dma_addr;
+};
+
+struct dmabounce_pool {
+ unsigned long size;
+ struct dma_pool *pool;
+#ifdef STATS
+ unsigned long allocs;
+#endif
+};
+
+struct dmabounce_device_info {
+ struct device *dev;
+ struct list_head safe_buffers;
+#ifdef STATS
+ unsigned long total_allocs;
+ unsigned long map_op_count;
+ unsigned long bounce_count;
+ int attr_res;
+#endif
+ struct dmabounce_pool small;
+ struct dmabounce_pool large;
+
+ rwlock_t lock;
+};
+
+#ifdef STATS
+static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+ return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
+ device_info->small.allocs,
+ device_info->large.allocs,
+ device_info->total_allocs - device_info->small.allocs -
+ device_info->large.allocs,
+ device_info->total_allocs,
+ device_info->map_op_count,
+ device_info->bounce_count);
+}
+
+static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
+#endif
+
+
+/* allocate a 'safe' buffer and keep track of it */
+static inline struct safe_buffer *
+alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
+ size_t size, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf;
+ struct dmabounce_pool *pool;
+ struct device *dev = device_info->dev;
+ unsigned long flags;
+
+ dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
+ __func__, ptr, size, dir);
+
+ if (size <= device_info->small.size) {
+ pool = &device_info->small;
+ } else if (size <= device_info->large.size) {
+ pool = &device_info->large;
+ } else {
+ pool = NULL;
+ }
+
+ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
+ if (buf == NULL) {
+ dev_warn(dev, "%s: kmalloc failed\n", __func__);
+ return NULL;
+ }
+
+ buf->ptr = ptr;
+ buf->size = size;
+ buf->direction = dir;
+ buf->pool = pool;
+
+ if (pool) {
+ buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
+ &buf->safe_dma_addr);
+ } else {
+ buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
+ GFP_ATOMIC);
+ }
+
+ if (buf->safe == NULL) {
+ dev_warn(dev,
+ "%s: could not alloc dma memory (size=%d)\n",
+ __func__, size);
+ kfree(buf);
+ return NULL;
+ }
+
+#ifdef STATS
+ if (pool)
+ pool->allocs++;
+ device_info->total_allocs++;
+#endif
+
+ write_lock_irqsave(&device_info->lock, flags);
+ list_add(&buf->node, &device_info->safe_buffers);
+ write_unlock_irqrestore(&device_info->lock, flags);
+
+ return buf;
+}
+
+/* determine if a buffer is from our "safe" pool */
+static inline struct safe_buffer *
+find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
+{
+ struct safe_buffer *b, *rb = NULL;
+ unsigned long flags;
+
+ read_lock_irqsave(&device_info->lock, flags);
+
+ list_for_each_entry(b, &device_info->safe_buffers, node)
+ if (b->safe_dma_addr == safe_dma_addr) {
+ rb = b;
+ break;
+ }
+
+ read_unlock_irqrestore(&device_info->lock, flags);
+ return rb;
+}
+
+static inline void
+free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf)
+{
+ unsigned long flags;
+
+ dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf);
+
+ write_lock_irqsave(&device_info->lock, flags);
+
+ list_del(&buf->node);
+
+ write_unlock_irqrestore(&device_info->lock, flags);
+
+ if (buf->pool)
+ dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
+ else
+ dma_free_coherent(device_info->dev, buf->size, buf->safe,
+ buf->safe_dma_addr);
+
+ kfree(buf);
+}
+
+/* ************************************************** */
+
+static struct safe_buffer *find_safe_buffer_dev(struct device *dev,
+ dma_addr_t dma_addr, const char *where)
+{
+ if (!dev || !dev->archdata.dmabounce)
+ return NULL;
+ if (dma_mapping_error(dev, dma_addr)) {
+ if (dev)
+ dev_err(dev, "Trying to %s invalid mapping\n", where);
+ else
+ pr_err("unknown device: Trying to %s invalid mapping\n", where);
+ return NULL;
+ }
+ return find_safe_buffer(dev->archdata.dmabounce, dma_addr);
+}
+
+static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction dir)
+{
+ struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+ dma_addr_t dma_addr;
+ int needs_bounce = 0;
+
+ if (device_info)
+ DO_STATS ( device_info->map_op_count++ );
+
+ dma_addr = virt_to_dma(dev, ptr);
+
+ if (dev->dma_mask) {
+ unsigned long mask = *dev->dma_mask;
+ unsigned long limit;
+
+ limit = (mask + 1) & ~mask;
+ if (limit && size > limit) {
+ dev_err(dev, "DMA mapping too big (requested %#x "
+ "mask %#Lx)\n", size, *dev->dma_mask);
+ return ~0;
+ }
+
+ /*
+ * Figure out if we need to bounce from the DMA mask.
+ */
+ needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask;
+ }
+
+ if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) {
+ struct safe_buffer *buf;
+
+ buf = alloc_safe_buffer(device_info, ptr, size, dir);
+ if (buf == 0) {
+ dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
+ __func__, ptr);
+ return ~0;
+ }
+
+ dev_dbg(dev,
+ "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
+
+ if ((dir == DMA_TO_DEVICE) ||
+ (dir == DMA_BIDIRECTIONAL)) {
+ dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n",
+ __func__, ptr, buf->safe, size);
+ memcpy(buf->safe, ptr, size);
+ }
+ ptr = buf->safe;
+
+ dma_addr = buf->safe_dma_addr;
+ } else {
+ /*
+ * We don't need to sync the DMA buffer since
+ * it was allocated via the coherent allocators.
+ */
+ __dma_single_cpu_to_dev(ptr, size, dir);
+ }
+
+ return dma_addr;
+}
+
+static inline void unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap");
+
+ if (buf) {
+ BUG_ON(buf->size != size);
+ BUG_ON(buf->direction != dir);
+
+ dev_dbg(dev,
+ "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
+
+ DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ void *ptr = buf->ptr;
+
+ dev_dbg(dev,
+ "%s: copy back safe %p to unsafe %p size %d\n",
+ __func__, buf->safe, ptr, size);
+ memcpy(ptr, buf->safe, size);
+
+ /*
+ * Since we may have written to a page cache page,
+ * we need to ensure that the data will be coherent
+ * with user mappings.
+ */
+ __cpuc_flush_dcache_area(ptr, size);
+ }
+ free_safe_buffer(dev->archdata.dmabounce, buf);
+ } else {
+ __dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir);
+ }
+}
+
+/* ************************************************** */
+
+/*
+ * see if a buffer address is in an 'unsafe' range. if it is
+ * allocate a 'safe' buffer and copy the unsafe buffer into it.
+ * substitute the safe buffer for the unsafe one.
+ * (basically move the buffer from an unsafe area to a safe one)
+ */
+dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction dir)
+{
+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
+ __func__, ptr, size, dir);
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ return map_single(dev, ptr, size, dir);
+}
+EXPORT_SYMBOL(__dma_map_single);
+
+/*
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer. (basically return things back to the way they
+ * should be)
+ */
+void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir)
+{
+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
+ __func__, (void *) dma_addr, size, dir);
+
+ unmap_single(dev, dma_addr, size, dir);
+}
+EXPORT_SYMBOL(__dma_unmap_single);
+
+dma_addr_t __dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n",
+ __func__, page, offset, size, dir);
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ if (PageHighMem(page)) {
+ dev_err(dev, "DMA buffer bouncing of HIGHMEM pages "
+ "is not supported\n");
+ return ~0;
+ }
+
+ return map_single(dev, page_address(page) + offset, size, dir);
+}
+EXPORT_SYMBOL(__dma_map_page);
+
+/*
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer. (basically return things back to the way they
+ * should be)
+ */
+void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction dir)
+{
+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
+ __func__, (void *) dma_addr, size, dir);
+
+ unmap_single(dev, dma_addr, size, dir);
+}
+EXPORT_SYMBOL(__dma_unmap_page);
+
+int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
+ unsigned long off, size_t sz, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf;
+
+ dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
+ __func__, addr, off, sz, dir);
+
+ buf = find_safe_buffer_dev(dev, addr, __func__);
+ if (!buf)
+ return 1;
+
+ BUG_ON(buf->direction != dir);
+
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
+
+ DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n",
+ __func__, buf->safe + off, buf->ptr + off, sz);
+ memcpy(buf->ptr + off, buf->safe + off, sz);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dmabounce_sync_for_cpu);
+
+int dmabounce_sync_for_device(struct device *dev, dma_addr_t addr,
+ unsigned long off, size_t sz, enum dma_data_direction dir)
+{
+ struct safe_buffer *buf;
+
+ dev_dbg(dev, "%s(dma=%#x,off=%#lx,sz=%zx,dir=%x)\n",
+ __func__, addr, off, sz, dir);
+
+ buf = find_safe_buffer_dev(dev, addr, __func__);
+ if (!buf)
+ return 1;
+
+ BUG_ON(buf->direction != dir);
+
+ dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n",
+ __func__, buf->ptr, virt_to_dma(dev, buf->ptr),
+ buf->safe, buf->safe_dma_addr);
+
+ DO_STATS(dev->archdata.dmabounce->bounce_count++);
+
+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) {
+ dev_dbg(dev, "%s: copy out unsafe %p to safe %p, size %d\n",
+ __func__,buf->ptr + off, buf->safe + off, sz);
+ memcpy(buf->safe + off, buf->ptr + off, sz);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dmabounce_sync_for_device);
+
+static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev,
+ const char *name, unsigned long size)
+{
+ pool->size = size;
+ DO_STATS(pool->allocs = 0);
+ pool->pool = dma_pool_create(name, dev, size,
+ 0 /* byte alignment */,
+ 0 /* no page-crossing issues */);
+
+ return pool->pool ? 0 : -ENOMEM;
+}
+
+int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
+ unsigned long large_buffer_size)
+{
+ struct dmabounce_device_info *device_info;
+ int ret;
+
+ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
+ if (!device_info) {
+ dev_err(dev,
+ "Could not allocated dmabounce_device_info\n");
+ return -ENOMEM;
+ }
+
+ ret = dmabounce_init_pool(&device_info->small, dev,
+ "small_dmabounce_pool", small_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ small_buffer_size);
+ goto err_free;
+ }
+
+ if (large_buffer_size) {
+ ret = dmabounce_init_pool(&device_info->large, dev,
+ "large_dmabounce_pool",
+ large_buffer_size);
+ if (ret) {
+ dev_err(dev,
+ "dmabounce: could not allocate DMA pool for %ld byte objects\n",
+ large_buffer_size);
+ goto err_destroy;
+ }
+ }
+
+ device_info->dev = dev;
+ INIT_LIST_HEAD(&device_info->safe_buffers);
+ rwlock_init(&device_info->lock);
+
+#ifdef STATS
+ device_info->total_allocs = 0;
+ device_info->map_op_count = 0;
+ device_info->bounce_count = 0;
+ device_info->attr_res = device_create_file(dev, &dev_attr_dmabounce_stats);
+#endif
+
+ dev->archdata.dmabounce = device_info;
+
+ dev_info(dev, "dmabounce: registered device\n");
+
+ return 0;
+
+ err_destroy:
+ dma_pool_destroy(device_info->small.pool);
+ err_free:
+ kfree(device_info);
+ return ret;
+}
+EXPORT_SYMBOL(dmabounce_register_dev);
+
+void dmabounce_unregister_dev(struct device *dev)
+{
+ struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
+
+ dev->archdata.dmabounce = NULL;
+
+ if (!device_info) {
+ dev_warn(dev,
+ "Never registered with dmabounce but attempting"
+ "to unregister!\n");
+ return;
+ }
+
+ if (!list_empty(&device_info->safe_buffers)) {
+ dev_err(dev,
+ "Removing from dmabounce with pending buffers!\n");
+ BUG();
+ }
+
+ if (device_info->small.pool)
+ dma_pool_destroy(device_info->small.pool);
+ if (device_info->large.pool)
+ dma_pool_destroy(device_info->large.pool);
+
+#ifdef STATS
+ if (device_info->attr_res == 0)
+ device_remove_file(dev, &dev_attr_dmabounce_stats);
+#endif
+
+ kfree(device_info);
+
+ dev_info(dev, "dmabounce: device unregistered\n");
+}
+EXPORT_SYMBOL(dmabounce_unregister_dev);
+
+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>");
+MODULE_DESCRIPTION("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
new file mode 100644
index 00000000..3ed18ae2
--- /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 00000000..2649b558
--- /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 00000000..9e3455a0
--- /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 00000000..4044c7db
--- /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
new file mode 100644
index 00000000..21140fdc
--- /dev/null
+++ b/arch/arm/common/gic.c
@@ -0,0 +1,522 @@
+/*
+ * linux/arch/arm/common/gic.c
+ *
+ * Copyright (C) 2002 ARM Limited, 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.
+ *
+ * Interrupt architecture for the GIC:
+ *
+ * o There is one Interrupt Distributor, which receives interrupts
+ * from system devices and sends them to the Interrupt Controllers.
+ *
+ * o There is one CPU Interface per CPU, which sends interrupts sent
+ * by the Distributor, and interrupts generated locally, to the
+ * associated CPU. The base address of the CPU interface is usually
+ * aliased so that the same address points to different chips depending
+ * on the CPU it is accessed from.
+ *
+ * Note that IRQs 0-31 are special - they are local to each CPU.
+ * As such, the enable set/clear, pending set/clear and active bit
+ * registers are banked per-cpu for these sources.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/smp.h>
+#include <linux/cpumask.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+
+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.
+ */
+struct irq_chip gic_arch_extn = {
+ .irq_eoi = NULL,
+ .irq_mask = NULL,
+ .irq_unmask = NULL,
+ .irq_retrigger = NULL,
+ .irq_set_type = NULL,
+ .irq_set_wake = NULL,
+};
+
+#ifndef MAX_GIC_NR
+#define MAX_GIC_NR 1
+#endif
+
+static struct gic_chip_data gic_data[MAX_GIC_NR] __read_mostly;
+
+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;
+}
+
+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;
+}
+
+static inline unsigned int gic_irq(struct irq_data *d)
+{
+ struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d);
+ return d->irq - gic_data->irq_offset;
+}
+
+/*
+ * Routines to acknowledge, disable and enable interrupts
+ */
+static void gic_mask_irq(struct irq_data *d)
+{
+ u32 mask = 1 << (d->irq % 32);
+
+ spin_lock(&irq_controller_lock);
+ writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
+ if (gic_arch_extn.irq_mask)
+ gic_arch_extn.irq_mask(d);
+ spin_unlock(&irq_controller_lock);
+}
+
+static void gic_unmask_irq(struct irq_data *d)
+{
+ u32 mask = 1 << (d->irq % 32);
+
+ spin_lock(&irq_controller_lock);
+ if (gic_arch_extn.irq_unmask)
+ gic_arch_extn.irq_unmask(d);
+ writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
+ spin_unlock(&irq_controller_lock);
+}
+
+static void gic_eoi_irq(struct irq_data *d)
+{
+ if (gic_arch_extn.irq_eoi) {
+ spin_lock(&irq_controller_lock);
+ gic_arch_extn.irq_eoi(d);
+ spin_unlock(&irq_controller_lock);
+ }
+
+ writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+}
+
+static int gic_set_type(struct irq_data *d, unsigned int type)
+{
+ void __iomem *base = gic_dist_base(d);
+ unsigned int gicirq = gic_irq(d);
+ u32 enablemask = 1 << (gicirq % 32);
+ u32 enableoff = (gicirq / 32) * 4;
+ u32 confmask = 0x2 << ((gicirq % 16) * 2);
+ u32 confoff = (gicirq / 16) * 4;
+ bool enabled = false;
+ u32 val;
+
+ /* Interrupt configuration for SGIs can't be changed */
+ if (gicirq < 16)
+ return -EINVAL;
+
+ if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ return -EINVAL;
+
+ spin_lock(&irq_controller_lock);
+
+ if (gic_arch_extn.irq_set_type)
+ gic_arch_extn.irq_set_type(d, type);
+
+ val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
+ if (type == IRQ_TYPE_LEVEL_HIGH)
+ val &= ~confmask;
+ else if (type == IRQ_TYPE_EDGE_RISING)
+ val |= confmask;
+
+ /*
+ * As recommended by the spec, disable the interrupt before changing
+ * the configuration
+ */
+ if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+ enabled = true;
+ }
+
+ writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
+
+ if (enabled)
+ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+
+ spin_unlock(&irq_controller_lock);
+
+ return 0;
+}
+
+static int gic_retrigger(struct irq_data *d)
+{
+ if (gic_arch_extn.irq_retrigger)
+ return gic_arch_extn.irq_retrigger(d);
+
+ return -ENXIO;
+}
+
+#ifdef CONFIG_SMP
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ bool force)
+{
+ void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
+ unsigned int shift = (d->irq % 4) * 8;
+ unsigned int cpu = cpumask_first(mask_val);
+ u32 val, mask, bit;
+
+ if (cpu >= 8)
+ return -EINVAL;
+
+ mask = 0xff << shift;
+ bit = 1 << (cpu + shift);
+
+ spin_lock(&irq_controller_lock);
+ val = readl_relaxed(reg) & ~mask;
+ writel_relaxed(val | bit, reg);
+ spin_unlock(&irq_controller_lock);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM
+static int gic_set_wake(struct irq_data *d, unsigned int on)
+{
+ int ret = -ENXIO;
+
+ if (gic_arch_extn.irq_set_wake)
+ ret = gic_arch_extn.irq_set_wake(d, on);
+
+ return ret;
+}
+
+#else
+#define gic_set_wake NULL
+#endif
+
+static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct gic_chip_data *chip_data = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
+ unsigned int cascade_irq, gic_irq;
+ unsigned long status;
+
+ chained_irq_enter(chip, desc);
+
+ spin_lock(&irq_controller_lock);
+ status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
+ spin_unlock(&irq_controller_lock);
+
+ gic_irq = (status & 0x3ff);
+ if (gic_irq == 1023)
+ goto out;
+
+ cascade_irq = gic_irq + chip_data->irq_offset;
+ if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
+ do_bad_IRQ(cascade_irq, desc);
+ else
+ generic_handle_irq(cascade_irq);
+
+ out:
+ chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip gic_chip = {
+ .name = "GIC",
+ .irq_mask = gic_mask_irq,
+ .irq_unmask = gic_unmask_irq,
+ .irq_eoi = gic_eoi_irq,
+ .irq_set_type = gic_set_type,
+ .irq_retrigger = gic_retrigger,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = gic_set_affinity,
+#endif
+ .irq_set_wake = gic_set_wake,
+};
+
+void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
+{
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+ if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
+ BUG();
+ irq_set_chained_handler(irq, gic_handle_cascade_irq);
+}
+
+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;
+ u32 cpumask = 1 << smp_processor_id();
+
+ cpumask |= cpumask << 8;
+ cpumask |= cpumask << 16;
+
+ writel_relaxed(0, base + GIC_DIST_CTRL);
+
+ /*
+ * Find out how many interrupts are supported.
+ * The GIC only supports up to 1020 interrupt sources.
+ */
+ gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+
+ /*
+ * Set all global interrupts to be level triggered, active low.
+ */
+ for (i = 32; i < gic_irqs; i += 16)
+ writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
+
+ /*
+ * Set all global interrupts to this CPU only.
+ */
+ for (i = 32; i < gic_irqs; i += 4)
+ writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
+
+ /*
+ * Set priority on all global interrupts.
+ */
+ for (i = 32; i < gic_irqs; i += 4)
+ writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
+
+ /*
+ * Disable all interrupts. Leave the PPI and SGIs alone
+ * as these enables are banked registers.
+ */
+ for (i = 32; i < gic_irqs; i += 32)
+ writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
+
+ /*
+ * Limit number of interrupts registered to the platform maximum
+ */
+ irq_limit = gic->irq_offset + gic_irqs;
+ if (WARN_ON(irq_limit > NR_IRQS))
+ irq_limit = NR_IRQS;
+
+ /*
+ * Setup the Linux IRQ subsystem.
+ */
+ for (i = irq_start; i < irq_limit; i++) {
+ irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
+ irq_set_chip_data(i, gic);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ writel_relaxed(1, base + GIC_DIST_CTRL);
+}
+
+static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
+{
+ void __iomem *dist_base = gic->dist_base;
+ void __iomem *base = gic->cpu_base;
+ int i;
+
+ /*
+ * Deal with the banked PPI and SGI interrupts - disable all
+ * PPI interrupts, ensure all SGI interrupts are enabled.
+ */
+ writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
+ writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+
+ /*
+ * Set priority on PPI and SGI interrupts
+ */
+ for (i = 0; i < 32; i += 4)
+ writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+
+ writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
+ writel_relaxed(1, base + GIC_CPU_CTRL);
+}
+
+void gic_init(unsigned int gic_nr, unsigned int irq_start,
+ void __iomem *dist_base, void __iomem *cpu_base)
+{
+ struct gic_chip_data *gic;
+
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic = &gic_data[gic_nr];
+ gic->dist_base = dist_base;
+ gic->cpu_base = cpu_base;
+ gic->irq_offset = (irq_start - 1) & ~31;
+
+ if (gic_nr == 0)
+ gic_cpu_base_addr = cpu_base;
+
+ gic_dist_init(gic, irq_start);
+ gic_cpu_init(gic);
+}
+
+void __cpuinit gic_secondary_init(unsigned int gic_nr)
+{
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic_cpu_init(&gic_data[gic_nr]);
+}
+
+void __cpuinit gic_enable_ppi(unsigned int irq)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ irq_set_status_flags(irq, IRQ_NOPROBE);
+ gic_unmask_irq(irq_get_irq_data(irq));
+ local_irq_restore(flags);
+}
+void __cpuinit gic_disable_ppi(unsigned int irq)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ irq_set_status_flags(irq, IRQ_NOPROBE);
+ gic_mask_irq(irq_get_irq_data(irq));
+ local_irq_restore(flags);
+}
+
+void save_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs)
+{
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gcs->iccicr = __raw_readl(gic_data[gic_nr].cpu_base + GIC_CPU_CTRL);
+ gcs->iccpmr = __raw_readl(gic_data[gic_nr].cpu_base + GIC_CPU_PRIMASK);
+ gcs->iccbpr = __raw_readl(gic_data[gic_nr].cpu_base + GIC_CPU_BINPOINT);
+}
+
+void restore_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs)
+{
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ __raw_writel(gcs->iccpmr, gic_data[gic_nr].cpu_base + GIC_CPU_PRIMASK);
+ __raw_writel(gcs->iccbpr, gic_data[gic_nr].cpu_base + GIC_CPU_BINPOINT);
+
+ /* at last, restore ctrl register */
+ __raw_writel(gcs->iccicr, gic_data[gic_nr].cpu_base + GIC_CPU_CTRL);
+}
+
+void save_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds)
+{
+ unsigned int gic_irqs, i;
+
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic_irqs = readl(gic_data[gic_nr].dist_base + GIC_DIST_CTR) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+
+ gds->icddcr = __raw_readl(gic_data[gic_nr].dist_base + GIC_DIST_CTRL);
+
+ /* save interrupt enable status */
+ for (i = 0; i < gic_irqs; i += 32)
+ gds->icdisern[i / 32] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_ENABLE_SET + i * 4 / 32);
+
+ /* save interrupt pending status */
+ for (i = 0; i < gic_irqs; i += 32)
+ gds->icdisprn[i / 32] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_PENDING_SET + i * 4 / 32);
+
+ /* save active bit status */
+ for (i = 0; i < gic_irqs; i += 32)
+ gds->icdabrn[i / 32] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_ACTIVE_BIT + i * 4 / 32);
+
+ /* interrupt priority registers */
+ for (i = 0; i < gic_irqs; i += 4)
+ gds->icdiprn[i / 4] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_PRI + i * 4 / 4);
+
+ /* interrupt processor targets registers */
+ for (i = 0; i < gic_irqs; i += 4)
+ gds->icdiptrn[i / 4] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_TARGET + i * 4 / 4);
+
+ /* interrupt configuration registers */
+ for (i = 0; i < gic_irqs; i += 16)
+ gds->icdicfrn[i / 16] = __raw_readl(gic_data[gic_nr].dist_base
+ + GIC_DIST_CONFIG + i * 4 / 16);
+}
+
+void restore_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds)
+{
+ unsigned int gic_irqs, i;
+
+ BUG_ON(gic_nr >= MAX_GIC_NR);
+
+ gic_irqs = readl(gic_data[gic_nr].dist_base + GIC_DIST_CTR) & 0x1f;
+ gic_irqs = (gic_irqs + 1) * 32;
+ if (gic_irqs > 1020)
+ gic_irqs = 1020;
+
+ __raw_writel(0, gic_data[gic_nr].dist_base + GIC_DIST_CTRL);
+
+ /* interrupt configuration registers */
+ for (i = 0; i < gic_irqs; i += 16)
+ __raw_writel(gds->icdicfrn[i / 16], gic_data[gic_nr].dist_base
+ + GIC_DIST_CONFIG + i * 4 / 16);
+
+ /* interrupt priority registers */
+ for (i = 0; i < gic_irqs; i += 4)
+ __raw_writel(gds->icdiprn[i / 4], gic_data[gic_nr].dist_base
+ + GIC_DIST_PRI + i * 4 / 4);
+
+ /* interrupt processor targets registers */
+ for (i = 0; i < gic_irqs; i += 4)
+ __raw_writel(gds->icdiptrn[i / 4], gic_data[gic_nr].dist_base
+ + GIC_DIST_TARGET + i * 4 / 4);
+
+ /* restore active bits */
+ for (i = 0; i < gic_irqs; i += 32)
+ __raw_writel(gds->icdabrn[i / 32], gic_data[gic_nr].dist_base
+ + GIC_DIST_ACTIVE_BIT + i * 4 / 32);
+
+ /* restore pending bits */
+ for (i = 0; i < gic_irqs; i += 32)
+ __raw_writel(gds->icdisprn[i / 32], gic_data[gic_nr].dist_base
+ + GIC_DIST_PENDING_SET + i * 4 / 32);
+
+ /* restore interrupt enable status */
+ for (i = 0; i < gic_irqs; i += 32)
+ __raw_writel(gds->icdisern[i / 32], gic_data[gic_nr].dist_base
+ + GIC_DIST_ENABLE_SET + i * 4 / 32);
+
+ /* at last restore ctrl register */
+ __raw_writel(gds->icddcr, gic_data[gic_nr].dist_base + GIC_DIST_CTRL);
+}
+
+#ifdef CONFIG_SMP
+void gic_raise_softirq(const struct cpumask *mask, unsigned int irq)
+{
+ unsigned long map = *cpus_addr(*mask);
+
+ /*
+ * Ensure that stores to Normal memory are visible to the
+ * other CPUs before issuing the IPI.
+ */
+ dsb();
+
+ /* this always happens on GIC0 */
+ writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
+}
+#endif
diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
new file mode 100644
index 00000000..2dc6da70
--- /dev/null
+++ b/arch/arm/common/icst.c
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/common/icst307.c
+ *
+ * Copyright (C) 2003 Deep Blue Solutions, 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.
+ *
+ * Support functions for calculating clocks/divisors for the ICST307
+ * clock generators. See http://www.idt.com/ for more information
+ * on these devices.
+ *
+ * This is an almost identical implementation to the ICST525 clock generator.
+ * The s2div and idx2s files are different
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/icst.h>
+
+/*
+ * Divisors for each OD setting.
+ */
+const unsigned char icst307_s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 };
+const unsigned char icst525_s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+EXPORT_SYMBOL(icst307_s2div);
+EXPORT_SYMBOL(icst525_s2div);
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
+{
+ return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
+}
+
+EXPORT_SYMBOL(icst_hz);
+
+/*
+ * Ascending divisor S values.
+ */
+const unsigned char icst307_idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 };
+const unsigned char icst525_idx2s[8] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+EXPORT_SYMBOL(icst307_idx2s);
+EXPORT_SYMBOL(icst525_idx2s);
+
+struct icst_vco
+icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
+{
+ struct icst_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
+ unsigned long f;
+ unsigned int i = 0, rd, best = (unsigned int)-1;
+
+ /*
+ * First, find the PLL output divisor such
+ * that the PLL output is within spec.
+ */
+ do {
+ f = freq * p->s2div[p->idx2s[i]];
+
+ if (f > p->vco_min && f <= p->vco_max)
+ break;
+ } while (i < 8);
+
+ if (i >= 8)
+ return vco;
+
+ vco.s = p->idx2s[i];
+
+ /*
+ * Now find the closest divisor combination
+ * which gives a PLL output of 'f'.
+ */
+ for (rd = p->rd_min; rd <= p->rd_max; rd++) {
+ unsigned long fref_div, f_pll;
+ unsigned int vd;
+ int f_diff;
+
+ fref_div = (2 * p->ref) / rd;
+
+ vd = (f + fref_div / 2) / fref_div;
+ if (vd < p->vd_min || vd > p->vd_max)
+ continue;
+
+ f_pll = fref_div * vd;
+ f_diff = f_pll - f;
+ if (f_diff < 0)
+ f_diff = -f_diff;
+
+ if ((unsigned)f_diff < best) {
+ vco.v = vd - 8;
+ vco.r = rd - 2;
+ if (f_diff == 0)
+ break;
+ best = f_diff;
+ }
+ }
+
+ return vco;
+}
+
+EXPORT_SYMBOL(icst_hz_to_vco);
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
new file mode 100644
index 00000000..7a21927c
--- /dev/null
+++ b/arch/arm/common/it8152.c
@@ -0,0 +1,359 @@
+/*
+ * linux/arch/arm/common/it8152.c
+ *
+ * Copyright Compulab Ltd, 2002-2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * The DMA bouncing part is taken from arch/arm/mach-ixp4xx/common-pci.c
+ * (see this file for respective copyrights)
+ *
+ * Thanks to Guennadi Liakhovetski <gl@dsa-ac.de> for IRQ enumberation
+ * and demux code.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/mach/pci.h>
+#include <asm/hardware/it8152.h>
+
+#define MAX_SLOTS 21
+
+static void it8152_mask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ if (irq >= IT8152_LD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) |
+ (1 << (irq - IT8152_LD_IRQ(0)))),
+ IT8152_INTC_LDCNIMR);
+ } else if (irq >= IT8152_LP_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) |
+ (1 << (irq - IT8152_LP_IRQ(0)))),
+ IT8152_INTC_LPCNIMR);
+ } else if (irq >= IT8152_PD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) |
+ (1 << (irq - IT8152_PD_IRQ(0)))),
+ IT8152_INTC_PDCNIMR);
+ }
+}
+
+static void it8152_unmask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ if (irq >= IT8152_LD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LDCNIMR) &
+ ~(1 << (irq - IT8152_LD_IRQ(0)))),
+ IT8152_INTC_LDCNIMR);
+ } else if (irq >= IT8152_LP_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_LPCNIMR) &
+ ~(1 << (irq - IT8152_LP_IRQ(0)))),
+ IT8152_INTC_LPCNIMR);
+ } else if (irq >= IT8152_PD_IRQ(0)) {
+ __raw_writel((__raw_readl(IT8152_INTC_PDCNIMR) &
+ ~(1 << (irq - IT8152_PD_IRQ(0)))),
+ IT8152_INTC_PDCNIMR);
+ }
+}
+
+static struct irq_chip it8152_irq_chip = {
+ .name = "it8152",
+ .irq_ack = it8152_mask_irq,
+ .irq_mask = it8152_mask_irq,
+ .irq_unmask = it8152_unmask_irq,
+};
+
+void it8152_init_irq(void)
+{
+ int irq;
+
+ __raw_writel((0xffff), IT8152_INTC_PDCNIMR);
+ __raw_writel((0), IT8152_INTC_PDCNIRR);
+ __raw_writel((0xffff), IT8152_INTC_LPCNIMR);
+ __raw_writel((0), IT8152_INTC_LPCNIRR);
+ __raw_writel((0xffff), IT8152_INTC_LDCNIMR);
+ __raw_writel((0), IT8152_INTC_LDCNIRR);
+
+ for (irq = IT8152_IRQ(0); irq <= IT8152_LAST_IRQ; irq++) {
+ irq_set_chip_and_handler(irq, &it8152_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+}
+
+void it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ int bits_pd, bits_lp, bits_ld;
+ int i;
+
+ while (1) {
+ /* Read all */
+ bits_pd = __raw_readl(IT8152_INTC_PDCNIRR);
+ bits_lp = __raw_readl(IT8152_INTC_LPCNIRR);
+ bits_ld = __raw_readl(IT8152_INTC_LDCNIRR);
+
+ /* Ack */
+ __raw_writel((~bits_pd), IT8152_INTC_PDCNIRR);
+ __raw_writel((~bits_lp), IT8152_INTC_LPCNIRR);
+ __raw_writel((~bits_ld), IT8152_INTC_LDCNIRR);
+
+ if (!(bits_ld | bits_lp | bits_pd)) {
+ /* Re-read to guarantee, that there was a moment of
+ time, when they all three were 0. */
+ bits_pd = __raw_readl(IT8152_INTC_PDCNIRR);
+ bits_lp = __raw_readl(IT8152_INTC_LPCNIRR);
+ bits_ld = __raw_readl(IT8152_INTC_LDCNIRR);
+ if (!(bits_ld | bits_lp | bits_pd))
+ return;
+ }
+
+ bits_pd &= ((1 << IT8152_PD_IRQ_COUNT) - 1);
+ while (bits_pd) {
+ i = __ffs(bits_pd);
+ generic_handle_irq(IT8152_PD_IRQ(i));
+ bits_pd &= ~(1 << i);
+ }
+
+ bits_lp &= ((1 << IT8152_LP_IRQ_COUNT) - 1);
+ while (bits_lp) {
+ i = __ffs(bits_lp);
+ generic_handle_irq(IT8152_LP_IRQ(i));
+ bits_lp &= ~(1 << i);
+ }
+
+ bits_ld &= ((1 << IT8152_LD_IRQ_COUNT) - 1);
+ while (bits_ld) {
+ i = __ffs(bits_ld);
+ generic_handle_irq(IT8152_LD_IRQ(i));
+ bits_ld &= ~(1 << i);
+ }
+ }
+}
+
+/* mapping for on-chip devices */
+int __init it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if ((dev->vendor == PCI_VENDOR_ID_ITE) &&
+ (dev->device == PCI_DEVICE_ID_ITE_8152)) {
+ if ((dev->class >> 8) == PCI_CLASS_MULTIMEDIA_AUDIO)
+ return IT8152_AUDIO_INT;
+ if ((dev->class >> 8) == PCI_CLASS_SERIAL_USB)
+ return IT8152_USB_INT;
+ if ((dev->class >> 8) == PCI_CLASS_SYSTEM_DMA)
+ return IT8152_CDMA_INT;
+ }
+
+ return 0;
+}
+
+static unsigned long it8152_pci_dev_base_address(struct pci_bus *bus,
+ unsigned int devfn)
+{
+ unsigned long addr = 0;
+
+ if (bus->number == 0) {
+ if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+ addr = (devfn << 8);
+ } else
+ addr = (bus->number << 16) | (devfn << 8);
+
+ return addr;
+}
+
+static int it8152_pci_read_config(struct pci_bus *bus,
+ unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+ u32 v;
+ int shift;
+
+ shift = (where & 3);
+
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ v = (__raw_readl(IT8152_PCI_CFG_DATA) >> (8 * (shift)));
+
+ *value = v;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int it8152_pci_write_config(struct pci_bus *bus,
+ unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = it8152_pci_dev_base_address(bus, devfn);
+ u32 v, vtemp, mask = 0;
+ int shift;
+
+ if (size == 1)
+ mask = 0xff;
+ if (size == 2)
+ mask = 0xffff;
+
+ shift = (where & 3);
+
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ vtemp = __raw_readl(IT8152_PCI_CFG_DATA);
+
+ if (mask)
+ vtemp &= ~(mask << (8 * shift));
+ else
+ vtemp = 0;
+
+ v = (value << (8 * shift));
+ __raw_writel((addr + where), IT8152_PCI_CFG_ADDR);
+ __raw_writel((v | vtemp), IT8152_PCI_CFG_DATA);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops it8152_ops = {
+ .read = it8152_pci_read_config,
+ .write = it8152_pci_write_config,
+};
+
+static struct resource it8152_io = {
+ .name = "IT8152 PCI I/O region",
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource it8152_mem = {
+ .name = "IT8152 PCI memory region",
+ .start = 0x10000000,
+ .end = 0x13e00000,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * The following functions are needed for DMA bouncing.
+ * ITE8152 chip can address up to 64MByte, so all the devices
+ * connected to ITE8152 (PCI and USB) should have limited DMA window
+ */
+
+/*
+ * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all
+ * other devices.
+ */
+static int it8152_pci_platform_notify(struct device *dev)
+{
+ if (dev->bus == &pci_bus_type) {
+ if (dev->dma_mask)
+ *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
+ dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET;
+ dmabounce_register_dev(dev, 2048, 4096);
+ }
+ return 0;
+}
+
+static int it8152_pci_platform_notify_remove(struct device *dev)
+{
+ if (dev->bus == &pci_bus_type)
+ dmabounce_unregister_dev(dev);
+
+ return 0;
+}
+
+int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ dev_dbg(dev, "%s: dma_addr %08x, size %08x\n",
+ __func__, dma_addr, size);
+ return (dev->bus == &pci_bus_type) &&
+ ((dma_addr + size - PHYS_OFFSET) >= SZ_64M);
+}
+
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (mask >= PHYS_OFFSET + SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
+int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ it8152_io.start = IT8152_IO_BASE + 0x12000;
+ it8152_io.end = IT8152_IO_BASE + 0x12000 + 0x100000;
+
+ sys->mem_offset = 0x10000000;
+ sys->io_offset = IT8152_IO_BASE;
+
+ if (request_resource(&ioport_resource, &it8152_io)) {
+ printk(KERN_ERR "PCI: unable to allocate IO region\n");
+ goto err0;
+ }
+ if (request_resource(&iomem_resource, &it8152_mem)) {
+ printk(KERN_ERR "PCI: unable to allocate memory region\n");
+ goto err1;
+ }
+
+ sys->resource[0] = &it8152_io;
+ sys->resource[1] = &it8152_mem;
+
+ if (platform_notify || platform_notify_remove) {
+ printk(KERN_ERR "PCI: Can't use platform_notify\n");
+ goto err2;
+ }
+
+ platform_notify = it8152_pci_platform_notify;
+ platform_notify_remove = it8152_pci_platform_notify_remove;
+
+ return 1;
+
+err2:
+ release_resource(&it8152_io);
+err1:
+ release_resource(&it8152_mem);
+err0:
+ return -EBUSY;
+}
+
+/*
+ * If we set up a device for bus mastering, we need to check the latency
+ * timer as we don't have even crappy BIOSes to set it properly.
+ * The implementation is from arch/i386/pci/i386.c
+ */
+unsigned int pcibios_max_latency = 255;
+
+void pcibios_set_master(struct pci_dev *dev)
+{
+ u8 lat;
+
+ /* no need to update on-chip OHCI controller */
+ if ((dev->vendor == PCI_VENDOR_ID_ITE) &&
+ (dev->device == PCI_DEVICE_ID_ITE_8152) &&
+ ((dev->class >> 8) == PCI_CLASS_SERIAL_USB))
+ return;
+
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
+ if (lat < 16)
+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
+ else if (lat > pcibios_max_latency)
+ lat = pcibios_max_latency;
+ else
+ return;
+ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n",
+ pci_name(dev), lat);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
+}
+
+
+struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(nr, &it8152_ops, sys);
+}
+
+EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
new file mode 100644
index 00000000..b55c3625
--- /dev/null
+++ b/arch/arm/common/locomo.c
@@ -0,0 +1,914 @@
+/*
+ * linux/arch/arm/common/locomo.c
+ *
+ * Sharp LoCoMo 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.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ *
+ * Based on sa1111.c
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <asm/hardware/locomo.h>
+
+/* LoCoMo Interrupts */
+#define IRQ_LOCOMO_KEY (0)
+#define IRQ_LOCOMO_GPIO (1)
+#define IRQ_LOCOMO_LT (2)
+#define IRQ_LOCOMO_SPI (3)
+
+/* M62332 output channel selection */
+#define M62332_EVR_CH 1 /* M62332 volume channel number */
+ /* 0 : CH.1 , 1 : CH. 2 */
+/* DAC send data */
+#define M62332_SLAVE_ADDR 0x4e /* Slave address */
+#define M62332_W_BIT 0x00 /* W bit (0 only) */
+#define M62332_SUB_ADDR 0x00 /* Sub address */
+#define M62332_A_BIT 0x00 /* A bit (0 only) */
+
+/* DAC setup and hold times (expressed in us) */
+#define DAC_BUS_FREE_TIME 5 /* 4.7 us */
+#define DAC_START_SETUP_TIME 5 /* 4.7 us */
+#define DAC_STOP_SETUP_TIME 4 /* 4.0 us */
+#define DAC_START_HOLD_TIME 5 /* 4.7 us */
+#define DAC_SCL_LOW_HOLD_TIME 5 /* 4.7 us */
+#define DAC_SCL_HIGH_HOLD_TIME 4 /* 4.0 us */
+#define DAC_DATA_SETUP_TIME 1 /* 250 ns */
+#define DAC_DATA_HOLD_TIME 1 /* 300 ns */
+#define DAC_LOW_SETUP_TIME 1 /* 300 ns */
+#define DAC_HIGH_SETUP_TIME 1 /* 1000 ns */
+
+/* the following is the overall data for the locomo chip */
+struct locomo {
+ struct device *dev;
+ unsigned long phys;
+ unsigned int irq;
+ int irq_base;
+ spinlock_t lock;
+ void __iomem *base;
+#ifdef CONFIG_PM
+ void *saved_state;
+#endif
+};
+
+struct locomo_dev_info {
+ unsigned long offset;
+ unsigned long length;
+ unsigned int devid;
+ unsigned int irq[1];
+ const char * name;
+};
+
+/* All the locomo devices. If offset is non-zero, the mapbase for the
+ * locomo_dev will be set to the chip base plus offset. If offset is
+ * zero, then the mapbase for the locomo_dev will be set to zero. An
+ * offset of zero means the device only uses GPIOs or other helper
+ * functions inside this file */
+static struct locomo_dev_info locomo_devices[] = {
+ {
+ .devid = LOCOMO_DEVID_KEYBOARD,
+ .irq = { IRQ_LOCOMO_KEY },
+ .name = "locomo-keyboard",
+ .offset = LOCOMO_KEYBOARD,
+ .length = 16,
+ },
+ {
+ .devid = LOCOMO_DEVID_FRONTLIGHT,
+ .irq = {},
+ .name = "locomo-frontlight",
+ .offset = LOCOMO_FRONTLIGHT,
+ .length = 8,
+
+ },
+ {
+ .devid = LOCOMO_DEVID_BACKLIGHT,
+ .irq = {},
+ .name = "locomo-backlight",
+ .offset = LOCOMO_BACKLIGHT,
+ .length = 8,
+ },
+ {
+ .devid = LOCOMO_DEVID_AUDIO,
+ .irq = {},
+ .name = "locomo-audio",
+ .offset = LOCOMO_AUDIO,
+ .length = 4,
+ },
+ {
+ .devid = LOCOMO_DEVID_LED,
+ .irq = {},
+ .name = "locomo-led",
+ .offset = LOCOMO_LED,
+ .length = 8,
+ },
+ {
+ .devid = LOCOMO_DEVID_UART,
+ .irq = {},
+ .name = "locomo-uart",
+ .offset = 0,
+ .length = 0,
+ },
+ {
+ .devid = LOCOMO_DEVID_SPI,
+ .irq = {},
+ .name = "locomo-spi",
+ .offset = LOCOMO_SPI,
+ .length = 0x30,
+ },
+};
+
+static void locomo_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct locomo *lchip = irq_get_chip_data(irq);
+ int req, i;
+
+ /* Acknowledge the parent IRQ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ /* check why this interrupt was generated */
+ req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
+
+ if (req) {
+ /* generate the next interrupt(s) */
+ irq = lchip->irq_base;
+ for (i = 0; i <= 3; i++, irq++) {
+ if (req & (0x0100 << i)) {
+ generic_handle_irq(irq);
+ }
+
+ }
+ }
+}
+
+static void locomo_ack_irq(struct irq_data *d)
+{
+}
+
+static void locomo_mask_irq(struct irq_data *d)
+{
+ struct locomo *lchip = irq_data_get_irq_chip_data(d);
+ unsigned int r;
+ r = locomo_readl(lchip->base + LOCOMO_ICR);
+ r &= ~(0x0010 << (d->irq - lchip->irq_base));
+ locomo_writel(r, lchip->base + LOCOMO_ICR);
+}
+
+static void locomo_unmask_irq(struct irq_data *d)
+{
+ struct locomo *lchip = irq_data_get_irq_chip_data(d);
+ unsigned int r;
+ r = locomo_readl(lchip->base + LOCOMO_ICR);
+ r |= (0x0010 << (d->irq - lchip->irq_base));
+ locomo_writel(r, lchip->base + LOCOMO_ICR);
+}
+
+static struct irq_chip locomo_chip = {
+ .name = "LOCOMO",
+ .irq_ack = locomo_ack_irq,
+ .irq_mask = locomo_mask_irq,
+ .irq_unmask = locomo_unmask_irq,
+};
+
+static void locomo_setup_irq(struct locomo *lchip)
+{
+ int irq = lchip->irq_base;
+
+ /*
+ * Install handler for IRQ_LOCOMO_HW.
+ */
+ irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
+ irq_set_chip_data(lchip->irq, lchip);
+ irq_set_chained_handler(lchip->irq, locomo_handler);
+
+ /* Install handlers for IRQ_LOCOMO_* */
+ for ( ; irq <= lchip->irq_base + 3; irq++) {
+ irq_set_chip_and_handler(irq, &locomo_chip, handle_level_irq);
+ irq_set_chip_data(irq, lchip);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+}
+
+
+static void locomo_dev_release(struct device *_dev)
+{
+ struct locomo_dev *dev = LOCOMO_DEV(_dev);
+
+ kfree(dev);
+}
+
+static int
+locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
+{
+ struct locomo_dev *dev;
+ int ret;
+
+ dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * If the parent device has a DMA mask associated with it,
+ * propagate it down to the children.
+ */
+ if (lchip->dev->dma_mask) {
+ dev->dma_mask = *lchip->dev->dma_mask;
+ dev->dev.dma_mask = &dev->dma_mask;
+ }
+
+ dev_set_name(&dev->dev, "%s", info->name);
+ dev->devid = info->devid;
+ dev->dev.parent = lchip->dev;
+ dev->dev.bus = &locomo_bus_type;
+ dev->dev.release = locomo_dev_release;
+ dev->dev.coherent_dma_mask = lchip->dev->coherent_dma_mask;
+
+ if (info->offset)
+ dev->mapbase = lchip->base + info->offset;
+ else
+ dev->mapbase = 0;
+ dev->length = info->length;
+
+ dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
+ NO_IRQ : lchip->irq_base + info->irq[0];
+
+ ret = device_register(&dev->dev);
+ if (ret) {
+ out:
+ kfree(dev);
+ }
+ return ret;
+}
+
+#ifdef CONFIG_PM
+
+struct locomo_save_data {
+ u16 LCM_GPO;
+ u16 LCM_SPICT;
+ u16 LCM_GPE;
+ u16 LCM_ASD;
+ u16 LCM_SPIMD;
+};
+
+static int locomo_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct locomo *lchip = platform_get_drvdata(dev);
+ struct locomo_save_data *save;
+ unsigned long flags;
+
+ save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
+ if (!save)
+ return -ENOMEM;
+
+ lchip->saved_state = save;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ save->LCM_GPO = locomo_readl(lchip->base + LOCOMO_GPO); /* GPIO */
+ locomo_writel(0x00, lchip->base + LOCOMO_GPO);
+ save->LCM_SPICT = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT); /* SPI */
+ locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
+ save->LCM_GPE = locomo_readl(lchip->base + LOCOMO_GPE); /* GPIO */
+ locomo_writel(0x00, lchip->base + LOCOMO_GPE);
+ save->LCM_ASD = locomo_readl(lchip->base + LOCOMO_ASD); /* ADSTART */
+ locomo_writel(0x00, lchip->base + LOCOMO_ASD);
+ save->LCM_SPIMD = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD); /* SPI */
+ locomo_writel(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
+
+ locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
+ locomo_writel(0x00, lchip->base + LOCOMO_DAC);
+ locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
+
+ if ((locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88))
+ locomo_writel(0x00, lchip->base + LOCOMO_C32K); /* CLK32 off */
+ else
+ /* 18MHz already enabled, so no wait */
+ locomo_writel(0xc1, lchip->base + LOCOMO_C32K); /* CLK32 on */
+
+ locomo_writel(0x00, lchip->base + LOCOMO_TADC); /* 18MHz clock off*/
+ locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC); /* 22MHz/24MHz clock off */
+ locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); /* FL */
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ return 0;
+}
+
+static int locomo_resume(struct platform_device *dev)
+{
+ struct locomo *lchip = platform_get_drvdata(dev);
+ struct locomo_save_data *save;
+ unsigned long r;
+ unsigned long flags;
+
+ save = lchip->saved_state;
+ if (!save)
+ return 0;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
+ locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
+ locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
+ locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
+ locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
+
+ locomo_writel(0x00, lchip->base + LOCOMO_C32K);
+ locomo_writel(0x90, lchip->base + LOCOMO_TADC);
+
+ locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
+ r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+ r &= 0xFEFF;
+ locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+ locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ lchip->saved_state = NULL;
+ kfree(save);
+
+ return 0;
+}
+#endif
+
+
+/**
+ * locomo_probe - probe for a single LoCoMo chip.
+ * @phys_addr: physical address of device.
+ *
+ * Probe for a LoCoMo chip. This must be called
+ * before any other locomo-specific code.
+ *
+ * Returns:
+ * %-ENODEV device not found.
+ * %-EBUSY physical address already marked in-use.
+ * %0 successful.
+ */
+static int
+__locomo_probe(struct device *me, struct resource *mem, int irq)
+{
+ struct locomo_platform_data *pdata = me->platform_data;
+ struct locomo *lchip;
+ unsigned long r;
+ int i, ret = -ENODEV;
+
+ lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL);
+ if (!lchip)
+ return -ENOMEM;
+
+ spin_lock_init(&lchip->lock);
+
+ lchip->dev = me;
+ dev_set_drvdata(lchip->dev, lchip);
+
+ lchip->phys = mem->start;
+ lchip->irq = irq;
+ lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
+
+ /*
+ * Map the whole region. This also maps the
+ * registers for our children.
+ */
+ lchip->base = ioremap(mem->start, PAGE_SIZE);
+ if (!lchip->base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* locomo initialize */
+ locomo_writel(0, lchip->base + LOCOMO_ICR);
+ /* KEYBOARD */
+ locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
+
+ /* GPIO */
+ locomo_writel(0, lchip->base + LOCOMO_GPO);
+ locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
+ , lchip->base + LOCOMO_GPE);
+ locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
+ , lchip->base + LOCOMO_GPD);
+ locomo_writel(0, lchip->base + LOCOMO_GIE);
+
+ /* Frontlight */
+ locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+ locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
+
+ /* Longtime timer */
+ locomo_writel(0, lchip->base + LOCOMO_LTINT);
+ /* SPI */
+ locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
+
+ locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
+ r = locomo_readl(lchip->base + LOCOMO_ASD);
+ r |= 0x8000;
+ locomo_writel(r, lchip->base + LOCOMO_ASD);
+
+ locomo_writel(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD);
+ r = locomo_readl(lchip->base + LOCOMO_HSD);
+ r |= 0x8000;
+ locomo_writel(r, lchip->base + LOCOMO_HSD);
+
+ locomo_writel(128 / 8, lchip->base + LOCOMO_HSC);
+
+ /* XON */
+ locomo_writel(0x80, lchip->base + LOCOMO_TADC);
+ udelay(1000);
+ /* CLK9MEN */
+ r = locomo_readl(lchip->base + LOCOMO_TADC);
+ r |= 0x10;
+ locomo_writel(r, lchip->base + LOCOMO_TADC);
+ udelay(100);
+
+ /* init DAC */
+ r = locomo_readl(lchip->base + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
+ locomo_writel(r, lchip->base + LOCOMO_DAC);
+
+ r = locomo_readl(lchip->base + LOCOMO_VER);
+ printk(KERN_INFO "LoCoMo Chip: %lu%lu\n", (r >> 8), (r & 0xff));
+
+ /*
+ * The interrupt controller must be initialised before any
+ * other device to ensure that the interrupts are available.
+ */
+ if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
+ locomo_setup_irq(lchip);
+
+ for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
+ locomo_init_one_child(lchip, &locomo_devices[i]);
+ return 0;
+
+ out:
+ kfree(lchip);
+ return ret;
+}
+
+static int locomo_remove_child(struct device *dev, void *data)
+{
+ device_unregister(dev);
+ return 0;
+}
+
+static void __locomo_remove(struct locomo *lchip)
+{
+ device_for_each_child(lchip->dev, NULL, locomo_remove_child);
+
+ if (lchip->irq != NO_IRQ) {
+ irq_set_chained_handler(lchip->irq, NULL);
+ irq_set_handler_data(lchip->irq, NULL);
+ }
+
+ iounmap(lchip->base);
+ kfree(lchip);
+}
+
+static int locomo_probe(struct platform_device *dev)
+{
+ struct resource *mem;
+ int irq;
+
+ mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -EINVAL;
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0)
+ return -ENXIO;
+
+ return __locomo_probe(&dev->dev, mem, irq);
+}
+
+static int locomo_remove(struct platform_device *dev)
+{
+ struct locomo *lchip = platform_get_drvdata(dev);
+
+ if (lchip) {
+ __locomo_remove(lchip);
+ platform_set_drvdata(dev, NULL);
+ }
+
+ return 0;
+}
+
+/*
+ * Not sure if this should be on the system bus or not yet.
+ * We really want some way to register a system device at
+ * the per-machine level, and then have this driver pick
+ * up the registered devices.
+ */
+static struct platform_driver locomo_device_driver = {
+ .probe = locomo_probe,
+ .remove = locomo_remove,
+#ifdef CONFIG_PM
+ .suspend = locomo_suspend,
+ .resume = locomo_resume,
+#endif
+ .driver = {
+ .name = "locomo",
+ },
+};
+
+/*
+ * Get the parent device driver (us) structure
+ * from a child function device
+ */
+static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev)
+{
+ return (struct locomo *)dev_get_drvdata(ldev->dev.parent);
+}
+
+void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int r;
+
+ if (!lchip)
+ return;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ r = locomo_readl(lchip->base + LOCOMO_GPD);
+ if (dir)
+ r |= bits;
+ else
+ r &= ~bits;
+ locomo_writel(r, lchip->base + LOCOMO_GPD);
+
+ r = locomo_readl(lchip->base + LOCOMO_GPE);
+ if (dir)
+ r |= bits;
+ else
+ r &= ~bits;
+ locomo_writel(r, lchip->base + LOCOMO_GPE);
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+}
+EXPORT_SYMBOL(locomo_gpio_set_dir);
+
+int locomo_gpio_read_level(struct device *dev, unsigned int bits)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int ret;
+
+ if (!lchip)
+ return -ENODEV;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+ ret = locomo_readl(lchip->base + LOCOMO_GPL);
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ ret &= bits;
+ return ret;
+}
+EXPORT_SYMBOL(locomo_gpio_read_level);
+
+int locomo_gpio_read_output(struct device *dev, unsigned int bits)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int ret;
+
+ if (!lchip)
+ return -ENODEV;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+ ret = locomo_readl(lchip->base + LOCOMO_GPO);
+ spin_unlock_irqrestore(&lchip->lock, flags);
+
+ ret &= bits;
+ return ret;
+}
+EXPORT_SYMBOL(locomo_gpio_read_output);
+
+void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
+{
+ struct locomo *lchip = dev_get_drvdata(dev);
+ unsigned long flags;
+ unsigned int r;
+
+ if (!lchip)
+ return;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ r = locomo_readl(lchip->base + LOCOMO_GPO);
+ if (set)
+ r |= bits;
+ else
+ r &= ~bits;
+ locomo_writel(r, lchip->base + LOCOMO_GPO);
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+}
+EXPORT_SYMBOL(locomo_gpio_write);
+
+static void locomo_m62332_sendbit(void *mapbase, int bit)
+{
+ unsigned int r;
+
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+
+ if (bit & 1) {
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SDAOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ } else {
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SDAOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ }
+
+ udelay(DAC_DATA_SETUP_TIME); /* 250 nsec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */
+}
+
+void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel)
+{
+ struct locomo *lchip = locomo_chip_driver(ldev);
+ int i;
+ unsigned char data;
+ unsigned int r;
+ void *mapbase = lchip->base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&lchip->lock, flags);
+
+ /* Start */
+ udelay(DAC_BUS_FREE_TIME); /* 5.0 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.0 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SDAOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_START_HOLD_TIME); /* 5.0 usec */
+ udelay(DAC_DATA_HOLD_TIME); /* 300 nsec */
+
+ /* Send slave address and W bit (LSB is W bit) */
+ data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT;
+ for (i = 1; i <= 8; i++) {
+ locomo_m62332_sendbit(mapbase, data >> (8 - i));
+ }
+
+ /* Check A bit */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SDAOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
+ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
+ printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
+ goto out;
+ }
+
+ /* Send Sub address (LSB is channel select) */
+ /* channel = 0 : ch1 select */
+ /* = 1 : ch2 select */
+ data = M62332_SUB_ADDR + channel;
+ for (i = 1; i <= 8; i++) {
+ locomo_m62332_sendbit(mapbase, data >> (8 - i));
+ }
+
+ /* Check A bit */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SDAOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
+ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
+ printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
+ goto out;
+ }
+
+ /* Send DAC data */
+ for (i = 1; i <= 8; i++) {
+ locomo_m62332_sendbit(mapbase, dac_data >> (8 - i));
+ }
+
+ /* Check A bit */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SDAOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4.7 usec */
+ if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) { /* High is error */
+ printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
+ }
+
+out:
+ /* stop */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r &= ~(LOCOMO_DAC_SCLOEB);
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 300 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SDAOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_HIGH_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_HIGH_HOLD_TIME); /* 4 usec */
+
+ r = locomo_readl(mapbase + LOCOMO_DAC);
+ r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
+ locomo_writel(r, mapbase + LOCOMO_DAC);
+ udelay(DAC_LOW_SETUP_TIME); /* 1000 nsec */
+ udelay(DAC_SCL_LOW_HOLD_TIME); /* 4.7 usec */
+
+ spin_unlock_irqrestore(&lchip->lock, flags);
+}
+EXPORT_SYMBOL(locomo_m62332_senddata);
+
+/*
+ * Frontlight control
+ */
+
+void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
+{
+ unsigned long flags;
+ struct locomo *lchip = locomo_chip_driver(dev);
+
+ if (vr)
+ locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);
+ else
+ locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
+
+ spin_lock_irqsave(&lchip->lock, flags);
+ locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+ udelay(100);
+ locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
+ locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
+ spin_unlock_irqrestore(&lchip->lock, flags);
+}
+EXPORT_SYMBOL(locomo_frontlight_set);
+
+/*
+ * LoCoMo "Register Access Bus."
+ *
+ * We model this as a regular bus type, and hang devices directly
+ * off this.
+ */
+static int locomo_match(struct device *_dev, struct device_driver *_drv)
+{
+ struct locomo_dev *dev = LOCOMO_DEV(_dev);
+ struct locomo_driver *drv = LOCOMO_DRV(_drv);
+
+ return dev->devid == drv->devid;
+}
+
+static int locomo_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct locomo_dev *ldev = LOCOMO_DEV(dev);
+ struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv && drv->suspend)
+ ret = drv->suspend(ldev, state);
+ return ret;
+}
+
+static int locomo_bus_resume(struct device *dev)
+{
+ struct locomo_dev *ldev = LOCOMO_DEV(dev);
+ struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv && drv->resume)
+ ret = drv->resume(ldev);
+ return ret;
+}
+
+static int locomo_bus_probe(struct device *dev)
+{
+ struct locomo_dev *ldev = LOCOMO_DEV(dev);
+ struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
+ int ret = -ENODEV;
+
+ if (drv->probe)
+ ret = drv->probe(ldev);
+ return ret;
+}
+
+static int locomo_bus_remove(struct device *dev)
+{
+ struct locomo_dev *ldev = LOCOMO_DEV(dev);
+ struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv->remove)
+ ret = drv->remove(ldev);
+ return ret;
+}
+
+struct bus_type locomo_bus_type = {
+ .name = "locomo-bus",
+ .match = locomo_match,
+ .probe = locomo_bus_probe,
+ .remove = locomo_bus_remove,
+ .suspend = locomo_bus_suspend,
+ .resume = locomo_bus_resume,
+};
+
+int locomo_driver_register(struct locomo_driver *driver)
+{
+ driver->drv.bus = &locomo_bus_type;
+ return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(locomo_driver_register);
+
+void locomo_driver_unregister(struct locomo_driver *driver)
+{
+ driver_unregister(&driver->drv);
+}
+EXPORT_SYMBOL(locomo_driver_unregister);
+
+static int __init locomo_init(void)
+{
+ int ret = bus_register(&locomo_bus_type);
+ if (ret == 0)
+ platform_driver_register(&locomo_device_driver);
+ return ret;
+}
+
+static void __exit locomo_exit(void)
+{
+ platform_driver_unregister(&locomo_device_driver);
+ bus_unregister(&locomo_bus_type);
+}
+
+module_init(locomo_init);
+module_exit(locomo_exit);
+
+MODULE_DESCRIPTION("Sharp LoCoMo core driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
new file mode 100644
index 00000000..97912fa4
--- /dev/null
+++ b/arch/arm/common/pl330.c
@@ -0,0 +1,1965 @@
+/* linux/arch/arm/common/pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/hardware/pl330.h>
+
+/* Register and Bit field Definitions */
+#define DS 0x0
+#define DS_ST_STOP 0x0
+#define DS_ST_EXEC 0x1
+#define DS_ST_CMISS 0x2
+#define DS_ST_UPDTPC 0x3
+#define DS_ST_WFE 0x4
+#define DS_ST_ATBRR 0x5
+#define DS_ST_QBUSY 0x6
+#define DS_ST_WFP 0x7
+#define DS_ST_KILL 0x8
+#define DS_ST_CMPLT 0x9
+#define DS_ST_FLTCMP 0xe
+#define DS_ST_FAULT 0xf
+
+#define DPC 0x4
+#define INTEN 0x20
+#define ES 0x24
+#define INTSTATUS 0x28
+#define INTCLR 0x2c
+#define FSM 0x30
+#define FSC 0x34
+#define FTM 0x38
+
+#define _FTC 0x40
+#define FTC(n) (_FTC + (n)*0x4)
+
+#define _CS 0x100
+#define CS(n) (_CS + (n)*0x8)
+#define CS_CNS (1 << 21)
+
+#define _CPC 0x104
+#define CPC(n) (_CPC + (n)*0x8)
+
+#define _SA 0x400
+#define SA(n) (_SA + (n)*0x20)
+
+#define _DA 0x404
+#define DA(n) (_DA + (n)*0x20)
+
+#define _CC 0x408
+#define CC(n) (_CC + (n)*0x20)
+
+#define CC_SRCINC (1 << 0)
+#define CC_DSTINC (1 << 14)
+#define CC_SRCPRI (1 << 8)
+#define CC_DSTPRI (1 << 22)
+#define CC_SRCNS (1 << 9)
+#define CC_DSTNS (1 << 23)
+#define CC_SRCIA (1 << 10)
+#define CC_DSTIA (1 << 24)
+#define CC_SRCBRSTLEN_SHFT 4
+#define CC_DSTBRSTLEN_SHFT 18
+#define CC_SRCBRSTSIZE_SHFT 1
+#define CC_DSTBRSTSIZE_SHFT 15
+#define CC_SRCCCTRL_SHFT 11
+#define CC_SRCCCTRL_MASK 0x7
+#define CC_DSTCCTRL_SHFT 25
+#define CC_DRCCCTRL_MASK 0x7
+#define CC_SWAP_SHFT 28
+
+#define _LC0 0x40c
+#define LC0(n) (_LC0 + (n)*0x20)
+
+#define _LC1 0x410
+#define LC1(n) (_LC1 + (n)*0x20)
+
+#define DBGSTATUS 0xd00
+#define DBG_BUSY (1 << 0)
+
+#define DBGCMD 0xd04
+#define DBGINST0 0xd08
+#define DBGINST1 0xd0c
+
+#define CR0 0xe00
+#define CR1 0xe04
+#define CR2 0xe08
+#define CR3 0xe0c
+#define CR4 0xe10
+#define CRD 0xe14
+
+#define PERIPH_ID 0xfe0
+#define PCELL_ID 0xff0
+
+#define CR0_PERIPH_REQ_SET (1 << 0)
+#define CR0_BOOT_EN_SET (1 << 1)
+#define CR0_BOOT_MAN_NS (1 << 2)
+#define CR0_NUM_CHANS_SHIFT 4
+#define CR0_NUM_CHANS_MASK 0x7
+#define CR0_NUM_PERIPH_SHIFT 12
+#define CR0_NUM_PERIPH_MASK 0x1f
+#define CR0_NUM_EVENTS_SHIFT 17
+#define CR0_NUM_EVENTS_MASK 0x1f
+
+#define CR1_ICACHE_LEN_SHIFT 0
+#define CR1_ICACHE_LEN_MASK 0x7
+#define CR1_NUM_ICACHELINES_SHIFT 4
+#define CR1_NUM_ICACHELINES_MASK 0xf
+
+#define CRD_DATA_WIDTH_SHIFT 0
+#define CRD_DATA_WIDTH_MASK 0x7
+#define CRD_WR_CAP_SHIFT 4
+#define CRD_WR_CAP_MASK 0x7
+#define CRD_WR_Q_DEP_SHIFT 8
+#define CRD_WR_Q_DEP_MASK 0xf
+#define CRD_RD_CAP_SHIFT 12
+#define CRD_RD_CAP_MASK 0x7
+#define CRD_RD_Q_DEP_SHIFT 16
+#define CRD_RD_Q_DEP_MASK 0xf
+#define CRD_DATA_BUFF_SHIFT 20
+#define CRD_DATA_BUFF_MASK 0x3ff
+
+#define PART 0x330
+#define DESIGNER 0x41
+#define REVISION 0x0
+#define INTEG_CFG 0x0
+#define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12))
+
+#define PCELL_ID_VAL 0xb105f00d
+
+#define PL330_STATE_STOPPED (1 << 0)
+#define PL330_STATE_EXECUTING (1 << 1)
+#define PL330_STATE_WFE (1 << 2)
+#define PL330_STATE_FAULTING (1 << 3)
+#define PL330_STATE_COMPLETING (1 << 4)
+#define PL330_STATE_WFP (1 << 5)
+#define PL330_STATE_KILLING (1 << 6)
+#define PL330_STATE_FAULT_COMPLETING (1 << 7)
+#define PL330_STATE_CACHEMISS (1 << 8)
+#define PL330_STATE_UPDTPC (1 << 9)
+#define PL330_STATE_ATBARRIER (1 << 10)
+#define PL330_STATE_QUEUEBUSY (1 << 11)
+#define PL330_STATE_INVALID (1 << 15)
+
+#define PL330_STABLE_STATES (PL330_STATE_STOPPED | PL330_STATE_EXECUTING \
+ | PL330_STATE_WFE | PL330_STATE_FAULTING)
+
+#define CMD_DMAADDH 0x54
+#define CMD_DMAEND 0x00
+#define CMD_DMAFLUSHP 0x35
+#define CMD_DMAGO 0xa0
+#define CMD_DMALD 0x04
+#define CMD_DMALDP 0x25
+#define CMD_DMALP 0x20
+#define CMD_DMALPEND 0x28
+#define CMD_DMAKILL 0x01
+#define CMD_DMAMOV 0xbc
+#define CMD_DMANOP 0x18
+#define CMD_DMARMB 0x12
+#define CMD_DMASEV 0x34
+#define CMD_DMAST 0x08
+#define CMD_DMASTP 0x29
+#define CMD_DMASTZ 0x0c
+#define CMD_DMAWFE 0x36
+#define CMD_DMAWFP 0x30
+#define CMD_DMAWMB 0x13
+
+#define SZ_DMAADDH 3
+#define SZ_DMAEND 1
+#define SZ_DMAFLUSHP 2
+#define SZ_DMALD 1
+#define SZ_DMALDP 2
+#define SZ_DMALP 2
+#define SZ_DMALPEND 2
+#define SZ_DMAKILL 1
+#define SZ_DMAMOV 6
+#define SZ_DMANOP 1
+#define SZ_DMARMB 1
+#define SZ_DMASEV 2
+#define SZ_DMAST 1
+#define SZ_DMASTP 2
+#define SZ_DMASTZ 1
+#define SZ_DMAWFE 2
+#define SZ_DMAWFP 2
+#define SZ_DMAWMB 1
+#define SZ_DMAGO 6
+
+#define BRST_LEN(ccr) ((((ccr) >> CC_SRCBRSTLEN_SHFT) & 0xf) + 1)
+#define BRST_SIZE(ccr) (1 << (((ccr) >> CC_SRCBRSTSIZE_SHFT) & 0x7))
+
+#define BYTE_TO_BURST(b, ccr) ((b) / BRST_SIZE(ccr) / BRST_LEN(ccr))
+#define BURST_TO_BYTE(c, ccr) ((c) * BRST_SIZE(ccr) * BRST_LEN(ccr))
+
+/*
+ * With 256 bytes, we can do more than 2.5MB and 5MB xfers per req
+ * at 1byte/burst for P<->M and M<->M respectively.
+ * For typical scenario, at 1word/burst, 10MB and 20MB xfers per req
+ * should be enough for P<->M and M<->M respectively.
+ */
+#define MCODE_BUFF_PER_REQ 256
+
+/*
+ * Mark a _pl330_req as free.
+ * We do it by writing DMAEND as the first instruction
+ * because no valid request is going to have DMAEND as
+ * its first instruction to execute.
+ */
+#define MARK_FREE(req) do { \
+ _emit_END(0, (req)->mc_cpu); \
+ (req)->mc_len = 0; \
+ } while (0)
+
+/* If the _pl330_req is available to the client */
+#define IS_FREE(req) (*((u8 *)((req)->mc_cpu)) == CMD_DMAEND)
+
+/* Use this _only_ to wait on transient states */
+#define UNTIL(t, s) while (!(_state(t) & (s))) cpu_relax();
+
+#ifdef PL330_DEBUG_MCGEN
+static unsigned cmd_line;
+#define PL330_DBGCMD_DUMP(off, x...) do { \
+ printk("%x:", cmd_line); \
+ printk(x); \
+ cmd_line += off; \
+ } while (0)
+#define PL330_DBGMC_START(addr) (cmd_line = addr)
+#else
+#define PL330_DBGCMD_DUMP(off, x...) do {} while (0)
+#define PL330_DBGMC_START(addr) do {} while (0)
+#endif
+
+struct _xfer_spec {
+ u32 ccr;
+ struct pl330_req *r;
+ struct pl330_xfer *x;
+};
+
+enum dmamov_dst {
+ SAR = 0,
+ CCR,
+ DAR,
+};
+
+enum pl330_dst {
+ SRC = 0,
+ DST,
+};
+
+enum pl330_cond {
+ SINGLE,
+ BURST,
+ ALWAYS,
+};
+
+struct _pl330_req {
+ u32 mc_bus;
+ void *mc_cpu;
+ /* Number of bytes taken to setup MC for the req */
+ u32 mc_len;
+ struct pl330_req *r;
+ /* Hook to attach to DMAC's list of reqs with due callback */
+ struct list_head rqd;
+};
+
+/* ToBeDone for tasklet */
+struct _pl330_tbd {
+ bool reset_dmac;
+ bool reset_mngr;
+ u8 reset_chan;
+};
+
+/* A DMAC Thread */
+struct pl330_thread {
+ u8 id;
+ int ev;
+ /* If the channel is not yet acquired by any client */
+ bool free;
+ /* Parent DMAC */
+ struct pl330_dmac *dmac;
+ /* Only two at a time */
+ struct _pl330_req req[2];
+ /* Index of the last submitted request */
+ unsigned lstenq;
+};
+
+enum pl330_dmac_state {
+ UNINIT,
+ INIT,
+ DYING,
+};
+
+/* A DMAC */
+struct pl330_dmac {
+ spinlock_t lock;
+ /* Holds list of reqs with due callbacks */
+ struct list_head req_done;
+ /* Pointer to platform specific stuff */
+ struct pl330_info *pinfo;
+ /* Maximum possible events/irqs */
+ int events[32];
+ /* BUS address of MicroCode buffer */
+ u32 mcode_bus;
+ /* CPU address of MicroCode buffer */
+ void *mcode_cpu;
+ /* List of all Channel threads */
+ struct pl330_thread *channels;
+ /* Pointer to the MANAGER thread */
+ struct pl330_thread *manager;
+ /* To handle bad news in interrupt */
+ struct tasklet_struct tasks;
+ struct _pl330_tbd dmac_tbd;
+ /* State of DMAC operation */
+ enum pl330_dmac_state state;
+};
+
+static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
+{
+ if (r && r->xfer_cb)
+ r->xfer_cb(r->token, err);
+}
+
+static inline bool _queue_empty(struct pl330_thread *thrd)
+{
+ return (IS_FREE(&thrd->req[0]) && IS_FREE(&thrd->req[1]))
+ ? true : false;
+}
+
+static inline bool _queue_full(struct pl330_thread *thrd)
+{
+ return (IS_FREE(&thrd->req[0]) || IS_FREE(&thrd->req[1]))
+ ? false : true;
+}
+
+static inline bool is_manager(struct pl330_thread *thrd)
+{
+ struct pl330_dmac *pl330 = thrd->dmac;
+
+ /* MANAGER is indexed at the end */
+ if (thrd->id == pl330->pinfo->pcfg.num_chan)
+ return true;
+ else
+ return false;
+}
+
+/* If manager of the thread is in Non-Secure mode */
+static inline bool _manager_ns(struct pl330_thread *thrd)
+{
+ struct pl330_dmac *pl330 = thrd->dmac;
+
+ return (pl330->pinfo->pcfg.mode & DMAC_MODE_NS) ? true : false;
+}
+
+static inline u32 get_id(struct pl330_info *pi, u32 off)
+{
+ void __iomem *regs = pi->base;
+ u32 id = 0;
+
+ id |= (readb(regs + off + 0x0) << 0);
+ id |= (readb(regs + off + 0x4) << 8);
+ id |= (readb(regs + off + 0x8) << 16);
+ id |= (readb(regs + off + 0xc) << 24);
+
+ return id;
+}
+
+static inline u32 _emit_ADDH(unsigned dry_run, u8 buf[],
+ enum pl330_dst da, u16 val)
+{
+ if (dry_run)
+ return SZ_DMAADDH;
+
+ buf[0] = CMD_DMAADDH;
+ buf[0] |= (da << 1);
+ *((u16 *)&buf[1]) = val;
+
+ PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
+ da == 1 ? "DA" : "SA", val);
+
+ return SZ_DMAADDH;
+}
+
+static inline u32 _emit_END(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMAEND;
+
+ buf[0] = CMD_DMAEND;
+
+ PL330_DBGCMD_DUMP(SZ_DMAEND, "\tDMAEND\n");
+
+ return SZ_DMAEND;
+}
+
+static inline u32 _emit_FLUSHP(unsigned dry_run, u8 buf[], u8 peri)
+{
+ if (dry_run)
+ return SZ_DMAFLUSHP;
+
+ buf[0] = CMD_DMAFLUSHP;
+
+ peri &= 0x1f;
+ peri <<= 3;
+ buf[1] = peri;
+
+ PL330_DBGCMD_DUMP(SZ_DMAFLUSHP, "\tDMAFLUSHP %u\n", peri >> 3);
+
+ return SZ_DMAFLUSHP;
+}
+
+static inline u32 _emit_LD(unsigned dry_run, u8 buf[], enum pl330_cond cond)
+{
+ if (dry_run)
+ return SZ_DMALD;
+
+ buf[0] = CMD_DMALD;
+
+ if (cond == SINGLE)
+ buf[0] |= (0 << 1) | (1 << 0);
+ else if (cond == BURST)
+ buf[0] |= (1 << 1) | (1 << 0);
+
+ PL330_DBGCMD_DUMP(SZ_DMALD, "\tDMALD%c\n",
+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+ return SZ_DMALD;
+}
+
+static inline u32 _emit_LDP(unsigned dry_run, u8 buf[],
+ enum pl330_cond cond, u8 peri)
+{
+ if (dry_run)
+ return SZ_DMALDP;
+
+ buf[0] = CMD_DMALDP;
+
+ if (cond == BURST)
+ buf[0] |= (1 << 1);
+
+ peri &= 0x1f;
+ peri <<= 3;
+ buf[1] = peri;
+
+ PL330_DBGCMD_DUMP(SZ_DMALDP, "\tDMALDP%c %u\n",
+ cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+ return SZ_DMALDP;
+}
+
+static inline u32 _emit_LP(unsigned dry_run, u8 buf[],
+ unsigned loop, u8 cnt)
+{
+ if (dry_run)
+ return SZ_DMALP;
+
+ buf[0] = CMD_DMALP;
+
+ if (loop)
+ buf[0] |= (1 << 1);
+
+ cnt--; /* DMAC increments by 1 internally */
+ buf[1] = cnt;
+
+ PL330_DBGCMD_DUMP(SZ_DMALP, "\tDMALP_%c %u\n", loop ? '1' : '0', cnt);
+
+ return SZ_DMALP;
+}
+
+struct _arg_LPEND {
+ enum pl330_cond cond;
+ bool forever;
+ unsigned loop;
+ u8 bjump;
+};
+
+static inline u32 _emit_LPEND(unsigned dry_run, u8 buf[],
+ const struct _arg_LPEND *arg)
+{
+ enum pl330_cond cond = arg->cond;
+ bool forever = arg->forever;
+ unsigned loop = arg->loop;
+ u8 bjump = arg->bjump;
+
+ if (dry_run)
+ return SZ_DMALPEND;
+
+ buf[0] = CMD_DMALPEND;
+
+ if (loop)
+ buf[0] |= (1 << 2);
+
+ if (!forever)
+ buf[0] |= (1 << 4);
+
+ if (cond == SINGLE)
+ buf[0] |= (0 << 1) | (1 << 0);
+ else if (cond == BURST)
+ buf[0] |= (1 << 1) | (1 << 0);
+
+ buf[1] = bjump;
+
+ PL330_DBGCMD_DUMP(SZ_DMALPEND, "\tDMALP%s%c_%c bjmpto_%x\n",
+ forever ? "FE" : "END",
+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'),
+ loop ? '1' : '0',
+ bjump);
+
+ return SZ_DMALPEND;
+}
+
+static inline u32 _emit_KILL(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMAKILL;
+
+ buf[0] = CMD_DMAKILL;
+
+ return SZ_DMAKILL;
+}
+
+static inline u32 _emit_MOV(unsigned dry_run, u8 buf[],
+ enum dmamov_dst dst, u32 val)
+{
+ if (dry_run)
+ return SZ_DMAMOV;
+
+ buf[0] = CMD_DMAMOV;
+ buf[1] = dst;
+ *((u32 *)&buf[2]) = val;
+
+ PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
+ dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
+
+ return SZ_DMAMOV;
+}
+
+static inline u32 _emit_NOP(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMANOP;
+
+ buf[0] = CMD_DMANOP;
+
+ PL330_DBGCMD_DUMP(SZ_DMANOP, "\tDMANOP\n");
+
+ return SZ_DMANOP;
+}
+
+static inline u32 _emit_RMB(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMARMB;
+
+ buf[0] = CMD_DMARMB;
+
+ PL330_DBGCMD_DUMP(SZ_DMARMB, "\tDMARMB\n");
+
+ return SZ_DMARMB;
+}
+
+static inline u32 _emit_SEV(unsigned dry_run, u8 buf[], u8 ev)
+{
+ if (dry_run)
+ return SZ_DMASEV;
+
+ buf[0] = CMD_DMASEV;
+
+ ev &= 0x1f;
+ ev <<= 3;
+ buf[1] = ev;
+
+ PL330_DBGCMD_DUMP(SZ_DMASEV, "\tDMASEV %u\n", ev >> 3);
+
+ return SZ_DMASEV;
+}
+
+static inline u32 _emit_ST(unsigned dry_run, u8 buf[], enum pl330_cond cond)
+{
+ if (dry_run)
+ return SZ_DMAST;
+
+ buf[0] = CMD_DMAST;
+
+ if (cond == SINGLE)
+ buf[0] |= (0 << 1) | (1 << 0);
+ else if (cond == BURST)
+ buf[0] |= (1 << 1) | (1 << 0);
+
+ PL330_DBGCMD_DUMP(SZ_DMAST, "\tDMAST%c\n",
+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'A'));
+
+ return SZ_DMAST;
+}
+
+static inline u32 _emit_STP(unsigned dry_run, u8 buf[],
+ enum pl330_cond cond, u8 peri)
+{
+ if (dry_run)
+ return SZ_DMASTP;
+
+ buf[0] = CMD_DMASTP;
+
+ if (cond == BURST)
+ buf[0] |= (1 << 1);
+
+ peri &= 0x1f;
+ peri <<= 3;
+ buf[1] = peri;
+
+ PL330_DBGCMD_DUMP(SZ_DMASTP, "\tDMASTP%c %u\n",
+ cond == SINGLE ? 'S' : 'B', peri >> 3);
+
+ return SZ_DMASTP;
+}
+
+static inline u32 _emit_STZ(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMASTZ;
+
+ buf[0] = CMD_DMASTZ;
+
+ PL330_DBGCMD_DUMP(SZ_DMASTZ, "\tDMASTZ\n");
+
+ return SZ_DMASTZ;
+}
+
+static inline u32 _emit_WFE(unsigned dry_run, u8 buf[], u8 ev,
+ unsigned invalidate)
+{
+ if (dry_run)
+ return SZ_DMAWFE;
+
+ buf[0] = CMD_DMAWFE;
+
+ ev &= 0x1f;
+ ev <<= 3;
+ buf[1] = ev;
+
+ if (invalidate)
+ buf[1] |= (1 << 1);
+
+ PL330_DBGCMD_DUMP(SZ_DMAWFE, "\tDMAWFE %u%s\n",
+ ev >> 3, invalidate ? ", I" : "");
+
+ return SZ_DMAWFE;
+}
+
+static inline u32 _emit_WFP(unsigned dry_run, u8 buf[],
+ enum pl330_cond cond, u8 peri)
+{
+ if (dry_run)
+ return SZ_DMAWFP;
+
+ buf[0] = CMD_DMAWFP;
+
+ if (cond == SINGLE)
+ buf[0] |= (0 << 1) | (0 << 0);
+ else if (cond == BURST)
+ buf[0] |= (1 << 1) | (0 << 0);
+ else
+ buf[0] |= (0 << 1) | (1 << 0);
+
+ peri &= 0x1f;
+ peri <<= 3;
+ buf[1] = peri;
+
+ PL330_DBGCMD_DUMP(SZ_DMAWFP, "\tDMAWFP%c %u\n",
+ cond == SINGLE ? 'S' : (cond == BURST ? 'B' : 'P'), peri >> 3);
+
+ return SZ_DMAWFP;
+}
+
+static inline u32 _emit_WMB(unsigned dry_run, u8 buf[])
+{
+ if (dry_run)
+ return SZ_DMAWMB;
+
+ buf[0] = CMD_DMAWMB;
+
+ PL330_DBGCMD_DUMP(SZ_DMAWMB, "\tDMAWMB\n");
+
+ return SZ_DMAWMB;
+}
+
+struct _arg_GO {
+ u8 chan;
+ u32 addr;
+ unsigned ns;
+};
+
+static inline u32 _emit_GO(unsigned dry_run, u8 buf[],
+ const struct _arg_GO *arg)
+{
+ u8 chan = arg->chan;
+ u32 addr = arg->addr;
+ unsigned ns = arg->ns;
+
+ if (dry_run)
+ return SZ_DMAGO;
+
+ buf[0] = CMD_DMAGO;
+ buf[0] |= (ns << 1);
+
+ buf[1] = chan & 0x7;
+
+ *((u32 *)&buf[2]) = addr;
+
+ return SZ_DMAGO;
+}
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+/* Returns Time-Out */
+static bool _until_dmac_idle(struct pl330_thread *thrd)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ unsigned long loops = msecs_to_loops(5);
+
+ do {
+ /* Until Manager is Idle */
+ if (!(readl(regs + DBGSTATUS) & DBG_BUSY))
+ break;
+
+ cpu_relax();
+ } while (--loops);
+
+ if (!loops)
+ return true;
+
+ return false;
+}
+
+static inline void _execute_DBGINSN(struct pl330_thread *thrd,
+ u8 insn[], bool as_manager)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ u32 val;
+
+ val = (insn[0] << 16) | (insn[1] << 24);
+ if (!as_manager) {
+ val |= (1 << 0);
+ val |= (thrd->id << 8); /* Channel Number */
+ }
+ writel(val, regs + DBGINST0);
+
+ val = *((u32 *)&insn[2]);
+ writel(val, regs + DBGINST1);
+
+ /* If timed out due to halted state-machine */
+ if (_until_dmac_idle(thrd)) {
+ dev_err(thrd->dmac->pinfo->dev, "DMAC halted!\n");
+ return;
+ }
+
+ /* Get going */
+ writel(0, regs + DBGCMD);
+}
+
+static inline u32 _state(struct pl330_thread *thrd)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ u32 val;
+
+ if (is_manager(thrd))
+ val = readl(regs + DS) & 0xf;
+ else
+ val = readl(regs + CS(thrd->id)) & 0xf;
+
+ switch (val) {
+ case DS_ST_STOP:
+ return PL330_STATE_STOPPED;
+ case DS_ST_EXEC:
+ return PL330_STATE_EXECUTING;
+ case DS_ST_CMISS:
+ return PL330_STATE_CACHEMISS;
+ case DS_ST_UPDTPC:
+ return PL330_STATE_UPDTPC;
+ case DS_ST_WFE:
+ return PL330_STATE_WFE;
+ case DS_ST_FAULT:
+ return PL330_STATE_FAULTING;
+ case DS_ST_ATBRR:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_ATBARRIER;
+ case DS_ST_QBUSY:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_QUEUEBUSY;
+ case DS_ST_WFP:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_WFP;
+ case DS_ST_KILL:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_KILLING;
+ case DS_ST_CMPLT:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_COMPLETING;
+ case DS_ST_FLTCMP:
+ if (is_manager(thrd))
+ return PL330_STATE_INVALID;
+ else
+ return PL330_STATE_FAULT_COMPLETING;
+ default:
+ return PL330_STATE_INVALID;
+ }
+}
+
+/* If the request 'req' of thread 'thrd' is currently active */
+static inline bool _req_active(struct pl330_thread *thrd,
+ struct _pl330_req *req)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ u32 buf = req->mc_bus, pc = readl(regs + CPC(thrd->id));
+
+ if (IS_FREE(req))
+ return false;
+
+ return (pc >= buf && pc <= buf + req->mc_len) ? true : false;
+}
+
+/* Returns 0 if the thread is inactive, ID of active req + 1 otherwise */
+static inline unsigned _thrd_active(struct pl330_thread *thrd)
+{
+ if (_req_active(thrd, &thrd->req[0]))
+ return 1; /* First req active */
+
+ if (_req_active(thrd, &thrd->req[1]))
+ return 2; /* Second req active */
+
+ return 0;
+}
+
+static void _stop(struct pl330_thread *thrd)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+ if (_state(thrd) == PL330_STATE_FAULT_COMPLETING)
+ UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+ /* Return if nothing needs to be done */
+ if (_state(thrd) == PL330_STATE_COMPLETING
+ || _state(thrd) == PL330_STATE_KILLING
+ || _state(thrd) == PL330_STATE_STOPPED)
+ return;
+
+ _emit_KILL(0, insn);
+
+ /* Stop generating interrupts for SEV */
+ writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN);
+
+ _execute_DBGINSN(thrd, insn, is_manager(thrd));
+}
+
+/* Start doing req 'idx' of thread 'thrd' */
+static bool _trigger(struct pl330_thread *thrd)
+{
+ void __iomem *regs = thrd->dmac->pinfo->base;
+ struct _pl330_req *req;
+ struct pl330_req *r;
+ struct _arg_GO go;
+ unsigned ns;
+ u8 insn[6] = {0, 0, 0, 0, 0, 0};
+
+ /* Return if already ACTIVE */
+ if (_state(thrd) != PL330_STATE_STOPPED)
+ return true;
+
+ if (!IS_FREE(&thrd->req[1 - thrd->lstenq]))
+ req = &thrd->req[1 - thrd->lstenq];
+ else if (!IS_FREE(&thrd->req[thrd->lstenq]))
+ req = &thrd->req[thrd->lstenq];
+ else
+ req = NULL;
+
+ /* Return if no request */
+ if (!req || !req->r)
+ return true;
+
+ r = req->r;
+
+ if (r->cfg)
+ ns = r->cfg->nonsecure ? 1 : 0;
+ else if (readl(regs + CS(thrd->id)) & CS_CNS)
+ ns = 1;
+ else
+ ns = 0;
+
+ /* See 'Abort Sources' point-4 at Page 2-25 */
+ if (_manager_ns(thrd) && !ns)
+ dev_info(thrd->dmac->pinfo->dev, "%s:%d Recipe for ABORT!\n",
+ __func__, __LINE__);
+
+ go.chan = thrd->id;
+ go.addr = req->mc_bus;
+ go.ns = ns;
+ _emit_GO(0, insn, &go);
+
+ /* Set to generate interrupts for SEV */
+ writel(readl(regs + INTEN) | (1 << thrd->ev), regs + INTEN);
+
+ /* Only manager can execute GO */
+ _execute_DBGINSN(thrd, insn, true);
+
+ return true;
+}
+
+static bool _start(struct pl330_thread *thrd)
+{
+ switch (_state(thrd)) {
+ case PL330_STATE_FAULT_COMPLETING:
+ UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING);
+
+ if (_state(thrd) == PL330_STATE_KILLING)
+ UNTIL(thrd, PL330_STATE_STOPPED)
+
+ case PL330_STATE_FAULTING:
+ _stop(thrd);
+
+ case PL330_STATE_KILLING:
+ case PL330_STATE_COMPLETING:
+ UNTIL(thrd, PL330_STATE_STOPPED)
+
+ case PL330_STATE_STOPPED:
+ return _trigger(thrd);
+
+ case PL330_STATE_WFP:
+ case PL330_STATE_QUEUEBUSY:
+ case PL330_STATE_ATBARRIER:
+ case PL330_STATE_UPDTPC:
+ case PL330_STATE_CACHEMISS:
+ case PL330_STATE_EXECUTING:
+ return true;
+
+ case PL330_STATE_WFE: /* For RESUME, nothing yet */
+ default:
+ return false;
+ }
+}
+
+static inline int _ldst_memtomem(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int cyc)
+{
+ int off = 0;
+
+ while (cyc--) {
+ off += _emit_LD(dry_run, &buf[off], ALWAYS);
+ off += _emit_RMB(dry_run, &buf[off]);
+ off += _emit_ST(dry_run, &buf[off], ALWAYS);
+ off += _emit_WMB(dry_run, &buf[off]);
+ }
+
+ return off;
+}
+
+static inline int _ldst_devtomem(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int cyc)
+{
+ int off = 0;
+
+ while (cyc--) {
+ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+ off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+ off += _emit_ST(dry_run, &buf[off], ALWAYS);
+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+ }
+
+ return off;
+}
+
+static inline int _ldst_memtodev(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int cyc)
+{
+ int off = 0;
+
+ while (cyc--) {
+ off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+ off += _emit_LD(dry_run, &buf[off], ALWAYS);
+ off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri);
+ off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
+ }
+
+ return off;
+}
+
+static int _bursts(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs, int cyc)
+{
+ int off = 0;
+
+ switch (pxs->r->rqtype) {
+ case MEMTODEV:
+ off += _ldst_memtodev(dry_run, &buf[off], pxs, cyc);
+ break;
+ case DEVTOMEM:
+ off += _ldst_devtomem(dry_run, &buf[off], pxs, cyc);
+ break;
+ case MEMTOMEM:
+ off += _ldst_memtomem(dry_run, &buf[off], pxs, cyc);
+ break;
+ default:
+ off += 0x40000000; /* Scare off the Client */
+ break;
+ }
+
+ return off;
+}
+
+/* Returns bytes consumed and updates bursts */
+static inline int _loop(unsigned dry_run, u8 buf[],
+ unsigned long *bursts, const struct _xfer_spec *pxs)
+{
+ int cyc, cycmax, szlp, szlpend, szbrst, off;
+ unsigned lcnt0, lcnt1, ljmp0, ljmp1;
+ struct _arg_LPEND lpend;
+
+ /* Max iterations possible in DMALP is 256 */
+ if (*bursts >= 256*256) {
+ lcnt1 = 256;
+ lcnt0 = 256;
+ cyc = *bursts / lcnt1 / lcnt0;
+ } else if (*bursts > 256) {
+ lcnt1 = 256;
+ lcnt0 = *bursts / lcnt1;
+ cyc = 1;
+ } else {
+ lcnt1 = *bursts;
+ lcnt0 = 0;
+ cyc = 1;
+ }
+
+ szlp = _emit_LP(1, buf, 0, 0);
+ szbrst = _bursts(1, buf, pxs, 1);
+
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 0;
+ lpend.bjump = 0;
+ szlpend = _emit_LPEND(1, buf, &lpend);
+
+ if (lcnt0) {
+ szlp *= 2;
+ szlpend *= 2;
+ }
+
+ /*
+ * Max bursts that we can unroll due to limit on the
+ * size of backward jump that can be encoded in DMALPEND
+ * which is 8-bits and hence 255
+ */
+ cycmax = (255 - (szlp + szlpend)) / szbrst;
+
+ cyc = (cycmax < cyc) ? cycmax : cyc;
+
+ off = 0;
+
+ if (lcnt0) {
+ off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
+ ljmp0 = off;
+ }
+
+ 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);
+
+ if (lcnt0) {
+ lpend.cond = ALWAYS;
+ lpend.forever = false;
+ lpend.loop = 0;
+ lpend.bjump = off - ljmp0;
+ off += _emit_LPEND(dry_run, &buf[off], &lpend);
+ }
+
+ *bursts = lcnt1 * cyc;
+ if (lcnt0)
+ *bursts *= lcnt0;
+
+ return off;
+}
+
+static inline int _setup_loops(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs)
+{
+ struct pl330_xfer *x = pxs->x;
+ u32 ccr = pxs->ccr;
+ unsigned long c, bursts = BYTE_TO_BURST(x->bytes, ccr);
+ int off = 0;
+
+ while (bursts) {
+ c = bursts;
+ off += _loop(dry_run, &buf[off], &c, pxs);
+ bursts -= c;
+ }
+
+ return off;
+}
+
+static inline int _setup_xfer(unsigned dry_run, u8 buf[],
+ const struct _xfer_spec *pxs)
+{
+ struct pl330_xfer *x = pxs->x;
+ int off = 0;
+
+ /* DMAMOV SAR, x->src_addr */
+ off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr);
+ /* DMAMOV DAR, x->dst_addr */
+ off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr);
+
+ /* Setup Loop(s) */
+ off += _setup_loops(dry_run, &buf[off], pxs);
+
+ 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.
+ */
+static int _setup_req(unsigned dry_run, struct pl330_thread *thrd,
+ unsigned index, struct _xfer_spec *pxs)
+{
+ struct _pl330_req *req = &thrd->req[index];
+ struct pl330_xfer *x;
+ u8 *buf = req->mc_cpu;
+ int off = 0;
+
+ PL330_DBGMC_START(req->mc_bus);
+
+ /* DMAMOV CCR, ccr */
+ off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
+
+ x = pxs->r->x;
+ 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]);
+
+ return off;
+}
+
+static inline u32 _prepare_ccr(const struct pl330_reqcfg *rqc)
+{
+ u32 ccr = 0;
+
+ if (rqc->src_inc)
+ ccr |= CC_SRCINC;
+
+ if (rqc->dst_inc)
+ ccr |= CC_DSTINC;
+
+ /* We set same protection levels for Src and DST for now */
+ if (rqc->privileged)
+ ccr |= CC_SRCPRI | CC_DSTPRI;
+ if (rqc->nonsecure)
+ ccr |= CC_SRCNS | CC_DSTNS;
+ if (rqc->insnaccess)
+ ccr |= CC_SRCIA | CC_DSTIA;
+
+ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_SRCBRSTLEN_SHFT);
+ ccr |= (((rqc->brst_len - 1) & 0xf) << CC_DSTBRSTLEN_SHFT);
+
+ ccr |= (rqc->brst_size << CC_SRCBRSTSIZE_SHFT);
+ ccr |= (rqc->brst_size << CC_DSTBRSTSIZE_SHFT);
+
+ ccr |= (rqc->dcctl << CC_SRCCCTRL_SHFT);
+ ccr |= (rqc->scctl << CC_DSTCCTRL_SHFT);
+
+ ccr |= (rqc->swap << CC_SWAP_SHFT);
+
+ return ccr;
+}
+
+static inline bool _is_valid(u32 ccr)
+{
+ enum pl330_dstcachectrl dcctl;
+ enum pl330_srccachectrl scctl;
+
+ dcctl = (ccr >> CC_DSTCCTRL_SHFT) & CC_DRCCCTRL_MASK;
+ scctl = (ccr >> CC_SRCCCTRL_SHFT) & CC_SRCCCTRL_MASK;
+
+ if (dcctl == DINVALID1 || dcctl == DINVALID2
+ || scctl == SINVALID1 || scctl == SINVALID2)
+ return false;
+ else
+ return true;
+}
+
+/*
+ * Submit a list of xfers after which the client wants notification.
+ * Client is not notified after each xfer unit, just once after all
+ * xfer units are done or some error occurs.
+ */
+int pl330_submit_req(void *ch_id, struct pl330_req *r)
+{
+ struct pl330_thread *thrd = ch_id;
+ struct pl330_dmac *pl330;
+ struct pl330_info *pi;
+ struct _xfer_spec xs;
+ unsigned long flags;
+ void __iomem *regs;
+ unsigned idx;
+ u32 ccr;
+ int ret = 0;
+
+ /* No Req or Unacquired Channel or DMAC */
+ if (!r || !thrd || thrd->free)
+ return -EINVAL;
+
+ pl330 = thrd->dmac;
+ pi = pl330->pinfo;
+ regs = pi->base;
+
+ if (pl330->state == DYING
+ || pl330->dmac_tbd.reset_chan & (1 << thrd->id)) {
+ dev_info(thrd->dmac->pinfo->dev, "%s:%d\n",
+ __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ /* If request for non-existing peripheral */
+ if (r->rqtype != MEMTOMEM && r->peri >= pi->pcfg.num_peri) {
+ dev_info(thrd->dmac->pinfo->dev,
+ "%s:%d Invalid peripheral(%u)!\n",
+ __func__, __LINE__, r->peri);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ if (_queue_full(thrd)) {
+ ret = -EAGAIN;
+ 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)
+ ccr = _prepare_ccr(r->cfg);
+ else
+ ccr = readl(regs + CC(thrd->id));
+
+ /* If this req doesn't have valid xfer settings */
+ if (!_is_valid(ccr)) {
+ ret = -EINVAL;
+ dev_info(thrd->dmac->pinfo->dev, "%s:%d Invalid CCR(%x)!\n",
+ __func__, __LINE__, ccr);
+ goto xfer_exit;
+ }
+
+ idx = IS_FREE(&thrd->req[0]) ? 0 : 1;
+
+ xs.ccr = ccr;
+ xs.r = r;
+
+ /* First dry run to check if req is acceptable */
+ ret = _setup_req(1, thrd, idx, &xs);
+ if (ret < 0)
+ goto xfer_exit;
+
+ if (ret > pi->mcbufsz / 2) {
+ dev_info(thrd->dmac->pinfo->dev,
+ "%s:%d Trying increasing mcbufsz\n",
+ __func__, __LINE__);
+ ret = -ENOMEM;
+ goto xfer_exit;
+ }
+
+ /* Hook the request */
+ thrd->lstenq = idx;
+ thrd->req[idx].mc_len = _setup_req(0, thrd, idx, &xs);
+ thrd->req[idx].r = r;
+
+ ret = 0;
+
+xfer_exit:
+ spin_unlock_irqrestore(&pl330->lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(pl330_submit_req);
+
+static void pl330_dotask(unsigned long data)
+{
+ struct pl330_dmac *pl330 = (struct pl330_dmac *) data;
+ struct pl330_info *pi = pl330->pinfo;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ /* The DMAC itself gone nuts */
+ if (pl330->dmac_tbd.reset_dmac) {
+ pl330->state = DYING;
+ /* Reset the manager too */
+ pl330->dmac_tbd.reset_mngr = true;
+ /* Clear the reset flag */
+ pl330->dmac_tbd.reset_dmac = false;
+ }
+
+ if (pl330->dmac_tbd.reset_mngr) {
+ _stop(pl330->manager);
+ /* Reset all channels */
+ pl330->dmac_tbd.reset_chan = (1 << pi->pcfg.num_chan) - 1;
+ /* Clear the reset flag */
+ pl330->dmac_tbd.reset_mngr = false;
+ }
+
+ for (i = 0; i < pi->pcfg.num_chan; i++) {
+
+ if (pl330->dmac_tbd.reset_chan & (1 << i)) {
+ struct pl330_thread *thrd = &pl330->channels[i];
+ void __iomem *regs = pi->base;
+ enum pl330_op_err err;
+
+ _stop(thrd);
+
+ if (readl(regs + FSC) & (1 << thrd->id))
+ err = PL330_ERR_FAIL;
+ else
+ err = PL330_ERR_ABORT;
+
+ spin_unlock_irqrestore(&pl330->lock, flags);
+
+ _callback(thrd->req[1 - thrd->lstenq].r, err);
+ _callback(thrd->req[thrd->lstenq].r, err);
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ thrd->req[0].r = NULL;
+ thrd->req[1].r = NULL;
+ MARK_FREE(&thrd->req[0]);
+ MARK_FREE(&thrd->req[1]);
+
+ /* Clear the reset flag */
+ pl330->dmac_tbd.reset_chan &= ~(1 << i);
+ }
+ }
+
+ spin_unlock_irqrestore(&pl330->lock, flags);
+
+ return;
+}
+
+/* Returns 1 if state was updated, 0 otherwise */
+int pl330_update(const struct pl330_info *pi)
+{
+ struct _pl330_req *rqdone;
+ struct pl330_dmac *pl330;
+ unsigned long flags;
+ void __iomem *regs;
+ u32 val;
+ int id, ev, ret = 0;
+
+ if (!pi || !pi->pl330_data)
+ return 0;
+
+ regs = pi->base;
+ pl330 = pi->pl330_data;
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ val = readl(regs + FSM) & 0x1;
+ if (val)
+ pl330->dmac_tbd.reset_mngr = true;
+ else
+ pl330->dmac_tbd.reset_mngr = false;
+
+ val = readl(regs + FSC) & ((1 << pi->pcfg.num_chan) - 1);
+ pl330->dmac_tbd.reset_chan |= val;
+ if (val) {
+ int i = 0;
+ while (i < pi->pcfg.num_chan) {
+ if (val & (1 << i)) {
+ dev_info(pi->dev,
+ "Reset Channel-%d\t CS-%x FTC-%x\n",
+ i, readl(regs + CS(i)),
+ readl(regs + FTC(i)));
+ _stop(&pl330->channels[i]);
+ }
+ i++;
+ }
+ }
+
+ /* Check which event happened i.e, thread notified */
+ val = readl(regs + ES);
+ if (pi->pcfg.num_events < 32
+ && val & ~((1 << pi->pcfg.num_events) - 1)) {
+ pl330->dmac_tbd.reset_dmac = true;
+ dev_err(pi->dev, "%s:%d Unexpected!\n", __func__, __LINE__);
+ ret = 1;
+ goto updt_exit;
+ }
+
+ for (ev = 0; ev < pi->pcfg.num_events; ev++) {
+ if (val & (1 << ev)) { /* Event occurred */
+ struct pl330_thread *thrd;
+ u32 inten = readl(regs + INTEN);
+ int active;
+
+ /* Clear the event */
+ if (inten & (1 << ev))
+ writel(1 << ev, regs + INTCLR);
+
+ ret = 1;
+
+ id = pl330->events[ev];
+
+ thrd = &pl330->channels[id];
+
+ active = _thrd_active(thrd);
+ if (!active) /* Aborted */
+ continue;
+
+ active -= 1;
+
+ rqdone = &thrd->req[active];
+ 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);
+ }
+ }
+
+ /* Now that we are in no hurry, do the callbacks */
+ while (!list_empty(&pl330->req_done)) {
+ rqdone = container_of(pl330->req_done.next,
+ struct _pl330_req, rqd);
+
+ list_del_init(&rqdone->rqd);
+
+ spin_unlock_irqrestore(&pl330->lock, flags);
+ _callback(rqdone->r, PL330_ERR_NONE);
+ spin_lock_irqsave(&pl330->lock, flags);
+ }
+
+updt_exit:
+ spin_unlock_irqrestore(&pl330->lock, flags);
+
+ if (pl330->dmac_tbd.reset_dmac
+ || pl330->dmac_tbd.reset_mngr
+ || pl330->dmac_tbd.reset_chan) {
+ ret = 1;
+ tasklet_schedule(&pl330->tasks);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pl330_update);
+
+int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
+{
+ struct pl330_thread *thrd = ch_id;
+ struct pl330_dmac *pl330;
+ unsigned long flags;
+ int ret = 0, active;
+
+ if (!thrd || thrd->free || thrd->dmac->state == DYING)
+ return -EINVAL;
+
+ pl330 = thrd->dmac;
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ switch (op) {
+ case PL330_OP_FLUSH:
+ /* Make sure the channel is stopped */
+ _stop(thrd);
+
+ thrd->req[0].r = NULL;
+ thrd->req[1].r = NULL;
+ MARK_FREE(&thrd->req[0]);
+ MARK_FREE(&thrd->req[1]);
+ break;
+
+ case PL330_OP_ABORT:
+ active = _thrd_active(thrd);
+
+ /* Make sure the channel is stopped */
+ _stop(thrd);
+
+ /* ABORT is only for the active req */
+ if (!active)
+ break;
+
+ active--;
+
+ thrd->req[active].r = NULL;
+ MARK_FREE(&thrd->req[active]);
+
+ /* Start the next */
+ case PL330_OP_START:
+ if (!_start(thrd))
+ ret = -EIO;
+ break;
+
+ default:
+ ret = -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&pl330->lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(pl330_chan_ctrl);
+
+int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus)
+{
+ struct pl330_thread *thrd = ch_id;
+ struct pl330_dmac *pl330;
+ struct pl330_info *pi;
+ void __iomem *regs;
+ int active;
+ u32 val;
+
+ if (!pstatus || !thrd || thrd->free)
+ return -EINVAL;
+
+ pl330 = thrd->dmac;
+ pi = pl330->pinfo;
+ regs = pi->base;
+
+ /* The client should remove the DMAC and add again */
+ if (pl330->state == DYING)
+ pstatus->dmac_halted = true;
+ else
+ pstatus->dmac_halted = false;
+
+ val = readl(regs + FSC);
+ if (val & (1 << thrd->id))
+ pstatus->faulting = true;
+ else
+ pstatus->faulting = false;
+
+ active = _thrd_active(thrd);
+
+ if (!active) {
+ /* Indicate that the thread is not running */
+ pstatus->top_req = NULL;
+ pstatus->wait_req = NULL;
+ } else {
+ active--;
+ pstatus->top_req = thrd->req[active].r;
+ pstatus->wait_req = !IS_FREE(&thrd->req[1 - active])
+ ? thrd->req[1 - active].r : NULL;
+ }
+
+ pstatus->src_addr = readl(regs + SA(thrd->id));
+ pstatus->dst_addr = readl(regs + DA(thrd->id));
+
+ return 0;
+}
+EXPORT_SYMBOL(pl330_chan_status);
+
+/* Reserve an event */
+static inline int _alloc_event(struct pl330_thread *thrd)
+{
+ struct pl330_dmac *pl330 = thrd->dmac;
+ struct pl330_info *pi = pl330->pinfo;
+ int ev;
+
+ for (ev = 0; ev < pi->pcfg.num_events; ev++)
+ if (pl330->events[ev] == -1) {
+ pl330->events[ev] = thrd->id;
+ return ev;
+ }
+
+ return -1;
+}
+
+/* Upon success, returns IdentityToken for the
+ * allocated channel, NULL otherwise.
+ */
+void *pl330_request_channel(const struct pl330_info *pi)
+{
+ struct pl330_thread *thrd = NULL;
+ struct pl330_dmac *pl330;
+ unsigned long flags;
+ int chans, i;
+
+ if (!pi || !pi->pl330_data)
+ return NULL;
+
+ pl330 = pi->pl330_data;
+
+ if (pl330->state == DYING)
+ return NULL;
+
+ chans = pi->pcfg.num_chan;
+
+ spin_lock_irqsave(&pl330->lock, flags);
+
+ for (i = 0; i < chans; i++) {
+ thrd = &pl330->channels[i];
+ if (thrd->free) {
+ thrd->ev = _alloc_event(thrd);
+ if (thrd->ev >= 0) {
+ thrd->free = false;
+ thrd->lstenq = 1;
+ thrd->req[0].r = NULL;
+ MARK_FREE(&thrd->req[0]);
+ thrd->req[1].r = NULL;
+ MARK_FREE(&thrd->req[1]);
+ break;
+ }
+ }
+ thrd = NULL;
+ }
+
+ spin_unlock_irqrestore(&pl330->lock, flags);
+
+ return thrd;
+}
+EXPORT_SYMBOL(pl330_request_channel);
+
+/* Release an event */
+static inline void _free_event(struct pl330_thread *thrd, int ev)
+{
+ struct pl330_dmac *pl330 = thrd->dmac;
+ struct pl330_info *pi = pl330->pinfo;
+
+ /* If the event is valid and was held by the thread */
+ if (ev >= 0 && ev < pi->pcfg.num_events
+ && pl330->events[ev] == thrd->id)
+ pl330->events[ev] = -1;
+}
+
+void pl330_release_channel(void *ch_id)
+{
+ struct pl330_thread *thrd = ch_id;
+ struct pl330_dmac *pl330;
+ unsigned long flags;
+
+ if (!thrd || thrd->free)
+ return;
+
+ _stop(thrd);
+
+ _callback(thrd->req[1 - thrd->lstenq].r, PL330_ERR_ABORT);
+ _callback(thrd->req[thrd->lstenq].r, PL330_ERR_ABORT);
+
+ pl330 = thrd->dmac;
+
+ spin_lock_irqsave(&pl330->lock, flags);
+ _free_event(thrd, thrd->ev);
+ thrd->free = true;
+ spin_unlock_irqrestore(&pl330->lock, flags);
+}
+EXPORT_SYMBOL(pl330_release_channel);
+
+/* Initialize the structure for PL330 configuration, that can be used
+ * by the client driver the make best use of the DMAC
+ */
+static void read_dmac_config(struct pl330_info *pi)
+{
+ void __iomem *regs = pi->base;
+ u32 val;
+
+ val = readl(regs + CRD) >> CRD_DATA_WIDTH_SHIFT;
+ val &= CRD_DATA_WIDTH_MASK;
+ pi->pcfg.data_bus_width = 8 * (1 << val);
+
+ val = readl(regs + CRD) >> CRD_DATA_BUFF_SHIFT;
+ val &= CRD_DATA_BUFF_MASK;
+ pi->pcfg.data_buf_dep = val + 1;
+
+ val = readl(regs + CR0) >> CR0_NUM_CHANS_SHIFT;
+ val &= CR0_NUM_CHANS_MASK;
+ val += 1;
+ pi->pcfg.num_chan = val;
+
+ val = readl(regs + CR0);
+ if (val & CR0_PERIPH_REQ_SET) {
+ val = (val >> CR0_NUM_PERIPH_SHIFT) & CR0_NUM_PERIPH_MASK;
+ val += 1;
+ pi->pcfg.num_peri = val;
+ pi->pcfg.peri_ns = readl(regs + CR4);
+ } else {
+ pi->pcfg.num_peri = 0;
+ }
+
+ val = readl(regs + CR0);
+ if (val & CR0_BOOT_MAN_NS)
+ pi->pcfg.mode |= DMAC_MODE_NS;
+ else
+ pi->pcfg.mode &= ~DMAC_MODE_NS;
+
+ val = readl(regs + CR0) >> CR0_NUM_EVENTS_SHIFT;
+ val &= CR0_NUM_EVENTS_MASK;
+ val += 1;
+ pi->pcfg.num_events = val;
+
+ pi->pcfg.irq_ns = readl(regs + CR3);
+
+ pi->pcfg.periph_id = get_id(pi, PERIPH_ID);
+ pi->pcfg.pcell_id = get_id(pi, PCELL_ID);
+}
+
+static inline void _reset_thread(struct pl330_thread *thrd)
+{
+ struct pl330_dmac *pl330 = thrd->dmac;
+ struct pl330_info *pi = pl330->pinfo;
+
+ thrd->req[0].mc_cpu = pl330->mcode_cpu
+ + (thrd->id * pi->mcbufsz);
+ thrd->req[0].mc_bus = pl330->mcode_bus
+ + (thrd->id * pi->mcbufsz);
+ thrd->req[0].r = NULL;
+ MARK_FREE(&thrd->req[0]);
+
+ thrd->req[1].mc_cpu = thrd->req[0].mc_cpu
+ + pi->mcbufsz / 2;
+ thrd->req[1].mc_bus = thrd->req[0].mc_bus
+ + pi->mcbufsz / 2;
+ thrd->req[1].r = NULL;
+ MARK_FREE(&thrd->req[1]);
+}
+
+static int dmac_alloc_threads(struct pl330_dmac *pl330)
+{
+ struct pl330_info *pi = pl330->pinfo;
+ int chans = pi->pcfg.num_chan;
+ struct pl330_thread *thrd;
+ int i;
+
+ /* Allocate 1 Manager and 'chans' Channel threads */
+ pl330->channels = kzalloc((1 + chans) * sizeof(*thrd),
+ GFP_KERNEL);
+ if (!pl330->channels)
+ return -ENOMEM;
+
+ /* Init Channel threads */
+ for (i = 0; i < chans; i++) {
+ thrd = &pl330->channels[i];
+ thrd->id = i;
+ thrd->dmac = pl330;
+ _reset_thread(thrd);
+ thrd->free = true;
+ }
+
+ /* MANAGER is indexed at the end */
+ thrd = &pl330->channels[chans];
+ thrd->id = chans;
+ thrd->dmac = pl330;
+ thrd->free = false;
+ pl330->manager = thrd;
+
+ return 0;
+}
+
+static int dmac_alloc_resources(struct pl330_dmac *pl330)
+{
+ struct pl330_info *pi = pl330->pinfo;
+ int chans = pi->pcfg.num_chan;
+ int ret;
+
+ /*
+ * Alloc MicroCode buffer for 'chans' Channel threads.
+ * A channel's buffer offset is (Channel_Id * MCODE_BUFF_PERCHAN)
+ */
+ pl330->mcode_cpu = dma_alloc_coherent(pi->dev,
+ chans * pi->mcbufsz,
+ &pl330->mcode_bus, GFP_KERNEL);
+ if (!pl330->mcode_cpu) {
+ dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ ret = dmac_alloc_threads(pl330);
+ if (ret) {
+ dev_err(pi->dev, "%s:%d Can't to create channels for DMAC!\n",
+ __func__, __LINE__);
+ dma_free_coherent(pi->dev,
+ chans * pi->mcbufsz,
+ pl330->mcode_cpu, pl330->mcode_bus);
+ return ret;
+ }
+
+ return 0;
+}
+
+int pl330_add(struct pl330_info *pi)
+{
+ struct pl330_dmac *pl330;
+ void __iomem *regs;
+ int i, ret;
+
+ if (!pi || !pi->dev)
+ return -EINVAL;
+
+ /* If already added */
+ if (pi->pl330_data)
+ return -EINVAL;
+
+ /*
+ * If the SoC can perform reset on the DMAC, then do it
+ * before reading its configuration.
+ */
+ if (pi->dmac_reset)
+ pi->dmac_reset(pi);
+
+ regs = pi->base;
+
+ /* Check if we can handle this DMAC */
+ if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL
+ || get_id(pi, PCELL_ID) != PCELL_ID_VAL) {
+ dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n",
+ get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID));
+ return -EINVAL;
+ }
+
+ /* Read the configuration of the DMAC */
+ read_dmac_config(pi);
+
+ if (pi->pcfg.num_events == 0) {
+ dev_err(pi->dev, "%s:%d Can't work without events!\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ pl330 = kzalloc(sizeof(*pl330), GFP_KERNEL);
+ if (!pl330) {
+ dev_err(pi->dev, "%s:%d Can't allocate memory!\n",
+ __func__, __LINE__);
+ return -ENOMEM;
+ }
+
+ /* Assign the info structure and private data */
+ pl330->pinfo = pi;
+ pi->pl330_data = pl330;
+
+ spin_lock_init(&pl330->lock);
+
+ INIT_LIST_HEAD(&pl330->req_done);
+
+ /* Use default MC buffer size if not provided */
+ if (!pi->mcbufsz)
+ pi->mcbufsz = MCODE_BUFF_PER_REQ * 2;
+
+ /* Mark all events as free */
+ for (i = 0; i < pi->pcfg.num_events; i++)
+ pl330->events[i] = -1;
+
+ /* Allocate resources needed by the DMAC */
+ ret = dmac_alloc_resources(pl330);
+ if (ret) {
+ dev_err(pi->dev, "Unable to create channels for DMAC\n");
+ kfree(pl330);
+ return ret;
+ }
+
+ tasklet_init(&pl330->tasks, pl330_dotask, (unsigned long) pl330);
+
+ pl330->state = INIT;
+
+ return 0;
+}
+EXPORT_SYMBOL(pl330_add);
+
+static int dmac_free_threads(struct pl330_dmac *pl330)
+{
+ struct pl330_info *pi = pl330->pinfo;
+ int chans = pi->pcfg.num_chan;
+ struct pl330_thread *thrd;
+ int i;
+
+ /* Release Channel threads */
+ for (i = 0; i < chans; i++) {
+ thrd = &pl330->channels[i];
+ pl330_release_channel((void *)thrd);
+ }
+
+ /* Free memory */
+ kfree(pl330->channels);
+
+ return 0;
+}
+
+static void dmac_free_resources(struct pl330_dmac *pl330)
+{
+ struct pl330_info *pi = pl330->pinfo;
+ int chans = pi->pcfg.num_chan;
+
+ dmac_free_threads(pl330);
+
+ dma_free_coherent(pi->dev, chans * pi->mcbufsz,
+ pl330->mcode_cpu, pl330->mcode_bus);
+}
+
+void pl330_del(struct pl330_info *pi)
+{
+ struct pl330_dmac *pl330;
+
+ if (!pi || !pi->pl330_data)
+ return;
+
+ pl330 = pi->pl330_data;
+
+ pl330->state = UNINIT;
+
+ tasklet_kill(&pl330->tasks);
+
+ /* Free DMAC resources */
+ dmac_free_resources(pl330);
+
+ kfree(pl330);
+ pi->pl330_data = NULL;
+}
+EXPORT_SYMBOL(pl330_del);
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
new file mode 100644
index 00000000..9c49a46a
--- /dev/null
+++ b/arch/arm/common/sa1111.c
@@ -0,0 +1,1361 @@
+/*
+ * linux/arch/arm/common/sa1111.c
+ *
+ * SA1111 support
+ *
+ * Original code by John Dorsey
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic SA1111 support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/hardware/sa1111.h>
+
+/* SA1111 IRQs */
+#define IRQ_GPAIN0 (0)
+#define IRQ_GPAIN1 (1)
+#define IRQ_GPAIN2 (2)
+#define IRQ_GPAIN3 (3)
+#define IRQ_GPBIN0 (4)
+#define IRQ_GPBIN1 (5)
+#define IRQ_GPBIN2 (6)
+#define IRQ_GPBIN3 (7)
+#define IRQ_GPBIN4 (8)
+#define IRQ_GPBIN5 (9)
+#define IRQ_GPCIN0 (10)
+#define IRQ_GPCIN1 (11)
+#define IRQ_GPCIN2 (12)
+#define IRQ_GPCIN3 (13)
+#define IRQ_GPCIN4 (14)
+#define IRQ_GPCIN5 (15)
+#define IRQ_GPCIN6 (16)
+#define IRQ_GPCIN7 (17)
+#define IRQ_MSTXINT (18)
+#define IRQ_MSRXINT (19)
+#define IRQ_MSSTOPERRINT (20)
+#define IRQ_TPTXINT (21)
+#define IRQ_TPRXINT (22)
+#define IRQ_TPSTOPERRINT (23)
+#define SSPXMTINT (24)
+#define SSPRCVINT (25)
+#define SSPROR (26)
+#define AUDXMTDMADONEA (32)
+#define AUDRCVDMADONEA (33)
+#define AUDXMTDMADONEB (34)
+#define AUDRCVDMADONEB (35)
+#define AUDTFSR (36)
+#define AUDRFSR (37)
+#define AUDTUR (38)
+#define AUDROR (39)
+#define AUDDTS (40)
+#define AUDRDD (41)
+#define AUDSTO (42)
+#define IRQ_USBPWR (43)
+#define IRQ_HCIM (44)
+#define IRQ_HCIBUFFACC (45)
+#define IRQ_HCIRMTWKP (46)
+#define IRQ_NHCIMFCIR (47)
+#define IRQ_USB_PORT_RESUME (48)
+#define IRQ_S0_READY_NINT (49)
+#define IRQ_S1_READY_NINT (50)
+#define IRQ_S0_CD_VALID (51)
+#define IRQ_S1_CD_VALID (52)
+#define IRQ_S0_BVD1_STSCHG (53)
+#define IRQ_S1_BVD1_STSCHG (54)
+
+extern void __init sa1110_mb_enable(void);
+
+/*
+ * We keep the following data for the overall SA1111. Note that the
+ * struct device and struct resource are "fake"; they should be supplied
+ * by the bus above us. However, in the interests of getting all SA1111
+ * drivers converted over to the device model, we provide this as an
+ * anchor point for all the other drivers.
+ */
+struct sa1111 {
+ struct device *dev;
+ struct clk *clk;
+ unsigned long phys;
+ int irq;
+ int irq_base; /* base for cascaded on-chip IRQs */
+ spinlock_t lock;
+ void __iomem *base;
+#ifdef CONFIG_PM
+ void *saved_state;
+#endif
+};
+
+/*
+ * We _really_ need to eliminate this. Its only users
+ * are the PWM and DMA checking code.
+ */
+static struct sa1111 *g_sa1111;
+
+struct sa1111_dev_info {
+ unsigned long offset;
+ unsigned long skpcr_mask;
+ unsigned int devid;
+ unsigned int irq[6];
+};
+
+static struct sa1111_dev_info sa1111_devices[] = {
+ {
+ .offset = SA1111_USB,
+ .skpcr_mask = SKPCR_UCLKEN,
+ .devid = SA1111_DEVID_USB,
+ .irq = {
+ IRQ_USBPWR,
+ IRQ_HCIM,
+ IRQ_HCIBUFFACC,
+ IRQ_HCIRMTWKP,
+ IRQ_NHCIMFCIR,
+ IRQ_USB_PORT_RESUME
+ },
+ },
+ {
+ .offset = 0x0600,
+ .skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
+ .devid = SA1111_DEVID_SAC,
+ .irq = {
+ AUDXMTDMADONEA,
+ AUDXMTDMADONEB,
+ AUDRCVDMADONEA,
+ AUDRCVDMADONEB
+ },
+ },
+ {
+ .offset = 0x0800,
+ .skpcr_mask = SKPCR_SCLKEN,
+ .devid = SA1111_DEVID_SSP,
+ },
+ {
+ .offset = SA1111_KBD,
+ .skpcr_mask = SKPCR_PTCLKEN,
+ .devid = SA1111_DEVID_PS2,
+ .irq = {
+ IRQ_TPRXINT,
+ IRQ_TPTXINT
+ },
+ },
+ {
+ .offset = SA1111_MSE,
+ .skpcr_mask = SKPCR_PMCLKEN,
+ .devid = SA1111_DEVID_PS2,
+ .irq = {
+ IRQ_MSRXINT,
+ IRQ_MSTXINT
+ },
+ },
+ {
+ .offset = 0x1800,
+ .skpcr_mask = 0,
+ .devid = SA1111_DEVID_PCMCIA,
+ .irq = {
+ IRQ_S0_READY_NINT,
+ IRQ_S0_CD_VALID,
+ IRQ_S0_BVD1_STSCHG,
+ IRQ_S1_READY_NINT,
+ IRQ_S1_CD_VALID,
+ IRQ_S1_BVD1_STSCHG,
+ },
+ },
+};
+
+/*
+ * SA1111 interrupt support. Since clearing an IRQ while there are
+ * active IRQs causes the interrupt output to pulse, the upper levels
+ * will call us again if there are more interrupts to process.
+ */
+static void
+sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int stat0, stat1, i;
+ struct sa1111 *sachip = irq_get_handler_data(irq);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+
+ stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
+ stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
+
+ sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
+
+ if (stat0 == 0 && stat1 == 0) {
+ do_bad_IRQ(irq, desc);
+ return;
+ }
+
+ for (i = 0; stat0; i++, stat0 >>= 1)
+ if (stat0 & 1)
+ generic_handle_irq(i + sachip->irq_base);
+
+ for (i = 32; stat1; i++, stat1 >>= 1)
+ if (stat1 & 1)
+ generic_handle_irq(i + sachip->irq_base);
+
+ /* For level-based interrupts */
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
+#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
+
+static void sa1111_ack_irq(struct irq_data *d)
+{
+}
+
+static void sa1111_mask_lowirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned long ie0;
+
+ ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
+ ie0 &= ~SA1111_IRQMASK_LO(d->irq);
+ writel(ie0, mapbase + SA1111_INTEN0);
+}
+
+static void sa1111_unmask_lowirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned long ie0;
+
+ ie0 = sa1111_readl(mapbase + SA1111_INTEN0);
+ ie0 |= SA1111_IRQMASK_LO(d->irq);
+ sa1111_writel(ie0, mapbase + SA1111_INTEN0);
+}
+
+/*
+ * Attempt to re-trigger the interrupt. The SA1111 contains a register
+ * (INTSET) which claims to do this. However, in practice no amount of
+ * manipulation of INTEN and INTSET guarantees that the interrupt will
+ * be triggered. In fact, its very difficult, if not impossible to get
+ * INTSET to re-trigger the interrupt.
+ */
+static int sa1111_retrigger_lowirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
+ unsigned long ip0;
+ int i;
+
+ ip0 = sa1111_readl(mapbase + SA1111_INTPOL0);
+ for (i = 0; i < 8; i++) {
+ sa1111_writel(ip0 ^ mask, mapbase + SA1111_INTPOL0);
+ sa1111_writel(ip0, mapbase + SA1111_INTPOL0);
+ if (sa1111_readl(mapbase + SA1111_INTSTATCLR0) & mask)
+ break;
+ }
+
+ if (i == 8)
+ printk(KERN_ERR "Danger Will Robinson: failed to "
+ "re-trigger IRQ%d\n", d->irq);
+ return i == 8 ? -1 : 0;
+}
+
+static int sa1111_type_lowirq(struct irq_data *d, unsigned int flags)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
+ unsigned long ip0;
+
+ if (flags == IRQ_TYPE_PROBE)
+ return 0;
+
+ if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0)
+ return -EINVAL;
+
+ ip0 = sa1111_readl(mapbase + SA1111_INTPOL0);
+ if (flags & IRQ_TYPE_EDGE_RISING)
+ ip0 &= ~mask;
+ else
+ ip0 |= mask;
+ sa1111_writel(ip0, mapbase + SA1111_INTPOL0);
+ sa1111_writel(ip0, mapbase + SA1111_WAKEPOL0);
+
+ return 0;
+}
+
+static int sa1111_wake_lowirq(struct irq_data *d, unsigned int on)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_LO(d->irq);
+ unsigned long we0;
+
+ we0 = sa1111_readl(mapbase + SA1111_WAKEEN0);
+ if (on)
+ we0 |= mask;
+ else
+ we0 &= ~mask;
+ sa1111_writel(we0, mapbase + SA1111_WAKEEN0);
+
+ return 0;
+}
+
+static struct irq_chip sa1111_low_chip = {
+ .name = "SA1111-l",
+ .irq_ack = sa1111_ack_irq,
+ .irq_mask = sa1111_mask_lowirq,
+ .irq_unmask = sa1111_unmask_lowirq,
+ .irq_retrigger = sa1111_retrigger_lowirq,
+ .irq_set_type = sa1111_type_lowirq,
+ .irq_set_wake = sa1111_wake_lowirq,
+};
+
+static void sa1111_mask_highirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned long ie1;
+
+ ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
+ ie1 &= ~SA1111_IRQMASK_HI(d->irq);
+ sa1111_writel(ie1, mapbase + SA1111_INTEN1);
+}
+
+static void sa1111_unmask_highirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned long ie1;
+
+ ie1 = sa1111_readl(mapbase + SA1111_INTEN1);
+ ie1 |= SA1111_IRQMASK_HI(d->irq);
+ sa1111_writel(ie1, mapbase + SA1111_INTEN1);
+}
+
+/*
+ * Attempt to re-trigger the interrupt. The SA1111 contains a register
+ * (INTSET) which claims to do this. However, in practice no amount of
+ * manipulation of INTEN and INTSET guarantees that the interrupt will
+ * be triggered. In fact, its very difficult, if not impossible to get
+ * INTSET to re-trigger the interrupt.
+ */
+static int sa1111_retrigger_highirq(struct irq_data *d)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
+ unsigned long ip1;
+ int i;
+
+ ip1 = sa1111_readl(mapbase + SA1111_INTPOL1);
+ for (i = 0; i < 8; i++) {
+ sa1111_writel(ip1 ^ mask, mapbase + SA1111_INTPOL1);
+ sa1111_writel(ip1, mapbase + SA1111_INTPOL1);
+ if (sa1111_readl(mapbase + SA1111_INTSTATCLR1) & mask)
+ break;
+ }
+
+ if (i == 8)
+ printk(KERN_ERR "Danger Will Robinson: failed to "
+ "re-trigger IRQ%d\n", d->irq);
+ return i == 8 ? -1 : 0;
+}
+
+static int sa1111_type_highirq(struct irq_data *d, unsigned int flags)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
+ unsigned long ip1;
+
+ if (flags == IRQ_TYPE_PROBE)
+ return 0;
+
+ if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0)
+ return -EINVAL;
+
+ ip1 = sa1111_readl(mapbase + SA1111_INTPOL1);
+ if (flags & IRQ_TYPE_EDGE_RISING)
+ ip1 &= ~mask;
+ else
+ ip1 |= mask;
+ sa1111_writel(ip1, mapbase + SA1111_INTPOL1);
+ sa1111_writel(ip1, mapbase + SA1111_WAKEPOL1);
+
+ return 0;
+}
+
+static int sa1111_wake_highirq(struct irq_data *d, unsigned int on)
+{
+ struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
+ void __iomem *mapbase = sachip->base + SA1111_INTC;
+ unsigned int mask = SA1111_IRQMASK_HI(d->irq);
+ unsigned long we1;
+
+ we1 = sa1111_readl(mapbase + SA1111_WAKEEN1);
+ if (on)
+ we1 |= mask;
+ else
+ we1 &= ~mask;
+ sa1111_writel(we1, mapbase + SA1111_WAKEEN1);
+
+ return 0;
+}
+
+static struct irq_chip sa1111_high_chip = {
+ .name = "SA1111-h",
+ .irq_ack = sa1111_ack_irq,
+ .irq_mask = sa1111_mask_highirq,
+ .irq_unmask = sa1111_unmask_highirq,
+ .irq_retrigger = sa1111_retrigger_highirq,
+ .irq_set_type = sa1111_type_highirq,
+ .irq_set_wake = sa1111_wake_highirq,
+};
+
+static void sa1111_setup_irq(struct sa1111 *sachip)
+{
+ void __iomem *irqbase = sachip->base + SA1111_INTC;
+ unsigned int irq;
+
+ /*
+ * We're guaranteed that this region hasn't been taken.
+ */
+ request_mem_region(sachip->phys + SA1111_INTC, 512, "irq");
+
+ /* disable all IRQs */
+ sa1111_writel(0, irqbase + SA1111_INTEN0);
+ sa1111_writel(0, irqbase + SA1111_INTEN1);
+ sa1111_writel(0, irqbase + SA1111_WAKEEN0);
+ sa1111_writel(0, irqbase + SA1111_WAKEEN1);
+
+ /*
+ * detect on rising edge. Note: Feb 2001 Errata for SA1111
+ * specifies that S0ReadyInt and S1ReadyInt should be '1'.
+ */
+ sa1111_writel(0, irqbase + SA1111_INTPOL0);
+ sa1111_writel(SA1111_IRQMASK_HI(IRQ_S0_READY_NINT) |
+ SA1111_IRQMASK_HI(IRQ_S1_READY_NINT),
+ irqbase + SA1111_INTPOL1);
+
+ /* clear all IRQs */
+ sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
+ sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
+
+ for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
+ irq_set_chip_and_handler(irq, &sa1111_low_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, sachip);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
+ irq_set_chip_and_handler(irq, &sa1111_high_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, sachip);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /*
+ * Register SA1111 interrupt
+ */
+ irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_handler_data(sachip->irq, sachip);
+ irq_set_chained_handler(sachip->irq, sa1111_irq_handler);
+}
+
+/*
+ * Bring the SA1111 out of reset. This requires a set procedure:
+ * 1. nRESET asserted (by hardware)
+ * 2. CLK turned on from SA1110
+ * 3. nRESET deasserted
+ * 4. VCO turned on, PLL_BYPASS turned off
+ * 5. Wait lock time, then assert RCLKEn
+ * 7. PCR set to allow clocking of individual functions
+ *
+ * Until we've done this, the only registers we can access are:
+ * SBI_SKCR
+ * SBI_SMCR
+ * SBI_SKID
+ */
+static void sa1111_wake(struct sa1111 *sachip)
+{
+ unsigned long flags, r;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+
+ clk_enable(sachip->clk);
+
+ /*
+ * Turn VCO on, and disable PLL Bypass.
+ */
+ r = sa1111_readl(sachip->base + SA1111_SKCR);
+ r &= ~SKCR_VCO_OFF;
+ sa1111_writel(r, sachip->base + SA1111_SKCR);
+ r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
+ sa1111_writel(r, sachip->base + SA1111_SKCR);
+
+ /*
+ * Wait lock time. SA1111 manual _doesn't_
+ * specify a figure for this! We choose 100us.
+ */
+ udelay(100);
+
+ /*
+ * Enable RCLK. We also ensure that RDYEN is set.
+ */
+ r |= SKCR_RCLKEN | SKCR_RDYEN;
+ sa1111_writel(r, sachip->base + SA1111_SKCR);
+
+ /*
+ * Wait 14 RCLK cycles for the chip to finish coming out
+ * of reset. (RCLK=24MHz). This is 590ns.
+ */
+ udelay(1);
+
+ /*
+ * Ensure all clocks are initially off.
+ */
+ sa1111_writel(0, sachip->base + SA1111_SKPCR);
+
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+
+#ifdef CONFIG_ARCH_SA1100
+
+static u32 sa1111_dma_mask[] = {
+ ~0,
+ ~(1 << 20),
+ ~(1 << 23),
+ ~(1 << 24),
+ ~(1 << 25),
+ ~(1 << 20),
+ ~(1 << 20),
+ 0,
+};
+
+/*
+ * Configure the SA1111 shared memory controller.
+ */
+void
+sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
+ unsigned int cas_latency)
+{
+ unsigned int smcr = SMCR_DTIM | SMCR_MBGE | FInsrt(drac, SMCR_DRAC);
+
+ if (cas_latency == 3)
+ smcr |= SMCR_CLAT;
+
+ sa1111_writel(smcr, sachip->base + SA1111_SMCR);
+
+ /*
+ * Now clear the bits in the DMA mask to work around the SA1111
+ * DMA erratum (Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update, June 2000, Erratum #7).
+ */
+ if (sachip->dev->dma_mask)
+ *sachip->dev->dma_mask &= sa1111_dma_mask[drac >> 2];
+
+ sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2];
+}
+
+#endif
+
+static void sa1111_dev_release(struct device *_dev)
+{
+ struct sa1111_dev *dev = SA1111_DEV(_dev);
+
+ release_resource(&dev->res);
+ kfree(dev);
+}
+
+static int
+sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
+ struct sa1111_dev_info *info)
+{
+ struct sa1111_dev *dev;
+ int ret;
+
+ dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ dev_set_name(&dev->dev, "%4.4lx", info->offset);
+ dev->devid = info->devid;
+ dev->dev.parent = sachip->dev;
+ dev->dev.bus = &sa1111_bus_type;
+ dev->dev.release = sa1111_dev_release;
+ dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
+ dev->res.start = sachip->phys + info->offset;
+ dev->res.end = dev->res.start + 511;
+ dev->res.name = dev_name(&dev->dev);
+ dev->res.flags = IORESOURCE_MEM;
+ dev->mapbase = sachip->base + info->offset;
+ dev->skpcr_mask = info->skpcr_mask;
+ memmove(dev->irq, info->irq, sizeof(dev->irq));
+
+ ret = request_resource(parent, &dev->res);
+ if (ret) {
+ printk("SA1111: failed to allocate resource for %s\n",
+ dev->res.name);
+ dev_set_name(&dev->dev, NULL);
+ kfree(dev);
+ goto out;
+ }
+
+
+ ret = device_register(&dev->dev);
+ if (ret) {
+ release_resource(&dev->res);
+ kfree(dev);
+ goto out;
+ }
+
+#ifdef CONFIG_DMABOUNCE
+ /*
+ * If the parent device has a DMA mask associated with it,
+ * propagate it down to the children.
+ */
+ if (sachip->dev->dma_mask) {
+ dev->dma_mask = *sachip->dev->dma_mask;
+ dev->dev.dma_mask = &dev->dma_mask;
+
+ if (dev->dma_mask != 0xffffffffUL) {
+ ret = dmabounce_register_dev(&dev->dev, 1024, 4096);
+ if (ret) {
+ dev_err(&dev->dev, "SA1111: Failed to register"
+ " with dmabounce\n");
+ device_unregister(&dev->dev);
+ }
+ }
+ }
+#endif
+
+out:
+ return ret;
+}
+
+/**
+ * sa1111_probe - probe for a single SA1111 chip.
+ * @phys_addr: physical address of device.
+ *
+ * Probe for a SA1111 chip. This must be called
+ * before any other SA1111-specific code.
+ *
+ * Returns:
+ * %-ENODEV device not found.
+ * %-EBUSY physical address already marked in-use.
+ * %0 successful.
+ */
+static int __devinit
+__sa1111_probe(struct device *me, struct resource *mem, int irq)
+{
+ struct sa1111 *sachip;
+ unsigned long id;
+ unsigned int has_devs;
+ int i, ret = -ENODEV;
+
+ sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
+ if (!sachip)
+ return -ENOMEM;
+
+ sachip->clk = clk_get(me, "SA1111_CLK");
+ if (IS_ERR(sachip->clk)) {
+ ret = PTR_ERR(sachip->clk);
+ goto err_free;
+ }
+
+ spin_lock_init(&sachip->lock);
+
+ sachip->dev = me;
+ dev_set_drvdata(sachip->dev, sachip);
+
+ sachip->phys = mem->start;
+ sachip->irq = irq;
+
+ /*
+ * Map the whole region. This also maps the
+ * registers for our children.
+ */
+ sachip->base = ioremap(mem->start, PAGE_SIZE * 2);
+ if (!sachip->base) {
+ ret = -ENOMEM;
+ goto err_clkput;
+ }
+
+ /*
+ * Probe for the chip. Only touch the SBI registers.
+ */
+ id = sa1111_readl(sachip->base + SA1111_SKID);
+ if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
+ printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
+ ret = -ENODEV;
+ goto err_unmap;
+ }
+
+ printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
+ "silicon revision %lx, metal revision %lx\n",
+ (id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+
+ /*
+ * We found it. Wake the chip up, and initialise.
+ */
+ sa1111_wake(sachip);
+
+#ifdef CONFIG_ARCH_SA1100
+ {
+ unsigned int val;
+
+ /*
+ * The SDRAM configuration of the SA1110 and the SA1111 must
+ * match. This is very important to ensure that SA1111 accesses
+ * don't corrupt the SDRAM. Note that this ungates the SA1111's
+ * MBGNT signal, so we must have called sa1110_mb_disable()
+ * beforehand.
+ */
+ sa1111_configure_smc(sachip, 1,
+ FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+ FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+ /*
+ * We only need to turn on DCLK whenever we want to use the
+ * DMA. It can otherwise be held firmly in the off position.
+ * (currently, we always enable it.)
+ */
+ val = sa1111_readl(sachip->base + SA1111_SKPCR);
+ sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR);
+
+ /*
+ * Enable the SA1110 memory bus request and grant signals.
+ */
+ sa1110_mb_enable();
+ }
+#endif
+
+ /*
+ * The interrupt controller must be initialised before any
+ * other device to ensure that the interrupts are available.
+ */
+ if (sachip->irq != NO_IRQ)
+ sa1111_setup_irq(sachip);
+
+ g_sa1111 = sachip;
+
+ has_devs = ~0;
+ if (machine_is_assabet() || machine_is_jornada720() ||
+ machine_is_badge4())
+ has_devs &= ~(1 << 4);
+ else
+ has_devs &= ~(1 << 1);
+
+ for (i = 0; i < ARRAY_SIZE(sa1111_devices); i++)
+ if (has_devs & (1 << i))
+ sa1111_init_one_child(sachip, mem, &sa1111_devices[i]);
+
+ return 0;
+
+ err_unmap:
+ iounmap(sachip->base);
+ err_clkput:
+ clk_put(sachip->clk);
+ err_free:
+ kfree(sachip);
+ return ret;
+}
+
+static int sa1111_remove_one(struct device *dev, void *data)
+{
+ device_unregister(dev);
+ return 0;
+}
+
+static void __sa1111_remove(struct sa1111 *sachip)
+{
+ void __iomem *irqbase = sachip->base + SA1111_INTC;
+
+ device_for_each_child(sachip->dev, NULL, sa1111_remove_one);
+
+ /* disable all IRQs */
+ sa1111_writel(0, irqbase + SA1111_INTEN0);
+ sa1111_writel(0, irqbase + SA1111_INTEN1);
+ sa1111_writel(0, irqbase + SA1111_WAKEEN0);
+ sa1111_writel(0, irqbase + SA1111_WAKEEN1);
+
+ clk_disable(sachip->clk);
+
+ if (sachip->irq != NO_IRQ) {
+ irq_set_chained_handler(sachip->irq, NULL);
+ irq_set_handler_data(sachip->irq, NULL);
+
+ release_mem_region(sachip->phys + SA1111_INTC, 512);
+ }
+
+ iounmap(sachip->base);
+ clk_put(sachip->clk);
+ kfree(sachip);
+}
+
+/*
+ * According to the "Intel StrongARM SA-1111 Microprocessor Companion
+ * Chip Specification Update" (June 2000), erratum #7, there is a
+ * significant bug in the SA1111 SDRAM shared memory controller. If
+ * an access to a region of memory above 1MB relative to the bank base,
+ * it is important that address bit 10 _NOT_ be asserted. Depending
+ * on the configuration of the RAM, bit 10 may correspond to one
+ * of several different (processor-relative) address bits.
+ *
+ * This routine only identifies whether or not a given DMA address
+ * is susceptible to the bug.
+ *
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+{
+ /*
+ * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+ * User's Guide" mentions that jumpers R51 and R52 control the
+ * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or
+ * SDRAM bank 1 on Neponset). The default configuration selects
+ * Assabet, so any address in bank 1 is necessarily invalid.
+ */
+ return ((machine_is_assabet() || machine_is_pfs168()) &&
+ (addr >= 0xc8000000 || (addr + size) >= 0xc8000000));
+}
+
+struct sa1111_save_data {
+ unsigned int skcr;
+ unsigned int skpcr;
+ unsigned int skcdr;
+ unsigned char skaud;
+ unsigned char skpwm0;
+ unsigned char skpwm1;
+
+ /*
+ * Interrupt controller
+ */
+ unsigned int intpol0;
+ unsigned int intpol1;
+ unsigned int inten0;
+ unsigned int inten1;
+ unsigned int wakepol0;
+ unsigned int wakepol1;
+ unsigned int wakeen0;
+ unsigned int wakeen1;
+};
+
+#ifdef CONFIG_PM
+
+static int sa1111_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct sa1111 *sachip = platform_get_drvdata(dev);
+ struct sa1111_save_data *save;
+ unsigned long flags;
+ unsigned int val;
+ void __iomem *base;
+
+ save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
+ if (!save)
+ return -ENOMEM;
+ sachip->saved_state = save;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+
+ /*
+ * Save state.
+ */
+ base = sachip->base;
+ save->skcr = sa1111_readl(base + SA1111_SKCR);
+ save->skpcr = sa1111_readl(base + SA1111_SKPCR);
+ save->skcdr = sa1111_readl(base + SA1111_SKCDR);
+ save->skaud = sa1111_readl(base + SA1111_SKAUD);
+ save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0);
+ save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1);
+
+ base = sachip->base + SA1111_INTC;
+ save->intpol0 = sa1111_readl(base + SA1111_INTPOL0);
+ save->intpol1 = sa1111_readl(base + SA1111_INTPOL1);
+ save->inten0 = sa1111_readl(base + SA1111_INTEN0);
+ save->inten1 = sa1111_readl(base + SA1111_INTEN1);
+ save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0);
+ save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1);
+ save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0);
+ save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1);
+
+ /*
+ * Disable.
+ */
+ val = sa1111_readl(sachip->base + SA1111_SKCR);
+ sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
+ sa1111_writel(0, sachip->base + SA1111_SKPWM0);
+ sa1111_writel(0, sachip->base + SA1111_SKPWM1);
+
+ clk_disable(sachip->clk);
+
+ spin_unlock_irqrestore(&sachip->lock, flags);
+
+ return 0;
+}
+
+/*
+ * sa1111_resume - Restore the SA1111 device state.
+ * @dev: device to restore
+ *
+ * Restore the general state of the SA1111; clock control and
+ * interrupt controller. Other parts of the SA1111 must be
+ * restored by their respective drivers, and must be called
+ * via LDM after this function.
+ */
+static int sa1111_resume(struct platform_device *dev)
+{
+ struct sa1111 *sachip = platform_get_drvdata(dev);
+ struct sa1111_save_data *save;
+ unsigned long flags, id;
+ void __iomem *base;
+
+ save = sachip->saved_state;
+ if (!save)
+ return 0;
+
+ /*
+ * Ensure that the SA1111 is still here.
+ * FIXME: shouldn't do this here.
+ */
+ id = sa1111_readl(sachip->base + SA1111_SKID);
+ if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
+ __sa1111_remove(sachip);
+ platform_set_drvdata(dev, NULL);
+ kfree(save);
+ return 0;
+ }
+
+ /*
+ * First of all, wake up the chip.
+ */
+ sa1111_wake(sachip);
+
+ /*
+ * Only lock for write ops. Also, sa1111_wake must be called with
+ * released spinlock!
+ */
+ spin_lock_irqsave(&sachip->lock, flags);
+
+ sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0);
+ sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1);
+
+ base = sachip->base;
+ sa1111_writel(save->skcr, base + SA1111_SKCR);
+ sa1111_writel(save->skpcr, base + SA1111_SKPCR);
+ sa1111_writel(save->skcdr, base + SA1111_SKCDR);
+ sa1111_writel(save->skaud, base + SA1111_SKAUD);
+ sa1111_writel(save->skpwm0, base + SA1111_SKPWM0);
+ sa1111_writel(save->skpwm1, base + SA1111_SKPWM1);
+
+ base = sachip->base + SA1111_INTC;
+ sa1111_writel(save->intpol0, base + SA1111_INTPOL0);
+ sa1111_writel(save->intpol1, base + SA1111_INTPOL1);
+ sa1111_writel(save->inten0, base + SA1111_INTEN0);
+ sa1111_writel(save->inten1, base + SA1111_INTEN1);
+ sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0);
+ sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1);
+ sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0);
+ sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1);
+
+ spin_unlock_irqrestore(&sachip->lock, flags);
+
+ sachip->saved_state = NULL;
+ kfree(save);
+
+ return 0;
+}
+
+#else
+#define sa1111_suspend NULL
+#define sa1111_resume NULL
+#endif
+
+static int __devinit sa1111_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ int irq;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -EINVAL;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return -ENXIO;
+
+ return __sa1111_probe(&pdev->dev, mem, irq);
+}
+
+static int sa1111_remove(struct platform_device *pdev)
+{
+ struct sa1111 *sachip = platform_get_drvdata(pdev);
+
+ if (sachip) {
+#ifdef CONFIG_PM
+ kfree(sachip->saved_state);
+ sachip->saved_state = NULL;
+#endif
+ __sa1111_remove(sachip);
+ platform_set_drvdata(pdev, NULL);
+ }
+
+ return 0;
+}
+
+/*
+ * Not sure if this should be on the system bus or not yet.
+ * We really want some way to register a system device at
+ * the per-machine level, and then have this driver pick
+ * up the registered devices.
+ *
+ * We also need to handle the SDRAM configuration for
+ * PXA250/SA1110 machine classes.
+ */
+static struct platform_driver sa1111_device_driver = {
+ .probe = sa1111_probe,
+ .remove = sa1111_remove,
+ .suspend = sa1111_suspend,
+ .resume = sa1111_resume,
+ .driver = {
+ .name = "sa1111",
+ },
+};
+
+/*
+ * Get the parent device driver (us) structure
+ * from a child function device
+ */
+static inline struct sa1111 *sa1111_chip_driver(struct sa1111_dev *sadev)
+{
+ return (struct sa1111 *)dev_get_drvdata(sadev->dev.parent);
+}
+
+/*
+ * The bits in the opdiv field are non-linear.
+ */
+static unsigned char opdiv_table[] = { 1, 4, 2, 8 };
+
+static unsigned int __sa1111_pll_clock(struct sa1111 *sachip)
+{
+ unsigned int skcdr, fbdiv, ipdiv, opdiv;
+
+ skcdr = sa1111_readl(sachip->base + SA1111_SKCDR);
+
+ fbdiv = (skcdr & 0x007f) + 2;
+ ipdiv = ((skcdr & 0x0f80) >> 7) + 2;
+ opdiv = opdiv_table[(skcdr & 0x3000) >> 12];
+
+ return 3686400 * fbdiv / (ipdiv * opdiv);
+}
+
+/**
+ * sa1111_pll_clock - return the current PLL clock frequency.
+ * @sadev: SA1111 function block
+ *
+ * BUG: we should look at SKCR. We also blindly believe that
+ * the chip is being fed with the 3.6864MHz clock.
+ *
+ * Returns the PLL clock in Hz.
+ */
+unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+
+ return __sa1111_pll_clock(sachip);
+}
+EXPORT_SYMBOL(sa1111_pll_clock);
+
+/**
+ * sa1111_select_audio_mode - select I2S or AC link mode
+ * @sadev: SA1111 function block
+ * @mode: One of %SA1111_AUDIO_ACLINK or %SA1111_AUDIO_I2S
+ *
+ * Frob the SKCR to select AC Link mode or I2S mode for
+ * the audio block.
+ */
+void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+
+ val = sa1111_readl(sachip->base + SA1111_SKCR);
+ if (mode == SA1111_AUDIO_I2S) {
+ val &= ~SKCR_SELAC;
+ } else {
+ val |= SKCR_SELAC;
+ }
+ sa1111_writel(val, sachip->base + SA1111_SKCR);
+
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_select_audio_mode);
+
+/**
+ * sa1111_set_audio_rate - set the audio sample rate
+ * @sadev: SA1111 SAC function block
+ * @rate: sample rate to select
+ */
+int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned int div;
+
+ if (sadev->devid != SA1111_DEVID_SAC)
+ return -EINVAL;
+
+ div = (__sa1111_pll_clock(sachip) / 256 + rate / 2) / rate;
+ if (div == 0)
+ div = 1;
+ if (div > 128)
+ div = 128;
+
+ sa1111_writel(div - 1, sachip->base + SA1111_SKAUD);
+
+ return 0;
+}
+EXPORT_SYMBOL(sa1111_set_audio_rate);
+
+/**
+ * sa1111_get_audio_rate - get the audio sample rate
+ * @sadev: SA1111 SAC function block device
+ */
+int sa1111_get_audio_rate(struct sa1111_dev *sadev)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long div;
+
+ if (sadev->devid != SA1111_DEVID_SAC)
+ return -EINVAL;
+
+ div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1;
+
+ return __sa1111_pll_clock(sachip) / (256 * div);
+}
+EXPORT_SYMBOL(sa1111_get_audio_rate);
+
+void sa1111_set_io_dir(struct sa1111_dev *sadev,
+ unsigned int bits, unsigned int dir,
+ unsigned int sleep_dir)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+ void __iomem *gpio = sachip->base + SA1111_GPIO;
+
+#define MODIFY_BITS(port, mask, dir) \
+ if (mask) { \
+ val = sa1111_readl(port); \
+ val &= ~(mask); \
+ val |= (dir) & (mask); \
+ sa1111_writel(val, port); \
+ }
+
+ spin_lock_irqsave(&sachip->lock, flags);
+ MODIFY_BITS(gpio + SA1111_GPIO_PADDR, bits & 15, dir);
+ MODIFY_BITS(gpio + SA1111_GPIO_PBDDR, (bits >> 8) & 255, dir >> 8);
+ MODIFY_BITS(gpio + SA1111_GPIO_PCDDR, (bits >> 16) & 255, dir >> 16);
+
+ MODIFY_BITS(gpio + SA1111_GPIO_PASDR, bits & 15, sleep_dir);
+ MODIFY_BITS(gpio + SA1111_GPIO_PBSDR, (bits >> 8) & 255, sleep_dir >> 8);
+ MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_set_io_dir);
+
+void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+ void __iomem *gpio = sachip->base + SA1111_GPIO;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+ MODIFY_BITS(gpio + SA1111_GPIO_PADWR, bits & 15, v);
+ MODIFY_BITS(gpio + SA1111_GPIO_PBDWR, (bits >> 8) & 255, v >> 8);
+ MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_set_io);
+
+void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+ void __iomem *gpio = sachip->base + SA1111_GPIO;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+ MODIFY_BITS(gpio + SA1111_GPIO_PASSR, bits & 15, v);
+ MODIFY_BITS(gpio + SA1111_GPIO_PBSSR, (bits >> 8) & 255, v >> 8);
+ MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_set_sleep_io);
+
+/*
+ * Individual device operations.
+ */
+
+/**
+ * sa1111_enable_device - enable an on-chip SA1111 function block
+ * @sadev: SA1111 function block device to enable
+ */
+void sa1111_enable_device(struct sa1111_dev *sadev)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+ val = sa1111_readl(sachip->base + SA1111_SKPCR);
+ sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_enable_device);
+
+/**
+ * sa1111_disable_device - disable an on-chip SA1111 function block
+ * @sadev: SA1111 function block device to disable
+ */
+void sa1111_disable_device(struct sa1111_dev *sadev)
+{
+ struct sa1111 *sachip = sa1111_chip_driver(sadev);
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&sachip->lock, flags);
+ val = sa1111_readl(sachip->base + SA1111_SKPCR);
+ sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
+ spin_unlock_irqrestore(&sachip->lock, flags);
+}
+EXPORT_SYMBOL(sa1111_disable_device);
+
+/*
+ * SA1111 "Register Access Bus."
+ *
+ * We model this as a regular bus type, and hang devices directly
+ * off this.
+ */
+static int sa1111_match(struct device *_dev, struct device_driver *_drv)
+{
+ struct sa1111_dev *dev = SA1111_DEV(_dev);
+ struct sa1111_driver *drv = SA1111_DRV(_drv);
+
+ return dev->devid == drv->devid;
+}
+
+static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
+{
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv && drv->suspend)
+ ret = drv->suspend(sadev, state);
+ return ret;
+}
+
+static int sa1111_bus_resume(struct device *dev)
+{
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv && drv->resume)
+ ret = drv->resume(sadev);
+ return ret;
+}
+
+static int sa1111_bus_probe(struct device *dev)
+{
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+ int ret = -ENODEV;
+
+ if (drv->probe)
+ ret = drv->probe(sadev);
+ return ret;
+}
+
+static int sa1111_bus_remove(struct device *dev)
+{
+ struct sa1111_dev *sadev = SA1111_DEV(dev);
+ struct sa1111_driver *drv = SA1111_DRV(dev->driver);
+ int ret = 0;
+
+ if (drv->remove)
+ ret = drv->remove(sadev);
+ return ret;
+}
+
+struct bus_type sa1111_bus_type = {
+ .name = "sa1111-rab",
+ .match = sa1111_match,
+ .probe = sa1111_bus_probe,
+ .remove = sa1111_bus_remove,
+ .suspend = sa1111_bus_suspend,
+ .resume = sa1111_bus_resume,
+};
+EXPORT_SYMBOL(sa1111_bus_type);
+
+int sa1111_driver_register(struct sa1111_driver *driver)
+{
+ driver->drv.bus = &sa1111_bus_type;
+ return driver_register(&driver->drv);
+}
+EXPORT_SYMBOL(sa1111_driver_register);
+
+void sa1111_driver_unregister(struct sa1111_driver *driver)
+{
+ driver_unregister(&driver->drv);
+}
+EXPORT_SYMBOL(sa1111_driver_unregister);
+
+static int __init sa1111_init(void)
+{
+ int ret = bus_register(&sa1111_bus_type);
+ if (ret == 0)
+ platform_driver_register(&sa1111_device_driver);
+ return ret;
+}
+
+static void __exit sa1111_exit(void)
+{
+ platform_driver_unregister(&sa1111_device_driver);
+ bus_unregister(&sa1111_bus_type);
+}
+
+subsys_initcall(sa1111_init);
+module_exit(sa1111_exit);
+
+MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
new file mode 100644
index 00000000..c11af1e4
--- /dev/null
+++ b/arch/arm/common/scoop.c
@@ -0,0 +1,283 @@
+/*
+ * Support code for the SCOOP interface found on various Sharp PDAs
+ *
+ * Copyright (c) 2004 Richard Purdie
+ *
+ * Based on code written by Sharp/Lineo for 2.4 kernels
+ *
+ * This program is free software; you can 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/string.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <asm/hardware/scoop.h>
+
+/* PCMCIA to Scoop linkage
+
+ There is no easy way to link multiple scoop devices into one
+ single entity for the pxa2xx_pcmcia device so this structure
+ is used which is setup by the platform code.
+
+ This file is never modular so this symbol is always
+ accessile to the board support files.
+*/
+struct scoop_pcmcia_config *platform_scoop_config;
+EXPORT_SYMBOL(platform_scoop_config);
+
+struct scoop_dev {
+ void __iomem *base;
+ struct gpio_chip gpio;
+ spinlock_t scoop_lock;
+ unsigned short suspend_clr;
+ unsigned short suspend_set;
+ u32 scoop_gpwr;
+};
+
+void reset_scoop(struct device *dev)
+{
+ struct scoop_dev *sdev = dev_get_drvdata(dev);
+
+ iowrite16(0x0100, sdev->base + SCOOP_MCR); /* 00 */
+ iowrite16(0x0000, sdev->base + SCOOP_CDR); /* 04 */
+ iowrite16(0x0000, sdev->base + SCOOP_CCR); /* 10 */
+ iowrite16(0x0000, sdev->base + SCOOP_IMR); /* 18 */
+ iowrite16(0x00FF, sdev->base + SCOOP_IRM); /* 14 */
+ iowrite16(0x0000, sdev->base + SCOOP_ISR); /* 1C */
+ iowrite16(0x0000, sdev->base + SCOOP_IRM);
+}
+
+static void __scoop_gpio_set(struct scoop_dev *sdev,
+ unsigned offset, int value)
+{
+ unsigned short gpwr;
+
+ gpwr = ioread16(sdev->base + SCOOP_GPWR);
+ if (value)
+ gpwr |= 1 << (offset + 1);
+ else
+ gpwr &= ~(1 << (offset + 1));
+ iowrite16(gpwr, sdev->base + SCOOP_GPWR);
+}
+
+static void scoop_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdev->scoop_lock, flags);
+
+ __scoop_gpio_set(sdev, offset, value);
+
+ spin_unlock_irqrestore(&sdev->scoop_lock, flags);
+}
+
+static int scoop_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+
+ /* XXX: I'm unsure, but it seems so */
+ return ioread16(sdev->base + SCOOP_GPRR) & (1 << (offset + 1));
+}
+
+static int scoop_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+ unsigned long flags;
+ unsigned short gpcr;
+
+ spin_lock_irqsave(&sdev->scoop_lock, flags);
+
+ gpcr = ioread16(sdev->base + SCOOP_GPCR);
+ gpcr &= ~(1 << (offset + 1));
+ iowrite16(gpcr, sdev->base + SCOOP_GPCR);
+
+ spin_unlock_irqrestore(&sdev->scoop_lock, flags);
+
+ return 0;
+}
+
+static int scoop_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct scoop_dev *sdev = container_of(chip, struct scoop_dev, gpio);
+ unsigned long flags;
+ unsigned short gpcr;
+
+ spin_lock_irqsave(&sdev->scoop_lock, flags);
+
+ __scoop_gpio_set(sdev, offset, value);
+
+ gpcr = ioread16(sdev->base + SCOOP_GPCR);
+ gpcr |= 1 << (offset + 1);
+ iowrite16(gpcr, sdev->base + SCOOP_GPCR);
+
+ spin_unlock_irqrestore(&sdev->scoop_lock, flags);
+
+ return 0;
+}
+
+unsigned short read_scoop_reg(struct device *dev, unsigned short reg)
+{
+ struct scoop_dev *sdev = dev_get_drvdata(dev);
+ return ioread16(sdev->base + reg);
+}
+
+void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data)
+{
+ struct scoop_dev *sdev = dev_get_drvdata(dev);
+ iowrite16(data, sdev->base + reg);
+}
+
+EXPORT_SYMBOL(reset_scoop);
+EXPORT_SYMBOL(read_scoop_reg);
+EXPORT_SYMBOL(write_scoop_reg);
+
+#ifdef CONFIG_PM
+static void check_scoop_reg(struct scoop_dev *sdev)
+{
+ unsigned short mcr;
+
+ mcr = ioread16(sdev->base + SCOOP_MCR);
+ if ((mcr & 0x100) == 0)
+ iowrite16(0x0101, sdev->base + SCOOP_MCR);
+}
+
+static int scoop_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct scoop_dev *sdev = platform_get_drvdata(dev);
+
+ check_scoop_reg(sdev);
+ sdev->scoop_gpwr = ioread16(sdev->base + SCOOP_GPWR);
+ iowrite16((sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set, sdev->base + SCOOP_GPWR);
+
+ return 0;
+}
+
+static int scoop_resume(struct platform_device *dev)
+{
+ struct scoop_dev *sdev = platform_get_drvdata(dev);
+
+ check_scoop_reg(sdev);
+ iowrite16(sdev->scoop_gpwr, sdev->base + SCOOP_GPWR);
+
+ return 0;
+}
+#else
+#define scoop_suspend NULL
+#define scoop_resume NULL
+#endif
+
+static int __devinit scoop_probe(struct platform_device *pdev)
+{
+ struct scoop_dev *devptr;
+ struct scoop_config *inf;
+ struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ int ret;
+ int temp;
+
+ if (!mem)
+ return -EINVAL;
+
+ devptr = kzalloc(sizeof(struct scoop_dev), GFP_KERNEL);
+ if (!devptr)
+ return -ENOMEM;
+
+ spin_lock_init(&devptr->scoop_lock);
+
+ inf = pdev->dev.platform_data;
+ devptr->base = ioremap(mem->start, mem->end - mem->start + 1);
+
+ if (!devptr->base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ platform_set_drvdata(pdev, devptr);
+
+ printk("Sharp Scoop Device found at 0x%08x -> 0x%8p\n",(unsigned int)mem->start, devptr->base);
+
+ iowrite16(0x0140, devptr->base + SCOOP_MCR);
+ reset_scoop(&pdev->dev);
+ iowrite16(0x0000, devptr->base + SCOOP_CPR);
+ iowrite16(inf->io_dir & 0xffff, devptr->base + SCOOP_GPCR);
+ iowrite16(inf->io_out & 0xffff, devptr->base + SCOOP_GPWR);
+
+ devptr->suspend_clr = inf->suspend_clr;
+ devptr->suspend_set = inf->suspend_set;
+
+ devptr->gpio.base = -1;
+
+ if (inf->gpio_base != 0) {
+ devptr->gpio.label = dev_name(&pdev->dev);
+ devptr->gpio.base = inf->gpio_base;
+ devptr->gpio.ngpio = 12; /* PA11 = 0, PA12 = 1, etc. up to PA22 = 11 */
+ devptr->gpio.set = scoop_gpio_set;
+ devptr->gpio.get = scoop_gpio_get;
+ devptr->gpio.direction_input = scoop_gpio_direction_input;
+ devptr->gpio.direction_output = scoop_gpio_direction_output;
+
+ ret = gpiochip_add(&devptr->gpio);
+ if (ret)
+ goto err_gpio;
+ }
+
+ return 0;
+
+ if (devptr->gpio.base != -1)
+ temp = gpiochip_remove(&devptr->gpio);
+err_gpio:
+ platform_set_drvdata(pdev, NULL);
+err_ioremap:
+ iounmap(devptr->base);
+ kfree(devptr);
+
+ return ret;
+}
+
+static int __devexit scoop_remove(struct platform_device *pdev)
+{
+ struct scoop_dev *sdev = platform_get_drvdata(pdev);
+ int ret;
+
+ if (!sdev)
+ return -EINVAL;
+
+ if (sdev->gpio.base != -1) {
+ ret = gpiochip_remove(&sdev->gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "Can't remove gpio chip: %d\n", ret);
+ return ret;
+ }
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ iounmap(sdev->base);
+ kfree(sdev);
+
+ return 0;
+}
+
+static struct platform_driver scoop_driver = {
+ .probe = scoop_probe,
+ .remove = __devexit_p(scoop_remove),
+ .suspend = scoop_suspend,
+ .resume = scoop_resume,
+ .driver = {
+ .name = "sharp-scoop",
+ },
+};
+
+static int __init scoop_init(void)
+{
+ return platform_driver_register(&scoop_driver);
+}
+
+subsys_initcall(scoop_init);
diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
new file mode 100644
index 00000000..d56c9325
--- /dev/null
+++ b/arch/arm/common/sharpsl_param.c
@@ -0,0 +1,62 @@
+/*
+ * Hardware parameter area specific to Sharp SL series devices
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can 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/string.h>
+#include <asm/mach/sharpsl_param.h>
+
+/*
+ * Certain hardware parameters determined at the time of device manufacture,
+ * typically including LCD parameters are loaded by the bootloader at the
+ * address PARAM_BASE. As the kernel will overwrite them, we need to store
+ * them early in the boot process, then pass them to the appropriate drivers.
+ * Not all devices use all parameters but the format is common to all.
+ */
+#ifdef CONFIG_ARCH_SA1100
+#define PARAM_BASE 0xe8ffc000
+#else
+#define PARAM_BASE 0xa0000a00
+#endif
+#define MAGIC_CHG(a,b,c,d) ( ( d << 24 ) | ( c << 16 ) | ( b << 8 ) | a )
+
+#define COMADJ_MAGIC MAGIC_CHG('C','M','A','D')
+#define UUID_MAGIC MAGIC_CHG('U','U','I','D')
+#define TOUCH_MAGIC MAGIC_CHG('T','U','C','H')
+#define AD_MAGIC MAGIC_CHG('B','V','A','D')
+#define PHAD_MAGIC MAGIC_CHG('P','H','A','D')
+
+struct sharpsl_param_info sharpsl_param;
+EXPORT_SYMBOL(sharpsl_param);
+
+void sharpsl_save_param(void)
+{
+ memcpy(&sharpsl_param, (void *)PARAM_BASE, sizeof(struct sharpsl_param_info));
+
+ if (sharpsl_param.comadj_keyword != COMADJ_MAGIC)
+ sharpsl_param.comadj=-1;
+
+ if (sharpsl_param.phad_keyword != PHAD_MAGIC)
+ sharpsl_param.phadadj=-1;
+
+ if (sharpsl_param.uuid_keyword != UUID_MAGIC)
+ sharpsl_param.uuid[0]=-1;
+
+ if (sharpsl_param.touch_keyword != TOUCH_MAGIC)
+ sharpsl_param.touch_xp=-1;
+
+ if (sharpsl_param.adadj_keyword != AD_MAGIC)
+ sharpsl_param.adadj=-1;
+}
+
+
diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c
new file mode 100644
index 00000000..deeed561
--- /dev/null
+++ b/arch/arm/common/time-acorn.c
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/common/time-acorn.c
+ *
+ * Copyright (c) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 24-Sep-1996 RMK Created
+ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
+ * 04-Dec-1997 RMK Updated for new arch/arm/time.c
+ * 13=Jun-2004 DS Moved to arch/arm/common b/c shared w/CLPS7500
+ */
+#include <linux/timex.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/ioc.h>
+
+#include <asm/mach/time.h>
+
+unsigned long ioc_timer_gettimeoffset(void)
+{
+ unsigned int count1, count2, status;
+ long offset;
+
+ ioc_writeb (0, IOC_T0LATCH);
+ barrier ();
+ count1 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+ barrier ();
+ status = ioc_readb(IOC_IRQREQA);
+ barrier ();
+ ioc_writeb (0, IOC_T0LATCH);
+ barrier ();
+ count2 = ioc_readb(IOC_T0CNTL) | (ioc_readb(IOC_T0CNTH) << 8);
+
+ offset = count2;
+ if (count2 < count1) {
+ /*
+ * We have not had an interrupt between reading count1
+ * and count2.
+ */
+ if (status & (1 << 5))
+ offset -= LATCH;
+ } else if (count2 > count1) {
+ /*
+ * We have just had another interrupt between reading
+ * count1 and count2.
+ */
+ offset -= LATCH;
+ }
+
+ offset = (LATCH - offset) * (tick_nsec / 1000);
+ return (offset + LATCH/2) / LATCH;
+}
+
+void __init ioctime_init(void)
+{
+ ioc_writeb(LATCH & 255, IOC_T0LTCHL);
+ ioc_writeb(LATCH >> 8, IOC_T0LTCHH);
+ ioc_writeb(0, IOC_T0GO);
+}
+
+static irqreturn_t
+ioc_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ioc_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED,
+ .handler = ioc_timer_interrupt
+};
+
+/*
+ * Set up timer interrupt.
+ */
+static void __init ioc_timer_init(void)
+{
+ ioctime_init();
+ setup_irq(IRQ_TIMER, &ioc_timer_irq);
+}
+
+struct sys_timer ioc_timer = {
+ .init = ioc_timer_init,
+ .offset = ioc_timer_gettimeoffset,
+};
+
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
new file mode 100644
index 00000000..41df4787
--- /dev/null
+++ b/arch/arm/common/timer-sp.c
@@ -0,0 +1,172 @@
+/*
+ * linux/arch/arm/common/timer-sp.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/arm_timer.h>
+
+static long __init sp804_get_clock_rate(const char *name)
+{
+ struct clk *clk;
+ long rate;
+ int err;
+
+ clk = clk_get_sys("sp804", name);
+ if (IS_ERR(clk)) {
+ pr_err("sp804: %s clock not found: %d\n", name,
+ (int)PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+
+ err = clk_enable(clk);
+ if (err) {
+ pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+ clk_put(clk);
+ return err;
+ }
+
+ rate = clk_get_rate(clk);
+ if (rate < 0) {
+ pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+ clk_disable(clk);
+ clk_put(clk);
+ }
+
+ return rate;
+}
+
+void __init sp804_clocksource_init(void __iomem *base, const char *name)
+{
+ long rate = sp804_get_clock_rate(name);
+
+ if (rate < 0)
+ return;
+
+ /* setup timer 0 as free-running clocksource */
+ writel(0, base + TIMER_CTRL);
+ writel(0xffffffff, base + TIMER_LOAD);
+ writel(0xffffffff, base + TIMER_VALUE);
+ writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
+ base + TIMER_CTRL);
+
+ clocksource_mmio_init(base + TIMER_VALUE, name,
+ rate, 200, 32, clocksource_mmio_readl_down);
+}
+
+
+static void __iomem *clkevt_base;
+static unsigned long clkevt_reload;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* clear the interrupt */
+ writel(1, clkevt_base + TIMER_INTCLR);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static void sp804_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE;
+
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ writel(clkevt_reload, clkevt_base + TIMER_LOAD);
+ ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set, and timer enabled in 'next_event' hook */
+ ctrl |= TIMER_CTRL_ONESHOT;
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ break;
+ }
+
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int sp804_set_next_event(unsigned long next,
+ struct clock_event_device *evt)
+{
+ unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+ writel(next, clkevt_base + TIMER_LOAD);
+ writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+ return 0;
+}
+
+static struct clock_event_device sp804_clockevent = {
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = sp804_set_mode,
+ .set_next_event = sp804_set_next_event,
+ .rating = 300,
+ .cpumask = cpu_all_mask,
+};
+
+static struct irqaction sp804_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = sp804_timer_interrupt,
+ .dev_id = &sp804_clockevent,
+};
+
+void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
+ const char *name)
+{
+ struct clock_event_device *evt = &sp804_clockevent;
+ long rate = sp804_get_clock_rate(name);
+
+ if (rate < 0)
+ return;
+
+ clkevt_base = base;
+ clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
+
+ evt->name = name;
+ evt->irq = irq;
+ evt->mult = div_sc(rate, NSEC_PER_SEC, evt->shift);
+ evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
+ evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+ setup_irq(irq, &sp804_timer_irq);
+ clockevents_register_device(evt);
+}
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
new file mode 100644
index 00000000..bef408f3
--- /dev/null
+++ b/arch/arm/common/uengine.c
@@ -0,0 +1,507 @@
+/*
+ * Generic library functions for the microengines found on the Intel
+ * IXP2000 series of network processors.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/hardware/uengine.h>
+
+#if defined(CONFIG_ARCH_IXP2000)
+#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE
+#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID
+#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL
+#define IXP_RESET1 IXP2000_RESET1
+#else
+#if defined(CONFIG_ARCH_IXP23XX)
+#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE
+#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID
+#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL
+#define IXP_RESET1 IXP23XX_RESET1
+#else
+#error unknown platform
+#endif
+#endif
+
+#define USTORE_ADDRESS 0x000
+#define USTORE_DATA_LOWER 0x004
+#define USTORE_DATA_UPPER 0x008
+#define CTX_ENABLES 0x018
+#define CC_ENABLE 0x01c
+#define CSR_CTX_POINTER 0x020
+#define INDIRECT_CTX_STS 0x040
+#define ACTIVE_CTX_STS 0x044
+#define INDIRECT_CTX_SIG_EVENTS 0x048
+#define INDIRECT_CTX_WAKEUP_EVENTS 0x050
+#define NN_PUT 0x080
+#define NN_GET 0x084
+#define TIMESTAMP_LOW 0x0c0
+#define TIMESTAMP_HIGH 0x0c4
+#define T_INDEX_BYTE_INDEX 0x0f4
+#define LOCAL_CSR_STATUS 0x180
+
+u32 ixp2000_uengine_mask;
+
+static void *ixp2000_uengine_csr_area(int uengine)
+{
+ return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
+}
+
+/*
+ * LOCAL_CSR_STATUS=1 after a read or write to a microengine's CSR
+ * space means that the microengine we tried to access was also trying
+ * to access its own CSR space on the same clock cycle as we did. When
+ * this happens, we lose the arbitration process by default, and the
+ * read or write we tried to do was not actually performed, so we try
+ * again until it succeeds.
+ */
+u32 ixp2000_uengine_csr_read(int uengine, int offset)
+{
+ void *uebase;
+ u32 *local_csr_status;
+ u32 *reg;
+ u32 value;
+
+ uebase = ixp2000_uengine_csr_area(uengine);
+
+ local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
+ reg = (u32 *)(uebase + offset);
+ do {
+ value = ixp2000_reg_read(reg);
+ } while (ixp2000_reg_read(local_csr_status) & 1);
+
+ return value;
+}
+EXPORT_SYMBOL(ixp2000_uengine_csr_read);
+
+void ixp2000_uengine_csr_write(int uengine, int offset, u32 value)
+{
+ void *uebase;
+ u32 *local_csr_status;
+ u32 *reg;
+
+ uebase = ixp2000_uengine_csr_area(uengine);
+
+ local_csr_status = (u32 *)(uebase + LOCAL_CSR_STATUS);
+ reg = (u32 *)(uebase + offset);
+ do {
+ ixp2000_reg_write(reg, value);
+ } while (ixp2000_reg_read(local_csr_status) & 1);
+}
+EXPORT_SYMBOL(ixp2000_uengine_csr_write);
+
+void ixp2000_uengine_reset(u32 uengine_mask)
+{
+ u32 value;
+
+ value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask;
+
+ uengine_mask &= ixp2000_uengine_mask;
+ ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask);
+ ixp2000_reg_wrb(IXP_RESET1, value);
+}
+EXPORT_SYMBOL(ixp2000_uengine_reset);
+
+void ixp2000_uengine_set_mode(int uengine, u32 mode)
+{
+ /*
+ * CTL_STR_PAR_EN: unconditionally enable parity checking on
+ * control store.
+ */
+ mode |= 0x10000000;
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mode);
+
+ /*
+ * Enable updating of condition codes.
+ */
+ ixp2000_uengine_csr_write(uengine, CC_ENABLE, 0x00002000);
+
+ /*
+ * Initialise other per-microengine registers.
+ */
+ ixp2000_uengine_csr_write(uengine, NN_PUT, 0x00);
+ ixp2000_uengine_csr_write(uengine, NN_GET, 0x00);
+ ixp2000_uengine_csr_write(uengine, T_INDEX_BYTE_INDEX, 0);
+}
+EXPORT_SYMBOL(ixp2000_uengine_set_mode);
+
+static int make_even_parity(u32 x)
+{
+ return hweight32(x) & 1;
+}
+
+static void ustore_write(int uengine, u64 insn)
+{
+ /*
+ * Generate even parity for top and bottom 20 bits.
+ */
+ insn |= (u64)make_even_parity((insn >> 20) & 0x000fffff) << 41;
+ insn |= (u64)make_even_parity(insn & 0x000fffff) << 40;
+
+ /*
+ * Write to microstore. The second write auto-increments
+ * the USTORE_ADDRESS index register.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_DATA_LOWER, (u32)insn);
+ ixp2000_uengine_csr_write(uengine, USTORE_DATA_UPPER, (u32)(insn >> 32));
+}
+
+void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns)
+{
+ int i;
+
+ /*
+ * Start writing to microstore at address 0.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x80000000);
+ for (i = 0; i < insns; i++) {
+ u64 insn;
+
+ insn = (((u64)ucode[0]) << 32) |
+ (((u64)ucode[1]) << 24) |
+ (((u64)ucode[2]) << 16) |
+ (((u64)ucode[3]) << 8) |
+ ((u64)ucode[4]);
+ ucode += 5;
+
+ ustore_write(uengine, insn);
+ }
+
+ /*
+ * Pad with a few NOPs at the end (to avoid the microengine
+ * aborting as it prefetches beyond the last instruction), unless
+ * we run off the end of the instruction store first, at which
+ * point the address register will wrap back to zero.
+ */
+ for (i = 0; i < 4; i++) {
+ u32 addr;
+
+ addr = ixp2000_uengine_csr_read(uengine, USTORE_ADDRESS);
+ if (addr == 0x80000000)
+ break;
+ ustore_write(uengine, 0xf0000c0300ULL);
+ }
+
+ /*
+ * End programming.
+ */
+ ixp2000_uengine_csr_write(uengine, USTORE_ADDRESS, 0x00000000);
+}
+EXPORT_SYMBOL(ixp2000_uengine_load_microcode);
+
+void ixp2000_uengine_init_context(int uengine, int context, int pc)
+{
+ /*
+ * Select the right context for indirect access.
+ */
+ ixp2000_uengine_csr_write(uengine, CSR_CTX_POINTER, context);
+
+ /*
+ * Initialise signal masks to immediately go to Ready state.
+ */
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_SIG_EVENTS, 1);
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_WAKEUP_EVENTS, 1);
+
+ /*
+ * Set program counter.
+ */
+ ixp2000_uengine_csr_write(uengine, INDIRECT_CTX_STS, pc);
+}
+EXPORT_SYMBOL(ixp2000_uengine_init_context);
+
+void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask)
+{
+ u32 mask;
+
+ /*
+ * Enable the specified context to go to Executing state.
+ */
+ mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
+ mask |= ctx_mask << 8;
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
+}
+EXPORT_SYMBOL(ixp2000_uengine_start_contexts);
+
+void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask)
+{
+ u32 mask;
+
+ /*
+ * Disable the Ready->Executing transition. Note that this
+ * does not stop the context until it voluntarily yields.
+ */
+ mask = ixp2000_uengine_csr_read(uengine, CTX_ENABLES);
+ mask &= ~(ctx_mask << 8);
+ ixp2000_uengine_csr_write(uengine, CTX_ENABLES, mask);
+}
+EXPORT_SYMBOL(ixp2000_uengine_stop_contexts);
+
+static int check_ixp_type(struct ixp2000_uengine_code *c)
+{
+ u32 product_id;
+ u32 rev;
+
+ product_id = ixp2000_reg_read(IXP_PRODUCT_ID);
+ if (((product_id >> 16) & 0x1f) != 0)
+ return 0;
+
+ switch ((product_id >> 8) & 0xff) {
+#ifdef CONFIG_ARCH_IXP2000
+ case 0: /* IXP2800 */
+ if (!(c->cpu_model_bitmask & 4))
+ return 0;
+ break;
+
+ case 1: /* IXP2850 */
+ if (!(c->cpu_model_bitmask & 8))
+ return 0;
+ break;
+
+ case 2: /* IXP2400 */
+ if (!(c->cpu_model_bitmask & 2))
+ return 0;
+ break;
+#endif
+
+#ifdef CONFIG_ARCH_IXP23XX
+ case 4: /* IXP23xx */
+ if (!(c->cpu_model_bitmask & 0x3f0))
+ return 0;
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ rev = product_id & 0xff;
+ if (rev < c->cpu_min_revision || rev > c->cpu_max_revision)
+ return 0;
+
+ return 1;
+}
+
+static void generate_ucode(u8 *ucode, u32 *gpr_a, u32 *gpr_b)
+{
+ int offset;
+ int i;
+
+ offset = 0;
+
+ for (i = 0; i < 128; i++) {
+ u8 b3;
+ u8 b2;
+ u8 b1;
+ u8 b0;
+
+ b3 = (gpr_a[i] >> 24) & 0xff;
+ b2 = (gpr_a[i] >> 16) & 0xff;
+ b1 = (gpr_a[i] >> 8) & 0xff;
+ b0 = gpr_a[i] & 0xff;
+
+ /* immed[@ai, (b1 << 8) | b0] */
+ /* 11110000 0000VVVV VVVV11VV VVVVVV00 1IIIIIII */
+ ucode[offset++] = 0xf0;
+ ucode[offset++] = (b1 >> 4);
+ ucode[offset++] = (b1 << 4) | 0x0c | (b0 >> 6);
+ ucode[offset++] = (b0 << 2);
+ ucode[offset++] = 0x80 | i;
+
+ /* immed_w1[@ai, (b3 << 8) | b2] */
+ /* 11110100 0100VVVV VVVV11VV VVVVVV00 1IIIIIII */
+ ucode[offset++] = 0xf4;
+ ucode[offset++] = 0x40 | (b3 >> 4);
+ ucode[offset++] = (b3 << 4) | 0x0c | (b2 >> 6);
+ ucode[offset++] = (b2 << 2);
+ ucode[offset++] = 0x80 | i;
+ }
+
+ for (i = 0; i < 128; i++) {
+ u8 b3;
+ u8 b2;
+ u8 b1;
+ u8 b0;
+
+ b3 = (gpr_b[i] >> 24) & 0xff;
+ b2 = (gpr_b[i] >> 16) & 0xff;
+ b1 = (gpr_b[i] >> 8) & 0xff;
+ b0 = gpr_b[i] & 0xff;
+
+ /* immed[@bi, (b1 << 8) | b0] */
+ /* 11110000 0000VVVV VVVV001I IIIIII11 VVVVVVVV */
+ ucode[offset++] = 0xf0;
+ ucode[offset++] = (b1 >> 4);
+ ucode[offset++] = (b1 << 4) | 0x02 | (i >> 6);
+ ucode[offset++] = (i << 2) | 0x03;
+ ucode[offset++] = b0;
+
+ /* immed_w1[@bi, (b3 << 8) | b2] */
+ /* 11110100 0100VVVV VVVV001I IIIIII11 VVVVVVVV */
+ ucode[offset++] = 0xf4;
+ ucode[offset++] = 0x40 | (b3 >> 4);
+ ucode[offset++] = (b3 << 4) | 0x02 | (i >> 6);
+ ucode[offset++] = (i << 2) | 0x03;
+ ucode[offset++] = b2;
+ }
+
+ /* ctx_arb[kill] */
+ ucode[offset++] = 0xe0;
+ ucode[offset++] = 0x00;
+ ucode[offset++] = 0x01;
+ ucode[offset++] = 0x00;
+ ucode[offset++] = 0x00;
+}
+
+static int set_initial_registers(int uengine, struct ixp2000_uengine_code *c)
+{
+ int per_ctx_regs;
+ u32 *gpr_a;
+ u32 *gpr_b;
+ u8 *ucode;
+ int i;
+
+ gpr_a = kzalloc(128 * sizeof(u32), GFP_KERNEL);
+ gpr_b = kzalloc(128 * sizeof(u32), GFP_KERNEL);
+ ucode = kmalloc(513 * 5, GFP_KERNEL);
+ if (gpr_a == NULL || gpr_b == NULL || ucode == NULL) {
+ kfree(ucode);
+ kfree(gpr_b);
+ kfree(gpr_a);
+ return 1;
+ }
+
+ per_ctx_regs = 16;
+ if (c->uengine_parameters & IXP2000_UENGINE_4_CONTEXTS)
+ per_ctx_regs = 32;
+
+ for (i = 0; i < 256; i++) {
+ struct ixp2000_reg_value *r = c->initial_reg_values + i;
+ u32 *bank;
+ int inc;
+ int j;
+
+ if (r->reg == -1)
+ break;
+
+ bank = (r->reg & 0x400) ? gpr_b : gpr_a;
+ inc = (r->reg & 0x80) ? 128 : per_ctx_regs;
+
+ j = r->reg & 0x7f;
+ while (j < 128) {
+ bank[j] = r->value;
+ j += inc;
+ }
+ }
+
+ generate_ucode(ucode, gpr_a, gpr_b);
+ ixp2000_uengine_load_microcode(uengine, ucode, 513);
+ ixp2000_uengine_init_context(uengine, 0, 0);
+ ixp2000_uengine_start_contexts(uengine, 0x01);
+ for (i = 0; i < 100; i++) {
+ u32 status;
+
+ status = ixp2000_uengine_csr_read(uengine, ACTIVE_CTX_STS);
+ if (!(status & 0x80000000))
+ break;
+ }
+ ixp2000_uengine_stop_contexts(uengine, 0x01);
+
+ kfree(ucode);
+ kfree(gpr_b);
+ kfree(gpr_a);
+
+ return !!(i == 100);
+}
+
+int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c)
+{
+ int ctx;
+
+ if (!check_ixp_type(c))
+ return 1;
+
+ if (!(ixp2000_uengine_mask & (1 << uengine)))
+ return 1;
+
+ ixp2000_uengine_reset(1 << uengine);
+ ixp2000_uengine_set_mode(uengine, c->uengine_parameters);
+ if (set_initial_registers(uengine, c))
+ return 1;
+ ixp2000_uengine_load_microcode(uengine, c->insns, c->num_insns);
+
+ for (ctx = 0; ctx < 8; ctx++)
+ ixp2000_uengine_init_context(uengine, ctx, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(ixp2000_uengine_load);
+
+
+static int __init ixp2000_uengine_init(void)
+{
+ int uengine;
+ u32 value;
+
+ /*
+ * Determine number of microengines present.
+ */
+ switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) {
+#ifdef CONFIG_ARCH_IXP2000
+ case 0: /* IXP2800 */
+ case 1: /* IXP2850 */
+ ixp2000_uengine_mask = 0x00ff00ff;
+ break;
+
+ case 2: /* IXP2400 */
+ ixp2000_uengine_mask = 0x000f000f;
+ break;
+#endif
+
+#ifdef CONFIG_ARCH_IXP23XX
+ case 4: /* IXP23xx */
+ ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf;
+ break;
+#endif
+
+ default:
+ printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
+ (unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID));
+ ixp2000_uengine_mask = 0x00000000;
+ break;
+ }
+
+ /*
+ * Reset microengines.
+ */
+ ixp2000_uengine_reset(ixp2000_uengine_mask);
+
+ /*
+ * Synchronise timestamp counters across all microengines.
+ */
+ value = ixp2000_reg_read(IXP_MISC_CONTROL);
+ ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80);
+ for (uengine = 0; uengine < 32; uengine++) {
+ if (ixp2000_uengine_mask & (1 << uengine)) {
+ ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
+ ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
+ }
+ }
+ ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80);
+
+ return 0;
+}
+
+subsys_initcall(ixp2000_uengine_init);
diff --git a/arch/arm/common/via82c505.c b/arch/arm/common/via82c505.c
new file mode 100644
index 00000000..8421d391
--- /dev/null
+++ b/arch/arm/common/via82c505.c
@@ -0,0 +1,92 @@
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+
+#include <asm/mach/pci.h>
+
+#define MAX_SLOTS 7
+
+#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+static int
+via82c505_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ outl(CONFIG_CMD(bus,devfn,where),0xCF8);
+ switch (size) {
+ case 1:
+ *value=inb(0xCFC + (where&3));
+ break;
+ case 2:
+ *value=inw(0xCFC + (where&2));
+ break;
+ case 4:
+ *value=inl(0xCFC);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ outl(CONFIG_CMD(bus,devfn,where),0xCF8);
+ switch (size) {
+ case 1:
+ outb(value, 0xCFC + (where&3));
+ break;
+ case 2:
+ outw(value, 0xCFC + (where&2));
+ break;
+ case 4:
+ outl(value, 0xCFC);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops via82c505_ops = {
+ .read = via82c505_read_config,
+ .write = via82c505_write_config,
+};
+
+void __init via82c505_preinit(void)
+{
+ printk(KERN_DEBUG "PCI: VIA 82c505\n");
+ if (!request_region(0xA8,2,"via config")) {
+ printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
+ return;
+ }
+ if (!request_region(0xCF8,8,"pci config")) {
+ printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
+ release_region(0xA8, 2);
+ return;
+ }
+
+ /* Enable compatible Mode */
+ outb(0x96,0xA8);
+ outb(0x18,0xA9);
+ outb(0x93,0xA8);
+ outb(0xd0,0xA9);
+
+}
+
+int __init via82c505_setup(int nr, struct pci_sys_data *sys)
+{
+ return (nr == 0);
+}
+
+struct pci_bus * __init via82c505_scan_bus(int nr, struct pci_sys_data *sysdata)
+{
+ if (nr == 0)
+ return pci_scan_bus(0, &via82c505_ops, sysdata);
+
+ return NULL;
+}
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
new file mode 100644
index 00000000..7aa4262a
--- /dev/null
+++ b/arch/arm/common/vic.c
@@ -0,0 +1,379 @@
+/*
+ * linux/arch/arm/common/vic.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware/vic.h>
+
+#ifdef CONFIG_PM
+/**
+ * struct vic_device - VIC PM device
+ * @irq: The IRQ number for the base of the VIC.
+ * @base: The register base for the VIC.
+ * @resume_sources: A bitmask of interrupts for resume.
+ * @resume_irqs: The IRQs enabled for resume.
+ * @int_select: Save for VIC_INT_SELECT.
+ * @int_enable: Save for VIC_INT_ENABLE.
+ * @soft_int: Save for VIC_INT_SOFT.
+ * @protect: Save for VIC_PROTECT.
+ */
+struct vic_device {
+ void __iomem *base;
+ int irq;
+ u32 resume_sources;
+ u32 resume_irqs;
+ u32 int_select;
+ u32 int_enable;
+ u32 soft_int;
+ u32 protect;
+};
+
+/* we cannot allocate memory when VICs are initially registered */
+static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];
+
+static int vic_id;
+#endif /* CONFIG_PM */
+
+/**
+ * vic_init2 - common initialisation code
+ * @base: Base of the VIC.
+ *
+ * Common initialisation code for registration
+ * and resume.
+*/
+static void vic_init2(void __iomem *base)
+{
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+ writel(VIC_VECT_CNTL_ENABLE | i, reg);
+ }
+
+ writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+}
+
+#ifdef CONFIG_PM
+static void resume_one_vic(struct vic_device *vic)
+{
+ void __iomem *base = vic->base;
+
+ printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
+
+ /* re-initialise static settings */
+ vic_init2(base);
+
+ writel(vic->int_select, base + VIC_INT_SELECT);
+ writel(vic->protect, base + VIC_PROTECT);
+
+ /* set the enabled ints and then clear the non-enabled */
+ writel(vic->int_enable, base + VIC_INT_ENABLE);
+ writel(~vic->int_enable, base + VIC_INT_ENABLE_CLEAR);
+
+ /* and the same for the soft-int register */
+
+ writel(vic->soft_int, base + VIC_INT_SOFT);
+ writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void vic_resume(void)
+{
+ int id;
+
+ for (id = vic_id - 1; id >= 0; id--)
+ resume_one_vic(vic_devices + id);
+}
+
+static void suspend_one_vic(struct vic_device *vic)
+{
+ void __iomem *base = vic->base;
+
+ printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
+
+ vic->int_select = readl(base + VIC_INT_SELECT);
+ vic->int_enable = readl(base + VIC_INT_ENABLE);
+ vic->soft_int = readl(base + VIC_INT_SOFT);
+ vic->protect = readl(base + VIC_PROTECT);
+
+ /* set the interrupts (if any) that are used for
+ * resuming the system */
+
+ writel(vic->resume_irqs, base + VIC_INT_ENABLE);
+ writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static int vic_suspend(void)
+{
+ int id;
+
+ for (id = 0; id < vic_id; id++)
+ suspend_one_vic(vic_devices + id);
+
+ return 0;
+}
+
+struct syscore_ops vic_syscore_ops = {
+ .suspend = vic_suspend,
+ .resume = vic_resume,
+};
+
+/**
+ * vic_pm_init - initicall to register VIC pm
+ *
+ * This is called via late_initcall() to register
+ * the resources for the VICs due to the early
+ * nature of the VIC's registration.
+*/
+static int __init vic_pm_init(void)
+{
+ if (vic_id > 0)
+ register_syscore_ops(&vic_syscore_ops);
+
+ return 0;
+}
+late_initcall(vic_pm_init);
+
+/**
+ * vic_pm_register - Register a VIC for later power management control
+ * @base: The base address of the VIC.
+ * @irq: The base IRQ for the VIC.
+ * @resume_sources: bitmask of interrupts allowed for resume sources.
+ *
+ * Register the VIC with the system device tree so that it can be notified
+ * of suspend and resume requests and ensure that the correct actions are
+ * taken to re-instate the settings on resume.
+ */
+static void __init vic_pm_register(void __iomem *base, unsigned int irq, u32 resume_sources)
+{
+ struct vic_device *v;
+
+ if (vic_id >= ARRAY_SIZE(vic_devices))
+ printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__);
+ else {
+ v = &vic_devices[vic_id];
+ v->base = base;
+ v->resume_sources = resume_sources;
+ v->irq = irq;
+ vic_id++;
+ }
+}
+#else
+static inline void vic_pm_register(void __iomem *base, unsigned int irq, u32 arg1) { }
+#endif /* CONFIG_PM */
+
+static void vic_ack_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
+ writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+ /* moreover, clear the soft-triggered, in case it was the reason */
+ writel(1 << irq, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void vic_mask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
+ writel(1 << irq, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void vic_unmask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ unsigned int irq = d->irq & 31;
+ writel(1 << irq, base + VIC_INT_ENABLE);
+}
+
+#if defined(CONFIG_PM)
+static struct vic_device *vic_from_irq(unsigned int irq)
+{
+ struct vic_device *v = vic_devices;
+ unsigned int base_irq = irq & ~31;
+ int id;
+
+ for (id = 0; id < vic_id; id++, v++) {
+ if (v->irq == base_irq)
+ return v;
+ }
+
+ return NULL;
+}
+
+static int vic_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct vic_device *v = vic_from_irq(d->irq);
+ unsigned int off = d->irq & 31;
+ u32 bit = 1 << off;
+
+ if (!v)
+ return -EINVAL;
+
+ if (!(bit & v->resume_sources))
+ return -EINVAL;
+
+ if (on)
+ v->resume_irqs |= bit;
+ else
+ v->resume_irqs &= ~bit;
+
+ return 0;
+}
+#else
+#define vic_set_wake NULL
+#endif /* CONFIG_PM */
+
+static struct irq_chip vic_chip = {
+ .name = "VIC",
+ .irq_ack = vic_ack_irq,
+ .irq_mask = vic_mask_irq,
+ .irq_unmask = vic_unmask_irq,
+ .irq_set_wake = vic_set_wake,
+};
+
+static void __init vic_disable(void __iomem *base)
+{
+ writel(0, base + VIC_INT_SELECT);
+ writel(0, base + VIC_INT_ENABLE);
+ writel(~0, base + VIC_INT_ENABLE_CLEAR);
+ writel(0, base + VIC_IRQ_STATUS);
+ writel(0, base + VIC_ITCR);
+ writel(~0, base + VIC_INT_SOFT_CLEAR);
+}
+
+static void __init vic_clear_interrupts(void __iomem *base)
+{
+ unsigned int i;
+
+ writel(0, base + VIC_PL190_VECT_ADDR);
+ for (i = 0; i < 19; i++) {
+ unsigned int value;
+
+ value = readl(base + VIC_PL190_VECT_ADDR);
+ writel(value, base + VIC_PL190_VECT_ADDR);
+ }
+}
+
+static void __init vic_set_irq_sources(void __iomem *base,
+ unsigned int irq_start, u32 vic_sources)
+{
+ unsigned int i;
+
+ for (i = 0; i < 32; i++) {
+ if (vic_sources & (1 << i)) {
+ unsigned int irq = irq_start + i;
+
+ irq_set_chip_and_handler(irq, &vic_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, base);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+}
+
+/*
+ * The PL190 cell from ARM has been modified by ST to handle 64 interrupts.
+ * The original cell has 32 interrupts, while the modified one has 64,
+ * replocating two blocks 0x00..0x1f in 0x20..0x3f. In that case
+ * the probe function is called twice, with base set to offset 000
+ * and 020 within the page. We call this "second block".
+ */
+static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources)
+{
+ unsigned int i;
+ int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0;
+
+ /* Disable all interrupts initially. */
+ vic_disable(base);
+
+ /*
+ * Make sure we clear all existing interrupts. The vector registers
+ * in this cell are after the second block of general registers,
+ * so we can address them using standard offsets, but only from
+ * the second base address, which is 0x20 in the page
+ */
+ if (vic_2nd_block) {
+ vic_clear_interrupts(base);
+
+ /* ST has 16 vectors as well, but we don't enable them by now */
+ for (i = 0; i < 16; i++) {
+ void __iomem *reg = base + VIC_VECT_CNTL0 + (i * 4);
+ writel(0, reg);
+ }
+
+ writel(32, base + VIC_PL190_DEF_VECT_ADDR);
+ }
+
+ vic_set_irq_sources(base, irq_start, vic_sources);
+}
+
+/**
+ * vic_init - initialise a vectored interrupt controller
+ * @base: iomem base address
+ * @irq_start: starting interrupt number, must be muliple of 32
+ * @vic_sources: bitmask of interrupt sources to allow
+ * @resume_sources: bitmask of interrupt sources to allow for resume
+ */
+void __init vic_init(void __iomem *base, unsigned int irq_start,
+ u32 vic_sources, u32 resume_sources)
+{
+ unsigned int i;
+ u32 cellid = 0;
+ enum amba_vendor vendor;
+
+ /* Identify which VIC cell this one is, by reading the ID */
+ for (i = 0; i < 4; i++) {
+ u32 addr = ((u32)base & PAGE_MASK) + 0xfe0 + (i * 4);
+ cellid |= (readl(addr) & 0xff) << (8 * i);
+ }
+ vendor = (cellid >> 12) & 0xff;
+ printk(KERN_INFO "VIC @%p: id 0x%08x, vendor 0x%02x\n",
+ base, cellid, vendor);
+
+ switch(vendor) {
+ case AMBA_VENDOR_ST:
+ vic_init_st(base, irq_start, vic_sources);
+ return;
+ default:
+ printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n");
+ /* fall through */
+ case AMBA_VENDOR_ARM:
+ break;
+ }
+
+ /* Disable all interrupts initially. */
+ vic_disable(base);
+
+ /* Make sure we clear all existing interrupts */
+ vic_clear_interrupts(base);
+
+ vic_init2(base);
+
+ vic_set_irq_sources(base, irq_start, vic_sources);
+
+ vic_pm_register(base, irq_start, resume_sources);
+}
diff --git a/arch/arm/configs/acs5k_defconfig b/arch/arm/configs/acs5k_defconfig
new file mode 100644
index 00000000..92b0f90d
--- /dev/null
+++ b/arch/arm/configs/acs5k_defconfig
@@ -0,0 +1,86 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_KS8695=y
+CONFIG_MACH_KS8695=y
+CONFIG_MACH_DSM320=y
+CONFIG_MACH_ACS5K=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCCARD=y
+CONFIG_YENTA=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_KS8695_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PRISM54=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_WATCHDOG=y
+CONFIG_KS8695_WATCHDOG=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/acs5k_tiny_defconfig b/arch/arm/configs/acs5k_tiny_defconfig
new file mode 100644
index 00000000..2a27a147
--- /dev/null
+++ b/arch/arm/configs/acs5k_tiny_defconfig
@@ -0,0 +1,80 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_KS8695=y
+CONFIG_MACH_ACS5K=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 init=/bin/sh"
+CONFIG_FPE_NWFPE=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_KS8695_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_KS8695_WATCHDOG=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_SQUASHFS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig
new file mode 100644
index 00000000..2afdf67c
--- /dev/null
+++ b/arch/arm/configs/afeb9260_defconfig
@@ -0,0 +1,107 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_AFEB9260=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_SSC=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DEBUG=y
+CONFIG_RTC_DRV_FM3130=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+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_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRC_T10DIF=y
diff --git a/arch/arm/configs/ag5evm_defconfig b/arch/arm/configs/ag5evm_defconfig
new file mode 100644
index 00000000..212ead35
--- /dev/null
+++ b/arch/arm/configs/ag5evm_defconfig
@@ -0,0 +1,83 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_NAMESPACES=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_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH73A0=y
+CONFIG_MACH_AG5EVM=y
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_CPU_BPREDICT_DISABLE=y
+CONFIG_ARM_ERRATA_430973=y
+CONFIG_ARM_ERRATA_458693=y
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty0 console=ttySC2,115200 earlyprintk=sh-sci.2,115200 ignore_loglevel"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_PM_RUNTIME=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_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_BLK_DEV 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_SPARSEKMAP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=9
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_FTRACE is not set
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
new file mode 100644
index 00000000..f0dea52e
--- /dev/null
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -0,0 +1,108 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="gum"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SHMEM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_ARCH_GUMSTIX=y
+CONFIG_PCCARD=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,115200n8 root=1f01 rootfstype=jffs2"
+CONFIG_NET=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=m
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+CONFIG_FB_VIRTUAL=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_PXA2XX_AC97=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_ARC4=m
diff --git a/arch/arm/configs/android_common_defconfig b/arch/arm/configs/android_common_defconfig
new file mode 100644
index 00000000..f3477ebd
--- /dev/null
+++ b/arch/arm/configs/android_common_defconfig
@@ -0,0 +1,153 @@
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_ASHMEM=y
+CONFIG_SLAB=y
+CONFIG_MXC_REBOOT_MFGMODE=y
+CONFIG_MXC_REBOOT_ANDROID_CMD=y
+CONFIG_VMSPLIT_3G=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_CPUFREQ_GOV_ON_EARLYSUPSEND=y
+CONFIG_WAKELOCK=y
+CONFIG_WAKELOCK_STAT=y
+CONFIG_USER_WAKELOCK=y
+CONFIG_EARLYSUSPEND=y
+CONFIG_FB_EARLYSUSPEND=y
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+CONFIG_NET_IPIP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=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=y
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_ANDROID_PARANOID_NETWORK=y
+CONFIG_NET_ACTIVITY_STATS=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_ADVANCED=y
+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=y
+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=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XTABLES=y
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+CONFIG_IP_NF_QUEUE=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_QUEUE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_NET_IPGRE_DEMUX=y
+CONFIG_PPTP=y
+CONFIG_CFG80211=m
+CONFIG_SUSPEND_COUNTER=y
+CONFIG_UID_STAT=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_TUN=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN=y
+CONFIG_DEVMEM=y
+CONFIG_ION=y
+CONFIG_ION_MXC=y
+CONFIG_USB_ACM=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_QUALCOMM=y
+CONFIG_USB_SERIAL_WWAN=y
+CONFIG_USB_SERIAL_OPTION=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_OTG_WAKELOCK=y
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_SLEEP=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+CONFIG_STAGING=y
+
+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_TIMED_OUTPUT=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_MACH_NO_WESTBRIDGE=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_KEYS=y
diff --git a/arch/arm/configs/ap4evb_defconfig b/arch/arm/configs/ap4evb_defconfig
new file mode 100644
index 00000000..2eef85e3
--- /dev/null
+++ b/arch/arm/configs/ap4evb_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH7372=y
+CONFIG_MACH_AP4EVB=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=sh-sci.0,115200"
+CONFIG_KEXEC=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig
new file mode 100644
index 00000000..558ecd8f
--- /dev/null
+++ b/arch/arm/configs/assabet_defconfig
@@ -0,0 +1,60 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_ASSABET=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttySA0,38400n8 initrd=0xc0800000,3M root=/dev/ram"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_SA1100_FIR=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_SA1100=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig
new file mode 100644
index 00000000..ffb1edd9
--- /dev/null
+++ b/arch/arm/configs/at91cap9adk_defconfig
@@ -0,0 +1,115 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91CAP9=y
+CONFIG_MACH_AT91CAP9ADK=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_DATAFLASH=y
+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_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/at91rm9200_defconfig b/arch/arm/configs/at91rm9200_defconfig
new file mode 100644
index 00000000..38cb7c98
--- /dev/null
+++ b/arch/arm/configs/at91rm9200_defconfig
@@ -0,0 +1,341 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_MACH_ONEARM=y
+CONFIG_ARCH_AT91RM9200DK=y
+CONFIG_MACH_AT91RM9200EK=y
+CONFIG_MACH_CSB337=y
+CONFIG_MACH_CSB637=y
+CONFIG_MACH_CARMEVA=y
+CONFIG_MACH_ATEB9200=y
+CONFIG_MACH_KB9200=y
+CONFIG_MACH_PICOTUX2XX=y
+CONFIG_MACH_KAFA=y
+CONFIG_MACH_ECBAT91=y
+CONFIG_MACH_YL9200=y
+CONFIG_MACH_CPUAT91=y
+CONFIG_MACH_ECO920=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_TIMER_HZ=100
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_AT91_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=0x10000000
+CONFIG_ZBOOT_ROM_BSS=0x20040000
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_TCLIB=y
+CONFIG_EEPROM_LEGACY=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_PHYLIB=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_MICREL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_AT91_ETHER=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_BITBANG=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_HWMON=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_ADM1025=m
+CONFIG_SENSORS_ADM1026=m
+CONFIG_SENSORS_ADM1029=m
+CONFIG_SENSORS_ADM1031=m
+CONFIG_SENSORS_ADM9240=m
+CONFIG_SENSORS_DS1621=m
+CONFIG_SENSORS_GL518SM=m
+CONFIG_SENSORS_GL520SM=m
+CONFIG_SENSORS_IT87=m
+CONFIG_SENSORS_LM63=m
+CONFIG_SENSORS_LM73=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM77=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM80=m
+CONFIG_SENSORS_LM83=m
+CONFIG_SENSORS_LM85=m
+CONFIG_SENSORS_LM87=m
+CONFIG_SENSORS_LM90=m
+CONFIG_SENSORS_LM92=m
+CONFIG_SENSORS_MAX1619=m
+CONFIG_SENSORS_PCF8591=m
+CONFIG_SENSORS_SMSC47B397=m
+CONFIG_SENSORS_W83781D=m
+CONFIG_SENSORS_W83791D=m
+CONFIG_SENSORS_W83792D=m
+CONFIG_SENSORS_W83793=m
+CONFIG_SENSORS_W83L785TS=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91RM9200_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_DISPLAY_SUPPORT=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_KEYSPAN=y
+CONFIG_USB_SERIAL_KEYSPAN_MPR=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
+CONFIG_USB_SERIAL_MCT_U232=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=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_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_AT91RM9200=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_REISERFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_SHA1=y
diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig
new file mode 100644
index 00000000..f8a92264
--- /dev/null
+++ b/arch/arm/configs/at91sam9260ek_defconfig
@@ -0,0 +1,83 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_AT91SAM9260EK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91sam9261_defconfig b/arch/arm/configs/at91sam9261_defconfig
new file mode 100644
index 00000000..ade6b2f2
--- /dev/null
+++ b/arch/arm/configs/at91sam9261_defconfig
@@ -0,0 +1,158 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9261=y
+CONFIG_MACH_AT91SAM9261EK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_LIB80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_ZD1201=m
+CONFIG_RTL8187=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_ZD1211RW=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=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_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_AT73C213=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+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_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=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_FTRACE=y
+CONFIG_CRC_CCITT=m
diff --git a/arch/arm/configs/at91sam9263_defconfig b/arch/arm/configs/at91sam9263_defconfig
new file mode 100644
index 00000000..1cf96264
--- /dev/null
+++ b/arch/arm/configs/at91sam9263_defconfig
@@ -0,0 +1,168 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9263=y
+CONFIG_MACH_AT91SAM9263EK=y
+CONFIG_MACH_USB_A9263=y
+CONFIG_MACH_NEOCORE926=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_ZD1201=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_LEGACY_PTY_COUNT=4
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=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_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_ATMEL_AC97C=y
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_AT91=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_ATMEL_PWM=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=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_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_FTRACE=y
+CONFIG_DEBUG_USER=y
+CONFIG_XZ_DEC=y
diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig
new file mode 100644
index 00000000..9e90e6d7
--- /dev/null
+++ b/arch/arm/configs/at91sam9g20ek_defconfig
@@ -0,0 +1,123 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_AT91SAM9G20EK=y
+CONFIG_MACH_AT91SAM9G20EK_2MMC=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 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_DATAFLASH=y
+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_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_HW_RANDOM=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_SPIDEV=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_AT73C213=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+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_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=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_ENABLE_WARN_DEPRECATED is not set
diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig
new file mode 100644
index 00000000..75621e4d
--- /dev/null
+++ b/arch/arm/configs/at91sam9rlek_defconfig
@@ -0,0 +1,84 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9RL=y
+CONFIG_MACH_AT91SAM9RLEK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,17105363 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+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_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=24576
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=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_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/at91x40_defconfig b/arch/arm/configs/at91x40_defconfig
new file mode 100644
index 00000000..c55e9212
--- /dev/null
+++ b/arch/arm/configs/at91x40_defconfig
@@ -0,0 +1,48 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EMBEDDED=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_FUTEX is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=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_MMU is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91X40=y
+CONFIG_MACH_AT91EB01=y
+CONFIG_AT91_EARLY_USART0=y
+CONFIG_CPU_ARM7TDMI=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x01000000
+CONFIG_DRAM_SIZE=0x00400000
+CONFIG_FLASH_MEM_BASE=0x01400000
+CONFIG_PROCESSOR_ID=0x14000040
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_BINFMT_FLAT=y
+# CONFIG_SUSPEND is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig
new file mode 100644
index 00000000..5b54abbe
--- /dev/null
+++ b/arch/arm/configs/badge4_defconfig
@@ -0,0 +1,122 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_BADGE4=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3"
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_ARTHUR=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=y
+CONFIG_IRLAN=y
+CONFIG_IRCOMM=y
+CONFIG_IRDA_ULTRA=y
+CONFIG_SA1100_FIR=y
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_SA1100=y
+CONFIG_PARPORT=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=y
+CONFIG_NETDEVICES=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_ELEKTOR=m
+CONFIG_WATCHDOG=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_SOUND=y
+CONFIG_SOUND_PRIME=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_RIO500=m
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=m
+CONFIG_MINIX_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_SMB_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/bcmring_defconfig b/arch/arm/configs/bcmring_defconfig
new file mode 100644
index 00000000..795374d4
--- /dev/null
+++ b/arch/arm/configs/bcmring_defconfig
@@ -0,0 +1,79 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_PERF_COUNTERS=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_BCMRING=y
+CONFIG_BCM_ZRELADDR=0x8000
+CONFIG_CPU_32v6K=y
+CONFIG_NO_HZ=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_UACCESS_WITH_MEMCPY=y
+CONFIG_ZBOOT_ROM_TEXT=0x0e000000
+CONFIG_ZBOOT_ROM_BSS=0x0ea00000
+CONFIG_ZBOOT_ROM=y
+CONFIG_NET=y
+# CONFIG_WIRELESS is not set
+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_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_BCM_UMI=y
+CONFIG_MTD_NAND_BCM_UMI_HWCS=y
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=64
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_SECURITY is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_HEADERS_CHECK=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_ARM_UNWIND is not set
diff --git a/arch/arm/configs/cam60_defconfig b/arch/arm/configs/cam60_defconfig
new file mode 100644
index 00000000..cedc92ef
--- /dev/null
+++ b/arch/arm/configs/cam60_defconfig
@@ -0,0 +1,174 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_AUDIT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_CAM60=y
+CONFIG_ZBOOT_ROM_BSS=0x20004000
+CONFIG_CMDLINE="console=ttyS0,115200 noinitrd root=/dev/mtdblock0 rootfstype=jffs2 mem=64M"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_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_NETWORK_SECMARK=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+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_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PLATRAM=m
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_LIBSAS=m
+# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=m
+CONFIG_DAVICOM_PHY=m
+CONFIG_QSEMI_PHY=m
+CONFIG_LXT_PHY=m
+CONFIG_CICADA_PHY=m
+CONFIG_VITESSE_PHY=m
+CONFIG_SMSC_PHY=m
+CONFIG_BROADCOM_PHY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_STOWAWAY=m
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_VSXXXAA=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_TEST=m
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig
new file mode 100644
index 00000000..dce912d1
--- /dev/null
+++ b/arch/arm/configs/cerfcube_defconfig
@@ -0,0 +1,75 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_CERF=y
+CONFIG_SA1100_CERF_FLASH_16MB=y
+CONFIG_PCCARD=m
+CONFIG_PCMCIA_SA1100=m
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySA0,38400 root=/dev/mtdblock3 rootfstype=jffs2 rw mem=32M init=/linuxrc"
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_FPE_FASTFPE=y
+CONFIG_PM=y
+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_IP_PNP_RARP=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig
new file mode 100644
index 00000000..a93ff8da
--- /dev/null
+++ b/arch/arm/configs/cm_x2xx_defconfig
@@ -0,0 +1,189 @@
+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_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_ARMCORE=y
+CONFIG_PCI=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+# CONFIG_YENTA_O2 is not set
+# CONFIG_YENTA_RICOH is not set
+# CONFIG_YENTA_ENE_TUNE is not set
+# CONFIG_YENTA_TOSHIBA is not set
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_BNEP=m
+CONFIG_BT_HIDP=m
+CONFIG_LIB80211=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPIO=m
+CONFIG_MTD_NAND_CM_X270=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=m
+# CONFIG_SATA_PMP is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=1
+CONFIG_NET_PCI=y
+CONFIG_8139TOO=m
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_PXA27x=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_UCB1400=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=m
+# CONFIG_HWMON is not set
+CONFIG_UCB1400_CORE=m
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+CONFIG_SND_PXA2XX_AC97=m
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=m
+CONFIG_MMC_PXA=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_V3020=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=m
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+CONFIG_FRAME_WARN=0
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig
new file mode 100644
index 00000000..921e56a7
--- /dev/null
+++ b/arch/arm/configs/cm_x300_defconfig
@@ -0,0 +1,188 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-cm-x300"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_CM_X300=y
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/mtdblock5 rootfstype=ubifs console=ttyS2,38400"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+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_IP_PNP_RARP=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_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_LIB80211=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=0
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PXA27x=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_DA9034 is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+# CONFIG_HWMON is not set
+CONFIG_PMIC_DA903X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DA903X=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_TDO24M=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_DA903X=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_6x11=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
+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_WACOM=m
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=m
+CONFIG_MMC_PXA=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_V3020=y
+CONFIG_RTC_DRV_PXA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_T10DIF=y
diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig
new file mode 100644
index 00000000..313627ad
--- /dev/null
+++ b/arch/arm/configs/cns3420vb_defconfig
@@ -0,0 +1,72 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_PERF_EVENTS is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_IOSCHED_CFQ=m
+CONFIG_ARCH_CNS3XXX=y
+CONFIG_MACH_CNS3420VB=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,38400 mem=128M root=/dev/mmcblk0p1 ro rootwait"
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL 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_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=20000
+# CONFIG_MISC_DEVICES is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+# CONFIG_ATA_SFF is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FSCACHE=y
+CONFIG_TMPFS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig
new file mode 100644
index 00000000..2ef2c5e8
--- /dev/null
+++ b/arch/arm/configs/colibri_pxa270_defconfig
@@ -0,0 +1,180 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=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_PXA=y
+CONFIG_MACH_COLIBRI=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=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_NETFILTER=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRTTY_SIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_CFG80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+CONFIG_MTD_ONENAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HOSTAP=y
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_SERIAL=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_MMC=y
+CONFIG_NEW_LEDS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=1
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V4=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig
new file mode 100644
index 00000000..b985334e
--- /dev/null
+++ b/arch/arm/configs/colibri_pxa300_defconfig
@@ -0,0 +1,73 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_COLIBRI300=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_AX88796=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_DEBUG_GPIO=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_PXA=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig
new file mode 100644
index 00000000..6c56ad08
--- /dev/null
+++ b/arch/arm/configs/collie_defconfig
@@ -0,0 +1,94 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_EPOLL is not set
+CONFIG_SLOB=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_COLLIE=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_PCMCIA_DEBUG=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd root=/dev/mtdblock2 rootfstype=jffs2 fbcon=rotate:1"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_CFI_I1 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_I4=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=1024
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_LOCOMO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CS=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HWMON is not set
+CONFIG_MCP_SA11X0=y
+CONFIG_MCP_UCB1200=y
+CONFIG_MCP_UCB1200_TS=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SA1100=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LOCOMO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
new file mode 100644
index 00000000..e53c4756
--- /dev/null
+++ b/arch/arm/configs/corgi_defconfig
@@ -0,0 +1,274 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_PXA_SHARPSL=y
+CONFIG_MACH_POODLE=y
+CONFIG_MACH_CORGI=y
+CONFIG_MACH_SHEPHERD=y
+CONFIG_MACH_HUSKY=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_PXA2XX=y
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_INET=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_PXA_FICP=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_SHARPSL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_I2C=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_FB=y
+CONFIG_FB_W100=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_CORGI=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_SOUND=y
+CONFIG_SOUND_PRIME=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/cpu9260_defconfig b/arch/arm/configs/cpu9260_defconfig
new file mode 100644
index 00000000..bbf729e2
--- /dev/null
+++ b/arch/arm/configs/cpu9260_defconfig
@@ -0,0 +1,116 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_CPU9260=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=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_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_VGA_CONSOLE 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=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+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_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/cpu9g20_defconfig b/arch/arm/configs/cpu9g20_defconfig
new file mode 100644
index 00000000..e7d79429
--- /dev/null
+++ b/arch/arm/configs/cpu9g20_defconfig
@@ -0,0 +1,116 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_CPU9G20=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=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_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_VGA_CONSOLE 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=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+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_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig
new file mode 100644
index 00000000..88ccde05
--- /dev/null
+++ b/arch/arm/configs/da8xx_omapl_defconfig
@@ -0,0 +1,129 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_DAVINCI=y
+CONFIG_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_MACH_MITYOMAPL138=y
+CONFIG_MACH_OMAPL138_HAWKBOARD=y
+CONFIG_DAVINCI_RESET_CLOCKS=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_LEDS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=m
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_IDLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+CONFIG_NETFILTER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_LXT_PHY=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_TI_DAVINCI_EMAC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DUMMY=y
+CONFIG_REGULATOR_TPS6507X=y
+CONFIG_FB=y
+CONFIG_FB_DA8XX=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_XFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SMB_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=m
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=m
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
new file mode 100644
index 00000000..67b5abb6
--- /dev/null
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -0,0 +1,194 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_DAVINCI=y
+CONFIG_ARCH_DAVINCI_DM644x=y
+CONFIG_ARCH_DAVINCI_DM355=y
+CONFIG_ARCH_DAVINCI_DM646x=y
+CONFIG_ARCH_DAVINCI_DM365=y
+CONFIG_MACH_SFFSDR=y
+CONFIG_MACH_NEUROS_OSD2=y
+CONFIG_MACH_DM355_LEOPARD=y
+CONFIG_DAVINCI_MUX_DEBUG=y
+CONFIG_DAVINCI_MUX_WARNINGS=y
+CONFIG_DAVINCI_RESET_CLOCKS=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_LEDS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+CONFIG_NETFILTER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_CFI=m
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_PHYSMAP=m
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_DAVINCI=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_EEPROM_AT24=y
+CONFIG_IDE=m
+CONFIG_BLK_DEV_PALMCHIP_BK3710=m
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_LXT_PHY=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_TI_DAVINCI_EMAC=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL_TRAP=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_ATKBD=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_DM355EVM=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DAVINCI=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_WATCHDOG=y
+CONFIG_DAVINCI_WATCHDOG=m
+CONFIG_MFD_DM355EVM_MSP=y
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+CONFIG_SND_DAVINCI_SOC_EVM=m
+CONFIG_SND_DM6467_SOC_EVM=m
+CONFIG_HID=m
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_PERIPHERAL=y
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_MUSB_PIO_ONLY=y
+CONFIG_USB_STORAGE=m
+CONFIG_USB_TEST=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=m
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_DAVINCI=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_RTC_CLASS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_XFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=m
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_SMB_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=m
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_T10DIF=m
diff --git a/arch/arm/configs/dove_defconfig b/arch/arm/configs/dove_defconfig
new file mode 100644
index 00000000..40db34cf
--- /dev/null
+++ b/arch/arm/configs/dove_defconfig
@@ -0,0 +1,127 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_DOVE=y
+CONFIG_MACH_DOVE_DB=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_MV643XX_ETH=y
+# CONFIG_NETDEV_10000 is not set
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+# CONFIG_HWMON is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/ebsa110_defconfig b/arch/arm/configs/ebsa110_defconfig
new file mode 100644
index 00000000..14559dbb
--- /dev/null
+++ b/arch/arm/configs/ebsa110_defconfig
@@ -0,0 +1,75 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_ARCH_EBSA110=y
+CONFIG_PCCARD=m
+CONFIG_I82365=m
+CONFIG_LEDS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_FASTFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_IPV6=y
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_IPTABLES=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_LOG=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_FW_LOADER=m
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_1284=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_AM79C961A=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_CS=m
+CONFIG_PRINTER=m
+CONFIG_WATCHDOG=y
+CONFIG_SOFT_WATCHDOG=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
diff --git a/arch/arm/configs/edb7211_defconfig b/arch/arm/configs/edb7211_defconfig
new file mode 100644
index 00000000..d52ded35
--- /dev/null
+++ b/arch/arm/configs/edb7211_defconfig
@@ -0,0 +1,27 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_ARCH_CLPS711X=y
+CONFIG_ARCH_EDB7211=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_NETDEVICES=y
+# CONFIG_INPUT is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_VT is not set
+CONFIG_SERIAL_CLPS711X=y
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+CONFIG_EXT2_FS=y
+CONFIG_MINIX_FS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig
new file mode 100644
index 00000000..60a21e01
--- /dev/null
+++ b/arch/arm/configs/em_x270_defconfig
@@ -0,0 +1,194 @@
+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_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_EM_X270=y
+CONFIG_MACH_EXEDA=y
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_BNEP=m
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_LIB80211=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+CONFIG_DM9000_DEBUGLEVEL=1
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_APMPOWER=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_DA9034 is not set
+CONFIG_TOUCHSCREEN_WM97XX=m
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_DA9030=y
+# CONFIG_HWMON is not set
+CONFIG_PMIC_DA903X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DA903X=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_FB_MBX=m
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_TDO24M=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_DA903X=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_EM_X270=m
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=m
+CONFIG_MMC_PXA=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_DA903X=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_V3020=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=m
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+CONFIG_FRAME_WARN=0
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ARC4=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
new file mode 100644
index 00000000..8e97b2f7
--- /dev/null
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -0,0 +1,124 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_EP93XX=y
+CONFIG_CRUNCH=y
+CONFIG_MACH_ADSSPHERE=y
+CONFIG_MACH_EDB9301=y
+CONFIG_MACH_EDB9302=y
+CONFIG_MACH_EDB9307=y
+CONFIG_MACH_EDB9312=y
+CONFIG_MACH_EDB9315=y
+CONFIG_MACH_GESBC9312=y
+CONFIG_MACH_MICRO9H=y
+CONFIG_MACH_MICRO9L=y
+CONFIG_MACH_TS72XX=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,115200 root=/dev/nfs ip=bootp"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=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_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_EEPROM_LEGACY=y
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_EP93XX_ETH=y
+CONFIG_USB_RTL8150=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_WATCHDOG=y
+CONFIG_EP93XX_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_CONSOLE=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_M48T86=y
+CONFIG_RTC_DRV_EP93XX=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig
new file mode 100644
index 00000000..d68ac67c
--- /dev/null
+++ b/arch/arm/configs/eseries_pxa_defconfig
@@ -0,0 +1,118 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_COMPAT_BRK 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_PXA=y
+CONFIG_ARCH_PXA_ESERIES=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_IWMMXT=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=y
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_PXA_FICP=y
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_RC_PID=y
+# CONFIG_MAC80211_RC_MINSTREL is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+CONFIG_MTD=m
+CONFIG_MTD_NAND=m
+CONFIG_MTD_NAND_TMIO=m
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=m
+# CONFIG_SATA_PMP is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_NET_PCMCIA=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=m
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_WM97XX=m
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_MFD_T7L66XB=y
+CONFIG_MFD_TC6387XB=y
+CONFIG_MFD_TC6393XB=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_W100=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_SOUND=y
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+CONFIG_SND_PXA2XX_SOC_E800=m
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_TMIO=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=m
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/exynos4_defconfig b/arch/arm/configs/exynos4_defconfig
new file mode 100644
index 00000000..da53ff3b
--- /dev/null
+++ b/arch/arm/configs/exynos4_defconfig
@@ -0,0 +1,72 @@
+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/ezx_defconfig b/arch/arm/configs/ezx_defconfig
new file mode 100644
index 00000000..d95763d5
--- /dev/null
+++ b/arch/arm/configs/ezx_defconfig
@@ -0,0 +1,420 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-ezx200910312315"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_EXPERT=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_PXA_EZX=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty1 root=/dev/mmcblk0p2 rootfstype=ext2 rootdelay=3 ip=192.168.0.202:192.168.0.200:192.168.0.200:255.255.255.0 debug"
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEBUG=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME=y
+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_IP_PNP_RARP=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_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE=m
+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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=m
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_OTP=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_PCAP=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_PCAP=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_HWMON is not set
+CONFIG_EZX_PCAP=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_PCAP=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# 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_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9M111=y
+CONFIG_VIDEO_PXA27x=y
+# CONFIG_V4L_USB_DRIVERS is not set
+CONFIG_RADIO_TEA5764=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+# CONFIG_USB_HID is not set
+CONFIG_HID_APPLE=m
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_PXA27X=y
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_PXA=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LP3944=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCAP=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=m
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_XFS_FS=m
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_PROVE_LOCKING=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/footbridge_defconfig b/arch/arm/configs/footbridge_defconfig
new file mode 100644
index 00000000..038518ab
--- /dev/null
+++ b/arch/arm/configs/footbridge_defconfig
@@ -0,0 +1,127 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_MODULES=y
+CONFIG_ARCH_FOOTBRIDGE=y
+CONFIG_ARCH_CATS=y
+CONFIG_ARCH_PERSONAL_SERVER=y
+CONFIG_ARCH_EBSA285_HOST=y
+CONFIG_ARCH_NETWINDER=y
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_ATM=y
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+CONFIG_WINBOND_FIR=m
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_1284=y
+CONFIG_PNP=y
+CONFIG_ISAPNP=y
+CONFIG_PARIDE=m
+CONFIG_PARIDE_PD=m
+CONFIG_PARIDE_PCD=m
+CONFIG_PARIDE_PF=m
+CONFIG_PARIDE_PT=m
+CONFIG_PARIDE_PG=m
+CONFIG_PARIDE_ATEN=m
+CONFIG_PARIDE_BPCK=m
+CONFIG_PARIDE_COMM=m
+CONFIG_PARIDE_DSTR=m
+CONFIG_PARIDE_FIT2=m
+CONFIG_PARIDE_FIT3=m
+CONFIG_PARIDE_EPAT=m
+CONFIG_PARIDE_EPIA=m
+CONFIG_PARIDE_FRIQ=m
+CONFIG_PARIDE_FRPW=m
+CONFIG_PARIDE_KBIC=m
+CONFIG_PARIDE_KTTI=m
+CONFIG_PARIDE_ON20=m
+CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_VENDOR_3COM=y
+CONFIG_VORTEX=y
+CONFIG_NET_PCI=y
+CONFIG_NE2K_PCI=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_21285=y
+CONFIG_SERIAL_21285_CONSOLE=y
+CONFIG_PRINTER=m
+CONFIG_DS1620=y
+CONFIG_NWBUTTON=y
+CONFIG_NWBUTTON_REBOOT=y
+CONFIG_NWFLASH=m
+CONFIG_I2C=m
+CONFIG_WATCHDOG=y
+CONFIG_SOFT_WATCHDOG=y
+CONFIG_21285_WATCHDOG=m
+CONFIG_977_WATCHDOG=m
+CONFIG_FB=y
+CONFIG_FB_CYBER2000=y
+CONFIG_SOUND=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=m
+CONFIG_USB_DEBUG=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_PRINTER=m
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_ADFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ADFS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/fortunet_defconfig b/arch/arm/configs/fortunet_defconfig
new file mode 100644
index 00000000..840fced7
--- /dev/null
+++ b/arch/arm/configs/fortunet_defconfig
@@ -0,0 +1,28 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_ARCH_CLPS711X=y
+CONFIG_ARCH_FORTUNET=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_FASTFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_CLPS711X=y
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+CONFIG_EXT2_FS=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/g3evm_defconfig b/arch/arm/configs/g3evm_defconfig
new file mode 100644
index 00000000..4a336ab5
--- /dev/null
+++ b/arch/arm/configs/g3evm_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH7367=y
+CONFIG_MACH_G3EVM=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200"
+CONFIG_KEXEC=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/g4evm_defconfig b/arch/arm/configs/g4evm_defconfig
new file mode 100644
index 00000000..21c6d030
--- /dev/null
+++ b/arch/arm/configs/g4evm_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH7377=y
+CONFIG_MACH_G4EVM=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySC4,115200 earlyprintk=sh-sci.4,115200"
+CONFIG_KEXEC=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
new file mode 100644
index 00000000..317960f1
--- /dev/null
+++ b/arch/arm/configs/h3600_defconfig
@@ -0,0 +1,79 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=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_SA1100=y
+CONFIG_SA1100_H3600=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_CPU_FREQ_STAT is not set
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_SA1100_FIR=m
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_MISC_DEVICES is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_SA1100=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=m
+CONFIG_NFS_FS=y
+CONFIG_NFSD=m
+CONFIG_SMB_FS=m
+CONFIG_NLS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/h5000_defconfig b/arch/arm/configs/h5000_defconfig
new file mode 100644
index 00000000..37903e3f
--- /dev/null
+++ b/arch/arm/configs/h5000_defconfig
@@ -0,0 +1,82 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_UID16 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_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_H5000=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="keepinitrd"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/h7201_defconfig b/arch/arm/configs/h7201_defconfig
new file mode 100644
index 00000000..bee94d29
--- /dev/null
+++ b/arch/arm/configs/h7201_defconfig
@@ -0,0 +1,27 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_ARCH_H720X=y
+CONFIG_ARCH_H7201=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_EXT2_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig
new file mode 100644
index 00000000..69405a76
--- /dev/null
+++ b/arch/arm/configs/h7202_defconfig
@@ -0,0 +1,48 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_MODULES=y
+CONFIG_ARCH_H720X=y
+CONFIG_ARCH_H7202=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,19200"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 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_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_H720X=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB_GADGET=m
+CONFIG_USB_ZERO=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_FILE_STORAGE_TEST=y
+CONFIG_USB_G_SERIAL=m
+CONFIG_EXT2_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig
new file mode 100644
index 00000000..bed80472
--- /dev/null
+++ b/arch/arm/configs/hackkit_defconfig
@@ -0,0 +1,49 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_HACKKIT=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySA0,115200 root=/dev/ram0 initrd=0xc0400000,8M init=/rootshell"
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig
new file mode 100644
index 00000000..fd996bb1
--- /dev/null
+++ b/arch/arm/configs/imote2_defconfig
@@ -0,0 +1,392 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_EXPERT=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_INTELMOTE2=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 console=ttyS2,115200 mem=32M"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME=y
+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_IP_PNP_RARP=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_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BRIDGE=m
+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+CONFIG_IEEE802154=y
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER=m
+CONFIG_CONNECTOR=m
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_AR7_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_OTP=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+# CONFIG_HWMON is not set
+CONFIG_PMIC_DA903X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_DA903X=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_MEDIA_TUNER_CUSTOMISE=y
+# 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_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9M111=y
+CONFIG_VIDEO_PXA27x=y
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_PXA27X=y
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_PXA=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LP3944=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=m
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_ROMFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_PROVE_LOCKING=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_GHASH=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC16=y
diff --git a/arch/arm/configs/imx5_defconfig b/arch/arm/configs/imx5_defconfig
new file mode 100755
index 00000000..df02a3aa
--- /dev/null
+++ b/arch/arm/configs/imx5_defconfig
@@ -0,0 +1,2429 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 2.6.38 Kernel Configuration
+# Mon Oct 24 21:25:30 2011
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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_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_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set
+CONFIG_HAVE_SPARSE_IRQ=y
+# CONFIG_GENERIC_PENDING_IRQ is not set
+# CONFIG_AUTO_IRQ_AFFINITY is not set
+# CONFIG_IRQ_PER_CPU is not set
+# CONFIG_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TINY_PREEMPT_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+CONFIG_RELAY=y
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+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_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# 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_AAEC2000 is not set
+# 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=y
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_STMP3XXX 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_NS9XXX 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_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_S5PV310 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_TCC_926 is not set
+# CONFIG_ARCH_LH7A40X 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_GPIO_PCA953X is not set
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SRTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_TVE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IIM=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MXC91231 is not set
+CONFIG_ARCH_MX5=y
+# CONFIG_ARCH_MX6 is not set
+CONFIG_ARCH_MX50=y
+CONFIG_ARCH_MX51=y
+CONFIG_ARCH_MX53=y
+CONFIG_SOC_IMX50=y
+CONFIG_SOC_IMX51=y
+CONFIG_SOC_IMX53=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# MX5 platforms:
+#
+CONFIG_MACH_MX51_BABBAGE=y
+# CONFIG_MACH_MX51_3DS is not set
+# CONFIG_MACH_EUKREA_CPUIMX51 is not set
+# CONFIG_MACH_EUKREA_CPUIMX51SD is not set
+# CONFIG_MACH_MX51_EFIKAMX is not set
+# CONFIG_MACH_MX51_EFIKASB is not set
+CONFIG_MACH_MX53_EVK=y
+CONFIG_MACH_MX53_SMD=y
+CONFIG_MACH_MX53_LOCO=y
+CONFIG_MACH_MX53_ARD=y
+CONFIG_MACH_MX50_RDP=y
+# CONFIG_MACH_IMX_BLUETOOTH_RFKILL is not set
+CONFIG_ISP1504_MXC=y
+CONFIG_UTMI_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_TZIC=y
+CONFIG_MXC_PWM=y
+CONFIG_MXC_DEBUG_BOARD=y
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=96
+
+#
+# System MMU
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+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_743622 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+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=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+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
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.101:/shared/nfs ip=dhcp"
+# 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=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+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=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP 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 is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# 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=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 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+# CONFIG_CAN_DEV is not set
+CONFIG_CAN_DEBUG_DEVICES=y
+# 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIUART_ATH3K=y
+# 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=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# 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 is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# 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
+# CONFIG_BLK_DEV_DRBD is not set
+# 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=65536
+# 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_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT 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_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MXS_PERFMON=y
+# 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_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 is not set
+
+#
+# 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 is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+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 is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_SATA_MV is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+# CONFIG_BCM63XX_PHY is not set
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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=m
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+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=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# 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_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_IMX 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_MXC is not set
+CONFIG_KEYBOARD_MPR121=y
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879 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_EGALAX is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 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_QT602240 is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_MC13783 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_TOUCHSCREEN_ST1232 is not set
+CONFIG_TOUCHSCREEN_P1003=y
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+# CONFIG_TOUCHSCREEN_DA9052 is not set
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_DA9052_ONKEY is not set
+CONFIG_INPUT_ISL29023=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+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=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_FSL_OTP 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_HW_RANDOM_FSL_RNGC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_MXC_IIM is not set
+# CONFIG_MXS_VIIM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+# CONFIG_I2C_HELPER_AUTO is not set
+# CONFIG_I2C_SMBUS is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_0_7=y
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# 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_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_DA9052_GPIO_ENABLE is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_DA9052 is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+CONFIG_SENSORS_MAX17135=y
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+# CONFIG_SENSORS_MC13783_ADC is not set
+CONFIG_SENSORS_IMX_AHCI=y
+CONFIG_MXC_MMA8450=y
+CONFIG_MXC_MMA8451=y
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB 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_UCB1400_CORE is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X 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_MAX8998 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 is not set
+# CONFIG_MFD_PCF50633 is not set
+CONFIG_PMIC_DIALOG=y
+# CONFIG_PMIC_DA9052 is not set
+# CONFIG_PMIC_DA9053AA is not set
+CONFIG_PMIC_DA9053Bx=y
+CONFIG_MFD_MC13783=y
+CONFIG_MFD_MC13XXX=y
+CONFIG_MFD_MC_PMIC=y
+CONFIG_MFD_MC34708=y
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_TPS6586X is not set
+# CONFIG_MFD_WL1273_CORE is not set
+CONFIG_MFD_MAX17135=y
+# CONFIG_MFD_MXC_HDMI 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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+CONFIG_REGULATOR_MC13XXX_CORE=y
+# CONFIG_REGULATOR_MC13783 is not set
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_MC34708=y
+# 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_REGULATOR_MAX17135=y
+CONFIG_REGULATOR_DA9052=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=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_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=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_MT2131=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_MEDIA_TUNER_MXL5007T=m
+CONFIG_MEDIA_TUNER_MC44S803=m
+CONFIG_MEDIA_TUNER_MAX2165=m
+CONFIG_MEDIA_TUNER_TDA18218=m
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+CONFIG_VIDEO_IR_I2C=y
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# 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_M52790 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_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X 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
+
+#
+# Video and audio decoders
+#
+# 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_THS7303 is not set
+# CONFIG_VIDEO_ADV7343 is not set
+# CONFIG_VIDEO_AK881X is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_VIDEO_MXC_CSI_CAMERA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+CONFIG_MXC_CAMERA_OV3640=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_IPU_PRP_VF_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_MXC_IPU_CSI_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_SOC_CAMERA 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=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX 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_V4L_MEM2MEM_DRIVERS is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_I2C_SI4713 is not set
+# CONFIG_RADIO_SI4713 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_RADIO_SI470X is not set
+# CONFIG_USB_MR800 is not set
+# CONFIG_RADIO_TEA5764 is not set
+# CONFIG_RADIO_SAA7706H is not set
+# CONFIG_RADIO_TEF6862 is not set
+# CONFIG_RADIO_WL1273 is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# 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_MB862XX 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_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_DA9052 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_TVOUT_TVE=y
+CONFIG_FB_MXC_LDB=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_SII902X=y
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_MXC_EINK_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+# CONFIG_FB_MXC_HDMI is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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 is not set
+CONFIG_SND_SOC=y
+# CONFIG_SND_SOC_CACHE_LZO is not set
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_CS42888=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_MXC_SPDIF=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_CS42888=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+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_3M_PCT is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_ACRUX_FF is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EGALAX is not set
+# CONFIG_HID_ELECOM is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MAGICMOUSE is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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_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_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 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_GADGET=y
+# 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_ARC=y
+# CONFIG_USB_STATIC_IRAM_PPH is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM 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=m
+# CONFIG_FSL_UTP is not set
+# CONFIG_USB_FILE_STORAGE_TEST 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_CDC_COMPOSITE 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_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+# CONFIG_MMC_MXC is not set
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_DA9052 is not set
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+# 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=y
+# 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_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
+
+#
+# SPI RTC drivers
+#
+# 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_MXC is not set
+CONFIG_RTC_DRV_MXC_V2=y
+# CONFIG_RTC_DRV_SNVS 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_RTC_DRV_MC13XXX is not set
+CONFIG_RTC_DRV_MC34708=y
+# CONFIG_RTC_DRV_DA9052 is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_MXC_PXP=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3EX=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+# CONFIG_MXC_PMIC_MC13783 is not set
+CONFIG_MXC_PMIC_MC13892=y
+CONFIG_MXC_PMIC_I2C=y
+CONFIG_MXC_PMIC_SPI=y
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_CHARDEV is not set
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13892_ADC=y
+CONFIG_MXC_MC13892_RTC=y
+# CONFIG_MXC_MC13892_LIGHT is not set
+# CONFIG_MXC_MC13892_BATTERY is not set
+# CONFIG_MXC_MC13892_CONNECTIVITY is not set
+CONFIG_MXC_MC13892_POWER=y
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_SCC2 is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# SAHARA2 Security Hardware Support
+#
+# CONFIG_MXC_SAHARA is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+# CONFIG_MXC_ASRC is not set
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+# CONFIG_MXC_MLB is not set
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC GPU support
+#
+CONFIG_MXC_AMD_GPU=y
+
+#
+# MXC GPU support
+#
+
+#
+# ANATOP_THERMAL
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_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=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# 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 is not set
+# 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_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_USE_KERNEL_DNS=y
+# CONFIG_NFS_USE_NEW_IDMAPPER is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+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 is not set
+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_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_BKL=y
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_LKDTM is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+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_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_CRYPTODEV 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 is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# 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 is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/imx6_android_defconfig b/arch/arm/configs/imx6_android_defconfig
new file mode 100644
index 00000000..8da0b52d
--- /dev/null
+++ b/arch/arm/configs/imx6_android_defconfig
@@ -0,0 +1,2982 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=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_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_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+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=""
+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=y
+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_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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_CPUACCT=y
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_PERF is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+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 is not set
+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=y
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_MACH_MX6Q_ARM2=y
+# CONFIG_MACH_MX6SL_ARM2 is not set
+CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABRESD=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_EHCI_ARC_H1=y
+# CONFIG_MX6_INTER_LDO_BYPASS is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+CONFIG_MXC_REBOOT_MFGMODE=y
+CONFIG_MXC_REBOOT_ANDROID_CMD=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_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_GIC=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 is not set
+# 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_HAVE_ARM_TWD=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=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+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_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 is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+# 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_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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_CPUFREQ_GOV_ON_EARLYSUPSEND=y
+# CONFIG_CPUHOTPLUG_EARLYSUSPEND is not set
+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_FB_EARLYSUSPEND=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+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=y
+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=y
+# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_PIMSM_V2 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=y
+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=y
+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=y
+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_LED is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+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 is not set
+# 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=y
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+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 is not set
+# 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=y
+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 is not set
+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_SNMP_BASIC=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 is not set
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_QUEUE=y
+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 is not set
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set
+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=y
+# CONFIG_L2TP_DEBUGFS is not set
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# 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_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_MCP251X is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_C_CAN is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_ESD_USB2 is not set
+# CONFIG_CAN_SOFTING is not set
+# CONFIG_CAN_DEBUG_DEVICES 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIUART_ATH3K=y
+# 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=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=m
+# 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=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_LIB80211_DEBUG 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_LEDS=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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_SUSPEND_COUNTER=y
+# 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_MXS_PERFMON=m
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_APANIC 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_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 is not set
+# 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=y
+# CONFIG_DM_FLAKEY is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# 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=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC_NAPI is not set
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_BCM4329 is not set
+# CONFIG_BCMDHD is not set
+CONFIG_HOSTAP=y
+# CONFIG_HOSTAP_FIRMWARE 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOE=y
+CONFIG_PPTP=y
+CONFIG_PPPOL2TP=y
+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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+# CONFIG_INPUT_KEYRESET 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_IMX 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN=y
+# CONFIG_TOUCHSCREEN_FUJITSU 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=y
+# CONFIG_TOUCHSCREEN_MCS5000 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_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYCHORD is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+CONFIG_INPUT_ISL29023=y
+
+#
+# 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 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# 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_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX17135 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+# CONFIG_MXC_MMA8450 is not set
+CONFIG_MXC_MMA8451=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_WM8994 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_MXC_CAMERA=y
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_VIDEO_MXC_CSI_CAMERA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_CAMERA_OV3640 is not set
+# CONFIG_MXC_CAMERA_OV5640 is not set
+# CONFIG_MXC_CAMERA_OV8820_MIPI is not set
+CONFIG_MXC_CAMERA_OV5642=y
+# CONFIG_MXC_TVIN_ADV7180 is not set
+CONFIG_MXC_CAMERA_OV5640_MIPI=y
+CONFIG_MXC_CAMERA_SENSOR_CLK=y
+# CONFIG_MXC_IPU_DEVICE_QUEUE_SDC is not set
+CONFIG_MXC_IPU_PRP_VF_SDC=y
+CONFIG_MXC_IPU_PRP_ENC=y
+CONFIG_MXC_IPU_CSI_ENC=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=y
+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_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_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# 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=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_MIPI_DSI=y
+CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_MXC_EINK_PANEL is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+CONFIG_FB_MXC_HDMI=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_WM8958=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=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_MXC_HDMI=y
+CONFIG_SND_SOC_MXC_SPDIF=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_CS42888=y
+CONFIG_SND_SOC_WM8962=y
+CONFIG_SND_SOC_WM8994=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_EHCI_ARC_HSIC is not set
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+# CONFIG_USB_PRINTER is not set
+# 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 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+CONFIG_USB_SERIAL_QUALCOMM=y
+# 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_WWAN=y
+CONFIG_USB_SERIAL_OPTION=y
+# 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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+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_ANDROID=y
+# CONFIG_USB_CDC_COMPOSITE 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_UTILS=y
+CONFIG_USB_OTG_WAKELOCK=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_SDHCI_USE_LEDS_CLASS is not set
+# CONFIG_MEMSTICK 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=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# 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_TRIGGERS=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_SLEEP=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+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=y
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_MXC_PXP_V2 is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# 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_RESERVED_MEMORY_ACCOUNT=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_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_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_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3H=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+# CONFIG_MXC_MLB150 is not set
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+CONFIG_MXC_GPU_VIV=y
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+CONFIG_MXC_MIPI_CSI2=y
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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 is not set
+# 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_YAFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# 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_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_DISABLE_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=m
+# CONFIG_CRYPTO_CRYPTODEV 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=y
+# 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 is not set
+# 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=y
+# 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=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=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_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
new file mode 100644
index 00000000..219068be
--- /dev/null
+++ b/arch/arm/configs/imx6_defconfig
@@ -0,0 +1,2709 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=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_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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+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=""
+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=y
+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_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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+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 is not set
+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=y
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_MACH_MX6Q_ARM2=y
+# CONFIG_MACH_MX6SL_ARM2 is not set
+# CONFIG_MACH_MX6SL_EVK is not set
+CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABRESD=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
+CONFIG_MACH_MX6Q_HDMIDONGLE=y
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_USB_FSL_ARC_OTG=y
+# CONFIG_MX6_INTER_LDO_BYPASS is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+CONFIG_MXC_REBOOT_MFGMODE=y
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+#CONFIG_MX6_ENET_IRQ_TO_GPIO is not set
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_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_775420=y
+CONFIG_ARM_GIC=y
+
+#
+# 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=y
+
+#
+# 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_HAVE_ARM_TWD=y
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+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=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CLEANCACHE is not set
+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
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME_CLK=y
+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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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_LLC=y
+CONFIG_LLC2=y
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB 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_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_MCP251X is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_C_CAN is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_ESD_USB2 is not set
+# CONFIG_CAN_SOFTING is not set
+# CONFIG_CAN_DEBUG_DEVICES 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIUART_ATH3K=y
+# 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=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=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=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_LIB80211_DEBUG is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_LEDS=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MXS_PERFMON=m
+# 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_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 is not set
+# 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=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_SATA_MV is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ARASAN_CF is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+CONFIG_FEC_NAPI=y
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_ATH_COMMON=m
+# CONFIG_ATH_DEBUG is not set
+CONFIG_ATH6KL=m
+# CONFIG_ATH6KL_DEBUG is not set
+CONFIG_HOSTAP=y
+# CONFIG_HOSTAP_FIRMWARE 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER 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_IMX 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_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN=y
+# CONFIG_TOUCHSCREEN_FUJITSU 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=y
+# CONFIG_TOUCHSCREEN_MCS5000 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_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# 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_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_INPUT_CMA3000 is not set
+CONFIG_INPUT_ISL29023=y
+
+#
+# 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=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# 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_RAMOOPS is not set
+CONFIG_MXS_VIIM=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=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+CONFIG_SENSORS_MAX17135=y
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+# CONFIG_MXC_MMA8450 is not set
+CONFIG_MXC_MMA8451=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MPCORE_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_WM8994 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_VIDEO_MXC_CSI_CAMERA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+CONFIG_MXC_CAMERA_OV3640=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV8820_MIPI=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+# CONFIG_MXC_MIPI_CSI2_TVIN_ADV7280 is not set
+CONFIG_MXC_CAMERA_SENSOR_CLK=m
+CONFIG_MXC_IPU_DEVICE_QUEUE_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_MXC_IPU_CSI_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_KINECT is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR 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_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+CONFIG_DRM=m
+CONFIG_DRM_VIVANTE=m
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_MIPI_DSI=y
+CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+CONFIG_FB_MXC_HDMI=y
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+# CONFIG_SND_SOC_IMX_WM8958 is not set
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_MXC_HDMI=y
+CONFIG_SND_SOC_MXC_SPDIF=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_CS42888=y
+CONFIG_SND_SOC_WM8962=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_EHCI_ARC_HSIC is not set
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM 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=m
+# CONFIG_FSL_UTP is not set
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE 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_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_LM3530 is not set
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LP3944 is not set
+# 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_TRIGGERS=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+# 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=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3H=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+CONFIG_MXC_GPU_VIV=y
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+CONFIG_MXC_MIPI_CSI2=y
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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_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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_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_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_GF128MUL=y
+# 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=m
+# CONFIG_CRYPTO_CRYPTODEV is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_GHASH=y
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE=9
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD=255
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD=2048
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API=y
+# CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST is not set
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_SLOTSIZE=7
+CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=y
+CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_CRC_CCITT=m
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6_updater_defconfig b/arch/arm/configs/imx6_updater_defconfig
new file mode 100644
index 00000000..b1c55eba
--- /dev/null
+++ b/arch/arm/configs/imx6_updater_defconfig
@@ -0,0 +1,2400 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=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_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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=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=""
+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=y
+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_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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+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 is not set
+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=y
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABRESD=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
+CONFIG_MACH_MX6Q_HDMIDONGLE=y
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_FSL_ARC_OTG=y
+# CONFIG_MX6_INTER_LDO_BYPASS is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+# CONFIG_MXC_REBOOT_MFGMODE is not set
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_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_775420=y
+CONFIG_ARM_GIC=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_ARM_ERRATA_764369 is not set
+CONFIG_PL310_ERRATA_769419=y
+
+#
+# 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 is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_LOCAL_TIMERS is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+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_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
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=y
+# 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_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME_CLK=y
+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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB 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_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+# CONFIG_CAN_DEV is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_DEBUG_DEVICES=y
+# 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+CONFIG_BT_HCIVHCI=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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 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 is not set
+# 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=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_SATA_MV is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ARASAN_CF is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC_NAPI is not set
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+# CONFIG_TOUCHSCREEN_ELAN is not set
+# CONFIG_TOUCHSCREEN_FUJITSU 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_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# 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_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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_ISL29023 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_FSL_RNGC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_VIVI is not set
+# CONFIG_VIDEO_MXC_CAMERA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_CAMERA_OV3640 is not set
+# CONFIG_MXC_CAMERA_OV5640 is not set
+# CONFIG_MXC_CAMERA_OV8820_MIPI is not set
+# CONFIG_MXC_CAMERA_OV5642 is not set
+# CONFIG_MXC_TVIN_ADV7180 is not set
+# CONFIG_MXC_IPU_DEVICE_QUEUE_SDC is not set
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_LDB=y
+# CONFIG_FB_MXC_MIPI_DSI is not set
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_MXC_EINK_PANEL is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+CONFIG_FB_MXC_HDMI=y
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# 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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+# CONFIG_SND_SOC_IMX_SGTL5000 is not set
+# CONFIG_SND_SOC_IMX_WM8962 is not set
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+# CONFIG_SND_SOC_IMX_SPDIF is not set
+# CONFIG_SND_SOC_IMX_HDMI is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_CS42888=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# 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_USB_MON is not set
+# 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_EHCI_HCD is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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_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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+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=y
+CONFIG_FSL_UTP=y
+# CONFIG_USB_FILE_STORAGE_TEST 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_CDC_COMPOSITE 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_UTILS=y
+# 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 is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_NEW_LEDS is not set
+# CONFIG_NFC_DEVICES is not set
+# 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=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+# CONFIG_MXC_PXP_V2 is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_USBIP_CORE 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
+# CONFIG_POHMELFS is not set
+# CONFIG_LINE6_USB 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_EASYCAP is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# 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_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3H=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+# CONFIG_MXC_MLB150 is not set
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+# CONFIG_MXC_GPU_VIV is not set
+
+#
+# ANATOP_THERMAL
+#
+# CONFIG_ANATOP_THERMAL is not set
+
+#
+# MXC MIPI Support
+#
+# CONFIG_MXC_MIPI_CSI2 is not set
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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_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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_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 is not set
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CRYPTODEV=y
+
+#
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_DCP is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_CRC_CCITT=m
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6s_android_defconfig b/arch/arm/configs/imx6s_android_defconfig
new file mode 100644
index 00000000..2cadfaeb
--- /dev/null
+++ b/arch/arm/configs/imx6s_android_defconfig
@@ -0,0 +1,2977 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_PERF is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+# CONFIG_MACH_MX6Q_SABRELITE is not set
+CONFIG_MACH_MX6Q_SABRESD=y
+# CONFIG_MACH_MX6Q_SABREAUTO is not set
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_MX6_INTER_LDO_BYPASS=y
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+CONFIG_MXC_REBOOT_MFGMODE=y
+CONFIG_MXC_REBOOT_ANDROID_CMD=y
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_GIC=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_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 is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+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=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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 is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=y
+# 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_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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_CPUFREQ_GOV_ON_EARLYSUPSEND=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_FB_EARLYSUSPEND=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+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=y
+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=y
+# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_PIMSM_V2 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=y
+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=y
+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=y
+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_LED is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+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 is not set
+# 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=y
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+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 is not set
+# 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=y
+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 is not set
+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_SNMP_BASIC=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 is not set
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_QUEUE=y
+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 is not set
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set
+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=y
+# CONFIG_L2TP_DEBUGFS is not set
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_DNS_RESOLVER is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_MCP251X is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_C_CAN is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_ESD_USB2 is not set
+# CONFIG_CAN_SOFTING is not set
+# CONFIG_CAN_DEBUG_DEVICES 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIUART_ATH3K=y
+# 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=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=m
+# 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=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_LIB80211_DEBUG 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_LEDS=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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_SUSPEND_COUNTER=y
+# 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_MXS_PERFMON=m
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_APANIC 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_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 is not set
+# 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=y
+# CONFIG_DM_FLAKEY is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# 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=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC_NAPI is not set
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_BCM4329 is not set
+# CONFIG_BCMDHD is not set
+CONFIG_HOSTAP=y
+# CONFIG_HOSTAP_FIRMWARE 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOE=y
+CONFIG_PPTP=y
+CONFIG_PPPOL2TP=y
+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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+# CONFIG_INPUT_KEYRESET 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_IMX=y
+# 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN=y
+# CONFIG_TOUCHSCREEN_FUJITSU 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=y
+# CONFIG_TOUCHSCREEN_MCS5000 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_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYCHORD is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+CONFIG_INPUT_ISL29023=y
+
+#
+# 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 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_FSL_RNGC 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_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+CONFIG_CHARGER_MAX8903=y
+# CONFIG_SABRESD_MAX8903 is not set
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+CONFIG_SENSORS_MAX17135=y
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+# CONFIG_MXC_MMA8450 is not set
+CONFIG_MXC_MMA8451=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_WM8994 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_VIDEO_MXC_CSI_CAMERA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+CONFIG_MXC_CAMERA_OV3640=m
+CONFIG_MXC_CAMERA_OV5640=m
+CONFIG_MXC_CAMERA_OV8820_MIPI=m
+CONFIG_MXC_CAMERA_OV5642=m
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_CAMERA_OV5640_MIPI=m
+CONFIG_MXC_CAMERA_SENSOR_CLK=m
+CONFIG_MXC_IPU_PRP_VF_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_MXC_IPU_CSI_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+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_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_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+CONFIG_ION=y
+CONFIG_ION_MXC=y
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_LDB=y
+CONFIG_FB_MXC_MIPI_DSI=y
+CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_SII902X is not set
+CONFIG_FB_MXC_SII902X_ELCDIF=y
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+CONFIG_FB_MXC_ELCDIF_FB=y
+CONFIG_FB_MXC_HDMI=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_WM8958=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=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_MXC_HDMI=y
+CONFIG_SND_SOC_MXC_SPDIF=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_CS42888=y
+CONFIG_SND_SOC_WM8962=y
+CONFIG_SND_SOC_WM8994=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_EHCI_ARC_HSIC is not set
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+# CONFIG_USB_PRINTER is not set
+# 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 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+CONFIG_USB_SERIAL_QUALCOMM=y
+# 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_WWAN=y
+CONFIG_USB_SERIAL_OPTION=y
+# 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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+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_ANDROID=y
+# CONFIG_USB_CDC_COMPOSITE 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_UTILS=y
+CONFIG_USB_OTG_WAKELOCK=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_SDHCI_USE_LEDS_CLASS is not set
+# CONFIG_MEMSTICK 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_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_TRIGGERS=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_LEDS_TRIGGER_SLEEP=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+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=y
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# 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_RESERVED_MEMORY_ACCOUNT=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_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_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_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3H=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+CONFIG_MXC_GPU_VIV=y
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+CONFIG_MXC_MIPI_CSI2=y
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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 is not set
+# 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_YAFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# 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_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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_CRYPTODEV 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=y
+# 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 is not set
+# 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=y
+# 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=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_DCP is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=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_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6s_defconfig b/arch/arm/configs/imx6s_defconfig
new file mode 100644
index 00000000..5f34cca0
--- /dev/null
+++ b/arch/arm/configs/imx6s_defconfig
@@ -0,0 +1,2680 @@
+
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+# CONFIG_MACH_MX6Q_SABRELITE is not set
+CONFIG_MACH_MX6Q_SABRESD=y
+# CONFIG_MACH_MX6Q_SABREAUTO is not set
+CONFIG_SDMA_IRAM=y
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_USB_FSL_ARC_OTG=y
+CONFIG_MX6_INTER_LDO_BYPASS=y
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+# CONFIG_MXC_REBOOT_MFGMODE is not set
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# 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 is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME_CLK=y
+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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+CONFIG_CAN_DEV=y
+CONFIG_CAN_CALC_BITTIMING=y
+# CONFIG_CAN_MCP251X is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_FLEXCAN=y
+# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_C_CAN is not set
+
+#
+# CAN USB interfaces
+#
+# CONFIG_CAN_EMS_USB is not set
+# CONFIG_CAN_ESD_USB2 is not set
+# CONFIG_CAN_SOFTING is not set
+# CONFIG_CAN_DEBUG_DEVICES 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+# CONFIG_BT_HCIUART_H4 is not set
+# CONFIG_BT_HCIUART_BCSP is not set
+CONFIG_BT_HCIUART_ATH3K=y
+# 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=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_SPY=y
+CONFIG_WEXT_PRIV=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=y
+CONFIG_LIB80211_CRYPT_WEP=y
+CONFIG_LIB80211_CRYPT_CCMP=y
+CONFIG_LIB80211_CRYPT_TKIP=y
+# CONFIG_LIB80211_DEBUG is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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_DS1682 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MXS_PERFMON=m
+# 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_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 is not set
+# 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=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_SATA_MV is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ARASAN_CF is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC_NAPI is not set
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_ATH_COMMON=m
+# CONFIG_ATH_DEBUG is not set
+CONFIG_ATH6KL=m
+# CONFIG_ATH6KL_DEBUG is not set
+CONFIG_HOSTAP=y
+# CONFIG_HOSTAP_FIRMWARE 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER 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_IMX=y
+# 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+CONFIG_TOUCHSCREEN_ELAN=y
+# CONFIG_TOUCHSCREEN_FUJITSU 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_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# 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_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_INPUT_CMA3000 is not set
+CONFIG_INPUT_ISL29023=y
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+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=y
+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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_FSL_RNGC=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+CONFIG_SENSORS_MAX17135=y
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+CONFIG_MXC_MMA8450=y
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_WM8994 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=y
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_CSI_CAMERA=y
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_CAMERA_OV3640 is not set
+CONFIG_MXC_CAMERA_OV5640=y
+# CONFIG_MXC_CAMERA_OV8820_MIPI is not set
+# CONFIG_MXC_CAMERA_OV5642 is not set
+# CONFIG_MXC_TVIN_ADV7180 is not set
+# CONFIG_MXC_CAMERA_OV5640_MIPI is not set
+CONFIG_MXC_CAMERA_SENSOR_CLK=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_PXP_V4L2=y
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=m
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_KINECT is not set
+# CONFIG_USB_GSPCA_KONICA is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SPCA1528 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_SQ930X is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR 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_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_SII902X is not set
+CONFIG_FB_MXC_SII902X_ELCDIF=y
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+CONFIG_FB_MXC_ELCDIF_FB=y
+# CONFIG_FB_MXC_HDMI is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_IRAM=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_WM8958=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=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_MXC_HDMI=y
+CONFIG_SND_SOC_MXC_SPDIF=y
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_CS42888=y
+CONFIG_SND_SOC_WM8962=y
+CONFIG_SND_SOC_WM8994=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_EHCI_ARC_HSIC is not set
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM 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=m
+# CONFIG_FSL_UTP is not set
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE 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_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_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_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_TRIGGERS is not set
+
+#
+# LED Triggers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+# 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=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+# CONFIG_MXC_IPU is not set
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+CONFIG_MXC_GPU_VIV=y
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+CONFIG_MXC_MIPI_CSI2=y
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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_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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_OC_ETM=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_CRYPTODEV 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+CONFIG_CRYPTO_DEV_DCP=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_CRC_CCITT=m
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6s_ntx_alyssum_defconfig b/arch/arm/configs/imx6s_ntx_alyssum_defconfig
new file mode 100644
index 00000000..3abbf795
--- /dev/null
+++ b/arch/arm/configs/imx6s_ntx_alyssum_defconfig
@@ -0,0 +1,2137 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+CONFIG_MACH_MX6SL_NTX=y
+# CONFIG_MACH_MX6Q_SABRELITE is not set
+CONFIG_MACH_MX6Q_SABRESD=y
+# CONFIG_MACH_MX6Q_SABREAUTO is not set
+# CONFIG_MACH_MX6Q_HDMIDONGLE is not set
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_FSL_ARC_OTG=y
+CONFIG_USB_ID_WAKEUP_ENABLE=y
+CONFIG_MX6_INTER_LDO_BYPASS=y
+# CONFIG_MX6_ENET_IRQ_TO_GPIO is not set
+# CONFIG_SDMA_IRAM is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+# CONFIG_MXC_REBOOT_MFGMODE is not set
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCCARD is not set
+# 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 is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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 is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_WAKELOCK is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+# CONFIG_NET_ACTIVITY_STATS is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+# CONFIG_WEXT_SPY is not set
+CONFIG_WEXT_PRIV=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RFKILL_REGULATOR 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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_SUSPEND_COUNTER 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 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MXS_PERFMON=m
+# CONFIG_APANIC is not set
+CONFIG_NTX_MISC=y
+# 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=y
+# 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_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 is not set
+# 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 is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_BCM4329 is not set
+# CONFIG_BCMDHD is not set
+# CONFIG_HOSTAP 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+# CONFIG_INPUT_KEYRESET 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_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+CONFIG_KEYBOARD_IMX=y
+# 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX is not set
+# CONFIG_TOUCHSCREEN_ELAN is not set
+# CONFIG_TOUCHSCREEN_FUJITSU 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_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_NOVATEK 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_TOUCHSCREEN_ZFORCE=y
+CONFIG_TOUCHSCREEN_ELAN_TOUCH=y
+CONFIG_TOUCHSCREEN_WACOM_I2C=y
+CONFIG_TOUCHSCREEN_WALTOP_I2C=y
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYCHORD is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_ISL29023 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+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=y
+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=y
+CONFIG_LEGACY_PTY_COUNT=4
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVMEM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_FSL_RNGC=y
+# 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_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_BATTERY_RICOH619=y
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX17135 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_MAG3110 is not set
+# CONFIG_MXC_MMA8450 is not set
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_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 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+CONFIG_MFD_RICOH619=y
+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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_REGULATOR_RICOH619=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+CONFIG_BACKLIGHT_MXC_MSP430=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+# CONFIG_FB_MXC_EDID is not set
+# CONFIG_FB_MXC_SYNC_PANEL is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_EINK_REGAL=y
+# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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 is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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 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_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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM 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=m
+# CONFIG_FSL_UTP is not set
+CONFIG_USB_FILE_STORAGE_TEST=y
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# 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 is not set
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+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_SDIO_WIFI_PWR=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+# CONFIG_SWITCH is not set
+# 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=y
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+CONFIG_RTC_DRV_NTX_MISC=y
+# 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_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_R5T619=y
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+# CONFIG_MXC_IPU is not set
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+# CONFIG_MXC_GPU_VIV is not set
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+# CONFIG_MXC_MIPI_CSI2 is not set
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS 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 is not set
+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 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 is not set
+# 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_STACKTRACE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_OC_ETM=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_CRYPTODEV 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_FSL_CAAM_SM is not set
+CONFIG_CRYPTO_DEV_DCP=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+# CONFIG_CRC_CCITT is not set
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_AVERAGE=y
diff --git a/arch/arm/configs/imx6s_ntx_android_defconfig b/arch/arm/configs/imx6s_ntx_android_defconfig
new file mode 100644
index 00000000..5812394d
--- /dev/null
+++ b/arch/arm/configs/imx6s_ntx_android_defconfig
@@ -0,0 +1,2784 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+# CONFIG_CGROUP_FREEZER is not set
+# CONFIG_CGROUP_DEVICE is not set
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+# CONFIG_CGROUP_CPUACCT is not set
+# CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_PERF is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+CONFIG_MACH_MX6SL_NTX=y
+# CONFIG_MACH_MX6Q_SABRELITE is not set
+CONFIG_MACH_MX6Q_SABRESD=y
+# CONFIG_MACH_MX6Q_SABREAUTO is not set
+# CONFIG_MACH_MX6Q_HDMIDONGLE is not set
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+# CONFIG_USB_EHCI_ARC_H1 is not set
+CONFIG_USB_FSL_ARC_OTG=y
+# CONFIG_USB_ID_WAKEUP_ENABLE is not set
+CONFIG_MX6_INTER_LDO_BYPASS=y
+# CONFIG_MX6_CLK_FOR_BOOTUI_TRANS is not set
+# CONFIG_MX6_ENET_IRQ_TO_GPIO is not set
+# CONFIG_SDMA_IRAM is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+CONFIG_MXC_REBOOT_MFGMODE=y
+CONFIG_MXC_REBOOT_ANDROID_CMD=y
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCCARD is not set
+# 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 is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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 is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+# CONFIG_CPUFREQ_GOV_ON_EARLYSUPSEND is not set
+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_FB_EARLYSUSPEND=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE_DEMUX=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+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=y
+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=y
+# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_PIMSM_V2 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=y
+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=y
+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=y
+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_LED is not set
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+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 is not set
+# 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=y
+# CONFIG_NETFILTER_XT_MATCH_OSF is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+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 is not set
+# 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=y
+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 is not set
+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_SNMP_BASIC=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 is not set
+# CONFIG_IP_NF_ARP_MANGLE is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_QUEUE=y
+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 is not set
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+# CONFIG_IP6_NF_TARGET_REJECT_SKERR is not set
+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=y
+# CONFIG_L2TP_DEBUGFS is not set
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_DNS_RESOLVER is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+# CONFIG_WEXT_SPY is not set
+CONFIG_WEXT_PRIV=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_PM=y
+CONFIG_RFKILL_LEDS=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=20480
+# 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_SUSPEND_COUNTER=y
+# 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_MXS_PERFMON=m
+# CONFIG_WL127X_RFKILL is not set
+# CONFIG_APANIC is not set
+CONFIG_NTX_MISC=y
+# 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_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 is not set
+# 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=y
+# CONFIG_DM_FLAKEY is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# 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=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_BCM4329 is not set
+CONFIG_BCMDHD=m
+CONFIG_BCMDHD_FW_PATH="/lib/firmware/wc121/rtecdc.bin"
+CONFIG_BCMDHD_NVRAM_PATH="/lib/firmware/wc121/nvram.txt"
+CONFIG_BCMDHD_WEXT=y
+# CONFIG_HOSTAP 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOE=y
+CONFIG_PPTP=y
+CONFIG_PPPOL2TP=y
+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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+# CONFIG_INPUT_KEYRESET 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_IMX=y
+# 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX is not set
+# CONFIG_TOUCHSCREEN_ELAN is not set
+# CONFIG_TOUCHSCREEN_FUJITSU 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_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_WM97XX is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_NOVATEK 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_TOUCHSCREEN_ZFORCE=y
+CONFIG_TOUCHSCREEN_ELAN_TOUCH=y
+CONFIG_TOUCHSCREEN_WACOM_I2C=y
+CONFIG_TOUCHSCREEN_WALTOP_I2C=y
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYCHORD is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_ISL29023 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+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 is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# 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 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_FSL_RNGC 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_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+CONFIG_CHARGER_MAX8903=y
+# CONFIG_SABRESD_MAX8903 is not set
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_BATTERY_RICOH619=y
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+CONFIG_SENSORS_MAX17135=y
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+# CONFIG_MXC_MMA8450 is not set
+CONFIG_MXC_MMA8451=y
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+CONFIG_MFD_RICOH619=y
+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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_REGULATOR_RICOH619=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_MXC_CAMERA is not set
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+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_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_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+CONFIG_ION=y
+CONFIG_ION_MXC=y
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+CONFIG_BACKLIGHT_MXC_MSP430=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+# CONFIG_FB_MXC_EDID is not set
+# CONFIG_FB_MXC_SYNC_PANEL is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_EINK_REGAL=y
+CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE=y
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB 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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+CONFIG_SND_MXC_SOC_SPDIF_DAI=y
+# CONFIG_SND_SOC_IMX_SGTL5000 is not set
+# CONFIG_SND_SOC_IMX_WM8962 is not set
+# CONFIG_SND_SOC_IMX_CS42888 is not set
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_HDMI=y
+# CONFIG_SND_MXC_SOC_IRAM is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_MXC_HDMI=y
+CONFIG_SND_SOC_MXC_SPDIF=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_OTG=y
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD=y
+# CONFIG_FSL_USB_TEST_MODE is not set
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_EHCI_ARC_HSIC is not set
+# CONFIG_USB_STATIC_IRAM is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_MXC is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=y
+# CONFIG_USB_PRINTER is not set
+# 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 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
+CONFIG_USB_SERIAL_QUALCOMM=y
+# 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_WWAN=y
+CONFIG_USB_SERIAL_OPTION=y
+# 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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+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_ANDROID=y
+# CONFIG_USB_CDC_COMPOSITE 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_UTILS=y
+CONFIG_USB_OTG_WAKELOCK=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MXC_OTG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+# CONFIG_MMC_CLKGATE is not set
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+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_SDIO_WIFI_PWR is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
+# CONFIG_MMC_USHC is not set
+# CONFIG_SDHCI_USE_LEDS_CLASS is not set
+# CONFIG_MEMSTICK 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_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_TRIGGERS=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_LEDS_TRIGGER_SLEEP=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+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=y
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+CONFIG_RTC_DRV_NTX_MISC=y
+# 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_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_R5T619=y
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_USBIP_CORE 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_RESERVED_MEMORY_ACCOUNT=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_EASYCAP is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_BCM_WIMAX is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# 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_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+CONFIG_MXC_IPU_V3H=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+CONFIG_MXC_GPU_VIV=y
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+CONFIG_MXC_MIPI_CSI2=y
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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 is not set
+# 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=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_OC_ETM=y
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# 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_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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_CRYPTODEV 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=y
+# 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=y
+# 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=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_FSL_CAAM_SM is not set
+# CONFIG_CRYPTO_DEV_DCP is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=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_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/imx6s_ntx_defconfig b/arch/arm/configs/imx6s_ntx_defconfig
new file mode 100644
index 00000000..6d04b5db
--- /dev/null
+++ b/arch/arm/configs/imx6s_ntx_defconfig
@@ -0,0 +1,2204 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+# CONFIG_KEYBOARD_GPIO_POLLED is not set
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+CONFIG_MACH_MX6SL_NTX=y
+# CONFIG_MACH_MX6Q_SABRELITE is not set
+CONFIG_MACH_MX6Q_SABRESD=y
+# CONFIG_MACH_MX6Q_SABREAUTO is not set
+# CONFIG_MACH_MX6Q_HDMIDONGLE is not set
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_FSL_ARC_OTG=y
+CONFIG_USB_ID_WAKEUP_ENABLE=y
+CONFIG_MX6_INTER_LDO_BYPASS=y
+# CONFIG_MX6_ENET_IRQ_TO_GPIO is not set
+# CONFIG_SDMA_IRAM is not set
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+# CONFIG_MXC_REBOOT_MFGMODE is not set
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCCARD is not set
+# 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 is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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 is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=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_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_WAKELOCK is not set
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+# CONFIG_TCP_CONG_BIC is not set
+CONFIG_TCP_CONG_CUBIC=y
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
+# CONFIG_TCP_CONG_LP is not set
+# CONFIG_TCP_CONG_VENO is not set
+# CONFIG_TCP_CONG_YEAH is not set
+# CONFIG_TCP_CONG_ILLINOIS is not set
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+CONFIG_ANDROID_PARANOID_NETWORK=y
+# CONFIG_NET_ACTIVITY_STATS is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+# CONFIG_WEXT_SPY is not set
+CONFIG_WEXT_PRIV=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_LIB80211=y
+# CONFIG_LIB80211_DEBUG is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RFKILL_REGULATOR 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=20480
+# 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_SUSPEND_COUNTER 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 is not set
+# CONFIG_BMP085 is not set
+CONFIG_MXS_PERFMON=m
+# CONFIG_APANIC is not set
+CONFIG_NTX_MISC=y
+# 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=y
+# 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_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 is not set
+# 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 is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+CONFIG_MICREL_PHY=y
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_BCM4329 is not set
+# CONFIG_BCMDHD is not set
+# CONFIG_HOSTAP 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+# CONFIG_INPUT_KEYRESET 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_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+CONFIG_KEYBOARD_IMX=y
+# 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_MXC is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX is not set
+# CONFIG_TOUCHSCREEN_ELAN is not set
+# CONFIG_TOUCHSCREEN_FUJITSU 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_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_NOVATEK 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_TOUCHSCREEN_ZFORCE=y
+CONFIG_TOUCHSCREEN_ELAN_TOUCH=y
+CONFIG_TOUCHSCREEN_WACOM_I2C=y
+CONFIG_TOUCHSCREEN_WALTOP_I2C=y
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYCHORD is not set
+# 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 is not set
+# 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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_ISL29023 is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+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=y
+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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVMEM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_FSL_RNGC=y
+# 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_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+CONFIG_SABRESD_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_BATTERY_RICOH619=y
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX17135 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_PMBUS is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SHT21 is not set
+# CONFIG_SENSORS_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_SENSORS_MAG3110 is not set
+# CONFIG_MXC_MMA8450 is not set
+# CONFIG_MXC_MMA8451 is not set
+CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_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 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+CONFIG_MFD_RICOH619=y
+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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_REGULATOR_RICOH619=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# 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_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
+CONFIG_BACKLIGHT_MXC_MSP430=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+# CONFIG_FB_MXC_EDID is not set
+# CONFIG_FB_MXC_SYNC_PANEL is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+CONFIG_FB_MXC_EINK_PANEL=y
+CONFIG_FB_MXC_EINK_REGAL=y
+# CONFIG_FB_MXC_EINK_AUTO_UPDATE_MODE is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# 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_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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# 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_IMX_SOC is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+
+#
+# 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 is not set
+# CONFIG_HID_ACRUX is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_PRODIKEYS is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# 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_EHCI_HCD is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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 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_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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM 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=m
+# CONFIG_FSL_UTP is not set
+CONFIG_USB_FILE_STORAGE_TEST=y
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# 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 is not set
+# CONFIG_MMC_EMBEDDED_SDIO is not set
+# CONFIG_MMC_PARANOID_SD_INIT is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+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_SDIO_WIFI_PWR=m
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_NEW_LEDS=y
+# CONFIG_LEDS_CLASS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# LED Triggers
+#
+# CONFIG_NFC_DEVICES is not set
+# CONFIG_SWITCH is not set
+# 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=y
+# CONFIG_RTC_INTF_ALARM 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_RTC_DRV_SNVS is not set
+CONFIG_RTC_DRV_NTX_MISC=y
+# 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_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_RTC_DRV_R5T619=y
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+# CONFIG_MXC_IPU is not set
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=y
+CONFIG_MXC_MLB150=m
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+# CONFIG_MXC_GPU_VIV is not set
+
+#
+# ANATOP_THERMAL
+#
+CONFIG_ANATOP_THERMAL=y
+
+#
+# MXC MIPI Support
+#
+# CONFIG_MXC_MIPI_CSI2 is not set
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+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 is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+# CONFIG_MISC_FILESYSTEMS 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=y
+CONFIG_NLS_CODEPAGE_950=y
+# 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 is not set
+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 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 is not set
+# 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_STACKTRACE is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_OC_ETM=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=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_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+# CONFIG_CRYPTO_CRYPTODEV 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_FSL_CAAM_SM is not set
+CONFIG_CRYPTO_DEV_DCP=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+# CONFIG_CRC_CCITT is not set
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_AVERAGE=y
diff --git a/arch/arm/configs/imx6s_updater_defconfig b/arch/arm/configs/imx6s_updater_defconfig
new file mode 100644
index 00000000..3fffe500
--- /dev/null
+++ b/arch/arm/configs/imx6s_updater_defconfig
@@ -0,0 +1,2387 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.35 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_HAVE_PWM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_HAVE_SCHED_CLOCK=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=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_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_FIQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_ARM_PATCH_PHYS_VIRT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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=y
+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_SPARSE_IRQ is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_PREEMPT_RCU=y
+# CONFIG_TINY_RCU is not set
+# CONFIG_TINY_PREEMPT_RCU is not set
+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=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+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_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=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_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS 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_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=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 is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+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=y
+# 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_EXYNOS4 is not set
+# 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=y
+CONFIG_IMX_HAVE_PLATFORM_DMA=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_MLB=y
+CONFIG_IMX_HAVE_PLATFORM_FEC=y
+CONFIG_IMX_HAVE_PLATFORM_FLEXCAN=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC=y
+CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_I2C=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_UART=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_PWM=y
+CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_SPI_IMX=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VPU=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS=y
+CONFIG_IMX_HAVE_PLATFORM_AHCI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_DCP=y
+CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC=y
+CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
+CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
+CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
+CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_OTG=y
+CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PM=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI=y
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX6=y
+CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_MACH_MX6Q_ARM2=y
+CONFIG_MACH_MX6SL_ARM2=y
+CONFIG_MACH_MX6SL_EVK=y
+CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABRESD=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
+
+#
+# MX6 Options:
+#
+# CONFIG_IMX_PCIE is not set
+CONFIG_USB_FSL_ARC_OTG=y
+CONFIG_MX6_INTER_LDO_BYPASS=y
+CONFIG_ISP1504_MXC=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_PWM=y
+# CONFIG_MXC_DEBUG_BOARD is not set
+# CONFIG_MXC_REBOOT_MFGMODE is not set
+# CONFIG_MXC_REBOOT_ANDROID_CMD is not set
+CONFIG_ARCH_HAS_RNGC=y
+CONFIG_ARCH_MXC_IOMUX_V3=y
+CONFIG_ARCH_MXC_AUDMUX_V2=y
+CONFIG_IRAM_ALLOC=y
+CONFIG_CLK_DEBUG=y
+CONFIG_DMA_ZONE_SIZE=184
+
+#
+# System MMU
+#
+
+#
+# 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_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_SWP_EMULATE is not set
+# 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_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_PL310_ERRATA_588369 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
+CONFIG_ARM_ERRATA_743622=y
+# CONFIG_ARM_ERRATA_753970 is not set
+CONFIG_ARM_ERRATA_754322=y
+CONFIG_ARM_ERRATA_775420=y
+CONFIG_ARM_GIC=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# 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 is not set
+# CONFIG_VMSPLIT_3G is not set
+CONFIG_VMSPLIT_2G=y
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0x80000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=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=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+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
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+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=y
+
+#
+# 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=y
+# 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_GOV_PERFORMANCE is not set
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_IMX=y
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+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 is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+# CONFIG_PM_TEST_SUSPEND is not set
+CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME_CLK=y
+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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# 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 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# 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 is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_SLCAN is not set
+# CONFIG_CAN_DEV is not set
+CONFIG_HAVE_CAN_FLEXCAN=y
+CONFIG_CAN_DEBUG_DEVICES=y
+# 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=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIBTUSB=y
+# CONFIG_BT_HCIBTSDIO is not set
+# CONFIG_BT_HCIUART is not set
+# CONFIG_BT_HCIBCM203X is not set
+# CONFIG_BT_HCIBPA10X is not set
+# CONFIG_BT_HCIBFUSB is not set
+CONFIG_BT_HCIVHCI=y
+# CONFIG_BT_MRVL is not set
+# CONFIG_BT_ATH3K is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+# 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_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+CONFIG_MTD_M25P80=y
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+# CONFIG_MTD_UBI_DEBUG 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
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM 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 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 is not set
+# 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=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+# CONFIG_SATA_PMP is not set
+
+#
+# Controllers with non-SFF native interface
+#
+CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_SATA_MV is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ARASAN_CF is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_SMSC911X_ARCH_HOOKS is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC_NAPI is not set
+# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP 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_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# 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 is not set
+CONFIG_INPUT_POLLDEV=y
+# 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_APMPOWER is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# 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_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_EGALAX=y
+# CONFIG_TOUCHSCREEN_ELAN is not set
+# CONFIG_TOUCHSCREEN_FUJITSU 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_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_WM97XX 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_P1003 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# 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_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_INPUT_CMA3000 is not set
+# CONFIG_INPUT_ISL29023 is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+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=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+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_FSL_OTP=y
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_HW_RANDOM_FSL_RNGC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_MXS_VIIM=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
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_IMX=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# 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_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_GPIO is not set
+CONFIG_SPI_IMX_VER_2_3=y
+CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# 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_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_BASIC_MMIO is not set
+# CONFIG_GPIO_IT8761E is not set
+# CONFIG_GPIO_PL061 is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X_IRQ is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_SX150X 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_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_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_CHARGER_ISP1704 is not set
+# CONFIG_CHARGER_MAX8903 is not set
+# CONFIG_SABRESD_MAX8903 is not set
+# CONFIG_CHARGER_GPIO is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ARM_SP805_WATCHDOG is not set
+# CONFIG_MAX63XX_WATCHDOG is not set
+CONFIG_IMX2_WDT=y
+
+#
+# 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_UCB1400_CORE 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_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 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_PMIC_DIALOG is not set
+# CONFIG_MFD_MC_PMIC is not set
+# CONFIG_MFD_MC34708 is not set
+CONFIG_MFD_PFUZE=y
+# 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_MFD_MAX17135=y
+CONFIG_MFD_MXC_HDMI=y
+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_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_MC34708 is not set
+CONFIG_REGULATOR_PFUZE100=y
+# 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_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_REGULATOR_MAX17135=y
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_MEDIA_CONTROLLER is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA827X=y
+CONFIG_MEDIA_TUNER_TDA18271=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# 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
+
+#
+# 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_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_VIVI is not set
+# CONFIG_VIDEO_MXC_CAMERA is not set
+CONFIG_VIDEO_MXC_OUTPUT=y
+# CONFIG_VIDEO_MXC_PXP_V4L2 is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_TIMBERDALE is not set
+# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# 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=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# 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 is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_EDID=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SEIKO_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_SII902X is not set
+# CONFIG_FB_MXC_SII902X_ELCDIF is not set
+# CONFIG_FB_MXC_CH7026 is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_MXC_EINK_PANEL is not set
+# CONFIG_FB_MXC_SIPIX_PANEL is not set
+# CONFIG_FB_MXC_ELCDIF_FB is not set
+# CONFIG_FB_MXC_HDMI is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=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=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG 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=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# 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_AC97_BUS=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_MXC_SOC_MX2=y
+# CONFIG_SND_SOC_IMX_SGTL5000 is not set
+# CONFIG_SND_SOC_IMX_WM8962 is not set
+CONFIG_SND_SOC_IMX_CS42888=y
+# CONFIG_SND_SOC_IMX_SI4763 is not set
+# CONFIG_SND_SOC_IMX_SPDIF is not set
+# CONFIG_SND_SOC_IMX_HDMI is not set
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_CS42888=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+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=m
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+# CONFIG_HID_ELECOM is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
+# CONFIG_HID_KYE is not set
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=m
+# 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 is not set
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_WACOM is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_DEVICE_CLASS is not set
+# 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_USB_MON is not set
+# 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_EHCI_HCD is not set
+# 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_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# 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 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_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_GADGET=y
+# 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_ARC=y
+# CONFIG_IMX_USB_CHARGER is not set
+CONFIG_USB_ARC=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+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=y
+CONFIG_FSL_UTP=y
+# CONFIG_USB_FILE_STORAGE_TEST 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_CDC_COMPOSITE 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_UTILS=y
+# 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 is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_ARMMMCI is not set
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=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_NEW_LEDS is not set
+# CONFIG_NFC_DEVICES is not set
+# 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=y
+# 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_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_MXC is not set
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_DRV_SNVS=y
+# 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_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+# CONFIG_AMBA_PL08X is not set
+# CONFIG_DW_DMAC is not set
+# CONFIG_MXC_PXP_V2 is not set
+# CONFIG_TIMB_DMA is not set
+CONFIG_IMX_SDMA=y
+# CONFIG_MXS_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_USBIP_CORE 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
+# CONFIG_POHMELFS is not set
+# CONFIG_LINE6_USB 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_EASYCAP is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# 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_CLKSRC_MMIO=y
+
+#
+# MXC support drivers
+#
+# CONFIG_MXC_IPU is not set
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC_MC13783 is not set
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_MC9S08DZ60 is not set
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+# CONFIG_MX6_VPU_352M is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+# CONFIG_MXC_MLB150 is not set
+
+#
+# i.MX ADC support
+#
+# CONFIG_IMX_ADC is not set
+
+#
+# MXC Vivante GPU support
+#
+# CONFIG_MXC_GPU_VIV is not set
+
+#
+# ANATOP_THERMAL
+#
+# CONFIG_ANATOP_THERMAL is not set
+
+#
+# MXC MIPI Support
+#
+# CONFIG_MXC_MIPI_CSI2 is not set
+
+#
+# MXC HDMI CEC (Consumer Electronics Control) support
+#
+# CONFIG_MXC_HDMI_CEC is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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 is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# 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 is not set
+# CONFIG_TMPFS_XATTR is not set
+# 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_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_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+# CONFIG_UBIFS_FS_XATTR is not set
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS 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=m
+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=m
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME 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 is not set
+# 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 is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_MEMORY_INIT is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
+# CONFIG_LKDTM is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=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_TRACING_SUPPORT=y
+# CONFIG_FTRACE 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_TEST_KSTRTOX is not set
+# CONFIG_STRICT_DEVMEM is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_OC_ETM=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# 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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CRYPTODEV=y
+
+#
+# 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 is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# 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 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# 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 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# 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_DEV_FSL_CAAM is not set
+# CONFIG_CRYPTO_DEV_DCP is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_CRC_CCITT=m
+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 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig
new file mode 100644
index 00000000..7196ade0
--- /dev/null
+++ b/arch/arm/configs/integrator_defconfig
@@ -0,0 +1,71 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_INTEGRATOR=y
+CONFIG_ARCH_INTEGRATOR_AP=y
+CONFIG_CPU_ARM720T=y
+CONFIG_CPU_ARM920T=y
+CONFIG_PCI=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp mem=32M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_AFS_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_E100=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_AMBA_PL010=y
+CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_EXT2_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_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
new file mode 100644
index 00000000..4fa94a1f
--- /dev/null
+++ b/arch/arm/configs/iop13xx_defconfig
@@ -0,0 +1,124 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_IOP13XX=y
+CONFIG_MACH_IQ81340SC=y
+CONFIG_MACH_IQ81340MC=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="ip=bootp root=nfs console=ttyS0,115200 nfsroot=,tcp,v3,wsize=8192,rsize=8192"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=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_BOOTP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_ISCSI_ATTRS=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=y
+CONFIG_MD_RAID456=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_IOP3XX=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DMADEVICES=y
+CONFIG_INTEL_IOP_ADMA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_ECRYPT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
new file mode 100644
index 00000000..4f2ec3ac
--- /dev/null
+++ b/arch/arm/configs/iop32x_defconfig
@@ -0,0 +1,135 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_IOP32X=y
+CONFIG_MACH_GLANTANK=y
+CONFIG_ARCH_IQ80321=y
+CONFIG_ARCH_IQ31244=y
+CONFIG_MACH_N2100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=y
+CONFIG_SATA_SIL=y
+CONFIG_SATA_VITESSE=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=y
+CONFIG_MD_RAID456=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_E100=y
+CONFIG_E1000=y
+CONFIG_R8169=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IOP3XX=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_DMADEVICES=y
+CONFIG_INTEL_IOP_ADMA=y
+CONFIG_NET_DMA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_ECRYPT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_KHAZAD=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
new file mode 100644
index 00000000..aa36128a
--- /dev/null
+++ b/arch/arm/configs/iop33x_defconfig
@@ -0,0 +1,91 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_IOP33X=y
+CONFIG_ARCH_IQ80331=y
+CONFIG_MACH_IQ80332=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc iop3xx_init_atu=y"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_NBD=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_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=y
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID456=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_NETDEVICES=y
+CONFIG_E1000=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IOP3XX=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DMADEVICES=y
+CONFIG_INTEL_IOP_ADMA=y
+CONFIG_NET_DMA=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig
new file mode 100644
index 00000000..8405aded
--- /dev/null
+++ b/arch/arm/configs/ixp2000_defconfig
@@ -0,0 +1,99 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_IXP2000=y
+CONFIG_ARCH_ENP2611=y
+CONFIG_ARCH_IXDP2400=y
+CONFIG_ARCH_IXDP2800=y
+CONFIG_ARCH_IXDP2401=y
+CONFIG_ARCH_IXDP2801=y
+# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
+# CONFIG_ARM_THUMB is not set
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+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_SYN_COOKIES=y
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_IXP2000=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_EEPROM_LEGACY=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_CS89x0=y
+CONFIG_E100=y
+CONFIG_ENP2611_MSF_NET=y
+CONFIG_WAN=y
+CONFIG_HDLC=y
+CONFIG_HDLC_RAW=y
+CONFIG_HDLC_CISCO=y
+CONFIG_HDLC_FR=y
+CONFIG_HDLC_PPP=y
+CONFIG_DLCI=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IXP2000=y
+CONFIG_WATCHDOG=y
+CONFIG_IXP2000_WATCHDOG=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig
new file mode 100644
index 00000000..68871761
--- /dev/null
+++ b/arch/arm/configs/ixp23xx_defconfig
@@ -0,0 +1,105 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_IXP23XX=y
+CONFIG_MACH_ESPRESSO=y
+CONFIG_MACH_IXDP2351=y
+CONFIG_MACH_ROADRUNNER=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+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_SYN_COOKIES=y
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_EEPROM_LEGACY=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_SIIMAGE=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_E100=y
+CONFIG_E1000=y
+CONFIG_WAN=y
+CONFIG_HDLC=y
+CONFIG_HDLC_RAW=y
+CONFIG_HDLC_CISCO=y
+CONFIG_HDLC_FR=y
+CONFIG_HDLC_PPP=y
+CONFIG_DLCI=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_WATCHDOG=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
new file mode 100644
index 00000000..063e2ab2
--- /dev/null
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -0,0 +1,205 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_IXP4XX=y
+CONFIG_MACH_NSLU2=y
+CONFIG_MACH_AVILA=y
+CONFIG_MACH_LOFT=y
+CONFIG_ARCH_ADI_COYOTE=y
+CONFIG_MACH_GATEWAY7001=y
+CONFIG_MACH_WG302V2=y
+CONFIG_ARCH_IXDP425=y
+CONFIG_MACH_IXDPG425=y
+CONFIG_MACH_IXDP465=y
+CONFIG_MACH_KIXRP435=y
+CONFIG_ARCH_PRPMC1100=y
+CONFIG_MACH_NAS100D=y
+CONFIG_MACH_DSMG600=y
+CONFIG_MACH_FSG=y
+CONFIG_MACH_GTWX5715=y
+CONFIG_IXP4XX_QMGR=y
+CONFIG_IXP4XX_NPE=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_CPU_BIG_ENDIAN=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_IP_VS=m
+CONFIG_IP_VS_DEBUG=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_PKTGEN=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_IXP4XX=y
+CONFIG_MTD_NAND=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_EEPROM_LEGACY=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_HPT366=y
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_VIA=y
+CONFIG_PATA_ARTOP=y
+CONFIG_PATA_IXP4XX_CF=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_IXP4XX_ETH=y
+CONFIG_NET_PCI=y
+CONFIG_WAN=y
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+CONFIG_HDLC_X25=m
+CONFIG_DLCI=m
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_ATM_TCP=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_IXP4XX_BEEPER=y
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SENSORS_W83781D=y
+CONFIG_WATCHDOG=y
+CONFIG_IXP4XX_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_FSG=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_ISL1208=y
+CONFIG_RTC_DRV_X1205=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig
new file mode 100644
index 00000000..ea80e7e8
--- /dev/null
+++ b/arch/arm/configs/jornada720_defconfig
@@ -0,0 +1,112 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_MODULES=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_JORNADA720=y
+CONFIG_SA1100_JORNADA720_SSP=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_SA1100_FIR=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_HP7XX=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_HP7XX=y
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=32
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_S1D13XXX=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/kirkwood_defconfig b/arch/arm/configs/kirkwood_defconfig
new file mode 100644
index 00000000..aeb3af54
--- /dev/null
+++ b/arch/arm/configs/kirkwood_defconfig
@@ -0,0 +1,186 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_KIRKWOOD=y
+CONFIG_MACH_DB88F6281_BP=y
+CONFIG_MACH_RD88F6192_NAS=y
+CONFIG_MACH_RD88F6281=y
+CONFIG_MACH_MV88F6281GTW_GE=y
+CONFIG_MACH_SHEEVAPLUG=y
+CONFIG_MACH_ESATA_SHEEVAPLUG=y
+CONFIG_MACH_GURUPLUG=y
+CONFIG_MACH_DOCKSTAR=y
+CONFIG_MACH_TS219=y
+CONFIG_MACH_TS41X=y
+CONFIG_MACH_OPENRD_BASE=y
+CONFIG_MACH_OPENRD_CLIENT=y
+CONFIG_MACH_OPENRD_ULTIMATE=y
+CONFIG_MACH_NETSPACE_V2=y
+CONFIG_MACH_INETSPACE_V2=y
+CONFIG_MACH_NETSPACE_MAX_V2=y
+CONFIG_MACH_D2NET_V2=y
+CONFIG_MACH_NET2BIG_V2=y
+CONFIG_MACH_NET5BIG_V2=y
+CONFIG_MACH_T5325=y
+# CONFIG_CPU_FEROCEON_OLD_ID is not set
+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_CPU_IDLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_PKTGEN=m
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_PCI=y
+CONFIG_MV643XX_ETH=y
+# CONFIG_NETDEV_10000 is not set
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+CONFIG_SPI_ORION=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+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_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_PRINTER=m
+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_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_MVSDIO=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_S35390A=y
+CONFIG_RTC_DRV_MV=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+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_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_MV_CESA=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig
new file mode 100644
index 00000000..47c48837
--- /dev/null
+++ b/arch/arm/configs/ks8695_defconfig
@@ -0,0 +1,75 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_KS8695=y
+CONFIG_MACH_KS8695=y
+CONFIG_MACH_DSM320=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCCARD=y
+CONFIG_YENTA=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PRISM54=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_KS8695=y
+CONFIG_SERIAL_KS8695_CONSOLE=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig
new file mode 100644
index 00000000..faa28656
--- /dev/null
+++ b/arch/arm/configs/lart_defconfig
@@ -0,0 +1,75 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_LART=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySA0,9600 root=/dev/ram"
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=m
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_DEBUG=y
+CONFIG_SA1100_FIR=m
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_LART=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_IDE=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_NET_ETHERNET=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=m
+CONFIG_REISERFS_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=1
+CONFIG_CRAMFS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_DEBUG_USER=y
+CONFIG_CRC32=m
diff --git a/arch/arm/configs/loki_defconfig b/arch/arm/configs/loki_defconfig
new file mode 100644
index 00000000..1ba752b2
--- /dev/null
+++ b/arch/arm/configs/loki_defconfig
@@ -0,0 +1,120 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_LOKI=y
+CONFIG_MACH_LB88RC8480=y
+# CONFIG_CPU_FEROCEON_OLD_ID is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_PKTGEN=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_FTL=y
+CONFIG_NFTL=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_I4=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MV643XX_ETH=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_SPI=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_PRINTER=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_NEW_LEDS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_XFS_FS=y
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+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_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_LDM_DEBUG=y
+CONFIG_SUN_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig
new file mode 100644
index 00000000..1c8c9ee7
--- /dev/null
+++ b/arch/arm/configs/lpd270_defconfig
@@ -0,0 +1,65 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_LOGICPD_PXA270=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_PXA2XX_AC97=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig
new file mode 100644
index 00000000..c4ba2745
--- /dev/null
+++ b/arch/arm/configs/lubbock_defconfig
@@ -0,0 +1,56 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_MODULES=y
+CONFIG_ARCH_PXA=y
+CONFIG_ARCH_LUBBOCK=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_PXA2XX=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_SA1111=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_G_SERIAL=m
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/mackerel_defconfig b/arch/arm/configs/mackerel_defconfig
new file mode 100644
index 00000000..306a2e2d
--- /dev/null
+++ b/arch/arm/configs/mackerel_defconfig
@@ -0,0 +1,138 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+# 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_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_SH7372=y
+CONFIG_MACH_MACKEREL=y
+CONFIG_MEMORY_SIZE=0x10000000
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_FORCE_MAX_ZONEORDER=15
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=tty0, console=ttySC0,115200 earlyprintk=sh-sci.0,115200 root=/dev/nfs nfsroot=,tcp,v3 ip=dhcp memchunk.vpu=64m memchunk.veu0=8m memchunk.spu0=2m mem=240m"
+CONFIG_KEXEC=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_PM=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL 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_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=8
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_CLUT224 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_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=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_INOTIFY_USER is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=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_NFS_V4_1=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
new file mode 100644
index 00000000..443675d3
--- /dev/null
+++ b/arch/arm/configs/magician_defconfig
@@ -0,0 +1,182 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_UID16 is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_H4700=y
+CONFIG_MACH_MAGICIAN=y
+CONFIG_NO_HZ=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="keepinitrd"
+CONFIG_KEXEC=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRDA_DEBUG=y
+CONFIG_IRTTY_SIR=m
+CONFIG_PXA_FICP=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL 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_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_PXA=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PXA=y
+CONFIG_W1_MASTER_DS1WM=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PDA_POWER=y
+CONFIG_BATTERY_DS2760=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_ASIC3=y
+CONFIG_HTC_EGPIO=y
+CONFIG_HTC_PASIC3=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_BQ24022=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_FB_PXA_OVERLAY=y
+CONFIG_FB_W100=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_DISPLAY_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_MINI_4x6=y
+CONFIG_SOUND=y
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_PXA27X=y
+CONFIG_USB_ETH=m
+# CONFIG_USB_ETH_RNDIS is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_USB_GPIO_VBUS=y
+CONFIG_MMC=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DEBUG=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig
new file mode 100644
index 00000000..04efa1b3
--- /dev/null
+++ b/arch/arm/configs/mainstone_defconfig
@@ -0,0 +1,55 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_MODULES=y
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_MAINSTONE=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
new file mode 100644
index 00000000..2472a958
--- /dev/null
+++ b/arch/arm/configs/mini2440_defconfig
@@ -0,0 +1,384 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_RELAY=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_BLK_DEV_INITRD=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_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_ARCH_S3C2410=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_MACH_MINI2440=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_KEXEC=y
+CONFIG_CPU_IDLE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=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=m
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_NET_PKTGEN=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTSDIO=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_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_CONNECTOR=m
+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_FTL=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_INFTL=y
+CONFIG_RFD_FTL=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_S3C2410=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_LPDDR=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_SG=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_ZD1211RW=m
+CONFIG_ZD1211RW_DEBUG=y
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIO_RAW=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=128
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SIMTEC=y
+CONFIG_SPI=y
+CONFIG_SPI_S3C24XX=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM75=y
+CONFIG_THERMAL=m
+CONFIG_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=y
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_S3C2410=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_DISPLAY_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=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_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DYNAMIC_MINORS=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_S3C24XX_SOC=y
+CONFIG_HIDRAW=y
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_HID_GYRATION=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_TOPSEED=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_SPCP8X5=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_S3C2410=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_S3C=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_S3C24XX=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_DMADEVICES=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BOTH=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_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_CRYPTO_FIPS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_T10DIF=y
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig
new file mode 100644
index 00000000..47ad3b1a
--- /dev/null
+++ b/arch/arm/configs/mmp2_defconfig
@@ -0,0 +1,88 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MMP=y
+CONFIG_MACH_FLINT=y
+CONFIG_MACH_MARVELL_JASPER=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS2,38400 mem=128M user_debug=255"
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_GENERIC=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_PXA=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_MAX8925=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_MAX8649=y
+CONFIG_REGULATOR_MAX8925=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_MAX8925=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_MAX8925=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_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_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm_defconfig b/arch/arm/configs/msm_defconfig
new file mode 100644
index 00000000..2b8f7aff
--- /dev/null
+++ b/arch/arm/configs/msm_defconfig
@@ -0,0 +1,72 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MSM=y
+CONFIG_MACH_HALIBUT=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="mem=64M console=ttyMSM,115200n8"
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_HWMON is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_MSM=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_SCHEDSTATS=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
new file mode 100644
index 00000000..7305ebdd
--- /dev/null
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -0,0 +1,140 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MV78XX0=y
+CONFIG_MACH_DB78X00_BP=y
+CONFIG_MACH_RD78X00_MASA=y
+CONFIG_MACH_TERASTATION_WXL=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_VFP=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_PKTGEN=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL 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_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_PCI=y
+CONFIG_MV643XX_ETH=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_PRINTER=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_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+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_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/mx1_defconfig b/arch/arm/configs/mx1_defconfig
new file mode 100644
index 00000000..c9436d0b
--- /dev/null
+++ b/arch/arm/configs/mx1_defconfig
@@ -0,0 +1,91 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MX1=y
+CONFIG_ARCH_MX1ADS=y
+CONFIG_MACH_SCB9328=y
+CONFIG_MACH_APF9328=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_MXC=y
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_IMX=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_MXC=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/mx21_defconfig b/arch/arm/configs/mx21_defconfig
new file mode 100644
index 00000000..411f88dd
--- /dev/null
+++ b/arch/arm/configs/mx21_defconfig
@@ -0,0 +1,97 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MX2=y
+CONFIG_MACH_MX21ADS=y
+CONFIG_MXC_PWM=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_NET=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=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 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=3
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_SERIO is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_IMX=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_LOGO=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_MXC=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/mx27_defconfig b/arch/arm/configs/mx27_defconfig
new file mode 100644
index 00000000..9ad4c656
--- /dev/null
+++ b/arch/arm/configs/mx27_defconfig
@@ -0,0 +1,130 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MX2=y
+CONFIG_MACH_MX27=y
+CONFIG_MACH_MX27ADS=y
+CONFIG_MACH_PCM038=y
+CONFIG_MACH_CPUIMX27=y
+CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2=y
+CONFIG_MACH_EUKREA_CPUIMX27_USEUART4=y
+CONFIG_MACH_MX27_3DS=y
+CONFIG_MACH_IMX27_VISSTRIM_M10=y
+CONFIG_MACH_IMX27LITE=y
+CONFIG_MACH_PCA100=y
+CONFIG_MACH_MXT_TD60=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_MXC_PWM=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=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_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_UBI=y
+CONFIG_EEPROM_AT24=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=m
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_IMX=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_MXC=y
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_IMX=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=m
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_ULPI=y
+CONFIG_MMC=y
+CONFIG_MMC_MXC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/mx3_defconfig b/arch/arm/configs/mx3_defconfig
new file mode 100644
index 00000000..7c4b30b3
--- /dev/null
+++ b/arch/arm/configs/mx3_defconfig
@@ -0,0 +1,124 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MXC=y
+CONFIG_MACH_MX31ADS_WM1133_EV1=y
+CONFIG_MACH_PCM037=y
+CONFIG_MACH_PCM037_EET=y
+CONFIG_MACH_MX31LITE=y
+CONFIG_MACH_MX31_3DS=y
+CONFIG_MACH_MX31MOBOARD=y
+CONFIG_MACH_MX31LILLY=y
+CONFIG_MACH_QONG=y
+CONFIG_MACH_PCM043=y
+CONFIG_MACH_ARMADILLO5X0=y
+CONFIG_MACH_MX35_3DS=y
+CONFIG_MACH_KZM_ARM11_01=y
+CONFIG_MACH_EUKREA_CPUIMX35=y
+CONFIG_MXC_IRQ_PRIOR=y
+CONFIG_MXC_PWM=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw ip=off"
+CONFIG_VFP=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_UBI=y
+# CONFIG_BLK_DEV is not set
+CONFIG_EEPROM_AT24=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+CONFIG_DNET=y
+CONFIG_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_MXC=y
+CONFIG_W1_SLAVE_THERM=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_WM8350_I2C=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_WM8350=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9M001=y
+CONFIG_SOC_CAMERA_MT9M111=y
+CONFIG_SOC_CAMERA_MT9T031=y
+CONFIG_SOC_CAMERA_MT9V022=y
+CONFIG_SOC_CAMERA_TW9910=y
+CONFIG_SOC_CAMERA_OV772X=y
+CONFIG_VIDEO_MX3=y
+# CONFIG_RADIO_ADAPTERS is not set
+CONFIG_FB=y
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_MXC=y
+CONFIG_DMADEVICES=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig
new file mode 100644
index 00000000..0ace16cb
--- /dev/null
+++ b/arch/arm/configs/mx51_defconfig
@@ -0,0 +1,169 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_RELAY=y
+CONFIG_EXPERT=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MXC=y
+CONFIG_ARCH_MX51=y
+CONFIG_MACH_MX51_BABBAGE=y
+CONFIG_MACH_MX51_3DS=y
+CONFIG_MACH_EUKREA_CPUIMX51=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.101:/shared/nfs ip=dhcp"
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=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_WIRELESS is not set
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=m
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_FEC=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_SDHCI=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=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_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig
new file mode 100644
index 00000000..2bf22431
--- /dev/null
+++ b/arch/arm/configs/mxs_defconfig
@@ -0,0 +1,129 @@
+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/neponset_defconfig b/arch/arm/configs/neponset_defconfig
new file mode 100644
index 00000000..d7dc9922
--- /dev/null
+++ b/arch/arm/configs/neponset_defconfig
@@ -0,0 +1,90 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_ASSABET=y
+CONFIG_ASSABET_NEPONSET=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_PCMCIA_SA1111=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x80000
+CONFIG_ZBOOT_ROM_BSS=0xc1000000
+CONFIG_ZBOOT_ROM=y
+CONFIG_CMDLINE="console=ttySA0,38400n8 cpufreq=221200 rw root=/dev/mtdblock2 mtdparts=sa1100:512K(boot),1M(kernel),2560K(initrd),4M(root) load_ramdisk=1 prompt_ramdisk=0 mem=32M noinitrd initrd=0xc0800000,3M"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_VENDOR_SMC=y
+CONFIG_SMC9194=y
+CONFIG_SMC91X=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_SA1111=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CS=y
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=64
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=m
+CONFIG_FB=y
+CONFIG_FB_SA1100=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SOUND_PRIME=y
+# CONFIG_USB_HID is not set
+CONFIG_USB=m
+CONFIG_USB_DEBUG=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MSDOS_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig
new file mode 100644
index 00000000..25ed772d
--- /dev/null
+++ b/arch/arm/configs/netwinder_defconfig
@@ -0,0 +1,87 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_ARCH_FOOTBRIDGE=y
+CONFIG_ARCH_NETWINDER=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=0x301"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+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_IP_PNP_RARP=y
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_QUEUE=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_SUPERIO=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_TULIP=y
+CONFIG_TULIP=y
+CONFIG_TULIP_MMIO=y
+CONFIG_NET_PCI=y
+CONFIG_NE2K_PCI=y
+CONFIG_MOUSE_SERIAL=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_PRINTER=y
+CONFIG_DS1620=y
+CONFIG_NWBUTTON=y
+CONFIG_NWBUTTON_REBOOT=y
+CONFIG_NWFLASH=y
+CONFIG_WATCHDOG=y
+CONFIG_977_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_CYBER2000=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SOUND_PRIME=y
+CONFIG_SOUND_OSS=y
+CONFIG_SOUND_TRACEINIT=y
+CONFIG_SOUND_DMAP=y
+CONFIG_SOUND_YM3812=y
+CONFIG_SOUND_WAVEARTIST=y
+CONFIG_EXT2_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SMB_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig
new file mode 100644
index 00000000..9c0ad799
--- /dev/null
+++ b/arch/arm/configs/netx_defconfig
@@ -0,0 +1,86 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_ARCH_NETX=y
+CONFIG_MACH_NXDKN=y
+CONFIG_MACH_NXDB500=y
+CONFIG_MACH_NXEB500HMI=y
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySMX0,115200"
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_NET_IPGRE=m
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_NET_PKTGEN=m
+CONFIG_MTD=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_PLATRAM=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_NETX=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_NETX=y
+CONFIG_SERIAL_NETX_CONSOLE=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_RTC_CLASS=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRC_CCITT=m
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
new file mode 100644
index 00000000..37207d1b
--- /dev/null
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -0,0 +1,132 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_NOMADIK=y
+CONFIG_MACH_NOMADIK_8815NHK=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIVHCI=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC_SMC=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_NOMADIK=y
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_GENERIC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_NETCONSOLE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_SERIO 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_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_DEBUG_GPIO=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_RTC_CLASS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/nuc910_defconfig b/arch/arm/configs/nuc910_defconfig
new file mode 100644
index 00000000..10180cfd
--- /dev/null
+++ b/arch/arm/configs/nuc910_defconfig
@@ -0,0 +1,60 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_W90X900=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_STORAGE=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ROMFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig
new file mode 100644
index 00000000..27aa8731
--- /dev/null
+++ b/arch/arm/configs/nuc950_defconfig
@@ -0,0 +1,76 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_W90X900=y
+# CONFIG_MACH_W90P910EVB is not set
+CONFIG_MACH_W90P950EVB=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_NUC900=y
+CONFIG_GPM1040A0_320X240=y
+CONFIG_FB_NUC900_DEBUG=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_STORAGE=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ROMFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
diff --git a/arch/arm/configs/nuc960_defconfig b/arch/arm/configs/nuc960_defconfig
new file mode 100644
index 00000000..56fd7ad0
--- /dev/null
+++ b/arch/arm/configs/nuc960_defconfig
@@ -0,0 +1,66 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_USER_NS=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_W90X900=y
+# CONFIG_MACH_W90P910EVB is not set
+CONFIG_MACH_W90N960EVB=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+CONFIG_KEXEC=y
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_MON=y
+CONFIG_USB_STORAGE=y
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ROMFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig
new file mode 100644
index 00000000..7b63462b
--- /dev/null
+++ b/arch/arm/configs/omap1_defconfig
@@ -0,0 +1,286 @@
+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
new file mode 100644
index 00000000..d5f00d7e
--- /dev/null
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -0,0 +1,236 @@
+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/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
new file mode 100644
index 00000000..a288d703
--- /dev/null
+++ b/arch/arm/configs/orion5x_defconfig
@@ -0,0 +1,179 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_ORION5X=y
+CONFIG_MACH_DB88F5281=y
+CONFIG_MACH_RD88F5182=y
+CONFIG_MACH_KUROBOX_PRO=y
+CONFIG_MACH_DNS323=y
+CONFIG_MACH_TS209=y
+CONFIG_MACH_TERASTATION_PRO2=y
+CONFIG_MACH_LINKSTATION_PRO=y
+CONFIG_MACH_LINKSTATION_MINI=y
+CONFIG_MACH_LINKSTATION_LS_HGL=y
+CONFIG_MACH_TS409=y
+CONFIG_MACH_WRT350N_V2=y
+CONFIG_MACH_TS78XX=y
+CONFIG_MACH_MV2120=y
+CONFIG_MACH_EDMINI_V2=y
+CONFIG_MACH_D2NET=y
+CONFIG_MACH_BIGDISK=y
+CONFIG_MACH_NET2BIG=y
+CONFIG_MACH_MSS2=y
+CONFIG_MACH_WNR854T=y
+CONFIG_MACH_RD88F5181L_GE=y
+CONFIG_MACH_RD88F5181L_FXO=y
+CONFIG_MACH_RD88F6183AP_GE=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_FPE_NWFPE=y
+CONFIG_VFP=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_NET_PKTGEN=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_FIRMWARE_IN_KERNEL 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_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_NAND_ORION=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_ATA=y
+CONFIG_SATA_MV=y
+CONFIG_NETDEVICES=y
+CONFIG_MARVELL_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_NET_PCI=y
+CONFIG_MV643XX_ETH=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MV64XXX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_SENSORS_LM75=y
+# CONFIG_VGA_ARB is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_PRINTER=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_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_DS1307=y
+CONFIG_RTC_DRV_RS5C372=y
+CONFIG_RTC_DRV_PCF8563=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_RTC_DRV_S35390A=y
+CONFIG_RTC_DRV_M48T86=y
+CONFIG_DMADEVICES=y
+CONFIG_MV_XOR=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4_FS=m
+CONFIG_INOTIFY=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+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_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_LATENCYTOP=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_DEV_MV_CESA=y
+CONFIG_CRC_T10DIF=y
diff --git a/arch/arm/configs/palmz72_defconfig b/arch/arm/configs/palmz72_defconfig
new file mode 100644
index 00000000..4baa83c1
--- /dev/null
+++ b/arch/arm/configs/palmz72_defconfig
@@ -0,0 +1,85 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_ARCH_PXA_PALM=y
+# CONFIG_MACH_PALMTX is not set
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=32M console=tty root=/dev/mmcblk0"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PXA27x=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PDA_POWER=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_DISPLAY_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_PXA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_SA1100=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=866
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_TMPFS=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_UTF8=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRC_T10DIF=y
diff --git a/arch/arm/configs/pcm027_defconfig b/arch/arm/configs/pcm027_defconfig
new file mode 100644
index 00000000..2f136c30
--- /dev/null
+++ b/arch/arm/configs/pcm027_defconfig
@@ -0,0 +1,102 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS 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_PXA=y
+CONFIG_MACH_PCM027=y
+CONFIG_MACH_PCM990_BASEBOARD=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_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=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_PHYSMAP=y
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PXA=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PXA2XX_AC97=y
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8563=m
+CONFIG_RTC_DRV_SA1100=m
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=m
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_MAGIC_SYSRQ=y
diff --git a/arch/arm/configs/pcontrol_g20_defconfig b/arch/arm/configs/pcontrol_g20_defconfig
new file mode 100644
index 00000000..c75c9fce
--- /dev/null
+++ b/arch/arm/configs/pcontrol_g20_defconfig
@@ -0,0 +1,175 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="/opt/arm-2010q1/bin/arm-none-linux-gnueabi-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_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/pleb_defconfig b/arch/arm/configs/pleb_defconfig
new file mode 100644
index 00000000..cb08cc56
--- /dev/null
+++ b/arch/arm/configs/pleb_defconfig
@@ -0,0 +1,57 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_SHMEM is not set
+CONFIG_MODULES=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_PLEB=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySA0,9600 mem=16M@0xc0000000 mem=16M@0xc8000000 root=/dev/ram initrd=0xc0400000,4M"
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=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_SA1100=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NLS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig
new file mode 100644
index 00000000..35a31cca
--- /dev/null
+++ b/arch/arm/configs/pnx4008_defconfig
@@ -0,0 +1,472 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_AUDIT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_ARCH_PNX4008=y
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_IP_SCTP=m
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_PKTGEN=m
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_SLRAM=m
+CONFIG_MTD_PHRAM=m
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTD_DOC2000=m
+CONFIG_MTD_DOC2001=m
+CONFIG_MTD_DOC2001PLUS=m
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_NANDSIM=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_EQUALIZER=m
+CONFIG_TUN=m
+CONFIG_NET_ETHERNET=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_WAN=y
+CONFIG_HDLC=m
+CONFIG_HDLC_RAW=m
+CONFIG_HDLC_RAW_ETH=m
+CONFIG_HDLC_CISCO=m
+CONFIG_HDLC_FR=m
+CONFIG_HDLC_PPP=m
+CONFIG_HDLC_X25=m
+CONFIG_DLCI=m
+CONFIG_WAN_ROUTER_DRIVERS=m
+CONFIG_LAPBETHER=m
+CONFIG_X25_ASY=m
+CONFIG_ATM_TCP=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+CONFIG_PPPOATM=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_NETCONSOLE=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_RAW=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_SOFT_WATCHDOG=m
+CONFIG_USBPCWATCHDOG=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_DUMMY=m
+CONFIG_SND_VIRMIDI=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SOUND_PRIME=m
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_TEST=m
+CONFIG_USB_ATM=m
+CONFIG_USB_SPEEDTOUCH=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_STATISTICS=y
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
+CONFIG_INOTIFY=y
+CONFIG_QUOTA=y
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=m
+CONFIG_CRAMFS=y
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
+CONFIG_RPCSEC_GSS_SPKM3=m
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRC16=m
diff --git a/arch/arm/configs/pxa168_defconfig b/arch/arm/configs/pxa168_defconfig
new file mode 100644
index 00000000..74d7e010
--- /dev/null
+++ b/arch/arm/configs/pxa168_defconfig
@@ -0,0 +1,70 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MMP=y
+CONFIG_MACH_ASPENITE=y
+CONFIG_MACH_ZYLONITE2=y
+CONFIG_MACH_AVENGERS_LITE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=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_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT 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_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig
new file mode 100644
index 00000000..917a070b
--- /dev/null
+++ b/arch/arm/configs/pxa255-idp_defconfig
@@ -0,0 +1,59 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_MODULES=y
+CONFIG_ARCH_PXA=y
+CONFIG_ARCH_PXA_IDP=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs ip=dhcp console=ttyS0,115200 mem=64M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_IDE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_EXT2_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
new file mode 100644
index 00000000..1677a060
--- /dev/null
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -0,0 +1,134 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_LITTLETON=y
+CONFIG_MACH_TAVOREVB=y
+CONFIG_MACH_SAAR=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.1.100:/nfsroot/ ip=192.168.1.101:192.168.1.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=64M debug"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_NAND_PXA3xx_BUILTIN=y
+CONFIG_MTD_ONENAND=y
+CONFIG_MTD_ONENAND_VERIFY_WRITE=y
+CONFIG_MTD_ONENAND_GENERIC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_PXA27x=y
+CONFIG_KEYBOARD_PXA930_ROTARY=y
+CONFIG_MOUSE_PXA930_TRKBALL=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCF857X=y
+CONFIG_GPIO_MAX7301=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_SUPPLY_DEBUG=y
+CONFIG_PDA_POWER=y
+CONFIG_BATTERY_DA9030=y
+# CONFIG_HWMON is not set
+CONFIG_PMIC_DA903X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_DA903X=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_TDO24M=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_DA903X=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_6x11=y
+CONFIG_LOGO=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_DA903X=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/pxa910_defconfig b/arch/arm/configs/pxa910_defconfig
new file mode 100644
index 00000000..1cd381e1
--- /dev/null
+++ b/arch/arm/configs/pxa910_defconfig
@@ -0,0 +1,70 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_MMP=y
+CONFIG_MACH_TAVOREVB=y
+CONFIG_MACH_TTC_DKB=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs rootfstype=nfs nfsroot=192.168.2.100:/nfsroot/ ip=192.168.2.101:192.168.2.100::255.255.255.0::eth0:on console=ttyS0,115200 mem=128M"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_BLK_DEV is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=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_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT 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_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/qil-a9260_defconfig b/arch/arm/configs/qil-a9260_defconfig
new file mode 100644
index 00000000..9160f3b7
--- /dev/null
+++ b/arch/arm/configs/qil-a9260_defconfig
@@ -0,0 +1,115 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_QIL_A9260=y
+CONFIG_AT91_SLOW_CLOCK=y
+CONFIG_AT91_EARLY_USART0=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS1,115200"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T94=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_FUSE_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig
new file mode 100644
index 00000000..f7caa909
--- /dev/null
+++ b/arch/arm/configs/raumfeld_defconfig
@@ -0,0 +1,208 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_RAUMFELD_RC=y
+CONFIG_MACH_RAUMFELD_CONNECTOR=y
+CONFIG_MACH_RAUMFELD_SPEAKER=y
+CONFIG_NO_HZ=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_CMDLINE="console=ttyS0,115200 rw"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_REG_DEBUG=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_PXA3xx=y
+CONFIG_MTD_UBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_ISL29003=y
+CONFIG_TI_DAC7512=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_USB_USBNET=y
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_NET1080 is not set
+CONFIG_USB_NET_MCS7830=y
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_DEBUG=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_W1_MASTER_GPIO=m
+CONFIG_POWER_SUPPLY=y
+CONFIG_PDA_POWER=y
+CONFIG_BATTERY_DS2760=m
+CONFIG_SENSORS_LIS3_SPI=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_MAX8660=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_USB is not set
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+CONFIG_SND_SOC_RAUMFELD=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_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_MMC=y
+CONFIG_MMC_PXA=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_LT3593=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PXA=y
+CONFIG_DMADEVICES=y
+CONFIG_UIO=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
new file mode 100644
index 00000000..abe61bf3
--- /dev/null
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -0,0 +1,101 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_REALVIEW=y
+CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_MACH_REALVIEW_PB11MP=y
+CONFIG_SMP=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_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_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_PHYSMAP=y
+CONFIG_ARM_CHARLCD=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# 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_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
+CONFIG_GPIOLIB=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_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_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig
new file mode 100644
index 00000000..7079cbe8
--- /dev/null
+++ b/arch/arm/configs/realview_defconfig
@@ -0,0 +1,100 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_REALVIEW=y
+CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_EB_ARM11MP=y
+CONFIG_MACH_REALVIEW_PB11MP=y
+CONFIG_MACH_REALVIEW_PB1176=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_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_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_PHYSMAP=y
+CONFIG_ARM_CHARLCD=y
+CONFIG_NETDEVICES=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# 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_I2C=y
+CONFIG_I2C_VERSATILE=y
+CONFIG_SPI=y
+CONFIG_GPIOLIB=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_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_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
new file mode 100644
index 00000000..af278f7a
--- /dev/null
+++ b/arch/arm/configs/rpc_defconfig
@@ -0,0 +1,135 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_RPC=y
+CONFIG_CPU_ARM610=y
+CONFIG_CPU_ARM710=y
+CONFIG_CPU_SA110=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=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_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_ARXESCSI=m
+CONFIG_SCSI_CUMANA_2=m
+CONFIG_SCSI_EESOXSCSI=m
+CONFIG_SCSI_POWERTECSCSI=y
+CONFIG_SCSI_CUMANA_1=m
+CONFIG_SCSI_OAK1=m
+CONFIG_ATA=y
+CONFIG_PATA_ICSIDE=y
+CONFIG_PATA_PLATFORM=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ARM_ETHER1=y
+CONFIG_ARM_ETHER3=y
+CONFIG_ARM_ETHERH=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_PPP=m
+CONFIG_PPPOE=m
+CONFIG_INPUT_EVDEV=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_RISCPC=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_RUNTIME_UARTS=8
+CONFIG_SERIAL_8250_ACORN=y
+CONFIG_LEGACY_PTY_COUNT=64
+CONFIG_PRINTER=m
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ACORN=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SOUND_PRIME=m
+CONFIG_SOUND_OSS=m
+CONFIG_SOUND_VIDC=m
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PCF8583=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_ADFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION_CUMANA is not set
+# CONFIG_ACORN_PARTITION_EESOX is not set
+CONFIG_BSD_DISKLABEL=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
new file mode 100644
index 00000000..f9096c1b
--- /dev/null
+++ b/arch/arm/configs/s3c2410_defconfig
@@ -0,0 +1,489 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=m
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_S3C2410=y
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_S3C_ADC=y
+CONFIG_S3C24XX_PWM=y
+CONFIG_ARCH_SMDK2410=y
+CONFIG_ARCH_H1940=y
+CONFIG_MACH_N30=y
+CONFIG_ARCH_BAST=y
+CONFIG_MACH_OTOM=y
+CONFIG_MACH_AML_M5900=y
+CONFIG_MACH_TCT_HAMMER=y
+CONFIG_MACH_VR1000=y
+CONFIG_MACH_QT2410=y
+CONFIG_MACH_JIVE=y
+CONFIG_MACH_SMDK2412=y
+CONFIG_MACH_VSTMS=y
+CONFIG_MACH_SMDK2416=y
+CONFIG_MACH_ANUBIS=y
+CONFIG_MACH_NEO1973_GTA02=y
+CONFIG_MACH_OSIRIS=y
+CONFIG_MACH_OSIRIS_DVS=m
+CONFIG_MACH_RX3715=y
+CONFIG_ARCH_S3C2440=y
+CONFIG_MACH_NEXCODER_2440=y
+CONFIG_SMDK2440_CPU2442=y
+CONFIG_MACH_AT2440EVB=y
+CONFIG_MACH_MINI2440=y
+CONFIG_MACH_RX1950=y
+CONFIG_MACH_SMDK2443=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=m
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+# CONFIG_INET_LRO is not set
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_S3C2410=y
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=m
+CONFIG_PARPORT_AX88796=m
+CONFIG_PARPORT_1284=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_UB=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_ATA_OVER_ETH=m
+CONFIG_EEPROM_AT25=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_93CX6=m
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_PLATFORM=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_MOUSE_APPLETOUCH=m
+CONFIG_MOUSE_BCM5974=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_DB9=m
+CONFIG_JOYSTICK_GAMECON=m
+CONFIG_JOYSTICK_TURBOGRAFX=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_JOYSTICK_XPAD=m
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_ATI_REMOTE=m
+CONFIG_INPUT_ATI_REMOTE2=m
+CONFIG_INPUT_KEYSPAN_REMOTE=m
+CONFIG_INPUT_POWERMATE=m
+CONFIG_INPUT_YEALINK=m
+CONFIG_INPUT_CM109=m
+CONFIG_INPUT_UINPUT=m
+CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_PRINTER=y
+CONFIG_PPDEV=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_S3C2410=y
+CONFIG_I2C_SIMTEC=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_S3C24XX=m
+CONFIG_SPI_S3C24XX_GPIO=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPI_TLE62X0=m
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM78=m
+CONFIG_SENSORS_LM85=m
+CONFIG_WATCHDOG=y
+CONFIG_S3C2410_WATCHDOG=y
+CONFIG_MFD_SM501=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_S3C2410=y
+CONFIG_FB_SM501=y
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_SOC=y
+CONFIG_SND_S3C24XX_SOC=y
+CONFIG_SND_S3C24XX_SOC_JIVE_WM8750=m
+CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710=m
+CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DATAFAB=m
+CONFIG_USB_STORAGE_FREECOM=m
+CONFIG_USB_STORAGE_ISD200=m
+CONFIG_USB_STORAGE_USBAT=m
+CONFIG_USB_STORAGE_SDDR09=m
+CONFIG_USB_STORAGE_SDDR55=m
+CONFIG_USB_STORAGE_JUMPSHOT=m
+CONFIG_USB_STORAGE_ALAUDA=m
+CONFIG_USB_STORAGE_ONETOUCH=m
+CONFIG_USB_STORAGE_KARMA=m
+CONFIG_USB_STORAGE_CYPRESS_ATACB=m
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_USS720=m
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_NAVMAN=m
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_ADUTUX=m
+CONFIG_USB_SEVSEG=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYPRESS_CY7C63=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_FTDI_ELAN=m
+CONFIG_USB_APPLEDISPLAY=m
+CONFIG_USB_LD=m
+CONFIG_USB_TRANCEVIBRATOR=m
+CONFIG_USB_IOWARRIOR=m
+CONFIG_USB_TEST=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_TEST=m
+CONFIG_MMC_SDHCI=m
+CONFIG_MMC_SPI=m
+CONFIG_MMC_S3C=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_S3C24XX=m
+CONFIG_LEDS_H1940=m
+CONFIG_LEDS_PCA9532=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_DAC124S085=m
+CONFIG_LEDS_PWM=m
+CONFIG_LEDS_BD2802=m
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S3C=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_FS_POSIX_ACL=y
+CONFIG_EXT4_FS=m
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_NTFS_FS=m
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_CRAMFS=y
+CONFIG_SQUASHFS=m
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=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_CRYPTO_ANSI_CPRNG is not set
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig
new file mode 100644
index 00000000..ba6a5150
--- /dev/null
+++ b/arch/arm/configs/s3c6400_defconfig
@@ -0,0 +1,93 @@
+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_S3C64XX=y
+CONFIG_S3C_BOOT_ERROR_RESET=y
+CONFIG_MACH_SMDK6400=y
+CONFIG_MACH_ANW6410=y
+CONFIG_MACH_SMDK6410=y
+CONFIG_MACH_NCP=y
+CONFIG_MACH_HMT=y
+CONFIG_MACH_SMARTQ5=y
+CONFIG_MACH_SMARTQ7=y
+CONFIG_CPU_32v6K=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x51000000,6M ramdisk_size=6144"
+CONFIG_VFP=y
+CONFIG_PM=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_S3C2410=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_S3C2410=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=m
+CONFIG_SPI_S3C64XX=m
+CONFIG_FB=y
+CONFIG_FB_S3C=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_LTV350QV=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SOC=m
+CONFIG_SND_S3C24XX_SOC=m
+CONFIG_SND_SOC_SMDK_WM9713=m
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_S3C=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_S3C=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=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
diff --git a/arch/arm/configs/s5p64x0_defconfig b/arch/arm/configs/s5p64x0_defconfig
new file mode 100644
index 00000000..ad6b61b0
--- /dev/null
+++ b/arch/arm/configs/s5p64x0_defconfig
@@ -0,0 +1,68 @@
+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/s5pc100_defconfig b/arch/arm/configs/s5pc100_defconfig
new file mode 100644
index 00000000..41bafc94
--- /dev/null
+++ b/arch/arm/configs/s5pc100_defconfig
@@ -0,0 +1,49 @@
+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_S5PC100=y
+CONFIG_MACH_SMDKC100=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=cramfs init=/linuxrc console=ttySAC2,115200 mem=128M"
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_EEPROM_AT24=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_SAMSUNG=y
+CONFIG_SERIAL_SAMSUNG_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_SDIO_UART=y
+CONFIG_MMC_SDHCI=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=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
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
new file mode 100644
index 00000000..fa989902
--- /dev/null
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -0,0 +1,73 @@
+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_S5PV210=y
+CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_DEV_FB=y
+CONFIG_S5PV210_SETUP_FB_24BPP=y
+CONFIG_MACH_AQUILA=y
+CONFIG_MACH_GONI=y
+CONFIG_MACH_SMDKC110=y
+CONFIG_MACH_SMDKV210=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
+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_MISC_DEVICES is not set
+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_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=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_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_DEBUG_PREEMPT is not set
+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/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig
new file mode 100644
index 00000000..ecf25315
--- /dev/null
+++ b/arch/arm/configs/sam9_l9260_defconfig
@@ -0,0 +1,148 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_AUDIT=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_SAM9_L9260=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+CONFIG_PREEMPT=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200 mem=64M initrd=0x21100000,4194304 root=/dev/ram0 rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=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_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_RESERVE=3
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_MISC_DEVICES is not set
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_GADGET=y
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=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_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1553=y
+CONFIG_RTC_DRV_DS1742=y
+CONFIG_RTC_DRV_M48T86=y
+CONFIG_RTC_DRV_V3020=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_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/shannon_defconfig b/arch/arm/configs/shannon_defconfig
new file mode 100644
index 00000000..b0b96942
--- /dev/null
+++ b/arch/arm/configs/shannon_defconfig
@@ -0,0 +1,48 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_MODULES=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_SHANNON=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IPV6 is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_IDE=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_PCMCIA_SMC91C92=y
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_SA1100=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_SOUND=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_JFFS2_FS=y
+CONFIG_MINIX_FS=y
+CONFIG_NFS_FS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig
new file mode 100644
index 00000000..caa07db9
--- /dev/null
+++ b/arch/arm/configs/shark_defconfig
@@ -0,0 +1,81 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_SHARK=y
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_FPE_NWFPE=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_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_STANDALONE is not set
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_CS89x0=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_PRINTER=m
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_CYBER2000=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=m
+CONFIG_SOUND_PRIME=m
+CONFIG_SOUND_OSS=m
+CONFIG_SOUND_SB=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_CMOS=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFSD=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig
new file mode 100644
index 00000000..d3358155
--- /dev/null
+++ b/arch/arm/configs/simpad_defconfig
@@ -0,0 +1,111 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="oe1"
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_ARCH_SA1100=y
+CONFIG_SA1100_SIMPAD=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_SA1100=y
+CONFIG_PREEMPT=y
+CONFIG_LEDS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mtdparts=sa1100:512k(boot),1m(kernel),-(root) console=ttySA0 root=1f02 noinitrd mem=64M jffs2_orphaned_inodes=delete rootfstype=jffs2"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+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_IPV6 is not set
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRTTY_SIR=m
+CONFIG_SA1100_FIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+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_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_SA1100=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=800
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=600
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO=m
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_FB=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=m
+CONFIG_REISERFS_FS=m
+CONFIG_REISERFS_PROC_INFO=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=m
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_SMB_FS=m
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig
new file mode 100644
index 00000000..fea7e1f0
--- /dev/null
+++ b/arch/arm/configs/spear3xx_defconfig
@@ -0,0 +1,53 @@
+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
new file mode 100644
index 00000000..cef2e836
--- /dev/null
+++ b/arch/arm/configs/spear6xx_defconfig
@@ -0,0 +1,49 @@
+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/spitz_defconfig b/arch/arm/configs/spitz_defconfig
new file mode 100644
index 00000000..70158273
--- /dev/null
+++ b/arch/arm/configs/spitz_defconfig
@@ -0,0 +1,275 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_PXA=y
+CONFIG_PXA_SHARPSL=y
+CONFIG_MACH_AKITA=y
+CONFIG_MACH_BORZOI=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_PXA2XX=y
+CONFIG_PREEMPT=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug"
+CONFIG_FPE_NWFPE=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_PXA_FICP=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+CONFIG_MTD_NAND_SHARPSL=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_SCSI=m
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_PCNET=m
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_FB=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_CORGI=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_SAFE=m
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+CONFIG_USB_IDMOUSE=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_PXA=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_FS_XATTR is not set
+CONFIG_INOTIFY=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_CRAMFS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_CCITT=y
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig
new file mode 100644
index 00000000..d5e260b8
--- /dev/null
+++ b/arch/arm/configs/stamp9g20_defconfig
@@ -0,0 +1,129 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_TREE_PREEMPT_RCU=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_PORTUXG20=y
+CONFIG_MACH_STAMP9G20=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+CONFIG_AT91_SLOW_CLOCK=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="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_KEXEC=y
+CONFIG_CPU_IDLE=y
+CONFIG_PM=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_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_DATAFLASH=y
+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_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MACB=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_MOUSEDEV_SCREEN_X=320
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_W1=y
+CONFIG_W1_MASTER_GPIO=y
+CONFIG_W1_SLAVE_THERM=y
+CONFIG_W1_SLAVE_DS2431=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=m
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+# CONFIG_MMC_AT91 is not set
+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_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=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_ARM_UNWIND is not set
diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig
new file mode 100644
index 00000000..95c0f0d6
--- /dev/null
+++ b/arch/arm/configs/tct_hammer_defconfig
@@ -0,0 +1,70 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_KALLSYMS is not set
+# CONFIG_BUG is not set
+# CONFIG_ELF_CORE is not set
+# CONFIG_SHMEM is not set
+CONFIG_SLOB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_S3C2410=y
+CONFIG_MACH_TCT_HAMMER=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M root=/dev/ram0 init=/linuxrc rw"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=10240
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT_CONSOLE is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_S3C2410=y
+CONFIG_USB_ETH=m
+CONFIG_EXT2_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_PROC_SYSCTL is not set
+CONFIG_JFFS2_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DETECT_SOFTLOCKUP is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
new file mode 100644
index 00000000..8845f1c9
--- /dev/null
+++ b/arch/arm/configs/tegra_defconfig
@@ -0,0 +1,146 @@
+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/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig
new file mode 100644
index 00000000..3162173f
--- /dev/null
+++ b/arch/arm/configs/trizeps4_defconfig
@@ -0,0 +1,226 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_ARCH_PXA=y
+CONFIG_TRIZEPS_PXA=y
+CONFIG_MACH_TRIZEPS4=y
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_LOAD_CIS is not set
+CONFIG_PCMCIA_PXA2XX=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_CMDLINE="root=fe01 console=ttyS0,38400n8 loglevel=5"
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_NWFPE_XP=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IPV6 is not set
+CONFIG_NETFILTER=y
+CONFIG_IP_NF_QUEUE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_IRDA=m
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+CONFIG_IRDA_ULTRA=y
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+CONFIG_IRTTY_SIR=m
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_CFG80211=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_DOC2000=y
+CONFIG_MTD_DOC2001=y
+CONFIG_MTD_DOC2001PLUS=y
+CONFIG_MTD_DOCPROBE_ADVANCED=y
+CONFIG_MTD_DOCPROBE_ADDRESS=0x4000000
+CONFIG_MTD_DOCPROBE_HIGH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y
+CONFIG_MTD_ONENAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=8
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_ATA=m
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PLATFORM=m
+CONFIG_NETDEVICES=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+CONFIG_HOSTAP=y
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+CONFIG_HOSTAP_CS=y
+CONFIG_HERMES=y
+CONFIG_PCMCIA_HERMES=y
+CONFIG_PCMCIA_SPECTRUM=y
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_SERIAL=m
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PXA=y
+CONFIG_I2C_PXA_SLAVE=y
+CONFIG_WATCHDOG=y
+CONFIG_SA1100_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_FB_PXA=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+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=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+CONFIG_SND_PXA2XX_AC97=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DUMMY_HCD=y
+CONFIG_MMC=y
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_PCF8583=m
+CONFIG_RTC_DRV_SA1100=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_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_INOTIFY=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-15"
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V4=y
+CONFIG_SMB_FS=m
+CONFIG_CIFS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_LDM_PARTITION=y
+CONFIG_NLS_DEFAULT="iso8859-15"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_USER=y
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig
new file mode 100644
index 00000000..4a5a1268
--- /dev/null
+++ b/arch/arm/configs/u300_defconfig
@@ -0,0 +1,74 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_EXPERT=y
+# CONFIG_AIO is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_U300=y
+CONFIG_MACH_U300=y
+CONFIG_MACH_U300_BS335=y
+CONFIG_MACH_U300_DUAL_RAM=y
+CONFIG_U300_DEBUG=y
+CONFIG_MACH_U300_SPIDUMMY=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072"
+CONFIG_CPU_IDLE=y
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+# CONFIG_SUSPEND is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_MISC_DEVICES is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_FB=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_RTC_CLASS=y
+# CONFIG_RTC_HCTOSYS is not set
+CONFIG_RTC_DRV_COH901331=y
+CONFIG_DMADEVICES=y
+CONFIG_COH901318=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
new file mode 100644
index 00000000..a5cce242
--- /dev/null
+++ b/arch/arm/configs/u8500_defconfig
@@ -0,0 +1,105 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_ARCH_U8500=y
+CONFIG_UX500_SOC_DB5500=y
+CONFIG_UX500_SOC_DB8500=y
+CONFIG_MACH_U8500=y
+CONFIG_MACH_U5500=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 console=ttyAMA2,115200n8"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_PHONET=y
+CONFIG_PHONET_PIPECTRLR=y
+# CONFIG_WIRELESS is not set
+CONFIG_CAIF=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_MISC_DEVICES=y
+CONFIG_AB8500_PWM=y
+CONFIG_SENSORS_BH1780=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_NOMADIK=y
+CONFIG_KEYBOARD_STMPE=y
+CONFIG_KEYBOARD_TC3589X=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_BU21013=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AB8500_PONKEY=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_NOMADIK=y
+CONFIG_I2C=y
+CONFIG_I2C_NOMADIK=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_GPIO_STMPE=y
+CONFIG_GPIO_TC3589X=y
+# CONFIG_HWMON is not set
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_TC3589X=y
+CONFIG_AB8500_CORE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AB8500=y
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LP5521=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AB8500=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_STE_DMA40=y
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=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_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=m
+# CONFIG_MISC_FILESYSTEMS 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_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/usb-a9260_defconfig b/arch/arm/configs/usb-a9260_defconfig
new file mode 100644
index 00000000..2e39f38b
--- /dev/null
+++ b/arch/arm/configs/usb-a9260_defconfig
@@ -0,0 +1,106 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9260=y
+CONFIG_MACH_USB_A9260=y
+CONFIG_AT91_SLOW_CLOCK=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=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_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ETH=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_EXT2_FS=y
+CONFIG_INOTIFY=y
+CONFIG_FUSE_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig
new file mode 100644
index 00000000..cdd4d2bd
--- /dev/null
+++ b/arch/arm/configs/versatile_defconfig
@@ -0,0 +1,84 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MACH_VERSATILE_AB=y
+CONFIG_LEDS=y
+CONFIG_LEDS_CPU=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=1f03 mem=32M"
+CONFIG_FPE_NWFPE=y
+CONFIG_VFP=y
+CONFIG_PM=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 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_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_EEPROM_LEGACY=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=m
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_SOUND=y
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_ARMAACI=m
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=m
+CONFIG_EXT2_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_MINIX_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
new file mode 100644
index 00000000..f2de51f0
--- /dev/null
+++ b/arch/arm/configs/vexpress_defconfig
@@ -0,0 +1,140 @@
+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/configs/viper_defconfig b/arch/arm/configs/viper_defconfig
new file mode 100644
index 00000000..1d01ddd3
--- /dev/null
+++ b/arch/arm/configs/viper_defconfig
@@ -0,0 +1,174 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_LOG_BUF_SHIFT=13
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_EXPERT=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_SHMEM is not set
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_ARCH_VIPER=y
+CONFIG_IWMMXT=y
+CONFIG_PCCARD=m
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=31:02 rootfstype=jffs2 ro console=ttyS0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_FPE_FASTFPE=y
+CONFIG_PM=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_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_FW_LOADER=m
+CONFIG_MTD=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=0
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+# CONFIG_SATA_PMP is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMC91X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_INPUT_MOUSEDEV=m
+# 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_FUJITSU=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_HTCPEN=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_PXA=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_PXA=m
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_PWM=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PXA2XX_AC97=m
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_ISP116X_HCD=m
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_R8A66597_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_RTC_DRV_SA1100=m
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=m
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRC_T10DIF=m
diff --git a/arch/arm/configs/xcep_defconfig b/arch/arm/configs/xcep_defconfig
new file mode 100644
index 00000000..721832ff
--- /dev/null
+++ b/arch/arm/configs/xcep_defconfig
@@ -0,0 +1,99 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION=".xcep-itech"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+# CONFIG_UID16 is not set
+# CONFIG_SHMEM is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLOB=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_BLOCK is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_XCEP=y
+CONFIG_IWMMXT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=mtd4 rootfstype=jffs2 ro console=ttyS0,115200"
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=m
+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_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PXA2XX=y
+# CONFIG_MISC_DEVICES is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PXA=m
+CONFIG_HWMON=m
+CONFIG_SENSORS_ADM1021=m
+CONFIG_SENSORS_MAX6650=m
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_SA1100=m
+CONFIG_DMADEVICES=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_WBUF_VERIFY=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_UTF8=m
+CONFIG_PRINTK_TIME=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_FTRACE is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_LIBCRC32C=m
diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig
new file mode 100644
index 00000000..547a3c1e
--- /dev/null
+++ b/arch/arm/configs/zeus_defconfig
@@ -0,0 +1,189 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=13
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_PXA=y
+CONFIG_MACH_ARCOM_ZEUS=y
+CONFIG_PCCARD=m
+CONFIG_PCMCIA_PXA2XX=m
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=31:02 rootfstype=jffs2 ro console=ttyS0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_FPE_NWFPE=y
+CONFIG_PM=y
+CONFIG_APM_EMULATION=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_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_CFG80211=m
+CONFIG_LIB80211=m
+CONFIG_MAC80211=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_PARTS_READONLY=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PXA2XX=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_EEPROM_AT24=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+CONFIG_ATA=m
+# CONFIG_SATA_PMP is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_RT2X00=m
+CONFIG_RT73USB=m
+CONFIG_NET_PCMCIA=y
+CONFIG_PPP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# 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_FUJITSU=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_HTCPEN=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=7
+CONFIG_SERIAL_8250_RUNTIME_UARTS=7
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_GPIO=y
+CONFIG_I2C_PXA=y
+CONFIG_SPI=y
+CONFIG_SPI_PXA2XX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_SENSORS_LM75=m
+CONFIG_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_PXA=m
+CONFIG_FB_PXA_PARAMETERS=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_LOGO=y
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_PXA2XX_AC97=m
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_PXA2XX_SOC=m
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_MCT_U232=m
+CONFIG_USB_GADGET=m
+CONFIG_USB_PXA27X=y
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_USB_G_PRINTER=m
+CONFIG_MMC=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_PXA=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_GPIO=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_ISL1208=m
+CONFIG_RTC_DRV_PXA=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRC_T10DIF=m
diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild
new file mode 100644
index 00000000..6550db3a
--- /dev/null
+++ b/arch/arm/include/asm/Kbuild
@@ -0,0 +1,3 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += hwcap.h
diff --git a/arch/arm/include/asm/a.out-core.h b/arch/arm/include/asm/a.out-core.h
new file mode 100644
index 00000000..92f10cb5
--- /dev/null
+++ b/arch/arm/include/asm/a.out-core.h
@@ -0,0 +1,45 @@
+/* a.out coredump register dumper
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_A_OUT_CORE_H
+#define _ASM_A_OUT_CORE_H
+
+#ifdef __KERNEL__
+
+#include <linux/user.h>
+#include <linux/elfcore.h>
+
+/*
+ * fill in the user structure for an a.out core dump
+ */
+static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
+{
+ struct task_struct *tsk = current;
+
+ dump->magic = CMAGIC;
+ dump->start_code = tsk->mm->start_code;
+ dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
+
+ dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+ dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ dump->u_ssize = 0;
+
+ memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg));
+
+ if (dump->start_stack < 0x04000000)
+ dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
+
+ dump->regs = *regs;
+ dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
+}
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_A_OUT_CORE_H */
diff --git a/arch/arm/include/asm/a.out.h b/arch/arm/include/asm/a.out.h
new file mode 100644
index 00000000..083894b2
--- /dev/null
+++ b/arch/arm/include/asm/a.out.h
@@ -0,0 +1,34 @@
+#ifndef __ARM_A_OUT_H__
+#define __ARM_A_OUT_H__
+
+#include <linux/personality.h>
+#include <linux/types.h>
+
+struct exec
+{
+ __u32 a_info; /* Use macros N_MAGIC, etc for access */
+ __u32 a_text; /* length of text, in bytes */
+ __u32 a_data; /* length of data, in bytes */
+ __u32 a_bss; /* length of uninitialized data area for file, in bytes */
+ __u32 a_syms; /* length of symbol table data in file, in bytes */
+ __u32 a_entry; /* start address */
+ __u32 a_trsize; /* length of relocation info for text, in bytes */
+ __u32 a_drsize; /* length of relocation info for data, in bytes */
+};
+
+/*
+ * This is always the same
+ */
+#define N_TXTADDR(a) (0x00008000)
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+
+#define M_ARM 103
+
+#ifndef LIBRARY_START_TEXT
+#define LIBRARY_START_TEXT (0x00c00000)
+#endif
+
+#endif /* __A_OUT_GNU_H__ */
diff --git a/arch/arm/include/asm/asm-offsets.h b/arch/arm/include/asm/asm-offsets.h
new file mode 100644
index 00000000..d370ee36
--- /dev/null
+++ b/arch/arm/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
new file mode 100644
index 00000000..fed335ef
--- /dev/null
+++ b/arch/arm/include/asm/assembler.h
@@ -0,0 +1,310 @@
+/*
+ * arch/arm/include/asm/assembler.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
+ */
+#ifndef __ASM_ASSEMBLER_H__
+#define __ASM_ASSEMBLER_H__
+
+#ifndef __ASSEMBLY__
+#error "Only include this from assembly code"
+#endif
+
+#include <asm/ptrace.h>
+#include <asm/domain.h>
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull lsr
+#define push lsl
+#define get_byte_0 lsl #0
+#define get_byte_1 lsr #8
+#define get_byte_2 lsr #16
+#define get_byte_3 lsr #24
+#define put_byte_0 lsl #0
+#define put_byte_1 lsl #8
+#define put_byte_2 lsl #16
+#define put_byte_3 lsl #24
+#else
+#define pull lsl
+#define push lsr
+#define get_byte_0 lsr #24
+#define get_byte_1 lsr #16
+#define get_byte_2 lsr #8
+#define get_byte_3 lsl #0
+#define put_byte_0 lsl #24
+#define put_byte_1 lsl #16
+#define put_byte_2 lsl #8
+#define put_byte_3 lsl #0
+#endif
+
+/*
+ * Data preload for architectures that support it
+ */
+#if __LINUX_ARM_ARCH__ >= 5
+#define PLD(code...) code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * This can be used to enable code to cacheline align the destination
+ * pointer when bulk writing to memory. Experiments on StrongARM and
+ * XScale didn't show this a worthwhile thing to do when the cache is not
+ * set to write-allocate (this would need further testing on XScale when WA
+ * is used).
+ *
+ * On Feroceon there is much to gain however, regardless of cache mode.
+ */
+#ifdef CONFIG_CPU_FEROCEON
+#define CALGN(code...) code
+#else
+#define CALGN(code...)
+#endif
+
+/*
+ * Enable and disable interrupts
+ */
+#if __LINUX_ARM_ARCH__ >= 6
+ .macro disable_irq_notrace
+ cpsid i
+ .endm
+
+ .macro enable_irq_notrace
+ cpsie i
+ .endm
+#else
+ .macro disable_irq_notrace
+ msr cpsr_c, #PSR_I_BIT | SVC_MODE
+ .endm
+
+ .macro enable_irq_notrace
+ msr cpsr_c, #SVC_MODE
+ .endm
+#endif
+
+ .macro asm_trace_hardirqs_off
+#if defined(CONFIG_TRACE_IRQFLAGS)
+ stmdb sp!, {r0-r3, ip, lr}
+ bl trace_hardirqs_off
+ ldmia sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro asm_trace_hardirqs_on_cond, cond
+#if defined(CONFIG_TRACE_IRQFLAGS)
+ /*
+ * actually the registers should be pushed and pop'd conditionally, but
+ * after bl the flags are certainly clobbered
+ */
+ stmdb sp!, {r0-r3, ip, lr}
+ bl\cond trace_hardirqs_on
+ ldmia sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro asm_trace_hardirqs_on
+ asm_trace_hardirqs_on_cond al
+ .endm
+
+ .macro disable_irq
+ disable_irq_notrace
+ asm_trace_hardirqs_off
+ .endm
+
+ .macro enable_irq
+ asm_trace_hardirqs_on
+ enable_irq_notrace
+ .endm
+/*
+ * Save the current IRQ state and disable IRQs. Note that this macro
+ * assumes FIQs are enabled, and that the processor is in SVC mode.
+ */
+ .macro save_and_disable_irqs, oldcpsr
+ mrs \oldcpsr, cpsr
+ disable_irq
+ .endm
+
+ .macro save_and_disable_irqs_notrace, oldcpsr
+ mrs \oldcpsr, cpsr
+ disable_irq_notrace
+ .endm
+
+/*
+ * Restore interrupt state previously stored in a register. We don't
+ * guarantee that this will preserve the flags.
+ */
+ .macro restore_irqs_notrace, oldcpsr
+ msr cpsr_c, \oldcpsr
+ .endm
+
+ .macro restore_irqs, oldcpsr
+ tst \oldcpsr, #PSR_I_BIT
+ asm_trace_hardirqs_on_cond eq
+ restore_irqs_notrace \oldcpsr
+ .endm
+
+#define USER(x...) \
+9999: x; \
+ .pushsection __ex_table,"a"; \
+ .align 3; \
+ .long 9999b,9001f; \
+ .popsection
+
+#ifdef CONFIG_SMP
+#define ALT_SMP(instr...) \
+9998: instr
+/*
+ * Note: if you get assembler errors from ALT_UP() when building with
+ * CONFIG_THUMB2_KERNEL, you almost certainly need to use
+ * ALT_SMP( W(instr) ... )
+ */
+#define ALT_UP(instr...) \
+ .pushsection ".alt.smp.init", "a" ;\
+ .long 9998b ;\
+9997: instr ;\
+ .if . - 9997b != 4 ;\
+ .error "ALT_UP() content must assemble to exactly 4 bytes";\
+ .endif ;\
+ .popsection
+#define ALT_UP_B(label) \
+ .equ up_b_offset, label - 9998b ;\
+ .pushsection ".alt.smp.init", "a" ;\
+ .long 9998b ;\
+ W(b) . + up_b_offset ;\
+ .popsection
+#else
+#define ALT_SMP(instr...)
+#define ALT_UP(instr...) instr
+#define ALT_UP_B(label) b label
+#endif
+
+/*
+ * SMP data memory barrier
+ */
+ .macro smp_dmb mode
+#ifdef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7
+ .ifeqs "\mode","arm"
+ ALT_SMP(dmb)
+ .else
+ ALT_SMP(W(dmb))
+ .endif
+#elif __LINUX_ARM_ARCH__ == 6
+ ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
+#else
+#error Incompatible SMP platform
+#endif
+ .ifeqs "\mode","arm"
+ ALT_UP(nop)
+ .else
+ ALT_UP(W(nop))
+ .endif
+#endif
+ .endm
+
+#ifdef CONFIG_THUMB2_KERNEL
+ .macro setmode, mode, reg
+ mov \reg, #\mode
+ msr cpsr_c, \reg
+ .endm
+#else
+ .macro setmode, mode, reg
+ msr cpsr_c, #\mode
+ .endm
+#endif
+
+/*
+ * STRT/LDRT access macros with ARM and Thumb-2 variants
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+
+ .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER()
+9999:
+ .if \inc == 1
+ \instr\cond\()b\()\t\().w \reg, [\ptr, #\off]
+ .elseif \inc == 4
+ \instr\cond\()\t\().w \reg, [\ptr, #\off]
+ .else
+ .error "Unsupported inc macro argument"
+ .endif
+
+ .pushsection __ex_table,"a"
+ .align 3
+ .long 9999b, \abort
+ .popsection
+ .endm
+
+ .macro usracc, instr, reg, ptr, inc, cond, rept, abort
+ @ explicit IT instruction needed because of the label
+ @ introduced by the USER macro
+ .ifnc \cond,al
+ .if \rept == 1
+ itt \cond
+ .elseif \rept == 2
+ ittt \cond
+ .else
+ .error "Unsupported rept macro argument"
+ .endif
+ .endif
+
+ @ Slightly optimised to avoid incrementing the pointer twice
+ usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
+ .if \rept == 2
+ usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
+ .endif
+
+ add\cond \ptr, #\rept * \inc
+ .endm
+
+#else /* !CONFIG_THUMB2_KERNEL */
+
+ .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER()
+ .rept \rept
+9999:
+ .if \inc == 1
+ \instr\cond\()b\()\t \reg, [\ptr], #\inc
+ .elseif \inc == 4
+ \instr\cond\()\t \reg, [\ptr], #\inc
+ .else
+ .error "Unsupported inc macro argument"
+ .endif
+
+ .pushsection __ex_table,"a"
+ .align 3
+ .long 9999b, \abort
+ .popsection
+ .endr
+ .endm
+
+#endif /* CONFIG_THUMB2_KERNEL */
+
+ .macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
+ usracc str, \reg, \ptr, \inc, \cond, \rept, \abort
+ .endm
+
+ .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/atomic.h b/arch/arm/include/asm/atomic.h
new file mode 100644
index 00000000..7e79503a
--- /dev/null
+++ b/arch/arm/include/asm/atomic.h
@@ -0,0 +1,468 @@
+/*
+ * arch/arm/include/asm/atomic.h
+ *
+ * Copyright (C) 1996 Russell King.
+ * Copyright (C) 2002 Deep Blue Solutions 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 __ASM_ARM_ATOMIC_H
+#define __ASM_ARM_ATOMIC_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/system.h>
+
+#define ATOMIC_INIT(i) { (i) }
+
+#ifdef __KERNEL__
+
+/*
+ * On ARM, ordinary assignment (str instruction) doesn't clear the local
+ * strex/ldrex monitor on some implementations. The reason we can use it for
+ * atomic_set() is the clrex or dummy strex done on every exception return.
+ */
+#define atomic_read(v) (*(volatile int *)&(v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+/*
+ * ARMv6 UP and SMP safe atomic ops. We use load exclusive and
+ * store exclusive to ensure that these are atomic. We may loop
+ * to ensure that the update happens.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+ unsigned long tmp;
+ int result;
+
+ __asm__ __volatile__("@ atomic_add\n"
+"1: ldrex %0, [%3]\n"
+" add %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "Ir" (i)
+ : "cc");
+}
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long tmp;
+ int result;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic_add_return\n"
+"1: ldrex %0, [%3]\n"
+" add %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "Ir" (i)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline void atomic_sub(int i, atomic_t *v)
+{
+ unsigned long tmp;
+ int result;
+
+ __asm__ __volatile__("@ atomic_sub\n"
+"1: ldrex %0, [%3]\n"
+" sub %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "Ir" (i)
+ : "cc");
+}
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long tmp;
+ int result;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic_sub_return\n"
+"1: ldrex %0, [%3]\n"
+" sub %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "Ir" (i)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+{
+ unsigned long oldval, res;
+
+ smp_mb();
+
+ do {
+ __asm__ __volatile__("@ atomic_cmpxchg\n"
+ "ldrex %1, [%3]\n"
+ "mov %0, #0\n"
+ "teq %1, %4\n"
+ "strexeq %0, %5, [%3]\n"
+ : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
+ : "r" (&ptr->counter), "Ir" (old), "r" (new)
+ : "cc");
+ } while (res);
+
+ smp_mb();
+
+ return oldval;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+ unsigned long tmp, tmp2;
+
+ __asm__ __volatile__("@ atomic_clear_mask\n"
+"1: ldrex %0, [%3]\n"
+" bic %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr)
+ : "r" (addr), "Ir" (mask)
+ : "cc");
+}
+
+#else /* ARM_ARCH_6 */
+
+#ifdef CONFIG_SMP
+#error SMP not supported on pre-ARMv6 CPUs
+#endif
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ raw_local_irq_save(flags);
+ val = v->counter;
+ v->counter = val += i;
+ raw_local_irq_restore(flags);
+
+ return val;
+}
+#define atomic_add(i, v) (void) atomic_add_return(i, v)
+
+static inline int atomic_sub_return(int i, atomic_t *v)
+{
+ unsigned long flags;
+ int val;
+
+ raw_local_irq_save(flags);
+ val = v->counter;
+ v->counter = val -= i;
+ raw_local_irq_restore(flags);
+
+ return val;
+}
+#define atomic_sub(i, v) (void) atomic_sub_return(i, v)
+
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+ int ret;
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ ret = v->counter;
+ if (likely(ret == old))
+ v->counter = new;
+ raw_local_irq_restore(flags);
+
+ return ret;
+}
+
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+{
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ *addr &= ~mask;
+ raw_local_irq_restore(flags);
+}
+
+#endif /* __LINUX_ARM_ARCH__ */
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int c, old;
+
+ c = atomic_read(v);
+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+ c = old;
+ return c != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#define atomic_inc(v) atomic_add(1, v)
+#define atomic_dec(v) atomic_sub(1, v)
+
+#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
+#define atomic_inc_return(v) (atomic_add_return(1, v))
+#define atomic_dec_return(v) (atomic_sub_return(1, v))
+#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
+
+#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)
+
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#ifndef CONFIG_GENERIC_ATOMIC64
+typedef struct {
+ u64 __aligned(8) counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+static inline u64 atomic64_read(atomic64_t *v)
+{
+ u64 result;
+
+ __asm__ __volatile__("@ atomic64_read\n"
+" ldrexd %0, %H0, [%1]"
+ : "=&r" (result)
+ : "r" (&v->counter), "Qo" (v->counter)
+ );
+
+ return result;
+}
+
+static inline void atomic64_set(atomic64_t *v, u64 i)
+{
+ u64 tmp;
+
+ __asm__ __volatile__("@ atomic64_set\n"
+"1: ldrexd %0, %H0, [%2]\n"
+" strexd %0, %3, %H3, [%2]\n"
+" teq %0, #0\n"
+" bne 1b"
+ : "=&r" (tmp), "=Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+}
+
+static inline void atomic64_add(u64 i, atomic64_t *v)
+{
+ u64 result;
+ unsigned long tmp;
+
+ __asm__ __volatile__("@ atomic64_add\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" adds %0, %0, %4\n"
+" adc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+}
+
+static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+{
+ u64 result;
+ unsigned long tmp;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic64_add_return\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" adds %0, %0, %4\n"
+" adc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline void atomic64_sub(u64 i, atomic64_t *v)
+{
+ u64 result;
+ unsigned long tmp;
+
+ __asm__ __volatile__("@ atomic64_sub\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %0, %0, %4\n"
+" sbc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+}
+
+static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
+{
+ u64 result;
+ unsigned long tmp;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic64_sub_return\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %0, %0, %4\n"
+" sbc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (i)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
+{
+ u64 oldval;
+ unsigned long res;
+
+ smp_mb();
+
+ do {
+ __asm__ __volatile__("@ atomic64_cmpxchg\n"
+ "ldrexd %1, %H1, [%3]\n"
+ "mov %0, #0\n"
+ "teq %1, %4\n"
+ "teqeq %H1, %H4\n"
+ "strexdeq %0, %5, %H5, [%3]"
+ : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
+ : "r" (&ptr->counter), "r" (old), "r" (new)
+ : "cc");
+ } while (res);
+
+ smp_mb();
+
+ return oldval;
+}
+
+static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
+{
+ u64 result;
+ unsigned long tmp;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic64_xchg\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" strexd %1, %4, %H4, [%3]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
+ : "r" (&ptr->counter), "r" (new)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline u64 atomic64_dec_if_positive(atomic64_t *v)
+{
+ u64 result;
+ unsigned long tmp;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic64_dec_if_positive\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %0, %0, #1\n"
+" sbc %H0, %H0, #0\n"
+" teq %H0, #0\n"
+" bmi 2f\n"
+" strexd %1, %0, %H0, [%3]\n"
+" teq %1, #0\n"
+" bne 1b\n"
+"2:"
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter)
+ : "cc");
+
+ smp_mb();
+
+ return result;
+}
+
+static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+{
+ u64 val;
+ unsigned long tmp;
+ int ret = 1;
+
+ smp_mb();
+
+ __asm__ __volatile__("@ atomic64_add_unless\n"
+"1: ldrexd %0, %H0, [%4]\n"
+" teq %0, %5\n"
+" teqeq %H0, %H5\n"
+" moveq %1, #0\n"
+" beq 2f\n"
+" adds %0, %0, %6\n"
+" adc %H0, %H0, %H6\n"
+" strexd %2, %0, %H0, [%4]\n"
+" teq %2, #0\n"
+" bne 1b\n"
+"2:"
+ : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
+ : "r" (&v->counter), "r" (u), "r" (a)
+ : "cc");
+
+ if (ret)
+ smp_mb();
+
+ return ret;
+}
+
+#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v) atomic64_add(1LL, (v))
+#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
+#define atomic64_dec(v) atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
+
+#else /* !CONFIG_GENERIC_ATOMIC64 */
+#include <asm-generic/atomic64.h>
+#endif
+#include <asm-generic/atomic-long.h>
+#endif
+#endif
diff --git a/arch/arm/include/asm/auxvec.h b/arch/arm/include/asm/auxvec.h
new file mode 100644
index 00000000..c0536f6b
--- /dev/null
+++ b/arch/arm/include/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef __ASMARM_AUXVEC_H
+#define __ASMARM_AUXVEC_H
+
+#endif
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
new file mode 100644
index 00000000..b4892a06
--- /dev/null
+++ b/arch/arm/include/asm/bitops.h
@@ -0,0 +1,320 @@
+/*
+ * Copyright 1995, Russell King.
+ * Various bits and pieces copyrights include:
+ * Linus Torvalds (test_bit).
+ * Big endian support: Copyright 2001, Nicolas Pitre
+ * reworked by rmk.
+ *
+ * bit 0 is the LSB of an "unsigned long" quantity.
+ *
+ * Please note that the code in this file should never be included
+ * from user space. Many of these are not implemented in assembler
+ * since they would be too costly. Also, they require privileged
+ * instructions (which are not available from user mode) to ensure
+ * that they are atomic.
+ */
+
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <linux/compiler.h>
+#include <asm/system.h>
+
+#define smp_mb__before_clear_bit() mb()
+#define smp_mb__after_clear_bit() mb()
+
+/*
+ * These functions are the basis of our bit ops.
+ *
+ * First, the atomic bitops. These use native endian.
+ */
+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p |= mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p &= ~mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ *p ^= mask;
+ raw_local_irq_restore(flags);
+}
+
+static inline int
+____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res | mask;
+ raw_local_irq_restore(flags);
+
+ return (res & mask) != 0;
+}
+
+static inline int
+____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res & ~mask;
+ raw_local_irq_restore(flags);
+
+ return (res & mask) != 0;
+}
+
+static inline int
+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
+{
+ unsigned long flags;
+ unsigned int res;
+ unsigned long mask = 1UL << (bit & 31);
+
+ p += bit >> 5;
+
+ raw_local_irq_save(flags);
+ res = *p;
+ *p = res ^ mask;
+ raw_local_irq_restore(flags);
+
+ return (res & mask) != 0;
+}
+
+#include <asm-generic/bitops/non-atomic.h>
+
+/*
+ * A note about Endian-ness.
+ * -------------------------
+ *
+ * When the ARM is put into big endian mode via CR15, the processor
+ * merely swaps the order of bytes within words, thus:
+ *
+ * ------------ physical data bus bits -----------
+ * D31 ... D24 D23 ... D16 D15 ... D8 D7 ... D0
+ * little byte 3 byte 2 byte 1 byte 0
+ * big byte 0 byte 1 byte 2 byte 3
+ *
+ * This means that reading a 32-bit word at address 0 returns the same
+ * value irrespective of the endian mode bit.
+ *
+ * Peripheral devices should be connected with the data bus reversed in
+ * "Big Endian" mode. ARM Application Note 61 is applicable, and is
+ * available from http://www.arm.com/.
+ *
+ * The following assumes that the data bus connectivity for big endian
+ * mode has been followed.
+ *
+ * Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
+ */
+
+/*
+ * Native endian assembly bitops. nr = 0 -> word 0 bit 0.
+ */
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+
+/*
+ * Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
+ */
+extern int _find_first_zero_bit_le(const void * p, unsigned size);
+extern int _find_next_zero_bit_le(const void * p, int size, int offset);
+extern int _find_first_bit_le(const unsigned long *p, unsigned size);
+extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
+
+/*
+ * Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
+ */
+extern int _find_first_zero_bit_be(const void * p, unsigned size);
+extern int _find_next_zero_bit_be(const void * p, int size, int offset);
+extern int _find_first_bit_be(const unsigned long *p, unsigned size);
+extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
+
+#ifndef CONFIG_SMP
+/*
+ * The __* form of bitops are non-atomic and may be reordered.
+ */
+#define ATOMIC_BITOP(name,nr,p) \
+ (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
+#else
+#define ATOMIC_BITOP(name,nr,p) _##name(nr,p)
+#endif
+
+/*
+ * Native endian atomic definitions.
+ */
+#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p)
+
+#ifndef __ARMEB__
+/*
+ * These are the little endian, atomic definitions.
+ */
+#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
+#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
+#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
+#define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off)
+
+#else
+/*
+ * These are the big endian, atomic definitions.
+ */
+#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz)
+#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off)
+#define find_first_bit(p,sz) _find_first_bit_be(p,sz)
+#define find_next_bit(p,sz,off) _find_next_bit_be(p,sz,off)
+
+#endif
+
+#if __LINUX_ARM_ARCH__ < 5
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/__ffs.h>
+#include <asm-generic/bitops/fls.h>
+#include <asm-generic/bitops/ffs.h>
+
+#else
+
+static inline int constant_fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+/*
+ * On ARMv5 and above those functions can be implemented around
+ * the clz instruction for much better code efficiency.
+ */
+
+static inline int fls(int x)
+{
+ int ret;
+
+ if (__builtin_constant_p(x))
+ return constant_fls(x);
+
+ asm("clz\t%0, %1" : "=r" (ret) : "r" (x));
+ ret = 32 - ret;
+ return ret;
+}
+
+#define __fls(x) (fls(x) - 1)
+#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
+#define __ffs(x) (ffs(x) - 1)
+#define ffz(x) __ffs( ~(x) )
+
+#endif
+
+#include <asm-generic/bitops/fls64.h>
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#ifdef __ARMEB__
+
+static inline int find_first_zero_bit_le(const void *p, unsigned size)
+{
+ return _find_first_zero_bit_le(p, size);
+}
+#define find_first_zero_bit_le find_first_zero_bit_le
+
+static inline int find_next_zero_bit_le(const void *p, int size, int offset)
+{
+ return _find_next_zero_bit_le(p, size, offset);
+}
+#define find_next_zero_bit_le find_next_zero_bit_le
+
+static inline int find_next_bit_le(const void *p, int size, int offset)
+{
+ return _find_next_bit_le(p, size, offset);
+}
+#define find_next_bit_le find_next_bit_le
+
+#endif
+
+#include <asm-generic/bitops/le.h>
+
+/*
+ * Ext2 is defined to use little-endian byte ordering.
+ */
+#define ext2_set_bit_atomic(lock, nr, p) \
+ test_and_set_bit_le(nr, p)
+#define ext2_clear_bit_atomic(lock, nr, p) \
+ test_and_clear_bit_le(nr, p)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ARM_BITOPS_H */
diff --git a/arch/arm/include/asm/bitsperlong.h b/arch/arm/include/asm/bitsperlong.h
new file mode 100644
index 00000000..6dc0bb0c
--- /dev/null
+++ b/arch/arm/include/asm/bitsperlong.h
@@ -0,0 +1 @@
+#include <asm-generic/bitsperlong.h>
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
new file mode 100644
index 00000000..4d88425a
--- /dev/null
+++ b/arch/arm/include/asm/bug.h
@@ -0,0 +1,24 @@
+#ifndef _ASMARM_BUG_H
+#define _ASMARM_BUG_H
+
+
+#ifdef CONFIG_BUG
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+extern void __bug(const char *file, int line) __attribute__((noreturn));
+
+/* give file/line information */
+#define BUG() __bug(__FILE__, __LINE__)
+
+#else
+
+/* this just causes an oops */
+#define BUG() do { *(int *)0 = 0; } while (1)
+
+#endif
+
+#define HAVE_ARCH_BUG
+#endif
+
+#include <asm-generic/bug.h>
+
+#endif
diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h
new file mode 100644
index 00000000..a97f1ea7
--- /dev/null
+++ b/arch/arm/include/asm/bugs.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/include/asm/bugs.h
+ *
+ * Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can 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_BUGS_H
+#define __ASM_BUGS_H
+
+#ifdef CONFIG_MMU
+extern void check_writebuffer_bugs(void);
+
+#define check_bugs() check_writebuffer_bugs()
+#else
+#define check_bugs() do { } while (0)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h
new file mode 100644
index 00000000..77379748
--- /dev/null
+++ b/arch/arm/include/asm/byteorder.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/include/asm/byteorder.h
+ *
+ * ARM Endian-ness. In little endian mode, the data bus is connected such
+ * that byte accesses appear as:
+ * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ *
+ * When in big endian mode, byte accesses appear as:
+ * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ */
+#ifndef __ASM_ARM_BYTEORDER_H
+#define __ASM_ARM_BYTEORDER_H
+
+#ifdef __ARMEB__
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif
+
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
new file mode 100644
index 00000000..75fe66bc
--- /dev/null
+++ b/arch/arm/include/asm/cache.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/include/asm/cache.h
+ */
+#ifndef __ASMARM_CACHE_H
+#define __ASMARM_CACHE_H
+
+#define L1_CACHE_SHIFT CONFIG_ARM_L1_CACHE_SHIFT
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+/*
+ * Memory returned by kmalloc() may be used for DMA, so we must make
+ * sure that all such allocations are cache aligned. Otherwise,
+ * unrelated code may cause parts of the buffer to be read into the
+ * cache before the transfer is done, causing old data to be seen by
+ * the CPU.
+ */
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+
+/*
+ * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
+ */
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define ARCH_SLAB_MINALIGN 8
+#endif
+
+#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+
+#endif
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
new file mode 100644
index 00000000..1252a267
--- /dev/null
+++ b/arch/arm/include/asm/cacheflush.h
@@ -0,0 +1,347 @@
+/*
+ * arch/arm/include/asm/cacheflush.h
+ *
+ * Copyright (C) 1999-2002 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_CACHEFLUSH_H
+#define _ASMARM_CACHEFLUSH_H
+
+#include <linux/mm.h>
+
+#include <asm/glue-cache.h>
+#include <asm/shmparam.h>
+#include <asm/cachetype.h>
+#include <asm/outercache.h>
+
+#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
+
+/*
+ * This flag is used to indicate that the page pointed to by a pte is clean
+ * and does not require cleaning before returning it to the user.
+ */
+#define PG_dcache_clean PG_arch_1
+
+/*
+ * MM Cache Management
+ * ===================
+ *
+ * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
+ * implement these methods.
+ *
+ * Start addresses are inclusive and end addresses are exclusive;
+ * start addresses should be rounded down, end addresses up.
+ *
+ * See Documentation/cachetlb.txt for more information.
+ * Please note that the implementation of these, and the required
+ * effects are cache-type (VIVT/VIPT/PIPT) specific.
+ *
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ * Currently only needed for cache-v6.S and cache-v7.S, see
+ * __flush_icache_all for the generic implementation.
+ *
+ * flush_kern_all()
+ *
+ * Unconditionally clean and invalidate the entire cache.
+ *
+ * flush_user_all()
+ *
+ * Clean and invalidate all user space cache entries
+ * before a change of page tables.
+ *
+ * flush_user_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address space before a change of page tables.
+ * - start - user start address (inclusive, page aligned)
+ * - end - user end address (exclusive, page aligned)
+ * - flags - vma->vm_flags field
+ *
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * flush_kern_dcache_area(kaddr, size)
+ *
+ * Ensure that the data held in page is written back.
+ * - kaddr - page address
+ * - size - region size
+ *
+ * DMA Cache Coherency
+ * ===================
+ *
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+
+struct cpu_cache_fns {
+ void (*flush_icache_all)(void);
+ void (*flush_kern_all)(void);
+ void (*flush_user_all)(void);
+ void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
+
+ void (*coherent_kern_range)(unsigned long, unsigned long);
+ void (*coherent_user_range)(unsigned long, unsigned long);
+ void (*flush_kern_dcache_area)(void *, size_t);
+
+ void (*dma_map_area)(const void *, size_t, int);
+ void (*dma_unmap_area)(const void *, size_t, int);
+
+ void (*dma_flush_range)(const void *, const void *);
+};
+
+/*
+ * Select the calling method
+ */
+#ifdef MULTI_CACHE
+
+extern struct cpu_cache_fns cpu_cache;
+
+#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
+#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
+#define __cpuc_flush_user_all cpu_cache.flush_user_all
+#define __cpuc_flush_user_range cpu_cache.flush_user_range
+#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
+#define __cpuc_coherent_user_range cpu_cache.coherent_user_range
+#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area
+
+/*
+ * These are private to the dma-mapping API. Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+#define dmac_map_area cpu_cache.dma_map_area
+#define dmac_unmap_area cpu_cache.dma_unmap_area
+#define dmac_flush_range cpu_cache.dma_flush_range
+
+#else
+
+extern void __cpuc_flush_icache_all(void);
+extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_user_all(void);
+extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
+extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
+extern void __cpuc_coherent_user_range(unsigned long, unsigned long);
+extern void __cpuc_flush_dcache_area(void *, size_t);
+
+/*
+ * These are private to the dma-mapping API. Do not use directly.
+ * Their sole purpose is to ensure that data held in the cache
+ * is visible to DMA, or data written by DMA to system memory is
+ * visible to the CPU.
+ */
+extern void dmac_map_area(const void *, size_t, int);
+extern void dmac_unmap_area(const void *, size_t, int);
+extern void dmac_flush_range(const void *, const void *);
+
+#endif
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space. Really, we want to allow our "user
+ * space" model to handle this.
+ */
+extern void copy_to_user_page(struct vm_area_struct *, struct page *,
+ unsigned long, void *, const void *, unsigned long);
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ do { \
+ memcpy(dst, src, len); \
+ } while (0)
+
+/*
+ * Convert calls to our calling convention.
+ */
+
+/* Invalidate I-cache */
+#define __flush_icache_all_generic() \
+ asm("mcr p15, 0, %0, c7, c5, 0" \
+ : : "r" (0));
+
+/* Invalidate I-cache inner shareable */
+#define __flush_icache_all_v7_smp() \
+ asm("mcr p15, 0, %0, c7, c1, 0" \
+ : : "r" (0));
+
+/*
+ * Optimized __flush_icache_all for the common cases. Note that UP ARMv7
+ * will fall through to use __flush_icache_all_generic.
+ */
+#if (defined(CONFIG_CPU_V7) && \
+ (defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \
+ defined(CONFIG_SMP_ON_UP)
+#define __flush_icache_preferred __cpuc_flush_icache_all
+#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
+#define __flush_icache_preferred __flush_icache_all_v7_smp
+#elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920)
+#define __flush_icache_preferred __cpuc_flush_icache_all
+#else
+#define __flush_icache_preferred __flush_icache_all_generic
+#endif
+
+static inline void __flush_icache_all(void)
+{
+ __flush_icache_preferred();
+}
+
+#define flush_cache_all() __cpuc_flush_kern_all()
+
+static inline void vivt_flush_cache_mm(struct mm_struct *mm)
+{
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
+ __cpuc_flush_user_all();
+}
+
+static inline void
+vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
+ __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
+ vma->vm_flags);
+}
+
+static inline void
+vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+{
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+ unsigned long addr = user_addr & PAGE_MASK;
+ __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
+ }
+}
+
+#ifndef CONFIG_CPU_CACHE_VIPT
+#define flush_cache_mm(mm) \
+ vivt_flush_cache_mm(mm)
+#define flush_cache_range(vma,start,end) \
+ vivt_flush_cache_range(vma,start,end)
+#define flush_cache_page(vma,addr,pfn) \
+ vivt_flush_cache_page(vma,addr,pfn)
+#else
+extern void flush_cache_mm(struct mm_struct *mm);
+extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn);
+#endif
+
+#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
+
+/*
+ * flush_cache_user_range is used when we want to ensure that the
+ * 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(start,end) \
+ __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
+
+/*
+ * Perform necessary cache operations to ensure that data previously
+ * stored within this range of addresses can be executed by the CPU.
+ */
+#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
+
+/*
+ * Perform necessary cache operations to ensure that the TLB will
+ * see data written in the specified area.
+ */
+#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
+
+/*
+ * flush_dcache_page is used when the kernel has written to the page
+ * cache page at virtual address page->virtual.
+ *
+ * If this page isn't mapped (ie, page_mapping == NULL), or it might
+ * have userspace mappings, then we _must_ always clean + invalidate
+ * the dcache entries associated with the kernel mapping.
+ *
+ * Otherwise we can defer the operation, and clean the cache when we are
+ * about to change to user space. This is the same method as used on SPARC64.
+ * See update_mmu_cache for the user space part.
+ */
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+extern void flush_dcache_page(struct page *);
+
+static inline void flush_kernel_vmap_range(void *addr, int size)
+{
+ if ((cache_is_vivt() || cache_is_vipt_aliasing()))
+ __cpuc_flush_dcache_area(addr, (size_t)size);
+}
+static inline void invalidate_kernel_vmap_range(void *addr, int size)
+{
+ if ((cache_is_vivt() || cache_is_vipt_aliasing()))
+ __cpuc_flush_dcache_area(addr, (size_t)size);
+}
+
+#define ARCH_HAS_FLUSH_ANON_PAGE
+static inline void flush_anon_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vmaddr)
+{
+ extern void __flush_anon_page(struct vm_area_struct *vma,
+ struct page *, unsigned long);
+ if (PageAnon(page))
+ __flush_anon_page(vma, page, vmaddr);
+}
+
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+}
+
+#define flush_dcache_mmap_lock(mapping) \
+ spin_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping) \
+ spin_unlock_irq(&(mapping)->tree_lock)
+
+#define flush_icache_user_range(vma,page,addr,len) \
+ flush_dcache_page(page)
+
+/*
+ * We don't appear to need to do anything here. In fact, if we did, we'd
+ * duplicate cache flushing elsewhere performed by flush_dcache_page().
+ */
+#define flush_icache_page(vma,page) do { } while (0)
+
+/*
+ * flush_cache_vmap() is used when creating mappings (eg, via vmap,
+ * vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
+ * caches, since the direct-mappings of these pages may contain cached
+ * data, we need to do a full cache flush to ensure that writebacks
+ * don't corrupt data placed into these pages via the new mappings.
+ */
+static inline void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+ if (!cache_is_vipt_nonaliasing())
+ flush_cache_all();
+ else
+ /*
+ * set_pte_at() called from vmap_pte_range() does not
+ * have a DSB after cleaning the cache line.
+ */
+ dsb();
+}
+
+static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+ if (!cache_is_vipt_nonaliasing())
+ flush_cache_all();
+}
+
+#endif
diff --git a/arch/arm/include/asm/cachetype.h b/arch/arm/include/asm/cachetype.h
new file mode 100644
index 00000000..c023db09
--- /dev/null
+++ b/arch/arm/include/asm/cachetype.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_ARM_CACHETYPE_H
+#define __ASM_ARM_CACHETYPE_H
+
+#define CACHEID_VIVT (1 << 0)
+#define CACHEID_VIPT_NONALIASING (1 << 1)
+#define CACHEID_VIPT_ALIASING (1 << 2)
+#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
+#define CACHEID_ASID_TAGGED (1 << 3)
+#define CACHEID_VIPT_I_ALIASING (1 << 4)
+
+extern unsigned int cacheid;
+
+#define cache_is_vivt() cacheid_is(CACHEID_VIVT)
+#define cache_is_vipt() cacheid_is(CACHEID_VIPT)
+#define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING)
+#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
+#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
+#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
+
+/*
+ * __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
+ * Mask out support which will never be present on newer CPUs.
+ * - v6+ is never VIVT
+ * - v7+ VIPT never aliases on D-side
+ */
+#if __LINUX_ARM_ARCH__ >= 7
+#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\
+ CACHEID_ASID_TAGGED |\
+ CACHEID_VIPT_I_ALIASING)
+#elif __LINUX_ARM_ARCH__ >= 6
+#define __CACHEID_ARCH_MIN (~CACHEID_VIVT)
+#else
+#define __CACHEID_ARCH_MIN (~0)
+#endif
+
+/*
+ * Mask out support which isn't configured
+ */
+#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
+#define __CACHEID_ALWAYS (CACHEID_VIVT)
+#define __CACHEID_NEVER (~CACHEID_VIVT)
+#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
+#define __CACHEID_ALWAYS (0)
+#define __CACHEID_NEVER (CACHEID_VIVT)
+#else
+#define __CACHEID_ALWAYS (0)
+#define __CACHEID_NEVER (0)
+#endif
+
+static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)
+{
+ return (__CACHEID_ALWAYS & mask) |
+ (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid);
+}
+
+#endif
diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h
new file mode 100644
index 00000000..6dcc1643
--- /dev/null
+++ b/arch/arm/include/asm/checksum.h
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/include/asm/checksum.h
+ *
+ * IP checksum routines
+ *
+ * Copyright (C) Original authors of ../asm-i386/checksum.h
+ * Copyright (C) 1996-1999 Russell King
+ */
+#ifndef __ASM_ARM_CHECKSUM_H
+#define __ASM_ARM_CHECKSUM_H
+
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+__wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+__wsum
+csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum);
+
+__wsum
+csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
+
+/*
+ * Fold a partial checksum without adding pseudo headers
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+ __asm__(
+ "add %0, %1, %1, ror #16 @ csum_fold"
+ : "=r" (sum)
+ : "r" (sum)
+ : "cc");
+ return (__force __sum16)(~(__force u32)sum >> 16);
+}
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ */
+static inline __sum16
+ip_fast_csum(const void *iph, unsigned int ihl)
+{
+ unsigned int tmp1;
+ __wsum sum;
+
+ __asm__ __volatile__(
+ "ldr %0, [%1], #4 @ ip_fast_csum \n\
+ ldr %3, [%1], #4 \n\
+ sub %2, %2, #5 \n\
+ adds %0, %0, %3 \n\
+ ldr %3, [%1], #4 \n\
+ adcs %0, %0, %3 \n\
+ ldr %3, [%1], #4 \n\
+1: adcs %0, %0, %3 \n\
+ ldr %3, [%1], #4 \n\
+ tst %2, #15 @ do this carefully \n\
+ subne %2, %2, #1 @ without destroying \n\
+ bne 1b @ the carry flag \n\
+ adcs %0, %0, %3 \n\
+ adc %0, %0, #0"
+ : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
+ : "1" (iph), "2" (ihl)
+ : "cc", "memory");
+ return csum_fold(sum);
+}
+
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ __asm__(
+ "adds %0, %1, %2 @ csum_tcpudp_nofold \n\
+ adcs %0, %0, %3 \n"
+#ifdef __ARMEB__
+ "adcs %0, %0, %4 \n"
+#else
+ "adcs %0, %0, %4, lsl #8 \n"
+#endif
+ "adcs %0, %0, %5 \n\
+ adc %0, %0, #0"
+ : "=&r"(sum)
+ : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
+ : "cc");
+ return sum;
+}
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+}
+
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+ */
+static inline __sum16
+ip_compute_csum(const void *buff, int len)
+{
+ return csum_fold(csum_partial(buff, len, 0));
+}
+
+#define _HAVE_ARCH_IPV6_CSUM
+extern __wsum
+__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len,
+ __be32 proto, __wsum sum);
+
+static inline __sum16
+csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len,
+ unsigned short proto, __wsum sum)
+{
+ return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
+ htonl(proto), sum));
+}
+#endif
diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h
new file mode 100644
index 00000000..765d3322
--- /dev/null
+++ b/arch/arm/include/asm/clkdev.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/include/asm/clkdev.h
+ *
+ * Copyright (C) 2008 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+#include <linux/slab.h>
+
+#include <mach/clkdev.h>
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+ return kzalloc(size, GFP_KERNEL);
+}
+
+#endif
diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h
new file mode 100644
index 00000000..79396817
--- /dev/null
+++ b/arch/arm/include/asm/cpu.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/include/asm/cpu.h
+ *
+ * Copyright (C) 2004-2005 ARM 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 __ASM_ARM_CPU_H
+#define __ASM_ARM_CPU_H
+
+#include <linux/percpu.h>
+#include <linux/cpu.h>
+
+struct cpuinfo_arm {
+ struct cpu cpu;
+#ifdef CONFIG_SMP
+ struct task_struct *idle;
+ unsigned int loops_per_jiffy;
+#endif
+};
+
+DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data);
+
+#endif
diff --git a/arch/arm/include/asm/cputime.h b/arch/arm/include/asm/cputime.h
new file mode 100644
index 00000000..3a8002a5
--- /dev/null
+++ b/arch/arm/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef __ARM_CPUTIME_H
+#define __ARM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __ARM_CPUTIME_H */
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
new file mode 100644
index 00000000..cd4458f6
--- /dev/null
+++ b/arch/arm/include/asm/cputype.h
@@ -0,0 +1,99 @@
+#ifndef __ASM_ARM_CPUTYPE_H
+#define __ASM_ARM_CPUTYPE_H
+
+#include <linux/stringify.h>
+#include <linux/kernel.h>
+
+#define CPUID_ID 0
+#define CPUID_CACHETYPE 1
+#define CPUID_TCM 2
+#define CPUID_TLBTYPE 3
+
+#define CPUID_EXT_PFR0 "c1, 0"
+#define CPUID_EXT_PFR1 "c1, 1"
+#define CPUID_EXT_DFR0 "c1, 2"
+#define CPUID_EXT_AFR0 "c1, 3"
+#define CPUID_EXT_MMFR0 "c1, 4"
+#define CPUID_EXT_MMFR1 "c1, 5"
+#define CPUID_EXT_MMFR2 "c1, 6"
+#define CPUID_EXT_MMFR3 "c1, 7"
+#define CPUID_EXT_ISAR0 "c2, 0"
+#define CPUID_EXT_ISAR1 "c2, 1"
+#define CPUID_EXT_ISAR2 "c2, 2"
+#define CPUID_EXT_ISAR3 "c2, 3"
+#define CPUID_EXT_ISAR4 "c2, 4"
+#define CPUID_EXT_ISAR5 "c2, 5"
+
+extern unsigned int processor_id;
+
+#ifdef CONFIG_CPU_CP15
+#define read_cpuid(reg) \
+ ({ \
+ unsigned int __val; \
+ asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \
+ : "=r" (__val) \
+ : \
+ : "cc"); \
+ __val; \
+ })
+#define read_cpuid_ext(ext_reg) \
+ ({ \
+ unsigned int __val; \
+ asm("mrc p15, 0, %0, c0, " ext_reg \
+ : "=r" (__val) \
+ : \
+ : "cc"); \
+ __val; \
+ })
+#else
+#define read_cpuid(reg) (processor_id)
+#define read_cpuid_ext(reg) 0
+#endif
+
+/*
+ * The CPU ID never changes at run time, so we might as well tell the
+ * compiler that it's constant. Use this function to read the CPU ID
+ * rather than directly reading processor_id or read_cpuid() directly.
+ */
+static inline unsigned int __attribute_const__ read_cpuid_id(void)
+{
+ return read_cpuid(CPUID_ID);
+}
+
+static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
+{
+ return read_cpuid(CPUID_CACHETYPE);
+}
+
+static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
+{
+ return read_cpuid(CPUID_TCM);
+}
+
+/*
+ * Intel's XScale3 core supports some v6 features (supersections, L2)
+ * but advertises itself as v5 as it does not support the v6 ISA. For
+ * this reason, we need a way to explicitly test for this type of CPU.
+ */
+#ifndef CONFIG_CPU_XSC3
+#define cpu_is_xsc3() 0
+#else
+static inline int cpu_is_xsc3(void)
+{
+ unsigned int id;
+ id = read_cpuid_id() & 0xffffe000;
+ /* It covers both Intel ID and Marvell ID */
+ if ((id == 0x69056000) || (id == 0x56056000))
+ return 1;
+
+ return 0;
+}
+#endif
+
+#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
+#define cpu_is_xscale() 0
+#else
+#define cpu_is_xscale() 1
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
new file mode 100644
index 00000000..75d21e2a
--- /dev/null
+++ b/arch/arm/include/asm/current.h
@@ -0,0 +1,15 @@
+#ifndef _ASMARM_CURRENT_H
+#define _ASMARM_CURRENT_H
+
+#include <linux/thread_info.h>
+
+static inline struct task_struct *get_current(void) __attribute_const__;
+
+static inline struct task_struct *get_current(void)
+{
+ return current_thread_info()->task;
+}
+
+#define current (get_current())
+
+#endif /* _ASMARM_CURRENT_H */
diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
new file mode 100644
index 00000000..b2deda18
--- /dev/null
+++ b/arch/arm/include/asm/delay.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 1995-2004 Russell King
+ *
+ * Delay routines, using a pre-computed "loops_per_second" value.
+ */
+#ifndef __ASM_ARM_DELAY_H
+#define __ASM_ARM_DELAY_H
+
+#include <asm/param.h> /* HZ */
+
+extern void __delay(int loops);
+
+/*
+ * This function intentionally does not exist; if you see references to
+ * it, it means that you're calling udelay() with an out of range value.
+ *
+ * With currently imposed limits, this means that we support a max delay
+ * of 2000us. Further limits: HZ<=1000 and bogomips<=3355
+ */
+extern void __bad_udelay(void);
+
+/*
+ * division by multiplication: you don't have to worry about
+ * loss of precision.
+ *
+ * Use only for very small delays ( < 1 msec). Should probably use a
+ * lookup table, really, as the multiplications take much too long with
+ * short delays. This is a "reasonable" implementation, though (and the
+ * first constant multiplications gets optimized away if the delay is
+ * a constant)
+ */
+extern void __udelay(unsigned long usecs);
+extern void __const_udelay(unsigned long);
+
+#define MAX_UDELAY_MS 2
+
+#define udelay(n) \
+ (__builtin_constant_p(n) ? \
+ ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
+ __const_udelay((n) * ((2199023U*HZ)>>11))) : \
+ __udelay(n))
+
+#endif /* defined(_ARM_DELAY_H) */
+
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
new file mode 100644
index 00000000..9f390ce3
--- /dev/null
+++ b/arch/arm/include/asm/device.h
@@ -0,0 +1,18 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#ifndef ASMARM_DEVICE_H
+#define ASMARM_DEVICE_H
+
+struct dev_archdata {
+#ifdef CONFIG_DMABOUNCE
+ struct dmabounce_device_info *dmabounce;
+#endif
+};
+
+struct pdev_archdata {
+};
+
+#endif
diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
new file mode 100644
index 00000000..d3f0a9ee
--- /dev/null
+++ b/arch/arm/include/asm/div64.h
@@ -0,0 +1,227 @@
+#ifndef __ASM_ARM_DIV64
+#define __ASM_ARM_DIV64
+
+#include <asm/system.h>
+#include <linux/types.h>
+
+/*
+ * The semantics of do_div() are:
+ *
+ * uint32_t do_div(uint64_t *n, uint32_t base)
+ * {
+ * uint32_t remainder = *n % base;
+ * *n = *n / base;
+ * return remainder;
+ * }
+ *
+ * In other words, a 64-bit dividend with a 32-bit divisor producing
+ * a 64-bit result and a 32-bit remainder. To accomplish this optimally
+ * we call a special __do_div64 helper with completely non standard
+ * calling convention for arguments and results (beware).
+ */
+
+#ifdef __ARMEB__
+#define __xh "r0"
+#define __xl "r1"
+#else
+#define __xl "r0"
+#define __xh "r1"
+#endif
+
+#define __do_div_asm(n, base) \
+({ \
+ register unsigned int __base asm("r4") = base; \
+ register unsigned long long __n asm("r0") = n; \
+ register unsigned long long __res asm("r2"); \
+ register unsigned int __rem asm(__xh); \
+ asm( __asmeq("%0", __xh) \
+ __asmeq("%1", "r2") \
+ __asmeq("%2", "r0") \
+ __asmeq("%3", "r4") \
+ "bl __do_div64" \
+ : "=r" (__rem), "=r" (__res) \
+ : "r" (__n), "r" (__base) \
+ : "ip", "lr", "cc"); \
+ n = __res; \
+ __rem; \
+})
+
+#if __GNUC__ < 4
+
+/*
+ * gcc versions earlier than 4.0 are simply too problematic for the
+ * optimized implementation below. First there is gcc PR 15089 that
+ * tend to trig on more complex constructs, spurious .global __udivsi3
+ * are inserted even if none of those symbols are referenced in the
+ * generated code, and those gcc versions are not able to do constant
+ * propagation on long long values anyway.
+ */
+#define do_div(n, base) __do_div_asm(n, base)
+
+#elif __GNUC__ >= 4
+
+#include <asm/bug.h>
+
+/*
+ * If the divisor happens to be constant, we determine the appropriate
+ * inverse at compile time to turn the division into a few inline
+ * multiplications instead which is much faster. And yet only if compiling
+ * for ARMv4 or higher (we need umull/umlal) and if the gcc version is
+ * sufficiently recent to perform proper long long constant propagation.
+ * (It is unfortunate that gcc doesn't perform all this internally.)
+ */
+#define do_div(n, base) \
+({ \
+ unsigned int __r, __b = (base); \
+ if (!__builtin_constant_p(__b) || __b == 0 || \
+ (__LINUX_ARM_ARCH__ < 4 && (__b & (__b - 1)) != 0)) { \
+ /* non-constant divisor (or zero): slow path */ \
+ __r = __do_div_asm(n, __b); \
+ } else if ((__b & (__b - 1)) == 0) { \
+ /* Trivial: __b is constant and a power of 2 */ \
+ /* gcc does the right thing with this code. */ \
+ __r = n; \
+ __r &= (__b - 1); \
+ n /= __b; \
+ } else { \
+ /* Multiply by inverse of __b: n/b = n*(p/b)/p */ \
+ /* We rely on the fact that most of this code gets */ \
+ /* optimized away at compile time due to constant */ \
+ /* propagation and only a couple inline assembly */ \
+ /* instructions should remain. Better avoid any */ \
+ /* code construct that might prevent that. */ \
+ unsigned long long __res, __x, __t, __m, __n = n; \
+ unsigned int __c, __p, __z = 0; \
+ /* preserve low part of n for reminder computation */ \
+ __r = __n; \
+ /* determine number of bits to represent __b */ \
+ __p = 1 << __div64_fls(__b); \
+ /* compute __m = ((__p << 64) + __b - 1) / __b */ \
+ __m = (~0ULL / __b) * __p; \
+ __m += (((~0ULL % __b + 1) * __p) + __b - 1) / __b; \
+ /* compute __res = __m*(~0ULL/__b*__b-1)/(__p << 64) */ \
+ __x = ~0ULL / __b * __b - 1; \
+ __res = (__m & 0xffffffff) * (__x & 0xffffffff); \
+ __res >>= 32; \
+ __res += (__m & 0xffffffff) * (__x >> 32); \
+ __t = __res; \
+ __res += (__x & 0xffffffff) * (__m >> 32); \
+ __t = (__res < __t) ? (1ULL << 32) : 0; \
+ __res = (__res >> 32) + __t; \
+ __res += (__m >> 32) * (__x >> 32); \
+ __res /= __p; \
+ /* Now sanitize and optimize what we've got. */ \
+ if (~0ULL % (__b / (__b & -__b)) == 0) { \
+ /* those cases can be simplified with: */ \
+ __n /= (__b & -__b); \
+ __m = ~0ULL / (__b / (__b & -__b)); \
+ __p = 1; \
+ __c = 1; \
+ } else if (__res != __x / __b) { \
+ /* We can't get away without a correction */ \
+ /* to compensate for bit truncation errors. */ \
+ /* To avoid it we'd need an additional bit */ \
+ /* to represent __m which would overflow it. */ \
+ /* Instead we do m=p/b and n/b=(n*m+m)/p. */ \
+ __c = 1; \
+ /* Compute __m = (__p << 64) / __b */ \
+ __m = (~0ULL / __b) * __p; \
+ __m += ((~0ULL % __b + 1) * __p) / __b; \
+ } else { \
+ /* Reduce __m/__p, and try to clear bit 31 */ \
+ /* of __m when possible otherwise that'll */ \
+ /* need extra overflow handling later. */ \
+ unsigned int __bits = -(__m & -__m); \
+ __bits |= __m >> 32; \
+ __bits = (~__bits) << 1; \
+ /* If __bits == 0 then setting bit 31 is */ \
+ /* unavoidable. Simply apply the maximum */ \
+ /* possible reduction in that case. */ \
+ /* Otherwise the MSB of __bits indicates the */ \
+ /* best reduction we should apply. */ \
+ if (!__bits) { \
+ __p /= (__m & -__m); \
+ __m /= (__m & -__m); \
+ } else { \
+ __p >>= __div64_fls(__bits); \
+ __m >>= __div64_fls(__bits); \
+ } \
+ /* No correction needed. */ \
+ __c = 0; \
+ } \
+ /* Now we have a combination of 2 conditions: */ \
+ /* 1) whether or not we need a correction (__c), and */ \
+ /* 2) whether or not there might be an overflow in */ \
+ /* the cross product (__m & ((1<<63) | (1<<31))) */ \
+ /* Select the best insn combination to perform the */ \
+ /* actual __m * __n / (__p << 64) operation. */ \
+ if (!__c) { \
+ asm ( "umull %Q0, %R0, %1, %Q2\n\t" \
+ "mov %Q0, #0" \
+ : "=&r" (__res) \
+ : "r" (__m), "r" (__n) \
+ : "cc" ); \
+ } else if (!(__m & ((1ULL << 63) | (1ULL << 31)))) { \
+ __res = __m; \
+ asm ( "umlal %Q0, %R0, %Q1, %Q2\n\t" \
+ "mov %Q0, #0" \
+ : "+&r" (__res) \
+ : "r" (__m), "r" (__n) \
+ : "cc" ); \
+ } else { \
+ asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \
+ "cmn %Q0, %Q1\n\t" \
+ "adcs %R0, %R0, %R1\n\t" \
+ "adc %Q0, %3, #0" \
+ : "=&r" (__res) \
+ : "r" (__m), "r" (__n), "r" (__z) \
+ : "cc" ); \
+ } \
+ if (!(__m & ((1ULL << 63) | (1ULL << 31)))) { \
+ asm ( "umlal %R0, %Q0, %R1, %Q2\n\t" \
+ "umlal %R0, %Q0, %Q1, %R2\n\t" \
+ "mov %R0, #0\n\t" \
+ "umlal %Q0, %R0, %R1, %R2" \
+ : "+&r" (__res) \
+ : "r" (__m), "r" (__n) \
+ : "cc" ); \
+ } else { \
+ asm ( "umlal %R0, %Q0, %R2, %Q3\n\t" \
+ "umlal %R0, %1, %Q2, %R3\n\t" \
+ "mov %R0, #0\n\t" \
+ "adds %Q0, %1, %Q0\n\t" \
+ "adc %R0, %R0, #0\n\t" \
+ "umlal %Q0, %R0, %R2, %R3" \
+ : "+&r" (__res), "+&r" (__z) \
+ : "r" (__m), "r" (__n) \
+ : "cc" ); \
+ } \
+ __res /= __p; \
+ /* The reminder can be computed with 32-bit regs */ \
+ /* only, and gcc is good at that. */ \
+ { \
+ unsigned int __res0 = __res; \
+ unsigned int __b0 = __b; \
+ __r -= __res0 * __b0; \
+ } \
+ /* BUG_ON(__r >= __b || __res * __b + __r != n); */ \
+ n = __res; \
+ } \
+ __r; \
+})
+
+/* our own fls implementation to make sure constant propagation is fine */
+#define __div64_fls(bits) \
+({ \
+ unsigned int __left = (bits), __nr = 0; \
+ if (__left & 0xffff0000) __nr += 16, __left >>= 16; \
+ if (__left & 0x0000ff00) __nr += 8, __left >>= 8; \
+ if (__left & 0x000000f0) __nr += 4, __left >>= 4; \
+ if (__left & 0x0000000c) __nr += 2, __left >>= 2; \
+ if (__left & 0x00000002) __nr += 1; \
+ __nr; \
+})
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
new file mode 100644
index 00000000..5eaa7a2f
--- /dev/null
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -0,0 +1,568 @@
+#ifndef ASMARM_DMA_MAPPING_H
+#define ASMARM_DMA_MAPPING_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-debug.h>
+
+#include <asm-generic/dma-coherent.h>
+#include <asm/memory.h>
+
+#ifdef __arch_page_to_dma
+#error Please update to __arch_pfn_to_dma
+#endif
+
+/*
+ * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
+ * functions used internally by the DMA-mapping API to provide DMA
+ * addresses. They must not be used by drivers.
+ */
+#ifndef __arch_pfn_to_dma
+static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
+{
+ return (dma_addr_t)__pfn_to_bus(pfn);
+}
+
+static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
+{
+ return __bus_to_pfn(addr);
+}
+
+static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
+{
+ return (void *)__bus_to_virt(addr);
+}
+
+static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
+{
+ return (dma_addr_t)__virt_to_bus((unsigned long)(addr));
+}
+#else
+static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn)
+{
+ return __arch_pfn_to_dma(dev, pfn);
+}
+
+static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr)
+{
+ return __arch_dma_to_pfn(dev, addr);
+}
+
+static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
+{
+ return __arch_dma_to_virt(dev, addr);
+}
+
+static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
+{
+ return __arch_virt_to_dma(dev, addr);
+}
+#endif
+
+/*
+ * The DMA API is built upon the notion of "buffer ownership". A buffer
+ * is either exclusively owned by the CPU (and therefore may be accessed
+ * by it) or exclusively owned by the DMA device. These helper functions
+ * represent the transitions between these two ownership states.
+ *
+ * Note, however, that on later ARMs, this notion does not work due to
+ * speculative prefetches. We model our approach on the assumption that
+ * the CPU does do speculative prefetches, which means we clean caches
+ * before transfers and delay cache invalidation until transfer completion.
+ *
+ * Private support functions: these are not part of the API and are
+ * liable to change. Drivers must not use these.
+ */
+static inline void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ extern void ___dma_single_cpu_to_dev(const void *, size_t,
+ enum dma_data_direction);
+
+ if (!arch_is_coherent())
+ ___dma_single_cpu_to_dev(kaddr, size, dir);
+}
+
+static inline void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ extern void ___dma_single_dev_to_cpu(const void *, size_t,
+ enum dma_data_direction);
+
+ if (!arch_is_coherent())
+ ___dma_single_dev_to_cpu(kaddr, size, dir);
+}
+
+static inline void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ extern void ___dma_page_cpu_to_dev(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+
+ if (!arch_is_coherent())
+ ___dma_page_cpu_to_dev(page, off, size, dir);
+}
+
+static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ extern void ___dma_page_dev_to_cpu(struct page *, unsigned long,
+ size_t, enum dma_data_direction);
+
+ if (!arch_is_coherent())
+ ___dma_page_dev_to_cpu(page, off, size, dir);
+}
+
+/*
+ * Return whether the given device DMA address mask can be supported
+ * properly. For example, if your device can only drive the low 24-bits
+ * during bus mastering, then you would pass 0x00ffffff as the mask
+ * to this function.
+ *
+ * FIXME: This should really be a platform specific issue - we should
+ * return false if GFP_DMA allocations may not satisfy the supplied 'mask'.
+ */
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ if (mask < ISA_DMA_THRESHOLD)
+ return 0;
+ return 1;
+}
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+#ifdef CONFIG_DMABOUNCE
+ if (dev->archdata.dmabounce) {
+ if (dma_mask >= ISA_DMA_THRESHOLD)
+ return 0;
+ else
+ return -EIO;
+ }
+#endif
+ if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+ return -EIO;
+
+ *dev->dma_mask = dma_mask;
+
+ return 0;
+}
+
+/*
+ * DMA errors are defined by all-bits-set in the DMA address.
+ */
+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return dma_addr == ~0;
+}
+
+/*
+ * Dummy noncoherent implementation. We don't provide a dma_cache_sync
+ * function so drivers using this API are highlighted with build warnings.
+ */
+static inline void *dma_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t gfp)
+{
+ return NULL;
+}
+
+static inline void dma_free_noncoherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t handle)
+{
+}
+
+/**
+ * dma_alloc_noncached - allocate consistent memory for DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: required memory size
+ * @handle: bus-specific DMA address
+ *
+ * Allocate some uncached, unbuffered memory for a device for
+ * performing DMA. This function allocates pages, and will
+ * return the CPU-viewed address, and sets @handle to be the
+ * device-viewed address.
+ */
+extern void *dma_alloc_noncached(struct device *, size_t, dma_addr_t *, gfp_t);
+
+/**
+ * dma_alloc_coherent - allocate consistent memory for DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: required memory size
+ * @handle: bus-specific DMA address
+ *
+ * Allocate some uncached, unbuffered memory for a device for
+ * performing DMA. This function allocates pages, and will
+ * return the CPU-viewed address, and sets @handle to be the
+ * device-viewed address.
+ */
+extern void *dma_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t);
+
+/**
+ * dma_alloc_writethrough - allocate consistent memory for DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: required memory size
+ * @handle: bus-specific DMA address
+ *
+ * Allocate some writethrough cached, for a device for
+ * performing DMA. This function allocates pages, and will
+ * return the CPU-viewed address, and sets @handle to be the
+ * device-viewed address.
+ */
+extern void *dma_alloc_writethrough(struct device *, size_t, dma_addr_t *, gfp_t);
+
+/**
+ * dma_alloc_noncacheable - allocate consistent memory for DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: required memory size
+ * @handle: bus-specific DMA address
+ *
+ * Allocate some noncacheable memory, for a device for
+ * performing DMA. This function allocates pages, and will
+ * return the CPU-viewed address, and sets @handle to be the
+ * device-viewed address.
+ */
+extern void *dma_alloc_noncacheable(struct device *, size_t, dma_addr_t *, gfp_t);
+
+/**
+ * dma_free_coherent - free memory allocated by dma_alloc_coherent
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: size of memory originally requested in dma_alloc_coherent
+ * @cpu_addr: CPU-view address returned from dma_alloc_coherent
+ * @handle: device-view address returned from dma_alloc_coherent
+ *
+ * Free (and unmap) a DMA buffer previously allocated by
+ * dma_alloc_coherent().
+ *
+ * References to memory and mappings associated with cpu_addr/handle
+ * during and after this call executing are illegal.
+ */
+extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
+
+/**
+ * dma_mmap_coherent - map a coherent DMA allocation into user space
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @vma: vm_area_struct describing requested user mapping
+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent
+ * @handle: device-view address returned from dma_alloc_coherent
+ * @size: size of memory originally requested in dma_alloc_coherent
+ *
+ * Map a coherent DMA buffer previously allocated by dma_alloc_coherent
+ * into user space. The coherent DMA buffer must not be freed by the
+ * driver until the user space mapping has been released.
+ */
+int dma_mmap_coherent(struct device *, struct vm_area_struct *,
+ void *, dma_addr_t, size_t);
+
+
+/**
+ * dma_alloc_writecombine - allocate writecombining memory for DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @size: required memory size
+ * @handle: bus-specific DMA address
+ *
+ * Allocate some uncached, buffered memory for a device for
+ * performing DMA. This function allocates pages, and will
+ * return the CPU-viewed address, and sets @handle to be the
+ * device-viewed address.
+ */
+extern void *dma_alloc_writecombine(struct device *, size_t, dma_addr_t *,
+ gfp_t);
+
+#define dma_free_writecombine(dev,size,cpu_addr,handle) \
+ dma_free_coherent(dev,size,cpu_addr,handle)
+
+int dma_mmap_writecombine(struct device *, struct vm_area_struct *,
+ void *, dma_addr_t, size_t);
+
+
+#ifdef CONFIG_DMABOUNCE
+/*
+ * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
+ * and utilize bounce buffers as needed to work around limited DMA windows.
+ *
+ * On the SA-1111, a bug limits DMA to only certain regions of RAM.
+ * On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
+ *
+ * The following are helper functions used by the dmabounce subystem
+ *
+ */
+
+/**
+ * dmabounce_register_dev
+ *
+ * @dev: valid struct device pointer
+ * @small_buf_size: size of buffers to use with small buffer pool
+ * @large_buf_size: size of buffers to use with large buffer pool (can be 0)
+ *
+ * This function should be called by low-level platform code to register
+ * a device as requireing DMA buffer bouncing. The function will allocate
+ * appropriate DMA pools for the device.
+ *
+ */
+extern int dmabounce_register_dev(struct device *, unsigned long,
+ unsigned long);
+
+/**
+ * dmabounce_unregister_dev
+ *
+ * @dev: valid struct device pointer
+ *
+ * This function should be called by low-level platform code when device
+ * that was previously registered with dmabounce_register_dev is removed
+ * from the system.
+ *
+ */
+extern void dmabounce_unregister_dev(struct device *);
+
+/**
+ * dma_needs_bounce
+ *
+ * @dev: valid struct device pointer
+ * @dma_handle: dma_handle of unbounced buffer
+ * @size: size of region being mapped
+ *
+ * Platforms that utilize the dmabounce mechanism must implement
+ * this function.
+ *
+ * The dmabounce routines call this function whenever a dma-mapping
+ * is requested to determine whether a given buffer needs to be bounced
+ * or not. The function must return 0 if the buffer is OK for
+ * DMA access and 1 if the buffer needs to be bounced.
+ *
+ */
+extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
+
+/*
+ * The DMA API, implemented by dmabounce.c. See below for descriptions.
+ */
+extern dma_addr_t __dma_map_single(struct device *, void *, size_t,
+ enum dma_data_direction);
+extern void __dma_unmap_single(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern dma_addr_t __dma_map_page(struct device *, struct page *,
+ unsigned long, size_t, enum dma_data_direction);
+extern void __dma_unmap_page(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+
+/*
+ * Private functions
+ */
+int dmabounce_sync_for_cpu(struct device *, dma_addr_t, unsigned long,
+ size_t, enum dma_data_direction);
+int dmabounce_sync_for_device(struct device *, dma_addr_t, unsigned long,
+ size_t, enum dma_data_direction);
+#else
+static inline int dmabounce_sync_for_cpu(struct device *d, dma_addr_t addr,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ return 1;
+}
+
+static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ return 1;
+}
+
+
+static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_single_cpu_to_dev(cpu_addr, size, dir);
+ return virt_to_dma(dev, cpu_addr);
+}
+
+static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+ return pfn_to_dma(dev, page_to_pfn(page)) + offset;
+}
+
+static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
+}
+
+static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
+ handle & ~PAGE_MASK, size, dir);
+}
+#endif /* CONFIG_DMABOUNCE */
+
+/**
+ * dma_map_single - map a single buffer for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @cpu_addr: CPU direct mapped address of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed. The CPU
+ * can regain ownership by calling dma_unmap_single() or
+ * dma_sync_single_for_cpu().
+ */
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ dma_addr_t addr;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ addr = __dma_map_single(dev, cpu_addr, size, dir);
+ debug_dma_map_page(dev, virt_to_page(cpu_addr),
+ (unsigned long)cpu_addr & ~PAGE_MASK, size,
+ dir, addr, true);
+
+ return addr;
+}
+
+/**
+ * dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed. The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size, enum dma_data_direction dir)
+{
+ dma_addr_t addr;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ addr = __dma_map_page(dev, page, offset, size, dir);
+ debug_dma_map_page(dev, page, offset, size, dir, addr, false);
+
+ return addr;
+}
+
+/**
+ * dma_unmap_single - unmap a single buffer previously mapped
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_single)
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * Unmap a single streaming mode DMA translation. The handle and size
+ * must match what was provided in the previous dma_map_single() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ debug_dma_unmap_page(dev, handle, size, dir, true);
+ __dma_unmap_single(dev, handle, size, dir);
+}
+
+/**
+ * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation. The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ debug_dma_unmap_page(dev, handle, size, dir, false);
+ __dma_unmap_page(dev, handle, size, dir);
+}
+
+/**
+ * dma_sync_single_range_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @offset: offset of region to start sync
+ * @size: size of region to sync
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * Make physical memory consistent for a single streaming mode DMA
+ * translation after a transfer.
+ *
+ * If you perform a dma_map_single() but wish to interrogate the
+ * buffer using the cpu, yet do not wish to teardown the PCI dma
+ * mapping, you must call this function before doing so. At the
+ * next point you give the PCI dma address back to the card, you
+ * must first the perform a dma_sync_for_device, and then the
+ * device again owns the buffer.
+ */
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ debug_dma_sync_single_for_cpu(dev, handle + offset, size, dir);
+
+ if (!dmabounce_sync_for_cpu(dev, handle, offset, size, dir))
+ return;
+
+ __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ debug_dma_sync_single_for_device(dev, handle + offset, size, dir);
+
+ if (!dmabounce_sync_for_device(dev, handle, offset, size, dir))
+ return;
+
+ __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_cpu(dev, handle, 0, size, dir);
+}
+
+static inline void dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_device(dev, handle, 0, size, dir);
+}
+
+/*
+ * The scatter list versions of the above methods.
+ */
+extern int dma_map_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+extern void dma_unmap_sg(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+extern void dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
+ enum dma_data_direction);
+
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
new file mode 100644
index 00000000..42005542
--- /dev/null
+++ b/arch/arm/include/asm/dma.h
@@ -0,0 +1,151 @@
+#ifndef __ASM_ARM_DMA_H
+#define __ASM_ARM_DMA_H
+
+#include <asm/memory.h>
+
+/*
+ * This is the maximum virtual address which can be DMA'd from.
+ */
+#ifndef ARM_DMA_ZONE_SIZE
+#define MAX_DMA_ADDRESS 0xffffffff
+#else
+#define MAX_DMA_ADDRESS (PAGE_OFFSET + ARM_DMA_ZONE_SIZE)
+#endif
+
+#ifdef CONFIG_ISA_DMA_API
+/*
+ * This is used to support drivers written for the x86 ISA DMA API.
+ * It should not be re-used except for that purpose.
+ */
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/scatterlist.h>
+
+#include <mach/isa-dma.h>
+
+/*
+ * The DMA modes reflect the settings for the ISA DMA controller
+ */
+#define DMA_MODE_MASK 0xcc
+
+#define DMA_MODE_READ 0x44
+#define DMA_MODE_WRITE 0x48
+#define DMA_MODE_CASCADE 0xc0
+#define DMA_AUTOINIT 0x10
+
+extern spinlock_t dma_spin_lock;
+
+static inline unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static inline void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ */
+#define clear_dma_ff(chan)
+
+/* Set only the page register bits of the transfer address.
+ *
+ * NOTE: This is an architecture specific function, and should
+ * be hidden from the drivers
+ */
+extern void set_dma_page(unsigned int chan, char pagenr);
+
+/* Request a DMA channel
+ *
+ * Some architectures may need to do allocate an interrupt
+ */
+extern int request_dma(unsigned int chan, const char * device_id);
+
+/* Free a DMA channel
+ *
+ * Some architectures may need to do free an interrupt
+ */
+extern void free_dma(unsigned int chan);
+
+/* Enable DMA for this channel
+ *
+ * On some architectures, this may have other side effects like
+ * enabling an interrupt and setting the DMA registers.
+ */
+extern void enable_dma(unsigned int chan);
+
+/* Disable DMA for this channel
+ *
+ * On some architectures, this may have other side effects like
+ * disabling an interrupt or whatever.
+ */
+extern void disable_dma(unsigned int chan);
+
+/* Test whether the specified channel has an active DMA transfer
+ */
+extern int dma_channel_active(unsigned int chan);
+
+/* Set the DMA scatter gather list for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA address immediately, but defer it to the enable_dma().
+ */
+extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
+
+/* Set the DMA address for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA address immediately, but defer it to the enable_dma().
+ */
+extern void __set_dma_addr(unsigned int chan, void *addr);
+#define set_dma_addr(chan, addr) \
+ __set_dma_addr(chan, bus_to_virt(addr))
+
+/* Set the DMA byte count for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA count immediately, but defer it to the enable_dma().
+ */
+extern void set_dma_count(unsigned int chan, unsigned long count);
+
+/* Set the transfer direction for this channel
+ *
+ * This should not be called if a DMA channel is enabled,
+ * especially since some DMA architectures don't update the
+ * DMA transfer direction immediately, but defer it to the
+ * enable_dma().
+ */
+extern void set_dma_mode(unsigned int chan, unsigned int mode);
+
+/* Set the transfer speed for this channel
+ */
+extern void set_dma_speed(unsigned int chan, int cycle_ns);
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ */
+extern int get_dma_residue(unsigned int chan);
+
+#ifndef NO_DMA
+#define NO_DMA 255
+#endif
+
+#endif /* CONFIG_ISA_DMA_API */
+
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy (0)
+#endif
+
+#endif /* __ASM_ARM_DMA_H */
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
new file mode 100644
index 00000000..b5dc173d
--- /dev/null
+++ b/arch/arm/include/asm/domain.h
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/include/asm/domain.h
+ *
+ * Copyright (C) 1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_PROC_DOMAIN_H
+#define __ASM_PROC_DOMAIN_H
+
+/*
+ * Domain numbers
+ *
+ * DOMAIN_IO - domain 2 includes all IO only
+ * DOMAIN_USER - domain 1 includes all user memory only
+ * DOMAIN_KERNEL - domain 0 includes all kernel memory only
+ *
+ * The domain numbering depends on whether we support 36 physical
+ * address for I/O or not. Addresses above the 32 bit boundary can
+ * only be mapped using supersections and supersections can only
+ * be set for domain 0. We could just default to DOMAIN_IO as zero,
+ * but there may be systems with supersection support and no 36-bit
+ * addressing. In such cases, we want to map system memory with
+ * supersections to reduce TLB misses and footprint.
+ *
+ * 36-bit addressing and supersections are only available on
+ * CPUs based on ARMv6+ or the Intel XSC3 core.
+ */
+#ifndef CONFIG_IO_36
+#define DOMAIN_KERNEL 0
+#define DOMAIN_TABLE 0
+#define DOMAIN_USER 1
+#define DOMAIN_IO 2
+#else
+#define DOMAIN_KERNEL 2
+#define DOMAIN_TABLE 2
+#define DOMAIN_USER 1
+#define DOMAIN_IO 0
+#endif
+
+/*
+ * Domain types
+ */
+#define DOMAIN_NOACCESS 0
+#define DOMAIN_CLIENT 1
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define DOMAIN_MANAGER 3
+#else
+#define DOMAIN_MANAGER 1
+#endif
+
+#define domain_val(dom,type) ((type) << (2*(dom)))
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define set_domain(x) \
+ do { \
+ __asm__ __volatile__( \
+ "mcr p15, 0, %0, c3, c0 @ set domain" \
+ : : "r" (x)); \
+ isb(); \
+ } while (0)
+
+#define modify_domain(dom,type) \
+ do { \
+ struct thread_info *thread = current_thread_info(); \
+ unsigned int domain = thread->cpu_domain; \
+ domain &= ~domain_val(dom, DOMAIN_MANAGER); \
+ thread->cpu_domain = domain | domain_val(dom, type); \
+ set_domain(thread->cpu_domain); \
+ } while (0)
+
+#else
+#define set_domain(x) do { } while (0)
+#define modify_domain(dom,type) do { } while (0)
+#endif
+
+/*
+ * Generate the T (user) versions of the LDR/STR and related
+ * instructions (inline assembly)
+ */
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define TUSER(instr) #instr "t"
+#else
+#define TUSER(instr) #instr
+#endif
+
+#else /* __ASSEMBLY__ */
+
+/*
+ * Generate the T (user) versions of the LDR/STR and related
+ * instructions
+ */
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define TUSER(instr) instr ## t
+#else
+#define TUSER(instr) instr
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* !__ASM_PROC_DOMAIN_H */
diff --git a/arch/arm/include/asm/ecard.h b/arch/arm/include/asm/ecard.h
new file mode 100644
index 00000000..29f2610e
--- /dev/null
+++ b/arch/arm/include/asm/ecard.h
@@ -0,0 +1,219 @@
+/*
+ * arch/arm/include/asm/ecard.h
+ *
+ * definitions for expansion cards
+ *
+ * This is a new system as from Linux 1.2.3
+ *
+ * Changelog:
+ * 11-12-1996 RMK Further minor improvements
+ * 12-09-1997 RMK Added interrupt enable/disable for card level
+ *
+ * Reference: Acorns Risc OS 3 Programmers Reference Manuals.
+ */
+
+#ifndef __ASM_ECARD_H
+#define __ASM_ECARD_H
+
+/*
+ * Currently understood cards (but not necessarily
+ * supported):
+ * Manufacturer Product ID
+ */
+#define MANU_ACORN 0x0000
+#define PROD_ACORN_SCSI 0x0002
+#define PROD_ACORN_ETHER1 0x0003
+#define PROD_ACORN_MFM 0x000b
+
+#define MANU_ANT2 0x0011
+#define PROD_ANT_ETHER3 0x00a4
+
+#define MANU_ATOMWIDE 0x0017
+#define PROD_ATOMWIDE_3PSERIAL 0x0090
+
+#define MANU_IRLAM_INSTRUMENTS 0x001f
+#define MANU_IRLAM_INSTRUMENTS_ETHERN 0x5678
+
+#define MANU_OAK 0x0021
+#define PROD_OAK_SCSI 0x0058
+
+#define MANU_MORLEY 0x002b
+#define PROD_MORLEY_SCSI_UNCACHED 0x0067
+
+#define MANU_CUMANA 0x003a
+#define PROD_CUMANA_SCSI_2 0x003a
+#define PROD_CUMANA_SCSI_1 0x00a0
+
+#define MANU_ICS 0x003c
+#define PROD_ICS_IDE 0x00ae
+
+#define MANU_ICS2 0x003d
+#define PROD_ICS2_IDE 0x00ae
+
+#define MANU_SERPORT 0x003f
+#define PROD_SERPORT_DSPORT 0x00b9
+
+#define MANU_ARXE 0x0041
+#define PROD_ARXE_SCSI 0x00be
+
+#define MANU_I3 0x0046
+#define PROD_I3_ETHERLAN500 0x00d4
+#define PROD_I3_ETHERLAN600 0x00ec
+#define PROD_I3_ETHERLAN600A 0x011e
+
+#define MANU_ANT 0x0053
+#define PROD_ANT_ETHERM 0x00d8
+#define PROD_ANT_ETHERB 0x00e4
+
+#define MANU_ALSYSTEMS 0x005b
+#define PROD_ALSYS_SCSIATAPI 0x0107
+
+#define MANU_MCS 0x0063
+#define PROD_MCS_CONNECT32 0x0125
+
+#define MANU_EESOX 0x0064
+#define PROD_EESOX_SCSI2 0x008c
+
+#define MANU_YELLOWSTONE 0x0096
+#define PROD_YELLOWSTONE_RAPIDE32 0x0120
+
+#ifdef ECARD_C
+#define CONST
+#else
+#define CONST const
+#endif
+
+#define MAX_ECARDS 9
+
+struct ecard_id { /* Card ID structure */
+ unsigned short manufacturer;
+ unsigned short product;
+ void *data;
+};
+
+struct in_ecid { /* Packed card ID information */
+ unsigned short product; /* Product code */
+ unsigned short manufacturer; /* Manufacturer code */
+ unsigned char id:4; /* Simple ID */
+ unsigned char cd:1; /* Chunk dir present */
+ unsigned char is:1; /* Interrupt status pointers */
+ unsigned char w:2; /* Width */
+ unsigned char country; /* Country */
+ unsigned char irqmask; /* IRQ mask */
+ unsigned char fiqmask; /* FIQ mask */
+ unsigned long irqoff; /* IRQ offset */
+ unsigned long fiqoff; /* FIQ offset */
+};
+
+typedef struct expansion_card ecard_t;
+typedef unsigned long *loader_t;
+
+typedef struct expansion_card_ops { /* Card handler routines */
+ void (*irqenable)(ecard_t *ec, int irqnr);
+ void (*irqdisable)(ecard_t *ec, int irqnr);
+ int (*irqpending)(ecard_t *ec);
+ void (*fiqenable)(ecard_t *ec, int fiqnr);
+ void (*fiqdisable)(ecard_t *ec, int fiqnr);
+ int (*fiqpending)(ecard_t *ec);
+} expansioncard_ops_t;
+
+#define ECARD_NUM_RESOURCES (6)
+
+#define ECARD_RES_IOCSLOW (0)
+#define ECARD_RES_IOCMEDIUM (1)
+#define ECARD_RES_IOCFAST (2)
+#define ECARD_RES_IOCSYNC (3)
+#define ECARD_RES_MEMC (4)
+#define ECARD_RES_EASI (5)
+
+#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start)
+#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end)
+#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \
+ (ec)->resource[nr].start + 1)
+#define ecard_resource_flags(ec,nr) ((ec)->resource[nr].flags)
+
+/*
+ * This contains all the info needed on an expansion card
+ */
+struct expansion_card {
+ struct expansion_card *next;
+
+ struct device dev;
+ struct resource resource[ECARD_NUM_RESOURCES];
+
+ /* Public data */
+ void __iomem *irqaddr; /* address of IRQ register */
+ void __iomem *fiqaddr; /* address of FIQ register */
+ unsigned char irqmask; /* IRQ mask */
+ unsigned char fiqmask; /* FIQ mask */
+ unsigned char claimed; /* Card claimed? */
+ unsigned char easi; /* EASI card */
+
+ void *irq_data; /* Data for use for IRQ by card */
+ void *fiq_data; /* Data for use for FIQ by card */
+ const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
+
+ CONST unsigned int slot_no; /* Slot number */
+ CONST unsigned int dma; /* DMA number (for request_dma) */
+ CONST unsigned int irq; /* IRQ number (for request_irq) */
+ CONST unsigned int fiq; /* FIQ number (for request_irq) */
+ CONST struct in_ecid cid; /* Card Identification */
+
+ /* Private internal data */
+ const char *card_desc; /* Card description */
+ CONST unsigned int podaddr; /* Base Linux address for card */
+ CONST loader_t loader; /* loader program */
+ u64 dma_mask;
+};
+
+void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);
+
+struct in_chunk_dir {
+ unsigned int start_offset;
+ union {
+ unsigned char string[256];
+ unsigned char data[1];
+ } d;
+};
+
+/*
+ * Read a chunk from an expansion card
+ * cd : where to put read data
+ * ec : expansion card info struct
+ * id : id number to find
+ * num: (n+1)'th id to find.
+ */
+extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
+
+/*
+ * Request and release ecard resources
+ */
+extern int ecard_request_resources(struct expansion_card *ec);
+extern void ecard_release_resources(struct expansion_card *ec);
+
+void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
+ unsigned long offset, unsigned long maxsize);
+#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr)
+
+extern struct bus_type ecard_bus_type;
+
+#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
+
+struct ecard_driver {
+ int (*probe)(struct expansion_card *, const struct ecard_id *id);
+ void (*remove)(struct expansion_card *);
+ void (*shutdown)(struct expansion_card *);
+ const struct ecard_id *id_table;
+ unsigned int id;
+ struct device_driver drv;
+};
+
+#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv)
+
+#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data))
+#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev)
+
+int ecard_register_driver(struct ecard_driver *);
+void ecard_remove_driver(struct ecard_driver *);
+
+#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
new file mode 100644
index 00000000..0e9ce8d9
--- /dev/null
+++ b/arch/arm/include/asm/elf.h
@@ -0,0 +1,137 @@
+#ifndef __ASMARM_ELF_H
+#define __ASMARM_ELF_H
+
+#include <asm/hwcap.h>
+
+/*
+ * ELF register definitions..
+ */
+#include <asm/ptrace.h>
+#include <asm/user.h>
+
+struct task_struct;
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fp elf_fpregset_t;
+
+#define EM_ARM 40
+
+#define EF_ARM_EABI_MASK 0xff000000
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+#define EF_ARM_BE8 0x00800000 /* ABI 4,5 */
+#define EF_ARM_LE8 0x00400000 /* ABI 4,5 */
+#define EF_ARM_MAVERICK_FLOAT 0x00000800 /* ABI 0 */
+#define EF_ARM_VFP_FLOAT 0x00000400 /* ABI 0 */
+#define EF_ARM_SOFT_FLOAT 0x00000200 /* ABI 0 */
+#define EF_ARM_OLD_ABI 0x00000100 /* ABI 0 */
+#define EF_ARM_NEW_ABI 0x00000080 /* ABI 0 */
+#define EF_ARM_ALIGN8 0x00000040 /* ABI 0 */
+#define EF_ARM_PIC 0x00000020 /* ABI 0 */
+#define EF_ARM_MAPSYMSFIRST 0x00000010 /* ABI 2 */
+#define EF_ARM_APCS_FLOAT 0x00000010 /* ABI 0, floats in fp regs */
+#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ABI 2 */
+#define EF_ARM_APCS_26 0x00000008 /* ABI 0 */
+#define EF_ARM_SYMSARESORTED 0x00000004 /* ABI 1,2 */
+#define EF_ARM_INTERWORK 0x00000004 /* ABI 0 */
+#define EF_ARM_HASENTRY 0x00000002 /* All */
+#define EF_ARM_RELEXEC 0x00000001 /* All */
+
+#define R_ARM_NONE 0
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+#define R_ARM_V4BX 40
+#define R_ARM_PREL31 42
+#define R_ARM_MOVW_ABS_NC 43
+#define R_ARM_MOVT_ABS 44
+
+#define R_ARM_THM_CALL 10
+#define R_ARM_THM_JUMP24 30
+#define R_ARM_THM_MOVW_ABS_NC 47
+#define R_ARM_THM_MOVT_ABS 48
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS ELFCLASS32
+#ifdef __ARMEB__
+#define ELF_DATA ELFDATA2MSB
+#else
+#define ELF_DATA ELFDATA2LSB
+#endif
+#define ELF_ARCH EM_ARM
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization. This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ *
+ * For now we just provide a fairly general string that describes the
+ * processor family. This could be made more specific later if someone
+ * implemented optimisations that require it. 26-bit CPUs give you
+ * "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
+ * supported). 32-bit CPUs give you "v3[lb]" for anything based on an
+ * ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1
+ * core.
+ */
+#define ELF_PLATFORM_SIZE 8
+#define ELF_PLATFORM (elf_platform)
+
+extern char elf_platform[];
+
+struct elf32_hdr;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+extern int elf_check_arch(const struct elf32_hdr *);
+#define elf_check_arch elf_check_arch
+
+#define vmcore_elf64_check_arch(x) (0)
+
+extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
+#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(&(ex), stk)
+
+struct task_struct;
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
+#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+
+#define CORE_DUMP_USE_REGSET
+#define ELF_EXEC_PAGESIZE 4096
+
+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ use of this is to invoke "./ld.so someprog" to test out a new version of
+ the loader. We need to make sure that it is out of the way of the program
+ that it will "exec", and that there is sufficient room for the brk. */
+
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+
+/* When the program starts, a1 contains a pointer to a function to be
+ registered with atexit, as per the SVR4 ABI. A value of 0 means we
+ have no such handler. */
+#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
+
+extern void elf_set_personality(const struct elf32_hdr *);
+#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
+
+struct mm_struct;
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
+extern int vectors_user_mapping(void);
+#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+
+#endif
diff --git a/arch/arm/include/asm/emergency-restart.h b/arch/arm/include/asm/emergency-restart.h
new file mode 100644
index 00000000..108d8c48
--- /dev/null
+++ b/arch/arm/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
new file mode 100644
index 00000000..2da8547d
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -0,0 +1,46 @@
+#include <asm/assembler.h>
+
+/*
+ * Interrupt handling. Preserves r7, r8, r9
+ */
+ .macro arch_irq_handler_default
+ get_irqnr_preamble r5, lr
+1: get_irqnr_and_base r0, r6, r5, lr
+ movne r1, sp
+ @
+ @ routine called with r0 = irq number, r1 = struct pt_regs *
+ @
+ adrne lr, BSYM(1b)
+ bne asm_do_IRQ
+
+#ifdef CONFIG_SMP
+ /*
+ * XXX
+ *
+ * this macro assumes that irqstat (r6) and base (r5) are
+ * preserved from get_irqnr_and_base above
+ */
+ ALT_SMP(test_for_ipi r0, r6, r5, lr)
+ ALT_UP_B(9997f)
+ movne r1, sp
+ adrne lr, BSYM(1b)
+ bne do_IPI
+
+#ifdef CONFIG_LOCAL_TIMERS
+ test_for_ltirq r0, r6, r5, lr
+ movne r0, sp
+ adrne lr, BSYM(1b)
+ bne do_local_timer
+#endif
+#endif
+9997:
+ .endm
+
+ .macro arch_irq_handler, symbol_name
+ .align 5
+ .global \symbol_name
+\symbol_name:
+ mov r4, lr
+ arch_irq_handler_default
+ mov pc, r4
+ .endm
diff --git a/arch/arm/include/asm/entry-macro-vic2.S b/arch/arm/include/asm/entry-macro-vic2.S
new file mode 100644
index 00000000..3ceb85e4
--- /dev/null
+++ b/arch/arm/include/asm/entry-macro-vic2.S
@@ -0,0 +1,57 @@
+/* arch/arm/include/asm/entry-macro-vic2.S
+ *
+ * Originally arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for a device with two VICs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+/* This should be included from <mach/entry-macro.S> with the necessary
+ * defines for virtual addresses and IRQ bases for the two vics.
+ *
+ * The code needs the following defined:
+ * IRQ_VIC0_BASE IRQ number of VIC0's first IRQ
+ * IRQ_VIC1_BASE IRQ number of VIC1's first IRQ
+ * VA_VIC0 Virtual address of VIC0
+ * VA_VIC1 Virtual address of VIC1
+ *
+ * Note, code assumes VIC0's virtual address is an ARM immediate constant
+ * away from VIC1.
+*/
+
+#include <asm/hardware/vic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, #IRQ_VIC0_BASE + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #(IRQ_VIC1_BASE - IRQ_VIC0_BASE)
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/include/asm/errno.h b/arch/arm/include/asm/errno.h
new file mode 100644
index 00000000..6e60f061
--- /dev/null
+++ b/arch/arm/include/asm/errno.h
@@ -0,0 +1,6 @@
+#ifndef _ARM_ERRNO_H
+#define _ARM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif
diff --git a/arch/arm/include/asm/fb.h b/arch/arm/include/asm/fb.h
new file mode 100644
index 00000000..d92e99cd
--- /dev/null
+++ b/arch/arm/include/asm/fb.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_FB_H_
+#define _ASM_FB_H_
+
+#include <linux/fb.h>
+#include <linux/fs.h>
+#include <asm/page.h>
+
+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
+ unsigned long off)
+{
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+}
+
+static inline int fb_is_primary_device(struct fb_info *info)
+{
+ return 0;
+}
+
+#endif /* _ASM_FB_H_ */
diff --git a/arch/arm/include/asm/fcntl.h b/arch/arm/include/asm/fcntl.h
new file mode 100644
index 00000000..a80b6607
--- /dev/null
+++ b/arch/arm/include/asm/fcntl.h
@@ -0,0 +1,11 @@
+#ifndef _ARM_FCNTL_H
+#define _ARM_FCNTL_H
+
+#define O_DIRECTORY 040000 /* must be a directory */
+#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE 0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif
diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h
new file mode 100644
index 00000000..d493d0b7
--- /dev/null
+++ b/arch/arm/include/asm/fiq.h
@@ -0,0 +1,56 @@
+/*
+ * arch/arm/include/asm/fiq.h
+ *
+ * Support for FIQ on ARM architectures.
+ * Written by Philip Blundell <philb@gnu.org>, 1998
+ * Re-written by Russell King
+ *
+ * NOTE: The FIQ mode registers are not magically preserved across
+ * suspend/resume.
+ *
+ * Drivers which require these registers to be preserved across power
+ * management operations must implement appropriate suspend/resume handlers to
+ * save and restore them.
+ */
+
+#ifndef __ASM_FIQ_H
+#define __ASM_FIQ_H
+
+#include <asm/ptrace.h>
+
+struct fiq_handler {
+ struct fiq_handler *next;
+ /* Name
+ */
+ const char *name;
+ /* Called to ask driver to relinquish/
+ * reacquire FIQ
+ * return zero to accept, or -<errno>
+ */
+ int (*fiq_op)(void *, int relinquish);
+ /* data for the relinquish/reacquire functions
+ */
+ void *dev_id;
+};
+
+extern int claim_fiq(struct fiq_handler *f);
+extern void release_fiq(struct fiq_handler *f);
+extern void set_fiq_handler(void *start, unsigned int length);
+extern void enable_fiq(int fiq);
+extern void disable_fiq(int fiq);
+
+/* helpers defined in fiqasm.S: */
+extern void __set_fiq_regs(unsigned long const *regs);
+extern void __get_fiq_regs(unsigned long *regs);
+
+static inline void set_fiq_regs(struct pt_regs const *regs)
+{
+ __set_fiq_regs(&regs->ARM_r8);
+}
+
+static inline void get_fiq_regs(struct pt_regs *regs)
+{
+ __get_fiq_regs(&regs->ARM_r8);
+}
+
+#endif
diff --git a/arch/arm/include/asm/fiq_debugger.h b/arch/arm/include/asm/fiq_debugger.h
new file mode 100644
index 00000000..4d274883
--- /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 00000000..d54c29db
--- /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/fixmap.h b/arch/arm/include/asm/fixmap.h
new file mode 100644
index 00000000..bbae919b
--- /dev/null
+++ b/arch/arm/include/asm/fixmap.h
@@ -0,0 +1,41 @@
+#ifndef _ASM_FIXMAP_H
+#define _ASM_FIXMAP_H
+
+/*
+ * Nothing too fancy for now.
+ *
+ * On ARM we already have well known fixed virtual addresses imposed by
+ * the architecture such as the vector page which is located at 0xffff0000,
+ * therefore a second level page table is already allocated covering
+ * 0xfff00000 upwards.
+ *
+ * The cache flushing code in proc-xscale.S uses the virtual area between
+ * 0xfffe0000 and 0xfffeffff.
+ */
+
+#define FIXADDR_START 0xfff00000UL
+#define FIXADDR_TOP 0xfffe0000UL
+#define FIXADDR_SIZE (FIXADDR_TOP - FIXADDR_START)
+
+#define FIX_KMAP_BEGIN 0
+#define FIX_KMAP_END (FIXADDR_SIZE >> PAGE_SHIFT)
+
+#define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+ if (idx >= FIX_KMAP_END)
+ __this_fixmap_does_not_exist();
+ return __fix_to_virt(idx);
+}
+
+static inline unsigned int virt_to_fix(const unsigned long vaddr)
+{
+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+ return __virt_to_fix(vaddr);
+}
+
+#endif
diff --git a/arch/arm/include/asm/flat.h b/arch/arm/include/asm/flat.h
new file mode 100644
index 00000000..59426a45
--- /dev/null
+++ b/arch/arm/include/asm/flat.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/include/asm/flat.h -- uClinux flat-format executables
+ */
+
+#ifndef __ARM_FLAT_H__
+#define __ARM_FLAT_H__
+
+#define flat_argvp_envp_on_stack() 1
+#define flat_old_ram_flag(flags) (flags)
+#define flat_reloc_valid(reloc, size) ((reloc) <= (size))
+#define flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp)
+#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
+#define flat_get_relocate_addr(rel) (rel)
+#define flat_set_persistent(relval, p) 0
+
+#endif /* __ARM_FLAT_H__ */
diff --git a/arch/arm/include/asm/floppy.h b/arch/arm/include/asm/floppy.h
new file mode 100644
index 00000000..c9f03ecc
--- /dev/null
+++ b/arch/arm/include/asm/floppy.h
@@ -0,0 +1,148 @@
+/*
+ * arch/arm/include/asm/floppy.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
+ */
+#ifndef __ASM_ARM_FLOPPY_H
+#define __ASM_ARM_FLOPPY_H
+#if 0
+#include <mach/floppy.h>
+#endif
+
+#define fd_outb(val,port) \
+ do { \
+ if ((port) == FD_DOR) \
+ fd_setdor((val)); \
+ else \
+ outb((val),(port)); \
+ } while(0)
+
+#define fd_inb(port) inb((port))
+#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
+ IRQF_DISABLED,"floppy",NULL)
+#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
+#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK)
+#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK)
+
+static inline int fd_dma_setup(void *data, unsigned int length,
+ unsigned int mode, unsigned long addr)
+{
+ set_dma_mode(DMA_FLOPPY, mode);
+ __set_dma_addr(DMA_FLOPPY, data);
+ set_dma_count(DMA_FLOPPY, length);
+ virtual_dma_port = addr;
+ enable_dma(DMA_FLOPPY);
+ return 0;
+}
+#define fd_dma_setup fd_dma_setup
+
+#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy")
+#define fd_free_dma() free_dma(DMA_FLOPPY)
+#define fd_disable_dma() disable_dma(DMA_FLOPPY)
+
+/* need to clean up dma.h */
+#define DMA_FLOPPYDISK DMA_FLOPPY
+
+/* Floppy_selects is the list of DOR's to select drive fd
+ *
+ * On initialisation, the floppy list is scanned, and the drives allocated
+ * in the order that they are found. This is done by seeking the drive
+ * to a non-zero track, and then restoring it to track 0. If an error occurs,
+ * then there is no floppy drive present. [to be put back in again]
+ */
+static unsigned char floppy_selects[2][4] =
+{
+ { 0x10, 0x21, 0x23, 0x33 },
+ { 0x10, 0x21, 0x23, 0x33 }
+};
+
+#define fd_setdor(dor) \
+do { \
+ int new_dor = (dor); \
+ if (new_dor & 0xf0) \
+ new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \
+ else \
+ new_dor &= 0x0c; \
+ outb(new_dor, FD_DOR); \
+} while (0)
+
+/*
+ * Someday, we'll automatically detect which drives are present...
+ */
+static inline void fd_scandrives (void)
+{
+#if 0
+ int floppy, drive_count;
+
+ fd_disable_irq();
+ raw_cmd = &default_raw_cmd;
+ raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK;
+ raw_cmd->track = 0;
+ raw_cmd->rate = ?;
+ drive_count = 0;
+ for (floppy = 0; floppy < 4; floppy ++) {
+ current_drive = drive_count;
+ /*
+ * Turn on floppy motor
+ */
+ if (start_motor(redo_fd_request))
+ continue;
+ /*
+ * Set up FDC
+ */
+ fdc_specify();
+ /*
+ * Tell FDC to recalibrate
+ */
+ output_byte(FD_RECALIBRATE);
+ LAST_OUT(UNIT(floppy));
+ /* wait for command to complete */
+ if (!successful) {
+ int i;
+ for (i = drive_count; i < 3; i--)
+ floppy_selects[fdc][i] = floppy_selects[fdc][i + 1];
+ floppy_selects[fdc][3] = 0;
+ floppy -= 1;
+ } else
+ drive_count++;
+ }
+#else
+ floppy_selects[0][0] = 0x10;
+ floppy_selects[0][1] = 0x21;
+ floppy_selects[0][2] = 0x23;
+ floppy_selects[0][3] = 0x33;
+#endif
+}
+
+#define FDC1 (0x3f0)
+
+#define FLOPPY0_TYPE 4
+#define FLOPPY1_TYPE 4
+
+#define N_FDC 1
+#define N_DRIVE 4
+
+#define CROSS_64KB(a,s) (0)
+
+/*
+ * This allows people to reverse the order of
+ * fd0 and fd1, in case their hardware is
+ * strangely connected (as some RiscPCs
+ * and A5000s seem to be).
+ */
+static void driveswap(int *ints, int dummy, int dummy2)
+{
+ floppy_selects[0][0] ^= floppy_selects[0][1];
+ floppy_selects[0][1] ^= floppy_selects[0][0];
+ floppy_selects[0][0] ^= floppy_selects[0][1];
+}
+
+#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
+
+#endif
diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 00000000..de535474
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ * NOTE: in order for embedded literals and data to get referenced correctly,
+ * the alignment of functions must be preserved when copying. To ensure this,
+ * the source and destination addresses for fncpy() must be aligned to a
+ * multiple of 8 bytes: you will be get a BUG() if this condition is not met.
+ * You will typically need a ".align 3" directive in the assembler where the
+ * function to be copied is defined, and ensure that your allocator for the
+ * destination buffer returns 8-byte-aligned pointers.
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Minimum alignment requirement for the source and destination addresses
+ * for function copying.
+ */
+#define FNCPY_ALIGN 8
+
+#define fncpy(dest_buf, funcp, size) ({ \
+ uintptr_t __funcp_address; \
+ typeof(funcp) __result; \
+ \
+ asm("" : "=r" (__funcp_address) : "0" (funcp)); \
+ \
+ /* \
+ * Ensure alignment of source and destination addresses, \
+ * disregarding the function's Thumb bit: \
+ */ \
+ BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
+ (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+ \
+ memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
+ flush_icache_range((unsigned long)(dest_buf), \
+ (unsigned long)(dest_buf) + (size)); \
+ \
+ asm("" : "=r" (__result) \
+ : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
+ \
+ __result; \
+})
+
+#endif /* !__ASM_FNCPY_H */
diff --git a/arch/arm/include/asm/fpstate.h b/arch/arm/include/asm/fpstate.h
new file mode 100644
index 00000000..3ad4c10d
--- /dev/null
+++ b/arch/arm/include/asm/fpstate.h
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/include/asm/fpstate.h
+ *
+ * Copyright (C) 1995 Russell King
+ *
+ * This program is free software; you can 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_FPSTATE_H
+#define __ASM_ARM_FPSTATE_H
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * VFP storage area has:
+ * - FPEXC, FPSCR, FPINST and FPINST2.
+ * - 16 or 32 double precision data registers
+ * - an implementation-dependent word of state for FLDMX/FSTMX (pre-ARMv6)
+ *
+ * FPEXC will always be non-zero once the VFP has been used in this process.
+ */
+
+struct vfp_hard_struct {
+#ifdef CONFIG_VFPv3
+ __u64 fpregs[32];
+#else
+ __u64 fpregs[16];
+#endif
+#if __LINUX_ARM_ARCH__ < 6
+ __u32 fpmx_state;
+#endif
+ __u32 fpexc;
+ __u32 fpscr;
+ /*
+ * VFP implementation specific state
+ */
+ __u32 fpinst;
+ __u32 fpinst2;
+
+#ifdef CONFIG_SMP
+ __u32 cpu;
+#endif
+};
+
+union vfp_state {
+ struct vfp_hard_struct hard;
+};
+
+extern void vfp_flush_thread(union vfp_state *);
+extern void vfp_release_thread(union vfp_state *);
+
+#define FP_HARD_SIZE 35
+
+struct fp_hard_struct {
+ unsigned int save[FP_HARD_SIZE]; /* as yet undefined */
+};
+
+#define FP_SOFT_SIZE 35
+
+struct fp_soft_struct {
+ unsigned int save[FP_SOFT_SIZE]; /* undefined information */
+};
+
+#define IWMMXT_SIZE 0x98
+
+struct iwmmxt_struct {
+ unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)];
+};
+
+union fp_state {
+ struct fp_hard_struct hard;
+ struct fp_soft_struct soft;
+#ifdef CONFIG_IWMMXT
+ struct iwmmxt_struct iwmmxt;
+#endif
+};
+
+#define FP_SIZE (sizeof(union fp_state) / sizeof(int))
+
+struct crunch_state {
+ unsigned int mvdx[16][2];
+ unsigned int mvax[4][3];
+ unsigned int dspsc[2];
+};
+
+#define CRUNCH_SIZE sizeof(struct crunch_state)
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
new file mode 100644
index 00000000..f89515ad
--- /dev/null
+++ b/arch/arm/include/asm/ftrace.h
@@ -0,0 +1,67 @@
+#ifndef _ASM_ARM_FTRACE
+#define _ASM_ARM_FTRACE
+
+#ifdef CONFIG_FUNCTION_TRACER
+#define MCOUNT_ADDR ((unsigned long)(__gnu_mcount_nc))
+#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+extern void __gnu_mcount_nc(void);
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+struct dyn_arch_ftrace {
+#ifdef CONFIG_OLD_MCOUNT
+ bool old_mcount;
+#endif
+};
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+ /* With Thumb-2, the recorded addresses have the lsb set */
+ return addr & ~1;
+}
+
+extern void ftrace_caller_old(void);
+extern void ftrace_call_old(void);
+#endif
+
+#endif
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+/*
+ * return_address uses walk_stackframe to do it's work. If both
+ * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
+ * information. For this to work in the function tracer many functions would
+ * have to be marked with __notrace. So for now just depend on
+ * !CONFIG_ARM_UNWIND.
+ */
+
+void *return_address(unsigned int);
+
+#else
+
+extern inline void *return_address(unsigned int level)
+{
+ return NULL;
+}
+
+#endif
+
+#define HAVE_ARCH_CALLER_ADDR
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)return_address(1))
+#define CALLER_ADDR2 ((unsigned long)return_address(2))
+#define CALLER_ADDR3 ((unsigned long)return_address(3))
+#define CALLER_ADDR4 ((unsigned long)return_address(4))
+#define CALLER_ADDR5 ((unsigned long)return_address(5))
+#define CALLER_ADDR6 ((unsigned long)return_address(6))
+
+#endif /* ifndef __ASSEMBLY__ */
+
+#endif /* _ASM_ARM_FTRACE */
diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h
new file mode 100644
index 00000000..7be54690
--- /dev/null
+++ b/arch/arm/include/asm/futex.h
@@ -0,0 +1,168 @@
+#ifndef _ASM_ARM_FUTEX_H
+#define _ASM_ARM_FUTEX_H
+
+#ifdef __KERNEL__
+
+#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP)
+/* ARM doesn't provide unprivileged exclusive memory accessors */
+#include <asm-generic/futex.h>
+#else
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+#define __futex_atomic_ex_table(err_reg) \
+ "3:\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 4f, 2b, 4f\n" \
+ " .popsection\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ "4: mov %0, " err_reg "\n" \
+ " b 3b\n" \
+ " .popsection"
+
+#ifdef CONFIG_SMP
+
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "1: ldrex %1, [%3]\n" \
+ " " insn "\n" \
+ "2: strex %2, %0, [%3]\n" \
+ " teq %2, #0\n" \
+ " bne 1b\n" \
+ " mov %0, #0\n" \
+ __futex_atomic_ex_table("%5") \
+ : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
+ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
+ : "cc", "memory")
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ int ret;
+ u32 val;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ smp_mb();
+ __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ "1: ldrex %1, [%4]\n"
+ " teq %1, %2\n"
+ " ite eq @ explicit IT needed for the 2b label\n"
+ "2: strexeq %0, %3, [%4]\n"
+ " movne %0, #0\n"
+ " teq %0, #0\n"
+ " bne 1b\n"
+ __futex_atomic_ex_table("%5")
+ : "=&r" (ret), "=&r" (val)
+ : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+ : "cc", "memory");
+ smp_mb();
+
+ *uval = val;
+ return ret;
+}
+
+#else /* !SMP, we can work around lack of atomic ops by disabling preemption */
+
+#include <linux/preempt.h>
+#include <asm/domain.h>
+
+#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
+ __asm__ __volatile__( \
+ "1: " TUSER(ldr) " %1, [%3]\n" \
+ " " insn "\n" \
+ "2: " TUSER(str) " %0, [%3]\n" \
+ " mov %0, #0\n" \
+ __futex_atomic_ex_table("%5") \
+ : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
+ : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
+ : "cc", "memory")
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ u32 oldval, u32 newval)
+{
+ int ret = 0;
+ u32 val;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+ "1: " TUSER(ldr) " %1, [%4]\n"
+ " teq %1, %2\n"
+ " it eq @ explicit IT needed for the 2b label\n"
+ "2: " TUSER(streq) " %3, [%4]\n"
+ __futex_atomic_ex_table("%5")
+ : "+r" (ret), "=&r" (val)
+ : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+ : "cc", "memory");
+
+ *uval = val;
+ return ret;
+}
+
+#endif /* !SMP */
+
+static inline int
+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
+{
+ int op = (encoded_op >> 28) & 7;
+ int cmp = (encoded_op >> 24) & 15;
+ int oparg = (encoded_op << 8) >> 20;
+ int cmparg = (encoded_op << 20) >> 20;
+ int oldval = 0, ret, tmp;
+
+ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+ oparg = 1 << oparg;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+ return -EFAULT;
+
+ pagefault_disable(); /* implies preempt_disable() */
+
+ switch (op) {
+ case FUTEX_OP_SET:
+ __futex_atomic_op("mov %0, %4", ret, oldval, tmp, uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+ __futex_atomic_op("add %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ __futex_atomic_op("orr %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ __futex_atomic_op("and %0, %1, %4", ret, oldval, tmp, uaddr, ~oparg);
+ break;
+ case FUTEX_OP_XOR:
+ __futex_atomic_op("eor %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ pagefault_enable(); /* subsumes preempt_enable() */
+
+ if (!ret) {
+ switch (cmp) {
+ case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+ case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+ case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+ case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+ case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+ case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+ default: ret = -ENOSYS;
+ }
+ }
+ return ret;
+}
+
+#endif /* !(CPU_USE_DOMAINS && SMP) */
+#endif /* __KERNEL__ */
+#endif /* _ASM_ARM_FUTEX_H */
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
new file mode 100644
index 00000000..7e308743
--- /dev/null
+++ b/arch/arm/include/asm/glue-cache.h
@@ -0,0 +1,146 @@
+/*
+ * arch/arm/include/asm/glue-cache.h
+ *
+ * Copyright (C) 1999-2002 Russell King
+ *
+ * This program is free software; you can 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_GLUE_CACHE_H
+#define ASM_GLUE_CACHE_H
+
+#include <asm/glue.h>
+
+/*
+ * Cache Model
+ * ===========
+ */
+#undef _CACHE
+#undef MULTI_CACHE
+
+#if defined(CONFIG_CPU_CACHE_V3)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
+ defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
+ defined(CONFIG_CPU_ARM1026)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_FA526)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE fa
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM926T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm926
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM940T)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm940
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM946E)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE arm946
+# endif
+#endif
+
+#if defined(CONFIG_CPU_CACHE_V4WB)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE v4wb
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSCALE)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE xscale
+# endif
+#endif
+
+#if defined(CONFIG_CPU_XSC3)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE xsc3
+# endif
+#endif
+
+#if defined(CONFIG_CPU_MOHAWK)
+# ifdef _CACHE
+# define MULTI_CACHE 1
+# else
+# define _CACHE mohawk
+# endif
+#endif
+
+#if defined(CONFIG_CPU_FEROCEON)
+# define MULTI_CACHE 1
+#endif
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+//# ifdef _CACHE
+# define MULTI_CACHE 1
+//# else
+//# define _CACHE v6
+//# endif
+#endif
+
+#if defined(CONFIG_CPU_V7)
+//# ifdef _CACHE
+# define MULTI_CACHE 1
+//# else
+//# define _CACHE v7
+//# endif
+#endif
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintenance model
+#endif
+
+#ifndef MULTI_CACHE
+#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
+#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
+#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
+#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
+#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
+#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
+
+#define dmac_map_area __glue(_CACHE,_dma_map_area)
+#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
+#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h
new file mode 100644
index 00000000..354d571e
--- /dev/null
+++ b/arch/arm/include/asm/glue-df.h
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/include/asm/glue-df.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000-2002 Deep Blue Solutions 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 ASM_GLUE_DF_H
+#define ASM_GLUE_DF_H
+
+#include <asm/glue.h>
+
+/*
+ * Data Abort Model
+ * ================
+ *
+ * We have the following to choose from:
+ * arm6 - ARM6 style
+ * arm7 - ARM7 style
+ * v4_early - ARMv4 without Thumb early abort handler
+ * v4t_late - ARMv4 with Thumb late abort handler
+ * v4t_early - ARMv4 with Thumb early abort handler
+ * v5tej_early - ARMv5 with Thumb and Java early abort handler
+ * xscale - ARMv5 with Thumb with Xscale extensions
+ * v6_early - ARMv6 generic early abort handler
+ * v7_early - ARMv7 generic early abort handler
+ */
+#undef CPU_DABORT_HANDLER
+#undef MULTI_DABORT
+
+#if defined(CONFIG_CPU_ARM610)
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER cpu_arm6_data_abort
+# endif
+#endif
+
+#if defined(CONFIG_CPU_ARM710)
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER cpu_arm7_data_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_LV4T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4t_late_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV4T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v4t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5TJ
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v5tj_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV5T
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v5t_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV6
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v6_early_abort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ABRT_EV7
+# ifdef CPU_DABORT_HANDLER
+# define MULTI_DABORT 1
+# else
+# define CPU_DABORT_HANDLER v7_early_abort
+# endif
+#endif
+
+#ifndef CPU_DABORT_HANDLER
+#error Unknown data abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-pf.h b/arch/arm/include/asm/glue-pf.h
new file mode 100644
index 00000000..d385f37c
--- /dev/null
+++ b/arch/arm/include/asm/glue-pf.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/include/asm/glue-pf.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000-2002 Deep Blue Solutions 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 ASM_GLUE_PF_H
+#define ASM_GLUE_PF_H
+
+#include <asm/glue.h>
+
+/*
+ * Prefetch Abort Model
+ * ================
+ *
+ * We have the following to choose from:
+ * legacy - no IFSR, no IFAR
+ * v6 - ARMv6: IFSR, no IFAR
+ * v7 - ARMv7: IFSR and IFAR
+ */
+
+#undef CPU_PABORT_HANDLER
+#undef MULTI_PABORT
+
+#ifdef CONFIG_CPU_PABRT_LEGACY
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER legacy_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V6
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER v6_pabort
+# endif
+#endif
+
+#ifdef CONFIG_CPU_PABRT_V7
+# ifdef CPU_PABORT_HANDLER
+# define MULTI_PABORT 1
+# else
+# define CPU_PABORT_HANDLER v7_pabort
+# endif
+#endif
+
+#ifndef CPU_PABORT_HANDLER
+#error Unknown prefetch abort handler type
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
new file mode 100644
index 00000000..e2be7f14
--- /dev/null
+++ b/arch/arm/include/asm/glue-proc.h
@@ -0,0 +1,264 @@
+/*
+ * arch/arm/include/asm/glue-proc.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000 Deep Blue Solutions 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 ASM_GLUE_PROC_H
+#define ASM_GLUE_PROC_H
+
+#include <asm/glue.h>
+
+/*
+ * Work out if we need multiple CPU support
+ */
+#undef MULTI_CPU
+#undef CPU_NAME
+
+/*
+ * CPU_NAME - the prefix for CPU related functions
+ */
+
+#ifdef CONFIG_CPU_ARM610
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM7TDMI
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm7tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM710
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm7
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM720T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm720
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM740T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm740
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM9TDMI
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm9tdmi
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM920T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm920
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM922T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm922
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FA526
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_fa526
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM925T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm925
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM926T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm926
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM940T
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm940
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM946E
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm946
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA110
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_sa110
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_sa1100
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1020
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1020E
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1020e
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1022
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1022
+# endif
+#endif
+
+#ifdef CONFIG_CPU_ARM1026
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_arm1026
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_xscale
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_xsc3
+# endif
+#endif
+
+#ifdef CONFIG_CPU_MOHAWK
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_mohawk
+# endif
+#endif
+
+#ifdef CONFIG_CPU_FEROCEON
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_feroceon
+# endif
+#endif
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_v6
+# endif
+#endif
+
+#ifdef CONFIG_CPU_V7
+# ifdef CPU_NAME
+# undef MULTI_CPU
+# define MULTI_CPU
+# else
+# define CPU_NAME cpu_v7
+# endif
+#endif
+
+#ifndef MULTI_CPU
+#define cpu_proc_init __glue(CPU_NAME,_proc_init)
+#define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
+#define cpu_reset __glue(CPU_NAME,_reset)
+#define cpu_do_idle __glue(CPU_NAME,_do_idle)
+#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
+#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
+#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
+#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
+#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
+#define cpu_do_resume __glue(CPU_NAME,_do_resume)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
new file mode 100644
index 00000000..fbf71d75
--- /dev/null
+++ b/arch/arm/include/asm/glue.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/include/asm/glue.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000-2002 Deep Blue Solutions 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.
+ *
+ * This file provides the glue to stick the processor-specific bits
+ * into the kernel in an efficient manner. The idea is to use branches
+ * when we're only targeting one class of TLB, or indirect calls
+ * when we're targeting multiple classes of TLBs.
+ */
+#ifdef __KERNEL__
+
+#ifdef __STDC__
+#define ____glue(name,fn) name##fn
+#else
+#define ____glue(name,fn) name/**/fn
+#endif
+#define __glue(name,fn) ____glue(name,fn)
+
+#endif
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
new file mode 100644
index 00000000..166a7a3e
--- /dev/null
+++ b/arch/arm/include/asm/gpio.h
@@ -0,0 +1,7 @@
+#ifndef _ARCH_ARM_GPIO_H
+#define _ARCH_ARM_GPIO_H
+
+/* not all ARM platforms necessarily support this API ... */
+#include <mach/gpio.h>
+
+#endif /* _ARCH_ARM_GPIO_H */
diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h
new file mode 100644
index 00000000..2635c8b5
--- /dev/null
+++ b/arch/arm/include/asm/hardirq.h
@@ -0,0 +1,52 @@
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <asm/irq.h>
+
+#define NR_IPI 6
+
+typedef struct {
+ unsigned int __softirq_pending;
+#ifdef CONFIG_LOCAL_TIMERS
+ unsigned int local_timer_irqs;
+#endif
+#ifdef CONFIG_SMP
+ unsigned int ipi_irqs[NR_IPI];
+#endif
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define __inc_irq_stat(cpu, member) __IRQ_STAT(cpu, member)++
+#define __get_irq_stat(cpu, member) __IRQ_STAT(cpu, member)
+
+#ifdef CONFIG_SMP
+u64 smp_irq_stat_cpu(unsigned int cpu);
+#else
+#define smp_irq_stat_cpu(cpu) 0
+#endif
+
+#define arch_irq_stat_cpu smp_irq_stat_cpu
+
+#if NR_IRQS > 512
+#define HARDIRQ_BITS 10
+#elif NR_IRQS > 256
+#define HARDIRQ_BITS 9
+#else
+#define HARDIRQ_BITS 8
+#endif
+
+/*
+ * The hardirq mask has to be large enough to have space
+ * for potentially all IRQ sources in the system nesting
+ * on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
+
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
+
+#endif /* __ASM_HARDIRQ_H */
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h
new file mode 100644
index 00000000..c0f4e7bf
--- /dev/null
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms. Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD 0x00 /* ACVR rw */
+#define TIMER_VALUE 0x04 /* ACVR ro */
+#define TIMER_CTRL 0x08 /* ACVR rw */
+#define TIMER_CTRL_ONESHOT (1 << 0) /* CVR */
+#define TIMER_CTRL_32BIT (1 << 1) /* CVR */
+#define TIMER_CTRL_DIV1 (0 << 2) /* ACVR */
+#define TIMER_CTRL_DIV16 (1 << 2) /* ACVR */
+#define TIMER_CTRL_DIV256 (2 << 2) /* ACVR */
+#define TIMER_CTRL_IE (1 << 5) /* VR */
+#define TIMER_CTRL_PERIODIC (1 << 6) /* ACVR */
+#define TIMER_CTRL_ENABLE (1 << 7) /* ACVR */
+
+#define TIMER_INTCLR 0x0c /* ACVR wo */
+#define TIMER_RIS 0x10 /* CVR ro */
+#define TIMER_MIS 0x14 /* CVR ro */
+#define TIMER_BGLOAD 0x18 /* CVR rw */
+
+#endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
new file mode 100644
index 00000000..2a20876e
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/include/asm/hardware/cache-l2x0.h
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARM_HARDWARE_L2X0_H
+#define __ASM_ARM_HARDWARE_L2X0_H
+
+#define L2X0_CACHE_ID 0x000
+#define L2X0_CACHE_TYPE 0x004
+#define L2X0_CTRL 0x100
+#define L2X0_AUX_CTRL 0x104
+#define L2X0_TAG_LATENCY_CTRL 0x108
+#define L2X0_DATA_LATENCY_CTRL 0x10C
+#define L2X0_EVENT_CNT_CTRL 0x200
+#define L2X0_EVENT_CNT1_CFG 0x204
+#define L2X0_EVENT_CNT0_CFG 0x208
+#define L2X0_EVENT_CNT1_VAL 0x20C
+#define L2X0_EVENT_CNT0_VAL 0x210
+#define L2X0_INTR_MASK 0x214
+#define L2X0_MASKED_INTR_STAT 0x218
+#define L2X0_RAW_INTR_STAT 0x21C
+#define L2X0_INTR_CLEAR 0x220
+#define L2X0_CACHE_SYNC 0x730
+#define L2X0_DUMMY_REG 0x740
+#define L2X0_INV_LINE_PA 0x770
+#define L2X0_INV_WAY 0x77C
+#define L2X0_CLEAN_LINE_PA 0x7B0
+#define L2X0_CLEAN_LINE_IDX 0x7B8
+#define L2X0_CLEAN_WAY 0x7BC
+#define L2X0_CLEAN_INV_LINE_PA 0x7F0
+#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
+#define L2X0_CLEAN_INV_WAY 0x7FC
+#define L2X0_LOCKDOWN_WAY_D 0x900
+#define L2X0_LOCKDOWN_WAY_I 0x904
+#define L2X0_TEST_OPERATION 0xF00
+#define L2X0_LINE_DATA 0xF10
+#define L2X0_LINE_TAG 0xF30
+#define L2X0_DEBUG_CTRL 0xF40
+#define L2X0_PREFETCH_CTRL 0xF60
+#define L2X0_POWER_CTRL 0xF80
+#define L2X0_DYNAMIC_CLK_GATING_EN (1 << 1)
+#define L2X0_STNDBY_MODE_EN (1 << 0)
+
+/* Registers shifts and masks */
+#define L2X0_CACHE_ID_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)
+
+#define L2X0_AUX_CTRL_MASK 0xc0000fff
+#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT 16
+#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT 17
+#define L2X0_AUX_CTRL_WAY_SIZE_MASK (0x7 << 17)
+#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT 22
+#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT 26
+#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT 27
+#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT 28
+#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
+
+#endif
diff --git a/arch/arm/include/asm/hardware/cache-tauros2.h b/arch/arm/include/asm/hardware/cache-tauros2.h
new file mode 100644
index 00000000..538f17ca
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cache-tauros2.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/include/asm/hardware/cache-tauros2.h
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+extern void __init tauros2_init(void);
diff --git a/arch/arm/include/asm/hardware/clps7111.h b/arch/arm/include/asm/hardware/clps7111.h
new file mode 100644
index 00000000..44477225
--- /dev/null
+++ b/arch/arm/include/asm/hardware/clps7111.h
@@ -0,0 +1,184 @@
+/*
+ * arch/arm/include/asm/hardware/clps7111.h
+ *
+ * This file contains the hardware definitions of the CLPS7111 internal
+ * registers.
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_HARDWARE_CLPS7111_H
+#define __ASM_HARDWARE_CLPS7111_H
+
+#define CLPS7111_PHYS_BASE (0x80000000)
+
+#ifndef __ASSEMBLY__
+#define clps_readb(off) __raw_readb(CLPS7111_BASE + (off))
+#define clps_readw(off) __raw_readw(CLPS7111_BASE + (off))
+#define clps_readl(off) __raw_readl(CLPS7111_BASE + (off))
+#define clps_writeb(val,off) __raw_writeb(val, CLPS7111_BASE + (off))
+#define clps_writew(val,off) __raw_writew(val, CLPS7111_BASE + (off))
+#define clps_writel(val,off) __raw_writel(val, CLPS7111_BASE + (off))
+#endif
+
+#define PADR (0x0000)
+#define PBDR (0x0001)
+#define PDDR (0x0003)
+#define PADDR (0x0040)
+#define PBDDR (0x0041)
+#define PDDDR (0x0043)
+#define PEDR (0x0080)
+#define PEDDR (0x00c0)
+#define SYSCON1 (0x0100)
+#define SYSFLG1 (0x0140)
+#define MEMCFG1 (0x0180)
+#define MEMCFG2 (0x01c0)
+#define DRFPR (0x0200)
+#define INTSR1 (0x0240)
+#define INTMR1 (0x0280)
+#define LCDCON (0x02c0)
+#define TC1D (0x0300)
+#define TC2D (0x0340)
+#define RTCDR (0x0380)
+#define RTCMR (0x03c0)
+#define PMPCON (0x0400)
+#define CODR (0x0440)
+#define UARTDR1 (0x0480)
+#define UBRLCR1 (0x04c0)
+#define SYNCIO (0x0500)
+#define PALLSW (0x0540)
+#define PALMSW (0x0580)
+#define STFCLR (0x05c0)
+#define BLEOI (0x0600)
+#define MCEOI (0x0640)
+#define TEOI (0x0680)
+#define TC1EOI (0x06c0)
+#define TC2EOI (0x0700)
+#define RTCEOI (0x0740)
+#define UMSEOI (0x0780)
+#define COEOI (0x07c0)
+#define HALT (0x0800)
+#define STDBY (0x0840)
+
+#define FBADDR (0x1000)
+#define SYSCON2 (0x1100)
+#define SYSFLG2 (0x1140)
+#define INTSR2 (0x1240)
+#define INTMR2 (0x1280)
+#define UARTDR2 (0x1480)
+#define UBRLCR2 (0x14c0)
+#define SS2DR (0x1500)
+#define SRXEOF (0x1600)
+#define SS2POP (0x16c0)
+#define KBDEOI (0x1700)
+
+/* common bits: SYSCON1 / SYSCON2 */
+#define SYSCON_UARTEN (1 << 8)
+
+#define SYSCON1_KBDSCAN(x) ((x) & 15)
+#define SYSCON1_KBDSCANMASK (15)
+#define SYSCON1_TC1M (1 << 4)
+#define SYSCON1_TC1S (1 << 5)
+#define SYSCON1_TC2M (1 << 6)
+#define SYSCON1_TC2S (1 << 7)
+#define SYSCON1_UART1EN SYSCON_UARTEN
+#define SYSCON1_BZTOG (1 << 9)
+#define SYSCON1_BZMOD (1 << 10)
+#define SYSCON1_DBGEN (1 << 11)
+#define SYSCON1_LCDEN (1 << 12)
+#define SYSCON1_CDENTX (1 << 13)
+#define SYSCON1_CDENRX (1 << 14)
+#define SYSCON1_SIREN (1 << 15)
+#define SYSCON1_ADCKSEL(x) (((x) & 3) << 16)
+#define SYSCON1_ADCKSEL_MASK (3 << 16)
+#define SYSCON1_EXCKEN (1 << 18)
+#define SYSCON1_WAKEDIS (1 << 19)
+#define SYSCON1_IRTXM (1 << 20)
+
+/* common bits: SYSFLG1 / SYSFLG2 */
+#define SYSFLG_UBUSY (1 << 11)
+#define SYSFLG_URXFE (1 << 22)
+#define SYSFLG_UTXFF (1 << 23)
+
+#define SYSFLG1_MCDR (1 << 0)
+#define SYSFLG1_DCDET (1 << 1)
+#define SYSFLG1_WUDR (1 << 2)
+#define SYSFLG1_WUON (1 << 3)
+#define SYSFLG1_CTS (1 << 8)
+#define SYSFLG1_DSR (1 << 9)
+#define SYSFLG1_DCD (1 << 10)
+#define SYSFLG1_UBUSY SYSFLG_UBUSY
+#define SYSFLG1_NBFLG (1 << 12)
+#define SYSFLG1_RSTFLG (1 << 13)
+#define SYSFLG1_PFFLG (1 << 14)
+#define SYSFLG1_CLDFLG (1 << 15)
+#define SYSFLG1_URXFE SYSFLG_URXFE
+#define SYSFLG1_UTXFF SYSFLG_UTXFF
+#define SYSFLG1_CRXFE (1 << 24)
+#define SYSFLG1_CTXFF (1 << 25)
+#define SYSFLG1_SSIBUSY (1 << 26)
+#define SYSFLG1_ID (1 << 29)
+
+#define SYSFLG2_SSRXOF (1 << 0)
+#define SYSFLG2_RESVAL (1 << 1)
+#define SYSFLG2_RESFRM (1 << 2)
+#define SYSFLG2_SS2RXFE (1 << 3)
+#define SYSFLG2_SS2TXFF (1 << 4)
+#define SYSFLG2_SS2TXUF (1 << 5)
+#define SYSFLG2_CKMODE (1 << 6)
+#define SYSFLG2_UBUSY SYSFLG_UBUSY
+#define SYSFLG2_URXFE SYSFLG_URXFE
+#define SYSFLG2_UTXFF SYSFLG_UTXFF
+
+#define LCDCON_GSEN (1 << 30)
+#define LCDCON_GSMD (1 << 31)
+
+#define SYSCON2_SERSEL (1 << 0)
+#define SYSCON2_KBD6 (1 << 1)
+#define SYSCON2_DRAMZ (1 << 2)
+#define SYSCON2_KBWEN (1 << 3)
+#define SYSCON2_SS2TXEN (1 << 4)
+#define SYSCON2_PCCARD1 (1 << 5)
+#define SYSCON2_PCCARD2 (1 << 6)
+#define SYSCON2_SS2RXEN (1 << 7)
+#define SYSCON2_UART2EN SYSCON_UARTEN
+#define SYSCON2_SS2MAEN (1 << 9)
+#define SYSCON2_OSTB (1 << 12)
+#define SYSCON2_CLKENSL (1 << 13)
+#define SYSCON2_BUZFREQ (1 << 14)
+
+/* common bits: UARTDR1 / UARTDR2 */
+#define UARTDR_FRMERR (1 << 8)
+#define UARTDR_PARERR (1 << 9)
+#define UARTDR_OVERR (1 << 10)
+
+/* common bits: UBRLCR1 / UBRLCR2 */
+#define UBRLCR_BAUD_MASK ((1 << 12) - 1)
+#define UBRLCR_BREAK (1 << 12)
+#define UBRLCR_PRTEN (1 << 13)
+#define UBRLCR_EVENPRT (1 << 14)
+#define UBRLCR_XSTOP (1 << 15)
+#define UBRLCR_FIFOEN (1 << 16)
+#define UBRLCR_WRDLEN5 (0 << 17)
+#define UBRLCR_WRDLEN6 (1 << 17)
+#define UBRLCR_WRDLEN7 (2 << 17)
+#define UBRLCR_WRDLEN8 (3 << 17)
+#define UBRLCR_WRDLEN_MASK (3 << 17)
+
+#define SYNCIO_SMCKEN (1 << 13)
+#define SYNCIO_TXFRMEN (1 << 14)
+
+#endif /* __ASM_HARDWARE_CLPS7111_H */
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
new file mode 100644
index 00000000..dcf74d71
--- /dev/null
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -0,0 +1,185 @@
+/*
+ * linux/arch/arm/include/asm/hardware/coresight.h
+ *
+ * CoreSight components' registers
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can 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_HARDWARE_CORESIGHT_H
+#define __ASM_HARDWARE_CORESIGHT_H
+
+#define TRACER_ACCESSED_BIT 0
+#define TRACER_RUNNING_BIT 1
+#define TRACER_CYCLE_ACC_BIT 2
+#define TRACER_TRACE_DATA_BIT 3
+#define TRACER_TIMESTAMP_BIT 4
+#define TRACER_BRANCHOUTPUT_BIT 5
+#define TRACER_RETURN_STACK_BIT 6
+#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_TIMESTAMP BIT(TRACER_TIMESTAMP_BIT)
+#define TRACER_BRANCHOUTPUT BIT(TRACER_BRANCHOUTPUT_BIT)
+#define TRACER_RETURN_STACK BIT(TRACER_RETURN_STACK_BIT)
+
+#define TRACER_TIMEOUT 10000
+
+#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
+#define CSMR_LOCKSTATUS 0xfb4
+#define CSMR_AUTHSTATUS 0xfb8
+#define CSMR_DEVID 0xfc8
+#define CSMR_DEVTYPE 0xfcc
+/* CoreSight Component Registers */
+#define CSCR_CLASS 0xff4
+
+#define UNLOCK_MAGIC 0xc5acce55
+
+/* ETM control register, "ETM Architecture", 3.3.1 */
+#define ETMR_CTRL 0
+#define ETMCTRL_POWERDOWN 1
+#define ETMCTRL_PROGRAM (1 << 10)
+#define ETMCTRL_PORTSEL (1 << 11)
+#define ETMCTRL_CONTEXTIDSIZE(x) (((x) & 3) << 14)
+#define ETMCTRL_PORTMASK1 (7 << 4)
+#define ETMCTRL_PORTMASK2 (1 << 21)
+#define ETMCTRL_PORTMASK (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
+#define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21)
+#define ETMCTRL_DO_CPRT (1 << 1)
+#define ETMCTRL_DATAMASK (3 << 2)
+#define ETMCTRL_DATA_DO_DATA (1 << 2)
+#define ETMCTRL_DATA_DO_ADDR (1 << 3)
+#define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
+#define ETMCTRL_BRANCH_OUTPUT (1 << 8)
+#define ETMCTRL_CYCLEACCURATE (1 << 12)
+#define ETMCTRL_TIMESTAMP_EN (1 << 28)
+#define ETMCTRL_RETURN_STACK_EN (1 << 29)
+
+/* ETM configuration code register */
+#define ETMR_CONFCODE (0x04)
+#define ETMCCR_ETMIDR_PRESENT BIT(31)
+
+/* ETM trace start/stop resource control register */
+#define ETMR_TRACESSCTRL (0x18)
+
+/* ETM trigger event register */
+#define ETMR_TRIGEVT (0x08)
+
+/* address access type register bits, "ETM architecture",
+ * table 3-27 */
+/* - access type */
+#define ETMAAT_IFETCH 0
+#define ETMAAT_IEXEC 1
+#define ETMAAT_IEXECPASS 2
+#define ETMAAT_IEXECFAIL 3
+#define ETMAAT_DLOADSTORE 4
+#define ETMAAT_DLOAD 5
+#define ETMAAT_DSTORE 6
+/* - comparison access size */
+#define ETMAAT_JAVA (0 << 3)
+#define ETMAAT_THUMB (1 << 3)
+#define ETMAAT_ARM (3 << 3)
+/* - data value comparison control */
+#define ETMAAT_NOVALCMP (0 << 5)
+#define ETMAAT_VALMATCH (1 << 5)
+#define ETMAAT_VALNOMATCH (3 << 5)
+/* - exact match */
+#define ETMAAT_EXACTMATCH (1 << 7)
+/* - context id comparator control */
+#define ETMAAT_IGNCONTEXTID (0 << 8)
+#define ETMAAT_VALUE1 (1 << 8)
+#define ETMAAT_VALUE2 (2 << 8)
+#define ETMAAT_VALUE3 (3 << 8)
+/* - security level control */
+#define ETMAAT_IGNSECURITY (0 << 10)
+#define ETMAAT_NSONLY (1 << 10)
+#define ETMAAT_SONLY (2 << 10)
+
+#define ETMR_COMP_VAL(x) (0x40 + (x) * 4)
+#define ETMR_COMP_ACC_TYPE(x) (0x80 + (x) * 4)
+
+/* ETM status register, "ETM Architecture", 3.3.2 */
+#define ETMR_STATUS (0x10)
+#define ETMST_OVERFLOW BIT(0)
+#define ETMST_PROGBIT BIT(1)
+#define ETMST_STARTSTOP BIT(2)
+#define ETMST_TRIGGER BIT(3)
+
+#define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT)
+#define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP)
+#define etm_triggered(t) (etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER)
+
+#define ETMR_TRACEENCTRL2 0x1c
+#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)
+
+#define ETMR_ID 0x1e4
+#define ETMIDR_VERSION(x) (((x) >> 4) & 0xff)
+#define ETMIDR_VERSION_3_1 0x21
+#define ETMIDR_VERSION_PFT_1_0 0x30
+
+#define ETMR_CCE 0x1e8
+#define ETMCCER_RETURN_STACK_IMPLEMENTED BIT(23)
+#define ETMCCER_TIMESTAMPING_IMPLEMENTED BIT(22)
+
+#define ETMR_TRACEIDR 0x200
+
+/* ETM management registers, "ETM Architecture", 3.5.24 */
+#define ETMMR_OSLAR 0x300
+#define ETMMR_OSLSR 0x304
+#define ETMMR_OSSRR 0x308
+#define ETMMR_PDSR 0x314
+
+/* ETB registers, "CoreSight Components TRM", 9.3 */
+#define ETBR_DEPTH 0x04
+#define ETBR_STATUS 0x0c
+#define ETBR_READMEM 0x10
+#define ETBR_READADDR 0x14
+#define ETBR_WRITEADDR 0x18
+#define ETBR_TRIGGERCOUNT 0x1c
+#define ETBR_CTRL 0x20
+#define ETBR_FORMATTERCTRL 0x304
+#define ETBFF_ENFTC 1
+#define ETBFF_ENFCONT BIT(1)
+#define ETBFF_FONFLIN BIT(4)
+#define ETBFF_MANUAL_FLUSH BIT(6)
+#define ETBFF_TRIGIN BIT(8)
+#define ETBFF_TRIGEVT BIT(9)
+#define ETBFF_TRIGFL BIT(10)
+#define 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, 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) \
+ do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+
+#endif /* __ASM_HARDWARE_CORESIGHT_H */
+
diff --git a/arch/arm/include/asm/hardware/cs89712.h b/arch/arm/include/asm/hardware/cs89712.h
new file mode 100644
index 00000000..f7562693
--- /dev/null
+++ b/arch/arm/include/asm/hardware/cs89712.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/include/asm/hardware/cs89712.h
+ *
+ * This file contains the hardware definitions of the CS89712
+ * additional internal registers.
+ *
+ * Copyright (C) 2001 Thomas Gleixner autronix automation <gleixner@autronix.de>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_HARDWARE_CS89712_H
+#define __ASM_HARDWARE_CS89712_H
+
+/*
+* CS89712 additional registers
+*/
+
+#define PCDR 0x0002 /* Port C Data register ---------------------------- */
+#define PCDDR 0x0042 /* Port C Data Direction register ------------------ */
+#define SDCONF 0x2300 /* SDRAM Configuration register ---------------------*/
+#define SDRFPR 0x2340 /* SDRAM Refresh period register --------------------*/
+
+#define SDCONF_ACTIVE (1 << 10)
+#define SDCONF_CLKCTL (1 << 9)
+#define SDCONF_WIDTH_4 (0 << 7)
+#define SDCONF_WIDTH_8 (1 << 7)
+#define SDCONF_WIDTH_16 (2 << 7)
+#define SDCONF_WIDTH_32 (3 << 7)
+#define SDCONF_SIZE_16 (0 << 5)
+#define SDCONF_SIZE_64 (1 << 5)
+#define SDCONF_SIZE_128 (2 << 5)
+#define SDCONF_SIZE_256 (3 << 5)
+#define SDCONF_CASLAT_2 (2)
+#define SDCONF_CASLAT_3 (3)
+
+#endif /* __ASM_HARDWARE_CS89712_H */
diff --git a/arch/arm/include/asm/hardware/debug-8250.S b/arch/arm/include/asm/hardware/debug-8250.S
new file mode 100644
index 00000000..22c68925
--- /dev/null
+++ b/arch/arm/include/asm/hardware/debug-8250.S
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/include/asm/hardware/debug-8250.S
+ *
+ * Copyright (C) 1994-1999 Russell King
+ *
+ * This program is free software; you can 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_reg.h>
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UART_TX << UART_SHIFT]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+#ifdef FLOW_CONTROL
+1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+#endif
+ .endm
diff --git a/arch/arm/include/asm/hardware/debug-pl01x.S b/arch/arm/include/asm/hardware/debug-pl01x.S
new file mode 100644
index 00000000..f9fd083e
--- /dev/null
+++ b/arch/arm/include/asm/hardware/debug-pl01x.S
@@ -0,0 +1,29 @@
+/* arch/arm/include/asm/hardware/debug-pl01x.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+#include <linux/amba/serial.h>
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UART01x_DR]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UART01x_FR]
+ tst \rd, #UART01x_FR_TXFF
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #UART01x_FR]
+ tst \rd, #UART01x_FR_BUSY
+ bne 1001b
+ .endm
diff --git a/arch/arm/include/asm/hardware/dec21285.h b/arch/arm/include/asm/hardware/dec21285.h
new file mode 100644
index 00000000..0d755275
--- /dev/null
+++ b/arch/arm/include/asm/hardware/dec21285.h
@@ -0,0 +1,147 @@
+/*
+ * arch/arm/include/asm/hardware/dec21285.h
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DC21285 registers
+ */
+#define DC21285_PCI_IACK 0x79000000
+#define DC21285_ARMCSR_BASE 0x42000000
+#define DC21285_PCI_TYPE_0_CONFIG 0x7b000000
+#define DC21285_PCI_TYPE_1_CONFIG 0x7a000000
+#define DC21285_OUTBOUND_WRITE_FLUSH 0x78000000
+#define DC21285_FLASH 0x41000000
+#define DC21285_PCI_IO 0x7c000000
+#define DC21285_PCI_MEM 0x80000000
+
+#ifndef __ASSEMBLY__
+#include <mach/hardware.h>
+#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
+#else
+#define DC21285_IO(x) (x)
+#endif
+
+#define CSR_PCICMD DC21285_IO(0x0004)
+#define CSR_CLASSREV DC21285_IO(0x0008)
+#define CSR_PCICACHELINESIZE DC21285_IO(0x000c)
+#define CSR_PCICSRBASE DC21285_IO(0x0010)
+#define CSR_PCICSRIOBASE DC21285_IO(0x0014)
+#define CSR_PCISDRAMBASE DC21285_IO(0x0018)
+#define CSR_PCIROMBASE DC21285_IO(0x0030)
+#define CSR_MBOX0 DC21285_IO(0x0050)
+#define CSR_MBOX1 DC21285_IO(0x0054)
+#define CSR_MBOX2 DC21285_IO(0x0058)
+#define CSR_MBOX3 DC21285_IO(0x005c)
+#define CSR_DOORBELL DC21285_IO(0x0060)
+#define CSR_DOORBELL_SETUP DC21285_IO(0x0064)
+#define CSR_ROMWRITEREG DC21285_IO(0x0068)
+#define CSR_CSRBASEMASK DC21285_IO(0x00f8)
+#define CSR_CSRBASEOFFSET DC21285_IO(0x00fc)
+#define CSR_SDRAMBASEMASK DC21285_IO(0x0100)
+#define CSR_SDRAMBASEOFFSET DC21285_IO(0x0104)
+#define CSR_ROMBASEMASK DC21285_IO(0x0108)
+#define CSR_SDRAMTIMING DC21285_IO(0x010c)
+#define CSR_SDRAMADDRSIZE0 DC21285_IO(0x0110)
+#define CSR_SDRAMADDRSIZE1 DC21285_IO(0x0114)
+#define CSR_SDRAMADDRSIZE2 DC21285_IO(0x0118)
+#define CSR_SDRAMADDRSIZE3 DC21285_IO(0x011c)
+#define CSR_I2O_INFREEHEAD DC21285_IO(0x0120)
+#define CSR_I2O_INPOSTTAIL DC21285_IO(0x0124)
+#define CSR_I2O_OUTPOSTHEAD DC21285_IO(0x0128)
+#define CSR_I2O_OUTFREETAIL DC21285_IO(0x012c)
+#define CSR_I2O_INFREECOUNT DC21285_IO(0x0130)
+#define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134)
+#define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138)
+#define CSR_SA110_CNTL DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE (1 << 0)
+#define SA110_CNTL_ASSERTSERR (1 << 1)
+#define SA110_CNTL_RXSERR (1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY (1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY (1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY (1 << 6)
+#define SA110_CNTL_DISCARDTIMER (1 << 8)
+#define SA110_CNTL_PCINRESET (1 << 9)
+#define SA110_CNTL_I2O_256 (0 << 10)
+#define SA110_CNTL_I20_512 (1 << 10)
+#define SA110_CNTL_I2O_1024 (2 << 10)
+#define SA110_CNTL_I2O_2048 (3 << 10)
+#define SA110_CNTL_I2O_4096 (4 << 10)
+#define SA110_CNTL_I2O_8192 (5 << 10)
+#define SA110_CNTL_I2O_16384 (6 << 10)
+#define SA110_CNTL_I2O_32768 (7 << 10)
+#define SA110_CNTL_WATCHDOG (1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14)
+#define SA110_CNTL_ROMWIDTH_16 (1 << 14)
+#define SA110_CNTL_ROMWIDTH_32 (2 << 14)
+#define SA110_CNTL_ROMWIDTH_8 (3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24)
+#define SA110_CNTL_XCSDIR(x) ((x)<<28)
+#define SA110_CNTL_PCICFN (1 << 31)
+
+/*
+ * footbridge_cfn_mode() is used when we want
+ * to check whether we are the central function
+ */
+#define __footbridge_cfn_mode() (*CSR_SA110_CNTL & SA110_CNTL_PCICFN)
+#if defined(CONFIG_FOOTBRIDGE_HOST) && defined(CONFIG_FOOTBRIDGE_ADDIN)
+#define footbridge_cfn_mode() __footbridge_cfn_mode()
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+#define footbridge_cfn_mode() (1)
+#else
+#define footbridge_cfn_mode() (0)
+#endif
+
+#define CSR_PCIADDR_EXTN DC21285_IO(0x0140)
+#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144)
+#define CSR_XBUS_CYCLE DC21285_IO(0x0148)
+#define CSR_XBUS_IOSTROBE DC21285_IO(0x014c)
+#define CSR_DOORBELL_PCI DC21285_IO(0x0150)
+#define CSR_DOORBELL_SA110 DC21285_IO(0x0154)
+#define CSR_UARTDR DC21285_IO(0x0160)
+#define CSR_RXSTAT DC21285_IO(0x0164)
+#define CSR_H_UBRLCR DC21285_IO(0x0168)
+#define CSR_M_UBRLCR DC21285_IO(0x016c)
+#define CSR_L_UBRLCR DC21285_IO(0x0170)
+#define CSR_UARTCON DC21285_IO(0x0174)
+#define CSR_UARTFLG DC21285_IO(0x0178)
+#define CSR_IRQ_STATUS DC21285_IO(0x0180)
+#define CSR_IRQ_RAWSTATUS DC21285_IO(0x0184)
+#define CSR_IRQ_ENABLE DC21285_IO(0x0188)
+#define CSR_IRQ_DISABLE DC21285_IO(0x018c)
+#define CSR_IRQ_SOFT DC21285_IO(0x0190)
+#define CSR_FIQ_STATUS DC21285_IO(0x0280)
+#define CSR_FIQ_RAWSTATUS DC21285_IO(0x0284)
+#define CSR_FIQ_ENABLE DC21285_IO(0x0288)
+#define CSR_FIQ_DISABLE DC21285_IO(0x028c)
+#define CSR_FIQ_SOFT DC21285_IO(0x0290)
+#define CSR_TIMER1_LOAD DC21285_IO(0x0300)
+#define CSR_TIMER1_VALUE DC21285_IO(0x0304)
+#define CSR_TIMER1_CNTL DC21285_IO(0x0308)
+#define CSR_TIMER1_CLR DC21285_IO(0x030c)
+#define CSR_TIMER2_LOAD DC21285_IO(0x0320)
+#define CSR_TIMER2_VALUE DC21285_IO(0x0324)
+#define CSR_TIMER2_CNTL DC21285_IO(0x0328)
+#define CSR_TIMER2_CLR DC21285_IO(0x032c)
+#define CSR_TIMER3_LOAD DC21285_IO(0x0340)
+#define CSR_TIMER3_VALUE DC21285_IO(0x0344)
+#define CSR_TIMER3_CNTL DC21285_IO(0x0348)
+#define CSR_TIMER3_CLR DC21285_IO(0x034c)
+#define CSR_TIMER4_LOAD DC21285_IO(0x0360)
+#define CSR_TIMER4_VALUE DC21285_IO(0x0364)
+#define CSR_TIMER4_CNTL DC21285_IO(0x0368)
+#define CSR_TIMER4_CLR DC21285_IO(0x036c)
+
+#define TIMER_CNTL_ENABLE (1 << 7)
+#define TIMER_CNTL_AUTORELOAD (1 << 6)
+#define TIMER_CNTL_DIV1 (0)
+#define TIMER_CNTL_DIV16 (1 << 2)
+#define TIMER_CNTL_DIV256 (2 << 2)
+#define TIMER_CNTL_CNTEXT (3 << 2)
+
+
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
new file mode 100644
index 00000000..c115b82f
--- /dev/null
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/include/asm/hardware/entry-macro-gic.S
+ *
+ * Low-level IRQ helper macros for GIC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware/gic.h>
+
+#ifndef HAVE_GET_IRQNR_PREAMBLE
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =gic_cpu_base_addr
+ ldr \base, [\base]
+ .endm
+#endif
+
+/*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ /* bits 12-10 = src CPU, 9-0 = int # */
+
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+ .endm
+
+/* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+/* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
new file mode 100644
index 00000000..e0af4983
--- /dev/null
+++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/include/asm/hardware/entry-macro-iomd.S
+ *
+ * Low-level IRQ helper macros for IOC/IOMD based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/* IOC / IOMD based hardware */
+#include <asm/hardware/iomd.h>
+
+ .macro disable_fiq
+ mov r12, #ioc_base_high
+ .if ioc_base_low
+ orr r12, r12, #ioc_base_low
+ .endif
+ strb r12, [r12, #0x38] @ Disable FIQ register
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first
+ ldr \tmp, =irq_prio_h
+ teq \irqstat, #0
+#ifdef IOMD_BASE
+ ldreqb \irqstat, [\base, #IOMD_DMAREQ] @ get dma
+ addeq \tmp, \tmp, #256 @ irq_prio_h table size
+ teqeq \irqstat, #0
+ bne 2406f
+#endif
+ ldreqb \irqstat, [\base, #IOMD_IRQREQA] @ get low priority
+ addeq \tmp, \tmp, #256 @ irq_prio_d table size
+ teqeq \irqstat, #0
+#ifdef IOMD_IRQREQC
+ ldreqb \irqstat, [\base, #IOMD_IRQREQC]
+ addeq \tmp, \tmp, #256 @ irq_prio_l table size
+ teqeq \irqstat, #0
+#endif
+#ifdef IOMD_IRQREQD
+ ldreqb \irqstat, [\base, #IOMD_IRQREQD]
+ addeq \tmp, \tmp, #256 @ irq_prio_lc table size
+ teqeq \irqstat, #0
+#endif
+2406: ldrneb \irqnr, [\tmp, \irqstat] @ get IRQ number
+ .endm
+
+/*
+ * Interrupt table (incorporates priority). Please note that we
+ * rely on the order of these tables (see above code).
+ */
+ .align 5
+irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+ .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
+#ifdef IOMD_BASE
+irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+ .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
+#endif
+irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+#ifdef IOMD_IRQREQC
+irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+ .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
+ .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+ .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+ .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+ .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
+ .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+ .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+ .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+#endif
+#ifdef IOMD_IRQREQD
+irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+ .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
+ .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+ .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+ .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+ .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
+ .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+ .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+ .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
+#endif
+
diff --git a/arch/arm/include/asm/hardware/ep7211.h b/arch/arm/include/asm/hardware/ep7211.h
new file mode 100644
index 00000000..654d5f62
--- /dev/null
+++ b/arch/arm/include/asm/hardware/ep7211.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/include/asm/hardware/ep7211.h
+ *
+ * This file contains the hardware definitions of the EP7211 internal
+ * registers.
+ *
+ * Copyright (C) 2001 Blue Mug, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_HARDWARE_EP7211_H
+#define __ASM_HARDWARE_EP7211_H
+
+#include <asm/hardware/clps7111.h>
+
+/*
+ * define EP7211_BASE to be the base address of the region
+ * you want to access.
+ */
+
+#define EP7211_PHYS_BASE (0x80000000)
+
+/*
+ * XXX miket@bluemug.com: need to introduce EP7211 registers (those not
+ * present in 7212) here.
+ */
+
+#endif /* __ASM_HARDWARE_EP7211_H */
diff --git a/arch/arm/include/asm/hardware/ep7212.h b/arch/arm/include/asm/hardware/ep7212.h
new file mode 100644
index 00000000..3b43bbea
--- /dev/null
+++ b/arch/arm/include/asm/hardware/ep7212.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/include/asm/hardware/ep7212.h
+ *
+ * This file contains the hardware definitions of the EP7212 internal
+ * registers.
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_HARDWARE_EP7212_H
+#define __ASM_HARDWARE_EP7212_H
+
+/*
+ * define EP7212_BASE to be the base address of the region
+ * you want to access.
+ */
+
+#define EP7212_PHYS_BASE (0x80000000)
+
+#ifndef __ASSEMBLY__
+#define ep_readl(off) __raw_readl(EP7212_BASE + (off))
+#define ep_writel(val,off) __raw_writel(val, EP7212_BASE + (off))
+#endif
+
+/*
+ * These registers are specific to the EP7212 only
+ */
+#define DAIR 0x2000
+#define DAIR0 0x2040
+#define DAIDR1 0x2080
+#define DAIDR2 0x20c0
+#define DAISR 0x2100
+#define SYSCON3 0x2200
+#define INTSR3 0x2240
+#define INTMR3 0x2280
+#define LEDFLSH 0x22c0
+
+#define DAIR_DAIEN (1 << 16)
+#define DAIR_ECS (1 << 17)
+#define DAIR_LCTM (1 << 19)
+#define DAIR_LCRM (1 << 20)
+#define DAIR_RCTM (1 << 21)
+#define DAIR_RCRM (1 << 22)
+#define DAIR_LBM (1 << 23)
+
+#define DAIDR2_FIFOEN (1 << 15)
+#define DAIDR2_FIFOLEFT (0x0d << 16)
+#define DAIDR2_FIFORIGHT (0x11 << 16)
+
+#define DAISR_RCTS (1 << 0)
+#define DAISR_RCRS (1 << 1)
+#define DAISR_LCTS (1 << 2)
+#define DAISR_LCRS (1 << 3)
+#define DAISR_RCTU (1 << 4)
+#define DAISR_RCRO (1 << 5)
+#define DAISR_LCTU (1 << 6)
+#define DAISR_LCRO (1 << 7)
+#define DAISR_RCNF (1 << 8)
+#define DAISR_RCNE (1 << 9)
+#define DAISR_LCNF (1 << 10)
+#define DAISR_LCNE (1 << 11)
+#define DAISR_FIFO (1 << 12)
+
+#define SYSCON3_ADCCON (1 << 0)
+#define SYSCON3_DAISEL (1 << 3)
+#define SYSCON3_ADCCKNSEN (1 << 4)
+#define SYSCON3_FASTWAKE (1 << 8)
+#define SYSCON3_DAIEN (1 << 9)
+
+#endif /* __ASM_HARDWARE_EP7212_H */
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
new file mode 100644
index 00000000..c8647b30
--- /dev/null
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/include/asm/hardware/gic.h
+ *
+ * Copyright (C) 2002 ARM Limited, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_HARDWARE_GIC_H
+#define __ASM_ARM_HARDWARE_GIC_H
+
+#include <linux/compiler.h>
+
+#define GIC_CPU_CTRL 0x00
+#define GIC_CPU_PRIMASK 0x04
+#define GIC_CPU_BINPOINT 0x08
+#define GIC_CPU_INTACK 0x0c
+#define GIC_CPU_EOI 0x10
+#define GIC_CPU_RUNNINGPRI 0x14
+#define GIC_CPU_HIGHPRI 0x18
+
+#define GIC_DIST_CTRL 0x000
+#define GIC_DIST_CTR 0x004
+#define GIC_DIST_ENABLE_SET 0x100
+#define GIC_DIST_ENABLE_CLEAR 0x180
+#define GIC_DIST_PENDING_SET 0x200
+#define GIC_DIST_PENDING_CLEAR 0x280
+#define GIC_DIST_ACTIVE_BIT 0x300
+#define GIC_DIST_PRI 0x400
+#define GIC_DIST_TARGET 0x800
+#define GIC_DIST_CONFIG 0xc00
+#define GIC_DIST_SOFTINT 0xf00
+
+#ifndef __ASSEMBLY__
+extern void __iomem *gic_cpu_base_addr;
+extern struct irq_chip gic_arch_extn;
+
+struct gic_dist_state {
+ u32 icddcr; /* 0x000 */
+ /* 0x004 RO */
+ /* 0x008 RO */
+ /* 0x00c ~ 0x07c Reserved */
+ u32 icdisrn[8]; /* 0x080 ~ 0x09c */
+ u32 icdisern[8]; /* 0x100 ~ 0x11c Reserved */
+ /* 0x120 ~ 0x17c */
+ u32 icdicern[8]; /* 0x180 ~ 0x19c */
+ u32 icdisprn[32]; /* 0x200 ~ 0x27c */
+ u32 icdicprn[8]; /* 0x280 ~ 0x29c */
+ u32 icdabrn[8]; /* 0x300 ~ 0x31c */
+ /* 0x320 ~ 0x3fc Reserved */
+ u32 icdiprn[64]; /* 0x400 ~ 0x4fc */
+ /* 0x500 ~ 0x7fc Reserved */
+ u32 icdiptrn[64]; /* 0x800 ~ 0x8fc */
+ /* 0x900 ~ 0xbfc Reserved */
+ u32 icdicfrn[16]; /* 0xc00 ~ 0xc3c */
+};
+
+struct gic_cpu_state {
+ u32 iccicr; /* 0x000 */
+ u32 iccpmr; /* 0x004 */
+ u32 iccbpr; /* 0x008 */
+};
+
+void gic_init(unsigned int, unsigned int, void __iomem *, void __iomem *);
+void gic_secondary_init(unsigned int);
+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);
+void gic_disable_ppi(unsigned int);
+void save_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs);
+void restore_gic_cpu_state(unsigned int gic_nr, struct gic_cpu_state *gcs);
+void save_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds);
+void restore_gic_dist_state(unsigned int gic_nr, struct gic_dist_state *gds);
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/hardware/icst.h b/arch/arm/include/asm/hardware/icst.h
new file mode 100644
index 00000000..794220b0
--- /dev/null
+++ b/arch/arm/include/asm/hardware/icst.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/include/asm/hardware/icst.h
+ *
+ * Copyright (C) 2003 Deep Blue Solutions, 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.
+ *
+ * Support functions for calculating clocks/divisors for the ICST
+ * clock generators. See http://www.idt.com/ for more information
+ * on these devices.
+ */
+#ifndef ASMARM_HARDWARE_ICST_H
+#define ASMARM_HARDWARE_ICST_H
+
+struct icst_params {
+ unsigned long ref;
+ unsigned long vco_max; /* inclusive */
+ unsigned long vco_min; /* exclusive */
+ unsigned short vd_min; /* inclusive */
+ unsigned short vd_max; /* inclusive */
+ unsigned char rd_min; /* inclusive */
+ unsigned char rd_max; /* inclusive */
+ const unsigned char *s2div; /* chip specific s2div array */
+ const unsigned char *idx2s; /* chip specific idx2s array */
+};
+
+struct icst_vco {
+ unsigned short v;
+ unsigned char r;
+ unsigned char s;
+};
+
+unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco);
+struct icst_vco icst_hz_to_vco(const struct icst_params *p, unsigned long freq);
+
+/*
+ * ICST307 VCO frequency must be between 6MHz and 200MHz (3.3 or 5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST307_VCO_MIN 6000000
+#define ICST307_VCO_MAX 200000000
+
+extern const unsigned char icst307_s2div[];
+extern const unsigned char icst307_idx2s[];
+
+/*
+ * ICST525 VCO frequency must be between 10MHz and 200MHz (3V) or 320MHz (5V).
+ * This frequency is pre-output divider.
+ */
+#define ICST525_VCO_MIN 10000000
+#define ICST525_VCO_MAX_3V 200000000
+#define ICST525_VCO_MAX_5V 320000000
+
+extern const unsigned char icst525_s2div[];
+extern const unsigned char icst525_idx2s[];
+
+#endif
diff --git a/arch/arm/include/asm/hardware/ioc.h b/arch/arm/include/asm/hardware/ioc.h
new file mode 100644
index 00000000..1f6b8013
--- /dev/null
+++ b/arch/arm/include/asm/hardware/ioc.h
@@ -0,0 +1,72 @@
+/*
+ * arch/arm/include/asm/hardware/ioc.h
+ *
+ * Copyright (C) Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Use these macros to read/write the IOC. All it does is perform the actual
+ * read/write.
+ */
+#ifndef __ASMARM_HARDWARE_IOC_H
+#define __ASMARM_HARDWARE_IOC_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * We use __raw_base variants here so that we give the compiler the
+ * chance to keep IOC_BASE in a register.
+ */
+#define ioc_readb(off) __raw_readb(IOC_BASE + (off))
+#define ioc_writeb(val,off) __raw_writeb(val, IOC_BASE + (off))
+
+#endif
+
+#define IOC_CONTROL (0x00)
+#define IOC_KARTTX (0x04)
+#define IOC_KARTRX (0x04)
+
+#define IOC_IRQSTATA (0x10)
+#define IOC_IRQREQA (0x14)
+#define IOC_IRQCLRA (0x14)
+#define IOC_IRQMASKA (0x18)
+
+#define IOC_IRQSTATB (0x20)
+#define IOC_IRQREQB (0x24)
+#define IOC_IRQMASKB (0x28)
+
+#define IOC_FIQSTAT (0x30)
+#define IOC_FIQREQ (0x34)
+#define IOC_FIQMASK (0x38)
+
+#define IOC_T0CNTL (0x40)
+#define IOC_T0LTCHL (0x40)
+#define IOC_T0CNTH (0x44)
+#define IOC_T0LTCHH (0x44)
+#define IOC_T0GO (0x48)
+#define IOC_T0LATCH (0x4c)
+
+#define IOC_T1CNTL (0x50)
+#define IOC_T1LTCHL (0x50)
+#define IOC_T1CNTH (0x54)
+#define IOC_T1LTCHH (0x54)
+#define IOC_T1GO (0x58)
+#define IOC_T1LATCH (0x5c)
+
+#define IOC_T2CNTL (0x60)
+#define IOC_T2LTCHL (0x60)
+#define IOC_T2CNTH (0x64)
+#define IOC_T2LTCHH (0x64)
+#define IOC_T2GO (0x68)
+#define IOC_T2LATCH (0x6c)
+
+#define IOC_T3CNTL (0x70)
+#define IOC_T3LTCHL (0x70)
+#define IOC_T3CNTH (0x74)
+#define IOC_T3LTCHH (0x74)
+#define IOC_T3GO (0x78)
+#define IOC_T3LATCH (0x7c)
+
+#endif
diff --git a/arch/arm/include/asm/hardware/iomd.h b/arch/arm/include/asm/hardware/iomd.h
new file mode 100644
index 00000000..f9ee69e4
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iomd.h
@@ -0,0 +1,185 @@
+/*
+ * arch/arm/include/asm/hardware/iomd.h
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains information out the IOMD ASIC used in the
+ * Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
+ */
+#ifndef __ASMARM_HARDWARE_IOMD_H
+#define __ASMARM_HARDWARE_IOMD_H
+
+
+#ifndef __ASSEMBLY__
+
+/*
+ * We use __raw_base variants here so that we give the compiler the
+ * chance to keep IOC_BASE in a register.
+ */
+#define iomd_readb(off) __raw_readb(IOMD_BASE + (off))
+#define iomd_readl(off) __raw_readl(IOMD_BASE + (off))
+#define iomd_writeb(val,off) __raw_writeb(val, IOMD_BASE + (off))
+#define iomd_writel(val,off) __raw_writel(val, IOMD_BASE + (off))
+
+#endif
+
+#define IOMD_CONTROL (0x000)
+#define IOMD_KARTTX (0x004)
+#define IOMD_KARTRX (0x004)
+#define IOMD_KCTRL (0x008)
+
+#define IOMD_IRQSTATA (0x010)
+#define IOMD_IRQREQA (0x014)
+#define IOMD_IRQCLRA (0x014)
+#define IOMD_IRQMASKA (0x018)
+
+#define IOMD_IRQSTATB (0x020)
+#define IOMD_IRQREQB (0x024)
+#define IOMD_IRQMASKB (0x028)
+
+#define IOMD_FIQSTAT (0x030)
+#define IOMD_FIQREQ (0x034)
+#define IOMD_FIQMASK (0x038)
+
+#define IOMD_T0CNTL (0x040)
+#define IOMD_T0LTCHL (0x040)
+#define IOMD_T0CNTH (0x044)
+#define IOMD_T0LTCHH (0x044)
+#define IOMD_T0GO (0x048)
+#define IOMD_T0LATCH (0x04c)
+
+#define IOMD_T1CNTL (0x050)
+#define IOMD_T1LTCHL (0x050)
+#define IOMD_T1CNTH (0x054)
+#define IOMD_T1LTCHH (0x054)
+#define IOMD_T1GO (0x058)
+#define IOMD_T1LATCH (0x05c)
+
+#define IOMD_ROMCR0 (0x080)
+#define IOMD_ROMCR1 (0x084)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DRAMCR (0x088)
+#endif
+#define IOMD_REFCR (0x08C)
+
+#define IOMD_FSIZE (0x090)
+#define IOMD_ID0 (0x094)
+#define IOMD_ID1 (0x098)
+#define IOMD_VERSION (0x09C)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_MOUSEX (0x0A0)
+#define IOMD_MOUSEY (0x0A4)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMATCR (0x0C0)
+#endif
+#define IOMD_IOTCR (0x0C4)
+#define IOMD_ECTCR (0x0C8)
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_DMAEXT (0x0CC)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+#define DMA_EXT_IO0 1
+#define DMA_EXT_IO1 2
+#define DMA_EXT_IO2 4
+#define DMA_EXT_IO3 8
+
+#define IOMD_IO0CURA (0x100)
+#define IOMD_IO0ENDA (0x104)
+#define IOMD_IO0CURB (0x108)
+#define IOMD_IO0ENDB (0x10C)
+#define IOMD_IO0CR (0x110)
+#define IOMD_IO0ST (0x114)
+
+#define IOMD_IO1CURA (0x120)
+#define IOMD_IO1ENDA (0x124)
+#define IOMD_IO1CURB (0x128)
+#define IOMD_IO1ENDB (0x12C)
+#define IOMD_IO1CR (0x130)
+#define IOMD_IO1ST (0x134)
+
+#define IOMD_IO2CURA (0x140)
+#define IOMD_IO2ENDA (0x144)
+#define IOMD_IO2CURB (0x148)
+#define IOMD_IO2ENDB (0x14C)
+#define IOMD_IO2CR (0x150)
+#define IOMD_IO2ST (0x154)
+
+#define IOMD_IO3CURA (0x160)
+#define IOMD_IO3ENDA (0x164)
+#define IOMD_IO3CURB (0x168)
+#define IOMD_IO3ENDB (0x16C)
+#define IOMD_IO3CR (0x170)
+#define IOMD_IO3ST (0x174)
+#endif
+
+#define IOMD_SD0CURA (0x180)
+#define IOMD_SD0ENDA (0x184)
+#define IOMD_SD0CURB (0x188)
+#define IOMD_SD0ENDB (0x18C)
+#define IOMD_SD0CR (0x190)
+#define IOMD_SD0ST (0x194)
+
+#ifdef CONFIG_ARCH_RPC
+#define IOMD_SD1CURA (0x1A0)
+#define IOMD_SD1ENDA (0x1A4)
+#define IOMD_SD1CURB (0x1A8)
+#define IOMD_SD1ENDB (0x1AC)
+#define IOMD_SD1CR (0x1B0)
+#define IOMD_SD1ST (0x1B4)
+#endif
+
+#define IOMD_CURSCUR (0x1C0)
+#define IOMD_CURSINIT (0x1C4)
+
+#define IOMD_VIDCUR (0x1D0)
+#define IOMD_VIDEND (0x1D4)
+#define IOMD_VIDSTART (0x1D8)
+#define IOMD_VIDINIT (0x1DC)
+#define IOMD_VIDCR (0x1E0)
+
+#define IOMD_DMASTAT (0x1F0)
+#define IOMD_DMAREQ (0x1F4)
+#define IOMD_DMAMASK (0x1F8)
+
+#define DMA_END_S (1 << 31)
+#define DMA_END_L (1 << 30)
+
+#define DMA_CR_C 0x80
+#define DMA_CR_D 0x40
+#define DMA_CR_E 0x20
+
+#define DMA_ST_OFL 4
+#define DMA_ST_INT 2
+#define DMA_ST_AB 1
+
+/*
+ * DMA (MEMC) compatibility
+ */
+#define HALF_SAM vram_half_sam
+#define VDMA_ALIGNMENT (HALF_SAM * 2)
+#define VDMA_XFERSIZE (HALF_SAM)
+#define VDMA_INIT IOMD_VIDINIT
+#define VDMA_START IOMD_VIDSTART
+#define VDMA_END IOMD_VIDEND
+
+#ifndef __ASSEMBLY__
+extern unsigned int vram_half_sam;
+#define video_set_dma(start,end,offset) \
+do { \
+ outl (SCREEN_START + start, VDMA_START); \
+ outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \
+ if (offset >= end - VDMA_XFERSIZE) \
+ offset |= 0x40000000; \
+ outl (SCREEN_START + offset, VDMA_INIT); \
+} while (0)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h
new file mode 100644
index 00000000..9b28f124
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop3xx-adma.h
@@ -0,0 +1,962 @@
+/*
+ * Copyright © 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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.
+ *
+ */
+#ifndef _ADMA_H
+#define _ADMA_H
+#include <linux/types.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iop_adma.h>
+
+/* Memory copy units */
+#define DMA_CCR(chan) (chan->mmr_base + 0x0)
+#define DMA_CSR(chan) (chan->mmr_base + 0x4)
+#define DMA_DAR(chan) (chan->mmr_base + 0xc)
+#define DMA_NDAR(chan) (chan->mmr_base + 0x10)
+#define DMA_PADR(chan) (chan->mmr_base + 0x14)
+#define DMA_PUADR(chan) (chan->mmr_base + 0x18)
+#define DMA_LADR(chan) (chan->mmr_base + 0x1c)
+#define DMA_BCR(chan) (chan->mmr_base + 0x20)
+#define DMA_DCR(chan) (chan->mmr_base + 0x24)
+
+/* Application accelerator unit */
+#define AAU_ACR(chan) (chan->mmr_base + 0x0)
+#define AAU_ASR(chan) (chan->mmr_base + 0x4)
+#define AAU_ADAR(chan) (chan->mmr_base + 0x8)
+#define AAU_ANDAR(chan) (chan->mmr_base + 0xc)
+#define AAU_SAR(src, chan) (chan->mmr_base + (0x10 + ((src) << 2)))
+#define AAU_DAR(chan) (chan->mmr_base + 0x20)
+#define AAU_ABCR(chan) (chan->mmr_base + 0x24)
+#define AAU_ADCR(chan) (chan->mmr_base + 0x28)
+#define AAU_SAR_EDCR(src_edc) (chan->mmr_base + (0x02c + ((src_edc-4) << 2)))
+#define AAU_EDCR0_IDX 8
+#define AAU_EDCR1_IDX 17
+#define AAU_EDCR2_IDX 26
+
+#define DMA0_ID 0
+#define DMA1_ID 1
+#define AAU_ID 2
+
+struct iop3xx_aau_desc_ctrl {
+ unsigned int int_en:1;
+ unsigned int blk1_cmd_ctrl:3;
+ unsigned int blk2_cmd_ctrl:3;
+ unsigned int blk3_cmd_ctrl:3;
+ unsigned int blk4_cmd_ctrl:3;
+ unsigned int blk5_cmd_ctrl:3;
+ unsigned int blk6_cmd_ctrl:3;
+ unsigned int blk7_cmd_ctrl:3;
+ unsigned int blk8_cmd_ctrl:3;
+ unsigned int blk_ctrl:2;
+ unsigned int dual_xor_en:1;
+ unsigned int tx_complete:1;
+ unsigned int zero_result_err:1;
+ unsigned int zero_result_en:1;
+ unsigned int dest_write_en:1;
+};
+
+struct iop3xx_aau_e_desc_ctrl {
+ unsigned int reserved:1;
+ unsigned int blk1_cmd_ctrl:3;
+ unsigned int blk2_cmd_ctrl:3;
+ unsigned int blk3_cmd_ctrl:3;
+ unsigned int blk4_cmd_ctrl:3;
+ unsigned int blk5_cmd_ctrl:3;
+ unsigned int blk6_cmd_ctrl:3;
+ unsigned int blk7_cmd_ctrl:3;
+ unsigned int blk8_cmd_ctrl:3;
+ unsigned int reserved2:7;
+};
+
+struct iop3xx_dma_desc_ctrl {
+ unsigned int pci_transaction:4;
+ unsigned int int_en:1;
+ unsigned int dac_cycle_en:1;
+ unsigned int mem_to_mem_en:1;
+ unsigned int crc_data_tx_en:1;
+ unsigned int crc_gen_en:1;
+ unsigned int crc_seed_dis:1;
+ unsigned int reserved:21;
+ unsigned int crc_tx_complete:1;
+};
+
+struct iop3xx_desc_dma {
+ u32 next_desc;
+ union {
+ u32 pci_src_addr;
+ u32 pci_dest_addr;
+ u32 src_addr;
+ };
+ union {
+ u32 upper_pci_src_addr;
+ u32 upper_pci_dest_addr;
+ };
+ union {
+ u32 local_pci_src_addr;
+ u32 local_pci_dest_addr;
+ u32 dest_addr;
+ };
+ u32 byte_count;
+ union {
+ u32 desc_ctrl;
+ struct iop3xx_dma_desc_ctrl desc_ctrl_field;
+ };
+ u32 crc_addr;
+};
+
+struct iop3xx_desc_aau {
+ u32 next_desc;
+ u32 src[4];
+ u32 dest_addr;
+ u32 byte_count;
+ union {
+ u32 desc_ctrl;
+ struct iop3xx_aau_desc_ctrl desc_ctrl_field;
+ };
+ union {
+ u32 src_addr;
+ u32 e_desc_ctrl;
+ struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
+ } src_edc[31];
+};
+
+struct iop3xx_aau_gfmr {
+ unsigned int gfmr1:8;
+ unsigned int gfmr2:8;
+ unsigned int gfmr3:8;
+ unsigned int gfmr4:8;
+};
+
+struct iop3xx_desc_pq_xor {
+ u32 next_desc;
+ u32 src[3];
+ union {
+ u32 data_mult1;
+ struct iop3xx_aau_gfmr data_mult1_field;
+ };
+ u32 dest_addr;
+ u32 byte_count;
+ union {
+ u32 desc_ctrl;
+ struct iop3xx_aau_desc_ctrl desc_ctrl_field;
+ };
+ union {
+ u32 src_addr;
+ u32 e_desc_ctrl;
+ struct iop3xx_aau_e_desc_ctrl e_desc_ctrl_field;
+ u32 data_multiplier;
+ struct iop3xx_aau_gfmr data_mult_field;
+ u32 reserved;
+ } src_edc_gfmr[19];
+};
+
+struct iop3xx_desc_dual_xor {
+ u32 next_desc;
+ u32 src0_addr;
+ u32 src1_addr;
+ u32 h_src_addr;
+ u32 d_src_addr;
+ u32 h_dest_addr;
+ u32 byte_count;
+ union {
+ u32 desc_ctrl;
+ struct iop3xx_aau_desc_ctrl desc_ctrl_field;
+ };
+ u32 d_dest_addr;
+};
+
+union iop3xx_desc {
+ struct iop3xx_desc_aau *aau;
+ struct iop3xx_desc_dma *dma;
+ struct iop3xx_desc_pq_xor *pq_xor;
+ struct iop3xx_desc_dual_xor *dual_xor;
+ void *ptr;
+};
+
+/* No support for p+q operations */
+static inline int
+iop_chan_pq_slot_count(size_t len, int src_cnt, int *slots_per_op)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ BUG();
+}
+
+static inline void
+iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
+{
+ BUG();
+}
+
+static inline void
+iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
+ dma_addr_t addr, unsigned char coef)
+{
+ BUG();
+}
+
+static inline int
+iop_chan_pq_zero_sum_slot_count(size_t len, int src_cnt, int *slots_per_op)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ BUG();
+}
+
+static inline void
+iop_desc_set_pq_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
+{
+ BUG();
+}
+
+#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
+
+static inline void
+iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
+ dma_addr_t *src)
+{
+ BUG();
+}
+
+static inline int iop_adma_get_max_xor(void)
+{
+ return 32;
+}
+
+static inline int iop_adma_get_max_pq(void)
+{
+ BUG();
+ return 0;
+}
+
+static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
+{
+ int id = chan->device->id;
+
+ switch (id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return __raw_readl(DMA_DAR(chan));
+ case AAU_ID:
+ return __raw_readl(AAU_ADAR(chan));
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
+ u32 next_desc_addr)
+{
+ int id = chan->device->id;
+
+ switch (id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ __raw_writel(next_desc_addr, DMA_NDAR(chan));
+ break;
+ case AAU_ID:
+ __raw_writel(next_desc_addr, AAU_ANDAR(chan));
+ break;
+ }
+
+}
+
+#define IOP_ADMA_STATUS_BUSY (1 << 10)
+#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT (1024)
+#define IOP_ADMA_XOR_MAX_BYTE_COUNT (16 * 1024 * 1024)
+#define IOP_ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)
+
+static inline int iop_chan_is_busy(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(DMA_CSR(chan));
+ return (status & IOP_ADMA_STATUS_BUSY) ? 1 : 0;
+}
+
+static inline int iop_desc_is_aligned(struct iop_adma_desc_slot *desc,
+ int num_slots)
+{
+ /* num_slots will only ever be 1, 2, 4, or 8 */
+ return (desc->idx & (num_slots - 1)) ? 0 : 1;
+}
+
+/* to do: support large (i.e. > hw max) buffer sizes */
+static inline int iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
+{
+ *slots_per_op = 1;
+ return 1;
+}
+
+/* to do: support large (i.e. > hw max) buffer sizes */
+static inline int iop_chan_memset_slot_count(size_t len, int *slots_per_op)
+{
+ *slots_per_op = 1;
+ return 1;
+}
+
+static inline int iop3xx_aau_xor_slot_count(size_t len, int src_cnt,
+ int *slots_per_op)
+{
+ static const char slot_count_table[] = {
+ 1, 1, 1, 1, /* 01 - 04 */
+ 2, 2, 2, 2, /* 05 - 08 */
+ 4, 4, 4, 4, /* 09 - 12 */
+ 4, 4, 4, 4, /* 13 - 16 */
+ 8, 8, 8, 8, /* 17 - 20 */
+ 8, 8, 8, 8, /* 21 - 24 */
+ 8, 8, 8, 8, /* 25 - 28 */
+ 8, 8, 8, 8, /* 29 - 32 */
+ };
+ *slots_per_op = slot_count_table[src_cnt - 1];
+ return *slots_per_op;
+}
+
+static inline int
+iop_chan_interrupt_slot_count(int *slots_per_op, struct iop_adma_chan *chan)
+{
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return iop_chan_memcpy_slot_count(0, slots_per_op);
+ case AAU_ID:
+ return iop3xx_aau_xor_slot_count(0, 2, slots_per_op);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static inline int iop_chan_xor_slot_count(size_t len, int src_cnt,
+ int *slots_per_op)
+{
+ int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
+
+ if (len <= IOP_ADMA_XOR_MAX_BYTE_COUNT)
+ return slot_cnt;
+
+ len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
+ while (len > IOP_ADMA_XOR_MAX_BYTE_COUNT) {
+ len -= IOP_ADMA_XOR_MAX_BYTE_COUNT;
+ slot_cnt += *slots_per_op;
+ }
+
+ slot_cnt += *slots_per_op;
+
+ return slot_cnt;
+}
+
+/* zero sum on iop3xx is limited to 1k at a time so it requires multiple
+ * descriptors
+ */
+static inline int iop_chan_zero_sum_slot_count(size_t len, int src_cnt,
+ int *slots_per_op)
+{
+ int slot_cnt = iop3xx_aau_xor_slot_count(len, src_cnt, slots_per_op);
+
+ if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT)
+ return slot_cnt;
+
+ len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
+ len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ slot_cnt += *slots_per_op;
+ }
+
+ slot_cnt += *slots_per_op;
+
+ return slot_cnt;
+}
+
+static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
+{
+ return 0;
+}
+
+static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return hw_desc.dma->dest_addr;
+ case AAU_ID:
+ return hw_desc.aau->dest_addr;
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+
+static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ BUG();
+ return 0;
+}
+
+static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return hw_desc.dma->byte_count;
+ case AAU_ID:
+ return hw_desc.aau->byte_count;
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+/* translate the src_idx to a descriptor word index */
+static inline int __desc_idx(int src_idx)
+{
+ static const int desc_idx_table[] = { 0, 0, 0, 0,
+ 0, 1, 2, 3,
+ 5, 6, 7, 8,
+ 9, 10, 11, 12,
+ 14, 15, 16, 17,
+ 18, 19, 20, 21,
+ 23, 24, 25, 26,
+ 27, 28, 29, 30,
+ };
+
+ return desc_idx_table[src_idx];
+}
+
+static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ int src_idx)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return hw_desc.dma->src_addr;
+ case AAU_ID:
+ break;
+ default:
+ BUG();
+ }
+
+ if (src_idx < 4)
+ return hw_desc.aau->src[src_idx];
+ else
+ return hw_desc.aau->src_edc[__desc_idx(src_idx)].src_addr;
+}
+
+static inline void iop3xx_aau_desc_set_src_addr(struct iop3xx_desc_aau *hw_desc,
+ int src_idx, dma_addr_t addr)
+{
+ if (src_idx < 4)
+ hw_desc->src[src_idx] = addr;
+ else
+ hw_desc->src_edc[__desc_idx(src_idx)].src_addr = addr;
+}
+
+static inline void
+iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
+{
+ struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop3xx_dma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.mem_to_mem_en = 1;
+ u_desc_ctrl.field.pci_transaction = 0xe; /* memory read block */
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+ hw_desc->upper_pci_src_addr = 0;
+ hw_desc->crc_addr = 0;
+}
+
+static inline void
+iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
+{
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop3xx_aau_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.blk1_cmd_ctrl = 0x2; /* memory block fill */
+ u_desc_ctrl.field.dest_write_en = 1;
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+}
+
+static inline u32
+iop3xx_desc_init_xor(struct iop3xx_desc_aau *hw_desc, int src_cnt,
+ unsigned long flags)
+{
+ int i, shift;
+ u32 edcr;
+ union {
+ u32 value;
+ struct iop3xx_aau_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ switch (src_cnt) {
+ case 25 ... 32:
+ u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
+ edcr = 0;
+ shift = 1;
+ for (i = 24; i < src_cnt; i++) {
+ edcr |= (1 << shift);
+ shift += 3;
+ }
+ hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = edcr;
+ src_cnt = 24;
+ /* fall through */
+ case 17 ... 24:
+ if (!u_desc_ctrl.field.blk_ctrl) {
+ hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
+ u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
+ }
+ edcr = 0;
+ shift = 1;
+ for (i = 16; i < src_cnt; i++) {
+ edcr |= (1 << shift);
+ shift += 3;
+ }
+ hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = edcr;
+ src_cnt = 16;
+ /* fall through */
+ case 9 ... 16:
+ if (!u_desc_ctrl.field.blk_ctrl)
+ u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
+ edcr = 0;
+ shift = 1;
+ for (i = 8; i < src_cnt; i++) {
+ edcr |= (1 << shift);
+ shift += 3;
+ }
+ hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = edcr;
+ src_cnt = 8;
+ /* fall through */
+ case 2 ... 8:
+ shift = 1;
+ for (i = 0; i < src_cnt; i++) {
+ u_desc_ctrl.value |= (1 << shift);
+ shift += 3;
+ }
+
+ if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
+ u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
+ }
+
+ u_desc_ctrl.field.dest_write_en = 1;
+ u_desc_ctrl.field.blk1_cmd_ctrl = 0x7; /* direct fill */
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+
+ return u_desc_ctrl.value;
+}
+
+static inline void
+iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ iop3xx_desc_init_xor(desc->hw_desc, src_cnt, flags);
+}
+
+/* return the number of operations */
+static inline int
+iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
+ struct iop3xx_desc_aau *hw_desc, *prev_hw_desc, *iter;
+ union {
+ u32 value;
+ struct iop3xx_aau_desc_ctrl field;
+ } u_desc_ctrl;
+ int i, j;
+
+ hw_desc = desc->hw_desc;
+
+ for (i = 0, j = 0; (slot_cnt -= slots_per_op) >= 0;
+ i += slots_per_op, j++) {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ u_desc_ctrl.value = iop3xx_desc_init_xor(iter, src_cnt, flags);
+ u_desc_ctrl.field.dest_write_en = 0;
+ u_desc_ctrl.field.zero_result_en = 1;
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ iter->desc_ctrl = u_desc_ctrl.value;
+
+ /* for the subsequent descriptors preserve the store queue
+ * and chain them together
+ */
+ if (i) {
+ prev_hw_desc =
+ iop_hw_desc_slot_idx(hw_desc, i - slots_per_op);
+ prev_hw_desc->next_desc =
+ (u32) (desc->async_tx.phys + (i << 5));
+ }
+ }
+
+ return j;
+}
+
+static inline void
+iop_desc_init_null_xor(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop3xx_aau_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ switch (src_cnt) {
+ case 25 ... 32:
+ u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
+ hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
+ /* fall through */
+ case 17 ... 24:
+ if (!u_desc_ctrl.field.blk_ctrl) {
+ hw_desc->src_edc[AAU_EDCR2_IDX].e_desc_ctrl = 0;
+ u_desc_ctrl.field.blk_ctrl = 0x3; /* use EDCR[2:0] */
+ }
+ hw_desc->src_edc[AAU_EDCR1_IDX].e_desc_ctrl = 0;
+ /* fall through */
+ case 9 ... 16:
+ if (!u_desc_ctrl.field.blk_ctrl)
+ u_desc_ctrl.field.blk_ctrl = 0x2; /* use EDCR0 */
+ hw_desc->src_edc[AAU_EDCR0_IDX].e_desc_ctrl = 0;
+ /* fall through */
+ case 1 ... 8:
+ if (!u_desc_ctrl.field.blk_ctrl && src_cnt > 4)
+ u_desc_ctrl.field.blk_ctrl = 0x1; /* use mini-desc */
+ }
+
+ u_desc_ctrl.field.dest_write_en = 0;
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+}
+
+static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ u32 byte_count)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ hw_desc.dma->byte_count = byte_count;
+ break;
+ case AAU_ID:
+ hw_desc.aau->byte_count = byte_count;
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void
+iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ iop_desc_init_memcpy(desc, 1);
+ hw_desc.dma->byte_count = 0;
+ hw_desc.dma->dest_addr = 0;
+ hw_desc.dma->src_addr = 0;
+ break;
+ case AAU_ID:
+ iop_desc_init_null_xor(desc, 2, 1);
+ hw_desc.aau->byte_count = 0;
+ hw_desc.aau->dest_addr = 0;
+ hw_desc.aau->src[0] = 0;
+ hw_desc.aau->src[1] = 0;
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void
+iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
+{
+ int slots_per_op = desc->slots_per_op;
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
+ int i = 0;
+
+ if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
+ hw_desc->byte_count = len;
+ } else {
+ do {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ i += slots_per_op;
+ } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
+
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iter->byte_count = len;
+ }
+}
+
+static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ dma_addr_t addr)
+{
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ hw_desc.dma->dest_addr = addr;
+ break;
+ case AAU_ID:
+ hw_desc.aau->dest_addr = addr;
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
+ dma_addr_t addr)
+{
+ struct iop3xx_desc_dma *hw_desc = desc->hw_desc;
+ hw_desc->src_addr = addr;
+}
+
+static inline void
+iop_desc_set_zero_sum_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
+ dma_addr_t addr)
+{
+
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
+ int i;
+
+ for (i = 0; (slot_cnt -= slots_per_op) >= 0;
+ i += slots_per_op, addr += IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
+ }
+}
+
+static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
+ int src_idx, dma_addr_t addr)
+{
+
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc, *iter;
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
+ int i;
+
+ for (i = 0; (slot_cnt -= slots_per_op) >= 0;
+ i += slots_per_op, addr += IOP_ADMA_XOR_MAX_BYTE_COUNT) {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iop3xx_aau_desc_set_src_addr(iter, src_idx, addr);
+ }
+}
+
+static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
+ u32 next_desc_addr)
+{
+ /* hw_desc->next_desc is the same location for all channels */
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+
+ iop_paranoia(hw_desc.dma->next_desc);
+ hw_desc.dma->next_desc = next_desc_addr;
+}
+
+static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
+{
+ /* hw_desc->next_desc is the same location for all channels */
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+ return hw_desc.dma->next_desc;
+}
+
+static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
+{
+ /* hw_desc->next_desc is the same location for all channels */
+ union iop3xx_desc hw_desc = { .ptr = desc->hw_desc, };
+ hw_desc.dma->next_desc = 0;
+}
+
+static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
+ u32 val)
+{
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
+ hw_desc->src[0] = val;
+}
+
+static inline enum sum_check_flags
+iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
+{
+ struct iop3xx_desc_aau *hw_desc = desc->hw_desc;
+ struct iop3xx_aau_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
+
+ iop_paranoia(!(desc_ctrl.tx_complete && desc_ctrl.zero_result_en));
+ return desc_ctrl.zero_result_err << SUM_CHECK_P;
+}
+
+static inline void iop_chan_append(struct iop_adma_chan *chan)
+{
+ u32 dma_chan_ctrl;
+
+ dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
+ dma_chan_ctrl |= 0x2;
+ __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
+}
+
+static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
+{
+ return __raw_readl(DMA_CSR(chan));
+}
+
+static inline void iop_chan_disable(struct iop_adma_chan *chan)
+{
+ u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
+ dma_chan_ctrl &= ~1;
+ __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
+}
+
+static inline void iop_chan_enable(struct iop_adma_chan *chan)
+{
+ u32 dma_chan_ctrl = __raw_readl(DMA_CCR(chan));
+
+ dma_chan_ctrl |= 1;
+ __raw_writel(dma_chan_ctrl, DMA_CCR(chan));
+}
+
+static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(DMA_CSR(chan));
+ status &= (1 << 9);
+ __raw_writel(status, DMA_CSR(chan));
+}
+
+static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(DMA_CSR(chan));
+ status &= (1 << 8);
+ __raw_writel(status, DMA_CSR(chan));
+}
+
+static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(DMA_CSR(chan));
+
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ status &= (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1);
+ break;
+ case AAU_ID:
+ status &= (1 << 5);
+ break;
+ default:
+ BUG();
+ }
+
+ __raw_writel(status, DMA_CSR(chan));
+}
+
+static inline int
+iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+static inline int
+iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+static inline int
+iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+static inline int
+iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return test_bit(5, &status);
+}
+
+static inline int
+iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return test_bit(2, &status);
+ default:
+ return 0;
+ }
+}
+
+static inline int
+iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return test_bit(3, &status);
+ default:
+ return 0;
+ }
+}
+
+static inline int
+iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
+{
+ switch (chan->device->id) {
+ case DMA0_ID:
+ case DMA1_ID:
+ return test_bit(1, &status);
+ default:
+ return 0;
+ }
+}
+#endif /* _ADMA_H */
diff --git a/arch/arm/include/asm/hardware/iop3xx-gpio.h b/arch/arm/include/asm/hardware/iop3xx-gpio.h
new file mode 100644
index 00000000..b69d972b
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop3xx-gpio.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/include/asm/hardware/iop3xx-gpio.h
+ *
+ * IOP3xx GPIO wrappers
+ *
+ * Copyright (c) 2008 Arnaud Patard <arnaud.patard@rtp-net.org>
+ * Based on IXP4XX gpio.h file
+ *
+ * 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 __ASM_ARM_HARDWARE_IOP3XX_GPIO_H
+#define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H
+
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define IOP3XX_N_GPIOS 8
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (gpio > IOP3XX_N_GPIOS)
+ return __gpio_get_value(gpio);
+
+ return gpio_line_get(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio > IOP3XX_N_GPIOS) {
+ __gpio_set_value(gpio, value);
+ return;
+ }
+ gpio_line_set(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ if (gpio < IOP3XX_N_GPIOS)
+ return 0;
+ else
+ return __gpio_cansleep(gpio);
+}
+
+/*
+ * The GPIOs are not generating any interrupt
+ * Note : manuals are not clear about this
+ */
+static inline int gpio_to_irq(int gpio)
+{
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(int gpio)
+{
+ return -EINVAL;
+}
+
+#endif
+
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h
new file mode 100644
index 00000000..5daea296
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop3xx.h
@@ -0,0 +1,329 @@
+/*
+ * arch/arm/include/asm/hardware/iop3xx.h
+ *
+ * Intel IOP32X and IOP33X register definitions
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can 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 __IOP3XX_H
+#define __IOP3XX_H
+
+/*
+ * IOP3XX GPIO handling
+ */
+#define GPIO_IN 0
+#define GPIO_OUT 1
+#define GPIO_LOW 0
+#define GPIO_HIGH 1
+#define IOP3XX_GPIO_LINE(x) (x)
+
+#ifndef __ASSEMBLY__
+extern void gpio_line_config(int line, int direction);
+extern int gpio_line_get(int line);
+extern void gpio_line_set(int line, int value);
+extern int init_atu;
+extern int iop3xx_get_init_atu(void);
+#endif
+
+
+/*
+ * IOP3XX processor registers
+ */
+#define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000
+#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000
+#define IOP3XX_PERIPHERAL_SIZE 0x00002000
+#define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\
+ IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\
+ IOP3XX_PERIPHERAL_SIZE - 1)
+#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) (addr) -\
+ (IOP3XX_PERIPHERAL_PHYS_BASE\
+ - IOP3XX_PERIPHERAL_VIRT_BASE))
+#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
+
+/* Address Translation Unit */
+#define IOP3XX_ATUVID (volatile u16 *)IOP3XX_REG_ADDR(0x0100)
+#define IOP3XX_ATUDID (volatile u16 *)IOP3XX_REG_ADDR(0x0102)
+#define IOP3XX_ATUCMD (volatile u16 *)IOP3XX_REG_ADDR(0x0104)
+#define IOP3XX_ATUSR (volatile u16 *)IOP3XX_REG_ADDR(0x0106)
+#define IOP3XX_ATURID (volatile u8 *)IOP3XX_REG_ADDR(0x0108)
+#define IOP3XX_ATUCCR (volatile u32 *)IOP3XX_REG_ADDR(0x0109)
+#define IOP3XX_ATUCLSR (volatile u8 *)IOP3XX_REG_ADDR(0x010c)
+#define IOP3XX_ATULT (volatile u8 *)IOP3XX_REG_ADDR(0x010d)
+#define IOP3XX_ATUHTR (volatile u8 *)IOP3XX_REG_ADDR(0x010e)
+#define IOP3XX_ATUBIST (volatile u8 *)IOP3XX_REG_ADDR(0x010f)
+#define IOP3XX_IABAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0110)
+#define IOP3XX_IAUBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0114)
+#define IOP3XX_IABAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0118)
+#define IOP3XX_IAUBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x011c)
+#define IOP3XX_IABAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0120)
+#define IOP3XX_IAUBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0124)
+#define IOP3XX_ASVIR (volatile u16 *)IOP3XX_REG_ADDR(0x012c)
+#define IOP3XX_ASIR (volatile u16 *)IOP3XX_REG_ADDR(0x012e)
+#define IOP3XX_ERBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0130)
+#define IOP3XX_ATUILR (volatile u8 *)IOP3XX_REG_ADDR(0x013c)
+#define IOP3XX_ATUIPR (volatile u8 *)IOP3XX_REG_ADDR(0x013d)
+#define IOP3XX_ATUMGNT (volatile u8 *)IOP3XX_REG_ADDR(0x013e)
+#define IOP3XX_ATUMLAT (volatile u8 *)IOP3XX_REG_ADDR(0x013f)
+#define IOP3XX_IALR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0140)
+#define IOP3XX_IATVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0144)
+#define IOP3XX_ERLR (volatile u32 *)IOP3XX_REG_ADDR(0x0148)
+#define IOP3XX_ERTVR (volatile u32 *)IOP3XX_REG_ADDR(0x014c)
+#define IOP3XX_IALR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0150)
+#define IOP3XX_IALR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0154)
+#define IOP3XX_IATVR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0158)
+#define IOP3XX_OIOWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x015c)
+#define IOP3XX_OMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0160)
+#define IOP3XX_OUMWTVR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0164)
+#define IOP3XX_OMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0168)
+#define IOP3XX_OUMWTVR1 (volatile u32 *)IOP3XX_REG_ADDR(0x016c)
+#define IOP3XX_OUDWTVR (volatile u32 *)IOP3XX_REG_ADDR(0x0178)
+#define IOP3XX_ATUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0180)
+#define IOP3XX_PCSR (volatile u32 *)IOP3XX_REG_ADDR(0x0184)
+#define IOP3XX_ATUISR (volatile u32 *)IOP3XX_REG_ADDR(0x0188)
+#define IOP3XX_ATUIMR (volatile u32 *)IOP3XX_REG_ADDR(0x018c)
+#define IOP3XX_IABAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0190)
+#define IOP3XX_IAUBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0194)
+#define IOP3XX_IALR3 (volatile u32 *)IOP3XX_REG_ADDR(0x0198)
+#define IOP3XX_IATVR3 (volatile u32 *)IOP3XX_REG_ADDR(0x019c)
+#define IOP3XX_OCCAR (volatile u32 *)IOP3XX_REG_ADDR(0x01a4)
+#define IOP3XX_OCCDR (volatile u32 *)IOP3XX_REG_ADDR(0x01ac)
+#define IOP3XX_PDSCR (volatile u32 *)IOP3XX_REG_ADDR(0x01bc)
+#define IOP3XX_PMCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01c0)
+#define IOP3XX_PMNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01c1)
+#define IOP3XX_APMCR (volatile u16 *)IOP3XX_REG_ADDR(0x01c2)
+#define IOP3XX_APMCSR (volatile u16 *)IOP3XX_REG_ADDR(0x01c4)
+#define IOP3XX_PCIXCAPID (volatile u8 *)IOP3XX_REG_ADDR(0x01e0)
+#define IOP3XX_PCIXNEXT (volatile u8 *)IOP3XX_REG_ADDR(0x01e1)
+#define IOP3XX_PCIXCMD (volatile u16 *)IOP3XX_REG_ADDR(0x01e2)
+#define IOP3XX_PCIXSR (volatile u32 *)IOP3XX_REG_ADDR(0x01e4)
+#define IOP3XX_PCIIRSR (volatile u32 *)IOP3XX_REG_ADDR(0x01ec)
+#define IOP3XX_PCSR_OUT_Q_BUSY (1 << 15)
+#define IOP3XX_PCSR_IN_Q_BUSY (1 << 14)
+#define IOP3XX_ATUCR_OUT_EN (1 << 1)
+
+#define IOP3XX_INIT_ATU_DEFAULT 0
+#define IOP3XX_INIT_ATU_DISABLE -1
+#define IOP3XX_INIT_ATU_ENABLE 1
+
+/* Messaging Unit */
+#define IOP3XX_IMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0310)
+#define IOP3XX_IMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0314)
+#define IOP3XX_OMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0318)
+#define IOP3XX_OMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x031c)
+#define IOP3XX_IDR (volatile u32 *)IOP3XX_REG_ADDR(0x0320)
+#define IOP3XX_IISR (volatile u32 *)IOP3XX_REG_ADDR(0x0324)
+#define IOP3XX_IIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0328)
+#define IOP3XX_ODR (volatile u32 *)IOP3XX_REG_ADDR(0x032c)
+#define IOP3XX_OISR (volatile u32 *)IOP3XX_REG_ADDR(0x0330)
+#define IOP3XX_OIMR (volatile u32 *)IOP3XX_REG_ADDR(0x0334)
+#define IOP3XX_MUCR (volatile u32 *)IOP3XX_REG_ADDR(0x0350)
+#define IOP3XX_QBAR (volatile u32 *)IOP3XX_REG_ADDR(0x0354)
+#define IOP3XX_IFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0360)
+#define IOP3XX_IFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0364)
+#define IOP3XX_IPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0368)
+#define IOP3XX_IPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x036c)
+#define IOP3XX_OFHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0370)
+#define IOP3XX_OFTPR (volatile u32 *)IOP3XX_REG_ADDR(0x0374)
+#define IOP3XX_OPHPR (volatile u32 *)IOP3XX_REG_ADDR(0x0378)
+#define IOP3XX_OPTPR (volatile u32 *)IOP3XX_REG_ADDR(0x037c)
+#define IOP3XX_IAR (volatile u32 *)IOP3XX_REG_ADDR(0x0380)
+
+/* DMA Controller */
+#define IOP3XX_DMA_PHYS_BASE(chan) (IOP3XX_PERIPHERAL_PHYS_BASE + \
+ (0x400 + (chan << 6)))
+#define IOP3XX_DMA_UPPER_PA(chan) (IOP3XX_DMA_PHYS_BASE(chan) + 0x27)
+
+/* Peripheral bus interface */
+#define IOP3XX_PBCR (volatile u32 *)IOP3XX_REG_ADDR(0x0680)
+#define IOP3XX_PBISR (volatile u32 *)IOP3XX_REG_ADDR(0x0684)
+#define IOP3XX_PBBAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0688)
+#define IOP3XX_PBLR0 (volatile u32 *)IOP3XX_REG_ADDR(0x068c)
+#define IOP3XX_PBBAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0690)
+#define IOP3XX_PBLR1 (volatile u32 *)IOP3XX_REG_ADDR(0x0694)
+#define IOP3XX_PBBAR2 (volatile u32 *)IOP3XX_REG_ADDR(0x0698)
+#define IOP3XX_PBLR2 (volatile u32 *)IOP3XX_REG_ADDR(0x069c)
+#define IOP3XX_PBBAR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a0)
+#define IOP3XX_PBLR3 (volatile u32 *)IOP3XX_REG_ADDR(0x06a4)
+#define IOP3XX_PBBAR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06a8)
+#define IOP3XX_PBLR4 (volatile u32 *)IOP3XX_REG_ADDR(0x06ac)
+#define IOP3XX_PBBAR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b0)
+#define IOP3XX_PBLR5 (volatile u32 *)IOP3XX_REG_ADDR(0x06b4)
+#define IOP3XX_PMBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x06c0)
+#define IOP3XX_PMBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x06e0)
+#define IOP3XX_PMBR2 (volatile u32 *)IOP3XX_REG_ADDR(0x06e4)
+
+/* Peripheral performance monitoring unit */
+#define IOP3XX_GTMR (volatile u32 *)IOP3XX_REG_ADDR(0x0700)
+#define IOP3XX_ESR (volatile u32 *)IOP3XX_REG_ADDR(0x0704)
+#define IOP3XX_EMISR (volatile u32 *)IOP3XX_REG_ADDR(0x0708)
+#define IOP3XX_GTSR (volatile u32 *)IOP3XX_REG_ADDR(0x0710)
+/* PERCR0 DOESN'T EXIST - index from 1! */
+#define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710)
+
+/* General Purpose I/O */
+#define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0000)
+#define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0004)
+#define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x0008)
+
+/* Timers */
+#define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000)
+#define IOP3XX_TU_TMR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0004)
+#define IOP3XX_TU_TCR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0008)
+#define IOP3XX_TU_TCR1 (volatile u32 *)IOP3XX_TIMER_REG(0x000c)
+#define IOP3XX_TU_TRR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0010)
+#define IOP3XX_TU_TRR1 (volatile u32 *)IOP3XX_TIMER_REG(0x0014)
+#define IOP3XX_TU_TISR (volatile u32 *)IOP3XX_TIMER_REG(0x0018)
+#define IOP3XX_TU_WDTCR (volatile u32 *)IOP3XX_TIMER_REG(0x001c)
+#define IOP_TMR_EN 0x02
+#define IOP_TMR_RELOAD 0x04
+#define IOP_TMR_PRIVILEGED 0x08
+#define IOP_TMR_RATIO_1_1 0x00
+
+/* Watchdog timer definitions */
+#define IOP_WDTCR_EN_ARM 0x1e1e1e1e
+#define IOP_WDTCR_EN 0xe1e1e1e1
+/* iop3xx does not support stopping the watchdog, so we just re-arm */
+#define IOP_WDTCR_DIS_ARM (IOP_WDTCR_EN_ARM)
+#define IOP_WDTCR_DIS (IOP_WDTCR_EN)
+
+/* Application accelerator unit */
+#define IOP3XX_AAU_PHYS_BASE (IOP3XX_PERIPHERAL_PHYS_BASE + 0x800)
+#define IOP3XX_AAU_UPPER_PA (IOP3XX_AAU_PHYS_BASE + 0xa7)
+
+/* I2C bus interface unit */
+#define IOP3XX_ICR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1680)
+#define IOP3XX_ISR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1684)
+#define IOP3XX_ISAR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1688)
+#define IOP3XX_IDBR0 (volatile u32 *)IOP3XX_REG_ADDR(0x168c)
+#define IOP3XX_IBMR0 (volatile u32 *)IOP3XX_REG_ADDR(0x1694)
+#define IOP3XX_ICR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a0)
+#define IOP3XX_ISR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a4)
+#define IOP3XX_ISAR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16a8)
+#define IOP3XX_IDBR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16ac)
+#define IOP3XX_IBMR1 (volatile u32 *)IOP3XX_REG_ADDR(0x16b4)
+
+
+/*
+ * IOP3XX I/O and Mem space regions for PCI autoconfiguration
+ */
+#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
+#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000
+
+#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
+#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
+#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000
+#define IOP3XX_PCI_LOWER_IO_BA 0x90000000
+#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\
+ IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
+ IOP3XX_PCI_IO_WINDOW_SIZE - 1)
+#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) (addr) -\
+ IOP3XX_PCI_LOWER_IO_PA) +\
+ IOP3XX_PCI_LOWER_IO_VA)
+
+
+#ifndef __ASSEMBLY__
+void iop3xx_map_io(void);
+void iop_init_cp6_handler(void);
+void iop_init_time(unsigned long tickrate);
+
+static inline u32 read_tmr0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c0, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tmr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (val));
+}
+
+static inline void write_tmr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (val));
+}
+
+static inline u32 read_tcr0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c2, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tcr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c1, 0" : : "r" (val));
+}
+
+static inline u32 read_tcr1(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c3, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tcr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c3, c1, 0" : : "r" (val));
+}
+
+static inline void write_trr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (val));
+}
+
+static inline void write_trr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (val));
+}
+
+static inline void write_tisr(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (val));
+}
+
+static inline u32 read_wdtcr(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c7, c1, 0":"=r" (val));
+ return val;
+}
+static inline void write_wdtcr(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c7, c1, 0"::"r" (val));
+}
+
+extern unsigned long get_iop_tick_rate(void);
+
+/* only iop13xx has these registers, we define these to present a
+ * common register interface for the iop_wdt driver.
+ */
+#define IOP_RCSR_WDT (0)
+static inline u32 read_rcsr(void)
+{
+ return 0;
+}
+static inline void write_wdtsr(u32 val)
+{
+ do { } while (0);
+}
+
+extern struct platform_device iop3xx_dma_0_channel;
+extern struct platform_device iop3xx_dma_1_channel;
+extern struct platform_device iop3xx_aau_channel;
+extern struct platform_device iop3xx_i2c0_device;
+extern struct platform_device iop3xx_i2c1_device;
+
+#endif
+
+
+#endif
diff --git a/arch/arm/include/asm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h
new file mode 100644
index 00000000..59b8c389
--- /dev/null
+++ b/arch/arm/include/asm/hardware/iop_adma.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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.
+ *
+ */
+#ifndef IOP_ADMA_H
+#define IOP_ADMA_H
+#include <linux/types.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+
+#define IOP_ADMA_SLOT_SIZE 32
+#define IOP_ADMA_THRESHOLD 4
+#ifdef DEBUG
+#define IOP_PARANOIA 1
+#else
+#define IOP_PARANOIA 0
+#endif
+#define iop_paranoia(x) BUG_ON(IOP_PARANOIA && (x))
+
+/**
+ * struct iop_adma_device - internal representation of an ADMA device
+ * @pdev: Platform device
+ * @id: HW ADMA Device selector
+ * @dma_desc_pool: base of DMA descriptor region (DMA address)
+ * @dma_desc_pool_virt: base of DMA descriptor region (CPU address)
+ * @common: embedded struct dma_device
+ */
+struct iop_adma_device {
+ struct platform_device *pdev;
+ int id;
+ dma_addr_t dma_desc_pool;
+ void *dma_desc_pool_virt;
+ struct dma_device common;
+};
+
+/**
+ * struct iop_adma_chan - internal representation of an ADMA device
+ * @pending: allows batching of hardware operations
+ * @completed_cookie: identifier for the most recently completed operation
+ * @lock: serializes enqueue/dequeue operations to the slot pool
+ * @mmr_base: memory mapped register base
+ * @chain: device chain view of the descriptors
+ * @device: parent device
+ * @common: common dmaengine channel object members
+ * @last_used: place holder for allocation to continue from where it left off
+ * @all_slots: complete domain of slots usable by the channel
+ * @slots_allocated: records the actual size of the descriptor slot pool
+ * @irq_tasklet: bottom half where iop_adma_slot_cleanup runs
+ */
+struct iop_adma_chan {
+ int pending;
+ dma_cookie_t completed_cookie;
+ spinlock_t lock; /* protects the descriptor slot pool */
+ void __iomem *mmr_base;
+ struct list_head chain;
+ struct iop_adma_device *device;
+ struct dma_chan common;
+ struct iop_adma_desc_slot *last_used;
+ struct list_head all_slots;
+ int slots_allocated;
+ struct tasklet_struct irq_tasklet;
+};
+
+/**
+ * struct iop_adma_desc_slot - IOP-ADMA software descriptor
+ * @slot_node: node on the iop_adma_chan.all_slots list
+ * @chain_node: node on the op_adma_chan.chain list
+ * @hw_desc: virtual address of the hardware descriptor chain
+ * @phys: hardware address of the hardware descriptor chain
+ * @group_head: first operation in a transaction
+ * @slot_cnt: total slots used in an transaction (group of operations)
+ * @slots_per_op: number of slots per operation
+ * @idx: pool index
+ * @unmap_src_cnt: number of xor sources
+ * @unmap_len: transaction bytecount
+ * @tx_list: list of descriptors that are associated with one operation
+ * @async_tx: support for the async_tx api
+ * @group_list: list of slots that make up a multi-descriptor transaction
+ * for example transfer lengths larger than the supported hw max
+ * @xor_check_result: result of zero sum
+ * @crc32_result: result crc calculation
+ */
+struct iop_adma_desc_slot {
+ struct list_head slot_node;
+ struct list_head chain_node;
+ void *hw_desc;
+ struct iop_adma_desc_slot *group_head;
+ u16 slot_cnt;
+ u16 slots_per_op;
+ u16 idx;
+ u16 unmap_src_cnt;
+ size_t unmap_len;
+ struct list_head tx_list;
+ struct dma_async_tx_descriptor async_tx;
+ union {
+ u32 *xor_check_result;
+ u32 *crc32_result;
+ u32 *pq_check_result;
+ };
+};
+
+struct iop_adma_platform_data {
+ int hw_id;
+ dma_cap_mask_t cap_mask;
+ size_t pool_size;
+};
+
+#define to_iop_sw_desc(addr_hw_desc) \
+ container_of(addr_hw_desc, struct iop_adma_desc_slot, hw_desc)
+#define iop_hw_desc_slot_idx(hw_desc, idx) \
+ ( (void *) (((unsigned long) hw_desc) + ((idx) << 5)) )
+#endif
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h
new file mode 100644
index 00000000..b2f95c72
--- /dev/null
+++ b/arch/arm/include/asm/hardware/it8152.h
@@ -0,0 +1,112 @@
+/*
+ * linux/include/arm/hardware/it8152.h
+ *
+ * Copyright Compulab Ltd., 2006,2007
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * ITE 8152 companion chip register definitions
+ */
+
+#ifndef __ASM_HARDWARE_IT8152_H
+#define __ASM_HARDWARE_IT8152_H
+extern unsigned long it8152_base_address;
+
+#define IT8152_IO_BASE (it8152_base_address + 0x03e00000)
+#define IT8152_CFGREG_BASE (it8152_base_address + 0x03f00000)
+
+#define __REG_IT8152(x) (it8152_base_address + (x))
+
+#define IT8152_PCI_CFG_ADDR __REG_IT8152(0x3f00800)
+#define IT8152_PCI_CFG_DATA __REG_IT8152(0x3f00804)
+
+#define IT8152_INTC_LDCNIRR __REG_IT8152(0x3f00300)
+#define IT8152_INTC_LDPNIRR __REG_IT8152(0x3f00304)
+#define IT8152_INTC_LDCNIMR __REG_IT8152(0x3f00308)
+#define IT8152_INTC_LDPNIMR __REG_IT8152(0x3f0030C)
+#define IT8152_INTC_LDNITR __REG_IT8152(0x3f00310)
+#define IT8152_INTC_LDNIAR __REG_IT8152(0x3f00314)
+#define IT8152_INTC_LPCNIRR __REG_IT8152(0x3f00320)
+#define IT8152_INTC_LPPNIRR __REG_IT8152(0x3f00324)
+#define IT8152_INTC_LPCNIMR __REG_IT8152(0x3f00328)
+#define IT8152_INTC_LPPNIMR __REG_IT8152(0x3f0032C)
+#define IT8152_INTC_LPNITR __REG_IT8152(0x3f00330)
+#define IT8152_INTC_LPNIAR __REG_IT8152(0x3f00334)
+#define IT8152_INTC_PDCNIRR __REG_IT8152(0x3f00340)
+#define IT8152_INTC_PDPNIRR __REG_IT8152(0x3f00344)
+#define IT8152_INTC_PDCNIMR __REG_IT8152(0x3f00348)
+#define IT8152_INTC_PDPNIMR __REG_IT8152(0x3f0034C)
+#define IT8152_INTC_PDNITR __REG_IT8152(0x3f00350)
+#define IT8152_INTC_PDNIAR __REG_IT8152(0x3f00354)
+#define IT8152_INTC_INTC_TYPER __REG_IT8152(0x3f003FC)
+
+#define IT8152_GPIO_GPDR __REG_IT8152(0x3f00500)
+
+/*
+ Interrupt controller per register summary:
+ ---------------------------------------
+ LCDNIRR:
+ IT8152_LD_IRQ(8) PCICLK stop
+ IT8152_LD_IRQ(7) MCLK ready
+ IT8152_LD_IRQ(6) s/w
+ IT8152_LD_IRQ(5) UART
+ IT8152_LD_IRQ(4) GPIO
+ IT8152_LD_IRQ(3) TIMER 4
+ IT8152_LD_IRQ(2) TIMER 3
+ IT8152_LD_IRQ(1) TIMER 2
+ IT8152_LD_IRQ(0) TIMER 1
+
+ LPCNIRR:
+ IT8152_LP_IRQ(x) serial IRQ x
+
+ PCIDNIRR:
+ IT8152_PD_IRQ(14) PCISERR
+ IT8152_PD_IRQ(13) CPU/PCI bridge target abort (h2pTADR)
+ IT8152_PD_IRQ(12) CPU/PCI bridge master abort (h2pMADR)
+ IT8152_PD_IRQ(11) PCI INTD
+ IT8152_PD_IRQ(10) PCI INTC
+ IT8152_PD_IRQ(9) PCI INTB
+ IT8152_PD_IRQ(8) PCI INTA
+ IT8152_PD_IRQ(7) serial INTD
+ IT8152_PD_IRQ(6) serial INTC
+ IT8152_PD_IRQ(5) serial INTB
+ IT8152_PD_IRQ(4) serial INTA
+ IT8152_PD_IRQ(3) serial IRQ IOCHK (IOCHKR)
+ IT8152_PD_IRQ(2) chaining DMA (CDMAR)
+ IT8152_PD_IRQ(1) USB (USBR)
+ IT8152_PD_IRQ(0) Audio controller (ACR)
+ */
+#define IT8152_IRQ(x) (IRQ_BOARD_START + (x))
+#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40)
+
+/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
+#define IT8152_LD_IRQ_COUNT 9
+#define IT8152_LP_IRQ_COUNT 16
+#define IT8152_PD_IRQ_COUNT 15
+
+/* Priorities: */
+#define IT8152_PD_IRQ(i) IT8152_IRQ(i)
+#define IT8152_LP_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT)
+#define IT8152_LD_IRQ(i) (IT8152_IRQ(i) + IT8152_PD_IRQ_COUNT + IT8152_LP_IRQ_COUNT)
+
+/* frequently used interrupts */
+#define IT8152_PCISERR IT8152_PD_IRQ(14)
+#define IT8152_H2PTADR IT8152_PD_IRQ(13)
+#define IT8152_H2PMAR IT8152_PD_IRQ(12)
+#define IT8152_PCI_INTD IT8152_PD_IRQ(11)
+#define IT8152_PCI_INTC IT8152_PD_IRQ(10)
+#define IT8152_PCI_INTB IT8152_PD_IRQ(9)
+#define IT8152_PCI_INTA IT8152_PD_IRQ(8)
+#define IT8152_CDMA_INT IT8152_PD_IRQ(2)
+#define IT8152_USB_INT IT8152_PD_IRQ(1)
+#define IT8152_AUDIO_INT IT8152_PD_IRQ(0)
+
+struct pci_dev;
+struct pci_sys_data;
+
+extern void it8152_irq_demux(unsigned int irq, struct irq_desc *desc);
+extern void it8152_init_irq(void);
+extern int it8152_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
+extern int it8152_pci_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_bus *it8152_pci_scan_bus(int nr, struct pci_sys_data *sys);
+
+#endif /* __ASM_HARDWARE_IT8152_H */
diff --git a/arch/arm/include/asm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h
new file mode 100644
index 00000000..7ec91168
--- /dev/null
+++ b/arch/arm/include/asm/hardware/linkup-l1110.h
@@ -0,0 +1,48 @@
+/*
+*
+* Definitions for H3600 Handheld Computer
+*
+* Copyright 2001 Compaq Computer Corporation.
+*
+* Use consistent with the GNU GPL is permitted,
+* provided that this copyright notice is
+* preserved in its entirety in all copies and derived works.
+*
+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+* FITNESS FOR ANY PARTICULAR PURPOSE.
+*
+* Author: Jamey Hicks.
+*
+*/
+
+/* LinkUp Systems PCCard/CompactFlash Interface for SA-1100 */
+
+/* PC Card Status Register */
+#define LINKUP_PRS_S1 (1 << 0) /* voltage control bits S1-S4 */
+#define LINKUP_PRS_S2 (1 << 1)
+#define LINKUP_PRS_S3 (1 << 2)
+#define LINKUP_PRS_S4 (1 << 3)
+#define LINKUP_PRS_BVD1 (1 << 4)
+#define LINKUP_PRS_BVD2 (1 << 5)
+#define LINKUP_PRS_VS1 (1 << 6)
+#define LINKUP_PRS_VS2 (1 << 7)
+#define LINKUP_PRS_RDY (1 << 8)
+#define LINKUP_PRS_CD1 (1 << 9)
+#define LINKUP_PRS_CD2 (1 << 10)
+
+/* PC Card Command Register */
+#define LINKUP_PRC_S1 (1 << 0)
+#define LINKUP_PRC_S2 (1 << 1)
+#define LINKUP_PRC_S3 (1 << 2)
+#define LINKUP_PRC_S4 (1 << 3)
+#define LINKUP_PRC_RESET (1 << 4)
+#define LINKUP_PRC_APOE (1 << 5) /* Auto Power Off Enable: clears S1-S4 when either nCD goes high */
+#define LINKUP_PRC_CFE (1 << 6) /* CompactFlash mode Enable: addresses A[10:0] only, A[25:11] high */
+#define LINKUP_PRC_SOE (1 << 7) /* signal output driver enable */
+#define LINKUP_PRC_SSP (1 << 8) /* sock select polarity: 0 for socket 0, 1 for socket 1 */
+#define LINKUP_PRC_MBZ (1 << 15) /* must be zero */
+
+struct linkup_l1110 {
+ volatile short prc;
+};
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
new file mode 100644
index 00000000..74e51d6b
--- /dev/null
+++ b/arch/arm/include/asm/hardware/locomo.h
@@ -0,0 +1,221 @@
+/*
+ * arch/arm/include/asm/hardware/locomo.h
+ *
+ * This file contains the definitions for the LoCoMo G/A Chip
+ *
+ * (C) Copyright 2004 John Lenz
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Based on sa1111.h
+ */
+#ifndef _ASM_ARCH_LOCOMO
+#define _ASM_ARCH_LOCOMO
+
+#define locomo_writel(val,addr) ({ *(volatile u16 *)(addr) = (val); })
+#define locomo_readl(addr) (*(volatile u16 *)(addr))
+
+/* LOCOMO version */
+#define LOCOMO_VER 0x00
+
+/* Pin status */
+#define LOCOMO_ST 0x04
+
+/* Pin status */
+#define LOCOMO_C32K 0x08
+
+/* Interrupt controller */
+#define LOCOMO_ICR 0x0C
+
+/* MCS decoder for boot selecting */
+#define LOCOMO_MCSX0 0x10
+#define LOCOMO_MCSX1 0x14
+#define LOCOMO_MCSX2 0x18
+#define LOCOMO_MCSX3 0x1c
+
+/* Touch panel controller */
+#define LOCOMO_ASD 0x20 /* AD start delay */
+#define LOCOMO_HSD 0x28 /* HSYS delay */
+#define LOCOMO_HSC 0x2c /* HSYS period */
+#define LOCOMO_TADC 0x30 /* tablet ADC clock */
+
+
+/* Long time timer */
+#define LOCOMO_LTC 0xd8 /* LTC interrupt setting */
+#define LOCOMO_LTINT 0xdc /* LTC interrupt */
+
+/* DAC control signal for LCD (COMADJ ) */
+#define LOCOMO_DAC 0xe0
+/* DAC control */
+#define LOCOMO_DAC_SCLOEB 0x08 /* SCL pin output data */
+#define LOCOMO_DAC_TEST 0x04 /* Test bit */
+#define LOCOMO_DAC_SDA 0x02 /* SDA pin level (read-only) */
+#define LOCOMO_DAC_SDAOEB 0x01 /* SDA pin output data */
+
+/* SPI interface */
+#define LOCOMO_SPI 0x60
+#define LOCOMO_SPIMD 0x00 /* SPI mode setting */
+#define LOCOMO_SPICT 0x04 /* SPI mode control */
+#define LOCOMO_SPIST 0x08 /* SPI status */
+#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */
+#define LOCOMO_SPI_REND (1 << 2) /* Receive end bit */
+#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */
+#define LOCOMO_SPI_RFR (1) /* read buffer bit */
+
+#define LOCOMO_SPIIS 0x10 /* SPI interrupt status */
+#define LOCOMO_SPIWE 0x14 /* SPI interrupt status write enable */
+#define LOCOMO_SPIIE 0x18 /* SPI interrupt enable */
+#define LOCOMO_SPIIR 0x1c /* SPI interrupt request */
+#define LOCOMO_SPITD 0x20 /* SPI transfer data write */
+#define LOCOMO_SPIRD 0x24 /* SPI receive data read */
+#define LOCOMO_SPITS 0x28 /* SPI transfer data shift */
+#define LOCOMO_SPIRS 0x2C /* SPI receive data shift */
+
+/* GPIO */
+#define LOCOMO_GPD 0x90 /* GPIO direction */
+#define LOCOMO_GPE 0x94 /* GPIO input enable */
+#define LOCOMO_GPL 0x98 /* GPIO level */
+#define LOCOMO_GPO 0x9c /* GPIO out data setting */
+#define LOCOMO_GRIE 0xa0 /* GPIO rise detection */
+#define LOCOMO_GFIE 0xa4 /* GPIO fall detection */
+#define LOCOMO_GIS 0xa8 /* GPIO edge detection status */
+#define LOCOMO_GWE 0xac /* GPIO status write enable */
+#define LOCOMO_GIE 0xb0 /* GPIO interrupt enable */
+#define LOCOMO_GIR 0xb4 /* GPIO interrupt request */
+#define LOCOMO_GPIO(Nb) (0x01 << (Nb))
+#define LOCOMO_GPIO_RTS LOCOMO_GPIO(0)
+#define LOCOMO_GPIO_CTS LOCOMO_GPIO(1)
+#define LOCOMO_GPIO_DSR LOCOMO_GPIO(2)
+#define LOCOMO_GPIO_DTR LOCOMO_GPIO(3)
+#define LOCOMO_GPIO_LCD_VSHA_ON LOCOMO_GPIO(4)
+#define LOCOMO_GPIO_LCD_VSHD_ON LOCOMO_GPIO(5)
+#define LOCOMO_GPIO_LCD_VEE_ON LOCOMO_GPIO(6)
+#define LOCOMO_GPIO_LCD_MOD LOCOMO_GPIO(7)
+#define LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8)
+#define LOCOMO_GPIO_FL_VR LOCOMO_GPIO(9)
+#define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10)
+#define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11)
+#define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12)
+#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13)
+#define LOCOMO_GPIO_WRITE_PROT LOCOMO_GPIO(14)
+#define LOCOMO_GPIO_CARD_POWER LOCOMO_GPIO(15)
+
+/* Start the definitions of the devices. Each device has an initial
+ * base address and a series of offsets from that base address. */
+
+/* Keyboard controller */
+#define LOCOMO_KEYBOARD 0x40
+#define LOCOMO_KIB 0x00 /* KIB level */
+#define LOCOMO_KSC 0x04 /* KSTRB control */
+#define LOCOMO_KCMD 0x08 /* KSTRB command */
+#define LOCOMO_KIC 0x0c /* Key interrupt */
+
+/* Front light adjustment controller */
+#define LOCOMO_FRONTLIGHT 0xc8
+#define LOCOMO_ALS 0x00 /* Adjust light cycle */
+#define LOCOMO_ALD 0x04 /* Adjust light duty */
+
+#define LOCOMO_ALC_EN 0x8000
+
+/* Backlight controller: TFT signal */
+#define LOCOMO_BACKLIGHT 0x38
+#define LOCOMO_TC 0x00 /* TFT control signal */
+#define LOCOMO_CPSD 0x04 /* CPS delay */
+
+/* Audio controller */
+#define LOCOMO_AUDIO 0x54
+#define LOCOMO_ACC 0x00 /* Audio clock */
+#define LOCOMO_PAIF 0xD0 /* PCM audio interface */
+/* Audio clock */
+#define LOCOMO_ACC_XON 0x80
+#define LOCOMO_ACC_XEN 0x40
+#define LOCOMO_ACC_XSEL0 0x00
+#define LOCOMO_ACC_XSEL1 0x20
+#define LOCOMO_ACC_MCLKEN 0x10
+#define LOCOMO_ACC_64FSEN 0x08
+#define LOCOMO_ACC_CLKSEL000 0x00 /* mclk 2 */
+#define LOCOMO_ACC_CLKSEL001 0x01 /* mclk 3 */
+#define LOCOMO_ACC_CLKSEL010 0x02 /* mclk 4 */
+#define LOCOMO_ACC_CLKSEL011 0x03 /* mclk 6 */
+#define LOCOMO_ACC_CLKSEL100 0x04 /* mclk 8 */
+#define LOCOMO_ACC_CLKSEL101 0x05 /* mclk 12 */
+/* PCM audio interface */
+#define LOCOMO_PAIF_SCINV 0x20
+#define LOCOMO_PAIF_SCEN 0x10
+#define LOCOMO_PAIF_LRCRST 0x08
+#define LOCOMO_PAIF_LRCEVE 0x04
+#define LOCOMO_PAIF_LRCINV 0x02
+#define LOCOMO_PAIF_LRCEN 0x01
+
+/* LED controller */
+#define LOCOMO_LED 0xe8
+#define LOCOMO_LPT0 0x00
+#define LOCOMO_LPT1 0x04
+/* LED control */
+#define LOCOMO_LPT_TOFH 0x80
+#define LOCOMO_LPT_TOFL 0x08
+#define LOCOMO_LPT_TOH(TOH) ((TOH & 0x7) << 4)
+#define LOCOMO_LPT_TOL(TOL) ((TOL & 0x7))
+
+extern struct bus_type locomo_bus_type;
+
+#define LOCOMO_DEVID_KEYBOARD 0
+#define LOCOMO_DEVID_FRONTLIGHT 1
+#define LOCOMO_DEVID_BACKLIGHT 2
+#define LOCOMO_DEVID_AUDIO 3
+#define LOCOMO_DEVID_LED 4
+#define LOCOMO_DEVID_UART 5
+#define LOCOMO_DEVID_SPI 6
+
+struct locomo_dev {
+ struct device dev;
+ unsigned int devid;
+ unsigned int irq[1];
+
+ void *mapbase;
+ unsigned long length;
+
+ u64 dma_mask;
+};
+
+#define LOCOMO_DEV(_d) container_of((_d), struct locomo_dev, dev)
+
+#define locomo_get_drvdata(d) dev_get_drvdata(&(d)->dev)
+#define locomo_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p)
+
+struct locomo_driver {
+ struct device_driver drv;
+ unsigned int devid;
+ int (*probe)(struct locomo_dev *);
+ int (*remove)(struct locomo_dev *);
+ int (*suspend)(struct locomo_dev *, pm_message_t);
+ int (*resume)(struct locomo_dev *);
+};
+
+#define LOCOMO_DRV(_d) container_of((_d), struct locomo_driver, drv)
+
+#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
+
+void locomo_lcd_power(struct locomo_dev *, int, unsigned int);
+
+int locomo_driver_register(struct locomo_driver *);
+void locomo_driver_unregister(struct locomo_driver *);
+
+/* GPIO control functions */
+void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir);
+int locomo_gpio_read_level(struct device *dev, unsigned int bits);
+int locomo_gpio_read_output(struct device *dev, unsigned int bits);
+void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set);
+
+/* M62332 control function */
+void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
+
+/* Frontlight control */
+void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
+
+struct locomo_platform_data {
+ int irq_base; /* IRQ base for cascaded on-chip IRQs */
+};
+
+#endif
diff --git a/arch/arm/include/asm/hardware/memc.h b/arch/arm/include/asm/hardware/memc.h
new file mode 100644
index 00000000..42ba7c16
--- /dev/null
+++ b/arch/arm/include/asm/hardware/memc.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/include/asm/hardware/memc.h
+ *
+ * Copyright (C) Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VDMA_ALIGNMENT PAGE_SIZE
+#define VDMA_XFERSIZE 16
+#define VDMA_INIT 0
+#define VDMA_START 1
+#define VDMA_END 2
+
+#ifndef __ASSEMBLY__
+extern void memc_write(unsigned int reg, unsigned long val);
+
+#define video_set_dma(start,end,offset) \
+do { \
+ memc_write (VDMA_START, (start >> 2)); \
+ memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \
+ memc_write (VDMA_INIT, (offset >> 2)); \
+} while (0)
+
+#endif
diff --git a/arch/arm/include/asm/hardware/pci_v3.h b/arch/arm/include/asm/hardware/pci_v3.h
new file mode 100644
index 00000000..2811c7e2
--- /dev/null
+++ b/arch/arm/include/asm/hardware/pci_v3.h
@@ -0,0 +1,186 @@
+/*
+ * arch/arm/include/asm/hardware/pci_v3.h
+ *
+ * Internal header file PCI V3 chip
+ *
+ * Copyright (C) ARM Limited
+ * Copyright (C) 2000-2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 ASM_ARM_HARDWARE_PCI_V3_H
+#define ASM_ARM_HARDWARE_PCI_V3_H
+
+/* -------------------------------------------------------------------------------
+ * V3 Local Bus to PCI Bridge definitions
+ * -------------------------------------------------------------------------------
+ * Registers (these are taken from page 129 of the EPC User's Manual Rev 1.04
+ * All V3 register names are prefaced by V3_ to avoid clashing with any other
+ * PCI definitions. Their names match the user's manual.
+ *
+ * I'm assuming that I20 is disabled.
+ *
+ */
+#define V3_PCI_VENDOR 0x00000000
+#define V3_PCI_DEVICE 0x00000002
+#define V3_PCI_CMD 0x00000004
+#define V3_PCI_STAT 0x00000006
+#define V3_PCI_CC_REV 0x00000008
+#define V3_PCI_HDR_CFG 0x0000000C
+#define V3_PCI_IO_BASE 0x00000010
+#define V3_PCI_BASE0 0x00000014
+#define V3_PCI_BASE1 0x00000018
+#define V3_PCI_SUB_VENDOR 0x0000002C
+#define V3_PCI_SUB_ID 0x0000002E
+#define V3_PCI_ROM 0x00000030
+#define V3_PCI_BPARAM 0x0000003C
+#define V3_PCI_MAP0 0x00000040
+#define V3_PCI_MAP1 0x00000044
+#define V3_PCI_INT_STAT 0x00000048
+#define V3_PCI_INT_CFG 0x0000004C
+#define V3_LB_BASE0 0x00000054
+#define V3_LB_BASE1 0x00000058
+#define V3_LB_MAP0 0x0000005E
+#define V3_LB_MAP1 0x00000062
+#define V3_LB_BASE2 0x00000064
+#define V3_LB_MAP2 0x00000066
+#define V3_LB_SIZE 0x00000068
+#define V3_LB_IO_BASE 0x0000006E
+#define V3_FIFO_CFG 0x00000070
+#define V3_FIFO_PRIORITY 0x00000072
+#define V3_FIFO_STAT 0x00000074
+#define V3_LB_ISTAT 0x00000076
+#define V3_LB_IMASK 0x00000077
+#define V3_SYSTEM 0x00000078
+#define V3_LB_CFG 0x0000007A
+#define V3_PCI_CFG 0x0000007C
+#define V3_DMA_PCI_ADR0 0x00000080
+#define V3_DMA_PCI_ADR1 0x00000090
+#define V3_DMA_LOCAL_ADR0 0x00000084
+#define V3_DMA_LOCAL_ADR1 0x00000094
+#define V3_DMA_LENGTH0 0x00000088
+#define V3_DMA_LENGTH1 0x00000098
+#define V3_DMA_CSR0 0x0000008B
+#define V3_DMA_CSR1 0x0000009B
+#define V3_DMA_CTLB_ADR0 0x0000008C
+#define V3_DMA_CTLB_ADR1 0x0000009C
+#define V3_DMA_DELAY 0x000000E0
+#define V3_MAIL_DATA 0x000000C0
+#define V3_PCI_MAIL_IEWR 0x000000D0
+#define V3_PCI_MAIL_IERD 0x000000D2
+#define V3_LB_MAIL_IEWR 0x000000D4
+#define V3_LB_MAIL_IERD 0x000000D6
+#define V3_MAIL_WR_STAT 0x000000D8
+#define V3_MAIL_RD_STAT 0x000000DA
+#define V3_QBA_MAP 0x000000DC
+
+/* PCI COMMAND REGISTER bits
+ */
+#define V3_COMMAND_M_FBB_EN (1 << 9)
+#define V3_COMMAND_M_SERR_EN (1 << 8)
+#define V3_COMMAND_M_PAR_EN (1 << 6)
+#define V3_COMMAND_M_MASTER_EN (1 << 2)
+#define V3_COMMAND_M_MEM_EN (1 << 1)
+#define V3_COMMAND_M_IO_EN (1 << 0)
+
+/* SYSTEM REGISTER bits
+ */
+#define V3_SYSTEM_M_RST_OUT (1 << 15)
+#define V3_SYSTEM_M_LOCK (1 << 14)
+
+/* PCI_CFG bits
+ */
+#define V3_PCI_CFG_M_I2O_EN (1 << 15)
+#define V3_PCI_CFG_M_IO_REG_DIS (1 << 14)
+#define V3_PCI_CFG_M_IO_DIS (1 << 13)
+#define V3_PCI_CFG_M_EN3V (1 << 12)
+#define V3_PCI_CFG_M_RETRY_EN (1 << 10)
+#define V3_PCI_CFG_M_AD_LOW1 (1 << 9)
+#define V3_PCI_CFG_M_AD_LOW0 (1 << 8)
+
+/* PCI_BASE register bits (PCI -> Local Bus)
+ */
+#define V3_PCI_BASE_M_ADR_BASE 0xFFF00000
+#define V3_PCI_BASE_M_ADR_BASEL 0x000FFF00
+#define V3_PCI_BASE_M_PREFETCH (1 << 3)
+#define V3_PCI_BASE_M_TYPE (3 << 1)
+#define V3_PCI_BASE_M_IO (1 << 0)
+
+/* PCI MAP register bits (PCI -> Local bus)
+ */
+#define V3_PCI_MAP_M_MAP_ADR 0xFFF00000
+#define V3_PCI_MAP_M_RD_POST_INH (1 << 15)
+#define V3_PCI_MAP_M_ROM_SIZE (3 << 10)
+#define V3_PCI_MAP_M_SWAP (3 << 8)
+#define V3_PCI_MAP_M_ADR_SIZE 0x000000F0
+#define V3_PCI_MAP_M_REG_EN (1 << 1)
+#define V3_PCI_MAP_M_ENABLE (1 << 0)
+
+/*
+ * LB_BASE0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_BASE_ADR_BASE 0xfff00000
+#define V3_LB_BASE_SWAP (3 << 8)
+#define V3_LB_BASE_ADR_SIZE (15 << 4)
+#define V3_LB_BASE_PREFETCH (1 << 3)
+#define V3_LB_BASE_ENABLE (1 << 0)
+
+#define V3_LB_BASE_ADR_SIZE_1MB (0 << 4)
+#define V3_LB_BASE_ADR_SIZE_2MB (1 << 4)
+#define V3_LB_BASE_ADR_SIZE_4MB (2 << 4)
+#define V3_LB_BASE_ADR_SIZE_8MB (3 << 4)
+#define V3_LB_BASE_ADR_SIZE_16MB (4 << 4)
+#define V3_LB_BASE_ADR_SIZE_32MB (5 << 4)
+#define V3_LB_BASE_ADR_SIZE_64MB (6 << 4)
+#define V3_LB_BASE_ADR_SIZE_128MB (7 << 4)
+#define V3_LB_BASE_ADR_SIZE_256MB (8 << 4)
+#define V3_LB_BASE_ADR_SIZE_512MB (9 << 4)
+#define V3_LB_BASE_ADR_SIZE_1GB (10 << 4)
+#define V3_LB_BASE_ADR_SIZE_2GB (11 << 4)
+
+#define v3_addr_to_lb_base(a) ((a) & V3_LB_BASE_ADR_BASE)
+
+/*
+ * LB_MAP0,1 register bits (Local bus -> PCI)
+ */
+#define V3_LB_MAP_MAP_ADR 0xfff0
+#define V3_LB_MAP_TYPE (7 << 1)
+#define V3_LB_MAP_AD_LOW_EN (1 << 0)
+
+#define V3_LB_MAP_TYPE_IACK (0 << 1)
+#define V3_LB_MAP_TYPE_IO (1 << 1)
+#define V3_LB_MAP_TYPE_MEM (3 << 1)
+#define V3_LB_MAP_TYPE_CONFIG (5 << 1)
+#define V3_LB_MAP_TYPE_MEM_MULTIPLE (6 << 1)
+
+#define v3_addr_to_lb_map(a) (((a) >> 16) & V3_LB_MAP_MAP_ADR)
+
+/*
+ * LB_BASE2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_BASE2_ADR_BASE 0xff00
+#define V3_LB_BASE2_SWAP (3 << 6)
+#define V3_LB_BASE2_ENABLE (1 << 0)
+
+#define v3_addr_to_lb_base2(a) (((a) >> 16) & V3_LB_BASE2_ADR_BASE)
+
+/*
+ * LB_MAP2 register bits (Local bus -> PCI IO)
+ */
+#define V3_LB_MAP2_MAP_ADR 0xff00
+
+#define v3_addr_to_lb_map2(a) (((a) >> 16) & V3_LB_MAP2_MAP_ADR)
+
+#endif
diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h
new file mode 100644
index 00000000..e4a04e4e
--- /dev/null
+++ b/arch/arm/include/asm/hardware/pl080.h
@@ -0,0 +1,140 @@
+/* arch/arm/include/asm/hardware/pl080.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ARM PrimeCell PL080 DMA 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.
+*/
+
+/* Note, there are some Samsung updates to this controller block which
+ * make it not entierly compatible with the PL080 specification from
+ * ARM. When in doubt, check the Samsung documentation first.
+ *
+ * The Samsung defines are PL080S, and add an extra control register,
+ * the ability to move more than 2^11 counts of data and some extra
+ * OneNAND features.
+*/
+
+#define PL080_INT_STATUS (0x00)
+#define PL080_TC_STATUS (0x04)
+#define PL080_TC_CLEAR (0x08)
+#define PL080_ERR_STATUS (0x0C)
+#define PL080_ERR_CLEAR (0x10)
+#define PL080_RAW_TC_STATUS (0x14)
+#define PL080_RAW_ERR_STATUS (0x18)
+#define PL080_EN_CHAN (0x1c)
+#define PL080_SOFT_BREQ (0x20)
+#define PL080_SOFT_SREQ (0x24)
+#define PL080_SOFT_LBREQ (0x28)
+#define PL080_SOFT_LSREQ (0x2C)
+
+#define PL080_CONFIG (0x30)
+#define PL080_CONFIG_M2_BE (1 << 2)
+#define PL080_CONFIG_M1_BE (1 << 1)
+#define PL080_CONFIG_ENABLE (1 << 0)
+
+#define PL080_SYNC (0x34)
+
+/* Per channel configuration registers */
+
+#define PL080_Cx_STRIDE (0x20)
+#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20)))
+#define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20)))
+#define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20)))
+#define PL080_Cx_LLI(x) ((0x108 + (x * 0x20)))
+#define PL080_Cx_CONTROL(x) ((0x10C + (x * 0x20)))
+#define PL080_Cx_CONFIG(x) ((0x110 + (x * 0x20)))
+#define PL080S_Cx_CONTROL2(x) ((0x110 + (x * 0x20)))
+#define PL080S_Cx_CONFIG(x) ((0x114 + (x * 0x20)))
+
+#define PL080_CH_SRC_ADDR (0x00)
+#define PL080_CH_DST_ADDR (0x04)
+#define PL080_CH_LLI (0x08)
+#define PL080_CH_CONTROL (0x0C)
+#define PL080_CH_CONFIG (0x10)
+#define PL080S_CH_CONTROL2 (0x10)
+#define PL080S_CH_CONFIG (0x14)
+
+#define PL080_LLI_ADDR_MASK (0x3fffffff << 2)
+#define PL080_LLI_ADDR_SHIFT (2)
+#define PL080_LLI_LM_AHB2 (1 << 0)
+
+#define PL080_CONTROL_TC_IRQ_EN (1 << 31)
+#define PL080_CONTROL_PROT_MASK (0x7 << 28)
+#define PL080_CONTROL_PROT_SHIFT (28)
+#define PL080_CONTROL_PROT_CACHE (1 << 30)
+#define PL080_CONTROL_PROT_BUFF (1 << 29)
+#define PL080_CONTROL_PROT_SYS (1 << 28)
+#define PL080_CONTROL_DST_INCR (1 << 27)
+#define PL080_CONTROL_SRC_INCR (1 << 26)
+#define PL080_CONTROL_DST_AHB2 (1 << 25)
+#define PL080_CONTROL_SRC_AHB2 (1 << 24)
+#define PL080_CONTROL_DWIDTH_MASK (0x7 << 21)
+#define PL080_CONTROL_DWIDTH_SHIFT (21)
+#define PL080_CONTROL_SWIDTH_MASK (0x7 << 18)
+#define PL080_CONTROL_SWIDTH_SHIFT (18)
+#define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15)
+#define PL080_CONTROL_DB_SIZE_SHIFT (15)
+#define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12)
+#define PL080_CONTROL_SB_SIZE_SHIFT (12)
+#define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0)
+#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0)
+
+#define PL080_BSIZE_1 (0x0)
+#define PL080_BSIZE_4 (0x1)
+#define PL080_BSIZE_8 (0x2)
+#define PL080_BSIZE_16 (0x3)
+#define PL080_BSIZE_32 (0x4)
+#define PL080_BSIZE_64 (0x5)
+#define PL080_BSIZE_128 (0x6)
+#define PL080_BSIZE_256 (0x7)
+
+#define PL080_WIDTH_8BIT (0x0)
+#define PL080_WIDTH_16BIT (0x1)
+#define PL080_WIDTH_32BIT (0x2)
+
+#define PL080_CONFIG_HALT (1 << 18)
+#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */
+#define PL080_CONFIG_LOCK (1 << 16)
+#define PL080_CONFIG_TC_IRQ_MASK (1 << 15)
+#define PL080_CONFIG_ERR_IRQ_MASK (1 << 14)
+#define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11)
+#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11)
+#define PL080_CONFIG_DST_SEL_MASK (0xf << 6)
+#define PL080_CONFIG_DST_SEL_SHIFT (6)
+#define PL080_CONFIG_SRC_SEL_MASK (0xf << 1)
+#define PL080_CONFIG_SRC_SEL_SHIFT (1)
+#define PL080_CONFIG_ENABLE (1 << 0)
+
+#define PL080_FLOW_MEM2MEM (0x0)
+#define PL080_FLOW_MEM2PER (0x1)
+#define PL080_FLOW_PER2MEM (0x2)
+#define PL080_FLOW_SRC2DST (0x3)
+#define PL080_FLOW_SRC2DST_DST (0x4)
+#define PL080_FLOW_MEM2PER_PER (0x5)
+#define PL080_FLOW_PER2MEM_PER (0x6)
+#define PL080_FLOW_SRC2DST_SRC (0x7)
+
+/* DMA linked list chain structure */
+
+struct pl080_lli {
+ u32 src_addr;
+ u32 dst_addr;
+ u32 next_lli;
+ u32 control0;
+};
+
+struct pl080s_lli {
+ u32 src_addr;
+ u32 dst_addr;
+ u32 next_lli;
+ u32 control0;
+ u32 control1;
+};
+
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
new file mode 100644
index 00000000..575fa818
--- /dev/null
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -0,0 +1,217 @@
+/* linux/include/asm/hardware/pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PL330_CORE_H
+#define __PL330_CORE_H
+
+#define PL330_MAX_CHAN 8
+#define PL330_MAX_IRQS 32
+#define PL330_MAX_PERI 32
+
+enum pl330_srccachectrl {
+ SCCTRL0 = 0, /* Noncacheable and nonbufferable */
+ SCCTRL1, /* Bufferable only */
+ SCCTRL2, /* Cacheable, but do not allocate */
+ SCCTRL3, /* Cacheable and bufferable, but do not allocate */
+ SINVALID1,
+ SINVALID2,
+ SCCTRL6, /* Cacheable write-through, allocate on reads only */
+ SCCTRL7, /* Cacheable write-back, allocate on reads only */
+};
+
+enum pl330_dstcachectrl {
+ DCCTRL0 = 0, /* Noncacheable and nonbufferable */
+ DCCTRL1, /* Bufferable only */
+ DCCTRL2, /* Cacheable, but do not allocate */
+ DCCTRL3, /* Cacheable and bufferable, but do not allocate */
+ DINVALID1 = 8,
+ DINVALID2,
+ DCCTRL6, /* Cacheable write-through, allocate on writes only */
+ DCCTRL7, /* Cacheable write-back, allocate on writes only */
+};
+
+/* Populated by the PL330 core driver for DMA API driver's info */
+struct pl330_config {
+ u32 periph_id;
+ u32 pcell_id;
+#define DMAC_MODE_NS (1 << 0)
+ unsigned int mode;
+ unsigned int data_bus_width:10; /* In number of bits */
+ unsigned int data_buf_dep:10;
+ unsigned int num_chan:4;
+ unsigned int num_peri:6;
+ u32 peri_ns;
+ unsigned int num_events:6;
+ u32 irq_ns;
+};
+
+/* Handle to the DMAC provided to the PL330 core */
+struct pl330_info {
+ /* Owning device */
+ struct device *dev;
+ /* Size of MicroCode buffers for each channel. */
+ unsigned mcbufsz;
+ /* ioremap'ed address of PL330 registers. */
+ void __iomem *base;
+ /* Client can freely use it. */
+ void *client_data;
+ /* PL330 core data, Client must not touch it. */
+ void *pl330_data;
+ /* Populated by the PL330 core driver during pl330_add */
+ struct pl330_config pcfg;
+ /*
+ * If the DMAC has some reset mechanism, then the
+ * client may want to provide pointer to the method.
+ */
+ void (*dmac_reset)(struct pl330_info *pi);
+};
+
+enum pl330_byteswap {
+ SWAP_NO = 0,
+ SWAP_2,
+ SWAP_4,
+ SWAP_8,
+ SWAP_16,
+};
+
+/**
+ * Request Configuration.
+ * The PL330 core does not modify this and uses the last
+ * working configuration if the request doesn't provide any.
+ *
+ * The Client may want to provide this info only for the
+ * first request and a request with new settings.
+ */
+struct pl330_reqcfg {
+ /* Address Incrementing */
+ unsigned dst_inc:1;
+ unsigned src_inc:1;
+
+ /*
+ * For now, the SRC & DST protection levels
+ * and burst size/length are assumed same.
+ */
+ bool nonsecure;
+ bool privileged;
+ bool insnaccess;
+ unsigned brst_len:5;
+ unsigned brst_size:3; /* in power of 2 */
+
+ enum pl330_dstcachectrl dcctl;
+ enum pl330_srccachectrl scctl;
+ enum pl330_byteswap swap;
+};
+
+/*
+ * One cycle of DMAC operation.
+ * There may be more than one xfer in a request.
+ */
+struct pl330_xfer {
+ u32 src_addr;
+ u32 dst_addr;
+ /* Size to xfer */
+ u32 bytes;
+ /*
+ * Pointer to next xfer in the list.
+ * The last xfer in the req must point to NULL.
+ */
+ struct pl330_xfer *next;
+};
+
+/* The xfer callbacks are made with one of these arguments. */
+enum pl330_op_err {
+ /* The all xfers in the request were success. */
+ PL330_ERR_NONE,
+ /* If req aborted due to global error. */
+ PL330_ERR_ABORT,
+ /* If req failed due to problem with Channel. */
+ PL330_ERR_FAIL,
+};
+
+enum pl330_reqtype {
+ MEMTOMEM,
+ MEMTODEV,
+ DEVTOMEM,
+ DEVTODEV,
+};
+
+/* A request defining Scatter-Gather List ending with NULL xfer. */
+struct pl330_req {
+ enum pl330_reqtype rqtype;
+ /* Index of peripheral for the xfer. */
+ unsigned peri:5;
+ /* Unique token for this xfer, set by the client. */
+ void *token;
+ /* Callback to be called after xfer. */
+ void (*xfer_cb)(void *token, enum pl330_op_err err);
+ /* If NULL, req will be done at last set parameters. */
+ struct pl330_reqcfg *cfg;
+ /* Pointer to first xfer in the request. */
+ struct pl330_xfer *x;
+};
+
+/*
+ * To know the status of the channel and DMAC, the client
+ * provides a pointer to this structure. The PL330 core
+ * fills it with current information.
+ */
+struct pl330_chanstatus {
+ /*
+ * If the DMAC engine halted due to some error,
+ * the client should remove-add DMAC.
+ */
+ bool dmac_halted;
+ /*
+ * If channel is halted due to some error,
+ * the client should ABORT/FLUSH and START the channel.
+ */
+ bool faulting;
+ /* Location of last load */
+ u32 src_addr;
+ /* Location of last store */
+ u32 dst_addr;
+ /*
+ * Pointer to the currently active req, NULL if channel is
+ * inactive, even though the requests may be present.
+ */
+ struct pl330_req *top_req;
+ /* Pointer to req waiting second in the queue if any. */
+ struct pl330_req *wait_req;
+};
+
+enum pl330_chan_op {
+ /* Start the channel */
+ PL330_OP_START,
+ /* Abort the active xfer */
+ PL330_OP_ABORT,
+ /* Stop xfer and flush queue */
+ PL330_OP_FLUSH,
+};
+
+extern int pl330_add(struct pl330_info *);
+extern void pl330_del(struct pl330_info *pi);
+extern int pl330_update(const struct pl330_info *pi);
+extern void pl330_release_channel(void *ch_id);
+extern void *pl330_request_channel(const struct pl330_info *pi);
+extern int pl330_chan_status(void *ch_id, struct pl330_chanstatus *pstatus);
+extern int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op);
+extern int pl330_submit_req(void *ch_id, struct pl330_req *r);
+
+#endif /* __PL330_CORE_H */
diff --git a/arch/arm/include/asm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h
new file mode 100644
index 00000000..92ed254c
--- /dev/null
+++ b/arch/arm/include/asm/hardware/sa1111.h
@@ -0,0 +1,585 @@
+/*
+ * arch/arm/include/asm/hardware/sa1111.h
+ *
+ * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
+ *
+ * This file contains definitions for the SA-1111 Companion Chip.
+ * (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.)
+ *
+ * Macro that calculates real address for registers in the SA-1111
+ */
+
+#ifndef _ASM_ARCH_SA1111
+#define _ASM_ARCH_SA1111
+
+#include <mach/bitfield.h>
+
+/*
+ * The SA1111 is always located at virtual 0xf4000000, and is always
+ * "native" endian.
+ */
+
+#define SA1111_VBASE 0xf4000000
+
+/* Don't use these! */
+#define SA1111_p2v( x ) ((x) - SA1111_BASE + SA1111_VBASE)
+#define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE)
+
+#ifndef __ASSEMBLY__
+#define _SA1111(x) ((x) + sa1111->resource.start)
+#endif
+
+#define sa1111_writel(val,addr) __raw_writel(val, addr)
+#define sa1111_readl(addr) __raw_readl(addr)
+
+/*
+ * 26 bits of the SA-1110 address bus are available to the SA-1111.
+ * Use these when feeding target addresses to the DMA engines.
+ */
+
+#define SA1111_ADDR_WIDTH (26)
+#define SA1111_ADDR_MASK ((1<<SA1111_ADDR_WIDTH)-1)
+#define SA1111_DMA_ADDR(x) ((x)&SA1111_ADDR_MASK)
+
+/*
+ * Don't ask the (SAC) DMA engines to move less than this amount.
+ */
+
+#define SA1111_SAC_DMA_MIN_XFER (0x800)
+
+/*
+ * System Bus Interface (SBI)
+ *
+ * Registers
+ * SKCR Control Register
+ * SMCR Shared Memory Controller Register
+ * SKID ID Register
+ */
+#define SA1111_SKCR 0x0000
+#define SA1111_SMCR 0x0004
+#define SA1111_SKID 0x0008
+
+#define SKCR_PLL_BYPASS (1<<0)
+#define SKCR_RCLKEN (1<<1)
+#define SKCR_SLEEP (1<<2)
+#define SKCR_DOZE (1<<3)
+#define SKCR_VCO_OFF (1<<4)
+#define SKCR_SCANTSTEN (1<<5)
+#define SKCR_CLKTSTEN (1<<6)
+#define SKCR_RDYEN (1<<7)
+#define SKCR_SELAC (1<<8)
+#define SKCR_OPPC (1<<9)
+#define SKCR_PLLTSTEN (1<<10)
+#define SKCR_USBIOTSTEN (1<<11)
+/*
+ * Don't believe the specs! Take them, throw them outside. Leave them
+ * there for a week. Spit on them. Walk on them. Stamp on them.
+ * Pour gasoline over them and finally burn them. Now think about coding.
+ * - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
+ * - The Feb 2001 errata (278260-010) says that the previous errata
+ * (278260-009) is wrong, and its bit actually 12, fixed in spec
+ * 278242-003.
+ * - The SA1111 manual (278242) says bit 12, but 0 to enable.
+ * - Reality is bit 13, 1 to enable.
+ * -- rmk
+ */
+#define SKCR_OE_EN (1<<13)
+
+#define SMCR_DTIM (1<<0)
+#define SMCR_MBGE (1<<1)
+#define SMCR_DRAC_0 (1<<2)
+#define SMCR_DRAC_1 (1<<3)
+#define SMCR_DRAC_2 (1<<4)
+#define SMCR_DRAC Fld(3, 2)
+#define SMCR_CLAT (1<<5)
+
+#define SKID_SIREV_MASK (0x000000f0)
+#define SKID_MTREV_MASK (0x0000000f)
+#define SKID_ID_MASK (0xffffff00)
+#define SKID_SA1111_ID (0x690cc200)
+
+/*
+ * System Controller
+ *
+ * Registers
+ * SKPCR Power Control Register
+ * SKCDR Clock Divider Register
+ * SKAUD Audio Clock Divider Register
+ * SKPMC PS/2 Mouse Clock Divider Register
+ * SKPTC PS/2 Track Pad Clock Divider Register
+ * SKPEN0 PWM0 Enable Register
+ * SKPWM0 PWM0 Clock Register
+ * SKPEN1 PWM1 Enable Register
+ * SKPWM1 PWM1 Clock Register
+ */
+#define SA1111_SKPCR 0x0200
+#define SA1111_SKCDR 0x0204
+#define SA1111_SKAUD 0x0208
+#define SA1111_SKPMC 0x020c
+#define SA1111_SKPTC 0x0210
+#define SA1111_SKPEN0 0x0214
+#define SA1111_SKPWM0 0x0218
+#define SA1111_SKPEN1 0x021c
+#define SA1111_SKPWM1 0x0220
+
+#define SKPCR_UCLKEN (1<<0)
+#define SKPCR_ACCLKEN (1<<1)
+#define SKPCR_I2SCLKEN (1<<2)
+#define SKPCR_L3CLKEN (1<<3)
+#define SKPCR_SCLKEN (1<<4)
+#define SKPCR_PMCLKEN (1<<5)
+#define SKPCR_PTCLKEN (1<<6)
+#define SKPCR_DCLKEN (1<<7)
+#define SKPCR_PWMCLKEN (1<<8)
+
+/*
+ * USB Host controller
+ */
+#define SA1111_USB 0x0400
+
+/*
+ * Offsets from SA1111_USB_BASE
+ */
+#define SA1111_USB_STATUS 0x0118
+#define SA1111_USB_RESET 0x011c
+#define SA1111_USB_IRQTEST 0x0120
+
+#define USB_RESET_FORCEIFRESET (1 << 0)
+#define USB_RESET_FORCEHCRESET (1 << 1)
+#define USB_RESET_CLKGENRESET (1 << 2)
+#define USB_RESET_SIMSCALEDOWN (1 << 3)
+#define USB_RESET_USBINTTEST (1 << 4)
+#define USB_RESET_SLEEPSTBYEN (1 << 5)
+#define USB_RESET_PWRSENSELOW (1 << 6)
+#define USB_RESET_PWRCTRLLOW (1 << 7)
+
+#define USB_STATUS_IRQHCIRMTWKUP (1 << 7)
+#define USB_STATUS_IRQHCIBUFFACC (1 << 8)
+#define USB_STATUS_NIRQHCIM (1 << 9)
+#define USB_STATUS_NHCIMFCLR (1 << 10)
+#define USB_STATUS_USBPWRSENSE (1 << 11)
+
+/*
+ * Serial Audio Controller
+ *
+ * Registers
+ * SACR0 Serial Audio Common Control Register
+ * SACR1 Serial Audio Alternate Mode (I2C/MSB) Control Register
+ * SACR2 Serial Audio AC-link Control Register
+ * SASR0 Serial Audio I2S/MSB Interface & FIFO Status Register
+ * SASR1 Serial Audio AC-link Interface & FIFO Status Register
+ * SASCR Serial Audio Status Clear Register
+ * L3_CAR L3 Control Bus Address Register
+ * L3_CDR L3 Control Bus Data Register
+ * ACCAR AC-link Command Address Register
+ * ACCDR AC-link Command Data Register
+ * ACSAR AC-link Status Address Register
+ * ACSDR AC-link Status Data Register
+ * SADTCS Serial Audio DMA Transmit Control/Status Register
+ * SADTSA Serial Audio DMA Transmit Buffer Start Address A
+ * SADTCA Serial Audio DMA Transmit Buffer Count Register A
+ * SADTSB Serial Audio DMA Transmit Buffer Start Address B
+ * SADTCB Serial Audio DMA Transmit Buffer Count Register B
+ * SADRCS Serial Audio DMA Receive Control/Status Register
+ * SADRSA Serial Audio DMA Receive Buffer Start Address A
+ * SADRCA Serial Audio DMA Receive Buffer Count Register A
+ * SADRSB Serial Audio DMA Receive Buffer Start Address B
+ * SADRCB Serial Audio DMA Receive Buffer Count Register B
+ * SAITR Serial Audio Interrupt Test Register
+ * SADR Serial Audio Data Register (16 x 32-bit)
+ */
+
+#define SA1111_SERAUDIO 0x0600
+
+/*
+ * These are offsets from the above base.
+ */
+#define SA1111_SACR0 0x00
+#define SA1111_SACR1 0x04
+#define SA1111_SACR2 0x08
+#define SA1111_SASR0 0x0c
+#define SA1111_SASR1 0x10
+#define SA1111_SASCR 0x18
+#define SA1111_L3_CAR 0x1c
+#define SA1111_L3_CDR 0x20
+#define SA1111_ACCAR 0x24
+#define SA1111_ACCDR 0x28
+#define SA1111_ACSAR 0x2c
+#define SA1111_ACSDR 0x30
+#define SA1111_SADTCS 0x34
+#define SA1111_SADTSA 0x38
+#define SA1111_SADTCA 0x3c
+#define SA1111_SADTSB 0x40
+#define SA1111_SADTCB 0x44
+#define SA1111_SADRCS 0x48
+#define SA1111_SADRSA 0x4c
+#define SA1111_SADRCA 0x50
+#define SA1111_SADRSB 0x54
+#define SA1111_SADRCB 0x58
+#define SA1111_SAITR 0x5c
+#define SA1111_SADR 0x80
+
+#ifndef CONFIG_ARCH_PXA
+
+#define SACR0_ENB (1<<0)
+#define SACR0_BCKD (1<<2)
+#define SACR0_RST (1<<3)
+
+#define SACR1_AMSL (1<<0)
+#define SACR1_L3EN (1<<1)
+#define SACR1_L3MB (1<<2)
+#define SACR1_DREC (1<<3)
+#define SACR1_DRPL (1<<4)
+#define SACR1_ENLBF (1<<5)
+
+#define SACR2_TS3V (1<<0)
+#define SACR2_TS4V (1<<1)
+#define SACR2_WKUP (1<<2)
+#define SACR2_DREC (1<<3)
+#define SACR2_DRPL (1<<4)
+#define SACR2_ENLBF (1<<5)
+#define SACR2_RESET (1<<6)
+
+#define SASR0_TNF (1<<0)
+#define SASR0_RNE (1<<1)
+#define SASR0_BSY (1<<2)
+#define SASR0_TFS (1<<3)
+#define SASR0_RFS (1<<4)
+#define SASR0_TUR (1<<5)
+#define SASR0_ROR (1<<6)
+#define SASR0_L3WD (1<<16)
+#define SASR0_L3RD (1<<17)
+
+#define SASR1_TNF (1<<0)
+#define SASR1_RNE (1<<1)
+#define SASR1_BSY (1<<2)
+#define SASR1_TFS (1<<3)
+#define SASR1_RFS (1<<4)
+#define SASR1_TUR (1<<5)
+#define SASR1_ROR (1<<6)
+#define SASR1_CADT (1<<16)
+#define SASR1_SADR (1<<17)
+#define SASR1_RSTO (1<<18)
+#define SASR1_CLPM (1<<19)
+#define SASR1_CRDY (1<<20)
+#define SASR1_RS3V (1<<21)
+#define SASR1_RS4V (1<<22)
+
+#define SASCR_TUR (1<<5)
+#define SASCR_ROR (1<<6)
+#define SASCR_DTS (1<<16)
+#define SASCR_RDD (1<<17)
+#define SASCR_STO (1<<18)
+
+#define SADTCS_TDEN (1<<0)
+#define SADTCS_TDIE (1<<1)
+#define SADTCS_TDBDA (1<<3)
+#define SADTCS_TDSTA (1<<4)
+#define SADTCS_TDBDB (1<<5)
+#define SADTCS_TDSTB (1<<6)
+#define SADTCS_TBIU (1<<7)
+
+#define SADRCS_RDEN (1<<0)
+#define SADRCS_RDIE (1<<1)
+#define SADRCS_RDBDA (1<<3)
+#define SADRCS_RDSTA (1<<4)
+#define SADRCS_RDBDB (1<<5)
+#define SADRCS_RDSTB (1<<6)
+#define SADRCS_RBIU (1<<7)
+
+#define SAD_CS_DEN (1<<0)
+#define SAD_CS_DIE (1<<1) /* Not functional on metal 1 */
+#define SAD_CS_DBDA (1<<3) /* Not functional on metal 1 */
+#define SAD_CS_DSTA (1<<4)
+#define SAD_CS_DBDB (1<<5) /* Not functional on metal 1 */
+#define SAD_CS_DSTB (1<<6)
+#define SAD_CS_BIU (1<<7) /* Not functional on metal 1 */
+
+#define SAITR_TFS (1<<0)
+#define SAITR_RFS (1<<1)
+#define SAITR_TUR (1<<2)
+#define SAITR_ROR (1<<3)
+#define SAITR_CADT (1<<4)
+#define SAITR_SADR (1<<5)
+#define SAITR_RSTO (1<<6)
+#define SAITR_TDBDA (1<<8)
+#define SAITR_TDBDB (1<<9)
+#define SAITR_RDBDA (1<<10)
+#define SAITR_RDBDB (1<<11)
+
+#endif /* !CONFIG_ARCH_PXA */
+
+/*
+ * General-Purpose I/O Interface
+ *
+ * Registers
+ * PA_DDR GPIO Block A Data Direction
+ * PA_DRR/PA_DWR GPIO Block A Data Value Register (read/write)
+ * PA_SDR GPIO Block A Sleep Direction
+ * PA_SSR GPIO Block A Sleep State
+ * PB_DDR GPIO Block B Data Direction
+ * PB_DRR/PB_DWR GPIO Block B Data Value Register (read/write)
+ * PB_SDR GPIO Block B Sleep Direction
+ * PB_SSR GPIO Block B Sleep State
+ * PC_DDR GPIO Block C Data Direction
+ * PC_DRR/PC_DWR GPIO Block C Data Value Register (read/write)
+ * PC_SDR GPIO Block C Sleep Direction
+ * PC_SSR GPIO Block C Sleep State
+ */
+
+#define _PA_DDR _SA1111( 0x1000 )
+#define _PA_DRR _SA1111( 0x1004 )
+#define _PA_DWR _SA1111( 0x1004 )
+#define _PA_SDR _SA1111( 0x1008 )
+#define _PA_SSR _SA1111( 0x100c )
+#define _PB_DDR _SA1111( 0x1010 )
+#define _PB_DRR _SA1111( 0x1014 )
+#define _PB_DWR _SA1111( 0x1014 )
+#define _PB_SDR _SA1111( 0x1018 )
+#define _PB_SSR _SA1111( 0x101c )
+#define _PC_DDR _SA1111( 0x1020 )
+#define _PC_DRR _SA1111( 0x1024 )
+#define _PC_DWR _SA1111( 0x1024 )
+#define _PC_SDR _SA1111( 0x1028 )
+#define _PC_SSR _SA1111( 0x102c )
+
+#define SA1111_GPIO 0x1000
+
+#define SA1111_GPIO_PADDR (0x000)
+#define SA1111_GPIO_PADRR (0x004)
+#define SA1111_GPIO_PADWR (0x004)
+#define SA1111_GPIO_PASDR (0x008)
+#define SA1111_GPIO_PASSR (0x00c)
+#define SA1111_GPIO_PBDDR (0x010)
+#define SA1111_GPIO_PBDRR (0x014)
+#define SA1111_GPIO_PBDWR (0x014)
+#define SA1111_GPIO_PBSDR (0x018)
+#define SA1111_GPIO_PBSSR (0x01c)
+#define SA1111_GPIO_PCDDR (0x020)
+#define SA1111_GPIO_PCDRR (0x024)
+#define SA1111_GPIO_PCDWR (0x024)
+#define SA1111_GPIO_PCSDR (0x028)
+#define SA1111_GPIO_PCSSR (0x02c)
+
+#define GPIO_A0 (1 << 0)
+#define GPIO_A1 (1 << 1)
+#define GPIO_A2 (1 << 2)
+#define GPIO_A3 (1 << 3)
+
+#define GPIO_B0 (1 << 8)
+#define GPIO_B1 (1 << 9)
+#define GPIO_B2 (1 << 10)
+#define GPIO_B3 (1 << 11)
+#define GPIO_B4 (1 << 12)
+#define GPIO_B5 (1 << 13)
+#define GPIO_B6 (1 << 14)
+#define GPIO_B7 (1 << 15)
+
+#define GPIO_C0 (1 << 16)
+#define GPIO_C1 (1 << 17)
+#define GPIO_C2 (1 << 18)
+#define GPIO_C3 (1 << 19)
+#define GPIO_C4 (1 << 20)
+#define GPIO_C5 (1 << 21)
+#define GPIO_C6 (1 << 22)
+#define GPIO_C7 (1 << 23)
+
+/*
+ * Interrupt Controller
+ *
+ * Registers
+ * INTTEST0 Test register 0
+ * INTTEST1 Test register 1
+ * INTEN0 Interrupt Enable register 0
+ * INTEN1 Interrupt Enable register 1
+ * INTPOL0 Interrupt Polarity selection 0
+ * INTPOL1 Interrupt Polarity selection 1
+ * INTTSTSEL Interrupt source selection
+ * INTSTATCLR0 Interrupt Status/Clear 0
+ * INTSTATCLR1 Interrupt Status/Clear 1
+ * INTSET0 Interrupt source set 0
+ * INTSET1 Interrupt source set 1
+ * WAKE_EN0 Wake-up source enable 0
+ * WAKE_EN1 Wake-up source enable 1
+ * WAKE_POL0 Wake-up polarity selection 0
+ * WAKE_POL1 Wake-up polarity selection 1
+ */
+#define SA1111_INTC 0x1600
+
+/*
+ * These are offsets from the above base.
+ */
+#define SA1111_INTTEST0 0x0000
+#define SA1111_INTTEST1 0x0004
+#define SA1111_INTEN0 0x0008
+#define SA1111_INTEN1 0x000c
+#define SA1111_INTPOL0 0x0010
+#define SA1111_INTPOL1 0x0014
+#define SA1111_INTTSTSEL 0x0018
+#define SA1111_INTSTATCLR0 0x001c
+#define SA1111_INTSTATCLR1 0x0020
+#define SA1111_INTSET0 0x0024
+#define SA1111_INTSET1 0x0028
+#define SA1111_WAKEEN0 0x002c
+#define SA1111_WAKEEN1 0x0030
+#define SA1111_WAKEPOL0 0x0034
+#define SA1111_WAKEPOL1 0x0038
+
+/*
+ * PS/2 Trackpad and Mouse Interfaces
+ *
+ * Registers
+ * PS2CR Control Register
+ * PS2STAT Status Register
+ * PS2DATA Transmit/Receive Data register
+ * PS2CLKDIV Clock Division Register
+ * PS2PRECNT Clock Precount Register
+ * PS2TEST1 Test register 1
+ * PS2TEST2 Test register 2
+ * PS2TEST3 Test register 3
+ * PS2TEST4 Test register 4
+ */
+
+#define SA1111_KBD 0x0a00
+#define SA1111_MSE 0x0c00
+
+/*
+ * These are offsets from the above bases.
+ */
+#define SA1111_PS2CR 0x0000
+#define SA1111_PS2STAT 0x0004
+#define SA1111_PS2DATA 0x0008
+#define SA1111_PS2CLKDIV 0x000c
+#define SA1111_PS2PRECNT 0x0010
+
+#define PS2CR_ENA 0x08
+#define PS2CR_FKD 0x02
+#define PS2CR_FKC 0x01
+
+#define PS2STAT_STP 0x0100
+#define PS2STAT_TXE 0x0080
+#define PS2STAT_TXB 0x0040
+#define PS2STAT_RXF 0x0020
+#define PS2STAT_RXB 0x0010
+#define PS2STAT_ENA 0x0008
+#define PS2STAT_RXP 0x0004
+#define PS2STAT_KBD 0x0002
+#define PS2STAT_KBC 0x0001
+
+/*
+ * PCMCIA Interface
+ *
+ * Registers
+ * PCSR Status Register
+ * PCCR Control Register
+ * PCSSR Sleep State Register
+ */
+
+#define SA1111_PCMCIA 0x1600
+
+/*
+ * These are offsets from the above base.
+ */
+#define SA1111_PCCR 0x0000
+#define SA1111_PCSSR 0x0004
+#define SA1111_PCSR 0x0008
+
+#define PCSR_S0_READY (1<<0)
+#define PCSR_S1_READY (1<<1)
+#define PCSR_S0_DETECT (1<<2)
+#define PCSR_S1_DETECT (1<<3)
+#define PCSR_S0_VS1 (1<<4)
+#define PCSR_S0_VS2 (1<<5)
+#define PCSR_S1_VS1 (1<<6)
+#define PCSR_S1_VS2 (1<<7)
+#define PCSR_S0_WP (1<<8)
+#define PCSR_S1_WP (1<<9)
+#define PCSR_S0_BVD1 (1<<10)
+#define PCSR_S0_BVD2 (1<<11)
+#define PCSR_S1_BVD1 (1<<12)
+#define PCSR_S1_BVD2 (1<<13)
+
+#define PCCR_S0_RST (1<<0)
+#define PCCR_S1_RST (1<<1)
+#define PCCR_S0_FLT (1<<2)
+#define PCCR_S1_FLT (1<<3)
+#define PCCR_S0_PWAITEN (1<<4)
+#define PCCR_S1_PWAITEN (1<<5)
+#define PCCR_S0_PSE (1<<6)
+#define PCCR_S1_PSE (1<<7)
+
+#define PCSSR_S0_SLEEP (1<<0)
+#define PCSSR_S1_SLEEP (1<<1)
+
+
+
+
+extern struct bus_type sa1111_bus_type;
+
+#define SA1111_DEVID_SBI 0
+#define SA1111_DEVID_SK 1
+#define SA1111_DEVID_USB 2
+#define SA1111_DEVID_SAC 3
+#define SA1111_DEVID_SSP 4
+#define SA1111_DEVID_PS2 5
+#define SA1111_DEVID_GPIO 6
+#define SA1111_DEVID_INT 7
+#define SA1111_DEVID_PCMCIA 8
+
+struct sa1111_dev {
+ struct device dev;
+ unsigned int devid;
+ struct resource res;
+ void __iomem *mapbase;
+ unsigned int skpcr_mask;
+ unsigned int irq[6];
+ u64 dma_mask;
+};
+
+#define SA1111_DEV(_d) container_of((_d), struct sa1111_dev, dev)
+
+#define sa1111_get_drvdata(d) dev_get_drvdata(&(d)->dev)
+#define sa1111_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p)
+
+struct sa1111_driver {
+ struct device_driver drv;
+ unsigned int devid;
+ int (*probe)(struct sa1111_dev *);
+ int (*remove)(struct sa1111_dev *);
+ int (*suspend)(struct sa1111_dev *, pm_message_t);
+ int (*resume)(struct sa1111_dev *);
+};
+
+#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)
+
+#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
+
+/*
+ * These frob the SKPCR register.
+ */
+void sa1111_enable_device(struct sa1111_dev *);
+void sa1111_disable_device(struct sa1111_dev *);
+
+unsigned int sa1111_pll_clock(struct sa1111_dev *);
+
+#define SA1111_AUDIO_ACLINK 0
+#define SA1111_AUDIO_I2S 1
+
+void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode);
+int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate);
+int sa1111_get_audio_rate(struct sa1111_dev *sadev);
+
+int sa1111_check_dma_bug(dma_addr_t addr);
+
+int sa1111_driver_register(struct sa1111_driver *);
+void sa1111_driver_unregister(struct sa1111_driver *);
+
+void sa1111_set_io_dir(struct sa1111_dev *sadev, unsigned int bits, unsigned int dir, unsigned int sleep_dir);
+void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
+void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v);
+
+struct sa1111_platform_data {
+ int irq_base; /* base for cascaded on-chip IRQs */
+};
+
+#endif /* _ASM_ARCH_SA1111 */
diff --git a/arch/arm/include/asm/hardware/scoop.h b/arch/arm/include/asm/hardware/scoop.h
new file mode 100644
index 00000000..ebb3ceaa
--- /dev/null
+++ b/arch/arm/include/asm/hardware/scoop.h
@@ -0,0 +1,72 @@
+/*
+ * Definitions for the SCOOP interface found on various Sharp PDAs
+ *
+ * Copyright (c) 2004 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define SCOOP_MCR 0x00
+#define SCOOP_CDR 0x04
+#define SCOOP_CSR 0x08
+#define SCOOP_CPR 0x0C
+#define SCOOP_CCR 0x10
+#define SCOOP_IRR 0x14
+#define SCOOP_IRM 0x14
+#define SCOOP_IMR 0x18
+#define SCOOP_ISR 0x1C
+#define SCOOP_GPCR 0x20
+#define SCOOP_GPWR 0x24
+#define SCOOP_GPRR 0x28
+
+#define SCOOP_CPR_OUT (1 << 7)
+#define SCOOP_CPR_SD_3V (1 << 2)
+#define SCOOP_CPR_CF_XV (1 << 1)
+#define SCOOP_CPR_CF_3V (1 << 0)
+
+#define SCOOP_GPCR_PA22 (1 << 12)
+#define SCOOP_GPCR_PA21 (1 << 11)
+#define SCOOP_GPCR_PA20 (1 << 10)
+#define SCOOP_GPCR_PA19 (1 << 9)
+#define SCOOP_GPCR_PA18 (1 << 8)
+#define SCOOP_GPCR_PA17 (1 << 7)
+#define SCOOP_GPCR_PA16 (1 << 6)
+#define SCOOP_GPCR_PA15 (1 << 5)
+#define SCOOP_GPCR_PA14 (1 << 4)
+#define SCOOP_GPCR_PA13 (1 << 3)
+#define SCOOP_GPCR_PA12 (1 << 2)
+#define SCOOP_GPCR_PA11 (1 << 1)
+
+struct scoop_config {
+ unsigned short io_out;
+ unsigned short io_dir;
+ unsigned short suspend_clr;
+ unsigned short suspend_set;
+ int gpio_base;
+};
+
+/* Structure for linking scoop devices to PCMCIA sockets */
+struct scoop_pcmcia_dev {
+ struct device *dev; /* Pointer to this socket's scoop device */
+ int irq; /* irq for socket */
+ int cd_irq;
+ const char *cd_irq_str;
+ unsigned char keep_vs;
+ unsigned char keep_rd;
+};
+
+struct scoop_pcmcia_config {
+ struct scoop_pcmcia_dev *devs;
+ int num_devs;
+ void (*pcmcia_init)(void);
+ void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
+};
+
+extern struct scoop_pcmcia_config *platform_scoop_config;
+
+void reset_scoop(struct device *dev);
+unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
+void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);
diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h
new file mode 100644
index 00000000..e0d1c0cf
--- /dev/null
+++ b/arch/arm/include/asm/hardware/sp810.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/include/asm/hardware/sp810.h
+ *
+ * ARM PrimeXsys System Controller SP810 header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARM_SP810_H
+#define __ASM_ARM_SP810_H
+
+#include <linux/io.h>
+
+/* sysctl registers offset */
+#define SCCTRL 0x000
+#define SCSYSSTAT 0x004
+#define SCIMCTRL 0x008
+#define SCIMSTAT 0x00C
+#define SCXTALCTRL 0x010
+#define SCPLLCTRL 0x014
+#define SCPLLFCTRL 0x018
+#define SCPERCTRL0 0x01C
+#define SCPERCTRL1 0x020
+#define SCPEREN 0x024
+#define SCPERDIS 0x028
+#define SCPERCLKEN 0x02C
+#define SCPERSTAT 0x030
+#define SCSYSID0 0xEE0
+#define SCSYSID1 0xEE4
+#define SCSYSID2 0xEE8
+#define SCSYSID3 0xEEC
+#define SCITCR 0xF00
+#define SCITIR0 0xF04
+#define SCITIR1 0xF08
+#define SCITOR 0xF0C
+#define SCCNTCTRL 0xF10
+#define SCCNTDATA 0xF14
+#define SCCNTSTEP 0xF18
+#define SCPERIPHID0 0xFE0
+#define SCPERIPHID1 0xFE4
+#define SCPERIPHID2 0xFE8
+#define SCPERIPHID3 0xFEC
+#define SCPCELLID0 0xFF0
+#define SCPCELLID1 0xFF4
+#define SCPCELLID2 0xFF8
+#define SCPCELLID3 0xFFC
+
+#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15)
+#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15)
+
+#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
+#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
+
+static inline void sysctl_soft_reset(void __iomem *base)
+{
+ /* switch to slow mode */
+ writel(0x2, base + SCCTRL);
+
+ /* writing any value to SCSYSSTAT reg will reset system */
+ writel(0, base + SCSYSSTAT);
+}
+
+#endif /* __ASM_ARM_SP810_H */
diff --git a/arch/arm/include/asm/hardware/ssp.h b/arch/arm/include/asm/hardware/ssp.h
new file mode 100644
index 00000000..3b42e181
--- /dev/null
+++ b/arch/arm/include/asm/hardware/ssp.h
@@ -0,0 +1,28 @@
+/*
+ * ssp.h
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef SSP_H
+#define SSP_H
+
+struct ssp_state {
+ unsigned int cr0;
+ unsigned int cr1;
+};
+
+int ssp_write_word(u16 data);
+int ssp_read_word(u16 *data);
+int ssp_flush(void);
+void ssp_enable(void);
+void ssp_disable(void);
+void ssp_save_state(struct ssp_state *ssp);
+void ssp_restore_state(struct ssp_state *ssp);
+int ssp_init(void);
+void ssp_exit(void);
+
+#endif
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
new file mode 100644
index 00000000..4384d81e
--- /dev/null
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -0,0 +1,2 @@
+void sp804_clocksource_init(void __iomem *, const char *);
+void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
diff --git a/arch/arm/include/asm/hardware/uengine.h b/arch/arm/include/asm/hardware/uengine.h
new file mode 100644
index 00000000..b442d65c
--- /dev/null
+++ b/arch/arm/include/asm/hardware/uengine.h
@@ -0,0 +1,62 @@
+/*
+ * Generic library functions for the microengines found on the Intel
+ * IXP2000 series of network processors.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#ifndef __IXP2000_UENGINE_H
+#define __IXP2000_UENGINE_H
+
+extern u32 ixp2000_uengine_mask;
+
+struct ixp2000_uengine_code
+{
+ u32 cpu_model_bitmask;
+ u8 cpu_min_revision;
+ u8 cpu_max_revision;
+
+ u32 uengine_parameters;
+
+ struct ixp2000_reg_value {
+ int reg;
+ u32 value;
+ } *initial_reg_values;
+
+ int num_insns;
+ u8 *insns;
+};
+
+u32 ixp2000_uengine_csr_read(int uengine, int offset);
+void ixp2000_uengine_csr_write(int uengine, int offset, u32 value);
+void ixp2000_uengine_reset(u32 uengine_mask);
+void ixp2000_uengine_set_mode(int uengine, u32 mode);
+void ixp2000_uengine_load_microcode(int uengine, u8 *ucode, int insns);
+void ixp2000_uengine_init_context(int uengine, int context, int pc);
+void ixp2000_uengine_start_contexts(int uengine, u8 ctx_mask);
+void ixp2000_uengine_stop_contexts(int uengine, u8 ctx_mask);
+int ixp2000_uengine_load(int uengine, struct ixp2000_uengine_code *c);
+
+#define IXP2000_UENGINE_8_CONTEXTS 0x00000000
+#define IXP2000_UENGINE_4_CONTEXTS 0x80000000
+#define IXP2000_UENGINE_PRN_UPDATE_EVERY 0x40000000
+#define IXP2000_UENGINE_PRN_UPDATE_ON_ACCESS 0x00000000
+#define IXP2000_UENGINE_NN_FROM_SELF 0x00100000
+#define IXP2000_UENGINE_NN_FROM_PREVIOUS 0x00000000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_3 0x000c0000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_2 0x00080000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_1 0x00040000
+#define IXP2000_UENGINE_ASSERT_EMPTY_AT_0 0x00000000
+#define IXP2000_UENGINE_LM_ADDR1_GLOBAL 0x00020000
+#define IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT 0x00000000
+#define IXP2000_UENGINE_LM_ADDR0_GLOBAL 0x00010000
+#define IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT 0x00000000
+
+
+#endif
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
new file mode 100644
index 00000000..5d72550a
--- /dev/null
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/include/asm/hardware/vic.h
+ *
+ * Copyright (c) ARM Limited 2003. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_ARM_HARDWARE_VIC_H
+#define __ASM_ARM_HARDWARE_VIC_H
+
+#define VIC_IRQ_STATUS 0x00
+#define VIC_FIQ_STATUS 0x04
+#define VIC_RAW_STATUS 0x08
+#define VIC_INT_SELECT 0x0c /* 1 = FIQ, 0 = IRQ */
+#define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */
+#define VIC_INT_ENABLE_CLEAR 0x14
+#define VIC_INT_SOFT 0x18
+#define VIC_INT_SOFT_CLEAR 0x1c
+#define VIC_PROTECT 0x20
+#define VIC_PL190_VECT_ADDR 0x30 /* PL190 only */
+#define VIC_PL190_DEF_VECT_ADDR 0x34 /* PL190 only */
+
+#define VIC_VECT_ADDR0 0x100 /* 0 to 15 (0..31 PL192) */
+#define VIC_VECT_CNTL0 0x200 /* 0 to 15 (0..31 PL192) */
+#define VIC_ITCR 0x300 /* VIC test control register */
+
+#define VIC_VECT_CNTL_ENABLE (1 << 5)
+
+#define VIC_PL192_VECT_ADDR 0xF00
+
+#ifndef __ASSEMBLY__
+void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
new file mode 100644
index 00000000..a4edd19d
--- /dev/null
+++ b/arch/arm/include/asm/highmem.h
@@ -0,0 +1,66 @@
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#include <asm/kmap_types.h>
+
+#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)
+#define LAST_PKMAP PTRS_PER_PTE
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define kmap_prot PAGE_KERNEL
+
+#define flush_cache_kmaps() \
+ do { \
+ if (cache_is_vivt()) \
+ flush_cache_all(); \
+ } while (0)
+
+extern pte_t *pkmap_page_table;
+
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+/*
+ * The reason for kmap_high_get() is to ensure that the currently kmap'd
+ * page usage count does not decrease to zero while we're using its
+ * existing virtual mapping in an atomic context. With a VIVT cache this
+ * is essential to do, but with a VIPT cache this is only an optimization
+ * so not to pay the price of establishing a second mapping if an existing
+ * one can be used. However, on platforms without hardware TLB maintenance
+ * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
+ * the locking involved must also disable IRQs which is incompatible with
+ * the IPI mechanism used by global TLB operations.
+ */
+#define ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
+#undef ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
+#error "The sum of features in your kernel config cannot be supported together"
+#endif
+#endif
+
+#ifdef ARCH_NEEDS_KMAP_HIGH_GET
+extern void *kmap_high_get(struct page *page);
+#else
+static inline void *kmap_high_get(struct page *page)
+{
+ return NULL;
+}
+#endif
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *__kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void *kmap_atomic_pfn(unsigned long pfn);
+extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h
new file mode 100644
index 00000000..f389b270
--- /dev/null
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -0,0 +1,133 @@
+#ifndef _ARM_HW_BREAKPOINT_H
+#define _ARM_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+
+struct task_struct;
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint_ctrl {
+ u32 __reserved : 9,
+ mismatch : 1,
+ : 9,
+ len : 8,
+ type : 2,
+ privilege : 2,
+ enabled : 1;
+};
+
+struct arch_hw_breakpoint {
+ u32 address;
+ u32 trigger;
+ struct arch_hw_breakpoint_ctrl step_ctrl;
+ struct arch_hw_breakpoint_ctrl ctrl;
+};
+
+static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
+{
+ return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) |
+ (ctrl.privilege << 1) | ctrl.enabled;
+}
+
+static inline void decode_ctrl_reg(u32 reg,
+ struct arch_hw_breakpoint_ctrl *ctrl)
+{
+ ctrl->enabled = reg & 0x1;
+ reg >>= 1;
+ ctrl->privilege = reg & 0x3;
+ reg >>= 2;
+ ctrl->type = reg & 0x3;
+ reg >>= 2;
+ ctrl->len = reg & 0xff;
+ reg >>= 17;
+ ctrl->mismatch = reg & 0x1;
+}
+
+/* Debug architecture numbers. */
+#define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */
+#define ARM_DEBUG_ARCH_V6 1
+#define ARM_DEBUG_ARCH_V6_1 2
+#define ARM_DEBUG_ARCH_V7_ECP14 3
+#define ARM_DEBUG_ARCH_V7_MM 4
+
+/* Breakpoint */
+#define ARM_BREAKPOINT_EXECUTE 0
+
+/* Watchpoints */
+#define ARM_BREAKPOINT_LOAD 1
+#define ARM_BREAKPOINT_STORE 2
+
+/* Privilege Levels */
+#define ARM_BREAKPOINT_PRIV 1
+#define ARM_BREAKPOINT_USER 2
+
+/* Lengths */
+#define ARM_BREAKPOINT_LEN_1 0x1
+#define ARM_BREAKPOINT_LEN_2 0x3
+#define ARM_BREAKPOINT_LEN_4 0xf
+#define ARM_BREAKPOINT_LEN_8 0xff
+
+/* Limits */
+#define ARM_MAX_BRP 16
+#define ARM_MAX_WRP 16
+#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP)
+
+/* DSCR method of entry bits. */
+#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf)
+#define ARM_ENTRY_BREAKPOINT 0x1
+#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2
+#define ARM_ENTRY_SYNC_WATCHPOINT 0xa
+
+/* DSCR monitor/halting bits. */
+#define ARM_DSCR_HDBGEN (1 << 14)
+#define ARM_DSCR_MDBGEN (1 << 15)
+
+/* opcode2 numbers for the co-processor instructions. */
+#define ARM_OP2_BVR 4
+#define ARM_OP2_BCR 5
+#define ARM_OP2_WVR 6
+#define ARM_OP2_WCR 7
+
+/* Base register numbers for the debug registers. */
+#define ARM_BASE_BVR 64
+#define ARM_BASE_BCR 80
+#define ARM_BASE_WVR 96
+#define ARM_BASE_WCR 112
+
+/* Accessor macros for the debug registers. */
+#define ARM_DBG_READ(M, OP2, VAL) do {\
+ asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\
+} while (0)
+
+#define ARM_DBG_WRITE(M, OP2, VAL) do {\
+ asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\
+} while (0)
+
+struct notifier_block;
+struct perf_event;
+struct pmu;
+
+extern struct pmu perf_ops_bp;
+extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
+ int *gen_len, int *gen_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+
+extern u8 arch_get_debug_arch(void);
+extern u8 arch_get_max_wp_len(void);
+extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+int hw_breakpoint_slots(int type);
+
+#else
+static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _ARM_HW_BREAKPOINT_H */
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
new file mode 100644
index 00000000..a71b417b
--- /dev/null
+++ b/arch/arm/include/asm/hw_irq.h
@@ -0,0 +1,21 @@
+/*
+ * Nothing to see here yet
+ */
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+static inline void ack_bad_irq(int irq)
+{
+ extern unsigned long irq_err_count;
+ irq_err_count++;
+}
+
+void set_irq_flags(unsigned int irq, unsigned int flags);
+
+#define IRQF_VALID (1 << 0)
+#define IRQF_PROBE (1 << 1)
+#define IRQF_NOAUTOEN (1 << 2)
+
+#define ARCH_IRQ_INIT_FLAGS (IRQ_NOREQUEST | IRQ_NOPROBE)
+
+#endif
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
new file mode 100644
index 00000000..c1062c31
--- /dev/null
+++ b/arch/arm/include/asm/hwcap.h
@@ -0,0 +1,33 @@
+#ifndef __ASMARM_HWCAP_H
+#define __ASMARM_HWCAP_H
+
+/*
+ * 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
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this cpu supports.
+ */
+#define ELF_HWCAP (elf_hwcap)
+extern unsigned int elf_hwcap;
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/i8253.h b/arch/arm/include/asm/i8253.h
new file mode 100644
index 00000000..70656b69
--- /dev/null
+++ b/arch/arm/include/asm/i8253.h
@@ -0,0 +1,15 @@
+#ifndef __ASMARM_I8253_H
+#define __ASMARM_I8253_H
+
+/* i8253A PIT registers */
+#define PIT_MODE 0x43
+#define PIT_CH0 0x40
+
+#define PIT_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
+
+extern raw_spinlock_t i8253_lock;
+
+#define outb_pit outb_p
+#define inb_pit inb_p
+
+#endif
diff --git a/arch/arm/include/asm/ide.h b/arch/arm/include/asm/ide.h
new file mode 100644
index 00000000..b507ce8e
--- /dev/null
+++ b/arch/arm/include/asm/ide.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/include/asm/ide.h
+ *
+ * Copyright (C) 1994-1996 Linus Torvalds & authors
+ */
+
+/*
+ * This file contains the ARM architecture specific IDE code.
+ */
+
+#ifndef __ASMARM_IDE_H
+#define __ASMARM_IDE_H
+
+#ifdef __KERNEL__
+
+#define __ide_mm_insw(port,addr,len) readsw(port,addr,len)
+#define __ide_mm_insl(port,addr,len) readsl(port,addr,len)
+#define __ide_mm_outsw(port,addr,len) writesw(port,addr,len)
+#define __ide_mm_outsl(port,addr,len) writesl(port,addr,len)
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASMARM_IDE_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
new file mode 100644
index 00000000..d66605de
--- /dev/null
+++ b/arch/arm/include/asm/io.h
@@ -0,0 +1,317 @@
+/*
+ * arch/arm/include/asm/io.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
+ * constant addresses and variable addresses.
+ * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
+ * specific IO header files.
+ * 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
+ * 04-Apr-1999 PJB Added check_signature.
+ * 12-Dec-1999 RMK More cleanups
+ * 18-Jun-2000 RMK Removed virt_to_* and friends definitions
+ * 05-Oct-2004 BJD Moved memory string functions to use void __iomem
+ */
+#ifndef __ASM_ARM_IO_H
+#define __ASM_ARM_IO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+
+/*
+ * ISA I/O bus memory addresses are 1:1 with the physical address.
+ */
+#define isa_virt_to_bus virt_to_phys
+#define isa_page_to_bus page_to_phys
+#define isa_bus_to_virt phys_to_virt
+
+/*
+ * Generic IO read/write. These perform native-endian accesses. Note
+ * that some architectures will want to re-define __raw_{read,write}w.
+ */
+extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen);
+extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
+extern void __raw_writesl(void __iomem *addr, const void *data, int longlen);
+
+extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
+extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
+extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
+
+#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
+#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
+#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
+
+#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
+#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
+
+/*
+ * Architecture ioremap implementation.
+ */
+#define MT_DEVICE 0
+#define MT_DEVICE_NONSHARED 1
+#define MT_DEVICE_CACHED 2
+#define MT_DEVICE_WC 3
+/*
+ * types 4 onwards can be found in asm/mach/map.h and are undefined
+ * for ioremap
+ */
+
+/*
+ * __arm_ioremap takes CPU physical address.
+ * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
+ * The _caller variety takes a __builtin_return_address(0) value for
+ * /proc/vmalloc to use - and should only be used in non-inline functions.
+ */
+extern void __iomem *__arm_ioremap_pfn_caller(unsigned long, unsigned long,
+ size_t, unsigned int, void *);
+extern void __iomem *__arm_ioremap_caller(unsigned long, size_t, unsigned int,
+ void *);
+
+extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
+extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
+extern void __iounmap(volatile void __iomem *addr);
+
+/*
+ * Bad read/write accesses...
+ */
+extern void __readwrite_bug(const char *fn);
+
+/*
+ * A typesafe __io() helper
+ */
+static inline void __iomem *__typesafe_io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+
+/* IO barriers */
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+#define __iormb() rmb()
+#define __iowmb() wmb()
+#else
+#define __iormb() do { } while (0)
+#define __iowmb() do { } while (0)
+#endif
+
+/*
+ * Now, pick up the machine-defined IO definitions
+ */
+#include <mach/io.h>
+
+/*
+ * IO port access primitives
+ * -------------------------
+ *
+ * The ARM doesn't have special IO access instructions; all IO is memory
+ * mapped. Note that these are defined to perform little endian accesses
+ * only. Their primary purpose is to access PCI and ISA peripherals.
+ *
+ * Note that for a big endian machine, this implies that the following
+ * big endian mode connectivity is in place, as described by numerous
+ * ARM documents:
+ *
+ * PCI: D0-D7 D8-D15 D16-D23 D24-D31
+ * ARM: D24-D31 D16-D23 D8-D15 D0-D7
+ *
+ * The machine specific io.h include defines __io to translate an "IO"
+ * address to a memory address.
+ *
+ * Note that we prevent GCC re-ordering or caching values in expressions
+ * by introducing sequence points into the in*() definitions. Note that
+ * __raw_* do not guarantee this behaviour.
+ *
+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
+ */
+#ifdef __io
+#define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); })
+#define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \
+ cpu_to_le16(v),__io(p)); })
+#define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \
+ cpu_to_le32(v),__io(p)); })
+
+#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
+#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
+ __raw_readw(__io(p))); __iormb(); __v; })
+#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
+ __raw_readl(__io(p))); __iormb(); __v; })
+
+#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
+#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
+#define outsl(p,d,l) __raw_writesl(__io(p),d,l)
+
+#define insb(p,d,l) __raw_readsb(__io(p),d,l)
+#define insw(p,d,l) __raw_readsw(__io(p),d,l)
+#define insl(p,d,l) __raw_readsl(__io(p),d,l)
+#endif
+
+#define outb_p(val,port) outb((val),(port))
+#define outw_p(val,port) outw((val),(port))
+#define outl_p(val,port) outl((val),(port))
+#define inb_p(port) inb((port))
+#define inw_p(port) inw((port))
+#define inl_p(port) inl((port))
+
+#define outsb_p(port,from,len) outsb(port,from,len)
+#define outsw_p(port,from,len) outsw(port,from,len)
+#define outsl_p(port,from,len) outsl(port,from,len)
+#define insb_p(port,to,len) insb(port,to,len)
+#define insw_p(port,to,len) insw(port,to,len)
+#define insl_p(port,to,len) insl(port,to,len)
+
+/*
+ * String version of IO memory access ops:
+ */
+extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t);
+extern void _memcpy_toio(volatile void __iomem *, const void *, size_t);
+extern void _memset_io(volatile void __iomem *, int, size_t);
+
+#define mmiowb()
+
+/*
+ * Memory access primitives
+ * ------------------------
+ *
+ * These perform PCI memory accesses via an ioremap region. They don't
+ * take an address as such, but a cookie.
+ *
+ * Again, this are defined to perform little endian accesses. See the
+ * IO port primitives for more information.
+ */
+#ifdef __mem_pci
+#define readb_relaxed(c) ({ u8 __v = __raw_readb(__mem_pci(c)); __v; })
+#define readw_relaxed(c) ({ u16 __v = le16_to_cpu((__force __le16) \
+ __raw_readw(__mem_pci(c))); __v; })
+#define readl_relaxed(c) ({ u32 __v = le32_to_cpu((__force __le32) \
+ __raw_readl(__mem_pci(c))); __v; })
+
+#define writeb_relaxed(v,c) ((void)__raw_writeb(v,__mem_pci(c)))
+#define writew_relaxed(v,c) ((void)__raw_writew((__force u16) \
+ cpu_to_le16(v),__mem_pci(c)))
+#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
+ cpu_to_le32(v),__mem_pci(c)))
+
+#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
+#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
+#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
+
+#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); })
+#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); })
+#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
+
+#define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l)
+#define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l)
+#define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l)
+
+#define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l)
+#define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l)
+#define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l)
+
+#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l))
+#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l))
+#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l))
+
+#elif !defined(readb)
+
+#define readb(c) (__readwrite_bug("readb"),0)
+#define readw(c) (__readwrite_bug("readw"),0)
+#define readl(c) (__readwrite_bug("readl"),0)
+#define writeb(v,c) __readwrite_bug("writeb")
+#define writew(v,c) __readwrite_bug("writew")
+#define writel(v,c) __readwrite_bug("writel")
+
+#define check_signature(io,sig,len) (0)
+
+#endif /* __mem_pci */
+
+/*
+ * ioremap and friends.
+ *
+ * ioremap takes a PCI memory address, as specified in
+ * Documentation/IO-mapping.txt.
+ *
+ */
+#ifndef __arch_ioremap
+#define __arch_ioremap __arm_ioremap
+#define __arch_iounmap __iounmap
+#endif
+
+#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
+#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
+#define ioremap_wc(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_WC)
+#define iounmap __arch_iounmap
+
+/*
+ * io{read,write}{8,16,32} macros
+ */
+#ifndef ioread8
+#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __iormb(); __v; })
+#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __iormb(); __v; })
+#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __iormb(); __v; })
+
+#define iowrite8(v,p) ({ __iowmb(); (void)__raw_writeb(v, p); })
+#define iowrite16(v,p) ({ __iowmb(); (void)__raw_writew((__force __u16)cpu_to_le16(v), p); })
+#define iowrite32(v,p) ({ __iowmb(); (void)__raw_writel((__force __u32)cpu_to_le32(v), p); })
+
+#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
+#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
+#define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
+
+#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c)
+#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c)
+#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c)
+
+extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
+extern void ioport_unmap(void __iomem *addr);
+#endif
+
+struct pci_dev;
+
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
+extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
+
+/*
+ * can the hardware map this into one segment or not, given no other
+ * constraints.
+ */
+#define BIOVEC_MERGEABLE(vec1, vec2) \
+ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
+
+#ifdef CONFIG_MMU
+#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
+extern int valid_phys_addr_range(unsigned long addr, size_t size);
+extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
+extern int devmem_is_allowed(unsigned long pfn);
+#endif
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+/*
+ * Register ISA memory and port locations for glibc iopl/inb/outb
+ * emulation.
+ */
+extern void register_isa_ports(unsigned int mmio, unsigned int io,
+ unsigned int io_shift);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_ARM_IO_H */
diff --git a/arch/arm/include/asm/ioctl.h b/arch/arm/include/asm/ioctl.h
new file mode 100644
index 00000000..b279fe06
--- /dev/null
+++ b/arch/arm/include/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/arm/include/asm/ioctls.h b/arch/arm/include/asm/ioctls.h
new file mode 100644
index 00000000..9c962981
--- /dev/null
+++ b/arch/arm/include/asm/ioctls.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_ARM_IOCTLS_H
+#define __ASM_ARM_IOCTLS_H
+
+#define FIOQSIZE 0x545E
+
+#include <asm-generic/ioctls.h>
+
+#endif
diff --git a/arch/arm/include/asm/ipcbuf.h b/arch/arm/include/asm/ipcbuf.h
new file mode 100644
index 00000000..97683975
--- /dev/null
+++ b/arch/arm/include/asm/ipcbuf.h
@@ -0,0 +1,29 @@
+#ifndef __ASMARM_IPCBUF_H
+#define __ASMARM_IPCBUF_H
+
+/*
+ * The ipc64_perm structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct ipc64_perm
+{
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif /* __ASMARM_IPCBUF_H */
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
new file mode 100644
index 00000000..a5656333
--- /dev/null
+++ b/arch/arm/include/asm/irq.h
@@ -0,0 +1,35 @@
+#ifndef __ASM_ARM_IRQ_H
+#define __ASM_ARM_IRQ_H
+
+#include <mach/irqs.h>
+
+#ifndef irq_canonicalize
+#define irq_canonicalize(i) (i)
+#endif
+
+#define NR_IRQS_LEGACY 16
+
+/*
+ * Use this value to indicate lack of interrupt
+ * capability
+ */
+#ifndef NO_IRQ
+#define NO_IRQ ((unsigned int)(-1))
+#endif
+
+#ifndef __ASSEMBLY__
+struct irqaction;
+struct pt_regs;
+extern void migrate_irqs(void);
+
+extern void asm_do_IRQ(unsigned int, struct pt_regs *);
+void handle_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/irq_regs.h b/arch/arm/include/asm/irq_regs.h
new file mode 100644
index 00000000..3dd9c0b7
--- /dev/null
+++ b/arch/arm/include/asm/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
new file mode 100644
index 00000000..1e6cca55
--- /dev/null
+++ b/arch/arm/include/asm/irqflags.h
@@ -0,0 +1,155 @@
+#ifndef __ASM_ARM_IRQFLAGS_H
+#define __ASM_ARM_IRQFLAGS_H
+
+#ifdef __KERNEL__
+
+#include <asm/ptrace.h>
+
+/*
+ * CPU interrupt mask handling.
+ */
+#if __LINUX_ARM_ARCH__ >= 6
+
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_save\n"
+ " cpsid i"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+}
+
+static inline void arch_local_irq_enable(void)
+{
+ asm volatile(
+ " cpsie i @ arch_local_irq_enable"
+ :
+ :
+ : "memory", "cc");
+}
+
+static inline void arch_local_irq_disable(void)
+{
+ asm volatile(
+ " cpsid i @ arch_local_irq_disable"
+ :
+ :
+ : "memory", "cc");
+}
+
+#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
+#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
+#else
+
+/*
+ * Save the current interrupt enable state & disable IRQs
+ */
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags, temp;
+
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_save\n"
+ " orr %1, %0, #128\n"
+ " msr cpsr_c, %1"
+ : "=r" (flags), "=r" (temp)
+ :
+ : "memory", "cc");
+ return flags;
+}
+
+/*
+ * Enable IRQs
+ */
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long temp;
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_enable\n"
+ " bic %0, %0, #128\n"
+ " msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory", "cc");
+}
+
+/*
+ * Disable IRQs
+ */
+static inline void arch_local_irq_disable(void)
+{
+ unsigned long temp;
+ asm volatile(
+ " mrs %0, cpsr @ arch_local_irq_disable\n"
+ " orr %0, %0, #128\n"
+ " msr cpsr_c, %0"
+ : "=r" (temp)
+ :
+ : "memory", "cc");
+}
+
+/*
+ * Enable FIQs
+ */
+#define local_fiq_enable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ stf\n" \
+" bic %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+/*
+ * Disable FIQs
+ */
+#define local_fiq_disable() \
+ ({ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "mrs %0, cpsr @ clf\n" \
+" orr %0, %0, #64\n" \
+" msr cpsr_c, %0" \
+ : "=r" (temp) \
+ : \
+ : "memory", "cc"); \
+ })
+
+#endif
+
+/*
+ * Save the current interrupt enable state.
+ */
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+ asm volatile(
+ " mrs %0, cpsr @ local_save_flags"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+}
+
+/*
+ * restore saved IRQ & FIQ state
+ */
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile(
+ " msr cpsr_c, %0 @ local_irq_restore"
+ :
+ : "r" (flags)
+ : "memory", "cc");
+}
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return flags & PSR_I_BIT;
+}
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/kdebug.h b/arch/arm/include/asm/kdebug.h
new file mode 100644
index 00000000..6ece1b03
--- /dev/null
+++ b/arch/arm/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
new file mode 100644
index 00000000..c2b9b4bd
--- /dev/null
+++ b/arch/arm/include/asm/kexec.h
@@ -0,0 +1,60 @@
+#ifndef _ARM_KEXEC_H
+#define _ARM_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+#define KEXEC_CONTROL_PAGE_SIZE 4096
+
+#define KEXEC_ARCH KEXEC_ARCH_ARM
+
+#define KEXEC_ARM_ATAGS_OFFSET 0x1000
+#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
+
+#ifndef __ASSEMBLY__
+
+/**
+ * crash_setup_regs() - save registers for the panic kernel
+ * @newregs: registers are saved here
+ * @oldregs: registers to be saved (may be %NULL)
+ *
+ * Function copies machine registers from @oldregs to @newregs. If @oldregs is
+ * %NULL then current registers are stored there.
+ */
+static inline void crash_setup_regs(struct pt_regs *newregs,
+ struct pt_regs *oldregs)
+{
+ if (oldregs) {
+ memcpy(newregs, oldregs, sizeof(*newregs));
+ } else {
+ __asm__ __volatile__ (
+ "stmia %[regs_base], {r0-r12}\n\t"
+ "mov %[_ARM_sp], sp\n\t"
+ "str lr, %[_ARM_lr]\n\t"
+ "adr %[_ARM_pc], 1f\n\t"
+ "mrs %[_ARM_cpsr], cpsr\n\t"
+ "1:"
+ : [_ARM_pc] "=r" (newregs->ARM_pc),
+ [_ARM_cpsr] "=r" (newregs->ARM_cpsr),
+ [_ARM_sp] "=r" (newregs->ARM_sp),
+ [_ARM_lr] "=o" (newregs->ARM_lr)
+ : [regs_base] "r" (&newregs->ARM_r0)
+ : "memory"
+ );
+ }
+}
+
+/* Function pointer to optional machine-specific reinitialization */
+extern void (*kexec_reinit)(void);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ARM_KEXEC_H */
diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h
new file mode 100644
index 00000000..48066ce9
--- /dev/null
+++ b/arch/arm/include/asm/kgdb.h
@@ -0,0 +1,105 @@
+/*
+ * ARM KGDB support
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2002 MontaVista Software Inc.
+ *
+ */
+
+#ifndef __ARM_KGDB_H__
+#define __ARM_KGDB_H__
+
+#include <linux/ptrace.h>
+
+/*
+ * GDB assumes that we're a user process being debugged, so
+ * it will send us an SWI command to write into memory as the
+ * debug trap. When an SWI occurs, the next instruction addr is
+ * placed into R14_svc before jumping to the vector trap.
+ * This doesn't work for kernel debugging as we are already in SVC
+ * we would loose the kernel's LR, which is a bad thing. This
+ * is bad thing.
+ *
+ * By doing this as an undefined instruction trap, we force a mode
+ * switch from SVC to UND mode, allowing us to save full kernel state.
+ *
+ * We also define a KGDB_COMPILED_BREAK which can be used to compile
+ * in breakpoints. This is important for things like sysrq-G and for
+ * the initial breakpoint from trap_init().
+ *
+ * Note to ARM HW designers: Add real trap support like SH && PPC to
+ * make our lives much much simpler. :)
+ */
+#define BREAK_INSTR_SIZE 4
+#define GDB_BREAKINST 0xef9f0001
+#define KGDB_BREAKINST 0xe7ffdefe
+#define KGDB_COMPILED_BREAK 0xe7ffdeff
+#define CACHE_FLUSH_IS_SAFE 1
+
+#ifndef __ASSEMBLY__
+
+static inline void arch_kgdb_breakpoint(void)
+{
+ asm(".word 0xe7ffdeff");
+}
+
+extern void kgdb_handle_bus_error(void);
+extern int kgdb_fault_expected;
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * From Kevin Hilman:
+ *
+ * gdb is expecting the following registers layout.
+ *
+ * r0-r15: 1 long word each
+ * f0-f7: unused, 3 long words each !!
+ * fps: unused, 1 long word
+ * cpsr: 1 long word
+ *
+ * Even though f0-f7 and fps are not used, they need to be
+ * present in the registers sent for correct processing in
+ * the host-side gdb.
+ *
+ * In particular, it is crucial that CPSR is in the right place,
+ * otherwise gdb will not be able to correctly interpret stepping over
+ * conditional branches.
+ */
+#define _GP_REGS 16
+#define _FP_REGS 8
+#define _EXTRA_REGS 2
+#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
+#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
+
+#define KGDB_MAX_NO_CPUS 1
+#define BUFMAX 400
+#define NUMREGBYTES (DBG_MAX_REG_NUM << 2)
+#define NUMCRITREGBYTES (32 << 2)
+
+#define _R0 0
+#define _R1 1
+#define _R2 2
+#define _R3 3
+#define _R4 4
+#define _R5 5
+#define _R6 6
+#define _R7 7
+#define _R8 8
+#define _R9 9
+#define _R10 10
+#define _FP 11
+#define _IP 12
+#define _SPT 13
+#define _LR 14
+#define _PC 15
+#define _CPSR (GDB_MAX_REGS - 1)
+
+/*
+ * So that we can denote the end of a frame for tracing,
+ * in the simple case:
+ */
+#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC, _SPT, func)
+
+#endif /* __ASM_KGDB_H__ */
diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h
new file mode 100644
index 00000000..e51b1e81
--- /dev/null
+++ b/arch/arm/include/asm/kmap_types.h
@@ -0,0 +1,33 @@
+#ifndef __ARM_KMAP_TYPES_H
+#define __ARM_KMAP_TYPES_H
+
+/*
+ * This is the "bare minimum". AIO seems to require this.
+ */
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_L1_CACHE,
+ KM_L2_CACHE,
+ KM_KDB,
+ KM_TYPE_NR
+};
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI (-1)
+#define KM_NMI_PTE (-1)
+#define KM_IRQ_PTE (-1)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
new file mode 100644
index 00000000..e46bdd00
--- /dev/null
+++ b/arch/arm/include/asm/kprobes.h
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/include/asm/kprobes.h
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 _ARM_KPROBES_H
+#define _ARM_KPROBES_H
+
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/percpu.h>
+
+#define __ARCH_WANT_KPROBES_INSN_SLOT
+#define MAX_INSN_SIZE 2
+#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
+
+/*
+ * This undefined instruction must be unique and
+ * reserved solely for kprobes' use.
+ */
+#define KPROBE_BREAKPOINT_INSTRUCTION 0xe7f001f8
+
+#define regs_return_value(regs) ((regs)->ARM_r0)
+#define flush_insn_slot(p) do { } while (0)
+#define kretprobe_blacklist_size 0
+
+typedef u32 kprobe_opcode_t;
+
+struct kprobe;
+typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *);
+
+typedef unsigned long (kprobe_check_cc)(unsigned long);
+
+/* Architecture specific copy of original instruction. */
+struct arch_specific_insn {
+ kprobe_opcode_t *insn;
+ kprobe_insn_handler_t *insn_handler;
+ kprobe_check_cc *insn_check_cc;
+};
+
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned int status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned int kprobe_status;
+ struct prev_kprobe prev_kprobe;
+ struct pt_regs jprobe_saved_regs;
+ char jprobes_stack[MAX_STACK_SIZE];
+};
+
+void arch_remove_kprobe(struct kprobe *);
+void kretprobe_trampoline(void);
+
+int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
+int kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data);
+
+enum kprobe_insn {
+ INSN_REJECTED,
+ INSN_GOOD,
+ INSN_GOOD_NO_SLOT
+};
+
+enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t,
+ struct arch_specific_insn *);
+void __init arm_kprobe_decode_init(void);
+
+#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm/include/asm/leds.h b/arch/arm/include/asm/leds.h
new file mode 100644
index 00000000..c545739f
--- /dev/null
+++ b/arch/arm/include/asm/leds.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/include/asm/leds.h
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Event-driven interface for LEDs on machines
+ * Added led_start and led_stop- Alex Holden, 28th Dec 1998.
+ */
+#ifndef ASM_ARM_LEDS_H
+#define ASM_ARM_LEDS_H
+
+
+typedef enum {
+ led_idle_start,
+ led_idle_end,
+ led_timer,
+ led_start,
+ led_stop,
+ led_claim, /* override idle & timer leds */
+ led_release, /* restore idle & timer leds */
+ led_start_timer_mode,
+ led_stop_timer_mode,
+ led_green_on,
+ led_green_off,
+ led_amber_on,
+ led_amber_off,
+ led_red_on,
+ led_red_off,
+ led_blue_on,
+ led_blue_off,
+ /*
+ * I want this between led_timer and led_start, but
+ * someone has decided to export this to user space
+ */
+ led_halted
+} led_event_t;
+
+/* Use this routine to handle LEDs */
+
+#ifdef CONFIG_LEDS
+extern void (*leds_event)(led_event_t);
+#else
+#define leds_event(e)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/limits.h b/arch/arm/include/asm/limits.h
new file mode 100644
index 00000000..08d8c660
--- /dev/null
+++ b/arch/arm/include/asm/limits.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_PIPE_H
+#define __ASM_PIPE_H
+
+#ifndef PAGE_SIZE
+#include <asm/page.h>
+#endif
+
+#define PIPE_BUF PAGE_SIZE
+
+#endif
+
diff --git a/arch/arm/include/asm/linkage.h b/arch/arm/include/asm/linkage.h
new file mode 100644
index 00000000..5a25632b
--- /dev/null
+++ b/arch/arm/include/asm/linkage.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+
+#define ENDPROC(name) \
+ .type name, %function; \
+ END(name)
+
+#endif
diff --git a/arch/arm/include/asm/local.h b/arch/arm/include/asm/local.h
new file mode 100644
index 00000000..c11c530f
--- /dev/null
+++ b/arch/arm/include/asm/local.h
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff --git a/arch/arm/include/asm/local64.h b/arch/arm/include/asm/local64.h
new file mode 100644
index 00000000..36c93b5c
--- /dev/null
+++ b/arch/arm/include/asm/local64.h
@@ -0,0 +1 @@
+#include <asm-generic/local64.h>
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
new file mode 100644
index 00000000..080d74f8
--- /dev/null
+++ b/arch/arm/include/asm/localtimer.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/include/asm/localtimer.h
+ *
+ * Copyright (C) 2004-2005 ARM 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 __ASM_ARM_LOCALTIMER_H
+#define __ASM_ARM_LOCALTIMER_H
+
+struct clock_event_device;
+
+/*
+ * Setup a per-cpu timer, whether it be a local timer or dummy broadcast
+ */
+void percpu_timer_setup(void);
+
+/*
+ * Called from assembly, this is the local timer IRQ handler
+ */
+asmlinkage void do_local_timer(struct pt_regs *);
+
+
+#ifdef CONFIG_LOCAL_TIMERS
+
+#ifdef CONFIG_HAVE_ARM_TWD
+
+#include "smp_twd.h"
+
+#define local_timer_ack() twd_timer_ack()
+
+#else
+
+/*
+ * Platform provides this to acknowledge a local timer IRQ.
+ * Returns true if the local timer IRQ is to be processed.
+ */
+int local_timer_ack(void);
+
+#endif
+
+/*
+ * Setup a local timer interrupt for a CPU.
+ */
+int local_timer_setup(struct clock_event_device *);
+
+#else
+
+static inline int local_timer_setup(struct clock_event_device *evt)
+{
+ return -ENXIO;
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/locks.h b/arch/arm/include/asm/locks.h
new file mode 100644
index 00000000..ef4c8977
--- /dev/null
+++ b/arch/arm/include/asm/locks.h
@@ -0,0 +1,274 @@
+/*
+ * arch/arm/include/asm/locks.h
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Interrupt safe locking assembler.
+ */
+#ifndef __ASM_PROC_LOCKS_H
+#define __ASM_PROC_LOCKS_H
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+#define __down_op(ptr,fail) \
+ ({ \
+ __asm__ __volatile__( \
+ "@ down_op\n" \
+"1: ldrex lr, [%0]\n" \
+" sub lr, lr, %1\n" \
+" strex ip, lr, [%0]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" teq lr, #0\n" \
+" movmi ip, %0\n" \
+" blmi " #fail \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ })
+
+#define __down_op_ret(ptr,fail) \
+ ({ \
+ unsigned int ret; \
+ __asm__ __volatile__( \
+ "@ down_op_ret\n" \
+"1: ldrex lr, [%1]\n" \
+" sub lr, lr, %2\n" \
+" strex ip, lr, [%1]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" teq lr, #0\n" \
+" movmi ip, %1\n" \
+" movpl ip, #0\n" \
+" blmi " #fail "\n" \
+" mov %0, ip" \
+ : "=&r" (ret) \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ ret; \
+ })
+
+#define __up_op(ptr,wake) \
+ ({ \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "@ up_op\n" \
+"1: ldrex lr, [%0]\n" \
+" add lr, lr, %1\n" \
+" strex ip, lr, [%0]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" cmp lr, #0\n" \
+" movle ip, %0\n" \
+" blle " #wake \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ })
+
+/*
+ * The value 0x01000000 supports up to 128 processors and
+ * lots of processes. BIAS must be chosen such that sub'ing
+ * BIAS once per CPU will result in the long remaining
+ * negative.
+ */
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __down_op_write(ptr,fail) \
+ ({ \
+ __asm__ __volatile__( \
+ "@ down_op_write\n" \
+"1: ldrex lr, [%0]\n" \
+" sub lr, lr, %1\n" \
+" strex ip, lr, [%0]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" teq lr, #0\n" \
+" movne ip, %0\n" \
+" blne " #fail \
+ : \
+ : "r" (ptr), "I" (RW_LOCK_BIAS) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ })
+
+#define __up_op_write(ptr,wake) \
+ ({ \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "@ up_op_write\n" \
+"1: ldrex lr, [%0]\n" \
+" adds lr, lr, %1\n" \
+" strex ip, lr, [%0]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" movcs ip, %0\n" \
+" blcs " #wake \
+ : \
+ : "r" (ptr), "I" (RW_LOCK_BIAS) \
+ : "ip", "lr", "cc"); \
+ })
+
+#define __down_op_read(ptr,fail) \
+ __down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake) \
+ ({ \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "@ up_op_read\n" \
+"1: ldrex lr, [%0]\n" \
+" add lr, lr, %1\n" \
+" strex ip, lr, [%0]\n" \
+" teq ip, #0\n" \
+" bne 1b\n" \
+" teq lr, #0\n" \
+" moveq ip, %0\n" \
+" bleq " #wake \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ })
+
+#else
+
+#define __down_op(ptr,fail) \
+ ({ \
+ __asm__ __volatile__( \
+ "@ down_op\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%0]\n" \
+" subs lr, lr, %1\n" \
+" str lr, [%0]\n" \
+" msr cpsr_c, ip\n" \
+" movmi ip, %0\n" \
+" blmi " #fail \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ })
+
+#define __down_op_ret(ptr,fail) \
+ ({ \
+ unsigned int ret; \
+ __asm__ __volatile__( \
+ "@ down_op_ret\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%1]\n" \
+" subs lr, lr, %2\n" \
+" str lr, [%1]\n" \
+" msr cpsr_c, ip\n" \
+" movmi ip, %1\n" \
+" movpl ip, #0\n" \
+" blmi " #fail "\n" \
+" mov %0, ip" \
+ : "=&r" (ret) \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ ret; \
+ })
+
+#define __up_op(ptr,wake) \
+ ({ \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "@ up_op\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%0]\n" \
+" adds lr, lr, %1\n" \
+" str lr, [%0]\n" \
+" msr cpsr_c, ip\n" \
+" movle ip, %0\n" \
+" blle " #wake \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ })
+
+/*
+ * The value 0x01000000 supports up to 128 processors and
+ * lots of processes. BIAS must be chosen such that sub'ing
+ * BIAS once per CPU will result in the long remaining
+ * negative.
+ */
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __down_op_write(ptr,fail) \
+ ({ \
+ __asm__ __volatile__( \
+ "@ down_op_write\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%0]\n" \
+" subs lr, lr, %1\n" \
+" str lr, [%0]\n" \
+" msr cpsr_c, ip\n" \
+" movne ip, %0\n" \
+" blne " #fail \
+ : \
+ : "r" (ptr), "I" (RW_LOCK_BIAS) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ })
+
+#define __up_op_write(ptr,wake) \
+ ({ \
+ __asm__ __volatile__( \
+ "@ up_op_write\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%0]\n" \
+" adds lr, lr, %1\n" \
+" str lr, [%0]\n" \
+" msr cpsr_c, ip\n" \
+" movcs ip, %0\n" \
+" blcs " #wake \
+ : \
+ : "r" (ptr), "I" (RW_LOCK_BIAS) \
+ : "ip", "lr", "cc"); \
+ smp_mb(); \
+ })
+
+#define __down_op_read(ptr,fail) \
+ __down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake) \
+ ({ \
+ smp_mb(); \
+ __asm__ __volatile__( \
+ "@ up_op_read\n" \
+" mrs ip, cpsr\n" \
+" orr lr, ip, #128\n" \
+" msr cpsr_c, lr\n" \
+" ldr lr, [%0]\n" \
+" adds lr, lr, %1\n" \
+" str lr, [%0]\n" \
+" msr cpsr_c, ip\n" \
+" moveq ip, %0\n" \
+" bleq " #wake \
+ : \
+ : "r" (ptr), "I" (1) \
+ : "ip", "lr", "cc"); \
+ })
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/mach-types.h b/arch/arm/include/asm/mach-types.h
new file mode 100644
index 00000000..948178cc
--- /dev/null
+++ b/arch/arm/include/asm/mach-types.h
@@ -0,0 +1 @@
+#include <generated/mach-types.h>
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
new file mode 100644
index 00000000..946f4d77
--- /dev/null
+++ b/arch/arm/include/asm/mach/arch.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/include/asm/mach/arch.h
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can 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 __ASSEMBLY__
+
+struct tag;
+struct meminfo;
+struct sys_timer;
+
+struct machine_desc {
+ unsigned int nr; /* architecture number */
+ const char *name; /* architecture name */
+ unsigned long boot_params; /* tagged list */
+ const char **dt_compat; /* array of device tree
+ * 'compatible' strings */
+
+ unsigned int nr_irqs; /* number of IRQs */
+
+ unsigned int video_start; /* start of video RAM */
+ unsigned int video_end; /* end of video RAM */
+
+ unsigned int reserve_lp0 :1; /* never has lp0 */
+ unsigned int reserve_lp1 :1; /* never has lp1 */
+ unsigned int reserve_lp2 :1; /* never has lp2 */
+ unsigned int soft_reboot :1; /* soft reboot */
+ void (*fixup)(struct machine_desc *,
+ struct tag *, char **,
+ struct meminfo *);
+ void (*reserve)(void);/* reserve mem blocks */
+ void (*map_io)(void);/* IO mapping function */
+ void (*init_early)(void);
+ void (*init_irq)(void);
+ struct sys_timer *timer; /* system tick timer */
+ void (*init_machine)(void);
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ void (*handle_irq)(struct pt_regs *);
+#endif
+};
+
+/*
+ * Current machine - only accessible during boot.
+ */
+extern struct machine_desc *machine_desc;
+
+/*
+ * Machine type table - also only accessible during boot
+ */
+extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+#define for_each_machine_desc(p) \
+ for (p = __arch_info_begin; p < __arch_info_end; p++)
+
+/*
+ * Set of macros to define architecture features. This is built into
+ * a table by the linker.
+ */
+#define MACHINE_START(_type,_name) \
+static const struct machine_desc __mach_desc_##_type \
+ __used \
+ __attribute__((__section__(".arch.info.init"))) = { \
+ .nr = MACH_TYPE_##_type, \
+ .name = _name,
+
+#define MACHINE_END \
+};
+
+#endif
diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h
new file mode 100644
index 00000000..9e614a18
--- /dev/null
+++ b/arch/arm/include/asm/mach/dma.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/include/asm/mach/dma.h
+ *
+ * Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can 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 header file describes the interface between the generic DMA handler
+ * (dma.c) and the architecture-specific DMA backends (dma-*.c)
+ */
+
+struct dma_struct;
+typedef struct dma_struct dma_t;
+
+struct dma_ops {
+ int (*request)(unsigned int, dma_t *); /* optional */
+ void (*free)(unsigned int, dma_t *); /* optional */
+ void (*enable)(unsigned int, dma_t *); /* mandatory */
+ void (*disable)(unsigned int, dma_t *); /* mandatory */
+ int (*residue)(unsigned int, dma_t *); /* optional */
+ int (*setspeed)(unsigned int, dma_t *, int); /* optional */
+ const char *type;
+};
+
+struct dma_struct {
+ void *addr; /* single DMA address */
+ unsigned long count; /* single DMA size */
+ struct scatterlist buf; /* single DMA */
+ int sgcount; /* number of DMA SG */
+ struct scatterlist *sg; /* DMA Scatter-Gather List */
+
+ unsigned int active:1; /* Transfer active */
+ unsigned int invalid:1; /* Address/Count changed */
+
+ unsigned int dma_mode; /* DMA mode */
+ int speed; /* DMA speed */
+
+ unsigned int lock; /* Device is allocated */
+ const char *device_id; /* Device name */
+
+ const struct dma_ops *d_ops;
+};
+
+/*
+ * isa_dma_add - add an ISA-style DMA channel
+ */
+extern int isa_dma_add(unsigned int, dma_t *dma);
+
+/*
+ * Add the ISA DMA controller. Always takes channels 0-7.
+ */
+extern void isa_init_dma(void);
diff --git a/arch/arm/include/asm/mach/flash.h b/arch/arm/include/asm/mach/flash.h
new file mode 100644
index 00000000..4ca69fe2
--- /dev/null
+++ b/arch/arm/include/asm/mach/flash.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/include/asm/mach/flash.h
+ *
+ * Copyright (C) 2003 Russell King, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASMARM_MACH_FLASH_H
+#define ASMARM_MACH_FLASH_H
+
+struct mtd_partition;
+struct mtd_info;
+
+/*
+ * map_name: the map probe function name
+ * name: flash device name (eg, as used with mtdparts=)
+ * width: width of mapped device
+ * init: method called at driver/device initialisation
+ * exit: method called at driver/device removal
+ * set_vpp: method called to enable or disable VPP
+ * mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
+ * parts: optional array of mtd_partitions for static partitioning
+ * nr_parts: number of mtd_partitions for static partitoning
+ */
+struct flash_platform_data {
+ const char *map_name;
+ const char *name;
+ unsigned int width;
+ int (*init)(void);
+ void (*exit)(void);
+ void (*set_vpp)(int on);
+ void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
+ struct mtd_partition *parts;
+ unsigned int nr_parts;
+};
+
+#endif
diff --git a/arch/arm/include/asm/mach/irda.h b/arch/arm/include/asm/mach/irda.h
new file mode 100644
index 00000000..38f77b5e
--- /dev/null
+++ b/arch/arm/include/asm/mach/irda.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/include/asm/mach/irda.h
+ *
+ * Copyright (C) 2004 Russell King.
+ *
+ * This program is free software; you can 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_MACH_IRDA_H
+#define __ASM_ARM_MACH_IRDA_H
+
+struct irda_platform_data {
+ int (*startup)(struct device *);
+ void (*shutdown)(struct device *);
+ int (*set_power)(struct device *, unsigned int state);
+ void (*set_speed)(struct device *, unsigned int speed);
+};
+
+#endif
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
new file mode 100644
index 00000000..febe495d
--- /dev/null
+++ b/arch/arm/include/asm/mach/irq.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/include/asm/mach/irq.h
+ *
+ * Copyright (C) 1995-2000 Russell King.
+ *
+ * This program is free software; you can 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_MACH_IRQ_H
+#define __ASM_ARM_MACH_IRQ_H
+
+#include <linux/irq.h>
+
+struct seq_file;
+
+/*
+ * This is internal. Do not use it.
+ */
+extern void init_FIQ(void);
+extern int show_fiq_list(struct seq_file *, int);
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+extern void (*handle_arch_irq)(struct pt_regs *);
+#endif
+
+/*
+ * This is for easy migration, but should be changed in the source
+ */
+#define do_bad_IRQ(irq,desc) \
+do { \
+ raw_spin_lock(&desc->lock); \
+ handle_bad_irq(irq, desc); \
+ raw_spin_unlock(&desc->lock); \
+} while(0)
+
+#ifndef __ASSEMBLY__
+/*
+ * Entry/exit functions for chained handlers where the primary IRQ chip
+ * may implement either fasteoi or level-trigger flow control.
+ */
+static inline void chained_irq_enter(struct irq_chip *chip,
+ struct irq_desc *desc)
+{
+ /* FastEOI controllers require no action on entry. */
+ if (chip->irq_eoi)
+ return;
+
+ if (chip->irq_mask_ack) {
+ chip->irq_mask_ack(&desc->irq_data);
+ } else {
+ chip->irq_mask(&desc->irq_data);
+ if (chip->irq_ack)
+ chip->irq_ack(&desc->irq_data);
+ }
+}
+
+static inline void chained_irq_exit(struct irq_chip *chip,
+ struct irq_desc *desc)
+{
+ if (chip->irq_eoi)
+ chip->irq_eoi(&desc->irq_data);
+ else
+ chip->irq_unmask(&desc->irq_data);
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h
new file mode 100644
index 00000000..d2fedb5a
--- /dev/null
+++ b/arch/arm/include/asm/mach/map.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/include/asm/map.h
+ *
+ * Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Page table mapping constructs and function prototypes
+ */
+#include <asm/io.h>
+
+struct map_desc {
+ unsigned long virtual;
+ unsigned long pfn;
+ unsigned long length;
+ unsigned int type;
+};
+
+/* types 0-3 are defined in asm/io.h */
+#define MT_UNCACHED 4
+#define MT_CACHECLEAN 5
+#define MT_MINICLEAN 6
+#define MT_LOW_VECTORS 7
+#define MT_HIGH_VECTORS 8
+#define MT_MEMORY 9
+#define MT_ROM 10
+#define MT_MEMORY_NONCACHED 11
+#define MT_MEMORY_DTCM 12
+#define MT_MEMORY_ITCM 13
+
+#ifdef CONFIG_MMU
+extern void iotable_init(struct map_desc *, int);
+
+struct mem_type;
+extern const struct mem_type *get_mem_type(unsigned int type);
+/*
+ * external interface to remap single page with appropriate type
+ */
+extern int ioremap_page(unsigned long virt, unsigned long phys,
+ const struct mem_type *mtype);
+#else
+#define iotable_init(map,num) do { } while (0)
+#endif
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
new file mode 100644
index 00000000..bca864ac
--- /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/mach/pci.h b/arch/arm/include/asm/mach/pci.h
new file mode 100644
index 00000000..16330bd0
--- /dev/null
+++ b/arch/arm/include/asm/mach/pci.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/include/asm/mach/pci.h
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can 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_MACH_PCI_H
+#define __ASM_MACH_PCI_H
+
+struct pci_sys_data;
+struct pci_bus;
+
+struct hw_pci {
+#ifdef CONFIG_PCI_DOMAINS
+ int domain;
+#endif
+ struct list_head buses;
+ int nr_controllers;
+ int (*setup)(int nr, struct pci_sys_data *);
+ struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
+ void (*preinit)(void);
+ void (*postinit)(void);
+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
+ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+};
+
+/*
+ * Per-controller structure
+ */
+struct pci_sys_data {
+#ifdef CONFIG_PCI_DOMAINS
+ int domain;
+#endif
+ struct list_head node;
+ int busnr; /* primary bus number */
+ u64 mem_offset; /* bus->cpu memory mapping offset */
+ unsigned long io_offset; /* bus->cpu IO mapping offset */
+ struct pci_bus *bus; /* PCI bus */
+ struct resource *resource[3]; /* Primary PCI bus resources */
+ /* Bridge swizzling */
+ u8 (*swizzle)(struct pci_dev *, u8 *);
+ /* IRQ mapping */
+ int (*map_irq)(struct pci_dev *, u8, u8);
+ struct hw_pci *hw;
+ void *private_data; /* platform controller private data */
+};
+
+/*
+ * This is the standard PCI-PCI bridge swizzling algorithm.
+ */
+#define pci_std_swizzle pci_common_swizzle
+
+/*
+ * Call this with your hw_pci struct to initialise the PCI system.
+ */
+void pci_common_init(struct hw_pci *);
+
+/*
+ * PCI controllers
+ */
+extern int iop3xx_pci_setup(int nr, struct pci_sys_data *);
+extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *);
+extern void iop3xx_pci_preinit(void);
+extern void iop3xx_pci_preinit_cond(void);
+
+extern int dc21285_setup(int nr, struct pci_sys_data *);
+extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *);
+extern void dc21285_preinit(void);
+extern void dc21285_postinit(void);
+
+extern int via82c505_setup(int nr, struct pci_sys_data *);
+extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *);
+extern void via82c505_init(void *sysdata);
+
+extern int pci_v3_setup(int nr, struct pci_sys_data *);
+extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *);
+extern void pci_v3_preinit(void);
+extern void pci_v3_postinit(void);
+
+#endif /* __ASM_MACH_PCI_H */
diff --git a/arch/arm/include/asm/mach/serial_at91.h b/arch/arm/include/asm/mach/serial_at91.h
new file mode 100644
index 00000000..ea6d0639
--- /dev/null
+++ b/arch/arm/include/asm/mach/serial_at91.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/include/asm/mach/serial_at91.h
+ *
+ * Based on serial_sa1100.h by Nicolas Pitre
+ *
+ * Copyright (C) 2002 ATMEL Rousset
+ *
+ * Low level machine dependent UART functions.
+ */
+
+struct uart_port;
+
+/*
+ * This is a temporary structure for registering these
+ * functions; it is intended to be discarded after boot.
+ */
+struct atmel_port_fns {
+ void (*set_mctrl)(struct uart_port *, u_int);
+ u_int (*get_mctrl)(struct uart_port *);
+ void (*enable_ms)(struct uart_port *);
+ void (*pm)(struct uart_port *, u_int, u_int);
+ int (*set_wake)(struct uart_port *, u_int);
+ int (*open)(struct uart_port *);
+ void (*close)(struct uart_port *);
+};
+
+#if defined(CONFIG_SERIAL_ATMEL)
+void atmel_register_uart_fns(struct atmel_port_fns *fns);
+#else
+#define atmel_register_uart_fns(fns) do { } while (0)
+#endif
+
+
diff --git a/arch/arm/include/asm/mach/serial_sa1100.h b/arch/arm/include/asm/mach/serial_sa1100.h
new file mode 100644
index 00000000..d09064bf
--- /dev/null
+++ b/arch/arm/include/asm/mach/serial_sa1100.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/include/asm/mach/serial_sa1100.h
+ *
+ * Author: Nicolas Pitre
+ *
+ * Moved and changed lots, Russell King
+ *
+ * Low level machine dependent UART functions.
+ */
+
+struct uart_port;
+struct uart_info;
+
+/*
+ * This is a temporary structure for registering these
+ * functions; it is intended to be discarded after boot.
+ */
+struct sa1100_port_fns {
+ void (*set_mctrl)(struct uart_port *, u_int);
+ u_int (*get_mctrl)(struct uart_port *);
+ void (*pm)(struct uart_port *, u_int, u_int);
+ int (*set_wake)(struct uart_port *, u_int);
+};
+
+#ifdef CONFIG_SERIAL_SA1100
+void sa1100_register_uart_fns(struct sa1100_port_fns *fns);
+void sa1100_register_uart(int idx, int port);
+#else
+#define sa1100_register_uart_fns(fns) do { } while (0)
+#define sa1100_register_uart(idx,port) do { } while (0)
+#endif
diff --git a/arch/arm/include/asm/mach/sharpsl_param.h b/arch/arm/include/asm/mach/sharpsl_param.h
new file mode 100644
index 00000000..7a24ecf0
--- /dev/null
+++ b/arch/arm/include/asm/mach/sharpsl_param.h
@@ -0,0 +1,37 @@
+/*
+ * Hardware parameter area specific to Sharp SL series devices
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can 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 sharpsl_param_info {
+ unsigned int comadj_keyword;
+ unsigned int comadj;
+
+ unsigned int uuid_keyword;
+ unsigned char uuid[16];
+
+ unsigned int touch_keyword;
+ unsigned int touch_xp;
+ unsigned int touch_yp;
+ unsigned int touch_xd;
+ unsigned int touch_yd;
+
+ unsigned int adadj_keyword;
+ unsigned int adadj;
+
+ unsigned int phad_keyword;
+ unsigned int phadadj;
+} __attribute__((packed));
+
+
+extern struct sharpsl_param_info sharpsl_param;
+extern void sharpsl_save_param(void);
+
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
new file mode 100644
index 00000000..d5adaae5
--- /dev/null
+++ b/arch/arm/include/asm/mach/time.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/include/asm/mach/time.h
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARM_MACH_TIME_H
+#define __ASM_ARM_MACH_TIME_H
+
+#include <linux/sysdev.h>
+
+/*
+ * This is our kernel timer structure.
+ *
+ * - init
+ * Initialise the kernels jiffy timer source, claim interrupt
+ * using setup_irq. This is called early on during initialisation
+ * while interrupts are still disabled on the local CPU.
+ * - suspend
+ * Suspend the kernel jiffy timer source, if necessary. This
+ * is called with interrupts disabled, after all normal devices
+ * have been suspended. If no action is required, set this to
+ * NULL.
+ * - resume
+ * Resume the kernel jiffy timer source, if necessary. This
+ * is called with interrupts disabled before any normal devices
+ * are resumed. If no action is required, set this to NULL.
+ * - offset
+ * Return the timer offset in microseconds since the last timer
+ * interrupt. Note: this must take account of any unprocessed
+ * timer interrupt which may be pending.
+ */
+struct sys_timer {
+ void (*init)(void);
+ void (*suspend)(void);
+ void (*resume)(void);
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+ unsigned long (*offset)(void);
+#endif
+};
+
+extern void timer_tick(void);
+
+#endif
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h
new file mode 100644
index 00000000..ea297ac7
--- /dev/null
+++ b/arch/arm/include/asm/mach/udc_pxa2xx.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/include/asm/mach/udc_pxa2xx.h
+ *
+ * This supports machine-specific differences in how the PXA2xx
+ * USB Device Controller (UDC) is wired.
+ *
+ * It is set in linux/arch/arm/mach-pxa/<machine>.c or in
+ * linux/arch/mach-ixp4xx/<machine>.c and used in
+ * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c
+ */
+
+struct pxa2xx_udc_mach_info {
+ int (*udc_is_connected)(void); /* do we see host? */
+ void (*udc_command)(int cmd);
+#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */
+#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */
+
+ /* Boards following the design guidelines in the developer's manual,
+ * with on-chip GPIOs not Lubbock's weird hardware, can have a sane
+ * VBUS IRQ and omit the methods above. Store the GPIO number
+ * here. Note that sometimes the signals go through inverters...
+ */
+ bool gpio_pullup_inverted;
+ int gpio_pullup; /* high == pullup activated */
+};
+
diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h
new file mode 100644
index 00000000..6b884d2b
--- /dev/null
+++ b/arch/arm/include/asm/mc146818rtc.h
@@ -0,0 +1,28 @@
+/*
+ * Machine dependent access functions for RTC registers.
+ */
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <linux/io.h>
+#include <mach/irqs.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */
+#endif
+
+/*
+ * The yet supported machines all access the RTC index register via
+ * an ISA port access but the way to access the date register differs ...
+ */
+#define CMOS_READ(addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+inb_p(RTC_PORT(1)); \
+})
+#define CMOS_WRITE(val, addr) ({ \
+outb_p((addr),RTC_PORT(0)); \
+outb_p((val),RTC_PORT(1)); \
+})
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/arch/arm/include/asm/memblock.h b/arch/arm/include/asm/memblock.h
new file mode 100644
index 00000000..b8da2e41
--- /dev/null
+++ b/arch/arm/include/asm/memblock.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_ARM_MEMBLOCK_H
+#define _ASM_ARM_MEMBLOCK_H
+
+struct meminfo;
+struct machine_desc;
+
+extern void arm_memblock_init(struct meminfo *, struct machine_desc *);
+
+#endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
new file mode 100644
index 00000000..af44a8fb
--- /dev/null
+++ b/arch/arm/include/asm/memory.h
@@ -0,0 +1,306 @@
+/*
+ * arch/arm/include/asm/memory.h
+ *
+ * Copyright (C) 2000-2002 Russell King
+ * modification for nommu, Hyok S. Choi, 2004
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Note: this file should not be included by non-asm/.h files
+ */
+#ifndef __ASM_ARM_MEMORY_H
+#define __ASM_ARM_MEMORY_H
+
+#include <linux/compiler.h>
+#include <linux/const.h>
+#include <linux/types.h>
+#include <mach/memory.h>
+#include <asm/sizes.h>
+
+/*
+ * Allow for constants defined here to be used from assembly code
+ * by prepending the UL suffix only with actual C code compilation.
+ */
+#define UL(x) _AC(x, UL)
+
+#ifdef CONFIG_MMU
+
+/*
+ * PAGE_OFFSET - the virtual address of the start of the kernel image
+ * TASK_SIZE - the maximum size of a user space task.
+ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
+ */
+#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
+#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
+#define TASK_UNMAPPED_BASE (UL(CONFIG_PAGE_OFFSET) / 3)
+
+/*
+ * The maximum size of a 26-bit user space task.
+ */
+#define TASK_SIZE_26 UL(0x04000000)
+
+/*
+ * The module space lives between the addresses given by TASK_SIZE
+ * and PAGE_OFFSET - it must be within 32MB of the kernel text.
+ */
+#ifndef CONFIG_THUMB2_KERNEL
+#define MODULES_VADDR (PAGE_OFFSET - 16*1024*1024)
+#else
+/* smaller range for Thumb-2 symbols relocation (2^24)*/
+#define MODULES_VADDR (PAGE_OFFSET - 8*1024*1024)
+#endif
+
+#if TASK_SIZE > MODULES_VADDR
+#error Top of user space clashes with start of module space
+#endif
+
+/*
+ * The highmem pkmap virtual space shares the end of the module area.
+ */
+#ifdef CONFIG_HIGHMEM
+#define MODULES_END (PAGE_OFFSET - PMD_SIZE)
+#else
+#define MODULES_END (PAGE_OFFSET)
+#endif
+
+/*
+ * The XIP kernel gets mapped at the bottom of the module vm area.
+ * Since we use sections to map it, this macro replaces the physical address
+ * with its virtual address while keeping offset from the base section.
+ */
+#define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff))
+
+/*
+ * Allow 16MB-aligned ioremap pages
+ */
+#define IOREMAP_MAX_ORDER 24
+
+/*
+ * Size of DMA-consistent memory region. Must be multiple of 2M,
+ * between 2MB and 14MB inclusive.
+ */
+#ifndef CONSISTENT_DMA_SIZE
+#define CONSISTENT_DMA_SIZE SZ_2M
+#endif
+
+#define CONSISTENT_END (0xffe00000UL)
+#define CONSISTENT_BASE (CONSISTENT_END - CONSISTENT_DMA_SIZE)
+
+#else /* CONFIG_MMU */
+
+/*
+ * The limitation of user task size can grow up to the end of free ram region.
+ * It is difficult to define and perhaps will never meet the original meaning
+ * of this define that was meant to.
+ * Fortunately, there is no reference for this in noMMU mode, for now.
+ */
+#ifndef TASK_SIZE
+#define TASK_SIZE (CONFIG_DRAM_SIZE)
+#endif
+
+#ifndef TASK_UNMAPPED_BASE
+#define TASK_UNMAPPED_BASE UL(0x00000000)
+#endif
+
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET UL(CONFIG_DRAM_BASE)
+#endif
+
+#ifndef END_MEM
+#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
+#endif
+
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET (PHYS_OFFSET)
+#endif
+
+/*
+ * The module can be at any place in ram in nommu mode.
+ */
+#define MODULES_END (END_MEM)
+#define MODULES_VADDR (PHYS_OFFSET)
+
+#endif /* !CONFIG_MMU */
+
+/*
+ * We fix the TCM memories max 32 KiB ITCM resp DTCM at these
+ * locations
+ */
+#ifdef CONFIG_HAVE_TCM
+#define ITCM_OFFSET UL(0xfffe0000)
+#define DTCM_OFFSET UL(0xfffe8000)
+#endif
+
+/*
+ * Convert a physical address to a Page Frame Number and back
+ */
+#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
+#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)
+
+/*
+ * Convert a page to/from a physical address
+ */
+#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page)))
+#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys)))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Physical vs virtual RAM address space conversion. These are
+ * private definitions which should NOT be used outside memory.h
+ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+#ifndef __virt_to_phys
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+
+/*
+ * Constants used to force the right instruction encodings and shifts
+ * so that all we need to do is modify the 8-bit constant field.
+ */
+#define __PV_BITS_31_24 0x81000000
+#define __PV_BITS_23_16 0x00810000
+
+extern unsigned long __pv_phys_offset;
+#define PHYS_OFFSET __pv_phys_offset
+
+#define __pv_stub(from,to,instr,type) \
+ __asm__("@ __pv_stub\n" \
+ "1: " instr " %0, %1, %2\n" \
+ " .pushsection .pv_table,\"a\"\n" \
+ " .long 1b\n" \
+ " .popsection\n" \
+ : "=r" (to) \
+ : "r" (from), "I" (type))
+
+static inline unsigned long __virt_to_phys(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "add", __PV_BITS_31_24);
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ __pv_stub(t, t, "add", __PV_BITS_23_16);
+#endif
+ return t;
+}
+
+static inline unsigned long __phys_to_virt(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "sub", __PV_BITS_31_24);
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ __pv_stub(t, t, "sub", __PV_BITS_23_16);
+#endif
+ return t;
+}
+#else
+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
+#endif
+
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET PLAT_PHYS_OFFSET
+#endif
+
+/*
+ * The DMA mask corresponding to the maximum bus address allocatable
+ * using GFP_DMA. The default here places no restriction on DMA
+ * allocations. This must be the smallest DMA mask in the system,
+ * so a successful GFP_DMA allocation will always satisfy this.
+ */
+#ifndef ARM_DMA_ZONE_SIZE
+#define ISA_DMA_THRESHOLD (0xffffffffULL)
+#else
+#define ISA_DMA_THRESHOLD (PHYS_OFFSET + ARM_DMA_ZONE_SIZE - 1)
+#endif
+
+/*
+ * PFNs are used to describe any physical page; this means
+ * PFN 0 == physical address 0.
+ *
+ * This is the PFN of the first RAM page in the kernel
+ * direct-mapped view. We assume this is the first page
+ * of RAM in the mem_map as well.
+ */
+#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
+
+/*
+ * These are *only* valid on the kernel direct mapped RAM memory.
+ * Note: Drivers should NOT use these. They are the wrong
+ * translation for translating DMA addresses. Use the driver
+ * DMA support - see dma-mapping.h.
+ */
+static inline phys_addr_t virt_to_phys(const volatile void *x)
+{
+ return __virt_to_phys((unsigned long)(x));
+}
+
+static inline void *phys_to_virt(phys_addr_t x)
+{
+ return (void *)(__phys_to_virt((unsigned long)(x)));
+}
+
+/*
+ * Drivers should NOT use these either.
+ */
+#define __pa(x) __virt_to_phys((unsigned long)(x))
+#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+
+/*
+ * Virtual <-> DMA view memory address translations
+ * Again, these are *only* valid on the kernel direct mapped RAM
+ * memory. Use of these is *deprecated* (and that doesn't mean
+ * use the __ prefixed forms instead.) See dma-mapping.h.
+ */
+#ifndef __virt_to_bus
+#define __virt_to_bus __virt_to_phys
+#define __bus_to_virt __phys_to_virt
+#define __pfn_to_bus(x) __pfn_to_phys(x)
+#define __bus_to_pfn(x) __phys_to_pfn(x)
+#endif
+
+static inline __deprecated unsigned long virt_to_bus(void *x)
+{
+ return __virt_to_bus((unsigned long)x);
+}
+
+static inline __deprecated void *bus_to_virt(unsigned long x)
+{
+ return (void *)__bus_to_virt(x);
+}
+
+/*
+ * Conversion between a struct page and a physical address.
+ *
+ * Note: when converting an unknown physical address to a
+ * struct page, the resulting pointer must be validated
+ * using VALID_PAGE(). It must return an invalid struct page
+ * for any physical address not corresponding to a system
+ * RAM address.
+ *
+ * page_to_pfn(page) convert a struct page * to a PFN number
+ * pfn_to_page(pfn) convert a _valid_ PFN number to struct page *
+ *
+ * virt_to_page(k) convert a _valid_ virtual address to struct page *
+ * virt_addr_valid(k) indicates whether a virtual address is valid
+ */
+#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
+
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
+
+/*
+ * Optional coherency support. Currently used only by selected
+ * Intel XSC3-based systems.
+ */
+#ifndef arch_is_coherent
+#define arch_is_coherent() 0
+#endif
+
+#endif
+
+#include <asm-generic/memory_model.h>
+
+#endif
diff --git a/arch/arm/include/asm/mman.h b/arch/arm/include/asm/mman.h
new file mode 100644
index 00000000..41f99c57
--- /dev/null
+++ b/arch/arm/include/asm/mman.h
@@ -0,0 +1,4 @@
+#include <asm-generic/mman.h>
+
+#define arch_mmap_check(addr, len, flags) \
+ (((flags) & MAP_FIXED && (addr) < FIRST_USER_ADDRESS) ? -EINVAL : 0)
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
new file mode 100644
index 00000000..b4ffe9d5
--- /dev/null
+++ b/arch/arm/include/asm/mmu.h
@@ -0,0 +1,37 @@
+#ifndef __ARM_MMU_H
+#define __ARM_MMU_H
+
+#ifdef CONFIG_MMU
+
+typedef struct {
+#ifdef CONFIG_CPU_HAS_ASID
+ unsigned int id;
+ spinlock_t id_lock;
+#endif
+ unsigned int kvm_seq;
+} mm_context_t;
+
+#ifdef CONFIG_CPU_HAS_ASID
+#define ASID(mm) ((mm)->context.id & 255)
+
+/* init_mm.context.id_lock should be initialized. */
+#define INIT_MM_CONTEXT(name) \
+ .context.id_lock = __SPIN_LOCK_UNLOCKED(name.context.id_lock),
+#else
+#define ASID(mm) (0)
+#endif
+
+#else
+
+/*
+ * From nommu.h:
+ * Copyright (C) 2002, David McCullough <davidm@snapgear.com>
+ * modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>
+ */
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
new file mode 100644
index 00000000..71605d9f
--- /dev/null
+++ b/arch/arm/include/asm/mmu_context.h
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/include/asm/mmu_context.h
+ *
+ * Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 27-06-1996 RMK Created
+ */
+#ifndef __ASM_ARM_MMU_CONTEXT_H
+#define __ASM_ARM_MMU_CONTEXT_H
+
+#include <linux/compiler.h>
+#include <linux/sched.h>
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/proc-fns.h>
+
+void __check_kvm_seq(struct mm_struct *mm);
+
+#ifdef CONFIG_CPU_HAS_ASID
+
+/*
+ * On ARMv6, we have the following structure in the Context ID:
+ *
+ * 31 7 0
+ * +-------------------------+-----------+
+ * | process ID | ASID |
+ * +-------------------------+-----------+
+ * | context ID |
+ * +-------------------------------------+
+ *
+ * The ASID is used to tag entries in the CPU caches and TLBs.
+ * The context ID is used by debuggers and trace logic, and
+ * should be unique within all running processes.
+ */
+#define ASID_BITS 8
+#define ASID_MASK ((~0) << ASID_BITS)
+#define ASID_FIRST_VERSION (1 << ASID_BITS)
+
+extern unsigned int cpu_last_asid;
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(struct mm_struct *, current_mm);
+#endif
+
+void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
+void __new_context(struct mm_struct *mm);
+
+static inline void check_context(struct mm_struct *mm)
+{
+ /*
+ * This code is executed with interrupts enabled. Therefore,
+ * mm->context.id cannot be updated to the latest ASID version
+ * on a different CPU (and condition below not triggered)
+ * without first getting an IPI to reset the context. The
+ * alternative is to take a read_lock on mm->context.id_lock
+ * (after changing its type to rwlock_t).
+ */
+ if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
+ __new_context(mm);
+
+ if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
+ __check_kvm_seq(mm);
+}
+
+#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0)
+
+#else
+
+static inline void check_context(struct mm_struct *mm)
+{
+#ifdef CONFIG_MMU
+ if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
+ __check_kvm_seq(mm);
+#endif
+}
+
+#define init_new_context(tsk,mm) 0
+
+#endif
+
+#define destroy_context(mm) do { } while(0)
+
+/*
+ * This is called when "tsk" is about to enter lazy TLB mode.
+ *
+ * mm: describes the currently active mm context
+ * tsk: task which is entering lazy tlb
+ * cpu: cpu number which is entering lazy tlb
+ *
+ * tsk->mm will be NULL
+ */
+static inline void
+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+}
+
+/*
+ * This is the actual mm switch as far as the scheduler
+ * is concerned. No registers are touched. We avoid
+ * calling the CPU specific function when the mm hasn't
+ * actually changed.
+ */
+static inline void
+switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+#ifdef CONFIG_MMU
+ unsigned int cpu = smp_processor_id();
+
+#ifdef CONFIG_SMP
+ /* check for possible thread migration */
+ if (!cpumask_empty(mm_cpumask(next)) &&
+ !cpumask_test_cpu(cpu, mm_cpumask(next)))
+ __flush_icache_all();
+#endif
+ if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
+#ifdef CONFIG_SMP
+ struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
+ *crt_mm = next;
+#endif
+ check_context(next);
+ cpu_switch_mm(next->pgd, next);
+ if (cache_is_vivt())
+ cpumask_clear_cpu(cpu, mm_cpumask(prev));
+ }
+#endif
+}
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+#define activate_mm(prev,next) switch_mm(prev, next, NULL)
+
+/*
+ * We are inserting a "fake" vma for the user-accessible vector page so
+ * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
+ * But we also want to remove it before the generic code gets to see it
+ * during process exit or the unmapping of it would cause total havoc.
+ * (the macro is used as remove_vma() is static to mm/mmap.c)
+ */
+#define arch_exit_mmap(mm) \
+do { \
+ struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
+ if (high_vma) { \
+ BUG_ON(high_vma->vm_next); /* it should be last */ \
+ if (high_vma->vm_prev) \
+ high_vma->vm_prev->vm_next = NULL; \
+ else \
+ mm->mmap = NULL; \
+ rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
+ mm->mmap_cache = NULL; \
+ mm->map_count--; \
+ remove_vma(high_vma); \
+ } \
+} while (0)
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+ struct mm_struct *mm)
+{
+}
+
+#endif
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
new file mode 100644
index 00000000..543b4491
--- /dev/null
+++ b/arch/arm/include/asm/module.h
@@ -0,0 +1,55 @@
+#ifndef _ASM_ARM_MODULE_H
+#define _ASM_ARM_MODULE_H
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+struct unwind_table;
+
+#ifdef CONFIG_ARM_UNWIND
+enum {
+ ARM_SEC_INIT,
+ ARM_SEC_DEVINIT,
+ ARM_SEC_CORE,
+ ARM_SEC_EXIT,
+ ARM_SEC_DEVEXIT,
+ ARM_SEC_MAX,
+};
+#endif
+
+struct mod_arch_specific {
+#ifdef CONFIG_ARM_UNWIND
+ struct unwind_table *unwind[ARM_SEC_MAX];
+#endif
+};
+
+/*
+ * Add the ARM architecture version to the version magic string
+ */
+#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+
+/* Add __virt_to_phys patching state as well */
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
+#else
+#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
+#endif
+#else
+#define MODULE_ARCH_VERMAGIC_P2V ""
+#endif
+
+/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */
+#ifdef CONFIG_THUMB2_KERNEL
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 "
+#else
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+ MODULE_ARCH_VERMAGIC_ARMVSN \
+ MODULE_ARCH_VERMAGIC_ARMTHUMB \
+ MODULE_ARCH_VERMAGIC_P2V
+
+#endif /* _ASM_ARM_MODULE_H */
diff --git a/arch/arm/include/asm/msgbuf.h b/arch/arm/include/asm/msgbuf.h
new file mode 100644
index 00000000..33b35b94
--- /dev/null
+++ b/arch/arm/include/asm/msgbuf.h
@@ -0,0 +1,31 @@
+#ifndef _ASMARM_MSGBUF_H
+#define _ASMARM_MSGBUF_H
+
+/*
+ * The msqid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+ __kernel_time_t msg_stime; /* last msgsnd time */
+ unsigned long __unused1;
+ __kernel_time_t msg_rtime; /* last msgrcv time */
+ unsigned long __unused2;
+ __kernel_time_t msg_ctime; /* last change time */
+ unsigned long __unused3;
+ unsigned long msg_cbytes; /* current number of bytes on queue */
+ unsigned long msg_qnum; /* number of messages in queue */
+ unsigned long msg_qbytes; /* max number of bytes on queue */
+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */
+ __kernel_pid_t msg_lrpid; /* last receive pid */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif /* _ASMARM_MSGBUF_H */
diff --git a/arch/arm/include/asm/mtd-xip.h b/arch/arm/include/asm/mtd-xip.h
new file mode 100644
index 00000000..d79d66d2
--- /dev/null
+++ b/arch/arm/include/asm/mtd-xip.h
@@ -0,0 +1,23 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 2, 2004
+ * Copyright: (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARM_MTD_XIP_H__
+#define __ARM_MTD_XIP_H__
+
+#include <mach/mtd-xip.h>
+
+/* fill instruction prefetch */
+#define xip_iprefetch() do { asm volatile (".rep 8; nop; .endr"); } while (0)
+
+#endif /* __ARM_MTD_XIP_H__ */
diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h
new file mode 100644
index 00000000..93226cf2
--- /dev/null
+++ b/arch/arm/include/asm/mutex.h
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/include/asm/mutex.h
+ *
+ * ARM optimized mutex locking primitives
+ *
+ * Please look into asm-generic/mutex-xchg.h for a formal definition.
+ */
+#ifndef _ASM_MUTEX_H
+#define _ASM_MUTEX_H
+
+#if __LINUX_ARM_ARCH__ < 6
+/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */
+# include <asm-generic/mutex-xchg.h>
+#else
+
+/*
+ * Attempting to lock a mutex on ARMv6+ can be done with a bastardized
+ * atomic decrement (it is not a reliable atomic decrement but it satisfies
+ * the defined semantics for our purpose, while being smaller and faster
+ * than a real atomic decrement or atomic swap. The idea is to attempt
+ * decrementing the lock value only once. If once decremented it isn't zero,
+ * or if its store-back fails due to a dispute on the exclusive store, we
+ * simply bail out immediately through the slow path where the lock will be
+ * reattempted until it succeeds.
+ */
+static inline void
+__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+ int __ex_flag, __res;
+
+ __asm__ (
+
+ "ldrex %0, [%2] \n\t"
+ "sub %0, %0, #1 \n\t"
+ "strex %1, %0, [%2] "
+
+ : "=&r" (__res), "=&r" (__ex_flag)
+ : "r" (&(count)->counter)
+ : "cc","memory" );
+
+ __res |= __ex_flag;
+ if (unlikely(__res != 0))
+ fail_fn(count);
+}
+
+static inline int
+__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+ int __ex_flag, __res;
+
+ __asm__ (
+
+ "ldrex %0, [%2] \n\t"
+ "sub %0, %0, #1 \n\t"
+ "strex %1, %0, [%2] "
+
+ : "=&r" (__res), "=&r" (__ex_flag)
+ : "r" (&(count)->counter)
+ : "cc","memory" );
+
+ __res |= __ex_flag;
+ if (unlikely(__res != 0))
+ __res = fail_fn(count);
+ return __res;
+}
+
+/*
+ * Same trick is used for the unlock fast path. However the original value,
+ * rather than the result, is used to test for success in order to have
+ * better generated assembly.
+ */
+static inline void
+__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
+{
+ int __ex_flag, __res, __orig;
+
+ __asm__ (
+
+ "ldrex %0, [%3] \n\t"
+ "add %1, %0, #1 \n\t"
+ "strex %2, %1, [%3] "
+
+ : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+ : "r" (&(count)->counter)
+ : "cc","memory" );
+
+ __orig |= __ex_flag;
+ if (unlikely(__orig != 0))
+ fail_fn(count);
+}
+
+/*
+ * If the unlock was done on a contended lock, or if the unlock simply fails
+ * then the mutex remains locked.
+ */
+#define __mutex_slowpath_needs_to_unlock() 1
+
+/*
+ * For __mutex_fastpath_trylock we use another construct which could be
+ * described as a "single value cmpxchg".
+ *
+ * This provides the needed trylock semantics like cmpxchg would, but it is
+ * lighter and less generic than a true cmpxchg implementation.
+ */
+static inline int
+__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
+{
+ int __ex_flag, __res, __orig;
+
+ __asm__ (
+
+ "1: ldrex %0, [%3] \n\t"
+ "subs %1, %0, #1 \n\t"
+ "strexeq %2, %1, [%3] \n\t"
+ "movlt %0, #0 \n\t"
+ "cmpeq %2, #0 \n\t"
+ "bgt 1b "
+
+ : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
+ : "r" (&count->counter)
+ : "cc", "memory" );
+
+ return __orig;
+}
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/nwflash.h b/arch/arm/include/asm/nwflash.h
new file mode 100644
index 00000000..04e5a557
--- /dev/null
+++ b/arch/arm/include/asm/nwflash.h
@@ -0,0 +1,9 @@
+#ifndef _FLASH_H
+#define _FLASH_H
+
+#define FLASH_MINOR 160 /* MAJOR is 10 - miscdevice */
+#define CMD_WRITE_DISABLE 0
+#define CMD_WRITE_ENABLE 0x28
+#define CMD_WRITE_BASE64K_ENABLE 0x47
+
+#endif /* _FLASH_H */
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
new file mode 100644
index 00000000..d8387437
--- /dev/null
+++ b/arch/arm/include/asm/outercache.h
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/include/asm/outercache.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_OUTERCACHE_H
+#define __ASM_OUTERCACHE_H
+
+#include <linux/types.h>
+
+struct outer_cache_fns {
+ void (*inv_range)(unsigned long, unsigned long);
+ void (*clean_range)(unsigned long, unsigned long);
+ void (*flush_range)(unsigned long, unsigned long);
+ void (*flush_all)(void);
+ void (*inv_all)(void);
+ void (*disable)(void);
+#ifdef CONFIG_OUTER_CACHE_SYNC
+ void (*sync)(void);
+#endif
+ void (*set_debug)(unsigned long);
+};
+
+#ifdef CONFIG_OUTER_CACHE
+
+extern struct outer_cache_fns outer_cache;
+
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
+{
+ if (outer_cache.inv_range)
+ outer_cache.inv_range(start, end);
+}
+static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
+{
+ if (outer_cache.clean_range)
+ outer_cache.clean_range(start, end);
+}
+static inline void outer_flush_range(phys_addr_t start, phys_addr_t end)
+{
+ if (outer_cache.flush_range)
+ outer_cache.flush_range(start, end);
+}
+
+static inline void outer_flush_all(void)
+{
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
+}
+
+static inline void outer_inv_all(void)
+{
+ if (outer_cache.inv_all)
+ outer_cache.inv_all();
+}
+
+static inline void outer_disable(void)
+{
+ if (outer_cache.disable)
+ outer_cache.disable();
+}
+
+#else
+
+static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
+{ }
+static inline void outer_clean_range(phys_addr_t start, phys_addr_t end)
+{ }
+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_disable(void) { }
+
+#endif
+
+#ifdef CONFIG_OUTER_CACHE_SYNC
+static inline void outer_sync(void)
+{
+ if (outer_cache.sync)
+ outer_cache.sync();
+}
+#else
+static inline void outer_sync(void)
+{ }
+#endif
+
+#endif /* __ASM_OUTERCACHE_H */
diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h
new file mode 100644
index 00000000..d1b162a1
--- /dev/null
+++ b/arch/arm/include/asm/page-nommu.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/include/asm/page-nommu.h
+ *
+ * Copyright (C) 2004 Hyok S. Choi
+ *
+ * This program is free software; you can 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 _ASMARM_PAGE_NOMMU_H
+#define _ASMARM_PAGE_NOMMU_H
+
+#if !defined(CONFIG_SMALL_TASKS) && PAGE_SHIFT < 13
+#define KTHREAD_SIZE (8192)
+#else
+#define KTHREAD_SIZE PAGE_SIZE
+#endif
+
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define free_user_page(page, addr) free_page(addr)
+
+#define clear_page(page) memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg) clear_page(page)
+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t[2];
+typedef unsigned long pgprot_t;
+
+#define pte_val(x) (x)
+#define pmd_val(x) (x)
+#define pgd_val(x) ((x)[0])
+#define pgprot_val(x) (x)
+
+#define __pte(x) (x)
+#define __pmd(x) (x)
+#define __pgprot(x) (x)
+
+#endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
new file mode 100644
index 00000000..ac75d084
--- /dev/null
+++ b/arch/arm/include/asm/page.h
@@ -0,0 +1,214 @@
+/*
+ * arch/arm/include/asm/page.h
+ *
+ * Copyright (C) 1995-2003 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_PAGE_H
+#define _ASMARM_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+#ifndef CONFIG_MMU
+
+#include "page-nommu.h"
+
+#else
+
+#include <asm/glue.h>
+
+/*
+ * User Space Model
+ * ================
+ *
+ * This section selects the correct set of functions for dealing with
+ * page-based copying and clearing for user space for the particular
+ * processor(s) we're building for.
+ *
+ * We have the following to choose from:
+ * v3 - ARMv3
+ * v4wt - ARMv4 with writethrough cache, without minicache
+ * v4wb - ARMv4 with writeback cache, without minicache
+ * v4_mc - ARMv4 with minicache
+ * xscale - Xscale
+ * xsc3 - XScalev3
+ */
+#undef _USER
+#undef MULTI_USER
+
+#ifdef CONFIG_CPU_COPY_V3
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v3
+# endif
+#endif
+
+#ifdef CONFIG_CPU_COPY_V4WT
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4wt
+# endif
+#endif
+
+#ifdef CONFIG_CPU_COPY_V4WB
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4wb
+# endif
+#endif
+
+#ifdef CONFIG_CPU_COPY_FEROCEON
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER feroceon
+# endif
+#endif
+
+#ifdef CONFIG_CPU_COPY_FA
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER fa
+# endif
+#endif
+
+#ifdef CONFIG_CPU_SA1100
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER v4_mc
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSCALE
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER xscale_mc
+# endif
+#endif
+
+#ifdef CONFIG_CPU_XSC3
+# ifdef _USER
+# define MULTI_USER 1
+# else
+# define _USER xsc3_mc
+# endif
+#endif
+
+#ifdef CONFIG_CPU_COPY_V6
+# define MULTI_USER 1
+#endif
+
+#if !defined(_USER) && !defined(MULTI_USER)
+#error Unknown user operations model
+#endif
+
+struct page;
+struct vm_area_struct;
+
+struct cpu_user_fns {
+ void (*cpu_clear_user_highpage)(struct page *page, unsigned long vaddr);
+ void (*cpu_copy_user_highpage)(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma);
+};
+
+#ifdef MULTI_USER
+extern struct cpu_user_fns cpu_user;
+
+#define __cpu_clear_user_highpage cpu_user.cpu_clear_user_highpage
+#define __cpu_copy_user_highpage cpu_user.cpu_copy_user_highpage
+
+#else
+
+#define __cpu_clear_user_highpage __glue(_USER,_clear_user_highpage)
+#define __cpu_copy_user_highpage __glue(_USER,_copy_user_highpage)
+
+extern void __cpu_clear_user_highpage(struct page *page, unsigned long vaddr);
+extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma);
+#endif
+
+#define clear_user_highpage(page,vaddr) \
+ __cpu_clear_user_highpage(page, vaddr)
+
+#define __HAVE_ARCH_COPY_USER_HIGHPAGE
+#define copy_user_highpage(to,from,vaddr,vma) \
+ __cpu_copy_user_highpage(to, from, vaddr, vma)
+
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+extern void copy_page(void *to, const void *from);
+
+typedef unsigned long pteval_t;
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { pteval_t pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd[2]; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x) ((x).pte)
+#define pmd_val(x) ((x).pmd)
+#define pgd_val(x) ((x).pgd[0])
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef pteval_t pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t[2];
+typedef unsigned long pgprot_t;
+
+#define pte_val(x) (x)
+#define pmd_val(x) (x)
+#define pgd_val(x) ((x)[0])
+#define pgprot_val(x) (x)
+
+#define __pte(x) (x)
+#define __pmd(x) (x)
+#define __pgprot(x) (x)
+
+#endif /* STRICT_MM_TYPECHECKS */
+
+#endif /* CONFIG_MMU */
+
+typedef struct page *pgtable_t;
+
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
+extern int pfn_valid(unsigned long);
+#endif
+
+#include <asm/memory.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS \
+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/getorder.h>
+
+#endif
diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h
new file mode 100644
index 00000000..8b24bf94
--- /dev/null
+++ b/arch/arm/include/asm/param.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/include/asm/param.h
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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_PARAM_H
+#define __ASM_PARAM_H
+
+#ifdef __KERNEL__
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
+# define USER_HZ 100 /* User interfaces are in "ticks" */
+# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
+#else
+# define HZ 100
+#endif
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+/* max length of hostname */
+#define MAXHOSTNAMELEN 64
+
+#endif
+
diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h
new file mode 100644
index 00000000..26e94b09
--- /dev/null
+++ b/arch/arm/include/asm/parport.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/include/asm/parport.h: ARM-specific parport initialisation
+ *
+ * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk>
+ *
+ * This file should only be included by drivers/parport/parport_pc.c.
+ */
+
+#ifndef __ASMARM_PARPORT_H
+#define __ASMARM_PARPORT_H
+
+static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma);
+static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
+{
+ return parport_pc_find_isa_ports (autoirq, autodma);
+}
+
+#endif /* !(_ASMARM_PARPORT_H) */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
new file mode 100644
index 00000000..92e2a833
--- /dev/null
+++ b/arch/arm/include/asm/pci.h
@@ -0,0 +1,80 @@
+#ifndef ASMARM_PCI_H
+#define ASMARM_PCI_H
+
+#ifdef __KERNEL__
+#include <asm-generic/pci-dma-compat.h>
+
+#include <asm/mach/pci.h> /* for pci_sys_data */
+#include <mach/hardware.h> /* for PCIBIOS_MIN_* */
+
+#ifdef CONFIG_PCI_DOMAINS
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->domain;
+}
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return pci_domain_nr(bus);
+}
+#endif /* CONFIG_PCI_DOMAINS */
+
+#ifdef CONFIG_PCI_HOST_ITE8152
+/* ITE bridge requires setting latency timer to avoid early bus access
+ termination by PIC bus mater devices
+*/
+extern void pcibios_set_master(struct pci_dev *dev);
+#else
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+#endif
+
+static inline void pcibios_penalize_isa_irq(int irq, int active)
+{
+ /* We don't do dynamic PCI IRQ allocation */
+}
+
+/*
+ * The PCI address space does equal the physical memory address space.
+ * The networking and block device layers use this boolean for bounce
+ * buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS (1)
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+ enum pci_dma_burst_strategy *strat,
+ unsigned long *strategy_parameter)
+{
+ *strat = PCI_DMA_BURST_INFINITY;
+ *strategy_parameter = ~0UL;
+}
+#endif
+
+#define HAVE_PCI_MMAP
+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine);
+
+extern void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res);
+
+extern void
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region);
+
+/*
+ * Dummy implementation; always return 0.
+ */
+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+ return 0;
+}
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
new file mode 100644
index 00000000..b4e32d8e
--- /dev/null
+++ b/arch/arm/include/asm/percpu.h
@@ -0,0 +1,6 @@
+#ifndef __ARM_PERCPU
+#define __ARM_PERCPU
+
+#include <asm-generic/percpu.h>
+
+#endif
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
new file mode 100644
index 00000000..c4aa4e8c
--- /dev/null
+++ b/arch/arm/include/asm/perf_event.h
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/include/asm/perf_event.h
+ *
+ * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can 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_PERF_EVENT_H__
+#define __ARM_PERF_EVENT_H__
+
+/* ARM performance counters start from 1 (in the cp15 accesses) so use the
+ * same indexes here for consistency. */
+#define PERF_EVENT_INDEX_OFFSET 1
+
+/* ARM perf PMU IDs for use by internal perf clients. */
+enum arm_perf_pmu_ids {
+ ARM_PERF_PMU_ID_XSCALE1 = 0,
+ ARM_PERF_PMU_ID_XSCALE2,
+ ARM_PERF_PMU_ID_V6,
+ ARM_PERF_PMU_ID_V6MP,
+ ARM_PERF_PMU_ID_CA8,
+ ARM_PERF_PMU_ID_CA9,
+ ARM_NUM_PMU_IDS,
+};
+
+extern enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void);
+
+extern int
+armpmu_get_max_events(void);
+
+#endif /* __ARM_PERF_EVENT_H__ */
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
new file mode 100644
index 00000000..22de005f
--- /dev/null
+++ b/arch/arm/include/asm/pgalloc.h
@@ -0,0 +1,140 @@
+/*
+ * arch/arm/include/asm/pgalloc.h
+ *
+ * Copyright (C) 2000-2001 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_PGALLOC_H
+#define _ASMARM_PGALLOC_H
+
+#include <linux/pagemap.h>
+
+#include <asm/domain.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#define check_pgt_cache() do { } while (0)
+
+#ifdef CONFIG_MMU
+
+#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
+
+/*
+ * Since we have only two-level page tables, these are trivial
+ */
+#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
+#define pmd_free(mm, pmd) do { } while (0)
+#define pgd_populate(mm,pmd,pte) BUG()
+
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
+
+static inline void clean_pte_table(pte_t *pte)
+{
+ clean_dcache_area(pte + PTE_HWTABLE_PTRS, PTE_HWTABLE_SIZE);
+}
+
+/*
+ * Allocate one PTE table.
+ *
+ * This actually allocates two hardware PTE tables, but we wrap this up
+ * into one table thus:
+ *
+ * +------------+
+ * | Linux pt 0 |
+ * +------------+
+ * | Linux pt 1 |
+ * +------------+
+ * | h/w pt 0 |
+ * +------------+
+ * | h/w pt 1 |
+ * +------------+
+ */
+static inline pte_t *
+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
+{
+ pte_t *pte;
+
+ pte = (pte_t *)__get_free_page(PGALLOC_GFP);
+ if (pte)
+ clean_pte_table(pte);
+
+ return pte;
+}
+
+static inline pgtable_t
+pte_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+ struct page *pte;
+
+#ifdef CONFIG_HIGHPTE
+ pte = alloc_pages(PGALLOC_GFP | __GFP_HIGHMEM, 0);
+#else
+ pte = alloc_pages(PGALLOC_GFP, 0);
+#endif
+ if (pte) {
+ if (!PageHighMem(pte))
+ clean_pte_table(page_address(pte));
+ pgtable_page_ctor(pte);
+ }
+
+ return pte;
+}
+
+/*
+ * Free one PTE table.
+ */
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ if (pte)
+ free_page((unsigned long)pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ pgtable_page_dtor(pte);
+ __free_page(pte);
+}
+
+static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
+ unsigned long prot)
+{
+ unsigned long pmdval = (pte + PTE_HWTABLE_OFF) | prot;
+ pmdp[0] = __pmd(pmdval);
+ pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
+ flush_pmd_entry(pmdp);
+}
+
+/*
+ * Populate the pmdp entry with a pointer to the pte. This pmd is part
+ * of the mm address space.
+ *
+ * Ensure that we always set both PMD entries.
+ */
+static inline void
+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
+{
+ /*
+ * The pmd must be loaded with the physical address of the PTE table
+ */
+ __pmd_populate(pmdp, __pa(ptep), _PAGE_KERNEL_TABLE);
+}
+
+static inline void
+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
+{
+ __pmd_populate(pmdp, page_to_phys(ptep), _PAGE_USER_TABLE);
+}
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+#endif /* CONFIG_MMU */
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-hwdef.h b/arch/arm/include/asm/pgtable-hwdef.h
new file mode 100644
index 00000000..fd1521d5
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-hwdef.h
@@ -0,0 +1,90 @@
+/*
+ * arch/arm/include/asm/pgtable-hwdef.h
+ *
+ * Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_PGTABLE_HWDEF_H
+#define _ASMARM_PGTABLE_HWDEF_H
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1 descriptor (PMD)
+ * - common
+ */
+#define PMD_TYPE_MASK (3 << 0)
+#define PMD_TYPE_FAULT (0 << 0)
+#define PMD_TYPE_TABLE (1 << 0)
+#define PMD_TYPE_SECT (2 << 0)
+#define PMD_BIT4 (1 << 4)
+#define PMD_DOMAIN(x) ((x) << 5)
+#define PMD_PROTECTION (1 << 9) /* v5 */
+/*
+ * - section
+ */
+#define PMD_SECT_BUFFERABLE (1 << 2)
+#define PMD_SECT_CACHEABLE (1 << 3)
+#define PMD_SECT_XN (1 << 4) /* v6 */
+#define PMD_SECT_AP_WRITE (1 << 10)
+#define PMD_SECT_AP_READ (1 << 11)
+#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
+#define PMD_SECT_APX (1 << 15) /* v6 */
+#define PMD_SECT_S (1 << 16) /* v6 */
+#define PMD_SECT_nG (1 << 17) /* v6 */
+#define PMD_SECT_SUPER (1 << 18) /* v6 */
+
+#define PMD_SECT_UNCACHED (0)
+#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
+#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
+
+/*
+ * - coarse table (not used)
+ */
+
+/*
+ * + Level 2 descriptor (PTE)
+ * - common
+ */
+#define PTE_TYPE_MASK (3 << 0)
+#define PTE_TYPE_FAULT (0 << 0)
+#define PTE_TYPE_LARGE (1 << 0)
+#define PTE_TYPE_SMALL (2 << 0)
+#define PTE_TYPE_EXT (3 << 0) /* v5 */
+#define PTE_BUFFERABLE (1 << 2)
+#define PTE_CACHEABLE (1 << 3)
+
+/*
+ * - extended small page/tiny page
+ */
+#define PTE_EXT_XN (1 << 0) /* v6 */
+#define PTE_EXT_AP_MASK (3 << 4)
+#define PTE_EXT_AP0 (1 << 4)
+#define PTE_EXT_AP1 (2 << 4)
+#define PTE_EXT_AP_UNO_SRO (0 << 4)
+#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
+#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
+#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
+#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
+#define PTE_EXT_APX (1 << 9) /* v6 */
+#define PTE_EXT_COHERENT (1 << 9) /* XScale3 */
+#define PTE_EXT_SHARED (1 << 10) /* v6 */
+#define PTE_EXT_NG (1 << 11) /* v6 */
+
+/*
+ * - small page
+ */
+#define PTE_SMALL_AP_MASK (0xff << 4)
+#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
+#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
+#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
+#define PTE_SMALL_AP_URW_SRW (0xff << 4)
+
+#endif
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
new file mode 100644
index 00000000..ffc0e857
--- /dev/null
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -0,0 +1,119 @@
+/*
+ * arch/arm/include/asm/pgtable-nommu.h
+ *
+ * Copyright (C) 1995-2002 Russell King
+ * Copyright (C) 2004 Hyok S. Choi
+ *
+ * This program is free software; you can 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 _ASMARM_PGTABLE_NOMMU_H
+#define _ASMARM_PGTABLE_NOMMU_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/slab.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/*
+ * Trivial page table functions.
+ */
+#define pgd_present(pgd) (1)
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr) (1)
+#define pmd_offset(a, b) ((void *)0)
+/* FIXME */
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PGDIR_SHIFT 21
+
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+/* FIXME */
+
+#define PAGE_NONE __pgprot(0)
+#define PAGE_SHARED __pgprot(0)
+#define PAGE_COPY __pgprot(0)
+#define PAGE_READONLY __pgprot(0)
+#define PAGE_KERNEL __pgprot(0)
+
+#define swapper_pg_dir ((pgd_t *) 0)
+
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+
+typedef pte_t *pte_addr_t;
+
+static inline int pte_file(pte_t pte) { return 0; }
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) (virt_to_page(0))
+
+/*
+ * Mark the prot value as uncacheable and unbufferable.
+ */
+#define pgprot_noncached(prot) __pgprot(0)
+#define pgprot_writecombine(prot) __pgprot(0)
+#define pgprot_dmacoherent(prot) __pgprot(0)
+
+
+/*
+ * These would be in other places but having them here reduces the diffs.
+ */
+extern unsigned int kobjsize(const void *objp);
+
+/*
+ * No page table caches to initialise.
+ */
+#define pgtable_cache_init() do { } while (0)
+#define io_remap_page_range remap_page_range
+#define io_remap_pfn_range remap_pfn_range
+
+
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define VMALLOC_START 0UL
+#define VMALLOC_END 0xffffffffUL
+
+#define FIRST_USER_ADDRESS (0)
+
+#include <asm-generic/pgtable.h>
+
+#else
+
+/*
+ * dummy tlb and user structures.
+ */
+#define v3_tlb_fns (0)
+#define v4_tlb_fns (0)
+#define v4wb_tlb_fns (0)
+#define v4wbi_tlb_fns (0)
+#define v6wbi_tlb_fns (0)
+#define v7wbi_tlb_fns (0)
+
+#define v3_user_fns (0)
+#define v4_user_fns (0)
+#define v4_mc_user_fns (0)
+#define v4wb_user_fns (0)
+#define v4wt_user_fns (0)
+#define v6_user_fns (0)
+#define xscale_mc_user_fns (0)
+
+#endif /*__ASSEMBLY__*/
+
+#endif /* _ASMARM_PGTABLE_H */
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
new file mode 100644
index 00000000..6682ab93
--- /dev/null
+++ b/arch/arm/include/asm/pgtable.h
@@ -0,0 +1,487 @@
+/*
+ * arch/arm/include/asm/pgtable.h
+ *
+ * Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_PGTABLE_H
+#define _ASMARM_PGTABLE_H
+
+#include <linux/const.h>
+#include <asm-generic/4level-fixup.h>
+#include <asm/proc-fns.h>
+
+#ifndef CONFIG_MMU
+
+#include "pgtable-nommu.h"
+
+#else
+
+#include <asm/memory.h>
+#include <mach/vmalloc.h>
+#include <asm/pgtable-hwdef.h>
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ *
+ * Note that platforms may override VMALLOC_START, but they must provide
+ * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space,
+ * which may not overlap IO space.
+ */
+#ifndef VMALLOC_START
+#define VMALLOC_OFFSET (8*1024*1024)
+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#endif
+
+/*
+ * Hardware-wise, we have a two level page table structure, where the first
+ * level has 4096 entries, and the second level has 256 entries. Each entry
+ * is one 32-bit word. Most of the bits in the second level entry are used
+ * by hardware, and there aren't any "accessed" and "dirty" bits.
+ *
+ * Linux on the other hand has a three level page table structure, which can
+ * be wrapped to fit a two level page table structure easily - using the PGD
+ * and PTE only. However, Linux also expects one "PTE" table per page, and
+ * at least a "dirty" bit.
+ *
+ * Therefore, we tweak the implementation slightly - we tell Linux that we
+ * have 2048 entries in the first level, each of which is 8 bytes (iow, two
+ * hardware pointers to the second level.) The second level contains two
+ * hardware PTE tables arranged contiguously, preceded by Linux versions
+ * which contain the state information Linux needs. We, therefore, end up
+ * with 512 entries in the "PTE" level.
+ *
+ * This leads to the page tables having the following layout:
+ *
+ * pgd pte
+ * | |
+ * +--------+
+ * | | +------------+ +0
+ * +- - - - + | Linux pt 0 |
+ * | | +------------+ +1024
+ * +--------+ +0 | Linux pt 1 |
+ * | |-----> +------------+ +2048
+ * +- - - - + +4 | h/w pt 0 |
+ * | |-----> +------------+ +3072
+ * +--------+ +8 | h/w pt 1 |
+ * | | +------------+ +4096
+ *
+ * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
+ * PTE_xxx for definitions of bits appearing in the "h/w pt".
+ *
+ * PMD_xxx definitions refer to bits in the first level page table.
+ *
+ * The "dirty" bit is emulated by only granting hardware write permission
+ * iff the page is marked "writable" and "dirty" in the Linux PTE. This
+ * means that a write to a clean page will cause a permission fault, and
+ * the Linux MM layer will mark the page dirty via handle_pte_fault().
+ * For the hardware to notice the permission change, the TLB entry must
+ * be flushed, and ptep_set_access_flags() does that for us.
+ *
+ * The "accessed" or "young" bit is emulated by a similar method; we only
+ * allow accesses to the page if the "young" bit is set. Accesses to the
+ * page will cause a fault, and handle_pte_fault() will set the young bit
+ * for us as long as the page is marked present in the corresponding Linux
+ * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is
+ * up to date.
+ *
+ * However, when the "young" bit is cleared, we deny access to the page
+ * by clearing the hardware PTE. Currently Linux does not flush the TLB
+ * for us in this case, which means the TLB will retain the transation
+ * until either the TLB entry is evicted under pressure, or a context
+ * switch which changes the user space mapping occurs.
+ */
+#define PTRS_PER_PTE 512
+#define PTRS_PER_PMD 1
+#define PTRS_PER_PGD 2048
+
+#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
+#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
+#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
+
+/*
+ * PMD_SHIFT determines the size of the area a second-level page table can map
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
+#define PMD_SHIFT 21
+#define PGDIR_SHIFT 21
+
+#define LIBRARY_TEXT_START 0x0c000000
+
+#ifndef __ASSEMBLY__
+extern void __pte_error(const char *file, int line, pte_t);
+extern void __pmd_error(const char *file, int line, pmd_t);
+extern void __pgd_error(const char *file, int line, pgd_t);
+
+#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
+#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
+#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
+#endif /* !__ASSEMBLY__ */
+
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * This is the lowest virtual address we can permit any user space
+ * mapping to be mapped at. This is particularly important for
+ * non-high vector CPUs.
+ */
+#define FIRST_USER_ADDRESS PAGE_SIZE
+
+#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
+
+/*
+ * section address mask and size definitions.
+ */
+#define SECTION_SHIFT 20
+#define SECTION_SIZE (1UL << SECTION_SHIFT)
+#define SECTION_MASK (~(SECTION_SIZE-1))
+
+/*
+ * ARMv6 supersection address mask and size definitions.
+ */
+#define SUPERSECTION_SHIFT 24
+#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT)
+#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1))
+
+/*
+ * "Linux" PTE definitions.
+ *
+ * We keep two sets of PTEs - the hardware and the linux version.
+ * This allows greater flexibility in the way we map the Linux bits
+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
+ * bits.
+ *
+ * The PTE table pointer refers to the hardware entries; the "Linux"
+ * entries are stored 1024 bytes below.
+ */
+#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
+#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
+#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
+#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
+#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
+#define L_PTE_USER (_AT(pteval_t, 1) << 8)
+#define L_PTE_XN (_AT(pteval_t, 1) << 9)
+#define L_PTE_SHARED (_AT(pteval_t, 1) << 10) /* shared(v6), coherent(xsc3) */
+
+/*
+ * These are the memory types, defined to be compatible with
+ * pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
+ */
+#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0x00) << 2) /* 0000 */
+#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 0x01) << 2) /* 0001 */
+#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 0x02) << 2) /* 0010 */
+#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 0x03) << 2) /* 0011 */
+#define L_PTE_MT_MINICACHE (_AT(pteval_t, 0x06) << 2) /* 0110 (sa1100, xscale) */
+#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 0x07) << 2) /* 0111 */
+#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 0x04) << 2) /* 0100 */
+#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 0x0c) << 2) /* 1100 */
+#define L_PTE_MT_DEV_WC (_AT(pteval_t, 0x09) << 2) /* 1001 */
+#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
+#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * The pgprot_* and protection_map entries will be fixed up in runtime
+ * to include the cachable and bufferable bits based on memory policy,
+ * as well as any architecture dependent bits like global/ASID and SMP
+ * shared mapping bits.
+ */
+#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
+
+extern pgprot_t pgprot_user;
+extern pgprot_t pgprot_kernel;
+
+#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
+
+#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
+#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
+#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
+#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
+#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
+#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
+#define PAGE_KERNEL_EXEC pgprot_kernel
+
+#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
+#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
+#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
+#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
+#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
+
+#define __pgprot_modify(prot,mask,bits) \
+ __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
+
+#define pgprot_noncached(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
+
+#define pgprot_writecombine(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
+
+#define pgprot_writethrough(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_WRITETHROUGH)
+
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
+#define __HAVE_PHYS_MEM_ACCESS_PROT
+struct file;
+extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot);
+#else
+#define pgprot_dmacoherent(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * The table below defines the page protection levels that we insert into our
+ * Linux page table version. These get translated into the best that the
+ * architecture can perform. Note that on most ARM hardware:
+ * 1) We cannot do execute protection
+ * 2) If we could do execute protection, then read is implied
+ * 3) write implies read permissions
+ */
+#define __P000 __PAGE_NONE
+#define __P001 __PAGE_READONLY
+#define __P010 __PAGE_COPY
+#define __P011 __PAGE_COPY
+#define __P100 __PAGE_READONLY_EXEC
+#define __P101 __PAGE_READONLY_EXEC
+#define __P110 __PAGE_COPY_EXEC
+#define __P111 __PAGE_COPY_EXEC
+
+#define __S000 __PAGE_NONE
+#define __S001 __PAGE_READONLY
+#define __S010 __PAGE_SHARED
+#define __S011 __PAGE_SHARED
+#define __S100 __PAGE_READONLY_EXEC
+#define __S101 __PAGE_READONLY_EXEC
+#define __S110 __PAGE_SHARED_EXEC
+#define __S111 __PAGE_SHARED_EXEC
+
+#ifndef __ASSEMBLY__
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern struct page *empty_zero_page;
+#define ZERO_PAGE(vaddr) (empty_zero_page)
+
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/* to find an entry in a page-table-directory */
+#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
+
+#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_present(pgd) (1)
+#define pgd_clear(pgdp) do { } while (0)
+#define set_pgd(pgd,pgdp) do { } while (0)
+#define set_pud(pud,pudp) do { } while (0)
+
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir, addr) ((pmd_t *)(dir))
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_present(pmd) (pmd_val(pmd))
+#define pmd_bad(pmd) (pmd_val(pmd) & 2)
+
+#define copy_pmd(pmdpd,pmdps) \
+ do { \
+ pmdpd[0] = pmdps[0]; \
+ pmdpd[1] = pmdps[1]; \
+ flush_pmd_entry(pmdpd); \
+ } while (0)
+
+#define pmd_clear(pmdp) \
+ do { \
+ pmdp[0] = __pmd(0); \
+ pmdp[1] = __pmd(0); \
+ clean_pmd_entry(pmdp); \
+ } while (0)
+
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+{
+ return __va(pmd_val(pmd) & PAGE_MASK);
+}
+
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
+
+/* we don't need complex calculations here as the pmd is folded into the pgd */
+#define pmd_addr_end(addr,end) (end)
+
+
+#ifndef CONFIG_HIGHPTE
+#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
+#define __pte_unmap(pte) do { } while (0)
+#else
+#define __pte_map(pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd)))
+#define __pte_unmap(pte) kunmap_atomic(pte)
+#endif
+
+#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+
+#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
+
+#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
+#define pte_unmap(pte) __pte_unmap(pte)
+
+#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
+#define pfn_pte(pfn,prot) __pte(__pfn_to_phys(pfn) | pgprot_val(prot))
+
+#define pte_page(pte) pfn_to_page(pte_pfn(pte))
+#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
+
+#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
+#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
+
+#if __LINUX_ARM_ARCH__ < 6
+static inline void __sync_icache_dcache(pte_t pteval)
+{
+}
+#else
+extern void __sync_icache_dcache(pte_t pteval);
+#endif
+
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pteval)
+{
+ if (addr >= TASK_SIZE)
+ set_pte_ext(ptep, pteval, 0);
+ else {
+ __sync_icache_dcache(pteval);
+ set_pte_ext(ptep, pteval, PTE_EXT_NG);
+ }
+}
+
+#define pte_none(pte) (!pte_val(pte))
+#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
+#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
+#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
+#define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN))
+#define pte_special(pte) (0)
+
+#define pte_present_user(pte) \
+ ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
+ (L_PTE_PRESENT | L_PTE_USER))
+
+#define PTE_BIT_FUNC(fn,op) \
+static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
+
+PTE_BIT_FUNC(wrprotect, |= L_PTE_RDONLY);
+PTE_BIT_FUNC(mkwrite, &= ~L_PTE_RDONLY);
+PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY);
+PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY);
+PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG);
+PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
+
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER;
+ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
+ return pte;
+}
+
+/*
+ * Encode and decode a swap entry. Swap entries are stored in the Linux
+ * page tables as follows:
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * <--------------- offset --------------------> <- type --> 0 0 0
+ *
+ * This gives us up to 63 swap files and 32GB per swap file. Note that
+ * the offset field is always non-zero.
+ */
+#define __SWP_TYPE_SHIFT 3
+#define __SWP_TYPE_BITS 6
+#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
+#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
+
+#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
+#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
+#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
+
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
+
+/*
+ * It is an error for the kernel to have more swap files than we can
+ * encode in the PTEs. This ensures that we know when MAX_SWAPFILES
+ * is increased beyond what we presently support.
+ */
+#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
+
+/*
+ * Encode and decode a file entry. File entries are stored in the Linux
+ * page tables as follows:
+ *
+ * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * <----------------------- offset ------------------------> 1 0 0
+ */
+#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
+#define pte_to_pgoff(x) (pte_val(x) >> 3)
+#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
+
+#define PTE_FILE_MAX_BITS 29
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+/* FIXME: this is not correct */
+#define kern_addr_valid(addr) (1)
+
+#include <asm-generic/pgtable.h>
+
+/*
+ * We provide our own arch_get_unmapped_area to cope with VIPT caches.
+ */
+#define HAVE_ARCH_UNMAPPED_AREA
+
+/*
+ * remap a physical page `pfn' of size `size' with page protection `prot'
+ * into virtual address `from'
+ */
+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
+ remap_pfn_range(vma, from, pfn, size, prot)
+
+#define pgtable_cache_init() do { } while (0)
+
+void identity_mapping_add(pgd_t *, unsigned long, unsigned long);
+void identity_mapping_del(pgd_t *, unsigned long, unsigned long);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_MMU */
+
+#endif /* _ASMARM_PGTABLE_H */
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
new file mode 100644
index 00000000..7544ce6b
--- /dev/null
+++ b/arch/arm/include/asm/pmu.h
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/arm/include/asm/pmu.h
+ *
+ * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ *
+ * This program is free software; you can 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_PMU_H__
+#define __ARM_PMU_H__
+
+#include <linux/interrupt.h>
+
+enum arm_pmu_type {
+ ARM_PMU_DEVICE_CPU = 0,
+ ARM_NUM_PMU_DEVICES,
+};
+
+/*
+ * struct arm_pmu_platdata - ARM PMU platform data
+ *
+ * @handle_irq: an optional handler which will be called from the interrupt and
+ * passed the address of the low level handler, and can be used to implement
+ * any platform specific handling before or after calling it.
+ */
+struct arm_pmu_platdata {
+ irqreturn_t (*handle_irq)(int irq, void *dev,
+ irq_handler_t pmu_handler);
+};
+
+#ifdef CONFIG_CPU_HAS_PMU
+
+/**
+ * reserve_pmu() - reserve the hardware performance counters
+ *
+ * Reserve the hardware performance counters in the system for exclusive use.
+ * The platform_device for the system is returned on success, ERR_PTR()
+ * encoded error on failure.
+ */
+extern struct platform_device *
+reserve_pmu(enum arm_pmu_type device);
+
+/**
+ * release_pmu() - Relinquish control of the performance counters
+ *
+ * Release the performance counters and allow someone else to use them.
+ * Callers must have disabled the counters and released IRQs before calling
+ * this. The platform_device returned from reserve_pmu() must be passed as
+ * a cookie.
+ */
+extern int
+release_pmu(struct platform_device *pdev);
+
+/**
+ * init_pmu() - Initialise the PMU.
+ *
+ * Initialise the system ready for PMU enabling. This should typically set the
+ * IRQ affinity and nothing else. The users (oprofile/perf events etc) will do
+ * the actual hardware initialisation.
+ */
+extern int
+init_pmu(enum arm_pmu_type device);
+
+#else /* CONFIG_CPU_HAS_PMU */
+
+#include <linux/err.h>
+
+static inline struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline int
+release_pmu(struct platform_device *pdev)
+{
+ return -ENODEV;
+}
+
+static inline int
+init_pmu(enum arm_pmu_type device)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_CPU_HAS_PMU */
+
+#endif /* __ARM_PMU_H__ */
diff --git a/arch/arm/include/asm/poll.h b/arch/arm/include/asm/poll.h
new file mode 100644
index 00000000..c98509d3
--- /dev/null
+++ b/arch/arm/include/asm/poll.h
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h
new file mode 100644
index 00000000..2446d23b
--- /dev/null
+++ b/arch/arm/include/asm/posix_types.h
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/include/asm/posix_types.h
+ *
+ * Copyright (C) 1996-1998 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 27-06-1996 RMK Created
+ */
+#ifndef __ARCH_ARM_POSIX_TYPES_H
+#define __ARCH_ARM_POSIX_TYPES_H
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc. Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef int __kernel_daddr_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+ int val[2];
+} __kernel_fsid_t;
+
+#if defined(__KERNEL__)
+
+#undef __FD_SET
+#define __FD_SET(fd, fdsetp) \
+ (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
+
+#undef __FD_CLR
+#define __FD_CLR(fd, fdsetp) \
+ (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
+
+#undef __FD_ISSET
+#define __FD_ISSET(fd, fdsetp) \
+ ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp) \
+ (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
new file mode 100644
index 00000000..8ec535e1
--- /dev/null
+++ b/arch/arm/include/asm/proc-fns.h
@@ -0,0 +1,115 @@
+/*
+ * arch/arm/include/asm/proc-fns.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2000 Deep Blue Solutions 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 __ASM_PROCFNS_H
+#define __ASM_PROCFNS_H
+
+#ifdef __KERNEL__
+
+#include <asm/glue-proc.h>
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+
+struct mm_struct;
+
+/*
+ * Don't change this structure - ASM code relies on it.
+ */
+extern struct processor {
+ /* MISC
+ * get data abort address/flags
+ */
+ void (*_data_abort)(unsigned long pc);
+ /*
+ * Retrieve prefetch fault address
+ */
+ unsigned long (*_prefetch_abort)(unsigned long lr);
+ /*
+ * Set up any processor specifics
+ */
+ void (*_proc_init)(void);
+ /*
+ * Disable any processor specifics
+ */
+ void (*_proc_fin)(void);
+ /*
+ * Special stuff for a reset
+ */
+ void (*reset)(unsigned long addr) __attribute__((noreturn));
+ /*
+ * Idle the processor
+ */
+ int (*_do_idle)(void);
+ /*
+ * Processor architecture specific
+ */
+ /*
+ * clean a virtual address range from the
+ * D-cache without flushing the cache.
+ */
+ void (*dcache_clean_area)(void *addr, int size);
+
+ /*
+ * Set the page table
+ */
+ void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
+ /*
+ * Set a possibly extended PTE. Non-extended PTEs should
+ * ignore 'ext'.
+ */
+ void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
+
+ /* Suspend/resume */
+ unsigned int suspend_size;
+ void (*do_suspend)(void *);
+ void (*do_resume)(void *);
+} processor;
+
+#ifndef MULTI_CPU
+extern void cpu_proc_init(void);
+extern void cpu_proc_fin(void);
+extern int cpu_do_idle(void);
+extern void cpu_dcache_clean_area(void *, int);
+extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
+extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
+extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+#else
+#define cpu_proc_init() processor._proc_init()
+#define cpu_proc_fin() processor._proc_fin()
+#define cpu_reset(addr) processor.reset(addr)
+#define cpu_do_idle() processor._do_idle()
+#define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz)
+#define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext)
+#define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm)
+#endif
+
+extern void cpu_resume(void);
+
+#include <asm/memory.h>
+
+#ifdef CONFIG_MMU
+
+#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
+
+#define cpu_get_pgd() \
+ ({ \
+ unsigned long pg; \
+ __asm__("mrc p15, 0, %0, c2, c0, 0" \
+ : "=r" (pg) : : "cc"); \
+ pg &= ~0x3fff; \
+ (pgd_t *)phys_to_virt(pg); \
+ })
+
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* __ASM_PROCFNS_H */
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
new file mode 100644
index 00000000..b2d9df56
--- /dev/null
+++ b/arch/arm/include/asm/processor.h
@@ -0,0 +1,128 @@
+/*
+ * arch/arm/include/asm/processor.h
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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_PROCESSOR_H
+#define __ASM_ARM_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#ifdef __KERNEL__
+
+#include <asm/hw_breakpoint.h>
+#include <asm/ptrace.h>
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
+ TASK_SIZE : TASK_SIZE_26)
+#define STACK_TOP_MAX TASK_SIZE
+#endif
+
+struct debug_info {
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ struct perf_event *hbp[ARM_MAX_HBP_SLOTS];
+#endif
+};
+
+struct thread_struct {
+ /* fault info */
+ unsigned long address;
+ unsigned long trap_no;
+ unsigned long error_code;
+ /* debugging */
+ struct debug_info debug;
+};
+
+#define INIT_THREAD { }
+
+#ifdef CONFIG_MMU
+#define nommu_start_thread(regs) do { } while (0)
+#else
+#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
+#endif
+
+#define start_thread(regs,pc,sp) \
+({ \
+ unsigned long *stack = (unsigned long *)sp; \
+ set_fs(USER_DS); \
+ memset(regs->uregs, 0, sizeof(regs->uregs)); \
+ if (current->personality & ADDR_LIMIT_32BIT) \
+ regs->ARM_cpsr = USR_MODE; \
+ else \
+ regs->ARM_cpsr = USR26_MODE; \
+ if (elf_hwcap & HWCAP_THUMB && pc & 1) \
+ regs->ARM_cpsr |= PSR_T_BIT; \
+ regs->ARM_cpsr |= PSR_ENDSTATE; \
+ regs->ARM_pc = pc & ~1; /* pc */ \
+ regs->ARM_sp = sp; /* sp */ \
+ regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
+ regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
+ regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
+ nommu_start_thread(regs); \
+})
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+extern void release_thread(struct task_struct *);
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
+#define cpu_relax() smp_mb()
+#else
+#define cpu_relax() barrier()
+#endif
+
+/*
+ * Create a new kernel thread
+ */
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+#define task_pt_regs(p) \
+ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
+
+#define KSTK_EIP(tsk) task_pt_regs(tsk)->ARM_pc
+#define KSTK_ESP(tsk) task_pt_regs(tsk)->ARM_sp
+
+/*
+ * Prefetching support - only ARMv5.
+ */
+#if __LINUX_ARM_ARCH__ >= 5
+
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *ptr)
+{
+ __asm__ __volatile__(
+ "pld\t%a0"
+ :
+ : "p" (ptr)
+ : "cc");
+}
+
+#define ARCH_HAS_PREFETCHW
+#define prefetchw(ptr) prefetch(ptr)
+
+#define ARCH_HAS_SPINLOCK_PREFETCH
+#define spin_lock_prefetch(x) do { } while (0)
+
+#endif
+
+#endif
+
+#endif /* __ASM_ARM_PROCESSOR_H */
diff --git a/arch/arm/include/asm/procinfo.h b/arch/arm/include/asm/procinfo.h
new file mode 100644
index 00000000..ca52e584
--- /dev/null
+++ b/arch/arm/include/asm/procinfo.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/include/asm/procinfo.h
+ *
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can 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_PROCINFO_H
+#define __ASM_PROCINFO_H
+
+#ifdef __KERNEL__
+
+struct cpu_tlb_fns;
+struct cpu_user_fns;
+struct cpu_cache_fns;
+struct processor;
+
+/*
+ * Note! struct processor is always defined if we're
+ * using MULTI_CPU, otherwise this entry is unused,
+ * but still exists.
+ *
+ * NOTE! The following structure is defined by assembly
+ * language, NOT C code. For more information, check:
+ * arch/arm/mm/proc-*.S and arch/arm/kernel/head.S
+ */
+struct proc_info_list {
+ unsigned int cpu_val;
+ unsigned int cpu_mask;
+ unsigned long __cpu_mm_mmu_flags; /* used by head.S */
+ unsigned long __cpu_io_mmu_flags; /* used by head.S */
+ unsigned long __cpu_flush; /* used by head.S */
+ const char *arch_name;
+ const char *elf_name;
+ unsigned int elf_hwcap;
+ const char *cpu_name;
+ struct processor *proc;
+ struct cpu_tlb_fns *tlb;
+ struct cpu_user_fns *user;
+ struct cpu_cache_fns *cache;
+};
+
+#else /* __KERNEL__ */
+#include <asm/elf.h>
+#warning "Please include asm/elf.h instead"
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
new file mode 100644
index 00000000..11b8708f
--- /dev/null
+++ b/arch/arm/include/asm/prom.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/include/asm/prom.h
+ *
+ * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.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 __ASMARM_PROM_H
+#define __ASMARM_PROM_H
+
+#ifdef CONFIG_OF
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+ return;
+}
+
+extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+extern void arm_dt_memblock_reserve(void);
+
+#else /* CONFIG_OF */
+
+static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+ return NULL;
+}
+
+static inline void arm_dt_memblock_reserve(void) { }
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
new file mode 100644
index 00000000..312d1087
--- /dev/null
+++ b/arch/arm/include/asm/ptrace.h
@@ -0,0 +1,243 @@
+/*
+ * arch/arm/include/asm/ptrace.h
+ *
+ * Copyright (C) 1996-2003 Russell King
+ *
+ * This program is free software; you can 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_PTRACE_H
+#define __ASM_ARM_PTRACE_H
+
+#include <asm/hwcap.h>
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+/* PTRACE_ATTACH is 16 */
+/* PTRACE_DETACH is 17 */
+#define PTRACE_GETWMMXREGS 18
+#define PTRACE_SETWMMXREGS 19
+/* 20 is unused */
+#define PTRACE_OLDSETOPTIONS 21
+#define PTRACE_GET_THREAD_AREA 22
+#define PTRACE_SET_SYSCALL 23
+/* PTRACE_SYSCALL is 24 */
+#define PTRACE_GETCRUNCHREGS 25
+#define PTRACE_SETCRUNCHREGS 26
+#define PTRACE_GETVFPREGS 27
+#define PTRACE_SETVFPREGS 28
+#define PTRACE_GETHBPREGS 29
+#define PTRACE_SETHBPREGS 30
+
+/*
+ * PSR bits
+ */
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define ABT_MODE 0x00000017
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+#define PSR_T_BIT 0x00000020
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_A_BIT 0x00000100
+#define PSR_E_BIT 0x00000200
+#define PSR_J_BIT 0x01000000
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+
+/*
+ * Groups of PSR bits
+ */
+#define PSR_f 0xff000000 /* Flags */
+#define PSR_s 0x00ff0000 /* Status */
+#define PSR_x 0x0000ff00 /* Extension */
+#define PSR_c 0x000000ff /* Control */
+
+/*
+ * ARMv7 groups of APSR bits
+ */
+#define PSR_ISET_MASK 0x01000010 /* ISA state (J, T) mask */
+#define PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
+#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
+
+/*
+ * Default endianness state
+ */
+#ifdef CONFIG_CPU_ENDIAN_BE8
+#define PSR_ENDSTATE PSR_E_BIT
+#else
+#define PSR_ENDSTATE 0
+#endif
+
+/*
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR 0x10000
+#define PT_DATA_ADDR 0x10004
+#define PT_TEXT_END_ADDR 0x10008
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored on the
+ * stack during a system call. Note that sizeof(struct pt_regs)
+ * has to be a multiple of 8.
+ */
+#ifndef __KERNEL__
+struct pt_regs {
+ long uregs[18];
+};
+#else /* __KERNEL__ */
+struct pt_regs {
+ unsigned long uregs[18];
+};
+#endif /* __KERNEL__ */
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+/*
+ * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+ * and core dumps.
+ */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+
+#ifdef __KERNEL__
+
+#define user_mode(regs) \
+ (((regs)->ARM_cpsr & 0xf) == 0)
+
+#ifdef CONFIG_ARM_THUMB
+#define thumb_mode(regs) \
+ (((regs)->ARM_cpsr & PSR_T_BIT))
+#else
+#define thumb_mode(regs) (0)
+#endif
+
+#define isa_mode(regs) \
+ ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \
+ (((regs)->ARM_cpsr & PSR_T_BIT) >> 5))
+
+#define processor_mode(regs) \
+ ((regs)->ARM_cpsr & MODE_MASK)
+
+#define interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_I_BIT))
+
+#define fast_interrupts_enabled(regs) \
+ (!((regs)->ARM_cpsr & PSR_F_BIT))
+
+/* Are the current registers suitable for user mode?
+ * (used to maintain security in signal handlers)
+ */
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+ unsigned long mode = regs->ARM_cpsr & MODE_MASK;
+
+ /*
+ * Always clear the F (FIQ) and A (delayed abort) bits
+ */
+ regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
+
+ if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
+ if (mode == USR_MODE)
+ return 1;
+ if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
+ return 1;
+ }
+
+ /*
+ * Force CPSR to something logical...
+ */
+ regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
+ if (!(elf_hwcap & HWCAP_26BIT))
+ regs->ARM_cpsr |= USR_MODE;
+
+ return 0;
+}
+
+#define instruction_pointer(regs) (regs)->ARM_pc
+
+#ifdef CONFIG_SMP
+extern unsigned long profile_pc(struct pt_regs *regs);
+#else
+#define profile_pc(regs) instruction_pointer(regs)
+#endif
+
+#define predicate(x) ((x) & 0xf0000000)
+#define PREDICATE_ALWAYS 0xe0000000
+
+/*
+ * kprobe-based event tracer support
+ */
+#include <linux/stddef.h>
+#include <linux/types.h>
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
+
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n);
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+ return regs->ARM_sp;
+}
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASSEMBLY__ */
+
+#endif
+
diff --git a/arch/arm/include/asm/resource.h b/arch/arm/include/asm/resource.h
new file mode 100644
index 00000000..734b581b
--- /dev/null
+++ b/arch/arm/include/asm/resource.h
@@ -0,0 +1,6 @@
+#ifndef _ARM_RESOURCE_H
+#define _ARM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif
diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h
new file mode 100644
index 00000000..2f87870d
--- /dev/null
+++ b/arch/arm/include/asm/scatterlist.h
@@ -0,0 +1,8 @@
+#ifndef _ASMARM_SCATTERLIST_H
+#define _ASMARM_SCATTERLIST_H
+
+#include <asm/memory.h>
+#include <asm/types.h>
+#include <asm-generic/scatterlist.h>
+
+#endif /* _ASMARM_SCATTERLIST_H */
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
new file mode 100644
index 00000000..c8e6ddf3
--- /dev/null
+++ b/arch/arm/include/asm/sched_clock.h
@@ -0,0 +1,120 @@
+/*
+ * sched_clock.h: support for extending counters to full 64-bit ns counter
+ *
+ * This program is free software; you can 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_SCHED_CLOCK
+#define ASM_SCHED_CLOCK
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct clock_data {
+ u64 epoch_ns;
+ u32 epoch_cyc;
+ u32 epoch_cyc_copy;
+ u32 mult;
+ u32 shift;
+};
+
+#define DEFINE_CLOCK_DATA(name) struct clock_data name
+
+static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
+{
+ return (cyc * mult) >> shift;
+}
+
+/*
+ * Atomically update the sched_clock epoch. Your update callback will
+ * be called from a timer before the counter wraps - read the current
+ * counter value, and call this function to safely move the epochs
+ * forward. Only use this from the update callback.
+ */
+static inline void update_sched_clock(struct clock_data *cd, u32 cyc, u32 mask)
+{
+ unsigned long flags;
+ u64 ns = cd->epoch_ns +
+ cyc_to_ns((cyc - cd->epoch_cyc) & mask, cd->mult, cd->shift);
+
+ /*
+ * Write epoch_cyc and epoch_ns in a way that the update is
+ * detectable in cyc_to_fixed_sched_clock().
+ */
+ raw_local_irq_save(flags);
+ cd->epoch_cyc = cyc;
+ smp_wmb();
+ cd->epoch_ns = ns;
+ smp_wmb();
+ cd->epoch_cyc_copy = cyc;
+ raw_local_irq_restore(flags);
+}
+
+/*
+ * If your clock rate is known at compile time, using this will allow
+ * you to optimize the mult/shift loads away. This is paired with
+ * init_fixed_sched_clock() to ensure that your mult/shift are correct.
+ */
+static inline unsigned long long cyc_to_fixed_sched_clock(struct clock_data *cd,
+ u32 cyc, u32 mask, u32 mult, u32 shift)
+{
+ u64 epoch_ns;
+ u32 epoch_cyc;
+
+ /*
+ * Load the epoch_cyc and epoch_ns atomically. We do this by
+ * ensuring that we always write epoch_cyc, epoch_ns and
+ * epoch_cyc_copy in strict order, and read them in strict order.
+ * If epoch_cyc and epoch_cyc_copy are not equal, then we're in
+ * the middle of an update, and we should repeat the load.
+ */
+ do {
+ epoch_cyc = cd->epoch_cyc;
+ smp_rmb();
+ epoch_ns = cd->epoch_ns;
+ smp_rmb();
+ } while (epoch_cyc != cd->epoch_cyc_copy);
+
+ return epoch_ns + cyc_to_ns((cyc - epoch_cyc) & mask, mult, shift);
+}
+
+/*
+ * Otherwise, you need to use this, which will obtain the mult/shift
+ * from the clock_data structure. Use init_sched_clock() with this.
+ */
+static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
+ u32 cyc, u32 mask)
+{
+ return cyc_to_fixed_sched_clock(cd, cyc, mask, cd->mult, cd->shift);
+}
+
+/*
+ * Initialize the clock data - calculate the appropriate multiplier
+ * and shift. Also setup a timer to ensure that the epoch is refreshed
+ * at the appropriate time interval, which will call your update
+ * handler.
+ */
+void init_sched_clock(struct clock_data *, void (*)(void),
+ unsigned int, unsigned long);
+
+/*
+ * Use this initialization function rather than init_sched_clock() if
+ * you're using cyc_to_fixed_sched_clock, which will warn if your
+ * constants are incorrect.
+ */
+static inline void init_fixed_sched_clock(struct clock_data *cd,
+ void (*update)(void), unsigned int bits, unsigned long rate,
+ u32 mult, u32 shift)
+{
+ init_sched_clock(cd, update, bits, rate);
+ if (cd->mult != mult || cd->shift != shift) {
+ pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n"
+ "sched_clock: fix multiply/shift to avoid scheduler hiccups\n",
+ mult, shift, cd->mult, cd->shift);
+ }
+}
+
+extern void sched_clock_postinit(void);
+
+#endif
diff --git a/arch/arm/include/asm/seccomp.h b/arch/arm/include/asm/seccomp.h
new file mode 100644
index 00000000..52b156b3
--- /dev/null
+++ b/arch/arm/include/asm/seccomp.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_ARM_SECCOMP_H
+#define _ASM_ARM_SECCOMP_H
+
+#include <linux/unistd.h>
+
+#define __NR_seccomp_read __NR_read
+#define __NR_seccomp_write __NR_write
+#define __NR_seccomp_exit __NR_exit
+#define __NR_seccomp_sigreturn __NR_rt_sigreturn
+
+#endif /* _ASM_ARM_SECCOMP_H */
diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h
new file mode 100644
index 00000000..2b8c5160
--- /dev/null
+++ b/arch/arm/include/asm/sections.h
@@ -0,0 +1 @@
+#include <asm-generic/sections.h>
diff --git a/arch/arm/include/asm/segment.h b/arch/arm/include/asm/segment.h
new file mode 100644
index 00000000..9e24c21f
--- /dev/null
+++ b/arch/arm/include/asm/segment.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_ARM_SEGMENT_H
+#define __ASM_ARM_SEGMENT_H
+
+#define __KERNEL_CS 0x0
+#define __KERNEL_DS 0x0
+
+#define __USER_CS 0x1
+#define __USER_DS 0x1
+
+#endif /* __ASM_ARM_SEGMENT_H */
+
diff --git a/arch/arm/include/asm/sembuf.h b/arch/arm/include/asm/sembuf.h
new file mode 100644
index 00000000..1c028395
--- /dev/null
+++ b/arch/arm/include/asm/sembuf.h
@@ -0,0 +1,25 @@
+#ifndef _ASMARM_SEMBUF_H
+#define _ASMARM_SEMBUF_H
+
+/*
+ * The semid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */
+ __kernel_time_t sem_otime; /* last semop time */
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime; /* last change time */
+ unsigned long __unused2;
+ unsigned long sem_nsems; /* no. of semaphores in array */
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASMARM_SEMBUF_H */
diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h
new file mode 100644
index 00000000..ebb04909
--- /dev/null
+++ b/arch/arm/include/asm/serial.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/include/asm/serial.h
+ *
+ * Copyright (C) 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 15-10-1996 RMK Created
+ */
+
+#ifndef __ASM_SERIAL_H
+#define __ASM_SERIAL_H
+
+#define BASE_BAUD (1843200 / 16)
+
+#endif
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
new file mode 100644
index 00000000..ee2ad8ae
--- /dev/null
+++ b/arch/arm/include/asm/setup.h
@@ -0,0 +1,226 @@
+/*
+ * linux/include/asm/setup.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Structure passed to kernel to tell it about the
+ * hardware it's running on. See Documentation/arm/Setup
+ * for more info.
+ */
+#ifndef __ASMARM_SETUP_H
+#define __ASMARM_SETUP_H
+
+#include <linux/types.h>
+
+#define COMMAND_LINE_SIZE 1024
+
+/* The list ends with an ATAG_NONE node. */
+#define ATAG_NONE 0x00000000
+
+struct tag_header {
+ __u32 size;
+ __u32 tag;
+};
+
+/* The list must start with an ATAG_CORE node */
+#define ATAG_CORE 0x54410001
+
+struct tag_core {
+ __u32 flags; /* bit 0 = read-only */
+ __u32 pagesize;
+ __u32 rootdev;
+};
+
+/* it is allowed to have multiple ATAG_MEM nodes */
+#define ATAG_MEM 0x54410002
+
+struct tag_mem32 {
+ __u32 size;
+ __u32 start; /* physical start address */
+};
+
+/* VGA text type displays */
+#define ATAG_VIDEOTEXT 0x54410003
+
+struct tag_videotext {
+ __u8 x;
+ __u8 y;
+ __u16 video_page;
+ __u8 video_mode;
+ __u8 video_cols;
+ __u16 video_ega_bx;
+ __u8 video_lines;
+ __u8 video_isvga;
+ __u16 video_points;
+};
+
+/* describes how the ramdisk will be used in kernel */
+#define ATAG_RAMDISK 0x54410004
+
+struct tag_ramdisk {
+ __u32 flags; /* bit 0 = load, bit 1 = prompt */
+ __u32 size; /* decompressed ramdisk size in _kilo_ bytes */
+ __u32 start; /* starting block of floppy-based RAM disk image */
+};
+
+/* describes where the compressed ramdisk image lives (virtual address) */
+/*
+ * this one accidentally used virtual addresses - as such,
+ * it's deprecated.
+ */
+#define ATAG_INITRD 0x54410005
+
+/* describes where the compressed ramdisk image lives (physical address) */
+#define ATAG_INITRD2 0x54420005
+
+struct tag_initrd {
+ __u32 start; /* physical start address */
+ __u32 size; /* size of compressed ramdisk image in bytes */
+};
+
+/* board serial number. "64 bits should be enough for everybody" */
+#define ATAG_SERIAL 0x54410006
+
+struct tag_serialnr {
+ __u32 low;
+ __u32 high;
+};
+
+/* board revision */
+#define ATAG_REVISION 0x54410007
+
+struct tag_revision {
+ __u32 rev;
+};
+
+/* initial values for vesafb-type framebuffers. see struct screen_info
+ * in include/linux/tty.h
+ */
+#define ATAG_VIDEOLFB 0x54410008
+
+struct tag_videolfb {
+ __u16 lfb_width;
+ __u16 lfb_height;
+ __u16 lfb_depth;
+ __u16 lfb_linelength;
+ __u32 lfb_base;
+ __u32 lfb_size;
+ __u8 red_size;
+ __u8 red_pos;
+ __u8 green_size;
+ __u8 green_pos;
+ __u8 blue_size;
+ __u8 blue_pos;
+ __u8 rsvd_size;
+ __u8 rsvd_pos;
+};
+
+/* command line: \0 terminated string */
+#define ATAG_CMDLINE 0x54410009
+
+struct tag_cmdline {
+ char cmdline[1]; /* this is the minimum size */
+};
+
+/* acorn RiscPC specific information */
+#define ATAG_ACORN 0x41000101
+
+struct tag_acorn {
+ __u32 memc_control_reg;
+ __u32 vram_pages;
+ __u8 sounddefault;
+ __u8 adfsdrives;
+};
+
+/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
+#define ATAG_MEMCLK 0x41000402
+
+struct tag_memclk {
+ __u32 fmemclk;
+};
+
+struct tag {
+ struct tag_header hdr;
+ union {
+ struct tag_core core;
+ struct tag_mem32 mem;
+ struct tag_videotext videotext;
+ struct tag_ramdisk ramdisk;
+ struct tag_initrd initrd;
+ struct tag_serialnr serialnr;
+ struct tag_revision revision;
+ struct tag_videolfb videolfb;
+ struct tag_cmdline cmdline;
+
+ /*
+ * Acorn specific
+ */
+ struct tag_acorn acorn;
+
+ /*
+ * DC21285 specific
+ */
+ struct tag_memclk memclk;
+ } u;
+};
+
+struct tagtable {
+ __u32 tag;
+ int (*parse)(const struct tag *);
+};
+
+#define tag_member_present(tag,member) \
+ ((unsigned long)(&((struct tag *)0L)->member + 1) \
+ <= (tag)->hdr.size * 4)
+
+#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size))
+#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
+
+#define for_each_tag(t,base) \
+ for (t = base; t->hdr.size; t = tag_next(t))
+
+#ifdef __KERNEL__
+
+#define __tag __used __attribute__((__section__(".taglist.init")))
+#define __tagtable(tag, fn) \
+static struct tagtable __tagtable_##fn __tag = { tag, fn }
+
+/*
+ * Memory map description
+ */
+#define NR_BANKS 8
+
+struct membank {
+ phys_addr_t start;
+ unsigned long size;
+ unsigned int highmem;
+};
+
+struct meminfo {
+ int nr_banks;
+ struct membank bank[NR_BANKS];
+};
+
+extern struct meminfo meminfo;
+
+#define for_each_bank(iter,mi) \
+ for (iter = 0; iter < (mi)->nr_banks; iter++)
+
+#define bank_pfn_start(bank) __phys_to_pfn((bank)->start)
+#define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size)
+#define bank_pfn_size(bank) ((bank)->size >> PAGE_SHIFT)
+#define bank_phys_start(bank) (bank)->start
+#define bank_phys_end(bank) ((bank)->start + (bank)->size)
+#define bank_phys_size(bank) (bank)->size
+
+extern int arm_add_memory(phys_addr_t start, unsigned long size);
+extern void early_print(const char *str, ...);
+extern void dump_machine_table(void);
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/arm/include/asm/shmbuf.h b/arch/arm/include/asm/shmbuf.h
new file mode 100644
index 00000000..2e5c67ba
--- /dev/null
+++ b/arch/arm/include/asm/shmbuf.h
@@ -0,0 +1,42 @@
+#ifndef _ASMARM_SHMBUF_H
+#define _ASMARM_SHMBUF_H
+
+/*
+ * The shmid64_ds structure for arm architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm; /* operation perms */
+ size_t shm_segsz; /* size of segment (bytes) */
+ __kernel_time_t shm_atime; /* last attach time */
+ unsigned long __unused1;
+ __kernel_time_t shm_dtime; /* last detach time */
+ unsigned long __unused2;
+ __kernel_time_t shm_ctime; /* last change time */
+ unsigned long __unused3;
+ __kernel_pid_t shm_cpid; /* pid of creator */
+ __kernel_pid_t shm_lpid; /* pid of last operator */
+ unsigned long shm_nattch; /* no. of current attaches */
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif /* _ASMARM_SHMBUF_H */
diff --git a/arch/arm/include/asm/shmparam.h b/arch/arm/include/asm/shmparam.h
new file mode 100644
index 00000000..a5223b3a
--- /dev/null
+++ b/arch/arm/include/asm/shmparam.h
@@ -0,0 +1,16 @@
+#ifndef _ASMARM_SHMPARAM_H
+#define _ASMARM_SHMPARAM_H
+
+/*
+ * This should be the size of the virtually indexed cache/ways,
+ * or page size, whichever is greater since the cache aliases
+ * every size/ways bytes.
+ */
+#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */
+
+/*
+ * Enforce SHMLBA in shmat
+ */
+#define __ARCH_FORCE_SHMLBA
+
+#endif /* _ASMARM_SHMPARAM_H */
diff --git a/arch/arm/include/asm/sigcontext.h b/arch/arm/include/asm/sigcontext.h
new file mode 100644
index 00000000..fc0b80b6
--- /dev/null
+++ b/arch/arm/include/asm/sigcontext.h
@@ -0,0 +1,34 @@
+#ifndef _ASMARM_SIGCONTEXT_H
+#define _ASMARM_SIGCONTEXT_H
+
+/*
+ * Signal context structure - contains all info to do with the state
+ * before the signal handler was invoked. Note: only add new entries
+ * to the end of the structure.
+ */
+struct sigcontext {
+ unsigned long trap_no;
+ unsigned long error_code;
+ unsigned long oldmask;
+ unsigned long arm_r0;
+ unsigned long arm_r1;
+ unsigned long arm_r2;
+ unsigned long arm_r3;
+ unsigned long arm_r4;
+ unsigned long arm_r5;
+ unsigned long arm_r6;
+ unsigned long arm_r7;
+ unsigned long arm_r8;
+ unsigned long arm_r9;
+ unsigned long arm_r10;
+ unsigned long arm_fp;
+ unsigned long arm_ip;
+ unsigned long arm_sp;
+ unsigned long arm_lr;
+ unsigned long arm_pc;
+ unsigned long arm_cpsr;
+ unsigned long fault_address;
+};
+
+
+#endif
diff --git a/arch/arm/include/asm/siginfo.h b/arch/arm/include/asm/siginfo.h
new file mode 100644
index 00000000..5e21852e
--- /dev/null
+++ b/arch/arm/include/asm/siginfo.h
@@ -0,0 +1,6 @@
+#ifndef _ASMARM_SIGINFO_H
+#define _ASMARM_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif
diff --git a/arch/arm/include/asm/signal.h b/arch/arm/include/asm/signal.h
new file mode 100644
index 00000000..43ba0fb1
--- /dev/null
+++ b/arch/arm/include/asm/signal.h
@@ -0,0 +1,164 @@
+#ifndef _ASMARM_SIGNAL_H
+#define _ASMARM_SIGNAL_H
+
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems. */
+struct siginfo;
+
+#ifdef __KERNEL__
+/* Most things should be clean enough to redefine this at will, if care
+ is taken to make libc match. */
+
+#define _NSIG 64
+#define _NSIG_BPW 32
+#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t; /* at least 32 bits */
+
+typedef struct {
+ unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+/*
+#define SIGLOST 29
+*/
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+/* These should not be considered constants from userland. */
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+#define SIGSWI 32
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_SIGINFO deliver the signal with SIGINFO structs
+ * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task
+ * is running in 26-bit.
+ * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)).
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_THIRTYTWO 0x02000000
+#define SA_RESTORER 0x04000000
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifdef __KERNEL__
+struct old_sigaction {
+ __sighandler_t sa_handler;
+ old_sigset_t sa_mask;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+};
+
+struct sigaction {
+ __sighandler_t sa_handler;
+ unsigned long sa_flags;
+ __sigrestore_t sa_restorer;
+ sigset_t sa_mask; /* mask last for extensibility */
+};
+
+struct k_sigaction {
+ struct sigaction sa;
+};
+
+#else
+/* Here we must cater to libcs that poke about in kernel headers. */
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h
new file mode 100644
index 00000000..154b89b8
--- /dev/null
+++ b/arch/arm/include/asm/sizes.h
@@ -0,0 +1,21 @@
+/*
+ * 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
+ */
+/* Size definitions
+ * Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+#include <asm-generic/sizes.h>
+
+#define SZ_48M (SZ_32M + SZ_16M)
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
new file mode 100644
index 00000000..74f288f4
--- /dev/null
+++ b/arch/arm/include/asm/smp.h
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/include/asm/smp.h
+ *
+ * Copyright (C) 2004-2005 ARM 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 __ASM_ARM_SMP_H
+#define __ASM_ARM_SMP_H
+
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/thread_info.h>
+
+#ifndef CONFIG_SMP
+# error "<asm/smp.h> included in non-SMP build"
+#endif
+
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+
+struct seq_file;
+
+/*
+ * generate IPI list text
+ */
+extern void show_ipi_list(struct seq_file *, int);
+
+/*
+ * Called from assembly code, this handles an IPI.
+ */
+asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
+
+/*
+ * Setup the set of possible CPUs (via set_cpu_possible)
+ */
+extern void smp_init_cpus(void);
+
+
+/*
+ * Provide a function to raise an IPI cross call on CPUs in callmap.
+ */
+extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
+
+/*
+ * Boot a secondary CPU, and assign it the specified idle task.
+ * This also gives us the initial stack to use for this CPU.
+ */
+extern int boot_secondary(unsigned int cpu, struct task_struct *);
+
+/*
+ * Called from platform specific assembly code, this is the
+ * secondary CPU entry point.
+ */
+asmlinkage void secondary_start_kernel(void);
+
+/*
+ * Perform platform specific initialisation of the specified CPU.
+ */
+extern void platform_secondary_init(unsigned int cpu);
+
+/*
+ * Initialize cpu_possible map, and enable coherency
+ */
+extern void platform_smp_prepare_cpus(unsigned int);
+
+/*
+ * Initial data for bringing up a secondary CPU.
+ */
+struct secondary_data {
+ unsigned long pgdir;
+ unsigned long swapper_pg_dir;
+ void *stack;
+};
+extern struct secondary_data secondary_data;
+
+extern int __cpu_disable(void);
+extern int platform_cpu_disable(unsigned int cpu);
+
+extern void __cpu_die(unsigned int cpu);
+extern void cpu_die(void);
+
+extern void platform_cpu_die(unsigned int cpu);
+extern int platform_cpu_kill(unsigned int cpu);
+extern void platform_cpu_enable(unsigned int cpu);
+
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
+
+/*
+ * show local interrupt info
+ */
+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/smp_plat.h b/arch/arm/include/asm/smp_plat.h
new file mode 100644
index 00000000..f24c1b9e
--- /dev/null
+++ b/arch/arm/include/asm/smp_plat.h
@@ -0,0 +1,46 @@
+/*
+ * ARM specific SMP header, this contains our implementation
+ * details.
+ */
+#ifndef __ASMARM_SMP_PLAT_H
+#define __ASMARM_SMP_PLAT_H
+
+#include <asm/cputype.h>
+
+/*
+ * Return true if we are running on a SMP platform
+ */
+static inline bool is_smp(void)
+{
+#ifndef CONFIG_SMP
+ return false;
+#elif defined(CONFIG_SMP_ON_UP)
+ extern unsigned int smp_on_up;
+ return !!smp_on_up;
+#else
+ return true;
+#endif
+}
+
+/* all SMP configurations have the extended CPUID registers */
+static inline int tlb_ops_need_broadcast(void)
+{
+ if (!is_smp())
+ return 0;
+
+ return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
+}
+
+#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
+#define cache_ops_need_broadcast() 0
+#else
+static inline int cache_ops_need_broadcast(void)
+{
+ if (!is_smp())
+ return 0;
+
+ return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/smp_scu.h b/arch/arm/include/asm/smp_scu.h
new file mode 100644
index 00000000..4eb6d005
--- /dev/null
+++ b/arch/arm/include/asm/smp_scu.h
@@ -0,0 +1,14 @@
+#ifndef __ASMARM_ARCH_SCU_H
+#define __ASMARM_ARCH_SCU_H
+
+#define SCU_PM_NORMAL 0
+#define SCU_PM_DORMANT 2
+#define SCU_PM_POWEROFF 3
+
+#ifndef __ASSEMBLER__
+unsigned int scu_get_core_count(void __iomem *);
+void scu_enable(void __iomem *);
+int scu_power_mode(void __iomem *, unsigned int);
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
new file mode 100644
index 00000000..fed9981f
--- /dev/null
+++ b/arch/arm/include/asm/smp_twd.h
@@ -0,0 +1,28 @@
+#ifndef __ASMARM_SMP_TWD_H
+#define __ASMARM_SMP_TWD_H
+
+#define TWD_TIMER_LOAD 0x00
+#define TWD_TIMER_COUNTER 0x04
+#define TWD_TIMER_CONTROL 0x08
+#define TWD_TIMER_INTSTAT 0x0C
+
+#define TWD_WDOG_LOAD 0x20
+#define TWD_WDOG_COUNTER 0x24
+#define TWD_WDOG_CONTROL 0x28
+#define TWD_WDOG_INTSTAT 0x2C
+#define TWD_WDOG_RESETSTAT 0x30
+#define TWD_WDOG_DISABLE 0x34
+
+#define TWD_TIMER_CONTROL_ENABLE (1 << 0)
+#define TWD_TIMER_CONTROL_ONESHOT (0 << 1)
+#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
+#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
+
+struct clock_event_device;
+
+extern void __iomem *twd_base;
+
+int twd_timer_ack(void);
+void twd_timer_setup(struct clock_event_device *);
+
+#endif
diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h
new file mode 100644
index 00000000..90ffd04b
--- /dev/null
+++ b/arch/arm/include/asm/socket.h
@@ -0,0 +1,65 @@
+#ifndef _ASMARM_SOCKET_H
+#define _ASMARM_SOCKET_H
+
+#include <asm/sockios.h>
+
+/* For setsockopt(2) */
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+/* To add :#define SO_REUSEPORT 15 */
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+/* Security levels - as per NRL IPv6 - don't actually do anything */
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+/* Socket filtering */
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_ACCEPTCONN 30
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+#define SO_TIMESTAMPNS 35
+#define SCM_TIMESTAMPNS SO_TIMESTAMPNS
+
+#define SO_MARK 36
+
+#define SO_TIMESTAMPING 37
+#define SCM_TIMESTAMPING SO_TIMESTAMPING
+
+#define SO_PROTOCOL 38
+#define SO_DOMAIN 39
+
+#define SO_RXQ_OVFL 40
+
+#endif /* _ASM_SOCKET_H */
diff --git a/arch/arm/include/asm/sockios.h b/arch/arm/include/asm/sockios.h
new file mode 100644
index 00000000..a2588a25
--- /dev/null
+++ b/arch/arm/include/asm/sockios.h
@@ -0,0 +1,13 @@
+#ifndef __ARCH_ARM_SOCKIOS_H
+#define __ARCH_ARM_SOCKIOS_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */
+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */
+
+#endif
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h
new file mode 100644
index 00000000..00098615
--- /dev/null
+++ b/arch/arm/include/asm/sparsemem.h
@@ -0,0 +1,24 @@
+#ifndef ASMARM_SPARSEMEM_H
+#define ASMARM_SPARSEMEM_H
+
+#include <asm/memory.h>
+
+/*
+ * Two definitions are required for sparsemem:
+ *
+ * MAX_PHYSMEM_BITS: The number of physical address bits required
+ * to address the last byte of memory.
+ *
+ * SECTION_SIZE_BITS: The number of physical address bits to cover
+ * the maximum amount of memory in a section.
+ *
+ * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000,
+ * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26.
+ *
+ * Define these in your mach/memory.h.
+ */
+#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS)
+#error Sparsemem is not supported on this platform
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
new file mode 100644
index 00000000..65fa3c88
--- /dev/null
+++ b/arch/arm/include/asm/spinlock.h
@@ -0,0 +1,268 @@
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#if __LINUX_ARM_ARCH__ < 6
+#error SMP not supported on pre-ARMv6 CPUs
+#endif
+
+#include <asm/processor.h>
+
+/*
+ * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K
+ * extensions, so when running on UP, we have to patch these instructions away.
+ */
+#define ALT_SMP(smp, up) \
+ "9998: " smp "\n" \
+ " .pushsection \".alt.smp.init\", \"a\"\n" \
+ " .long 9998b\n" \
+ " " up "\n" \
+ " .popsection\n"
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define SEV ALT_SMP("sev.w", "nop.w")
+/*
+ * For Thumb-2, special care is needed to ensure that the conditional WFE
+ * instruction really does assemble to exactly 4 bytes (as required by
+ * the SMP_ON_UP fixup code). By itself "wfene" might cause the
+ * assembler to insert a extra (16-bit) IT instruction, depending on the
+ * presence or absence of neighbouring conditional instructions.
+ *
+ * To avoid this unpredictableness, an approprite IT is inserted explicitly:
+ * the assembler won't change IT instructions which are explicitly present
+ * in the input.
+ */
+#define WFE(cond) ALT_SMP( \
+ "it " cond "\n\t" \
+ "wfe" cond ".n", \
+ \
+ "nop.w" \
+)
+#else
+#define SEV ALT_SMP("sev", "nop")
+#define WFE(cond) ALT_SMP("wfe" cond, "nop")
+#endif
+
+static inline void dsb_sev(void)
+{
+#if __LINUX_ARM_ARCH__ >= 7
+ __asm__ __volatile__ (
+ "dsb\n"
+ SEV
+ );
+#else
+ __asm__ __volatile__ (
+ "mcr p15, 0, %0, c7, c10, 4\n"
+ SEV
+ : : "r" (0)
+ );
+#endif
+}
+
+/*
+ * ARMv6 Spin-locking.
+ *
+ * We exclusively read the old value. If it is zero, we may have
+ * won the lock, so we try exclusively storing it. A memory barrier
+ * is required after we get a lock, and before we release it, because
+ * V6 CPUs are assumed to have weakly ordered memory.
+ *
+ * Unlocked value: 0
+ * Locked value: 1
+ */
+
+#define arch_spin_is_locked(x) ((x)->lock != 0)
+#define arch_spin_unlock_wait(lock) \
+ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
+
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%1]\n"
+" teq %0, #0\n"
+ WFE("ne")
+" strexeq %0, %2, [%1]\n"
+" teqeq %0, #0\n"
+" bne 1b"
+ : "=&r" (tmp)
+ : "r" (&lock->lock), "r" (1)
+ : "cc");
+
+ smp_mb();
+}
+
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+" ldrex %0, [%1]\n"
+" teq %0, #0\n"
+" strexeq %0, %2, [%1]"
+ : "=&r" (tmp)
+ : "r" (&lock->lock), "r" (1)
+ : "cc");
+
+ if (tmp == 0) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ smp_mb();
+
+ __asm__ __volatile__(
+" str %1, [%0]\n"
+ :
+ : "r" (&lock->lock), "r" (0)
+ : "cc");
+
+ dsb_sev();
+}
+
+/*
+ * RWLOCKS
+ *
+ *
+ * Write locks are easy - we just set bit 31. When unlocking, we can
+ * just write zero since the lock is exclusively held.
+ */
+
+static inline void arch_write_lock(arch_rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%1]\n"
+" teq %0, #0\n"
+ WFE("ne")
+" strexeq %0, %2, [%1]\n"
+" teq %0, #0\n"
+" bne 1b"
+ : "=&r" (tmp)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc");
+
+ smp_mb();
+}
+
+static inline int arch_write_trylock(arch_rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%1]\n"
+" teq %0, #0\n"
+" strexeq %0, %2, [%1]"
+ : "=&r" (tmp)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc");
+
+ if (tmp == 0) {
+ smp_mb();
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline void arch_write_unlock(arch_rwlock_t *rw)
+{
+ smp_mb();
+
+ __asm__ __volatile__(
+ "str %1, [%0]\n"
+ :
+ : "r" (&rw->lock), "r" (0)
+ : "cc");
+
+ dsb_sev();
+}
+
+/* write_can_lock - would write_trylock() succeed? */
+#define arch_write_can_lock(x) ((x)->lock == 0)
+
+/*
+ * Read locks are a bit more hairy:
+ * - Exclusively load the lock value.
+ * - Increment it.
+ * - Store new lock value if positive, and we still own this location.
+ * If the value is negative, we've already failed.
+ * - If we failed to store the value, we want a negative result.
+ * - If we failed, try again.
+ * Unlocking is similarly hairy. We may have multiple read locks
+ * currently active. However, we know we won't have any write
+ * locks.
+ */
+static inline void arch_read_lock(arch_rwlock_t *rw)
+{
+ unsigned long tmp, tmp2;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%2]\n"
+" adds %0, %0, #1\n"
+" strexpl %1, %0, [%2]\n"
+ WFE("mi")
+" rsbpls %0, %1, #0\n"
+" bmi 1b"
+ : "=&r" (tmp), "=&r" (tmp2)
+ : "r" (&rw->lock)
+ : "cc");
+
+ smp_mb();
+}
+
+static inline void arch_read_unlock(arch_rwlock_t *rw)
+{
+ unsigned long tmp, tmp2;
+
+ smp_mb();
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%2]\n"
+" sub %0, %0, #1\n"
+" strex %1, %0, [%2]\n"
+" teq %1, #0\n"
+" bne 1b"
+ : "=&r" (tmp), "=&r" (tmp2)
+ : "r" (&rw->lock)
+ : "cc");
+
+ if (tmp == 0)
+ dsb_sev();
+}
+
+static inline int arch_read_trylock(arch_rwlock_t *rw)
+{
+ unsigned long tmp, tmp2 = 1;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%2]\n"
+" adds %0, %0, #1\n"
+" strexpl %1, %0, [%2]\n"
+ : "=&r" (tmp), "+r" (tmp2)
+ : "r" (&rw->lock)
+ : "cc");
+
+ smp_mb();
+ return tmp2 == 0;
+}
+
+/* read_can_lock - would read_trylock() succeed? */
+#define arch_read_can_lock(x) ((x)->lock < 0x80000000)
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#define arch_spin_relax(lock) cpu_relax()
+#define arch_read_relax(lock) cpu_relax()
+#define arch_write_relax(lock) cpu_relax()
+
+#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/arm/include/asm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h
new file mode 100644
index 00000000..d14d197a
--- /dev/null
+++ b/arch/arm/include/asm/spinlock_types.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
new file mode 100644
index 00000000..de003327
--- /dev/null
+++ b/arch/arm/include/asm/stackprotector.h
@@ -0,0 +1,38 @@
+/*
+ * GCC stack protector support.
+ *
+ * Stack protector works by putting predefined pattern at the start of
+ * the stack frame and verifying that it hasn't been overwritten when
+ * returning from the function. The pattern is called stack canary
+ * and gcc expects it to be defined by a global variable called
+ * "__stack_chk_guard" on ARM. This unfortunately means that on SMP
+ * we cannot have a different canary value per task.
+ */
+
+#ifndef _ASM_STACKPROTECTOR_H
+#define _ASM_STACKPROTECTOR_H 1
+
+#include <linux/random.h>
+#include <linux/version.h>
+
+extern unsigned long __stack_chk_guard;
+
+/*
+ * Initialize the stackprotector canary value.
+ *
+ * NOTE: this must only be called from functions that never return,
+ * and it must always be inlined.
+ */
+static __always_inline void boot_init_stack_canary(void)
+{
+ unsigned long canary;
+
+ /* Try to get a semi random initial value. */
+ get_random_bytes(&canary, sizeof(canary));
+ canary ^= LINUX_VERSION_CODE;
+
+ current->stack_canary = canary;
+ __stack_chk_guard = current->stack_canary;
+}
+
+#endif /* _ASM_STACKPROTECTOR_H */
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
new file mode 100644
index 00000000..4d0a1644
--- /dev/null
+++ b/arch/arm/include/asm/stacktrace.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_STACKTRACE_H
+#define __ASM_STACKTRACE_H
+
+struct stackframe {
+ unsigned long fp;
+ unsigned long sp;
+ unsigned long lr;
+ unsigned long pc;
+};
+
+extern int unwind_frame(struct stackframe *frame);
+extern void walk_stackframe(struct stackframe *frame,
+ int (*fn)(struct stackframe *, void *), void *data);
+
+#endif /* __ASM_STACKTRACE_H */
diff --git a/arch/arm/include/asm/stat.h b/arch/arm/include/asm/stat.h
new file mode 100644
index 00000000..42c0c139
--- /dev/null
+++ b/arch/arm/include/asm/stat.h
@@ -0,0 +1,87 @@
+#ifndef _ASMARM_STAT_H
+#define _ASMARM_STAT_H
+
+struct __old_kernel_stat {
+ unsigned short st_dev;
+ unsigned short st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned long st_size;
+ unsigned long st_atime;
+ unsigned long st_mtime;
+ unsigned long st_ctime;
+};
+
+#define STAT_HAVE_NSEC
+
+struct stat {
+#if defined(__ARMEB__)
+ unsigned short st_dev;
+ unsigned short __pad1;
+#else
+ unsigned long st_dev;
+#endif
+ unsigned long st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+#if defined(__ARMEB__)
+ unsigned short st_rdev;
+ unsigned short __pad2;
+#else
+ unsigned long st_rdev;
+#endif
+ unsigned long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ * Note: The kernel zero's the padded region because glibc might read them
+ * in the hope that the kernel has stretched to using larger sizes.
+ */
+struct stat64 {
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
+#define STAT64_HAS_BROKEN_ST_INO 1
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+};
+
+#endif
diff --git a/arch/arm/include/asm/statfs.h b/arch/arm/include/asm/statfs.h
new file mode 100644
index 00000000..079447c0
--- /dev/null
+++ b/arch/arm/include/asm/statfs.h
@@ -0,0 +1,12 @@
+#ifndef _ASMARM_STATFS_H
+#define _ASMARM_STATFS_H
+
+/*
+ * With EABI there is 4 bytes of padding added to this structure.
+ * Let's pack it so the padding goes away to simplify dual ABI support.
+ * Note that user space does NOT have to pack this structure.
+ */
+#define ARCH_PACK_STATFS64 __attribute__((packed,aligned(4)))
+
+#include <asm-generic/statfs.h>
+#endif
diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
new file mode 100644
index 00000000..cf4f3aad
--- /dev/null
+++ b/arch/arm/include/asm/string.h
@@ -0,0 +1,41 @@
+#ifndef __ASM_ARM_STRING_H
+#define __ASM_ARM_STRING_H
+
+/*
+ * We don't do inline string functions, since the
+ * optimised inline asm versions are not small.
+ */
+
+#define __HAVE_ARCH_STRRCHR
+extern char * strrchr(const char * s, int c);
+
+#define __HAVE_ARCH_STRCHR
+extern char * strchr(const char * s, int c);
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void * memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCHR
+extern void * memchr(const void *, int, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void *, int, __kernel_size_t);
+
+extern void __memzero(void *ptr, __kernel_size_t n);
+
+#define memset(p,v,n) \
+ ({ \
+ void *__p = (p); size_t __n = n; \
+ if ((__n) != 0) { \
+ if (__builtin_constant_p((v)) && (v) == 0) \
+ __memzero((__p),(__n)); \
+ else \
+ memset((__p),(v),(__n)); \
+ } \
+ (__p); \
+ })
+
+#endif
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
new file mode 100644
index 00000000..9997ad20
--- /dev/null
+++ b/arch/arm/include/asm/swab.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/include/asm/byteorder.h
+ *
+ * ARM Endian-ness. In little endian mode, the data bus is connected such
+ * that byte accesses appear as:
+ * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ *
+ * When in big endian mode, byte accesses appear as:
+ * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7
+ * and word accesses (data or instruction) appear as:
+ * d0...d31
+ */
+#ifndef __ASM_ARM_SWAB_H
+#define __ASM_ARM_SWAB_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
+# define __SWAB_64_THRU_32__
+#endif
+
+#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6
+
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
+{
+ __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+#define __arch_swab16 __arch_swab16
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+ __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#else
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+ __u32 t;
+
+#ifndef __thumb__
+ if (!__builtin_constant_p(x)) {
+ /*
+ * The compiler needs a bit of a hint here to always do the
+ * right thing and not screw it up to different degrees
+ * depending on the gcc version.
+ */
+ asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
+ } else
+#endif
+ t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */
+
+ x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */
+ t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */
+ x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */
+
+ return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
new file mode 100644
index 00000000..832888d0
--- /dev/null
+++ b/arch/arm/include/asm/system.h
@@ -0,0 +1,542 @@
+#ifndef __ASM_ARM_SYSTEM_H
+#define __ASM_ARM_SYSTEM_H
+
+#ifdef __KERNEL__
+
+#define CPU_ARCH_UNKNOWN 0
+#define CPU_ARCH_ARMv3 1
+#define CPU_ARCH_ARMv4 2
+#define CPU_ARCH_ARMv4T 3
+#define CPU_ARCH_ARMv5 4
+#define CPU_ARCH_ARMv5T 5
+#define CPU_ARCH_ARMv5TE 6
+#define CPU_ARCH_ARMv5TEJ 7
+#define CPU_ARCH_ARMv6 8
+#define CPU_ARCH_ARMv7 9
+
+/*
+ * CR1 bits (CP#15 CR1)
+ */
+#define CR_M (1 << 0) /* MMU enable */
+#define CR_A (1 << 1) /* Alignment abort enable */
+#define CR_C (1 << 2) /* Dcache enable */
+#define CR_W (1 << 3) /* Write buffer enable */
+#define CR_P (1 << 4) /* 32-bit exception handler */
+#define CR_D (1 << 5) /* 32-bit data address range */
+#define CR_L (1 << 6) /* Implementation defined */
+#define CR_B (1 << 7) /* Big endian */
+#define CR_S (1 << 8) /* System MMU protection */
+#define CR_R (1 << 9) /* ROM MMU protection */
+#define CR_F (1 << 10) /* Implementation defined */
+#define CR_Z (1 << 11) /* Implementation defined */
+#define CR_I (1 << 12) /* Icache enable */
+#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
+#define CR_RR (1 << 14) /* Round Robin cache replacement */
+#define CR_L4 (1 << 15) /* LDR pc can set T bit */
+#define CR_DT (1 << 16)
+#define CR_IT (1 << 18)
+#define CR_ST (1 << 19)
+#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */
+#define CR_U (1 << 22) /* Unaligned access operation */
+#define CR_XP (1 << 23) /* Extended page tables */
+#define CR_VE (1 << 24) /* Vectored interrupts */
+#define CR_EE (1 << 25) /* Exception (Big) Endian */
+#define CR_TRE (1 << 28) /* TEX remap enable */
+#define CR_AFE (1 << 29) /* Access flag enable */
+#define CR_TE (1 << 30) /* Thumb exception enable */
+
+/*
+ * This is used to ensure the compiler did actually allocate the register we
+ * asked it for some inline assembly sequences. Apparently we can't trust
+ * the compiler from one version to another so a bit of paranoia won't hurt.
+ * This string is meant to be concatenated with the inline asm string and
+ * will cause compilation to stop on mismatch.
+ * (for details, see gcc PR 15089)
+ */
+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/irqflags.h>
+
+#include <asm/outercache.h>
+
+#define __exception __attribute__((section(".exception.text")))
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+#define __exception_irq_entry __irq_entry
+#else
+#define __exception_irq_entry __exception
+#endif
+
+struct thread_info;
+struct task_struct;
+
+/* information about the system we're running on */
+extern unsigned int system_rev;
+extern unsigned int system_serial_low;
+extern unsigned int system_serial_high;
+extern unsigned int mem_fclk_21285;
+
+struct pt_regs;
+
+void die(const char *msg, struct pt_regs *regs, int err);
+
+struct siginfo;
+void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
+ unsigned long err, unsigned long trap);
+
+void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
+ struct pt_regs *),
+ int sig, int code, const char *name);
+
+void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
+ struct pt_regs *),
+ int sig, int code, const char *name);
+
+#define xchg(ptr,x) \
+ ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+extern asmlinkage void __backtrace(void);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+
+struct mm_struct;
+extern void show_pte(struct mm_struct *mm, unsigned long addr);
+extern void __show_regs(struct pt_regs *);
+
+extern int cpu_architecture(void);
+extern void cpu_init(void);
+
+void arm_machine_restart(char mode, const char *cmd);
+extern void (*arm_pm_restart)(char str, const char *cmd);
+
+#define UDBG_UNDEFINED (1 << 0)
+#define UDBG_SYSCALL (1 << 1)
+#define UDBG_BADABORT (1 << 2)
+#define UDBG_SEGV (1 << 3)
+#define UDBG_BUS (1 << 4)
+
+extern unsigned int user_debug;
+
+#if __LINUX_ARM_ARCH__ >= 4
+#define vectors_high() (cr_alignment & CR_V)
+#else
+#define vectors_high() (0)
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7 || \
+ (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
+#define sev() __asm__ __volatile__ ("sev" : : : "memory")
+#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
+#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#endif
+
+#if __LINUX_ARM_ARCH__ >= 7
+#define isb() __asm__ __volatile__ ("isb" : : : "memory")
+#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
+#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
+#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+ : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+ : : "r" (0) : "memory")
+#elif defined(CONFIG_CPU_FA526)
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+ : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+#else
+#define isb() __asm__ __volatile__ ("" : : : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+ : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("" : : : "memory")
+#endif
+
+#ifdef CONFIG_ARCH_HAS_BARRIERS
+#include <mach/barriers.h>
+#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
+#define mb() do { dsb(); outer_sync(); } while (0)
+#define rmb() dsb()
+#define wmb() mb()
+#else
+#include <asm/memory.h>
+#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#endif
+
+#ifndef CONFIG_SMP
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#else
+#define smp_mb() dmb()
+#define smp_rmb() dmb()
+#define smp_wmb() dmb()
+#endif
+
+#define read_barrier_depends() do { } while(0)
+#define smp_read_barrier_depends() do { } while(0)
+
+#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
+extern unsigned long cr_alignment; /* defined in entry-armv.S */
+
+static inline unsigned int get_cr(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_cr(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
+ : : "r" (val) : "cc");
+ isb();
+}
+
+#ifndef CONFIG_SMP
+extern void adjust_cr(unsigned long mask, unsigned long set);
+#endif
+
+#define CPACC_FULL(n) (3 << (n * 2))
+#define CPACC_SVC(n) (1 << (n * 2))
+#define CPACC_DISABLE(n) (0 << (n * 2))
+
+static inline unsigned int get_copro_access(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
+ : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_copro_access(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
+ : : "r" (val) : "cc");
+ isb();
+}
+
+/*
+ * switch_mm() may do a full cache flush over the context switch,
+ * so enable interrupts over the context switch to avoid high
+ * latency.
+ */
+#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
+
+/*
+ * switch_to(prev, next) should switch from task `prev' to `next'
+ * `prev' will never be the same as `next'. schedule() itself
+ * contains the memory barrier to tell GCC not to cache `current'.
+ */
+extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
+
+#define switch_to(prev,next,last) \
+do { \
+ last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
+} while (0)
+
+#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
+/*
+ * On the StrongARM, "swp" is terminally broken since it bypasses the
+ * cache totally. This means that the cache becomes inconsistent, and,
+ * since we use normal loads/stores as well, this is really bad.
+ * Typically, this causes oopsen in filp_close, but could have other,
+ * more disastrous effects. There are two work-arounds:
+ * 1. Disable interrupts and emulate the atomic swap
+ * 2. Clean the cache, perform atomic swap, flush the cache
+ *
+ * We choose (1) since its the "easiest" to achieve here and is not
+ * dependent on the processor type.
+ *
+ * NOTE that this solution won't work on an SMP system, so explcitly
+ * forbid it here.
+ */
+#define swp_is_buggy
+#endif
+
+static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
+{
+ extern void __bad_xchg(volatile void *, int);
+ unsigned long ret;
+#ifdef swp_is_buggy
+ unsigned long flags;
+#endif
+#if __LINUX_ARM_ARCH__ >= 6
+ unsigned int tmp;
+#endif
+
+ smp_mb();
+
+ switch (size) {
+#if __LINUX_ARM_ARCH__ >= 6
+ case 1:
+ asm volatile("@ __xchg1\n"
+ "1: ldrexb %0, [%3]\n"
+ " strexb %1, %2, [%3]\n"
+ " teq %1, #0\n"
+ " bne 1b"
+ : "=&r" (ret), "=&r" (tmp)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+ case 4:
+ asm volatile("@ __xchg4\n"
+ "1: ldrex %0, [%3]\n"
+ " strex %1, %2, [%3]\n"
+ " teq %1, #0\n"
+ " bne 1b"
+ : "=&r" (ret), "=&r" (tmp)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+#elif defined(swp_is_buggy)
+#ifdef CONFIG_SMP
+#error SMP is not supported on this platform
+#endif
+ case 1:
+ raw_local_irq_save(flags);
+ ret = *(volatile unsigned char *)ptr;
+ *(volatile unsigned char *)ptr = x;
+ raw_local_irq_restore(flags);
+ break;
+
+ case 4:
+ raw_local_irq_save(flags);
+ ret = *(volatile unsigned long *)ptr;
+ *(volatile unsigned long *)ptr = x;
+ raw_local_irq_restore(flags);
+ break;
+#else
+ case 1:
+ asm volatile("@ __xchg1\n"
+ " swpb %0, %1, [%2]"
+ : "=&r" (ret)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+ case 4:
+ asm volatile("@ __xchg4\n"
+ " swp %0, %1, [%2]"
+ : "=&r" (ret)
+ : "r" (x), "r" (ptr)
+ : "memory", "cc");
+ break;
+#endif
+ default:
+ __bad_xchg(ptr, size), ret = 0;
+ break;
+ }
+ smp_mb();
+
+ return ret;
+}
+
+extern void disable_hlt(void);
+extern void enable_hlt(void);
+
+void cpu_idle_wait(void);
+
+#include <asm-generic/cmpxchg-local.h>
+
+#if __LINUX_ARM_ARCH__ < 6
+/* min ARCH < ARMv6 */
+
+#ifdef CONFIG_SMP
+#error "SMP is not supported on this platform"
+#endif
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
+ (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#ifndef CONFIG_SMP
+#include <asm-generic/cmpxchg.h>
+#endif
+
+#else /* min ARCH >= ARMv6 */
+
+extern void __bad_cmpxchg(volatile void *ptr, int size);
+
+/*
+ * cmpxchg only support 32-bits operands on ARMv6.
+ */
+
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long oldval, res;
+
+ switch (size) {
+#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
+ case 1:
+ do {
+ asm volatile("@ __cmpxchg1\n"
+ " ldrexb %1, [%2]\n"
+ " mov %0, #0\n"
+ " teq %1, %3\n"
+ " strexbeq %0, %4, [%2]\n"
+ : "=&r" (res), "=&r" (oldval)
+ : "r" (ptr), "Ir" (old), "r" (new)
+ : "memory", "cc");
+ } while (res);
+ break;
+ case 2:
+ do {
+ asm volatile("@ __cmpxchg1\n"
+ " ldrexh %1, [%2]\n"
+ " mov %0, #0\n"
+ " teq %1, %3\n"
+ " strexheq %0, %4, [%2]\n"
+ : "=&r" (res), "=&r" (oldval)
+ : "r" (ptr), "Ir" (old), "r" (new)
+ : "memory", "cc");
+ } while (res);
+ break;
+#endif
+ case 4:
+ do {
+ asm volatile("@ __cmpxchg4\n"
+ " ldrex %1, [%2]\n"
+ " mov %0, #0\n"
+ " teq %1, %3\n"
+ " strexeq %0, %4, [%2]\n"
+ : "=&r" (res), "=&r" (oldval)
+ : "r" (ptr), "Ir" (old), "r" (new)
+ : "memory", "cc");
+ } while (res);
+ break;
+ default:
+ __bad_cmpxchg(ptr, size);
+ oldval = 0;
+ }
+
+ return oldval;
+}
+
+static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long ret;
+
+ smp_mb();
+ ret = __cmpxchg(ptr, old, new, size);
+ smp_mb();
+
+ return ret;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))))
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long ret;
+
+ switch (size) {
+#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */
+ case 1:
+ case 2:
+ ret = __cmpxchg_local_generic(ptr, old, new, size);
+ break;
+#endif
+ default:
+ ret = __cmpxchg(ptr, old, new, size);
+ }
+
+ return ret;
+}
+
+#define cmpxchg_local(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))))
+
+#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
+
+/*
+ * Note : ARMv7-M (currently unsupported by Linux) does not support
+ * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
+ * not be allowed to use __cmpxchg64.
+ */
+static inline unsigned long long __cmpxchg64(volatile void *ptr,
+ unsigned long long old,
+ unsigned long long new)
+{
+ register unsigned long long oldval asm("r0");
+ register unsigned long long __old asm("r2") = old;
+ register unsigned long long __new asm("r4") = new;
+ unsigned long res;
+
+ do {
+ asm volatile(
+ " @ __cmpxchg8\n"
+ " ldrexd %1, %H1, [%2]\n"
+ " mov %0, #0\n"
+ " teq %1, %3\n"
+ " teqeq %H1, %H3\n"
+ " strexdeq %0, %4, %H4, [%2]\n"
+ : "=&r" (res), "=&r" (oldval)
+ : "r" (ptr), "Ir" (__old), "r" (__new)
+ : "memory", "cc");
+ } while (res);
+
+ return oldval;
+}
+
+static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
+ unsigned long long old,
+ unsigned long long new)
+{
+ unsigned long long ret;
+
+ smp_mb();
+ ret = __cmpxchg64(ptr, old, new);
+ smp_mb();
+
+ return ret;
+}
+
+#define cmpxchg64(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \
+ (unsigned long long)(o), \
+ (unsigned long long)(n)))
+
+#define cmpxchg64_local(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
+ (unsigned long long)(o), \
+ (unsigned long long)(n)))
+
+#else /* min ARCH = ARMv6 */
+
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#endif
+
+#endif /* __LINUX_ARM_ARCH__ >= 6 */
+
+#endif /* __ASSEMBLY__ */
+
+#define arch_align_stack(x) (x)
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/arm/include/asm/tcm.h b/arch/arm/include/asm/tcm.h
new file mode 100644
index 00000000..5929ef5d
--- /dev/null
+++ b/arch/arm/include/asm/tcm.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ *
+ */
+#ifndef __ASMARM_TCM_H
+#define __ASMARM_TCM_H
+
+#ifndef CONFIG_HAVE_TCM
+#error "You should not be including tcm.h unless you have a TCM!"
+#endif
+
+#include <linux/compiler.h>
+
+/* Tag variables with this */
+#define __tcmdata __section(.tcm.data)
+/* Tag constants with this */
+#define __tcmconst __section(.tcm.rodata)
+/* Tag functions inside TCM called from outside TCM with this */
+#define __tcmfunc __attribute__((long_call)) __section(.tcm.text) noinline
+/* Tag function inside TCM called from inside TCM with this */
+#define __tcmlocalfunc __section(.tcm.text)
+
+void *tcm_alloc(size_t len);
+void tcm_free(void *addr, size_t len);
+
+#endif
diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h
new file mode 100644
index 00000000..704135d2
--- /dev/null
+++ b/arch/arm/include/asm/termbits.h
@@ -0,0 +1,198 @@
+#ifndef __ASM_ARM_TERMBITS_H
+#define __ASM_ARM_TERMBITS_H
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+};
+
+struct termios2 {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+struct ktermios {
+ tcflag_t c_iflag; /* input mode flags */
+ tcflag_t c_oflag; /* output mode flags */
+ tcflag_t c_cflag; /* control mode flags */
+ tcflag_t c_lflag; /* local mode flags */
+ cc_t c_line; /* line discipline */
+ cc_t c_cc[NCCS]; /* control characters */
+ speed_t c_ispeed; /* input speed */
+ speed_t c_ospeed; /* output speed */
+};
+
+
+/* c_cc characters */
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+/* c_iflag bits */
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+/* c_oflag bits */
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+/* c_cflag bit meaning */
+#define CBAUD 0010017
+#define B0 0000000 /* hang up */
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define BOTHER 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000 /* input baud rate */
+#define CMSPAR 010000000000 /* mark or space (stick) parity */
+#define CRTSCTS 020000000000 /* flow control */
+
+#define IBSHIFT 16
+
+/* c_lflag bits */
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+#define EXTPROC 0200000
+
+/* tcflow() and TCXONC use these */
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+/* tcflush() and TCFLSH use these */
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+/* tcsetattr uses these */
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif /* __ASM_ARM_TERMBITS_H */
diff --git a/arch/arm/include/asm/termios.h b/arch/arm/include/asm/termios.h
new file mode 100644
index 00000000..293e3f1b
--- /dev/null
+++ b/arch/arm/include/asm/termios.h
@@ -0,0 +1,92 @@
+#ifndef __ASM_ARM_TERMIOS_H
+#define __ASM_ARM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag; /* input mode flags */
+ unsigned short c_oflag; /* output mode flags */
+ unsigned short c_cflag; /* control mode flags */
+ unsigned short c_lflag; /* local mode flags */
+ unsigned char c_line; /* line discipline */
+ unsigned char c_cc[NCC]; /* control characters */
+};
+
+#ifdef __KERNEL__
+/* intr=^C quit=^| erase=del kill=^U
+ eof=^D vtime=\0 vmin=\1 sxtc=\0
+ start=^Q stop=^S susp=^Z eol=\0
+ reprint=^R discard=^U werase=^W lnext=^V
+ eol2=\0
+*/
+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
+#endif
+
+/* modem lines */
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
+ unsigned short __tmp; \
+ get_user(__tmp,&(termio)->x); \
+ *(unsigned short *) &(termios)->x = __tmp; \
+}
+
+#define user_termio_to_kernel_termios(termios, termio) \
+({ \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
+ SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
+ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
+})
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ */
+#define kernel_termios_to_user_termio(termio, termios) \
+({ \
+ put_user((termios)->c_iflag, &(termio)->c_iflag); \
+ put_user((termios)->c_oflag, &(termio)->c_oflag); \
+ put_user((termios)->c_cflag, &(termio)->c_cflag); \
+ put_user((termios)->c_lflag, &(termio)->c_lflag); \
+ put_user((termios)->c_line, &(termio)->c_line); \
+ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
+})
+
+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2))
+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2))
+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios))
+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios))
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARM_TERMIOS_H */
diff --git a/arch/arm/include/asm/therm.h b/arch/arm/include/asm/therm.h
new file mode 100644
index 00000000..f002f019
--- /dev/null
+++ b/arch/arm/include/asm/therm.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/include/asm/therm.h: Definitions for Dallas Semiconductor
+ * DS1620 thermometer driver (as used in the Rebel.com NetWinder)
+ */
+#ifndef __ASM_THERM_H
+#define __ASM_THERM_H
+
+/* ioctl numbers for /dev/therm */
+#define CMD_SET_THERMOSTATE 0x53
+#define CMD_GET_THERMOSTATE 0x54
+#define CMD_GET_STATUS 0x56
+#define CMD_GET_TEMPERATURE 0x57
+#define CMD_SET_THERMOSTATE2 0x58
+#define CMD_GET_THERMOSTATE2 0x59
+#define CMD_GET_TEMPERATURE2 0x5a
+#define CMD_GET_FAN 0x5b
+#define CMD_SET_FAN 0x5c
+
+#define FAN_OFF 0
+#define FAN_ON 1
+#define FAN_ALWAYS_ON 2
+
+struct therm {
+ int hi;
+ int lo;
+};
+
+#endif
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
new file mode 100644
index 00000000..7b5cc8da
--- /dev/null
+++ b/arch/arm/include/asm/thread_info.h
@@ -0,0 +1,165 @@
+/*
+ * arch/arm/include/asm/thread_info.h
+ *
+ * Copyright (C) 2002 Russell King.
+ *
+ * This program is free software; you can 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_THREAD_INFO_H
+#define __ASM_ARM_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <asm/fpstate.h>
+
+#define THREAD_SIZE_ORDER 1
+#define THREAD_SIZE 8192
+#define THREAD_START_SP (THREAD_SIZE - 8)
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+struct exec_domain;
+
+#include <asm/types.h>
+#include <asm/domain.h>
+
+typedef unsigned long mm_segment_t;
+
+struct cpu_context_save {
+ __u32 r4;
+ __u32 r5;
+ __u32 r6;
+ __u32 r7;
+ __u32 r8;
+ __u32 r9;
+ __u32 sl;
+ __u32 fp;
+ __u32 sp;
+ __u32 pc;
+ __u32 extra[2]; /* Xscale 'acc' register, etc */
+};
+
+/*
+ * low level task data that entry.S needs immediate access to.
+ * __switch_to() assumes cpu_context follows immediately after cpu_domain.
+ */
+struct thread_info {
+ unsigned long flags; /* low level flags */
+ int preempt_count; /* 0 => preemptable, <0 => bug */
+ mm_segment_t addr_limit; /* address limit */
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ __u32 cpu; /* cpu */
+ __u32 cpu_domain; /* cpu domain */
+ struct cpu_context_save cpu_context; /* cpu context */
+ __u32 syscall; /* syscall number */
+ __u8 used_cp[16]; /* thread used copro */
+ unsigned long tp_value;
+ struct crunch_state crunchstate;
+ union fp_state fpstate __attribute__((aligned(8)));
+ union vfp_state vfpstate;
+#ifdef CONFIG_ARM_THUMBEE
+ unsigned long thumbee_state; /* ThumbEE Handler Base register */
+#endif
+ struct restart_block restart_block;
+};
+
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+ .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_IO, DOMAIN_CLIENT), \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+/*
+ * how to get the thread information struct from C
+ */
+static inline struct thread_info *current_thread_info(void) __attribute_const__;
+
+static inline struct thread_info *current_thread_info(void)
+{
+ register unsigned long sp asm ("sp");
+ return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
+}
+
+#define thread_saved_pc(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
+#define thread_saved_sp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.sp))
+#define thread_saved_fp(tsk) \
+ ((unsigned long)(task_thread_info(tsk)->cpu_context.fp))
+
+extern void crunch_task_disable(struct thread_info *);
+extern void crunch_task_copy(struct thread_info *, void *);
+extern void crunch_task_restore(struct thread_info *, void *);
+extern void crunch_task_release(struct thread_info *);
+
+extern void iwmmxt_task_disable(struct thread_info *);
+extern void iwmmxt_task_copy(struct thread_info *, void *);
+extern void iwmmxt_task_restore(struct thread_info *, void *);
+extern void iwmmxt_task_release(struct thread_info *);
+extern void iwmmxt_task_switch(struct thread_info *);
+
+extern void vfp_sync_hwstate(struct thread_info *);
+extern void vfp_flush_hwstate(struct thread_info *);
+
+#endif
+
+/*
+ * We use bit 30 of the preempt_count to indicate that kernel
+ * preemption is occurring. See <asm/hardirq.h>.
+ */
+#define PREEMPT_ACTIVE 0x40000000
+
+/*
+ * thread information flags:
+ * TIF_SYSCALL_TRACE - syscall trace active
+ * TIF_SIGPENDING - signal pending
+ * TIF_NEED_RESCHED - rescheduling necessary
+ * TIF_NOTIFY_RESUME - callback before returning to user
+ * TIF_USEDFPU - FPU was used by this task this quantum (SMP)
+ * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED
+ */
+#define TIF_SIGPENDING 0
+#define TIF_NEED_RESCHED 1
+#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */
+#define TIF_SYSCALL_TRACE 8
+#define TIF_POLLING_NRFLAG 16
+#define TIF_USING_IWMMXT 17
+#define TIF_MEMDIE 18 /* is terminating due to OOM killer */
+#define TIF_FREEZE 19
+#define TIF_RESTORE_SIGMASK 20
+#define TIF_SECCOMP 21
+
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
+#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SECCOMP (1 << TIF_SECCOMP)
+
+/*
+ * Change these and you break ASM code in entry-common.S
+ */
+#define _TIF_WORK_MASK 0x000000ff
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_ARM_THREAD_INFO_H */
diff --git a/arch/arm/include/asm/thread_notify.h b/arch/arm/include/asm/thread_notify.h
new file mode 100644
index 00000000..1dc98067
--- /dev/null
+++ b/arch/arm/include/asm/thread_notify.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/include/asm/thread_notify.h
+ *
+ * Copyright (C) 2006 Russell King.
+ *
+ * This program is free software; you can 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 ASMARM_THREAD_NOTIFY_H
+#define ASMARM_THREAD_NOTIFY_H
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <linux/notifier.h>
+#include <asm/thread_info.h>
+
+static inline int thread_register_notifier(struct notifier_block *n)
+{
+ extern struct atomic_notifier_head thread_notify_head;
+ return atomic_notifier_chain_register(&thread_notify_head, n);
+}
+
+static inline void thread_unregister_notifier(struct notifier_block *n)
+{
+ extern struct atomic_notifier_head thread_notify_head;
+ atomic_notifier_chain_unregister(&thread_notify_head, n);
+}
+
+static inline void thread_notify(unsigned long rc, struct thread_info *thread)
+{
+ extern struct atomic_notifier_head thread_notify_head;
+ atomic_notifier_call_chain(&thread_notify_head, rc, thread);
+}
+
+#endif
+
+/*
+ * These are the reason codes for the thread notifier.
+ */
+#define THREAD_NOTIFY_FLUSH 0
+#define THREAD_NOTIFY_EXIT 1
+#define THREAD_NOTIFY_SWITCH 2
+#define THREAD_NOTIFY_COPY 3
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h
new file mode 100644
index 00000000..3be8de3a
--- /dev/null
+++ b/arch/arm/include/asm/timex.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/include/asm/timex.h
+ *
+ * Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Architecture Specific TIME specifications
+ */
+#ifndef _ASMARM_TIMEX_H
+#define _ASMARM_TIMEX_H
+
+#include <mach/timex.h>
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles (void)
+{
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h
new file mode 100644
index 00000000..265f908c
--- /dev/null
+++ b/arch/arm/include/asm/tlb.h
@@ -0,0 +1,211 @@
+/*
+ * arch/arm/include/asm/tlb.h
+ *
+ * Copyright (C) 2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Experimentation shows that on a StrongARM, it appears to be faster
+ * to use the "invalidate whole tlb" rather than "invalidate single
+ * tlb" for this.
+ *
+ * This appears true for both the process fork+exit case, as well as
+ * the munmap-large-area case.
+ */
+#ifndef __ASMARM_TLB_H
+#define __ASMARM_TLB_H
+
+#include <asm/cacheflush.h>
+
+#ifndef CONFIG_MMU
+
+#include <linux/pagemap.h>
+
+#define tlb_flush(tlb) ((void) tlb)
+
+#include <asm-generic/tlb.h>
+
+#else /* !CONFIG_MMU */
+
+#include <linux/swap.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+/*
+ * We need to delay page freeing for SMP as other CPUs can access pages
+ * which have been removed but not yet had their TLB entries invalidated.
+ * Also, as ARMv7 speculative prefetch can drag new entries into the TLB,
+ * we need to apply this same delaying tactic to ensure correct operation.
+ */
+#if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)
+#define tlb_fast_mode(tlb) 0
+#else
+#define tlb_fast_mode(tlb) 1
+#endif
+
+#define MMU_GATHER_BUNDLE 8
+
+/*
+ * TLB handling. This allows us to remove pages from the page
+ * tables, and efficiently handle the TLB issues.
+ */
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int fullmm;
+ struct vm_area_struct *vma;
+ unsigned long range_start;
+ unsigned long range_end;
+ unsigned int nr;
+ unsigned int max;
+ struct page **pages;
+ struct page *local[MMU_GATHER_BUNDLE];
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+/*
+ * This is unnecessarily complex. There's three ways the TLB shootdown
+ * code is used:
+ * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region().
+ * tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called.
+ * tlb->vma will be non-NULL.
+ * 2. Unmapping all vmas. See exit_mmap().
+ * tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called.
+ * tlb->vma will be non-NULL. Additionally, page tables will be freed.
+ * 3. Unmapping argument pages. See shift_arg_pages().
+ * tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called.
+ * tlb->vma will be NULL.
+ */
+static inline void tlb_flush(struct mmu_gather *tlb)
+{
+ if (tlb->fullmm || !tlb->vma)
+ flush_tlb_mm(tlb->mm);
+ else if (tlb->range_end > 0) {
+ flush_tlb_range(tlb->vma, tlb->range_start, tlb->range_end);
+ tlb->range_start = TASK_SIZE;
+ tlb->range_end = 0;
+ }
+}
+
+static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr)
+{
+ if (!tlb->fullmm) {
+ if (addr < tlb->range_start)
+ tlb->range_start = addr;
+ if (addr + PAGE_SIZE > tlb->range_end)
+ tlb->range_end = addr + PAGE_SIZE;
+ }
+}
+
+static inline void __tlb_alloc_page(struct mmu_gather *tlb)
+{
+ unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
+
+ if (addr) {
+ tlb->pages = (void *)addr;
+ tlb->max = PAGE_SIZE / sizeof(struct page *);
+ }
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+ tlb_flush(tlb);
+ if (!tlb_fast_mode(tlb)) {
+ free_pages_and_swap_cache(tlb->pages, tlb->nr);
+ tlb->nr = 0;
+ if (tlb->pages == tlb->local)
+ __tlb_alloc_page(tlb);
+ }
+}
+
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
+{
+ tlb->mm = mm;
+ tlb->fullmm = fullmm;
+ tlb->vma = NULL;
+ tlb->max = ARRAY_SIZE(tlb->local);
+ tlb->pages = tlb->local;
+ tlb->nr = 0;
+ __tlb_alloc_page(tlb);
+}
+
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ tlb_flush_mmu(tlb);
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+
+ if (tlb->pages != tlb->local)
+ free_pages((unsigned long)tlb->pages, 0);
+}
+
+/*
+ * Memorize the range for the TLB flush.
+ */
+static inline void
+tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep, unsigned long addr)
+{
+ tlb_add_flush(tlb, addr);
+}
+
+/*
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush. When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
+ */
+static inline void
+tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm) {
+ flush_cache_range(vma, vma->vm_start, vma->vm_end);
+ tlb->vma = vma;
+ tlb->range_start = TASK_SIZE;
+ tlb->range_end = 0;
+ }
+}
+
+static inline void
+tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm)
+ tlb_flush(tlb);
+}
+
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ if (tlb_fast_mode(tlb)) {
+ free_page_and_swap_cache(page);
+ return 1; /* avoid calling tlb_flush_mmu */
+ }
+
+ tlb->pages[tlb->nr++] = page;
+ VM_BUG_ON(tlb->nr > tlb->max);
+ return tlb->max - tlb->nr;
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ if (!__tlb_remove_page(tlb, page))
+ tlb_flush_mmu(tlb);
+}
+
+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);
+ tlb_remove_page(tlb, pte);
+}
+
+#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
+#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+
+#define tlb_migrate_finish(mm) do { } while (0)
+
+#endif /* CONFIG_MMU */
+#endif
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
new file mode 100644
index 00000000..d2005de3
--- /dev/null
+++ b/arch/arm/include/asm/tlbflush.h
@@ -0,0 +1,587 @@
+/*
+ * arch/arm/include/asm/tlbflush.h
+ *
+ * Copyright (C) 1999-2003 Russell King
+ *
+ * This program is free software; you can 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 _ASMARM_TLBFLUSH_H
+#define _ASMARM_TLBFLUSH_H
+
+#ifdef CONFIG_MMU
+
+#include <asm/glue.h>
+
+#define TLB_V3_PAGE (1 << 0)
+#define TLB_V4_U_PAGE (1 << 1)
+#define TLB_V4_D_PAGE (1 << 2)
+#define TLB_V4_I_PAGE (1 << 3)
+#define TLB_V6_U_PAGE (1 << 4)
+#define TLB_V6_D_PAGE (1 << 5)
+#define TLB_V6_I_PAGE (1 << 6)
+
+#define TLB_V3_FULL (1 << 8)
+#define TLB_V4_U_FULL (1 << 9)
+#define TLB_V4_D_FULL (1 << 10)
+#define TLB_V4_I_FULL (1 << 11)
+#define TLB_V6_U_FULL (1 << 12)
+#define TLB_V6_D_FULL (1 << 13)
+#define TLB_V6_I_FULL (1 << 14)
+
+#define TLB_V6_U_ASID (1 << 16)
+#define TLB_V6_D_ASID (1 << 17)
+#define TLB_V6_I_ASID (1 << 18)
+
+#define TLB_BTB (1 << 28)
+
+/* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */
+#define TLB_V7_UIS_PAGE (1 << 19)
+#define TLB_V7_UIS_FULL (1 << 20)
+#define TLB_V7_UIS_ASID (1 << 21)
+
+/* Inner Shareable BTB operation (ARMv7 MP extensions) */
+#define TLB_V7_IS_BTB (1 << 22)
+
+#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */
+#define TLB_DCLEAN (1 << 30)
+#define TLB_WB (1 << 31)
+
+/*
+ * MMU TLB Model
+ * =============
+ *
+ * We have the following to choose from:
+ * v3 - ARMv3
+ * v4 - ARMv4 without write buffer
+ * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
+ * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
+ * fr - Feroceon (v4wbi with non-outer-cacheable page table walks)
+ * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB))
+ * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
+ * v7wbi - identical to v6wbi
+ */
+#undef _TLB
+#undef MULTI_TLB
+
+#ifdef CONFIG_SMP_ON_UP
+#define MULTI_TLB 1
+#endif
+
+#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
+
+#ifdef CONFIG_CPU_TLB_V3
+# define v3_possible_flags v3_tlb_flags
+# define v3_always_flags v3_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v3
+# endif
+#else
+# define v3_possible_flags 0
+# define v3_always_flags (-1UL)
+#endif
+
+#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#ifdef CONFIG_CPU_TLB_V4WT
+# define v4_possible_flags v4_tlb_flags
+# define v4_always_flags v4_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4
+# endif
+#else
+# define v4_possible_flags 0
+# define v4_always_flags (-1UL)
+#endif
+
+#define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \
+ TLB_V4_U_FULL | TLB_V4_U_PAGE)
+
+#ifdef CONFIG_CPU_TLB_FA
+# define fa_possible_flags fa_tlb_flags
+# define fa_always_flags fa_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB fa
+# endif
+#else
+# define fa_possible_flags 0
+# define fa_always_flags (-1UL)
+#endif
+
+#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+
+#ifdef CONFIG_CPU_TLB_V4WBI
+# define v4wbi_possible_flags v4wbi_tlb_flags
+# define v4wbi_always_flags v4wbi_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wbi
+# endif
+#else
+# define v4wbi_possible_flags 0
+# define v4wbi_always_flags (-1UL)
+#endif
+
+#define fr_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_L2CLEAN_FR | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_I_PAGE | TLB_V4_D_PAGE)
+
+#ifdef CONFIG_CPU_TLB_FEROCEON
+# define fr_possible_flags fr_tlb_flags
+# define fr_always_flags fr_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wbi
+# endif
+#else
+# define fr_possible_flags 0
+# define fr_always_flags (-1UL)
+#endif
+
+#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \
+ TLB_V4_I_FULL | TLB_V4_D_FULL | \
+ TLB_V4_D_PAGE)
+
+#ifdef CONFIG_CPU_TLB_V4WB
+# define v4wb_possible_flags v4wb_tlb_flags
+# define v4wb_always_flags v4wb_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v4wb
+# endif
+#else
+# define v4wb_possible_flags 0
+# define v4wb_always_flags (-1UL)
+#endif
+
+#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+ TLB_V6_I_FULL | TLB_V6_D_FULL | \
+ TLB_V6_I_PAGE | TLB_V6_D_PAGE | \
+ TLB_V6_I_ASID | TLB_V6_D_ASID)
+
+#ifdef CONFIG_CPU_TLB_V6
+# define v6wbi_possible_flags v6wbi_tlb_flags
+# define v6wbi_always_flags v6wbi_tlb_flags
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v6wbi
+# endif
+#else
+# define v6wbi_possible_flags 0
+# define v6wbi_always_flags (-1UL)
+#endif
+
+#define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
+ TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
+#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \
+ TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
+
+#ifdef CONFIG_CPU_TLB_V7
+
+# ifdef CONFIG_SMP_ON_UP
+# define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
+# define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up)
+# elif defined(CONFIG_SMP)
+# define v7wbi_possible_flags v7wbi_tlb_flags_smp
+# define v7wbi_always_flags v7wbi_tlb_flags_smp
+# else
+# define v7wbi_possible_flags v7wbi_tlb_flags_up
+# define v7wbi_always_flags v7wbi_tlb_flags_up
+# endif
+# ifdef _TLB
+# define MULTI_TLB 1
+# else
+# define _TLB v7wbi
+# endif
+#else
+# define v7wbi_possible_flags 0
+# define v7wbi_always_flags (-1UL)
+#endif
+
+#ifndef _TLB
+#error Unknown TLB model
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/sched.h>
+
+struct cpu_tlb_fns {
+ void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *);
+ void (*flush_kern_range)(unsigned long, unsigned long);
+ unsigned long tlb_flags;
+};
+
+/*
+ * Select the calling method
+ */
+#ifdef MULTI_TLB
+
+#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range
+#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range
+
+#else
+
+#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range)
+#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range)
+
+extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *);
+extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long);
+
+#endif
+
+extern struct cpu_tlb_fns cpu_tlb;
+
+#define __cpu_tlb_flags cpu_tlb.tlb_flags
+
+/*
+ * TLB Management
+ * ==============
+ *
+ * The arch/arm/mm/tlb-*.S files implement these methods.
+ *
+ * The TLB specific code is expected to perform whatever tests it
+ * needs to determine if it should invalidate the TLB for each
+ * call. Start addresses are inclusive and end addresses are
+ * exclusive; it is safe to round these addresses down.
+ *
+ * flush_tlb_all()
+ *
+ * Invalidate the entire TLB.
+ *
+ * flush_tlb_mm(mm)
+ *
+ * Invalidate all TLB entries in a particular address
+ * space.
+ * - mm - mm_struct describing address space
+ *
+ * flush_tlb_range(mm,start,end)
+ *
+ * Invalidate a range of TLB entries in the specified
+ * address space.
+ * - mm - mm_struct describing address space
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ *
+ * flush_tlb_page(vaddr,vma)
+ *
+ * Invalidate the specified page in the specified address range.
+ * - vaddr - virtual address (may not be aligned)
+ * - vma - vma_struct describing address range
+ *
+ * flush_kern_tlb_page(kaddr)
+ *
+ * Invalidate the TLB entry for the specified page. The address
+ * will be in the kernels virtual memory space. Current uses
+ * only require the D-TLB to be invalidated.
+ * - kaddr - Kernel virtual memory address
+ */
+
+/*
+ * We optimise the code below by:
+ * - building a set of TLB flags that might be set in __cpu_tlb_flags
+ * - building a set of TLB flags that will always be set in __cpu_tlb_flags
+ * - if we're going to need __cpu_tlb_flags, access it once and only once
+ *
+ * This allows us to build optimal assembly for the single-CPU type case,
+ * and as close to optimal given the compiler constrants for multi-CPU
+ * case. We could do better for the multi-CPU case if the compiler
+ * implemented the "%?" method, but this has been discontinued due to too
+ * many people getting it wrong.
+ */
+#define possible_tlb_flags (v3_possible_flags | \
+ v4_possible_flags | \
+ v4wbi_possible_flags | \
+ fr_possible_flags | \
+ v4wb_possible_flags | \
+ fa_possible_flags | \
+ v6wbi_possible_flags | \
+ v7wbi_possible_flags)
+
+#define always_tlb_flags (v3_always_flags & \
+ v4_always_flags & \
+ v4wbi_always_flags & \
+ fr_always_flags & \
+ v4wb_always_flags & \
+ fa_always_flags & \
+ v6wbi_always_flags & \
+ v7wbi_always_flags)
+
+#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
+
+static inline void local_flush_tlb_all(void)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ dsb();
+
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
+ asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
+ asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V7_UIS_FULL))
+ asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+
+ if (tlb_flag(TLB_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+ if (tlb_flag(TLB_V7_IS_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+}
+
+static inline void local_flush_tlb_mm(struct mm_struct *mm)
+{
+ const int zero = 0;
+ const int asid = ASID(mm);
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_WB))
+ dsb();
+
+ if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
+ if (tlb_flag(TLB_V3_FULL))
+ asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_U_FULL))
+ asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_D_FULL))
+ asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
+ if (tlb_flag(TLB_V4_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+ }
+ put_cpu();
+
+ if (tlb_flag(TLB_V6_U_ASID))
+ asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
+ if (tlb_flag(TLB_V6_D_ASID))
+ asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
+ if (tlb_flag(TLB_V6_I_ASID))
+ asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
+ if (tlb_flag(TLB_V7_UIS_ASID))
+#ifdef CONFIG_ARM_ERRATA_720789
+ asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
+#else
+ asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
+#endif
+
+ if (tlb_flag(TLB_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+ dsb();
+ }
+ if (tlb_flag(TLB_V7_IS_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+}
+
+static inline void
+local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
+
+ if (tlb_flag(TLB_WB))
+ dsb();
+
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+ }
+
+ if (tlb_flag(TLB_V6_U_PAGE))
+ asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V6_D_PAGE))
+ asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V6_I_PAGE))
+ asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
+ if (tlb_flag(TLB_V7_UIS_PAGE))
+#ifdef CONFIG_ARM_ERRATA_720789
+ asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
+#else
+ asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
+#endif
+
+ if (tlb_flag(TLB_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+ dsb();
+ }
+ if (tlb_flag(TLB_V7_IS_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+}
+
+static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
+{
+ const int zero = 0;
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ kaddr &= PAGE_MASK;
+
+ if (tlb_flag(TLB_WB))
+ dsb();
+
+ if (tlb_flag(TLB_V3_PAGE))
+ asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V4_U_PAGE))
+ asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V4_D_PAGE))
+ asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V4_I_PAGE))
+ asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
+ if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
+ asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
+
+ if (tlb_flag(TLB_V6_U_PAGE))
+ asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V6_D_PAGE))
+ asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V6_I_PAGE))
+ asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
+ if (tlb_flag(TLB_V7_UIS_PAGE))
+ asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
+
+ if (tlb_flag(TLB_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+ if (tlb_flag(TLB_V7_IS_BTB)) {
+ /* flush the branch target cache */
+ asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc");
+ dsb();
+ isb();
+ }
+}
+
+/*
+ * flush_pmd_entry
+ *
+ * Flush a PMD entry (word aligned, or double-word aligned) to
+ * RAM if the TLB for the CPU we are running on requires this.
+ * This is typically used when we are creating PMD entries.
+ *
+ * clean_pmd_entry
+ *
+ * Clean (but don't drain the write buffer) if the CPU requires
+ * these operations. This is typically used when we are removing
+ * PMD entries.
+ */
+static inline void flush_pmd_entry(pmd_t *pmd)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_DCLEAN))
+ asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd"
+ : : "r" (pmd) : "cc");
+
+ if (tlb_flag(TLB_L2CLEAN_FR))
+ asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
+ : : "r" (pmd) : "cc");
+
+ if (tlb_flag(TLB_WB))
+ dsb();
+}
+
+static inline void clean_pmd_entry(pmd_t *pmd)
+{
+ const unsigned int __tlb_flag = __cpu_tlb_flags;
+
+ if (tlb_flag(TLB_DCLEAN))
+ asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd"
+ : : "r" (pmd) : "cc");
+
+ if (tlb_flag(TLB_L2CLEAN_FR))
+ asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
+ : : "r" (pmd) : "cc");
+}
+
+#undef tlb_flag
+#undef always_tlb_flags
+#undef possible_tlb_flags
+
+/*
+ * Convert calls to our calling convention.
+ */
+#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma)
+#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e)
+
+#ifndef CONFIG_SMP
+#define flush_tlb_all local_flush_tlb_all
+#define flush_tlb_mm local_flush_tlb_mm
+#define flush_tlb_page local_flush_tlb_page
+#define flush_tlb_kernel_page local_flush_tlb_kernel_page
+#define flush_tlb_range local_flush_tlb_range
+#define flush_tlb_kernel_range local_flush_tlb_kernel_range
+#else
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr);
+extern void flush_tlb_kernel_page(unsigned long kaddr);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+#endif
+
+/*
+ * If PG_dcache_clean is not set for the page, we need to ensure that any
+ * cache entries for the kernels virtual memory range are written
+ * back to the page. On ARMv6 and later, the cache coherency is handled via
+ * the set_pte_at() function.
+ */
+#if __LINUX_ARM_ARCH__ < 6
+extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+ pte_t *ptep);
+#else
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+}
+#endif
+
+#endif
+
+#endif /* CONFIG_MMU */
+
+#endif
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
new file mode 100644
index 00000000..73409e6c
--- /dev/null
+++ b/arch/arm/include/asm/tls.h
@@ -0,0 +1,49 @@
+#ifndef __ASMARM_TLS_H
+#define __ASMARM_TLS_H
+
+#ifdef __ASSEMBLY__
+ .macro set_tls_none, tp, tmp1, tmp2
+ .endm
+
+ .macro set_tls_v6k, tp, tmp1, tmp2
+ mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
+ mov \tmp1, #0
+ mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
+ .endm
+
+ .macro set_tls_v6, tp, tmp1, tmp2
+ ldr \tmp1, =elf_hwcap
+ ldr \tmp1, [\tmp1, #0]
+ mov \tmp2, #0xffff0fff
+ tst \tmp1, #HWCAP_TLS @ hardware TLS available?
+ mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+ movne \tmp1, #0
+ mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
+ streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
+ .endm
+
+ .macro set_tls_software, tp, tmp1, tmp2
+ mov \tmp1, #0xffff0fff
+ str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
+ .endm
+#endif
+
+#ifdef CONFIG_TLS_REG_EMUL
+#define tls_emu 1
+#define has_tls_reg 1
+#define set_tls set_tls_none
+#elif defined(CONFIG_CPU_V6)
+#define tls_emu 0
+#define has_tls_reg (elf_hwcap & HWCAP_TLS)
+#define set_tls set_tls_v6
+#elif defined(CONFIG_CPU_32v6K)
+#define tls_emu 0
+#define has_tls_reg 1
+#define set_tls set_tls_v6k
+#else
+#define tls_emu 0
+#define has_tls_reg 0
+#define set_tls set_tls_software
+#endif
+
+#endif /* __ASMARM_TLS_H */
diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h
new file mode 100644
index 00000000..accbd7ca
--- /dev/null
+++ b/arch/arm/include/asm/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_ARM_TOPOLOGY_H
+#define _ASM_ARM_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
new file mode 100644
index 00000000..f90756dc
--- /dev/null
+++ b/arch/arm/include/asm/traps.h
@@ -0,0 +1,52 @@
+#ifndef _ASMARM_TRAP_H
+#define _ASMARM_TRAP_H
+
+#include <linux/list.h>
+
+struct undef_hook {
+ struct list_head node;
+ u32 instr_mask;
+ u32 instr_val;
+ u32 cpsr_mask;
+ u32 cpsr_val;
+ int (*fn)(struct pt_regs *regs, unsigned int instr);
+};
+
+void register_undef_hook(struct undef_hook *hook);
+void unregister_undef_hook(struct undef_hook *hook);
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+ extern char __irqentry_text_start[];
+ extern char __irqentry_text_end[];
+
+ return ptr >= (unsigned long)&__irqentry_text_start &&
+ ptr < (unsigned long)&__irqentry_text_end;
+}
+#else
+static inline int __in_irqentry_text(unsigned long ptr)
+{
+ return 0;
+}
+#endif
+
+static inline int in_exception_text(unsigned long ptr)
+{
+ extern char __exception_text_start[];
+ extern char __exception_text_end[];
+ int in;
+
+ in = ptr >= (unsigned long)&__exception_text_start &&
+ ptr < (unsigned long)&__exception_text_end;
+
+ return in ? : __in_irqentry_text(ptr);
+}
+
+extern void __init early_trap_init(void);
+extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
+extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);
+
+extern void *vectors_page;
+
+#endif
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
new file mode 100644
index 00000000..48192ac3
--- /dev/null
+++ b/arch/arm/include/asm/types.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_ARM_TYPES_H
+#define __ASM_ARM_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+#define BITS_PER_LONG 32
+
+#endif /* __KERNEL__ */
+
+#endif
+
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
new file mode 100644
index 00000000..2958976d
--- /dev/null
+++ b/arch/arm/include/asm/uaccess.h
@@ -0,0 +1,450 @@
+/*
+ * arch/arm/include/asm/uaccess.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASMARM_UACCESS_H
+#define _ASMARM_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/string.h>
+#include <linux/thread_info.h>
+#include <asm/errno.h>
+#include <asm/memory.h>
+#include <asm/domain.h>
+#include <asm/system.h>
+#include <asm/unified.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry
+{
+ unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+/*
+ * These two are intentionally not defined anywhere - if the kernel
+ * code generates any references to them, that's a bug.
+ */
+extern int __get_user_bad(void);
+extern int __put_user_bad(void);
+
+/*
+ * Note that this is actually 0x1,0000,0000
+ */
+#define KERNEL_DS 0x00000000
+#define get_ds() (KERNEL_DS)
+
+#ifdef CONFIG_MMU
+
+#define USER_DS TASK_SIZE
+#define get_fs() (current_thread_info()->addr_limit)
+
+static inline void set_fs(mm_segment_t fs)
+{
+ current_thread_info()->addr_limit = fs;
+ modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
+}
+
+#define segment_eq(a,b) ((a) == (b))
+
+#define __addr_ok(addr) ({ \
+ unsigned long flag; \
+ __asm__("cmp %2, %0; movlo %0, #0" \
+ : "=&r" (flag) \
+ : "0" (current_thread_info()->addr_limit), "r" (addr) \
+ : "cc"); \
+ (flag == 0); })
+
+/* We use 33-bit arithmetic here... */
+#define __range_ok(addr,size) ({ \
+ unsigned long flag, roksum; \
+ __chk_user_ptr(addr); \
+ __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
+ : "=&r" (flag), "=&r" (roksum) \
+ : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
+ : "cc"); \
+ flag; })
+
+/*
+ * Single-value transfer routines. They automatically use the right
+ * size if we just have the right pointer type. Note that the functions
+ * which read from user space (*get_*) need to take care not to leak
+ * kernel data even if the calling code is buggy and fails to check
+ * the return value. This means zeroing out the destination variable
+ * or buffer on error. Normally this is done out of line by the
+ * fixup code, but there are a few places where it intrudes on the
+ * main code path. When we only write to user space, there is no
+ * problem.
+ */
+extern int __get_user_1(void *);
+extern int __get_user_2(void *);
+extern int __get_user_4(void *);
+
+#define __get_user_x(__r2,__p,__e,__s,__i...) \
+ __asm__ __volatile__ ( \
+ __asmeq("%0", "r0") __asmeq("%1", "r2") \
+ "bl __get_user_" #__s \
+ : "=&r" (__e), "=r" (__r2) \
+ : "0" (__p) \
+ : __i, "cc")
+
+#define get_user(x,p) \
+ ({ \
+ register const typeof(*(p)) __user *__p asm("r0") = (p);\
+ register unsigned long __r2 asm("r2"); \
+ register int __e asm("r0"); \
+ switch (sizeof(*(__p))) { \
+ case 1: \
+ __get_user_x(__r2, __p, __e, 1, "lr"); \
+ break; \
+ case 2: \
+ __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \
+ break; \
+ case 4: \
+ __get_user_x(__r2, __p, __e, 4, "lr"); \
+ break; \
+ default: __e = __get_user_bad(); break; \
+ } \
+ x = (typeof(*(p))) __r2; \
+ __e; \
+ })
+
+extern int __put_user_1(void *, unsigned int);
+extern int __put_user_2(void *, unsigned int);
+extern int __put_user_4(void *, unsigned int);
+extern int __put_user_8(void *, unsigned long long);
+
+#define __put_user_x(__r2,__p,__e,__s) \
+ __asm__ __volatile__ ( \
+ __asmeq("%0", "r0") __asmeq("%2", "r2") \
+ "bl __put_user_" #__s \
+ : "=&r" (__e) \
+ : "0" (__p), "r" (__r2) \
+ : "ip", "lr", "cc")
+
+#define put_user(x,p) \
+ ({ \
+ register const typeof(*(p)) __r2 asm("r2") = (x); \
+ register const typeof(*(p)) __user *__p asm("r0") = (p);\
+ register int __e asm("r0"); \
+ switch (sizeof(*(__p))) { \
+ case 1: \
+ __put_user_x(__r2, __p, __e, 1); \
+ break; \
+ case 2: \
+ __put_user_x(__r2, __p, __e, 2); \
+ break; \
+ case 4: \
+ __put_user_x(__r2, __p, __e, 4); \
+ break; \
+ case 8: \
+ __put_user_x(__r2, __p, __e, 8); \
+ break; \
+ default: __e = __put_user_bad(); break; \
+ } \
+ __e; \
+ })
+
+#else /* CONFIG_MMU */
+
+/*
+ * uClinux has only one addr space, so has simplified address limits.
+ */
+#define USER_DS KERNEL_DS
+
+#define segment_eq(a,b) (1)
+#define __addr_ok(addr) (1)
+#define __range_ok(addr,size) (0)
+#define get_fs() (KERNEL_DS)
+
+static inline void set_fs(mm_segment_t fs)
+{
+}
+
+#define get_user(x,p) __get_user(x,p)
+#define put_user(x,p) __put_user(x,p)
+
+#endif /* CONFIG_MMU */
+
+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+
+/*
+ * The "__xxx" versions of the user access functions do not verify the
+ * address space - it must have been done previously with a separate
+ * "access_ok()" call.
+ *
+ * The "xxx_error" versions set the third argument to EFAULT if an
+ * error occurs, and leave it unchanged on success. Note that these
+ * versions are void (ie, don't return a value as such).
+ */
+#define __get_user(x,ptr) \
+({ \
+ long __gu_err = 0; \
+ __get_user_err((x),(ptr),__gu_err); \
+ __gu_err; \
+})
+
+#define __get_user_error(x,ptr,err) \
+({ \
+ __get_user_err((x),(ptr),err); \
+ (void) 0; \
+})
+
+#define __get_user_err(x,ptr,err) \
+do { \
+ unsigned long __gu_addr = (unsigned long)(ptr); \
+ unsigned long __gu_val; \
+ __chk_user_ptr(ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
+ case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
+ case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \
+ default: (__gu_val) = __get_user_bad(); \
+ } \
+ (x) = (__typeof__(*(ptr)))__gu_val; \
+} while (0)
+
+#define __get_user_asm_byte(x,addr,err) \
+ __asm__ __volatile__( \
+ "1: " TUSER(ldrb) " %1,[%2],#0\n" \
+ "2:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " mov %1, #0\n" \
+ " b 2b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .popsection" \
+ : "+r" (err), "=&r" (x) \
+ : "r" (addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __get_user_asm_half(x,__gu_addr,err) \
+({ \
+ unsigned long __b1, __b2; \
+ __get_user_asm_byte(__b1, __gu_addr, err); \
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
+ (x) = __b1 | (__b2 << 8); \
+})
+#else
+#define __get_user_asm_half(x,__gu_addr,err) \
+({ \
+ unsigned long __b1, __b2; \
+ __get_user_asm_byte(__b1, __gu_addr, err); \
+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
+ (x) = (__b1 << 8) | __b2; \
+})
+#endif
+
+#define __get_user_asm_word(x,addr,err) \
+ __asm__ __volatile__( \
+ "1: " TUSER(ldr) " %1,[%2],#0\n" \
+ "2:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " mov %1, #0\n" \
+ " b 2b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .popsection" \
+ : "+r" (err), "=&r" (x) \
+ : "r" (addr), "i" (-EFAULT) \
+ : "cc")
+
+#define __put_user(x,ptr) \
+({ \
+ long __pu_err = 0; \
+ __put_user_err((x),(ptr),__pu_err); \
+ __pu_err; \
+})
+
+#define __put_user_error(x,ptr,err) \
+({ \
+ __put_user_err((x),(ptr),err); \
+ (void) 0; \
+})
+
+#define __put_user_err(x,ptr,err) \
+do { \
+ unsigned long __pu_addr = (unsigned long)(ptr); \
+ __typeof__(*(ptr)) __pu_val = (x); \
+ __chk_user_ptr(ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
+ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
+ case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
+ case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
+ default: __put_user_bad(); \
+ } \
+} while (0)
+
+#define __put_user_asm_byte(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ "1: " TUSER(strb) " %1,[%2],#0\n" \
+ "2:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " b 2b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .popsection" \
+ : "+r" (err) \
+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __put_user_asm_half(x,__pu_addr,err) \
+({ \
+ unsigned long __temp = (unsigned long)(x); \
+ __put_user_asm_byte(__temp, __pu_addr, err); \
+ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
+})
+#else
+#define __put_user_asm_half(x,__pu_addr,err) \
+({ \
+ unsigned long __temp = (unsigned long)(x); \
+ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
+ __put_user_asm_byte(__temp, __pu_addr + 1, err); \
+})
+#endif
+
+#define __put_user_asm_word(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ "1: " TUSER(str) " %1,[%2],#0\n" \
+ "2:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %3\n" \
+ " b 2b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .popsection" \
+ : "+r" (err) \
+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
+ : "cc")
+
+#ifndef __ARMEB__
+#define __reg_oper0 "%R2"
+#define __reg_oper1 "%Q2"
+#else
+#define __reg_oper0 "%Q2"
+#define __reg_oper1 "%R2"
+#endif
+
+#define __put_user_asm_dword(x,__pu_addr,err) \
+ __asm__ __volatile__( \
+ ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \
+ ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \
+ THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \
+ THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \
+ "3:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "4: mov %0, %3\n" \
+ " b 3b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 4b\n" \
+ " .long 2b, 4b\n" \
+ " .popsection" \
+ : "+r" (err), "+r" (__pu_addr) \
+ : "r" (x), "i" (-EFAULT) \
+ : "cc")
+
+
+#ifdef CONFIG_MMU
+extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
+#else
+#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
+#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
+#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0)
+#endif
+
+extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
+extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
+
+static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ if (access_ok(VERIFY_READ, from, n))
+ n = __copy_from_user(to, from, n);
+ else /* security hole - plug it */
+ memset(to, 0, n);
+ return n;
+}
+
+static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n))
+ n = __copy_to_user(to, from, n);
+ return n;
+}
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
+static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n))
+ n = __clear_user(to, n);
+ return n;
+}
+
+static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
+{
+ long res = -EFAULT;
+ if (access_ok(VERIFY_READ, src, 1))
+ res = __strncpy_from_user(dst, src, count);
+ return res;
+}
+
+#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
+
+static inline long __must_check strnlen_user(const char __user *s, long n)
+{
+ unsigned long res = 0;
+
+ if (__addr_ok(s))
+ res = __strnlen_user(s, n);
+
+ return res;
+}
+
+#endif /* _ASMARM_UACCESS_H */
diff --git a/arch/arm/include/asm/ucontext.h b/arch/arm/include/asm/ucontext.h
new file mode 100644
index 00000000..14749aec
--- /dev/null
+++ b/arch/arm/include/asm/ucontext.h
@@ -0,0 +1,102 @@
+#ifndef _ASMARM_UCONTEXT_H
+#define _ASMARM_UCONTEXT_H
+
+#include <asm/fpstate.h>
+
+/*
+ * struct sigcontext only has room for the basic registers, but struct
+ * ucontext now has room for all registers which need to be saved and
+ * restored. Coprocessor registers are stored in uc_regspace. Each
+ * coprocessor's saved state should start with a documented 32-bit magic
+ * number, followed by a 32-bit word giving the coproccesor's saved size.
+ * uc_regspace may be expanded if necessary, although this takes some
+ * coordination with glibc.
+ */
+
+struct ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask;
+ /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
+ int __unused[32 - (sizeof (sigset_t) / sizeof (int))];
+ /* Last for extensibility. Eight byte aligned because some
+ coprocessors require eight byte alignment. */
+ unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
+};
+
+#ifdef __KERNEL__
+
+/*
+ * Coprocessor save state. The magic values and specific
+ * coprocessor's layouts are part of the userspace ABI. Each one of
+ * these should be a multiple of eight bytes and aligned to eight
+ * bytes, to prevent unpredictable padding in the signal frame.
+ */
+
+#ifdef CONFIG_CRUNCH
+#define CRUNCH_MAGIC 0x5065cf03
+#define CRUNCH_STORAGE_SIZE (CRUNCH_SIZE + 8)
+
+struct crunch_sigframe {
+ unsigned long magic;
+ unsigned long size;
+ struct crunch_state storage;
+} __attribute__((__aligned__(8)));
+#endif
+
+#ifdef CONFIG_IWMMXT
+/* iwmmxt_area is 0x98 bytes long, preceded by 8 bytes of signature */
+#define IWMMXT_MAGIC 0x12ef842a
+#define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8)
+
+struct iwmmxt_sigframe {
+ unsigned long magic;
+ unsigned long size;
+ struct iwmmxt_struct storage;
+} __attribute__((__aligned__(8)));
+#endif /* CONFIG_IWMMXT */
+
+#ifdef CONFIG_VFP
+#define VFP_MAGIC 0x56465001
+
+struct vfp_sigframe
+{
+ unsigned long magic;
+ unsigned long size;
+ struct user_vfp ufp;
+ struct user_vfp_exc ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ * 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ * 4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe)
+
+#endif /* CONFIG_VFP */
+
+/*
+ * Auxiliary signal frame. This saves stuff like FP state.
+ * The layout of this structure is not part of the user ABI,
+ * because the config options aren't. uc_regspace is really
+ * one of these.
+ */
+struct aux_sigframe {
+#ifdef CONFIG_CRUNCH
+ struct crunch_sigframe crunch;
+#endif
+#ifdef CONFIG_IWMMXT
+ struct iwmmxt_sigframe iwmmxt;
+#endif
+#ifdef CONFIG_VFP
+ struct vfp_sigframe vfp;
+#endif
+ /* Something that isn't a valid magic number for any coprocessor. */
+ unsigned long end_magic;
+} __attribute__((__aligned__(8)));
+
+#endif
+
+#endif /* !_ASMARM_UCONTEXT_H */
diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h
new file mode 100644
index 00000000..44593a89
--- /dev/null
+++ b/arch/arm/include/asm/unaligned.h
@@ -0,0 +1,19 @@
+#ifndef _ASM_ARM_UNALIGNED_H
+#define _ASM_ARM_UNALIGNED_H
+
+#include <linux/unaligned/le_byteshift.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+/*
+ * Select endianness
+ */
+#ifndef __ARMEB__
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#else
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+#endif
+
+#endif /* _ASM_ARM_UNALIGNED_H */
diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h
new file mode 100644
index 00000000..bc631161
--- /dev/null
+++ b/arch/arm/include/asm/unified.h
@@ -0,0 +1,130 @@
+/*
+ * include/asm-arm/unified.h - Unified Assembler Syntax helper macros
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_UNIFIED_H
+#define __ASM_UNIFIED_H
+
+#if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED)
+ .syntax unified
+#endif
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+#if __GNUC__ < 4
+#error Thumb-2 kernel requires gcc >= 4
+#endif
+
+/* The CPSR bit describing the instruction set (Thumb) */
+#define PSR_ISETSTATE PSR_T_BIT
+
+#define ARM(x...)
+#define THUMB(x...) x
+#ifdef __ASSEMBLY__
+#define W(instr) instr.w
+#endif
+#define BSYM(sym) sym + 1
+
+#else /* !CONFIG_THUMB2_KERNEL */
+
+/* The CPSR bit describing the instruction set (ARM) */
+#define PSR_ISETSTATE 0
+
+#define ARM(x...) x
+#define THUMB(x...)
+#ifdef __ASSEMBLY__
+#define W(instr) instr
+#endif
+#define BSYM(sym) sym
+
+#endif /* CONFIG_THUMB2_KERNEL */
+
+#ifndef CONFIG_ARM_ASM_UNIFIED
+
+/*
+ * If the unified assembly syntax isn't used (in ARM mode), these
+ * macros expand to an empty string
+ */
+#ifdef __ASSEMBLY__
+ .macro it, cond
+ .endm
+ .macro itt, cond
+ .endm
+ .macro ite, cond
+ .endm
+ .macro ittt, cond
+ .endm
+ .macro itte, cond
+ .endm
+ .macro itet, cond
+ .endm
+ .macro itee, cond
+ .endm
+ .macro itttt, cond
+ .endm
+ .macro ittte, cond
+ .endm
+ .macro ittet, cond
+ .endm
+ .macro ittee, cond
+ .endm
+ .macro itett, cond
+ .endm
+ .macro itete, cond
+ .endm
+ .macro iteet, cond
+ .endm
+ .macro iteee, cond
+ .endm
+#else /* !__ASSEMBLY__ */
+__asm__(
+" .macro it, cond\n"
+" .endm\n"
+" .macro itt, cond\n"
+" .endm\n"
+" .macro ite, cond\n"
+" .endm\n"
+" .macro ittt, cond\n"
+" .endm\n"
+" .macro itte, cond\n"
+" .endm\n"
+" .macro itet, cond\n"
+" .endm\n"
+" .macro itee, cond\n"
+" .endm\n"
+" .macro itttt, cond\n"
+" .endm\n"
+" .macro ittte, cond\n"
+" .endm\n"
+" .macro ittet, cond\n"
+" .endm\n"
+" .macro ittee, cond\n"
+" .endm\n"
+" .macro itett, cond\n"
+" .endm\n"
+" .macro itete, cond\n"
+" .endm\n"
+" .macro iteet, cond\n"
+" .endm\n"
+" .macro iteee, cond\n"
+" .endm\n");
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_ARM_ASM_UNIFIED */
+
+#endif /* !__ASM_UNIFIED_H */
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
new file mode 100644
index 00000000..2c04ed5e
--- /dev/null
+++ b/arch/arm/include/asm/unistd.h
@@ -0,0 +1,485 @@
+/*
+ * arch/arm/include/asm/unistd.h
+ *
+ * Copyright (C) 2001-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk,
+ * no matter what the change is. Thanks!
+ */
+#ifndef __ASM_ARM_UNISTD_H
+#define __ASM_ARM_UNISTD_H
+
+#define __NR_OABI_SYSCALL_BASE 0x900000
+
+#if defined(__thumb__) || defined(__ARM_EABI__)
+#define __NR_SYSCALL_BASE 0
+#else
+#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#endif
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
+#define __NR_exit (__NR_SYSCALL_BASE+ 1)
+#define __NR_fork (__NR_SYSCALL_BASE+ 2)
+#define __NR_read (__NR_SYSCALL_BASE+ 3)
+#define __NR_write (__NR_SYSCALL_BASE+ 4)
+#define __NR_open (__NR_SYSCALL_BASE+ 5)
+#define __NR_close (__NR_SYSCALL_BASE+ 6)
+ /* 7 was sys_waitpid */
+#define __NR_creat (__NR_SYSCALL_BASE+ 8)
+#define __NR_link (__NR_SYSCALL_BASE+ 9)
+#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
+#define __NR_execve (__NR_SYSCALL_BASE+ 11)
+#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
+#define __NR_time (__NR_SYSCALL_BASE+ 13)
+#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
+#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
+#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
+ /* 17 was sys_break */
+ /* 18 was sys_stat */
+#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
+#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
+#define __NR_mount (__NR_SYSCALL_BASE+ 21)
+#define __NR_umount (__NR_SYSCALL_BASE+ 22)
+#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
+#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
+#define __NR_stime (__NR_SYSCALL_BASE+ 25)
+#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
+#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
+ /* 28 was sys_fstat */
+#define __NR_pause (__NR_SYSCALL_BASE+ 29)
+#define __NR_utime (__NR_SYSCALL_BASE+ 30)
+ /* 31 was sys_stty */
+ /* 32 was sys_gtty */
+#define __NR_access (__NR_SYSCALL_BASE+ 33)
+#define __NR_nice (__NR_SYSCALL_BASE+ 34)
+ /* 35 was sys_ftime */
+#define __NR_sync (__NR_SYSCALL_BASE+ 36)
+#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+#define __NR_rename (__NR_SYSCALL_BASE+ 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
+#define __NR_dup (__NR_SYSCALL_BASE+ 41)
+#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
+#define __NR_times (__NR_SYSCALL_BASE+ 43)
+ /* 44 was sys_prof */
+#define __NR_brk (__NR_SYSCALL_BASE+ 45)
+#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
+#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
+ /* 48 was sys_signal */
+#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
+#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
+#define __NR_acct (__NR_SYSCALL_BASE+ 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
+ /* 53 was sys_lock */
+#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
+ /* 56 was sys_mpx */
+#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
+ /* 58 was sys_ulimit */
+ /* 59 was sys_olduname */
+#define __NR_umask (__NR_SYSCALL_BASE+ 60)
+#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
+#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
+#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
+#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
+ /* 68 was sys_sgetmask */
+ /* 69 was sys_ssetmask */
+#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
+#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
+#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */
+#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
+#define __NR_select (__NR_SYSCALL_BASE+ 82)
+#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
+ /* 84 was sys_lstat */
+#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
+#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
+#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
+#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
+#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
+#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
+#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
+#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
+#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
+ /* 98 was sys_profil */
+#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
+ /* 101 was sys_ioperm */
+#define __NR_socketcall (__NR_SYSCALL_BASE+102)
+#define __NR_syslog (__NR_SYSCALL_BASE+103)
+#define __NR_setitimer (__NR_SYSCALL_BASE+104)
+#define __NR_getitimer (__NR_SYSCALL_BASE+105)
+#define __NR_stat (__NR_SYSCALL_BASE+106)
+#define __NR_lstat (__NR_SYSCALL_BASE+107)
+#define __NR_fstat (__NR_SYSCALL_BASE+108)
+ /* 109 was sys_uname */
+ /* 110 was sys_iopl */
+#define __NR_vhangup (__NR_SYSCALL_BASE+111)
+ /* 112 was sys_idle */
+#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
+#define __NR_wait4 (__NR_SYSCALL_BASE+114)
+#define __NR_swapoff (__NR_SYSCALL_BASE+115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
+#define __NR_ipc (__NR_SYSCALL_BASE+117)
+#define __NR_fsync (__NR_SYSCALL_BASE+118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
+#define __NR_clone (__NR_SYSCALL_BASE+120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
+#define __NR_uname (__NR_SYSCALL_BASE+122)
+ /* 123 was sys_modify_ldt */
+#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
+#define __NR_mprotect (__NR_SYSCALL_BASE+125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
+ /* 127 was sys_create_module */
+#define __NR_init_module (__NR_SYSCALL_BASE+128)
+#define __NR_delete_module (__NR_SYSCALL_BASE+129)
+ /* 130 was sys_get_kernel_syms */
+#define __NR_quotactl (__NR_SYSCALL_BASE+131)
+#define __NR_getpgid (__NR_SYSCALL_BASE+132)
+#define __NR_fchdir (__NR_SYSCALL_BASE+133)
+#define __NR_bdflush (__NR_SYSCALL_BASE+134)
+#define __NR_sysfs (__NR_SYSCALL_BASE+135)
+#define __NR_personality (__NR_SYSCALL_BASE+136)
+ /* 137 was sys_afs_syscall */
+#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
+#define __NR__llseek (__NR_SYSCALL_BASE+140)
+#define __NR_getdents (__NR_SYSCALL_BASE+141)
+#define __NR__newselect (__NR_SYSCALL_BASE+142)
+#define __NR_flock (__NR_SYSCALL_BASE+143)
+#define __NR_msync (__NR_SYSCALL_BASE+144)
+#define __NR_readv (__NR_SYSCALL_BASE+145)
+#define __NR_writev (__NR_SYSCALL_BASE+146)
+#define __NR_getsid (__NR_SYSCALL_BASE+147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
+#define __NR__sysctl (__NR_SYSCALL_BASE+149)
+#define __NR_mlock (__NR_SYSCALL_BASE+150)
+#define __NR_munlock (__NR_SYSCALL_BASE+151)
+#define __NR_mlockall (__NR_SYSCALL_BASE+152)
+#define __NR_munlockall (__NR_SYSCALL_BASE+153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
+#define __NR_mremap (__NR_SYSCALL_BASE+163)
+#define __NR_setresuid (__NR_SYSCALL_BASE+164)
+#define __NR_getresuid (__NR_SYSCALL_BASE+165)
+ /* 166 was sys_vm86 */
+ /* 167 was sys_query_module */
+#define __NR_poll (__NR_SYSCALL_BASE+168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
+#define __NR_setresgid (__NR_SYSCALL_BASE+170)
+#define __NR_getresgid (__NR_SYSCALL_BASE+171)
+#define __NR_prctl (__NR_SYSCALL_BASE+172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
+#define __NR_pread64 (__NR_SYSCALL_BASE+180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
+#define __NR_chown (__NR_SYSCALL_BASE+182)
+#define __NR_getcwd (__NR_SYSCALL_BASE+183)
+#define __NR_capget (__NR_SYSCALL_BASE+184)
+#define __NR_capset (__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
+#define __NR_sendfile (__NR_SYSCALL_BASE+187)
+ /* 188 reserved */
+ /* 189 reserved */
+#define __NR_vfork (__NR_SYSCALL_BASE+190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */
+#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
+#define __NR_stat64 (__NR_SYSCALL_BASE+195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
+#define __NR_chown32 (__NR_SYSCALL_BASE+212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
+#define __NR_mincore (__NR_SYSCALL_BASE+219)
+#define __NR_madvise (__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
+ /* 222 for tux */
+ /* 223 is unused */
+#define __NR_gettid (__NR_SYSCALL_BASE+224)
+#define __NR_readahead (__NR_SYSCALL_BASE+225)
+#define __NR_setxattr (__NR_SYSCALL_BASE+226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
+#define __NR_getxattr (__NR_SYSCALL_BASE+229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
+#define __NR_listxattr (__NR_SYSCALL_BASE+232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
+#define __NR_removexattr (__NR_SYSCALL_BASE+235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
+#define __NR_tkill (__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
+#define __NR_futex (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+ /* 254 for set_thread_area */
+ /* 255 for get_thread_area */
+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
+#define __NR_timer_create (__NR_SYSCALL_BASE+257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
+#define __NR_tgkill (__NR_SYSCALL_BASE+268)
+#define __NR_utimes (__NR_SYSCALL_BASE+269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
+#define __NR_mq_open (__NR_SYSCALL_BASE+274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
+#define __NR_waitid (__NR_SYSCALL_BASE+280)
+#define __NR_socket (__NR_SYSCALL_BASE+281)
+#define __NR_bind (__NR_SYSCALL_BASE+282)
+#define __NR_connect (__NR_SYSCALL_BASE+283)
+#define __NR_listen (__NR_SYSCALL_BASE+284)
+#define __NR_accept (__NR_SYSCALL_BASE+285)
+#define __NR_getsockname (__NR_SYSCALL_BASE+286)
+#define __NR_getpeername (__NR_SYSCALL_BASE+287)
+#define __NR_socketpair (__NR_SYSCALL_BASE+288)
+#define __NR_send (__NR_SYSCALL_BASE+289)
+#define __NR_sendto (__NR_SYSCALL_BASE+290)
+#define __NR_recv (__NR_SYSCALL_BASE+291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
+#define __NR_shutdown (__NR_SYSCALL_BASE+293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
+#define __NR_semop (__NR_SYSCALL_BASE+298)
+#define __NR_semget (__NR_SYSCALL_BASE+299)
+#define __NR_semctl (__NR_SYSCALL_BASE+300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
+#define __NR_msgget (__NR_SYSCALL_BASE+303)
+#define __NR_msgctl (__NR_SYSCALL_BASE+304)
+#define __NR_shmat (__NR_SYSCALL_BASE+305)
+#define __NR_shmdt (__NR_SYSCALL_BASE+306)
+#define __NR_shmget (__NR_SYSCALL_BASE+307)
+#define __NR_shmctl (__NR_SYSCALL_BASE+308)
+#define __NR_add_key (__NR_SYSCALL_BASE+309)
+#define __NR_request_key (__NR_SYSCALL_BASE+310)
+#define __NR_keyctl (__NR_SYSCALL_BASE+311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
+#define __NR_vserver (__NR_SYSCALL_BASE+313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
+#define __NR_mbind (__NR_SYSCALL_BASE+319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+#define __NR_openat (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
+#define __NR_renameat (__NR_SYSCALL_BASE+329)
+#define __NR_linkat (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat (__NR_SYSCALL_BASE+334)
+#define __NR_pselect6 (__NR_SYSCALL_BASE+335)
+#define __NR_ppoll (__NR_SYSCALL_BASE+336)
+#define __NR_unshare (__NR_SYSCALL_BASE+337)
+#define __NR_set_robust_list (__NR_SYSCALL_BASE+338)
+#define __NR_get_robust_list (__NR_SYSCALL_BASE+339)
+#define __NR_splice (__NR_SYSCALL_BASE+340)
+#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341)
+#define __NR_sync_file_range2 __NR_arm_sync_file_range
+#define __NR_tee (__NR_SYSCALL_BASE+342)
+#define __NR_vmsplice (__NR_SYSCALL_BASE+343)
+#define __NR_move_pages (__NR_SYSCALL_BASE+344)
+#define __NR_getcpu (__NR_SYSCALL_BASE+345)
+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+346)
+#define __NR_kexec_load (__NR_SYSCALL_BASE+347)
+#define __NR_utimensat (__NR_SYSCALL_BASE+348)
+#define __NR_signalfd (__NR_SYSCALL_BASE+349)
+#define __NR_timerfd_create (__NR_SYSCALL_BASE+350)
+#define __NR_eventfd (__NR_SYSCALL_BASE+351)
+#define __NR_fallocate (__NR_SYSCALL_BASE+352)
+#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353)
+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354)
+#define __NR_signalfd4 (__NR_SYSCALL_BASE+355)
+#define __NR_eventfd2 (__NR_SYSCALL_BASE+356)
+#define __NR_epoll_create1 (__NR_SYSCALL_BASE+357)
+#define __NR_dup3 (__NR_SYSCALL_BASE+358)
+#define __NR_pipe2 (__NR_SYSCALL_BASE+359)
+#define __NR_inotify_init1 (__NR_SYSCALL_BASE+360)
+#define __NR_preadv (__NR_SYSCALL_BASE+361)
+#define __NR_pwritev (__NR_SYSCALL_BASE+362)
+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+363)
+#define __NR_perf_event_open (__NR_SYSCALL_BASE+364)
+#define __NR_recvmmsg (__NR_SYSCALL_BASE+365)
+#define __NR_accept4 (__NR_SYSCALL_BASE+366)
+#define __NR_fanotify_init (__NR_SYSCALL_BASE+367)
+#define __NR_fanotify_mark (__NR_SYSCALL_BASE+368)
+#define __NR_prlimit64 (__NR_SYSCALL_BASE+369)
+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370)
+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371)
+#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372)
+#define __NR_syncfs (__NR_SYSCALL_BASE+373)
+#define __NR_sendmmsg (__NR_SYSCALL_BASE+374)
+#define __NR_setns (__NR_SYSCALL_BASE+375)
+
+/*
+ * The following SWIs are ARM private.
+ */
+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
+#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
+#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
+#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
+
+/*
+ * *NOTE*: This is a ghost syscall private to the kernel. Only the
+ * __kuser_cmpxchg code in entry-armv.S should be aware of its
+ * existence. Don't ever use this from user code.
+ */
+#ifdef __KERNEL__
+#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
+#endif
+
+/*
+ * The following syscalls are obsolete and no longer available for EABI.
+ */
+#if defined(__ARM_EABI__) && !defined(__KERNEL__)
+#undef __NR_time
+#undef __NR_umount
+#undef __NR_stime
+#undef __NR_alarm
+#undef __NR_utime
+#undef __NR_getrlimit
+#undef __NR_select
+#undef __NR_readdir
+#undef __NR_mmap
+#undef __NR_socketcall
+#undef __NR_syscall
+#undef __NR_ipc
+#endif
+
+#ifdef __KERNEL__
+
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_OLD_MMAP
+#define __ARCH_WANT_SYS_OLD_SELECT
+
+#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_SYS_SOCKETCALL
+#endif
+
+/*
+ * "Conditional" syscalls
+ *
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
+ * but it doesn't work on all toolchains, so we just do it by hand
+ */
+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
+
+/*
+ * Unimplemented (or alternatively implemented) syscalls
+ */
+#define __IGNORE_fadvise64_64 1
+#define __IGNORE_migrate_pages 1
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/include/asm/unwind.h b/arch/arm/include/asm/unwind.h
new file mode 100644
index 00000000..a5edf421
--- /dev/null
+++ b/arch/arm/include/asm/unwind.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/include/asm/unwind.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_UNWIND_H
+#define __ASM_UNWIND_H
+
+#ifndef __ASSEMBLY__
+
+/* Unwind reason code according the the ARM EABI documents */
+enum unwind_reason_code {
+ URC_OK = 0, /* operation completed successfully */
+ URC_CONTINUE_UNWIND = 8,
+ URC_FAILURE = 9 /* unspecified failure of some kind */
+};
+
+struct unwind_idx {
+ unsigned long addr;
+ unsigned long insn;
+};
+
+struct unwind_table {
+ struct list_head list;
+ struct unwind_idx *start;
+ struct unwind_idx *stop;
+ unsigned long begin_addr;
+ unsigned long end_addr;
+};
+
+extern struct unwind_table *unwind_table_add(unsigned long start,
+ unsigned long size,
+ unsigned long text_addr,
+ unsigned long text_size);
+extern void unwind_table_del(struct unwind_table *tab);
+extern void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk);
+
+#ifdef CONFIG_ARM_UNWIND
+extern int __init unwind_init(void);
+#else
+static inline int __init unwind_init(void)
+{
+ return 0;
+}
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef CONFIG_ARM_UNWIND
+#define UNWIND(code...) code
+#else
+#define UNWIND(code...)
+#endif
+
+#endif /* __ASM_UNWIND_H */
diff --git a/arch/arm/include/asm/user.h b/arch/arm/include/asm/user.h
new file mode 100644
index 00000000..35917b3a
--- /dev/null
+++ b/arch/arm/include/asm/user.h
@@ -0,0 +1,103 @@
+#ifndef _ARM_USER_H
+#define _ARM_USER_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+/* Core file format: The core file is written in such a way that gdb
+ can understand it and provide useful information to the user (under
+ linux we use the 'trad-core' bfd). There are quite a number of
+ obstacles to being able to view the contents of the floating point
+ registers, and until these are solved you will not be able to view the
+ contents of them. Actually, you can read in the core file and look at
+ the contents of the user struct to find out what the floating point
+ registers contain.
+ The actual file contents are as follows:
+ UPAGE: 1 page consisting of a user struct that tells gdb what is present
+ in the file. Directly after this is a copy of the task_struct, which
+ is currently not used by gdb, but it may come in useful at some point.
+ All of the registers are stored as part of the upage. The upage should
+ always be only one page.
+ DATA: The data area is stored. We use current->end_text to
+ current->brk to pick up all of the user variables, plus any memory
+ that may have been malloced. No attempt is made to determine if a page
+ is demand-zero or if a page is totally unused, we just cover the entire
+ range. All of the addresses are rounded in such a way that an integral
+ number of pages is written.
+ STACK: We need the stack information in order to get a meaningful
+ backtrace. We need to write the data from (esp) to
+ current->start_stack, so we round each of these off in order to be able
+ to write an integer number of pages.
+ The minimum core file size is 3 pages, or 12288 bytes.
+*/
+
+struct user_fp {
+ struct fp_reg {
+ unsigned int sign1:1;
+ unsigned int unused:15;
+ unsigned int sign2:1;
+ unsigned int exponent:14;
+ unsigned int j:1;
+ unsigned int mantissa1:31;
+ unsigned int mantissa0:32;
+ } fpregs[8];
+ unsigned int fpsr:32;
+ unsigned int fpcr:32;
+ unsigned char ftype[8];
+ unsigned int init_flag;
+};
+
+/* When the kernel dumps core, it starts by dumping the user struct -
+ this will be used by gdb to figure out where the data and stack segments
+ are within the file, and what virtual addresses to use. */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+ from the ptrace(3,...) function. */
+ struct pt_regs regs; /* Where the registers are actually stored */
+/* ptrace does not yet supply these. Someday.... */
+ int u_fpvalid; /* True if math co-processor being used. */
+ /* for this mess. Not yet used. */
+/* The rest of this junk is to help gdb figure out what goes where */
+ unsigned long int u_tsize; /* Text segment size (pages). */
+ unsigned long int u_dsize; /* Data segment size (pages). */
+ unsigned long int u_ssize; /* Stack segment size (pages). */
+ unsigned long start_code; /* Starting virtual address of text. */
+ unsigned long start_stack; /* Starting virtual address of stack area.
+ This is actually the bottom of the stack,
+ the top of the stack is always found in the
+ esp register. */
+ long int signal; /* Signal that caused the core dump. */
+ int reserved; /* No longer used */
+ unsigned long u_ar0; /* Used by gdb to help find the values for */
+ /* the registers. */
+ unsigned long magic; /* To uniquely identify a core file */
+ char u_comm[32]; /* User command that was responsible */
+ int u_debugreg[8]; /* No longer used */
+ struct user_fp u_fp; /* FP state */
+ struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */
+ /* the FP registers. */
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+/*
+ * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
+ * are ignored by the ptrace system call and the signal handler.
+ */
+struct user_vfp {
+ unsigned long long fpregs[32];
+ unsigned long fpscr;
+};
+
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+ unsigned long fpexc;
+ unsigned long fpinst;
+ unsigned long fpinst2;
+};
+
+#endif /* _ARM_USER_H */
diff --git a/arch/arm/include/asm/vfp.h b/arch/arm/include/asm/vfp.h
new file mode 100644
index 00000000..f4ab34fd
--- /dev/null
+++ b/arch/arm/include/asm/vfp.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/include/asm/vfp.h
+ *
+ * VFP register definitions.
+ * First, the standard VFP set.
+ */
+
+#define FPSID cr0
+#define FPSCR cr1
+#define MVFR1 cr6
+#define MVFR0 cr7
+#define FPEXC cr8
+#define FPINST cr9
+#define FPINST2 cr10
+
+/* FPSID bits */
+#define FPSID_IMPLEMENTER_BIT (24)
+#define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT)
+#define FPSID_SOFTWARE (1<<23)
+#define FPSID_FORMAT_BIT (21)
+#define FPSID_FORMAT_MASK (0x3 << FPSID_FORMAT_BIT)
+#define FPSID_NODOUBLE (1<<20)
+#define FPSID_ARCH_BIT (16)
+#define FPSID_ARCH_MASK (0xF << FPSID_ARCH_BIT)
+#define FPSID_PART_BIT (8)
+#define FPSID_PART_MASK (0xFF << FPSID_PART_BIT)
+#define FPSID_VARIANT_BIT (4)
+#define FPSID_VARIANT_MASK (0xF << FPSID_VARIANT_BIT)
+#define FPSID_REV_BIT (0)
+#define FPSID_REV_MASK (0xF << FPSID_REV_BIT)
+
+/* FPEXC bits */
+#define FPEXC_EX (1 << 31)
+#define FPEXC_EN (1 << 30)
+#define FPEXC_DEX (1 << 29)
+#define FPEXC_FP2V (1 << 28)
+#define FPEXC_VV (1 << 27)
+#define FPEXC_TFV (1 << 26)
+#define FPEXC_LENGTH_BIT (8)
+#define FPEXC_LENGTH_MASK (7 << FPEXC_LENGTH_BIT)
+#define FPEXC_IDF (1 << 7)
+#define FPEXC_IXF (1 << 4)
+#define FPEXC_UFF (1 << 3)
+#define FPEXC_OFF (1 << 2)
+#define FPEXC_DZF (1 << 1)
+#define FPEXC_IOF (1 << 0)
+#define FPEXC_TRAP_MASK (FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF)
+
+/* FPSCR bits */
+#define FPSCR_DEFAULT_NAN (1<<25)
+#define FPSCR_FLUSHTOZERO (1<<24)
+#define FPSCR_ROUND_NEAREST (0<<22)
+#define FPSCR_ROUND_PLUSINF (1<<22)
+#define FPSCR_ROUND_MINUSINF (2<<22)
+#define FPSCR_ROUND_TOZERO (3<<22)
+#define FPSCR_RMODE_BIT (22)
+#define FPSCR_RMODE_MASK (3 << FPSCR_RMODE_BIT)
+#define FPSCR_STRIDE_BIT (20)
+#define FPSCR_STRIDE_MASK (3 << FPSCR_STRIDE_BIT)
+#define FPSCR_LENGTH_BIT (16)
+#define FPSCR_LENGTH_MASK (7 << FPSCR_LENGTH_BIT)
+#define FPSCR_IOE (1<<8)
+#define FPSCR_DZE (1<<9)
+#define FPSCR_OFE (1<<10)
+#define FPSCR_UFE (1<<11)
+#define FPSCR_IXE (1<<12)
+#define FPSCR_IDE (1<<15)
+#define FPSCR_IOC (1<<0)
+#define FPSCR_DZC (1<<1)
+#define FPSCR_OFC (1<<2)
+#define FPSCR_UFC (1<<3)
+#define FPSCR_IXC (1<<4)
+#define FPSCR_IDC (1<<7)
+
+/* MVFR0 bits */
+#define MVFR0_A_SIMD_BIT (0)
+#define MVFR0_A_SIMD_MASK (0xf << MVFR0_A_SIMD_BIT)
+
+/* Bit patterns for decoding the packaged operation descriptors */
+#define VFPOPDESC_LENGTH_BIT (9)
+#define VFPOPDESC_LENGTH_MASK (0x07 << VFPOPDESC_LENGTH_BIT)
+#define VFPOPDESC_UNUSED_BIT (24)
+#define VFPOPDESC_UNUSED_MASK (0xFF << VFPOPDESC_UNUSED_BIT)
+#define VFPOPDESC_OPDESC_MASK (~(VFPOPDESC_LENGTH_MASK | VFPOPDESC_UNUSED_MASK))
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
new file mode 100644
index 00000000..3d5fc41a
--- /dev/null
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/include/asm/vfpmacros.h
+ *
+ * Assembler-only file containing VFP macros and register definitions.
+ */
+#include <asm/hwcap.h>
+
+#include "vfp.h"
+
+@ Macros to allow building with old toolkits (with no VFP support)
+ .macro VFPFMRX, rd, sysreg, cond
+ MRC\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMRX \rd, \sysreg
+ .endm
+
+ .macro VFPFMXR, sysreg, rd, cond
+ MCR\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMXR \sysreg, \rd
+ .endm
+
+ @ read all the working registers back into the VFP
+ .macro VFPFLDMIA, base, tmp
+#if __LINUX_ARM_ARCH__ < 6
+ LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15}
+#else
+ LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15}
+#endif
+#ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+ ldr \tmp, =elf_hwcap @ may not have MVFR regs
+ ldr \tmp, [\tmp, #0]
+ tst \tmp, #HWCAP_VFPv3D16
+ ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#else
+ VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
+ and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
+ cmp \tmp, #2 @ 32 x 64bit registers?
+ ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#endif
+#endif
+ .endm
+
+ @ write all the working registers out of the VFP
+ .macro VFPFSTMIA, base, tmp
+#if __LINUX_ARM_ARCH__ < 6
+ STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15}
+#else
+ STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15}
+#endif
+#ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+ ldr \tmp, =elf_hwcap @ may not have MVFR regs
+ ldr \tmp, [\tmp, #0]
+ tst \tmp, #HWCAP_VFPv3D16
+ stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#else
+ VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
+ and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
+ cmp \tmp, #2 @ 32 x 64bit registers?
+ stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#endif
+#endif
+ .endm
diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h
new file mode 100644
index 00000000..250a4dd0
--- /dev/null
+++ b/arch/arm/include/asm/vga.h
@@ -0,0 +1,12 @@
+#ifndef ASMARM_VGA_H
+#define ASMARM_VGA_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x))
+
+#define vga_readb(x) (*((volatile unsigned char *)x))
+#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x))
+
+#endif
diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h
new file mode 100644
index 00000000..7604673d
--- /dev/null
+++ b/arch/arm/include/asm/xor.h
@@ -0,0 +1,141 @@
+/*
+ * arch/arm/include/asm/xor.h
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm-generic/xor.h>
+
+#define __XOR(a1, a2) a1 ^= a2
+
+#define GET_BLOCK_2(dst) \
+ __asm__("ldmia %0, {%1, %2}" \
+ : "=r" (dst), "=r" (a1), "=r" (a2) \
+ : "0" (dst))
+
+#define GET_BLOCK_4(dst) \
+ __asm__("ldmia %0, {%1, %2, %3, %4}" \
+ : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \
+ : "0" (dst))
+
+#define XOR_BLOCK_2(src) \
+ __asm__("ldmia %0!, {%1, %2}" \
+ : "=r" (src), "=r" (b1), "=r" (b2) \
+ : "0" (src)); \
+ __XOR(a1, b1); __XOR(a2, b2);
+
+#define XOR_BLOCK_4(src) \
+ __asm__("ldmia %0!, {%1, %2, %3, %4}" \
+ : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \
+ : "0" (src)); \
+ __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4)
+
+#define PUT_BLOCK_2(dst) \
+ __asm__ __volatile__("stmia %0!, {%2, %3}" \
+ : "=r" (dst) \
+ : "0" (dst), "r" (a1), "r" (a2))
+
+#define PUT_BLOCK_4(dst) \
+ __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \
+ : "=r" (dst) \
+ : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4))
+
+static void
+xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+{
+ unsigned int lines = bytes / sizeof(unsigned long) / 4;
+ register unsigned int a1 __asm__("r4");
+ register unsigned int a2 __asm__("r5");
+ register unsigned int a3 __asm__("r6");
+ register unsigned int a4 __asm__("r7");
+ register unsigned int b1 __asm__("r8");
+ register unsigned int b2 __asm__("r9");
+ register unsigned int b3 __asm__("ip");
+ register unsigned int b4 __asm__("lr");
+
+ do {
+ GET_BLOCK_4(p1);
+ XOR_BLOCK_4(p2);
+ PUT_BLOCK_4(p1);
+ } while (--lines);
+}
+
+static void
+xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3)
+{
+ unsigned int lines = bytes / sizeof(unsigned long) / 4;
+ register unsigned int a1 __asm__("r4");
+ register unsigned int a2 __asm__("r5");
+ register unsigned int a3 __asm__("r6");
+ register unsigned int a4 __asm__("r7");
+ register unsigned int b1 __asm__("r8");
+ register unsigned int b2 __asm__("r9");
+ register unsigned int b3 __asm__("ip");
+ register unsigned int b4 __asm__("lr");
+
+ do {
+ GET_BLOCK_4(p1);
+ XOR_BLOCK_4(p2);
+ XOR_BLOCK_4(p3);
+ PUT_BLOCK_4(p1);
+ } while (--lines);
+}
+
+static void
+xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4)
+{
+ unsigned int lines = bytes / sizeof(unsigned long) / 2;
+ register unsigned int a1 __asm__("r8");
+ register unsigned int a2 __asm__("r9");
+ register unsigned int b1 __asm__("ip");
+ register unsigned int b2 __asm__("lr");
+
+ do {
+ GET_BLOCK_2(p1);
+ XOR_BLOCK_2(p2);
+ XOR_BLOCK_2(p3);
+ XOR_BLOCK_2(p4);
+ PUT_BLOCK_2(p1);
+ } while (--lines);
+}
+
+static void
+xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
+{
+ unsigned int lines = bytes / sizeof(unsigned long) / 2;
+ register unsigned int a1 __asm__("r8");
+ register unsigned int a2 __asm__("r9");
+ register unsigned int b1 __asm__("ip");
+ register unsigned int b2 __asm__("lr");
+
+ do {
+ GET_BLOCK_2(p1);
+ XOR_BLOCK_2(p2);
+ XOR_BLOCK_2(p3);
+ XOR_BLOCK_2(p4);
+ XOR_BLOCK_2(p5);
+ PUT_BLOCK_2(p1);
+ } while (--lines);
+}
+
+static struct xor_block_template xor_block_arm4regs = {
+ .name = "arm4regs",
+ .do_2 = xor_arm4regs_2,
+ .do_3 = xor_arm4regs_3,
+ .do_4 = xor_arm4regs_4,
+ .do_5 = xor_arm4regs_5,
+};
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES \
+ do { \
+ xor_speed(&xor_block_arm4regs); \
+ xor_speed(&xor_block_8regs); \
+ xor_speed(&xor_block_32regs); \
+ } while (0)
diff --git a/arch/arm/kernel/.gitignore b/arch/arm/kernel/.gitignore
new file mode 100644
index 00000000..c5f676c3
--- /dev/null
+++ b/arch/arm/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
new file mode 100644
index 00000000..a5b31af5
--- /dev/null
+++ b/arch/arm/kernel/Makefile
@@ -0,0 +1,73 @@
+#
+# Makefile for the linux kernel.
+#
+
+CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
+AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
+
+ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_REMOVE_ftrace.o = -pg
+endif
+
+CFLAGS_REMOVE_return_address.o = -pg
+
+# Object file lists.
+
+obj-y := elf.o entry-armv.o entry-common.o irq.o \
+ process.o ptrace.o return_address.o setup.o signal.o \
+ sys_arm.o stacktrace.o time.o traps.o
+
+obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
+
+obj-$(CONFIG_LEDS) += leds.o
+obj-$(CONFIG_OC_ETM) += etm.o
+
+obj-$(CONFIG_ISA_DMA_API) += dma.o
+obj-$(CONFIG_ARCH_ACORN) += ecard.o
+obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
+obj-$(CONFIG_MODULES) += armksyms.o module.o
+obj-$(CONFIG_ARTHUR) += arthur.o
+obj-$(CONFIG_ISA_DMA) += dma-isa.o
+obj-$(CONFIG_PCI) += bios32.o isa.o
+obj-$(CONFIG_PM_SLEEP) += sleep.o
+obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
+obj-$(CONFIG_SMP) += smp.o smp_tlb.o
+obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
+obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
+obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
+obj-$(CONFIG_ATAGS_PROC) += atags.o
+obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
+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_OF) += devtree.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
+CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
+
+obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
+AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
+
+obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
+obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
+obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
+obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
+obj-$(CONFIG_IWMMXT) += iwmmxt.o
+obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
+obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
+
+ifneq ($(CONFIG_ARCH_EBSA110),y)
+ obj-y += io.o
+endif
+
+head-y := head$(MMUEXT).o
+obj-$(CONFIG_DEBUG_LL) += debug.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+extra-y := $(head-y) init_task.o vmlinux.lds
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
new file mode 100644
index 00000000..acca35ae
--- /dev/null
+++ b/arch/arm/kernel/armksyms.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/kernel/armksyms.c
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can 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/sched.h>
+#include <linux/string.h>
+#include <linux/cryptohash.h>
+#include <linux/delay.h>
+#include <linux/in6.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#include <asm/checksum.h>
+#include <asm/system.h>
+#include <asm/ftrace.h>
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler... (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __ucmpdi2(void);
+extern void __udivsi3(void);
+extern void __umodsi3(void);
+extern void __do_div64(void);
+
+extern void __aeabi_idiv(void);
+extern void __aeabi_idivmod(void);
+extern void __aeabi_lasr(void);
+extern void __aeabi_llsl(void);
+extern void __aeabi_llsr(void);
+extern void __aeabi_lmul(void);
+extern void __aeabi_uidiv(void);
+extern void __aeabi_uidivmod(void);
+extern void __aeabi_ulcmp(void);
+
+extern void fpundefinstr(void);
+
+
+EXPORT_SYMBOL(__backtrace);
+
+ /* platform dependent support */
+EXPORT_SYMBOL(__udelay);
+EXPORT_SYMBOL(__const_udelay);
+
+ /* networking */
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_ipv6_magic);
+
+ /* io */
+#ifndef __raw_readsb
+EXPORT_SYMBOL(__raw_readsb);
+#endif
+#ifndef __raw_readsw
+EXPORT_SYMBOL(__raw_readsw);
+#endif
+#ifndef __raw_readsl
+EXPORT_SYMBOL(__raw_readsl);
+#endif
+#ifndef __raw_writesb
+EXPORT_SYMBOL(__raw_writesb);
+#endif
+#ifndef __raw_writesw
+EXPORT_SYMBOL(__raw_writesw);
+#endif
+#ifndef __raw_writesl
+EXPORT_SYMBOL(__raw_writesl);
+#endif
+
+ /* string / mem functions */
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memchr);
+EXPORT_SYMBOL(__memzero);
+
+ /* user mem (segment) */
+EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(__strncpy_from_user);
+
+#ifdef CONFIG_MMU
+EXPORT_SYMBOL(copy_page);
+
+EXPORT_SYMBOL(__copy_from_user);
+EXPORT_SYMBOL(__copy_to_user);
+EXPORT_SYMBOL(__clear_user);
+
+EXPORT_SYMBOL(__get_user_1);
+EXPORT_SYMBOL(__get_user_2);
+EXPORT_SYMBOL(__get_user_4);
+
+EXPORT_SYMBOL(__put_user_1);
+EXPORT_SYMBOL(__put_user_2);
+EXPORT_SYMBOL(__put_user_4);
+EXPORT_SYMBOL(__put_user_8);
+#endif
+
+ /* crypto hash */
+EXPORT_SYMBOL(sha_transform);
+
+ /* gcc lib functions */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__ucmpdi2);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
+EXPORT_SYMBOL(__do_div64);
+
+#ifdef CONFIG_AEABI
+EXPORT_SYMBOL(__aeabi_idiv);
+EXPORT_SYMBOL(__aeabi_idivmod);
+EXPORT_SYMBOL(__aeabi_lasr);
+EXPORT_SYMBOL(__aeabi_llsl);
+EXPORT_SYMBOL(__aeabi_llsr);
+EXPORT_SYMBOL(__aeabi_lmul);
+EXPORT_SYMBOL(__aeabi_uidiv);
+EXPORT_SYMBOL(__aeabi_uidivmod);
+EXPORT_SYMBOL(__aeabi_ulcmp);
+#endif
+
+ /* bitops */
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
+EXPORT_SYMBOL(_find_first_zero_bit_le);
+EXPORT_SYMBOL(_find_next_zero_bit_le);
+EXPORT_SYMBOL(_find_first_bit_le);
+EXPORT_SYMBOL(_find_next_bit_le);
+
+#ifdef __ARMEB__
+EXPORT_SYMBOL(_find_first_zero_bit_be);
+EXPORT_SYMBOL(_find_next_zero_bit_be);
+EXPORT_SYMBOL(_find_first_bit_be);
+EXPORT_SYMBOL(_find_next_bit_be);
+#endif
+
+#ifdef CONFIG_FUNCTION_TRACER
+#ifdef CONFIG_OLD_MCOUNT
+EXPORT_SYMBOL(mcount);
+#endif
+EXPORT_SYMBOL(__gnu_mcount_nc);
+#endif
+
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+EXPORT_SYMBOL(__pv_phys_offset);
+#endif
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
new file mode 100644
index 00000000..321c5291
--- /dev/null
+++ b/arch/arm/kernel/arthur.c
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/kernel/arthur.c
+ *
+ * Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell
+ *
+ * Arthur personality
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/personality.h>
+#include <linux/stddef.h>
+#include <linux/signal.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/ptrace.h>
+
+/* Arthur doesn't have many signals, and a lot of those that it does
+ have don't map easily to any Linux equivalent. Never mind. */
+
+#define ARTHUR_SIGABRT 1
+#define ARTHUR_SIGFPE 2
+#define ARTHUR_SIGILL 3
+#define ARTHUR_SIGINT 4
+#define ARTHUR_SIGSEGV 5
+#define ARTHUR_SIGTERM 6
+#define ARTHUR_SIGSTAK 7
+#define ARTHUR_SIGUSR1 8
+#define ARTHUR_SIGUSR2 9
+#define ARTHUR_SIGOSERROR 10
+
+static unsigned long arthur_to_linux_signals[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31
+};
+
+static unsigned long linux_to_arthur_signals[32] = {
+ 0, -1, ARTHUR_SIGINT, -1,
+ ARTHUR_SIGILL, 5, ARTHUR_SIGABRT, 7,
+ ARTHUR_SIGFPE, 9, ARTHUR_SIGUSR1, ARTHUR_SIGSEGV,
+ ARTHUR_SIGUSR2, 13, 14, ARTHUR_SIGTERM,
+ 16, 17, 18, 19,
+ 20, 21, 22, 23,
+ 24, 25, 26, 27,
+ 28, 29, 30, 31
+};
+
+static void arthur_lcall7(int nr, struct pt_regs *regs)
+{
+ struct siginfo info;
+ info.si_signo = SIGSWI;
+ info.si_errno = nr;
+ /* Bounce it to the emulator */
+ send_sig_info(SIGSWI, &info, current);
+}
+
+static struct exec_domain arthur_exec_domain = {
+ .name = "Arthur",
+ .handler = arthur_lcall7,
+ .pers_low = PER_RISCOS,
+ .pers_high = PER_RISCOS,
+ .signal_map = arthur_to_linux_signals,
+ .signal_invmap = linux_to_arthur_signals,
+ .module = THIS_MODULE,
+};
+
+/*
+ * We could do with some locking to stop Arthur being removed while
+ * processes are using it.
+ */
+
+static int __init arthur_init(void)
+{
+ return register_exec_domain(&arthur_exec_domain);
+}
+
+static void __exit arthur_exit(void)
+{
+ unregister_exec_domain(&arthur_exec_domain);
+}
+
+module_init(arthur_init);
+module_exit(arthur_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
new file mode 100644
index 00000000..927522cf
--- /dev/null
+++ b/arch/arm/kernel/asm-offsets.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 1995-2003 Russell King
+ * 2001-2002 Keith Owens
+ *
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ *
+ * This program is free software; you can 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/mm.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
+#include <asm/mach/arch.h>
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/procinfo.h>
+#include <linux/kbuild.h>
+
+/*
+ * Make sure that the compiler and target are compatible.
+ */
+#if defined(__APCS_26__)
+#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
+#endif
+/*
+ * GCC 3.0, 3.1: general bad code generation.
+ * GCC 3.2.0: incorrect function argument offset calculation.
+ * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
+ * (http://gcc.gnu.org/PR8896) and incorrect structure
+ * initialisation in fs/jffs2/erase.c
+ */
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#error Your compiler is too buggy; it is known to miscompile kernels.
+#error Known good compilers: 3.3
+#endif
+
+int main(void)
+{
+ DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+#ifdef CONFIG_CC_STACKPROTECTOR
+ DEFINE(TSK_STACK_CANARY, offsetof(struct task_struct, stack_canary));
+#endif
+ BLANK();
+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
+ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
+ DEFINE(TI_TASK, offsetof(struct thread_info, task));
+ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+ DEFINE(TI_CPU_DOMAIN, offsetof(struct thread_info, cpu_domain));
+ DEFINE(TI_CPU_SAVE, offsetof(struct thread_info, cpu_context));
+ DEFINE(TI_USED_CP, offsetof(struct thread_info, used_cp));
+ DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value));
+ DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
+ DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
+#ifdef CONFIG_ARM_THUMBEE
+ DEFINE(TI_THUMBEE_STATE, offsetof(struct thread_info, thumbee_state));
+#endif
+#ifdef CONFIG_IWMMXT
+ DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt));
+#endif
+#ifdef CONFIG_CRUNCH
+ DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate));
+#endif
+ BLANK();
+ DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
+ DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
+ DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));
+ DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));
+ DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));
+ DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));
+ DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));
+ DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));
+ DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));
+ DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));
+ DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));
+ DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));
+ DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));
+ DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));
+ DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));
+ DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
+ DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
+ DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
+ DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
+ BLANK();
+#ifdef CONFIG_CPU_HAS_ASID
+ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
+ BLANK();
+#endif
+ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm));
+ DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags));
+ BLANK();
+ DEFINE(VM_EXEC, VM_EXEC);
+ BLANK();
+ DEFINE(PAGE_SZ, PAGE_SIZE);
+ BLANK();
+ DEFINE(SYS_ERROR0, 0x9f0000);
+ BLANK();
+ DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc));
+ DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr));
+ DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name));
+ BLANK();
+ DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list));
+ DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));
+ DEFINE(PROCINFO_MM_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mm_mmu_flags));
+ DEFINE(PROCINFO_IO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_io_mmu_flags));
+ BLANK();
+#ifdef MULTI_DABORT
+ DEFINE(PROCESSOR_DABT_FUNC, offsetof(struct processor, _data_abort));
+#endif
+#ifdef MULTI_PABORT
+ DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
+#endif
+#ifdef MULTI_CPU
+ DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
+ DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
+ DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
+#endif
+#ifdef MULTI_CACHE
+ DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
+#endif
+ BLANK();
+ DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
+ DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
+ DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
+ return 0;
+}
diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags.c
new file mode 100644
index 00000000..42a1a141
--- /dev/null
+++ b/arch/arm/kernel/atags.c
@@ -0,0 +1,83 @@
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/setup.h>
+#include <asm/types.h>
+#include <asm/page.h>
+
+struct buffer {
+ size_t size;
+ char data[];
+};
+
+static int
+read_buffer(char* page, char** start, off_t off, int count,
+ int* eof, void* data)
+{
+ struct buffer *buffer = (struct buffer *)data;
+
+ if (off >= buffer->size) {
+ *eof = 1;
+ return 0;
+ }
+
+ count = min((int) (buffer->size - off), count);
+
+ memcpy(page, &buffer->data[off], count);
+
+ return count;
+}
+
+#define BOOT_PARAMS_SIZE 1536
+static char __initdata atags_copy[BOOT_PARAMS_SIZE];
+
+void __init save_atags(const struct tag *tags)
+{
+ memcpy(atags_copy, tags, sizeof(atags_copy));
+}
+
+static int __init init_atags_procfs(void)
+{
+ /*
+ * This cannot go into save_atags() because kmalloc and proc don't work
+ * yet when it is called.
+ */
+ struct proc_dir_entry *tags_entry;
+ struct tag *tag = (struct tag *)atags_copy;
+ struct buffer *b;
+ size_t size;
+
+ if (tag->hdr.tag != ATAG_CORE) {
+ printk(KERN_INFO "No ATAGs?");
+ return -EINVAL;
+ }
+
+ for (; tag->hdr.size; tag = tag_next(tag))
+ ;
+
+ /* include the terminating ATAG_NONE */
+ size = (char *)tag - atags_copy + sizeof(struct tag_header);
+
+ WARN_ON(tag->hdr.tag != ATAG_NONE);
+
+ b = kmalloc(sizeof(*b) + size, GFP_KERNEL);
+ if (!b)
+ goto nomem;
+
+ b->size = size;
+ memcpy(b->data, atags_copy, size);
+
+ tags_entry = create_proc_read_entry("atags", 0400,
+ NULL, read_buffer, b);
+
+ if (!tags_entry)
+ goto nomem;
+
+ return 0;
+
+nomem:
+ kfree(b);
+ printk(KERN_ERR "Exporting ATAGs: not enough memory\n");
+
+ return -ENOMEM;
+}
+arch_initcall(init_atags_procfs);
diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h
new file mode 100644
index 00000000..e5f028d2
--- /dev/null
+++ b/arch/arm/kernel/atags.h
@@ -0,0 +1,5 @@
+#ifdef CONFIG_ATAGS_PROC
+extern void save_atags(struct tag *tags);
+#else
+static inline void save_atags(struct tag *tags) { }
+#endif
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
new file mode 100644
index 00000000..e4ee050a
--- /dev/null
+++ b/arch/arm/kernel/bios32.c
@@ -0,0 +1,681 @@
+/*
+ * linux/arch/arm/kernel/bios32.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/pci.h>
+
+static int debug_pci;
+static int use_firmware;
+
+/*
+ * We can't use pci_find_device() here since we are
+ * called from interrupt context.
+ */
+static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, int warn)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ u16 status;
+
+ /*
+ * ignore host bridge - we handle
+ * that separately
+ */
+ if (dev->bus->number == 0 && dev->devfn == 0)
+ continue;
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+ if (status == 0xffff)
+ continue;
+
+ if ((status & status_mask) == 0)
+ continue;
+
+ /* clear the status errors */
+ pci_write_config_word(dev, PCI_STATUS, status & status_mask);
+
+ if (warn)
+ printk("(%s: %04X) ", pci_name(dev), status);
+ }
+
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->subordinate)
+ pcibios_bus_report_status(dev->subordinate, status_mask, warn);
+}
+
+void pcibios_report_status(u_int status_mask, int warn)
+{
+ struct list_head *l;
+
+ list_for_each(l, &pci_root_buses) {
+ struct pci_bus *bus = pci_bus_b(l);
+
+ pcibios_bus_report_status(bus, status_mask, warn);
+ }
+}
+
+/*
+ * We don't use this to fix the device, but initialisation of it.
+ * It's not the correct use for this, but it works.
+ * Note that the arbiter/ISA bridge appears to be buggy, specifically in
+ * the following area:
+ * 1. park on CPU
+ * 2. ISA bridge ping-pong
+ * 3. ISA bridge master handling of target RETRY
+ *
+ * Bug 3 is responsible for the sound DMA grinding to a halt. We now
+ * live with bug 2.
+ */
+static void __devinit pci_fixup_83c553(struct pci_dev *dev)
+{
+ /*
+ * Set memory region to start at address 0, and enable IO
+ */
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_SPACE_MEMORY);
+ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ dev->resource[0].end -= dev->resource[0].start;
+ dev->resource[0].start = 0;
+
+ /*
+ * All memory requests from ISA to be channelled to PCI
+ */
+ pci_write_config_byte(dev, 0x48, 0xff);
+
+ /*
+ * Enable ping-pong on bus master to ISA bridge transactions.
+ * This improves the sound DMA substantially. The fixed
+ * priority arbiter also helps (see below).
+ */
+ pci_write_config_byte(dev, 0x42, 0x01);
+
+ /*
+ * Enable PCI retry
+ */
+ pci_write_config_byte(dev, 0x40, 0x22);
+
+ /*
+ * We used to set the arbiter to "park on last master" (bit
+ * 1 set), but unfortunately the CyberPro does not park the
+ * bus. We must therefore park on CPU. Unfortunately, this
+ * may trigger yet another bug in the 553.
+ */
+ pci_write_config_byte(dev, 0x83, 0x02);
+
+ /*
+ * Make the ISA DMA request lowest priority, and disable
+ * rotating priorities completely.
+ */
+ pci_write_config_byte(dev, 0x80, 0x11);
+ pci_write_config_byte(dev, 0x81, 0x00);
+
+ /*
+ * Route INTA input to IRQ 11, and set IRQ11 to be level
+ * sensitive.
+ */
+ pci_write_config_word(dev, 0x44, 0xb000);
+ outb(0x08, 0x4d1);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553);
+
+static void __devinit pci_fixup_unassign(struct pci_dev *dev)
+{
+ dev->resource[0].end -= dev->resource[0].start;
+ dev->resource[0].start = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, pci_fixup_unassign);
+
+/*
+ * Prevent the PCI layer from seeing the resources allocated to this device
+ * if it is the host bridge by marking it as such. These resources are of
+ * no consequence to the PCI layer (they are handled elsewhere).
+ */
+static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
+{
+ int i;
+
+ if (dev->devfn == 0) {
+ dev->class &= 0xff;
+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285);
+
+/*
+ * PCI IDE controllers use non-standard I/O port decoding, respect it.
+ */
+static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
+{
+ struct resource *r;
+ int i;
+
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+ return;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ r = dev->resource + i;
+ if ((r->start & ~0x80) == 0x374) {
+ r->start |= 2;
+ r->end = r->start;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
+
+/*
+ * Put the DEC21142 to sleep
+ */
+static void __devinit pci_fixup_dec21142(struct pci_dev *dev)
+{
+ pci_write_config_dword(dev, 0x40, 0x80000000);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, pci_fixup_dec21142);
+
+/*
+ * The CY82C693 needs some rather major fixups to ensure that it does
+ * the right thing. Idea from the Alpha people, with a few additions.
+ *
+ * We ensure that the IDE base registers are set to 1f0/3f4 for the
+ * primary bus, and 170/374 for the secondary bus. Also, hide them
+ * from the PCI subsystem view as well so we won't try to perform
+ * our own auto-configuration on them.
+ *
+ * In addition, we ensure that the PCI IDE interrupts are routed to
+ * IRQ 14 and IRQ 15 respectively.
+ *
+ * The above gets us to a point where the IDE on this device is
+ * functional. However, The CY82C693U _does not work_ in bus
+ * master mode without locking the PCI bus solid.
+ */
+static void __devinit pci_fixup_cy82c693(struct pci_dev *dev)
+{
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+ u32 base0, base1;
+
+ if (dev->class & 0x80) { /* primary */
+ base0 = 0x1f0;
+ base1 = 0x3f4;
+ } else { /* secondary */
+ base0 = 0x170;
+ base1 = 0x374;
+ }
+
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+ base0 | PCI_BASE_ADDRESS_SPACE_IO);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
+ base1 | PCI_BASE_ADDRESS_SPACE_IO);
+
+ dev->resource[0].start = 0;
+ dev->resource[0].end = 0;
+ dev->resource[0].flags = 0;
+
+ dev->resource[1].start = 0;
+ dev->resource[1].end = 0;
+ dev->resource[1].flags = 0;
+ } else if (PCI_FUNC(dev->devfn) == 0) {
+ /*
+ * Setup IDE IRQ routing.
+ */
+ pci_write_config_byte(dev, 0x4b, 14);
+ pci_write_config_byte(dev, 0x4c, 15);
+
+ /*
+ * Disable FREQACK handshake, enable USB.
+ */
+ pci_write_config_byte(dev, 0x4d, 0x41);
+
+ /*
+ * Enable PCI retry, and PCI post-write buffer.
+ */
+ pci_write_config_byte(dev, 0x44, 0x17);
+
+ /*
+ * Enable ISA master and DMA post write buffering.
+ */
+ pci_write_config_byte(dev, 0x45, 0x03);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
+
+static void __init pci_fixup_it8152(struct pci_dev *dev)
+{
+ int i;
+ /* fixup for ITE 8152 devices */
+ /* FIXME: add defines for class 0x68000 and 0x80103 */
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST ||
+ dev->class == 0x68000 ||
+ dev->class == 0x80103) {
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8152, pci_fixup_it8152);
+
+
+
+void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ if (debug_pci)
+ printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev));
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/*
+ * If the bus contains any of these devices, then we must not turn on
+ * parity checking of any kind. Currently this is CyberPro 20x0 only.
+ */
+static inline int pdev_bad_for_parity(struct pci_dev *dev)
+{
+ return ((dev->vendor == PCI_VENDOR_ID_INTERG &&
+ (dev->device == PCI_DEVICE_ID_INTERG_2000 ||
+ dev->device == PCI_DEVICE_ID_INTERG_2010)) ||
+ (dev->vendor == PCI_VENDOR_ID_ITE &&
+ dev->device == PCI_DEVICE_ID_ITE_8152));
+
+}
+
+/*
+ * Adjust the device resources from bus-centric to Linux-centric.
+ */
+static void __devinit
+pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
+{
+ resource_size_t offset;
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (dev->resource[i].start == 0)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_MEM)
+ offset = root->mem_offset;
+ else
+ offset = root->io_offset;
+
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
+ }
+}
+
+static void __devinit
+pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root)
+{
+ struct pci_dev *dev = bus->self;
+ int i;
+
+ if (!dev) {
+ /*
+ * Assign root bus resources.
+ */
+ for (i = 0; i < 3; i++)
+ bus->resource[i] = root->resource[i];
+ }
+}
+
+/*
+ * pcibios_fixup_bus - Called after each bus is probed,
+ * but before its children are examined.
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+ struct pci_dev *dev;
+ u16 features = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK;
+
+ pbus_assign_bus_resources(bus, root);
+
+ /*
+ * Walk the devices on this bus, working out what we can
+ * and can't support.
+ */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ u16 status;
+
+ pdev_fixup_device_resources(root, dev);
+
+ pci_read_config_word(dev, PCI_STATUS, &status);
+
+ /*
+ * If any device on this bus does not support fast back
+ * to back transfers, then the bus as a whole is not able
+ * to support them. Having fast back to back transfers
+ * on saves us one PCI cycle per transaction.
+ */
+ if (!(status & PCI_STATUS_FAST_BACK))
+ features &= ~PCI_COMMAND_FAST_BACK;
+
+ if (pdev_bad_for_parity(dev))
+ features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+
+ switch (dev->class >> 8) {
+ case PCI_CLASS_BRIDGE_PCI:
+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status);
+ status |= PCI_BRIDGE_CTL_PARITY|PCI_BRIDGE_CTL_MASTER_ABORT;
+ status &= ~(PCI_BRIDGE_CTL_BUS_RESET|PCI_BRIDGE_CTL_FAST_BACK);
+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status);
+ break;
+
+ case PCI_CLASS_BRIDGE_CARDBUS:
+ pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL, &status);
+ status |= PCI_CB_BRIDGE_CTL_PARITY|PCI_CB_BRIDGE_CTL_MASTER_ABORT;
+ pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL, status);
+ break;
+ }
+ }
+
+ /*
+ * Now walk the devices again, this time setting them up.
+ */
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ u16 cmd;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd |= features;
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ L1_CACHE_BYTES >> 2);
+ }
+
+ /*
+ * Propagate the flags to the PCI bridge.
+ */
+ if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ if (features & PCI_COMMAND_FAST_BACK)
+ bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK;
+ if (features & PCI_COMMAND_PARITY)
+ bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY;
+ }
+
+ /*
+ * Report what we did for this bus
+ */
+ printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n",
+ bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
+}
+
+/*
+ * Convert from Linux-centric to bus-centric addresses for bridge devices.
+ */
+void
+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+ struct resource *res)
+{
+ struct pci_sys_data *root = dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = root->io_offset;
+ if (res->flags & IORESOURCE_MEM)
+ offset = root->mem_offset;
+
+ region->start = res->start - offset;
+ region->end = res->end - offset;
+}
+
+void __devinit
+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+ struct pci_bus_region *region)
+{
+ struct pci_sys_data *root = dev->sysdata;
+ unsigned long offset = 0;
+
+ if (res->flags & IORESOURCE_IO)
+ offset = root->io_offset;
+ if (res->flags & IORESOURCE_MEM)
+ offset = root->mem_offset;
+
+ res->start = region->start + offset;
+ res->end = region->end + offset;
+}
+
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pcibios_fixup_bus);
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+#endif
+
+/*
+ * Swizzle the device pin each time we cross a bridge.
+ * This might update pin and returns the slot number.
+ */
+static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ struct pci_sys_data *sys = dev->sysdata;
+ int slot = 0, oldpin = *pin;
+
+ if (sys->swizzle)
+ slot = sys->swizzle(dev, pin);
+
+ if (debug_pci)
+ printk("PCI: %s swizzling pin %d => pin %d slot %d\n",
+ pci_name(dev), oldpin, *pin, slot);
+
+ return slot;
+}
+
+/*
+ * Map a slot/pin to an IRQ.
+ */
+static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct pci_sys_data *sys = dev->sysdata;
+ int irq = -1;
+
+ if (sys->map_irq)
+ irq = sys->map_irq(dev, slot, pin);
+
+ if (debug_pci)
+ printk("PCI: %s mapping slot %d pin %d => irq %d\n",
+ pci_name(dev), slot, pin, irq);
+
+ return irq;
+}
+
+static void __init pcibios_init_hw(struct hw_pci *hw)
+{
+ struct pci_sys_data *sys = NULL;
+ int ret;
+ int nr, busnr;
+
+ for (nr = busnr = 0; nr < hw->nr_controllers; nr++) {
+ sys = kzalloc(sizeof(struct pci_sys_data), GFP_KERNEL);
+ if (!sys)
+ panic("PCI: unable to allocate sys data!");
+
+#ifdef CONFIG_PCI_DOMAINS
+ sys->domain = hw->domain;
+#endif
+ sys->hw = hw;
+ sys->busnr = busnr;
+ sys->swizzle = hw->swizzle;
+ sys->map_irq = hw->map_irq;
+ sys->resource[0] = &ioport_resource;
+ sys->resource[1] = &iomem_resource;
+
+ ret = hw->setup(nr, sys);
+
+ if (ret > 0) {
+ sys->bus = hw->scan(nr, sys);
+
+ if (!sys->bus)
+ panic("PCI: unable to scan bus!");
+
+ busnr = sys->bus->subordinate + 1;
+
+ list_add(&sys->node, &hw->buses);
+ } else {
+ kfree(sys);
+ if (ret < 0)
+ break;
+ }
+ }
+}
+
+void __init pci_common_init(struct hw_pci *hw)
+{
+ struct pci_sys_data *sys;
+
+ INIT_LIST_HEAD(&hw->buses);
+
+ if (hw->preinit)
+ hw->preinit();
+ pcibios_init_hw(hw);
+ if (hw->postinit)
+ hw->postinit();
+
+ pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
+
+ list_for_each_entry(sys, &hw->buses, node) {
+ struct pci_bus *bus = sys->bus;
+
+ if (!use_firmware) {
+ /*
+ * Size the bridge windows.
+ */
+ pci_bus_size_bridges(bus);
+
+ /*
+ * Assign resources.
+ */
+ pci_bus_assign_resources(bus);
+
+ /*
+ * Enable bridges
+ */
+ pci_enable_bridges(bus);
+ }
+
+ /*
+ * Tell drivers about devices found.
+ */
+ pci_bus_add_devices(bus);
+ }
+}
+
+char * __init pcibios_setup(char *str)
+{
+ if (!strcmp(str, "debug")) {
+ debug_pci = 1;
+ return NULL;
+ } else if (!strcmp(str, "firmware")) {
+ use_firmware = 1;
+ return NULL;
+ }
+ return str;
+}
+
+/*
+ * From arch/i386/kernel/pci-i386.c:
+ *
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might be mirrored at 0x0100-0x03ff..
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ resource_size_t start = res->start;
+
+ if (res->flags & IORESOURCE_IO && start & 0x300)
+ start = (start + 0x3ff) & ~0x3ff;
+
+ start = (start + align - 1) & ~(align - 1);
+
+ return start;
+}
+
+/**
+ * pcibios_enable_device - Enable I/O and memory.
+ * @dev: PCI device to be enabled
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx = 0; idx < 6; idx++) {
+ /* Only set up the requested stuff */
+ if (!(mask & (1 << idx)))
+ continue;
+
+ r = dev->resource + idx;
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available because"
+ " of resource collisions\n", pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+
+ /*
+ * Bridges (eg, cardbus bridges) need to be fully enabled
+ */
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+ cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+
+ if (cmd != old_cmd) {
+ printk("PCI: enabling device %s (%04x -> %04x)\n",
+ pci_name(dev), old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state, int write_combine)
+{
+ struct pci_sys_data *root = dev->sysdata;
+ unsigned long phys;
+
+ if (mmap_state == pci_mmap_io) {
+ return -EINVAL;
+ } else {
+ phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT);
+ }
+
+ /*
+ * Mark this as IO
+ */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, phys,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
new file mode 100644
index 00000000..80f7896c
--- /dev/null
+++ b/arch/arm/kernel/calls.S
@@ -0,0 +1,394 @@
+/*
+ * linux/arch/arm/kernel/calls.S
+ *
+ * Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is included thrice in entry-common.S
+ */
+/* 0 */ CALL(sys_restart_syscall)
+ CALL(sys_exit)
+ CALL(sys_fork_wrapper)
+ CALL(sys_read)
+ CALL(sys_write)
+/* 5 */ CALL(sys_open)
+ CALL(sys_close)
+ CALL(sys_ni_syscall) /* was sys_waitpid */
+ CALL(sys_creat)
+ CALL(sys_link)
+/* 10 */ CALL(sys_unlink)
+ CALL(sys_execve_wrapper)
+ CALL(sys_chdir)
+ CALL(OBSOLETE(sys_time)) /* used by libc4 */
+ CALL(sys_mknod)
+/* 15 */ CALL(sys_chmod)
+ CALL(sys_lchown16)
+ CALL(sys_ni_syscall) /* was sys_break */
+ CALL(sys_ni_syscall) /* was sys_stat */
+ CALL(sys_lseek)
+/* 20 */ CALL(sys_getpid)
+ CALL(sys_mount)
+ CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
+ CALL(sys_setuid16)
+ CALL(sys_getuid16)
+/* 25 */ CALL(OBSOLETE(sys_stime))
+ CALL(sys_ptrace)
+ CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
+ CALL(sys_ni_syscall) /* was sys_fstat */
+ CALL(sys_pause)
+/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
+ CALL(sys_ni_syscall) /* was sys_stty */
+ CALL(sys_ni_syscall) /* was sys_getty */
+ CALL(sys_access)
+ CALL(sys_nice)
+/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */
+ CALL(sys_sync)
+ CALL(sys_kill)
+ CALL(sys_rename)
+ CALL(sys_mkdir)
+/* 40 */ CALL(sys_rmdir)
+ CALL(sys_dup)
+ CALL(sys_pipe)
+ CALL(sys_times)
+ CALL(sys_ni_syscall) /* was sys_prof */
+/* 45 */ CALL(sys_brk)
+ CALL(sys_setgid16)
+ CALL(sys_getgid16)
+ CALL(sys_ni_syscall) /* was sys_signal */
+ CALL(sys_geteuid16)
+/* 50 */ CALL(sys_getegid16)
+ CALL(sys_acct)
+ CALL(sys_umount)
+ CALL(sys_ni_syscall) /* was sys_lock */
+ CALL(sys_ioctl)
+/* 55 */ CALL(sys_fcntl)
+ CALL(sys_ni_syscall) /* was sys_mpx */
+ CALL(sys_setpgid)
+ CALL(sys_ni_syscall) /* was sys_ulimit */
+ CALL(sys_ni_syscall) /* was sys_olduname */
+/* 60 */ CALL(sys_umask)
+ CALL(sys_chroot)
+ CALL(sys_ustat)
+ CALL(sys_dup2)
+ CALL(sys_getppid)
+/* 65 */ CALL(sys_getpgrp)
+ CALL(sys_setsid)
+ CALL(sys_sigaction)
+ CALL(sys_ni_syscall) /* was sys_sgetmask */
+ CALL(sys_ni_syscall) /* was sys_ssetmask */
+/* 70 */ CALL(sys_setreuid16)
+ CALL(sys_setregid16)
+ CALL(sys_sigsuspend)
+ CALL(sys_sigpending)
+ CALL(sys_sethostname)
+/* 75 */ CALL(sys_setrlimit)
+ CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
+ CALL(sys_getrusage)
+ CALL(sys_gettimeofday)
+ CALL(sys_settimeofday)
+/* 80 */ CALL(sys_getgroups16)
+ CALL(sys_setgroups16)
+ CALL(OBSOLETE(sys_old_select)) /* used by libc4 */
+ CALL(sys_symlink)
+ CALL(sys_ni_syscall) /* was sys_lstat */
+/* 85 */ CALL(sys_readlink)
+ CALL(sys_uselib)
+ CALL(sys_swapon)
+ CALL(sys_reboot)
+ CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */
+/* 90 */ CALL(OBSOLETE(sys_old_mmap)) /* used by libc4 */
+ CALL(sys_munmap)
+ CALL(sys_truncate)
+ CALL(sys_ftruncate)
+ CALL(sys_fchmod)
+/* 95 */ CALL(sys_fchown16)
+ CALL(sys_getpriority)
+ CALL(sys_setpriority)
+ CALL(sys_ni_syscall) /* was sys_profil */
+ CALL(sys_statfs)
+/* 100 */ CALL(sys_fstatfs)
+ CALL(sys_ni_syscall) /* sys_ioperm */
+ CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
+ CALL(sys_syslog)
+ CALL(sys_setitimer)
+/* 105 */ CALL(sys_getitimer)
+ CALL(sys_newstat)
+ CALL(sys_newlstat)
+ CALL(sys_newfstat)
+ CALL(sys_ni_syscall) /* was sys_uname */
+/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
+ CALL(sys_vhangup)
+ CALL(sys_ni_syscall)
+ CALL(OBSOLETE(sys_syscall)) /* call a syscall */
+ CALL(sys_wait4)
+/* 115 */ CALL(sys_swapoff)
+ CALL(sys_sysinfo)
+ CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
+ CALL(sys_fsync)
+ CALL(sys_sigreturn_wrapper)
+/* 120 */ CALL(sys_clone_wrapper)
+ CALL(sys_setdomainname)
+ CALL(sys_newuname)
+ CALL(sys_ni_syscall) /* modify_ldt */
+ CALL(sys_adjtimex)
+/* 125 */ CALL(sys_mprotect)
+ CALL(sys_sigprocmask)
+ CALL(sys_ni_syscall) /* was sys_create_module */
+ CALL(sys_init_module)
+ CALL(sys_delete_module)
+/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */
+ CALL(sys_quotactl)
+ CALL(sys_getpgid)
+ CALL(sys_fchdir)
+ CALL(sys_bdflush)
+/* 135 */ CALL(sys_sysfs)
+ CALL(sys_personality)
+ CALL(sys_ni_syscall) /* reserved for afs_syscall */
+ CALL(sys_setfsuid16)
+ CALL(sys_setfsgid16)
+/* 140 */ CALL(sys_llseek)
+ CALL(sys_getdents)
+ CALL(sys_select)
+ CALL(sys_flock)
+ CALL(sys_msync)
+/* 145 */ CALL(sys_readv)
+ CALL(sys_writev)
+ CALL(sys_getsid)
+ CALL(sys_fdatasync)
+ CALL(sys_sysctl)
+/* 150 */ CALL(sys_mlock)
+ CALL(sys_munlock)
+ CALL(sys_mlockall)
+ CALL(sys_munlockall)
+ CALL(sys_sched_setparam)
+/* 155 */ CALL(sys_sched_getparam)
+ CALL(sys_sched_setscheduler)
+ CALL(sys_sched_getscheduler)
+ CALL(sys_sched_yield)
+ CALL(sys_sched_get_priority_max)
+/* 160 */ CALL(sys_sched_get_priority_min)
+ CALL(sys_sched_rr_get_interval)
+ CALL(sys_nanosleep)
+ CALL(sys_mremap)
+ CALL(sys_setresuid16)
+/* 165 */ CALL(sys_getresuid16)
+ CALL(sys_ni_syscall) /* vm86 */
+ CALL(sys_ni_syscall) /* was sys_query_module */
+ CALL(sys_poll)
+ CALL(sys_nfsservctl)
+/* 170 */ CALL(sys_setresgid16)
+ CALL(sys_getresgid16)
+ CALL(sys_prctl)
+ CALL(sys_rt_sigreturn_wrapper)
+ CALL(sys_rt_sigaction)
+/* 175 */ CALL(sys_rt_sigprocmask)
+ CALL(sys_rt_sigpending)
+ CALL(sys_rt_sigtimedwait)
+ CALL(sys_rt_sigqueueinfo)
+ CALL(sys_rt_sigsuspend)
+/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
+ CALL(ABI(sys_pwrite64, sys_oabi_pwrite64))
+ CALL(sys_chown16)
+ CALL(sys_getcwd)
+ CALL(sys_capget)
+/* 185 */ CALL(sys_capset)
+ CALL(sys_sigaltstack_wrapper)
+ CALL(sys_sendfile)
+ CALL(sys_ni_syscall) /* getpmsg */
+ CALL(sys_ni_syscall) /* putpmsg */
+/* 190 */ CALL(sys_vfork_wrapper)
+ CALL(sys_getrlimit)
+ CALL(sys_mmap2)
+ CALL(ABI(sys_truncate64, sys_oabi_truncate64))
+ CALL(ABI(sys_ftruncate64, sys_oabi_ftruncate64))
+/* 195 */ CALL(ABI(sys_stat64, sys_oabi_stat64))
+ CALL(ABI(sys_lstat64, sys_oabi_lstat64))
+ CALL(ABI(sys_fstat64, sys_oabi_fstat64))
+ CALL(sys_lchown)
+ CALL(sys_getuid)
+/* 200 */ CALL(sys_getgid)
+ CALL(sys_geteuid)
+ CALL(sys_getegid)
+ CALL(sys_setreuid)
+ CALL(sys_setregid)
+/* 205 */ CALL(sys_getgroups)
+ CALL(sys_setgroups)
+ CALL(sys_fchown)
+ CALL(sys_setresuid)
+ CALL(sys_getresuid)
+/* 210 */ CALL(sys_setresgid)
+ CALL(sys_getresgid)
+ CALL(sys_chown)
+ CALL(sys_setuid)
+ CALL(sys_setgid)
+/* 215 */ CALL(sys_setfsuid)
+ CALL(sys_setfsgid)
+ CALL(sys_getdents64)
+ CALL(sys_pivot_root)
+ CALL(sys_mincore)
+/* 220 */ CALL(sys_madvise)
+ CALL(ABI(sys_fcntl64, sys_oabi_fcntl64))
+ CALL(sys_ni_syscall) /* TUX */
+ CALL(sys_ni_syscall)
+ CALL(sys_gettid)
+/* 225 */ CALL(ABI(sys_readahead, sys_oabi_readahead))
+ CALL(sys_setxattr)
+ CALL(sys_lsetxattr)
+ CALL(sys_fsetxattr)
+ CALL(sys_getxattr)
+/* 230 */ CALL(sys_lgetxattr)
+ CALL(sys_fgetxattr)
+ CALL(sys_listxattr)
+ CALL(sys_llistxattr)
+ CALL(sys_flistxattr)
+/* 235 */ CALL(sys_removexattr)
+ CALL(sys_lremovexattr)
+ CALL(sys_fremovexattr)
+ CALL(sys_tkill)
+ CALL(sys_sendfile64)
+/* 240 */ CALL(sys_futex)
+ CALL(sys_sched_setaffinity)
+ CALL(sys_sched_getaffinity)
+ CALL(sys_io_setup)
+ CALL(sys_io_destroy)
+/* 245 */ CALL(sys_io_getevents)
+ CALL(sys_io_submit)
+ CALL(sys_io_cancel)
+ CALL(sys_exit_group)
+ CALL(sys_lookup_dcookie)
+/* 250 */ CALL(sys_epoll_create)
+ CALL(ABI(sys_epoll_ctl, sys_oabi_epoll_ctl))
+ CALL(ABI(sys_epoll_wait, sys_oabi_epoll_wait))
+ CALL(sys_remap_file_pages)
+ CALL(sys_ni_syscall) /* sys_set_thread_area */
+/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
+ CALL(sys_set_tid_address)
+ CALL(sys_timer_create)
+ CALL(sys_timer_settime)
+ CALL(sys_timer_gettime)
+/* 260 */ CALL(sys_timer_getoverrun)
+ CALL(sys_timer_delete)
+ CALL(sys_clock_settime)
+ CALL(sys_clock_gettime)
+ CALL(sys_clock_getres)
+/* 265 */ CALL(sys_clock_nanosleep)
+ CALL(sys_statfs64_wrapper)
+ CALL(sys_fstatfs64_wrapper)
+ CALL(sys_tgkill)
+ CALL(sys_utimes)
+/* 270 */ CALL(sys_arm_fadvise64_64)
+ CALL(sys_pciconfig_iobase)
+ CALL(sys_pciconfig_read)
+ CALL(sys_pciconfig_write)
+ CALL(sys_mq_open)
+/* 275 */ CALL(sys_mq_unlink)
+ CALL(sys_mq_timedsend)
+ CALL(sys_mq_timedreceive)
+ CALL(sys_mq_notify)
+ CALL(sys_mq_getsetattr)
+/* 280 */ CALL(sys_waitid)
+ CALL(sys_socket)
+ CALL(ABI(sys_bind, sys_oabi_bind))
+ CALL(ABI(sys_connect, sys_oabi_connect))
+ CALL(sys_listen)
+/* 285 */ CALL(sys_accept)
+ CALL(sys_getsockname)
+ CALL(sys_getpeername)
+ CALL(sys_socketpair)
+ CALL(sys_send)
+/* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto))
+ CALL(sys_recv)
+ CALL(sys_recvfrom)
+ CALL(sys_shutdown)
+ CALL(sys_setsockopt)
+/* 295 */ CALL(sys_getsockopt)
+ CALL(ABI(sys_sendmsg, sys_oabi_sendmsg))
+ CALL(sys_recvmsg)
+ CALL(ABI(sys_semop, sys_oabi_semop))
+ CALL(sys_semget)
+/* 300 */ CALL(sys_semctl)
+ CALL(sys_msgsnd)
+ CALL(sys_msgrcv)
+ CALL(sys_msgget)
+ CALL(sys_msgctl)
+/* 305 */ CALL(sys_shmat)
+ CALL(sys_shmdt)
+ CALL(sys_shmget)
+ CALL(sys_shmctl)
+ CALL(sys_add_key)
+/* 310 */ CALL(sys_request_key)
+ CALL(sys_keyctl)
+ CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
+/* vserver */ CALL(sys_ni_syscall)
+ CALL(sys_ioprio_set)
+/* 315 */ CALL(sys_ioprio_get)
+ CALL(sys_inotify_init)
+ CALL(sys_inotify_add_watch)
+ CALL(sys_inotify_rm_watch)
+ CALL(sys_mbind)
+/* 320 */ CALL(sys_get_mempolicy)
+ CALL(sys_set_mempolicy)
+ CALL(sys_openat)
+ CALL(sys_mkdirat)
+ CALL(sys_mknodat)
+/* 325 */ CALL(sys_fchownat)
+ CALL(sys_futimesat)
+ CALL(ABI(sys_fstatat64, sys_oabi_fstatat64))
+ CALL(sys_unlinkat)
+ CALL(sys_renameat)
+/* 330 */ CALL(sys_linkat)
+ CALL(sys_symlinkat)
+ CALL(sys_readlinkat)
+ CALL(sys_fchmodat)
+ CALL(sys_faccessat)
+/* 335 */ CALL(sys_pselect6)
+ CALL(sys_ppoll)
+ CALL(sys_unshare)
+ CALL(sys_set_robust_list)
+ CALL(sys_get_robust_list)
+/* 340 */ CALL(sys_splice)
+ CALL(sys_sync_file_range2)
+ CALL(sys_tee)
+ CALL(sys_vmsplice)
+ CALL(sys_move_pages)
+/* 345 */ CALL(sys_getcpu)
+ CALL(sys_epoll_pwait)
+ CALL(sys_kexec_load)
+ CALL(sys_utimensat)
+ CALL(sys_signalfd)
+/* 350 */ CALL(sys_timerfd_create)
+ CALL(sys_eventfd)
+ CALL(sys_fallocate)
+ CALL(sys_timerfd_settime)
+ CALL(sys_timerfd_gettime)
+/* 355 */ CALL(sys_signalfd4)
+ CALL(sys_eventfd2)
+ CALL(sys_epoll_create1)
+ CALL(sys_dup3)
+ CALL(sys_pipe2)
+/* 360 */ CALL(sys_inotify_init1)
+ CALL(sys_preadv)
+ CALL(sys_pwritev)
+ CALL(sys_rt_tgsigqueueinfo)
+ CALL(sys_perf_event_open)
+/* 365 */ CALL(sys_recvmmsg)
+ CALL(sys_accept4)
+ CALL(sys_fanotify_init)
+ CALL(sys_fanotify_mark)
+ CALL(sys_prlimit64)
+/* 370 */ CALL(sys_name_to_handle_at)
+ CALL(sys_open_by_handle_at)
+ CALL(sys_clock_adjtime)
+ CALL(sys_syncfs)
+ CALL(sys_sendmmsg)
+/* 375 */ CALL(sys_setns)
+#ifndef syscalls_counted
+.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
+#define syscalls_counted
+#endif
+.rept syscalls_padding
+ CALL(sys_ni_syscall)
+.endr
diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/compat.c
new file mode 100644
index 00000000..92565231
--- /dev/null
+++ b/arch/arm/kernel/compat.c
@@ -0,0 +1,219 @@
+/*
+ * linux/arch/arm/kernel/compat.c
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * We keep the old params compatibility cruft in one place (here)
+ * so we don't end up with lots of mess around other places.
+ *
+ * NOTE:
+ * The old struct param_struct is deprecated, but it will be kept in
+ * the kernel for 5 years from now (2001). This will allow boot loaders
+ * to convert to the new struct tag way.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+
+#include <asm/mach/arch.h>
+
+#include "compat.h"
+
+/*
+ * Usage:
+ * - do not go blindly adding fields, add them at the end
+ * - when adding fields, don't rely on the address until
+ * a patch from me has been released
+ * - unused fields should be zero (for future expansion)
+ * - this structure is relatively short-lived - only
+ * guaranteed to contain useful data in setup_arch()
+ *
+ * This is the old deprecated way to pass parameters to the kernel
+ */
+struct param_struct {
+ union {
+ struct {
+ unsigned long page_size; /* 0 */
+ unsigned long nr_pages; /* 4 */
+ unsigned long ramdisk_size; /* 8 */
+ unsigned long flags; /* 12 */
+#define FLAG_READONLY 1
+#define FLAG_RDLOAD 4
+#define FLAG_RDPROMPT 8
+ unsigned long rootdev; /* 16 */
+ unsigned long video_num_cols; /* 20 */
+ unsigned long video_num_rows; /* 24 */
+ unsigned long video_x; /* 28 */
+ unsigned long video_y; /* 32 */
+ unsigned long memc_control_reg; /* 36 */
+ unsigned char sounddefault; /* 40 */
+ unsigned char adfsdrives; /* 41 */
+ unsigned char bytes_per_char_h; /* 42 */
+ unsigned char bytes_per_char_v; /* 43 */
+ unsigned long pages_in_bank[4]; /* 44 */
+ unsigned long pages_in_vram; /* 60 */
+ unsigned long initrd_start; /* 64 */
+ unsigned long initrd_size; /* 68 */
+ unsigned long rd_start; /* 72 */
+ unsigned long system_rev; /* 76 */
+ unsigned long system_serial_low; /* 80 */
+ unsigned long system_serial_high; /* 84 */
+ unsigned long mem_fclk_21285; /* 88 */
+ } s;
+ char unused[256];
+ } u1;
+ union {
+ char paths[8][128];
+ struct {
+ unsigned long magic;
+ char n[1024 - sizeof(unsigned long)];
+ } s;
+ } u2;
+ char commandline[COMMAND_LINE_SIZE];
+};
+
+static struct tag * __init memtag(struct tag *tag, unsigned long start, unsigned long size)
+{
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_MEM;
+ tag->hdr.size = tag_size(tag_mem32);
+ tag->u.mem.size = size;
+ tag->u.mem.start = start;
+
+ return tag;
+}
+
+static void __init build_tag_list(struct param_struct *params, void *taglist)
+{
+ struct tag *tag = taglist;
+
+ if (params->u1.s.page_size != PAGE_SIZE) {
+ printk(KERN_WARNING "Warning: bad configuration page, "
+ "trying to continue\n");
+ return;
+ }
+
+ printk(KERN_DEBUG "Converting old-style param struct to taglist\n");
+
+#ifdef CONFIG_ARCH_NETWINDER
+ if (params->u1.s.nr_pages != 0x02000 &&
+ params->u1.s.nr_pages != 0x04000 &&
+ params->u1.s.nr_pages != 0x08000 &&
+ params->u1.s.nr_pages != 0x10000) {
+ printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+ "detected, using defaults\n");
+
+ params->u1.s.nr_pages = 0x1000; /* 16MB */
+ params->u1.s.ramdisk_size = 0;
+ params->u1.s.flags = FLAG_READONLY;
+ params->u1.s.initrd_start = 0;
+ params->u1.s.initrd_size = 0;
+ params->u1.s.rd_start = 0;
+ }
+#endif
+
+ tag->hdr.tag = ATAG_CORE;
+ tag->hdr.size = tag_size(tag_core);
+ tag->u.core.flags = params->u1.s.flags & FLAG_READONLY;
+ tag->u.core.pagesize = params->u1.s.page_size;
+ tag->u.core.rootdev = params->u1.s.rootdev;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_RAMDISK;
+ tag->hdr.size = tag_size(tag_ramdisk);
+ tag->u.ramdisk.flags = (params->u1.s.flags & FLAG_RDLOAD ? 1 : 0) |
+ (params->u1.s.flags & FLAG_RDPROMPT ? 2 : 0);
+ tag->u.ramdisk.size = params->u1.s.ramdisk_size;
+ tag->u.ramdisk.start = params->u1.s.rd_start;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_INITRD;
+ tag->hdr.size = tag_size(tag_initrd);
+ tag->u.initrd.start = params->u1.s.initrd_start;
+ tag->u.initrd.size = params->u1.s.initrd_size;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_SERIAL;
+ tag->hdr.size = tag_size(tag_serialnr);
+ tag->u.serialnr.low = params->u1.s.system_serial_low;
+ tag->u.serialnr.high = params->u1.s.system_serial_high;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_REVISION;
+ tag->hdr.size = tag_size(tag_revision);
+ tag->u.revision.rev = params->u1.s.system_rev;
+
+#ifdef CONFIG_ARCH_ACORN
+ if (machine_is_riscpc()) {
+ int i;
+ for (i = 0; i < 4; i++)
+ tag = memtag(tag, PHYS_OFFSET + (i << 26),
+ params->u1.s.pages_in_bank[i] * PAGE_SIZE);
+ } else
+#endif
+ tag = memtag(tag, PHYS_OFFSET, params->u1.s.nr_pages * PAGE_SIZE);
+
+#ifdef CONFIG_FOOTBRIDGE
+ if (params->u1.s.mem_fclk_21285) {
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_MEMCLK;
+ tag->hdr.size = tag_size(tag_memclk);
+ tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285;
+ }
+#endif
+
+#ifdef CONFIG_ARCH_EBSA285
+ if (machine_is_ebsa285()) {
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_VIDEOTEXT;
+ tag->hdr.size = tag_size(tag_videotext);
+ tag->u.videotext.x = params->u1.s.video_x;
+ tag->u.videotext.y = params->u1.s.video_y;
+ tag->u.videotext.video_page = 0;
+ tag->u.videotext.video_mode = 0;
+ tag->u.videotext.video_cols = params->u1.s.video_num_cols;
+ tag->u.videotext.video_ega_bx = 0;
+ tag->u.videotext.video_lines = params->u1.s.video_num_rows;
+ tag->u.videotext.video_isvga = 1;
+ tag->u.videotext.video_points = 8;
+ }
+#endif
+
+#ifdef CONFIG_ARCH_ACORN
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_ACORN;
+ tag->hdr.size = tag_size(tag_acorn);
+ tag->u.acorn.memc_control_reg = params->u1.s.memc_control_reg;
+ tag->u.acorn.vram_pages = params->u1.s.pages_in_vram;
+ tag->u.acorn.sounddefault = params->u1.s.sounddefault;
+ tag->u.acorn.adfsdrives = params->u1.s.adfsdrives;
+#endif
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_CMDLINE;
+ tag->hdr.size = (strlen(params->commandline) + 3 +
+ sizeof(struct tag_header)) >> 2;
+ strcpy(tag->u.cmdline.cmdline, params->commandline);
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_NONE;
+ tag->hdr.size = 0;
+
+ memmove(params, taglist, ((int)tag) - ((int)taglist) +
+ sizeof(struct tag_header));
+}
+
+void __init convert_to_tag_list(struct tag *tags)
+{
+ struct param_struct *params = (struct param_struct *)tags;
+ build_tag_list(params, &params->u2);
+}
diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h
new file mode 100644
index 00000000..39264ab1
--- /dev/null
+++ b/arch/arm/kernel/compat.h
@@ -0,0 +1,11 @@
+/*
+ * linux/arch/arm/kernel/compat.h
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void convert_to_tag_list(struct tag *tags);
diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
new file mode 100644
index 00000000..90c50d4b
--- /dev/null
+++ b/arch/arm/kernel/crash_dump.c
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/kernel/crash_dump.c
+ *
+ * Copyright (C) 2010 Nokia Corporation.
+ * Author: Mika Westerberg
+ *
+ * This code is taken from arch/x86/kernel/crash_dump_64.c
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ * Copyright (C) IBM Corporation, 2004. 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/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+/**
+ * copy_oldmem_page() - copy one page from old kernel memory
+ * @pfn: page frame number to be copied
+ * @buf: buffer where the copied page is placed
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page
+ * @userbuf: if set, @buf is int he user address space
+ *
+ * This function copies one page from old kernel memory into buffer pointed by
+ * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
+ * copied or negative error in case of failure.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ size_t csize, unsigned long offset,
+ int userbuf)
+{
+ void *vaddr;
+
+ if (!csize)
+ return 0;
+
+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+ if (!vaddr)
+ return -ENOMEM;
+
+ if (userbuf) {
+ if (copy_to_user(buf, vaddr + offset, csize)) {
+ iounmap(vaddr);
+ return -EFAULT;
+ }
+ } else {
+ memcpy(buf, vaddr + offset, csize);
+ }
+
+ iounmap(vaddr);
+ return csize;
+}
diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/kernel/crunch-bits.S
new file mode 100644
index 00000000..0ec9bb48
--- /dev/null
+++ b/arch/arm/kernel/crunch-bits.S
@@ -0,0 +1,305 @@
+/*
+ * arch/arm/kernel/crunch-bits.S
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is
+ * Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <mach/ep93xx-regs.h>
+
+/*
+ * We can't use hex constants here due to a bug in gas.
+ */
+#define CRUNCH_MVDX0 0
+#define CRUNCH_MVDX1 8
+#define CRUNCH_MVDX2 16
+#define CRUNCH_MVDX3 24
+#define CRUNCH_MVDX4 32
+#define CRUNCH_MVDX5 40
+#define CRUNCH_MVDX6 48
+#define CRUNCH_MVDX7 56
+#define CRUNCH_MVDX8 64
+#define CRUNCH_MVDX9 72
+#define CRUNCH_MVDX10 80
+#define CRUNCH_MVDX11 88
+#define CRUNCH_MVDX12 96
+#define CRUNCH_MVDX13 104
+#define CRUNCH_MVDX14 112
+#define CRUNCH_MVDX15 120
+#define CRUNCH_MVAX0L 128
+#define CRUNCH_MVAX0M 132
+#define CRUNCH_MVAX0H 136
+#define CRUNCH_MVAX1L 140
+#define CRUNCH_MVAX1M 144
+#define CRUNCH_MVAX1H 148
+#define CRUNCH_MVAX2L 152
+#define CRUNCH_MVAX2M 156
+#define CRUNCH_MVAX2H 160
+#define CRUNCH_MVAX3L 164
+#define CRUNCH_MVAX3M 168
+#define CRUNCH_MVAX3H 172
+#define CRUNCH_DSPSC 176
+
+#define CRUNCH_SIZE 184
+
+ .text
+
+/*
+ * Lazy switching of crunch coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9 = ret_from_exception
+ * lr = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+ENTRY(crunch_task_enable)
+ ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
+
+ ldr r1, [r8, #0x80]
+ tst r1, #0x00800000 @ access to crunch enabled?
+ movne pc, lr @ if so no business here
+ mov r3, #0xaa @ unlock syscon swlock
+ str r3, [r8, #0xc0]
+ orr r1, r1, #0x00800000 @ enable access to crunch
+ str r1, [r8, #0x80]
+
+ ldr r3, =crunch_owner
+ add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area
+ ldr r2, [sp, #60] @ current task pc value
+ ldr r1, [r3] @ get current crunch owner
+ str r0, [r3] @ this task now owns crunch
+ sub r2, r2, #4 @ adjust pc back
+ str r2, [sp, #60]
+
+ ldr r2, [r8, #0x80]
+ mov r2, r2 @ flush out enable (@@@)
+
+ teq r1, #0 @ test for last ownership
+ mov lr, r9 @ normal exit from exception
+ beq crunch_load @ no owner, skip save
+
+crunch_save:
+ cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers
+ cfstr64 mvdx1, [r1, #CRUNCH_MVDX1]
+ cfstr64 mvdx2, [r1, #CRUNCH_MVDX2]
+ cfstr64 mvdx3, [r1, #CRUNCH_MVDX3]
+ cfstr64 mvdx4, [r1, #CRUNCH_MVDX4]
+ cfstr64 mvdx5, [r1, #CRUNCH_MVDX5]
+ cfstr64 mvdx6, [r1, #CRUNCH_MVDX6]
+ cfstr64 mvdx7, [r1, #CRUNCH_MVDX7]
+ cfstr64 mvdx8, [r1, #CRUNCH_MVDX8]
+ cfstr64 mvdx9, [r1, #CRUNCH_MVDX9]
+ cfstr64 mvdx10, [r1, #CRUNCH_MVDX10]
+ cfstr64 mvdx11, [r1, #CRUNCH_MVDX11]
+ cfstr64 mvdx12, [r1, #CRUNCH_MVDX12]
+ cfstr64 mvdx13, [r1, #CRUNCH_MVDX13]
+ cfstr64 mvdx14, [r1, #CRUNCH_MVDX14]
+ cfstr64 mvdx15, [r1, #CRUNCH_MVDX15]
+
+#ifdef __ARMEB__
+#error fix me for ARMEB
+#endif
+
+ cfmv32al mvfx0, mvax0 @ save 72b accumulators
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L]
+ cfmv32am mvfx0, mvax0
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M]
+ cfmv32ah mvfx0, mvax0
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H]
+ cfmv32al mvfx0, mvax1
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L]
+ cfmv32am mvfx0, mvax1
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M]
+ cfmv32ah mvfx0, mvax1
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H]
+ cfmv32al mvfx0, mvax2
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L]
+ cfmv32am mvfx0, mvax2
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M]
+ cfmv32ah mvfx0, mvax2
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H]
+ cfmv32al mvfx0, mvax3
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L]
+ cfmv32am mvfx0, mvax3
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M]
+ cfmv32ah mvfx0, mvax3
+ cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H]
+
+ cfmv32sc mvdx0, dspsc @ save status word
+ cfstr64 mvdx0, [r1, #CRUNCH_DSPSC]
+
+ teq r0, #0 @ anything to load?
+ cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered
+ moveq pc, lr
+
+crunch_load:
+ cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word
+ cfmvsc32 dspsc, mvdx0
+
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators
+ cfmval32 mvax0, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M]
+ cfmvam32 mvax0, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H]
+ cfmvah32 mvax0, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L]
+ cfmval32 mvax1, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M]
+ cfmvam32 mvax1, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H]
+ cfmvah32 mvax1, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L]
+ cfmval32 mvax2, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M]
+ cfmvam32 mvax2, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H]
+ cfmvah32 mvax2, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L]
+ cfmval32 mvax3, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M]
+ cfmvam32 mvax3, mvfx0
+ cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H]
+ cfmvah32 mvax3, mvfx0
+
+ cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers
+ cfldr64 mvdx1, [r0, #CRUNCH_MVDX1]
+ cfldr64 mvdx2, [r0, #CRUNCH_MVDX2]
+ cfldr64 mvdx3, [r0, #CRUNCH_MVDX3]
+ cfldr64 mvdx4, [r0, #CRUNCH_MVDX4]
+ cfldr64 mvdx5, [r0, #CRUNCH_MVDX5]
+ cfldr64 mvdx6, [r0, #CRUNCH_MVDX6]
+ cfldr64 mvdx7, [r0, #CRUNCH_MVDX7]
+ cfldr64 mvdx8, [r0, #CRUNCH_MVDX8]
+ cfldr64 mvdx9, [r0, #CRUNCH_MVDX9]
+ cfldr64 mvdx10, [r0, #CRUNCH_MVDX10]
+ cfldr64 mvdx11, [r0, #CRUNCH_MVDX11]
+ cfldr64 mvdx12, [r0, #CRUNCH_MVDX12]
+ cfldr64 mvdx13, [r0, #CRUNCH_MVDX13]
+ cfldr64 mvdx14, [r0, #CRUNCH_MVDX14]
+ cfldr64 mvdx15, [r0, #CRUNCH_MVDX15]
+
+ mov pc, lr
+
+/*
+ * Back up crunch regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+ENTRY(crunch_task_disable)
+ stmfd sp!, {r4, r5, lr}
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr
+
+ ldr r3, =crunch_owner
+ add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
+ ldr r1, [r3] @ get current crunch owner
+ teq r1, #0 @ any current owner?
+ beq 1f @ no: quit
+ teq r0, #0 @ any owner?
+ teqne r1, r2 @ or specified one?
+ bne 1f @ no: quit
+
+ ldr r5, [r4, #0x80] @ enable access to crunch
+ mov r2, #0xaa
+ str r2, [r4, #0xc0]
+ orr r5, r5, #0x00800000
+ str r5, [r4, #0x80]
+
+ mov r0, #0 @ nothing to load
+ str r0, [r3] @ no more current owner
+ ldr r2, [r4, #0x80] @ flush out enable (@@@)
+ mov r2, r2
+ bl crunch_save
+
+ mov r2, #0xaa @ disable access to crunch
+ str r2, [r4, #0xc0]
+ bic r5, r5, #0x00800000
+ str r5, [r4, #0x80]
+ ldr r5, [r4, #0x80] @ flush out enable (@@@)
+ mov r5, r5
+
+1: msr cpsr_c, ip @ restore interrupt mode
+ ldmfd sp!, {r4, r5, pc}
+
+/*
+ * Copy crunch state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store crunch state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+ENTRY(crunch_task_copy)
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =crunch_owner
+ add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
+ ldr r3, [r3] @ get current crunch owner
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ current crunch values are in the task save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r1
+ mov r1, r2
+ mov r2, #CRUNCH_SIZE
+ b memcpy
+
+1: @ this task owns crunch regs -- grab a copy from there
+ mov r0, #0 @ nothing to load
+ mov r3, lr @ preserve return address
+ bl crunch_save
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
+
+/*
+ * Restore crunch state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get crunch state from
+ *
+ * this is used to restore crunch state when unwinding a signal stack frame
+ */
+ENTRY(crunch_task_restore)
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =crunch_owner
+ add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area
+ ldr r3, [r3] @ get current crunch owner
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ this task doesn't own crunch regs -- use its save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r2
+ mov r2, #CRUNCH_SIZE
+ b memcpy
+
+1: @ this task owns crunch regs -- load them directly
+ mov r0, r1
+ mov r1, #0 @ nothing to save
+ mov r3, lr @ preserve return address
+ bl crunch_load
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
new file mode 100644
index 00000000..25ef223b
--- /dev/null
+++ b/arch/arm/kernel/crunch.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/kernel/crunch.c
+ * Cirrus MaverickCrunch context switching and handling
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <mach/ep93xx-regs.h>
+#include <asm/thread_notify.h>
+
+struct crunch_state *crunch_owner;
+
+void crunch_task_release(struct thread_info *thread)
+{
+ local_irq_disable();
+ if (crunch_owner == &thread->crunchstate)
+ crunch_owner = NULL;
+ local_irq_enable();
+}
+
+static int crunch_enabled(u32 devcfg)
+{
+ return !!(devcfg & EP93XX_SYSCON_DEVCFG_CPENA);
+}
+
+static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = (struct thread_info *)t;
+ struct crunch_state *crunch_state;
+ u32 devcfg;
+
+ crunch_state = &thread->crunchstate;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ memset(crunch_state, 0, sizeof(*crunch_state));
+
+ /*
+ * FALLTHROUGH: Ensure we don't try to overwrite our newly
+ * initialised state information on the first fault.
+ */
+
+ case THREAD_NOTIFY_EXIT:
+ crunch_task_release(thread);
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ devcfg = __raw_readl(EP93XX_SYSCON_DEVCFG);
+ if (crunch_enabled(devcfg) || crunch_owner == crunch_state) {
+ /*
+ * We don't use ep93xx_syscon_swlocked_write() here
+ * because we are on the context switch path and
+ * preemption is already disabled.
+ */
+ devcfg ^= EP93XX_SYSCON_DEVCFG_CPENA;
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(devcfg, EP93XX_SYSCON_DEVCFG);
+ }
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block crunch_notifier_block = {
+ .notifier_call = crunch_do,
+};
+
+static int __init crunch_init(void)
+{
+ thread_register_notifier(&crunch_notifier_block);
+ elf_hwcap |= HWCAP_CRUNCH;
+
+ return 0;
+}
+
+late_initcall(crunch_init);
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
new file mode 100644
index 00000000..bcd66e00
--- /dev/null
+++ b/arch/arm/kernel/debug.S
@@ -0,0 +1,179 @@
+/*
+ * linux/arch/arm/kernel/debug.S
+ *
+ * Copyright (C) 1994-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 32-bit debugging code
+ */
+#include <linux/linkage.h>
+
+ .text
+
+/*
+ * Some debugging routines (useful if you've got MM problems and
+ * printk isn't working). For DEBUGGING ONLY!!! Do not leave
+ * references to these in a production kernel!
+ */
+
+#if defined(CONFIG_DEBUG_ICEDCC)
+ @@ debug using ARM EmbeddedICE DCC channel
+
+ .macro addruart, rp, rv
+ .endm
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
+
+ .macro senduart, rd, rx
+ mcr p14, 0, \rd, c0, c5, 0
+ .endm
+
+ .macro busyuart, rd, rx
+1001:
+ mrc p14, 0, \rx, c0, c1, 0
+ tst \rx, #0x20000000
+ beq 1001b
+ .endm
+
+ .macro waituart, rd, rx
+ mov \rd, #0x2000000
+1001:
+ subs \rd, \rd, #1
+ bmi 1002f
+ mrc p14, 0, \rx, c0, c1, 0
+ tst \rx, #0x20000000
+ bne 1001b
+1002:
+ .endm
+
+#elif defined(CONFIG_CPU_XSCALE)
+
+ .macro senduart, rd, rx
+ mcr p14, 0, \rd, c8, c0, 0
+ .endm
+
+ .macro busyuart, rd, rx
+1001:
+ mrc p14, 0, \rx, c14, c0, 0
+ tst \rx, #0x10000000
+ beq 1001b
+ .endm
+
+ .macro waituart, rd, rx
+ mov \rd, #0x10000000
+1001:
+ subs \rd, \rd, #1
+ bmi 1002f
+ mrc p14, 0, \rx, c14, c0, 0
+ tst \rx, #0x10000000
+ bne 1001b
+1002:
+ .endm
+
+#else
+
+ .macro senduart, rd, rx
+ mcr p14, 0, \rd, c1, c0, 0
+ .endm
+
+ .macro busyuart, rd, rx
+1001:
+ mrc p14, 0, \rx, c0, c0, 0
+ tst \rx, #2
+ beq 1001b
+
+ .endm
+
+ .macro waituart, rd, rx
+ mov \rd, #0x2000000
+1001:
+ subs \rd, \rd, #1
+ bmi 1002f
+ mrc p14, 0, \rx, c0, c0, 0
+ tst \rx, #2
+ bne 1001b
+1002:
+ .endm
+
+#endif /* CONFIG_CPU_V6 */
+
+#else
+#include <mach/debug-macro.S>
+#endif /* CONFIG_DEBUG_ICEDCC */
+
+#ifdef CONFIG_MMU
+ .macro addruart_current, rx, tmp1, tmp2
+ addruart \tmp1, \tmp2
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1
+ moveq \rx, \tmp1
+ movne \rx, \tmp2
+ .endm
+
+#else /* !CONFIG_MMU */
+ .macro addruart_current, rx, tmp1, tmp2
+ addruart \rx, \tmp1
+ .endm
+
+#endif /* CONFIG_MMU */
+
+/*
+ * Useful debugging routines
+ */
+ENTRY(printhex8)
+ mov r1, #8
+ b printhex
+ENDPROC(printhex8)
+
+ENTRY(printhex4)
+ mov r1, #4
+ b printhex
+ENDPROC(printhex4)
+
+ENTRY(printhex2)
+ mov r1, #2
+printhex: adr r2, hexbuf
+ add r3, r2, r1
+ mov r1, #0
+ strb r1, [r3]
+1: and r1, r0, #15
+ mov r0, r0, lsr #4
+ cmp r1, #10
+ addlt r1, r1, #'0'
+ addge r1, r1, #'a' - 10
+ strb r1, [r3, #-1]!
+ teq r3, r2
+ bne 1b
+ mov r0, r2
+ b printascii
+ENDPROC(printhex2)
+
+ .ltorg
+
+ENTRY(printascii)
+ addruart_current r3, r1, r2
+ b 2f
+1: waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ teq r1, #'\n'
+ moveq r1, #'\r'
+ beq 1b
+2: teq r0, #0
+ ldrneb r1, [r0], #1
+ teqne r1, #0
+ bne 1b
+ mov pc, lr
+ENDPROC(printascii)
+
+ENTRY(printch)
+ addruart_current r3, r1, r2
+ mov r1, r0
+ mov r0, #0
+ b 1b
+ENDPROC(printch)
+
+hexbuf: .space 16
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644
index 00000000..0cdd7b45
--- /dev/null
+++ b/arch/arm/kernel/devtree.c
@@ -0,0 +1,148 @@
+/*
+ * linux/arch/arm/kernel/devtree.c
+ *
+ * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ arm_add_memory(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return alloc_bootmem_align(size, align);
+}
+
+void __init arm_dt_memblock_reserve(void)
+{
+ u64 *reserve_map, base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ /* Reserve the dtb region */
+ memblock_reserve(virt_to_phys(initial_boot_params),
+ be32_to_cpu(initial_boot_params->totalsize));
+
+ /*
+ * Process the reserve map. This will probably overlap the initrd
+ * and dtb locations which are already reserved, but overlaping
+ * doesn't hurt anything
+ */
+ reserve_map = ((void*)initial_boot_params) +
+ be32_to_cpu(initial_boot_params->off_mem_rsvmap);
+ while (1) {
+ base = be64_to_cpup(reserve_map++);
+ size = be64_to_cpup(reserve_map++);
+ if (!size)
+ break;
+ memblock_reserve(base, size);
+ }
+}
+
+/**
+ * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
+ * @dt_phys: physical address of dt blob
+ *
+ * If a dtb was passed to the kernel in r2, then use it to choose the
+ * correct machine_desc and to setup the system.
+ */
+struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+ struct boot_param_header *devtree;
+ struct machine_desc *mdesc, *mdesc_best = NULL;
+ unsigned int score, mdesc_score = ~1;
+ unsigned long dt_root;
+ const char *model;
+
+ if (!dt_phys)
+ return NULL;
+
+ devtree = phys_to_virt(dt_phys);
+
+ /* check device tree validity */
+ if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
+ return NULL;
+
+ /* Search the mdescs for the 'best' compatible value match */
+ initial_boot_params = devtree;
+ dt_root = of_get_flat_dt_root();
+ for_each_machine_desc(mdesc) {
+ score = of_flat_dt_match(dt_root, mdesc->dt_compat);
+ if (score > 0 && score < mdesc_score) {
+ mdesc_best = mdesc;
+ mdesc_score = score;
+ }
+ }
+ if (!mdesc_best) {
+ const char *prop;
+ long size;
+
+ early_print("\nError: unrecognized/unsupported "
+ "device tree compatible list:\n[ ");
+
+ prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
+ while (size > 0) {
+ early_print("'%s' ", prop);
+ size -= strlen(prop) + 1;
+ prop += strlen(prop) + 1;
+ }
+ early_print("]\n\n");
+
+ dump_machine_table(); /* does not return */
+ }
+
+ model = of_get_flat_dt_prop(dt_root, "model", NULL);
+ if (!model)
+ model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
+ if (!model)
+ model = "<unknown>";
+ pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+ /* Retrieve various information from the /chosen node */
+ of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
+ /* Initialize {size,address}-cells info */
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ /* Setup memory, calling early_init_dt_add_memory_arch */
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+ /* Change machine number to match the mdesc we're using */
+ __machine_arch_type = mdesc_best->nr;
+
+ return mdesc_best;
+}
+
+/**
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
new file mode 100644
index 00000000..360bb6d7
--- /dev/null
+++ b/arch/arm/kernel/dma-isa.c
@@ -0,0 +1,222 @@
+/*
+ * linux/arch/arm/kernel/dma-isa.c
+ *
+ * Copyright (C) 1999-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ISA DMA primitives
+ * Taken from various sources, including:
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen and John Boyd,
+ * Nov. 1992.
+ * arch/arm/kernel/dma-ebsa285.c
+ * Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+#define ISA_DMA_MASK 0
+#define ISA_DMA_MODE 1
+#define ISA_DMA_CLRFF 2
+#define ISA_DMA_PGHI 3
+#define ISA_DMA_PGLO 4
+#define ISA_DMA_ADDR 5
+#define ISA_DMA_COUNT 6
+
+static unsigned int isa_dma_port[8][7] = {
+ /* MASK MODE CLRFF PAGE_HI PAGE_LO ADDR COUNT */
+ { 0x0a, 0x0b, 0x0c, 0x487, 0x087, 0x00, 0x01 },
+ { 0x0a, 0x0b, 0x0c, 0x483, 0x083, 0x02, 0x03 },
+ { 0x0a, 0x0b, 0x0c, 0x481, 0x081, 0x04, 0x05 },
+ { 0x0a, 0x0b, 0x0c, 0x482, 0x082, 0x06, 0x07 },
+ { 0xd4, 0xd6, 0xd8, 0x000, 0x000, 0xc0, 0xc2 },
+ { 0xd4, 0xd6, 0xd8, 0x48b, 0x08b, 0xc4, 0xc6 },
+ { 0xd4, 0xd6, 0xd8, 0x489, 0x089, 0xc8, 0xca },
+ { 0xd4, 0xd6, 0xd8, 0x48a, 0x08a, 0xcc, 0xce }
+};
+
+static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
+{
+ unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
+ int count;
+
+ count = 1 + inb(io_port);
+ count |= inb(io_port) << 8;
+
+ return chan < 4 ? count : (count << 1);
+}
+
+static void isa_enable_dma(unsigned int chan, dma_t *dma)
+{
+ if (dma->invalid) {
+ unsigned long address, length;
+ unsigned int mode;
+ enum dma_data_direction direction;
+
+ mode = (chan & 3) | dma->dma_mode;
+ switch (dma->dma_mode & DMA_MODE_MASK) {
+ case DMA_MODE_READ:
+ direction = DMA_FROM_DEVICE;
+ break;
+
+ case DMA_MODE_WRITE:
+ direction = DMA_TO_DEVICE;
+ break;
+
+ case DMA_MODE_CASCADE:
+ direction = DMA_BIDIRECTIONAL;
+ break;
+
+ default:
+ direction = DMA_NONE;
+ break;
+ }
+
+ if (!dma->sg) {
+ /*
+ * Cope with ISA-style drivers which expect cache
+ * coherence.
+ */
+ dma->sg = &dma->buf;
+ dma->sgcount = 1;
+ dma->buf.length = dma->count;
+ dma->buf.dma_address = dma_map_single(NULL,
+ dma->addr, dma->count,
+ direction);
+ }
+
+ address = dma->buf.dma_address;
+ length = dma->buf.length - 1;
+
+ outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
+ outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
+
+ if (chan >= 4) {
+ address >>= 1;
+ length >>= 1;
+ }
+
+ outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
+
+ outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
+ outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
+
+ outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
+ outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
+
+ outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
+ dma->invalid = 0;
+ }
+ outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
+}
+
+static void isa_disable_dma(unsigned int chan, dma_t *dma)
+{
+ outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
+}
+
+static struct dma_ops isa_dma_ops = {
+ .type = "ISA",
+ .enable = isa_enable_dma,
+ .disable = isa_disable_dma,
+ .residue = isa_get_dma_residue,
+};
+
+static struct resource dma_resources[] = { {
+ .name = "dma1",
+ .start = 0x0000,
+ .end = 0x000f
+}, {
+ .name = "dma low page",
+ .start = 0x0080,
+ .end = 0x008f
+}, {
+ .name = "dma2",
+ .start = 0x00c0,
+ .end = 0x00df
+}, {
+ .name = "dma high page",
+ .start = 0x0480,
+ .end = 0x048f
+} };
+
+static dma_t isa_dma[8];
+
+/*
+ * ISA DMA always starts at channel 0
+ */
+void __init isa_init_dma(void)
+{
+ /*
+ * Try to autodetect presence of an ISA DMA controller.
+ * We do some minimal initialisation, and check that
+ * channel 0's DMA address registers are writeable.
+ */
+ outb(0xff, 0x0d);
+ outb(0xff, 0xda);
+
+ /*
+ * Write high and low address, and then read them back
+ * in the same order.
+ */
+ outb(0x55, 0x00);
+ outb(0xaa, 0x00);
+
+ if (inb(0) == 0x55 && inb(0) == 0xaa) {
+ unsigned int chan, i;
+
+ for (chan = 0; chan < 8; chan++) {
+ isa_dma[chan].d_ops = &isa_dma_ops;
+ isa_disable_dma(chan, NULL);
+ }
+
+ outb(0x40, 0x0b);
+ outb(0x41, 0x0b);
+ outb(0x42, 0x0b);
+ outb(0x43, 0x0b);
+
+ outb(0xc0, 0xd6);
+ outb(0x41, 0xd6);
+ outb(0x42, 0xd6);
+ outb(0x43, 0xd6);
+
+ outb(0, 0xd4);
+
+ outb(0x10, 0x08);
+ outb(0x10, 0xd0);
+
+ /*
+ * Is this correct? According to my documentation, it
+ * doesn't appear to be. It should be:
+ * outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
+ */
+ outb(0x30, 0x40b);
+ outb(0x31, 0x40b);
+ outb(0x32, 0x40b);
+ outb(0x33, 0x40b);
+ outb(0x31, 0x4d6);
+ outb(0x32, 0x4d6);
+ outb(0x33, 0x4d6);
+
+ for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
+ request_resource(&ioport_resource, dma_resources + i);
+
+ for (chan = 0; chan < 8; chan++) {
+ int ret = isa_dma_add(chan, &isa_dma[chan]);
+ if (ret)
+ printk(KERN_ERR "ISADMA%u: unable to register: %d\n",
+ chan, ret);
+ }
+
+ request_dma(DMA_ISA_CASCADE, "cascade");
+ }
+}
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
new file mode 100644
index 00000000..2c4a185f
--- /dev/null
+++ b/arch/arm/kernel/dma.c
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/arm/kernel/dma.c
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/scatterlist.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
+#include <asm/dma.h>
+
+#include <asm/mach/dma.h>
+
+DEFINE_SPINLOCK(dma_spin_lock);
+EXPORT_SYMBOL(dma_spin_lock);
+
+static dma_t *dma_chan[MAX_DMA_CHANNELS];
+
+static inline dma_t *dma_channel(unsigned int chan)
+{
+ if (chan >= MAX_DMA_CHANNELS)
+ return NULL;
+
+ return dma_chan[chan];
+}
+
+int __init isa_dma_add(unsigned int chan, dma_t *dma)
+{
+ if (!dma->d_ops)
+ return -EINVAL;
+
+ sg_init_table(&dma->buf, 1);
+
+ if (dma_chan[chan])
+ return -EBUSY;
+ dma_chan[chan] = dma;
+ return 0;
+}
+
+/*
+ * Request DMA channel
+ *
+ * On certain platforms, we have to allocate an interrupt as well...
+ */
+int request_dma(unsigned int chan, const char *device_id)
+{
+ dma_t *dma = dma_channel(chan);
+ int ret;
+
+ if (!dma)
+ goto bad_dma;
+
+ if (xchg(&dma->lock, 1) != 0)
+ goto busy;
+
+ dma->device_id = device_id;
+ dma->active = 0;
+ dma->invalid = 1;
+
+ ret = 0;
+ if (dma->d_ops->request)
+ ret = dma->d_ops->request(chan, dma);
+
+ if (ret)
+ xchg(&dma->lock, 0);
+
+ return ret;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to allocate DMA%d\n", chan);
+ return -EINVAL;
+
+busy:
+ return -EBUSY;
+}
+EXPORT_SYMBOL(request_dma);
+
+/*
+ * Free DMA channel
+ *
+ * On certain platforms, we have to free interrupt as well...
+ */
+void free_dma(unsigned int chan)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (!dma)
+ goto bad_dma;
+
+ if (dma->active) {
+ printk(KERN_ERR "dma%d: freeing active DMA\n", chan);
+ dma->d_ops->disable(chan, dma);
+ dma->active = 0;
+ }
+
+ if (xchg(&dma->lock, 0) != 0) {
+ if (dma->d_ops->free)
+ dma->d_ops->free(chan, dma);
+ return;
+ }
+
+ printk(KERN_ERR "dma%d: trying to free free DMA\n", chan);
+ return;
+
+bad_dma:
+ printk(KERN_ERR "dma: trying to free DMA%d\n", chan);
+}
+EXPORT_SYMBOL(free_dma);
+
+/* Set DMA Scatter-Gather list
+ */
+void set_dma_sg (unsigned int chan, struct scatterlist *sg, int nr_sg)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA SG while "
+ "DMA active\n", chan);
+
+ dma->sg = sg;
+ dma->sgcount = nr_sg;
+ dma->invalid = 1;
+}
+EXPORT_SYMBOL(set_dma_sg);
+
+/* Set DMA address
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void __set_dma_addr (unsigned int chan, void *addr)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA address while "
+ "DMA active\n", chan);
+
+ dma->sg = NULL;
+ dma->addr = addr;
+ dma->invalid = 1;
+}
+EXPORT_SYMBOL(__set_dma_addr);
+
+/* Set DMA byte count
+ *
+ * Copy address to the structure, and set the invalid bit
+ */
+void set_dma_count (unsigned int chan, unsigned long count)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA count while "
+ "DMA active\n", chan);
+
+ dma->sg = NULL;
+ dma->count = count;
+ dma->invalid = 1;
+}
+EXPORT_SYMBOL(set_dma_count);
+
+/* Set DMA direction mode
+ */
+void set_dma_mode (unsigned int chan, unsigned int mode)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (dma->active)
+ printk(KERN_ERR "dma%d: altering DMA mode while "
+ "DMA active\n", chan);
+
+ dma->dma_mode = mode;
+ dma->invalid = 1;
+}
+EXPORT_SYMBOL(set_dma_mode);
+
+/* Enable DMA channel
+ */
+void enable_dma (unsigned int chan)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 0) {
+ dma->active = 1;
+ dma->d_ops->enable(chan, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to enable free DMA\n", chan);
+ BUG();
+}
+EXPORT_SYMBOL(enable_dma);
+
+/* Disable DMA channel
+ */
+void disable_dma (unsigned int chan)
+{
+ dma_t *dma = dma_channel(chan);
+
+ if (!dma->lock)
+ goto free_dma;
+
+ if (dma->active == 1) {
+ dma->active = 0;
+ dma->d_ops->disable(chan, dma);
+ }
+ return;
+
+free_dma:
+ printk(KERN_ERR "dma%d: trying to disable free DMA\n", chan);
+ BUG();
+}
+EXPORT_SYMBOL(disable_dma);
+
+/*
+ * Is the specified DMA channel active?
+ */
+int dma_channel_active(unsigned int chan)
+{
+ dma_t *dma = dma_channel(chan);
+ return dma->active;
+}
+EXPORT_SYMBOL(dma_channel_active);
+
+void set_dma_page(unsigned int chan, char pagenr)
+{
+ printk(KERN_ERR "dma%d: trying to set_dma_page\n", chan);
+}
+EXPORT_SYMBOL(set_dma_page);
+
+void set_dma_speed(unsigned int chan, int cycle_ns)
+{
+ dma_t *dma = dma_channel(chan);
+ int ret = 0;
+
+ if (dma->d_ops->setspeed)
+ ret = dma->d_ops->setspeed(chan, dma, cycle_ns);
+ dma->speed = ret;
+}
+EXPORT_SYMBOL(set_dma_speed);
+
+int get_dma_residue(unsigned int chan)
+{
+ dma_t *dma = dma_channel(chan);
+ int ret = 0;
+
+ if (dma->d_ops->residue)
+ ret = dma->d_ops->residue(chan, dma);
+
+ return ret;
+}
+EXPORT_SYMBOL(get_dma_residue);
+
+#ifdef CONFIG_PROC_FS
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+ int i;
+
+ for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+ dma_t *dma = dma_channel(i);
+ if (dma && dma->lock)
+ seq_printf(m, "%2d: %s\n", i, dma->device_id);
+ }
+ return 0;
+}
+
+static int proc_dma_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_dma_show, NULL);
+}
+
+static const struct file_operations proc_dma_operations = {
+ .open = proc_dma_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init proc_dma_init(void)
+{
+ proc_create("dma", 0, NULL, &proc_dma_operations);
+ return 0;
+}
+
+__initcall(proc_dma_init);
+#endif
diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c
new file mode 100644
index 00000000..85aa2b29
--- /dev/null
+++ b/arch/arm/kernel/early_printk.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/arm/kernel/early_printk.c
+ *
+ * Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+extern void printch(int);
+
+static void early_write(const char *s, unsigned n)
+{
+ while (n-- > 0) {
+ if (*s == '\n')
+ printch('\r');
+ printch(*s);
+ s++;
+ }
+}
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+ early_write(s, n);
+}
+
+static struct console early_console = {
+ .name = "earlycon",
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1,
+};
+
+asmlinkage void early_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vscnprintf(buf, sizeof(buf), fmt, ap);
+ early_write(buf, n);
+ va_end(ap);
+}
+
+static int __init setup_early_printk(char *buf)
+{
+ register_console(&early_console);
+ return 0;
+}
+
+early_param("earlyprintk", setup_early_printk);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
new file mode 100644
index 00000000..d1650011
--- /dev/null
+++ b/arch/arm/kernel/ecard.c
@@ -0,0 +1,1241 @@
+/*
+ * linux/arch/arm/kernel/ecard.c
+ *
+ * Copyright 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Find all installed expansion cards, and handle interrupts from them.
+ *
+ * Created from information from Acorns RiscOS3 PRMs
+ *
+ * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether
+ * podule slot.
+ * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
+ * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
+ * - cards can now register their own routine to control
+ * interrupts (recommended).
+ * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
+ * on reset from Linux. (Caused cards not to respond
+ * under RiscOS without hard reset).
+ * 15-Feb-1998 RMK Added DMA support
+ * 12-Sep-1998 RMK Added EASI support
+ * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
+ * 17-Apr-1999 RMK Support for EASI Type C cycles.
+ */
+#define ECARD_C
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <linux/reboot.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/kthread.h>
+#include <linux/io.h>
+
+#include <asm/dma.h>
+#include <asm/ecard.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/mach/irq.h>
+#include <asm/tlbflush.h>
+
+#include "ecard.h"
+
+#ifndef CONFIG_ARCH_RPC
+#define HAVE_EXPMASK
+#endif
+
+struct ecard_request {
+ void (*fn)(struct ecard_request *);
+ ecard_t *ec;
+ unsigned int address;
+ unsigned int length;
+ unsigned int use_loader;
+ void *buffer;
+ struct completion *complete;
+};
+
+struct expcard_blacklist {
+ unsigned short manufacturer;
+ unsigned short product;
+ const char *type;
+};
+
+static ecard_t *cards;
+static ecard_t *slot_to_expcard[MAX_ECARDS];
+static unsigned int ectcr;
+#ifdef HAS_EXPMASK
+static unsigned int have_expmask;
+#endif
+
+/* List of descriptions of cards which don't have an extended
+ * identification, or chunk directories containing a description.
+ */
+static struct expcard_blacklist __initdata blacklist[] = {
+ { MANU_ACORN, PROD_ACORN_ETHER1, "Acorn Ether1" }
+};
+
+asmlinkage extern int
+ecard_loader_reset(unsigned long base, loader_t loader);
+asmlinkage extern int
+ecard_loader_read(int off, unsigned long base, loader_t loader);
+
+static inline unsigned short ecard_getu16(unsigned char *v)
+{
+ return v[0] | v[1] << 8;
+}
+
+static inline signed long ecard_gets24(unsigned char *v)
+{
+ return v[0] | v[1] << 8 | v[2] << 16 | ((v[2] & 0x80) ? 0xff000000 : 0);
+}
+
+static inline ecard_t *slot_to_ecard(unsigned int slot)
+{
+ return slot < MAX_ECARDS ? slot_to_expcard[slot] : NULL;
+}
+
+/* ===================== Expansion card daemon ======================== */
+/*
+ * Since the loader programs on the expansion cards need to be run
+ * in a specific environment, create a separate task with this
+ * environment up, and pass requests to this task as and when we
+ * need to.
+ *
+ * This should allow 99% of loaders to be called from Linux.
+ *
+ * From a security standpoint, we trust the card vendors. This
+ * may be a misplaced trust.
+ */
+static void ecard_task_reset(struct ecard_request *req)
+{
+ struct expansion_card *ec = req->ec;
+ struct resource *res;
+
+ res = ec->slot_no == 8
+ ? &ec->resource[ECARD_RES_MEMC]
+ : ec->easi
+ ? &ec->resource[ECARD_RES_EASI]
+ : &ec->resource[ECARD_RES_IOCSYNC];
+
+ ecard_loader_reset(res->start, ec->loader);
+}
+
+static void ecard_task_readbytes(struct ecard_request *req)
+{
+ struct expansion_card *ec = req->ec;
+ unsigned char *buf = req->buffer;
+ unsigned int len = req->length;
+ unsigned int off = req->address;
+
+ if (ec->slot_no == 8) {
+ void __iomem *base = (void __iomem *)
+ ec->resource[ECARD_RES_MEMC].start;
+
+ /*
+ * The card maintains an index which increments the address
+ * into a 4096-byte page on each access. We need to keep
+ * track of the counter.
+ */
+ static unsigned int index;
+ unsigned int page;
+
+ page = (off >> 12) * 4;
+ if (page > 256 * 4)
+ return;
+
+ off &= 4095;
+
+ /*
+ * If we are reading offset 0, or our current index is
+ * greater than the offset, reset the hardware index counter.
+ */
+ if (off == 0 || index > off) {
+ writeb(0, base);
+ index = 0;
+ }
+
+ /*
+ * Increment the hardware index counter until we get to the
+ * required offset. The read bytes are discarded.
+ */
+ while (index < off) {
+ readb(base + page);
+ index += 1;
+ }
+
+ while (len--) {
+ *buf++ = readb(base + page);
+ index += 1;
+ }
+ } else {
+ unsigned long base = (ec->easi
+ ? &ec->resource[ECARD_RES_EASI]
+ : &ec->resource[ECARD_RES_IOCSYNC])->start;
+ void __iomem *pbase = (void __iomem *)base;
+
+ if (!req->use_loader || !ec->loader) {
+ off *= 4;
+ while (len--) {
+ *buf++ = readb(pbase + off);
+ off += 4;
+ }
+ } else {
+ while(len--) {
+ /*
+ * The following is required by some
+ * expansion card loader programs.
+ */
+ *(unsigned long *)0x108 = 0;
+ *buf++ = ecard_loader_read(off++, base,
+ ec->loader);
+ }
+ }
+ }
+
+}
+
+static DECLARE_WAIT_QUEUE_HEAD(ecard_wait);
+static struct ecard_request *ecard_req;
+static DEFINE_MUTEX(ecard_mutex);
+
+/*
+ * Set up the expansion card daemon's page tables.
+ */
+static void ecard_init_pgtables(struct mm_struct *mm)
+{
+ struct vm_area_struct vma;
+
+ /* We want to set up the page tables for the following mapping:
+ * Virtual Physical
+ * 0x03000000 0x03000000
+ * 0x03010000 unmapped
+ * 0x03210000 0x03210000
+ * 0x03400000 unmapped
+ * 0x08000000 0x08000000
+ * 0x10000000 unmapped
+ *
+ * FIXME: we don't follow this 100% yet.
+ */
+ pgd_t *src_pgd, *dst_pgd;
+
+ src_pgd = pgd_offset(mm, (unsigned long)IO_BASE);
+ dst_pgd = pgd_offset(mm, IO_START);
+
+ memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE));
+
+ src_pgd = pgd_offset(mm, EASI_BASE);
+ dst_pgd = pgd_offset(mm, EASI_START);
+
+ memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE));
+
+ vma.vm_mm = mm;
+
+ flush_tlb_range(&vma, IO_START, IO_START + IO_SIZE);
+ flush_tlb_range(&vma, EASI_START, EASI_START + EASI_SIZE);
+}
+
+static int ecard_init_mm(void)
+{
+ struct mm_struct * mm = mm_alloc();
+ struct mm_struct *active_mm = current->active_mm;
+
+ if (!mm)
+ return -ENOMEM;
+
+ current->mm = mm;
+ current->active_mm = mm;
+ activate_mm(active_mm, mm);
+ mmdrop(active_mm);
+ ecard_init_pgtables(mm);
+ return 0;
+}
+
+static int
+ecard_task(void * unused)
+{
+ /*
+ * Allocate a mm. We're not a lazy-TLB kernel task since we need
+ * to set page table entries where the user space would be. Note
+ * that this also creates the page tables. Failure is not an
+ * option here.
+ */
+ if (ecard_init_mm())
+ panic("kecardd: unable to alloc mm\n");
+
+ while (1) {
+ struct ecard_request *req;
+
+ wait_event_interruptible(ecard_wait, ecard_req != NULL);
+
+ req = xchg(&ecard_req, NULL);
+ if (req != NULL) {
+ req->fn(req);
+ complete(req->complete);
+ }
+ }
+}
+
+/*
+ * Wake the expansion card daemon to action our request.
+ *
+ * FIXME: The test here is not sufficient to detect if the
+ * kcardd is running.
+ */
+static void ecard_call(struct ecard_request *req)
+{
+ DECLARE_COMPLETION_ONSTACK(completion);
+
+ req->complete = &completion;
+
+ mutex_lock(&ecard_mutex);
+ ecard_req = req;
+ wake_up(&ecard_wait);
+
+ /*
+ * Now wait for kecardd to run.
+ */
+ wait_for_completion(&completion);
+ mutex_unlock(&ecard_mutex);
+}
+
+/* ======================= Mid-level card control ===================== */
+
+static void
+ecard_readbytes(void *addr, ecard_t *ec, int off, int len, int useld)
+{
+ struct ecard_request req;
+
+ req.fn = ecard_task_readbytes;
+ req.ec = ec;
+ req.address = off;
+ req.length = len;
+ req.use_loader = useld;
+ req.buffer = addr;
+
+ ecard_call(&req);
+}
+
+int ecard_readchunk(struct in_chunk_dir *cd, ecard_t *ec, int id, int num)
+{
+ struct ex_chunk_dir excd;
+ int index = 16;
+ int useld = 0;
+
+ if (!ec->cid.cd)
+ return 0;
+
+ while(1) {
+ ecard_readbytes(&excd, ec, index, 8, useld);
+ index += 8;
+ if (c_id(&excd) == 0) {
+ if (!useld && ec->loader) {
+ useld = 1;
+ index = 0;
+ continue;
+ }
+ return 0;
+ }
+ if (c_id(&excd) == 0xf0) { /* link */
+ index = c_start(&excd);
+ continue;
+ }
+ if (c_id(&excd) == 0x80) { /* loader */
+ if (!ec->loader) {
+ ec->loader = kmalloc(c_len(&excd),
+ GFP_KERNEL);
+ if (ec->loader)
+ ecard_readbytes(ec->loader, ec,
+ (int)c_start(&excd),
+ c_len(&excd), useld);
+ else
+ return 0;
+ }
+ continue;
+ }
+ if (c_id(&excd) == id && num-- == 0)
+ break;
+ }
+
+ if (c_id(&excd) & 0x80) {
+ switch (c_id(&excd) & 0x70) {
+ case 0x70:
+ ecard_readbytes((unsigned char *)excd.d.string, ec,
+ (int)c_start(&excd), c_len(&excd),
+ useld);
+ break;
+ case 0x00:
+ break;
+ }
+ }
+ cd->start_offset = c_start(&excd);
+ memcpy(cd->d.string, excd.d.string, 256);
+ return 1;
+}
+
+/* ======================= Interrupt control ============================ */
+
+static void ecard_def_irq_enable(ecard_t *ec, int irqnr)
+{
+#ifdef HAS_EXPMASK
+ if (irqnr < 4 && have_expmask) {
+ have_expmask |= 1 << irqnr;
+ __raw_writeb(have_expmask, EXPMASK_ENABLE);
+ }
+#endif
+}
+
+static void ecard_def_irq_disable(ecard_t *ec, int irqnr)
+{
+#ifdef HAS_EXPMASK
+ if (irqnr < 4 && have_expmask) {
+ have_expmask &= ~(1 << irqnr);
+ __raw_writeb(have_expmask, EXPMASK_ENABLE);
+ }
+#endif
+}
+
+static int ecard_def_irq_pending(ecard_t *ec)
+{
+ return !ec->irqmask || readb(ec->irqaddr) & ec->irqmask;
+}
+
+static void ecard_def_fiq_enable(ecard_t *ec, int fiqnr)
+{
+ panic("ecard_def_fiq_enable called - impossible");
+}
+
+static void ecard_def_fiq_disable(ecard_t *ec, int fiqnr)
+{
+ panic("ecard_def_fiq_disable called - impossible");
+}
+
+static int ecard_def_fiq_pending(ecard_t *ec)
+{
+ return !ec->fiqmask || readb(ec->fiqaddr) & ec->fiqmask;
+}
+
+static expansioncard_ops_t ecard_default_ops = {
+ ecard_def_irq_enable,
+ ecard_def_irq_disable,
+ ecard_def_irq_pending,
+ ecard_def_fiq_enable,
+ ecard_def_fiq_disable,
+ ecard_def_fiq_pending
+};
+
+/*
+ * Enable and disable interrupts from expansion cards.
+ * (interrupts are disabled for these functions).
+ *
+ * They are not meant to be called directly, but via enable/disable_irq.
+ */
+static void ecard_irq_unmask(struct irq_data *d)
+{
+ ecard_t *ec = slot_to_ecard(d->irq - 32);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->claimed && ec->ops->irqenable)
+ ec->ops->irqenable(ec, d->irq);
+ else
+ printk(KERN_ERR "ecard: rejecting request to "
+ "enable IRQs for %d\n", d->irq);
+ }
+}
+
+static void ecard_irq_mask(struct irq_data *d)
+{
+ ecard_t *ec = slot_to_ecard(d->irq - 32);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->ops && ec->ops->irqdisable)
+ ec->ops->irqdisable(ec, d->irq);
+ }
+}
+
+static struct irq_chip ecard_chip = {
+ .name = "ECARD",
+ .irq_ack = ecard_irq_mask,
+ .irq_mask = ecard_irq_mask,
+ .irq_unmask = ecard_irq_unmask,
+};
+
+void ecard_enablefiq(unsigned int fiqnr)
+{
+ ecard_t *ec = slot_to_ecard(fiqnr);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->claimed && ec->ops->fiqenable)
+ ec->ops->fiqenable(ec, fiqnr);
+ else
+ printk(KERN_ERR "ecard: rejecting request to "
+ "enable FIQs for %d\n", fiqnr);
+ }
+}
+
+void ecard_disablefiq(unsigned int fiqnr)
+{
+ ecard_t *ec = slot_to_ecard(fiqnr);
+
+ if (ec) {
+ if (!ec->ops)
+ ec->ops = &ecard_default_ops;
+
+ if (ec->ops->fiqdisable)
+ ec->ops->fiqdisable(ec, fiqnr);
+ }
+}
+
+static void ecard_dump_irq_state(void)
+{
+ ecard_t *ec;
+
+ printk("Expansion card IRQ state:\n");
+
+ for (ec = cards; ec; ec = ec->next) {
+ if (ec->slot_no == 8)
+ continue;
+
+ printk(" %d: %sclaimed, ",
+ ec->slot_no, ec->claimed ? "" : "not ");
+
+ if (ec->ops && ec->ops->irqpending &&
+ ec->ops != &ecard_default_ops)
+ printk("irq %spending\n",
+ ec->ops->irqpending(ec) ? "" : "not ");
+ else
+ printk("irqaddr %p, mask = %02X, status = %02X\n",
+ ec->irqaddr, ec->irqmask, readb(ec->irqaddr));
+ }
+}
+
+static void ecard_check_lockup(struct irq_desc *desc)
+{
+ static unsigned long last;
+ static int lockup;
+
+ /*
+ * If the timer interrupt has not run since the last million
+ * unrecognised expansion card interrupts, then there is
+ * something seriously wrong. Disable the expansion card
+ * interrupts so at least we can continue.
+ *
+ * Maybe we ought to start a timer to re-enable them some time
+ * later?
+ */
+ if (last == jiffies) {
+ lockup += 1;
+ if (lockup > 1000000) {
+ printk(KERN_ERR "\nInterrupt lockup detected - "
+ "disabling all expansion card interrupts\n");
+
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ ecard_dump_irq_state();
+ }
+ } else
+ lockup = 0;
+
+ /*
+ * If we did not recognise the source of this interrupt,
+ * warn the user, but don't flood the user with these messages.
+ */
+ if (!last || time_after(jiffies, last + 5*HZ)) {
+ last = jiffies;
+ printk(KERN_WARNING "Unrecognised interrupt from backplane\n");
+ ecard_dump_irq_state();
+ }
+}
+
+static void
+ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ ecard_t *ec;
+ int called = 0;
+
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ for (ec = cards; ec; ec = ec->next) {
+ int pending;
+
+ if (!ec->claimed || ec->irq == NO_IRQ || ec->slot_no == 8)
+ continue;
+
+ if (ec->ops && ec->ops->irqpending)
+ pending = ec->ops->irqpending(ec);
+ else
+ pending = ecard_default_ops.irqpending(ec);
+
+ if (pending) {
+ generic_handle_irq(ec->irq);
+ called ++;
+ }
+ }
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+
+ if (called == 0)
+ ecard_check_lockup(desc);
+}
+
+#ifdef HAS_EXPMASK
+static unsigned char priority_masks[] =
+{
+ 0xf0, 0xf1, 0xf3, 0xf7, 0xff, 0xff, 0xff, 0xff
+};
+
+static unsigned char first_set[] =
+{
+ 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00
+};
+
+static void
+ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc)
+{
+ const unsigned int statusmask = 15;
+ unsigned int status;
+
+ status = __raw_readb(EXPMASK_STATUS) & statusmask;
+ if (status) {
+ unsigned int slot = first_set[status];
+ ecard_t *ec = slot_to_ecard(slot);
+
+ if (ec->claimed) {
+ /*
+ * this ugly code is so that we can operate a
+ * prioritorising system:
+ *
+ * Card 0 highest priority
+ * Card 1
+ * Card 2
+ * Card 3 lowest priority
+ *
+ * Serial cards should go in 0/1, ethernet/scsi in 2/3
+ * otherwise you will lose serial data at high speeds!
+ */
+ generic_handle_irq(ec->irq);
+ } else {
+ printk(KERN_WARNING "card%d: interrupt from unclaimed "
+ "card???\n", slot);
+ have_expmask &= ~(1 << slot);
+ __raw_writeb(have_expmask, EXPMASK_ENABLE);
+ }
+ } else
+ printk(KERN_WARNING "Wild interrupt from backplane (masks)\n");
+}
+
+static int __init ecard_probeirqhw(void)
+{
+ ecard_t *ec;
+ int found;
+
+ __raw_writeb(0x00, EXPMASK_ENABLE);
+ __raw_writeb(0xff, EXPMASK_STATUS);
+ found = (__raw_readb(EXPMASK_STATUS) & 15) == 0;
+ __raw_writeb(0xff, EXPMASK_ENABLE);
+
+ if (found) {
+ printk(KERN_DEBUG "Expansion card interrupt "
+ "management hardware found\n");
+
+ /* for each card present, set a bit to '1' */
+ have_expmask = 0x80000000;
+
+ for (ec = cards; ec; ec = ec->next)
+ have_expmask |= 1 << ec->slot_no;
+
+ __raw_writeb(have_expmask, EXPMASK_ENABLE);
+ }
+
+ return found;
+}
+#else
+#define ecard_irqexp_handler NULL
+#define ecard_probeirqhw() (0)
+#endif
+
+#ifndef IO_EC_MEMC8_BASE
+#define IO_EC_MEMC8_BASE 0
+#endif
+
+static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed)
+{
+ unsigned long address = 0;
+ int slot = ec->slot_no;
+
+ if (ec->slot_no == 8)
+ return IO_EC_MEMC8_BASE;
+
+ ectcr &= ~(1 << slot);
+
+ switch (type) {
+ case ECARD_MEMC:
+ if (slot < 4)
+ address = IO_EC_MEMC_BASE + (slot << 12);
+ break;
+
+ case ECARD_IOC:
+ if (slot < 4)
+ address = IO_EC_IOC_BASE + (slot << 12);
+#ifdef IO_EC_IOC4_BASE
+ else
+ address = IO_EC_IOC4_BASE + ((slot - 4) << 12);
+#endif
+ if (address)
+ address += speed << 17;
+ break;
+
+#ifdef IO_EC_EASI_BASE
+ case ECARD_EASI:
+ address = IO_EC_EASI_BASE + (slot << 22);
+ if (speed == ECARD_FAST)
+ ectcr |= 1 << slot;
+ break;
+#endif
+ default:
+ break;
+ }
+
+#ifdef IOMD_ECTCR
+ iomd_writeb(ectcr, IOMD_ECTCR);
+#endif
+ return address;
+}
+
+static int ecard_prints(struct seq_file *m, ecard_t *ec)
+{
+ seq_printf(m, " %d: %s ", ec->slot_no, ec->easi ? "EASI" : " ");
+
+ if (ec->cid.id == 0) {
+ struct in_chunk_dir incd;
+
+ seq_printf(m, "[%04X:%04X] ",
+ ec->cid.manufacturer, ec->cid.product);
+
+ if (!ec->card_desc && ec->cid.cd &&
+ ecard_readchunk(&incd, ec, 0xf5, 0)) {
+ ec->card_desc = kmalloc(strlen(incd.d.string)+1, GFP_KERNEL);
+
+ if (ec->card_desc)
+ strcpy((char *)ec->card_desc, incd.d.string);
+ }
+
+ seq_printf(m, "%s\n", ec->card_desc ? ec->card_desc : "*unknown*");
+ } else
+ seq_printf(m, "Simple card %d\n", ec->cid.id);
+
+ return 0;
+}
+
+static int ecard_devices_proc_show(struct seq_file *m, void *v)
+{
+ ecard_t *ec = cards;
+
+ while (ec) {
+ ecard_prints(m, ec);
+ ec = ec->next;
+ }
+ return 0;
+}
+
+static int ecard_devices_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ecard_devices_proc_show, NULL);
+}
+
+static const struct file_operations bus_ecard_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ecard_devices_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
+
+static void ecard_proc_init(void)
+{
+ proc_bus_ecard_dir = proc_mkdir("bus/ecard", NULL);
+ proc_create("devices", 0, proc_bus_ecard_dir, &bus_ecard_proc_fops);
+}
+
+#define ec_set_resource(ec,nr,st,sz) \
+ do { \
+ (ec)->resource[nr].name = dev_name(&ec->dev); \
+ (ec)->resource[nr].start = st; \
+ (ec)->resource[nr].end = (st) + (sz) - 1; \
+ (ec)->resource[nr].flags = IORESOURCE_MEM; \
+ } while (0)
+
+static void __init ecard_free_card(struct expansion_card *ec)
+{
+ int i;
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+ if (ec->resource[i].flags)
+ release_resource(&ec->resource[i]);
+
+ kfree(ec);
+}
+
+static struct expansion_card *__init ecard_alloc_card(int type, int slot)
+{
+ struct expansion_card *ec;
+ unsigned long base;
+ int i;
+
+ ec = kzalloc(sizeof(ecard_t), GFP_KERNEL);
+ if (!ec) {
+ ec = ERR_PTR(-ENOMEM);
+ goto nomem;
+ }
+
+ ec->slot_no = slot;
+ ec->easi = type == ECARD_EASI;
+ ec->irq = NO_IRQ;
+ ec->fiq = NO_IRQ;
+ ec->dma = NO_DMA;
+ ec->ops = &ecard_default_ops;
+
+ dev_set_name(&ec->dev, "ecard%d", slot);
+ ec->dev.parent = NULL;
+ ec->dev.bus = &ecard_bus_type;
+ ec->dev.dma_mask = &ec->dma_mask;
+ ec->dma_mask = (u64)0xffffffff;
+ ec->dev.coherent_dma_mask = ec->dma_mask;
+
+ if (slot < 4) {
+ ec_set_resource(ec, ECARD_RES_MEMC,
+ PODSLOT_MEMC_BASE + (slot << 14),
+ PODSLOT_MEMC_SIZE);
+ base = PODSLOT_IOC0_BASE + (slot << 14);
+ } else
+ base = PODSLOT_IOC4_BASE + ((slot - 4) << 14);
+
+#ifdef CONFIG_ARCH_RPC
+ if (slot < 8) {
+ ec_set_resource(ec, ECARD_RES_EASI,
+ PODSLOT_EASI_BASE + (slot << 24),
+ PODSLOT_EASI_SIZE);
+ }
+
+ if (slot == 8) {
+ ec_set_resource(ec, ECARD_RES_MEMC, NETSLOT_BASE, NETSLOT_SIZE);
+ } else
+#endif
+
+ for (i = 0; i <= ECARD_RES_IOCSYNC - ECARD_RES_IOCSLOW; i++)
+ ec_set_resource(ec, i + ECARD_RES_IOCSLOW,
+ base + (i << 19), PODSLOT_IOC_SIZE);
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+ if (ec->resource[i].flags &&
+ request_resource(&iomem_resource, &ec->resource[i])) {
+ dev_err(&ec->dev, "resource(s) not available\n");
+ ec->resource[i].end -= ec->resource[i].start;
+ ec->resource[i].start = 0;
+ ec->resource[i].flags = 0;
+ }
+ }
+
+ nomem:
+ return ec;
+}
+
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->irq);
+}
+
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->dma);
+}
+
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ char *str = buf;
+ int i;
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+ str += sprintf(str, "%08x %08x %08lx\n",
+ ec->resource[i].start,
+ ec->resource[i].end,
+ ec->resource[i].flags);
+
+ return str - buf;
+}
+
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->cid.manufacturer);
+}
+
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%u\n", ec->cid.product);
+}
+
+static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
+}
+
+static struct device_attribute ecard_dev_attrs[] = {
+ __ATTR(device, S_IRUGO, ecard_show_device, NULL),
+ __ATTR(dma, S_IRUGO, ecard_show_dma, NULL),
+ __ATTR(irq, S_IRUGO, ecard_show_irq, NULL),
+ __ATTR(resource, S_IRUGO, ecard_show_resources, NULL),
+ __ATTR(type, S_IRUGO, ecard_show_type, NULL),
+ __ATTR(vendor, S_IRUGO, ecard_show_vendor, NULL),
+ __ATTR_NULL,
+};
+
+
+int ecard_request_resources(struct expansion_card *ec)
+{
+ int i, err = 0;
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
+ if (ecard_resource_end(ec, i) &&
+ !request_mem_region(ecard_resource_start(ec, i),
+ ecard_resource_len(ec, i),
+ ec->dev.driver->name)) {
+ err = -EBUSY;
+ break;
+ }
+ }
+
+ if (err) {
+ while (i--)
+ if (ecard_resource_end(ec, i))
+ release_mem_region(ecard_resource_start(ec, i),
+ ecard_resource_len(ec, i));
+ }
+ return err;
+}
+EXPORT_SYMBOL(ecard_request_resources);
+
+void ecard_release_resources(struct expansion_card *ec)
+{
+ int i;
+
+ for (i = 0; i < ECARD_NUM_RESOURCES; i++)
+ if (ecard_resource_end(ec, i))
+ release_mem_region(ecard_resource_start(ec, i),
+ ecard_resource_len(ec, i));
+}
+EXPORT_SYMBOL(ecard_release_resources);
+
+void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data)
+{
+ ec->irq_data = irq_data;
+ barrier();
+ ec->ops = ops;
+}
+EXPORT_SYMBOL(ecard_setirq);
+
+void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
+ unsigned long offset, unsigned long maxsize)
+{
+ unsigned long start = ecard_resource_start(ec, res);
+ unsigned long end = ecard_resource_end(ec, res);
+
+ if (offset > (end - start))
+ return NULL;
+
+ start += offset;
+ if (maxsize && end - start > maxsize)
+ end = start + maxsize;
+
+ return devm_ioremap(&ec->dev, start, end - start);
+}
+EXPORT_SYMBOL(ecardm_iomap);
+
+/*
+ * Probe for an expansion card.
+ *
+ * If bit 1 of the first byte of the card is set, then the
+ * card does not exist.
+ */
+static int __init
+ecard_probe(int slot, card_type_t type)
+{
+ ecard_t **ecp;
+ ecard_t *ec;
+ struct ex_ecid cid;
+ int i, rc;
+
+ ec = ecard_alloc_card(type, slot);
+ if (IS_ERR(ec)) {
+ rc = PTR_ERR(ec);
+ goto nomem;
+ }
+
+ rc = -ENODEV;
+ if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0)
+ goto nodev;
+
+ cid.r_zero = 1;
+ ecard_readbytes(&cid, ec, 0, 16, 0);
+ if (cid.r_zero)
+ goto nodev;
+
+ ec->cid.id = cid.r_id;
+ ec->cid.cd = cid.r_cd;
+ ec->cid.is = cid.r_is;
+ ec->cid.w = cid.r_w;
+ ec->cid.manufacturer = ecard_getu16(cid.r_manu);
+ ec->cid.product = ecard_getu16(cid.r_prod);
+ ec->cid.country = cid.r_country;
+ ec->cid.irqmask = cid.r_irqmask;
+ ec->cid.irqoff = ecard_gets24(cid.r_irqoff);
+ ec->cid.fiqmask = cid.r_fiqmask;
+ ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff);
+ ec->fiqaddr =
+ ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr);
+
+ if (ec->cid.is) {
+ ec->irqmask = ec->cid.irqmask;
+ ec->irqaddr += ec->cid.irqoff;
+ ec->fiqmask = ec->cid.fiqmask;
+ ec->fiqaddr += ec->cid.fiqoff;
+ } else {
+ ec->irqmask = 1;
+ ec->fiqmask = 4;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(blacklist); i++)
+ if (blacklist[i].manufacturer == ec->cid.manufacturer &&
+ blacklist[i].product == ec->cid.product) {
+ ec->card_desc = blacklist[i].type;
+ break;
+ }
+
+ /*
+ * hook the interrupt handlers
+ */
+ if (slot < 8) {
+ ec->irq = 32 + slot;
+ irq_set_chip_and_handler(ec->irq, &ecard_chip,
+ handle_level_irq);
+ set_irq_flags(ec->irq, IRQF_VALID);
+ }
+
+#ifdef IO_EC_MEMC8_BASE
+ if (slot == 8)
+ ec->irq = 11;
+#endif
+#ifdef CONFIG_ARCH_RPC
+ /* On RiscPC, only first two slots have DMA capability */
+ if (slot < 2)
+ ec->dma = 2 + slot;
+#endif
+
+ for (ecp = &cards; *ecp; ecp = &(*ecp)->next);
+
+ *ecp = ec;
+ slot_to_expcard[slot] = ec;
+
+ device_register(&ec->dev);
+
+ return 0;
+
+ nodev:
+ ecard_free_card(ec);
+ nomem:
+ return rc;
+}
+
+/*
+ * Initialise the expansion card system.
+ * Locate all hardware - interrupt management and
+ * actual cards.
+ */
+static int __init ecard_init(void)
+{
+ struct task_struct *task;
+ int slot, irqhw;
+
+ task = kthread_run(ecard_task, NULL, "kecardd");
+ if (IS_ERR(task)) {
+ printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
+ PTR_ERR(task));
+ return PTR_ERR(task);
+ }
+
+ printk("Probing expansion cards\n");
+
+ for (slot = 0; slot < 8; slot ++) {
+ if (ecard_probe(slot, ECARD_EASI) == -ENODEV)
+ ecard_probe(slot, ECARD_IOC);
+ }
+
+#ifdef IO_EC_MEMC8_BASE
+ ecard_probe(8, ECARD_IOC);
+#endif
+
+ irqhw = ecard_probeirqhw();
+
+ irq_set_chained_handler(IRQ_EXPANSIONCARD,
+ irqhw ? ecard_irqexp_handler : ecard_irq_handler);
+
+ ecard_proc_init();
+
+ return 0;
+}
+
+subsys_initcall(ecard_init);
+
+/*
+ * ECARD "bus"
+ */
+static const struct ecard_id *
+ecard_match_device(const struct ecard_id *ids, struct expansion_card *ec)
+{
+ int i;
+
+ for (i = 0; ids[i].manufacturer != 65535; i++)
+ if (ec->cid.manufacturer == ids[i].manufacturer &&
+ ec->cid.product == ids[i].product)
+ return ids + i;
+
+ return NULL;
+}
+
+static int ecard_drv_probe(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+ const struct ecard_id *id;
+ int ret;
+
+ id = ecard_match_device(drv->id_table, ec);
+
+ ec->claimed = 1;
+ ret = drv->probe(ec, id);
+ if (ret)
+ ec->claimed = 0;
+ return ret;
+}
+
+static int ecard_drv_remove(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+
+ drv->remove(ec);
+ ec->claimed = 0;
+
+ /*
+ * Restore the default operations. We ensure that the
+ * ops are set before we change the data.
+ */
+ ec->ops = &ecard_default_ops;
+ barrier();
+ ec->irq_data = NULL;
+
+ return 0;
+}
+
+/*
+ * Before rebooting, we must make sure that the expansion card is in a
+ * sensible state, so it can be re-detected. This means that the first
+ * page of the ROM must be visible. We call the expansion cards reset
+ * handler, if any.
+ */
+static void ecard_drv_shutdown(struct device *dev)
+{
+ struct expansion_card *ec = ECARD_DEV(dev);
+ struct ecard_driver *drv = ECARD_DRV(dev->driver);
+ struct ecard_request req;
+
+ if (dev->driver) {
+ if (drv->shutdown)
+ drv->shutdown(ec);
+ ec->claimed = 0;
+ }
+
+ /*
+ * If this card has a loader, call the reset handler.
+ */
+ if (ec->loader) {
+ req.fn = ecard_task_reset;
+ req.ec = ec;
+ ecard_call(&req);
+ }
+}
+
+int ecard_register_driver(struct ecard_driver *drv)
+{
+ drv->drv.bus = &ecard_bus_type;
+
+ return driver_register(&drv->drv);
+}
+
+void ecard_remove_driver(struct ecard_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+static int ecard_match(struct device *_dev, struct device_driver *_drv)
+{
+ struct expansion_card *ec = ECARD_DEV(_dev);
+ struct ecard_driver *drv = ECARD_DRV(_drv);
+ int ret;
+
+ if (drv->id_table) {
+ ret = ecard_match_device(drv->id_table, ec) != NULL;
+ } else {
+ ret = ec->cid.id == drv->id;
+ }
+
+ return ret;
+}
+
+struct bus_type ecard_bus_type = {
+ .name = "ecard",
+ .dev_attrs = ecard_dev_attrs,
+ .match = ecard_match,
+ .probe = ecard_drv_probe,
+ .remove = ecard_drv_remove,
+ .shutdown = ecard_drv_shutdown,
+};
+
+static int ecard_bus_init(void)
+{
+ return bus_register(&ecard_bus_type);
+}
+
+postcore_initcall(ecard_bus_init);
+
+EXPORT_SYMBOL(ecard_readchunk);
+EXPORT_SYMBOL(ecard_register_driver);
+EXPORT_SYMBOL(ecard_remove_driver);
+EXPORT_SYMBOL(ecard_bus_type);
diff --git a/arch/arm/kernel/ecard.h b/arch/arm/kernel/ecard.h
new file mode 100644
index 00000000..4642d436
--- /dev/null
+++ b/arch/arm/kernel/ecard.h
@@ -0,0 +1,69 @@
+/*
+ * ecard.h
+ *
+ * Copyright 2007 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Definitions internal to ecard.c - for it's use only!!
+ *
+ * External expansion card header as read from the card
+ */
+struct ex_ecid {
+ unsigned char r_irq:1;
+ unsigned char r_zero:1;
+ unsigned char r_fiq:1;
+ unsigned char r_id:4;
+ unsigned char r_a:1;
+
+ unsigned char r_cd:1;
+ unsigned char r_is:1;
+ unsigned char r_w:2;
+ unsigned char r_r1:4;
+
+ unsigned char r_r2:8;
+
+ unsigned char r_prod[2];
+
+ unsigned char r_manu[2];
+
+ unsigned char r_country;
+
+ unsigned char r_fiqmask;
+ unsigned char r_fiqoff[3];
+
+ unsigned char r_irqmask;
+ unsigned char r_irqoff[3];
+};
+
+/*
+ * Chunk directory entry as read from the card
+ */
+struct ex_chunk_dir {
+ unsigned char r_id;
+ unsigned char r_len[3];
+ unsigned long r_start;
+ union {
+ char string[256];
+ char data[1];
+ } d;
+#define c_id(x) ((x)->r_id)
+#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
+#define c_start(x) ((x)->r_start)
+};
+
+typedef enum ecard_type { /* Cards address space */
+ ECARD_IOC,
+ ECARD_MEMC,
+ ECARD_EASI
+} card_type_t;
+
+typedef enum { /* Speed for ECARD_IOC space */
+ ECARD_SLOW = 0,
+ ECARD_MEDIUM = 1,
+ ECARD_FAST = 2,
+ ECARD_SYNC = 3
+} card_speed_t;
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
new file mode 100644
index 00000000..9b05c6a0
--- /dev/null
+++ b/arch/arm/kernel/elf.c
@@ -0,0 +1,90 @@
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/personality.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+
+int elf_check_arch(const struct elf32_hdr *x)
+{
+ unsigned int eflags;
+
+ /* Make sure it's an ARM executable */
+ if (x->e_machine != EM_ARM)
+ return 0;
+
+ /* Make sure the entry address is reasonable */
+ if (x->e_entry & 1) {
+ if (!(elf_hwcap & HWCAP_THUMB))
+ return 0;
+ } else if (x->e_entry & 3)
+ return 0;
+
+ eflags = x->e_flags;
+ if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
+ unsigned int flt_fmt;
+
+ /* APCS26 is only allowed if the CPU supports it */
+ if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT))
+ return 0;
+
+ flt_fmt = eflags & (EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT);
+
+ /* VFP requires the supporting code */
+ if (flt_fmt == EF_ARM_VFP_FLOAT && !(elf_hwcap & HWCAP_VFP))
+ return 0;
+ }
+ return 1;
+}
+EXPORT_SYMBOL(elf_check_arch);
+
+void elf_set_personality(const struct elf32_hdr *x)
+{
+ unsigned int eflags = x->e_flags;
+ unsigned int personality = current->personality & ~PER_MASK;
+
+ /*
+ * We only support Linux ELF executables, so always set the
+ * personality to LINUX.
+ */
+ personality |= PER_LINUX;
+
+ /*
+ * APCS-26 is only valid for OABI executables
+ */
+ if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
+ (eflags & EF_ARM_APCS_26))
+ personality &= ~ADDR_LIMIT_32BIT;
+ else
+ personality |= ADDR_LIMIT_32BIT;
+
+ set_personality(personality);
+
+ /*
+ * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0
+ * and CP1, we only enable access to the iWMMXt coprocessor if the
+ * binary is EABI or softfloat (and thus, guaranteed not to use
+ * FPA instructions.)
+ */
+ if (elf_hwcap & HWCAP_IWMMXT &&
+ eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) {
+ set_thread_flag(TIF_USING_IWMMXT);
+ } else {
+ clear_thread_flag(TIF_USING_IWMMXT);
+ }
+}
+EXPORT_SYMBOL(elf_set_personality);
+
+/*
+ * Set READ_IMPLIES_EXEC if:
+ * - the binary requires an executable stack
+ * - we're running on a CPU which doesn't support NX.
+ */
+int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack)
+{
+ if (executable_stack != EXSTACK_DISABLE_X)
+ return 1;
+ if (cpu_architecture() < CPU_ARCH_ARMv6)
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL(arm_elf_read_implies_exec);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
new file mode 100644
index 00000000..2cd00764
--- /dev/null
+++ b/arch/arm/kernel/entry-armv.S
@@ -0,0 +1,1242 @@
+/*
+ * linux/arch/arm/kernel/entry-armv.S
+ *
+ * Copyright (C) 1996,1997,1998 Russell King.
+ * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
+ * nommu support by Hyok S. Choi (hyok.choi@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.
+ *
+ * Low-level vector interface routines
+ *
+ * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction
+ * that causes it to save wrong values... Be aware!
+ */
+
+#include <asm/memory.h>
+#include <asm/glue-df.h>
+#include <asm/glue-pf.h>
+#include <asm/vfpmacros.h>
+#include <mach/entry-macro.S>
+#include <asm/thread_notify.h>
+#include <asm/unwind.h>
+#include <asm/unistd.h>
+#include <asm/tls.h>
+
+#include "entry-header.S"
+#include <asm/entry-macro-multi.S>
+
+/*
+ * Interrupt handling. Preserves r7, r8, r9
+ */
+ .macro irq_handler
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ ldr r5, =handle_arch_irq
+ mov r0, sp
+ ldr r5, [r5]
+ adr lr, BSYM(9997f)
+ teq r5, #0
+ movne pc, r5
+#endif
+ arch_irq_handler_default
+9997:
+ .endm
+
+#ifdef CONFIG_KPROBES
+ .section .kprobes.text,"ax",%progbits
+#else
+ .text
+#endif
+
+/*
+ * Invalid mode handlers
+ */
+ .macro inv_entry, reason
+ sub sp, sp, #S_FRAME_SIZE
+ ARM( stmib sp, {r1 - lr} )
+ THUMB( stmia sp, {r0 - r12} )
+ THUMB( str sp, [sp, #S_SP] )
+ THUMB( str lr, [sp, #S_LR] )
+ mov r1, #\reason
+ .endm
+
+__pabt_invalid:
+ inv_entry BAD_PREFETCH
+ b common_invalid
+ENDPROC(__pabt_invalid)
+
+__dabt_invalid:
+ inv_entry BAD_DATA
+ b common_invalid
+ENDPROC(__dabt_invalid)
+
+__irq_invalid:
+ inv_entry BAD_IRQ
+ b common_invalid
+ENDPROC(__irq_invalid)
+
+__und_invalid:
+ inv_entry BAD_UNDEFINSTR
+
+ @
+ @ XXX fall through to common_invalid
+ @
+
+@
+@ common_invalid - generic code for failed exception (re-entrant version of handlers)
+@
+common_invalid:
+ zero_fp
+
+ ldmia r0, {r4 - r6}
+ add r0, sp, #S_PC @ here for interlock avoidance
+ mov r7, #-1 @ "" "" "" ""
+ str r4, [sp] @ save preserved r0
+ stmia r0, {r5 - r7} @ lr_<exception>,
+ @ cpsr_<exception>, "old_r0"
+
+ mov r0, sp
+ b bad_mode
+ENDPROC(__und_invalid)
+
+/*
+ * SVC mode handlers
+ */
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
+#define SPFIX(code...) code
+#else
+#define SPFIX(code...)
+#endif
+
+ .macro svc_entry, stack_hole=0
+ UNWIND(.fnstart )
+ UNWIND(.save {r0 - pc} )
+ sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+#ifdef CONFIG_THUMB2_KERNEL
+ SPFIX( str r0, [sp] ) @ temporarily saved
+ SPFIX( mov r0, sp )
+ SPFIX( tst r0, #4 ) @ test original stack alignment
+ SPFIX( ldr r0, [sp] ) @ restored
+#else
+ SPFIX( tst sp, #4 )
+#endif
+ SPFIX( subeq sp, sp, #4 )
+ stmia sp, {r1 - r12}
+
+ ldmia r0, {r1 - r3}
+ add r5, sp, #S_SP - 4 @ here for interlock avoidance
+ mov r4, #-1 @ "" "" "" ""
+ add r0, sp, #(S_FRAME_SIZE + \stack_hole - 4)
+ SPFIX( addeq r0, r0, #4 )
+ str r1, [sp, #-4]! @ save the "real" r0 copied
+ @ from the exception stack
+
+ mov r1, lr
+
+ @
+ @ We are now ready to fill in the remaining blanks on the stack:
+ @
+ @ r0 - sp_svc
+ @ r1 - lr_svc
+ @ r2 - lr_<exception>, already fixed up for correct return/restart
+ @ r3 - spsr_<exception>
+ @ r4 - orig_r0 (see pt_regs definition in ptrace.h)
+ @
+ stmia r5, {r0 - r4}
+ .endm
+
+ .align 5
+__dabt_svc:
+ svc_entry
+
+ @
+ @ get ready to re-enable interrupts if appropriate
+ @
+ mrs r9, cpsr
+ tst r3, #PSR_I_BIT
+ biceq r9, r9, #PSR_I_BIT
+
+ @
+ @ Call the processor-specific abort handler:
+ @
+ @ r2 - aborted context pc
+ @ r3 - aborted context cpsr
+ @
+ @ The abort handler must return the aborted address in r0, and
+ @ the fault status register in r1. r9 must be preserved.
+ @
+#ifdef MULTI_DABORT
+ ldr r4, .LCprocfns
+ mov lr, pc
+ ldr pc, [r4, #PROCESSOR_DABT_FUNC]
+#else
+ bl CPU_DABORT_HANDLER
+#endif
+
+ @
+ @ set desired IRQ state, then call main handler
+ @
+ debug_entry r1
+ msr cpsr_c, r9
+ mov r2, sp
+ bl do_DataAbort
+
+ @
+ @ IRQs off again before pulling preserved data off the stack
+ @
+ disable_irq_notrace
+
+ @
+ @ restore SPSR and restart the instruction
+ @
+ ldr r2, [sp, #S_PSR]
+ svc_exit r2 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__dabt_svc)
+
+ .align 5
+__irq_svc:
+ svc_entry
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off
+#endif
+#ifdef CONFIG_PREEMPT
+ get_thread_info tsk
+ ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
+ add r7, r8, #1 @ increment it
+ str r7, [tsk, #TI_PREEMPT]
+#endif
+
+ irq_handler
+#ifdef CONFIG_PREEMPT
+ str r8, [tsk, #TI_PREEMPT] @ restore preempt count
+ ldr r0, [tsk, #TI_FLAGS] @ get flags
+ teq r8, #0 @ if preempt count != 0
+ movne r0, #0 @ force flags to 0
+ tst r0, #_TIF_NEED_RESCHED
+ blne svc_preempt
+#endif
+ ldr r4, [sp, #S_PSR] @ irqs are already disabled
+#ifdef CONFIG_TRACE_IRQFLAGS
+ tst r4, #PSR_I_BIT
+ bleq trace_hardirqs_on
+#endif
+ svc_exit r4 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__irq_svc)
+
+ .ltorg
+
+#ifdef CONFIG_PREEMPT
+svc_preempt:
+ mov r8, lr
+1: bl preempt_schedule_irq @ irq en/disable is done inside
+ ldr r0, [tsk, #TI_FLAGS] @ get new tasks TI_FLAGS
+ tst r0, #_TIF_NEED_RESCHED
+ moveq pc, r8 @ go again
+ b 1b
+#endif
+
+ .align 5
+__und_svc:
+#ifdef CONFIG_KPROBES
+ @ If a kprobe is about to simulate a "stmdb sp..." instruction,
+ @ it obviously needs free stack space which then will belong to
+ @ the saved context.
+ svc_entry 64
+#else
+ svc_entry
+#endif
+
+ @
+ @ call emulation code, which returns using r9 if it has emulated
+ @ the instruction, or the more conventional lr if we are to treat
+ @ this as a real undefined instruction
+ @
+ @ r0 - instruction
+ @
+#ifndef CONFIG_THUMB2_KERNEL
+ ldr r0, [r2, #-4]
+#else
+ ldrh r0, [r2, #-2] @ Thumb instruction at LR - 2
+ and r9, r0, #0xf800
+ cmp r9, #0xe800 @ 32-bit instruction if xx >= 0
+ ldrhhs r9, [r2] @ bottom 16 bits
+ orrhs r0, r9, r0, lsl #16
+#endif
+ adr r9, BSYM(1f)
+ bl call_fpe
+
+ mov r0, sp @ struct pt_regs *regs
+ bl do_undefinstr
+
+ @
+ @ IRQs off again before pulling preserved data off the stack
+ @
+1: disable_irq_notrace
+
+ @
+ @ restore SPSR and restart the instruction
+ @
+ ldr r2, [sp, #S_PSR] @ Get SVC cpsr
+ svc_exit r2 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__und_svc)
+
+ .align 5
+__pabt_svc:
+ svc_entry
+
+ @
+ @ re-enable interrupts if appropriate
+ @
+ mrs r9, cpsr
+ tst r3, #PSR_I_BIT
+ biceq r9, r9, #PSR_I_BIT
+
+ mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
+ ldr r4, .LCprocfns
+ mov lr, pc
+ ldr pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+ bl CPU_PABORT_HANDLER
+#endif
+ debug_entry r1
+ msr cpsr_c, r9 @ Maybe enable interrupts
+ mov r2, sp @ regs
+ bl do_PrefetchAbort @ call abort handler
+
+ @
+ @ IRQs off again before pulling preserved data off the stack
+ @
+ disable_irq_notrace
+
+ @
+ @ restore SPSR and restart the instruction
+ @
+ ldr r2, [sp, #S_PSR]
+ svc_exit r2 @ return from exception
+ UNWIND(.fnend )
+ENDPROC(__pabt_svc)
+
+ .align 5
+.LCcralign:
+ .word cr_alignment
+#ifdef MULTI_DABORT
+.LCprocfns:
+ .word processor
+#endif
+.LCfp:
+ .word fp_enter
+
+/*
+ * User mode handlers
+ *
+ * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE
+ */
+
+#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7)
+#error "sizeof(struct pt_regs) must be a multiple of 8"
+#endif
+
+ .macro usr_entry
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind ) @ don't unwind the user space
+ sub sp, sp, #S_FRAME_SIZE
+ ARM( stmib sp, {r1 - r12} )
+ THUMB( stmia sp, {r0 - r12} )
+
+ ldmia r0, {r1 - r3}
+ add r0, sp, #S_PC @ here for interlock avoidance
+ mov r4, #-1 @ "" "" "" ""
+
+ str r1, [sp] @ save the "real" r0 copied
+ @ from the exception stack
+
+ @
+ @ We are now ready to fill in the remaining blanks on the stack:
+ @
+ @ r2 - lr_<exception>, already fixed up for correct return/restart
+ @ r3 - spsr_<exception>
+ @ r4 - orig_r0 (see pt_regs definition in ptrace.h)
+ @
+ @ Also, separately save sp_usr and lr_usr
+ @
+ stmia r0, {r2 - r4}
+ ARM( stmdb r0, {sp, lr}^ )
+ THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )
+
+ @
+ @ Enable the alignment trap while in kernel mode
+ @
+ alignment_trap r0
+
+ @
+ @ Clear FP to mark the first stack frame
+ @
+ zero_fp
+ .endm
+
+ .macro kuser_cmpxchg_check
+#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+#ifndef CONFIG_MMU
+#warning "NPTL on non MMU needs fixing"
+#else
+ @ Make sure our user space atomic helper is restarted
+ @ if it was interrupted in a critical region. Here we
+ @ perform a quick test inline since it should be false
+ @ 99.9999% of the time. The rest is done out of line.
+ cmp r2, #TASK_SIZE
+ blhs kuser_cmpxchg_fixup
+#endif
+#endif
+ .endm
+
+ .align 5
+__dabt_usr:
+ usr_entry
+ kuser_cmpxchg_check
+
+ @
+ @ Call the processor-specific abort handler:
+ @
+ @ r2 - aborted context pc
+ @ r3 - aborted context cpsr
+ @
+ @ The abort handler must return the aborted address in r0, and
+ @ the fault status register in r1.
+ @
+#ifdef MULTI_DABORT
+ ldr r4, .LCprocfns
+ mov lr, pc
+ ldr pc, [r4, #PROCESSOR_DABT_FUNC]
+#else
+ bl CPU_DABORT_HANDLER
+#endif
+
+ @
+ @ IRQs on, then call the main handler
+ @
+ debug_entry r1
+ enable_irq
+ mov r2, sp
+ adr lr, BSYM(ret_from_exception)
+ b do_DataAbort
+ UNWIND(.fnend )
+ENDPROC(__dabt_usr)
+
+ .align 5
+__irq_usr:
+ usr_entry
+ kuser_cmpxchg_check
+
+#ifdef CONFIG_IRQSOFF_TRACER
+ bl trace_hardirqs_off
+#endif
+
+ get_thread_info tsk
+#ifdef CONFIG_PREEMPT
+ ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
+ add r7, r8, #1 @ increment it
+ str r7, [tsk, #TI_PREEMPT]
+#endif
+
+ irq_handler
+#ifdef CONFIG_PREEMPT
+ ldr r0, [tsk, #TI_PREEMPT]
+ str r8, [tsk, #TI_PREEMPT]
+ teq r0, r7
+ ARM( strne r0, [r0, -r0] )
+ THUMB( movne r0, #0 )
+ THUMB( strne r0, [r0] )
+#endif
+
+ mov why, #0
+ b ret_to_user_from_irq
+ UNWIND(.fnend )
+ENDPROC(__irq_usr)
+
+ .ltorg
+
+ .align 5
+__und_usr:
+ usr_entry
+
+ @
+ @ fall through to the emulation code, which returns using r9 if
+ @ it has emulated the instruction, or the more conventional lr
+ @ if we are to treat this as a real undefined instruction
+ @
+ @ r0 - instruction
+ @
+ adr r9, BSYM(ret_from_exception)
+ adr lr, BSYM(__und_usr_unknown)
+ tst r3, #PSR_T_BIT @ Thumb mode?
+ itet eq @ explicit IT needed for the 1f label
+ subeq r4, r2, #4 @ ARM instr at LR - 4
+ subne r4, r2, #2 @ Thumb instr at LR - 2
+1: ldreqt r0, [r4]
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ reveq r0, r0 @ little endian instruction
+#endif
+ beq call_fpe
+ @ Thumb instruction
+#if __LINUX_ARM_ARCH__ >= 7
+2:
+ ARM( ldrht r5, [r4], #2 )
+ THUMB( ldrht r5, [r4] )
+ THUMB( add r4, r4, #2 )
+ and r0, r5, #0xf800 @ mask bits 111x x... .... ....
+ cmp r0, #0xe800 @ 32bit instruction if xx != 0
+ 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
+#else
+ b __und_usr_unknown
+#endif
+ UNWIND(.fnend )
+ENDPROC(__und_usr)
+
+ @
+ @ fallthrough to call_fpe
+ @
+
+/*
+ * The out of line fixup for the ldrt above.
+ */
+ .pushsection .fixup, "ax"
+4: mov pc, r9
+ .popsection
+ .pushsection __ex_table,"a"
+ .long 1b, 4b
+#if __LINUX_ARM_ARCH__ >= 7
+ .long 2b, 4b
+ .long 3b, 4b
+#endif
+ .popsection
+
+/*
+ * Check whether the instruction is a co-processor instruction.
+ * If yes, we need to call the relevant co-processor handler.
+ *
+ * Note that we don't do a full check here for the co-processor
+ * instructions; all instructions with bit 27 set are well
+ * defined. The only instructions that should fault are the
+ * co-processor instructions. However, we have to watch out
+ * for the ARM6/ARM7 SWI bug.
+ *
+ * NEON is a special case that has to be handled here. Not all
+ * NEON instructions are co-processor instructions, so we have
+ * to make a special case of checking for them. Plus, there's
+ * five groups of them, so we have a table of mask/opcode pairs
+ * to check against, and if any match then we branch off into the
+ * NEON handler code.
+ *
+ * Emulators may wish to make use of the following registers:
+ * r0 = instruction opcode.
+ * r2 = PC+4
+ * r9 = normal "successful" return address
+ * r10 = this threads thread_info structure.
+ * lr = unrecognised instruction return address
+ */
+ @
+ @ Fall-through from Thumb-2 __und_usr
+ @
+#ifdef CONFIG_NEON
+ adr r6, .LCneon_thumb_opcodes
+ b 2f
+#endif
+call_fpe:
+#ifdef CONFIG_NEON
+ adr r6, .LCneon_arm_opcodes
+2:
+ ldr r7, [r6], #4 @ mask value
+ cmp r7, #0 @ end mask?
+ beq 1f
+ and r8, r0, r7
+ ldr r7, [r6], #4 @ opcode bits matching in mask
+ cmp r8, r7 @ NEON instruction?
+ bne 2b
+ get_thread_info r10
+ mov r7, #1
+ strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used
+ strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used
+ b do_vfp @ let VFP handler handle this
+1:
+#endif
+ tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27
+ tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2
+#if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
+ and r8, r0, #0x0f000000 @ mask out op-code bits
+ teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)?
+#endif
+ moveq pc, lr
+ get_thread_info r10 @ get current thread
+ and r8, r0, #0x00000f00 @ mask out CP number
+ THUMB( lsr r8, r8, #8 )
+ mov r7, #1
+ add r6, r10, #TI_USED_CP
+ ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[]
+ THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[]
+#ifdef CONFIG_IWMMXT
+ @ Test if we need to give access to iWMMXt coprocessors
+ ldr r5, [r10, #TI_FLAGS]
+ rsbs r7, r8, #(1 << 8) @ CP 0 or 1 only
+ movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1)
+ bcs iwmmxt_task_enable
+#endif
+ ARM( add pc, pc, r8, lsr #6 )
+ THUMB( lsl r8, r8, #2 )
+ THUMB( add pc, r8 )
+ nop
+
+ movw_pc lr @ CP#0
+ W(b) do_fpe @ CP#1 (FPE)
+ W(b) do_fpe @ CP#2 (FPE)
+ movw_pc lr @ CP#3
+#ifdef CONFIG_CRUNCH
+ b crunch_task_enable @ CP#4 (MaverickCrunch)
+ b crunch_task_enable @ CP#5 (MaverickCrunch)
+ b crunch_task_enable @ CP#6 (MaverickCrunch)
+#else
+ movw_pc lr @ CP#4
+ movw_pc lr @ CP#5
+ movw_pc lr @ CP#6
+#endif
+ movw_pc lr @ CP#7
+ movw_pc lr @ CP#8
+ movw_pc lr @ CP#9
+#ifdef CONFIG_VFP
+ W(b) do_vfp @ CP#10 (VFP)
+ W(b) do_vfp @ CP#11 (VFP)
+#else
+ movw_pc lr @ CP#10 (VFP)
+ movw_pc lr @ CP#11 (VFP)
+#endif
+ movw_pc lr @ CP#12
+ movw_pc lr @ CP#13
+ movw_pc lr @ CP#14 (Debug)
+ movw_pc lr @ CP#15 (Control)
+
+#ifdef CONFIG_NEON
+ .align 6
+
+.LCneon_arm_opcodes:
+ .word 0xfe000000 @ mask
+ .word 0xf2000000 @ opcode
+
+ .word 0xff100000 @ mask
+ .word 0xf4000000 @ opcode
+
+ .word 0x00000000 @ mask
+ .word 0x00000000 @ opcode
+
+.LCneon_thumb_opcodes:
+ .word 0xef000000 @ mask
+ .word 0xef000000 @ opcode
+
+ .word 0xff100000 @ mask
+ .word 0xf9000000 @ opcode
+
+ .word 0x00000000 @ mask
+ .word 0x00000000 @ opcode
+#endif
+
+do_fpe:
+ enable_irq
+ ldr r4, .LCfp
+ add r10, r10, #TI_FPSTATE @ r10 = workspace
+ ldr pc, [r4] @ Call FP module USR entry point
+
+/*
+ * The FP module is called with these registers set:
+ * r0 = instruction
+ * r2 = PC+4
+ * r9 = normal "successful" return address
+ * r10 = FP workspace
+ * lr = unrecognised FP instruction return address
+ */
+
+ .pushsection .data
+ENTRY(fp_enter)
+ .word no_fp
+ .popsection
+
+ENTRY(no_fp)
+ mov pc, lr
+ENDPROC(no_fp)
+
+__und_usr_unknown:
+ enable_irq
+ mov r0, sp
+ adr lr, BSYM(ret_from_exception)
+ b do_undefinstr
+ENDPROC(__und_usr_unknown)
+
+ .align 5
+__pabt_usr:
+ usr_entry
+
+ mov r0, r2 @ pass address of aborted instruction.
+#ifdef MULTI_PABORT
+ ldr r4, .LCprocfns
+ mov lr, pc
+ ldr pc, [r4, #PROCESSOR_PABT_FUNC]
+#else
+ bl CPU_PABORT_HANDLER
+#endif
+ debug_entry r1
+ enable_irq @ Enable interrupts
+ mov r2, sp @ regs
+ bl do_PrefetchAbort @ call abort handler
+ UNWIND(.fnend )
+ /* fall through */
+/*
+ * This is the return code to user mode for abort handlers
+ */
+ENTRY(ret_from_exception)
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
+ get_thread_info tsk
+ mov why, #0
+ b ret_to_user
+ UNWIND(.fnend )
+ENDPROC(__pabt_usr)
+ENDPROC(ret_from_exception)
+
+/*
+ * Register switch for ARMv3 and ARMv4 processors
+ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
+ * previous and next are guaranteed not to be the same.
+ */
+ENTRY(__switch_to)
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
+ add ip, r1, #TI_CPU_SAVE
+ ldr r3, [r2, #TI_TP_VALUE]
+ ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
+ THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
+ THUMB( str sp, [ip], #4 )
+ THUMB( str lr, [ip], #4 )
+#ifdef CONFIG_CPU_USE_DOMAINS
+ ldr r6, [r2, #TI_CPU_DOMAIN]
+#endif
+ set_tls r3, r4, r5
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+ ldr r7, [r2, #TI_TASK]
+ ldr r8, =__stack_chk_guard
+ ldr r7, [r7, #TSK_STACK_CANARY]
+#endif
+#ifdef CONFIG_CPU_USE_DOMAINS
+ mcr p15, 0, r6, c3, c0, 0 @ Set domain register
+#endif
+ mov r5, r0
+ add r4, r2, #TI_CPU_SAVE
+ ldr r0, =thread_notify_head
+ mov r1, #THREAD_NOTIFY_SWITCH
+ bl atomic_notifier_call_chain
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+ str r7, [r8]
+#endif
+ THUMB( mov ip, r4 )
+ mov r0, r5
+ ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
+ THUMB( ldmia ip!, {r4 - sl, fp} ) @ Load all regs saved previously
+ THUMB( ldr sp, [ip], #4 )
+ THUMB( ldr pc, [ip] )
+ UNWIND(.fnend )
+ENDPROC(__switch_to)
+
+ __INIT
+
+/*
+ * User helpers.
+ *
+ * These are segment of kernel provided user code reachable from user space
+ * at a fixed address in kernel memory. This is used to provide user space
+ * with some operations which require kernel help because of unimplemented
+ * native feature and/or instructions in many ARM CPUs. The idea is for
+ * this code to be executed directly in user mode for best efficiency but
+ * which is too intimate with the kernel counter part to be left to user
+ * libraries. In fact this code might even differ from one CPU to another
+ * depending on the available instruction set and restrictions like on
+ * SMP systems. In other words, the kernel reserves the right to change
+ * this code as needed without warning. Only the entry points and their
+ * results are guaranteed to be stable.
+ *
+ * Each segment is 32-byte aligned and will be moved to the top of the high
+ * vector page. New segments (if ever needed) must be added in front of
+ * existing ones. This mechanism should be used only for things that are
+ * really small and justified, and not be abused freely.
+ *
+ * User space is expected to implement those things inline when optimizing
+ * for a processor that has the necessary native support, but only if such
+ * resulting binaries are already to be incompatible with earlier ARM
+ * processors due to the use of unsupported instructions other than what
+ * is provided here. In other words don't make binaries unable to run on
+ * earlier processors just for the sake of not using these kernel helpers
+ * if your compiled code is not going to use the new instructions for other
+ * purpose.
+ */
+ THUMB( .arm )
+
+ .macro usr_ret, reg
+#ifdef CONFIG_ARM_THUMB
+ bx \reg
+#else
+ mov pc, \reg
+#endif
+ .endm
+
+ .align 5
+ .globl __kuser_helper_start
+__kuser_helper_start:
+
+/*
+ * Reference prototype:
+ *
+ * void __kernel_memory_barrier(void)
+ *
+ * Input:
+ *
+ * lr = return address
+ *
+ * Output:
+ *
+ * none
+ *
+ * Clobbered:
+ *
+ * none
+ *
+ * Definition and user space usage example:
+ *
+ * typedef void (__kernel_dmb_t)(void);
+ * #define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
+ *
+ * Apply any needed memory barrier to preserve consistency with data modified
+ * manually and __kuser_cmpxchg usage.
+ *
+ * This could be used as follows:
+ *
+ * #define __kernel_dmb() \
+ * asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
+ * : : : "r0", "lr","cc" )
+ */
+
+__kuser_memory_barrier: @ 0xffff0fa0
+ smp_dmb arm
+ usr_ret lr
+
+ .align 5
+
+/*
+ * Reference prototype:
+ *
+ * int __kernel_cmpxchg(int oldval, int newval, int *ptr)
+ *
+ * Input:
+ *
+ * r0 = oldval
+ * r1 = newval
+ * r2 = ptr
+ * lr = return address
+ *
+ * Output:
+ *
+ * r0 = returned value (zero or non-zero)
+ * C flag = set if r0 == 0, clear if r0 != 0
+ *
+ * Clobbered:
+ *
+ * r3, ip, flags
+ *
+ * Definition and user space usage example:
+ *
+ * typedef int (__kernel_cmpxchg_t)(int oldval, int newval, int *ptr);
+ * #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
+ *
+ * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
+ * Return zero if *ptr was changed or non-zero if no exchange happened.
+ * The C flag is also set if *ptr was changed to allow for assembly
+ * optimization in the calling code.
+ *
+ * Notes:
+ *
+ * - This routine already includes memory barriers as needed.
+ *
+ * For example, a user space atomic_add implementation could look like this:
+ *
+ * #define atomic_add(ptr, val) \
+ * ({ register unsigned int *__ptr asm("r2") = (ptr); \
+ * register unsigned int __result asm("r1"); \
+ * asm volatile ( \
+ * "1: @ atomic_add\n\t" \
+ * "ldr r0, [r2]\n\t" \
+ * "mov r3, #0xffff0fff\n\t" \
+ * "add lr, pc, #4\n\t" \
+ * "add r1, r0, %2\n\t" \
+ * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
+ * "bcc 1b" \
+ * : "=&r" (__result) \
+ * : "r" (__ptr), "rIL" (val) \
+ * : "r0","r3","ip","lr","cc","memory" ); \
+ * __result; })
+ */
+
+__kuser_cmpxchg: @ 0xffff0fc0
+
+#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG)
+
+ /*
+ * Poor you. No fast solution possible...
+ * The kernel itself must perform the operation.
+ * A special ghost syscall is used for that (see traps.c).
+ */
+ stmfd sp!, {r7, lr}
+ ldr r7, 1f @ it's 20 bits
+ swi __ARM_NR_cmpxchg
+ ldmfd sp!, {r7, pc}
+1: .word __ARM_NR_cmpxchg
+
+#elif __LINUX_ARM_ARCH__ < 6
+
+#ifdef CONFIG_MMU
+
+ /*
+ * The only thing that can break atomicity in this cmpxchg
+ * implementation is either an IRQ or a data abort exception
+ * causing another process/thread to be scheduled in the middle
+ * of the critical sequence. To prevent this, code is added to
+ * the IRQ and data abort exception handlers to set the pc back
+ * to the beginning of the critical section if it is found to be
+ * within that critical section (see kuser_cmpxchg_fixup).
+ */
+1: ldr r3, [r2] @ load current val
+ subs r3, r3, r0 @ compare with oldval
+2: streq r1, [r2] @ store newval if eq
+ rsbs r0, r3, #0 @ set return val and C flag
+ usr_ret lr
+
+ .text
+kuser_cmpxchg_fixup:
+ @ Called from kuser_cmpxchg_check macro.
+ @ r2 = address of interrupted insn (must be preserved).
+ @ sp = saved regs. r7 and r8 are clobbered.
+ @ 1b = first critical insn, 2b = last critical insn.
+ @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b.
+ mov r7, #0xffff0fff
+ sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
+ subs r8, r2, r7
+ rsbcss r8, r8, #(2b - 1b)
+ strcs r7, [sp, #S_PC]
+ mov pc, lr
+ .previous
+
+#else
+#warning "NPTL on non MMU needs fixing"
+ mov r0, #-1
+ adds r0, r0, #0
+ usr_ret lr
+#endif
+
+#else
+
+ smp_dmb arm
+1: ldrex r3, [r2]
+ subs r3, r3, r0
+ strexeq r3, r1, [r2]
+ teqeq r3, #1
+ beq 1b
+ rsbs r0, r3, #0
+ /* beware -- each __kuser slot must be 8 instructions max */
+ ALT_SMP(b __kuser_memory_barrier)
+ ALT_UP(usr_ret lr)
+
+#endif
+
+ .align 5
+
+/*
+ * Reference prototype:
+ *
+ * int __kernel_get_tls(void)
+ *
+ * Input:
+ *
+ * lr = return address
+ *
+ * Output:
+ *
+ * r0 = TLS value
+ *
+ * Clobbered:
+ *
+ * none
+ *
+ * Definition and user space usage example:
+ *
+ * typedef int (__kernel_get_tls_t)(void);
+ * #define __kernel_get_tls (*(__kernel_get_tls_t *)0xffff0fe0)
+ *
+ * Get the TLS value as previously set via the __ARM_NR_set_tls syscall.
+ *
+ * This could be used as follows:
+ *
+ * #define __kernel_get_tls() \
+ * ({ register unsigned int __val asm("r0"); \
+ * asm( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #31" \
+ * : "=r" (__val) : : "lr","cc" ); \
+ * __val; })
+ */
+
+__kuser_get_tls: @ 0xffff0fe0
+ ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init
+ usr_ret lr
+ mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code
+ .rep 4
+ .word 0 @ 0xffff0ff0 software TLS value, then
+ .endr @ pad up to __kuser_helper_version
+
+/*
+ * Reference declaration:
+ *
+ * extern unsigned int __kernel_helper_version;
+ *
+ * Definition and user space usage example:
+ *
+ * #define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
+ *
+ * User space may read this to determine the curent number of helpers
+ * available.
+ */
+
+__kuser_helper_version: @ 0xffff0ffc
+ .word ((__kuser_helper_end - __kuser_helper_start) >> 5)
+
+ .globl __kuser_helper_end
+__kuser_helper_end:
+
+ THUMB( .thumb )
+
+/*
+ * Vector stubs.
+ *
+ * This code is copied to 0xffff0200 so we can use branches in the
+ * vectors, rather than ldr's. Note that this code must not
+ * exceed 0x300 bytes.
+ *
+ * Common stub entry macro:
+ * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ *
+ * SP points to a minimal amount of processor-private memory, the address
+ * of which is copied into r0 for the mode specific abort handler.
+ */
+ .macro vector_stub, name, mode, correction=0
+ .align 5
+
+vector_\name:
+ .if \correction
+ sub lr, lr, #\correction
+ .endif
+
+ @
+ @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
+ @ (parent CPSR)
+ @
+ stmia sp, {r0, lr} @ save r0, lr
+ mrs lr, spsr
+ str lr, [sp, #8] @ save spsr
+
+ @
+ @ Prepare for SVC32 mode. IRQs remain disabled.
+ @
+ mrs r0, cpsr
+ eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
+ msr spsr_cxsf, r0
+
+ @
+ @ the branch table must immediately follow this code
+ @
+ and lr, lr, #0x0f
+ THUMB( adr r0, 1f )
+ THUMB( ldr lr, [r0, lr, lsl #2] )
+ mov r0, sp
+ ARM( ldr lr, [pc, lr, lsl #2] )
+ movs pc, lr @ branch to handler in SVC mode
+ENDPROC(vector_\name)
+
+ .align 2
+ @ handler addresses follow this label
+1:
+ .endm
+
+ .globl __stubs_start
+__stubs_start:
+/*
+ * Interrupt dispatcher
+ */
+ vector_stub irq, IRQ_MODE, 4
+
+ .long __irq_usr @ 0 (USR_26 / USR_32)
+ .long __irq_invalid @ 1 (FIQ_26 / FIQ_32)
+ .long __irq_invalid @ 2 (IRQ_26 / IRQ_32)
+ .long __irq_svc @ 3 (SVC_26 / SVC_32)
+ .long __irq_invalid @ 4
+ .long __irq_invalid @ 5
+ .long __irq_invalid @ 6
+ .long __irq_invalid @ 7
+ .long __irq_invalid @ 8
+ .long __irq_invalid @ 9
+ .long __irq_invalid @ a
+ .long __irq_invalid @ b
+ .long __irq_invalid @ c
+ .long __irq_invalid @ d
+ .long __irq_invalid @ e
+ .long __irq_invalid @ f
+
+/*
+ * Data abort dispatcher
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+ vector_stub dabt, ABT_MODE, 8
+
+ .long __dabt_usr @ 0 (USR_26 / USR_32)
+ .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
+ .long __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
+ .long __dabt_svc @ 3 (SVC_26 / SVC_32)
+ .long __dabt_invalid @ 4
+ .long __dabt_invalid @ 5
+ .long __dabt_invalid @ 6
+ .long __dabt_invalid @ 7
+ .long __dabt_invalid @ 8
+ .long __dabt_invalid @ 9
+ .long __dabt_invalid @ a
+ .long __dabt_invalid @ b
+ .long __dabt_invalid @ c
+ .long __dabt_invalid @ d
+ .long __dabt_invalid @ e
+ .long __dabt_invalid @ f
+
+/*
+ * Prefetch abort dispatcher
+ * Enter in ABT mode, spsr = USR CPSR, lr = USR PC
+ */
+ vector_stub pabt, ABT_MODE, 4
+
+ .long __pabt_usr @ 0 (USR_26 / USR_32)
+ .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32)
+ .long __pabt_invalid @ 2 (IRQ_26 / IRQ_32)
+ .long __pabt_svc @ 3 (SVC_26 / SVC_32)
+ .long __pabt_invalid @ 4
+ .long __pabt_invalid @ 5
+ .long __pabt_invalid @ 6
+ .long __pabt_invalid @ 7
+ .long __pabt_invalid @ 8
+ .long __pabt_invalid @ 9
+ .long __pabt_invalid @ a
+ .long __pabt_invalid @ b
+ .long __pabt_invalid @ c
+ .long __pabt_invalid @ d
+ .long __pabt_invalid @ e
+ .long __pabt_invalid @ f
+
+/*
+ * Undef instr entry dispatcher
+ * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
+ */
+ vector_stub und, UND_MODE
+
+ .long __und_usr @ 0 (USR_26 / USR_32)
+ .long __und_invalid @ 1 (FIQ_26 / FIQ_32)
+ .long __und_invalid @ 2 (IRQ_26 / IRQ_32)
+ .long __und_svc @ 3 (SVC_26 / SVC_32)
+ .long __und_invalid @ 4
+ .long __und_invalid @ 5
+ .long __und_invalid @ 6
+ .long __und_invalid @ 7
+ .long __und_invalid @ 8
+ .long __und_invalid @ 9
+ .long __und_invalid @ a
+ .long __und_invalid @ b
+ .long __und_invalid @ c
+ .long __und_invalid @ d
+ .long __und_invalid @ e
+ .long __und_invalid @ f
+
+ .align 5
+
+/*=============================================================================
+ * Undefined FIQs
+ *-----------------------------------------------------------------------------
+ * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
+ * MUST PRESERVE SVC SPSR, but need to switch to SVC mode to show our msg.
+ * Basically to switch modes, we *HAVE* to clobber one register... brain
+ * damage alert! I don't think that we can execute any code in here in any
+ * other mode than FIQ... Ok you can switch to another mode, but you can't
+ * get out of that mode without clobbering one register.
+ */
+vector_fiq:
+ disable_fiq
+ subs pc, lr, #4
+
+/*=============================================================================
+ * Address exception handler
+ *-----------------------------------------------------------------------------
+ * These aren't too critical.
+ * (they're not supposed to happen, and won't happen in 32-bit data mode).
+ */
+
+vector_addrexcptn:
+ b vector_addrexcptn
+
+/*
+ * We group all the following data together to optimise
+ * for CPUs with separate I & D caches.
+ */
+ .align 5
+
+.LCvswi:
+ .word vector_swi
+
+ .globl __stubs_end
+__stubs_end:
+
+ .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
+
+ .globl __vectors_start
+__vectors_start:
+ ARM( swi SYS_ERROR0 )
+ THUMB( svc #0 )
+ THUMB( nop )
+ W(b) vector_und + stubs_offset
+ W(ldr) pc, .LCvswi + stubs_offset
+ W(b) vector_pabt + stubs_offset
+ W(b) vector_dabt + stubs_offset
+ W(b) vector_addrexcptn + stubs_offset
+ W(b) vector_irq + stubs_offset
+ W(b) vector_fiq + stubs_offset
+
+ .globl __vectors_end
+__vectors_end:
+
+ .data
+
+ .globl cr_alignment
+ .globl cr_no_alignment
+cr_alignment:
+ .space 4
+cr_no_alignment:
+ .space 4
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ .globl handle_arch_irq
+handle_arch_irq:
+ .space 4
+#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
new file mode 100644
index 00000000..b2a27b6b
--- /dev/null
+++ b/arch/arm/kernel/entry-common.S
@@ -0,0 +1,647 @@
+/*
+ * linux/arch/arm/kernel/entry-common.S
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/unistd.h>
+#include <asm/ftrace.h>
+#include <mach/entry-macro.S>
+#include <asm/unwind.h>
+
+#include "entry-header.S"
+
+
+ .align 5
+/*
+ * This is the fast syscall return path. We do as little as
+ * possible here, and this includes saving r0 back into the SVC
+ * stack.
+ */
+ret_fast_syscall:
+ UNWIND(.fnstart )
+ UNWIND(.cantunwind )
+ disable_irq @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
+
+ /* perform architecture specific actions before user return */
+ arch_ret_to_user r1, lr
+
+ restore_user_regs fast = 1, offset = S_OFF
+ UNWIND(.fnend )
+
+/*
+ * Ok, we need to do extra processing, enter the slow path.
+ */
+fast_work_pending:
+ str r0, [sp, #S_R0+S_OFF]! @ returned r0
+work_pending:
+ tst r1, #_TIF_NEED_RESCHED
+ bne work_resched
+ tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
+ beq no_work_pending
+ mov r0, sp @ 'regs'
+ mov r2, why @ 'syscall'
+ tst r1, #_TIF_SIGPENDING @ delivering a signal?
+ movne why, #0 @ prevent further restarts
+ bl do_notify_resume
+ b ret_slow_syscall @ Check work again
+
+work_resched:
+ bl schedule
+/*
+ * "slow" syscall return path. "why" tells us if this was a real syscall.
+ */
+ENTRY(ret_to_user)
+ret_slow_syscall:
+ disable_irq @ disable interrupts
+ENTRY(ret_to_user_from_irq)
+ ldr r1, [tsk, #TI_FLAGS]
+ tst r1, #_TIF_WORK_MASK
+ bne work_pending
+no_work_pending:
+#if defined(CONFIG_IRQSOFF_TRACER)
+ asm_trace_hardirqs_on
+#endif
+ /* perform architecture specific actions before user return */
+ arch_ret_to_user r1, lr
+
+ restore_user_regs fast = 0, offset = 0
+ENDPROC(ret_to_user_from_irq)
+ENDPROC(ret_to_user)
+
+/*
+ * This is how we return from a fork.
+ */
+ENTRY(ret_from_fork)
+ bl schedule_tail
+ get_thread_info tsk
+ ldr r1, [tsk, #TI_FLAGS] @ check for syscall tracing
+ mov why, #1
+ tst r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+ beq ret_slow_syscall
+ mov r1, sp
+ mov r0, #1 @ trace exit [IP = 1]
+ bl syscall_trace
+ b ret_slow_syscall
+ENDPROC(ret_from_fork)
+
+ .equ NR_syscalls,0
+#define CALL(x) .equ NR_syscalls,NR_syscalls+1
+#include "calls.S"
+#undef CALL
+#define CALL(x) .long x
+
+#ifdef CONFIG_FUNCTION_TRACER
+/*
+ * When compiling with -pg, gcc inserts a call to the mcount routine at the
+ * start of every function. In mcount, apart from the function's address (in
+ * lr), we need to get hold of the function's caller's address.
+ *
+ * Older GCCs (pre-4.4) inserted a call to a routine called mcount like this:
+ *
+ * bl mcount
+ *
+ * These versions have the limitation that in order for the mcount routine to
+ * be able to determine the function's caller's address, an APCS-style frame
+ * pointer (which is set up with something like the code below) is required.
+ *
+ * mov ip, sp
+ * push {fp, ip, lr, pc}
+ * sub fp, ip, #4
+ *
+ * With EABI, these frame pointers are not available unless -mapcs-frame is
+ * specified, and if building as Thumb-2, not even then.
+ *
+ * Newer GCCs (4.4+) solve this problem by introducing a new version of mcount,
+ * with call sites like:
+ *
+ * push {lr}
+ * bl __gnu_mcount_nc
+ *
+ * With these compilers, frame pointers are not necessary.
+ *
+ * mcount can be thought of as a function called in the middle of a subroutine
+ * call. As such, it needs to be transparent for both the caller and the
+ * callee: the original lr needs to be restored when leaving mcount, and no
+ * registers should be clobbered. (In the __gnu_mcount_nc implementation, we
+ * clobber the ip register. This is OK because the ARM calling convention
+ * allows it to be clobbered in subroutines and doesn't use it to hold
+ * parameters.)
+ *
+ * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
+ * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
+ * arch/arm/kernel/ftrace.c).
+ */
+
+#ifndef CONFIG_OLD_MCOUNT
+#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
+#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
+#endif
+#endif
+
+.macro __mcount suffix
+ mcount_enter
+ ldr r0, =ftrace_trace_function
+ ldr r2, [r0]
+ adr r0, .Lftrace_stub
+ cmp r0, r2
+ bne 1f
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ ldr r1, =ftrace_graph_return
+ ldr r2, [r1]
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+
+ ldr r1, =ftrace_graph_entry
+ ldr r2, [r1]
+ ldr r0, =ftrace_graph_entry_stub
+ cmp r0, r2
+ bne ftrace_graph_caller\suffix
+#endif
+
+ mcount_exit
+
+1: mcount_get_lr r1 @ lr of instrumented func
+ mov r0, lr @ instrumented function
+ sub r0, r0, #MCOUNT_INSN_SIZE
+ adr lr, BSYM(2f)
+ mov pc, r2
+2: mcount_exit
+.endm
+
+.macro __ftrace_caller suffix
+ mcount_enter
+
+ mcount_get_lr r1 @ lr of instrumented func
+ mov r0, lr @ instrumented function
+ sub r0, r0, #MCOUNT_INSN_SIZE
+
+ .globl ftrace_call\suffix
+ftrace_call\suffix:
+ bl ftrace_stub
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl ftrace_graph_call\suffix
+ftrace_graph_call\suffix:
+ mov r0, r0
+#endif
+
+ mcount_exit
+.endm
+
+.macro __ftrace_graph_caller
+ sub r0, fp, #4 @ &lr of instrumented routine (&parent)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ @ called from __ftrace_caller, saved in mcount_enter
+ ldr r1, [sp, #16] @ instrumented routine (func)
+#else
+ @ called from __mcount, untouched in lr
+ mov r1, lr @ instrumented routine (func)
+#endif
+ sub r1, r1, #MCOUNT_INSN_SIZE
+ mov r2, fp @ frame pointer
+ bl prepare_ftrace_return
+ mcount_exit
+.endm
+
+#ifdef CONFIG_OLD_MCOUNT
+/*
+ * mcount
+ */
+
+.macro mcount_enter
+ stmdb sp!, {r0-r3, lr}
+.endm
+
+.macro mcount_get_lr reg
+ ldr \reg, [fp, #-4]
+.endm
+
+.macro mcount_exit
+ ldr lr, [fp, #-4]
+ ldmia sp!, {r0-r3, pc}
+.endm
+
+ENTRY(mcount)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ stmdb sp!, {lr}
+ ldr lr, [fp, #-4]
+ ldmia sp!, {pc}
+#else
+ __mcount _old
+#endif
+ENDPROC(mcount)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+ENTRY(ftrace_caller_old)
+ __ftrace_caller _old
+ENDPROC(ftrace_caller_old)
+#endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller_old)
+ __ftrace_graph_caller
+ENDPROC(ftrace_graph_caller_old)
+#endif
+
+.purgem mcount_enter
+.purgem mcount_get_lr
+.purgem mcount_exit
+#endif
+
+/*
+ * __gnu_mcount_nc
+ */
+
+.macro mcount_enter
+ stmdb sp!, {r0-r3, lr}
+.endm
+
+.macro mcount_get_lr reg
+ ldr \reg, [sp, #20]
+.endm
+
+.macro mcount_exit
+ ldmia sp!, {r0-r3, ip, lr}
+ mov pc, ip
+.endm
+
+ENTRY(__gnu_mcount_nc)
+#ifdef CONFIG_DYNAMIC_FTRACE
+ mov ip, lr
+ ldmia sp!, {lr}
+ mov pc, ip
+#else
+ __mcount
+#endif
+ENDPROC(__gnu_mcount_nc)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+ENTRY(ftrace_caller)
+ __ftrace_caller
+ENDPROC(ftrace_caller)
+#endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+ __ftrace_graph_caller
+ENDPROC(ftrace_graph_caller)
+#endif
+
+.purgem mcount_enter
+.purgem mcount_get_lr
+.purgem mcount_exit
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ .globl return_to_handler
+return_to_handler:
+ stmdb sp!, {r0-r3}
+ mov r0, fp @ frame pointer
+ bl ftrace_return_to_handler
+ mov lr, r0 @ r0 has real ret addr
+ ldmia sp!, {r0-r3}
+ mov pc, lr
+#endif
+
+ENTRY(ftrace_stub)
+.Lftrace_stub:
+ mov pc, lr
+ENDPROC(ftrace_stub)
+
+#endif /* CONFIG_FUNCTION_TRACER */
+
+/*=============================================================================
+ * SWI handler
+ *-----------------------------------------------------------------------------
+ */
+
+ /* If we're optimising for StrongARM the resulting code won't
+ run on an ARM7 and we can save a couple of instructions.
+ --pb */
+#ifdef CONFIG_CPU_ARM710
+#define A710(code...) code
+.Larm710bug:
+ ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
+ mov r0, r0
+ add sp, sp, #S_FRAME_SIZE
+ subs pc, lr, #4
+#else
+#define A710(code...)
+#endif
+
+ .align 5
+ENTRY(vector_swi)
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0 - r12
+ ARM( add r8, sp, #S_PC )
+ ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
+ THUMB( mov r8, sp )
+ THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
+ mrs r8, spsr @ called from non-FIQ mode, so ok.
+ str lr, [sp, #S_PC] @ Save calling PC
+ str r8, [sp, #S_PSR] @ Save CPSR
+ str r0, [sp, #S_OLD_R0] @ Save OLD_R0
+ zero_fp
+
+ /*
+ * Get the system call number.
+ */
+
+#if defined(CONFIG_OABI_COMPAT)
+
+ /*
+ * If we have CONFIG_OABI_COMPAT then we need to look at the swi
+ * value to determine if it is an EABI or an old ABI call.
+ */
+#ifdef CONFIG_ARM_THUMB
+ tst r8, #PSR_T_BIT
+ movne r10, #0 @ no thumb OABI emulation
+ ldreq r10, [lr, #-4] @ get SWI instruction
+#else
+ ldr r10, [lr, #-4] @ get SWI instruction
+ A710( and ip, r10, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+#endif
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ rev r10, r10 @ little endian instruction
+#endif
+
+#elif defined(CONFIG_AEABI)
+
+ /*
+ * Pure EABI user space always put syscall number into scno (r7).
+ */
+ A710( ldr ip, [lr, #-4] @ get SWI instruction )
+ A710( and ip, ip, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
+#elif defined(CONFIG_ARM_THUMB)
+
+ /* Legacy ABI only, possibly thumb mode. */
+ tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
+ addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
+ ldreq scno, [lr, #-4]
+
+#else
+
+ /* Legacy ABI only. */
+ ldr scno, [lr, #-4] @ get SWI instruction
+ A710( and ip, scno, #0x0f000000 @ check for SWI )
+ A710( teq ip, #0x0f000000 )
+ A710( bne .Larm710bug )
+
+#endif
+
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr ip, __cr_alignment
+ ldr ip, [ip]
+ mcr p15, 0, ip, c1, c0 @ update control register
+#endif
+ enable_irq
+
+ get_thread_info tsk
+ adr tbl, sys_call_table @ load syscall table pointer
+
+#if defined(CONFIG_OABI_COMPAT)
+ /*
+ * If the swi argument is zero, this is an EABI call and we do nothing.
+ *
+ * If this is an old ABI call, get the syscall number into scno and
+ * get the old ABI syscall table address.
+ */
+ bics r10, r10, #0xff000000
+ eorne scno, r10, #__NR_OABI_SYSCALL_BASE
+ ldrne tbl, =sys_oabi_call_table
+#elif !defined(CONFIG_AEABI)
+ bic scno, scno, #0xff000000 @ mask off SWI op-code
+ eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
+#endif
+
+ ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
+ stmdb sp!, {r4, r5} @ push fifth and sixth args
+
+#ifdef CONFIG_SECCOMP
+ tst r10, #_TIF_SECCOMP
+ beq 1f
+ mov r0, scno
+ bl __secure_computing
+ add r0, sp, #S_R0 + S_OFF @ pointer to regs
+ ldmia r0, {r0 - r3} @ have to reload r0 - r3
+1:
+#endif
+
+ tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
+ bne __sys_trace
+
+ cmp scno, #NR_syscalls @ check upper syscall limit
+ adr lr, BSYM(ret_fast_syscall) @ return address
+ ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+
+ add r1, sp, #S_OFF
+2: mov why, #0 @ no longer a real syscall
+ cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
+ eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
+ bcs arm_syscall
+ b sys_ni_syscall @ not private func
+ENDPROC(vector_swi)
+
+ /*
+ * This is the really slow path. We're going to be doing
+ * context switches, and waiting for our parent to respond.
+ */
+__sys_trace:
+ mov r2, scno
+ add r1, sp, #S_OFF
+ mov r0, #0 @ trace entry [IP = 0]
+ bl syscall_trace
+
+ adr lr, BSYM(__sys_trace_return) @ return address
+ mov scno, r0 @ syscall number (possibly new)
+ add r1, sp, #S_R0 + S_OFF @ pointer to regs
+ cmp scno, #NR_syscalls @ check upper syscall limit
+ ldmccia r1, {r0 - r3} @ have to reload r0 - r3
+ ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
+ b 2b
+
+__sys_trace_return:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ mov r2, scno
+ mov r1, sp
+ mov r0, #1 @ trace exit [IP = 1]
+ bl syscall_trace
+ b ret_slow_syscall
+
+ .align 5
+#ifdef CONFIG_ALIGNMENT_TRAP
+ .type __cr_alignment, #object
+__cr_alignment:
+ .word cr_alignment
+#endif
+ .ltorg
+
+/*
+ * This is the syscall table declaration for native ABI syscalls.
+ * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall.
+ */
+#define ABI(native, compat) native
+#ifdef CONFIG_AEABI
+#define OBSOLETE(syscall) sys_ni_syscall
+#else
+#define OBSOLETE(syscall) syscall
+#endif
+
+ .type sys_call_table, #object
+ENTRY(sys_call_table)
+#include "calls.S"
+#undef ABI
+#undef OBSOLETE
+
+/*============================================================================
+ * Special system call wrappers
+ */
+@ r0 = syscall number
+@ r8 = syscall table
+sys_syscall:
+ bic scno, r0, #__NR_OABI_SYSCALL_BASE
+ cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
+ cmpne scno, #NR_syscalls @ check range
+ stmloia sp, {r5, r6} @ shuffle args
+ movlo r0, r1
+ movlo r1, r2
+ movlo r2, r3
+ movlo r3, r4
+ ldrlo pc, [tbl, scno, lsl #2]
+ b sys_ni_syscall
+ENDPROC(sys_syscall)
+
+sys_fork_wrapper:
+ add r0, sp, #S_OFF
+ b sys_fork
+ENDPROC(sys_fork_wrapper)
+
+sys_vfork_wrapper:
+ add r0, sp, #S_OFF
+ b sys_vfork
+ENDPROC(sys_vfork_wrapper)
+
+sys_execve_wrapper:
+ add r3, sp, #S_OFF
+ b sys_execve
+ENDPROC(sys_execve_wrapper)
+
+sys_clone_wrapper:
+ add ip, sp, #S_OFF
+ str ip, [sp, #4]
+ b sys_clone
+ENDPROC(sys_clone_wrapper)
+
+sys_sigreturn_wrapper:
+ add r0, sp, #S_OFF
+ mov why, #0 @ prevent syscall restart handling
+ b sys_sigreturn
+ENDPROC(sys_sigreturn_wrapper)
+
+sys_rt_sigreturn_wrapper:
+ add r0, sp, #S_OFF
+ mov why, #0 @ prevent syscall restart handling
+ b sys_rt_sigreturn
+ENDPROC(sys_rt_sigreturn_wrapper)
+
+sys_sigaltstack_wrapper:
+ ldr r2, [sp, #S_OFF + S_SP]
+ b do_sigaltstack
+ENDPROC(sys_sigaltstack_wrapper)
+
+sys_statfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_statfs64
+ENDPROC(sys_statfs64_wrapper)
+
+sys_fstatfs64_wrapper:
+ teq r1, #88
+ moveq r1, #84
+ b sys_fstatfs64
+ENDPROC(sys_fstatfs64_wrapper)
+
+/*
+ * Note: off_4k (r5) is always units of 4K. If we can't do the requested
+ * offset, we return EINVAL.
+ */
+sys_mmap2:
+#if PAGE_SHIFT > 12
+ tst r5, #PGOFF_MASK
+ moveq r5, r5, lsr #PAGE_SHIFT - 12
+ streq r5, [sp, #4]
+ beq sys_mmap_pgoff
+ mov r0, #-EINVAL
+ mov pc, lr
+#else
+ str r5, [sp, #4]
+ b sys_mmap_pgoff
+#endif
+ENDPROC(sys_mmap2)
+
+#ifdef CONFIG_OABI_COMPAT
+
+/*
+ * These are syscalls with argument register differences
+ */
+
+sys_oabi_pread64:
+ stmia sp, {r3, r4}
+ b sys_pread64
+ENDPROC(sys_oabi_pread64)
+
+sys_oabi_pwrite64:
+ stmia sp, {r3, r4}
+ b sys_pwrite64
+ENDPROC(sys_oabi_pwrite64)
+
+sys_oabi_truncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_truncate64
+ENDPROC(sys_oabi_truncate64)
+
+sys_oabi_ftruncate64:
+ mov r3, r2
+ mov r2, r1
+ b sys_ftruncate64
+ENDPROC(sys_oabi_ftruncate64)
+
+sys_oabi_readahead:
+ str r3, [sp]
+ mov r3, r2
+ mov r2, r1
+ b sys_readahead
+ENDPROC(sys_oabi_readahead)
+
+/*
+ * Let's declare a second syscall table for old ABI binaries
+ * using the compatibility syscall entries.
+ */
+#define ABI(native, compat) compat
+#define OBSOLETE(syscall) syscall
+
+ .type sys_oabi_call_table, #object
+ENTRY(sys_oabi_call_table)
+#include "calls.S"
+#undef ABI
+#undef OBSOLETE
+
+#endif
+
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
new file mode 100644
index 00000000..051166c2
--- /dev/null
+++ b/arch/arm/kernel/entry-header.S
@@ -0,0 +1,200 @@
+#include <linux/init.h>
+#include <linux/linkage.h>
+
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/errno.h>
+#include <asm/thread_info.h>
+
+@ Bad Abort numbers
+@ -----------------
+@
+#define BAD_PREFETCH 0
+#define BAD_DATA 1
+#define BAD_ADDREXCPTN 2
+#define BAD_IRQ 3
+#define BAD_UNDEFINSTR 4
+
+@
+@ Most of the stack format comes from struct pt_regs, but with
+@ the addition of 8 bytes for storing syscall args 5 and 6.
+@ This _must_ remain a multiple of 8 for EABI.
+@
+#define S_OFF 8
+
+/*
+ * The SWI code relies on the fact that R0 is at the bottom of the stack
+ * (due to slow/fast restore user regs).
+ */
+#if S_R0 != 0
+#error "Please fix"
+#endif
+
+ .macro zero_fp
+#ifdef CONFIG_FRAME_POINTER
+ mov fp, #0
+#endif
+ .endm
+
+ .macro alignment_trap, rtemp
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr \rtemp, .LCcralign
+ ldr \rtemp, [\rtemp]
+ mcr p15, 0, \rtemp, c1, c0
+#endif
+ .endm
+
+ @
+ @ Store/load the USER SP and LR registers by switching to the SYS
+ @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not
+ @ available. Should only be called from SVC mode
+ @
+ .macro store_user_sp_lr, rd, rtemp, offset = 0
+ mrs \rtemp, cpsr
+ eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+ msr cpsr_c, \rtemp @ switch to the SYS mode
+
+ str sp, [\rd, #\offset] @ save sp_usr
+ str lr, [\rd, #\offset + 4] @ save lr_usr
+
+ eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+ msr cpsr_c, \rtemp @ switch back to the SVC mode
+ .endm
+
+ .macro load_user_sp_lr, rd, rtemp, offset = 0
+ mrs \rtemp, cpsr
+ eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+ msr cpsr_c, \rtemp @ switch to the SYS mode
+
+ ldr sp, [\rd, #\offset] @ load sp_usr
+ ldr lr, [\rd, #\offset + 4] @ load lr_usr
+
+ eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE)
+ msr cpsr_c, \rtemp @ switch back to the SVC mode
+ .endm
+
+#ifndef CONFIG_THUMB2_KERNEL
+ .macro svc_exit, rpsr
+ msr spsr_cxsf, \rpsr
+#if defined(CONFIG_CPU_V6)
+ ldr r0, [sp]
+ strex r1, r2, [sp] @ clear the exclusive monitor
+ ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr
+#elif defined(CONFIG_CPU_32v6K)
+ clrex @ clear the exclusive monitor
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+#else
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
+#endif
+ .endm
+
+ .macro restore_user_regs, fast = 0, offset = 0
+ ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [sp, #\offset + S_PC]! @ get pc
+ msr spsr_cxsf, r1 @ save in spsr_svc
+#if defined(CONFIG_CPU_V6)
+ strex r1, r2, [sp] @ clear the exclusive monitor
+#elif defined(CONFIG_CPU_32v6K)
+ clrex @ clear the exclusive monitor
+#endif
+ .if \fast
+ ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
+ .else
+ ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
+ .endif
+ mov r0, r0 @ ARMv5T and earlier require a nop
+ @ after ldm {}^
+ add sp, sp, #S_FRAME_SIZE - S_PC
+ movs pc, lr @ return & move spsr_svc into cpsr
+ .endm
+
+ .macro get_thread_info, rd
+ mov \rd, sp, lsr #13
+ mov \rd, \rd, lsl #13
+ .endm
+
+ @
+ @ 32-bit wide "mov pc, reg"
+ @
+ .macro movw_pc, reg
+ mov pc, \reg
+ .endm
+#else /* CONFIG_THUMB2_KERNEL */
+ .macro svc_exit, rpsr
+ clrex @ clear the exclusive monitor
+ ldr r0, [sp, #S_SP] @ top of the stack
+ ldr r1, [sp, #S_PC] @ return address
+ tst r0, #4 @ orig stack 8-byte aligned?
+ stmdb r0, {r1, \rpsr} @ rfe context
+ ldmia sp, {r0 - r12}
+ ldr lr, [sp, #S_LR]
+ addeq sp, sp, #S_FRAME_SIZE - 8 @ aligned
+ addne sp, sp, #S_FRAME_SIZE - 4 @ not aligned
+ rfeia sp!
+ .endm
+
+ .macro restore_user_regs, fast = 0, offset = 0
+ clrex @ clear the exclusive monitor
+ mov r2, sp
+ load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr
+ ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [sp, #\offset + S_PC] @ get pc
+ add sp, sp, #\offset + S_SP
+ msr spsr_cxsf, r1 @ save in spsr_svc
+ .if \fast
+ ldmdb sp, {r1 - r12} @ get calling r1 - r12
+ .else
+ ldmdb sp, {r0 - r12} @ get calling r0 - r12
+ .endif
+ add sp, sp, #S_FRAME_SIZE - S_SP
+ movs pc, lr @ return & move spsr_svc into cpsr
+ .endm
+
+ .macro get_thread_info, rd
+ mov \rd, sp
+ lsr \rd, \rd, #13
+ mov \rd, \rd, lsl #13
+ .endm
+
+ @
+ @ 32-bit wide "mov pc, reg"
+ @
+ .macro movw_pc, reg
+ mov pc, \reg
+ nop
+ .endm
+#endif /* !CONFIG_THUMB2_KERNEL */
+
+ @
+ @ Debug exceptions are taken as prefetch or data aborts.
+ @ We must disable preemption during the handler so that
+ @ we can access the debug registers safely.
+ @
+ .macro debug_entry, fsr
+#if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT)
+ ldr r4, =0x40f @ mask out fsr.fs
+ and r5, r4, \fsr
+ cmp r5, #2 @ debug exception
+ bne 1f
+ get_thread_info r10
+ ldr r6, [r10, #TI_PREEMPT] @ get preempt count
+ add r11, r6, #1 @ increment it
+ str r11, [r10, #TI_PREEMPT]
+1:
+#endif
+ .endm
+
+/*
+ * These are the registers used in the syscall handler, and allow us to
+ * have in theory up to 7 arguments to a function - r0 to r6.
+ *
+ * r7 is reserved for the system call number for thumb mode.
+ *
+ * Note that tbl == why is intentional.
+ *
+ * We must set at least "tsk" and "why" when calling ret_with_reschedule.
+ */
+scno .req r7 @ syscall number
+tbl .req r8 @ syscall table pointer
+why .req r8 @ Linux syscall (!= 0)
+tsk .req r9 @ current thread_info
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
new file mode 100644
index 00000000..93d06ba0
--- /dev/null
+++ b/arch/arm/kernel/etm.c
@@ -0,0 +1,1075 @@
+/*
+ * linux/arch/arm/kernel/etm.c
+ *
+ * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/sysrq.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/amba/bus.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/mutex.h>
+#include <asm/hardware/coresight.h>
+#include <asm/sections.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+/*
+ * ETM tracer state
+ */
+struct tracectx {
+ unsigned int etb_bufsz;
+ void __iomem *etb_regs;
+ void __iomem **etm_regs;
+ int etm_regs_count;
+ unsigned long flags;
+ int ncmppairs;
+ int etm_portsz;
+ int etm_contextid_size;
+ 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 = {
+ .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 id, int n,
+ unsigned long start, unsigned long end, int exclude, int data)
+{
+ u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
+ ETMAAT_NOVALCMP;
+
+ if (n < 1 || n > t->ncmppairs)
+ return -EINVAL;
+
+ /* comparators and ranges are numbered starting with 1 as opposed
+ * to bits in a word */
+ n--;
+
+ if (data)
+ flags |= ETMAAT_DLOADSTORE;
+ else
+ flags |= ETMAAT_IEXEC;
+
+ /* first comparator for the range */
+ 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, 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_etm(struct tracectx *t, int id)
+{
+ u32 v;
+ unsigned long timeout = TRACER_TIMEOUT;
+
+ v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
+ v |= ETMCTRL_CONTEXTIDSIZE(t->etm_contextid_size);
+
+ if (t->flags & TRACER_CYCLE_ACC)
+ v |= ETMCTRL_CYCLEACCURATE;
+
+ if (t->flags & TRACER_BRANCHOUTPUT)
+ v |= ETMCTRL_BRANCH_OUTPUT;
+
+ if (t->flags & TRACER_TRACE_DATA)
+ v |= ETMCTRL_DATA_DO_ADDR;
+
+ if (t->flags & TRACER_TIMESTAMP)
+ v |= ETMCTRL_TIMESTAMP_EN;
+
+ if (t->flags & TRACER_RETURN_STACK)
+ v |= ETMCTRL_RETURN_STACK_EN;
+
+ etm_unlock(t, id);
+
+ etm_writel(t, id, v, 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, id);
+ return -EFAULT;
+ }
+
+ 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, id, v, ETMR_CTRL);
+
+ timeout = TRACER_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, id);
+ return -EFAULT;
+ }
+
+ 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_etm(struct tracectx *t, int id)
+{
+ unsigned long timeout = TRACER_TIMEOUT;
+
+ etm_unlock(t, id);
+
+ etm_writel(t, id, 0x440, ETMR_CTRL);
+ while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+ ;
+ if (!timeout) {
+ dev_err(t->dev,
+ "etm%d: Waiting for progbit to assert timed out\n",
+ id);
+ etm_lock(t, id);
+ return -EFAULT;
+ }
+
+ etm_lock(t, id);
+ return 0;
+}
+
+static int trace_power_down_etm(struct tracectx *t, int id)
+{
+ unsigned long timeout = TRACER_TIMEOUT;
+ etm_unlock(t, id);
+ while (!(etm_readl(t, id, ETMR_STATUS) & ETMST_PROGBIT) && --timeout)
+ ;
+ if (!timeout) {
+ dev_err(t->dev, "etm%d: Waiting for status progbit to assert timed out\n",
+ id);
+ etm_lock(t, id);
+ return -EFAULT;
+ }
+
+ etm_writel(t, id, 0x441, ETMR_CTRL);
+
+ etm_lock(t, id);
+ return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+ int id;
+ unsigned long timeout = TRACER_TIMEOUT;
+ u32 etb_fc = t->etb_fc;
+
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_stop_etm(t, id);
+
+ for (id = 0; id < t->etm_regs_count; id++)
+ trace_power_down_etm(t, id);
+
+ etb_unlock(t);
+ 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) &
+ ETBFF_MANUAL_FLUSH && --timeout)
+ ;
+ if (!timeout) {
+ dev_dbg(t->dev, "Waiting for formatter flush to commence "
+ "timed out\n");
+ etb_lock(t);
+ return -EFAULT;
+ }
+
+ etb_writel(t, 0, ETBR_CTRL);
+
+ etb_lock(t);
+
+ t->flags &= ~TRACER_RUNNING;
+
+ return 0;
+}
+
+static int etb_getdatalen(struct tracectx *t)
+{
+ u32 v;
+ int wp;
+
+ v = etb_readl(t, ETBR_STATUS);
+
+ if (v & 1)
+ return t->etb_bufsz;
+
+ wp = etb_readl(t, ETBR_WRITEADDR);
+ return wp;
+}
+
+/* sysrq+v will always stop the running trace and leave it at that */
+static void etm_dump(void)
+{
+ struct tracectx *t = &tracer;
+ u32 first = 0;
+ int length;
+
+ if (!t->etb_regs) {
+ printk(KERN_INFO "No tracing hardware found\n");
+ return;
+ }
+
+ if (trace_isrunning(t))
+ trace_stop(t);
+
+ etb_unlock(t);
+
+ length = etb_getdatalen(t);
+
+ if (length == t->etb_bufsz)
+ first = etb_readl(t, ETBR_WRITEADDR);
+
+ etb_writel(t, first, ETBR_READADDR);
+
+ printk(KERN_INFO "Trace buffer contents length: %d\n", length);
+ printk(KERN_INFO "--- ETB buffer begin ---\n");
+ for (; length; length--)
+ printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
+ printk(KERN_INFO "\n--- ETB buffer end ---\n");
+
+ 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 = {
+ .handler = sysrq_etm_dump,
+ .help_msg = "ETM buffer dump",
+ .action_msg = "etm",
+};
+
+static int etb_open(struct inode *inode, struct file *file)
+{
+ if (!tracer.etb_regs)
+ return -ENODEV;
+
+ file->private_data = &tracer;
+
+ return nonseekable_open(inode, file);
+}
+
+static ssize_t etb_read(struct file *file, char __user *data,
+ size_t len, loff_t *ppos)
+{
+ int total, i;
+ long length;
+ 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);
+
+ if (trace_isrunning(t)) {
+ length = 0;
+ goto out;
+ }
+
+ 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);
+
+ 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 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 < wlength; i++)
+ buf[i] = etb_readl(t, ETBR_READMEM);
+
+ etb_lock(t);
+
+ length -= copy_to_user(data, (u8 *)buf + skip, length);
+ vfree(buf);
+ *ppos = pos + length;
+
+out:
+ mutex_unlock(&t->mutex);
+
+ return length;
+}
+
+static int etb_release(struct inode *inode, struct file *file)
+{
+ /* there's nothing to do here, actually */
+ return 0;
+}
+
+static const struct file_operations etb_fops = {
+ .owner = THIS_MODULE,
+ .read = etb_read,
+ .open = etb_open,
+ .release = etb_release,
+ .llseek = no_llseek,
+};
+
+static struct miscdevice etb_miscdev = {
+ .name = "tracebuf",
+ .minor = 0,
+ .fops = &etb_fops,
+};
+
+static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
+{
+ struct tracectx *t = &tracer;
+ int ret = 0;
+
+ ret = amba_request_regions(dev, NULL);
+ 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_unlock(t);
+ t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
+ dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
+
+ /* make sure trace capture is disabled */
+ 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");
+
+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;
+}
+
+static int etb_remove(struct amba_device *dev)
+{
+ struct tracectx *t = amba_get_drvdata(dev);
+
+ amba_set_drvdata(dev, NULL);
+
+ iounmap(t->etb_regs);
+ t->etb_regs = NULL;
+
+ if (!IS_ERR(t->emu_clk)) {
+ clk_disable(t->emu_clk);
+ clk_put(t->emu_clk);
+ }
+
+ amba_release_regions(dev);
+
+ return 0;
+}
+
+static struct amba_id etb_ids[] = {
+ {
+ .id = 0x0003b907,
+ .mask = 0x0007ffff,
+ },
+ { 0, 0 },
+};
+
+static struct amba_driver etb_driver = {
+ .drv = {
+ .name = "etb",
+ .owner = THIS_MODULE,
+ },
+ .probe = etb_probe,
+ .remove = etb_remove,
+ .id_table = etb_ids,
+};
+
+/* use a sysfs file "trace_running" to start/stop tracing */
+static ssize_t trace_running_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%x\n", trace_isrunning(&tracer));
+}
+
+static ssize_t trace_running_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int value;
+ int ret;
+
+ if (sscanf(buf, "%u", &value) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (!tracer.etb_regs)
+ ret = -ENODEV;
+ else
+ ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+ mutex_unlock(&tracer.mutex);
+
+ return ret ? : n;
+}
+
+static struct kobj_attribute trace_running_attr =
+ __ATTR(trace_running, 0644, trace_running_show, trace_running_store);
+
+static ssize_t trace_info_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
+ int datalen;
+ int id;
+ int ret;
+
+ 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;
+ }
+
+ 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",
+ datalen,
+ tracer.ncmppairs,
+ etb_wa,
+ etb_ra,
+ etb_st,
+ 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 =
+ __ATTR(trace_info, 0444, trace_info_show, NULL);
+
+static ssize_t trace_mode_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d %d\n",
+ !!(tracer.flags & TRACER_CYCLE_ACC),
+ tracer.etm_portsz);
+}
+
+static ssize_t trace_mode_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int cycacc, portsz;
+
+ if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (cycacc)
+ tracer.flags |= TRACER_CYCLE_ACC;
+ else
+ tracer.flags &= ~TRACER_CYCLE_ACC;
+
+ tracer.etm_portsz = portsz & 0x0f;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_mode_attr =
+ __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+
+static ssize_t trace_contextid_size_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ /* 0: No context id tracing, 1: One byte, 2: Two bytes, 3: Four bytes */
+ return sprintf(buf, "%d\n", (1 << tracer.etm_contextid_size) >> 1);
+}
+
+static ssize_t trace_contextid_size_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int contextid_size;
+
+ if (sscanf(buf, "%u", &contextid_size) != 1)
+ return -EINVAL;
+
+ if (contextid_size == 3 || contextid_size > 4)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ tracer.etm_contextid_size = fls(contextid_size);
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_contextid_size_attr =
+ __ATTR(trace_contextid_size, 0644,
+ trace_contextid_size_show, trace_contextid_size_store);
+
+static ssize_t trace_branch_output_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_BRANCHOUTPUT));
+}
+
+static ssize_t trace_branch_output_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int branch_output;
+
+ if (sscanf(buf, "%u", &branch_output) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (branch_output) {
+ tracer.flags |= TRACER_BRANCHOUTPUT;
+ /* Branch broadcasting is incompatible with the return stack */
+ tracer.flags &= ~TRACER_RETURN_STACK;
+ } else {
+ tracer.flags &= ~TRACER_BRANCHOUTPUT;
+ }
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_branch_output_attr =
+ __ATTR(trace_branch_output, 0644,
+ trace_branch_output_show, trace_branch_output_store);
+
+static ssize_t trace_return_stack_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_RETURN_STACK));
+}
+
+static ssize_t trace_return_stack_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int return_stack;
+
+ if (sscanf(buf, "%u", &return_stack) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (return_stack) {
+ tracer.flags |= TRACER_RETURN_STACK;
+ /* Return stack is incompatible with branch broadcasting */
+ tracer.flags &= ~TRACER_BRANCHOUTPUT;
+ } else {
+ tracer.flags &= ~TRACER_RETURN_STACK;
+ }
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_return_stack_attr =
+ __ATTR(trace_return_stack, 0644,
+ trace_return_stack_show, trace_return_stack_store);
+
+static ssize_t trace_timestamp_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", !!(tracer.flags & TRACER_TIMESTAMP));
+}
+
+static ssize_t trace_timestamp_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t n)
+{
+ unsigned int timestamp;
+
+ if (sscanf(buf, "%u", &timestamp) != 1)
+ return -EINVAL;
+
+ mutex_lock(&tracer.mutex);
+ if (timestamp)
+ tracer.flags |= TRACER_TIMESTAMP;
+ else
+ tracer.flags &= ~TRACER_TIMESTAMP;
+ mutex_unlock(&tracer.mutex);
+
+ return n;
+}
+
+static struct kobj_attribute trace_timestamp_attr =
+ __ATTR(trace_timestamp, 0644,
+ trace_timestamp_show, trace_timestamp_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;
+ u32 etmccr;
+ u32 etmidr;
+ u32 etmccer = 0;
+ u8 etm_version = 0;
+
+ 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[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->etm_regs[t->etm_regs_count]);
+
+ t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA | TRACER_BRANCHOUTPUT;
+ t->etm_portsz = 1;
+ t->etm_contextid_size = 3;
+
+ etm_unlock(t, t->etm_regs_count);
+ (void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
+ /* dummy first read */
+ (void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
+
+ etmccr = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE);
+ t->ncmppairs = etmccr & 0xf;
+ if (etmccr & ETMCCR_ETMIDR_PRESENT) {
+ etmidr = etm_readl(t, t->etm_regs_count, ETMR_ID);
+ etm_version = ETMIDR_VERSION(etmidr);
+ if (etm_version >= ETMIDR_VERSION_3_1)
+ etmccer = etm_readl(t, t->etm_regs_count, ETMR_CCE);
+ }
+ 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);
+ if (ret)
+ goto out_unmap;
+
+ /* failing to create any of these two is not fatal */
+ ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
+
+ ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
+
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_contextid_size_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_contextid_size in sysfs\n");
+
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_branch_output_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_branch_output in sysfs\n");
+
+ if (etmccer & ETMCCER_RETURN_STACK_IMPLEMENTED) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_return_stack_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_return_stack in sysfs\n");
+ }
+
+ if (etmccer & ETMCCER_TIMESTAMPING_IMPLEMENTED) {
+ ret = sysfs_create_file(&dev->dev.kobj,
+ &trace_timestamp_attr.attr);
+ if (ret)
+ dev_dbg(&dev->dev,
+ "Failed to create trace_timestamp in sysfs\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");
+
+ if (etm_version < ETMIDR_VERSION_PFT_1_0) {
+ 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");
+ } else {
+ tracer.flags &= ~TRACER_TRACE_DATA;
+ }
+
+ 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[t->etm_regs_count]);
+
+out_release:
+ amba_release_regions(dev);
+
+ mutex_unlock(&t->mutex);
+ return ret;
+}
+
+static int etm_remove(struct amba_device *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);
+
+ 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);
+
+ return 0;
+}
+
+static struct amba_id etm_ids[] = {
+ {
+ .id = 0x0003b921,
+ .mask = 0x0007ffff,
+ },
+ {
+ .id = 0x0003b950,
+ .mask = 0x0007ffff,
+ },
+ { 0, 0 },
+};
+
+static struct amba_driver etm_driver = {
+ .drv = {
+ .name = "etm",
+ .owner = THIS_MODULE,
+ },
+ .probe = etm_probe,
+ .remove = etm_remove,
+ .id_table = etm_ids,
+};
+
+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");
+ return retval;
+ }
+
+ retval = amba_driver_register(&etm_driver);
+ if (retval) {
+ amba_driver_unregister(&etb_driver);
+ printk(KERN_ERR "Failed to probe etm\n");
+ return retval;
+ }
+
+ /* not being able to install this handler is not fatal */
+ (void)register_sysrq_key('v', &sysrq_etm_op);
+
+ return 0;
+}
+
+device_initcall(etm_init);
+
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
new file mode 100644
index 00000000..4c164ece
--- /dev/null
+++ b/arch/arm/kernel/fiq.c
@@ -0,0 +1,146 @@
+/*
+ * linux/arch/arm/kernel/fiq.c
+ *
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998, 1999 Phil Blundell
+ *
+ * FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
+ *
+ * FIQ support re-written by Russell King to be more generic
+ *
+ * We now properly support a method by which the FIQ handlers can
+ * be stacked onto the vector. We still do not support sharing
+ * the FIQ vector itself.
+ *
+ * Operation is as follows:
+ * 1. Owner A claims FIQ:
+ * - default_fiq relinquishes control.
+ * 2. Owner A:
+ * - inserts code.
+ * - sets any registers,
+ * - enables FIQ.
+ * 3. Owner B claims FIQ:
+ * - if owner A has a relinquish function.
+ * - disable FIQs.
+ * - saves any registers.
+ * - returns zero.
+ * 4. Owner B:
+ * - inserts code.
+ * - sets any registers,
+ * - enables FIQ.
+ * 5. Owner B releases FIQ:
+ * - Owner A is asked to reacquire FIQ:
+ * - inserts code.
+ * - restores saved registers.
+ * - enables FIQ.
+ * 6. Goto 3
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+
+#include <asm/cacheflush.h>
+#include <asm/fiq.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+static unsigned long no_fiq_insn;
+
+/* Default reacquire function
+ * - we always relinquish FIQ control
+ * - we always reacquire FIQ control
+ */
+static int fiq_def_op(void *ref, int relinquish)
+{
+ if (!relinquish)
+ set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn));
+
+ return 0;
+}
+
+static struct fiq_handler default_owner = {
+ .name = "default",
+ .fiq_op = fiq_def_op,
+};
+
+static struct fiq_handler *current_fiq = &default_owner;
+
+int show_fiq_list(struct seq_file *p, int prec)
+{
+ if (current_fiq != &default_owner)
+ seq_printf(p, "%*s: %s\n", prec, "FIQ",
+ current_fiq->name);
+
+ return 0;
+}
+
+void set_fiq_handler(void *start, unsigned int length)
+{
+#if defined(CONFIG_CPU_USE_DOMAINS)
+ memcpy((void *)0xffff001c, start, length);
+#else
+ memcpy(vectors_page + 0x1c, start, length);
+#endif
+ flush_icache_range(0xffff001c, 0xffff001c + length);
+ if (!vectors_high())
+ flush_icache_range(0x1c, 0x1c + length);
+}
+
+int claim_fiq(struct fiq_handler *f)
+{
+ int ret = 0;
+
+ if (current_fiq) {
+ ret = -EBUSY;
+
+ if (current_fiq->fiq_op != NULL)
+ ret = current_fiq->fiq_op(current_fiq->dev_id, 1);
+ }
+
+ if (!ret) {
+ f->next = current_fiq;
+ current_fiq = f;
+ }
+
+ return ret;
+}
+
+void release_fiq(struct fiq_handler *f)
+{
+ if (current_fiq != f) {
+ printk(KERN_ERR "%s FIQ trying to release %s FIQ\n",
+ f->name, current_fiq->name);
+ dump_stack();
+ return;
+ }
+
+ do
+ current_fiq = current_fiq->next;
+ while (current_fiq->fiq_op(current_fiq->dev_id, 0));
+}
+
+void enable_fiq(int fiq)
+{
+ enable_irq(fiq + FIQ_START);
+}
+
+void disable_fiq(int fiq)
+{
+ disable_irq(fiq + FIQ_START);
+}
+
+EXPORT_SYMBOL(set_fiq_handler);
+EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */
+EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */
+EXPORT_SYMBOL(claim_fiq);
+EXPORT_SYMBOL(release_fiq);
+EXPORT_SYMBOL(enable_fiq);
+EXPORT_SYMBOL(disable_fiq);
+
+void __init init_FIQ(void)
+{
+ no_fiq_insn = *(unsigned long *)0xffff001c;
+}
diff --git a/arch/arm/kernel/fiqasm.S b/arch/arm/kernel/fiqasm.S
new file mode 100644
index 00000000..207f9d65
--- /dev/null
+++ b/arch/arm/kernel/fiqasm.S
@@ -0,0 +1,49 @@
+/*
+ * linux/arch/arm/kernel/fiqasm.S
+ *
+ * Derived from code originally in linux/arch/arm/kernel/fiq.c:
+ *
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998, 1999 Phil Blundell
+ * Copyright (C) 2011, Linaro Limited
+ *
+ * FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
+ *
+ * FIQ support re-written by Russell King to be more generic
+ *
+ * v7/Thumb-2 compatibility modifications by Linaro Limited, 2011.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Taking an interrupt in FIQ mode is death, so both these functions
+ * disable irqs for the duration.
+ */
+
+ENTRY(__set_fiq_regs)
+ mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+ mrs r1, cpsr
+ msr cpsr_c, r2 @ select FIQ mode
+ mov r0, r0 @ avoid hazard prior to ARMv4
+ ldmia r0!, {r8 - r12}
+ ldr sp, [r0], #4
+ ldr lr, [r0]
+ msr cpsr_c, r1 @ return to SVC mode
+ mov r0, r0 @ avoid hazard prior to ARMv4
+ mov pc, lr
+ENDPROC(__set_fiq_regs)
+
+ENTRY(__get_fiq_regs)
+ mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+ mrs r1, cpsr
+ msr cpsr_c, r2 @ select FIQ mode
+ mov r0, r0 @ avoid hazard prior to ARMv4
+ stmia r0!, {r8 - r12}
+ str sp, [r0], #4
+ str lr, [r0]
+ msr cpsr_c, r1 @ return to SVC mode
+ mov r0, r0 @ avoid hazard prior to ARMv4
+ mov pc, lr
+ENDPROC(__get_fiq_regs)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
new file mode 100644
index 00000000..c0062ad1
--- /dev/null
+++ b/arch/arm/kernel/ftrace.c
@@ -0,0 +1,288 @@
+/*
+ * Dynamic function tracing support.
+ *
+ * Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com>
+ * Copyright (C) 2010 Rabin Vincent <rabin@rab.in>
+ *
+ * For licencing details, see COPYING.
+ *
+ * Defines low-level handling of mcount calls when the kernel
+ * is compiled with the -pg flag. When using dynamic ftrace, the
+ * mcount call-sites get patched with NOP till they are enabled.
+ * All code mutation routines here are called under stop_machine().
+ */
+
+#include <linux/ftrace.h>
+#include <linux/uaccess.h>
+
+#include <asm/cacheflush.h>
+#include <asm/ftrace.h>
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define NOP 0xeb04f85d /* pop.w {lr} */
+#else
+#define NOP 0xe8bd4000 /* pop {lr} */
+#endif
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+#ifdef CONFIG_OLD_MCOUNT
+#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
+#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
+
+#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
+
+static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
+{
+ return rec->arch.old_mcount ? OLD_NOP : NOP;
+}
+
+static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+{
+ if (!rec->arch.old_mcount)
+ return addr;
+
+ if (addr == MCOUNT_ADDR)
+ addr = OLD_MCOUNT_ADDR;
+ else if (addr == FTRACE_ADDR)
+ addr = OLD_FTRACE_ADDR;
+
+ return addr;
+}
+#else
+static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
+{
+ return NOP;
+}
+
+static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
+{
+ return addr;
+}
+#endif
+
+#ifdef CONFIG_THUMB2_KERNEL
+static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
+ bool link)
+{
+ unsigned long s, j1, j2, i1, i2, imm10, imm11;
+ unsigned long first, second;
+ long offset;
+
+ offset = (long)addr - (long)(pc + 4);
+ if (offset < -16777216 || offset > 16777214) {
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+
+ s = (offset >> 24) & 0x1;
+ i1 = (offset >> 23) & 0x1;
+ i2 = (offset >> 22) & 0x1;
+ imm10 = (offset >> 12) & 0x3ff;
+ imm11 = (offset >> 1) & 0x7ff;
+
+ j1 = (!i1) ^ s;
+ j2 = (!i2) ^ s;
+
+ first = 0xf000 | (s << 10) | imm10;
+ second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
+ if (link)
+ second |= 1 << 14;
+
+ return (second << 16) | first;
+}
+#else
+static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
+ bool link)
+{
+ unsigned long opcode = 0xea000000;
+ long offset;
+
+ if (link)
+ opcode |= 1 << 24;
+
+ offset = (long)addr - (long)(pc + 8);
+ if (unlikely(offset < -33554432 || offset > 33554428)) {
+ /* Can't generate branches that far (from ARM ARM). Ftrace
+ * doesn't generate branches outside of kernel text.
+ */
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+
+ offset = (offset >> 2) & 0x00ffffff;
+
+ return opcode | offset;
+}
+#endif
+
+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
+{
+ return ftrace_gen_branch(pc, addr, true);
+}
+
+static int ftrace_modify_code(unsigned long pc, unsigned long old,
+ unsigned long new)
+{
+ unsigned long replaced;
+
+ if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
+ return -EFAULT;
+
+ if (replaced != old)
+ return -EINVAL;
+
+ if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
+ return -EPERM;
+
+ flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
+
+ return 0;
+}
+
+int ftrace_update_ftrace_func(ftrace_func_t func)
+{
+ unsigned long pc, old;
+ unsigned long new;
+ int ret;
+
+ pc = (unsigned long)&ftrace_call;
+ memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
+ new = ftrace_call_replace(pc, (unsigned long)func);
+
+ ret = ftrace_modify_code(pc, old, new);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (!ret) {
+ pc = (unsigned long)&ftrace_call_old;
+ memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
+ new = ftrace_call_replace(pc, (unsigned long)func);
+
+ ret = ftrace_modify_code(pc, old, new);
+ }
+#endif
+
+ return ret;
+}
+
+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned long new, old;
+ unsigned long ip = rec->ip;
+
+ old = ftrace_nop_replace(rec);
+ new = ftrace_call_replace(ip, adjust_address(rec, addr));
+
+ return ftrace_modify_code(rec->ip, old, new);
+}
+
+int ftrace_make_nop(struct module *mod,
+ struct dyn_ftrace *rec, unsigned long addr)
+{
+ unsigned long ip = rec->ip;
+ unsigned long old;
+ unsigned long new;
+ int ret;
+
+ old = ftrace_call_replace(ip, adjust_address(rec, addr));
+ new = ftrace_nop_replace(rec);
+ ret = ftrace_modify_code(ip, old, new);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (ret == -EINVAL && addr == MCOUNT_ADDR) {
+ rec->arch.old_mcount = true;
+
+ old = ftrace_call_replace(ip, adjust_address(rec, addr));
+ new = ftrace_nop_replace(rec);
+ ret = ftrace_modify_code(ip, old, new);
+ }
+#endif
+
+ return ret;
+}
+
+int __init ftrace_dyn_arch_init(void *data)
+{
+ *(unsigned long *)data = 0;
+
+ return 0;
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+ unsigned long frame_pointer)
+{
+ unsigned long return_hooker = (unsigned long) &return_to_handler;
+ struct ftrace_graph_ent trace;
+ unsigned long old;
+ int err;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ old = *parent;
+ *parent = return_hooker;
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer);
+ if (err == -EBUSY) {
+ *parent = old;
+ return;
+ }
+
+ trace.func = self_addr;
+
+ /* Only trace if the calling function expects to */
+ if (!ftrace_graph_entry(&trace)) {
+ current->curr_ret_stack--;
+ *parent = old;
+ }
+}
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern unsigned long ftrace_graph_call;
+extern unsigned long ftrace_graph_call_old;
+extern void ftrace_graph_caller_old(void);
+
+static int __ftrace_modify_caller(unsigned long *callsite,
+ void (*func) (void), bool enable)
+{
+ unsigned long caller_fn = (unsigned long) func;
+ unsigned long pc = (unsigned long) callsite;
+ unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
+ unsigned long nop = 0xe1a00000; /* mov r0, r0 */
+ unsigned long old = enable ? nop : branch;
+ unsigned long new = enable ? branch : nop;
+
+ return ftrace_modify_code(pc, old, new);
+}
+
+static int ftrace_modify_graph_caller(bool enable)
+{
+ int ret;
+
+ ret = __ftrace_modify_caller(&ftrace_graph_call,
+ ftrace_graph_caller,
+ enable);
+
+#ifdef CONFIG_OLD_MCOUNT
+ if (!ret)
+ ret = __ftrace_modify_caller(&ftrace_graph_call_old,
+ ftrace_graph_caller_old,
+ enable);
+#endif
+
+ return ret;
+}
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_graph_caller(true);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+ return ftrace_modify_graph_caller(false);
+}
+#endif /* CONFIG_DYNAMIC_FTRACE */
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
new file mode 100644
index 00000000..854bd223
--- /dev/null
+++ b/arch/arm/kernel/head-common.S
@@ -0,0 +1,204 @@
+/*
+ * linux/arch/arm/kernel/head-common.S
+ *
+ * Copyright (C) 1994-2002 Russell King
+ * Copyright (c) 2003 ARM Limited
+ * 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.
+ *
+ */
+
+#define ATAG_CORE 0x54410001
+#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
+#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define OF_DT_MAGIC 0xd00dfeed
+#else
+#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
+#endif
+
+/*
+ * Exception handling. Something went wrong and we can't proceed. We
+ * ought to tell the user, but since we don't have any guarantee that
+ * we're even running on the right architecture, we do virtually nothing.
+ *
+ * If CONFIG_DEBUG_LL is set we try to print out something about the error
+ * and hope for the best (useful if bootloader fails to pass a proper
+ * machine ID for example).
+ */
+ __HEAD
+
+/* Determine validity of the r2 atags pointer. The heuristic requires
+ * that the pointer be aligned, in the first 16k of physical RAM and
+ * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE
+ * is selected, then it will also accept a dtb pointer. Future revisions
+ * of this function may be more lenient with the physical address and
+ * may also be able to move the ATAGS block if necessary.
+ *
+ * Returns:
+ * r2 either valid atags pointer, valid dtb pointer, or zero
+ * r5, r6 corrupted
+ */
+__vet_atags:
+ tst r2, #0x3 @ aligned?
+ bne 1f
+
+ ldr r5, [r2, #0]
+#ifdef CONFIG_OF_FLATTREE
+ ldr r6, =OF_DT_MAGIC @ is it a DTB?
+ cmp r5, r6
+ beq 2f
+#endif
+ cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE?
+ cmpne r5, #ATAG_CORE_SIZE_EMPTY
+ bne 1f
+ ldr r5, [r2, #4]
+ ldr r6, =ATAG_CORE
+ cmp r5, r6
+ bne 1f
+
+2: mov pc, lr @ atag/dtb pointer is ok
+
+1: mov r2, #0
+ mov pc, lr
+ENDPROC(__vet_atags)
+
+/*
+ * The following fragment of code is executed with the MMU on in MMU mode,
+ * and uses absolute addresses; this is not position independent.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags/dtb pointer
+ * r9 = processor ID
+ */
+ __INIT
+__mmap_switched:
+ adr r3, __mmap_switched_data
+
+ ldmia r3!, {r4, r5, r6, r7}
+ cmp r4, r5 @ Copy data segment if needed
+1: cmpne r5, r6
+ ldrne fp, [r4], #4
+ strne fp, [r5], #4
+ bne 1b
+
+ mov fp, #0 @ Clear BSS (and zero fp)
+1: cmp r6, r7
+ strcc fp, [r6],#4
+ bcc 1b
+
+ ARM( ldmia r3, {r4, r5, r6, r7, sp})
+ THUMB( ldmia r3, {r4, r5, r6, r7} )
+ THUMB( ldr sp, [r3, #16] )
+ str r9, [r4] @ Save processor ID
+ str r1, [r5] @ Save machine type
+ str r2, [r6] @ Save atags pointer
+ bic r4, r0, #CR_A @ Clear 'A' bit
+ stmia r7, {r0, r4} @ Save control register values
+ b start_kernel
+ENDPROC(__mmap_switched)
+
+ .align 2
+ .type __mmap_switched_data, %object
+__mmap_switched_data:
+ .long __data_loc @ r4
+ .long _sdata @ r5
+ .long __bss_start @ r6
+ .long _end @ r7
+ .long processor_id @ r4
+ .long __machine_arch_type @ r5
+ .long __atags_pointer @ r6
+ .long cr_alignment @ r7
+ .long init_thread_union + THREAD_START_SP @ sp
+ .size __mmap_switched_data, . - __mmap_switched_data
+
+/*
+ * This provides a C-API version of __lookup_processor_type
+ */
+ENTRY(lookup_processor_type)
+ stmfd sp!, {r4 - r6, r9, lr}
+ mov r9, r0
+ bl __lookup_processor_type
+ mov r0, r5
+ ldmfd sp!, {r4 - r6, r9, pc}
+ENDPROC(lookup_processor_type)
+
+/*
+ * Read processor ID register (CP#15, CR0), and look up in the linker-built
+ * supported processor list. Note that we can't use the absolute addresses
+ * for the __proc_info lists since we aren't running with the MMU on
+ * (and therefore, we are not in the correct address space). We have to
+ * calculate the offset.
+ *
+ * r9 = cpuid
+ * Returns:
+ * r3, r4, r6 corrupted
+ * r5 = proc_info pointer in physical address space
+ * r9 = cpuid (preserved)
+ */
+ __CPUINIT
+__lookup_processor_type:
+ adr r3, __lookup_processor_type_data
+ ldmia r3, {r4 - r6}
+ sub r3, r3, r4 @ get offset between virt&phys
+ add r5, r5, r3 @ convert virt addresses to
+ add r6, r6, r3 @ physical address space
+1: ldmia r5, {r3, r4} @ value, mask
+ and r4, r4, r9 @ mask wanted bits
+ teq r3, r4
+ beq 2f
+ add r5, r5, #PROC_INFO_SZ @ sizeof(proc_info_list)
+ cmp r5, r6
+ blo 1b
+ mov r5, #0 @ unknown processor
+2: mov pc, lr
+ENDPROC(__lookup_processor_type)
+
+/*
+ * Look in <asm/procinfo.h> for information about the __proc_info structure.
+ */
+ .align 2
+ .type __lookup_processor_type_data, %object
+__lookup_processor_type_data:
+ .long .
+ .long __proc_info_begin
+ .long __proc_info_end
+ .size __lookup_processor_type_data, . - __lookup_processor_type_data
+
+__error_p:
+#ifdef CONFIG_DEBUG_LL
+ adr r0, str_p1
+ bl printascii
+ mov r0, r9
+ bl printhex8
+ adr r0, str_p2
+ bl printascii
+ b __error
+str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x"
+str_p2: .asciz ").\n"
+ .align
+#endif
+ENDPROC(__error_p)
+
+__error:
+#ifdef CONFIG_ARCH_RPC
+/*
+ * Turn the screen red on a error - RiscPC only.
+ */
+ mov r0, #0x02000000
+ mov r3, #0x11
+ orr r3, r3, r3, lsl #8
+ orr r3, r3, r3, lsl #16
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+#endif
+1: mov r0, r0
+ b 1b
+ENDPROC(__error)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
new file mode 100644
index 00000000..6b1e0ad9
--- /dev/null
+++ b/arch/arm/kernel/head-nommu.S
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/kernel/head-nommu.S
+ *
+ * Copyright (C) 1994-2002 Russell King
+ * Copyright (C) 2003-2006 Hyok S. Choi
+ *
+ * This program is free software; you can 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 kernel startup code (non-paged MM)
+ *
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+#include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/system.h>
+
+/*
+ * Kernel startup entry point.
+ * ---------------------------
+ *
+ * This is normally called from the decompressor code. The requirements
+ * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
+ * r1 = machine nr.
+ *
+ * See linux/arch/arm/tools/mach-types for the complete list of machine
+ * numbers for r1.
+ *
+ */
+ __HEAD
+ENTRY(stext)
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ @ and irqs disabled
+#ifndef CONFIG_CPU_CP15
+ ldr r9, =CONFIG_PROCESSOR_ID
+#else
+ mrc p15, 0, r9, c0, c0 @ get processor id
+#endif
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+ beq __error_p @ yes, error 'p'
+
+ adr lr, BSYM(__after_proc_init) @ return (PIC) address
+ ARM( add pc, r10, #PROCINFO_INITFUNC )
+ THUMB( add r12, r10, #PROCINFO_INITFUNC )
+ THUMB( mov pc, r12 )
+ENDPROC(stext)
+
+/*
+ * Set the Control Register and Read the process ID.
+ */
+__after_proc_init:
+#ifdef CONFIG_CPU_CP15
+ /*
+ * CP15 system control register value returned in r0 from
+ * the CPU init function.
+ */
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #CR_A
+#else
+ bic r0, r0, #CR_A
+#endif
+#ifdef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CR_C
+#endif
+#ifdef CONFIG_CPU_BPREDICT_DISABLE
+ bic r0, r0, #CR_Z
+#endif
+#ifdef CONFIG_CPU_ICACHE_DISABLE
+ bic r0, r0, #CR_I
+#endif
+#ifdef CONFIG_CPU_HIGH_VECTOR
+ orr r0, r0, #CR_V
+#else
+ bic r0, r0, #CR_V
+#endif
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+#endif /* CONFIG_CPU_CP15 */
+
+ b __mmap_switched @ clear the BSS and jump
+ @ to start_kernel
+ENDPROC(__after_proc_init)
+ .ltorg
+
+#include "head-common.S"
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
new file mode 100644
index 00000000..673151c7
--- /dev/null
+++ b/arch/arm/kernel/head.S
@@ -0,0 +1,592 @@
+/*
+ * linux/arch/arm/kernel/head.S
+ *
+ * Copyright (C) 1994-2002 Russell King
+ * Copyright (c) 2003 ARM Limited
+ * 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.
+ *
+ * Kernel startup code for all 32-bit CPUs
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+#include <asm/domain.h>
+#include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
+#include <asm/memory.h>
+#include <asm/thread_info.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_DEBUG_LL
+#include <mach/debug-macro.S>
+#endif
+
+/*
+ * swapper_pg_dir is the virtual address of the initial page table.
+ * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
+ * make sure that KERNEL_RAM_VADDR is correctly set. Currently, we expect
+ * the least significant 16 bits to be 0x8000, but we could probably
+ * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
+ */
+#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
+#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_VADDR must start at 0xXXXX8000
+#endif
+
+ .globl swapper_pg_dir
+ .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
+
+ .macro pgtbl, rd, phys
+ add \rd, \phys, #TEXT_OFFSET - 0x4000
+ .endm
+
+#ifdef CONFIG_XIP_KERNEL
+#define KERNEL_START XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+#define KERNEL_END _edata_loc
+#else
+#define KERNEL_START KERNEL_RAM_VADDR
+#define KERNEL_END _end
+#endif
+
+/*
+ * Kernel startup entry point.
+ * ---------------------------
+ *
+ * This is normally called from the decompressor code. The requirements
+ * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
+ * r1 = machine nr, r2 = atags or dtb pointer.
+ *
+ * This code is mostly position independent, so if you link the kernel at
+ * 0xc0008000, you call this at __pa(0xc0008000).
+ *
+ * See linux/arch/arm/tools/mach-types for the complete list of machine
+ * numbers for r1.
+ *
+ * We're trying to keep crap to a minimum; DO NOT add any machine specific
+ * crap here - that's what the boot loader (or in extreme, well justified
+ * circumstances, zImage) is for.
+ */
+ __HEAD
+ENTRY(stext)
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ @ and irqs disabled
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+ THUMB( it eq ) @ force fixup-able long branch encoding
+ beq __error_p @ yes, error 'p'
+
+#ifndef CONFIG_XIP_KERNEL
+ adr r3, 2f
+ ldmia r3, {r4, r8}
+ sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
+ add r8, r8, r4 @ PHYS_OFFSET
+#else
+ ldr r8, =PLAT_PHYS_OFFSET
+#endif
+
+ /*
+ * r1 = machine no, r2 = atags or dtb,
+ * r8 = phys_offset, r9 = cpuid, r10 = procinfo
+ */
+ bl __vet_atags
+#ifdef CONFIG_SMP_ON_UP
+ bl __fixup_smp
+#endif
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+ bl __fixup_pv_table
+#endif
+ bl __create_page_tables
+
+ /*
+ * The following calls CPU specific code in a position independent
+ * manner. See arch/arm/mm/proc-*.S for details. r10 = base of
+ * xxx_proc_info structure selected by __lookup_processor_type
+ * above. On return, the CPU will be ready for the MMU to be
+ * turned on, and r0 will hold the CPU control register value.
+ */
+ ldr r13, =__mmap_switched @ address to jump to after
+ @ mmu has been enabled
+ adr lr, BSYM(1f) @ return (PIC) address
+ mov r8, r4 @ set TTBR1 to swapper_pg_dir
+ ARM( add pc, r10, #PROCINFO_INITFUNC )
+ THUMB( add r12, r10, #PROCINFO_INITFUNC )
+ THUMB( mov pc, r12 )
+1: b __enable_mmu
+ENDPROC(stext)
+ .ltorg
+#ifndef CONFIG_XIP_KERNEL
+2: .long .
+ .long PAGE_OFFSET
+#endif
+
+/*
+ * Setup the initial page tables. We only setup the barest
+ * amount which are required to get the kernel running, which
+ * generally means mapping in the kernel code.
+ *
+ * r8 = phys_offset, r9 = cpuid, r10 = procinfo
+ *
+ * Returns:
+ * r0, r3, r5-r7 corrupted
+ * r4 = physical page table address
+ */
+__create_page_tables:
+ pgtbl r4, r8 @ page table address
+
+ /*
+ * Clear the 16K level 1 swapper page table
+ */
+ mov r0, r4
+ mov r3, #0
+ add r6, r0, #0x4000
+1: str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ str r3, [r0], #4
+ teq r0, r6
+ bne 1b
+
+ ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
+
+ /*
+ * Create identity mapping to cater for __enable_mmu.
+ * This identity mapping will be removed by paging_init().
+ */
+ adr r0, __enable_mmu_loc
+ ldmia r0, {r3, r5, r6}
+ sub r0, r0, r3 @ virt->phys offset
+ add r5, r5, r0 @ phys __enable_mmu
+ add r6, r6, r0 @ phys __enable_mmu_end
+ mov r5, r5, lsr #20
+ mov r6, r6, lsr #20
+
+1: orr r3, r7, r5, lsl #20 @ flags + kernel base
+ str r3, [r4, r5, lsl #2] @ identity mapping
+ teq r5, r6
+ addne r5, r5, #1 @ next section
+ bne 1b
+
+ /*
+ * Now setup the pagetables for our kernel direct
+ * mapped region.
+ */
+ mov r3, pc
+ mov r3, r3, lsr #20
+ orr r3, r7, r3, lsl #20
+ add r0, r4, #(KERNEL_START & 0xff000000) >> 18
+ str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
+ ldr r6, =(KERNEL_END - 1)
+ add r0, r0, #4
+ add r6, r4, r6, lsr #18
+1: cmp r0, r6
+ add r3, r3, #1 << 20
+ strls r3, [r0], #4
+ bls 1b
+
+#ifdef CONFIG_XIP_KERNEL
+ /*
+ * Map some ram to cover our .data and .bss areas.
+ */
+ add r3, r8, #TEXT_OFFSET
+ orr r3, r3, r7
+ add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
+ str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
+ ldr r6, =(_end - 1)
+ add r0, r0, #4
+ add r6, r4, r6, lsr #18
+1: cmp r0, r6
+ add r3, r3, #1 << 20
+ strls r3, [r0], #4
+ bls 1b
+#endif
+
+ /*
+ * Then map boot params address in r2 or
+ * the first 1MB of ram if boot params address is not specified.
+ */
+ mov r0, r2, lsr #20
+ movs r0, r0, lsl #20
+ moveq r0, r8
+ sub r3, r0, r8
+ add r3, r3, #PAGE_OFFSET
+ add r3, r4, r3, lsr #18
+ orr r6, r7, r0
+ str r6, [r3]
+
+#ifdef CONFIG_DEBUG_LL
+#ifndef CONFIG_DEBUG_ICEDCC
+ /*
+ * Map in IO space for serial debugging.
+ * This allows debug messages to be output
+ * via a serial console before paging_init.
+ */
+ addruart r7, r3
+
+ mov r3, r3, lsr #20
+ mov r3, r3, lsl #2
+
+ add r0, r4, r3
+ rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
+ cmp r3, #0x0800 @ limit to 512MB
+ movhi r3, #0x0800
+ add r6, r0, r3
+ mov r3, r7, lsr #20
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+ orr r3, r7, r3, lsl #20
+1: str r3, [r0], #4
+ add r3, r3, #1 << 20
+ teq r0, r6
+ bne 1b
+
+#else /* CONFIG_DEBUG_ICEDCC */
+ /* we don't need any serial debugging mappings for ICEDCC */
+ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
+#endif /* !CONFIG_DEBUG_ICEDCC */
+
+#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
+ /*
+ * If we're using the NetWinder or CATS, we also need to map
+ * in the 16550-type serial port for the debug messages
+ */
+ add r0, r4, #0xff000000 >> 18
+ orr r3, r7, #0x7c000000
+ str r3, [r0]
+#endif
+#ifdef CONFIG_ARCH_RPC
+ /*
+ * Map in screen at 0x02000000 & SCREEN2_BASE
+ * Similar reasons here - for debug. This is
+ * only for Acorn RiscPC architectures.
+ */
+ add r0, r4, #0x02000000 >> 18
+ orr r3, r7, #0x02000000
+ str r3, [r0]
+ add r0, r4, #0xd8000000 >> 18
+ str r3, [r0]
+#endif
+#endif
+ mov pc, lr
+ENDPROC(__create_page_tables)
+ .ltorg
+ .align
+__enable_mmu_loc:
+ .long .
+ .long __enable_mmu
+ .long __enable_mmu_end
+
+#if defined(CONFIG_SMP)
+ __CPUINIT
+ENTRY(secondary_startup)
+ /*
+ * Common entry point for secondary CPUs.
+ *
+ * Ensure that we're in SVC mode, and IRQs are disabled. Lookup
+ * the processor type - there is no need to check the machine type
+ * as it has already been validated by the primary processor.
+ */
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+ mrc p15, 0, r9, c0, c0 @ get processor id
+ bl __lookup_processor_type
+ movs r10, r5 @ invalid processor?
+ moveq r0, #'p' @ yes, error 'p'
+ THUMB( it eq ) @ force fixup-able long branch encoding
+ beq __error_p
+
+ /*
+ * Use the page tables supplied from __cpu_up.
+ */
+ adr r4, __secondary_data
+ ldmia r4, {r5, r7, r12} @ address to jump to after
+ sub lr, r4, r5 @ mmu has been enabled
+ ldr r4, [r7, lr] @ get secondary_data.pgdir
+ add r7, r7, #4
+ ldr r8, [r7, lr] @ get secondary_data.swapper_pg_dir
+ adr lr, BSYM(__enable_mmu) @ return address
+ mov r13, r12 @ __secondary_switched address
+ ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
+ @ (return control reg)
+ THUMB( add r12, r10, #PROCINFO_INITFUNC )
+ THUMB( mov pc, r12 )
+ENDPROC(secondary_startup)
+
+ /*
+ * r6 = &secondary_data
+ */
+ENTRY(__secondary_switched)
+ ldr sp, [r7, #4] @ get secondary_data.stack
+ mov fp, #0
+ b secondary_start_kernel
+ENDPROC(__secondary_switched)
+
+ .align
+
+ .type __secondary_data, %object
+__secondary_data:
+ .long .
+ .long secondary_data
+ .long __secondary_switched
+#endif /* defined(CONFIG_SMP) */
+
+
+
+/*
+ * Setup common bits before finally enabling the MMU. Essentially
+ * this is just loading the page table pointer and domain access
+ * registers.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags or dtb pointer
+ * r4 = page table pointer
+ * r9 = processor ID
+ * r13 = *virtual* address to jump to upon completion
+ */
+__enable_mmu:
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
+ orr r0, r0, #CR_A
+#else
+ bic r0, r0, #CR_A
+#endif
+#ifdef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CR_C
+#endif
+#ifdef CONFIG_CPU_BPREDICT_DISABLE
+ bic r0, r0, #CR_Z
+#endif
+#ifdef CONFIG_CPU_ICACHE_DISABLE
+ bic r0, r0, #CR_I
+#endif
+ mov r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | \
+ domain_val(DOMAIN_IO, DOMAIN_CLIENT))
+ mcr p15, 0, r5, c3, c0, 0 @ load domain access register
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+ b __turn_mmu_on
+ENDPROC(__enable_mmu)
+
+/*
+ * Enable the MMU. This completely changes the structure of the visible
+ * memory space. You will not be able to trace execution through this.
+ * If you have an enquiry about this, *please* check the linux-arm-kernel
+ * mailing list archives BEFORE sending another post to the list.
+ *
+ * r0 = cp#15 control register
+ * r1 = machine ID
+ * r2 = atags or dtb pointer
+ * r9 = processor ID
+ * r13 = *virtual* address to jump to upon completion
+ *
+ * other registers depend on the function called upon completion
+ */
+ .align 5
+__turn_mmu_on:
+ mov r0, r0
+ mcr p15, 0, r0, c1, c0, 0 @ write control reg
+ mrc p15, 0, r3, c0, c0, 0 @ read id reg
+ mov r3, r3
+ mov r3, r13
+ mov pc, r3
+__enable_mmu_end:
+ENDPROC(__turn_mmu_on)
+
+
+#ifdef CONFIG_SMP_ON_UP
+ __INIT
+__fixup_smp:
+ and r3, r9, #0x000f0000 @ architecture version
+ teq r3, #0x000f0000 @ CPU ID supported?
+ bne __fixup_smp_on_up @ no, assume UP
+
+ bic r3, r9, #0x00ff0000
+ bic r3, r3, #0x0000000f @ mask 0xff00fff0
+ mov r4, #0x41000000
+ orr r4, r4, #0x0000b000
+ orr r4, r4, #0x00000020 @ val 0x4100b020
+ teq r3, r4 @ ARM 11MPCore?
+ moveq pc, lr @ yes, assume SMP
+
+ mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
+ and r0, r0, #0xc0000000 @ multiprocessing extensions and
+ teq r0, #0x80000000 @ not part of a uniprocessor system?
+ moveq pc, lr @ yes, assume SMP
+
+__fixup_smp_on_up:
+ adr r0, 1f
+ ldmia r0, {r3 - r5}
+ sub r3, r0, r3
+ add r4, r4, r3
+ add r5, r5, r3
+ b __do_fixup_smp_on_up
+ENDPROC(__fixup_smp)
+
+ .align
+1: .word .
+ .word __smpalt_begin
+ .word __smpalt_end
+
+ .pushsection .data
+ .globl smp_on_up
+smp_on_up:
+ ALT_SMP(.long 1)
+ ALT_UP(.long 0)
+ .popsection
+#endif
+
+ .text
+__do_fixup_smp_on_up:
+ cmp r4, r5
+ movhs pc, lr
+ ldmia r4!, {r0, r6}
+ ARM( str r6, [r0, r3] )
+ THUMB( add r0, r0, r3 )
+#ifdef __ARMEB__
+ THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
+#endif
+ THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
+ THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
+ THUMB( strh r6, [r0] )
+ b __do_fixup_smp_on_up
+ENDPROC(__do_fixup_smp_on_up)
+
+ENTRY(fixup_smp)
+ stmfd sp!, {r4 - r6, lr}
+ mov r4, r0
+ add r5, r0, r1
+ mov r3, #0
+ bl __do_fixup_smp_on_up
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(fixup_smp)
+
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+
+/* __fixup_pv_table - patch the stub instructions with the delta between
+ * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be 16MiB aligned and
+ * can be expressed by an immediate shifter operand. The stub instruction
+ * has a form of '(add|sub) rd, rn, #imm'.
+ */
+ __HEAD
+__fixup_pv_table:
+ adr r0, 1f
+ ldmia r0, {r3-r5, r7}
+ sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
+ add r4, r4, r3 @ adjust table start address
+ add r5, r5, r3 @ adjust table end address
+ add r7, r7, r3 @ adjust __pv_phys_offset address
+ str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
+#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ mov r6, r3, lsr #24 @ constant for add/sub instructions
+ teq r3, r6, lsl #24 @ must be 16MiB aligned
+#else
+ mov r6, r3, lsr #16 @ constant for add/sub instructions
+ teq r3, r6, lsl #16 @ must be 64kiB aligned
+#endif
+THUMB( it ne @ cross section branch )
+ bne __error
+ str r6, [r7, #4] @ save to __pv_offset
+ b __fixup_a_pv_table
+ENDPROC(__fixup_pv_table)
+
+ .align
+1: .long .
+ .long __pv_table_begin
+ .long __pv_table_end
+2: .long __pv_phys_offset
+
+ .text
+__fixup_a_pv_table:
+#ifdef CONFIG_THUMB2_KERNEL
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ lsls r0, r6, #24
+ lsr r6, #8
+ beq 1f
+ clz r7, r0
+ lsr r0, #24
+ lsl r0, r7
+ bic r0, 0x0080
+ lsrs r7, #1
+ orrcs r0, #0x0080
+ orr r0, r0, r7, lsl #12
+#endif
+1: lsls r6, #24
+ beq 4f
+ clz r7, r6
+ lsr r6, #24
+ lsl r6, r7
+ bic r6, #0x0080
+ lsrs r7, #1
+ orrcs r6, #0x0080
+ orr r6, r6, r7, lsl #12
+ orr r6, #0x4000
+ b 4f
+2: @ at this point the C flag is always clear
+ add r7, r3
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ ldrh ip, [r7]
+ tst ip, 0x0400 @ the i bit tells us LS or MS byte
+ beq 3f
+ cmp r0, #0 @ set C flag, and ...
+ biceq ip, 0x0400 @ immediate zero value has a special encoding
+ streqh ip, [r7] @ that requires the i bit cleared
+#endif
+3: ldrh ip, [r7, #2]
+ and ip, 0x8f00
+ orrcc ip, r6 @ mask in offset bits 31-24
+ orrcs ip, r0 @ mask in offset bits 23-16
+ strh ip, [r7, #2]
+4: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 2b
+ bx lr
+#else
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ and r0, r6, #255 @ offset bits 23-16
+ mov r6, r6, lsr #8 @ offset bits 31-24
+#else
+ mov r0, #0 @ just in case...
+#endif
+ b 3f
+2: ldr ip, [r7, r3]
+ bic ip, ip, #0x000000ff
+ tst ip, #0x400 @ rotate shift tells us LS or MS byte
+ orrne ip, ip, r6 @ mask in offset bits 31-24
+ orreq ip, ip, r0 @ mask in offset bits 23-16
+ str ip, [r7, r3]
+3: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 2b
+ mov pc, lr
+#endif
+ENDPROC(__fixup_a_pv_table)
+
+ENTRY(fixup_pv_table)
+ stmfd sp!, {r4 - r7, lr}
+ ldr r2, 2f @ get address of __pv_phys_offset
+ mov r3, #0 @ no offset
+ mov r4, r0 @ r0 = table start
+ add r5, r0, r1 @ r1 = table size
+ ldr r6, [r2, #4] @ get __pv_offset
+ bl __fixup_a_pv_table
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(fixup_pv_table)
+
+ .align
+2: .long __pv_phys_offset
+
+ .data
+ .globl __pv_phys_offset
+ .type __pv_phys_offset, %object
+__pv_phys_offset:
+ .long 0
+ .size __pv_phys_offset, . - __pv_phys_offset
+__pv_offset:
+ .long 0
+#endif
+
+#include "head-common.S"
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
new file mode 100644
index 00000000..87acc25d
--- /dev/null
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -0,0 +1,978 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) 2009, 2010 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers.
+ */
+#define pr_fmt(fmt) "hw-breakpoint: " fmt
+
+#include <linux/errno.h>
+#include <linux/hardirq.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/current.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/kdebug.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+/* Breakpoint currently in use for each BRP. */
+static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
+
+/* Watchpoint currently in use for each WRP. */
+static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
+
+/* Number of BRP/WRP registers on this CPU. */
+static int core_num_brps;
+static int core_num_reserved_brps;
+static int core_num_wrps;
+
+/* Debug architecture version. */
+static u8 debug_arch;
+
+/* Maximum supported watchpoint length. */
+static u8 max_watchpoint_len;
+
+#define READ_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_READ(c ## M, OP2, VAL); \
+ break
+
+#define WRITE_WB_REG_CASE(OP2, M, VAL) \
+ case ((OP2 << 4) + M): \
+ ARM_DBG_WRITE(c ## M, OP2, VAL);\
+ break
+
+#define GEN_READ_WB_REG_CASES(OP2, VAL) \
+ READ_WB_REG_CASE(OP2, 0, VAL); \
+ READ_WB_REG_CASE(OP2, 1, VAL); \
+ READ_WB_REG_CASE(OP2, 2, VAL); \
+ READ_WB_REG_CASE(OP2, 3, VAL); \
+ READ_WB_REG_CASE(OP2, 4, VAL); \
+ READ_WB_REG_CASE(OP2, 5, VAL); \
+ READ_WB_REG_CASE(OP2, 6, VAL); \
+ READ_WB_REG_CASE(OP2, 7, VAL); \
+ READ_WB_REG_CASE(OP2, 8, VAL); \
+ READ_WB_REG_CASE(OP2, 9, VAL); \
+ READ_WB_REG_CASE(OP2, 10, VAL); \
+ READ_WB_REG_CASE(OP2, 11, VAL); \
+ READ_WB_REG_CASE(OP2, 12, VAL); \
+ READ_WB_REG_CASE(OP2, 13, VAL); \
+ READ_WB_REG_CASE(OP2, 14, VAL); \
+ READ_WB_REG_CASE(OP2, 15, VAL)
+
+#define GEN_WRITE_WB_REG_CASES(OP2, VAL) \
+ WRITE_WB_REG_CASE(OP2, 0, VAL); \
+ WRITE_WB_REG_CASE(OP2, 1, VAL); \
+ WRITE_WB_REG_CASE(OP2, 2, VAL); \
+ WRITE_WB_REG_CASE(OP2, 3, VAL); \
+ WRITE_WB_REG_CASE(OP2, 4, VAL); \
+ WRITE_WB_REG_CASE(OP2, 5, VAL); \
+ WRITE_WB_REG_CASE(OP2, 6, VAL); \
+ WRITE_WB_REG_CASE(OP2, 7, VAL); \
+ WRITE_WB_REG_CASE(OP2, 8, VAL); \
+ WRITE_WB_REG_CASE(OP2, 9, VAL); \
+ WRITE_WB_REG_CASE(OP2, 10, VAL); \
+ WRITE_WB_REG_CASE(OP2, 11, VAL); \
+ WRITE_WB_REG_CASE(OP2, 12, VAL); \
+ WRITE_WB_REG_CASE(OP2, 13, VAL); \
+ WRITE_WB_REG_CASE(OP2, 14, VAL); \
+ WRITE_WB_REG_CASE(OP2, 15, VAL)
+
+static u32 read_wb_reg(int n)
+{
+ u32 val = 0;
+
+ switch (n) {
+ GEN_READ_WB_REG_CASES(ARM_OP2_BVR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_BCR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_WVR, val);
+ GEN_READ_WB_REG_CASES(ARM_OP2_WCR, val);
+ default:
+ pr_warning("attempt to read from unknown breakpoint "
+ "register %d\n", n);
+ }
+
+ return val;
+}
+
+static void write_wb_reg(int n, u32 val)
+{
+ switch (n) {
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_BVR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_BCR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_WVR, val);
+ GEN_WRITE_WB_REG_CASES(ARM_OP2_WCR, val);
+ default:
+ pr_warning("attempt to write to unknown breakpoint "
+ "register %d\n", n);
+ }
+ isb();
+}
+
+/* Determine debug architecture. */
+static u8 get_debug_arch(void)
+{
+ u32 didr;
+
+ /* Do we implement the extended CPUID interface? */
+ if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf),
+ "CPUID feature registers not supported. "
+ "Assuming v6 debug is present.\n"))
+ return ARM_DEBUG_ARCH_V6;
+
+ ARM_DBG_READ(c0, 0, didr);
+ return (didr >> 16) & 0xf;
+}
+
+u8 arch_get_debug_arch(void)
+{
+ return debug_arch;
+}
+
+static int debug_arch_supported(void)
+{
+ u8 arch = get_debug_arch();
+ return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14;
+}
+
+/* Determine number of BRP register available. */
+static int get_num_brp_resources(void)
+{
+ u32 didr;
+ ARM_DBG_READ(c0, 0, didr);
+ return ((didr >> 24) & 0xf) + 1;
+}
+
+/* Does this core support mismatch breakpoints? */
+static int core_has_mismatch_brps(void)
+{
+ return (get_debug_arch() >= ARM_DEBUG_ARCH_V7_ECP14 &&
+ get_num_brp_resources() > 1);
+}
+
+/* Determine number of usable WRPs available. */
+static int get_num_wrps(void)
+{
+ /*
+ * FIXME: When a watchpoint fires, the only way to work out which
+ * watchpoint it was is by disassembling the faulting instruction
+ * and working out the address of the memory access.
+ *
+ * Furthermore, we can only do this if the watchpoint was precise
+ * since imprecise watchpoints prevent us from calculating register
+ * based addresses.
+ *
+ * Providing we have more than 1 breakpoint register, we only report
+ * a single watchpoint register for the time being. This way, we always
+ * know which watchpoint fired. In the future we can either add a
+ * disassembler and address generation emulator, or we can insert a
+ * check to see if the DFAR is set on watchpoint exception entry
+ * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
+ * that it is set on some implementations].
+ */
+
+#if 0
+ int wrps;
+ u32 didr;
+ ARM_DBG_READ(c0, 0, didr);
+ wrps = ((didr >> 28) & 0xf) + 1;
+#endif
+ int wrps = 1;
+
+ if (core_has_mismatch_brps() && wrps >= get_num_brp_resources())
+ wrps = get_num_brp_resources() - 1;
+
+ return wrps;
+}
+
+/* We reserve one breakpoint for each watchpoint. */
+static int get_num_reserved_brps(void)
+{
+ if (core_has_mismatch_brps())
+ return get_num_wrps();
+ return 0;
+}
+
+/* Determine number of usable BRPs available. */
+static int get_num_brps(void)
+{
+ int brps = get_num_brp_resources();
+ if (core_has_mismatch_brps())
+ brps -= get_num_reserved_brps();
+ return brps;
+}
+
+/*
+ * In order to access the breakpoint/watchpoint control registers,
+ * we must be running in debug monitor mode. Unfortunately, we can
+ * be put into halting debug mode at any time by an external debugger
+ * but there is nothing we can do to prevent that.
+ */
+static int enable_monitor_mode(void)
+{
+ u32 dscr;
+ int ret = 0;
+
+ ARM_DBG_READ(c1, 0, dscr);
+
+ /* Ensure that halting mode is disabled. */
+ if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
+ "halting debug mode enabled. Unable to access hardware resources.\n")) {
+ ret = -EPERM;
+ goto out;
+ }
+
+ /* If monitor mode is already enabled, just return. */
+ if (dscr & ARM_DSCR_MDBGEN)
+ goto out;
+
+ /* Write to the corresponding DSCR. */
+ switch (get_debug_arch()) {
+ case ARM_DEBUG_ARCH_V6:
+ case ARM_DEBUG_ARCH_V6_1:
+ ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
+ break;
+ case ARM_DEBUG_ARCH_V7_ECP14:
+ ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
+ break;
+ default:
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* Check that the write made it through. */
+ ARM_DBG_READ(c1, 0, dscr);
+ if (!(dscr & ARM_DSCR_MDBGEN))
+ ret = -EPERM;
+
+out:
+ return ret;
+}
+
+int hw_breakpoint_slots(int type)
+{
+ if (!debug_arch_supported())
+ return 0;
+
+ /*
+ * We can be called early, so don't rely on
+ * our static variables being initialised.
+ */
+ switch (type) {
+ case TYPE_INST:
+ return get_num_brps();
+ case TYPE_DATA:
+ return get_num_wrps();
+ default:
+ pr_warning("unknown slot type: %d\n", type);
+ return 0;
+ }
+}
+
+/*
+ * Check if 8-bit byte-address select is available.
+ * This clobbers WRP 0.
+ */
+static u8 get_max_wp_len(void)
+{
+ u32 ctrl_reg;
+ struct arch_hw_breakpoint_ctrl ctrl;
+ u8 size = 4;
+
+ if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14)
+ goto out;
+
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.len = ARM_BREAKPOINT_LEN_8;
+ ctrl_reg = encode_ctrl_reg(ctrl);
+
+ write_wb_reg(ARM_BASE_WVR, 0);
+ write_wb_reg(ARM_BASE_WCR, ctrl_reg);
+ if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg)
+ size = 8;
+
+out:
+ return size;
+}
+
+u8 arch_get_max_wp_len(void)
+{
+ return max_watchpoint_len;
+}
+
+/*
+ * Install a perf counter breakpoint.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ struct perf_event **slot, **slots;
+ int i, max_slots, ctrl_base, val_base, ret = 0;
+ u32 addr, ctrl;
+
+ /* Ensure that we are in monitor mode and halting mode is disabled. */
+ ret = enable_monitor_mode();
+ if (ret)
+ goto out;
+
+ addr = info->address;
+ ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
+
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
+ /* Breakpoint */
+ ctrl_base = ARM_BASE_BCR;
+ val_base = ARM_BASE_BVR;
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps;
+ if (info->step_ctrl.enabled) {
+ /* Override the breakpoint data with the step data. */
+ addr = info->trigger & ~0x3;
+ ctrl = encode_ctrl_reg(info->step_ctrl);
+ }
+ } else {
+ /* Watchpoint */
+ if (info->step_ctrl.enabled) {
+ /* Install into the reserved breakpoint region. */
+ ctrl_base = ARM_BASE_BCR + core_num_brps;
+ val_base = ARM_BASE_BVR + core_num_brps;
+ /* Override the watchpoint data with the step data. */
+ addr = info->trigger & ~0x3;
+ ctrl = encode_ctrl_reg(info->step_ctrl);
+ } else {
+ ctrl_base = ARM_BASE_WCR;
+ val_base = ARM_BASE_WVR;
+ }
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
+ max_slots = core_num_wrps;
+ }
+
+ for (i = 0; i < max_slots; ++i) {
+ slot = &slots[i];
+
+ if (!*slot) {
+ *slot = bp;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ /* Setup the address register. */
+ write_wb_reg(val_base + i, addr);
+
+ /* Setup the control register. */
+ write_wb_reg(ctrl_base + i, ctrl);
+
+out:
+ return ret;
+}
+
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ struct perf_event **slot, **slots;
+ int i, max_slots, base;
+
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
+ /* Breakpoint */
+ base = ARM_BASE_BCR;
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+ max_slots = core_num_brps;
+ } else {
+ /* Watchpoint */
+ if (info->step_ctrl.enabled)
+ base = ARM_BASE_BCR + core_num_brps;
+ else
+ base = ARM_BASE_WCR;
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
+ max_slots = core_num_wrps;
+ }
+
+ /* Remove the breakpoint. */
+ for (i = 0; i < max_slots; ++i) {
+ slot = &slots[i];
+
+ if (*slot == bp) {
+ *slot = NULL;
+ break;
+ }
+ }
+
+ if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
+ return;
+
+ /* Reset the control register. */
+ write_wb_reg(base + i, 0);
+}
+
+static int get_hbp_len(u8 hbp_len)
+{
+ unsigned int len_in_bytes = 0;
+
+ switch (hbp_len) {
+ case ARM_BREAKPOINT_LEN_1:
+ len_in_bytes = 1;
+ break;
+ case ARM_BREAKPOINT_LEN_2:
+ len_in_bytes = 2;
+ break;
+ case ARM_BREAKPOINT_LEN_4:
+ len_in_bytes = 4;
+ break;
+ case ARM_BREAKPOINT_LEN_8:
+ len_in_bytes = 8;
+ break;
+ }
+
+ return len_in_bytes;
+}
+
+/*
+ * Check whether bp virtual address is in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
+{
+ unsigned int len;
+ unsigned long va;
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ va = info->address;
+ len = get_hbp_len(info->ctrl.len);
+
+ return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
+}
+
+/*
+ * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl.
+ * Hopefully this will disappear when ptrace can bypass the conversion
+ * to generic breakpoint descriptions.
+ */
+int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
+ int *gen_len, int *gen_type)
+{
+ /* Type */
+ switch (ctrl.type) {
+ case ARM_BREAKPOINT_EXECUTE:
+ *gen_type = HW_BREAKPOINT_X;
+ break;
+ case ARM_BREAKPOINT_LOAD:
+ *gen_type = HW_BREAKPOINT_R;
+ break;
+ case ARM_BREAKPOINT_STORE:
+ *gen_type = HW_BREAKPOINT_W;
+ break;
+ case ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE:
+ *gen_type = HW_BREAKPOINT_RW;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Len */
+ switch (ctrl.len) {
+ case ARM_BREAKPOINT_LEN_1:
+ *gen_len = HW_BREAKPOINT_LEN_1;
+ break;
+ case ARM_BREAKPOINT_LEN_2:
+ *gen_len = HW_BREAKPOINT_LEN_2;
+ break;
+ case ARM_BREAKPOINT_LEN_4:
+ *gen_len = HW_BREAKPOINT_LEN_4;
+ break;
+ case ARM_BREAKPOINT_LEN_8:
+ *gen_len = HW_BREAKPOINT_LEN_8;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * Construct an arch_hw_breakpoint from a perf_event.
+ */
+static int arch_build_bp_info(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ /* Type */
+ switch (bp->attr.bp_type) {
+ case HW_BREAKPOINT_X:
+ info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
+ break;
+ case HW_BREAKPOINT_R:
+ info->ctrl.type = ARM_BREAKPOINT_LOAD;
+ break;
+ case HW_BREAKPOINT_W:
+ info->ctrl.type = ARM_BREAKPOINT_STORE;
+ break;
+ case HW_BREAKPOINT_RW:
+ info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Len */
+ switch (bp->attr.bp_len) {
+ case HW_BREAKPOINT_LEN_1:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_1;
+ break;
+ case HW_BREAKPOINT_LEN_2:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_2;
+ break;
+ case HW_BREAKPOINT_LEN_4:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_4;
+ break;
+ case HW_BREAKPOINT_LEN_8:
+ info->ctrl.len = ARM_BREAKPOINT_LEN_8;
+ if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE)
+ && max_watchpoint_len >= 8)
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes.
+ * Watchpoints can be of length 1, 2, 4 or 8 bytes if supported
+ * by the hardware and must be aligned to the appropriate number of
+ * bytes.
+ */
+ if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
+ info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
+ info->ctrl.len != ARM_BREAKPOINT_LEN_4)
+ return -EINVAL;
+
+ /* Address */
+ info->address = bp->attr.bp_addr;
+
+ /* Privilege */
+ info->ctrl.privilege = ARM_BREAKPOINT_USER;
+ if (arch_check_bp_in_kernelspace(bp))
+ info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
+
+ /* Enabled? */
+ info->ctrl.enabled = !bp->attr.disabled;
+
+ /* Mismatch */
+ info->ctrl.mismatch = 0;
+
+ return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings.
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ int ret = 0;
+ u32 offset, alignment_mask = 0x3;
+
+ /* Build the arch_hw_breakpoint. */
+ ret = arch_build_bp_info(bp);
+ if (ret)
+ goto out;
+
+ /* Check address alignment. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
+ alignment_mask = 0x7;
+ offset = info->address & alignment_mask;
+ switch (offset) {
+ case 0:
+ /* Aligned */
+ break;
+ case 1:
+ /* Allow single byte watchpoint. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
+ break;
+ case 2:
+ /* Allow halfword watchpoints and breakpoints. */
+ if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
+ break;
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
+
+ info->address &= ~alignment_mask;
+ info->ctrl.len <<= offset;
+
+ /*
+ * Currently we rely on an overflow handler to take
+ * care of single-stepping the breakpoint when it fires.
+ * In the case of userspace breakpoints on a core with V7 debug,
+ * we can use the mismatch feature as a poor-man's hardware
+ * single-step, but this only works for per-task breakpoints.
+ */
+ if (WARN_ONCE(!bp->overflow_handler &&
+ (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
+ || !bp->hw.bp_target),
+ "overflow handler required but none found\n")) {
+ ret = -EINVAL;
+ }
+out:
+ return ret;
+}
+
+/*
+ * Enable/disable single-stepping over the breakpoint bp at address addr.
+ */
+static void enable_single_step(struct perf_event *bp, u32 addr)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ arch_uninstall_hw_breakpoint(bp);
+ info->step_ctrl.mismatch = 1;
+ info->step_ctrl.len = ARM_BREAKPOINT_LEN_4;
+ info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE;
+ info->step_ctrl.privilege = info->ctrl.privilege;
+ info->step_ctrl.enabled = 1;
+ info->trigger = addr;
+ arch_install_hw_breakpoint(bp);
+}
+
+static void disable_single_step(struct perf_event *bp)
+{
+ arch_uninstall_hw_breakpoint(bp);
+ counter_arch_bp(bp)->step_ctrl.enabled = 0;
+ arch_install_hw_breakpoint(bp);
+}
+
+static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
+{
+ int i;
+ struct perf_event *wp, **slots;
+ struct arch_hw_breakpoint *info;
+
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
+
+ /* Without a disassembler, we can only handle 1 watchpoint. */
+ BUG_ON(core_num_wrps > 1);
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ rcu_read_lock();
+
+ wp = slots[i];
+
+ if (wp == NULL) {
+ rcu_read_unlock();
+ continue;
+ }
+
+ /*
+ * The DFAR is an unknown value. Since we only allow a
+ * single watchpoint, we can set the trigger to the lowest
+ * possible faulting address.
+ */
+ info = counter_arch_bp(wp);
+ info->trigger = wp->attr.bp_addr;
+ pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
+ perf_bp_event(wp, regs);
+
+ /*
+ * If no overflow handler is present, insert a temporary
+ * mismatch breakpoint so we can single-step over the
+ * watchpoint trigger.
+ */
+ if (!wp->overflow_handler)
+ enable_single_step(wp, instruction_pointer(regs));
+
+ rcu_read_unlock();
+ }
+}
+
+static void watchpoint_single_step_handler(unsigned long pc)
+{
+ int i;
+ struct perf_event *wp, **slots;
+ struct arch_hw_breakpoint *info;
+
+ slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
+
+ for (i = 0; i < core_num_reserved_brps; ++i) {
+ rcu_read_lock();
+
+ wp = slots[i];
+
+ if (wp == NULL)
+ goto unlock;
+
+ info = counter_arch_bp(wp);
+ if (!info->step_ctrl.enabled)
+ goto unlock;
+
+ /*
+ * Restore the original watchpoint if we've completed the
+ * single-step.
+ */
+ if (info->trigger != pc)
+ disable_single_step(wp);
+
+unlock:
+ rcu_read_unlock();
+ }
+}
+
+static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
+{
+ int i;
+ u32 ctrl_reg, val, addr;
+ struct perf_event *bp, **slots;
+ struct arch_hw_breakpoint *info;
+ struct arch_hw_breakpoint_ctrl ctrl;
+
+ slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
+
+ /* The exception entry code places the amended lr in the PC. */
+ addr = regs->ARM_pc;
+
+ /* Check the currently installed breakpoints first. */
+ for (i = 0; i < core_num_brps; ++i) {
+ rcu_read_lock();
+
+ bp = slots[i];
+
+ if (bp == NULL)
+ goto unlock;
+
+ info = counter_arch_bp(bp);
+
+ /* Check if the breakpoint value matches. */
+ val = read_wb_reg(ARM_BASE_BVR + i);
+ if (val != (addr & ~0x3))
+ goto mismatch;
+
+ /* Possible match, check the byte address select to confirm. */
+ ctrl_reg = read_wb_reg(ARM_BASE_BCR + i);
+ decode_ctrl_reg(ctrl_reg, &ctrl);
+ if ((1 << (addr & 0x3)) & ctrl.len) {
+ info->trigger = addr;
+ pr_debug("breakpoint fired: address = 0x%x\n", addr);
+ perf_bp_event(bp, regs);
+ if (!bp->overflow_handler)
+ enable_single_step(bp, addr);
+ goto unlock;
+ }
+
+mismatch:
+ /* If we're stepping a breakpoint, it can now be restored. */
+ if (info->step_ctrl.enabled)
+ disable_single_step(bp);
+unlock:
+ rcu_read_unlock();
+ }
+
+ /* Handle any pending watchpoint single-step breakpoints. */
+ watchpoint_single_step_handler(addr);
+}
+
+/*
+ * Called from either the Data Abort Handler [watchpoint] or the
+ * Prefetch Abort Handler [breakpoint] with preemption disabled.
+ */
+static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ int ret = 0;
+ u32 dscr;
+
+ /* We must be called with preemption disabled. */
+ WARN_ON(preemptible());
+
+ /* We only handle watchpoints and hardware breakpoints. */
+ ARM_DBG_READ(c1, 0, dscr);
+
+ /* Perform perf callbacks. */
+ switch (ARM_DSCR_MOE(dscr)) {
+ case ARM_ENTRY_BREAKPOINT:
+ breakpoint_handler(addr, regs);
+ break;
+ case ARM_ENTRY_ASYNC_WATCHPOINT:
+ WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
+ case ARM_ENTRY_SYNC_WATCHPOINT:
+ watchpoint_handler(addr, regs);
+ break;
+ default:
+ ret = 1; /* Unhandled fault. */
+ }
+
+ /*
+ * Re-enable preemption after it was disabled in the
+ * low-level exception handling code.
+ */
+ preempt_enable();
+
+ return ret;
+}
+
+/*
+ * One-time initialisation.
+ */
+static void reset_ctrl_regs(void *info)
+{
+ int i, cpu = smp_processor_id();
+ u32 dbg_power;
+ cpumask_t *cpumask = info;
+
+ /*
+ * v7 debug contains save and restore registers so that debug state
+ * can be maintained across low-power modes without leaving the debug
+ * logic powered up. It is IMPLEMENTATION DEFINED whether we can access
+ * the debug registers out of reset, so we must unlock the OS Lock
+ * Access Register to avoid taking undefined instruction exceptions
+ * later on.
+ */
+ if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
+ /*
+ * Ensure sticky power-down is clear (i.e. debug logic is
+ * powered up).
+ */
+ asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
+ if ((dbg_power & 0x1) == 0) {
+ pr_warning("CPU %d debug is powered down!\n", cpu);
+ cpumask_or(cpumask, cpumask, cpumask_of(cpu));
+ return;
+ }
+
+ /*
+ * Unconditionally clear the lock by writing a value
+ * other than 0xC5ACCE55 to the access register.
+ */
+ asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
+ isb();
+
+ /*
+ * Clear any configured vector-catch events before
+ * enabling monitor mode.
+ */
+ asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
+ isb();
+ }
+
+ if (enable_monitor_mode())
+ return;
+
+ /* We must also reset any reserved registers. */
+ for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) {
+ write_wb_reg(ARM_BASE_BCR + i, 0UL);
+ write_wb_reg(ARM_BASE_BVR + i, 0UL);
+ }
+
+ for (i = 0; i < core_num_wrps; ++i) {
+ write_wb_reg(ARM_BASE_WCR + i, 0UL);
+ write_wb_reg(ARM_BASE_WVR + i, 0UL);
+ }
+}
+
+static int __cpuinit dbg_reset_notify(struct notifier_block *self,
+ unsigned long action, void *cpu)
+{
+ if (action == CPU_ONLINE)
+ smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata dbg_reset_nb = {
+ .notifier_call = dbg_reset_notify,
+};
+
+static int __init arch_hw_breakpoint_init(void)
+{
+ u32 dscr;
+ cpumask_t cpumask = { CPU_BITS_NONE };
+
+ debug_arch = get_debug_arch();
+
+ if (!debug_arch_supported()) {
+ pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
+ return 0;
+ }
+
+ /* Determine how many BRPs/WRPs are available. */
+ core_num_brps = get_num_brps();
+ core_num_reserved_brps = get_num_reserved_brps();
+ core_num_wrps = get_num_wrps();
+
+ pr_info("found %d breakpoint and %d watchpoint registers.\n",
+ core_num_brps + core_num_reserved_brps, core_num_wrps);
+
+ if (core_num_reserved_brps)
+ pr_info("%d breakpoint(s) reserved for watchpoint "
+ "single-step.\n", core_num_reserved_brps);
+
+ /*
+ * Reset the breakpoint resources. We assume that a halting
+ * debugger will leave the world in a nice state for us.
+ */
+ on_each_cpu(reset_ctrl_regs, &cpumask, 1);
+ if (!cpumask_empty(&cpumask)) {
+ core_num_brps = 0;
+ core_num_reserved_brps = 0;
+ core_num_wrps = 0;
+ return 0;
+ }
+
+ ARM_DBG_READ(c1, 0, dscr);
+ if (dscr & ARM_DSCR_HDBGEN) {
+ max_watchpoint_len = 4;
+ pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
+ max_watchpoint_len);
+ } else {
+ /* Work out the maximum supported watchpoint length. */
+ max_watchpoint_len = get_max_wp_len();
+ pr_info("maximum watchpoint size is %u bytes.\n",
+ max_watchpoint_len);
+ }
+
+ /* Register debug fault handler. */
+ hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
+ "watchpoint debug exception");
+ hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
+ "breakpoint debug exception");
+
+ /* Register hotplug notifier. */
+ register_cpu_notifier(&dbg_reset_nb);
+ return 0;
+}
+arch_initcall(arch_hw_breakpoint_init);
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+}
+
+/*
+ * Dummy function to register with die_notifier.
+ */
+int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data)
+{
+ return NOTIFY_DONE;
+}
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
new file mode 100644
index 00000000..e7cbb50d
--- /dev/null
+++ b/arch/arm/kernel/init_task.c
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/kernel/init_task.c
+ */
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+#include <linux/uaccess.h>
+
+#include <asm/pgtable.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte aligned due to the
+ * way process stacks are handled. This is done by making sure
+ * the linker maps this in the .text segment right after head.S,
+ * and making head.S ensure the proper alignment.
+ *
+ * The things we do for performance..
+ */
+union thread_union init_thread_union __init_task_data =
+ { INIT_THREAD_INFO(init_task) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
diff --git a/arch/arm/kernel/io.c b/arch/arm/kernel/io.c
new file mode 100644
index 00000000..f4470307
--- /dev/null
+++ b/arch/arm/kernel/io.c
@@ -0,0 +1,50 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+{
+ unsigned char *t = to;
+ while (count) {
+ count--;
+ *t = readb(from);
+ t++;
+ from++;
+ }
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+{
+ const unsigned char *f = from;
+ while (count) {
+ count--;
+ writeb(*f, to);
+ f++;
+ to++;
+ }
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void _memset_io(volatile void __iomem *dst, int c, size_t count)
+{
+ while (count) {
+ count--;
+ writeb(c, dst);
+ dst++;
+ }
+}
+
+EXPORT_SYMBOL(_memcpy_fromio);
+EXPORT_SYMBOL(_memcpy_toio);
+EXPORT_SYMBOL(_memset_io);
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
new file mode 100644
index 00000000..26179497
--- /dev/null
+++ b/arch/arm/kernel/irq.c
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/arm/kernel/irq.c
+ *
+ * Copyright (C) 1992 Linus Torvalds
+ * Modifications for ARM processor Copyright (C) 1995-2000 Russell King.
+ *
+ * Support for Dynamic Tick Timer Copyright (C) 2004-2005 Nokia Corporation.
+ * Dynamic Tick Timer written by Tony Lindgren <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.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.
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/random.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/kallsyms.h>
+#include <linux/proc_fs.h>
+#include <linux/ftrace.h>
+
+#include <asm/system.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+/*
+ * No architecture-specific irq_finish function defined in arm/arch/irqs.h.
+ */
+#ifndef irq_finish
+#define irq_finish(irq) do { } while (0)
+#endif
+
+unsigned long irq_err_count;
+
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+#ifdef CONFIG_FIQ
+ show_fiq_list(p, prec);
+#endif
+#ifdef CONFIG_SMP
+ show_ipi_list(p, prec);
+#endif
+#ifdef CONFIG_LOCAL_TIMERS
+ show_local_irqs(p, prec);
+#endif
+ seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
+ return 0;
+}
+
+/*
+ * handle_IRQ handles all hardware IRQ's. Decoded IRQs should
+ * not come via this function. Instead, they should provide their
+ * own 'handler'. Used by platform code implementing C-based 1st
+ * level decoding.
+ */
+void handle_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ irq_enter();
+
+ /*
+ * Some hardware gives randomly wrong interrupts. Rather
+ * than crashing, do something sensible.
+ */
+ if (unlikely(irq >= nr_irqs)) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "Bad IRQ%u\n", irq);
+ ack_bad_irq(irq);
+ } else {
+ generic_handle_irq(irq);
+ }
+
+ /* AT91 specific workaround */
+ irq_finish(irq);
+
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+
+/*
+ * asm_do_IRQ is the interface to be used from assembly code.
+ */
+asmlinkage void __exception_irq_entry
+asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
+{
+ handle_IRQ(irq, regs);
+}
+
+void set_irq_flags(unsigned int irq, unsigned int iflags)
+{
+ unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+
+ if (irq >= nr_irqs) {
+ printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
+ return;
+ }
+
+ if (iflags & IRQF_VALID)
+ clr |= IRQ_NOREQUEST;
+ if (iflags & IRQF_PROBE)
+ clr |= IRQ_NOPROBE;
+ if (!(iflags & IRQF_NOAUTOEN))
+ clr |= IRQ_NOAUTOEN;
+ /* Order is clear bits in "clr" then set bits in "set" */
+ irq_modify_status(irq, clr, set & ~clr);
+}
+
+void __init init_IRQ(void)
+{
+ machine_desc->init_irq();
+}
+
+#ifdef CONFIG_SPARSE_IRQ
+int __init arch_probe_nr_irqs(void)
+{
+ nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
+ return nr_irqs;
+}
+#endif
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static bool migrate_one_irq(struct irq_desc *desc)
+{
+ struct irq_data *d = irq_desc_get_irq_data(desc);
+ const struct cpumask *affinity = d->affinity;
+ struct irq_chip *c;
+ bool ret = false;
+
+ /*
+ * If this is a per-CPU interrupt, or the affinity does not
+ * include this CPU, then we have nothing to do.
+ */
+ if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
+ return false;
+
+ if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+ affinity = cpu_online_mask;
+ ret = true;
+ }
+
+ c = irq_data_get_irq_chip(d);
+ if (!c->irq_set_affinity)
+ pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+ else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret)
+ cpumask_copy(d->affinity, affinity);
+
+ return ret;
+}
+
+/*
+ * The current CPU has been marked offline. Migrate IRQs off this CPU.
+ * If the affinity settings do not allow other CPUs, force them onto any
+ * available CPU.
+ *
+ * Note: we must iterate over all IRQs, whether they have an attached
+ * action structure or not, as we need to get chained interrupts too.
+ */
+void migrate_irqs(void)
+{
+ unsigned int i;
+ struct irq_desc *desc;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ for_each_irq_desc(i, desc) {
+ bool affinity_broken;
+
+ raw_spin_lock(&desc->lock);
+ affinity_broken = migrate_one_irq(desc);
+ raw_spin_unlock(&desc->lock);
+
+ if (affinity_broken && printk_ratelimit())
+ pr_warning("IRQ%u no longer affine to CPU%u\n", i,
+ smp_processor_id());
+ }
+
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
new file mode 100644
index 00000000..34648591
--- /dev/null
+++ b/arch/arm/kernel/isa.c
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/arm/kernel/isa.c
+ *
+ * Copyright (C) 1999 Phil Blundell
+ *
+ * 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.
+ *
+ * ISA shared memory and I/O port support, and is required to support
+ * iopl, inb, outb and friends in userspace via glibc emulation.
+ */
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+static unsigned int isa_membase, isa_portbase, isa_portshift;
+
+static ctl_table ctl_isa_vars[4] = {
+ {
+ .procname = "membase",
+ .data = &isa_membase,
+ .maxlen = sizeof(isa_membase),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ }, {
+ .procname = "portbase",
+ .data = &isa_portbase,
+ .maxlen = sizeof(isa_portbase),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ }, {
+ .procname = "portshift",
+ .data = &isa_portshift,
+ .maxlen = sizeof(isa_portshift),
+ .mode = 0444,
+ .proc_handler = proc_dointvec,
+ }, {}
+};
+
+static struct ctl_table_header *isa_sysctl_header;
+
+static ctl_table ctl_isa[2] = {
+ {
+ .procname = "isa",
+ .mode = 0555,
+ .child = ctl_isa_vars,
+ }, {}
+};
+
+static ctl_table ctl_bus[2] = {
+ {
+ .procname = "bus",
+ .mode = 0555,
+ .child = ctl_isa,
+ }, {}
+};
+
+void __init
+register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
+{
+ isa_membase = membase;
+ isa_portbase = portbase;
+ isa_portshift = portshift;
+ isa_sysctl_header = register_sysctl_table(ctl_bus);
+}
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
new file mode 100644
index 00000000..7fa3bb0d
--- /dev/null
+++ b/arch/arm/kernel/iwmmxt.S
@@ -0,0 +1,346 @@
+/*
+ * linux/arch/arm/kernel/iwmmxt.S
+ *
+ * XScale iWMMXt (Concan) context switching and handling
+ *
+ * Initial code:
+ * Copyright (c) 2003, Intel Corporation
+ *
+ * Full lazy switching support, optimizations and more, by Nicolas Pitre
+* Copyright (c) 2003-2004, MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+
+#if defined(CONFIG_CPU_PJ4)
+#define PJ4(code...) code
+#define XSC(code...)
+#else
+#define PJ4(code...)
+#define XSC(code...) code
+#endif
+
+#define MMX_WR0 (0x00)
+#define MMX_WR1 (0x08)
+#define MMX_WR2 (0x10)
+#define MMX_WR3 (0x18)
+#define MMX_WR4 (0x20)
+#define MMX_WR5 (0x28)
+#define MMX_WR6 (0x30)
+#define MMX_WR7 (0x38)
+#define MMX_WR8 (0x40)
+#define MMX_WR9 (0x48)
+#define MMX_WR10 (0x50)
+#define MMX_WR11 (0x58)
+#define MMX_WR12 (0x60)
+#define MMX_WR13 (0x68)
+#define MMX_WR14 (0x70)
+#define MMX_WR15 (0x78)
+#define MMX_WCSSF (0x80)
+#define MMX_WCASF (0x84)
+#define MMX_WCGR0 (0x88)
+#define MMX_WCGR1 (0x8C)
+#define MMX_WCGR2 (0x90)
+#define MMX_WCGR3 (0x94)
+
+#define MMX_SIZE (0x98)
+
+ .text
+
+/*
+ * Lazy switching of Concan coprocessor context
+ *
+ * r10 = struct thread_info pointer
+ * r9 = ret_from_exception
+ * lr = undefined instr exit
+ *
+ * called from prefetch exception handler with interrupts disabled
+ */
+
+ENTRY(iwmmxt_task_enable)
+
+ XSC(mrc p15, 0, r2, c15, c1, 0)
+ PJ4(mrc p15, 0, r2, c1, c0, 2)
+ @ CP0 and CP1 accessible?
+ XSC(tst r2, #0x3)
+ PJ4(tst r2, #0xf)
+ movne pc, lr @ if so no business here
+ @ enable access to CP0 and CP1
+ XSC(orr r2, r2, #0x3)
+ XSC(mcr p15, 0, r2, c15, c1, 0)
+ PJ4(orr r2, r2, #0xf)
+ PJ4(mcr p15, 0, r2, c1, c0, 2)
+
+ ldr r3, =concan_owner
+ add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r2, [sp, #60] @ current task pc value
+ ldr r1, [r3] @ get current Concan owner
+ str r0, [r3] @ this task now owns Concan regs
+ sub r2, r2, #4 @ adjust pc back
+ str r2, [sp, #60]
+
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+
+ teq r1, #0 @ test for last ownership
+ mov lr, r9 @ normal exit from exception
+ beq concan_load @ no owner, skip save
+
+concan_save:
+
+ tmrc r2, wCon
+
+ @ CUP? wCx
+ tst r2, #0x1
+ beq 1f
+
+concan_dump:
+
+ wstrw wCSSF, [r1, #MMX_WCSSF]
+ wstrw wCASF, [r1, #MMX_WCASF]
+ wstrw wCGR0, [r1, #MMX_WCGR0]
+ wstrw wCGR1, [r1, #MMX_WCGR1]
+ wstrw wCGR2, [r1, #MMX_WCGR2]
+ wstrw wCGR3, [r1, #MMX_WCGR3]
+
+1: @ MUP? wRn
+ tst r2, #0x2
+ beq 2f
+
+ wstrd wR0, [r1, #MMX_WR0]
+ wstrd wR1, [r1, #MMX_WR1]
+ wstrd wR2, [r1, #MMX_WR2]
+ wstrd wR3, [r1, #MMX_WR3]
+ wstrd wR4, [r1, #MMX_WR4]
+ wstrd wR5, [r1, #MMX_WR5]
+ wstrd wR6, [r1, #MMX_WR6]
+ wstrd wR7, [r1, #MMX_WR7]
+ wstrd wR8, [r1, #MMX_WR8]
+ wstrd wR9, [r1, #MMX_WR9]
+ wstrd wR10, [r1, #MMX_WR10]
+ wstrd wR11, [r1, #MMX_WR11]
+ wstrd wR12, [r1, #MMX_WR12]
+ wstrd wR13, [r1, #MMX_WR13]
+ wstrd wR14, [r1, #MMX_WR14]
+ wstrd wR15, [r1, #MMX_WR15]
+
+2: teq r0, #0 @ anything to load?
+ moveq pc, lr
+
+concan_load:
+
+ @ Load wRn
+ wldrd wR0, [r0, #MMX_WR0]
+ wldrd wR1, [r0, #MMX_WR1]
+ wldrd wR2, [r0, #MMX_WR2]
+ wldrd wR3, [r0, #MMX_WR3]
+ wldrd wR4, [r0, #MMX_WR4]
+ wldrd wR5, [r0, #MMX_WR5]
+ wldrd wR6, [r0, #MMX_WR6]
+ wldrd wR7, [r0, #MMX_WR7]
+ wldrd wR8, [r0, #MMX_WR8]
+ wldrd wR9, [r0, #MMX_WR9]
+ wldrd wR10, [r0, #MMX_WR10]
+ wldrd wR11, [r0, #MMX_WR11]
+ wldrd wR12, [r0, #MMX_WR12]
+ wldrd wR13, [r0, #MMX_WR13]
+ wldrd wR14, [r0, #MMX_WR14]
+ wldrd wR15, [r0, #MMX_WR15]
+
+ @ Load wCx
+ wldrw wCSSF, [r0, #MMX_WCSSF]
+ wldrw wCASF, [r0, #MMX_WCASF]
+ wldrw wCGR0, [r0, #MMX_WCGR0]
+ wldrw wCGR1, [r0, #MMX_WCGR1]
+ wldrw wCGR2, [r0, #MMX_WCGR2]
+ wldrw wCGR3, [r0, #MMX_WCGR3]
+
+ @ clear CUP/MUP (only if r1 != 0)
+ teq r1, #0
+ mov r2, #0
+ moveq pc, lr
+ tmcr wCon, r2
+ mov pc, lr
+
+/*
+ * Back up Concan regs to save area and disable access to them
+ * (mainly for gdb or sleep mode usage)
+ *
+ * r0 = struct thread_info pointer of target task or NULL for any
+ */
+
+ENTRY(iwmmxt_task_disable)
+
+ stmfd sp!, {r4, lr}
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r1, [r3] @ get current Concan owner
+ teq r1, #0 @ any current owner?
+ beq 1f @ no: quit
+ teq r0, #0 @ any owner?
+ teqne r1, r2 @ or specified one?
+ bne 1f @ no: quit
+
+ @ enable access to CP0 and CP1
+ XSC(mrc p15, 0, r4, c15, c1, 0)
+ XSC(orr r4, r4, #0xf)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
+ PJ4(mrc p15, 0, r4, c1, c0, 2)
+ PJ4(orr r4, r4, #0x3)
+ PJ4(mcr p15, 0, r4, c1, c0, 2)
+
+ mov r0, #0 @ nothing to load
+ str r0, [r3] @ no more current owner
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+ bl concan_save
+
+ @ disable access to CP0 and CP1
+ XSC(bic r4, r4, #0x3)
+ XSC(mcr p15, 0, r4, c15, c1, 0)
+ PJ4(bic r4, r4, #0xf)
+ PJ4(mcr p15, 0, r4, c1, c0, 2)
+
+ mrc p15, 0, r2, c2, c0, 0
+ mov r2, r2 @ cpwait
+
+1: msr cpsr_c, ip @ restore interrupt mode
+ ldmfd sp!, {r4, pc}
+
+/*
+ * Copy Concan state to given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to store Concan state
+ *
+ * this is called mainly in the creation of signal stack frames
+ */
+
+ENTRY(iwmmxt_task_copy)
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r3, [r3] @ get current Concan owner
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ current Concan values are in the task save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r1
+ mov r1, r2
+ mov r2, #MMX_SIZE
+ b memcpy
+
+1: @ this task owns Concan regs -- grab a copy from there
+ mov r0, #0 @ nothing to load
+ mov r2, #3 @ save all regs
+ mov r3, lr @ preserve return address
+ bl concan_dump
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
+
+/*
+ * Restore Concan state from given memory address
+ *
+ * r0 = struct thread_info pointer of target task
+ * r1 = memory address where to get Concan state from
+ *
+ * this is used to restore Concan state when unwinding a signal stack frame
+ */
+
+ENTRY(iwmmxt_task_restore)
+
+ mrs ip, cpsr
+ orr r2, ip, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, r2
+
+ ldr r3, =concan_owner
+ add r2, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r3, [r3] @ get current Concan owner
+ bic r2, r2, #0x7 @ 64-bit alignment
+ teq r2, r3 @ does this task own it...
+ beq 1f
+
+ @ this task doesn't own Concan regs -- use its save area
+ msr cpsr_c, ip @ restore interrupt mode
+ mov r0, r2
+ mov r2, #MMX_SIZE
+ b memcpy
+
+1: @ this task owns Concan regs -- load them directly
+ mov r0, r1
+ mov r1, #0 @ don't clear CUP/MUP
+ mov r3, lr @ preserve return address
+ bl concan_load
+ msr cpsr_c, ip @ restore interrupt mode
+ mov pc, r3
+
+/*
+ * Concan handling on task switch
+ *
+ * r0 = next thread_info pointer
+ *
+ * Called only from the iwmmxt notifier with task preemption disabled.
+ */
+ENTRY(iwmmxt_task_switch)
+
+ XSC(mrc p15, 0, r1, c15, c1, 0)
+ PJ4(mrc p15, 0, r1, c1, c0, 2)
+ @ CP0 and CP1 accessible?
+ XSC(tst r1, #0x3)
+ PJ4(tst r1, #0xf)
+ bne 1f @ yes: block them for next task
+
+ ldr r2, =concan_owner
+ add r3, r0, #TI_IWMMXT_STATE @ get next task Concan save area
+ ldr r2, [r2] @ get current Concan owner
+ teq r2, r3 @ next task owns it?
+ movne pc, lr @ no: leave Concan disabled
+
+1: @ flip Conan access
+ XSC(eor r1, r1, #0x3)
+ XSC(mcr p15, 0, r1, c15, c1, 0)
+ PJ4(eor r1, r1, #0xf)
+ PJ4(mcr p15, 0, r1, c1, c0, 2)
+
+ mrc p15, 0, r1, c2, c0, 0
+ sub pc, lr, r1, lsr #32 @ cpwait and return
+
+/*
+ * Remove Concan ownership of given task
+ *
+ * r0 = struct thread_info pointer
+ */
+ENTRY(iwmmxt_task_release)
+
+ mrs r2, cpsr
+ orr ip, r2, #PSR_I_BIT @ disable interrupts
+ msr cpsr_c, ip
+ ldr r3, =concan_owner
+ add r0, r0, #TI_IWMMXT_STATE @ get task Concan save area
+ ldr r1, [r3] @ get current Concan owner
+ eors r0, r0, r1 @ if equal...
+ streq r0, [r3] @ then clear ownership
+ msr cpsr_c, r2 @ restore interrupts
+ mov pc, lr
+
+ .data
+concan_owner:
+ .word 0
+
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
new file mode 100644
index 00000000..778c2f70
--- /dev/null
+++ b/arch/arm/kernel/kgdb.c
@@ -0,0 +1,255 @@
+/*
+ * arch/arm/kernel/kgdb.c
+ *
+ * ARM KGDB support
+ *
+ * Copyright (c) 2002-2004 MontaVista Software, Inc
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: George Davis <davis_g@mvista.com>
+ * Deepak Saxena <dsaxena@plexity.net>
+ */
+#include <linux/irq.h>
+#include <linux/kdebug.h>
+#include <linux/kgdb.h>
+#include <asm/traps.h>
+
+struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
+{
+ { "r0", 4, offsetof(struct pt_regs, ARM_r0)},
+ { "r1", 4, offsetof(struct pt_regs, ARM_r1)},
+ { "r2", 4, offsetof(struct pt_regs, ARM_r2)},
+ { "r3", 4, offsetof(struct pt_regs, ARM_r3)},
+ { "r4", 4, offsetof(struct pt_regs, ARM_r4)},
+ { "r5", 4, offsetof(struct pt_regs, ARM_r5)},
+ { "r6", 4, offsetof(struct pt_regs, ARM_r6)},
+ { "r7", 4, offsetof(struct pt_regs, ARM_r7)},
+ { "r8", 4, offsetof(struct pt_regs, ARM_r8)},
+ { "r9", 4, offsetof(struct pt_regs, ARM_r9)},
+ { "r10", 4, offsetof(struct pt_regs, ARM_r10)},
+ { "fp", 4, offsetof(struct pt_regs, ARM_fp)},
+ { "ip", 4, offsetof(struct pt_regs, ARM_ip)},
+ { "sp", 4, offsetof(struct pt_regs, ARM_sp)},
+ { "lr", 4, offsetof(struct pt_regs, ARM_lr)},
+ { "pc", 4, offsetof(struct pt_regs, ARM_pc)},
+ { "f0", 12, -1 },
+ { "f1", 12, -1 },
+ { "f2", 12, -1 },
+ { "f3", 12, -1 },
+ { "f4", 12, -1 },
+ { "f5", 12, -1 },
+ { "f6", 12, -1 },
+ { "f7", 12, -1 },
+ { "fps", 4, -1 },
+ { "cpsr", 4, offsetof(struct pt_regs, ARM_cpsr)},
+};
+
+char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return NULL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
+ dbg_reg_def[regno].size);
+ else
+ memset(mem, 0, dbg_reg_def[regno].size);
+ return dbg_reg_def[regno].name;
+}
+
+int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
+{
+ if (regno >= DBG_MAX_REG_NUM || regno < 0)
+ return -EINVAL;
+
+ if (dbg_reg_def[regno].offset != -1)
+ memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
+ dbg_reg_def[regno].size);
+ return 0;
+}
+
+void
+sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
+{
+ struct pt_regs *thread_regs;
+ int regno;
+
+ /* Just making sure... */
+ if (task == NULL)
+ return;
+
+ /* Initialize to zero */
+ for (regno = 0; regno < GDB_MAX_REGS; regno++)
+ gdb_regs[regno] = 0;
+
+ /* Otherwise, we have only some registers from switch_to() */
+ thread_regs = task_pt_regs(task);
+ gdb_regs[_R0] = thread_regs->ARM_r0;
+ gdb_regs[_R1] = thread_regs->ARM_r1;
+ gdb_regs[_R2] = thread_regs->ARM_r2;
+ gdb_regs[_R3] = thread_regs->ARM_r3;
+ gdb_regs[_R4] = thread_regs->ARM_r4;
+ gdb_regs[_R5] = thread_regs->ARM_r5;
+ gdb_regs[_R6] = thread_regs->ARM_r6;
+ gdb_regs[_R7] = thread_regs->ARM_r7;
+ gdb_regs[_R8] = thread_regs->ARM_r8;
+ gdb_regs[_R9] = thread_regs->ARM_r9;
+ gdb_regs[_R10] = thread_regs->ARM_r10;
+ gdb_regs[_FP] = thread_regs->ARM_fp;
+ gdb_regs[_IP] = thread_regs->ARM_ip;
+ gdb_regs[_SPT] = thread_regs->ARM_sp;
+ gdb_regs[_LR] = thread_regs->ARM_lr;
+ gdb_regs[_PC] = thread_regs->ARM_pc;
+ gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
+}
+
+void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
+{
+ regs->ARM_pc = pc;
+}
+
+static int compiled_break;
+
+int kgdb_arch_handle_exception(int exception_vector, int signo,
+ int err_code, char *remcom_in_buffer,
+ char *remcom_out_buffer,
+ struct pt_regs *linux_regs)
+{
+ unsigned long addr;
+ char *ptr;
+
+ switch (remcom_in_buffer[0]) {
+ case 'D':
+ case 'k':
+ case 'c':
+ /*
+ * Try to read optional parameter, pc unchanged if no parm.
+ * If this was a compiled breakpoint, we need to move
+ * to the next instruction or we will just breakpoint
+ * over and over again.
+ */
+ ptr = &remcom_in_buffer[1];
+ if (kgdb_hex2long(&ptr, &addr))
+ linux_regs->ARM_pc = addr;
+ else if (compiled_break == 1)
+ linux_regs->ARM_pc += 4;
+
+ compiled_break = 0;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+static int kgdb_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+ return 0;
+}
+
+static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
+{
+ compiled_break = 1;
+ kgdb_handle_exception(1, SIGTRAP, 0, regs);
+
+ return 0;
+}
+
+static struct undef_hook kgdb_brkpt_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = KGDB_BREAKINST,
+ .fn = kgdb_brk_fn
+};
+
+static struct undef_hook kgdb_compiled_brkpt_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = KGDB_COMPILED_BREAK,
+ .fn = kgdb_compiled_brk_fn
+};
+
+static void kgdb_call_nmi_hook(void *ignored)
+{
+ kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
+}
+
+void kgdb_roundup_cpus(unsigned long flags)
+{
+ local_irq_enable();
+ smp_call_function(kgdb_call_nmi_hook, NULL, 0);
+ local_irq_disable();
+}
+
+static int __kgdb_notify(struct die_args *args, unsigned long cmd)
+{
+ struct pt_regs *regs = args->regs;
+
+ if (kgdb_handle_exception(1, args->signr, cmd, regs))
+ return NOTIFY_DONE;
+ return NOTIFY_STOP;
+}
+static int
+kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr)
+{
+ unsigned long flags;
+ int ret;
+
+ local_irq_save(flags);
+ ret = __kgdb_notify(ptr, cmd);
+ local_irq_restore(flags);
+
+ return ret;
+}
+
+static struct notifier_block kgdb_notifier = {
+ .notifier_call = kgdb_notify,
+ .priority = -INT_MAX,
+};
+
+
+/**
+ * kgdb_arch_init - Perform any architecture specific initalization.
+ *
+ * This function will handle the initalization of any architecture
+ * specific callbacks.
+ */
+int kgdb_arch_init(void)
+{
+ int ret = register_die_notifier(&kgdb_notifier);
+
+ if (ret != 0)
+ return ret;
+
+ register_undef_hook(&kgdb_brkpt_hook);
+ register_undef_hook(&kgdb_compiled_brkpt_hook);
+
+ return 0;
+}
+
+/**
+ * kgdb_arch_exit - Perform any architecture specific uninitalization.
+ *
+ * This function will handle the uninitalization of any architecture
+ * specific callbacks, for dynamic registration and unregistration.
+ */
+void kgdb_arch_exit(void)
+{
+ unregister_undef_hook(&kgdb_brkpt_hook);
+ unregister_undef_hook(&kgdb_compiled_brkpt_hook);
+ unregister_die_notifier(&kgdb_notifier);
+}
+
+/*
+ * Register our undef instruction hooks with ARM undef core.
+ * We regsiter a hook specifically looking for the KGB break inst
+ * and we handle the normal undef case within the do_undefinstr
+ * handler.
+ */
+struct kgdb_arch arch_kgdb_ops = {
+#ifndef __ARMEB__
+ .gdb_bpt_instr = {0xfe, 0xde, 0xff, 0xe7}
+#else /* ! __ARMEB__ */
+ .gdb_bpt_instr = {0xe7, 0xff, 0xde, 0xfe}
+#endif
+};
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
new file mode 100644
index 00000000..15eeff6a
--- /dev/null
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -0,0 +1,1670 @@
+/*
+ * arch/arm/kernel/kprobes-decode.c
+ *
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+/*
+ * We do not have hardware single-stepping on ARM, This
+ * effort is further complicated by the ARM not having a
+ * "next PC" register. Instructions that change the PC
+ * can't be safely single-stepped in a MP environment, so
+ * we have a lot of work to do:
+ *
+ * In the prepare phase:
+ * *) If it is an instruction that does anything
+ * with the CPU mode, we reject it for a kprobe.
+ * (This is out of laziness rather than need. The
+ * instructions could be simulated.)
+ *
+ * *) Otherwise, decode the instruction rewriting its
+ * registers to take fixed, ordered registers and
+ * setting a handler for it to run the instruction.
+ *
+ * In the execution phase by an instruction's handler:
+ *
+ * *) If the PC is written to by the instruction, the
+ * instruction must be fully simulated in software.
+ *
+ * *) Otherwise, a modified form of the instruction is
+ * directly executed. Its handler calls the
+ * instruction in insn[0]. In insn[1] is a
+ * "mov pc, lr" to return.
+ *
+ * Before calling, load up the reordered registers
+ * from the original instruction's registers. If one
+ * of the original input registers is the PC, compute
+ * and adjust the appropriate input register.
+ *
+ * After call completes, copy the output registers to
+ * the original instruction's original registers.
+ *
+ * We don't use a real breakpoint instruction since that
+ * would have us in the kernel go from SVC mode to SVC
+ * mode losing the link register. Instead we use an
+ * undefined instruction. To simplify processing, the
+ * undefined instruction used for kprobes must be reserved
+ * exclusively for kprobes use.
+ *
+ * TODO: ifdef out some instruction decoding based on architecture.
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+
+#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
+
+#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
+
+#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
+
+/*
+ * Test if load/store instructions writeback the address register.
+ * if P (bit 24) == 0 or W (bit 21) == 1
+ */
+#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
+
+#define PSR_fs (PSR_f|PSR_s)
+
+#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */
+
+typedef long (insn_0arg_fn_t)(void);
+typedef long (insn_1arg_fn_t)(long);
+typedef long (insn_2arg_fn_t)(long, long);
+typedef long (insn_3arg_fn_t)(long, long, long);
+typedef long (insn_4arg_fn_t)(long, long, long, long);
+typedef long long (insn_llret_0arg_fn_t)(void);
+typedef long long (insn_llret_3arg_fn_t)(long, long, long);
+typedef long long (insn_llret_4arg_fn_t)(long, long, long, long);
+
+union reg_pair {
+ long long dr;
+#ifdef __LITTLE_ENDIAN
+ struct { long r0, r1; };
+#else
+ struct { long r1, r0; };
+#endif
+};
+
+/*
+ * For STR and STM instructions, an ARM core may choose to use either
+ * a +8 or a +12 displacement from the current instruction's address.
+ * Whichever value is chosen for a given core, it must be the same for
+ * both instructions and may not change. This function measures it.
+ */
+
+static int str_pc_offset;
+
+static void __init find_str_pc_offset(void)
+{
+ int addr, scratch, ret;
+
+ __asm__ (
+ "sub %[ret], pc, #4 \n\t"
+ "str pc, %[addr] \n\t"
+ "ldr %[scr], %[addr] \n\t"
+ "sub %[ret], %[scr], %[ret] \n\t"
+ : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
+
+ str_pc_offset = ret;
+}
+
+/*
+ * The insnslot_?arg_r[w]flags() functions below are to keep the
+ * msr -> *fn -> mrs instruction sequences indivisible so that
+ * the state of the CPSR flags aren't inadvertently modified
+ * just before or just after the call.
+ */
+
+static inline long __kprobes
+insnslot_0arg_rflags(long cpsr, insn_0arg_fn_t *fn)
+{
+ register long ret asm("r0");
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret)
+ : [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_0arg_rflags(long cpsr, insn_llret_0arg_fn_t *fn)
+{
+ register long ret0 asm("r0");
+ register long ret1 asm("r1");
+ union reg_pair fnr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret0), "=r" (ret1)
+ : [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ fnr.r0 = ret0;
+ fnr.r1 = ret1;
+ return fnr.dr;
+}
+
+static inline long __kprobes
+insnslot_1arg_rflags(long r0, long cpsr, insn_1arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long ret asm("r0");
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret)
+ : "0" (rr0), [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_2arg_rflags(long r0, long r1, long cpsr, insn_2arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long ret asm("r0");
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret)
+ : "0" (rr0), "r" (rr1),
+ [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_3arg_rflags(long r0, long r1, long r2, long cpsr, insn_3arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long ret asm("r0");
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret)
+ : "0" (rr0), "r" (rr1), "r" (rr2),
+ [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_3arg_rflags(long r0, long r1, long r2, long cpsr,
+ insn_llret_3arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long ret0 asm("r0");
+ register long ret1 asm("r1");
+ union reg_pair fnr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret0), "=r" (ret1)
+ : "0" (rr0), "r" (rr1), "r" (rr2),
+ [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ fnr.r0 = ret0;
+ fnr.r1 = ret1;
+ return fnr.dr;
+}
+
+static inline long __kprobes
+insnslot_4arg_rflags(long r0, long r1, long r2, long r3, long cpsr,
+ insn_4arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long rr3 asm("r3") = r3;
+ register long ret asm("r0");
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[cpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ : "=r" (ret)
+ : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+ [cpsr] "r" (cpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_1arg_rwflags(long r0, long *cpsr, insn_1arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long ret asm("r0");
+ long oldcpsr = *cpsr;
+ long newcpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : "=r" (ret), [newcpsr] "=r" (newcpsr)
+ : "0" (rr0), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_2arg_rwflags(long r0, long r1, long *cpsr, insn_2arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long ret asm("r0");
+ long oldcpsr = *cpsr;
+ long newcpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : "=r" (ret), [newcpsr] "=r" (newcpsr)
+ : "0" (rr0), "r" (rr1), [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_3arg_rwflags(long r0, long r1, long r2, long *cpsr,
+ insn_3arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long ret asm("r0");
+ long oldcpsr = *cpsr;
+ long newcpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : "=r" (ret), [newcpsr] "=r" (newcpsr)
+ : "0" (rr0), "r" (rr1), "r" (rr2),
+ [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+ return ret;
+}
+
+static inline long __kprobes
+insnslot_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
+ insn_4arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long rr3 asm("r3") = r3;
+ register long ret asm("r0");
+ long oldcpsr = *cpsr;
+ long newcpsr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : "=r" (ret), [newcpsr] "=r" (newcpsr)
+ : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+ [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+ return ret;
+}
+
+static inline long long __kprobes
+insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
+ insn_llret_4arg_fn_t *fn)
+{
+ register long rr0 asm("r0") = r0;
+ register long rr1 asm("r1") = r1;
+ register long rr2 asm("r2") = r2;
+ register long rr3 asm("r3") = r3;
+ register long ret0 asm("r0");
+ register long ret1 asm("r1");
+ long oldcpsr = *cpsr;
+ long newcpsr;
+ union reg_pair fnr;
+
+ __asm__ __volatile__ (
+ "msr cpsr_fs, %[oldcpsr] \n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[fn] \n\t"
+ "mrs %[newcpsr], cpsr \n\t"
+ : "=r" (ret0), "=r" (ret1), [newcpsr] "=r" (newcpsr)
+ : "0" (rr0), "r" (rr1), "r" (rr2), "r" (rr3),
+ [oldcpsr] "r" (oldcpsr), [fn] "r" (fn)
+ : "lr", "cc"
+ );
+ *cpsr = (oldcpsr & ~PSR_fs) | (newcpsr & PSR_fs);
+ fnr.r0 = ret0;
+ fnr.r1 = ret1;
+ return fnr.dr;
+}
+
+/*
+ * To avoid the complications of mimicing single-stepping on a
+ * processor without a Next-PC or a single-step mode, and to
+ * avoid having to deal with the side-effects of boosting, we
+ * simulate or emulate (almost) all ARM instructions.
+ *
+ * "Simulation" is where the instruction's behavior is duplicated in
+ * C code. "Emulation" is where the original instruction is rewritten
+ * and executed, often by altering its registers.
+ *
+ * By having all behavior of the kprobe'd instruction completed before
+ * returning from the kprobe_handler(), all locks (scheduler and
+ * interrupt) can safely be released. There is no need for secondary
+ * breakpoints, no race with MP or preemptable kernels, nor having to
+ * clean up resources counts at a later time impacting overall system
+ * performance. By rewriting the instruction, only the minimum registers
+ * need to be loaded and saved back optimizing performance.
+ *
+ * Calling the insnslot_*_rwflags version of a function doesn't hurt
+ * anything even when the CPSR flags aren't updated by the
+ * instruction. It's just a little slower in return for saving
+ * a little space by not having a duplicate function that doesn't
+ * update the flags. (The same optimization can be said for
+ * instructions that do or don't perform register writeback)
+ * Also, instructions can either read the flags, only write the
+ * flags, or read and write the flags. To save combinations
+ * rather than for sheer performance, flag functions just assume
+ * read and write of flags.
+ */
+
+static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t insn = p->opcode;
+ long iaddr = (long)p->addr;
+ int disp = branch_displacement(insn);
+
+ if (insn & (1 << 24))
+ regs->ARM_lr = iaddr + 4;
+
+ regs->ARM_pc = iaddr + 8 + disp;
+}
+
+static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t insn = p->opcode;
+ long iaddr = (long)p->addr;
+ int disp = branch_displacement(insn);
+
+ regs->ARM_lr = iaddr + 4;
+ regs->ARM_pc = iaddr + 8 + disp + ((insn >> 23) & 0x2);
+ regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t insn = p->opcode;
+ int rm = insn & 0xf;
+ long rmv = regs->uregs[rm];
+
+ if (insn & (1 << 5))
+ regs->ARM_lr = (long)p->addr + 4;
+
+ regs->ARM_pc = rmv & ~0x1;
+ regs->ARM_cpsr &= ~PSR_T_BIT;
+ if (rmv & 0x1)
+ regs->ARM_cpsr |= PSR_T_BIT;
+}
+
+static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ unsigned long mask = 0xf8ff03df; /* Mask out execution state */
+ regs->uregs[rd] = regs->ARM_cpsr & mask;
+}
+
+static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t insn = p->opcode;
+ int rn = (insn >> 16) & 0xf;
+ int lbit = insn & (1 << 20);
+ int wbit = insn & (1 << 21);
+ int ubit = insn & (1 << 23);
+ int pbit = insn & (1 << 24);
+ long *addr = (long *)regs->uregs[rn];
+ int reg_bit_vector;
+ int reg_count;
+
+ reg_count = 0;
+ reg_bit_vector = insn & 0xffff;
+ while (reg_bit_vector) {
+ reg_bit_vector &= (reg_bit_vector - 1);
+ ++reg_count;
+ }
+
+ if (!ubit)
+ addr -= reg_count;
+ addr += (!pbit == !ubit);
+
+ reg_bit_vector = insn & 0xffff;
+ while (reg_bit_vector) {
+ int reg = __ffs(reg_bit_vector);
+ reg_bit_vector &= (reg_bit_vector - 1);
+ if (lbit)
+ regs->uregs[reg] = *addr++;
+ else
+ *addr++ = regs->uregs[reg];
+ }
+
+ if (wbit) {
+ if (!ubit)
+ addr -= reg_count;
+ addr -= (!pbit == !ubit);
+ regs->uregs[rn] = (long)addr;
+ }
+}
+
+static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
+{
+ regs->ARM_pc = (long)p->addr + str_pc_offset;
+ simulate_ldm1stm1(p, regs);
+ regs->ARM_pc = (long)p->addr + 4;
+}
+
+static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
+{
+ regs->uregs[12] = regs->uregs[13];
+}
+
+static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf; /* rm may be invalid, don't care. */
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+
+ /* Not following the C calling convention here, so need asm(). */
+ __asm__ __volatile__ (
+ "ldr r0, %[rn] \n\t"
+ "ldr r1, %[rm] \n\t"
+ "msr cpsr_fs, %[cpsr]\n\t"
+ "mov lr, pc \n\t"
+ "mov pc, %[i_fn] \n\t"
+ "str r0, %[rn] \n\t" /* in case of writeback */
+ "str r2, %[rd0] \n\t"
+ "str r3, %[rd1] \n\t"
+ : [rn] "+m" (rnv),
+ [rd0] "=m" (regs->uregs[rd]),
+ [rd1] "=m" (regs->uregs[rd+1])
+ : [rm] "m" (rmv),
+ [cpsr] "r" (regs->ARM_cpsr),
+ [i_fn] "r" (i_fn)
+ : "r0", "r1", "r2", "r3", "lr", "cc"
+ );
+ if (is_writeback(insn))
+ regs->uregs[rn] = rnv;
+}
+
+static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ /* rm/rmv may be invalid, don't care. */
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long rnv_wb;
+
+ rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
+ regs->uregs[rd+1],
+ regs->ARM_cpsr, i_fn);
+ if (is_writeback(insn))
+ regs->uregs[rn] = rnv_wb;
+}
+
+static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ union reg_pair fnr;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ long rdv;
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long cpsr = regs->ARM_cpsr;
+
+ fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
+ if (rn != 15)
+ regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */
+ rdv = fnr.r1;
+
+ if (rd == 15) {
+#if __LINUX_ARM_ARCH__ >= 5
+ cpsr &= ~PSR_T_BIT;
+ if (rdv & 0x1)
+ cpsr |= PSR_T_BIT;
+ regs->ARM_cpsr = cpsr;
+ rdv &= ~0x1;
+#else
+ rdv &= ~0x2;
+#endif
+ }
+ regs->uregs[rd] = rdv;
+}
+
+static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long iaddr = (long)p->addr;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
+ long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn];
+ long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+ long rnv_wb;
+
+ rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+ if (rn != 15)
+ regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */
+}
+
+static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rm = insn & 0xf;
+ long rmv = regs->uregs[rm];
+
+ /* Writes Q flag */
+ regs->uregs[rd] = insnslot_1arg_rwflags(rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_sel(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ long rnv = regs->uregs[rn];
+ long rmv = regs->uregs[rm];
+
+ /* Reads GE bits */
+ regs->uregs[rd] = insnslot_2arg_rflags(rnv, rmv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
+
+ insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
+{
+}
+
+static void __kprobes
+emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ long rdv = regs->uregs[rd];
+
+ regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rn = insn & 0xf;
+ long rdv = regs->uregs[rd];
+ long rnv = regs->uregs[rn];
+
+ regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rm = insn & 0xf;
+ long rmv = regs->uregs[rm];
+
+ regs->uregs[rd] = insnslot_1arg_rflags(rmv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd12rn16rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ int rm = insn & 0xf;
+ long rnv = regs->uregs[rn];
+ long rmv = regs->uregs[rm];
+
+ regs->uregs[rd] =
+ insnslot_2arg_rwflags(rnv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd16rn12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 16) & 0xf;
+ int rn = (insn >> 12) & 0xf;
+ int rs = (insn >> 8) & 0xf;
+ int rm = insn & 0xf;
+ long rnv = regs->uregs[rn];
+ long rsv = regs->uregs[rs];
+ long rmv = regs->uregs[rm];
+
+ regs->uregs[rd] =
+ insnslot_3arg_rwflags(rnv, rsv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rd16rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 16) & 0xf;
+ int rs = (insn >> 8) & 0xf;
+ int rm = insn & 0xf;
+ long rsv = regs->uregs[rs];
+ long rmv = regs->uregs[rm];
+
+ regs->uregs[rd] =
+ insnslot_2arg_rwflags(rsv, rmv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_rdhi16rdlo12rs8rm0_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_llret_4arg_fn_t *i_fn = (insn_llret_4arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ union reg_pair fnr;
+ int rdhi = (insn >> 16) & 0xf;
+ int rdlo = (insn >> 12) & 0xf;
+ int rs = (insn >> 8) & 0xf;
+ int rm = insn & 0xf;
+ long rsv = regs->uregs[rs];
+ long rmv = regs->uregs[rm];
+
+ fnr.dr = insnslot_llret_4arg_rwflags(regs->uregs[rdhi],
+ regs->uregs[rdlo], rsv, rmv,
+ &regs->ARM_cpsr, i_fn);
+ regs->uregs[rdhi] = fnr.r0;
+ regs->uregs[rdlo] = fnr.r1;
+}
+
+static void __kprobes
+emulate_alu_imm_rflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+ regs->uregs[rd] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf;
+ long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+ regs->uregs[rd] = insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ int rn = (insn >> 16) & 0xf;
+ long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
+
+ insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */
+ int rs = (insn >> 8) & 0xf; /* invalid, don't care. */
+ int rm = insn & 0xf;
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long rsv = regs->uregs[rs];
+
+ regs->uregs[rd] =
+ insnslot_3arg_rflags(rnv, rmv, rsv, regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ int rd = (insn >> 12) & 0xf;
+ int rn = (insn >> 16) & 0xf; /* rn/rnv/rs/rsv may be */
+ int rs = (insn >> 8) & 0xf; /* invalid, don't care. */
+ int rm = insn & 0xf;
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long rsv = regs->uregs[rs];
+
+ regs->uregs[rd] =
+ insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
+}
+
+static void __kprobes
+emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
+{
+ insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
+ kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
+ int rn = (insn >> 16) & 0xf;
+ int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */
+ int rm = insn & 0xf;
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
+ long rsv = regs->uregs[rs];
+
+ insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
+ : (~insn & (1 << 22));
+
+ if (is_writeback(insn) && is_r15(insn, 16))
+ return INSN_REJECTED; /* Writeback to PC */
+
+ insn &= 0xfff00fff;
+ insn |= 0x00001000; /* Rn = r0, Rd = r1 */
+ if (not_imm) {
+ insn &= ~0xf;
+ insn |= 2; /* Rm = r2 */
+ }
+ asi->insn[0] = insn;
+ asi->insn_handler = (insn & (1 << 20)) ? emulate_ldr : emulate_str;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xffff0fff; /* Rd = r0 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd12_modify;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
+ struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xffff0ff0; /* Rd = r0 */
+ insn |= 0x00000001; /* Rn = r1 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd12rn0_modify;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd12rm0;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
+ struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
+ insn |= 0x00000001; /* Rm = r1 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd12rn16rm0_rwflags;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
+ struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 16))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */
+ insn |= 0x00000001; /* Rm = r1 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd16rs8rm0_rwflags;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
+ struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 16))
+ return INSN_REJECTED; /* Rd is PC */
+
+ insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */
+ insn |= 0x00000102; /* Rs = r1, Rm = r2 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rd16rn12rs8rm0_rwflags;
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
+ struct arch_specific_insn *asi)
+{
+ if (is_r15(insn, 16) || is_r15(insn, 12))
+ return INSN_REJECTED; /* RdHi or RdLo is PC */
+
+ insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */
+ insn |= 0x00001203; /* Rs = r2, Rm = r3 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_rdhi16rdlo12rs8rm0_rwflags;
+ return INSN_GOOD;
+}
+
+/*
+ * For the instruction masking and comparisons in all the "space_*"
+ * functions below, Do _not_ rearrange the order of tests unless
+ * you're very, very sure of what you are doing. For the sake of
+ * efficiency, the masks for some tests sometimes assume other test
+ * have been done prior to them so the number of patterns to test
+ * for an instruction set can be as broad as possible to reduce the
+ * number of tests needed.
+ */
+
+static enum kprobe_insn __kprobes
+space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
+ /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
+ /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
+ /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
+ if ((insn & 0xfe300000) == 0xf4100000) {
+ asi->insn_handler = emulate_nop;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
+ if ((insn & 0xfe000000) == 0xfa000000) {
+ asi->insn_handler = simulate_blx1;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
+ /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
+
+ /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
+ /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+
+ /* Coprocessor instructions... */
+ /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
+ /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
+ /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+ /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+ /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+ /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+ /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+
+ return INSN_REJECTED;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
+ if ((insn & 0x0f900010) == 0x01000000) {
+
+ /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
+ if ((insn & 0x0ff000f0) == 0x01000000) {
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+ asi->insn_handler = simulate_mrs;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
+ if ((insn & 0x0ff00090) == 0x01400080)
+ return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
+ asi);
+
+ /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
+ /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
+ if ((insn & 0x0ff000b0) == 0x012000a0 ||
+ (insn & 0x0ff00090) == 0x01600080)
+ return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+
+ /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
+ /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
+ if ((insn & 0x0ff00090) == 0x01000080 ||
+ (insn & 0x0ff000b0) == 0x01200080)
+ return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+ /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
+ /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
+ /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
+
+ /* Other instruction encodings aren't yet defined */
+ return INSN_REJECTED;
+ }
+
+ /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
+ else if ((insn & 0x0f900090) == 0x01000010) {
+
+ /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
+ /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
+ if ((insn & 0x0ff000d0) == 0x01200010) {
+ if ((insn & 0x0ff000ff) == 0x0120003f)
+ return INSN_REJECTED; /* BLX pc */
+ asi->insn_handler = simulate_blx2bx;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
+ if ((insn & 0x0ff000f0) == 0x01600010)
+ return prep_emulate_rd12rm0(insn, asi);
+
+ /* QADD : cccc 0001 0000 xxxx xxxx xxxx 0101 xxxx :Q */
+ /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
+ /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
+ /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
+ if ((insn & 0x0f9000f0) == 0x01000050)
+ return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
+ /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
+ /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
+
+ /* Other instruction encodings aren't yet defined */
+ return INSN_REJECTED;
+ }
+
+ /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
+ else if ((insn & 0x0f0000f0) == 0x00000090) {
+
+ /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */
+ /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
+ /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */
+ /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
+ /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */
+ /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */
+ /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */
+ /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */
+ /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */
+ /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
+ /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */
+ /* UMLALS : cccc 0000 1011 xxxx xxxx xxxx 1001 xxxx :cc */
+ /* SMULL : cccc 0000 1100 xxxx xxxx xxxx 1001 xxxx : */
+ /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
+ /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */
+ /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
+ if ((insn & 0x00d00000) == 0x00500000)
+ return INSN_REJECTED;
+ else if ((insn & 0x00e00000) == 0x00000000)
+ return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+ else if ((insn & 0x00a00000) == 0x00200000)
+ return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+ else
+ return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
+ asi);
+ }
+
+ /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
+ else if ((insn & 0x0e000090) == 0x00000090) {
+
+ /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
+ /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
+ /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
+ /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
+ /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
+ /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
+ /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
+ /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
+ /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
+ /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
+ /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
+ /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
+ /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
+
+ /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
+ /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
+ /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
+ /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
+ /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
+ /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
+ if ((insn & 0x0f0000f0) == 0x01000090) {
+ if ((insn & 0x0fb000f0) == 0x01000090) {
+ /* SWP/SWPB */
+ return prep_emulate_rd12rn16rm0_wflags(insn,
+ asi);
+ } else {
+ /* STREX/LDREX variants and unallocaed space */
+ return INSN_REJECTED;
+ }
+
+ } else if ((insn & 0x0e1000d0) == 0x00000d0) {
+ /* STRD/LDRD */
+ if ((insn & 0x0000e000) == 0x0000e000)
+ return INSN_REJECTED; /* Rd is LR or PC */
+ if (is_writeback(insn) && is_r15(insn, 16))
+ return INSN_REJECTED; /* Writeback to PC */
+
+ insn &= 0xfff00fff;
+ insn |= 0x00002000; /* Rn = r0, Rd = r2 */
+ if (!(insn & (1 << 22))) {
+ /* Register index */
+ insn &= ~0xf;
+ insn |= 1; /* Rm = r1 */
+ }
+ asi->insn[0] = insn;
+ asi->insn_handler =
+ (insn & (1 << 5)) ? emulate_strd : emulate_ldrd;
+ return INSN_GOOD;
+ }
+
+ /* LDRH/STRH/LDRSB/LDRSH */
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+ return prep_emulate_ldr_str(insn, asi);
+ }
+
+ /* cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx xxxx */
+
+ /*
+ * ALU op with S bit and Rd == 15 :
+ * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
+ */
+ if ((insn & 0x0e10f000) == 0x0010f000)
+ return INSN_REJECTED;
+
+ /*
+ * "mov ip, sp" is the most common kprobe'd instruction by far.
+ * Check and optimize for it explicitly.
+ */
+ if (insn == 0xe1a0c00d) {
+ asi->insn_handler = simulate_mov_ipsp;
+ return INSN_GOOD_NO_SLOT;
+ }
+
+ /*
+ * Data processing: Immediate-shift / Register-shift
+ * ALU op : cccc 000x xxxx xxxx xxxx xxxx xxxx xxxx
+ * CPY : cccc 0001 1010 xxxx xxxx 0000 0000 xxxx
+ * MOV : cccc 0001 101x xxxx xxxx xxxx xxxx xxxx
+ * *S (bit 20) updates condition codes
+ * ADC/SBC/RSC reads the C flag
+ */
+ insn &= 0xfff00ff0; /* Rn = r0, Rd = r0 */
+ insn |= 0x00000001; /* Rm = r1 */
+ if (insn & 0x010) {
+ insn &= 0xfffff0ff; /* register shift */
+ insn |= 0x00000200; /* Rs = r2 */
+ }
+ asi->insn[0] = insn;
+
+ if ((insn & 0x0f900000) == 0x01100000) {
+ /*
+ * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
+ * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
+ * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
+ * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
+ */
+ asi->insn_handler = emulate_alu_tests;
+ } else {
+ /* ALU ops which write to Rd */
+ asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
+ emulate_alu_rwflags : emulate_alu_rflags;
+ }
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
+ /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
+ if ((insn & 0x0fb00000) == 0x03000000)
+ return prep_emulate_rd12_modify(insn, asi);
+
+ /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
+ if ((insn & 0x0fff0000) == 0x03200000) {
+ unsigned op2 = insn & 0x000000ff;
+ if (op2 == 0x01 || op2 == 0x04) {
+ /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
+ /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_none;
+ return INSN_GOOD;
+ } else if (op2 <= 0x03) {
+ /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
+ /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
+ /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
+ /*
+ * We make WFE and WFI true NOPs to avoid stalls due
+ * to missing events whilst processing the probe.
+ */
+ asi->insn_handler = emulate_nop;
+ return INSN_GOOD_NO_SLOT;
+ }
+ /* For DBG and unallocated hints it's safest to reject them */
+ return INSN_REJECTED;
+ }
+
+ /*
+ * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
+ * ALU op with S bit and Rd == 15 :
+ * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
+ */
+ if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */
+ (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
+ return INSN_REJECTED;
+
+ /*
+ * Data processing: 32-bit Immediate
+ * ALU op : cccc 001x xxxx xxxx xxxx xxxx xxxx xxxx
+ * MOV : cccc 0011 101x xxxx xxxx xxxx xxxx xxxx
+ * *S (bit 20) updates condition codes
+ * ADC/SBC/RSC reads the C flag
+ */
+ insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */
+ asi->insn[0] = insn;
+
+ if ((insn & 0x0f900000) == 0x03100000) {
+ /*
+ * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
+ * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
+ * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
+ * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
+ */
+ asi->insn_handler = emulate_alu_tests_imm;
+ } else {
+ /* ALU ops which write to Rd */
+ asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
+ emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
+ }
+ return INSN_GOOD;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
+ if ((insn & 0x0ff000f0) == 0x068000b0) {
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+ insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
+ insn |= 0x00000001; /* Rm = r1 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_sel;
+ return INSN_GOOD;
+ }
+
+ /* SSAT : cccc 0110 101x xxxx xxxx xxxx xx01 xxxx :Q */
+ /* USAT : cccc 0110 111x xxxx xxxx xxxx xx01 xxxx :Q */
+ /* SSAT16 : cccc 0110 1010 xxxx xxxx xxxx 0011 xxxx :Q */
+ /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
+ if ((insn & 0x0fa00030) == 0x06a00010 ||
+ (insn & 0x0fb000f0) == 0x06a00030) {
+ if (is_r15(insn, 12))
+ return INSN_REJECTED; /* Rd is PC */
+ insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
+ asi->insn[0] = insn;
+ asi->insn_handler = emulate_sat;
+ return INSN_GOOD;
+ }
+
+ /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
+ /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
+ /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
+ /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
+ if ((insn & 0x0ff00070) == 0x06b00030 ||
+ (insn & 0x0ff00070) == 0x06f00030)
+ return prep_emulate_rd12rm0(insn, asi);
+
+ /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */
+ /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
+ /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
+ /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
+ /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
+ /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
+ /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */
+ /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
+ /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */
+ /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */
+ /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */
+ /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */
+ /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */
+ /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */
+ /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */
+ /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */
+ /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */
+ /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */
+ /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */
+ /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */
+ /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */
+ /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */
+ /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */
+ /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
+ /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
+ /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
+ /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
+ /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
+ /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */
+ /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
+ /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */
+ /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */
+ /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */
+ /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */
+ /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */
+ /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */
+ /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */
+ /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */
+ /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */
+ /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */
+ /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */
+ /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */
+ /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */
+ /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */
+ /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */
+ if ((insn & 0x0f800010) == 0x06000010) {
+ if ((insn & 0x00300000) == 0x00000000 ||
+ (insn & 0x000000e0) == 0x000000a0 ||
+ (insn & 0x000000e0) == 0x000000c0)
+ return INSN_REJECTED; /* Unallocated space */
+ return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+ }
+
+ /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */
+ /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */
+ if ((insn & 0x0ff00030) == 0x06800010)
+ return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+
+ /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */
+ /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */
+ /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */
+ /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
+ /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */
+ /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */
+ /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */
+ /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */
+ /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */
+ /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */
+ /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */
+ /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */
+ /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */
+ /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */
+ if ((insn & 0x0f8000f0) == 0x06800070) {
+ if ((insn & 0x00300000) == 0x00100000)
+ return INSN_REJECTED; /* Unallocated space */
+
+ if ((insn & 0x000f0000) == 0x000f0000)
+ return prep_emulate_rd12rm0(insn, asi);
+ else
+ return prep_emulate_rd12rn16rm0_wflags(insn, asi);
+ }
+
+ /* Other instruction encodings aren't yet defined */
+ return INSN_REJECTED;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* Undef : cccc 0111 1111 xxxx xxxx xxxx 1111 xxxx */
+ if ((insn & 0x0ff000f0) == 0x03f000f0)
+ return INSN_REJECTED;
+
+ /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
+ /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
+ if ((insn & 0x0ff00090) == 0x07400010)
+ return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
+
+ /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
+ /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
+ /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
+ /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */
+ /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */
+ /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */
+ /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */
+ /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */
+ if ((insn & 0x0ff00090) == 0x07000010 ||
+ (insn & 0x0ff000d0) == 0x07500010 ||
+ (insn & 0x0ff000f0) == 0x07800010) {
+
+ if ((insn & 0x0000f000) == 0x0000f000)
+ return prep_emulate_rd16rs8rm0_wflags(insn, asi);
+ else
+ return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+ }
+
+ /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */
+ if ((insn & 0x0ff000d0) == 0x075000d0)
+ return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
+
+ /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */
+ /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */
+ if ((insn & 0x0fa00070) == 0x07a00050)
+ return prep_emulate_rd12rm0(insn, asi);
+
+ /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */
+ /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */
+ if ((insn & 0x0fe00070) == 0x07c00010) {
+
+ if ((insn & 0x0000000f) == 0x0000000f)
+ return prep_emulate_rd12_modify(insn, asi);
+ else
+ return prep_emulate_rd12rn0_modify(insn, asi);
+ }
+
+ return INSN_REJECTED;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* LDR : cccc 01xx x0x1 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRB : cccc 01xx x1x1 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRBT : cccc 01x0 x111 xxxx xxxx xxxx xxxx xxxx */
+ /* LDRT : cccc 01x0 x011 xxxx xxxx xxxx xxxx xxxx */
+ /* STR : cccc 01xx x0x0 xxxx xxxx xxxx xxxx xxxx */
+ /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
+ /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
+ /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
+
+ if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
+ return INSN_REJECTED; /* LDRB into PC */
+
+ return prep_emulate_ldr_str(insn, asi);
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* LDM(2) : cccc 100x x101 xxxx 0xxx xxxx xxxx xxxx */
+ /* LDM(3) : cccc 100x x1x1 xxxx 1xxx xxxx xxxx xxxx */
+ if ((insn & 0x0e708000) == 0x85000000 ||
+ (insn & 0x0e508000) == 0x85010000)
+ return INSN_REJECTED;
+
+ /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
+ /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
+ asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
+ simulate_stm1_pc : simulate_ldm1stm1;
+ return INSN_GOOD_NO_SLOT;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
+ /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
+ asi->insn_handler = simulate_bbl;
+ return INSN_GOOD_NO_SLOT;
+}
+
+static enum kprobe_insn __kprobes
+space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ /* Coprocessor instructions... */
+ /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
+ /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
+ /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
+ /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
+ /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
+ /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
+ /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
+
+ /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
+
+ return INSN_REJECTED;
+}
+
+static unsigned long __kprobes __check_eq(unsigned long cpsr)
+{
+ return cpsr & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_ne(unsigned long cpsr)
+{
+ return (~cpsr) & PSR_Z_BIT;
+}
+
+static unsigned long __kprobes __check_cs(unsigned long cpsr)
+{
+ return cpsr & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_cc(unsigned long cpsr)
+{
+ return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_mi(unsigned long cpsr)
+{
+ return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_pl(unsigned long cpsr)
+{
+ return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_vs(unsigned long cpsr)
+{
+ return cpsr & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_vc(unsigned long cpsr)
+{
+ return (~cpsr) & PSR_V_BIT;
+}
+
+static unsigned long __kprobes __check_hi(unsigned long cpsr)
+{
+ cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+ return cpsr & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ls(unsigned long cpsr)
+{
+ cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
+ return (~cpsr) & PSR_C_BIT;
+}
+
+static unsigned long __kprobes __check_ge(unsigned long cpsr)
+{
+ cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ return (~cpsr) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_lt(unsigned long cpsr)
+{
+ cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ return cpsr & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_gt(unsigned long cpsr)
+{
+ unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
+ return (~temp) & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_le(unsigned long cpsr)
+{
+ unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
+ temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
+ return temp & PSR_N_BIT;
+}
+
+static unsigned long __kprobes __check_al(unsigned long cpsr)
+{
+ return true;
+}
+
+static kprobe_check_cc * const condition_checks[16] = {
+ &__check_eq, &__check_ne, &__check_cs, &__check_cc,
+ &__check_mi, &__check_pl, &__check_vs, &__check_vc,
+ &__check_hi, &__check_ls, &__check_ge, &__check_lt,
+ &__check_gt, &__check_le, &__check_al, &__check_al
+};
+
+/* Return:
+ * INSN_REJECTED If instruction is one not allowed to kprobe,
+ * INSN_GOOD If instruction is supported and uses instruction slot,
+ * INSN_GOOD_NO_SLOT If instruction is supported but doesn't use its slot.
+ *
+ * For instructions we don't want to kprobe (INSN_REJECTED return result):
+ * These are generally ones that modify the processor state making
+ * them "hard" to simulate such as switches processor modes or
+ * make accesses in alternate modes. Any of these could be simulated
+ * if the work was put into it, but low return considering they
+ * should also be very rare.
+ */
+enum kprobe_insn __kprobes
+arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
+{
+ asi->insn_check_cc = condition_checks[insn>>28];
+ asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
+
+ if ((insn & 0xf0000000) == 0xf0000000)
+
+ return space_1111(insn, asi);
+
+ else if ((insn & 0x0e000000) == 0x00000000)
+
+ return space_cccc_000x(insn, asi);
+
+ else if ((insn & 0x0e000000) == 0x02000000)
+
+ return space_cccc_001x(insn, asi);
+
+ else if ((insn & 0x0f000010) == 0x06000010)
+
+ return space_cccc_0110__1(insn, asi);
+
+ else if ((insn & 0x0f000010) == 0x07000010)
+
+ return space_cccc_0111__1(insn, asi);
+
+ else if ((insn & 0x0c000000) == 0x04000000)
+
+ return space_cccc_01xx(insn, asi);
+
+ else if ((insn & 0x0e000000) == 0x08000000)
+
+ return space_cccc_100x(insn, asi);
+
+ else if ((insn & 0x0e000000) == 0x0a000000)
+
+ return space_cccc_101x(insn, asi);
+
+ return space_cccc_11xx(insn, asi);
+}
+
+void __init arm_kprobe_decode_init(void)
+{
+ find_str_pc_offset();
+}
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
new file mode 100644
index 00000000..1656c875
--- /dev/null
+++ b/arch/arm/kernel/kprobes.c
@@ -0,0 +1,476 @@
+/*
+ * arch/arm/kernel/kprobes.c
+ *
+ * Kprobes on ARM
+ *
+ * Abhishek Sagar <sagar.abhishek@gmail.com>
+ * Copyright (C) 2006, 2007 Motorola Inc.
+ *
+ * Nicolas Pitre <nico@marvell.com>
+ * Copyright (C) 2007 Marvell 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/kprobes.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/stop_machine.h>
+#include <linux/stringify.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+
+#define MIN_STACK_SIZE(addr) \
+ min((unsigned long)MAX_STACK_SIZE, \
+ (unsigned long)current_thread_info() + THREAD_START_SP - (addr))
+
+#define flush_insns(addr, cnt) \
+ flush_icache_range((unsigned long)(addr), \
+ (unsigned long)(addr) + \
+ sizeof(kprobe_opcode_t) * (cnt))
+
+/* Used as a marker in ARM_pc to note when we're in a jprobe. */
+#define JPROBE_MAGIC_ADDR 0xffffffff
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+ kprobe_opcode_t insn;
+ kprobe_opcode_t tmp_insn[MAX_INSN_SIZE];
+ unsigned long addr = (unsigned long)p->addr;
+ int is;
+
+ if (addr & 0x3 || in_exception_text(addr))
+ return -EINVAL;
+
+ insn = *p->addr;
+ p->opcode = insn;
+ p->ainsn.insn = tmp_insn;
+
+ switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
+ case INSN_REJECTED: /* not supported */
+ return -EINVAL;
+
+ case INSN_GOOD: /* instruction uses slot */
+ p->ainsn.insn = get_insn_slot();
+ if (!p->ainsn.insn)
+ return -ENOMEM;
+ for (is = 0; is < MAX_INSN_SIZE; ++is)
+ p->ainsn.insn[is] = tmp_insn[is];
+ flush_insns(p->ainsn.insn, MAX_INSN_SIZE);
+ break;
+
+ case INSN_GOOD_NO_SLOT: /* instruction doesn't need insn slot */
+ p->ainsn.insn = NULL;
+ break;
+ }
+
+ return 0;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+ *p->addr = KPROBE_BREAKPOINT_INSTRUCTION;
+ flush_insns(p->addr, 1);
+}
+
+/*
+ * The actual disarming is done here on each CPU and synchronized using
+ * stop_machine. This synchronization is necessary on SMP to avoid removing
+ * a probe between the moment the 'Undefined Instruction' exception is raised
+ * and the moment the exception handler reads the faulting instruction from
+ * memory.
+ */
+int __kprobes __arch_disarm_kprobe(void *p)
+{
+ struct kprobe *kp = p;
+ *kp->addr = kp->opcode;
+ flush_insns(kp->addr, 1);
+ return 0;
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+ stop_machine(__arch_disarm_kprobe, p, &cpu_online_map);
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+ if (p->ainsn.insn) {
+ free_insn_slot(p->ainsn.insn, 0);
+ p->ainsn.insn = NULL;
+ }
+}
+
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+}
+
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p)
+{
+ __get_cpu_var(current_kprobe) = p;
+}
+
+static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ regs->ARM_pc += 4;
+ if (p->ainsn.insn_check_cc(regs->ARM_cpsr))
+ p->ainsn.insn_handler(p, regs);
+}
+
+/*
+ * Called with IRQs disabled. IRQs must remain disabled from that point
+ * all the way until processing this kprobe is complete. The current
+ * kprobes implementation cannot process more than one nested level of
+ * kprobe, and that level is reserved for user kprobe handlers, so we can't
+ * risk encountering a new kprobe in an interrupt handler.
+ */
+void __kprobes kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *p, *cur;
+ struct kprobe_ctlblk *kcb;
+ kprobe_opcode_t *addr = (kprobe_opcode_t *)regs->ARM_pc;
+
+ kcb = get_kprobe_ctlblk();
+ cur = kprobe_running();
+ p = get_kprobe(addr);
+
+ if (p) {
+ if (cur) {
+ /* Kprobe is pending, so we're recursing. */
+ switch (kcb->kprobe_status) {
+ case KPROBE_HIT_ACTIVE:
+ case KPROBE_HIT_SSDONE:
+ /* A pre- or post-handler probe got us here. */
+ kprobes_inc_nmissed_count(p);
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p);
+ kcb->kprobe_status = KPROBE_REENTER;
+ singlestep(p, regs, kcb);
+ restore_previous_kprobe(kcb);
+ break;
+ default:
+ /* impossible cases */
+ BUG();
+ }
+ } else {
+ set_current_kprobe(p);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+ /*
+ * If we have no pre-handler or it returned 0, we
+ * continue with normal processing. If we have a
+ * pre-handler and it returned non-zero, it prepped
+ * for calling the break_handler below on re-entry,
+ * so get out doing nothing more here.
+ */
+ if (!p->pre_handler || !p->pre_handler(p, regs)) {
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ singlestep(p, regs, kcb);
+ if (p->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ p->post_handler(p, regs, 0);
+ }
+ reset_current_kprobe();
+ }
+ }
+ } else if (cur) {
+ /* We probably hit a jprobe. Call its break handler. */
+ if (cur->break_handler && cur->break_handler(cur, regs)) {
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ singlestep(cur, regs, kcb);
+ if (cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
+ }
+ }
+ reset_current_kprobe();
+ } else {
+ /*
+ * The probe was removed and a race is in progress.
+ * There is nothing we can do about it. Let's restart
+ * the instruction. By the time we can restart, the
+ * real instruction will be there.
+ */
+ }
+}
+
+static int __kprobes kprobe_trap_handler(struct pt_regs *regs, unsigned int instr)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ kprobe_handler(regs);
+ local_irq_restore(flags);
+ return 0;
+}
+
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ switch (kcb->kprobe_status) {
+ case KPROBE_HIT_SS:
+ case KPROBE_REENTER:
+ /*
+ * We are here because the instruction being single
+ * stepped caused a page fault. We reset the current
+ * kprobe and the PC to point back to the probe address
+ * and allow the page fault handler to continue as a
+ * normal page fault.
+ */
+ regs->ARM_pc = (long)cur->addr;
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
+ } else {
+ reset_current_kprobe();
+ }
+ break;
+
+ case KPROBE_HIT_ACTIVE:
+ case KPROBE_HIT_SSDONE:
+ /*
+ * We increment the nmissed count for accounting,
+ * we can also use npre/npostfault count for accounting
+ * these specific fault cases.
+ */
+ kprobes_inc_nmissed_count(cur);
+
+ /*
+ * We come here because instructions in the pre/post
+ * handler caused the page_fault, this could happen
+ * if handler tries to access user space by
+ * copy_from_user(), get_user() etc. Let the
+ * user-specified handler try to fix it.
+ */
+ if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
+ return 1;
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ /*
+ * notify_die() is currently never called on ARM,
+ * so this callback is currently empty.
+ */
+ return NOTIFY_DONE;
+}
+
+/*
+ * When a retprobed function returns, trampoline_handler() is called,
+ * calling the kretprobe's handler. We construct a struct pt_regs to
+ * give a view of registers r0-r11 to the user return-handler. This is
+ * not a complete pt_regs structure, but that should be plenty sufficient
+ * for kretprobe handlers which should normally be interested in r0 only
+ * anyway.
+ */
+void __naked __kprobes kretprobe_trampoline(void)
+{
+ __asm__ __volatile__ (
+ "stmdb sp!, {r0 - r11} \n\t"
+ "mov r0, sp \n\t"
+ "bl trampoline_handler \n\t"
+ "mov lr, r0 \n\t"
+ "ldmia sp!, {r0 - r11} \n\t"
+ "mov pc, lr \n\t"
+ : : : "memory");
+}
+
+/* Called from kretprobe_trampoline */
+static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
+ unsigned long flags, orig_ret_address = 0;
+ unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+
+ INIT_HLIST_HEAD(&empty_rp);
+ kretprobe_hash_lock(current, &head, &flags);
+
+ /*
+ * It is possible to have multiple instances associated with a given
+ * task either because multiple functions in the call path have
+ * a return probe installed on them, and/or more than one return
+ * probe was registered for a target function.
+ *
+ * We can handle this because:
+ * - instances are always inserted at the head of the list
+ * - when multiple return probes are registered for the same
+ * function, the first instance's ret_addr will point to the
+ * real return address, and all the rest will point to
+ * kretprobe_trampoline
+ */
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler) {
+ __get_cpu_var(current_kprobe) = &ri->rp->kp;
+ get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
+ ri->rp->handler(ri, regs);
+ __get_cpu_var(current_kprobe) = NULL;
+ }
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
+ recycle_rp_inst(ri, &empty_rp);
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+ kretprobe_hash_unlock(current, &flags);
+
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
+
+ return (void *)orig_ret_address;
+}
+
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+{
+ ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
+
+ /* Replace the return addr with trampoline addr. */
+ regs->ARM_lr = (unsigned long)&kretprobe_trampoline;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ long sp_addr = regs->ARM_sp;
+
+ kcb->jprobe_saved_regs = *regs;
+ memcpy(kcb->jprobes_stack, (void *)sp_addr, MIN_STACK_SIZE(sp_addr));
+ regs->ARM_pc = (long)jp->entry;
+ regs->ARM_cpsr |= PSR_I_BIT;
+ preempt_disable();
+ return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ __asm__ __volatile__ (
+ /*
+ * Setup an empty pt_regs. Fill SP and PC fields as
+ * they're needed by longjmp_break_handler.
+ *
+ * We allocate some slack between the original SP and start of
+ * our fabricated regs. To be precise we want to have worst case
+ * covered which is STMFD with all 16 regs so we allocate 2 *
+ * sizeof(struct_pt_regs)).
+ *
+ * This is to prevent any simulated instruction from writing
+ * over the regs when they are accessing the stack.
+ */
+ "sub sp, %0, %1 \n\t"
+ "ldr r0, ="__stringify(JPROBE_MAGIC_ADDR)"\n\t"
+ "str %0, [sp, %2] \n\t"
+ "str r0, [sp, %3] \n\t"
+ "mov r0, sp \n\t"
+ "bl kprobe_handler \n\t"
+
+ /*
+ * Return to the context saved by setjmp_pre_handler
+ * and restored by longjmp_break_handler.
+ */
+ "ldr r0, [sp, %4] \n\t"
+ "msr cpsr_cxsf, r0 \n\t"
+ "ldmia sp, {r0 - pc} \n\t"
+ :
+ : "r" (kcb->jprobe_saved_regs.ARM_sp),
+ "I" (sizeof(struct pt_regs) * 2),
+ "J" (offsetof(struct pt_regs, ARM_sp)),
+ "J" (offsetof(struct pt_regs, ARM_pc)),
+ "J" (offsetof(struct pt_regs, ARM_cpsr))
+ : "memory", "cc");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ long stack_addr = kcb->jprobe_saved_regs.ARM_sp;
+ long orig_sp = regs->ARM_sp;
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+
+ if (regs->ARM_pc == JPROBE_MAGIC_ADDR) {
+ if (orig_sp != stack_addr) {
+ struct pt_regs *saved_regs =
+ (struct pt_regs *)kcb->jprobe_saved_regs.ARM_sp;
+ printk("current sp %lx does not match saved sp %lx\n",
+ orig_sp, stack_addr);
+ printk("Saved registers for jprobe %p\n", jp);
+ show_regs(saved_regs);
+ printk("Current registers\n");
+ show_regs(regs);
+ BUG();
+ }
+ *regs = kcb->jprobe_saved_regs;
+ memcpy((void *)stack_addr, kcb->jprobes_stack,
+ MIN_STACK_SIZE(stack_addr));
+ preempt_enable_no_resched();
+ return 1;
+ }
+ return 0;
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ return 0;
+}
+
+static struct undef_hook kprobes_break_hook = {
+ .instr_mask = 0xffffffff,
+ .instr_val = KPROBE_BREAKPOINT_INSTRUCTION,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = kprobe_trap_handler,
+};
+
+int __init arch_init_kprobes()
+{
+ arm_kprobe_decode_init();
+ register_undef_hook(&kprobes_break_hook);
+ return 0;
+}
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
new file mode 100644
index 00000000..136e8376
--- /dev/null
+++ b/arch/arm/kernel/leds.c
@@ -0,0 +1,144 @@
+/*
+ * LED support code, ripped out of arch/arm/kernel/time.c
+ *
+ * Copyright (C) 1994-2001 Russell King
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/leds.h>
+
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+struct leds_evt_name {
+ const char name[8];
+ int on;
+ int off;
+};
+
+static const struct leds_evt_name evt_names[] = {
+ { "amber", led_amber_on, led_amber_off },
+ { "blue", led_blue_on, led_blue_off },
+ { "green", led_green_on, led_green_off },
+ { "red", led_red_on, led_red_off },
+};
+
+static ssize_t leds_store(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ int ret = -EINVAL, len = strcspn(buf, " ");
+
+ if (len > 0 && buf[len] == '\0')
+ len--;
+
+ if (strncmp(buf, "claim", len) == 0) {
+ leds_event(led_claim);
+ ret = size;
+ } else if (strncmp(buf, "release", len) == 0) {
+ leds_event(led_release);
+ ret = size;
+ } else {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
+ if (strlen(evt_names[i].name) != len ||
+ strncmp(buf, evt_names[i].name, len) != 0)
+ continue;
+ if (strncmp(buf+len, " on", 3) == 0) {
+ leds_event(evt_names[i].on);
+ ret = size;
+ } else if (strncmp(buf+len, " off", 4) == 0) {
+ leds_event(evt_names[i].off);
+ ret = size;
+ }
+ break;
+ }
+ }
+ return ret;
+}
+
+static SYSDEV_ATTR(event, 0200, NULL, leds_store);
+
+static struct sysdev_class leds_sysclass = {
+ .name = "leds",
+};
+
+static struct sys_device leds_device = {
+ .id = 0,
+ .cls = &leds_sysclass,
+};
+
+static int leds_suspend(void)
+{
+ leds_event(led_stop);
+ return 0;
+}
+
+static void leds_resume(void)
+{
+ leds_event(led_start);
+}
+
+static void leds_shutdown(void)
+{
+ leds_event(led_halted);
+}
+
+static struct syscore_ops leds_syscore_ops = {
+ .shutdown = leds_shutdown,
+ .suspend = leds_suspend,
+ .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;
+ ret = sysdev_class_register(&leds_sysclass);
+ if (ret == 0)
+ ret = sysdev_register(&leds_device);
+ if (ret == 0)
+ ret = sysdev_create_file(&leds_device, &attr_event);
+
+ if (ret == 0) {
+ register_syscore_ops(&leds_syscore_ops);
+ idle_notifier_register(&leds_idle_nb);
+ }
+
+ return ret;
+}
+
+device_initcall(leds_init);
+
+EXPORT_SYMBOL(leds_event);
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
new file mode 100644
index 00000000..e59bbd49
--- /dev/null
+++ b/arch/arm/kernel/machine_kexec.c
@@ -0,0 +1,124 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/io.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+
+extern const unsigned char relocate_new_kernel[];
+extern const unsigned int relocate_new_kernel_size;
+
+extern void setup_mm_for_reboot(char mode);
+
+extern unsigned long kexec_start_address;
+extern unsigned long kexec_indirection_page;
+extern unsigned long kexec_mach_type;
+extern unsigned long kexec_boot_atags;
+
+static atomic_t waiting_for_crash_ipi;
+
+/*
+ * Provide a dummy crash_notes definition while crash dump arrives to arm.
+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
+ */
+
+int machine_kexec_prepare(struct kimage *image)
+{
+ return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+}
+
+void machine_crash_nonpanic_core(void *unused)
+{
+ struct pt_regs regs;
+
+ crash_setup_regs(&regs, NULL);
+ printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
+ smp_processor_id());
+ crash_save_cpu(&regs, smp_processor_id());
+ flush_cache_all();
+
+ atomic_dec(&waiting_for_crash_ipi);
+ while (1)
+ cpu_relax();
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+ unsigned long msecs;
+
+ local_irq_disable();
+
+ atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
+ smp_call_function(machine_crash_nonpanic_core, NULL, false);
+ msecs = 1000; /* Wait at most a second for the other cpus to stop */
+ while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
+ mdelay(1);
+ msecs--;
+ }
+ if (atomic_read(&waiting_for_crash_ipi) > 0)
+ printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
+
+ crash_save_cpu(regs, smp_processor_id());
+
+ printk(KERN_INFO "Loading crashdump kernel...\n");
+}
+
+/*
+ * Function pointer to optional machine-specific reinitialization
+ */
+void (*kexec_reinit)(void);
+
+void machine_kexec(struct kimage *image)
+{
+ unsigned long page_list;
+ unsigned long reboot_code_buffer_phys;
+ void *reboot_code_buffer;
+
+
+ page_list = image->head & PAGE_MASK;
+
+ /* we need both effective and real address here */
+ reboot_code_buffer_phys =
+ page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+ reboot_code_buffer = page_address(image->control_code_page);
+
+ /* Prepare parameters for reboot_code_buffer*/
+ kexec_start_address = image->start;
+ kexec_indirection_page = page_list;
+ kexec_mach_type = machine_arch_type;
+ kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
+ /* copy our kernel relocation code to the control code page */
+ memcpy(reboot_code_buffer,
+ relocate_new_kernel, relocate_new_kernel_size);
+
+
+ flush_icache_range((unsigned long) reboot_code_buffer,
+ (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
+ printk(KERN_INFO "Bye!\n");
+
+ if (kexec_reinit)
+ kexec_reinit();
+ local_irq_disable();
+ local_fiq_disable();
+ setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
+ flush_cache_all();
+ outer_flush_all();
+ outer_disable();
+ cpu_proc_fin();
+ outer_inv_all();
+ flush_cache_all();
+ cpu_reset(reboot_code_buffer_phys);
+}
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
new file mode 100644
index 00000000..016d6a08
--- /dev/null
+++ b/arch/arm/kernel/module.c
@@ -0,0 +1,367 @@
+/*
+ * linux/arch/arm/kernel/module.c
+ *
+ * Copyright (C) 2002 Russell King.
+ * Modified for nommu by Hyok S. Choi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Module allocation method suggested by Andi Kleen.
+ */
+#include <linux/module.h>
+#include <linux/moduleloader.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/gfp.h>
+
+#include <asm/pgtable.h>
+#include <asm/sections.h>
+#include <asm/smp_plat.h>
+#include <asm/unwind.h>
+
+#ifdef CONFIG_XIP_KERNEL
+/*
+ * The XIP kernel text is mapped in the module area for modules and
+ * some other stuff to work without any indirect relocations.
+ * MODULES_VADDR is redefined here and not in asm/memory.h to avoid
+ * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off.
+ */
+#undef MODULES_VADDR
+#define MODULES_VADDR (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK)
+#endif
+
+#ifdef CONFIG_MMU
+void *module_alloc(unsigned long size)
+{
+ return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+ GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
+ __builtin_return_address(0));
+}
+#else /* CONFIG_MMU */
+void *module_alloc(unsigned long size)
+{
+ return size == 0 ? NULL : vmalloc(size);
+}
+#endif /* !CONFIG_MMU */
+
+void module_free(struct module *module, void *region)
+{
+ vfree(region);
+}
+
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+ Elf_Shdr *sechdrs,
+ char *secstrings,
+ struct module *mod)
+{
+ return 0;
+}
+
+int
+apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
+ unsigned int relindex, struct module *module)
+{
+ Elf32_Shdr *symsec = sechdrs + symindex;
+ Elf32_Shdr *relsec = sechdrs + relindex;
+ Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
+ Elf32_Rel *rel = (void *)relsec->sh_addr;
+ unsigned int i;
+
+ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
+ unsigned long loc;
+ Elf32_Sym *sym;
+ const char *symname;
+ s32 offset;
+#ifdef CONFIG_THUMB2_KERNEL
+ u32 upper, lower, sign, j1, j2;
+#endif
+
+ offset = ELF32_R_SYM(rel->r_info);
+ if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
+ pr_err("%s: section %u reloc %u: bad relocation sym offset\n",
+ module->name, relindex, i);
+ return -ENOEXEC;
+ }
+
+ sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
+ symname = strtab + sym->st_name;
+
+ if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
+ pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
+ module->name, relindex, i, symname,
+ rel->r_offset, dstsec->sh_size);
+ return -ENOEXEC;
+ }
+
+ loc = dstsec->sh_addr + rel->r_offset;
+
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_ARM_NONE:
+ /* ignore */
+ break;
+
+ case R_ARM_ABS32:
+ *(u32 *)loc += sym->st_value;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ offset = (*(u32 *)loc & 0x00ffffff) << 2;
+ if (offset & 0x02000000)
+ offset -= 0x04000000;
+
+ offset += sym->st_value - loc;
+ if (offset & 3 ||
+ offset <= (s32)0xfe000000 ||
+ offset >= (s32)0x02000000) {
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
+ return -ENOEXEC;
+ }
+
+ offset >>= 2;
+
+ *(u32 *)loc &= 0xff000000;
+ *(u32 *)loc |= offset & 0x00ffffff;
+ break;
+
+ case R_ARM_V4BX:
+ /* Preserve Rm and the condition code. Alter
+ * other bits to re-code instruction as
+ * MOV PC,Rm.
+ */
+ *(u32 *)loc &= 0xf000000f;
+ *(u32 *)loc |= 0x01a0f000;
+ break;
+
+ case R_ARM_PREL31:
+ offset = *(u32 *)loc + sym->st_value - loc;
+ *(u32 *)loc = offset & 0x7fffffff;
+ break;
+
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ offset = *(u32 *)loc;
+ offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
+ offset = (offset ^ 0x8000) - 0x8000;
+
+ offset += sym->st_value;
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
+ offset >>= 16;
+
+ *(u32 *)loc &= 0xfff0f000;
+ *(u32 *)loc |= ((offset & 0xf000) << 4) |
+ (offset & 0x0fff);
+ break;
+
+#ifdef CONFIG_THUMB2_KERNEL
+ case R_ARM_THM_CALL:
+ case R_ARM_THM_JUMP24:
+ upper = *(u16 *)loc;
+ lower = *(u16 *)(loc + 2);
+
+ /*
+ * 25 bit signed address range (Thumb-2 BL and B.W
+ * instructions):
+ * S:I1:I2:imm10:imm11:0
+ * where:
+ * S = upper[10] = offset[24]
+ * I1 = ~(J1 ^ S) = offset[23]
+ * I2 = ~(J2 ^ S) = offset[22]
+ * imm10 = upper[9:0] = offset[21:12]
+ * imm11 = lower[10:0] = offset[11:1]
+ * J1 = lower[13]
+ * J2 = lower[11]
+ */
+ sign = (upper >> 10) & 1;
+ j1 = (lower >> 13) & 1;
+ j2 = (lower >> 11) & 1;
+ offset = (sign << 24) | ((~(j1 ^ sign) & 1) << 23) |
+ ((~(j2 ^ sign) & 1) << 22) |
+ ((upper & 0x03ff) << 12) |
+ ((lower & 0x07ff) << 1);
+ if (offset & 0x01000000)
+ offset -= 0x02000000;
+ offset += sym->st_value - loc;
+
+ /*
+ * For function symbols, only Thumb addresses are
+ * allowed (no interworking).
+ *
+ * For non-function symbols, the destination
+ * has no specific ARM/Thumb disposition, so
+ * the branch is resolved under the assumption
+ * that interworking is not required.
+ */
+ if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+ !(offset & 1)) ||
+ offset <= (s32)0xff000000 ||
+ offset >= (s32)0x01000000) {
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
+ return -ENOEXEC;
+ }
+
+ sign = (offset >> 24) & 1;
+ j1 = sign ^ (~(offset >> 23) & 1);
+ j2 = sign ^ (~(offset >> 22) & 1);
+ *(u16 *)loc = (u16)((upper & 0xf800) | (sign << 10) |
+ ((offset >> 12) & 0x03ff));
+ *(u16 *)(loc + 2) = (u16)((lower & 0xd000) |
+ (j1 << 13) | (j2 << 11) |
+ ((offset >> 1) & 0x07ff));
+ break;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ upper = *(u16 *)loc;
+ lower = *(u16 *)(loc + 2);
+
+ /*
+ * MOVT/MOVW instructions encoding in Thumb-2:
+ *
+ * i = upper[10]
+ * imm4 = upper[3:0]
+ * imm3 = lower[14:12]
+ * imm8 = lower[7:0]
+ *
+ * imm16 = imm4:i:imm3:imm8
+ */
+ offset = ((upper & 0x000f) << 12) |
+ ((upper & 0x0400) << 1) |
+ ((lower & 0x7000) >> 4) | (lower & 0x00ff);
+ offset = (offset ^ 0x8000) - 0x8000;
+ offset += sym->st_value;
+
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
+ offset >>= 16;
+
+ *(u16 *)loc = (u16)((upper & 0xfbf0) |
+ ((offset & 0xf000) >> 12) |
+ ((offset & 0x0800) >> 1));
+ *(u16 *)(loc + 2) = (u16)((lower & 0x8f00) |
+ ((offset & 0x0700) << 4) |
+ (offset & 0x00ff));
+ break;
+#endif
+
+ default:
+ printk(KERN_ERR "%s: unknown relocation: %u\n",
+ module->name, ELF32_R_TYPE(rel->r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int
+apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *module)
+{
+ printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
+ module->name);
+ return -ENOEXEC;
+}
+
+struct mod_unwind_map {
+ const Elf_Shdr *unw_sec;
+ const Elf_Shdr *txt_sec;
+};
+
+static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
+ const Elf_Shdr *sechdrs, const char *name)
+{
+ const Elf_Shdr *s, *se;
+ const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++)
+ if (strcmp(name, secstrs + s->sh_name) == 0)
+ return s;
+
+ return NULL;
+}
+
+extern void fixup_pv_table(const void *, unsigned long);
+extern void fixup_smp(const void *, unsigned long);
+
+int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
+ struct module *mod)
+{
+ const Elf_Shdr *s = NULL;
+#ifdef CONFIG_ARM_UNWIND
+ const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+ const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
+ struct mod_unwind_map maps[ARM_SEC_MAX];
+ int i;
+
+ memset(maps, 0, sizeof(maps));
+
+ for (s = sechdrs; s < sechdrs_end; s++) {
+ const char *secname = secstrs + s->sh_name;
+
+ if (!(s->sh_flags & SHF_ALLOC))
+ continue;
+
+ if (strcmp(".ARM.exidx.init.text", secname) == 0)
+ maps[ARM_SEC_INIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx", secname) == 0)
+ maps[ARM_SEC_CORE].unw_sec = s;
+ else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].unw_sec = s;
+ else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].unw_sec = s;
+ else if (strcmp(".init.text", secname) == 0)
+ maps[ARM_SEC_INIT].txt_sec = s;
+ else if (strcmp(".devinit.text", secname) == 0)
+ maps[ARM_SEC_DEVINIT].txt_sec = s;
+ else if (strcmp(".text", secname) == 0)
+ maps[ARM_SEC_CORE].txt_sec = s;
+ else if (strcmp(".exit.text", secname) == 0)
+ maps[ARM_SEC_EXIT].txt_sec = s;
+ else if (strcmp(".devexit.text", secname) == 0)
+ maps[ARM_SEC_DEVEXIT].txt_sec = s;
+ }
+
+ for (i = 0; i < ARM_SEC_MAX; i++)
+ if (maps[i].unw_sec && maps[i].txt_sec)
+ mod->arch.unwind[i] =
+ unwind_table_add(maps[i].unw_sec->sh_addr,
+ maps[i].unw_sec->sh_size,
+ maps[i].txt_sec->sh_addr,
+ maps[i].txt_sec->sh_size);
+#endif
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+ s = find_mod_section(hdr, sechdrs, ".pv_table");
+ if (s)
+ fixup_pv_table((void *)s->sh_addr, s->sh_size);
+#endif
+ s = find_mod_section(hdr, sechdrs, ".alt.smp.init");
+ if (s && !is_smp())
+ fixup_smp((void *)s->sh_addr, s->sh_size);
+ return 0;
+}
+
+void
+module_arch_cleanup(struct module *mod)
+{
+#ifdef CONFIG_ARM_UNWIND
+ int i;
+
+ for (i = 0; i < ARM_SEC_MAX; i++)
+ if (mod->arch.unwind[i])
+ unwind_table_del(mod->arch.unwind[i]);
+#endif
+}
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
new file mode 100644
index 00000000..2b5b1421
--- /dev/null
+++ b/arch/arm/kernel/perf_event.c
@@ -0,0 +1,775 @@
+#undef DEBUG
+
+/*
+ * ARM performance counter support.
+ *
+ * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
+ * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
+ *
+ * This code is based on the sparc64 perf event code, which is in turn based
+ * on the x86 code. Callchain code is based on the ARM OProfile backtrace
+ * code.
+ */
+#define pr_fmt(fmt) "hw perfevents: " fmt
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/irq_regs.h>
+#include <asm/pmu.h>
+#include <asm/stacktrace.h>
+
+static struct platform_device *pmu_device;
+
+/*
+ * Hardware lock to serialize accesses to PMU registers. Needed for the
+ * read/modify/write sequences.
+ */
+static DEFINE_RAW_SPINLOCK(pmu_lock);
+
+/*
+ * ARMv6 supports a maximum of 3 events, starting from index 1. If we add
+ * another platform that supports more, we need to increase this to be the
+ * largest of all platforms.
+ *
+ * ARMv7 supports up to 32 events:
+ * cycle counter CCNT + 31 events counters CNT0..30.
+ * Cortex-A8 has 1+4 counters, Cortex-A9 has 1+6 counters.
+ */
+#define ARMPMU_MAX_HWEVENTS 33
+
+/* The events for a given CPU. */
+struct cpu_hw_events {
+ /*
+ * The events that are active on the CPU for the given index. Index 0
+ * is reserved.
+ */
+ struct perf_event *events[ARMPMU_MAX_HWEVENTS];
+
+ /*
+ * A 1 bit for an index indicates that the counter is being used for
+ * an event. A 0 means that the counter can be used.
+ */
+ unsigned long used_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+
+ /*
+ * A 1 bit for an index indicates that the counter is actively being
+ * used.
+ */
+ unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
+};
+static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+struct arm_pmu {
+ enum arm_perf_pmu_ids id;
+ const char *name;
+ irqreturn_t (*handle_irq)(int irq_num, void *dev);
+ void (*enable)(struct hw_perf_event *evt, int idx);
+ void (*disable)(struct hw_perf_event *evt, int idx);
+ int (*get_event_idx)(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *hwc);
+ u32 (*read_counter)(int idx);
+ void (*write_counter)(int idx, u32 val);
+ void (*start)(void);
+ void (*stop)(void);
+ void (*reset)(void *);
+ const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX];
+ const unsigned (*event_map)[PERF_COUNT_HW_MAX];
+ u32 raw_event_mask;
+ int num_events;
+ u64 max_period;
+};
+
+/* Set at runtime when we know what CPU type we are. */
+static const struct arm_pmu *armpmu;
+
+enum arm_perf_pmu_ids
+armpmu_get_pmu_id(void)
+{
+ int id = -ENODEV;
+
+ if (armpmu != NULL)
+ id = armpmu->id;
+
+ return id;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_pmu_id);
+
+int
+armpmu_get_max_events(void)
+{
+ int max_events = 0;
+
+ if (armpmu != NULL)
+ max_events = armpmu->num_events;
+
+ return max_events;
+}
+EXPORT_SYMBOL_GPL(armpmu_get_max_events);
+
+int perf_num_counters(void)
+{
+ return armpmu_get_max_events();
+}
+EXPORT_SYMBOL_GPL(perf_num_counters);
+
+#define HW_OP_UNSUPPORTED 0xFFFF
+
+#define C(_x) \
+ PERF_COUNT_HW_CACHE_##_x
+
+#define CACHE_OP_UNSUPPORTED 0xFFFF
+
+static int
+armpmu_map_cache_event(u64 config)
+{
+ unsigned int cache_type, cache_op, cache_result, ret;
+
+ cache_type = (config >> 0) & 0xff;
+ if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
+ return -EINVAL;
+
+ cache_op = (config >> 8) & 0xff;
+ if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
+ return -EINVAL;
+
+ cache_result = (config >> 16) & 0xff;
+ if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
+ return -EINVAL;
+
+ ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result];
+
+ if (ret == CACHE_OP_UNSUPPORTED)
+ return -ENOENT;
+
+ return ret;
+}
+
+static int
+armpmu_map_event(u64 config)
+{
+ int mapping = (*armpmu->event_map)[config];
+ return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping;
+}
+
+static int
+armpmu_map_raw_event(u64 config)
+{
+ return (int)(config & armpmu->raw_event_mask);
+}
+
+static int
+armpmu_event_set_period(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx)
+{
+ s64 left = local64_read(&hwc->period_left);
+ s64 period = hwc->sample_period;
+ int ret = 0;
+
+ if (unlikely(left <= -period)) {
+ left = period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (unlikely(left <= 0)) {
+ left += period;
+ local64_set(&hwc->period_left, left);
+ hwc->last_period = period;
+ ret = 1;
+ }
+
+ if (left > (s64)armpmu->max_period)
+ left = armpmu->max_period;
+
+ local64_set(&hwc->prev_count, (u64)-left);
+
+ armpmu->write_counter(idx, (u64)(-left) & 0xffffffff);
+
+ perf_event_update_userpage(event);
+
+ return ret;
+}
+
+static u64
+armpmu_event_update(struct perf_event *event,
+ struct hw_perf_event *hwc,
+ int idx, int overflow)
+{
+ u64 delta, prev_raw_count, new_raw_count;
+
+again:
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = armpmu->read_counter(idx);
+
+ if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+ new_raw_count) != prev_raw_count)
+ goto again;
+
+ new_raw_count &= armpmu->max_period;
+ prev_raw_count &= armpmu->max_period;
+
+ if (overflow)
+ delta = armpmu->max_period - prev_raw_count + new_raw_count + 1;
+ else
+ delta = new_raw_count - prev_raw_count;
+
+ local64_add(delta, &event->count);
+ local64_sub(delta, &hwc->period_left);
+
+ return new_raw_count;
+}
+
+static void
+armpmu_read(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ /* Don't read disabled counters! */
+ if (hwc->idx < 0)
+ return;
+
+ armpmu_event_update(event, hwc, hwc->idx, 0);
+}
+
+static void
+armpmu_stop(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!armpmu)
+ return;
+
+ /*
+ * ARM pmu always has to update the counter, so ignore
+ * PERF_EF_UPDATE, see comments in armpmu_start().
+ */
+ if (!(hwc->state & PERF_HES_STOPPED)) {
+ armpmu->disable(hwc, hwc->idx);
+ barrier(); /* why? */
+ armpmu_event_update(event, hwc, hwc->idx, 0);
+ hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ }
+}
+
+static void
+armpmu_start(struct perf_event *event, int flags)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!armpmu)
+ return;
+
+ /*
+ * ARM pmu always has to reprogram the period, so ignore
+ * PERF_EF_RELOAD, see the comment below.
+ */
+ if (flags & PERF_EF_RELOAD)
+ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+
+ hwc->state = 0;
+ /*
+ * Set the period again. Some counters can't be stopped, so when we
+ * were stopped we simply disabled the IRQ source and the counter
+ * may have been left counting. If we don't do this step then we may
+ * get an interrupt too soon or *way* too late if the overflow has
+ * happened since disabling.
+ */
+ armpmu_event_set_period(event, hwc, hwc->idx);
+ armpmu->enable(hwc, hwc->idx);
+}
+
+static void
+armpmu_del(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx = hwc->idx;
+
+ WARN_ON(idx < 0);
+
+ clear_bit(idx, cpuc->active_mask);
+ armpmu_stop(event, PERF_EF_UPDATE);
+ cpuc->events[idx] = NULL;
+ clear_bit(idx, cpuc->used_mask);
+
+ perf_event_update_userpage(event);
+}
+
+static int
+armpmu_add(struct perf_event *event, int flags)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+ struct hw_perf_event *hwc = &event->hw;
+ int idx;
+ int err = 0;
+
+ perf_pmu_disable(event->pmu);
+
+ /* If we don't have a space for the counter then finish early. */
+ idx = armpmu->get_event_idx(cpuc, hwc);
+ if (idx < 0) {
+ err = idx;
+ goto out;
+ }
+
+ /*
+ * If there is an event in the counter we are going to use then make
+ * sure it is disabled.
+ */
+ event->hw.idx = idx;
+ armpmu->disable(hwc, idx);
+ cpuc->events[idx] = event;
+ set_bit(idx, cpuc->active_mask);
+
+ hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+ if (flags & PERF_EF_START)
+ armpmu_start(event, PERF_EF_RELOAD);
+
+ /* Propagate our changes to the userspace mapping. */
+ perf_event_update_userpage(event);
+
+out:
+ perf_pmu_enable(event->pmu);
+ return err;
+}
+
+static struct pmu pmu;
+
+static int
+validate_event(struct cpu_hw_events *cpuc,
+ struct perf_event *event)
+{
+ struct hw_perf_event fake_event = event->hw;
+
+ if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
+ return 1;
+
+ return armpmu->get_event_idx(cpuc, &fake_event) >= 0;
+}
+
+static int
+validate_group(struct perf_event *event)
+{
+ struct perf_event *sibling, *leader = event->group_leader;
+ struct cpu_hw_events fake_pmu;
+
+ memset(&fake_pmu, 0, sizeof(fake_pmu));
+
+ if (!validate_event(&fake_pmu, leader))
+ return -ENOSPC;
+
+ list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
+ if (!validate_event(&fake_pmu, sibling))
+ return -ENOSPC;
+ }
+
+ if (!validate_event(&fake_pmu, event))
+ return -ENOSPC;
+
+ return 0;
+}
+
+static irqreturn_t armpmu_platform_irq(int irq, void *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev);
+
+ return plat->handle_irq(irq, dev, armpmu->handle_irq);
+}
+
+static int
+armpmu_reserve_hardware(void)
+{
+ struct arm_pmu_platdata *plat;
+ irq_handler_t handle_irq;
+ int i, err = -ENODEV, irq;
+
+ pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU);
+ if (IS_ERR(pmu_device)) {
+ pr_warning("unable to reserve pmu\n");
+ return PTR_ERR(pmu_device);
+ }
+
+ init_pmu(ARM_PMU_DEVICE_CPU);
+
+ plat = dev_get_platdata(&pmu_device->dev);
+ if (plat && plat->handle_irq)
+ handle_irq = armpmu_platform_irq;
+ else
+ handle_irq = armpmu->handle_irq;
+
+ if (pmu_device->num_resources < 1) {
+ pr_err("no irqs for PMUs defined\n");
+ return -ENODEV;
+ }
+
+ for (i = 0; i < pmu_device->num_resources; ++i) {
+ irq = platform_get_irq(pmu_device, i);
+ if (irq < 0)
+ continue;
+
+ err = request_irq(irq, handle_irq,
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "armpmu", NULL);
+ if (err) {
+ pr_warning("unable to request IRQ%d for ARM perf "
+ "counters\n", irq);
+ break;
+ }
+ }
+
+ if (err) {
+ for (i = i - 1; i >= 0; --i) {
+ irq = platform_get_irq(pmu_device, i);
+ if (irq >= 0)
+ free_irq(irq, NULL);
+ }
+ release_pmu(pmu_device);
+ pmu_device = NULL;
+ }
+
+ return err;
+}
+
+static void
+armpmu_release_hardware(void)
+{
+ int i, irq;
+
+ for (i = pmu_device->num_resources - 1; i >= 0; --i) {
+ irq = platform_get_irq(pmu_device, i);
+ if (irq >= 0)
+ free_irq(irq, NULL);
+ }
+ armpmu->stop();
+
+ release_pmu(pmu_device);
+ pmu_device = NULL;
+}
+
+static atomic_t active_events = ATOMIC_INIT(0);
+static DEFINE_MUTEX(pmu_reserve_mutex);
+
+static void
+hw_perf_event_destroy(struct perf_event *event)
+{
+ if (atomic_dec_and_mutex_lock(&active_events, &pmu_reserve_mutex)) {
+ armpmu_release_hardware();
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+}
+
+static int
+__hw_perf_event_init(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ int mapping, err;
+
+ /* Decode the generic type into an ARM event identifier. */
+ if (PERF_TYPE_HARDWARE == event->attr.type) {
+ mapping = armpmu_map_event(event->attr.config);
+ } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
+ mapping = armpmu_map_cache_event(event->attr.config);
+ } else if (PERF_TYPE_RAW == event->attr.type) {
+ mapping = armpmu_map_raw_event(event->attr.config);
+ } else {
+ pr_debug("event type %x not supported\n", event->attr.type);
+ return -EOPNOTSUPP;
+ }
+
+ if (mapping < 0) {
+ pr_debug("event %x:%llx not supported\n", event->attr.type,
+ event->attr.config);
+ return mapping;
+ }
+
+ /*
+ * Check whether we need to exclude the counter from certain modes.
+ * The ARM performance counters are on all of the time so if someone
+ * has asked us for some excludes then we have to fail.
+ */
+ if (event->attr.exclude_kernel || event->attr.exclude_user ||
+ event->attr.exclude_hv || event->attr.exclude_idle) {
+ pr_debug("ARM performance counters do not support "
+ "mode exclusion\n");
+ return -EPERM;
+ }
+
+ /*
+ * We don't assign an index until we actually place the event onto
+ * hardware. Use -1 to signify that we haven't decided where to put it
+ * yet. For SMP systems, each core has it's own PMU so we can't do any
+ * clever allocation or constraints checking at this point.
+ */
+ hwc->idx = -1;
+
+ /*
+ * Store the event encoding into the config_base field. config and
+ * event_base are unused as the only 2 things we need to know are
+ * the event mapping and the counter to use. The counter to use is
+ * also the indx and the config_base is the event type.
+ */
+ hwc->config_base = (unsigned long)mapping;
+ hwc->config = 0;
+ hwc->event_base = 0;
+
+ if (!hwc->sample_period) {
+ hwc->sample_period = armpmu->max_period;
+ hwc->last_period = hwc->sample_period;
+ local64_set(&hwc->period_left, hwc->sample_period);
+ }
+
+ err = 0;
+ if (event->group_leader != event) {
+ err = validate_group(event);
+ if (err)
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int armpmu_event_init(struct perf_event *event)
+{
+ int err = 0;
+
+ switch (event->attr.type) {
+ case PERF_TYPE_RAW:
+ case PERF_TYPE_HARDWARE:
+ case PERF_TYPE_HW_CACHE:
+ break;
+
+ default:
+ return -ENOENT;
+ }
+
+ if (!armpmu)
+ return -ENODEV;
+
+ event->destroy = hw_perf_event_destroy;
+
+ if (!atomic_inc_not_zero(&active_events)) {
+ mutex_lock(&pmu_reserve_mutex);
+ if (atomic_read(&active_events) == 0) {
+ err = armpmu_reserve_hardware();
+ }
+
+ if (!err)
+ atomic_inc(&active_events);
+ mutex_unlock(&pmu_reserve_mutex);
+ }
+
+ if (err)
+ return err;
+
+ err = __hw_perf_event_init(event);
+ if (err)
+ hw_perf_event_destroy(event);
+
+ return err;
+}
+
+static void armpmu_enable(struct pmu *pmu)
+{
+ /* Enable all of the perf events on hardware. */
+ int idx, enabled = 0;
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ if (!armpmu)
+ return;
+
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+
+ if (!event)
+ continue;
+
+ armpmu->enable(&event->hw, idx);
+ enabled = 1;
+ }
+
+ if (enabled)
+ armpmu->start();
+}
+
+static void armpmu_disable(struct pmu *pmu)
+{
+ if (armpmu)
+ armpmu->stop();
+}
+
+static struct pmu pmu = {
+ .pmu_enable = armpmu_enable,
+ .pmu_disable = armpmu_disable,
+ .event_init = armpmu_event_init,
+ .add = armpmu_add,
+ .del = armpmu_del,
+ .start = armpmu_start,
+ .stop = armpmu_stop,
+ .read = armpmu_read,
+};
+
+/* Include the PMU-specific implementations. */
+#include "perf_event_xscale.c"
+#include "perf_event_v6.c"
+#include "perf_event_v7.c"
+
+/*
+ * Ensure the PMU has sane values out of reset.
+ * This requires SMP to be available, so exists as a separate initcall.
+ */
+static int __init
+armpmu_reset(void)
+{
+ if (armpmu && armpmu->reset)
+ return on_each_cpu(armpmu->reset, NULL, 1);
+ return 0;
+}
+arch_initcall(armpmu_reset);
+
+static int __init
+init_hw_perf_events(void)
+{
+ unsigned long cpuid = read_cpuid_id();
+ unsigned long implementor = (cpuid & 0xFF000000) >> 24;
+ unsigned long part_number = (cpuid & 0xFFF0);
+
+ /* ARM Ltd CPUs. */
+ if (0x41 == implementor) {
+ switch (part_number) {
+ case 0xB360: /* ARM1136 */
+ case 0xB560: /* ARM1156 */
+ case 0xB760: /* ARM1176 */
+ armpmu = armv6pmu_init();
+ break;
+ case 0xB020: /* ARM11mpcore */
+ armpmu = armv6mpcore_pmu_init();
+ break;
+ case 0xC080: /* Cortex-A8 */
+ armpmu = armv7_a8_pmu_init();
+ break;
+ case 0xC090: /* Cortex-A9 */
+ armpmu = armv7_a9_pmu_init();
+ break;
+ }
+ /* Intel CPUs [xscale]. */
+ } else if (0x69 == implementor) {
+ part_number = (cpuid >> 13) & 0x7;
+ switch (part_number) {
+ case 1:
+ armpmu = xscale1pmu_init();
+ break;
+ case 2:
+ armpmu = xscale2pmu_init();
+ break;
+ }
+ }
+
+ if (armpmu) {
+ pr_info("enabled with %s PMU driver, %d counters available\n",
+ armpmu->name, armpmu->num_events);
+ } else {
+ pr_info("no hardware support available\n");
+ }
+
+ perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+
+ return 0;
+}
+early_initcall(init_hw_perf_events);
+
+/*
+ * Callchain handling code.
+ */
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ *
+ * This code has been adapted from the ARM OProfile support.
+ */
+struct frame_tail {
+ struct frame_tail __user *fp;
+ unsigned long sp;
+ unsigned long lr;
+} __attribute__((packed));
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static struct frame_tail __user *
+user_backtrace(struct frame_tail __user *tail,
+ struct perf_callchain_entry *entry)
+{
+ struct frame_tail buftail;
+
+ /* Also check accessibility of one struct frame_tail beyond */
+ if (!access_ok(VERIFY_READ, tail, sizeof(buftail)))
+ return NULL;
+ if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
+ return NULL;
+
+ perf_callchain_store(entry, buftail.lr);
+
+ /*
+ * Frame pointers should strictly progress back up the stack
+ * (towards higher addresses).
+ */
+ if (tail + 1 >= buftail.fp)
+ return NULL;
+
+ return buftail.fp - 1;
+}
+
+void
+perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+ struct frame_tail __user *tail;
+
+
+ tail = (struct frame_tail __user *)regs->ARM_fp - 1;
+
+ while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+ tail && !((unsigned long)tail & 0x3))
+ tail = user_backtrace(tail, entry);
+}
+
+/*
+ * Gets called by walk_stackframe() for every stackframe. This will be called
+ * whist unwinding the stackframe and is like a subroutine return so we use
+ * the PC.
+ */
+static int
+callchain_trace(struct stackframe *fr,
+ void *data)
+{
+ struct perf_callchain_entry *entry = data;
+ perf_callchain_store(entry, fr->pc);
+ return 0;
+}
+
+void
+perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
+{
+ struct stackframe fr;
+
+ fr.fp = regs->ARM_fp;
+ fr.sp = regs->ARM_sp;
+ fr.lr = regs->ARM_lr;
+ fr.pc = regs->ARM_pc;
+ walk_stackframe(&fr, callchain_trace, entry);
+}
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
new file mode 100644
index 00000000..f1e8dd94
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -0,0 +1,672 @@
+/*
+ * ARMv6 Performance counter handling code.
+ *
+ * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
+ *
+ * ARMv6 has 2 configurable performance counters and a single cycle counter.
+ * They all share a single reset bit but can be written to zero so we can use
+ * that for a reset.
+ *
+ * The counters can't be individually enabled or disabled so when we remove
+ * one event and replace it with another we could get spurious counts from the
+ * wrong event. However, we can take advantage of the fact that the
+ * performance counters can export events to the event bus, and the event bus
+ * itself can be monitored. This requires that we *don't* export the events to
+ * the event bus. The procedure for disabling a configurable counter is:
+ * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
+ * effectively stops the counter from counting.
+ * - disable the counter's interrupt generation (each counter has it's
+ * own interrupt enable bit).
+ * Once stopped, the counter value can be written as 0 to reset.
+ *
+ * To enable a counter:
+ * - enable the counter's interrupt generation.
+ * - set the new event type.
+ *
+ * Note: the dedicated cycle counter only counts cycles and can't be
+ * enabled/disabled independently of the others. When we want to disable the
+ * cycle counter, we have to just disable the interrupt reporting and start
+ * ignoring that counter. When re-enabling, we have to reset the value and
+ * enable the interrupt.
+ */
+
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+enum armv6_perf_types {
+ ARMV6_PERFCTR_ICACHE_MISS = 0x0,
+ ARMV6_PERFCTR_IBUF_STALL = 0x1,
+ ARMV6_PERFCTR_DDEP_STALL = 0x2,
+ ARMV6_PERFCTR_ITLB_MISS = 0x3,
+ ARMV6_PERFCTR_DTLB_MISS = 0x4,
+ ARMV6_PERFCTR_BR_EXEC = 0x5,
+ ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
+ ARMV6_PERFCTR_INSTR_EXEC = 0x7,
+ ARMV6_PERFCTR_DCACHE_HIT = 0x9,
+ ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
+ ARMV6_PERFCTR_DCACHE_MISS = 0xB,
+ ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
+ ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
+ ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
+ ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
+ ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
+ ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
+ ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
+ ARMV6_PERFCTR_NOP = 0x20,
+};
+
+enum armv6_counters {
+ ARMV6_CYCLE_COUNTER = 1,
+ ARMV6_COUNTER0,
+ ARMV6_COUNTER1,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [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)] = {
+ /*
+ * The ARM performance counters can count micro DTLB misses,
+ * micro ITLB misses and main TLB misses. There isn't an event
+ * for TLB misses, so use the micro misses here and if users
+ * want the main TLB misses they can use a raw counter.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
+ },
+ [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)] = ARMV6_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6_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)] = 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,
+ },
+ },
+};
+
+enum armv6mpcore_perf_types {
+ ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
+ ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
+ ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
+ ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
+ ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
+ ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
+ ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
+ ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
+ ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
+ ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
+ ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
+ ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
+ ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
+ ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
+ ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
+ ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
+ ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
+ ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
+ ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
+ ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
+};
+
+/*
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
+ [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv6mpcore_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)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
+ [C(RESULT_MISS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
+ [C(RESULT_MISS)] =
+ ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [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)] = {
+ /*
+ * The ARM performance counters can count micro DTLB misses,
+ * micro ITLB misses and main TLB misses. There isn't an event
+ * for TLB misses, so use the micro misses here and if users
+ * want the main TLB misses they can use a raw counter.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
+ },
+ [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)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV6MPCORE_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)] = 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,
+ },
+ },
+};
+
+static inline unsigned long
+armv6_pmcr_read(void)
+{
+ u32 val;
+ asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
+ return val;
+}
+
+static inline void
+armv6_pmcr_write(unsigned long val)
+{
+ asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
+}
+
+#define ARMV6_PMCR_ENABLE (1 << 0)
+#define ARMV6_PMCR_CTR01_RESET (1 << 1)
+#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
+#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
+#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
+#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
+#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
+#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
+#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
+#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
+#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
+#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
+#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
+#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
+
+#define ARMV6_PMCR_OVERFLOWED_MASK \
+ (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
+ ARMV6_PMCR_CCOUNT_OVERFLOW)
+
+static inline int
+armv6_pmcr_has_overflowed(unsigned long pmcr)
+{
+ return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
+}
+
+static inline int
+armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
+ enum armv6_counters counter)
+{
+ int ret = 0;
+
+ if (ARMV6_CYCLE_COUNTER == counter)
+ ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
+ else if (ARMV6_COUNTER0 == counter)
+ ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
+ else if (ARMV6_COUNTER1 == counter)
+ ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+ return ret;
+}
+
+static inline u32
+armv6pmu_read_counter(int counter)
+{
+ unsigned long value = 0;
+
+ if (ARMV6_CYCLE_COUNTER == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
+ else if (ARMV6_COUNTER0 == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
+ else if (ARMV6_COUNTER1 == counter)
+ asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+
+ return value;
+}
+
+static inline void
+armv6pmu_write_counter(int counter,
+ u32 value)
+{
+ if (ARMV6_CYCLE_COUNTER == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
+ else if (ARMV6_COUNTER0 == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
+ else if (ARMV6_COUNTER1 == counter)
+ asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
+ else
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+}
+
+static void
+armv6pmu_enable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = 0;
+ evt = ARMV6_PMCR_CCOUNT_IEN;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_EVT_COUNT0_MASK;
+ evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
+ ARMV6_PMCR_COUNT0_IEN;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_EVT_COUNT1_MASK;
+ evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
+ ARMV6_PMCR_COUNT1_IEN;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Mask out the current event and set the counter to count the event
+ * that we're interested in.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t
+armv6pmu_handle_irq(int irq_num,
+ void *dev)
+{
+ unsigned long pmcr = armv6_pmcr_read();
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ if (!armv6_pmcr_has_overflowed(pmcr))
+ return IRQ_NONE;
+
+ regs = get_irq_regs();
+
+ /*
+ * The interrupts are cleared by writing the overflow flags back to
+ * the control register. All of the other bits don't have any effect
+ * if they are rewritten, so write the whole value back.
+ */
+ armv6_pmcr_write(pmcr);
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ /*
+ * We have a single interrupt for all counters. Check that
+ * each counter has overflowed before we process it.
+ */
+ if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx, 1);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ /*
+ * Handle the pending perf events.
+ *
+ * Note: this call *must* be run with interrupts disabled. For
+ * platforms that can have the PMU interrupts raised as an NMI, this
+ * will not work.
+ */
+ irq_work_run();
+
+ return IRQ_HANDLED;
+}
+
+static void
+armv6pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val |= ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~ARMV6_PMCR_ENABLE;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ /* Always place a cycle counter into the cycle counter. */
+ if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
+ if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return ARMV6_CYCLE_COUNTER;
+ } else {
+ /*
+ * For anything other than a cycle counter, try and use
+ * counter0 and counter1.
+ */
+ if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
+ return ARMV6_COUNTER1;
+
+ if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
+ return ARMV6_COUNTER0;
+
+ /* The counters are all in use. */
+ return -EAGAIN;
+ }
+}
+
+static void
+armv6pmu_disable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = ARMV6_PMCR_CCOUNT_IEN;
+ evt = 0;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
+ evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
+ evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Mask out the current event and set the counter to count the number
+ * of ETM bus signal assertion cycles. The external reporting should
+ * be disabled and so this should never increment.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
+ int idx)
+{
+ unsigned long val, mask, flags, evt = 0;
+
+ if (ARMV6_CYCLE_COUNTER == idx) {
+ mask = ARMV6_PMCR_CCOUNT_IEN;
+ } else if (ARMV6_COUNTER0 == idx) {
+ mask = ARMV6_PMCR_COUNT0_IEN;
+ } else if (ARMV6_COUNTER1 == idx) {
+ mask = ARMV6_PMCR_COUNT1_IEN;
+ } else {
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ /*
+ * Unlike UP ARMv6, we don't have a way of stopping the counters. We
+ * simply disable the interrupt reporting.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = armv6_pmcr_read();
+ val &= ~mask;
+ val |= evt;
+ armv6_pmcr_write(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static const struct arm_pmu armv6pmu = {
+ .id = ARM_PERF_PMU_ID_V6,
+ .name = "v6",
+ .handle_irq = armv6pmu_handle_irq,
+ .enable = armv6pmu_enable_event,
+ .disable = armv6pmu_disable_event,
+ .read_counter = armv6pmu_read_counter,
+ .write_counter = armv6pmu_write_counter,
+ .get_event_idx = armv6pmu_get_event_idx,
+ .start = armv6pmu_start,
+ .stop = armv6pmu_stop,
+ .cache_map = &armv6_perf_cache_map,
+ .event_map = &armv6_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init armv6pmu_init(void)
+{
+ return &armv6pmu;
+}
+
+/*
+ * ARMv6mpcore is almost identical to single core ARMv6 with the exception
+ * that some of the events have different enumerations and that there is no
+ * *hack* to stop the programmable counters. To stop the counters we simply
+ * disable the interrupt reporting and update the event. When unthrottling we
+ * reset the period and enable the interrupt reporting.
+ */
+static const struct arm_pmu armv6mpcore_pmu = {
+ .id = ARM_PERF_PMU_ID_V6MP,
+ .name = "v6mpcore",
+ .handle_irq = armv6pmu_handle_irq,
+ .enable = armv6pmu_enable_event,
+ .disable = armv6mpcore_pmu_disable_event,
+ .read_counter = armv6pmu_read_counter,
+ .write_counter = armv6pmu_write_counter,
+ .get_event_idx = armv6pmu_get_event_idx,
+ .start = armv6pmu_start,
+ .stop = armv6pmu_stop,
+ .cache_map = &armv6mpcore_perf_cache_map,
+ .event_map = &armv6mpcore_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
+{
+ return &armv6mpcore_pmu;
+}
+#else
+static const struct arm_pmu *__init armv6pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
new file mode 100644
index 00000000..43727630
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -0,0 +1,918 @@
+/*
+ * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
+ *
+ * ARMv7 support: Jean Pihet <jpihet@mvista.com>
+ * 2010 (c) MontaVista Software, LLC.
+ *
+ * Copied from ARMv6 code, with the low level code inspired
+ * by the ARMv7 Oprofile code.
+ *
+ * Cortex-A8 has up to 4 configurable performance counters and
+ * a single cycle counter.
+ * Cortex-A9 has up to 31 configurable performance counters and
+ * a single cycle counter.
+ *
+ * All counters can be enabled/disabled and IRQ masked separately. The cycle
+ * counter and all 4 performance counters together can be reset separately.
+ */
+
+#ifdef CONFIG_CPU_V7
+/* Common ARMv7 event types */
+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_DTLB_REFILL = 0x05,
+ ARMV7_PERFCTR_DREAD = 0x06,
+ ARMV7_PERFCTR_DWRITE = 0x07,
+
+ ARMV7_PERFCTR_EXC_TAKEN = 0x09,
+ ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
+ ARMV7_PERFCTR_CID_WRITE = 0x0B,
+ /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
+ * It counts:
+ * - all branch instructions,
+ * - instructions that explicitly write the PC,
+ * - exception generating instructions.
+ */
+ ARMV7_PERFCTR_PC_WRITE = 0x0C,
+ ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
+ ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
+ ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
+ ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
+
+ ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
+
+ 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,
+ ARMV7_PERFCTR_L2_ACCESS = 0x43,
+ ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
+ ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
+ ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
+ ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
+ ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
+ ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
+ ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
+ ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
+ ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
+ ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
+ ARMV7_PERFCTR_L2_NEON = 0x4E,
+ ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
+ ARMV7_PERFCTR_L1_INST = 0x50,
+ ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
+ ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
+ ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
+ ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
+ ARMV7_PERFCTR_OP_EXECUTED = 0x55,
+ ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
+ ARMV7_PERFCTR_CYCLES_INST = 0x57,
+ ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
+ ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
+ ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
+
+ ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
+ ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
+ ARMV7_PERFCTR_PMU_EVENTS = 0x72,
+};
+
+/* ARMv7 Cortex-A9 specific event types */
+enum armv7_a9_perf_types {
+ ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
+ ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
+ ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
+
+ ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
+ ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
+
+ ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
+ ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
+ ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
+ ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
+ ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
+ ARMV7_PERFCTR_DATA_EVICTION = 0x65,
+ ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
+ ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
+ ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
+
+ ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
+
+ ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
+ ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
+ ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
+ ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
+ ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
+
+ ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
+ ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
+ ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
+ ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
+ ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
+ ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
+ ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
+
+ ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
+ ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
+
+ ARMV7_PERFCTR_ISB_INST = 0x90,
+ ARMV7_PERFCTR_DSB_INST = 0x91,
+ ARMV7_PERFCTR_DMB_INST = 0x92,
+ ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
+
+ ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
+ ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
+ ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
+ ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
+ ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
+ ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
+};
+
+/*
+ * Cortex-A8 HW events mapping
+ *
+ * The hardware events that we support. We do support cache operations but
+ * we have harvard caches and no way to combine instruction and data
+ * accesses/misses in hardware.
+ */
+static const unsigned armv7_a8_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] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 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)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_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_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [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,
+ },
+ [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_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [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-A9 HW events mapping
+ */
+static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
+ [PERF_COUNT_HW_INSTRUCTIONS] =
+ ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL,
+ [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] = ARMV7_PERFCTR_CLOCK_CYCLES,
+};
+
+static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+ [C(L1D)] = {
+ /*
+ * The performance counters don't differentiate between read
+ * and write accesses/misses so this isn't strictly correct,
+ * but it's the best we can do. Writes and reads get
+ * combined.
+ */
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = 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)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [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)] = 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)] = {
+ /*
+ * 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,
+ },
+ [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_WRITE,
+ [C(RESULT_MISS)]
+ = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
+ [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 {
+ ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
+ ARMV7_COUNTER0 = 2, /* First event counter */
+};
+
+/*
+ * The cycle counter is ARMV7_CYCLE_COUNTER.
+ * The first event counter is ARMV7_COUNTER0.
+ * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
+ */
+#define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
+
+/*
+ * ARMv7 low level PMNC access
+ */
+
+/*
+ * Per-CPU PMNC: config reg
+ */
+#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
+#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
+#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
+#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
+#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
+#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
+#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
+#define ARMV7_PMNC_N_MASK 0x1f
+#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
+
+/*
+ * Available counters
+ */
+#define ARMV7_CNT0 0 /* First event counter */
+#define ARMV7_CCNT 31 /* Cycle counter */
+
+/* Perf Event to low level counters mapping */
+#define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
+
+/*
+ * CNTENS: counters enable reg
+ */
+#define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
+
+/*
+ * CNTENC: counters disable reg
+ */
+#define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
+
+/*
+ * INTENS: counters overflow interrupt enable reg
+ */
+#define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENS_C (1 << ARMV7_CCNT)
+
+/*
+ * INTENC: counters overflow interrupt disable reg
+ */
+#define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_INTENC_C (1 << ARMV7_CCNT)
+
+/*
+ * EVTSEL: Event selection reg
+ */
+#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
+
+/*
+ * SELECT: Counter selection reg
+ */
+#define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
+
+/*
+ * FLAG: counters overflow flag status reg
+ */
+#define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
+#define ARMV7_FLAG_C (1 << ARMV7_CCNT)
+#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
+#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
+
+static inline unsigned long armv7_pmnc_read(void)
+{
+ u32 val;
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
+ return val;
+}
+
+static inline void armv7_pmnc_write(unsigned long val)
+{
+ val &= ARMV7_PMNC_MASK;
+ isb();
+ asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
+}
+
+static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
+{
+ return pmnc & ARMV7_OVERFLOWED_MASK;
+}
+
+static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
+ enum armv7_counters counter)
+{
+ int ret = 0;
+
+ if (counter == ARMV7_CYCLE_COUNTER)
+ ret = pmnc & ARMV7_FLAG_C;
+ else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
+ ret = pmnc & ARMV7_FLAG_P(counter);
+ else
+ pr_err("CPU%u checking wrong counter %d overflow status\n",
+ smp_processor_id(), counter);
+
+ return ret;
+}
+
+static inline int armv7_pmnc_select_counter(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
+ pr_err("CPU%u selecting wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+ isb();
+
+ return idx;
+}
+
+static inline u32 armv7pmu_read_counter(int idx)
+{
+ unsigned long value = 0;
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
+ else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+ if (armv7_pmnc_select_counter(idx) == idx)
+ asm volatile("mrc p15, 0, %0, c9, c13, 2"
+ : "=r" (value));
+ } else
+ pr_err("CPU%u reading wrong counter %d\n",
+ smp_processor_id(), idx);
+
+ return value;
+}
+
+static inline void armv7pmu_write_counter(int idx, u32 value)
+{
+ if (idx == ARMV7_CYCLE_COUNTER)
+ asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
+ else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
+ if (armv7_pmnc_select_counter(idx) == idx)
+ asm volatile("mcr p15, 0, %0, c9, c13, 2"
+ : : "r" (value));
+ } else
+ pr_err("CPU%u writing wrong counter %d\n",
+ smp_processor_id(), idx);
+}
+
+static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
+{
+ if (armv7_pmnc_select_counter(idx) == idx) {
+ val &= ARMV7_EVTSEL_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
+ }
+}
+
+static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u enabling wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_CNTENS_C;
+ else
+ val = ARMV7_CNTENS_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
+{
+ u32 val;
+
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u disabling wrong PMNC counter"
+ " %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_CNTENC_C;
+ else
+ val = ARMV7_CNTENC_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u enabling wrong PMNC counter"
+ " interrupt enable %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_INTENS_C;
+ else
+ val = ARMV7_INTENS_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
+{
+ u32 val;
+
+ if ((idx != ARMV7_CYCLE_COUNTER) &&
+ ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
+ pr_err("CPU%u disabling wrong PMNC counter"
+ " interrupt enable %d\n", smp_processor_id(), idx);
+ return -1;
+ }
+
+ if (idx == ARMV7_CYCLE_COUNTER)
+ val = ARMV7_INTENC_C;
+ else
+ val = ARMV7_INTENC_P(idx);
+
+ asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
+
+ return idx;
+}
+
+static inline u32 armv7_pmnc_getreset_flags(void)
+{
+ u32 val;
+
+ /* Read */
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+
+ /* Write to clear flags */
+ val &= ARMV7_FLAG_MASK;
+ asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
+
+ return val;
+}
+
+#ifdef DEBUG
+static void armv7_pmnc_dump_regs(void)
+{
+ u32 val;
+ unsigned int cnt;
+
+ printk(KERN_INFO "PMNC registers dump:\n");
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
+ printk(KERN_INFO "PMNC =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
+ printk(KERN_INFO "CNTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
+ printk(KERN_INFO "INTENS=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
+ printk(KERN_INFO "FLAGS =0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
+ printk(KERN_INFO "SELECT=0x%08x\n", val);
+
+ asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
+ printk(KERN_INFO "CCNT =0x%08x\n", val);
+
+ for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
+ armv7_pmnc_select_counter(cnt);
+ asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
+ printk(KERN_INFO "CNT[%d] count =0x%08x\n",
+ cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+ asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
+ printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
+ cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
+ }
+}
+#endif
+
+static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags;
+
+ /*
+ * Enable counter and interrupt, and set the counter to count
+ * the event that we're interested in.
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Set event (if destined for PMNx counters)
+ * We don't need to set the event if it's a cycle count
+ */
+ if (idx != ARMV7_CYCLE_COUNTER)
+ armv7_pmnc_write_evtsel(idx, hwc->config_base);
+
+ /*
+ * Enable interrupt for this counter
+ */
+ armv7_pmnc_enable_intens(idx);
+
+ /*
+ * Enable counter
+ */
+ armv7_pmnc_enable_counter(idx);
+
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags;
+
+ /*
+ * Disable counter and interrupt
+ */
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+
+ /*
+ * Disable counter
+ */
+ armv7_pmnc_disable_counter(idx);
+
+ /*
+ * Disable interrupt for this counter
+ */
+ armv7_pmnc_disable_intens(idx);
+
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /*
+ * Get and reset the IRQ flags
+ */
+ pmnc = armv7_pmnc_getreset_flags();
+
+ /*
+ * Did an overflow occur?
+ */
+ if (!armv7_pmnc_has_overflowed(pmnc))
+ return IRQ_NONE;
+
+ /*
+ * Handle the counter(s) overflow(s)
+ */
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ /*
+ * We have a single interrupt for all counters. Check that
+ * each counter has overflowed before we process it.
+ */
+ if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx, 1);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ /*
+ * Handle the pending perf events.
+ *
+ * Note: this call *must* be run with interrupts disabled. For
+ * platforms that can have the PMU interrupts raised as an NMI, this
+ * will not work.
+ */
+ irq_work_run();
+
+ return IRQ_HANDLED;
+}
+
+static void armv7pmu_start(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ /* Enable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void armv7pmu_stop(void)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ /* Disable all counters */
+ armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ int idx;
+
+ /* Always place a cycle counter into the cycle counter. */
+ if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
+ if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return ARMV7_CYCLE_COUNTER;
+ } else {
+ /*
+ * For anything other than a cycle counter, try and use
+ * the events counters
+ */
+ for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
+ if (!test_and_set_bit(idx, cpuc->used_mask))
+ return idx;
+ }
+
+ /* The counters are all in use. */
+ return -EAGAIN;
+ }
+}
+
+static void armv7pmu_reset(void *info)
+{
+ u32 idx, nb_cnt = armpmu->num_events;
+
+ /* The counter and interrupt enable registers are unknown at reset. */
+ for (idx = 1; idx < nb_cnt; ++idx)
+ armv7pmu_disable_event(NULL, idx);
+
+ /* Initialize & Reset PMNC: C and P bits */
+ armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+}
+
+static struct arm_pmu armv7pmu = {
+ .handle_irq = armv7pmu_handle_irq,
+ .enable = armv7pmu_enable_event,
+ .disable = armv7pmu_disable_event,
+ .read_counter = armv7pmu_read_counter,
+ .write_counter = armv7pmu_write_counter,
+ .get_event_idx = armv7pmu_get_event_idx,
+ .start = armv7pmu_start,
+ .stop = armv7pmu_stop,
+ .reset = armv7pmu_reset,
+ .raw_event_mask = 0xFF,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static u32 __init armv7_read_num_pmnc_events(void)
+{
+ u32 nb_cnt;
+
+ /* Read the nb of CNTx counters supported from PMNC */
+ nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
+
+ /* Add the CPU cycles counter and return */
+ return nb_cnt + 1;
+}
+
+static const struct arm_pmu *__init armv7_a8_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA8;
+ armv7pmu.name = "ARMv7 Cortex-A8";
+ armv7pmu.cache_map = &armv7_a8_perf_cache_map;
+ armv7pmu.event_map = &armv7_a8_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a9_pmu_init(void)
+{
+ armv7pmu.id = ARM_PERF_PMU_ID_CA9;
+ armv7pmu.name = "ARMv7 Cortex-A9";
+ armv7pmu.cache_map = &armv7_a9_perf_cache_map;
+ armv7pmu.event_map = &armv7_a9_perf_map;
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
+ return &armv7pmu;
+}
+#else
+static const struct arm_pmu *__init armv7_a8_pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a9_pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
new file mode 100644
index 00000000..39affbe4
--- /dev/null
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -0,0 +1,807 @@
+/*
+ * ARMv5 [xscale] Performance counter handling code.
+ *
+ * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com>
+ *
+ * Based on the previous xscale OProfile code.
+ *
+ * There are two variants of the xscale PMU that we support:
+ * - xscale1pmu: 2 event counters and a cycle counter
+ * - xscale2pmu: 4 event counters and a cycle counter
+ * The two variants share event definitions, but have different
+ * PMU structures.
+ */
+
+#ifdef CONFIG_CPU_XSCALE
+enum xscale_perf_types {
+ XSCALE_PERFCTR_ICACHE_MISS = 0x00,
+ XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
+ XSCALE_PERFCTR_DATA_STALL = 0x02,
+ XSCALE_PERFCTR_ITLB_MISS = 0x03,
+ XSCALE_PERFCTR_DTLB_MISS = 0x04,
+ XSCALE_PERFCTR_BRANCH = 0x05,
+ XSCALE_PERFCTR_BRANCH_MISS = 0x06,
+ XSCALE_PERFCTR_INSTRUCTION = 0x07,
+ XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
+ XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
+ XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
+ XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
+ XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
+ XSCALE_PERFCTR_PC_CHANGED = 0x0D,
+ XSCALE_PERFCTR_BCU_REQUEST = 0x10,
+ XSCALE_PERFCTR_BCU_FULL = 0x11,
+ XSCALE_PERFCTR_BCU_DRAIN = 0x12,
+ XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
+ XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
+ XSCALE_PERFCTR_RMW = 0x16,
+ /* XSCALE_PERFCTR_CCNT is not hardware defined */
+ XSCALE_PERFCTR_CCNT = 0xFE,
+ XSCALE_PERFCTR_UNUSED = 0xFF,
+};
+
+enum xscale_counters {
+ XSCALE_CYCLE_COUNTER = 1,
+ XSCALE_COUNTER0,
+ XSCALE_COUNTER1,
+ XSCALE_COUNTER2,
+ XSCALE_COUNTER3,
+};
+
+static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
+ [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
+ [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
+ [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
+ [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
+ [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned xscale_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)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [C(L1I)] = {
+ [C(OP_READ)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
+ },
+ [C(OP_PREFETCH)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
+ },
+ },
+ [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)] = XSCALE_PERFCTR_DTLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
+ },
+ [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)] = XSCALE_PERFCTR_ITLB_MISS,
+ },
+ [C(OP_WRITE)] = {
+ [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
+ [C(RESULT_MISS)] = XSCALE_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)] = 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,
+ },
+ },
+};
+
+#define XSCALE_PMU_ENABLE 0x001
+#define XSCALE_PMN_RESET 0x002
+#define XSCALE_CCNT_RESET 0x004
+#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
+#define XSCALE_PMU_CNT64 0x008
+
+#define XSCALE1_OVERFLOWED_MASK 0x700
+#define XSCALE1_CCOUNT_OVERFLOW 0x400
+#define XSCALE1_COUNT0_OVERFLOW 0x100
+#define XSCALE1_COUNT1_OVERFLOW 0x200
+#define XSCALE1_CCOUNT_INT_EN 0x040
+#define XSCALE1_COUNT0_INT_EN 0x010
+#define XSCALE1_COUNT1_INT_EN 0x020
+#define XSCALE1_COUNT0_EVT_SHFT 12
+#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
+#define XSCALE1_COUNT1_EVT_SHFT 20
+#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
+
+static inline u32
+xscale1pmu_read_pmnc(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale1pmu_write_pmnc(u32 val)
+{
+ /* upper 4bits and 7, 11 are write-as-0 */
+ val &= 0xffff77f;
+ asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static inline int
+xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
+ enum xscale_counters counter)
+{
+ int ret = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
+ break;
+ case XSCALE_COUNTER0:
+ ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
+ break;
+ case XSCALE_COUNTER1:
+ ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+ }
+
+ return ret;
+}
+
+static irqreturn_t
+xscale1pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /*
+ * NOTE: there's an A stepping erratum that states if an overflow
+ * bit already exists and another occurs, the previous
+ * Overflow bit gets cleared. There's no workaround.
+ * Fixed in B stepping or later.
+ */
+ pmnc = xscale1pmu_read_pmnc();
+
+ /*
+ * Write the value back to clear the overflow flags. Overflow
+ * flags remain in pmnc for use below. We also disable the PMU
+ * while we process the interrupt.
+ */
+ xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+ if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
+ return IRQ_NONE;
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx, 1);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ irq_work_run();
+
+ /*
+ * Re-enable the PMU.
+ */
+ pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(pmnc);
+
+ return IRQ_HANDLED;
+}
+
+static void
+xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ mask = 0;
+ evt = XSCALE1_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ mask = XSCALE1_COUNT0_EVT_MASK;
+ evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
+ XSCALE1_COUNT0_INT_EN;
+ break;
+ case XSCALE_COUNTER1:
+ mask = XSCALE1_COUNT1_EVT_MASK;
+ evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
+ XSCALE1_COUNT1_INT_EN;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long val, mask, evt, flags;
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ mask = XSCALE1_CCOUNT_INT_EN;
+ evt = 0;
+ break;
+ case XSCALE_COUNTER0:
+ mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
+ evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
+ evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~mask;
+ val |= evt;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ if (XSCALE_PERFCTR_CCNT == event->config_base) {
+ if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
+ return -EAGAIN;
+
+ return XSCALE_CYCLE_COUNTER;
+ } else {
+ if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
+ return XSCALE_COUNTER1;
+
+ if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
+ return XSCALE_COUNTER0;
+
+ return -EAGAIN;
+ }
+}
+
+static void
+xscale1pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val |= XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale1pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale1pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale1pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale1pmu_read_counter(int counter)
+{
+ u32 val = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
+ break;
+ }
+
+ return val;
+}
+
+static inline void
+xscale1pmu_write_counter(int counter, u32 val)
+{
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
+ break;
+ }
+}
+
+static const struct arm_pmu xscale1pmu = {
+ .id = ARM_PERF_PMU_ID_XSCALE1,
+ .name = "xscale1",
+ .handle_irq = xscale1pmu_handle_irq,
+ .enable = xscale1pmu_enable_event,
+ .disable = xscale1pmu_disable_event,
+ .read_counter = xscale1pmu_read_counter,
+ .write_counter = xscale1pmu_write_counter,
+ .get_event_idx = xscale1pmu_get_event_idx,
+ .start = xscale1pmu_start,
+ .stop = xscale1pmu_stop,
+ .cache_map = &xscale_perf_cache_map,
+ .event_map = &xscale_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 3,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init xscale1pmu_init(void)
+{
+ return &xscale1pmu;
+}
+
+#define XSCALE2_OVERFLOWED_MASK 0x01f
+#define XSCALE2_CCOUNT_OVERFLOW 0x001
+#define XSCALE2_COUNT0_OVERFLOW 0x002
+#define XSCALE2_COUNT1_OVERFLOW 0x004
+#define XSCALE2_COUNT2_OVERFLOW 0x008
+#define XSCALE2_COUNT3_OVERFLOW 0x010
+#define XSCALE2_CCOUNT_INT_EN 0x001
+#define XSCALE2_COUNT0_INT_EN 0x002
+#define XSCALE2_COUNT1_INT_EN 0x004
+#define XSCALE2_COUNT2_INT_EN 0x008
+#define XSCALE2_COUNT3_INT_EN 0x010
+#define XSCALE2_COUNT0_EVT_SHFT 0
+#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
+#define XSCALE2_COUNT1_EVT_SHFT 8
+#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
+#define XSCALE2_COUNT2_EVT_SHFT 16
+#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
+#define XSCALE2_COUNT3_EVT_SHFT 24
+#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
+
+static inline u32
+xscale2pmu_read_pmnc(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
+ /* bits 1-2 and 4-23 are read-unpredictable */
+ return val & 0xff000009;
+}
+
+static inline void
+xscale2pmu_write_pmnc(u32 val)
+{
+ /* bits 4-23 are write-as-0, 24-31 are write ignored */
+ val &= 0xf;
+ asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_overflow_flags(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale2pmu_write_overflow_flags(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
+}
+
+static inline u32
+xscale2pmu_read_event_select(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
+ return val;
+}
+
+static inline void
+xscale2pmu_write_event_select(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
+}
+
+static inline u32
+xscale2pmu_read_int_enable(void)
+{
+ u32 val;
+ asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
+ return val;
+}
+
+static void
+xscale2pmu_write_int_enable(u32 val)
+{
+ asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
+}
+
+static inline int
+xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
+ enum xscale_counters counter)
+{
+ int ret = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
+ break;
+ case XSCALE_COUNTER0:
+ ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
+ break;
+ case XSCALE_COUNTER1:
+ ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
+ break;
+ case XSCALE_COUNTER2:
+ ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
+ break;
+ case XSCALE_COUNTER3:
+ ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", counter);
+ }
+
+ return ret;
+}
+
+static irqreturn_t
+xscale2pmu_handle_irq(int irq_num, void *dev)
+{
+ unsigned long pmnc, of_flags;
+ struct perf_sample_data data;
+ struct cpu_hw_events *cpuc;
+ struct pt_regs *regs;
+ int idx;
+
+ /* Disable the PMU. */
+ pmnc = xscale2pmu_read_pmnc();
+ xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
+
+ /* Check the overflow flag register. */
+ of_flags = xscale2pmu_read_overflow_flags();
+ if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
+ return IRQ_NONE;
+
+ /* Clear the overflow bits. */
+ xscale2pmu_write_overflow_flags(of_flags);
+
+ regs = get_irq_regs();
+
+ perf_sample_data_init(&data, 0);
+
+ cpuc = &__get_cpu_var(cpu_hw_events);
+ for (idx = 0; idx <= armpmu->num_events; ++idx) {
+ struct perf_event *event = cpuc->events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!test_bit(idx, cpuc->active_mask))
+ continue;
+
+ if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
+ continue;
+
+ hwc = &event->hw;
+ armpmu_event_update(event, hwc, idx, 1);
+ data.period = event->hw.last_period;
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, 0, &data, regs))
+ armpmu->disable(hwc, idx);
+ }
+
+ irq_work_run();
+
+ /*
+ * Re-enable the PMU.
+ */
+ pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(pmnc);
+
+ return IRQ_HANDLED;
+}
+
+static void
+xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags, ien, evtsel;
+
+ ien = xscale2pmu_read_int_enable();
+ evtsel = xscale2pmu_read_event_select();
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ ien |= XSCALE2_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ ien |= XSCALE2_COUNT0_INT_EN;
+ evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ ien |= XSCALE2_COUNT1_INT_EN;
+ evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER2:
+ ien |= XSCALE2_COUNT2_INT_EN;
+ evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER3:
+ ien |= XSCALE2_COUNT3_INT_EN;
+ evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+ evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
+{
+ unsigned long flags, ien, evtsel;
+
+ ien = xscale2pmu_read_int_enable();
+ evtsel = xscale2pmu_read_event_select();
+
+ switch (idx) {
+ case XSCALE_CYCLE_COUNTER:
+ ien &= ~XSCALE2_CCOUNT_INT_EN;
+ break;
+ case XSCALE_COUNTER0:
+ ien &= ~XSCALE2_COUNT0_INT_EN;
+ evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER1:
+ ien &= ~XSCALE2_COUNT1_INT_EN;
+ evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER2:
+ ien &= ~XSCALE2_COUNT2_INT_EN;
+ evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
+ break;
+ case XSCALE_COUNTER3:
+ ien &= ~XSCALE2_COUNT3_INT_EN;
+ evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
+ evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
+ break;
+ default:
+ WARN_ONCE(1, "invalid counter number (%d)\n", idx);
+ return;
+ }
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ xscale2pmu_write_event_select(evtsel);
+ xscale2pmu_write_int_enable(ien);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static int
+xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
+ struct hw_perf_event *event)
+{
+ int idx = xscale1pmu_get_event_idx(cpuc, event);
+ if (idx >= 0)
+ goto out;
+
+ if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
+ idx = XSCALE_COUNTER3;
+ else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
+ idx = XSCALE_COUNTER2;
+out:
+ return idx;
+}
+
+static void
+xscale2pmu_start(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
+ val |= XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static void
+xscale2pmu_stop(void)
+{
+ unsigned long flags, val;
+
+ raw_spin_lock_irqsave(&pmu_lock, flags);
+ val = xscale2pmu_read_pmnc();
+ val &= ~XSCALE_PMU_ENABLE;
+ xscale2pmu_write_pmnc(val);
+ raw_spin_unlock_irqrestore(&pmu_lock, flags);
+}
+
+static inline u32
+xscale2pmu_read_counter(int counter)
+{
+ u32 val = 0;
+
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER2:
+ asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
+ break;
+ case XSCALE_COUNTER3:
+ asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
+ break;
+ }
+
+ return val;
+}
+
+static inline void
+xscale2pmu_write_counter(int counter, u32 val)
+{
+ switch (counter) {
+ case XSCALE_CYCLE_COUNTER:
+ asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER0:
+ asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER1:
+ asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER2:
+ asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
+ break;
+ case XSCALE_COUNTER3:
+ asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
+ break;
+ }
+}
+
+static const struct arm_pmu xscale2pmu = {
+ .id = ARM_PERF_PMU_ID_XSCALE2,
+ .name = "xscale2",
+ .handle_irq = xscale2pmu_handle_irq,
+ .enable = xscale2pmu_enable_event,
+ .disable = xscale2pmu_disable_event,
+ .read_counter = xscale2pmu_read_counter,
+ .write_counter = xscale2pmu_write_counter,
+ .get_event_idx = xscale2pmu_get_event_idx,
+ .start = xscale2pmu_start,
+ .stop = xscale2pmu_stop,
+ .cache_map = &xscale_perf_cache_map,
+ .event_map = &xscale_perf_map,
+ .raw_event_mask = 0xFF,
+ .num_events = 5,
+ .max_period = (1LLU << 32) - 1,
+};
+
+static const struct arm_pmu *__init xscale2pmu_init(void)
+{
+ return &xscale2pmu;
+}
+#else
+static const struct arm_pmu *__init xscale1pmu_init(void)
+{
+ return NULL;
+}
+
+static const struct arm_pmu *__init xscale2pmu_init(void)
+{
+ return NULL;
+}
+#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
new file mode 100644
index 00000000..a4b1b074
--- /dev/null
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/kernel/pj4-cp0.c
+ *
+ * PJ4 iWMMXt coprocessor context switching and handling
+ *
+ * Copyright (c) 2010 Marvell International Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/thread_notify.h>
+
+static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = t;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ /*
+ * flush_thread() zeroes thread->fpstate, so no need
+ * to do anything here.
+ *
+ * FALLTHROUGH: Ensure we don't try to overwrite our newly
+ * initialised state information on the first fault.
+ */
+
+ case THREAD_NOTIFY_EXIT:
+ iwmmxt_task_release(thread);
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ iwmmxt_task_switch(thread);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block iwmmxt_notifier_block = {
+ .notifier_call = iwmmxt_do,
+};
+
+
+static u32 __init pj4_cp_access_read(void)
+{
+ u32 value;
+
+ __asm__ __volatile__ (
+ "mrc p15, 0, %0, c1, c0, 2\n\t"
+ : "=r" (value));
+ return value;
+}
+
+static void __init pj4_cp_access_write(u32 value)
+{
+ u32 temp;
+
+ __asm__ __volatile__ (
+ "mcr p15, 0, %1, c1, c0, 2\n\t"
+ "mrc p15, 0, %0, c1, c0, 2\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4\n\t"
+ : "=r" (temp) : "r" (value));
+}
+
+
+/*
+ * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
+ * switch code handle iWMMXt context switching.
+ */
+static int __init pj4_cp0_init(void)
+{
+ u32 cp_access;
+
+ cp_access = pj4_cp_access_read() & ~0xf;
+ pj4_cp_access_write(cp_access);
+
+ printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
+ elf_hwcap |= HWCAP_IWMMXT;
+ thread_register_notifier(&iwmmxt_notifier_block);
+
+ return 0;
+}
+
+late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
new file mode 100644
index 00000000..2c79eec1
--- /dev/null
+++ b/arch/arm/kernel/pmu.c
@@ -0,0 +1,148 @@
+/*
+ * linux/arch/arm/kernel/pmu.c
+ *
+ * Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
+ * Copyright (C) 2010 ARM Ltd, Will Deacon
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#define pr_fmt(fmt) "PMU: " fmt
+
+#include <linux/cpumask.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/pmu.h>
+
+static volatile long pmu_lock;
+
+static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES];
+
+static int __devinit pmu_device_probe(struct platform_device *pdev)
+{
+
+ if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) {
+ pr_warning("received registration request for unknown "
+ "device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ if (pmu_devices[pdev->id])
+ pr_warning("registering new PMU device type %d overwrites "
+ "previous registration!\n", pdev->id);
+ else
+ pr_info("registered new PMU device of type %d\n",
+ pdev->id);
+
+ pmu_devices[pdev->id] = pdev;
+ return 0;
+}
+
+static struct platform_driver pmu_driver = {
+ .driver = {
+ .name = "arm-pmu",
+ },
+ .probe = pmu_device_probe,
+};
+
+static int __init register_pmu_driver(void)
+{
+ return platform_driver_register(&pmu_driver);
+}
+device_initcall(register_pmu_driver);
+
+struct platform_device *
+reserve_pmu(enum arm_pmu_type device)
+{
+ struct platform_device *pdev;
+
+ if (test_and_set_bit_lock(device, &pmu_lock)) {
+ pdev = ERR_PTR(-EBUSY);
+ } else if (pmu_devices[device] == NULL) {
+ clear_bit_unlock(device, &pmu_lock);
+ pdev = ERR_PTR(-ENODEV);
+ } else {
+ pdev = pmu_devices[device];
+ }
+
+ return pdev;
+}
+EXPORT_SYMBOL_GPL(reserve_pmu);
+
+int
+release_pmu(struct platform_device *pdev)
+{
+ if (WARN_ON(pdev != pmu_devices[pdev->id]))
+ return -EINVAL;
+ clear_bit_unlock(pdev->id, &pmu_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(release_pmu);
+
+static int
+set_irq_affinity(int irq,
+ unsigned int cpu)
+{
+#ifdef CONFIG_SMP
+ int err = irq_set_affinity(irq, cpumask_of(cpu));
+ if (err)
+ pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
+ irq, cpu);
+ return err;
+#else
+ return -EINVAL;
+#endif
+}
+
+static int
+init_cpu_pmu(void)
+{
+ int i, irqs, err = 0;
+ struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU];
+
+ if (!pdev)
+ return -ENODEV;
+
+ irqs = pdev->num_resources;
+
+ /*
+ * If we have a single PMU interrupt that we can't shift, assume that
+ * we're running on a uniprocessor machine and continue.
+ */
+ if (irqs == 1 && !irq_can_set_affinity(platform_get_irq(pdev, 0)))
+ return 0;
+
+ for (i = 0; i < irqs; ++i) {
+ err = set_irq_affinity(platform_get_irq(pdev, i), i);
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+int
+init_pmu(enum arm_pmu_type device)
+{
+ int err = 0;
+
+ switch (device) {
+ case ARM_PMU_DEVICE_CPU:
+ err = init_cpu_pmu();
+ break;
+ default:
+ pr_warning("attempt to initialise unknown device %d\n",
+ device);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(init_pmu);
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
new file mode 100644
index 00000000..300649c7
--- /dev/null
+++ b/arch/arm/kernel/process.c
@@ -0,0 +1,626 @@
+/*
+ * linux/arch/arm/kernel/process.c
+ *
+ * Copyright (C) 1996-2000 Russell King - Converted to ARM.
+ * Original Copyright (C) 1995 Linus Torvalds
+ *
+ * This program is free software; you can 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 <stdarg.h>
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/user.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+#include <linux/kallsyms.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/elfcore.h>
+#include <linux/pm.h>
+#include <linux/tick.h>
+#include <linux/utsname.h>
+#include <linux/uaccess.h>
+#include <linux/random.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/console.h>
+
+#include <asm/cacheflush.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/thread_notify.h>
+#include <asm/stacktrace.h>
+#include <asm/mach/time.h>
+
+#ifdef CONFIG_CC_STACKPROTECTOR
+#include <linux/stackprotector.h>
+unsigned long __stack_chk_guard __read_mostly;
+EXPORT_SYMBOL(__stack_chk_guard);
+#endif
+
+static const char *processor_modes[] = {
+ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
+ "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
+ "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
+ "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
+};
+
+static const char *isa_modes[] = {
+ "ARM" , "Thumb" , "Jazelle", "ThumbEE"
+};
+
+extern void setup_mm_for_reboot(char mode);
+
+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++;
+}
+
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+ hlt_counter--;
+}
+
+EXPORT_SYMBOL(enable_hlt);
+
+static int __init nohlt_setup(char *__unused)
+{
+ hlt_counter = 1;
+ return 1;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+ hlt_counter = 0;
+ return 1;
+}
+
+__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();
+
+ /*
+ * Tell the mm system that we are going to reboot -
+ * we may need it to insert some 1:1 mappings so that
+ * soft boot works.
+ */
+ setup_mm_for_reboot(mode);
+
+ /* Clean and invalidate caches */
+ flush_cache_all();
+
+ /* Turn off caching */
+ cpu_proc_fin();
+
+ /* Push out any further dirty data, and ensure cache is empty */
+ flush_cache_all();
+
+ /*
+ * Now call the architecture specific reboot code.
+ */
+ arch_reset(mode, cmd);
+
+ /*
+ * Whoops - the architecture was unable to reboot.
+ * Tell the user!
+ */
+ mdelay(1000);
+ printk("Reboot failed -- System halted\n");
+ while (1);
+}
+
+/*
+ * Function pointers to optional machine specific functions
+ */
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
+EXPORT_SYMBOL_GPL(arm_pm_restart);
+
+static void do_nothing(void *unused)
+{
+}
+
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
+void cpu_idle_wait(void)
+{
+ smp_mb();
+ /* kick all the CPUs so that they exit out of pm_idle */
+ smp_call_function(do_nothing, NULL, 1);
+}
+EXPORT_SYMBOL_GPL(cpu_idle_wait);
+
+/*
+ * This is our default idle handler. We need to disable
+ * interrupts here to ensure we don't miss a wakeup call.
+ */
+static void default_idle(void)
+{
+ if (!need_resched())
+ arch_idle();
+ local_irq_enable();
+}
+
+void (*pm_idle)(void) = default_idle;
+EXPORT_SYMBOL(pm_idle);
+
+/*
+ * The idle thread, has rather strange semantics for calling pm_idle,
+ * but this is what x86 does and we need to do the same, so that
+ * things like cpuidle get called in the same way. The only difference
+ * is that we always respect 'hlt_counter' to prevent low power idle.
+ */
+void cpu_idle(void)
+{
+ local_fiq_enable();
+
+ /* endless idle loop with no priority at all */
+ while (1) {
+ idle_notifier_call_chain(IDLE_START);
+ tick_nohz_stop_sched_tick(1);
+ while (!need_resched()) {
+#ifdef CONFIG_HOTPLUG_CPU
+ if (cpu_is_offline(smp_processor_id()))
+ cpu_die();
+#endif
+
+ local_irq_disable();
+#ifdef CONFIG_PL310_ERRATA_769419
+ wmb();
+#endif
+ if (hlt_counter || tick_check_broadcast_pending()) {
+ local_irq_enable();
+ cpu_relax();
+ } else {
+ stop_critical_timings();
+ pm_idle();
+ start_critical_timings();
+ /*
+ * This will eventually be removed - pm_idle
+ * functions should always return with IRQs
+ * enabled.
+ */
+ WARN_ON(irqs_disabled());
+ local_irq_enable();
+ }
+ }
+ tick_nohz_restart_sched_tick();
+ idle_notifier_call_chain(IDLE_END);
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+static char reboot_mode = 'h';
+
+int __init reboot_setup(char *str)
+{
+ reboot_mode = str[0];
+ return 1;
+}
+
+__setup("reboot=", reboot_setup);
+
+void machine_shutdown(void)
+{
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
+}
+
+void machine_halt(void)
+{
+ machine_shutdown();
+ while (1);
+}
+
+void machine_power_off(void)
+{
+ machine_shutdown();
+ if (pm_power_off)
+ pm_power_off();
+}
+
+void machine_restart(char *cmd)
+{
+ machine_shutdown();
+ 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;
+ char buf[64];
+
+ printk("CPU: %d %s (%s %.*s)\n",
+ raw_smp_processor_id(), print_tainted(),
+ init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
+ print_symbol("PC is at %s\n", instruction_pointer(regs));
+ print_symbol("LR is at %s\n", regs->ARM_lr);
+ printk("pc : [<%08lx>] lr : [<%08lx>] psr: %08lx\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
+ regs->ARM_pc, regs->ARM_lr, regs->ARM_cpsr,
+ regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+ printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
+ regs->ARM_r10, regs->ARM_r9,
+ regs->ARM_r8);
+ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ regs->ARM_r7, regs->ARM_r6,
+ regs->ARM_r5, regs->ARM_r4);
+ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ regs->ARM_r3, regs->ARM_r2,
+ regs->ARM_r1, regs->ARM_r0);
+
+ flags = regs->ARM_cpsr;
+ buf[0] = flags & PSR_N_BIT ? 'N' : 'n';
+ buf[1] = flags & PSR_Z_BIT ? 'Z' : 'z';
+ buf[2] = flags & PSR_C_BIT ? 'C' : 'c';
+ buf[3] = flags & PSR_V_BIT ? 'V' : 'v';
+ buf[4] = '\0';
+
+ printk("Flags: %s IRQs o%s FIQs o%s Mode %s ISA %s Segment %s\n",
+ buf, interrupts_enabled(regs) ? "n" : "ff",
+ fast_interrupts_enabled(regs) ? "n" : "ff",
+ processor_modes[processor_mode(regs)],
+ isa_modes[isa_mode(regs)],
+ get_fs() == get_ds() ? "kernel" : "user");
+#ifdef CONFIG_CPU_CP15
+ {
+ unsigned int ctrl;
+
+ buf[0] = '\0';
+#ifdef CONFIG_CPU_CP15_MMU
+ {
+ unsigned int transbase, dac;
+ asm("mrc p15, 0, %0, c2, c0\n\t"
+ "mrc p15, 0, %1, c3, c0\n"
+ : "=r" (transbase), "=r" (dac));
+ snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x",
+ transbase, dac);
+ }
+#endif
+ asm("mrc p15, 0, %0, c1, c0\n" : "=r" (ctrl));
+
+ printk("Control: %08x%s\n", ctrl, buf);
+ }
+#endif
+
+ show_extra_register_data(regs, 128);
+}
+
+void show_regs(struct pt_regs * regs)
+{
+ printk("\n");
+ printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
+ __show_regs(regs);
+ __backtrace();
+}
+
+ATOMIC_NOTIFIER_HEAD(thread_notify_head);
+
+EXPORT_SYMBOL_GPL(thread_notify_head);
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+ thread_notify(THREAD_NOTIFY_EXIT, current_thread_info());
+}
+
+void flush_thread(void)
+{
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = current;
+
+ flush_ptrace_hw_breakpoint(tsk);
+
+ memset(thread->used_cp, 0, sizeof(thread->used_cp));
+ memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
+ memset(&thread->fpstate, 0, sizeof(union fp_state));
+
+ thread_notify(THREAD_NOTIFY_FLUSH, thread);
+}
+
+void release_thread(struct task_struct *dead_task)
+{
+}
+
+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+
+int
+copy_thread(unsigned long clone_flags, unsigned long stack_start,
+ unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs)
+{
+ struct thread_info *thread = task_thread_info(p);
+ struct pt_regs *childregs = task_pt_regs(p);
+
+ *childregs = *regs;
+ childregs->ARM_r0 = 0;
+ childregs->ARM_sp = stack_start;
+
+ memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+ thread->cpu_context.sp = (unsigned long)childregs;
+ thread->cpu_context.pc = (unsigned long)ret_from_fork;
+
+ clear_ptrace_hw_breakpoint(p);
+
+ if (clone_flags & CLONE_SETTLS)
+ thread->tp_value = regs->ARM_r3;
+
+ thread_notify(THREAD_NOTIFY_COPY, thread);
+
+ return 0;
+}
+
+/*
+ * Fill in the task's elfregs structure for a core dump.
+ */
+int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
+{
+ elf_core_copy_regs(elfregs, task_pt_regs(t));
+ return 1;
+}
+
+/*
+ * fill in the fpe structure for a core dump...
+ */
+int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
+{
+ struct thread_info *thread = current_thread_info();
+ int used_math = thread->used_cp[1] | thread->used_cp[2];
+
+ if (used_math)
+ memcpy(fp, &thread->fpstate.soft, sizeof (*fp));
+
+ return used_math != 0;
+}
+EXPORT_SYMBOL(dump_fpu);
+
+/*
+ * Shuffle the argument into the correct register before calling the
+ * thread function. r4 is the thread argument, r5 is the pointer to
+ * the thread function, and r6 points to the exit function.
+ */
+extern void kernel_thread_helper(void);
+asm( ".pushsection .text\n"
+" .align\n"
+" .type kernel_thread_helper, #function\n"
+"kernel_thread_helper:\n"
+#ifdef CONFIG_TRACE_IRQFLAGS
+" bl trace_hardirqs_on\n"
+#endif
+" msr cpsr_c, r7\n"
+" mov r0, r4\n"
+" mov lr, r6\n"
+" mov pc, r5\n"
+" .size kernel_thread_helper, . - kernel_thread_helper\n"
+" .popsection");
+
+#ifdef CONFIG_ARM_UNWIND
+extern void kernel_thread_exit(long code);
+asm( ".pushsection .text\n"
+" .align\n"
+" .type kernel_thread_exit, #function\n"
+"kernel_thread_exit:\n"
+" .fnstart\n"
+" .cantunwind\n"
+" bl do_exit\n"
+" nop\n"
+" .fnend\n"
+" .size kernel_thread_exit, . - kernel_thread_exit\n"
+" .popsection");
+#else
+#define kernel_thread_exit do_exit
+#endif
+
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+
+ regs.ARM_r4 = (unsigned long)arg;
+ regs.ARM_r5 = (unsigned long)fn;
+ regs.ARM_r6 = (unsigned long)kernel_thread_exit;
+ regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
+ regs.ARM_pc = (unsigned long)kernel_thread_helper;
+ regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
+
+ return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+}
+EXPORT_SYMBOL(kernel_thread);
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ struct stackframe frame;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ frame.fp = thread_saved_fp(p);
+ frame.sp = thread_saved_sp(p);
+ frame.lr = 0; /* recovered from the stack */
+ frame.pc = thread_saved_pc(p);
+ do {
+ int ret = unwind_frame(&frame);
+ if (ret < 0)
+ return 0;
+ if (!in_sched_functions(frame.pc))
+ return frame.pc;
+ } while (count ++ < 16);
+ return 0;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+ unsigned long range_end = mm->brk + 0x02000000;
+ return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+}
+
+#ifdef CONFIG_MMU
+/*
+ * The vectors page is always readable from user space for the
+ * atomic helpers and the signal restart code. Let's declare a mapping
+ * for it so it is visible through ptrace and /proc/<pid>/mem.
+ */
+
+int vectors_user_mapping(void)
+{
+ struct mm_struct *mm = current->mm;
+ return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
+ VM_READ | VM_EXEC |
+ VM_MAYREAD | VM_MAYEXEC |
+ VM_ALWAYSDUMP | VM_RESERVED,
+ NULL);
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
+}
+#endif
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
new file mode 100644
index 00000000..172ae01c
--- /dev/null
+++ b/arch/arm/kernel/ptrace.c
@@ -0,0 +1,961 @@
+/*
+ * linux/arch/arm/kernel/ptrace.c
+ *
+ * By Ross Biro 1/23/92
+ * edited by Linus Torvalds
+ * ARM modifications Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can 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/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/security.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/uaccess.h>
+#include <linux/perf_event.h>
+#include <linux/hw_breakpoint.h>
+#include <linux/regset.h>
+
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+
+#define REG_PC 15
+#define REG_PSR 16
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+#if 0
+/*
+ * Breakpoint SWI instruction: SWI &9F0001
+ */
+#define BREAKINST_ARM 0xef9f0001
+#define BREAKINST_THUMB 0xdf00 /* fill this in later */
+#else
+/*
+ * New breakpoints - use an undefined instruction. The ARM architecture
+ * reference manual guarantees that the following instruction space
+ * will produce an undefined instruction exception on all CPUs:
+ *
+ * ARM: xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
+ * Thumb: 1101 1110 xxxx xxxx
+ */
+#define BREAKINST_ARM 0xe7f001f0
+#define BREAKINST_THUMB 0xde01
+#endif
+
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
+
+#define REG_OFFSET_NAME(r) \
+ {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(r0),
+ REG_OFFSET_NAME(r1),
+ REG_OFFSET_NAME(r2),
+ REG_OFFSET_NAME(r3),
+ REG_OFFSET_NAME(r4),
+ REG_OFFSET_NAME(r5),
+ REG_OFFSET_NAME(r6),
+ REG_OFFSET_NAME(r7),
+ REG_OFFSET_NAME(r8),
+ REG_OFFSET_NAME(r9),
+ REG_OFFSET_NAME(r10),
+ REG_OFFSET_NAME(fp),
+ REG_OFFSET_NAME(ip),
+ REG_OFFSET_NAME(sp),
+ REG_OFFSET_NAME(lr),
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(cpsr),
+ REG_OFFSET_NAME(ORIG_r0),
+ REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
+
+/*
+ * this routine will get a word off of the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline long get_user_reg(struct task_struct *task, int offset)
+{
+ return task_pt_regs(task)->uregs[offset];
+}
+
+/*
+ * this routine will put a word on the processes privileged stack.
+ * the offset is how far from the base addr as stored in the THREAD.
+ * this routine assumes that all the privileged stacks are in our
+ * data space.
+ */
+static inline int
+put_user_reg(struct task_struct *task, int offset, long data)
+{
+ struct pt_regs newregs, *regs = task_pt_regs(task);
+ int ret = -EINVAL;
+
+ newregs = *regs;
+ newregs.uregs[offset] = data;
+
+ if (valid_user_regs(&newregs)) {
+ regs->uregs[offset] = data;
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ /* Nothing to do. */
+}
+
+/*
+ * Handle hitting a breakpoint.
+ */
+void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ info.si_signo = SIGTRAP;
+ info.si_errno = 0;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void __user *)instruction_pointer(regs);
+
+ force_sig_info(SIGTRAP, &info, tsk);
+}
+
+static int break_trap(struct pt_regs *regs, unsigned int instr)
+{
+ ptrace_break(current, regs);
+ return 0;
+}
+
+static struct undef_hook arm_break_hook = {
+ .instr_mask = 0x0fffffff,
+ .instr_val = 0x07f001f0,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = 0,
+ .fn = break_trap,
+};
+
+static struct undef_hook thumb_break_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = 0xde01,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = PSR_T_BIT,
+ .fn = break_trap,
+};
+
+static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
+{
+ unsigned int instr2;
+ void __user *pc;
+
+ /* Check the second half of the instruction. */
+ pc = (void __user *)(instruction_pointer(regs) + 2);
+
+ if (processor_mode(regs) == SVC_MODE) {
+ instr2 = *(u16 *) pc;
+ } else {
+ get_user(instr2, (u16 __user *)pc);
+ }
+
+ if (instr2 == 0xa000) {
+ ptrace_break(current, regs);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static struct undef_hook thumb2_break_hook = {
+ .instr_mask = 0xffff,
+ .instr_val = 0xf7f0,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = PSR_T_BIT,
+ .fn = thumb2_break_trap,
+};
+
+static int __init ptrace_break_init(void)
+{
+ register_undef_hook(&arm_break_hook);
+ register_undef_hook(&thumb_break_hook);
+ register_undef_hook(&thumb2_break_hook);
+ return 0;
+}
+
+core_initcall(ptrace_break_init);
+
+/*
+ * Read the word at offset "off" into the "struct user". We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_read_user(struct task_struct *tsk, unsigned long off,
+ unsigned long __user *ret)
+{
+ unsigned long tmp;
+
+ if (off & 3 || off >= sizeof(struct user))
+ return -EIO;
+
+ tmp = 0;
+ if (off == PT_TEXT_ADDR)
+ tmp = tsk->mm->start_code;
+ else if (off == PT_DATA_ADDR)
+ tmp = tsk->mm->start_data;
+ else if (off == PT_TEXT_END_ADDR)
+ tmp = tsk->mm->end_code;
+ else if (off < sizeof(struct pt_regs))
+ tmp = get_user_reg(tsk, off >> 2);
+
+ return put_user(tmp, ret);
+}
+
+/*
+ * Write the word at offset "off" into "struct user". We
+ * actually access the pt_regs stored on the kernel stack.
+ */
+static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
+ unsigned long val)
+{
+ if (off & 3 || off >= sizeof(struct user))
+ return -EIO;
+
+ if (off >= sizeof(struct pt_regs))
+ return 0;
+
+ return put_user_reg(tsk, off >> 2, val);
+}
+
+#ifdef CONFIG_IWMMXT
+
+/*
+ * Get the child iWMMXt state.
+ */
+static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+
+ if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
+ return -ENODATA;
+ iwmmxt_task_disable(thread); /* force it to ram */
+ return copy_to_user(ufp, &thread->fpstate.iwmmxt, IWMMXT_SIZE)
+ ? -EFAULT : 0;
+}
+
+/*
+ * Set the child iWMMXt state.
+ */
+static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+
+ if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT))
+ return -EACCES;
+ iwmmxt_task_release(thread); /* force a reload */
+ return copy_from_user(&thread->fpstate.iwmmxt, ufp, IWMMXT_SIZE)
+ ? -EFAULT : 0;
+}
+
+#endif
+
+#ifdef CONFIG_CRUNCH
+/*
+ * Get the child Crunch state.
+ */
+static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+
+ crunch_task_disable(thread); /* force it to ram */
+ return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE)
+ ? -EFAULT : 0;
+}
+
+/*
+ * Set the child Crunch state.
+ */
+static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
+{
+ struct thread_info *thread = task_thread_info(tsk);
+
+ crunch_task_release(thread); /* force a reload */
+ return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE)
+ ? -EFAULT : 0;
+}
+#endif
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+/*
+ * Convert a virtual register number into an index for a thread_info
+ * breakpoint array. Breakpoints are identified using positive numbers
+ * whilst watchpoints are negative. The registers are laid out as pairs
+ * of (address, control), each pair mapping to a unique hw_breakpoint struct.
+ * Register 0 is reserved for describing resource information.
+ */
+static int ptrace_hbp_num_to_idx(long num)
+{
+ if (num < 0)
+ num = (ARM_MAX_BRP << 1) - num;
+ return (num - 1) >> 1;
+}
+
+/*
+ * Returns the virtual register number for the address of the
+ * breakpoint at index idx.
+ */
+static long ptrace_hbp_idx_to_num(int idx)
+{
+ long mid = ARM_MAX_BRP << 1;
+ long num = (idx << 1) + 1;
+ return num > mid ? mid - num : num;
+}
+
+/*
+ * Handle hitting a HW-breakpoint.
+ */
+static void ptrace_hbptriggered(struct perf_event *bp, int unused,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
+ long num;
+ int i;
+ siginfo_t info;
+
+ for (i = 0; i < ARM_MAX_HBP_SLOTS; ++i)
+ if (current->thread.debug.hbp[i] == bp)
+ break;
+
+ num = (i == ARM_MAX_HBP_SLOTS) ? 0 : ptrace_hbp_idx_to_num(i);
+
+ info.si_signo = SIGTRAP;
+ info.si_errno = (int)num;
+ info.si_code = TRAP_HWBKPT;
+ info.si_addr = (void __user *)(bkpt->trigger);
+
+ force_sig_info(SIGTRAP, &info, current);
+}
+
+/*
+ * Set ptrace breakpoint pointers to zero for this task.
+ * This is required in order to prevent child processes from unregistering
+ * breakpoints held by their parent.
+ */
+void clear_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ memset(tsk->thread.debug.hbp, 0, sizeof(tsk->thread.debug.hbp));
+}
+
+/*
+ * Unregister breakpoints from this task and reset the pointers in
+ * the thread_struct.
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ int i;
+ struct thread_struct *t = &tsk->thread;
+
+ for (i = 0; i < ARM_MAX_HBP_SLOTS; i++) {
+ if (t->debug.hbp[i]) {
+ unregister_hw_breakpoint(t->debug.hbp[i]);
+ t->debug.hbp[i] = NULL;
+ }
+ }
+}
+
+static u32 ptrace_get_hbp_resource_info(void)
+{
+ u8 num_brps, num_wrps, debug_arch, wp_len;
+ u32 reg = 0;
+
+ num_brps = hw_breakpoint_slots(TYPE_INST);
+ num_wrps = hw_breakpoint_slots(TYPE_DATA);
+ debug_arch = arch_get_debug_arch();
+ wp_len = arch_get_max_wp_len();
+
+ reg |= debug_arch;
+ reg <<= 8;
+ reg |= wp_len;
+ reg <<= 8;
+ reg |= num_wrps;
+ reg <<= 8;
+ reg |= num_brps;
+
+ return reg;
+}
+
+static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type)
+{
+ struct perf_event_attr attr;
+
+ ptrace_breakpoint_init(&attr);
+
+ /* Initialise fields to sane defaults. */
+ attr.bp_addr = 0;
+ attr.bp_len = HW_BREAKPOINT_LEN_4;
+ attr.bp_type = type;
+ attr.disabled = 1;
+
+ return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, tsk);
+}
+
+static int ptrace_gethbpregs(struct task_struct *tsk, long num,
+ unsigned long __user *data)
+{
+ u32 reg;
+ int idx, ret = 0;
+ struct perf_event *bp;
+ struct arch_hw_breakpoint_ctrl arch_ctrl;
+
+ if (num == 0) {
+ reg = ptrace_get_hbp_resource_info();
+ } else {
+ idx = ptrace_hbp_num_to_idx(num);
+ if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ bp = tsk->thread.debug.hbp[idx];
+ if (!bp) {
+ reg = 0;
+ goto put;
+ }
+
+ arch_ctrl = counter_arch_bp(bp)->ctrl;
+
+ /*
+ * Fix up the len because we may have adjusted it
+ * to compensate for an unaligned address.
+ */
+ while (!(arch_ctrl.len & 0x1))
+ arch_ctrl.len >>= 1;
+
+ if (num & 0x1)
+ reg = bp->attr.bp_addr;
+ else
+ reg = encode_ctrl_reg(arch_ctrl);
+ }
+
+put:
+ if (put_user(reg, data))
+ ret = -EFAULT;
+
+out:
+ return ret;
+}
+
+static int ptrace_sethbpregs(struct task_struct *tsk, long num,
+ unsigned long __user *data)
+{
+ int idx, gen_len, gen_type, implied_type, ret = 0;
+ u32 user_val;
+ struct perf_event *bp;
+ struct arch_hw_breakpoint_ctrl ctrl;
+ struct perf_event_attr attr;
+
+ if (num == 0)
+ goto out;
+ else if (num < 0)
+ implied_type = HW_BREAKPOINT_RW;
+ else
+ implied_type = HW_BREAKPOINT_X;
+
+ idx = ptrace_hbp_num_to_idx(num);
+ if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (get_user(user_val, data)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ bp = tsk->thread.debug.hbp[idx];
+ if (!bp) {
+ bp = ptrace_hbp_create(tsk, implied_type);
+ if (IS_ERR(bp)) {
+ ret = PTR_ERR(bp);
+ goto out;
+ }
+ tsk->thread.debug.hbp[idx] = bp;
+ }
+
+ attr = bp->attr;
+
+ if (num & 0x1) {
+ /* Address */
+ attr.bp_addr = user_val;
+ } else {
+ /* Control */
+ decode_ctrl_reg(user_val, &ctrl);
+ ret = arch_bp_generic_fields(ctrl, &gen_len, &gen_type);
+ if (ret)
+ goto out;
+
+ if ((gen_type & implied_type) != gen_type) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ attr.bp_len = gen_len;
+ attr.bp_type = gen_type;
+ attr.disabled = !ctrl.enabled;
+ }
+
+ ret = modify_user_hw_breakpoint(bp, &attr);
+out:
+ return ret;
+}
+#endif
+
+/* regset get/set implementations */
+
+static int gpr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ regs,
+ 0, sizeof(*regs));
+}
+
+static int gpr_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ struct pt_regs newregs;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &newregs,
+ 0, sizeof(newregs));
+ if (ret)
+ return ret;
+
+ if (!valid_user_regs(&newregs))
+ return -EINVAL;
+
+ *task_pt_regs(target) = newregs;
+ return 0;
+}
+
+static int fpa_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &task_thread_info(target)->fpstate,
+ 0, sizeof(struct user_fp));
+}
+
+static int fpa_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct thread_info *thread = task_thread_info(target);
+
+ thread->used_cp[1] = thread->used_cp[2] = 1;
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &thread->fpstate,
+ 0, sizeof(struct user_fp));
+}
+
+#ifdef CONFIG_VFP
+/*
+ * VFP register get/set implementations.
+ *
+ * With respect to the kernel, struct user_fp is divided into three chunks:
+ * 16 or 32 real VFP registers (d0-d15 or d0-31)
+ * These are transferred to/from the real registers in the task's
+ * vfp_hard_struct. The number of registers depends on the kernel
+ * configuration.
+ *
+ * 16 or 0 fake VFP registers (d16-d31 or empty)
+ * i.e., the user_vfp structure has space for 32 registers even if
+ * the kernel doesn't have them all.
+ *
+ * vfp_get() reads this chunk as zero where applicable
+ * vfp_set() ignores this chunk
+ *
+ * 1 word for the FPSCR
+ *
+ * The bounds-checking logic built into user_regset_copyout and friends
+ * means that we can make a simple sequence of calls to map the relevant data
+ * to/from the specified slice of the user regset structure.
+ */
+static int vfp_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+ struct thread_info *thread = task_thread_info(target);
+ struct vfp_hard_struct const *vfp = &thread->vfpstate.hard;
+ const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+ const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+ vfp_sync_hwstate(thread);
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &vfp->fpregs,
+ user_fpregs_offset,
+ user_fpregs_offset + sizeof(vfp->fpregs));
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ user_fpregs_offset + sizeof(vfp->fpregs),
+ user_fpscr_offset);
+ if (ret)
+ return ret;
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &vfp->fpscr,
+ user_fpscr_offset,
+ user_fpscr_offset + sizeof(vfp->fpscr));
+}
+
+/*
+ * For vfp_set() a read-modify-write is done on the VFP registers,
+ * in order to avoid writing back a half-modified set of registers on
+ * failure.
+ */
+static int vfp_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ struct thread_info *thread = task_thread_info(target);
+ struct vfp_hard_struct new_vfp;
+ const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+ const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+ vfp_sync_hwstate(thread);
+ new_vfp = thread->vfpstate.hard;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &new_vfp.fpregs,
+ user_fpregs_offset,
+ user_fpregs_offset + sizeof(new_vfp.fpregs));
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ user_fpregs_offset + sizeof(new_vfp.fpregs),
+ user_fpscr_offset);
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &new_vfp.fpscr,
+ user_fpscr_offset,
+ user_fpscr_offset + sizeof(new_vfp.fpscr));
+ if (ret)
+ return ret;
+
+ vfp_flush_hwstate(thread);
+ thread->vfpstate.hard = new_vfp;
+
+ return 0;
+}
+#endif /* CONFIG_VFP */
+
+enum arm_regset {
+ REGSET_GPR,
+ REGSET_FPR,
+#ifdef CONFIG_VFP
+ REGSET_VFP,
+#endif
+};
+
+static const struct user_regset arm_regsets[] = {
+ [REGSET_GPR] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = gpr_get,
+ .set = gpr_set
+ },
+ [REGSET_FPR] = {
+ /*
+ * For the FPA regs in fpstate, the real fields are a mixture
+ * of sizes, so pretend that the registers are word-sized:
+ */
+ .core_note_type = NT_PRFPREG,
+ .n = sizeof(struct user_fp) / sizeof(u32),
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = fpa_get,
+ .set = fpa_set
+ },
+#ifdef CONFIG_VFP
+ [REGSET_VFP] = {
+ /*
+ * Pretend that the VFP regs are word-sized, since the FPSCR is
+ * a single word dangling at the end of struct user_vfp:
+ */
+ .core_note_type = NT_ARM_VFP,
+ .n = ARM_VFPREGS_SIZE / sizeof(u32),
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = vfp_get,
+ .set = vfp_set
+ },
+#endif /* CONFIG_VFP */
+};
+
+static const struct user_regset_view user_arm_view = {
+ .name = "arm", .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
+ .regsets = arm_regsets, .n = ARRAY_SIZE(arm_regsets)
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_arm_view;
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ int ret;
+ unsigned long __user *datap = (unsigned long __user *) data;
+
+ switch (request) {
+ case PTRACE_PEEKUSR:
+ ret = ptrace_read_user(child, addr, datap);
+ break;
+
+ case PTRACE_POKEUSR:
+ ret = ptrace_write_user(child, addr, data);
+ break;
+
+ case PTRACE_GETREGS:
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_GPR,
+ 0, sizeof(struct pt_regs),
+ datap);
+ break;
+
+ case PTRACE_SETREGS:
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_GPR,
+ 0, sizeof(struct pt_regs),
+ datap);
+ break;
+
+ case PTRACE_GETFPREGS:
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_FPR,
+ 0, sizeof(union fp_state),
+ datap);
+ break;
+
+ case PTRACE_SETFPREGS:
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_FPR,
+ 0, sizeof(union fp_state),
+ datap);
+ break;
+
+#ifdef CONFIG_IWMMXT
+ case PTRACE_GETWMMXREGS:
+ ret = ptrace_getwmmxregs(child, datap);
+ break;
+
+ case PTRACE_SETWMMXREGS:
+ ret = ptrace_setwmmxregs(child, datap);
+ break;
+#endif
+
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value,
+ datap);
+ break;
+
+ case PTRACE_SET_SYSCALL:
+ task_thread_info(child)->syscall = data;
+ ret = 0;
+ break;
+
+#ifdef CONFIG_CRUNCH
+ case PTRACE_GETCRUNCHREGS:
+ ret = ptrace_getcrunchregs(child, datap);
+ break;
+
+ case PTRACE_SETCRUNCHREGS:
+ ret = ptrace_setcrunchregs(child, datap);
+ break;
+#endif
+
+#ifdef CONFIG_VFP
+ case PTRACE_GETVFPREGS:
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_VFP,
+ 0, ARM_VFPREGS_SIZE,
+ datap);
+ break;
+
+ case PTRACE_SETVFPREGS:
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_VFP,
+ 0, ARM_VFPREGS_SIZE,
+ datap);
+ break;
+#endif
+
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ case PTRACE_GETHBPREGS:
+ if (ptrace_get_breakpoints(child) < 0)
+ return -ESRCH;
+
+ ret = ptrace_gethbpregs(child, addr,
+ (unsigned long __user *)data);
+ ptrace_put_breakpoints(child);
+ break;
+ case PTRACE_SETHBPREGS:
+ if (ptrace_get_breakpoints(child) < 0)
+ return -ESRCH;
+
+ ret = ptrace_sethbpregs(child, addr,
+ (unsigned long __user *)data);
+ ptrace_put_breakpoints(child);
+ break;
+#endif
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
+{
+ unsigned long ip;
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return scno;
+ if (!(current->ptrace & PT_PTRACED))
+ return scno;
+
+ /*
+ * Save IP. IP is used to denote syscall entry/exit:
+ * IP = 0 -> entry, = 1 -> exit
+ */
+ ip = regs->ARM_ip;
+ regs->ARM_ip = why;
+
+ current_thread_info()->syscall = scno;
+
+ /* the 0x80 provides a way for the tracing parent to distinguish
+ between a syscall stop and SIGTRAP delivery */
+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ ? 0x80 : 0));
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+ regs->ARM_ip = ip;
+
+ return current_thread_info()->syscall;
+}
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
new file mode 100644
index 00000000..9cf4cbf8
--- /dev/null
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -0,0 +1,87 @@
+/*
+ * relocate_kernel.S - put the kernel image in place to boot
+ */
+
+#include <asm/kexec.h>
+
+ .globl relocate_new_kernel
+relocate_new_kernel:
+
+ ldr r0,kexec_indirection_page
+ ldr r1,kexec_start_address
+
+ /*
+ * If there is no indirection page (we are doing crashdumps)
+ * skip any relocation.
+ */
+ cmp r0, #0
+ beq 2f
+
+0: /* top, read another word for the indirection page */
+ ldr r3, [r0],#4
+
+ /* Is it a destination page. Put destination address to r4 */
+ tst r3,#1,0
+ beq 1f
+ bic r4,r3,#1
+ b 0b
+1:
+ /* Is it an indirection page */
+ tst r3,#2,0
+ beq 1f
+ bic r0,r3,#2
+ b 0b
+1:
+
+ /* are we done ? */
+ tst r3,#4,0
+ beq 1f
+ b 2f
+
+1:
+ /* is it source ? */
+ tst r3,#8,0
+ beq 0b
+ bic r3,r3,#8
+ mov r6,#1024
+9:
+ ldr r5,[r3],#4
+ str r5,[r4],#4
+ subs r6,r6,#1
+ bne 9b
+ b 0b
+
+2:
+ /* Jump to relocated kernel */
+ mov lr,r1
+ mov r0,#0
+ ldr r1,kexec_mach_type
+ ldr r2,kexec_boot_atags
+ mov pc,lr
+
+ .align
+
+ .globl kexec_start_address
+kexec_start_address:
+ .long 0x0
+
+ .globl kexec_indirection_page
+kexec_indirection_page:
+ .long 0x0
+
+ .globl kexec_mach_type
+kexec_mach_type:
+ .long 0x0
+
+ /* phy addr of the atags for the new kernel */
+ .globl kexec_boot_atags
+kexec_boot_atags:
+ .long 0x0
+
+relocate_new_kernel_end:
+
+ .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+ .long relocate_new_kernel_end - relocate_new_kernel
+
+
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
new file mode 100644
index 00000000..0b13a72f
--- /dev/null
+++ b/arch/arm/kernel/return_address.c
@@ -0,0 +1,72 @@
+/*
+ * arch/arm/kernel/return_address.c
+ *
+ * Copyright (C) 2009 Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ * for Pengutronix
+ *
+ * This program is free software; you can 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/ftrace.h>
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+#include <linux/sched.h>
+
+#include <asm/stacktrace.h>
+
+struct return_address_data {
+ unsigned int level;
+ void *addr;
+};
+
+static int save_return_addr(struct stackframe *frame, void *d)
+{
+ struct return_address_data *data = d;
+
+ if (!data->level) {
+ data->addr = (void *)frame->lr;
+
+ return 1;
+ } else {
+ --data->level;
+ return 0;
+ }
+}
+
+void *return_address(unsigned int level)
+{
+ struct return_address_data data;
+ struct stackframe frame;
+ register unsigned long current_sp asm ("sp");
+
+ data.level = level + 1;
+
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)return_address;
+
+ walk_stackframe(&frame, save_return_addr, &data);
+
+ if (!data.level)
+ return data.addr;
+ else
+ return NULL;
+}
+
+#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
+
+#if defined(CONFIG_ARM_UNWIND)
+#warning "TODO: return_address should use unwind tables"
+#endif
+
+void *return_address(unsigned int level)
+{
+ return NULL;
+}
+
+#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) / else */
+
+EXPORT_SYMBOL_GPL(return_address);
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
new file mode 100644
index 00000000..9a46370f
--- /dev/null
+++ b/arch/arm/kernel/sched_clock.c
@@ -0,0 +1,74 @@
+/*
+ * sched_clock.c: support for extending counters to full 64-bit ns counter
+ *
+ * This program is free software; you can 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/clocksource.h>
+#include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+
+#include <asm/sched_clock.h>
+
+static void sched_clock_poll(unsigned long wrap_ticks);
+static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
+static void (*sched_clock_update_fn)(void);
+
+static void sched_clock_poll(unsigned long wrap_ticks)
+{
+ mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
+ sched_clock_update_fn();
+}
+
+void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
+ unsigned int clock_bits, unsigned long rate)
+{
+ unsigned long r, w;
+ u64 res, wrap;
+ char r_unit;
+
+ sched_clock_update_fn = update;
+
+ /* calculate the mult/shift to convert counter ticks to ns. */
+ clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
+
+ r = rate;
+ if (r >= 4000000) {
+ r /= 1000000;
+ r_unit = 'M';
+ } else {
+ r /= 1000;
+ r_unit = 'k';
+ }
+
+ /* calculate how many ns until we wrap */
+ wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
+ do_div(wrap, NSEC_PER_MSEC);
+ w = wrap;
+
+ /* calculate the ns resolution of this counter */
+ res = cyc_to_ns(1ULL, cd->mult, cd->shift);
+ pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
+ clock_bits, r, r_unit, res, w);
+
+ /*
+ * Start the timer to keep sched_clock() properly updated and
+ * sets the initial epoch.
+ */
+ sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
+ update();
+
+ /*
+ * Ensure that sched_clock() starts off at 0ns
+ */
+ cd->epoch_ns = 0;
+}
+
+void __init sched_clock_postinit(void)
+{
+ sched_clock_poll(sched_clock_timer.data);
+}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
new file mode 100644
index 00000000..acbb447a
--- /dev/null
+++ b/arch/arm/kernel/setup.c
@@ -0,0 +1,1068 @@
+/*
+ * linux/arch/arm/kernel/setup.c
+ *
+ * Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can 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/stddef.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/utsname.h>
+#include <linux/initrd.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/screen_info.h>
+#include <linux/init.h>
+#include <linux/kexec.h>
+#include <linux/of_fdt.h>
+#include <linux/crash_dump.h>
+#include <linux/root_dev.h>
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/memblock.h>
+
+#include <asm/unified.h>
+#include <asm/cpu.h>
+#include <asm/cputype.h>
+#include <asm/elf.h>
+#include <asm/procinfo.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/smp_plat.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/tlbflush.h>
+
+#include <asm/prom.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+
+#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
+#include "compat.h"
+#endif
+#include "atags.h"
+#include "tcm.h"
+
+#ifndef MEM_SIZE
+#define MEM_SIZE (16*1024*1024)
+#endif
+
+#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
+char fpe_type[8];
+
+static int __init fpe_setup(char *line)
+{
+ memcpy(fpe_type, line, 8);
+ return 1;
+}
+
+__setup("fpe=", fpe_setup);
+#endif
+
+extern void paging_init(struct machine_desc *desc);
+extern void sanity_check_meminfo(void);
+extern void reboot_setup(char *str);
+
+unsigned int processor_id;
+EXPORT_SYMBOL(processor_id);
+unsigned int __machine_arch_type __read_mostly;
+EXPORT_SYMBOL(__machine_arch_type);
+unsigned int cacheid __read_mostly;
+EXPORT_SYMBOL(cacheid);
+
+unsigned int __atags_pointer __initdata;
+
+unsigned int system_rev;
+EXPORT_SYMBOL(system_rev);
+
+unsigned int system_serial_low;
+EXPORT_SYMBOL(system_serial_low);
+
+unsigned int system_serial_high;
+EXPORT_SYMBOL(system_serial_high);
+
+unsigned int elf_hwcap __read_mostly;
+EXPORT_SYMBOL(elf_hwcap);
+
+
+#ifdef MULTI_CPU
+struct processor processor __read_mostly;
+#endif
+#ifdef MULTI_TLB
+struct cpu_tlb_fns cpu_tlb __read_mostly;
+#endif
+#ifdef MULTI_USER
+struct cpu_user_fns cpu_user __read_mostly;
+#endif
+#ifdef MULTI_CACHE
+struct cpu_cache_fns cpu_cache __read_mostly;
+#endif
+#ifdef CONFIG_OUTER_CACHE
+struct outer_cache_fns outer_cache __read_mostly;
+EXPORT_SYMBOL(outer_cache);
+#endif
+
+struct stack {
+ u32 irq[3];
+ u32 abt[3];
+ u32 und[3];
+} ____cacheline_aligned;
+
+static struct stack stacks[NR_CPUS];
+
+char elf_platform[ELF_PLATFORM_SIZE];
+EXPORT_SYMBOL(elf_platform);
+
+static const char *cpu_name;
+static const char *machine_name;
+static char __initdata cmd_line[COMMAND_LINE_SIZE];
+struct machine_desc *machine_desc __initdata;
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
+static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
+#define ENDIANNESS ((char)endian_test.l)
+
+DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
+
+/*
+ * Standard memory resources
+ */
+static struct resource mem_res[] = {
+ {
+ .name = "Video RAM",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .name = "Kernel text",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .name = "Kernel data",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+#define video_ram mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
+
+static struct resource io_res[] = {
+ {
+ .name = "reserved",
+ .start = 0x3bc,
+ .end = 0x3be,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
+ },
+ {
+ .name = "reserved",
+ .start = 0x378,
+ .end = 0x37f,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
+ },
+ {
+ .name = "reserved",
+ .start = 0x278,
+ .end = 0x27f,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
+ }
+};
+
+#define lp0 io_res[0]
+#define lp1 io_res[1]
+#define lp2 io_res[2]
+
+static const char *proc_arch[] = {
+ "undefined/unknown",
+ "3",
+ "4",
+ "4T",
+ "5",
+ "5T",
+ "5TE",
+ "5TEJ",
+ "6TEJ",
+ "7",
+ "?(11)",
+ "?(12)",
+ "?(13)",
+ "?(14)",
+ "?(15)",
+ "?(16)",
+ "?(17)",
+};
+
+int cpu_architecture(void)
+{
+ int cpu_arch;
+
+ if ((read_cpuid_id() & 0x0008f000) == 0) {
+ cpu_arch = CPU_ARCH_UNKNOWN;
+ } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
+ cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
+ } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
+ cpu_arch = (read_cpuid_id() >> 16) & 7;
+ if (cpu_arch)
+ cpu_arch += CPU_ARCH_ARMv3;
+ } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+ unsigned int mmfr0;
+
+ /* Revised CPUID format. Read the Memory Model Feature
+ * Register 0 and check for VMSAv7 or PMSAv7 */
+ asm("mrc p15, 0, %0, c0, c1, 4"
+ : "=r" (mmfr0));
+ if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
+ (mmfr0 & 0x000000f0) >= 0x00000030)
+ cpu_arch = CPU_ARCH_ARMv7;
+ else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
+ (mmfr0 & 0x000000f0) == 0x00000020)
+ cpu_arch = CPU_ARCH_ARMv6;
+ else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+ } else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+
+ return cpu_arch;
+}
+
+static int cpu_has_aliasing_icache(unsigned int arch)
+{
+ int aliasing_icache;
+ unsigned int id_reg, num_sets, line_size;
+
+ /* arch specifies the register format */
+ switch (arch) {
+ case CPU_ARCH_ARMv7:
+ asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
+ : /* No output operands */
+ : "r" (1));
+ isb();
+ asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
+ : "=r" (id_reg));
+ line_size = 4 << ((id_reg & 0x7) + 2);
+ num_sets = ((id_reg >> 13) & 0x7fff) + 1;
+ aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
+ break;
+ case CPU_ARCH_ARMv6:
+ aliasing_icache = read_cpuid_cachetype() & (1 << 11);
+ break;
+ default:
+ /* I-cache aliases will be handled by D-cache aliasing code */
+ aliasing_icache = 0;
+ }
+
+ return aliasing_icache;
+}
+
+static void __init cacheid_init(void)
+{
+ unsigned int cachetype = read_cpuid_cachetype();
+ unsigned int arch = cpu_architecture();
+
+ if (arch >= CPU_ARCH_ARMv6) {
+ if ((cachetype & (7 << 29)) == 4 << 29) {
+ /* ARMv7 register format */
+ cacheid = CACHEID_VIPT_NONALIASING;
+ if ((cachetype & (3 << 14)) == 1 << 14)
+ cacheid |= CACHEID_ASID_TAGGED;
+ else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
+ } else if (cachetype & (1 << 23)) {
+ cacheid = CACHEID_VIPT_ALIASING;
+ } else {
+ cacheid = CACHEID_VIPT_NONALIASING;
+ if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
+ cacheid |= CACHEID_VIPT_I_ALIASING;
+ }
+ } else {
+ cacheid = CACHEID_VIVT;
+ }
+
+ printk("CPU: %s data cache, %s instruction cache\n",
+ cache_is_vivt() ? "VIVT" :
+ cache_is_vipt_aliasing() ? "VIPT aliasing" :
+ cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
+ cache_is_vivt() ? "VIVT" :
+ icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
+ icache_is_vipt_aliasing() ? "VIPT aliasing" :
+ cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
+}
+
+/*
+ * These functions re-use the assembly code in head.S, which
+ * already provide the required functionality.
+ */
+extern struct proc_info_list *lookup_processor_type(unsigned int);
+
+void __init early_print(const char *str, ...)
+{
+ extern void printascii(const char *);
+ char buf[256];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+#ifdef CONFIG_DEBUG_LL
+ printascii(buf);
+#endif
+ printk("%s", buf);
+}
+
+static void __init feat_v6_fixup(void)
+{
+ int id = read_cpuid_id();
+
+ if ((id & 0xff0f0000) != 0x41070000)
+ return;
+
+ /*
+ * HWCAP_TLS is available only on 1136 r1p0 and later,
+ * see also kuser_get_tls_init.
+ */
+ if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
+ elf_hwcap &= ~HWCAP_TLS;
+}
+
+static void __init setup_processor(void)
+{
+ struct proc_info_list *list;
+
+ /*
+ * locate processor in the list of supported processor
+ * types. The linker builds this table for us from the
+ * entries in arch/arm/mm/proc-*.S
+ */
+ list = lookup_processor_type(read_cpuid_id());
+ if (!list) {
+ printk("CPU configuration botched (ID %08x), unable "
+ "to continue.\n", read_cpuid_id());
+ while (1);
+ }
+
+ cpu_name = list->cpu_name;
+
+#ifdef MULTI_CPU
+ processor = *list->proc;
+#endif
+#ifdef MULTI_TLB
+ cpu_tlb = *list->tlb;
+#endif
+#ifdef MULTI_USER
+ cpu_user = *list->user;
+#endif
+#ifdef MULTI_CACHE
+ cpu_cache = *list->cache;
+#endif
+
+ printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
+ cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
+ proc_arch[cpu_architecture()], cr_alignment);
+
+ sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
+ sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
+ elf_hwcap = list->elf_hwcap;
+#ifndef CONFIG_ARM_THUMB
+ elf_hwcap &= ~HWCAP_THUMB;
+#endif
+
+ feat_v6_fixup();
+
+ cacheid_init();
+ cpu_proc_init();
+}
+
+/*
+ * cpu_init - initialise one CPU.
+ *
+ * cpu_init sets up the per-CPU stacks.
+ */
+void cpu_init(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct stack *stk = &stacks[cpu];
+
+ if (cpu >= NR_CPUS) {
+ printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
+ BUG();
+ }
+
+ /*
+ * Define the placement constraint for the inline asm directive below.
+ * In Thumb-2, msr with an immediate value is not allowed.
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define PLC "r"
+#else
+#define PLC "I"
+#endif
+
+ /*
+ * setup stacks for re-entrant exception handlers
+ */
+ __asm__ (
+ "msr cpsr_c, %1\n\t"
+ "add r14, %0, %2\n\t"
+ "mov sp, r14\n\t"
+ "msr cpsr_c, %3\n\t"
+ "add r14, %0, %4\n\t"
+ "mov sp, r14\n\t"
+ "msr cpsr_c, %5\n\t"
+ "add r14, %0, %6\n\t"
+ "mov sp, r14\n\t"
+ "msr cpsr_c, %7"
+ :
+ : "r" (stk),
+ PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+ "I" (offsetof(struct stack, irq[0])),
+ PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+ "I" (offsetof(struct stack, abt[0])),
+ PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+ "I" (offsetof(struct stack, und[0])),
+ PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+ : "r14");
+}
+
+void __init dump_machine_table(void)
+{
+ struct machine_desc *p;
+
+ early_print("Available machine support:\n\nID (hex)\tNAME\n");
+ for_each_machine_desc(p)
+ early_print("%08x\t%s\n", p->nr, p->name);
+
+ early_print("\nPlease check your kernel config and/or bootloader.\n");
+
+ while (true)
+ /* can't use cpu_relax() here as it may require MMU setup */;
+}
+
+int __init arm_add_memory(phys_addr_t start, unsigned long size)
+{
+ struct membank *bank = &meminfo.bank[meminfo.nr_banks];
+
+ if (meminfo.nr_banks >= NR_BANKS) {
+ printk(KERN_CRIT "NR_BANKS too low, "
+ "ignoring memory at 0x%08llx\n", (long long)start);
+ return -EINVAL;
+ }
+
+ /*
+ * Ensure that start/size are aligned to a page boundary.
+ * Size is appropriately rounded down, start is rounded up.
+ */
+ size -= start & ~PAGE_MASK;
+ bank->start = PAGE_ALIGN(start);
+ bank->size = size & PAGE_MASK;
+
+ /*
+ * Check whether this memory region has non-zero size or
+ * invalid node number.
+ */
+ if (bank->size == 0)
+ return -EINVAL;
+
+ meminfo.nr_banks++;
+ return 0;
+}
+
+/*
+ * Pick out the memory size. We look for mem=size@start,
+ * where start and size are "size[KkMm]"
+ */
+static int __init early_mem(char *p)
+{
+ static int usermem __initdata = 0;
+ unsigned long size;
+ phys_addr_t start;
+ char *endp;
+
+ /*
+ * If the user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ usermem = 1;
+ meminfo.nr_banks = 0;
+ }
+
+ start = PHYS_OFFSET;
+ size = memparse(p, &endp);
+ if (*endp == '@')
+ start = memparse(endp + 1, NULL);
+
+ arm_add_memory(start, size);
+
+ return 0;
+}
+early_param("mem", early_mem);
+
+static void __init
+setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
+{
+#ifdef CONFIG_BLK_DEV_RAM
+ extern int rd_size, rd_image_start, rd_prompt, rd_doload;
+
+ rd_image_start = image_start;
+ rd_prompt = prompt;
+ rd_doload = doload;
+
+ if (rd_sz)
+ rd_size = rd_sz;
+#endif
+}
+
+static void __init request_standard_resources(struct machine_desc *mdesc)
+{
+ struct memblock_region *region;
+ struct resource *res;
+
+ kernel_code.start = virt_to_phys(_text);
+ kernel_code.end = virt_to_phys(_etext - 1);
+ kernel_data.start = virt_to_phys(_sdata);
+ kernel_data.end = virt_to_phys(_end - 1);
+
+ for_each_memblock(memory, region) {
+ res = alloc_bootmem_low(sizeof(*res));
+ res->name = "System RAM";
+ res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+ res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ request_resource(&iomem_resource, res);
+
+ if (kernel_code.start >= res->start &&
+ kernel_code.end <= res->end)
+ request_resource(res, &kernel_code);
+ if (kernel_data.start >= res->start &&
+ kernel_data.end <= res->end)
+ request_resource(res, &kernel_data);
+ }
+
+ if (mdesc->video_start) {
+ video_ram.start = mdesc->video_start;
+ video_ram.end = mdesc->video_end;
+ request_resource(&iomem_resource, &video_ram);
+ }
+
+ /*
+ * Some machines don't have the possibility of ever
+ * possessing lp0, lp1 or lp2
+ */
+ if (mdesc->reserve_lp0)
+ request_resource(&ioport_resource, &lp0);
+ if (mdesc->reserve_lp1)
+ request_resource(&ioport_resource, &lp1);
+ if (mdesc->reserve_lp2)
+ request_resource(&ioport_resource, &lp2);
+}
+
+/*
+ * Tag parsing.
+ *
+ * This is the new way of passing data to the kernel at boot time. Rather
+ * than passing a fixed inflexible structure to the kernel, we pass a list
+ * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
+ * tag for the list to be recognised (to distinguish the tagged list from
+ * a param_struct). The list is terminated with a zero-length tag (this tag
+ * is not parsed in any way).
+ */
+static int __init parse_tag_core(const struct tag *tag)
+{
+ if (tag->hdr.size > 2) {
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+ ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
+ }
+ return 0;
+}
+
+__tagtable(ATAG_CORE, parse_tag_core);
+
+static int __init parse_tag_mem32(const struct tag *tag)
+{
+ return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
+}
+
+__tagtable(ATAG_MEM, parse_tag_mem32);
+
+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
+struct screen_info screen_info = {
+ .orig_video_lines = 30,
+ .orig_video_cols = 80,
+ .orig_video_mode = 0,
+ .orig_video_ega_bx = 0,
+ .orig_video_isVGA = 1,
+ .orig_video_points = 8
+};
+
+static int __init parse_tag_videotext(const struct tag *tag)
+{
+ screen_info.orig_x = tag->u.videotext.x;
+ screen_info.orig_y = tag->u.videotext.y;
+ screen_info.orig_video_page = tag->u.videotext.video_page;
+ screen_info.orig_video_mode = tag->u.videotext.video_mode;
+ screen_info.orig_video_cols = tag->u.videotext.video_cols;
+ screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
+ screen_info.orig_video_lines = tag->u.videotext.video_lines;
+ screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
+ screen_info.orig_video_points = tag->u.videotext.video_points;
+ return 0;
+}
+
+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
+#endif
+
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
+ (tag->u.ramdisk.flags & 2) == 0,
+ tag->u.ramdisk.start, tag->u.ramdisk.size);
+ return 0;
+}
+
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+
+static int __init parse_tag_serialnr(const struct tag *tag)
+{
+ system_serial_low = tag->u.serialnr.low;
+ system_serial_high = tag->u.serialnr.high;
+ return 0;
+}
+
+__tagtable(ATAG_SERIAL, parse_tag_serialnr);
+
+static int __init parse_tag_revision(const struct tag *tag)
+{
+ system_rev = tag->u.revision.rev;
+ return 0;
+}
+
+__tagtable(ATAG_REVISION, parse_tag_revision);
+
+static int __init parse_tag_cmdline(const struct tag *tag)
+{
+#if defined(CONFIG_CMDLINE_EXTEND)
+ strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
+ strlcat(default_command_line, tag->u.cmdline.cmdline,
+ COMMAND_LINE_SIZE);
+#elif defined(CONFIG_CMDLINE_FORCE)
+ pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
+#else
+ strlcpy(default_command_line, tag->u.cmdline.cmdline,
+ COMMAND_LINE_SIZE);
+#endif
+ return 0;
+}
+
+__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
+
+/*
+ * Scan the tag table for this tag, and call its parse function.
+ * The tag table is built by the linker from all the __tagtable
+ * declarations.
+ */
+static int __init parse_tag(const struct tag *tag)
+{
+ extern struct tagtable __tagtable_begin, __tagtable_end;
+ struct tagtable *t;
+
+ for (t = &__tagtable_begin; t < &__tagtable_end; t++)
+ if (tag->hdr.tag == t->tag) {
+ t->parse(tag);
+ break;
+ }
+
+ return t < &__tagtable_end;
+}
+
+/*
+ * Parse all tags in the list, checking both the global and architecture
+ * specific tag tables.
+ */
+static void __init parse_tags(const struct tag *t)
+{
+ for (; t->hdr.size; t = tag_next(t))
+ if (!parse_tag(t))
+ printk(KERN_WARNING
+ "Ignoring unrecognised tag 0x%08x\n",
+ t->hdr.tag);
+}
+
+/*
+ * This holds our defaults.
+ */
+static struct init_tags {
+ struct tag_header hdr1;
+ struct tag_core core;
+ struct tag_header hdr2;
+ struct tag_mem32 mem;
+ struct tag_header hdr3;
+} init_tags __initdata = {
+ { tag_size(tag_core), ATAG_CORE },
+ { 1, PAGE_SIZE, 0xff },
+ { tag_size(tag_mem32), ATAG_MEM },
+ { MEM_SIZE },
+ { 0, ATAG_NONE }
+};
+
+static int __init customize_machine(void)
+{
+ /* customizes platform devices, or adds new ones */
+ if (machine_desc->init_machine)
+ machine_desc->init_machine();
+ return 0;
+}
+arch_initcall(customize_machine);
+
+#ifdef CONFIG_KEXEC
+static inline unsigned long long get_total_mem(void)
+{
+ unsigned long total;
+
+ total = max_low_pfn - min_low_pfn;
+ return total << PAGE_SHIFT;
+}
+
+/**
+ * reserve_crashkernel() - reserves memory are for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by a dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+ unsigned long long crash_size, crash_base;
+ unsigned long long total_mem;
+ int ret;
+
+ total_mem = get_total_mem();
+ ret = parse_crashkernel(boot_command_line, total_mem,
+ &crash_size, &crash_base);
+ if (ret)
+ return;
+
+ ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE);
+ if (ret < 0) {
+ printk(KERN_WARNING "crashkernel reservation failed - "
+ "memory is in use (0x%lx)\n", (unsigned long)crash_base);
+ return;
+ }
+
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crash_base >> 20),
+ (unsigned long)(total_mem >> 20));
+
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+ insert_resource(&iomem_resource, &crashk_res);
+}
+#else
+static inline void reserve_crashkernel(void) {}
+#endif /* CONFIG_KEXEC */
+
+static void __init squash_mem_tags(struct tag *tag)
+{
+ for (; tag->hdr.size; tag = tag_next(tag))
+ if (tag->hdr.tag == ATAG_MEM)
+ tag->hdr.tag = ATAG_NONE;
+}
+
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
+{
+ struct tag *tags = (struct tag *)&init_tags;
+ struct machine_desc *mdesc = NULL, *p;
+ char *from = default_command_line;
+
+ init_tags.mem.start = PHYS_OFFSET;
+
+ /*
+ * locate machine in the list of supported machines.
+ */
+ for_each_machine_desc(p)
+ if (nr == p->nr) {
+ printk("Machine: %s\n", p->name);
+ mdesc = p;
+ break;
+ }
+
+ if (!mdesc) {
+ early_print("\nError: unrecognized/unsupported machine ID"
+ " (r1 = 0x%08x).\n\n", nr);
+ dump_machine_table(); /* does not return */
+ }
+
+ if (__atags_pointer)
+ tags = phys_to_virt(__atags_pointer);
+ else if (mdesc->boot_params) {
+#ifdef CONFIG_MMU
+ /*
+ * We still are executing with a minimal MMU mapping created
+ * with the presumption that the machine default for this
+ * is located in the first MB of RAM. Anything else will
+ * fault and silently hang the kernel at this point.
+ */
+ if (mdesc->boot_params < PHYS_OFFSET ||
+ mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {
+ printk(KERN_WARNING
+ "Default boot params at physical 0x%08lx out of reach\n",
+ mdesc->boot_params);
+ } else
+#endif
+ {
+ tags = phys_to_virt(mdesc->boot_params);
+ }
+ }
+
+#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
+ /*
+ * If we have the old style parameters, convert them to
+ * a tag list.
+ */
+ if (tags->hdr.tag != ATAG_CORE)
+ convert_to_tag_list(tags);
+#endif
+
+ if (tags->hdr.tag != ATAG_CORE) {
+#if defined(CONFIG_OF)
+ /*
+ * If CONFIG_OF is set, then assume this is a reasonably
+ * modern system that should pass boot parameters
+ */
+ early_print("Warning: Neither atags nor dtb found\n");
+#endif
+ tags = (struct tag *)&init_tags;
+ }
+
+ if (mdesc->fixup)
+ mdesc->fixup(mdesc, tags, &from, &meminfo);
+
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (meminfo.nr_banks != 0)
+ squash_mem_tags(tags);
+ save_atags(tags);
+ parse_tags(tags);
+ }
+
+ /* parse_early_param needs a boot_command_line */
+ strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+ return mdesc;
+}
+
+
+void __init setup_arch(char **cmdline_p)
+{
+ struct machine_desc *mdesc;
+
+ unwind_init();
+
+ setup_processor();
+ mdesc = setup_machine_fdt(__atags_pointer);
+ if (!mdesc)
+ mdesc = setup_machine_tags(machine_arch_type);
+ machine_desc = mdesc;
+ machine_name = mdesc->name;
+
+ if (mdesc->soft_reboot)
+ reboot_setup("s");
+
+ init_mm.start_code = (unsigned long) _text;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) _end;
+
+ /* populate cmd_line too for later use, preserving boot_command_line */
+ strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+ *cmdline_p = cmd_line;
+
+ parse_early_param();
+
+ sanity_check_meminfo();
+ arm_memblock_init(&meminfo, mdesc);
+
+ paging_init(mdesc);
+ request_standard_resources(mdesc);
+
+ unflatten_device_tree();
+
+#ifdef CONFIG_SMP
+ if (is_smp())
+ smp_init_cpus();
+#endif
+ reserve_crashkernel();
+
+ cpu_init();
+ tcm_init();
+
+#ifdef CONFIG_MULTI_IRQ_HANDLER
+ handle_arch_irq = mdesc->handle_irq;
+#endif
+
+#ifdef CONFIG_VT
+#if defined(CONFIG_VGA_CONSOLE)
+ conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+#endif
+ early_trap_init();
+
+ if (mdesc->init_early)
+ mdesc->init_early();
+}
+
+
+static int __init topology_init(void)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
+ cpuinfo->cpu.hotpluggable = 1;
+ register_cpu(&cpuinfo->cpu, cpu);
+ }
+
+ return 0;
+}
+subsys_initcall(topology_init);
+
+#ifdef CONFIG_HAVE_PROC_CPU
+static int __init proc_cpu_init(void)
+{
+ struct proc_dir_entry *res;
+
+ res = proc_mkdir("cpu", NULL);
+ if (!res)
+ return -ENOMEM;
+ return 0;
+}
+fs_initcall(proc_cpu_init);
+#endif
+
+static const char *hwcap_str[] = {
+ "swp",
+ "half",
+ "thumb",
+ "26bit",
+ "fastmult",
+ "fpa",
+ "vfp",
+ "edsp",
+ "java",
+ "iwmmxt",
+ "crunch",
+ "thumbee",
+ "neon",
+ "vfpv3",
+ "vfpv3d16",
+ NULL
+};
+
+static int c_show(struct seq_file *m, void *v)
+{
+ int i;
+
+ seq_printf(m, "Processor\t: %s rev %d (%s)\n",
+ cpu_name, read_cpuid_id() & 15, elf_platform);
+
+#if defined(CONFIG_SMP)
+ for_each_online_cpu(i) {
+ /*
+ * glibc reads /proc/cpuinfo to determine the number of
+ * online processors, looking for lines beginning with
+ * "processor". Give glibc what it expects.
+ */
+ seq_printf(m, "processor\t: %d\n", i);
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
+ per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
+ (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
+ }
+#else /* CONFIG_SMP */
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
+#endif
+
+ /* dump out the processor features */
+ seq_puts(m, "Features\t: ");
+
+ for (i = 0; hwcap_str[i]; i++)
+ if (elf_hwcap & (1 << i))
+ seq_printf(m, "%s ", hwcap_str[i]);
+
+ seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
+ seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
+
+ if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
+ /* pre-ARM7 */
+ seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
+ } else {
+ if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
+ /* ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%02x\n",
+ (read_cpuid_id() >> 16) & 127);
+ } else {
+ /* post-ARM7 */
+ seq_printf(m, "CPU variant\t: 0x%x\n",
+ (read_cpuid_id() >> 20) & 15);
+ }
+ seq_printf(m, "CPU part\t: 0x%03x\n",
+ (read_cpuid_id() >> 4) & 0xfff);
+ }
+ seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
+
+ seq_puts(m, "\n");
+
+ seq_printf(m, "Hardware\t: %s\n", machine_name);
+ seq_printf(m, "Revision\t: %04x\n", system_rev);
+ seq_printf(m, "Serial\t\t: %08x%08x\n",
+ system_serial_high, system_serial_low);
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return NULL;
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = c_show
+};
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
new file mode 100644
index 00000000..9e617bd4
--- /dev/null
+++ b/arch/arm/kernel/signal.c
@@ -0,0 +1,796 @@
+/*
+ * linux/arch/arm/kernel/signal.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/signal.h>
+#include <linux/personality.h>
+#include <linux/freezer.h>
+#include <linux/uaccess.h>
+#include <linux/tracehook.h>
+
+#include <asm/elf.h>
+#include <asm/cacheflush.h>
+#include <asm/ucontext.h>
+#include <asm/unistd.h>
+#include <asm/vfp.h>
+
+#include "signal.h"
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/*
+ * For ARM syscalls, we encode the syscall number into the instruction.
+ */
+#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
+#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
+#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
+
+/*
+ * With EABI, the syscall number has to be loaded into r7.
+ */
+#define MOV_R7_NR_SIGRETURN (0xe3a07000 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define MOV_R7_NR_RT_SIGRETURN (0xe3a07000 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+/*
+ * For Thumb syscalls, we pass the syscall number via r7. We therefore
+ * need two 16-bit instructions.
+ */
+#define SWI_THUMB_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE))
+#define SWI_THUMB_RT_SIGRETURN (0xdf00 << 16 | 0x2700 | (__NR_rt_sigreturn - __NR_SYSCALL_BASE))
+
+const unsigned long sigreturn_codes[7] = {
+ MOV_R7_NR_SIGRETURN, SWI_SYS_SIGRETURN, SWI_THUMB_SIGRETURN,
+ MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
+};
+
+/*
+ * Either we support OABI only, or we have EABI with the OABI
+ * compat layer enabled. In the later case we don't know if
+ * user space is EABI or not, and if not we must not clobber r7.
+ * Always using the OABI syscall solves that issue and works for
+ * all those cases.
+ */
+const unsigned long syscall_restart_code[2] = {
+ SWI_SYS_RESTART, /* swi __NR_restart_syscall */
+ 0xe49df004, /* ldr pc, [sp], #4 */
+};
+
+/*
+ * atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
+{
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sighand->siglock);
+ current->saved_sigmask = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ set_restore_sigmask();
+ return -ERESTARTNOHAND;
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction __user *act,
+ struct old_sigaction __user *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_CRUNCH
+static int preserve_crunch_context(struct crunch_sigframe __user *frame)
+{
+ char kbuf[sizeof(*frame) + 8];
+ struct crunch_sigframe *kframe;
+
+ /* the crunch context must be 64 bit aligned */
+ kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ kframe->magic = CRUNCH_MAGIC;
+ kframe->size = CRUNCH_STORAGE_SIZE;
+ crunch_task_copy(current_thread_info(), &kframe->storage);
+ return __copy_to_user(frame, kframe, sizeof(*frame));
+}
+
+static int restore_crunch_context(struct crunch_sigframe __user *frame)
+{
+ char kbuf[sizeof(*frame) + 8];
+ struct crunch_sigframe *kframe;
+
+ /* the crunch context must be 64 bit aligned */
+ kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ if (__copy_from_user(kframe, frame, sizeof(*frame)))
+ return -1;
+ if (kframe->magic != CRUNCH_MAGIC ||
+ kframe->size != CRUNCH_STORAGE_SIZE)
+ return -1;
+ crunch_task_restore(current_thread_info(), &kframe->storage);
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_IWMMXT
+
+static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
+{
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
+
+ /* the iWMMXt context must be 64 bit aligned */
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ kframe->magic = IWMMXT_MAGIC;
+ kframe->size = IWMMXT_STORAGE_SIZE;
+ iwmmxt_task_copy(current_thread_info(), &kframe->storage);
+ return __copy_to_user(frame, kframe, sizeof(*frame));
+}
+
+static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
+{
+ char kbuf[sizeof(*frame) + 8];
+ struct iwmmxt_sigframe *kframe;
+
+ /* the iWMMXt context must be 64 bit aligned */
+ kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
+ if (__copy_from_user(kframe, frame, sizeof(*frame)))
+ return -1;
+ if (kframe->magic != IWMMXT_MAGIC ||
+ kframe->size != IWMMXT_STORAGE_SIZE)
+ return -1;
+ iwmmxt_task_restore(current_thread_info(), &kframe->storage);
+ return 0;
+}
+
+#endif
+
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *h = &thread->vfpstate.hard;
+ const unsigned long magic = VFP_MAGIC;
+ const unsigned long size = VFP_STORAGE_SIZE;
+ int err = 0;
+
+ vfp_sync_hwstate(thread);
+ __put_user_error(magic, &frame->magic, err);
+ __put_user_error(size, &frame->size, err);
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+ sizeof(h->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+ /*
+ * Copy the exception registers.
+ */
+ __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+ __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+ __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+ return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+ struct thread_info *thread = current_thread_info();
+ struct vfp_hard_struct *h = &thread->vfpstate.hard;
+ unsigned long magic;
+ unsigned long size;
+ unsigned long fpexc;
+ int err = 0;
+
+ __get_user_error(magic, &frame->magic, err);
+ __get_user_error(size, &frame->size, err);
+
+ if (err)
+ return -EFAULT;
+ if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+ return -EINVAL;
+
+ vfp_flush_hwstate(thread);
+
+ /*
+ * Copy the floating point registers. There can be unused
+ * registers see asm/hwcap.h for details.
+ */
+ err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+ sizeof(h->fpregs));
+ /*
+ * Copy the status and control register.
+ */
+ __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+ /*
+ * Sanitise and restore the exception registers.
+ */
+ __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+ /* Ensure the VFP is enabled. */
+ fpexc |= FPEXC_EN;
+ /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+ fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+ h->fpexc = fpexc;
+
+ __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+ __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+ return err ? -EFAULT : 0;
+}
+
+#endif
+
+/*
+ * Do a signal return; undo the signal stack. These are aligned to 64-bit.
+ */
+struct sigframe {
+ struct ucontext uc;
+ unsigned long retcode[2];
+};
+
+struct rt_sigframe {
+ struct siginfo info;
+ struct sigframe sig;
+};
+
+static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
+{
+ struct aux_sigframe __user *aux;
+ sigset_t set;
+ int err;
+
+ err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
+ if (err == 0) {
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+
+ __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
+ __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
+ __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
+ __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
+ __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
+ __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
+ __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
+ __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
+ __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
+ __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
+ __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
+ __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
+ __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
+ __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
+ __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
+ __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
+ __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
+
+ err |= !valid_user_regs(regs);
+
+ aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
+#ifdef CONFIG_CRUNCH
+ if (err == 0)
+ err |= restore_crunch_context(&aux->crunch);
+#endif
+#ifdef CONFIG_IWMMXT
+ if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
+ err |= restore_iwmmxt_context(&aux->iwmmxt);
+#endif
+#ifdef CONFIG_VFP
+ if (err == 0)
+ err |= restore_vfp_context(&aux->vfp);
+#endif
+
+ return err;
+}
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+ struct sigframe __user *frame;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ /*
+ * Since we stacked the signal on a 64-bit boundary,
+ * then 'sp' should be word aligned here. If it's
+ * not, then the user is trying to mess with us.
+ */
+ if (regs->ARM_sp & 7)
+ goto badframe;
+
+ frame = (struct sigframe __user *)regs->ARM_sp;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
+ goto badframe;
+
+ if (restore_sigframe(regs, frame))
+ goto badframe;
+
+ return regs->ARM_r0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ /*
+ * Since we stacked the signal on a 64-bit boundary,
+ * then 'sp' should be word aligned here. If it's
+ * not, then the user is trying to mess with us.
+ */
+ if (regs->ARM_sp & 7)
+ goto badframe;
+
+ frame = (struct rt_sigframe __user *)regs->ARM_sp;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
+ goto badframe;
+
+ if (restore_sigframe(regs, &frame->sig))
+ goto badframe;
+
+ if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
+ goto badframe;
+
+ return regs->ARM_r0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static int
+setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
+{
+ struct aux_sigframe __user *aux;
+ int err = 0;
+
+ __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
+ __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
+ __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
+ __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
+ __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
+ __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
+ __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
+ __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
+ __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
+ __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
+ __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
+ __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
+ __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
+ __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
+ __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
+ __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
+ __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
+
+ __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err);
+ __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err);
+ __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err);
+ __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
+
+ err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
+
+ aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
+#ifdef CONFIG_CRUNCH
+ if (err == 0)
+ err |= preserve_crunch_context(&aux->crunch);
+#endif
+#ifdef CONFIG_IWMMXT
+ if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
+ err |= preserve_iwmmxt_context(&aux->iwmmxt);
+#endif
+#ifdef CONFIG_VFP
+ if (err == 0)
+ err |= preserve_vfp_context(&aux->vfp);
+#endif
+ __put_user_error(0, &aux->end_magic, err);
+
+ return err;
+}
+
+static inline void __user *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
+{
+ unsigned long sp = regs->ARM_sp;
+ void __user *frame;
+
+ /*
+ * This is the X/Open sanctioned signal stack switching.
+ */
+ if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ /*
+ * ATPCS B01 mandates 8-byte alignment
+ */
+ frame = (void __user *)((sp - framesize) & ~7);
+
+ /*
+ * Check that we can actually write to the signal frame.
+ */
+ if (!access_ok(VERIFY_WRITE, frame, framesize))
+ frame = NULL;
+
+ return frame;
+}
+
+static int
+setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+ unsigned long __user *rc, void __user *frame, int usig)
+{
+ unsigned long handler = (unsigned long)ka->sa.sa_handler;
+ unsigned long retcode;
+ int thumb = 0;
+ unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
+
+ cpsr |= PSR_ENDSTATE;
+
+ /*
+ * Maybe we need to deliver a 32-bit signal to a 26-bit task.
+ */
+ if (ka->sa.sa_flags & SA_THIRTYTWO)
+ cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
+
+#ifdef CONFIG_ARM_THUMB
+ if (elf_hwcap & HWCAP_THUMB) {
+ /*
+ * The LSB of the handler determines if we're going to
+ * be using THUMB or ARM mode for this signal handler.
+ */
+ thumb = handler & 1;
+
+ if (thumb) {
+ cpsr |= PSR_T_BIT;
+#if __LINUX_ARM_ARCH__ >= 7
+ /* clear the If-Then Thumb-2 execution state */
+ cpsr &= ~PSR_IT_MASK;
+#endif
+ } else
+ cpsr &= ~PSR_T_BIT;
+ }
+#endif
+
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ retcode = (unsigned long)ka->sa.sa_restorer;
+ } else {
+ unsigned int idx = thumb << 1;
+
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ idx += 3;
+
+ if (__put_user(sigreturn_codes[idx], rc) ||
+ __put_user(sigreturn_codes[idx+1], rc+1))
+ return 1;
+
+ if (cpsr & MODE32_BIT) {
+ /*
+ * 32-bit code can use the new high-page
+ * signal return code support.
+ */
+ retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
+ } else {
+ /*
+ * Ensure that the instruction cache sees
+ * the return code written onto the stack.
+ */
+ flush_icache_range((unsigned long)rc,
+ (unsigned long)(rc + 2));
+
+ retcode = ((unsigned long)rc) + thumb;
+ }
+ }
+
+ regs->ARM_r0 = usig;
+ regs->ARM_sp = (unsigned long)frame;
+ regs->ARM_lr = retcode;
+ regs->ARM_pc = handler;
+ regs->ARM_cpsr = cpsr;
+
+ return 0;
+}
+
+static int
+setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs)
+{
+ struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+ int err = 0;
+
+ if (!frame)
+ return 1;
+
+ /*
+ * Set uc.uc_flags to a value which sc.trap_no would never have.
+ */
+ __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
+
+ err |= setup_sigframe(frame, regs, set);
+ if (err == 0)
+ err = setup_return(regs, ka, frame->retcode, frame, usig);
+
+ return err;
+}
+
+static int
+setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+ stack_t stack;
+ int err = 0;
+
+ if (!frame)
+ return 1;
+
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ __put_user_error(0, &frame->sig.uc.uc_flags, err);
+ __put_user_error(NULL, &frame->sig.uc.uc_link, err);
+
+ memset(&stack, 0, sizeof(stack));
+ stack.ss_sp = (void __user *)current->sas_ss_sp;
+ stack.ss_flags = sas_ss_flags(regs->ARM_sp);
+ stack.ss_size = current->sas_ss_size;
+ err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack));
+
+ err |= setup_sigframe(&frame->sig, regs, set);
+ if (err == 0)
+ err = setup_return(regs, ka, frame->sig.retcode, frame, usig);
+
+ if (err == 0) {
+ /*
+ * For realtime signals we must also set the second and third
+ * arguments for the signal handler.
+ * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
+ */
+ regs->ARM_r1 = (unsigned long)&frame->info;
+ regs->ARM_r2 = (unsigned long)&frame->sig.uc;
+ }
+
+ return err;
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static int
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset,
+ struct pt_regs * regs)
+{
+ struct thread_info *thread = current_thread_info();
+ struct task_struct *tsk = current;
+ int usig = sig;
+ int ret;
+
+ /*
+ * translate the signal
+ */
+ if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
+ usig = thread->exec_domain->signal_invmap[usig];
+
+ /*
+ * Set up the stack frame
+ */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ ret = setup_rt_frame(usig, ka, info, oldset, regs);
+ else
+ ret = setup_frame(usig, ka, oldset, regs);
+
+ /*
+ * Check that the resulting registers are actually sane.
+ */
+ ret |= !valid_user_regs(regs);
+
+ if (ret != 0) {
+ force_sigsegv(sig, tsk);
+ return ret;
+ }
+
+ /*
+ * Block the signal if we were successful.
+ */
+ spin_lock_irq(&tsk->sighand->siglock);
+ sigorsets(&tsk->blocked, &tsk->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&tsk->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&tsk->sighand->siglock);
+
+ return 0;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+static void do_signal(struct pt_regs *regs, int syscall)
+{
+ unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
+ struct k_sigaction ka;
+ siginfo_t info;
+ int signr;
+
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if (!user_mode(regs))
+ return;
+
+ /*
+ * If we were from a system call, check for system call restarting...
+ */
+ if (syscall) {
+ continue_addr = regs->ARM_pc;
+ restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4);
+ retval = regs->ARM_r0;
+
+ /*
+ * Prepare for system call restart. We do this here so that a
+ * debugger will see the already changed PSW.
+ */
+ switch (retval) {
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ regs->ARM_r0 = regs->ARM_ORIG_r0;
+ regs->ARM_pc = restart_addr;
+ break;
+ case -ERESTART_RESTARTBLOCK:
+ regs->ARM_r0 = -EINTR;
+ break;
+ }
+ }
+
+ if (try_to_freeze())
+ goto no_signal;
+
+ /*
+ * Get the signal to deliver. When running under ptrace, at this
+ * point the debugger may change all our registers ...
+ */
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ sigset_t *oldset;
+
+ /*
+ * Depending on the signal settings we may need to revert the
+ * decision to restart the system call. But skip this if a
+ * debugger has chosen to restart at a different PC.
+ */
+ if (regs->ARM_pc == restart_addr) {
+ if (retval == -ERESTARTNOHAND
+ || (retval == -ERESTARTSYS
+ && !(ka.sa.sa_flags & SA_RESTART))) {
+ regs->ARM_r0 = -EINTR;
+ regs->ARM_pc = continue_addr;
+ }
+ }
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+ if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
+ /*
+ * A signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TIF_RESTORE_SIGMASK flag.
+ */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ }
+ return;
+ }
+
+ no_signal:
+ if (syscall) {
+ /*
+ * Handle restarting a different system call. As above,
+ * if a debugger has chosen to restart at a different PC,
+ * ignore the restart.
+ */
+ if (retval == -ERESTART_RESTARTBLOCK
+ && regs->ARM_pc == continue_addr) {
+ if (thumb_mode(regs)) {
+ regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
+ regs->ARM_pc -= 2;
+ } else {
+#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
+ regs->ARM_r7 = __NR_restart_syscall;
+ regs->ARM_pc -= 4;
+#else
+ u32 __user *usp;
+
+ regs->ARM_sp -= 4;
+ usp = (u32 __user *)regs->ARM_sp;
+
+ if (put_user(regs->ARM_pc, usp) == 0) {
+ regs->ARM_pc = KERN_RESTART_CODE;
+ } else {
+ regs->ARM_sp += 4;
+ force_sigsegv(0, current);
+ }
+#endif
+ }
+ }
+
+ /* If there's no signal to deliver, we just put the saved sigmask
+ * back.
+ */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+ }
+}
+
+asmlinkage void
+do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+{
+ if (thread_flags & _TIF_SIGPENDING)
+ do_signal(regs, syscall);
+
+ if (thread_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ if (current->replacement_session_keyring)
+ key_replace_session_keyring();
+ }
+}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
new file mode 100644
index 00000000..6fcfe839
--- /dev/null
+++ b/arch/arm/kernel/signal.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/kernel/signal.h
+ *
+ * Copyright (C) 2005-2009 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
+#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
+
+extern const unsigned long sigreturn_codes[7];
+extern const unsigned long syscall_restart_code[2];
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 00000000..6398ead9
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,142 @@
+#include <linux/linkage.h>
+#include <linux/threads.h>
+#include <asm/asm-offsets.h>
+#include <asm/assembler.h>
+#include <asm/glue-cache.h>
+#include <asm/glue-proc.h>
+#include <asm/system.h>
+ .text
+
+/*
+ * Save CPU state for a suspend
+ * r1 = v:p offset
+ * r3 = virtual return function
+ * Note: sp is decremented to allocate space for CPU state on stack
+ * r0-r3,r9,r10,lr corrupted
+ */
+ENTRY(cpu_suspend)
+ mov r9, lr
+#ifdef MULTI_CPU
+ ldr r10, =processor
+ mov r2, sp @ current virtual SP
+ ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
+ ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ add ip, ip, r1 @ convert resume fn to phys
+ stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+ ALT_UP(mov lr, #0)
+ and lr, lr, #15
+ str r2, [r3, lr, lsl #2] @ save phys SP
+#else
+ str r2, [r3] @ save phys SP
+#endif
+ mov lr, pc
+ ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
+#else
+ mov r2, sp @ current virtual SP
+ ldr r0, =cpu_suspend_size
+ sub sp, sp, r0 @ allocate CPU state on stack
+ mov r0, sp @ save pointer
+ stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
+ ldr r3, =sleep_save_sp
+ add r2, sp, r1 @ convert SP to phys
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
+ ALT_UP(mov lr, #0)
+ and lr, lr, #15
+ str r2, [r3, lr, lsl #2] @ save phys SP
+#else
+ str r2, [r3] @ save phys SP
+#endif
+ bl cpu_do_suspend
+#endif
+
+ @ flush data cache
+#ifdef MULTI_CACHE
+ ldr r10, =cpu_cache
+ mov lr, r9
+ ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
+#else
+ mov lr, r9
+ b __cpuc_flush_kern_all
+#endif
+ENDPROC(cpu_suspend)
+ .ltorg
+
+/*
+ * r0 = control register value
+ * r1 = v:p offset (preserved by cpu_do_resume)
+ * r2 = phys page table base
+ * r3 = L1 section flags
+ */
+ENTRY(cpu_resume_mmu)
+ adr r4, cpu_resume_turn_mmu_on
+ mov r4, r4, lsr #20
+ orr r3, r3, r4, lsl #20
+ ldr r5, [r2, r4, lsl #2] @ save old mapping
+ str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
+ sub r2, r2, r1
+ ldr r3, =cpu_resume_after_mmu
+ bic r1, r0, #CR_C @ ensure D-cache is disabled
+ b cpu_resume_turn_mmu_on
+ENDPROC(cpu_resume_mmu)
+ .ltorg
+ .align 5
+cpu_resume_turn_mmu_on:
+ mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
+ mrc p15, 0, r1, c0, c0, 0 @ read id reg
+ mov r1, r1
+ mov r1, r1
+ mov pc, r3 @ jump to virtual address
+ENDPROC(cpu_resume_turn_mmu_on)
+cpu_resume_after_mmu:
+ str r5, [r2, r4, lsl #2] @ restore old mapping
+ mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
+ mov pc, lr
+ENDPROC(cpu_resume_after_mmu)
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow sleep_save_sp to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ .align
+ENTRY(cpu_resume)
+#ifdef CONFIG_SMP
+ adr r0, sleep_save_sp
+ ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
+ ALT_UP(mov r1, #0)
+ and r1, r1, #15
+ ldr r0, [r0, r1, lsl #2] @ stack phys addr
+#else
+ ldr r0, sleep_save_sp @ stack phys addr
+#endif
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
+#ifdef MULTI_CPU
+ @ load v:p, stack, return fn, resume fn
+ ARM( ldmia r0!, {r1, sp, lr, pc} )
+THUMB( ldmia r0!, {r1, r2, r3, r4} )
+THUMB( mov sp, r2 )
+THUMB( mov lr, r3 )
+THUMB( bx r4 )
+#else
+ @ load v:p, stack, return fn
+ ARM( ldmia r0!, {r1, sp, lr} )
+THUMB( ldmia r0!, {r1, r2, lr} )
+THUMB( mov sp, r2 )
+ b cpu_do_resume
+#endif
+ENDPROC(cpu_resume)
+
+sleep_save_sp:
+ .rept CONFIG_NR_CPUS
+ .long 0 @ preserve stack phys ptr here
+ .endr
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
new file mode 100644
index 00000000..24cdba4e
--- /dev/null
+++ b/arch/arm/kernel/smp.c
@@ -0,0 +1,686 @@
+/*
+ * linux/arch/arm/kernel/smp.c
+ *
+ * Copyright (C) 2002 ARM Limited, 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/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/cache.h>
+#include <linux/profile.h>
+#include <linux/errno.h>
+#include <linux/ftrace.h>
+#include <linux/mm.h>
+#include <linux/err.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/seq_file.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/clockchips.h>
+#include <linux/completion.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/cpu.h>
+#include <asm/cputype.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/ptrace.h>
+#include <asm/localtimer.h>
+
+/*
+ * as from 2.5, kernels no longer have an init_tasks structure
+ * so we need some other way of telling a new secondary core
+ * where to place its SVC stack
+ */
+struct secondary_data secondary_data;
+
+enum ipi_msg_type {
+ IPI_TIMER = 2,
+ IPI_RESCHEDULE,
+ IPI_CALL_FUNC,
+ IPI_CALL_FUNC_SINGLE,
+ IPI_CPU_STOP,
+ IPI_CPU_BACKTRACE,
+};
+
+static DECLARE_COMPLETION(cpu_running);
+
+int __cpuinit __cpu_up(unsigned int cpu)
+{
+ struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
+ struct task_struct *idle = ci->idle;
+ pgd_t *pgd;
+ int ret;
+
+ /*
+ * Spawn a new process manually, if not already done.
+ * Grab a pointer to its task struct so we can mess with it
+ */
+ if (!idle) {
+ idle = fork_idle(cpu);
+ if (IS_ERR(idle)) {
+ printk(KERN_ERR "CPU%u: fork() failed\n", cpu);
+ return PTR_ERR(idle);
+ }
+ ci->idle = idle;
+ } else {
+ /*
+ * Since this idle thread is being re-used, call
+ * init_idle() to reinitialize the thread structure.
+ */
+ init_idle(idle, cpu);
+ }
+
+ /*
+ * Allocate initial page tables to allow the new CPU to
+ * enable the MMU safely. This essentially means a set
+ * of our "standard" page tables, with the addition of
+ * a 1:1 mapping for the physical address of the kernel.
+ */
+ pgd = pgd_alloc(&init_mm);
+ if (!pgd)
+ return -ENOMEM;
+
+ if (PHYS_OFFSET != PAGE_OFFSET) {
+#ifndef CONFIG_HOTPLUG_CPU
+ identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end));
+#endif
+ identity_mapping_add(pgd, __pa(_stext), __pa(_etext));
+ identity_mapping_add(pgd, __pa(_sdata), __pa(_edata));
+ }
+
+ /*
+ * We need to tell the secondary core where to find
+ * its stack and the page tables.
+ */
+ secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
+ secondary_data.pgdir = virt_to_phys(pgd);
+ secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
+ __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
+ outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
+
+ /*
+ * Now bring the CPU into our world.
+ */
+ ret = boot_secondary(cpu, idle);
+ if (ret == 0) {
+ /*
+ * CPU was successfully started, wait for it
+ * to come online or time out.
+ */
+ wait_for_completion_timeout(&cpu_running,
+ msecs_to_jiffies(1000));
+
+ if (!cpu_online(cpu)) {
+ pr_crit("CPU%u: failed to come online\n", cpu);
+ ret = -EIO;
+ }
+ } else {
+ pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
+ }
+
+ secondary_data.stack = NULL;
+ secondary_data.pgdir = 0;
+
+ if (PHYS_OFFSET != PAGE_OFFSET) {
+#ifndef CONFIG_HOTPLUG_CPU
+ identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end));
+#endif
+ identity_mapping_del(pgd, __pa(_stext), __pa(_etext));
+ identity_mapping_del(pgd, __pa(_sdata), __pa(_edata));
+ }
+
+ pgd_free(&init_mm, pgd);
+
+ return ret;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void percpu_timer_stop(void);
+
+/*
+ * __cpu_disable runs on the processor to be shutdown.
+ */
+int __cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct task_struct *p;
+ int ret;
+
+ ret = platform_cpu_disable(cpu);
+ if (ret)
+ return ret;
+
+ /*
+ * Take this CPU offline. Once we clear this, we can't return,
+ * and we must not schedule until we're ready to give up the cpu.
+ */
+ set_cpu_online(cpu, false);
+
+ /*
+ * OK - migrate IRQs away from this CPU
+ */
+ migrate_irqs();
+
+ /*
+ * Stop the local timer for this CPU.
+ */
+ percpu_timer_stop();
+
+ /*
+ * Flush user cache and TLB mappings, and then remove this CPU
+ * from the vm mask set of all processes.
+ */
+ flush_cache_all();
+ local_flush_tlb_all();
+
+ read_lock(&tasklist_lock);
+ for_each_process(p) {
+ if (p->mm)
+ cpumask_clear_cpu(cpu, mm_cpumask(p->mm));
+ }
+ read_unlock(&tasklist_lock);
+
+ return 0;
+}
+
+static DECLARE_COMPLETION(cpu_died);
+
+/*
+ * called on the thread which is asking for a CPU to be shutdown -
+ * waits until shutdown has completed, or it is timed out.
+ */
+void __cpu_die(unsigned int cpu)
+{
+ if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
+ pr_err("CPU%u: cpu didn't die\n", cpu);
+ return;
+ }
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+
+ if (!platform_cpu_kill(cpu))
+ printk("CPU%u: unable to kill\n", cpu);
+}
+
+/*
+ * Called from the idle thread for the CPU which has been shutdown.
+ *
+ * Note that we disable IRQs here, but do not re-enable them
+ * before returning to the caller. This is also the behaviour
+ * of the other hotplug-cpu capable cores, so presumably coming
+ * out of idle fixes this.
+ */
+void __ref cpu_die(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ idle_task_exit();
+
+ local_irq_disable();
+ mb();
+
+ /* Tell __cpu_die() that this CPU is now safe to dispose of */
+ complete(&cpu_died);
+
+ /*
+ * actual CPU shutdown procedure is at least platform (if not
+ * CPU) specific.
+ */
+ platform_cpu_die(cpu);
+
+ /*
+ * Do not return to the idle loop - jump back to the secondary
+ * cpu initialisation. There's some initialisation which needs
+ * to be repeated to undo the effects of taking the CPU offline.
+ */
+ __asm__("mov sp, %0\n"
+ " mov fp, #0\n"
+ " b secondary_start_kernel"
+ :
+ : "r" (task_stack_page(current) + THREAD_SIZE - 8));
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+/*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+ */
+static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+{
+ struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
+
+ cpu_info->loops_per_jiffy = loops_per_jiffy;
+}
+
+/*
+ * This is the secondary CPU boot entry. We're using this CPUs
+ * idle thread stack, but a set of temporary page tables.
+ */
+asmlinkage void __cpuinit secondary_start_kernel(void)
+{
+ struct mm_struct *mm = &init_mm;
+ unsigned int cpu = smp_processor_id();
+
+ /*
+ * All kernel threads share the same mm context; grab a
+ * reference and switch to it.
+ */
+ atomic_inc(&mm->mm_count);
+ current->active_mm = mm;
+ cpumask_set_cpu(cpu, mm_cpumask(mm));
+ cpu_switch_mm(mm->pgd, mm);
+ enter_lazy_tlb(mm, current);
+ local_flush_tlb_all();
+
+ printk("CPU%u: Booted secondary processor\n", cpu);
+
+ cpu_init();
+ preempt_disable();
+ trace_hardirqs_off();
+
+ /*
+ * Give the platform a chance to do its own initialisation.
+ */
+ platform_secondary_init(cpu);
+
+ notify_cpu_starting(cpu);
+
+ calibrate_delay();
+
+ smp_store_cpu_info(cpu);
+
+ /*
+ * OK, now it's safe to let the boot CPU continue. Wait for
+ * the CPU migration code to notice that the CPU is online
+ * before we continue - which happens after __cpu_up returns.
+ */
+ set_cpu_online(cpu, true);
+ complete(&cpu_running);
+
+ /*
+ * 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
+ */
+ cpu_idle();
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+ int cpu;
+ unsigned long bogosum = 0;
+
+ for_each_online_cpu(cpu)
+ bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy;
+
+ printk(KERN_INFO "SMP: Total of %d processors activated "
+ "(%lu.%02lu BogoMIPS).\n",
+ num_online_cpus(),
+ bogosum / (500000/HZ),
+ (bogosum / (5000/HZ)) % 100);
+}
+
+void __init smp_prepare_boot_cpu(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ per_cpu(cpu_data, cpu).idle = current;
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned int ncores = num_possible_cpus();
+
+ smp_store_cpu_info(smp_processor_id());
+
+ /*
+ * are we trying to boot more cores than exist?
+ */
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+
+ if (max_cpus > 1) {
+ /*
+ * Enable the local timer or broadcast device for the
+ * boot CPU, but only if we have more than one CPU.
+ */
+ percpu_timer_setup();
+
+ /*
+ * Initialise the SCU if there are more than one CPU
+ * and let them know where to start.
+ */
+ platform_smp_prepare_cpus(max_cpus);
+ }
+}
+
+static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+
+void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
+{
+ smp_cross_call = fn;
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_CALL_FUNC);
+}
+
+void arch_send_call_function_single_ipi(int cpu)
+{
+ smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
+}
+
+static const char *ipi_types[NR_IPI] = {
+#define S(x,s) [x - IPI_TIMER] = s
+ S(IPI_TIMER, "Timer broadcast interrupts"),
+ S(IPI_RESCHEDULE, "Rescheduling interrupts"),
+ 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)
+{
+ unsigned int cpu, i;
+
+ for (i = 0; i < NR_IPI; i++) {
+ seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
+
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ",
+ __get_irq_stat(cpu, ipi_irqs[i]));
+
+ seq_printf(p, " %s\n", ipi_types[i]);
+ }
+}
+
+u64 smp_irq_stat_cpu(unsigned int cpu)
+{
+ u64 sum = 0;
+ int i;
+
+ for (i = 0; i < NR_IPI; i++)
+ sum += __get_irq_stat(cpu, ipi_irqs[i]);
+
+#ifdef CONFIG_LOCAL_TIMERS
+ sum += __get_irq_stat(cpu, local_timer_irqs);
+#endif
+
+ return sum;
+}
+
+/*
+ * Timer (local or broadcast) support
+ */
+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);
+ evt->event_handler(evt);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ int cpu = smp_processor_id();
+
+ if (local_timer_ack()) {
+ __inc_irq_stat(cpu, local_timer_irqs);
+ irq_enter();
+ ipi_timer();
+ irq_exit();
+ }
+
+ set_irq_regs(old_regs);
+}
+
+void show_local_irqs(struct seq_file *p, int prec)
+{
+ unsigned int cpu;
+
+ seq_printf(p, "%*s: ", prec, "LOC");
+
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
+
+ seq_printf(p, " Local timer interrupts\n");
+}
+#endif
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+static void smp_timer_broadcast(const struct cpumask *mask)
+{
+ smp_cross_call(mask, IPI_TIMER);
+}
+#else
+#define smp_timer_broadcast NULL
+#endif
+
+static void broadcast_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
+{
+ evt->name = "dummy_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_DUMMY;
+ evt->rating = 400;
+ evt->mult = 1;
+ evt->set_mode = broadcast_timer_set_mode;
+
+ clockevents_register_device(evt);
+}
+
+void __cpuinit percpu_timer_setup(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+ evt->cpumask = cpumask_of(cpu);
+ evt->broadcast = smp_timer_broadcast;
+
+ if (local_timer_setup(evt))
+ broadcast_timer_setup(evt);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The generic clock events code purposely does not stop the local timer
+ * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
+ * manually here.
+ */
+static void percpu_timer_stop(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+}
+#endif
+
+static DEFINE_SPINLOCK(stop_lock);
+
+/*
+ * ipi_cpu_stop - handle IPI from smp_send_stop()
+ */
+static void ipi_cpu_stop(unsigned int cpu)
+{
+ if (system_state == SYSTEM_BOOTING ||
+ system_state == SYSTEM_RUNNING) {
+ spin_lock(&stop_lock);
+ printk(KERN_CRIT "CPU%u: stopping\n", cpu);
+ dump_stack();
+ spin_unlock(&stop_lock);
+ }
+
+ set_cpu_online(cpu, false);
+
+ local_fiq_disable();
+ local_irq_disable();
+
+ 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
+ */
+asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
+{
+ unsigned int cpu = smp_processor_id();
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
+ __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
+
+ switch (ipinr) {
+ case IPI_TIMER:
+ irq_enter();
+ ipi_timer();
+ irq_exit();
+ break;
+
+ case IPI_RESCHEDULE:
+ scheduler_ipi();
+ 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:
+ printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
+ cpu, ipinr);
+ break;
+ }
+ set_irq_regs(old_regs);
+}
+
+void smp_send_reschedule(int cpu)
+{
+ smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
+}
+
+void smp_send_stop(void)
+{
+ unsigned long timeout;
+
+ if (num_online_cpus() > 1) {
+ cpumask_t mask = cpu_online_map;
+ cpu_clear(smp_processor_id(), mask);
+
+ smp_cross_call(&mask, IPI_CPU_STOP);
+ }
+
+ /* Wait up to one second for other CPUs to stop */
+ timeout = USEC_PER_SEC;
+ while (num_online_cpus() > 1 && timeout--)
+ udelay(1);
+
+ if (num_online_cpus() > 1)
+ pr_warning("SMP: failed to stop secondary CPUs\n");
+}
+
+/*
+ * not supported here
+ */
+int setup_profiling_timer(unsigned int multiplier)
+{
+ return -EINVAL;
+}
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
new file mode 100644
index 00000000..cb7dd40e
--- /dev/null
+++ b/arch/arm/kernel/smp_scu.c
@@ -0,0 +1,85 @@
+/*
+ * linux/arch/arm/kernel/smp_scu.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/init.h>
+#include <linux/io.h>
+
+#include <asm/smp_scu.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+
+#define SCU_CTRL 0x00
+#define SCU_CONFIG 0x04
+#define SCU_CPU_STATUS 0x08
+#define SCU_INVALIDATE 0x0c
+#define SCU_FPGA_REVISION 0x10
+
+/*
+ * Get the number of CPU cores from the SCU configuration
+ */
+unsigned int __init scu_get_core_count(void __iomem *scu_base)
+{
+ unsigned int ncores = __raw_readl(scu_base + SCU_CONFIG);
+ return (ncores & 0x03) + 1;
+}
+
+/*
+ * Enable the SCU
+ */
+void __init scu_enable(void __iomem *scu_base)
+{
+ u32 scu_ctrl;
+
+#ifdef CONFIG_ARM_ERRATA_764369
+ /* Cortex-A9 only */
+ if ((read_cpuid(CPUID_ID) & 0xff0ffff0) == 0x410fc090) {
+ scu_ctrl = __raw_readl(scu_base + 0x30);
+ if (!(scu_ctrl & 1))
+ __raw_writel(scu_ctrl | 0x1, scu_base + 0x30);
+ }
+#endif
+
+ scu_ctrl = __raw_readl(scu_base + SCU_CTRL);
+ /* already enabled? */
+ if (scu_ctrl & 1)
+ return;
+
+ scu_ctrl |= 1;
+ __raw_writel(scu_ctrl, scu_base + SCU_CTRL);
+
+ /*
+ * Ensure that the data accessed by CPU0 before the SCU was
+ * initialised is visible to the other CPUs.
+ */
+ flush_cache_all();
+}
+
+/*
+ * Set the executing CPUs power mode as defined. This will be in
+ * preparation for it executing a WFI instruction.
+ *
+ * This function must be called with preemption disabled, and as it
+ * has the side effect of disabling coherency, caches must have been
+ * flushed. Interrupts must also have been disabled.
+ */
+int scu_power_mode(void __iomem *scu_base, unsigned int mode)
+{
+ unsigned int val;
+ int cpu = smp_processor_id();
+
+ if (mode > 3 || mode == 1 || cpu > 3)
+ return -EINVAL;
+
+ val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
+ val |= mode;
+ __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
+
+ return 0;
+}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
new file mode 100644
index 00000000..7dcb3528
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/kernel/smp_tlb.c
+ *
+ * Copyright (C) 2002 ARM Limited, 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/preempt.h>
+#include <linux/smp.h>
+
+#include <asm/smp_plat.h>
+#include <asm/tlbflush.h>
+
+static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
+ const struct cpumask *mask)
+{
+ preempt_disable();
+
+ smp_call_function_many(mask, func, info, wait);
+ if (cpumask_test_cpu(smp_processor_id(), mask))
+ func(info);
+
+ preempt_enable();
+}
+
+/**********************************************************************/
+
+/*
+ * TLB operations
+ */
+struct tlb_args {
+ struct vm_area_struct *ta_vma;
+ unsigned long ta_start;
+ unsigned long ta_end;
+};
+
+static inline void ipi_flush_tlb_all(void *ignored)
+{
+ local_flush_tlb_all();
+}
+
+static inline void ipi_flush_tlb_mm(void *arg)
+{
+ struct mm_struct *mm = (struct mm_struct *)arg;
+
+ local_flush_tlb_mm(mm);
+}
+
+static inline void ipi_flush_tlb_page(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_page(ta->ta_vma, ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_kernel_page(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_kernel_page(ta->ta_start);
+}
+
+static inline void ipi_flush_tlb_range(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
+}
+
+static inline void ipi_flush_tlb_kernel_range(void *arg)
+{
+ struct tlb_args *ta = (struct tlb_args *)arg;
+
+ local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
+}
+
+void flush_tlb_all(void)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+ else
+ local_flush_tlb_all();
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (tlb_ops_need_broadcast())
+ on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
+ else
+ local_flush_tlb_mm(mm);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_vma = vma;
+ ta.ta_start = uaddr;
+ on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
+ } else
+ local_flush_tlb_page(vma, uaddr);
+}
+
+void flush_tlb_kernel_page(unsigned long kaddr)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_start = kaddr;
+ on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
+ } else
+ local_flush_tlb_kernel_page(kaddr);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_vma = vma;
+ ta.ta_start = start;
+ ta.ta_end = end;
+ on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
+ } else
+ local_flush_tlb_range(vma, start, end);
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ if (tlb_ops_need_broadcast()) {
+ struct tlb_args ta;
+ ta.ta_start = start;
+ ta.ta_end = end;
+ on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
+ } else
+ local_flush_tlb_kernel_range(start, end);
+}
+
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
new file mode 100644
index 00000000..31deb5ae
--- /dev/null
+++ b/arch/arm/kernel/smp_twd.c
@@ -0,0 +1,223 @@
+/*
+ * linux/arch/arm/kernel/smp_twd.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/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/jiffies.h>
+#include <linux/clockchips.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
+
+/* set up by the platform code */
+void __iomem *twd_base;
+static struct clk *twd_clk;
+
+static unsigned long twd_timer_rate;
+
+static struct clock_event_device __percpu **twd_evt;
+
+static void twd_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ unsigned long ctrl;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* timer load already set up */
+ ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
+ | TWD_TIMER_CONTROL_PERIODIC;
+ __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD);
+ gic_enable_ppi(clk->irq);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set, and timer enabled in 'next_event' hook */
+ ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT;
+ gic_enable_ppi(clk->irq);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ ctrl = 0;
+ gic_disable_ppi(clk->irq);
+ }
+
+ __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
+}
+
+static int twd_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
+
+ ctrl |= TWD_TIMER_CONTROL_ENABLE;
+
+ __raw_writel(evt, twd_base + TWD_TIMER_COUNTER);
+ __raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
+
+ return 0;
+}
+
+/*
+ * local_timer_ack: checks for a local timer interrupt.
+ *
+ * If a local timer interrupt has occurred, acknowledge and return 1.
+ * Otherwise, return 0.
+ */
+int twd_timer_ack(void)
+{
+ if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
+ __raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct clk *twd_get_clock(void)
+{
+ return clk_get_sys("smp_twd", NULL);
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Updates clockevent frequency when the cpu frequency changes.
+ * Called on the cpu that is changing frequency with interrupts disabled.
+ */
+static void twd_update_frequency(void *data)
+{
+ twd_timer_rate = clk_get_rate(twd_clk);
+
+ clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
+}
+
+static int twd_cpufreq_transition(struct notifier_block *nb,
+ unsigned long state, void *data)
+{
+ struct cpufreq_freqs *freqs = data;
+
+ /*
+ * The twd clock events must be reprogrammed to account for the new
+ * frequency. The timer is local to a cpu, so cross-call to the
+ * changing cpu.
+ *
+ * Only wait for it to finish, if the cpu is active to avoid
+ * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during
+ * booting of that cpu.
+ */
+ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
+ smp_call_function_single(freqs->cpu, twd_update_frequency,
+ NULL, cpu_active(freqs->cpu));
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block twd_cpufreq_nb = {
+ .notifier_call = twd_cpufreq_transition,
+};
+
+static int twd_cpufreq_init(void)
+{
+ if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
+ return cpufreq_register_notifier(&twd_cpufreq_nb,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ return 0;
+}
+core_initcall(twd_cpufreq_init);
+
+#endif
+static void __cpuinit twd_calibrate_rate(void)
+{
+ unsigned long count;
+ u64 waitjiffies;
+
+ /*
+ * If this is the first time round, we need to work out how fast
+ * the timer ticks
+ */
+ if (twd_timer_rate == 0) {
+ printk(KERN_INFO "Calibrating local timer... ");
+
+ /* Wait for a tick to start */
+ waitjiffies = get_jiffies_64() + 1;
+
+ while (get_jiffies_64() < waitjiffies)
+ udelay(10);
+
+ /* OK, now the tick has started, let's get the timer going */
+ waitjiffies += 5;
+
+ /* enable, no interrupt or reload */
+ __raw_writel(0x1, twd_base + TWD_TIMER_CONTROL);
+
+ /* maximum value */
+ __raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
+
+ while (get_jiffies_64() < waitjiffies)
+ udelay(10);
+
+ count = __raw_readl(twd_base + TWD_TIMER_COUNTER);
+
+ twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
+
+ printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
+ (twd_timer_rate / 10000) % 100);
+ }
+}
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+{
+ struct clock_event_device **this_cpu_clk;
+
+ if (!twd_evt) {
+
+ twd_evt = alloc_percpu(struct clock_event_device *);
+ if (!twd_evt) {
+ pr_err("twd: can't allocate memory\n");
+ return;
+ }
+ }
+
+ if (!twd_clk)
+ twd_clk = twd_get_clock();
+
+ if (!IS_ERR_OR_NULL(twd_clk))
+ twd_timer_rate = clk_get_rate(twd_clk);
+ else
+ twd_calibrate_rate();
+
+ clk->name = "local_timer";
+ clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_C3STOP;
+ clk->rating = 350;
+ clk->set_mode = twd_set_mode;
+ clk->set_next_event = twd_set_next_event;
+
+ this_cpu_clk = __this_cpu_ptr(twd_evt);
+ *this_cpu_clk = clk;
+
+ clockevents_config_and_register(clk, twd_timer_rate,
+ 0xf, 0xffffffff);
+
+ /* Make sure our local interrupt controller has this enabled */
+ gic_enable_ppi(clk->irq);
+}
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
new file mode 100644
index 00000000..381d23a4
--- /dev/null
+++ b/arch/arm/kernel/stacktrace.c
@@ -0,0 +1,131 @@
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+
+#include <asm/stacktrace.h>
+
+#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
+/*
+ * Unwind the current stack frame and store the new register values in the
+ * structure passed as argument. Unwinding is equivalent to a function return,
+ * hence the new PC value rather than LR should be used for backtrace.
+ *
+ * With framepointer enabled, a simple function prologue looks like this:
+ * mov ip, sp
+ * stmdb sp!, {fp, ip, lr, pc}
+ * sub fp, ip, #4
+ *
+ * A simple function epilogue looks like this:
+ * ldm sp, {fp, sp, pc}
+ *
+ * Note that with framepointer enabled, even the leaf functions have the same
+ * prologue and epilogue, therefore we can ignore the LR value in this case.
+ */
+int notrace unwind_frame(struct stackframe *frame)
+{
+ unsigned long high, low;
+ unsigned long fp = frame->fp;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE);
+
+ /* check current frame pointer is within bounds */
+ if (fp < (low + 12) || fp + 4 >= high)
+ return -EINVAL;
+
+ /* restore the registers from the stack frame */
+ frame->fp = *(unsigned long *)(fp - 12);
+ frame->sp = *(unsigned long *)(fp - 8);
+ frame->pc = *(unsigned long *)(fp - 4);
+
+ return 0;
+}
+#endif
+
+void notrace walk_stackframe(struct stackframe *frame,
+ int (*fn)(struct stackframe *, void *), void *data)
+{
+ while (1) {
+ int ret;
+
+ if (fn(frame, data))
+ break;
+ ret = unwind_frame(frame);
+ if (ret < 0)
+ break;
+ }
+}
+EXPORT_SYMBOL(walk_stackframe);
+
+#ifdef CONFIG_STACKTRACE
+struct stack_trace_data {
+ struct stack_trace *trace;
+ unsigned int no_sched_functions;
+ unsigned int skip;
+};
+
+static int save_trace(struct stackframe *frame, void *d)
+{
+ struct stack_trace_data *data = d;
+ struct stack_trace *trace = data->trace;
+ unsigned long addr = frame->pc;
+
+ if (data->no_sched_functions && in_sched_functions(addr))
+ return 0;
+ if (data->skip) {
+ data->skip--;
+ return 0;
+ }
+
+ trace->entries[trace->nr_entries++] = addr;
+
+ return trace->nr_entries >= trace->max_entries;
+}
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ struct stack_trace_data data;
+ struct stackframe frame;
+
+ data.trace = trace;
+ data.skip = trace->skip;
+
+ 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.
+ */
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+ return;
+#else
+ 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");
+
+ data.no_sched_functions = 0;
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)save_stack_trace_tsk;
+ }
+
+ walk_stackframe(&frame, save_trace, &data);
+ if (trace->nr_entries < trace->max_entries)
+ trace->entries[trace->nr_entries++] = ULONG_MAX;
+}
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ save_stack_trace_tsk(current, trace);
+}
+EXPORT_SYMBOL_GPL(save_stack_trace);
+#endif
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 00000000..40ee7e50
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,267 @@
+/*
+ * linux/arch/arm/kernel/swp_emulate.c
+ *
+ * Copyright (C) 2009 ARM Limited
+ * __user_* functions adapted from include/asm/uaccess.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Implements emulation of the SWP/SWPB instructions using load-exclusive and
+ * store-exclusive for processors that have them disabled (or future ones that
+ * might not implement them).
+ *
+ * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
+ * Where: Rt = destination
+ * Rt2 = source
+ * Rn = address
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/syscalls.h>
+#include <linux/perf_event.h>
+
+#include <asm/traps.h>
+#include <asm/uaccess.h>
+
+/*
+ * Error-checking SWP macros implemented using ldrex{b}/strex{b}
+ */
+#define __user_swpX_asm(data, addr, res, temp, B) \
+ __asm__ __volatile__( \
+ " mov %2, %1\n" \
+ "0: ldrex"B" %1, [%3]\n" \
+ "1: strex"B" %0, %2, [%3]\n" \
+ " cmp %0, #0\n" \
+ " movne %0, %4\n" \
+ "2:\n" \
+ " .section .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, %5\n" \
+ " b 2b\n" \
+ " .previous\n" \
+ " .section __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 0b, 3b\n" \
+ " .long 1b, 3b\n" \
+ " .previous" \
+ : "=&r" (res), "+r" (data), "=&r" (temp) \
+ : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
+ : "cc", "memory")
+
+#define __user_swp_asm(data, addr, res, temp) \
+ __user_swpX_asm(data, addr, res, temp, "")
+#define __user_swpb_asm(data, addr, res, temp) \
+ __user_swpX_asm(data, addr, res, temp, "b")
+
+/*
+ * Macros/defines for extracting register numbers from instruction.
+ */
+#define EXTRACT_REG_NUM(instruction, offset) \
+ (((instruction) & (0xf << (offset))) >> (offset))
+#define RN_OFFSET 16
+#define RT_OFFSET 12
+#define RT2_OFFSET 0
+/*
+ * Bit 22 of the instruction encoding distinguishes between
+ * the SWP and SWPB variants (bit set means SWPB).
+ */
+#define TYPE_SWPB (1 << 22)
+
+static unsigned long swpcounter;
+static unsigned long swpbcounter;
+static unsigned long abtcounter;
+static pid_t previous_pid;
+
+#ifdef CONFIG_PROC_FS
+static int proc_read_status(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *p = page;
+ int len;
+
+ p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
+ p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
+ p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
+ if (previous_pid != 0)
+ p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
+
+ len = (p - page) - off;
+ if (len < 0)
+ len = 0;
+
+ *eof = (len <= count) ? 1 : 0;
+ *start = page + off;
+
+ return len;
+}
+#endif
+
+/*
+ * Set up process info to signal segmentation fault - called on access error.
+ */
+static void set_segfault(struct pt_regs *regs, unsigned long addr)
+{
+ siginfo_t info;
+
+ if (find_vma(current->mm, addr) == NULL)
+ info.si_code = SEGV_MAPERR;
+ else
+ info.si_code = SEGV_ACCERR;
+
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_addr = (void *) instruction_pointer(regs);
+
+ pr_debug("SWP{B} emulation: access caused memory abort!\n");
+ arm_notify_die("Illegal memory access", regs, &info, 0, 0);
+
+ abtcounter++;
+}
+
+static int emulate_swpX(unsigned int address, unsigned int *data,
+ unsigned int type)
+{
+ unsigned int res = 0;
+
+ if ((type != TYPE_SWPB) && (address & 0x3)) {
+ /* SWP to unaligned address not permitted */
+ pr_debug("SWP instruction on unaligned pointer!\n");
+ return -EFAULT;
+ }
+
+ while (1) {
+ unsigned long temp;
+
+ /*
+ * Barrier required between accessing protected resource and
+ * releasing a lock for it. Legacy code might not have done
+ * this, and we cannot determine that this is not the case
+ * being emulated, so insert always.
+ */
+ smp_mb();
+
+ if (type == TYPE_SWPB)
+ __user_swpb_asm(*data, address, res, temp);
+ else
+ __user_swp_asm(*data, address, res, temp);
+
+ if (likely(res != -EAGAIN) || signal_pending(current))
+ break;
+
+ cond_resched();
+ }
+
+ if (res == 0) {
+ /*
+ * Barrier also required between acquiring a lock for a
+ * protected resource and accessing the resource. Inserted for
+ * same reason as above.
+ */
+ smp_mb();
+
+ if (type == TYPE_SWPB)
+ swpbcounter++;
+ else
+ swpcounter++;
+ }
+
+ return res;
+}
+
+/*
+ * swp_handler logs the id of calling process, dissects the instruction, sanity
+ * checks the memory location, calls emulate_swpX for the actual operation and
+ * deals with fixup/error handling before returning
+ */
+static int swp_handler(struct pt_regs *regs, unsigned int instr)
+{
+ unsigned int address, destreg, data, type;
+ unsigned int res = 0;
+
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
+
+ if (current->pid != previous_pid) {
+ pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
+ current->comm, (unsigned long)current->pid);
+ previous_pid = current->pid;
+ }
+
+ address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
+ data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
+ destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
+
+ type = instr & TYPE_SWPB;
+
+ pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
+ EXTRACT_REG_NUM(instr, RN_OFFSET), address,
+ destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
+
+ /* Check access in reasonable access range for both SWP and SWPB */
+ if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
+ pr_debug("SWP{B} emulation: access to %p not allowed!\n",
+ (void *)address);
+ res = -EFAULT;
+ } else {
+ res = emulate_swpX(address, &data, type);
+ }
+
+ if (res == 0) {
+ /*
+ * On successful emulation, revert the adjustment to the PC
+ * made in kernel/traps.c in order to resume execution at the
+ * instruction following the SWP{B}.
+ */
+ regs->ARM_pc += 4;
+ regs->uregs[destreg] = data;
+ } else if (res == -EFAULT) {
+ /*
+ * Memory errors do not mean emulation failed.
+ * Set up signal info to return SEGV, then return OK
+ */
+ set_segfault(regs, address);
+ }
+
+ return 0;
+}
+
+/*
+ * Only emulate SWP/SWPB executed in ARM state/User mode.
+ * The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
+ */
+static struct undef_hook swp_hook = {
+ .instr_mask = 0x0fb00ff0,
+ .instr_val = 0x01000090,
+ .cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
+ .cpsr_val = USR_MODE,
+ .fn = swp_handler
+};
+
+/*
+ * Register handler and create status file in /proc/cpu
+ * Invoked as late_initcall, since not needed before init spawned.
+ */
+static int __init swp_emulation_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *res;
+
+ res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
+
+ if (!res)
+ return -ENOMEM;
+
+ res->read_proc = proc_read_status;
+#endif /* CONFIG_PROC_FS */
+
+ printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
+ register_undef_hook(&swp_hook);
+
+ return 0;
+}
+
+late_initcall(swp_emulation_init);
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
new file mode 100644
index 00000000..0264ab43
--- /dev/null
+++ b/arch/arm/kernel/sys_arm.c
@@ -0,0 +1,133 @@
+/*
+ * linux/arch/arm/kernel/sys_arm.c
+ *
+ * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
+ * Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/arm
+ * platform.
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/ipc.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+/* Fork a new task - this creates a new program thread.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_fork(struct pt_regs *regs)
+{
+#ifdef CONFIG_MMU
+ return do_fork(SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
+#else
+ /* can not support in nommu mode */
+ return(-EINVAL);
+#endif
+}
+
+/* Clone a task - this clones the calling program thread.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+ int __user *parent_tidptr, int tls_val,
+ int __user *child_tidptr, struct pt_regs *regs)
+{
+ if (!newsp)
+ newsp = regs->ARM_sp;
+
+ return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
+}
+
+asmlinkage int sys_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
+}
+
+/* sys_execve() executes a new program.
+ * This is called indirectly via a small wrapper
+ */
+asmlinkage int sys_execve(const char __user *filenamei,
+ const char __user *const __user *argv,
+ const char __user *const __user *envp, struct pt_regs *regs)
+{
+ int error;
+ char * filename;
+
+ filename = getname(filenamei);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+
+int kernel_execve(const char *filename,
+ const char *const argv[],
+ const char *const envp[])
+{
+ struct pt_regs regs;
+ int ret;
+
+ memset(&regs, 0, sizeof(struct pt_regs));
+ ret = do_execve(filename,
+ (const char __user *const __user *)argv,
+ (const char __user *const __user *)envp, &regs);
+ if (ret < 0)
+ goto out;
+
+ /*
+ * Save argc to the register structure for userspace.
+ */
+ regs.ARM_r0 = ret;
+
+ /*
+ * We were successful. We won't be returning to our caller, but
+ * instead to user space by manipulating the kernel stack.
+ */
+ asm( "add r0, %0, %1\n\t"
+ "mov r1, %2\n\t"
+ "mov r2, %3\n\t"
+ "bl memmove\n\t" /* copy regs to top of stack */
+ "mov r8, #0\n\t" /* not a syscall */
+ "mov r9, %0\n\t" /* thread structure */
+ "mov sp, r0\n\t" /* reposition stack pointer */
+ "b ret_to_user"
+ :
+ : "r" (current_thread_info()),
+ "Ir" (THREAD_START_SP - sizeof(regs)),
+ "r" (&regs),
+ "Ir" (sizeof(regs))
+ : "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
+
+ out:
+ return ret;
+}
+EXPORT_SYMBOL(kernel_execve);
+
+/*
+ * Since loff_t is a 64 bit type we avoid a lot of ABI hassle
+ * with a different argument ordering.
+ */
+asmlinkage long sys_arm_fadvise64_64(int fd, int advice,
+ loff_t offset, loff_t len)
+{
+ return sys_fadvise64_64(fd, offset, len, advice);
+}
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
new file mode 100644
index 00000000..af0aaebf
--- /dev/null
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -0,0 +1,453 @@
+/*
+ * arch/arm/kernel/sys_oabi-compat.c
+ *
+ * Compatibility wrappers for syscalls that are used from
+ * old ABI user space binaries with an EABI kernel.
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 7, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * The legacy ABI and the new ARM EABI have different rules making some
+ * syscalls incompatible especially with structure arguments.
+ * Most notably, Eabi says 64-bit members should be 64-bit aligned instead of
+ * simply word aligned. EABI also pads structures to the size of the largest
+ * member it contains instead of the invariant 32-bit.
+ *
+ * The following syscalls are affected:
+ *
+ * sys_stat64:
+ * sys_lstat64:
+ * sys_fstat64:
+ * sys_fstatat64:
+ *
+ * struct stat64 has different sizes and some members are shifted
+ * Compatibility wrappers are needed for them and provided below.
+ *
+ * sys_fcntl64:
+ *
+ * struct flock64 has different sizes and some members are shifted
+ * A compatibility wrapper is needed and provided below.
+ *
+ * sys_statfs64:
+ * sys_fstatfs64:
+ *
+ * struct statfs64 has extra padding with EABI growing its size from
+ * 84 to 88. This struct is now __attribute__((packed,aligned(4)))
+ * with a small assembly wrapper to force the sz argument to 84 if it is 88
+ * to avoid copying the extra padding over user space unexpecting it.
+ *
+ * sys_newuname:
+ *
+ * struct new_utsname has no padding with EABI. No problem there.
+ *
+ * sys_epoll_ctl:
+ * sys_epoll_wait:
+ *
+ * struct epoll_event has its second member shifted also affecting the
+ * structure size. Compatibility wrappers are needed and provided below.
+ *
+ * sys_ipc:
+ * sys_semop:
+ * sys_semtimedop:
+ *
+ * struct sembuf loses its padding with EABI. Since arrays of them are
+ * used they have to be copyed to remove the padding. Compatibility wrappers
+ * provided below.
+ *
+ * sys_bind:
+ * sys_connect:
+ * sys_sendmsg:
+ * sys_sendto:
+ * sys_socketcall:
+ *
+ * struct sockaddr_un loses its padding with EABI. Since the size of the
+ * structure is used as a validation test in unix_mkname(), we need to
+ * change the length argument to 110 whenever it is 112. Compatibility
+ * wrappers provided below.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/eventpoll.h>
+#include <linux/sem.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/ipc.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+struct oldabi_stat64 {
+ unsigned long long st_dev;
+ unsigned int __pad1;
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned int __pad2;
+
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long long st_blocks;
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+} __attribute__ ((packed,aligned(4)));
+
+static long cp_oldabi_stat64(struct kstat *stat,
+ struct oldabi_stat64 __user *statbuf)
+{
+ struct oldabi_stat64 tmp;
+
+ tmp.st_dev = huge_encode_dev(stat->dev);
+ tmp.__pad1 = 0;
+ tmp.__st_ino = stat->ino;
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ tmp.st_uid = stat->uid;
+ tmp.st_gid = stat->gid;
+ tmp.st_rdev = huge_encode_dev(stat->rdev);
+ tmp.st_size = stat->size;
+ tmp.st_blocks = stat->blocks;
+ tmp.__pad2 = 0;
+ tmp.st_blksize = stat->blksize;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+ tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+ tmp.st_ctime = stat->ctime.tv_sec;
+ tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+ tmp.st_ino = stat->ino;
+ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
+}
+
+asmlinkage long sys_oabi_stat64(const char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_stat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_lstat64(const char __user * filename,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_lstat(filename, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_fstat64(unsigned long fd,
+ struct oldabi_stat64 __user * statbuf)
+{
+ struct kstat stat;
+ int error = vfs_fstat(fd, &stat);
+ if (!error)
+ error = cp_oldabi_stat64(&stat, statbuf);
+ return error;
+}
+
+asmlinkage long sys_oabi_fstatat64(int dfd,
+ const char __user *filename,
+ struct oldabi_stat64 __user *statbuf,
+ int flag)
+{
+ struct kstat stat;
+ int error;
+
+ error = vfs_fstatat(dfd, filename, &stat, flag);
+ if (error)
+ return error;
+ return cp_oldabi_stat64(&stat, statbuf);
+}
+
+struct oabi_flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+{
+ struct oabi_flock64 user;
+ struct flock64 kernel;
+ mm_segment_t fs = USER_DS; /* initialized to kill a warning */
+ unsigned long local_arg = arg;
+ int ret;
+
+ switch (cmd) {
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+ if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
+ sizeof(user)))
+ return -EFAULT;
+ kernel.l_type = user.l_type;
+ kernel.l_whence = user.l_whence;
+ kernel.l_start = user.l_start;
+ kernel.l_len = user.l_len;
+ kernel.l_pid = user.l_pid;
+ local_arg = (unsigned long)&kernel;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ }
+
+ ret = sys_fcntl64(fd, cmd, local_arg);
+
+ switch (cmd) {
+ case F_GETLK64:
+ if (!ret) {
+ user.l_type = kernel.l_type;
+ user.l_whence = kernel.l_whence;
+ user.l_start = kernel.l_start;
+ user.l_len = kernel.l_len;
+ user.l_pid = kernel.l_pid;
+ if (copy_to_user((struct oabi_flock64 __user *)arg,
+ &user, sizeof(user)))
+ ret = -EFAULT;
+ }
+ case F_SETLK64:
+ case F_SETLKW64:
+ set_fs(fs);
+ }
+
+ return ret;
+}
+
+struct oabi_epoll_event {
+ __u32 events;
+ __u64 data;
+} __attribute__ ((packed,aligned(4)));
+
+asmlinkage long sys_oabi_epoll_ctl(int epfd, int op, int fd,
+ struct oabi_epoll_event __user *event)
+{
+ struct oabi_epoll_event user;
+ struct epoll_event kernel;
+ mm_segment_t fs;
+ long ret;
+
+ if (op == EPOLL_CTL_DEL)
+ return sys_epoll_ctl(epfd, op, fd, NULL);
+ if (copy_from_user(&user, event, sizeof(user)))
+ return -EFAULT;
+ kernel.events = user.events;
+ kernel.data = user.data;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_ctl(epfd, op, fd, &kernel);
+ set_fs(fs);
+ return ret;
+}
+
+asmlinkage long sys_oabi_epoll_wait(int epfd,
+ struct oabi_epoll_event __user *events,
+ int maxevents, int timeout)
+{
+ struct epoll_event *kbuf;
+ mm_segment_t fs;
+ long ret, err, i;
+
+ if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
+ return -EINVAL;
+ kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout);
+ set_fs(fs);
+ err = 0;
+ for (i = 0; i < ret; i++) {
+ __put_user_error(kbuf[i].events, &events->events, err);
+ __put_user_error(kbuf[i].data, &events->data, err);
+ events++;
+ }
+ kfree(kbuf);
+ return err ? -EFAULT : ret;
+}
+
+struct oabi_sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+ unsigned short __pad;
+};
+
+asmlinkage long sys_oabi_semtimedop(int semid,
+ struct oabi_sembuf __user *tsops,
+ unsigned nsops,
+ const struct timespec __user *timeout)
+{
+ struct sembuf *sops;
+ struct timespec local_timeout;
+ long err;
+ int i;
+
+ if (nsops < 1 || nsops > SEMOPM)
+ return -EINVAL;
+ sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
+ if (!sops)
+ return -ENOMEM;
+ err = 0;
+ for (i = 0; i < nsops; i++) {
+ __get_user_error(sops[i].sem_num, &tsops->sem_num, err);
+ __get_user_error(sops[i].sem_op, &tsops->sem_op, err);
+ __get_user_error(sops[i].sem_flg, &tsops->sem_flg, err);
+ tsops++;
+ }
+ if (timeout) {
+ /* copy this as well before changing domain protection */
+ err |= copy_from_user(&local_timeout, timeout, sizeof(*timeout));
+ timeout = &local_timeout;
+ }
+ if (err) {
+ err = -EFAULT;
+ } else {
+ mm_segment_t fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_semtimedop(semid, sops, nsops, timeout);
+ set_fs(fs);
+ }
+ kfree(sops);
+ return err;
+}
+
+asmlinkage long sys_oabi_semop(int semid, struct oabi_sembuf __user *tsops,
+ unsigned nsops)
+{
+ return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
+}
+
+asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
+ void __user *ptr, long fifth)
+{
+ switch (call & 0xffff) {
+ case SEMOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second, NULL);
+ case SEMTIMEDOP:
+ return sys_oabi_semtimedop(first,
+ (struct oabi_sembuf __user *)ptr,
+ second,
+ (const struct timespec __user *)fifth);
+ default:
+ return sys_ipc(call, first, second, third, ptr, fifth);
+ }
+}
+
+asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_bind(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_connect(fd, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendto(int fd, void __user *buff,
+ size_t len, unsigned flags,
+ struct sockaddr __user *addr,
+ int addrlen)
+{
+ sa_family_t sa_family;
+ if (addrlen == 112 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ addrlen = 110;
+ return sys_sendto(fd, buff, len, flags, addr, addrlen);
+}
+
+asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags)
+{
+ struct sockaddr __user *addr;
+ int msg_namelen;
+ sa_family_t sa_family;
+ if (msg &&
+ get_user(msg_namelen, &msg->msg_namelen) == 0 &&
+ msg_namelen == 112 &&
+ get_user(addr, &msg->msg_name) == 0 &&
+ get_user(sa_family, &addr->sa_family) == 0 &&
+ sa_family == AF_UNIX)
+ {
+ /*
+ * HACK ALERT: there is a limit to how much backward bending
+ * we should do for what is actually a transitional
+ * compatibility layer. This already has known flaws with
+ * a few ioctls that we don't intend to fix. Therefore
+ * consider this blatent hack as another one... and take care
+ * to run for cover. In most cases it will "just work fine".
+ * If it doesn't, well, tough.
+ */
+ put_user(110, &msg->msg_namelen);
+ }
+ return sys_sendmsg(fd, msg, flags);
+}
+
+asmlinkage long sys_oabi_socketcall(int call, unsigned long __user *args)
+{
+ unsigned long r = -EFAULT, a[6];
+
+ switch (call) {
+ case SYS_BIND:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_bind(a[0], (struct sockaddr __user *)a[1], a[2]);
+ break;
+ case SYS_CONNECT:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_connect(a[0], (struct sockaddr __user *)a[1], a[2]);
+ break;
+ case SYS_SENDTO:
+ if (copy_from_user(a, args, 6 * sizeof(long)) == 0)
+ r = sys_oabi_sendto(a[0], (void __user *)a[1], a[2], a[3],
+ (struct sockaddr __user *)a[4], a[5]);
+ break;
+ case SYS_SENDMSG:
+ if (copy_from_user(a, args, 3 * sizeof(long)) == 0)
+ r = sys_oabi_sendmsg(a[0], (struct msghdr __user *)a[1], a[2]);
+ break;
+ default:
+ r = sys_socketcall(call, args);
+ }
+
+ return r;
+}
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
new file mode 100644
index 00000000..f5cf660e
--- /dev/null
+++ b/arch/arm/kernel/tcm.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * TCM memory handling for ARM systems
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <linux/ioport.h>
+#include <linux/genalloc.h>
+#include <linux/string.h> /* memcpy */
+#include <asm/cputype.h>
+#include <asm/mach/map.h>
+#include <asm/memory.h>
+#include "tcm.h"
+
+static struct gen_pool *tcm_pool;
+
+/* TCM section definitions from the linker */
+extern char __itcm_start, __sitcm_text, __eitcm_text;
+extern char __dtcm_start, __sdtcm_data, __edtcm_data;
+
+/* These will be increased as we run */
+u32 dtcm_end = DTCM_OFFSET;
+u32 itcm_end = ITCM_OFFSET;
+
+/*
+ * TCM memory resources
+ */
+static struct resource dtcm_res = {
+ .name = "DTCM RAM",
+ .start = DTCM_OFFSET,
+ .end = DTCM_OFFSET,
+ .flags = IORESOURCE_MEM
+};
+
+static struct resource itcm_res = {
+ .name = "ITCM RAM",
+ .start = ITCM_OFFSET,
+ .end = ITCM_OFFSET,
+ .flags = IORESOURCE_MEM
+};
+
+static struct map_desc dtcm_iomap[] __initdata = {
+ {
+ .virtual = DTCM_OFFSET,
+ .pfn = __phys_to_pfn(DTCM_OFFSET),
+ .length = 0,
+ .type = MT_MEMORY_DTCM
+ }
+};
+
+static struct map_desc itcm_iomap[] __initdata = {
+ {
+ .virtual = ITCM_OFFSET,
+ .pfn = __phys_to_pfn(ITCM_OFFSET),
+ .length = 0,
+ .type = MT_MEMORY_ITCM
+ }
+};
+
+/*
+ * Allocate a chunk of TCM memory
+ */
+void *tcm_alloc(size_t len)
+{
+ unsigned long vaddr;
+
+ if (!tcm_pool)
+ return NULL;
+
+ vaddr = gen_pool_alloc(tcm_pool, len);
+ if (!vaddr)
+ return NULL;
+
+ return (void *) vaddr;
+}
+EXPORT_SYMBOL(tcm_alloc);
+
+/*
+ * Free a chunk of TCM memory
+ */
+void tcm_free(void *addr, size_t len)
+{
+ gen_pool_free(tcm_pool, (unsigned long) addr, len);
+}
+EXPORT_SYMBOL(tcm_free);
+
+static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks,
+ u32 *offset)
+{
+ const int tcm_sizes[16] = { 0, -1, -1, 4, 8, 16, 32, 64, 128,
+ 256, 512, 1024, -1, -1, -1, -1 };
+ u32 tcm_region;
+ int tcm_size;
+
+ /*
+ * If there are more than one TCM bank of this type,
+ * select the TCM bank to operate on in the TCM selection
+ * register.
+ */
+ if (banks > 1)
+ asm("mcr p15, 0, %0, c9, c2, 0"
+ : /* No output operands */
+ : "r" (bank));
+
+ /* Read the special TCM region register c9, 0 */
+ if (!type)
+ asm("mrc p15, 0, %0, c9, c1, 0"
+ : "=r" (tcm_region));
+ else
+ asm("mrc p15, 0, %0, c9, c1, 1"
+ : "=r" (tcm_region));
+
+ tcm_size = tcm_sizes[(tcm_region >> 2) & 0x0f];
+ if (tcm_size < 0) {
+ pr_err("CPU: %sTCM%d of unknown size\n",
+ type ? "I" : "D", bank);
+ return -EINVAL;
+ } else if (tcm_size > 32) {
+ pr_err("CPU: %sTCM%d larger than 32k found\n",
+ type ? "I" : "D", bank);
+ return -EINVAL;
+ } else {
+ pr_info("CPU: found %sTCM%d %dk @ %08x, %senabled\n",
+ type ? "I" : "D",
+ bank,
+ tcm_size,
+ (tcm_region & 0xfffff000U),
+ (tcm_region & 1) ? "" : "not ");
+ }
+
+ /* Force move the TCM bank to where we want it, enable */
+ tcm_region = *offset | (tcm_region & 0x00000ffeU) | 1;
+
+ if (!type)
+ asm("mcr p15, 0, %0, c9, c1, 0"
+ : /* No output operands */
+ : "r" (tcm_region));
+ else
+ asm("mcr p15, 0, %0, c9, c1, 1"
+ : /* No output operands */
+ : "r" (tcm_region));
+
+ /* Increase offset */
+ *offset += (tcm_size << 10);
+
+ pr_info("CPU: moved %sTCM%d %dk to %08x, enabled\n",
+ type ? "I" : "D",
+ bank,
+ tcm_size,
+ (tcm_region & 0xfffff000U));
+ return 0;
+}
+
+/*
+ * This initializes the TCM memory
+ */
+void __init tcm_init(void)
+{
+ u32 tcm_status = read_cpuid_tcmstatus();
+ u8 dtcm_banks = (tcm_status >> 16) & 0x03;
+ u8 itcm_banks = (tcm_status & 0x03);
+ char *start;
+ char *end;
+ char *ram;
+ int ret;
+ int i;
+
+ /* Setup DTCM if present */
+ if (dtcm_banks > 0) {
+ for (i = 0; i < dtcm_banks; i++) {
+ ret = setup_tcm_bank(0, i, dtcm_banks, &dtcm_end);
+ if (ret)
+ return;
+ }
+ dtcm_res.end = dtcm_end - 1;
+ request_resource(&iomem_resource, &dtcm_res);
+ dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET;
+ iotable_init(dtcm_iomap, 1);
+ /* Copy data from RAM to DTCM */
+ start = &__sdtcm_data;
+ end = &__edtcm_data;
+ ram = &__dtcm_start;
+ /* This means you compiled more code than fits into DTCM */
+ BUG_ON((end - start) > (dtcm_end - DTCM_OFFSET));
+ memcpy(start, ram, (end-start));
+ pr_debug("CPU DTCM: copied data from %p - %p\n", start, end);
+ }
+
+ /* Setup ITCM if present */
+ if (itcm_banks > 0) {
+ for (i = 0; i < itcm_banks; i++) {
+ ret = setup_tcm_bank(1, i, itcm_banks, &itcm_end);
+ if (ret)
+ return;
+ }
+ itcm_res.end = itcm_end - 1;
+ request_resource(&iomem_resource, &itcm_res);
+ itcm_iomap[0].length = itcm_end - ITCM_OFFSET;
+ iotable_init(itcm_iomap, 1);
+ /* Copy code from RAM to ITCM */
+ start = &__sitcm_text;
+ end = &__eitcm_text;
+ ram = &__itcm_start;
+ /* This means you compiled more code than fits into ITCM */
+ BUG_ON((end - start) > (itcm_end - ITCM_OFFSET));
+ memcpy(start, ram, (end-start));
+ pr_debug("CPU ITCM: copied code from %p - %p\n", start, end);
+ }
+}
+
+/*
+ * This creates the TCM memory pool and has to be done later,
+ * during the core_initicalls, since the allocator is not yet
+ * up and running when the first initialization runs.
+ */
+static int __init setup_tcm_pool(void)
+{
+ u32 tcm_status = read_cpuid_tcmstatus();
+ u32 dtcm_pool_start = (u32) &__edtcm_data;
+ u32 itcm_pool_start = (u32) &__eitcm_text;
+ int ret;
+
+ /*
+ * Set up malloc pool, 2^2 = 4 bytes granularity since
+ * the TCM is sometimes just 4 KiB. NB: pages and cache
+ * line alignments does not matter in TCM!
+ */
+ tcm_pool = gen_pool_create(2, -1);
+
+ pr_debug("Setting up TCM memory pool\n");
+
+ /* Add the rest of DTCM to the TCM pool */
+ if (tcm_status & (0x03 << 16)) {
+ if (dtcm_pool_start < dtcm_end) {
+ ret = gen_pool_add(tcm_pool, dtcm_pool_start,
+ dtcm_end - dtcm_pool_start, -1);
+ if (ret) {
+ pr_err("CPU DTCM: could not add DTCM " \
+ "remainder to pool!\n");
+ return ret;
+ }
+ pr_debug("CPU DTCM: Added %08x bytes @ %08x to " \
+ "the TCM memory pool\n",
+ dtcm_end - dtcm_pool_start,
+ dtcm_pool_start);
+ }
+ }
+
+ /* Add the rest of ITCM to the TCM pool */
+ if (tcm_status & 0x03) {
+ if (itcm_pool_start < itcm_end) {
+ ret = gen_pool_add(tcm_pool, itcm_pool_start,
+ itcm_end - itcm_pool_start, -1);
+ if (ret) {
+ pr_err("CPU ITCM: could not add ITCM " \
+ "remainder to pool!\n");
+ return ret;
+ }
+ pr_debug("CPU ITCM: Added %08x bytes @ %08x to " \
+ "the TCM memory pool\n",
+ itcm_end - itcm_pool_start,
+ itcm_pool_start);
+ }
+ }
+ return 0;
+}
+
+core_initcall(setup_tcm_pool);
diff --git a/arch/arm/kernel/tcm.h b/arch/arm/kernel/tcm.h
new file mode 100644
index 00000000..8015ad43
--- /dev/null
+++ b/arch/arm/kernel/tcm.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * TCM memory handling for ARM systems
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+
+#ifdef CONFIG_HAVE_TCM
+void __init tcm_init(void);
+#else
+/* No TCM support, just blank inlines to be optimized out */
+inline void tcm_init(void)
+{
+}
+#endif
diff --git a/arch/arm/kernel/thumbee.c b/arch/arm/kernel/thumbee.c
new file mode 100644
index 00000000..9cb7aaca
--- /dev/null
+++ b/arch/arm/kernel/thumbee.c
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/kernel/thumbee.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/thread_notify.h>
+
+/*
+ * Access to the ThumbEE Handler Base register
+ */
+static inline unsigned long teehbr_read(void)
+{
+ unsigned long v;
+ asm("mrc p14, 6, %0, c1, c0, 0\n" : "=r" (v));
+ return v;
+}
+
+static inline void teehbr_write(unsigned long v)
+{
+ asm("mcr p14, 6, %0, c1, c0, 0\n" : : "r" (v));
+}
+
+static int thumbee_notifier(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = t;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ thread->thumbee_state = 0;
+ break;
+ case THREAD_NOTIFY_SWITCH:
+ current_thread_info()->thumbee_state = teehbr_read();
+ teehbr_write(thread->thumbee_state);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block thumbee_notifier_block = {
+ .notifier_call = thumbee_notifier,
+};
+
+static int __init thumbee_init(void)
+{
+ unsigned long pfr0;
+ unsigned int cpu_arch = cpu_architecture();
+
+ if (cpu_arch < CPU_ARCH_ARMv7)
+ return 0;
+
+ /* processor feature register 0 */
+ asm("mrc p15, 0, %0, c0, c1, 0\n" : "=r" (pfr0));
+ if ((pfr0 & 0x0000f000) != 0x00001000)
+ return 0;
+
+ printk(KERN_INFO "ThumbEE CPU extension supported.\n");
+ elf_hwcap |= HWCAP_THUMBEE;
+ thread_register_notifier(&thumbee_notifier_block);
+
+ return 0;
+}
+
+late_initcall(thumbee_init);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
new file mode 100644
index 00000000..cb634c3e
--- /dev/null
+++ b/arch/arm/kernel/time.c
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/kernel/time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ * Modifications for ARM (C) 1994-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the ARM-specific time handling details:
+ * reading the RTC at bootup, etc...
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/timex.h>
+#include <linux/errno.h>
+#include <linux/profile.h>
+#include <linux/syscore_ops.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
+
+#include <linux/mc146818rtc.h>
+
+#include <asm/leds.h>
+#include <asm/thread_info.h>
+#include <asm/sched_clock.h>
+#include <asm/stacktrace.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+/*
+ * Our system timer.
+ */
+static struct sys_timer *system_timer;
+
+#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
+/* this needs a better home */
+DEFINE_SPINLOCK(rtc_lock);
+
+#ifdef CONFIG_RTC_DRV_CMOS_MODULE
+EXPORT_SYMBOL(rtc_lock);
+#endif
+#endif /* pc-style 'CMOS' RTC support */
+
+/* change this if you have some constant time drift */
+#define USECS_PER_JIFFY (1000000/HZ)
+
+#ifdef CONFIG_SMP
+unsigned long profile_pc(struct pt_regs *regs)
+{
+ struct stackframe frame;
+
+ if (!in_lock_functions(regs->ARM_pc))
+ return regs->ARM_pc;
+
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ frame.pc = regs->ARM_pc;
+ do {
+ int ret = unwind_frame(&frame);
+ if (ret < 0)
+ return 0;
+ } while (in_lock_functions(frame.pc));
+
+ return frame.pc;
+}
+EXPORT_SYMBOL(profile_pc);
+#endif
+
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+u32 arch_gettimeoffset(void)
+{
+ if (system_timer->offset != NULL)
+ return system_timer->offset() * 1000;
+
+ return 0;
+}
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
+
+#ifdef CONFIG_LEDS_TIMER
+static inline void do_leds(void)
+{
+ static unsigned int count = HZ/2;
+
+ if (--count == 0) {
+ count = HZ/2;
+ leds_event(led_timer);
+ }
+}
+#else
+#define do_leds()
+#endif
+
+
+#ifndef CONFIG_GENERIC_CLOCKEVENTS
+/*
+ * Kernel system timer support.
+ */
+void timer_tick(void)
+{
+ profile_tick(CPU_PROFILING);
+ do_leds();
+ xtime_update(1);
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(get_irq_regs()));
+#endif
+}
+#endif
+
+#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
+static int timer_suspend(void)
+{
+ if (system_timer->suspend)
+ system_timer->suspend();
+
+ return 0;
+}
+
+static void timer_resume(void)
+{
+ if (system_timer->resume)
+ system_timer->resume();
+}
+#else
+#define timer_suspend NULL
+#define timer_resume NULL
+#endif
+
+static struct syscore_ops timer_syscore_ops = {
+ .suspend = timer_suspend,
+ .resume = timer_resume,
+};
+
+static int __init timer_init_syscore_ops(void)
+{
+ register_syscore_ops(&timer_syscore_ops);
+
+ return 0;
+}
+
+device_initcall(timer_init_syscore_ops);
+
+void __init time_init(void)
+{
+ system_timer = machine_desc->timer;
+ system_timer->init();
+#ifdef CONFIG_HAVE_SCHED_CLOCK
+ sched_clock_postinit();
+#endif
+}
+
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
new file mode 100644
index 00000000..56b27153
--- /dev/null
+++ b/arch/arm/kernel/traps.c
@@ -0,0 +1,796 @@
+/*
+ * linux/arch/arm/kernel/traps.c
+ *
+ * Copyright (C) 1995-2009 Russell King
+ * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 'traps.c' handles hardware exceptions after we have saved some state in
+ * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
+ * kill the offending process.
+ */
+#include <linux/signal.h>
+#include <linux/personality.h>
+#include <linux/kallsyms.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/hardirq.h>
+#include <linux/kdebug.h>
+#include <linux/module.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+#include <asm/system.h>
+#include <asm/unistd.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+#include <asm/tls.h>
+
+#include "signal.h"
+
+static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
+
+void *vectors_page;
+
+#ifdef CONFIG_DEBUG_USER
+unsigned int user_debug;
+
+static int __init user_debug_setup(char *str)
+{
+ get_option(&str, &user_debug);
+ return 1;
+}
+__setup("user_debug=", user_debug_setup);
+#endif
+
+static void dump_mem(const char *, const char *, unsigned long, unsigned long);
+
+void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
+{
+#ifdef CONFIG_KALLSYMS
+ printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+#else
+ printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+#endif
+
+ if (in_exception_text(where))
+ dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
+}
+
+#ifndef CONFIG_ARM_UNWIND
+/*
+ * Stack pointers should always be within the kernels view of
+ * physical memory. If it is not there, then we can't dump
+ * out any information relating to the stack.
+ */
+static int verify_stack(unsigned long sp)
+{
+ if (sp < PAGE_OFFSET ||
+ (sp > (unsigned long)high_memory && high_memory != NULL))
+ return -EFAULT;
+
+ return 0;
+}
+#endif
+
+/*
+ * Dump out the contents of some memory nicely...
+ */
+static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ unsigned long top)
+{
+ unsigned long first;
+ mm_segment_t fs;
+ int i;
+
+ /*
+ * We need to switch to kernel mode so that we can use __get_user
+ * to safely read from kernel space. Note that we now dump the
+ * code first, just in case the backtrace kills us.
+ */
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
+
+ for (first = bottom & ~31; first < top; first += 32) {
+ unsigned long p;
+ char str[sizeof(" 12345678") * 8 + 1];
+
+ memset(str, ' ', sizeof(str));
+ str[sizeof(str) - 1] = '\0';
+
+ for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
+ if (p >= bottom && p < top) {
+ unsigned long val;
+ if (__get_user(val, (unsigned long *)p) == 0)
+ sprintf(str + i * 9, " %08lx", val);
+ else
+ sprintf(str + i * 9, " ????????");
+ }
+ }
+ printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
+ }
+
+ set_fs(fs);
+}
+
+static void dump_instr(const char *lvl, struct pt_regs *regs)
+{
+ unsigned long addr = instruction_pointer(regs);
+ const int thumb = thumb_mode(regs);
+ const int width = thumb ? 4 : 8;
+ mm_segment_t fs;
+ char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
+ int i;
+
+ /*
+ * We need to switch to kernel mode so that we can use __get_user
+ * to safely read from kernel space. Note that we now dump the
+ * code first, just in case the backtrace kills us.
+ */
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ for (i = -4; i < 1 + !!thumb; i++) {
+ unsigned int val, bad;
+
+ if (thumb)
+ bad = __get_user(val, &((u16 *)addr)[i]);
+ else
+ bad = __get_user(val, &((u32 *)addr)[i]);
+
+ if (!bad)
+ p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
+ width, val);
+ else {
+ p += sprintf(p, "bad PC value");
+ break;
+ }
+ }
+ printk("%sCode: %s\n", lvl, str);
+
+ set_fs(fs);
+}
+
+#ifdef CONFIG_ARM_UNWIND
+static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+ unwind_backtrace(regs, tsk);
+}
+#else
+static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+ unsigned int fp, mode;
+ int ok = 1;
+
+ printk("Backtrace: ");
+
+ if (!tsk)
+ tsk = current;
+
+ if (regs) {
+ fp = regs->ARM_fp;
+ mode = processor_mode(regs);
+ } else if (tsk != current) {
+ fp = thread_saved_fp(tsk);
+ mode = 0x10;
+ } else {
+ asm("mov %0, fp" : "=r" (fp) : : "cc");
+ mode = 0x10;
+ }
+
+ if (!fp) {
+ printk("no frame pointer");
+ ok = 0;
+ } else if (verify_stack(fp)) {
+ printk("invalid frame pointer 0x%08x", fp);
+ ok = 0;
+ } else if (fp < (unsigned long)end_of_stack(tsk))
+ printk("frame pointer underflow");
+ printk("\n");
+
+ if (ok)
+ c_backtrace(fp, mode);
+}
+#endif
+
+void dump_stack(void)
+{
+ dump_backtrace(NULL, NULL);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+void show_stack(struct task_struct *tsk, unsigned long *sp)
+{
+ dump_backtrace(NULL, tsk);
+ barrier();
+}
+
+#ifdef CONFIG_PREEMPT
+#define S_PREEMPT " PREEMPT"
+#else
+#define S_PREEMPT ""
+#endif
+#ifdef CONFIG_SMP
+#define S_SMP " SMP"
+#else
+#define S_SMP ""
+#endif
+
+static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
+{
+ struct task_struct *tsk = thread->task;
+ static int die_counter;
+ int ret;
+
+ printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
+ str, err, ++die_counter);
+
+ /* trap and error numbers are mostly meaningless on ARM */
+ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
+ if (ret == NOTIFY_STOP)
+ return ret;
+
+ print_modules();
+ __show_regs(regs);
+ printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
+ TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
+
+ if (!user_mode(regs) || in_interrupt()) {
+ dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
+ THREAD_SIZE + (unsigned long)task_stack_page(tsk));
+ dump_backtrace(regs, tsk);
+ dump_instr(KERN_EMERG, regs);
+ }
+
+ return ret;
+}
+
+static DEFINE_SPINLOCK(die_lock);
+
+/*
+ * This function is protected against re-entrancy.
+ */
+void die(const char *str, struct pt_regs *regs, int err)
+{
+ struct thread_info *thread = current_thread_info();
+ int ret;
+
+ oops_enter();
+
+ spin_lock_irq(&die_lock);
+ console_verbose();
+ bust_spinlocks(1);
+ ret = __die(str, err, thread, regs);
+
+ if (regs && kexec_should_crash(thread->task))
+ crash_kexec(regs);
+
+ bust_spinlocks(0);
+ add_taint(TAINT_DIE);
+ spin_unlock_irq(&die_lock);
+ oops_exit();
+
+ if (in_interrupt())
+ panic("Fatal exception in interrupt");
+ if (panic_on_oops)
+ panic("Fatal exception");
+ if (ret != NOTIFY_STOP)
+ do_exit(SIGSEGV);
+}
+
+void arm_notify_die(const char *str, struct pt_regs *regs,
+ struct siginfo *info, unsigned long err, unsigned long trap)
+{
+ if (user_mode(regs)) {
+ current->thread.error_code = err;
+ current->thread.trap_no = trap;
+
+ force_sig_info(info->si_signo, info, current);
+ } else {
+ die(str, regs, err);
+ }
+}
+
+static LIST_HEAD(undef_hook);
+static DEFINE_SPINLOCK(undef_lock);
+
+void register_undef_hook(struct undef_hook *hook)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&undef_lock, flags);
+ list_add(&hook->node, &undef_hook);
+ spin_unlock_irqrestore(&undef_lock, flags);
+}
+
+void unregister_undef_hook(struct undef_hook *hook)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&undef_lock, flags);
+ list_del(&hook->node);
+ spin_unlock_irqrestore(&undef_lock, flags);
+}
+
+static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
+{
+ struct undef_hook *hook;
+ unsigned long flags;
+ int (*fn)(struct pt_regs *regs, unsigned int instr) = NULL;
+
+ spin_lock_irqsave(&undef_lock, flags);
+ list_for_each_entry(hook, &undef_hook, node)
+ if ((instr & hook->instr_mask) == hook->instr_val &&
+ (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val)
+ fn = hook->fn;
+ spin_unlock_irqrestore(&undef_lock, flags);
+
+ return fn ? fn(regs, instr) : 1;
+}
+
+asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
+{
+ unsigned int correction = thumb_mode(regs) ? 2 : 4;
+ unsigned int instr;
+ siginfo_t info;
+ void __user *pc;
+
+ /*
+ * According to the ARM ARM, PC is 2 or 4 bytes ahead,
+ * depending whether we're in Thumb mode or not.
+ * Correct this offset.
+ */
+ regs->ARM_pc -= correction;
+
+ pc = (void __user *)instruction_pointer(regs);
+
+ if (processor_mode(regs) == SVC_MODE) {
+ instr = *(u32 *) pc;
+ } else if (thumb_mode(regs)) {
+ get_user(instr, (u16 __user *)pc);
+ } else {
+ get_user(instr, (u32 __user *)pc);
+ }
+
+ if (call_undef_hook(regs, instr) == 0)
+ return;
+
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_UNDEFINED) {
+ printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
+ current->comm, task_pid_nr(current), pc);
+ dump_instr(KERN_INFO, regs);
+ }
+#endif
+
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLOPC;
+ info.si_addr = pc;
+
+ arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
+}
+
+asmlinkage void do_unexp_fiq (struct pt_regs *regs)
+{
+ printk("Hmm. Unexpected FIQ received, but trying to continue\n");
+ printk("You may have a hardware problem...\n");
+}
+
+/*
+ * bad_mode handles the impossible case in the vectors. If you see one of
+ * these, then it's extremely serious, and could mean you have buggy hardware.
+ * It never returns, and never tries to sync. We hope that we can at least
+ * dump out some state information...
+ */
+asmlinkage void bad_mode(struct pt_regs *regs, int reason)
+{
+ console_verbose();
+
+ printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
+
+ die("Oops - bad mode", regs, 0);
+ local_irq_disable();
+ panic("bad mode");
+}
+
+static int bad_syscall(int n, struct pt_regs *regs)
+{
+ struct thread_info *thread = current_thread_info();
+ siginfo_t info;
+
+ if ((current->personality & PER_MASK) != PER_LINUX &&
+ thread->exec_domain->handler) {
+ thread->exec_domain->handler(n, regs);
+ return regs->ARM_r0;
+ }
+
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_SYSCALL) {
+ printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
+ task_pid_nr(current), current->comm, n);
+ dump_instr(KERN_ERR, regs);
+ }
+#endif
+
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLTRP;
+ info.si_addr = (void __user *)instruction_pointer(regs) -
+ (thumb_mode(regs) ? 2 : 4);
+
+ arm_notify_die("Oops - bad syscall", regs, &info, n, 0);
+
+ return regs->ARM_r0;
+}
+
+static inline void
+do_cache_op(unsigned long start, unsigned long end, int flags)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct vm_area_struct *vma;
+
+ if (end < start || flags)
+ return;
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, start);
+ if (vma && vma->vm_start < end) {
+ if (start < vma->vm_start)
+ start = vma->vm_start;
+ if (end > vma->vm_end)
+ end = vma->vm_end;
+
+ up_read(&mm->mmap_sem);
+ flush_cache_user_range(start, end);
+ return;
+ }
+ up_read(&mm->mmap_sem);
+}
+
+/*
+ * Handle all unrecognised system calls.
+ * 0x9f0000 - 0x9fffff are some more esoteric system calls
+ */
+#define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE)
+asmlinkage int arm_syscall(int no, struct pt_regs *regs)
+{
+ struct thread_info *thread = current_thread_info();
+ siginfo_t info;
+
+ if ((no >> 16) != (__ARM_NR_BASE>> 16))
+ return bad_syscall(no, regs);
+
+ switch (no & 0xffff) {
+ case 0: /* branch through 0 */
+ info.si_signo = SIGSEGV;
+ info.si_errno = 0;
+ info.si_code = SEGV_MAPERR;
+ info.si_addr = NULL;
+
+ arm_notify_die("branch through zero", regs, &info, 0, 0);
+ return 0;
+
+ case NR(breakpoint): /* SWI BREAK_POINT */
+ regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
+ ptrace_break(current, regs);
+ return regs->ARM_r0;
+
+ /*
+ * Flush a region from virtual address 'r0' to virtual address 'r1'
+ * _exclusive_. There is no alignment requirement on either address;
+ * user space does not need to know the hardware cache layout.
+ *
+ * r2 contains flags. It should ALWAYS be passed as ZERO until it
+ * is defined to be something else. For now we ignore it, but may
+ * the fires of hell burn in your belly if you break this rule. ;)
+ *
+ * (at a later date, we may want to allow this call to not flush
+ * various aspects of the cache. Passing '0' will guarantee that
+ * everything necessary gets flushed to maintain consistency in
+ * the specified region).
+ */
+ case NR(cacheflush):
+ do_cache_op(regs->ARM_r0, regs->ARM_r1, regs->ARM_r2);
+ return 0;
+
+ case NR(usr26):
+ if (!(elf_hwcap & HWCAP_26BIT))
+ break;
+ regs->ARM_cpsr &= ~MODE32_BIT;
+ return regs->ARM_r0;
+
+ case NR(usr32):
+ if (!(elf_hwcap & HWCAP_26BIT))
+ break;
+ regs->ARM_cpsr |= MODE32_BIT;
+ return regs->ARM_r0;
+
+ case NR(set_tls):
+ thread->tp_value = regs->ARM_r0;
+ if (tls_emu)
+ return 0;
+ if (has_tls_reg) {
+ asm ("mcr p15, 0, %0, c13, c0, 3"
+ : : "r" (regs->ARM_r0));
+ } else {
+ /*
+ * User space must never try to access this directly.
+ * Expect your app to break eventually if you do so.
+ * The user helper at 0xffff0fe0 must be used instead.
+ * (see entry-armv.S for details)
+ */
+ *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
+ }
+ return 0;
+
+#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
+ /*
+ * Atomically store r1 in *r2 if *r2 is equal to r0 for user space.
+ * Return zero in r0 if *MEM was changed or non-zero if no exchange
+ * happened. Also set the user C flag accordingly.
+ * If access permissions have to be fixed up then non-zero is
+ * returned and the operation has to be re-attempted.
+ *
+ * *NOTE*: This is a ghost syscall private to the kernel. Only the
+ * __kuser_cmpxchg code in entry-armv.S should be aware of its
+ * existence. Don't ever use this from user code.
+ */
+ case NR(cmpxchg):
+ for (;;) {
+ extern void do_DataAbort(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs);
+ unsigned long val;
+ unsigned long addr = regs->ARM_r2;
+ struct mm_struct *mm = current->mm;
+ pgd_t *pgd; pmd_t *pmd; pte_t *pte;
+ spinlock_t *ptl;
+
+ regs->ARM_cpsr &= ~PSR_C_BIT;
+ down_read(&mm->mmap_sem);
+ pgd = pgd_offset(mm, addr);
+ if (!pgd_present(*pgd))
+ goto bad_access;
+ pmd = pmd_offset(pgd, addr);
+ if (!pmd_present(*pmd))
+ goto bad_access;
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) {
+ pte_unmap_unlock(pte, ptl);
+ goto bad_access;
+ }
+ val = *(unsigned long *)addr;
+ val -= regs->ARM_r0;
+ if (val == 0) {
+ *(unsigned long *)addr = regs->ARM_r1;
+ regs->ARM_cpsr |= PSR_C_BIT;
+ }
+ pte_unmap_unlock(pte, ptl);
+ up_read(&mm->mmap_sem);
+ return val;
+
+ bad_access:
+ up_read(&mm->mmap_sem);
+ /* simulate a write access fault */
+ do_DataAbort(addr, 15 + (1 << 11), regs);
+ }
+#endif
+
+ default:
+ /* Calls 9f00xx..9f07ff are defined to return -ENOSYS
+ if not implemented, rather than raising SIGILL. This
+ way the calling program can gracefully determine whether
+ a feature is supported. */
+ if ((no & 0xffff) <= 0x7ff)
+ return -ENOSYS;
+ break;
+ }
+#ifdef CONFIG_DEBUG_USER
+ /*
+ * experience shows that these seem to indicate that
+ * something catastrophic has happened
+ */
+ if (user_debug & UDBG_SYSCALL) {
+ printk("[%d] %s: arm syscall %d\n",
+ task_pid_nr(current), current->comm, no);
+ dump_instr("", regs);
+ if (user_mode(regs)) {
+ __show_regs(regs);
+ c_backtrace(regs->ARM_fp, processor_mode(regs));
+ }
+ }
+#endif
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLTRP;
+ info.si_addr = (void __user *)instruction_pointer(regs) -
+ (thumb_mode(regs) ? 2 : 4);
+
+ arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0);
+ return 0;
+}
+
+#ifdef CONFIG_TLS_REG_EMUL
+
+/*
+ * We might be running on an ARMv6+ processor which should have the TLS
+ * register but for some reason we can't use it, or maybe an SMP system
+ * using a pre-ARMv6 processor (there are apparently a few prototypes like
+ * that in existence) and therefore access to that register must be
+ * emulated.
+ */
+
+static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
+{
+ int reg = (instr >> 12) & 15;
+ if (reg == 15)
+ return 1;
+ regs->uregs[reg] = current_thread_info()->tp_value;
+ regs->ARM_pc += 4;
+ return 0;
+}
+
+static struct undef_hook arm_mrc_hook = {
+ .instr_mask = 0x0fff0fff,
+ .instr_val = 0x0e1d0f70,
+ .cpsr_mask = PSR_T_BIT,
+ .cpsr_val = 0,
+ .fn = get_tp_trap,
+};
+
+static int __init arm_mrc_hook_init(void)
+{
+ register_undef_hook(&arm_mrc_hook);
+ return 0;
+}
+
+late_initcall(arm_mrc_hook_init);
+
+#endif
+
+void __bad_xchg(volatile void *ptr, int size)
+{
+ printk("xchg: bad data size: pc 0x%p, ptr 0x%p, size %d\n",
+ __builtin_return_address(0), ptr, size);
+ BUG();
+}
+EXPORT_SYMBOL(__bad_xchg);
+
+/*
+ * A data abort trap was taken, but we did not handle the instruction.
+ * Try to abort the user program, or panic if it was the kernel.
+ */
+asmlinkage void
+baddataabort(int code, unsigned long instr, struct pt_regs *regs)
+{
+ unsigned long addr = instruction_pointer(regs);
+ siginfo_t info;
+
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_BADABORT) {
+ printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
+ task_pid_nr(current), current->comm, code, instr);
+ dump_instr(KERN_ERR, regs);
+ show_pte(current->mm, addr);
+ }
+#endif
+
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_ILLOPC;
+ info.si_addr = (void __user *)addr;
+
+ arm_notify_die("unknown data abort code", regs, &info, instr, 0);
+}
+
+void __attribute__((noreturn)) __bug(const char *file, int line)
+{
+ printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
+ *(int *)0 = 0;
+
+ /* Avoid "noreturn function does return" */
+ for (;;);
+}
+EXPORT_SYMBOL(__bug);
+
+void __readwrite_bug(const char *fn)
+{
+ printk("%s called, but not implemented\n", fn);
+ BUG();
+}
+EXPORT_SYMBOL(__readwrite_bug);
+
+void __pte_error(const char *file, int line, pte_t pte)
+{
+ printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
+}
+
+void __pmd_error(const char *file, int line, pmd_t pmd)
+{
+ printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
+}
+
+void __pgd_error(const char *file, int line, pgd_t pgd)
+{
+ printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
+}
+
+asmlinkage void __div0(void)
+{
+ printk("Division by zero in kernel.\n");
+ dump_stack();
+}
+EXPORT_SYMBOL(__div0);
+
+void abort(void)
+{
+ BUG();
+
+ /* if that doesn't kill us, halt */
+ panic("Oops failed to kill thread");
+}
+EXPORT_SYMBOL(abort);
+
+void __init trap_init(void)
+{
+ return;
+}
+
+static void __init kuser_get_tls_init(unsigned long vectors)
+{
+ /*
+ * vectors + 0xfe0 = __kuser_get_tls
+ * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
+ */
+ if (tls_emu || has_tls_reg)
+ memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
+}
+
+void __init early_trap_init(void)
+{
+#if defined(CONFIG_CPU_USE_DOMAINS)
+ unsigned long vectors = CONFIG_VECTORS_BASE;
+#else
+ unsigned long vectors = (unsigned long)vectors_page;
+#endif
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
+ extern char __kuser_helper_start[], __kuser_helper_end[];
+ int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+
+ /*
+ * Copy the vectors, stubs and kuser helpers (in entry-armv.S)
+ * into the vector page, mapped at 0xffff0000, and ensure these
+ * are visible to the instruction stream.
+ */
+ memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
+ memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
+ memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
+
+ /*
+ * Do processor specific fixups for the kuser helpers
+ */
+ kuser_get_tls_init(vectors);
+
+ /*
+ * Copy signal return handlers into the vector page, and
+ * set sigreturn to be a pointer to these.
+ */
+ memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
+ sigreturn_codes, sizeof(sigreturn_codes));
+ memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
+ syscall_restart_code, sizeof(syscall_restart_code));
+
+ flush_icache_range(vectors, vectors + PAGE_SIZE);
+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+}
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
new file mode 100644
index 00000000..d2cb0b3c
--- /dev/null
+++ b/arch/arm/kernel/unwind.c
@@ -0,0 +1,452 @@
+/*
+ * arch/arm/kernel/unwind.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Stack unwinding support for ARM
+ *
+ * An ARM EABI version of gcc is required to generate the unwind
+ * tables. For information about the structure of the unwind tables,
+ * see "Exception Handling ABI for the ARM Architecture" at:
+ *
+ * http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+ */
+
+#ifndef __CHECKER__
+#if !defined (__ARM_EABI__)
+#warning Your compiler does not have EABI support.
+#warning ARM unwind is known to compile only with EABI compilers.
+#warning Change compiler or disable ARM_UNWIND option.
+#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
+#warning Your compiler is too buggy; it is known to not compile ARM unwind support.
+#warning Change compiler or disable ARM_UNWIND option.
+#endif
+#endif /* __CHECKER__ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+#include <asm/stacktrace.h>
+#include <asm/traps.h>
+#include <asm/unwind.h>
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
+
+struct unwind_ctrl_block {
+ unsigned long vrs[16]; /* virtual register set */
+ unsigned long *insn; /* pointer to the current instructions word */
+ int entries; /* number of entries left to interpret */
+ int byte; /* current byte number in the instructions word */
+};
+
+enum regs {
+#ifdef CONFIG_THUMB2_KERNEL
+ FP = 7,
+#else
+ FP = 11,
+#endif
+ SP = 13,
+ LR = 14,
+ PC = 15
+};
+
+extern struct unwind_idx __start_unwind_idx[];
+extern struct unwind_idx __stop_unwind_idx[];
+
+static DEFINE_SPINLOCK(unwind_lock);
+static LIST_HEAD(unwind_tables);
+
+/* Convert a prel31 symbol to an absolute address */
+#define prel31_to_addr(ptr) \
+({ \
+ /* sign-extend to 32 bits */ \
+ long offset = (((long)*(ptr)) << 1) >> 1; \
+ (unsigned long)(ptr) + offset; \
+})
+
+/*
+ * Binary search in the unwind index. The entries entries are
+ * guaranteed to be sorted in ascending order by the linker.
+ */
+static struct unwind_idx *search_index(unsigned long addr,
+ struct unwind_idx *first,
+ struct unwind_idx *last)
+{
+ pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
+
+ if (addr < first->addr) {
+ pr_warning("unwind: Unknown symbol address %08lx\n", addr);
+ return NULL;
+ } else if (addr >= last->addr)
+ return last;
+
+ while (first < last - 1) {
+ struct unwind_idx *mid = first + ((last - first + 1) >> 1);
+
+ if (addr < mid->addr)
+ last = mid;
+ else
+ first = mid;
+ }
+
+ return first;
+}
+
+static struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+ struct unwind_idx *idx = NULL;
+ unsigned long flags;
+
+ pr_debug("%s(%08lx)\n", __func__, addr);
+
+ if (core_kernel_text(addr))
+ /* main unwind table */
+ idx = search_index(addr, __start_unwind_idx,
+ __stop_unwind_idx - 1);
+ else {
+ /* module unwind tables */
+ struct unwind_table *table;
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_for_each_entry(table, &unwind_tables, list) {
+ if (addr >= table->begin_addr &&
+ addr < table->end_addr) {
+ idx = search_index(addr, table->start,
+ table->stop - 1);
+ /* Move-to-front to exploit common traces */
+ list_move(&table->list, &unwind_tables);
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&unwind_lock, flags);
+ }
+
+ pr_debug("%s: idx = %p\n", __func__, idx);
+ return idx;
+}
+
+static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long ret;
+
+ if (ctrl->entries <= 0) {
+ pr_warning("unwind: Corrupt unwind table\n");
+ return 0;
+ }
+
+ ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
+
+ if (ctrl->byte == 0) {
+ ctrl->insn++;
+ ctrl->entries--;
+ ctrl->byte = 3;
+ } else
+ ctrl->byte--;
+
+ return ret;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long insn = unwind_get_byte(ctrl);
+
+ pr_debug("%s: insn = %08lx\n", __func__, insn);
+
+ if ((insn & 0xc0) == 0x00)
+ ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xc0) == 0x40)
+ ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xf0) == 0x80) {
+ unsigned long mask;
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int load_sp, reg = 4;
+
+ insn = (insn << 8) | unwind_get_byte(ctrl);
+ mask = insn & 0x0fff;
+ if (mask == 0) {
+ pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
+ insn);
+ return -URC_FAILURE;
+ }
+
+ /* pop R4-R15 according to mask */
+ load_sp = mask & (1 << (13 - 4));
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ if (!load_sp)
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if ((insn & 0xf0) == 0x90 &&
+ (insn & 0x0d) != 0x0d)
+ ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+ else if ((insn & 0xf0) == 0xa0) {
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg;
+
+ /* pop R4-R[4+bbb] */
+ for (reg = 4; reg <= 4 + (insn & 7); reg++)
+ ctrl->vrs[reg] = *vsp++;
+ if (insn & 0x80)
+ ctrl->vrs[14] = *vsp++;
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb0) {
+ if (ctrl->vrs[PC] == 0)
+ ctrl->vrs[PC] = ctrl->vrs[LR];
+ /* no further processing */
+ ctrl->entries = 0;
+ } else if (insn == 0xb1) {
+ unsigned long mask = unwind_get_byte(ctrl);
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg = 0;
+
+ if (mask == 0 || mask & 0xf0) {
+ pr_warning("unwind: Spare encoding %04lx\n",
+ (insn << 8) | mask);
+ return -URC_FAILURE;
+ }
+
+ /* pop R0-R3 according to mask */
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb2) {
+ unsigned long uleb128 = unwind_get_byte(ctrl);
+
+ ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+ } else {
+ pr_warning("unwind: Unhandled instruction %02lx\n", insn);
+ return -URC_FAILURE;
+ }
+
+ pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
+ ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
+
+ return URC_OK;
+}
+
+/*
+ * Unwind a single frame starting with *sp for the symbol at *pc. It
+ * updates the *pc and *sp with the new values.
+ */
+int unwind_frame(struct stackframe *frame)
+{
+ unsigned long high, low;
+ struct unwind_idx *idx;
+ struct unwind_ctrl_block ctrl;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE);
+
+ pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
+ frame->pc, frame->lr, frame->sp);
+
+ if (!kernel_text_address(frame->pc))
+ return -URC_FAILURE;
+
+ idx = unwind_find_idx(frame->pc);
+ if (!idx) {
+ pr_warning("unwind: Index not found %08lx\n", frame->pc);
+ return -URC_FAILURE;
+ }
+
+ ctrl.vrs[FP] = frame->fp;
+ ctrl.vrs[SP] = frame->sp;
+ ctrl.vrs[LR] = frame->lr;
+ ctrl.vrs[PC] = 0;
+
+ if (idx->insn == 1)
+ /* can't unwind */
+ return -URC_FAILURE;
+ else if ((idx->insn & 0x80000000) == 0)
+ /* prel31 to the unwind table */
+ ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
+ else if ((idx->insn & 0xff000000) == 0x80000000)
+ /* only personality routine 0 supported in the index */
+ ctrl.insn = &idx->insn;
+ else {
+ pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
+ idx->insn, idx);
+ return -URC_FAILURE;
+ }
+
+ /* check the personality routine */
+ if ((*ctrl.insn & 0xff000000) == 0x80000000) {
+ ctrl.byte = 2;
+ ctrl.entries = 1;
+ } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
+ ctrl.byte = 1;
+ ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
+ } else {
+ pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
+ *ctrl.insn, ctrl.insn);
+ return -URC_FAILURE;
+ }
+
+ while (ctrl.entries > 0) {
+ int urc = unwind_exec_insn(&ctrl);
+ if (urc < 0)
+ return urc;
+ if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+ return -URC_FAILURE;
+ }
+
+ if (ctrl.vrs[PC] == 0)
+ ctrl.vrs[PC] = ctrl.vrs[LR];
+
+ /* check for infinite loop */
+ if (frame->pc == ctrl.vrs[PC])
+ return -URC_FAILURE;
+
+ frame->fp = ctrl.vrs[FP];
+ frame->sp = ctrl.vrs[SP];
+ frame->lr = ctrl.vrs[LR];
+ frame->pc = ctrl.vrs[PC];
+
+ return URC_OK;
+}
+
+void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+{
+ struct stackframe frame;
+ register unsigned long current_sp asm ("sp");
+
+ pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+
+ if (!tsk)
+ tsk = current;
+
+ if (regs) {
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ /* PC might be corrupted, use LR in that case. */
+ frame.pc = kernel_text_address(regs->ARM_pc)
+ ? regs->ARM_pc : regs->ARM_lr;
+ } else if (tsk == current) {
+ frame.fp = (unsigned long)__builtin_frame_address(0);
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)unwind_backtrace;
+ } else {
+ /* task blocked in __switch_to */
+ frame.fp = thread_saved_fp(tsk);
+ frame.sp = thread_saved_sp(tsk);
+ /*
+ * The function calling __switch_to cannot be a leaf function
+ * so LR is recovered from the stack.
+ */
+ frame.lr = 0;
+ frame.pc = thread_saved_pc(tsk);
+ }
+
+ while (1) {
+ int urc;
+ unsigned long where = frame.pc;
+
+ urc = unwind_frame(&frame);
+ if (urc < 0)
+ break;
+ dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+ }
+}
+
+struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
+ unsigned long text_addr,
+ unsigned long text_size)
+{
+ unsigned long flags;
+ struct unwind_idx *idx;
+ struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL);
+
+ pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size,
+ text_addr, text_size);
+
+ if (!tab)
+ return tab;
+
+ tab->start = (struct unwind_idx *)start;
+ tab->stop = (struct unwind_idx *)(start + size);
+ tab->begin_addr = text_addr;
+ tab->end_addr = text_addr + text_size;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = tab->start; idx < tab->stop; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_add_tail(&tab->list, &unwind_tables);
+ spin_unlock_irqrestore(&unwind_lock, flags);
+
+ return tab;
+}
+
+void unwind_table_del(struct unwind_table *tab)
+{
+ unsigned long flags;
+
+ if (!tab)
+ return;
+
+ spin_lock_irqsave(&unwind_lock, flags);
+ list_del(&tab->list);
+ spin_unlock_irqrestore(&unwind_lock, flags);
+
+ kfree(tab);
+}
+
+int __init unwind_init(void)
+{
+ struct unwind_idx *idx;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ pr_debug("unwind: ARM stack unwinding initialised\n");
+
+ return 0;
+}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
new file mode 100644
index 00000000..e5287f21
--- /dev/null
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -0,0 +1,287 @@
+/* ld script to make ARM Linux kernel
+ * taken from the i386 version by Russell King
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/thread_info.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+
+#define PROC_INFO \
+ VMLINUX_SYMBOL(__proc_info_begin) = .; \
+ *(.proc.info.init) \
+ VMLINUX_SYMBOL(__proc_info_end) = .;
+
+#ifdef CONFIG_HOTPLUG_CPU
+#define ARM_CPU_DISCARD(x)
+#define ARM_CPU_KEEP(x) x
+#else
+#define ARM_CPU_DISCARD(x) x
+#define ARM_CPU_KEEP(x)
+#endif
+
+#if defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)
+#define ARM_EXIT_KEEP(x) x
+#else
+#define ARM_EXIT_KEEP(x)
+#endif
+
+OUTPUT_ARCH(arm)
+ENTRY(stext)
+
+#ifndef __ARMEB__
+jiffies = jiffies_64;
+#else
+jiffies = jiffies_64 + 4;
+#endif
+
+SECTIONS
+{
+#ifdef CONFIG_XIP_KERNEL
+ . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+#else
+ . = PAGE_OFFSET + TEXT_OFFSET;
+#endif
+
+ .init : { /* Init code and data */
+ _stext = .;
+ _sinittext = .;
+ HEAD_TEXT
+ INIT_TEXT
+ ARM_EXIT_KEEP(EXIT_TEXT)
+ _einittext = .;
+ ARM_CPU_DISCARD(PROC_INFO)
+ __arch_info_begin = .;
+ *(.arch.info.init)
+ __arch_info_end = .;
+ __tagtable_begin = .;
+ *(.taglist.init)
+ __tagtable_end = .;
+#ifdef CONFIG_SMP_ON_UP
+ __smpalt_begin = .;
+ *(.alt.smp.init)
+ __smpalt_end = .;
+#endif
+
+ __pv_table_begin = .;
+ *(.pv_table)
+ __pv_table_end = .;
+
+ INIT_SETUP(16)
+
+ INIT_CALLS
+ CON_INITCALL
+ SECURITY_INITCALL
+ INIT_RAM_FS
+
+#ifndef CONFIG_XIP_KERNEL
+ __init_begin = _stext;
+ INIT_DATA
+ ARM_EXIT_KEEP(EXIT_DATA)
+#endif
+ }
+
+ PERCPU_SECTION(32)
+
+#ifndef CONFIG_XIP_KERNEL
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+#endif
+
+ /*
+ * unwind exit sections must be discarded before the rest of the
+ * unwind sections get included.
+ */
+ /DISCARD/ : {
+ *(.ARM.exidx.exit.text)
+ *(.ARM.extab.exit.text)
+ ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
+ ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
+#ifndef CONFIG_HOTPLUG
+ *(.ARM.exidx.devexit.text)
+ *(.ARM.extab.devexit.text)
+#endif
+#ifndef CONFIG_MMU
+ *(.fixup)
+ *(__ex_table)
+#endif
+ }
+
+ .text : { /* Real text segment */
+ _text = .; /* Text and read-only data */
+ __exception_text_start = .;
+ *(.exception.text)
+ __exception_text_end = .;
+ IRQENTRY_TEXT
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+#ifdef CONFIG_MMU
+ *(.fixup)
+#endif
+ *(.gnu.warning)
+ *(.rodata)
+ *(.rodata.*)
+ *(.glue_7)
+ *(.glue_7t)
+ . = ALIGN(4);
+ *(.got) /* Global offset table */
+ ARM_CPU_KEEP(PROC_INFO)
+ }
+
+ RO_DATA(PAGE_SIZE)
+
+#ifdef CONFIG_ARM_UNWIND
+ /*
+ * Stack unwinding tables
+ */
+ . = ALIGN(8);
+ .ARM.unwind_idx : {
+ __start_unwind_idx = .;
+ *(.ARM.exidx*)
+ __stop_unwind_idx = .;
+ }
+ .ARM.unwind_tab : {
+ __start_unwind_tab = .;
+ *(.ARM.extab*)
+ __stop_unwind_tab = .;
+ }
+#endif
+
+ _etext = .; /* End of text and rodata section */
+
+#ifdef CONFIG_XIP_KERNEL
+ __data_loc = ALIGN(4); /* location in binary */
+ . = PAGE_OFFSET + TEXT_OFFSET;
+#else
+ . = ALIGN(THREAD_SIZE);
+ __data_loc = .;
+#endif
+
+ .data : AT(__data_loc) {
+ _data = .; /* address in memory */
+ _sdata = .;
+
+ /*
+ * first, the init task union, aligned
+ * to an 8192 byte boundary.
+ */
+ INIT_TASK_DATA(THREAD_SIZE)
+
+#ifdef CONFIG_XIP_KERNEL
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ INIT_DATA
+ ARM_EXIT_KEEP(EXIT_DATA)
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+#endif
+
+ NOSAVE_DATA
+ CACHELINE_ALIGNED_DATA(32)
+ READ_MOSTLY_DATA(32)
+
+ /*
+ * The exception fixup table (might need resorting at runtime)
+ */
+ . = ALIGN(32);
+ __start___ex_table = .;
+#ifdef CONFIG_MMU
+ *(__ex_table)
+#endif
+ __stop___ex_table = .;
+
+ /*
+ * and the usual data section
+ */
+ DATA_DATA
+ CONSTRUCTORS
+
+ _edata = .;
+ }
+ _edata_loc = __data_loc + SIZEOF(.data);
+
+#ifdef CONFIG_HAVE_TCM
+ /*
+ * We align everything to a page boundary so we can
+ * free it after init has commenced and TCM contents have
+ * been copied to its destination.
+ */
+ .tcm_start : {
+ . = ALIGN(PAGE_SIZE);
+ __tcm_start = .;
+ __itcm_start = .;
+ }
+
+ /*
+ * Link these to the ITCM RAM
+ * Put VMA to the TCM address and LMA to the common RAM
+ * and we'll upload the contents from RAM to TCM and free
+ * the used RAM after that.
+ */
+ .text_itcm ITCM_OFFSET : AT(__itcm_start)
+ {
+ __sitcm_text = .;
+ *(.tcm.text)
+ *(.tcm.rodata)
+ . = ALIGN(4);
+ __eitcm_text = .;
+ }
+
+ /*
+ * Reset the dot pointer, this is needed to create the
+ * relative __dtcm_start below (to be used as extern in code).
+ */
+ . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm);
+
+ .dtcm_start : {
+ __dtcm_start = .;
+ }
+
+ /* TODO: add remainder of ITCM as well, that can be used for data! */
+ .data_dtcm DTCM_OFFSET : AT(__dtcm_start)
+ {
+ . = ALIGN(4);
+ __sdtcm_data = .;
+ *(.tcm.data)
+ . = ALIGN(4);
+ __edtcm_data = .;
+ }
+
+ /* Reset the dot pointer or the linker gets confused */
+ . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm);
+
+ /* End marker for freeing TCM copy in linked object */
+ .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){
+ . = ALIGN(PAGE_SIZE);
+ __tcm_end = .;
+ }
+#endif
+
+ NOTES
+
+ BSS_SECTION(0, 0, 0)
+ _end = .;
+
+ STABS_DEBUG
+ .comment 0 : { *(.comment) }
+
+ /* Default discards */
+ DISCARDS
+
+#ifndef CONFIG_SMP_ON_UP
+ /DISCARD/ : {
+ *(.alt.smp.init)
+ }
+#endif
+}
+
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
+ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
+ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
new file mode 100644
index 00000000..1796157e
--- /dev/null
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -0,0 +1,179 @@
+/*
+ * linux/arch/arm/kernel/xscale-cp0.c
+ *
+ * XScale DSP and iWMMXt coprocessor context switching and handling
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <asm/thread_notify.h>
+
+static inline void dsp_save_state(u32 *state)
+{
+ __asm__ __volatile__ (
+ "mrrc p0, 0, %0, %1, c0\n"
+ : "=r" (state[0]), "=r" (state[1]));
+}
+
+static inline void dsp_load_state(u32 *state)
+{
+ __asm__ __volatile__ (
+ "mcrr p0, 0, %0, %1, c0\n"
+ : : "r" (state[0]), "r" (state[1]));
+}
+
+static int dsp_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = t;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ thread->cpu_context.extra[0] = 0;
+ thread->cpu_context.extra[1] = 0;
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ dsp_save_state(current_thread_info()->cpu_context.extra);
+ dsp_load_state(thread->cpu_context.extra);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block dsp_notifier_block = {
+ .notifier_call = dsp_do,
+};
+
+
+#ifdef CONFIG_IWMMXT
+static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
+{
+ struct thread_info *thread = t;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ /*
+ * flush_thread() zeroes thread->fpstate, so no need
+ * to do anything here.
+ *
+ * FALLTHROUGH: Ensure we don't try to overwrite our newly
+ * initialised state information on the first fault.
+ */
+
+ case THREAD_NOTIFY_EXIT:
+ iwmmxt_task_release(thread);
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ iwmmxt_task_switch(thread);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block iwmmxt_notifier_block = {
+ .notifier_call = iwmmxt_do,
+};
+#endif
+
+
+static u32 __init xscale_cp_access_read(void)
+{
+ u32 value;
+
+ __asm__ __volatile__ (
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ : "=r" (value));
+
+ return value;
+}
+
+static void __init xscale_cp_access_write(u32 value)
+{
+ u32 temp;
+
+ __asm__ __volatile__ (
+ "mcr p15, 0, %1, c15, c1, 0\n\t"
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ "mov %0, %0\n\t"
+ "sub pc, pc, #4\n\t"
+ : "=r" (temp) : "r" (value));
+}
+
+/*
+ * Detect whether we have a MAC coprocessor (40 bit register) or an
+ * iWMMXt coprocessor (64 bit registers) by loading 00000100:00000000
+ * into a coprocessor register and reading it back, and checking
+ * whether the upper word survived intact.
+ */
+static int __init cpu_has_iwmmxt(void)
+{
+ u32 lo;
+ u32 hi;
+
+ /*
+ * This sequence is interpreted by the DSP coprocessor as:
+ * mar acc0, %2, %3
+ * mra %0, %1, acc0
+ *
+ * And by the iWMMXt coprocessor as:
+ * tmcrr wR0, %2, %3
+ * tmrrc %0, %1, wR0
+ */
+ __asm__ __volatile__ (
+ "mcrr p0, 0, %2, %3, c0\n"
+ "mrrc p0, 0, %0, %1, c0\n"
+ : "=r" (lo), "=r" (hi)
+ : "r" (0), "r" (0x100));
+
+ return !!hi;
+}
+
+
+/*
+ * If we detect that the CPU has iWMMXt (and CONFIG_IWMMXT=y), we
+ * disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
+ * switch code handle iWMMXt context switching. If on the other
+ * hand the CPU has a DSP coprocessor, we keep access to CP0 enabled
+ * all the time, and save/restore acc0 on context switch in non-lazy
+ * fashion.
+ */
+static int __init xscale_cp0_init(void)
+{
+ u32 cp_access;
+
+ cp_access = xscale_cp_access_read() & ~3;
+ xscale_cp_access_write(cp_access | 1);
+
+ if (cpu_has_iwmmxt()) {
+#ifndef CONFIG_IWMMXT
+ printk(KERN_WARNING "CAUTION: XScale iWMMXt coprocessor "
+ "detected, but kernel support is missing.\n");
+#else
+ printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n");
+ elf_hwcap |= HWCAP_IWMMXT;
+ thread_register_notifier(&iwmmxt_notifier_block);
+#endif
+ } else {
+ printk(KERN_INFO "XScale DSP coprocessor detected.\n");
+ thread_register_notifier(&dsp_notifier_block);
+ cp_access |= 1;
+ }
+
+ xscale_cp_access_write(cp_access);
+
+ return 0;
+}
+
+late_initcall(xscale_cp0_init);
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
new file mode 100644
index 00000000..59ff42dd
--- /dev/null
+++ b/arch/arm/lib/Makefile
@@ -0,0 +1,47 @@
+#
+# linux/arch/arm/lib/Makefile
+#
+# Copyright (C) 1995-2000 Russell King
+#
+
+lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
+ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
+ delay.o findbit.o memchr.o memcpy.o \
+ memmove.o memset.o memzero.o setbit.o \
+ strncpy_from_user.o strnlen_user.o \
+ strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o \
+ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+ ucmpdi2.o lib1funcs.o div64.o sha1.o \
+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o
+
+mmu-y := clear_user.o copy_page.o getuser.o putuser.o
+
+# the code in uaccess.S is not preemption safe and
+# probably faster on ARMv3 only
+ifeq ($(CONFIG_PREEMPT),y)
+ mmu-y += copy_from_user.o copy_to_user.o
+else
+ifneq ($(CONFIG_CPU_32v3),y)
+ mmu-y += copy_from_user.o copy_to_user.o
+else
+ mmu-y += uaccess.o
+endif
+endif
+
+# using lib_ here won't override already available weak symbols
+obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o
+
+lib-$(CONFIG_MMU) += $(mmu-y)
+
+ifeq ($(CONFIG_CPU_32v3),y)
+ lib-y += io-readsw-armv3.o io-writesw-armv3.o
+else
+ lib-y += io-readsw-armv4.o io-writesw-armv4.o
+endif
+
+lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o
+lib-$(CONFIG_ARCH_SHARK) += io-shark.o
+
+$(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S
+$(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
new file mode 100644
index 00000000..638deb13
--- /dev/null
+++ b/arch/arm/lib/ashldi3.S
@@ -0,0 +1,53 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashldi3)
+ENTRY(__aeabi_llsl)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi ah, ah, lsl r2
+ movpl ah, al, lsl r3
+ ARM( orrmi ah, ah, al, lsr ip )
+ THUMB( lsrmi r3, al, ip )
+ THUMB( orrmi ah, ah, r3 )
+ mov al, al, lsl r2
+ mov pc, lr
+
+ENDPROC(__ashldi3)
+ENDPROC(__aeabi_llsl)
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
new file mode 100644
index 00000000..015e8aa5
--- /dev/null
+++ b/arch/arm/lib/ashrdi3.S
@@ -0,0 +1,53 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__ashrdi3)
+ENTRY(__aeabi_lasr)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, asr r3
+ ARM( orrmi al, al, ah, lsl ip )
+ THUMB( lslmi r3, ah, ip )
+ THUMB( orrmi al, al, r3 )
+ mov ah, ah, asr r2
+ mov pc, lr
+
+ENDPROC(__ashrdi3)
+ENDPROC(__aeabi_lasr)
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
new file mode 100644
index 00000000..a673297b
--- /dev/null
+++ b/arch/arm/lib/backtrace.S
@@ -0,0 +1,158 @@
+/*
+ * linux/arch/arm/lib/backtrace.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 27/03/03 Ian Molton Clean up CONFIG_CPU
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+@ fp is 0 or stack frame
+
+#define frame r4
+#define sv_fp r5
+#define sv_pc r6
+#define mask r7
+#define offset r8
+
+ENTRY(__backtrace)
+ mov r1, #0x10
+ mov r0, fp
+
+ENTRY(c_backtrace)
+
+#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
+ mov pc, lr
+ENDPROC(__backtrace)
+ENDPROC(c_backtrace)
+#else
+ stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
+ movs frame, r0 @ if frame pointer is zero
+ beq no_frame @ we have no stack frames
+
+ tst r1, #0x10 @ 26 or 32-bit mode?
+ ARM( moveq mask, #0xfc000003 )
+ THUMB( moveq mask, #0xfc000000 )
+ THUMB( orreq mask, #0x03 )
+ movne mask, #0 @ mask for 32-bit
+
+1: stmfd sp!, {pc} @ calculate offset of PC stored
+ ldr r0, [sp], #4 @ by stmfd for this CPU
+ adr r1, 1b
+ sub offset, r0, r1
+
+/*
+ * Stack frame layout:
+ * optionally saved caller registers (r4 - r10)
+ * saved fp
+ * saved sp
+ * saved lr
+ * frame => saved pc
+ * optionally saved arguments (r0 - r3)
+ * saved sp => <next word>
+ *
+ * Functions start with the following code sequence:
+ * mov ip, sp
+ * stmfd sp!, {r0 - r3} (optional)
+ * corrected pc => stmfd sp!, {..., fp, ip, lr, pc}
+ */
+for_each_frame: tst frame, mask @ Check for address exceptions
+ bne no_frame
+
+1001: ldr sv_pc, [frame, #0] @ get saved pc
+1002: ldr sv_fp, [frame, #-12] @ get saved fp
+
+ sub sv_pc, sv_pc, offset @ Correct PC for prefetching
+ bic sv_pc, sv_pc, mask @ mask PC/LR for the mode
+
+1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
+ ldr r3, .Ldsi+4 @ adjust saved 'pc' back one
+ teq r3, r2, lsr #10 @ instruction
+ subne r0, sv_pc, #4 @ allow for mov
+ subeq r0, sv_pc, #8 @ allow for mov + stmia
+
+ ldr r1, [frame, #-4] @ get saved lr
+ mov r2, frame
+ bic r1, r1, mask @ mask PC/LR for the mode
+ bl dump_backtrace_entry
+
+ ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
+ ldr r3, .Ldsi+4
+ teq r3, r1, lsr #10
+ ldreq r0, [frame, #-8] @ get sp
+ subeq r0, r0, #4 @ point at the last arg
+ bleq .Ldumpstm @ dump saved registers
+
+1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}
+ ldr r3, .Ldsi @ instruction exists,
+ teq r3, r1, lsr #10
+ subeq r0, frame, #16
+ bleq .Ldumpstm @ dump saved registers
+
+ teq sv_fp, #0 @ zero saved fp means
+ beq no_frame @ no further frames
+
+ cmp sv_fp, frame @ next frame must be
+ mov frame, sv_fp @ above the current frame
+ bhi for_each_frame
+
+1006: adr r0, .Lbad
+ mov r1, frame
+ bl printk
+no_frame: ldmfd sp!, {r4 - r8, pc}
+ENDPROC(__backtrace)
+ENDPROC(c_backtrace)
+
+ .pushsection __ex_table,"a"
+ .align 3
+ .long 1001b, 1006b
+ .long 1002b, 1006b
+ .long 1003b, 1006b
+ .long 1004b, 1006b
+ .popsection
+
+#define instr r4
+#define reg r5
+#define stack r6
+
+.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
+ mov stack, r0
+ mov instr, r1
+ mov reg, #10
+ mov r7, #0
+1: mov r3, #1
+ ARM( tst instr, r3, lsl reg )
+ THUMB( lsl r3, reg )
+ THUMB( tst instr, r3 )
+ beq 2f
+ add r7, r7, #1
+ teq r7, #6
+ moveq r7, #1
+ moveq r1, #'\n'
+ movne r1, #' '
+ ldr r3, [stack], #-4
+ mov r2, reg
+ adr r0, .Lfp
+ bl printk
+2: subs reg, reg, #1
+ bpl 1b
+ teq r7, #0
+ adrne r0, .Lcr
+ blne printk
+ ldmfd sp!, {instr, reg, stack, r7, pc}
+
+.Lfp: .asciz "%cr%d:%08x"
+.Lcr: .asciz "\n"
+.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
+ .align
+.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc}
+ .word 0xe92d0000 >> 10 @ stmfd sp!, {}
+
+#endif
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
new file mode 100644
index 00000000..10d868a5
--- /dev/null
+++ b/arch/arm/lib/bitops.h
@@ -0,0 +1,77 @@
+#if __LINUX_ARM_ARCH__ >= 6
+ .macro bitop, instr
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ mov r2, #1
+ and r3, r0, #31 @ Get bit offset
+ mov r0, r0, lsr #5
+ add r1, r1, r0, lsl #2 @ Get word offset
+ mov r3, r2, lsl r3
+1: ldrex r2, [r1]
+ \instr r2, r2, r3
+ strex r0, r2, [r1]
+ cmp r0, #0
+ bne 1b
+ bx lr
+ .endm
+
+ .macro testop, instr, store
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ mov r2, #1
+ and r3, r0, #31 @ Get bit offset
+ mov r0, r0, lsr #5
+ add r1, r1, r0, lsl #2 @ Get word offset
+ mov r3, r2, lsl r3 @ create mask
+ smp_dmb
+1: ldrex r2, [r1]
+ ands r0, r2, r3 @ save old value of bit
+ \instr r2, r2, r3 @ toggle bit
+ strex ip, r2, [r1]
+ cmp ip, #0
+ bne 1b
+ smp_dmb
+ cmp r0, #0
+ movne r0, #1
+2: bx lr
+ .endm
+#else
+ .macro bitop, instr
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ and r2, r0, #31
+ mov r0, r0, lsr #5
+ mov r3, #1
+ mov r3, r3, lsl r2
+ save_and_disable_irqs ip
+ ldr r2, [r1, r0, lsl #2]
+ \instr r2, r2, r3
+ str r2, [r1, r0, lsl #2]
+ restore_irqs ip
+ mov pc, lr
+ .endm
+
+/**
+ * testop - implement a test_and_xxx_bit operation.
+ * @instr: operational instruction
+ * @store: store instruction
+ *
+ * Note: we can trivially conditionalise the store instruction
+ * to avoid dirtying the data cache.
+ */
+ .macro testop, instr, store
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ and r3, r0, #31
+ mov r0, r0, lsr #5
+ save_and_disable_irqs ip
+ ldr r2, [r1, r0, lsl #2]!
+ mov r0, #1
+ tst r2, r0, lsl r3
+ \instr r2, r2, r0, lsl r3
+ \store r2, [r1]
+ moveq r0, #0
+ restore_irqs ip
+ mov pc, lr
+ .endm
+#endif
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
new file mode 100644
index 00000000..68ed5b62
--- /dev/null
+++ b/arch/arm/lib/changebit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/changebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_change_bit)
+ bitop eor
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clear_user.S b/arch/arm/lib/clear_user.S
new file mode 100644
index 00000000..14a0d988
--- /dev/null
+++ b/arch/arm/lib/clear_user.S
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/lib/clear_user.S
+ *
+ * Copyright (C) 1995, 1996,1997,1998 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/* Prototype: int __clear_user(void *addr, size_t sz)
+ * Purpose : clear some user memory
+ * Params : addr - user memory address to clear
+ * : sz - number of bytes to clear
+ * Returns : number of bytes NOT cleared
+ */
+ENTRY(__clear_user_std)
+WEAK(__clear_user)
+ stmfd sp!, {r1, lr}
+ mov r2, #0
+ cmp r1, #4
+ blt 2f
+ ands ip, r0, #3
+ beq 1f
+ cmp ip, #2
+ strusr r2, r0, 1
+ strusr r2, r0, 1, le
+ strusr r2, r0, 1, lt
+ rsb ip, ip, #4
+ sub r1, r1, ip @ 7 6 5 4 3 2 1
+1: subs r1, r1, #8 @ -1 -2 -3 -4 -5 -6 -7
+ strusr r2, r0, 4, pl, rept=2
+ bpl 1b
+ adds r1, r1, #4 @ 3 2 1 0 -1 -2 -3
+ strusr r2, r0, 4, pl
+2: tst r1, #2 @ 1x 1x 0x 0x 1x 1x 0x
+ strusr r2, r0, 1, ne, rept=2
+ tst r1, #1 @ x1 x0 x1 x0 x1 x0 x1
+ it ne @ explicit IT needed for the label
+USER( strnebt r2, [r0])
+ mov r0, #0
+ ldmfd sp!, {r1, pc}
+ENDPROC(__clear_user)
+ENDPROC(__clear_user_std)
+
+ .pushsection .fixup,"ax"
+ .align 0
+9001: ldmfd sp!, {r0, pc}
+ .popsection
+
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
new file mode 100644
index 00000000..4c04c3b5
--- /dev/null
+++ b/arch/arm/lib/clearbit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/clearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_clear_bit)
+ bitop bic
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
new file mode 100644
index 00000000..66a477a3
--- /dev/null
+++ b/arch/arm/lib/copy_from_user.S
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/arm/lib/copy_from_user.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 29, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Prototype:
+ *
+ * size_t __copy_from_user(void *to, const void *from, size_t n)
+ *
+ * Purpose:
+ *
+ * copy a block to kernel memory from user memory
+ *
+ * Params:
+ *
+ * to = kernel memory
+ * from = user memory
+ * n = number of bytes to copy
+ *
+ * Return value:
+ *
+ * Number of bytes NOT copied.
+ */
+
+#ifndef CONFIG_THUMB2_KERNEL
+#define LDR1W_SHIFT 0
+#else
+#define LDR1W_SHIFT 1
+#endif
+#define STR1W_SHIFT 0
+
+ .macro ldr1w ptr reg abort
+ ldrusr \reg, \ptr, 4, abort=\abort
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldr1w \ptr, \reg1, \abort
+ ldr1w \ptr, \reg2, \abort
+ ldr1w \ptr, \reg3, \abort
+ ldr1w \ptr, \reg4, \abort
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
+ ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldrusr \reg, \ptr, 1, \cond, abort=\abort
+ .endm
+
+ .macro str1w ptr reg abort
+ W(str) \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ mov r3, #0
+ stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ add sp, sp, #8
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+ENTRY(__copy_from_user)
+
+#include "copy_template.S"
+
+ENDPROC(__copy_from_user)
+
+ .pushsection .fixup,"ax"
+ .align 0
+ copy_abort_preamble
+ ldmfd sp!, {r1, r2}
+ sub r3, r0, r1
+ rsb r1, r3, r2
+ str r1, [sp]
+ bl __memzero
+ ldr r0, [sp], #4
+ copy_abort_end
+ .popsection
+
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
new file mode 100644
index 00000000..6ee2f670
--- /dev/null
+++ b/arch/arm/lib/copy_page.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/lib/copypage.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+
+#define COPY_COUNT (PAGE_SZ / (2 * L1_CACHE_BYTES) PLD( -1 ))
+
+ .text
+ .align 5
+/*
+ * StrongARM optimised copy_page routine
+ * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s)
+ * Note that we probably achieve closer to the 100MB/s target with
+ * the core clock switching.
+ */
+ENTRY(copy_page)
+ stmfd sp!, {r4, lr} @ 2
+ PLD( pld [r1, #0] )
+ PLD( pld [r1, #L1_CACHE_BYTES] )
+ mov r2, #COPY_COUNT @ 1
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+1: PLD( pld [r1, #2 * L1_CACHE_BYTES])
+ PLD( pld [r1, #3 * L1_CACHE_BYTES])
+2:
+ .rept (2 * L1_CACHE_BYTES / 16 - 1)
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4
+ .endr
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmgtia r1!, {r3, r4, ip, lr} @ 4
+ bgt 1b @ 1
+ PLD( ldmeqia r1!, {r3, r4, ip, lr} )
+ PLD( beq 2b )
+ ldmfd sp!, {r4, pc} @ 3
+ENDPROC(copy_page)
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
new file mode 100644
index 00000000..805e3f8f
--- /dev/null
+++ b/arch/arm/lib/copy_template.S
@@ -0,0 +1,267 @@
+/*
+ * linux/arch/arm/lib/copy_template.s
+ *
+ * Code template for optimized memory copy functions
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * Theory of operation
+ * -------------------
+ *
+ * This file provides the core code for a forward memory copy used in
+ * the implementation of memcopy(), copy_to_user() and copy_from_user().
+ *
+ * The including file must define the following accessor macros
+ * according to the need of the given function:
+ *
+ * ldr1w ptr reg abort
+ *
+ * This loads one word from 'ptr', stores it in 'reg' and increments
+ * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
+ *
+ * ldr4w ptr reg1 reg2 reg3 reg4 abort
+ * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ *
+ * This loads four or eight words starting from 'ptr', stores them
+ * in provided registers and increments 'ptr' past those words.
+ * The'abort' argument is used for fixup tables.
+ *
+ * ldr1b ptr reg cond abort
+ *
+ * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
+ * It also must apply the condition code if provided, otherwise the
+ * "al" condition is assumed by default.
+ *
+ * str1w ptr reg abort
+ * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ * str1b ptr reg cond abort
+ *
+ * Same as their ldr* counterparts, but data is stored to 'ptr' location
+ * rather than being loaded.
+ *
+ * enter reg1 reg2
+ *
+ * Preserve the provided registers on the stack plus any additional
+ * data as needed by the implementation including this code. Called
+ * upon code entry.
+ *
+ * exit reg1 reg2
+ *
+ * Restore registers with the values previously saved with the
+ * 'preserv' macro. Called upon code termination.
+ *
+ * LDR1W_SHIFT
+ * STR1W_SHIFT
+ *
+ * Correction to be applied to the "ip" register when branching into
+ * the ldr1w or str1w instructions (some of these macros may expand to
+ * than one 32bit instruction in Thumb-2)
+ */
+
+
+ enter r4, lr
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+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( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+#if LDR1W_SHIFT > 0
+ lsl ip, ip, #LDR1W_SHIFT
+#endif
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6:
+ .rept (1 << LDR1W_SHIFT)
+ W(nop)
+ .endr
+ ldr1w r1, r3, abort=20f
+ ldr1w r1, r4, abort=20f
+ ldr1w r1, r5, abort=20f
+ ldr1w r1, r6, abort=20f
+ ldr1w r1, r7, abort=20f
+ ldr1w r1, r8, abort=20f
+ ldr1w r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+ lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+ lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+ add pc, pc, ip
+ nop
+ .rept (1 << STR1W_SHIFT)
+ W(nop)
+ .endr
+ str1w r0, r3, abort=20f
+ str1w r0, r4, abort=20f
+ str1w r0, r5, abort=20f
+ str1w r0, r6, abort=20f
+ str1w r0, r7, abort=20f
+ str1w r0, r8, abort=20f
+ str1w r0, lr, abort=20f
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldr1b r1, r3, ne, abort=21f
+ ldr1b r1, r4, cs, abort=21f
+ ldr1b r1, ip, cs, abort=21f
+ str1b r0, r3, ne, abort=21f
+ str1b r0, r4, cs, abort=21f
+ str1b r0, ip, cs, abort=21f
+
+ exit r4, pc
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldr1b r1, r3, gt, abort=21f
+ ldr1b r1, r4, ge, abort=21f
+ ldr1b r1, lr, abort=21f
+ str1b r0, r3, gt, abort=21f
+ str1b r0, r4, ge, abort=21f
+ subs r2, r2, ip
+ str1b r0, lr, abort=21f
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr1w r1, lr, abort=21f
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldr4w r1, r4, r5, r6, r7, abort=19f
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
+
+
+/*
+ * Abort preamble and completion macros.
+ * If a fixup handler is required then those macros must surround it.
+ * It is assumed that the fixup code will handle the private part of
+ * the exit macro.
+ */
+
+ .macro copy_abort_preamble
+19: ldmfd sp!, {r5 - r9}
+ b 21f
+20: ldmfd sp!, {r5 - r8}
+21:
+ .endm
+
+ .macro copy_abort_end
+ ldmfd sp!, {r4, pc}
+ .endm
+
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
new file mode 100644
index 00000000..d066df68
--- /dev/null
+++ b/arch/arm/lib/copy_to_user.S
@@ -0,0 +1,106 @@
+/*
+ * linux/arch/arm/lib/copy_to_user.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 29, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Prototype:
+ *
+ * size_t __copy_to_user(void *to, const void *from, size_t n)
+ *
+ * Purpose:
+ *
+ * copy a block to user memory from kernel memory
+ *
+ * Params:
+ *
+ * to = user memory
+ * from = kernel memory
+ * n = number of bytes to copy
+ *
+ * Return value:
+ *
+ * Number of bytes NOT copied.
+ */
+
+#define LDR1W_SHIFT 0
+#ifndef CONFIG_THUMB2_KERNEL
+#define STR1W_SHIFT 0
+#else
+#define STR1W_SHIFT 1
+#endif
+
+ .macro ldr1w ptr reg abort
+ W(ldr) \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+ strusr \reg, \ptr, 4, abort=\abort
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ str1w \ptr, \reg1, \abort
+ str1w \ptr, \reg2, \abort
+ str1w \ptr, \reg3, \abort
+ str1w \ptr, \reg4, \abort
+ str1w \ptr, \reg5, \abort
+ str1w \ptr, \reg6, \abort
+ str1w \ptr, \reg7, \abort
+ str1w \ptr, \reg8, \abort
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ strusr \reg, \ptr, 1, \cond, abort=\abort
+ .endm
+
+ .macro enter reg1 reg2
+ mov r3, #0
+ stmdb sp!, {r0, r2, r3, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ add sp, sp, #8
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+ENTRY(__copy_to_user_std)
+WEAK(__copy_to_user)
+
+#include "copy_template.S"
+
+ENDPROC(__copy_to_user)
+ENDPROC(__copy_to_user_std)
+
+ .pushsection .fixup,"ax"
+ .align 0
+ copy_abort_preamble
+ ldmfd sp!, {r1, r2, r3}
+ sub r0, r0, r1
+ rsb r0, r0, r2
+ copy_abort_end
+ .popsection
+
diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S
new file mode 100644
index 00000000..3ac6ef01
--- /dev/null
+++ b/arch/arm/lib/csumipv6.S
@@ -0,0 +1,33 @@
+/*
+ * linux/arch/arm/lib/csumipv6.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+ENTRY(__csum_ipv6_magic)
+ str lr, [sp, #-4]!
+ adds ip, r2, r3
+ ldmia r1, {r1 - r3, lr}
+ adcs ip, ip, r1
+ adcs ip, ip, r2
+ adcs ip, ip, r3
+ adcs ip, ip, lr
+ ldmia r0, {r0 - r3}
+ adcs r0, ip, r0
+ adcs r0, r0, r1
+ adcs r0, r0, r2
+ ldr r2, [sp, #4]
+ adcs r0, r0, r3
+ adcs r0, r0, r2
+ adcs r0, r0, #0
+ ldmfd sp!, {pc}
+ENDPROC(__csum_ipv6_magic)
+
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
new file mode 100644
index 00000000..31d3cb34
--- /dev/null
+++ b/arch/arm/lib/csumpartial.S
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/arm/lib/csumpartial.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/*
+ * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
+ * Params : r0 = buffer, r1 = len, r2 = checksum
+ * Returns : r0 = new checksum
+ */
+
+buf .req r0
+len .req r1
+sum .req r2
+td0 .req r3
+td1 .req r4 @ save before use
+td2 .req r5 @ save before use
+td3 .req lr
+
+.Lzero: mov r0, sum
+ add sp, sp, #4
+ ldr pc, [sp], #4
+
+ /*
+ * Handle 0 to 7 bytes, with any alignment of source and
+ * destination pointers. Note that when we get here, C = 0
+ */
+.Lless8: teq len, #0 @ check for zero count
+ beq .Lzero
+
+ /* we must have at least one byte. */
+ tst buf, #1 @ odd address?
+ movne sum, sum, ror #8
+ ldrneb td0, [buf], #1
+ subne len, len, #1
+ adcnes sum, sum, td0, put_byte_1
+
+.Lless4: tst len, #6
+ beq .Lless8_byte
+
+ /* we are now half-word aligned */
+
+.Lless8_wordlp:
+#if __LINUX_ARM_ARCH__ >= 4
+ ldrh td0, [buf], #2
+ sub len, len, #2
+#else
+ ldrb td0, [buf], #1
+ ldrb td3, [buf], #1
+ sub len, len, #2
+#ifndef __ARMEB__
+ orr td0, td0, td3, lsl #8
+#else
+ orr td0, td3, td0, lsl #8
+#endif
+#endif
+ adcs sum, sum, td0
+ tst len, #6
+ bne .Lless8_wordlp
+
+.Lless8_byte: tst len, #1 @ odd number of bytes
+ ldrneb td0, [buf], #1 @ include last byte
+ adcnes sum, sum, td0, put_byte_0 @ update checksum
+
+.Ldone: adc r0, sum, #0 @ collect up the last carry
+ ldr td0, [sp], #4
+ tst td0, #1 @ check buffer alignment
+ movne r0, r0, ror #8 @ rotate checksum by 8 bits
+ ldr pc, [sp], #4 @ return
+
+.Lnot_aligned: tst buf, #1 @ odd address
+ ldrneb td0, [buf], #1 @ make even
+ subne len, len, #1
+ adcnes sum, sum, td0, put_byte_1 @ update checksum
+
+ tst buf, #2 @ 32-bit aligned?
+#if __LINUX_ARM_ARCH__ >= 4
+ ldrneh td0, [buf], #2 @ make 32-bit aligned
+ subne len, len, #2
+#else
+ ldrneb td0, [buf], #1
+ ldrneb ip, [buf], #1
+ subne len, len, #2
+#ifndef __ARMEB__
+ orrne td0, td0, ip, lsl #8
+#else
+ orrne td0, ip, td0, lsl #8
+#endif
+#endif
+ adcnes sum, sum, td0 @ update checksum
+ mov pc, lr
+
+ENTRY(csum_partial)
+ stmfd sp!, {buf, lr}
+ cmp len, #8 @ Ensure that we have at least
+ blo .Lless8 @ 8 bytes to copy.
+
+ tst buf, #1
+ movne sum, sum, ror #8
+
+ adds sum, sum, #0 @ C = 0
+ tst buf, #3 @ Test destination alignment
+ blne .Lnot_aligned @ align destination, return here
+
+1: bics ip, len, #31
+ beq 3f
+
+ stmfd sp!, {r4 - r5}
+2: ldmia buf!, {td0, td1, td2, td3}
+ adcs sum, sum, td0
+ adcs sum, sum, td1
+ adcs sum, sum, td2
+ adcs sum, sum, td3
+ ldmia buf!, {td0, td1, td2, td3}
+ adcs sum, sum, td0
+ adcs sum, sum, td1
+ adcs sum, sum, td2
+ adcs sum, sum, td3
+ sub ip, ip, #32
+ teq ip, #0
+ bne 2b
+ ldmfd sp!, {r4 - r5}
+
+3: tst len, #0x1c @ should not change C
+ beq .Lless4
+
+4: ldr td0, [buf], #4
+ sub len, len, #4
+ adcs sum, sum, td0
+ tst len, #0x1c
+ bne 4b
+ b .Lless4
+ENDPROC(csum_partial)
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
new file mode 100644
index 00000000..d03fc71f
--- /dev/null
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -0,0 +1,53 @@
+/*
+ * linux/arch/arm/lib/csumpartialcopy.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
+ * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
+ * Returns : r0 = new checksum
+ */
+
+ .macro save_regs
+ stmfd sp!, {r1, r4 - r8, lr}
+ .endm
+
+ .macro load_regs
+ ldmfd sp!, {r1, r4 - r8, pc}
+ .endm
+
+ .macro load1b, reg1
+ ldrb \reg1, [r0], #1
+ .endm
+
+ .macro load2b, reg1, reg2
+ ldrb \reg1, [r0], #1
+ ldrb \reg2, [r0], #1
+ .endm
+
+ .macro load1l, reg1
+ ldr \reg1, [r0], #4
+ .endm
+
+ .macro load2l, reg1, reg2
+ ldr \reg1, [r0], #4
+ ldr \reg2, [r0], #4
+ .endm
+
+ .macro load4l, reg1, reg2, reg3, reg4
+ ldmia r0!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+#define FN_ENTRY ENTRY(csum_partial_copy_nocheck)
+#define FN_EXIT ENDPROC(csum_partial_copy_nocheck)
+
+#include "csumpartialcopygeneric.S"
diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S
new file mode 100644
index 00000000..d620a5f2
--- /dev/null
+++ b/arch/arm/lib/csumpartialcopygeneric.S
@@ -0,0 +1,332 @@
+/*
+ * linux/arch/arm/lib/csumpartialcopygeneric.S
+ *
+ * Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * unsigned int
+ * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
+ * r0 = src, r1 = dst, r2 = len, r3 = sum
+ * Returns : r0 = checksum
+ *
+ * Note that 'tst' and 'teq' preserve the carry flag.
+ */
+
+src .req r0
+dst .req r1
+len .req r2
+sum .req r3
+
+.Lzero: mov r0, sum
+ load_regs
+
+ /*
+ * Align an unaligned destination pointer. We know that
+ * we have >= 8 bytes here, so we don't need to check
+ * the length. Note that the source pointer hasn't been
+ * aligned yet.
+ */
+.Ldst_unaligned:
+ tst dst, #1
+ beq .Ldst_16bit
+
+ load1b ip
+ sub len, len, #1
+ adcs sum, sum, ip, put_byte_1 @ update checksum
+ strb ip, [dst], #1
+ tst dst, #2
+ moveq pc, lr @ dst is now 32bit aligned
+
+.Ldst_16bit: load2b r8, ip
+ sub len, len, #2
+ adcs sum, sum, r8, put_byte_0
+ strb r8, [dst], #1
+ adcs sum, sum, ip, put_byte_1
+ strb ip, [dst], #1
+ mov pc, lr @ dst is now 32bit aligned
+
+ /*
+ * Handle 0 to 7 bytes, with any alignment of source and
+ * destination pointers. Note that when we get here, C = 0
+ */
+.Lless8: teq len, #0 @ check for zero count
+ beq .Lzero
+
+ /* we must have at least one byte. */
+ tst dst, #1 @ dst 16-bit aligned
+ beq .Lless8_aligned
+
+ /* Align dst */
+ load1b ip
+ sub len, len, #1
+ adcs sum, sum, ip, put_byte_1 @ update checksum
+ strb ip, [dst], #1
+ tst len, #6
+ beq .Lless8_byteonly
+
+1: load2b r8, ip
+ sub len, len, #2
+ adcs sum, sum, r8, put_byte_0
+ strb r8, [dst], #1
+ adcs sum, sum, ip, put_byte_1
+ strb ip, [dst], #1
+.Lless8_aligned:
+ tst len, #6
+ bne 1b
+.Lless8_byteonly:
+ tst len, #1
+ beq .Ldone
+ load1b r8
+ adcs sum, sum, r8, put_byte_0 @ update checksum
+ strb r8, [dst], #1
+ b .Ldone
+
+FN_ENTRY
+ save_regs
+
+ cmp len, #8 @ Ensure that we have at least
+ blo .Lless8 @ 8 bytes to copy.
+
+ adds sum, sum, #0 @ C = 0
+ tst dst, #3 @ Test destination alignment
+ blne .Ldst_unaligned @ align destination, return here
+
+ /*
+ * Ok, the dst pointer is now 32bit aligned, and we know
+ * that we must have more than 4 bytes to copy. Note
+ * that C contains the carry from the dst alignment above.
+ */
+
+ tst src, #3 @ Test source alignment
+ bne .Lsrc_not_aligned
+
+ /* Routine for src & dst aligned */
+
+ bics ip, len, #15
+ beq 2f
+
+1: load4l r4, r5, r6, r7
+ stmia dst!, {r4, r5, r6, r7}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ adcs sum, sum, r6
+ adcs sum, sum, r7
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+
+2: ands ip, len, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ load2l r4, r5
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ tst ip, #4
+ beq 4f
+
+3: load1l r4
+ str r4, [dst], #4
+ adcs sum, sum, r4
+
+4: ands len, len, #3
+ beq .Ldone
+ load1l r4
+ tst len, #2
+ mov r5, r4, get_byte_0
+ beq .Lexit
+ adcs sum, sum, r4, push #16
+ strb r5, [dst], #1
+ mov r5, r4, get_byte_1
+ strb r5, [dst], #1
+ mov r5, r4, get_byte_2
+.Lexit: tst len, #1
+ strneb r5, [dst], #1
+ andne r5, r5, #255
+ adcnes sum, sum, r5, put_byte_0
+
+ /*
+ * If the dst pointer was not 16-bit aligned, we
+ * need to rotate the checksum here to get around
+ * the inefficient byte manipulations in the
+ * architecture independent code.
+ */
+.Ldone: adc r0, sum, #0
+ ldr sum, [sp, #0] @ dst
+ tst sum, #1
+ movne r0, r0, ror #8
+ load_regs
+
+.Lsrc_not_aligned:
+ adc sum, sum, #0 @ include C from dst alignment
+ and ip, src, #3
+ bic src, src, #3
+ load1l r5
+ cmp ip, #2
+ beq .Lsrc2_aligned
+ bhi .Lsrc3_aligned
+ mov r4, r5, pull #8 @ C = 0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
+ mov r6, r6, pull #8
+ orr r6, r6, r7, push #24
+ mov r7, r7, pull #8
+ orr r7, r7, r8, push #24
+ stmia dst!, {r4, r5, r6, r7}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ adcs sum, sum, r6
+ adcs sum, sum, r7
+ mov r4, r8, pull #8
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, len, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ load2l r5, r6
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, pull #8
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, push #24
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, pull #8
+4: ands len, len, #3
+ beq .Ldone
+ mov r5, r4, get_byte_0
+ tst len, #2
+ beq .Lexit
+ adcs sum, sum, r4, push #16
+ strb r5, [dst], #1
+ mov r5, r4, get_byte_1
+ strb r5, [dst], #1
+ mov r5, r4, get_byte_2
+ b .Lexit
+
+.Lsrc2_aligned: mov r4, r5, pull #16
+ adds sum, sum, #0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
+ mov r6, r6, pull #16
+ orr r6, r6, r7, push #16
+ mov r7, r7, pull #16
+ orr r7, r7, r8, push #16
+ stmia dst!, {r4, r5, r6, r7}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ adcs sum, sum, r6
+ adcs sum, sum, r7
+ mov r4, r8, pull #16
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, len, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ load2l r5, r6
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, pull #16
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, push #16
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, pull #16
+4: ands len, len, #3
+ beq .Ldone
+ mov r5, r4, get_byte_0
+ tst len, #2
+ beq .Lexit
+ adcs sum, sum, r4
+ strb r5, [dst], #1
+ mov r5, r4, get_byte_1
+ strb r5, [dst], #1
+ tst len, #1
+ beq .Ldone
+ load1b r5
+ b .Lexit
+
+.Lsrc3_aligned: mov r4, r5, pull #24
+ adds sum, sum, #0
+ bics ip, len, #15
+ beq 2f
+1: load4l r5, r6, r7, r8
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
+ mov r6, r6, pull #24
+ orr r6, r6, r7, push #8
+ mov r7, r7, pull #24
+ orr r7, r7, r8, push #8
+ stmia dst!, {r4, r5, r6, r7}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ adcs sum, sum, r6
+ adcs sum, sum, r7
+ mov r4, r8, pull #24
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, len, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ load2l r5, r6
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
+ stmia dst!, {r4, r5}
+ adcs sum, sum, r4
+ adcs sum, sum, r5
+ mov r4, r6, pull #24
+ tst ip, #4
+ beq 4f
+3: load1l r5
+ orr r4, r4, r5, push #8
+ str r4, [dst], #4
+ adcs sum, sum, r4
+ mov r4, r5, pull #24
+4: ands len, len, #3
+ beq .Ldone
+ mov r5, r4, get_byte_0
+ tst len, #2
+ beq .Lexit
+ strb r5, [dst], #1
+ adcs sum, sum, r4
+ load1l r4
+ mov r5, r4, get_byte_0
+ strb r5, [dst], #1
+ adcs sum, sum, r4, push #24
+ mov r5, r4, get_byte_1
+ b .Lexit
+FN_EXIT
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
new file mode 100644
index 00000000..7d08b43d
--- /dev/null
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/lib/csumpartialcopyuser.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 27/03/03 Ian Molton Clean up CONFIG_CPU
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+#include <asm/asm-offsets.h>
+
+ .text
+
+ .macro save_regs
+ stmfd sp!, {r1, r2, r4 - r8, lr}
+ .endm
+
+ .macro load_regs
+ ldmfd sp!, {r1, r2, r4 - r8, pc}
+ .endm
+
+ .macro load1b, reg1
+ ldrusr \reg1, r0, 1
+ .endm
+
+ .macro load2b, reg1, reg2
+ ldrusr \reg1, r0, 1
+ ldrusr \reg2, r0, 1
+ .endm
+
+ .macro load1l, reg1
+ ldrusr \reg1, r0, 4
+ .endm
+
+ .macro load2l, reg1, reg2
+ ldrusr \reg1, r0, 4
+ ldrusr \reg2, r0, 4
+ .endm
+
+ .macro load4l, reg1, reg2, reg3, reg4
+ ldrusr \reg1, r0, 4
+ ldrusr \reg2, r0, 4
+ ldrusr \reg3, r0, 4
+ ldrusr \reg4, r0, 4
+ .endm
+
+/*
+ * unsigned int
+ * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
+ * r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
+ * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+ */
+
+#define FN_ENTRY ENTRY(csum_partial_copy_from_user)
+#define FN_EXIT ENDPROC(csum_partial_copy_from_user)
+
+#include "csumpartialcopygeneric.S"
+
+/*
+ * FIXME: minor buglet here
+ * We don't return the checksum for the data present in the buffer. To do
+ * so properly, we would have to add in whatever registers were loaded before
+ * the fault, which, with the current asm above is not predictable.
+ */
+ .pushsection .fixup,"ax"
+ .align 4
+9001: mov r4, #-EFAULT
+ ldr r5, [sp, #8*4] @ *err_ptr
+ str r4, [r5]
+ ldmia sp, {r1, r2} @ retrieve dst, len
+ add r2, r2, r1
+ mov r0, #0 @ zero the buffer
+9002: teq r2, r1
+ strneb r0, [r1], #1
+ bne 9002b
+ load_regs
+ .popsection
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S
new file mode 100644
index 00000000..3c9a05c8
--- /dev/null
+++ b/arch/arm/lib/delay.S
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/lib/delay.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/param.h>
+ .text
+
+.LC0: .word loops_per_jiffy
+.LC1: .word (2199023*HZ)>>11
+
+/*
+ * r0 <= 2000
+ * lpj <= 0x01ffffff (max. 3355 bogomips)
+ * HZ <= 1000
+ */
+
+ENTRY(__udelay)
+ ldr r2, .LC1
+ mul r0, r2, r0
+ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06
+ mov r1, #-1
+ ldr r2, .LC0
+ ldr r2, [r2] @ max = 0x01ffffff
+ add r0, r0, r1, lsr #32-14
+ mov r0, r0, lsr #14 @ max = 0x0001ffff
+ add r2, r2, r1, lsr #32-10
+ mov r2, r2, lsr #10 @ max = 0x00007fff
+ mul r0, r2, r0 @ max = 2^32-1
+ add r0, r0, r1, lsr #32-6
+ movs r0, r0, lsr #6
+ moveq pc, lr
+
+/*
+ * loops = r0 * HZ * loops_per_jiffy / 1000000
+ *
+ * Oh, if only we had a cycle counter...
+ */
+
+@ Delay routine
+ENTRY(__delay)
+ subs r0, r0, #1
+#if 0
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+ movls pc, lr
+ subs r0, r0, #1
+#endif
+ bhi __delay
+ mov pc, lr
+ENDPROC(__udelay)
+ENDPROC(__const_udelay)
+ENDPROC(__delay)
diff --git a/arch/arm/lib/div64.S b/arch/arm/lib/div64.S
new file mode 100644
index 00000000..faa77481
--- /dev/null
+++ b/arch/arm/lib/div64.S
@@ -0,0 +1,203 @@
+/*
+ * linux/arch/arm/lib/div64.S
+ *
+ * Optimized computation of 64-bit dividend / 32-bit divisor
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 5, 2003
+ * Copyright: Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+/*
+ * __do_div64: perform a division with 64-bit dividend and 32-bit divisor.
+ *
+ * Note: Calling convention is totally non standard for optimal code.
+ * This is meant to be used by do_div() from include/asm/div64.h only.
+ *
+ * Input parameters:
+ * xh-xl = dividend (clobbered)
+ * r4 = divisor (preserved)
+ *
+ * Output values:
+ * yh-yl = result
+ * xh = remainder
+ *
+ * Clobbered regs: xl, ip
+ */
+
+ENTRY(__do_div64)
+
+ @ Test for easy paths first.
+ subs ip, r4, #1
+ bls 9f @ divisor is 0 or 1
+ tst ip, r4
+ beq 8f @ divisor is power of 2
+
+ @ See if we need to handle upper 32-bit result.
+ cmp xh, r4
+ mov yh, #0
+ blo 3f
+
+ @ Align divisor with upper part of dividend.
+ @ The aligned divisor is stored in yl preserving the original.
+ @ The bit position is stored in ip.
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz yl, r4
+ clz ip, xh
+ sub yl, yl, ip
+ mov ip, #1
+ mov ip, ip, lsl yl
+ mov yl, r4, lsl yl
+
+#else
+
+ mov yl, r4
+ mov ip, #1
+1: cmp yl, #0x80000000
+ cmpcc yl, xh
+ movcc yl, yl, lsl #1
+ movcc ip, ip, lsl #1
+ bcc 1b
+
+#endif
+
+ @ The division loop for needed upper bit positions.
+ @ Break out early if dividend reaches 0.
+2: cmp xh, yl
+ orrcs yh, yh, ip
+ subcss xh, xh, yl
+ movnes ip, ip, lsr #1
+ mov yl, yl, lsr #1
+ bne 2b
+
+ @ See if we need to handle lower 32-bit result.
+3: cmp xh, #0
+ mov yl, #0
+ cmpeq xl, r4
+ movlo xh, xl
+ movlo pc, lr
+
+ @ The division loop for lower bit positions.
+ @ Here we shift remainer bits leftwards rather than moving the
+ @ divisor for comparisons, considering the carry-out bit as well.
+ mov ip, #0x80000000
+4: movs xl, xl, lsl #1
+ adcs xh, xh, xh
+ beq 6f
+ cmpcc xh, r4
+5: orrcs yl, yl, ip
+ subcs xh, xh, r4
+ movs ip, ip, lsr #1
+ bne 4b
+ mov pc, lr
+
+ @ The top part of remainder became zero. If carry is set
+ @ (the 33th bit) this is a false positive so resume the loop.
+ @ Otherwise, if lower part is also null then we are done.
+6: bcs 5b
+ cmp xl, #0
+ moveq pc, lr
+
+ @ We still have remainer bits in the low part. Bring them up.
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz xh, xl @ we know xh is zero here so...
+ add xh, xh, #1
+ mov xl, xl, lsl xh
+ mov ip, ip, lsr xh
+
+#else
+
+7: movs xl, xl, lsl #1
+ mov ip, ip, lsr #1
+ bcc 7b
+
+#endif
+
+ @ Current remainder is now 1. It is worthless to compare with
+ @ divisor at this point since divisor can not be smaller than 3 here.
+ @ If possible, branch for another shift in the division loop.
+ @ If no bit position left then we are done.
+ movs ip, ip, lsr #1
+ mov xh, #1
+ bne 4b
+ mov pc, lr
+
+8: @ Division by a power of 2: determine what that divisor order is
+ @ then simply shift values around
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz ip, r4
+ rsb ip, ip, #31
+
+#else
+
+ mov yl, r4
+ cmp r4, #(1 << 16)
+ mov ip, #0
+ movhs yl, yl, lsr #16
+ movhs ip, #16
+
+ cmp yl, #(1 << 8)
+ movhs yl, yl, lsr #8
+ addhs ip, ip, #8
+
+ cmp yl, #(1 << 4)
+ movhs yl, yl, lsr #4
+ addhs ip, ip, #4
+
+ cmp yl, #(1 << 2)
+ addhi ip, ip, #3
+ addls ip, ip, yl, lsr #1
+
+#endif
+
+ mov yh, xh, lsr ip
+ mov yl, xl, lsr ip
+ rsb ip, ip, #32
+ ARM( orr yl, yl, xh, lsl ip )
+ THUMB( lsl xh, xh, ip )
+ THUMB( orr yl, yl, xh )
+ mov xh, xl, lsl ip
+ mov xh, xh, lsr ip
+ mov pc, lr
+
+ @ eq -> division by 1: obvious enough...
+9: moveq yl, xl
+ moveq yh, xh
+ moveq xh, #0
+ moveq pc, lr
+
+ @ Division by 0:
+ str lr, [sp, #-8]!
+ bl __div0
+
+ @ as wrong as it could be...
+ mov yl, #0
+ mov yh, #0
+ mov xh, #0
+ ldr pc, [sp], #8
+
+ENDPROC(__do_div64)
diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S
new file mode 100644
index 00000000..8678eb2b
--- /dev/null
+++ b/arch/arm/lib/ecard.S
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/lib/ecard.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 27/03/03 Ian Molton Clean up CONFIG_CPU
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+#define CPSR2SPSR(rt) \
+ mrs rt, cpsr; \
+ msr spsr_cxsf, rt
+
+@ Purpose: call an expansion card loader to read bytes.
+@ Proto : char read_loader(int offset, char *card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_read)
+ stmfd sp!, {r4 - r12, lr}
+ mov r11, r1
+ mov r1, r0
+ CPSR2SPSR(r0)
+ mov lr, pc
+ mov pc, r2
+ ldmfd sp!, {r4 - r12, pc}
+
+@ Purpose: call an expansion card loader to reset the card
+@ Proto : void read_loader(int card_base, char *loader);
+@ Returns: byte read
+
+ENTRY(ecard_loader_reset)
+ stmfd sp!, {r4 - r12, lr}
+ mov r11, r0
+ CPSR2SPSR(r0)
+ mov lr, pc
+ add pc, r1, #8
+ ldmfd sp!, {r4 - r12, pc}
+
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
new file mode 100644
index 00000000..64f6bc1a
--- /dev/null
+++ b/arch/arm/lib/findbit.S
@@ -0,0 +1,196 @@
+/*
+ * linux/arch/arm/lib/findbit.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 16th March 2001 - John Ripley <jripley@sonicblue.com>
+ * Fixed so that "size" is an exclusive not an inclusive quantity.
+ * All users of these functions expect exclusive sizes, and may
+ * also call with zero size.
+ * Reworked by rmk.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
+ */
+ENTRY(_find_first_zero_bit_le)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1:
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_zero_bit_le)
+
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(_find_next_zero_bit_le)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_zero_bit_le)
+
+/*
+ * Purpose : Find a 'one' bit
+ * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
+ */
+ENTRY(_find_first_bit_le)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1:
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_bit_le)
+
+/*
+ * Purpose : Find next 'one' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(_find_next_bit_le)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_bit_le)
+
+#ifdef __ARMEB__
+
+ENTRY(_find_first_zero_bit_be)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_zero_bit_be)
+
+ENTRY(_find_next_zero_bit_be)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_zero_bit_be)
+
+ENTRY(_find_first_bit_be)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_bit_be)
+
+ENTRY(_find_next_bit_be)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_bit_be)
+
+#endif
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.L_found:
+#if __LINUX_ARM_ARCH__ >= 5
+ rsb r0, r3, #0
+ and r3, r3, r0
+ clz r3, r3
+ rsb r3, r3, #31
+ add r0, r2, r3
+#else
+ tst r3, #0x0f
+ addeq r2, r2, #4
+ movne r3, r3, lsl #4
+ tst r3, #0x30
+ addeq r2, r2, #2
+ movne r3, r3, lsl #2
+ tst r3, #0x40
+ addeq r2, r2, #1
+ mov r0, r2
+#endif
+ cmp r1, r0 @ Clamp to maxbit
+ movlo r0, r1
+ mov pc, lr
+
diff --git a/arch/arm/lib/floppydma.S b/arch/arm/lib/floppydma.S
new file mode 100644
index 00000000..617150b1
--- /dev/null
+++ b/arch/arm/lib/floppydma.S
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/lib/floppydma.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+ .global floppy_fiqin_end
+ENTRY(floppy_fiqin_start)
+ subs r9, r9, #1
+ ldrgtb r12, [r11, #-4]
+ ldrleb r12, [r11], #0
+ strb r12, [r10], #1
+ subs pc, lr, #4
+floppy_fiqin_end:
+
+ .global floppy_fiqout_end
+ENTRY(floppy_fiqout_start)
+ subs r9, r9, #1
+ ldrgeb r12, [r10], #1
+ movlt r12, #0
+ strleb r12, [r11], #0
+ subles pc, lr, #4
+ strb r12, [r11, #-4]
+ subs pc, lr, #4
+floppy_fiqout_end:
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
new file mode 100644
index 00000000..11093a7c
--- /dev/null
+++ b/arch/arm/lib/getuser.S
@@ -0,0 +1,73 @@
+/*
+ * linux/arch/arm/lib/getuser.S
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make them more
+ * efficient, especially as they return an error value in addition to
+ * the "real" return value.
+ *
+ * __get_user_X
+ *
+ * Inputs: r0 contains the address
+ * Outputs: r0 is the error code
+ * r2, r3 contains the zero-extended value
+ * lr corrupted
+ *
+ * No other registers must be altered. (see <asm/uaccess.h>
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000.
+ * Note also that it is intended that __get_user_bad is not global.
+ */
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+ENTRY(__get_user_1)
+1: TUSER(ldrb) r2, [r0]
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__get_user_1)
+
+ENTRY(__get_user_2)
+#ifdef CONFIG_THUMB2_KERNEL
+2: TUSER(ldrb) r2, [r0]
+3: TUSER(ldrb) r3, [r0, #1]
+#else
+2: TUSER(ldrb) r2, [r0], #1
+3: TUSER(ldrb) r3, [r0]
+#endif
+#ifndef __ARMEB__
+ orr r2, r2, r3, lsl #8
+#else
+ orr r2, r3, r2, lsl #8
+#endif
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__get_user_2)
+
+ENTRY(__get_user_4)
+4: TUSER(ldr) r2, [r0]
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__get_user_4)
+
+__get_user_bad:
+ mov r2, #0
+ mov r0, #-EFAULT
+ mov pc, lr
+ENDPROC(__get_user_bad)
+
+.pushsection __ex_table, "a"
+ .long 1b, __get_user_bad
+ .long 2b, __get_user_bad
+ .long 3b, __get_user_bad
+ .long 4b, __get_user_bad
+.popsection
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S
new file mode 100644
index 00000000..1b197ea7
--- /dev/null
+++ b/arch/arm/lib/io-acorn.S
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/lib/io-acorn.S
+ *
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 27/03/03 Ian Molton Clean up CONFIG_CPU
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align
+
+.Liosl_warning:
+ .ascii "<4>insl/outsl not implemented, called from %08lX\0"
+ .align
+
+/*
+ * These make no sense on Acorn machines.
+ * Print a warning message.
+ */
+ENTRY(insl)
+ENTRY(outsl)
+ adr r0, .Liosl_warning
+ mov r1, lr
+ b printk
diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S
new file mode 100644
index 00000000..9f423898
--- /dev/null
+++ b/arch/arm/lib/io-readsb.S
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+.Linsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1], #1
+ subs r2, r2, ip
+ bne .Linsb_aligned
+
+ENTRY(__raw_readsb)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne .Linsb_align
+
+.Linsb_aligned: stmfd sp!, {r4 - r6, lr}
+
+ subs r2, r2, #16
+ bmi .Linsb_no_16
+
+.Linsb_16_lp: ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3, put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4, put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ ldrb r5, [r0]
+ orr r4, r4, r6, put_byte_2
+ ldrb r6, [r0]
+ orr r4, r4, ip, put_byte_3
+ ldrb ip, [r0]
+ mov r5, r5, put_byte_0
+ ldrb lr, [r0]
+ orr r5, r5, r6, put_byte_1
+ ldrb r6, [r0]
+ orr r5, r5, ip, put_byte_2
+ ldrb ip, [r0]
+ orr r5, r5, lr, put_byte_3
+ ldrb lr, [r0]
+ mov r6, r6, put_byte_0
+ orr r6, r6, ip, put_byte_1
+ ldrb ip, [r0]
+ orr r6, r6, lr, put_byte_2
+ orr r6, r6, ip, put_byte_3
+ stmia r1!, {r3 - r6}
+
+ subs r2, r2, #16
+ bpl .Linsb_16_lp
+
+ tst r2, #15
+ ldmeqfd sp!, {r4 - r6, pc}
+
+.Linsb_no_16: tst r2, #8
+ beq .Linsb_no_8
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3, put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4, put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ orr r4, r4, r6, put_byte_2
+ orr r4, r4, ip, put_byte_3
+ stmia r1!, {r3, r4}
+
+.Linsb_no_8: tst r2, #4
+ beq .Linsb_no_4
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ ldrb r6, [r0]
+ mov r3, r3, put_byte_0
+ orr r3, r3, r4, put_byte_1
+ orr r3, r3, r5, put_byte_2
+ orr r3, r3, r6, put_byte_3
+ str r3, [r1], #4
+
+.Linsb_no_4: ands r2, r2, #3
+ ldmeqfd sp!, {r4 - r6, pc}
+
+ cmp r2, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1]
+
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(__raw_readsb)
diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S
new file mode 100644
index 00000000..5fb97e7f
--- /dev/null
+++ b/arch/arm/lib/io-readsl.S
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/lib/io-readsl.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(__raw_readsl)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne 3f
+
+ subs r2, r2, #4
+ bmi 2f
+ stmfd sp!, {r4, lr}
+1: ldr r3, [r0, #0]
+ ldr r4, [r0, #0]
+ ldr ip, [r0, #0]
+ ldr lr, [r0, #0]
+ subs r2, r2, #4
+ stmia r1!, {r3, r4, ip, lr}
+ bpl 1b
+ ldmfd sp!, {r4, lr}
+2: movs r2, r2, lsl #31
+ ldrcs r3, [r0, #0]
+ ldrcs ip, [r0, #0]
+ stmcsia r1!, {r3, ip}
+ ldrne r3, [r0, #0]
+ strne r3, [r1, #0]
+ mov pc, lr
+
+3: ldr r3, [r0]
+ cmp ip, #2
+ mov ip, r3, get_byte_0
+ strb ip, [r1], #1
+ bgt 6f
+ mov ip, r3, get_byte_1
+ strb ip, [r1], #1
+ beq 5f
+ mov ip, r3, get_byte_2
+ strb ip, [r1], #1
+
+4: subs r2, r2, #1
+ mov ip, r3, pull #24
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #8
+ strne ip, [r1], #4
+ bne 4b
+ b 8f
+
+5: subs r2, r2, #1
+ mov ip, r3, pull #16
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #16
+ strne ip, [r1], #4
+ bne 5b
+ b 7f
+
+6: subs r2, r2, #1
+ mov ip, r3, pull #8
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #24
+ strne ip, [r1], #4
+ bne 6b
+
+ mov r3, ip, get_byte_2
+ strb r3, [r1, #2]
+7: mov r3, ip, get_byte_1
+ strb r3, [r1, #1]
+8: mov r3, ip, get_byte_0
+ strb r3, [r1, #0]
+ mov pc, lr
+ENDPROC(__raw_readsl)
diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S
new file mode 100644
index 00000000..9aaf7c72
--- /dev/null
+++ b/arch/arm/lib/io-readsw-armv3.S
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/arm/lib/io-readsw-armv3.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+.Linsw_bad_alignment:
+ adr r0, .Linsw_bad_align_msg
+ mov r2, lr
+ b panic
+.Linsw_bad_align_msg:
+ .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.Linsw_align: tst r1, #1
+ bne .Linsw_bad_alignment
+
+ ldr r3, [r0]
+ strb r3, [r1], #1
+ mov r3, r3, lsr #8
+ strb r3, [r1], #1
+
+ subs r2, r2, #1
+ moveq pc, lr
+
+ENTRY(__raw_readsw)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ tst r1, #3
+ bne .Linsw_align
+
+.Linsw_aligned: mov ip, #0xff
+ orr ip, ip, ip, lsl #8
+ stmfd sp!, {r4, r5, r6, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_insw_8
+
+.Linsw_8_lp: ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldr r4, [r0]
+ and r4, r4, ip
+ ldr r5, [r0]
+ orr r4, r4, r5, lsl #16
+
+ ldr r5, [r0]
+ and r5, r5, ip
+ ldr r6, [r0]
+ orr r5, r5, r6, lsl #16
+
+ ldr r6, [r0]
+ and r6, r6, ip
+ ldr lr, [r0]
+ orr r6, r6, lr, lsl #16
+
+ stmia r1!, {r3 - r6}
+
+ subs r2, r2, #8
+ bpl .Linsw_8_lp
+
+ tst r2, #7
+ ldmeqfd sp!, {r4, r5, r6, pc}
+
+.Lno_insw_8: tst r2, #4
+ beq .Lno_insw_4
+
+ ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ ldr r4, [r0]
+ and r4, r4, ip
+ ldr r5, [r0]
+ orr r4, r4, r5, lsl #16
+
+ stmia r1!, {r3, r4}
+
+.Lno_insw_4: tst r2, #2
+ beq .Lno_insw_2
+
+ ldr r3, [r0]
+ and r3, r3, ip
+ ldr r4, [r0]
+ orr r3, r3, r4, lsl #16
+
+ str r3, [r1], #4
+
+.Lno_insw_2: tst r2, #1
+ ldrne r3, [r0]
+ strneb r3, [r1], #1
+ movne r3, r3, lsr #8
+ strneb r3, [r1]
+
+ ldmfd sp!, {r4, r5, r6, pc}
+
+
diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
new file mode 100644
index 00000000..1f393d42
--- /dev/null
+++ b/arch/arm/lib/io-readsw-armv4.S
@@ -0,0 +1,131 @@
+/*
+ * linux/arch/arm/lib/io-readsw-armv4.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .macro pack, rd, hw1, hw2
+#ifndef __ARMEB__
+ orr \rd, \hw1, \hw2, lsl #16
+#else
+ orr \rd, \hw2, \hw1, lsl #16
+#endif
+ .endm
+
+.Linsw_align: movs ip, r1, lsl #31
+ bne .Linsw_noalign
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ strh ip, [r1], #2
+
+ENTRY(__raw_readsw)
+ teq r2, #0
+ moveq pc, lr
+ tst r1, #3
+ bne .Linsw_align
+
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_insw_8
+
+.Linsw_8_lp: ldrh r3, [r0]
+ ldrh r4, [r0]
+ pack r3, r3, r4
+
+ ldrh r4, [r0]
+ ldrh r5, [r0]
+ pack r4, r4, r5
+
+ ldrh r5, [r0]
+ ldrh ip, [r0]
+ pack r5, r5, ip
+
+ ldrh ip, [r0]
+ ldrh lr, [r0]
+ pack ip, ip, lr
+
+ subs r2, r2, #8
+ stmia r1!, {r3 - r5, ip}
+ bpl .Linsw_8_lp
+
+.Lno_insw_8: tst r2, #4
+ beq .Lno_insw_4
+
+ ldrh r3, [r0]
+ ldrh r4, [r0]
+ pack r3, r3, r4
+
+ ldrh r4, [r0]
+ ldrh ip, [r0]
+ pack r4, r4, ip
+
+ stmia r1!, {r3, r4}
+
+.Lno_insw_4: movs r2, r2, lsl #31
+ bcc .Lno_insw_2
+
+ ldrh r3, [r0]
+ ldrh ip, [r0]
+ pack r3, r3, ip
+ str r3, [r1], #4
+
+.Lno_insw_2: ldrneh r3, [r0]
+ strneh r3, [r1]
+
+ ldmfd sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define _BE_ONLY_(code...) code
+#define _LE_ONLY_(code...)
+#define push_hbyte0 lsr #8
+#define pull_hbyte1 lsl #24
+#else
+#define _BE_ONLY_(code...)
+#define _LE_ONLY_(code...) code
+#define push_hbyte0 lsl #24
+#define pull_hbyte1 lsr #8
+#endif
+
+.Linsw_noalign: stmfd sp!, {r4, lr}
+ ldrccb ip, [r1, #-1]!
+ bcc 1f
+
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ _BE_ONLY_( mov ip, ip, ror #8 )
+ strb ip, [r1], #1
+ _LE_ONLY_( mov ip, ip, lsr #8 )
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+1: subs r2, r2, #2
+ bmi 3f
+ _BE_ONLY_( mov ip, ip, lsl #24 )
+
+2: ldrh r3, [r0]
+ ldrh r4, [r0]
+ subs r2, r2, #2
+ orr ip, ip, r3, lsl #8
+ orr ip, ip, r4, push_hbyte0
+ str ip, [r1], #4
+ mov ip, r4, pull_hbyte1
+ bpl 2b
+
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+3: tst r2, #1
+ strb ip, [r1], #1
+ ldrneh ip, [r0]
+ _BE_ONLY_( movne ip, ip, ror #8 )
+ strneb ip, [r1], #1
+ _LE_ONLY_( movne ip, ip, lsr #8 )
+ _BE_ONLY_( movne ip, ip, lsr #24 )
+ strneb ip, [r1]
+ ldmfd sp!, {r4, pc}
+ENDPROC(__raw_readsw)
diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c
new file mode 100644
index 00000000..82425394
--- /dev/null
+++ b/arch/arm/lib/io-shark.c
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/lib/io-shark.c
+ *
+ * by Alexander Schulz
+ *
+ * derived from:
+ * linux/arch/arm/lib/io-ebsa.S
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S
new file mode 100644
index 00000000..68b92f4a
--- /dev/null
+++ b/arch/arm/lib/io-writesb.S
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/lib/io-writesb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .macro outword, rd
+#ifndef __ARMEB__
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+#else
+ mov lr, \rd, lsr #24
+ strb lr, [r0]
+ mov lr, \rd, lsr #16
+ strb lr, [r0]
+ mov lr, \rd, lsr #8
+ strb lr, [r0]
+ strb \rd, [r0]
+#endif
+ .endm
+
+.Loutsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0]
+ subs r2, r2, ip
+ bne .Loutsb_aligned
+
+ENTRY(__raw_writesb)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne .Loutsb_align
+
+.Loutsb_aligned:
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #16
+ bmi .Loutsb_no_16
+
+.Loutsb_16_lp: ldmia r1!, {r3, r4, r5, ip}
+ outword r3
+ outword r4
+ outword r5
+ outword ip
+ subs r2, r2, #16
+ bpl .Loutsb_16_lp
+
+ tst r2, #15
+ ldmeqfd sp!, {r4, r5, pc}
+
+.Loutsb_no_16: tst r2, #8
+ beq .Loutsb_no_8
+
+ ldmia r1!, {r3, r4}
+ outword r3
+ outword r4
+
+.Loutsb_no_8: tst r2, #4
+ beq .Loutsb_no_4
+
+ ldr r3, [r1], #4
+ outword r3
+
+.Loutsb_no_4: ands r2, r2, #3
+ ldmeqfd sp!, {r4, r5, pc}
+
+ cmp r2, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1]
+ strgtb r3, [r0]
+
+ ldmfd sp!, {r4, r5, pc}
+ENDPROC(__raw_writesb)
diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S
new file mode 100644
index 00000000..8d3b7813
--- /dev/null
+++ b/arch/arm/lib/io-writesl.S
@@ -0,0 +1,67 @@
+/*
+ * linux/arch/arm/lib/io-writesl.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ENTRY(__raw_writesl)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne 3f
+
+ subs r2, r2, #4
+ bmi 2f
+ stmfd sp!, {r4, lr}
+1: ldmia r1!, {r3, r4, ip, lr}
+ subs r2, r2, #4
+ str r3, [r0, #0]
+ str r4, [r0, #0]
+ str ip, [r0, #0]
+ str lr, [r0, #0]
+ bpl 1b
+ ldmfd sp!, {r4, lr}
+2: movs r2, r2, lsl #31
+ ldmcsia r1!, {r3, ip}
+ strcs r3, [r0, #0]
+ ldrne r3, [r1, #0]
+ strcs ip, [r0, #0]
+ strne r3, [r0, #0]
+ mov pc, lr
+
+3: bic r1, r1, #3
+ ldr r3, [r1], #4
+ cmp ip, #2
+ blt 5f
+ bgt 6f
+
+4: mov ip, r3, pull #16
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #16
+ str ip, [r0]
+ bne 4b
+ mov pc, lr
+
+5: mov ip, r3, pull #8
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #24
+ str ip, [r0]
+ bne 5b
+ mov pc, lr
+
+6: mov ip, r3, pull #24
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #8
+ str ip, [r0]
+ bne 6b
+ mov pc, lr
+ENDPROC(__raw_writesl)
diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S
new file mode 100644
index 00000000..cd34503e
--- /dev/null
+++ b/arch/arm/lib/io-writesw-armv3.S
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/arm/lib/io-writesw-armv3.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+.Loutsw_bad_alignment:
+ adr r0, .Loutsw_bad_align_msg
+ mov r2, lr
+ b panic
+.Loutsw_bad_align_msg:
+ .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
+ .align
+
+.Loutsw_align: tst r1, #1
+ bne .Loutsw_bad_alignment
+
+ add r1, r1, #2
+
+ ldr r3, [r1, #-4]
+ mov r3, r3, lsr #16
+ orr r3, r3, r3, lsl #16
+ str r3, [r0]
+ subs r2, r2, #1
+ moveq pc, lr
+
+ENTRY(__raw_writesw)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ tst r1, #3
+ bne .Loutsw_align
+
+ stmfd sp!, {r4, r5, r6, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_outsw_8
+
+.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, r6}
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r4, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r4, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r5, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r5, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r6, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r6, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ subs r2, r2, #8
+ bpl .Loutsw_8_lp
+
+ tst r2, #7
+ ldmeqfd sp!, {r4, r5, r6, pc}
+
+.Lno_outsw_8: tst r2, #4
+ beq .Lno_outsw_4
+
+ ldmia r1!, {r3, r4}
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+ mov ip, r4, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r4, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+.Lno_outsw_4: tst r2, #2
+ beq .Lno_outsw_2
+
+ ldr r3, [r1], #4
+
+ mov ip, r3, lsl #16
+ orr ip, ip, ip, lsr #16
+ str ip, [r0]
+
+ mov ip, r3, lsr #16
+ orr ip, ip, ip, lsl #16
+ str ip, [r0]
+
+.Lno_outsw_2: tst r2, #1
+
+ ldrne r3, [r1]
+
+ movne ip, r3, lsl #16
+ orrne ip, ip, ip, lsr #16
+ strne ip, [r0]
+
+ ldmfd sp!, {r4, r5, r6, pc}
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
new file mode 100644
index 00000000..ff4f71b5
--- /dev/null
+++ b/arch/arm/lib/io-writesw-armv4.S
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/lib/io-writesw-armv4.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .macro outword, rd
+#ifndef __ARMEB__
+ strh \rd, [r0]
+ mov \rd, \rd, lsr #16
+ strh \rd, [r0]
+#else
+ mov lr, \rd, lsr #16
+ strh lr, [r0]
+ strh \rd, [r0]
+#endif
+ .endm
+
+.Loutsw_align: movs ip, r1, lsl #31
+ bne .Loutsw_noalign
+
+ ldrh r3, [r1], #2
+ sub r2, r2, #1
+ strh r3, [r0]
+
+ENTRY(__raw_writesw)
+ teq r2, #0
+ moveq pc, lr
+ ands r3, r1, #3
+ bne .Loutsw_align
+
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_outsw_8
+
+.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
+ subs r2, r2, #8
+ outword r3
+ outword r4
+ outword r5
+ outword ip
+ bpl .Loutsw_8_lp
+
+.Lno_outsw_8: tst r2, #4
+ beq .Lno_outsw_4
+
+ ldmia r1!, {r3, ip}
+ outword r3
+ outword ip
+
+.Lno_outsw_4: movs r2, r2, lsl #31
+ bcc .Lno_outsw_2
+
+ ldr r3, [r1], #4
+ outword r3
+
+.Lno_outsw_2: ldrneh r3, [r1]
+ strneh r3, [r0]
+
+ ldmfd sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define pull_hbyte0 lsl #8
+#define push_hbyte1 lsr #24
+#else
+#define pull_hbyte0 lsr #24
+#define push_hbyte1 lsl #8
+#endif
+
+.Loutsw_noalign:
+ ARM( ldr r3, [r1, -r3]! )
+ THUMB( rsb r3, r3, #0 )
+ THUMB( ldr r3, [r1, r3] )
+ THUMB( sub r1, r3 )
+ subcs r2, r2, #1
+ bcs 2f
+ subs r2, r2, #2
+ bmi 3f
+
+1: mov ip, r3, lsr #8
+ strh ip, [r0]
+2: mov ip, r3, pull_hbyte0
+ ldr r3, [r1, #4]!
+ subs r2, r2, #2
+ orr ip, ip, r3, push_hbyte1
+ strh ip, [r0]
+ bpl 1b
+
+ tst r2, #1
+3: movne ip, r3, lsr #8
+ strneh ip, [r0]
+ mov pc, lr
+ENDPROC(__raw_writesw)
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
new file mode 100644
index 00000000..c562f649
--- /dev/null
+++ b/arch/arm/lib/lib1funcs.S
@@ -0,0 +1,363 @@
+/*
+ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
+ *
+ * Author: Nicolas Pitre <nico@fluxnic.net>
+ * - contributed to gcc-3.4 on Sep 30, 2003
+ * - adapted for the Linux kernel on Oct 2, 2003
+ */
+
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+
+This 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/unwind.h>
+
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \curbit, \divisor
+ clz \result, \dividend
+ sub \result, \curbit, \result
+ mov \curbit, #1
+ mov \divisor, \divisor, lsl \result
+ mov \curbit, \curbit, lsl \result
+ mov \result, #0
+
+#else
+
+ @ Initially shift the divisor left 3 bits if possible,
+ @ set curbit accordingly. This allows for curbit to be located
+ @ at the left end of each 4 bit nibbles in the division loop
+ @ to save one loop in most cases.
+ tst \divisor, #0xe0000000
+ moveq \divisor, \divisor, lsl #3
+ moveq \curbit, #8
+ movne \curbit, #1
+
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ movlo \curbit, \curbit, lsl #4
+ blo 1b
+
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ movlo \curbit, \curbit, lsl #1
+ blo 1b
+
+ mov \result, #0
+
+#endif
+
+ @ Division loop
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ orrhs \result, \result, \curbit
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ orrhs \result, \result, \curbit, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ orrhs \result, \result, \curbit, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
+
+.endm
+
+
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ rsb \order, \order, #31
+
+#else
+
+ cmp \divisor, #(1 << 16)
+ movhs \divisor, \divisor, lsr #16
+ movhs \order, #16
+ movlo \order, #0
+
+ cmp \divisor, #(1 << 8)
+ movhs \divisor, \divisor, lsr #8
+ addhs \order, \order, #8
+
+ cmp \divisor, #(1 << 4)
+ movhs \divisor, \divisor, lsr #4
+ addhs \order, \order, #4
+
+ cmp \divisor, #(1 << 2)
+ addhi \order, \order, #3
+ addls \order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+
+
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ clz \spare, \dividend
+ sub \order, \order, \spare
+ mov \divisor, \divisor, lsl \order
+
+#else
+
+ mov \order, #0
+
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ addlo \order, \order, #4
+ blo 1b
+
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ addlo \order, \order, #1
+ blo 1b
+
+#endif
+
+ @ Perform all needed substractions to keep only the reminder.
+ @ Do comparisons in batch of 4 first.
+ subs \order, \order, #3 @ yes, 3 is intended here
+ blt 2f
+
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ cmp \dividend, #1
+ mov \divisor, \divisor, lsr #4
+ subges \order, \order, #4
+ bge 1b
+
+ tst \order, #3
+ teqne \dividend, #0
+ beq 5f
+
+ @ Either 1, 2 or 3 comparison/substractions are left.
+2: cmn \order, #2
+ blt 4f
+ beq 3f
+ cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+3: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+4: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+5:
+.endm
+
+
+ENTRY(__udivsi3)
+ENTRY(__aeabi_uidiv)
+UNWIND(.fnstart)
+
+ subs r2, r1, #1
+ moveq pc, lr
+ bcc Ldiv0
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
+
+ ARM_DIV_BODY r0, r1, r2, r3
+
+ mov r0, r2
+ mov pc, lr
+
+11: moveq r0, #1
+ movne r0, #0
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__udivsi3)
+ENDPROC(__aeabi_uidiv)
+
+ENTRY(__umodsi3)
+UNWIND(.fnstart)
+
+ subs r2, r1, #1 @ compare divisor with 1
+ bcc Ldiv0
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ movls pc, lr
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__umodsi3)
+
+ENTRY(__divsi3)
+ENTRY(__aeabi_idiv)
+UNWIND(.fnstart)
+
+ cmp r1, #0
+ eor ip, r0, r1 @ save the sign of the result.
+ beq Ldiv0
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ subs r2, r1, #1 @ division by 1 or -1 ?
+ beq 10f
+ movs r3, r0
+ rsbmi r3, r0, #0 @ positive dividend value
+ cmp r3, r1
+ bls 11f
+ tst r1, r2 @ divisor is power of 2 ?
+ beq 12f
+
+ ARM_DIV_BODY r3, r1, r0, r2
+
+ cmp ip, #0
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__divsi3)
+ENDPROC(__aeabi_idiv)
+
+ENTRY(__modsi3)
+UNWIND(.fnstart)
+
+ cmp r1, #0
+ beq Ldiv0
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ movs ip, r0 @ preserve sign of dividend
+ rsbmi r0, r0, #0 @ if negative make positive
+ subs r2, r1, #1 @ compare divisor with 1
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ bls 10f
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+10: cmp ip, #0
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__modsi3)
+
+#ifdef CONFIG_AEABI
+
+ENTRY(__aeabi_uidivmod)
+UNWIND(.fnstart)
+UNWIND(.save {r0, r1, ip, lr} )
+
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_uidiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__aeabi_uidivmod)
+
+ENTRY(__aeabi_idivmod)
+UNWIND(.fnstart)
+UNWIND(.save {r0, r1, ip, lr} )
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_idiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+UNWIND(.fnend)
+ENDPROC(__aeabi_idivmod)
+
+#endif
+
+Ldiv0:
+UNWIND(.fnstart)
+UNWIND(.pad #4)
+UNWIND(.save {lr})
+ str lr, [sp, #-8]!
+ bl __div0
+ mov r0, #0 @ About as wrong as it could be.
+ ldr pc, [sp], #8
+UNWIND(.fnend)
+ENDPROC(Ldiv0)
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
new file mode 100644
index 00000000..f83d4491
--- /dev/null
+++ b/arch/arm/lib/lshrdi3.S
@@ -0,0 +1,53 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT 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, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+ENTRY(__lshrdi3)
+ENTRY(__aeabi_llsr)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, lsr r3
+ ARM( orrmi al, al, ah, lsl ip )
+ THUMB( lslmi r3, ah, ip )
+ THUMB( orrmi al, al, r3 )
+ mov ah, ah, lsr r2
+ mov pc, lr
+
+ENDPROC(__lshrdi3)
+ENDPROC(__aeabi_llsr)
diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S
new file mode 100644
index 00000000..1da86991
--- /dev/null
+++ b/arch/arm/lib/memchr.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/memchr.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+ENTRY(memchr)
+1: subs r2, r2, #1
+ bmi 2f
+ ldrb r3, [r0], #1
+ teq r3, r1
+ bne 1b
+ sub r0, r0, #1
+2: movne r0, #0
+ mov pc, lr
+ENDPROC(memchr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
new file mode 100644
index 00000000..a9b9e228
--- /dev/null
+++ b/arch/arm/lib/memcpy.S
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/arm/lib/memcpy.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#define LDR1W_SHIFT 0
+#define STR1W_SHIFT 0
+
+ .macro ldr1w ptr reg abort
+ W(ldr) \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+ W(str) \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ stmdb sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+ENTRY(memcpy)
+
+#include "copy_template.S"
+
+ENDPROC(memcpy)
diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
new file mode 100644
index 00000000..938fc14f
--- /dev/null
+++ b/arch/arm/lib/memmove.S
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/lib/memmove.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: (C) MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/*
+ * Prototype: void *memmove(void *dest, const void *src, size_t n);
+ *
+ * Note:
+ *
+ * If the memory regions don't overlap, we simply branch to memcpy which is
+ * normally a bit faster. Otherwise the copy is done going downwards. This
+ * is a transposition of the code from copy_template.S but with the copy
+ * occurring in the opposite direction.
+ */
+
+ENTRY(memmove)
+
+ subs ip, r0, r1
+ cmphi r2, ip
+ bls memcpy
+
+ stmfd sp!, {r0, r4, lr}
+ add r1, r1, r2
+ add r0, r0, r2
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #-4] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, ip ) @ C is set here
+ CALGN( rsb ip, ip, #32 )
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #-4] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #-32] )
+ PLD( blt 4f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+3: PLD( pld [r1, #-128] )
+4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ subs r2, r2, #32
+ stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6: W(nop)
+ W(ldr) r3, [r1, #-4]!
+ W(ldr) r4, [r1, #-4]!
+ W(ldr) r5, [r1, #-4]!
+ W(ldr) r6, [r1, #-4]!
+ W(ldr) r7, [r1, #-4]!
+ W(ldr) r8, [r1, #-4]!
+ W(ldr) lr, [r1, #-4]!
+
+ add pc, pc, ip
+ nop
+ W(nop)
+ W(str) r3, [r0, #-4]!
+ W(str) r4, [r0, #-4]!
+ W(str) r5, [r0, #-4]!
+ W(str) r6, [r0, #-4]!
+ W(str) r7, [r0, #-4]!
+ W(str) r8, [r0, #-4]!
+ W(str) lr, [r0, #-4]!
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldrneb r3, [r1, #-1]!
+ ldrcsb r4, [r1, #-1]!
+ ldrcsb ip, [r1, #-1]
+ strneb r3, [r0, #-1]!
+ strcsb r4, [r0, #-1]!
+ strcsb ip, [r0, #-1]
+ ldmfd sp!, {r0, r4, pc}
+
+9: cmp ip, #2
+ ldrgtb r3, [r1, #-1]!
+ ldrgeb r4, [r1, #-1]!
+ ldrb lr, [r1, #-1]!
+ strgtb r3, [r0, #-1]!
+ strgeb r4, [r0, #-1]!
+ subs r2, r2, ip
+ strb lr, [r0, #-1]!
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr r3, [r1, #0]
+ beq 17f
+ blt 18f
+
+
+ .macro backward_copy_shift push pull
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #-4] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #-32] )
+ PLD( blt 13f )
+ PLD( pld [r1, #-64] )
+ PLD( pld [r1, #-96] )
+
+12: PLD( pld [r1, #-128] )
+13: ldmdb r1!, {r7, r8, r9, ip}
+ mov lr, r3, push #\push
+ subs r2, r2, #32
+ ldmdb r1!, {r3, r4, r5, r6}
+ orr lr, lr, ip, pull #\pull
+ mov ip, ip, push #\push
+ orr ip, ip, r9, pull #\pull
+ mov r9, r9, push #\push
+ orr r9, r9, r8, pull #\pull
+ mov r8, r8, push #\push
+ orr r8, r8, r7, pull #\pull
+ mov r7, r7, push #\push
+ orr r7, r7, r6, pull #\pull
+ mov r6, r6, push #\push
+ orr r6, r6, r5, pull #\pull
+ mov r5, r5, push #\push
+ orr r5, r5, r4, pull #\pull
+ mov r4, r4, push #\push
+ orr r4, r4, r3, pull #\pull
+ stmdb r0!, {r4 - r9, ip, lr}
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov lr, r3, push #\push
+ ldr r3, [r1, #-4]!
+ subs ip, ip, #4
+ orr lr, lr, r3, pull #\pull
+ str lr, [r0, #-4]!
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: add r1, r1, #(\pull / 8)
+ b 8b
+
+ .endm
+
+
+ backward_copy_shift push=8 pull=24
+
+17: backward_copy_shift push=16 pull=16
+
+18: backward_copy_shift push=24 pull=8
+
+ENDPROC(memmove)
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
new file mode 100644
index 00000000..650d5923
--- /dev/null
+++ b/arch/arm/lib/memset.S
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/arm/lib/memset.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+ .word 0
+
+1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [r0], #1 @ 1
+ strleb r1, [r0], #1 @ 1
+ strb r1, [r0], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memset again.
+ */
+
+ENTRY(memset)
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]!
+ mov ip, r1
+ mov lr, r1
+
+2: subs r2, r2, #64
+ stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ bgt 2b
+ ldmeqfd sp!, {pc} @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia r0!, {r1, r3, ip, lr}
+ stmneia r0!, {r1, r3, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r1, r3, ip, lr}
+ ldr lr, [sp], #4
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r7, lr}
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+ mov ip, r1
+ mov lr, r1
+
+ cmp r2, #96
+ tstgt r0, #31
+ ble 3f
+
+ and ip, r0, #31
+ rsb ip, ip, #32
+ sub r2, r2, ip
+ movs ip, ip, lsl #(32 - 4)
+ stmcsia r0!, {r4, r5, r6, r7}
+ stmmiia r0!, {r4, r5}
+ tst ip, #(1 << 30)
+ mov ip, r1
+ strne r1, [r0], #4
+
+3: subs r2, r2, #64
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r7, pc}
+
+ tst r2, #32
+ stmneia r0!, {r1, r3-r7, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r4-r7}
+ ldmfd sp!, {r4-r7, lr}
+
+#endif
+
+4: tst r2, #8
+ stmneia r0!, {r1, r3}
+ tst r2, #4
+ strne r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [r0], #1
+ strneb r1, [r0], #1
+ tst r2, #1
+ strneb r1, [r0], #1
+ mov pc, lr
+ENDPROC(memset)
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
new file mode 100644
index 00000000..3fbdef5f
--- /dev/null
+++ b/arch/arm/lib/memzero.S
@@ -0,0 +1,125 @@
+/*
+ * linux/arch/arm/lib/memzero.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+ .word 0
+/*
+ * Align the pointer in r0. r3 contains the number of bytes that we are
+ * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
+ * don't bother; we use byte stores instead.
+ */
+1: subs r1, r1, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r2, [r0], #1 @ 1
+ strleb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memzero again.
+ */
+
+ENTRY(__memzero)
+ mov r2, #0 @ 1
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
+ */
+ cmp r1, #16 @ 1 we can skip this chunk if we
+ blt 4f @ 1 have < 16 bytes
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]! @ 1
+ mov ip, r2 @ 1
+ mov lr, r2 @ 1
+
+3: subs r1, r1, #64 @ 1 write 32 bytes out per loop
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ bgt 3b @ 1
+ ldmeqfd sp!, {pc} @ 1/2 quick exit
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r1, #32 @ 1
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ tst r1, #16 @ 1 16 bytes or more?
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ ldr lr, [sp], #4 @ 1
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r7, lr}
+ mov r4, r2
+ mov r5, r2
+ mov r6, r2
+ mov r7, r2
+ mov ip, r2
+ mov lr, r2
+
+ cmp r1, #96
+ andgts ip, r0, #31
+ ble 3f
+
+ rsb ip, ip, #32
+ sub r1, r1, ip
+ movs ip, ip, lsl #(32 - 4)
+ stmcsia r0!, {r4, r5, r6, r7}
+ stmmiia r0!, {r4, r5}
+ movs ip, ip, lsl #2
+ strcs r2, [r0], #4
+
+3: subs r1, r1, #64
+ stmgeia r0!, {r2-r7, ip, lr}
+ stmgeia r0!, {r2-r7, ip, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r7, pc}
+
+ tst r1, #32
+ stmneia r0!, {r2-r7, ip, lr}
+ tst r1, #16
+ stmneia r0!, {r4-r7}
+ ldmfd sp!, {r4-r7, lr}
+
+#endif
+
+4: tst r1, #8 @ 1 8 bytes or more?
+ stmneia r0!, {r2, r3} @ 2
+ tst r1, #4 @ 1 4 bytes or more?
+ strne r2, [r0], #4 @ 1
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r1, #2 @ 1 2 bytes or more?
+ strneb r2, [r0], #1 @ 1
+ strneb r2, [r0], #1 @ 1
+ tst r1, #1 @ 1 a byte left over
+ strneb r2, [r0], #1 @ 1
+ mov pc, lr @ 1
+ENDPROC(__memzero)
diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S
new file mode 100644
index 00000000..36c91b49
--- /dev/null
+++ b/arch/arm/lib/muldi3.S
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/lib/muldi3.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__muldi3)
+ENTRY(__aeabi_lmul)
+
+ mul xh, yl, xh
+ mla xh, xl, yh, xh
+ mov ip, xl, lsr #16
+ mov yh, yl, lsr #16
+ bic xl, xl, ip, lsl #16
+ bic yl, yl, yh, lsl #16
+ mla xh, yh, ip, xh
+ mul yh, xl, yh
+ mul xl, yl, xl
+ mul ip, yl, ip
+ adds xl, xl, yh, lsl #16
+ adc xh, xh, yh, lsr #16
+ adds xl, xl, ip, lsl #16
+ adc xh, xh, ip, lsr #16
+ mov pc, lr
+
+ENDPROC(__muldi3)
+ENDPROC(__aeabi_lmul)
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
new file mode 100644
index 00000000..7db25990
--- /dev/null
+++ b/arch/arm/lib/putuser.S
@@ -0,0 +1,92 @@
+/*
+ * linux/arch/arm/lib/putuser.S
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
+ *
+ * These functions have a non-standard call interface to make
+ * them more efficient, especially as they return an error
+ * value in addition to the "real" return value.
+ *
+ * __put_user_X
+ *
+ * Inputs: r0 contains the address
+ * r2, r3 contains the value
+ * Outputs: r0 is the error code
+ * lr corrupted
+ *
+ * No other registers must be altered. (see <asm/uaccess.h>
+ * for specific ASM register usage).
+ *
+ * Note that ADDR_LIMIT is either 0 or 0xc0000000
+ * Note also that it is intended that __put_user_bad is not global.
+ */
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+ENTRY(__put_user_1)
+1: TUSER(strb) r2, [r0]
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__put_user_1)
+
+ENTRY(__put_user_2)
+ mov ip, r2, lsr #8
+#ifdef CONFIG_THUMB2_KERNEL
+#ifndef __ARMEB__
+2: TUSER(strb) r2, [r0]
+3: TUSER(strb) ip, [r0, #1]
+#else
+2: TUSER(strb) ip, [r0]
+3: TUSER(strb) r2, [r0, #1]
+#endif
+#else /* !CONFIG_THUMB2_KERNEL */
+#ifndef __ARMEB__
+2: TUSER(strb) r2, [r0], #1
+3: TUSER(strb) ip, [r0]
+#else
+2: TUSER(strb) ip, [r0], #1
+3: TUSER(strb) r2, [r0]
+#endif
+#endif /* CONFIG_THUMB2_KERNEL */
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__put_user_2)
+
+ENTRY(__put_user_4)
+4: TUSER(str) r2, [r0]
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__put_user_4)
+
+ENTRY(__put_user_8)
+#ifdef CONFIG_THUMB2_KERNEL
+5: TUSER(str) r2, [r0]
+6: TUSER(str) r3, [r0, #4]
+#else
+5: TUSER(str) r2, [r0], #4
+6: TUSER(str) r3, [r0]
+#endif
+ mov r0, #0
+ mov pc, lr
+ENDPROC(__put_user_8)
+
+__put_user_bad:
+ mov r0, #-EFAULT
+ mov pc, lr
+ENDPROC(__put_user_bad)
+
+.pushsection __ex_table, "a"
+ .long 1b, __put_user_bad
+ .long 2b, __put_user_bad
+ .long 3b, __put_user_bad
+ .long 4b, __put_user_bad
+ .long 5b, __put_user_bad
+ .long 6b, __put_user_bad
+.popsection
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
new file mode 100644
index 00000000..bbee5c66
--- /dev/null
+++ b/arch/arm/lib/setbit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/setbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_set_bit)
+ bitop orr
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/sha1.S b/arch/arm/lib/sha1.S
new file mode 100644
index 00000000..eb0edb80
--- /dev/null
+++ b/arch/arm/lib/sha1.S
@@ -0,0 +1,211 @@
+/*
+ * linux/arch/arm/lib/sha1.S
+ *
+ * SHA transform optimized for ARM
+ *
+ * Copyright: (C) 2005 by Nicolas Pitre <nico@fluxnic.net>
+ * Created: September 17, 2005
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The reference implementation for this code is linux/lib/sha1.c
+ */
+
+#include <linux/linkage.h>
+
+ .text
+
+
+/*
+ * void sha_transform(__u32 *digest, const char *in, __u32 *W)
+ *
+ * Note: the "in" ptr may be unaligned.
+ */
+
+ENTRY(sha_transform)
+
+ stmfd sp!, {r4 - r8, lr}
+
+ @ for (i = 0; i < 16; i++)
+ @ W[i] = be32_to_cpu(in[i]);
+
+#ifdef __ARMEB__
+ mov r4, r0
+ mov r0, r2
+ mov r2, #64
+ bl memcpy
+ mov r2, r0
+ mov r0, r4
+#else
+ mov r3, r2
+ mov lr, #16
+1: ldrb r4, [r1], #1
+ ldrb r5, [r1], #1
+ ldrb r6, [r1], #1
+ ldrb r7, [r1], #1
+ subs lr, lr, #1
+ orr r5, r5, r4, lsl #8
+ orr r6, r6, r5, lsl #8
+ orr r7, r7, r6, lsl #8
+ str r7, [r3], #4
+ bne 1b
+#endif
+
+ @ for (i = 0; i < 64; i++)
+ @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31);
+
+ sub r3, r2, #4
+ mov lr, #64
+2: ldr r4, [r3, #4]!
+ subs lr, lr, #1
+ ldr r5, [r3, #8]
+ ldr r6, [r3, #32]
+ ldr r7, [r3, #52]
+ eor r4, r4, r5
+ eor r4, r4, r6
+ eor r4, r4, r7
+ mov r4, r4, ror #31
+ str r4, [r3, #64]
+ bne 2b
+
+ /*
+ * The SHA functions are:
+ *
+ * f1(B,C,D) = (D ^ (B & (C ^ D)))
+ * f2(B,C,D) = (B ^ C ^ D)
+ * f3(B,C,D) = ((B & C) | (D & (B | C)))
+ *
+ * Then the sub-blocks are processed as follows:
+ *
+ * A' = ror(A, 27) + f(B,C,D) + E + K + *W++
+ * B' = A
+ * C' = ror(B, 2)
+ * D' = C
+ * E' = D
+ *
+ * We therefore unroll each loop 5 times to avoid register shuffling.
+ * Also the ror for C (and also D and E which are successivelyderived
+ * from it) is applied in place to cut on an additional mov insn for
+ * each round.
+ */
+
+ .macro sha_f1, A, B, C, D, E
+ ldr r3, [r2], #4
+ eor ip, \C, \D
+ add \E, r1, \E, ror #2
+ and ip, \B, ip, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f2, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ eor ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ eor ip, ip, \D, ror #2
+ add \E, \E, r3
+ add \E, \E, ip
+ .endm
+
+ .macro sha_f3, A, B, C, D, E
+ ldr r3, [r2], #4
+ add \E, r1, \E, ror #2
+ orr ip, \B, \C, ror #2
+ add \E, \E, \A, ror #27
+ and ip, ip, \D, ror #2
+ add \E, \E, r3
+ and r3, \B, \C, ror #2
+ orr ip, ip, r3
+ add \E, \E, ip
+ .endm
+
+ ldmia r0, {r4 - r8}
+
+ mov lr, #4
+ ldr r1, .L_sha_K + 0
+
+ /* adjust initial values */
+ mov r6, r6, ror #30
+ mov r7, r7, ror #30
+ mov r8, r8, ror #30
+
+3: subs lr, lr, #1
+ sha_f1 r4, r5, r6, r7, r8
+ sha_f1 r8, r4, r5, r6, r7
+ sha_f1 r7, r8, r4, r5, r6
+ sha_f1 r6, r7, r8, r4, r5
+ sha_f1 r5, r6, r7, r8, r4
+ bne 3b
+
+ ldr r1, .L_sha_K + 4
+ mov lr, #4
+
+4: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 4b
+
+ ldr r1, .L_sha_K + 8
+ mov lr, #4
+
+5: subs lr, lr, #1
+ sha_f3 r4, r5, r6, r7, r8
+ sha_f3 r8, r4, r5, r6, r7
+ sha_f3 r7, r8, r4, r5, r6
+ sha_f3 r6, r7, r8, r4, r5
+ sha_f3 r5, r6, r7, r8, r4
+ bne 5b
+
+ ldr r1, .L_sha_K + 12
+ mov lr, #4
+
+6: subs lr, lr, #1
+ sha_f2 r4, r5, r6, r7, r8
+ sha_f2 r8, r4, r5, r6, r7
+ sha_f2 r7, r8, r4, r5, r6
+ sha_f2 r6, r7, r8, r4, r5
+ sha_f2 r5, r6, r7, r8, r4
+ bne 6b
+
+ ldmia r0, {r1, r2, r3, ip, lr}
+ add r4, r1, r4
+ add r5, r2, r5
+ add r6, r3, r6, ror #2
+ add r7, ip, r7, ror #2
+ add r8, lr, r8, ror #2
+ stmia r0, {r4 - r8}
+
+ ldmfd sp!, {r4 - r8, pc}
+
+ENDPROC(sha_transform)
+
+ .align 2
+.L_sha_K:
+ .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
+
+
+/*
+ * void sha_init(__u32 *buf)
+ */
+
+ .align 2
+.L_sha_initial_digest:
+ .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
+
+ENTRY(sha_init)
+
+ str lr, [sp, #-4]!
+ adr r1, .L_sha_initial_digest
+ ldmia r1, {r1, r2, r3, ip, lr}
+ stmia r0, {r1, r2, r3, ip, lr}
+ ldr pc, [sp], #4
+
+ENDPROC(sha_init)
diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S
new file mode 100644
index 00000000..d8f2a1c1
--- /dev/null
+++ b/arch/arm/lib/strchr.S
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/lib/strchr.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+ENTRY(strchr)
+ and r1, r1, #0xff
+1: ldrb r2, [r0], #1
+ teq r2, r1
+ teqne r2, #0
+ bne 1b
+ teq r2, r1
+ movne r0, #0
+ subeq r0, r0, #1
+ mov pc, lr
+ENDPROC(strchr)
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
new file mode 100644
index 00000000..f202d7bd
--- /dev/null
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/lib/strncpy_from_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/*
+ * Copy a string from user space to kernel space.
+ * r0 = dst, r1 = src, r2 = byte length
+ * returns the number of characters copied (strlen of copied string),
+ * -EFAULT on exception, or "len" if we fill the whole buffer
+ */
+ENTRY(__strncpy_from_user)
+ mov ip, r1
+1: subs r2, r2, #1
+ ldrusr r3, r1, 1, pl
+ bmi 2f
+ strb r3, [r0], #1
+ teq r3, #0
+ bne 1b
+ sub r1, r1, #1 @ take NUL character out of count
+2: sub r0, r1, ip
+ mov pc, lr
+ENDPROC(__strncpy_from_user)
+
+ .pushsection .fixup,"ax"
+ .align 0
+9001: mov r3, #0
+ strb r3, [r0, #0] @ null terminate
+ mov r0, #-EFAULT
+ mov pc, lr
+ .popsection
+
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
new file mode 100644
index 00000000..0ecbb459
--- /dev/null
+++ b/arch/arm/lib/strnlen_user.S
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/lib/strnlen_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/* Prototype: unsigned long __strnlen_user(const char *str, long n)
+ * Purpose : get length of a string in user memory
+ * Params : str - address of string in user memory
+ * Returns : length of string *including terminator*
+ * or zero on exception, or n + 1 if too long
+ */
+ENTRY(__strnlen_user)
+ mov r2, r0
+1:
+ ldrusr r3, r0, 1
+ teq r3, #0
+ beq 2f
+ subs r1, r1, #1
+ bne 1b
+ add r0, r0, #1
+2: sub r0, r0, r2
+ mov pc, lr
+ENDPROC(__strnlen_user)
+
+ .pushsection .fixup,"ax"
+ .align 0
+9001: mov r0, #0
+ mov pc, lr
+ .popsection
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
new file mode 100644
index 00000000..302f20cd
--- /dev/null
+++ b/arch/arm/lib/strrchr.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/strrchr.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+ENTRY(strrchr)
+ mov r3, #0
+1: ldrb r2, [r0], #1
+ teq r2, r1
+ subeq r3, r0, #1
+ teq r2, #0
+ bne 1b
+ mov r0, r3
+ mov pc, lr
+ENDPROC(strrchr)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
new file mode 100644
index 00000000..15a4d431
--- /dev/null
+++ b/arch/arm/lib/testchangebit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/testchangebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_change_bit)
+ testop eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
new file mode 100644
index 00000000..521b66b5
--- /dev/null
+++ b/arch/arm/lib/testclearbit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/testclearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_clear_bit)
+ testop bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
new file mode 100644
index 00000000..1c98cc21
--- /dev/null
+++ b/arch/arm/lib/testsetbit.S
@@ -0,0 +1,17 @@
+/*
+ * linux/arch/arm/lib/testsetbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include "bitops.h"
+ .text
+
+ENTRY(_test_and_set_bit)
+ testop orreq, streq
+ENDPROC(_test_and_set_bit)
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
new file mode 100644
index 00000000..5c908b1c
--- /dev/null
+++ b/arch/arm/lib/uaccess.S
@@ -0,0 +1,564 @@
+/*
+ * linux/arch/arm/lib/uaccess.S
+ *
+ * Copyright (C) 1995, 1996,1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Routines to block copy data to/from user memory
+ * These are highly optimised both for the 4k page size
+ * and for various alignments.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+#include <asm/domain.h>
+
+ .text
+
+#define PAGE_SHIFT 12
+
+/* Prototype: int __copy_to_user(void *to, const char *from, size_t n)
+ * Purpose : copy a block to user memory from kernel memory
+ * Params : to - user memory
+ * : from - kernel memory
+ * : n - number of bytes to copy
+ * Returns : Number of bytes NOT copied.
+ */
+
+.Lc2u_dest_not_aligned:
+ rsb ip, ip, #4
+ cmp ip, #2
+ ldrb r3, [r1], #1
+USER( TUSER( strb) r3, [r0], #1) @ May fault
+ ldrgeb r3, [r1], #1
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
+ ldrgtb r3, [r1], #1
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
+ sub r2, r2, ip
+ b .Lc2u_dest_aligned
+
+ENTRY(__copy_to_user)
+ stmfd sp!, {r2, r4 - r7, lr}
+ cmp r2, #4
+ blt .Lc2u_not_enough
+ ands ip, r0, #3
+ bne .Lc2u_dest_not_aligned
+.Lc2u_dest_aligned:
+
+ ands ip, r1, #3
+ bne .Lc2u_src_not_aligned
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.Lc2u_0fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lc2u_0nowords
+ ldr r3, [r1], #4
+USER( TUSER( str) r3, [r0], #4) @ May fault
+ mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lc2u_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #32
+ blt .Lc2u_0rem8lp
+
+.Lc2u_0cpy8lp: ldmia r1!, {r3 - r6}
+ stmia r0!, {r3 - r6} @ Shouldnt fault
+ ldmia r1!, {r3 - r6}
+ subs ip, ip, #32
+ stmia r0!, {r3 - r6} @ Shouldnt fault
+ bpl .Lc2u_0cpy8lp
+
+.Lc2u_0rem8lp: cmn ip, #16
+ ldmgeia r1!, {r3 - r6}
+ stmgeia r0!, {r3 - r6} @ Shouldnt fault
+ tst ip, #8
+ ldmneia r1!, {r3 - r4}
+ stmneia r0!, {r3 - r4} @ Shouldnt fault
+ tst ip, #4
+ ldrne r3, [r1], #4
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
+ ands ip, ip, #3
+ beq .Lc2u_0fupi
+.Lc2u_0nowords: teq ip, #0
+ beq .Lc2u_finished
+.Lc2u_nowords: cmp ip, #2
+ ldrb r3, [r1], #1
+USER( TUSER( strb) r3, [r0], #1) @ May fault
+ ldrgeb r3, [r1], #1
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
+ ldrgtb r3, [r1], #1
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
+ b .Lc2u_finished
+
+.Lc2u_not_enough:
+ movs ip, r2
+ bne .Lc2u_nowords
+.Lc2u_finished: mov r0, #0
+ ldmfd sp!, {r2, r4 - r7, pc}
+
+.Lc2u_src_not_aligned:
+ bic r1, r1, #3
+ ldr r7, [r1], #4
+ cmp ip, #2
+ bgt .Lc2u_3fupi
+ beq .Lc2u_2fupi
+.Lc2u_1fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lc2u_1nowords
+ mov r3, r7, pull #8
+ ldr r7, [r1], #4
+ orr r3, r3, r7, push #24
+USER( TUSER( str) r3, [r0], #4) @ May fault
+ mov ip, r0, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lc2u_1fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lc2u_1rem8lp
+
+.Lc2u_1cpy8lp: mov r3, r7, pull #8
+ ldmia r1!, {r4 - r7}
+ subs ip, ip, #16
+ orr r3, r3, r4, push #24
+ mov r4, r4, pull #8
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
+ mov r6, r6, pull #8
+ orr r6, r6, r7, push #24
+ stmia r0!, {r3 - r6} @ Shouldnt fault
+ bpl .Lc2u_1cpy8lp
+
+.Lc2u_1rem8lp: tst ip, #8
+ movne r3, r7, pull #8
+ ldmneia r1!, {r4, r7}
+ orrne r3, r3, r4, push #24
+ movne r4, r4, pull #8
+ orrne r4, r4, r7, push #24
+ stmneia r0!, {r3 - r4} @ Shouldnt fault
+ tst ip, #4
+ movne r3, r7, pull #8
+ ldrne r7, [r1], #4
+ orrne r3, r3, r7, push #24
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
+ ands ip, ip, #3
+ beq .Lc2u_1fupi
+.Lc2u_1nowords: mov r3, r7, get_byte_1
+ teq ip, #0
+ beq .Lc2u_finished
+ cmp ip, #2
+USER( TUSER( strb) r3, [r0], #1) @ May fault
+ movge r3, r7, get_byte_2
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
+ movgt r3, r7, get_byte_3
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
+ b .Lc2u_finished
+
+.Lc2u_2fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lc2u_2nowords
+ mov r3, r7, pull #16
+ ldr r7, [r1], #4
+ orr r3, r3, r7, push #16
+USER( TUSER( str) r3, [r0], #4) @ May fault
+ mov ip, r0, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lc2u_2fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lc2u_2rem8lp
+
+.Lc2u_2cpy8lp: mov r3, r7, pull #16
+ ldmia r1!, {r4 - r7}
+ subs ip, ip, #16
+ orr r3, r3, r4, push #16
+ mov r4, r4, pull #16
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
+ mov r6, r6, pull #16
+ orr r6, r6, r7, push #16
+ stmia r0!, {r3 - r6} @ Shouldnt fault
+ bpl .Lc2u_2cpy8lp
+
+.Lc2u_2rem8lp: tst ip, #8
+ movne r3, r7, pull #16
+ ldmneia r1!, {r4, r7}
+ orrne r3, r3, r4, push #16
+ movne r4, r4, pull #16
+ orrne r4, r4, r7, push #16
+ stmneia r0!, {r3 - r4} @ Shouldnt fault
+ tst ip, #4
+ movne r3, r7, pull #16
+ ldrne r7, [r1], #4
+ orrne r3, r3, r7, push #16
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
+ ands ip, ip, #3
+ beq .Lc2u_2fupi
+.Lc2u_2nowords: mov r3, r7, get_byte_2
+ teq ip, #0
+ beq .Lc2u_finished
+ cmp ip, #2
+USER( TUSER( strb) r3, [r0], #1) @ May fault
+ movge r3, r7, get_byte_3
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
+ ldrgtb r3, [r1], #0
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
+ b .Lc2u_finished
+
+.Lc2u_3fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lc2u_3nowords
+ mov r3, r7, pull #24
+ ldr r7, [r1], #4
+ orr r3, r3, r7, push #8
+USER( TUSER( str) r3, [r0], #4) @ May fault
+ mov ip, r0, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lc2u_3fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lc2u_3rem8lp
+
+.Lc2u_3cpy8lp: mov r3, r7, pull #24
+ ldmia r1!, {r4 - r7}
+ subs ip, ip, #16
+ orr r3, r3, r4, push #8
+ mov r4, r4, pull #24
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
+ mov r6, r6, pull #24
+ orr r6, r6, r7, push #8
+ stmia r0!, {r3 - r6} @ Shouldnt fault
+ bpl .Lc2u_3cpy8lp
+
+.Lc2u_3rem8lp: tst ip, #8
+ movne r3, r7, pull #24
+ ldmneia r1!, {r4, r7}
+ orrne r3, r3, r4, push #8
+ movne r4, r4, pull #24
+ orrne r4, r4, r7, push #8
+ stmneia r0!, {r3 - r4} @ Shouldnt fault
+ tst ip, #4
+ movne r3, r7, pull #24
+ ldrne r7, [r1], #4
+ orrne r3, r3, r7, push #8
+ TUSER( strne) r3, [r0], #4 @ Shouldnt fault
+ ands ip, ip, #3
+ beq .Lc2u_3fupi
+.Lc2u_3nowords: mov r3, r7, get_byte_3
+ teq ip, #0
+ beq .Lc2u_finished
+ cmp ip, #2
+USER( TUSER( strb) r3, [r0], #1) @ May fault
+ ldrgeb r3, [r1], #1
+USER( TUSER( strgeb) r3, [r0], #1) @ May fault
+ ldrgtb r3, [r1], #0
+USER( TUSER( strgtb) r3, [r0], #1) @ May fault
+ b .Lc2u_finished
+ENDPROC(__copy_to_user)
+
+ .pushsection .fixup,"ax"
+ .align 0
+9001: ldmfd sp!, {r0, r4 - r7, pc}
+ .popsection
+
+/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
+ * Purpose : copy a block from user memory to kernel memory
+ * Params : to - kernel memory
+ * : from - user memory
+ * : n - number of bytes to copy
+ * Returns : Number of bytes NOT copied.
+ */
+.Lcfu_dest_not_aligned:
+ rsb ip, ip, #4
+ cmp ip, #2
+USER( TUSER( ldrb) r3, [r1], #1) @ May fault
+ strb r3, [r0], #1
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
+ strgeb r3, [r0], #1
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
+ strgtb r3, [r0], #1
+ sub r2, r2, ip
+ b .Lcfu_dest_aligned
+
+ENTRY(__copy_from_user)
+ stmfd sp!, {r0, r2, r4 - r7, lr}
+ cmp r2, #4
+ blt .Lcfu_not_enough
+ ands ip, r0, #3
+ bne .Lcfu_dest_not_aligned
+.Lcfu_dest_aligned:
+ ands ip, r1, #3
+ bne .Lcfu_src_not_aligned
+
+/*
+ * Seeing as there has to be at least 8 bytes to copy, we can
+ * copy one word, and force a user-mode page fault...
+ */
+
+.Lcfu_0fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lcfu_0nowords
+USER( TUSER( ldr) r3, [r1], #4)
+ str r3, [r0], #4
+ mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lcfu_0fupi
+/*
+ * ip = max no. of bytes to copy before needing another "strt" insn
+ */
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #32
+ blt .Lcfu_0rem8lp
+
+.Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
+ stmia r0!, {r3 - r6}
+ ldmia r1!, {r3 - r6} @ Shouldnt fault
+ subs ip, ip, #32
+ stmia r0!, {r3 - r6}
+ bpl .Lcfu_0cpy8lp
+
+.Lcfu_0rem8lp: cmn ip, #16
+ ldmgeia r1!, {r3 - r6} @ Shouldnt fault
+ stmgeia r0!, {r3 - r6}
+ tst ip, #8
+ ldmneia r1!, {r3 - r4} @ Shouldnt fault
+ stmneia r0!, {r3 - r4}
+ tst ip, #4
+ TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault
+ strne r3, [r0], #4
+ ands ip, ip, #3
+ beq .Lcfu_0fupi
+.Lcfu_0nowords: teq ip, #0
+ beq .Lcfu_finished
+.Lcfu_nowords: cmp ip, #2
+USER( TUSER( ldrb) r3, [r1], #1) @ May fault
+ strb r3, [r0], #1
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
+ strgeb r3, [r0], #1
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
+ strgtb r3, [r0], #1
+ b .Lcfu_finished
+
+.Lcfu_not_enough:
+ movs ip, r2
+ bne .Lcfu_nowords
+.Lcfu_finished: mov r0, #0
+ add sp, sp, #8
+ ldmfd sp!, {r4 - r7, pc}
+
+.Lcfu_src_not_aligned:
+ bic r1, r1, #3
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
+ cmp ip, #2
+ bgt .Lcfu_3fupi
+ beq .Lcfu_2fupi
+.Lcfu_1fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lcfu_1nowords
+ mov r3, r7, pull #8
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
+ orr r3, r3, r7, push #24
+ str r3, [r0], #4
+ mov ip, r1, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lcfu_1fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lcfu_1rem8lp
+
+.Lcfu_1cpy8lp: mov r3, r7, pull #8
+ ldmia r1!, {r4 - r7} @ Shouldnt fault
+ subs ip, ip, #16
+ orr r3, r3, r4, push #24
+ mov r4, r4, pull #8
+ orr r4, r4, r5, push #24
+ mov r5, r5, pull #8
+ orr r5, r5, r6, push #24
+ mov r6, r6, pull #8
+ orr r6, r6, r7, push #24
+ stmia r0!, {r3 - r6}
+ bpl .Lcfu_1cpy8lp
+
+.Lcfu_1rem8lp: tst ip, #8
+ movne r3, r7, pull #8
+ ldmneia r1!, {r4, r7} @ Shouldnt fault
+ orrne r3, r3, r4, push #24
+ movne r4, r4, pull #8
+ orrne r4, r4, r7, push #24
+ stmneia r0!, {r3 - r4}
+ tst ip, #4
+ movne r3, r7, pull #8
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
+ orrne r3, r3, r7, push #24
+ strne r3, [r0], #4
+ ands ip, ip, #3
+ beq .Lcfu_1fupi
+.Lcfu_1nowords: mov r3, r7, get_byte_1
+ teq ip, #0
+ beq .Lcfu_finished
+ cmp ip, #2
+ strb r3, [r0], #1
+ movge r3, r7, get_byte_2
+ strgeb r3, [r0], #1
+ movgt r3, r7, get_byte_3
+ strgtb r3, [r0], #1
+ b .Lcfu_finished
+
+.Lcfu_2fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lcfu_2nowords
+ mov r3, r7, pull #16
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
+ orr r3, r3, r7, push #16
+ str r3, [r0], #4
+ mov ip, r1, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lcfu_2fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lcfu_2rem8lp
+
+
+.Lcfu_2cpy8lp: mov r3, r7, pull #16
+ ldmia r1!, {r4 - r7} @ Shouldnt fault
+ subs ip, ip, #16
+ orr r3, r3, r4, push #16
+ mov r4, r4, pull #16
+ orr r4, r4, r5, push #16
+ mov r5, r5, pull #16
+ orr r5, r5, r6, push #16
+ mov r6, r6, pull #16
+ orr r6, r6, r7, push #16
+ stmia r0!, {r3 - r6}
+ bpl .Lcfu_2cpy8lp
+
+.Lcfu_2rem8lp: tst ip, #8
+ movne r3, r7, pull #16
+ ldmneia r1!, {r4, r7} @ Shouldnt fault
+ orrne r3, r3, r4, push #16
+ movne r4, r4, pull #16
+ orrne r4, r4, r7, push #16
+ stmneia r0!, {r3 - r4}
+ tst ip, #4
+ movne r3, r7, pull #16
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
+ orrne r3, r3, r7, push #16
+ strne r3, [r0], #4
+ ands ip, ip, #3
+ beq .Lcfu_2fupi
+.Lcfu_2nowords: mov r3, r7, get_byte_2
+ teq ip, #0
+ beq .Lcfu_finished
+ cmp ip, #2
+ strb r3, [r0], #1
+ movge r3, r7, get_byte_3
+ strgeb r3, [r0], #1
+USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault
+ strgtb r3, [r0], #1
+ b .Lcfu_finished
+
+.Lcfu_3fupi: subs r2, r2, #4
+ addmi ip, r2, #4
+ bmi .Lcfu_3nowords
+ mov r3, r7, pull #24
+USER( TUSER( ldr) r7, [r1], #4) @ May fault
+ orr r3, r3, r7, push #8
+ str r3, [r0], #4
+ mov ip, r1, lsl #32 - PAGE_SHIFT
+ rsb ip, ip, #0
+ movs ip, ip, lsr #32 - PAGE_SHIFT
+ beq .Lcfu_3fupi
+ cmp r2, ip
+ movlt ip, r2
+ sub r2, r2, ip
+ subs ip, ip, #16
+ blt .Lcfu_3rem8lp
+
+.Lcfu_3cpy8lp: mov r3, r7, pull #24
+ ldmia r1!, {r4 - r7} @ Shouldnt fault
+ orr r3, r3, r4, push #8
+ mov r4, r4, pull #24
+ orr r4, r4, r5, push #8
+ mov r5, r5, pull #24
+ orr r5, r5, r6, push #8
+ mov r6, r6, pull #24
+ orr r6, r6, r7, push #8
+ stmia r0!, {r3 - r6}
+ subs ip, ip, #16
+ bpl .Lcfu_3cpy8lp
+
+.Lcfu_3rem8lp: tst ip, #8
+ movne r3, r7, pull #24
+ ldmneia r1!, {r4, r7} @ Shouldnt fault
+ orrne r3, r3, r4, push #8
+ movne r4, r4, pull #24
+ orrne r4, r4, r7, push #8
+ stmneia r0!, {r3 - r4}
+ tst ip, #4
+ movne r3, r7, pull #24
+USER( TUSER( ldrne) r7, [r1], #4) @ May fault
+ orrne r3, r3, r7, push #8
+ strne r3, [r0], #4
+ ands ip, ip, #3
+ beq .Lcfu_3fupi
+.Lcfu_3nowords: mov r3, r7, get_byte_3
+ teq ip, #0
+ beq .Lcfu_finished
+ cmp ip, #2
+ strb r3, [r0], #1
+USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
+ strgeb r3, [r0], #1
+USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
+ strgtb r3, [r0], #1
+ b .Lcfu_finished
+ENDPROC(__copy_from_user)
+
+ .pushsection .fixup,"ax"
+ .align 0
+ /*
+ * We took an exception. r0 contains a pointer to
+ * the byte not copied.
+ */
+9001: ldr r2, [sp], #4 @ void *to
+ sub r2, r0, r2 @ bytes copied
+ ldr r1, [sp], #4 @ unsigned long count
+ subs r4, r1, r2 @ bytes left to copy
+ movne r1, r4
+ blne __memzero
+ mov r0, r4
+ ldmfd sp!, {r4 - r7, pc}
+ .popsection
+
diff --git a/arch/arm/lib/uaccess_with_memcpy.c b/arch/arm/lib/uaccess_with_memcpy.c
new file mode 100644
index 00000000..8b9b1364
--- /dev/null
+++ b/arch/arm/lib/uaccess_with_memcpy.c
@@ -0,0 +1,234 @@
+/*
+ * linux/arch/arm/lib/uaccess_with_memcpy.c
+ *
+ * Written by: Lennert Buytenhek and Nicolas Pitre
+ * Copyright (C) 2009 Marvell Semiconductor
+ *
+ * This program is free software; you can 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/ctype.h>
+#include <linux/uaccess.h>
+#include <linux/rwsem.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h> /* for in_atomic() */
+#include <linux/gfp.h>
+#include <asm/current.h>
+#include <asm/page.h>
+
+static int
+pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
+{
+ unsigned long addr = (unsigned long)_addr;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ pud_t *pud;
+ spinlock_t *ptl;
+
+ pgd = pgd_offset(current->mm, addr);
+ if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
+ return 0;
+
+ pud = pud_offset(pgd, addr);
+ if (unlikely(pud_none(*pud) || pud_bad(*pud)))
+ return 0;
+
+ pmd = pmd_offset(pud, addr);
+ if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
+ return 0;
+
+ pte = pte_offset_map_lock(current->mm, pmd, addr, &ptl);
+ if (unlikely(!pte_present(*pte) || !pte_young(*pte) ||
+ !pte_write(*pte) || !pte_dirty(*pte))) {
+ pte_unmap_unlock(pte, ptl);
+ return 0;
+ }
+
+ *ptep = pte;
+ *ptlp = ptl;
+
+ return 1;
+}
+
+static unsigned long noinline
+__copy_to_user_memcpy(void __user *to, const void *from, unsigned long n)
+{
+ int atomic;
+
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+ memcpy((void *)to, from, n);
+ return 0;
+ }
+
+ /* the mmap semaphore is taken only if not in an atomic context */
+ atomic = in_atomic();
+
+ if (!atomic)
+ down_read(&current->mm->mmap_sem);
+ while (n) {
+ pte_t *pte;
+ spinlock_t *ptl;
+ int tocopy;
+
+ while (!pin_page_for_write(to, &pte, &ptl)) {
+ if (!atomic)
+ up_read(&current->mm->mmap_sem);
+ if (__put_user(0, (char __user *)to))
+ goto out;
+ if (!atomic)
+ down_read(&current->mm->mmap_sem);
+ }
+
+ tocopy = (~(unsigned long)to & ~PAGE_MASK) + 1;
+ if (tocopy > n)
+ tocopy = n;
+
+ memcpy((void *)to, from, tocopy);
+ to += tocopy;
+ from += tocopy;
+ n -= tocopy;
+
+ pte_unmap_unlock(pte, ptl);
+ }
+ if (!atomic)
+ up_read(&current->mm->mmap_sem);
+
+out:
+ return n;
+}
+
+unsigned long
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ /*
+ * This test is stubbed out of the main function above to keep
+ * the overhead for small copies low by avoiding a large
+ * register dump on the stack just to reload them right away.
+ * With frame pointer disabled, tail call optimization kicks in
+ * as well making this test almost invisible.
+ */
+ if (n < 64)
+ return __copy_to_user_std(to, from, n);
+ return __copy_to_user_memcpy(to, from, n);
+}
+
+static unsigned long noinline
+__clear_user_memset(void __user *addr, unsigned long n)
+{
+ if (unlikely(segment_eq(get_fs(), KERNEL_DS))) {
+ memset((void *)addr, 0, n);
+ return 0;
+ }
+
+ down_read(&current->mm->mmap_sem);
+ while (n) {
+ pte_t *pte;
+ spinlock_t *ptl;
+ int tocopy;
+
+ while (!pin_page_for_write(addr, &pte, &ptl)) {
+ up_read(&current->mm->mmap_sem);
+ if (__put_user(0, (char __user *)addr))
+ goto out;
+ down_read(&current->mm->mmap_sem);
+ }
+
+ tocopy = (~(unsigned long)addr & ~PAGE_MASK) + 1;
+ if (tocopy > n)
+ tocopy = n;
+
+ memset((void *)addr, 0, tocopy);
+ addr += tocopy;
+ n -= tocopy;
+
+ pte_unmap_unlock(pte, ptl);
+ }
+ up_read(&current->mm->mmap_sem);
+
+out:
+ return n;
+}
+
+unsigned long __clear_user(void __user *addr, unsigned long n)
+{
+ /* See rational for this in __copy_to_user() above. */
+ if (n < 64)
+ return __clear_user_std(addr, n);
+ return __clear_user_memset(addr, n);
+}
+
+#if 0
+
+/*
+ * This code is disabled by default, but kept around in case the chosen
+ * thresholds need to be revalidated. Some overhead (small but still)
+ * would be implied by a runtime determined variable threshold, and
+ * so far the measurement on concerned targets didn't show a worthwhile
+ * variation.
+ *
+ * Note that a fairly precise sched_clock() implementation is needed
+ * for results to make some sense.
+ */
+
+#include <linux/vmalloc.h>
+
+static int __init test_size_treshold(void)
+{
+ struct page *src_page, *dst_page;
+ void *user_ptr, *kernel_ptr;
+ unsigned long long t0, t1, t2;
+ int size, ret;
+
+ ret = -ENOMEM;
+ src_page = alloc_page(GFP_KERNEL);
+ if (!src_page)
+ goto no_src;
+ dst_page = alloc_page(GFP_KERNEL);
+ if (!dst_page)
+ goto no_dst;
+ kernel_ptr = page_address(src_page);
+ user_ptr = vmap(&dst_page, 1, VM_IOREMAP, __pgprot(__P010));
+ if (!user_ptr)
+ goto no_vmap;
+
+ /* warm up the src page dcache */
+ ret = __copy_to_user_memcpy(user_ptr, kernel_ptr, PAGE_SIZE);
+
+ for (size = PAGE_SIZE; size >= 4; size /= 2) {
+ t0 = sched_clock();
+ ret |= __copy_to_user_memcpy(user_ptr, kernel_ptr, size);
+ t1 = sched_clock();
+ ret |= __copy_to_user_std(user_ptr, kernel_ptr, size);
+ t2 = sched_clock();
+ printk("copy_to_user: %d %llu %llu\n", size, t1 - t0, t2 - t1);
+ }
+
+ for (size = PAGE_SIZE; size >= 4; size /= 2) {
+ t0 = sched_clock();
+ ret |= __clear_user_memset(user_ptr, size);
+ t1 = sched_clock();
+ ret |= __clear_user_std(user_ptr, size);
+ t2 = sched_clock();
+ printk("clear_user: %d %llu %llu\n", size, t1 - t0, t2 - t1);
+ }
+
+ if (ret)
+ ret = -EFAULT;
+
+ vunmap(user_ptr);
+no_vmap:
+ put_page(dst_page);
+no_dst:
+ put_page(src_page);
+no_src:
+ return ret;
+}
+
+subsys_initcall(test_size_treshold);
+
+#endif
diff --git a/arch/arm/lib/ucmpdi2.S b/arch/arm/lib/ucmpdi2.S
new file mode 100644
index 00000000..f0df6a91
--- /dev/null
+++ b/arch/arm/lib/ucmpdi2.S
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/lib/ucmpdi2.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Oct 19, 2005
+ * Copyright: Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#else
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#endif
+
+ENTRY(__ucmpdi2)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #0
+ moveq r0, #1
+ movhi r0, #2
+ mov pc, lr
+
+ENDPROC(__ucmpdi2)
+
+#ifdef CONFIG_AEABI
+
+ENTRY(__aeabi_ulcmp)
+
+ cmp xh, yh
+ cmpeq xl, yl
+ movlo r0, #-1
+ moveq r0, #0
+ movhi r0, #1
+ mov pc, lr
+
+ENDPROC(__aeabi_ulcmp)
+
+#endif
+
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
new file mode 100644
index 00000000..22484670
--- /dev/null
+++ b/arch/arm/mach-at91/Kconfig
@@ -0,0 +1,524 @@
+if ARCH_AT91
+
+config HAVE_AT91_DATAFLASH_CARD
+ bool
+
+config HAVE_AT91_USART3
+ bool
+
+config HAVE_AT91_USART4
+ bool
+
+config HAVE_AT91_USART5
+ bool
+
+menu "Atmel AT91 System-on-Chip"
+
+choice
+ prompt "Atmel AT91 Processor"
+
+config ARCH_AT91RM9200
+ bool "AT91RM9200"
+ select CPU_ARM920T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_AT91_USART3
+
+config ARCH_AT91SAM9260
+ bool "AT91SAM9260 or AT91SAM9XE"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_AT91_USART3
+ select HAVE_AT91_USART4
+ select HAVE_AT91_USART5
+ select HAVE_NET_MACB
+
+config ARCH_AT91SAM9261
+ bool "AT91SAM9261"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_FB_ATMEL
+
+config ARCH_AT91SAM9G10
+ bool "AT91SAM9G10"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_FB_ATMEL
+
+config ARCH_AT91SAM9263
+ bool "AT91SAM9263"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
+
+config ARCH_AT91SAM9RL
+ bool "AT91SAM9RL"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_AT91_USART3
+ select HAVE_FB_ATMEL
+
+config ARCH_AT91SAM9G20
+ bool "AT91SAM9G20"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_AT91_USART3
+ select HAVE_AT91_USART4
+ select HAVE_AT91_USART5
+ select HAVE_NET_MACB
+
+config ARCH_AT91SAM9G45
+ bool "AT91SAM9G45"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_AT91_USART3
+ select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
+
+config ARCH_AT91CAP9
+ bool "AT91CAP9"
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
+ select HAVE_FB_ATMEL
+ select HAVE_NET_MACB
+
+config ARCH_AT91X40
+ bool "AT91x40"
+ select ARCH_USES_GETTIMEOFFSET
+
+endchoice
+
+config AT91_PMC_UNIT
+ bool
+ default !ARCH_AT91X40
+
+# ----------------------------------------------------------
+
+if ARCH_AT91RM9200
+
+comment "AT91RM9200 Board Type"
+
+config MACH_ONEARM
+ bool "Ajeco 1ARM Single Board Computer"
+ help
+ Select this if you are using Ajeco's 1ARM Single Board Computer.
+ <http://www.ajeco.fi/>
+
+config ARCH_AT91RM9200DK
+ bool "Atmel AT91RM9200-DK Development board"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91RM9200-DK Development board.
+ (Discontinued)
+
+config MACH_AT91RM9200EK
+ bool "Atmel AT91RM9200-EK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91RM9200-EK Evaluation Kit.
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3507>
+
+config MACH_CSB337
+ bool "Cogent CSB337"
+ help
+ Select this if you are using Cogent's CSB337 board.
+ <http://www.cogcomp.com/csb_csb337.htm>
+
+config MACH_CSB637
+ bool "Cogent CSB637"
+ help
+ Select this if you are using Cogent's CSB637 board.
+ <http://www.cogcomp.com/csb_csb637.htm>
+
+config MACH_CARMEVA
+ bool "Conitec ARM&EVA"
+ help
+ Select this if you are using Conitec's AT91RM9200-MCU-Module.
+ <http://www.conitec.net/english/linuxboard.php>
+
+config MACH_ATEB9200
+ bool "Embest ATEB9200"
+ help
+ Select this if you are using Embest's ATEB9200 board.
+ <http://www.embedinfo.com/english/product/ATEB9200.asp>
+
+config MACH_KB9200
+ bool "KwikByte KB920x"
+ help
+ Select this if you are using KwikByte's KB920x board.
+ <http://www.kwikbyte.com/KB9202.html>
+
+config MACH_PICOTUX2XX
+ bool "picotux 200"
+ help
+ Select this if you are using a picotux 200.
+ <http://www.picotux.com/>
+
+config MACH_KAFA
+ bool "Sperry-Sun KAFA board"
+ help
+ Select this if you are using Sperry-Sun's KAFA board.
+
+config MACH_ECBAT91
+ bool "emQbit ECB_AT91 SBC"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using emQbit's ECB_AT91 board.
+ <http://wiki.emqbit.com/free-ecb-at91>
+
+config MACH_YL9200
+ bool "ucDragon YL-9200"
+ help
+ Select this if you are using the ucDragon YL-9200 board.
+
+config MACH_CPUAT91
+ bool "Eukrea CPUAT91"
+ help
+ Select this if you are using the Eukrea Electromatique's
+ CPUAT91 board <http://www.eukrea.com/>.
+
+config MACH_ECO920
+ bool "eco920"
+ help
+ Select this if you are using the eco920 board
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9260
+
+comment "AT91SAM9260 Variants"
+
+config ARCH_AT91SAM9260_SAM9XE
+ bool "AT91SAM9XE"
+ help
+ Select this if you are using Atmel's AT91SAM9XE System-on-Chip.
+ They are basically AT91SAM9260s with various sizes of embedded Flash.
+
+comment "AT91SAM9260 / AT91SAM9XE Board Type"
+
+config MACH_AT91SAM9260EK
+ bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
+
+config MACH_CAM60
+ bool "KwikByte KB9260 (CAM60) board"
+ help
+ Select this if you are using KwikByte's KB9260 (CAM60) board based on the Atmel AT91SAM9260.
+ <http://www.kwikbyte.com/KB9260.html>
+
+config MACH_SAM9_L9260
+ bool "Olimex SAM9-L9260 board"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Olimex's SAM9-L9260 board based on the Atmel AT91SAM9260.
+ <http://www.olimex.com/dev/sam9-L9260.html>
+
+config MACH_AFEB9260
+ bool "Custom afeb9260 board v1"
+ help
+ Select this if you are using custom afeb9260 board based on
+ open hardware design. Select this for revision 1 of the board.
+ <svn://194.85.238.22/home/users/george/svn/arm9eb>
+ <http://groups.google.com/group/arm9fpga-evolution-board>
+
+config MACH_USB_A9260
+ bool "CALAO USB-A9260"
+ help
+ Select this if you are using a Calao Systems USB-A9260.
+ <http://www.calao-systems.com>
+
+config MACH_QIL_A9260
+ bool "CALAO QIL-A9260 board"
+ help
+ Select this if you are using a Calao Systems QIL-A9260 Board.
+ <http://www.calao-systems.com>
+
+config MACH_CPU9260
+ bool "Eukrea CPU9260 board"
+ help
+ Select this if you are using a Eukrea Electromatique's
+ CPU9260 Board <http://www.eukrea.com/>
+
+config MACH_FLEXIBITY
+ bool "Flexibity Connect board"
+ help
+ Select this if you are using Flexibity Connect board
+ <http://www.flexibity.com>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9261
+
+comment "AT91SAM9261 Board Type"
+
+config MACH_AT91SAM9261EK
+ bool "Atmel AT91SAM9261-EK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit.
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9G10
+
+comment "AT91SAM9G10 Board Type"
+
+config MACH_AT91SAM9G10EK
+ bool "Atmel AT91SAM9G10-EK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9263
+
+comment "AT91SAM9263 Board Type"
+
+config MACH_AT91SAM9263EK
+ bool "Atmel AT91SAM9263-EK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
+
+config MACH_USB_A9263
+ bool "CALAO USB-A9263"
+ help
+ Select this if you are using a Calao Systems USB-A9263.
+ <http://www.calao-systems.com>
+
+config MACH_NEOCORE926
+ bool "Adeneo NEOCORE926"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using the Adeneo Neocore 926 board.
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9RL
+
+comment "AT91SAM9RL Board Type"
+
+config MACH_AT91SAM9RLEK
+ bool "Atmel AT91SAM9RL-EK Evaluation Kit"
+ help
+ Select this if you are using Atmel's AT91SAM9RL-EK Evaluation Kit.
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9G20
+
+comment "AT91SAM9G20 Board Type"
+
+config MACH_AT91SAM9G20EK
+ bool "Atmel AT91SAM9G20-EK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
+ that embeds only one SD/MMC slot.
+
+config MACH_AT91SAM9G20EK_2MMC
+ depends on MACH_AT91SAM9G20EK
+ bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
+ help
+ Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
+ with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
+ onwards.
+
+config MACH_CPU9G20
+ bool "Eukrea CPU9G20 board"
+ help
+ Select this if you are using a Eukrea Electromatique's
+ CPU9G20 Board <http://www.eukrea.com/>
+
+config MACH_ACMENETUSFOXG20
+ bool "Acme Systems srl FOX Board G20"
+ help
+ Select this if you are using Acme Systems
+ FOX Board G20 <http://www.acmesystems.it>
+
+config MACH_PORTUXG20
+ bool "taskit PortuxG20"
+ help
+ Select this if you are using taskit's PortuxG20.
+ <http://www.taskit.de/en/>
+
+config MACH_STAMP9G20
+ bool "taskit Stamp9G20 CPU module"
+ help
+ Select this if you are using taskit's Stamp9G20 CPU module on its
+ evaluation board.
+ <http://www.taskit.de/en/>
+
+config MACH_PCONTROL_G20
+ bool "PControl G20 CPU module"
+ help
+ Select this if you are using taskit's Stamp9G20 CPU module on this
+ carrier board, beeing the decentralized unit of a building automation
+ system; featuring nvram, eth-switch, iso-rs485, display, io
+
+config MACH_GSIA18S
+ bool "GS_IA18_S board"
+ help
+ This enables support for the GS_IA18_S board
+ produced by GeoSIG Ltd company. This is an internet accelerograph.
+ <http://www.geosig.com>
+endif
+
+if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
+comment "AT91SAM9260/AT91SAM9G20 boards"
+
+config MACH_SNAPPER_9260
+ bool "Bluewater Systems Snapper 9260/9G20 module"
+ help
+ Select this if you are using the Bluewater Systems Snapper 9260 or
+ Snapper 9G20 modules.
+ <http://www.bluewatersys.com/>
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91SAM9G45
+
+comment "AT91SAM9G45 Board Type"
+
+config MACH_AT91SAM9M10G45EK
+ bool "Atmel AT91SAM9M10G45-EK Evaluation Kits"
+ help
+ Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
+ "ES" at the end of the name means that this board is an
+ Engineering Sample.
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91CAP9
+
+comment "AT91CAP9 Board Type"
+
+config MACH_AT91CAP9ADK
+ bool "Atmel AT91CAP9A-DK Evaluation Kit"
+ select HAVE_AT91_DATAFLASH_CARD
+ help
+ Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
+ <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
+
+endif
+
+# ----------------------------------------------------------
+
+if ARCH_AT91X40
+
+comment "AT91X40 Board Type"
+
+config MACH_AT91EB01
+ bool "Atmel AT91EB01 Evaluation Kit"
+ help
+ Select this if you are using Atmel's AT91EB01 Evaluation Kit.
+ It is also a popular target for simulators such as GDB's
+ ARM simulator (commonly known as the ARMulator) and the
+ Skyeye simulator.
+
+endif
+
+# ----------------------------------------------------------
+
+comment "AT91 Board Options"
+
+config MTD_AT91_DATAFLASH_CARD
+ bool "Enable DataFlash Card support"
+ depends on HAVE_AT91_DATAFLASH_CARD
+ help
+ Enable support for the DataFlash card.
+
+# ----------------------------------------------------------
+
+comment "AT91 Feature Selections"
+
+config AT91_PROGRAMMABLE_CLOCKS
+ bool "Programmable Clocks"
+ help
+ Select this if you need to program one or more of the PCK0..PCK3
+ programmable clock outputs.
+
+config AT91_SLOW_CLOCK
+ bool "Suspend-to-RAM disables main oscillator"
+ depends on SUSPEND
+ help
+ Select this if you want Suspend-to-RAM to save the most power
+ possible (without powering off the CPU) by disabling the PLLs
+ and main oscillator so that only the 32 KiHz clock is available.
+
+ When only that slow-clock is available, some peripherals lose
+ functionality. Many can't issue wakeup events unless faster
+ clocks are available. Some lose their operating state and
+ need to be completely re-initialized.
+
+config AT91_TIMER_HZ
+ int "Kernel HZ (jiffies per second)"
+ range 32 1024
+ depends on ARCH_AT91
+ default "128" if ARCH_AT91RM9200
+ default "100"
+ help
+ On AT91rm9200 chips where you're using a system clock derived
+ from the 32768 Hz hardware clock, this tick rate should divide
+ it exactly: use a power-of-two value, such as 128 or 256, to
+ reduce timing errors caused by rounding.
+
+ On AT91sam926x chips, or otherwise when using a higher precision
+ system clock (of at least several MHz), rounding is less of a
+ problem so it can be safer to use a decimal values like 100.
+
+choice
+ prompt "Select a UART for early kernel messages"
+
+config AT91_EARLY_DBGU
+ bool "DBGU"
+
+config AT91_EARLY_USART0
+ bool "USART0"
+
+config AT91_EARLY_USART1
+ bool "USART1"
+
+config AT91_EARLY_USART2
+ bool "USART2"
+ depends on ! ARCH_AT91X40
+
+config AT91_EARLY_USART3
+ bool "USART3"
+ depends on HAVE_AT91_USART3
+
+config AT91_EARLY_USART4
+ bool "USART4"
+ depends on HAVE_AT91_USART4
+
+config AT91_EARLY_USART5
+ bool "USART5"
+ depends on HAVE_AT91_USART5
+
+endchoice
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
new file mode 100644
index 00000000..96966231
--- /dev/null
+++ b/arch/arm/mach-at91/Makefile
@@ -0,0 +1,93 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o gpio.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
+
+# CPU-specific support
+obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
+obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o
+obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
+
+# AT91RM9200 board-specific support
+obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
+obj-$(CONFIG_ARCH_AT91RM9200DK) += board-rm9200dk.o
+obj-$(CONFIG_MACH_AT91RM9200EK) += board-rm9200ek.o
+obj-$(CONFIG_MACH_CSB337) += board-csb337.o
+obj-$(CONFIG_MACH_CSB637) += board-csb637.o
+obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o
+obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
+obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
+obj-$(CONFIG_MACH_KAFA) += board-kafa.o
+obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
+obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o
+obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o
+obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o
+obj-$(CONFIG_MACH_ECO920) += board-eco920.o
+
+# AT91SAM9260 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
+obj-$(CONFIG_MACH_CAM60) += board-cam60.o
+obj-$(CONFIG_MACH_SAM9_L9260) += board-sam9-l9260.o
+obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o
+obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o
+obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o
+obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o
+obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o
+
+# AT91SAM9261 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
+obj-$(CONFIG_MACH_AT91SAM9G10EK) += board-sam9261ek.o
+
+# AT91SAM9263 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
+obj-$(CONFIG_MACH_USB_A9263) += board-usb-a9263.o
+obj-$(CONFIG_MACH_NEOCORE926) += board-neocore926.o
+
+# AT91SAM9RL board-specific support
+obj-$(CONFIG_MACH_AT91SAM9RLEK) += board-sam9rlek.o
+
+# AT91SAM9G20 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o
+obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
+obj-$(CONFIG_MACH_ACMENETUSFOXG20) += board-foxg20.o
+obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
+obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
+obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o
+obj-$(CONFIG_MACH_GSIA18S) += board-gsia18s.o board-stamp9g20.o
+
+# AT91SAM9260/AT91SAM9G20 board-specific support
+obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
+
+# AT91SAM9G45 board-specific support
+obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
+
+# AT91CAP9 board-specific support
+obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
+
+# AT91X40 board-specific support
+obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
+
+# Drivers
+obj-y += leds.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+
+ifeq ($(CONFIG_PM_DEBUG),y)
+CFLAGS_pm.o += -DDEBUG
+endif
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
new file mode 100644
index 00000000..3462b815
--- /dev/null
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -0,0 +1,18 @@
+# Note: the following conditions must always be true:
+# ZRELADDR == virt_to_phys(TEXTADDR)
+# PARAMS_PHYS must be within 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+
+ifeq ($(CONFIG_ARCH_AT91CAP9),y)
+ zreladdr-y := 0x70008000
+params_phys-y := 0x70000100
+initrd_phys-y := 0x70410000
+else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
+ zreladdr-y := 0x70008000
+params_phys-y := 0x70000100
+initrd_phys-y := 0x70410000
+else
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
+initrd_phys-y := 0x20410000
+endif
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
new file mode 100644
index 00000000..f1013d08
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -0,0 +1,422 @@
+/*
+ * arch/arm/mach-at91/at91cap9.c
+ *
+ * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/cpu.h>
+#include <mach/at91cap9.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91cap9_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91CAP9_SRAM_SIZE,
+ .pfn = __phys_to_pfn(AT91CAP9_SRAM_BASE),
+ .length = AT91CAP9_SRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioABCD_clk = {
+ .name = "pioABCD_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_PIOABCD,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb0_clk = {
+ .name = "mpb0_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MPB0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb1_clk = {
+ .name = "mpb1_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MPB1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb2_clk = {
+ .name = "mpb2_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MPB2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb3_clk = {
+ .name = "mpb3_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MPB3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mpb4_clk = {
+ .name = "mpb4_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MPB4,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+ .name = "mci0_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MCI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+ .name = "mci1_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_MCI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk can_clk = {
+ .name = "can_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_CAN,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+ .name = "twi_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_TWI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+ .name = "spi0_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_SPI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+ .name = "spi1_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_SPI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+ .name = "ac97_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_AC97C,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb_clk = {
+ .name = "tcb_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_TCB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+ .name = "pwm_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_PWMC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+ .name = "macb_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_EMAC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk aestdes_clk = {
+ .name = "aestdes_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_AESTDES,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk adc_clk = {
+ .name = "adc_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_ADC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+ .name = "isi_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_ISI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+ .name = "lcdc_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_LCDC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_DMA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+ .name = "udphs_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_UDPHS,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+ .name = "ohci_clk",
+ .pmc_mask = 1 << AT91CAP9_ID_UHP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioABCD_clk,
+ &mpb0_clk,
+ &mpb1_clk,
+ &mpb2_clk,
+ &mpb3_clk,
+ &mpb4_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &mmc0_clk,
+ &mmc1_clk,
+ &can_clk,
+ &twi_clk,
+ &spi0_clk,
+ &spi1_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &ac97_clk,
+ &tcb_clk,
+ &pwm_clk,
+ &macb_clk,
+ &aestdes_clk,
+ &adc_clk,
+ &isi_clk,
+ &lcdc_clk,
+ &dma_clk,
+ &udphs_clk,
+ &ohci_clk,
+ // irq0 .. irq1
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+ CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+static struct clk pck2 = {
+ .name = "pck2",
+ .pmc_mask = AT91_PMC_PCK2,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 2,
+};
+static struct clk pck3 = {
+ .name = "pck3",
+ .pmc_mask = AT91_PMC_PCK3,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 3,
+};
+
+static void __init at91cap9_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+ clk_register(&pck2);
+ clk_register(&pck3);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91cap9_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91cap9_gpio[] = {
+ {
+ .id = AT91CAP9_ID_PIOABCD,
+ .offset = AT91_PIOA,
+ .clock = &pioABCD_clk,
+ }, {
+ .id = AT91CAP9_ID_PIOABCD,
+ .offset = AT91_PIOB,
+ .clock = &pioABCD_clk,
+ }, {
+ .id = AT91CAP9_ID_PIOABCD,
+ .offset = AT91_PIOC,
+ .clock = &pioABCD_clk,
+ }, {
+ .id = AT91CAP9_ID_PIOABCD,
+ .offset = AT91_PIOD,
+ .clock = &pioABCD_clk,
+ }
+};
+
+static void at91cap9_reset(void)
+{
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+static void at91cap9_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91CAP9 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91cap9_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc));
+}
+
+void __init at91cap9_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91cap9_reset;
+ pm_power_off = at91cap9_poweroff;
+ at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91cap9_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91cap9_gpio, 4);
+
+ /* Remember the silicon revision */
+ if (cpu_is_at91cap9_revB())
+ system_rev = 0xB;
+ else if (cpu_is_at91cap9_revC())
+ system_rev = 0xC;
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A, B, C and D */
+ 0, /* MP Block Peripheral 0 */
+ 0, /* MP Block Peripheral 1 */
+ 0, /* MP Block Peripheral 2 */
+ 0, /* MP Block Peripheral 3 */
+ 0, /* MP Block Peripheral 4 */
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 0, /* Multimedia Card Interface 0 */
+ 0, /* Multimedia Card Interface 1 */
+ 3, /* CAN */
+ 6, /* Two-Wire Interface */
+ 5, /* Serial Peripheral Interface 0 */
+ 5, /* Serial Peripheral Interface 1 */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 5, /* AC97 Controller */
+ 0, /* Timer Counter 0, 1 and 2 */
+ 0, /* Pulse Width Modulation Controller */
+ 3, /* Ethernet */
+ 0, /* Advanced Encryption Standard, Triple DES*/
+ 0, /* Analog-to-Digital Converter */
+ 0, /* Image Sensor Interface */
+ 3, /* LCD Controller */
+ 0, /* DMA Controller */
+ 2, /* USB Device Port */
+ 2, /* USB Host port */
+ 0, /* Advanced Interrupt Controller (IRQ0) */
+ 0, /* Advanced Interrupt Controller (IRQ1) */
+};
+
+void __init at91cap9_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91cap9_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
new file mode 100644
index 00000000..dba0d8d8
--- /dev/null
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -0,0 +1,1259 @@
+/*
+ * arch/arm/mach-at91/at91cap9_devices.c
+ *
+ * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/cpu.h>
+#include <mach/gpio.h>
+#include <mach/at91cap9.h>
+#include <mach/at91cap9_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+ [0] = {
+ .start = AT91CAP9_UHP_BASE,
+ .end = AT91CAP9_UHP_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_UHP,
+ .end = AT91CAP9_ID_UHP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_usbh_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_data,
+ },
+ .resource = usbh_resources,
+ .num_resources = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ if (cpu_is_at91cap9_revB())
+ irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ usbh_data = *data;
+ platform_device_register(&at91_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+ [0] = {
+ .start = AT91CAP9_UDPHS_FIFO,
+ .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_BASE_UDPHS,
+ .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91CAP9_ID_UDPHS,
+ .end = AT91CAP9_ID_UDPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
+ [idx] = { \
+ .name = nam, \
+ .index = idx, \
+ .fifo_size = maxpkt, \
+ .nr_banks = maxbk, \
+ .can_dma = dma, \
+ .can_isoc = isoc, \
+ }
+
+static struct usba_ep_data usba_udc_ep[] = {
+ EP("ep0", 0, 64, 1, 0, 0),
+ EP("ep1", 1, 1024, 3, 1, 1),
+ EP("ep2", 2, 1024, 3, 1, 1),
+ EP("ep3", 3, 1024, 2, 1, 1),
+ EP("ep4", 4, 1024, 2, 1, 1),
+ EP("ep5", 5, 1024, 2, 1, 0),
+ EP("ep6", 6, 1024, 2, 1, 0),
+ EP("ep7", 7, 1024, 2, 0, 0),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+ struct usba_platform_data pdata;
+ struct usba_ep_data ep[8];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+ .name = "atmel_usba_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &usba_udc_data.pdata,
+ },
+ .resource = usba_udc_resources,
+ .num_resources = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+ if (cpu_is_at91cap9_revB()) {
+ irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
+ at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
+ AT91_MATRIX_UDPHS_BYPASS_LOCK);
+ }
+ else
+ at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
+
+ /*
+ * Invalid pins are 0 on AT91, but the usba driver is shared
+ * with AVR32, which use negative values instead. Once/if
+ * gpio_is_valid() is ported to AT91, revisit this code.
+ */
+ usba_udc_data.pdata.vbus_pin = -EINVAL;
+ usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+ memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
+
+ if (data && data->vbus_pin > 0) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_EMAC,
+ .end = AT91CAP9_BASE_EMAC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_EMAC,
+ .end = AT91CAP9_ID_EMAC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_eth_device = {
+ .name = "macb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &eth_data,
+ },
+ .resource = eth_resources,
+ .num_resources = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->phy_irq_pin) {
+ at91_set_gpio_input(data->phy_irq_pin, 0);
+ at91_set_deglitch(data->phy_irq_pin, 1);
+ }
+
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */
+ at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */
+
+ if (!data->is_rmii) {
+ at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
+ }
+
+ eth_data = *data;
+ platform_device_register(&at91cap9_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_MCI0,
+ .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_MCI0,
+ .end = AT91CAP9_ID_MCI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_mmc0_device = {
+ .name = "at91_mci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc0_data,
+ },
+ .resource = mmc0_resources,
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_MCI1,
+ .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_MCI1,
+ .end = AT91CAP9_ID_MCI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_mmc1_device = {
+ .name = "at91_mci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc1_data,
+ },
+ .resource = mmc1_resources,
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ if (mmc_id == 0) { /* MCI0 */
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA2, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA0, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA3, 1);
+ at91_set_A_periph(AT91_PIN_PA4, 1);
+ at91_set_A_periph(AT91_PIN_PA5, 1);
+ }
+
+ mmc0_data = *data;
+ platform_device_register(&at91cap9_mmc0_device);
+ } else { /* MCI1 */
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA16, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA17, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA18, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA19, 1);
+ at91_set_A_periph(AT91_PIN_PA20, 1);
+ at91_set_A_periph(AT91_PIN_PA21, 1);
+ }
+
+ mmc1_data = *data;
+ platform_device_register(&at91cap9_mmc1_device);
+ }
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91cap9_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ nand_data = *data;
+ platform_device_register(&at91cap9_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PB4,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PB5,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91cap9_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91cap9_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_TWI,
+ .end = AT91CAP9_BASE_TWI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_TWI,
+ .end = AT91CAP9_ID_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+ at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91cap9_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_SPI0,
+ .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_SPI0,
+ .end = AT91CAP9_ID_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_spi0_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi0_resources,
+ .num_resources = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
+
+static struct resource spi1_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_SPI1,
+ .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_SPI1,
+ .end = AT91CAP9_ID_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_spi1_device = {
+ .name = "atmel_spi",
+ .id = 1,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi1_resources,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+ short enable_spi0 = 0;
+ short enable_spi1 = 0;
+
+ /* Choose SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else if (devices[i].bus_num == 0)
+ cs_pin = spi0_standard_cs[devices[i].chip_select];
+ else
+ cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+ if (devices[i].bus_num == 0)
+ enable_spi0 = 1;
+ else
+ enable_spi1 = 1;
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+
+ /* Configure SPI bus(es) */
+ if (enable_spi0) {
+ at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
+ at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
+ at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
+
+ platform_device_register(&at91cap9_spi0_device);
+ }
+ if (enable_spi1) {
+ at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91cap9_spi1_device);
+ }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_TCB0,
+ .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_TCB,
+ .end = AT91CAP9_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91cap9_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91cap9_rtt_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91cap9_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91cap9_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91cap9_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_PWMC,
+ .end = AT91CAP9_BASE_PWMC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_PWMC,
+ .end = AT91CAP9_ID_PWMC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_pwm0_device = {
+ .name = "atmel_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_mask,
+ },
+ .resource = pwm_resources,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+ if (mask & (1 << AT91_PWM0))
+ at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */
+
+ if (mask & (1 << AT91_PWM1))
+ at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */
+
+ if (mask & (1 << AT91_PWM2))
+ at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */
+
+ if (mask & (1 << AT91_PWM3))
+ at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */
+
+ pwm_mask = mask;
+
+ platform_device_register(&at91cap9_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+
+/* --------------------------------------------------------------------
+ * AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
+static struct ac97c_platform_data ac97_data;
+
+static struct resource ac97_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_AC97C,
+ .end = AT91CAP9_BASE_AC97C + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_AC97C,
+ .end = AT91CAP9_ID_AC97C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_ac97_device = {
+ .name = "atmel_ac97c",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ac97_data,
+ },
+ .resource = ac97_resources,
+ .num_resources = ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */
+ at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */
+ at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */
+ at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
+
+ /* reset */
+ if (data->reset_pin)
+ at91_set_gpio_output(data->reset_pin, 0);
+
+ ac97_data = *data;
+ platform_device_register(&at91cap9_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91CAP9_LCDC_BASE,
+ .end = AT91CAP9_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_LCDC,
+ .end = AT91CAP9_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data)
+ return;
+
+ if (cpu_is_at91cap9_revB())
+ irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
+
+ at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
+ at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
+ at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
+ at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
+ at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
+ at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
+ at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
+ at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */
+ at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
+ at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
+ at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
+ at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
+ at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
+ at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */
+ at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
+ at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
+
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_SSC0,
+ .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_SSC0,
+ .end = AT91CAP9_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB0, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB1, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB2, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB3, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB4, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_SSC1,
+ .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_SSC1,
+ .end = AT91CAP9_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91cap9_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB6, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB7, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB8, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB9, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB10, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91CAP9_ID_SSC0:
+ pdev = &at91cap9_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91CAP9_ID_SSC1:
+ pdev = &at91cap9_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_US0,
+ .end = AT91CAP9_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_US0,
+ .end = AT91CAP9_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_US1,
+ .end = AT91CAP9_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_US1,
+ .end = AT91CAP9_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91CAP9_BASE_US2,
+ .end = AT91CAP9_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91CAP9_ID_US2,
+ .end = AT91CAP9_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91cap9_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91cap9_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91CAP9_ID_US0:
+ pdev = &at91cap9_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91CAP9_ID_US1:
+ pdev = &at91cap9_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91CAP9_ID_US2:
+ pdev = &at91cap9_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91cap9_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
new file mode 100644
index 00000000..83a1a3fe
--- /dev/null
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -0,0 +1,396 @@
+/*
+ * arch/arm/mach-at91/at91rm9200.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91rm9200.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_st.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91rm9200_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_VA_BASE_EMAC,
+ .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE,
+ .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE),
+ .length = AT91RM9200_SRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk udc_clk = {
+ .name = "udc_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_UDP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+ .name = "ohci_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_UHP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ether_clk = {
+ .name = "ether_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_EMAC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+ .name = "mci_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_MCI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+ .name = "twi_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TWI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+ .name = "usart3_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_US3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi_clk = {
+ .name = "spi_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SPI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+ .name = "pioC_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_PIOC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioD_clk = {
+ .name = "pioD_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_PIOD,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+ .name = "ssc2_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_SSC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+ .name = "tc0_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+ .name = "tc1_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+ .name = "tc2_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc3_clk = {
+ .name = "tc3_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc4_clk = {
+ .name = "tc4_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC4,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc5_clk = {
+ .name = "tc5_clk",
+ .pmc_mask = 1 << AT91RM9200_ID_TC5,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioC_clk,
+ &pioD_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &usart3_clk,
+ &mmc_clk,
+ &udc_clk,
+ &twi_clk,
+ &spi_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &ssc2_clk,
+ &tc0_clk,
+ &tc1_clk,
+ &tc2_clk,
+ &tc3_clk,
+ &tc4_clk,
+ &tc5_clk,
+ &ohci_clk,
+ &ether_clk,
+ // irq0 .. irq6
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+static struct clk pck2 = {
+ .name = "pck2",
+ .pmc_mask = AT91_PMC_PCK2,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 2,
+};
+static struct clk pck3 = {
+ .name = "pck3",
+ .pmc_mask = AT91_PMC_PCK3,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 3,
+};
+
+static void __init at91rm9200_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+ clk_register(&pck2);
+ clk_register(&pck3);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91rm9200_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91rm9200_gpio[] = {
+ {
+ .id = AT91RM9200_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91RM9200_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91RM9200_ID_PIOC,
+ .offset = AT91_PIOC,
+ .clock = &pioC_clk,
+ }, {
+ .id = AT91RM9200_ID_PIOD,
+ .offset = AT91_PIOD,
+ .clock = &pioD_clk,
+ }
+};
+
+static void at91rm9200_reset(void)
+{
+ /*
+ * Perform a hardware reset with the use of the Watchdog timer.
+ */
+ at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1);
+ at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
+}
+
+int rm9200_type;
+EXPORT_SYMBOL(rm9200_type);
+
+void __init at91rm9200_set_type(int type)
+{
+ rm9200_type = type;
+}
+
+/* --------------------------------------------------------------------
+ * AT91RM9200 processor initialization
+ * -------------------------------------------------------------------- */
+void __init at91rm9200_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
+}
+
+void __init at91rm9200_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91rm9200_reset;
+ at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
+ | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
+ | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5)
+ | (1 << AT91RM9200_ID_IRQ6);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91rm9200_register_clocks();
+
+ /* Initialize GPIO subsystem */
+ at91_gpio_init(at91rm9200_gpio,
+ cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP);
+}
+
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C */
+ 1, /* Parallel IO Controller D */
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 5, /* USART 3 */
+ 0, /* Multimedia Card Interface */
+ 2, /* USB Device Port */
+ 6, /* Two-Wire Interface */
+ 5, /* Serial Peripheral Interface */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 4, /* Serial Synchronous Controller 2 */
+ 0, /* Timer Counter 0 */
+ 0, /* Timer Counter 1 */
+ 0, /* Timer Counter 2 */
+ 0, /* Timer Counter 3 */
+ 0, /* Timer Counter 4 */
+ 0, /* Timer Counter 5 */
+ 2, /* USB Host port */
+ 3, /* Ethernet MAC */
+ 0, /* Advanced Interrupt Controller (IRQ0) */
+ 0, /* Advanced Interrupt Controller (IRQ1) */
+ 0, /* Advanced Interrupt Controller (IRQ2) */
+ 0, /* Advanced Interrupt Controller (IRQ3) */
+ 0, /* Advanced Interrupt Controller (IRQ4) */
+ 0, /* Advanced Interrupt Controller (IRQ5) */
+ 0 /* Advanced Interrupt Controller (IRQ6) */
+};
+
+void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91rm9200_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
new file mode 100644
index 00000000..7227755f
--- /dev/null
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -0,0 +1,1176 @@
+/*
+ * arch/arm/mach-at91/at91rm9200_devices.c
+ *
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ * Copyright (C) 2005 David Brownell
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+ [0] = {
+ .start = AT91RM9200_UHP_BASE,
+ .end = AT91RM9200_UHP_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_UHP,
+ .end = AT91RM9200_ID_UHP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_usbh_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_data,
+ },
+ .resource = usbh_resources,
+ .num_resources = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ usbh_data = *data;
+ platform_device_register(&at91rm9200_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_UDP,
+ .end = AT91RM9200_BASE_UDP + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_UDP,
+ .end = AT91RM9200_ID_UDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_udc_device = {
+ .name = "at91_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &udc_data,
+ },
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->vbus_pin) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ }
+ if (data->pullup_pin)
+ at91_set_gpio_output(data->pullup_pin, 0);
+
+ udc_data = *data;
+ platform_device_register(&at91rm9200_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_EMAC,
+ .end = AT91_VA_BASE_EMAC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_EMAC,
+ .end = AT91RM9200_ID_EMAC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_eth_device = {
+ .name = "at91_ether",
+ .id = -1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &eth_data,
+ },
+ .resource = eth_resources,
+ .num_resources = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->phy_irq_pin) {
+ at91_set_gpio_input(data->phy_irq_pin, 0);
+ at91_set_deglitch(data->phy_irq_pin, 1);
+ }
+
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */
+ at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */
+
+ if (!data->is_rmii) {
+ at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */
+ at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */
+ at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */
+ }
+
+ eth_data = *data;
+ platform_device_register(&at91rm9200_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Compact Flash / PCMCIA
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
+static struct at91_cf_data cf_data;
+
+#define CF_BASE AT91_CHIPSELECT_4
+
+static struct resource cf_resources[] = {
+ [0] = {
+ .start = CF_BASE,
+ /* ties up CS4, CS5 and CS6 */
+ .end = CF_BASE + (0x30000000 - 1),
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+ },
+};
+
+static struct platform_device at91rm9200_cf_device = {
+ .name = "at91_cf",
+ .id = -1,
+ .dev = {
+ .platform_data = &cf_data,
+ },
+ .resource = cf_resources,
+ .num_resources = ARRAY_SIZE(cf_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+ unsigned int csa;
+
+ if (!data)
+ return;
+
+ data->chipselect = 4; /* can only use EBI ChipSelect 4 */
+
+ /* CF takes over CS4, CS5, CS6 */
+ csa = at91_sys_read(AT91_EBI_CSA);
+ at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
+
+ /*
+ * Static memory controller timing adjustments.
+ * REVISIT: these timings are in terms of MCK cycles, so
+ * when MCK changes (cpufreq etc) so must these values...
+ */
+ at91_sys_write(AT91_SMC_CSR(4),
+ AT91_SMC_ACSS_STD
+ | AT91_SMC_DBW_16
+ | AT91_SMC_BAT
+ | AT91_SMC_WSEN
+ | AT91_SMC_NWS_(32) /* wait states */
+ | AT91_SMC_RWSETUP_(6) /* setup time */
+ | AT91_SMC_RWHOLD_(4) /* hold time */
+ );
+
+ /* input/irq */
+ if (data->irq_pin) {
+ at91_set_gpio_input(data->irq_pin, 1);
+ at91_set_deglitch(data->irq_pin, 1);
+ }
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+
+ /* outputs, initially off */
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+ at91_set_gpio_output(data->rst_pin, 0);
+
+ /* force poweron defaults for these pins ... */
+ at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */
+ at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */
+
+ /* nWAIT is _not_ a default setting */
+ at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */
+
+ cf_data = *data;
+ platform_device_register(&at91rm9200_cf_device);
+}
+#else
+void __init at91_add_device_cf(struct at91_cf_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_MCI,
+ .end = AT91RM9200_BASE_MCI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_MCI,
+ .end = AT91RM9200_ID_MCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_mmc_device = {
+ .name = "at91_mci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc_data,
+ },
+ .resource = mmc_resources,
+ .num_resources = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA27, 0);
+
+ if (data->slot_b) {
+ /* CMD */
+ at91_set_B_periph(AT91_PIN_PA8, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_B_periph(AT91_PIN_PA9, 1);
+ if (data->wire4) {
+ at91_set_B_periph(AT91_PIN_PA10, 1);
+ at91_set_B_periph(AT91_PIN_PA11, 1);
+ at91_set_B_periph(AT91_PIN_PA12, 1);
+ }
+ } else {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA28, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA29, 1);
+ if (data->wire4) {
+ at91_set_B_periph(AT91_PIN_PB3, 1);
+ at91_set_B_periph(AT91_PIN_PB4, 1);
+ at91_set_B_periph(AT91_PIN_PB5, 1);
+ }
+ }
+
+ mmc_data = *data;
+ platform_device_register(&at91rm9200_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91rm9200_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned int csa;
+
+ if (!data)
+ return;
+
+ /* enable the address range of CS3 */
+ csa = at91_sys_read(AT91_EBI_CSA);
+ at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA);
+
+ /* set the bus interface characteristics */
+ at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN
+ | AT91_SMC_NWS_(5)
+ | AT91_SMC_TDF_(1)
+ | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */
+ | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */
+ );
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */
+ at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */
+
+ nand_data = *data;
+ platform_device_register(&at91rm9200_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA25,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA26,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91rm9200_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA25, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA26, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91rm9200_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_TWI,
+ .end = AT91RM9200_BASE_TWI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_TWI,
+ .end = AT91RM9200_ID_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PA25, 1);
+
+ at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PA26, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91rm9200_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_SPI,
+ .end = AT91RM9200_BASE_SPI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_SPI,
+ .end = AT91RM9200_ID_SPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_spi_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi_resources,
+ .num_resources = ARRAY_SIZE(spi_resources),
+};
+
+static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+
+ at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */
+ at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */
+ at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */
+
+ /* Enable SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else
+ cs_pin = spi_standard_cs[devices[i].chip_select];
+
+ if (devices[i].chip_select == 0) /* for CS0 errata */
+ at91_set_A_periph(cs_pin, 0);
+ else
+ at91_set_gpio_output(cs_pin, 1);
+
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+ platform_device_register(&at91rm9200_spi_device);
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb0_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_TCB0,
+ .end = AT91RM9200_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_TC0,
+ .end = AT91RM9200_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91RM9200_ID_TC1,
+ .end = AT91RM9200_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91RM9200_ID_TC2,
+ .end = AT91RM9200_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_tcb0_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb0_resources,
+ .num_resources = ARRAY_SIZE(tcb0_resources),
+};
+
+static struct resource tcb1_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_TCB1,
+ .end = AT91RM9200_BASE_TCB1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_TC3,
+ .end = AT91RM9200_ID_TC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91RM9200_ID_TC4,
+ .end = AT91RM9200_ID_TC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91RM9200_ID_TC5,
+ .end = AT91RM9200_ID_TC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_tcb1_device = {
+ .name = "atmel_tcb",
+ .id = 1,
+ .resource = tcb1_resources,
+ .num_resources = ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91rm9200_tcb0_device);
+ platform_device_register(&at91rm9200_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
+static struct platform_device at91rm9200_rtc_device = {
+ .name = "at91_rtc",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_rtc(void)
+{
+ platform_device_register(&at91rm9200_rtc_device);
+}
+#else
+static void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE)
+static struct platform_device at91rm9200_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91rm9200_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_SSC0,
+ .end = AT91RM9200_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_SSC0,
+ .end = AT91RM9200_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB0, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB1, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB2, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB3, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB4, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_SSC1,
+ .end = AT91RM9200_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_SSC1,
+ .end = AT91RM9200_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB6, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB7, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB8, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB9, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB10, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+static u64 ssc2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc2_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_SSC2,
+ .end = AT91RM9200_BASE_SSC2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_SSC2,
+ .end = AT91RM9200_ID_SSC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91rm9200_ssc2_device = {
+ .name = "ssc",
+ .id = 2,
+ .dev = {
+ .dma_mask = &ssc2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc2_resources,
+ .num_resources = ARRAY_SIZE(ssc2_resources),
+};
+
+static inline void configure_ssc2_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB12, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB13, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB14, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB15, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB16, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB17, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91RM9200_ID_SSC0:
+ pdev = &at91rm9200_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91RM9200_ID_SSC1:
+ pdev = &at91rm9200_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ case AT91RM9200_ID_SSC2:
+ pdev = &at91rm9200_ssc2_device;
+ configure_ssc2_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91rm9200_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_US0,
+ .end = AT91RM9200_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_US0,
+ .end = AT91RM9200_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91rm9200_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */
+
+ if (pins & ATMEL_UART_RTS) {
+ /*
+ * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21.
+ * We need to drive the pin manually. Default is off (RTS is active low).
+ */
+ at91_set_gpio_output(AT91_PIN_PA21, 1);
+ }
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_US1,
+ .end = AT91RM9200_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_US1,
+ .end = AT91RM9200_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91rm9200_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RI)
+ at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */
+ if (pins & ATMEL_UART_DTR)
+ at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */
+ if (pins & ATMEL_UART_DCD)
+ at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */
+ if (pins & ATMEL_UART_DSR)
+ at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_US2,
+ .end = AT91RM9200_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_US2,
+ .end = AT91RM9200_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91rm9200_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */
+ at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */
+
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA30, 0); /* CTS2 */
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA31, 0); /* RTS2 */
+}
+
+static struct resource uart3_resources[] = {
+ [0] = {
+ .start = AT91RM9200_BASE_US3,
+ .end = AT91RM9200_BASE_US3 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91RM9200_ID_US3,
+ .end = AT91RM9200_ID_US3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart3_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91rm9200_uart3_device = {
+ .name = "atmel_usart",
+ .id = 4,
+ .dev = {
+ .dma_mask = &uart3_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart3_data,
+ },
+ .resource = uart3_resources,
+ .num_resources = ARRAY_SIZE(uart3_resources),
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+ at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */
+ at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */
+
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS3 */
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS3 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91rm9200_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91RM9200_ID_US0:
+ pdev = &at91rm9200_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91RM9200_ID_US1:
+ pdev = &at91rm9200_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91RM9200_ID_US2:
+ pdev = &at91rm9200_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ case AT91RM9200_ID_US3:
+ pdev = &at91rm9200_uart3_device;
+ configure_usart3_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91rm9200_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init __deprecated at91_init_serial(struct at91_uart_config *config) {}
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_rtc();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
new file mode 100644
index 00000000..1dd69c85
--- /dev/null
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -0,0 +1,209 @@
+/*
+ * linux/arch/arm/mach-at91/at91rm9200_time.c
+ *
+ * Copyright (C) 2003 SAN People
+ * Copyright (C) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/at91_st.h>
+
+static unsigned long last_crtr;
+static u32 irqmask;
+static struct clock_event_device clkevt;
+
+/*
+ * The ST_CRTR is updated asynchronously to the master clock ... but
+ * the updates as seen by the CPU don't seem to be strictly monotonic.
+ * Waiting until we read the same value twice avoids glitching.
+ */
+static inline unsigned long read_CRTR(void)
+{
+ unsigned long x1, x2;
+
+ x1 = at91_sys_read(AT91_ST_CRTR);
+ do {
+ x2 = at91_sys_read(AT91_ST_CRTR);
+ if (x1 == x2)
+ break;
+ x1 = x2;
+ } while (1);
+ return x1;
+}
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id)
+{
+ u32 sr = at91_sys_read(AT91_ST_SR) & irqmask;
+
+ /*
+ * irqs should be disabled here, but as the irq is shared they are only
+ * guaranteed to be off if the timer irq is registered first.
+ */
+ WARN_ON_ONCE(!irqs_disabled());
+
+ /* simulate "oneshot" timer with alarm */
+ if (sr & AT91_ST_ALMS) {
+ clkevt.event_handler(&clkevt);
+ return IRQ_HANDLED;
+ }
+
+ /* periodic mode should handle delayed ticks */
+ if (sr & AT91_ST_PITS) {
+ u32 crtr = read_CRTR();
+
+ while (((crtr - last_crtr) & AT91_ST_CRTV) >= LATCH) {
+ last_crtr += LATCH;
+ clkevt.event_handler(&clkevt);
+ }
+ return IRQ_HANDLED;
+ }
+
+ /* this irq is shared ... */
+ return IRQ_NONE;
+}
+
+static struct irqaction at91rm9200_timer_irq = {
+ .name = "at91_tick",
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = at91rm9200_timer_interrupt
+};
+
+static cycle_t read_clk32k(struct clocksource *cs)
+{
+ return read_CRTR();
+}
+
+static struct clocksource clk32k = {
+ .name = "32k_counter",
+ .rating = 150,
+ .read = read_clk32k,
+ .mask = CLOCKSOURCE_MASK(20),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void
+clkevt32k_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ /* Disable and flush pending timer interrupts */
+ at91_sys_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_ALMS);
+ (void) at91_sys_read(AT91_ST_SR);
+
+ last_crtr = read_CRTR();
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* PIT for periodic irqs; fixed rate of 1/HZ */
+ irqmask = AT91_ST_PITS;
+ at91_sys_write(AT91_ST_PIMR, LATCH);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* ALM for oneshot irqs, set by next_event()
+ * before 32 seconds have passed
+ */
+ irqmask = AT91_ST_ALMS;
+ at91_sys_write(AT91_ST_RTAR, last_crtr);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ irqmask = 0;
+ break;
+ }
+ at91_sys_write(AT91_ST_IER, irqmask);
+}
+
+static int
+clkevt32k_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+ u32 alm;
+ int status = 0;
+
+ BUG_ON(delta < 2);
+
+ /* The alarm IRQ uses absolute time (now+delta), not the relative
+ * time (delta) in our calling convention. Like all clockevents
+ * using such "match" hardware, we have a race to defend against.
+ *
+ * Our defense here is to have set up the clockevent device so the
+ * delta is at least two. That way we never end up writing RTAR
+ * with the value then held in CRTR ... which would mean the match
+ * wouldn't trigger until 32 seconds later, after CRTR wraps.
+ */
+ alm = read_CRTR();
+
+ /* Cancel any pending alarm; flush any pending IRQ */
+ at91_sys_write(AT91_ST_RTAR, alm);
+ (void) at91_sys_read(AT91_ST_SR);
+
+ /* Schedule alarm by writing RTAR. */
+ alm += delta;
+ at91_sys_write(AT91_ST_RTAR, alm);
+
+ return status;
+}
+
+static struct clock_event_device clkevt = {
+ .name = "at91_tick",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 150,
+ .set_next_event = clkevt32k_next_event,
+ .set_mode = clkevt32k_mode,
+};
+
+/*
+ * ST (system timer) module supports both clockevents and clocksource.
+ */
+void __init at91rm9200_timer_init(void)
+{
+ /* Disable all timer interrupts, and clear any pending ones */
+ at91_sys_write(AT91_ST_IDR,
+ AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS);
+ (void) at91_sys_read(AT91_ST_SR);
+
+ /* Make IRQs happen for the system timer */
+ setup_irq(AT91_ID_SYS, &at91rm9200_timer_irq);
+
+ /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used
+ * directly for the clocksource and all clockevents, after adjusting
+ * its prescaler from the 1 Hz default.
+ */
+ at91_sys_write(AT91_ST_RTMR, 1);
+
+ /* Setup timer clockevent, with minimum of two ticks (important!!) */
+ clkevt.mult = div_sc(AT91_SLOW_CLOCK, NSEC_PER_SEC, clkevt.shift);
+ clkevt.max_delta_ns = clockevent_delta2ns(AT91_ST_ALMV, &clkevt);
+ clkevt.min_delta_ns = clockevent_delta2ns(2, &clkevt) + 1;
+ clkevt.cpumask = cpumask_of(0);
+ clockevents_register_device(&clkevt);
+
+ /* register clocksource */
+ clocksource_register_hz(&clk32k, AT91_SLOW_CLOCK);
+}
+
+struct sys_timer at91rm9200_timer = {
+ .init = at91rm9200_timer_init,
+};
+
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
new file mode 100644
index 00000000..eeb94785
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -0,0 +1,434 @@
+/*
+ * arch/arm/mach-at91/at91sam9260.c
+ *
+ * Copyright (C) 2006 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/cpu.h>
+#include <mach/at91sam9260.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9260_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }
+};
+
+static struct map_desc at91sam9260_sram_desc[] __initdata = {
+ {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE),
+ .length = AT91SAM9260_SRAM0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE),
+ .length = AT91SAM9260_SRAM1_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+static struct map_desc at91sam9g20_sram_desc[] __initdata = {
+ {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE),
+ .length = AT91SAM9G20_SRAM0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE),
+ .length = AT91SAM9G20_SRAM1_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+static struct map_desc at91sam9xe_sram_desc[] __initdata = {
+ {
+ .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE),
+ .type = MT_DEVICE,
+ }
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+ .name = "pioC_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_PIOC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk adc_clk = {
+ .name = "adc_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_ADC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+ .name = "mci_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_MCI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+ .name = "udc_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_UDP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+ .name = "twi_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TWI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+ .name = "spi0_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_SPI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+ .name = "spi1_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_SPI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc_clk = {
+ .name = "ssc_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_SSC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+ .name = "tc0_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+ .name = "tc1_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+ .name = "tc2_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+ .name = "ohci_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_UHP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+ .name = "macb_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_EMAC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+ .name = "isi_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_ISI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+ .name = "usart3_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart4_clk = {
+ .name = "usart4_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US4,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart5_clk = {
+ .name = "usart5_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_US5,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc3_clk = {
+ .name = "tc3_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc4_clk = {
+ .name = "tc4_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC4,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc5_clk = {
+ .name = "tc5_clk",
+ .pmc_mask = 1 << AT91SAM9260_ID_TC5,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioC_clk,
+ &adc_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &mmc_clk,
+ &udc_clk,
+ &twi_clk,
+ &spi0_clk,
+ &spi1_clk,
+ &ssc_clk,
+ &tc0_clk,
+ &tc1_clk,
+ &tc2_clk,
+ &ohci_clk,
+ &macb_clk,
+ &isi_clk,
+ &usart3_clk,
+ &usart4_clk,
+ &usart5_clk,
+ &tc3_clk,
+ &tc4_clk,
+ &tc5_clk,
+ // irq0 .. irq2
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk),
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+
+static void __init at91sam9260_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9260_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9260_gpio[] = {
+ {
+ .id = AT91SAM9260_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91SAM9260_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91SAM9260_ID_PIOC,
+ .offset = AT91_PIOC,
+ .clock = &pioC_clk,
+ }
+};
+
+static void at91sam9260_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91SAM9260 processor initialization
+ * -------------------------------------------------------------------- */
+
+static void __init at91sam9xe_map_io(void)
+{
+ unsigned long cidr, sram_size;
+
+ cidr = at91_sys_read(AT91_DBGU_CIDR);
+
+ switch (cidr & AT91_CIDR_SRAMSIZ) {
+ case AT91_CIDR_SRAMSIZ_32K:
+ sram_size = 2 * SZ_16K;
+ break;
+ case AT91_CIDR_SRAMSIZ_16K:
+ default:
+ sram_size = SZ_16K;
+ }
+
+ at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
+ at91sam9xe_sram_desc->length = sram_size;
+
+ iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc));
+}
+
+void __init at91sam9260_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
+
+ if (cpu_is_at91sam9xe())
+ at91sam9xe_map_io();
+ else if (cpu_is_at91sam9g20())
+ iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc));
+ else
+ iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
+}
+
+void __init at91sam9260_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91sam9_alt_reset;
+ pm_power_off = at91sam9260_poweroff;
+ at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
+ | (1 << AT91SAM9260_ID_IRQ2);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91sam9260_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9260_gpio, 3);
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C */
+ 0, /* Analog-to-Digital Converter */
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 0, /* Multimedia Card Interface */
+ 2, /* USB Device Port */
+ 6, /* Two-Wire Interface */
+ 5, /* Serial Peripheral Interface 0 */
+ 5, /* Serial Peripheral Interface 1 */
+ 5, /* Serial Synchronous Controller */
+ 0,
+ 0,
+ 0, /* Timer Counter 0 */
+ 0, /* Timer Counter 1 */
+ 0, /* Timer Counter 2 */
+ 2, /* USB Host port */
+ 3, /* Ethernet */
+ 0, /* Image Sensor Interface */
+ 5, /* USART 3 */
+ 5, /* USART 4 */
+ 5, /* USART 5 */
+ 0, /* Timer Counter 3 */
+ 0, /* Timer Counter 4 */
+ 0, /* Timer Counter 5 */
+ 0, /* Advanced Interrupt Controller */
+ 0, /* Advanced Interrupt Controller */
+ 0, /* Advanced Interrupt Controller */
+};
+
+void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91sam9260_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
new file mode 100644
index 00000000..39f81f47
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -0,0 +1,1328 @@
+/*
+ * arch/arm/mach-at91/at91sam9260_devices.c
+ *
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+#include <mach/at91sam9260.h>
+#include <mach/at91sam9260_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_UHP_BASE,
+ .end = AT91SAM9260_UHP_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_UHP,
+ .end = AT91SAM9260_ID_UHP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_usbh_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_data,
+ },
+ .resource = usbh_resources,
+ .num_resources = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ usbh_data = *data;
+ platform_device_register(&at91_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_UDP,
+ .end = AT91SAM9260_BASE_UDP + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_UDP,
+ .end = AT91SAM9260_ID_UDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_udc_device = {
+ .name = "at91_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &udc_data,
+ },
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->vbus_pin) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ udc_data = *data;
+ platform_device_register(&at91_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_EMAC,
+ .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_EMAC,
+ .end = AT91SAM9260_ID_EMAC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_eth_device = {
+ .name = "macb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &eth_data,
+ },
+ .resource = eth_resources,
+ .num_resources = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->phy_irq_pin) {
+ at91_set_gpio_input(data->phy_irq_pin, 0);
+ at91_set_deglitch(data->phy_irq_pin, 1);
+ }
+
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */
+ at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */
+
+ if (!data->is_rmii) {
+ at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */
+ }
+
+ eth_data = *data;
+ platform_device_register(&at91sam9260_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_MCI,
+ .end = AT91SAM9260_BASE_MCI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_MCI,
+ .end = AT91SAM9260_ID_MCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_mmc_device = {
+ .name = "at91_mci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc_data,
+ },
+ .resource = mmc_resources,
+ .num_resources = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA8, 0);
+
+ if (data->slot_b) {
+ /* CMD */
+ at91_set_B_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_B_periph(AT91_PIN_PA0, 1);
+ if (data->wire4) {
+ at91_set_B_periph(AT91_PIN_PA5, 1);
+ at91_set_B_periph(AT91_PIN_PA4, 1);
+ at91_set_B_periph(AT91_PIN_PA3, 1);
+ }
+ } else {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA6, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ at91_set_A_periph(AT91_PIN_PA10, 1);
+ at91_set_A_periph(AT91_PIN_PA11, 1);
+ }
+ }
+
+ mmc_data = *data;
+ platform_device_register(&at91sam9260_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * MMC / SD Slot for Atmel MCI Driver
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct mci_platform_data mmc_data;
+
+static struct resource mmc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_MCI,
+ .end = AT91SAM9260_BASE_MCI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_MCI,
+ .end = AT91SAM9260_ID_MCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_mmc_device = {
+ .name = "atmel_mci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc_data,
+ },
+ .resource = mmc_resources,
+ .num_resources = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
+{
+ unsigned int i;
+ unsigned int slot_count = 0;
+
+ if (!data)
+ return;
+
+ for (i = 0; i < ATMEL_MCI_MAX_NR_SLOTS; i++) {
+ if (data->slot[i].bus_width) {
+ /* input/irq */
+ if (data->slot[i].detect_pin) {
+ at91_set_gpio_input(data->slot[i].detect_pin, 1);
+ at91_set_deglitch(data->slot[i].detect_pin, 1);
+ }
+ if (data->slot[i].wp_pin)
+ at91_set_gpio_input(data->slot[i].wp_pin, 1);
+
+ switch (i) {
+ case 0:
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA6, 1);
+ if (data->slot[i].bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ at91_set_A_periph(AT91_PIN_PA10, 1);
+ at91_set_A_periph(AT91_PIN_PA11, 1);
+ }
+ slot_count++;
+ break;
+ case 1:
+ /* CMD */
+ at91_set_B_periph(AT91_PIN_PA1, 1);
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_B_periph(AT91_PIN_PA0, 1);
+ if (data->slot[i].bus_width == 4) {
+ at91_set_B_periph(AT91_PIN_PA5, 1);
+ at91_set_B_periph(AT91_PIN_PA4, 1);
+ at91_set_B_periph(AT91_PIN_PA3, 1);
+ }
+ slot_count++;
+ break;
+ default:
+ printk(KERN_ERR
+ "AT91: SD/MMC slot %d not available\n", i);
+ break;
+ }
+ }
+ }
+
+ if (slot_count) {
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA8, 0);
+
+ mmc_data = *data;
+ platform_device_register(&at91sam9260_mmc_device);
+ }
+}
+#else
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9260_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ nand_data = *data;
+ platform_device_register(&at91sam9260_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA23,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA24,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9260_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9260_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_TWI,
+ .end = AT91SAM9260_BASE_TWI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_TWI,
+ .end = AT91SAM9260_ID_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9260_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_SPI0,
+ .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_SPI0,
+ .end = AT91SAM9260_ID_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_spi0_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi0_resources,
+ .num_resources = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 };
+
+static struct resource spi1_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_SPI1,
+ .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_SPI1,
+ .end = AT91SAM9260_ID_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_spi1_device = {
+ .name = "atmel_spi",
+ .id = 1,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi1_resources,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+ short enable_spi0 = 0;
+ short enable_spi1 = 0;
+
+ /* Choose SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else if (devices[i].bus_num == 0)
+ cs_pin = spi0_standard_cs[devices[i].chip_select];
+ else
+ cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+ if (devices[i].bus_num == 0)
+ enable_spi0 = 1;
+ else
+ enable_spi1 = 1;
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+
+ /* Configure SPI bus(es) */
+ if (enable_spi0) {
+ at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
+ at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
+ at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91sam9260_spi0_device);
+ }
+ if (enable_spi1) {
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91sam9260_spi1_device);
+ }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter blocks
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb0_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_TCB0,
+ .end = AT91SAM9260_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_TC0,
+ .end = AT91SAM9260_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9260_ID_TC1,
+ .end = AT91SAM9260_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9260_ID_TC2,
+ .end = AT91SAM9260_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_tcb0_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb0_resources,
+ .num_resources = ARRAY_SIZE(tcb0_resources),
+};
+
+static struct resource tcb1_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_TCB1,
+ .end = AT91SAM9260_BASE_TCB1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_TC3,
+ .end = AT91SAM9260_ID_TC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9260_ID_TC4,
+ .end = AT91SAM9260_ID_TC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9260_ID_TC5,
+ .end = AT91SAM9260_ID_TC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_tcb1_device = {
+ .name = "atmel_tcb",
+ .id = 1,
+ .resource = tcb1_resources,
+ .num_resources = ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91sam9260_tcb0_device);
+ platform_device_register(&at91sam9260_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9260_rtt_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91sam9260_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91sam9260_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91sam9260_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_SSC,
+ .end = AT91SAM9260_BASE_SSC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_SSC,
+ .end = AT91SAM9260_ID_SSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9260_ssc_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc_resources,
+ .num_resources = ARRAY_SIZE(ssc_resources),
+};
+
+static inline void configure_ssc_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB17, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB16, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB18, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB19, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB20, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB21, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91SAM9260_ID_SSC:
+ pdev = &at91sam9260_ssc_device;
+ configure_ssc_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US0,
+ .end = AT91SAM9260_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US0,
+ .end = AT91SAM9260_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */
+ if (pins & ATMEL_UART_DTR)
+ at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */
+ if (pins & ATMEL_UART_DSR)
+ at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */
+ if (pins & ATMEL_UART_DCD)
+ at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */
+ if (pins & ATMEL_UART_RI)
+ at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US1,
+ .end = AT91SAM9260_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US1,
+ .end = AT91SAM9260_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US2,
+ .end = AT91SAM9260_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US2,
+ .end = AT91SAM9260_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA4, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA5, 0); /* CTS2 */
+}
+
+static struct resource uart3_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US3,
+ .end = AT91SAM9260_BASE_US3 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US3,
+ .end = AT91SAM9260_ID_US3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart3_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart3_device = {
+ .name = "atmel_usart",
+ .id = 4,
+ .dev = {
+ .dma_mask = &uart3_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart3_data,
+ },
+ .resource = uart3_resources,
+ .num_resources = ARRAY_SIZE(uart3_resources),
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */
+ at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PC8, 0); /* RTS3 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PC10, 0); /* CTS3 */
+}
+
+static struct resource uart4_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US4,
+ .end = AT91SAM9260_BASE_US4 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US4,
+ .end = AT91SAM9260_ID_US4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart4_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart4_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart4_device = {
+ .name = "atmel_usart",
+ .id = 5,
+ .dev = {
+ .dma_mask = &uart4_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart4_data,
+ },
+ .resource = uart4_resources,
+ .num_resources = ARRAY_SIZE(uart4_resources),
+};
+
+static inline void configure_usart4_pins(void)
+{
+ at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */
+ at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */
+}
+
+static struct resource uart5_resources[] = {
+ [0] = {
+ .start = AT91SAM9260_BASE_US5,
+ .end = AT91SAM9260_BASE_US5 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9260_ID_US5,
+ .end = AT91SAM9260_ID_US5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart5_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart5_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9260_uart5_device = {
+ .name = "atmel_usart",
+ .id = 6,
+ .dev = {
+ .dma_mask = &uart5_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart5_data,
+ },
+ .resource = uart5_resources,
+ .num_resources = ARRAY_SIZE(uart5_resources),
+};
+
+static inline void configure_usart5_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */
+ at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9260_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91SAM9260_ID_US0:
+ pdev = &at91sam9260_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91SAM9260_ID_US1:
+ pdev = &at91sam9260_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91SAM9260_ID_US2:
+ pdev = &at91sam9260_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ case AT91SAM9260_ID_US3:
+ pdev = &at91sam9260_uart3_device;
+ configure_usart3_pins(pins);
+ break;
+ case AT91SAM9260_ID_US4:
+ pdev = &at91sam9260_uart4_device;
+ configure_usart4_pins();
+ break;
+ case AT91SAM9260_ID_US5:
+ pdev = &at91sam9260_uart5_device;
+ configure_usart5_pins();
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91sam9260_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * CF/IDE
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \
+ defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \
+ defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
+
+static struct at91_cf_data cf0_data;
+
+static struct resource cf0_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_4,
+ .end = AT91_CHIPSELECT_4 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device cf0_device = {
+ .id = 0,
+ .dev = {
+ .platform_data = &cf0_data,
+ },
+ .resource = cf0_resources,
+ .num_resources = ARRAY_SIZE(cf0_resources),
+};
+
+static struct at91_cf_data cf1_data;
+
+static struct resource cf1_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_5,
+ .end = AT91_CHIPSELECT_5 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device cf1_device = {
+ .id = 1,
+ .dev = {
+ .platform_data = &cf1_data,
+ },
+ .resource = cf1_resources,
+ .num_resources = ARRAY_SIZE(cf1_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+ struct platform_device *pdev;
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+
+ switch (data->chipselect) {
+ case 4:
+ at91_set_multi_drive(AT91_PIN_PC8, 0);
+ at91_set_A_periph(AT91_PIN_PC8, 0);
+ csa |= AT91_MATRIX_CS4A_SMC_CF1;
+ cf0_data = *data;
+ pdev = &cf0_device;
+ break;
+ case 5:
+ at91_set_multi_drive(AT91_PIN_PC9, 0);
+ at91_set_A_periph(AT91_PIN_PC9, 0);
+ csa |= AT91_MATRIX_CS5A_SMC_CF2;
+ cf1_data = *data;
+ pdev = &cf1_device;
+ break;
+ default:
+ printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
+ data->chipselect);
+ return;
+ }
+
+ at91_sys_write(AT91_MATRIX_EBICSA, csa);
+
+ if (data->rst_pin) {
+ at91_set_multi_drive(data->rst_pin, 0);
+ at91_set_gpio_output(data->rst_pin, 1);
+ }
+
+ if (data->irq_pin) {
+ at91_set_gpio_input(data->irq_pin, 0);
+ at91_set_deglitch(data->irq_pin, 1);
+ }
+
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 0);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+
+ at91_set_B_periph(AT91_PIN_PC6, 0); /* CFCE1 */
+ at91_set_B_periph(AT91_PIN_PC7, 0); /* CFCE2 */
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* CFRNW */
+ at91_set_A_periph(AT91_PIN_PC15, 1); /* NWAIT */
+
+ if (data->flags & AT91_CF_TRUE_IDE)
+#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE)
+ pdev->name = "pata_at91";
+#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+ pdev->name = "at91_ide";
+#else
+#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91"
+#endif
+ else
+ pdev->name = "at91_cf";
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_cf(struct at91_cf_data * data) {}
+#endif
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
new file mode 100644
index 00000000..c1483168
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -0,0 +1,385 @@
+/*
+ * arch/arm/mach-at91/at91sam9261.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/cpu.h>
+#include <mach/at91sam9261.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9261_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc at91sam9261_sram_desc[] __initdata = {
+ {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE),
+ .length = AT91SAM9261_SRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc at91sam9g10_sram_desc[] __initdata = {
+ {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G10_SRAM_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G10_SRAM_BASE),
+ .length = AT91SAM9G10_SRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+ .name = "pioC_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_PIOC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+ .name = "mci_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_MCI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+ .name = "udc_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_UDP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+ .name = "twi_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_TWI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+ .name = "spi0_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SPI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+ .name = "spi1_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SPI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc2_clk = {
+ .name = "ssc2_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_SSC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+ .name = "tc0_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_TC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+ .name = "tc1_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_TC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+ .name = "tc2_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_TC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+ .name = "ohci_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_UHP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+ .name = "lcdc_clk",
+ .pmc_mask = 1 << AT91SAM9261_ID_LCDC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioC_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &mmc_clk,
+ &udc_clk,
+ &twi_clk,
+ &spi0_clk,
+ &spi1_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &ssc2_clk,
+ &tc0_clk,
+ &tc1_clk,
+ &tc2_clk,
+ &ohci_clk,
+ &lcdc_clk,
+ // irq0 .. irq2
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+static struct clk pck2 = {
+ .name = "pck2",
+ .pmc_mask = AT91_PMC_PCK2,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 2,
+};
+static struct clk pck3 = {
+ .name = "pck3",
+ .pmc_mask = AT91_PMC_PCK3,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 3,
+};
+
+/* HClocks */
+static struct clk hck0 = {
+ .name = "hck0",
+ .pmc_mask = AT91_PMC_HCK0,
+ .type = CLK_TYPE_SYSTEM,
+ .id = 0,
+};
+static struct clk hck1 = {
+ .name = "hck1",
+ .pmc_mask = AT91_PMC_HCK1,
+ .type = CLK_TYPE_SYSTEM,
+ .id = 1,
+};
+
+static void __init at91sam9261_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+ clk_register(&pck2);
+ clk_register(&pck3);
+
+ clk_register(&hck0);
+ clk_register(&hck1);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9261_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9261_gpio[] = {
+ {
+ .id = AT91SAM9261_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91SAM9261_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91SAM9261_ID_PIOC,
+ .offset = AT91_PIOC,
+ .clock = &pioC_clk,
+ }
+};
+
+static void at91sam9261_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91SAM9261 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9261_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
+
+ if (cpu_is_at91sam9g10())
+ iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
+ else
+ iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
+}
+
+void __init at91sam9261_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91sam9_alt_reset;
+ pm_power_off = at91sam9261_poweroff;
+ at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
+ | (1 << AT91SAM9261_ID_IRQ2);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91sam9261_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9261_gpio, 3);
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C */
+ 0,
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 0, /* Multimedia Card Interface */
+ 2, /* USB Device Port */
+ 6, /* Two-Wire Interface */
+ 5, /* Serial Peripheral Interface 0 */
+ 5, /* Serial Peripheral Interface 1 */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 4, /* Serial Synchronous Controller 2 */
+ 0, /* Timer Counter 0 */
+ 0, /* Timer Counter 1 */
+ 0, /* Timer Counter 2 */
+ 2, /* USB Host port */
+ 3, /* LCD Controller */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* Advanced Interrupt Controller */
+ 0, /* Advanced Interrupt Controller */
+ 0, /* Advanced Interrupt Controller */
+};
+
+void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91sam9261_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
new file mode 100644
index 00000000..5004bf0a
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -0,0 +1,1053 @@
+/*
+ * arch/arm/mach-at91/at91sam9261_devices.c
+ *
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ * Copyright (C) 2005 David Brownell
+ *
+ * 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9261.h>
+#include <mach/at91sam9261_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_UHP_BASE,
+ .end = AT91SAM9261_UHP_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_UHP,
+ .end = AT91SAM9261_ID_UHP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_usbh_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_data,
+ },
+ .resource = usbh_resources,
+ .num_resources = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+ if (!data)
+ return;
+
+ usbh_data = *data;
+ platform_device_register(&at91sam9261_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_UDP,
+ .end = AT91SAM9261_BASE_UDP + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_UDP,
+ .end = AT91SAM9261_ID_UDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_udc_device = {
+ .name = "at91_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &udc_data,
+ },
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->vbus_pin) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ udc_data = *data;
+ platform_device_register(&at91sam9261_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_MCI,
+ .end = AT91SAM9261_BASE_MCI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_MCI,
+ .end = AT91SAM9261_ID_MCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_mmc_device = {
+ .name = "at91_mci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc_data,
+ },
+ .resource = mmc_resources,
+ .num_resources = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ /* CLK */
+ at91_set_B_periph(AT91_PIN_PA2, 0);
+
+ /* CMD */
+ at91_set_B_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_B_periph(AT91_PIN_PA0, 1);
+ if (data->wire4) {
+ at91_set_B_periph(AT91_PIN_PA4, 1);
+ at91_set_B_periph(AT91_PIN_PA5, 1);
+ at91_set_B_periph(AT91_PIN_PA6, 1);
+ }
+
+ mmc_data = *data;
+ platform_device_register(&at91sam9261_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device atmel_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */
+ at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */
+
+ nand_data = *data;
+ platform_device_register(&atmel_nand_device);
+}
+
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA7,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA8,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9261_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA7, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA7, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA8, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA8, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9261_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_TWI,
+ .end = AT91SAM9261_BASE_TWI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_TWI,
+ .end = AT91SAM9261_ID_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PA7, 1);
+
+ at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PA8, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9261_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SPI0,
+ .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_SPI0,
+ .end = AT91SAM9261_ID_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_spi0_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi0_resources,
+ .num_resources = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 };
+
+static struct resource spi1_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SPI1,
+ .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_SPI1,
+ .end = AT91SAM9261_ID_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_spi1_device = {
+ .name = "atmel_spi",
+ .id = 1,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi1_resources,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+ short enable_spi0 = 0;
+ short enable_spi1 = 0;
+
+ /* Choose SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else if (devices[i].bus_num == 0)
+ cs_pin = spi0_standard_cs[devices[i].chip_select];
+ else
+ cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+ if (devices[i].bus_num == 0)
+ enable_spi0 = 1;
+ else
+ enable_spi1 = 1;
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+
+ /* Configure SPI bus(es) */
+ if (enable_spi0) {
+ at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
+ at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
+ at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
+
+ platform_device_register(&at91sam9261_spi0_device);
+ }
+ if (enable_spi1) {
+ at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91sam9261_spi1_device);
+ }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_LCDC_BASE,
+ .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_LCDC,
+ .end = AT91SAM9261_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+#if defined(CONFIG_FB_INTSRAM)
+ [2] = {
+ .start = AT91SAM9261_SRAM_BASE,
+ .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+#endif
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data) {
+ return;
+ }
+
+#if defined(CONFIG_FB_ATMEL_STN)
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* LCDVSYNC */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */
+ at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* LCDD0 */
+ at91_set_A_periph(AT91_PIN_PB6, 0); /* LCDD1 */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */
+#else
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */
+ at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */
+ at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */
+ at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */
+ at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */
+ at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */
+ at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */
+ at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */
+ at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */
+ at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */
+ at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */
+ at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */
+ at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */
+ at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */
+ at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */
+ at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */
+ at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */
+ at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */
+#endif
+
+ if (ARRAY_SIZE(lcdc_resources) > 2) {
+ void __iomem *fb;
+ struct resource *fb_res = &lcdc_resources[2];
+ size_t fb_len = fb_res->end - fb_res->start + 1;
+
+ fb = ioremap(fb_res->start, fb_len);
+ if (fb) {
+ memset(fb, 0, fb_len);
+ iounmap(fb);
+ }
+ }
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_TCB0,
+ .end = AT91SAM9261_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_TC0,
+ .end = AT91SAM9261_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9261_ID_TC1,
+ .end = AT91SAM9261_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9261_ID_TC2,
+ .end = AT91SAM9261_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91sam9261_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9261_rtt_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91sam9261_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91sam9261_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91sam9261_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SSC0,
+ .end = AT91SAM9261_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_SSC0,
+ .end = AT91SAM9261_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB21, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB22, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB23, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB24, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB25, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB26, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SSC1,
+ .end = AT91SAM9261_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_SSC1,
+ .end = AT91SAM9261_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_B_periph(AT91_PIN_PA17, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_B_periph(AT91_PIN_PA18, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_B_periph(AT91_PIN_PA19, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_B_periph(AT91_PIN_PA20, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_B_periph(AT91_PIN_PA21, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_B_periph(AT91_PIN_PA22, 1);
+}
+
+static u64 ssc2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc2_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_SSC2,
+ .end = AT91SAM9261_BASE_SSC2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_SSC2,
+ .end = AT91SAM9261_ID_SSC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9261_ssc2_device = {
+ .name = "ssc",
+ .id = 2,
+ .dev = {
+ .dma_mask = &ssc2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc2_resources,
+ .num_resources = ARRAY_SIZE(ssc2_resources),
+};
+
+static inline void configure_ssc2_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_B_periph(AT91_PIN_PC25, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_B_periph(AT91_PIN_PC26, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_B_periph(AT91_PIN_PC27, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_B_periph(AT91_PIN_PC28, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_B_periph(AT91_PIN_PC29, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_B_periph(AT91_PIN_PC30, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91SAM9261_ID_SSC0:
+ pdev = &at91sam9261_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91SAM9261_ID_SSC1:
+ pdev = &at91sam9261_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ case AT91SAM9261_ID_SSC2:
+ pdev = &at91sam9261_ssc2_device;
+ configure_ssc2_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9261_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_US0,
+ .end = AT91SAM9261_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_US0,
+ .end = AT91SAM9261_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9261_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_US1,
+ .end = AT91SAM9261_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_US1,
+ .end = AT91SAM9261_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9261_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA12, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA13, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91SAM9261_BASE_US2,
+ .end = AT91SAM9261_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9261_ID_US2,
+ .end = AT91SAM9261_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9261_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */
+ at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA15, 0); /* RTS2*/
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA16, 0); /* CTS2 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9261_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91SAM9261_ID_US0:
+ pdev = &at91sam9261_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91SAM9261_ID_US1:
+ pdev = &at91sam9261_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91SAM9261_ID_US2:
+ pdev = &at91sam9261_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91sam9261_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
new file mode 100644
index 00000000..dc28477d
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -0,0 +1,390 @@
+/*
+ * arch/arm/mach-at91/at91sam9263.c
+ *
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91sam9263.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9263_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE),
+ .length = AT91SAM9263_SRAM0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE),
+ .length = AT91SAM9263_SRAM1_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioCDE_clk = {
+ .name = "pioCDE_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_PIOCDE,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+ .name = "mci0_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_MCI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+ .name = "mci1_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_MCI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk can_clk = {
+ .name = "can_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_CAN,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi_clk = {
+ .name = "twi_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_TWI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+ .name = "spi0_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SPI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+ .name = "spi1_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SPI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+ .name = "ac97_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_AC97C,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb_clk = {
+ .name = "tcb_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_TCB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+ .name = "pwm_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_PWMC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+ .name = "macb_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_EMAC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_DMA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twodge_clk = {
+ .name = "2dge_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_2DGE,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udc_clk = {
+ .name = "udc_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_UDP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+ .name = "isi_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_ISI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+ .name = "lcdc_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_LCDC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ohci_clk = {
+ .name = "ohci_clk",
+ .pmc_mask = 1 << AT91SAM9263_ID_UHP,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioCDE_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &mmc0_clk,
+ &mmc1_clk,
+ &can_clk,
+ &twi_clk,
+ &spi0_clk,
+ &spi1_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &ac97_clk,
+ &tcb_clk,
+ &pwm_clk,
+ &macb_clk,
+ &twodge_clk,
+ &udc_clk,
+ &isi_clk,
+ &lcdc_clk,
+ &dma_clk,
+ &ohci_clk,
+ // irq0 .. irq1
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
+/*
+ * The four programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+static struct clk pck2 = {
+ .name = "pck2",
+ .pmc_mask = AT91_PMC_PCK2,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 2,
+};
+static struct clk pck3 = {
+ .name = "pck3",
+ .pmc_mask = AT91_PMC_PCK3,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 3,
+};
+
+static void __init at91sam9263_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+ clk_register(&pck2);
+ clk_register(&pck3);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9263_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9263_gpio[] = {
+ {
+ .id = AT91SAM9263_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91SAM9263_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOC,
+ .clock = &pioCDE_clk,
+ }, {
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOD,
+ .clock = &pioCDE_clk,
+ }, {
+ .id = AT91SAM9263_ID_PIOCDE,
+ .offset = AT91_PIOE,
+ .clock = &pioCDE_clk,
+ }
+};
+
+static void at91sam9263_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91SAM9263 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9263_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
+}
+
+void __init at91sam9263_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91sam9_alt_reset;
+ pm_power_off = at91sam9263_poweroff;
+ at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91sam9263_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9263_gpio, 5);
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C, D and E */
+ 0,
+ 0,
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 0, /* Multimedia Card Interface 0 */
+ 0, /* Multimedia Card Interface 1 */
+ 3, /* CAN */
+ 6, /* Two-Wire Interface */
+ 5, /* Serial Peripheral Interface 0 */
+ 5, /* Serial Peripheral Interface 1 */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 5, /* AC97 Controller */
+ 0, /* Timer Counter 0, 1 and 2 */
+ 0, /* Pulse Width Modulation Controller */
+ 3, /* Ethernet */
+ 0,
+ 0, /* 2D Graphic Engine */
+ 2, /* USB Device Port */
+ 0, /* Image Sensor Interface */
+ 3, /* LDC Controller */
+ 0, /* DMA Controller */
+ 0,
+ 2, /* USB Host port */
+ 0, /* Advanced Interrupt Controller (IRQ0) */
+ 0, /* Advanced Interrupt Controller (IRQ1) */
+};
+
+void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91sam9263_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
new file mode 100644
index 00000000..a050f41f
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -0,0 +1,1434 @@
+/*
+ * arch/arm/mach-at91/at91sam9263_devices.c
+ *
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9263.h>
+#include <mach/at91sam9263_matrix.h>
+#include <mach/at91sam9_smc.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * USB Host
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_data;
+
+static struct resource usbh_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_UHP_BASE,
+ .end = AT91SAM9263_UHP_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_UHP,
+ .end = AT91SAM9263_ID_UHP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_usbh_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_data,
+ },
+ .resource = usbh_resources,
+ .num_resources = ARRAY_SIZE(usbh_resources),
+};
+
+void __init at91_add_device_usbh(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ usbh_data = *data;
+ platform_device_register(&at91_usbh_device);
+}
+#else
+void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_USB_GADGET_AT91
+static struct at91_udc_data udc_data;
+
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_UDP,
+ .end = AT91SAM9263_BASE_UDP + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_UDP,
+ .end = AT91SAM9263_ID_UDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_udc_device = {
+ .name = "at91_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &udc_data,
+ },
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+};
+
+void __init at91_add_device_udc(struct at91_udc_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->vbus_pin) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ udc_data = *data;
+ platform_device_register(&at91_udc_device);
+}
+#else
+void __init at91_add_device_udc(struct at91_udc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_EMAC,
+ .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_EMAC,
+ .end = AT91SAM9263_ID_EMAC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_eth_device = {
+ .name = "macb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &eth_data,
+ },
+ .resource = eth_resources,
+ .num_resources = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->phy_irq_pin) {
+ at91_set_gpio_input(data->phy_irq_pin, 0);
+ at91_set_deglitch(data->phy_irq_pin, 1);
+ }
+
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */
+ at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */
+
+ if (!data->is_rmii) {
+ at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
+ }
+
+ eth_data = *data;
+ platform_device_register(&at91sam9263_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_MCI0,
+ .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_MCI0,
+ .end = AT91SAM9263_ID_MCI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_mmc0_device = {
+ .name = "at91_mci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc0_data,
+ },
+ .resource = mmc0_resources,
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_MCI1,
+ .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_MCI1,
+ .end = AT91SAM9263_ID_MCI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_mmc1_device = {
+ .name = "at91_mci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc1_data,
+ },
+ .resource = mmc1_resources,
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ if (mmc_id == 0) { /* MCI0 */
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA12, 0);
+
+ if (data->slot_b) {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA16, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA17, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA18, 1);
+ at91_set_A_periph(AT91_PIN_PA19, 1);
+ at91_set_A_periph(AT91_PIN_PA20, 1);
+ }
+ } else {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA0, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA3, 1);
+ at91_set_A_periph(AT91_PIN_PA4, 1);
+ at91_set_A_periph(AT91_PIN_PA5, 1);
+ }
+ }
+
+ mmc0_data = *data;
+ platform_device_register(&at91sam9263_mmc0_device);
+ } else { /* MCI1 */
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA6, 0);
+
+ if (data->slot_b) {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA21, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA22, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA23, 1);
+ at91_set_A_periph(AT91_PIN_PA24, 1);
+ at91_set_A_periph(AT91_PIN_PA25, 1);
+ }
+ } else {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA8, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ at91_set_A_periph(AT91_PIN_PA10, 1);
+ at91_set_A_periph(AT91_PIN_PA11, 1);
+ }
+ }
+
+ mmc1_data = *data;
+ platform_device_register(&at91sam9263_mmc1_device);
+ }
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * Compact Flash (PCMCIA or IDE)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \
+ defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE)
+
+static struct at91_cf_data cf0_data;
+
+static struct resource cf0_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_4,
+ .end = AT91_CHIPSELECT_4 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+ }
+};
+
+static struct platform_device cf0_device = {
+ .id = 0,
+ .dev = {
+ .platform_data = &cf0_data,
+ },
+ .resource = cf0_resources,
+ .num_resources = ARRAY_SIZE(cf0_resources),
+};
+
+static struct at91_cf_data cf1_data;
+
+static struct resource cf1_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_5,
+ .end = AT91_CHIPSELECT_5 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+ }
+};
+
+static struct platform_device cf1_device = {
+ .id = 1,
+ .dev = {
+ .platform_data = &cf1_data,
+ },
+ .resource = cf1_resources,
+ .num_resources = ARRAY_SIZE(cf1_resources),
+};
+
+void __init at91_add_device_cf(struct at91_cf_data *data)
+{
+ unsigned long ebi0_csa;
+ struct platform_device *pdev;
+
+ if (!data)
+ return;
+
+ /*
+ * assign CS4 or CS5 to SMC with Compact Flash logic support,
+ * we assume SMC timings are configured by board code,
+ * except True IDE where timings are controlled by driver
+ */
+ ebi0_csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+ switch (data->chipselect) {
+ case 4:
+ at91_set_A_periph(AT91_PIN_PD6, 0); /* EBI0_NCS4/CFCS0 */
+ ebi0_csa |= AT91_MATRIX_EBI0_CS4A_SMC_CF1;
+ cf0_data = *data;
+ pdev = &cf0_device;
+ break;
+ case 5:
+ at91_set_A_periph(AT91_PIN_PD7, 0); /* EBI0_NCS5/CFCS1 */
+ ebi0_csa |= AT91_MATRIX_EBI0_CS5A_SMC_CF2;
+ cf1_data = *data;
+ pdev = &cf1_device;
+ break;
+ default:
+ printk(KERN_ERR "AT91 CF: bad chip-select requested (%u)\n",
+ data->chipselect);
+ return;
+ }
+ at91_sys_write(AT91_MATRIX_EBI0CSA, ebi0_csa);
+
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+
+ if (data->irq_pin) {
+ at91_set_gpio_input(data->irq_pin, 1);
+ at91_set_deglitch(data->irq_pin, 1);
+ }
+
+ if (data->vcc_pin)
+ /* initially off */
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ /* enable EBI controlled pins */
+ at91_set_A_periph(AT91_PIN_PD5, 1); /* NWAIT */
+ at91_set_A_periph(AT91_PIN_PD8, 0); /* CFCE1 */
+ at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */
+ at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */
+
+ pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf";
+ platform_device_register(pdev);
+}
+#else
+void __init at91_add_device_cf(struct at91_cf_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC0,
+ .end = AT91_BASE_SYS + AT91_ECC0 + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9263_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
+ at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ nand_data = *data;
+ platform_device_register(&at91sam9263_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PB4,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PB5,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9263_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9263_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_TWI,
+ .end = AT91SAM9263_BASE_TWI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_TWI,
+ .end = AT91SAM9263_ID_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PB4, 1);
+
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PB5, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9263_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_SPI0,
+ .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_SPI0,
+ .end = AT91SAM9263_ID_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_spi0_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi0_resources,
+ .num_resources = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 };
+
+static struct resource spi1_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_SPI1,
+ .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_SPI1,
+ .end = AT91SAM9263_ID_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_spi1_device = {
+ .name = "atmel_spi",
+ .id = 1,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi1_resources,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+ short enable_spi0 = 0;
+ short enable_spi1 = 0;
+
+ /* Choose SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else if (devices[i].bus_num == 0)
+ cs_pin = spi0_standard_cs[devices[i].chip_select];
+ else
+ cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+ if (devices[i].bus_num == 0)
+ enable_spi0 = 1;
+ else
+ enable_spi1 = 1;
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+
+ /* Configure SPI bus(es) */
+ if (enable_spi0) {
+ at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
+ at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
+ at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
+
+ platform_device_register(&at91sam9263_spi0_device);
+ }
+ if (enable_spi1) {
+ at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91sam9263_spi1_device);
+ }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
+static struct ac97c_platform_data ac97_data;
+
+static struct resource ac97_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_AC97C,
+ .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_AC97C,
+ .end = AT91SAM9263_ID_AC97C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_ac97_device = {
+ .name = "atmel_ac97c",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ac97_data,
+ },
+ .resource = ac97_resources,
+ .num_resources = ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */
+ at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */
+
+ /* reset */
+ if (data->reset_pin)
+ at91_set_gpio_output(data->reset_pin, 0);
+
+ ac97_data = *data;
+ platform_device_register(&at91sam9263_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * CAN Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE)
+static struct resource can_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_CAN,
+ .end = AT91SAM9263_BASE_CAN + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_CAN,
+ .end = AT91SAM9263_ID_CAN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_can_device = {
+ .name = "at91_can",
+ .id = -1,
+ .resource = can_resources,
+ .num_resources = ARRAY_SIZE(can_resources),
+};
+
+void __init at91_add_device_can(struct at91_can_data *data)
+{
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */
+ at91sam9263_can_device.dev.platform_data = data;
+
+ platform_device_register(&at91sam9263_can_device);
+}
+#else
+void __init at91_add_device_can(struct at91_can_data *data) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_LCDC_BASE,
+ .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_LCDC,
+ .end = AT91SAM9263_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
+ at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
+ at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
+ at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
+ at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
+ at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
+ at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
+ at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
+ at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
+ at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */
+ at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
+ at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
+ at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
+ at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
+ at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
+ at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */
+ at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
+ at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
+
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Image Sensor Interface
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_VIDEO_AT91_ISI) || defined(CONFIG_VIDEO_AT91_ISI_MODULE)
+
+struct resource isi_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_ISI,
+ .end = AT91SAM9263_BASE_ISI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_ISI,
+ .end = AT91SAM9263_ID_ISI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_isi_device = {
+ .name = "at91_isi",
+ .id = -1,
+ .resource = isi_resources,
+ .num_resources = ARRAY_SIZE(isi_resources),
+};
+
+void __init at91_add_device_isi(void)
+{
+ at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */
+ at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */
+ at91_set_A_periph(AT91_PIN_PE2, 0); /* ISI_D2 */
+ at91_set_A_periph(AT91_PIN_PE3, 0); /* ISI_D3 */
+ at91_set_A_periph(AT91_PIN_PE4, 0); /* ISI_D4 */
+ at91_set_A_periph(AT91_PIN_PE5, 0); /* ISI_D5 */
+ at91_set_A_periph(AT91_PIN_PE6, 0); /* ISI_D6 */
+ at91_set_A_periph(AT91_PIN_PE7, 0); /* ISI_D7 */
+ at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */
+ at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */
+ at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */
+ at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */
+ at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */
+ at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */
+ at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */
+ at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */
+}
+#else
+void __init at91_add_device_isi(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_TCB0,
+ .end = AT91SAM9263_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_TCB,
+ .end = AT91SAM9263_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91sam9263_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt0_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT0,
+ .end = AT91_BASE_SYS + AT91_RTT0 + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9263_rtt0_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt0_resources,
+ .num_resources = ARRAY_SIZE(rtt0_resources),
+};
+
+static struct resource rtt1_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT1,
+ .end = AT91_BASE_SYS + AT91_RTT1 + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9263_rtt1_device = {
+ .name = "at91_rtt",
+ .id = 1,
+ .resource = rtt1_resources,
+ .num_resources = ARRAY_SIZE(rtt1_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91sam9263_rtt0_device);
+ platform_device_register(&at91sam9263_rtt1_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91sam9263_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91sam9263_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_PWMC,
+ .end = AT91SAM9263_BASE_PWMC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_PWMC,
+ .end = AT91SAM9263_ID_PWMC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_pwm0_device = {
+ .name = "atmel_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_mask,
+ },
+ .resource = pwm_resources,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+ if (mask & (1 << AT91_PWM0))
+ at91_set_B_periph(AT91_PIN_PB7, 1); /* enable PWM0 */
+
+ if (mask & (1 << AT91_PWM1))
+ at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */
+
+ if (mask & (1 << AT91_PWM2))
+ at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */
+
+ if (mask & (1 << AT91_PWM3))
+ at91_set_B_periph(AT91_PIN_PB29, 1); /* enable PWM3 */
+
+ pwm_mask = mask;
+
+ platform_device_register(&at91sam9263_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_SSC0,
+ .end = AT91SAM9263_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_SSC0,
+ .end = AT91SAM9263_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_B_periph(AT91_PIN_PB0, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_B_periph(AT91_PIN_PB1, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_B_periph(AT91_PIN_PB2, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_B_periph(AT91_PIN_PB3, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_B_periph(AT91_PIN_PB4, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_B_periph(AT91_PIN_PB5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_SSC1,
+ .end = AT91SAM9263_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_SSC1,
+ .end = AT91SAM9263_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9263_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PB6, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PB7, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PB8, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PB9, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PB10, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PB11, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91SAM9263_ID_SSC0:
+ pdev = &at91sam9263_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91SAM9263_ID_SSC1:
+ pdev = &at91sam9263_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9263_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_US0,
+ .end = AT91SAM9263_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_US0,
+ .end = AT91SAM9263_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9263_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_US1,
+ .end = AT91SAM9263_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_US1,
+ .end = AT91SAM9263_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9263_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91SAM9263_BASE_US2,
+ .end = AT91SAM9263_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9263_ID_US2,
+ .end = AT91SAM9263_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9263_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9263_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91SAM9263_ID_US0:
+ pdev = &at91sam9263_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91SAM9263_ID_US1:
+ pdev = &at91sam9263_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91SAM9263_ID_US2:
+ pdev = &at91sam9263_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91sam9263_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
new file mode 100644
index 00000000..4ba85499
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -0,0 +1,188 @@
+/*
+ * at91sam926x_time.c - Periodic Interval Timer (PIT) for at91sam926x
+ *
+ * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
+ * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
+ * Converted to ClockSource/ClockEvents by David Brownell.
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/at91_pit.h>
+
+
+#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV)
+#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20)
+
+static u32 pit_cycle; /* write-once */
+static u32 pit_cnt; /* access only w/system irq blocked */
+
+
+/*
+ * Clocksource: just a monotonic counter of MCK/16 cycles.
+ * We don't care whether or not PIT irqs are enabled.
+ */
+static cycle_t read_pit_clk(struct clocksource *cs)
+{
+ unsigned long flags;
+ u32 elapsed;
+ u32 t;
+
+ raw_local_irq_save(flags);
+ elapsed = pit_cnt;
+ t = at91_sys_read(AT91_PIT_PIIR);
+ raw_local_irq_restore(flags);
+
+ elapsed += PIT_PICNT(t) * pit_cycle;
+ elapsed += PIT_CPIV(t);
+ return elapsed;
+}
+
+static struct clocksource pit_clk = {
+ .name = "pit",
+ .rating = 175,
+ .read = read_pit_clk,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+
+/*
+ * Clockevent device: interrupts every 1/HZ (== pit_cycles * MCK/16)
+ */
+static void
+pit_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* update clocksource counter */
+ pit_cnt += pit_cycle * PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN
+ | AT91_PIT_PITIEN);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ BUG();
+ /* FALLTHROUGH */
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ /* disable irq, leaving the clocksource active */
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device pit_clkevt = {
+ .name = "pit",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 32,
+ .rating = 100,
+ .set_mode = pit_clkevt_mode,
+};
+
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id)
+{
+ /*
+ * irqs should be disabled here, but as the irq is shared they are only
+ * guaranteed to be off if the timer irq is registered first.
+ */
+ WARN_ON_ONCE(!irqs_disabled());
+
+ /* The PIT interrupt may be disabled, and is shared */
+ if ((pit_clkevt.mode == CLOCK_EVT_MODE_PERIODIC)
+ && (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS)) {
+ unsigned nr_ticks;
+
+ /* Get number of ticks performed before irq, and ack it */
+ nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR));
+ do {
+ pit_cnt += pit_cycle;
+ pit_clkevt.event_handler(&pit_clkevt);
+ nr_ticks--;
+ } while (nr_ticks);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static struct irqaction at91sam926x_pit_irq = {
+ .name = "at91_tick",
+ .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = at91sam926x_pit_interrupt
+};
+
+static void at91sam926x_pit_reset(void)
+{
+ /* Disable timer and irqs */
+ at91_sys_write(AT91_PIT_MR, 0);
+
+ /* Clear any pending interrupts, wait for PIT to stop counting */
+ while (PIT_CPIV(at91_sys_read(AT91_PIT_PIVR)) != 0)
+ cpu_relax();
+
+ /* Start PIT but don't enable IRQ */
+ at91_sys_write(AT91_PIT_MR, (pit_cycle - 1) | AT91_PIT_PITEN);
+}
+
+/*
+ * Set up both clocksource and clockevent support.
+ */
+static void __init at91sam926x_pit_init(void)
+{
+ unsigned long pit_rate;
+ unsigned bits;
+
+ /*
+ * Use our actual MCK to figure out how many MCK/16 ticks per
+ * 1/HZ period (instead of a compile-time constant LATCH).
+ */
+ pit_rate = clk_get_rate(clk_get(NULL, "mck")) / 16;
+ pit_cycle = (pit_rate + HZ/2) / HZ;
+ WARN_ON(((pit_cycle - 1) & ~AT91_PIT_PIV) != 0);
+
+ /* Initialize and enable the timer */
+ at91sam926x_pit_reset();
+
+ /*
+ * Register clocksource. The high order bits of PIV are unused,
+ * so this isn't a 32-bit counter unless we get clockevent irqs.
+ */
+ bits = 12 /* PICNT */ + ilog2(pit_cycle) /* PIV */;
+ pit_clk.mask = CLOCKSOURCE_MASK(bits);
+ clocksource_register_hz(&pit_clk, pit_rate);
+
+ /* Set up irq handler */
+ setup_irq(AT91_ID_SYS, &at91sam926x_pit_irq);
+
+ /* Set up and register clockevents */
+ pit_clkevt.mult = div_sc(pit_rate, NSEC_PER_SEC, pit_clkevt.shift);
+ pit_clkevt.cpumask = cpumask_of(0);
+ clockevents_register_device(&pit_clkevt);
+}
+
+static void at91sam926x_pit_suspend(void)
+{
+ /* Disable timer */
+ at91_sys_write(AT91_PIT_MR, 0);
+}
+
+struct sys_timer at91sam926x_timer = {
+ .init = at91sam926x_pit_init,
+ .suspend = at91sam926x_pit_suspend,
+ .resume = at91sam926x_pit_reset,
+};
diff --git a/arch/arm/mach-at91/at91sam9_alt_reset.S b/arch/arm/mach-at91/at91sam9_alt_reset.S
new file mode 100644
index 00000000..e0256deb
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9_alt_reset.S
@@ -0,0 +1,48 @@
+/*
+ * reset AT91SAM9G20 as per errata
+ *
+ * (C) BitBox Ltd 2010
+ *
+ * unless the SDRAM is cleanly shutdown before we hit the
+ * reset register it can be left driving the data bus and
+ * killing the chance of a subsequent boot from NAND
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <mach/at91sam9_sdramc.h>
+#include <mach/at91_rstc.h>
+
+ .arm
+
+ .globl at91sam9_alt_reset
+
+at91sam9_alt_reset: mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #CR_I
+ mcr p15, 0, r0, c1, c0, 0 @ enable I-cache
+
+ ldr r0, .at91_va_base_sdramc @ preload constants
+ ldr r1, .at91_va_base_rstc_cr
+
+ mov r2, #1
+ mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN
+ ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST
+
+ .balign 32 @ align to cache line
+
+ str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access
+ str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM
+ str r4, [r1] @ reset processor
+
+ b .
+
+.at91_va_base_sdramc:
+ .word AT91_VA_BASE_SYS + AT91_SDRAMC0
+.at91_va_base_rstc_cr:
+ .word AT91_VA_BASE_SYS + AT91_RSTC_CR
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
new file mode 100644
index 00000000..11e21412
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -0,0 +1,406 @@
+/*
+ * Chip-specific setup code for the AT91SAM9G45 family
+ *
+ * Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/at91sam9g45.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9g45_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = AT91_IO_VIRT_BASE - AT91SAM9G45_SRAM_SIZE,
+ .pfn = __phys_to_pfn(AT91SAM9G45_SRAM_BASE),
+ .length = AT91SAM9G45_SRAM_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+ .name = "pioC_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_PIOC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioDE_clk = {
+ .name = "pioDE_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_PIODE,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+ .name = "usart3_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_US3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc0_clk = {
+ .name = "mci0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_MCI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+ .name = "twi0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_TWI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+ .name = "twi1_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_TWI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi0_clk = {
+ .name = "spi0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_SPI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi1_clk = {
+ .name = "spi1_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_SPI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tcb0_clk = {
+ .name = "tcb0_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_TCB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+ .name = "pwm_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_PWMC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tsc_clk = {
+ .name = "tsc_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_TSC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_DMA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk uhphs_clk = {
+ .name = "uhphs_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_UHPHS,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+ .name = "lcdc_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_LCDC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+ .name = "ac97_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_AC97C,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk macb_clk = {
+ .name = "macb_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_EMAC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk isi_clk = {
+ .name = "isi_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_ISI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+ .name = "udphs_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_UDPHS,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc1_clk = {
+ .name = "mci1_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_MCI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+/* Video decoder clock - Only for sam9m10/sam9m11 */
+static struct clk vdec_clk = {
+ .name = "vdec_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_VDEC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioC_clk,
+ &pioDE_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &usart3_clk,
+ &mmc0_clk,
+ &twi0_clk,
+ &twi1_clk,
+ &spi0_clk,
+ &spi1_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &tcb0_clk,
+ &pwm_clk,
+ &tsc_clk,
+ &dma_clk,
+ &uhphs_clk,
+ &lcdc_clk,
+ &ac97_clk,
+ &macb_clk,
+ &isi_clk,
+ &udphs_clk,
+ &mmc1_clk,
+ // irq0
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ /* One additional fake clock for ohci */
+ CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
+ CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
+ CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+ CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
+ CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+ CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+
+static void __init at91sam9g45_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11())
+ clk_register(&vdec_clk);
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9g45_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9g45_gpio[] = {
+ {
+ .id = AT91SAM9G45_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91SAM9G45_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91SAM9G45_ID_PIOC,
+ .offset = AT91_PIOC,
+ .clock = &pioC_clk,
+ }, {
+ .id = AT91SAM9G45_ID_PIODE,
+ .offset = AT91_PIOD,
+ .clock = &pioDE_clk,
+ }, {
+ .id = AT91SAM9G45_ID_PIODE,
+ .offset = AT91_PIOE,
+ .clock = &pioDE_clk,
+ }
+};
+
+static void at91sam9g45_reset(void)
+{
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
+}
+
+static void at91sam9g45_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91SAM9G45 processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9g45_map_io(void)
+{
+ /* Map peripherals */
+ iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
+}
+
+void __init at91sam9g45_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91sam9g45_reset;
+ pm_power_off = at91sam9g45_poweroff;
+ at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91sam9g45_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9g45_gpio, 5);
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C */
+ 1, /* Parallel IO Controller D and E */
+ 0,
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 5, /* USART 3 */
+ 0, /* Multimedia Card Interface 0 */
+ 6, /* Two-Wire Interface 0 */
+ 6, /* Two-Wire Interface 1 */
+ 5, /* Serial Peripheral Interface 0 */
+ 5, /* Serial Peripheral Interface 1 */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */
+ 0, /* Pulse Width Modulation Controller */
+ 0, /* Touch Screen Controller */
+ 0, /* DMA Controller */
+ 2, /* USB Host High Speed port */
+ 3, /* LDC Controller */
+ 5, /* AC97 Controller */
+ 3, /* Ethernet */
+ 0, /* Image Sensor Interface */
+ 2, /* USB Device High speed port */
+ 0,
+ 0, /* Multimedia Card Interface 1 */
+ 0,
+ 0, /* Advanced Interrupt Controller (IRQ0) */
+};
+
+void __init at91sam9g45_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91sam9g45_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
new file mode 100644
index 00000000..600bffb0
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -0,0 +1,1591 @@
+/*
+ * On-Chip devices setup code for the AT91SAM9G45 family
+ *
+ * Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+#include <linux/atmel-mci.h>
+
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9g45.h>
+#include <mach/at91sam9g45_matrix.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at_hdmac.h>
+#include <mach/atmel-mci.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * HDMAC - AHB DMA Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
+static u64 hdmac_dmamask = DMA_BIT_MASK(32);
+
+static struct at_dma_platform_data atdma_pdata = {
+ .nr_channels = 8,
+};
+
+static struct resource hdmac_resources[] = {
+ [0] = {
+ .start = AT91_BASE_SYS + AT91_DMA,
+ .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_DMA,
+ .end = AT91SAM9G45_ID_DMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at_hdmac_device = {
+ .name = "at_hdmac",
+ .id = -1,
+ .dev = {
+ .dma_mask = &hdmac_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &atdma_pdata,
+ },
+ .resource = hdmac_resources,
+ .num_resources = ARRAY_SIZE(hdmac_resources),
+};
+
+void __init at91_add_device_hdmac(void)
+{
+ dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
+ dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
+ platform_device_register(&at_hdmac_device);
+}
+#else
+void __init at91_add_device_hdmac(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Host (OHCI)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static u64 ohci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ohci_data;
+
+static struct resource usbh_ohci_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_OHCI_BASE,
+ .end = AT91SAM9G45_OHCI_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_UHPHS,
+ .end = AT91SAM9G45_ID_UHPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_usbh_ohci_device = {
+ .name = "at91_ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_ohci_data,
+ },
+ .resource = usbh_ohci_resources,
+ .num_resources = ARRAY_SIZE(usbh_ohci_resources),
+};
+
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ usbh_ohci_data = *data;
+ platform_device_register(&at91_usbh_ohci_device);
+}
+#else
+void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB Host HS (EHCI)
+ * Needs an OHCI host for low and full speed management
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ehci_data;
+
+static struct resource usbh_ehci_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_EHCI_BASE,
+ .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_UHPHS,
+ .end = AT91SAM9G45_ID_UHPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_usbh_ehci_device = {
+ .name = "atmel-ehci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &usbh_ehci_data,
+ },
+ .resource = usbh_ehci_resources,
+ .num_resources = ARRAY_SIZE(usbh_ehci_resources),
+};
+
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
+{
+ int i;
+
+ if (!data)
+ return;
+
+ /* Enable VBus control for UHP ports */
+ for (i = 0; i < data->ports; i++) {
+ if (data->vbus_pin[i])
+ at91_set_gpio_output(data->vbus_pin[i], 0);
+ }
+
+ usbh_ehci_data = *data;
+ platform_device_register(&at91_usbh_ehci_device);
+}
+#else
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+static struct resource usba_udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_UDPHS_FIFO,
+ .end = AT91SAM9G45_UDPHS_FIFO + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_BASE_UDPHS,
+ .end = AT91SAM9G45_BASE_UDPHS + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91SAM9G45_ID_UDPHS,
+ .end = AT91SAM9G45_ID_UDPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
+ [idx] = { \
+ .name = nam, \
+ .index = idx, \
+ .fifo_size = maxpkt, \
+ .nr_banks = maxbk, \
+ .can_dma = dma, \
+ .can_isoc = isoc, \
+ }
+
+static struct usba_ep_data usba_udc_ep[] __initdata = {
+ EP("ep0", 0, 64, 1, 0, 0),
+ EP("ep1", 1, 1024, 2, 1, 1),
+ EP("ep2", 2, 1024, 2, 1, 1),
+ EP("ep3", 3, 1024, 3, 1, 0),
+ EP("ep4", 4, 1024, 3, 1, 0),
+ EP("ep5", 5, 1024, 3, 1, 1),
+ EP("ep6", 6, 1024, 3, 1, 1),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+ struct usba_platform_data pdata;
+ struct usba_ep_data ep[7];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+ .name = "atmel_usba_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &usba_udc_data.pdata,
+ },
+ .resource = usba_udc_resources,
+ .num_resources = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+ usba_udc_data.pdata.vbus_pin = -EINVAL;
+ usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+ memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
+
+ if (data && data->vbus_pin > 0) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
+static u64 eth_dmamask = DMA_BIT_MASK(32);
+static struct at91_eth_data eth_data;
+
+static struct resource eth_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_EMAC,
+ .end = AT91SAM9G45_BASE_EMAC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_EMAC,
+ .end = AT91SAM9G45_ID_EMAC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_eth_device = {
+ .name = "macb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &eth_data,
+ },
+ .resource = eth_resources,
+ .num_resources = ARRAY_SIZE(eth_resources),
+};
+
+void __init at91_add_device_eth(struct at91_eth_data *data)
+{
+ if (!data)
+ return;
+
+ if (data->phy_irq_pin) {
+ at91_set_gpio_input(data->phy_irq_pin, 0);
+ at91_set_deglitch(data->phy_irq_pin, 1);
+ }
+
+ /* Pins used for MII and RMII */
+ at91_set_A_periph(AT91_PIN_PA17, 0); /* ETXCK_EREFCK */
+ at91_set_A_periph(AT91_PIN_PA15, 0); /* ERXDV */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */
+ at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */
+ at91_set_A_periph(AT91_PIN_PA16, 0); /* ERXER */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* ETXEN */
+ at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX0 */
+ at91_set_A_periph(AT91_PIN_PA11, 0); /* ETX1 */
+ at91_set_A_periph(AT91_PIN_PA19, 0); /* EMDIO */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* EMDC */
+
+ if (!data->is_rmii) {
+ at91_set_B_periph(AT91_PIN_PA29, 0); /* ECRS */
+ at91_set_B_periph(AT91_PIN_PA30, 0); /* ECOL */
+ at91_set_B_periph(AT91_PIN_PA8, 0); /* ERX2 */
+ at91_set_B_periph(AT91_PIN_PA9, 0); /* ERX3 */
+ at91_set_B_periph(AT91_PIN_PA28, 0); /* ERXCK */
+ at91_set_B_periph(AT91_PIN_PA6, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA7, 0); /* ETX3 */
+ at91_set_B_periph(AT91_PIN_PA27, 0); /* ETXER */
+ }
+
+ eth_data = *data;
+ platform_device_register(&at91sam9g45_eth_device);
+}
+#else
+void __init at91_add_device_eth(struct at91_eth_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct mci_platform_data mmc0_data, mmc1_data;
+
+static struct resource mmc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_MCI0,
+ .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_MCI0,
+ .end = AT91SAM9G45_ID_MCI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_mmc0_device = {
+ .name = "atmel_mci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc0_data,
+ },
+ .resource = mmc0_resources,
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+};
+
+static struct resource mmc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_MCI1,
+ .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_MCI1,
+ .end = AT91SAM9G45_ID_MCI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_mmc1_device = {
+ .name = "atmel_mci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc1_data,
+ },
+ .resource = mmc1_resources,
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+};
+
+/* Consider only one slot : slot 0 */
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data)
+{
+
+ if (!data)
+ return;
+
+ /* Must have at least one usable slot */
+ if (!data->slot[0].bus_width)
+ return;
+
+#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
+ {
+ struct at_dma_slave *atslave;
+ struct mci_dma_data *alt_atslave;
+
+ alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL);
+ atslave = &alt_atslave->sdata;
+
+ /* DMA slave channel configuration */
+ atslave->dma_dev = &at_hdmac_device.dev;
+ atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT;
+ atslave->cfg = ATC_FIFOCFG_HALFFIFO
+ | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW;
+ atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16;
+ if (mmc_id == 0) /* MCI0 */
+ atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0)
+ | ATC_DST_PER(AT_DMA_ID_MCI0);
+
+ else /* MCI1 */
+ atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1)
+ | ATC_DST_PER(AT_DMA_ID_MCI1);
+
+ data->dma_slave = alt_atslave;
+ }
+#endif
+
+
+ /* input/irq */
+ if (data->slot[0].detect_pin) {
+ at91_set_gpio_input(data->slot[0].detect_pin, 1);
+ at91_set_deglitch(data->slot[0].detect_pin, 1);
+ }
+ if (data->slot[0].wp_pin)
+ at91_set_gpio_input(data->slot[0].wp_pin, 1);
+
+ if (mmc_id == 0) { /* MCI0 */
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA0, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
+ at91_set_A_periph(AT91_PIN_PA2, 1);
+ if (data->slot[0].bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA3, 1);
+ at91_set_A_periph(AT91_PIN_PA4, 1);
+ at91_set_A_periph(AT91_PIN_PA5, 1);
+ if (data->slot[0].bus_width == 8) {
+ at91_set_A_periph(AT91_PIN_PA6, 1);
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+ at91_set_A_periph(AT91_PIN_PA8, 1);
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ }
+ }
+
+ mmc0_data = *data;
+ platform_device_register(&at91sam9g45_mmc0_device);
+
+ } else { /* MCI1 */
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA31, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA22, 1);
+
+ /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */
+ at91_set_A_periph(AT91_PIN_PA23, 1);
+ if (data->slot[0].bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA24, 1);
+ at91_set_A_periph(AT91_PIN_PA25, 1);
+ at91_set_A_periph(AT91_PIN_PA26, 1);
+ if (data->slot[0].bus_width == 8) {
+ at91_set_A_periph(AT91_PIN_PA27, 1);
+ at91_set_A_periph(AT91_PIN_PA28, 1);
+ at91_set_A_periph(AT91_PIN_PA29, 1);
+ at91_set_A_periph(AT91_PIN_PA30, 1);
+ }
+ }
+
+ mmc1_data = *data;
+ platform_device_register(&at91sam9g45_mmc1_device);
+
+ }
+}
+#else
+void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9g45_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ nand_data = *data;
+ platform_device_register(&at91sam9g45_nand_device);
+}
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+static struct i2c_gpio_platform_data pdata_i2c0 = {
+ .sda_pin = AT91_PIN_PA20,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA21,
+ .scl_is_open_drain = 1,
+ .udelay = 5, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9g45_twi0_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev.platform_data = &pdata_i2c0,
+};
+
+static struct i2c_gpio_platform_data pdata_i2c1 = {
+ .sda_pin = AT91_PIN_PB10,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PB11,
+ .scl_is_open_drain = 1,
+ .udelay = 5, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9g45_twi1_device = {
+ .name = "i2c-gpio",
+ .id = 1,
+ .dev.platform_data = &pdata_i2c1,
+};
+
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
+{
+ i2c_register_board_info(i2c_id, devices, nr_devices);
+
+ if (i2c_id == 0) {
+ at91_set_GPIO_periph(AT91_PIN_PA20, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA20, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA21, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA21, 1);
+
+ platform_device_register(&at91sam9g45_twi0_device);
+ } else {
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PB10, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PB11, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PB11, 1);
+
+ platform_device_register(&at91sam9g45_twi1_device);
+ }
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+static struct resource twi0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_TWI0,
+ .end = AT91SAM9G45_BASE_TWI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_TWI0,
+ .end = AT91SAM9G45_ID_TWI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_twi0_device = {
+ .name = "at91_i2c",
+ .id = 0,
+ .resource = twi0_resources,
+ .num_resources = ARRAY_SIZE(twi0_resources),
+};
+
+static struct resource twi1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_TWI1,
+ .end = AT91SAM9G45_BASE_TWI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_TWI1,
+ .end = AT91SAM9G45_ID_TWI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_twi1_device = {
+ .name = "at91_i2c",
+ .id = 1,
+ .resource = twi1_resources,
+ .num_resources = ARRAY_SIZE(twi1_resources),
+};
+
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices)
+{
+ i2c_register_board_info(i2c_id, devices, nr_devices);
+
+ /* pins used for TWI interface */
+ if (i2c_id == 0) {
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PA20, 1);
+
+ at91_set_A_periph(AT91_PIN_PA21, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PA21, 1);
+
+ platform_device_register(&at91sam9g45_twi0_device);
+ } else {
+ at91_set_A_periph(AT91_PIN_PB10, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PB10, 1);
+
+ at91_set_A_periph(AT91_PIN_PB11, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PB11, 1);
+
+ platform_device_register(&at91sam9g45_twi1_device);
+ }
+}
+#else
+void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_SPI0,
+ .end = AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_SPI0,
+ .end = AT91SAM9G45_ID_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_spi0_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi0_resources,
+ .num_resources = ARRAY_SIZE(spi0_resources),
+};
+
+static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
+
+static struct resource spi1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_SPI1,
+ .end = AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_SPI1,
+ .end = AT91SAM9G45_ID_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_spi1_device = {
+ .name = "atmel_spi",
+ .id = 1,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi1_resources,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+};
+
+static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+ short enable_spi0 = 0;
+ short enable_spi1 = 0;
+
+ /* Choose SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else if (devices[i].bus_num == 0)
+ cs_pin = spi0_standard_cs[devices[i].chip_select];
+ else
+ cs_pin = spi1_standard_cs[devices[i].chip_select];
+
+ if (devices[i].bus_num == 0)
+ enable_spi0 = 1;
+ else
+ enable_spi1 = 1;
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+
+ /* Configure SPI bus(es) */
+ if (enable_spi0) {
+ at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI0_MISO */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI0_MOSI */
+ at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI0_SPCK */
+
+ platform_device_register(&at91sam9g45_spi0_device);
+ }
+ if (enable_spi1) {
+ at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_MISO */
+ at91_set_A_periph(AT91_PIN_PB15, 0); /* SPI1_MOSI */
+ at91_set_A_periph(AT91_PIN_PB16, 0); /* SPI1_SPCK */
+
+ platform_device_register(&at91sam9g45_spi1_device);
+ }
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
+static struct ac97c_platform_data ac97_data;
+
+static struct resource ac97_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_AC97C,
+ .end = AT91SAM9G45_BASE_AC97C + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_AC97C,
+ .end = AT91SAM9G45_ID_AC97C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_ac97_device = {
+ .name = "atmel_ac97c",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ac97_data,
+ },
+ .resource = ac97_resources,
+ .num_resources = ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PD8, 0); /* AC97FS */
+ at91_set_A_periph(AT91_PIN_PD9, 0); /* AC97CK */
+ at91_set_A_periph(AT91_PIN_PD7, 0); /* AC97TX */
+ at91_set_A_periph(AT91_PIN_PD6, 0); /* AC97RX */
+
+ /* reset */
+ if (data->reset_pin)
+ at91_set_gpio_output(data->reset_pin, 0);
+
+ ac97_data = *data;
+ platform_device_register(&at91sam9g45_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_LCDC_BASE,
+ .end = AT91SAM9G45_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_LCDC,
+ .end = AT91SAM9G45_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PE0, 0); /* LCDDPWR */
+
+ at91_set_A_periph(AT91_PIN_PE2, 0); /* LCDCC */
+ at91_set_A_periph(AT91_PIN_PE3, 0); /* LCDVSYNC */
+ at91_set_A_periph(AT91_PIN_PE4, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PE5, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PE6, 0); /* LCDDEN */
+ at91_set_A_periph(AT91_PIN_PE7, 0); /* LCDD0 */
+ at91_set_A_periph(AT91_PIN_PE8, 0); /* LCDD1 */
+ at91_set_A_periph(AT91_PIN_PE9, 0); /* LCDD2 */
+ at91_set_A_periph(AT91_PIN_PE10, 0); /* LCDD3 */
+ at91_set_A_periph(AT91_PIN_PE11, 0); /* LCDD4 */
+ at91_set_A_periph(AT91_PIN_PE12, 0); /* LCDD5 */
+ at91_set_A_periph(AT91_PIN_PE13, 0); /* LCDD6 */
+ at91_set_A_periph(AT91_PIN_PE14, 0); /* LCDD7 */
+ at91_set_A_periph(AT91_PIN_PE15, 0); /* LCDD8 */
+ at91_set_A_periph(AT91_PIN_PE16, 0); /* LCDD9 */
+ at91_set_A_periph(AT91_PIN_PE17, 0); /* LCDD10 */
+ at91_set_A_periph(AT91_PIN_PE18, 0); /* LCDD11 */
+ at91_set_A_periph(AT91_PIN_PE19, 0); /* LCDD12 */
+ at91_set_A_periph(AT91_PIN_PE20, 0); /* LCDD13 */
+ at91_set_A_periph(AT91_PIN_PE21, 0); /* LCDD14 */
+ at91_set_A_periph(AT91_PIN_PE22, 0); /* LCDD15 */
+ at91_set_A_periph(AT91_PIN_PE23, 0); /* LCDD16 */
+ at91_set_A_periph(AT91_PIN_PE24, 0); /* LCDD17 */
+ at91_set_A_periph(AT91_PIN_PE25, 0); /* LCDD18 */
+ at91_set_A_periph(AT91_PIN_PE26, 0); /* LCDD19 */
+ at91_set_A_periph(AT91_PIN_PE27, 0); /* LCDD20 */
+ at91_set_A_periph(AT91_PIN_PE28, 0); /* LCDD21 */
+ at91_set_A_periph(AT91_PIN_PE29, 0); /* LCDD22 */
+ at91_set_A_periph(AT91_PIN_PE30, 0); /* LCDD23 */
+
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+static struct resource tcb0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_TCB0,
+ .end = AT91SAM9G45_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_TCB,
+ .end = AT91SAM9G45_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_tcb0_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb0_resources,
+ .num_resources = ARRAY_SIZE(tcb0_resources),
+};
+
+/* TCB1 begins with TC3 */
+static struct resource tcb1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_TCB1,
+ .end = AT91SAM9G45_BASE_TCB1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_TCB,
+ .end = AT91SAM9G45_ID_TCB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_tcb1_device = {
+ .name = "atmel_tcb",
+ .id = 1,
+ .resource = tcb1_resources,
+ .num_resources = ARRAY_SIZE(tcb1_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91sam9g45_tcb0_device);
+ platform_device_register(&at91sam9g45_tcb1_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
+static struct platform_device at91sam9g45_rtc_device = {
+ .name = "at91_rtc",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_rtc(void)
+{
+ platform_device_register(&at91sam9g45_rtc_device);
+}
+#else
+static void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Touchscreen
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
+
+static struct resource tsadcc_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_TSC,
+ .end = AT91SAM9G45_BASE_TSC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_TSC,
+ .end = AT91SAM9G45_ID_TSC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device at91sam9g45_tsadcc_device = {
+ .name = "atmel_tsadcc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &tsadcc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tsadcc_data,
+ },
+ .resource = tsadcc_resources,
+ .num_resources = ARRAY_SIZE(tsadcc_resources),
+};
+
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_gpio_input(AT91_PIN_PD20, 0); /* AD0_XR */
+ at91_set_gpio_input(AT91_PIN_PD21, 0); /* AD1_XL */
+ at91_set_gpio_input(AT91_PIN_PD22, 0); /* AD2_YT */
+ at91_set_gpio_input(AT91_PIN_PD23, 0); /* AD3_TB */
+
+ tsadcc_data = *data;
+ platform_device_register(&at91sam9g45_tsadcc_device);
+}
+#else
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9g45_rtt_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91sam9g45_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91sam9g45_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91sam9g45_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM) || defined(CONFIG_ATMEL_PWM_MODULE)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_PWMC,
+ .end = AT91SAM9G45_BASE_PWMC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_PWMC,
+ .end = AT91SAM9G45_ID_PWMC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_pwm0_device = {
+ .name = "atmel_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_mask,
+ },
+ .resource = pwm_resources,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+ if (mask & (1 << AT91_PWM0))
+ at91_set_B_periph(AT91_PIN_PD24, 1); /* enable PWM0 */
+
+ if (mask & (1 << AT91_PWM1))
+ at91_set_B_periph(AT91_PIN_PD31, 1); /* enable PWM1 */
+
+ if (mask & (1 << AT91_PWM2))
+ at91_set_B_periph(AT91_PIN_PD26, 1); /* enable PWM2 */
+
+ if (mask & (1 << AT91_PWM3))
+ at91_set_B_periph(AT91_PIN_PD0, 1); /* enable PWM3 */
+
+ pwm_mask = mask;
+
+ platform_device_register(&at91sam9g45_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_SSC0,
+ .end = AT91SAM9G45_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_SSC0,
+ .end = AT91SAM9G45_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PD1, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PD0, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PD2, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PD3, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PD4, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PD5, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_SSC1,
+ .end = AT91SAM9G45_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_SSC1,
+ .end = AT91SAM9G45_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PD14, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PD12, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PD10, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PD11, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_A_periph(AT91_PIN_PD13, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_A_periph(AT91_PIN_PD15, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91SAM9G45_ID_SSC0:
+ pdev = &at91sam9g45_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91SAM9G45_ID_SSC1:
+ pdev = &at91sam9g45_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0,
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PB12, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PB13, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_US0,
+ .end = AT91SAM9G45_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_US0,
+ .end = AT91SAM9G45_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB19, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PB18, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PB17, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PB15, 0); /* CTS0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_US1,
+ .end = AT91SAM9G45_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_US1,
+ .end = AT91SAM9G45_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PD16, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PD17, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_US2,
+ .end = AT91SAM9G45_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_US2,
+ .end = AT91SAM9G45_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PC9, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PC11, 0); /* CTS2 */
+}
+
+static struct resource uart3_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_US3,
+ .end = AT91SAM9G45_BASE_US3 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_US3,
+ .end = AT91SAM9G45_ID_US3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart3_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9g45_uart3_device = {
+ .name = "atmel_usart",
+ .id = 4,
+ .dev = {
+ .dma_mask = &uart3_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart3_data,
+ },
+ .resource = uart3_resources,
+ .num_resources = ARRAY_SIZE(uart3_resources),
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD3 */
+ at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD3 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA23, 0); /* RTS3 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA24, 0); /* CTS3 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9g45_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91SAM9G45_ID_US0:
+ pdev = &at91sam9g45_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91SAM9G45_ID_US1:
+ pdev = &at91sam9g45_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91SAM9G45_ID_US2:
+ pdev = &at91sam9g45_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ case AT91SAM9G45_ID_US3:
+ pdev = &at91sam9g45_uart3_device;
+ configure_usart3_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_hdmac();
+ at91_add_device_rtc();
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
new file mode 100644
index 00000000..29dff18e
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -0,0 +1,383 @@
+/*
+ * arch/arm/mach-at91/at91sam9rl.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/cpu.h>
+#include <mach/at91sam9rl.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+#include "generic.h"
+#include "clock.h"
+
+static struct map_desc at91sam9rl_io_desc[] __initdata = {
+ {
+ .virtual = AT91_VA_BASE_SYS,
+ .pfn = __phys_to_pfn(AT91_BASE_SYS),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc at91sam9rl_sram_desc[] __initdata = {
+ {
+ .pfn = __phys_to_pfn(AT91SAM9RL_SRAM_BASE),
+ .type = MT_DEVICE,
+ }
+};
+
+/* --------------------------------------------------------------------
+ * Clocks
+ * -------------------------------------------------------------------- */
+
+/*
+ * The peripheral clocks.
+ */
+static struct clk pioA_clk = {
+ .name = "pioA_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_PIOA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioB_clk = {
+ .name = "pioB_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_PIOB,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioC_clk = {
+ .name = "pioC_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_PIOC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pioD_clk = {
+ .name = "pioD_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_PIOD,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart0_clk = {
+ .name = "usart0_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_US0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart1_clk = {
+ .name = "usart1_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_US1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart2_clk = {
+ .name = "usart2_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_US2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk usart3_clk = {
+ .name = "usart3_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_US3,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk mmc_clk = {
+ .name = "mci_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_MCI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi0_clk = {
+ .name = "twi0_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TWI0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk twi1_clk = {
+ .name = "twi1_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TWI1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk spi_clk = {
+ .name = "spi_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_SPI,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc0_clk = {
+ .name = "ssc0_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_SSC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ssc1_clk = {
+ .name = "ssc1_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_SSC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc0_clk = {
+ .name = "tc0_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TC0,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc1_clk = {
+ .name = "tc1_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TC1,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tc2_clk = {
+ .name = "tc2_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TC2,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk pwm_clk = {
+ .name = "pwm_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_PWMC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk tsc_clk = {
+ .name = "tsc_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_TSC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_DMA,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk udphs_clk = {
+ .name = "udphs_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_UDPHS,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk lcdc_clk = {
+ .name = "lcdc_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_LCDC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+static struct clk ac97_clk = {
+ .name = "ac97_clk",
+ .pmc_mask = 1 << AT91SAM9RL_ID_AC97C,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
+static struct clk *periph_clocks[] __initdata = {
+ &pioA_clk,
+ &pioB_clk,
+ &pioC_clk,
+ &pioD_clk,
+ &usart0_clk,
+ &usart1_clk,
+ &usart2_clk,
+ &usart3_clk,
+ &mmc_clk,
+ &twi0_clk,
+ &twi1_clk,
+ &spi_clk,
+ &ssc0_clk,
+ &ssc1_clk,
+ &tc0_clk,
+ &tc1_clk,
+ &tc2_clk,
+ &pwm_clk,
+ &tsc_clk,
+ &dma_clk,
+ &udphs_clk,
+ &lcdc_clk,
+ &ac97_clk,
+ // irq0
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+ CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+ CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+};
+
+/*
+ * The two programmable clocks.
+ * You must configure pin multiplexing to bring these signals out.
+ */
+static struct clk pck0 = {
+ .name = "pck0",
+ .pmc_mask = AT91_PMC_PCK0,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 0,
+};
+static struct clk pck1 = {
+ .name = "pck1",
+ .pmc_mask = AT91_PMC_PCK1,
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .id = 1,
+};
+
+static void __init at91sam9rl_register_clocks(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
+ clk_register(periph_clocks[i]);
+
+ clkdev_add_table(periph_clocks_lookups,
+ ARRAY_SIZE(periph_clocks_lookups));
+ clkdev_add_table(usart_clocks_lookups,
+ ARRAY_SIZE(usart_clocks_lookups));
+
+ clk_register(&pck0);
+ clk_register(&pck1);
+}
+
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9rl_set_console_clock(int id)
+{
+ if (id >= ARRAY_SIZE(usart_clocks_lookups))
+ return;
+
+ console_clock_lookup.con_id = "usart";
+ console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+ clkdev_add(&console_clock_lookup);
+}
+
+/* --------------------------------------------------------------------
+ * GPIO
+ * -------------------------------------------------------------------- */
+
+static struct at91_gpio_bank at91sam9rl_gpio[] = {
+ {
+ .id = AT91SAM9RL_ID_PIOA,
+ .offset = AT91_PIOA,
+ .clock = &pioA_clk,
+ }, {
+ .id = AT91SAM9RL_ID_PIOB,
+ .offset = AT91_PIOB,
+ .clock = &pioB_clk,
+ }, {
+ .id = AT91SAM9RL_ID_PIOC,
+ .offset = AT91_PIOC,
+ .clock = &pioC_clk,
+ }, {
+ .id = AT91SAM9RL_ID_PIOD,
+ .offset = AT91_PIOD,
+ .clock = &pioD_clk,
+ }
+};
+
+static void at91sam9rl_poweroff(void)
+{
+ at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW);
+}
+
+
+/* --------------------------------------------------------------------
+ * AT91SAM9RL processor initialization
+ * -------------------------------------------------------------------- */
+
+void __init at91sam9rl_map_io(void)
+{
+ unsigned long cidr, sram_size;
+
+ /* Map peripherals */
+ iotable_init(at91sam9rl_io_desc, ARRAY_SIZE(at91sam9rl_io_desc));
+
+ cidr = at91_sys_read(AT91_DBGU_CIDR);
+
+ switch (cidr & AT91_CIDR_SRAMSIZ) {
+ case AT91_CIDR_SRAMSIZ_32K:
+ sram_size = 2 * SZ_16K;
+ break;
+ case AT91_CIDR_SRAMSIZ_16K:
+ default:
+ sram_size = SZ_16K;
+ }
+
+ at91sam9rl_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
+ at91sam9rl_sram_desc->length = sram_size;
+
+ /* Map SRAM */
+ iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc));
+}
+
+void __init at91sam9rl_initialize(unsigned long main_clock)
+{
+ at91_arch_reset = at91sam9_alt_reset;
+ pm_power_off = at91sam9rl_poweroff;
+ at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
+
+ /* Init clock subsystem */
+ at91_clock_init(main_clock);
+
+ /* Register the processor-specific clocks */
+ at91sam9rl_register_clocks();
+
+ /* Register GPIO subsystem */
+ at91_gpio_init(at91sam9rl_gpio, 4);
+}
+
+/* --------------------------------------------------------------------
+ * Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller */
+ 7, /* System Peripherals */
+ 1, /* Parallel IO Controller A */
+ 1, /* Parallel IO Controller B */
+ 1, /* Parallel IO Controller C */
+ 1, /* Parallel IO Controller D */
+ 5, /* USART 0 */
+ 5, /* USART 1 */
+ 5, /* USART 2 */
+ 5, /* USART 3 */
+ 0, /* Multimedia Card Interface */
+ 6, /* Two-Wire Interface 0 */
+ 6, /* Two-Wire Interface 1 */
+ 5, /* Serial Peripheral Interface */
+ 4, /* Serial Synchronous Controller 0 */
+ 4, /* Serial Synchronous Controller 1 */
+ 0, /* Timer Counter 0 */
+ 0, /* Timer Counter 1 */
+ 0, /* Timer Counter 2 */
+ 0,
+ 0, /* Touch Screen Controller */
+ 0, /* DMA Controller */
+ 2, /* USB Device High speed port */
+ 2, /* LCD Controller */
+ 6, /* AC97 Controller */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* Advanced Interrupt Controller */
+};
+
+void __init at91sam9rl_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91sam9rl_default_irq_priority;
+
+ /* Initialize the AIC interrupt controller */
+ at91_aic_init(priority);
+
+ /* Enable GPIO interrupts */
+ at91_gpio_irq_setup();
+}
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
new file mode 100644
index 00000000..aacb19dc
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -0,0 +1,1210 @@
+/*
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/i2c-gpio.h>
+
+#include <linux/fb.h>
+#include <video/atmel_lcdc.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9rl.h>
+#include <mach/at91sam9rl_matrix.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at_hdmac.h>
+
+#include "generic.h"
+
+
+/* --------------------------------------------------------------------
+ * HDMAC - AHB DMA Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
+static u64 hdmac_dmamask = DMA_BIT_MASK(32);
+
+static struct at_dma_platform_data atdma_pdata = {
+ .nr_channels = 2,
+};
+
+static struct resource hdmac_resources[] = {
+ [0] = {
+ .start = AT91_BASE_SYS + AT91_DMA,
+ .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91SAM9RL_ID_DMA,
+ .end = AT91SAM9RL_ID_DMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at_hdmac_device = {
+ .name = "at_hdmac",
+ .id = -1,
+ .dev = {
+ .dma_mask = &hdmac_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &atdma_pdata,
+ },
+ .resource = hdmac_resources,
+ .num_resources = ARRAY_SIZE(hdmac_resources),
+};
+
+void __init at91_add_device_hdmac(void)
+{
+ dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
+ platform_device_register(&at_hdmac_device);
+}
+#else
+void __init at91_add_device_hdmac(void) {}
+#endif
+
+/* --------------------------------------------------------------------
+ * USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_UDPHS_FIFO,
+ .end = AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_BASE_UDPHS,
+ .end = AT91SAM9RL_BASE_UDPHS + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = AT91SAM9RL_ID_UDPHS,
+ .end = AT91SAM9RL_ID_UDPHS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
+ [idx] = { \
+ .name = nam, \
+ .index = idx, \
+ .fifo_size = maxpkt, \
+ .nr_banks = maxbk, \
+ .can_dma = dma, \
+ .can_isoc = isoc, \
+ }
+
+static struct usba_ep_data usba_udc_ep[] __initdata = {
+ EP("ep0", 0, 64, 1, 0, 0),
+ EP("ep1", 1, 1024, 2, 1, 1),
+ EP("ep2", 2, 1024, 2, 1, 1),
+ EP("ep3", 3, 1024, 3, 1, 0),
+ EP("ep4", 4, 1024, 3, 1, 0),
+ EP("ep5", 5, 1024, 3, 1, 1),
+ EP("ep6", 6, 1024, 3, 1, 1),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+ struct usba_platform_data pdata;
+ struct usba_ep_data ep[7];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+ .name = "atmel_usba_udc",
+ .id = -1,
+ .dev = {
+ .platform_data = &usba_udc_data.pdata,
+ },
+ .resource = usba_udc_resources,
+ .num_resources = ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+ /*
+ * Invalid pins are 0 on AT91, but the usba driver is shared
+ * with AVR32, which use negative values instead. Once/if
+ * gpio_is_valid() is ported to AT91, revisit this code.
+ */
+ usba_udc_data.pdata.vbus_pin = -EINVAL;
+ usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+ memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
+
+ if (data && data->vbus_pin > 0) {
+ at91_set_gpio_input(data->vbus_pin, 0);
+ at91_set_deglitch(data->vbus_pin, 1);
+ usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+ }
+
+ /* Pullup pin is handled internally by USB device peripheral */
+
+ platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * MMC / SD
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
+static u64 mmc_dmamask = DMA_BIT_MASK(32);
+static struct at91_mmc_data mmc_data;
+
+static struct resource mmc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_MCI,
+ .end = AT91SAM9RL_BASE_MCI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_MCI,
+ .end = AT91SAM9RL_ID_MCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_mmc_device = {
+ .name = "at91_mci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &mmc_data,
+ },
+ .resource = mmc_resources,
+ .num_resources = ARRAY_SIZE(mmc_resources),
+};
+
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
+{
+ if (!data)
+ return;
+
+ /* input/irq */
+ if (data->det_pin) {
+ at91_set_gpio_input(data->det_pin, 1);
+ at91_set_deglitch(data->det_pin, 1);
+ }
+ if (data->wp_pin)
+ at91_set_gpio_input(data->wp_pin, 1);
+ if (data->vcc_pin)
+ at91_set_gpio_output(data->vcc_pin, 0);
+
+ /* CLK */
+ at91_set_A_periph(AT91_PIN_PA2, 0);
+
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA0, 1);
+ if (data->wire4) {
+ at91_set_A_periph(AT91_PIN_PA3, 1);
+ at91_set_A_periph(AT91_PIN_PA4, 1);
+ at91_set_A_periph(AT91_PIN_PA5, 1);
+ }
+
+ mmc_data = *data;
+ platform_device_register(&at91sam9rl_mmc_device);
+}
+#else
+void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * NAND / SmartMedia
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
+static struct atmel_nand_data nand_data;
+
+#define NAND_BASE AT91_CHIPSELECT_3
+
+static struct resource nand_resources[] = {
+ [0] = {
+ .start = NAND_BASE,
+ .end = NAND_BASE + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+ .end = AT91_BASE_SYS + AT91_ECC + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device atmel_nand_device = {
+ .name = "atmel_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .resource = nand_resources,
+ .num_resources = ARRAY_SIZE(nand_resources),
+};
+
+void __init at91_add_device_nand(struct atmel_nand_data *data)
+{
+ unsigned long csa;
+
+ if (!data)
+ return;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC_SMARTMEDIA);
+
+ /* enable pin */
+ if (data->enable_pin)
+ at91_set_gpio_output(data->enable_pin, 1);
+
+ /* ready/busy pin */
+ if (data->rdy_pin)
+ at91_set_gpio_input(data->rdy_pin, 1);
+
+ /* card detect pin */
+ if (data->det_pin)
+ at91_set_gpio_input(data->det_pin, 1);
+
+ at91_set_A_periph(AT91_PIN_PB4, 0); /* NANDOE */
+ at91_set_A_periph(AT91_PIN_PB5, 0); /* NANDWE */
+
+ nand_data = *data;
+ platform_device_register(&atmel_nand_device);
+}
+
+#else
+void __init at91_add_device_nand(struct atmel_nand_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * TWI (i2c)
+ * -------------------------------------------------------------------- */
+
+/*
+ * Prefer the GPIO code since the TWI controller isn't robust
+ * (gets overruns and underruns under load) and can only issue
+ * repeated STARTs in one scenario (the driver doesn't yet handle them).
+ */
+#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = AT91_PIN_PA23,
+ .sda_is_open_drain = 1,
+ .scl_pin = AT91_PIN_PA24,
+ .scl_is_open_drain = 1,
+ .udelay = 2, /* ~100 kHz */
+};
+
+static struct platform_device at91sam9rl_twi_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .dev.platform_data = &pdata,
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ at91_set_GPIO_periph(AT91_PIN_PA23, 1); /* TWD (SDA) */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_GPIO_periph(AT91_PIN_PA24, 1); /* TWCK (SCL) */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9rl_twi_device);
+}
+
+#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
+
+static struct resource twi_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_TWI0,
+ .end = AT91SAM9RL_BASE_TWI0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_TWI0,
+ .end = AT91SAM9RL_ID_TWI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_twi_device = {
+ .name = "at91_i2c",
+ .id = -1,
+ .resource = twi_resources,
+ .num_resources = ARRAY_SIZE(twi_resources),
+};
+
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
+{
+ /* pins used for TWI interface */
+ at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */
+ at91_set_multi_drive(AT91_PIN_PA23, 1);
+
+ at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */
+ at91_set_multi_drive(AT91_PIN_PA24, 1);
+
+ i2c_register_board_info(0, devices, nr_devices);
+ platform_device_register(&at91sam9rl_twi_device);
+}
+#else
+void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct resource spi_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_SPI,
+ .end = AT91SAM9RL_BASE_SPI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_SPI,
+ .end = AT91SAM9RL_ID_SPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_spi_device = {
+ .name = "atmel_spi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = spi_resources,
+ .num_resources = ARRAY_SIZE(spi_resources),
+};
+
+static const unsigned spi_standard_cs[4] = { AT91_PIN_PA28, AT91_PIN_PB7, AT91_PIN_PD8, AT91_PIN_PD9 };
+
+
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
+{
+ int i;
+ unsigned long cs_pin;
+
+ at91_set_A_periph(AT91_PIN_PA25, 0); /* MISO */
+ at91_set_A_periph(AT91_PIN_PA26, 0); /* MOSI */
+ at91_set_A_periph(AT91_PIN_PA27, 0); /* SPCK */
+
+ /* Enable SPI chip-selects */
+ for (i = 0; i < nr_devices; i++) {
+ if (devices[i].controller_data)
+ cs_pin = (unsigned long) devices[i].controller_data;
+ else
+ cs_pin = spi_standard_cs[devices[i].chip_select];
+
+ /* enable chip-select pin */
+ at91_set_gpio_output(cs_pin, 1);
+
+ /* pass chip-select pin to driver */
+ devices[i].controller_data = (void *) cs_pin;
+ }
+
+ spi_register_board_info(devices, nr_devices);
+ platform_device_register(&at91sam9rl_spi_device);
+}
+#else
+void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * AC97
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
+static u64 ac97_dmamask = DMA_BIT_MASK(32);
+static struct ac97c_platform_data ac97_data;
+
+static struct resource ac97_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_AC97C,
+ .end = AT91SAM9RL_BASE_AC97C + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_AC97C,
+ .end = AT91SAM9RL_ID_AC97C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_ac97_device = {
+ .name = "atmel_ac97c",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ac97_data,
+ },
+ .resource = ac97_resources,
+ .num_resources = ARRAY_SIZE(ac97_resources),
+};
+
+void __init at91_add_device_ac97(struct ac97c_platform_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PD1, 0); /* AC97FS */
+ at91_set_A_periph(AT91_PIN_PD2, 0); /* AC97CK */
+ at91_set_A_periph(AT91_PIN_PD3, 0); /* AC97TX */
+ at91_set_A_periph(AT91_PIN_PD4, 0); /* AC97RX */
+
+ /* reset */
+ if (data->reset_pin)
+ at91_set_gpio_output(data->reset_pin, 0);
+
+ ac97_data = *data;
+ platform_device_register(&at91sam9rl_ac97_device);
+}
+#else
+void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * LCD Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static u64 lcdc_dmamask = DMA_BIT_MASK(32);
+static struct atmel_lcdfb_info lcdc_data;
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_LCDC_BASE,
+ .end = AT91SAM9RL_LCDC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_LCDC,
+ .end = AT91SAM9RL_ID_LCDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91_lcdc_device = {
+ .name = "atmel_lcdfb",
+ .id = 0,
+ .dev = {
+ .dma_mask = &lcdc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &lcdc_data,
+ },
+ .resource = lcdc_resources,
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+};
+
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
+{
+ if (!data) {
+ return;
+ }
+
+ at91_set_B_periph(AT91_PIN_PC1, 0); /* LCDPWR */
+ at91_set_A_periph(AT91_PIN_PC5, 0); /* LCDHSYNC */
+ at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDDOTCK */
+ at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDDEN */
+ at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDCC */
+ at91_set_B_periph(AT91_PIN_PC9, 0); /* LCDD3 */
+ at91_set_B_periph(AT91_PIN_PC10, 0); /* LCDD4 */
+ at91_set_B_periph(AT91_PIN_PC11, 0); /* LCDD5 */
+ at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD6 */
+ at91_set_B_periph(AT91_PIN_PC13, 0); /* LCDD7 */
+ at91_set_B_periph(AT91_PIN_PC15, 0); /* LCDD11 */
+ at91_set_B_periph(AT91_PIN_PC16, 0); /* LCDD12 */
+ at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD13 */
+ at91_set_B_periph(AT91_PIN_PC18, 0); /* LCDD14 */
+ at91_set_B_periph(AT91_PIN_PC19, 0); /* LCDD15 */
+ at91_set_B_periph(AT91_PIN_PC20, 0); /* LCDD18 */
+ at91_set_B_periph(AT91_PIN_PC21, 0); /* LCDD19 */
+ at91_set_B_periph(AT91_PIN_PC22, 0); /* LCDD20 */
+ at91_set_B_periph(AT91_PIN_PC23, 0); /* LCDD21 */
+ at91_set_B_periph(AT91_PIN_PC24, 0); /* LCDD22 */
+ at91_set_B_periph(AT91_PIN_PC25, 0); /* LCDD23 */
+
+ lcdc_data = *data;
+ platform_device_register(&at91_lcdc_device);
+}
+#else
+void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Timer/Counter block
+ * -------------------------------------------------------------------- */
+
+#ifdef CONFIG_ATMEL_TCLIB
+
+static struct resource tcb_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_TCB0,
+ .end = AT91SAM9RL_BASE_TCB0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_TC0,
+ .end = AT91SAM9RL_ID_TC0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AT91SAM9RL_ID_TC1,
+ .end = AT91SAM9RL_ID_TC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = AT91SAM9RL_ID_TC2,
+ .end = AT91SAM9RL_ID_TC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_tcb_device = {
+ .name = "atmel_tcb",
+ .id = 0,
+ .resource = tcb_resources,
+ .num_resources = ARRAY_SIZE(tcb_resources),
+};
+
+static void __init at91_add_device_tc(void)
+{
+ platform_device_register(&at91sam9rl_tcb_device);
+}
+#else
+static void __init at91_add_device_tc(void) { }
+#endif
+
+
+/* --------------------------------------------------------------------
+ * Touchscreen
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
+static u64 tsadcc_dmamask = DMA_BIT_MASK(32);
+static struct at91_tsadcc_data tsadcc_data;
+
+static struct resource tsadcc_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_TSC,
+ .end = AT91SAM9RL_BASE_TSC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_TSC,
+ .end = AT91SAM9RL_ID_TSC,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device at91sam9rl_tsadcc_device = {
+ .name = "atmel_tsadcc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &tsadcc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tsadcc_data,
+ },
+ .resource = tsadcc_resources,
+ .num_resources = ARRAY_SIZE(tsadcc_resources),
+};
+
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data)
+{
+ if (!data)
+ return;
+
+ at91_set_A_periph(AT91_PIN_PA17, 0); /* AD0_XR */
+ at91_set_A_periph(AT91_PIN_PA18, 0); /* AD1_XL */
+ at91_set_A_periph(AT91_PIN_PA19, 0); /* AD2_YT */
+ at91_set_A_periph(AT91_PIN_PA20, 0); /* AD3_TB */
+
+ tsadcc_data = *data;
+ platform_device_register(&at91sam9rl_tsadcc_device);
+}
+#else
+void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTC
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE)
+static struct platform_device at91sam9rl_rtc_device = {
+ .name = "at91_rtc",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_rtc(void)
+{
+ platform_device_register(&at91sam9rl_rtc_device);
+}
+#else
+static void __init at91_add_device_rtc(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * RTT
+ * -------------------------------------------------------------------- */
+
+static struct resource rtt_resources[] = {
+ {
+ .start = AT91_BASE_SYS + AT91_RTT,
+ .end = AT91_BASE_SYS + AT91_RTT + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device at91sam9rl_rtt_device = {
+ .name = "at91_rtt",
+ .id = 0,
+ .resource = rtt_resources,
+ .num_resources = ARRAY_SIZE(rtt_resources),
+};
+
+static void __init at91_add_device_rtt(void)
+{
+ platform_device_register(&at91sam9rl_rtt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
+static struct platform_device at91sam9rl_wdt_device = {
+ .name = "at91_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init at91_add_device_watchdog(void)
+{
+ platform_device_register(&at91sam9rl_wdt_device);
+}
+#else
+static void __init at91_add_device_watchdog(void) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * PWM
+ * --------------------------------------------------------------------*/
+
+#if defined(CONFIG_ATMEL_PWM)
+static u32 pwm_mask;
+
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_PWMC,
+ .end = AT91SAM9RL_BASE_PWMC + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_PWMC,
+ .end = AT91SAM9RL_ID_PWMC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_pwm0_device = {
+ .name = "atmel_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_mask,
+ },
+ .resource = pwm_resources,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+};
+
+void __init at91_add_device_pwm(u32 mask)
+{
+ if (mask & (1 << AT91_PWM0))
+ at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM0 */
+
+ if (mask & (1 << AT91_PWM1))
+ at91_set_B_periph(AT91_PIN_PB9, 1); /* enable PWM1 */
+
+ if (mask & (1 << AT91_PWM2))
+ at91_set_B_periph(AT91_PIN_PD5, 1); /* enable PWM2 */
+
+ if (mask & (1 << AT91_PWM3))
+ at91_set_B_periph(AT91_PIN_PD8, 1); /* enable PWM3 */
+
+ pwm_mask = mask;
+
+ platform_device_register(&at91sam9rl_pwm0_device);
+}
+#else
+void __init at91_add_device_pwm(u32 mask) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * SSC -- Synchronous Serial Controller
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
+static u64 ssc0_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc0_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_SSC0,
+ .end = AT91SAM9RL_BASE_SSC0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_SSC0,
+ .end = AT91SAM9RL_ID_SSC0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_ssc0_device = {
+ .name = "ssc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ssc0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc0_resources,
+ .num_resources = ARRAY_SIZE(ssc0_resources),
+};
+
+static inline void configure_ssc0_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_A_periph(AT91_PIN_PC0, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_A_periph(AT91_PIN_PC1, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_A_periph(AT91_PIN_PA15, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_A_periph(AT91_PIN_PA16, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_B_periph(AT91_PIN_PA10, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_B_periph(AT91_PIN_PA22, 1);
+}
+
+static u64 ssc1_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ssc1_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_SSC1,
+ .end = AT91SAM9RL_BASE_SSC1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_SSC1,
+ .end = AT91SAM9RL_ID_SSC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9rl_ssc1_device = {
+ .name = "ssc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ssc1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = ssc1_resources,
+ .num_resources = ARRAY_SIZE(ssc1_resources),
+};
+
+static inline void configure_ssc1_pins(unsigned pins)
+{
+ if (pins & ATMEL_SSC_TF)
+ at91_set_B_periph(AT91_PIN_PA29, 1);
+ if (pins & ATMEL_SSC_TK)
+ at91_set_B_periph(AT91_PIN_PA30, 1);
+ if (pins & ATMEL_SSC_TD)
+ at91_set_B_periph(AT91_PIN_PA13, 1);
+ if (pins & ATMEL_SSC_RD)
+ at91_set_B_periph(AT91_PIN_PA14, 1);
+ if (pins & ATMEL_SSC_RK)
+ at91_set_B_periph(AT91_PIN_PA9, 1);
+ if (pins & ATMEL_SSC_RF)
+ at91_set_B_periph(AT91_PIN_PA8, 1);
+}
+
+/*
+ * SSC controllers are accessed through library code, instead of any
+ * kind of all-singing/all-dancing driver. For example one could be
+ * used by a particular I2S audio codec's driver, while another one
+ * on the same system might be used by a custom data capture driver.
+ */
+void __init at91_add_device_ssc(unsigned id, unsigned pins)
+{
+ struct platform_device *pdev;
+
+ /*
+ * NOTE: caller is responsible for passing information matching
+ * "pins" to whatever will be using each particular controller.
+ */
+ switch (id) {
+ case AT91SAM9RL_ID_SSC0:
+ pdev = &at91sam9rl_ssc0_device;
+ configure_ssc0_pins(pins);
+ break;
+ case AT91SAM9RL_ID_SSC1:
+ pdev = &at91sam9rl_ssc1_device;
+ configure_ssc1_pins(pins);
+ break;
+ default:
+ return;
+ }
+
+ platform_device_register(pdev);
+}
+
+#else
+void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
+#endif
+
+
+/* --------------------------------------------------------------------
+ * UART
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_SERIAL_ATMEL)
+static struct resource dbgu_resources[] = {
+ [0] = {
+ .start = AT91_VA_BASE_SYS + AT91_DBGU,
+ .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_ID_SYS,
+ .end = AT91_ID_SYS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data dbgu_data = {
+ .use_dma_tx = 0,
+ .use_dma_rx = 0, /* DBGU not capable of receive DMA */
+ .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
+};
+
+static u64 dbgu_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9rl_dbgu_device = {
+ .name = "atmel_usart",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dbgu_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dbgu_data,
+ },
+ .resource = dbgu_resources,
+ .num_resources = ARRAY_SIZE(dbgu_resources),
+};
+
+static inline void configure_dbgu_pins(void)
+{
+ at91_set_A_periph(AT91_PIN_PA21, 0); /* DRXD */
+ at91_set_A_periph(AT91_PIN_PA22, 1); /* DTXD */
+}
+
+static struct resource uart0_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_US0,
+ .end = AT91SAM9RL_BASE_US0 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_US0,
+ .end = AT91SAM9RL_ID_US0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart0_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart0_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9rl_uart0_device = {
+ .name = "atmel_usart",
+ .id = 1,
+ .dev = {
+ .dma_mask = &uart0_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart0_data,
+ },
+ .resource = uart0_resources,
+ .num_resources = ARRAY_SIZE(uart0_resources),
+};
+
+static inline void configure_usart0_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA6, 1); /* TXD0 */
+ at91_set_A_periph(AT91_PIN_PA7, 0); /* RXD0 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA9, 0); /* RTS0 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA10, 0); /* CTS0 */
+ if (pins & ATMEL_UART_DSR)
+ at91_set_A_periph(AT91_PIN_PD14, 0); /* DSR0 */
+ if (pins & ATMEL_UART_DTR)
+ at91_set_A_periph(AT91_PIN_PD15, 0); /* DTR0 */
+ if (pins & ATMEL_UART_DCD)
+ at91_set_A_periph(AT91_PIN_PD16, 0); /* DCD0 */
+ if (pins & ATMEL_UART_RI)
+ at91_set_A_periph(AT91_PIN_PD17, 0); /* RI0 */
+}
+
+static struct resource uart1_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_US1,
+ .end = AT91SAM9RL_BASE_US1 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_US1,
+ .end = AT91SAM9RL_ID_US1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart1_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart1_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9rl_uart1_device = {
+ .name = "atmel_usart",
+ .id = 2,
+ .dev = {
+ .dma_mask = &uart1_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart1_data,
+ },
+ .resource = uart1_resources,
+ .num_resources = ARRAY_SIZE(uart1_resources),
+};
+
+static inline void configure_usart1_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA11, 1); /* TXD1 */
+ at91_set_A_periph(AT91_PIN_PA12, 0); /* RXD1 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PA18, 0); /* RTS1 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PA19, 0); /* CTS1 */
+}
+
+static struct resource uart2_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_US2,
+ .end = AT91SAM9RL_BASE_US2 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_US2,
+ .end = AT91SAM9RL_ID_US2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart2_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart2_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9rl_uart2_device = {
+ .name = "atmel_usart",
+ .id = 3,
+ .dev = {
+ .dma_mask = &uart2_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart2_data,
+ },
+ .resource = uart2_resources,
+ .num_resources = ARRAY_SIZE(uart2_resources),
+};
+
+static inline void configure_usart2_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PA13, 1); /* TXD2 */
+ at91_set_A_periph(AT91_PIN_PA14, 0); /* RXD2 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_A_periph(AT91_PIN_PA29, 0); /* RTS2 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_A_periph(AT91_PIN_PA30, 0); /* CTS2 */
+}
+
+static struct resource uart3_resources[] = {
+ [0] = {
+ .start = AT91SAM9RL_BASE_US3,
+ .end = AT91SAM9RL_BASE_US3 + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9RL_ID_US3,
+ .end = AT91SAM9RL_ID_US3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct atmel_uart_data uart3_data = {
+ .use_dma_tx = 1,
+ .use_dma_rx = 1,
+};
+
+static u64 uart3_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device at91sam9rl_uart3_device = {
+ .name = "atmel_usart",
+ .id = 4,
+ .dev = {
+ .dma_mask = &uart3_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &uart3_data,
+ },
+ .resource = uart3_resources,
+ .num_resources = ARRAY_SIZE(uart3_resources),
+};
+
+static inline void configure_usart3_pins(unsigned pins)
+{
+ at91_set_A_periph(AT91_PIN_PB0, 1); /* TXD3 */
+ at91_set_A_periph(AT91_PIN_PB1, 0); /* RXD3 */
+
+ if (pins & ATMEL_UART_RTS)
+ at91_set_B_periph(AT91_PIN_PD4, 0); /* RTS3 */
+ if (pins & ATMEL_UART_CTS)
+ at91_set_B_periph(AT91_PIN_PD3, 0); /* CTS3 */
+}
+
+static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
+struct platform_device *atmel_default_console_device; /* the serial console device */
+
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
+{
+ struct platform_device *pdev;
+ struct atmel_uart_data *pdata;
+
+ switch (id) {
+ case 0: /* DBGU */
+ pdev = &at91sam9rl_dbgu_device;
+ configure_dbgu_pins();
+ break;
+ case AT91SAM9RL_ID_US0:
+ pdev = &at91sam9rl_uart0_device;
+ configure_usart0_pins(pins);
+ break;
+ case AT91SAM9RL_ID_US1:
+ pdev = &at91sam9rl_uart1_device;
+ configure_usart1_pins(pins);
+ break;
+ case AT91SAM9RL_ID_US2:
+ pdev = &at91sam9rl_uart2_device;
+ configure_usart2_pins(pins);
+ break;
+ case AT91SAM9RL_ID_US3:
+ pdev = &at91sam9rl_uart3_device;
+ configure_usart3_pins(pins);
+ break;
+ default:
+ return;
+ }
+ pdata = pdev->dev.platform_data;
+ pdata->num = portnr; /* update to mapped ID */
+
+ if (portnr < ATMEL_MAX_UART)
+ at91_uarts[portnr] = pdev;
+}
+
+void __init at91_set_serial_console(unsigned portnr)
+{
+ if (portnr < ATMEL_MAX_UART) {
+ atmel_default_console_device = at91_uarts[portnr];
+ at91sam9rl_set_console_clock(at91_uarts[portnr]->id);
+ }
+}
+
+void __init at91_add_device_serial(void)
+{
+ int i;
+
+ for (i = 0; i < ATMEL_MAX_UART; i++) {
+ if (at91_uarts[i])
+ platform_device_register(at91_uarts[i]);
+ }
+
+ if (!atmel_default_console_device)
+ printk(KERN_INFO "AT91: No default serial console defined.\n");
+}
+#else
+void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
+void __init at91_set_serial_console(unsigned portnr) {}
+void __init at91_add_device_serial(void) {}
+#endif
+
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init at91_add_standard_devices(void)
+{
+ at91_add_device_hdmac();
+ at91_add_device_rtc();
+ at91_add_device_rtt();
+ at91_add_device_watchdog();
+ at91_add_device_tc();
+ return 0;
+}
+
+arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
new file mode 100644
index 00000000..56ba3bd0
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-at91/at91x40.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/at91x40.h>
+#include <mach/at91_st.h>
+#include <mach/timex.h>
+#include "generic.h"
+
+/*
+ * Export the clock functions for the AT91X40. Some external code common
+ * to all AT91 family parts relys on this, like the gpio and serial support.
+ */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return AT91X40_MASTER_CLOCK;
+}
+
+void __init at91x40_initialize(unsigned long main_clock)
+{
+ at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
+ | (1 << AT91X40_ID_IRQ2);
+}
+
+/*
+ * The default interrupt priority levels (0 = lowest, 7 = highest).
+ */
+static unsigned int at91x40_default_irq_priority[NR_AIC_IRQS] __initdata = {
+ 7, /* Advanced Interrupt Controller (FIQ) */
+ 0, /* System Peripherals */
+ 0, /* USART 0 */
+ 0, /* USART 1 */
+ 2, /* Timer Counter 0 */
+ 2, /* Timer Counter 1 */
+ 2, /* Timer Counter 2 */
+ 0, /* Watchdog timer */
+ 0, /* Parallel IO Controller A */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* External IRQ0 */
+ 0, /* External IRQ1 */
+ 0, /* External IRQ2 */
+};
+
+void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS])
+{
+ if (!priority)
+ priority = at91x40_default_irq_priority;
+
+ at91_aic_init(priority);
+}
+
diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c
new file mode 100644
index 00000000..dfff2895
--- /dev/null
+++ b/arch/arm/mach-at91/at91x40_time.c
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/mach-at91/at91x40_time.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/at91_tc.h>
+
+/*
+ * 3 counter/timer units present.
+ */
+#define AT91_TC_CLK0BASE 0
+#define AT91_TC_CLK1BASE 0x40
+#define AT91_TC_CLK2BASE 0x80
+
+static unsigned long at91x40_gettimeoffset(void)
+{
+ return (at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CV) * 1000000 / (AT91X40_MASTER_CLOCK / 128));
+}
+
+static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id)
+{
+ at91_sys_read(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_SR);
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction at91x40_timer_irq = {
+ .name = "at91_tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = at91x40_timer_interrupt
+};
+
+void __init at91x40_timer_init(void)
+{
+ unsigned int v;
+
+ at91_sys_write(AT91_TC + AT91_TC_BCR, 0);
+ v = at91_sys_read(AT91_TC + AT91_TC_BMR);
+ v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
+ at91_sys_write(AT91_TC + AT91_TC_BMR, v);
+
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));
+
+ setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);
+
+ at91_sys_write(AT91_TC + AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
+}
+
+struct sys_timer at91x40_timer = {
+ .init = at91x40_timer_init,
+ .offset = at91x40_gettimeoffset,
+};
+
diff --git a/arch/arm/mach-at91/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
new file mode 100644
index 00000000..ab1d463a
--- /dev/null
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/arm/mach-at91/board-1arm.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+
+static void __init onearm_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART1 on ttyS2 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init onearm_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata onearm_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata onearm_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_udc_data __initdata onearm_udc_data = {
+ .vbus_pin = AT91_PIN_PC2,
+ .pullup_pin = AT91_PIN_PC3,
+};
+
+static void __init onearm_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&onearm_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&onearm_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&onearm_udc_data);
+}
+
+MACHINE_START(ONEARM, "Ajeco 1ARM single board computer")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = onearm_init_early,
+ .init_irq = onearm_init_irq,
+ .init_machine = onearm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-afeb-9260v1.c b/arch/arm/mach-at91/board-afeb-9260v1.c
new file mode 100644
index 00000000..a4924de4
--- /dev/null
+++ b/arch/arm/mach-at91/board-afeb-9260v1.c
@@ -0,0 +1,227 @@
+/*
+ * linux/arch/arm/mach-at91/board-afeb-9260v1.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2008 Sergey Lapin
+ *
+ * A custom board designed as open hardware; PCBs and various information
+ * is available at http://groups.google.com/group/arm9fpga-evolution-board/
+ * Subversion repository: svn://194.85.238.22/home/users/george/svn/arm9eb
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init afeb9260_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR
+ | ATMEL_UART_DCD | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init afeb9260_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata afeb9260_usbh_data = {
+ .ports = 1,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata afeb9260_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info afeb9260_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata afeb9260_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA9,
+ .is_rmii = 0,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata afeb9260_nand_partition[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = (640 * SZ_1K),
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_2M,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(afeb9260_nand_partition);
+ return afeb9260_nand_partition;
+}
+
+static struct atmel_nand_data __initdata afeb9260_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+ .bus_width_16 = 0,
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata afeb9260_mmc_data = {
+ .det_pin = AT91_PIN_PC9,
+ .wp_pin = AT91_PIN_PC4,
+ .slot_b = 1,
+ .wire4 = 1,
+};
+
+
+
+static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ }, {
+ I2C_BOARD_INFO("fm3130", 0x68),
+ }, {
+ I2C_BOARD_INFO("24c64", 0x50),
+ },
+};
+
+/*
+ * IDE (CF True IDE mode)
+ */
+static struct at91_cf_data afeb9260_cf_data = {
+ .chipselect = 4,
+ .irq_pin = AT91_PIN_PA6,
+ .rst_pin = AT91_PIN_PA7,
+ .flags = AT91_CF_TRUE_IDE,
+};
+
+static void __init afeb9260_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&afeb9260_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&afeb9260_udc_data);
+ /* SPI */
+ at91_add_device_spi(afeb9260_spi_devices,
+ ARRAY_SIZE(afeb9260_spi_devices));
+ /* NAND */
+ at91_add_device_nand(&afeb9260_nand_data);
+ /* Ethernet */
+ at91_add_device_eth(&afeb9260_macb_data);
+
+ /* Standard function's pin assignments are not
+ * appropriate for us and generic code provide
+ * no API to configure these pins any other way */
+ at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */
+ /* MMC */
+ at91_add_device_mmc(0, &afeb9260_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(afeb9260_i2c_devices,
+ ARRAY_SIZE(afeb9260_i2c_devices));
+ /* Audio */
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+ /* IDE */
+ at91_add_device_cf(&afeb9260_cf_data);
+}
+
+MACHINE_START(AFEB9260, "Custom afeb9260 board")
+ /* Maintainer: Sergey Lapin <slapin@ossfans.org> */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = afeb9260_init_early,
+ .init_irq = afeb9260_init_irq,
+ .init_machine = afeb9260_board_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-at91/board-cam60.c b/arch/arm/mach-at91/board-cam60.c
new file mode 100644
index 00000000..148fccb9
--- /dev/null
+++ b/arch/arm/mach-at91/board-cam60.c
@@ -0,0 +1,206 @@
+/*
+ * KwikByte CAM60 (KB9260)
+ *
+ * based on board-sam9260ek.c
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init cam60_init_early(void)
+{
+ /* Initialize processor: 10 MHz crystal */
+ at91sam9260_initialize(10000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init cam60_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host
+ */
+static struct at91_usbh_data __initdata cam60_usbh_data = {
+ .ports = 1,
+};
+
+
+/*
+ * SPI devices.
+ */
+#if defined(CONFIG_MTD_DATAFLASH)
+static struct mtd_partition cam60_spi_partitions[] = {
+ {
+ .name = "BOOT1",
+ .offset = 0,
+ .size = 4 * 1056,
+ },
+ {
+ .name = "BOOT2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 256 * 1056,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 2222 * 1056,
+ },
+ {
+ .name = "file system",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data cam60_spi_flash_platform_data = {
+ .name = "spi_flash",
+ .parts = cam60_spi_partitions,
+ .nr_parts = ARRAY_SIZE(cam60_spi_partitions)
+};
+#endif
+
+static struct spi_board_info cam60_spi_devices[] __initdata = {
+#if defined(CONFIG_MTD_DATAFLASH)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ .platform_data = &cam60_spi_flash_platform_data
+ },
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct __initdata at91_eth_data cam60_macb_data = {
+ .phy_irq_pin = AT91_PIN_PB5,
+ .is_rmii = 0,
+};
+
+
+/*
+ * NAND Flash
+ */
+static struct mtd_partition __initdata cam60_nand_partition[] = {
+ {
+ .name = "nand_fs",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(cam60_nand_partition);
+ return cam60_nand_partition;
+}
+
+static struct atmel_nand_data __initdata cam60_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ // .det_pin = ... not there
+ .rdy_pin = AT91_PIN_PA9,
+ .enable_pin = AT91_PIN_PA7,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata cam60_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init cam60_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &cam60_nand_smc_config);
+
+ at91_add_device_nand(&cam60_nand_data);
+}
+
+
+static void __init cam60_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* SPI */
+ at91_add_device_spi(cam60_spi_devices, ARRAY_SIZE(cam60_spi_devices));
+ /* Ethernet */
+ at91_add_device_eth(&cam60_macb_data);
+ /* USB Host */
+ /* enable USB power supply circuit */
+ at91_set_gpio_output(AT91_PIN_PB18, 1);
+ at91_add_device_usbh(&cam60_usbh_data);
+ /* NAND */
+ cam60_add_device_nand();
+}
+
+MACHINE_START(CAM60, "KwikByte CAM60")
+ /* Maintainer: KwikByte */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = cam60_init_early,
+ .init_irq = cam60_init_irq,
+ .init_machine = cam60_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
new file mode 100644
index 00000000..cdb65d48
--- /dev/null
+++ b/arch/arm/mach-at91/board-cap9adk.c
@@ -0,0 +1,404 @@
+/*
+ * linux/arch/arm/mach-at91/board-cap9adk.c
+ *
+ * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/fb.h>
+#include <linux/mtd/physmap.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91cap9_matrix.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init cap9adk_init_early(void)
+{
+ /* Initialize processor: 12 MHz crystal */
+ at91cap9_initialize(12000000);
+
+ /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
+ at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
+ /* ... POWER LED always on */
+ at91_set_gpio_output(AT91_PIN_PC29, 1);
+
+ /* Setup the serial ports and console */
+ at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */
+ at91_set_serial_console(0);
+}
+
+static void __init cap9adk_init_irq(void)
+{
+ at91cap9_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata cap9adk_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
+ .vbus_pin = AT91_PIN_PB31,
+};
+
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init cap9adk_add_device_ts(void)
+{
+ at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */
+ at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */
+}
+#else
+static void __init cap9adk_add_device_ts(void) {}
+#endif
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info cap9adk_spi_devices[] = {
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */
+ .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91_PIN_PC4,
+ },
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata cap9adk_mmc_data = {
+ .wire4 = 1,
+// .det_pin = ... not connected
+// .wp_pin = ... not connected
+// .vcc_pin = ... not connected
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata cap9adk_macb_data = {
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
+ {
+ .name = "NAND partition",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(cap9adk_nand_partitions);
+ return cap9adk_nand_partitions;
+}
+
+static struct atmel_nand_data __initdata cap9adk_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+// .rdy_pin = ... not connected
+ .enable_pin = AT91_PIN_PD15,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
+ .ncs_read_setup = 1,
+ .nrd_setup = 2,
+ .ncs_write_setup = 1,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 6,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 6,
+ .nwe_pulse = 4,
+
+ .read_cycle = 8,
+ .write_cycle = 8,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 1,
+};
+
+static void __init cap9adk_add_device_nand(void)
+{
+ unsigned long csa;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
+
+ cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (cap9adk_nand_data.bus_width_16)
+ cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &cap9adk_nand_smc_config);
+
+ at91_add_device_nand(&cap9adk_nand_data);
+}
+
+
+/*
+ * NOR flash
+ */
+static struct mtd_partition cap9adk_nor_partitions[] = {
+ {
+ .name = "NOR partition",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data cap9adk_nor_data = {
+ .width = 2,
+ .parts = cap9adk_nor_partitions,
+ .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions),
+};
+
+#define NOR_BASE AT91_CHIPSELECT_0
+#define NOR_SIZE SZ_8M
+
+static struct resource nor_flash_resources[] = {
+ {
+ .start = NOR_BASE,
+ .end = NOR_BASE + NOR_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device cap9adk_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &cap9adk_nor_data,
+ },
+ .resource = nor_flash_resources,
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+};
+
+static struct sam9_smc_config __initdata cap9adk_nor_smc_config = {
+ .ncs_read_setup = 2,
+ .nrd_setup = 4,
+ .ncs_write_setup = 2,
+ .nwe_setup = 4,
+
+ .ncs_read_pulse = 10,
+ .nrd_pulse = 8,
+ .ncs_write_pulse = 10,
+ .nwe_pulse = 8,
+
+ .read_cycle = 16,
+ .write_cycle = 16,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16,
+ .tdf_cycles = 1,
+};
+
+static __init void cap9adk_add_device_nor(void)
+{
+ unsigned long csa;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
+
+ /* configure chip-select 0 (NOR) */
+ sam9_smc_configure(0, &cap9adk_nor_smc_config);
+
+ platform_device_register(&cap9adk_nor_flash);
+}
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "TX09D50VM1CCA @ 60",
+ .refresh = 60,
+ .xres = 240, .yres = 320,
+ .pixclock = KHZ2PICOS(4965),
+
+ .left_margin = 1, .right_margin = 33,
+ .upper_margin = 1, .lower_margin = 0,
+ .hsync_len = 5, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "TX09D70VM1CCA",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+ if (on)
+ at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */
+ else
+ at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
+ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_power_control,
+ .guard_time = 1,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
+#endif
+
+
+/*
+ * AC97
+ */
+static struct ac97c_platform_data cap9adk_ac97_data = {
+// .reset_pin = ... not connected
+};
+
+
+static void __init cap9adk_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&cap9adk_usbh_data);
+ /* USB HS */
+ at91_add_device_usba(&cap9adk_usba_udc_data);
+ /* SPI */
+ at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
+ /* Touchscreen */
+ cap9adk_add_device_ts();
+ /* MMC */
+ at91_add_device_mmc(1, &cap9adk_mmc_data);
+ /* Ethernet */
+ at91_add_device_eth(&cap9adk_macb_data);
+ /* NAND */
+ cap9adk_add_device_nand();
+ /* NOR Flash */
+ cap9adk_add_device_nor();
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* LCD Controller */
+ at91_add_device_lcdc(&cap9adk_lcdc_data);
+ /* AC97 */
+ at91_add_device_ac97(&cap9adk_ac97_data);
+}
+
+MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
+ /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
+ .timer = &at91sam926x_timer,
+ .map_io = at91cap9_map_io,
+ .init_early = cap9adk_init_early,
+ .init_irq = cap9adk_init_irq,
+ .init_machine = cap9adk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
new file mode 100644
index 00000000..f36b1868
--- /dev/null
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-at91/board-carmeva.c
+ *
+ * Copyright (c) 2005 Peer Georgi
+ * Conitec Datasystems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init carmeva_init_early(void)
+{
+ /* Initialize processor: 20.000 MHz crystal */
+ at91rm9200_initialize(20000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init carmeva_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata carmeva_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata carmeva_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata carmeva_udc_data = {
+ .vbus_pin = AT91_PIN_PD12,
+ .pullup_pin = AT91_PIN_PD9,
+};
+
+/* FIXME: user dependent */
+// static struct at91_cf_data __initdata carmeva_cf_data = {
+// .det_pin = AT91_PIN_PB0,
+// .rst_pin = AT91_PIN_PC5,
+ // .irq_pin = ... not connected
+ // .vcc_pin = ... always powered
+// };
+
+static struct at91_mmc_data __initdata carmeva_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PB10,
+ .wp_pin = AT91_PIN_PC14,
+};
+
+static struct spi_board_info carmeva_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 10 * 1000 * 1000,
+ },
+ { /* User accessible spi - cs1 (250KHz) */
+ .modalias = "spi-cs1",
+ .chip_select = 1,
+ .max_speed_hz = 250 * 1000,
+ },
+ { /* User accessible spi - cs2 (1MHz) */
+ .modalias = "spi-cs2",
+ .chip_select = 2,
+ .max_speed_hz = 1 * 1000 * 1000,
+ },
+ { /* User accessible spi - cs3 (10MHz) */
+ .modalias = "spi-cs3",
+ .chip_select = 3,
+ .max_speed_hz = 10 * 1000 * 1000,
+ },
+};
+
+static struct gpio_led carmeva_leds[] = {
+ { /* "user led 1", LED9 */
+ .name = "led9",
+ .gpio = AT91_PIN_PA21,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* "user led 2", LED10 */
+ .name = "led10",
+ .gpio = AT91_PIN_PA25,
+ .active_low = 1,
+ },
+ { /* "user led 3", LED11 */
+ .name = "led11",
+ .gpio = AT91_PIN_PA26,
+ .active_low = 1,
+ },
+ { /* "user led 4", LED12 */
+ .name = "led12",
+ .gpio = AT91_PIN_PA18,
+ .active_low = 1,
+ }
+};
+
+static void __init carmeva_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&carmeva_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&carmeva_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&carmeva_udc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices));
+ /* Compact Flash */
+// at91_add_device_cf(&carmeva_cf_data);
+ /* MMC */
+ at91_add_device_mmc(0, &carmeva_mmc_data);
+ /* LEDs */
+ at91_gpio_leds(carmeva_leds, ARRAY_SIZE(carmeva_leds));
+}
+
+MACHINE_START(CARMEVA, "Carmeva")
+ /* Maintainer: Conitec Datasystems */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = carmeva_init_early,
+ .init_irq = carmeva_init_irq,
+ .init_machine = carmeva_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-cpu9krea.c b/arch/arm/mach-at91/board-cpu9krea.c
new file mode 100644
index 00000000..98051108
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpu9krea.c
@@ -0,0 +1,383 @@
+/*
+ * linux/arch/arm/mach-at91/board-cpu9krea.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91sam9260_matrix.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+static void __init cpu9krea_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
+ ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
+ ATMEL_UART_DCD | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS |
+ ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS |
+ ATMEL_UART_RTS);
+
+ /* USART3 on ttyS4. (Rx, Tx) */
+ at91_register_uart(AT91SAM9260_ID_US3, 4, 0);
+
+ /* USART4 on ttyS5. (Rx, Tx) */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+ /* USART5 on ttyS6. (Rx, Tx) */
+ at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init cpu9krea_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata cpu9krea_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata cpu9krea_udc_data = {
+ .vbus_pin = AT91_PIN_PC8,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata cpu9krea_macb_data = {
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct atmel_nand_data __initdata cpu9krea_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .bus_width_16 = 0,
+};
+
+#ifdef CONFIG_MACH_CPU9260
+static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+#else
+static struct sam9_smc_config __initdata cpu9krea_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 3,
+};
+#endif
+
+static void __init cpu9krea_add_device_nand(void)
+{
+ sam9_smc_configure(3, &cpu9krea_nand_smc_config);
+ at91_add_device_nand(&cpu9krea_nand_data);
+}
+
+/*
+ * NOR flash
+ */
+static struct physmap_flash_data cpuat9260_nor_data = {
+ .width = 2,
+};
+
+#define NOR_BASE AT91_CHIPSELECT_0
+#define NOR_SIZE SZ_64M
+
+static struct resource nor_flash_resources[] = {
+ {
+ .start = NOR_BASE,
+ .end = NOR_BASE + NOR_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device cpu9krea_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &cpuat9260_nor_data,
+ },
+ .resource = nor_flash_resources,
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+};
+
+#ifdef CONFIG_MACH_CPU9260
+static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 10,
+ .nrd_pulse = 10,
+ .ncs_write_pulse = 6,
+ .nwe_pulse = 6,
+
+ .read_cycle = 12,
+ .write_cycle = 8,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
+ | AT91_SMC_DBW_16,
+ .tdf_cycles = 2,
+};
+#else
+static struct sam9_smc_config __initdata cpu9krea_nor_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 13,
+ .nrd_pulse = 13,
+ .ncs_write_pulse = 8,
+ .nwe_pulse = 8,
+
+ .read_cycle = 15,
+ .write_cycle = 10,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE
+ | AT91_SMC_DBW_16,
+ .tdf_cycles = 2,
+};
+#endif
+
+static __init void cpu9krea_add_device_nor(void)
+{
+ unsigned long csa;
+
+ csa = at91_sys_read(AT91_MATRIX_EBICSA);
+ at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_VDDIOMSEL_3_3V);
+
+ /* configure chip-select 0 (NOR) */
+ sam9_smc_configure(0, &cpu9krea_nor_smc_config);
+
+ platform_device_register(&cpu9krea_nor_flash);
+}
+
+/*
+ * LEDs
+ */
+static struct gpio_led cpu9krea_leds[] = {
+ { /* LED1 */
+ .name = "LED1",
+ .gpio = AT91_PIN_PC11,
+ .active_low = 1,
+ .default_trigger = "timer",
+ },
+ { /* LED2 */
+ .name = "LED2",
+ .gpio = AT91_PIN_PC12,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* LED3 */
+ .name = "LED3",
+ .gpio = AT91_PIN_PC7,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* LED4 */
+ .name = "LED4",
+ .gpio = AT91_PIN_PC9,
+ .active_low = 1,
+ .default_trigger = "none",
+ }
+};
+
+static struct i2c_board_info __initdata cpu9krea_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rtc-ds1307", 0x68),
+ .type = "ds1339",
+ },
+};
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button cpu9krea_buttons[] = {
+ {
+ .gpio = AT91_PIN_PC3,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB20,
+ .code = BTN_1,
+ .desc = "BP2",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data cpu9krea_button_data = {
+ .buttons = cpu9krea_buttons,
+ .nbuttons = ARRAY_SIZE(cpu9krea_buttons),
+};
+
+static struct platform_device cpu9krea_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &cpu9krea_button_data,
+ }
+};
+
+static void __init cpu9krea_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PC3, 1); /* BP1 */
+ at91_set_deglitch(AT91_PIN_PC3, 1);
+ at91_set_gpio_input(AT91_PIN_PB20, 1); /* BP2 */
+ at91_set_deglitch(AT91_PIN_PB20, 1);
+
+ platform_device_register(&cpu9krea_button_device);
+}
+#else
+static void __init cpu9krea_add_device_buttons(void)
+{
+}
+#endif
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata cpu9krea_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PA29,
+};
+
+static void __init cpu9krea_board_init(void)
+{
+ /* NOR */
+ cpu9krea_add_device_nor();
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&cpu9krea_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&cpu9krea_udc_data);
+ /* NAND */
+ cpu9krea_add_device_nand();
+ /* Ethernet */
+ at91_add_device_eth(&cpu9krea_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &cpu9krea_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(cpu9krea_i2c_devices,
+ ARRAY_SIZE(cpu9krea_i2c_devices));
+ /* LEDs */
+ at91_gpio_leds(cpu9krea_leds, ARRAY_SIZE(cpu9krea_leds));
+ /* Push Buttons */
+ cpu9krea_add_device_buttons();
+}
+
+#ifdef CONFIG_MACH_CPU9260
+MACHINE_START(CPUAT9260, "Eukrea CPU9260")
+#else
+MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
+#endif
+ /* Maintainer: Eric Benard - EUKREA Electromatique */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = cpu9krea_init_early,
+ .init_irq = cpu9krea_init_irq,
+ .init_machine = cpu9krea_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-cpuat91.c b/arch/arm/mach-at91/board-cpuat91.c
new file mode 100644
index 00000000..6daabe39
--- /dev/null
+++ b/arch/arm/mach-at91/board-cpuat91.c
@@ -0,0 +1,187 @@
+/*
+ * linux/arch/arm/mach-at91/board-cpuat91.c
+ *
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+static struct gpio_led cpuat91_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = AT91_PIN_PC0,
+ },
+};
+
+static void __init cpuat91_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS |
+ ATMEL_UART_RTS);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 2, ATMEL_UART_CTS |
+ ATMEL_UART_RTS | ATMEL_UART_DTR | ATMEL_UART_DSR |
+ ATMEL_UART_DCD | ATMEL_UART_RI);
+
+ /* USART2 on ttyS3 (Rx, Tx) */
+ at91_register_uart(AT91RM9200_ID_US2, 3, 0);
+
+ /* USART3 on ttyS4 (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US3, 4, ATMEL_UART_CTS |
+ ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init cpuat91_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata cpuat91_eth_data = {
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata cpuat91_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_udc_data __initdata cpuat91_udc_data = {
+ .vbus_pin = AT91_PIN_PC15,
+ .pullup_pin = AT91_PIN_PC14,
+};
+
+static struct at91_mmc_data __initdata cpuat91_mmc_data = {
+ .det_pin = AT91_PIN_PC2,
+ .wire4 = 1,
+};
+
+static struct physmap_flash_data cpuat91_flash_data = {
+ .width = 2,
+};
+
+static struct resource cpuat91_flash_resource = {
+ .start = AT91_CHIPSELECT_0,
+ .end = AT91_CHIPSELECT_0 + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cpuat91_norflash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &cpuat91_flash_data,
+ },
+ .resource = &cpuat91_flash_resource,
+ .num_resources = 1,
+};
+
+#ifdef CONFIG_MTD_PLATRAM
+struct platdata_mtd_ram at91_sram_pdata = {
+ .mapname = "SRAM",
+ .bankwidth = 2,
+};
+
+static struct resource at91_sram_resource[] = {
+ [0] = {
+ .start = AT91RM9200_SRAM_BASE,
+ .end = AT91RM9200_SRAM_BASE + AT91RM9200_SRAM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device at91_sram = {
+ .name = "mtd-ram",
+ .id = 0,
+ .resource = at91_sram_resource,
+ .num_resources = ARRAY_SIZE(at91_sram_resource),
+ .dev = {
+ .platform_data = &at91_sram_pdata,
+ },
+};
+#endif /* MTD_PLATRAM */
+
+static struct platform_device *platform_devices[] __initdata = {
+ &cpuat91_norflash,
+#ifdef CONFIG_MTD_PLATRAM
+ &at91_sram,
+#endif /* CONFIG_MTD_PLATRAM */
+};
+
+static void __init cpuat91_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* LEDs. */
+ at91_gpio_leds(cpuat91_leds, ARRAY_SIZE(cpuat91_leds));
+ /* Ethernet */
+ at91_add_device_eth(&cpuat91_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&cpuat91_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&cpuat91_udc_data);
+ /* MMC */
+ at91_add_device_mmc(0, &cpuat91_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Platform devices */
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+MACHINE_START(CPUAT91, "Eukrea")
+ /* Maintainer: Eric Benard - EUKREA Electromatique */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = cpuat91_init_early,
+ .init_irq = cpuat91_init_irq,
+ .init_machine = cpuat91_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
new file mode 100644
index 00000000..d98bcec1
--- /dev/null
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -0,0 +1,265 @@
+/*
+ * linux/arch/arm/mach-at91/board-csb337.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init csb337_init_early(void)
+{
+ /* Initialize processor: 3.6864 MHz crystal */
+ at91rm9200_initialize(3686400);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
+
+ /* DBGU on ttyS0 */
+ at91_register_uart(0, 0, 0);
+
+ /* make console=ttyS0 the default */
+ at91_set_serial_console(0);
+}
+
+static void __init csb337_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata csb337_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC2,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata csb337_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata csb337_udc_data = {
+ // this has no VBUS sensing pin
+ .pullup_pin = AT91_PIN_PA24,
+};
+
+static struct i2c_board_info __initdata csb337_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1307", 0x68),
+ },
+};
+
+static struct at91_cf_data __initdata csb337_cf_data = {
+ /*
+ * connector P4 on the CSB 337 mates to
+ * connector P8 on the CSB 300CF
+ */
+
+ /* CSB337 specific */
+ .det_pin = AT91_PIN_PC3,
+
+ /* CSB300CF specific */
+ .irq_pin = AT91_PIN_PA19,
+ .vcc_pin = AT91_PIN_PD0,
+ .rst_pin = AT91_PIN_PD2,
+};
+
+static struct at91_mmc_data __initdata csb337_mmc_data = {
+ .det_pin = AT91_PIN_PD5,
+ .slot_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PD6,
+};
+
+static struct spi_board_info csb337_spi_devices[] = {
+ { /* CAN controller */
+ .modalias = "sak82c900",
+ .chip_select = 0,
+ .max_speed_hz = 6 * 1000 * 1000,
+ },
+};
+
+#define CSB_FLASH_BASE AT91_CHIPSELECT_0
+#define CSB_FLASH_SIZE SZ_8M
+
+static struct mtd_partition csb_flash_partitions[] = {
+ {
+ .name = "uMON flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = MTD_WRITEABLE, /* read only */
+ }
+};
+
+static struct physmap_flash_data csb_flash_data = {
+ .width = 2,
+ .parts = csb_flash_partitions,
+ .nr_parts = ARRAY_SIZE(csb_flash_partitions),
+};
+
+static struct resource csb_flash_resources[] = {
+ {
+ .start = CSB_FLASH_BASE,
+ .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device csb_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &csb_flash_data,
+ },
+ .resource = csb_flash_resources,
+ .num_resources = ARRAY_SIZE(csb_flash_resources),
+};
+
+/*
+ * GPIO Buttons (on CSB300)
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button csb300_buttons[] = {
+ {
+ .gpio = AT91_PIN_PB29,
+ .code = BTN_0,
+ .desc = "sw0",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB28,
+ .code = BTN_1,
+ .desc = "sw1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA21,
+ .code = BTN_2,
+ .desc = "sw2",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data csb300_button_data = {
+ .buttons = csb300_buttons,
+ .nbuttons = ARRAY_SIZE(csb300_buttons),
+};
+
+static struct platform_device csb300_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &csb300_button_data,
+ }
+};
+
+static void __init csb300_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PB29, 1); /* sw0 */
+ at91_set_deglitch(AT91_PIN_PB29, 1);
+ at91_set_gpio_input(AT91_PIN_PB28, 1); /* sw1 */
+ at91_set_deglitch(AT91_PIN_PB28, 1);
+ at91_set_gpio_input(AT91_PIN_PA21, 1); /* sw2 */
+ at91_set_deglitch(AT91_PIN_PA21, 1);
+
+ platform_device_register(&csb300_button_device);
+}
+#else
+static void __init csb300_add_device_buttons(void) {}
+#endif
+
+static struct gpio_led csb_leds[] = {
+ { /* "led0", yellow */
+ .name = "led0",
+ .gpio = AT91_PIN_PB2,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* "led1", green */
+ .name = "led1",
+ .gpio = AT91_PIN_PB1,
+ .active_low = 1,
+ .default_trigger = "mmc0",
+ },
+ { /* "led2", yellow */
+ .name = "led2",
+ .gpio = AT91_PIN_PB0,
+ .active_low = 1,
+ .default_trigger = "ide-disk",
+ }
+};
+
+
+static void __init csb337_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&csb337_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&csb337_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&csb337_udc_data);
+ /* I2C */
+ at91_add_device_i2c(csb337_i2c_devices, ARRAY_SIZE(csb337_i2c_devices));
+ /* Compact Flash */
+ at91_set_gpio_input(AT91_PIN_PB22, 1); /* IOIS16 */
+ at91_add_device_cf(&csb337_cf_data);
+ /* SPI */
+ at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &csb337_mmc_data);
+ /* NOR flash */
+ platform_device_register(&csb_flash);
+ /* LEDs */
+ at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds));
+ /* Switches on CSB300 */
+ csb300_add_device_buttons();
+}
+
+MACHINE_START(CSB337, "Cogent CSB337")
+ /* Maintainer: Bill Gatliff */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = csb337_init_early,
+ .init_irq = csb337_init_irq,
+ .init_machine = csb337_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
new file mode 100644
index 00000000..019aab4e
--- /dev/null
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -0,0 +1,146 @@
+/*
+ * linux/arch/arm/mach-at91/board-csb637.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init csb637_init_early(void)
+{
+ /* Initialize processor: 3.6864 MHz crystal */
+ at91rm9200_initialize(3686400);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* make console=ttyS0 (ie, DBGU) the default */
+ at91_set_serial_console(0);
+}
+
+static void __init csb637_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata csb637_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC0,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata csb637_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata csb637_udc_data = {
+ .vbus_pin = AT91_PIN_PB28,
+ .pullup_pin = AT91_PIN_PB1,
+};
+
+#define CSB_FLASH_BASE AT91_CHIPSELECT_0
+#define CSB_FLASH_SIZE SZ_16M
+
+static struct mtd_partition csb_flash_partitions[] = {
+ {
+ .name = "uMON flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = MTD_WRITEABLE, /* read only */
+ }
+};
+
+static struct physmap_flash_data csb_flash_data = {
+ .width = 2,
+ .parts = csb_flash_partitions,
+ .nr_parts = ARRAY_SIZE(csb_flash_partitions),
+};
+
+static struct resource csb_flash_resources[] = {
+ {
+ .start = CSB_FLASH_BASE,
+ .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device csb_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &csb_flash_data,
+ },
+ .resource = csb_flash_resources,
+ .num_resources = ARRAY_SIZE(csb_flash_resources),
+};
+
+static struct gpio_led csb_leds[] = {
+ { /* "d1", red */
+ .name = "d1",
+ .gpio = AT91_PIN_PB2,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+};
+
+static void __init csb637_board_init(void)
+{
+ /* LED(s) */
+ at91_gpio_leds(csb_leds, ARRAY_SIZE(csb_leds));
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&csb637_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&csb637_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&csb637_udc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(NULL, 0);
+ /* NOR flash */
+ platform_device_register(&csb_flash);
+}
+
+MACHINE_START(CSB637, "Cogent CSB637")
+ /* Maintainer: Bill Gatliff */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = csb637_init_early,
+ .init_irq = csb637_init_irq,
+ .init_machine = csb637_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-eb01.c b/arch/arm/mach-at91/board-eb01.c
new file mode 100644
index 00000000..d2023f27
--- /dev/null
+++ b/arch/arm/mach-at91/board-eb01.c
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-at91/board-eb01.c
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/board.h>
+#include "generic.h"
+
+static void __init at91eb01_init_irq(void)
+{
+ at91x40_init_interrupts(NULL);
+}
+
+static void __init at91eb01_init_early(void)
+{
+ at91x40_initialize(40000000);
+}
+
+MACHINE_START(AT91EB01, "Atmel AT91 EB01")
+ /* Maintainer: Greg Ungerer <gerg@snapgear.com> */
+ .timer = &at91x40_timer,
+ .init_early = at91eb01_init_early,
+ .init_irq = at91eb01_init_irq,
+MACHINE_END
+
diff --git a/arch/arm/mach-at91/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
new file mode 100644
index 00000000..e9484535
--- /dev/null
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -0,0 +1,128 @@
+/*
+ * linux/arch/arm/mach-at91/board-eb9200.c
+ *
+ * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest
+ * by Andrew Patrikalakis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+
+static void __init eb9200_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART2 on ttyS2. (Rx, Tx) - IRDA */
+ at91_register_uart(AT91RM9200_ID_US2, 2, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init eb9200_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata eb9200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata eb9200_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata eb9200_udc_data = {
+ .vbus_pin = AT91_PIN_PD4,
+ .pullup_pin = AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata eb9200_cf_data = {
+ .det_pin = AT91_PIN_PB0,
+ .rst_pin = AT91_PIN_PC5,
+ // .irq_pin = ... not connected
+ // .vcc_pin = ... always powered
+};
+
+static struct at91_mmc_data __initdata eb9200_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+};
+
+static struct i2c_board_info __initdata eb9200_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50),
+ },
+};
+
+
+static void __init eb9200_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&eb9200_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&eb9200_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&eb9200_udc_data);
+ /* I2C */
+ at91_add_device_i2c(eb9200_i2c_devices, ARRAY_SIZE(eb9200_i2c_devices));
+ /* Compact Flash */
+ at91_add_device_cf(&eb9200_cf_data);
+ /* SPI */
+ at91_add_device_spi(NULL, 0);
+ /* MMC */
+ /* only supports 1 or 4 bit interface, not wired through to SPI */
+ at91_add_device_mmc(0, &eb9200_mmc_data);
+}
+
+MACHINE_START(ATEB9200, "Embest ATEB9200")
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = eb9200_init_early,
+ .init_irq = eb9200_init_irq,
+ .init_machine = eb9200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c
new file mode 100644
index 00000000..a6f57faa
--- /dev/null
+++ b/arch/arm/mach-at91/board-ecbat91.c
@@ -0,0 +1,180 @@
+/*
+ * linux/arch/arm/mach-at91rm9200/board-ecbat91.c
+ * Copyright (C) 2007 emQbit.com.
+ *
+ * We started from board-dk.c, which is Copyright (C) 2005 SAN People.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+
+static void __init ecb_at91init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx & Tx only) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ecb_at91init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata ecb_at91eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata ecb_at91usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_mmc_data __initdata ecb_at91mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+};
+
+
+#if defined(CONFIG_MTD_DATAFLASH)
+static struct mtd_partition __initdata my_flash0_partitions[] =
+{
+ { /* 0x8400 */
+ .name = "Darrell-loader",
+ .offset = 0,
+ .size = 12 * 1056,
+ },
+ {
+ .name = "U-boot",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 110 * 1056,
+ },
+ { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */
+ .name = "UBoot-env",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 8 * 1056,
+ },
+ { /* 1336 (167 blocks) pages * 1056 bytes = 0x158700 bytes */
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 1534 * 1056,
+ },
+ { /* 190200 - jffs2 root filesystem */
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL, /* 26 sectors */
+ }
+};
+
+static struct flash_platform_data __initdata my_flash0_platform = {
+ .name = "Removable flash card",
+ .parts = my_flash0_partitions,
+ .nr_parts = ARRAY_SIZE(my_flash0_partitions)
+};
+
+#endif
+
+static struct spi_board_info __initdata ecb_at91spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+#if defined(CONFIG_MTD_DATAFLASH)
+ .platform_data = &my_flash0_platform,
+#endif
+ },
+ { /* User accessible spi - cs1 (250KHz) */
+ .modalias = "spi-cs1",
+ .chip_select = 1,
+ .max_speed_hz = 250 * 1000,
+ },
+ { /* User accessible spi - cs2 (1MHz) */
+ .modalias = "spi-cs2",
+ .chip_select = 2,
+ .max_speed_hz = 1 * 1000 * 1000,
+ },
+ { /* User accessible spi - cs3 (10MHz) */
+ .modalias = "spi-cs3",
+ .chip_select = 3,
+ .max_speed_hz = 10 * 1000 * 1000,
+ },
+};
+
+static void __init ecb_at91board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+
+ /* Ethernet */
+ at91_add_device_eth(&ecb_at91eth_data);
+
+ /* USB Host */
+ at91_add_device_usbh(&ecb_at91usbh_data);
+
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+
+ /* MMC */
+ at91_add_device_mmc(0, &ecb_at91mmc_data);
+
+ /* SPI */
+ at91_add_device_spi(ecb_at91spi_devices, ARRAY_SIZE(ecb_at91spi_devices));
+}
+
+MACHINE_START(ECBAT91, "emQbit's ECB_AT91")
+ /* Maintainer: emQbit.com */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = ecb_at91init_early,
+ .init_irq = ecb_at91init_irq,
+ .init_machine = ecb_at91board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c
new file mode 100644
index 00000000..bfc0062d
--- /dev/null
+++ b/arch/arm/mach-at91/board-eco920.c
@@ -0,0 +1,142 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board.h>
+#include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+static void __init eco920_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ at91rm9200_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
+
+ /* DBGU on ttyS0. (Rx & Tx only */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init eco920_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata eco920_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC2,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata eco920_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_udc_data __initdata eco920_udc_data = {
+ .vbus_pin = AT91_PIN_PB12,
+ .pullup_pin = AT91_PIN_PB13,
+};
+
+static struct at91_mmc_data __initdata eco920_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 0,
+};
+
+static struct physmap_flash_data eco920_flash_data = {
+ .width = 2,
+};
+
+static struct resource eco920_flash_resource = {
+ .start = 0x11000000,
+ .end = 0x11ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device eco920_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &eco920_flash_data,
+ },
+ .resource = &eco920_flash_resource,
+ .num_resources = 1,
+};
+
+static struct spi_board_info eco920_spi_devices[] = {
+ { /* CAN controller */
+ .modalias = "tlv5638",
+ .chip_select = 3,
+ .max_speed_hz = 20 * 1000 * 1000,
+ .mode = SPI_CPHA,
+ },
+};
+
+static void __init eco920_board_init(void)
+{
+ at91_add_device_serial();
+ at91_add_device_eth(&eco920_eth_data);
+ at91_add_device_usbh(&eco920_usbh_data);
+ at91_add_device_udc(&eco920_udc_data);
+
+ at91_add_device_mmc(0, &eco920_mmc_data);
+ platform_device_register(&eco920_flash);
+
+ at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1)
+ | AT91_SMC_RWSETUP_(1)
+ | AT91_SMC_DBW_8
+ | AT91_SMC_WSEN
+ | AT91_SMC_NWS_(15));
+
+ at91_set_A_periph(AT91_PIN_PC6, 1);
+
+ at91_set_gpio_input(AT91_PIN_PA23, 0);
+ at91_set_deglitch(AT91_PIN_PA23, 1);
+
+/* Initialization of the Static Memory Controller for Chip Select 3 */
+ at91_sys_write(AT91_SMC_CSR(3),
+ AT91_SMC_DBW_16 | /* 16 bit */
+ AT91_SMC_WSEN |
+ AT91_SMC_NWS_(5) | /* wait states */
+ AT91_SMC_TDF_(1) /* float time */
+ );
+
+ at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
+}
+
+MACHINE_START(ECO920, "eco920")
+ /* Maintainer: Sascha Hauer */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = eco920_init_early,
+ .init_irq = eco920_init_irq,
+ .init_machine = eco920_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
new file mode 100644
index 00000000..466c063b
--- /dev/null
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -0,0 +1,162 @@
+/*
+ * linux/arch/arm/mach-at91/board-flexibity.c
+ *
+ * Copyright (C) 2010 Flexibity
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+
+#include "generic.h"
+
+static void __init flexibity_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init flexibity_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+/* USB Host port */
+static struct at91_usbh_data __initdata flexibity_usbh_data = {
+ .ports = 2,
+};
+
+/* USB Device port */
+static struct at91_udc_data __initdata flexibity_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/* SPI devices */
+static struct spi_board_info flexibity_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+};
+
+/* MCI (SD/MMC) */
+static struct at91_mmc_data __initdata flexibity_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
+ .wp_pin = AT91_PIN_PC4,
+};
+
+/* LEDs */
+static struct gpio_led flexibity_leds[] = {
+ {
+ .name = "usb1:green",
+ .gpio = AT91_PIN_PA12,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb1:red",
+ .gpio = AT91_PIN_PA13,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb2:green",
+ .gpio = AT91_PIN_PB26,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb2:red",
+ .gpio = AT91_PIN_PB27,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb3:green",
+ .gpio = AT91_PIN_PC8,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb3:red",
+ .gpio = AT91_PIN_PC6,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb4:green",
+ .gpio = AT91_PIN_PB4,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "usb4:red",
+ .gpio = AT91_PIN_PB5,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ }
+};
+
+static void __init flexibity_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&flexibity_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&flexibity_udc_data);
+ /* SPI */
+ at91_add_device_spi(flexibity_spi_devices,
+ ARRAY_SIZE(flexibity_spi_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &flexibity_mmc_data);
+ /* LEDs */
+ at91_gpio_leds(flexibity_leds, ARRAY_SIZE(flexibity_leds));
+}
+
+MACHINE_START(FLEXIBITY, "Flexibity Connect")
+ /* Maintainer: Maxim Osipov */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = flexibity_init_early,
+ .init_irq = flexibity_init_irq,
+ .init_machine = flexibity_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-foxg20.c b/arch/arm/mach-at91/board-foxg20.c
new file mode 100644
index 00000000..e2d1dc9e
--- /dev/null
+++ b/arch/arm/mach-at91/board-foxg20.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ * Copyright (C) 2010 Lee McLoughlin - lee@lmmrtech.com
+ * Copyright (C) 2010 Sergio Tanzilli - tanzilli@acmesystems.it
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+#include <linux/w1-gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+/*
+ * The FOX Board G20 hardware comes as the "Netus G20" board with
+ * just the cpu, ram, dataflash and two header connectors.
+ * This is plugged into the FOX Board which provides the ethernet,
+ * usb, rtc, leds, switch, ...
+ *
+ * For more info visit: http://www.acmesystems.it/foxg20
+ */
+
+
+static void __init foxg20_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS
+ | ATMEL_UART_DTR
+ | ATMEL_UART_DSR
+ | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
+
+ /* USART3 on ttyS4. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US3, 4,
+ ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART4 on ttyS5. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+ /* USART5 on ttyS6. (Rx & Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+
+ /* Set the internal pull-up resistor on DRXD */
+ at91_set_A_periph(AT91_PIN_PB14, 1);
+
+}
+
+static void __init foxg20_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata foxg20_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata foxg20_udc_data = {
+ .vbus_pin = AT91_PIN_PC6,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info foxg20_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ {
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata foxg20_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 1,
+};
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+static struct at91_mmc_data __initdata foxg20_mmc_data = {
+ .slot_b = 1,
+ .wire4 = 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led foxg20_leds[] = {
+ { /* user led, red */
+ .name = "user_led",
+ .gpio = AT91_PIN_PC7,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ },
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button foxg20_buttons[] = {
+ {
+ .gpio = AT91_PIN_PC4,
+ .code = BTN_1,
+ .desc = "Button 1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data foxg20_button_data = {
+ .buttons = foxg20_buttons,
+ .nbuttons = ARRAY_SIZE(foxg20_buttons),
+};
+
+static struct platform_device foxg20_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &foxg20_button_data,
+ }
+};
+
+static void __init foxg20_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PC4, 1); /* btn1 */
+ at91_set_deglitch(AT91_PIN_PC4, 1);
+
+ platform_device_register(&foxg20_button_device);
+}
+#else
+static void __init foxg20_add_device_buttons(void) {}
+#endif
+
+
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+ /* If you choose to use a pin other than PB16 it needs to be 3.3V */
+ .pin = AT91_PIN_PB16,
+ .is_open_drain = 1,
+};
+
+static struct platform_device w1_device = {
+ .name = "w1-gpio",
+ .id = -1,
+ .dev.platform_data = &w1_gpio_pdata,
+};
+
+static void __init at91_add_device_w1(void)
+{
+ at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+ at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+ platform_device_register(&w1_device);
+}
+
+#endif
+
+
+static struct i2c_board_info __initdata foxg20_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50),
+ },
+};
+
+
+static void __init foxg20_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&foxg20_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&foxg20_udc_data);
+ /* SPI */
+ at91_add_device_spi(foxg20_spi_devices, ARRAY_SIZE(foxg20_spi_devices));
+ /* Ethernet */
+ at91_add_device_eth(&foxg20_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &foxg20_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(foxg20_i2c_devices, ARRAY_SIZE(foxg20_i2c_devices));
+ /* LEDs */
+ at91_gpio_leds(foxg20_leds, ARRAY_SIZE(foxg20_leds));
+ /* Push Buttons */
+ foxg20_add_device_buttons();
+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
+ at91_add_device_w1();
+#endif
+}
+
+MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20")
+ /* Maintainer: Sergio Tanzilli */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = foxg20_init_early,
+ .init_irq = foxg20_init_irq,
+ .init_machine = foxg20_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-gsia18s.c b/arch/arm/mach-at91/board-gsia18s.c
new file mode 100644
index 00000000..1d4f36b3
--- /dev/null
+++ b/arch/arm/mach-at91/board-gsia18s.c
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ * taskit GmbH
+ * 2010 Igor Plyatov <plyatov@gmail.com>
+ * GeoSIG 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/w1-gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/gsia18s.h>
+#include <mach/stamp9g20.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+static void __init gsia18s_init_early(void)
+{
+ stamp9g20_init_early();
+
+ /*
+ * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI).
+ * Used for Internal Analog Modem.
+ */
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS | ATMEL_UART_RTS |
+ ATMEL_UART_DTR | ATMEL_UART_DSR |
+ ATMEL_UART_DCD | ATMEL_UART_RI);
+ /*
+ * USART1 on ttyS2 (Rx, Tx, CTS, RTS).
+ * Used for GPS or WiFi or Data stream.
+ */
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ /*
+ * USART2 on ttyS3 (Rx, Tx, CTS, RTS).
+ * Used for External Modem.
+ */
+ at91_register_uart(AT91SAM9260_ID_US2, 3,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ /*
+ * USART3 on ttyS4 (Rx, Tx, RTS).
+ * Used for RS-485.
+ */
+ at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS);
+
+ /*
+ * USART4 on ttyS5 (Rx, Tx).
+ * Used for TRX433 Radio Module.
+ */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+}
+
+static void __init init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+/*
+ * Two USB Host ports
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata udc_data = {
+ .vbus_pin = AT91_PIN_PA22,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+ .phy_irq_pin = AT91_PIN_PA28,
+ .is_rmii = 1,
+};
+
+/*
+ * LEDs and GPOs
+ */
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "gpo:spi1reset",
+ .gpio = AT91_PIN_PC1,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:trig_net_out",
+ .gpio = AT91_PIN_PB20,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:trig_net_dir",
+ .gpio = AT91_PIN_PB19,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "gpo:charge_dis",
+ .gpio = AT91_PIN_PC2,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:event",
+ .gpio = AT91_PIN_PB17,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:lan",
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "led:error",
+ .gpio = AT91_PIN_PB16,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ }
+};
+
+static void __init gsia18s_leds_init(void)
+{
+ platform_device_register(&leds);
+}
+
+/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */
+static struct gpio_led pcf_gpio_leds1[] = {
+ { /* bit 0 */
+ .name = "gpo:hdc_power",
+ .gpio = PCF_GPIO_HDC_POWER,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 1 */
+ .name = "gpo:wifi_setup",
+ .gpio = PCF_GPIO_WIFI_SETUP,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 2 */
+ .name = "gpo:wifi_enable",
+ .gpio = PCF_GPIO_WIFI_ENABLE,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 3 */
+ .name = "gpo:wifi_reset",
+ .gpio = PCF_GPIO_WIFI_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ /* bit 4 used as GPI */
+ { /* bit 5 */
+ .name = "gpo:gps_setup",
+ .gpio = PCF_GPIO_GPS_SETUP,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 6 */
+ .name = "gpo:gps_standby",
+ .gpio = PCF_GPIO_GPS_STANDBY,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ { /* bit 7 */
+ .name = "gpo:gps_power",
+ .gpio = PCF_GPIO_GPS_POWER,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ }
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info1 = {
+ .leds = pcf_gpio_leds1,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds1),
+};
+
+static struct platform_device pcf_leds1 = {
+ .name = "leds-gpio", /* GS_IA18-CB_board */
+ .id = 1,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info1,
+ }
+};
+
+/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+static struct gpio_led pcf_gpio_leds2[] = {
+ { /* bit 0 */
+ .name = "gpo:alarm_1",
+ .gpio = PCF_GPIO_ALARM1,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 1 */
+ .name = "gpo:alarm_2",
+ .gpio = PCF_GPIO_ALARM2,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 2 */
+ .name = "gpo:alarm_3",
+ .gpio = PCF_GPIO_ALARM3,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ { /* bit 3 */
+ .name = "gpo:alarm_4",
+ .gpio = PCF_GPIO_ALARM4,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ /* bits 4, 5, 6 not used */
+ { /* bit 7 */
+ .name = "gpo:alarm_v_relay_on",
+ .gpio = PCF_GPIO_ALARM_V_RELAY_ON,
+ .active_low = 0,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info2 = {
+ .leds = pcf_gpio_leds2,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds2),
+};
+
+static struct platform_device pcf_leds2 = {
+ .name = "leds-gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info2,
+ }
+};
+
+/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+static struct gpio_led pcf_gpio_leds3[] = {
+ { /* bit 0 */
+ .name = "gpo:modem_power",
+ .gpio = PCF_GPIO_MODEM_POWER,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ /* bits 1 and 2 not used */
+ { /* bit 3 */
+ .name = "gpo:modem_reset",
+ .gpio = PCF_GPIO_MODEM_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ /* bits 4, 5 and 6 not used */
+ { /* bit 7 */
+ .name = "gpo:trx_reset",
+ .gpio = PCF_GPIO_TRX_RESET,
+ .active_low = 1,
+ .default_trigger = "none",
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data pcf_gpio_led_info3 = {
+ .leds = pcf_gpio_leds3,
+ .num_leds = ARRAY_SIZE(pcf_gpio_leds3),
+};
+
+static struct platform_device pcf_leds3 = {
+ .name = "leds-gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &pcf_gpio_led_info3,
+ }
+};
+
+static void __init gsia18s_pcf_leds_init(void)
+{
+ platform_device_register(&pcf_leds1);
+ platform_device_register(&pcf_leds2);
+ platform_device_register(&pcf_leds3);
+}
+
+/*
+ * SPI busses.
+ */
+static struct spi_board_info gsia18s_spi_devices[] = {
+ { /* User accessible spi0, cs0 used for communication with MSP RTC */
+ .modalias = "spidev",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 580000,
+ .mode = SPI_MODE_1,
+ },
+ { /* User accessible spi1, cs0 used for communication with int. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs1 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs2 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ },
+ { /* User accessible spi1, cs3 used for communication with ext. DSP */
+ .modalias = "spidev",
+ .bus_num = 1,
+ .chip_select = 3,
+ .max_speed_hz = 5600000,
+ .mode = SPI_MODE_0,
+ }
+};
+
+/*
+ * GPI Buttons
+ */
+static struct gpio_keys_button buttons[] = {
+ {
+ .gpio = GPIO_TRIG_NET_IN,
+ .code = BTN_1,
+ .desc = "TRIG_NET_IN",
+ .type = EV_KEY,
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ { /* SW80 on the GS_IA18_S-MN board*/
+ .gpio = GPIO_CARD_UNMOUNT_0,
+ .code = BTN_2,
+ .desc = "Card umount 0",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ { /* SW79 on the GS_IA18_S-MN board*/
+ .gpio = GPIO_CARD_UNMOUNT_1,
+ .code = BTN_3,
+ .desc = "Card umount 1",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ { /* SW280 on the GS_IA18-CB board*/
+ .gpio = GPIO_KEY_POWER,
+ .code = KEY_POWER,
+ .desc = "Power Off Button",
+ .type = EV_KEY,
+ .active_low = 0,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data button_data = {
+ .buttons = buttons,
+ .nbuttons = ARRAY_SIZE(buttons),
+};
+
+static struct platform_device button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &button_data,
+ }
+};
+
+static void __init gsia18s_add_device_buttons(void)
+{
+ at91_set_gpio_input(GPIO_TRIG_NET_IN, 1);
+ at91_set_deglitch(GPIO_TRIG_NET_IN, 1);
+ at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1);
+ at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1);
+ at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1);
+ at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1);
+ at91_set_gpio_input(GPIO_KEY_POWER, 0);
+ at91_set_deglitch(GPIO_KEY_POWER, 1);
+
+ platform_device_register(&button_device);
+}
+
+/*
+ * I2C
+ */
+static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *context)
+{
+ int status;
+
+ status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det");
+ if (status < 0) {
+ pr_err("error: can't request GPIO%d\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT);
+ if (status < 0) {
+ pr_err("error: can't setup GPIO%d as input\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false);
+ if (status < 0) {
+ pr_err("error: can't export GPIO%d\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+ status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1);
+ if (status < 0) {
+ pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n",
+ gpio + PCF_GPIO_ETH_DETECT);
+ return status;
+ }
+
+ return 0;
+}
+
+static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *context)
+{
+ gpio_free(gpio + PCF_GPIO_ETH_DETECT);
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf20_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE0,
+ .n_latch = (1 << 4),
+ .setup = pcf8574x_0x20_setup,
+ .teardown = pcf8574x_0x20_teardown,
+};
+
+static struct pcf857x_platform_data pcf22_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE1,
+};
+
+static struct pcf857x_platform_data pcf24_pdata = {
+ .gpio_base = GS_IA18_S_PCF_GPIO_BASE2,
+};
+
+static struct i2c_board_info __initdata gsia18s_i2c_devices[] = {
+ { /* U1 on the GS_IA18-CB_V3 board */
+ I2C_BOARD_INFO("pcf8574", 0x20),
+ .platform_data = &pcf20_pdata,
+ },
+ { /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+ I2C_BOARD_INFO("pcf8574", 0x22),
+ .platform_data = &pcf22_pdata,
+ },
+ { /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+ I2C_BOARD_INFO("pcf8574", 0x24),
+ .platform_data = &pcf24_pdata,
+ },
+ { /* U161 on the GS_IA18_S-MN board */
+ I2C_BOARD_INFO("24c1024", 0x50),
+ },
+ { /* U162 on the GS_IA18_S-MN board */
+ I2C_BOARD_INFO("24c01", 0x53),
+ },
+};
+
+/*
+ * Compact Flash
+ */
+static struct at91_cf_data __initdata gsia18s_cf1_data = {
+ .irq_pin = AT91_PIN_PA27,
+ .det_pin = AT91_PIN_PB30,
+ .rst_pin = AT91_PIN_PB31,
+ .chipselect = 5,
+ .flags = AT91_CF_TRUE_IDE,
+};
+
+/* Power Off by RTC */
+static void gsia18s_power_off(void)
+{
+ pr_notice("Power supply will be switched off automatically now or after 60 seconds without ArmDAS.\n");
+ at91_set_gpio_output(AT91_PIN_PA25, 1);
+ /* Spin to death... */
+ while (1)
+ ;
+}
+
+static int __init gsia18s_power_off_init(void)
+{
+ pm_power_off = gsia18s_power_off;
+ return 0;
+}
+
+/* ---------------------------------------------------------------------------*/
+
+static void __init gsia18s_board_init(void)
+{
+ stamp9g20_board_init();
+ at91_add_device_usbh(&usbh_data);
+ at91_add_device_udc(&udc_data);
+ at91_add_device_eth(&macb_data);
+ gsia18s_leds_init();
+ gsia18s_pcf_leds_init();
+ gsia18s_add_device_buttons();
+ at91_add_device_i2c(gsia18s_i2c_devices,
+ ARRAY_SIZE(gsia18s_i2c_devices));
+ at91_add_device_cf(&gsia18s_cf1_data);
+ at91_add_device_spi(gsia18s_spi_devices,
+ ARRAY_SIZE(gsia18s_spi_devices));
+ gsia18s_power_off_init();
+}
+
+MACHINE_START(GSIA18S, "GS_IA18_S")
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = gsia18s_init_early,
+ .init_irq = init_irq,
+ .init_machine = gsia18s_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
new file mode 100644
index 00000000..9b003ff7
--- /dev/null
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -0,0 +1,106 @@
+/*
+ * linux/arch/arm/mach-at91/board-kafa.c
+ *
+ * Copyright (C) 2006 Sperry-Sun
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+
+static void __init kafa_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* Set up the LEDs */
+ at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init kafa_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata kafa_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata kafa_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_udc_data __initdata kafa_udc_data = {
+ .vbus_pin = AT91_PIN_PB6,
+ .pullup_pin = AT91_PIN_PB7,
+};
+
+static void __init kafa_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&kafa_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&kafa_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&kafa_udc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(NULL, 0);
+}
+
+MACHINE_START(KAFA, "Sperry-Sun KAFA")
+ /* Maintainer: Sergei Sharonov */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = kafa_init_early,
+ .init_irq = kafa_init_irq,
+ .init_machine = kafa_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
new file mode 100644
index 00000000..a813a74b
--- /dev/null
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -0,0 +1,147 @@
+/*
+ * linux/arch/arm/mach-at91/board-kb9202.c
+ *
+ * Copyright (c) 2005 kb_admin
+ * KwikByte, 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/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init kb9202_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 10 MHz crystal */
+ at91rm9200_initialize(10000000);
+
+ /* Set up the LEDs */
+ at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1 (Rx & Tx only) */
+ at91_register_uart(AT91RM9200_ID_US0, 1, 0);
+
+ /* USART1 on ttyS2 (Rx & Tx only) - IRDA (optional) */
+ at91_register_uart(AT91RM9200_ID_US1, 2, 0);
+
+ /* USART3 on ttyS3 (Rx, Tx, CTS, RTS) - RS485 (optional) */
+ at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init kb9202_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata kb9202_eth_data = {
+ .phy_irq_pin = AT91_PIN_PB29,
+ .is_rmii = 0,
+};
+
+static struct at91_usbh_data __initdata kb9202_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_udc_data __initdata kb9202_udc_data = {
+ .vbus_pin = AT91_PIN_PB24,
+ .pullup_pin = AT91_PIN_PB22,
+};
+
+static struct at91_mmc_data __initdata kb9202_mmc_data = {
+ .det_pin = AT91_PIN_PB2,
+ .slot_b = 0,
+ .wire4 = 1,
+};
+
+static struct mtd_partition __initdata kb9202_nand_partition[] = {
+ {
+ .name = "nand_fs",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(kb9202_nand_partition);
+ return kb9202_nand_partition;
+}
+
+static struct atmel_nand_data __initdata kb9202_nand_data = {
+ .ale = 22,
+ .cle = 21,
+ // .det_pin = ... not there
+ .rdy_pin = AT91_PIN_PC29,
+ .enable_pin = AT91_PIN_PC28,
+ .partition_info = nand_partitions,
+};
+
+static void __init kb9202_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&kb9202_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&kb9202_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&kb9202_udc_data);
+ /* MMC */
+ at91_add_device_mmc(0, &kb9202_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(NULL, 0);
+ /* NAND */
+ at91_add_device_nand(&kb9202_nand_data);
+}
+
+MACHINE_START(KB9200, "KB920x")
+ /* Maintainer: KwikByte, Inc. */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = kb9202_init_early,
+ .init_irq = kb9202_init_irq,
+ .init_machine = kb9202_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-neocore926.c b/arch/arm/mach-at91/board-neocore926.c
new file mode 100644
index 00000000..961e805d
--- /dev/null
+++ b/arch/arm/mach-at91/board-neocore926.c
@@ -0,0 +1,395 @@
+/*
+ * linux/arch/arm/mach-at91/board-neocore926.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation
+ * Copyright (C) 2008 ADENEO.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init neocore926_init_early(void)
+{
+ /* Initialize processor: 20 MHz crystal */
+ at91sam9263_initialize(20000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init neocore926_init_irq(void)
+{
+ at91sam9263_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata neocore926_usbh_data = {
+ .ports = 2,
+ .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 },
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata neocore926_udc_data = {
+ .vbus_pin = AT91_PIN_PA25,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init neocore926_add_device_ts(void)
+{
+ at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */
+ at91_set_gpio_input(AT91_PIN_PC13, 1); /* Touchscreen BUSY signal */
+}
+#else
+static void __init neocore926_add_device_ts(void) {}
+#endif
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info neocore926_spi_devices[] = {
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 1,
+ .max_speed_hz = 125000 * 16,
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91SAM9263_ID_IRQ1,
+ },
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata neocore926_mmc_data = {
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PE18,
+ .wp_pin = AT91_PIN_PE19,
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata neocore926_macb_data = {
+ .phy_irq_pin = AT91_PIN_PE31,
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata neocore926_nand_partition[] = {
+ {
+ .name = "Linux Kernel", /* "Partition 1", */
+ .offset = 0,
+ .size = SZ_8M,
+ },
+ {
+ .name = "Filesystem", /* "Partition 2", */
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_32M,
+ },
+ {
+ .name = "Free", /* "Partition 3", */
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(neocore926_nand_partition);
+ return neocore926_nand_partition;
+}
+
+static struct atmel_nand_data __initdata neocore926_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PB19,
+ .rdy_pin_active_low = 1,
+ .enable_pin = AT91_PIN_PD15,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata neocore926_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 6,
+ .write_cycle = 6,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init neocore926_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &neocore926_nand_smc_config);
+
+ at91_add_device_nand(&neocore926_nand_data);
+}
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "TX09D50VM1CCA @ 60",
+ .refresh = 60,
+ .xres = 240, .yres = 320,
+ .pixclock = KHZ2PICOS(5000),
+
+ .left_margin = 1, .right_margin = 33,
+ .upper_margin = 1, .lower_margin = 0,
+ .hsync_len = 5, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "TX09D70VM1CCA",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+ at91_set_gpio_value(AT91_PIN_PA30, on);
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata neocore926_lcdc_data = {
+ .lcdcon_is_backlight = true,
+ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_power_control,
+ .guard_time = 1,
+ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB555,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata neocore926_lcdc_data;
+#endif
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button neocore926_buttons[] = {
+ { /* BP1, "leftclic" */
+ .code = BTN_LEFT,
+ .gpio = AT91_PIN_PC5,
+ .active_low = 1,
+ .desc = "left_click",
+ .wakeup = 1,
+ },
+ { /* BP2, "rightclic" */
+ .code = BTN_RIGHT,
+ .gpio = AT91_PIN_PC4,
+ .active_low = 1,
+ .desc = "right_click",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data neocore926_button_data = {
+ .buttons = neocore926_buttons,
+ .nbuttons = ARRAY_SIZE(neocore926_buttons),
+};
+
+static struct platform_device neocore926_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &neocore926_button_data,
+ }
+};
+
+static void __init neocore926_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PC5, 0); /* left button */
+ at91_set_deglitch(AT91_PIN_PC5, 1);
+ at91_set_GPIO_periph(AT91_PIN_PC4, 0); /* right button */
+ at91_set_deglitch(AT91_PIN_PC4, 1);
+
+ platform_device_register(&neocore926_button_device);
+}
+#else
+static void __init neocore926_add_device_buttons(void) {}
+#endif
+
+
+/*
+ * AC97
+ */
+static struct ac97c_platform_data neocore926_ac97_data = {
+ .reset_pin = AT91_PIN_PA13,
+};
+
+
+static void __init neocore926_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+
+ /* USB Host */
+ at91_add_device_usbh(&neocore926_usbh_data);
+
+ /* USB Device */
+ at91_add_device_udc(&neocore926_udc_data);
+
+ /* SPI */
+ at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */
+ at91_add_device_spi(neocore926_spi_devices, ARRAY_SIZE(neocore926_spi_devices));
+
+ /* Touchscreen */
+ neocore926_add_device_ts();
+
+ /* MMC */
+ at91_add_device_mmc(1, &neocore926_mmc_data);
+
+ /* Ethernet */
+ at91_add_device_eth(&neocore926_macb_data);
+
+ /* NAND */
+ neocore926_add_device_nand();
+
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+
+ /* LCD Controller */
+ at91_add_device_lcdc(&neocore926_lcdc_data);
+
+ /* Push Buttons */
+ neocore926_add_device_buttons();
+
+ /* AC97 */
+ at91_add_device_ac97(&neocore926_ac97_data);
+}
+
+MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926")
+ /* Maintainer: ADENEO */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9263_map_io,
+ .init_early = neocore926_init_early,
+ .init_irq = neocore926_init_irq,
+ .init_machine = neocore926_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c
new file mode 100644
index 00000000..21a21af2
--- /dev/null
+++ b/arch/arm/mach-at91/board-pcontrol-g20.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ * taskit GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ * copied and adjusted from board-stamp9g20.c
+ * by Peter Gsellmann <pgsellmann@portner-elektronik.at>
+ */
+
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/stamp9g20.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init pcontrol_g20_init_early(void)
+{
+ stamp9g20_init_early();
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) isolated RS485 X5 */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS
+ | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */
+ at91_register_uart(AT91SAM9260_ID_US4, 3, 0);
+}
+
+
+static void __init init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { {
+ .ncs_read_setup = 16,
+ .nrd_setup = 18,
+ .ncs_write_setup = 16,
+ .nwe_setup = 18,
+
+ .ncs_read_pulse = 63,
+ .nrd_pulse = 55,
+ .ncs_write_pulse = 63,
+ .nwe_pulse = 55,
+
+ .read_cycle = 127,
+ .write_cycle = 127,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT
+ | AT91_SMC_DBW_8 | AT91_SMC_PS_4
+ | AT91_SMC_TDFMODE,
+ .tdf_cycles = 3,
+}, {
+ .ncs_read_setup = 0,
+ .nrd_setup = 0,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 8,
+ .nrd_pulse = 8,
+ .ncs_write_pulse = 5,
+ .nwe_pulse = 4,
+
+ .read_cycle = 8,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE
+ | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_SELECT
+ | AT91_SMC_DBW_16 | AT91_SMC_PS_8
+ | AT91_SMC_TDFMODE,
+ .tdf_cycles = 1,
+} };
+
+static void __init add_device_pcontrol(void)
+{
+ /* configure chip-select 4 (IO compatible to 8051 X4 ) */
+ sam9_smc_configure(4, &pcontrol_smc_config[0]);
+ /* configure chip-select 7 (FerroRAM 256KiBx16bit MR2A16A D4 ) */
+ sam9_smc_configure(7, &pcontrol_smc_config[1]);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+ .ports = 2,
+};
+
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata pcontrol_g20_udc_data = {
+ .vbus_pin = AT91_PIN_PA22, /* Detect +5V bus voltage */
+ .pullup_pin = AT91_PIN_PA4, /* K-state, active low */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+ .phy_irq_pin = AT91_PIN_PA28,
+ .is_rmii = 1,
+};
+
+
+/*
+ * I2C devices: eeprom and phy/switch
+ */
+static struct i2c_board_info __initdata pcontrol_g20_i2c_devices[] = {
+{ /* D7 address width=2, 8KiB */
+ I2C_BOARD_INFO("24c64", 0x50)
+}, { /* D8 address width=1, 1 byte has 32 bits! */
+ I2C_BOARD_INFO("lan9303", 0x0a)
+}, };
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led pcontrol_g20_leds[] = {
+ {
+ .name = "LED1", /* red H5 */
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .default_trigger = "none", /* supervisor */
+ }, {
+ .name = "LED2", /* yellow H7 */
+ .gpio = AT91_PIN_PB19,
+ .active_low = 1,
+ .default_trigger = "mmc0", /* SD-card activity */
+ }, {
+ .name = "LED3", /* green H2 */
+ .gpio = AT91_PIN_PB20,
+ .active_low = 1,
+ .default_trigger = "heartbeat", /* blinky */
+ }, {
+ .name = "LED4", /* red H3 */
+ .gpio = AT91_PIN_PC6,
+ .active_low = 1,
+ .default_trigger = "none", /* connection lost */
+ }, {
+ .name = "LED5", /* yellow H6 */
+ .gpio = AT91_PIN_PC7,
+ .active_low = 1,
+ .default_trigger = "none", /* unsent data */
+ }, {
+ .name = "LED6", /* green H1 */
+ .gpio = AT91_PIN_PC9,
+ .active_low = 1,
+ .default_trigger = "none", /* snafu */
+ }
+};
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info pcontrol_g20_spi_devices[] = {
+ {
+ .modalias = "spidev", /* HMI port X4 */
+ .chip_select = 1,
+ .max_speed_hz = 50 * 1000 * 1000,
+ .bus_num = 0,
+ }, {
+ .modalias = "spidev", /* piggyback A2 */
+ .chip_select = 0,
+ .max_speed_hz = 50 * 1000 * 1000,
+ .bus_num = 1,
+ },
+};
+
+
+static void __init pcontrol_g20_board_init(void)
+{
+ stamp9g20_board_init();
+ at91_add_device_usbh(&usbh_data);
+ at91_add_device_eth(&macb_data);
+ at91_add_device_i2c(pcontrol_g20_i2c_devices,
+ ARRAY_SIZE(pcontrol_g20_i2c_devices));
+ add_device_pcontrol();
+ at91_add_device_spi(pcontrol_g20_spi_devices,
+ ARRAY_SIZE(pcontrol_g20_spi_devices));
+ at91_add_device_udc(&pcontrol_g20_udc_data);
+ at91_gpio_leds(pcontrol_g20_leds,
+ ARRAY_SIZE(pcontrol_g20_leds));
+ /* piggyback A2 */
+ at91_set_gpio_output(AT91_PIN_PB31, 1);
+}
+
+
+MACHINE_START(PCONTROL_G20, "PControl G20")
+ /* Maintainer: pgsellmann@portner-elektronik.at */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = pcontrol_g20_init_early,
+ .init_irq = init_irq,
+ .init_machine = pcontrol_g20_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-picotux200.c b/arch/arm/mach-at91/board-picotux200.c
new file mode 100644
index 00000000..756cc2a7
--- /dev/null
+++ b/arch/arm/mach-at91/board-picotux200.c
@@ -0,0 +1,131 @@
+/*
+ * linux/arch/arm/mach-at91/board-picotux200.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Kleinhenz Elektronik GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init picotux200_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init picotux200_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata picotux200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata picotux200_usbh_data = {
+ .ports = 1,
+};
+
+static struct at91_mmc_data __initdata picotux200_mmc_data = {
+ .det_pin = AT91_PIN_PB27,
+ .slot_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PA17,
+};
+
+#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0
+#define PICOTUX200_FLASH_SIZE SZ_4M
+
+static struct physmap_flash_data picotux200_flash_data = {
+ .width = 2,
+};
+
+static struct resource picotux200_flash_resource = {
+ .start = PICOTUX200_FLASH_BASE,
+ .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device picotux200_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &picotux200_flash_data,
+ },
+ .resource = &picotux200_flash_resource,
+ .num_resources = 1,
+};
+
+static void __init picotux200_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&picotux200_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&picotux200_usbh_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+ at91_add_device_mmc(0, &picotux200_mmc_data);
+ /* NOR Flash */
+ platform_device_register(&picotux200_flash);
+}
+
+MACHINE_START(PICOTUX2XX, "picotux 200")
+ /* Maintainer: Kleinhenz Elektronik GmbH */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = picotux200_init_early,
+ .init_irq = picotux200_init_irq,
+ .init_machine = picotux200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-qil-a9260.c b/arch/arm/mach-at91/board-qil-a9260.c
new file mode 100644
index 00000000..d1a6001b
--- /dev/null
+++ b/arch/arm/mach-at91/board-qil-a9260.c
@@ -0,0 +1,276 @@
+/*
+ * linux/arch/arm/mach-at91/board-qil-a9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9260_initialize(12000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS1 (ie, USART0) */
+ at91_set_serial_console(1);
+
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if defined(CONFIG_RTC_DRV_M41T94)
+ { /* M41T94 RTC */
+ .modalias = "m41t94",
+ .chip_select = 0,
+ .max_speed_hz = 1 * 1000 * 1000,
+ .bus_num = 0,
+ }
+#endif
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Uboot & Kernel",
+ .offset = 0,
+ .size = SZ_16M,
+ },
+ {
+ .name = "Root FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ },
+ {
+ .name = "FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+// .det_pin = ... not connected
+// .wp_pin = ... not connected
+// .vcc_pin = ... not connected
+};
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(QIL_A9260, "CALAO QIL_A9260")
+ /* Maintainer: calao-systems */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c
new file mode 100644
index 00000000..aef96277
--- /dev/null
+++ b/arch/arm/mach-at91/board-rm9200dk.c
@@ -0,0 +1,235 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200dk.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * Epson S1D framebuffer glue code is:
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init dk_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init dk_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata dk_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata dk_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata dk_udc_data = {
+ .vbus_pin = AT91_PIN_PD4,
+ .pullup_pin = AT91_PIN_PD5,
+};
+
+static struct at91_cf_data __initdata dk_cf_data = {
+ .det_pin = AT91_PIN_PB0,
+ .rst_pin = AT91_PIN_PC5,
+ // .irq_pin = ... not connected
+ // .vcc_pin = ... always powered
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata dk_mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+};
+#endif
+
+static struct spi_board_info dk_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ },
+ { /* UR6HCPS2-SP40 PS2-to-SPI adapter */
+ .modalias = "ur6hcps2",
+ .chip_select = 1,
+ .max_speed_hz = 250 * 1000,
+ },
+ { /* TLV1504 ADC, 4 channels, 10 bits; one is a temp sensor */
+ .modalias = "tlv1504",
+ .chip_select = 2,
+ .max_speed_hz = 20 * 1000 * 1000,
+ },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 3,
+ .max_speed_hz = 15 * 1000 * 1000,
+ }
+#endif
+};
+
+static struct i2c_board_info __initdata dk_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ics1523", 0x26),
+ },
+ {
+ I2C_BOARD_INFO("x9429", 0x28),
+ },
+ {
+ I2C_BOARD_INFO("24c1024", 0x50),
+ }
+};
+
+static struct mtd_partition __initdata dk_nand_partition[] = {
+ {
+ .name = "NAND Partition 1",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(dk_nand_partition);
+ return dk_nand_partition;
+}
+
+static struct atmel_nand_data __initdata dk_nand_data = {
+ .ale = 22,
+ .cle = 21,
+ .det_pin = AT91_PIN_PB1,
+ .rdy_pin = AT91_PIN_PC2,
+ // .enable_pin = ... not there
+ .partition_info = nand_partitions,
+};
+
+#define DK_FLASH_BASE AT91_CHIPSELECT_0
+#define DK_FLASH_SIZE SZ_2M
+
+static struct physmap_flash_data dk_flash_data = {
+ .width = 2,
+};
+
+static struct resource dk_flash_resource = {
+ .start = DK_FLASH_BASE,
+ .end = DK_FLASH_BASE + DK_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device dk_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &dk_flash_data,
+ },
+ .resource = &dk_flash_resource,
+ .num_resources = 1,
+};
+
+static struct gpio_led dk_leds[] = {
+ {
+ .name = "led0",
+ .gpio = AT91_PIN_PB2,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static void __init dk_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&dk_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&dk_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&dk_udc_data);
+ at91_set_multi_drive(dk_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
+ /* Compact Flash */
+ at91_add_device_cf(&dk_cf_data);
+ /* I2C */
+ at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));
+ /* SPI */
+ at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+ /* DataFlash card */
+ at91_set_gpio_output(AT91_PIN_PB7, 0);
+#else
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+ at91_add_device_mmc(0, &dk_mmc_data);
+#endif
+ /* NAND */
+ at91_add_device_nand(&dk_nand_data);
+ /* NOR Flash */
+ platform_device_register(&dk_flash);
+ /* LEDs */
+ at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));
+ /* VGA */
+// dk_add_device_video();
+}
+
+MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
+ /* Maintainer: SAN People/Atmel */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = dk_init_early,
+ .init_irq = dk_init_irq,
+ .init_machine = dk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-rm9200ek.c b/arch/arm/mach-at91/board-rm9200ek.c
new file mode 100644
index 00000000..015a0218
--- /dev/null
+++ b/arch/arm/mach-at91/board-rm9200ek.c
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/arm/mach-at91/board-rm9200ek.c
+ *
+ * Copyright (C) 2005 SAN People
+ *
+ * Epson S1D framebuffer glue code is:
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata ek_eth_data = {
+ .phy_irq_pin = AT91_PIN_PC4,
+ .is_rmii = 1,
+};
+
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PD4,
+ .pullup_pin = AT91_PIN_PD5,
+};
+
+#ifndef CONFIG_MTD_AT91_DATAFLASH_CARD
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .det_pin = AT91_PIN_PB27,
+ .slot_b = 0,
+ .wire4 = 1,
+ .wp_pin = AT91_PIN_PA17,
+};
+#endif
+
+static struct spi_board_info ek_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ },
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 3,
+ .max_speed_hz = 15 * 1000 * 1000,
+ },
+#endif
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ics1523", 0x26),
+ },
+ {
+ I2C_BOARD_INFO("dac3550", 0x4d),
+ }
+};
+
+#define EK_FLASH_BASE AT91_CHIPSELECT_0
+#define EK_FLASH_SIZE SZ_2M
+
+static struct physmap_flash_data ek_flash_data = {
+ .width = 2,
+};
+
+static struct resource ek_flash_resource = {
+ .start = EK_FLASH_BASE,
+ .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ek_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ek_flash_data,
+ },
+ .resource = &ek_flash_resource,
+ .num_resources = 1,
+};
+
+static struct gpio_led ek_leds[] = {
+ { /* "user led 1", DS2 */
+ .name = "green",
+ .gpio = AT91_PIN_PB0,
+ .active_low = 1,
+ .default_trigger = "mmc0",
+ },
+ { /* "user led 2", DS4 */
+ .name = "yellow",
+ .gpio = AT91_PIN_PB1,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* "user led 3", DS6 */
+ .name = "red",
+ .gpio = AT91_PIN_PB2,
+ .active_low = 1,
+ }
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&ek_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ at91_set_multi_drive(ek_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
+ /* I2C */
+ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
+ /* DataFlash card */
+ at91_set_gpio_output(AT91_PIN_PB22, 0);
+#else
+ /* MMC */
+ at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+ /* NOR Flash */
+ platform_device_register(&ek_flash);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* VGA */
+// ek_add_device_video();
+}
+
+MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
+ /* Maintainer: SAN People/Atmel */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9-l9260.c b/arch/arm/mach-at91/board-sam9-l9260.c
new file mode 100644
index 00000000..aaf1bf09
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9-l9260.c
@@ -0,0 +1,220 @@
+/*
+ * linux/arch/arm/mach-at91/board-sam9-l9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Olimex 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PA9, AT91_PIN_PA6);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 0,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Bootloader Area",
+ .offset = 0,
+ .size = 10 * SZ_1M,
+ },
+ {
+ .name = "User Area",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 1,
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PC8,
+ .wp_pin = AT91_PIN_PC4,
+// .vcc_pin = ... not connected
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* NAND */
+ ek_add_device_nand();
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+}
+
+MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
+ /* Maintainer: Olimex */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
new file mode 100644
index 00000000..5c240743
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/arm/mach-at91/board-sam9260ek.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+ .ssc_id = 0,
+ .shortname = "AT91SAM9260-EK external DAC",
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+ struct clk *pck0;
+ struct clk *plla;
+
+ pck0 = clk_get(NULL, "pck0");
+ plla = clk_get(NULL, "plla");
+
+ /* AT73C213 MCK Clock */
+ at91_set_B_periph(AT91_PIN_PC1, 0); /* PCK0 */
+
+ clk_set_parent(pck0, plla);
+ clk_put(plla);
+
+ info->dac_clk = pck0;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#endif
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+ { /* AT73C213 DAC */
+ .modalias = "at73c213",
+ .chip_select = 0,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 1,
+ .mode = SPI_MODE_1,
+ .platform_data = &at73c213_data,
+ },
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Partition 1",
+ .offset = 0,
+ .size = SZ_256K,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 1,
+ .wire4 = 1,
+// .det_pin = ... not connected
+// .wp_pin = ... not connected
+// .vcc_pin = ... not connected
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds5",
+ .gpio = AT91_PIN_PA6,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA9,
+ .default_trigger = "heartbeat",
+ }
+};
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c512 = {
+ .byte_len = SZ_512K / 8,
+ .page_size = 128,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50),
+ .platform_data = &at24c512,
+ },
+ /* more devices can be added using expansion connectors */
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ {
+ .gpio = AT91_PIN_PA30,
+ .code = BTN_3,
+ .desc = "Button 3",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA31,
+ .code = BTN_4,
+ .desc = "Button 4",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */
+ at91_set_deglitch(AT91_PIN_PA30, 1);
+ at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */
+ at91_set_deglitch(AT91_PIN_PA31, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* NAND */
+ ek_add_device_nand();
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* I2C */
+ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ /* SSC (to AT73C213) */
+ at73c213_set_clk(&at73c213_data);
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* Push Buttons */
+ ek_add_device_buttons();
+}
+
+MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
new file mode 100644
index 00000000..b60c22b6
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -0,0 +1,628 @@
+/*
+ * linux/arch/arm/mach-at91/board-sam9261ek.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/at73c213.h>
+#include <linux/clk.h>
+#include <linux/dm9000.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9261_initialize(18432000);
+
+ /* Setup the LEDs */
+ at91_init_leds(AT91_PIN_PA13, AT91_PIN_PA14);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9261_init_interrupts(NULL);
+}
+
+
+/*
+ * DM9000 ethernet device
+ */
+#if defined(CONFIG_DM9000)
+static struct resource dm9000_resource[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_2,
+ .end = AT91_CHIPSELECT_2 + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = AT91_CHIPSELECT_2 + 0x44,
+ .end = AT91_CHIPSELECT_2 + 0xFF,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = AT91_PIN_PC11,
+ .end = AT91_PIN_PC11,
+ .flags = IORESOURCE_IRQ
+ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+};
+
+static struct platform_device dm9000_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000_resource),
+ .resource = dm9000_resource,
+ .dev = {
+ .platform_data = &dm9000_platdata,
+ }
+};
+
+/*
+ * SMC timings for the DM9000.
+ * Note: These timings were calculated for MASTER_CLOCK = 100000000 according to the DM9000 timings.
+ */
+static struct sam9_smc_config __initdata dm9000_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 8,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 8,
+ .nwe_pulse = 4,
+
+ .read_cycle = 16,
+ .write_cycle = 16,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16,
+ .tdf_cycles = 1,
+};
+
+static void __init ek_add_device_dm9000(void)
+{
+ /* Configure chip-select 2 (DM9000) */
+ sam9_smc_configure(2, &dm9000_smc_config);
+
+ /* Configure Reset signal as output */
+ at91_set_gpio_output(AT91_PIN_PC10, 0);
+
+ /* Configure Interrupt pin as input, no pull-up */
+ at91_set_gpio_input(AT91_PIN_PC11, 0);
+
+ platform_device_register(&dm9000_device);
+}
+#else
+static void __init ek_add_device_dm9000(void) {}
+#endif /* CONFIG_DM9000 */
+
+
+/*
+ * USB Host Port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+
+/*
+ * USB Device Port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PB29,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Partition 1",
+ .offset = 0,
+ .size = SZ_256K,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 22,
+ .cle = 21,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC15,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+/*
+ * SPI related devices
+ */
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+ at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */
+ at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
+/*
+ * Audio
+ */
+static struct at73c213_board_info at73c213_data = {
+ .ssc_id = 1,
+#if defined(CONFIG_MACH_AT91SAM9261EK)
+ .shortname = "AT91SAM9261-EK external DAC",
+#else
+ .shortname = "AT91SAM9G10-EK external DAC",
+#endif
+};
+
+#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+static void __init at73c213_set_clk(struct at73c213_board_info *info)
+{
+ struct clk *pck2;
+ struct clk *plla;
+
+ pck2 = clk_get(NULL, "pck2");
+ plla = clk_get(NULL, "plla");
+
+ /* AT73C213 MCK Clock */
+ at91_set_B_periph(AT91_PIN_PB31, 0); /* PCK2 */
+
+ clk_set_parent(pck2, plla);
+ clk_put(plla);
+
+ info->dac_clk = pck2;
+}
+#else
+static void __init at73c213_set_clk(struct at73c213_board_info *info) {}
+#endif
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info ek_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 2,
+ .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91SAM9261_ID_IRQ0,
+ .controller_data = (void *) AT91_PIN_PA28, /* CS pin */
+ },
+#endif
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */
+ .modalias = "mtd_dataflash",
+ .chip_select = 3,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
+ { /* AT73C213 DAC */
+ .modalias = "at73c213",
+ .chip_select = 3,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .mode = SPI_MODE_1,
+ .platform_data = &at73c213_data,
+ .controller_data = (void*) AT91_PIN_PA29, /* default for CS3 is PA6, but it must be PA29 */
+ },
+#endif
+};
+
+#else /* CONFIG_SPI_ATMEL_* */
+/* spi0 and mmc/sd share the same PIO pins: cannot be used at the same time */
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .wire4 = 1,
+};
+
+#endif /* CONFIG_SPI_ATMEL_* */
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+
+#if defined(CONFIG_FB_ATMEL_STN)
+
+/* STN */
+static struct fb_videomode at91_stn_modes[] = {
+ {
+ .name = "SP06Q002 @ 75",
+ .refresh = 75,
+ .xres = 320, .yres = 240,
+ .pixclock = KHZ2PICOS(1440),
+
+ .left_margin = 1, .right_margin = 1,
+ .upper_margin = 0, .lower_margin = 0,
+ .hsync_len = 1, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_stn_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "SP06Q002",
+
+ .modedb = at91_stn_modes,
+ .modedb_len = ARRAY_SIZE(at91_stn_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91SAM9261_DEFAULT_STN_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_STNMONO \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE \
+ | ATMEL_LCDC_IFWIDTH_4 \
+ | ATMEL_LCDC_SCANMOD_SINGLE)
+
+static void at91_lcdc_stn_power_control(int on)
+{
+ /* backlight */
+ if (on) { /* power up */
+ at91_set_gpio_value(AT91_PIN_PC14, 0);
+ at91_set_gpio_value(AT91_PIN_PC15, 0);
+ } else { /* power down */
+ at91_set_gpio_value(AT91_PIN_PC14, 1);
+ at91_set_gpio_value(AT91_PIN_PC15, 1);
+ }
+}
+
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .default_bpp = 1,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9261_DEFAULT_STN_LCDCON2,
+ .default_monspecs = &at91fb_default_stn_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_stn_power_control,
+ .guard_time = 1,
+#if defined(CONFIG_MACH_AT91SAM9G10EK)
+ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
+#endif
+};
+
+#else
+
+/* TFT */
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "TX09D50VM1CCA @ 60",
+ .refresh = 60,
+ .xres = 240, .yres = 320,
+ .pixclock = KHZ2PICOS(4965),
+
+ .left_margin = 1, .right_margin = 33,
+ .upper_margin = 1, .lower_margin = 0,
+ .hsync_len = 5, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_tft_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "TX09D50VM1CCA",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91SAM9261_DEFAULT_TFT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_tft_power_control(int on)
+{
+ if (on)
+ at91_set_gpio_value(AT91_PIN_PA12, 0); /* power up */
+ else
+ at91_set_gpio_value(AT91_PIN_PA12, 1); /* power down */
+}
+
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .lcdcon_is_backlight = true,
+ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2,
+ .default_monspecs = &at91fb_default_tft_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_tft_power_control,
+ .guard_time = 1,
+#if defined(CONFIG_MACH_AT91SAM9G10EK)
+ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
+#endif
+};
+#endif
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ {
+ .gpio = AT91_PIN_PA27,
+ .code = BTN_0,
+ .desc = "Button 0",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA26,
+ .code = BTN_1,
+ .desc = "Button 1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA25,
+ .code = BTN_2,
+ .desc = "Button 2",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA24,
+ .code = BTN_3,
+ .desc = "Button 3",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PA27, 1); /* btn0 */
+ at91_set_deglitch(AT91_PIN_PA27, 1);
+ at91_set_gpio_input(AT91_PIN_PA26, 1); /* btn1 */
+ at91_set_deglitch(AT91_PIN_PA26, 1);
+ at91_set_gpio_input(AT91_PIN_PA25, 1); /* btn2 */
+ at91_set_deglitch(AT91_PIN_PA25, 1);
+ at91_set_gpio_input(AT91_PIN_PA24, 1); /* btn3 */
+ at91_set_deglitch(AT91_PIN_PA24, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds7",
+ .gpio = AT91_PIN_PA14,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "top" led, green, userled2 to be defined */
+ .name = "ds8",
+ .gpio = AT91_PIN_PA13,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA23,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* NAND */
+ ek_add_device_nand();
+ /* DM9000 ethernet */
+ ek_add_device_dm9000();
+
+ /* spi0 and mmc/sd share the same PIO pins */
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* Touchscreen */
+ ek_add_device_ts();
+ /* SSC (to AT73C213) */
+ at73c213_set_clk(&at73c213_data);
+ at91_add_device_ssc(AT91SAM9261_ID_SSC1, ATMEL_SSC_TX);
+#else
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+ /* LCD Controller */
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
+
+#if defined(CONFIG_MACH_AT91SAM9261EK)
+MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK")
+#else
+MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
+#endif
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9261_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
new file mode 100644
index 00000000..9bbdc92e
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -0,0 +1,459 @@
+/*
+ * linux/arch/arm/mach-at91/board-sam9263ek.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/at24.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 16.367 MHz crystal */
+ at91sam9263_initialize(16367660);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9263_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9263_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+ .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 },
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PA25,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * ADS7846 Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 450,
+ .y_plate_ohms = 250,
+ .pressure_max = 15000,
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init ek_add_device_ts(void)
+{
+ at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */
+ at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */
+}
+#else
+static void __init ek_add_device_ts(void) {}
+#endif
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .chip_select = 3,
+ .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
+ .bus_num = 0,
+ .platform_data = &ads_info,
+ .irq = AT91SAM9263_ID_IRQ1,
+ },
+#endif
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PE18,
+ .wp_pin = AT91_PIN_PE19,
+// .vcc_pin = ... not connected
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PE31,
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Partition 1",
+ .offset = 0,
+ .size = SZ_64M,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PA22,
+ .enable_pin = AT91_PIN_PD15,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c512 = {
+ .byte_len = SZ_512K / 8,
+ .page_size = 128,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50),
+ .platform_data = &at24c512,
+ },
+ /* more devices can be added using expansion connectors */
+};
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "TX09D50VM1CCA @ 60",
+ .refresh = 60,
+ .xres = 240, .yres = 320,
+ .pixclock = KHZ2PICOS(4965),
+
+ .left_margin = 1, .right_margin = 33,
+ .upper_margin = 1, .lower_margin = 0,
+ .hsync_len = 5, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "TX09D70VM1CCA",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91SAM9263_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+ at91_set_gpio_value(AT91_PIN_PA30, on);
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .lcdcon_is_backlight = true,
+ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_power_control,
+ .guard_time = 1,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* BP1, "leftclic" */
+ .code = BTN_LEFT,
+ .gpio = AT91_PIN_PC5,
+ .active_low = 1,
+ .desc = "left_click",
+ .wakeup = 1,
+ },
+ { /* BP2, "rightclic" */
+ .code = BTN_RIGHT,
+ .gpio = AT91_PIN_PC4,
+ .active_low = 1,
+ .desc = "right_click",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PC5, 1); /* left button */
+ at91_set_deglitch(AT91_PIN_PC5, 1);
+ at91_set_GPIO_periph(AT91_PIN_PC4, 1); /* right button */
+ at91_set_deglitch(AT91_PIN_PC4, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+/*
+ * AC97
+ * reset_pin is not connected: NRST
+ */
+static struct ac97c_platform_data ek_ac97_data = {
+};
+
+
+/*
+ * LEDs ... these could all be PWM-driven, for variable brightness
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "right" led, green, userled2 (could be driven by pwm2) */
+ .name = "ds2",
+ .gpio = AT91_PIN_PC29,
+ .active_low = 1,
+ .default_trigger = "nand-disk",
+ },
+ { /* "power" led, yellow (could be driven by pwm0) */
+ .name = "ds3",
+ .gpio = AT91_PIN_PB7,
+ .default_trigger = "heartbeat",
+ }
+};
+
+/*
+ * PWM Leds
+ */
+static struct gpio_led ek_pwm_led[] = {
+ /* For now only DS1 is PWM-driven (by pwm1) */
+ {
+ .name = "ds1",
+ .gpio = 1, /* is PWM channel number */
+ .active_low = 1,
+ .default_trigger = "none",
+ }
+};
+
+/*
+ * CAN
+ */
+static void sam9263ek_transceiver_switch(int on)
+{
+ if (on) {
+ at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */
+ at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */
+ } else {
+ at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */
+ at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */
+ }
+}
+
+static struct at91_can_data ek_can_data = {
+ .transceiver_switch = sam9263ek_transceiver_switch,
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* Touchscreen */
+ ek_add_device_ts();
+ /* MMC */
+ at91_add_device_mmc(1, &ek_mmc_data);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ /* LCD Controller */
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* AC97 */
+ at91_add_device_ac97(&ek_ac97_data);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+ /* CAN */
+ at91_add_device_can(&ek_can_data);
+}
+
+MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9263_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
new file mode 100644
index 00000000..1325a501
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/at73c213.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+/*
+ * board revision encoding
+ * bit 0:
+ * 0 => 1 sd/mmc slot
+ * 1 => 2 sd/mmc slots connectors (board from revision C)
+ */
+#define HAVE_2MMC (1 << 0)
+static int inline ek_have_2mmc(void)
+{
+ return machine_is_at91sam9g20ek_2mmc() || (system_rev & HAVE_2MMC);
+}
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 1,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
+ { /* DataFlash card */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+#endif
+#endif
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
+ .is_rmii = 1,
+};
+
+static void __init ek_add_device_macb(void)
+{
+ if (ek_have_2mmc())
+ ek_macb_data.phy_irq_pin = AT91_PIN_PB0;
+
+ at91_add_device_eth(&ek_macb_data);
+}
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Bootstrap",
+ .offset = 0,
+ .size = 4 * SZ_1M,
+ },
+ {
+ .name = "Partition 1",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 60 * SZ_1M,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+/* det_pin is not connected */
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 3,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * wp_pin and vcc_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata ek_mmc_data = {
+ .slot[1] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PC9,
+ },
+
+};
+#else
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .slot_b = 1, /* Only one slot so use slot B */
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PC9,
+};
+#endif
+
+static void __init ek_add_device_mmc(void)
+{
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ if (ek_have_2mmc()) {
+ ek_mmc_data.slot[0].bus_width = 4;
+ ek_mmc_data.slot[0].detect_pin = AT91_PIN_PC2;
+ }
+ at91_add_device_mci(0, &ek_mmc_data);
+#else
+ at91_add_device_mmc(0, &ek_mmc_data);
+#endif
+}
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds5",
+ .gpio = AT91_PIN_PA6,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds1",
+ .gpio = AT91_PIN_PA9,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static void __init ek_add_device_gpio_leds(void)
+{
+ if (ek_have_2mmc()) {
+ ek_leds[0].gpio = AT91_PIN_PB8;
+ ek_leds[1].gpio = AT91_PIN_PB9;
+ }
+
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+}
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ {
+ .gpio = AT91_PIN_PA30,
+ .code = BTN_3,
+ .desc = "Button 3",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PA31,
+ .code = BTN_4,
+ .desc = "Button 4",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PA30, 1); /* btn3 */
+ at91_set_deglitch(AT91_PIN_PA30, 1);
+ at91_set_gpio_input(AT91_PIN_PA31, 1); /* btn4 */
+ at91_set_deglitch(AT91_PIN_PA31, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("HPVDD", "0-001b"),
+ REGULATOR_SUPPLY("DBVDD", "0-001b"),
+ REGULATOR_SUPPLY("DCVDD", "0-001b"),
+};
+
+static struct regulator_init_data ek_avdd_reg_init_data = {
+ .constraints = {
+ .name = "3V3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .consumer_supplies = ek_audio_consumer_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config ek_vdd_pdata = {
+ .supply_name = "board-3V3",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 0,
+ .init_data = &ek_avdd_reg_init_data,
+};
+static struct platform_device ek_voltage_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_vdd_pdata,
+ },
+};
+static void __init ek_add_regulators(void)
+{
+ platform_device_register(&ek_voltage_regulator);
+}
+#else
+static void __init ek_add_regulators(void) {}
+#endif
+
+
+static struct i2c_board_info __initdata ek_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c512", 0x50)
+ },
+ {
+ I2C_BOARD_INFO("wm8731", 0x1b)
+ },
+};
+
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* NAND */
+ ek_add_device_nand();
+ /* Ethernet */
+ ek_add_device_macb();
+ /* Regulators */
+ ek_add_regulators();
+ /* MMC */
+ ek_add_device_mmc();
+ /* I2C */
+ at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
+ /* LEDs */
+ ek_add_device_gpio_leds();
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* PCK0 provides MCLK to the WM8731 */
+ at91_set_B_periph(AT91_PIN_PC1, 0);
+ /* SSC (for WM8731) */
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, ATMEL_SSC_TX);
+}
+
+MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
+
+MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
new file mode 100644
index 00000000..33eaa135
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -0,0 +1,429 @@
+/*
+ * Board-specific setup code for the AT91SAM9M10G45 Evaluation Kit family
+ *
+ * Covers: * AT91SAM9G45-EKES board
+ * * AT91SAM9M10G45-EK board
+ *
+ * Copyright (C) 2009 Atmel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/fb.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+#include <linux/atmel-mci.h>
+
+#include <mach/hardware.h>
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9g45_initialize(12000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 not connected on the -EK board */
+ /* USART1 on ttyS2. (Rx, Tx, RTS, CTS) */
+ at91_register_uart(AT91SAM9G45_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9g45_init_interrupts(NULL);
+}
+
+
+/*
+ * USB HS Host port (common to OHCI & EHCI)
+ */
+static struct at91_usbh_data __initdata ek_usbh_hs_data = {
+ .ports = 2,
+ .vbus_pin = {AT91_PIN_PD1, AT91_PIN_PD3},
+};
+
+
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata ek_usba_udc_data = {
+ .vbus_pin = AT91_PIN_PB19,
+};
+
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct mci_platform_data __initdata mci0_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PD10,
+ },
+};
+
+static struct mci_platform_data __initdata mci1_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ .detect_pin = AT91_PIN_PD11,
+ .wp_pin = AT91_PIN_PD29,
+ },
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PD5,
+ .is_rmii = 1,
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Partition 1",
+ .offset = 0,
+ .size = SZ_64M,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+/* det_pin is not connected */
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC8,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 3,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "LG",
+ .refresh = 60,
+ .xres = 480, .yres = 272,
+ .pixclock = KHZ2PICOS(9000),
+
+ .left_margin = 1, .right_margin = 1,
+ .upper_margin = 40, .lower_margin = 1,
+ .hsync_len = 45, .vsync_len = 1,
+
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "LG",
+ .monitor = "LB043WQ1",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 17640,
+ .vfmin = 57,
+ .vfmax = 67,
+};
+
+#define AT91SAM9G45_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .lcdcon_is_backlight = true,
+ .default_bpp = 32,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9G45_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+ .guard_time = 9,
+ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+ .adc_clock = 300000,
+ .pendet_debounce = 0x0d,
+ .ts_sample_hold_time = 0x0a,
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* BP1, "leftclic" */
+ .code = BTN_LEFT,
+ .gpio = AT91_PIN_PB6,
+ .active_low = 1,
+ .desc = "left_click",
+ .wakeup = 1,
+ },
+ { /* BP2, "rightclic" */
+ .code = BTN_RIGHT,
+ .gpio = AT91_PIN_PB7,
+ .active_low = 1,
+ .desc = "right_click",
+ .wakeup = 1,
+ },
+ /* BP3, "joystick" */
+ {
+ .code = KEY_LEFT,
+ .gpio = AT91_PIN_PB14,
+ .active_low = 1,
+ .desc = "Joystick Left",
+ },
+ {
+ .code = KEY_RIGHT,
+ .gpio = AT91_PIN_PB15,
+ .active_low = 1,
+ .desc = "Joystick Right",
+ },
+ {
+ .code = KEY_UP,
+ .gpio = AT91_PIN_PB16,
+ .active_low = 1,
+ .desc = "Joystick Up",
+ },
+ {
+ .code = KEY_DOWN,
+ .gpio = AT91_PIN_PB17,
+ .active_low = 1,
+ .desc = "Joystick Down",
+ },
+ {
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .desc = "Joystick Press",
+ },
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ek_buttons); i++) {
+ at91_set_GPIO_periph(ek_buttons[i].gpio, 1);
+ at91_set_deglitch(ek_buttons[i].gpio, 1);
+ }
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+/*
+ * AC97
+ * reset_pin is not connected: NRST
+ */
+static struct ac97c_platform_data ek_ac97_data = {
+};
+
+
+/*
+ * LEDs ... these could all be PWM-driven, for variable brightness
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "top" led, red, powerled */
+ .name = "d8",
+ .gpio = AT91_PIN_PD30,
+ .default_trigger = "heartbeat",
+ },
+ { /* "left" led, green, userled2, pwm3 */
+ .name = "d6",
+ .gpio = AT91_PIN_PD0,
+ .active_low = 1,
+ .default_trigger = "nand-disk",
+ },
+#if !(defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE))
+ { /* "right" led, green, userled1, pwm1 */
+ .name = "d7",
+ .gpio = AT91_PIN_PD31,
+ .active_low = 1,
+ .default_trigger = "mmc0",
+ },
+#endif
+};
+
+
+/*
+ * PWM Leds
+ */
+static struct gpio_led ek_pwm_led[] = {
+#if defined(CONFIG_LEDS_ATMEL_PWM) || defined(CONFIG_LEDS_ATMEL_PWM_MODULE)
+ { /* "right" led, green, userled1, pwm1 */
+ .name = "d7",
+ .gpio = 1, /* is PWM channel number */
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+#endif
+};
+
+
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB HS Host */
+ at91_add_device_usbh_ohci(&ek_usbh_hs_data);
+ at91_add_device_usbh_ehci(&ek_usbh_hs_data);
+ /* USB HS Device */
+ at91_add_device_usba(&ek_usba_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* MMC */
+ at91_add_device_mci(0, &mci0_data);
+ at91_add_device_mci(1, &mci1_data);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(0, NULL, 0);
+ /* LCD Controller */
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* Touch Screen */
+ at91_add_device_tsadcc(&ek_tsadcc_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* AC97 */
+ at91_add_device_ac97(&ek_ac97_data);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+}
+
+MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9g45_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c
new file mode 100644
index 00000000..effb399a
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9rlek.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <video/atmel_lcdc.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9rl_initialize(12000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9RL_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9rl_init_interrupts(NULL);
+}
+
+
+/*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata ek_usba_udc_data = {
+ .vbus_pin = AT91_PIN_PA8,
+};
+
+
+/*
+ * MCI (SD/MMC)
+ */
+static struct at91_mmc_data __initdata ek_mmc_data = {
+ .wire4 = 1,
+ .det_pin = AT91_PIN_PA15,
+// .wp_pin = ... not connected
+// .vcc_pin = ... not connected
+};
+
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Partition 1",
+ .offset = 0,
+ .size = SZ_256K,
+ },
+ {
+ .name = "Partition 2",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PD17,
+ .enable_pin = AT91_PIN_PB6,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info ek_spi_devices[] = {
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ },
+};
+
+
+/*
+ * LCD Controller
+ */
+#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
+static struct fb_videomode at91_tft_vga_modes[] = {
+ {
+ .name = "TX09D50VM1CCA @ 60",
+ .refresh = 60,
+ .xres = 240, .yres = 320,
+ .pixclock = KHZ2PICOS(4965),
+
+ .left_margin = 1, .right_margin = 33,
+ .upper_margin = 1, .lower_margin = 0,
+ .hsync_len = 5, .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+};
+
+static struct fb_monspecs at91fb_default_monspecs = {
+ .manufacturer = "HIT",
+ .monitor = "TX09D50VM1CCA",
+
+ .modedb = at91_tft_vga_modes,
+ .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
+ .hfmin = 15000,
+ .hfmax = 64000,
+ .vfmin = 50,
+ .vfmax = 150,
+};
+
+#define AT91SAM9RL_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
+ | ATMEL_LCDC_DISTYPE_TFT \
+ | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
+
+static void at91_lcdc_power_control(int on)
+{
+ if (on)
+ at91_set_gpio_value(AT91_PIN_PC1, 0); /* power up */
+ else
+ at91_set_gpio_value(AT91_PIN_PC1, 1); /* power down */
+}
+
+/* Driver datas */
+static struct atmel_lcdfb_info __initdata ek_lcdc_data = {
+ .lcdcon_is_backlight = true,
+ .default_bpp = 16,
+ .default_dmacon = ATMEL_LCDC_DMAEN,
+ .default_lcdcon2 = AT91SAM9RL_DEFAULT_LCDCON2,
+ .default_monspecs = &at91fb_default_monspecs,
+ .atmel_lcdfb_power_control = at91_lcdc_power_control,
+ .guard_time = 1,
+ .lcd_wiring_mode = ATMEL_LCDC_WIRING_RGB,
+};
+
+#else
+static struct atmel_lcdfb_info __initdata ek_lcdc_data;
+#endif
+
+
+/*
+ * AC97
+ * reset_pin is not connected: NRST
+ */
+static struct ac97c_platform_data ek_ac97_data = {
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* "bottom" led, green, userled1 to be defined */
+ .name = "ds1",
+ .gpio = AT91_PIN_PD15,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "bottom" led, green, userled2 to be defined */
+ .name = "ds2",
+ .gpio = AT91_PIN_PD16,
+ .active_low = 1,
+ .default_trigger = "none",
+ },
+ { /* "power" led, yellow */
+ .name = "ds3",
+ .gpio = AT91_PIN_PD14,
+ .default_trigger = "heartbeat",
+ }
+};
+
+
+/*
+ * Touchscreen
+ */
+static struct at91_tsadcc_data ek_tsadcc_data = {
+ .adc_clock = 1000000,
+ .pendet_debounce = 0x0f,
+ .ts_sample_hold_time = 0x03,
+};
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ {
+ .gpio = AT91_PIN_PB0,
+ .code = BTN_2,
+ .desc = "Right Click",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB1,
+ .code = BTN_1,
+ .desc = "Left Click",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PB1, 1); /* btn1 */
+ at91_set_deglitch(AT91_PIN_PB1, 1);
+ at91_set_gpio_input(AT91_PIN_PB0, 1); /* btn2 */
+ at91_set_deglitch(AT91_PIN_PB0, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB HS */
+ at91_add_device_usba(&ek_usba_udc_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* NAND */
+ ek_add_device_nand();
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &ek_mmc_data);
+ /* LCD Controller */
+ at91_add_device_lcdc(&ek_lcdc_data);
+ /* AC97 */
+ at91_add_device_ac97(&ek_ac97_data);
+ /* Touch Screen Controller */
+ at91_add_device_tsadcc(&ek_tsadcc_data);
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* Push Buttons */
+ ek_add_device_buttons();
+}
+
+MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9rl_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
new file mode 100644
index 00000000..3eb0a115
--- /dev/null
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-at91/board-snapper9260.c
+ *
+ * Copyright (C) 2010 Bluewater System Ltd
+ *
+ * Author: Andre Renaud <andre@bluewatersys.com>
+ * Author: Ryan Mallon <ryan@bluewatersys.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/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/pca953x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+#define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x))
+
+static void __init snapper9260_init_early(void)
+{
+ at91sam9260_initialize(18432000);
+
+ /* Debug on ttyS0 */
+ at91_register_uart(0, 0, 0);
+ at91_set_serial_console(0);
+
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
+}
+
+static void __init snapper9260_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+static struct at91_usbh_data __initdata snapper9260_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata snapper9260_udc_data = {
+ .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5),
+ .vbus_active_low = 1,
+ .vbus_polled = 1,
+};
+
+static struct at91_eth_data snapper9260_macb_data = {
+ .is_rmii = 1,
+};
+
+static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
+ {
+ .name = "Preboot",
+ .offset = 0,
+ .size = SZ_128K,
+ },
+ {
+ .name = "Bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ },
+ {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ },
+ {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init
+snapper9260_nand_partition_info(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
+ return snapper9260_nand_partitions;
+}
+
+static struct atmel_nand_data __initdata snapper9260_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .partition_info = snapper9260_nand_partition_info,
+ .bus_width_16 = 0,
+};
+
+static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 0,
+ .ncs_write_setup = 0,
+ .nwe_setup = 0,
+
+ .ncs_read_pulse = 5,
+ .nrd_pulse = 2,
+ .ncs_write_pulse = 5,
+ .nwe_pulse = 2,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = (AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
+ AT91_SMC_EXNWMODE_DISABLE),
+ .tdf_cycles = 1,
+};
+
+static struct pca953x_platform_data snapper9260_io_expander_data = {
+ .gpio_base = SNAPPER9260_IO_EXP_GPIO(0),
+};
+
+static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
+ {
+ /* IO expander */
+ I2C_BOARD_INFO("max7312", 0x28),
+ .platform_data = &snapper9260_io_expander_data,
+ },
+ {
+ /* Audio codec */
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+ {
+ /* RTC */
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ .irq = gpio_to_irq(AT91_PIN_PA31),
+ },
+};
+
+static void __init snapper9260_add_device_nand(void)
+{
+ at91_set_A_periph(AT91_PIN_PC14, 0);
+ sam9_smc_configure(3, &snapper9260_nand_smc_config);
+ at91_add_device_nand(&snapper9260_nand_data);
+}
+
+static void __init snapper9260_board_init(void)
+{
+ at91_add_device_i2c(snapper9260_i2c_devices,
+ ARRAY_SIZE(snapper9260_i2c_devices));
+ at91_add_device_serial();
+ at91_add_device_usbh(&snapper9260_usbh_data);
+ at91_add_device_udc(&snapper9260_udc_data);
+ at91_add_device_eth(&snapper9260_macb_data);
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, (ATMEL_SSC_TF | ATMEL_SSC_TK |
+ ATMEL_SSC_TD | ATMEL_SSC_RD));
+ snapper9260_add_device_nand();
+}
+
+MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = snapper9260_init_early,
+ .init_irq = snapper9260_init_irq,
+ .init_machine = snapper9260_board_init,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c
new file mode 100644
index 00000000..5e5c8568
--- /dev/null
+++ b/arch/arm/mach-at91/board-stamp9g20.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
+ * taskit GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+void __init stamp9g20_init_early(void)
+{
+ /* Initialize processor: 18.432 MHz crystal */
+ at91sam9260_initialize(18432000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init stamp9g20evb_init_early(void)
+{
+ stamp9g20_init_early();
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR
+ | ATMEL_UART_DCD | ATMEL_UART_RI);
+}
+
+static void __init portuxg20_init_early(void)
+{
+ stamp9g20_init_early();
+
+ /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR
+ | ATMEL_UART_DCD | ATMEL_UART_RI);
+
+ /* USART1 on ttyS2. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US1, 2, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART2 on ttyS3. (Rx, Tx, CTS, RTS) */
+ at91_register_uart(AT91SAM9260_ID_US2, 3, ATMEL_UART_CTS | ATMEL_UART_RTS);
+
+ /* USART4 on ttyS5. (Rx, Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
+
+ /* USART5 on ttyS6. (Rx, Tx only) */
+ at91_register_uart(AT91SAM9260_ID_US5, 6, 0);
+}
+
+static void __init init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * NAND flash
+ */
+static struct atmel_nand_data __initdata nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .bus_width_16 = 0,
+};
+
+static struct sam9_smc_config __initdata nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 3,
+};
+
+static void __init add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &nand_smc_config);
+
+ at91_add_device_nand(&nand_data);
+}
+
+
+/*
+ * MCI (SD/MMC)
+ * det_pin, wp_pin and vcc_pin are not connected
+ */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+static struct mci_platform_data __initdata mmc_data = {
+ .slot[0] = {
+ .bus_width = 4,
+ },
+};
+#else
+static struct at91_mmc_data __initdata mmc_data = {
+ .slot_b = 0,
+ .wire4 = 1,
+};
+#endif
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata usbh_data = {
+ .ports = 2,
+};
+
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata portuxg20_udc_data = {
+ .vbus_pin = AT91_PIN_PC7,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+static struct at91_udc_data __initdata stamp9g20evb_udc_data = {
+ .vbus_pin = AT91_PIN_PA22,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata macb_data = {
+ .phy_irq_pin = AT91_PIN_PA28,
+ .is_rmii = 1,
+};
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led portuxg20_leds[] = {
+ {
+ .name = "LED2",
+ .gpio = AT91_PIN_PC5,
+ .default_trigger = "none",
+ }, {
+ .name = "LED3",
+ .gpio = AT91_PIN_PC4,
+ .default_trigger = "none",
+ }, {
+ .name = "LED4",
+ .gpio = AT91_PIN_PC10,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static struct gpio_led stamp9g20evb_leds[] = {
+ {
+ .name = "D8",
+ .gpio = AT91_PIN_PB18,
+ .active_low = 1,
+ .default_trigger = "none",
+ }, {
+ .name = "D9",
+ .gpio = AT91_PIN_PB19,
+ .active_low = 1,
+ .default_trigger = "none",
+ }, {
+ .name = "D10",
+ .gpio = AT91_PIN_PB20,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ }
+};
+
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info portuxg20_spi_devices[] = {
+ {
+ .modalias = "spidev",
+ .chip_select = 0,
+ .max_speed_hz = 1 * 1000 * 1000,
+ .bus_num = 0,
+ }, {
+ .modalias = "spidev",
+ .chip_select = 0,
+ .max_speed_hz = 1 * 1000 * 1000,
+ .bus_num = 1,
+ },
+};
+
+
+/*
+ * Dallas 1-Wire
+ */
+static struct w1_gpio_platform_data w1_gpio_pdata = {
+ .pin = AT91_PIN_PA29,
+ .is_open_drain = 1,
+};
+
+static struct platform_device w1_device = {
+ .name = "w1-gpio",
+ .id = -1,
+ .dev.platform_data = &w1_gpio_pdata,
+};
+
+void add_w1(void)
+{
+ at91_set_GPIO_periph(w1_gpio_pdata.pin, 1);
+ at91_set_multi_drive(w1_gpio_pdata.pin, 1);
+ platform_device_register(&w1_device);
+}
+
+
+void __init stamp9g20_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* NAND */
+ add_device_nand();
+ /* MMC */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
+ at91_add_device_mci(0, &mmc_data);
+#else
+ at91_add_device_mmc(0, &mmc_data);
+#endif
+ /* W1 */
+ add_w1();
+}
+
+static void __init portuxg20_board_init(void)
+{
+ stamp9g20_board_init();
+ /* USB Host */
+ at91_add_device_usbh(&usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&portuxg20_udc_data);
+ /* Ethernet */
+ at91_add_device_eth(&macb_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* SPI */
+ at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices));
+ /* LEDs */
+ at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds));
+}
+
+static void __init stamp9g20evb_board_init(void)
+{
+ stamp9g20_board_init();
+ /* USB Host */
+ at91_add_device_usbh(&usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&stamp9g20evb_udc_data);
+ /* Ethernet */
+ at91_add_device_eth(&macb_data);
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* LEDs */
+ at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds));
+}
+
+MACHINE_START(PORTUXG20, "taskit PortuxG20")
+ /* Maintainer: taskit GmbH */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = portuxg20_init_early,
+ .init_irq = init_irq,
+ .init_machine = portuxg20_board_init,
+MACHINE_END
+
+MACHINE_START(STAMP9G20, "taskit Stamp9G20")
+ /* Maintainer: taskit GmbH */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = stamp9g20evb_init_early,
+ .init_irq = init_irq,
+ .init_machine = stamp9g20evb_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-usb-a9260.c b/arch/arm/mach-at91/board-usb-a9260.c
new file mode 100644
index 00000000..0e784e6f
--- /dev/null
+++ b/arch/arm/mach-at91/board-usb-a9260.c
@@ -0,0 +1,236 @@
+/*
+ * linux/arch/arm/mach-at91/board-usb-a9260.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2006 Atmel
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91sam9260_initialize(12000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Uboot & Kernel",
+ .offset = 0,
+ .size = SZ_16M,
+ },
+ {
+ .name = "Root FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ },
+ {
+ .name = "FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+/*
+ * GPIO Buttons
+ */
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 0,
+ .default_trigger = "heartbeat",
+ }
+};
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(USB_A9260, "CALAO USB_A9260")
+ /* Maintainer: calao-systems */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9260_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-usb-a9263.c b/arch/arm/mach-at91/board-usb-a9263.c
new file mode 100644
index 00000000..cf626dd1
--- /dev/null
+++ b/arch/arm/mach-at91/board-usb-a9263.c
@@ -0,0 +1,252 @@
+/*
+ * linux/arch/arm/mach-at91/board-usb-a9263.c
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2007 Atmel Corporation.
+ * Copyright (C) 2007 Calao-systems
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/at91_shdwc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.00 MHz crystal */
+ at91sam9263_initialize(12000000);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init ek_init_irq(void)
+{
+ at91sam9263_init_interrupts(NULL);
+}
+
+
+/*
+ * USB Host port
+ */
+static struct at91_usbh_data __initdata ek_usbh_data = {
+ .ports = 2,
+};
+
+/*
+ * USB Device port
+ */
+static struct at91_udc_data __initdata ek_udc_data = {
+ .vbus_pin = AT91_PIN_PB11,
+ .pullup_pin = 0, /* pull-up driven by UDC */
+};
+
+/*
+ * SPI devices.
+ */
+static struct spi_board_info ek_spi_devices[] = {
+#if !defined(CONFIG_MMC_AT91)
+ { /* DataFlash chip */
+ .modalias = "mtd_dataflash",
+ .chip_select = 0,
+ .max_speed_hz = 15 * 1000 * 1000,
+ .bus_num = 0,
+ }
+#endif
+};
+
+/*
+ * MACB Ethernet device
+ */
+static struct at91_eth_data __initdata ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PE31,
+ .is_rmii = 1,
+};
+
+/*
+ * NAND flash
+ */
+static struct mtd_partition __initdata ek_nand_partition[] = {
+ {
+ .name = "Linux Kernel",
+ .offset = 0,
+ .size = SZ_16M,
+ },
+ {
+ .name = "Root FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ },
+ {
+ .name = "FS",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 120 * SZ_1M,
+ }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(ek_nand_partition);
+ return ek_nand_partition;
+}
+
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+// .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PA22,
+ .enable_pin = AT91_PIN_PD15,
+ .partition_info = nand_partitions,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 2,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+
+/*
+ * GPIO Buttons
+ */
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button ek_buttons[] = {
+ { /* USER PUSH BUTTON */
+ .code = KEY_ENTER,
+ .gpio = AT91_PIN_PB10,
+ .active_low = 1,
+ .desc = "user_pb",
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data ek_button_data = {
+ .buttons = ek_buttons,
+ .nbuttons = ARRAY_SIZE(ek_buttons),
+};
+
+static struct platform_device ek_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_button_data,
+ }
+};
+
+static void __init ek_add_device_buttons(void)
+{
+ at91_set_GPIO_periph(AT91_PIN_PB10, 1); /* user push button, pull up enabled */
+ at91_set_deglitch(AT91_PIN_PB10, 1);
+
+ platform_device_register(&ek_button_device);
+}
+#else
+static void __init ek_add_device_buttons(void) {}
+#endif
+
+/*
+ * LEDs
+ */
+static struct gpio_led ek_leds[] = {
+ { /* user_led (green) */
+ .name = "user_led",
+ .gpio = AT91_PIN_PB21,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ }
+};
+
+
+static void __init ek_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* USB Host */
+ at91_add_device_usbh(&ek_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&ek_udc_data);
+ /* SPI */
+ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
+ /* Ethernet */
+ at91_add_device_eth(&ek_macb_data);
+ /* NAND */
+ ek_add_device_nand();
+ /* I2C */
+ at91_add_device_i2c(NULL, 0);
+ /* Push Buttons */
+ ek_add_device_buttons();
+ /* LEDs */
+ at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
+ /* shutdown controller, wakeup button (5 msec low) */
+ at91_sys_write(AT91_SHDW_MR, AT91_SHDW_CPTWK0_(10) | AT91_SHDW_WKMODE0_LOW
+ | AT91_SHDW_RTTWKEN);
+}
+
+MACHINE_START(USB_A9263, "CALAO USB_A9263")
+ /* Maintainer: calao-systems */
+ .timer = &at91sam926x_timer,
+ .map_io = at91sam9263_map_io,
+ .init_early = ek_init_early,
+ .init_irq = ek_init_irq,
+ .init_machine = ek_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c
new file mode 100644
index 00000000..c208cc33
--- /dev/null
+++ b/arch/arm/mach-at91/board-yl-9200.c
@@ -0,0 +1,606 @@
+/*
+ * linux/arch/arm/mach-at91/board-yl-9200.c
+ *
+ * Adapted from various board files in arch/arm/mach-at91
+ *
+ * Modifications for YL-9200 platform:
+ * Copyright (C) 2007 S. Birtles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+
+
+static void __init yl9200_init_early(void)
+{
+ /* Set cpu type: PQFP */
+ at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+ /* Initialize processor: 18.432 MHz crystal */
+ at91rm9200_initialize(18432000);
+
+ /* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */
+ at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17);
+
+ /* DBGU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* USART1 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
+ at91_register_uart(AT91RM9200_ID_US1, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
+ | ATMEL_UART_DTR | ATMEL_UART_DSR | ATMEL_UART_DCD
+ | ATMEL_UART_RI);
+
+ /* USART0 on ttyS2. (Rx & Tx only to JP3) */
+ at91_register_uart(AT91RM9200_ID_US0, 2, 0);
+
+ /* USART3 on ttyS3. (Rx, Tx, RTS - RS485 interface) */
+ at91_register_uart(AT91RM9200_ID_US3, 3, ATMEL_UART_RTS);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+static void __init yl9200_init_irq(void)
+{
+ at91rm9200_init_interrupts(NULL);
+}
+
+
+/*
+ * LEDs
+ */
+static struct gpio_led yl9200_leds[] = {
+ { /* D2 */
+ .name = "led2",
+ .gpio = AT91_PIN_PB17,
+ .active_low = 1,
+ .default_trigger = "timer",
+ },
+ { /* D3 */
+ .name = "led3",
+ .gpio = AT91_PIN_PB16,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+ { /* D4 */
+ .name = "led4",
+ .gpio = AT91_PIN_PB15,
+ .active_low = 1,
+ },
+ { /* D5 */
+ .name = "led5",
+ .gpio = AT91_PIN_PB8,
+ .active_low = 1,
+ }
+};
+
+/*
+ * Ethernet
+ */
+static struct at91_eth_data __initdata yl9200_eth_data = {
+ .phy_irq_pin = AT91_PIN_PB28,
+ .is_rmii = 1,
+};
+
+/*
+ * USB Host
+ */
+static struct at91_usbh_data __initdata yl9200_usbh_data = {
+ .ports = 1, /* PQFP version of AT91RM9200 */
+};
+
+/*
+ * USB Device
+ */
+static struct at91_udc_data __initdata yl9200_udc_data = {
+ .pullup_pin = AT91_PIN_PC4,
+ .vbus_pin = AT91_PIN_PC5,
+ .pullup_active_low = 1, /* Active Low due to PNP transistor (pg 7) */
+
+};
+
+/*
+ * MMC
+ */
+static struct at91_mmc_data __initdata yl9200_mmc_data = {
+ .det_pin = AT91_PIN_PB9,
+ // .wp_pin = ... not connected
+ .wire4 = 1,
+};
+
+/*
+ * NAND Flash
+ */
+static struct mtd_partition __initdata yl9200_nand_partition[] = {
+ {
+ .name = "AT91 NAND partition 1, boot",
+ .offset = 0,
+ .size = SZ_256K
+ },
+ {
+ .name = "AT91 NAND partition 2, kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = (2 * SZ_1M) - SZ_256K
+ },
+ {
+ .name = "AT91 NAND partition 3, filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = 14 * SZ_1M
+ },
+ {
+ .name = "AT91 NAND partition 4, storage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_16M
+ },
+ {
+ .name = "AT91 NAND partition 5, ext-fs",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_32M
+ }
+};
+
+static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(yl9200_nand_partition);
+ return yl9200_nand_partition;
+}
+
+static struct atmel_nand_data __initdata yl9200_nand_data = {
+ .ale = 6,
+ .cle = 7,
+ // .det_pin = ... not connected
+ .rdy_pin = AT91_PIN_PC14, /* R/!B (Sheet10) */
+ .enable_pin = AT91_PIN_PC15, /* !CE (Sheet10) */
+ .partition_info = nand_partitions,
+};
+
+/*
+ * NOR Flash
+ */
+#define YL9200_FLASH_BASE AT91_CHIPSELECT_0
+#define YL9200_FLASH_SIZE SZ_16M
+
+static struct mtd_partition yl9200_flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = (2 * SZ_1M) - SZ_256K
+ },
+ {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ }
+};
+
+static struct physmap_flash_data yl9200_flash_data = {
+ .width = 2,
+ .parts = yl9200_flash_partitions,
+ .nr_parts = ARRAY_SIZE(yl9200_flash_partitions),
+};
+
+static struct resource yl9200_flash_resources[] = {
+ {
+ .start = YL9200_FLASH_BASE,
+ .end = YL9200_FLASH_BASE + YL9200_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device yl9200_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &yl9200_flash_data,
+ },
+ .resource = yl9200_flash_resources,
+ .num_resources = ARRAY_SIZE(yl9200_flash_resources),
+};
+
+/*
+ * I2C (TWI)
+ */
+static struct i2c_board_info __initdata yl9200_i2c_devices[] = {
+ { /* EEPROM */
+ I2C_BOARD_INFO("24c128", 0x50),
+ }
+};
+
+/*
+ * GPIO Buttons
+*/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button yl9200_buttons[] = {
+ {
+ .gpio = AT91_PIN_PA24,
+ .code = BTN_2,
+ .desc = "SW2",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB1,
+ .code = BTN_3,
+ .desc = "SW3",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB2,
+ .code = BTN_4,
+ .desc = "SW4",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+ {
+ .gpio = AT91_PIN_PB6,
+ .code = BTN_5,
+ .desc = "SW5",
+ .active_low = 1,
+ .wakeup = 1,
+ }
+};
+
+static struct gpio_keys_platform_data yl9200_button_data = {
+ .buttons = yl9200_buttons,
+ .nbuttons = ARRAY_SIZE(yl9200_buttons),
+};
+
+static struct platform_device yl9200_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &yl9200_button_data,
+ }
+};
+
+static void __init yl9200_add_device_buttons(void)
+{
+ at91_set_gpio_input(AT91_PIN_PA24, 1); /* SW2 */
+ at91_set_deglitch(AT91_PIN_PA24, 1);
+ at91_set_gpio_input(AT91_PIN_PB1, 1); /* SW3 */
+ at91_set_deglitch(AT91_PIN_PB1, 1);
+ at91_set_gpio_input(AT91_PIN_PB2, 1); /* SW4 */
+ at91_set_deglitch(AT91_PIN_PB2, 1);
+ at91_set_gpio_input(AT91_PIN_PB6, 1); /* SW5 */
+ at91_set_deglitch(AT91_PIN_PB6, 1);
+
+ /* Enable buttons (Sheet 5) */
+ at91_set_gpio_output(AT91_PIN_PB7, 1);
+
+ platform_device_register(&yl9200_button_device);
+}
+#else
+static void __init yl9200_add_device_buttons(void) {}
+#endif
+
+/*
+ * Touchscreen
+ */
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static int ads7843_pendown_state(void)
+{
+ return !at91_get_gpio_value(AT91_PIN_PB11); /* Touchscreen PENIRQ */
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7843,
+ .x_min = 150,
+ .x_max = 3830,
+ .y_min = 190,
+ .y_max = 3830,
+ .vref_delay_usecs = 100,
+
+ /* For a 8" touch-screen */
+ // .x_plate_ohms = 603,
+ // .y_plate_ohms = 332,
+
+ /* For a 10.4" touch-screen */
+ // .x_plate_ohms = 611,
+ // .y_plate_ohms = 325,
+
+ .x_plate_ohms = 576,
+ .y_plate_ohms = 366,
+
+ .pressure_max = 15000, /* generally nonsense on the 7843 */
+ .debounce_max = 1,
+ .debounce_rep = 0,
+ .debounce_tol = (~0),
+ .get_pendown_state = ads7843_pendown_state,
+};
+
+static void __init yl9200_add_device_ts(void)
+{
+ at91_set_gpio_input(AT91_PIN_PB11, 1); /* Touchscreen interrupt pin */
+ at91_set_gpio_input(AT91_PIN_PB10, 1); /* Touchscreen BUSY signal - not used! */
+}
+#else
+static void __init yl9200_add_device_ts(void) {}
+#endif
+
+/*
+ * SPI devices
+ */
+static struct spi_board_info yl9200_spi_devices[] = {
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ { /* Touchscreen */
+ .modalias = "ads7846",
+ .chip_select = 0,
+ .max_speed_hz = 5000 * 26,
+ .platform_data = &ads_info,
+ .irq = AT91_PIN_PB11,
+ },
+#endif
+ { /* CAN */
+ .modalias = "mcp2510",
+ .chip_select = 1,
+ .max_speed_hz = 25000 * 26,
+ .irq = AT91_PIN_PC0,
+ }
+};
+
+/*
+ * LCD / VGA
+ *
+ * EPSON S1D13806 FB (discontinued chip)
+ * EPSON S1D13506 FB
+ */
+#if defined(CONFIG_FB_S1D13XXX) || defined(CONFIG_FB_S1D13XXX_MODULE)
+#include <video/s1d13xxxfb.h>
+
+
+static void __init yl9200_init_video(void)
+{
+ /* NWAIT Signal */
+ at91_set_A_periph(AT91_PIN_PC6, 0);
+
+ /* Initialization of the Static Memory Controller for Chip Select 2 */
+ at91_sys_write(AT91_SMC_CSR(2), AT91_SMC_DBW_16 /* 16 bit */
+ | AT91_SMC_WSEN | AT91_SMC_NWS_(0x4) /* wait states */
+ | AT91_SMC_TDF_(0x100) /* float time */
+ );
+}
+
+static struct s1d13xxxfb_regval yl9200_s1dfb_initregs[] =
+{
+ {S1DREG_MISC, 0x00}, /* Miscellaneous Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+ {S1DREG_GPIO_CNF0, 0x00}, /* General IO Pins Configuration Register*/
+ {S1DREG_GPIO_CTL0, 0x00}, /* General IO Pins Control Register*/
+ {S1DREG_CLK_CNF, 0x11}, /* Memory Clock Configuration Register*/
+ {S1DREG_LCD_CLK_CNF, 0x10}, /* LCD Pixel Clock Configuration Register*/
+ {S1DREG_CRT_CLK_CNF, 0x12}, /* CRT/TV Pixel Clock Configuration Register*/
+ {S1DREG_MPLUG_CLK_CNF, 0x01}, /* MediaPlug Clock Configuration Register*/
+ {S1DREG_CPU2MEM_WST_SEL, 0x02}, /* CPU To Memory Wait State Select Register*/
+ {S1DREG_MEM_CNF, 0x00}, /* Memory Configuration Register*/
+ {S1DREG_SDRAM_REF_RATE, 0x04}, /* DRAM Refresh Rate Register, MCLK source*/
+ {S1DREG_SDRAM_TC0, 0x12}, /* DRAM Timings Control Register 0*/
+ {S1DREG_SDRAM_TC1, 0x02}, /* DRAM Timings Control Register 1*/
+ {S1DREG_PANEL_TYPE, 0x25}, /* Panel Type Register*/
+ {S1DREG_MOD_RATE, 0x00}, /* MOD Rate Register*/
+ {S1DREG_LCD_DISP_HWIDTH, 0x4F}, /* LCD Horizontal Display Width Register*/
+ {S1DREG_LCD_NDISP_HPER, 0x13}, /* LCD Horizontal Non-Display Period Register*/
+ {S1DREG_TFT_FPLINE_START, 0x01}, /* TFT FPLINE Start Position Register*/
+ {S1DREG_TFT_FPLINE_PWIDTH, 0x0c}, /* TFT FPLINE Pulse Width Register*/
+ {S1DREG_LCD_DISP_VHEIGHT0, 0xDF}, /* LCD Vertical Display Height Register 0*/
+ {S1DREG_LCD_DISP_VHEIGHT1, 0x01}, /* LCD Vertical Display Height Register 1*/
+ {S1DREG_LCD_NDISP_VPER, 0x2c}, /* LCD Vertical Non-Display Period Register*/
+ {S1DREG_TFT_FPFRAME_START, 0x0a}, /* TFT FPFRAME Start Position Register*/
+ {S1DREG_TFT_FPFRAME_PWIDTH, 0x02}, /* TFT FPFRAME Pulse Width Register*/
+ {S1DREG_LCD_DISP_MODE, 0x05}, /* LCD Display Mode Register*/
+ {S1DREG_LCD_MISC, 0x01}, /* LCD Miscellaneous Register*/
+ {S1DREG_LCD_DISP_START0, 0x00}, /* LCD Display Start Address Register 0*/
+ {S1DREG_LCD_DISP_START1, 0x00}, /* LCD Display Start Address Register 1*/
+ {S1DREG_LCD_DISP_START2, 0x00}, /* LCD Display Start Address Register 2*/
+ {S1DREG_LCD_MEM_OFF0, 0x80}, /* LCD Memory Address Offset Register 0*/
+ {S1DREG_LCD_MEM_OFF1, 0x02}, /* LCD Memory Address Offset Register 1*/
+ {S1DREG_LCD_PIX_PAN, 0x03}, /* LCD Pixel Panning Register*/
+ {S1DREG_LCD_DISP_FIFO_HTC, 0x00}, /* LCD Display FIFO High Threshold Control Register*/
+ {S1DREG_LCD_DISP_FIFO_LTC, 0x00}, /* LCD Display FIFO Low Threshold Control Register*/
+ {S1DREG_CRT_DISP_HWIDTH, 0x4F}, /* CRT/TV Horizontal Display Width Register*/
+ {S1DREG_CRT_NDISP_HPER, 0x13}, /* CRT/TV Horizontal Non-Display Period Register*/
+ {S1DREG_CRT_HRTC_START, 0x01}, /* CRT/TV HRTC Start Position Register*/
+ {S1DREG_CRT_HRTC_PWIDTH, 0x0B}, /* CRT/TV HRTC Pulse Width Register*/
+ {S1DREG_CRT_DISP_VHEIGHT0, 0xDF}, /* CRT/TV Vertical Display Height Register 0*/
+ {S1DREG_CRT_DISP_VHEIGHT1, 0x01}, /* CRT/TV Vertical Display Height Register 1*/
+ {S1DREG_CRT_NDISP_VPER, 0x2B}, /* CRT/TV Vertical Non-Display Period Register*/
+ {S1DREG_CRT_VRTC_START, 0x09}, /* CRT/TV VRTC Start Position Register*/
+ {S1DREG_CRT_VRTC_PWIDTH, 0x01}, /* CRT/TV VRTC Pulse Width Register*/
+ {S1DREG_TV_OUT_CTL, 0x18}, /* TV Output Control Register */
+ {S1DREG_CRT_DISP_MODE, 0x05}, /* CRT/TV Display Mode Register, 16BPP*/
+ {S1DREG_CRT_DISP_START0, 0x00}, /* CRT/TV Display Start Address Register 0*/
+ {S1DREG_CRT_DISP_START1, 0x00}, /* CRT/TV Display Start Address Register 1*/
+ {S1DREG_CRT_DISP_START2, 0x00}, /* CRT/TV Display Start Address Register 2*/
+ {S1DREG_CRT_MEM_OFF0, 0x80}, /* CRT/TV Memory Address Offset Register 0*/
+ {S1DREG_CRT_MEM_OFF1, 0x02}, /* CRT/TV Memory Address Offset Register 1*/
+ {S1DREG_CRT_PIX_PAN, 0x00}, /* CRT/TV Pixel Panning Register*/
+ {S1DREG_CRT_DISP_FIFO_HTC, 0x00}, /* CRT/TV Display FIFO High Threshold Control Register*/
+ {S1DREG_CRT_DISP_FIFO_LTC, 0x00}, /* CRT/TV Display FIFO Low Threshold Control Register*/
+ {S1DREG_LCD_CUR_CTL, 0x00}, /* LCD Ink/Cursor Control Register*/
+ {S1DREG_LCD_CUR_START, 0x01}, /* LCD Ink/Cursor Start Address Register*/
+ {S1DREG_LCD_CUR_XPOS0, 0x00}, /* LCD Cursor X Position Register 0*/
+ {S1DREG_LCD_CUR_XPOS1, 0x00}, /* LCD Cursor X Position Register 1*/
+ {S1DREG_LCD_CUR_YPOS0, 0x00}, /* LCD Cursor Y Position Register 0*/
+ {S1DREG_LCD_CUR_YPOS1, 0x00}, /* LCD Cursor Y Position Register 1*/
+ {S1DREG_LCD_CUR_BCTL0, 0x00}, /* LCD Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_LCD_CUR_GCTL0, 0x00}, /* LCD Ink/Cursor Green Color 0 Register*/
+ {S1DREG_LCD_CUR_RCTL0, 0x00}, /* LCD Ink/Cursor Red Color 0 Register*/
+ {S1DREG_LCD_CUR_BCTL1, 0x1F}, /* LCD Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_LCD_CUR_GCTL1, 0x3F}, /* LCD Ink/Cursor Green Color 1 Register*/
+ {S1DREG_LCD_CUR_RCTL1, 0x1F}, /* LCD Ink/Cursor Red Color 1 Register*/
+ {S1DREG_LCD_CUR_FIFO_HTC, 0x00}, /* LCD Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_CRT_CUR_CTL, 0x00}, /* CRT/TV Ink/Cursor Control Register*/
+ {S1DREG_CRT_CUR_START, 0x01}, /* CRT/TV Ink/Cursor Start Address Register*/
+ {S1DREG_CRT_CUR_XPOS0, 0x00}, /* CRT/TV Cursor X Position Register 0*/
+ {S1DREG_CRT_CUR_XPOS1, 0x00}, /* CRT/TV Cursor X Position Register 1*/
+ {S1DREG_CRT_CUR_YPOS0, 0x00}, /* CRT/TV Cursor Y Position Register 0*/
+ {S1DREG_CRT_CUR_YPOS1, 0x00}, /* CRT/TV Cursor Y Position Register 1*/
+ {S1DREG_CRT_CUR_BCTL0, 0x00}, /* CRT/TV Ink/Cursor Blue Color 0 Register*/
+ {S1DREG_CRT_CUR_GCTL0, 0x00}, /* CRT/TV Ink/Cursor Green Color 0 Register*/
+ {S1DREG_CRT_CUR_RCTL0, 0x00}, /* CRT/TV Ink/Cursor Red Color 0 Register*/
+ {S1DREG_CRT_CUR_BCTL1, 0x1F}, /* CRT/TV Ink/Cursor Blue Color 1 Register*/
+ {S1DREG_CRT_CUR_GCTL1, 0x3F}, /* CRT/TV Ink/Cursor Green Color 1 Register*/
+ {S1DREG_CRT_CUR_RCTL1, 0x1F}, /* CRT/TV Ink/Cursor Red Color 1 Register*/
+ {S1DREG_CRT_CUR_FIFO_HTC, 0x00}, /* CRT/TV Ink/Cursor FIFO Threshold Register*/
+ {S1DREG_BBLT_CTL0, 0x00}, /* BitBlt Control Register 0*/
+ {S1DREG_BBLT_CTL1, 0x01}, /* BitBlt Control Register 1*/
+ {S1DREG_BBLT_CC_EXP, 0x00}, /* BitBlt ROP Code/Color Expansion Register*/
+ {S1DREG_BBLT_OP, 0x00}, /* BitBlt Operation Register*/
+ {S1DREG_BBLT_SRC_START0, 0x00}, /* BitBlt Source Start Address Register 0*/
+ {S1DREG_BBLT_SRC_START1, 0x00}, /* BitBlt Source Start Address Register 1*/
+ {S1DREG_BBLT_SRC_START2, 0x00}, /* BitBlt Source Start Address Register 2*/
+ {S1DREG_BBLT_DST_START0, 0x00}, /* BitBlt Destination Start Address Register 0*/
+ {S1DREG_BBLT_DST_START1, 0x00}, /* BitBlt Destination Start Address Register 1*/
+ {S1DREG_BBLT_DST_START2, 0x00}, /* BitBlt Destination Start Address Register 2*/
+ {S1DREG_BBLT_MEM_OFF0, 0x00}, /* BitBlt Memory Address Offset Register 0*/
+ {S1DREG_BBLT_MEM_OFF1, 0x00}, /* BitBlt Memory Address Offset Register 1*/
+ {S1DREG_BBLT_WIDTH0, 0x00}, /* BitBlt Width Register 0*/
+ {S1DREG_BBLT_WIDTH1, 0x00}, /* BitBlt Width Register 1*/
+ {S1DREG_BBLT_HEIGHT0, 0x00}, /* BitBlt Height Register 0*/
+ {S1DREG_BBLT_HEIGHT1, 0x00}, /* BitBlt Height Register 1*/
+ {S1DREG_BBLT_BGC0, 0x00}, /* BitBlt Background Color Register 0*/
+ {S1DREG_BBLT_BGC1, 0x00}, /* BitBlt Background Color Register 1*/
+ {S1DREG_BBLT_FGC0, 0x00}, /* BitBlt Foreground Color Register 0*/
+ {S1DREG_BBLT_FGC1, 0x00}, /* BitBlt Foreground Color Register 1*/
+ {S1DREG_LKUP_MODE, 0x00}, /* Look-Up Table Mode Register*/
+ {S1DREG_LKUP_ADDR, 0x00}, /* Look-Up Table Address Register*/
+ {S1DREG_PS_CNF, 0x00}, /* Power Save Configuration Register*/
+ {S1DREG_PS_STATUS, 0x00}, /* Power Save Status Register*/
+ {S1DREG_CPU2MEM_WDOGT, 0x00}, /* CPU-to-Memory Access Watchdog Timer Register*/
+ {S1DREG_COM_DISP_MODE, 0x01}, /* Display Mode Register, LCD only*/
+};
+
+static struct s1d13xxxfb_pdata yl9200_s1dfb_pdata = {
+ .initregs = yl9200_s1dfb_initregs,
+ .initregssize = ARRAY_SIZE(yl9200_s1dfb_initregs),
+ .platform_init_video = yl9200_init_video,
+};
+
+#define YL9200_FB_REG_BASE AT91_CHIPSELECT_7
+#define YL9200_FB_VMEM_BASE YL9200_FB_REG_BASE + SZ_2M
+#define YL9200_FB_VMEM_SIZE SZ_2M
+
+static struct resource yl9200_s1dfb_resource[] = {
+ [0] = { /* video mem */
+ .name = "s1d13xxxfb memory",
+ .start = YL9200_FB_VMEM_BASE,
+ .end = YL9200_FB_VMEM_BASE + YL9200_FB_VMEM_SIZE -1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* video registers */
+ .name = "s1d13xxxfb registers",
+ .start = YL9200_FB_REG_BASE,
+ .end = YL9200_FB_REG_BASE + SZ_512 -1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static u64 s1dfb_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device yl9200_s1dfb_device = {
+ .name = "s1d13806fb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &s1dfb_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &yl9200_s1dfb_pdata,
+ },
+ .resource = yl9200_s1dfb_resource,
+ .num_resources = ARRAY_SIZE(yl9200_s1dfb_resource),
+};
+
+void __init yl9200_add_device_video(void)
+{
+ platform_device_register(&yl9200_s1dfb_device);
+}
+#else
+void __init yl9200_add_device_video(void) {}
+#endif
+
+
+static void __init yl9200_board_init(void)
+{
+ /* Serial */
+ at91_add_device_serial();
+ /* Ethernet */
+ at91_add_device_eth(&yl9200_eth_data);
+ /* USB Host */
+ at91_add_device_usbh(&yl9200_usbh_data);
+ /* USB Device */
+ at91_add_device_udc(&yl9200_udc_data);
+ /* I2C */
+ at91_add_device_i2c(yl9200_i2c_devices, ARRAY_SIZE(yl9200_i2c_devices));
+ /* MMC */
+ at91_add_device_mmc(0, &yl9200_mmc_data);
+ /* NAND */
+ at91_add_device_nand(&yl9200_nand_data);
+ /* NOR Flash */
+ platform_device_register(&yl9200_flash);
+#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
+ /* SPI */
+ at91_add_device_spi(yl9200_spi_devices, ARRAY_SIZE(yl9200_spi_devices));
+ /* Touchscreen */
+ yl9200_add_device_ts();
+#endif
+ /* LEDs. */
+ at91_gpio_leds(yl9200_leds, ARRAY_SIZE(yl9200_leds));
+ /* Push Buttons */
+ yl9200_add_device_buttons();
+ /* VGA */
+ yl9200_add_device_video();
+}
+
+MACHINE_START(YL9200, "uCdragon YL-9200")
+ /* Maintainer: S.Birtles */
+ .timer = &at91rm9200_timer,
+ .map_io = at91rm9200_map_io,
+ .init_early = yl9200_init_early,
+ .init_irq = yl9200_init_irq,
+ .init_machine = yl9200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
new file mode 100644
index 00000000..61873f3a
--- /dev/null
+++ b/arch/arm/mach-at91/clock.c
@@ -0,0 +1,778 @@
+/*
+ * linux/arch/arm/mach-at91/clock.c
+ *
+ * Copyright (C) 2005 David Brownell
+ * Copyright (C) 2005 Ivan Kokshaysky
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/at91_pmc.h>
+#include <mach/cpu.h>
+
+#include "clock.h"
+#include "generic.h"
+
+
+/*
+ * There's a lot more which can be done with clocks, including cpufreq
+ * integration, slow clock mode support (for system suspend), letting
+ * PLLB be used at other rates (on boards that don't need USB), etc.
+ */
+
+#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
+#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
+#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL)
+#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM)
+
+
+/*
+ * Chips have some kind of clocks : group them by functionality
+ */
+#define cpu_has_utmi() ( cpu_is_at91cap9() \
+ || cpu_is_at91sam9rl() \
+ || cpu_is_at91sam9g45())
+
+#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
+ || cpu_is_at91sam9g45())
+
+#define cpu_has_300M_plla() (cpu_is_at91sam9g10())
+
+#define cpu_has_pllb() (!(cpu_is_at91sam9rl() \
+ || cpu_is_at91sam9g45()))
+
+#define cpu_has_upll() (cpu_is_at91sam9g45())
+
+/* USB host HS & FS */
+#define cpu_has_uhp() (!cpu_is_at91sam9rl())
+
+/* USB device FS only */
+#define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \
+ || cpu_is_at91sam9g45()))
+
+static LIST_HEAD(clocks);
+static DEFINE_SPINLOCK(clk_lock);
+
+static u32 at91_pllb_usb_init;
+
+/*
+ * Four primary clock sources: two crystal oscillators (32K, main), and
+ * two PLLs. PLLA usually runs the master clock; and PLLB must run at
+ * 48 MHz (unless no USB function clocks are needed). The main clock and
+ * both PLLs are turned off to run in "slow clock mode" (system suspend).
+ */
+static struct clk clk32k = {
+ .name = "clk32k",
+ .rate_hz = AT91_SLOW_CLOCK,
+ .users = 1, /* always on */
+ .id = 0,
+ .type = CLK_TYPE_PRIMARY,
+};
+static struct clk main_clk = {
+ .name = "main",
+ .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */
+ .id = 1,
+ .type = CLK_TYPE_PRIMARY,
+};
+static struct clk plla = {
+ .name = "plla",
+ .parent = &main_clk,
+ .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */
+ .id = 2,
+ .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
+};
+
+static void pllb_mode(struct clk *clk, int is_on)
+{
+ u32 value;
+
+ if (is_on) {
+ is_on = AT91_PMC_LOCKB;
+ value = at91_pllb_usb_init;
+ } else
+ value = 0;
+
+ // REVISIT: Add work-around for AT91RM9200 Errata #26 ?
+ at91_sys_write(AT91_CKGR_PLLBR, value);
+
+ do {
+ cpu_relax();
+ } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on);
+}
+
+static struct clk pllb = {
+ .name = "pllb",
+ .parent = &main_clk,
+ .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */
+ .mode = pllb_mode,
+ .id = 3,
+ .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL,
+};
+
+static void pmc_sys_mode(struct clk *clk, int is_on)
+{
+ if (is_on)
+ at91_sys_write(AT91_PMC_SCER, clk->pmc_mask);
+ else
+ at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask);
+}
+
+static void pmc_uckr_mode(struct clk *clk, int is_on)
+{
+ unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR);
+
+ if (cpu_is_at91sam9g45()) {
+ if (is_on)
+ uckr |= AT91_PMC_BIASEN;
+ else
+ uckr &= ~AT91_PMC_BIASEN;
+ }
+
+ if (is_on) {
+ is_on = AT91_PMC_LOCKU;
+ at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask);
+ } else
+ at91_sys_write(AT91_CKGR_UCKR, uckr & ~(clk->pmc_mask));
+
+ do {
+ cpu_relax();
+ } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKU) != is_on);
+}
+
+/* USB function clocks (PLLB must be 48 MHz) */
+static struct clk udpck = {
+ .name = "udpck",
+ .parent = &pllb,
+ .mode = pmc_sys_mode,
+};
+struct clk utmi_clk = {
+ .name = "utmi_clk",
+ .parent = &main_clk,
+ .pmc_mask = AT91_PMC_UPLLEN, /* in CKGR_UCKR */
+ .mode = pmc_uckr_mode,
+ .type = CLK_TYPE_PLL,
+};
+static struct clk uhpck = {
+ .name = "uhpck",
+ /*.parent = ... we choose parent at runtime */
+ .mode = pmc_sys_mode,
+};
+
+
+/*
+ * The master clock is divided from the CPU clock (by 1-4). It's used for
+ * memory, interfaces to on-chip peripherals, the AIC, and sometimes more
+ * (e.g baud rate generation). It's sourced from one of the primary clocks.
+ */
+struct clk mck = {
+ .name = "mck",
+ .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */
+};
+
+static void pmc_periph_mode(struct clk *clk, int is_on)
+{
+ if (is_on)
+ at91_sys_write(AT91_PMC_PCER, clk->pmc_mask);
+ else
+ at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask);
+}
+
+static struct clk __init *at91_css_to_clk(unsigned long css)
+{
+ switch (css) {
+ case AT91_PMC_CSS_SLOW:
+ return &clk32k;
+ case AT91_PMC_CSS_MAIN:
+ return &main_clk;
+ case AT91_PMC_CSS_PLLA:
+ return &plla;
+ case AT91_PMC_CSS_PLLB:
+ if (cpu_has_upll())
+ /* CSS_PLLB == CSS_UPLL */
+ return &utmi_clk;
+ else if (cpu_has_pllb())
+ return &pllb;
+ }
+
+ return NULL;
+}
+
+static void __clk_enable(struct clk *clk)
+{
+ if (clk->parent)
+ __clk_enable(clk->parent);
+ if (clk->users++ == 0 && clk->mode)
+ clk->mode(clk, 1);
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+ BUG_ON(clk->users == 0);
+ if (--clk->users == 0 && clk->mode)
+ clk->mode(clk, 0);
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long flags;
+ unsigned long rate;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ for (;;) {
+ rate = clk->rate_hz;
+ if (rate || !clk->parent)
+ break;
+ clk = clk->parent;
+ }
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/*------------------------------------------------------------------------*/
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+
+/*
+ * For now, only the programmable clocks support reparenting (MCK could
+ * do this too, with care) or rate changing (the PLLs could do this too,
+ * ditto MCK but that's more for cpufreq). Drivers may reparent to get
+ * a better rate match; we don't.
+ */
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ unsigned prescale;
+ unsigned long actual;
+ unsigned long prev = ULONG_MAX;
+
+ if (!clk_is_programmable(clk))
+ return -EINVAL;
+ spin_lock_irqsave(&clk_lock, flags);
+
+ actual = clk->parent->rate_hz;
+ for (prescale = 0; prescale < 7; prescale++) {
+ if (actual > rate)
+ prev = actual;
+
+ if (actual && actual <= rate) {
+ if ((prev - rate) < (rate - actual)) {
+ actual = prev;
+ prescale--;
+ }
+ break;
+ }
+ actual >>= 1;
+ }
+
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return (prescale < 7) ? actual : -ENOENT;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ unsigned prescale;
+ unsigned long actual;
+
+ if (!clk_is_programmable(clk))
+ return -EINVAL;
+ if (clk->users)
+ return -EBUSY;
+ spin_lock_irqsave(&clk_lock, flags);
+
+ actual = clk->parent->rate_hz;
+ for (prescale = 0; prescale < 7; prescale++) {
+ if (actual && actual <= rate) {
+ u32 pckr;
+
+ pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+ pckr &= AT91_PMC_CSS; /* clock selection */
+ pckr |= prescale << 2;
+ at91_sys_write(AT91_PMC_PCKR(clk->id), pckr);
+ clk->rate_hz = actual;
+ break;
+ }
+ actual >>= 1;
+ }
+
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return (prescale < 7) ? actual : -ENOENT;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+
+ if (clk->users)
+ return -EBUSY;
+ if (!clk_is_primary(parent) || !clk_is_programmable(clk))
+ return -EINVAL;
+
+ if (cpu_is_at91sam9rl() && parent->id == AT91_PMC_CSS_PLLB)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clk_lock, flags);
+
+ clk->rate_hz = parent->rate_hz;
+ clk->parent = parent;
+ at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id);
+
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* establish PCK0..PCKN parentage and rate */
+static void __init init_programmable_clock(struct clk *clk)
+{
+ struct clk *parent;
+ u32 pckr;
+
+ pckr = at91_sys_read(AT91_PMC_PCKR(clk->id));
+ parent = at91_css_to_clk(pckr & AT91_PMC_CSS);
+ clk->parent = parent;
+ clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2));
+}
+
+#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */
+
+/*------------------------------------------------------------------------*/
+
+#ifdef CONFIG_DEBUG_FS
+
+static int at91_clk_show(struct seq_file *s, void *unused)
+{
+ u32 scsr, pcsr, uckr = 0, sr;
+ struct clk *clk;
+
+ seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR));
+ seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR));
+ seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR));
+ seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
+ seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
+ if (cpu_has_pllb())
+ seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+ if (cpu_has_utmi())
+ seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
+ seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
+ if (cpu_has_upll())
+ seq_printf(s, "USB = %8x\n", at91_sys_read(AT91_PMC_USB));
+ seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
+
+ seq_printf(s, "\n");
+
+ list_for_each_entry(clk, &clocks, node) {
+ char *state;
+
+ if (clk->mode == pmc_sys_mode)
+ state = (scsr & clk->pmc_mask) ? "on" : "off";
+ else if (clk->mode == pmc_periph_mode)
+ state = (pcsr & clk->pmc_mask) ? "on" : "off";
+ else if (clk->mode == pmc_uckr_mode)
+ state = (uckr & clk->pmc_mask) ? "on" : "off";
+ else if (clk->pmc_mask)
+ state = (sr & clk->pmc_mask) ? "on" : "off";
+ else if (clk == &clk32k || clk == &main_clk)
+ state = "on";
+ else
+ state = "";
+
+ seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n",
+ clk->name, clk->users, state, clk_get_rate(clk),
+ clk->parent ? clk->parent->name : "");
+ }
+ return 0;
+}
+
+static int at91_clk_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, at91_clk_show, NULL);
+}
+
+static const struct file_operations at91_clk_operations = {
+ .open = at91_clk_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init at91_clk_debugfs_init(void)
+{
+ /* /sys/kernel/debug/at91_clk */
+ (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations);
+
+ return 0;
+}
+postcore_initcall(at91_clk_debugfs_init);
+
+#endif
+
+/*------------------------------------------------------------------------*/
+
+/* Register a new clock */
+static void __init at91_clk_add(struct clk *clk)
+{
+ list_add_tail(&clk->node, &clocks);
+
+ clk->cl.con_id = clk->name;
+ clk->cl.clk = clk;
+ clkdev_add(&clk->cl);
+}
+
+int __init clk_register(struct clk *clk)
+{
+ if (clk_is_peripheral(clk)) {
+ if (!clk->parent)
+ clk->parent = &mck;
+ clk->mode = pmc_periph_mode;
+ }
+ else if (clk_is_sys(clk)) {
+ clk->parent = &mck;
+ clk->mode = pmc_sys_mode;
+ }
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+ else if (clk_is_programmable(clk)) {
+ clk->mode = pmc_sys_mode;
+ init_programmable_clock(clk);
+ }
+#endif
+
+ at91_clk_add(clk);
+
+ return 0;
+}
+
+/*------------------------------------------------------------------------*/
+
+static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
+{
+ unsigned mul, div;
+
+ div = reg & 0xff;
+ mul = (reg >> 16) & 0x7ff;
+ if (div && mul) {
+ freq /= div;
+ freq *= mul + 1;
+ } else
+ freq = 0;
+
+ return freq;
+}
+
+static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg)
+{
+ if (pll == &pllb && (reg & AT91_PMC_USB96M))
+ return freq / 2;
+ else
+ return freq;
+}
+
+static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq)
+{
+ unsigned i, div = 0, mul = 0, diff = 1 << 30;
+ unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00;
+
+ /* PLL output max 240 MHz (or 180 MHz per errata) */
+ if (out_freq > 240000000)
+ goto fail;
+
+ for (i = 1; i < 256; i++) {
+ int diff1;
+ unsigned input, mul1;
+
+ /*
+ * PLL input between 1MHz and 32MHz per spec, but lower
+ * frequences seem necessary in some cases so allow 100K.
+ * Warning: some newer products need 2MHz min.
+ */
+ input = main_freq / i;
+ if (cpu_is_at91sam9g20() && input < 2000000)
+ continue;
+ if (input < 100000)
+ continue;
+ if (input > 32000000)
+ continue;
+
+ mul1 = out_freq / input;
+ if (cpu_is_at91sam9g20() && mul > 63)
+ continue;
+ if (mul1 > 2048)
+ continue;
+ if (mul1 < 2)
+ goto fail;
+
+ diff1 = out_freq - input * mul1;
+ if (diff1 < 0)
+ diff1 = -diff1;
+ if (diff > diff1) {
+ diff = diff1;
+ div = i;
+ mul = mul1;
+ if (diff == 0)
+ break;
+ }
+ }
+ if (i == 256 && diff > (out_freq >> 5))
+ goto fail;
+ return ret | ((mul - 1) << 16) | div;
+fail:
+ return 0;
+}
+
+static struct clk *const standard_pmc_clocks[] __initdata = {
+ /* four primary clocks */
+ &clk32k,
+ &main_clk,
+ &plla,
+
+ /* MCK */
+ &mck
+};
+
+/* PLLB generated USB full speed clock init */
+static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
+{
+ /*
+ * USB clock init: choose 48 MHz PLLB value,
+ * disable 48MHz clock during usb peripheral suspend.
+ *
+ * REVISIT: assumes MCK doesn't derive from PLLB!
+ */
+ uhpck.parent = &pllb;
+
+ at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M;
+ pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init);
+ if (cpu_is_at91rm9200()) {
+ uhpck.pmc_mask = AT91RM9200_PMC_UHP;
+ udpck.pmc_mask = AT91RM9200_PMC_UDP;
+ at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
+ } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() ||
+ cpu_is_at91sam9263() || cpu_is_at91sam9g20() ||
+ cpu_is_at91sam9g10()) {
+ uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+ udpck.pmc_mask = AT91SAM926x_PMC_UDP;
+ } else if (cpu_is_at91cap9()) {
+ uhpck.pmc_mask = AT91CAP9_PMC_UHP;
+ }
+ at91_sys_write(AT91_CKGR_PLLBR, 0);
+
+ udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+ uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init);
+}
+
+/* UPLL generated USB full speed clock init */
+static void __init at91_upll_usbfs_clock_init(unsigned long main_clock)
+{
+ /*
+ * USB clock init: choose 480 MHz from UPLL,
+ */
+ unsigned int usbr = AT91_PMC_USBS_UPLL;
+
+ /* Setup divider by 10 to reach 48 MHz */
+ usbr |= ((10 - 1) << 8) & AT91_PMC_OHCIUSBDIV;
+
+ at91_sys_write(AT91_PMC_USB, usbr);
+
+ /* Now set uhpck values */
+ uhpck.parent = &utmi_clk;
+ uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
+ uhpck.rate_hz = utmi_clk.rate_hz;
+ uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8);
+}
+
+int __init at91_clock_init(unsigned long main_clock)
+{
+ unsigned tmp, freq, mckr;
+ int i;
+ int pll_overclock = false;
+
+ /*
+ * When the bootloader initialized the main oscillator correctly,
+ * there's no problem using the cycle counter. But if it didn't,
+ * or when using oscillator bypass mode, we must be told the speed
+ * of the main clock.
+ */
+ if (!main_clock) {
+ do {
+ tmp = at91_sys_read(AT91_CKGR_MCFR);
+ } while (!(tmp & AT91_PMC_MAINRDY));
+ main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16);
+ }
+ main_clk.rate_hz = main_clock;
+
+ /* report if PLLA is more than mildly overclocked */
+ plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR));
+ if (cpu_has_300M_plla()) {
+ if (plla.rate_hz > 300000000)
+ pll_overclock = true;
+ } else if (cpu_has_800M_plla()) {
+ if (plla.rate_hz > 800000000)
+ pll_overclock = true;
+ } else {
+ if (plla.rate_hz > 209000000)
+ pll_overclock = true;
+ }
+ if (pll_overclock)
+ pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
+
+ if (cpu_is_at91sam9g45()) {
+ mckr = at91_sys_read(AT91_PMC_MCKR);
+ plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */
+ }
+
+ if (!cpu_has_pllb() && cpu_has_upll()) {
+ /* setup UTMI clock as the fourth primary clock
+ * (instead of pllb) */
+ utmi_clk.type |= CLK_TYPE_PRIMARY;
+ utmi_clk.id = 3;
+ }
+
+
+ /*
+ * USB HS clock init
+ */
+ if (cpu_has_utmi()) {
+ /*
+ * multiplier is hard-wired to 40
+ * (obtain the USB High Speed 480 MHz when input is 12 MHz)
+ */
+ utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz;
+ }
+
+ /*
+ * USB FS clock init
+ */
+ if (cpu_has_pllb())
+ at91_pllb_usbfs_clock_init(main_clock);
+ if (cpu_has_upll())
+ /* assumes that we choose UPLL for USB and not PLLA */
+ at91_upll_usbfs_clock_init(main_clock);
+
+ /*
+ * MCK and CPU derive from one of those primary clocks.
+ * For now, assume this parentage won't change.
+ */
+ mckr = at91_sys_read(AT91_PMC_MCKR);
+ mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS);
+ freq = mck.parent->rate_hz;
+ freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */
+ if (cpu_is_at91rm9200()) {
+ mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ } else if (cpu_is_at91sam9g20()) {
+ mck.rate_hz = (mckr & AT91_PMC_MDIV) ?
+ freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */
+ if (mckr & AT91_PMC_PDIV)
+ freq /= 2; /* processor clock division */
+ } else if (cpu_is_at91sam9g45()) {
+ mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ?
+ freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ } else {
+ mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */
+ }
+
+ /* Register the PMC's standard clocks */
+ for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
+ at91_clk_add(standard_pmc_clocks[i]);
+
+ if (cpu_has_pllb())
+ at91_clk_add(&pllb);
+
+ if (cpu_has_uhp())
+ at91_clk_add(&uhpck);
+
+ if (cpu_has_udpfs())
+ at91_clk_add(&udpck);
+
+ if (cpu_has_utmi())
+ at91_clk_add(&utmi_clk);
+
+ /* MCK and CPU clock are "always on" */
+ clk_enable(&mck);
+
+ printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
+ freq / 1000000, (unsigned) mck.rate_hz / 1000000,
+ (unsigned) main_clock / 1000000,
+ ((unsigned) main_clock % 1000000) / 1000);
+
+ return 0;
+}
+
+/*
+ * Several unused clocks may be active. Turn them off.
+ */
+static int __init at91_clock_reset(void)
+{
+ unsigned long pcdr = 0;
+ unsigned long scdr = 0;
+ struct clk *clk;
+
+ list_for_each_entry(clk, &clocks, node) {
+ if (clk->users > 0)
+ continue;
+
+ if (clk->mode == pmc_periph_mode)
+ pcdr |= clk->pmc_mask;
+
+ if (clk->mode == pmc_sys_mode)
+ scdr |= clk->pmc_mask;
+
+ pr_debug("Clocks: disable unused %s\n", clk->name);
+ }
+
+ at91_sys_write(AT91_PMC_PCDR, pcdr);
+ at91_sys_write(AT91_PMC_SCDR, scdr);
+
+ return 0;
+}
+late_initcall(at91_clock_reset);
diff --git a/arch/arm/mach-at91/clock.h b/arch/arm/mach-at91/clock.h
new file mode 100644
index 00000000..c2e63e47
--- /dev/null
+++ b/arch/arm/mach-at91/clock.h
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-at91/clock.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clkdev.h>
+
+#define CLK_TYPE_PRIMARY 0x1
+#define CLK_TYPE_PLL 0x2
+#define CLK_TYPE_PROGRAMMABLE 0x4
+#define CLK_TYPE_PERIPHERAL 0x8
+#define CLK_TYPE_SYSTEM 0x10
+
+
+struct clk {
+ struct list_head node;
+ const char *name; /* unique clock name */
+ struct clk_lookup cl;
+ unsigned long rate_hz;
+ struct clk *parent;
+ u32 pmc_mask;
+ void (*mode)(struct clk *, int);
+ unsigned id:3; /* PCK0..4, or 32k/main/a/b */
+ unsigned type; /* clock type */
+ u16 users;
+};
+
+
+extern int __init clk_register(struct clk *clk);
+extern struct clk mck;
+extern struct clk utmi_clk;
+
+#define CLKDEV_CON_ID(_id, _clk) \
+ { \
+ .con_id = _id, \
+ .clk = _clk, \
+ }
+
+#define CLKDEV_CON_DEV_ID(_con_id, _dev_id, _clk) \
+ { \
+ .con_id = _con_id, \
+ .dev_id = _dev_id, \
+ .clk = _clk, \
+ }
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
new file mode 100644
index 00000000..1cfeac14
--- /dev/null
+++ b/arch/arm/mach-at91/cpuidle.c
@@ -0,0 +1,94 @@
+/*
+ * based on arch/arm/mach-kirkwood/cpuidle.c
+ *
+ * CPU idle support for AT91 SoC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The cpu idle uses wait-for-interrupt and RAM self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and RAM self refresh
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <linux/io.h>
+
+#include "pm.h"
+
+#define AT91_MAX_STATES 2
+
+static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
+
+static struct cpuidle_driver at91_idle_driver = {
+ .name = "at91_idle",
+ .owner = THIS_MODULE,
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int at91_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+ u32 saved_lpr;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+ if (state == &dev->states[0])
+ /* Wait for interrupt state */
+ cpu_do_idle();
+ else if (state == &dev->states[1]) {
+ asm("b 1f; .align 5; 1:");
+ asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */
+ saved_lpr = sdram_selfrefresh_enable();
+ cpu_do_idle();
+ sdram_selfrefresh_disable(saved_lpr);
+ }
+ 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;
+}
+
+/* Initialize CPU idle by registering the idle states */
+static int at91_init_cpuidle(void)
+{
+ struct cpuidle_device *device;
+
+ cpuidle_register_driver(&at91_idle_driver);
+
+ device = &per_cpu(at91_cpuidle_device, smp_processor_id());
+ device->state_count = AT91_MAX_STATES;
+
+ /* Wait for interrupt state */
+ device->states[0].enter = at91_enter_idle;
+ device->states[0].exit_latency = 1;
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "WFI");
+ strcpy(device->states[0].desc, "Wait for interrupt");
+
+ /* Wait for interrupt and RAM self refresh state */
+ device->states[1].enter = at91_enter_idle;
+ device->states[1].exit_latency = 10;
+ device->states[1].target_residency = 10000;
+ device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[1].name, "RAM_SR");
+ strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
+
+ if (cpuidle_register_device(device)) {
+ printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+device_initcall(at91_init_cpuidle);
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
new file mode 100644
index 00000000..8ff3418f
--- /dev/null
+++ b/arch/arm/mach-at91/generic.h
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/mach-at91/generic.h
+ *
+ * Copyright (C) 2005 David Brownell
+ *
+ * This program is free software; you can 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/clkdev.h>
+
+ /* Map io */
+extern void __init at91rm9200_map_io(void);
+extern void __init at91sam9260_map_io(void);
+extern void __init at91sam9261_map_io(void);
+extern void __init at91sam9263_map_io(void);
+extern void __init at91sam9rl_map_io(void);
+extern void __init at91sam9g45_map_io(void);
+extern void __init at91x40_map_io(void);
+extern void __init at91cap9_map_io(void);
+
+ /* Processors */
+extern void __init at91rm9200_set_type(int type);
+extern void __init at91rm9200_initialize(unsigned long main_clock);
+extern void __init at91sam9260_initialize(unsigned long main_clock);
+extern void __init at91sam9261_initialize(unsigned long main_clock);
+extern void __init at91sam9263_initialize(unsigned long main_clock);
+extern void __init at91sam9rl_initialize(unsigned long main_clock);
+extern void __init at91sam9g45_initialize(unsigned long main_clock);
+extern void __init at91x40_initialize(unsigned long main_clock);
+extern void __init at91cap9_initialize(unsigned long main_clock);
+
+ /* Interrupts */
+extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9rl_init_interrupts(unsigned int priority[]);
+extern void __init at91sam9g45_init_interrupts(unsigned int priority[]);
+extern void __init at91x40_init_interrupts(unsigned int priority[]);
+extern void __init at91cap9_init_interrupts(unsigned int priority[]);
+extern void __init at91_aic_init(unsigned int priority[]);
+
+ /* Timer */
+struct sys_timer;
+extern struct sys_timer at91rm9200_timer;
+extern struct sys_timer at91sam926x_timer;
+extern struct sys_timer at91x40_timer;
+
+ /* Clocks */
+extern int __init at91_clock_init(unsigned long main_clock);
+/*
+ * function to specify the clock of the default console. As we do not
+ * use the device/driver bus, the dev_name is not intialize. So we need
+ * to link the clock to a specific con_id only "usart"
+ */
+extern void __init at91rm9200_set_console_clock(int id);
+extern void __init at91sam9260_set_console_clock(int id);
+extern void __init at91sam9261_set_console_clock(int id);
+extern void __init at91sam9263_set_console_clock(int id);
+extern void __init at91sam9rl_set_console_clock(int id);
+extern void __init at91sam9g45_set_console_clock(int id);
+extern void __init at91cap9_set_console_clock(int id);
+struct device;
+
+ /* Power Management */
+extern void at91_irq_suspend(void);
+extern void at91_irq_resume(void);
+
+/* reset */
+extern void at91sam9_alt_reset(void);
+
+ /* GPIO */
+#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */
+#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */
+
+struct at91_gpio_bank {
+ unsigned short id; /* peripheral ID */
+ unsigned long offset; /* offset from system peripheral base */
+ struct clk *clock; /* associated clock */
+};
+extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
+extern void __init at91_gpio_irq_setup(void);
+
+extern void (*at91_arch_reset)(void);
+extern int at91_extern_irq;
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
new file mode 100644
index 00000000..46155282
--- /dev/null
+++ b/arch/arm/mach-at91/gpio.c
@@ -0,0 +1,632 @@
+/*
+ * linux/arch/arm/mach-at91/gpio.c
+ *
+ * Copyright (C) 2005 HP Labs
+ *
+ * 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/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/at91_pio.h>
+#include <mach/gpio.h>
+
+#include <asm/gpio.h>
+
+#include "generic.h"
+
+struct at91_gpio_chip {
+ struct gpio_chip chip;
+ struct at91_gpio_chip *next; /* Bank sharing same clock */
+ struct at91_gpio_bank *bank; /* Bank definition */
+ void __iomem *regbase; /* Base of register bank */
+};
+
+#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
+
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip);
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val);
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset);
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val);
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset);
+
+#define AT91_GPIO_CHIP(name, base_gpio, nr_gpio) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = at91_gpiolib_direction_input, \
+ .direction_output = at91_gpiolib_direction_output, \
+ .get = at91_gpiolib_get, \
+ .set = at91_gpiolib_set, \
+ .dbg_show = at91_gpiolib_dbg_show, \
+ .base = base_gpio, \
+ .ngpio = nr_gpio, \
+ }, \
+ }
+
+static struct at91_gpio_chip gpio_chip[] = {
+ AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
+ AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
+};
+
+static int gpio_banks;
+
+static inline void __iomem *pin_to_controller(unsigned pin)
+{
+ pin -= PIN_BASE;
+ pin /= 32;
+ if (likely(pin < gpio_banks))
+ return gpio_chip[pin].regbase;
+
+ return NULL;
+}
+
+static inline unsigned pin_to_mask(unsigned pin)
+{
+ pin -= PIN_BASE;
+ return 1 << (pin % 32);
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+/* Not all hardware capabilities are exposed through these calls; they
+ * only encapsulate the most common features and modes. (So if you
+ * want to change signals in groups, do it directly.)
+ *
+ * Bootloaders will usually handle some of the pin multiplexing setup.
+ * The intent is certainly that by the time Linux is fully booted, all
+ * pins should have been fully initialized. These setup calls should
+ * only be used by board setup routines, or possibly in driver probe().
+ *
+ * For bootloaders doing all that setup, these calls could be inlined
+ * as NOPs so Linux won't duplicate any setup code
+ */
+
+
+/*
+ * mux the pin to the "GPIO" peripheral role.
+ */
+int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_GPIO_periph);
+
+
+/*
+ * mux the pin to the "A" internal peripheral role.
+ */
+int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_ASR);
+ __raw_writel(mask, pio + PIO_PDR);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_A_periph);
+
+
+/*
+ * mux the pin to the "B" internal peripheral role.
+ */
+int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_BSR);
+ __raw_writel(mask, pio + PIO_PDR);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_B_periph);
+
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and
+ * configure it for an input.
+ */
+int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
+ __raw_writel(mask, pio + PIO_ODR);
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_input);
+
+
+/*
+ * mux the pin to the gpio controller (instead of "A" or "B" peripheral),
+ * and configure it for an output.
+ */
+int __init_or_module at91_set_gpio_output(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + PIO_IDR);
+ __raw_writel(mask, pio + PIO_PUDR);
+ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+ __raw_writel(mask, pio + PIO_OER);
+ __raw_writel(mask, pio + PIO_PER);
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_output);
+
+
+/*
+ * enable/disable the glitch filter; mostly used with IRQ handling.
+ */
+int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+ __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_deglitch);
+
+/*
+ * enable/disable the multi-driver; This is only valid for output and
+ * allows the output pin to run as an open collector output.
+ */
+int __init_or_module at91_set_multi_drive(unsigned pin, int is_on)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+
+ __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR));
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_multi_drive);
+
+/*
+ * assuming the pin is muxed as a gpio output, set its value.
+ */
+int at91_set_gpio_value(unsigned pin, int value)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (!pio)
+ return -EINVAL;
+ __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
+ return 0;
+}
+EXPORT_SYMBOL(at91_set_gpio_value);
+
+
+/*
+ * read the pin's value (works even if it's not muxed as a gpio).
+ */
+int at91_get_gpio_value(unsigned pin)
+{
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+ u32 pdsr;
+
+ if (!pio)
+ return -EINVAL;
+ pdsr = __raw_readl(pio + PIO_PDSR);
+ return (pdsr & mask) != 0;
+}
+EXPORT_SYMBOL(at91_get_gpio_value);
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PM
+
+static u32 wakeups[MAX_GPIO_BANKS];
+static u32 backups[MAX_GPIO_BANKS];
+
+static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
+{
+ unsigned mask = pin_to_mask(d->irq);
+ unsigned bank = (d->irq - PIN_BASE) / 32;
+
+ if (unlikely(bank >= MAX_GPIO_BANKS))
+ return -EINVAL;
+
+ if (state)
+ wakeups[bank] |= mask;
+ else
+ wakeups[bank] &= ~mask;
+
+ irq_set_irq_wake(gpio_chip[bank].bank->id, state);
+
+ return 0;
+}
+
+void at91_gpio_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ void __iomem *pio = gpio_chip[i].regbase;
+
+ backups[i] = __raw_readl(pio + PIO_IMR);
+ __raw_writel(backups[i], pio + PIO_IDR);
+ __raw_writel(wakeups[i], pio + PIO_IER);
+
+ if (!wakeups[i])
+ clk_disable(gpio_chip[i].bank->clock);
+ else {
+#ifdef CONFIG_PM_DEBUG
+ printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]);
+#endif
+ }
+ }
+}
+
+void at91_gpio_resume(void)
+{
+ int i;
+
+ for (i = 0; i < gpio_banks; i++) {
+ void __iomem *pio = gpio_chip[i].regbase;
+
+ if (!wakeups[i])
+ clk_enable(gpio_chip[i].bank->clock);
+
+ __raw_writel(wakeups[i], pio + PIO_IDR);
+ __raw_writel(backups[i], pio + PIO_IER);
+ }
+}
+
+#else
+#define gpio_irq_set_wake NULL
+#endif
+
+
+/* Several AIC controller irqs are dispatched through this GPIO handler.
+ * To use any AT91_PIN_* as an externally triggered IRQ, first call
+ * at91_set_gpio_input() then maybe enable its glitch filter.
+ * Then just request_irq() with the pin ID; it works like any ARM IRQ
+ * handler, though it always triggers on rising and falling edges.
+ *
+ * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
+ * configuring them with at91_set_a_periph() or at91_set_b_periph().
+ * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
+ */
+
+static void gpio_irq_mask(struct irq_data *d)
+{
+ void __iomem *pio = pin_to_controller(d->irq);
+ unsigned mask = pin_to_mask(d->irq);
+
+ if (pio)
+ __raw_writel(mask, pio + PIO_IDR);
+}
+
+static void gpio_irq_unmask(struct irq_data *d)
+{
+ void __iomem *pio = pin_to_controller(d->irq);
+ unsigned mask = pin_to_mask(d->irq);
+
+ if (pio)
+ __raw_writel(mask, pio + PIO_IER);
+}
+
+static int gpio_irq_type(struct irq_data *d, unsigned type)
+{
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ case IRQ_TYPE_EDGE_BOTH:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static struct irq_chip gpio_irqchip = {
+ .name = "GPIO",
+ .irq_disable = gpio_irq_mask,
+ .irq_mask = gpio_irq_mask,
+ .irq_unmask = gpio_irq_unmask,
+ .irq_set_type = gpio_irq_type,
+ .irq_set_wake = gpio_irq_set_wake,
+};
+
+static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ unsigned pin;
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(idata);
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
+ void __iomem *pio = at91_gpio->regbase;
+ u32 isr;
+
+ /* temporarily mask (level sensitive) parent IRQ */
+ chip->irq_ack(idata);
+ for (;;) {
+ /* Reading ISR acks pending (edge triggered) GPIO interrupts.
+ * When there none are pending, we're finished unless we need
+ * to process multiple banks (like ID_PIOCDE on sam9263).
+ */
+ isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR);
+ if (!isr) {
+ if (!at91_gpio->next)
+ break;
+ at91_gpio = at91_gpio->next;
+ pio = at91_gpio->regbase;
+ continue;
+ }
+
+ pin = at91_gpio->chip.base;
+
+ while (isr) {
+ if (isr & 1)
+ generic_handle_irq(pin);
+ pin++;
+ isr >>= 1;
+ }
+ }
+ chip->irq_unmask(idata);
+ /* now it may re-trigger */
+}
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef CONFIG_DEBUG_FS
+
+static int at91_gpio_show(struct seq_file *s, void *unused)
+{
+ int bank, j;
+
+ /* print heading */
+ seq_printf(s, "Pin\t");
+ for (bank = 0; bank < gpio_banks; bank++) {
+ seq_printf(s, "PIO%c\t", 'A' + bank);
+ };
+ seq_printf(s, "\n\n");
+
+ /* print pin status */
+ for (j = 0; j < 32; j++) {
+ seq_printf(s, "%i:\t", j);
+
+ for (bank = 0; bank < gpio_banks; bank++) {
+ unsigned pin = PIN_BASE + (32 * bank) + j;
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+
+ if (__raw_readl(pio + PIO_PSR) & mask)
+ seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
+ else
+ seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");
+
+ seq_printf(s, "\t");
+ }
+
+ seq_printf(s, "\n");
+ }
+
+ return 0;
+}
+
+static int at91_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, at91_gpio_show, NULL);
+}
+
+static const struct file_operations at91_gpio_operations = {
+ .open = at91_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init at91_gpio_debugfs_init(void)
+{
+ /* /sys/kernel/debug/at91_gpio */
+ (void) debugfs_create_file("at91_gpio", S_IFREG | S_IRUGO, NULL, NULL, &at91_gpio_operations);
+ return 0;
+}
+postcore_initcall(at91_gpio_debugfs_init);
+
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+/*
+ * Called from the processor-specific init to enable GPIO interrupt support.
+ */
+void __init at91_gpio_irq_setup(void)
+{
+ unsigned pioc, pin;
+ struct at91_gpio_chip *this, *prev;
+
+ for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
+ pioc++ < gpio_banks;
+ prev = this, this++) {
+ unsigned id = this->bank->id;
+ unsigned i;
+
+ __raw_writel(~0, this->regbase + PIO_IDR);
+
+ for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
+ irq_set_lockdep_class(pin, &gpio_lock_class);
+
+ /*
+ * Can use the "simple" and not "edge" handler since it's
+ * shorter, and the AIC handles interrupts sanely.
+ */
+ irq_set_chip_and_handler(pin, &gpio_irqchip,
+ handle_simple_irq);
+ set_irq_flags(pin, IRQF_VALID);
+ }
+
+ /* The toplevel handler handles one bank of GPIOs, except
+ * AT91SAM9263_ID_PIOCDE handles three... PIOC is first in
+ * the list, so we only set up that handler.
+ */
+ if (prev && prev->next == this)
+ continue;
+
+ irq_set_chip_data(id, this);
+ irq_set_chained_handler(id, gpio_irq_handler);
+ }
+ pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
+}
+
+/* gpiolib support */
+static int at91_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + PIO_ODR);
+ return 0;
+}
+
+static int at91_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+ __raw_writel(mask, pio + PIO_OER);
+ return 0;
+}
+
+static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+ u32 pdsr;
+
+ pdsr = __raw_readl(pio + PIO_PDSR);
+ return (pdsr & mask) != 0;
+}
+
+static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip);
+ void __iomem *pio = at91_gpio->regbase;
+ unsigned mask = 1 << offset;
+
+ __raw_writel(mask, pio + (val ? PIO_SODR : PIO_CODR));
+}
+
+static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ int i;
+
+ for (i = 0; i < chip->ngpio; i++) {
+ unsigned pin = chip->base + i;
+ void __iomem *pio = pin_to_controller(pin);
+ unsigned mask = pin_to_mask(pin);
+ const char *gpio_label;
+
+ gpio_label = gpiochip_is_requested(chip, i);
+ if (gpio_label) {
+ seq_printf(s, "[%s] GPIO%s%d: ",
+ gpio_label, chip->label, i);
+ if (__raw_readl(pio + PIO_PSR) & mask)
+ seq_printf(s, "[gpio] %s\n",
+ at91_get_gpio_value(pin) ?
+ "set" : "clear");
+ else
+ seq_printf(s, "[periph %s]\n",
+ __raw_readl(pio + PIO_ABSR) &
+ mask ? "B" : "A");
+ }
+ }
+}
+
+/*
+ * Called from the processor-specific init to enable GPIO pin support.
+ */
+void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
+{
+ unsigned i;
+ struct at91_gpio_chip *at91_gpio, *last = NULL;
+
+ BUG_ON(nr_banks > MAX_GPIO_BANKS);
+
+ gpio_banks = nr_banks;
+
+ for (i = 0; i < nr_banks; i++) {
+ at91_gpio = &gpio_chip[i];
+
+ at91_gpio->bank = &data[i];
+ at91_gpio->chip.base = PIN_BASE + i * 32;
+ at91_gpio->regbase = at91_gpio->bank->offset +
+ (void __iomem *)AT91_VA_BASE_SYS;
+
+ /* enable PIO controller's clock */
+ clk_enable(at91_gpio->bank->clock);
+
+ /* AT91SAM9263_ID_PIOCDE groups PIOC, PIOD, PIOE */
+ if (last && last->bank->id == at91_gpio->bank->id)
+ last->next = at91_gpio;
+ last = at91_gpio;
+
+ gpiochip_add(&at91_gpio->chip);
+ }
+}
diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h
new file mode 100644
index 00000000..8e7ed5c9
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_adc.h
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_adc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Analog-to-Digital Converter (ADC) registers.
+ * Based on AT91SAM9260 datasheet revision D.
+ *
+ * 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 AT91_ADC_H
+#define AT91_ADC_H
+
+#define AT91_ADC_CR 0x00 /* Control Register */
+#define AT91_ADC_SWRST (1 << 0) /* Software Reset */
+#define AT91_ADC_START (1 << 1) /* Start Conversion */
+
+#define AT91_ADC_MR 0x04 /* Mode Register */
+#define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */
+#define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */
+#define AT91_ADC_TRGSEL_TC0 (0 << 1)
+#define AT91_ADC_TRGSEL_TC1 (1 << 1)
+#define AT91_ADC_TRGSEL_TC2 (2 << 1)
+#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1)
+#define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */
+#define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */
+#define AT91_ADC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */
+#define AT91_ADC_PRESCAL_(x) ((x) << 8)
+#define AT91_ADC_STARTUP (0x1f << 16) /* Startup Up Time */
+#define AT91_ADC_STARTUP_(x) ((x) << 16)
+#define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */
+#define AT91_ADC_SHTIM_(x) ((x) << 24)
+
+#define AT91_ADC_CHER 0x10 /* Channel Enable Register */
+#define AT91_ADC_CHDR 0x14 /* Channel Disable Register */
+#define AT91_ADC_CHSR 0x18 /* Channel Status Register */
+#define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */
+
+#define AT91_ADC_SR 0x1C /* Status Register */
+#define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */
+#define AT91_ADC_OVRE(n) (1 << ((n) + 8))/* Overrun Error on Channel N */
+#define AT91_ADC_DRDY (1 << 16) /* Data Ready */
+#define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */
+#define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */
+#define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */
+
+#define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */
+#define AT91_ADC_LDATA (0x3ff)
+
+#define AT91_ADC_IER 0x24 /* Interrupt Enable Register */
+#define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */
+#define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */
+
+#define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */
+#define AT91_ADC_DATA (0x3ff)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_aic.h b/arch/arm/mach-at91/include/mach/at91_aic.h
new file mode 100644
index 00000000..03566799
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_aic.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_aic.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Advanced Interrupt Controller (AIC) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_AIC_H
+#define AT91_AIC_H
+
+#define AT91_AIC_SMR(n) (AT91_AIC + ((n) * 4)) /* Source Mode Registers 0-31 */
+#define AT91_AIC_PRIOR (7 << 0) /* Priority Level */
+#define AT91_AIC_SRCTYPE (3 << 5) /* Interrupt Source Type */
+#define AT91_AIC_SRCTYPE_LOW (0 << 5)
+#define AT91_AIC_SRCTYPE_FALLING (1 << 5)
+#define AT91_AIC_SRCTYPE_HIGH (2 << 5)
+#define AT91_AIC_SRCTYPE_RISING (3 << 5)
+
+#define AT91_AIC_SVR(n) (AT91_AIC + 0x80 + ((n) * 4)) /* Source Vector Registers 0-31 */
+#define AT91_AIC_IVR (AT91_AIC + 0x100) /* Interrupt Vector Register */
+#define AT91_AIC_FVR (AT91_AIC + 0x104) /* Fast Interrupt Vector Register */
+#define AT91_AIC_ISR (AT91_AIC + 0x108) /* Interrupt Status Register */
+#define AT91_AIC_IRQID (0x1f << 0) /* Current Interrupt Identifier */
+
+#define AT91_AIC_IPR (AT91_AIC + 0x10c) /* Interrupt Pending Register */
+#define AT91_AIC_IMR (AT91_AIC + 0x110) /* Interrupt Mask Register */
+#define AT91_AIC_CISR (AT91_AIC + 0x114) /* Core Interrupt Status Register */
+#define AT91_AIC_NFIQ (1 << 0) /* nFIQ Status */
+#define AT91_AIC_NIRQ (1 << 1) /* nIRQ Status */
+
+#define AT91_AIC_IECR (AT91_AIC + 0x120) /* Interrupt Enable Command Register */
+#define AT91_AIC_IDCR (AT91_AIC + 0x124) /* Interrupt Disable Command Register */
+#define AT91_AIC_ICCR (AT91_AIC + 0x128) /* Interrupt Clear Command Register */
+#define AT91_AIC_ISCR (AT91_AIC + 0x12c) /* Interrupt Set Command Register */
+#define AT91_AIC_EOICR (AT91_AIC + 0x130) /* End of Interrupt Command Register */
+#define AT91_AIC_SPU (AT91_AIC + 0x134) /* Spurious Interrupt Vector Register */
+#define AT91_AIC_DCR (AT91_AIC + 0x138) /* Debug Control Register */
+#define AT91_AIC_DCR_PROT (1 << 0) /* Protection Mode */
+#define AT91_AIC_DCR_GMSK (1 << 1) /* General Mask */
+
+#define AT91_AIC_FFER (AT91_AIC + 0x140) /* Fast Forcing Enable Register [SAM9 only] */
+#define AT91_AIC_FFDR (AT91_AIC + 0x144) /* Fast Forcing Disable Register [SAM9 only] */
+#define AT91_AIC_FFSR (AT91_AIC + 0x148) /* Fast Forcing Status Register [SAM9 only] */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h
new file mode 100644
index 00000000..6dcaa771
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h
@@ -0,0 +1,66 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_dbgu.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Debug Unit (DBGU) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_DBGU_H
+#define AT91_DBGU_H
+
+#ifdef AT91_DBGU
+#define AT91_DBGU_CR (AT91_DBGU + 0x00) /* Control Register */
+#define AT91_DBGU_MR (AT91_DBGU + 0x04) /* Mode Register */
+#define AT91_DBGU_IER (AT91_DBGU + 0x08) /* Interrupt Enable Register */
+#define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */
+#define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */
+#define AT91_DBGU_IDR (AT91_DBGU + 0x0c) /* Interrupt Disable Register */
+#define AT91_DBGU_IMR (AT91_DBGU + 0x10) /* Interrupt Mask Register */
+#define AT91_DBGU_SR (AT91_DBGU + 0x14) /* Status Register */
+#define AT91_DBGU_RHR (AT91_DBGU + 0x18) /* Receiver Holding Register */
+#define AT91_DBGU_THR (AT91_DBGU + 0x1c) /* Transmitter Holding Register */
+#define AT91_DBGU_BRGR (AT91_DBGU + 0x20) /* Baud Rate Generator Register */
+
+#define AT91_DBGU_CIDR (AT91_DBGU + 0x40) /* Chip ID Register */
+#define AT91_DBGU_EXID (AT91_DBGU + 0x44) /* Chip ID Extension Register */
+#define AT91_DBGU_FNR (AT91_DBGU + 0x48) /* Force NTRST Register [SAM9 only] */
+#define AT91_DBGU_FNTRST (1 << 0) /* Force NTRST */
+
+#endif /* AT91_DBGU */
+
+/*
+ * Some AT91 parts that don't have full DEBUG units still support the ID
+ * and extensions register.
+ */
+#define AT91_CIDR_VERSION (0x1f << 0) /* Version of the Device */
+#define AT91_CIDR_EPROC (7 << 5) /* Embedded Processor */
+#define AT91_CIDR_NVPSIZ (0xf << 8) /* Nonvolatile Program Memory Size */
+#define AT91_CIDR_NVPSIZ2 (0xf << 12) /* Second Nonvolatile Program Memory Size */
+#define AT91_CIDR_SRAMSIZ (0xf << 16) /* Internal SRAM Size */
+#define AT91_CIDR_SRAMSIZ_1K (1 << 16)
+#define AT91_CIDR_SRAMSIZ_2K (2 << 16)
+#define AT91_CIDR_SRAMSIZ_112K (4 << 16)
+#define AT91_CIDR_SRAMSIZ_4K (5 << 16)
+#define AT91_CIDR_SRAMSIZ_80K (6 << 16)
+#define AT91_CIDR_SRAMSIZ_160K (7 << 16)
+#define AT91_CIDR_SRAMSIZ_8K (8 << 16)
+#define AT91_CIDR_SRAMSIZ_16K (9 << 16)
+#define AT91_CIDR_SRAMSIZ_32K (10 << 16)
+#define AT91_CIDR_SRAMSIZ_64K (11 << 16)
+#define AT91_CIDR_SRAMSIZ_128K (12 << 16)
+#define AT91_CIDR_SRAMSIZ_256K (13 << 16)
+#define AT91_CIDR_SRAMSIZ_96K (14 << 16)
+#define AT91_CIDR_SRAMSIZ_512K (15 << 16)
+#define AT91_CIDR_ARCH (0xff << 20) /* Architecture Identifier */
+#define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */
+#define AT91_CIDR_EXT (1 << 31) /* Extension Flag */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h
new file mode 100644
index 00000000..02182c16
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_mci.h
@@ -0,0 +1,115 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_mci.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * MultiMedia Card Interface (MCI) registers.
+ * Based on AT91RM9200 datasheet revision F.
+ *
+ * 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 AT91_MCI_H
+#define AT91_MCI_H
+
+#define AT91_MCI_CR 0x00 /* Control Register */
+#define AT91_MCI_MCIEN (1 << 0) /* Multi-Media Interface Enable */
+#define AT91_MCI_MCIDIS (1 << 1) /* Multi-Media Interface Disable */
+#define AT91_MCI_PWSEN (1 << 2) /* Power Save Mode Enable */
+#define AT91_MCI_PWSDIS (1 << 3) /* Power Save Mode Disable */
+#define AT91_MCI_SWRST (1 << 7) /* Software Reset */
+
+#define AT91_MCI_MR 0x04 /* Mode Register */
+#define AT91_MCI_CLKDIV (0xff << 0) /* Clock Divider */
+#define AT91_MCI_PWSDIV (7 << 8) /* Power Saving Divider */
+#define AT91_MCI_RDPROOF (1 << 11) /* Read Proof Enable [SAM926[03] only] */
+#define AT91_MCI_WRPROOF (1 << 12) /* Write Proof Enable [SAM926[03] only] */
+#define AT91_MCI_PDCFBYTE (1 << 13) /* PDC Force Byte Transfer [SAM926[03] only] */
+#define AT91_MCI_PDCPADV (1 << 14) /* PDC Padding Value */
+#define AT91_MCI_PDCMODE (1 << 15) /* PDC-orientated Mode */
+#define AT91_MCI_BLKLEN (0xfff << 18) /* Data Block Length */
+
+#define AT91_MCI_DTOR 0x08 /* Data Timeout Register */
+#define AT91_MCI_DTOCYC (0xf << 0) /* Data Timeout Cycle Number */
+#define AT91_MCI_DTOMUL (7 << 4) /* Data Timeout Multiplier */
+#define AT91_MCI_DTOMUL_1 (0 << 4)
+#define AT91_MCI_DTOMUL_16 (1 << 4)
+#define AT91_MCI_DTOMUL_128 (2 << 4)
+#define AT91_MCI_DTOMUL_256 (3 << 4)
+#define AT91_MCI_DTOMUL_1K (4 << 4)
+#define AT91_MCI_DTOMUL_4K (5 << 4)
+#define AT91_MCI_DTOMUL_64K (6 << 4)
+#define AT91_MCI_DTOMUL_1M (7 << 4)
+
+#define AT91_MCI_SDCR 0x0c /* SD Card Register */
+#define AT91_MCI_SDCSEL (3 << 0) /* SD Card Selector */
+#define AT91_MCI_SDCBUS (1 << 7) /* 1-bit or 4-bit bus */
+
+#define AT91_MCI_ARGR 0x10 /* Argument Register */
+
+#define AT91_MCI_CMDR 0x14 /* Command Register */
+#define AT91_MCI_CMDNB (0x3f << 0) /* Command Number */
+#define AT91_MCI_RSPTYP (3 << 6) /* Response Type */
+#define AT91_MCI_RSPTYP_NONE (0 << 6)
+#define AT91_MCI_RSPTYP_48 (1 << 6)
+#define AT91_MCI_RSPTYP_136 (2 << 6)
+#define AT91_MCI_SPCMD (7 << 8) /* Special Command */
+#define AT91_MCI_SPCMD_NONE (0 << 8)
+#define AT91_MCI_SPCMD_INIT (1 << 8)
+#define AT91_MCI_SPCMD_SYNC (2 << 8)
+#define AT91_MCI_SPCMD_ICMD (4 << 8)
+#define AT91_MCI_SPCMD_IRESP (5 << 8)
+#define AT91_MCI_OPDCMD (1 << 11) /* Open Drain Command */
+#define AT91_MCI_MAXLAT (1 << 12) /* Max Latency for Command to Response */
+#define AT91_MCI_TRCMD (3 << 16) /* Transfer Command */
+#define AT91_MCI_TRCMD_NONE (0 << 16)
+#define AT91_MCI_TRCMD_START (1 << 16)
+#define AT91_MCI_TRCMD_STOP (2 << 16)
+#define AT91_MCI_TRDIR (1 << 18) /* Transfer Direction */
+#define AT91_MCI_TRTYP (3 << 19) /* Transfer Type */
+#define AT91_MCI_TRTYP_BLOCK (0 << 19)
+#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
+#define AT91_MCI_TRTYP_STREAM (2 << 19)
+#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19)
+#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19)
+
+#define AT91_MCI_BLKR 0x18 /* Block Register */
+#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
+#define AT91_MCI_BLKR_BLKLEN(n) ((0xffff & (n)) << 16) /* Block length */
+
+#define AT91_MCI_RSPR(n) (0x20 + ((n) * 4)) /* Response Registers 0-3 */
+#define AT91_MCR_RDR 0x30 /* Receive Data Register */
+#define AT91_MCR_TDR 0x34 /* Transmit Data Register */
+
+#define AT91_MCI_SR 0x40 /* Status Register */
+#define AT91_MCI_CMDRDY (1 << 0) /* Command Ready */
+#define AT91_MCI_RXRDY (1 << 1) /* Receiver Ready */
+#define AT91_MCI_TXRDY (1 << 2) /* Transmit Ready */
+#define AT91_MCI_BLKE (1 << 3) /* Data Block Ended */
+#define AT91_MCI_DTIP (1 << 4) /* Data Transfer in Progress */
+#define AT91_MCI_NOTBUSY (1 << 5) /* Data Not Busy */
+#define AT91_MCI_ENDRX (1 << 6) /* End of RX Buffer */
+#define AT91_MCI_ENDTX (1 << 7) /* End fo TX Buffer */
+#define AT91_MCI_SDIOIRQA (1 << 8) /* SDIO Interrupt for Slot A */
+#define AT91_MCI_SDIOIRQB (1 << 9) /* SDIO Interrupt for Slot B */
+#define AT91_MCI_RXBUFF (1 << 14) /* RX Buffer Full */
+#define AT91_MCI_TXBUFE (1 << 15) /* TX Buffer Empty */
+#define AT91_MCI_RINDE (1 << 16) /* Response Index Error */
+#define AT91_MCI_RDIRE (1 << 17) /* Response Direction Error */
+#define AT91_MCI_RCRCE (1 << 18) /* Response CRC Error */
+#define AT91_MCI_RENDE (1 << 19) /* Response End Bit Error */
+#define AT91_MCI_RTOE (1 << 20) /* Response Time-out Error */
+#define AT91_MCI_DCRCE (1 << 21) /* Data CRC Error */
+#define AT91_MCI_DTOE (1 << 22) /* Data Time-out Error */
+#define AT91_MCI_OVRE (1 << 30) /* Overrun */
+#define AT91_MCI_UNRE (1 << 31) /* Underrun */
+
+#define AT91_MCI_IER 0x44 /* Interrupt Enable Register */
+#define AT91_MCI_IDR 0x48 /* Interrupt Disable Register */
+#define AT91_MCI_IMR 0x4c /* Interrupt Mask Register */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h
new file mode 100644
index 00000000..c6a31bf8
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_pio.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_pio.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Parallel I/O Controller (PIO) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_PIO_H
+#define AT91_PIO_H
+
+#define PIO_PER 0x00 /* Enable Register */
+#define PIO_PDR 0x04 /* Disable Register */
+#define PIO_PSR 0x08 /* Status Register */
+#define PIO_OER 0x10 /* Output Enable Register */
+#define PIO_ODR 0x14 /* Output Disable Register */
+#define PIO_OSR 0x18 /* Output Status Register */
+#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
+#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
+#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
+#define PIO_SODR 0x30 /* Set Output Data Register */
+#define PIO_CODR 0x34 /* Clear Output Data Register */
+#define PIO_ODSR 0x38 /* Output Data Status Register */
+#define PIO_PDSR 0x3c /* Pin Data Status Register */
+#define PIO_IER 0x40 /* Interrupt Enable Register */
+#define PIO_IDR 0x44 /* Interrupt Disable Register */
+#define PIO_IMR 0x48 /* Interrupt Mask Register */
+#define PIO_ISR 0x4c /* Interrupt Status Register */
+#define PIO_MDER 0x50 /* Multi-driver Enable Register */
+#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
+#define PIO_MDSR 0x58 /* Multi-driver Status Register */
+#define PIO_PUDR 0x60 /* Pull-up Disable Register */
+#define PIO_PUER 0x64 /* Pull-up Enable Register */
+#define PIO_PUSR 0x68 /* Pull-up Status Register */
+#define PIO_ASR 0x70 /* Peripheral A Select Register */
+#define PIO_BSR 0x74 /* Peripheral B Select Register */
+#define PIO_ABSR 0x78 /* AB Status Register */
+#define PIO_OWER 0xa0 /* Output Write Enable Register */
+#define PIO_OWDR 0xa4 /* Output Write Disable Register */
+#define PIO_OWSR 0xa8 /* Output Write Status Register */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_pit.h b/arch/arm/mach-at91/include/mach/at91_pit.h
new file mode 100644
index 00000000..974d0bd0
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_pit.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_pit.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Periodic Interval Timer (PIT) - System peripherals regsters.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91_PIT_H
+#define AT91_PIT_H
+
+#define AT91_PIT_MR (AT91_PIT + 0x00) /* Mode Register */
+#define AT91_PIT_PITIEN (1 << 25) /* Timer Interrupt Enable */
+#define AT91_PIT_PITEN (1 << 24) /* Timer Enabled */
+#define AT91_PIT_PIV (0xfffff) /* Periodic Interval Value */
+
+#define AT91_PIT_SR (AT91_PIT + 0x04) /* Status Register */
+#define AT91_PIT_PITS (1 << 0) /* Timer Status */
+
+#define AT91_PIT_PIVR (AT91_PIT + 0x08) /* Periodic Interval Value Register */
+#define AT91_PIT_PIIR (AT91_PIT + 0x0c) /* Periodic Interval Image Register */
+#define AT91_PIT_PICNT (0xfff << 20) /* Interval Counter */
+#define AT91_PIT_CPIV (0xfffff) /* Inverval Value */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
new file mode 100644
index 00000000..e46f93e3
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -0,0 +1,133 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_pmc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Power Management Controller (PMC) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_PMC_H
+#define AT91_PMC_H
+
+#define AT91_PMC_SCER (AT91_PMC + 0x00) /* System Clock Enable Register */
+#define AT91_PMC_SCDR (AT91_PMC + 0x04) /* System Clock Disable Register */
+
+#define AT91_PMC_SCSR (AT91_PMC + 0x08) /* System Clock Status Register */
+#define AT91_PMC_PCK (1 << 0) /* Processor Clock */
+#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */
+#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
+#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */
+#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */
+#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */
+#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */
+#define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */
+#define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */
+#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */
+#define AT91_PMC_PCK2 (1 << 10) /* Programmable Clock 2 */
+#define AT91_PMC_PCK3 (1 << 11) /* Programmable Clock 3 */
+#define AT91_PMC_PCK4 (1 << 12) /* Programmable Clock 4 [AT572D940HF only] */
+#define AT91_PMC_HCK0 (1 << 16) /* AHB Clock (USB host) [AT91SAM9261 only] */
+#define AT91_PMC_HCK1 (1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */
+
+#define AT91_PMC_PCER (AT91_PMC + 0x10) /* Peripheral Clock Enable Register */
+#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */
+#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */
+
+#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */
+#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
+#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
+#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
+#define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */
+
+#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */
+#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
+#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */
+#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */
+
+#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */
+#define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */
+#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */
+
+#define AT91_CKGR_PLLAR (AT91_PMC + 0x28) /* PLL A Register */
+#define AT91_CKGR_PLLBR (AT91_PMC + 0x2c) /* PLL B Register */
+#define AT91_PMC_DIV (0xff << 0) /* Divider */
+#define AT91_PMC_PLLCOUNT (0x3f << 8) /* PLL Counter */
+#define AT91_PMC_OUT (3 << 14) /* PLL Clock Frequency Range */
+#define AT91_PMC_MUL (0x7ff << 16) /* PLL Multiplier */
+#define AT91_PMC_USBDIV (3 << 28) /* USB Divisor (PLLB only) */
+#define AT91_PMC_USBDIV_1 (0 << 28)
+#define AT91_PMC_USBDIV_2 (1 << 28)
+#define AT91_PMC_USBDIV_4 (2 << 28)
+#define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */
+
+#define AT91_PMC_MCKR (AT91_PMC + 0x30) /* Master Clock Register */
+#define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */
+#define AT91_PMC_CSS_SLOW (0 << 0)
+#define AT91_PMC_CSS_MAIN (1 << 0)
+#define AT91_PMC_CSS_PLLA (2 << 0)
+#define AT91_PMC_CSS_PLLB (3 << 0)
+#define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */
+#define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */
+#define AT91_PMC_PRES_1 (0 << 2)
+#define AT91_PMC_PRES_2 (1 << 2)
+#define AT91_PMC_PRES_4 (2 << 2)
+#define AT91_PMC_PRES_8 (3 << 2)
+#define AT91_PMC_PRES_16 (4 << 2)
+#define AT91_PMC_PRES_32 (5 << 2)
+#define AT91_PMC_PRES_64 (6 << 2)
+#define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */
+#define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */
+#define AT91RM9200_PMC_MDIV_2 (1 << 8)
+#define AT91RM9200_PMC_MDIV_3 (2 << 8)
+#define AT91RM9200_PMC_MDIV_4 (3 << 8)
+#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */
+#define AT91SAM9_PMC_MDIV_2 (1 << 8)
+#define AT91SAM9_PMC_MDIV_4 (2 << 8)
+#define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */
+#define AT91SAM9_PMC_MDIV_3 (3 << 8) /* [some SAM9 only] */
+#define AT91_PMC_PDIV (1 << 12) /* Processor Clock Division [some SAM9 only] */
+#define AT91_PMC_PDIV_1 (0 << 12)
+#define AT91_PMC_PDIV_2 (1 << 12)
+#define AT91_PMC_PLLADIV2 (1 << 12) /* PLLA divisor by 2 [some SAM9 only] */
+#define AT91_PMC_PLLADIV2_OFF (0 << 12)
+#define AT91_PMC_PLLADIV2_ON (1 << 12)
+
+#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register [some SAM9 only] */
+#define AT91_PMC_USBS (0x1 << 0) /* USB OHCI Input clock selection */
+#define AT91_PMC_USBS_PLLA (0 << 0)
+#define AT91_PMC_USBS_UPLL (1 << 0)
+#define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */
+
+#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */
+#define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */
+#define AT91_PMC_CSSMCK_CSS (0 << 8)
+#define AT91_PMC_CSSMCK_MCK (1 << 8)
+
+#define AT91_PMC_IER (AT91_PMC + 0x60) /* Interrupt Enable Register */
+#define AT91_PMC_IDR (AT91_PMC + 0x64) /* Interrupt Disable Register */
+#define AT91_PMC_SR (AT91_PMC + 0x68) /* Status Register */
+#define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */
+#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */
+#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
+#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
+#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */
+#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */
+#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
+#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
+#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
+#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */
+#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */
+
+#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */
+#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */
+
+#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_rstc.h b/arch/arm/mach-at91/include/mach/at91_rstc.h
new file mode 100644
index 00000000..cbd2bf05
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_rstc.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_rstc.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Reset Controller (RSTC) - System peripherals regsters.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91_RSTC_H
+#define AT91_RSTC_H
+
+#define AT91_RSTC_CR (AT91_RSTC + 0x00) /* Reset Controller Control Register */
+#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
+#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
+#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
+#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
+
+#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */
+#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
+#define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */
+#define AT91_RSTC_RSTTYP_GENERAL (0 << 8)
+#define AT91_RSTC_RSTTYP_WAKEUP (1 << 8)
+#define AT91_RSTC_RSTTYP_WATCHDOG (2 << 8)
+#define AT91_RSTC_RSTTYP_SOFTWARE (3 << 8)
+#define AT91_RSTC_RSTTYP_USER (4 << 8)
+#define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */
+#define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */
+
+#define AT91_RSTC_MR (AT91_RSTC + 0x08) /* Reset Controller Mode Register */
+#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
+#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
+#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_rtc.h b/arch/arm/mach-at91/include/mach/at91_rtc.h
new file mode 100644
index 00000000..e56f4701
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_rtc.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_rtc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Real Time Clock (RTC) - System peripheral registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_RTC_H
+#define AT91_RTC_H
+
+#define AT91_RTC_CR (AT91_RTC + 0x00) /* Control Register */
+#define AT91_RTC_UPDTIM (1 << 0) /* Update Request Time Register */
+#define AT91_RTC_UPDCAL (1 << 1) /* Update Request Calendar Register */
+#define AT91_RTC_TIMEVSEL (3 << 8) /* Time Event Selection */
+#define AT91_RTC_TIMEVSEL_MINUTE (0 << 8)
+#define AT91_RTC_TIMEVSEL_HOUR (1 << 8)
+#define AT91_RTC_TIMEVSEL_DAY24 (2 << 8)
+#define AT91_RTC_TIMEVSEL_DAY12 (3 << 8)
+#define AT91_RTC_CALEVSEL (3 << 16) /* Calendar Event Selection */
+#define AT91_RTC_CALEVSEL_WEEK (0 << 16)
+#define AT91_RTC_CALEVSEL_MONTH (1 << 16)
+#define AT91_RTC_CALEVSEL_YEAR (2 << 16)
+
+#define AT91_RTC_MR (AT91_RTC + 0x04) /* Mode Register */
+#define AT91_RTC_HRMOD (1 << 0) /* 12/24 Hour Mode */
+
+#define AT91_RTC_TIMR (AT91_RTC + 0x08) /* Time Register */
+#define AT91_RTC_SEC (0x7f << 0) /* Current Second */
+#define AT91_RTC_MIN (0x7f << 8) /* Current Minute */
+#define AT91_RTC_HOUR (0x3f << 16) /* Current Hour */
+#define AT91_RTC_AMPM (1 << 22) /* Ante Meridiem Post Meridiem Indicator */
+
+#define AT91_RTC_CALR (AT91_RTC + 0x0c) /* Calendar Register */
+#define AT91_RTC_CENT (0x7f << 0) /* Current Century */
+#define AT91_RTC_YEAR (0xff << 8) /* Current Year */
+#define AT91_RTC_MONTH (0x1f << 16) /* Current Month */
+#define AT91_RTC_DAY (7 << 21) /* Current Day */
+#define AT91_RTC_DATE (0x3f << 24) /* Current Date */
+
+#define AT91_RTC_TIMALR (AT91_RTC + 0x10) /* Time Alarm Register */
+#define AT91_RTC_SECEN (1 << 7) /* Second Alarm Enable */
+#define AT91_RTC_MINEN (1 << 15) /* Minute Alarm Enable */
+#define AT91_RTC_HOUREN (1 << 23) /* Hour Alarm Enable */
+
+#define AT91_RTC_CALALR (AT91_RTC + 0x14) /* Calendar Alarm Register */
+#define AT91_RTC_MTHEN (1 << 23) /* Month Alarm Enable */
+#define AT91_RTC_DATEEN (1 << 31) /* Date Alarm Enable */
+
+#define AT91_RTC_SR (AT91_RTC + 0x18) /* Status Register */
+#define AT91_RTC_ACKUPD (1 << 0) /* Acknowledge for Update */
+#define AT91_RTC_ALARM (1 << 1) /* Alarm Flag */
+#define AT91_RTC_SECEV (1 << 2) /* Second Event */
+#define AT91_RTC_TIMEV (1 << 3) /* Time Event */
+#define AT91_RTC_CALEV (1 << 4) /* Calendar Event */
+
+#define AT91_RTC_SCCR (AT91_RTC + 0x1c) /* Status Clear Command Register */
+#define AT91_RTC_IER (AT91_RTC + 0x20) /* Interrupt Enable Register */
+#define AT91_RTC_IDR (AT91_RTC + 0x24) /* Interrupt Disable Register */
+#define AT91_RTC_IMR (AT91_RTC + 0x28) /* Interrupt Mask Register */
+
+#define AT91_RTC_VER (AT91_RTC + 0x2c) /* Valid Entry Register */
+#define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */
+#define AT91_RTC_NVCAL (1 << 1) /* Non valid Calendar */
+#define AT91_RTC_NVTIMALR (1 << 2) /* Non valid Time Alarm */
+#define AT91_RTC_NVCALALR (1 << 3) /* Non valid Calendar Alarm */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h
new file mode 100644
index 00000000..7ec75de8
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_rtt.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_rtt.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Real-time Timer (RTT) - System peripherals regsters.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91_RTT_H
+#define AT91_RTT_H
+
+#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
+#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */
+#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
+#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
+#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */
+
+#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
+#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
+
+#define AT91_RTT_VR 0x08 /* Real-time Value Register */
+#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
+
+#define AT91_RTT_SR 0x0c /* Real-time Status Register */
+#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
+#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_shdwc.h b/arch/arm/mach-at91/include/mach/at91_shdwc.h
new file mode 100644
index 00000000..c4ce07e8
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_shdwc.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_shdwc.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Shutdown Controller (SHDWC) - System peripherals regsters.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91_SHDWC_H
+#define AT91_SHDWC_H
+
+#define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */
+#define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */
+#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */
+
+#define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */
+#define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */
+#define AT91_SHDW_WKMODE0_NONE 0
+#define AT91_SHDW_WKMODE0_HIGH 1
+#define AT91_SHDW_WKMODE0_LOW 2
+#define AT91_SHDW_WKMODE0_ANYLEVEL 3
+#define AT91_SHDW_CPTWK0 (0xf << 4) /* Counter On Wake Up 0 */
+#define AT91_SHDW_CPTWK0_(x) ((x) << 4)
+#define AT91_SHDW_RTTWKEN (1 << 16) /* Real Time Timer Wake-up Enable */
+
+#define AT91_SHDW_SR (AT91_SHDWC + 0x08) /* Shut Down Status Register */
+#define AT91_SHDW_WAKEUP0 (1 << 0) /* Wake-up 0 Status */
+#define AT91_SHDW_RTTWK (1 << 16) /* Real-time Timer Wake-up */
+#define AT91_SHDW_RTCWK (1 << 17) /* Real-time Clock Wake-up [SAM9RL] */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_spi.h b/arch/arm/mach-at91/include/mach/at91_spi.h
new file mode 100644
index 00000000..2f6ba0c5
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_spi.h
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_spi.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Serial Peripheral Interface (SPI) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_SPI_H
+#define AT91_SPI_H
+
+#define AT91_SPI_CR 0x00 /* Control Register */
+#define AT91_SPI_SPIEN (1 << 0) /* SPI Enable */
+#define AT91_SPI_SPIDIS (1 << 1) /* SPI Disable */
+#define AT91_SPI_SWRST (1 << 7) /* SPI Software Reset */
+#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */
+
+#define AT91_SPI_MR 0x04 /* Mode Register */
+#define AT91_SPI_MSTR (1 << 0) /* Master/Slave Mode */
+#define AT91_SPI_PS (1 << 1) /* Peripheral Select */
+#define AT91_SPI_PS_FIXED (0 << 1)
+#define AT91_SPI_PS_VARIABLE (1 << 1)
+#define AT91_SPI_PCSDEC (1 << 2) /* Chip Select Decode */
+#define AT91_SPI_DIV32 (1 << 3) /* Clock Selection [AT91RM9200 only] */
+#define AT91_SPI_MODFDIS (1 << 4) /* Mode Fault Detection */
+#define AT91_SPI_LLB (1 << 7) /* Local Loopback Enable */
+#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */
+#define AT91_SPI_DLYBCS (0xff << 24) /* Delay Between Chip Selects */
+
+#define AT91_SPI_RDR 0x08 /* Receive Data Register */
+#define AT91_SPI_RD (0xffff << 0) /* Receive Data */
+#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */
+
+#define AT91_SPI_TDR 0x0c /* Transmit Data Register */
+#define AT91_SPI_TD (0xffff << 0) /* Transmit Data */
+#define AT91_SPI_PCS (0xf << 16) /* Peripheral Chip Select */
+#define AT91_SPI_LASTXFER (1 << 24) /* Last Transfer [SAM9261 only] */
+
+#define AT91_SPI_SR 0x10 /* Status Register */
+#define AT91_SPI_RDRF (1 << 0) /* Receive Data Register Full */
+#define AT91_SPI_TDRE (1 << 1) /* Transmit Data Register Full */
+#define AT91_SPI_MODF (1 << 2) /* Mode Fault Error */
+#define AT91_SPI_OVRES (1 << 3) /* Overrun Error Status */
+#define AT91_SPI_ENDRX (1 << 4) /* End of RX buffer */
+#define AT91_SPI_ENDTX (1 << 5) /* End of TX buffer */
+#define AT91_SPI_RXBUFF (1 << 6) /* RX Buffer Full */
+#define AT91_SPI_TXBUFE (1 << 7) /* TX Buffer Empty */
+#define AT91_SPI_NSSR (1 << 8) /* NSS Rising [SAM9261 only] */
+#define AT91_SPI_TXEMPTY (1 << 9) /* Transmission Register Empty [SAM9261 only] */
+#define AT91_SPI_SPIENS (1 << 16) /* SPI Enable Status */
+
+#define AT91_SPI_IER 0x14 /* Interrupt Enable Register */
+#define AT91_SPI_IDR 0x18 /* Interrupt Disable Register */
+#define AT91_SPI_IMR 0x1c /* Interrupt Mask Register */
+
+#define AT91_SPI_CSR(n) (0x30 + ((n) * 4)) /* Chip Select Registers 0-3 */
+#define AT91_SPI_CPOL (1 << 0) /* Clock Polarity */
+#define AT91_SPI_NCPHA (1 << 1) /* Clock Phase */
+#define AT91_SPI_CSAAT (1 << 3) /* Chip Select Active After Transfer [SAM9261 only] */
+#define AT91_SPI_BITS (0xf << 4) /* Bits Per Transfer */
+#define AT91_SPI_BITS_8 (0 << 4)
+#define AT91_SPI_BITS_9 (1 << 4)
+#define AT91_SPI_BITS_10 (2 << 4)
+#define AT91_SPI_BITS_11 (3 << 4)
+#define AT91_SPI_BITS_12 (4 << 4)
+#define AT91_SPI_BITS_13 (5 << 4)
+#define AT91_SPI_BITS_14 (6 << 4)
+#define AT91_SPI_BITS_15 (7 << 4)
+#define AT91_SPI_BITS_16 (8 << 4)
+#define AT91_SPI_SCBR (0xff << 8) /* Serial Clock Baud Rate */
+#define AT91_SPI_DLYBS (0xff << 16) /* Delay before SPCK */
+#define AT91_SPI_DLYBCT (0xff << 24) /* Delay between Consecutive Transfers */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_ssc.h b/arch/arm/mach-at91/include/mach/at91_ssc.h
new file mode 100644
index 00000000..a81114c1
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_ssc.h
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_ssc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Serial Synchronous Controller (SSC) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_SSC_H
+#define AT91_SSC_H
+
+#define AT91_SSC_CR 0x00 /* Control Register */
+#define AT91_SSC_RXEN (1 << 0) /* Receive Enable */
+#define AT91_SSC_RXDIS (1 << 1) /* Receive Disable */
+#define AT91_SSC_TXEN (1 << 8) /* Transmit Enable */
+#define AT91_SSC_TXDIS (1 << 9) /* Transmit Disable */
+#define AT91_SSC_SWRST (1 << 15) /* Software Reset */
+
+#define AT91_SSC_CMR 0x04 /* Clock Mode Register */
+#define AT91_SSC_CMR_DIV (0xfff << 0) /* Clock Divider */
+
+#define AT91_SSC_RCMR 0x10 /* Receive Clock Mode Register */
+#define AT91_SSC_CKS (3 << 0) /* Clock Selection */
+#define AT91_SSC_CKS_DIV (0 << 0)
+#define AT91_SSC_CKS_CLOCK (1 << 0)
+#define AT91_SSC_CKS_PIN (2 << 0)
+#define AT91_SSC_CKO (7 << 2) /* Clock Output Mode Selection */
+#define AT91_SSC_CKO_NONE (0 << 2)
+#define AT91_SSC_CKO_CONTINUOUS (1 << 2)
+#define AT91_SSC_CKI (1 << 5) /* Clock Inversion */
+#define AT91_SSC_CKI_FALLING (0 << 5)
+#define AT91_SSC_CK_RISING (1 << 5)
+#define AT91_SSC_CKG (1 << 6) /* Receive Clock Gating Selection [AT91SAM9261 only] */
+#define AT91_SSC_CKG_NONE (0 << 6)
+#define AT91_SSC_CKG_RFLOW (1 << 6)
+#define AT91_SSC_CKG_RFHIGH (2 << 6)
+#define AT91_SSC_START (0xf << 8) /* Start Selection */
+#define AT91_SSC_START_CONTINUOUS (0 << 8)
+#define AT91_SSC_START_TX_RX (1 << 8)
+#define AT91_SSC_START_LOW_RF (2 << 8)
+#define AT91_SSC_START_HIGH_RF (3 << 8)
+#define AT91_SSC_START_FALLING_RF (4 << 8)
+#define AT91_SSC_START_RISING_RF (5 << 8)
+#define AT91_SSC_START_LEVEL_RF (6 << 8)
+#define AT91_SSC_START_EDGE_RF (7 << 8)
+#define AT91_SSC_STOP (1 << 12) /* Receive Stop Selection [AT91SAM9261 only] */
+#define AT91_SSC_STTDLY (0xff << 16) /* Start Delay */
+#define AT91_SSC_PERIOD (0xff << 24) /* Period Divider Selection */
+
+#define AT91_SSC_RFMR 0x14 /* Receive Frame Mode Register */
+#define AT91_SSC_DATALEN (0x1f << 0) /* Data Length */
+#define AT91_SSC_LOOP (1 << 5) /* Loop Mode */
+#define AT91_SSC_MSBF (1 << 7) /* Most Significant Bit First */
+#define AT91_SSC_DATNB (0xf << 8) /* Data Number per Frame */
+#define AT91_SSC_FSLEN (0xf << 16) /* Frame Sync Length */
+#define AT91_SSC_FSOS (7 << 20) /* Frame Sync Output Selection */
+#define AT91_SSC_FSOS_NONE (0 << 20)
+#define AT91_SSC_FSOS_NEGATIVE (1 << 20)
+#define AT91_SSC_FSOS_POSITIVE (2 << 20)
+#define AT91_SSC_FSOS_LOW (3 << 20)
+#define AT91_SSC_FSOS_HIGH (4 << 20)
+#define AT91_SSC_FSOS_TOGGLE (5 << 20)
+#define AT91_SSC_FSEDGE (1 << 24) /* Frame Sync Edge Detection */
+#define AT91_SSC_FSEDGE_POSITIVE (0 << 24)
+#define AT91_SSC_FSEDGE_NEGATIVE (1 << 24)
+
+#define AT91_SSC_TCMR 0x18 /* Transmit Clock Mode Register */
+#define AT91_SSC_TFMR 0x1c /* Transmit Fram Mode Register */
+#define AT91_SSC_DATDEF (1 << 5) /* Data Default Value */
+#define AT91_SSC_FSDEN (1 << 23) /* Frame Sync Data Enable */
+
+#define AT91_SSC_RHR 0x20 /* Receive Holding Register */
+#define AT91_SSC_THR 0x24 /* Transmit Holding Register */
+#define AT91_SSC_RSHR 0x30 /* Receive Sync Holding Register */
+#define AT91_SSC_TSHR 0x34 /* Transmit Sync Holding Register */
+
+#define AT91_SSC_RC0R 0x38 /* Receive Compare 0 Register [AT91SAM9261 only] */
+#define AT91_SSC_RC1R 0x3c /* Receive Compare 1 Register [AT91SAM9261 only] */
+
+#define AT91_SSC_SR 0x40 /* Status Register */
+#define AT91_SSC_TXRDY (1 << 0) /* Transmit Ready */
+#define AT91_SSC_TXEMPTY (1 << 1) /* Transmit Empty */
+#define AT91_SSC_ENDTX (1 << 2) /* End of Transmission */
+#define AT91_SSC_TXBUFE (1 << 3) /* Transmit Buffer Empty */
+#define AT91_SSC_RXRDY (1 << 4) /* Receive Ready */
+#define AT91_SSC_OVRUN (1 << 5) /* Receive Overrun */
+#define AT91_SSC_ENDRX (1 << 6) /* End of Reception */
+#define AT91_SSC_RXBUFF (1 << 7) /* Receive Buffer Full */
+#define AT91_SSC_CP0 (1 << 8) /* Compare 0 [AT91SAM9261 only] */
+#define AT91_SSC_CP1 (1 << 9) /* Compare 1 [AT91SAM9261 only] */
+#define AT91_SSC_TXSYN (1 << 10) /* Transmit Sync */
+#define AT91_SSC_RXSYN (1 << 11) /* Receive Sync */
+#define AT91_SSC_TXENA (1 << 16) /* Transmit Enable */
+#define AT91_SSC_RXENA (1 << 17) /* Receive Enable */
+
+#define AT91_SSC_IER 0x44 /* Interrupt Enable Register */
+#define AT91_SSC_IDR 0x48 /* Interrupt Disable Register */
+#define AT91_SSC_IMR 0x4c /* Interrupt Mask Register */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_st.h b/arch/arm/mach-at91/include/mach/at91_st.h
new file mode 100644
index 00000000..8847173e
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_st.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_st.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * System Timer (ST) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_ST_H
+#define AT91_ST_H
+
+#define AT91_ST_CR (AT91_ST + 0x00) /* Control Register */
+#define AT91_ST_WDRST (1 << 0) /* Watchdog Timer Restart */
+
+#define AT91_ST_PIMR (AT91_ST + 0x04) /* Period Interval Mode Register */
+#define AT91_ST_PIV (0xffff << 0) /* Period Interval Value */
+
+#define AT91_ST_WDMR (AT91_ST + 0x08) /* Watchdog Mode Register */
+#define AT91_ST_WDV (0xffff << 0) /* Watchdog Counter Value */
+#define AT91_ST_RSTEN (1 << 16) /* Reset Enable */
+#define AT91_ST_EXTEN (1 << 17) /* External Signal Assertion Enable */
+
+#define AT91_ST_RTMR (AT91_ST + 0x0c) /* Real-time Mode Register */
+#define AT91_ST_RTPRES (0xffff << 0) /* Real-time Prescalar Value */
+
+#define AT91_ST_SR (AT91_ST + 0x10) /* Status Register */
+#define AT91_ST_PITS (1 << 0) /* Period Interval Timer Status */
+#define AT91_ST_WDOVF (1 << 1) /* Watchdog Overflow */
+#define AT91_ST_RTTINC (1 << 2) /* Real-time Timer Increment */
+#define AT91_ST_ALMS (1 << 3) /* Alarm Status */
+
+#define AT91_ST_IER (AT91_ST + 0x14) /* Interrupt Enable Register */
+#define AT91_ST_IDR (AT91_ST + 0x18) /* Interrupt Disable Register */
+#define AT91_ST_IMR (AT91_ST + 0x1c) /* Interrupt Mask Register */
+
+#define AT91_ST_RTAR (AT91_ST + 0x20) /* Real-time Alarm Register */
+#define AT91_ST_ALMV (0xfffff << 0) /* Alarm Value */
+
+#define AT91_ST_CRTR (AT91_ST + 0x24) /* Current Real-time Register */
+#define AT91_ST_CRTV (0xfffff << 0) /* Current Real-Time Value */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_tc.h b/arch/arm/mach-at91/include/mach/at91_tc.h
new file mode 100644
index 00000000..46a317fd
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_tc.h
@@ -0,0 +1,146 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_tc.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Timer/Counter Unit (TC) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_TC_H
+#define AT91_TC_H
+
+#define AT91_TC_BCR 0xc0 /* TC Block Control Register */
+#define AT91_TC_SYNC (1 << 0) /* Synchro Command */
+
+#define AT91_TC_BMR 0xc4 /* TC Block Mode Register */
+#define AT91_TC_TC0XC0S (3 << 0) /* External Clock Signal 0 Selection */
+#define AT91_TC_TC0XC0S_TCLK0 (0 << 0)
+#define AT91_TC_TC0XC0S_NONE (1 << 0)
+#define AT91_TC_TC0XC0S_TIOA1 (2 << 0)
+#define AT91_TC_TC0XC0S_TIOA2 (3 << 0)
+#define AT91_TC_TC1XC1S (3 << 2) /* External Clock Signal 1 Selection */
+#define AT91_TC_TC1XC1S_TCLK1 (0 << 2)
+#define AT91_TC_TC1XC1S_NONE (1 << 2)
+#define AT91_TC_TC1XC1S_TIOA0 (2 << 2)
+#define AT91_TC_TC1XC1S_TIOA2 (3 << 2)
+#define AT91_TC_TC2XC2S (3 << 4) /* External Clock Signal 2 Selection */
+#define AT91_TC_TC2XC2S_TCLK2 (0 << 4)
+#define AT91_TC_TC2XC2S_NONE (1 << 4)
+#define AT91_TC_TC2XC2S_TIOA0 (2 << 4)
+#define AT91_TC_TC2XC2S_TIOA1 (3 << 4)
+
+
+#define AT91_TC_CCR 0x00 /* Channel Control Register */
+#define AT91_TC_CLKEN (1 << 0) /* Counter Clock Enable Command */
+#define AT91_TC_CLKDIS (1 << 1) /* Counter CLock Disable Command */
+#define AT91_TC_SWTRG (1 << 2) /* Software Trigger Command */
+
+#define AT91_TC_CMR 0x04 /* Channel Mode Register */
+#define AT91_TC_TCCLKS (7 << 0) /* Capture/Waveform Mode: Clock Selection */
+#define AT91_TC_TIMER_CLOCK1 (0 << 0)
+#define AT91_TC_TIMER_CLOCK2 (1 << 0)
+#define AT91_TC_TIMER_CLOCK3 (2 << 0)
+#define AT91_TC_TIMER_CLOCK4 (3 << 0)
+#define AT91_TC_TIMER_CLOCK5 (4 << 0)
+#define AT91_TC_XC0 (5 << 0)
+#define AT91_TC_XC1 (6 << 0)
+#define AT91_TC_XC2 (7 << 0)
+#define AT91_TC_CLKI (1 << 3) /* Capture/Waveform Mode: Clock Invert */
+#define AT91_TC_BURST (3 << 4) /* Capture/Waveform Mode: Burst Signal Selection */
+#define AT91_TC_LDBSTOP (1 << 6) /* Capture Mode: Counter Clock Stopped with TB Loading */
+#define AT91_TC_LDBDIS (1 << 7) /* Capture Mode: Counter Clock Disable with RB Loading */
+#define AT91_TC_ETRGEDG (3 << 8) /* Capture Mode: External Trigger Edge Selection */
+#define AT91_TC_ABETRG (1 << 10) /* Capture Mode: TIOA or TIOB External Trigger Selection */
+#define AT91_TC_CPCTRG (1 << 14) /* Capture Mode: RC Compare Trigger Enable */
+#define AT91_TC_WAVE (1 << 15) /* Capture/Waveform mode */
+#define AT91_TC_LDRA (3 << 16) /* Capture Mode: RA Loading Selection */
+#define AT91_TC_LDRB (3 << 18) /* Capture Mode: RB Loading Selection */
+
+#define AT91_TC_CPCSTOP (1 << 6) /* Waveform Mode: Counter Clock Stopped with RC Compare */
+#define AT91_TC_CPCDIS (1 << 7) /* Waveform Mode: Counter Clock Disable with RC Compare */
+#define AT91_TC_EEVTEDG (3 << 8) /* Waveform Mode: External Event Edge Selection */
+#define AT91_TC_EEVTEDG_NONE (0 << 8)
+#define AT91_TC_EEVTEDG_RISING (1 << 8)
+#define AT91_TC_EEVTEDG_FALLING (2 << 8)
+#define AT91_TC_EEVTEDG_BOTH (3 << 8)
+#define AT91_TC_EEVT (3 << 10) /* Waveform Mode: External Event Selection */
+#define AT91_TC_EEVT_TIOB (0 << 10)
+#define AT91_TC_EEVT_XC0 (1 << 10)
+#define AT91_TC_EEVT_XC1 (2 << 10)
+#define AT91_TC_EEVT_XC2 (3 << 10)
+#define AT91_TC_ENETRG (1 << 12) /* Waveform Mode: External Event Trigger Enable */
+#define AT91_TC_WAVESEL (3 << 13) /* Waveform Mode: Waveform Selection */
+#define AT91_TC_WAVESEL_UP (0 << 13)
+#define AT91_TC_WAVESEL_UP_AUTO (2 << 13)
+#define AT91_TC_WAVESEL_UPDOWN (1 << 13)
+#define AT91_TC_WAVESEL_UPDOWN_AUTO (3 << 13)
+#define AT91_TC_ACPA (3 << 16) /* Waveform Mode: RA Compare Effect on TIOA */
+#define AT91_TC_ACPA_NONE (0 << 16)
+#define AT91_TC_ACPA_SET (1 << 16)
+#define AT91_TC_ACPA_CLEAR (2 << 16)
+#define AT91_TC_ACPA_TOGGLE (3 << 16)
+#define AT91_TC_ACPC (3 << 18) /* Waveform Mode: RC Compre Effect on TIOA */
+#define AT91_TC_ACPC_NONE (0 << 18)
+#define AT91_TC_ACPC_SET (1 << 18)
+#define AT91_TC_ACPC_CLEAR (2 << 18)
+#define AT91_TC_ACPC_TOGGLE (3 << 18)
+#define AT91_TC_AEEVT (3 << 20) /* Waveform Mode: External Event Effect on TIOA */
+#define AT91_TC_AEEVT_NONE (0 << 20)
+#define AT91_TC_AEEVT_SET (1 << 20)
+#define AT91_TC_AEEVT_CLEAR (2 << 20)
+#define AT91_TC_AEEVT_TOGGLE (3 << 20)
+#define AT91_TC_ASWTRG (3 << 22) /* Waveform Mode: Software Trigger Effect on TIOA */
+#define AT91_TC_ASWTRG_NONE (0 << 22)
+#define AT91_TC_ASWTRG_SET (1 << 22)
+#define AT91_TC_ASWTRG_CLEAR (2 << 22)
+#define AT91_TC_ASWTRG_TOGGLE (3 << 22)
+#define AT91_TC_BCPB (3 << 24) /* Waveform Mode: RB Compare Effect on TIOB */
+#define AT91_TC_BCPB_NONE (0 << 24)
+#define AT91_TC_BCPB_SET (1 << 24)
+#define AT91_TC_BCPB_CLEAR (2 << 24)
+#define AT91_TC_BCPB_TOGGLE (3 << 24)
+#define AT91_TC_BCPC (3 << 26) /* Waveform Mode: RC Compare Effect on TIOB */
+#define AT91_TC_BCPC_NONE (0 << 26)
+#define AT91_TC_BCPC_SET (1 << 26)
+#define AT91_TC_BCPC_CLEAR (2 << 26)
+#define AT91_TC_BCPC_TOGGLE (3 << 26)
+#define AT91_TC_BEEVT (3 << 28) /* Waveform Mode: External Event Effect on TIOB */
+#define AT91_TC_BEEVT_NONE (0 << 28)
+#define AT91_TC_BEEVT_SET (1 << 28)
+#define AT91_TC_BEEVT_CLEAR (2 << 28)
+#define AT91_TC_BEEVT_TOGGLE (3 << 28)
+#define AT91_TC_BSWTRG (3 << 30) /* Waveform Mode: Software Trigger Effect on TIOB */
+#define AT91_TC_BSWTRG_NONE (0 << 30)
+#define AT91_TC_BSWTRG_SET (1 << 30)
+#define AT91_TC_BSWTRG_CLEAR (2 << 30)
+#define AT91_TC_BSWTRG_TOGGLE (3 << 30)
+
+#define AT91_TC_CV 0x10 /* Counter Value */
+#define AT91_TC_RA 0x14 /* Register A */
+#define AT91_TC_RB 0x18 /* Register B */
+#define AT91_TC_RC 0x1c /* Register C */
+
+#define AT91_TC_SR 0x20 /* Status Register */
+#define AT91_TC_COVFS (1 << 0) /* Counter Overflow Status */
+#define AT91_TC_LOVRS (1 << 1) /* Load Overrun Status */
+#define AT91_TC_CPAS (1 << 2) /* RA Compare Status */
+#define AT91_TC_CPBS (1 << 3) /* RB Compare Status */
+#define AT91_TC_CPCS (1 << 4) /* RC Compare Status */
+#define AT91_TC_LDRAS (1 << 5) /* RA Loading Status */
+#define AT91_TC_LDRBS (1 << 6) /* RB Loading Status */
+#define AT91_TC_ETRGS (1 << 7) /* External Trigger Status */
+#define AT91_TC_CLKSTA (1 << 16) /* Clock Enabling Status */
+#define AT91_TC_MTIOA (1 << 17) /* TIOA Mirror */
+#define AT91_TC_MTIOB (1 << 18) /* TIOB Mirror */
+
+#define AT91_TC_IER 0x24 /* Interrupt Enable Register */
+#define AT91_TC_IDR 0x28 /* Interrupt Disable Register */
+#define AT91_TC_IMR 0x2c /* Interrupt Mask Register */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_twi.h b/arch/arm/mach-at91/include/mach/at91_twi.h
new file mode 100644
index 00000000..bb2880f6
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_twi.h
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_twi.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Two-wire Interface (TWI) registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91_TWI_H
+#define AT91_TWI_H
+
+#define AT91_TWI_CR 0x00 /* Control Register */
+#define AT91_TWI_START (1 << 0) /* Send a Start Condition */
+#define AT91_TWI_STOP (1 << 1) /* Send a Stop Condition */
+#define AT91_TWI_MSEN (1 << 2) /* Master Transfer Enable */
+#define AT91_TWI_MSDIS (1 << 3) /* Master Transfer Disable */
+#define AT91_TWI_SVEN (1 << 4) /* Slave Transfer Enable [SAM9260 only] */
+#define AT91_TWI_SVDIS (1 << 5) /* Slave Transfer Disable [SAM9260 only] */
+#define AT91_TWI_SWRST (1 << 7) /* Software Reset */
+
+#define AT91_TWI_MMR 0x04 /* Master Mode Register */
+#define AT91_TWI_IADRSZ (3 << 8) /* Internal Device Address Size */
+#define AT91_TWI_IADRSZ_NO (0 << 8)
+#define AT91_TWI_IADRSZ_1 (1 << 8)
+#define AT91_TWI_IADRSZ_2 (2 << 8)
+#define AT91_TWI_IADRSZ_3 (3 << 8)
+#define AT91_TWI_MREAD (1 << 12) /* Master Read Direction */
+#define AT91_TWI_DADR (0x7f << 16) /* Device Address */
+
+#define AT91_TWI_SMR 0x08 /* Slave Mode Register [SAM9260 only] */
+#define AT91_TWI_SADR (0x7f << 16) /* Slave Address */
+
+#define AT91_TWI_IADR 0x0c /* Internal Address Register */
+
+#define AT91_TWI_CWGR 0x10 /* Clock Waveform Generator Register */
+#define AT91_TWI_CLDIV (0xff << 0) /* Clock Low Divisor */
+#define AT91_TWI_CHDIV (0xff << 8) /* Clock High Divisor */
+#define AT91_TWI_CKDIV (7 << 16) /* Clock Divider */
+
+#define AT91_TWI_SR 0x20 /* Status Register */
+#define AT91_TWI_TXCOMP (1 << 0) /* Transmission Complete */
+#define AT91_TWI_RXRDY (1 << 1) /* Receive Holding Register Ready */
+#define AT91_TWI_TXRDY (1 << 2) /* Transmit Holding Register Ready */
+#define AT91_TWI_SVREAD (1 << 3) /* Slave Read [SAM9260 only] */
+#define AT91_TWI_SVACC (1 << 4) /* Slave Access [SAM9260 only] */
+#define AT91_TWI_GACC (1 << 5) /* General Call Access [SAM9260 only] */
+#define AT91_TWI_OVRE (1 << 6) /* Overrun Error [AT91RM9200 only] */
+#define AT91_TWI_UNRE (1 << 7) /* Underrun Error [AT91RM9200 only] */
+#define AT91_TWI_NACK (1 << 8) /* Not Acknowledged */
+#define AT91_TWI_ARBLST (1 << 9) /* Arbitration Lost [SAM9260 only] */
+#define AT91_TWI_SCLWS (1 << 10) /* Clock Wait State [SAM9260 only] */
+#define AT91_TWI_EOSACC (1 << 11) /* End of Slave Address [SAM9260 only] */
+
+#define AT91_TWI_IER 0x24 /* Interrupt Enable Register */
+#define AT91_TWI_IDR 0x28 /* Interrupt Disable Register */
+#define AT91_TWI_IMR 0x2c /* Interrupt Mask Register */
+#define AT91_TWI_RHR 0x30 /* Receive Holding Register */
+#define AT91_TWI_THR 0x34 /* Transmit Holding Register */
+
+#endif
+
diff --git a/arch/arm/mach-at91/include/mach/at91_wdt.h b/arch/arm/mach-at91/include/mach/at91_wdt.h
new file mode 100644
index 00000000..fecc2e9f
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91_wdt.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91_wdt.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Watchdog Timer (WDT) - System peripherals regsters.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91_WDT_H
+#define AT91_WDT_H
+
+#define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */
+#define AT91_WDT_WDRSTT (1 << 0) /* Restart */
+#define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */
+
+#define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */
+#define AT91_WDT_WDV (0xfff << 0) /* Counter Value */
+#define AT91_WDT_WDFIEN (1 << 12) /* Fault Interrupt Enable */
+#define AT91_WDT_WDRSTEN (1 << 13) /* Reset Processor */
+#define AT91_WDT_WDRPROC (1 << 14) /* Timer Restart */
+#define AT91_WDT_WDDIS (1 << 15) /* Watchdog Disable */
+#define AT91_WDT_WDD (0xfff << 16) /* Delta Value */
+#define AT91_WDT_WDDBGHLT (1 << 28) /* Debug Halt */
+#define AT91_WDT_WDIDLEHLT (1 << 29) /* Idle Halt */
+
+#define AT91_WDT_SR (AT91_WDT + 0x08) /* Watchdog Status Register */
+#define AT91_WDT_WDUNF (1 << 0) /* Watchdog Underflow */
+#define AT91_WDT_WDERR (1 << 1) /* Watchdog Error */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
new file mode 100644
index 00000000..66599384
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -0,0 +1,124 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91cap9.h
+ *
+ * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91CAP9 datasheet revision B (Preliminary).
+ *
+ * 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 AT91CAP9_H
+#define AT91CAP9_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */
+#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */
+#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */
+#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */
+#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */
+#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */
+#define AT91CAP9_ID_US0 8 /* USART 0 */
+#define AT91CAP9_ID_US1 9 /* USART 1 */
+#define AT91CAP9_ID_US2 10 /* USART 2 */
+#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */
+#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */
+#define AT91CAP9_ID_CAN 13 /* CAN */
+#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */
+#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */
+#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */
+#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */
+#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */
+#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */
+#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */
+#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */
+#define AT91CAP9_ID_EMAC 22 /* Ethernet */
+#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */
+#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */
+#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */
+#define AT91CAP9_ID_LCDC 26 /* LCD Controller */
+#define AT91CAP9_ID_DMA 27 /* DMA Controller */
+#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */
+#define AT91CAP9_ID_UHP 29 /* USB Host Port */
+#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91CAP9_BASE_UDPHS 0xfff78000
+#define AT91CAP9_BASE_TCB0 0xfff7c000
+#define AT91CAP9_BASE_TC0 0xfff7c000
+#define AT91CAP9_BASE_TC1 0xfff7c040
+#define AT91CAP9_BASE_TC2 0xfff7c080
+#define AT91CAP9_BASE_MCI0 0xfff80000
+#define AT91CAP9_BASE_MCI1 0xfff84000
+#define AT91CAP9_BASE_TWI 0xfff88000
+#define AT91CAP9_BASE_US0 0xfff8c000
+#define AT91CAP9_BASE_US1 0xfff90000
+#define AT91CAP9_BASE_US2 0xfff94000
+#define AT91CAP9_BASE_SSC0 0xfff98000
+#define AT91CAP9_BASE_SSC1 0xfff9c000
+#define AT91CAP9_BASE_AC97C 0xfffa0000
+#define AT91CAP9_BASE_SPI0 0xfffa4000
+#define AT91CAP9_BASE_SPI1 0xfffa8000
+#define AT91CAP9_BASE_CAN 0xfffac000
+#define AT91CAP9_BASE_PWMC 0xfffb8000
+#define AT91CAP9_BASE_EMAC 0xfffbc000
+#define AT91CAP9_BASE_ADC 0xfffc0000
+#define AT91CAP9_BASE_ISI 0xfffc4000
+#define AT91_BASE_SYS 0xffffe200
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
+#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS)
+#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
+#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
+#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS)
+#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
+#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR (cpu_is_at91cap9_revB() ? \
+ (0xfffffd50 - AT91_BASE_SYS) : \
+ (0xfffffd60 - AT91_BASE_SYS))
+
+#define AT91_USART0 AT91CAP9_BASE_US0
+#define AT91_USART1 AT91CAP9_BASE_US1
+#define AT91_USART2 AT91CAP9_BASE_US2
+
+
+/*
+ * Internal Memory.
+ */
+#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */
+#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */
+
+#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */
+#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */
+
+#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */
+#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */
+#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
new file mode 100644
index 00000000..976f4a6c
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+ *
+ * (C) 2008 Andrew Victor
+ *
+ * DDR/SDR Controller (DDRSDRC) - System peripherals registers.
+ * Based on AT91CAP9 datasheet revision B.
+ *
+ * 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 AT91CAP9_DDRSDR_H
+#define AT91CAP9_DDRSDR_H
+
+#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
+#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */
+#define AT91_DDRSDRC_MODE_NORMAL 0
+#define AT91_DDRSDRC_MODE_NOP 1
+#define AT91_DDRSDRC_MODE_PRECHARGE 2
+#define AT91_DDRSDRC_MODE_LMR 3
+#define AT91_DDRSDRC_MODE_REFRESH 4
+#define AT91_DDRSDRC_MODE_EXT_LMR 5
+#define AT91_DDRSDRC_MODE_DEEP 6
+
+#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
+#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
+
+#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
+#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
+#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
+#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
+#define AT91_DDRSDRC_NC_SDR10 (2 << 0)
+#define AT91_DDRSDRC_NC_SDR11 (3 << 0)
+#define AT91_DDRSDRC_NC_DDR9 (0 << 0)
+#define AT91_DDRSDRC_NC_DDR10 (1 << 0)
+#define AT91_DDRSDRC_NC_DDR11 (2 << 0)
+#define AT91_DDRSDRC_NC_DDR12 (3 << 0)
+#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */
+#define AT91_DDRSDRC_NR_11 (0 << 2)
+#define AT91_DDRSDRC_NR_12 (1 << 2)
+#define AT91_DDRSDRC_NR_13 (2 << 2)
+#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */
+#define AT91_DDRSDRC_CAS_2 (2 << 4)
+#define AT91_DDRSDRC_CAS_3 (3 << 4)
+#define AT91_DDRSDRC_CAS_25 (6 << 4)
+#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */
+#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
+
+#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
+#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
+#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
+#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
+#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */
+#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
+#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
+#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
+#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
+
+#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
+#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
+#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
+#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
+#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
+
+#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */
+#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
+#define AT91_DDRSDRC_LPCB_DISABLE 0
+#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
+#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
+#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
+#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
+#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
+#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
+#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
+#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
+#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12)
+#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
+#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
+
+#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */
+#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
+#define AT91_DDRSDRC_MD_SDR 0
+#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
+#define AT91_DDRSDRC_MD_DDR 2
+#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
+
+#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */
+#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
+#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
+#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
+#define AT91_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */
+#define AT91_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */
+#define AT91_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */
+#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
+#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
+#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
+
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
new file mode 100644
index 00000000..4b9d4aff
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
@@ -0,0 +1,137 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+ *
+ * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
+ * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
+ * Copyright (C) 2006 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91CAP9 datasheet revision B (Preliminary).
+ *
+ * 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 AT91CAP9_MATRIX_H
+#define AT91CAP9_MATRIX_H
+
+#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */
+#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */
+#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */
+#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
+#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */
+#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
+#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
+#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
+#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
+#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */
+#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */
+#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */
+#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */
+#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
+#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
+#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
+#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
+#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
+#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
+#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
+#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
+#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
+#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
+#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
+#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define AT91_MATRIX_RCB2 (1 << 2)
+#define AT91_MATRIX_RCB3 (1 << 3)
+#define AT91_MATRIX_RCB4 (1 << 4)
+#define AT91_MATRIX_RCB5 (1 << 5)
+#define AT91_MATRIX_RCB6 (1 << 6)
+#define AT91_MATRIX_RCB7 (1 << 7)
+#define AT91_MATRIX_RCB8 (1 << 8)
+#define AT91_MATRIX_RCB9 (1 << 9)
+#define AT91_MATRIX_RCB10 (1 << 10)
+#define AT91_MATRIX_RCB11 (1 << 11)
+
+#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */
+#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */
+
+#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */
+#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */
+#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */
+#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */
+
+#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1)
+#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4)
+#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5)
+#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */
+#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
+
+#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */
+#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */
+#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h
new file mode 100644
index 00000000..99e0f8d0
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91rm9200.h
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91rm9200.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Common definitions.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91RM9200_H
+#define AT91RM9200_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91RM9200_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91RM9200_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91RM9200_ID_PIOC 4 /* Parallel IO Controller C */
+#define AT91RM9200_ID_PIOD 5 /* Parallel IO Controller D */
+#define AT91RM9200_ID_US0 6 /* USART 0 */
+#define AT91RM9200_ID_US1 7 /* USART 1 */
+#define AT91RM9200_ID_US2 8 /* USART 2 */
+#define AT91RM9200_ID_US3 9 /* USART 3 */
+#define AT91RM9200_ID_MCI 10 /* Multimedia Card Interface */
+#define AT91RM9200_ID_UDP 11 /* USB Device Port */
+#define AT91RM9200_ID_TWI 12 /* Two-Wire Interface */
+#define AT91RM9200_ID_SPI 13 /* Serial Peripheral Interface */
+#define AT91RM9200_ID_SSC0 14 /* Serial Synchronous Controller 0 */
+#define AT91RM9200_ID_SSC1 15 /* Serial Synchronous Controller 1 */
+#define AT91RM9200_ID_SSC2 16 /* Serial Synchronous Controller 2 */
+#define AT91RM9200_ID_TC0 17 /* Timer Counter 0 */
+#define AT91RM9200_ID_TC1 18 /* Timer Counter 1 */
+#define AT91RM9200_ID_TC2 19 /* Timer Counter 2 */
+#define AT91RM9200_ID_TC3 20 /* Timer Counter 3 */
+#define AT91RM9200_ID_TC4 21 /* Timer Counter 4 */
+#define AT91RM9200_ID_TC5 22 /* Timer Counter 5 */
+#define AT91RM9200_ID_UHP 23 /* USB Host port */
+#define AT91RM9200_ID_EMAC 24 /* Ethernet MAC */
+#define AT91RM9200_ID_IRQ0 25 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91RM9200_ID_IRQ1 26 /* Advanced Interrupt Controller (IRQ1) */
+#define AT91RM9200_ID_IRQ2 27 /* Advanced Interrupt Controller (IRQ2) */
+#define AT91RM9200_ID_IRQ3 28 /* Advanced Interrupt Controller (IRQ3) */
+#define AT91RM9200_ID_IRQ4 29 /* Advanced Interrupt Controller (IRQ4) */
+#define AT91RM9200_ID_IRQ5 30 /* Advanced Interrupt Controller (IRQ5) */
+#define AT91RM9200_ID_IRQ6 31 /* Advanced Interrupt Controller (IRQ6) */
+
+
+/*
+ * Peripheral physical base addresses.
+ */
+#define AT91RM9200_BASE_TCB0 0xfffa0000
+#define AT91RM9200_BASE_TC0 0xfffa0000
+#define AT91RM9200_BASE_TC1 0xfffa0040
+#define AT91RM9200_BASE_TC2 0xfffa0080
+#define AT91RM9200_BASE_TCB1 0xfffa4000
+#define AT91RM9200_BASE_TC3 0xfffa4000
+#define AT91RM9200_BASE_TC4 0xfffa4040
+#define AT91RM9200_BASE_TC5 0xfffa4080
+#define AT91RM9200_BASE_UDP 0xfffb0000
+#define AT91RM9200_BASE_MCI 0xfffb4000
+#define AT91RM9200_BASE_TWI 0xfffb8000
+#define AT91RM9200_BASE_EMAC 0xfffbc000
+#define AT91RM9200_BASE_US0 0xfffc0000
+#define AT91RM9200_BASE_US1 0xfffc4000
+#define AT91RM9200_BASE_US2 0xfffc8000
+#define AT91RM9200_BASE_US3 0xfffcc000
+#define AT91RM9200_BASE_SSC0 0xfffd0000
+#define AT91RM9200_BASE_SSC1 0xfffd4000
+#define AT91RM9200_BASE_SSC2 0xfffd8000
+#define AT91RM9200_BASE_SPI 0xfffe0000
+#define AT91_BASE_SYS 0xfffff000
+
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */
+#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS) /* Debug Unit */
+#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS) /* PIO Controller A */
+#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS) /* PIO Controller B */
+#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS) /* PIO Controller C */
+#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS) /* PIO Controller D */
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) /* Power Management Controller */
+#define AT91_ST (0xfffffd00 - AT91_BASE_SYS) /* System Timer */
+#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS) /* Real-Time Clock */
+#define AT91_MC (0xffffff00 - AT91_BASE_SYS) /* Memory Controllers */
+
+#define AT91_USART0 AT91RM9200_BASE_US0
+#define AT91_USART1 AT91RM9200_BASE_US1
+#define AT91_USART2 AT91RM9200_BASE_US2
+#define AT91_USART3 AT91RM9200_BASE_US3
+
+#define AT91_MATRIX 0 /* not supported */
+
+/*
+ * Internal Memory.
+ */
+#define AT91RM9200_ROM_BASE 0x00100000 /* Internal ROM base address */
+#define AT91RM9200_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */
+
+#define AT91RM9200_SRAM_BASE 0x00200000 /* Internal SRAM base address */
+#define AT91RM9200_SRAM_SIZE SZ_16K /* Internal SRAM size (16Kb) */
+
+#define AT91RM9200_UHP_BASE 0x00300000 /* USB Host controller */
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_emac.h b/arch/arm/mach-at91/include/mach/at91rm9200_emac.h
new file mode 100644
index 00000000..b8260cd8
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91rm9200_emac.h
@@ -0,0 +1,138 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91rm9200_emac.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Ethernet MAC registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91RM9200_EMAC_H
+#define AT91RM9200_EMAC_H
+
+#define AT91_EMAC_CTL 0x00 /* Control Register */
+#define AT91_EMAC_LB (1 << 0) /* Loopback */
+#define AT91_EMAC_LBL (1 << 1) /* Loopback Local */
+#define AT91_EMAC_RE (1 << 2) /* Receive Enable */
+#define AT91_EMAC_TE (1 << 3) /* Transmit Enable */
+#define AT91_EMAC_MPE (1 << 4) /* Management Port Enable */
+#define AT91_EMAC_CSR (1 << 5) /* Clear Statistics Registers */
+#define AT91_EMAC_INCSTAT (1 << 6) /* Increment Statistics Registers */
+#define AT91_EMAC_WES (1 << 7) /* Write Enable for Statistics Registers */
+#define AT91_EMAC_BP (1 << 8) /* Back Pressure */
+
+#define AT91_EMAC_CFG 0x04 /* Configuration Register */
+#define AT91_EMAC_SPD (1 << 0) /* Speed */
+#define AT91_EMAC_FD (1 << 1) /* Full Duplex */
+#define AT91_EMAC_BR (1 << 2) /* Bit Rate */
+#define AT91_EMAC_CAF (1 << 4) /* Copy All Frames */
+#define AT91_EMAC_NBC (1 << 5) /* No Broadcast */
+#define AT91_EMAC_MTI (1 << 6) /* Multicast Hash Enable */
+#define AT91_EMAC_UNI (1 << 7) /* Unicast Hash Enable */
+#define AT91_EMAC_BIG (1 << 8) /* Receive 1522 Bytes */
+#define AT91_EMAC_EAE (1 << 9) /* External Address Match Enable */
+#define AT91_EMAC_CLK (3 << 10) /* MDC Clock Divisor */
+#define AT91_EMAC_CLK_DIV8 (0 << 10)
+#define AT91_EMAC_CLK_DIV16 (1 << 10)
+#define AT91_EMAC_CLK_DIV32 (2 << 10)
+#define AT91_EMAC_CLK_DIV64 (3 << 10)
+#define AT91_EMAC_RTY (1 << 12) /* Retry Test */
+#define AT91_EMAC_RMII (1 << 13) /* Reduce MII (RMII) */
+
+#define AT91_EMAC_SR 0x08 /* Status Register */
+#define AT91_EMAC_SR_LINK (1 << 0) /* Link */
+#define AT91_EMAC_SR_MDIO (1 << 1) /* MDIO pin */
+#define AT91_EMAC_SR_IDLE (1 << 2) /* PHY idle */
+
+#define AT91_EMAC_TAR 0x0c /* Transmit Address Register */
+
+#define AT91_EMAC_TCR 0x10 /* Transmit Control Register */
+#define AT91_EMAC_LEN (0x7ff << 0) /* Transmit Frame Length */
+#define AT91_EMAC_NCRC (1 << 15) /* No CRC */
+
+#define AT91_EMAC_TSR 0x14 /* Transmit Status Register */
+#define AT91_EMAC_TSR_OVR (1 << 0) /* Transmit Buffer Overrun */
+#define AT91_EMAC_TSR_COL (1 << 1) /* Collision Occurred */
+#define AT91_EMAC_TSR_RLE (1 << 2) /* Retry Limit Exceeded */
+#define AT91_EMAC_TSR_IDLE (1 << 3) /* Transmitter Idle */
+#define AT91_EMAC_TSR_BNQ (1 << 4) /* Transmit Buffer not Queued */
+#define AT91_EMAC_TSR_COMP (1 << 5) /* Transmit Complete */
+#define AT91_EMAC_TSR_UND (1 << 6) /* Transmit Underrun */
+
+#define AT91_EMAC_RBQP 0x18 /* Receive Buffer Queue Pointer */
+
+#define AT91_EMAC_RSR 0x20 /* Receive Status Register */
+#define AT91_EMAC_RSR_BNA (1 << 0) /* Buffer Not Available */
+#define AT91_EMAC_RSR_REC (1 << 1) /* Frame Received */
+#define AT91_EMAC_RSR_OVR (1 << 2) /* RX Overrun */
+
+#define AT91_EMAC_ISR 0x24 /* Interrupt Status Register */
+#define AT91_EMAC_DONE (1 << 0) /* Management Done */
+#define AT91_EMAC_RCOM (1 << 1) /* Receive Complete */
+#define AT91_EMAC_RBNA (1 << 2) /* Receive Buffer Not Available */
+#define AT91_EMAC_TOVR (1 << 3) /* Transmit Buffer Overrun */
+#define AT91_EMAC_TUND (1 << 4) /* Transmit Buffer Underrun */
+#define AT91_EMAC_RTRY (1 << 5) /* Retry Limit */
+#define AT91_EMAC_TBRE (1 << 6) /* Transmit Buffer Register Empty */
+#define AT91_EMAC_TCOM (1 << 7) /* Transmit Complete */
+#define AT91_EMAC_TIDLE (1 << 8) /* Transmit Idle */
+#define AT91_EMAC_LINK (1 << 9) /* Link */
+#define AT91_EMAC_ROVR (1 << 10) /* RX Overrun */
+#define AT91_EMAC_ABT (1 << 11) /* Abort */
+
+#define AT91_EMAC_IER 0x28 /* Interrupt Enable Register */
+#define AT91_EMAC_IDR 0x2c /* Interrupt Disable Register */
+#define AT91_EMAC_IMR 0x30 /* Interrupt Mask Register */
+
+#define AT91_EMAC_MAN 0x34 /* PHY Maintenance Register */
+#define AT91_EMAC_DATA (0xffff << 0) /* MDIO Data */
+#define AT91_EMAC_REGA (0x1f << 18) /* MDIO Register */
+#define AT91_EMAC_PHYA (0x1f << 23) /* MDIO PHY Address */
+#define AT91_EMAC_RW (3 << 28) /* Read/Write operation */
+#define AT91_EMAC_RW_W (1 << 28)
+#define AT91_EMAC_RW_R (2 << 28)
+#define AT91_EMAC_MAN_802_3 0x40020000 /* IEEE 802.3 value */
+
+/*
+ * Statistics Registers.
+ */
+#define AT91_EMAC_FRA 0x40 /* Frames Transmitted OK */
+#define AT91_EMAC_SCOL 0x44 /* Single Collision Frame */
+#define AT91_EMAC_MCOL 0x48 /* Multiple Collision Frame */
+#define AT91_EMAC_OK 0x4c /* Frames Received OK */
+#define AT91_EMAC_SEQE 0x50 /* Frame Check Sequence Error */
+#define AT91_EMAC_ALE 0x54 /* Alignmemt Error */
+#define AT91_EMAC_DTE 0x58 /* Deffered Transmission Frame */
+#define AT91_EMAC_LCOL 0x5c /* Late Collision */
+#define AT91_EMAC_ECOL 0x60 /* Excessive Collision */
+#define AT91_EMAC_TUE 0x64 /* Transmit Underrun Error */
+#define AT91_EMAC_CSE 0x68 /* Carrier Sense Error */
+#define AT91_EMAC_DRFC 0x6c /* Discard RX Frame */
+#define AT91_EMAC_ROV 0x70 /* Receive Overrun */
+#define AT91_EMAC_CDE 0x74 /* Code Error */
+#define AT91_EMAC_ELR 0x78 /* Excessive Length Error */
+#define AT91_EMAC_RJB 0x7c /* Receive Jabber */
+#define AT91_EMAC_USF 0x80 /* Undersize Frame */
+#define AT91_EMAC_SQEE 0x84 /* SQE Test Error */
+
+/*
+ * Address Registers.
+ */
+#define AT91_EMAC_HSL 0x90 /* Hash Address Low [31:0] */
+#define AT91_EMAC_HSH 0x94 /* Hash Address High [63:32] */
+#define AT91_EMAC_SA1L 0x98 /* Specific Address 1 Low, bytes 0-3 */
+#define AT91_EMAC_SA1H 0x9c /* Specific Address 1 High, bytes 4-5 */
+#define AT91_EMAC_SA2L 0xa0 /* Specific Address 2 Low, bytes 0-3 */
+#define AT91_EMAC_SA2H 0xa4 /* Specific Address 2 High, bytes 4-5 */
+#define AT91_EMAC_SA3L 0xa8 /* Specific Address 3 Low, bytes 0-3 */
+#define AT91_EMAC_SA3H 0xac /* Specific Address 3 High, bytes 4-5 */
+#define AT91_EMAC_SA4L 0xb0 /* Specific Address 4 Low, bytes 0-3 */
+#define AT91_EMAC_SA4H 0xb4 /* Specific Address 4 High, bytes 4-5 */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200_mc.h b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h
new file mode 100644
index 00000000..d34e4ed8
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91rm9200_mc.h
@@ -0,0 +1,160 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91rm9200_mc.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Memory Controllers (MC, EBI, SMC, SDRAMC, BFC) - System peripherals registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * 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 AT91RM9200_MC_H
+#define AT91RM9200_MC_H
+
+/* Memory Controller */
+#define AT91_MC_RCR (AT91_MC + 0x00) /* MC Remap Control Register */
+#define AT91_MC_RCB (1 << 0) /* Remap Command Bit */
+
+#define AT91_MC_ASR (AT91_MC + 0x04) /* MC Abort Status Register */
+#define AT91_MC_UNADD (1 << 0) /* Undefined Address Abort Status */
+#define AT91_MC_MISADD (1 << 1) /* Misaligned Address Abort Status */
+#define AT91_MC_ABTSZ (3 << 8) /* Abort Size Status */
+#define AT91_MC_ABTSZ_BYTE (0 << 8)
+#define AT91_MC_ABTSZ_HALFWORD (1 << 8)
+#define AT91_MC_ABTSZ_WORD (2 << 8)
+#define AT91_MC_ABTTYP (3 << 10) /* Abort Type Status */
+#define AT91_MC_ABTTYP_DATAREAD (0 << 10)
+#define AT91_MC_ABTTYP_DATAWRITE (1 << 10)
+#define AT91_MC_ABTTYP_FETCH (2 << 10)
+#define AT91_MC_MST0 (1 << 16) /* ARM920T Abort Source */
+#define AT91_MC_MST1 (1 << 17) /* PDC Abort Source */
+#define AT91_MC_MST2 (1 << 18) /* UHP Abort Source */
+#define AT91_MC_MST3 (1 << 19) /* EMAC Abort Source */
+#define AT91_MC_SVMST0 (1 << 24) /* Saved ARM920T Abort Source */
+#define AT91_MC_SVMST1 (1 << 25) /* Saved PDC Abort Source */
+#define AT91_MC_SVMST2 (1 << 26) /* Saved UHP Abort Source */
+#define AT91_MC_SVMST3 (1 << 27) /* Saved EMAC Abort Source */
+
+#define AT91_MC_AASR (AT91_MC + 0x08) /* MC Abort Address Status Register */
+
+#define AT91_MC_MPR (AT91_MC + 0x0c) /* MC Master Priority Register */
+#define AT91_MPR_MSTP0 (7 << 0) /* ARM920T Priority */
+#define AT91_MPR_MSTP1 (7 << 4) /* PDC Priority */
+#define AT91_MPR_MSTP2 (7 << 8) /* UHP Priority */
+#define AT91_MPR_MSTP3 (7 << 12) /* EMAC Priority */
+
+/* External Bus Interface (EBI) registers */
+#define AT91_EBI_CSA (AT91_MC + 0x60) /* Chip Select Assignment Register */
+#define AT91_EBI_CS0A (1 << 0) /* Chip Select 0 Assignment */
+#define AT91_EBI_CS0A_SMC (0 << 0)
+#define AT91_EBI_CS0A_BFC (1 << 0)
+#define AT91_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_EBI_CS1A_SMC (0 << 1)
+#define AT91_EBI_CS1A_SDRAMC (1 << 1)
+#define AT91_EBI_CS3A (1 << 3) /* Chip Select 2 Assignment */
+#define AT91_EBI_CS3A_SMC (0 << 3)
+#define AT91_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_EBI_CS4A (1 << 4) /* Chip Select 3 Assignment */
+#define AT91_EBI_CS4A_SMC (0 << 4)
+#define AT91_EBI_CS4A_SMC_COMPACTFLASH (1 << 4)
+#define AT91_EBI_CFGR (AT91_MC + 0x64) /* Configuration Register */
+#define AT91_EBI_DBPUC (1 << 0) /* Data Bus Pull-Up Configuration */
+
+/* Static Memory Controller (SMC) registers */
+#define AT91_SMC_CSR(n) (AT91_MC + 0x70 + ((n) * 4))/* SMC Chip Select Register */
+#define AT91_SMC_NWS (0x7f << 0) /* Number of Wait States */
+#define AT91_SMC_NWS_(x) ((x) << 0)
+#define AT91_SMC_WSEN (1 << 7) /* Wait State Enable */
+#define AT91_SMC_TDF (0xf << 8) /* Data Float Time */
+#define AT91_SMC_TDF_(x) ((x) << 8)
+#define AT91_SMC_BAT (1 << 12) /* Byte Access Type */
+#define AT91_SMC_DBW (3 << 13) /* Data Bus Width */
+#define AT91_SMC_DBW_16 (1 << 13)
+#define AT91_SMC_DBW_8 (2 << 13)
+#define AT91_SMC_DPR (1 << 15) /* Data Read Protocol */
+#define AT91_SMC_ACSS (3 << 16) /* Address to Chip Select Setup */
+#define AT91_SMC_ACSS_STD (0 << 16)
+#define AT91_SMC_ACSS_1 (1 << 16)
+#define AT91_SMC_ACSS_2 (2 << 16)
+#define AT91_SMC_ACSS_3 (3 << 16)
+#define AT91_SMC_RWSETUP (7 << 24) /* Read & Write Signal Time Setup */
+#define AT91_SMC_RWSETUP_(x) ((x) << 24)
+#define AT91_SMC_RWHOLD (7 << 28) /* Read & Write Signal Hold Time */
+#define AT91_SMC_RWHOLD_(x) ((x) << 28)
+
+/* SDRAM Controller registers */
+#define AT91_SDRAMC_MR (AT91_MC + 0x90) /* Mode Register */
+#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */
+#define AT91_SDRAMC_MODE_NORMAL (0 << 0)
+#define AT91_SDRAMC_MODE_NOP (1 << 0)
+#define AT91_SDRAMC_MODE_PRECHARGE (2 << 0)
+#define AT91_SDRAMC_MODE_LMR (3 << 0)
+#define AT91_SDRAMC_MODE_REFRESH (4 << 0)
+#define AT91_SDRAMC_DBW (1 << 4) /* Data Bus Width */
+#define AT91_SDRAMC_DBW_32 (0 << 4)
+#define AT91_SDRAMC_DBW_16 (1 << 4)
+
+#define AT91_SDRAMC_TR (AT91_MC + 0x94) /* Refresh Timer Register */
+#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Count */
+
+#define AT91_SDRAMC_CR (AT91_MC + 0x98) /* Configuration Register */
+#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */
+#define AT91_SDRAMC_NC_8 (0 << 0)
+#define AT91_SDRAMC_NC_9 (1 << 0)
+#define AT91_SDRAMC_NC_10 (2 << 0)
+#define AT91_SDRAMC_NC_11 (3 << 0)
+#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */
+#define AT91_SDRAMC_NR_11 (0 << 2)
+#define AT91_SDRAMC_NR_12 (1 << 2)
+#define AT91_SDRAMC_NR_13 (2 << 2)
+#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */
+#define AT91_SDRAMC_NB_2 (0 << 4)
+#define AT91_SDRAMC_NB_4 (1 << 4)
+#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */
+#define AT91_SDRAMC_CAS_2 (2 << 5)
+#define AT91_SDRAMC_TWR (0xf << 7) /* Write Recovery Delay */
+#define AT91_SDRAMC_TRC (0xf << 11) /* Row Cycle Delay */
+#define AT91_SDRAMC_TRP (0xf << 15) /* Row Precharge Delay */
+#define AT91_SDRAMC_TRCD (0xf << 19) /* Row to Column Delay */
+#define AT91_SDRAMC_TRAS (0xf << 23) /* Active to Precharge Delay */
+#define AT91_SDRAMC_TXSR (0xf << 27) /* Exit Self Refresh to Active Delay */
+
+#define AT91_SDRAMC_SRR (AT91_MC + 0x9c) /* Self Refresh Register */
+#define AT91_SDRAMC_LPR (AT91_MC + 0xa0) /* Low Power Register */
+#define AT91_SDRAMC_IER (AT91_MC + 0xa4) /* Interrupt Enable Register */
+#define AT91_SDRAMC_IDR (AT91_MC + 0xa8) /* Interrupt Disable Register */
+#define AT91_SDRAMC_IMR (AT91_MC + 0xac) /* Interrupt Mask Register */
+#define AT91_SDRAMC_ISR (AT91_MC + 0xb0) /* Interrupt Status Register */
+
+/* Burst Flash Controller register */
+#define AT91_BFC_MR (AT91_MC + 0xc0) /* Mode Register */
+#define AT91_BFC_BFCOM (3 << 0) /* Burst Flash Controller Operating Mode */
+#define AT91_BFC_BFCOM_DISABLED (0 << 0)
+#define AT91_BFC_BFCOM_ASYNC (1 << 0)
+#define AT91_BFC_BFCOM_BURST (2 << 0)
+#define AT91_BFC_BFCC (3 << 2) /* Burst Flash Controller Clock */
+#define AT91_BFC_BFCC_MCK (1 << 2)
+#define AT91_BFC_BFCC_DIV2 (2 << 2)
+#define AT91_BFC_BFCC_DIV4 (3 << 2)
+#define AT91_BFC_AVL (0xf << 4) /* Address Valid Latency */
+#define AT91_BFC_PAGES (7 << 8) /* Page Size */
+#define AT91_BFC_PAGES_NO_PAGE (0 << 8)
+#define AT91_BFC_PAGES_16 (1 << 8)
+#define AT91_BFC_PAGES_32 (2 << 8)
+#define AT91_BFC_PAGES_64 (3 << 8)
+#define AT91_BFC_PAGES_128 (4 << 8)
+#define AT91_BFC_PAGES_256 (5 << 8)
+#define AT91_BFC_PAGES_512 (6 << 8)
+#define AT91_BFC_PAGES_1024 (7 << 8)
+#define AT91_BFC_OEL (3 << 12) /* Output Enable Latency */
+#define AT91_BFC_BAAEN (1 << 16) /* Burst Address Advance Enable */
+#define AT91_BFC_BFOEH (1 << 17) /* Burst Flash Output Enable Handling */
+#define AT91_BFC_MUXEN (1 << 18) /* Multiplexed Bus Enable */
+#define AT91_BFC_RDYEN (1 << 19) /* Ready Enable Mode */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h
new file mode 100644
index 00000000..8b6bf835
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -0,0 +1,136 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9260.h
+ *
+ * (C) 2006 Andrew Victor
+ *
+ * Common definitions.
+ * Based on AT91SAM9260 datasheet revision A (Preliminary).
+ *
+ * Includes also definitions for AT91SAM9XE and AT91SAM9G families
+ *
+ * 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 AT91SAM9260_H
+#define AT91SAM9260_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9260_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91SAM9260_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91SAM9260_ID_PIOC 4 /* Parallel IO Controller C */
+#define AT91SAM9260_ID_ADC 5 /* Analog-to-Digital Converter */
+#define AT91SAM9260_ID_US0 6 /* USART 0 */
+#define AT91SAM9260_ID_US1 7 /* USART 1 */
+#define AT91SAM9260_ID_US2 8 /* USART 2 */
+#define AT91SAM9260_ID_MCI 9 /* Multimedia Card Interface */
+#define AT91SAM9260_ID_UDP 10 /* USB Device Port */
+#define AT91SAM9260_ID_TWI 11 /* Two-Wire Interface */
+#define AT91SAM9260_ID_SPI0 12 /* Serial Peripheral Interface 0 */
+#define AT91SAM9260_ID_SPI1 13 /* Serial Peripheral Interface 1 */
+#define AT91SAM9260_ID_SSC 14 /* Serial Synchronous Controller */
+#define AT91SAM9260_ID_TC0 17 /* Timer Counter 0 */
+#define AT91SAM9260_ID_TC1 18 /* Timer Counter 1 */
+#define AT91SAM9260_ID_TC2 19 /* Timer Counter 2 */
+#define AT91SAM9260_ID_UHP 20 /* USB Host port */
+#define AT91SAM9260_ID_EMAC 21 /* Ethernet */
+#define AT91SAM9260_ID_ISI 22 /* Image Sensor Interface */
+#define AT91SAM9260_ID_US3 23 /* USART 3 */
+#define AT91SAM9260_ID_US4 24 /* USART 4 */
+#define AT91SAM9260_ID_US5 25 /* USART 5 */
+#define AT91SAM9260_ID_TC3 26 /* Timer Counter 3 */
+#define AT91SAM9260_ID_TC4 27 /* Timer Counter 4 */
+#define AT91SAM9260_ID_TC5 28 /* Timer Counter 5 */
+#define AT91SAM9260_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91SAM9260_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */
+#define AT91SAM9260_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9260_BASE_TCB0 0xfffa0000
+#define AT91SAM9260_BASE_TC0 0xfffa0000
+#define AT91SAM9260_BASE_TC1 0xfffa0040
+#define AT91SAM9260_BASE_TC2 0xfffa0080
+#define AT91SAM9260_BASE_UDP 0xfffa4000
+#define AT91SAM9260_BASE_MCI 0xfffa8000
+#define AT91SAM9260_BASE_TWI 0xfffac000
+#define AT91SAM9260_BASE_US0 0xfffb0000
+#define AT91SAM9260_BASE_US1 0xfffb4000
+#define AT91SAM9260_BASE_US2 0xfffb8000
+#define AT91SAM9260_BASE_SSC 0xfffbc000
+#define AT91SAM9260_BASE_ISI 0xfffc0000
+#define AT91SAM9260_BASE_EMAC 0xfffc4000
+#define AT91SAM9260_BASE_SPI0 0xfffc8000
+#define AT91SAM9260_BASE_SPI1 0xfffcc000
+#define AT91SAM9260_BASE_US3 0xfffd0000
+#define AT91SAM9260_BASE_US4 0xfffd4000
+#define AT91SAM9260_BASE_US5 0xfffd8000
+#define AT91SAM9260_BASE_TCB1 0xfffdc000
+#define AT91SAM9260_BASE_TC3 0xfffdc000
+#define AT91SAM9260_BASE_TC4 0xfffdc040
+#define AT91SAM9260_BASE_TC5 0xfffdc080
+#define AT91SAM9260_BASE_ADC 0xfffe0000
+#define AT91_BASE_SYS 0xffffe800
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
+#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
+
+#define AT91_USART0 AT91SAM9260_BASE_US0
+#define AT91_USART1 AT91SAM9260_BASE_US1
+#define AT91_USART2 AT91SAM9260_BASE_US2
+#define AT91_USART3 AT91SAM9260_BASE_US3
+#define AT91_USART4 AT91SAM9260_BASE_US4
+#define AT91_USART5 AT91SAM9260_BASE_US5
+
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9260_ROM_BASE 0x00100000 /* Internal ROM base address */
+#define AT91SAM9260_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
+
+#define AT91SAM9260_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */
+#define AT91SAM9260_SRAM0_SIZE SZ_4K /* Internal SRAM 0 size (4Kb) */
+#define AT91SAM9260_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */
+#define AT91SAM9260_SRAM1_SIZE SZ_4K /* Internal SRAM 1 size (4Kb) */
+
+#define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */
+
+#define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */
+#define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */
+
+#define AT91SAM9G20_ROM_BASE 0x00100000 /* Internal ROM base address */
+#define AT91SAM9G20_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
+
+#define AT91SAM9G20_SRAM0_BASE 0x00200000 /* Internal SRAM 0 base address */
+#define AT91SAM9G20_SRAM0_SIZE SZ_16K /* Internal SRAM 0 size (16Kb) */
+#define AT91SAM9G20_SRAM1_BASE 0x00300000 /* Internal SRAM 1 base address */
+#define AT91SAM9G20_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */
+
+#define AT91SAM9G20_UHP_BASE 0x00500000 /* USB Host controller */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
new file mode 100644
index 00000000..020f02ed
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9260_matrix.h
+ *
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9260 datasheet revision B.
+ *
+ * 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 AT91SAM9260_MATRIX_H
+#define AT91SAM9260_MATRIX_H
+
+#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
+#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */
+#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
+#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
+#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
+#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
+#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
+#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
+#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
+#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
+
+#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+
+#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x11C) /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
+#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
+#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
new file mode 100644
index 00000000..eafbddaf
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9261.h
+ *
+ * Copyright (C) SAN People
+ *
+ * Common definitions.
+ * Based on AT91SAM9261 datasheet revision E. (Preliminary)
+ *
+ * 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 AT91SAM9261_H
+#define AT91SAM9261_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9261_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91SAM9261_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91SAM9261_ID_PIOC 4 /* Parallel IO Controller C */
+#define AT91SAM9261_ID_US0 6 /* USART 0 */
+#define AT91SAM9261_ID_US1 7 /* USART 1 */
+#define AT91SAM9261_ID_US2 8 /* USART 2 */
+#define AT91SAM9261_ID_MCI 9 /* Multimedia Card Interface */
+#define AT91SAM9261_ID_UDP 10 /* USB Device Port */
+#define AT91SAM9261_ID_TWI 11 /* Two-Wire Interface */
+#define AT91SAM9261_ID_SPI0 12 /* Serial Peripheral Interface 0 */
+#define AT91SAM9261_ID_SPI1 13 /* Serial Peripheral Interface 1 */
+#define AT91SAM9261_ID_SSC0 14 /* Serial Synchronous Controller 0 */
+#define AT91SAM9261_ID_SSC1 15 /* Serial Synchronous Controller 1 */
+#define AT91SAM9261_ID_SSC2 16 /* Serial Synchronous Controller 2 */
+#define AT91SAM9261_ID_TC0 17 /* Timer Counter 0 */
+#define AT91SAM9261_ID_TC1 18 /* Timer Counter 1 */
+#define AT91SAM9261_ID_TC2 19 /* Timer Counter 2 */
+#define AT91SAM9261_ID_UHP 20 /* USB Host port */
+#define AT91SAM9261_ID_LCDC 21 /* LDC Controller */
+#define AT91SAM9261_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91SAM9261_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */
+#define AT91SAM9261_ID_IRQ2 31 /* Advanced Interrupt Controller (IRQ2) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9261_BASE_TCB0 0xfffa0000
+#define AT91SAM9261_BASE_TC0 0xfffa0000
+#define AT91SAM9261_BASE_TC1 0xfffa0040
+#define AT91SAM9261_BASE_TC2 0xfffa0080
+#define AT91SAM9261_BASE_UDP 0xfffa4000
+#define AT91SAM9261_BASE_MCI 0xfffa8000
+#define AT91SAM9261_BASE_TWI 0xfffac000
+#define AT91SAM9261_BASE_US0 0xfffb0000
+#define AT91SAM9261_BASE_US1 0xfffb4000
+#define AT91SAM9261_BASE_US2 0xfffb8000
+#define AT91SAM9261_BASE_SSC0 0xfffbc000
+#define AT91SAM9261_BASE_SSC1 0xfffc0000
+#define AT91SAM9261_BASE_SSC2 0xfffc4000
+#define AT91SAM9261_BASE_SPI0 0xfffc8000
+#define AT91SAM9261_BASE_SPI1 0xfffcc000
+#define AT91_BASE_SYS 0xffffea00
+
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS)
+
+#define AT91_USART0 AT91SAM9261_BASE_US0
+#define AT91_USART1 AT91SAM9261_BASE_US1
+#define AT91_USART2 AT91SAM9261_BASE_US2
+
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9261_SRAM_BASE 0x00300000 /* Internal SRAM base address */
+#define AT91SAM9261_SRAM_SIZE 0x00028000 /* Internal SRAM size (160Kb) */
+
+#define AT91SAM9G10_SRAM_BASE AT91SAM9261_SRAM_BASE /* Internal SRAM base address */
+#define AT91SAM9G10_SRAM_SIZE 0x00004000 /* Internal SRAM size (16Kb) */
+
+#define AT91SAM9261_ROM_BASE 0x00400000 /* Internal ROM base address */
+#define AT91SAM9261_ROM_SIZE SZ_32K /* Internal ROM size (32Kb) */
+
+#define AT91SAM9261_UHP_BASE 0x00500000 /* USB Host controller */
+#define AT91SAM9261_LCDC_BASE 0x00600000 /* LDC controller */
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
new file mode 100644
index 00000000..69c65019
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9261_matrix.h
+ *
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91SAM9261_MATRIX_H
+#define AT91SAM9261_MATRIX_H
+
+#define AT91_MATRIX_MCFG (AT91_MATRIX + 0x00) /* Master Configuration Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x04) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x08) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x0C) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x10) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x14) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */
+
+#define AT91_MATRIX_TCR (AT91_MATRIX + 0x24) /* TCM Configuration Register */
+#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
+#define AT91_MATRIX_ITCM_0 (0 << 0)
+#define AT91_MATRIX_ITCM_16 (5 << 0)
+#define AT91_MATRIX_ITCM_32 (6 << 0)
+#define AT91_MATRIX_ITCM_64 (7 << 0)
+#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
+#define AT91_MATRIX_DTCM_0 (0 << 4)
+#define AT91_MATRIX_DTCM_16 (5 << 4)
+#define AT91_MATRIX_DTCM_32 (6 << 4)
+#define AT91_MATRIX_DTCM_64 (7 << 4)
+
+#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x30) /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
+#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
+#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+
+#define AT91_MATRIX_USBPUCR (AT91_MATRIX + 0x34) /* USB Pad Pull-Up Control Register */
+#define AT91_MATRIX_USBPUCR_PUON (1 << 30) /* USB Device PAD Pull-up Enable */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h
new file mode 100644
index 00000000..e2d34821
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9263.h
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9263.h
+ *
+ * (C) 2007 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9263 datasheet revision B (Preliminary).
+ *
+ * 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 AT91SAM9263_H
+#define AT91SAM9263_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9263_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91SAM9263_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91SAM9263_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */
+#define AT91SAM9263_ID_US0 7 /* USART 0 */
+#define AT91SAM9263_ID_US1 8 /* USART 1 */
+#define AT91SAM9263_ID_US2 9 /* USART 2 */
+#define AT91SAM9263_ID_MCI0 10 /* Multimedia Card Interface 0 */
+#define AT91SAM9263_ID_MCI1 11 /* Multimedia Card Interface 1 */
+#define AT91SAM9263_ID_CAN 12 /* CAN */
+#define AT91SAM9263_ID_TWI 13 /* Two-Wire Interface */
+#define AT91SAM9263_ID_SPI0 14 /* Serial Peripheral Interface 0 */
+#define AT91SAM9263_ID_SPI1 15 /* Serial Peripheral Interface 1 */
+#define AT91SAM9263_ID_SSC0 16 /* Serial Synchronous Controller 0 */
+#define AT91SAM9263_ID_SSC1 17 /* Serial Synchronous Controller 1 */
+#define AT91SAM9263_ID_AC97C 18 /* AC97 Controller */
+#define AT91SAM9263_ID_TCB 19 /* Timer Counter 0, 1 and 2 */
+#define AT91SAM9263_ID_PWMC 20 /* Pulse Width Modulation Controller */
+#define AT91SAM9263_ID_EMAC 21 /* Ethernet */
+#define AT91SAM9263_ID_2DGE 23 /* 2D Graphic Engine */
+#define AT91SAM9263_ID_UDP 24 /* USB Device Port */
+#define AT91SAM9263_ID_ISI 25 /* Image Sensor Interface */
+#define AT91SAM9263_ID_LCDC 26 /* LCD Controller */
+#define AT91SAM9263_ID_DMA 27 /* DMA Controller */
+#define AT91SAM9263_ID_UHP 29 /* USB Host port */
+#define AT91SAM9263_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
+#define AT91SAM9263_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9263_BASE_UDP 0xfff78000
+#define AT91SAM9263_BASE_TCB0 0xfff7c000
+#define AT91SAM9263_BASE_TC0 0xfff7c000
+#define AT91SAM9263_BASE_TC1 0xfff7c040
+#define AT91SAM9263_BASE_TC2 0xfff7c080
+#define AT91SAM9263_BASE_MCI0 0xfff80000
+#define AT91SAM9263_BASE_MCI1 0xfff84000
+#define AT91SAM9263_BASE_TWI 0xfff88000
+#define AT91SAM9263_BASE_US0 0xfff8c000
+#define AT91SAM9263_BASE_US1 0xfff90000
+#define AT91SAM9263_BASE_US2 0xfff94000
+#define AT91SAM9263_BASE_SSC0 0xfff98000
+#define AT91SAM9263_BASE_SSC1 0xfff9c000
+#define AT91SAM9263_BASE_AC97C 0xfffa0000
+#define AT91SAM9263_BASE_SPI0 0xfffa4000
+#define AT91SAM9263_BASE_SPI1 0xfffa8000
+#define AT91SAM9263_BASE_CAN 0xfffac000
+#define AT91SAM9263_BASE_PWMC 0xfffb8000
+#define AT91SAM9263_BASE_EMAC 0xfffbc000
+#define AT91SAM9263_BASE_ISI 0xfffc4000
+#define AT91SAM9263_BASE_2DGE 0xfffc8000
+#define AT91_BASE_SYS 0xffffe000
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS)
+#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS)
+#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS)
+#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS)
+#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS)
+#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS)
+#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS)
+#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
+
+#define AT91_USART0 AT91SAM9263_BASE_US0
+#define AT91_USART1 AT91SAM9263_BASE_US1
+#define AT91_USART2 AT91SAM9263_BASE_US2
+
+#define AT91_SMC AT91_SMC0
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9263_SRAM0_BASE 0x00300000 /* Internal SRAM 0 base address */
+#define AT91SAM9263_SRAM0_SIZE (80 * SZ_1K) /* Internal SRAM 0 size (80Kb) */
+
+#define AT91SAM9263_ROM_BASE 0x00400000 /* Internal ROM base address */
+#define AT91SAM9263_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */
+
+#define AT91SAM9263_SRAM1_BASE 0x00500000 /* Internal SRAM 1 base address */
+#define AT91SAM9263_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */
+
+#define AT91SAM9263_LCDC_BASE 0x00700000 /* LCD Controller */
+#define AT91SAM9263_DMAC_BASE 0x00800000 /* DMA Controller */
+#define AT91SAM9263_UHP_BASE 0x00a00000 /* USB Host controller */
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h
new file mode 100644
index 00000000..9b3efd3e
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9263_matrix.h
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9263_matrix.h
+ *
+ * Copyright (C) 2006 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9263 datasheet revision B (Preliminary).
+ *
+ * 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 AT91SAM9263_MATRIX_H
+#define AT91SAM9263_MATRIX_H
+
+#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
+#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
+#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
+#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
+#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
+#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
+#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
+#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
+#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
+#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
+#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
+#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
+#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
+#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define AT91_MATRIX_RCB2 (1 << 2)
+#define AT91_MATRIX_RCB3 (1 << 3)
+#define AT91_MATRIX_RCB4 (1 << 4)
+#define AT91_MATRIX_RCB5 (1 << 5)
+#define AT91_MATRIX_RCB6 (1 << 6)
+#define AT91_MATRIX_RCB7 (1 << 7)
+#define AT91_MATRIX_RCB8 (1 << 8)
+
+#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */
+#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
+#define AT91_MATRIX_ITCM_0 (0 << 0)
+#define AT91_MATRIX_ITCM_16 (5 << 0)
+#define AT91_MATRIX_ITCM_32 (6 << 0)
+#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
+#define AT91_MATRIX_DTCM_0 (0 << 4)
+#define AT91_MATRIX_DTCM_16 (5 << 4)
+#define AT91_MATRIX_DTCM_32 (6 << 4)
+
+#define AT91_MATRIX_EBI0CSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */
+#define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_EBI0_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_EBI0_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_EBI0_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_EBI0_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_EBI0_CS4A_SMC_CF1 (1 << 4)
+#define AT91_MATRIX_EBI0_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_EBI0_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_EBI0_CS5A_SMC_CF2 (1 << 5)
+#define AT91_MATRIX_EBI0_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_EBI0_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16)
+
+#define AT91_MATRIX_EBI1CSA (AT91_MATRIX + 0x124) /* EBI1 Chip Select Assignment Register */
+#define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_EBI1_CS2A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_EBI1_CS2A_SMC (0 << 3)
+#define AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_EBI1_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_EBI1_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_EBI1_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_EBI1_VDDIOMSEL_3_3V (1 << 16)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
new file mode 100644
index 00000000..d27b15ba
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -0,0 +1,130 @@
+/*
+ * Header file for the Atmel DDR/SDR SDRAM Controller
+ *
+ * Copyright (C) 2010 Atmel Corporation
+ * Nicolas Ferre <nicolas.ferre@atmel.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 AT91SAM9_DDRSDR_H
+#define AT91SAM9_DDRSDR_H
+
+#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
+#define AT91_DDRSDRC_MODE (0x7 << 0) /* Command Mode */
+#define AT91_DDRSDRC_MODE_NORMAL 0
+#define AT91_DDRSDRC_MODE_NOP 1
+#define AT91_DDRSDRC_MODE_PRECHARGE 2
+#define AT91_DDRSDRC_MODE_LMR 3
+#define AT91_DDRSDRC_MODE_REFRESH 4
+#define AT91_DDRSDRC_MODE_EXT_LMR 5
+#define AT91_DDRSDRC_MODE_DEEP 6
+
+#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
+#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
+
+#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
+#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
+#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
+#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
+#define AT91_DDRSDRC_NC_SDR10 (2 << 0)
+#define AT91_DDRSDRC_NC_SDR11 (3 << 0)
+#define AT91_DDRSDRC_NC_DDR9 (0 << 0)
+#define AT91_DDRSDRC_NC_DDR10 (1 << 0)
+#define AT91_DDRSDRC_NC_DDR11 (2 << 0)
+#define AT91_DDRSDRC_NC_DDR12 (3 << 0)
+#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */
+#define AT91_DDRSDRC_NR_11 (0 << 2)
+#define AT91_DDRSDRC_NR_12 (1 << 2)
+#define AT91_DDRSDRC_NR_13 (2 << 2)
+#define AT91_DDRSDRC_NR_14 (3 << 2)
+#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */
+#define AT91_DDRSDRC_CAS_2 (2 << 4)
+#define AT91_DDRSDRC_CAS_3 (3 << 4)
+#define AT91_DDRSDRC_CAS_25 (6 << 4)
+#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */
+#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
+#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */
+#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */
+#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */
+#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */
+
+#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
+#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
+#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
+#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
+#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */
+#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
+#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
+#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */
+#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */
+#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
+
+#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
+#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
+#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
+#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
+#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
+
+#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */
+#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */
+#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */
+#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */
+#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */
+
+#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */
+#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
+#define AT91_DDRSDRC_LPCB_DISABLE 0
+#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
+#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
+#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
+#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
+#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
+#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
+#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
+#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
+#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12)
+#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
+#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
+#define AT91_DDRSDRC_APDE (1 << 16) /* Active power down exit time */
+#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
+
+#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
+#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
+#define AT91_DDRSDRC_MD_SDR 0
+#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
+#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
+#define AT91_DDRSDRC_MD_DDR2 6
+#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
+#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
+#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
+
+#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */
+#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
+#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
+#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
+#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
+
+#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */
+#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */
+
+#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */
+
+#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */
+#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */
+#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */
+#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */
+
+#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */
+#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */
+#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */
+
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
new file mode 100644
index 00000000..100f5a59
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * SDRAM Controllers (SDRAMC) - System peripherals registers.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91SAM9_SDRAMC_H
+#define AT91SAM9_SDRAMC_H
+
+/* SDRAM Controller (SDRAMC) registers */
+#define AT91_SDRAMC_MR 0x00 /* SDRAM Controller Mode Register */
+#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */
+#define AT91_SDRAMC_MODE_NORMAL 0
+#define AT91_SDRAMC_MODE_NOP 1
+#define AT91_SDRAMC_MODE_PRECHARGE 2
+#define AT91_SDRAMC_MODE_LMR 3
+#define AT91_SDRAMC_MODE_REFRESH 4
+#define AT91_SDRAMC_MODE_EXT_LMR 5
+#define AT91_SDRAMC_MODE_DEEP 6
+
+#define AT91_SDRAMC_TR 0x04 /* SDRAM Controller Refresh Timer Register */
+#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */
+
+#define AT91_SDRAMC_CR 0x08 /* SDRAM Controller Configuration Register */
+#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */
+#define AT91_SDRAMC_NC_8 (0 << 0)
+#define AT91_SDRAMC_NC_9 (1 << 0)
+#define AT91_SDRAMC_NC_10 (2 << 0)
+#define AT91_SDRAMC_NC_11 (3 << 0)
+#define AT91_SDRAMC_NR (3 << 2) /* Number of Row Bits */
+#define AT91_SDRAMC_NR_11 (0 << 2)
+#define AT91_SDRAMC_NR_12 (1 << 2)
+#define AT91_SDRAMC_NR_13 (2 << 2)
+#define AT91_SDRAMC_NB (1 << 4) /* Number of Banks */
+#define AT91_SDRAMC_NB_2 (0 << 4)
+#define AT91_SDRAMC_NB_4 (1 << 4)
+#define AT91_SDRAMC_CAS (3 << 5) /* CAS Latency */
+#define AT91_SDRAMC_CAS_1 (1 << 5)
+#define AT91_SDRAMC_CAS_2 (2 << 5)
+#define AT91_SDRAMC_CAS_3 (3 << 5)
+#define AT91_SDRAMC_DBW (1 << 7) /* Data Bus Width */
+#define AT91_SDRAMC_DBW_32 (0 << 7)
+#define AT91_SDRAMC_DBW_16 (1 << 7)
+#define AT91_SDRAMC_TWR (0xf << 8) /* Write Recovery Delay */
+#define AT91_SDRAMC_TRC (0xf << 12) /* Row Cycle Delay */
+#define AT91_SDRAMC_TRP (0xf << 16) /* Row Precharge Delay */
+#define AT91_SDRAMC_TRCD (0xf << 20) /* Row to Column Delay */
+#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */
+#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */
+
+#define AT91_SDRAMC_LPR 0x10 /* SDRAM Controller Low Power Register */
+#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */
+#define AT91_SDRAMC_LPCB_DISABLE 0
+#define AT91_SDRAMC_LPCB_SELF_REFRESH 1
+#define AT91_SDRAMC_LPCB_POWER_DOWN 2
+#define AT91_SDRAMC_LPCB_DEEP_POWER_DOWN 3
+#define AT91_SDRAMC_PASR (7 << 4) /* Partial Array Self Refresh */
+#define AT91_SDRAMC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
+#define AT91_SDRAMC_DS (3 << 10) /* Drive Strength */
+#define AT91_SDRAMC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
+#define AT91_SDRAMC_TIMEOUT_0_CLK_CYCLES (0 << 12)
+#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12)
+#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12)
+
+#define AT91_SDRAMC_IER 0x14 /* SDRAM Controller Interrupt Enable Register */
+#define AT91_SDRAMC_IDR 0x18 /* SDRAM Controller Interrupt Disable Register */
+#define AT91_SDRAMC_IMR 0x1C /* SDRAM Controller Interrupt Mask Register */
+#define AT91_SDRAMC_ISR 0x20 /* SDRAM Controller Interrupt Status Register */
+#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */
+
+#define AT91_SDRAMC_MDR 0x24 /* SDRAM Memory Device Register */
+#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */
+#define AT91_SDRAMC_MD_SDRAM 0
+#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1
+
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_SDRAMC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_SDRAMC##num + reg, value)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_smc.h b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
new file mode 100644
index 00000000..57de6207
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_smc.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9_smc.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ * Copyright (C) 2007 Atmel Corporation.
+ *
+ * Static Memory Controllers (SMC) - System peripherals registers.
+ * Based on AT91SAM9261 datasheet revision D.
+ *
+ * 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 AT91SAM9_SMC_H
+#define AT91SAM9_SMC_H
+
+#define AT91_SMC_SETUP(n) (AT91_SMC + 0x00 + ((n)*0x10)) /* Setup Register for CS n */
+#define AT91_SMC_NWESETUP (0x3f << 0) /* NWE Setup Length */
+#define AT91_SMC_NWESETUP_(x) ((x) << 0)
+#define AT91_SMC_NCS_WRSETUP (0x3f << 8) /* NCS Setup Length in Write Access */
+#define AT91_SMC_NCS_WRSETUP_(x) ((x) << 8)
+#define AT91_SMC_NRDSETUP (0x3f << 16) /* NRD Setup Length */
+#define AT91_SMC_NRDSETUP_(x) ((x) << 16)
+#define AT91_SMC_NCS_RDSETUP (0x3f << 24) /* NCS Setup Length in Read Access */
+#define AT91_SMC_NCS_RDSETUP_(x) ((x) << 24)
+
+#define AT91_SMC_PULSE(n) (AT91_SMC + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */
+#define AT91_SMC_NWEPULSE (0x7f << 0) /* NWE Pulse Length */
+#define AT91_SMC_NWEPULSE_(x) ((x) << 0)
+#define AT91_SMC_NCS_WRPULSE (0x7f << 8) /* NCS Pulse Length in Write Access */
+#define AT91_SMC_NCS_WRPULSE_(x)((x) << 8)
+#define AT91_SMC_NRDPULSE (0x7f << 16) /* NRD Pulse Length */
+#define AT91_SMC_NRDPULSE_(x) ((x) << 16)
+#define AT91_SMC_NCS_RDPULSE (0x7f << 24) /* NCS Pulse Length in Read Access */
+#define AT91_SMC_NCS_RDPULSE_(x)((x) << 24)
+
+#define AT91_SMC_CYCLE(n) (AT91_SMC + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */
+#define AT91_SMC_NWECYCLE (0x1ff << 0 ) /* Total Write Cycle Length */
+#define AT91_SMC_NWECYCLE_(x) ((x) << 0)
+#define AT91_SMC_NRDCYCLE (0x1ff << 16) /* Total Read Cycle Length */
+#define AT91_SMC_NRDCYCLE_(x) ((x) << 16)
+
+#define AT91_SMC_MODE(n) (AT91_SMC + 0x0c + ((n)*0x10)) /* Mode Register for CS n */
+#define AT91_SMC_READMODE (1 << 0) /* Read Mode */
+#define AT91_SMC_WRITEMODE (1 << 1) /* Write Mode */
+#define AT91_SMC_EXNWMODE (3 << 4) /* NWAIT Mode */
+#define AT91_SMC_EXNWMODE_DISABLE (0 << 4)
+#define AT91_SMC_EXNWMODE_FROZEN (2 << 4)
+#define AT91_SMC_EXNWMODE_READY (3 << 4)
+#define AT91_SMC_BAT (1 << 8) /* Byte Access Type */
+#define AT91_SMC_BAT_SELECT (0 << 8)
+#define AT91_SMC_BAT_WRITE (1 << 8)
+#define AT91_SMC_DBW (3 << 12) /* Data Bus Width */
+#define AT91_SMC_DBW_8 (0 << 12)
+#define AT91_SMC_DBW_16 (1 << 12)
+#define AT91_SMC_DBW_32 (2 << 12)
+#define AT91_SMC_TDF (0xf << 16) /* Data Float Time. */
+#define AT91_SMC_TDF_(x) ((x) << 16)
+#define AT91_SMC_TDFMODE (1 << 20) /* TDF Optimization - Enabled */
+#define AT91_SMC_PMEN (1 << 24) /* Page Mode Enabled */
+#define AT91_SMC_PS (3 << 28) /* Page Size */
+#define AT91_SMC_PS_4 (0 << 28)
+#define AT91_SMC_PS_8 (1 << 28)
+#define AT91_SMC_PS_16 (2 << 28)
+#define AT91_SMC_PS_32 (3 << 28)
+
+#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */
+#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */
+#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */
+#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */
+#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */
+#endif
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
new file mode 100644
index 00000000..659304aa
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -0,0 +1,151 @@
+/*
+ * Chip-specific header file for the AT91SAM9G45 family
+ *
+ * Copyright (C) 2008-2009 Atmel Corporation.
+ *
+ * Common definitions.
+ * Based on AT91SAM9G45 preliminary datasheet.
+ *
+ * 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 AT91SAM9G45_H
+#define AT91SAM9G45_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9G45_ID_PIOA 2 /* Parallel I/O Controller A */
+#define AT91SAM9G45_ID_PIOB 3 /* Parallel I/O Controller B */
+#define AT91SAM9G45_ID_PIOC 4 /* Parallel I/O Controller C */
+#define AT91SAM9G45_ID_PIODE 5 /* Parallel I/O Controller D and E */
+#define AT91SAM9G45_ID_TRNG 6 /* True Random Number Generator */
+#define AT91SAM9G45_ID_US0 7 /* USART 0 */
+#define AT91SAM9G45_ID_US1 8 /* USART 1 */
+#define AT91SAM9G45_ID_US2 9 /* USART 2 */
+#define AT91SAM9G45_ID_US3 10 /* USART 3 */
+#define AT91SAM9G45_ID_MCI0 11 /* High Speed Multimedia Card Interface 0 */
+#define AT91SAM9G45_ID_TWI0 12 /* Two-Wire Interface 0 */
+#define AT91SAM9G45_ID_TWI1 13 /* Two-Wire Interface 1 */
+#define AT91SAM9G45_ID_SPI0 14 /* Serial Peripheral Interface 0 */
+#define AT91SAM9G45_ID_SPI1 15 /* Serial Peripheral Interface 1 */
+#define AT91SAM9G45_ID_SSC0 16 /* Synchronous Serial Controller 0 */
+#define AT91SAM9G45_ID_SSC1 17 /* Synchronous Serial Controller 1 */
+#define AT91SAM9G45_ID_TCB 18 /* Timer Counter 0, 1, 2, 3, 4 and 5 */
+#define AT91SAM9G45_ID_PWMC 19 /* Pulse Width Modulation Controller */
+#define AT91SAM9G45_ID_TSC 20 /* Touch Screen ADC Controller */
+#define AT91SAM9G45_ID_DMA 21 /* DMA Controller */
+#define AT91SAM9G45_ID_UHPHS 22 /* USB Host High Speed */
+#define AT91SAM9G45_ID_LCDC 23 /* LCD Controller */
+#define AT91SAM9G45_ID_AC97C 24 /* AC97 Controller */
+#define AT91SAM9G45_ID_EMAC 25 /* Ethernet MAC */
+#define AT91SAM9G45_ID_ISI 26 /* Image Sensor Interface */
+#define AT91SAM9G45_ID_UDPHS 27 /* USB Device High Speed */
+#define AT91SAM9G45_ID_AESTDESSHA 28 /* AES + T-DES + SHA */
+#define AT91SAM9G45_ID_MCI1 29 /* High Speed Multimedia Card Interface 1 */
+#define AT91SAM9G45_ID_VDEC 30 /* Video Decoder */
+#define AT91SAM9G45_ID_IRQ0 31 /* Advanced Interrupt Controller */
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9G45_BASE_UDPHS 0xfff78000
+#define AT91SAM9G45_BASE_TCB0 0xfff7c000
+#define AT91SAM9G45_BASE_TC0 0xfff7c000
+#define AT91SAM9G45_BASE_TC1 0xfff7c040
+#define AT91SAM9G45_BASE_TC2 0xfff7c080
+#define AT91SAM9G45_BASE_MCI0 0xfff80000
+#define AT91SAM9G45_BASE_TWI0 0xfff84000
+#define AT91SAM9G45_BASE_TWI1 0xfff88000
+#define AT91SAM9G45_BASE_US0 0xfff8c000
+#define AT91SAM9G45_BASE_US1 0xfff90000
+#define AT91SAM9G45_BASE_US2 0xfff94000
+#define AT91SAM9G45_BASE_US3 0xfff98000
+#define AT91SAM9G45_BASE_SSC0 0xfff9c000
+#define AT91SAM9G45_BASE_SSC1 0xfffa0000
+#define AT91SAM9G45_BASE_SPI0 0xfffa4000
+#define AT91SAM9G45_BASE_SPI1 0xfffa8000
+#define AT91SAM9G45_BASE_AC97C 0xfffac000
+#define AT91SAM9G45_BASE_TSC 0xfffb0000
+#define AT91SAM9G45_BASE_ISI 0xfffb4000
+#define AT91SAM9G45_BASE_PWMC 0xfffb8000
+#define AT91SAM9G45_BASE_EMAC 0xfffbc000
+#define AT91SAM9G45_BASE_AES 0xfffc0000
+#define AT91SAM9G45_BASE_TDES 0xfffc4000
+#define AT91SAM9G45_BASE_SHA 0xfffc8000
+#define AT91SAM9G45_BASE_TRNG 0xfffcc000
+#define AT91SAM9G45_BASE_MCI1 0xfffd0000
+#define AT91SAM9G45_BASE_TCB1 0xfffd4000
+#define AT91SAM9G45_BASE_TC3 0xfffd4000
+#define AT91SAM9G45_BASE_TC4 0xfffd4040
+#define AT91SAM9G45_BASE_TC5 0xfffd4080
+#define AT91_BASE_SYS 0xffffe200
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
+#define AT91_DDRSDRC1 (0xffffe400 - AT91_BASE_SYS)
+#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
+#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
+#define AT91_DMA (0xffffec00 - AT91_BASE_SYS)
+#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
+#define AT91_RTC (0xfffffdb0 - AT91_BASE_SYS)
+
+#define AT91_USART0 AT91SAM9G45_BASE_US0
+#define AT91_USART1 AT91SAM9G45_BASE_US1
+#define AT91_USART2 AT91SAM9G45_BASE_US2
+#define AT91_USART3 AT91SAM9G45_BASE_US3
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9G45_SRAM_BASE 0x00300000 /* Internal SRAM base address */
+#define AT91SAM9G45_SRAM_SIZE SZ_64K /* Internal SRAM size (64Kb) */
+
+#define AT91SAM9G45_ROM_BASE 0x00400000 /* Internal ROM base address */
+#define AT91SAM9G45_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */
+
+#define AT91SAM9G45_LCDC_BASE 0x00500000 /* LCD Controller */
+#define AT91SAM9G45_UDPHS_FIFO 0x00600000 /* USB Device HS controller */
+#define AT91SAM9G45_OHCI_BASE 0x00700000 /* USB Host controller (OHCI) */
+#define AT91SAM9G45_EHCI_BASE 0x00800000 /* USB Host controller (EHCI) */
+#define AT91SAM9G45_VDEC_BASE 0x00900000 /* Video Decoder Controller */
+
+#define CONSISTENT_DMA_SIZE SZ_4M
+
+/*
+ * DMA peripheral identifiers
+ * for hardware handshaking interface
+ */
+#define AT_DMA_ID_MCI0 0
+#define AT_DMA_ID_SPI0_TX 1
+#define AT_DMA_ID_SPI0_RX 2
+#define AT_DMA_ID_SPI1_TX 3
+#define AT_DMA_ID_SPI1_RX 4
+#define AT_DMA_ID_SSC0_TX 5
+#define AT_DMA_ID_SSC0_RX 6
+#define AT_DMA_ID_SSC1_TX 7
+#define AT_DMA_ID_SSC1_RX 8
+#define AT_DMA_ID_AC97_TX 9
+#define AT_DMA_ID_AC97_RX 10
+#define AT_DMA_ID_MCI1 13
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
new file mode 100644
index 00000000..c972d60e
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45_matrix.h
@@ -0,0 +1,153 @@
+/*
+ * Matrix-centric header file for the AT91SAM9G45 family
+ *
+ * Copyright (C) 2008-2009 Atmel Corporation.
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9G45 preliminary datasheet.
+ *
+ * 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 AT91SAM9G45_MATRIX_H
+#define AT91SAM9G45_MATRIX_H
+
+#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
+#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
+#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
+#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
+#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */
+#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */
+#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */
+#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+#define AT91_MATRIX_ULBT_THIRTYTWO (5 << 0)
+#define AT91_MATRIX_ULBT_SIXTYFOUR (6 << 0)
+#define AT91_MATRIX_ULBT_128 (7 << 0)
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
+#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
+#define AT91_MATRIX_SLOT_CYCLE (0x1ff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
+
+#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
+#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
+#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
+#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
+#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
+#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
+#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
+#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
+#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
+#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
+#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
+#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
+#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
+#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
+#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
+#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
+#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
+#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
+#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
+#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
+#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
+#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
+
+#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define AT91_MATRIX_RCB2 (1 << 2)
+#define AT91_MATRIX_RCB3 (1 << 3)
+#define AT91_MATRIX_RCB4 (1 << 4)
+#define AT91_MATRIX_RCB5 (1 << 5)
+#define AT91_MATRIX_RCB6 (1 << 6)
+#define AT91_MATRIX_RCB7 (1 << 7)
+#define AT91_MATRIX_RCB8 (1 << 8)
+#define AT91_MATRIX_RCB9 (1 << 9)
+#define AT91_MATRIX_RCB10 (1 << 10)
+#define AT91_MATRIX_RCB11 (1 << 11)
+
+#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x110) /* TCM Configuration Register */
+#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
+#define AT91_MATRIX_ITCM_0 (0 << 0)
+#define AT91_MATRIX_ITCM_32 (6 << 0)
+#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
+#define AT91_MATRIX_DTCM_0 (0 << 4)
+#define AT91_MATRIX_DTCM_32 (6 << 4)
+#define AT91_MATRIX_DTCM_64 (7 << 4)
+#define AT91_MATRIX_TCM_NWS (0x1 << 11) /* Wait state TCM register */
+#define AT91_MATRIX_TCM_NO_WS (0x0 << 11)
+#define AT91_MATRIX_TCM_ONE_WS (0x1 << 11)
+
+#define AT91_MATRIX_VIDEO (AT91_MATRIX + 0x118) /* Video Mode Configuration Register */
+#define AT91C_VDEC_SEL (0x1 << 0) /* Video Mode Selection */
+#define AT91C_VDEC_SEL_OFF (0 << 0)
+#define AT91C_VDEC_SEL_ON (1 << 0)
+
+#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x128) /* EBI Chip Select Assignment Register */
+#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_EBI_CS4A_SMC_CF0 (1 << 4)
+#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_EBI_CS5A_SMC_CF1 (1 << 5)
+#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_EBI_DBPU_ON (0 << 8)
+#define AT91_MATRIX_EBI_DBPU_OFF (1 << 8)
+#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
+#define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */
+#define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17)
+#define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17)
+#define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */
+#define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18)
+#define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18)
+
+#define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */
+#define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */
+#define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0)
+#define AT91_MATRIX_WPMR_WP_WPEN (1 << 0)
+#define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */
+
+#define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */
+#define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */
+#define AT91_MATRIX_WPSR_NO_WPV (0 << 0)
+#define AT91_MATRIX_WPSR_WPV (1 << 0)
+#define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h
new file mode 100644
index 00000000..41dbbe61
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9260.h
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * Common definitions.
+ * Based on AT91SAM9RL datasheet revision A. (Preliminary)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#ifndef AT91SAM9RL_H
+#define AT91SAM9RL_H
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91SAM9RL_ID_PIOA 2 /* Parallel IO Controller A */
+#define AT91SAM9RL_ID_PIOB 3 /* Parallel IO Controller B */
+#define AT91SAM9RL_ID_PIOC 4 /* Parallel IO Controller C */
+#define AT91SAM9RL_ID_PIOD 5 /* Parallel IO Controller D */
+#define AT91SAM9RL_ID_US0 6 /* USART 0 */
+#define AT91SAM9RL_ID_US1 7 /* USART 1 */
+#define AT91SAM9RL_ID_US2 8 /* USART 2 */
+#define AT91SAM9RL_ID_US3 9 /* USART 3 */
+#define AT91SAM9RL_ID_MCI 10 /* Multimedia Card Interface */
+#define AT91SAM9RL_ID_TWI0 11 /* TWI 0 */
+#define AT91SAM9RL_ID_TWI1 12 /* TWI 1 */
+#define AT91SAM9RL_ID_SPI 13 /* Serial Peripheral Interface */
+#define AT91SAM9RL_ID_SSC0 14 /* Serial Synchronous Controller 0 */
+#define AT91SAM9RL_ID_SSC1 15 /* Serial Synchronous Controller 1 */
+#define AT91SAM9RL_ID_TC0 16 /* Timer Counter 0 */
+#define AT91SAM9RL_ID_TC1 17 /* Timer Counter 1 */
+#define AT91SAM9RL_ID_TC2 18 /* Timer Counter 2 */
+#define AT91SAM9RL_ID_PWMC 19 /* Pulse Width Modulation Controller */
+#define AT91SAM9RL_ID_TSC 20 /* Touch Screen Controller */
+#define AT91SAM9RL_ID_DMA 21 /* DMA Controller */
+#define AT91SAM9RL_ID_UDPHS 22 /* USB Device HS */
+#define AT91SAM9RL_ID_LCDC 23 /* LCD Controller */
+#define AT91SAM9RL_ID_AC97C 24 /* AC97 Controller */
+#define AT91SAM9RL_ID_IRQ0 31 /* Advanced Interrupt Controller (IRQ0) */
+
+
+/*
+ * User Peripheral physical base addresses.
+ */
+#define AT91SAM9RL_BASE_TCB0 0xfffa0000
+#define AT91SAM9RL_BASE_TC0 0xfffa0000
+#define AT91SAM9RL_BASE_TC1 0xfffa0040
+#define AT91SAM9RL_BASE_TC2 0xfffa0080
+#define AT91SAM9RL_BASE_MCI 0xfffa4000
+#define AT91SAM9RL_BASE_TWI0 0xfffa8000
+#define AT91SAM9RL_BASE_TWI1 0xfffac000
+#define AT91SAM9RL_BASE_US0 0xfffb0000
+#define AT91SAM9RL_BASE_US1 0xfffb4000
+#define AT91SAM9RL_BASE_US2 0xfffb8000
+#define AT91SAM9RL_BASE_US3 0xfffbc000
+#define AT91SAM9RL_BASE_SSC0 0xfffc0000
+#define AT91SAM9RL_BASE_SSC1 0xfffc4000
+#define AT91SAM9RL_BASE_PWMC 0xfffc8000
+#define AT91SAM9RL_BASE_SPI 0xfffcc000
+#define AT91SAM9RL_BASE_TSC 0xfffd0000
+#define AT91SAM9RL_BASE_UDPHS 0xfffd4000
+#define AT91SAM9RL_BASE_AC97C 0xfffd8000
+#define AT91_BASE_SYS 0xffffc000
+
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_DMA (0xffffe600 - AT91_BASE_SYS)
+#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
+#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
+#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
+#define AT91_DBGU (0xfffff200 - AT91_BASE_SYS)
+#define AT91_PIOA (0xfffff400 - AT91_BASE_SYS)
+#define AT91_PIOB (0xfffff600 - AT91_BASE_SYS)
+#define AT91_PIOC (0xfffff800 - AT91_BASE_SYS)
+#define AT91_PIOD (0xfffffa00 - AT91_BASE_SYS)
+#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
+#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
+#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
+#define AT91_RTT (0xfffffd20 - AT91_BASE_SYS)
+#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
+#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
+#define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS)
+#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
+#define AT91_RTC (0xfffffe00 - AT91_BASE_SYS)
+
+#define AT91_USART0 AT91SAM9RL_BASE_US0
+#define AT91_USART1 AT91SAM9RL_BASE_US1
+#define AT91_USART2 AT91SAM9RL_BASE_US2
+#define AT91_USART3 AT91SAM9RL_BASE_US3
+
+
+/*
+ * Internal Memory.
+ */
+#define AT91SAM9RL_SRAM_BASE 0x00300000 /* Internal SRAM base address */
+#define AT91SAM9RL_SRAM_SIZE SZ_16K /* Internal SRAM size (16Kb) */
+
+#define AT91SAM9RL_ROM_BASE 0x00400000 /* Internal ROM base address */
+#define AT91SAM9RL_ROM_SIZE (2 * SZ_16K) /* Internal ROM size (32Kb) */
+
+#define AT91SAM9RL_LCDC_BASE 0x00500000 /* LCD Controller */
+#define AT91SAM9RL_UDPHS_FIFO 0x00600000 /* USB Device HS controller */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h
new file mode 100644
index 00000000..5f914907
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91sam9rl_matrix.h
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * Memory Controllers (MATRIX, EBI) - System peripherals registers.
+ * Based on AT91SAM9RL datasheet revision A. (Preliminary)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#ifndef AT91SAM9RL_MATRIX_H
+#define AT91SAM9RL_MATRIX_H
+
+#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
+#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
+#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
+#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
+#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
+#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
+#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
+#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
+#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
+#define AT91_MATRIX_ULBT_FOUR (2 << 0)
+#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
+#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
+
+#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
+#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
+#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
+#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
+#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
+#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
+#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
+#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
+#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
+#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
+#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
+#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
+#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
+#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
+
+#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
+#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
+#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
+#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
+#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
+#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
+#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
+#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
+#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
+#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
+#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
+#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
+
+#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
+#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
+#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
+#define AT91_MATRIX_RCB2 (1 << 2)
+#define AT91_MATRIX_RCB3 (1 << 3)
+#define AT91_MATRIX_RCB4 (1 << 4)
+#define AT91_MATRIX_RCB5 (1 << 5)
+
+#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */
+#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
+#define AT91_MATRIX_ITCM_0 (0 << 0)
+#define AT91_MATRIX_ITCM_16 (5 << 0)
+#define AT91_MATRIX_ITCM_32 (6 << 0)
+#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
+#define AT91_MATRIX_DTCM_0 (0 << 4)
+#define AT91_MATRIX_DTCM_16 (5 << 4)
+#define AT91_MATRIX_DTCM_32 (6 << 4)
+
+#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */
+#define AT91_MATRIX_CS1A (1 << 1) /* Chip Select 1 Assignment */
+#define AT91_MATRIX_CS1A_SMC (0 << 1)
+#define AT91_MATRIX_CS1A_SDRAMC (1 << 1)
+#define AT91_MATRIX_CS3A (1 << 3) /* Chip Select 3 Assignment */
+#define AT91_MATRIX_CS3A_SMC (0 << 3)
+#define AT91_MATRIX_CS3A_SMC_SMARTMEDIA (1 << 3)
+#define AT91_MATRIX_CS4A (1 << 4) /* Chip Select 4 Assignment */
+#define AT91_MATRIX_CS4A_SMC (0 << 4)
+#define AT91_MATRIX_CS4A_SMC_CF1 (1 << 4)
+#define AT91_MATRIX_CS5A (1 << 5) /* Chip Select 5 Assignment */
+#define AT91_MATRIX_CS5A_SMC (0 << 5)
+#define AT91_MATRIX_CS5A_SMC_CF2 (1 << 5)
+#define AT91_MATRIX_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
+#define AT91_MATRIX_VDDIOMSEL (1 << 16) /* Memory voltage selection */
+#define AT91_MATRIX_VDDIOMSEL_1_8V (0 << 16)
+#define AT91_MATRIX_VDDIOMSEL_3_3V (1 << 16)
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91x40.h b/arch/arm/mach-at91/include/mach/at91x40.h
new file mode 100644
index 00000000..a152ff87
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91x40.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-at91/include/mach/at91x40.h
+ *
+ * (C) Copyright 2007, Greg Ungerer <gerg@snapgear.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 AT91X40_H
+#define AT91X40_H
+
+/*
+ * IRQ list.
+ */
+#define AT91X40_ID_USART0 2 /* USART port 0 */
+#define AT91X40_ID_USART1 3 /* USART port 1 */
+#define AT91X40_ID_TC0 4 /* Timer/Counter 0 */
+#define AT91X40_ID_TC1 5 /* Timer/Counter 1*/
+#define AT91X40_ID_TC2 6 /* Timer/Counter 2*/
+#define AT91X40_ID_WD 7 /* Watchdog? */
+#define AT91X40_ID_PIOA 8 /* Parallel IO Controller A */
+
+#define AT91X40_ID_IRQ0 16 /* External IRQ 0 */
+#define AT91X40_ID_IRQ1 17 /* External IRQ 1 */
+#define AT91X40_ID_IRQ2 18 /* External IRQ 2 */
+
+/*
+ * System Peripherals (offset from AT91_BASE_SYS)
+ */
+#define AT91_BASE_SYS 0xffc00000
+
+#define AT91_EBI (0xffe00000 - AT91_BASE_SYS) /* External Bus Interface */
+#define AT91_SF (0xfff00000 - AT91_BASE_SYS) /* Special Function */
+#define AT91_USART1 (0xfffcc000 - AT91_BASE_SYS) /* USART 1 */
+#define AT91_USART0 (0xfffd0000 - AT91_BASE_SYS) /* USART 0 */
+#define AT91_TC (0xfffe0000 - AT91_BASE_SYS) /* Timer Counter */
+#define AT91_PIOA (0xffff0000 - AT91_BASE_SYS) /* PIO Controller A */
+#define AT91_PS (0xffff4000 - AT91_BASE_SYS) /* Power Save */
+#define AT91_WD (0xffff8000 - AT91_BASE_SYS) /* Watchdog Timer */
+#define AT91_AIC (0xfffff000 - AT91_BASE_SYS) /* Advanced Interrupt Controller */
+
+/*
+ * The AT91x40 series doesn't have a debug unit like the other AT91 parts.
+ * But it does have a chip identify register and extension ID, so define at
+ * least these here.
+ */
+#define AT91_DBGU_CIDR (AT91_SF + 0) /* CIDR in PS segment */
+#define AT91_DBGU_EXID (AT91_SF + 4) /* EXID in PS segment */
+
+/*
+ * Support defines for the simple Power Controller module.
+ */
+#define AT91_PS_CR (AT91_PS + 0) /* PS Control register */
+#define AT91_PS_CR_CPU (1 << 0) /* CPU clock disable bit */
+
+#endif /* AT91X40_H */
diff --git a/arch/arm/mach-at91/include/mach/at_hdmac.h b/arch/arm/mach-at91/include/mach/at_hdmac.h
new file mode 100644
index 00000000..187cb583
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at_hdmac.h
@@ -0,0 +1,102 @@
+/*
+ * Header file for the Atmel AHB DMA Controller driver
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef AT_HDMAC_H
+#define AT_HDMAC_H
+
+#include <linux/dmaengine.h>
+
+/**
+ * struct at_dma_platform_data - Controller configuration parameters
+ * @nr_channels: Number of channels supported by hardware (max 8)
+ * @cap_mask: dma_capability flags supported by the platform
+ */
+struct at_dma_platform_data {
+ unsigned int nr_channels;
+ dma_cap_mask_t cap_mask;
+};
+
+/**
+ * enum at_dma_slave_width - DMA slave register access width.
+ * @AT_DMA_SLAVE_WIDTH_8BIT: Do 8-bit slave register accesses
+ * @AT_DMA_SLAVE_WIDTH_16BIT: Do 16-bit slave register accesses
+ * @AT_DMA_SLAVE_WIDTH_32BIT: Do 32-bit slave register accesses
+ */
+enum at_dma_slave_width {
+ AT_DMA_SLAVE_WIDTH_8BIT = 0,
+ AT_DMA_SLAVE_WIDTH_16BIT,
+ AT_DMA_SLAVE_WIDTH_32BIT,
+};
+
+/**
+ * struct at_dma_slave - Controller-specific information about a slave
+ * @dma_dev: required DMA master device
+ * @tx_reg: physical address of data register used for
+ * memory-to-peripheral transfers
+ * @rx_reg: physical address of data register used for
+ * peripheral-to-memory transfers
+ * @reg_width: peripheral register width
+ * @cfg: Platform-specific initializer for the CFG register
+ * @ctrla: Platform-specific initializer for the CTRLA register
+ */
+struct at_dma_slave {
+ struct device *dma_dev;
+ dma_addr_t tx_reg;
+ dma_addr_t rx_reg;
+ enum at_dma_slave_width reg_width;
+ u32 cfg;
+ u32 ctrla;
+};
+
+
+/* Platform-configurable bits in CFG */
+#define ATC_SRC_PER(h) (0xFU & (h)) /* Channel src rq associated with periph handshaking ifc h */
+#define ATC_DST_PER(h) ((0xFU & (h)) << 4) /* Channel dst rq associated with periph handshaking ifc h */
+#define ATC_SRC_REP (0x1 << 8) /* Source Replay Mod */
+#define ATC_SRC_H2SEL (0x1 << 9) /* Source Handshaking Mod */
+#define ATC_SRC_H2SEL_SW (0x0 << 9)
+#define ATC_SRC_H2SEL_HW (0x1 << 9)
+#define ATC_DST_REP (0x1 << 12) /* Destination Replay Mod */
+#define ATC_DST_H2SEL (0x1 << 13) /* Destination Handshaking Mod */
+#define ATC_DST_H2SEL_SW (0x0 << 13)
+#define ATC_DST_H2SEL_HW (0x1 << 13)
+#define ATC_SOD (0x1 << 16) /* Stop On Done */
+#define ATC_LOCK_IF (0x1 << 20) /* Interface Lock */
+#define ATC_LOCK_B (0x1 << 21) /* AHB Bus Lock */
+#define ATC_LOCK_IF_L (0x1 << 22) /* Master Interface Arbiter Lock */
+#define ATC_LOCK_IF_L_CHUNK (0x0 << 22)
+#define ATC_LOCK_IF_L_BUFFER (0x1 << 22)
+#define ATC_AHB_PROT_MASK (0x7 << 24) /* AHB Protection */
+#define ATC_FIFOCFG_MASK (0x3 << 28) /* FIFO Request Configuration */
+#define ATC_FIFOCFG_LARGESTBURST (0x0 << 28)
+#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)
+#define ATC_FIFOCFG_ENOUGHSPACE (0x2 << 28)
+
+/* Platform-configurable bits in CTRLA */
+#define ATC_SCSIZE_MASK (0x7 << 16) /* Source Chunk Transfer Size */
+#define ATC_SCSIZE_1 (0x0 << 16)
+#define ATC_SCSIZE_4 (0x1 << 16)
+#define ATC_SCSIZE_8 (0x2 << 16)
+#define ATC_SCSIZE_16 (0x3 << 16)
+#define ATC_SCSIZE_32 (0x4 << 16)
+#define ATC_SCSIZE_64 (0x5 << 16)
+#define ATC_SCSIZE_128 (0x6 << 16)
+#define ATC_SCSIZE_256 (0x7 << 16)
+#define ATC_DCSIZE_MASK (0x7 << 20) /* Destination Chunk Transfer Size */
+#define ATC_DCSIZE_1 (0x0 << 20)
+#define ATC_DCSIZE_4 (0x1 << 20)
+#define ATC_DCSIZE_8 (0x2 << 20)
+#define ATC_DCSIZE_16 (0x3 << 20)
+#define ATC_DCSIZE_32 (0x4 << 20)
+#define ATC_DCSIZE_64 (0x5 << 20)
+#define ATC_DCSIZE_128 (0x6 << 20)
+#define ATC_DCSIZE_256 (0x7 << 20)
+
+#endif /* AT_HDMAC_H */
diff --git a/arch/arm/mach-at91/include/mach/atmel-mci.h b/arch/arm/mach-at91/include/mach/atmel-mci.h
new file mode 100644
index 00000000..998cb0c0
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/atmel-mci.h
@@ -0,0 +1,24 @@
+#ifndef __MACH_ATMEL_MCI_H
+#define __MACH_ATMEL_MCI_H
+
+#include <mach/at_hdmac.h>
+
+/**
+ * struct mci_dma_data - DMA data for MCI interface
+ */
+struct mci_dma_data {
+ struct at_dma_slave sdata;
+};
+
+/* accessor macros */
+#define slave_data_ptr(s) (&(s)->sdata)
+#define find_slave_dev(s) ((s)->sdata.dma_dev)
+
+#define setup_dma_addr(s, t, r) do { \
+ if (s) { \
+ (s)->sdata.tx_reg = (t); \
+ (s)->sdata.rx_reg = (r); \
+ } \
+} while (0)
+
+#endif /* __MACH_ATMEL_MCI_H */
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
new file mode 100644
index 00000000..ed544a0d
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -0,0 +1,210 @@
+/*
+ * arch/arm/mach-at91/include/mach/board.h
+ *
+ * Copyright (C) 2005 HP Labs
+ *
+ * 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
+ */
+
+/*
+ * These are data structures found in platform_device.dev.platform_data,
+ * and describing board-specific data needed by drivers. For example,
+ * which pin is used for a given GPIO role.
+ *
+ * In 2.6, drivers should strongly avoid board-specific knowledge so
+ * that supporting new boards normally won't require driver patches.
+ * Most board-specific knowledge should be in arch/.../board-*.c files.
+ */
+
+#ifndef __ASM_ARCH_BOARD_H
+#define __ASM_ARCH_BOARD_H
+
+#include <linux/mtd/partitions.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/atmel_usba_udc.h>
+#include <linux/atmel-mci.h>
+#include <sound/atmel-ac97c.h>
+#include <linux/serial.h>
+
+ /* USB Device */
+struct at91_udc_data {
+ u8 vbus_pin; /* high == host powering us */
+ u8 vbus_active_low; /* vbus polarity */
+ u8 vbus_polled; /* Use polling, not interrupt */
+ u8 pullup_pin; /* active == D+ pulled up */
+ u8 pullup_active_low; /* true == pullup_pin is active low */
+};
+extern void __init at91_add_device_udc(struct at91_udc_data *data);
+
+ /* USB High Speed Device */
+extern void __init at91_add_device_usba(struct usba_platform_data *data);
+
+ /* Compact Flash */
+struct at91_cf_data {
+ u8 irq_pin; /* I/O IRQ */
+ u8 det_pin; /* Card detect */
+ u8 vcc_pin; /* power switching */
+ u8 rst_pin; /* card reset */
+ u8 chipselect; /* EBI Chip Select number */
+ u8 flags;
+#define AT91_CF_TRUE_IDE 0x01
+#define AT91_IDE_SWAP_A0_A2 0x02
+};
+extern void __init at91_add_device_cf(struct at91_cf_data *data);
+
+ /* MMC / SD */
+ /* at91_mci platform config */
+struct at91_mmc_data {
+ u8 det_pin; /* card detect IRQ */
+ unsigned slot_b:1; /* uses Slot B */
+ unsigned wire4:1; /* (SD) supports DAT0..DAT3 */
+ u8 wp_pin; /* (SD) writeprotect detect */
+ u8 vcc_pin; /* power switching (high == on) */
+};
+extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
+
+ /* atmel-mci platform config */
+extern void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data);
+
+ /* Ethernet (EMAC & MACB) */
+struct at91_eth_data {
+ u32 phy_mask;
+ u8 phy_irq_pin; /* PHY IRQ */
+ u8 is_rmii; /* using RMII interface? */
+};
+extern void __init at91_add_device_eth(struct at91_eth_data *data);
+
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91SAM9G20) || defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
+#define eth_platform_data at91_eth_data
+#endif
+
+ /* USB Host */
+struct at91_usbh_data {
+ u8 ports; /* number of ports on root hub */
+ u8 vbus_pin[2]; /* port power-control pin */
+};
+extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
+
+ /* NAND / SmartMedia */
+struct atmel_nand_data {
+ u8 enable_pin; /* chip enable */
+ u8 det_pin; /* card detect */
+ u8 rdy_pin; /* ready/busy */
+ u8 rdy_pin_active_low; /* rdy_pin value is inverted */
+ u8 ale; /* address line number connected to ALE */
+ u8 cle; /* address line number connected to CLE */
+ u8 bus_width_16; /* buswidth is 16 bit */
+ struct mtd_partition* (*partition_info)(int, int*);
+};
+extern void __init at91_add_device_nand(struct atmel_nand_data *data);
+
+ /* I2C*/
+#if defined(CONFIG_ARCH_AT91SAM9G45)
+extern void __init at91_add_device_i2c(short i2c_id, struct i2c_board_info *devices, int nr_devices);
+#else
+extern void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices);
+#endif
+
+ /* SPI */
+extern void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices);
+
+ /* Serial */
+#define ATMEL_UART_CTS 0x01
+#define ATMEL_UART_RTS 0x02
+#define ATMEL_UART_DSR 0x04
+#define ATMEL_UART_DTR 0x08
+#define ATMEL_UART_DCD 0x10
+#define ATMEL_UART_RI 0x20
+
+extern void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins);
+extern void __init at91_set_serial_console(unsigned portnr);
+
+extern struct platform_device *atmel_default_console_device;
+
+struct atmel_uart_data {
+ int num; /* port num */
+ short use_dma_tx; /* use transmit DMA? */
+ short use_dma_rx; /* use receive DMA? */
+ void __iomem *regs; /* virt. base address, if any */
+ struct serial_rs485 rs485; /* rs485 settings */
+};
+extern void __init at91_add_device_serial(void);
+
+/*
+ * PWM
+ */
+#define AT91_PWM0 0
+#define AT91_PWM1 1
+#define AT91_PWM2 2
+#define AT91_PWM3 3
+
+extern void __init at91_add_device_pwm(u32 mask);
+
+/*
+ * SSC -- accessed through ssc_request(id). Drivers don't bind to SSC
+ * platform devices. Their SSC ID is part of their configuration data,
+ * along with information about which SSC signals they should use.
+ */
+#define ATMEL_SSC_TK 0x01
+#define ATMEL_SSC_TF 0x02
+#define ATMEL_SSC_TD 0x04
+#define ATMEL_SSC_TX (ATMEL_SSC_TK | ATMEL_SSC_TF | ATMEL_SSC_TD)
+
+#define ATMEL_SSC_RK 0x10
+#define ATMEL_SSC_RF 0x20
+#define ATMEL_SSC_RD 0x40
+#define ATMEL_SSC_RX (ATMEL_SSC_RK | ATMEL_SSC_RF | ATMEL_SSC_RD)
+
+extern void __init at91_add_device_ssc(unsigned id, unsigned pins);
+
+ /* LCD Controller */
+struct atmel_lcdfb_info;
+extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
+
+ /* AC97 */
+extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
+
+ /* ISI */
+extern void __init at91_add_device_isi(void);
+
+ /* Touchscreen Controller */
+struct at91_tsadcc_data {
+ unsigned int adc_clock;
+ u8 pendet_debounce;
+ u8 ts_sample_hold_time;
+};
+extern void __init at91_add_device_tsadcc(struct at91_tsadcc_data *data);
+
+/* CAN */
+struct at91_can_data {
+ void (*transceiver_switch)(int on);
+};
+extern void __init at91_add_device_can(struct at91_can_data *data);
+
+ /* LEDs */
+extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
+extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);
+extern void __init at91_pwm_leds(struct gpio_led *leds, int nr);
+
+/* FIXME: this needs a better location, but gets stuff building again */
+extern int at91_suspend_entering_slow_clock(void);
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/clkdev.h b/arch/arm/mach-at91/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
new file mode 100644
index 00000000..df966c2b
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -0,0 +1,195 @@
+/*
+ * arch/arm/mach-at91/include/mach/cpu.h
+ *
+ * Copyright (C) 2006 SAN People
+ *
+ * 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_CPU_H
+#define __ASM_ARCH_CPU_H
+
+#include <mach/hardware.h>
+#include <mach/at91_dbgu.h>
+
+
+#define ARCH_ID_AT91RM9200 0x09290780
+#define ARCH_ID_AT91SAM9260 0x019803a0
+#define ARCH_ID_AT91SAM9261 0x019703a0
+#define ARCH_ID_AT91SAM9263 0x019607a0
+#define ARCH_ID_AT91SAM9G10 0x019903a0
+#define ARCH_ID_AT91SAM9G20 0x019905a0
+#define ARCH_ID_AT91SAM9RL64 0x019b03a0
+#define ARCH_ID_AT91SAM9G45 0x819b05a0
+#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
+#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
+#define ARCH_ID_AT91SAM9X5 0x819a05a0
+#define ARCH_ID_AT91CAP9 0x039A03A0
+
+#define ARCH_ID_AT91SAM9XE128 0x329973a0
+#define ARCH_ID_AT91SAM9XE256 0x329a93a0
+#define ARCH_ID_AT91SAM9XE512 0x329aa3a0
+
+#define ARCH_ID_AT91M40800 0x14080044
+#define ARCH_ID_AT91R40807 0x44080746
+#define ARCH_ID_AT91M40807 0x14080745
+#define ARCH_ID_AT91R40008 0x44000840
+
+static inline unsigned long at91_cpu_identify(void)
+{
+ return (at91_sys_read(AT91_DBGU_CIDR) & ~AT91_CIDR_VERSION);
+}
+
+static inline unsigned long at91_cpu_fully_identify(void)
+{
+ return at91_sys_read(AT91_DBGU_CIDR);
+}
+
+#define ARCH_EXID_AT91SAM9M11 0x00000001
+#define ARCH_EXID_AT91SAM9M10 0x00000002
+#define ARCH_EXID_AT91SAM9G46 0x00000003
+#define ARCH_EXID_AT91SAM9G45 0x00000004
+
+#define ARCH_EXID_AT91SAM9G15 0x00000000
+#define ARCH_EXID_AT91SAM9G35 0x00000001
+#define ARCH_EXID_AT91SAM9X35 0x00000002
+#define ARCH_EXID_AT91SAM9G25 0x00000003
+#define ARCH_EXID_AT91SAM9X25 0x00000004
+
+static inline unsigned long at91_exid_identify(void)
+{
+ return at91_sys_read(AT91_DBGU_EXID);
+}
+
+
+#define ARCH_FAMILY_AT91X92 0x09200000
+#define ARCH_FAMILY_AT91SAM9 0x01900000
+#define ARCH_FAMILY_AT91SAM9XE 0x02900000
+
+static inline unsigned long at91_arch_identify(void)
+{
+ return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH);
+}
+
+#ifdef CONFIG_ARCH_AT91CAP9
+#include <mach/at91_pmc.h>
+
+#define ARCH_REVISION_CAP9_B 0x399
+#define ARCH_REVISION_CAP9_C 0x601
+
+static inline unsigned long at91cap9_rev_identify(void)
+{
+ return (at91_sys_read(AT91_PMC_VER));
+}
+#endif
+
+#ifdef CONFIG_ARCH_AT91RM9200
+extern int rm9200_type;
+#define ARCH_REVISON_9200_BGA (0 << 0)
+#define ARCH_REVISON_9200_PQFP (1 << 0)
+#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200)
+#define cpu_is_at91rm9200_bga() (!cpu_is_at91rm9200_pqfp())
+#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP)
+#else
+#define cpu_is_at91rm9200() (0)
+#define cpu_is_at91rm9200_bga() (0)
+#define cpu_is_at91rm9200_pqfp() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9260
+#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE)
+#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe())
+#else
+#define cpu_is_at91sam9xe() (0)
+#define cpu_is_at91sam9260() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9G20
+#define cpu_is_at91sam9g20() (at91_cpu_identify() == ARCH_ID_AT91SAM9G20)
+#else
+#define cpu_is_at91sam9g20() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9261
+#define cpu_is_at91sam9261() (at91_cpu_identify() == ARCH_ID_AT91SAM9261)
+#else
+#define cpu_is_at91sam9261() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9G10
+#define cpu_is_at91sam9g10() ((at91_cpu_identify() & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10)
+#else
+#define cpu_is_at91sam9g10() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263)
+#else
+#define cpu_is_at91sam9263() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9RL
+#define cpu_is_at91sam9rl() (at91_cpu_identify() == ARCH_ID_AT91SAM9RL64)
+#else
+#define cpu_is_at91sam9rl() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9G45
+#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
+#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
+#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9M10))
+#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9G46))
+#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9M11))
+#else
+#define cpu_is_at91sam9g45() (0)
+#define cpu_is_at91sam9g45es() (0)
+#define cpu_is_at91sam9m10() (0)
+#define cpu_is_at91sam9g46() (0)
+#define cpu_is_at91sam9m11() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91SAM9X5
+#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5)
+#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9G15))
+#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9G35))
+#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9X35))
+#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9G25))
+#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9X25))
+#else
+#define cpu_is_at91sam9x5() (0)
+#define cpu_is_at91sam9g15() (0)
+#define cpu_is_at91sam9g35() (0)
+#define cpu_is_at91sam9x35() (0)
+#define cpu_is_at91sam9g25() (0)
+#define cpu_is_at91sam9x25() (0)
+#endif
+
+#ifdef CONFIG_ARCH_AT91CAP9
+#define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9)
+#define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B)
+#define cpu_is_at91cap9_revC() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_C)
+#else
+#define cpu_is_at91cap9() (0)
+#define cpu_is_at91cap9_revB() (0)
+#define cpu_is_at91cap9_revC() (0)
+#endif
+
+/*
+ * Since this is ARM, we will never run on any AVR32 CPU. But these
+ * definitions may reduce clutter in common drivers.
+ */
+#define cpu_is_at32ap7000() (0)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/mach-at91/include/mach/debug-macro.S
new file mode 100644
index 00000000..0f959faf
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/debug-macro.S
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-at91/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2003-2005 SAN People
+ *
+ * Debugging macro include 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.
+ *
+*/
+
+#include <mach/hardware.h>
+#include <mach/at91_dbgu.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
+ ldr \rv, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address)
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #(AT91_DBGU_THR - AT91_DBGU)] @ Write to Transmitter Holding Register
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register
+ tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit
+ beq 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register
+ tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
+ beq 1001b
+ .endm
+
diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S
new file mode 100644
index 00000000..7ab68f97
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/entry-macro.S
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-at91/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2003-2005 SAN People
+ *
+ * Low-level IRQ helper macros for AT91RM9200 platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/at91_aic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
+ ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number
+ teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt
+ streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now.
+ .endm
+
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
new file mode 100644
index 00000000..056dc667
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -0,0 +1,228 @@
+/*
+ * arch/arm/mach-at91/include/mach/gpio.h
+ *
+ * Copyright (C) 2005 HP Labs
+ *
+ * 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_AT91RM9200_GPIO_H
+#define __ASM_ARCH_AT91RM9200_GPIO_H
+
+#include <linux/kernel.h>
+#include <asm/irq.h>
+
+#define PIN_BASE NR_AIC_IRQS
+
+#define MAX_GPIO_BANKS 5
+#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32))
+
+/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
+
+#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0)
+#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1)
+#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2)
+#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3)
+#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4)
+#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5)
+#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6)
+#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7)
+#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8)
+#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9)
+#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10)
+#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11)
+#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12)
+#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13)
+#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14)
+#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15)
+#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16)
+#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17)
+#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18)
+#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19)
+#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20)
+#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21)
+#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22)
+#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23)
+#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24)
+#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25)
+#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26)
+#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27)
+#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28)
+#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29)
+#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30)
+#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31)
+
+#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0)
+#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1)
+#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2)
+#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3)
+#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4)
+#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5)
+#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6)
+#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7)
+#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8)
+#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9)
+#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10)
+#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11)
+#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12)
+#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13)
+#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14)
+#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15)
+#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16)
+#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17)
+#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18)
+#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19)
+#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20)
+#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21)
+#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22)
+#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23)
+#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24)
+#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25)
+#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26)
+#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27)
+#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28)
+#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29)
+#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30)
+#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31)
+
+#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0)
+#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1)
+#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2)
+#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3)
+#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4)
+#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5)
+#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6)
+#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7)
+#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8)
+#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9)
+#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10)
+#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11)
+#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12)
+#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13)
+#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14)
+#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15)
+#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16)
+#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17)
+#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18)
+#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19)
+#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20)
+#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21)
+#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22)
+#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23)
+#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24)
+#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25)
+#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26)
+#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27)
+#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28)
+#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29)
+#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30)
+#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
+
+#define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0)
+#define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1)
+#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2)
+#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3)
+#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4)
+#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5)
+#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6)
+#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7)
+#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8)
+#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9)
+#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10)
+#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11)
+#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12)
+#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13)
+#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14)
+#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15)
+#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16)
+#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17)
+#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18)
+#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19)
+#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20)
+#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21)
+#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22)
+#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23)
+#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24)
+#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25)
+#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26)
+#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27)
+#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28)
+#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29)
+#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30)
+#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31)
+
+#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0)
+#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1)
+#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2)
+#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3)
+#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4)
+#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5)
+#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6)
+#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7)
+#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8)
+#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9)
+#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10)
+#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11)
+#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12)
+#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13)
+#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14)
+#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15)
+#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16)
+#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17)
+#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18)
+#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19)
+#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20)
+#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21)
+#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22)
+#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23)
+#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24)
+#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25)
+#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26)
+#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27)
+#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28)
+#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29)
+#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30)
+#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31)
+
+#ifndef __ASSEMBLY__
+/* setup setup routines, called from board init or driver probe() */
+extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
+extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
+extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
+
+/* callable at any time */
+extern int at91_set_gpio_value(unsigned pin, int value);
+extern int at91_get_gpio_value(unsigned pin);
+
+/* callable only from core power-management code */
+extern void at91_gpio_suspend(void);
+extern void at91_gpio_resume(void);
+
+/*-------------------------------------------------------------------------*/
+
+/* wrappers for "new style" GPIO calls. the old AT91-specific ones should
+ * eventually be removed (along with this errno.h inclusion), and the
+ * gpio request/free calls should probably be implemented.
+ */
+
+#include <asm/errno.h>
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (gpio)
+#define irq_to_gpio(irq) (irq)
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/gsia18s.h b/arch/arm/mach-at91/include/mach/gsia18s.h
new file mode 100644
index 00000000..307c1949
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/gsia18s.h
@@ -0,0 +1,33 @@
+/* Buttons */
+#define GPIO_TRIG_NET_IN AT91_PIN_PB21
+#define GPIO_CARD_UNMOUNT_0 AT91_PIN_PB13
+#define GPIO_CARD_UNMOUNT_1 AT91_PIN_PB12
+#define GPIO_KEY_POWER AT91_PIN_PA25
+
+/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */
+#define GS_IA18_S_PCF_GPIO_BASE0 NR_BUILTIN_GPIO
+#define PCF_GPIO_HDC_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 0)
+#define PCF_GPIO_WIFI_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 1)
+#define PCF_GPIO_WIFI_ENABLE (GS_IA18_S_PCF_GPIO_BASE0 + 2)
+#define PCF_GPIO_WIFI_RESET (GS_IA18_S_PCF_GPIO_BASE0 + 3)
+#define PCF_GPIO_ETH_DETECT 4 /* this is a GPI */
+#define PCF_GPIO_GPS_SETUP (GS_IA18_S_PCF_GPIO_BASE0 + 5)
+#define PCF_GPIO_GPS_STANDBY (GS_IA18_S_PCF_GPIO_BASE0 + 6)
+#define PCF_GPIO_GPS_POWER (GS_IA18_S_PCF_GPIO_BASE0 + 7)
+
+/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
+#define GS_IA18_S_PCF_GPIO_BASE1 (GS_IA18_S_PCF_GPIO_BASE0 + 8)
+#define PCF_GPIO_ALARM1 (GS_IA18_S_PCF_GPIO_BASE1 + 0)
+#define PCF_GPIO_ALARM2 (GS_IA18_S_PCF_GPIO_BASE1 + 1)
+#define PCF_GPIO_ALARM3 (GS_IA18_S_PCF_GPIO_BASE1 + 2)
+#define PCF_GPIO_ALARM4 (GS_IA18_S_PCF_GPIO_BASE1 + 3)
+/* bits 4, 5, 6 not used */
+#define PCF_GPIO_ALARM_V_RELAY_ON (GS_IA18_S_PCF_GPIO_BASE1 + 7)
+
+/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */
+#define GS_IA18_S_PCF_GPIO_BASE2 (GS_IA18_S_PCF_GPIO_BASE1 + 8)
+#define PCF_GPIO_MODEM_POWER (GS_IA18_S_PCF_GPIO_BASE2 + 0)
+#define PCF_GPIO_MODEM_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 3)
+/* bits 1, 2, 4, 5 not used */
+#define PCF_GPIO_TRX_RESET (GS_IA18_S_PCF_GPIO_BASE2 + 6)
+/* bit 7 not used */
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
new file mode 100644
index 00000000..1008b9fb
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-at91/include/mach/hardware.h
+ *
+ * Copyright (C) 2003 SAN People
+ * Copyright (C) 2003 ATMEL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+#if defined(CONFIG_ARCH_AT91RM9200)
+#include <mach/at91rm9200.h>
+#elif defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
+#include <mach/at91sam9260.h>
+#elif defined(CONFIG_ARCH_AT91SAM9261) || defined(CONFIG_ARCH_AT91SAM9G10)
+#include <mach/at91sam9261.h>
+#elif defined(CONFIG_ARCH_AT91SAM9263)
+#include <mach/at91sam9263.h>
+#elif defined(CONFIG_ARCH_AT91SAM9RL)
+#include <mach/at91sam9rl.h>
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9g45.h>
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9.h>
+#elif defined(CONFIG_ARCH_AT91X40)
+#include <mach/at91x40.h>
+#else
+#error "Unsupported AT91 processor"
+#endif
+
+
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS 1 /* System Peripherals */
+
+#ifdef CONFIG_MMU
+/*
+ * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
+ * to 0xFEF78000 .. 0xFF000000. (544Kb)
+ */
+#define AT91_IO_PHYS_BASE 0xFFF78000
+#define AT91_IO_VIRT_BASE (0xFF000000 - AT91_IO_SIZE)
+#else
+/*
+ * Identity mapping for the non MMU case.
+ */
+#define AT91_IO_PHYS_BASE AT91_BASE_SYS
+#define AT91_IO_VIRT_BASE AT91_IO_PHYS_BASE
+#endif
+
+#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
+
+ /* Convert a physical IO address to virtual IO address */
+#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
+
+/*
+ * Virtual to Physical Address mapping for IO devices.
+ */
+#define AT91_VA_BASE_SYS AT91_IO_P2V(AT91_BASE_SYS)
+#define AT91_VA_BASE_EMAC AT91_IO_P2V(AT91RM9200_BASE_EMAC)
+
+ /* Internal SRAM is mapped below the IO devices */
+#define AT91_SRAM_MAX SZ_1M
+#define AT91_VIRT_BASE (AT91_IO_VIRT_BASE - AT91_SRAM_MAX)
+
+/* Serial ports */
+#define ATMEL_MAX_UART 7 /* 6 USART3's and one DBGU port (SAM9260) */
+
+/* External Memory Map */
+#define AT91_CHIPSELECT_0 0x10000000
+#define AT91_CHIPSELECT_1 0x20000000
+#define AT91_CHIPSELECT_2 0x30000000
+#define AT91_CHIPSELECT_3 0x40000000
+#define AT91_CHIPSELECT_4 0x50000000
+#define AT91_CHIPSELECT_5 0x60000000
+#define AT91_CHIPSELECT_6 0x70000000
+#define AT91_CHIPSELECT_7 0x80000000
+
+/* Clocks */
+#define AT91_SLOW_CLOCK 32768 /* slow clock */
+
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/io.h b/arch/arm/mach-at91/include/mach/io.h
new file mode 100644
index 00000000..0b0cccc4
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/io.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-at91/include/mach/io.h
+ *
+ * Copyright (C) 2003 SAN People
+ *
+ * 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 __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xFFFFFFFF
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned int at91_sys_read(unsigned int reg_offset)
+{
+ void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
+
+ return __raw_readl(addr + reg_offset);
+}
+
+static inline void at91_sys_write(unsigned int reg_offset, unsigned long value)
+{
+ void __iomem *addr = (void __iomem *)AT91_VA_BASE_SYS;
+
+ __raw_writel(value, addr + reg_offset);
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/irqs.h b/arch/arm/mach-at91/include/mach/irqs.h
new file mode 100644
index 00000000..36bd55f3
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/irqs.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-at91/include/mach/irqs.h
+ *
+ * Copyright (C) 2004 SAN People
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include <linux/io.h>
+#include <mach/at91_aic.h>
+
+#define NR_AIC_IRQS 32
+
+
+/*
+ * Acknowledge interrupt with AIC after interrupt has been handled.
+ * (by kernel/irq.c)
+ */
+#define irq_finish(irq) do { at91_sys_write(AT91_AIC_EOICR, 0); } while (0)
+
+
+/*
+ * IRQ interrupt symbols are the AT91xxx_ID_* symbols
+ * for IRQs handled directly through the AIC, or else the AT91_PIN_*
+ * symbols in gpio.h for ones handled indirectly as GPIOs.
+ * We make provision for 5 banks of GPIO.
+ */
+#define NR_IRQS (NR_AIC_IRQS + (5 * 32))
+
+/* FIQ is AIC source 0. */
+#define FIQ_START AT91_ID_FIQ
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h
new file mode 100644
index 00000000..401c207f
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/memory.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-at91/include/mach/memory.h
+ *
+ * Copyright (C) 2004 SAN People
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <mach/hardware.h>
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h
new file mode 100644
index 00000000..f62c0abc
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/stamp9g20.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_STAMP9G20_H
+#define __MACH_STAMP9G20_H
+
+void stamp9g20_init_early(void);
+void stamp9g20_board_init(void);
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
new file mode 100644
index 00000000..36af14bc
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/system.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-at91/include/mach/system.h
+ *
+ * Copyright (C) 2003 SAN People
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/hardware.h>
+#include <mach/at91_st.h>
+#include <mach/at91_dbgu.h>
+#include <mach/at91_pmc.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * Disable the processor clock. The processor will be automatically
+ * re-enabled by an interrupt or by a reset.
+ */
+#ifdef AT91_PS
+ at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
+#else
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+#endif
+#ifndef CONFIG_CPU_ARM920T
+ /*
+ * Set the processor (CP15) into 'Wait for Interrupt' mode.
+ * Post-RM9200 processors need this in conjunction with the above
+ * to save power when idle.
+ */
+ cpu_do_idle();
+#endif
+}
+
+void (*at91_arch_reset)(void);
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /* call the CPU-specific reset function */
+ if (at91_arch_reset)
+ (at91_arch_reset)();
+}
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h
new file mode 100644
index 00000000..8f486604
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/system_rev.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#ifndef __ARCH_SYSTEM_REV_H__
+#define __ARCH_SYSTEM_REV_H__
+
+/*
+ * board revision encoding
+ * mach specific
+ * the 16-31 bit are reserved for at91 generic information
+ *
+ * bit 31:
+ * 0 => nand 8 bit
+ * 1 => nand 16 bit
+ */
+#define BOARD_HAVE_NAND_16BIT (1 << 31)
+static inline int board_have_nand_16bit(void)
+{
+ return system_rev & BOARD_HAVE_NAND_16BIT;
+}
+
+#endif /* __ARCH_SYSTEM_REV_H__ */
diff --git a/arch/arm/mach-at91/include/mach/timex.h b/arch/arm/mach-at91/include/mach/timex.h
new file mode 100644
index 00000000..31ac2d97
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/timex.h
@@ -0,0 +1,87 @@
+/*
+ * arch/arm/mach-at91/include/mach/timex.h
+ *
+ * Copyright (C) 2003 SAN People
+ *
+ * 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 __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#include <mach/hardware.h>
+
+#if defined(CONFIG_ARCH_AT91RM9200)
+
+#define CLOCK_TICK_RATE (AT91_SLOW_CLOCK)
+
+#elif defined(CONFIG_ARCH_AT91SAM9260)
+
+#if defined(CONFIG_MACH_USB_A9260) || defined(CONFIG_MACH_QIL_A9260)
+#define AT91SAM9_MASTER_CLOCK 90000000
+#else
+#define AT91SAM9_MASTER_CLOCK 99300000
+#endif
+
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9261)
+
+#define AT91SAM9_MASTER_CLOCK 99300000
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9G10)
+
+#define AT91SAM9_MASTER_CLOCK 133000000
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9263)
+
+#if defined(CONFIG_MACH_USB_A9263)
+#define AT91SAM9_MASTER_CLOCK 90000000
+#else
+#define AT91SAM9_MASTER_CLOCK 99959500
+#endif
+
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9RL)
+
+#define AT91SAM9_MASTER_CLOCK 100000000
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9G20)
+
+#define AT91SAM9_MASTER_CLOCK 132096000
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+
+#define AT91SAM9_MASTER_CLOCK 133333333
+#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91CAP9)
+
+#define AT91CAP9_MASTER_CLOCK 100000000
+#define CLOCK_TICK_RATE (AT91CAP9_MASTER_CLOCK/16)
+
+#elif defined(CONFIG_ARCH_AT91X40)
+
+#define AT91X40_MASTER_CLOCK 40000000
+#define CLOCK_TICK_RATE (AT91X40_MASTER_CLOCK)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/uncompress.h b/arch/arm/mach-at91/include/mach/uncompress.h
new file mode 100644
index 00000000..18bdcdeb
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-at91/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 SAN People
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <linux/io.h>
+#include <linux/atmel_serial.h>
+
+#if defined(CONFIG_AT91_EARLY_DBGU)
+#define UART_OFFSET (AT91_DBGU + AT91_BASE_SYS)
+#elif defined(CONFIG_AT91_EARLY_USART0)
+#define UART_OFFSET AT91_USART0
+#elif defined(CONFIG_AT91_EARLY_USART1)
+#define UART_OFFSET AT91_USART1
+#elif defined(CONFIG_AT91_EARLY_USART2)
+#define UART_OFFSET AT91_USART2
+#elif defined(CONFIG_AT91_EARLY_USART3)
+#define UART_OFFSET AT91_USART3
+#elif defined(CONFIG_AT91_EARLY_USART4)
+#define UART_OFFSET AT91_USART4
+#elif defined(CONFIG_AT91_EARLY_USART5)
+#define UART_OFFSET AT91_USART5
+#endif
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+#ifdef UART_OFFSET
+ void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */
+
+ while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXRDY))
+ barrier();
+ __raw_writel(c, sys + ATMEL_US_THR);
+#endif
+}
+
+static inline void flush(void)
+{
+#ifdef UART_OFFSET
+ void __iomem *sys = (void __iomem *) UART_OFFSET; /* physical address */
+
+ /* wait for transmission to complete */
+ while (!(__raw_readl(sys + ATMEL_US_CSR) & ATMEL_US_TXEMPTY))
+ barrier();
+#endif
+}
+
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/vmalloc.h b/arch/arm/mach-at91/include/mach/vmalloc.h
new file mode 100644
index 00000000..8eb459f3
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/vmalloc.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-at91/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2003 SAN People
+ *
+ * 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 __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK)
+
+#endif
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
new file mode 100644
index 00000000..9665265e
--- /dev/null
+++ b/arch/arm/mach-at91/irq.c
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-at91/irq.c
+ *
+ * Copyright (C) 2004 SAN People
+ * Copyright (C) 2004 ATMEL
+ * Copyright (C) Rick Bronson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+
+static void at91_aic_mask_irq(struct irq_data *d)
+{
+ /* Disable interrupt on AIC */
+ at91_sys_write(AT91_AIC_IDCR, 1 << d->irq);
+}
+
+static void at91_aic_unmask_irq(struct irq_data *d)
+{
+ /* Enable interrupt on AIC */
+ at91_sys_write(AT91_AIC_IECR, 1 << d->irq);
+}
+
+unsigned int at91_extern_irq;
+
+#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq)
+
+static int at91_aic_set_type(struct irq_data *d, unsigned type)
+{
+ unsigned int smr, srctype;
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ srctype = AT91_AIC_SRCTYPE_HIGH;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ srctype = AT91_AIC_SRCTYPE_RISING;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */
+ srctype = AT91_AIC_SRCTYPE_LOW;
+ else
+ return -EINVAL;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ if ((d->irq == AT91_ID_FIQ) || is_extern_irq(d->irq)) /* only supported on external interrupts */
+ srctype = AT91_AIC_SRCTYPE_FALLING;
+ else
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ smr = at91_sys_read(AT91_AIC_SMR(d->irq)) & ~AT91_AIC_SRCTYPE;
+ at91_sys_write(AT91_AIC_SMR(d->irq), smr | srctype);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static u32 wakeups;
+static u32 backups;
+
+static int at91_aic_set_wake(struct irq_data *d, unsigned value)
+{
+ if (unlikely(d->irq >= 32))
+ return -EINVAL;
+
+ if (value)
+ wakeups |= (1 << d->irq);
+ else
+ wakeups &= ~(1 << d->irq);
+
+ return 0;
+}
+
+void at91_irq_suspend(void)
+{
+ backups = at91_sys_read(AT91_AIC_IMR);
+ at91_sys_write(AT91_AIC_IDCR, backups);
+ at91_sys_write(AT91_AIC_IECR, wakeups);
+}
+
+void at91_irq_resume(void)
+{
+ at91_sys_write(AT91_AIC_IDCR, wakeups);
+ at91_sys_write(AT91_AIC_IECR, backups);
+}
+
+#else
+#define at91_aic_set_wake NULL
+#endif
+
+static struct irq_chip at91_aic_chip = {
+ .name = "AIC",
+ .irq_ack = at91_aic_mask_irq,
+ .irq_mask = at91_aic_mask_irq,
+ .irq_unmask = at91_aic_unmask_irq,
+ .irq_set_type = at91_aic_set_type,
+ .irq_set_wake = at91_aic_set_wake,
+};
+
+/*
+ * Initialize the AIC interrupt controller.
+ */
+void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
+{
+ unsigned int i;
+
+ /*
+ * The IVR is used by macro get_irqnr_and_base to read and verify.
+ * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
+ */
+ for (i = 0; i < NR_AIC_IRQS; i++) {
+ /* Put irq number in Source Vector Register: */
+ at91_sys_write(AT91_AIC_SVR(i), i);
+ /* Active Low interrupt, with the specified priority */
+ at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
+
+ irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+
+ /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
+ if (i < 8)
+ at91_sys_write(AT91_AIC_EOICR, 0);
+ }
+
+ /*
+ * Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
+ * When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
+ */
+ at91_sys_write(AT91_AIC_SPU, NR_AIC_IRQS);
+
+ /* No debugging in AIC: Debug (Protect) Control Register */
+ at91_sys_write(AT91_AIC_DCR, 0);
+
+ /* Disable and clear all interrupts initially */
+ at91_sys_write(AT91_AIC_IDCR, 0xFFFFFFFF);
+ at91_sys_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+}
diff --git a/arch/arm/mach-at91/leds.c b/arch/arm/mach-at91/leds.c
new file mode 100644
index 00000000..0415a839
--- /dev/null
+++ b/arch/arm/mach-at91/leds.c
@@ -0,0 +1,197 @@
+/*
+ * LED driver for Atmel AT91-based boards.
+ *
+ * Copyright (C) SAN People (Pty) 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/board.h>
+#include <mach/gpio.h>
+
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_NEW_LEDS)
+
+/*
+ * New cross-platform LED support.
+ */
+
+static struct gpio_led_platform_data led_data;
+
+static struct platform_device at91_gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &led_data,
+};
+
+void __init at91_gpio_leds(struct gpio_led *leds, int nr)
+{
+ int i;
+
+ if (!nr)
+ return;
+
+ for (i = 0; i < nr; i++)
+ at91_set_gpio_output(leds[i].gpio, leds[i].active_low);
+
+ led_data.leds = leds;
+ led_data.num_leds = nr;
+ platform_device_register(&at91_gpio_leds_device);
+}
+
+#else
+void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+
+#if defined (CONFIG_LEDS_ATMEL_PWM)
+
+/*
+ * PWM Leds
+ */
+
+static struct gpio_led_platform_data pwm_led_data;
+
+static struct platform_device at91_pwm_leds_device = {
+ .name = "leds-atmel-pwm",
+ .id = -1,
+ .dev.platform_data = &pwm_led_data,
+};
+
+void __init at91_pwm_leds(struct gpio_led *leds, int nr)
+{
+ int i;
+ u32 pwm_mask = 0;
+
+ if (!nr)
+ return;
+
+ for (i = 0; i < nr; i++)
+ pwm_mask |= (1 << leds[i].gpio);
+
+ pwm_led_data.leds = leds;
+ pwm_led_data.num_leds = nr;
+
+ at91_add_device_pwm(pwm_mask);
+ platform_device_register(&at91_pwm_leds_device);
+}
+#else
+void __init at91_pwm_leds(struct gpio_led *leds, int nr){}
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_LEDS)
+
+#include <asm/leds.h>
+
+/*
+ * Old ARM-specific LED framework; not fully functional when generic time is
+ * in use.
+ */
+
+static u8 at91_leds_cpu;
+static u8 at91_leds_timer;
+
+static inline void at91_led_on(unsigned int led)
+{
+ at91_set_gpio_value(led, 0);
+}
+
+static inline void at91_led_off(unsigned int led)
+{
+ at91_set_gpio_value(led, 1);
+}
+
+static inline void at91_led_toggle(unsigned int led)
+{
+ unsigned long is_off = at91_get_gpio_value(led);
+ if (is_off)
+ at91_led_on(led);
+ else
+ at91_led_off(led);
+}
+
+
+/*
+ * Handle LED events.
+ */
+static void at91_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch(evt) {
+ case led_start: /* System startup */
+ at91_led_on(at91_leds_cpu);
+ break;
+
+ case led_stop: /* System stop / suspend */
+ at91_led_off(at91_leds_cpu);
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer: /* Every 50 timer ticks */
+ at91_led_toggle(at91_leds_timer);
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start: /* Entering idle state */
+ at91_led_off(at91_leds_cpu);
+ break;
+
+ case led_idle_end: /* Exit idle state */
+ at91_led_on(at91_leds_cpu);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ local_irq_restore(flags);
+}
+
+
+static int __init leds_init(void)
+{
+ if (!at91_leds_timer || !at91_leds_cpu)
+ return -ENODEV;
+
+ leds_event = at91_leds_event;
+
+ leds_event(led_start);
+ return 0;
+}
+
+__initcall(leds_init);
+
+
+void __init at91_init_leds(u8 cpu_led, u8 timer_led)
+{
+ /* Enable GPIO to access the LEDs */
+ at91_set_gpio_output(cpu_led, 1);
+ at91_set_gpio_output(timer_led, 1);
+
+ at91_leds_cpu = cpu_led;
+ at91_leds_timer = timer_led;
+}
+
+#else
+void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
+#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
new file mode 100644
index 00000000..ea53f4d9
--- /dev/null
+++ b/arch/arm/mach-at91/pm.c
@@ -0,0 +1,329 @@
+/*
+ * arch/arm/mach-at91/pm.c
+ * AT91 Power Management
+ *
+ * Copyright (C) 2005 David Brownell
+ *
+ * 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/suspend.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include <mach/at91_pmc.h>
+#include <mach/gpio.h>
+#include <mach/cpu.h>
+
+#include "generic.h"
+#include "pm.h"
+
+/*
+ * Show the reason for the previous system reset.
+ */
+#if defined(AT91_SHDWC)
+
+#include <mach/at91_rstc.h>
+#include <mach/at91_shdwc.h>
+
+static void __init show_reset_status(void)
+{
+ static char reset[] __initdata = "reset";
+
+ static char general[] __initdata = "general";
+ static char wakeup[] __initdata = "wakeup";
+ static char watchdog[] __initdata = "watchdog";
+ static char software[] __initdata = "software";
+ static char user[] __initdata = "user";
+ static char unknown[] __initdata = "unknown";
+
+ static char signal[] __initdata = "signal";
+ static char rtc[] __initdata = "rtc";
+ static char rtt[] __initdata = "rtt";
+ static char restore[] __initdata = "power-restored";
+
+ char *reason, *r2 = reset;
+ u32 reset_type, wake_type;
+
+ reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP;
+ wake_type = at91_sys_read(AT91_SHDW_SR);
+
+ switch (reset_type) {
+ case AT91_RSTC_RSTTYP_GENERAL:
+ reason = general;
+ break;
+ case AT91_RSTC_RSTTYP_WAKEUP:
+ /* board-specific code enabled the wakeup sources */
+ reason = wakeup;
+
+ /* "wakeup signal" */
+ if (wake_type & AT91_SHDW_WAKEUP0)
+ r2 = signal;
+ else {
+ r2 = reason;
+ if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */
+ reason = rtt;
+ else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */
+ reason = rtc;
+ else if (wake_type == 0) /* power-restored wakeup */
+ reason = restore;
+ else /* unknown wakeup */
+ reason = unknown;
+ }
+ break;
+ case AT91_RSTC_RSTTYP_WATCHDOG:
+ reason = watchdog;
+ break;
+ case AT91_RSTC_RSTTYP_SOFTWARE:
+ reason = software;
+ break;
+ case AT91_RSTC_RSTTYP_USER:
+ reason = user;
+ break;
+ default:
+ reason = unknown;
+ break;
+ }
+ pr_info("AT91: Starting after %s %s\n", reason, r2);
+}
+#else
+static void __init show_reset_status(void) {}
+#endif
+
+
+static int at91_pm_valid_state(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_ON:
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+
+static suspend_state_t target_state;
+
+/*
+ * Called after processes are frozen, but before we shutdown devices.
+ */
+static int at91_pm_begin(suspend_state_t state)
+{
+ target_state = state;
+ return 0;
+}
+
+/*
+ * Verify that all the clocks are correct before entering
+ * slow-clock mode.
+ */
+static int at91_pm_verify_clocks(void)
+{
+ unsigned long scsr;
+ int i;
+
+ scsr = at91_sys_read(AT91_PMC_SCSR);
+
+ /* USB must not be using PLLB */
+ if (cpu_is_at91rm9200()) {
+ if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
+ }
+ } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
+ || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
+ if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
+ }
+ } else if (cpu_is_at91cap9()) {
+ if ((scsr & AT91CAP9_PMC_UHP) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
+ }
+ }
+
+#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
+ /* PCK0..PCK3 must be disabled, or configured to use clk32k */
+ for (i = 0; i < 4; i++) {
+ u32 css;
+
+ if ((scsr & (AT91_PMC_PCK0 << i)) == 0)
+ continue;
+
+ css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS;
+ if (css != AT91_PMC_CSS_SLOW) {
+ pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css);
+ return 0;
+ }
+ }
+#endif
+
+ return 1;
+}
+
+/*
+ * Call this from platform driver suspend() to see how deeply to suspend.
+ * For example, some controllers (like OHCI) need one of the PLL clocks
+ * in order to act as a wakeup source, and those are not available when
+ * going into slow clock mode.
+ *
+ * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have
+ * the very same problem (but not using at91 main_clk), and it'd be better
+ * to add one generic API rather than lots of platform-specific ones.
+ */
+int at91_suspend_entering_slow_clock(void)
+{
+ return (target_state == PM_SUSPEND_MEM);
+}
+EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
+
+
+static void (*slow_clock)(void);
+
+#ifdef CONFIG_AT91_SLOW_CLOCK
+extern void at91_slow_clock(void);
+extern u32 at91_slow_clock_sz;
+#endif
+
+
+static int at91_pm_enter(suspend_state_t state)
+{
+ u32 saved_lpr;
+ at91_gpio_suspend();
+ at91_irq_suspend();
+
+ pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
+ /* remember all the always-wake irqs */
+ (at91_sys_read(AT91_PMC_PCSR)
+ | (1 << AT91_ID_FIQ)
+ | (1 << AT91_ID_SYS)
+ | (at91_extern_irq))
+ & at91_sys_read(AT91_AIC_IMR),
+ state);
+
+ switch (state) {
+ /*
+ * Suspend-to-RAM is like STANDBY plus slow clock mode, so
+ * drivers must suspend more deeply: only the master clock
+ * controller may be using the main oscillator.
+ */
+ case PM_SUSPEND_MEM:
+ /*
+ * Ensure that clocks are in a valid state.
+ */
+ if (!at91_pm_verify_clocks())
+ goto error;
+
+ /*
+ * Enter slow clock mode by switching over to clk32k and
+ * turning off the main oscillator; reverse on wakeup.
+ */
+ if (slow_clock) {
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ /* copy slow_clock handler to SRAM, and call it */
+ memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
+#endif
+ slow_clock();
+ break;
+ } else {
+ pr_info("AT91: PM - no slow clock mode enabled ...\n");
+ /* FALLTHROUGH leaving master clock alone */
+ }
+
+ /*
+ * STANDBY mode has *all* drivers suspended; ignores irqs not
+ * marked as 'wakeup' event sources; and reduces DRAM power.
+ * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and
+ * nothing fancy done with main or cpu clocks.
+ */
+ case PM_SUSPEND_STANDBY:
+ /*
+ * NOTE: the Wait-for-Interrupt instruction needs to be
+ * in icache so no SDRAM accesses are needed until the
+ * wakeup IRQ occurs and self-refresh is terminated.
+ * For ARM 926 based chips, this requirement is weaker
+ * as at91sam9 can access a RAM in self-refresh mode.
+ */
+ asm volatile ( "mov r0, #0\n\t"
+ "b 1f\n\t"
+ ".align 5\n\t"
+ "1: mcr p15, 0, r0, c7, c10, 4\n\t"
+ : /* no output */
+ : /* no input */
+ : "r0");
+ saved_lpr = sdram_selfrefresh_enable();
+ wait_for_interrupt_enable();
+ sdram_selfrefresh_disable(saved_lpr);
+ break;
+
+ case PM_SUSPEND_ON:
+ cpu_do_idle();
+ break;
+
+ default:
+ pr_debug("AT91: PM - bogus suspend state %d\n", state);
+ goto error;
+ }
+
+ pr_debug("AT91: PM - wakeup %08x\n",
+ at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR));
+
+error:
+ target_state = PM_SUSPEND_ON;
+ at91_irq_resume();
+ at91_gpio_resume();
+ return 0;
+}
+
+/*
+ * Called right prior to thawing processes.
+ */
+static void at91_pm_end(void)
+{
+ target_state = PM_SUSPEND_ON;
+}
+
+
+static const struct platform_suspend_ops at91_pm_ops = {
+ .valid = at91_pm_valid_state,
+ .begin = at91_pm_begin,
+ .enter = at91_pm_enter,
+ .end = at91_pm_end,
+};
+
+static int __init at91_pm_init(void)
+{
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz);
+#endif
+
+ pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
+
+#ifdef CONFIG_ARCH_AT91RM9200
+ /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
+ at91_sys_write(AT91_SDRAMC_LPR, 0);
+#endif
+
+ suspend_set_ops(&at91_pm_ops);
+
+ show_reset_status();
+ return 0;
+}
+arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
new file mode 100644
index 00000000..ce9a2069
--- /dev/null
+++ b/arch/arm/mach-at91/pm.h
@@ -0,0 +1,107 @@
+#ifdef CONFIG_ARCH_AT91RM9200
+#include <mach/at91rm9200_mc.h>
+
+/*
+ * The AT91RM9200 goes into self-refresh mode with this command, and will
+ * terminate self-refresh automatically on the next SDRAM access.
+ *
+ * Self-refresh mode is exited as soon as a memory access is made, but we don't
+ * know for sure when that happens. However, we need to restore the low-power
+ * mode if it was enabled before going idle. Restoring low-power mode while
+ * still in self-refresh is "not recommended", but seems to work.
+ */
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+ u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+ at91_sys_write(AT91_SDRAMC_LPR, 0);
+ at91_sys_write(AT91_SDRAMC_SRR, 1);
+ return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \
+ : : "r" (0))
+
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9_ddrsdr.h>
+
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+ u32 saved_lpr, lpr;
+
+ saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+
+ lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+ return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() cpu_do_idle()
+
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
+
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
+ */
+static u32 saved_lpr1;
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+ /* Those tow values allow us to delay self-refresh activation
+ * to the maximum. */
+ u32 lpr0, lpr1;
+ u32 saved_lpr0;
+
+ saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
+ lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
+ lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+ saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+ lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
+ lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+ /* self-refresh mode now */
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
+
+ return saved_lpr0;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr0) \
+ do { \
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
+ } while (0)
+#define wait_for_interrupt_enable() cpu_do_idle()
+
+#else
+#include <mach/at91sam9_sdramc.h>
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+/*
+ * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
+ * handle those cases both here and in the Suspend-To-RAM support.
+ */
+#warning Assuming EB1 SDRAM controller is *NOT* used
+#endif
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+ u32 saved_lpr, lpr;
+
+ saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
+
+ lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
+ at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+ return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
+#define wait_for_interrupt_enable() cpu_do_idle()
+
+#endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
new file mode 100644
index 00000000..f7922a43
--- /dev/null
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -0,0 +1,326 @@
+/*
+ * arch/arm/mach-at91/pm_slow_clock.S
+ *
+ * Copyright (C) 2006 Savin Zlobec
+ *
+ * AT91SAM9 support:
+ * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <mach/hardware.h>
+#include <mach/at91_pmc.h>
+
+#if defined(CONFIG_ARCH_AT91RM9200)
+#include <mach/at91rm9200_mc.h>
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9_ddrsdr.h>
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
+#else
+#include <mach/at91sam9_sdramc.h>
+#endif
+
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+/*
+ * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
+ * handle those cases both here and in the Suspend-To-RAM support.
+ */
+#warning Assuming EB1 SDRAM controller is *NOT* used
+#endif
+
+/*
+ * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
+ * clock during suspend by adjusting its prescalar and divisor.
+ * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
+ * are errata regarding adjusting the prescalar and divisor.
+ */
+#undef SLOWDOWN_MASTER_CLOCK
+
+#define MCKRDY_TIMEOUT 1000
+#define MOSCRDY_TIMEOUT 1000
+#define PLLALOCK_TIMEOUT 1000
+#define PLLBLOCK_TIMEOUT 1000
+
+
+/*
+ * Wait until master clock is ready (after switching master clock source)
+ */
+ .macro wait_mckrdy
+ mov r4, #MCKRDY_TIMEOUT
+1: sub r4, r4, #1
+ cmp r4, #0
+ beq 2f
+ ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+ tst r3, #AT91_PMC_MCKRDY
+ beq 1b
+2:
+ .endm
+
+/*
+ * Wait until master oscillator has stabilized.
+ */
+ .macro wait_moscrdy
+ mov r4, #MOSCRDY_TIMEOUT
+1: sub r4, r4, #1
+ cmp r4, #0
+ beq 2f
+ ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+ tst r3, #AT91_PMC_MOSCS
+ beq 1b
+2:
+ .endm
+
+/*
+ * Wait until PLLA has locked.
+ */
+ .macro wait_pllalock
+ mov r4, #PLLALOCK_TIMEOUT
+1: sub r4, r4, #1
+ cmp r4, #0
+ beq 2f
+ ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+ tst r3, #AT91_PMC_LOCKA
+ beq 1b
+2:
+ .endm
+
+/*
+ * Wait until PLLB has locked.
+ */
+ .macro wait_pllblock
+ mov r4, #PLLBLOCK_TIMEOUT
+1: sub r4, r4, #1
+ cmp r4, #0
+ beq 2f
+ ldr r3, [r1, #(AT91_PMC_SR - AT91_PMC)]
+ tst r3, #AT91_PMC_LOCKB
+ beq 1b
+2:
+ .endm
+
+ .text
+
+ENTRY(at91_slow_clock)
+ /* Save registers on stack */
+ stmfd sp!, {r0 - r12, lr}
+
+ /*
+ * Register usage:
+ * R1 = Base address of AT91_PMC
+ * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
+ * R3 = temporary register
+ * R4 = temporary register
+ * R5 = Base address of second RAM Controller or 0 if not present
+ */
+ ldr r1, .at91_va_base_pmc
+ ldr r2, .at91_va_base_sdramc
+ ldr r5, .at91_va_base_ramc1
+
+ /* Drain write buffer */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4
+
+#ifdef CONFIG_ARCH_AT91RM9200
+ /* Put SDRAM in self-refresh mode */
+ mov r3, #1
+ str r3, [r2, #AT91_SDRAMC_SRR]
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
+
+ /* prepare for DDRAM self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, #AT91_DDRSDRC_LPCB
+ orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* figure out if we use the second ram controller */
+ cmp r5, #0
+ ldrne r4, [r5, #AT91_DDRSDRC_LPR]
+ strne r4, .saved_sam9_lpr1
+ bicne r4, #AT91_DDRSDRC_LPCB
+ orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* Enable DDRAM self-refresh mode */
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+ strne r4, [r5, #AT91_DDRSDRC_LPR]
+#else
+ /* Enable SDRAM self-refresh mode */
+ ldr r3, [r2, #AT91_SDRAMC_LPR]
+ str r3, .saved_sam9_lpr
+
+ bic r3, #AT91_SDRAMC_LPCB
+ orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_SDRAMC_LPR]
+#endif
+
+ /* Save Master clock setting */
+ ldr r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+ str r3, .saved_mckr
+
+ /*
+ * Set the Master clock source to slow clock
+ */
+ bic r3, r3, #AT91_PMC_CSS
+ str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+ wait_mckrdy
+
+#ifdef SLOWDOWN_MASTER_CLOCK
+ /*
+ * Set the Master Clock PRES and MDIV fields.
+ *
+ * See AT91RM9200 errata #27 and #28 for details.
+ */
+ mov r3, #0
+ str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+ wait_mckrdy
+#endif
+
+ /* Save PLLA setting and disable it */
+ ldr r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+ str r3, .saved_pllar
+
+ mov r3, #AT91_PMC_PLLCOUNT
+ orr r3, r3, #(1 << 29) /* bit 29 always set */
+ str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+
+ /* Save PLLB setting and disable it */
+ ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+ str r3, .saved_pllbr
+
+ mov r3, #AT91_PMC_PLLCOUNT
+ str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+
+ /* Turn off the main oscillator */
+ ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+ bic r3, r3, #AT91_PMC_MOSCEN
+ str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+
+ /* Wait for interrupt */
+ mcr p15, 0, r0, c7, c0, 4
+
+ /* Turn on the main oscillator */
+ ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+ orr r3, r3, #AT91_PMC_MOSCEN
+ str r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
+
+ wait_moscrdy
+
+ /* Restore PLLB setting */
+ ldr r3, .saved_pllbr
+ str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
+
+ tst r3, #(AT91_PMC_MUL & 0xff0000)
+ bne 1f
+ tst r3, #(AT91_PMC_MUL & ~0xff0000)
+ beq 2f
+1:
+ wait_pllblock
+2:
+
+ /* Restore PLLA setting */
+ ldr r3, .saved_pllar
+ str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
+
+ tst r3, #(AT91_PMC_MUL & 0xff0000)
+ bne 3f
+ tst r3, #(AT91_PMC_MUL & ~0xff0000)
+ beq 4f
+3:
+ wait_pllalock
+4:
+
+#ifdef SLOWDOWN_MASTER_CLOCK
+ /*
+ * First set PRES if it was not 0,
+ * than set CSS and MDIV fields.
+ *
+ * See AT91RM9200 errata #27 and #28 for details.
+ */
+ ldr r3, .saved_mckr
+ tst r3, #AT91_PMC_PRES
+ beq 2f
+ and r3, r3, #AT91_PMC_PRES
+ str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+ wait_mckrdy
+#endif
+
+ /*
+ * Restore master clock setting
+ */
+2: ldr r3, .saved_mckr
+ str r3, [r1, #(AT91_PMC_MCKR - AT91_PMC)]
+
+ wait_mckrdy
+
+#ifdef CONFIG_ARCH_AT91RM9200
+ /* Do nothing - self-refresh is automatically disabled. */
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
+ /* Restore LPR on AT91 with DDRAM */
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* if we use the second ram controller */
+ cmp r5, #0
+ ldrne r4, .saved_sam9_lpr1
+ strne r4, [r5, #AT91_DDRSDRC_LPR]
+
+#else
+ /* Restore LPR on AT91 with SDRAM */
+ ldr r3, .saved_sam9_lpr
+ str r3, [r2, #AT91_SDRAMC_LPR]
+#endif
+
+ /* Restore registers, and return */
+ ldmfd sp!, {r0 - r12, pc}
+
+
+.saved_mckr:
+ .word 0
+
+.saved_pllar:
+ .word 0
+
+.saved_pllbr:
+ .word 0
+
+.saved_sam9_lpr:
+ .word 0
+
+.saved_sam9_lpr1:
+ .word 0
+
+.at91_va_base_pmc:
+ .word AT91_VA_BASE_SYS + AT91_PMC
+
+#ifdef CONFIG_ARCH_AT91RM9200
+.at91_va_base_sdramc:
+ .word AT91_VA_BASE_SYS
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
+.at91_va_base_sdramc:
+ .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
+#else
+.at91_va_base_sdramc:
+ .word AT91_VA_BASE_SYS + AT91_SDRAMC0
+#endif
+
+.at91_va_base_ramc1:
+#if defined(CONFIG_ARCH_AT91SAM9G45)
+ .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
+#else
+ .word 0
+#endif
+
+ENTRY(at91_slow_clock_sz)
+ .word .-at91_slow_clock
diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c
new file mode 100644
index 00000000..5eab6aa6
--- /dev/null
+++ b/arch/arm/mach-at91/sam9_smc.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-at91/sam9_smc.c
+ *
+ * Copyright (C) 2008 Andrew Victor
+ *
+ * This program is free software; you can 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/io.h>
+
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+
+void __init sam9_smc_configure(int cs, struct sam9_smc_config* config)
+{
+ /* Setup register */
+ at91_sys_write(AT91_SMC_SETUP(cs),
+ AT91_SMC_NWESETUP_(config->nwe_setup)
+ | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup)
+ | AT91_SMC_NRDSETUP_(config->nrd_setup)
+ | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup)
+ );
+
+ /* Pulse register */
+ at91_sys_write(AT91_SMC_PULSE(cs),
+ AT91_SMC_NWEPULSE_(config->nwe_pulse)
+ | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse)
+ | AT91_SMC_NRDPULSE_(config->nrd_pulse)
+ | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse)
+ );
+
+ /* Cycle register */
+ at91_sys_write(AT91_SMC_CYCLE(cs),
+ AT91_SMC_NWECYCLE_(config->write_cycle)
+ | AT91_SMC_NRDCYCLE_(config->read_cycle)
+ );
+
+ /* Mode register */
+ at91_sys_write(AT91_SMC_MODE(cs),
+ config->mode
+ | AT91_SMC_TDF_(config->tdf_cycles)
+ );
+}
diff --git a/arch/arm/mach-at91/sam9_smc.h b/arch/arm/mach-at91/sam9_smc.h
new file mode 100644
index 00000000..bf72cfb3
--- /dev/null
+++ b/arch/arm/mach-at91/sam9_smc.h
@@ -0,0 +1,33 @@
+/*
+ * linux/arch/arm/mach-at91/sam9_smc.
+ *
+ * Copyright (C) 2008 Andrew Victor
+ *
+ * This program is free software; you can 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 sam9_smc_config {
+ /* Setup register */
+ u8 ncs_read_setup;
+ u8 nrd_setup;
+ u8 ncs_write_setup;
+ u8 nwe_setup;
+
+ /* Pulse register */
+ u8 ncs_read_pulse;
+ u8 nrd_pulse;
+ u8 ncs_write_pulse;
+ u8 nwe_pulse;
+
+ /* Cycle register */
+ u16 read_cycle;
+ u16 write_cycle;
+
+ /* Mode register */
+ u32 mode;
+ u8 tdf_cycles:4;
+};
+
+extern void __init sam9_smc_configure(int cs, struct sam9_smc_config* config);
diff --git a/arch/arm/mach-bcmring/Kconfig b/arch/arm/mach-bcmring/Kconfig
new file mode 100644
index 00000000..457b4384
--- /dev/null
+++ b/arch/arm/mach-bcmring/Kconfig
@@ -0,0 +1,21 @@
+choice
+ prompt "Processor selection in BCMRING family of devices"
+ depends on ARCH_BCMRING
+ default ARCH_BCM11107
+
+config ARCH_FPGA11107
+ bool "FPGA11107"
+
+config ARCH_BCM11107
+ bool "BCM11107"
+endchoice
+
+menu "BCMRING Options"
+ depends on ARCH_BCMRING
+
+config BCM_ZRELADDR
+ hex "Compressed ZREL ADDR"
+
+endmenu
+
+# source "drivers/char/bcmring/Kconfig"
diff --git a/arch/arm/mach-bcmring/Makefile b/arch/arm/mach-bcmring/Makefile
new file mode 100644
index 00000000..f8d9fced
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := arch.o mm.o irq.o clock.o core.o timer.o dma.o
+obj-y += csp/
diff --git a/arch/arm/mach-bcmring/Makefile.boot b/arch/arm/mach-bcmring/Makefile.boot
new file mode 100644
index 00000000..fb53b283
--- /dev/null
+++ b/arch/arm/mach-bcmring/Makefile.boot
@@ -0,0 +1,6 @@
+# Address where decompressor will be written and eventually executed.
+#
+# default to SDRAM
+zreladdr-y := $(CONFIG_BCM_ZRELADDR)
+params_phys-y := 0x00000800
+
diff --git a/arch/arm/mach-bcmring/arch.c b/arch/arm/mach-bcmring/arch.c
new file mode 100644
index 00000000..a604b9eb
--- /dev/null
+++ b/arch/arm/mach-bcmring/arch.c
@@ -0,0 +1,176 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/time.h>
+#include <asm/pmu.h>
+
+#include <asm/mach/arch.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <cfg_global.h>
+
+#include "core.h"
+
+HW_DECLARE_SPINLOCK(arch)
+HW_DECLARE_SPINLOCK(gpio)
+#if defined(CONFIG_DEBUG_SPINLOCK)
+ EXPORT_SYMBOL(bcmring_gpio_reg_lock);
+#endif
+
+/* sysctl */
+int bcmring_arch_warm_reboot; /* do a warm reboot on hard reset */
+
+static struct ctl_table_header *bcmring_sysctl_header;
+
+static struct ctl_table bcmring_sysctl_warm_reboot[] = {
+ {
+ .procname = "warm",
+ .data = &bcmring_arch_warm_reboot,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec},
+ {}
+};
+
+static struct ctl_table bcmring_sysctl_reboot[] = {
+ {
+ .procname = "reboot",
+ .mode = 0555,
+ .child = bcmring_sysctl_warm_reboot},
+ {}
+};
+
+static struct resource nand_resource[] = {
+ [0] = {
+ .start = MM_ADDR_IO_NAND,
+ .end = MM_ADDR_IO_NAND + 0x1000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device nand_device = {
+ .name = "bcm-nand",
+ .id = -1,
+ .resource = nand_resource,
+ .num_resources = ARRAY_SIZE(nand_resource),
+};
+
+static struct resource pmu_resource = {
+ .start = IRQ_PMUIRQ,
+ .end = IRQ_PMUIRQ,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .resource = &pmu_resource,
+ .num_resources = 1,
+};
+
+
+static struct platform_device *devices[] __initdata = {
+ &nand_device,
+ &pmu_device,
+};
+
+/****************************************************************************
+*
+* Called from the customize_machine function in arch/arm/kernel/setup.c
+*
+* The customize_machine function is tagged as an arch_initcall
+* (see include/linux/init.h for the order that the various init sections
+* are called in.
+*
+*****************************************************************************/
+static void __init bcmring_init_machine(void)
+{
+
+ bcmring_sysctl_header = register_sysctl_table(bcmring_sysctl_reboot);
+
+ /* Enable spread spectrum */
+ chipcHw_enableSpreadSpectrum();
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ bcmring_amba_init();
+
+ dma_init();
+}
+
+/****************************************************************************
+*
+* Called from setup_arch (in arch/arm/kernel/setup.c) to fixup any tags
+* passed in by the boot loader.
+*
+*****************************************************************************/
+
+static void __init bcmring_fixup(struct machine_desc *desc,
+ struct tag *t, char **cmdline, struct meminfo *mi) {
+#ifdef CONFIG_BLK_DEV_INITRD
+ printk(KERN_NOTICE "bcmring_fixup\n");
+ t->hdr.tag = ATAG_CORE;
+ t->hdr.size = tag_size(tag_core);
+ t->u.core.flags = 0;
+ t->u.core.pagesize = PAGE_SIZE;
+ t->u.core.rootdev = 31 << 8 | 0;
+ t = tag_next(t);
+
+ t->hdr.tag = ATAG_MEM;
+ t->hdr.size = tag_size(tag_mem32);
+ t->u.mem.start = CFG_GLOBAL_RAM_BASE;
+ t->u.mem.size = CFG_GLOBAL_RAM_SIZE;
+
+ t = tag_next(t);
+
+ t->hdr.tag = ATAG_NONE;
+ t->hdr.size = 0;
+#endif
+}
+
+/****************************************************************************
+*
+* Machine Description
+*
+*****************************************************************************/
+
+MACHINE_START(BCMRING, "BCMRING")
+ /* Maintainer: Broadcom Corporation */
+ .fixup = bcmring_fixup,
+ .map_io = bcmring_map_io,
+ .init_early = bcmring_init_early,
+ .init_irq = bcmring_init_irq,
+ .timer = &bcmring_timer,
+ .init_machine = bcmring_init_machine
+MACHINE_END
diff --git a/arch/arm/mach-bcmring/clock.c b/arch/arm/mach-bcmring/clock.c
new file mode 100644
index 00000000..ad237a42
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.c
@@ -0,0 +1,223 @@
+/*****************************************************************************
+* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/clkdev.h>
+#include <mach/csp/hw_cfg.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_reg.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include "clock.h"
+
+#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY)
+#define clk_is_pll1(x) ((x)->type & CLK_TYPE_PLL1)
+#define clk_is_pll2(x) ((x)->type & CLK_TYPE_PLL2)
+#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE)
+#define clk_is_bypassable(x) ((x)->type & CLK_TYPE_BYPASSABLE)
+
+#define clk_is_using_xtal(x) ((x)->mode & CLK_MODE_XTAL)
+
+static DEFINE_SPINLOCK(clk_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ /* enable parent clock first */
+ if (clk->parent)
+ __clk_enable(clk->parent);
+
+ if (clk->use_cnt++ == 0) {
+ if (clk_is_pll1(clk)) { /* PLL1 */
+ chipcHw_pll1Enable(clk->rate_hz, 0);
+ } else if (clk_is_pll2(clk)) { /* PLL2 */
+ chipcHw_pll2Enable(clk->rate_hz);
+ } else if (clk_is_using_xtal(clk)) { /* source is crystal */
+ if (!clk_is_primary(clk))
+ chipcHw_bypassClockEnable(clk->csp_id);
+ } else { /* source is PLL */
+ chipcHw_setClockEnable(clk->csp_id);
+ }
+ }
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (!clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ BUG_ON(clk->use_cnt == 0);
+
+ if (--clk->use_cnt == 0) {
+ if (clk_is_pll1(clk)) { /* PLL1 */
+ chipcHw_pll1Disable();
+ } else if (clk_is_pll2(clk)) { /* PLL2 */
+ chipcHw_pll2Disable();
+ } else if (clk_is_using_xtal(clk)) { /* source is crystal */
+ if (!clk_is_primary(clk))
+ chipcHw_bypassClockDisable(clk->csp_id);
+ } else { /* source is PLL */
+ chipcHw_setClockDisable(clk->csp_id);
+ }
+ }
+
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (!clk)
+ return;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0;
+
+ return clk->rate_hz;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ unsigned long actual;
+ unsigned long rate_hz;
+
+ if (!clk)
+ return -EINVAL;
+
+ if (!clk_is_programmable(clk))
+ return -EINVAL;
+
+ if (clk->use_cnt)
+ return -EBUSY;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ actual = clk->parent->rate_hz;
+ rate_hz = min(actual, rate);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return rate_hz;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ unsigned long actual;
+ unsigned long rate_hz;
+
+ if (!clk)
+ return -EINVAL;
+
+ if (!clk_is_programmable(clk))
+ return -EINVAL;
+
+ if (clk->use_cnt)
+ return -EBUSY;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ actual = clk->parent->rate_hz;
+ rate_hz = min(actual, rate);
+ rate_hz = chipcHw_setClockFrequency(clk->csp_id, rate_hz);
+ clk->rate_hz = rate_hz;
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+ struct clk *old_parent;
+
+ if (!clk || !parent)
+ return -EINVAL;
+
+ if (!clk_is_primary(parent) || !clk_is_bypassable(clk))
+ return -EINVAL;
+
+ /* if more than one user, parent is not allowed */
+ if (clk->use_cnt > 1)
+ return -EBUSY;
+
+ if (clk->parent == parent)
+ return 0;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ old_parent = clk->parent;
+ clk->parent = parent;
+ if (clk_is_using_xtal(parent))
+ clk->mode |= CLK_MODE_XTAL;
+ else
+ clk->mode &= (~CLK_MODE_XTAL);
+
+ /* if clock is active */
+ if (clk->use_cnt != 0) {
+ clk->use_cnt--;
+ /* enable clock with the new parent */
+ __clk_enable(clk);
+ /* disable the old parent */
+ __clk_disable(old_parent);
+ }
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
diff --git a/arch/arm/mach-bcmring/clock.h b/arch/arm/mach-bcmring/clock.h
new file mode 100644
index 00000000..5e0b9813
--- /dev/null
+++ b/arch/arm/mach-bcmring/clock.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+* Copyright 2001 - 2009 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+#include <mach/csp/chipcHw_def.h>
+
+#define CLK_TYPE_PRIMARY 1 /* primary clock must NOT have a parent */
+#define CLK_TYPE_PLL1 2 /* PPL1 */
+#define CLK_TYPE_PLL2 4 /* PPL2 */
+#define CLK_TYPE_PROGRAMMABLE 8 /* programmable clock rate */
+#define CLK_TYPE_BYPASSABLE 16 /* parent can be changed */
+
+#define CLK_MODE_XTAL 1 /* clock source is from crystal */
+
+struct clk {
+ const char *name; /* clock name */
+ unsigned int type; /* clock type */
+ unsigned int mode; /* current mode */
+ volatile int use_bypass; /* indicate if it's in bypass mode */
+ chipcHw_CLOCK_e csp_id; /* clock ID for CSP CHIPC */
+ unsigned long rate_hz; /* clock rate in Hz */
+ unsigned int use_cnt; /* usage count */
+ struct clk *parent; /* parent clock */
+};
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
new file mode 100644
index 00000000..43eadbcc
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.c
@@ -0,0 +1,248 @@
+/*
+ * derived from linux/arch/arm/mach-versatile/core.c
+ * linux/arch/arm/mach-bcmring/core.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+/* Portions copyright Broadcom 2008 */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/clkdev.h>
+
+#include <mach/csp/mm_addr.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <cfg_global.h>
+
+#include "clock.h"
+
+#include <csp/secHw.h>
+#include <mach/csp/secHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+#include <mach/csp/tmrHw_reg.h>
+
+#define AMBA_DEVICE(name, initname, base, plat, size) \
+static struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0, \
+ .init_name = initname, \
+ .platform_data = plat \
+ }, \
+ .res = { \
+ .start = MM_ADDR_IO_##base, \
+ .end = MM_ADDR_IO_##base + (size) - 1, \
+ .flags = IORESOURCE_MEM \
+ }, \
+ .dma_mask = ~0, \
+ .irq = { \
+ IRQ_##base \
+ } \
+}
+
+
+AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
+AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
+
+static struct clk pll1_clk = {
+ .name = "PLL1",
+ .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL1,
+ .rate_hz = 2000000000,
+ .use_cnt = 7,
+};
+
+static struct clk uart_clk = {
+ .name = "UART",
+ .type = CLK_TYPE_PROGRAMMABLE,
+ .csp_id = chipcHw_CLOCK_UART,
+ .rate_hz = HW_CFG_UART_CLK_HZ,
+ .parent = &pll1_clk,
+};
+
+static struct clk dummy_apb_pclk = {
+ .name = "BUSCLK",
+ .type = CLK_TYPE_PRIMARY,
+ .mode = CLK_MODE_XTAL,
+};
+
+/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically 150-166 MHz */
+#if defined(CONFIG_ARCH_FPGA11107)
+/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
+/* slow down Linux's sense of time */
+#define TIMER0_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER1_FREQUENCY_MHZ (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_MHZ (tmrHw_HIGH_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
+#else
+#define TIMER0_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER1_FREQUENCY_MHZ tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_MHZ tmrHw_HIGH_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_KHZ (tmrHw_HIGH_FREQUENCY_HZ / 1000)
+#endif
+
+static struct clk sp804_timer012_clk = {
+ .name = "sp804-timer-0,1,2",
+ .type = CLK_TYPE_PRIMARY,
+ .mode = CLK_MODE_XTAL,
+ .rate_hz = TIMER1_FREQUENCY_MHZ * 1000000,
+};
+
+static struct clk sp804_timer3_clk = {
+ .name = "sp804-timer-3",
+ .type = CLK_TYPE_PRIMARY,
+ .mode = CLK_MODE_XTAL,
+ .rate_hz = TIMER3_FREQUENCY_KHZ * 1000,
+};
+
+static struct clk_lookup lookups[] = {
+ { /* Bus clock */
+ .con_id = "apb_pclk",
+ .clk = &dummy_apb_pclk,
+ }, { /* UART0 */
+ .dev_id = "uarta",
+ .clk = &uart_clk,
+ }, { /* UART1 */
+ .dev_id = "uartb",
+ .clk = &uart_clk,
+ }, { /* SP804 timer 0 */
+ .dev_id = "sp804",
+ .con_id = "timer0",
+ .clk = &sp804_timer012_clk,
+ }, { /* SP804 timer 1 */
+ .dev_id = "sp804",
+ .con_id = "timer1",
+ .clk = &sp804_timer012_clk,
+ }, { /* SP804 timer 3 */
+ .dev_id = "sp804",
+ .con_id = "timer3",
+ .clk = &sp804_timer3_clk,
+ }
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &uartA_device,
+ &uartB_device,
+};
+
+void __init bcmring_amba_init(void)
+{
+ int i;
+ u32 bus_clock;
+
+/* Linux is run initially in non-secure mode. Secure peripherals */
+/* generate FIQ, and must be handled in secure mode. Until we have */
+/* a linux security monitor implementation, keep everything in */
+/* non-secure mode. */
+ chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_SPU);
+ secHw_setUnsecure(secHw_BLK_MASK_CHIP_CONTROL |
+ secHw_BLK_MASK_KEY_SCAN |
+ secHw_BLK_MASK_TOUCH_SCREEN |
+ secHw_BLK_MASK_UART0 |
+ secHw_BLK_MASK_UART1 |
+ secHw_BLK_MASK_WATCHDOG |
+ secHw_BLK_MASK_SPUM |
+ secHw_BLK_MASK_DDR2 |
+ secHw_BLK_MASK_SPU |
+ secHw_BLK_MASK_PKA |
+ secHw_BLK_MASK_RNG |
+ secHw_BLK_MASK_RTC |
+ secHw_BLK_MASK_OTP |
+ secHw_BLK_MASK_BOOT |
+ secHw_BLK_MASK_MPU |
+ secHw_BLK_MASK_TZCTRL | secHw_BLK_MASK_INTR);
+
+ /* Only the devices attached to the AMBA bus are enabled just before the bus is */
+ /* scanned and the drivers are loaded. The clocks need to be on for the AMBA bus */
+ /* driver to access these blocks. The bus is probed, and the drivers are loaded. */
+ /* FIXME Need to remove enable of PIF once CLCD clock enable used properly in FPGA. */
+ bus_clock = chipcHw_REG_BUS_CLOCK_GE
+ | chipcHw_REG_BUS_CLOCK_SDIO0 | chipcHw_REG_BUS_CLOCK_SDIO1;
+
+ chipcHw_busInterfaceClockEnable(bus_clock);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+}
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE ((void __iomem *)MM_IO_BASE_TMR)
+#define TIMER1_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x20))
+#define TIMER2_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x40))
+#define TIMER3_VA_BASE ((void __iomem *)(MM_IO_BASE_TMR + 0x60))
+
+static int __init bcmring_clocksource_init(void)
+{
+ /* setup timer1 as free-running clocksource */
+ sp804_clocksource_init(TIMER1_VA_BASE, "timer1");
+
+ /* setup timer3 as free-running clocksource */
+ sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
+
+ return 0;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init bcmring_init_timer(void)
+{
+ printk(KERN_INFO "bcmring_init_timer\n");
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ bcmring_clocksource_init();
+
+ sp804_clockevents_register(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
+}
+
+struct sys_timer bcmring_timer = {
+ .init = bcmring_init_timer,
+};
+
+void __init bcmring_init_early(void)
+{
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
diff --git a/arch/arm/mach-bcmring/core.h b/arch/arm/mach-bcmring/core.h
new file mode 100644
index 00000000..e0e02c48
--- /dev/null
+++ b/arch/arm/mach-bcmring/core.h
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-versatile/core.h
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+/* Portions copyright Broadcom 2008 */
+#ifndef __ASM_ARCH_BCMRING_H
+#define __ASM_ARCH_BCMRING_H
+
+void __init bcmring_amba_init(void);
+void __init bcmring_map_io(void);
+void __init bcmring_init_irq(void);
+void __init bcmring_init_early(void);
+
+extern struct sys_timer bcmring_timer;
+#endif
diff --git a/arch/arm/mach-bcmring/csp/Makefile b/arch/arm/mach-bcmring/csp/Makefile
new file mode 100644
index 00000000..648c0377
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/Makefile
@@ -0,0 +1,3 @@
+obj-y += dmac/
+obj-y += tmr/
+obj-y += chipc/
diff --git a/arch/arm/mach-bcmring/csp/chipc/Makefile b/arch/arm/mach-bcmring/csp/chipc/Makefile
new file mode 100644
index 00000000..67395276
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/Makefile
@@ -0,0 +1 @@
+obj-y += chipcHw.o chipcHw_str.o chipcHw_reset.o chipcHw_init.o
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
new file mode 100644
index 00000000..96273ff3
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c
@@ -0,0 +1,776 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file chipcHw.c
+*
+* @brief Low level Various CHIP clock controlling routines
+*
+* @note
+*
+* These routines provide basic clock controlling functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+#include <csp/module.h>
+
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <csp/reg.h>
+#include <csp/delay.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+
+/* VPM alignment algorithm uses this */
+#define MAX_PHASE_ADJUST_COUNT 0xFFFF /* Max number of times allowed to adjust the phase */
+#define MAX_PHASE_ALIGN_ATTEMPTS 10 /* Max number of attempt to align the phase */
+
+/* Local definition of clock type */
+#define PLL_CLOCK 1 /* PLL Clock */
+#define NON_PLL_CLOCK 2 /* Divider clock */
+
+static int chipcHw_divide(int num, int denom)
+ __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Set clock fequency for miscellaneous configurable clocks
+*
+* This function sets clock frequency
+*
+* @return Configured clock frequency in hertz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ ) {
+ volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+ volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+ volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
+ uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
+ uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
+ uint32_t dependentClockType = 0;
+ uint32_t vcoHz = 0;
+
+ /* Get VCO frequencies */
+ if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+ uint64_t adjustFreq = 0;
+
+ vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+ /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
+ adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
+ (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
+ vcoFreqPll1Hz += (uint32_t) adjustFreq;
+ } else {
+ vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+ }
+ vcoFreqPll2Hz =
+ chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+ switch (clock) {
+ case chipcHw_CLOCK_DDR:
+ pPLLReg = &pChipcHw->DDRClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ARM:
+ pPLLReg = &pChipcHw->ARMClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ESW:
+ pPLLReg = &pChipcHw->ESWClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_VPM:
+ pPLLReg = &pChipcHw->VPMClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ESW125:
+ pPLLReg = &pChipcHw->ESW125Clock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_UART:
+ pPLLReg = &pChipcHw->UARTClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SDIO0:
+ pPLLReg = &pChipcHw->SDIO0Clock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SDIO1:
+ pPLLReg = &pChipcHw->SDIO1Clock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SPI:
+ pPLLReg = &pChipcHw->SPIClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ETM:
+ pPLLReg = &pChipcHw->ETMClock;
+ vcoHz = vcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_USB:
+ pPLLReg = &pChipcHw->USBClock;
+ vcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_LCD:
+ pPLLReg = &pChipcHw->LCDClock;
+ vcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_APM:
+ pPLLReg = &pChipcHw->APMClock;
+ vcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_BUS:
+ pClockCtrl = &pChipcHw->ACLKClock;
+ pDependentClock = &pChipcHw->ARMClock;
+ vcoHz = vcoFreqPll1Hz;
+ dependentClockType = PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_OTP:
+ pClockCtrl = &pChipcHw->OTPClock;
+ break;
+ case chipcHw_CLOCK_I2C:
+ pClockCtrl = &pChipcHw->I2CClock;
+ break;
+ case chipcHw_CLOCK_I2S0:
+ pClockCtrl = &pChipcHw->I2S0Clock;
+ break;
+ case chipcHw_CLOCK_RTBUS:
+ pClockCtrl = &pChipcHw->RTBUSClock;
+ pDependentClock = &pChipcHw->ACLKClock;
+ dependentClockType = NON_PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_APM100:
+ pClockCtrl = &pChipcHw->APM100Clock;
+ pDependentClock = &pChipcHw->APMClock;
+ vcoHz = vcoFreqPll2Hz;
+ dependentClockType = PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_TSC:
+ pClockCtrl = &pChipcHw->TSCClock;
+ break;
+ case chipcHw_CLOCK_LED:
+ pClockCtrl = &pChipcHw->LEDClock;
+ break;
+ case chipcHw_CLOCK_I2S1:
+ pClockCtrl = &pChipcHw->I2S1Clock;
+ break;
+ }
+
+ if (pPLLReg) {
+ /* Obtain PLL clock frequency */
+ if (*pPLLReg & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
+ /* Return crystal clock frequency when bypassed */
+ return chipcHw_XTAL_FREQ_Hz;
+ } else if (clock == chipcHw_CLOCK_DDR) {
+ /* DDR frequency is configured in PLLDivider register */
+ return chipcHw_divide (vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
+ } else {
+ /* From chip revision number B0, LCD clock is internally divided by 2 */
+ if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
+ vcoHz >>= 1;
+ }
+ /* Obtain PLL clock frequency using VCO dividers */
+ return chipcHw_divide(vcoHz, ((*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*pPLLReg & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
+ }
+ } else if (pClockCtrl) {
+ /* Obtain divider clock frequency */
+ uint32_t div;
+ uint32_t freq = 0;
+
+ if (*pClockCtrl & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
+ /* Return crystal clock frequency when bypassed */
+ return chipcHw_XTAL_FREQ_Hz;
+ } else if (pDependentClock) {
+ /* Identify the dependent clock frequency */
+ switch (dependentClockType) {
+ case PLL_CLOCK:
+ if (*pDependentClock & chipcHw_REG_PLL_CLOCK_BYPASS_SELECT) {
+ /* Use crystal clock frequency when dependent PLL clock is bypassed */
+ freq = chipcHw_XTAL_FREQ_Hz;
+ } else {
+ /* Obtain PLL clock frequency using VCO dividers */
+ div = *pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK;
+ freq = div ? chipcHw_divide(vcoHz, div) : 0;
+ }
+ break;
+ case NON_PLL_CLOCK:
+ if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
+ freq = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
+ } else {
+ if (*pDependentClock & chipcHw_REG_DIV_CLOCK_BYPASS_SELECT) {
+ /* Use crystal clock frequency when dependent divider clock is bypassed */
+ freq = chipcHw_XTAL_FREQ_Hz;
+ } else {
+ /* Obtain divider clock frequency using XTAL dividers */
+ div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+ freq = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, (div ? div : 256));
+ }
+ }
+ break;
+ }
+ } else {
+ /* Dependent on crystal clock */
+ freq = chipcHw_XTAL_FREQ_Hz;
+ }
+
+ div = *pClockCtrl & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+ return chipcHw_divide(freq, (div ? div : 256));
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Set clock fequency for miscellaneous configurable clocks
+*
+* This function sets clock frequency
+*
+* @return Configured clock frequency in Hz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */
+ uint32_t freq /* [ IN ] Clock frequency in Hz */
+ ) {
+ volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+ volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+ volatile uint32_t *pDependentClock = (uint32_t *) 0x0;
+ uint32_t vcoFreqPll1Hz = 0; /* Effective VCO frequency for PLL1 in Hz */
+ uint32_t desVcoFreqPll1Hz = 0; /* Desired VCO frequency for PLL1 in Hz */
+ uint32_t vcoFreqPll2Hz = 0; /* Effective VCO frequency for PLL2 in Hz */
+ uint32_t dependentClockType = 0;
+ uint32_t vcoHz = 0;
+ uint32_t desVcoHz = 0;
+
+ /* Get VCO frequencies */
+ if ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) != chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+ uint64_t adjustFreq = 0;
+
+ vcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+ /* Adjusted frequency due to chipcHw_REG_PLL_DIVIDER_NDIV_f_SS */
+ adjustFreq = (uint64_t) chipcHw_XTAL_FREQ_Hz *
+ (uint64_t) chipcHw_REG_PLL_DIVIDER_NDIV_f_SS *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, (chipcHw_REG_PLL_PREDIVIDER_P2 * (uint64_t) chipcHw_REG_PLL_DIVIDER_FRAC));
+ vcoFreqPll1Hz += (uint32_t) adjustFreq;
+
+ /* Desired VCO frequency */
+ desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ (((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) + 1);
+ } else {
+ vcoFreqPll1Hz = desVcoFreqPll1Hz = chipcHw_XTAL_FREQ_Hz *
+ chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+ }
+ vcoFreqPll2Hz = chipcHw_XTAL_FREQ_Hz * chipcHw_divide(chipcHw_REG_PLL_PREDIVIDER_P1, chipcHw_REG_PLL_PREDIVIDER_P2) *
+ ((pChipcHw->PLLPreDivider2 & chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK) >>
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT);
+
+ switch (clock) {
+ case chipcHw_CLOCK_DDR:
+ /* Configure the DDR_ctrl:BUS ratio settings */
+ {
+ REG_LOCAL_IRQ_SAVE;
+ /* Dvide DDR_phy by two to obtain DDR_ctrl clock */
+ pChipcHw->DDRClock = (pChipcHw->DDRClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((((freq / 2) / chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
+ << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
+ REG_LOCAL_IRQ_RESTORE;
+ }
+ pPLLReg = &pChipcHw->DDRClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ARM:
+ pPLLReg = &pChipcHw->ARMClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ESW:
+ pPLLReg = &pChipcHw->ESWClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_VPM:
+ /* Configure the VPM:BUS ratio settings */
+ {
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK) | ((chipcHw_divide (freq, chipcHw_getClockFrequency(chipcHw_CLOCK_BUS)) - 1)
+ << chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT);
+ REG_LOCAL_IRQ_RESTORE;
+ }
+ pPLLReg = &pChipcHw->VPMClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ESW125:
+ pPLLReg = &pChipcHw->ESW125Clock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_UART:
+ pPLLReg = &pChipcHw->UARTClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SDIO0:
+ pPLLReg = &pChipcHw->SDIO0Clock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SDIO1:
+ pPLLReg = &pChipcHw->SDIO1Clock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_SPI:
+ pPLLReg = &pChipcHw->SPIClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_ETM:
+ pPLLReg = &pChipcHw->ETMClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ break;
+ case chipcHw_CLOCK_USB:
+ pPLLReg = &pChipcHw->USBClock;
+ vcoHz = vcoFreqPll2Hz;
+ desVcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_LCD:
+ pPLLReg = &pChipcHw->LCDClock;
+ vcoHz = vcoFreqPll2Hz;
+ desVcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_APM:
+ pPLLReg = &pChipcHw->APMClock;
+ vcoHz = vcoFreqPll2Hz;
+ desVcoHz = vcoFreqPll2Hz;
+ break;
+ case chipcHw_CLOCK_BUS:
+ pClockCtrl = &pChipcHw->ACLKClock;
+ pDependentClock = &pChipcHw->ARMClock;
+ vcoHz = vcoFreqPll1Hz;
+ desVcoHz = desVcoFreqPll1Hz;
+ dependentClockType = PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_OTP:
+ pClockCtrl = &pChipcHw->OTPClock;
+ break;
+ case chipcHw_CLOCK_I2C:
+ pClockCtrl = &pChipcHw->I2CClock;
+ break;
+ case chipcHw_CLOCK_I2S0:
+ pClockCtrl = &pChipcHw->I2S0Clock;
+ break;
+ case chipcHw_CLOCK_RTBUS:
+ pClockCtrl = &pChipcHw->RTBUSClock;
+ pDependentClock = &pChipcHw->ACLKClock;
+ dependentClockType = NON_PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_APM100:
+ pClockCtrl = &pChipcHw->APM100Clock;
+ pDependentClock = &pChipcHw->APMClock;
+ vcoHz = vcoFreqPll2Hz;
+ desVcoHz = vcoFreqPll2Hz;
+ dependentClockType = PLL_CLOCK;
+ break;
+ case chipcHw_CLOCK_TSC:
+ pClockCtrl = &pChipcHw->TSCClock;
+ break;
+ case chipcHw_CLOCK_LED:
+ pClockCtrl = &pChipcHw->LEDClock;
+ break;
+ case chipcHw_CLOCK_I2S1:
+ pClockCtrl = &pChipcHw->I2S1Clock;
+ break;
+ }
+
+ if (pPLLReg) {
+ /* Select XTAL as bypass source */
+ reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_SOURCE_GPIO);
+ reg32_modify_or(pPLLReg, chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+ /* For DDR settings use only the PLL divider clock */
+ if (pPLLReg == &pChipcHw->DDRClock) {
+ /* Set M1DIV for PLL1, which controls the DDR clock */
+ reg32_write(&pChipcHw->PLLDivider, (pChipcHw->PLLDivider & 0x00FFFFFF) | ((chipcHw_REG_PLL_DIVIDER_MDIV (desVcoHz, freq)) << 24));
+ /* Calculate expected frequency */
+ freq = chipcHw_divide(vcoHz, (((pChipcHw->PLLDivider & 0xFF000000) >> 24) ? ((pChipcHw->PLLDivider & 0xFF000000) >> 24) : 256));
+ } else {
+ /* From chip revision number B0, LCD clock is internally divided by 2 */
+ if ((pPLLReg == &pChipcHw->LCDClock) && (chipcHw_getChipRevisionNumber() != chipcHw_REV_NUMBER_A0)) {
+ desVcoHz >>= 1;
+ vcoHz >>= 1;
+ }
+ /* Set MDIV to change the frequency */
+ reg32_modify_and(pPLLReg, ~(chipcHw_REG_PLL_CLOCK_MDIV_MASK));
+ reg32_modify_or(pPLLReg, chipcHw_REG_PLL_DIVIDER_MDIV(desVcoHz, freq));
+ /* Calculate expected frequency */
+ freq = chipcHw_divide(vcoHz, ((*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) ? (*(pPLLReg) & chipcHw_REG_PLL_CLOCK_MDIV_MASK) : 256));
+ }
+ /* Wait for for atleast 200ns as per the protocol to change frequency */
+ udelay(1);
+ /* Do not bypass */
+ reg32_modify_and(pPLLReg, ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+ /* Return the configured frequency */
+ return freq;
+ } else if (pClockCtrl) {
+ uint32_t divider = 0;
+
+ /* Divider clock should not be bypassed */
+ reg32_modify_and(pClockCtrl,
+ ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+
+ /* Identify the clock source */
+ if (pDependentClock) {
+ switch (dependentClockType) {
+ case PLL_CLOCK:
+ divider = chipcHw_divide(chipcHw_divide (desVcoHz, (*pDependentClock & chipcHw_REG_PLL_CLOCK_MDIV_MASK)), freq);
+ break;
+ case NON_PLL_CLOCK:
+ {
+ uint32_t sourceClock = 0;
+
+ if (pDependentClock == (uint32_t *) &pChipcHw->ACLKClock) {
+ sourceClock = chipcHw_getClockFrequency (chipcHw_CLOCK_BUS);
+ } else {
+ uint32_t div = *pDependentClock & chipcHw_REG_DIV_CLOCK_DIV_MASK;
+ sourceClock = chipcHw_divide (chipcHw_XTAL_FREQ_Hz, ((div) ? div : 256));
+ }
+ divider = chipcHw_divide(sourceClock, freq);
+ }
+ break;
+ }
+ } else {
+ divider = chipcHw_divide(chipcHw_XTAL_FREQ_Hz, freq);
+ }
+
+ if (divider) {
+ REG_LOCAL_IRQ_SAVE;
+ /* Set the divider to obtain the required frequency */
+ *pClockCtrl = (*pClockCtrl & (~chipcHw_REG_DIV_CLOCK_DIV_MASK)) | (((divider > 256) ? chipcHw_REG_DIV_CLOCK_DIV_256 : divider) & chipcHw_REG_DIV_CLOCK_DIV_MASK);
+ REG_LOCAL_IRQ_RESTORE;
+ return freq;
+ }
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(chipcHw_setClockFrequency);
+
+/****************************************************************************/
+/**
+* @brief Set VPM clock in sync with BUS clock for Chip Rev #A0
+*
+* This function does the phase adjustment between VPM and BUS clock
+*
+* @return >= 0 : On success (# of adjustment required)
+* -1 : On failure
+*
+*/
+/****************************************************************************/
+static int vpmPhaseAlignA0(void)
+{
+ uint32_t phaseControl;
+ uint32_t phaseValue;
+ uint32_t prevPhaseComp;
+ int iter = 0;
+ int adjustCount = 0;
+ int count = 0;
+
+ for (iter = 0; (iter < MAX_PHASE_ALIGN_ATTEMPTS) && (adjustCount < MAX_PHASE_ADJUST_COUNT); iter++) {
+ phaseControl = (pChipcHw->VPMClock & chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT;
+ phaseValue = 0;
+ prevPhaseComp = 0;
+
+ /* Step 1: Look for falling PH_COMP transition */
+
+ /* Read the contents of VPM Clock resgister */
+ phaseValue = pChipcHw->VPMClock;
+ do {
+ /* Store previous value of phase comparator */
+ prevPhaseComp = phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP;
+ /* Change the value of PH_CTRL. */
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ /* Read the contents of VPM Clock resgister. */
+ phaseValue = pChipcHw->VPMClock;
+
+ if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
+ phaseControl = (0x3F & (phaseControl - 1));
+ } else {
+ /* Increment to the Phase count value for next write, if Phase is not stable. */
+ phaseControl = (0x3F & (phaseControl + 1));
+ }
+ /* Count number of adjustment made */
+ adjustCount++;
+ } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || /* Look for a transition */
+ ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && /* Look for a falling edge */
+ (adjustCount < MAX_PHASE_ADJUST_COUNT) /* Do not exceed the limit while trying */
+ );
+
+ if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+ /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+ return -1;
+ }
+
+ /* Step 2: Keep moving forward to make sure falling PH_COMP transition was valid */
+
+ for (count = 0; (count < 5) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
+ phaseControl = (0x3F & (phaseControl + 1));
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ phaseValue = pChipcHw->VPMClock;
+ /* Count number of adjustment made */
+ adjustCount++;
+ }
+
+ if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+ /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+ return -1;
+ }
+
+ if (count != 5) {
+ /* Detected false transition */
+ continue;
+ }
+
+ /* Step 3: Keep moving backward to make sure falling PH_COMP transition was stable */
+
+ for (count = 0; (count < 3) && ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0); count++) {
+ phaseControl = (0x3F & (phaseControl - 1));
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ phaseValue = pChipcHw->VPMClock;
+ /* Count number of adjustment made */
+ adjustCount++;
+ }
+
+ if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+ /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+ return -1;
+ }
+
+ if (count != 3) {
+ /* Detected noisy transition */
+ continue;
+ }
+
+ /* Step 4: Keep moving backward before the original transition took place. */
+
+ for (count = 0; (count < 5); count++) {
+ phaseControl = (0x3F & (phaseControl - 1));
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ phaseValue = pChipcHw->VPMClock;
+ /* Count number of adjustment made */
+ adjustCount++;
+ }
+
+ if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+ /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+ return -1;
+ }
+
+ if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0) {
+ /* Detected false transition */
+ continue;
+ }
+
+ /* Step 5: Re discover the valid transition */
+
+ do {
+ /* Store previous value of phase comparator */
+ prevPhaseComp = phaseValue;
+ /* Change the value of PH_CTRL. */
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^=
+ chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ /* Read the contents of VPM Clock resgister. */
+ phaseValue = pChipcHw->VPMClock;
+
+ if ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) == 0x0) {
+ phaseControl = (0x3F & (phaseControl - 1));
+ } else {
+ /* Increment to the Phase count value for next write, if Phase is not stable. */
+ phaseControl = (0x3F & (phaseControl + 1));
+ }
+
+ /* Count number of adjustment made */
+ adjustCount++;
+ } while (((prevPhaseComp == (phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP)) || ((phaseValue & chipcHw_REG_PLL_CLOCK_PHASE_COMP) != 0x0)) && (adjustCount < MAX_PHASE_ADJUST_COUNT));
+
+ if (adjustCount >= MAX_PHASE_ADJUST_COUNT) {
+ /* Failed to align VPM phase after MAX_PHASE_ADJUST_COUNT tries */
+ return -1;
+ } else {
+ /* Valid phase must have detected */
+ break;
+ }
+ }
+
+ /* For VPM Phase should be perfectly aligned. */
+ phaseControl = (((pChipcHw->VPMClock >> chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT) - 1) & 0x3F);
+ {
+ REG_LOCAL_IRQ_SAVE;
+
+ pChipcHw->VPMClock = (pChipcHw->VPMClock & ~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT);
+ /* Load new phase value */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+
+ REG_LOCAL_IRQ_RESTORE;
+ }
+ /* Return the status */
+ return (int)adjustCount;
+}
+
+/****************************************************************************/
+/**
+* @brief Set VPM clock in sync with BUS clock
+*
+* This function does the phase adjustment between VPM and BUS clock
+*
+* @return >= 0 : On success (# of adjustment required)
+* -1 : On failure
+*
+*/
+/****************************************************************************/
+int chipcHw_vpmPhaseAlign(void)
+{
+
+ if (chipcHw_getChipRevisionNumber() == chipcHw_REV_NUMBER_A0) {
+ return vpmPhaseAlignA0();
+ } else {
+ uint32_t phaseControl = chipcHw_getVpmPhaseControl();
+ uint32_t phaseValue = 0;
+ int adjustCount = 0;
+
+ /* Disable VPM access */
+ pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+ /* Disable HW VPM phase alignment */
+ chipcHw_vpmHwPhaseAlignDisable();
+ /* Enable SW VPM phase alignment */
+ chipcHw_vpmSwPhaseAlignEnable();
+ /* Adjust VPM phase */
+ while (adjustCount < MAX_PHASE_ADJUST_COUNT) {
+ phaseValue = chipcHw_getVpmHwPhaseAlignStatus();
+
+ /* Adjust phase control value */
+ if (phaseValue > 0xF) {
+ /* Increment phase control value */
+ phaseControl++;
+ } else if (phaseValue < 0xF) {
+ /* Decrement phase control value */
+ phaseControl--;
+ } else {
+ /* Enable VPM access */
+ pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+ /* Return adjust count */
+ return adjustCount;
+ }
+ /* Change the value of PH_CTRL. */
+ reg32_write(&pChipcHw->VPMClock, (pChipcHw->VPMClock & (~chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK)) | (phaseControl << chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT));
+ /* Wait atleast 20 ns */
+ udelay(1);
+ /* Toggle the LOAD_CH after phase control is written. */
+ pChipcHw->VPMClock ^= chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE;
+ /* Count adjustment */
+ adjustCount++;
+ }
+ }
+
+ /* Disable VPM access */
+ pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE;
+ return -1;
+}
+
+/****************************************************************************/
+/**
+* @brief Local Divide function
+*
+* This function does the divide
+*
+* @return divide value
+*
+*/
+/****************************************************************************/
+static int chipcHw_divide(int num, int denom)
+{
+ int r;
+ int t = 1;
+
+ /* Shift denom and t up to the largest value to optimize algorithm */
+ /* t contains the units of each divide */
+ while ((denom & 0x40000000) == 0) { /* fails if denom=0 */
+ denom = denom << 1;
+ t = t << 1;
+ }
+
+ /* Initialize the result */
+ r = 0;
+
+ do {
+ /* Determine if there exists a positive remainder */
+ if ((num - denom) >= 0) {
+ /* Accumlate t to the result and calculate a new remainder */
+ num = num - denom;
+ r = r + t;
+ }
+ /* Continue to shift denom and shift t down to 0 */
+ denom = denom >> 1;
+ t = t >> 1;
+ } while (t != 0);
+
+ return r;
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
new file mode 100644
index 00000000..367df75d
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_init.c
@@ -0,0 +1,293 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file chipcHw_init.c
+*
+* @brief Low level CHIPC PLL configuration functions
+*
+* @note
+*
+* These routines provide basic PLL controlling functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+#include <csp/module.h>
+
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+
+#include <csp/reg.h>
+#include <csp/delay.h>
+/* ---- Private Constants and Types --------------------------------------- */
+
+/*
+ Calculation for NDIV_i to obtain VCO frequency
+ -----------------------------------------------
+
+ Freq_vco = Freq_ref * (P2 / P1) * (PLL_NDIV_i + PLL_NDIV_f)
+ for Freq_vco = VCO_FREQ_MHz
+ Freq_ref = chipcHw_XTAL_FREQ_Hz
+ PLL_P1 = PLL_P2 = 1
+ and
+ PLL_NDIV_f = 0
+
+ We get:
+ PLL_NDIV_i = Freq_vco / Freq_ref = VCO_FREQ_MHz / chipcHw_XTAL_FREQ_Hz
+
+ Calculation for PLL MDIV to obtain frequency Freq_x for channel x
+ -----------------------------------------------------------------
+ Freq_x = chipcHw_XTAL_FREQ_Hz * PLL_NDIV_i / PLL_MDIV_x = VCO_FREQ_MHz / PLL_MDIV_x
+
+ PLL_MDIV_x = VCO_FREQ_MHz / Freq_x
+*/
+
+/* ---- Private Variables ------------------------------------------------- */
+/****************************************************************************/
+/**
+* @brief Initializes the PLL2
+*
+* This function initializes the PLL2
+*
+*/
+/****************************************************************************/
+void chipcHw_pll2Enable(uint32_t vcoFreqHz)
+{
+ uint32_t pllPreDivider2 = 0;
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig2 =
+ chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET;
+
+ pllPreDivider2 = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
+ (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+ chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+ chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+
+ /* Enable CHIPC registers to control the PLL */
+ pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
+
+ /* Set pre divider to get desired VCO frequency */
+ pChipcHw->PLLPreDivider2 = pllPreDivider2;
+ /* Set NDIV Frac */
+ pChipcHw->PLLDivider2 = chipcHw_REG_PLL_DIVIDER_NDIV_f;
+
+ /* This has to be removed once the default values are fixed for PLL2. */
+ pChipcHw->PLLControl12 = 0x38000700;
+ pChipcHw->PLLControl22 = 0x00000015;
+
+ /* Reset PLL2 */
+ if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
+ pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ } else {
+ pChipcHw->PLLConfig2 = chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ }
+ REG_LOCAL_IRQ_RESTORE;
+ }
+
+ /* Insert certain amount of delay before deasserting ARESET. */
+ udelay(1);
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+ /* Remove analog reset and Power on the PLL */
+ pChipcHw->PLLConfig2 &=
+ ~(chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN);
+
+ REG_LOCAL_IRQ_RESTORE;
+
+ }
+
+ /* Wait until PLL is locked */
+ while (!(pChipcHw->PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
+ ;
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+ /* Remove digital reset */
+ pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
+
+ REG_LOCAL_IRQ_RESTORE;
+ }
+}
+
+EXPORT_SYMBOL(chipcHw_pll2Enable);
+
+/****************************************************************************/
+/**
+* @brief Initializes the PLL1
+*
+* This function initializes the PLL1
+*
+*/
+/****************************************************************************/
+void chipcHw_pll1Enable(uint32_t vcoFreqHz, chipcHw_SPREAD_SPECTRUM_e ssSupport)
+{
+ uint32_t pllPreDivider = 0;
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+
+ pChipcHw->PLLConfig =
+ chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET;
+ /* Setting VCO frequency */
+ if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
+ pllPreDivider =
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 |
+ ((chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) -
+ 1) << chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+ chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+ chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+ } else {
+ pllPreDivider = chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN |
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER |
+ (chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vcoFreqHz) <<
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P1 <<
+ chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT) |
+ (chipcHw_REG_PLL_PREDIVIDER_P2 <<
+ chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT);
+ }
+
+ /* Enable CHIPC registers to control the PLL */
+ pChipcHw->PLLStatus |= chipcHw_REG_PLL_STATUS_CONTROL_ENABLE;
+
+ /* Set pre divider to get desired VCO frequency */
+ pChipcHw->PLLPreDivider = pllPreDivider;
+ /* Set NDIV Frac */
+ if (ssSupport == chipcHw_SPREAD_SPECTRUM_ALLOW) {
+ pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
+ chipcHw_REG_PLL_DIVIDER_NDIV_f_SS;
+ } else {
+ pChipcHw->PLLDivider = chipcHw_REG_PLL_DIVIDER_M1DIV |
+ chipcHw_REG_PLL_DIVIDER_NDIV_f;
+ }
+
+ /* Reset PLL1 */
+ if (vcoFreqHz > chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ) {
+ pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_VCO_1601_3200 |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ } else {
+ pChipcHw->PLLConfig = chipcHw_REG_PLL_CONFIG_D_RESET |
+ chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_VCO_800_1600 |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ }
+
+ REG_LOCAL_IRQ_RESTORE;
+
+ /* Insert certain amount of delay before deasserting ARESET. */
+ udelay(1);
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+ /* Remove analog reset and Power on the PLL */
+ pChipcHw->PLLConfig &=
+ ~(chipcHw_REG_PLL_CONFIG_A_RESET |
+ chipcHw_REG_PLL_CONFIG_POWER_DOWN);
+ REG_LOCAL_IRQ_RESTORE;
+ }
+
+ /* Wait until PLL is locked */
+ while (!(pChipcHw->PLLStatus & chipcHw_REG_PLL_STATUS_LOCKED)
+ || !(pChipcHw->
+ PLLStatus2 & chipcHw_REG_PLL_STATUS_LOCKED))
+ ;
+
+ /* Remove digital reset */
+ {
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_D_RESET;
+ REG_LOCAL_IRQ_RESTORE;
+ }
+ }
+}
+
+EXPORT_SYMBOL(chipcHw_pll1Enable);
+
+/****************************************************************************/
+/**
+* @brief Initializes the chipc module
+*
+* This function initializes the PLLs and core system clocks
+*
+*/
+/****************************************************************************/
+
+void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */
+ ) {
+#if !(defined(__KERNEL__) && !defined(STANDALONE))
+ delay_init();
+#endif
+
+ /* Do not program PLL, when warm reset */
+ if (!(chipcHw_getStickyBits() & chipcHw_REG_STICKY_CHIP_WARM_RESET)) {
+ chipcHw_pll1Enable(initParam->pllVcoFreqHz,
+ initParam->ssSupport);
+ chipcHw_pll2Enable(initParam->pll2VcoFreqHz);
+ } else {
+ /* Clear sticky bits */
+ chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_WARM_RESET);
+ }
+ /* Clear sticky bits */
+ chipcHw_clearStickyBits(chipcHw_REG_STICKY_CHIP_SOFT_RESET);
+
+ /* Before configuring the ARM clock, atleast we need to make sure BUS clock maintains the proper ratio with ARM clock */
+ pChipcHw->ACLKClock =
+ (pChipcHw->
+ ACLKClock & ~chipcHw_REG_ACLKClock_CLK_DIV_MASK) | (initParam->
+ armBusRatio &
+ chipcHw_REG_ACLKClock_CLK_DIV_MASK);
+
+ /* Set various core component frequencies. The order in which this is done is important for some. */
+ /* The RTBUS (DDR PHY) is derived from the BUS, and the BUS from the ARM, and VPM needs to know BUS */
+ /* frequency to find its ratio with the BUS. Hence we must set the ARM first, followed by the BUS, */
+ /* then VPM and RTBUS. */
+
+ chipcHw_setClockFrequency(chipcHw_CLOCK_ARM,
+ initParam->busClockFreqHz *
+ initParam->armBusRatio);
+ chipcHw_setClockFrequency(chipcHw_CLOCK_BUS, initParam->busClockFreqHz);
+ chipcHw_setClockFrequency(chipcHw_CLOCK_VPM,
+ initParam->busClockFreqHz *
+ initParam->vpmBusRatio);
+ chipcHw_setClockFrequency(chipcHw_CLOCK_DDR,
+ initParam->busClockFreqHz *
+ initParam->ddrBusRatio);
+ chipcHw_setClockFrequency(chipcHw_CLOCK_RTBUS,
+ initParam->busClockFreqHz / 2);
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
new file mode 100644
index 00000000..2671d889
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
@@ -0,0 +1,124 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <mach/csp/chipcHw_def.h>
+#include <mach/csp/chipcHw_inline.h>
+#include <csp/intcHw.h>
+#include <csp/cache.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+/* ---- Private Variables ------------------------------------------------- */
+void chipcHw_reset_run_from_aram(void);
+
+typedef void (*RUNFUNC) (void);
+
+/****************************************************************************/
+/**
+* @brief warmReset
+*
+* @note warmReset configures the clocks which are not reset back to the state
+* required to execute on reset. To do so we need to copy the code into internal
+* memory to change the ARM clock while we are not executing from DDR.
+*/
+/****************************************************************************/
+void chipcHw_reset(uint32_t mask)
+{
+ int i = 0;
+ RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
+
+ /* Disable all interrupts */
+ intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
+ intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
+ intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+ if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
+ chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+ }
+ /* Bypass the PLL clocks before reboot */
+ pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
+ pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
+
+ /* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
+ do {
+ ((uint32_t *) MM_IO_BASE_ARAM)[i] =
+ ((uint32_t *) &chipcHw_reset_run_from_aram)[i];
+ i++;
+ } while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */
+
+ CSP_CACHE_FLUSH_ALL;
+
+ /* run the function from ARAM */
+ runFunc();
+
+ /* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
+ REG_LOCAL_IRQ_RESTORE;
+ }
+}
+
+/* This function must run from internal memory */
+void chipcHw_reset_run_from_aram(void)
+{
+/* Make sure, pipeline is filled with instructions coming from ARAM */
+__asm (" nop \n\t"
+ " nop \n\t"
+#if defined(__KERNEL__) && !defined(STANDALONE)
+ " MRC p15,#0x0,r0,c1,c0,#0 \n\t"
+ " BIC r0,r0,#0xd \n\t"
+ " MCR p15,#0x0,r0,c1,c0,#0 \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+#endif
+ " nop \n\t"
+ " nop \n\t"
+/* Bypass the ARM clock and switch to XTAL clock */
+ " MOV r2,#0x80000000 \n\t"
+ " LDR r3,[r2,#8] \n\t"
+ " ORR r3,r3,#0x20000 \n\t"
+ " STR r3,[r2,#8] \n\t"
+
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+ " nop \n\t"
+/* Issue reset */
+ " MOV r3,#0x2 \n\t"
+ " STR r3,[r2,#0x80] \n\t"
+/* End here */
+ " MOV pc,pc \n\t");
+/* 0xe1a0f00f == asm ("mov r15, r15"); */
+}
diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
new file mode 100644
index 00000000..54ad964f
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw_str.c
@@ -0,0 +1,64 @@
+/*****************************************************************************
+* Copyright 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+/****************************************************************************/
+/**
+* @file chipcHw_str.c
+*
+* @brief Contains strings which are useful to linux and csp
+*
+* @note
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <mach/csp/chipcHw_inline.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+
+static const char *gMuxStr[] = {
+ "GPIO", /* 0 */
+ "KeyPad", /* 1 */
+ "I2C-Host", /* 2 */
+ "SPI", /* 3 */
+ "Uart", /* 4 */
+ "LED-Mtx-P", /* 5 */
+ "LED-Mtx-S", /* 6 */
+ "SDIO-0", /* 7 */
+ "SDIO-1", /* 8 */
+ "PCM", /* 9 */
+ "I2S", /* 10 */
+ "ETM", /* 11 */
+ "Debug", /* 12 */
+ "Misc", /* 13 */
+ "0xE", /* 14 */
+ "0xF", /* 15 */
+};
+
+/****************************************************************************/
+/**
+* @brief Retrieves a string representation of the mux setting for a pin.
+*
+* @return Pointer to a character string.
+*/
+/****************************************************************************/
+
+const char *chipcHw_getGpioPinFunctionStr(int pin)
+{
+ if ((pin < 0) || (pin >= chipcHw_GPIO_COUNT)) {
+ return "";
+ }
+
+ return gMuxStr[chipcHw_getGpioPinFunction(pin)];
+}
diff --git a/arch/arm/mach-bcmring/csp/dmac/Makefile b/arch/arm/mach-bcmring/csp/dmac/Makefile
new file mode 100644
index 00000000..fb1104fe
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/Makefile
@@ -0,0 +1 @@
+obj-y += dmacHw.o dmacHw_extra.o \ No newline at end of file
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
new file mode 100644
index 00000000..6b9be2e9
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c
@@ -0,0 +1,917 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dmacHw.c
+*
+* @brief Low level DMA controller driver routines
+*
+* @note
+*
+* These routines provide basic DMA functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <csp/string.h>
+#include <stddef.h>
+
+#include <csp/dmacHw.h>
+#include <mach/csp/dmacHw_reg.h>
+#include <mach/csp/dmacHw_priv.h>
+#include <mach/csp/chipcHw_inline.h>
+
+/* ---- External Function Prototypes ------------------------------------- */
+
+/* Allocate DMA control blocks */
+dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT];
+
+uint32_t dmaChannelCount_0 = dmacHw_MAX_CHANNEL_COUNT / 2;
+uint32_t dmaChannelCount_1 = dmacHw_MAX_CHANNEL_COUNT / 2;
+
+/****************************************************************************/
+/**
+* @brief Get maximum FIFO for a DMA channel
+*
+* @return Maximum allowable FIFO size
+*
+*
+*/
+/****************************************************************************/
+static uint32_t GetFifoSize(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ uint32_t val = 0;
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ dmacHw_MISC_t *pMiscReg =
+ (dmacHw_MISC_t *) dmacHw_REG_MISC_BASE(pCblk->module);
+
+ switch (pCblk->channel) {
+ case 0:
+ val = (pMiscReg->CompParm2.lo & 0x70000000) >> 28;
+ break;
+ case 1:
+ val = (pMiscReg->CompParm3.hi & 0x70000000) >> 28;
+ break;
+ case 2:
+ val = (pMiscReg->CompParm3.lo & 0x70000000) >> 28;
+ break;
+ case 3:
+ val = (pMiscReg->CompParm4.hi & 0x70000000) >> 28;
+ break;
+ case 4:
+ val = (pMiscReg->CompParm4.lo & 0x70000000) >> 28;
+ break;
+ case 5:
+ val = (pMiscReg->CompParm5.hi & 0x70000000) >> 28;
+ break;
+ case 6:
+ val = (pMiscReg->CompParm5.lo & 0x70000000) >> 28;
+ break;
+ case 7:
+ val = (pMiscReg->CompParm6.hi & 0x70000000) >> 28;
+ break;
+ }
+
+ if (val <= 0x4) {
+ return 8 << val;
+ } else {
+ dmacHw_ASSERT(0);
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Program channel register to initiate transfer
+*
+* @return void
+*
+*
+* @note
+* - Descriptor buffer MUST ALWAYS be flushed before calling this function
+* - This function should also be called from ISR to program the channel with
+* pending descriptors
+*/
+/****************************************************************************/
+void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor /* [ IN ] Descriptor buffer */
+ ) {
+ dmacHw_DESC_RING_t *pRing;
+ dmacHw_DESC_t *pProg;
+ dmacHw_CBLK_t *pCblk;
+
+ pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+ if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+ /* Not safe yet to program the channel */
+ return;
+ }
+
+ if (pCblk->varDataStarted) {
+ if (pCblk->descUpdated) {
+ pCblk->descUpdated = 0;
+ pProg =
+ (dmacHw_DESC_t *) ((uint32_t)
+ dmacHw_REG_LLP(pCblk->module,
+ pCblk->channel) +
+ pRing->virt2PhyOffset);
+
+ /* Load descriptor if not loaded */
+ if (!(pProg->ctl.hi & dmacHw_REG_CTL_DONE)) {
+ dmacHw_SET_SAR(pCblk->module, pCblk->channel,
+ pProg->sar);
+ dmacHw_SET_DAR(pCblk->module, pCblk->channel,
+ pProg->dar);
+ dmacHw_REG_CTL_LO(pCblk->module,
+ pCblk->channel) =
+ pProg->ctl.lo;
+ dmacHw_REG_CTL_HI(pCblk->module,
+ pCblk->channel) =
+ pProg->ctl.hi;
+ } else if (pProg == (dmacHw_DESC_t *) pRing->pEnd->llp) {
+ /* Return as end descriptor is processed */
+ return;
+ } else {
+ dmacHw_ASSERT(0);
+ }
+ } else {
+ return;
+ }
+ } else {
+ if (pConfig->transferMode == dmacHw_TRANSFER_MODE_PERIODIC) {
+ /* Do not make a single chain, rather process one descriptor at a time */
+ pProg = pRing->pHead;
+ /* Point to the next descriptor for next iteration */
+ dmacHw_NEXT_DESC(pRing, pHead);
+ } else {
+ /* Return if no more pending descriptor */
+ if (pRing->pEnd == NULL) {
+ return;
+ }
+
+ pProg = pRing->pProg;
+ if (pConfig->transferMode ==
+ dmacHw_TRANSFER_MODE_CONTINUOUS) {
+ /* Make sure a complete ring can be formed */
+ dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pEnd->
+ llp == pRing->pProg);
+ /* Make sure pProg pointing to the pHead */
+ dmacHw_ASSERT((dmacHw_DESC_t *) pRing->pProg ==
+ pRing->pHead);
+ /* Make a complete ring */
+ do {
+ pRing->pProg->ctl.lo |=
+ (dmacHw_REG_CTL_LLP_DST_EN |
+ dmacHw_REG_CTL_LLP_SRC_EN);
+ pRing->pProg =
+ (dmacHw_DESC_t *) pRing->pProg->llp;
+ } while (pRing->pProg != pRing->pHead);
+ } else {
+ /* Make a single long chain */
+ while (pRing->pProg != pRing->pEnd) {
+ pRing->pProg->ctl.lo |=
+ (dmacHw_REG_CTL_LLP_DST_EN |
+ dmacHw_REG_CTL_LLP_SRC_EN);
+ pRing->pProg =
+ (dmacHw_DESC_t *) pRing->pProg->llp;
+ }
+ }
+ }
+
+ /* Program the channel registers */
+ dmacHw_SET_SAR(pCblk->module, pCblk->channel, pProg->sar);
+ dmacHw_SET_DAR(pCblk->module, pCblk->channel, pProg->dar);
+ dmacHw_SET_LLP(pCblk->module, pCblk->channel,
+ (uint32_t) pProg - pRing->virt2PhyOffset);
+ dmacHw_REG_CTL_LO(pCblk->module, pCblk->channel) =
+ pProg->ctl.lo;
+ dmacHw_REG_CTL_HI(pCblk->module, pCblk->channel) =
+ pProg->ctl.hi;
+ if (pRing->pEnd) {
+ /* Remember the descriptor to use next */
+ pRing->pProg = (dmacHw_DESC_t *) pRing->pEnd->llp;
+ }
+ /* Indicate no more pending descriptor */
+ pRing->pEnd = (dmacHw_DESC_t *) NULL;
+ }
+ /* Start DMA operation */
+ dmacHw_DMA_START(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+* @brief Initializes DMA
+*
+* This function initializes DMA CSP driver
+*
+* @note
+* Must be called before using any DMA channel
+*/
+/****************************************************************************/
+void dmacHw_initDma(void)
+{
+
+ uint32_t i = 0;
+
+ dmaChannelCount_0 = dmacHw_GET_NUM_CHANNEL(0);
+ dmaChannelCount_1 = dmacHw_GET_NUM_CHANNEL(1);
+
+ /* Enable access to the DMA block */
+ chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC0);
+ chipcHw_busInterfaceClockEnable(chipcHw_REG_BUS_CLOCK_DMAC1);
+
+ if ((dmaChannelCount_0 + dmaChannelCount_1) > dmacHw_MAX_CHANNEL_COUNT) {
+ dmacHw_ASSERT(0);
+ }
+
+ memset((void *)dmacHw_gCblk, 0,
+ sizeof(dmacHw_CBLK_t) * (dmaChannelCount_0 + dmaChannelCount_1));
+ for (i = 0; i < dmaChannelCount_0; i++) {
+ dmacHw_gCblk[i].module = 0;
+ dmacHw_gCblk[i].channel = i;
+ }
+ for (i = 0; i < dmaChannelCount_1; i++) {
+ dmacHw_gCblk[i + dmaChannelCount_0].module = 1;
+ dmacHw_gCblk[i + dmaChannelCount_0].channel = i;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Exit function for DMA
+*
+* This function isolates DMA from the system
+*
+*/
+/****************************************************************************/
+void dmacHw_exitDma(void)
+{
+ /* Disable access to the DMA block */
+ chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC0);
+ chipcHw_busInterfaceClockDisable(chipcHw_REG_BUS_CLOCK_DMAC1);
+}
+
+/****************************************************************************/
+/**
+* @brief Gets a handle to a DMA channel
+*
+* This function returns a handle, representing a control block of a particular DMA channel
+*
+* @return -1 - On Failure
+* handle - On Success, representing a channel control block
+*
+* @note
+* None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */
+ ) {
+ int idx;
+
+ switch ((channelId >> 8)) {
+ case 0:
+ dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_0);
+ idx = (channelId & 0xff);
+ break;
+ case 1:
+ dmacHw_ASSERT((channelId & 0xff) < dmaChannelCount_1);
+ idx = dmaChannelCount_0 + (channelId & 0xff);
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ return (dmacHw_HANDLE_t) -1;
+ }
+
+ return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[idx]);
+}
+
+/****************************************************************************/
+/**
+* @brief Initializes a DMA channel for use
+*
+* This function initializes and resets a DMA channel for use
+*
+* @return -1 - On Failure
+* 0 - On Success
+*
+* @note
+* None
+*/
+/****************************************************************************/
+int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ int module = pCblk->module;
+ int channel = pCblk->channel;
+
+ /* Reinitialize the control block */
+ memset((void *)pCblk, 0, sizeof(dmacHw_CBLK_t));
+ pCblk->module = module;
+ pCblk->channel = channel;
+
+ /* Enable DMA controller */
+ dmacHw_DMA_ENABLE(pCblk->module);
+ /* Reset DMA channel */
+ dmacHw_RESET_CONTROL_LO(pCblk->module, pCblk->channel);
+ dmacHw_RESET_CONTROL_HI(pCblk->module, pCblk->channel);
+ dmacHw_RESET_CONFIG_LO(pCblk->module, pCblk->channel);
+ dmacHw_RESET_CONFIG_HI(pCblk->module, pCblk->channel);
+
+ /* Clear all raw interrupt status */
+ dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+
+ /* Mask event specific interrupts */
+ dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+ dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
+ dmacHw_STRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+ dmacHw_DTRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+ dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
+
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Finds amount of memory required to form a descriptor ring
+*
+*
+* @return Number of bytes required to form a descriptor ring
+*
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */
+ ) {
+ /* Need extra 4 byte to ensure 32 bit alignment */
+ return (descCnt * sizeof(dmacHw_DESC_t)) + sizeof(dmacHw_DESC_RING_t) +
+ sizeof(uint32_t);
+}
+
+/****************************************************************************/
+/**
+* @brief Initializes descriptor ring
+*
+* This function will initializes the descriptor ring of a DMA channel
+*
+*
+* @return -1 - On failure
+* 0 - On success
+* @note
+* - "len" parameter should be obtained from "dmacHw_descriptorLen"
+* - Descriptor buffer MUST be 32 bit aligned and uncached as it is
+* accessed by ARM and DMA
+*/
+/****************************************************************************/
+int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
+ uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
+ uint32_t len, /* [ IN ] Size of the pBuf */
+ uint32_t num /* [ IN ] Number of descriptor in the ring */
+ ) {
+ uint32_t i;
+ dmacHw_DESC_RING_t *pRing;
+ dmacHw_DESC_t *pDesc;
+
+ /* Check the alignment of the descriptor */
+ if ((uint32_t) pDescriptorVirt & 0x00000003) {
+ dmacHw_ASSERT(0);
+ return -1;
+ }
+
+ /* Check if enough space has been allocated for descriptor ring */
+ if (len < dmacHw_descriptorLen(num)) {
+ return -1;
+ }
+
+ pRing = dmacHw_GET_DESC_RING(pDescriptorVirt);
+ pRing->pHead =
+ (dmacHw_DESC_t *) ((uint32_t) pRing + sizeof(dmacHw_DESC_RING_t));
+ pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
+ pRing->pProg = dmacHw_DESC_INIT;
+ /* Initialize link item chain, starting from the head */
+ pDesc = pRing->pHead;
+ /* Find the offset between virtual to physical address */
+ pRing->virt2PhyOffset = (uint32_t) pDescriptorVirt - descriptorPhyAddr;
+
+ /* Form the descriptor ring */
+ for (i = 0; i < num - 1; i++) {
+ /* Clear link list item */
+ memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
+ /* Point to the next item in the physical address */
+ pDesc->llpPhy = (uint32_t) (pDesc + 1) - pRing->virt2PhyOffset;
+ /* Point to the next item in the virtual address */
+ pDesc->llp = (uint32_t) (pDesc + 1);
+ /* Mark descriptor is ready to use */
+ pDesc->ctl.hi = dmacHw_DESC_FREE;
+ /* Look into next link list item */
+ pDesc++;
+ }
+
+ /* Clear last link list item */
+ memset((void *)pDesc, 0, sizeof(dmacHw_DESC_t));
+ /* Last item pointing to the first item in the
+ physical address to complete the ring */
+ pDesc->llpPhy = (uint32_t) pRing->pHead - pRing->virt2PhyOffset;
+ /* Last item pointing to the first item in the
+ virtual address to complete the ring
+ */
+ pDesc->llp = (uint32_t) pRing->pHead;
+ /* Mark descriptor is ready to use */
+ pDesc->ctl.hi = dmacHw_DESC_FREE;
+ /* Set the number of descriptors in the ring */
+ pRing->num = num;
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Configure DMA channel
+*
+* @return 0 : On success
+* -1 : On failure
+*/
+/****************************************************************************/
+int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ uint32_t cfgHigh = 0;
+ int srcTrSize;
+ int dstTrSize;
+
+ pCblk->varDataStarted = 0;
+ pCblk->userData = NULL;
+
+ /* Configure
+ - Burst transaction when enough data in available in FIFO
+ - AHB Access protection 1
+ - Source and destination peripheral ports
+ */
+ cfgHigh =
+ dmacHw_REG_CFG_HI_FIFO_ENOUGH | dmacHw_REG_CFG_HI_AHB_HPROT_1 |
+ dmacHw_SRC_PERI_INTF(pConfig->
+ srcPeripheralPort) |
+ dmacHw_DST_PERI_INTF(pConfig->dstPeripheralPort);
+ /* Set priority */
+ dmacHw_SET_CHANNEL_PRIORITY(pCblk->module, pCblk->channel,
+ pConfig->channelPriority);
+
+ if (pConfig->dstStatusRegisterAddress != 0) {
+ /* Destination status update enable */
+ cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_DST_STAT;
+ /* Configure status registers */
+ dmacHw_SET_DSTATAR(pCblk->module, pCblk->channel,
+ pConfig->dstStatusRegisterAddress);
+ }
+
+ if (pConfig->srcStatusRegisterAddress != 0) {
+ /* Source status update enable */
+ cfgHigh |= dmacHw_REG_CFG_HI_UPDATE_SRC_STAT;
+ /* Source status update enable */
+ dmacHw_SET_SSTATAR(pCblk->module, pCblk->channel,
+ pConfig->srcStatusRegisterAddress);
+ }
+ /* Configure the config high register */
+ dmacHw_GET_CONFIG_HI(pCblk->module, pCblk->channel) = cfgHigh;
+
+ /* Clear all raw interrupt status */
+ dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+
+ /* Configure block interrupt */
+ if (pConfig->blockTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
+ dmacHw_BLOCK_INT_ENABLE(pCblk->module, pCblk->channel);
+ } else {
+ dmacHw_BLOCK_INT_DISABLE(pCblk->module, pCblk->channel);
+ }
+ /* Configure complete transfer interrupt */
+ if (pConfig->completeTransferInterrupt == dmacHw_INTERRUPT_ENABLE) {
+ dmacHw_TRAN_INT_ENABLE(pCblk->module, pCblk->channel);
+ } else {
+ dmacHw_TRAN_INT_DISABLE(pCblk->module, pCblk->channel);
+ }
+ /* Configure error interrupt */
+ if (pConfig->errorInterrupt == dmacHw_INTERRUPT_ENABLE) {
+ dmacHw_ERROR_INT_ENABLE(pCblk->module, pCblk->channel);
+ } else {
+ dmacHw_ERROR_INT_DISABLE(pCblk->module, pCblk->channel);
+ }
+ /* Configure gather register */
+ if (pConfig->srcGatherWidth) {
+ srcTrSize =
+ dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+ if (!
+ ((pConfig->srcGatherWidth % srcTrSize)
+ && (pConfig->srcGatherJump % srcTrSize))) {
+ dmacHw_REG_SGR_LO(pCblk->module, pCblk->channel) =
+ ((pConfig->srcGatherWidth /
+ srcTrSize) << 20) | (pConfig->srcGatherJump /
+ srcTrSize);
+ } else {
+ return -1;
+ }
+ }
+ /* Configure scatter register */
+ if (pConfig->dstScatterWidth) {
+ dstTrSize =
+ dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+ if (!
+ ((pConfig->dstScatterWidth % dstTrSize)
+ && (pConfig->dstScatterJump % dstTrSize))) {
+ dmacHw_REG_DSR_LO(pCblk->module, pCblk->channel) =
+ ((pConfig->dstScatterWidth /
+ dstTrSize) << 20) | (pConfig->dstScatterJump /
+ dstTrSize);
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Indicates whether DMA transfer is in progress or completed
+*
+* @return DMA transfer status
+* dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing
+* dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed
+* dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error
+*
+*/
+/****************************************************************************/
+dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ if (CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+ return dmacHw_TRANSFER_STATUS_BUSY;
+ } else if (dmacHw_REG_INT_RAW_ERROR(pCblk->module) &
+ (0x00000001 << pCblk->channel)) {
+ return dmacHw_TRANSFER_STATUS_ERROR;
+ }
+
+ return dmacHw_TRANSFER_STATUS_DONE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set descriptors for known data length
+*
+* When DMA has to work as a flow controller, this function prepares the
+* descriptor chain to transfer data
+*
+* from:
+* - Memory to memory
+* - Peripheral to memory
+* - Memory to Peripheral
+* - Peripheral to Peripheral
+*
+* @return -1 - On failure
+* 0 - On success
+*
+*/
+/****************************************************************************/
+int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
+ void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
+ size_t dataLen /* [ IN ] Data length in bytes */
+ ) {
+ dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
+ dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+ dmacHw_DESC_t *pStart;
+ dmacHw_DESC_t *pProg;
+ int srcTs = 0;
+ int blkTs = 0;
+ int oddSize = 0;
+ int descCount = 0;
+ int count = 0;
+ int dstTrSize = 0;
+ int srcTrSize = 0;
+ uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
+
+ dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+ srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+
+ /* Skip Tx if buffer is NULL or length is unknown */
+ if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
+ /* Do not initiate transfer */
+ return -1;
+ }
+
+ /* Ensure scatter and gather are transaction aligned */
+ if ((pConfig->srcGatherWidth % srcTrSize)
+ || (pConfig->dstScatterWidth % dstTrSize)) {
+ return -2;
+ }
+
+ /*
+ Background 1: DMAC can not perform DMA if source and destination addresses are
+ not properly aligned with the channel's transaction width. So, for successful
+ DMA transfer, transaction width must be set according to the alignment of the
+ source and destination address.
+ */
+
+ /* Adjust destination transaction width if destination address is not aligned properly */
+ dstTrWidth = pConfig->dstMaxTransactionWidth;
+ while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
+ dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
+ dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
+ }
+
+ /* Adjust source transaction width if source address is not aligned properly */
+ srcTrWidth = pConfig->srcMaxTransactionWidth;
+ while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
+ srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
+ srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
+ }
+
+ /* Find the maximum transaction per descriptor */
+ if (pConfig->maxDataPerBlock
+ && ((pConfig->maxDataPerBlock / srcTrSize) <
+ dmacHw_MAX_BLOCKSIZE)) {
+ maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
+ }
+
+ /* Find number of source transactions needed to complete the DMA transfer */
+ srcTs = dataLen / srcTrSize;
+ /* Find the odd number of bytes that need to be transferred as single byte transaction width */
+ if (srcTs && (dstTrSize > srcTrSize)) {
+ oddSize = dataLen % dstTrSize;
+ /* Adjust source transaction count due to "oddSize" */
+ srcTs = srcTs - (oddSize / srcTrSize);
+ } else {
+ oddSize = dataLen % srcTrSize;
+ }
+ /* Adjust "descCount" due to "oddSize" */
+ if (oddSize) {
+ descCount++;
+ }
+ /* Find the number of descriptor needed for total "srcTs" */
+ if (srcTs) {
+ descCount += ((srcTs - 1) / maxBlockSize) + 1;
+ }
+
+ /* Check the availability of "descCount" discriptors in the ring */
+ pProg = pRing->pHead;
+ for (count = 0; (descCount <= pRing->num) && (count < descCount);
+ count++) {
+ if ((pProg->ctl.hi & dmacHw_DESC_FREE) == 0) {
+ /* Sufficient descriptors are not available */
+ return -3;
+ }
+ pProg = (dmacHw_DESC_t *) pProg->llp;
+ }
+
+ /* Remember the link list item to program the channel registers */
+ pStart = pProg = pRing->pHead;
+ /* Make a link list with "descCount(=count)" number of descriptors */
+ while (count) {
+ /* Reset channel control information */
+ pProg->ctl.lo = 0;
+ /* Enable source gather if configured */
+ if (pConfig->srcGatherWidth) {
+ pProg->ctl.lo |= dmacHw_REG_CTL_SG_ENABLE;
+ }
+ /* Enable destination scatter if configured */
+ if (pConfig->dstScatterWidth) {
+ pProg->ctl.lo |= dmacHw_REG_CTL_DS_ENABLE;
+ }
+ /* Set source and destination address */
+ pProg->sar = (uint32_t) pSrcAddr;
+ pProg->dar = (uint32_t) pDstAddr;
+ /* Use "devCtl" to mark that user memory need to be freed later if needed */
+ if (pProg == pRing->pHead) {
+ pProg->devCtl = dmacHw_FREE_USER_MEMORY;
+ } else {
+ pProg->devCtl = 0;
+ }
+
+ blkTs = srcTs;
+
+ /* Special treatmeant for last descriptor */
+ if (count == 1) {
+ /* Mark the last descriptor */
+ pProg->ctl.lo &=
+ ~(dmacHw_REG_CTL_LLP_DST_EN |
+ dmacHw_REG_CTL_LLP_SRC_EN);
+ /* Treatment for odd data bytes */
+ if (oddSize) {
+ /* Adjust for single byte transaction width */
+ switch (pConfig->transferType) {
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+ dstTrWidth =
+ dmacHw_DST_TRANSACTION_WIDTH_8;
+ blkTs =
+ (oddSize / srcTrSize) +
+ ((oddSize % srcTrSize) ? 1 : 0);
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+ srcTrWidth =
+ dmacHw_SRC_TRANSACTION_WIDTH_8;
+ blkTs = oddSize;
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
+ srcTrWidth =
+ dmacHw_SRC_TRANSACTION_WIDTH_8;
+ dstTrWidth =
+ dmacHw_DST_TRANSACTION_WIDTH_8;
+ blkTs = oddSize;
+ break;
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
+ /* Do not adjust the transaction width */
+ break;
+ }
+ } else {
+ srcTs -= blkTs;
+ }
+ } else {
+ if (srcTs / maxBlockSize) {
+ blkTs = maxBlockSize;
+ }
+ /* Remaining source transactions for next iteration */
+ srcTs -= blkTs;
+ }
+ /* Must have a valid source transactions */
+ dmacHw_ASSERT(blkTs > 0);
+ /* Set control information */
+ if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
+ pProg->ctl.lo |= pConfig->transferType |
+ pConfig->srcUpdate |
+ pConfig->dstUpdate |
+ srcTrWidth |
+ dstTrWidth |
+ pConfig->srcMaxBurstWidth |
+ pConfig->dstMaxBurstWidth |
+ pConfig->srcMasterInterface |
+ pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+ } else {
+ uint32_t transferType = 0;
+ switch (pConfig->transferType) {
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+ transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+ transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ }
+ pProg->ctl.lo |= transferType |
+ pConfig->srcUpdate |
+ pConfig->dstUpdate |
+ srcTrWidth |
+ dstTrWidth |
+ pConfig->srcMaxBurstWidth |
+ pConfig->dstMaxBurstWidth |
+ pConfig->srcMasterInterface |
+ pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+ }
+
+ /* Set block transaction size */
+ pProg->ctl.hi = blkTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
+ /* Look for next descriptor */
+ if (count > 1) {
+ /* Point to the next descriptor */
+ pProg = (dmacHw_DESC_t *) pProg->llp;
+
+ /* Update source and destination address for next iteration */
+ switch (pConfig->transferType) {
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+ if (pConfig->dstScatterWidth) {
+ pDstAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize +
+ (((blkTs * srcTrSize) /
+ pConfig->dstScatterWidth) *
+ pConfig->dstScatterJump);
+ } else {
+ pDstAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize;
+ }
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+ if (pConfig->srcGatherWidth) {
+ pSrcAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize +
+ (((blkTs * srcTrSize) /
+ pConfig->srcGatherWidth) *
+ pConfig->srcGatherJump);
+ } else {
+ pSrcAddr =
+ (char *)pSrcAddr +
+ blkTs * srcTrSize;
+ }
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_MEM:
+ if (pConfig->dstScatterWidth) {
+ pDstAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize +
+ (((blkTs * srcTrSize) /
+ pConfig->dstScatterWidth) *
+ pConfig->dstScatterJump);
+ } else {
+ pDstAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize;
+ }
+
+ if (pConfig->srcGatherWidth) {
+ pSrcAddr =
+ (char *)pDstAddr +
+ blkTs * srcTrSize +
+ (((blkTs * srcTrSize) /
+ pConfig->srcGatherWidth) *
+ pConfig->srcGatherJump);
+ } else {
+ pSrcAddr =
+ (char *)pSrcAddr +
+ blkTs * srcTrSize;
+ }
+ break;
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL:
+ /* Do not adjust the address */
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ }
+ } else {
+ /* At the end of transfer "srcTs" must be zero */
+ dmacHw_ASSERT(srcTs == 0);
+ }
+ count--;
+ }
+
+ /* Remember the descriptor to initialize the registers */
+ if (pRing->pProg == dmacHw_DESC_INIT) {
+ pRing->pProg = pStart;
+ }
+ /* Indicate that the descriptor is updated */
+ pRing->pEnd = pProg;
+ /* Head pointing to the next descriptor */
+ pRing->pHead = (dmacHw_DESC_t *) pProg->llp;
+ /* Update Tail pointer if destination is a peripheral,
+ because no one is going to read from the pTail
+ */
+ if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+ pRing->pTail = pRing->pHead;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Provides DMA controller attributes
+*
+*
+* @return DMA controller attributes
+*
+* @note
+* None
+*/
+/****************************************************************************/
+uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ switch (attr) {
+ case dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM:
+ return dmacHw_GET_NUM_CHANNEL(pCblk->module);
+ case dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE:
+ return (1 <<
+ (dmacHw_GET_MAX_BLOCK_SIZE
+ (pCblk->module, pCblk->module) + 2)) - 8;
+ case dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM:
+ return dmacHw_GET_NUM_INTERFACE(pCblk->module);
+ case dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH:
+ return 32 << dmacHw_GET_CHANNEL_DATA_WIDTH(pCblk->module,
+ pCblk->channel);
+ case dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE:
+ return GetFifoSize(handle);
+ }
+ dmacHw_ASSERT(0);
+ return 0;
+}
diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
new file mode 100644
index 00000000..a1f32835
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c
@@ -0,0 +1,1017 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dmacHw_extra.c
+*
+* @brief Extra Low level DMA controller driver routines
+*
+* @note
+*
+* These routines provide basic DMA functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+#include <stddef.h>
+
+#include <csp/dmacHw.h>
+#include <mach/csp/dmacHw_reg.h>
+#include <mach/csp/dmacHw_priv.h>
+
+extern dmacHw_CBLK_t dmacHw_gCblk[dmacHw_MAX_CHANNEL_COUNT]; /* Declared in dmacHw.c */
+
+/* ---- External Function Prototypes ------------------------------------- */
+
+/* ---- Internal Use Function Prototypes --------------------------------- */
+/****************************************************************************/
+/**
+* @brief Overwrites data length in the descriptor
+*
+* This function overwrites data length in the descriptor
+*
+*
+* @return void
+*
+* @note
+* This is only used for PCM channel
+*/
+/****************************************************************************/
+void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ size_t dataLen /* [ IN ] Data length in bytes */
+ );
+
+/****************************************************************************/
+/**
+* @brief Helper function to display DMA registers
+*
+* @return void
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+static void DisplayRegisterContents(int module, /* [ IN ] DMA Controller unit (0-1) */
+ int channel, /* [ IN ] DMA Channel (0-7) / -1(all) */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */
+ ) {
+ int chan;
+
+ (*fpPrint) ("Displaying register content \n\n");
+ (*fpPrint) ("Module %d: Interrupt raw transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_RAW_TRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt raw block 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_RAW_BLOCK(module)));
+ (*fpPrint) ("Module %d: Interrupt raw src transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_RAW_STRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt raw dst transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_RAW_DTRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt raw error 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_RAW_ERROR(module)));
+ (*fpPrint) ("--------------------------------------------------\n");
+ (*fpPrint) ("Module %d: Interrupt stat transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_STAT_TRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt stat block 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_STAT_BLOCK(module)));
+ (*fpPrint) ("Module %d: Interrupt stat src transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_STAT_STRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt stat dst transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_STAT_DTRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt stat error 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_STAT_ERROR(module)));
+ (*fpPrint) ("--------------------------------------------------\n");
+ (*fpPrint) ("Module %d: Interrupt mask transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_MASK_TRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt mask block 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_MASK_BLOCK(module)));
+ (*fpPrint) ("Module %d: Interrupt mask src transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_MASK_STRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt mask dst transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_MASK_DTRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt mask error 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_MASK_ERROR(module)));
+ (*fpPrint) ("--------------------------------------------------\n");
+ (*fpPrint) ("Module %d: Interrupt clear transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_CLEAR_TRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt clear block 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_CLEAR_BLOCK(module)));
+ (*fpPrint) ("Module %d: Interrupt clear src transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_CLEAR_STRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt clear dst transfer 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_CLEAR_DTRAN(module)));
+ (*fpPrint) ("Module %d: Interrupt clear error 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_INT_CLEAR_ERROR(module)));
+ (*fpPrint) ("--------------------------------------------------\n");
+ (*fpPrint) ("Module %d: SW source req 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_SRC_REQ(module)));
+ (*fpPrint) ("Module %d: SW dest req 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_DST_REQ(module)));
+ (*fpPrint) ("Module %d: SW source signal 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_SRC_SGL_REQ(module)));
+ (*fpPrint) ("Module %d: SW dest signal 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_DST_SGL_REQ(module)));
+ (*fpPrint) ("Module %d: SW source last 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_SRC_LST_REQ(module)));
+ (*fpPrint) ("Module %d: SW dest last 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_SW_HS_DST_LST_REQ(module)));
+ (*fpPrint) ("--------------------------------------------------\n");
+ (*fpPrint) ("Module %d: misc config 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_MISC_CFG(module)));
+ (*fpPrint) ("Module %d: misc channel enable 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_MISC_CH_ENABLE(module)));
+ (*fpPrint) ("Module %d: misc ID 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_MISC_ID(module)));
+ (*fpPrint) ("Module %d: misc test 0x%X\n",
+ module, (uint32_t) (dmacHw_REG_MISC_TEST(module)));
+
+ if (channel == -1) {
+ for (chan = 0; chan < 8; chan++) {
+ (*fpPrint)
+ ("--------------------------------------------------\n");
+ (*fpPrint)
+ ("Module %d: Channel %d Source 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_SAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Destination 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_DAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d LLP 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_LLP(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Control (LO) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Control (HI) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Source Stats 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Dest Stats 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Source Stats Addr 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Dest Stats Addr 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Config (LO) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Config (HI) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
+ }
+ } else {
+ chan = channel;
+ (*fpPrint)
+ ("--------------------------------------------------\n");
+ (*fpPrint)
+ ("Module %d: Channel %d Source 0x%X\n",
+ module, chan, (uint32_t) (dmacHw_REG_SAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Destination 0x%X\n",
+ module, chan, (uint32_t) (dmacHw_REG_DAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d LLP 0x%X\n",
+ module, chan, (uint32_t) (dmacHw_REG_LLP(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Control (LO) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CTL_LO(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Control (HI) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CTL_HI(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Source Stats 0x%X\n",
+ module, chan, (uint32_t) (dmacHw_REG_SSTAT(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Dest Stats 0x%X\n",
+ module, chan, (uint32_t) (dmacHw_REG_DSTAT(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Source Stats Addr 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_SSTATAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Dest Stats Addr 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_DSTATAR(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Config (LO) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CFG_LO(module, chan)));
+ (*fpPrint)
+ ("Module %d: Channel %d Config (HI) 0x%X\n",
+ module, chan,
+ (uint32_t) (dmacHw_REG_CFG_HI(module, chan)));
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Helper function to display descriptor ring
+*
+* @return void
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+static void DisplayDescRing(void *pDescriptor, /* [ IN ] Descriptor buffer */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Callback to the print function */
+ ) {
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+ dmacHw_DESC_t *pStart;
+
+ if (pRing->pHead == NULL) {
+ return;
+ }
+
+ pStart = pRing->pHead;
+
+ while ((dmacHw_DESC_t *) pStart->llp != pRing->pHead) {
+ if (pStart == pRing->pHead) {
+ (*fpPrint) ("Head\n");
+ }
+ if (pStart == pRing->pTail) {
+ (*fpPrint) ("Tail\n");
+ }
+ if (pStart == pRing->pProg) {
+ (*fpPrint) ("Prog\n");
+ }
+ if (pStart == pRing->pEnd) {
+ (*fpPrint) ("End\n");
+ }
+ if (pStart == pRing->pFree) {
+ (*fpPrint) ("Free\n");
+ }
+ (*fpPrint) ("0x%X:\n", (uint32_t) pStart);
+ (*fpPrint) ("sar 0x%0X\n", pStart->sar);
+ (*fpPrint) ("dar 0x%0X\n", pStart->dar);
+ (*fpPrint) ("llp 0x%0X\n", pStart->llp);
+ (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
+ (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
+ (*fpPrint) ("sstat 0x%0X\n", pStart->sstat);
+ (*fpPrint) ("dstat 0x%0X\n", pStart->dstat);
+ (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
+
+ pStart = (dmacHw_DESC_t *) pStart->llp;
+ }
+ if (pStart == pRing->pHead) {
+ (*fpPrint) ("Head\n");
+ }
+ if (pStart == pRing->pTail) {
+ (*fpPrint) ("Tail\n");
+ }
+ if (pStart == pRing->pProg) {
+ (*fpPrint) ("Prog\n");
+ }
+ if (pStart == pRing->pEnd) {
+ (*fpPrint) ("End\n");
+ }
+ if (pStart == pRing->pFree) {
+ (*fpPrint) ("Free\n");
+ }
+ (*fpPrint) ("0x%X:\n", (uint32_t) pStart);
+ (*fpPrint) ("sar 0x%0X\n", pStart->sar);
+ (*fpPrint) ("dar 0x%0X\n", pStart->dar);
+ (*fpPrint) ("llp 0x%0X\n", pStart->llp);
+ (*fpPrint) ("ctl.lo 0x%0X\n", pStart->ctl.lo);
+ (*fpPrint) ("ctl.hi 0x%0X\n", pStart->ctl.hi);
+ (*fpPrint) ("sstat 0x%0X\n", pStart->sstat);
+ (*fpPrint) ("dstat 0x%0X\n", pStart->dstat);
+ (*fpPrint) ("devCtl 0x%0X\n", pStart->devCtl);
+}
+
+/****************************************************************************/
+/**
+* @brief Check if DMA channel is the flow controller
+*
+* @return 1 : If DMA is a flow controller
+* 0 : Peripheral is the flow controller
+*
+* @note
+* None
+*/
+/****************************************************************************/
+static inline int DmaIsFlowController(void *pDescriptor /* [ IN ] Descriptor buffer */
+ ) {
+ uint32_t ttfc =
+ (dmacHw_GET_DESC_RING(pDescriptor))->pTail->ctl.
+ lo & dmacHw_REG_CTL_TTFC_MASK;
+
+ switch (ttfc) {
+ case dmacHw_REG_CTL_TTFC_MM_DMAC:
+ case dmacHw_REG_CTL_TTFC_MP_DMAC:
+ case dmacHw_REG_CTL_TTFC_PM_DMAC:
+ case dmacHw_REG_CTL_TTFC_PP_DMAC:
+ return 1;
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Overwrites data length in the descriptor
+*
+* This function overwrites data length in the descriptor
+*
+*
+* @return void
+*
+* @note
+* This is only used for PCM channel
+*/
+/****************************************************************************/
+void dmacHw_setDataLength(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ size_t dataLen /* [ IN ] Data length in bytes */
+ ) {
+ dmacHw_DESC_t *pProg;
+ dmacHw_DESC_t *pHead;
+ int srcTs = 0;
+ int srcTrSize = 0;
+
+ pHead = (dmacHw_GET_DESC_RING(pDescriptor))->pHead;
+ pProg = pHead;
+
+ srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+ srcTs = dataLen / srcTrSize;
+ do {
+ pProg->ctl.hi = srcTs & dmacHw_REG_CTL_BLOCK_TS_MASK;
+ pProg = (dmacHw_DESC_t *) pProg->llp;
+ } while (pProg != pHead);
+}
+
+/****************************************************************************/
+/**
+* @brief Clears the interrupt
+*
+* This function clears the DMA channel specific interrupt
+*
+*
+* @return void
+*
+* @note
+* Must be called under the context of ISR
+*/
+/****************************************************************************/
+void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ dmacHw_TRAN_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_BLOCK_INT_CLEAR(pCblk->module, pCblk->channel);
+ dmacHw_ERROR_INT_CLEAR(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+* @brief Returns the cause of channel specific DMA interrupt
+*
+* This function returns the cause of interrupt
+*
+* @return Interrupt status, each bit representing a specific type of interrupt
+*
+* @note
+* Should be called under the context of ISR
+*/
+/****************************************************************************/
+dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ dmacHw_INTERRUPT_STATUS_e status = dmacHw_INTERRUPT_STATUS_NONE;
+
+ if (dmacHw_REG_INT_STAT_TRAN(pCblk->module) &
+ ((0x00000001 << pCblk->channel))) {
+ status |= dmacHw_INTERRUPT_STATUS_TRANS;
+ }
+ if (dmacHw_REG_INT_STAT_BLOCK(pCblk->module) &
+ ((0x00000001 << pCblk->channel))) {
+ status |= dmacHw_INTERRUPT_STATUS_BLOCK;
+ }
+ if (dmacHw_REG_INT_STAT_ERROR(pCblk->module) &
+ ((0x00000001 << pCblk->channel))) {
+ status |= dmacHw_INTERRUPT_STATUS_ERROR;
+ }
+
+ return status;
+}
+
+/****************************************************************************/
+/**
+* @brief Indentifies a DMA channel causing interrupt
+*
+* This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
+*
+* @return NULL : No channel causing DMA interrupt
+* ! NULL : Handle to a channel causing DMA interrupt
+* @note
+* dmacHw_clearInterrupt() must be called with a valid handle after calling this function
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getInterruptSource(void)
+{
+ uint32_t i;
+
+ for (i = 0; i < dmaChannelCount_0 + dmaChannelCount_1; i++) {
+ if ((dmacHw_REG_INT_STAT_TRAN(dmacHw_gCblk[i].module) &
+ ((0x00000001 << dmacHw_gCblk[i].channel)))
+ || (dmacHw_REG_INT_STAT_BLOCK(dmacHw_gCblk[i].module) &
+ ((0x00000001 << dmacHw_gCblk[i].channel)))
+ || (dmacHw_REG_INT_STAT_ERROR(dmacHw_gCblk[i].module) &
+ ((0x00000001 << dmacHw_gCblk[i].channel)))
+ ) {
+ return dmacHw_CBLK_TO_HANDLE(&dmacHw_gCblk[i]);
+ }
+ }
+ return dmacHw_CBLK_TO_HANDLE(NULL);
+}
+
+/****************************************************************************/
+/**
+* @brief Estimates number of descriptor needed to perform certain DMA transfer
+*
+*
+* @return On failure : -1
+* On success : Number of descriptor count
+*
+*
+*/
+/****************************************************************************/
+int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
+ void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
+ size_t dataLen /* [ IN ] Data length in bytes */
+ ) {
+ int srcTs = 0;
+ int oddSize = 0;
+ int descCount = 0;
+ int dstTrSize = 0;
+ int srcTrSize = 0;
+ uint32_t maxBlockSize = dmacHw_MAX_BLOCKSIZE;
+ dmacHw_TRANSACTION_WIDTH_e dstTrWidth;
+ dmacHw_TRANSACTION_WIDTH_e srcTrWidth;
+
+ dstTrSize = dmacHw_GetTrWidthInBytes(pConfig->dstMaxTransactionWidth);
+ srcTrSize = dmacHw_GetTrWidthInBytes(pConfig->srcMaxTransactionWidth);
+
+ /* Skip Tx if buffer is NULL or length is unknown */
+ if ((pSrcAddr == NULL) || (pDstAddr == NULL) || (dataLen == 0)) {
+ /* Do not initiate transfer */
+ return -1;
+ }
+
+ /* Ensure scatter and gather are transaction aligned */
+ if (pConfig->srcGatherWidth % srcTrSize
+ || pConfig->dstScatterWidth % dstTrSize) {
+ return -1;
+ }
+
+ /*
+ Background 1: DMAC can not perform DMA if source and destination addresses are
+ not properly aligned with the channel's transaction width. So, for successful
+ DMA transfer, transaction width must be set according to the alignment of the
+ source and destination address.
+ */
+
+ /* Adjust destination transaction width if destination address is not aligned properly */
+ dstTrWidth = pConfig->dstMaxTransactionWidth;
+ while (dmacHw_ADDRESS_MASK(dstTrSize) & (uint32_t) pDstAddr) {
+ dstTrWidth = dmacHw_GetNextTrWidth(dstTrWidth);
+ dstTrSize = dmacHw_GetTrWidthInBytes(dstTrWidth);
+ }
+
+ /* Adjust source transaction width if source address is not aligned properly */
+ srcTrWidth = pConfig->srcMaxTransactionWidth;
+ while (dmacHw_ADDRESS_MASK(srcTrSize) & (uint32_t) pSrcAddr) {
+ srcTrWidth = dmacHw_GetNextTrWidth(srcTrWidth);
+ srcTrSize = dmacHw_GetTrWidthInBytes(srcTrWidth);
+ }
+
+ /* Find the maximum transaction per descriptor */
+ if (pConfig->maxDataPerBlock
+ && ((pConfig->maxDataPerBlock / srcTrSize) <
+ dmacHw_MAX_BLOCKSIZE)) {
+ maxBlockSize = pConfig->maxDataPerBlock / srcTrSize;
+ }
+
+ /* Find number of source transactions needed to complete the DMA transfer */
+ srcTs = dataLen / srcTrSize;
+ /* Find the odd number of bytes that need to be transferred as single byte transaction width */
+ if (srcTs && (dstTrSize > srcTrSize)) {
+ oddSize = dataLen % dstTrSize;
+ /* Adjust source transaction count due to "oddSize" */
+ srcTs = srcTs - (oddSize / srcTrSize);
+ } else {
+ oddSize = dataLen % srcTrSize;
+ }
+ /* Adjust "descCount" due to "oddSize" */
+ if (oddSize) {
+ descCount++;
+ }
+
+ /* Find the number of descriptor needed for total "srcTs" */
+ if (srcTs) {
+ descCount += ((srcTs - 1) / maxBlockSize) + 1;
+ }
+
+ return descCount;
+}
+
+/****************************************************************************/
+/**
+* @brief Check the existence of pending descriptor
+*
+* This function confirmes if there is any pending descriptor in the chain
+* to program the channel
+*
+* @return 1 : Channel need to be programmed with pending descriptor
+* 0 : No more pending descriptor to programe the channel
+*
+* @note
+* - This function should be called from ISR in case there are pending
+* descriptor to program the channel.
+*
+* Example:
+*
+* dmac_isr ()
+* {
+* ...
+* if (dmacHw_descriptorPending (handle))
+* {
+* dmacHw_initiateTransfer (handle);
+* }
+* }
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *pDescriptor /* [ IN ] Descriptor buffer */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+ /* Make sure channel is not busy */
+ if (!CHANNEL_BUSY(pCblk->module, pCblk->channel)) {
+ /* Check if pEnd is not processed */
+ if (pRing->pEnd) {
+ /* Something left for processing */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Program channel register to stop transfer
+*
+* Ensures the channel is not doing any transfer after calling this function
+*
+* @return void
+*
+*/
+/****************************************************************************/
+void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk;
+
+ pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ /* Stop the channel */
+ dmacHw_DMA_STOP(pCblk->module, pCblk->channel);
+}
+
+/****************************************************************************/
+/**
+* @brief Deallocates source or destination memory, allocated
+*
+* This function can be called to deallocate data memory that was DMAed successfully
+*
+* @return On failure : -1
+* On success : Number of buffer freed
+*
+* @note
+* This function will be called ONLY, when source OR destination address is pointing
+* to dynamic memory
+*/
+/****************************************************************************/
+int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */
+ ) {
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+ uint32_t count = 0;
+
+ if (fpFree == NULL) {
+ return -1;
+ }
+
+ while ((pRing->pFree != pRing->pTail)
+ && (pRing->pFree->ctl.lo & dmacHw_DESC_FREE)) {
+ if (pRing->pFree->devCtl == dmacHw_FREE_USER_MEMORY) {
+ /* Identify, which memory to free */
+ if (dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+ (*fpFree) ((void *)pRing->pFree->dar);
+ } else {
+ /* Destination was a peripheral */
+ (*fpFree) ((void *)pRing->pFree->sar);
+ }
+ /* Unmark user memory to indicate it is freed */
+ pRing->pFree->devCtl = ~dmacHw_FREE_USER_MEMORY;
+ }
+ dmacHw_NEXT_DESC(pRing, pFree);
+
+ count++;
+ }
+
+ return count;
+}
+
+/****************************************************************************/
+/**
+* @brief Prepares descriptor ring, when source peripheral working as a flow controller
+*
+* This function will update the discriptor ring by allocating buffers, when source peripheral
+* has to work as a flow controller to transfer data from:
+* - Peripheral to memory.
+*
+* @return On failure : -1
+* On success : Number of descriptor updated
+*
+*
+* @note
+* Channel must be configured for peripheral to memory transfer
+*
+*/
+/****************************************************************************/
+int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ uint32_t srcAddr, /* [ IN ] Source peripheral address */
+ void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */
+ int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */
+ int num /* [ IN ] Number of descriptor to set */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+ dmacHw_DESC_t *pProg = NULL;
+ dmacHw_DESC_t *pLast = NULL;
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+ uint32_t dstAddr;
+ uint32_t controlParam;
+ int i;
+
+ dmacHw_ASSERT(pConfig->transferType ==
+ dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM);
+
+ if (num > pRing->num) {
+ return -1;
+ }
+
+ pLast = pRing->pEnd; /* Last descriptor updated */
+ pProg = pRing->pHead; /* First descriptor in the new list */
+
+ controlParam = pConfig->srcUpdate |
+ pConfig->dstUpdate |
+ pConfig->srcMaxTransactionWidth |
+ pConfig->dstMaxTransactionWidth |
+ pConfig->srcMasterInterface |
+ pConfig->dstMasterInterface |
+ pConfig->srcMaxBurstWidth |
+ pConfig->dstMaxBurstWidth |
+ dmacHw_REG_CTL_TTFC_PM_PERI |
+ dmacHw_REG_CTL_LLP_DST_EN |
+ dmacHw_REG_CTL_LLP_SRC_EN | dmacHw_REG_CTL_INT_EN;
+
+ for (i = 0; i < num; i++) {
+ /* Allocate Rx buffer only for idle descriptor */
+ if (((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) ||
+ ((dmacHw_DESC_t *) pRing->pHead->llp == pRing->pTail)
+ ) {
+ /* Rx descriptor is not idle */
+ break;
+ }
+ /* Set source address */
+ pRing->pHead->sar = srcAddr;
+ if (fpAlloc) {
+ /* Allocate memory for buffer in descriptor */
+ dstAddr = (uint32_t) (*fpAlloc) (len);
+ /* Check the destination address */
+ if (dstAddr == 0) {
+ if (i == 0) {
+ /* Not a single descriptor is available */
+ return -1;
+ }
+ break;
+ }
+ /* Set destination address */
+ pRing->pHead->dar = dstAddr;
+ }
+ /* Set control information */
+ pRing->pHead->ctl.lo = controlParam;
+ /* Use "devCtl" to mark the memory that need to be freed later */
+ pRing->pHead->devCtl = dmacHw_FREE_USER_MEMORY;
+ /* Descriptor is now owned by the channel */
+ pRing->pHead->ctl.hi = 0;
+ /* Remember the descriptor last updated */
+ pRing->pEnd = pRing->pHead;
+ /* Update next descriptor */
+ dmacHw_NEXT_DESC(pRing, pHead);
+ }
+
+ /* Mark the end of the list */
+ pRing->pEnd->ctl.lo &=
+ ~(dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN);
+ /* Connect the list */
+ if (pLast != pProg) {
+ pLast->ctl.lo |=
+ dmacHw_REG_CTL_LLP_DST_EN | dmacHw_REG_CTL_LLP_SRC_EN;
+ }
+ /* Mark the descriptors are updated */
+ pCblk->descUpdated = 1;
+ if (!pCblk->varDataStarted) {
+ /* LLP must be pointing to the first descriptor */
+ dmacHw_SET_LLP(pCblk->module, pCblk->channel,
+ (uint32_t) pProg - pRing->virt2PhyOffset);
+ /* Channel, handling variable data started */
+ pCblk->varDataStarted = 1;
+ }
+
+ return i;
+}
+
+/****************************************************************************/
+/**
+* @brief Read data DMAed to memory
+*
+* This function will read data that has been DMAed to memory while transferring from:
+* - Memory to memory
+* - Peripheral to memory
+*
+* @param handle -
+* @param ppBbuf -
+* @param pLen -
+*
+* @return 0 - No more data is available to read
+* 1 - More data might be available to read
+*
+*/
+/****************************************************************************/
+int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void **ppBbuf, /* [ OUT ] Data received */
+ size_t *pLlen /* [ OUT ] Length of the data received */
+ ) {
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+ (void)handle;
+
+ if (pConfig->transferMode != dmacHw_TRANSFER_MODE_CONTINUOUS) {
+ if (((pRing->pTail->ctl.hi & dmacHw_DESC_FREE) == 0) ||
+ (pRing->pTail == pRing->pHead)
+ ) {
+ /* No receive data available */
+ *ppBbuf = (char *)NULL;
+ *pLlen = 0;
+
+ return 0;
+ }
+ }
+
+ /* Return read buffer and length */
+ *ppBbuf = (char *)pRing->pTail->dar;
+
+ /* Extract length of the received data */
+ if (DmaIsFlowController(pDescriptor)) {
+ uint32_t srcTrSize = 0;
+
+ switch (pRing->pTail->ctl.lo & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
+ case dmacHw_REG_CTL_SRC_TR_WIDTH_8:
+ srcTrSize = 1;
+ break;
+ case dmacHw_REG_CTL_SRC_TR_WIDTH_16:
+ srcTrSize = 2;
+ break;
+ case dmacHw_REG_CTL_SRC_TR_WIDTH_32:
+ srcTrSize = 4;
+ break;
+ case dmacHw_REG_CTL_SRC_TR_WIDTH_64:
+ srcTrSize = 8;
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ }
+ /* Calculate length from the block size */
+ *pLlen =
+ (pRing->pTail->ctl.hi & dmacHw_REG_CTL_BLOCK_TS_MASK) *
+ srcTrSize;
+ } else {
+ /* Extract length from the source peripheral */
+ *pLlen = pRing->pTail->sstat;
+ }
+
+ /* Advance tail to next descriptor */
+ dmacHw_NEXT_DESC(pRing, pTail);
+
+ return 1;
+}
+
+/****************************************************************************/
+/**
+* @brief Set descriptor carrying control information
+*
+* This function will be used to send specific control information to the device
+* using the DMA channel
+*
+*
+* @return -1 - On failure
+* 0 - On success
+*
+* @note
+* None
+*/
+/****************************************************************************/
+int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ uint32_t ctlAddress, /* [ IN ] Address of the device control register */
+ uint32_t control /* [ IN ] Device control information */
+ ) {
+ dmacHw_DESC_RING_t *pRing = dmacHw_GET_DESC_RING(pDescriptor);
+
+ if (ctlAddress == 0) {
+ return -1;
+ }
+
+ /* Check the availability of descriptors in the ring */
+ if ((pRing->pHead->ctl.hi & dmacHw_DESC_FREE) == 0) {
+ return -1;
+ }
+ /* Set control information */
+ pRing->pHead->devCtl = control;
+ /* Set source and destination address */
+ pRing->pHead->sar = (uint32_t) &pRing->pHead->devCtl;
+ pRing->pHead->dar = ctlAddress;
+ /* Set control parameters */
+ if (pConfig->flowControler == dmacHw_FLOW_CONTROL_DMA) {
+ pRing->pHead->ctl.lo = pConfig->transferType |
+ dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
+ dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
+ dmacHw_SRC_TRANSACTION_WIDTH_32 |
+ pConfig->dstMaxTransactionWidth |
+ dmacHw_SRC_BURST_WIDTH_0 |
+ dmacHw_DST_BURST_WIDTH_0 |
+ pConfig->srcMasterInterface |
+ pConfig->dstMasterInterface | dmacHw_REG_CTL_INT_EN;
+ } else {
+ uint32_t transferType = 0;
+ switch (pConfig->transferType) {
+ case dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM:
+ transferType = dmacHw_REG_CTL_TTFC_PM_PERI;
+ break;
+ case dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL:
+ transferType = dmacHw_REG_CTL_TTFC_MP_PERI;
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ }
+ pRing->pHead->ctl.lo = transferType |
+ dmacHw_SRC_ADDRESS_UPDATE_MODE_INC |
+ dmacHw_DST_ADDRESS_UPDATE_MODE_INC |
+ dmacHw_SRC_TRANSACTION_WIDTH_32 |
+ pConfig->dstMaxTransactionWidth |
+ dmacHw_SRC_BURST_WIDTH_0 |
+ dmacHw_DST_BURST_WIDTH_0 |
+ pConfig->srcMasterInterface |
+ pConfig->dstMasterInterface |
+ pConfig->flowControler | dmacHw_REG_CTL_INT_EN;
+ }
+
+ /* Set block transaction size to one 32 bit transaction */
+ pRing->pHead->ctl.hi = dmacHw_REG_CTL_BLOCK_TS_MASK & 1;
+
+ /* Remember the descriptor to initialize the registers */
+ if (pRing->pProg == dmacHw_DESC_INIT) {
+ pRing->pProg = pRing->pHead;
+ }
+ pRing->pEnd = pRing->pHead;
+
+ /* Advance the descriptor */
+ dmacHw_NEXT_DESC(pRing, pHead);
+
+ /* Update Tail pointer if destination is a peripheral */
+ if (!dmacHw_DST_IS_MEMORY(pConfig->transferType)) {
+ pRing->pTail = pRing->pHead;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Sets channel specific user data
+*
+* This function associates user data to a specific DMA channel
+*
+*/
+/****************************************************************************/
+void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *userData /* [ IN ] User data */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ pCblk->userData = userData;
+}
+
+/****************************************************************************/
+/**
+* @brief Gets channel specific user data
+*
+* This function returns user data specific to a DMA channel
+*
+* @return user data
+*/
+/****************************************************************************/
+void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ return pCblk->userData;
+}
+
+/****************************************************************************/
+/**
+* @brief Resets descriptor control information
+*
+* @return void
+*/
+/****************************************************************************/
+void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */
+ ) {
+ int i;
+ dmacHw_DESC_RING_t *pRing;
+ dmacHw_DESC_t *pDesc;
+
+ pRing = dmacHw_GET_DESC_RING(pDescriptor);
+ pDesc = pRing->pHead;
+
+ for (i = 0; i < pRing->num; i++) {
+ /* Mark descriptor is ready to use */
+ pDesc->ctl.hi = dmacHw_DESC_FREE;
+ /* Look into next link list item */
+ pDesc++;
+ }
+ pRing->pFree = pRing->pTail = pRing->pEnd = pRing->pHead;
+ pRing->pProg = dmacHw_DESC_INIT;
+}
+
+/****************************************************************************/
+/**
+* @brief Displays channel specific registers and other control parameters
+*
+* @return void
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
+ ) {
+ dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle);
+
+ DisplayRegisterContents(pCblk->module, pCblk->channel, fpPrint);
+ DisplayDescRing(pDescriptor, fpPrint);
+}
diff --git a/arch/arm/mach-bcmring/csp/tmr/Makefile b/arch/arm/mach-bcmring/csp/tmr/Makefile
new file mode 100644
index 00000000..244a61ab
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/Makefile
@@ -0,0 +1 @@
+obj-y += tmrHw.o
diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
new file mode 100644
index 00000000..16225e43
--- /dev/null
+++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c
@@ -0,0 +1,576 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file tmrHw.c
+*
+* @brief Low level Timer driver routines
+*
+* @note
+*
+* These routines provide basic timer functionality only.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/stdint.h>
+
+#include <csp/tmrHw.h>
+#include <mach/csp/tmrHw_reg.h>
+
+#define tmrHw_ASSERT(a) if (!(a)) *(char *)0 = 0
+#define tmrHw_MILLISEC_PER_SEC (1000)
+
+#define tmrHw_LOW_1_RESOLUTION_COUNT (tmrHw_LOW_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
+#define tmrHw_LOW_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_1_RESOLUTION_COUNT)
+#define tmrHw_LOW_16_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 16)
+#define tmrHw_LOW_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_16_RESOLUTION_COUNT)
+#define tmrHw_LOW_256_RESOLUTION_COUNT (tmrHw_LOW_1_RESOLUTION_COUNT / 256)
+#define tmrHw_LOW_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_LOW_256_RESOLUTION_COUNT)
+
+#define tmrHw_HIGH_1_RESOLUTION_COUNT (tmrHw_HIGH_RESOLUTION_CLOCK / tmrHw_MILLISEC_PER_SEC)
+#define tmrHw_HIGH_1_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_1_RESOLUTION_COUNT)
+#define tmrHw_HIGH_16_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 16)
+#define tmrHw_HIGH_16_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_16_RESOLUTION_COUNT)
+#define tmrHw_HIGH_256_RESOLUTION_COUNT (tmrHw_HIGH_1_RESOLUTION_COUNT / 256)
+#define tmrHw_HIGH_256_MAX_MILLISEC (0xFFFFFFFF / tmrHw_HIGH_256_RESOLUTION_COUNT)
+
+static void ResetTimer(tmrHw_ID_t timerId)
+ __attribute__ ((section(".aramtext")));
+static int tmrHw_divide(int num, int denom)
+ __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Get timer capability
+*
+* This function returns various capabilities/attributes of a timer
+*
+* @return Capability
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */
+) {
+ switch (capability) {
+ case tmrHw_CAPABILITY_CLOCK:
+ return (timerId <=
+ 1) ? tmrHw_LOW_RESOLUTION_CLOCK :
+ tmrHw_HIGH_RESOLUTION_CLOCK;
+ case tmrHw_CAPABILITY_RESOLUTION:
+ return 32;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Resets a timer
+*
+* This function initializes timer
+*
+* @return void
+*
+*/
+/****************************************************************************/
+static void ResetTimer(tmrHw_ID_t timerId /* [ IN ] Timer Id */
+) {
+ /* Reset timer */
+ pTmrHw[timerId].LoadValue = 0;
+ pTmrHw[timerId].CurrentValue = 0xFFFFFFFF;
+ pTmrHw[timerId].Control = 0;
+ pTmrHw[timerId].BackgroundLoad = 0;
+ /* Always configure as a 32 bit timer */
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_32BIT;
+ /* Clear interrupt only if raw status interrupt is set */
+ if (pTmrHw[timerId].RawInterruptStatus) {
+ pTmrHw[timerId].InterruptClear = 0xFFFFFFFF;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Sets counter value for an interval in ms
+*
+* @return On success: Effective counter value set
+* On failure: 0
+*
+*/
+/****************************************************************************/
+static tmrHw_INTERVAL_t SetTimerPeriod(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
+) {
+ uint32_t scale = 0;
+ uint32_t count = 0;
+
+ if (timerId == 0 || timerId == 1) {
+ if (msec <= tmrHw_LOW_1_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+ scale = tmrHw_LOW_1_RESOLUTION_COUNT;
+ } else if (msec <= tmrHw_LOW_16_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+ scale = tmrHw_LOW_16_RESOLUTION_COUNT;
+ } else if (msec <= tmrHw_LOW_256_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+ scale = tmrHw_LOW_256_RESOLUTION_COUNT;
+ } else {
+ return 0;
+ }
+
+ count = msec * scale;
+ /* Set counter value */
+ pTmrHw[timerId].LoadValue = count;
+ pTmrHw[timerId].BackgroundLoad = count;
+
+ } else if (timerId == 2 || timerId == 3) {
+ if (msec <= tmrHw_HIGH_1_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+ scale = tmrHw_HIGH_1_RESOLUTION_COUNT;
+ } else if (msec <= tmrHw_HIGH_16_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+ scale = tmrHw_HIGH_16_RESOLUTION_COUNT;
+ } else if (msec <= tmrHw_HIGH_256_MAX_MILLISEC) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+ scale = tmrHw_HIGH_256_RESOLUTION_COUNT;
+ } else {
+ return 0;
+ }
+
+ count = msec * scale;
+ /* Set counter value */
+ pTmrHw[timerId].LoadValue = count;
+ pTmrHw[timerId].BackgroundLoad = count;
+ }
+ return count / scale;
+}
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer in terms of timer interrupt rate
+*
+* This function initializes a periodic timer to generate specific number of
+* timer interrupt per second
+*
+* @return On success: Effective timer frequency
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */
+) {
+ uint32_t resolution = 0;
+ uint32_t count = 0;
+ ResetTimer(timerId);
+
+ /* Set timer mode periodic */
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+ /* Set timer in highest resolution */
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+
+ if (rate && (timerId == 0 || timerId == 1)) {
+ if (rate > tmrHw_LOW_RESOLUTION_CLOCK) {
+ return 0;
+ }
+ resolution = tmrHw_LOW_RESOLUTION_CLOCK;
+ } else if (rate && (timerId == 2 || timerId == 3)) {
+ if (rate > tmrHw_HIGH_RESOLUTION_CLOCK) {
+ return 0;
+ } else {
+ resolution = tmrHw_HIGH_RESOLUTION_CLOCK;
+ }
+ } else {
+ return 0;
+ }
+ /* Find the counter value */
+ count = resolution / rate;
+ /* Set counter value */
+ pTmrHw[timerId].LoadValue = count;
+ pTmrHw[timerId].BackgroundLoad = count;
+
+ return resolution / count;
+}
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer to generate timer interrupt after
+* certain time interval
+*
+* This function initializes a periodic timer to generate timer interrupt
+* after every time interval in millisecond
+*
+* @return On success: Effective interval set in milli-second
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
+) {
+ ResetTimer(timerId);
+
+ /* Set timer mode periodic */
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+
+ return SetTimerPeriod(timerId, msec);
+}
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer to generate timer interrupt just once
+* after certain time interval
+*
+* This function initializes a periodic timer to generate a single ticks after
+* certain time interval in millisecond
+*
+* @return On success: Effective interval set in milli-second
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_INTERVAL_t msec /* [ IN ] Interval in milli-second */
+) {
+ ResetTimer(timerId);
+
+ /* Set timer mode oneshot */
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PERIODIC;
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_ONESHOT;
+
+ return SetTimerPeriod(timerId, msec);
+}
+
+/****************************************************************************/
+/**
+* @brief Configures a timer to run as a free running timer
+*
+* This function initializes a timer to run as a free running timer
+*
+* @return Timer resolution (count / sec)
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ uint32_t divider /* [ IN ] Dividing the clock frequency */
+) {
+ uint32_t scale = 0;
+
+ ResetTimer(timerId);
+ /* Set timer as free running mode */
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_PERIODIC;
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_ONESHOT;
+
+ if (divider >= 64) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_256;
+ scale = 256;
+ } else if (divider >= 8) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_16;
+ scale = 16;
+ } else {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_PRESCALE_1;
+ scale = 1;
+ }
+
+ if (timerId == 0 || timerId == 1) {
+ return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, scale);
+ } else if (timerId == 2 || timerId == 3) {
+ return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, scale);
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Starts a timer
+*
+* This function starts a preconfigured timer
+*
+* @return -1 - On Failure
+* 0 - On Success
+*
+*/
+/****************************************************************************/
+int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_TIMER_ENABLE;
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Stops a timer
+*
+* This function stops a running timer
+*
+* @return -1 - On Failure
+* 0 - On Success
+*
+*/
+/****************************************************************************/
+int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_TIMER_ENABLE;
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Gets current timer count
+*
+* This function returns the current timer value
+*
+* @return Current downcounting timer value
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ /* return 32 bit timer value */
+ switch (pTmrHw[timerId].Control & tmrHw_CONTROL_MODE_MASK) {
+ case tmrHw_CONTROL_FREE_RUNNING:
+ if (pTmrHw[timerId].CurrentValue) {
+ return tmrHw_MAX_COUNT - pTmrHw[timerId].CurrentValue;
+ }
+ break;
+ case tmrHw_CONTROL_PERIODIC:
+ case tmrHw_CONTROL_ONESHOT:
+ return pTmrHw[timerId].BackgroundLoad -
+ pTmrHw[timerId].CurrentValue;
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Gets timer count rate
+*
+* This function returns the number of counts per second
+*
+* @return Count rate
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ uint32_t divider = 0;
+
+ switch (pTmrHw[timerId].Control & tmrHw_CONTROL_PRESCALE_MASK) {
+ case tmrHw_CONTROL_PRESCALE_1:
+ divider = 1;
+ break;
+ case tmrHw_CONTROL_PRESCALE_16:
+ divider = 16;
+ break;
+ case tmrHw_CONTROL_PRESCALE_256:
+ divider = 256;
+ break;
+ default:
+ tmrHw_ASSERT(0);
+ }
+
+ if (timerId == 0 || timerId == 1) {
+ return tmrHw_divide(tmrHw_LOW_RESOLUTION_CLOCK, divider);
+ } else {
+ return tmrHw_divide(tmrHw_HIGH_RESOLUTION_CLOCK, divider);
+ }
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Enables timer interrupt
+*
+* This function enables the timer interrupt
+*
+* @return N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ pTmrHw[timerId].Control |= tmrHw_CONTROL_INTERRUPT_ENABLE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disables timer interrupt
+*
+* This function disable the timer interrupt
+*
+* @return N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ pTmrHw[timerId].Control &= ~tmrHw_CONTROL_INTERRUPT_ENABLE;
+}
+
+/****************************************************************************/
+/**
+* @brief Clears the interrupt
+*
+* This function clears the timer interrupt
+*
+* @return N/A
+*
+* @note
+* Must be called under the context of ISR
+*/
+/****************************************************************************/
+void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ pTmrHw[timerId].InterruptClear = 0x1;
+}
+
+/****************************************************************************/
+/**
+* @brief Gets the interrupt status
+*
+* This function returns timer interrupt status
+*
+* @return Interrupt status
+*/
+/****************************************************************************/
+tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) {
+ if (pTmrHw[timerId].InterruptStatus) {
+ return tmrHw_INTERRUPT_STATUS_SET;
+ } else {
+ return tmrHw_INTERRUPT_STATUS_UNSET;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Indentifies a timer causing interrupt
+*
+* This functions returns a timer causing interrupt
+*
+* @return 0xFFFFFFFF : No timer causing an interrupt
+* ! 0xFFFFFFFF : timer causing an interrupt
+* @note
+* tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
+*/
+/****************************************************************************/
+tmrHw_ID_t tmrHw_getInterruptSource(void /* void */
+) {
+ int i;
+
+ for (i = 0; i < tmrHw_TIMER_NUM_COUNT; i++) {
+ if (pTmrHw[i].InterruptStatus) {
+ return i;
+ }
+ }
+
+ return 0xFFFFFFFF;
+}
+
+/****************************************************************************/
+/**
+* @brief Displays specific timer registers
+*
+*
+* @return void
+*
+*/
+/****************************************************************************/
+void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
+) {
+ (*fpPrint) ("Displaying register contents \n\n");
+ (*fpPrint) ("Timer %d: Load value 0x%X\n", timerId,
+ pTmrHw[timerId].LoadValue);
+ (*fpPrint) ("Timer %d: Background load value 0x%X\n", timerId,
+ pTmrHw[timerId].BackgroundLoad);
+ (*fpPrint) ("Timer %d: Control 0x%X\n", timerId,
+ pTmrHw[timerId].Control);
+ (*fpPrint) ("Timer %d: Interrupt clear 0x%X\n", timerId,
+ pTmrHw[timerId].InterruptClear);
+ (*fpPrint) ("Timer %d: Interrupt raw interrupt 0x%X\n", timerId,
+ pTmrHw[timerId].RawInterruptStatus);
+ (*fpPrint) ("Timer %d: Interrupt status 0x%X\n", timerId,
+ pTmrHw[timerId].InterruptStatus);
+}
+
+/****************************************************************************/
+/**
+* @brief Use a timer to perform a busy wait delay for a number of usecs.
+*
+* @return N/A
+*/
+/****************************************************************************/
+void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */
+ unsigned long usecs /* [ IN ] usec to delay */
+) {
+ tmrHw_RATE_t usec_tick_rate;
+ tmrHw_COUNT_t start_time;
+ tmrHw_COUNT_t delta_time;
+
+ start_time = tmrHw_GetCurrentCount(timerId);
+ usec_tick_rate = tmrHw_divide(tmrHw_getCountRate(timerId), 1000000);
+ delta_time = usecs * usec_tick_rate;
+
+ /* Busy wait */
+ while (delta_time > (tmrHw_GetCurrentCount(timerId) - start_time))
+ ;
+}
+
+/****************************************************************************/
+/**
+* @brief Local Divide function
+*
+* This function does the divide
+*
+* @return divide value
+*
+*/
+/****************************************************************************/
+static int tmrHw_divide(int num, int denom)
+{
+ int r;
+ int t = 1;
+
+ /* Shift denom and t up to the largest value to optimize algorithm */
+ /* t contains the units of each divide */
+ while ((denom & 0x40000000) == 0) { /* fails if denom=0 */
+ denom = denom << 1;
+ t = t << 1;
+ }
+
+ /* Initialize the result */
+ r = 0;
+
+ do {
+ /* Determine if there exists a positive remainder */
+ if ((num - denom) >= 0) {
+ /* Accumlate t to the result and calculate a new remainder */
+ num = num - denom;
+ r = r + t;
+ }
+ /* Continue to shift denom and shift t down to 0 */
+ denom = denom >> 1;
+ t = t >> 1;
+ } while (t != 0);
+ return r;
+}
diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c
new file mode 100644
index 00000000..d87ad30d
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma.c
@@ -0,0 +1,2329 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dma.c
+*
+* @brief Implements the DMA interface.
+*/
+/****************************************************************************/
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+
+#include <mach/timer.h>
+
+#include <linux/mm.h>
+#include <linux/pfn.h>
+#include <asm/atomic.h>
+#include <mach/dma.h>
+
+/* I don't quite understand why dc4 fails when this is set to 1 and DMA is enabled */
+/* especially since dc4 doesn't use kmalloc'd memory. */
+
+#define ALLOW_MAP_OF_KMALLOC_MEMORY 0
+
+/* ---- Public Variables ------------------------------------------------- */
+
+/* ---- Private Constants and Types -------------------------------------- */
+
+#define MAKE_HANDLE(controllerIdx, channelIdx) (((controllerIdx) << 4) | (channelIdx))
+
+#define CONTROLLER_FROM_HANDLE(handle) (((handle) >> 4) & 0x0f)
+#define CHANNEL_FROM_HANDLE(handle) ((handle) & 0x0f)
+
+#define DMA_MAP_DEBUG 0
+
+#if DMA_MAP_DEBUG
+# define DMA_MAP_PRINT(fmt, args...) printk("%s: " fmt, __func__, ## args)
+#else
+# define DMA_MAP_PRINT(fmt, args...)
+#endif
+
+/* ---- Private Variables ------------------------------------------------ */
+
+static DMA_Global_t gDMA;
+static struct proc_dir_entry *gDmaDir;
+
+static atomic_t gDmaStatMemTypeKmalloc = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeVmalloc = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeUser = ATOMIC_INIT(0);
+static atomic_t gDmaStatMemTypeCoherent = ATOMIC_INIT(0);
+
+#include "dma_device.c"
+
+/* ---- Private Function Prototypes -------------------------------------- */
+
+/* ---- Functions ------------------------------------------------------- */
+
+/****************************************************************************/
+/**
+* Displays information for /proc/dma/mem-type
+*/
+/****************************************************************************/
+
+static int dma_proc_read_mem_type(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len += sprintf(buf + len, "dma_map_mem statistics\n");
+ len +=
+ sprintf(buf + len, "coherent: %d\n",
+ atomic_read(&gDmaStatMemTypeCoherent));
+ len +=
+ sprintf(buf + len, "kmalloc: %d\n",
+ atomic_read(&gDmaStatMemTypeKmalloc));
+ len +=
+ sprintf(buf + len, "vmalloc: %d\n",
+ atomic_read(&gDmaStatMemTypeVmalloc));
+ len +=
+ sprintf(buf + len, "user: %d\n",
+ atomic_read(&gDmaStatMemTypeUser));
+
+ return len;
+}
+
+/****************************************************************************/
+/**
+* Displays information for /proc/dma/channels
+*/
+/****************************************************************************/
+
+static int dma_proc_read_channels(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int controllerIdx;
+ int channelIdx;
+ int limit = count - 200;
+ int len = 0;
+ DMA_Channel_t *channel;
+
+ if (down_interruptible(&gDMA.lock) < 0) {
+ return -ERESTARTSYS;
+ }
+
+ for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+ controllerIdx++) {
+ for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+ channelIdx++) {
+ if (len >= limit) {
+ break;
+ }
+
+ channel =
+ &gDMA.controller[controllerIdx].channel[channelIdx];
+
+ len +=
+ sprintf(buf + len, "%d:%d ", controllerIdx,
+ channelIdx);
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
+ 0) {
+ len +=
+ sprintf(buf + len, "Dedicated for %s ",
+ DMA_gDeviceAttribute[channel->
+ devType].name);
+ } else {
+ len += sprintf(buf + len, "Shared ");
+ }
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) != 0) {
+ len += sprintf(buf + len, "No ISR ");
+ }
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_LARGE_FIFO) != 0) {
+ len += sprintf(buf + len, "Fifo: 128 ");
+ } else {
+ len += sprintf(buf + len, "Fifo: 64 ");
+ }
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
+ len +=
+ sprintf(buf + len, "InUse by %s",
+ DMA_gDeviceAttribute[channel->
+ devType].name);
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ len +=
+ sprintf(buf + len, " (%s:%d)",
+ channel->fileName,
+ channel->lineNum);
+#endif
+ } else {
+ len += sprintf(buf + len, "Avail ");
+ }
+
+ if (channel->lastDevType != DMA_DEVICE_NONE) {
+ len +=
+ sprintf(buf + len, "Last use: %s ",
+ DMA_gDeviceAttribute[channel->
+ lastDevType].
+ name);
+ }
+
+ len += sprintf(buf + len, "\n");
+ }
+ }
+ up(&gDMA.lock);
+ *eof = 1;
+
+ return len;
+}
+
+/****************************************************************************/
+/**
+* Displays information for /proc/dma/devices
+*/
+/****************************************************************************/
+
+static int dma_proc_read_devices(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int limit = count - 200;
+ int len = 0;
+ int devIdx;
+
+ if (down_interruptible(&gDMA.lock) < 0) {
+ return -ERESTARTSYS;
+ }
+
+ for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
+ DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
+
+ if (devAttr->name == NULL) {
+ continue;
+ }
+
+ if (len >= limit) {
+ break;
+ }
+
+ len += sprintf(buf + len, "%-12s ", devAttr->name);
+
+ if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+ len +=
+ sprintf(buf + len, "Dedicated %d:%d ",
+ devAttr->dedicatedController,
+ devAttr->dedicatedChannel);
+ } else {
+ len += sprintf(buf + len, "Shared DMA:");
+ if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA0) != 0) {
+ len += sprintf(buf + len, "0");
+ }
+ if ((devAttr->flags & DMA_DEVICE_FLAG_ON_DMA1) != 0) {
+ len += sprintf(buf + len, "1");
+ }
+ len += sprintf(buf + len, " ");
+ }
+ if ((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0) {
+ len += sprintf(buf + len, "NoISR ");
+ }
+ if ((devAttr->flags & DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO) != 0) {
+ len += sprintf(buf + len, "Allow-128 ");
+ }
+
+ len +=
+ sprintf(buf + len,
+ "Xfer #: %Lu Ticks: %Lu Bytes: %Lu DescLen: %u\n",
+ devAttr->numTransfers, devAttr->transferTicks,
+ devAttr->transferBytes,
+ devAttr->ring.bytesAllocated);
+
+ }
+
+ up(&gDMA.lock);
+ *eof = 1;
+
+ return len;
+}
+
+/****************************************************************************/
+/**
+* Determines if a DMA_Device_t is "valid".
+*
+* @return
+* TRUE - dma device is valid
+* FALSE - dma device isn't valid
+*/
+/****************************************************************************/
+
+static inline int IsDeviceValid(DMA_Device_t device)
+{
+ return (device >= 0) && (device < DMA_NUM_DEVICE_ENTRIES);
+}
+
+/****************************************************************************/
+/**
+* Translates a DMA handle into a pointer to a channel.
+*
+* @return
+* non-NULL - pointer to DMA_Channel_t
+* NULL - DMA Handle was invalid
+*/
+/****************************************************************************/
+
+static inline DMA_Channel_t *HandleToChannel(DMA_Handle_t handle)
+{
+ int controllerIdx;
+ int channelIdx;
+
+ controllerIdx = CONTROLLER_FROM_HANDLE(handle);
+ channelIdx = CHANNEL_FROM_HANDLE(handle);
+
+ if ((controllerIdx > DMA_NUM_CONTROLLERS)
+ || (channelIdx > DMA_NUM_CHANNELS)) {
+ return NULL;
+ }
+ return &gDMA.controller[controllerIdx].channel[channelIdx];
+}
+
+/****************************************************************************/
+/**
+* Interrupt handler which is called to process DMA interrupts.
+*/
+/****************************************************************************/
+
+static irqreturn_t dma_interrupt_handler(int irq, void *dev_id)
+{
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+ int irqStatus;
+
+ channel = (DMA_Channel_t *) dev_id;
+
+ /* Figure out why we were called, and knock down the interrupt */
+
+ irqStatus = dmacHw_getInterruptStatus(channel->dmacHwHandle);
+ dmacHw_clearInterrupt(channel->dmacHwHandle);
+
+ if ((channel->devType < 0)
+ || (channel->devType > DMA_NUM_DEVICE_ENTRIES)) {
+ printk(KERN_ERR "dma_interrupt_handler: Invalid devType: %d\n",
+ channel->devType);
+ return IRQ_NONE;
+ }
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ /* Update stats */
+
+ if ((irqStatus & dmacHw_INTERRUPT_STATUS_TRANS) != 0) {
+ devAttr->transferTicks +=
+ (timer_get_tick_count() - devAttr->transferStartTime);
+ }
+
+ if ((irqStatus & dmacHw_INTERRUPT_STATUS_ERROR) != 0) {
+ printk(KERN_ERR
+ "dma_interrupt_handler: devType :%d DMA error (%s)\n",
+ channel->devType, devAttr->name);
+ } else {
+ devAttr->numTransfers++;
+ devAttr->transferBytes += devAttr->numBytes;
+ }
+
+ /* Call any installed handler */
+
+ if (devAttr->devHandler != NULL) {
+ devAttr->devHandler(channel->devType, irqStatus,
+ devAttr->userData);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/****************************************************************************/
+/**
+* Allocates memory to hold a descriptor ring. The descriptor ring then
+* needs to be populated by making one or more calls to
+* dna_add_descriptors.
+*
+* The returned descriptor ring will be automatically initialized.
+*
+* @return
+* 0 Descriptor ring was allocated successfully
+* -EINVAL Invalid parameters passed in
+* -ENOMEM Unable to allocate memory for the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */
+ int numDescriptors /* Number of descriptors that need to be allocated. */
+ ) {
+ size_t bytesToAlloc = dmacHw_descriptorLen(numDescriptors);
+
+ if ((ring == NULL) || (numDescriptors <= 0)) {
+ return -EINVAL;
+ }
+
+ ring->physAddr = 0;
+ ring->descriptorsAllocated = 0;
+ ring->bytesAllocated = 0;
+
+ ring->virtAddr = dma_alloc_writecombine(NULL,
+ bytesToAlloc,
+ &ring->physAddr,
+ GFP_KERNEL);
+ if (ring->virtAddr == NULL) {
+ return -ENOMEM;
+ }
+
+ ring->bytesAllocated = bytesToAlloc;
+ ring->descriptorsAllocated = numDescriptors;
+
+ return dma_init_descriptor_ring(ring, numDescriptors);
+}
+
+EXPORT_SYMBOL(dma_alloc_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Releases the memory which was previously allocated for a descriptor ring.
+*/
+/****************************************************************************/
+
+void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */
+ ) {
+ if (ring->virtAddr != NULL) {
+ dma_free_writecombine(NULL,
+ ring->bytesAllocated,
+ ring->virtAddr, ring->physAddr);
+ }
+
+ ring->bytesAllocated = 0;
+ ring->descriptorsAllocated = 0;
+ ring->virtAddr = NULL;
+ ring->physAddr = 0;
+}
+
+EXPORT_SYMBOL(dma_free_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Initializes a descriptor ring, so that descriptors can be added to it.
+* Once a descriptor ring has been allocated, it may be reinitialized for
+* use with additional/different regions of memory.
+*
+* Note that if 7 descriptors are allocated, it's perfectly acceptable to
+* initialize the ring with a smaller number of descriptors. The amount
+* of memory allocated for the descriptor ring will not be reduced, and
+* the descriptor ring may be reinitialized later
+*
+* @return
+* 0 Descriptor ring was initialized successfully
+* -ENOMEM The descriptor which was passed in has insufficient space
+* to hold the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */
+ int numDescriptors /* Number of descriptors to initialize. */
+ ) {
+ if (ring->virtAddr == NULL) {
+ return -EINVAL;
+ }
+ if (dmacHw_initDescriptor(ring->virtAddr,
+ ring->physAddr,
+ ring->bytesAllocated, numDescriptors) < 0) {
+ printk(KERN_ERR
+ "dma_init_descriptor_ring: dmacHw_initDescriptor failed\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_init_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Determines the number of descriptors which would be required for a
+* transfer of the indicated memory region.
+*
+* This function also needs to know which DMA device this transfer will
+* be destined for, so that the appropriate DMA configuration can be retrieved.
+* DMA parameters such as transfer width, and whether this is a memory-to-memory
+* or memory-to-peripheral, etc can all affect the actual number of descriptors
+* required.
+*
+* @return
+* > 0 Returns the number of descriptors required for the indicated transfer
+* -ENODEV - Device handed in is invalid.
+* -EINVAL Invalid parameters
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ ) {
+ int numDescriptors;
+ DMA_DeviceAttribute_t *devAttr;
+
+ if (!IsDeviceValid(device)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[device];
+
+ numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
+ (void *)srcData,
+ (void *)dstData,
+ numBytes);
+ if (numDescriptors < 0) {
+ printk(KERN_ERR
+ "dma_calculate_descriptor_count: dmacHw_calculateDescriptorCount failed\n");
+ return -EINVAL;
+ }
+
+ return numDescriptors;
+}
+
+EXPORT_SYMBOL(dma_calculate_descriptor_count);
+
+/****************************************************************************/
+/**
+* Adds a region of memory to the descriptor ring. Note that it may take
+* multiple descriptors for each region of memory. It is the callers
+* responsibility to allocate a sufficiently large descriptor ring.
+*
+* @return
+* 0 Descriptors were added successfully
+* -ENODEV Device handed in is invalid.
+* -EINVAL Invalid parameters
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */
+ DMA_Device_t device, /* DMA Device that descriptors are for */
+ dma_addr_t srcData, /* Place to get data (memory or device) */
+ dma_addr_t dstData, /* Place to put data (memory or device) */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ ) {
+ int rc;
+ DMA_DeviceAttribute_t *devAttr;
+
+ if (!IsDeviceValid(device)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[device];
+
+ rc = dmacHw_setDataDescriptor(&devAttr->config,
+ ring->virtAddr,
+ (void *)srcData,
+ (void *)dstData, numBytes);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "dma_add_descriptors: dmacHw_setDataDescriptor failed with code: %d\n",
+ rc);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_add_descriptors);
+
+/****************************************************************************/
+/**
+* Sets the descriptor ring associated with a device.
+*
+* Once set, the descriptor ring will be associated with the device, even
+* across channel request/free calls. Passing in a NULL descriptor ring
+* will release any descriptor ring currently associated with the device.
+*
+* Note: If you call dma_transfer, or one of the other dma_alloc_ functions
+* the descriptor ring may be released and reallocated.
+*
+* Note: This function will release the descriptor memory for any current
+* descriptor ring associated with this device.
+*
+* @return
+* 0 Descriptors were added successfully
+* -ENODEV Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */
+ DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */
+ ) {
+ DMA_DeviceAttribute_t *devAttr;
+
+ if (!IsDeviceValid(device)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[device];
+
+ /* Free the previously allocated descriptor ring */
+
+ dma_free_descriptor_ring(&devAttr->ring);
+
+ if (ring != NULL) {
+ /* Copy in the new one */
+
+ devAttr->ring = *ring;
+ }
+
+ /* Set things up so that if dma_transfer is called then this descriptor */
+ /* ring will get freed. */
+
+ devAttr->prevSrcData = 0;
+ devAttr->prevDstData = 0;
+ devAttr->prevNumBytes = 0;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_set_device_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Retrieves the descriptor ring associated with a device.
+*
+* @return
+* 0 Descriptors were added successfully
+* -ENODEV Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */
+ DMA_DescriptorRing_t *ring /* Place to store retrieved ring */
+ ) {
+ DMA_DeviceAttribute_t *devAttr;
+
+ memset(ring, 0, sizeof(*ring));
+
+ if (!IsDeviceValid(device)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[device];
+
+ *ring = devAttr->ring;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_get_device_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Configures a DMA channel.
+*
+* @return
+* >= 0 - Initialization was successful.
+*
+* -EBUSY - Device is currently being used.
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+static int ConfigChannel(DMA_Handle_t handle)
+{
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+ int controllerIdx;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+ controllerIdx = CONTROLLER_FROM_HANDLE(handle);
+
+ if ((devAttr->flags & DMA_DEVICE_FLAG_PORT_PER_DMAC) != 0) {
+ if (devAttr->config.transferType ==
+ dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL) {
+ devAttr->config.dstPeripheralPort =
+ devAttr->dmacPort[controllerIdx];
+ } else if (devAttr->config.transferType ==
+ dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) {
+ devAttr->config.srcPeripheralPort =
+ devAttr->dmacPort[controllerIdx];
+ }
+ }
+
+ if (dmacHw_configChannel(channel->dmacHwHandle, &devAttr->config) != 0) {
+ printk(KERN_ERR "ConfigChannel: dmacHw_configChannel failed\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* Initializes all of the data structures associated with the DMA.
+* @return
+* >= 0 - Initialization was successful.
+*
+* -EBUSY - Device is currently being used.
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_init(void)
+{
+ int rc = 0;
+ int controllerIdx;
+ int channelIdx;
+ DMA_Device_t devIdx;
+ DMA_Channel_t *channel;
+ DMA_Handle_t dedicatedHandle;
+
+ memset(&gDMA, 0, sizeof(gDMA));
+
+ sema_init(&gDMA.lock, 0);
+ init_waitqueue_head(&gDMA.freeChannelQ);
+
+ /* Initialize the Hardware */
+
+ dmacHw_initDma();
+
+ /* Start off by marking all of the DMA channels as shared. */
+
+ for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+ controllerIdx++) {
+ for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+ channelIdx++) {
+ channel =
+ &gDMA.controller[controllerIdx].channel[channelIdx];
+
+ channel->flags = 0;
+ channel->devType = DMA_DEVICE_NONE;
+ channel->lastDevType = DMA_DEVICE_NONE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ channel->fileName = "";
+ channel->lineNum = 0;
+#endif
+
+ channel->dmacHwHandle =
+ dmacHw_getChannelHandle(dmacHw_MAKE_CHANNEL_ID
+ (controllerIdx,
+ channelIdx));
+ dmacHw_initChannel(channel->dmacHwHandle);
+ }
+ }
+
+ /* Record any special attributes that channels may have */
+
+ gDMA.controller[0].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+ gDMA.controller[0].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+ gDMA.controller[1].channel[0].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+ gDMA.controller[1].channel[1].flags |= DMA_CHANNEL_FLAG_LARGE_FIFO;
+
+ /* Now walk through and record the dedicated channels. */
+
+ for (devIdx = 0; devIdx < DMA_NUM_DEVICE_ENTRIES; devIdx++) {
+ DMA_DeviceAttribute_t *devAttr = &DMA_gDeviceAttribute[devIdx];
+
+ if (((devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) != 0)
+ && ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0)) {
+ printk(KERN_ERR
+ "DMA Device: %s Can only request NO_ISR for dedicated devices\n",
+ devAttr->name);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+ /* This is a dedicated device. Mark the channel as being reserved. */
+
+ if (devAttr->dedicatedController >= DMA_NUM_CONTROLLERS) {
+ printk(KERN_ERR
+ "DMA Device: %s DMA Controller %d is out of range\n",
+ devAttr->name,
+ devAttr->dedicatedController);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (devAttr->dedicatedChannel >= DMA_NUM_CHANNELS) {
+ printk(KERN_ERR
+ "DMA Device: %s DMA Channel %d is out of range\n",
+ devAttr->name,
+ devAttr->dedicatedChannel);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ dedicatedHandle =
+ MAKE_HANDLE(devAttr->dedicatedController,
+ devAttr->dedicatedChannel);
+ channel = HandleToChannel(dedicatedHandle);
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) !=
+ 0) {
+ printk
+ ("DMA Device: %s attempting to use same DMA Controller:Channel (%d:%d) as %s\n",
+ devAttr->name,
+ devAttr->dedicatedController,
+ devAttr->dedicatedChannel,
+ DMA_gDeviceAttribute[channel->devType].
+ name);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ channel->flags |= DMA_CHANNEL_FLAG_IS_DEDICATED;
+ channel->devType = devIdx;
+
+ if (devAttr->flags & DMA_DEVICE_FLAG_NO_ISR) {
+ channel->flags |= DMA_CHANNEL_FLAG_NO_ISR;
+ }
+
+ /* For dedicated channels, we can go ahead and configure the DMA channel now */
+ /* as well. */
+
+ ConfigChannel(dedicatedHandle);
+ }
+ }
+
+ /* Go through and register the interrupt handlers */
+
+ for (controllerIdx = 0; controllerIdx < DMA_NUM_CONTROLLERS;
+ controllerIdx++) {
+ for (channelIdx = 0; channelIdx < DMA_NUM_CHANNELS;
+ channelIdx++) {
+ channel =
+ &gDMA.controller[controllerIdx].channel[channelIdx];
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_NO_ISR) == 0) {
+ snprintf(channel->name, sizeof(channel->name),
+ "dma %d:%d %s", controllerIdx,
+ channelIdx,
+ channel->devType ==
+ DMA_DEVICE_NONE ? "" :
+ DMA_gDeviceAttribute[channel->devType].
+ name);
+
+ rc =
+ request_irq(IRQ_DMA0C0 +
+ (controllerIdx *
+ DMA_NUM_CHANNELS) +
+ channelIdx,
+ dma_interrupt_handler,
+ IRQF_DISABLED, channel->name,
+ channel);
+ if (rc != 0) {
+ printk(KERN_ERR
+ "request_irq for IRQ_DMA%dC%d failed\n",
+ controllerIdx, channelIdx);
+ }
+ }
+ }
+ }
+
+ /* Create /proc/dma/channels and /proc/dma/devices */
+
+ gDmaDir = create_proc_entry("dma", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+
+ if (gDmaDir == NULL) {
+ printk(KERN_ERR "Unable to create /proc/dma\n");
+ } else {
+ create_proc_read_entry("channels", 0, gDmaDir,
+ dma_proc_read_channels, NULL);
+ create_proc_read_entry("devices", 0, gDmaDir,
+ dma_proc_read_devices, NULL);
+ create_proc_read_entry("mem-type", 0, gDmaDir,
+ dma_proc_read_mem_type, NULL);
+ }
+
+out:
+
+ up(&gDMA.lock);
+
+ return rc;
+}
+
+/****************************************************************************/
+/**
+* Reserves a channel for use with @a dev. If the device is setup to use
+* a shared channel, then this function will block until a free channel
+* becomes available.
+*
+* @return
+* >= 0 - A valid DMA Handle.
+* -EBUSY - Device is currently being used.
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+DMA_Handle_t dma_request_channel_dbg
+ (DMA_Device_t dev, const char *fileName, int lineNum)
+#else
+DMA_Handle_t dma_request_channel(DMA_Device_t dev)
+#endif
+{
+ DMA_Handle_t handle;
+ DMA_DeviceAttribute_t *devAttr;
+ DMA_Channel_t *channel;
+ int controllerIdx;
+ int controllerIdx2;
+ int channelIdx;
+
+ if (down_interruptible(&gDMA.lock) < 0) {
+ return -ERESTARTSYS;
+ }
+
+ if ((dev < 0) || (dev >= DMA_NUM_DEVICE_ENTRIES)) {
+ handle = -ENODEV;
+ goto out;
+ }
+ devAttr = &DMA_gDeviceAttribute[dev];
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ {
+ char *s;
+
+ s = strrchr(fileName, '/');
+ if (s != NULL) {
+ fileName = s + 1;
+ }
+ }
+#endif
+ if ((devAttr->flags & DMA_DEVICE_FLAG_IN_USE) != 0) {
+ /* This device has already been requested and not been freed */
+
+ printk(KERN_ERR "%s: device %s is already requested\n",
+ __func__, devAttr->name);
+ handle = -EBUSY;
+ goto out;
+ }
+
+ if ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) != 0) {
+ /* This device has a dedicated channel. */
+
+ channel =
+ &gDMA.controller[devAttr->dedicatedController].
+ channel[devAttr->dedicatedChannel];
+ if ((channel->flags & DMA_CHANNEL_FLAG_IN_USE) != 0) {
+ handle = -EBUSY;
+ goto out;
+ }
+
+ channel->flags |= DMA_CHANNEL_FLAG_IN_USE;
+ devAttr->flags |= DMA_DEVICE_FLAG_IN_USE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ channel->fileName = fileName;
+ channel->lineNum = lineNum;
+#endif
+ handle =
+ MAKE_HANDLE(devAttr->dedicatedController,
+ devAttr->dedicatedChannel);
+ goto out;
+ }
+
+ /* This device needs to use one of the shared channels. */
+
+ handle = DMA_INVALID_HANDLE;
+ while (handle == DMA_INVALID_HANDLE) {
+ /* Scan through the shared channels and see if one is available */
+
+ for (controllerIdx2 = 0; controllerIdx2 < DMA_NUM_CONTROLLERS;
+ controllerIdx2++) {
+ /* Check to see if we should try on controller 1 first. */
+
+ controllerIdx = controllerIdx2;
+ if ((devAttr->
+ flags & DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST) != 0) {
+ controllerIdx = 1 - controllerIdx;
+ }
+
+ /* See if the device is available on the controller being tested */
+
+ if ((devAttr->
+ flags & (DMA_DEVICE_FLAG_ON_DMA0 << controllerIdx))
+ != 0) {
+ for (channelIdx = 0;
+ channelIdx < DMA_NUM_CHANNELS;
+ channelIdx++) {
+ channel =
+ &gDMA.controller[controllerIdx].
+ channel[channelIdx];
+
+ if (((channel->
+ flags &
+ DMA_CHANNEL_FLAG_IS_DEDICATED) ==
+ 0)
+ &&
+ ((channel->
+ flags & DMA_CHANNEL_FLAG_IN_USE)
+ == 0)) {
+ if (((channel->
+ flags &
+ DMA_CHANNEL_FLAG_LARGE_FIFO)
+ != 0)
+ &&
+ ((devAttr->
+ flags &
+ DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO)
+ == 0)) {
+ /* This channel is a large fifo - don't tie it up */
+ /* with devices that we don't want using it. */
+
+ continue;
+ }
+
+ channel->flags |=
+ DMA_CHANNEL_FLAG_IN_USE;
+ channel->devType = dev;
+ devAttr->flags |=
+ DMA_DEVICE_FLAG_IN_USE;
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ channel->fileName = fileName;
+ channel->lineNum = lineNum;
+#endif
+ handle =
+ MAKE_HANDLE(controllerIdx,
+ channelIdx);
+
+ /* Now that we've reserved the channel - we can go ahead and configure it */
+
+ if (ConfigChannel(handle) != 0) {
+ handle = -EIO;
+ printk(KERN_ERR
+ "dma_request_channel: ConfigChannel failed\n");
+ }
+ goto out;
+ }
+ }
+ }
+ }
+
+ /* No channels are currently available. Let's wait for one to free up. */
+
+ {
+ DEFINE_WAIT(wait);
+
+ prepare_to_wait(&gDMA.freeChannelQ, &wait,
+ TASK_INTERRUPTIBLE);
+ up(&gDMA.lock);
+ schedule();
+ finish_wait(&gDMA.freeChannelQ, &wait);
+
+ if (signal_pending(current)) {
+ /* We don't currently hold gDMA.lock, so we return directly */
+
+ return -ERESTARTSYS;
+ }
+ }
+
+ if (down_interruptible(&gDMA.lock)) {
+ return -ERESTARTSYS;
+ }
+ }
+
+out:
+ up(&gDMA.lock);
+
+ return handle;
+}
+
+/* Create both _dbg and non _dbg functions for modules. */
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+#undef dma_request_channel
+DMA_Handle_t dma_request_channel(DMA_Device_t dev)
+{
+ return dma_request_channel_dbg(dev, __FILE__, __LINE__);
+}
+
+EXPORT_SYMBOL(dma_request_channel_dbg);
+#endif
+EXPORT_SYMBOL(dma_request_channel);
+
+/****************************************************************************/
+/**
+* Frees a previously allocated DMA Handle.
+*/
+/****************************************************************************/
+
+int dma_free_channel(DMA_Handle_t handle /* DMA handle. */
+ ) {
+ int rc = 0;
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+
+ if (down_interruptible(&gDMA.lock) < 0) {
+ return -ERESTARTSYS;
+ }
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ if ((channel->flags & DMA_CHANNEL_FLAG_IS_DEDICATED) == 0) {
+ channel->lastDevType = channel->devType;
+ channel->devType = DMA_DEVICE_NONE;
+ }
+ channel->flags &= ~DMA_CHANNEL_FLAG_IN_USE;
+ devAttr->flags &= ~DMA_DEVICE_FLAG_IN_USE;
+
+out:
+ up(&gDMA.lock);
+
+ wake_up_interruptible(&gDMA.freeChannelQ);
+
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_free_channel);
+
+/****************************************************************************/
+/**
+* Determines if a given device has been configured as using a shared
+* channel.
+*
+* @return
+* 0 Device uses a dedicated channel
+* > zero Device uses a shared channel
+* < zero Error code
+*/
+/****************************************************************************/
+
+int dma_device_is_channel_shared(DMA_Device_t device /* Device to check. */
+ ) {
+ DMA_DeviceAttribute_t *devAttr;
+
+ if (!IsDeviceValid(device)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[device];
+
+ return ((devAttr->flags & DMA_DEVICE_FLAG_IS_DEDICATED) == 0);
+}
+
+EXPORT_SYMBOL(dma_device_is_channel_shared);
+
+/****************************************************************************/
+/**
+* Allocates buffers for the descriptors. This is normally done automatically
+* but needs to be done explicitly when initiating a dma from interrupt
+* context.
+*
+* @return
+* 0 Descriptors were allocated successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */
+ dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ ) {
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+ int numDescriptors;
+ size_t ringBytesRequired;
+ int rc = 0;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ if (devAttr->config.transferType != transferType) {
+ return -EINVAL;
+ }
+
+ /* Figure out how many descriptors we need. */
+
+ /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
+ /* srcData, dstData, numBytes); */
+
+ numDescriptors = dmacHw_calculateDescriptorCount(&devAttr->config,
+ (void *)srcData,
+ (void *)dstData,
+ numBytes);
+ if (numDescriptors < 0) {
+ printk(KERN_ERR "%s: dmacHw_calculateDescriptorCount failed\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
+ /* a new one. */
+
+ ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
+
+ /* printk("ringBytesRequired: %d\n", ringBytesRequired); */
+
+ if (ringBytesRequired > devAttr->ring.bytesAllocated) {
+ /* Make sure that this code path is never taken from interrupt context. */
+ /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
+ /* allocation needs to have already been done. */
+
+ might_sleep();
+
+ /* Free the old descriptor ring and allocate a new one. */
+
+ dma_free_descriptor_ring(&devAttr->ring);
+
+ /* And allocate a new one. */
+
+ rc =
+ dma_alloc_descriptor_ring(&devAttr->ring,
+ numDescriptors);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_alloc_descriptor_ring(%d) failed\n",
+ __func__, numDescriptors);
+ return rc;
+ }
+ /* Setup the descriptor for this transfer */
+
+ if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
+ devAttr->ring.physAddr,
+ devAttr->ring.bytesAllocated,
+ numDescriptors) < 0) {
+ printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n",
+ __func__);
+ return -EINVAL;
+ }
+ } else {
+ /* We've already got enough ring buffer allocated. All we need to do is reset */
+ /* any control information, just in case the previous DMA was stopped. */
+
+ dmacHw_resetDescriptorControl(devAttr->ring.virtAddr);
+ }
+
+ /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
+ /* as last time, then we don't need to call setDataDescriptor again. */
+
+ if (dmacHw_setDataDescriptor(&devAttr->config,
+ devAttr->ring.virtAddr,
+ (void *)srcData,
+ (void *)dstData, numBytes) < 0) {
+ printk(KERN_ERR "%s: dmacHw_setDataDescriptor failed\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* Remember the critical information for this transfer so that we can eliminate */
+ /* another call to dma_alloc_descriptors if the caller reuses the same buffers */
+
+ devAttr->prevSrcData = srcData;
+ devAttr->prevDstData = dstData;
+ devAttr->prevNumBytes = numBytes;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_alloc_descriptors);
+
+/****************************************************************************/
+/**
+* Allocates and sets up descriptors for a double buffered circular buffer.
+*
+* This is primarily intended to be used for things like the ingress samples
+* from a microphone.
+*
+* @return
+* > 0 Number of descriptors actually allocated.
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
+ dma_addr_t srcData, /* Physical address of source data */
+ dma_addr_t dstData1, /* Physical address of first destination buffer */
+ dma_addr_t dstData2, /* Physical address of second destination buffer */
+ size_t numBytes /* Number of bytes in each destination buffer */
+ ) {
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+ int numDst1Descriptors;
+ int numDst2Descriptors;
+ int numDescriptors;
+ size_t ringBytesRequired;
+ int rc = 0;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ /* Figure out how many descriptors we need. */
+
+ /* printk("srcData: 0x%08x dstData: 0x%08x, numBytes: %d\n", */
+ /* srcData, dstData, numBytes); */
+
+ numDst1Descriptors =
+ dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
+ (void *)dstData1, numBytes);
+ if (numDst1Descriptors < 0) {
+ return -EINVAL;
+ }
+ numDst2Descriptors =
+ dmacHw_calculateDescriptorCount(&devAttr->config, (void *)srcData,
+ (void *)dstData2, numBytes);
+ if (numDst2Descriptors < 0) {
+ return -EINVAL;
+ }
+ numDescriptors = numDst1Descriptors + numDst2Descriptors;
+ /* printk("numDescriptors: %d\n", numDescriptors); */
+
+ /* Check to see if we can reuse the existing descriptor ring, or if we need to allocate */
+ /* a new one. */
+
+ ringBytesRequired = dmacHw_descriptorLen(numDescriptors);
+
+ /* printk("ringBytesRequired: %d\n", ringBytesRequired); */
+
+ if (ringBytesRequired > devAttr->ring.bytesAllocated) {
+ /* Make sure that this code path is never taken from interrupt context. */
+ /* It's OK for an interrupt to initiate a DMA transfer, but the descriptor */
+ /* allocation needs to have already been done. */
+
+ might_sleep();
+
+ /* Free the old descriptor ring and allocate a new one. */
+
+ dma_free_descriptor_ring(&devAttr->ring);
+
+ /* And allocate a new one. */
+
+ rc =
+ dma_alloc_descriptor_ring(&devAttr->ring,
+ numDescriptors);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_alloc_descriptor_ring(%d) failed\n",
+ __func__, ringBytesRequired);
+ return rc;
+ }
+ }
+
+ /* Setup the descriptor for this transfer. Since this function is used with */
+ /* CONTINUOUS DMA operations, we need to reinitialize every time, otherwise */
+ /* setDataDescriptor will keep trying to append onto the end. */
+
+ if (dmacHw_initDescriptor(devAttr->ring.virtAddr,
+ devAttr->ring.physAddr,
+ devAttr->ring.bytesAllocated,
+ numDescriptors) < 0) {
+ printk(KERN_ERR "%s: dmacHw_initDescriptor failed\n", __func__);
+ return -EINVAL;
+ }
+
+ /* dma_alloc/free both set the prevSrc/DstData to 0. If they happen to be the same */
+ /* as last time, then we don't need to call setDataDescriptor again. */
+
+ if (dmacHw_setDataDescriptor(&devAttr->config,
+ devAttr->ring.virtAddr,
+ (void *)srcData,
+ (void *)dstData1, numBytes) < 0) {
+ printk(KERN_ERR "%s: dmacHw_setDataDescriptor 1 failed\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (dmacHw_setDataDescriptor(&devAttr->config,
+ devAttr->ring.virtAddr,
+ (void *)srcData,
+ (void *)dstData2, numBytes) < 0) {
+ printk(KERN_ERR "%s: dmacHw_setDataDescriptor 2 failed\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* You should use dma_start_transfer rather than dma_transfer_xxx so we don't */
+ /* try to make the 'prev' variables right. */
+
+ devAttr->prevSrcData = 0;
+ devAttr->prevDstData = 0;
+ devAttr->prevNumBytes = 0;
+
+ return numDescriptors;
+}
+
+EXPORT_SYMBOL(dma_alloc_double_dst_descriptors);
+
+/****************************************************************************/
+/**
+* Initiates a transfer when the descriptors have already been setup.
+*
+* This is a special case, and normally, the dma_transfer_xxx functions should
+* be used.
+*
+* @return
+* 0 Transfer was started successfully
+* -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_start_transfer(DMA_Handle_t handle)
+{
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
+ devAttr->ring.virtAddr);
+
+ /* Since we got this far, everything went successfully */
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_start_transfer);
+
+/****************************************************************************/
+/**
+* Stops a previously started DMA transfer.
+*
+* @return
+* 0 Transfer was stopped successfully
+* -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_stop_transfer(DMA_Handle_t handle)
+{
+ DMA_Channel_t *channel;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+
+ dmacHw_stopTransfer(channel->dmacHwHandle);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_stop_transfer);
+
+/****************************************************************************/
+/**
+* Waits for a DMA to complete by polling. This function is only intended
+* to be used for testing. Interrupts should be used for most DMA operations.
+*/
+/****************************************************************************/
+
+int dma_wait_transfer_done(DMA_Handle_t handle)
+{
+ DMA_Channel_t *channel;
+ dmacHw_TRANSFER_STATUS_e status;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+
+ while ((status =
+ dmacHw_transferCompleted(channel->dmacHwHandle)) ==
+ dmacHw_TRANSFER_STATUS_BUSY) {
+ ;
+ }
+
+ if (status == dmacHw_TRANSFER_STATUS_ERROR) {
+ printk(KERN_ERR "%s: DMA transfer failed\n", __func__);
+ return -EIO;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_wait_transfer_done);
+
+/****************************************************************************/
+/**
+* Initiates a DMA, allocating the descriptors as required.
+*
+* @return
+* 0 Transfer was started successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
+*/
+/****************************************************************************/
+
+int dma_transfer(DMA_Handle_t handle, /* DMA Handle */
+ dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ ) {
+ DMA_Channel_t *channel;
+ DMA_DeviceAttribute_t *devAttr;
+ int rc = 0;
+
+ channel = HandleToChannel(handle);
+ if (channel == NULL) {
+ return -ENODEV;
+ }
+
+ devAttr = &DMA_gDeviceAttribute[channel->devType];
+
+ if (devAttr->config.transferType != transferType) {
+ return -EINVAL;
+ }
+
+ /* We keep track of the information about the previous request for this */
+ /* device, and if the attributes match, then we can use the descriptors we setup */
+ /* the last time, and not have to reinitialize everything. */
+
+ {
+ rc =
+ dma_alloc_descriptors(handle, transferType, srcData,
+ dstData, numBytes);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+
+ /* And kick off the transfer */
+
+ devAttr->numBytes = numBytes;
+ devAttr->transferStartTime = timer_get_tick_count();
+
+ dmacHw_initiateTransfer(channel->dmacHwHandle, &devAttr->config,
+ devAttr->ring.virtAddr);
+
+ /* Since we got this far, everything went successfully */
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_transfer);
+
+/****************************************************************************/
+/**
+* Set the callback function which will be called when a transfer completes.
+* If a NULL callback function is set, then no callback will occur.
+*
+* @note @a devHandler will be called from IRQ context.
+*
+* @return
+* 0 - Success
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */
+ DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */
+ void *userData /* Pointer which will be passed to devHandler. */
+ ) {
+ DMA_DeviceAttribute_t *devAttr;
+ unsigned long flags;
+
+ if (!IsDeviceValid(dev)) {
+ return -ENODEV;
+ }
+ devAttr = &DMA_gDeviceAttribute[dev];
+
+ local_irq_save(flags);
+
+ devAttr->userData = userData;
+ devAttr->devHandler = devHandler;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_set_device_handler);
+
+/****************************************************************************/
+/**
+* Initializes a memory mapping structure
+*/
+/****************************************************************************/
+
+int dma_init_mem_map(DMA_MemMap_t *memMap)
+{
+ memset(memMap, 0, sizeof(*memMap));
+
+ sema_init(&memMap->lock, 1);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_init_mem_map);
+
+/****************************************************************************/
+/**
+* Releases any memory currently being held by a memory mapping structure.
+*/
+/****************************************************************************/
+
+int dma_term_mem_map(DMA_MemMap_t *memMap)
+{
+ down(&memMap->lock); /* Just being paranoid */
+
+ /* Free up any allocated memory */
+
+ up(&memMap->lock);
+ memset(memMap, 0, sizeof(*memMap));
+
+ return 0;
+}
+
+EXPORT_SYMBOL(dma_term_mem_map);
+
+/****************************************************************************/
+/**
+* Looks at a memory address and categorizes it.
+*
+* @return One of the values from the DMA_MemType_t enumeration.
+*/
+/****************************************************************************/
+
+DMA_MemType_t dma_mem_type(void *addr)
+{
+ unsigned long addrVal = (unsigned long)addr;
+
+ if (addrVal >= VMALLOC_END) {
+ /* NOTE: DMA virtual memory space starts at 0xFFxxxxxx */
+
+ /* dma_alloc_xxx pages are physically and virtually contiguous */
+
+ return DMA_MEM_TYPE_DMA;
+ }
+
+ /* Technically, we could add one more classification. Addresses between VMALLOC_END */
+ /* and the beginning of the DMA virtual address could be considered to be I/O space. */
+ /* Right now, nobody cares about this particular classification, so we ignore it. */
+
+ if (is_vmalloc_addr(addr)) {
+ /* Address comes from the vmalloc'd region. Pages are virtually */
+ /* contiguous but NOT physically contiguous */
+
+ return DMA_MEM_TYPE_VMALLOC;
+ }
+
+ if (addrVal >= PAGE_OFFSET) {
+ /* PAGE_OFFSET is typically 0xC0000000 */
+
+ /* kmalloc'd pages are physically contiguous */
+
+ return DMA_MEM_TYPE_KMALLOC;
+ }
+
+ return DMA_MEM_TYPE_USER;
+}
+
+EXPORT_SYMBOL(dma_mem_type);
+
+/****************************************************************************/
+/**
+* Looks at a memory address and determines if we support DMA'ing to/from
+* that type of memory.
+*
+* @return boolean -
+* return value != 0 means dma supported
+* return value == 0 means dma not supported
+*/
+/****************************************************************************/
+
+int dma_mem_supports_dma(void *addr)
+{
+ DMA_MemType_t memType = dma_mem_type(addr);
+
+ return (memType == DMA_MEM_TYPE_DMA)
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+ || (memType == DMA_MEM_TYPE_KMALLOC)
+#endif
+ || (memType == DMA_MEM_TYPE_USER);
+}
+
+EXPORT_SYMBOL(dma_mem_supports_dma);
+
+/****************************************************************************/
+/**
+* Maps in a memory region such that it can be used for performing a DMA.
+*
+* @return
+*/
+/****************************************************************************/
+
+int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ enum dma_data_direction dir /* Direction that the mapping will be going */
+ ) {
+ int rc;
+
+ down(&memMap->lock);
+
+ DMA_MAP_PRINT("memMap: %p\n", memMap);
+
+ if (memMap->inUse) {
+ printk(KERN_ERR "%s: memory map %p is already being used\n",
+ __func__, memMap);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ memMap->inUse = 1;
+ memMap->dir = dir;
+ memMap->numRegionsUsed = 0;
+
+ rc = 0;
+
+out:
+
+ DMA_MAP_PRINT("returning %d", rc);
+
+ up(&memMap->lock);
+
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_map_start);
+
+/****************************************************************************/
+/**
+* Adds a segment of memory to a memory map. Each segment is both
+* physically and virtually contiguous.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+static int dma_map_add_segment(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ DMA_Region_t *region, /* Region that the segment belongs to */
+ void *virtAddr, /* Virtual address of the segment being added */
+ dma_addr_t physAddr, /* Physical address of the segment being added */
+ size_t numBytes /* Number of bytes of the segment being added */
+ ) {
+ DMA_Segment_t *segment;
+
+ DMA_MAP_PRINT("memMap:%p va:%p pa:0x%x #:%d\n", memMap, virtAddr,
+ physAddr, numBytes);
+
+ /* Sanity check */
+
+ if (((unsigned long)virtAddr < (unsigned long)region->virtAddr)
+ || (((unsigned long)virtAddr + numBytes)) >
+ ((unsigned long)region->virtAddr + region->numBytes)) {
+ printk(KERN_ERR
+ "%s: virtAddr %p is outside region @ %p len: %d\n",
+ __func__, virtAddr, region->virtAddr, region->numBytes);
+ return -EINVAL;
+ }
+
+ if (region->numSegmentsUsed > 0) {
+ /* Check to see if this segment is physically contiguous with the previous one */
+
+ segment = &region->segment[region->numSegmentsUsed - 1];
+
+ if ((segment->physAddr + segment->numBytes) == physAddr) {
+ /* It is - just add on to the end */
+
+ DMA_MAP_PRINT("appending %d bytes to last segment\n",
+ numBytes);
+
+ segment->numBytes += numBytes;
+
+ return 0;
+ }
+ }
+
+ /* Reallocate to hold more segments, if required. */
+
+ if (region->numSegmentsUsed >= region->numSegmentsAllocated) {
+ DMA_Segment_t *newSegment;
+ size_t oldSize =
+ region->numSegmentsAllocated * sizeof(*newSegment);
+ int newAlloc = region->numSegmentsAllocated + 4;
+ size_t newSize = newAlloc * sizeof(*newSegment);
+
+ newSegment = kmalloc(newSize, GFP_KERNEL);
+ if (newSegment == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(newSegment, region->segment, oldSize);
+ memset(&((uint8_t *) newSegment)[oldSize], 0,
+ newSize - oldSize);
+ kfree(region->segment);
+
+ region->numSegmentsAllocated = newAlloc;
+ region->segment = newSegment;
+ }
+
+ segment = &region->segment[region->numSegmentsUsed];
+ region->numSegmentsUsed++;
+
+ segment->virtAddr = virtAddr;
+ segment->physAddr = physAddr;
+ segment->numBytes = numBytes;
+
+ DMA_MAP_PRINT("returning success\n");
+
+ return 0;
+}
+
+/****************************************************************************/
+/**
+* Adds a region of memory to a memory map. Each region is virtually
+* contiguous, but not necessarily physically contiguous.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ void *mem, /* Virtual address that we want to get a map of */
+ size_t numBytes /* Number of bytes being mapped */
+ ) {
+ unsigned long addr = (unsigned long)mem;
+ unsigned int offset;
+ int rc = 0;
+ DMA_Region_t *region;
+ dma_addr_t physAddr;
+
+ down(&memMap->lock);
+
+ DMA_MAP_PRINT("memMap:%p va:%p #:%d\n", memMap, mem, numBytes);
+
+ if (!memMap->inUse) {
+ printk(KERN_ERR "%s: Make sure you call dma_map_start first\n",
+ __func__);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ /* Reallocate to hold more regions. */
+
+ if (memMap->numRegionsUsed >= memMap->numRegionsAllocated) {
+ DMA_Region_t *newRegion;
+ size_t oldSize =
+ memMap->numRegionsAllocated * sizeof(*newRegion);
+ int newAlloc = memMap->numRegionsAllocated + 4;
+ size_t newSize = newAlloc * sizeof(*newRegion);
+
+ newRegion = kmalloc(newSize, GFP_KERNEL);
+ if (newRegion == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy(newRegion, memMap->region, oldSize);
+ memset(&((uint8_t *) newRegion)[oldSize], 0, newSize - oldSize);
+
+ kfree(memMap->region);
+
+ memMap->numRegionsAllocated = newAlloc;
+ memMap->region = newRegion;
+ }
+
+ region = &memMap->region[memMap->numRegionsUsed];
+ memMap->numRegionsUsed++;
+
+ offset = addr & ~PAGE_MASK;
+
+ region->memType = dma_mem_type(mem);
+ region->virtAddr = mem;
+ region->numBytes = numBytes;
+ region->numSegmentsUsed = 0;
+ region->numLockedPages = 0;
+ region->lockedPages = NULL;
+
+ switch (region->memType) {
+ case DMA_MEM_TYPE_VMALLOC:
+ {
+ atomic_inc(&gDmaStatMemTypeVmalloc);
+
+ /* printk(KERN_ERR "%s: vmalloc'd pages are not supported\n", __func__); */
+
+ /* vmalloc'd pages are not physically contiguous */
+
+ rc = -EINVAL;
+ break;
+ }
+
+ case DMA_MEM_TYPE_KMALLOC:
+ {
+ atomic_inc(&gDmaStatMemTypeKmalloc);
+
+ /* kmalloc'd pages are physically contiguous, so they'll have exactly */
+ /* one segment */
+
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+ physAddr =
+ dma_map_single(NULL, mem, numBytes, memMap->dir);
+ rc = dma_map_add_segment(memMap, region, mem, physAddr,
+ numBytes);
+#else
+ rc = -EINVAL;
+#endif
+ break;
+ }
+
+ case DMA_MEM_TYPE_DMA:
+ {
+ /* dma_alloc_xxx pages are physically contiguous */
+
+ atomic_inc(&gDmaStatMemTypeCoherent);
+
+ physAddr = (vmalloc_to_pfn(mem) << PAGE_SHIFT) + offset;
+
+ dma_sync_single_for_cpu(NULL, physAddr, numBytes,
+ memMap->dir);
+ rc = dma_map_add_segment(memMap, region, mem, physAddr,
+ numBytes);
+ break;
+ }
+
+ case DMA_MEM_TYPE_USER:
+ {
+ size_t firstPageOffset;
+ size_t firstPageSize;
+ struct page **pages;
+ struct task_struct *userTask;
+
+ atomic_inc(&gDmaStatMemTypeUser);
+
+#if 1
+ /* If the pages are user pages, then the dma_mem_map_set_user_task function */
+ /* must have been previously called. */
+
+ if (memMap->userTask == NULL) {
+ printk(KERN_ERR
+ "%s: must call dma_mem_map_set_user_task when using user-mode memory\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* User pages need to be locked. */
+
+ firstPageOffset =
+ (unsigned long)region->virtAddr & (PAGE_SIZE - 1);
+ firstPageSize = PAGE_SIZE - firstPageOffset;
+
+ region->numLockedPages = (firstPageOffset
+ + region->numBytes +
+ PAGE_SIZE - 1) / PAGE_SIZE;
+ pages =
+ kmalloc(region->numLockedPages *
+ sizeof(struct page *), GFP_KERNEL);
+
+ if (pages == NULL) {
+ region->numLockedPages = 0;
+ return -ENOMEM;
+ }
+
+ userTask = memMap->userTask;
+
+ down_read(&userTask->mm->mmap_sem);
+ rc = get_user_pages(userTask, /* task */
+ userTask->mm, /* mm */
+ (unsigned long)region->virtAddr, /* start */
+ region->numLockedPages, /* len */
+ memMap->dir == DMA_FROM_DEVICE, /* write */
+ 0, /* force */
+ pages, /* pages (array of pointers to page) */
+ NULL); /* vmas */
+ up_read(&userTask->mm->mmap_sem);
+
+ if (rc != region->numLockedPages) {
+ kfree(pages);
+ region->numLockedPages = 0;
+
+ if (rc >= 0) {
+ rc = -EINVAL;
+ }
+ } else {
+ uint8_t *virtAddr = region->virtAddr;
+ size_t bytesRemaining;
+ int pageIdx;
+
+ rc = 0; /* Since get_user_pages returns +ve number */
+
+ region->lockedPages = pages;
+
+ /* We've locked the user pages. Now we need to walk them and figure */
+ /* out the physical addresses. */
+
+ /* The first page may be partial */
+
+ dma_map_add_segment(memMap,
+ region,
+ virtAddr,
+ PFN_PHYS(page_to_pfn
+ (pages[0])) +
+ firstPageOffset,
+ firstPageSize);
+
+ virtAddr += firstPageSize;
+ bytesRemaining =
+ region->numBytes - firstPageSize;
+
+ for (pageIdx = 1;
+ pageIdx < region->numLockedPages;
+ pageIdx++) {
+ size_t bytesThisPage =
+ (bytesRemaining >
+ PAGE_SIZE ? PAGE_SIZE :
+ bytesRemaining);
+
+ DMA_MAP_PRINT
+ ("pageIdx:%d pages[pageIdx]=%p pfn=%u phys=%u\n",
+ pageIdx, pages[pageIdx],
+ page_to_pfn(pages[pageIdx]),
+ PFN_PHYS(page_to_pfn
+ (pages[pageIdx])));
+
+ dma_map_add_segment(memMap,
+ region,
+ virtAddr,
+ PFN_PHYS(page_to_pfn
+ (pages
+ [pageIdx])),
+ bytesThisPage);
+
+ virtAddr += bytesThisPage;
+ bytesRemaining -= bytesThisPage;
+ }
+ }
+#else
+ printk(KERN_ERR
+ "%s: User mode pages are not yet supported\n",
+ __func__);
+
+ /* user pages are not physically contiguous */
+
+ rc = -EINVAL;
+#endif
+ break;
+ }
+
+ default:
+ {
+ printk(KERN_ERR "%s: Unsupported memory type: %d\n",
+ __func__, region->memType);
+
+ rc = -EINVAL;
+ break;
+ }
+ }
+
+ if (rc != 0) {
+ memMap->numRegionsUsed--;
+ }
+
+out:
+
+ DMA_MAP_PRINT("returning %d\n", rc);
+
+ up(&memMap->lock);
+
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_map_add_segment);
+
+/****************************************************************************/
+/**
+* Maps in a memory region such that it can be used for performing a DMA.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ void *mem, /* Virtual address that we want to get a map of */
+ size_t numBytes, /* Number of bytes being mapped */
+ enum dma_data_direction dir /* Direction that the mapping will be going */
+ ) {
+ int rc;
+
+ rc = dma_map_start(memMap, dir);
+ if (rc == 0) {
+ rc = dma_map_add_region(memMap, mem, numBytes);
+ if (rc < 0) {
+ /* Since the add fails, this function will fail, and the caller won't */
+ /* call unmap, so we need to do it here. */
+
+ dma_unmap(memMap, 0);
+ }
+ }
+
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_map_mem);
+
+/****************************************************************************/
+/**
+* Setup a descriptor ring for a given memory map.
+*
+* It is assumed that the descriptor ring has already been initialized, and
+* this routine will only reallocate a new descriptor ring if the existing
+* one is too small.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
+ DMA_MemMap_t *memMap, /* Memory map that will be used */
+ dma_addr_t devPhysAddr /* Physical address of device */
+ ) {
+ int rc;
+ int numDescriptors;
+ DMA_DeviceAttribute_t *devAttr;
+ DMA_Region_t *region;
+ DMA_Segment_t *segment;
+ dma_addr_t srcPhysAddr;
+ dma_addr_t dstPhysAddr;
+ int regionIdx;
+ int segmentIdx;
+
+ devAttr = &DMA_gDeviceAttribute[dev];
+
+ down(&memMap->lock);
+
+ /* Figure out how many descriptors we need */
+
+ numDescriptors = 0;
+ for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+ region = &memMap->region[regionIdx];
+
+ for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+ segmentIdx++) {
+ segment = &region->segment[segmentIdx];
+
+ if (memMap->dir == DMA_TO_DEVICE) {
+ srcPhysAddr = segment->physAddr;
+ dstPhysAddr = devPhysAddr;
+ } else {
+ srcPhysAddr = devPhysAddr;
+ dstPhysAddr = segment->physAddr;
+ }
+
+ rc =
+ dma_calculate_descriptor_count(dev, srcPhysAddr,
+ dstPhysAddr,
+ segment->
+ numBytes);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_calculate_descriptor_count failed: %d\n",
+ __func__, rc);
+ goto out;
+ }
+ numDescriptors += rc;
+ }
+ }
+
+ /* Adjust the size of the ring, if it isn't big enough */
+
+ if (numDescriptors > devAttr->ring.descriptorsAllocated) {
+ dma_free_descriptor_ring(&devAttr->ring);
+ rc =
+ dma_alloc_descriptor_ring(&devAttr->ring,
+ numDescriptors);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_alloc_descriptor_ring failed: %d\n",
+ __func__, rc);
+ goto out;
+ }
+ } else {
+ rc =
+ dma_init_descriptor_ring(&devAttr->ring,
+ numDescriptors);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_init_descriptor_ring failed: %d\n",
+ __func__, rc);
+ goto out;
+ }
+ }
+
+ /* Populate the descriptors */
+
+ for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+ region = &memMap->region[regionIdx];
+
+ for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+ segmentIdx++) {
+ segment = &region->segment[segmentIdx];
+
+ if (memMap->dir == DMA_TO_DEVICE) {
+ srcPhysAddr = segment->physAddr;
+ dstPhysAddr = devPhysAddr;
+ } else {
+ srcPhysAddr = devPhysAddr;
+ dstPhysAddr = segment->physAddr;
+ }
+
+ rc =
+ dma_add_descriptors(&devAttr->ring, dev,
+ srcPhysAddr, dstPhysAddr,
+ segment->numBytes);
+ if (rc < 0) {
+ printk(KERN_ERR
+ "%s: dma_add_descriptors failed: %d\n",
+ __func__, rc);
+ goto out;
+ }
+ }
+ }
+
+ rc = 0;
+
+out:
+
+ up(&memMap->lock);
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_map_create_descriptor_ring);
+
+/****************************************************************************/
+/**
+* Maps in a memory region such that it can be used for performing a DMA.
+*
+* @return
+*/
+/****************************************************************************/
+
+int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ int dirtied /* non-zero if any of the pages were modified */
+ ) {
+
+ int rc = 0;
+ int regionIdx;
+ int segmentIdx;
+ DMA_Region_t *region;
+ DMA_Segment_t *segment;
+
+ down(&memMap->lock);
+
+ for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
+ region = &memMap->region[regionIdx];
+
+ for (segmentIdx = 0; segmentIdx < region->numSegmentsUsed;
+ segmentIdx++) {
+ segment = &region->segment[segmentIdx];
+
+ switch (region->memType) {
+ case DMA_MEM_TYPE_VMALLOC:
+ {
+ printk(KERN_ERR
+ "%s: vmalloc'd pages are not yet supported\n",
+ __func__);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ case DMA_MEM_TYPE_KMALLOC:
+ {
+#if ALLOW_MAP_OF_KMALLOC_MEMORY
+ dma_unmap_single(NULL,
+ segment->physAddr,
+ segment->numBytes,
+ memMap->dir);
+#endif
+ break;
+ }
+
+ case DMA_MEM_TYPE_DMA:
+ {
+ dma_sync_single_for_cpu(NULL,
+ segment->
+ physAddr,
+ segment->
+ numBytes,
+ memMap->dir);
+ break;
+ }
+
+ case DMA_MEM_TYPE_USER:
+ {
+ /* Nothing to do here. */
+
+ break;
+ }
+
+ default:
+ {
+ printk(KERN_ERR
+ "%s: Unsupported memory type: %d\n",
+ __func__, region->memType);
+ rc = -EINVAL;
+ goto out;
+ }
+ }
+
+ segment->virtAddr = NULL;
+ segment->physAddr = 0;
+ segment->numBytes = 0;
+ }
+
+ if (region->numLockedPages > 0) {
+ int pageIdx;
+
+ /* Some user pages were locked. We need to go and unlock them now. */
+
+ for (pageIdx = 0; pageIdx < region->numLockedPages;
+ pageIdx++) {
+ struct page *page =
+ region->lockedPages[pageIdx];
+
+ if (memMap->dir == DMA_FROM_DEVICE) {
+ SetPageDirty(page);
+ }
+ page_cache_release(page);
+ }
+ kfree(region->lockedPages);
+ region->numLockedPages = 0;
+ region->lockedPages = NULL;
+ }
+
+ region->memType = DMA_MEM_TYPE_NONE;
+ region->virtAddr = NULL;
+ region->numBytes = 0;
+ region->numSegmentsUsed = 0;
+ }
+ memMap->userTask = NULL;
+ memMap->numRegionsUsed = 0;
+ memMap->inUse = 0;
+
+out:
+ up(&memMap->lock);
+
+ return rc;
+}
+
+EXPORT_SYMBOL(dma_unmap);
diff --git a/arch/arm/mach-bcmring/dma_device.c b/arch/arm/mach-bcmring/dma_device.c
new file mode 100644
index 00000000..ca0ad736
--- /dev/null
+++ b/arch/arm/mach-bcmring/dma_device.c
@@ -0,0 +1,593 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dma_device.c
+*
+* @brief private array of DMA_DeviceAttribute_t
+*/
+/****************************************************************************/
+
+DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES] = {
+ [DMA_DEVICE_MEM_TO_MEM] = /* MEM 2 MEM */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "mem-to-mem",
+ .config = {
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+
+ },
+ },
+ [DMA_DEVICE_VPM_MEM_TO_MEM] = /* VPM */
+ {
+ .flags = DMA_DEVICE_FLAG_IS_DEDICATED | DMA_DEVICE_FLAG_NO_ISR,
+ .name = "vpm",
+ .dedicatedController = 0,
+ .dedicatedChannel = 0,
+ /* reserve DMA0:0 for VPM */
+ },
+ [DMA_DEVICE_NAND_MEM_TO_MEM] = /* NAND */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "nand",
+ .config = {
+ .srcPeripheralPort = 0,
+ .dstPeripheralPort = 0,
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_6,
+ },
+ },
+ [DMA_DEVICE_PIF_MEM_TO_DEV] = /* PIF TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
+ | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
+ | DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST | DMA_DEVICE_FLAG_PORT_PER_DMAC,
+ .name = "pif_tx",
+ .dmacPort = {14, 5},
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ /* dstPeripheralPort = 5 or 14 */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ .maxDataPerBlock = 16256,
+ },
+ },
+ [DMA_DEVICE_PIF_DEV_TO_MEM] = /* PIF RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1
+ | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO
+ /* DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST */
+ | DMA_DEVICE_FLAG_PORT_PER_DMAC,
+ .name = "pif_rx",
+ .dmacPort = {14, 5},
+ .config = {
+ /* srcPeripheralPort = 5 or 14 */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ .maxDataPerBlock = 16256,
+ },
+ },
+ [DMA_DEVICE_I2S0_DEV_TO_MEM] = /* I2S RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "i2s0_rx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: I2S0 */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_I2S0_MEM_TO_DEV] = /* I2S TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "i2s0_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 1, /* DST: I2S0 */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_I2S1_DEV_TO_MEM] = /* I2S1 RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "i2s1_rx",
+ .config = {
+ .srcPeripheralPort = 2, /* SRC: I2S1 */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_I2S1_MEM_TO_DEV] = /* I2S1 TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "i2s1_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 3, /* DST: I2S1 */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_ESW_MEM_TO_DEV] = /* ESW TX */
+ {
+ .name = "esw_tx",
+ .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
+ .dedicatedController = 1,
+ .dedicatedChannel = 3,
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 1, /* DST: ESW (MTP) */
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
+ /* DMAx_AHB_SSTATARy */
+ .srcStatusRegisterAddress = 0x00000000,
+ /* DMAx_AHB_DSTATARy */
+ .dstStatusRegisterAddress = 0x30490010,
+ /* DMAx_AHB_CFGy */
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ /* DMAx_AHB_CTLy */
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ },
+ },
+ [DMA_DEVICE_ESW_DEV_TO_MEM] = /* ESW RX */
+ {
+ .name = "esw_rx",
+ .flags = DMA_DEVICE_FLAG_IS_DEDICATED,
+ .dedicatedController = 1,
+ .dedicatedChannel = 2,
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: ESW (PTM) */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_DISABLE,
+ /* DMAx_AHB_SSTATARy */
+ .srcStatusRegisterAddress = 0x30480010,
+ /* DMAx_AHB_DSTATARy */
+ .dstStatusRegisterAddress = 0x00000000,
+ /* DMAx_AHB_CFGy */
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ /* DMAx_AHB_CTLy */
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ },
+ },
+ [DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM] = /* APM Codec A Ingress */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "apm_a_rx",
+ .config = {
+ .srcPeripheralPort = 2, /* SRC: Codec A Ingress FIFO */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV] = /* APM Codec A Egress */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "apm_a_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 3, /* DST: Codec A Egress FIFO */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM] = /* APM Codec B Ingress */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "apm_b_rx",
+ .config = {
+ .srcPeripheralPort = 4, /* SRC: Codec B Ingress FIFO */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV] = /* APM Codec B Egress */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "apm_b_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 5, /* DST: Codec B Egress FIFO */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM] = /* APM Codec C Ingress */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "apm_c_rx",
+ .config = {
+ .srcPeripheralPort = 4, /* SRC: Codec C Ingress FIFO */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_APM_PCM0_DEV_TO_MEM] = /* PCM0 RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "pcm0_rx",
+ .config = {
+ .srcPeripheralPort = 12, /* SRC: PCM0 */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_APM_PCM0_MEM_TO_DEV] = /* PCM0 TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0,
+ .name = "pcm0_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 13, /* DST: PCM0 */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_APM_PCM1_DEV_TO_MEM] = /* PCM1 RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "pcm1_rx",
+ .config = {
+ .srcPeripheralPort = 14, /* SRC: PCM1 */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS,
+ },
+ },
+ [DMA_DEVICE_APM_PCM1_MEM_TO_DEV] = /* PCM1 TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "pcm1_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 15, /* DST: PCM1 */
+ .srcStatusRegisterAddress = 0,
+ .dstStatusRegisterAddress = 0,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_SPUM_DEV_TO_MEM] = /* SPUM RX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "spum_rx",
+ .config = {
+ .srcPeripheralPort = 6, /* SRC: Codec A Ingress FIFO */
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ /* Busrt size **MUST** be 16 for SPUM to work */
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ /* on the RX side, SPU needs to be the flow controller */
+ .flowControler = dmacHw_FLOW_CONTROL_PERIPHERAL,
+ },
+ },
+ [DMA_DEVICE_SPUM_MEM_TO_DEV] = /* SPUM TX */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "spum_tx",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .dstPeripheralPort = 7, /* DST: SPUM */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32,
+ /* Busrt size **MUST** be 16 for SPUM to work */
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16,
+ .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST,
+ },
+ },
+ [DMA_DEVICE_MEM_TO_VRAM] = /* MEM 2 VRAM */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "mem-to-vram",
+ .config = {
+ .srcPeripheralPort = 0, /* SRC: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ },
+ },
+ [DMA_DEVICE_VRAM_TO_MEM] = /* VRAM 2 MEM */
+ {
+ .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1,
+ .name = "vram-to-mem",
+ .config = {
+ .dstPeripheralPort = 0, /* DST: memory */
+ .srcStatusRegisterAddress = 0x00000000,
+ .dstStatusRegisterAddress = 0x00000000,
+ .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC,
+ .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC,
+ .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+ .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2,
+ .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1,
+ .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .errorInterrupt = dmacHw_INTERRUPT_ENABLE,
+ .channelPriority = dmacHw_CHANNEL_PRIORITY_7,
+ .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64,
+ .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64,
+ .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8,
+ .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8,
+ },
+ },
+};
+EXPORT_SYMBOL(DMA_gDeviceAttribute); /* primarily for dma-test.c */
diff --git a/arch/arm/mach-bcmring/include/cfg_global.h b/arch/arm/mach-bcmring/include/cfg_global.h
new file mode 100644
index 00000000..f01da877
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global.h
@@ -0,0 +1,13 @@
+#ifndef _CFG_GLOBAL_H_
+#define _CFG_GLOBAL_H_
+
+#include <cfg_global_defines.h>
+
+#define CFG_GLOBAL_CHIP BCM11107
+#define CFG_GLOBAL_CHIP_FAMILY CFG_GLOBAL_CHIP_FAMILY_BCMRING
+#define CFG_GLOBAL_CHIP_REV 0xB0
+#define CFG_GLOBAL_RAM_SIZE 0x10000000
+#define CFG_GLOBAL_RAM_BASE 0x00000000
+#define CFG_GLOBAL_RAM_RESERVED_SIZE 0x000000
+
+#endif /* _CFG_GLOBAL_H_ */
diff --git a/arch/arm/mach-bcmring/include/cfg_global_defines.h b/arch/arm/mach-bcmring/include/cfg_global_defines.h
new file mode 100644
index 00000000..b5beb0b3
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/cfg_global_defines.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+* Copyright 2006 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CFG_GLOBAL_DEFINES_H
+#define CFG_GLOBAL_DEFINES_H
+
+/* CHIP */
+#define BCM1103 1
+
+#define BCM1191 4
+#define BCM2153 5
+#define BCM2820 6
+
+#define BCM2826 8
+#define FPGA11107 9
+#define BCM11107 10
+#define BCM11109 11
+#define BCM11170 12
+#define BCM11110 13
+#define BCM11211 14
+
+/* CFG_GLOBAL_CHIP_FAMILY types */
+#define CFG_GLOBAL_CHIP_FAMILY_NONE 0
+#define CFG_GLOBAL_CHIP_FAMILY_BCM116X 2
+#define CFG_GLOBAL_CHIP_FAMILY_BCMRING 4
+#define CFG_GLOBAL_CHIP_FAMILY_BCM1103 8
+
+#define IMAGE_HEADER_SIZE_CHECKSUM 4
+#endif
diff --git a/arch/arm/mach-bcmring/include/csp/cache.h b/arch/arm/mach-bcmring/include/csp/cache.h
new file mode 100644
index 00000000..caa20e59
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/cache.h
@@ -0,0 +1,35 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_CACHE_H
+#define CSP_CACHE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+#include <asm/cacheflush.h>
+
+#define CSP_CACHE_FLUSH_ALL flush_cache_all()
+
+#else
+
+#define CSP_CACHE_FLUSH_ALL
+
+#endif
+
+#endif /* CSP_CACHE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/delay.h b/arch/arm/mach-bcmring/include/csp/delay.h
new file mode 100644
index 00000000..8b3d8036
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/delay.h
@@ -0,0 +1,36 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_DELAY_H
+#define CSP_DELAY_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+/* Some CSP routines require use of the following delay routines. Use the OS */
+/* version if available, otherwise use a CSP specific definition. */
+/* void udelay(unsigned long usecs); */
+/* void mdelay(unsigned long msecs); */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+ #include <linux/delay.h>
+#else
+ #include <mach/csp/delay.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* CSP_DELAY_H */
diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h
new file mode 100644
index 00000000..e6a1dc48
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h
@@ -0,0 +1,596 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dmacHw.h
+*
+* @brief API definitions for low level DMA controller driver
+*
+*/
+/****************************************************************************/
+#ifndef _DMACHW_H
+#define _DMACHW_H
+
+#include <stddef.h>
+
+#include <csp/stdint.h>
+#include <mach/csp/dmacHw_reg.h>
+
+/* Define DMA Channel ID using DMA controller number (m) and channel number (c).
+
+ System specific channel ID should be defined as follows
+
+ For example:
+
+ #include <dmacHw.h>
+ ...
+ #define systemHw_LCD_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,5)
+ #define systemHw_SWITCH_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,0)
+ #define systemHw_SWITCH_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,1)
+ #define systemHw_APM_RX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,3)
+ #define systemHw_APM_TX_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,4)
+ ...
+ #define systemHw_SHARED1_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,4)
+ #define systemHw_SHARED2_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(1,5)
+ #define systemHw_SHARED3_CHANNEL_ID dmacHw_MAKE_CHANNEL_ID(0,6)
+ ...
+*/
+#define dmacHw_MAKE_CHANNEL_ID(m, c) (m << 8 | c)
+
+typedef enum {
+ dmacHw_CHANNEL_PRIORITY_0 = dmacHw_REG_CFG_LO_CH_PRIORITY_0, /* Channel priority 0. Lowest priority DMA channel */
+ dmacHw_CHANNEL_PRIORITY_1 = dmacHw_REG_CFG_LO_CH_PRIORITY_1, /* Channel priority 1 */
+ dmacHw_CHANNEL_PRIORITY_2 = dmacHw_REG_CFG_LO_CH_PRIORITY_2, /* Channel priority 2 */
+ dmacHw_CHANNEL_PRIORITY_3 = dmacHw_REG_CFG_LO_CH_PRIORITY_3, /* Channel priority 3 */
+ dmacHw_CHANNEL_PRIORITY_4 = dmacHw_REG_CFG_LO_CH_PRIORITY_4, /* Channel priority 4 */
+ dmacHw_CHANNEL_PRIORITY_5 = dmacHw_REG_CFG_LO_CH_PRIORITY_5, /* Channel priority 5 */
+ dmacHw_CHANNEL_PRIORITY_6 = dmacHw_REG_CFG_LO_CH_PRIORITY_6, /* Channel priority 6 */
+ dmacHw_CHANNEL_PRIORITY_7 = dmacHw_REG_CFG_LO_CH_PRIORITY_7 /* Channel priority 7. Highest priority DMA channel */
+} dmacHw_CHANNEL_PRIORITY_e;
+
+/* Source destination master interface */
+typedef enum {
+ dmacHw_SRC_MASTER_INTERFACE_1 = dmacHw_REG_CTL_SMS_1, /* Source DMA master interface 1 */
+ dmacHw_SRC_MASTER_INTERFACE_2 = dmacHw_REG_CTL_SMS_2, /* Source DMA master interface 2 */
+ dmacHw_DST_MASTER_INTERFACE_1 = dmacHw_REG_CTL_DMS_1, /* Destination DMA master interface 1 */
+ dmacHw_DST_MASTER_INTERFACE_2 = dmacHw_REG_CTL_DMS_2 /* Destination DMA master interface 2 */
+} dmacHw_MASTER_INTERFACE_e;
+
+typedef enum {
+ dmacHw_SRC_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_SRC_TR_WIDTH_8, /* Source 8 bit (1 byte) per transaction */
+ dmacHw_SRC_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_SRC_TR_WIDTH_16, /* Source 16 bit (2 byte) per transaction */
+ dmacHw_SRC_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_SRC_TR_WIDTH_32, /* Source 32 bit (4 byte) per transaction */
+ dmacHw_SRC_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_SRC_TR_WIDTH_64, /* Source 64 bit (8 byte) per transaction */
+ dmacHw_DST_TRANSACTION_WIDTH_8 = dmacHw_REG_CTL_DST_TR_WIDTH_8, /* Destination 8 bit (1 byte) per transaction */
+ dmacHw_DST_TRANSACTION_WIDTH_16 = dmacHw_REG_CTL_DST_TR_WIDTH_16, /* Destination 16 bit (2 byte) per transaction */
+ dmacHw_DST_TRANSACTION_WIDTH_32 = dmacHw_REG_CTL_DST_TR_WIDTH_32, /* Destination 32 bit (4 byte) per transaction */
+ dmacHw_DST_TRANSACTION_WIDTH_64 = dmacHw_REG_CTL_DST_TR_WIDTH_64 /* Destination 64 bit (8 byte) per transaction */
+} dmacHw_TRANSACTION_WIDTH_e;
+
+typedef enum {
+ dmacHw_SRC_BURST_WIDTH_0 = dmacHw_REG_CTL_SRC_MSIZE_0, /* Source No burst */
+ dmacHw_SRC_BURST_WIDTH_4 = dmacHw_REG_CTL_SRC_MSIZE_4, /* Source 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+ dmacHw_SRC_BURST_WIDTH_8 = dmacHw_REG_CTL_SRC_MSIZE_8, /* Source 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+ dmacHw_SRC_BURST_WIDTH_16 = dmacHw_REG_CTL_SRC_MSIZE_16, /* Source 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+ dmacHw_DST_BURST_WIDTH_0 = dmacHw_REG_CTL_DST_MSIZE_0, /* Destination No burst */
+ dmacHw_DST_BURST_WIDTH_4 = dmacHw_REG_CTL_DST_MSIZE_4, /* Destination 4 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+ dmacHw_DST_BURST_WIDTH_8 = dmacHw_REG_CTL_DST_MSIZE_8, /* Destination 8 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+ dmacHw_DST_BURST_WIDTH_16 = dmacHw_REG_CTL_DST_MSIZE_16 /* Destination 16 X dmacHw_TRANSACTION_WIDTH_xxx bytes per burst */
+} dmacHw_BURST_WIDTH_e;
+
+typedef enum {
+ dmacHw_TRANSFER_TYPE_MEM_TO_MEM = dmacHw_REG_CTL_TTFC_MM_DMAC, /* Memory to memory transfer */
+ dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM = dmacHw_REG_CTL_TTFC_PM_DMAC, /* Peripheral to memory transfer */
+ dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_MP_DMAC, /* Memory to peripheral transfer */
+ dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_PERIPHERAL = dmacHw_REG_CTL_TTFC_PP_DMAC /* Peripheral to peripheral transfer */
+} dmacHw_TRANSFER_TYPE_e;
+
+typedef enum {
+ dmacHw_TRANSFER_MODE_PERREQUEST, /* Block transfer per DMA request */
+ dmacHw_TRANSFER_MODE_CONTINUOUS, /* Continuous transfer of streaming data */
+ dmacHw_TRANSFER_MODE_PERIODIC /* Periodic transfer of streaming data */
+} dmacHw_TRANSFER_MODE_e;
+
+typedef enum {
+ dmacHw_SRC_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_SINC_INC, /* Increment source address after every transaction */
+ dmacHw_SRC_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_SINC_DEC, /* Decrement source address after every transaction */
+ dmacHw_DST_ADDRESS_UPDATE_MODE_INC = dmacHw_REG_CTL_DINC_INC, /* Increment destination address after every transaction */
+ dmacHw_DST_ADDRESS_UPDATE_MODE_DEC = dmacHw_REG_CTL_DINC_DEC, /* Decrement destination address after every transaction */
+ dmacHw_SRC_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_SINC_NC, /* No change in source address after every transaction */
+ dmacHw_DST_ADDRESS_UPDATE_MODE_NC = dmacHw_REG_CTL_DINC_NC /* No change in destination address after every transaction */
+} dmacHw_ADDRESS_UPDATE_MODE_e;
+
+typedef enum {
+ dmacHw_FLOW_CONTROL_DMA, /* DMA working as flow controller (default) */
+ dmacHw_FLOW_CONTROL_PERIPHERAL /* Peripheral working as flow controller */
+} dmacHw_FLOW_CONTROL_e;
+
+typedef enum {
+ dmacHw_TRANSFER_STATUS_BUSY, /* DMA Transfer ongoing */
+ dmacHw_TRANSFER_STATUS_DONE, /* DMA Transfer completed */
+ dmacHw_TRANSFER_STATUS_ERROR /* DMA Transfer error */
+} dmacHw_TRANSFER_STATUS_e;
+
+typedef enum {
+ dmacHw_INTERRUPT_DISABLE, /* Interrupt disable */
+ dmacHw_INTERRUPT_ENABLE /* Interrupt enable */
+} dmacHw_INTERRUPT_e;
+
+typedef enum {
+ dmacHw_INTERRUPT_STATUS_NONE = 0x0, /* No DMA interrupt */
+ dmacHw_INTERRUPT_STATUS_TRANS = 0x1, /* End of DMA transfer interrupt */
+ dmacHw_INTERRUPT_STATUS_BLOCK = 0x2, /* End of block transfer interrupt */
+ dmacHw_INTERRUPT_STATUS_ERROR = 0x4 /* Error interrupt */
+} dmacHw_INTERRUPT_STATUS_e;
+
+typedef enum {
+ dmacHw_CONTROLLER_ATTRIB_CHANNEL_NUM, /* Number of DMA channel */
+ dmacHw_CONTROLLER_ATTRIB_CHANNEL_MAX_BLOCK_SIZE, /* Maximum channel burst size */
+ dmacHw_CONTROLLER_ATTRIB_MASTER_INTF_NUM, /* Number of DMA master interface */
+ dmacHw_CONTROLLER_ATTRIB_CHANNEL_BUS_WIDTH, /* Channel Data bus width */
+ dmacHw_CONTROLLER_ATTRIB_CHANNEL_FIFO_SIZE /* Channel FIFO size */
+} dmacHw_CONTROLLER_ATTRIB_e;
+
+typedef unsigned long dmacHw_HANDLE_t; /* DMA channel handle */
+typedef uint32_t dmacHw_ID_t; /* DMA channel Id. Must be created using
+ "dmacHw_MAKE_CHANNEL_ID" macro
+ */
+/* DMA channel configuration parameters */
+typedef struct {
+ uint32_t srcPeripheralPort; /* Source peripheral port */
+ uint32_t dstPeripheralPort; /* Destination peripheral port */
+ uint32_t srcStatusRegisterAddress; /* Source status register address */
+ uint32_t dstStatusRegisterAddress; /* Destination status register address of type */
+
+ uint32_t srcGatherWidth; /* Number of bytes gathered before successive gather opearation */
+ uint32_t srcGatherJump; /* Number of bytes jumpped before successive gather opearation */
+ uint32_t dstScatterWidth; /* Number of bytes sacattered before successive scatter opearation */
+ uint32_t dstScatterJump; /* Number of bytes jumpped before successive scatter opearation */
+ uint32_t maxDataPerBlock; /* Maximum number of bytes to be transferred per block/descrptor.
+ 0 = Maximum possible.
+ */
+
+ dmacHw_ADDRESS_UPDATE_MODE_e srcUpdate; /* Source address update mode */
+ dmacHw_ADDRESS_UPDATE_MODE_e dstUpdate; /* Destination address update mode */
+ dmacHw_TRANSFER_TYPE_e transferType; /* DMA transfer type */
+ dmacHw_TRANSFER_MODE_e transferMode; /* DMA transfer mode */
+ dmacHw_MASTER_INTERFACE_e srcMasterInterface; /* DMA source interface */
+ dmacHw_MASTER_INTERFACE_e dstMasterInterface; /* DMA destination interface */
+ dmacHw_TRANSACTION_WIDTH_e srcMaxTransactionWidth; /* Source transaction width */
+ dmacHw_TRANSACTION_WIDTH_e dstMaxTransactionWidth; /* Destination transaction width */
+ dmacHw_BURST_WIDTH_e srcMaxBurstWidth; /* Source burst width */
+ dmacHw_BURST_WIDTH_e dstMaxBurstWidth; /* Destination burst width */
+ dmacHw_INTERRUPT_e blockTransferInterrupt; /* Block trsnafer interrupt */
+ dmacHw_INTERRUPT_e completeTransferInterrupt; /* Complete DMA trsnafer interrupt */
+ dmacHw_INTERRUPT_e errorInterrupt; /* Error interrupt */
+ dmacHw_CHANNEL_PRIORITY_e channelPriority; /* Channel priority */
+ dmacHw_FLOW_CONTROL_e flowControler; /* Data flow controller */
+} dmacHw_CONFIG_t;
+
+/****************************************************************************/
+/**
+* @brief Initializes DMA
+*
+* This function initializes DMA CSP driver
+*
+* @note
+* Must be called before using any DMA channel
+*/
+/****************************************************************************/
+void dmacHw_initDma(void);
+
+/****************************************************************************/
+/**
+* @brief Exit function for DMA
+*
+* This function isolates DMA from the system
+*
+*/
+/****************************************************************************/
+void dmacHw_exitDma(void);
+
+/****************************************************************************/
+/**
+* @brief Gets a handle to a DMA channel
+*
+* This function returns a handle, representing a control block of a particular DMA channel
+*
+* @return -1 - On Failure
+* handle - On Success, representing a channel control block
+*
+* @note
+* None Channel ID must be created using "dmacHw_MAKE_CHANNEL_ID" macro
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getChannelHandle(dmacHw_ID_t channelId /* [ IN ] DMA Channel Id */
+ );
+
+/****************************************************************************/
+/**
+* @brief Initializes a DMA channel for use
+*
+* This function initializes and resets a DMA channel for use
+*
+* @return -1 - On Failure
+* 0 - On Success
+*
+* @note
+* None
+*/
+/****************************************************************************/
+int dmacHw_initChannel(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Estimates number of descriptor needed to perform certain DMA transfer
+*
+*
+* @return On failure : -1
+* On success : Number of descriptor count
+*
+*
+*/
+/****************************************************************************/
+int dmacHw_calculateDescriptorCount(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
+ void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
+ size_t dataLen /* [ IN ] Data length in bytes */
+ );
+
+/****************************************************************************/
+/**
+* @brief Initializes descriptor ring
+*
+* This function will initializes the descriptor ring of a DMA channel
+*
+*
+* @return -1 - On failure
+* 0 - On success
+* @note
+* - "len" parameter should be obtained from "dmacHw_descriptorLen"
+* - Descriptor buffer MUST be 32 bit aligned and uncached as it
+* is accessed by ARM and DMA
+*/
+/****************************************************************************/
+int dmacHw_initDescriptor(void *pDescriptorVirt, /* [ IN ] Virtual address of uncahced buffer allocated to form descriptor ring */
+ uint32_t descriptorPhyAddr, /* [ IN ] Physical address of pDescriptorVirt (descriptor buffer) */
+ uint32_t len, /* [ IN ] Size of the pBuf */
+ uint32_t num /* [ IN ] Number of descriptor in the ring */
+ );
+
+/****************************************************************************/
+/**
+* @brief Finds amount of memory required to form a descriptor ring
+*
+*
+* @return Number of bytes required to form a descriptor ring
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorLen(uint32_t descCnt /* [ IN ] Number of descriptor in the ring */
+ );
+
+/****************************************************************************/
+/**
+* @brief Configure DMA channel
+*
+* @return 0 : On success
+* -1 : On failure
+*/
+/****************************************************************************/
+int dmacHw_configChannel(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig /* [ IN ] Configuration settings */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set descriptors for known data length
+*
+* When DMA has to work as a flow controller, this function prepares the
+* descriptor chain to transfer data
+*
+* from:
+* - Memory to memory
+* - Peripheral to memory
+* - Memory to Peripheral
+* - Peripheral to Peripheral
+*
+* @return -1 - On failure
+* 0 - On success
+*
+*/
+/****************************************************************************/
+int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void *pSrcAddr, /* [ IN ] Source (Peripheral/Memory) address */
+ void *pDstAddr, /* [ IN ] Destination (Peripheral/Memory) address */
+ size_t dataLen /* [ IN ] Length in bytes */
+ );
+
+/****************************************************************************/
+/**
+* @brief Indicates whether DMA transfer is in progress or completed
+*
+* @return DMA transfer status
+* dmacHw_TRANSFER_STATUS_BUSY: DMA Transfer ongoing
+* dmacHw_TRANSFER_STATUS_DONE: DMA Transfer completed
+* dmacHw_TRANSFER_STATUS_ERROR: DMA Transfer error
+*
+*/
+/****************************************************************************/
+dmacHw_TRANSFER_STATUS_e dmacHw_transferCompleted(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set descriptor carrying control information
+*
+* This function will be used to send specific control information to the device
+* using the DMA channel
+*
+*
+* @return -1 - On failure
+* 0 - On success
+*
+* @note
+* None
+*/
+/****************************************************************************/
+int dmacHw_setControlDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ uint32_t ctlAddress, /* [ IN ] Address of the device control register */
+ uint32_t control /* [ IN ] Device control information */
+ );
+
+/****************************************************************************/
+/**
+* @brief Read data DMA transferred to memory
+*
+* This function will read data that has been DMAed to memory while transferring from:
+* - Memory to memory
+* - Peripheral to memory
+*
+* @return 0 - No more data is available to read
+* 1 - More data might be available to read
+*
+*/
+/****************************************************************************/
+int dmacHw_readTransferredData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void **ppBbuf, /* [ OUT ] Data received */
+ size_t *pLlen /* [ OUT ] Length of the data received */
+ );
+
+/****************************************************************************/
+/**
+* @brief Prepares descriptor ring, when source peripheral working as a flow controller
+*
+* This function will form the descriptor ring by allocating buffers, when source peripheral
+* has to work as a flow controller to transfer data from:
+* - Peripheral to memory.
+*
+* @return -1 - On failure
+* 0 - On success
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+int dmacHw_setVariableDataDescriptor(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ uint32_t srcAddr, /* [ IN ] Source peripheral address */
+ void *(*fpAlloc) (int len), /* [ IN ] Function pointer that provides destination memory */
+ int len, /* [ IN ] Number of bytes "fpAlloc" will allocate for destination */
+ int num /* [ IN ] Number of descriptor to set */
+ );
+
+/****************************************************************************/
+/**
+* @brief Program channel register to initiate transfer
+*
+* @return void
+*
+*
+* @note
+* - Descriptor buffer MUST ALWAYS be flushed before calling this function
+* - This function should also be called from ISR to program the channel with
+* pending descriptors
+*/
+/****************************************************************************/
+void dmacHw_initiateTransfer(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor /* [ IN ] Descriptor buffer */
+ );
+
+/****************************************************************************/
+/**
+* @brief Resets descriptor control information
+*
+* @return void
+*/
+/****************************************************************************/
+void dmacHw_resetDescriptorControl(void *pDescriptor /* [ IN ] Descriptor buffer */
+ );
+
+/****************************************************************************/
+/**
+* @brief Program channel register to stop transfer
+*
+* Ensures the channel is not doing any transfer after calling this function
+*
+* @return void
+*
+*/
+/****************************************************************************/
+void dmacHw_stopTransfer(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Check the existence of pending descriptor
+*
+* This function confirmes if there is any pending descriptor in the chain
+* to program the channel
+*
+* @return 1 : Channel need to be programmed with pending descriptor
+* 0 : No more pending descriptor to programe the channel
+*
+* @note
+* - This function should be called from ISR in case there are pending
+* descriptor to program the channel.
+*
+* Example:
+*
+* dmac_isr ()
+* {
+* ...
+* if (dmacHw_descriptorPending (handle))
+* {
+* dmacHw_initiateTransfer (handle);
+* }
+* }
+*
+*/
+/****************************************************************************/
+uint32_t dmacHw_descriptorPending(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *pDescriptor /* [ IN ] Descriptor buffer */
+ );
+
+/****************************************************************************/
+/**
+* @brief Deallocates source or destination memory, allocated
+*
+* This function can be called to deallocate data memory that was DMAed successfully
+*
+* @return -1 - On failure
+* 0 - On success
+*
+* @note
+* This function will be called ONLY, when source OR destination address is pointing
+* to dynamic memory
+*/
+/****************************************************************************/
+int dmacHw_freeMem(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration settings */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ void (*fpFree) (void *) /* [ IN ] Function pointer to free data memory */
+ );
+
+/****************************************************************************/
+/**
+* @brief Clears the interrupt
+*
+* This function clears the DMA channel specific interrupt
+*
+* @return N/A
+*
+* @note
+* Must be called under the context of ISR
+*/
+/****************************************************************************/
+void dmacHw_clearInterrupt(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Returns the cause of channel specific DMA interrupt
+*
+* This function returns the cause of interrupt
+*
+* @return Interrupt status, each bit representing a specific type of interrupt
+* of type dmacHw_INTERRUPT_STATUS_e
+* @note
+* This function should be called under the context of ISR
+*/
+/****************************************************************************/
+dmacHw_INTERRUPT_STATUS_e dmacHw_getInterruptStatus(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Indentifies a DMA channel causing interrupt
+*
+* This functions returns a channel causing interrupt of type dmacHw_INTERRUPT_STATUS_e
+*
+* @return NULL : No channel causing DMA interrupt
+* ! NULL : Handle to a channel causing DMA interrupt
+* @note
+* dmacHw_clearInterrupt() must be called with a valid handle after calling this function
+*/
+/****************************************************************************/
+dmacHw_HANDLE_t dmacHw_getInterruptSource(void);
+
+/****************************************************************************/
+/**
+* @brief Sets channel specific user data
+*
+* This function associates user data to a specific DMA channel
+*
+*/
+/****************************************************************************/
+void dmacHw_setChannelUserData(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *userData /* [ IN ] User data */
+ );
+
+/****************************************************************************/
+/**
+* @brief Gets channel specific user data
+*
+* This function returns user data specific to a DMA channel
+*
+* @return user data
+*/
+/****************************************************************************/
+void *dmacHw_getChannelUserData(dmacHw_HANDLE_t handle /* [ IN ] DMA Channel handle */
+ );
+
+/****************************************************************************/
+/**
+* @brief Displays channel specific registers and other control parameters
+*
+*
+* @return void
+*
+* @note
+* None
+*/
+/****************************************************************************/
+void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ void *pDescriptor, /* [ IN ] Descriptor buffer */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
+ );
+
+/****************************************************************************/
+/**
+* @brief Provides DMA controller attributes
+*
+*
+* @return DMA controller attributes
+*
+* @note
+* None
+*/
+/****************************************************************************/
+uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */
+ dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */
+ );
+
+#endif /* _DMACHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/errno.h b/arch/arm/mach-bcmring/include/csp/errno.h
new file mode 100644
index 00000000..51357dd5
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/errno.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_ERRNO_H
+#define CSP_ERRNO_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#if defined(__KERNEL__)
+#include <linux/errno.h>
+#elif defined(CSP_SIMULATION)
+#include <asm-generic/errno.h>
+#else
+#include <errno.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* CSP_ERRNO_H */
diff --git a/arch/arm/mach-bcmring/include/csp/intcHw.h b/arch/arm/mach-bcmring/include/csp/intcHw.h
new file mode 100644
index 00000000..1c639c8e
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/intcHw.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+/****************************************************************************/
+/**
+* @file intcHw.h
+*
+* @brief generic interrupt controller API
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef _INTCHW_H
+#define _INTCHW_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/intcHw_reg.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+static inline void intcHw_irq_disable(void *basep, uint32_t mask);
+static inline void intcHw_irq_enable(void *basep, uint32_t mask);
+
+#endif /* _INTCHW_H */
+
diff --git a/arch/arm/mach-bcmring/include/csp/module.h b/arch/arm/mach-bcmring/include/csp/module.h
new file mode 100644
index 00000000..c30d2a59
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/module.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_MODULE_H
+#define CSP_MODULE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+ #include <linux/module.h>
+#else
+ #define EXPORT_SYMBOL(symbol)
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_MODULE_H */
diff --git a/arch/arm/mach-bcmring/include/csp/reg.h b/arch/arm/mach-bcmring/include/csp/reg.h
new file mode 100644
index 00000000..56654d23
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/reg.h
@@ -0,0 +1,114 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file reg.h
+*
+* @brief Generic register definitions used in CSP
+*/
+/****************************************************************************/
+
+#ifndef CSP_REG_H
+#define CSP_REG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/stdint.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#define __REG32(x) (*((volatile uint32_t *)(x)))
+#define __REG16(x) (*((volatile uint16_t *)(x)))
+#define __REG8(x) (*((volatile uint8_t *) (x)))
+
+/* Macros used to define a sequence of reserved registers. The start / end */
+/* are byte offsets in the particular register definition, with the "end" */
+/* being the offset of the next un-reserved register. E.g. if offsets */
+/* 0x10 through to 0x1f are reserved, then this reserved area could be */
+/* specified as follows. */
+/* typedef struct */
+/* { */
+/* uint32_t reg1; offset 0x00 */
+/* uint32_t reg2; offset 0x04 */
+/* uint32_t reg3; offset 0x08 */
+/* uint32_t reg4; offset 0x0c */
+/* REG32_RSVD(0x10, 0x20); */
+/* uint32_t reg5; offset 0x20 */
+/* ... */
+/* } EXAMPLE_REG_t; */
+#define REG8_RSVD(start, end) uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)]
+#define REG16_RSVD(start, end) uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)]
+#define REG32_RSVD(start, end) uint32_t rsvd_##start[(end - start) / sizeof(uint32_t)]
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/* Note: When protecting multiple statements, the REG_LOCAL_IRQ_SAVE and */
+/* REG_LOCAL_IRQ_RESTORE must be enclosed in { } to allow the */
+/* flags variable to be declared locally. */
+/* e.g. */
+/* statement1; */
+/* { */
+/* REG_LOCAL_IRQ_SAVE; */
+/* <multiple statements here> */
+/* REG_LOCAL_IRQ_RESTORE; */
+/* } */
+/* statement2; */
+/* */
+
+#if defined(__KERNEL__) && !defined(STANDALONE)
+#include <mach/hardware.h>
+#include <linux/interrupt.h>
+
+#define REG_LOCAL_IRQ_SAVE HW_DECLARE_SPINLOCK(reg32) \
+ unsigned long flags; HW_IRQ_SAVE(reg32, flags)
+
+#define REG_LOCAL_IRQ_RESTORE HW_IRQ_RESTORE(reg32, flags)
+
+#else
+
+#define REG_LOCAL_IRQ_SAVE
+#define REG_LOCAL_IRQ_RESTORE
+
+#endif
+
+static inline void reg32_modify_and(volatile uint32_t *reg, uint32_t value)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *reg &= value;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_modify_or(volatile uint32_t *reg, uint32_t value)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *reg |= value;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_modify_mask(volatile uint32_t *reg, uint32_t mask,
+ uint32_t value)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *reg = (*reg & mask) | value;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void reg32_write(volatile uint32_t *reg, uint32_t value)
+{
+ *reg = value;
+}
+
+#endif /* CSP_REG_H */
diff --git a/arch/arm/mach-bcmring/include/csp/secHw.h b/arch/arm/mach-bcmring/include/csp/secHw.h
new file mode 100644
index 00000000..b9d7e073
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/secHw.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file secHw.h
+*
+* @brief Definitions for accessing low level security features
+*
+*/
+/****************************************************************************/
+#ifndef SECHW_H
+#define SECHW_H
+
+typedef void (*secHw_FUNC_t) (void);
+
+typedef enum {
+ secHw_MODE_SECURE = 0x0, /* Switches processor into secure mode */
+ secHw_MODE_NONSECURE = 0x1 /* Switches processor into non-secure mode */
+} secHw_MODE;
+
+/****************************************************************************/
+/**
+* @brief Requesting to execute the function in secure mode
+*
+* This function requests the given function to run in secure mode
+*
+*/
+/****************************************************************************/
+void secHw_RunSecure(secHw_FUNC_t /* Function to run in secure mode */
+ );
+
+/****************************************************************************/
+/**
+* @brief Sets the mode
+*
+* his function sets the processor mode (secure/non-secure)
+*
+*/
+/****************************************************************************/
+void secHw_SetMode(secHw_MODE /* Processor mode */
+ );
+
+/****************************************************************************/
+/**
+* @brief Get the current mode
+*
+* This function retieves the processor mode (secure/non-secure)
+*
+*/
+/****************************************************************************/
+void secHw_GetMode(secHw_MODE *);
+
+#endif /* SECHW_H */
diff --git a/arch/arm/mach-bcmring/include/csp/stdint.h b/arch/arm/mach-bcmring/include/csp/stdint.h
new file mode 100644
index 00000000..3a8718bb
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/stdint.h
@@ -0,0 +1,30 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CSP_STDINT_H
+#define CSP_STDINT_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* CSP_STDINT_H */
diff --git a/arch/arm/mach-bcmring/include/csp/string.h b/arch/arm/mach-bcmring/include/csp/string.h
new file mode 100644
index 00000000..ad9e4005
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/string.h
@@ -0,0 +1,34 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+
+#ifndef CSP_STRING_H
+#define CSP_STRING_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#ifdef __KERNEL__
+ #include <linux/string.h>
+#else
+ #include <string.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_STRING_H */
+
diff --git a/arch/arm/mach-bcmring/include/csp/tmrHw.h b/arch/arm/mach-bcmring/include/csp/tmrHw.h
new file mode 100644
index 00000000..2cbb530d
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/csp/tmrHw.h
@@ -0,0 +1,263 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file tmrHw.h
+*
+* @brief API definitions for low level Timer driver
+*
+*/
+/****************************************************************************/
+#ifndef _TMRHW_H
+#define _TMRHW_H
+
+#include <csp/stdint.h>
+
+typedef uint32_t tmrHw_ID_t; /* Timer ID */
+typedef uint32_t tmrHw_COUNT_t; /* Timer count */
+typedef uint32_t tmrHw_INTERVAL_t; /* Timer interval */
+typedef uint32_t tmrHw_RATE_t; /* Timer event (count/interrupt) rate */
+
+typedef enum {
+ tmrHw_INTERRUPT_STATUS_SET, /* Interrupted */
+ tmrHw_INTERRUPT_STATUS_UNSET /* No Interrupt */
+} tmrHw_INTERRUPT_STATUS_e;
+
+typedef enum {
+ tmrHw_CAPABILITY_CLOCK, /* Clock speed in HHz */
+ tmrHw_CAPABILITY_RESOLUTION /* Timer resolution in bits */
+} tmrHw_CAPABILITY_e;
+
+/****************************************************************************/
+/**
+* @brief Get timer capability
+*
+* This function returns various capabilities/attributes of a timer
+*
+* @return Numeric capability
+*
+*/
+/****************************************************************************/
+uint32_t tmrHw_getTimerCapability(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_CAPABILITY_e capability /* [ IN ] Timer capability */
+);
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer in terms of timer interrupt rate
+*
+* This function initializes a periodic timer to generate specific number of
+* timer interrupt per second
+*
+* @return On success: Effective timer frequency
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setPeriodicTimerRate(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_RATE_t rate /* [ IN ] Number of timer interrupt per second */
+);
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer to generate timer interrupt after
+* certain time interval
+*
+* This function initializes a periodic timer to generate timer interrupt
+* after every time interval in millisecond
+*
+* @return On success: Effective interval set in mili-second
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setPeriodicTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */
+);
+
+/****************************************************************************/
+/**
+* @brief Configures a periodic timer to generate timer interrupt just once
+* after certain time interval
+*
+* This function initializes a periodic timer to generate a single ticks after
+* certain time interval in millisecond
+*
+* @return On success: Effective interval set in mili-second
+* On failure: 0
+*
+*/
+/****************************************************************************/
+tmrHw_INTERVAL_t tmrHw_setOneshotTimerInterval(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ tmrHw_INTERVAL_t msec /* [ IN ] Interval in mili-second */
+);
+
+/****************************************************************************/
+/**
+* @brief Configures a timer to run as a free running timer
+*
+* This function initializes a timer to run as a free running timer
+*
+* @return Timer resolution (count / sec)
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_setFreeRunningTimer(tmrHw_ID_t timerId, /* [ IN ] Timer Id */
+ uint32_t divider /* [ IN ] Dividing the clock frequency */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Starts a timer
+*
+* This function starts a preconfigured timer
+*
+* @return -1 - On Failure
+* 0 - On Success
+*/
+/****************************************************************************/
+int tmrHw_startTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Stops a timer
+*
+* This function stops a running timer
+*
+* @return -1 - On Failure
+* 0 - On Success
+*/
+/****************************************************************************/
+int tmrHw_stopTimer(tmrHw_ID_t timerId /* [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+* @brief Gets current timer count
+*
+* This function returns the current timer value
+*
+* @return Current downcounting timer value
+*
+*/
+/****************************************************************************/
+tmrHw_COUNT_t tmrHw_GetCurrentCount(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Gets timer count rate
+*
+* This function returns the number of counts per second
+*
+* @return Count rate
+*
+*/
+/****************************************************************************/
+tmrHw_RATE_t tmrHw_getCountRate(tmrHw_ID_t timerId /* [ IN ] Timer id */
+) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Enables timer interrupt
+*
+* This function enables the timer interrupt
+*
+* @return N/A
+*
+*/
+/****************************************************************************/
+void tmrHw_enableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+* @brief Disables timer interrupt
+*
+* This function disable the timer interrupt
+*
+* @return N/A
+*/
+/****************************************************************************/
+void tmrHw_disableInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+* @brief Clears the interrupt
+*
+* This function clears the timer interrupt
+*
+* @return N/A
+*
+* @note
+* Must be called under the context of ISR
+*/
+/****************************************************************************/
+void tmrHw_clearInterrupt(tmrHw_ID_t timerId /* [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+* @brief Gets the interrupt status
+*
+* This function returns timer interrupt status
+*
+* @return Interrupt status
+*/
+/****************************************************************************/
+tmrHw_INTERRUPT_STATUS_e tmrHw_getInterruptStatus(tmrHw_ID_t timerId /* [ IN ] Timer id */
+);
+
+/****************************************************************************/
+/**
+* @brief Indentifies a timer causing interrupt
+*
+* This functions returns a timer causing interrupt
+*
+* @return 0xFFFFFFFF : No timer causing an interrupt
+* ! 0xFFFFFFFF : timer causing an interrupt
+* @note
+* tmrHw_clearIntrrupt() must be called with a valid timer id after calling this function
+*/
+/****************************************************************************/
+tmrHw_ID_t tmrHw_getInterruptSource(void);
+
+/****************************************************************************/
+/**
+* @brief Displays specific timer registers
+*
+*
+* @return void
+*
+*/
+/****************************************************************************/
+void tmrHw_printDebugInfo(tmrHw_ID_t timerId, /* [ IN ] Timer id */
+ int (*fpPrint) (const char *, ...) /* [ IN ] Print callback function */
+);
+
+/****************************************************************************/
+/**
+* @brief Use a timer to perform a busy wait delay for a number of usecs.
+*
+* @return N/A
+*/
+/****************************************************************************/
+void tmrHw_udelay(tmrHw_ID_t timerId, /* [ IN ] Timer id */
+ unsigned long usecs /* [ IN ] usec to delay */
+) __attribute__ ((section(".aramtext")));
+
+#endif /* _TMRHW_H */
diff --git a/arch/arm/mach-bcmring/include/mach/clkdev.h b/arch/arm/mach-bcmring/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap.h b/arch/arm/mach-bcmring/include/mach/csp/cap.h
new file mode 100644
index 00000000..30fa2d54
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap.h
@@ -0,0 +1,63 @@
+/*****************************************************************************
+* Copyright 2009 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CAP_H
+#define CAP_H
+
+/* ---- Include Files ---------------------------------------------------- */
+/* ---- Public Constants and Types --------------------------------------- */
+typedef enum {
+ CAP_NOT_PRESENT = 0,
+ CAP_PRESENT
+} CAP_RC_T;
+
+typedef enum {
+ CAP_VPM,
+ CAP_ETH_PHY,
+ CAP_ETH_GMII,
+ CAP_ETH_SGMII,
+ CAP_USB,
+ CAP_TSC,
+ CAP_EHSS,
+ CAP_SDIO,
+ CAP_UARTB,
+ CAP_KEYPAD,
+ CAP_CLCD,
+ CAP_GE,
+ CAP_LEDM,
+ CAP_BBL,
+ CAP_VDEC,
+ CAP_PIF,
+ CAP_APM,
+ CAP_SPU,
+ CAP_PKA,
+ CAP_RNG,
+} CAP_CAPABILITY_T;
+
+typedef enum {
+ CAP_LCD_WVGA = 0,
+ CAP_LCD_VGA = 0x1,
+ CAP_LCD_WQVGA = 0x2,
+ CAP_LCD_QVGA = 0x3
+} CAP_LCD_RES_T;
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index);
+static inline uint32_t cap_getMaxArmSpeedHz(void);
+static inline uint32_t cap_getMaxVpmSpeedHz(void);
+static inline CAP_LCD_RES_T cap_getMaxLcdRes(void);
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
new file mode 100644
index 00000000..933ce68e
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/cap_inline.h
@@ -0,0 +1,409 @@
+/*****************************************************************************
+* Copyright 2009 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CAP_INLINE_H
+#define CAP_INLINE_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/cap.h>
+#include <cfg_global.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+#define CAP_CONFIG0_VPM_DIS 0x00000001
+#define CAP_CONFIG0_ETH_PHY0_DIS 0x00000002
+#define CAP_CONFIG0_ETH_PHY1_DIS 0x00000004
+#define CAP_CONFIG0_ETH_GMII0_DIS 0x00000008
+#define CAP_CONFIG0_ETH_GMII1_DIS 0x00000010
+#define CAP_CONFIG0_ETH_SGMII0_DIS 0x00000020
+#define CAP_CONFIG0_ETH_SGMII1_DIS 0x00000040
+#define CAP_CONFIG0_USB0_DIS 0x00000080
+#define CAP_CONFIG0_USB1_DIS 0x00000100
+#define CAP_CONFIG0_TSC_DIS 0x00000200
+#define CAP_CONFIG0_EHSS0_DIS 0x00000400
+#define CAP_CONFIG0_EHSS1_DIS 0x00000800
+#define CAP_CONFIG0_SDIO0_DIS 0x00001000
+#define CAP_CONFIG0_SDIO1_DIS 0x00002000
+#define CAP_CONFIG0_UARTB_DIS 0x00004000
+#define CAP_CONFIG0_KEYPAD_DIS 0x00008000
+#define CAP_CONFIG0_CLCD_DIS 0x00010000
+#define CAP_CONFIG0_GE_DIS 0x00020000
+#define CAP_CONFIG0_LEDM_DIS 0x00040000
+#define CAP_CONFIG0_BBL_DIS 0x00080000
+#define CAP_CONFIG0_VDEC_DIS 0x00100000
+#define CAP_CONFIG0_PIF_DIS 0x00200000
+#define CAP_CONFIG0_RESERVED1_DIS 0x00400000
+#define CAP_CONFIG0_RESERVED2_DIS 0x00800000
+
+#define CAP_CONFIG1_APMA_DIS 0x00000001
+#define CAP_CONFIG1_APMB_DIS 0x00000002
+#define CAP_CONFIG1_APMC_DIS 0x00000004
+#define CAP_CONFIG1_CLCD_RES_MASK 0x00000600
+#define CAP_CONFIG1_CLCD_RES_SHIFT 9
+#define CAP_CONFIG1_CLCD_RES_WVGA (CAP_LCD_WVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_VGA (CAP_LCD_VGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_WQVGA (CAP_LCD_WQVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+#define CAP_CONFIG1_CLCD_RES_QVGA (CAP_LCD_QVGA << CAP_CONFIG1_CLCD_RES_SHIFT)
+
+#define CAP_CONFIG2_SPU_DIS 0x00000010
+#define CAP_CONFIG2_PKA_DIS 0x00000020
+#define CAP_CONFIG2_RNG_DIS 0x00000080
+
+#if (CFG_GLOBAL_CHIP == BCM11107)
+#define capConfig0 0
+#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 3
+#elif (CFG_GLOBAL_CHIP == FPGA11107)
+#define capConfig0 0
+#define capConfig1 CAP_CONFIG1_CLCD_RES_WVGA
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 3
+#elif (CFG_GLOBAL_CHIP == BCM11109)
+#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11170)
+#define capConfig0 (CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_USB0_DIS | CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_CLCD_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 (CAP_CONFIG1_APMC_DIS | CAP_CONFIG1_CLCD_RES_WQVGA)
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11110)
+#define capConfig0 (CAP_CONFIG0_USB1_DIS | CAP_CONFIG0_TSC_DIS | CAP_CONFIG0_EHSS1_DIS | CAP_CONFIG0_SDIO0_DIS | CAP_CONFIG0_SDIO1_DIS | CAP_CONFIG0_UARTB_DIS | CAP_CONFIG0_GE_DIS | CAP_CONFIG0_BBL_DIS | CAP_CONFIG0_VDEC_DIS)
+#define capConfig1 CAP_CONFIG1_APMC_DIS
+#define capConfig2 (CAP_CONFIG2_SPU_DIS | CAP_CONFIG2_PKA_DIS)
+#define CAP_APM_MAX_NUM_CHANS 2
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+#define capConfig0 (CAP_CONFIG0_ETH_PHY0_DIS | CAP_CONFIG0_ETH_GMII0_DIS | CAP_CONFIG0_ETH_GMII1_DIS | CAP_CONFIG0_ETH_SGMII0_DIS | CAP_CONFIG0_ETH_SGMII1_DIS | CAP_CONFIG0_CLCD_DIS)
+#define capConfig1 CAP_CONFIG1_APMC_DIS
+#define capConfig2 0
+#define CAP_APM_MAX_NUM_CHANS 2
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
+#define CAP_HW_CFG_ARM_CLK_HZ 500000000
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+#define CAP_HW_CFG_ARM_CLK_HZ 300000000
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+#define CAP_HW_CFG_ARM_CLK_HZ 666666666
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
+#define CAP_HW_CFG_VPM_CLK_HZ 333333333
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+#define CAP_HW_CFG_VPM_CLK_HZ 200000000
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/****************************************************************************
+* cap_isPresent -
+*
+* PURPOSE:
+* Determines if the chip has a certain capability present
+*
+* PARAMETERS:
+* capability - type of capability to determine if present
+*
+* RETURNS:
+* CAP_PRESENT or CAP_NOT_PRESENT
+****************************************************************************/
+static inline CAP_RC_T cap_isPresent(CAP_CAPABILITY_T capability, int index)
+{
+ CAP_RC_T returnVal = CAP_NOT_PRESENT;
+
+ switch (capability) {
+ case CAP_VPM:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_VPM_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_ETH_PHY:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_PHY0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_PHY1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_ETH_GMII:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_GMII0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_GMII1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_ETH_SGMII:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_ETH_SGMII1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_USB:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_USB0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_USB1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_TSC:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_TSC_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_EHSS:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_EHSS0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_EHSS1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_SDIO:
+ {
+ if ((index == 0)
+ && (!(capConfig0 & CAP_CONFIG0_SDIO0_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig0 & CAP_CONFIG0_SDIO1_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_UARTB:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_UARTB_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_KEYPAD:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_KEYPAD_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_CLCD:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_CLCD_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_GE:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_GE_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_LEDM:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_LEDM_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_BBL:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_BBL_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_VDEC:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_VDEC_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_PIF:
+ {
+ if (!(capConfig0 & CAP_CONFIG0_PIF_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_APM:
+ {
+ if ((index == 0)
+ && (!(capConfig1 & CAP_CONFIG1_APMA_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 1)
+ && (!(capConfig1 & CAP_CONFIG1_APMB_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ if ((index == 2)
+ && (!(capConfig1 & CAP_CONFIG1_APMC_DIS))) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_SPU:
+ {
+ if (!(capConfig2 & CAP_CONFIG2_SPU_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_PKA:
+ {
+ if (!(capConfig2 & CAP_CONFIG2_PKA_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ case CAP_RNG:
+ {
+ if (!(capConfig2 & CAP_CONFIG2_RNG_DIS)) {
+ returnVal = CAP_PRESENT;
+ }
+ }
+ break;
+
+ default:
+ {
+ }
+ break;
+ }
+ return returnVal;
+}
+
+/****************************************************************************
+* cap_getMaxArmSpeedHz -
+*
+* PURPOSE:
+* Determines the maximum speed of the ARM CPU
+*
+* PARAMETERS:
+* none
+*
+* RETURNS:
+* clock speed in Hz that the ARM processor is able to run at
+****************************************************************************/
+static inline uint32_t cap_getMaxArmSpeedHz(void)
+{
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == FPGA11107))
+ return 500000000;
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+ return 300000000;
+#elif (CFG_GLOBAL_CHIP == BCM11211)
+ return 666666666;
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+}
+
+/****************************************************************************
+* cap_getMaxVpmSpeedHz -
+*
+* PURPOSE:
+* Determines the maximum speed of the VPM
+*
+* PARAMETERS:
+* none
+*
+* RETURNS:
+* clock speed in Hz that the VPM is able to run at
+****************************************************************************/
+static inline uint32_t cap_getMaxVpmSpeedHz(void)
+{
+#if ((CFG_GLOBAL_CHIP == BCM11107) || (CFG_GLOBAL_CHIP == BCM11211) || (CFG_GLOBAL_CHIP == FPGA11107))
+ return 333333333;
+#elif ((CFG_GLOBAL_CHIP == BCM11109) || (CFG_GLOBAL_CHIP == BCM11170) || (CFG_GLOBAL_CHIP == BCM11110))
+ return 200000000;
+#else
+#error CFG_GLOBAL_CHIP type capabilities not defined
+#endif
+}
+
+/****************************************************************************
+* cap_getMaxLcdRes -
+*
+* PURPOSE:
+* Determines the maximum LCD resolution capabilities
+*
+* PARAMETERS:
+* none
+*
+* RETURNS:
+* CAP_LCD_WVGA, CAP_LCD_VGA, CAP_LCD_WQVGA or CAP_LCD_QVGA
+*
+****************************************************************************/
+static inline CAP_LCD_RES_T cap_getMaxLcdRes(void)
+{
+ return (CAP_LCD_RES_T)
+ ((capConfig1 & CAP_CONFIG1_CLCD_RES_MASK) >>
+ CAP_CONFIG1_CLCD_RES_SHIFT);
+}
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
new file mode 100644
index 00000000..16197338
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_def.h
@@ -0,0 +1,1123 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CHIPC_DEF_H
+#define CHIPC_DEF_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <csp/stdint.h>
+#include <csp/errno.h>
+#include <csp/reg.h>
+#include <mach/csp/chipcHw_reg.h>
+
+/* ---- Public Constants and Types ---------------------------------------- */
+
+/* Set 1 to configure DDR/VPM phase alignment by HW */
+#define chipcHw_DDR_HW_PHASE_ALIGN 0
+#define chipcHw_VPM_HW_PHASE_ALIGN 0
+
+typedef uint32_t chipcHw_freq;
+
+/* Configurable miscellaneous clocks */
+typedef enum {
+ chipcHw_CLOCK_DDR, /* DDR PHY Clock */
+ chipcHw_CLOCK_ARM, /* ARM Clock */
+ chipcHw_CLOCK_ESW, /* Ethernet Switch Clock */
+ chipcHw_CLOCK_VPM, /* VPM Clock */
+ chipcHw_CLOCK_ESW125, /* Ethernet MII Clock */
+ chipcHw_CLOCK_UART, /* UART Clock */
+ chipcHw_CLOCK_SDIO0, /* SDIO 0 Clock */
+ chipcHw_CLOCK_SDIO1, /* SDIO 1 Clock */
+ chipcHw_CLOCK_SPI, /* SPI Clock */
+ chipcHw_CLOCK_ETM, /* ARM ETM Clock */
+
+ chipcHw_CLOCK_BUS, /* BUS Clock */
+ chipcHw_CLOCK_OTP, /* OTP Clock */
+ chipcHw_CLOCK_I2C, /* I2C Host Clock */
+ chipcHw_CLOCK_I2S0, /* I2S 0 Host Clock */
+ chipcHw_CLOCK_RTBUS, /* DDR PHY Configuration Clock */
+ chipcHw_CLOCK_APM100, /* APM100 Clock */
+ chipcHw_CLOCK_TSC, /* Touch screen Clock */
+ chipcHw_CLOCK_LED, /* LED Clock */
+
+ chipcHw_CLOCK_USB, /* USB Clock */
+ chipcHw_CLOCK_LCD, /* LCD CLock */
+ chipcHw_CLOCK_APM, /* APM Clock */
+
+ chipcHw_CLOCK_I2S1, /* I2S 1 Host Clock */
+} chipcHw_CLOCK_e;
+
+/* System booting strap options */
+typedef enum {
+ chipcHw_BOOT_DEVICE_UART = chipcHw_STRAPS_BOOT_DEVICE_UART,
+ chipcHw_BOOT_DEVICE_SERIAL_FLASH =
+ chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH,
+ chipcHw_BOOT_DEVICE_NOR_FLASH_16 =
+ chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16,
+ chipcHw_BOOT_DEVICE_NAND_FLASH_8 =
+ chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8,
+ chipcHw_BOOT_DEVICE_NAND_FLASH_16 =
+ chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16
+} chipcHw_BOOT_DEVICE_e;
+
+/* System booting modes */
+typedef enum {
+ chipcHw_BOOT_MODE_NORMAL = chipcHw_STRAPS_BOOT_MODE_NORMAL,
+ chipcHw_BOOT_MODE_DBG_SW = chipcHw_STRAPS_BOOT_MODE_DBG_SW,
+ chipcHw_BOOT_MODE_DBG_BOOT = chipcHw_STRAPS_BOOT_MODE_DBG_BOOT,
+ chipcHw_BOOT_MODE_NORMAL_QUIET = chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET
+} chipcHw_BOOT_MODE_e;
+
+/* NAND Flash page size strap options */
+typedef enum {
+ chipcHw_NAND_PAGESIZE_512 = chipcHw_STRAPS_NAND_PAGESIZE_512,
+ chipcHw_NAND_PAGESIZE_2048 = chipcHw_STRAPS_NAND_PAGESIZE_2048,
+ chipcHw_NAND_PAGESIZE_4096 = chipcHw_STRAPS_NAND_PAGESIZE_4096,
+ chipcHw_NAND_PAGESIZE_EXT = chipcHw_STRAPS_NAND_PAGESIZE_EXT
+} chipcHw_NAND_PAGESIZE_e;
+
+/* GPIO Pin function */
+typedef enum {
+ chipcHw_GPIO_FUNCTION_KEYPAD = chipcHw_REG_GPIO_MUX_KEYPAD,
+ chipcHw_GPIO_FUNCTION_I2CH = chipcHw_REG_GPIO_MUX_I2CH,
+ chipcHw_GPIO_FUNCTION_SPI = chipcHw_REG_GPIO_MUX_SPI,
+ chipcHw_GPIO_FUNCTION_UART = chipcHw_REG_GPIO_MUX_UART,
+ chipcHw_GPIO_FUNCTION_LEDMTXP = chipcHw_REG_GPIO_MUX_LEDMTXP,
+ chipcHw_GPIO_FUNCTION_LEDMTXS = chipcHw_REG_GPIO_MUX_LEDMTXS,
+ chipcHw_GPIO_FUNCTION_SDIO0 = chipcHw_REG_GPIO_MUX_SDIO0,
+ chipcHw_GPIO_FUNCTION_SDIO1 = chipcHw_REG_GPIO_MUX_SDIO1,
+ chipcHw_GPIO_FUNCTION_PCM = chipcHw_REG_GPIO_MUX_PCM,
+ chipcHw_GPIO_FUNCTION_I2S = chipcHw_REG_GPIO_MUX_I2S,
+ chipcHw_GPIO_FUNCTION_ETM = chipcHw_REG_GPIO_MUX_ETM,
+ chipcHw_GPIO_FUNCTION_DEBUG = chipcHw_REG_GPIO_MUX_DEBUG,
+ chipcHw_GPIO_FUNCTION_MISC = chipcHw_REG_GPIO_MUX_MISC,
+ chipcHw_GPIO_FUNCTION_GPIO = chipcHw_REG_GPIO_MUX_GPIO
+} chipcHw_GPIO_FUNCTION_e;
+
+/* PIN Output slew rate */
+typedef enum {
+ chipcHw_PIN_SLEW_RATE_HIGH = chipcHw_REG_SLEW_RATE_HIGH,
+ chipcHw_PIN_SLEW_RATE_NORMAL = chipcHw_REG_SLEW_RATE_NORMAL
+} chipcHw_PIN_SLEW_RATE_e;
+
+/* PIN Current drive strength */
+typedef enum {
+ chipcHw_PIN_CURRENT_STRENGTH_2mA = chipcHw_REG_CURRENT_STRENGTH_2mA,
+ chipcHw_PIN_CURRENT_STRENGTH_4mA = chipcHw_REG_CURRENT_STRENGTH_4mA,
+ chipcHw_PIN_CURRENT_STRENGTH_6mA = chipcHw_REG_CURRENT_STRENGTH_6mA,
+ chipcHw_PIN_CURRENT_STRENGTH_8mA = chipcHw_REG_CURRENT_STRENGTH_8mA,
+ chipcHw_PIN_CURRENT_STRENGTH_10mA = chipcHw_REG_CURRENT_STRENGTH_10mA,
+ chipcHw_PIN_CURRENT_STRENGTH_12mA = chipcHw_REG_CURRENT_STRENGTH_12mA
+} chipcHw_PIN_CURRENT_STRENGTH_e;
+
+/* PIN Pull up register settings */
+typedef enum {
+ chipcHw_PIN_PULL_NONE = chipcHw_REG_PULL_NONE,
+ chipcHw_PIN_PULL_UP = chipcHw_REG_PULL_UP,
+ chipcHw_PIN_PULL_DOWN = chipcHw_REG_PULL_DOWN
+} chipcHw_PIN_PULL_e;
+
+/* PIN input type settings */
+typedef enum {
+ chipcHw_PIN_INPUTTYPE_CMOS = chipcHw_REG_INPUTTYPE_CMOS,
+ chipcHw_PIN_INPUTTYPE_ST = chipcHw_REG_INPUTTYPE_ST
+} chipcHw_PIN_INPUTTYPE_e;
+
+/* Allow/Disalow the support of spread spectrum */
+typedef enum {
+ chipcHw_SPREAD_SPECTRUM_DISALLOW, /* Spread spectrum support is not allowed */
+ chipcHw_SPREAD_SPECTRUM_ALLOW /* Spread spectrum support is allowed */
+} chipcHw_SPREAD_SPECTRUM_e;
+
+typedef struct {
+ chipcHw_SPREAD_SPECTRUM_e ssSupport; /* Allow/Disalow to support spread spectrum.
+ If supported, call chipcHw_enableSpreadSpectrum ()
+ to activate the spread spectrum with desired spread. */
+ uint32_t pllVcoFreqHz; /* PLL VCO frequency in Hz */
+ uint32_t pll2VcoFreqHz; /* PLL2 VCO frequency in Hz */
+ uint32_t busClockFreqHz; /* Bus clock frequency in Hz */
+ uint32_t armBusRatio; /* ARM clock : Bus clock */
+ uint32_t vpmBusRatio; /* VPM clock : Bus clock */
+ uint32_t ddrBusRatio; /* DDR clock : Bus clock */
+} chipcHw_INIT_PARAM_t;
+
+/* CHIP revision number */
+typedef enum {
+ chipcHw_REV_NUMBER_A0 = chipcHw_REG_REV_A0,
+ chipcHw_REV_NUMBER_B0 = chipcHw_REG_REV_B0
+} chipcHw_REV_NUMBER_e;
+
+typedef enum {
+ chipcHw_VPM_HW_PHASE_INTR_DISABLE = chipcHw_REG_VPM_INTR_DISABLE,
+ chipcHw_VPM_HW_PHASE_INTR_FAST = chipcHw_REG_VPM_INTR_FAST,
+ chipcHw_VPM_HW_PHASE_INTR_MEDIUM = chipcHw_REG_VPM_INTR_MEDIUM,
+ chipcHw_VPM_HW_PHASE_INTR_SLOW = chipcHw_REG_VPM_INTR_SLOW
+} chipcHw_VPM_HW_PHASE_INTR_e;
+
+typedef enum {
+ chipcHw_DDR_HW_PHASE_MARGIN_STRICT, /* Strict margin for DDR phase align condition */
+ chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for DDR phase align condition */
+ chipcHw_DDR_HW_PHASE_MARGIN_WIDE /* Wider margin for DDR phase align condition */
+} chipcHw_DDR_HW_PHASE_MARGIN_e;
+
+typedef enum {
+ chipcHw_VPM_HW_PHASE_MARGIN_STRICT, /* Strict margin for VPM phase align condition */
+ chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM, /* Medium margin for VPM phase align condition */
+ chipcHw_VPM_HW_PHASE_MARGIN_WIDE /* Wider margin for VPM phase align condition */
+} chipcHw_VPM_HW_PHASE_MARGIN_e;
+
+#define chipcHw_XTAL_FREQ_Hz 25000000 /* Reference clock frequency in Hz */
+
+/* Programmable pin defines */
+#define chipcHw_PIN_GPIO(n) ((((n) >= 0) && ((n) < (chipcHw_GPIO_COUNT))) ? (n) : 0xFFFFFFFF)
+ /* GPIO pin 0 - 60 */
+#define chipcHw_PIN_UARTTXD (chipcHw_GPIO_COUNT + 0) /* UART Transmit */
+#define chipcHw_PIN_NVI_A (chipcHw_GPIO_COUNT + 1) /* NVI Interface */
+#define chipcHw_PIN_NVI_D (chipcHw_GPIO_COUNT + 2) /* NVI Interface */
+#define chipcHw_PIN_NVI_OEB (chipcHw_GPIO_COUNT + 3) /* NVI Interface */
+#define chipcHw_PIN_NVI_WEB (chipcHw_GPIO_COUNT + 4) /* NVI Interface */
+#define chipcHw_PIN_NVI_CS (chipcHw_GPIO_COUNT + 5) /* NVI Interface */
+#define chipcHw_PIN_NVI_NAND_CSB (chipcHw_GPIO_COUNT + 6) /* NVI Interface */
+#define chipcHw_PIN_NVI_FLASHWP (chipcHw_GPIO_COUNT + 7) /* NVI Interface */
+#define chipcHw_PIN_NVI_NAND_RDYB (chipcHw_GPIO_COUNT + 8) /* NVI Interface */
+#define chipcHw_PIN_CL_DATA_0_17 (chipcHw_GPIO_COUNT + 9) /* LCD Data 0 - 17 */
+#define chipcHw_PIN_CL_DATA_18_20 (chipcHw_GPIO_COUNT + 10) /* LCD Data 18 - 20 */
+#define chipcHw_PIN_CL_DATA_21_23 (chipcHw_GPIO_COUNT + 11) /* LCD Data 21 - 23 */
+#define chipcHw_PIN_CL_POWER (chipcHw_GPIO_COUNT + 12) /* LCD Power */
+#define chipcHw_PIN_CL_ACK (chipcHw_GPIO_COUNT + 13) /* LCD Ack */
+#define chipcHw_PIN_CL_FP (chipcHw_GPIO_COUNT + 14) /* LCD FP */
+#define chipcHw_PIN_CL_LP (chipcHw_GPIO_COUNT + 15) /* LCD LP */
+#define chipcHw_PIN_UARTRXD (chipcHw_GPIO_COUNT + 16) /* UART Receive */
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+/****************************************************************************/
+/**
+* @brief Initializes the clock module
+*
+*/
+/****************************************************************************/
+void chipcHw_Init(chipcHw_INIT_PARAM_t *initParam /* [ IN ] Misc chip initialization parameter */
+ ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Enables the PLL1
+*
+* This function enables the PLL1
+*
+*/
+/****************************************************************************/
+void chipcHw_pll1Enable(uint32_t vcoFreqHz, /* [ IN ] VCO frequency in Hz */
+ chipcHw_SPREAD_SPECTRUM_e ssSupport /* [ IN ] SS status */
+ ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Enables the PLL2
+*
+* This function enables the PLL2
+*
+*/
+/****************************************************************************/
+void chipcHw_pll2Enable(uint32_t vcoFreqHz /* [ IN ] VCO frequency in Hz */
+ ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Disable the PLL1
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll1Disable(void);
+
+/****************************************************************************/
+/**
+* @brief Disable the PLL2
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll2Disable(void);
+
+/****************************************************************************/
+/**
+* @brief Set clock fequency for miscellaneous configurable clocks
+*
+* This function sets clock frequency
+*
+* @return Configured clock frequency in KHz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_getClockFrequency(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Set clock fequency for miscellaneous configurable clocks
+*
+* This function sets clock frequency
+*
+* @return Configured clock frequency in Hz
+*
+*/
+/****************************************************************************/
+chipcHw_freq chipcHw_setClockFrequency(chipcHw_CLOCK_e clock, /* [ IN ] Configurable clock */
+ uint32_t freq /* [ IN ] Clock frequency in Hz */
+ ) __attribute__ ((section(".aramtext")));
+
+/****************************************************************************/
+/**
+* @brief Set VPM clock in sync with BUS clock
+*
+* This function does the phase adjustment between VPM and BUS clock
+*
+* @return >= 0 : On success ( # of adjustment required )
+* -1 : On failure
+*/
+/****************************************************************************/
+int chipcHw_vpmPhaseAlign(void);
+
+/****************************************************************************/
+/**
+* @brief Enables core a clock of a certain device
+*
+* This function enables a core clock
+*
+* @return void
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ );
+
+/****************************************************************************/
+/**
+* @brief Disabled a core clock of a certain device
+*
+* This function disables a core clock
+*
+* @return void
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ );
+
+/****************************************************************************/
+/**
+* @brief Enables bypass clock of a certain device
+*
+* This function enables bypass clock
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ );
+
+/****************************************************************************/
+/**
+* @brief Disabled bypass clock of a certain device
+*
+* This function disables bypass clock
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock /* [ IN ] Configurable clock */
+ );
+
+/****************************************************************************/
+/**
+* @brief Get Numeric Chip ID
+*
+* This function returns Chip ID that includes the revison number
+*
+* @return Complete numeric Chip ID
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipId(void);
+
+/****************************************************************************/
+/**
+* @brief Get Chip Product ID
+*
+* This function returns Chip Product ID
+*
+* @return Chip Product ID
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipProductId(void);
+
+/****************************************************************************/
+/**
+* @brief Get revision number
+*
+* This function returns revision number of the chip
+*
+* @return Revision number
+*/
+/****************************************************************************/
+static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void);
+
+/****************************************************************************/
+/**
+* @brief Enables bus interface clock
+*
+* Enables bus interface clock of various device
+*
+* @return void
+*
+* @note use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Disables bus interface clock
+*
+* Disables bus interface clock of various device
+*
+* @return void
+*
+* @note use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_BUS_CLOCK_XXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Enables various audio channels
+*
+* Enables audio channel
+*
+* @return void
+*
+* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Disables various audio channels
+*
+* Disables audio channel
+*
+* @return void
+*
+* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_AUDIO_CHANNEL_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Soft resets devices
+*
+* Soft resets various devices
+*
+* @return void
+*
+* @note use chipcHw_REG_SOFT_RESET_XXXXXX defines
+*/
+/****************************************************************************/
+static inline void chipcHw_softReset(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+ );
+
+static inline void chipcHw_softResetDisable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+ );
+
+static inline void chipcHw_softResetEnable(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_SOFT_RESET_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Configures misc CHIP functionality
+*
+* Configures CHIP functionality
+*
+* @return void
+*
+* @note use chipcHw_REG_MISC_CTRL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_miscControl(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+ );
+
+static inline void chipcHw_miscControlDisable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+ );
+
+static inline void chipcHw_miscControlEnable(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_MISC_CTRL_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set OTP options
+*
+* Set OTP options
+*
+* @return void
+*
+* @note use chipcHw_REG_OTP_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setOTPOption(uint64_t mask /* [ IN ] Bit map of type chipcHw_REG_OTP_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Get sticky bits
+*
+* @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getStickyBits(void);
+
+/****************************************************************************/
+/**
+* @brief Set sticky bits
+*
+* @return void
+*
+* @note use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Clear sticky bits
+*
+* @return void
+*
+* @note use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_clearStickyBits(uint32_t mask /* [ IN ] Bit map of type chipcHw_REG_STICKY_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Get software override strap options
+*
+* Retrieves software override strap options
+*
+* @return Software override strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getSoftStraps(void);
+
+/****************************************************************************/
+/**
+* @brief Set software override strap options
+*
+* set software override strap options
+*
+* @return nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setSoftStraps(uint32_t strapOptions);
+
+/****************************************************************************/
+/**
+* @brief Get pin strap options
+*
+* Retrieves pin strap options
+*
+* @return Pin strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getPinStraps(void);
+
+/****************************************************************************/
+/**
+* @brief Get valid pin strap options
+*
+* Retrieves valid pin strap options
+*
+* @return valid Pin strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getValidStraps(void);
+
+/****************************************************************************/
+/**
+* @brief Initialize valid pin strap options
+*
+* Retrieves valid pin strap options by copying HW strap options to soft register
+* (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
+*
+* @return nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_initValidStraps(void);
+
+/****************************************************************************/
+/**
+* @brief Get status (enabled/disabled) of bus interface clock
+*
+* This function returns the status of devices' bus interface clock
+*
+* @return Bus interface clock
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getBusInterfaceClockStatus(void);
+
+/****************************************************************************/
+/**
+* @brief Get boot device
+*
+* This function returns the device type used in booting the system
+*
+* @return Boot device of type chipcHw_BOOT_DEVICE_e
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void);
+
+/****************************************************************************/
+/**
+* @brief Get boot mode
+*
+* This function returns the way the system was booted
+*
+* @return Boot mode of type chipcHw_BOOT_MODE_e
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void);
+
+/****************************************************************************/
+/**
+* @brief Get NAND flash page size
+*
+* This function returns the NAND device page size
+*
+* @return Boot NAND device page size
+*
+*/
+/****************************************************************************/
+static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void);
+
+/****************************************************************************/
+/**
+* @brief Get NAND flash address cycle configuration
+*
+* This function returns the NAND flash address cycle configuration
+*
+* @return 0 = Do not extra address cycle, 1 = Add extra cycle
+*
+*/
+/****************************************************************************/
+static inline int chipcHw_getNandExtraCycle(void);
+
+/****************************************************************************/
+/**
+* @brief Activates PIF interface
+*
+* This function activates PIF interface by taking control of LCD pins
+*
+* @note
+* When activated, LCD pins will be defined as follows for PIF operation
+*
+* CLD[17:0] = pif_data[17:0]
+* CLD[23:18] = pif_address[5:0]
+* CLPOWER = pif_wr_str
+* CLCP = pif_rd_str
+* CLAC = pif_hat1
+* CLFP = pif_hrdy1
+* CLLP = pif_hat2
+* GPIO[42] = pif_hrdy2
+*
+* In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_activatePifInterface(void);
+
+/****************************************************************************/
+/**
+* @brief Activates LCD interface
+*
+* This function activates LCD interface
+*
+* @note
+* When activated, LCD pins will be defined as follows
+*
+* CLD[17:0] = LCD data
+* CLD[23:18] = LCD data
+* CLPOWER = LCD power
+* CLCP =
+* CLAC = LCD ack
+* CLFP =
+* CLLP =
+*/
+/****************************************************************************/
+static inline void chipcHw_activateLcdInterface(void);
+
+/****************************************************************************/
+/**
+* @brief Deactivates PIF/LCD interface
+*
+* This function deactivates PIF/LCD interface
+*
+* @note
+* When deactivated LCD pins will be in rti-stated
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_deactivatePifLcdInterface(void);
+
+/****************************************************************************/
+/**
+* @brief Get to know the configuration of GPIO pin
+*
+*/
+/****************************************************************************/
+static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin /* GPIO Pin number */
+ );
+
+/****************************************************************************/
+/**
+* @brief Configure GPIO pin function
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setGpioPinFunction(int pin, /* GPIO Pin number */
+ chipcHw_GPIO_FUNCTION_e func /* Configuration function */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set Pin slew rate
+*
+* This function sets the slew of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinSlewRate(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
+ chipcHw_PIN_SLEW_RATE_e slewRate /* Pin slew rate */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set Pin output drive current
+*
+* This function sets output drive current of individual pin
+*
+* Note: Avoid the use of the word 'current' since linux headers define this
+* to be the current task.
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinOutputCurrent(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
+ chipcHw_PIN_CURRENT_STRENGTH_e curr /* Pin current rating */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set Pin pullup register
+*
+* This function sets pullup register of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinPullup(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
+ chipcHw_PIN_PULL_e pullup /* Pullup register settings */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set Pin input type
+*
+* This function sets input type of individual Pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinInputType(uint32_t pin, /* Pin of type chipcHw_PIN_XXXXX */
+ chipcHw_PIN_INPUTTYPE_e inputType /* Pin input type */
+ );
+
+/****************************************************************************/
+/**
+* @brief Retrieves a string representation of the mux setting for a pin.
+*
+* @return Pointer to a character string.
+*/
+/****************************************************************************/
+
+const char *chipcHw_getGpioPinFunctionStr(int pin);
+
+/****************************************************************************/
+/** @brief issue warmReset
+ */
+/****************************************************************************/
+void chipcHw_reset(uint32_t mask);
+
+/****************************************************************************/
+/** @brief clock reconfigure
+ */
+/****************************************************************************/
+void chipcHw_clockReconfig(uint32_t busHz, uint32_t armRatio, uint32_t vpmRatio,
+ uint32_t ddrRatio);
+
+/****************************************************************************/
+/**
+* @brief Enable Spread Spectrum
+*
+* @note chipcHw_Init() must be called earlier
+*/
+/****************************************************************************/
+static inline void chipcHw_enableSpreadSpectrum(void);
+
+/****************************************************************************/
+/**
+* @brief Disable Spread Spectrum
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_disableSpreadSpectrum(void);
+
+/****************************************************************************/
+/** @brief Checks if software strap is enabled
+ *
+ * @return 1 : When enable
+ * 0 : When disable
+ */
+/****************************************************************************/
+static inline int chipcHw_isSoftwareStrapsEnable(void);
+
+/****************************************************************************/
+/** @brief Enable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsEnable(void);
+
+/****************************************************************************/
+/** @brief Disable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsDisable(void);
+
+/****************************************************************************/
+/** @brief PLL test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestEnable(void);
+
+/****************************************************************************/
+/** @brief PLL2 test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestEnable(void);
+
+/****************************************************************************/
+/** @brief PLL test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestDisable(void);
+
+/****************************************************************************/
+/** @brief PLL2 test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestDisable(void);
+
+/****************************************************************************/
+/** @brief Get PLL test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPllTestEnable(void);
+
+/****************************************************************************/
+/** @brief Get PLL2 test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPll2TestEnable(void);
+
+/****************************************************************************/
+/** @brief PLL test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestSelect(uint32_t val);
+
+/****************************************************************************/
+/** @brief PLL2 test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestSelect(uint32_t val);
+
+/****************************************************************************/
+/** @brief Get PLL test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPllTestSelected(void);
+
+/****************************************************************************/
+/** @brief Get PLL2 test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPll2TestSelected(void);
+
+/****************************************************************************/
+/**
+* @brief Enables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptEnable(void);
+
+/****************************************************************************/
+/**
+* @brief Disables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Set VPM SW phase alignment interrupt mode
+*
+* This function sets VPM phase alignment interrupt
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode);
+
+/****************************************************************************/
+/**
+* @brief Enable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+* @brief Disable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Enable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+* @brief Disable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Enable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+* @brief Disable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Enable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignEnable(void);
+
+/****************************************************************************/
+/**
+* @brief Disable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Set DDR phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin /* Margin alinging DDR phase */
+ );
+
+/****************************************************************************/
+/**
+* @brief Set VPM phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin /* Margin alinging VPM phase */
+ );
+
+/****************************************************************************/
+/**
+* @brief Checks DDR phase aligned status done by HW
+*
+* @return 1: When aligned
+* 0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isDdrHwPhaseAligned(void);
+
+/****************************************************************************/
+/**
+* @brief Checks VPM phase aligned status done by HW
+*
+* @return 1: When aligned
+* 0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isVpmHwPhaseAligned(void);
+
+/****************************************************************************/
+/**
+* @brief Get DDR phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void);
+
+/****************************************************************************/
+/**
+* @brief Get VPM phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void);
+
+/****************************************************************************/
+/**
+* @brief Get DDR phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrPhaseControl(void);
+
+/****************************************************************************/
+/**
+* @brief Get VPM phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmPhaseControl(void);
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout count
+*
+* @note If HW fails to perform the phase alignment, it will trigger
+* a DDR phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */
+ );
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout count
+*
+* @note If HW fails to perform the phase alignment, it will trigger
+* a VPM phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle /* Timeout in bus cycle */
+ );
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void);
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void);
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void);
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void);
+
+/****************************************************************************/
+/**
+* @brief Clear DDR phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void);
+
+/****************************************************************************/
+/**
+* @brief Clear VPM phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void);
+
+/* ---- Private Constants and Types -------------------------------------- */
+
+#endif /* CHIPC_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
new file mode 100644
index 00000000..03238c29
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_inline.h
@@ -0,0 +1,1673 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef CHIPC_INLINE_H
+#define CHIPC_INLINE_H
+
+/* ---- Include Files ----------------------------------------------------- */
+
+#include <csp/errno.h>
+#include <csp/reg.h>
+#include <mach/csp/chipcHw_reg.h>
+#include <mach/csp/chipcHw_def.h>
+
+/* ---- Private Constants and Types --------------------------------------- */
+typedef enum {
+ chipcHw_OPTYPE_BYPASS, /* Bypass operation */
+ chipcHw_OPTYPE_OUTPUT /* Output operation */
+} chipcHw_OPTYPE_e;
+
+/* ---- Public Constants and Types ---------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------- */
+/* ---- Public Function Prototypes ---------------------------------------- */
+/* ---- Private Function Prototypes --------------------------------------- */
+static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
+ chipcHw_OPTYPE_e type, int mode);
+
+/****************************************************************************/
+/**
+* @brief Get Numeric Chip ID
+*
+* This function returns Chip ID that includes the revison number
+*
+* @return Complete numeric Chip ID
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipId(void)
+{
+ return pChipcHw->ChipId;
+}
+
+/****************************************************************************/
+/**
+* @brief Enable Spread Spectrum
+*
+* @note chipcHw_Init() must be called earlier
+*/
+/****************************************************************************/
+static inline void chipcHw_enableSpreadSpectrum(void)
+{
+ if ((pChipcHw->
+ PLLPreDivider & chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK) !=
+ chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER) {
+ ddrcReg_PHY_ADDR_CTL_REGP->ssCfg =
+ (0xFFFF << ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT) |
+ (ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK <<
+ ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT);
+ ddrcReg_PHY_ADDR_CTL_REGP->ssCtl |=
+ ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disable Spread Spectrum
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_disableSpreadSpectrum(void)
+{
+ ddrcReg_PHY_ADDR_CTL_REGP->ssCtl &= ~ddrcReg_PHY_ADDR_SS_CTRL_ENABLE;
+}
+
+/****************************************************************************/
+/**
+* @brief Get Chip Product ID
+*
+* This function returns Chip Product ID
+*
+* @return Chip Product ID
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getChipProductId(void)
+{
+ return (pChipcHw->
+ ChipId & chipcHw_REG_CHIPID_BASE_MASK) >>
+ chipcHw_REG_CHIPID_BASE_SHIFT;
+}
+
+/****************************************************************************/
+/**
+* @brief Get revision number
+*
+* This function returns revision number of the chip
+*
+* @return Revision number
+*/
+/****************************************************************************/
+static inline chipcHw_REV_NUMBER_e chipcHw_getChipRevisionNumber(void)
+{
+ return pChipcHw->ChipId & chipcHw_REG_CHIPID_REV_MASK;
+}
+
+/****************************************************************************/
+/**
+* @brief Enables bus interface clock
+*
+* Enables bus interface clock of various device
+*
+* @return void
+*
+* @note use chipcHw_REG_BUS_CLOCK_XXXX for mask
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockEnable(uint32_t mask)
+{
+ reg32_modify_or(&pChipcHw->BusIntfClock, mask);
+}
+
+/****************************************************************************/
+/**
+* @brief Disables bus interface clock
+*
+* Disables bus interface clock of various device
+*
+* @return void
+*
+* @note use chipcHw_REG_BUS_CLOCK_XXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_busInterfaceClockDisable(uint32_t mask)
+{
+ reg32_modify_and(&pChipcHw->BusIntfClock, ~mask);
+}
+
+/****************************************************************************/
+/**
+* @brief Get status (enabled/disabled) of bus interface clock
+*
+* This function returns the status of devices' bus interface clock
+*
+* @return Bus interface clock
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getBusInterfaceClockStatus(void)
+{
+ return pChipcHw->BusIntfClock;
+}
+
+/****************************************************************************/
+/**
+* @brief Enables various audio channels
+*
+* Enables audio channel
+*
+* @return void
+*
+* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelEnable(uint32_t mask)
+{
+ reg32_modify_or(&pChipcHw->AudioEnable, mask);
+}
+
+/****************************************************************************/
+/**
+* @brief Disables various audio channels
+*
+* Disables audio channel
+*
+* @return void
+*
+* @note use chipcHw_REG_AUDIO_CHANNEL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_audioChannelDisable(uint32_t mask)
+{
+ reg32_modify_and(&pChipcHw->AudioEnable, ~mask);
+}
+
+/****************************************************************************/
+/**
+* @brief Soft resets devices
+*
+* Soft resets various devices
+*
+* @return void
+*
+* @note use chipcHw_REG_SOFT_RESET_XXXXXX defines
+*/
+/****************************************************************************/
+static inline void chipcHw_softReset(uint64_t mask)
+{
+ chipcHw_softResetEnable(mask);
+ chipcHw_softResetDisable(mask);
+}
+
+static inline void chipcHw_softResetDisable(uint64_t mask)
+{
+ uint32_t ctrl1 = (uint32_t) mask;
+ uint32_t ctrl2 = (uint32_t) (mask >> 32);
+
+ /* Deassert module soft reset */
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->SoftReset1 ^= ctrl1;
+ pChipcHw->SoftReset2 ^= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+static inline void chipcHw_softResetEnable(uint64_t mask)
+{
+ uint32_t ctrl1 = (uint32_t) mask;
+ uint32_t ctrl2 = (uint32_t) (mask >> 32);
+ uint32_t unhold = 0;
+
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->SoftReset1 |= ctrl1;
+ /* Mask out unhold request bits */
+ pChipcHw->SoftReset2 |= (ctrl2 & (~chipcHw_REG_SOFT_RESET_UNHOLD_MASK));
+
+ /* Process unhold requests */
+ if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD) {
+ unhold = chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD;
+ }
+
+ if (ctrl2 & chipcHw_REG_SOFT_RESET_VPM_UNHOLD) {
+ unhold |= chipcHw_REG_SOFT_RESET_VPM_HOLD;
+ }
+
+ if (ctrl2 & chipcHw_REG_SOFT_RESET_ARM_UNHOLD) {
+ unhold |= chipcHw_REG_SOFT_RESET_ARM_HOLD;
+ }
+
+ if (unhold) {
+ /* Make sure unhold request is effective */
+ pChipcHw->SoftReset1 &= ~unhold;
+ }
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Configures misc CHIP functionality
+*
+* Configures CHIP functionality
+*
+* @return void
+*
+* @note use chipcHw_REG_MISC_CTRL_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_miscControl(uint32_t mask)
+{
+ reg32_write(&pChipcHw->MiscCtrl, mask);
+}
+
+static inline void chipcHw_miscControlDisable(uint32_t mask)
+{
+ reg32_modify_and(&pChipcHw->MiscCtrl, ~mask);
+}
+
+static inline void chipcHw_miscControlEnable(uint32_t mask)
+{
+ reg32_modify_or(&pChipcHw->MiscCtrl, mask);
+}
+
+/****************************************************************************/
+/**
+* @brief Set OTP options
+*
+* Set OTP options
+*
+* @return void
+*
+* @note use chipcHw_REG_OTP_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setOTPOption(uint64_t mask)
+{
+ uint32_t ctrl1 = (uint32_t) mask;
+ uint32_t ctrl2 = (uint32_t) (mask >> 32);
+
+ reg32_modify_or(&pChipcHw->SoftOTP1, ctrl1);
+ reg32_modify_or(&pChipcHw->SoftOTP2, ctrl2);
+}
+
+/****************************************************************************/
+/**
+* @brief Get sticky bits
+*
+* @return Sticky bit options of type chipcHw_REG_STICKY_XXXXXX
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getStickyBits(void)
+{
+ return pChipcHw->Sticky;
+}
+
+/****************************************************************************/
+/**
+* @brief Set sticky bits
+*
+* @return void
+*
+* @note use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_setStickyBits(uint32_t mask)
+{
+ uint32_t bits = 0;
+
+ REG_LOCAL_IRQ_SAVE;
+ if (mask & chipcHw_REG_STICKY_POR_BROM) {
+ bits |= chipcHw_REG_STICKY_POR_BROM;
+ } else {
+ uint32_t sticky;
+ sticky = pChipcHw->Sticky;
+
+ if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
+ && (sticky & chipcHw_REG_STICKY_BOOT_DONE) == 0) {
+ bits |= chipcHw_REG_STICKY_BOOT_DONE;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_1)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_1) == 0) {
+ bits |= chipcHw_REG_STICKY_GENERAL_1;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_2)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_2) == 0) {
+ bits |= chipcHw_REG_STICKY_GENERAL_2;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_3)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_3) == 0) {
+ bits |= chipcHw_REG_STICKY_GENERAL_3;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_4)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_4) == 0) {
+ bits |= chipcHw_REG_STICKY_GENERAL_4;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_5)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_5) == 0) {
+ bits |= chipcHw_REG_STICKY_GENERAL_5;
+ }
+ }
+ pChipcHw->Sticky = bits;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Clear sticky bits
+*
+* @return void
+*
+* @note use chipcHw_REG_STICKY_XXXXXX
+*/
+/****************************************************************************/
+static inline void chipcHw_clearStickyBits(uint32_t mask)
+{
+ uint32_t bits = 0;
+
+ REG_LOCAL_IRQ_SAVE;
+ if (mask &
+ (chipcHw_REG_STICKY_BOOT_DONE | chipcHw_REG_STICKY_GENERAL_1 |
+ chipcHw_REG_STICKY_GENERAL_2 | chipcHw_REG_STICKY_GENERAL_3 |
+ chipcHw_REG_STICKY_GENERAL_4 | chipcHw_REG_STICKY_GENERAL_5)) {
+ uint32_t sticky = pChipcHw->Sticky;
+
+ if ((mask & chipcHw_REG_STICKY_BOOT_DONE)
+ && (sticky & chipcHw_REG_STICKY_BOOT_DONE)) {
+ bits = chipcHw_REG_STICKY_BOOT_DONE;
+ mask &= ~chipcHw_REG_STICKY_BOOT_DONE;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_1)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_1)) {
+ bits |= chipcHw_REG_STICKY_GENERAL_1;
+ mask &= ~chipcHw_REG_STICKY_GENERAL_1;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_2)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_2)) {
+ bits |= chipcHw_REG_STICKY_GENERAL_2;
+ mask &= ~chipcHw_REG_STICKY_GENERAL_2;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_3)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_3)) {
+ bits |= chipcHw_REG_STICKY_GENERAL_3;
+ mask &= ~chipcHw_REG_STICKY_GENERAL_3;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_4)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_4)) {
+ bits |= chipcHw_REG_STICKY_GENERAL_4;
+ mask &= ~chipcHw_REG_STICKY_GENERAL_4;
+ }
+ if ((mask & chipcHw_REG_STICKY_GENERAL_5)
+ && (sticky & chipcHw_REG_STICKY_GENERAL_5)) {
+ bits |= chipcHw_REG_STICKY_GENERAL_5;
+ mask &= ~chipcHw_REG_STICKY_GENERAL_5;
+ }
+ }
+ pChipcHw->Sticky = bits | mask;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Get software strap value
+*
+* Retrieves software strap value
+*
+* @return Software strap value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getSoftStraps(void)
+{
+ return pChipcHw->SoftStraps;
+}
+
+/****************************************************************************/
+/**
+* @brief Set software override strap options
+*
+* set software override strap options
+*
+* @return nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setSoftStraps(uint32_t strapOptions)
+{
+ reg32_write(&pChipcHw->SoftStraps, strapOptions);
+}
+
+/****************************************************************************/
+/**
+* @brief Get Pin Strap Options
+*
+* This function returns the raw boot strap options
+*
+* @return strap options
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getPinStraps(void)
+{
+ return pChipcHw->PinStraps;
+}
+
+/****************************************************************************/
+/**
+* @brief Get Valid Strap Options
+*
+* This function returns the valid raw boot strap options
+*
+* @return strap options
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getValidStraps(void)
+{
+ uint32_t softStraps;
+
+ /*
+ ** Always return the SoftStraps - bootROM calls chipcHw_initValidStraps
+ ** which copies HW straps to soft straps if there is no override
+ */
+ softStraps = chipcHw_getSoftStraps();
+
+ return softStraps;
+}
+
+/****************************************************************************/
+/**
+* @brief Initialize valid pin strap options
+*
+* Retrieves valid pin strap options by copying HW strap options to soft register
+* (if chipcHw_STRAPS_SOFT_OVERRIDE not set)
+*
+* @return nothing
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_initValidStraps(void)
+{
+ uint32_t softStraps;
+
+ REG_LOCAL_IRQ_SAVE;
+ softStraps = chipcHw_getSoftStraps();
+
+ if ((softStraps & chipcHw_STRAPS_SOFT_OVERRIDE) == 0) {
+ /* Copy HW straps to software straps */
+ chipcHw_setSoftStraps(chipcHw_getPinStraps());
+ }
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Get boot device
+*
+* This function returns the device type used in booting the system
+*
+* @return Boot device of type chipcHw_BOOT_DEVICE
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_DEVICE_e chipcHw_getBootDevice(void)
+{
+ return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_DEVICE_MASK;
+}
+
+/****************************************************************************/
+/**
+* @brief Get boot mode
+*
+* This function returns the way the system was booted
+*
+* @return Boot mode of type chipcHw_BOOT_MODE
+*
+*/
+/****************************************************************************/
+static inline chipcHw_BOOT_MODE_e chipcHw_getBootMode(void)
+{
+ return chipcHw_getValidStraps() & chipcHw_STRAPS_BOOT_MODE_MASK;
+}
+
+/****************************************************************************/
+/**
+* @brief Get NAND flash page size
+*
+* This function returns the NAND device page size
+*
+* @return Boot NAND device page size
+*
+*/
+/****************************************************************************/
+static inline chipcHw_NAND_PAGESIZE_e chipcHw_getNandPageSize(void)
+{
+ return chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_PAGESIZE_MASK;
+}
+
+/****************************************************************************/
+/**
+* @brief Get NAND flash address cycle configuration
+*
+* This function returns the NAND flash address cycle configuration
+*
+* @return 0 = Do not extra address cycle, 1 = Add extra cycle
+*
+*/
+/****************************************************************************/
+static inline int chipcHw_getNandExtraCycle(void)
+{
+ if (chipcHw_getValidStraps() & chipcHw_STRAPS_NAND_EXTRA_CYCLE) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Activates PIF interface
+*
+* This function activates PIF interface by taking control of LCD pins
+*
+* @note
+* When activated, LCD pins will be defined as follows for PIF operation
+*
+* CLD[17:0] = pif_data[17:0]
+* CLD[23:18] = pif_address[5:0]
+* CLPOWER = pif_wr_str
+* CLCP = pif_rd_str
+* CLAC = pif_hat1
+* CLFP = pif_hrdy1
+* CLLP = pif_hat2
+* GPIO[42] = pif_hrdy2
+*
+* In PIF mode, "pif_hrdy2" overrides other shared function for GPIO[42] pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_activatePifInterface(void)
+{
+ reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_PIF_PIN_ENABLE);
+}
+
+/****************************************************************************/
+/**
+* @brief Activates LCD interface
+*
+* This function activates LCD interface
+*
+* @note
+* When activated, LCD pins will be defined as follows
+*
+* CLD[17:0] = LCD data
+* CLD[23:18] = LCD data
+* CLPOWER = LCD power
+* CLCP =
+* CLAC = LCD ack
+* CLFP =
+* CLLP =
+*/
+/****************************************************************************/
+static inline void chipcHw_activateLcdInterface(void)
+{
+ reg32_write(&pChipcHw->LcdPifMode, chipcHw_REG_LCD_PIN_ENABLE);
+}
+
+/****************************************************************************/
+/**
+* @brief Deactivates PIF/LCD interface
+*
+* This function deactivates PIF/LCD interface
+*
+* @note
+* When deactivated LCD pins will be in rti-stated
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_deactivatePifLcdInterface(void)
+{
+ reg32_write(&pChipcHw->LcdPifMode, 0);
+}
+
+/****************************************************************************/
+/**
+* @brief Select GE2
+*
+* This function select GE2 as the graphic engine
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_selectGE2(void)
+{
+ reg32_modify_and(&pChipcHw->MiscCtrl, ~chipcHw_REG_MISC_CTRL_GE_SEL);
+}
+
+/****************************************************************************/
+/**
+* @brief Select GE3
+*
+* This function select GE3 as the graphic engine
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_selectGE3(void)
+{
+ reg32_modify_or(&pChipcHw->MiscCtrl, chipcHw_REG_MISC_CTRL_GE_SEL);
+}
+
+/****************************************************************************/
+/**
+* @brief Get to know the configuration of GPIO pin
+*
+*/
+/****************************************************************************/
+static inline chipcHw_GPIO_FUNCTION_e chipcHw_getGpioPinFunction(int pin)
+{
+ return (*((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &
+ (chipcHw_REG_GPIO_MUX_MASK <<
+ chipcHw_REG_GPIO_MUX_POSITION(pin))) >>
+ chipcHw_REG_GPIO_MUX_POSITION(pin);
+}
+
+/****************************************************************************/
+/**
+* @brief Configure GPIO pin function
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setGpioPinFunction(int pin,
+ chipcHw_GPIO_FUNCTION_e func)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) &=
+ ~(chipcHw_REG_GPIO_MUX_MASK << chipcHw_REG_GPIO_MUX_POSITION(pin));
+ *((uint32_t *) chipcHw_REG_GPIO_MUX(pin)) |=
+ func << chipcHw_REG_GPIO_MUX_POSITION(pin);
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set Pin slew rate
+*
+* This function sets the slew of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinSlewRate(uint32_t pin,
+ chipcHw_PIN_SLEW_RATE_e slewRate)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) &=
+ ~(chipcHw_REG_SLEW_RATE_MASK <<
+ chipcHw_REG_SLEW_RATE_POSITION(pin));
+ *((uint32_t *) chipcHw_REG_SLEW_RATE(pin)) |=
+ (uint32_t) slewRate << chipcHw_REG_SLEW_RATE_POSITION(pin);
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set Pin output drive current
+*
+* This function sets output drive current of individual pin
+*
+* Note: Avoid the use of the word 'current' since linux headers define this
+* to be the current task.
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinOutputCurrent(uint32_t pin,
+ chipcHw_PIN_CURRENT_STRENGTH_e
+ curr)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *((uint32_t *) chipcHw_REG_CURRENT(pin)) &=
+ ~(chipcHw_REG_CURRENT_MASK << chipcHw_REG_CURRENT_POSITION(pin));
+ *((uint32_t *) chipcHw_REG_CURRENT(pin)) |=
+ (uint32_t) curr << chipcHw_REG_CURRENT_POSITION(pin);
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set Pin pullup register
+*
+* This function sets pullup register of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinPullup(uint32_t pin, chipcHw_PIN_PULL_e pullup)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *((uint32_t *) chipcHw_REG_PULLUP(pin)) &=
+ ~(chipcHw_REG_PULLUP_MASK << chipcHw_REG_PULLUP_POSITION(pin));
+ *((uint32_t *) chipcHw_REG_PULLUP(pin)) |=
+ (uint32_t) pullup << chipcHw_REG_PULLUP_POSITION(pin);
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set Pin input type
+*
+* This function sets input type of individual pin
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setPinInputType(uint32_t pin,
+ chipcHw_PIN_INPUTTYPE_e inputType)
+{
+ REG_LOCAL_IRQ_SAVE;
+ *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) &=
+ ~(chipcHw_REG_INPUTTYPE_MASK <<
+ chipcHw_REG_INPUTTYPE_POSITION(pin));
+ *((uint32_t *) chipcHw_REG_INPUTTYPE(pin)) |=
+ (uint32_t) inputType << chipcHw_REG_INPUTTYPE_POSITION(pin);
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Power up the USB PHY
+*
+* This function powers up the USB PHY
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_powerUpUsbPhy(void)
+{
+ reg32_modify_and(&pChipcHw->MiscCtrl,
+ chipcHw_REG_MISC_CTRL_USB_POWERON);
+}
+
+/****************************************************************************/
+/**
+* @brief Power down the USB PHY
+*
+* This function powers down the USB PHY
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_powerDownUsbPhy(void)
+{
+ reg32_modify_or(&pChipcHw->MiscCtrl,
+ chipcHw_REG_MISC_CTRL_USB_POWEROFF);
+}
+
+/****************************************************************************/
+/**
+* @brief Set the 2nd USB as host
+*
+* This function sets the 2nd USB as host
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setUsbHost(void)
+{
+ reg32_modify_or(&pChipcHw->MiscCtrl,
+ chipcHw_REG_MISC_CTRL_USB_MODE_HOST);
+}
+
+/****************************************************************************/
+/**
+* @brief Set the 2nd USB as device
+*
+* This function sets the 2nd USB as device
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setUsbDevice(void)
+{
+ reg32_modify_and(&pChipcHw->MiscCtrl,
+ chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE);
+}
+
+/****************************************************************************/
+/**
+* @brief Lower layer function to enable/disable a clock of a certain device
+*
+* This function enables/disables a core clock
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_setClock(chipcHw_CLOCK_e clock,
+ chipcHw_OPTYPE_e type, int mode)
+{
+ volatile uint32_t *pPLLReg = (uint32_t *) 0x0;
+ volatile uint32_t *pClockCtrl = (uint32_t *) 0x0;
+
+ switch (clock) {
+ case chipcHw_CLOCK_DDR:
+ pPLLReg = &pChipcHw->DDRClock;
+ break;
+ case chipcHw_CLOCK_ARM:
+ pPLLReg = &pChipcHw->ARMClock;
+ break;
+ case chipcHw_CLOCK_ESW:
+ pPLLReg = &pChipcHw->ESWClock;
+ break;
+ case chipcHw_CLOCK_VPM:
+ pPLLReg = &pChipcHw->VPMClock;
+ break;
+ case chipcHw_CLOCK_ESW125:
+ pPLLReg = &pChipcHw->ESW125Clock;
+ break;
+ case chipcHw_CLOCK_UART:
+ pPLLReg = &pChipcHw->UARTClock;
+ break;
+ case chipcHw_CLOCK_SDIO0:
+ pPLLReg = &pChipcHw->SDIO0Clock;
+ break;
+ case chipcHw_CLOCK_SDIO1:
+ pPLLReg = &pChipcHw->SDIO1Clock;
+ break;
+ case chipcHw_CLOCK_SPI:
+ pPLLReg = &pChipcHw->SPIClock;
+ break;
+ case chipcHw_CLOCK_ETM:
+ pPLLReg = &pChipcHw->ETMClock;
+ break;
+ case chipcHw_CLOCK_USB:
+ pPLLReg = &pChipcHw->USBClock;
+ if (type == chipcHw_OPTYPE_OUTPUT) {
+ if (mode) {
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ } else {
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ }
+ }
+ break;
+ case chipcHw_CLOCK_LCD:
+ pPLLReg = &pChipcHw->LCDClock;
+ if (type == chipcHw_OPTYPE_OUTPUT) {
+ if (mode) {
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ } else {
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ }
+ }
+ break;
+ case chipcHw_CLOCK_APM:
+ pPLLReg = &pChipcHw->APMClock;
+ if (type == chipcHw_OPTYPE_OUTPUT) {
+ if (mode) {
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ } else {
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_POWER_DOWN);
+ }
+ }
+ break;
+ case chipcHw_CLOCK_BUS:
+ pClockCtrl = &pChipcHw->ACLKClock;
+ break;
+ case chipcHw_CLOCK_OTP:
+ pClockCtrl = &pChipcHw->OTPClock;
+ break;
+ case chipcHw_CLOCK_I2C:
+ pClockCtrl = &pChipcHw->I2CClock;
+ break;
+ case chipcHw_CLOCK_I2S0:
+ pClockCtrl = &pChipcHw->I2S0Clock;
+ break;
+ case chipcHw_CLOCK_RTBUS:
+ pClockCtrl = &pChipcHw->RTBUSClock;
+ break;
+ case chipcHw_CLOCK_APM100:
+ pClockCtrl = &pChipcHw->APM100Clock;
+ break;
+ case chipcHw_CLOCK_TSC:
+ pClockCtrl = &pChipcHw->TSCClock;
+ break;
+ case chipcHw_CLOCK_LED:
+ pClockCtrl = &pChipcHw->LEDClock;
+ break;
+ case chipcHw_CLOCK_I2S1:
+ pClockCtrl = &pChipcHw->I2S1Clock;
+ break;
+ }
+
+ if (pPLLReg) {
+ switch (type) {
+ case chipcHw_OPTYPE_OUTPUT:
+ /* PLL clock output enable/disable */
+ if (mode) {
+ if (clock == chipcHw_CLOCK_DDR) {
+ /* DDR clock enable is inverted */
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+ } else {
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+ }
+ } else {
+ if (clock == chipcHw_CLOCK_DDR) {
+ /* DDR clock disable is inverted */
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+ } else {
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE);
+ }
+ }
+ break;
+ case chipcHw_OPTYPE_BYPASS:
+ /* PLL clock bypass enable/disable */
+ if (mode) {
+ reg32_modify_or(pPLLReg,
+ chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+ } else {
+ reg32_modify_and(pPLLReg,
+ ~chipcHw_REG_PLL_CLOCK_BYPASS_SELECT);
+ }
+ break;
+ }
+ } else if (pClockCtrl) {
+ switch (type) {
+ case chipcHw_OPTYPE_OUTPUT:
+ if (mode) {
+ reg32_modify_or(pClockCtrl,
+ chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
+ } else {
+ reg32_modify_and(pClockCtrl,
+ ~chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE);
+ }
+ break;
+ case chipcHw_OPTYPE_BYPASS:
+ if (mode) {
+ reg32_modify_or(pClockCtrl,
+ chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+ } else {
+ reg32_modify_and(pClockCtrl,
+ ~chipcHw_REG_DIV_CLOCK_BYPASS_SELECT);
+ }
+ break;
+ }
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Disables a core clock of a certain device
+*
+* This function disables a core clock
+*
+* @note no change in power consumption
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockDisable(chipcHw_CLOCK_e clock)
+{
+
+ /* Disable output of the clock */
+ chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 0);
+}
+
+/****************************************************************************/
+/**
+* @brief Enable a core clock of a certain device
+*
+* This function enables a core clock
+*
+* @note no change in power consumption
+*/
+/****************************************************************************/
+static inline void chipcHw_setClockEnable(chipcHw_CLOCK_e clock)
+{
+
+ /* Enable output of the clock */
+ chipcHw_setClock(clock, chipcHw_OPTYPE_OUTPUT, 1);
+}
+
+/****************************************************************************/
+/**
+* @brief Enables bypass clock of a certain device
+*
+* This function enables bypass clock
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockEnable(chipcHw_CLOCK_e clock)
+{
+ /* Enable bypass clock */
+ chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 1);
+}
+
+/****************************************************************************/
+/**
+* @brief Disabled bypass clock of a certain device
+*
+* This function disables bypass clock
+*
+* @note Doesnot affect the bus interface clock
+*/
+/****************************************************************************/
+static inline void chipcHw_bypassClockDisable(chipcHw_CLOCK_e clock)
+{
+ /* Disable bypass clock */
+ chipcHw_setClock(clock, chipcHw_OPTYPE_BYPASS, 0);
+
+}
+
+/****************************************************************************/
+/** @brief Checks if software strap is enabled
+ *
+ * @return 1 : When enable
+ * 0 : When disable
+ */
+/****************************************************************************/
+static inline int chipcHw_isSoftwareStrapsEnable(void)
+{
+ return pChipcHw->SoftStraps & 0x00000001;
+}
+
+/****************************************************************************/
+/** @brief Enable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsEnable(void)
+{
+ reg32_modify_or(&pChipcHw->SoftStraps, 0x00000001);
+}
+
+/****************************************************************************/
+/** @brief Disable software strap
+ */
+/****************************************************************************/
+static inline void chipcHw_softwareStrapsDisable(void)
+{
+ reg32_modify_and(&pChipcHw->SoftStraps, (~0x00000001));
+}
+
+/****************************************************************************/
+/** @brief PLL test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestEnable(void)
+{
+ reg32_modify_or(&pChipcHw->PLLConfig,
+ chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/** @brief PLL2 test enable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestEnable(void)
+{
+ reg32_modify_or(&pChipcHw->PLLConfig2,
+ chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/** @brief PLL test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestDisable(void)
+{
+ reg32_modify_and(&pChipcHw->PLLConfig,
+ ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/** @brief PLL2 test disable
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestDisable(void)
+{
+ reg32_modify_and(&pChipcHw->PLLConfig2,
+ ~chipcHw_REG_PLL_CONFIG_TEST_ENABLE);
+}
+
+/****************************************************************************/
+/** @brief Get PLL test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPllTestEnable(void)
+{
+ return pChipcHw->PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
+}
+
+/****************************************************************************/
+/** @brief Get PLL2 test status
+ */
+/****************************************************************************/
+static inline int chipcHw_isPll2TestEnable(void)
+{
+ return pChipcHw->PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_ENABLE;
+}
+
+/****************************************************************************/
+/** @brief PLL test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pllTestSelect(uint32_t val)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
+ pChipcHw->PLLConfig |=
+ (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/** @brief PLL2 test select
+ */
+/****************************************************************************/
+static inline void chipcHw_pll2TestSelect(uint32_t val)
+{
+
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig2 &= ~chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK;
+ pChipcHw->PLLConfig2 |=
+ (val) << chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/** @brief Get PLL test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPllTestSelected(void)
+{
+ return (uint8_t) ((pChipcHw->
+ PLLConfig & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
+ >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
+}
+
+/****************************************************************************/
+/** @brief Get PLL2 test selected option
+ */
+/****************************************************************************/
+static inline uint8_t chipcHw_getPll2TestSelected(void)
+{
+ return (uint8_t) ((pChipcHw->
+ PLLConfig2 & chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK)
+ >> chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT);
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the PLL1
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll1Disable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disable the PLL2
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_pll2Disable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->PLLConfig2 |= chipcHw_REG_PLL_CONFIG_POWER_DOWN;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Enables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->Spare1 |= chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disables DDR SW phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrPhaseAlignInterruptDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set VPM SW phase alignment interrupt mode
+*
+* This function sets VPM phase alignment interrupt
+*/
+/****************************************************************************/
+static inline void
+chipcHw_vpmPhaseAlignInterruptMode(chipcHw_VPM_HW_PHASE_INTR_e mode)
+{
+ REG_LOCAL_IRQ_SAVE;
+ if (mode == chipcHw_VPM_HW_PHASE_INTR_DISABLE) {
+ pChipcHw->Spare1 &= ~chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
+ } else {
+ pChipcHw->Spare1 |= chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE;
+ }
+ pChipcHw->VPMPhaseCtrl2 =
+ (pChipcHw->
+ VPMPhaseCtrl2 & ~(chipcHw_REG_VPM_INTR_SELECT_MASK <<
+ chipcHw_REG_VPM_INTR_SELECT_SHIFT)) | mode;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Enable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disable DDR phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrSwPhaseAlignDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Enable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl1 |= chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disable DDR phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl1 &= ~chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Enable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disable VPM phase alignment in software
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmSwPhaseAlignDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Enable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl1 |= chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Disable VPM phase alignment in hardware
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl1 &= ~chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Set DDR phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_setDdrHwPhaseAlignMargin(chipcHw_DDR_HW_PHASE_MARGIN_e margin)
+{
+ uint32_t ge = 0;
+ uint32_t le = 0;
+
+ switch (margin) {
+ case chipcHw_DDR_HW_PHASE_MARGIN_STRICT:
+ ge = 0x0F;
+ le = 0x0F;
+ break;
+ case chipcHw_DDR_HW_PHASE_MARGIN_MEDIUM:
+ ge = 0x03;
+ le = 0x3F;
+ break;
+ case chipcHw_DDR_HW_PHASE_MARGIN_WIDE:
+ ge = 0x01;
+ le = 0x7F;
+ break;
+ }
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+
+ pChipcHw->DDRPhaseCtrl1 &=
+ ~((chipcHw_REG_DDR_PHASE_VALUE_GE_MASK <<
+ chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
+ || (chipcHw_REG_DDR_PHASE_VALUE_LE_MASK <<
+ chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
+
+ pChipcHw->DDRPhaseCtrl1 |=
+ ((ge << chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT)
+ || (le << chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT));
+
+ REG_LOCAL_IRQ_RESTORE;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Set VPM phase alignment margin in hardware
+*
+*/
+/****************************************************************************/
+static inline void
+chipcHw_setVpmHwPhaseAlignMargin(chipcHw_VPM_HW_PHASE_MARGIN_e margin)
+{
+ uint32_t ge = 0;
+ uint32_t le = 0;
+
+ switch (margin) {
+ case chipcHw_VPM_HW_PHASE_MARGIN_STRICT:
+ ge = 0x0F;
+ le = 0x0F;
+ break;
+ case chipcHw_VPM_HW_PHASE_MARGIN_MEDIUM:
+ ge = 0x03;
+ le = 0x3F;
+ break;
+ case chipcHw_VPM_HW_PHASE_MARGIN_WIDE:
+ ge = 0x01;
+ le = 0x7F;
+ break;
+ }
+
+ {
+ REG_LOCAL_IRQ_SAVE;
+
+ pChipcHw->VPMPhaseCtrl1 &=
+ ~((chipcHw_REG_VPM_PHASE_VALUE_GE_MASK <<
+ chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
+ || (chipcHw_REG_VPM_PHASE_VALUE_LE_MASK <<
+ chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
+
+ pChipcHw->VPMPhaseCtrl1 |=
+ ((ge << chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT)
+ || (le << chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT));
+
+ REG_LOCAL_IRQ_RESTORE;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Checks DDR phase aligned status done by HW
+*
+* @return 1: When aligned
+* 0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isDdrHwPhaseAligned(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_DDR_PHASE_ALIGNED) ? 1 : 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Checks VPM phase aligned status done by HW
+*
+* @return 1: When aligned
+* 0: When not aligned
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_isVpmHwPhaseAligned(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_VPM_PHASE_ALIGNED) ? 1 : 0;
+}
+
+/****************************************************************************/
+/**
+* @brief Get DDR phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrHwPhaseAlignStatus(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_DDR_PHASE_STATUS_MASK) >>
+ chipcHw_REG_DDR_PHASE_STATUS_SHIFT;
+}
+
+/****************************************************************************/
+/**
+* @brief Get VPM phase aligned status done by HW
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmHwPhaseAlignStatus(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_VPM_PHASE_STATUS_MASK) >>
+ chipcHw_REG_VPM_PHASE_STATUS_SHIFT;
+}
+
+/****************************************************************************/
+/**
+* @brief Get DDR phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getDdrPhaseControl(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_DDR_PHASE_CTRL_MASK) >>
+ chipcHw_REG_DDR_PHASE_CTRL_SHIFT;
+}
+
+/****************************************************************************/
+/**
+* @brief Get VPM phase control value
+*
+*/
+/****************************************************************************/
+static inline uint32_t chipcHw_getVpmPhaseControl(void)
+{
+ return (pChipcHw->
+ PhaseAlignStatus & chipcHw_REG_VPM_PHASE_CTRL_MASK) >>
+ chipcHw_REG_VPM_PHASE_CTRL_SHIFT;
+}
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout count
+*
+* @note If HW fails to perform the phase alignment, it will trigger
+* a DDR phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeout(uint32_t busCycle)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl2 &=
+ ~(chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK <<
+ chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT);
+ pChipcHw->DDRPhaseCtrl2 |=
+ (busCycle & chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK) <<
+ chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout count
+*
+* @note If HW fails to perform the phase alignment, it will trigger
+* a VPM phase alignment timeout interrupt.
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeout(uint32_t busCycle)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl2 &=
+ ~(chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK <<
+ chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT);
+ pChipcHw->VPMPhaseCtrl2 |=
+ (busCycle & chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK) <<
+ chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Clear DDR phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ /* Clear timeout interrupt service bit */
+ pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_INTR_SERVICED;
+ pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_INTR_SERVICED;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief Clear VPM phase alignment timeout interrupt
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ /* Clear timeout interrupt service bit */
+ pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_INTR_SERVICED;
+ pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_INTR_SERVICED;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ chipcHw_ddrHwPhaseAlignTimeoutInterruptClear(); /* Recommended */
+ /* Enable timeout interrupt */
+ pChipcHw->DDRPhaseCtrl2 |= chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout interrupt enable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptEnable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ chipcHw_vpmHwPhaseAlignTimeoutInterruptClear(); /* Recommended */
+ /* Enable timeout interrupt */
+ pChipcHw->VPMPhaseCtrl2 |= chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief DDR phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_ddrHwPhaseAlignTimeoutInterruptDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->DDRPhaseCtrl2 &= ~chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+/****************************************************************************/
+/**
+* @brief VPM phase alignment timeout interrupt disable
+*
+*/
+/****************************************************************************/
+static inline void chipcHw_vpmHwPhaseAlignTimeoutInterruptDisable(void)
+{
+ REG_LOCAL_IRQ_SAVE;
+ pChipcHw->VPMPhaseCtrl2 &= ~chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE;
+ REG_LOCAL_IRQ_RESTORE;
+}
+
+#endif /* CHIPC_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
new file mode 100644
index 00000000..b162448f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/chipcHw_reg.h
@@ -0,0 +1,530 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file chipcHw_reg.h
+*
+* @brief Definitions for low level chip control registers
+*
+*/
+/****************************************************************************/
+#ifndef CHIPCHW_REG_H
+#define CHIPCHW_REG_H
+
+#include <mach/csp/mm_io.h>
+#include <csp/reg.h>
+#include <mach/csp/ddrcReg.h>
+
+#define chipcHw_BASE_ADDRESS MM_IO_BASE_CHIPC
+
+typedef struct {
+ uint32_t ChipId; /* Chip ID */
+ uint32_t DDRClock; /* PLL1 Channel 1 for DDR clock */
+ uint32_t ARMClock; /* PLL1 Channel 2 for ARM clock */
+ uint32_t ESWClock; /* PLL1 Channel 3 for ESW system clock */
+ uint32_t VPMClock; /* PLL1 Channel 4 for VPM clock */
+ uint32_t ESW125Clock; /* PLL1 Channel 5 for ESW 125MHz clock */
+ uint32_t UARTClock; /* PLL1 Channel 6 for UART clock */
+ uint32_t SDIO0Clock; /* PLL1 Channel 7 for SDIO 0 clock */
+ uint32_t SDIO1Clock; /* PLL1 Channel 8 for SDIO 1 clock */
+ uint32_t SPIClock; /* PLL1 Channel 9 for SPI master Clock */
+ uint32_t ETMClock; /* PLL1 Channel 10 for ARM ETM Clock */
+
+ uint32_t ACLKClock; /* ACLK Clock (Divider) */
+ uint32_t OTPClock; /* OTP Clock (Divider) */
+ uint32_t I2CClock; /* I2C Clock (CK_13m) (Divider) */
+ uint32_t I2S0Clock; /* I2S0 Clock (Divider) */
+ uint32_t RTBUSClock; /* RTBUS (DDR PHY Config.) Clock (Divider) */
+ uint32_t pad1;
+ uint32_t APM100Clock; /* APM 100MHz CLK Clock (Divider) */
+ uint32_t TSCClock; /* TSC Clock (Divider) */
+ uint32_t LEDClock; /* LED Clock (Divider) */
+
+ uint32_t USBClock; /* PLL2 Channel 1 for USB clock */
+ uint32_t LCDClock; /* PLL2 Channel 2 for LCD clock */
+ uint32_t APMClock; /* PLL2 Channel 3 for APM 200 MHz clock */
+
+ uint32_t BusIntfClock; /* Bus interface clock */
+
+ uint32_t PLLStatus; /* PLL status register (PLL1) */
+ uint32_t PLLConfig; /* PLL configuration register (PLL1) */
+ uint32_t PLLPreDivider; /* PLL pre-divider control register (PLL1) */
+ uint32_t PLLDivider; /* PLL divider control register (PLL1) */
+ uint32_t PLLControl1; /* PLL analog control register #1 (PLL1) */
+ uint32_t PLLControl2; /* PLL analog control register #2 (PLL1) */
+
+ uint32_t I2S1Clock; /* I2S1 Clock */
+ uint32_t AudioEnable; /* Enable/ disable audio channel */
+ uint32_t SoftReset1; /* Reset blocks */
+ uint32_t SoftReset2; /* Reset blocks */
+ uint32_t Spare1; /* Phase align interrupts */
+ uint32_t Sticky; /* Sticky bits */
+ uint32_t MiscCtrl; /* Misc. control */
+ uint32_t pad3[3];
+
+ uint32_t PLLStatus2; /* PLL status register (PLL2) */
+ uint32_t PLLConfig2; /* PLL configuration register (PLL2) */
+ uint32_t PLLPreDivider2; /* PLL pre-divider control register (PLL2) */
+ uint32_t PLLDivider2; /* PLL divider control register (PLL2) */
+ uint32_t PLLControl12; /* PLL analog control register #1 (PLL2) */
+ uint32_t PLLControl22; /* PLL analog control register #2 (PLL2) */
+
+ uint32_t DDRPhaseCtrl1; /* DDR Clock Phase Alignment control1 */
+ uint32_t VPMPhaseCtrl1; /* VPM Clock Phase Alignment control1 */
+ uint32_t PhaseAlignStatus; /* DDR/VPM Clock Phase Alignment Status */
+ uint32_t PhaseCtrlStatus; /* DDR/VPM Clock HW DDR/VPM ph_ctrl and load_ch Status */
+ uint32_t DDRPhaseCtrl2; /* DDR Clock Phase Alignment control2 */
+ uint32_t VPMPhaseCtrl2; /* VPM Clock Phase Alignment control2 */
+ uint32_t pad4[9];
+
+ uint32_t SoftOTP1; /* Software OTP control */
+ uint32_t SoftOTP2; /* Software OTP control */
+ uint32_t SoftStraps; /* Software strap */
+ uint32_t PinStraps; /* Pin Straps */
+ uint32_t DiffOscCtrl; /* Diff oscillator control */
+ uint32_t DiagsCtrl; /* Diagnostic control */
+ uint32_t DiagsOutputCtrl; /* Diagnostic output enable */
+ uint32_t DiagsReadBackCtrl; /* Diagnostic read back control */
+
+ uint32_t LcdPifMode; /* LCD/PIF Pin Sharing MUX Mode */
+
+ uint32_t GpioMux_0_7; /* Pin Sharing MUX0 Control */
+ uint32_t GpioMux_8_15; /* Pin Sharing MUX1 Control */
+ uint32_t GpioMux_16_23; /* Pin Sharing MUX2 Control */
+ uint32_t GpioMux_24_31; /* Pin Sharing MUX3 Control */
+ uint32_t GpioMux_32_39; /* Pin Sharing MUX4 Control */
+ uint32_t GpioMux_40_47; /* Pin Sharing MUX5 Control */
+ uint32_t GpioMux_48_55; /* Pin Sharing MUX6 Control */
+ uint32_t GpioMux_56_63; /* Pin Sharing MUX7 Control */
+
+ uint32_t GpioSR_0_7; /* Slew rate for GPIO 0 - 7 */
+ uint32_t GpioSR_8_15; /* Slew rate for GPIO 8 - 15 */
+ uint32_t GpioSR_16_23; /* Slew rate for GPIO 16 - 23 */
+ uint32_t GpioSR_24_31; /* Slew rate for GPIO 24 - 31 */
+ uint32_t GpioSR_32_39; /* Slew rate for GPIO 32 - 39 */
+ uint32_t GpioSR_40_47; /* Slew rate for GPIO 40 - 47 */
+ uint32_t GpioSR_48_55; /* Slew rate for GPIO 48 - 55 */
+ uint32_t GpioSR_56_63; /* Slew rate for GPIO 56 - 63 */
+ uint32_t MiscSR_0_7; /* Slew rate for MISC 0 - 7 */
+ uint32_t MiscSR_8_15; /* Slew rate for MISC 8 - 15 */
+
+ uint32_t GpioPull_0_15; /* Pull up registers for GPIO 0 - 15 */
+ uint32_t GpioPull_16_31; /* Pull up registers for GPIO 16 - 31 */
+ uint32_t GpioPull_32_47; /* Pull up registers for GPIO 32 - 47 */
+ uint32_t GpioPull_48_63; /* Pull up registers for GPIO 48 - 63 */
+ uint32_t MiscPull_0_15; /* Pull up registers for MISC 0 - 15 */
+
+ uint32_t GpioInput_0_31; /* Input type for GPIO 0 - 31 */
+ uint32_t GpioInput_32_63; /* Input type for GPIO 32 - 63 */
+ uint32_t MiscInput_0_15; /* Input type for MISC 0 - 16 */
+} chipcHw_REG_t;
+
+#define pChipcHw ((volatile chipcHw_REG_t *) chipcHw_BASE_ADDRESS)
+#define pChipcPhysical ((volatile chipcHw_REG_t *) MM_ADDR_IO_CHIPC)
+
+#define chipcHw_REG_CHIPID_BASE_MASK 0xFFFFF000
+#define chipcHw_REG_CHIPID_BASE_SHIFT 12
+#define chipcHw_REG_CHIPID_REV_MASK 0x00000FFF
+#define chipcHw_REG_REV_A0 0xA00
+#define chipcHw_REG_REV_B0 0x0B0
+
+#define chipcHw_REG_PLL_STATUS_CONTROL_ENABLE 0x80000000 /* Allow controlling PLL registers */
+#define chipcHw_REG_PLL_STATUS_LOCKED 0x00000001 /* PLL is settled */
+#define chipcHw_REG_PLL_CONFIG_D_RESET 0x00000008 /* Digital reset */
+#define chipcHw_REG_PLL_CONFIG_A_RESET 0x00000004 /* Analog reset */
+#define chipcHw_REG_PLL_CONFIG_BYPASS_ENABLE 0x00000020 /* Bypass enable */
+#define chipcHw_REG_PLL_CONFIG_OUTPUT_ENABLE 0x00000010 /* Output enable */
+#define chipcHw_REG_PLL_CONFIG_POWER_DOWN 0x00000001 /* Power down */
+#define chipcHw_REG_PLL_CONFIG_VCO_SPLIT_FREQ 1600000000 /* 1.6GHz VCO split frequency */
+#define chipcHw_REG_PLL_CONFIG_VCO_800_1600 0x00000000 /* VCO range 800-1600 MHz */
+#define chipcHw_REG_PLL_CONFIG_VCO_1601_3200 0x00000080 /* VCO range 1601-3200 MHz */
+#define chipcHw_REG_PLL_CONFIG_TEST_ENABLE 0x00010000 /* PLL test output enable */
+#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_MASK 0x003E0000 /* Mask to set test values */
+#define chipcHw_REG_PLL_CONFIG_TEST_SELECT_SHIFT 17
+
+#define chipcHw_REG_PLL_CLOCK_PHASE_COMP 0x00800000 /* Phase comparator output */
+#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_MASK 0x00300000 /* Clock to bus ratio mask */
+#define chipcHw_REG_PLL_CLOCK_TO_BUS_RATIO_SHIFT 20 /* Number of bits to be shifted */
+#define chipcHw_REG_PLL_CLOCK_POWER_DOWN 0x00080000 /* PLL channel power down */
+#define chipcHw_REG_PLL_CLOCK_SOURCE_GPIO 0x00040000 /* Use GPIO as source */
+#define chipcHw_REG_PLL_CLOCK_BYPASS_SELECT 0x00020000 /* Select bypass clock */
+#define chipcHw_REG_PLL_CLOCK_OUTPUT_ENABLE 0x00010000 /* Clock gated ON */
+#define chipcHw_REG_PLL_CLOCK_PHASE_UPDATE_ENABLE 0x00008000 /* Clock phase update enable */
+#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_SHIFT 8 /* Number of bits to be shifted */
+#define chipcHw_REG_PLL_CLOCK_PHASE_CONTROL_MASK 0x00003F00 /* Phase control mask */
+#define chipcHw_REG_PLL_CLOCK_MDIV_MASK 0x000000FF /* Clock post divider mask
+
+ 00000000 = divide-by-256
+ 00000001 = divide-by-1
+ 00000010 = divide-by-2
+ 00000011 = divide-by-3
+ 00000100 = divide-by-4
+ 00000101 = divide-by-5
+ 00000110 = divide-by-6
+ .
+ .
+ 11111011 = divide-by-251
+ 11111100 = divide-by-252
+ 11111101 = divide-by-253
+ 11111110 = divide-by-254
+ */
+
+#define chipcHw_REG_DIV_CLOCK_SOURCE_OTHER 0x00040000 /* NON-PLL clock source select */
+#define chipcHw_REG_DIV_CLOCK_BYPASS_SELECT 0x00020000 /* NON-PLL clock bypass enable */
+#define chipcHw_REG_DIV_CLOCK_OUTPUT_ENABLE 0x00010000 /* NON-PLL clock output enable */
+#define chipcHw_REG_DIV_CLOCK_DIV_MASK 0x000000FF /* NON-PLL clock post-divide mask */
+#define chipcHw_REG_DIV_CLOCK_DIV_256 0x00000000 /* NON-PLL clock post-divide by 256 */
+
+#define chipcHw_REG_PLL_PREDIVIDER_P1_SHIFT 0
+#define chipcHw_REG_PLL_PREDIVIDER_P2_SHIFT 4
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_SHIFT 8
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MASK 0x0001FF00
+#define chipcHw_REG_PLL_PREDIVIDER_POWER_DOWN 0x02000000
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASK 0x00700000 /* Divider mask */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_INTEGER 0x00000000 /* Integer-N Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_UNIT 0x00100000 /* MASH Sigma-Delta Modulator Unit Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_UNIT 0x00200000 /* MFB Sigma-Delta Modulator Unit Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MASH_1_8 0x00300000 /* MASH Sigma-Delta Modulator 1/8 Mode */
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_MODE_MFB_1_8 0x00400000 /* MFB Sigma-Delta Modulator 1/8 Mode */
+
+#define chipcHw_REG_PLL_PREDIVIDER_NDIV_i(vco) ((vco) / chipcHw_XTAL_FREQ_Hz)
+#define chipcHw_REG_PLL_PREDIVIDER_P1 1
+#define chipcHw_REG_PLL_PREDIVIDER_P2 1
+
+#define chipcHw_REG_PLL_DIVIDER_M1DIV 0x03000000
+#define chipcHw_REG_PLL_DIVIDER_FRAC 0x00FFFFFF /* Fractional divider */
+
+#define chipcHw_REG_PLL_DIVIDER_NDIV_f_SS (0x00FFFFFF) /* To attain spread with max frequency */
+
+#define chipcHw_REG_PLL_DIVIDER_NDIV_f 0 /* ndiv_frac = chipcHw_REG_PLL_DIVIDER_NDIV_f /
+ chipcHw_REG_PLL_DIVIDER_FRAC
+ = 0, when SS is disable
+ */
+
+#define chipcHw_REG_PLL_DIVIDER_MDIV(vco, Hz) ((chipcHw_divide((vco), (Hz)) > 255) ? 0 : chipcHw_divide((vco), (Hz)))
+
+#define chipcHw_REG_ACLKClock_CLK_DIV_MASK 0x3
+
+/* System booting strap options */
+#define chipcHw_STRAPS_SOFT_OVERRIDE 0x00000001 /* Software Strap Override */
+
+#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_8 0x00000000 /* 8 bit NAND FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_NOR_FLASH_16 0x00000002 /* 16 bit NOR FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_SERIAL_FLASH 0x00000004 /* Serial FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_NAND_FLASH_16 0x00000006 /* 16 bit NAND FLASH Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_UART 0x00000008 /* UART Boot */
+#define chipcHw_STRAPS_BOOT_DEVICE_MASK 0x0000000E /* Mask */
+
+/* System boot option */
+#define chipcHw_STRAPS_BOOT_OPTION_BROM 0x00000000 /* Boot from Boot ROM */
+#define chipcHw_STRAPS_BOOT_OPTION_ARAM 0x00000020 /* Boot from ARAM */
+#define chipcHw_STRAPS_BOOT_OPTION_NOR 0x00000030 /* Boot from NOR flash */
+
+/* NAND Flash page size strap options */
+#define chipcHw_STRAPS_NAND_PAGESIZE_512 0x00000000 /* NAND FLASH page size of 512 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_2048 0x00000040 /* NAND FLASH page size of 2048 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_4096 0x00000080 /* NAND FLASH page size of 4096 bytes */
+#define chipcHw_STRAPS_NAND_PAGESIZE_EXT 0x000000C0 /* NAND FLASH page of extened size */
+#define chipcHw_STRAPS_NAND_PAGESIZE_MASK 0x000000C0 /* Mask */
+
+#define chipcHw_STRAPS_NAND_EXTRA_CYCLE 0x00000400 /* NAND FLASH address cycle configuration */
+#define chipcHw_STRAPS_REBOOT_TO_UART 0x00000800 /* Reboot to UART on error */
+
+/* Secure boot mode strap options */
+#define chipcHw_STRAPS_BOOT_MODE_NORMAL 0x00000000 /* Normal Boot */
+#define chipcHw_STRAPS_BOOT_MODE_DBG_SW 0x00000100 /* Software debugging Boot */
+#define chipcHw_STRAPS_BOOT_MODE_DBG_BOOT 0x00000200 /* Boot rom debugging Boot */
+#define chipcHw_STRAPS_BOOT_MODE_NORMAL_QUIET 0x00000300 /* Normal Boot (Quiet BootRom) */
+#define chipcHw_STRAPS_BOOT_MODE_MASK 0x00000300 /* Mask */
+
+/* Slave Mode straps */
+#define chipcHw_STRAPS_I2CS 0x02000000 /* I2C Slave */
+#define chipcHw_STRAPS_SPIS 0x01000000 /* SPI Slave */
+
+/* Strap pin options */
+#define chipcHw_REG_SW_STRAPS ((pChipcHw->PinStraps & 0x0000FC00) >> 10)
+
+/* PIF/LCD pin sharing defines */
+#define chipcHw_REG_LCD_PIN_ENABLE 0x00000001 /* LCD Controller is used and the pins have LCD functions */
+#define chipcHw_REG_PIF_PIN_ENABLE 0x00000002 /* LCD pins are used to perform PIF functions */
+
+#define chipcHw_GPIO_COUNT 61 /* Number of GPIO pin accessible thorugh CHIPC */
+
+/* NOTE: Any changes to these constants will require a corresponding change to chipcHw_str.c */
+#define chipcHw_REG_GPIO_MUX_KEYPAD 0x00000001 /* GPIO mux for Keypad */
+#define chipcHw_REG_GPIO_MUX_I2CH 0x00000002 /* GPIO mux for I2CH */
+#define chipcHw_REG_GPIO_MUX_SPI 0x00000003 /* GPIO mux for SPI */
+#define chipcHw_REG_GPIO_MUX_UART 0x00000004 /* GPIO mux for UART */
+#define chipcHw_REG_GPIO_MUX_LEDMTXP 0x00000005 /* GPIO mux for LEDMTXP */
+#define chipcHw_REG_GPIO_MUX_LEDMTXS 0x00000006 /* GPIO mux for LEDMTXS */
+#define chipcHw_REG_GPIO_MUX_SDIO0 0x00000007 /* GPIO mux for SDIO0 */
+#define chipcHw_REG_GPIO_MUX_SDIO1 0x00000008 /* GPIO mux for SDIO1 */
+#define chipcHw_REG_GPIO_MUX_PCM 0x00000009 /* GPIO mux for PCM */
+#define chipcHw_REG_GPIO_MUX_I2S 0x0000000A /* GPIO mux for I2S */
+#define chipcHw_REG_GPIO_MUX_ETM 0x0000000B /* GPIO mux for ETM */
+#define chipcHw_REG_GPIO_MUX_DEBUG 0x0000000C /* GPIO mux for DEBUG */
+#define chipcHw_REG_GPIO_MUX_MISC 0x0000000D /* GPIO mux for MISC */
+#define chipcHw_REG_GPIO_MUX_GPIO 0x00000000 /* GPIO mux for GPIO */
+#define chipcHw_REG_GPIO_MUX(pin) (&pChipcHw->GpioMux_0_7 + ((pin) >> 3))
+#define chipcHw_REG_GPIO_MUX_POSITION(pin) (((pin) & 0x00000007) << 2)
+#define chipcHw_REG_GPIO_MUX_MASK 0x0000000F /* Mask */
+
+#define chipcHw_REG_SLEW_RATE_HIGH 0x00000000 /* High speed slew rate */
+#define chipcHw_REG_SLEW_RATE_NORMAL 0x00000008 /* Normal slew rate */
+ /* Pins beyond 42 are defined by skipping 8 bits within the register */
+#define chipcHw_REG_SLEW_RATE(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
+#define chipcHw_REG_SLEW_RATE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
+#define chipcHw_REG_SLEW_RATE_MASK 0x00000008 /* Mask */
+
+#define chipcHw_REG_CURRENT_STRENGTH_2mA 0x00000001 /* Current driving strength 2 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_4mA 0x00000002 /* Current driving strength 4 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_6mA 0x00000004 /* Current driving strength 6 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_8mA 0x00000005 /* Current driving strength 8 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_10mA 0x00000006 /* Current driving strength 10 milli ampere */
+#define chipcHw_REG_CURRENT_STRENGTH_12mA 0x00000007 /* Current driving strength 12 milli ampere */
+#define chipcHw_REG_CURRENT_MASK 0x00000007 /* Mask */
+ /* Pins beyond 42 are defined by skipping 8 bits */
+#define chipcHw_REG_CURRENT(pin) (((pin) > 42) ? (&pChipcHw->GpioSR_0_7 + (((pin) + 2) >> 3)) : (&pChipcHw->GpioSR_0_7 + ((pin) >> 3)))
+#define chipcHw_REG_CURRENT_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x00000007) << 2) : (((pin) & 0x00000007) << 2))
+
+#define chipcHw_REG_PULL_NONE 0x00000000 /* No pull up register */
+#define chipcHw_REG_PULL_UP 0x00000001 /* Pull up register enable */
+#define chipcHw_REG_PULL_DOWN 0x00000002 /* Pull down register enable */
+#define chipcHw_REG_PULLUP_MASK 0x00000003 /* Mask */
+ /* Pins beyond 42 are defined by skipping 4 bits */
+#define chipcHw_REG_PULLUP(pin) (((pin) > 42) ? (&pChipcHw->GpioPull_0_15 + (((pin) + 2) >> 4)) : (&pChipcHw->GpioPull_0_15 + ((pin) >> 4)))
+#define chipcHw_REG_PULLUP_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000000F) << 1) : (((pin) & 0x0000000F) << 1))
+
+#define chipcHw_REG_INPUTTYPE_CMOS 0x00000000 /* Normal CMOS logic */
+#define chipcHw_REG_INPUTTYPE_ST 0x00000001 /* High speed Schmitt Trigger */
+#define chipcHw_REG_INPUTTYPE_MASK 0x00000001 /* Mask */
+ /* Pins beyond 42 are defined by skipping 2 bits */
+#define chipcHw_REG_INPUTTYPE(pin) (((pin) > 42) ? (&pChipcHw->GpioInput_0_31 + (((pin) + 2) >> 5)) : (&pChipcHw->GpioInput_0_31 + ((pin) >> 5)))
+#define chipcHw_REG_INPUTTYPE_POSITION(pin) (((pin) > 42) ? ((((pin) + 2) & 0x0000001F)) : (((pin) & 0x0000001F)))
+
+/* Device connected to the bus clock */
+#define chipcHw_REG_BUS_CLOCK_ARM 0x00000001 /* Bus interface clock for ARM */
+#define chipcHw_REG_BUS_CLOCK_VDEC 0x00000002 /* Bus interface clock for VDEC */
+#define chipcHw_REG_BUS_CLOCK_ARAM 0x00000004 /* Bus interface clock for ARAM */
+#define chipcHw_REG_BUS_CLOCK_HPM 0x00000008 /* Bus interface clock for HPM */
+#define chipcHw_REG_BUS_CLOCK_DDRC 0x00000010 /* Bus interface clock for DDRC */
+#define chipcHw_REG_BUS_CLOCK_DMAC0 0x00000020 /* Bus interface clock for DMAC0 */
+#define chipcHw_REG_BUS_CLOCK_DMAC1 0x00000040 /* Bus interface clock for DMAC1 */
+#define chipcHw_REG_BUS_CLOCK_NVI 0x00000080 /* Bus interface clock for NVI */
+#define chipcHw_REG_BUS_CLOCK_ESW 0x00000100 /* Bus interface clock for ESW */
+#define chipcHw_REG_BUS_CLOCK_GE 0x00000200 /* Bus interface clock for GE */
+#define chipcHw_REG_BUS_CLOCK_I2CH 0x00000400 /* Bus interface clock for I2CH */
+#define chipcHw_REG_BUS_CLOCK_I2S0 0x00000800 /* Bus interface clock for I2S0 */
+#define chipcHw_REG_BUS_CLOCK_I2S1 0x00001000 /* Bus interface clock for I2S1 */
+#define chipcHw_REG_BUS_CLOCK_VRAM 0x00002000 /* Bus interface clock for VRAM */
+#define chipcHw_REG_BUS_CLOCK_CLCD 0x00004000 /* Bus interface clock for CLCD */
+#define chipcHw_REG_BUS_CLOCK_LDK 0x00008000 /* Bus interface clock for LDK */
+#define chipcHw_REG_BUS_CLOCK_LED 0x00010000 /* Bus interface clock for LED */
+#define chipcHw_REG_BUS_CLOCK_OTP 0x00020000 /* Bus interface clock for OTP */
+#define chipcHw_REG_BUS_CLOCK_PIF 0x00040000 /* Bus interface clock for PIF */
+#define chipcHw_REG_BUS_CLOCK_SPU 0x00080000 /* Bus interface clock for SPU */
+#define chipcHw_REG_BUS_CLOCK_SDIO0 0x00100000 /* Bus interface clock for SDIO0 */
+#define chipcHw_REG_BUS_CLOCK_SDIO1 0x00200000 /* Bus interface clock for SDIO1 */
+#define chipcHw_REG_BUS_CLOCK_SPIH 0x00400000 /* Bus interface clock for SPIH */
+#define chipcHw_REG_BUS_CLOCK_SPIS 0x00800000 /* Bus interface clock for SPIS */
+#define chipcHw_REG_BUS_CLOCK_UART0 0x01000000 /* Bus interface clock for UART0 */
+#define chipcHw_REG_BUS_CLOCK_UART1 0x02000000 /* Bus interface clock for UART1 */
+#define chipcHw_REG_BUS_CLOCK_BBL 0x04000000 /* Bus interface clock for BBL */
+#define chipcHw_REG_BUS_CLOCK_I2CS 0x08000000 /* Bus interface clock for I2CS */
+#define chipcHw_REG_BUS_CLOCK_USBH 0x10000000 /* Bus interface clock for USB Host */
+#define chipcHw_REG_BUS_CLOCK_USBD 0x20000000 /* Bus interface clock for USB Device */
+#define chipcHw_REG_BUS_CLOCK_BROM 0x40000000 /* Bus interface clock for Boot ROM */
+#define chipcHw_REG_BUS_CLOCK_TSC 0x80000000 /* Bus interface clock for Touch screen */
+
+/* Software resets defines */
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_HOLD 0x0000000080000000ULL /* Reset Global VPM and hold */
+#define chipcHw_REG_SOFT_RESET_VPM_HOLD 0x0000000040000000ULL /* Reset VPM and hold */
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL 0x0000000020000000ULL /* Reset Global VPM */
+#define chipcHw_REG_SOFT_RESET_VPM 0x0000000010000000ULL /* Reset VPM */
+#define chipcHw_REG_SOFT_RESET_KEYPAD 0x0000000008000000ULL /* Reset Key pad */
+#define chipcHw_REG_SOFT_RESET_LED 0x0000000004000000ULL /* Reset LED */
+#define chipcHw_REG_SOFT_RESET_SPU 0x0000000002000000ULL /* Reset SPU */
+#define chipcHw_REG_SOFT_RESET_RNG 0x0000000001000000ULL /* Reset RNG */
+#define chipcHw_REG_SOFT_RESET_PKA 0x0000000000800000ULL /* Reset PKA */
+#define chipcHw_REG_SOFT_RESET_LCD 0x0000000000400000ULL /* Reset LCD */
+#define chipcHw_REG_SOFT_RESET_PIF 0x0000000000200000ULL /* Reset PIF */
+#define chipcHw_REG_SOFT_RESET_I2CS 0x0000000000100000ULL /* Reset I2C Slave */
+#define chipcHw_REG_SOFT_RESET_I2CH 0x0000000000080000ULL /* Reset I2C Host */
+#define chipcHw_REG_SOFT_RESET_SDIO1 0x0000000000040000ULL /* Reset SDIO 1 */
+#define chipcHw_REG_SOFT_RESET_SDIO0 0x0000000000020000ULL /* Reset SDIO 0 */
+#define chipcHw_REG_SOFT_RESET_BBL 0x0000000000010000ULL /* Reset BBL */
+#define chipcHw_REG_SOFT_RESET_I2S1 0x0000000000008000ULL /* Reset I2S1 */
+#define chipcHw_REG_SOFT_RESET_I2S0 0x0000000000004000ULL /* Reset I2S0 */
+#define chipcHw_REG_SOFT_RESET_SPIS 0x0000000000002000ULL /* Reset SPI Slave */
+#define chipcHw_REG_SOFT_RESET_SPIH 0x0000000000001000ULL /* Reset SPI Host */
+#define chipcHw_REG_SOFT_RESET_GPIO1 0x0000000000000800ULL /* Reset GPIO block 1 */
+#define chipcHw_REG_SOFT_RESET_GPIO0 0x0000000000000400ULL /* Reset GPIO block 0 */
+#define chipcHw_REG_SOFT_RESET_UART1 0x0000000000000200ULL /* Reset UART 1 */
+#define chipcHw_REG_SOFT_RESET_UART0 0x0000000000000100ULL /* Reset UART 0 */
+#define chipcHw_REG_SOFT_RESET_NVI 0x0000000000000080ULL /* Reset NVI */
+#define chipcHw_REG_SOFT_RESET_WDOG 0x0000000000000040ULL /* Reset Watch dog */
+#define chipcHw_REG_SOFT_RESET_TMR 0x0000000000000020ULL /* Reset Timer */
+#define chipcHw_REG_SOFT_RESET_ETM 0x0000000000000010ULL /* Reset ETM */
+#define chipcHw_REG_SOFT_RESET_ARM_HOLD 0x0000000000000008ULL /* Reset ARM and HOLD */
+#define chipcHw_REG_SOFT_RESET_ARM 0x0000000000000004ULL /* Reset ARM */
+#define chipcHw_REG_SOFT_RESET_CHIP_WARM 0x0000000000000002ULL /* Chip warm reset */
+#define chipcHw_REG_SOFT_RESET_CHIP_SOFT 0x0000000000000001ULL /* Chip soft reset */
+#define chipcHw_REG_SOFT_RESET_VDEC 0x0000100000000000ULL /* Video decoder */
+#define chipcHw_REG_SOFT_RESET_GE 0x0000080000000000ULL /* Graphics engine */
+#define chipcHw_REG_SOFT_RESET_OTP 0x0000040000000000ULL /* Reset OTP */
+#define chipcHw_REG_SOFT_RESET_USB2 0x0000020000000000ULL /* Reset USB2 */
+#define chipcHw_REG_SOFT_RESET_USB1 0x0000010000000000ULL /* Reset USB 1 */
+#define chipcHw_REG_SOFT_RESET_USB 0x0000008000000000ULL /* Reset USB 1 and USB2 soft reset */
+#define chipcHw_REG_SOFT_RESET_ESW 0x0000004000000000ULL /* Reset Ethernet switch */
+#define chipcHw_REG_SOFT_RESET_ESWCLK 0x0000002000000000ULL /* Reset Ethernet switch clock */
+#define chipcHw_REG_SOFT_RESET_DDRPHY 0x0000001000000000ULL /* Reset DDR Physical */
+#define chipcHw_REG_SOFT_RESET_DDR 0x0000000800000000ULL /* Reset DDR Controller */
+#define chipcHw_REG_SOFT_RESET_TSC 0x0000000400000000ULL /* Reset Touch screen */
+#define chipcHw_REG_SOFT_RESET_PCM 0x0000000200000000ULL /* Reset PCM device */
+#define chipcHw_REG_SOFT_RESET_APM 0x0000200100000000ULL /* Reset APM device */
+
+#define chipcHw_REG_SOFT_RESET_VPM_GLOBAL_UNHOLD 0x8000000000000000ULL /* Unhold Global VPM */
+#define chipcHw_REG_SOFT_RESET_VPM_UNHOLD 0x4000000000000000ULL /* Unhold VPM */
+#define chipcHw_REG_SOFT_RESET_ARM_UNHOLD 0x2000000000000000ULL /* Unhold ARM reset */
+#define chipcHw_REG_SOFT_RESET_UNHOLD_MASK 0xF000000000000000ULL /* Mask to handle unhold request */
+
+/* Audio channel control defines */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_ALL 0x00000001 /* Enable all audio channel */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_A 0x00000002 /* Enable channel A */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_B 0x00000004 /* Enable channel B */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_C 0x00000008 /* Enable channel C */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_NTP_CLOCK 0x00000010 /* Enable NTP clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM0_CLOCK 0x00000020 /* Enable PCM0 clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_PCM1_CLOCK 0x00000040 /* Enable PCM1 clock */
+#define chipcHw_REG_AUDIO_CHANNEL_ENABLE_APM_CLOCK 0x00000080 /* Enable APM clock */
+
+/* Misc. chip control defines */
+#define chipcHw_REG_MISC_CTRL_GE_SEL 0x00040000 /* Select GE2/GE3 */
+#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S1 */
+#define chipcHw_REG_MISC_CTRL_I2S1_CLOCK_GPIO 0x00020000 /* Use external clock via GPIO pin 26 for I2S1 */
+#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_ONCHIP 0x00000000 /* Use on chip clock for I2S0 */
+#define chipcHw_REG_MISC_CTRL_I2S0_CLOCK_GPIO 0x00010000 /* Use external clock via GPIO pin 45 for I2S0 */
+#define chipcHw_REG_MISC_CTRL_ARM_CP15_DISABLE 0x00008000 /* Disable ARM CP15 bit */
+#define chipcHw_REG_MISC_CTRL_RTC_DISABLE 0x00000008 /* Disable RTC registers */
+#define chipcHw_REG_MISC_CTRL_BBRAM_DISABLE 0x00000004 /* Disable Battery Backed RAM */
+#define chipcHw_REG_MISC_CTRL_USB_MODE_HOST 0x00000002 /* Set USB as host */
+#define chipcHw_REG_MISC_CTRL_USB_MODE_DEVICE 0xFFFFFFFD /* Set USB as device */
+#define chipcHw_REG_MISC_CTRL_USB_POWERON 0xFFFFFFFE /* Power up USB */
+#define chipcHw_REG_MISC_CTRL_USB_POWEROFF 0x00000001 /* Power down USB */
+
+/* OTP configuration defines */
+#define chipcHw_REG_OTP_SECURITY_OFF 0x0000020000000000ULL /* Security support is OFF */
+#define chipcHw_REG_OTP_SPU_SLOW 0x0000010000000000ULL /* Limited SPU throughput */
+#define chipcHw_REG_OTP_LCD_SPEED 0x0000000600000000ULL /* Set VPM speed one */
+#define chipcHw_REG_OTP_VPM_SPEED_1 0x0000000100000000ULL /* Set VPM speed one */
+#define chipcHw_REG_OTP_VPM_SPEED_0 0x0000000080000000ULL /* Set VPM speed zero */
+#define chipcHw_REG_OTP_AXI_SPEED 0x0000000060000000ULL /* Set maximum AXI bus speed */
+#define chipcHw_REG_OTP_APM_DISABLE 0x000000001F000000ULL /* Disable APM */
+#define chipcHw_REG_OTP_PIF_DISABLE 0x0000000000200000ULL /* Disable PIF */
+#define chipcHw_REG_OTP_VDEC_DISABLE 0x0000000000100000ULL /* Disable Video decoder */
+#define chipcHw_REG_OTP_BBL_DISABLE 0x0000000000080000ULL /* Disable RTC and BBRAM */
+#define chipcHw_REG_OTP_LED_DISABLE 0x0000000000040000ULL /* Disable LED */
+#define chipcHw_REG_OTP_GE_DISABLE 0x0000000000020000ULL /* Disable Graphics Engine */
+#define chipcHw_REG_OTP_LCD_DISABLE 0x0000000000010000ULL /* Disable LCD */
+#define chipcHw_REG_OTP_KEYPAD_DISABLE 0x0000000000008000ULL /* Disable keypad */
+#define chipcHw_REG_OTP_UART_DISABLE 0x0000000000004000ULL /* Disable UART */
+#define chipcHw_REG_OTP_SDIOH_DISABLE 0x0000000000003000ULL /* Disable SDIO host */
+#define chipcHw_REG_OTP_HSS_DISABLE 0x0000000000000C00ULL /* Disable HSS */
+#define chipcHw_REG_OTP_TSC_DISABLE 0x0000000000000200ULL /* Disable touch screen */
+#define chipcHw_REG_OTP_USB_DISABLE 0x0000000000000180ULL /* Disable USB */
+#define chipcHw_REG_OTP_SGMII_DISABLE 0x0000000000000060ULL /* Disable SGMII */
+#define chipcHw_REG_OTP_ETH_DISABLE 0x0000000000000018ULL /* Disable gigabit ethernet */
+#define chipcHw_REG_OTP_ETH_PHY_DISABLE 0x0000000000000006ULL /* Disable ethernet PHY */
+#define chipcHw_REG_OTP_VPM_DISABLE 0x0000000000000001ULL /* Disable VPM */
+
+/* Sticky bit defines */
+#define chipcHw_REG_STICKY_BOOT_DONE 0x00000001 /* Boot done */
+#define chipcHw_REG_STICKY_SOFT_RESET 0x00000002 /* ARM soft reset */
+#define chipcHw_REG_STICKY_GENERAL_1 0x00000004 /* General purpose bit 1 */
+#define chipcHw_REG_STICKY_GENERAL_2 0x00000008 /* General purpose bit 2 */
+#define chipcHw_REG_STICKY_GENERAL_3 0x00000010 /* General purpose bit 3 */
+#define chipcHw_REG_STICKY_GENERAL_4 0x00000020 /* General purpose bit 4 */
+#define chipcHw_REG_STICKY_GENERAL_5 0x00000040 /* General purpose bit 5 */
+#define chipcHw_REG_STICKY_POR_BROM 0x00000080 /* Special sticky bit for security - set in BROM to avoid other modes being entered */
+#define chipcHw_REG_STICKY_ARM_RESET 0x00000100 /* ARM reset */
+#define chipcHw_REG_STICKY_CHIP_SOFT_RESET 0x00000200 /* Chip soft reset */
+#define chipcHw_REG_STICKY_CHIP_WARM_RESET 0x00000400 /* Chip warm reset */
+#define chipcHw_REG_STICKY_WDOG_RESET 0x00000800 /* Watchdog reset */
+#define chipcHw_REG_STICKY_OTP_RESET 0x00001000 /* OTP reset */
+
+ /* HW phase alignment defines *//* Spare1 register definitions */
+#define chipcHw_REG_SPARE1_DDR_PHASE_INTR_ENABLE 0x80000000 /* Enable DDR phase align panic interrupt */
+#define chipcHw_REG_SPARE1_VPM_PHASE_INTR_ENABLE 0x40000000 /* Enable VPM phase align panic interrupt */
+#define chipcHw_REG_SPARE1_VPM_BUS_ACCESS_ENABLE 0x00000002 /* Enable access to VPM using system BUS */
+#define chipcHw_REG_SPARE1_DDR_BUS_ACCESS_ENABLE 0x00000001 /* Enable access to DDR using system BUS */
+ /* DDRPhaseCtrl1 register definitions */
+#define chipcHw_REG_DDR_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable DDR SW phase alignment */
+#define chipcHw_REG_DDR_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable DDR HW phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_GE_MASK 0x0000007F /* DDR lower threshold for phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_GE_SHIFT 23
+#define chipcHw_REG_DDR_PHASE_VALUE_LE_MASK 0x0000007F /* DDR upper threshold for phase alignment */
+#define chipcHw_REG_DDR_PHASE_VALUE_LE_SHIFT 16
+#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to run next DDR phase alignment */
+#define chipcHw_REG_DDR_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0
+ /* VPMPhaseCtrl1 register definitions */
+#define chipcHw_REG_VPM_SW_PHASE_CTRL_ENABLE 0x80000000 /* Enable VPM SW phase alignment */
+#define chipcHw_REG_VPM_HW_PHASE_CTRL_ENABLE 0x40000000 /* Enable VPM HW phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_GE_MASK 0x0000007F /* VPM lower threshold for phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_GE_SHIFT 23
+#define chipcHw_REG_VPM_PHASE_VALUE_LE_MASK 0x0000007F /* VPM upper threshold for phase alignment */
+#define chipcHw_REG_VPM_PHASE_VALUE_LE_SHIFT 16
+#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_MASK 0x0000FFFF /* BUS Cycle to wait to complete the VPM phase alignment */
+#define chipcHw_REG_VPM_PHASE_ALIGN_WAIT_CYCLE_SHIFT 0
+ /* PhaseAlignStatus register definitions */
+#define chipcHw_REG_DDR_TIMEOUT_INTR_STATUS 0x80000000 /* DDR time out interrupt status */
+#define chipcHw_REG_DDR_PHASE_STATUS_MASK 0x0000007F /* DDR phase status value */
+#define chipcHw_REG_DDR_PHASE_STATUS_SHIFT 24
+#define chipcHw_REG_DDR_PHASE_ALIGNED 0x00800000 /* DDR Phase aligned status */
+#define chipcHw_REG_DDR_LOAD 0x00400000 /* Load DDR phase status */
+#define chipcHw_REG_DDR_PHASE_CTRL_MASK 0x0000003F /* DDR phase control value */
+#define chipcHw_REG_DDR_PHASE_CTRL_SHIFT 16
+#define chipcHw_REG_VPM_TIMEOUT_INTR_STATUS 0x80000000 /* VPM time out interrupt status */
+#define chipcHw_REG_VPM_PHASE_STATUS_MASK 0x0000007F /* VPM phase status value */
+#define chipcHw_REG_VPM_PHASE_STATUS_SHIFT 8
+#define chipcHw_REG_VPM_PHASE_ALIGNED 0x00000080 /* VPM Phase aligned status */
+#define chipcHw_REG_VPM_LOAD 0x00000040 /* Load VPM phase status */
+#define chipcHw_REG_VPM_PHASE_CTRL_MASK 0x0000003F /* VPM phase control value */
+#define chipcHw_REG_VPM_PHASE_CTRL_SHIFT 0
+ /* DDRPhaseCtrl2 register definitions */
+#define chipcHw_REG_DDR_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */
+#define chipcHw_REG_DDR_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */
+#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */
+#define chipcHw_REG_DDR_LOAD_COUNT_PHASE_CTRL_SHIFT 20
+#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait to settle ph_ctrl and load_ch */
+#define chipcHw_REG_DDR_TOTAL_LOAD_COUNT_CTRL_SHIFT 16
+#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for DDR HW phase alignment */
+#define chipcHw_REG_DDR_PHASE_TIMEOUT_COUNT_SHIFT 0
+ /* VPMPhaseCtrl2 register definitions */
+#define chipcHw_REG_VPM_INTR_SELECT_MASK 0x00000003 /* Interrupt select */
+#define chipcHw_REG_VPM_INTR_SELECT_SHIFT 26
+#define chipcHw_REG_VPM_INTR_DISABLE 0x00000000
+#define chipcHw_REG_VPM_INTR_FAST (0x1 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_MEDIUM (0x2 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_SLOW (0x3 << chipcHw_REG_VPM_INTR_SELECT_SHIFT)
+#define chipcHw_REG_VPM_INTR_SERVICED 0x02000000 /* Acknowledge that interrupt was serviced */
+#define chipcHw_REG_VPM_TIMEOUT_INTR_ENABLE 0x01000000 /* Enable time out interrupt */
+#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_MASK 0x0000000F /* Wait before toggling load_ch */
+#define chipcHw_REG_VPM_LOAD_COUNT_PHASE_CTRL_SHIFT 20
+#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_MASK 0x0000000F /* Total wait cycle to settle ph_ctrl and load_ch */
+#define chipcHw_REG_VPM_TOTAL_LOAD_COUNT_CTRL_SHIFT 16
+#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_MASK 0x0000FFFF /* Time out value for VPM HW phase alignment */
+#define chipcHw_REG_VPM_PHASE_TIMEOUT_COUNT_SHIFT 0
+
+#endif /* CHIPCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
new file mode 100644
index 00000000..f1b68e26
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/ddrcReg.h
@@ -0,0 +1,872 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file ddrcReg.h
+*
+* @brief Register definitions for BCMRING DDR2 Controller and PHY
+*
+*/
+/****************************************************************************/
+
+#ifndef DDRC_REG_H
+#define DDRC_REG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <csp/reg.h>
+#include <csp/stdint.h>
+
+#include <mach/csp/mm_io.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+/*********************************************************************/
+/* DDR2 Controller (ARM PL341) register definitions */
+/*********************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 DDR2 configuration registers, offset 0x000 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+ typedef struct {
+ uint32_t memcStatus;
+ uint32_t memcCmd;
+ uint32_t directCmd;
+ uint32_t memoryCfg;
+ uint32_t refreshPrd;
+ uint32_t casLatency;
+ uint32_t writeLatency;
+ uint32_t tMrd;
+ uint32_t tRas;
+ uint32_t tRc;
+ uint32_t tRcd;
+ uint32_t tRfc;
+ uint32_t tRp;
+ uint32_t tRrd;
+ uint32_t tWr;
+ uint32_t tWtr;
+ uint32_t tXp;
+ uint32_t tXsr;
+ uint32_t tEsr;
+ uint32_t memoryCfg2;
+ uint32_t memoryCfg3;
+ uint32_t tFaw;
+ } ddrcReg_CTLR_MEMC_REG_t;
+
+#define ddrcReg_CTLR_MEMC_REG_OFFSET 0x0000
+#define ddrcReg_CTLR_MEMC_REGP ((volatile ddrcReg_CTLR_MEMC_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_MEMC_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_MASK (0x3 << 12)
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_4 (0x0 << 12)
+#define ddrcReg_CTLR_MEMC_STATUS_BANKS_8 (0x3 << 12)
+
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_MASK (0x3 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_0 (0x0 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_1 (0x1 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_2 (0x2 << 10)
+#define ddrcReg_CTLR_MEMC_STATUS_MONITORS_4 (0x3 << 10)
+
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_MASK (0x3 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_1 (0x0 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_2 (0x1 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_3 (0x2 << 7)
+#define ddrcReg_CTLR_MEMC_STATUS_CHIPS_4 (0x3 << 7)
+
+#define ddrcReg_CTLR_MEMC_STATUS_TYPE_MASK (0x7 << 4)
+#define ddrcReg_CTLR_MEMC_STATUS_TYPE_DDR2 (0x5 << 4)
+
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_MASK (0x3 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_16 (0x0 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_32 (0x1 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_64 (0x2 << 2)
+#define ddrcReg_CTLR_MEMC_STATUS_WIDTH_128 (0x3 << 2)
+
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_MASK (0x3 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_CONFIG (0x0 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_READY (0x1 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_PAUSED (0x2 << 0)
+#define ddrcReg_CTLR_MEMC_STATUS_STATE_LOWPWR (0x3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMC_CMD_MASK (0x7 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_GO (0x0 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_SLEEP (0x1 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_WAKEUP (0x2 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_PAUSE (0x3 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_CONFIGURE (0x4 << 0)
+#define ddrcReg_CTLR_MEMC_CMD_ACTIVE_PAUSE (0x7 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT 20
+#define ddrcReg_CTLR_DIRECT_CMD_CHIP_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_CHIP_SHIFT)
+
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_PRECHARGEALL (0x0 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_AUTOREFRESH (0x1 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_MODEREG (0x2 << 18)
+#define ddrcReg_CTLR_DIRECT_CMD_TYPE_NOP (0x3 << 18)
+
+#define ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT 16
+#define ddrcReg_CTLR_DIRECT_CMD_BANK_MASK (0x3 << ddrcReg_CTLR_DIRECT_CMD_BANK_SHIFT)
+
+#define ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT 0
+#define ddrcReg_CTLR_DIRECT_CMD_ADDR_MASK (0x1ffff << ddrcReg_CTLR_DIRECT_CMD_ADDR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_MASK (0x3 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_1 (0x0 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_2 (0x1 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_3 (0x2 << 21)
+#define ddrcReg_CTLR_MEMORY_CFG_CHIP_CNT_4 (0x3 << 21)
+
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_MASK (0x7 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_3_0 (0x0 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_4_1 (0x1 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_5_2 (0x2 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_6_3 (0x3 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_7_4 (0x4 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_8_5 (0x5 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_9_6 (0x6 << 18)
+#define ddrcReg_CTLR_MEMORY_CFG_QOS_ARID_10_7 (0x7 << 18)
+
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_MASK (0x7 << 15)
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_4 (0x2 << 15)
+#define ddrcReg_CTLR_MEMORY_CFG_BURST_LEN_8 (0x3 << 15) /* @note Not supported in PL341 */
+
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_ENABLE (0x1 << 13)
+
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT 7
+#define ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_MASK (0x3f << ddrcReg_CTLR_MEMORY_CFG_PWRDOWN_CYCLES_SHIFT)
+
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_MASK (0x7 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_11 (0x0 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_12 (0x1 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_13 (0x2 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_14 (0x3 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_15 (0x4 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_ROW_BITS_16 (0x5 << 3)
+
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_MASK (0x7 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_9 (0x1 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_10 (0x2 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG_AXI_COL_BITS_11 (0x3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_REFRESH_PRD_SHIFT 0
+#define ddrcReg_CTLR_REFRESH_PRD_MASK (0x7fff << ddrcReg_CTLR_REFRESH_PRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_CAS_LATENCY_SHIFT 1
+#define ddrcReg_CTLR_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_CAS_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_WRITE_LATENCY_SHIFT 0
+#define ddrcReg_CTLR_WRITE_LATENCY_MASK (0x7 << ddrcReg_CTLR_WRITE_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_MRD_SHIFT 0
+#define ddrcReg_CTLR_T_MRD_MASK (0x7f << ddrcReg_CTLR_T_MRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RAS_SHIFT 0
+#define ddrcReg_CTLR_T_RAS_MASK (0x1f << ddrcReg_CTLR_T_RAS_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RC_SHIFT 0
+#define ddrcReg_CTLR_T_RC_MASK (0x1f << ddrcReg_CTLR_T_RC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT 8
+#define ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RCD_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RCD_SHIFT 0
+#define ddrcReg_CTLR_T_RCD_MASK (0x7 << ddrcReg_CTLR_T_RCD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT 8
+#define ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_MASK (0x7f << ddrcReg_CTLR_T_RFC_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RFC_SHIFT 0
+#define ddrcReg_CTLR_T_RFC_MASK (0x7f << ddrcReg_CTLR_T_RFC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT 8
+#define ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_MASK (0x7 << ddrcReg_CTLR_T_RP_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_RP_SHIFT 0
+#define ddrcReg_CTLR_T_RP_MASK (0xf << ddrcReg_CTLR_T_RP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_RRD_SHIFT 0
+#define ddrcReg_CTLR_T_RRD_MASK (0xf << ddrcReg_CTLR_T_RRD_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_WR_SHIFT 0
+#define ddrcReg_CTLR_T_WR_MASK (0x7 << ddrcReg_CTLR_T_WR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_WTR_SHIFT 0
+#define ddrcReg_CTLR_T_WTR_MASK (0x7 << ddrcReg_CTLR_T_WTR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_XP_SHIFT 0
+#define ddrcReg_CTLR_T_XP_MASK (0xff << ddrcReg_CTLR_T_XP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_XSR_SHIFT 0
+#define ddrcReg_CTLR_T_XSR_MASK (0xff << ddrcReg_CTLR_T_XSR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_ESR_SHIFT 0
+#define ddrcReg_CTLR_T_ESR_MASK (0xff << ddrcReg_CTLR_T_ESR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_MASK (0x3 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_16BITS (0 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_32BITS (1 << 6)
+#define ddrcReg_CTLR_MEMORY_CFG2_WIDTH_64BITS (2 << 6)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_MASK (0x3 << 4)
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_2 (0 << 4)
+#define ddrcReg_CTLR_MEMORY_CFG2_AXI_BANK_BITS_3 (3 << 4)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_LOW (0 << 3)
+#define ddrcReg_CTLR_MEMORY_CFG2_CKE_INIT_STATE_HIGH (1 << 3)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_LOW (0 << 2)
+#define ddrcReg_CTLR_MEMORY_CFG2_DQM_INIT_STATE_HIGH (1 << 2)
+
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_MASK (0x3 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_ASYNC (0 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_LE_M (1 << 0)
+#define ddrcReg_CTLR_MEMORY_CFG2_CLK_SYNC_A_GT_M (3 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT 0
+#define ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_MASK (0x7 << ddrcReg_CTLR_MEMORY_CFG3_REFRESH_TO_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT 8
+#define ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_MASK (0x1f << ddrcReg_CTLR_T_FAW_SCHEDULE_DELAY_SHIFT)
+
+#define ddrcReg_CTLR_T_FAW_PERIOD_SHIFT 0
+#define ddrcReg_CTLR_T_FAW_PERIOD_MASK (0x1f << ddrcReg_CTLR_T_FAW_PERIOD_SHIFT)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 AXI ID QOS configuration registers, offset 0x100 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_QOS_CNT 16
+#define ddrcReg_CTLR_QOS_MAX (ddrcReg_CTLR_QOS_CNT - 1)
+
+ typedef struct {
+ uint32_t cfg[ddrcReg_CTLR_QOS_CNT];
+ } ddrcReg_CTLR_QOS_REG_t;
+
+#define ddrcReg_CTLR_QOS_REG_OFFSET 0x100
+#define ddrcReg_CTLR_QOS_REGP ((volatile ddrcReg_CTLR_QOS_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_QOS_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_QOS_CFG_MAX_SHIFT 2
+#define ddrcReg_CTLR_QOS_CFG_MAX_MASK (0xff << ddrcReg_CTLR_QOS_CFG_MAX_SHIFT)
+
+#define ddrcReg_CTLR_QOS_CFG_MIN_SHIFT 1
+#define ddrcReg_CTLR_QOS_CFG_MIN_MASK (1 << ddrcReg_CTLR_QOS_CFG_MIN_SHIFT)
+
+#define ddrcReg_CTLR_QOS_CFG_ENABLE (1 << 0)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 Memory chip configuration registers, offset 0x200 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_CHIP_CNT 4
+#define ddrcReg_CTLR_CHIP_MAX (ddrcReg_CTLR_CHIP_CNT - 1)
+
+ typedef struct {
+ uint32_t cfg[ddrcReg_CTLR_CHIP_CNT];
+ } ddrcReg_CTLR_CHIP_REG_t;
+
+#define ddrcReg_CTLR_CHIP_REG_OFFSET 0x200
+#define ddrcReg_CTLR_CHIP_REGP ((volatile ddrcReg_CTLR_CHIP_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_CHIP_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_MASK (1 << 16)
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_ROW_BANK_COL (0 << 16)
+#define ddrcReg_CTLR_CHIP_CFG_MEM_ORG_BANK_ROW_COL (1 << 16)
+
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT 8
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MATCH_SHIFT)
+
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT 0
+#define ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_MASK (0xff << ddrcReg_CTLR_CHIP_CFG_AXI_ADDR_MASK_SHIFT)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* ARM PL341 User configuration registers, offset 0x300 */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_OUTPUT_CNT 2
+
+ typedef struct {
+ uint32_t input;
+ uint32_t output[ddrcReg_CTLR_USER_OUTPUT_CNT];
+ uint32_t feature;
+ } ddrcReg_CTLR_USER_REG_t;
+
+#define ddrcReg_CTLR_USER_REG_OFFSET 0x300
+#define ddrcReg_CTLR_USER_REGP ((volatile ddrcReg_CTLR_USER_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_USER_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT 0
+#define ddrcReg_CTLR_USER_INPUT_STATUS_MASK (0xff << ddrcReg_CTLR_USER_INPUT_STATUS_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT 0
+#define ddrcReg_CTLR_USER_OUTPUT_CFG_MASK (0xff << ddrcReg_CTLR_USER_OUTPUT_CFG_SHIFT)
+
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT 1
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_USER_OUTPUT_0_CFG_SYNC_BRIDGE_PL301
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_CTLR_FEATURE_WRITE_BLOCK_DISABLE (1 << 2)
+#define ddrcReg_CTLR_FEATURE_EARLY_BURST_RSP_DISABLE (1 << 0)
+
+/*********************************************************************/
+/* Broadcom DDR23 PHY register definitions */
+/*********************************************************************/
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* Broadcom DDR23 PHY Address and Control register definitions */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+ typedef struct {
+ uint32_t revision;
+ uint32_t pmCtl;
+ REG32_RSVD(0x0008, 0x0010);
+ uint32_t pllStatus;
+ uint32_t pllCfg;
+ uint32_t pllPreDiv;
+ uint32_t pllDiv;
+ uint32_t pllCtl1;
+ uint32_t pllCtl2;
+ uint32_t ssCtl;
+ uint32_t ssCfg;
+ uint32_t vdlStatic;
+ uint32_t vdlDynamic;
+ uint32_t padIdle;
+ uint32_t pvtComp;
+ uint32_t padDrive;
+ uint32_t clkRgltrCtl;
+ } ddrcReg_PHY_ADDR_CTL_REG_t;
+
+#define ddrcReg_PHY_ADDR_CTL_REG_OFFSET 0x0400
+#define ddrcReg_PHY_ADDR_CTL_REGP ((volatile ddrcReg_PHY_ADDR_CTL_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_ADDR_CTL_REG_OFFSET))
+
+/* @todo These SS definitions are duplicates of ones below */
+
+#define ddrcReg_PHY_ADDR_SS_CTRL_ENABLE 0x00000001
+#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_MASK 0xFFFF0000
+#define ddrcReg_PHY_ADDR_SS_CFG_CYCLE_PER_TICK_SHIFT 16
+#define ddrcReg_PHY_ADDR_SS_CFG_MIN_CYCLE_PER_TICK 10 /* Higher the value, lower the SS modulation frequency */
+#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_MASK 0x0000FFFF
+#define ddrcReg_PHY_ADDR_SS_CFG_NDIV_AMPLITUDE_SHIFT 0
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT 8
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MAJOR_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_ADDR_CTL_REVISION_MINOR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_CLK_PM_CTL_DDR_CLK_DISABLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_STATUS_LOCKED (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_DIV2_CLK_RESET (1 << 31)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT 17
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_SEL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_TEST_ENABLE (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT 12
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_CFG_BGAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_VCO_RNG (1 << 7)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CH1_PWRDWN (1 << 6)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_BYPASS_ENABLE (1 << 5)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_CLKOUT_ENABLE (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_D_RESET (1 << 3)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_A_RESET (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CFG_PWRDWN (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_DITHER_MFB (1 << 26)
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_PWRDWN (1 << 25)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT 20
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_MODE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT 8
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_MASK (0x1ff << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_INT_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT 4
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P2_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PLL_PRE_DIV_P1_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT 24
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_MASK (0xff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_M1_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_MASK (0xffffff << ddrcReg_PHY_ADDR_CTL_PLL_DIV_FRAC_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT 30
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_TESTA_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT 27
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XS_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT 24
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_KVCO_XF_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT 22
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LPF_BW_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_LF_ORDER (0x1 << 21)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT 19
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CN_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT 17
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RN_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT 15
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CP_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT 13
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_CZ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT 10
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_MASK (0x7 << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_RZ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT 5
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICPX_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_MASK (0x1f << ddrcReg_PHY_ADDR_CTL_PLL_CTL1_ICP_OFF_SHIFT)
+
+/* ----------------------------------------------------- */
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT 4
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_PTAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT 2
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_PLL_CTL2_CTAP_ADJ_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_LOWCUR_ENABLE (0x1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PLL_CTL2_BIASIN_ENABLE (0x1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_EN_ENABLE (0x1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT 16
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_CYC_PER_TICK_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_MASK (0xffff << ddrcReg_PHY_ADDR_CTL_PLL_SS_CFG_NDIV_AMP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FORCE (1 << 20)
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_ENABLE (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT 12
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT 8
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_STATIC_OVR_STEP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_ENABLE (1 << 16)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT 12
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT 8
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_MASK (0x3 << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_MASK (0x3f << ddrcReg_PHY_ADDR_CTL_VDL_DYNAMIC_OVR_STEP_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_ENABLE (1u << 31)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_RXENB_DISABLE (1 << 8)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_IDDQ_DISABLE (1 << 6)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_REB_DISABLE (1 << 5)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CTL_OEB_DISABLE (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_IDDQ_DISABLE (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_REB_DISABLE (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PAD_IDLE_CKE_OEB_DISABLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_DONE (1 << 30)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_DONE (1 << 29)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_DONE (1 << 28)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_AUTO_ENABLE (1 << 27)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_SAMPLE_ENABLE (1 << 26)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_OVR_ENABLE (1 << 25)
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_OVR_ENABLE (1 << 24)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT 20
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT 16
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ND_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT 12
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT 8
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_ADDR_ND_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT 4
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_PD_SHIFT)
+
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT 0
+#define ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_MASK (0xf << ddrcReg_PHY_ADDR_CTL_PVT_COMP_DQ_ND_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_RT60B (1 << 4)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SEL_SSTL18 (1 << 3)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELTXDRV_CI (1 << 2)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SELRXDRV (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_PAD_DRIVE_SLEW (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_HALF (1 << 1)
+#define ddrcReg_PHY_ADDR_CTL_CLK_RGLTR_CTL_PWR_OFF (1 << 0)
+
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+/* Broadcom DDR23 PHY Byte Lane register definitions */
+/* -------------------------------------------------------------------- */
+/* -------------------------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_CNT 2
+#define ddrcReg_PHY_BYTE_LANE_MAX (ddrcReg_CTLR_BYTE_LANE_CNT - 1)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT 8
+
+ typedef struct {
+ uint32_t revision;
+ uint32_t vdlCalibrate;
+ uint32_t vdlStatus;
+ REG32_RSVD(0x000c, 0x0010);
+ uint32_t vdlOverride[ddrcReg_PHY_BYTE_LANE_VDL_OVR_CNT];
+ uint32_t readCtl;
+ uint32_t readStatus;
+ uint32_t readClear;
+ uint32_t padIdleCtl;
+ uint32_t padDriveCtl;
+ uint32_t padClkCtl;
+ uint32_t writeCtl;
+ uint32_t clkRegCtl;
+ } ddrcReg_PHY_BYTE_LANE_REG_t;
+
+/* There are 2 instances of the byte Lane registers, one for each byte lane. */
+#define ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET 0x0500
+#define ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET 0x0600
+
+#define ddrcReg_PHY_BYTE_LANE_1_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_1_REG_OFFSET))
+#define ddrcReg_PHY_BYTE_LANE_2_REGP ((volatile ddrcReg_PHY_BYTE_LANE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_PHY_BYTE_LANE_2_REG_OFFSET))
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT 8
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MAJOR_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT 0
+#define ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_MASK (0xff << ddrcReg_PHY_BYTE_LANE_REVISION_MINOR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_2CYCLE (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_CLK_1CYCLE (0 << 4)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_TEST (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ALWAYS (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_ONCE (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_VDL_CALIB_FAST (1 << 0)
+
+/* ----------------------------------------------------- */
+
+/* The byte lane VDL status calibTotal[9:0] is comprised of [9:4] step value, [3:2] fine fall */
+/* and [1:0] fine rise. Note that calibTotal[9:0] is located at bit 4 in the VDL status */
+/* register. The fine rise and fall are no longer used, so add some definitions for just */
+/* the step setting to simplify things. */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT 8
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_STEP_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT 4
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_MASK (0x3ff << ddrcReg_PHY_BYTE_LANE_VDL_STATUS_TOTAL_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_LOCK (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_VDL_STATUS_IDLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_ENABLE (1 << 16)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT 12
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_FALL_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT 8
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_VDL_OVR_RISE_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT 0
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_MASK (0x3f << ddrcReg_PHY_BYTE_LANE_VDL_OVR_STEP_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_P 0
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_DQS_N 1
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_READ_EN 2
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_STATIC_WRITE_DQ_DQM 3
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_P 4
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_DQS_N 5
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_READ_EN 6
+#define ddrcReg_PHY_BYTE_LANE_VDL_OVR_IDX_DYNAMIC_WRITE_DQ_DQM 7
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT 8
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_MASK (0x3 << ddrcReg_PHY_BYTE_LANE_READ_CTL_DELAY_SHIFT)
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ENABLE (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_DQ_ODT_ADJUST (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ENABLE (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_READ_CTL_RD_ODT_ADJUST (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT 0
+#define ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_MASK (0xf << ddrcReg_PHY_BYTE_LANE_READ_STATUS_ERROR_SHIFT)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_READ_CLEAR_STATUS (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_ENABLE (1u << 31)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_RXENB_DISABLE (1 << 19)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_IDDQ_DISABLE (1 << 18)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_REB_DISABLE (1 << 17)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DM_OEB_DISABLE (1 << 16)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_RXENB_DISABLE (1 << 15)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_IDDQ_DISABLE (1 << 14)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_REB_DISABLE (1 << 13)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQ_OEB_DISABLE (1 << 12)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_RXENB_DISABLE (1 << 11)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_IDDQ_DISABLE (1 << 10)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_REB_DISABLE (1 << 9)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_READ_ENB_OEB_DISABLE (1 << 8)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_RXENB_DISABLE (1 << 7)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_IDDQ_DISABLE (1 << 6)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_REB_DISABLE (1 << 5)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_DQS_OEB_DISABLE (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_RXENB_DISABLE (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_IDDQ_DISABLE (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_REB_DISABLE (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_PAD_IDLE_CTL_CLK_OEB_DISABLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B_DDR_READ_ENB (1 << 5)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_RT60B (1 << 4)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SEL_SSTL18 (1 << 3)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELTXDRV_CI (1 << 2)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SELRXDRV (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_PAD_DRIVE_CTL_SLEW (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_PAD_CLK_CTL_DISABLE (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_WRITE_CTL_PREAMBLE_DDR3 (1 << 0)
+
+/* ----------------------------------------------------- */
+
+#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_HALF (1 << 1)
+#define ddrcReg_PHY_BYTE_LANE_CLK_REG_CTL_PWR_OFF (1 << 0)
+
+/*********************************************************************/
+/* ARM PL341 DDRC to Broadcom DDR23 PHY glue register definitions */
+/*********************************************************************/
+
+ typedef struct {
+ uint32_t cfg;
+ uint32_t actMonCnt;
+ uint32_t ctl;
+ uint32_t lbistCtl;
+ uint32_t lbistSeed;
+ uint32_t lbistStatus;
+ uint32_t tieOff;
+ uint32_t actMonClear;
+ uint32_t status;
+ uint32_t user;
+ } ddrcReg_CTLR_PHY_GLUE_REG_t;
+
+#define ddrcReg_CTLR_PHY_GLUE_OFFSET 0x0700
+#define ddrcReg_CTLR_PHY_GLUE_REGP ((volatile ddrcReg_CTLR_PHY_GLUE_REG_t *) (MM_IO_BASE_DDRC + ddrcReg_CTLR_PHY_GLUE_OFFSET))
+
+/* ----------------------------------------------------- */
+
+/* DDR2 / AXI block phase alignment interrupt control */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT 18
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_MASK (0x3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_OFF (0 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_TIGHT (1 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_MEDIUM (2 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_INT_ON_LOOSE (3 << ddrcReg_CTLR_PHY_GLUE_CFG_INT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT 17
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_DIFFERENTIAL (0 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_CMOS (1 << ddrcReg_CTLR_PHY_GLUE_CFG_PLL_REFCLK_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT 16
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_DEEP (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_HW_FIXED_ALIGNMENT_DISABLED ddrcReg_CTLR_PHY_GLUE_CFG_DIV2CLK_TREE_SHALLOW
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT 15
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_BP134 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_REGISTERED ddrcReg_CTLR_PHY_GLUE_CFG_SYNC_BRIDGE_PL301
+
+/* Software control of PHY VDL updates from control register settings. Bit 13 enables the use of Bit 14. */
+/* If software control is not enabled, then updates occur when a refresh command is issued by the hardware */
+/* controller. If 2 chips selects are being used, then software control must be enabled. */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_LOAD (1 << 14)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_VDL_UPDATE_SW_CTL_ENABLE (1 << 13)
+
+/* Use these to bypass a pipeline stage. By default the ADDR is off but the BYTE LANE in / out are on. */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_ADDR_CTL_IN_BYPASS_PIPELINE_STAGE (1 << 12)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_IN_BYPASS_PIPELINE_STAGE (1 << 11)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_PHY_BYTE_LANE_OUT_BYPASS_PIPELINE_STAGE (1 << 10)
+
+/* Chip select count */
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT 9
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_MASK (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_1 (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_2 (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CS_CNT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT 8
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_ASYNC (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SYNC (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CLK_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT 7
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_CKE_INIT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT 6
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_LOW (0 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
+#define ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_HIGH (1 << ddrcReg_CTLR_PHY_GLUE_CFG_DQM_INIT_SHIFT)
+
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT 0
+#define ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_MASK (0x7 << ddrcReg_CTLR_PHY_GLUE_CFG_CAS_LATENCY_SHIFT)
+
+/* ----------------------------------------------------- */
+#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT 0
+#define ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_MASK (0x7f << ddrcReg_CTLR_PHY_GLUE_STATUS_PHASE_SHIFT)
+
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#ifdef __cplusplus
+} /* end extern "C" */
+#endif
+#endif /* DDRC_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
new file mode 100644
index 00000000..d67e2f8c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h
@@ -0,0 +1,145 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dmacHw_priv.h
+*
+* @brief Private Definitions for low level DMA driver
+*
+*/
+/****************************************************************************/
+
+#ifndef _DMACHW_PRIV_H
+#define _DMACHW_PRIV_H
+
+#include <csp/stdint.h>
+
+/* Data type for DMA Link List Item */
+typedef struct {
+ uint32_t sar; /* Source Address Register.
+ Address must be aligned to CTLx.SRC_TR_WIDTH. */
+ uint32_t dar; /* Destination Address Register.
+ Address must be aligned to CTLx.DST_TR_WIDTH. */
+ uint32_t llpPhy; /* LLP contains the physical address of the next descriptor for block chaining using linked lists.
+ Address MUST be aligned to a 32-bit boundary. */
+ dmacHw_REG64_t ctl; /* Control Register. 64 bits */
+ uint32_t sstat; /* Source Status Register */
+ uint32_t dstat; /* Destination Status Register */
+ uint32_t devCtl; /* Device specific control information */
+ uint32_t llp; /* LLP contains the virtual address of the next descriptor for block chaining using linked lists. */
+} dmacHw_DESC_t;
+
+/*
+ * Descriptor ring pointers
+ */
+typedef struct {
+ int num; /* Number of link items */
+ dmacHw_DESC_t *pHead; /* Head of descriptor ring (for writing) */
+ dmacHw_DESC_t *pTail; /* Tail of descriptor ring (for reading) */
+ dmacHw_DESC_t *pProg; /* Descriptor to program the channel (for programming the channel register) */
+ dmacHw_DESC_t *pEnd; /* End of current descriptor chain */
+ dmacHw_DESC_t *pFree; /* Descriptor to free memory (freeing dynamic memory) */
+ uint32_t virt2PhyOffset; /* Virtual to physical address offset for the descriptor ring */
+} dmacHw_DESC_RING_t;
+
+/*
+ * DMA channel control block
+ */
+typedef struct {
+ uint32_t module; /* DMA controller module (0-1) */
+ uint32_t channel; /* DMA channel (0-7) */
+ volatile uint32_t varDataStarted; /* Flag indicating variable data channel is enabled */
+ volatile uint32_t descUpdated; /* Flag to indicate descriptor update is complete */
+ void *userData; /* Channel specifc user data */
+} dmacHw_CBLK_t;
+
+#define dmacHw_ASSERT(a) if (!(a)) while (1)
+#define dmacHw_MAX_CHANNEL_COUNT 16
+#define dmacHw_FREE_USER_MEMORY 0xFFFFFFFF
+#define dmacHw_DESC_FREE dmacHw_REG_CTL_DONE
+#define dmacHw_DESC_INIT ((dmacHw_DESC_t *) 0xFFFFFFFF)
+#define dmacHw_MAX_BLOCKSIZE 4064
+#define dmacHw_GET_DESC_RING(addr) (dmacHw_DESC_RING_t *)(addr)
+#define dmacHw_ADDRESS_MASK(byte) ((byte) - 1)
+#define dmacHw_NEXT_DESC(rp, dp) ((rp)->dp = (dmacHw_DESC_t *)(rp)->dp->llp)
+#define dmacHw_HANDLE_TO_CBLK(handle) ((dmacHw_CBLK_t *) (handle))
+#define dmacHw_CBLK_TO_HANDLE(cblkp) ((dmacHw_HANDLE_t) (cblkp))
+#define dmacHw_DST_IS_MEMORY(tt) (((tt) == dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM) || ((tt) == dmacHw_TRANSFER_TYPE_MEM_TO_MEM)) ? 1 : 0
+
+/****************************************************************************/
+/**
+* @brief Get next available transaction width
+*
+*
+* @return On success : Next available transaction width
+* On failure : dmacHw_TRANSACTION_WIDTH_8
+*
+* @note
+* None
+*/
+/****************************************************************************/
+static inline dmacHw_TRANSACTION_WIDTH_e dmacHw_GetNextTrWidth(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Current transaction width */
+ ) {
+ if (tw & dmacHw_REG_CTL_SRC_TR_WIDTH_MASK) {
+ return ((tw >> dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT) -
+ 1) << dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT;
+ } else if (tw & dmacHw_REG_CTL_DST_TR_WIDTH_MASK) {
+ return ((tw >> dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT) -
+ 1) << dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT;
+ }
+
+ /* Default return */
+ return dmacHw_SRC_TRANSACTION_WIDTH_8;
+}
+
+/****************************************************************************/
+/**
+* @brief Get number of bytes per transaction
+*
+* @return Number of bytes per transaction
+*
+*
+* @note
+* None
+*/
+/****************************************************************************/
+static inline int dmacHw_GetTrWidthInBytes(dmacHw_TRANSACTION_WIDTH_e tw /* [ IN ] Transaction width */
+ ) {
+ int width = 1;
+ switch (tw) {
+ case dmacHw_SRC_TRANSACTION_WIDTH_8:
+ width = 1;
+ break;
+ case dmacHw_SRC_TRANSACTION_WIDTH_16:
+ case dmacHw_DST_TRANSACTION_WIDTH_16:
+ width = 2;
+ break;
+ case dmacHw_SRC_TRANSACTION_WIDTH_32:
+ case dmacHw_DST_TRANSACTION_WIDTH_32:
+ width = 4;
+ break;
+ case dmacHw_SRC_TRANSACTION_WIDTH_64:
+ case dmacHw_DST_TRANSACTION_WIDTH_64:
+ width = 8;
+ break;
+ default:
+ dmacHw_ASSERT(0);
+ }
+
+ /* Default transaction width */
+ return width;
+}
+
+#endif /* _DMACHW_PRIV_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
new file mode 100644
index 00000000..f1ecf96f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h
@@ -0,0 +1,406 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dmacHw_reg.h
+*
+* @brief Definitions for low level DMA registers
+*
+*/
+/****************************************************************************/
+
+#ifndef _DMACHW_REG_H
+#define _DMACHW_REG_H
+
+#include <csp/stdint.h>
+#include <mach/csp/mm_io.h>
+
+/* Data type for 64 bit little endian register */
+typedef struct {
+ volatile uint32_t lo; /* Lower 32 bit in little endian mode */
+ volatile uint32_t hi; /* Upper 32 bit in little endian mode */
+} dmacHw_REG64_t;
+
+/* Data type representing DMA channel registers */
+typedef struct {
+ dmacHw_REG64_t ChannelSar; /* Source Address Register. 64 bits (upper 32 bits are reserved)
+ Address must be aligned to CTLx.SRC_TR_WIDTH.
+ */
+ dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved)
+ Address must be aligned to CTLx.DST_TR_WIDTH.
+ */
+ dmacHw_REG64_t ChannelLlp; /* Link List Pointer.64 bits (upper 32 bits are reserved)
+ LLP contains the pointer to the next LLI for block chaining using linked lists.
+ If LLPis set to 0x0, then transfers using linked lists are not enabled.
+ Address MUST be aligned to a 32-bit boundary.
+ */
+ dmacHw_REG64_t ChannelCtl; /* Control Register. 64 bits */
+ dmacHw_REG64_t ChannelSstat; /* Source Status Register */
+ dmacHw_REG64_t ChannelDstat; /* Destination Status Register */
+ dmacHw_REG64_t ChannelSstatAddr; /* Source Status Address Register */
+ dmacHw_REG64_t ChannelDstatAddr; /* Destination Status Address Register */
+ dmacHw_REG64_t ChannelConfig; /* Channel Configuration Register */
+ dmacHw_REG64_t SrcGather; /* Source gather register */
+ dmacHw_REG64_t DstScatter; /* Destination scatter register */
+} dmacHw_CH_REG_t;
+
+/* Data type for RAW interrupt status registers */
+typedef struct {
+ dmacHw_REG64_t RawTfr; /* Raw Status for IntTfr Interrupt */
+ dmacHw_REG64_t RawBlock; /* Raw Status for IntBlock Interrupt */
+ dmacHw_REG64_t RawSrcTran; /* Raw Status for IntSrcTran Interrupt */
+ dmacHw_REG64_t RawDstTran; /* Raw Status for IntDstTran Interrupt */
+ dmacHw_REG64_t RawErr; /* Raw Status for IntErr Interrupt */
+} dmacHw_INT_RAW_t;
+
+/* Data type for interrupt status registers */
+typedef struct {
+ dmacHw_REG64_t StatusTfr; /* Status for IntTfr Interrupt */
+ dmacHw_REG64_t StatusBlock; /* Status for IntBlock Interrupt */
+ dmacHw_REG64_t StatusSrcTran; /* Status for IntSrcTran Interrupt */
+ dmacHw_REG64_t StatusDstTran; /* Status for IntDstTran Interrupt */
+ dmacHw_REG64_t StatusErr; /* Status for IntErr Interrupt */
+} dmacHw_INT_STATUS_t;
+
+/* Data type for interrupt mask registers*/
+typedef struct {
+ dmacHw_REG64_t MaskTfr; /* Mask for IntTfr Interrupt */
+ dmacHw_REG64_t MaskBlock; /* Mask for IntBlock Interrupt */
+ dmacHw_REG64_t MaskSrcTran; /* Mask for IntSrcTran Interrupt */
+ dmacHw_REG64_t MaskDstTran; /* Mask for IntDstTran Interrupt */
+ dmacHw_REG64_t MaskErr; /* Mask for IntErr Interrupt */
+} dmacHw_INT_MASK_t;
+
+/* Data type for interrupt clear registers */
+typedef struct {
+ dmacHw_REG64_t ClearTfr; /* Clear for IntTfr Interrupt */
+ dmacHw_REG64_t ClearBlock; /* Clear for IntBlock Interrupt */
+ dmacHw_REG64_t ClearSrcTran; /* Clear for IntSrcTran Interrupt */
+ dmacHw_REG64_t ClearDstTran; /* Clear for IntDstTran Interrupt */
+ dmacHw_REG64_t ClearErr; /* Clear for IntErr Interrupt */
+ dmacHw_REG64_t StatusInt; /* Status for each interrupt type */
+} dmacHw_INT_CLEAR_t;
+
+/* Data type for software handshaking registers */
+typedef struct {
+ dmacHw_REG64_t ReqSrcReg; /* Source Software Transaction Request Register */
+ dmacHw_REG64_t ReqDstReg; /* Destination Software Transaction Request Register */
+ dmacHw_REG64_t SglReqSrcReg; /* Single Source Transaction Request Register */
+ dmacHw_REG64_t SglReqDstReg; /* Single Destination Transaction Request Register */
+ dmacHw_REG64_t LstSrcReg; /* Last Source Transaction Request Register */
+ dmacHw_REG64_t LstDstReg; /* Last Destination Transaction Request Register */
+} dmacHw_SW_HANDSHAKE_t;
+
+/* Data type for misc. registers */
+typedef struct {
+ dmacHw_REG64_t DmaCfgReg; /* DMA Configuration Register */
+ dmacHw_REG64_t ChEnReg; /* DMA Channel Enable Register */
+ dmacHw_REG64_t DmaIdReg; /* DMA ID Register */
+ dmacHw_REG64_t DmaTestReg; /* DMA Test Register */
+ dmacHw_REG64_t Reserved0; /* Reserved */
+ dmacHw_REG64_t Reserved1; /* Reserved */
+ dmacHw_REG64_t CompParm6; /* Component Parameter 6 */
+ dmacHw_REG64_t CompParm5; /* Component Parameter 5 */
+ dmacHw_REG64_t CompParm4; /* Component Parameter 4 */
+ dmacHw_REG64_t CompParm3; /* Component Parameter 3 */
+ dmacHw_REG64_t CompParm2; /* Component Parameter 2 */
+ dmacHw_REG64_t CompParm1; /* Component Parameter 1 */
+ dmacHw_REG64_t CompId; /* Compoent ID */
+} dmacHw_MISC_t;
+
+/* Base registers */
+#define dmacHw_0_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA0 /* DMAC 0 module's base address */
+#define dmacHw_1_MODULE_BASE_ADDR (char *) MM_IO_BASE_DMA1 /* DMAC 1 module's base address */
+
+extern uint32_t dmaChannelCount_0;
+extern uint32_t dmaChannelCount_1;
+
+/* Define channel specific registers */
+#define dmacHw_CHAN_BASE(module, chan) ((dmacHw_CH_REG_t *) ((char *)((module) ? dmacHw_1_MODULE_BASE_ADDR : dmacHw_0_MODULE_BASE_ADDR) + ((chan) * sizeof(dmacHw_CH_REG_t))))
+
+/* Raw interrupt status registers */
+#define dmacHw_REG_INT_RAW_BASE(module) ((char *)dmacHw_CHAN_BASE((module), ((module) ? dmaChannelCount_1 : dmaChannelCount_0)))
+#define dmacHw_REG_INT_RAW_TRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawTfr.lo)
+#define dmacHw_REG_INT_RAW_BLOCK(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawBlock.lo)
+#define dmacHw_REG_INT_RAW_STRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawSrcTran.lo)
+#define dmacHw_REG_INT_RAW_DTRAN(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawDstTran.lo)
+#define dmacHw_REG_INT_RAW_ERROR(module) (((dmacHw_INT_RAW_t *) dmacHw_REG_INT_RAW_BASE((module)))->RawErr.lo)
+
+/* Interrupt status registers */
+#define dmacHw_REG_INT_STAT_BASE(module) ((char *)(dmacHw_REG_INT_RAW_BASE((module)) + sizeof(dmacHw_INT_RAW_t)))
+#define dmacHw_REG_INT_STAT_TRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusTfr.lo)
+#define dmacHw_REG_INT_STAT_BLOCK(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusBlock.lo)
+#define dmacHw_REG_INT_STAT_STRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusSrcTran.lo)
+#define dmacHw_REG_INT_STAT_DTRAN(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusDstTran.lo)
+#define dmacHw_REG_INT_STAT_ERROR(module) (((dmacHw_INT_STATUS_t *) dmacHw_REG_INT_STAT_BASE((module)))->StatusErr.lo)
+
+/* Interrupt status registers */
+#define dmacHw_REG_INT_MASK_BASE(module) ((char *)(dmacHw_REG_INT_STAT_BASE((module)) + sizeof(dmacHw_INT_STATUS_t)))
+#define dmacHw_REG_INT_MASK_TRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskTfr.lo)
+#define dmacHw_REG_INT_MASK_BLOCK(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskBlock.lo)
+#define dmacHw_REG_INT_MASK_STRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskSrcTran.lo)
+#define dmacHw_REG_INT_MASK_DTRAN(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskDstTran.lo)
+#define dmacHw_REG_INT_MASK_ERROR(module) (((dmacHw_INT_MASK_t *) dmacHw_REG_INT_MASK_BASE((module)))->MaskErr.lo)
+
+/* Interrupt clear registers */
+#define dmacHw_REG_INT_CLEAR_BASE(module) ((char *)(dmacHw_REG_INT_MASK_BASE((module)) + sizeof(dmacHw_INT_MASK_t)))
+#define dmacHw_REG_INT_CLEAR_TRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearTfr.lo)
+#define dmacHw_REG_INT_CLEAR_BLOCK(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearBlock.lo)
+#define dmacHw_REG_INT_CLEAR_STRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearSrcTran.lo)
+#define dmacHw_REG_INT_CLEAR_DTRAN(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearDstTran.lo)
+#define dmacHw_REG_INT_CLEAR_ERROR(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->ClearErr.lo)
+#define dmacHw_REG_INT_STATUS(module) (((dmacHw_INT_CLEAR_t *) dmacHw_REG_INT_CLEAR_BASE((module)))->StatusInt.lo)
+
+/* Software handshaking registers */
+#define dmacHw_REG_SW_HS_BASE(module) ((char *)(dmacHw_REG_INT_CLEAR_BASE((module)) + sizeof(dmacHw_INT_CLEAR_t)))
+#define dmacHw_REG_SW_HS_SRC_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->ReqDstReg.lo)
+#define dmacHw_REG_SW_HS_SRC_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_SGL_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->SglReqDstReg.lo)
+#define dmacHw_REG_SW_HS_SRC_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstSrcReg.lo)
+#define dmacHw_REG_SW_HS_DST_LST_REQ(module) (((dmacHw_SW_HANDSHAKE_t *) dmacHw_REG_SW_HS_BASE((module)))->LstDstReg.lo)
+
+/* Miscellaneous registers */
+#define dmacHw_REG_MISC_BASE(module) ((char *)(dmacHw_REG_SW_HS_BASE((module)) + sizeof(dmacHw_SW_HANDSHAKE_t)))
+#define dmacHw_REG_MISC_CFG(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaCfgReg.lo)
+#define dmacHw_REG_MISC_CH_ENABLE(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->ChEnReg.lo)
+#define dmacHw_REG_MISC_ID(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaIdReg.lo)
+#define dmacHw_REG_MISC_TEST(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->DmaTestReg.lo)
+#define dmacHw_REG_MISC_COMP_PARAM1_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.lo)
+#define dmacHw_REG_MISC_COMP_PARAM1_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm1.hi)
+#define dmacHw_REG_MISC_COMP_PARAM2_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.lo)
+#define dmacHw_REG_MISC_COMP_PARAM2_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm2.hi)
+#define dmacHw_REG_MISC_COMP_PARAM3_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.lo)
+#define dmacHw_REG_MISC_COMP_PARAM3_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm3.hi)
+#define dmacHw_REG_MISC_COMP_PARAM4_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.lo)
+#define dmacHw_REG_MISC_COMP_PARAM4_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm4.hi)
+#define dmacHw_REG_MISC_COMP_PARAM5_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.lo)
+#define dmacHw_REG_MISC_COMP_PARAM5_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm5.hi)
+#define dmacHw_REG_MISC_COMP_PARAM6_LO(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.lo)
+#define dmacHw_REG_MISC_COMP_PARAM6_HI(module) (((dmacHw_MISC_t *) dmacHw_REG_MISC_BASE((module)))->CompParm6.hi)
+
+/* Channel control registers */
+#define dmacHw_REG_SAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSar.lo)
+#define dmacHw_REG_DAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDar.lo)
+#define dmacHw_REG_LLP(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelLlp.lo)
+
+#define dmacHw_REG_CTL_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.lo)
+#define dmacHw_REG_CTL_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelCtl.hi)
+
+#define dmacHw_REG_SSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstat.lo)
+#define dmacHw_REG_DSTAT(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstat.lo)
+#define dmacHw_REG_SSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelSstatAddr.lo)
+#define dmacHw_REG_DSTATAR(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelDstatAddr.lo)
+
+#define dmacHw_REG_CFG_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.lo)
+#define dmacHw_REG_CFG_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->ChannelConfig.hi)
+
+#define dmacHw_REG_SGR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.lo)
+#define dmacHw_REG_SGR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->SrcGather.hi)
+
+#define dmacHw_REG_DSR_LO(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.lo)
+#define dmacHw_REG_DSR_HI(module, chan) (dmacHw_CHAN_BASE((module), (chan))->DstScatter.hi)
+
+#define INT_STATUS_MASK(channel) (0x00000001 << (channel))
+#define CHANNEL_BUSY(mod, channel) (dmacHw_REG_MISC_CH_ENABLE((mod)) & (0x00000001 << (channel)))
+
+/* Bit mask for REG_DMACx_CTL_LO */
+
+#define dmacHw_REG_CTL_INT_EN 0x00000001 /* Channel interrupt enable */
+
+#define dmacHw_REG_CTL_DST_TR_WIDTH_MASK 0x0000000E /* Destination transaction width mask */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_SHIFT 1
+#define dmacHw_REG_CTL_DST_TR_WIDTH_8 0x00000000 /* Destination transaction width 8 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_16 0x00000002 /* Destination transaction width 16 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_32 0x00000004 /* Destination transaction width 32 bit */
+#define dmacHw_REG_CTL_DST_TR_WIDTH_64 0x00000006 /* Destination transaction width 64 bit */
+
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_MASK 0x00000070 /* Source transaction width mask */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_SHIFT 4
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_8 0x00000000 /* Source transaction width 8 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_16 0x00000010 /* Source transaction width 16 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_32 0x00000020 /* Source transaction width 32 bit */
+#define dmacHw_REG_CTL_SRC_TR_WIDTH_64 0x00000030 /* Source transaction width 64 bit */
+
+#define dmacHw_REG_CTL_DS_ENABLE 0x00040000 /* Destination scatter enable */
+#define dmacHw_REG_CTL_SG_ENABLE 0x00020000 /* Source gather enable */
+
+#define dmacHw_REG_CTL_DINC_MASK 0x00000180 /* Destination address inc/dec mask */
+#define dmacHw_REG_CTL_DINC_INC 0x00000000 /* Destination address increment */
+#define dmacHw_REG_CTL_DINC_DEC 0x00000080 /* Destination address decrement */
+#define dmacHw_REG_CTL_DINC_NC 0x00000100 /* Destination address no change */
+
+#define dmacHw_REG_CTL_SINC_MASK 0x00000600 /* Source address inc/dec mask */
+#define dmacHw_REG_CTL_SINC_INC 0x00000000 /* Source address increment */
+#define dmacHw_REG_CTL_SINC_DEC 0x00000200 /* Source address decrement */
+#define dmacHw_REG_CTL_SINC_NC 0x00000400 /* Source address no change */
+
+#define dmacHw_REG_CTL_DST_MSIZE_MASK 0x00003800 /* Destination burst transaction length */
+#define dmacHw_REG_CTL_DST_MSIZE_0 0x00000000 /* No Destination burst */
+#define dmacHw_REG_CTL_DST_MSIZE_4 0x00000800 /* Destination burst transaction length 4 */
+#define dmacHw_REG_CTL_DST_MSIZE_8 0x00001000 /* Destination burst transaction length 8 */
+#define dmacHw_REG_CTL_DST_MSIZE_16 0x00001800 /* Destination burst transaction length 16 */
+
+#define dmacHw_REG_CTL_SRC_MSIZE_MASK 0x0001C000 /* Source burst transaction length */
+#define dmacHw_REG_CTL_SRC_MSIZE_0 0x00000000 /* No Source burst */
+#define dmacHw_REG_CTL_SRC_MSIZE_4 0x00004000 /* Source burst transaction length 4 */
+#define dmacHw_REG_CTL_SRC_MSIZE_8 0x00008000 /* Source burst transaction length 8 */
+#define dmacHw_REG_CTL_SRC_MSIZE_16 0x0000C000 /* Source burst transaction length 16 */
+
+#define dmacHw_REG_CTL_TTFC_MASK 0x00700000 /* Transfer type and flow controller */
+#define dmacHw_REG_CTL_TTFC_MM_DMAC 0x00000000 /* Memory to Memory with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_MP_DMAC 0x00100000 /* Memory to Peripheral with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PM_DMAC 0x00200000 /* Peripheral to Memory with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_DMAC 0x00300000 /* Peripheral to Peripheral with DMAC as flow controller */
+#define dmacHw_REG_CTL_TTFC_PM_PERI 0x00400000 /* Peripheral to Memory with Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_SPERI 0x00500000 /* Peripheral to Peripheral with Source Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_MP_PERI 0x00600000 /* Memory to Peripheral with Peripheral as flow controller */
+#define dmacHw_REG_CTL_TTFC_PP_DPERI 0x00700000 /* Peripheral to Peripheral with Destination Peripheral as flow controller */
+
+#define dmacHw_REG_CTL_DMS_MASK 0x01800000 /* Destination AHB master interface */
+#define dmacHw_REG_CTL_DMS_1 0x00000000 /* Destination AHB master interface 1 */
+#define dmacHw_REG_CTL_DMS_2 0x00800000 /* Destination AHB master interface 2 */
+
+#define dmacHw_REG_CTL_SMS_MASK 0x06000000 /* Source AHB master interface */
+#define dmacHw_REG_CTL_SMS_1 0x00000000 /* Source AHB master interface 1 */
+#define dmacHw_REG_CTL_SMS_2 0x02000000 /* Source AHB master interface 2 */
+
+#define dmacHw_REG_CTL_LLP_DST_EN 0x08000000 /* Block chaining enable for destination side */
+#define dmacHw_REG_CTL_LLP_SRC_EN 0x10000000 /* Block chaining enable for source side */
+
+/* Bit mask for REG_DMACx_CTL_HI */
+#define dmacHw_REG_CTL_BLOCK_TS_MASK 0x00000FFF /* Block transfer size */
+#define dmacHw_REG_CTL_DONE 0x00001000 /* Block trasnfer done */
+
+/* Bit mask for REG_DMACx_CFG_LO */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_SHIFT 5 /* Channel priority shift */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_MASK 0x000000E0 /* Channel priority mask */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_0 0x00000000 /* Channel priority 0 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_1 0x00000020 /* Channel priority 1 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_2 0x00000040 /* Channel priority 2 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_3 0x00000060 /* Channel priority 3 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_4 0x00000080 /* Channel priority 4 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_5 0x000000A0 /* Channel priority 5 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_6 0x000000C0 /* Channel priority 6 */
+#define dmacHw_REG_CFG_LO_CH_PRIORITY_7 0x000000E0 /* Channel priority 7 */
+
+#define dmacHw_REG_CFG_LO_CH_SUSPEND 0x00000100 /* Channel suspend */
+#define dmacHw_REG_CFG_LO_CH_FIFO_EMPTY 0x00000200 /* Channel FIFO empty */
+#define dmacHw_REG_CFG_LO_DST_CH_SW_HS 0x00000400 /* Destination channel SW handshaking */
+#define dmacHw_REG_CFG_LO_SRC_CH_SW_HS 0x00000800 /* Source channel SW handshaking */
+
+#define dmacHw_REG_CFG_LO_CH_LOCK_MASK 0x00003000 /* Channel locking mask */
+#define dmacHw_REG_CFG_LO_CH_LOCK_DMA 0x00000000 /* Channel lock over the entire DMA transfer operation */
+#define dmacHw_REG_CFG_LO_CH_LOCK_BLOCK 0x00001000 /* Channel lock over the block transfer operation */
+#define dmacHw_REG_CFG_LO_CH_LOCK_TRANS 0x00002000 /* Channel lock over the transaction */
+#define dmacHw_REG_CFG_LO_CH_LOCK_ENABLE 0x00010000 /* Channel lock enable */
+
+#define dmacHw_REG_CFG_LO_BUS_LOCK_MASK 0x0000C000 /* Bus locking mask */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_DMA 0x00000000 /* Bus lock over the entire DMA transfer operation */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_BLOCK 0x00004000 /* Bus lock over the block transfer operation */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_TRANS 0x00008000 /* Bus lock over the transaction */
+#define dmacHw_REG_CFG_LO_BUS_LOCK_ENABLE 0x00020000 /* Bus lock enable */
+
+#define dmacHw_REG_CFG_LO_DST_HS_POLARITY_LOW 0x00040000 /* Destination channel handshaking signal polarity low */
+#define dmacHw_REG_CFG_LO_SRC_HS_POLARITY_LOW 0x00080000 /* Source channel handshaking signal polarity low */
+
+#define dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK 0x3FF00000 /* Maximum AMBA burst length */
+
+#define dmacHw_REG_CFG_LO_AUTO_RELOAD_SRC 0x40000000 /* Source address auto reload */
+#define dmacHw_REG_CFG_LO_AUTO_RELOAD_DST 0x80000000 /* Destination address auto reload */
+
+/* Bit mask for REG_DMACx_CFG_HI */
+#define dmacHw_REG_CFG_HI_FC_DST_READY 0x00000001 /* Source transaction request is serviced when destination is ready */
+#define dmacHw_REG_CFG_HI_FIFO_ENOUGH 0x00000002 /* Initiate burst transaction when enough data in available in FIFO */
+
+#define dmacHw_REG_CFG_HI_AHB_HPROT_MASK 0x0000001C /* AHB protection mask */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_1 0x00000004 /* AHB protection 1 */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_2 0x00000008 /* AHB protection 2 */
+#define dmacHw_REG_CFG_HI_AHB_HPROT_3 0x00000010 /* AHB protection 3 */
+
+#define dmacHw_REG_CFG_HI_UPDATE_DST_STAT 0x00000020 /* Destination status update enable */
+#define dmacHw_REG_CFG_HI_UPDATE_SRC_STAT 0x00000040 /* Source status update enable */
+
+#define dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK 0x00000780 /* Source peripheral hardware interface mask */
+#define dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK 0x00007800 /* Destination peripheral hardware interface mask */
+
+/* DMA Configuration Parameters */
+#define dmacHw_REG_COMP_PARAM_NUM_CHANNELS 0x00000700 /* Number of channels */
+#define dmacHw_REG_COMP_PARAM_NUM_INTERFACE 0x00001800 /* Number of master interface */
+#define dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE 0x0000000f /* Maximum brust size */
+#define dmacHw_REG_COMP_PARAM_DATA_WIDTH 0x00006000 /* Data transfer width */
+
+/* Define GET/SET macros to program the registers */
+#define dmacHw_SET_SAR(module, channel, addr) (dmacHw_REG_SAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_DAR(module, channel, addr) (dmacHw_REG_DAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_LLP(module, channel, ptr) (dmacHw_REG_LLP((module), (channel)) = (uint32_t) (ptr))
+
+#define dmacHw_GET_SSTAT(module, channel) (dmacHw_REG_SSTAT((module), (channel)))
+#define dmacHw_GET_DSTAT(module, channel) (dmacHw_REG_DSTAT((module), (channel)))
+
+#define dmacHw_SET_SSTATAR(module, channel, addr) (dmacHw_REG_SSTATAR((module), (channel)) = (uint32_t) (addr))
+#define dmacHw_SET_DSTATAR(module, channel, addr) (dmacHw_REG_DSTATAR((module), (channel)) = (uint32_t) (addr))
+
+#define dmacHw_SET_CONTROL_LO(module, channel, ctl) (dmacHw_REG_CTL_LO((module), (channel)) |= (ctl))
+#define dmacHw_RESET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel)) = 0)
+#define dmacHw_GET_CONTROL_LO(module, channel) (dmacHw_REG_CTL_LO((module), (channel)))
+
+#define dmacHw_SET_CONTROL_HI(module, channel, ctl) (dmacHw_REG_CTL_HI((module), (channel)) |= (ctl))
+#define dmacHw_RESET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) = 0)
+#define dmacHw_GET_CONTROL_HI(module, channel) (dmacHw_REG_CTL_HI((module), (channel)))
+
+#define dmacHw_GET_BLOCK_SIZE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_BLOCK_TS_MASK)
+#define dmacHw_DMA_COMPLETE(module, channel) (dmacHw_REG_CTL_HI((module), (channel)) & dmacHw_REG_CTL_DONE)
+
+#define dmacHw_SET_CONFIG_LO(module, channel, cfg) (dmacHw_REG_CFG_LO((module), (channel)) |= (cfg))
+#define dmacHw_RESET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel)) = 0)
+#define dmacHw_GET_CONFIG_LO(module, channel) (dmacHw_REG_CFG_LO((module), (channel)))
+#define dmacHw_SET_AMBA_BUSRT_LEN(module, channel, len) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK)) | (((len) << 20) & dmacHw_REG_CFG_LO_MAX_AMBA_BURST_LEN_MASK))
+#define dmacHw_SET_CHANNEL_PRIORITY(module, channel, prio) (dmacHw_REG_CFG_LO((module), (channel)) = (dmacHw_REG_CFG_LO((module), (channel)) & ~(dmacHw_REG_CFG_LO_CH_PRIORITY_MASK)) | (prio))
+#define dmacHw_SET_AHB_HPROT(module, channel, protect) (dmacHw_REG_CFG_HI(module, channel) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_AHB_HPROT_MASK)) | (protect))
+
+#define dmacHw_SET_CONFIG_HI(module, channel, cfg) (dmacHw_REG_CFG_HI((module), (channel)) |= (cfg))
+#define dmacHw_RESET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel)) = 0)
+#define dmacHw_GET_CONFIG_HI(module, channel) (dmacHw_REG_CFG_HI((module), (channel)))
+#define dmacHw_SET_SRC_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)) | (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK))
+#define dmacHw_SRC_PERI_INTF(intf) (((intf) << 7) & dmacHw_REG_CFG_HI_SRC_PERI_INTF_MASK)
+#define dmacHw_SET_DST_PERI_INTF(module, channel, intf) (dmacHw_REG_CFG_HI((module), (channel)) = (dmacHw_REG_CFG_HI((module), (channel)) & ~(dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)) | (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK))
+#define dmacHw_DST_PERI_INTF(intf) (((intf) << 11) & dmacHw_REG_CFG_HI_DST_PERI_INTF_MASK)
+
+#define dmacHw_DMA_START(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_DMA_STOP(module, channel) (dmacHw_REG_MISC_CH_ENABLE((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_DMA_ENABLE(module) (dmacHw_REG_MISC_CFG((module)) = 1)
+#define dmacHw_DMA_DISABLE(module) (dmacHw_REG_MISC_CFG((module)) = 0)
+
+#define dmacHw_TRAN_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_BLOCK_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+#define dmacHw_ERROR_INT_ENABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)) | (0x00000001 << (channel)))
+
+#define dmacHw_TRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_TRAN((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_BLOCK_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_BLOCK((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_ERROR_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_ERROR((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_STRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_STRAN((module)) = (0x00000001 << ((channel) + 8)))
+#define dmacHw_DTRAN_INT_DISABLE(module, channel) (dmacHw_REG_INT_MASK_DTRAN((module)) = (0x00000001 << ((channel) + 8)))
+
+#define dmacHw_TRAN_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_TRAN((module)) = (0x00000001 << (channel)))
+#define dmacHw_BLOCK_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_BLOCK((module)) = (0x00000001 << (channel)))
+#define dmacHw_ERROR_INT_CLEAR(module, channel) (dmacHw_REG_INT_CLEAR_ERROR((module)) = (0x00000001 << (channel)))
+
+#define dmacHw_GET_NUM_CHANNEL(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_CHANNELS) >> 8) + 1)
+#define dmacHw_GET_NUM_INTERFACE(module) (((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_NUM_INTERFACE) >> 11) + 1)
+#define dmacHw_GET_MAX_BLOCK_SIZE(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_LO((module)) >> (4 * (channel))) & dmacHw_REG_COMP_PARAM_MAX_BLK_SIZE)
+#define dmacHw_GET_CHANNEL_DATA_WIDTH(module, channel) ((dmacHw_REG_MISC_COMP_PARAM1_HI((module)) & dmacHw_REG_COMP_PARAM_DATA_WIDTH) >> 13)
+
+#endif /* _DMACHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
new file mode 100644
index 00000000..cfa91bed
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/hw_cfg.h
@@ -0,0 +1,73 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+
+#ifndef CSP_HW_CFG_H
+#define CSP_HW_CFG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <cfg_global.h>
+#include <mach/csp/cap_inline.h>
+
+#if defined(__KERNEL__)
+#include <mach/memory_settings.h>
+#else
+#include <hw_cfg.h>
+#endif
+
+/* Some items that can be defined externally, but will be set to default values */
+/* if they are not defined. */
+/* HW_CFG_PLL_SPREAD_SPECTRUM_DISABLE Default undefined and SS is enabled. */
+/* HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */
+/* HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */
+/* HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */
+/* HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */
+/* HW_CFG_SDRAM_ADDR_BRC Default undefined and Row-Bank-Col (RBC) addressing used. Define to use Bank-Row-Col (BRC). */
+/* HW_CFG_SDRAM_CLK_ASYNC Default undefined and DDR clock is synchronous with AXI BUS clock. Define for ASYNC mode. */
+
+#if defined(CFG_GLOBAL_CHIP)
+ #if (CFG_GLOBAL_CHIP == FPGA11107)
+ #define HW_CFG_BUS_CLK_HZ 5000000
+ #define HW_CFG_DDR_CTLR_CLK_HZ 10000000
+ #define HW_CFG_DDR_PHY_OMIT
+ #define HW_CFG_UART_CLK_HZ 7500000
+ #else
+ #define HW_CFG_PLL_VCO_HZ 2000000000
+ #define HW_CFG_PLL2_VCO_HZ 1800000000
+ #define HW_CFG_ARM_CLK_HZ CAP_HW_CFG_ARM_CLK_HZ
+ #define HW_CFG_BUS_CLK_HZ 166666666
+ #define HW_CFG_DDR_CTLR_CLK_HZ 333333333
+ #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ)
+ #define HW_CFG_UART_CLK_HZ 142857142
+ #define HW_CFG_VPM_CLK_HZ CAP_HW_CFG_VPM_CLK_HZ
+ #endif
+#else
+ #define HW_CFG_PLL_VCO_HZ 1800000000
+ #define HW_CFG_PLL2_VCO_HZ 1800000000
+ #define HW_CFG_ARM_CLK_HZ 450000000
+ #define HW_CFG_BUS_CLK_HZ 150000000
+ #define HW_CFG_DDR_CTLR_CLK_HZ 300000000
+ #define HW_CFG_DDR_PHY_CLK_HZ (2 * HW_CFG_DDR_CTLR_CLK_HZ)
+ #define HW_CFG_UART_CLK_HZ 150000000
+ #define HW_CFG_VPM_CLK_HZ 300000000
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+
+#endif /* CSP_HW_CFG_H */
+
diff --git a/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
new file mode 100644
index 00000000..0aeb6a6f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/intcHw_reg.h
@@ -0,0 +1,246 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file intcHw_reg.h
+*
+* @brief platform specific interrupt controller bit assignments
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef _INTCHW_REG_H
+#define _INTCHW_REG_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/stdint.h>
+#include <csp/reg.h>
+#include <mach/csp/mm_io.h>
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#define INTCHW_NUM_IRQ_PER_INTC 32 /* Maximum number of interrupt controllers */
+#define INTCHW_NUM_INTC 3
+
+/* Defines for interrupt controllers. This simplifies and cleans up the function calls. */
+#define INTCHW_INTC0 ((void *)MM_IO_BASE_INTC0)
+#define INTCHW_INTC1 ((void *)MM_IO_BASE_INTC1)
+#define INTCHW_SINTC ((void *)MM_IO_BASE_SINTC)
+
+/* INTC0 - interrupt controller 0 */
+#define INTCHW_INTC0_PIF_BITNUM 31 /* Peripheral interface interrupt */
+#define INTCHW_INTC0_CLCD_BITNUM 30 /* LCD Controller interrupt */
+#define INTCHW_INTC0_GE_BITNUM 29 /* Graphic engine interrupt */
+#define INTCHW_INTC0_APM_BITNUM 28 /* Audio process module interrupt */
+#define INTCHW_INTC0_ESW_BITNUM 27 /* Ethernet switch interrupt */
+#define INTCHW_INTC0_SPIH_BITNUM 26 /* SPI host interrupt */
+#define INTCHW_INTC0_TIMER3_BITNUM 25 /* Timer3 interrupt */
+#define INTCHW_INTC0_TIMER2_BITNUM 24 /* Timer2 interrupt */
+#define INTCHW_INTC0_TIMER1_BITNUM 23 /* Timer1 interrupt */
+#define INTCHW_INTC0_TIMER0_BITNUM 22 /* Timer0 interrupt */
+#define INTCHW_INTC0_SDIOH1_BITNUM 21 /* SDIO1 host interrupt */
+#define INTCHW_INTC0_SDIOH0_BITNUM 20 /* SDIO0 host interrupt */
+#define INTCHW_INTC0_USBD_BITNUM 19 /* USB device interrupt */
+#define INTCHW_INTC0_USBH1_BITNUM 18 /* USB1 host interrupt */
+#define INTCHW_INTC0_USBHD2_BITNUM 17 /* USB host2/device2 interrupt */
+#define INTCHW_INTC0_VPM_BITNUM 16 /* Voice process module interrupt */
+#define INTCHW_INTC0_DMA1C7_BITNUM 15 /* DMA1 channel 7 interrupt */
+#define INTCHW_INTC0_DMA1C6_BITNUM 14 /* DMA1 channel 6 interrupt */
+#define INTCHW_INTC0_DMA1C5_BITNUM 13 /* DMA1 channel 5 interrupt */
+#define INTCHW_INTC0_DMA1C4_BITNUM 12 /* DMA1 channel 4 interrupt */
+#define INTCHW_INTC0_DMA1C3_BITNUM 11 /* DMA1 channel 3 interrupt */
+#define INTCHW_INTC0_DMA1C2_BITNUM 10 /* DMA1 channel 2 interrupt */
+#define INTCHW_INTC0_DMA1C1_BITNUM 9 /* DMA1 channel 1 interrupt */
+#define INTCHW_INTC0_DMA1C0_BITNUM 8 /* DMA1 channel 0 interrupt */
+#define INTCHW_INTC0_DMA0C7_BITNUM 7 /* DMA0 channel 7 interrupt */
+#define INTCHW_INTC0_DMA0C6_BITNUM 6 /* DMA0 channel 6 interrupt */
+#define INTCHW_INTC0_DMA0C5_BITNUM 5 /* DMA0 channel 5 interrupt */
+#define INTCHW_INTC0_DMA0C4_BITNUM 4 /* DMA0 channel 4 interrupt */
+#define INTCHW_INTC0_DMA0C3_BITNUM 3 /* DMA0 channel 3 interrupt */
+#define INTCHW_INTC0_DMA0C2_BITNUM 2 /* DMA0 channel 2 interrupt */
+#define INTCHW_INTC0_DMA0C1_BITNUM 1 /* DMA0 channel 1 interrupt */
+#define INTCHW_INTC0_DMA0C0_BITNUM 0 /* DMA0 channel 0 interrupt */
+
+#define INTCHW_INTC0_PIF (1<<INTCHW_INTC0_PIF_BITNUM)
+#define INTCHW_INTC0_CLCD (1<<INTCHW_INTC0_CLCD_BITNUM)
+#define INTCHW_INTC0_GE (1<<INTCHW_INTC0_GE_BITNUM)
+#define INTCHW_INTC0_APM (1<<INTCHW_INTC0_APM_BITNUM)
+#define INTCHW_INTC0_ESW (1<<INTCHW_INTC0_ESW_BITNUM)
+#define INTCHW_INTC0_SPIH (1<<INTCHW_INTC0_SPIH_BITNUM)
+#define INTCHW_INTC0_TIMER3 (1<<INTCHW_INTC0_TIMER3_BITNUM)
+#define INTCHW_INTC0_TIMER2 (1<<INTCHW_INTC0_TIMER2_BITNUM)
+#define INTCHW_INTC0_TIMER1 (1<<INTCHW_INTC0_TIMER1_BITNUM)
+#define INTCHW_INTC0_TIMER0 (1<<INTCHW_INTC0_TIMER0_BITNUM)
+#define INTCHW_INTC0_SDIOH1 (1<<INTCHW_INTC0_SDIOH1_BITNUM)
+#define INTCHW_INTC0_SDIOH0 (1<<INTCHW_INTC0_SDIOH0_BITNUM)
+#define INTCHW_INTC0_USBD (1<<INTCHW_INTC0_USBD_BITNUM)
+#define INTCHW_INTC0_USBH1 (1<<INTCHW_INTC0_USBH1_BITNUM)
+#define INTCHW_INTC0_USBHD2 (1<<INTCHW_INTC0_USBHD2_BITNUM)
+#define INTCHW_INTC0_VPM (1<<INTCHW_INTC0_VPM_BITNUM)
+#define INTCHW_INTC0_DMA1C7 (1<<INTCHW_INTC0_DMA1C7_BITNUM)
+#define INTCHW_INTC0_DMA1C6 (1<<INTCHW_INTC0_DMA1C6_BITNUM)
+#define INTCHW_INTC0_DMA1C5 (1<<INTCHW_INTC0_DMA1C5_BITNUM)
+#define INTCHW_INTC0_DMA1C4 (1<<INTCHW_INTC0_DMA1C4_BITNUM)
+#define INTCHW_INTC0_DMA1C3 (1<<INTCHW_INTC0_DMA1C3_BITNUM)
+#define INTCHW_INTC0_DMA1C2 (1<<INTCHW_INTC0_DMA1C2_BITNUM)
+#define INTCHW_INTC0_DMA1C1 (1<<INTCHW_INTC0_DMA1C1_BITNUM)
+#define INTCHW_INTC0_DMA1C0 (1<<INTCHW_INTC0_DMA1C0_BITNUM)
+#define INTCHW_INTC0_DMA0C7 (1<<INTCHW_INTC0_DMA0C7_BITNUM)
+#define INTCHW_INTC0_DMA0C6 (1<<INTCHW_INTC0_DMA0C6_BITNUM)
+#define INTCHW_INTC0_DMA0C5 (1<<INTCHW_INTC0_DMA0C5_BITNUM)
+#define INTCHW_INTC0_DMA0C4 (1<<INTCHW_INTC0_DMA0C4_BITNUM)
+#define INTCHW_INTC0_DMA0C3 (1<<INTCHW_INTC0_DMA0C3_BITNUM)
+#define INTCHW_INTC0_DMA0C2 (1<<INTCHW_INTC0_DMA0C2_BITNUM)
+#define INTCHW_INTC0_DMA0C1 (1<<INTCHW_INTC0_DMA0C1_BITNUM)
+#define INTCHW_INTC0_DMA0C0 (1<<INTCHW_INTC0_DMA0C0_BITNUM)
+
+/* INTC1 - interrupt controller 1 */
+#define INTCHW_INTC1_DDRVPMP_BITNUM 27 /* DDR and VPM PLL clock phase relationship interrupt (Not for A0) */
+#define INTCHW_INTC1_DDRVPMT_BITNUM 26 /* DDR and VPM HW phase align timeout interrupt (Not for A0) */
+#define INTCHW_INTC1_DDRP_BITNUM 26 /* DDR and PLL clock phase relationship interrupt (For A0 only)) */
+#define INTCHW_INTC1_RTC2_BITNUM 25 /* Real time clock tamper interrupt */
+#define INTCHW_INTC1_VDEC_BITNUM 24 /* Hantro Video Decoder interrupt */
+/* Bits 13-23 are non-secure versions of the corresponding secure bits in SINTC bits 0-10. */
+#define INTCHW_INTC1_SPUM_BITNUM 23 /* Secure process module interrupt */
+#define INTCHW_INTC1_RTC1_BITNUM 22 /* Real time clock one-shot interrupt */
+#define INTCHW_INTC1_RTC0_BITNUM 21 /* Real time clock periodic interrupt */
+#define INTCHW_INTC1_RNG_BITNUM 20 /* Random number generator interrupt */
+#define INTCHW_INTC1_FMPU_BITNUM 19 /* Flash memory parition unit interrupt */
+#define INTCHW_INTC1_VMPU_BITNUM 18 /* VRAM memory partition interrupt */
+#define INTCHW_INTC1_DMPU_BITNUM 17 /* DDR2 memory partition interrupt */
+#define INTCHW_INTC1_KEYC_BITNUM 16 /* Key pad controller interrupt */
+#define INTCHW_INTC1_TSC_BITNUM 15 /* Touch screen controller interrupt */
+#define INTCHW_INTC1_UART0_BITNUM 14 /* UART 0 */
+#define INTCHW_INTC1_WDOG_BITNUM 13 /* Watchdog timer interrupt */
+
+#define INTCHW_INTC1_UART1_BITNUM 12 /* UART 1 */
+#define INTCHW_INTC1_PMUIRQ_BITNUM 11 /* ARM performance monitor interrupt */
+#define INTCHW_INTC1_COMMRX_BITNUM 10 /* ARM DDC receive interrupt */
+#define INTCHW_INTC1_COMMTX_BITNUM 9 /* ARM DDC transmit interrupt */
+#define INTCHW_INTC1_FLASHC_BITNUM 8 /* Flash controller interrupt */
+#define INTCHW_INTC1_GPHY_BITNUM 7 /* Gigabit Phy interrupt */
+#define INTCHW_INTC1_SPIS_BITNUM 6 /* SPI slave interrupt */
+#define INTCHW_INTC1_I2CS_BITNUM 5 /* I2C slave interrupt */
+#define INTCHW_INTC1_I2CH_BITNUM 4 /* I2C host interrupt */
+#define INTCHW_INTC1_I2S1_BITNUM 3 /* I2S1 interrupt */
+#define INTCHW_INTC1_I2S0_BITNUM 2 /* I2S0 interrupt */
+#define INTCHW_INTC1_GPIO1_BITNUM 1 /* GPIO bit 64//32 combined interrupt */
+#define INTCHW_INTC1_GPIO0_BITNUM 0 /* GPIO bit 31//0 combined interrupt */
+
+#define INTCHW_INTC1_DDRVPMT (1<<INTCHW_INTC1_DDRVPMT_BITNUM)
+#define INTCHW_INTC1_DDRVPMP (1<<INTCHW_INTC1_DDRVPMP_BITNUM)
+#define INTCHW_INTC1_DDRP (1<<INTCHW_INTC1_DDRP_BITNUM)
+#define INTCHW_INTC1_VDEC (1<<INTCHW_INTC1_VDEC_BITNUM)
+#define INTCHW_INTC1_SPUM (1<<INTCHW_INTC1_SPUM_BITNUM)
+#define INTCHW_INTC1_RTC2 (1<<INTCHW_INTC1_RTC2_BITNUM)
+#define INTCHW_INTC1_RTC1 (1<<INTCHW_INTC1_RTC1_BITNUM)
+#define INTCHW_INTC1_RTC0 (1<<INTCHW_INTC1_RTC0_BITNUM)
+#define INTCHW_INTC1_RNG (1<<INTCHW_INTC1_RNG_BITNUM)
+#define INTCHW_INTC1_FMPU (1<<INTCHW_INTC1_FMPU_BITNUM)
+#define INTCHW_INTC1_IMPU (1<<INTCHW_INTC1_IMPU_BITNUM)
+#define INTCHW_INTC1_DMPU (1<<INTCHW_INTC1_DMPU_BITNUM)
+#define INTCHW_INTC1_KEYC (1<<INTCHW_INTC1_KEYC_BITNUM)
+#define INTCHW_INTC1_TSC (1<<INTCHW_INTC1_TSC_BITNUM)
+#define INTCHW_INTC1_UART0 (1<<INTCHW_INTC1_UART0_BITNUM)
+#define INTCHW_INTC1_WDOG (1<<INTCHW_INTC1_WDOG_BITNUM)
+#define INTCHW_INTC1_UART1 (1<<INTCHW_INTC1_UART1_BITNUM)
+#define INTCHW_INTC1_PMUIRQ (1<<INTCHW_INTC1_PMUIRQ_BITNUM)
+#define INTCHW_INTC1_COMMRX (1<<INTCHW_INTC1_COMMRX_BITNUM)
+#define INTCHW_INTC1_COMMTX (1<<INTCHW_INTC1_COMMTX_BITNUM)
+#define INTCHW_INTC1_FLASHC (1<<INTCHW_INTC1_FLASHC_BITNUM)
+#define INTCHW_INTC1_GPHY (1<<INTCHW_INTC1_GPHY_BITNUM)
+#define INTCHW_INTC1_SPIS (1<<INTCHW_INTC1_SPIS_BITNUM)
+#define INTCHW_INTC1_I2CS (1<<INTCHW_INTC1_I2CS_BITNUM)
+#define INTCHW_INTC1_I2CH (1<<INTCHW_INTC1_I2CH_BITNUM)
+#define INTCHW_INTC1_I2S1 (1<<INTCHW_INTC1_I2S1_BITNUM)
+#define INTCHW_INTC1_I2S0 (1<<INTCHW_INTC1_I2S0_BITNUM)
+#define INTCHW_INTC1_GPIO1 (1<<INTCHW_INTC1_GPIO1_BITNUM)
+#define INTCHW_INTC1_GPIO0 (1<<INTCHW_INTC1_GPIO0_BITNUM)
+
+/* SINTC secure int controller */
+#define INTCHW_SINTC_RTC2_BITNUM 15 /* Real time clock tamper interrupt */
+#define INTCHW_SINTC_TIMER3_BITNUM 14 /* Secure timer3 interrupt */
+#define INTCHW_SINTC_TIMER2_BITNUM 13 /* Secure timer2 interrupt */
+#define INTCHW_SINTC_TIMER1_BITNUM 12 /* Secure timer1 interrupt */
+#define INTCHW_SINTC_TIMER0_BITNUM 11 /* Secure timer0 interrupt */
+#define INTCHW_SINTC_SPUM_BITNUM 10 /* Secure process module interrupt */
+#define INTCHW_SINTC_RTC1_BITNUM 9 /* Real time clock one-shot interrupt */
+#define INTCHW_SINTC_RTC0_BITNUM 8 /* Real time clock periodic interrupt */
+#define INTCHW_SINTC_RNG_BITNUM 7 /* Random number generator interrupt */
+#define INTCHW_SINTC_FMPU_BITNUM 6 /* Flash memory parition unit interrupt */
+#define INTCHW_SINTC_VMPU_BITNUM 5 /* VRAM memory partition interrupt */
+#define INTCHW_SINTC_DMPU_BITNUM 4 /* DDR2 memory partition interrupt */
+#define INTCHW_SINTC_KEYC_BITNUM 3 /* Key pad controller interrupt */
+#define INTCHW_SINTC_TSC_BITNUM 2 /* Touch screen controller interrupt */
+#define INTCHW_SINTC_UART0_BITNUM 1 /* UART0 interrupt */
+#define INTCHW_SINTC_WDOG_BITNUM 0 /* Watchdog timer interrupt */
+
+#define INTCHW_SINTC_TIMER3 (1<<INTCHW_SINTC_TIMER3_BITNUM)
+#define INTCHW_SINTC_TIMER2 (1<<INTCHW_SINTC_TIMER2_BITNUM)
+#define INTCHW_SINTC_TIMER1 (1<<INTCHW_SINTC_TIMER1_BITNUM)
+#define INTCHW_SINTC_TIMER0 (1<<INTCHW_SINTC_TIMER0_BITNUM)
+#define INTCHW_SINTC_SPUM (1<<INTCHW_SINTC_SPUM_BITNUM)
+#define INTCHW_SINTC_RTC2 (1<<INTCHW_SINTC_RTC2_BITNUM)
+#define INTCHW_SINTC_RTC1 (1<<INTCHW_SINTC_RTC1_BITNUM)
+#define INTCHW_SINTC_RTC0 (1<<INTCHW_SINTC_RTC0_BITNUM)
+#define INTCHW_SINTC_RNG (1<<INTCHW_SINTC_RNG_BITNUM)
+#define INTCHW_SINTC_FMPU (1<<INTCHW_SINTC_FMPU_BITNUM)
+#define INTCHW_SINTC_IMPU (1<<INTCHW_SINTC_IMPU_BITNUM)
+#define INTCHW_SINTC_DMPU (1<<INTCHW_SINTC_DMPU_BITNUM)
+#define INTCHW_SINTC_KEYC (1<<INTCHW_SINTC_KEYC_BITNUM)
+#define INTCHW_SINTC_TSC (1<<INTCHW_SINTC_TSC_BITNUM)
+#define INTCHW_SINTC_UART0 (1<<INTCHW_SINTC_UART0_BITNUM)
+#define INTCHW_SINTC_WDOG (1<<INTCHW_SINTC_WDOG_BITNUM)
+
+/* PL192 Vectored Interrupt Controller (VIC) layout */
+#define INTCHW_IRQSTATUS 0x00 /* IRQ status register */
+#define INTCHW_FIQSTATUS 0x04 /* FIQ status register */
+#define INTCHW_RAWINTR 0x08 /* Raw Interrupt Status register */
+#define INTCHW_INTSELECT 0x0c /* Interrupt Select Register */
+#define INTCHW_INTENABLE 0x10 /* Interrupt Enable Register */
+#define INTCHW_INTENCLEAR 0x14 /* Interrupt Enable Clear Register */
+#define INTCHW_SOFTINT 0x18 /* Soft Interrupt Register */
+#define INTCHW_SOFTINTCLEAR 0x1c /* Soft Interrupt Clear Register */
+#define INTCHW_PROTECTION 0x20 /* Protection Enable Register */
+#define INTCHW_SWPRIOMASK 0x24 /* Software Priority Mask Register */
+#define INTCHW_PRIODAISY 0x28 /* Priority Daisy Chain Register */
+#define INTCHW_VECTADDR0 0x100 /* Vector Address Registers */
+#define INTCHW_VECTPRIO0 0x200 /* Vector Priority Registers 0-31 */
+#define INTCHW_ADDRESS 0xf00 /* Vector Address Register 0-31 */
+#define INTCHW_PID 0xfe0 /* Peripheral ID Register 0-3 */
+#define INTCHW_PCELLID 0xff0 /* PrimeCell ID Register 0-3 */
+
+/* Example Usage: intcHw_irq_enable(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
+/* intcHw_irq_clear(INTCHW_INTC0, INTCHW_INTC0_TIMER0); */
+/* uint32_t bits = intcHw_irq_status(INTCHW_INTC0); */
+/* uint32_t bits = intcHw_irq_raw_status(INTCHW_INTC0); */
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+/* Clear one or more IRQ interrupts. */
+static inline void intcHw_irq_disable(void *basep, uint32_t mask)
+{
+ __REG32(basep + INTCHW_INTENCLEAR) = mask;
+}
+
+/* Enables one or more IRQ interrupts. */
+static inline void intcHw_irq_enable(void *basep, uint32_t mask)
+{
+ __REG32(basep + INTCHW_INTENABLE) = mask;
+}
+
+#endif /* _INTCHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
new file mode 100644
index 00000000..ad58cf87
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_addr.h
@@ -0,0 +1,101 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file mm_addr.h
+*
+* @brief Memory Map address definitions
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef _MM_ADDR_H
+#define _MM_ADDR_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#if !defined(CSP_SIMULATION)
+#include <cfg_global.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+/* Memory Map address definitions */
+
+#define MM_ADDR_DDR 0x00000000
+
+#define MM_ADDR_IO_VPM_EXTMEM_RSVD 0x0F000000 /* 16 MB - Reserved external memory for VPM use */
+
+#define MM_ADDR_IO_FLASHC 0x20000000
+#define MM_ADDR_IO_BROM 0x30000000
+#define MM_ADDR_IO_ARAM 0x30100000 /* 64 KB - extra cycle latency - WS switch */
+#define MM_ADDR_IO_DMA0 0x30200000
+#define MM_ADDR_IO_DMA1 0x30300000
+#define MM_ADDR_IO_ESW 0x30400000
+#define MM_ADDR_IO_CLCD 0x30500000
+#define MM_ADDR_IO_PIF 0x30580000
+#define MM_ADDR_IO_APM 0x30600000
+#define MM_ADDR_IO_SPUM 0x30700000
+#define MM_ADDR_IO_VPM_PROG 0x30800000
+#define MM_ADDR_IO_VPM_DATA 0x30A00000
+#define MM_ADDR_IO_VRAM 0x40000000 /* 64 KB - security block in front of it */
+#define MM_ADDR_IO_CHIPC 0x80000000
+#define MM_ADDR_IO_UMI 0x80001000
+#define MM_ADDR_IO_NAND 0x80001800
+#define MM_ADDR_IO_LEDM 0x80002000
+#define MM_ADDR_IO_PWM 0x80002040
+#define MM_ADDR_IO_VINTC 0x80003000
+#define MM_ADDR_IO_GPIO0 0x80004000
+#define MM_ADDR_IO_GPIO1 0x80004800
+#define MM_ADDR_IO_I2CS 0x80005000
+#define MM_ADDR_IO_SPIS 0x80006000
+#define MM_ADDR_IO_HPM 0x80007400
+#define MM_ADDR_IO_HPM_REMAP 0x80007800
+#define MM_ADDR_IO_TZPC 0x80008000
+#define MM_ADDR_IO_MPU 0x80009000
+#define MM_ADDR_IO_SPUMP 0x8000a000
+#define MM_ADDR_IO_PKA 0x8000b000
+#define MM_ADDR_IO_RNG 0x8000c000
+#define MM_ADDR_IO_KEYC 0x8000d000
+#define MM_ADDR_IO_BBL 0x8000e000
+#define MM_ADDR_IO_OTP 0x8000f000
+#define MM_ADDR_IO_I2S0 0x80010000
+#define MM_ADDR_IO_I2S1 0x80011000
+#define MM_ADDR_IO_UARTA 0x80012000
+#define MM_ADDR_IO_UARTB 0x80013000
+#define MM_ADDR_IO_I2CH 0x80014020
+#define MM_ADDR_IO_SPIH 0x80015000
+#define MM_ADDR_IO_TSC 0x80016000
+#define MM_ADDR_IO_TMR 0x80017000
+#define MM_ADDR_IO_WATCHDOG 0x80017800
+#define MM_ADDR_IO_ETM 0x80018000
+#define MM_ADDR_IO_DDRC 0x80019000
+#define MM_ADDR_IO_SINTC 0x80100000
+#define MM_ADDR_IO_INTC0 0x80200000
+#define MM_ADDR_IO_INTC1 0x80201000
+#define MM_ADDR_IO_GE 0x80300000
+#define MM_ADDR_IO_USB_CTLR0 0x80400000
+#define MM_ADDR_IO_USB_CTLR1 0x80410000
+#define MM_ADDR_IO_USB_PHY 0x80420000
+#define MM_ADDR_IO_SDIOH0 0x80500000
+#define MM_ADDR_IO_SDIOH1 0x80600000
+#define MM_ADDR_IO_VDEC 0x80700000
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* _MM_ADDR_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/mm_io.h b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
new file mode 100644
index 00000000..de92ec6a
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/mm_io.h
@@ -0,0 +1,147 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file mm_io.h
+*
+* @brief Memory Map I/O definitions
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef _MM_IO_H
+#define _MM_IO_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <mach/csp/mm_addr.h>
+
+#if !defined(CSP_SIMULATION)
+#include <cfg_global.h>
+#endif
+
+/* ---- Public Constants and Types --------------------------------------- */
+
+#if defined(CONFIG_MMU)
+
+/* This macro is referenced in <mach/io.h>
+ * Phys to Virtual 0xNyxxxxxx => 0xFNxxxxxx
+ * This macro is referenced in <asm/arch/io.h>
+ *
+ * Assume VPM address is the last x MB of memory. For VPM, map to
+ * 0xf0000000 and up.
+ */
+
+#ifndef MM_IO_PHYS_TO_VIRT
+#ifdef __ASSEMBLY__
+#define MM_IO_PHYS_TO_VIRT(phys) (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF))
+#else
+#define MM_IO_PHYS_TO_VIRT(phys) (((phys) == MM_ADDR_IO_VPM_EXTMEM_RSVD) ? 0xF0000000 : \
+ (0xF0000000 | (((phys) >> 4) & 0x0F000000) | ((phys) & 0xFFFFFF)))
+#endif
+#endif
+
+/* Virtual to Physical 0xFNxxxxxx => 0xN0xxxxxx */
+
+#ifndef MM_IO_VIRT_TO_PHYS
+#ifdef __ASSEMBLY__
+#define MM_IO_VIRT_TO_PHYS(virt) ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF))
+#else
+#define MM_IO_VIRT_TO_PHYS(virt) (((virt) == 0xF0000000) ? MM_ADDR_IO_VPM_EXTMEM_RSVD : \
+ ((((virt) & 0x0F000000) << 4) | ((virt) & 0xFFFFFF)))
+#endif
+#endif
+
+#else
+
+#ifndef MM_IO_PHYS_TO_VIRT
+#define MM_IO_PHYS_TO_VIRT(phys) (phys)
+#endif
+
+#ifndef MM_IO_VIRT_TO_PHYS
+#define MM_IO_VIRT_TO_PHYS(virt) (virt)
+#endif
+
+#endif
+
+/* Registers in 0xExxxxxxx that should be moved to 0xFxxxxxxx */
+#define MM_IO_BASE_FLASHC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_FLASHC)
+#define MM_IO_BASE_NAND MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_NAND)
+#define MM_IO_BASE_UMI MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UMI)
+
+#define MM_IO_START MM_ADDR_IO_FLASHC /* Physical beginning of IO mapped memory */
+#define MM_IO_BASE MM_IO_BASE_FLASHC /* Virtual beginning of IO mapped memory */
+
+#define MM_IO_BASE_BROM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BROM)
+#define MM_IO_BASE_ARAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ARAM)
+#define MM_IO_BASE_DMA0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA0)
+#define MM_IO_BASE_DMA1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DMA1)
+#define MM_IO_BASE_ESW MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ESW)
+#define MM_IO_BASE_CLCD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CLCD)
+#define MM_IO_BASE_PIF MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PIF)
+#define MM_IO_BASE_APM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_APM)
+#define MM_IO_BASE_SPUM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUM)
+#define MM_IO_BASE_VPM_PROG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_PROG)
+#define MM_IO_BASE_VPM_DATA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_DATA)
+
+#define MM_IO_BASE_VRAM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VRAM)
+
+#define MM_IO_BASE_CHIPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_CHIPC)
+#define MM_IO_BASE_DDRC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_DDRC)
+#define MM_IO_BASE_LEDM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_LEDM)
+#define MM_IO_BASE_PWM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PWM)
+#define MM_IO_BASE_VINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VINTC)
+#define MM_IO_BASE_GPIO0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO0)
+#define MM_IO_BASE_GPIO1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GPIO1)
+#define MM_IO_BASE_TMR MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TMR)
+#define MM_IO_BASE_WATCHDOG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_WATCHDOG)
+#define MM_IO_BASE_ETM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_ETM)
+#define MM_IO_BASE_HPM MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM)
+#define MM_IO_BASE_HPM_REMAP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_HPM_REMAP)
+#define MM_IO_BASE_TZPC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TZPC)
+#define MM_IO_BASE_MPU MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_MPU)
+#define MM_IO_BASE_SPUMP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPUMP)
+#define MM_IO_BASE_PKA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_PKA)
+#define MM_IO_BASE_RNG MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_RNG)
+#define MM_IO_BASE_KEYC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_KEYC)
+#define MM_IO_BASE_BBL MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_BBL)
+#define MM_IO_BASE_OTP MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_OTP)
+#define MM_IO_BASE_I2S0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S0)
+#define MM_IO_BASE_I2S1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2S1)
+#define MM_IO_BASE_UARTA MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTA)
+#define MM_IO_BASE_UARTB MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_UARTB)
+#define MM_IO_BASE_I2CH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CH)
+#define MM_IO_BASE_SPIH MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIH)
+#define MM_IO_BASE_TSC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_TSC)
+#define MM_IO_BASE_I2CS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_I2CS)
+#define MM_IO_BASE_SPIS MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SPIS)
+#define MM_IO_BASE_SINTC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SINTC)
+#define MM_IO_BASE_INTC0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC0)
+#define MM_IO_BASE_INTC1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_INTC1)
+#define MM_IO_BASE_GE MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_GE)
+#define MM_IO_BASE_USB_CTLR0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR0)
+#define MM_IO_BASE_USB_CTLR1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_CTLR1)
+#define MM_IO_BASE_USB_PHY MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_USB_PHY)
+#define MM_IO_BASE_SDIOH0 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH0)
+#define MM_IO_BASE_SDIOH1 MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_SDIOH1)
+#define MM_IO_BASE_VDEC MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VDEC)
+
+#define MM_IO_BASE_VPM_EXTMEM_RSVD MM_IO_PHYS_TO_VIRT(MM_ADDR_IO_VPM_EXTMEM_RSVD)
+
+/* ---- Public Variable Externs ------------------------------------------ */
+/* ---- Public Function Prototypes --------------------------------------- */
+
+#endif /* _MM_IO_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
new file mode 100644
index 00000000..d15f5f3e
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_def.h
@@ -0,0 +1,100 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file secHw_def.h
+*
+* @brief Definitions for configuring/testing secure blocks
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef SECHW_DEF_H
+#define SECHW_DEF_H
+
+#include <mach/csp/mm_io.h>
+
+/* Bit mask for various secure device */
+#define secHw_BLK_MASK_CHIP_CONTROL 0x00000001
+#define secHw_BLK_MASK_KEY_SCAN 0x00000002
+#define secHw_BLK_MASK_TOUCH_SCREEN 0x00000004
+#define secHw_BLK_MASK_UART0 0x00000008
+#define secHw_BLK_MASK_UART1 0x00000010
+#define secHw_BLK_MASK_WATCHDOG 0x00000020
+#define secHw_BLK_MASK_SPUM 0x00000040
+#define secHw_BLK_MASK_DDR2 0x00000080
+#define secHw_BLK_MASK_EXT_MEM 0x00000100
+#define secHw_BLK_MASK_ESW 0x00000200
+#define secHw_BLK_MASK_SPU 0x00010000
+#define secHw_BLK_MASK_PKA 0x00020000
+#define secHw_BLK_MASK_RNG 0x00040000
+#define secHw_BLK_MASK_RTC 0x00080000
+#define secHw_BLK_MASK_OTP 0x00100000
+#define secHw_BLK_MASK_BOOT 0x00200000
+#define secHw_BLK_MASK_MPU 0x00400000
+#define secHw_BLK_MASK_TZCTRL 0x00800000
+#define secHw_BLK_MASK_INTR 0x01000000
+
+/* Trustzone register set */
+typedef struct {
+ volatile uint32_t status; /* read only - reflects status of writes of 2 write registers */
+ volatile uint32_t setUnsecure; /* write only. reads back as 0 */
+ volatile uint32_t setSecure; /* write only. reads back as 0 */
+} secHw_TZREG_t;
+
+/* There are 2 register sets. The first is for the lower 16 bits, the 2nd */
+/* is for the higher 16 bits. */
+
+typedef enum {
+ secHw_IDX_LS = 0,
+ secHw_IDX_MS = 1,
+ secHw_IDX_NUM
+} secHw_IDX_e;
+
+typedef struct {
+ volatile secHw_TZREG_t reg[secHw_IDX_NUM];
+} secHw_REGS_t;
+
+/****************************************************************************/
+/**
+* @brief Configures a device as a secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Configures a device as a non-secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
+ );
+
+/****************************************************************************/
+/**
+* @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure
+*
+*/
+/****************************************************************************/
+static inline uint32_t secHw_getStatus(void);
+
+#include <mach/csp/secHw_inline.h>
+
+#endif /* SECHW_DEF_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
new file mode 100644
index 00000000..9cd6a032
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/secHw_inline.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file secHw_inline.h
+*
+* @brief Definitions for configuring/testing secure blocks
+*
+* @note
+* None
+*/
+/****************************************************************************/
+
+#ifndef SECHW_INLINE_H
+#define SECHW_INLINE_H
+
+/****************************************************************************/
+/**
+* @brief Configures a device as a secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setSecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
+ ) {
+ secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+ if (mask & 0x0000FFFF) {
+ regp->reg[secHw_IDX_LS].setSecure = mask & 0x0000FFFF;
+ }
+
+ if (mask & 0xFFFF0000) {
+ regp->reg[secHw_IDX_MS].setSecure = mask >> 16;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Configures a device as a non-secure device
+*
+*/
+/****************************************************************************/
+static inline void secHw_setUnsecure(uint32_t mask /* mask of type secHw_BLK_MASK_XXXXXX */
+ ) {
+ secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+ if (mask & 0x0000FFFF) {
+ regp->reg[secHw_IDX_LS].setUnsecure = mask & 0x0000FFFF;
+ }
+ if (mask & 0xFFFF0000) {
+ regp->reg[secHw_IDX_MS].setUnsecure = mask >> 16;
+ }
+}
+
+/****************************************************************************/
+/**
+* @brief Get the trustzone status for all components. 1 = non-secure, 0 = secure
+*
+*/
+/****************************************************************************/
+static inline uint32_t secHw_getStatus(void)
+{
+ secHw_REGS_t *regp = (secHw_REGS_t *) MM_IO_BASE_TZPC;
+
+ return (regp->reg[1].status << 16) + regp->reg[0].status;
+}
+
+#endif /* SECHW_INLINE_H */
diff --git a/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
new file mode 100644
index 00000000..3080ac72
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/csp/tmrHw_reg.h
@@ -0,0 +1,82 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file tmrHw_reg.h
+*
+* @brief Definitions for low level Timer registers
+*
+*/
+/****************************************************************************/
+#ifndef _TMRHW_REG_H
+#define _TMRHW_REG_H
+
+#include <mach/csp/mm_io.h>
+#include <mach/csp/hw_cfg.h>
+/* Base address */
+#define tmrHw_MODULE_BASE_ADDR MM_IO_BASE_TMR
+
+/*
+This platform has four different timers running at different clock speed
+
+Timer one (Timer ID 0) runs at 25 MHz
+Timer two (Timer ID 1) runs at 25 MHz
+Timer three (Timer ID 2) runs at 150 MHz
+Timer four (Timer ID 3) runs at 150 MHz
+*/
+#define tmrHw_LOW_FREQUENCY_MHZ 25 /* Always 25MHz from XTAL */
+#define tmrHw_LOW_FREQUENCY_HZ 25000000
+
+#if defined(CFG_GLOBAL_CHIP) && (CFG_GLOBAL_CHIP == FPGA11107)
+#define tmrHw_HIGH_FREQUENCY_MHZ 150 /* Always 150MHz for FPGA */
+#define tmrHw_HIGH_FREQUENCY_HZ 150000000
+#else
+#define tmrHw_HIGH_FREQUENCY_HZ HW_CFG_BUS_CLK_HZ
+#define tmrHw_HIGH_FREQUENCY_MHZ (HW_CFG_BUS_CLK_HZ / 1000000)
+#endif
+
+#define tmrHw_LOW_RESOLUTION_CLOCK tmrHw_LOW_FREQUENCY_HZ
+#define tmrHw_HIGH_RESOLUTION_CLOCK tmrHw_HIGH_FREQUENCY_HZ
+#define tmrHw_MAX_COUNT (0xFFFFFFFF) /* maximum number of count a timer can count */
+#define tmrHw_TIMER_NUM_COUNT (4) /* Number of timer module supported */
+
+typedef struct {
+ uint32_t LoadValue; /* Load value for timer */
+ uint32_t CurrentValue; /* Current value for timer */
+ uint32_t Control; /* Control register */
+ uint32_t InterruptClear; /* Interrupt clear register */
+ uint32_t RawInterruptStatus; /* Raw interrupt status */
+ uint32_t InterruptStatus; /* Masked interrupt status */
+ uint32_t BackgroundLoad; /* Background load value */
+ uint32_t padding; /* Padding register */
+} tmrHw_REG_t;
+
+/* Control bot masks */
+#define tmrHw_CONTROL_TIMER_ENABLE 0x00000080
+#define tmrHw_CONTROL_PERIODIC 0x00000040
+#define tmrHw_CONTROL_INTERRUPT_ENABLE 0x00000020
+#define tmrHw_CONTROL_PRESCALE_MASK 0x0000000C
+#define tmrHw_CONTROL_PRESCALE_1 0x00000000
+#define tmrHw_CONTROL_PRESCALE_16 0x00000004
+#define tmrHw_CONTROL_PRESCALE_256 0x00000008
+#define tmrHw_CONTROL_32BIT 0x00000002
+#define tmrHw_CONTROL_ONESHOT 0x00000001
+#define tmrHw_CONTROL_FREE_RUNNING 0x00000000
+
+#define tmrHw_CONTROL_MODE_MASK (tmrHw_CONTROL_PERIODIC | tmrHw_CONTROL_ONESHOT)
+
+#define pTmrHw ((volatile tmrHw_REG_t *)tmrHw_MODULE_BASE_ADDR)
+
+#endif /* _TMRHW_REG_H */
diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h
new file mode 100644
index 00000000..1f2c5319
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/dma.h
@@ -0,0 +1,826 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+* @file dma.h
+*
+* @brief API definitions for the linux DMA interface.
+*/
+/****************************************************************************/
+
+#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H)
+#define ASM_ARM_ARCH_BCMRING_DMA_H
+
+/* ---- Include Files ---------------------------------------------------- */
+
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/semaphore.h>
+#include <csp/dmacHw.h>
+#include <mach/timer.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */
+/* and line number of the reservation request will be recorded in the channel table */
+
+#define DMA_DEBUG_TRACK_RESERVATION 1
+
+#define DMA_NUM_CONTROLLERS 2
+#define DMA_NUM_CHANNELS 8 /* per controller */
+
+typedef enum {
+ DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */
+ DMA_DEVICE_I2S0_DEV_TO_MEM,
+ DMA_DEVICE_I2S0_MEM_TO_DEV,
+ DMA_DEVICE_I2S1_DEV_TO_MEM,
+ DMA_DEVICE_I2S1_MEM_TO_DEV,
+ DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM,
+ DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV,
+ DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM,
+ DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV,
+ DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */
+ DMA_DEVICE_APM_PCM0_DEV_TO_MEM,
+ DMA_DEVICE_APM_PCM0_MEM_TO_DEV,
+ DMA_DEVICE_APM_PCM1_DEV_TO_MEM,
+ DMA_DEVICE_APM_PCM1_MEM_TO_DEV,
+ DMA_DEVICE_SPUM_DEV_TO_MEM,
+ DMA_DEVICE_SPUM_MEM_TO_DEV,
+ DMA_DEVICE_SPIH_DEV_TO_MEM,
+ DMA_DEVICE_SPIH_MEM_TO_DEV,
+ DMA_DEVICE_UART_A_DEV_TO_MEM,
+ DMA_DEVICE_UART_A_MEM_TO_DEV,
+ DMA_DEVICE_UART_B_DEV_TO_MEM,
+ DMA_DEVICE_UART_B_MEM_TO_DEV,
+ DMA_DEVICE_PIF_MEM_TO_DEV,
+ DMA_DEVICE_PIF_DEV_TO_MEM,
+ DMA_DEVICE_ESW_DEV_TO_MEM,
+ DMA_DEVICE_ESW_MEM_TO_DEV,
+ DMA_DEVICE_VPM_MEM_TO_MEM,
+ DMA_DEVICE_CLCD_MEM_TO_MEM,
+ DMA_DEVICE_NAND_MEM_TO_MEM,
+ DMA_DEVICE_MEM_TO_VRAM,
+ DMA_DEVICE_VRAM_TO_MEM,
+
+ /* Add new entries before this line. */
+
+ DMA_NUM_DEVICE_ENTRIES,
+ DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */
+
+} DMA_Device_t;
+
+/****************************************************************************
+*
+* The DMA_Handle_t is the primary object used by callers of the API.
+*
+*****************************************************************************/
+
+#define DMA_INVALID_HANDLE ((DMA_Handle_t) -1)
+
+typedef int DMA_Handle_t;
+
+/****************************************************************************
+*
+* The DMA_DescriptorRing_t contains a ring of descriptors which is used
+* to point to regions of memory.
+*
+*****************************************************************************/
+
+typedef struct {
+ void *virtAddr; /* Virtual Address of the descriptor ring */
+ dma_addr_t physAddr; /* Physical address of the descriptor ring */
+ int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */
+ size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */
+
+} DMA_DescriptorRing_t;
+
+/****************************************************************************
+*
+* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup
+* DMA chains from a variety of memory sources.
+*
+*****************************************************************************/
+
+#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */
+ /* off not being DMA'd. */
+
+typedef enum {
+ DMA_MEM_TYPE_NONE, /* Not a valid setting */
+ DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */
+ DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */
+ DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */
+ DMA_MEM_TYPE_USER, /* Memory came from user space. */
+
+} DMA_MemType_t;
+
+/* A segment represents a physically and virtually contiguous chunk of memory. */
+/* i.e. each segment can be DMA'd */
+/* A user of the DMA code will add memory regions. Each region may need to be */
+/* represented by one or more segments. */
+
+typedef struct {
+ void *virtAddr; /* Virtual address used for this segment */
+ dma_addr_t physAddr; /* Physical address this segment maps to */
+ size_t numBytes; /* Size of the segment, in bytes */
+
+} DMA_Segment_t;
+
+/* A region represents a virtually contiguous chunk of memory, which may be */
+/* made up of multiple segments. */
+
+typedef struct {
+ DMA_MemType_t memType;
+ void *virtAddr;
+ size_t numBytes;
+
+ /* Each region (virtually contiguous) consists of one or more segments. Each */
+ /* segment is virtually and physically contiguous. */
+
+ int numSegmentsUsed;
+ int numSegmentsAllocated;
+ DMA_Segment_t *segment;
+
+ /* When a region corresponds to user memory, we need to lock all of the pages */
+ /* down before we can figure out the physical addresses. The lockedPage array contains */
+ /* the pages that were locked, and which subsequently need to be unlocked once the */
+ /* memory is unmapped. */
+
+ unsigned numLockedPages;
+ struct page **lockedPages;
+
+} DMA_Region_t;
+
+typedef struct {
+ int inUse; /* Is this mapping currently being used? */
+ struct semaphore lock; /* Acquired when using this structure */
+ enum dma_data_direction dir; /* Direction this transfer is intended for */
+
+ /* In the event that we're mapping user memory, we need to know which task */
+ /* the memory is for, so that we can obtain the correct mm locks. */
+
+ struct task_struct *userTask;
+
+ int numRegionsUsed;
+ int numRegionsAllocated;
+ DMA_Region_t *region;
+
+} DMA_MemMap_t;
+
+/****************************************************************************
+*
+* The DMA_DeviceAttribute_t contains information which describes a
+* particular DMA device (or peripheral).
+*
+* It is anticipated that the arrary of DMA_DeviceAttribute_t's will be
+* statically initialized.
+*
+*****************************************************************************/
+
+/* The device handler is called whenever a DMA operation completes. The reaon */
+/* for it to be called will be a bitmask with one or more of the following bits */
+/* set. */
+
+#define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK
+#define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS
+#define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR
+
+typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason,
+ void *userData);
+
+#define DMA_DEVICE_FLAG_ON_DMA0 0x00000001
+#define DMA_DEVICE_FLAG_ON_DMA1 0x00000002
+#define DMA_DEVICE_FLAG_PORT_PER_DMAC 0x00000004 /* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */
+#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */
+#define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100
+#define DMA_DEVICE_FLAG_NO_ISR 0x00000200
+#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400
+#define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */
+
+/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */
+/* determine which DMA controllers a given device can be used from, and the interface */
+/* array determeines the actual interface number to use for a given controller. */
+
+typedef struct {
+ uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */
+ uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
+ uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */
+ const char *name; /* Will show up in the /proc entry */
+
+ uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */
+
+ dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */
+
+ void *userData; /* Passed to the devHandler */
+ DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */
+
+ timer_tick_count_t transferStartTime; /* Time the current transfer was started */
+
+ /* The following statistical information will be collected and presented in a proc entry. */
+ /* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */
+ /* a 64 bit counter. */
+
+ uint64_t numTransfers; /* Number of DMA transfers performed */
+ uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */
+ uint64_t transferBytes; /* Total bytes transferred */
+ uint32_t timesBlocked; /* Number of times a channel was unavailable */
+ uint32_t numBytes; /* Last transfer size */
+
+ /* It's not possible to free memory which is allocated for the descriptors from within */
+ /* the ISR. So make the presumption that a given device will tend to use the */
+ /* same sized buffers over and over again, and we keep them around. */
+
+ DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */
+
+ /* We stash away some of the information from the previous transfer. If back-to-back */
+ /* transfers are performed from the same buffer, then we don't have to keep re-initializing */
+ /* the descriptor buffers. */
+
+ uint32_t prevNumBytes;
+ dma_addr_t prevSrcData;
+ dma_addr_t prevDstData;
+
+} DMA_DeviceAttribute_t;
+
+/****************************************************************************
+*
+* DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal
+* data structures and don't belong in this header file, but are included
+* merely for discussion.
+*
+* By the time this is implemented, these structures will be moved out into
+* the appropriate C source file instead.
+*
+*****************************************************************************/
+
+/****************************************************************************
+*
+* The DMA_Channel_t contains state information about each DMA channel. Some
+* of the channels are dedicated. Non-dedicated channels are shared
+* amongst the other devices.
+*
+*****************************************************************************/
+
+#define DMA_CHANNEL_FLAG_IN_USE 0x00000001
+#define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002
+#define DMA_CHANNEL_FLAG_NO_ISR 0x00000004
+#define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008
+
+typedef struct {
+ uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */
+ DMA_Device_t devType; /* Device this channel is currently reserved for */
+ DMA_Device_t lastDevType; /* Device type that used this previously */
+ char name[20]; /* Name passed onto request_irq */
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+ const char *fileName; /* Place where channel reservation took place */
+ int lineNum; /* Place where channel reservation took place */
+#endif
+ dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */
+
+} DMA_Channel_t;
+
+/****************************************************************************
+*
+* The DMA_Controller_t contains state information about each DMA controller.
+*
+* The freeChannelQ is stored in the controller data structure rather than
+* the channel data structure since several of the devices are accessible
+* from multiple controllers, and there is no way to know which controller
+* will become available first.
+*
+*****************************************************************************/
+
+typedef struct {
+ DMA_Channel_t channel[DMA_NUM_CHANNELS];
+
+} DMA_Controller_t;
+
+/****************************************************************************
+*
+* The DMA_Global_t contains all of the global state information used by
+* the DMA code.
+*
+* Callers which need to allocate a shared channel will be queued up
+* on the freeChannelQ until a channel becomes available.
+*
+*****************************************************************************/
+
+typedef struct {
+ struct semaphore lock; /* acquired when manipulating table entries */
+ wait_queue_head_t freeChannelQ;
+
+ DMA_Controller_t controller[DMA_NUM_CONTROLLERS];
+
+} DMA_Global_t;
+
+/* ---- Variable Externs ------------------------------------------------- */
+
+extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES];
+
+/* ---- Function Prototypes ---------------------------------------------- */
+
+#if defined(__KERNEL__)
+
+/****************************************************************************/
+/**
+* Initializes the DMA module.
+*
+* @return
+* 0 - Success
+* < 0 - Error
+*/
+/****************************************************************************/
+
+int dma_init(void);
+
+#if (DMA_DEBUG_TRACK_RESERVATION)
+DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName,
+ int lineNum);
+#define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__)
+#else
+
+/****************************************************************************/
+/**
+* Reserves a channel for use with @a dev. If the device is setup to use
+* a shared channel, then this function will block until a free channel
+* becomes available.
+*
+* @return
+* >= 0 - A valid DMA Handle.
+* -EBUSY - Device is currently being used.
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */
+ );
+#endif
+
+/****************************************************************************/
+/**
+* Frees a previously allocated DMA Handle.
+*
+* @return
+* 0 - DMA Handle was released successfully.
+* -EINVAL - Invalid DMA handle
+*/
+/****************************************************************************/
+
+int dma_free_channel(DMA_Handle_t channel /* DMA handle. */
+ );
+
+/****************************************************************************/
+/**
+* Determines if a given device has been configured as using a shared
+* channel.
+*
+* @return boolean
+* 0 Device uses a dedicated channel
+* non-zero Device uses a shared channel
+*/
+/****************************************************************************/
+
+int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */
+ );
+
+/****************************************************************************/
+/**
+* Allocates memory to hold a descriptor ring. The descriptor ring then
+* needs to be populated by making one or more calls to
+* dna_add_descriptors.
+*
+* The returned descriptor ring will be automatically initialized.
+*
+* @return
+* 0 Descriptor ring was allocated successfully
+* -ENOMEM Unable to allocate memory for the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */
+ int numDescriptors /* Number of descriptors that need to be allocated. */
+ );
+
+/****************************************************************************/
+/**
+* Releases the memory which was previously allocated for a descriptor ring.
+*/
+/****************************************************************************/
+
+void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */
+ );
+
+/****************************************************************************/
+/**
+* Initializes a descriptor ring, so that descriptors can be added to it.
+* Once a descriptor ring has been allocated, it may be reinitialized for
+* use with additional/different regions of memory.
+*
+* Note that if 7 descriptors are allocated, it's perfectly acceptable to
+* initialize the ring with a smaller number of descriptors. The amount
+* of memory allocated for the descriptor ring will not be reduced, and
+* the descriptor ring may be reinitialized later
+*
+* @return
+* 0 Descriptor ring was initialized successfully
+* -ENOMEM The descriptor which was passed in has insufficient space
+* to hold the desired number of descriptors.
+*/
+/****************************************************************************/
+
+int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */
+ int numDescriptors /* Number of descriptors to initialize. */
+ );
+
+/****************************************************************************/
+/**
+* Determines the number of descriptors which would be required for a
+* transfer of the indicated memory region.
+*
+* This function also needs to know which DMA device this transfer will
+* be destined for, so that the appropriate DMA configuration can be retrieved.
+* DMA parameters such as transfer width, and whether this is a memory-to-memory
+* or memory-to-peripheral, etc can all affect the actual number of descriptors
+* required.
+*
+* @return
+* > 0 Returns the number of descriptors required for the indicated transfer
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ );
+
+/****************************************************************************/
+/**
+* Adds a region of memory to the descriptor ring. Note that it may take
+* multiple descriptors for each region of memory. It is the callers
+* responsibility to allocate a sufficiently large descriptor ring.
+*
+* @return
+* 0 Descriptors were added successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */
+ DMA_Device_t device, /* DMA Device that descriptors are for */
+ dma_addr_t srcData, /* Place to get data (memory or device) */
+ dma_addr_t dstData, /* Place to put data (memory or device) */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ );
+
+/****************************************************************************/
+/**
+* Sets the descriptor ring associated with a device.
+*
+* Once set, the descriptor ring will be associated with the device, even
+* across channel request/free calls. Passing in a NULL descriptor ring
+* will release any descriptor ring currently associated with the device.
+*
+* Note: If you call dma_transfer, or one of the other dma_alloc_ functions
+* the descriptor ring may be released and reallocated.
+*
+* Note: This function will release the descriptor memory for any current
+* descriptor ring associated with this device.
+*/
+/****************************************************************************/
+
+int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */
+ DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */
+ );
+
+/****************************************************************************/
+/**
+* Retrieves the descriptor ring associated with a device.
+*/
+/****************************************************************************/
+
+int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */
+ DMA_DescriptorRing_t *ring /* Place to store retrieved ring */
+ );
+
+/****************************************************************************/
+/**
+* Allocates buffers for the descriptors. This is normally done automatically
+* but needs to be done explicitly when initiating a dma from interrupt
+* context.
+*
+* @return
+* 0 Descriptors were allocated successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */
+ dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ );
+
+/****************************************************************************/
+/**
+* Allocates and sets up descriptors for a double buffered circular buffer.
+*
+* This is primarily intended to be used for things like the ingress samples
+* from a microphone.
+*
+* @return
+* > 0 Number of descriptors actually allocated.
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+* -ENOMEM Memory exhausted
+*/
+/****************************************************************************/
+
+int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
+ dma_addr_t srcData, /* Physical address of source data */
+ dma_addr_t dstData1, /* Physical address of first destination buffer */
+ dma_addr_t dstData2, /* Physical address of second destination buffer */
+ size_t numBytes /* Number of bytes in each destination buffer */
+ );
+
+/****************************************************************************/
+/**
+* Initializes a DMA_MemMap_t data structure
+*/
+/****************************************************************************/
+
+int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
+ );
+
+/****************************************************************************/
+/**
+* Releases any memory currently being held by a memory mapping structure.
+*/
+/****************************************************************************/
+
+int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
+ );
+
+/****************************************************************************/
+/**
+* Looks at a memory address and categorizes it.
+*
+* @return One of the values from the DMA_MemType_t enumeration.
+*/
+/****************************************************************************/
+
+DMA_MemType_t dma_mem_type(void *addr);
+
+/****************************************************************************/
+/**
+* Sets the process (aka userTask) associated with a mem map. This is
+* required if user-mode segments will be added to the mapping.
+*/
+/****************************************************************************/
+
+static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
+ struct task_struct *task)
+{
+ memMap->userTask = task;
+}
+
+/****************************************************************************/
+/**
+* Looks at a memory address and determines if we support DMA'ing to/from
+* that type of memory.
+*
+* @return boolean -
+* return value != 0 means dma supported
+* return value == 0 means dma not supported
+*/
+/****************************************************************************/
+
+int dma_mem_supports_dma(void *addr);
+
+/****************************************************************************/
+/**
+* Initializes a memory map for use. Since this function acquires a
+* sempaphore within the memory map, it is VERY important that dma_unmap
+* be called when you're finished using the map.
+*/
+/****************************************************************************/
+
+int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ enum dma_data_direction dir /* Direction that the mapping will be going */
+ );
+
+/****************************************************************************/
+/**
+* Adds a segment of memory to a memory map.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ void *mem, /* Virtual address that we want to get a map of */
+ size_t numBytes /* Number of bytes being mapped */
+ );
+
+/****************************************************************************/
+/**
+* Creates a descriptor ring from a memory mapping.
+*
+* @return 0 on success, error code otherwise.
+*/
+/****************************************************************************/
+
+int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
+ DMA_MemMap_t *memMap, /* Memory map that will be used */
+ dma_addr_t devPhysAddr /* Physical address of device */
+ );
+
+/****************************************************************************/
+/**
+* Maps in a memory region such that it can be used for performing a DMA.
+*
+* @return
+*/
+/****************************************************************************/
+
+int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ void *addr, /* Virtual address that we want to get a map of */
+ size_t count, /* Number of bytes being mapped */
+ enum dma_data_direction dir /* Direction that the mapping will be going */
+ );
+
+/****************************************************************************/
+/**
+* Maps in a memory region such that it can be used for performing a DMA.
+*
+* @return
+*/
+/****************************************************************************/
+
+int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
+ int dirtied /* non-zero if any of the pages were modified */
+ );
+
+/****************************************************************************/
+/**
+* Initiates a transfer when the descriptors have already been setup.
+*
+* This is a special case, and normally, the dma_transfer_xxx functions should
+* be used.
+*
+* @return
+* 0 Transfer was started successfully
+* -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_start_transfer(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+* Stops a previously started DMA transfer.
+*
+* @return
+* 0 Transfer was stopped successfully
+* -ENODEV Invalid handle
+*/
+/****************************************************************************/
+
+int dma_stop_transfer(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+* Waits for a DMA to complete by polling. This function is only intended
+* to be used for testing. Interrupts should be used for most DMA operations.
+*/
+/****************************************************************************/
+
+int dma_wait_transfer_done(DMA_Handle_t handle);
+
+/****************************************************************************/
+/**
+* Initiates a DMA transfer
+*
+* @return
+* 0 Transfer was started successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*/
+/****************************************************************************/
+
+int dma_transfer(DMA_Handle_t handle, /* DMA Handle */
+ dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
+ dma_addr_t srcData, /* Place to get data to write to device */
+ dma_addr_t dstData, /* Pointer to device data address */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ );
+
+/****************************************************************************/
+/**
+* Initiates a transfer from memory to a device.
+*
+* @return
+* 0 Transfer was started successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */
+ dma_addr_t srcData, /* Place to get data to write to device (physical address) */
+ dma_addr_t dstData, /* Pointer to device data address (physical address) */
+ size_t numBytes /* Number of bytes to transfer to the device */
+ ) {
+ return dma_transfer(handle,
+ dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
+ srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+* Initiates a transfer from a device to memory.
+*
+* @return
+* 0 Transfer was started successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */
+ dma_addr_t srcData, /* Pointer to the device data address (physical address) */
+ dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */
+ size_t numBytes /* Number of bytes to retrieve from the device */
+ ) {
+ return dma_transfer(handle,
+ dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
+ srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+* Initiates a memory to memory transfer.
+*
+* @return
+* 0 Transfer was started successfully
+* -EINVAL Invalid device type for this kind of transfer
+* (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM)
+*/
+/****************************************************************************/
+
+static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */
+ dma_addr_t srcData, /* Place to transfer data from (physical address) */
+ dma_addr_t dstData, /* Place to transfer data to (physical address) */
+ size_t numBytes /* Number of bytes to transfer */
+ ) {
+ return dma_transfer(handle,
+ dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
+ srcData, dstData, numBytes);
+}
+
+/****************************************************************************/
+/**
+* Set the callback function which will be called when a transfer completes.
+* If a NULL callback function is set, then no callback will occur.
+*
+* @note @a devHandler will be called from IRQ context.
+*
+* @return
+* 0 - Success
+* -ENODEV - Device handed in is invalid.
+*/
+/****************************************************************************/
+
+int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */
+ DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */
+ void *userData /* Pointer which will be passed to devHandler. */
+ );
+
+#endif
+
+#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */
diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S
new file mode 100644
index 00000000..7d393ca0
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S
@@ -0,0 +1,86 @@
+/*****************************************************************************
+* Copyright 2006 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+ *
+ * Low-level IRQ helper macros for BCMRing-based platforms
+ *
+ */
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =(MM_IO_BASE_INTC0)
+ ldr \irqstat, [\base, #0] @ get status
+ ldr \irqnr, [\base, #0x10] @ mask with enable register
+ ands \irqstat, \irqstat, \irqnr
+ mov \irqnr, #IRQ_INTC0_START
+ cmp \irqstat, #0
+ bne 1001f
+
+ ldr \base, =(MM_IO_BASE_INTC1)
+ ldr \irqstat, [\base, #0] @ get status
+ ldr \irqnr, [\base, #0x10] @ mask with enable register
+ ands \irqstat, \irqstat, \irqnr
+ mov \irqnr, #IRQ_INTC1_START
+ cmp \irqstat, #0
+ bne 1001f
+
+ ldr \base, =(MM_IO_BASE_SINTC)
+ ldr \irqstat, [\base, #0] @ get status
+ ldr \irqnr, [\base, #0x10] @ mask with enable register
+ ands \irqstat, \irqstat, \irqnr
+ mov \irqnr, #0xffffffff @ code meaning no interrupt bits set
+ cmp \irqstat, #0
+ beq 1002f
+
+ mov \irqnr, #IRQ_SINTC_START @ something is set, so fixup return value
+
+1001:
+ movs \tmp, \irqstat, lsl #16
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+
+ movs \tmp, \irqstat, lsl #8
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #8
+
+ movs \tmp, \irqstat, lsl #4
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #4
+
+ movs \tmp, \irqstat, lsl #2
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #2
+
+ movs \tmp, \irqstat, lsl #1
+ addeq \irqnr, \irqnr, #1
+ orrs \base, \base, #1
+
+1002: @ irqnr will be set to 0xffffffff if no irq bits are set
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h
new file mode 100644
index 00000000..8bf3564f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/hardware.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * This file contains the hardware definitions of the BCMRing.
+ *
+ * Copyright (C) 1999 ARM Limited.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/memory.h>
+#include <cfg_global.h>
+#include <mach/csp/mm_io.h>
+
+/* Hardware addresses of major areas.
+ * *_START is the physical address
+ * *_SIZE is the size of the region
+ * *_BASE is the virtual address
+ */
+#define RAM_START PLAT_PHYS_OFFSET
+
+#define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED)
+#define RAM_BASE PAGE_OFFSET
+
+#define pcibios_assign_all_busses() 1
+
+/* Macros to make managing spinlocks a bit more controlled in terms of naming. */
+/* See reg_gpio.h, reg_irq.h, arch.c, gpio.c for example usage. */
+#if defined(__KERNEL__)
+#define HW_DECLARE_SPINLOCK(name) DEFINE_SPINLOCK(bcmring_##name##_reg_lock);
+#define HW_EXTERN_SPINLOCK(name) extern spinlock_t bcmring_##name##_reg_lock;
+#define HW_IRQ_SAVE(name, val) spin_lock_irqsave(&bcmring_##name##_reg_lock, (val))
+#define HW_IRQ_RESTORE(name, val) spin_unlock_irqrestore(&bcmring_##name##_reg_lock, (val))
+#else
+#define HW_DECLARE_SPINLOCK(name)
+#define HW_EXTERN_SPINLOCK(name)
+#define HW_IRQ_SAVE(name, val) {(void)(name); (void)(val); }
+#define HW_IRQ_RESTORE(name, val) {(void)(name); (void)(val); }
+#endif
+
+#ifndef HW_IO_PHYS_TO_VIRT
+#define HW_IO_PHYS_TO_VIRT MM_IO_PHYS_TO_VIRT
+#endif
+#define HW_IO_VIRT_TO_PHYS MM_IO_VIRT_TO_PHYS
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h
new file mode 100644
index 00000000..dae5e9b1
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/io.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/irqs.h b/arch/arm/mach-bcmring/include/mach/irqs.h
new file mode 100644
index 00000000..b279b825
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/irqs.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2007 Broadcom
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+#if !defined(ARCH_BCMRING_IRQS_H)
+#define ARCH_BCMRING_IRQS_H
+
+/* INTC0 - interrupt controller 0 */
+#define IRQ_INTC0_START 0
+#define IRQ_DMA0C0 0 /* DMA0 channel 0 interrupt */
+#define IRQ_DMA0C1 1 /* DMA0 channel 1 interrupt */
+#define IRQ_DMA0C2 2 /* DMA0 channel 2 interrupt */
+#define IRQ_DMA0C3 3 /* DMA0 channel 3 interrupt */
+#define IRQ_DMA0C4 4 /* DMA0 channel 4 interrupt */
+#define IRQ_DMA0C5 5 /* DMA0 channel 5 interrupt */
+#define IRQ_DMA0C6 6 /* DMA0 channel 6 interrupt */
+#define IRQ_DMA0C7 7 /* DMA0 channel 7 interrupt */
+#define IRQ_DMA1C0 8 /* DMA1 channel 0 interrupt */
+#define IRQ_DMA1C1 9 /* DMA1 channel 1 interrupt */
+#define IRQ_DMA1C2 10 /* DMA1 channel 2 interrupt */
+#define IRQ_DMA1C3 11 /* DMA1 channel 3 interrupt */
+#define IRQ_DMA1C4 12 /* DMA1 channel 4 interrupt */
+#define IRQ_DMA1C5 13 /* DMA1 channel 5 interrupt */
+#define IRQ_DMA1C6 14 /* DMA1 channel 6 interrupt */
+#define IRQ_DMA1C7 15 /* DMA1 channel 7 interrupt */
+#define IRQ_VPM 16 /* Voice process module interrupt */
+#define IRQ_USBHD2 17 /* USB host2/device2 interrupt */
+#define IRQ_USBH1 18 /* USB1 host interrupt */
+#define IRQ_USBD 19 /* USB device interrupt */
+#define IRQ_SDIOH0 20 /* SDIO0 host interrupt */
+#define IRQ_SDIOH1 21 /* SDIO1 host interrupt */
+#define IRQ_TIMER0 22 /* Timer0 interrupt */
+#define IRQ_TIMER1 23 /* Timer1 interrupt */
+#define IRQ_TIMER2 24 /* Timer2 interrupt */
+#define IRQ_TIMER3 25 /* Timer3 interrupt */
+#define IRQ_SPIH 26 /* SPI host interrupt */
+#define IRQ_ESW 27 /* Ethernet switch interrupt */
+#define IRQ_APM 28 /* Audio process module interrupt */
+#define IRQ_GE 29 /* Graphic engine interrupt */
+#define IRQ_CLCD 30 /* LCD Controller interrupt */
+#define IRQ_PIF 31 /* Peripheral interface interrupt */
+#define IRQ_INTC0_END 31
+
+/* INTC1 - interrupt controller 1 */
+#define IRQ_INTC1_START 32
+#define IRQ_GPIO0 32 /* 0 GPIO bit 31//0 combined interrupt */
+#define IRQ_GPIO1 33 /* 1 GPIO bit 64//32 combined interrupt */
+#define IRQ_I2S0 34 /* 2 I2S0 interrupt */
+#define IRQ_I2S1 35 /* 3 I2S1 interrupt */
+#define IRQ_I2CH 36 /* 4 I2C host interrupt */
+#define IRQ_I2CS 37 /* 5 I2C slave interrupt */
+#define IRQ_SPIS 38 /* 6 SPI slave interrupt */
+#define IRQ_GPHY 39 /* 7 Gigabit Phy interrupt */
+#define IRQ_FLASHC 40 /* 8 Flash controller interrupt */
+#define IRQ_COMMTX 41 /* 9 ARM DDC transmit interrupt */
+#define IRQ_COMMRX 42 /* 10 ARM DDC receive interrupt */
+#define IRQ_PMUIRQ 43 /* 11 ARM performance monitor interrupt */
+#define IRQ_UARTB 44 /* 12 UARTB */
+#define IRQ_WATCHDOG 45 /* 13 Watchdog timer interrupt */
+#define IRQ_UARTA 46 /* 14 UARTA */
+#define IRQ_TSC 47 /* 15 Touch screen controller interrupt */
+#define IRQ_KEYC 48 /* 16 Key pad controller interrupt */
+#define IRQ_DMPU 49 /* 17 DDR2 memory partition interrupt */
+#define IRQ_VMPU 50 /* 18 VRAM memory partition interrupt */
+#define IRQ_FMPU 51 /* 19 Flash memory parition unit interrupt */
+#define IRQ_RNG 52 /* 20 Random number generator interrupt */
+#define IRQ_RTC0 53 /* 21 Real time clock periodic interrupt */
+#define IRQ_RTC1 54 /* 22 Real time clock one-shot interrupt */
+#define IRQ_SPUM 55 /* 23 Secure process module interrupt */
+#define IRQ_VDEC 56 /* 24 Hantro video decoder interrupt */
+#define IRQ_RTC2 57 /* 25 Real time clock tamper interrupt */
+#define IRQ_DDRP 58 /* 26 DDR Panic interrupt */
+#define IRQ_INTC1_END 58
+
+/* SINTC secure int controller */
+#define IRQ_SINTC_START 59
+#define IRQ_SEC_WATCHDOG 59 /* 0 Watchdog timer interrupt */
+#define IRQ_SEC_UARTA 60 /* 1 UARTA interrupt */
+#define IRQ_SEC_TSC 61 /* 2 Touch screen controller interrupt */
+#define IRQ_SEC_KEYC 62 /* 3 Key pad controller interrupt */
+#define IRQ_SEC_DMPU 63 /* 4 DDR2 memory partition interrupt */
+#define IRQ_SEC_VMPU 64 /* 5 VRAM memory partition interrupt */
+#define IRQ_SEC_FMPU 65 /* 6 Flash memory parition unit interrupt */
+#define IRQ_SEC_RNG 66 /* 7 Random number generator interrupt */
+#define IRQ_SEC_RTC0 67 /* 8 Real time clock periodic interrupt */
+#define IRQ_SEC_RTC1 68 /* 9 Real time clock one-shot interrupt */
+#define IRQ_SEC_SPUM 69 /* 10 Secure process module interrupt */
+#define IRQ_SEC_TIMER0 70 /* 11 Secure timer0 interrupt */
+#define IRQ_SEC_TIMER1 71 /* 12 Secure timer1 interrupt */
+#define IRQ_SEC_TIMER2 72 /* 13 Secure timer2 interrupt */
+#define IRQ_SEC_TIMER3 73 /* 14 Secure timer3 interrupt */
+#define IRQ_SEC_RTC2 74 /* 15 Real time clock tamper interrupt */
+
+#define IRQ_SINTC_END 74
+
+/* Note: there are 3 INTC registers of 32 bits each. So internal IRQs could go from 0-95 */
+/* Since IRQs are typically viewed in decimal, we start the gpio based IRQs off at 100 */
+/* to make the mapping easy for humans to decipher. */
+
+#define IRQ_GPIO_0 100
+
+#define NUM_INTERNAL_IRQS (IRQ_SINTC_END+1)
+
+/* I couldn't get the gpioHw_reg.h file to be included cleanly, so I hardcoded it */
+/* define NUM_GPIO_IRQS GPIOHW_TOTAL_NUM_PINS */
+#define NUM_GPIO_IRQS 62
+
+#define NR_IRQS (IRQ_GPIO_0 + NUM_GPIO_IRQS)
+
+#define IRQ_UNKNOWN -1
+
+/* Tune these bits to preclude noisy or unsupported interrupt sources as required. */
+#define IRQ_INTC0_VALID_MASK 0xffffffff
+#define IRQ_INTC1_VALID_MASK 0x07ffffff
+#define IRQ_SINTC_VALID_MASK 0x0000ffff
+
+#endif /* ARCH_BCMRING_IRQS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h
new file mode 100644
index 00000000..15162e4c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory.h
@@ -0,0 +1,33 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <cfg_global.h>
+
+/*
+ * Physical vs virtual RAM address space conversion. These are
+ * private definitions which should NOT be used outside memory.h
+ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+
+#define PLAT_PHYS_OFFSET CFG_GLOBAL_RAM_BASE
+
+/*
+ * Maximum DMA memory allowed is 14M
+ */
+#define CONSISTENT_DMA_SIZE (SZ_16M - SZ_2M)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/memory_settings.h b/arch/arm/mach-bcmring/include/mach/memory_settings.h
new file mode 100644
index 00000000..ce5cd16f
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/memory_settings.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#ifndef MEMORY_SETTINGS_H
+#define MEMORY_SETTINGS_H
+
+/* ---- Include Files ---------------------------------------- */
+/* ---- Constants and Types ---------------------------------- */
+
+/* Memory devices */
+/* NAND Flash timing for 166 MHz setting */
+#define HW_CFG_NAND_tBTA (5 << 16) /* Bus turnaround cycle (n) 0-7 (30 ns) */
+#define HW_CFG_NAND_tWP (4 << 11) /* Write pulse width cycle (n+1) 0-31 (25 ns) */
+#define HW_CFG_NAND_tWR (1 << 9) /* Write recovery cycle (n+1) 0-3 (10 ns) */
+#define HW_CFG_NAND_tAS (0 << 7) /* Write address setup cycle (n+1) 0-3 ( 0 ns) */
+#define HW_CFG_NAND_tOE (3 << 5) /* Output enable delay cycle (n) 0-3 (15 ns) */
+#define HW_CFG_NAND_tRC (7 << 0) /* Read access cycle (n+2) 0-31 (50 ns) */
+
+#define HW_CFG_NAND_TCR (HW_CFG_NAND_tBTA \
+ | HW_CFG_NAND_tWP \
+ | HW_CFG_NAND_tWR \
+ | HW_CFG_NAND_tAS \
+ | HW_CFG_NAND_tOE \
+ | HW_CFG_NAND_tRC)
+
+/* NOR Flash timing for 166 MHz setting */
+#define HW_CFG_NOR_TPRC_TWLC (0 << 19) /* Page read access cycle / Burst write latency (n+2 / n+1) (max 25ns) */
+#define HW_CFG_NOR_TBTA (0 << 16) /* Bus turnaround cycle (n) (DNA) */
+#define HW_CFG_NOR_TWP (6 << 11) /* Write pulse width cycle (n+1) (35ns) */
+#define HW_CFG_NOR_TWR (0 << 9) /* Write recovery cycle (n+1) (0ns) */
+#define HW_CFG_NOR_TAS (0 << 7) /* Write address setup cycle (n+1) (0ns) */
+#define HW_CFG_NOR_TOE (0 << 5) /* Output enable delay cycle (n) (max 25ns) */
+#define HW_CFG_NOR_TRC_TLC (0x10 << 0) /* Read access cycle / Burst read latency (n+2 / n+1) (100ns) */
+
+#define HW_CFG_FLASH0_TCR (HW_CFG_NOR_TPRC_TWLC \
+ | HW_CFG_NOR_TBTA \
+ | HW_CFG_NOR_TWP \
+ | HW_CFG_NOR_TWR \
+ | HW_CFG_NOR_TAS \
+ | HW_CFG_NOR_TOE \
+ | HW_CFG_NOR_TRC_TLC)
+
+#define HW_CFG_FLASH1_TCR HW_CFG_FLASH0_TCR
+#define HW_CFG_FLASH2_TCR HW_CFG_FLASH0_TCR
+
+/* SDRAM Settings */
+/* #define HW_CFG_SDRAM_CAS_LATENCY 5 Default 5, Values [3..6] */
+/* #define HW_CFG_SDRAM_CHIP_SELECT_CNT 1 Default 1, Vaules [1..2] */
+/* #define HW_CFG_SDRAM_SPEED_GRADE 667 Default 667, Values [400,533,667,800] */
+/* #define HW_CFG_SDRAM_WIDTH_BITS 16 Default 16, Vaules [8,16] */
+#define HW_CFG_SDRAM_SIZE_BYTES 0x10000000 /* Total memory, not per device size */
+
+/* ---- Variable Externs ------------------------------------- */
+/* ---- Function Prototypes ---------------------------------- */
+
+#endif /* MEMORY_SETTINGS_H */
diff --git a/arch/arm/mach-bcmring/include/mach/reg_nand.h b/arch/arm/mach-bcmring/include/mach/reg_nand.h
new file mode 100644
index 00000000..387376ff
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/reg_nand.h
@@ -0,0 +1,66 @@
+/*****************************************************************************
+* Copyright 2001 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+* REG_NAND.h
+*
+* PURPOSE:
+*
+* This file contains definitions for the nand registers:
+*
+* NOTES:
+*
+*****************************************************************************/
+
+#if !defined(__ASM_ARCH_REG_NAND_H)
+#define __ASM_ARCH_REG_NAND_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/reg.h>
+#include <mach/reg_umi.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+#define HW_NAND_BASE MM_IO_BASE_NAND /* NAND Flash */
+
+/* DMA accesses by the bootstrap need hard nonvirtual addresses */
+#define REG_NAND_CMD __REG16(HW_NAND_BASE + 0)
+#define REG_NAND_ADDR __REG16(HW_NAND_BASE + 4)
+
+#define REG_NAND_PHYS_DATA16 (HW_NAND_BASE + 8)
+#define REG_NAND_PHYS_DATA8 (HW_NAND_BASE + 8)
+#define REG_NAND_DATA16 __REG16(REG_NAND_PHYS_DATA16)
+#define REG_NAND_DATA8 __REG8(REG_NAND_PHYS_DATA8)
+
+/* use appropriate offset to make sure it start at the 1K boundary */
+#define REG_NAND_PHYS_DATA_DMA (HW_NAND_BASE + 0x400)
+#define REG_NAND_DATA_DMA __REG32(REG_NAND_PHYS_DATA_DMA)
+
+/* Linux DMA requires physical address of the data register */
+#define REG_NAND_DATA16_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA16)
+#define REG_NAND_DATA8_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA8)
+#define REG_NAND_DATA_PADDR HW_IO_VIRT_TO_PHYS(REG_NAND_PHYS_DATA_DMA)
+
+#define NAND_BUS_16BIT() (0)
+#define NAND_BUS_8BIT() (!NAND_BUS_16BIT())
+
+/* Register offsets */
+#define REG_NAND_CMD_OFFSET (0)
+#define REG_NAND_ADDR_OFFSET (4)
+#define REG_NAND_DATA8_OFFSET (8)
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/reg_umi.h b/arch/arm/mach-bcmring/include/mach/reg_umi.h
new file mode 100644
index 00000000..0992842c
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/reg_umi.h
@@ -0,0 +1,237 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+* REG_UMI.h
+*
+* PURPOSE:
+*
+* This file contains definitions for the nand registers:
+*
+* NOTES:
+*
+*****************************************************************************/
+
+#if !defined(__ASM_ARCH_REG_UMI_H)
+#define __ASM_ARCH_REG_UMI_H
+
+/* ---- Include Files ---------------------------------------------------- */
+#include <csp/reg.h>
+#include <mach/csp/mm_io.h>
+
+/* ---- Constants and Types ---------------------------------------------- */
+
+/* Unified Memory Interface Ctrl Register */
+#define HW_UMI_BASE MM_IO_BASE_UMI
+
+/* Flash bank 0 timing and control register */
+#define REG_UMI_FLASH0_TCR __REG32(HW_UMI_BASE + 0x00)
+/* Flash bank 1 timing and control register */
+#define REG_UMI_FLASH1_TCR __REG32(HW_UMI_BASE + 0x04)
+/* Flash bank 2 timing and control register */
+#define REG_UMI_FLASH2_TCR __REG32(HW_UMI_BASE + 0x08)
+/* MMD interface and control register */
+#define REG_UMI_MMD_ICR __REG32(HW_UMI_BASE + 0x0c)
+/* NAND timing and control register */
+#define REG_UMI_NAND_TCR __REG32(HW_UMI_BASE + 0x18)
+/* NAND ready/chip select register */
+#define REG_UMI_NAND_RCSR __REG32(HW_UMI_BASE + 0x1c)
+/* NAND ECC control & status register */
+#define REG_UMI_NAND_ECC_CSR __REG32(HW_UMI_BASE + 0x20)
+/* NAND ECC data register XXB2B1B0 */
+#define REG_UMI_NAND_ECC_DATA __REG32(HW_UMI_BASE + 0x24)
+/* BCH ECC Parameter N */
+#define REG_UMI_BCH_N __REG32(HW_UMI_BASE + 0x40)
+/* BCH ECC Parameter T */
+#define REG_UMI_BCH_K __REG32(HW_UMI_BASE + 0x44)
+/* BCH ECC Parameter K */
+#define REG_UMI_BCH_T __REG32(HW_UMI_BASE + 0x48)
+/* BCH ECC Contro Status */
+#define REG_UMI_BCH_CTRL_STATUS __REG32(HW_UMI_BASE + 0x4C)
+/* BCH WR ECC 31:0 */
+#define REG_UMI_BCH_WR_ECC_0 __REG32(HW_UMI_BASE + 0x50)
+/* BCH WR ECC 63:32 */
+#define REG_UMI_BCH_WR_ECC_1 __REG32(HW_UMI_BASE + 0x54)
+/* BCH WR ECC 95:64 */
+#define REG_UMI_BCH_WR_ECC_2 __REG32(HW_UMI_BASE + 0x58)
+/* BCH WR ECC 127:96 */
+#define REG_UMI_BCH_WR_ECC_3 __REG32(HW_UMI_BASE + 0x5c)
+/* BCH WR ECC 155:128 */
+#define REG_UMI_BCH_WR_ECC_4 __REG32(HW_UMI_BASE + 0x60)
+/* BCH Read Error Location 1,0 */
+#define REG_UMI_BCH_RD_ERR_LOC_1_0 __REG32(HW_UMI_BASE + 0x64)
+/* BCH Read Error Location 3,2 */
+#define REG_UMI_BCH_RD_ERR_LOC_3_2 __REG32(HW_UMI_BASE + 0x68)
+/* BCH Read Error Location 5,4 */
+#define REG_UMI_BCH_RD_ERR_LOC_5_4 __REG32(HW_UMI_BASE + 0x6c)
+/* BCH Read Error Location 7,6 */
+#define REG_UMI_BCH_RD_ERR_LOC_7_6 __REG32(HW_UMI_BASE + 0x70)
+/* BCH Read Error Location 9,8 */
+#define REG_UMI_BCH_RD_ERR_LOC_9_8 __REG32(HW_UMI_BASE + 0x74)
+/* BCH Read Error Location 11,10 */
+#define REG_UMI_BCH_RD_ERR_LOC_B_A __REG32(HW_UMI_BASE + 0x78)
+
+/* REG_UMI_FLASH0/1/2_TCR, REG_UMI_SRAM0/1_TCR bits */
+/* Enable wait pin during burst write or read */
+#define REG_UMI_TCR_WAITEN 0x80000000
+/* Enable mem ctrlr to work with ext mem of lower freq than AHB clk */
+#define REG_UMI_TCR_LOWFREQ 0x40000000
+/* 1=synch write, 0=async write */
+#define REG_UMI_TCR_MEMTYPE_SYNCWRITE 0x20000000
+/* 1=synch read, 0=async read */
+#define REG_UMI_TCR_MEMTYPE_SYNCREAD 0x10000000
+/* 1=page mode read, 0=normal mode read */
+#define REG_UMI_TCR_MEMTYPE_PAGEREAD 0x08000000
+/* page size/burst size (wrap only) */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_MASK 0x07000000
+/* 4 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_4 0x00000000
+/* 8 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_8 0x01000000
+/* 16 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_16 0x02000000
+/* 32 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_32 0x03000000
+/* 64 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_64 0x04000000
+/* 128 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_128 0x05000000
+/* 256 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_256 0x06000000
+/* 512 word */
+#define REG_UMI_TCR_MEMTYPE_PGSZ_512 0x07000000
+/* Page read access cycle / Burst write latency (n+2 / n+1) */
+#define REG_UMI_TCR_TPRC_TWLC_MASK 0x00f80000
+/* Bus turnaround cycle (n) */
+#define REG_UMI_TCR_TBTA_MASK 0x00070000
+/* Write pulse width cycle (n+1) */
+#define REG_UMI_TCR_TWP_MASK 0x0000f800
+/* Write recovery cycle (n+1) */
+#define REG_UMI_TCR_TWR_MASK 0x00000600
+/* Write address setup cycle (n+1) */
+#define REG_UMI_TCR_TAS_MASK 0x00000180
+/* Output enable delay cycle (n) */
+#define REG_UMI_TCR_TOE_MASK 0x00000060
+/* Read access cycle / Burst read latency (n+2 / n+1) */
+#define REG_UMI_TCR_TRC_TLC_MASK 0x0000001f
+
+/* REG_UMI_MMD_ICR bits */
+/* Flash write protection pin control */
+#define REG_UMI_MMD_ICR_FLASH_WP 0x8000
+/* Extend hold time for sram0, sram1 csn (39 MHz operation) */
+#define REG_UMI_MMD_ICR_XHCS 0x4000
+/* Enable SDRAM 2 interface control */
+#define REG_UMI_MMD_ICR_SDRAM2EN 0x2000
+/* Enable merge of flash banks 0/1 to 512 MBit bank */
+#define REG_UMI_MMD_ICR_INST512 0x1000
+/* Enable merge of flash banks 1/2 to 512 MBit bank */
+#define REG_UMI_MMD_ICR_DATA512 0x0800
+/* Enable SDRAM interface control */
+#define REG_UMI_MMD_ICR_SDRAMEN 0x0400
+/* Polarity of busy state of Burst Wait Signal */
+#define REG_UMI_MMD_ICR_WAITPOL 0x0200
+/* Enable burst clock stopped when not accessing external burst flash/sram */
+#define REG_UMI_MMD_ICR_BCLKSTOP 0x0100
+/* Enable the peri1_csn to replace flash1_csn in 512 Mb flash mode */
+#define REG_UMI_MMD_ICR_PERI1EN 0x0080
+/* Enable the peri2_csn to replace sdram_csn */
+#define REG_UMI_MMD_ICR_PERI2EN 0x0040
+/* Enable the peri3_csn to replace sdram2_csn */
+#define REG_UMI_MMD_ICR_PERI3EN 0x0020
+/* Enable sram bank1 for H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSB1 0x0010
+/* Enable sram bank0 for H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSB0 0x0008
+/* Polarity for assert3ed state of H/W controlled MRS */
+#define REG_UMI_MMD_ICR_MRSPOL 0x0004
+/* 0: S/W controllable ZZ/MRS/CRE/P-Mode pin */
+/* 1: H/W controlled ZZ/MRS/CRE/P-Mode, same timing as CS */
+#define REG_UMI_MMD_ICR_MRSMODE 0x0002
+/* MRS state for S/W controlled mode */
+#define REG_UMI_MMD_ICR_MRSSTATE 0x0001
+
+/* REG_UMI_NAND_TCR bits */
+/* Enable software to control CS */
+#define REG_UMI_NAND_TCR_CS_SWCTRL 0x80000000
+/* 16-bit nand wordsize if set */
+#define REG_UMI_NAND_TCR_WORD16 0x40000000
+/* Bus turnaround cycle (n) */
+#define REG_UMI_NAND_TCR_TBTA_MASK 0x00070000
+/* Write pulse width cycle (n+1) */
+#define REG_UMI_NAND_TCR_TWP_MASK 0x0000f800
+/* Write recovery cycle (n+1) */
+#define REG_UMI_NAND_TCR_TWR_MASK 0x00000600
+/* Write address setup cycle (n+1) */
+#define REG_UMI_NAND_TCR_TAS_MASK 0x00000180
+/* Output enable delay cycle (n) */
+#define REG_UMI_NAND_TCR_TOE_MASK 0x00000060
+/* Read access cycle (n+2) */
+#define REG_UMI_NAND_TCR_TRC_TLC_MASK 0x0000001f
+
+/* REG_UMI_NAND_RCSR bits */
+/* Status: Ready=1, Busy=0 */
+#define REG_UMI_NAND_RCSR_RDY 0x02
+/* Keep CS asserted during operation */
+#define REG_UMI_NAND_RCSR_CS_ASSERTED 0x01
+
+/* REG_UMI_NAND_ECC_CSR bits */
+/* Interrupt status - read-only */
+#define REG_UMI_NAND_ECC_CSR_NANDINT 0x80000000
+/* Read: Status of ECC done, Write: clear ECC interrupt */
+#define REG_UMI_NAND_ECC_CSR_ECCINT_RAW 0x00800000
+/* Read: Status of R/B, Write: clear R/B interrupt */
+#define REG_UMI_NAND_ECC_CSR_RBINT_RAW 0x00400000
+/* 1 = Enable ECC Interrupt */
+#define REG_UMI_NAND_ECC_CSR_ECCINT_ENABLE 0x00008000
+/* 1 = Assert interrupt at rising edge of R/B_ */
+#define REG_UMI_NAND_ECC_CSR_RBINT_ENABLE 0x00004000
+/* Calculate ECC by 0=512 bytes, 1=256 bytes */
+#define REG_UMI_NAND_ECC_CSR_256BYTE 0x00000080
+/* Enable ECC in hardware */
+#define REG_UMI_NAND_ECC_CSR_ECC_ENABLE 0x00000001
+
+/* REG_UMI_BCH_CTRL_STATUS bits */
+/* Shift to Indicate Number of correctable errors detected */
+#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR_SHIFT 20
+/* Indicate Number of correctable errors detected */
+#define REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR 0x00F00000
+/* Indicate Errors detected during read but uncorrectable */
+#define REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR 0x00080000
+/* Indicate Errors detected during read and are correctable */
+#define REG_UMI_BCH_CTRL_STATUS_CORR_ERR 0x00040000
+/* Flag indicates BCH's ECC status of read process are valid */
+#define REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID 0x00020000
+/* Flag indicates BCH's ECC status of write process are valid */
+#define REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID 0x00010000
+/* Pause ECC calculation */
+#define REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC 0x00000010
+/* Enable Interrupt */
+#define REG_UMI_BCH_CTRL_STATUS_INT_EN 0x00000004
+/* Enable ECC during read */
+#define REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN 0x00000002
+/* Enable ECC during write */
+#define REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN 0x00000001
+/* Mask for location */
+#define REG_UMI_BCH_ERR_LOC_MASK 0x00001FFF
+/* location within a byte */
+#define REG_UMI_BCH_ERR_LOC_BYTE 0x00000007
+/* location within a word */
+#define REG_UMI_BCH_ERR_LOC_WORD 0x00000018
+/* location within a page (512 byte) */
+#define REG_UMI_BCH_ERR_LOC_PAGE 0x00001FE0
+#define REG_UMI_BCH_ERR_LOC_ADDR(index) (__REG32(HW_UMI_BASE + 0x64 + (index / 2)*4) >> ((index % 2) * 16))
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
new file mode 100644
index 00000000..38b37060
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/system.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/csp/chipcHw_inline.h>
+
+extern int bcmring_arch_warm_reboot;
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
+
+ if (mode == 'h') {
+ /* Reboot configured in proc entry */
+ if (bcmring_arch_warm_reboot) {
+ printk("warm reset\n");
+ /* Issue Warm reset (do not reset ethernet switch, keep alive) */
+ chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_WARM);
+ } else {
+ /* Force reset of everything */
+ printk("force reset\n");
+ chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+ }
+ } else {
+ /* Force reset of everything */
+ printk("force reset\n");
+ chipcHw_reset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
+ }
+}
+
+#endif
diff --git a/arch/arm/mach-bcmring/include/mach/timer.h b/arch/arm/mach-bcmring/include/mach/timer.h
new file mode 100644
index 00000000..5a94bbb0
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timer.h
@@ -0,0 +1,77 @@
+/*****************************************************************************
+* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+/*
+*
+*****************************************************************************
+*
+* timer.h
+*
+* PURPOSE:
+*
+*
+*
+* NOTES:
+*
+*****************************************************************************/
+
+#if !defined(BCM_LINUX_TIMER_H)
+#define BCM_LINUX_TIMER_H
+
+#if defined(__KERNEL__)
+
+/* ---- Include Files ---------------------------------------------------- */
+/* ---- Constants and Types ---------------------------------------------- */
+
+typedef unsigned int timer_tick_count_t;
+typedef unsigned int timer_tick_rate_t;
+typedef unsigned int timer_msec_t;
+
+/* ---- Variable Externs ------------------------------------------------- */
+/* ---- Function Prototypes ---------------------------------------------- */
+
+/****************************************************************************
+*
+* timer_get_tick_count
+*
+*
+***************************************************************************/
+timer_tick_count_t timer_get_tick_count(void);
+
+/****************************************************************************
+*
+* timer_get_tick_rate
+*
+*
+***************************************************************************/
+timer_tick_rate_t timer_get_tick_rate(void);
+
+/****************************************************************************
+*
+* timer_get_msec
+*
+*
+***************************************************************************/
+timer_msec_t timer_get_msec(void);
+
+/****************************************************************************
+*
+* timer_ticks_to_msec
+*
+*
+***************************************************************************/
+timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks);
+
+#endif /* __KERNEL__ */
+#endif /* BCM_LINUX_TIMER_H */
diff --git a/arch/arm/mach-bcmring/include/mach/timex.h b/arch/arm/mach-bcmring/include/mach/timex.h
new file mode 100644
index 00000000..40d033ec
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/timex.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Integrator architecture timex specifications
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+/*
+ * Specifies the number of ticks per second
+ */
+#define CLOCK_TICK_RATE 100000 /* REG_SMT_TICKS_PER_SEC */
diff --git a/arch/arm/mach-bcmring/include/mach/uncompress.h b/arch/arm/mach-bcmring/include/mach/uncompress.h
new file mode 100644
index 00000000..9c9821b7
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/uncompress.h
@@ -0,0 +1,43 @@
+/*****************************************************************************
+* Copyright 2005 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+#include <mach/csp/mm_addr.h>
+
+#define BCMRING_UART_0_DR (*(volatile unsigned int *)MM_ADDR_IO_UARTA)
+#define BCMRING_UART_0_FR (*(volatile unsigned int *)(MM_ADDR_IO_UARTA + 0x18))
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ /* Send out UARTA */
+ while (BCMRING_UART_0_FR & (1 << 5))
+ ;
+
+ BCMRING_UART_0_DR = c;
+}
+
+
+static inline void flush(void)
+{
+ /* Wait for the tx fifo to be empty */
+ while ((BCMRING_UART_0_FR & (1 << 7)) == 0)
+ ;
+
+ /* Wait for the final character to be sent on the txd line */
+ while (BCMRING_UART_0_FR & (1 << 3))
+ ;
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-bcmring/include/mach/vmalloc.h b/arch/arm/mach-bcmring/include/mach/vmalloc.h
new file mode 100644
index 00000000..7397bd78
--- /dev/null
+++ b/arch/arm/mach-bcmring/include/mach/vmalloc.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+
+/*
+ * Move VMALLOC_END to 0xf0000000 so that the vm space can range from
+ * 0xe0000000 to 0xefffffff. This gives us 256 MB of vm space and handles
+ * larger physical memory designs better.
+ */
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
new file mode 100644
index 00000000..c48feaf4
--- /dev/null
+++ b/arch/arm/mach-bcmring/irq.c
@@ -0,0 +1,127 @@
+/*
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/version.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <mach/csp/intcHw_reg.h>
+#include <mach/csp/mm_io.h>
+
+static void bcmring_mask_irq0(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_INTC0_START),
+ MM_IO_BASE_INTC0 + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq0(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_INTC0_START),
+ MM_IO_BASE_INTC0 + INTCHW_INTENABLE);
+}
+
+static void bcmring_mask_irq1(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_INTC1_START),
+ MM_IO_BASE_INTC1 + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq1(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_INTC1_START),
+ MM_IO_BASE_INTC1 + INTCHW_INTENABLE);
+}
+
+static void bcmring_mask_irq2(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_SINTC_START),
+ MM_IO_BASE_SINTC + INTCHW_INTENCLEAR);
+}
+
+static void bcmring_unmask_irq2(struct irq_data *d)
+{
+ writel(1 << (d->irq - IRQ_SINTC_START),
+ MM_IO_BASE_SINTC + INTCHW_INTENABLE);
+}
+
+static struct irq_chip bcmring_irq0_chip = {
+ .name = "ARM-INTC0",
+ .irq_ack = bcmring_mask_irq0,
+ .irq_mask = bcmring_mask_irq0, /* mask a specific interrupt, blocking its delivery. */
+ .irq_unmask = bcmring_unmask_irq0, /* unmaks an interrupt */
+};
+
+static struct irq_chip bcmring_irq1_chip = {
+ .name = "ARM-INTC1",
+ .irq_ack = bcmring_mask_irq1,
+ .irq_mask = bcmring_mask_irq1,
+ .irq_unmask = bcmring_unmask_irq1,
+};
+
+static struct irq_chip bcmring_irq2_chip = {
+ .name = "ARM-SINTC",
+ .irq_ack = bcmring_mask_irq2,
+ .irq_mask = bcmring_mask_irq2,
+ .irq_unmask = bcmring_unmask_irq2,
+};
+
+static void vic_init(void __iomem *base, struct irq_chip *chip,
+ unsigned int irq_start, unsigned int vic_sources)
+{
+ unsigned int i;
+ for (i = 0; i < 32; i++) {
+ unsigned int irq = irq_start + i;
+ irq_set_chip(irq, chip);
+ irq_set_chip_data(irq, base);
+
+ if (vic_sources & (1 << i)) {
+ irq_set_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+ writel(0, base + INTCHW_INTSELECT);
+ writel(0, base + INTCHW_INTENABLE);
+ writel(~0, base + INTCHW_INTENCLEAR);
+ writel(0, base + INTCHW_IRQSTATUS);
+ writel(~0, base + INTCHW_SOFTINTCLEAR);
+}
+
+void __init bcmring_init_irq(void)
+{
+ vic_init((void __iomem *)MM_IO_BASE_INTC0, &bcmring_irq0_chip,
+ IRQ_INTC0_START, IRQ_INTC0_VALID_MASK);
+ vic_init((void __iomem *)MM_IO_BASE_INTC1, &bcmring_irq1_chip,
+ IRQ_INTC1_START, IRQ_INTC1_VALID_MASK);
+ vic_init((void __iomem *)MM_IO_BASE_SINTC, &bcmring_irq2_chip,
+ IRQ_SINTC_START, IRQ_SINTC_VALID_MASK);
+
+ /* special cases */
+ if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) {
+ irq_set_handler(IRQ_GPIO0, handle_simple_irq);
+ }
+ if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) {
+ irq_set_handler(IRQ_GPIO1, handle_simple_irq);
+ }
+}
diff --git a/arch/arm/mach-bcmring/mm.c b/arch/arm/mach-bcmring/mm.c
new file mode 100644
index 00000000..0f1c37e4
--- /dev/null
+++ b/arch/arm/mach-bcmring/mm.c
@@ -0,0 +1,56 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/csp/mm_io.h>
+
+#define IO_DESC(va, sz) { .virtual = va, \
+ .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
+ .length = sz, \
+ .type = MT_DEVICE }
+
+#define MEM_DESC(va, sz) { .virtual = va, \
+ .pfn = __phys_to_pfn(HW_IO_VIRT_TO_PHYS(va)), \
+ .length = sz, \
+ .type = MT_MEMORY }
+
+static struct map_desc bcmring_io_desc[] __initdata = {
+ IO_DESC(MM_IO_BASE_NAND, SZ_64K), /* phys:0x28000000-0x28000FFF virt:0xE8000000-0xE8000FFF size:0x00010000 */
+ IO_DESC(MM_IO_BASE_UMI, SZ_64K), /* phys:0x2C000000-0x2C000FFF virt:0xEC000000-0xEC000FFF size:0x00010000 */
+
+ IO_DESC(MM_IO_BASE_BROM, SZ_64K), /* phys:0x30000000-0x3000FFFF virt:0xF3000000-0xF300FFFF size:0x00010000 */
+ MEM_DESC(MM_IO_BASE_ARAM, SZ_1M), /* phys:0x31000000-0x31FFFFFF virt:0xF3100000-0xF31FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_DMA0, SZ_1M), /* phys:0x32000000-0x32FFFFFF virt:0xF3200000-0xF32FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_DMA1, SZ_1M), /* phys:0x33000000-0x33FFFFFF virt:0xF3300000-0xF33FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_ESW, SZ_1M), /* phys:0x34000000-0x34FFFFFF virt:0xF3400000-0xF34FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_CLCD, SZ_1M), /* phys:0x35000000-0x35FFFFFF virt:0xF3500000-0xF35FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_APM, SZ_1M), /* phys:0x36000000-0x36FFFFFF virt:0xF3600000-0xF36FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_SPUM, SZ_1M), /* phys:0x37000000-0x37FFFFFF virt:0xF3700000-0xF37FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_VPM_PROG, SZ_1M), /* phys:0x38000000-0x38FFFFFF virt:0xF3800000-0xF38FFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_VPM_DATA, SZ_1M), /* phys:0x3A000000-0x3AFFFFFF virt:0xF3A00000-0xF3AFFFFF size:0x01000000 */
+
+ IO_DESC(MM_IO_BASE_VRAM, SZ_64K), /* phys:0x40000000-0x4000FFFF virt:0xF4000000-0xF400FFFF size:0x00010000 */
+ IO_DESC(MM_IO_BASE_CHIPC, SZ_16M), /* phys:0x80000000-0x80FFFFFF virt:0xF8000000-0xF8FFFFFF size:0x01000000 */
+ IO_DESC(MM_IO_BASE_VPM_EXTMEM_RSVD,
+ SZ_16M), /* phys:0x0F000000-0x0FFFFFFF virt:0xF0000000-0xF0FFFFFF size:0x01000000 */
+};
+
+void __init bcmring_map_io(void)
+{
+
+ iotable_init(bcmring_io_desc, ARRAY_SIZE(bcmring_io_desc));
+}
diff --git a/arch/arm/mach-bcmring/timer.c b/arch/arm/mach-bcmring/timer.c
new file mode 100644
index 00000000..2d415d2a
--- /dev/null
+++ b/arch/arm/mach-bcmring/timer.c
@@ -0,0 +1,62 @@
+/*****************************************************************************
+* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.
+*
+* Unless you and Broadcom execute a separate written software license
+* agreement governing use of this software, this software is licensed to you
+* under the terms of the GNU General Public License version 2, available at
+* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
+*
+* Notwithstanding the above, under no circumstances may you combine this
+* software in any way with any other Broadcom software provided under a
+* license other than the GPL, without Broadcom's express prior written
+* consent.
+*****************************************************************************/
+
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <csp/tmrHw.h>
+
+#include <mach/timer.h>
+/* The core.c file initializes timers 1 and 3 as a linux clocksource. */
+/* The real time clock should probably be the real linux clocksource. */
+/* In the meantime, this file should agree with core.c as to the */
+/* profiling timer. If the clocksource is moved to rtc later, then */
+/* we can init the profiling timer here instead. */
+
+/* Timer 1 provides 25MHz resolution syncrhonized to scheduling and APM timing */
+/* Timer 3 provides bus freqeuncy sychronized to ACLK, but spread spectrum will */
+/* affect synchronization with scheduling and APM timing. */
+
+#define PROF_TIMER 1
+
+timer_tick_rate_t timer_get_tick_rate(void)
+{
+ return tmrHw_getCountRate(PROF_TIMER);
+}
+
+timer_tick_count_t timer_get_tick_count(void)
+{
+ return tmrHw_GetCurrentCount(PROF_TIMER); /* change downcounter to upcounter */
+}
+
+timer_msec_t timer_ticks_to_msec(timer_tick_count_t ticks)
+{
+ static int tickRateMsec;
+
+ if (tickRateMsec == 0) {
+ tickRateMsec = timer_get_tick_rate() / 1000;
+ }
+
+ return ticks / tickRateMsec;
+}
+
+timer_msec_t timer_get_msec(void)
+{
+ return timer_ticks_to_msec(timer_get_tick_count());
+}
+
+EXPORT_SYMBOL(timer_get_tick_count);
+EXPORT_SYMBOL(timer_ticks_to_msec);
+EXPORT_SYMBOL(timer_get_tick_rate);
+EXPORT_SYMBOL(timer_get_msec);
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
new file mode 100644
index 00000000..eb34bd12
--- /dev/null
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -0,0 +1,77 @@
+if ARCH_CLPS711X
+
+menu "CLPS711X/EP721X Implementations"
+
+config ARCH_AUTCPU12
+ bool "AUTCPU12"
+ help
+ Say Y if you intend to run the kernel on the autronix autcpu12
+ board. This board is based on a Cirrus Logic CS89712.
+
+config ARCH_CDB89712
+ bool "CDB89712"
+ select ISA
+ help
+ This is an evaluation board from Cirrus for the CS89712 processor.
+ The board includes 2 serial ports, Ethernet, IRDA, and expansion
+ headers. It comes with 16 MB SDRAM and 8 MB flash ROM.
+
+config ARCH_CEIVA
+ bool "CEIVA"
+ help
+ Say Y here if you intend to run this kernel on the Ceiva/Polaroid
+ PhotoMax Digital Picture Frame.
+
+config ARCH_CLEP7312
+ bool "CLEP7312"
+ help
+ Boards based on the Cirrus Logic 7212/7312 chips.
+
+config ARCH_EDB7211
+ bool "EDB7211"
+ select ISA
+ select ARCH_SPARSEMEM_ENABLE
+ select ARCH_SELECT_MEMORY_MODEL
+ help
+ Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211
+ evaluation board.
+
+config ARCH_P720T
+ bool "P720T"
+ help
+ Say Y here if you intend to run this kernel on the ARM Prospector
+ 720T.
+
+config ARCH_FORTUNET
+ bool "FORTUNET"
+
+# XXX Maybe these should indicate register compatibility
+# instead of being mutually exclusive.
+config ARCH_EP7211
+ bool
+ depends on ARCH_EDB7211
+ default y
+
+config ARCH_EP7212
+ bool
+ depends on ARCH_P720T || ARCH_CEIVA
+ default y
+
+config EP72XX_ROM_BOOT
+ bool "EP72xx ROM boot"
+ depends on ARCH_EP7211 || ARCH_EP7212
+ ---help---
+ If you say Y here, your CLPS711x-based kernel will use the bootstrap
+ mode memory map instead of the normal memory map.
+
+ Processors derived from the Cirrus CLPS-711X core support two boot
+ modes. Normal mode boots from the external memory device at CS0.
+ Bootstrap mode rearranges parts of the memory map, placing an
+ internal 128 byte bootstrap ROM at CS0. This option performs the
+ address map changes required to support booting in this mode.
+
+ You almost surely want to say N here.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-clps711x/Makefile b/arch/arm/mach-clps711x/Makefile
new file mode 100644
index 00000000..4a197315
--- /dev/null
+++ b/arch/arm/mach-clps711x/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := irq.o mm.o time.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_CEIVA) += ceiva.o
+obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o
+obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
+obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
+obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
+obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
+obj-$(CONFIG_ARCH_P720T) += p720t.o
+leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
+obj-$(CONFIG_LEDS) += $(leds-y)
diff --git a/arch/arm/mach-clps711x/Makefile.boot b/arch/arm/mach-clps711x/Makefile.boot
new file mode 100644
index 00000000..a51fcef6
--- /dev/null
+++ b/arch/arm/mach-clps711x/Makefile.boot
@@ -0,0 +1,6 @@
+# The standard locations for stuff on CLPS711x type processors
+ zreladdr-y := 0xc0028000
+params_phys-y := 0xc0000100
+# Should probably have some agreement on these...
+initrd_phys-$(CONFIG_ARCH_P720T) := 0xc0400000
+initrd_phys-$(CONFIG_ARCH_CDB89712) := 0x00700000
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
new file mode 100644
index 00000000..4a74b2c9
--- /dev/null
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/arm/mach-clps711x/autcpu12.c
+ *
+ * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <mach/autcpu12.h>
+
+#include "common.h"
+
+/*
+ * The on-chip registers are given a size of 1MB so that a section can
+ * be used to map them; this saves a page table. This is the place to
+ * add mappings for ROM, expansion memory, PCMCIA, etc. (if static
+ * mappings are chosen for those areas).
+ *
+*/
+
+static struct map_desc autcpu12_io_desc[] __initdata = {
+ /* memory-mapped extra io and CS8900A Ethernet chip */
+ /* ethernet chip */
+ {
+ .virtual = AUTCPU12_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(AUTCPU12_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
+};
+
+void __init autcpu12_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(autcpu12_io_desc, ARRAY_SIZE(autcpu12_io_desc));
+}
+
+MACHINE_START(AUTCPU12, "autronix autcpu12")
+ /* Maintainer: Thomas Gleixner */
+ .boot_params = 0xc0020000,
+ .map_io = autcpu12_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c
new file mode 100644
index 00000000..5a1689d4
--- /dev/null
+++ b/arch/arm/mach-clps711x/cdb89712.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-clps711x/cdb89712.c
+ *
+ * Copyright (C) 2000-2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+/*
+ * Map the CS89712 Ethernet port. That should be moved to the
+ * ethernet driver, perhaps.
+ */
+static struct map_desc cdb89712_io_desc[] __initdata = {
+ {
+ .virtual = ETHER_BASE,
+ .pfn =__phys_to_pfn(ETHER_START),
+ .length = ETHER_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init cdb89712_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(cdb89712_io_desc, ARRAY_SIZE(cdb89712_io_desc));
+}
+
+MACHINE_START(CDB89712, "Cirrus-CDB89712")
+ /* Maintainer: Ray Lehtiniemi */
+ .boot_params = 0xc0000100,
+ .map_io = cdb89712_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c
new file mode 100644
index 00000000..16481cf3
--- /dev/null
+++ b/arch/arm/mach-clps711x/ceiva.c
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/arm/mach-clps711x/arch-ceiva.c
+ *
+ * Copyright (C) 2002, Rob Scott <rscott@mtrob.fdns.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <linux/kernel.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+static struct map_desc ceiva_io_desc[] __initdata = {
+ /* SED1355 controlled video RAM & registers */
+ {
+ .virtual = CEIVA_VIRT_SED1355,
+ .pfn = __phys_to_pfn(CEIVA_PHYS_SED1355),
+ .length = SZ_2M,
+ .type = MT_DEVICE
+ }
+};
+
+
+static void __init ceiva_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(ceiva_io_desc, ARRAY_SIZE(ceiva_io_desc));
+}
+
+
+MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame")
+ /* Maintainer: Rob Scott */
+ .boot_params = 0xc0000100,
+ .map_io = ceiva_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
new file mode 100644
index 00000000..67b5abb4
--- /dev/null
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -0,0 +1,46 @@
+/*
+ * linux/arch/arm/mach-clps711x/clep7312.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+static void __init
+fixup_clep7312(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xc0000000;
+ mi->bank[0].size = 0x01000000;
+}
+
+
+MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
+ /* Maintainer: Nobody */
+ .boot_params = 0xc0000100,
+ .fixup = fixup_clep7312,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-clps711x/common.h b/arch/arm/mach-clps711x/common.h
new file mode 100644
index 00000000..2b8b801f
--- /dev/null
+++ b/arch/arm/mach-clps711x/common.h
@@ -0,0 +1,11 @@
+/*
+ * linux/arch/arm/mach-clps711x/common.h
+ *
+ * Common bits.
+ */
+
+struct sys_timer;
+
+extern void clps711x_map_io(void);
+extern void clps711x_init_irq(void);
+extern struct sys_timer clps711x_timer;
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
new file mode 100644
index 00000000..98ca5b2e
--- /dev/null
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-clps711x/arch-edb7211.c
+ *
+ * Copyright (C) 2000, 2001 Blue Mug, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/memblock.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+extern void edb7211_map_io(void);
+
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+ memblock_reserve(PHYS_OFFSET, 0x00020000);
+}
+
+static void __init
+fixup_edb7211(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ /*
+ * Bank start addresses are not present in the information
+ * passed in from the boot loader. We could potentially
+ * detect them, but instead we hard-code them.
+ *
+ * Banks sizes _are_ present in the param block, but we're
+ * not using that information yet.
+ */
+ mi->bank[0].start = 0xc0000000;
+ mi->bank[0].size = 8*1024*1024;
+ mi->bank[1].start = 0xc1000000;
+ mi->bank[1].size = 8*1024*1024;
+ mi->nr_banks = 2;
+}
+
+MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
+ /* Maintainer: Jon McClintock */
+ .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */
+ .fixup = fixup_edb7211,
+ .map_io = edb7211_map_io,
+ .reserve = edb7211_reserve,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/edb7211-mm.c b/arch/arm/mach-clps711x/edb7211-mm.c
new file mode 100644
index 00000000..0bea1454
--- /dev/null
+++ b/arch/arm/mach-clps711x/edb7211-mm.c
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/arm/mach-clps711x/mm.c
+ *
+ * Extra MM routines for the EDB7211 board
+ *
+ * Copyright (C) 2000, 2001 Blue Mug, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/map.h>
+
+extern void clps711x_map_io(void);
+
+/*
+ * The on-chip registers are given a size of 1MB so that a section can
+ * be used to map them; this saves a page table. This is the place to
+ * add mappings for ROM, expansion memory, PCMCIA, etc. (if static
+ * mappings are chosen for those areas).
+ *
+ * Here is a physical memory map (to be fleshed out later):
+ *
+ * Physical Address Size Description
+ * ----------------- ----- ---------------------------------
+ * c0000000-c001ffff 128KB reserved for video RAM [1]
+ * c0020000-c0023fff 16KB parameters (see Documentation/arm/Setup)
+ * c0024000-c0027fff 16KB swapper_pg_dir (task 0 page directory)
+ * c0028000-... kernel image (TEXTADDR)
+ *
+ * [1] Unused pages should be given back to the VM; they are not yet.
+ * The parameter block should also be released (not sure if this
+ * happens).
+ */
+static struct map_desc edb7211_io_desc[] __initdata = {
+ { /* memory-mapped extra keyboard row */
+ .virtual = EP7211_VIRT_EXTKBD,
+ .pfn = __phys_to_pfn(EP7211_PHYS_EXTKBD),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, { /* and CS8900A Ethernet chip */
+ .virtual = EP7211_VIRT_CS8900A,
+ .pfn = __phys_to_pfn(EP7211_PHYS_CS8900A),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, { /* flash banks */
+ .virtual = EP7211_VIRT_FLASH1,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH1),
+ .length = SZ_8M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = EP7211_VIRT_FLASH2,
+ .pfn = __phys_to_pfn(EP7211_PHYS_FLASH2),
+ .length = SZ_8M,
+ .type = MT_DEVICE,
+ }
+};
+
+void __init edb7211_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(edb7211_io_desc, ARRAY_SIZE(edb7211_io_desc));
+}
+
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
new file mode 100644
index 00000000..b1cb479e
--- /dev/null
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-clps711x/fortunet.c
+ *
+ * Derived from linux/arch/arm/mach-integrator/arch.c
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/initrd.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include <asm/memory.h>
+
+#include "common.h"
+
+struct meminfo memmap = {
+ .nr_banks = 1,
+ .bank = {
+ {
+ .start = 0xC0000000,
+ .size = 0x01000000,
+ },
+ },
+};
+
+typedef struct tag_IMAGE_PARAMS
+{
+ int ramdisk_ok;
+ int ramdisk_address;
+ int ramdisk_size;
+ int ram_size;
+ int extra_param_type;
+ int extra_param_ptr;
+ int command_line;
+} IMAGE_PARAMS;
+
+#define IMAGE_PARAMS_PHYS 0xC01F0000
+
+static void __init
+fortunet_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ IMAGE_PARAMS *ip = phys_to_virt(IMAGE_PARAMS_PHYS);
+ *cmdline = phys_to_virt(ip->command_line);
+#ifdef CONFIG_BLK_DEV_INITRD
+ if(ip->ramdisk_ok)
+ {
+ initrd_start = __phys_to_virt(ip->ramdisk_address);
+ initrd_end = initrd_start + ip->ramdisk_size;
+ }
+#endif
+ memmap.bank[0].size = ip->ram_size;
+ *mi = memmap;
+}
+
+MACHINE_START(FORTUNET, "ARM-FortuNet")
+ /* Maintainer: FortuNet Inc. */
+ .boot_params = 0x00000000,
+ .fixup = fortunet_fixup,
+ .map_io = clps711x_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-clps711x/include/mach/autcpu12.h b/arch/arm/mach-clps711x/include/mach/autcpu12.h
new file mode 100644
index 00000000..1588a365
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/autcpu12.h
@@ -0,0 +1,78 @@
+/*
+ * AUTCPU12 specific defines
+ *
+ * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_ARCH_AUTCPU12_H
+#define __ASM_ARCH_AUTCPU12_H
+
+/*
+ * The CS8900A ethernet chip has its I/O registers wired to chip select 2
+ * (nCS2). This is the mapping for it.
+ */
+#define AUTCPU12_PHYS_CS8900A CS2_PHYS_BASE /* physical */
+#define AUTCPU12_VIRT_CS8900A (0xfe000000) /* virtual */
+
+/*
+ * The flash bank is wired to chip select 0
+ */
+#define AUTCPU12_PHYS_FLASH CS0_PHYS_BASE /* physical */
+
+/* offset for device specific information structure */
+#define AUTCPU12_LCDINFO_OFFS (0x00010000)
+/*
+* Videomemory is the internal SRAM (CS 6)
+*/
+#define AUTCPU12_PHYS_VIDEO CS6_PHYS_BASE
+#define AUTCPU12_VIRT_VIDEO (0xfd000000)
+
+/*
+* All special IO's are tied to CS1
+*/
+#define AUTCPU12_PHYS_CHAR_LCD CS1_PHYS_BASE +0x00000000 /* physical */
+
+#define AUTCPU12_PHYS_NVRAM CS1_PHYS_BASE +0x02000000 /* physical */
+
+#define AUTCPU12_PHYS_CSAUX1 CS1_PHYS_BASE +0x04000000 /* physical */
+
+#define AUTCPU12_PHYS_SMC CS1_PHYS_BASE +0x06000000 /* physical */
+
+#define AUTCPU12_PHYS_CAN CS1_PHYS_BASE +0x08000000 /* physical */
+
+#define AUTCPU12_PHYS_TOUCH CS1_PHYS_BASE +0x0A000000 /* physical */
+
+#define AUTCPU12_PHYS_IO CS1_PHYS_BASE +0x0C000000 /* physical */
+
+#define AUTCPU12_PHYS_LPT CS1_PHYS_BASE +0x0E000000 /* physical */
+
+/*
+* defines for smartmedia card access
+*/
+#define AUTCPU12_SMC_RDY (1<<2)
+#define AUTCPU12_SMC_ALE (1<<3)
+#define AUTCPU12_SMC_CLE (1<<4)
+#define AUTCPU12_SMC_PORT_OFFSET PBDR
+#define AUTCPU12_SMC_SELECT_OFFSET 0x10
+/*
+* defines for lcd contrast
+*/
+#define AUTCPU12_DPOT_PORT_OFFSET PEDR
+#define AUTCPU12_DPOT_CS (1<<0)
+#define AUTCPU12_DPOT_CLK (1<<1)
+#define AUTCPU12_DPOT_UD (1<<2)
+
+#endif
diff --git a/arch/arm/mach-clps711x/include/mach/debug-macro.S b/arch/arm/mach-clps711x/include/mach/debug-macro.S
new file mode 100644
index 00000000..507c6873
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/debug-macro.S
@@ -0,0 +1,45 @@
+/* arch/arm/mach-clps711x/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <mach/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+ .macro addruart, rp, rv
+#ifndef CONFIG_DEBUG_CLPS711X_UART2
+ mov \rp, #0x0000 @ UART1
+#else
+ mov \rp, #0x1000 @ UART2
+#endif
+ orr \rv, \rp, #CLPS7111_VIRT_BASE
+ orr \rp, \rp, #CLPS7111_PHYS_BASE
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x0480] @ UARTDR
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x0140] @ SYSFLGx
+ tst \rd, #1 << 11 @ UBUSYx
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+ tst \rx, #0x1000 @ UART2 does not have CTS here
+ bne 1002f
+1001: ldr \rd, [\rx, #0x0140] @ SYSFLGx
+ tst \rd, #1 << 8 @ CTS
+ bne 1001b
+1002:
+ .endm
+
diff --git a/arch/arm/mach-clps711x/include/mach/entry-macro.S b/arch/arm/mach-clps711x/include/mach/entry-macro.S
new file mode 100644
index 00000000..90fa2f70
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/entry-macro.S
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for CLPS711X-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+#if (INTSR2 - INTSR1) != (INTMR2 - INTMR1)
+#error INTSR stride != INTMR stride
+#endif
+
+ .macro get_irqnr_and_base, irqnr, stat, base, mask
+ mov \base, #CLPS7111_BASE
+ ldr \stat, [\base, #INTSR1]
+ ldr \mask, [\base, #INTMR1]
+ mov \irqnr, #4
+ mov \mask, \mask, lsl #16
+ and \stat, \stat, \mask, lsr #16
+ movs \stat, \stat, lsr #4
+ bne 1001f
+
+ add \base, \base, #INTSR2 - INTSR1
+ ldr \stat, [\base, #INTSR1]
+ ldr \mask, [\base, #INTMR1]
+ mov \irqnr, #16
+ mov \mask, \mask, lsl #16
+ and \stat, \stat, \mask, lsr #16
+
+1001: tst \stat, #255
+ addeq \irqnr, \irqnr, #8
+ moveq \stat, \stat, lsr #8
+ tst \stat, #15
+ addeq \irqnr, \irqnr, #4
+ moveq \stat, \stat, lsr #4
+ tst \stat, #3
+ addeq \irqnr, \irqnr, #2
+ moveq \stat, \stat, lsr #2
+ tst \stat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \stat, \stat, lsr #1
+ tst \stat, #1 @ bit 0 should be set
+ .endm
+
+
diff --git a/arch/arm/mach-clps711x/include/mach/hardware.h b/arch/arm/mach-clps711x/include/mach/hardware.h
new file mode 100644
index 00000000..d0b7d870
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/hardware.h
@@ -0,0 +1,208 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/hardware.h
+ *
+ * This file contains the hardware definitions of the Prospector P720T.
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+
+#define CLPS7111_VIRT_BASE 0xff000000
+#define CLPS7111_BASE CLPS7111_VIRT_BASE
+
+/*
+ * The physical addresses that the external chip select signals map to is
+ * dependent on the setting of the nMEDCHG signal on EP7211 and EP7212
+ * processors. CONFIG_EP72XX_BOOT_ROM is only available if these
+ * processors are in use.
+ */
+#ifndef CONFIG_EP72XX_ROM_BOOT
+#define CS0_PHYS_BASE (0x00000000)
+#define CS1_PHYS_BASE (0x10000000)
+#define CS2_PHYS_BASE (0x20000000)
+#define CS3_PHYS_BASE (0x30000000)
+#define CS4_PHYS_BASE (0x40000000)
+#define CS5_PHYS_BASE (0x50000000)
+#define CS6_PHYS_BASE (0x60000000)
+#define CS7_PHYS_BASE (0x70000000)
+#else
+#define CS0_PHYS_BASE (0x70000000)
+#define CS1_PHYS_BASE (0x60000000)
+#define CS2_PHYS_BASE (0x50000000)
+#define CS3_PHYS_BASE (0x40000000)
+#define CS4_PHYS_BASE (0x30000000)
+#define CS5_PHYS_BASE (0x20000000)
+#define CS6_PHYS_BASE (0x10000000)
+#define CS7_PHYS_BASE (0x00000000)
+#endif
+
+#if defined (CONFIG_ARCH_EP7211)
+
+#define EP7211_VIRT_BASE CLPS7111_VIRT_BASE
+#define EP7211_BASE CLPS7111_VIRT_BASE
+#include <asm/hardware/ep7211.h>
+
+#elif defined (CONFIG_ARCH_EP7212)
+
+#define EP7212_VIRT_BASE CLPS7111_VIRT_BASE
+#define EP7212_BASE CLPS7111_VIRT_BASE
+#include <asm/hardware/ep7212.h>
+
+#endif
+
+#define SYSPLD_VIRT_BASE 0xfe000000
+#define SYSPLD_BASE SYSPLD_VIRT_BASE
+
+#if defined (CONFIG_ARCH_AUTCPU12)
+
+#define CS89712_VIRT_BASE CLPS7111_VIRT_BASE
+#define CS89712_BASE CLPS7111_VIRT_BASE
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+#include <asm/hardware/cs89712.h>
+
+#endif
+
+
+#if defined (CONFIG_ARCH_CDB89712)
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+#include <asm/hardware/cs89712.h>
+
+/* static cdb89712_map_io() areas */
+#define REGISTER_START 0x80000000
+#define REGISTER_SIZE 0x4000
+#define REGISTER_BASE 0xff000000
+
+#define ETHER_START 0x20000000
+#define ETHER_SIZE 0x1000
+#define ETHER_BASE 0xfe000000
+
+#endif
+
+
+#if defined (CONFIG_ARCH_EDB7211)
+
+/*
+ * The extra 8 lines of the keyboard matrix are wired to chip select 3 (nCS3)
+ * and repeat across it. This is the mapping for it.
+ *
+ * In jumpered boot mode, nCS3 is mapped to 0x4000000, not 0x3000000. This
+ * was cause for much consternation and headscratching. This should probably
+ * be made a compile/run time kernel option.
+ */
+#define EP7211_PHYS_EXTKBD CS3_PHYS_BASE /* physical */
+
+#define EP7211_VIRT_EXTKBD (0xfd000000) /* virtual */
+
+
+/*
+ * The CS8900A ethernet chip has its I/O registers wired to chip select 2
+ * (nCS2). This is the mapping for it.
+ *
+ * In jumpered boot mode, nCS2 is mapped to 0x5000000, not 0x2000000. This
+ * was cause for much consternation and headscratching. This should probably
+ * be made a compile/run time kernel option.
+ */
+#define EP7211_PHYS_CS8900A CS2_PHYS_BASE /* physical */
+
+#define EP7211_VIRT_CS8900A (0xfc000000) /* virtual */
+
+
+/*
+ * The two flash banks are wired to chip selects 0 and 1. This is the mapping
+ * for them.
+ *
+ * nCS0 and nCS1 are at 0x70000000 and 0x60000000, respectively, when running
+ * in jumpered boot mode.
+ */
+#define EP7211_PHYS_FLASH1 CS0_PHYS_BASE /* physical */
+#define EP7211_PHYS_FLASH2 CS1_PHYS_BASE /* physical */
+
+#define EP7211_VIRT_FLASH1 (0xfa000000) /* virtual */
+#define EP7211_VIRT_FLASH2 (0xfb000000) /* virtual */
+
+#endif /* CONFIG_ARCH_EDB7211 */
+
+
+/*
+ * Relevant bits in port D, which controls power to the various parts of
+ * the LCD on the EDB7211.
+ */
+#define EDB_PD1_LCD_DC_DC_EN (1<<1)
+#define EDB_PD2_LCDEN (1<<2)
+#define EDB_PD3_LCDBL (1<<3)
+
+
+#if defined (CONFIG_ARCH_CEIVA)
+
+#define CEIVA_VIRT_BASE CLPS7111_VIRT_BASE
+#define CEIVA_BASE CLPS7111_VIRT_BASE
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+
+
+/*
+ * The two flash banks are wired to chip selects 0 and 1. This is the mapping
+ * for them.
+ *
+ * nCS0 and nCS1 are at 0x70000000 and 0x60000000, respectively, when running
+ * in jumpered boot mode.
+ */
+#define CEIVA_PHYS_FLASH1 CS0_PHYS_BASE /* physical */
+#define CEIVA_PHYS_FLASH2 CS1_PHYS_BASE /* physical */
+
+#define CEIVA_VIRT_FLASH1 (0xfa000000) /* virtual */
+#define CEIVA_VIRT_FLASH2 (0xfb000000) /* virtual */
+
+#define CEIVA_FLASH_SIZE 0x100000
+#define CEIVA_FLASH_WIDTH 2
+
+/*
+ * SED1355 LCD controller
+ */
+#define CEIVA_PHYS_SED1355 CS2_PHYS_BASE
+#define CEIVA_VIRT_SED1355 (0xfc000000)
+
+/*
+ * Relevant bits in port D, which controls power to the various parts of
+ * the LCD on the Ceiva Photo Max, and reset to the LCD controller.
+ */
+
+// Reset line to SED1355 (must be high to operate)
+#define CEIVA_PD1_LCDRST (1<<1)
+// LCD panel enable (set to one, to enable LCD)
+#define CEIVA_PD4_LCDEN (1<<4)
+// Backlight (set to one, to turn on backlight
+#define CEIVA_PD5_LCDBL (1<<5)
+
+/*
+ * Relevant bits in port B, which report the status of the buttons.
+ */
+
+// White button
+#define CEIVA_PB4_WHT_BTN (1<<4)
+// Black button
+#define CEIVA_PB0_BLK_BTN (1<<0)
+#endif // #if defined (CONFIG_ARCH_CEIVA)
+
+#endif
diff --git a/arch/arm/mach-clps711x/include/mach/io.h b/arch/arm/mach-clps711x/include/mach/io.h
new file mode 100644
index 00000000..2e0b3ced
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/io.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/io.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+/*
+ * We don't support ins[lb]/outs[lb]. Make them fault.
+ */
+#define __raw_readsb(p,d,l) do { *(int *)0 = 0; } while (0)
+#define __raw_readsl(p,d,l) do { *(int *)0 = 0; } while (0)
+#define __raw_writesb(p,d,l) do { *(int *)0 = 0; } while (0)
+#define __raw_writesl(p,d,l) do { *(int *)0 = 0; } while (0)
+
+#endif
diff --git a/arch/arm/mach-clps711x/include/mach/irqs.h b/arch/arm/mach-clps711x/include/mach/irqs.h
new file mode 100644
index 00000000..30b7e972
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/irqs.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/irqs.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+/*
+ * Interrupts from INTSR1
+ */
+#define IRQ_CSINT 4
+#define IRQ_EINT1 5
+#define IRQ_EINT2 6
+#define IRQ_EINT3 7
+#define IRQ_TC1OI 8
+#define IRQ_TC2OI 9
+#define IRQ_RTCMI 10
+#define IRQ_TINT 11
+#define IRQ_UTXINT1 12
+#define IRQ_URXINT1 13
+#define IRQ_UMSINT 14
+#define IRQ_SSEOTI 15
+
+#define INT1_IRQS (0x0000fff0)
+#define INT1_ACK_IRQS (0x00004f10)
+
+/*
+ * Interrupts from INTSR2
+ */
+#define IRQ_KBDINT (16+0) /* bit 0 */
+#define IRQ_SS2RX (16+1) /* bit 1 */
+#define IRQ_SS2TX (16+2) /* bit 2 */
+#define IRQ_UTXINT2 (16+12) /* bit 12 */
+#define IRQ_URXINT2 (16+13) /* bit 13 */
+
+#define INT2_IRQS (0x30070000)
+#define INT2_ACK_IRQS (0x00010000)
+
+#define NR_IRQS 30
+
diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h
new file mode 100644
index 00000000..3a032a67
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/memory.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/memory.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
+
+#if !defined(CONFIG_ARCH_CDB89712) && !defined (CONFIG_ARCH_AUTCPU12)
+
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
+#define __pfn_to_bus(x) (__pfn_to_phys(x) - PHYS_OFFSET)
+#define __bus_to_pfn(x) __phys_to_pfn((x) + PHYS_OFFSET)
+
+#endif
+
+
+/*
+ * Like the SA1100, the EDB7211 has a large gap between physical RAM
+ * banks. In 2.2, the Psion (CL-PS7110) port added custom support for
+ * discontiguous physical memory. In 2.4, we can use the standard
+ * Linux NUMA support.
+ *
+ * This is not necessary for EP7211 implementations with only one used
+ * memory bank. For those systems, simply undefine CONFIG_DISCONTIGMEM.
+ */
+
+/*
+ * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211
+ * uses only one of the two banks (bank #1). However, even within
+ * bank #1, memory is discontiguous.
+ *
+ * The EDB7211 has two 8MB DRAM areas with 8MB of empty space between
+ * them, so we use 24 for the node max shift to get 16MB node sizes.
+ */
+
+/*
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much more convenient to use Linux's NUMA support to implement
+ * our memory map representation. Assuming all memory nodes have equal access
+ * characteristics, we then have generic discontiguous memory support.
+ *
+ * Of course, all this isn't mandatory for SA1100 implementations with only
+ * one used memory bank. For those, simply undefine CONFIG_DISCONTIGMEM.
+ *
+ * The nodes are matched with the physical memory bank addresses which are
+ * incidentally the same as virtual addresses.
+ *
+ * node 0: 0xc0000000 - 0xc7ffffff
+ * node 1: 0xc8000000 - 0xcfffffff
+ * node 2: 0xd0000000 - 0xd7ffffff
+ * node 3: 0xd8000000 - 0xdfffffff
+ */
+#define SECTION_SIZE_BITS 24
+#define MAX_PHYSMEM_BITS 32
+
+#endif
+
diff --git a/arch/arm/mach-clps711x/include/mach/syspld.h b/arch/arm/mach-clps711x/include/mach/syspld.h
new file mode 100644
index 00000000..f7f4c120
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/syspld.h
@@ -0,0 +1,121 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/syspld.h
+ *
+ * System Control PLD register definitions.
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSPLD_H
+#define __ASM_ARCH_SYSPLD_H
+
+#define SYSPLD_PHYS_BASE (0x10000000)
+
+#ifndef __ASSEMBLY__
+#include <asm/types.h>
+
+#define SYSPLD_REG(type,off) (*(volatile type *)(SYSPLD_BASE + off))
+#else
+#define SYSPLD_REG(type,off) (off)
+#endif
+
+#define PLD_INT SYSPLD_REG(u32, 0x000000)
+#define PLD_INT_PENIRQ (1 << 5)
+#define PLD_INT_UCB_IRQ (1 << 1)
+#define PLD_INT_KBD_ATN (1 << 0) /* EINT1 */
+
+#define PLD_PWR SYSPLD_REG(u32, 0x000004)
+#define PLD_PWR_EXT (1 << 5)
+#define PLD_PWR_MODE (1 << 4) /* 1 = PWM, 0 = PFM */
+#define PLD_S4_ON (1 << 3) /* LCD bias voltage enable */
+#define PLD_S3_ON (1 << 2) /* LCD backlight enable */
+#define PLD_S2_ON (1 << 1) /* LCD 3V3 supply enable */
+#define PLD_S1_ON (1 << 0) /* LCD 3V supply enable */
+
+#define PLD_KBD SYSPLD_REG(u32, 0x000008)
+#define PLD_KBD_WAKE (1 << 1)
+#define PLD_KBD_EN (1 << 0)
+
+#define PLD_SPI SYSPLD_REG(u32, 0x00000c)
+#define PLD_SPI_EN (1 << 0)
+
+#define PLD_IO SYSPLD_REG(u32, 0x000010)
+#define PLD_IO_BOOTSEL (1 << 6) /* boot sel switch */
+#define PLD_IO_USER (1 << 5) /* user defined switch */
+#define PLD_IO_LED3 (1 << 4)
+#define PLD_IO_LED2 (1 << 3)
+#define PLD_IO_LED1 (1 << 2)
+#define PLD_IO_LED0 (1 << 1)
+#define PLD_IO_LEDEN (1 << 0)
+
+#define PLD_IRDA SYSPLD_REG(u32, 0x000014)
+#define PLD_IRDA_EN (1 << 0)
+
+#define PLD_COM2 SYSPLD_REG(u32, 0x000018)
+#define PLD_COM2_EN (1 << 0)
+
+#define PLD_COM1 SYSPLD_REG(u32, 0x00001c)
+#define PLD_COM1_EN (1 << 0)
+
+#define PLD_AUD SYSPLD_REG(u32, 0x000020)
+#define PLD_AUD_DIV1 (1 << 6)
+#define PLD_AUD_DIV0 (1 << 5)
+#define PLD_AUD_CLK_SEL1 (1 << 4)
+#define PLD_AUD_CLK_SEL0 (1 << 3)
+#define PLD_AUD_MIC_PWR (1 << 2)
+#define PLD_AUD_MIC_GAIN (1 << 1)
+#define PLD_AUD_CODEC_EN (1 << 0)
+
+#define PLD_CF SYSPLD_REG(u32, 0x000024)
+#define PLD_CF2_SLEEP (1 << 5)
+#define PLD_CF1_SLEEP (1 << 4)
+#define PLD_CF2_nPDREQ (1 << 3)
+#define PLD_CF1_nPDREQ (1 << 2)
+#define PLD_CF2_nIRQ (1 << 1)
+#define PLD_CF1_nIRQ (1 << 0)
+
+#define PLD_SDC SYSPLD_REG(u32, 0x000028)
+#define PLD_SDC_INT_EN (1 << 2)
+#define PLD_SDC_WP (1 << 1)
+#define PLD_SDC_CD (1 << 0)
+
+#define PLD_FPGA SYSPLD_REG(u32, 0x00002c)
+
+#define PLD_CODEC SYSPLD_REG(u32, 0x400000)
+#define PLD_CODEC_IRQ3 (1 << 4)
+#define PLD_CODEC_IRQ2 (1 << 3)
+#define PLD_CODEC_IRQ1 (1 << 2)
+#define PLD_CODEC_EN (1 << 0)
+
+#define PLD_BRITE SYSPLD_REG(u32, 0x400004)
+#define PLD_BRITE_UP (1 << 1)
+#define PLD_BRITE_DN (1 << 0)
+
+#define PLD_LCDEN SYSPLD_REG(u32, 0x400008)
+#define PLD_LCDEN_EN (1 << 0)
+
+#define PLD_ID SYSPLD_REG(u32, 0x40000c)
+
+#define PLD_TCH SYSPLD_REG(u32, 0x400010)
+#define PLD_TCH_PENIRQ (1 << 1)
+#define PLD_TCH_EN (1 << 0)
+
+#define PLD_GPIO SYSPLD_REG(u32, 0x400014)
+#define PLD_GPIO2 (1 << 2)
+#define PLD_GPIO1 (1 << 1)
+#define PLD_GPIO0 (1 << 0)
+
+#endif
diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h
new file mode 100644
index 00000000..f916cd7a
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/system.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/system.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+static inline void arch_idle(void)
+{
+ clps_writel(1, HALT);
+ __asm__ __volatile__(
+ "mov r0, r0\n\
+ mov r0, r0");
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+
+#endif
diff --git a/arch/arm/mach-clps711x/include/mach/time.h b/arch/arm/mach-clps711x/include/mach/time.h
new file mode 100644
index 00000000..61fef912
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/time.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/time.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <asm/leds.h>
+#include <asm/hardware/clps7111.h>
+
+extern void clps711x_setup_timer(void);
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+p720t_timer_interrupt(int irq, void *dev_id)
+{
+ struct pt_regs *regs = get_irq_regs();
+ do_leds();
+ xtime_update(1);
+#ifndef CONFIG_SMP
+ update_process_times(user_mode(regs));
+#endif
+ do_profile(regs);
+ return IRQ_HANDLED;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init time_init(void)
+{
+ clps711x_setup_timer();
+ timer_irq.handler = p720t_timer_interrupt;
+ setup_irq(IRQ_TC2OI, &timer_irq);
+}
diff --git a/arch/arm/mach-clps711x/include/mach/timex.h b/arch/arm/mach-clps711x/include/mach/timex.h
new file mode 100644
index 00000000..ac8823cc
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/timex.h
+ *
+ * Prospector 720T architecture timex specifications
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+#define CLOCK_TICK_RATE 512000
diff --git a/arch/arm/mach-clps711x/include/mach/uncompress.h b/arch/arm/mach-clps711x/include/mach/uncompress.h
new file mode 100644
index 00000000..7164310d
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/uncompress.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/uncompress.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/io.h>
+#include <mach/hardware.h>
+#include <asm/hardware/clps7111.h>
+
+#undef CLPS7111_BASE
+#define CLPS7111_BASE CLPS7111_PHYS_BASE
+
+#define __raw_readl(p) (*(unsigned long *)(p))
+#define __raw_writel(v,p) (*(unsigned long *)(p) = (v))
+
+#ifdef CONFIG_DEBUG_CLPS711X_UART2
+#define SYSFLGx SYSFLG2
+#define UARTDRx UARTDR2
+#else
+#define SYSFLGx SYSFLG1
+#define UARTDRx UARTDR1
+#endif
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ while (clps_readl(SYSFLGx) & SYSFLG_UTXFF)
+ barrier();
+ clps_writel(c, UARTDRx);
+}
+
+static inline void flush(void)
+{
+ while (clps_readl(SYSFLGx) & SYSFLG_UBUSY)
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-clps711x/include/mach/vmalloc.h b/arch/arm/mach-clps711x/include/mach/vmalloc.h
new file mode 100644
index 00000000..467b9613
--- /dev/null
+++ b/arch/arm/mach-clps711x/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-clps711x/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
new file mode 100644
index 00000000..c2eceee6
--- /dev/null
+++ b/arch/arm/mach-clps711x/irq.c
@@ -0,0 +1,143 @@
+/*
+ * linux/arch/arm/mach-clps711x/irq.c
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/clps7111.h>
+
+static void int1_mask(struct irq_data *d)
+{
+ u32 intmr1;
+
+ intmr1 = clps_readl(INTMR1);
+ intmr1 &= ~(1 << d->irq);
+ clps_writel(intmr1, INTMR1);
+}
+
+static void int1_ack(struct irq_data *d)
+{
+ u32 intmr1;
+
+ intmr1 = clps_readl(INTMR1);
+ intmr1 &= ~(1 << d->irq);
+ clps_writel(intmr1, INTMR1);
+
+ switch (d->irq) {
+ case IRQ_CSINT: clps_writel(0, COEOI); break;
+ case IRQ_TC1OI: clps_writel(0, TC1EOI); break;
+ case IRQ_TC2OI: clps_writel(0, TC2EOI); break;
+ case IRQ_RTCMI: clps_writel(0, RTCEOI); break;
+ case IRQ_TINT: clps_writel(0, TEOI); break;
+ case IRQ_UMSINT: clps_writel(0, UMSEOI); break;
+ }
+}
+
+static void int1_unmask(struct irq_data *d)
+{
+ u32 intmr1;
+
+ intmr1 = clps_readl(INTMR1);
+ intmr1 |= 1 << d->irq;
+ clps_writel(intmr1, INTMR1);
+}
+
+static struct irq_chip int1_chip = {
+ .irq_ack = int1_ack,
+ .irq_mask = int1_mask,
+ .irq_unmask = int1_unmask,
+};
+
+static void int2_mask(struct irq_data *d)
+{
+ u32 intmr2;
+
+ intmr2 = clps_readl(INTMR2);
+ intmr2 &= ~(1 << (d->irq - 16));
+ clps_writel(intmr2, INTMR2);
+}
+
+static void int2_ack(struct irq_data *d)
+{
+ u32 intmr2;
+
+ intmr2 = clps_readl(INTMR2);
+ intmr2 &= ~(1 << (d->irq - 16));
+ clps_writel(intmr2, INTMR2);
+
+ switch (d->irq) {
+ case IRQ_KBDINT: clps_writel(0, KBDEOI); break;
+ }
+}
+
+static void int2_unmask(struct irq_data *d)
+{
+ u32 intmr2;
+
+ intmr2 = clps_readl(INTMR2);
+ intmr2 |= 1 << (d->irq - 16);
+ clps_writel(intmr2, INTMR2);
+}
+
+static struct irq_chip int2_chip = {
+ .irq_ack = int2_ack,
+ .irq_mask = int2_mask,
+ .irq_unmask = int2_unmask,
+};
+
+void __init clps711x_init_irq(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ if (INT1_IRQS & (1 << i)) {
+ irq_set_chip_and_handler(i, &int1_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+ if (INT2_IRQS & (1 << i)) {
+ irq_set_chip_and_handler(i, &int2_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+
+ /*
+ * Disable interrupts
+ */
+ clps_writel(0, INTMR1);
+ clps_writel(0, INTMR2);
+
+ /*
+ * Clear down any pending interrupts
+ */
+ clps_writel(0, COEOI);
+ clps_writel(0, TC1EOI);
+ clps_writel(0, TC2EOI);
+ clps_writel(0, RTCEOI);
+ clps_writel(0, TEOI);
+ clps_writel(0, UMSEOI);
+ clps_writel(0, SYNCIO);
+ clps_writel(0, KBDEOI);
+}
diff --git a/arch/arm/mach-clps711x/mm.c b/arch/arm/mach-clps711x/mm.c
new file mode 100644
index 00000000..98659217
--- /dev/null
+++ b/arch/arm/mach-clps711x/mm.c
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-clps711x/mm.c
+ *
+ * Generic MM setup for the CLPS711x-based machines.
+ *
+ * Copyright (C) 2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/mm.h>
+#include <linux/init.h>
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/clps7111.h>
+
+/*
+ * This maps the generic CLPS711x registers
+ */
+static struct map_desc clps711x_io_desc[] __initdata = {
+ {
+ .virtual = CLPS7111_VIRT_BASE,
+ .pfn = __phys_to_pfn(CLPS7111_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
+};
+
+void __init clps711x_map_io(void)
+{
+ iotable_init(clps711x_io_desc, ARRAY_SIZE(clps711x_io_desc));
+}
diff --git a/arch/arm/mach-clps711x/p720t-leds.c b/arch/arm/mach-clps711x/p720t-leds.c
new file mode 100644
index 00000000..15121446
--- /dev/null
+++ b/arch/arm/mach-clps711x/p720t-leds.c
@@ -0,0 +1,67 @@
+/*
+ * linux/arch/arm/mach-clps711x/leds.c
+ *
+ * Integrator LED control routines
+ *
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+
+static void p720t_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ u32 pddr;
+
+ local_irq_save(flags);
+ switch(ledevt) {
+ case led_idle_start:
+ break;
+
+ case led_idle_end:
+ break;
+
+ case led_timer:
+ pddr = clps_readb(PDDR);
+ clps_writeb(pddr ^ 1, PDDR);
+ break;
+
+ default:
+ break;
+ }
+
+ local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_p720t())
+ leds_event = p720t_leds_event;
+
+ return 0;
+}
+
+arch_initcall(leds_init);
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
new file mode 100644
index 00000000..cefbce04
--- /dev/null
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -0,0 +1,123 @@
+/*
+ * linux/arch/arm/mach-clps711x/p720t.c
+ *
+ * Copyright (C) 2000-2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/syspld.h>
+
+#include "common.h"
+
+/*
+ * Map the P720T system PLD. It occupies two address spaces:
+ * SYSPLD_PHYS_BASE and SYSPLD_PHYS_BASE + 0x00400000
+ * We map both here.
+ */
+static struct map_desc p720t_io_desc[] __initdata = {
+ {
+ .virtual = SYSPLD_VIRT_BASE,
+ .pfn = __phys_to_pfn(SYSPLD_PHYS_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = 0xfe400000,
+ .pfn = __phys_to_pfn(0x10400000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init
+fixup_p720t(struct machine_desc *desc, struct tag *tag,
+ char **cmdline, struct meminfo *mi)
+{
+ /*
+ * Our bootloader doesn't setup any tags (yet).
+ */
+ if (tag->hdr.tag != ATAG_CORE) {
+ tag->hdr.tag = ATAG_CORE;
+ tag->hdr.size = tag_size(tag_core);
+ tag->u.core.flags = 0;
+ tag->u.core.pagesize = PAGE_SIZE;
+ tag->u.core.rootdev = 0x0100;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_MEM;
+ tag->hdr.size = tag_size(tag_mem32);
+ tag->u.mem.size = 4096;
+ tag->u.mem.start = PHYS_OFFSET;
+
+ tag = tag_next(tag);
+ tag->hdr.tag = ATAG_NONE;
+ tag->hdr.size = 0;
+ }
+}
+
+static void __init p720t_map_io(void)
+{
+ clps711x_map_io();
+ iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc));
+}
+
+MACHINE_START(P720T, "ARM-Prospector720T")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = 0xc0000100,
+ .fixup = fixup_p720t,
+ .map_io = p720t_map_io,
+ .init_irq = clps711x_init_irq,
+ .timer = &clps711x_timer,
+MACHINE_END
+
+static int p720t_hw_init(void)
+{
+ /*
+ * Power down as much as possible in case we don't
+ * have the drivers loaded.
+ */
+ PLD_LCDEN = 0;
+ PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
+
+ PLD_KBD = 0;
+ PLD_IO = 0;
+ PLD_IRDA = 0;
+ PLD_CODEC = 0;
+ PLD_TCH = 0;
+ PLD_SPI = 0;
+#ifndef CONFIG_DEBUG_LL
+ PLD_COM2 = 0;
+ PLD_COM1 = 0;
+#endif
+
+ return 0;
+}
+
+__initcall(p720t_hw_init);
+
diff --git a/arch/arm/mach-clps711x/time.c b/arch/arm/mach-clps711x/time.c
new file mode 100644
index 00000000..d581ef0b
--- /dev/null
+++ b/arch/arm/mach-clps711x/time.c
@@ -0,0 +1,84 @@
+/*
+ * linux/arch/arm/mach-clps711x/time.c
+ *
+ * Copyright (C) 2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/timex.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/hardware/clps7111.h>
+
+#include <asm/mach/time.h>
+
+
+/*
+ * gettimeoffset() returns time since last timer tick, in usecs.
+ *
+ * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
+ * 'tick' is usecs per jiffy.
+ */
+static unsigned long clps711x_gettimeoffset(void)
+{
+ unsigned long hwticks;
+ hwticks = LATCH - (clps_readl(TC2D) & 0xffff); /* since last underflow */
+ return (hwticks * (tick_nsec / 1000)) / LATCH;
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+p720t_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction clps711x_timer_irq = {
+ .name = "CLPS711x Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = p720t_timer_interrupt,
+};
+
+static void __init clps711x_timer_init(void)
+{
+ struct timespec tv;
+ unsigned int syscon;
+
+ syscon = clps_readl(SYSCON1);
+ syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
+ clps_writel(syscon, SYSCON1);
+
+ clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
+
+ setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
+
+ tv.tv_nsec = 0;
+ tv.tv_sec = clps_readl(RTCDR);
+ do_settimeofday(&tv);
+}
+
+struct sys_timer clps711x_timer = {
+ .init = clps711x_timer_init,
+ .offset = clps711x_gettimeoffset,
+};
diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig
new file mode 100644
index 00000000..29b13f24
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Kconfig
@@ -0,0 +1,13 @@
+menu "CNS3XXX platform type"
+ depends on ARCH_CNS3XXX
+
+config MACH_CNS3420VB
+ bool "Support for CNS3420 Validation Board"
+ select MIGHT_HAVE_PCI
+ help
+ Include support for the Cavium Networks CNS3420 MPCore Platform
+ Baseboard.
+ This is a platform with an on-board ARM11 MPCore and has support
+ for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc.
+
+endmenu
diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile
new file mode 100644
index 00000000..11033f1c
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o devices.o
+obj-$(CONFIG_PCI) += pcie.o
+obj-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o
diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot
new file mode 100644
index 00000000..77701286
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00C00000
diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c
new file mode 100644
index 00000000..08e5c875
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/cns3420vb.c
@@ -0,0 +1,204 @@
+/*
+ * Cavium Networks CNS3420 Validation Board
+ *
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 ARM Limited
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include "core.h"
+#include "devices.h"
+
+/*
+ * NOR Flash
+ */
+static struct mtd_partition cns3420_nor_partitions[] = {
+ {
+ .name = "uboot",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .size = 0x004C0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "filesystem",
+ .size = 0x7000000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "filesystem2",
+ .size = 0x0AE0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "ubootenv",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static struct physmap_flash_data cns3420_nor_pdata = {
+ .width = 2,
+ .parts = cns3420_nor_partitions,
+ .nr_parts = ARRAY_SIZE(cns3420_nor_partitions),
+};
+
+static struct resource cns3420_nor_res = {
+ .start = CNS3XXX_FLASH_BASE,
+ .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device cns3420_nor_pdev = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &cns3420_nor_res,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &cns3420_nor_pdata,
+ },
+};
+
+/*
+ * UART
+ */
+static void __init cns3420_early_serial_setup(void)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ static struct uart_port cns3420_serial_port = {
+ .membase = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
+ .mapbase = CNS3XXX_UART0_BASE,
+ .irq = IRQ_CNS3XXX_UART0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
+ .regshift = 2,
+ .uartclk = 24000000,
+ .line = 0,
+ .type = PORT_16550A,
+ .fifosize = 16,
+ };
+
+ early_serial_setup(&cns3420_serial_port);
+#endif
+}
+
+/*
+ * USB
+ */
+static struct resource cns3xxx_usb_ehci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_BASE,
+ .end = CNS3XXX_USB_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_EHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ehci_device = {
+ .name = "cns3xxx-ehci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
+ .resource = cns3xxx_usb_ehci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ehci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource cns3xxx_usb_ohci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_USB_OHCI_BASE,
+ .end = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_USB_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_usb_ohci_device = {
+ .name = "cns3xxx-ohci",
+ .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
+ .resource = cns3xxx_usb_ohci_resources,
+ .dev = {
+ .dma_mask = &cns3xxx_usb_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/*
+ * Initialization
+ */
+static struct platform_device *cns3420_pdevs[] __initdata = {
+ &cns3420_nor_pdev,
+ &cns3xxx_usb_ehci_device,
+ &cns3xxx_usb_ohci_device,
+};
+
+static void __init cns3420_init(void)
+{
+ platform_add_devices(cns3420_pdevs, ARRAY_SIZE(cns3420_pdevs));
+
+ cns3xxx_ahci_init();
+ cns3xxx_sdhci_init();
+
+ pm_power_off = cns3xxx_power_off;
+}
+
+static struct map_desc cns3420_io_desc[] __initdata = {
+ {
+ .virtual = CNS3XXX_UART0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init cns3420_map_io(void)
+{
+ cns3xxx_map_io();
+ iotable_init(cns3420_io_desc, ARRAY_SIZE(cns3420_io_desc));
+
+ cns3420_early_serial_setup();
+}
+
+MACHINE_START(CNS3420VB, "Cavium Networks CNS3420 Validation Board")
+ .boot_params = 0x00000100,
+ .map_io = cns3420_map_io,
+ .init_irq = cns3xxx_init_irq,
+ .timer = &cns3xxx_timer,
+ .init_machine = cns3420_init,
+MACHINE_END
diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c
new file mode 100644
index 00000000..da30078a
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright 1999 - 2003 ARM Limited
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/hardware/gic.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+static struct map_desc cns3xxx_io_desc[] __initdata = {
+ {
+ .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_TIMER1_2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_GPIOA_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_GPIOA_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_GPIOB_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_GPIOB_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_MISC_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_MISC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = CNS3XXX_PM_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PM_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init cns3xxx_map_io(void)
+{
+ iotable_init(cns3xxx_io_desc, ARRAY_SIZE(cns3xxx_io_desc));
+}
+
+/* used by entry-macro.S */
+void __init cns3xxx_init_irq(void)
+{
+ gic_init(0, 29, __io(CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT),
+ __io(CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT));
+}
+
+void cns3xxx_power_off(void)
+{
+ u32 __iomem *pm_base = __io(CNS3XXX_PM_BASE_VIRT);
+ u32 clkctrl;
+
+ printk(KERN_INFO "powering system down...\n");
+
+ clkctrl = readl(pm_base + PM_SYS_CLK_CTRL_OFFSET);
+ clkctrl &= 0xfffff1ff;
+ clkctrl |= (0x5 << 9); /* Hibernate */
+ writel(clkctrl, pm_base + PM_SYS_CLK_CTRL_OFFSET);
+
+}
+
+/*
+ * Timer
+ */
+static void __iomem *cns3xxx_tmr1;
+
+static void cns3xxx_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ int pclk = cns3xxx_cpu_clock() / 8;
+ int reload;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ reload = pclk * 20 / (3 * HZ) * 0x25000;
+ writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+ ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set, and timer enabled in 'next_event' hook */
+ ctrl |= (1 << 2) | (1 << 9);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ default:
+ ctrl = 0;
+ }
+
+ writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+}
+
+static int cns3xxx_timer_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ writel(evt, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+ writel(ctrl | (1 << 0), cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ return 0;
+}
+
+static struct clock_event_device cns3xxx_tmr1_clockevent = {
+ .name = "cns3xxx timer1",
+ .shift = 8,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = cns3xxx_timer_set_mode,
+ .set_next_event = cns3xxx_timer_set_next_event,
+ .rating = 350,
+ .cpumask = cpu_all_mask,
+};
+
+static void __init cns3xxx_clockevents_init(unsigned int timer_irq)
+{
+ cns3xxx_tmr1_clockevent.irq = timer_irq;
+ cns3xxx_tmr1_clockevent.mult =
+ div_sc((cns3xxx_cpu_clock() >> 3) * 1000000, NSEC_PER_SEC,
+ cns3xxx_tmr1_clockevent.shift);
+ cns3xxx_tmr1_clockevent.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &cns3xxx_tmr1_clockevent);
+ cns3xxx_tmr1_clockevent.min_delta_ns =
+ clockevent_delta2ns(0xf, &cns3xxx_tmr1_clockevent);
+
+ clockevents_register_device(&cns3xxx_tmr1_clockevent);
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t cns3xxx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &cns3xxx_tmr1_clockevent;
+ u32 __iomem *stat = cns3xxx_tmr1 + TIMER1_2_INTERRUPT_STATUS_OFFSET;
+ u32 val;
+
+ /* Clear the interrupt */
+ val = readl(stat);
+ writel(val & ~(1 << 2), stat);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction cns3xxx_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = cns3xxx_timer_interrupt,
+};
+
+/*
+ * Set up the clock source and clock events devices
+ */
+static void __init __cns3xxx_timer_init(unsigned int timer_irq)
+{
+ u32 val;
+ u32 irq_mask;
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+
+ /* disable timer1 and timer2 */
+ writel(0, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ /* stop free running timer3 */
+ writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
+
+ /* timer1 */
+ writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
+ writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
+
+ writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
+ writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
+
+ /* mask irq, non-mask timer1 overflow */
+ irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+ irq_mask &= ~(1 << 2);
+ irq_mask |= 0x03;
+ writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+ /* down counter */
+ val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ val |= (1 << 9);
+ writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ /* timer2 */
+ writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
+ writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
+
+ /* mask irq */
+ irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+ irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
+ writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
+
+ /* down counter */
+ val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+ val |= (1 << 10);
+ writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
+
+ /* Make irqs happen for the system timer */
+ setup_irq(timer_irq, &cns3xxx_timer_irq);
+
+ cns3xxx_clockevents_init(timer_irq);
+}
+
+static void __init cns3xxx_timer_init(void)
+{
+ cns3xxx_tmr1 = __io(CNS3XXX_TIMER1_2_3_BASE_VIRT);
+
+ __cns3xxx_timer_init(IRQ_CNS3XXX_TIMER0);
+}
+
+struct sys_timer cns3xxx_timer = {
+ .init = cns3xxx_timer_init,
+};
diff --git a/arch/arm/mach-cns3xxx/core.h b/arch/arm/mach-cns3xxx/core.h
new file mode 100644
index 00000000..ffeb3a8b
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/core.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CNS3XXX_CORE_H
+#define __CNS3XXX_CORE_H
+
+extern struct sys_timer cns3xxx_timer;
+
+void __init cns3xxx_map_io(void);
+void __init cns3xxx_init_irq(void);
+void cns3xxx_power_off(void);
+
+#endif /* __CNS3XXX_CORE_H */
diff --git a/arch/arm/mach-cns3xxx/devices.c b/arch/arm/mach-cns3xxx/devices.c
new file mode 100644
index 00000000..79d1fb02
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/devices.c
@@ -0,0 +1,112 @@
+/*
+ * CNS3xxx common devices
+ *
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <mach/cns3xxx.h>
+#include <mach/irqs.h>
+#include <mach/pm.h>
+#include "core.h"
+#include "devices.h"
+
+/*
+ * AHCI
+ */
+static struct resource cns3xxx_ahci_resource[] = {
+ [0] = {
+ .start = CNS3XXX_SATA2_BASE,
+ .end = CNS3XXX_SATA2_BASE + CNS3XXX_SATA2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_SATA,
+ .end = IRQ_CNS3XXX_SATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 cns3xxx_ahci_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device cns3xxx_ahci_pdev = {
+ .name = "ahci",
+ .id = 0,
+ .resource = cns3xxx_ahci_resource,
+ .num_resources = ARRAY_SIZE(cns3xxx_ahci_resource),
+ .dev = {
+ .dma_mask = &cns3xxx_ahci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init cns3xxx_ahci_init(void)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(MISC_SATA_POWER_MODE);
+ tmp |= 0x1 << 16; /* Disable SATA PHY 0 from SLUMBER Mode */
+ tmp |= 0x1 << 17; /* Disable SATA PHY 1 from SLUMBER Mode */
+ __raw_writel(tmp, MISC_SATA_POWER_MODE);
+
+ /* Enable SATA PHY */
+ cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0);
+ cns3xxx_pwr_power_up(0x1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1);
+
+ /* Enable SATA Clock */
+ cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_SATA);
+
+ /* De-Asscer SATA Reset */
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA));
+
+ platform_device_register(&cns3xxx_ahci_pdev);
+}
+
+/*
+ * SDHCI
+ */
+static struct resource cns3xxx_sdhci_resources[] = {
+ [0] = {
+ .start = CNS3XXX_SDIO_BASE,
+ .end = CNS3XXX_SDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CNS3XXX_SDIO,
+ .end = IRQ_CNS3XXX_SDIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cns3xxx_sdhci_pdev = {
+ .name = "sdhci-cns3xxx",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cns3xxx_sdhci_resources),
+ .resource = cns3xxx_sdhci_resources,
+};
+
+void __init cns3xxx_sdhci_init(void)
+{
+ u32 __iomem *gpioa = __io(CNS3XXX_MISC_BASE_VIRT + 0x0014);
+ u32 gpioa_pins = __raw_readl(gpioa);
+
+ /* MMC/SD pins share with GPIOA */
+ gpioa_pins |= 0x1fff0004;
+ __raw_writel(gpioa_pins, gpioa);
+
+ cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO));
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO));
+
+ platform_device_register(&cns3xxx_sdhci_pdev);
+}
diff --git a/arch/arm/mach-cns3xxx/devices.h b/arch/arm/mach-cns3xxx/devices.h
new file mode 100644
index 00000000..27e15a10
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/devices.h
@@ -0,0 +1,20 @@
+/*
+ * CNS3xxx common devices
+ *
+ * Copyright 2008 Cavium Networks
+ * Scott Shu
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CNS3XXX_DEVICES_H_
+#define __CNS3XXX_DEVICES_H_
+
+void __init cns3xxx_ahci_init(void);
+void __init cns3xxx_sdhci_init(void);
+
+#endif /* __CNS3XXX_DEVICES_H_ */
diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
new file mode 100644
index 00000000..191c8e57
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h
@@ -0,0 +1,632 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_BOARD_CNS3XXXH
+#define __MACH_BOARD_CNS3XXXH
+
+/*
+ * Memory map
+ */
+#define CNS3XXX_FLASH_BASE 0x10000000 /* Flash/SRAM Memory Bank 0 */
+#define CNS3XXX_FLASH_SIZE SZ_256M
+
+#define CNS3XXX_DDR2SDRAM_BASE 0x20000000 /* DDR2 SDRAM Memory */
+
+#define CNS3XXX_SPI_FLASH_BASE 0x60000000 /* SPI Serial Flash Memory */
+
+#define CNS3XXX_SWITCH_BASE 0x70000000 /* Switch and HNAT Control */
+#define CNS3XXX_SWITCH_BASE_VIRT 0xFFF00000
+
+#define CNS3XXX_PPE_BASE 0x70001000 /* HANT */
+#define CNS3XXX_PPE_BASE_VIRT 0xFFF50000
+
+#define CNS3XXX_EMBEDDED_SRAM_BASE 0x70002000 /* HANT Embedded SRAM */
+#define CNS3XXX_EMBEDDED_SRAM_BASE_VIRT 0xFFF60000
+
+#define CNS3XXX_SSP_BASE 0x71000000 /* Synchronous Serial Port - SPI/PCM/I2C */
+#define CNS3XXX_SSP_BASE_VIRT 0xFFF01000
+
+#define CNS3XXX_DMC_BASE 0x72000000 /* DMC Control (DDR2 SDRAM) */
+#define CNS3XXX_DMC_BASE_VIRT 0xFFF02000
+
+#define CNS3XXX_SMC_BASE 0x73000000 /* SMC Control */
+#define CNS3XXX_SMC_BASE_VIRT 0xFFF03000
+
+#define SMC_MEMC_STATUS_OFFSET 0x000
+#define SMC_MEMIF_CFG_OFFSET 0x004
+#define SMC_MEMC_CFG_SET_OFFSET 0x008
+#define SMC_MEMC_CFG_CLR_OFFSET 0x00C
+#define SMC_DIRECT_CMD_OFFSET 0x010
+#define SMC_SET_CYCLES_OFFSET 0x014
+#define SMC_SET_OPMODE_OFFSET 0x018
+#define SMC_REFRESH_PERIOD_0_OFFSET 0x020
+#define SMC_REFRESH_PERIOD_1_OFFSET 0x024
+#define SMC_SRAM_CYCLES0_0_OFFSET 0x100
+#define SMC_NAND_CYCLES0_0_OFFSET 0x100
+#define SMC_OPMODE0_0_OFFSET 0x104
+#define SMC_SRAM_CYCLES0_1_OFFSET 0x120
+#define SMC_NAND_CYCLES0_1_OFFSET 0x120
+#define SMC_OPMODE0_1_OFFSET 0x124
+#define SMC_USER_STATUS_OFFSET 0x200
+#define SMC_USER_CONFIG_OFFSET 0x204
+#define SMC_ECC_STATUS_OFFSET 0x300
+#define SMC_ECC_MEMCFG_OFFSET 0x304
+#define SMC_ECC_MEMCOMMAND1_OFFSET 0x308
+#define SMC_ECC_MEMCOMMAND2_OFFSET 0x30C
+#define SMC_ECC_ADDR0_OFFSET 0x310
+#define SMC_ECC_ADDR1_OFFSET 0x314
+#define SMC_ECC_VALUE0_OFFSET 0x318
+#define SMC_ECC_VALUE1_OFFSET 0x31C
+#define SMC_ECC_VALUE2_OFFSET 0x320
+#define SMC_ECC_VALUE3_OFFSET 0x324
+#define SMC_PERIPH_ID_0_OFFSET 0xFE0
+#define SMC_PERIPH_ID_1_OFFSET 0xFE4
+#define SMC_PERIPH_ID_2_OFFSET 0xFE8
+#define SMC_PERIPH_ID_3_OFFSET 0xFEC
+#define SMC_PCELL_ID_0_OFFSET 0xFF0
+#define SMC_PCELL_ID_1_OFFSET 0xFF4
+#define SMC_PCELL_ID_2_OFFSET 0xFF8
+#define SMC_PCELL_ID_3_OFFSET 0xFFC
+
+#define CNS3XXX_GPIOA_BASE 0x74000000 /* GPIO port A */
+#define CNS3XXX_GPIOA_BASE_VIRT 0xFFF04000
+
+#define CNS3XXX_GPIOB_BASE 0x74800000 /* GPIO port B */
+#define CNS3XXX_GPIOB_BASE_VIRT 0xFFF05000
+
+#define CNS3XXX_RTC_BASE 0x75000000 /* Real Time Clock */
+#define CNS3XXX_RTC_BASE_VIRT 0xFFF06000
+
+#define RTC_SEC_OFFSET 0x00
+#define RTC_MIN_OFFSET 0x04
+#define RTC_HOUR_OFFSET 0x08
+#define RTC_DAY_OFFSET 0x0C
+#define RTC_SEC_ALM_OFFSET 0x10
+#define RTC_MIN_ALM_OFFSET 0x14
+#define RTC_HOUR_ALM_OFFSET 0x18
+#define RTC_REC_OFFSET 0x1C
+#define RTC_CTRL_OFFSET 0x20
+#define RTC_INTR_STS_OFFSET 0x34
+
+#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */
+#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */
+
+#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */
+#define CNS3XXX_PM_BASE_VIRT 0xFFF08000
+
+#define PM_CLK_GATE_OFFSET 0x00
+#define PM_SOFT_RST_OFFSET 0x04
+#define PM_HS_CFG_OFFSET 0x08
+#define PM_CACTIVE_STA_OFFSET 0x0C
+#define PM_PWR_STA_OFFSET 0x10
+#define PM_SYS_CLK_CTRL_OFFSET 0x14
+#define PM_PLL_LCD_I2S_CTRL_OFFSET 0x18
+#define PM_PLL_HM_PD_OFFSET 0x1C
+
+#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */
+#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000
+
+#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */
+#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000
+
+#define CNS3XXX_UART2_BASE 0x78800000 /* UART 2 */
+#define CNS3XXX_UART2_BASE_VIRT 0xFFF0B000
+
+#define CNS3XXX_DMAC_BASE 0x79000000 /* Generic DMA Control */
+#define CNS3XXX_DMAC_BASE_VIRT 0xFFF0D000
+
+#define CNS3XXX_CORESIGHT_BASE 0x7A000000 /* CoreSight */
+#define CNS3XXX_CORESIGHT_BASE_VIRT 0xFFF0E000
+
+#define CNS3XXX_CRYPTO_BASE 0x7B000000 /* Crypto */
+#define CNS3XXX_CRYPTO_BASE_VIRT 0xFFF0F000
+
+#define CNS3XXX_I2S_BASE 0x7C000000 /* I2S */
+#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000
+
+#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */
+#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800
+
+#define TIMER1_COUNTER_OFFSET 0x00
+#define TIMER1_AUTO_RELOAD_OFFSET 0x04
+#define TIMER1_MATCH_V1_OFFSET 0x08
+#define TIMER1_MATCH_V2_OFFSET 0x0C
+
+#define TIMER2_COUNTER_OFFSET 0x10
+#define TIMER2_AUTO_RELOAD_OFFSET 0x14
+#define TIMER2_MATCH_V1_OFFSET 0x18
+#define TIMER2_MATCH_V2_OFFSET 0x1C
+
+#define TIMER1_2_CONTROL_OFFSET 0x30
+#define TIMER1_2_INTERRUPT_STATUS_OFFSET 0x34
+#define TIMER1_2_INTERRUPT_MASK_OFFSET 0x38
+
+#define TIMER_FREERUN_OFFSET 0x40
+#define TIMER_FREERUN_CONTROL_OFFSET 0x44
+
+#define CNS3XXX_HCIE_BASE 0x7D000000 /* HCIE Control */
+#define CNS3XXX_HCIE_BASE_VIRT 0xFFF30000
+
+#define CNS3XXX_RAID_BASE 0x7E000000 /* RAID Control */
+#define CNS3XXX_RAID_BASE_VIRT 0xFFF12000
+
+#define CNS3XXX_AXI_IXC_BASE 0x7F000000 /* AXI IXC */
+#define CNS3XXX_AXI_IXC_BASE_VIRT 0xFFF13000
+
+#define CNS3XXX_CLCD_BASE 0x80000000 /* LCD Control */
+#define CNS3XXX_CLCD_BASE_VIRT 0xFFF14000
+
+#define CNS3XXX_USBOTG_BASE 0x81000000 /* USB OTG Control */
+#define CNS3XXX_USBOTG_BASE_VIRT 0xFFF15000
+
+#define CNS3XXX_USB_BASE 0x82000000 /* USB Host Control */
+
+#define CNS3XXX_SATA2_BASE 0x83000000 /* SATA */
+#define CNS3XXX_SATA2_SIZE SZ_16M
+#define CNS3XXX_SATA2_BASE_VIRT 0xFFF17000
+
+#define CNS3XXX_CAMERA_BASE 0x84000000 /* Camera Interface */
+#define CNS3XXX_CAMERA_BASE_VIRT 0xFFF18000
+
+#define CNS3XXX_SDIO_BASE 0x85000000 /* SDIO */
+#define CNS3XXX_SDIO_BASE_VIRT 0xFFF19000
+
+#define CNS3XXX_I2S_TDM_BASE 0x86000000 /* I2S TDM */
+#define CNS3XXX_I2S_TDM_BASE_VIRT 0xFFF1A000
+
+#define CNS3XXX_2DG_BASE 0x87000000 /* 2D Graphic Control */
+#define CNS3XXX_2DG_BASE_VIRT 0xFFF1B000
+
+#define CNS3XXX_USB_OHCI_BASE 0x88000000 /* USB OHCI */
+
+#define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */
+#define CNS3XXX_L2C_BASE_VIRT 0xFFF27000
+
+#define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */
+#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000
+
+#define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */
+#define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000
+
+#define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */
+#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000
+
+#define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */
+#define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000
+
+#define CNS3XXX_PCIE0_CFG1_BASE 0xAE000000 /* PCIe Port 0 CFG Type 1 */
+#define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000
+
+#define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */
+#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000
+
+#define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */
+#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000
+
+#define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */
+#define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000
+
+#define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */
+#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000
+
+#define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */
+#define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000
+
+#define CNS3XXX_PCIE1_CFG1_BASE 0xBE000000 /* PCIe Port 1 CFG Type 1 */
+#define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000
+
+#define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */
+#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */
+#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000
+
+#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */
+#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100
+
+#define CNS3XXX_TC11MP_TWD_BASE 0x90000600
+#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600
+
+#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */
+#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000
+
+#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */
+#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000
+
+/*
+ * Misc block
+ */
+#define MISC_MEM_MAP(offs) (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + (offs))
+
+#define MISC_MEMORY_REMAP_REG MISC_MEM_MAP(0x00)
+#define MISC_CHIP_CONFIG_REG MISC_MEM_MAP(0x04)
+#define MISC_DEBUG_PROBE_DATA_REG MISC_MEM_MAP(0x08)
+#define MISC_DEBUG_PROBE_SELECTION_REG MISC_MEM_MAP(0x0C)
+#define MISC_IO_PIN_FUNC_SELECTION_REG MISC_MEM_MAP(0x10)
+#define MISC_GPIOA_PIN_ENABLE_REG MISC_MEM_MAP(0x14)
+#define MISC_GPIOB_PIN_ENABLE_REG MISC_MEM_MAP(0x18)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_A MISC_MEM_MAP(0x1C)
+#define MISC_IO_PAD_DRIVE_STRENGTH_CTRL_B MISC_MEM_MAP(0x20)
+#define MISC_GPIOA_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x24)
+#define MISC_GPIOA_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x28)
+#define MISC_GPIOB_15_0_PULL_CTRL_REG MISC_MEM_MAP(0x2C)
+#define MISC_GPIOB_16_31_PULL_CTRL_REG MISC_MEM_MAP(0x30)
+#define MISC_IO_PULL_CTRL_REG MISC_MEM_MAP(0x34)
+#define MISC_E_FUSE_31_0_REG MISC_MEM_MAP(0x40)
+#define MISC_E_FUSE_63_32_REG MISC_MEM_MAP(0x44)
+#define MISC_E_FUSE_95_64_REG MISC_MEM_MAP(0x48)
+#define MISC_E_FUSE_127_96_REG MISC_MEM_MAP(0x4C)
+#define MISC_SOFTWARE_TEST_1_REG MISC_MEM_MAP(0x50)
+#define MISC_SOFTWARE_TEST_2_REG MISC_MEM_MAP(0x54)
+
+#define MISC_SATA_POWER_MODE MISC_MEM_MAP(0x310)
+
+#define MISC_USB_CFG_REG MISC_MEM_MAP(0x800)
+#define MISC_USB_STS_REG MISC_MEM_MAP(0x804)
+#define MISC_USBPHY00_CFG_REG MISC_MEM_MAP(0x808)
+#define MISC_USBPHY01_CFG_REG MISC_MEM_MAP(0x80c)
+#define MISC_USBPHY10_CFG_REG MISC_MEM_MAP(0x810)
+#define MISC_USBPHY11_CFG_REG MISC_MEM_MAP(0x814)
+
+#define MISC_PCIEPHY_CMCTL(x) MISC_MEM_MAP(0x900 + (x) * 0x004)
+#define MISC_PCIEPHY_CTL(x) MISC_MEM_MAP(0x940 + (x) * 0x100)
+#define MISC_PCIE_AXIS_AWMISC(x) MISC_MEM_MAP(0x944 + (x) * 0x100)
+#define MISC_PCIE_AXIS_ARMISC(x) MISC_MEM_MAP(0x948 + (x) * 0x100)
+#define MISC_PCIE_AXIS_RMISC(x) MISC_MEM_MAP(0x94C + (x) * 0x100)
+#define MISC_PCIE_AXIS_BMISC(x) MISC_MEM_MAP(0x950 + (x) * 0x100)
+#define MISC_PCIE_AXIM_RMISC(x) MISC_MEM_MAP(0x954 + (x) * 0x100)
+#define MISC_PCIE_AXIM_BMISC(x) MISC_MEM_MAP(0x958 + (x) * 0x100)
+#define MISC_PCIE_CTRL(x) MISC_MEM_MAP(0x95C + (x) * 0x100)
+#define MISC_PCIE_PM_DEBUG(x) MISC_MEM_MAP(0x960 + (x) * 0x100)
+#define MISC_PCIE_RFC_DEBUG(x) MISC_MEM_MAP(0x964 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGL(x) MISC_MEM_MAP(0x968 + (x) * 0x100)
+#define MISC_PCIE_CXPL_DEBUGH(x) MISC_MEM_MAP(0x96C + (x) * 0x100)
+#define MISC_PCIE_DIAG_DEBUGH(x) MISC_MEM_MAP(0x970 + (x) * 0x100)
+#define MISC_PCIE_W1CLR(x) MISC_MEM_MAP(0x974 + (x) * 0x100)
+#define MISC_PCIE_INT_MASK(x) MISC_MEM_MAP(0x978 + (x) * 0x100)
+#define MISC_PCIE_INT_STATUS(x) MISC_MEM_MAP(0x97C + (x) * 0x100)
+
+/*
+ * Power management and clock control
+ */
+#define PMU_MEM_MAP(offs) (void __iomem *)(CNS3XXX_PM_BASE_VIRT + (offs))
+
+#define PM_CLK_GATE_REG PMU_MEM_MAP(0x000)
+#define PM_SOFT_RST_REG PMU_MEM_MAP(0x004)
+#define PM_HS_CFG_REG PMU_MEM_MAP(0x008)
+#define PM_CACTIVE_STA_REG PMU_MEM_MAP(0x00C)
+#define PM_PWR_STA_REG PMU_MEM_MAP(0x010)
+#define PM_CLK_CTRL_REG PMU_MEM_MAP(0x014)
+#define PM_PLL_LCD_I2S_CTRL_REG PMU_MEM_MAP(0x018)
+#define PM_PLL_HM_PD_CTRL_REG PMU_MEM_MAP(0x01C)
+#define PM_REGULAT_CTRL_REG PMU_MEM_MAP(0x020)
+#define PM_WDT_CTRL_REG PMU_MEM_MAP(0x024)
+#define PM_WU_CTRL0_REG PMU_MEM_MAP(0x028)
+#define PM_WU_CTRL1_REG PMU_MEM_MAP(0x02C)
+#define PM_CSR_REG PMU_MEM_MAP(0x030)
+
+/* PM_CLK_GATE_REG */
+#define PM_CLK_GATE_REG_OFFSET_SDIO (25)
+#define PM_CLK_GATE_REG_OFFSET_GPU (24)
+#define PM_CLK_GATE_REG_OFFSET_CIM (23)
+#define PM_CLK_GATE_REG_OFFSET_LCDC (22)
+#define PM_CLK_GATE_REG_OFFSET_I2S (21)
+#define PM_CLK_GATE_REG_OFFSET_RAID (20)
+#define PM_CLK_GATE_REG_OFFSET_SATA (19)
+#define PM_CLK_GATE_REG_OFFSET_PCIE(x) (17 + (x))
+#define PM_CLK_GATE_REG_OFFSET_USB_HOST (16)
+#define PM_CLK_GATE_REG_OFFSET_USB_OTG (15)
+#define PM_CLK_GATE_REG_OFFSET_TIMER (14)
+#define PM_CLK_GATE_REG_OFFSET_CRYPTO (13)
+#define PM_CLK_GATE_REG_OFFSET_HCIE (12)
+#define PM_CLK_GATE_REG_OFFSET_SWITCH (11)
+#define PM_CLK_GATE_REG_OFFSET_GPIO (10)
+#define PM_CLK_GATE_REG_OFFSET_UART3 (9)
+#define PM_CLK_GATE_REG_OFFSET_UART2 (8)
+#define PM_CLK_GATE_REG_OFFSET_UART1 (7)
+#define PM_CLK_GATE_REG_OFFSET_RTC (5)
+#define PM_CLK_GATE_REG_OFFSET_GDMA (4)
+#define PM_CLK_GATE_REG_OFFSET_SPI_PCM_I2C (3)
+#define PM_CLK_GATE_REG_OFFSET_SMC_NFI (1)
+#define PM_CLK_GATE_REG_MASK (0x03FFFFBA)
+
+/* PM_SOFT_RST_REG */
+#define PM_SOFT_RST_REG_OFFST_WARM_RST_FLAG (31)
+#define PM_SOFT_RST_REG_OFFST_CPU1 (29)
+#define PM_SOFT_RST_REG_OFFST_CPU0 (28)
+#define PM_SOFT_RST_REG_OFFST_SDIO (25)
+#define PM_SOFT_RST_REG_OFFST_GPU (24)
+#define PM_SOFT_RST_REG_OFFST_CIM (23)
+#define PM_SOFT_RST_REG_OFFST_LCDC (22)
+#define PM_SOFT_RST_REG_OFFST_I2S (21)
+#define PM_SOFT_RST_REG_OFFST_RAID (20)
+#define PM_SOFT_RST_REG_OFFST_SATA (19)
+#define PM_SOFT_RST_REG_OFFST_PCIE(x) (17 + (x))
+#define PM_SOFT_RST_REG_OFFST_USB_HOST (16)
+#define PM_SOFT_RST_REG_OFFST_USB_OTG (15)
+#define PM_SOFT_RST_REG_OFFST_TIMER (14)
+#define PM_SOFT_RST_REG_OFFST_CRYPTO (13)
+#define PM_SOFT_RST_REG_OFFST_HCIE (12)
+#define PM_SOFT_RST_REG_OFFST_SWITCH (11)
+#define PM_SOFT_RST_REG_OFFST_GPIO (10)
+#define PM_SOFT_RST_REG_OFFST_UART3 (9)
+#define PM_SOFT_RST_REG_OFFST_UART2 (8)
+#define PM_SOFT_RST_REG_OFFST_UART1 (7)
+#define PM_SOFT_RST_REG_OFFST_RTC (5)
+#define PM_SOFT_RST_REG_OFFST_GDMA (4)
+#define PM_SOFT_RST_REG_OFFST_SPI_PCM_I2C (3)
+#define PM_SOFT_RST_REG_OFFST_DMC (2)
+#define PM_SOFT_RST_REG_OFFST_SMC_NFI (1)
+#define PM_SOFT_RST_REG_OFFST_GLOBAL (0)
+#define PM_SOFT_RST_REG_MASK (0xF3FFFFBF)
+
+/* PMHS_CFG_REG */
+#define PM_HS_CFG_REG_OFFSET_SDIO (25)
+#define PM_HS_CFG_REG_OFFSET_GPU (24)
+#define PM_HS_CFG_REG_OFFSET_CIM (23)
+#define PM_HS_CFG_REG_OFFSET_LCDC (22)
+#define PM_HS_CFG_REG_OFFSET_I2S (21)
+#define PM_HS_CFG_REG_OFFSET_RAID (20)
+#define PM_HS_CFG_REG_OFFSET_SATA (19)
+#define PM_HS_CFG_REG_OFFSET_PCIE1 (18)
+#define PM_HS_CFG_REG_OFFSET_PCIE0 (17)
+#define PM_HS_CFG_REG_OFFSET_USB_HOST (16)
+#define PM_HS_CFG_REG_OFFSET_USB_OTG (15)
+#define PM_HS_CFG_REG_OFFSET_TIMER (14)
+#define PM_HS_CFG_REG_OFFSET_CRYPTO (13)
+#define PM_HS_CFG_REG_OFFSET_HCIE (12)
+#define PM_HS_CFG_REG_OFFSET_SWITCH (11)
+#define PM_HS_CFG_REG_OFFSET_GPIO (10)
+#define PM_HS_CFG_REG_OFFSET_UART3 (9)
+#define PM_HS_CFG_REG_OFFSET_UART2 (8)
+#define PM_HS_CFG_REG_OFFSET_UART1 (7)
+#define PM_HS_CFG_REG_OFFSET_RTC (5)
+#define PM_HS_CFG_REG_OFFSET_GDMA (4)
+#define PM_HS_CFG_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_HS_CFG_REG_OFFSET_DMC (2)
+#define PM_HS_CFG_REG_OFFSET_SMC_NFI (1)
+#define PM_HS_CFG_REG_MASK (0x03FFFFBE)
+#define PM_HS_CFG_REG_MASK_SUPPORT (0x01100806)
+
+/* PM_CACTIVE_STA_REG */
+#define PM_CACTIVE_STA_REG_OFFSET_SDIO (25)
+#define PM_CACTIVE_STA_REG_OFFSET_GPU (24)
+#define PM_CACTIVE_STA_REG_OFFSET_CIM (23)
+#define PM_CACTIVE_STA_REG_OFFSET_LCDC (22)
+#define PM_CACTIVE_STA_REG_OFFSET_I2S (21)
+#define PM_CACTIVE_STA_REG_OFFSET_RAID (20)
+#define PM_CACTIVE_STA_REG_OFFSET_SATA (19)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE1 (18)
+#define PM_CACTIVE_STA_REG_OFFSET_PCIE0 (17)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_HOST (16)
+#define PM_CACTIVE_STA_REG_OFFSET_USB_OTG (15)
+#define PM_CACTIVE_STA_REG_OFFSET_TIMER (14)
+#define PM_CACTIVE_STA_REG_OFFSET_CRYPTO (13)
+#define PM_CACTIVE_STA_REG_OFFSET_HCIE (12)
+#define PM_CACTIVE_STA_REG_OFFSET_SWITCH (11)
+#define PM_CACTIVE_STA_REG_OFFSET_GPIO (10)
+#define PM_CACTIVE_STA_REG_OFFSET_UART3 (9)
+#define PM_CACTIVE_STA_REG_OFFSET_UART2 (8)
+#define PM_CACTIVE_STA_REG_OFFSET_UART1 (7)
+#define PM_CACTIVE_STA_REG_OFFSET_RTC (5)
+#define PM_CACTIVE_STA_REG_OFFSET_GDMA (4)
+#define PM_CACTIVE_STA_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_CACTIVE_STA_REG_OFFSET_DMC (2)
+#define PM_CACTIVE_STA_REG_OFFSET_SMC_NFI (1)
+#define PM_CACTIVE_STA_REG_MASK (0x03FFFFBE)
+
+/* PM_PWR_STA_REG */
+#define PM_PWR_STA_REG_REG_OFFSET_SDIO (25)
+#define PM_PWR_STA_REG_REG_OFFSET_GPU (24)
+#define PM_PWR_STA_REG_REG_OFFSET_CIM (23)
+#define PM_PWR_STA_REG_REG_OFFSET_LCDC (22)
+#define PM_PWR_STA_REG_REG_OFFSET_I2S (21)
+#define PM_PWR_STA_REG_REG_OFFSET_RAID (20)
+#define PM_PWR_STA_REG_REG_OFFSET_SATA (19)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE1 (18)
+#define PM_PWR_STA_REG_REG_OFFSET_PCIE0 (17)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_HOST (16)
+#define PM_PWR_STA_REG_REG_OFFSET_USB_OTG (15)
+#define PM_PWR_STA_REG_REG_OFFSET_TIMER (14)
+#define PM_PWR_STA_REG_REG_OFFSET_CRYPTO (13)
+#define PM_PWR_STA_REG_REG_OFFSET_HCIE (12)
+#define PM_PWR_STA_REG_REG_OFFSET_SWITCH (11)
+#define PM_PWR_STA_REG_REG_OFFSET_GPIO (10)
+#define PM_PWR_STA_REG_REG_OFFSET_UART3 (9)
+#define PM_PWR_STA_REG_REG_OFFSET_UART2 (8)
+#define PM_PWR_STA_REG_REG_OFFSET_UART1 (7)
+#define PM_PWR_STA_REG_REG_OFFSET_RTC (5)
+#define PM_PWR_STA_REG_REG_OFFSET_GDMA (4)
+#define PM_PWR_STA_REG_REG_OFFSET_SPI_PCM_I2S (3)
+#define PM_PWR_STA_REG_REG_OFFSET_DMC (2)
+#define PM_PWR_STA_REG_REG_OFFSET_SMC_NFI (1)
+#define PM_PWR_STA_REG_REG_MASK (0x03FFFFBE)
+
+/* PM_CLK_CTRL_REG */
+#define PM_CLK_CTRL_REG_OFFSET_I2S_MCLK (31)
+#define PM_CLK_CTRL_REG_OFFSET_DDR2_CHG_EN (30)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF1_EN (29)
+#define PM_CLK_CTRL_REG_OFFSET_PCIE_REF0_EN (28)
+#define PM_CLK_CTRL_REG_OFFSET_TIMER_SIM_MODE (27)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_DIV (24)
+#define PM_CLK_CTRL_REG_OFFSET_I2SCLK_SEL (22)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_DIV (20)
+#define PM_CLK_CTRL_REG_OFFSET_CLKOUT_SEL (16)
+#define PM_CLK_CTRL_REG_OFFSET_MDC_DIV (14)
+#define PM_CLK_CTRL_REG_OFFSET_CRYPTO_CLK_SEL (12)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_PWR_MODE (9)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_DDR2_SEL (7)
+#define PM_CLK_CTRL_REG_OFFSET_DIV_IMMEDIATE (6)
+#define PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV (4)
+#define PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL (0)
+
+#define PM_CPU_CLK_DIV(DIV) { \
+ PM_CLK_CTRL_REG &= ~((0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+ PM_CLK_CTRL_REG |= (((DIV)&0x3) << PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV); \
+}
+
+#define PM_PLL_CPU_SEL(CPU) { \
+ PM_CLK_CTRL_REG &= ~((0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+ PM_CLK_CTRL_REG |= (((CPU)&0xF) << PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL); \
+}
+
+/* PM_PLL_LCD_I2S_CTRL_REG */
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_MCLK_SMC_DIV (22)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_R_SEL (17)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_P (11)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_M (3)
+#define PM_PLL_LCD_I2S_CTRL_REG_OFFSET_PLL_LCD_S (0)
+
+/* PM_PLL_HM_PD_CTRL_REG */
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY1 (11)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_SATA_PHY0 (10)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2SCD (6)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_I2S (5)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_LCD (4)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB (3)
+#define PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_RGMII (2)
+#define PM_PLL_HM_PD_CTRL_REG_MASK (0x00000C7C)
+
+/* PM_WDT_CTRL_REG */
+#define PM_WDT_CTRL_REG_OFFSET_RESET_CPU_ONLY (0)
+
+/* PM_CSR_REG - Clock Scaling Register*/
+#define PM_CSR_REG_OFFSET_CSR_EN (30)
+#define PM_CSR_REG_OFFSET_CSR_NUM (0)
+
+#define CNS3XXX_PWR_CLK_EN(BLOCK) (0x1<<PM_CLK_GATE_REG_OFFSET_##BLOCK)
+
+/* Software reset*/
+#define CNS3XXX_PWR_SOFTWARE_RST(BLOCK) (0x1<<PM_SOFT_RST_REG_OFFST_##BLOCK)
+
+/*
+ * CNS3XXX support several power saving mode as following,
+ * DFS, IDLE, HALT, DOZE, SLEEP, Hibernate
+ */
+#define CNS3XXX_PWR_CPU_MODE_DFS (0)
+#define CNS3XXX_PWR_CPU_MODE_IDLE (1)
+#define CNS3XXX_PWR_CPU_MODE_HALT (2)
+#define CNS3XXX_PWR_CPU_MODE_DOZE (3)
+#define CNS3XXX_PWR_CPU_MODE_SLEEP (4)
+#define CNS3XXX_PWR_CPU_MODE_HIBERNATE (5)
+
+#define CNS3XXX_PWR_PLL(BLOCK) (0x1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_##BLOCK)
+#define CNS3XXX_PWR_PLL_ALL PM_PLL_HM_PD_CTRL_REG_MASK
+
+/* Change CPU frequency and divider */
+#define CNS3XXX_PWR_PLL_CPU_300MHZ (0)
+#define CNS3XXX_PWR_PLL_CPU_333MHZ (1)
+#define CNS3XXX_PWR_PLL_CPU_366MHZ (2)
+#define CNS3XXX_PWR_PLL_CPU_400MHZ (3)
+#define CNS3XXX_PWR_PLL_CPU_433MHZ (4)
+#define CNS3XXX_PWR_PLL_CPU_466MHZ (5)
+#define CNS3XXX_PWR_PLL_CPU_500MHZ (6)
+#define CNS3XXX_PWR_PLL_CPU_533MHZ (7)
+#define CNS3XXX_PWR_PLL_CPU_566MHZ (8)
+#define CNS3XXX_PWR_PLL_CPU_600MHZ (9)
+#define CNS3XXX_PWR_PLL_CPU_633MHZ (10)
+#define CNS3XXX_PWR_PLL_CPU_666MHZ (11)
+#define CNS3XXX_PWR_PLL_CPU_700MHZ (12)
+
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY1 (0)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY2 (1)
+#define CNS3XXX_PWR_CPU_CLK_DIV_BY4 (2)
+
+/* Change DDR2 frequency */
+#define CNS3XXX_PWR_PLL_DDR2_200MHZ (0)
+#define CNS3XXX_PWR_PLL_DDR2_266MHZ (1)
+#define CNS3XXX_PWR_PLL_DDR2_333MHZ (2)
+#define CNS3XXX_PWR_PLL_DDR2_400MHZ (3)
+
+void cns3xxx_pwr_soft_rst(unsigned int block);
+void cns3xxx_pwr_clk_en(unsigned int block);
+int cns3xxx_cpu_clock(void);
+
+/*
+ * ARM11 MPCore interrupt sources (primary GIC)
+ */
+#define IRQ_CNS3XXX_PMU (IRQ_TC11MP_GIC_START + 0)
+#define IRQ_CNS3XXX_SDIO (IRQ_TC11MP_GIC_START + 1)
+#define IRQ_CNS3XXX_L2CC (IRQ_TC11MP_GIC_START + 2)
+#define IRQ_CNS3XXX_RTC (IRQ_TC11MP_GIC_START + 3)
+#define IRQ_CNS3XXX_I2S (IRQ_TC11MP_GIC_START + 4)
+#define IRQ_CNS3XXX_PCM (IRQ_TC11MP_GIC_START + 5)
+#define IRQ_CNS3XXX_SPI (IRQ_TC11MP_GIC_START + 6)
+#define IRQ_CNS3XXX_I2C (IRQ_TC11MP_GIC_START + 7)
+#define IRQ_CNS3XXX_CIM (IRQ_TC11MP_GIC_START + 8)
+#define IRQ_CNS3XXX_GPU (IRQ_TC11MP_GIC_START + 9)
+#define IRQ_CNS3XXX_LCD (IRQ_TC11MP_GIC_START + 10)
+#define IRQ_CNS3XXX_GPIOA (IRQ_TC11MP_GIC_START + 11)
+#define IRQ_CNS3XXX_GPIOB (IRQ_TC11MP_GIC_START + 12)
+#define IRQ_CNS3XXX_UART0 (IRQ_TC11MP_GIC_START + 13)
+#define IRQ_CNS3XXX_UART1 (IRQ_TC11MP_GIC_START + 14)
+#define IRQ_CNS3XXX_UART2 (IRQ_TC11MP_GIC_START + 15)
+#define IRQ_CNS3XXX_ARM11 (IRQ_TC11MP_GIC_START + 16)
+
+#define IRQ_CNS3XXX_SW_STATUS (IRQ_TC11MP_GIC_START + 17)
+#define IRQ_CNS3XXX_SW_R0TXC (IRQ_TC11MP_GIC_START + 18)
+#define IRQ_CNS3XXX_SW_R0RXC (IRQ_TC11MP_GIC_START + 19)
+#define IRQ_CNS3XXX_SW_R0QE (IRQ_TC11MP_GIC_START + 20)
+#define IRQ_CNS3XXX_SW_R0QF (IRQ_TC11MP_GIC_START + 21)
+#define IRQ_CNS3XXX_SW_R1TXC (IRQ_TC11MP_GIC_START + 22)
+#define IRQ_CNS3XXX_SW_R1RXC (IRQ_TC11MP_GIC_START + 23)
+#define IRQ_CNS3XXX_SW_R1QE (IRQ_TC11MP_GIC_START + 24)
+#define IRQ_CNS3XXX_SW_R1QF (IRQ_TC11MP_GIC_START + 25)
+#define IRQ_CNS3XXX_SW_PPE (IRQ_TC11MP_GIC_START + 26)
+
+#define IRQ_CNS3XXX_CRYPTO (IRQ_TC11MP_GIC_START + 27)
+#define IRQ_CNS3XXX_HCIE (IRQ_TC11MP_GIC_START + 28)
+#define IRQ_CNS3XXX_PCIE0_DEVICE (IRQ_TC11MP_GIC_START + 29)
+#define IRQ_CNS3XXX_PCIE1_DEVICE (IRQ_TC11MP_GIC_START + 30)
+#define IRQ_CNS3XXX_USB_OTG (IRQ_TC11MP_GIC_START + 31)
+#define IRQ_CNS3XXX_USB_EHCI (IRQ_TC11MP_GIC_START + 32)
+#define IRQ_CNS3XXX_SATA (IRQ_TC11MP_GIC_START + 33)
+#define IRQ_CNS3XXX_RAID (IRQ_TC11MP_GIC_START + 34)
+#define IRQ_CNS3XXX_SMC (IRQ_TC11MP_GIC_START + 35)
+
+#define IRQ_CNS3XXX_DMAC_ABORT (IRQ_TC11MP_GIC_START + 36)
+#define IRQ_CNS3XXX_DMAC0 (IRQ_TC11MP_GIC_START + 37)
+#define IRQ_CNS3XXX_DMAC1 (IRQ_TC11MP_GIC_START + 38)
+#define IRQ_CNS3XXX_DMAC2 (IRQ_TC11MP_GIC_START + 39)
+#define IRQ_CNS3XXX_DMAC3 (IRQ_TC11MP_GIC_START + 40)
+#define IRQ_CNS3XXX_DMAC4 (IRQ_TC11MP_GIC_START + 41)
+#define IRQ_CNS3XXX_DMAC5 (IRQ_TC11MP_GIC_START + 42)
+#define IRQ_CNS3XXX_DMAC6 (IRQ_TC11MP_GIC_START + 43)
+#define IRQ_CNS3XXX_DMAC7 (IRQ_TC11MP_GIC_START + 44)
+#define IRQ_CNS3XXX_DMAC8 (IRQ_TC11MP_GIC_START + 45)
+#define IRQ_CNS3XXX_DMAC9 (IRQ_TC11MP_GIC_START + 46)
+#define IRQ_CNS3XXX_DMAC10 (IRQ_TC11MP_GIC_START + 47)
+#define IRQ_CNS3XXX_DMAC11 (IRQ_TC11MP_GIC_START + 48)
+#define IRQ_CNS3XXX_DMAC12 (IRQ_TC11MP_GIC_START + 49)
+#define IRQ_CNS3XXX_DMAC13 (IRQ_TC11MP_GIC_START + 50)
+#define IRQ_CNS3XXX_DMAC14 (IRQ_TC11MP_GIC_START + 51)
+#define IRQ_CNS3XXX_DMAC15 (IRQ_TC11MP_GIC_START + 52)
+#define IRQ_CNS3XXX_DMAC16 (IRQ_TC11MP_GIC_START + 53)
+#define IRQ_CNS3XXX_DMAC17 (IRQ_TC11MP_GIC_START + 54)
+
+#define IRQ_CNS3XXX_PCIE0_RC (IRQ_TC11MP_GIC_START + 55)
+#define IRQ_CNS3XXX_PCIE1_RC (IRQ_TC11MP_GIC_START + 56)
+#define IRQ_CNS3XXX_TIMER0 (IRQ_TC11MP_GIC_START + 57)
+#define IRQ_CNS3XXX_TIMER1 (IRQ_TC11MP_GIC_START + 58)
+#define IRQ_CNS3XXX_USB_OHCI (IRQ_TC11MP_GIC_START + 59)
+#define IRQ_CNS3XXX_TIMER2 (IRQ_TC11MP_GIC_START + 60)
+#define IRQ_CNS3XXX_EXTERNAL_PIN0 (IRQ_TC11MP_GIC_START + 61)
+#define IRQ_CNS3XXX_EXTERNAL_PIN1 (IRQ_TC11MP_GIC_START + 62)
+#define IRQ_CNS3XXX_EXTERNAL_PIN2 (IRQ_TC11MP_GIC_START + 63)
+
+#define NR_IRQS_CNS3XXX (IRQ_TC11MP_GIC_START + 64)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_CNS3XXX)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_CNS3XXX
+#endif
+
+#endif /* __MACH_BOARD_CNS3XXX_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/debug-macro.S b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
new file mode 100644
index 00000000..56d82863
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright 1994-1999 Russell King
+ * Copyright 2008 Cavium Networks
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+ .macro addruart,rp,rv
+ mov \rp, #0x00009000
+ orr \rv, \rp, #0xf0000000 @ virtual base
+ orr \rp, \rp, #0x10000000
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-cns3xxx/include/mach/entry-macro.S b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
new file mode 100644
index 00000000..6bd83ed9
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/entry-macro.S
@@ -0,0 +1,18 @@
+/*
+ * Low-level IRQ helper macros for Cavium Networks platforms
+ *
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-cns3xxx/include/mach/hardware.h b/arch/arm/mach-cns3xxx/include/mach/hardware.h
new file mode 100644
index 00000000..57e09836
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/hardware.h
@@ -0,0 +1,22 @@
+/*
+ * This file contains the hardware definitions of the Cavium Networks boards.
+ *
+ * Copyright 2003 ARM Limited.
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+#define pcibios_assign_all_busses() 1
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/io.h b/arch/arm/mach-cns3xxx/include/mach/io.h
new file mode 100644
index 00000000..33b6fc1e
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/io.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2008 Cavium Networks
+ * Copyright 2003 ARM Limited
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/irqs.h b/arch/arm/mach-cns3xxx/include/mach/irqs.h
new file mode 100644
index 00000000..2ab96f80
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/irqs.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+#define IRQ_TC11MP_GIC_START 32
+
+#include <mach/cns3xxx.h>
+
+#ifndef NR_IRQS
+#error "NR_IRQS not defined by the board-specific files"
+#endif
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h
new file mode 100644
index 00000000..dc16c5c5
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/memory.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#define __phys_to_bus(x) ((x) + PHYS_OFFSET)
+#define __bus_to_phys(x) ((x) - PHYS_OFFSET)
+
+#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/pm.h b/arch/arm/mach-cns3xxx/include/mach/pm.h
new file mode 100644
index 00000000..6eae7f76
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/pm.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2004 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __CNS3XXX_PM_H
+#define __CNS3XXX_PM_H
+
+#include <asm/atomic.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block);
+void cns3xxx_pwr_clk_dis(unsigned int block);
+void cns3xxx_pwr_power_up(unsigned int block);
+void cns3xxx_pwr_power_down(unsigned int block);
+
+extern atomic_t usb_pwr_ref;
+
+#endif /* __CNS3XXX_PM_H */
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
new file mode 100644
index 00000000..58bb03ae
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/system.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000 Deep Blue Solutions Ltd
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/timex.h b/arch/arm/mach-cns3xxx/include/mach/timex.h
new file mode 100644
index 00000000..1fd04217
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/timex.h
@@ -0,0 +1,12 @@
+/*
+ * Cavium Networks architecture timex specifications
+ *
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-cns3xxx/include/mach/uncompress.h b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
new file mode 100644
index 00000000..de8ead9b
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/uncompress.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/cns3xxx.h>
+
+#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18))
+
+/*
+ * Return the UART base address
+ */
+static inline unsigned long get_uart_base(void)
+{
+ if (machine_is_cns3420vb())
+ return CNS3XXX_UART0_BASE;
+ else
+ return 0;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-cns3xxx/include/mach/vmalloc.h b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
new file mode 100644
index 00000000..4d381ec0
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/include/mach/vmalloc.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2000 Russell King.
+ * Copyright 2003 ARM Limited
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#define VMALLOC_END 0xd8000000
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
new file mode 100644
index 00000000..78defd71
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -0,0 +1,389 @@
+/*
+ * PCI-E support for CNS3xxx
+ *
+ * Copyright 2008 Cavium Networks
+ * Richard Liu <richard.liu@caviumnetworks.com>
+ * Copyright 2010 MontaVista Software, LLC.
+ * Anton Vorontsov <avorontsov@mvista.com>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <asm/mach/map.h>
+#include <mach/cns3xxx.h>
+#include "core.h"
+
+enum cns3xxx_access_type {
+ CNS3XXX_HOST_TYPE = 0,
+ CNS3XXX_CFG0_TYPE,
+ CNS3XXX_CFG1_TYPE,
+ CNS3XXX_NUM_ACCESS_TYPES,
+};
+
+struct cns3xxx_pcie {
+ struct map_desc cfg_bases[CNS3XXX_NUM_ACCESS_TYPES];
+ unsigned int irqs[2];
+ struct resource res_io;
+ struct resource res_mem;
+ struct hw_pci hw_pci;
+
+ bool linked;
+};
+
+static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */
+
+static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
+{
+ struct pci_sys_data *root = sysdata;
+
+ return &cns3xxx_pcie[root->domain];
+}
+
+static struct cns3xxx_pcie *pdev_to_cnspci(struct pci_dev *dev)
+{
+ return sysdata_to_cnspci(dev->sysdata);
+}
+
+static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
+{
+ return sysdata_to_cnspci(bus->sysdata);
+}
+
+static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
+ unsigned int devfn, int where)
+{
+ struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
+ int busno = bus->number;
+ int slot = PCI_SLOT(devfn);
+ int offset;
+ enum cns3xxx_access_type type;
+ void __iomem *base;
+
+ /* If there is no link, just show the CNS PCI bridge. */
+ if (!cnspci->linked && (busno > 0 || slot > 0))
+ return NULL;
+
+ /*
+ * The CNS PCI bridge doesn't fit into the PCI hierarchy, though
+ * we still want to access it. For this to work, we must place
+ * the first device on the same bus as the CNS PCI bridge.
+ */
+ if (busno == 0) {
+ if (slot > 1)
+ return NULL;
+ type = slot;
+ } else {
+ type = CNS3XXX_CFG1_TYPE;
+ }
+
+ base = (void __iomem *)cnspci->cfg_bases[type].virtual;
+ offset = ((busno & 0xf) << 20) | (devfn << 12) | (where & 0xffc);
+
+ return base + offset;
+}
+
+static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 v;
+ void __iomem *base;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ base = cns3xxx_pci_cfg_base(bus, devfn, where);
+ if (!base) {
+ *val = 0xffffffff;
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ v = __raw_readl(base);
+
+ if (bus->number == 0 && devfn == 0 &&
+ (where & 0xffc) == PCI_CLASS_REVISION) {
+ /*
+ * RC's class is 0xb, but Linux PCI driver needs 0x604
+ * for a PCIe bridge. So we must fixup the class code
+ * to 0x604 here.
+ */
+ v &= 0xff;
+ v |= 0x604 << 16;
+ }
+
+ *val = (v >> shift) & mask;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 v;
+ void __iomem *base;
+ u32 mask = (0x1ull << (size * 8)) - 1;
+ int shift = (where % 4) * 8;
+
+ base = cns3xxx_pci_cfg_base(bus, devfn, where);
+ if (!base)
+ return PCIBIOS_SUCCESSFUL;
+
+ v = __raw_readl(base);
+
+ v &= ~(mask << shift);
+ v |= (val & mask) << shift;
+
+ __raw_writel(v, base);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ struct cns3xxx_pcie *cnspci = sysdata_to_cnspci(sys);
+ struct resource *res_io = &cnspci->res_io;
+ struct resource *res_mem = &cnspci->res_mem;
+ struct resource **sysres = sys->resource;
+
+ BUG_ON(request_resource(&iomem_resource, res_io) ||
+ request_resource(&iomem_resource, res_mem));
+
+ sysres[0] = res_io;
+ sysres[1] = res_mem;
+
+ return 1;
+}
+
+static struct pci_ops cns3xxx_pcie_ops = {
+ .read = cns3xxx_pci_read_config,
+ .write = cns3xxx_pci_write_config,
+};
+
+static struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys);
+}
+
+static int cns3xxx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct cns3xxx_pcie *cnspci = pdev_to_cnspci(dev);
+ int irq = cnspci->irqs[slot];
+
+ pr_info("PCIe map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n",
+ pci_domain_nr(dev->bus), dev->bus->number, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), slot, pin, irq);
+
+ return irq;
+}
+
+static struct cns3xxx_pcie cns3xxx_pcie[] = {
+ [0] = {
+ .cfg_bases = {
+ [CNS3XXX_HOST_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_HOST_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG0_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG1_TYPE] = {
+ .virtual = CNS3XXX_PCIE0_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE0_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ },
+ .res_io = {
+ .name = "PCIe0 I/O space",
+ .start = CNS3XXX_PCIE0_IO_BASE,
+ .end = CNS3XXX_PCIE0_IO_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe0 non-prefetchable",
+ .start = CNS3XXX_PCIE0_MEM_BASE,
+ .end = CNS3XXX_PCIE0_MEM_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
+ .hw_pci = {
+ .domain = 0,
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = cns3xxx_pci_setup,
+ .scan = cns3xxx_pci_scan_bus,
+ .map_irq = cns3xxx_pcie_map_irq,
+ },
+ },
+ [1] = {
+ .cfg_bases = {
+ [CNS3XXX_HOST_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_HOST_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_HOST_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG0_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_CFG0_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG0_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ [CNS3XXX_CFG1_TYPE] = {
+ .virtual = CNS3XXX_PCIE1_CFG1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CNS3XXX_PCIE1_CFG1_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ },
+ .res_io = {
+ .name = "PCIe1 I/O space",
+ .start = CNS3XXX_PCIE1_IO_BASE,
+ .end = CNS3XXX_PCIE1_IO_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_IO,
+ },
+ .res_mem = {
+ .name = "PCIe1 non-prefetchable",
+ .start = CNS3XXX_PCIE1_MEM_BASE,
+ .end = CNS3XXX_PCIE1_MEM_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
+ .hw_pci = {
+ .domain = 1,
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = cns3xxx_pci_setup,
+ .scan = cns3xxx_pci_scan_bus,
+ .map_irq = cns3xxx_pcie_map_irq,
+ },
+ },
+};
+
+static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
+{
+ int port = cnspci->hw_pci.domain;
+ u32 reg;
+ unsigned long time;
+
+ reg = __raw_readl(MISC_PCIE_CTRL(port));
+ /*
+ * Enable Application Request to 1, it will exit L1 automatically,
+ * but when chip back, it will use another clock, still can use 0x1.
+ */
+ reg |= 0x3;
+ __raw_writel(reg, MISC_PCIE_CTRL(port));
+
+ pr_info("PCIe: Port[%d] Enable PCIe LTSSM\n", port);
+ pr_info("PCIe: Port[%d] Check data link layer...", port);
+
+ time = jiffies;
+ while (1) {
+ reg = __raw_readl(MISC_PCIE_PM_DEBUG(port));
+ if (reg & 0x1) {
+ pr_info("Link up.\n");
+ cnspci->linked = 1;
+ break;
+ } else if (time_after(jiffies, time + 50)) {
+ pr_info("Device not found.\n");
+ break;
+ }
+ }
+}
+
+static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
+{
+ int port = cnspci->hw_pci.domain;
+ struct pci_sys_data sd = {
+ .domain = port,
+ };
+ struct pci_bus bus = {
+ .number = 0,
+ .ops = &cns3xxx_pcie_ops,
+ .sysdata = &sd,
+ };
+ u32 io_base = cnspci->res_io.start >> 16;
+ u32 mem_base = cnspci->res_mem.start >> 16;
+ u32 host_base = cnspci->cfg_bases[CNS3XXX_HOST_TYPE].pfn;
+ u32 cfg0_base = cnspci->cfg_bases[CNS3XXX_CFG0_TYPE].pfn;
+ u32 devfn = 0;
+ u8 tmp8;
+ u16 pos;
+ u16 dc;
+
+ host_base = (__pfn_to_phys(host_base) - 1) >> 16;
+ cfg0_base = (__pfn_to_phys(cfg0_base) - 1) >> 16;
+
+ pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0);
+ pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1);
+ pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1);
+
+ pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8);
+ pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8);
+ pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8);
+
+ pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, host_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base);
+ pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, cfg0_base);
+
+ if (!cnspci->linked)
+ return;
+
+ /* Set Device Max_Read_Request_Size to 128 byte */
+ devfn = PCI_DEVFN(1, 0);
+ pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP);
+ pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
+ dc &= ~(0x3 << 12); /* Clear Device Control Register [14:12] */
+ pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc);
+ pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc);
+ if (!(dc & (0x3 << 12)))
+ pr_info("PCIe: Set Device Max_Read_Request_Size to 128 byte\n");
+
+ /* Disable PCIe0 Interrupt Mask INTA to INTD */
+ __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port));
+}
+
+static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+ return 0;
+}
+
+static int __init cns3xxx_pcie_init(void)
+{
+ int i;
+
+ hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+
+ for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) {
+ iotable_init(cns3xxx_pcie[i].cfg_bases,
+ ARRAY_SIZE(cns3xxx_pcie[i].cfg_bases));
+ cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i));
+ cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i));
+ cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
+ cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]);
+ pci_common_init(&cns3xxx_pcie[i].hw_pci);
+ }
+
+ pci_assign_unassigned_resources();
+
+ return 0;
+}
+device_initcall(cns3xxx_pcie_init);
diff --git a/arch/arm/mach-cns3xxx/pm.c b/arch/arm/mach-cns3xxx/pm.c
new file mode 100644
index 00000000..5e579552
--- /dev/null
+++ b/arch/arm/mach-cns3xxx/pm.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <asm/atomic.h>
+#include <mach/system.h>
+#include <mach/cns3xxx.h>
+#include <mach/pm.h>
+
+void cns3xxx_pwr_clk_en(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_CLK_GATE_REG);
+
+ reg |= (block & PM_CLK_GATE_REG_MASK);
+ __raw_writel(reg, PM_CLK_GATE_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_en);
+
+void cns3xxx_pwr_clk_dis(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_CLK_GATE_REG);
+
+ reg &= ~(block & PM_CLK_GATE_REG_MASK);
+ __raw_writel(reg, PM_CLK_GATE_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_clk_dis);
+
+void cns3xxx_pwr_power_up(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
+
+ reg &= ~(block & CNS3XXX_PWR_PLL_ALL);
+ __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
+
+ /* Wait for 300us for the PLL output clock locked. */
+ udelay(300);
+};
+EXPORT_SYMBOL(cns3xxx_pwr_power_up);
+
+void cns3xxx_pwr_power_down(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_PLL_HM_PD_CTRL_REG);
+
+ /* write '1' to power down */
+ reg |= (block & CNS3XXX_PWR_PLL_ALL);
+ __raw_writel(reg, PM_PLL_HM_PD_CTRL_REG);
+};
+EXPORT_SYMBOL(cns3xxx_pwr_power_down);
+
+static void cns3xxx_pwr_soft_rst_force(unsigned int block)
+{
+ u32 reg = __raw_readl(PM_SOFT_RST_REG);
+
+ /*
+ * bit 0, 28, 29 => program low to reset,
+ * the other else program low and then high
+ */
+ if (block & 0x30000001) {
+ reg &= ~(block & PM_SOFT_RST_REG_MASK);
+ } else {
+ reg &= ~(block & PM_SOFT_RST_REG_MASK);
+ __raw_writel(reg, PM_SOFT_RST_REG);
+ reg |= (block & PM_SOFT_RST_REG_MASK);
+ }
+
+ __raw_writel(reg, PM_SOFT_RST_REG);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst_force);
+
+void cns3xxx_pwr_soft_rst(unsigned int block)
+{
+ static unsigned int soft_reset;
+
+ if (soft_reset & block) {
+ /* SPI/I2C/GPIO use the same block, reset once. */
+ return;
+ } else {
+ soft_reset |= block;
+ }
+ cns3xxx_pwr_soft_rst_force(block);
+}
+EXPORT_SYMBOL(cns3xxx_pwr_soft_rst);
+
+void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA.
+ */
+ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(GLOBAL));
+}
+
+/*
+ * cns3xxx_cpu_clock - return CPU/L2 clock
+ * aclk: cpu clock/2
+ * hclk: cpu clock/4
+ * pclk: cpu clock/8
+ */
+int cns3xxx_cpu_clock(void)
+{
+ u32 reg = __raw_readl(PM_CLK_CTRL_REG);
+ int cpu;
+ int cpu_sel;
+ int div_sel;
+
+ cpu_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_PLL_CPU_SEL) & 0xf;
+ div_sel = (reg >> PM_CLK_CTRL_REG_OFFSET_CPU_CLK_DIV) & 0x3;
+
+ cpu = (300 + ((cpu_sel / 3) * 100) + ((cpu_sel % 3) * 33)) >> div_sel;
+
+ return cpu;
+}
+EXPORT_SYMBOL(cns3xxx_cpu_clock);
+
+atomic_t usb_pwr_ref = ATOMIC_INIT(0);
+EXPORT_SYMBOL(usb_pwr_ref);
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
new file mode 100644
index 00000000..c0deacae
--- /dev/null
+++ b/arch/arm/mach-davinci/Kconfig
@@ -0,0 +1,266 @@
+if ARCH_DAVINCI
+
+config AINTC
+ bool
+
+config CP_INTC
+ bool
+
+config ARCH_DAVINCI_DMx
+ select CPU_ARM926T
+ bool
+
+menu "TI DaVinci Implementations"
+
+comment "DaVinci Core Type"
+
+config ARCH_DAVINCI_DM644x
+ bool "DaVinci 644x based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DM355
+ bool "DaVinci 355 based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DM646x
+ bool "DaVinci 646x based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_DA830
+ bool "DA830/OMAP-L137/AM17x based system"
+ select CP_INTC
+ select ARCH_DAVINCI_DA8XX
+ select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1
+
+config ARCH_DAVINCI_DA850
+ bool "DA850/OMAP-L138/AM18x based system"
+ select CP_INTC
+ select ARCH_DAVINCI_DA8XX
+ select ARCH_HAS_CPUFREQ
+
+config ARCH_DAVINCI_DA8XX
+ select CPU_ARM926T
+ bool
+
+config ARCH_DAVINCI_DM365
+ bool "DaVinci 365 based system"
+ select AINTC
+ select ARCH_DAVINCI_DMx
+
+config ARCH_DAVINCI_TNETV107X
+ select CPU_V6
+ select CP_INTC
+ bool "TNETV107X based system"
+
+comment "DaVinci Board Type"
+
+config MACH_DAVINCI_EVM
+ bool "TI DM644x EVM"
+ default ARCH_DAVINCI_DM644x
+ depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM644x EVM
+
+config MACH_SFFSDR
+ bool "Lyrtech SFFSDR"
+ depends on ARCH_DAVINCI_DM644x
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the Lyrtech Small Form Factor
+ Software Defined Radio (SFFSDR) board.
+
+config MACH_NEUROS_OSD2
+ bool "Neuros OSD2 Open Television Set Top Box"
+ depends on ARCH_DAVINCI_DM644x
+ help
+ Configure this option to specify the whether the board used
+ for development is a Neuros OSD2 Open Set Top Box.
+
+config MACH_DAVINCI_DM355_EVM
+ bool "TI DM355 EVM"
+ default ARCH_DAVINCI_DM355
+ depends on ARCH_DAVINCI_DM355
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM355 EVM
+
+config MACH_DM355_LEOPARD
+ bool "DM355 Leopard board"
+ depends on ARCH_DAVINCI_DM355
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM355 Leopard board.
+
+config MACH_DAVINCI_DM6467_EVM
+ bool "TI DM6467 EVM"
+ default ARCH_DAVINCI_DM646x
+ depends on ARCH_DAVINCI_DM646x
+ select MACH_DAVINCI_DM6467TEVM
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify the whether the board used
+ for development is a DM6467 EVM
+
+config MACH_DAVINCI_DM6467TEVM
+ bool
+
+config MACH_DAVINCI_DM365_EVM
+ bool "TI DM365 EVM"
+ default ARCH_DAVINCI_DM365
+ depends on ARCH_DAVINCI_DM365
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Configure this option to specify whether the board used
+ for development is a DM365 EVM
+
+config MACH_DAVINCI_DA830_EVM
+ bool "TI DA830/OMAP-L137/AM17x Reference Platform"
+ default ARCH_DAVINCI_DA830
+ depends on ARCH_DAVINCI_DA830
+ select GPIO_PCF857X
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module.
+
+choice
+ prompt "Select DA830/OMAP-L137/AM17x UI board peripheral"
+ depends on MACH_DAVINCI_DA830_EVM
+ help
+ The presence of UI card on the DA830/OMAP-L137/AM17x EVM is
+ detected automatically based on successful probe of the I2C
+ based GPIO expander on that board. This option selected in this
+ menu has an effect only in case of a successful UI card detection.
+
+config DA830_UI_LCD
+ bool "LCD"
+ help
+ Say Y here to use the LCD as a framebuffer or simple character
+ display.
+
+config DA830_UI_NAND
+ bool "NAND flash"
+ help
+ Say Y here to use the NAND flash. Do not forget to setup
+ the switch correctly.
+endchoice
+
+config MACH_DAVINCI_DA850_EVM
+ bool "TI DA850/OMAP-L138/AM18x Reference Platform"
+ default ARCH_DAVINCI_DA850
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module.
+
+choice
+ prompt "Select peripherals connected to expander on UI board"
+ depends on MACH_DAVINCI_DA850_EVM
+ help
+ The presence of User Interface (UI) card on the DA850/OMAP-L138/AM18x
+ EVM is detected automatically based on successful probe of the I2C
+ based GPIO expander on that card. This option selected in this
+ menu has an effect only in case of a successful UI card detection.
+
+config DA850_UI_NONE
+ bool "No peripheral is enabled"
+ help
+ Say Y if you do not want to enable any of the peripherals connected
+ to TCA6416 expander on DA850/OMAP-L138/AM18x EVM UI card
+
+config DA850_UI_RMII
+ bool "RMII Ethernet PHY"
+ help
+ Say Y if you want to use the RMII PHY on the DA850/OMAP-L138/AM18x
+ EVM. This PHY is found on the UI daughter card that is supplied with
+ the EVM.
+ NOTE: Please take care while choosing this option, MII PHY will
+ not be functional if RMII mode is selected.
+
+endchoice
+
+config GPIO_PCA953X
+ default MACH_DAVINCI_DA850_EVM
+
+config KEYBOARD_GPIO_POLLED
+ default MACH_DAVINCI_DA850_EVM
+
+config MACH_TNETV107X
+ bool "TI TNETV107X Reference Platform"
+ default ARCH_DAVINCI_TNETV107X
+ depends on ARCH_DAVINCI_TNETV107X
+ help
+ Say Y here to select the TI TNETV107X Evaluation Module.
+
+config MACH_MITYOMAPL138
+ bool "Critical Link MityDSP-L138/MityARM-1808 SoM"
+ depends on ARCH_DAVINCI_DA850
+ select MISC_DEVICES
+ select EEPROM_AT24
+ select I2C
+ help
+ Say Y here to select the Critical Link MityDSP-L138/MityARM-1808
+ System on Module. Information on this SoM may be found at
+ http://www.mitydsp.com
+
+config MACH_OMAPL138_HAWKBOARD
+ bool "TI AM1808 / OMAPL-138 Hawkboard platform"
+ depends on ARCH_DAVINCI_DA850
+ help
+ Say Y here to select the TI AM1808 / OMAPL-138 Hawkboard platform .
+ Information of this board may be found at
+ http://www.hawkboard.org/
+
+config DAVINCI_MUX
+ bool "DAVINCI multiplexing support"
+ depends on ARCH_DAVINCI
+ default y
+ help
+ Pin multiplexing support for DAVINCI boards. If your bootloader
+ sets the multiplexing correctly, say N. Otherwise, or if unsure,
+ say Y.
+
+config DAVINCI_MUX_DEBUG
+ bool "Multiplexing debug output"
+ depends on DAVINCI_MUX
+ help
+ Makes the multiplexing functions print out a lot of debug info.
+ This is useful if you want to find out the correct values of the
+ multiplexing registers.
+
+config DAVINCI_MUX_WARNINGS
+ bool "Warn about pins the bootloader didn't set up"
+ depends on DAVINCI_MUX
+ help
+ Choose Y here to warn whenever driver initialization logic needs
+ to change the pin multiplexing setup. When there are no warnings
+ printed, it's safe to deselect DAVINCI_MUX for your product.
+
+config DAVINCI_RESET_CLOCKS
+ bool "Reset unused clocks during boot"
+ depends on ARCH_DAVINCI
+ help
+ Say Y if you want to reset unused clocks during boot.
+ This option saves power, but assumes all drivers are
+ using the clock framework. Broken drivers that do not
+ yet use clock framework may not work with this option.
+ If you are booting from another operating system, you
+ probably do not want this option enabled until your
+ device drivers work properly.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
new file mode 100644
index 00000000..0b87a1ca
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile
@@ -0,0 +1,42 @@
+#
+# Makefile for the linux kernel.
+#
+#
+
+# Common objects
+obj-y := time.o clock.o serial.o io.o psc.o \
+ gpio.o dma.o usb.o common.o sram.o aemif.o
+
+obj-$(CONFIG_DAVINCI_MUX) += mux.o
+
+# Chip specific
+obj-$(CONFIG_ARCH_DAVINCI_DM644x) += dm644x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM355) += dm355.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o
+obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
+
+obj-$(CONFIG_AINTC) += irq.o
+obj-$(CONFIG_CP_INTC) += cp_intc.o
+
+# Board specific
+obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
+obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
+obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
+obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
+obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
+obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
+obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
+obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
+obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
+obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o
+obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o
+
+# Power Management
+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_SUSPEND) += pm.o sleep.o
diff --git a/arch/arm/mach-davinci/Makefile.boot b/arch/arm/mach-davinci/Makefile.boot
new file mode 100644
index 00000000..db97ef2c
--- /dev/null
+++ b/arch/arm/mach-davinci/Makefile.boot
@@ -0,0 +1,13 @@
+ifeq ($(CONFIG_ARCH_DAVINCI_DA8XX),y)
+ifeq ($(CONFIG_ARCH_DAVINCI_DMx),y)
+$(error Cannot enable DaVinci and DA8XX platforms concurrently)
+else
+ zreladdr-y := 0xc0008000
+params_phys-y := 0xc0000100
+initrd_phys-y := 0xc0800000
+endif
+else
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
+endif
diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c
new file mode 100644
index 00000000..1ce70a91
--- /dev/null
+++ b/arch/arm/mach-davinci/aemif.c
@@ -0,0 +1,133 @@
+/*
+ * AEMIF support for DaVinci SoCs
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/time.h>
+
+#include <mach/aemif.h>
+
+/* Timing value configuration */
+
+#define TA(x) ((x) << 2)
+#define RHOLD(x) ((x) << 4)
+#define RSTROBE(x) ((x) << 7)
+#define RSETUP(x) ((x) << 13)
+#define WHOLD(x) ((x) << 17)
+#define WSTROBE(x) ((x) << 20)
+#define WSETUP(x) ((x) << 26)
+
+#define TA_MAX 0x3
+#define RHOLD_MAX 0x7
+#define RSTROBE_MAX 0x3f
+#define RSETUP_MAX 0xf
+#define WHOLD_MAX 0x7
+#define WSTROBE_MAX 0x3f
+#define WSETUP_MAX 0xf
+
+#define TIMING_MASK (TA(TA_MAX) | \
+ RHOLD(RHOLD_MAX) | \
+ RSTROBE(RSTROBE_MAX) | \
+ RSETUP(RSETUP_MAX) | \
+ WHOLD(WHOLD_MAX) | \
+ WSTROBE(WSTROBE_MAX) | \
+ WSETUP(WSETUP_MAX))
+
+/*
+ * aemif_calc_rate - calculate timing data.
+ * @wanted: The cycle time needed in nanoseconds.
+ * @clk: The input clock rate in kHz.
+ * @max: The maximum divider value that can be programmed.
+ *
+ * On success, returns the calculated timing value minus 1 for easy
+ * programming into AEMIF timing registers, else negative errno.
+ */
+static int aemif_calc_rate(int wanted, unsigned long clk, int max)
+{
+ int result;
+
+ result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
+
+ pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted);
+
+ /* It is generally OK to have a more relaxed timing than requested... */
+ if (result < 0)
+ result = 0;
+
+ /* ... But configuring tighter timings is not an option. */
+ else if (result > max)
+ result = -EINVAL;
+
+ return result;
+}
+
+/**
+ * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface
+ * @t: timing values to be progammed
+ * @base: The virtual base address of the AEMIF interface
+ * @cs: chip-select to program the timing values for
+ *
+ * This function programs the given timing values (in real clock) into the
+ * AEMIF registers taking the AEMIF clock into account.
+ *
+ * This function does not use any locking while programming the AEMIF
+ * because it is expected that there is only one user of a given
+ * chip-select.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs)
+{
+ unsigned set, val;
+ int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ unsigned offset = A1CR_OFFSET + cs * 4;
+ struct clk *aemif_clk;
+ unsigned long clkrate;
+
+ if (!t)
+ return 0; /* Nothing to do */
+
+ aemif_clk = clk_get(NULL, "aemif");
+ if (IS_ERR(aemif_clk))
+ return PTR_ERR(aemif_clk);
+
+ clkrate = clk_get_rate(aemif_clk);
+
+ clkrate /= 1000; /* turn clock into kHz for ease of use */
+
+ ta = aemif_calc_rate(t->ta, clkrate, TA_MAX);
+ rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX);
+ rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX);
+ rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX);
+ whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX);
+ wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX);
+ wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX);
+
+ if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
+ whold < 0 || wstrobe < 0 || wsetup < 0) {
+ pr_err("%s: cannot get suitable timings\n", __func__);
+ return -EINVAL;
+ }
+
+ set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
+ WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
+
+ val = __raw_readl(base + offset);
+ val &= ~TIMING_MASK;
+ val |= set;
+ __raw_writel(val, base + offset);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_aemif_setup_timing);
diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c
new file mode 100644
index 00000000..8bc3701a
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da830-evm.c
@@ -0,0 +1,684 @@
+/*
+ * TI DA830/OMAP L137 EVM board
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c
+ *
+ * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/da8xx.h>
+#include <mach/usb.h>
+#include <mach/aemif.h>
+#include <mach/spi.h>
+
+#define DA830_EVM_PHY_ID ""
+/*
+ * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4].
+ */
+#define ON_BD_USB_DRV GPIO_TO_PIN(1, 15)
+#define ON_BD_USB_OVC GPIO_TO_PIN(2, 4)
+
+static const short da830_evm_usb11_pins[] = {
+ DA830_GPIO1_15, DA830_GPIO2_4,
+ -1
+};
+
+static da8xx_ocic_handler_t da830_evm_usb_ocic_handler;
+
+static int da830_evm_usb_set_power(unsigned port, int on)
+{
+ gpio_set_value(ON_BD_USB_DRV, on);
+ return 0;
+}
+
+static int da830_evm_usb_get_power(unsigned port)
+{
+ return gpio_get_value(ON_BD_USB_DRV);
+}
+
+static int da830_evm_usb_get_oci(unsigned port)
+{
+ return !gpio_get_value(ON_BD_USB_OVC);
+}
+
+static irqreturn_t da830_evm_usb_ocic_irq(int, void *);
+
+static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+ int irq = gpio_to_irq(ON_BD_USB_OVC);
+ int error = 0;
+
+ if (handler != NULL) {
+ da830_evm_usb_ocic_handler = handler;
+
+ error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED |
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "OHCI over-current indicator", NULL);
+ if (error)
+ printk(KERN_ERR "%s: could not request IRQ to watch "
+ "over-current indicator changes\n", __func__);
+ } else
+ free_irq(irq, NULL);
+
+ return error;
+}
+
+static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = {
+ .set_power = da830_evm_usb_set_power,
+ .get_power = da830_evm_usb_get_power,
+ .get_oci = da830_evm_usb_get_oci,
+ .ocic_notify = da830_evm_usb_ocic_notify,
+
+ /* TPS2065 switch @ 5V */
+ .potpgt = (3 + 1) / 2, /* 3 ms max */
+};
+
+static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id)
+{
+ da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1);
+ return IRQ_HANDLED;
+}
+
+static __init void da830_evm_usb_init(void)
+{
+ u32 cfgchip2;
+ int ret;
+
+ /*
+ * Set up USB clock/mode in the CFGCHIP2 register.
+ * FYI: CFGCHIP2 is 0x0000ef00 initially.
+ */
+ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* USB2.0 PHY reference clock is 24 MHz */
+ cfgchip2 &= ~CFGCHIP2_REFFREQ;
+ cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
+
+ /*
+ * Select internal reference clock for USB 2.0 PHY
+ * and use it as a clock source for USB 1.1 PHY
+ * (this is the default setting anyway).
+ */
+ cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX;
+ cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX;
+
+ /*
+ * We have to override VBUS/ID signals when MUSB is configured into the
+ * host-only mode -- ID pin will float if no cable is connected, so the
+ * controller won't be able to drive VBUS thinking that it's a B-device.
+ * Otherwise, we want to use the OTG mode and enable VBUS comparators.
+ */
+ cfgchip2 &= ~CFGCHIP2_OTGMODE;
+#ifdef CONFIG_USB_MUSB_HOST
+ cfgchip2 |= CFGCHIP2_FORCE_HOST;
+#else
+ cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN;
+#endif
+
+ __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ /* USB_REFCLKIN is not used. */
+ ret = davinci_cfg_reg(DA830_USB0_DRVVBUS);
+ if (ret)
+ pr_warning("%s: USB 2.0 PinMux setup failed: %d\n",
+ __func__, ret);
+ else {
+ /*
+ * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A),
+ * with the power on to power good time of 3 ms.
+ */
+ ret = da8xx_register_usb20(1000, 3);
+ if (ret)
+ pr_warning("%s: USB 2.0 registration failed: %d\n",
+ __func__, ret);
+ }
+
+ ret = davinci_cfg_reg_list(da830_evm_usb11_pins);
+ if (ret) {
+ pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
+ if (ret) {
+ printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+ "power control: %d\n", __func__, ret);
+ return;
+ }
+ gpio_direction_output(ON_BD_USB_DRV, 0);
+
+ ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
+ if (ret) {
+ printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port "
+ "over-current indicator: %d\n", __func__, ret);
+ return;
+ }
+ gpio_direction_input(ON_BD_USB_OVC);
+
+ ret = da8xx_register_usb11(&da830_evm_usb11_pdata);
+ if (ret)
+ pr_warning("%s: USB 1.1 registration failed: %d\n",
+ __func__, ret);
+}
+
+static struct davinci_uart_config da830_evm_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static const short da830_evm_mcasp1_pins[] = {
+ DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1, DA830_AHCLKR1, DA830_AFSR1,
+ DA830_AMUTE1, DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_5,
+ DA830_ACLKR1, DA830_AXR1_6, DA830_AXR1_7, DA830_AXR1_8, DA830_AXR1_10,
+ DA830_AXR1_11,
+ -1
+};
+
+static u8 da830_iis_serializer_direction[] = {
+ RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, TX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static struct snd_platform_data da830_evm_snd_data = {
+ .tx_dma_offset = 0x2000,
+ .rx_dma_offset = 0x2000,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(da830_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = da830_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+};
+
+/*
+ * GPIO2[1] is used as MMC_SD_WP and GPIO2[2] as MMC_SD_INS.
+ */
+static const short da830_evm_mmc_sd_pins[] = {
+ DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+ DA830_MMCSD_CMD, DA830_GPIO2_1, DA830_GPIO2_2,
+ -1
+};
+
+#define DA830_MMCSD_WP_PIN GPIO_TO_PIN(2, 1)
+#define DA830_MMCSD_CD_PIN GPIO_TO_PIN(2, 2)
+
+static int da830_evm_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA830_MMCSD_WP_PIN);
+}
+
+static int da830_evm_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA830_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da830_evm_mmc_config = {
+ .get_ro = da830_evm_mmc_get_ro,
+ .get_cd = da830_evm_mmc_get_cd,
+ .wires = 8,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static inline void da830_evm_init_mmc(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(da830_evm_mmc_sd_pins);
+ if (ret) {
+ pr_warning("da830_evm_init: mmc/sd mux setup failed: %d\n",
+ ret);
+ return;
+ }
+
+ ret = gpio_request(DA830_MMCSD_WP_PIN, "MMC WP");
+ if (ret) {
+ pr_warning("da830_evm_init: can not open GPIO %d\n",
+ DA830_MMCSD_WP_PIN);
+ return;
+ }
+ gpio_direction_input(DA830_MMCSD_WP_PIN);
+
+ ret = gpio_request(DA830_MMCSD_CD_PIN, "MMC CD\n");
+ if (ret) {
+ pr_warning("da830_evm_init: can not open GPIO %d\n",
+ DA830_MMCSD_CD_PIN);
+ return;
+ }
+ gpio_direction_input(DA830_MMCSD_CD_PIN);
+
+ ret = da8xx_register_mmcsd0(&da830_evm_mmc_config);
+ if (ret) {
+ pr_warning("da830_evm_init: mmc/sd registration failed: %d\n",
+ ret);
+ gpio_free(DA830_MMCSD_WP_PIN);
+ }
+}
+
+/*
+ * UI board NAND/NOR flashes only use 8-bit data bus.
+ */
+static const short da830_evm_emif25_pins[] = {
+ DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+ DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+ DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+ DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+ DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+ DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE,
+ DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0,
+ -1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+#ifdef CONFIG_DA830_UI_NAND
+static struct mtd_partition da830_evm_nand_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ [0] = {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ [1] = {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* kernel */
+ [2] = {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ /* file system */
+ [3] = {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+/* flash bbt decriptors */
+static uint8_t da830_evm_nand_bbt_pattern[] = { 'B', 'b', 't', '0' };
+static uint8_t da830_evm_nand_mirror_pattern[] = { '1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr da830_evm_nand_bbt_main_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+ NAND_BBT_WRITE | NAND_BBT_2BIT |
+ NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 2,
+ .len = 4,
+ .veroffs = 16,
+ .maxblocks = 4,
+ .pattern = da830_evm_nand_bbt_pattern
+};
+
+static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE |
+ NAND_BBT_WRITE | NAND_BBT_2BIT |
+ NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+ .offs = 2,
+ .len = 4,
+ .veroffs = 16,
+ .maxblocks = 4,
+ .pattern = da830_evm_nand_mirror_pattern
+};
+
+static struct davinci_aemif_timing da830_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
+static struct davinci_nand_pdata da830_evm_nand_pdata = {
+ .parts = da830_evm_nand_partitions,
+ .nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .ecc_bits = 4,
+ .options = NAND_USE_FLASH_BBT,
+ .bbt_td = &da830_evm_nand_bbt_main_descr,
+ .bbt_md = &da830_evm_nand_bbt_mirror_descr,
+ .timing = &da830_evm_nandflash_timing,
+};
+
+static struct resource da830_evm_nand_resources[] = {
+ [0] = { /* First memory resource is NAND I/O window */
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* Second memory resource is AEMIF control registers */
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da830_evm_nand_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &da830_evm_nand_pdata,
+ },
+ .num_resources = ARRAY_SIZE(da830_evm_nand_resources),
+ .resource = da830_evm_nand_resources,
+};
+
+static inline void da830_evm_init_nand(int mux_mode)
+{
+ int ret;
+
+ if (HAS_MMC) {
+ pr_warning("WARNING: both MMC/SD and NAND are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable MMC/SD for NAND support.\n");
+ return;
+ }
+
+ ret = davinci_cfg_reg_list(da830_evm_emif25_pins);
+ if (ret)
+ pr_warning("da830_evm_init: emif25 mux setup failed: %d\n",
+ ret);
+
+ ret = platform_device_register(&da830_evm_nand_device);
+ if (ret)
+ pr_warning("da830_evm_init: NAND device not registered.\n");
+
+ gpio_direction_output(mux_mode, 1);
+}
+#else
+static inline void da830_evm_init_nand(int mux_mode) { }
+#endif
+
+#ifdef CONFIG_DA830_UI_LCD
+static inline void da830_evm_init_lcdc(int mux_mode)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(da830_lcdcntl_pins);
+ if (ret)
+ pr_warning("da830_evm_init: lcdcntl mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_lcdc(&sharp_lcd035q3dg01_pdata);
+ if (ret)
+ pr_warning("da830_evm_init: lcd setup failed: %d\n", ret);
+
+ gpio_direction_output(mux_mode, 0);
+}
+#else
+static inline void da830_evm_init_lcdc(int mux_mode) { }
+#endif
+
+static struct at24_platform_data da830_evm_i2c_eeprom_info = {
+ .byte_len = SZ_256K / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static int __init da830_evm_ui_expander_setup(struct i2c_client *client,
+ int gpio, unsigned ngpio, void *context)
+{
+ gpio_request(gpio + 6, "UI MUX_MODE");
+
+ /* Drive mux mode low to match the default without UI card */
+ gpio_direction_output(gpio + 6, 0);
+
+ da830_evm_init_lcdc(gpio + 6);
+
+ da830_evm_init_nand(gpio + 6);
+
+ return 0;
+}
+
+static int da830_evm_ui_expander_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *context)
+{
+ gpio_free(gpio + 6);
+ return 0;
+}
+
+static struct pcf857x_platform_data __initdata da830_evm_ui_expander_info = {
+ .gpio_base = DAVINCI_N_GPIO,
+ .setup = da830_evm_ui_expander_setup,
+ .teardown = da830_evm_ui_expander_teardown,
+};
+
+static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &da830_evm_i2c_eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x3f),
+ .platform_data = &da830_evm_ui_expander_info,
+ },
+};
+
+static struct davinci_i2c_platform_data da830_evm_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da830/omap-l137 EVM, hence
+ * they are being reserved for codecs on the DSP side.
+ */
+static const s16 da830_dma_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 2},
+ {12, 2},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da830_dma_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 2},
+ {12, 2},
+ {24, 4},
+ {30, 26},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da830_edma_rsv[] = {
+ {
+ .rsv_chans = da830_dma_rsv_chans,
+ .rsv_slots = da830_dma_rsv_slots,
+ },
+};
+
+static struct mtd_partition da830evm_spiflash_part[] = {
+ [0] = {
+ .name = "DSP-UBL",
+ .offset = 0,
+ .size = SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "ARM-UBL",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16K + SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K - SZ_32K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "U-Boot-Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16K,
+ .mask_flags = 0,
+ },
+ [4] = {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct flash_platform_data da830evm_spiflash_data = {
+ .name = "m25p80",
+ .parts = da830evm_spiflash_part,
+ .nr_parts = ARRAY_SIZE(da830evm_spiflash_part),
+ .type = "w25x32",
+};
+
+static struct davinci_spi_config da830evm_spiflash_cfg = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info da830evm_spi_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &da830evm_spiflash_data,
+ .controller_data = &da830evm_spiflash_cfg,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static __init void da830_evm_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ int ret;
+
+ ret = da830_register_edma(da830_edma_rsv);
+ if (ret)
+ pr_warning("da830_evm_init: edma registration failed: %d\n",
+ ret);
+
+ ret = davinci_cfg_reg_list(da830_i2c0_pins);
+ if (ret)
+ pr_warning("da830_evm_init: i2c0 mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_i2c(0, &da830_evm_i2c_0_pdata);
+ if (ret)
+ pr_warning("da830_evm_init: i2c0 registration failed: %d\n",
+ ret);
+
+ da830_evm_usb_init();
+
+ soc_info->emac_pdata->rmii_en = 1;
+ soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID;
+
+ ret = davinci_cfg_reg_list(da830_cpgmac_pins);
+ if (ret)
+ pr_warning("da830_evm_init: cpgmac mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("da830_evm_init: emac registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+ ret);
+
+ davinci_serial_init(&da830_evm_uart_config);
+ i2c_register_board_info(1, da830_evm_i2c_devices,
+ ARRAY_SIZE(da830_evm_i2c_devices));
+
+ ret = davinci_cfg_reg_list(da830_evm_mcasp1_pins);
+ if (ret)
+ pr_warning("da830_evm_init: mcasp1 mux setup failed: %d\n",
+ ret);
+
+ da8xx_register_mcasp(1, &da830_evm_snd_data);
+
+ da830_evm_init_mmc();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("da830_evm_init: rtc setup failed: %d\n", ret);
+
+ ret = da8xx_register_spi(0, da830evm_spi_info,
+ ARRAY_SIZE(da830evm_spi_info));
+ if (ret)
+ pr_warning("da830_evm_init: spi 0 registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da830_evm_console_init(void)
+{
+ if (!machine_is_davinci_da830_evm())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da830_evm_console_init);
+#endif
+
+static void __init da830_evm_map_io(void)
+{
+ da830_init();
+}
+
+MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = da830_evm_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = da830_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
new file mode 100644
index 00000000..f8936174
--- /dev/null
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -0,0 +1,1292 @@
+/*
+ * TI DA850/OMAP-L138 EVM board
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/board-da830-evm.c
+ * Original Copyrights follow:
+ *
+ * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/input.h>
+#include <linux/mfd/tps6507x.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/tps6507x.h>
+#include <linux/input/tps6507x-ts.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+#include <mach/mux.h>
+#include <mach/aemif.h>
+#include <mach/spi.h>
+
+#define DA850_EVM_PHY_ID "0:00"
+#define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8)
+#define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15)
+
+#define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0)
+#define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1)
+
+#define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6)
+
+static struct mtd_partition da850evm_spiflash_part[] = {
+ [0] = {
+ .name = "UBL",
+ .offset = 0,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "U-Boot-Env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M + SZ_512K,
+ .mask_flags = 0,
+ },
+ [4] = {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ [5] = {
+ .name = "MAC-Address",
+ .offset = SZ_8M - SZ_64K,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct flash_platform_data da850evm_spiflash_data = {
+ .name = "m25p80",
+ .parts = da850evm_spiflash_part,
+ .nr_parts = ARRAY_SIZE(da850evm_spiflash_part),
+ .type = "m25p64",
+};
+
+static struct davinci_spi_config da850evm_spiflash_cfg = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info da850evm_spi_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &da850evm_spiflash_data,
+ .controller_data = &da850evm_spiflash_cfg,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+#ifdef CONFIG_MTD
+static void da850_evm_m25p80_notify_add(struct mtd_info *mtd)
+{
+ char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+ size_t retlen;
+
+ if (!strcmp(mtd->name, "MAC-Address")) {
+ mtd->read(mtd, 0, ETH_ALEN, &retlen, mac_addr);
+ if (retlen == ETH_ALEN)
+ pr_info("Read MAC addr from SPI Flash: %pM\n",
+ mac_addr);
+ }
+}
+
+static struct mtd_notifier da850evm_spi_notifier = {
+ .add = da850_evm_m25p80_notify_add,
+};
+
+static void da850_evm_setup_mac_addr(void)
+{
+ register_mtd_user(&da850evm_spi_notifier);
+}
+#else
+static void da850_evm_setup_mac_addr(void) { }
+#endif
+
+static struct mtd_partition da850_evm_norflash_partition[] = {
+ {
+ .name = "bootloaders + env",
+ .offset = 0,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct physmap_flash_data da850_evm_norflash_data = {
+ .width = 2,
+ .parts = da850_evm_norflash_partition,
+ .nr_parts = ARRAY_SIZE(da850_evm_norflash_partition),
+};
+
+static struct resource da850_evm_norflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS2_BASE,
+ .end = DA8XX_AEMIF_CS2_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_evm_norflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &da850_evm_norflash_data,
+ },
+ .num_resources = 1,
+ .resource = da850_evm_norflash_resource,
+};
+
+static struct davinci_pm_config da850_pm_pdata = {
+ .sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+ .name = "pm-davinci",
+ .dev = {
+ .platform_data = &da850_pm_pdata,
+ },
+ .id = -1,
+};
+
+/* DA850/OMAP-L138 EVM includes a 512 MByte large-page NAND flash
+ * (128K blocks). It may be used instead of the (default) SPI flash
+ * to boot, using TI's tools to install the secondary boot loader
+ * (UBL) and U-Boot.
+ */
+static struct mtd_partition da850_evm_nandflash_partition[] = {
+ {
+ .name = "u-boot env",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "UBL",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = 0x200000,
+ .size = SZ_2M,
+ .mask_flags = 0,
+ },
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct davinci_aemif_timing da850_evm_nandflash_timing = {
+ .wsetup = 24,
+ .wstrobe = 21,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 50,
+ .rhold = 0,
+ .ta = 20,
+};
+
+static struct davinci_nand_pdata da850_evm_nandflash_data = {
+ .parts = da850_evm_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .ecc_bits = 4,
+ .options = NAND_USE_FLASH_BBT,
+ .timing = &da850_evm_nandflash_timing,
+};
+
+static struct resource da850_evm_nandflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da850_evm_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &da850_evm_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(da850_evm_nandflash_resource),
+ .resource = da850_evm_nandflash_resource,
+};
+
+static struct platform_device *da850_evm_devices[] __initdata = {
+ &da850_evm_nandflash_device,
+ &da850_evm_norflash_device,
+};
+
+#define DA8XX_AEMIF_CE2CFG_OFFSET 0x10
+#define DA8XX_AEMIF_ASIZE_16BIT 0x1
+
+static void __init da850_evm_init_nor(void)
+{
+ void __iomem *aemif_addr;
+
+ aemif_addr = ioremap(DA8XX_AEMIF_CTL_BASE, SZ_32K);
+
+ /* Configure data bus width of CS2 to 16 bit */
+ writel(readl(aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET) |
+ DA8XX_AEMIF_ASIZE_16BIT,
+ aemif_addr + DA8XX_AEMIF_CE2CFG_OFFSET);
+
+ iounmap(aemif_addr);
+}
+
+static const short da850_evm_nand_pins[] = {
+ DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3,
+ DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7,
+ DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4,
+ DA850_NEMA_WE, DA850_NEMA_OE,
+ -1
+};
+
+static const short da850_evm_nor_pins[] = {
+ DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2,
+ DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1,
+ DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5,
+ DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9,
+ DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13,
+ DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1,
+ DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5,
+ DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9,
+ DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13,
+ DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17,
+ DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21,
+ DA850_EMA_A_22, DA850_EMA_A_23,
+ -1
+};
+
+#if defined(CONFIG_MMC_DAVINCI) || \
+ defined(CONFIG_MMC_DAVINCI_MODULE)
+#define HAS_MMC 1
+#else
+#define HAS_MMC 0
+#endif
+
+static inline void da850_evm_setup_nor_nand(void)
+{
+ int ret = 0;
+
+ if (!HAS_MMC) {
+ ret = davinci_cfg_reg_list(da850_evm_nand_pins);
+ if (ret)
+ pr_warning("da850_evm_init: nand mux setup failed: "
+ "%d\n", ret);
+
+ ret = davinci_cfg_reg_list(da850_evm_nor_pins);
+ if (ret)
+ pr_warning("da850_evm_init: nor mux setup failed: %d\n",
+ ret);
+
+ da850_evm_init_nor();
+
+ platform_add_devices(da850_evm_devices,
+ ARRAY_SIZE(da850_evm_devices));
+ }
+}
+
+#ifdef CONFIG_DA850_UI_RMII
+static inline void da850_evm_setup_emac_rmii(int rmii_sel)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ soc_info->emac_pdata->rmii_en = 1;
+ gpio_set_value_cansleep(rmii_sel, 0);
+}
+#else
+static inline void da850_evm_setup_emac_rmii(int rmii_sel) { }
+#endif
+
+
+#define DA850_KEYS_DEBOUNCE_MS 10
+/*
+ * At 200ms polling interval it is possible to miss an
+ * event by tapping very lightly on the push button but most
+ * pushes do result in an event; longer intervals require the
+ * user to hold the button whereas shorter intervals require
+ * more CPU time for polling.
+ */
+#define DA850_GPIO_KEYS_POLL_MS 200
+
+enum da850_evm_ui_exp_pins {
+ DA850_EVM_UI_EXP_SEL_C = 5,
+ DA850_EVM_UI_EXP_SEL_B,
+ DA850_EVM_UI_EXP_SEL_A,
+ DA850_EVM_UI_EXP_PB8,
+ DA850_EVM_UI_EXP_PB7,
+ DA850_EVM_UI_EXP_PB6,
+ DA850_EVM_UI_EXP_PB5,
+ DA850_EVM_UI_EXP_PB4,
+ DA850_EVM_UI_EXP_PB3,
+ DA850_EVM_UI_EXP_PB2,
+ DA850_EVM_UI_EXP_PB1,
+};
+
+static const char const *da850_evm_ui_exp[] = {
+ [DA850_EVM_UI_EXP_SEL_C] = "sel_c",
+ [DA850_EVM_UI_EXP_SEL_B] = "sel_b",
+ [DA850_EVM_UI_EXP_SEL_A] = "sel_a",
+ [DA850_EVM_UI_EXP_PB8] = "pb8",
+ [DA850_EVM_UI_EXP_PB7] = "pb7",
+ [DA850_EVM_UI_EXP_PB6] = "pb6",
+ [DA850_EVM_UI_EXP_PB5] = "pb5",
+ [DA850_EVM_UI_EXP_PB4] = "pb4",
+ [DA850_EVM_UI_EXP_PB3] = "pb3",
+ [DA850_EVM_UI_EXP_PB2] = "pb2",
+ [DA850_EVM_UI_EXP_PB1] = "pb1",
+};
+
+#define DA850_N_UI_PB 8
+
+static struct gpio_keys_button da850_evm_ui_keys[] = {
+ [0 ... DA850_N_UI_PB - 1] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_ui_keys_pdata = {
+ .buttons = da850_evm_ui_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_ui_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_ui_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 0,
+ .dev = {
+ .platform_data = &da850_evm_ui_keys_pdata
+ },
+};
+
+static void da850_evm_ui_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ for (i = 0; i < DA850_N_UI_PB; i++) {
+ button = &da850_evm_ui_keys[i];
+ button->code = KEY_F8 - i;
+ button->desc = (char *)
+ da850_evm_ui_exp[DA850_EVM_UI_EXP_PB8 + i];
+ button->gpio = gpio + DA850_EVM_UI_EXP_PB8 + i;
+ }
+}
+
+static int da850_evm_ui_expander_setup(struct i2c_client *client, unsigned gpio,
+ unsigned ngpio, void *c)
+{
+ int sel_a, sel_b, sel_c, ret;
+
+ sel_a = gpio + DA850_EVM_UI_EXP_SEL_A;
+ sel_b = gpio + DA850_EVM_UI_EXP_SEL_B;
+ sel_c = gpio + DA850_EVM_UI_EXP_SEL_C;
+
+ ret = gpio_request(sel_a, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_A]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_a);
+ goto exp_setup_sela_fail;
+ }
+
+ ret = gpio_request(sel_b, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_B]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_b);
+ goto exp_setup_selb_fail;
+ }
+
+ ret = gpio_request(sel_c, da850_evm_ui_exp[DA850_EVM_UI_EXP_SEL_C]);
+ if (ret) {
+ pr_warning("Cannot open UI expander pin %d\n", sel_c);
+ goto exp_setup_selc_fail;
+ }
+
+ /* deselect all functionalities */
+ gpio_direction_output(sel_a, 1);
+ gpio_direction_output(sel_b, 1);
+ gpio_direction_output(sel_c, 1);
+
+ da850_evm_ui_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_ui_keys_device);
+ if (ret) {
+ pr_warning("Could not register UI GPIO expander push-buttons");
+ goto exp_setup_keys_fail;
+ }
+
+ pr_info("DA850/OMAP-L138 EVM UI card detected\n");
+
+ da850_evm_setup_nor_nand();
+
+ da850_evm_setup_emac_rmii(sel_a);
+
+ return 0;
+
+exp_setup_keys_fail:
+ gpio_free(sel_c);
+exp_setup_selc_fail:
+ gpio_free(sel_b);
+exp_setup_selb_fail:
+ gpio_free(sel_a);
+exp_setup_sela_fail:
+ return ret;
+}
+
+static int da850_evm_ui_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
+{
+ platform_device_unregister(&da850_evm_ui_keys_device);
+
+ /* deselect all functionalities */
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_C, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_B, 1);
+ gpio_set_value_cansleep(gpio + DA850_EVM_UI_EXP_SEL_A, 1);
+
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_C);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_B);
+ gpio_free(gpio + DA850_EVM_UI_EXP_SEL_A);
+
+ return 0;
+}
+
+/* assign the baseboard expander's GPIOs after the UI board's */
+#define DA850_UI_EXPANDER_N_GPIOS ARRAY_SIZE(da850_evm_ui_exp)
+#define DA850_BB_EXPANDER_GPIO_BASE (DAVINCI_N_GPIO + DA850_UI_EXPANDER_N_GPIOS)
+
+enum da850_evm_bb_exp_pins {
+ DA850_EVM_BB_EXP_DEEP_SLEEP_EN = 0,
+ DA850_EVM_BB_EXP_SW_RST,
+ DA850_EVM_BB_EXP_TP_23,
+ DA850_EVM_BB_EXP_TP_22,
+ DA850_EVM_BB_EXP_TP_21,
+ DA850_EVM_BB_EXP_USER_PB1,
+ DA850_EVM_BB_EXP_USER_LED2,
+ DA850_EVM_BB_EXP_USER_LED1,
+ DA850_EVM_BB_EXP_USER_SW1,
+ DA850_EVM_BB_EXP_USER_SW2,
+ DA850_EVM_BB_EXP_USER_SW3,
+ DA850_EVM_BB_EXP_USER_SW4,
+ DA850_EVM_BB_EXP_USER_SW5,
+ DA850_EVM_BB_EXP_USER_SW6,
+ DA850_EVM_BB_EXP_USER_SW7,
+ DA850_EVM_BB_EXP_USER_SW8
+};
+
+static const char const *da850_evm_bb_exp[] = {
+ [DA850_EVM_BB_EXP_DEEP_SLEEP_EN] = "deep_sleep_en",
+ [DA850_EVM_BB_EXP_SW_RST] = "sw_rst",
+ [DA850_EVM_BB_EXP_TP_23] = "tp_23",
+ [DA850_EVM_BB_EXP_TP_22] = "tp_22",
+ [DA850_EVM_BB_EXP_TP_21] = "tp_21",
+ [DA850_EVM_BB_EXP_USER_PB1] = "user_pb1",
+ [DA850_EVM_BB_EXP_USER_LED2] = "user_led2",
+ [DA850_EVM_BB_EXP_USER_LED1] = "user_led1",
+ [DA850_EVM_BB_EXP_USER_SW1] = "user_sw1",
+ [DA850_EVM_BB_EXP_USER_SW2] = "user_sw2",
+ [DA850_EVM_BB_EXP_USER_SW3] = "user_sw3",
+ [DA850_EVM_BB_EXP_USER_SW4] = "user_sw4",
+ [DA850_EVM_BB_EXP_USER_SW5] = "user_sw5",
+ [DA850_EVM_BB_EXP_USER_SW6] = "user_sw6",
+ [DA850_EVM_BB_EXP_USER_SW7] = "user_sw7",
+ [DA850_EVM_BB_EXP_USER_SW8] = "user_sw8",
+};
+
+#define DA850_N_BB_USER_SW 8
+
+static struct gpio_keys_button da850_evm_bb_keys[] = {
+ [0] = {
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = KEY_PROG1,
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+ [1 ... DA850_N_BB_USER_SW] = {
+ .type = EV_SW,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = DA850_KEYS_DEBOUNCE_MS,
+ .code = -1, /* assigned at runtime */
+ .desc = NULL, /* assigned at runtime */
+ .gpio = -1, /* assigned at runtime */
+ },
+};
+
+static struct gpio_keys_platform_data da850_evm_bb_keys_pdata = {
+ .buttons = da850_evm_bb_keys,
+ .nbuttons = ARRAY_SIZE(da850_evm_bb_keys),
+ .poll_interval = DA850_GPIO_KEYS_POLL_MS,
+};
+
+static struct platform_device da850_evm_bb_keys_device = {
+ .name = "gpio-keys-polled",
+ .id = 1,
+ .dev = {
+ .platform_data = &da850_evm_bb_keys_pdata
+ },
+};
+
+static void da850_evm_bb_keys_init(unsigned gpio)
+{
+ int i;
+ struct gpio_keys_button *button;
+
+ button = &da850_evm_bb_keys[0];
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_PB1];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_PB1;
+
+ for (i = 0; i < DA850_N_BB_USER_SW; i++) {
+ button = &da850_evm_bb_keys[i + 1];
+ button->code = SW_LID + i;
+ button->desc = (char *)
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_SW1 + i];
+ button->gpio = gpio + DA850_EVM_BB_EXP_USER_SW1 + i;
+ }
+}
+
+#define DA850_N_BB_USER_LED 2
+
+static struct gpio_led da850_evm_bb_leds[] = {
+ [0 ... DA850_N_BB_USER_LED - 1] = {
+ .active_low = 1,
+ .gpio = -1, /* assigned at runtime */
+ .name = NULL, /* assigned at runtime */
+ },
+};
+
+static struct gpio_led_platform_data da850_evm_bb_leds_pdata = {
+ .leds = da850_evm_bb_leds,
+ .num_leds = ARRAY_SIZE(da850_evm_bb_leds),
+};
+
+static struct platform_device da850_evm_bb_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &da850_evm_bb_leds_pdata
+ }
+};
+
+static void da850_evm_bb_leds_init(unsigned gpio)
+{
+ int i;
+ struct gpio_led *led;
+
+ for (i = 0; i < DA850_N_BB_USER_LED; i++) {
+ led = &da850_evm_bb_leds[i];
+
+ led->gpio = gpio + DA850_EVM_BB_EXP_USER_LED2 + i;
+ led->name =
+ da850_evm_bb_exp[DA850_EVM_BB_EXP_USER_LED2 + i];
+ }
+}
+
+static int da850_evm_bb_expander_setup(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio,
+ void *c)
+{
+ int ret;
+
+ /*
+ * Register the switches and pushbutton on the baseboard as a gpio-keys
+ * device.
+ */
+ da850_evm_bb_keys_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_keys_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander keys");
+ goto io_exp_setup_sw_fail;
+ }
+
+ da850_evm_bb_leds_init(gpio);
+ ret = platform_device_register(&da850_evm_bb_leds_device);
+ if (ret) {
+ pr_warning("Could not register baseboard GPIO expander LEDS");
+ goto io_exp_setup_leds_fail;
+ }
+
+ return 0;
+
+io_exp_setup_leds_fail:
+ platform_device_unregister(&da850_evm_bb_keys_device);
+io_exp_setup_sw_fail:
+ return ret;
+}
+
+static int da850_evm_bb_expander_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *c)
+{
+ platform_device_unregister(&da850_evm_bb_leds_device);
+ platform_device_unregister(&da850_evm_bb_keys_device);
+
+ return 0;
+}
+
+static struct pca953x_platform_data da850_evm_ui_expander_info = {
+ .gpio_base = DAVINCI_N_GPIO,
+ .setup = da850_evm_ui_expander_setup,
+ .teardown = da850_evm_ui_expander_teardown,
+ .names = da850_evm_ui_exp,
+};
+
+static struct pca953x_platform_data da850_evm_bb_expander_info = {
+ .gpio_base = DA850_BB_EXPANDER_GPIO_BASE,
+ .setup = da850_evm_bb_expander_setup,
+ .teardown = da850_evm_bb_expander_teardown,
+ .names = da850_evm_bb_exp,
+};
+
+static struct i2c_board_info __initdata da850_evm_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x20),
+ .platform_data = &da850_evm_ui_expander_info,
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &da850_evm_bb_expander_info,
+ },
+};
+
+static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+static struct davinci_uart_config da850_evm_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+/* davinci da850 evm audio machine driver */
+static u8 da850_iis_serializer_direction[] = {
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+ INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, TX_MODE,
+ RX_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static struct snd_platform_data da850_evm_snd_data = {
+ .tx_dma_offset = 0x2000,
+ .rx_dma_offset = 0x2000,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = da850_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ .version = MCASP_VERSION_2,
+ .txnumevt = 1,
+ .rxnumevt = 1,
+};
+
+static const short da850_evm_mcasp_pins[] __initconst = {
+ DA850_AHCLKX, DA850_ACLKX, DA850_AFSX,
+ DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE,
+ DA850_AXR_11, DA850_AXR_12,
+ -1
+};
+
+static int da850_evm_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA850_MMCSD_WP_PIN);
+}
+
+static int da850_evm_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA850_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da850_mmc_config = {
+ .get_ro = da850_evm_mmc_get_ro,
+ .get_cd = da850_evm_mmc_get_cd,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static const short da850_evm_mmcsd0_pins[] __initconst = {
+ DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
+ DA850_GPIO4_0, DA850_GPIO4_1,
+ -1
+};
+
+static void da850_panel_power_ctrl(int val)
+{
+ /* lcd backlight */
+ gpio_set_value(DA850_LCD_BL_PIN, val);
+
+ /* lcd power */
+ gpio_set_value(DA850_LCD_PWR_PIN, val);
+}
+
+static int da850_lcd_hw_init(void)
+{
+ int status;
+
+ status = gpio_request(DA850_LCD_BL_PIN, "lcd bl\n");
+ if (status < 0)
+ return status;
+
+ status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr\n");
+ if (status < 0) {
+ gpio_free(DA850_LCD_BL_PIN);
+ return status;
+ }
+
+ gpio_direction_output(DA850_LCD_BL_PIN, 0);
+ gpio_direction_output(DA850_LCD_PWR_PIN, 0);
+
+ /* Switch off panel power and backlight */
+ da850_panel_power_ctrl(0);
+
+ /* Switch on panel power and backlight */
+ da850_panel_power_ctrl(1);
+
+ return 0;
+}
+
+/* TPS65070 voltage regulator support */
+
+/* 3.3V */
+static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = {
+ {
+ .supply = "usb0_vdda33",
+ },
+ {
+ .supply = "usb1_vdda33",
+ },
+};
+
+/* 3.3V or 1.8V */
+static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = {
+ {
+ .supply = "dvdd3318_a",
+ },
+ {
+ .supply = "dvdd3318_b",
+ },
+ {
+ .supply = "dvdd3318_c",
+ },
+};
+
+/* 1.2V */
+static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = {
+ {
+ .supply = "cvdd",
+ },
+};
+
+/* 1.8V LDO */
+static struct regulator_consumer_supply tps65070_ldo1_consumers[] = {
+ {
+ .supply = "sata_vddr",
+ },
+ {
+ .supply = "usb0_vdda18",
+ },
+ {
+ .supply = "usb1_vdda18",
+ },
+ {
+ .supply = "ddr_dvdd18",
+ },
+};
+
+/* 1.2V LDO */
+static struct regulator_consumer_supply tps65070_ldo2_consumers[] = {
+ {
+ .supply = "sata_vdd",
+ },
+ {
+ .supply = "pll0_vdda",
+ },
+ {
+ .supply = "pll1_vdda",
+ },
+ {
+ .supply = "usbs_cvdd",
+ },
+ {
+ .supply = "vddarnwa1",
+ },
+};
+
+/* We take advantage of the fact that both defdcdc{2,3} are tied high */
+static struct tps6507x_reg_platform_data tps6507x_platform_data = {
+ .defdcdc_default = true,
+};
+
+static struct regulator_init_data tps65070_regulator_data[] = {
+ /* dcdc1 */
+ {
+ .constraints = {
+ .min_uV = 3150000,
+ .max_uV = 3450000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc1_consumers),
+ .consumer_supplies = tps65070_dcdc1_consumers,
+ },
+
+ /* dcdc2 */
+ {
+ .constraints = {
+ .min_uV = 1710000,
+ .max_uV = 3450000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc2_consumers),
+ .consumer_supplies = tps65070_dcdc2_consumers,
+ .driver_data = &tps6507x_platform_data,
+ },
+
+ /* dcdc3 */
+ {
+ .constraints = {
+ .min_uV = 950000,
+ .max_uV = 1350000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_dcdc3_consumers),
+ .consumer_supplies = tps65070_dcdc3_consumers,
+ .driver_data = &tps6507x_platform_data,
+ },
+
+ /* ldo1 */
+ {
+ .constraints = {
+ .min_uV = 1710000,
+ .max_uV = 1890000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo1_consumers),
+ .consumer_supplies = tps65070_ldo1_consumers,
+ },
+
+ /* ldo2 */
+ {
+ .constraints = {
+ .min_uV = 1140000,
+ .max_uV = 1320000,
+ .valid_ops_mask = (REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS),
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65070_ldo2_consumers),
+ .consumer_supplies = tps65070_ldo2_consumers,
+ },
+};
+
+static struct touchscreen_init_data tps6507x_touchscreen_data = {
+ .poll_period = 30, /* ms between touch samples */
+ .min_pressure = 0x30, /* minimum pressure to trigger touch */
+ .vref = 0, /* turn off vref when not using A/D */
+ .vendor = 0, /* /sys/class/input/input?/id/vendor */
+ .product = 65070, /* /sys/class/input/input?/id/product */
+ .version = 0x100, /* /sys/class/input/input?/id/version */
+};
+
+static struct tps6507x_board tps_board = {
+ .tps6507x_pmic_init_data = &tps65070_regulator_data[0],
+ .tps6507x_ts_init_data = &tps6507x_touchscreen_data,
+};
+
+static struct i2c_board_info __initdata da850_evm_tps65070_info[] = {
+ {
+ I2C_BOARD_INFO("tps6507x", 0x48),
+ .platform_data = &tps_board,
+ },
+};
+
+static int __init pmic_tps65070_init(void)
+{
+ return i2c_register_board_info(1, da850_evm_tps65070_info,
+ ARRAY_SIZE(da850_evm_tps65070_info));
+}
+
+static const short da850_evm_lcdc_pins[] = {
+ DA850_GPIO2_8, DA850_GPIO2_15,
+ -1
+};
+
+static const short da850_evm_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short da850_evm_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static int __init da850_evm_config_emac(void)
+{
+ void __iomem *cfg_chip3_base;
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ u8 rmii_en = soc_info->emac_pdata->rmii_en;
+
+ if (!machine_is_davinci_da850_evm())
+ return 0;
+
+ cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+
+ val = __raw_readl(cfg_chip3_base);
+
+ if (rmii_en) {
+ val |= BIT(8);
+ ret = davinci_cfg_reg_list(da850_evm_rmii_pins);
+ pr_info("EMAC: RMII PHY configured, MII PHY will not be"
+ " functional\n");
+ } else {
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(da850_evm_mii_pins);
+ pr_info("EMAC: MII PHY configured, RMII PHY will not be"
+ " functional\n");
+ }
+
+ if (ret)
+ pr_warning("da850_evm_init: cpgmac/rmii mux setup failed: %d\n",
+ ret);
+
+ /* configure the CFGCHIP3 register for RMII or MII */
+ __raw_writel(val, cfg_chip3_base);
+
+ ret = davinci_cfg_reg(DA850_GPIO2_6);
+ if (ret)
+ pr_warning("da850_evm_init:GPIO(2,6) mux setup "
+ "failed\n");
+
+ ret = gpio_request(DA850_MII_MDIO_CLKEN_PIN, "mdio_clk_en");
+ if (ret) {
+ pr_warning("Cannot open GPIO %d\n",
+ DA850_MII_MDIO_CLKEN_PIN);
+ return ret;
+ }
+
+ /* Enable/Disable MII MDIO clock */
+ gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en);
+
+ soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("da850_evm_init: emac registration failed: %d\n",
+ ret);
+
+ return 0;
+}
+device_initcall(da850_evm_config_emac);
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence
+ * they are being reserved for codecs on the DSP side.
+ */
+static const s16 da850_dma0_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma0_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 50},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 90},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da850_edma_cc0_rsv = {
+ .rsv_chans = da850_dma0_rsv_chans,
+ .rsv_slots = da850_dma0_rsv_slots,
+};
+
+static struct edma_rsv_info da850_edma_cc1_rsv = {
+ .rsv_chans = da850_dma1_rsv_chans,
+ .rsv_slots = da850_dma1_rsv_slots,
+};
+
+static struct edma_rsv_info *da850_edma_rsv[2] = {
+ &da850_edma_cc0_rsv,
+ &da850_edma_cc1_rsv,
+};
+
+#ifdef CONFIG_CPU_FREQ
+static __init int da850_evm_init_cpufreq(void)
+{
+ switch (system_rev & 0xF) {
+ case 3:
+ da850_max_speed = 456000;
+ break;
+ case 2:
+ da850_max_speed = 408000;
+ break;
+ case 1:
+ da850_max_speed = 372000;
+ break;
+ }
+
+ return da850_register_cpufreq("pll0_sysclk3");
+}
+#else
+static __init int da850_evm_init_cpufreq(void) { return 0; }
+#endif
+
+static __init void da850_evm_init(void)
+{
+ int ret;
+
+ ret = pmic_tps65070_init();
+ if (ret)
+ pr_warning("da850_evm_init: TPS65070 PMIC init failed: %d\n",
+ ret);
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warning("da850_evm_init: edma registration failed: %d\n",
+ ret);
+
+ ret = davinci_cfg_reg_list(da850_i2c0_pins);
+ if (ret)
+ pr_warning("da850_evm_init: i2c0 mux setup failed: %d\n",
+ ret);
+
+ ret = da8xx_register_i2c(0, &da850_evm_i2c_0_pdata);
+ if (ret)
+ pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
+ ret);
+
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("da830_evm_init: watchdog registration failed: %d\n",
+ ret);
+
+ if (HAS_MMC) {
+ ret = davinci_cfg_reg_list(da850_evm_mmcsd0_pins);
+ if (ret)
+ pr_warning("da850_evm_init: mmcsd0 mux setup failed:"
+ " %d\n", ret);
+
+ ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n");
+ if (ret)
+ pr_warning("da850_evm_init: can not open GPIO %d\n",
+ DA850_MMCSD_CD_PIN);
+ gpio_direction_input(DA850_MMCSD_CD_PIN);
+
+ ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n");
+ if (ret)
+ pr_warning("da850_evm_init: can not open GPIO %d\n",
+ DA850_MMCSD_WP_PIN);
+ gpio_direction_input(DA850_MMCSD_WP_PIN);
+
+ ret = da8xx_register_mmcsd0(&da850_mmc_config);
+ if (ret)
+ pr_warning("da850_evm_init: mmcsd0 registration failed:"
+ " %d\n", ret);
+ }
+
+ davinci_serial_init(&da850_evm_uart_config);
+
+ i2c_register_board_info(1, da850_evm_i2c_devices,
+ ARRAY_SIZE(da850_evm_i2c_devices));
+
+ /*
+ * shut down uart 0 and 1; they are not used on the board and
+ * accessing them causes endless "too much work in irq53" messages
+ * with arago fs
+ */
+ __raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);
+ __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30);
+
+ ret = davinci_cfg_reg_list(da850_evm_mcasp_pins);
+ if (ret)
+ pr_warning("da850_evm_init: mcasp mux setup failed: %d\n",
+ ret);
+
+ da8xx_register_mcasp(0, &da850_evm_snd_data);
+
+ ret = davinci_cfg_reg_list(da850_lcdcntl_pins);
+ if (ret)
+ pr_warning("da850_evm_init: lcdcntl mux setup failed: %d\n",
+ ret);
+
+ /* Handle board specific muxing for LCD here */
+ ret = davinci_cfg_reg_list(da850_evm_lcdc_pins);
+ if (ret)
+ pr_warning("da850_evm_init: evm specific lcd mux setup "
+ "failed: %d\n", ret);
+
+ ret = da850_lcd_hw_init();
+ if (ret)
+ pr_warning("da850_evm_init: lcd initialization failed: %d\n",
+ ret);
+
+ sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
+ ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
+ if (ret)
+ pr_warning("da850_evm_init: lcdc registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("da850_evm_init: rtc setup failed: %d\n", ret);
+
+ ret = da850_evm_init_cpufreq();
+ if (ret)
+ pr_warning("da850_evm_init: cpufreq registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warning("da850_evm_init: cpuidle registration failed: %d\n",
+ ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warning("da850_evm_init: suspend registration failed: %d\n",
+ ret);
+
+ ret = da8xx_register_spi(1, da850evm_spi_info,
+ ARRAY_SIZE(da850evm_spi_info));
+ if (ret)
+ pr_warning("da850_evm_init: spi 1 registration failed: %d\n",
+ ret);
+
+ da850_evm_setup_mac_addr();
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init da850_evm_console_init(void)
+{
+ if (!machine_is_davinci_da850_evm())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(da850_evm_console_init);
+#endif
+
+static void __init da850_evm_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = da850_evm_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = da850_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c
new file mode 100644
index 00000000..6e7cad13
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-evm.c
@@ -0,0 +1,359 @@
+/*
+ * TI DaVinci EVM board support
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+#include <media/tvp514x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm355.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips, maybe with a different block size, partitioning may
+ * need to be changed.
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 4,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM355_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+ .sda_pin = 15,
+ .scl_pin = 14,
+};
+
+static struct snd_platform_data dm355_evm_snd_data;
+
+static int dm355evm_mmc_gpios = -EINVAL;
+
+static void dm355evm_mmcsd_gpios(unsigned gpio)
+{
+ gpio_request(gpio + 0, "mmc0_ro");
+ gpio_request(gpio + 1, "mmc0_cd");
+ gpio_request(gpio + 2, "mmc1_ro");
+ gpio_request(gpio + 3, "mmc1_cd");
+
+ /* we "know" these are input-only so we don't
+ * need to call gpio_direction_input()
+ */
+
+ dm355evm_mmc_gpios = gpio;
+}
+
+static struct i2c_board_info dm355evm_i2c_info[] = {
+ { I2C_BOARD_INFO("dm355evm_msp", 0x25),
+ .platform_data = dm355evm_mmcsd_gpios,
+ },
+ /* { plus irq }, */
+ { I2C_BOARD_INFO("tlv320aic33", 0x1b), },
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+
+ gpio_request(5, "dm355evm_msp");
+ gpio_direction_input(5);
+ dm355evm_i2c_info[0].irq = gpio_to_irq(5);
+
+ i2c_register_board_info(1, dm355evm_i2c_info,
+ ARRAY_SIZE(dm355evm_i2c_info));
+}
+
+static struct resource dm355evm_dm9000_rsrc[] = {
+ {
+ /* addr */
+ .start = 0x04014000,
+ .end = 0x04014001,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* data */
+ .start = 0x04014002,
+ .end = 0x04014003,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ
+ | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */,
+ },
+};
+
+static struct platform_device dm355evm_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .resource = dm355evm_dm9000_rsrc,
+ .num_resources = ARRAY_SIZE(dm355evm_dm9000_rsrc),
+};
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+ {
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ }
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .i2c_adapter_id = 1,
+ .sub_devs = vpfe_sub_devs,
+ .card_name = "DM355 EVM",
+ .ccdc = "DM355 CCDC",
+};
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &dm355evm_dm9000,
+ &davinci_nand_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm355_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm355_set_vpfe_config(&vpfe_cfg);
+ dm355_init();
+}
+
+static int dm355evm_mmc_get_cd(int module)
+{
+ if (!gpio_is_valid(dm355evm_mmc_gpios))
+ return -ENXIO;
+ /* low == card present */
+ return !gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 1);
+}
+
+static int dm355evm_mmc_get_ro(int module)
+{
+ if (!gpio_is_valid(dm355evm_mmc_gpios))
+ return -ENXIO;
+ /* high == card's write protect switch active */
+ return gpio_get_value_cansleep(dm355evm_mmc_gpios + 2 * module + 0);
+}
+
+static struct davinci_mmc_config dm355evm_mmc_config = {
+ .get_cd = dm355evm_mmc_get_cd,
+ .get_ro = dm355evm_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_1,
+};
+
+/* Don't connect anything to J10 unless you're only using USB host
+ * mode *and* have to do so with some kind of gender-bender. If
+ * you have proper Mini-B or Mini-A cables (or Mini-A adapters)
+ * the ID pin won't need any help.
+ */
+#ifdef CONFIG_USB_MUSB_PERIPHERAL
+#define USB_ID_VALUE 0 /* ID pulled high; *should* float */
+#else
+#define USB_ID_VALUE 1 /* ID pulled low */
+#endif
+
+static struct spi_eeprom at25640a = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640a",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm355_evm_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640a,
+ .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm355_evm_init(void)
+{
+ struct clk *aemif;
+
+ gpio_request(1, "dm9000");
+ gpio_direction_input(1);
+ dm355evm_dm9000_rsrc[2].start = gpio_to_irq(1);
+
+ aemif = clk_get(&dm355evm_dm9000.dev, "aemif");
+ if (IS_ERR(aemif))
+ WARN("%s: unable to get AEMIF clock\n", __func__);
+ else
+ clk_enable(aemif);
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ /* NOTE: NAND flash timings set by the UBL are slower than
+ * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
+ * but could be 0x0400008c for about 25% faster page reads.
+ */
+
+ gpio_request(2, "usb_id_toggle");
+ gpio_direction_output(2, USB_ID_VALUE);
+ /* irlml6401 switches over 1A in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ davinci_setup_mmc(0, &dm355evm_mmc_config);
+ davinci_setup_mmc(1, &dm355evm_mmc_config);
+
+ dm355_init_spi0(BIT(0), dm355_evm_spi_info,
+ ARRAY_SIZE(dm355_evm_spi_info));
+
+ /* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
+ dm355_init_asp1(ASP1_TX_EVT_EN | ASP1_RX_EVT_EN, &dm355_evm_snd_data);
+}
+
+MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM")
+ .boot_params = (0x80000100),
+ .map_io = dm355_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm355_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c
new file mode 100644
index 00000000..543f9911
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm355-leopard.c
@@ -0,0 +1,278 @@
+/*
+ * DM355 leopard board support
+ *
+ * Based on board-dm355-evm.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm355.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips, maybe with a different block size, partitioning may
+ * need to be changed.
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW_SYNDROME,
+ .options = NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM355_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM355_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM355_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM355_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+static int leopard_mmc_gpio = -EINVAL;
+
+static void dm355leopard_mmcsd_gpios(unsigned gpio)
+{
+ gpio_request(gpio + 0, "mmc0_ro");
+ gpio_request(gpio + 1, "mmc0_cd");
+ gpio_request(gpio + 2, "mmc1_ro");
+ gpio_request(gpio + 3, "mmc1_cd");
+
+ /* we "know" these are input-only so we don't
+ * need to call gpio_direction_input()
+ */
+
+ leopard_mmc_gpio = gpio;
+}
+
+static struct i2c_board_info dm355leopard_i2c_info[] = {
+ { I2C_BOARD_INFO("dm355leopard_msp", 0x25),
+ .platform_data = dm355leopard_mmcsd_gpios,
+ /* plus irq */ },
+ /* { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }, */
+ /* { I2C_BOARD_INFO("tvp5146", 0x5d), }, */
+};
+
+static void __init leopard_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+
+ gpio_request(5, "dm355leopard_msp");
+ gpio_direction_input(5);
+ dm355leopard_i2c_info[0].irq = gpio_to_irq(5);
+
+ i2c_register_board_info(1, dm355leopard_i2c_info,
+ ARRAY_SIZE(dm355leopard_i2c_info));
+}
+
+static struct resource dm355leopard_dm9000_rsrc[] = {
+ {
+ /* addr */
+ .start = 0x04000000,
+ .end = 0x04000001,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* data */
+ .start = 0x04000016,
+ .end = 0x04000017,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .flags = IORESOURCE_IRQ
+ | IORESOURCE_IRQ_HIGHEDGE /* rising (active high) */,
+ },
+};
+
+static struct platform_device dm355leopard_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .resource = dm355leopard_dm9000_rsrc,
+ .num_resources = ARRAY_SIZE(dm355leopard_dm9000_rsrc),
+};
+
+static struct platform_device *davinci_leopard_devices[] __initdata = {
+ &dm355leopard_dm9000,
+ &davinci_nand_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm355_leopard_map_io(void)
+{
+ dm355_init();
+}
+
+static int dm355leopard_mmc_get_cd(int module)
+{
+ if (!gpio_is_valid(leopard_mmc_gpio))
+ return -ENXIO;
+ /* low == card present */
+ return !gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 1);
+}
+
+static int dm355leopard_mmc_get_ro(int module)
+{
+ if (!gpio_is_valid(leopard_mmc_gpio))
+ return -ENXIO;
+ /* high == card's write protect switch active */
+ return gpio_get_value_cansleep(leopard_mmc_gpio + 2 * module + 0);
+}
+
+static struct davinci_mmc_config dm355leopard_mmc_config = {
+ .get_cd = dm355leopard_mmc_get_cd,
+ .get_ro = dm355leopard_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+};
+
+/* Don't connect anything to J10 unless you're only using USB host
+ * mode *and* have to do so with some kind of gender-bender. If
+ * you have proper Mini-B or Mini-A cables (or Mini-A adapters)
+ * the ID pin won't need any help.
+ */
+#ifdef CONFIG_USB_MUSB_PERIPHERAL
+#define USB_ID_VALUE 0 /* ID pulled high; *should* float */
+#else
+#define USB_ID_VALUE 1 /* ID pulled low */
+#endif
+
+static struct spi_eeprom at25640a = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640a",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm355_leopard_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640a,
+ .max_speed_hz = 10 * 1000 * 1000, /* at 3v3 */
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm355_leopard_init(void)
+{
+ struct clk *aemif;
+
+ gpio_request(9, "dm9000");
+ gpio_direction_input(9);
+ dm355leopard_dm9000_rsrc[2].start = gpio_to_irq(9);
+
+ aemif = clk_get(&dm355leopard_dm9000.dev, "aemif");
+ if (IS_ERR(aemif))
+ WARN("%s: unable to get AEMIF clock\n", __func__);
+ else
+ clk_enable(aemif);
+
+ platform_add_devices(davinci_leopard_devices,
+ ARRAY_SIZE(davinci_leopard_devices));
+ leopard_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ /* NOTE: NAND flash timings set by the UBL are slower than
+ * needed by MT29F16G08FAA chips ... EMIF.A1CR is 0x40400204
+ * but could be 0x0400008c for about 25% faster page reads.
+ */
+
+ gpio_request(2, "usb_id_toggle");
+ gpio_direction_output(2, USB_ID_VALUE);
+ /* irlml6401 switches over 1A in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ davinci_setup_mmc(0, &dm355leopard_mmc_config);
+ davinci_setup_mmc(1, &dm355leopard_mmc_config);
+
+ dm355_init_spi0(BIT(0), dm355_leopard_spi_info,
+ ARRAY_SIZE(dm355_leopard_spi_info));
+}
+
+MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard")
+ .boot_params = (0x80000100),
+ .map_io = dm355_leopard_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm355_leopard_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
new file mode 100644
index 00000000..09a87e61
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -0,0 +1,621 @@
+/*
+ * TI DaVinci DM365 EVM board support
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/i2c/at24.h>
+#include <linux/leds.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/mtd/nand.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mux.h>
+#include <mach/dm365.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mmc.h>
+#include <mach/nand.h>
+#include <mach/keyscan.h>
+
+#include <media/tvp514x.h>
+
+static inline int have_imager(void)
+{
+ /* REVISIT when it's supported, trigger via Kconfig */
+ return 0;
+}
+
+static inline int have_tvp7002(void)
+{
+ /* REVISIT when it's supported, trigger via Kconfig */
+ return 0;
+}
+
+#define DM365_EVM_PHY_ID "0:01"
+/*
+ * A MAX-II CPLD is used for various board control functions.
+ */
+#define CPLD_OFFSET(a13a8,a2a1) (((a13a8) << 10) + ((a2a1) << 3))
+
+#define CPLD_VERSION CPLD_OFFSET(0,0) /* r/o */
+#define CPLD_TEST CPLD_OFFSET(0,1)
+#define CPLD_LEDS CPLD_OFFSET(0,2)
+#define CPLD_MUX CPLD_OFFSET(0,3)
+#define CPLD_SWITCH CPLD_OFFSET(1,0) /* r/o */
+#define CPLD_POWER CPLD_OFFSET(1,1)
+#define CPLD_VIDEO CPLD_OFFSET(1,2)
+#define CPLD_CARDSTAT CPLD_OFFSET(1,3) /* r/o */
+
+#define CPLD_DILC_OUT CPLD_OFFSET(2,0)
+#define CPLD_DILC_IN CPLD_OFFSET(2,1) /* r/o */
+
+#define CPLD_IMG_DIR0 CPLD_OFFSET(2,2)
+#define CPLD_IMG_MUX0 CPLD_OFFSET(2,3)
+#define CPLD_IMG_MUX1 CPLD_OFFSET(3,0)
+#define CPLD_IMG_DIR1 CPLD_OFFSET(3,1)
+#define CPLD_IMG_MUX2 CPLD_OFFSET(3,2)
+#define CPLD_IMG_MUX3 CPLD_OFFSET(3,3)
+#define CPLD_IMG_DIR2 CPLD_OFFSET(4,0)
+#define CPLD_IMG_MUX4 CPLD_OFFSET(4,1)
+#define CPLD_IMG_MUX5 CPLD_OFFSET(4,2)
+
+#define CPLD_RESETS CPLD_OFFSET(4,3)
+
+#define CPLD_CCD_DIR1 CPLD_OFFSET(0x3e,0)
+#define CPLD_CCD_IO1 CPLD_OFFSET(0x3e,1)
+#define CPLD_CCD_DIR2 CPLD_OFFSET(0x3e,2)
+#define CPLD_CCD_IO2 CPLD_OFFSET(0x3e,3)
+#define CPLD_CCD_DIR3 CPLD_OFFSET(0x3f,0)
+#define CPLD_CCD_IO3 CPLD_OFFSET(0x3f,1)
+
+static void __iomem *cpld;
+
+
+/* NOTE: this is geared for the standard config, with a socketed
+ * 2 GByte Micron NAND (MT29F16G08FAA) using 128KB sectors. If you
+ * swap chips with a different block size, partitioning will
+ * need to be changed. This NAND chip MT29F16G08FAA is the default
+ * NAND shipped with the Spectrum Digital DM365 EVM
+ */
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 28 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* two blocks with bad block table (and mirror) at the end */
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_chipsel = BIT(14),
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 4,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM365_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM365_ASYNC_EMIF_DATA_CE0_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM365_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM365_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static struct snd_platform_data dm365_evm_snd_data = {
+ .asp_chan_q = EVENTQ_3,
+};
+
+static struct i2c_board_info i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 400 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+static int dm365evm_keyscan_enable(struct device *dev)
+{
+ return davinci_cfg_reg(DM365_KEYSCAN);
+}
+
+static unsigned short dm365evm_keymap[] = {
+ KEY_KP2,
+ KEY_LEFT,
+ KEY_EXIT,
+ KEY_DOWN,
+ KEY_ENTER,
+ KEY_UP,
+ KEY_KP1,
+ KEY_RIGHT,
+ KEY_MENU,
+ KEY_RECORD,
+ KEY_REWIND,
+ KEY_KPMINUS,
+ KEY_STOP,
+ KEY_FASTFORWARD,
+ KEY_KPPLUS,
+ KEY_PLAYPAUSE,
+ 0
+};
+
+static struct davinci_ks_platform_data dm365evm_ks_data = {
+ .device_enable = dm365evm_keyscan_enable,
+ .keymap = dm365evm_keymap,
+ .keymapsize = ARRAY_SIZE(dm365evm_keymap),
+ .rep = 1,
+ /* Scan period = strobe + interval */
+ .strobe = 0x5,
+ .interval = 0x2,
+ .matrix_type = DAVINCI_KEYSCAN_MATRIX_4X4,
+};
+
+static int cpld_mmc_get_cd(int module)
+{
+ if (!cpld)
+ return -ENXIO;
+
+ /* low == card present */
+ return !(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 4 : 0));
+}
+
+static int cpld_mmc_get_ro(int module)
+{
+ if (!cpld)
+ return -ENXIO;
+
+ /* high == card's write protect switch active */
+ return !!(__raw_readb(cpld + CPLD_CARDSTAT) & BIT(module ? 5 : 1));
+}
+
+static struct davinci_mmc_config dm365evm_mmc_config = {
+ .get_cd = cpld_mmc_get_cd,
+ .get_ro = cpld_mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static void dm365evm_emac_configure(void)
+{
+ /*
+ * EMAC pins are multiplexed with GPIO and UART
+ * Further details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 125 - 127
+ */
+ davinci_cfg_reg(DM365_EMAC_TX_EN);
+ davinci_cfg_reg(DM365_EMAC_TX_CLK);
+ davinci_cfg_reg(DM365_EMAC_COL);
+ davinci_cfg_reg(DM365_EMAC_TXD3);
+ davinci_cfg_reg(DM365_EMAC_TXD2);
+ davinci_cfg_reg(DM365_EMAC_TXD1);
+ davinci_cfg_reg(DM365_EMAC_TXD0);
+ davinci_cfg_reg(DM365_EMAC_RXD3);
+ davinci_cfg_reg(DM365_EMAC_RXD2);
+ davinci_cfg_reg(DM365_EMAC_RXD1);
+ davinci_cfg_reg(DM365_EMAC_RXD0);
+ davinci_cfg_reg(DM365_EMAC_RX_CLK);
+ davinci_cfg_reg(DM365_EMAC_RX_DV);
+ davinci_cfg_reg(DM365_EMAC_RX_ER);
+ davinci_cfg_reg(DM365_EMAC_CRS);
+ davinci_cfg_reg(DM365_EMAC_MDIO);
+ davinci_cfg_reg(DM365_EMAC_MDCLK);
+
+ /*
+ * EMAC interrupts are multiplexed with GPIO interrupts
+ * Details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 133 - 134
+ */
+ davinci_cfg_reg(DM365_INT_EMAC_RXTHRESH);
+ davinci_cfg_reg(DM365_INT_EMAC_RXPULSE);
+ davinci_cfg_reg(DM365_INT_EMAC_TXPULSE);
+ davinci_cfg_reg(DM365_INT_EMAC_MISCPULSE);
+}
+
+static void dm365evm_mmc_configure(void)
+{
+ /*
+ * MMC/SD pins are multiplexed with GPIO and EMIF
+ * Further details are available at the DM365 ARM
+ * Subsystem Users Guide(sprufg5.pdf) pages 118, 128 - 131
+ */
+ davinci_cfg_reg(DM365_SD1_CLK);
+ davinci_cfg_reg(DM365_SD1_CMD);
+ davinci_cfg_reg(DM365_SD1_DATA3);
+ davinci_cfg_reg(DM365_SD1_DATA2);
+ davinci_cfg_reg(DM365_SD1_DATA1);
+ davinci_cfg_reg(DM365_SD1_DATA0);
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+{
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .sub_devs = vpfe_sub_devs,
+ .i2c_adapter_id = 1,
+ .card_name = "DM365 EVM",
+ .ccdc = "ISIF",
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *dm365_evm_nand_devices[] __initdata = {
+ &davinci_nand_device,
+};
+
+static inline int have_leds(void)
+{
+#ifdef CONFIG_LEDS_CLASS
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+struct cpld_led {
+ struct led_classdev cdev;
+ u8 mask;
+};
+
+static const struct {
+ const char *name;
+ const char *trigger;
+} cpld_leds[] = {
+ { "dm365evm::ds2", },
+ { "dm365evm::ds3", },
+ { "dm365evm::ds4", },
+ { "dm365evm::ds5", },
+ { "dm365evm::ds6", "nand-disk", },
+ { "dm365evm::ds7", "mmc1", },
+ { "dm365evm::ds8", "mmc0", },
+ { "dm365evm::ds9", "heartbeat", },
+};
+
+static void cpld_led_set(struct led_classdev *cdev, enum led_brightness b)
+{
+ struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+ u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+ if (b != LED_OFF)
+ reg &= ~led->mask;
+ else
+ reg |= led->mask;
+ __raw_writeb(reg, cpld + CPLD_LEDS);
+}
+
+static enum led_brightness cpld_led_get(struct led_classdev *cdev)
+{
+ struct cpld_led *led = container_of(cdev, struct cpld_led, cdev);
+ u8 reg = __raw_readb(cpld + CPLD_LEDS);
+
+ return (reg & led->mask) ? LED_OFF : LED_FULL;
+}
+
+static int __init cpld_leds_init(void)
+{
+ int i;
+
+ if (!have_leds() || !cpld)
+ return 0;
+
+ /* setup LEDs */
+ __raw_writeb(0xff, cpld + CPLD_LEDS);
+ for (i = 0; i < ARRAY_SIZE(cpld_leds); i++) {
+ struct cpld_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = cpld_leds[i].name;
+ led->cdev.brightness_set = cpld_led_set;
+ led->cdev.brightness_get = cpld_led_get;
+ led->cdev.default_trigger = cpld_leds[i].trigger;
+ led->mask = BIT(i);
+
+ if (led_classdev_register(NULL, &led->cdev) < 0) {
+ kfree(led);
+ break;
+ }
+ }
+
+ return 0;
+}
+/* run after subsys_initcall() for LEDs */
+fs_initcall(cpld_leds_init);
+
+
+static void __init evm_init_cpld(void)
+{
+ u8 mux, resets;
+ const char *label;
+ struct clk *aemif_clk;
+
+ /* Make sure we can configure the CPLD through CS1. Then
+ * leave it on for later access to MMC and LED registers.
+ */
+ aemif_clk = clk_get(NULL, "aemif");
+ if (IS_ERR(aemif_clk))
+ return;
+ clk_enable(aemif_clk);
+
+ if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE,
+ "cpld") == NULL)
+ goto fail;
+ cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE);
+ if (!cpld) {
+ release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE,
+ SECTION_SIZE);
+fail:
+ pr_err("ERROR: can't map CPLD\n");
+ clk_disable(aemif_clk);
+ return;
+ }
+
+ /* External muxing for some signals */
+ mux = 0;
+
+ /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read).
+ * NOTE: SW4 bus width setting must match!
+ */
+ if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) {
+ /* external keypad mux */
+ mux |= BIT(7);
+
+ platform_add_devices(dm365_evm_nand_devices,
+ ARRAY_SIZE(dm365_evm_nand_devices));
+ } else {
+ /* no OneNAND support yet */
+ }
+
+ /* Leave external chips in reset when unused. */
+ resets = BIT(3) | BIT(2) | BIT(1) | BIT(0);
+
+ /* Static video input config with SN74CBT16214 1-of-3 mux:
+ * - port b1 == tvp7002 (mux lowbits == 1 or 6)
+ * - port b2 == imager (mux lowbits == 2 or 7)
+ * - port b3 == tvp5146 (mux lowbits == 5)
+ *
+ * Runtime switching could work too, with limitations.
+ */
+ if (have_imager()) {
+ label = "HD imager";
+ mux |= 2;
+
+ /* externally mux MMC1/ENET/AIC33 to imager */
+ mux |= BIT(6) | BIT(5) | BIT(3);
+ } else {
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ /* we can use MMC1 ... */
+ dm365evm_mmc_configure();
+ davinci_setup_mmc(1, &dm365evm_mmc_config);
+
+ /* ... and ENET ... */
+ dm365evm_emac_configure();
+ soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID;
+ resets &= ~BIT(3);
+
+ /* ... and AIC33 */
+ resets &= ~BIT(1);
+
+ if (have_tvp7002()) {
+ mux |= 1;
+ resets &= ~BIT(2);
+ label = "tvp7002 HD";
+ } else {
+ /* default to tvp5146 */
+ mux |= 5;
+ resets &= ~BIT(0);
+ label = "tvp5146 SD";
+ }
+ }
+ __raw_writeb(mux, cpld + CPLD_MUX);
+ __raw_writeb(resets, cpld + CPLD_RESETS);
+ pr_info("EVM: %s video input\n", label);
+
+ /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */
+}
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init dm365_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm365_set_vpfe_config(&vpfe_cfg);
+ dm365_init();
+}
+
+static struct spi_eeprom at25640 = {
+ .byte_len = SZ_64K / 8,
+ .name = "at25640",
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info dm365_evm_spi_info[] __initconst = {
+ {
+ .modalias = "at25",
+ .platform_data = &at25640,
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static __init void dm365_evm_init(void)
+{
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+
+ dm365evm_emac_configure();
+ dm365evm_mmc_configure();
+
+ davinci_setup_mmc(0, &dm365evm_mmc_config);
+
+ /* maybe setup mmc1/etc ... _after_ mmc0 */
+ evm_init_cpld();
+
+#ifdef CONFIG_SND_DM365_AIC3X_CODEC
+ dm365_init_asp(&dm365_evm_snd_data);
+#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
+ dm365_init_vc(&dm365_evm_snd_data);
+#endif
+ dm365_init_rtc();
+ dm365_init_ks(&dm365evm_ks_data);
+
+ dm365_init_spi0(BIT(0), dm365_evm_spi_info,
+ ARRAY_SIZE(dm365_evm_spi_info));
+}
+
+MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM")
+ .boot_params = (0x80000100),
+ .map_io = dm365_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = dm365_evm_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c
new file mode 100644
index 00000000..556bbd46
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm644x-evm.c
@@ -0,0 +1,720 @@
+/*
+ * TI DaVinci EVM board support
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/phy.h>
+#include <linux/clk.h>
+#include <linux/videodev2.h>
+
+#include <media/tvp514x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+#include <mach/aemif.h>
+
+#define DM644X_EVM_PHY_ID "0:01"
+#define LXT971_PHY_ID (0x001378e2)
+#define LXT971_PHY_MASK (0xfffffff0)
+
+static struct mtd_partition davinci_evm_norflash_partitions[] = {
+ /* bootloader (UBL, U-Boot, etc) in first 5 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 5 * SZ_64K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next 1 sectors */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data davinci_evm_norflash_data = {
+ .width = 2,
+ .parts = davinci_evm_norflash_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_evm_norflash_partitions),
+};
+
+/* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
+ * limits addresses to 16M, so using addresses past 16M will wrap */
+static struct resource davinci_evm_norflash_resource = {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device davinci_evm_norflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_evm_norflash_data,
+ },
+ .num_resources = 1,
+ .resource = &davinci_evm_norflash_resource,
+};
+
+/* DM644x EVM includes a 64 MByte small-page NAND flash (16K blocks).
+ * It may used instead of the (default) NOR chip to boot, using TI's
+ * tools to install the secondary boot loader (UBL) and U-Boot.
+ */
+static struct mtd_partition davinci_evm_nandflash_partition[] = {
+ /* Bootloader layout depends on whose u-boot is installed, but we
+ * can hide all the details.
+ * - block 0 for u-boot environment ... in mainline u-boot
+ * - block 1 for UBL (plus up to four backup copies in blocks 2..5)
+ * - blocks 6...? for u-boot
+ * - blocks 16..23 for u-boot environment ... in TI's u-boot
+ */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K + SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* Kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ /* File system (older GIT kernels started this on the 5MB mark) */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* A few blocks at end hold a flash BBT ... created by TI's CCS
+ * using flashwriter_nand.out, but ignored by TI's versions of
+ * Linux and u-boot. We boot faster by using them.
+ */
+};
+
+static struct davinci_aemif_timing davinci_evm_nandflash_timing = {
+ .wsetup = 20,
+ .wstrobe = 40,
+ .whold = 20,
+ .rsetup = 10,
+ .rstrobe = 40,
+ .rhold = 10,
+ .ta = 40,
+};
+
+static struct davinci_nand_pdata davinci_evm_nandflash_data = {
+ .parts = davinci_evm_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .timing = &davinci_evm_nandflash_timing,
+};
+
+static struct resource davinci_evm_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_evm_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_evm_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_evm_nandflash_resource),
+ .resource = davinci_evm_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+ .name = "davincifb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &davinci_fb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = 0,
+};
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+/* Inputs available at the TVP5146 */
+static struct v4l2_input tvp5146_inputs[] = {
+ {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ {
+ .index = 1,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+};
+
+/*
+ * this is the route info for connecting each input to decoder
+ * ouput that goes to vpfe. There is a one to one correspondence
+ * with tvp5146_inputs
+ */
+static struct vpfe_route tvp5146_routes[] = {
+ {
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+ {
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ },
+};
+
+static struct vpfe_subdev_info vpfe_sub_devs[] = {
+ {
+ .name = "tvp5146",
+ .grp_id = 0,
+ .num_inputs = ARRAY_SIZE(tvp5146_inputs),
+ .inputs = tvp5146_inputs,
+ .routes = tvp5146_routes,
+ .can_route = 1,
+ .ccdc_if_params = {
+ .if_type = VPFE_BT656,
+ .hdpol = VPFE_PINPOL_POSITIVE,
+ .vdpol = VPFE_PINPOL_POSITIVE,
+ },
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ },
+};
+
+static struct vpfe_config vpfe_cfg = {
+ .num_subdevs = ARRAY_SIZE(vpfe_sub_devs),
+ .i2c_adapter_id = 1,
+ .sub_devs = vpfe_sub_devs,
+ .card_name = "DM6446 EVM",
+ .ccdc = "DM6446 CCDC",
+};
+
+static struct platform_device rtc_dev = {
+ .name = "rtc_davinci_evm",
+ .id = -1,
+};
+
+static struct snd_platform_data dm644x_evm_snd_data;
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * I2C GPIO expanders
+ */
+
+#define PCF_Uxx_BASE(x) (DAVINCI_N_GPIO + ((x) * 8))
+
+
+/* U2 -- LEDs */
+
+static struct gpio_led evm_leds[] = {
+ { .name = "DS8", .active_low = 1,
+ .default_trigger = "heartbeat", },
+ { .name = "DS7", .active_low = 1, },
+ { .name = "DS6", .active_low = 1, },
+ { .name = "DS5", .active_low = 1, },
+ { .name = "DS4", .active_low = 1, },
+ { .name = "DS3", .active_low = 1, },
+ { .name = "DS2", .active_low = 1,
+ .default_trigger = "mmc0", },
+ { .name = "DS1", .active_low = 1,
+ .default_trigger = "ide-disk", },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+ .num_leds = ARRAY_SIZE(evm_leds),
+ .leds = evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int
+evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ struct gpio_led *leds = evm_leds;
+ int status;
+
+ while (ngpio--) {
+ leds->gpio = gpio++;
+ leds++;
+ }
+
+ /* what an extremely annoying way to be forced to handle
+ * device unregistration ...
+ */
+ evm_led_dev = platform_device_alloc("leds-gpio", 0);
+ platform_device_add_data(evm_led_dev,
+ &evm_led_data, sizeof evm_led_data);
+
+ evm_led_dev->dev.parent = &client->dev;
+ status = platform_device_add(evm_led_dev);
+ if (status < 0) {
+ platform_device_put(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return status;
+}
+
+static int
+evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ if (evm_led_dev) {
+ platform_device_unregister(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u2 = {
+ .gpio_base = PCF_Uxx_BASE(0),
+ .setup = evm_led_setup,
+ .teardown = evm_led_teardown,
+};
+
+
+/* U18 - A/V clock generator and user switch */
+
+static int sw_gpio;
+
+static ssize_t
+sw_show(struct device *d, struct device_attribute *a, char *buf)
+{
+ char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+
+ strcpy(buf, s);
+ return strlen(s);
+}
+
+static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
+
+static int
+evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ int status;
+
+ /* export dip switch option */
+ sw_gpio = gpio + 7;
+ status = gpio_request(sw_gpio, "user_sw");
+ if (status == 0)
+ status = gpio_direction_input(sw_gpio);
+ if (status == 0)
+ status = device_create_file(&client->dev, &dev_attr_user_sw);
+ else
+ gpio_free(sw_gpio);
+ if (status != 0)
+ sw_gpio = -EINVAL;
+
+ /* audio PLL: 48 kHz (vs 44.1 or 32), single rate (vs double) */
+ gpio_request(gpio + 3, "pll_fs2");
+ gpio_direction_output(gpio + 3, 0);
+
+ gpio_request(gpio + 2, "pll_fs1");
+ gpio_direction_output(gpio + 2, 0);
+
+ gpio_request(gpio + 1, "pll_sr");
+ gpio_direction_output(gpio + 1, 0);
+
+ return 0;
+}
+
+static int
+evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ gpio_free(gpio + 1);
+ gpio_free(gpio + 2);
+ gpio_free(gpio + 3);
+
+ if (sw_gpio > 0) {
+ device_remove_file(&client->dev, &dev_attr_user_sw);
+ gpio_free(sw_gpio);
+ }
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u18 = {
+ .gpio_base = PCF_Uxx_BASE(1),
+ .n_latch = (1 << 3) | (1 << 2) | (1 << 1),
+ .setup = evm_u18_setup,
+ .teardown = evm_u18_teardown,
+};
+
+
+/* U35 - various I/O signals used to manage USB, CF, ATA, etc */
+
+static int
+evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ /* p0 = nDRV_VBUS (initial: don't supply it) */
+ gpio_request(gpio + 0, "nDRV_VBUS");
+ gpio_direction_output(gpio + 0, 1);
+
+ /* p1 = VDDIMX_EN */
+ gpio_request(gpio + 1, "VDDIMX_EN");
+ gpio_direction_output(gpio + 1, 1);
+
+ /* p2 = VLYNQ_EN */
+ gpio_request(gpio + 2, "VLYNQ_EN");
+ gpio_direction_output(gpio + 2, 1);
+
+ /* p3 = n3V3_CF_RESET (initial: stay in reset) */
+ gpio_request(gpio + 3, "nCF_RESET");
+ gpio_direction_output(gpio + 3, 0);
+
+ /* (p4 unused) */
+
+ /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
+ gpio_request(gpio + 5, "WLAN_RESET");
+ gpio_direction_output(gpio + 5, 1);
+
+ /* p6 = nATA_SEL (initial: select) */
+ gpio_request(gpio + 6, "nATA_SEL");
+ gpio_direction_output(gpio + 6, 0);
+
+ /* p7 = nCF_SEL (initial: deselect) */
+ gpio_request(gpio + 7, "nCF_SEL");
+ gpio_direction_output(gpio + 7, 1);
+
+ return 0;
+}
+
+static int
+evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+{
+ gpio_free(gpio + 7);
+ gpio_free(gpio + 6);
+ gpio_free(gpio + 5);
+ gpio_free(gpio + 3);
+ gpio_free(gpio + 2);
+ gpio_free(gpio + 1);
+ gpio_free(gpio + 0);
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data_u35 = {
+ .gpio_base = PCF_Uxx_BASE(2),
+ .setup = evm_u35_setup,
+ .teardown = evm_u35_teardown,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ * - 0x7f00, 6 bytes Ethernet Address
+ * - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
+ * - ... newer boards may have more
+ */
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+/*
+ * MSP430 supports RTC, card detection, input from IR remote, and
+ * a bit more. It triggers interrupts on GPIO(7) from pressing
+ * buttons on the IR remote, and for card detect switches.
+ */
+static struct i2c_client *dm6446evm_msp;
+
+static int dm6446evm_msp_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ dm6446evm_msp = client;
+ return 0;
+}
+
+static int dm6446evm_msp_remove(struct i2c_client *client)
+{
+ dm6446evm_msp = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id dm6446evm_msp_ids[] = {
+ { "dm6446evm_msp", 0, },
+ { /* end of list */ },
+};
+
+static struct i2c_driver dm6446evm_msp_driver = {
+ .driver.name = "dm6446evm_msp",
+ .id_table = dm6446evm_msp_ids,
+ .probe = dm6446evm_msp_probe,
+ .remove = dm6446evm_msp_remove,
+};
+
+static int dm6444evm_msp430_get_pins(void)
+{
+ static const char txbuf[2] = { 2, 4, };
+ char buf[4];
+ struct i2c_msg msg[2] = {
+ {
+ .addr = dm6446evm_msp->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = (void __force *)txbuf,
+ },
+ {
+ .addr = dm6446evm_msp->addr,
+ .flags = I2C_M_RD,
+ .len = 4,
+ .buf = buf,
+ },
+ };
+ int status;
+
+ if (!dm6446evm_msp)
+ return -ENXIO;
+
+ /* Command 4 == get input state, returns port 2 and port3 data
+ * S Addr W [A] len=2 [A] cmd=4 [A]
+ * RS Addr R [A] [len=4] A [cmd=4] A [port2] A [port3] N P
+ */
+ status = i2c_transfer(dm6446evm_msp->adapter, msg, 2);
+ if (status < 0)
+ return status;
+
+ dev_dbg(&dm6446evm_msp->dev,
+ "PINS: %02x %02x %02x %02x\n",
+ buf[0], buf[1], buf[2], buf[3]);
+
+ return (buf[3] << 8) | buf[2];
+}
+
+static int dm6444evm_mmc_get_cd(int module)
+{
+ int status = dm6444evm_msp430_get_pins();
+
+ return (status < 0) ? status : !(status & BIT(1));
+}
+
+static int dm6444evm_mmc_get_ro(int module)
+{
+ int status = dm6444evm_msp430_get_pins();
+
+ return (status < 0) ? status : status & BIT(6 + 8);
+}
+
+static struct davinci_mmc_config dm6446evm_mmc_config = {
+ .get_cd = dm6444evm_mmc_get_cd,
+ .get_ro = dm6444evm_mmc_get_ro,
+ .wires = 4,
+ .version = MMC_CTLR_VERSION_1
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("dm6446evm_msp", 0x23),
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x38),
+ .platform_data = &pcf_data_u2,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x39),
+ .platform_data = &pcf_data_u18,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574", 0x3a),
+ .platform_data = &pcf_data_u35,
+ },
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic33", 0x1b),
+ },
+};
+
+/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
+ * which requires 100 usec of idle bus after i2c writes sent to it.
+ */
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+ .sda_pin = 44,
+ .scl_pin = 43,
+};
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_add_driver(&dm6446evm_msp_driver);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *davinci_evm_devices[] __initdata = {
+ &davinci_fb_device,
+ &rtc_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init
+davinci_evm_map_io(void)
+{
+ /* setup input configuration for VPFE input devices */
+ dm644x_set_vpfe_config(&vpfe_cfg);
+ dm644x_init();
+}
+
+static int davinci_phy_fixup(struct phy_device *phydev)
+{
+ unsigned int control;
+ /* CRITICAL: Fix for increasing PHY signal drive strength for
+ * TX lockup issue. On DaVinci EVM, the Intel LXT971 PHY
+ * signal strength was low causing TX to fail randomly. The
+ * fix is to Set bit 11 (Increased MII drive strength) of PHY
+ * register 26 (Digital Config register) on this phy. */
+ control = phy_read(phydev, 26);
+ phy_write(phydev, 26, (control | 0x800));
+ return 0;
+}
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || \
+ defined(CONFIG_MTD_PHYSMAP_MODULE)
+#define HAS_NOR 1
+#else
+#define HAS_NOR 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+ defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_evm_init(void)
+{
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND || HAS_NOR)
+ pr_warning("WARNING: both IDE and Flash are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable IDE for NAND/NOR support.\n");
+ davinci_init_ide();
+ } else if (HAS_NAND || HAS_NOR) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+ /* only one device will be jumpered and detected */
+ if (HAS_NAND) {
+ platform_device_register(&davinci_evm_nandflash_device);
+ evm_leds[7].default_trigger = "nand-disk";
+ if (HAS_NOR)
+ pr_warning("WARNING: both NAND and NOR flash "
+ "are enabled; disable one of them.\n");
+ } else if (HAS_NOR)
+ platform_device_register(&davinci_evm_norflash_device);
+ }
+
+ platform_add_devices(davinci_evm_devices,
+ ARRAY_SIZE(davinci_evm_devices));
+ evm_init_i2c();
+
+ davinci_setup_mmc(0, &dm6446evm_mmc_config);
+
+ davinci_serial_init(&uart_config);
+ dm644x_init_asp(&dm644x_evm_snd_data);
+
+ /* irlml6401 switches over 1A, in under 8 msec */
+ davinci_setup_usb(1000, 8);
+
+ soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID;
+ /* Register the fixup for PHY on DaVinci */
+ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK,
+ davinci_phy_fixup);
+
+}
+
+MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM")
+ /* Maintainer: MontaVista Software <source@mvista.com> */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_evm_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
new file mode 100644
index 00000000..3cdd2378
--- /dev/null
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -0,0 +1,814 @@
+/*
+ * TI DaVinci DM646X EVM board
+ *
+ * Derived from: arch/arm/mach-davinci/board-evm.c
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * (C) 2007-2008, MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/i2c/pcf857x.h>
+
+#include <media/tvp514x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm646x.h>
+#include <mach/common.h>
+#include <mach/serial.h>
+#include <mach/i2c.h>
+#include <mach/nand.h>
+#include <mach/clock.h>
+#include <mach/cdce949.h>
+#include <mach/aemif.h>
+
+#include "clock.h"
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+/* Note: We are setting first partition as 'bootloader' constituting UBL, U-Boot
+ * and U-Boot environment this avoids dependency on any particular combination
+ * of UBL, U-Boot or flashing tools etc.
+ */
+static struct mtd_partition davinci_nand_partitions[] = {
+ {
+ /* UBL, U-Boot with environment */
+ .name = "bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
+ .wsetup = 29,
+ .wstrobe = 24,
+ .whold = 14,
+ .rsetup = 19,
+ .rstrobe = 33,
+ .rhold = 0,
+ .ta = 29,
+};
+
+static struct davinci_nand_pdata davinci_nand_data = {
+ .mask_cle = 0x80000,
+ .mask_ale = 0x40000,
+ .parts = davinci_nand_partitions,
+ .nr_parts = ARRAY_SIZE(davinci_nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = 0,
+};
+
+static struct resource davinci_nand_resources[] = {
+ {
+ .start = DM646X_ASYNC_EMIF_CS2_SPACE_BASE,
+ .end = DM646X_ASYNC_EMIF_CS2_SPACE_BASE + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM646X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM646X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_nand_device = {
+ .name = "davinci_nand",
+ .id = 0,
+
+ .num_resources = ARRAY_SIZE(davinci_nand_resources),
+ .resource = davinci_nand_resources,
+
+ .dev = {
+ .platform_data = &davinci_nand_data,
+ },
+};
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+/* CPLD Register 0 bits to control ATA */
+#define DM646X_EVM_ATA_RST BIT(0)
+#define DM646X_EVM_ATA_PWD BIT(1)
+
+/* CPLD Register 0 Client: used for I/O Control */
+static int cpld_reg0_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ if (HAS_ATA) {
+ u8 data;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = &data,
+ },
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &data,
+ },
+ };
+
+ /* Clear ATA_RSTn and ATA_PWD bits to enable ATA operation. */
+ i2c_transfer(client->adapter, msg, 1);
+ data &= ~(DM646X_EVM_ATA_RST | DM646X_EVM_ATA_PWD);
+ i2c_transfer(client->adapter, msg + 1, 1);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id cpld_reg_ids[] = {
+ { "cpld_reg0", 0, },
+ { },
+};
+
+static struct i2c_driver dm6467evm_cpld_driver = {
+ .driver.name = "cpld_reg0",
+ .id_table = cpld_reg_ids,
+ .probe = cpld_reg0_probe,
+};
+
+/* LEDS */
+
+static struct gpio_led evm_leds[] = {
+ { .name = "DS1", .active_low = 1, },
+ { .name = "DS2", .active_low = 1, },
+ { .name = "DS3", .active_low = 1, },
+ { .name = "DS4", .active_low = 1, },
+};
+
+static const struct gpio_led_platform_data evm_led_data = {
+ .num_leds = ARRAY_SIZE(evm_leds),
+ .leds = evm_leds,
+};
+
+static struct platform_device *evm_led_dev;
+
+static int evm_led_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ struct gpio_led *leds = evm_leds;
+ int status;
+
+ while (ngpio--) {
+ leds->gpio = gpio++;
+ leds++;
+ };
+
+ evm_led_dev = platform_device_alloc("leds-gpio", 0);
+ platform_device_add_data(evm_led_dev, &evm_led_data,
+ sizeof(evm_led_data));
+
+ evm_led_dev->dev.parent = &client->dev;
+ status = platform_device_add(evm_led_dev);
+ if (status < 0) {
+ platform_device_put(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return status;
+}
+
+static int evm_led_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ if (evm_led_dev) {
+ platform_device_unregister(evm_led_dev);
+ evm_led_dev = NULL;
+ }
+ return 0;
+}
+
+static int evm_sw_gpio[4] = { -EINVAL, -EINVAL, -EINVAL, -EINVAL };
+
+static int evm_sw_setup(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ int status;
+ int i;
+ char label[10];
+
+ for (i = 0; i < 4; ++i) {
+ snprintf(label, 10, "user_sw%d", i);
+ status = gpio_request(gpio, label);
+ if (status)
+ goto out_free;
+ evm_sw_gpio[i] = gpio++;
+
+ status = gpio_direction_input(evm_sw_gpio[i]);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+
+ status = gpio_export(evm_sw_gpio[i], 0);
+ if (status) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ goto out_free;
+ }
+ }
+ return status;
+out_free:
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return status;
+}
+
+static int evm_sw_teardown(struct i2c_client *client, int gpio,
+ unsigned ngpio, void *c)
+{
+ int i;
+
+ for (i = 0; i < 4; ++i) {
+ if (evm_sw_gpio[i] != -EINVAL) {
+ gpio_unexport(evm_sw_gpio[i]);
+ gpio_free(evm_sw_gpio[i]);
+ evm_sw_gpio[i] = -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int evm_pcf_setup(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ int status;
+
+ if (ngpio < 8)
+ return -EINVAL;
+
+ status = evm_sw_setup(client, gpio, 4, c);
+ if (status)
+ return status;
+
+ return evm_led_setup(client, gpio+4, 4, c);
+}
+
+static int evm_pcf_teardown(struct i2c_client *client, int gpio,
+ unsigned int ngpio, void *c)
+{
+ BUG_ON(ngpio < 8);
+
+ evm_sw_teardown(client, gpio, 4, c);
+ evm_led_teardown(client, gpio+4, 4, c);
+
+ return 0;
+}
+
+static struct pcf857x_platform_data pcf_data = {
+ .gpio_base = DAVINCI_N_GPIO+1,
+ .setup = evm_pcf_setup,
+ .teardown = evm_pcf_teardown,
+};
+
+/* Most of this EEPROM is unused, but U-Boot uses some data:
+ * - 0x7f00, 6 bytes Ethernet Address
+ * - ... newer boards may have more
+ */
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (256*1024) / 8,
+ .page_size = 64,
+ .flags = AT24_FLAG_ADDR16,
+ .setup = davinci_get_mac_addr,
+ .context = (void *)0x7f00,
+};
+
+static u8 dm646x_iis_serializer_direction[] = {
+ TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE,
+};
+
+static u8 dm646x_dit_serializer_direction[] = {
+ TX_MODE,
+};
+
+static struct snd_platform_data dm646x_evm_snd_data[] = {
+ {
+ .tx_dma_offset = 0x400,
+ .rx_dma_offset = 0x400,
+ .op_mode = DAVINCI_MCASP_IIS_MODE,
+ .num_serializer = ARRAY_SIZE(dm646x_iis_serializer_direction),
+ .tdm_slots = 2,
+ .serial_dir = dm646x_iis_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ },
+ {
+ .tx_dma_offset = 0x400,
+ .rx_dma_offset = 0,
+ .op_mode = DAVINCI_MCASP_DIT_MODE,
+ .num_serializer = ARRAY_SIZE(dm646x_dit_serializer_direction),
+ .tdm_slots = 32,
+ .serial_dir = dm646x_dit_serializer_direction,
+ .asp_chan_q = EVENTQ_0,
+ },
+};
+
+static struct i2c_client *cpld_client;
+
+static int cpld_video_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ cpld_client = client;
+ return 0;
+}
+
+static int __devexit cpld_video_remove(struct i2c_client *client)
+{
+ cpld_client = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id cpld_video_id[] = {
+ { "cpld_video", 0 },
+ { }
+};
+
+static struct i2c_driver cpld_video_driver = {
+ .driver = {
+ .name = "cpld_video",
+ },
+ .probe = cpld_video_probe,
+ .remove = cpld_video_remove,
+ .id_table = cpld_video_id,
+};
+
+static void evm_init_cpld(void)
+{
+ i2c_add_driver(&cpld_video_driver);
+}
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c256", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ {
+ I2C_BOARD_INFO("pcf8574a", 0x38),
+ .platform_data = &pcf_data,
+ },
+ {
+ I2C_BOARD_INFO("cpld_reg0", 0x3a),
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic33", 0x18),
+ },
+ {
+ I2C_BOARD_INFO("cpld_video", 0x3b),
+ },
+ {
+ I2C_BOARD_INFO("cdce949", 0x6c),
+ },
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 100 /* kHz */,
+ .bus_delay = 0 /* usec */,
+};
+
+#define VIDCLKCTL_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x38)
+#define VSCLKDIS_OFFSET (DAVINCI_SYSTEM_MODULE_BASE + 0x6c)
+#define VCH2CLK_MASK (BIT_MASK(10) | BIT_MASK(9) | BIT_MASK(8))
+#define VCH2CLK_SYSCLK8 (BIT(9))
+#define VCH2CLK_AUXCLK (BIT(9) | BIT(8))
+#define VCH3CLK_MASK (BIT_MASK(14) | BIT_MASK(13) | BIT_MASK(12))
+#define VCH3CLK_SYSCLK8 (BIT(13))
+#define VCH3CLK_AUXCLK (BIT(14) | BIT(13))
+
+#define VIDCH2CLK (BIT(10))
+#define VIDCH3CLK (BIT(11))
+#define VIDCH1CLK (BIT(4))
+#define TVP7002_INPUT (BIT(4))
+#define TVP5147_INPUT (~BIT(4))
+#define VPIF_INPUT_ONE_CHANNEL (BIT(5))
+#define VPIF_INPUT_TWO_CHANNEL (~BIT(5))
+#define TVP5147_CH0 "tvp514x-0"
+#define TVP5147_CH1 "tvp514x-1"
+
+static void __iomem *vpif_vidclkctl_reg;
+static void __iomem *vpif_vsclkdis_reg;
+/* spin lock for updating above registers */
+static spinlock_t vpif_reg_lock;
+
+static int set_vpif_clock(int mux_mode, int hd)
+{
+ unsigned long flags;
+ unsigned int value;
+ int val = 0;
+ int err = 0;
+
+ if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg || !cpld_client)
+ return -ENXIO;
+
+ /* disable the clock */
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vsclkdis_reg);
+ value |= (VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, vpif_vsclkdis_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ if (mux_mode == 1)
+ val &= ~0x40;
+ else
+ val |= 0x40;
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+
+ value = __raw_readl(vpif_vidclkctl_reg);
+ value &= ~(VCH2CLK_MASK);
+ value &= ~(VCH3CLK_MASK);
+
+ if (hd >= 1)
+ value |= (VCH2CLK_SYSCLK8 | VCH3CLK_SYSCLK8);
+ else
+ value |= (VCH2CLK_AUXCLK | VCH3CLK_AUXCLK);
+
+ __raw_writel(value, vpif_vidclkctl_reg);
+
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vsclkdis_reg);
+ /* enable the clock */
+ value &= ~(VIDCH3CLK | VIDCH2CLK);
+ __raw_writel(value, vpif_vsclkdis_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ return 0;
+}
+
+static struct vpif_subdev_info dm646x_vpif_subdev[] = {
+ {
+ .name = "adv7343",
+ .board_info = {
+ I2C_BOARD_INFO("adv7343", 0x2a),
+ },
+ },
+ {
+ .name = "ths7303",
+ .board_info = {
+ I2C_BOARD_INFO("ths7303", 0x2c),
+ },
+ },
+};
+
+static const char *output[] = {
+ "Composite",
+ "Component",
+ "S-Video",
+};
+
+static struct vpif_display_config dm646x_vpif_display_config = {
+ .set_clock = set_vpif_clock,
+ .subdevinfo = dm646x_vpif_subdev,
+ .subdev_count = ARRAY_SIZE(dm646x_vpif_subdev),
+ .output = output,
+ .output_count = ARRAY_SIZE(output),
+ .card_name = "DM646x EVM",
+};
+
+/**
+ * setup_vpif_input_path()
+ * @channel: channel id (0 - CH0, 1 - CH1)
+ * @sub_dev_name: ptr sub device name
+ *
+ * This will set vpif input to capture data from tvp514x or
+ * tvp7002.
+ */
+static int setup_vpif_input_path(int channel, const char *sub_dev_name)
+{
+ int err = 0;
+ int val;
+
+ /* for channel 1, we don't do anything */
+ if (channel != 0)
+ return 0;
+
+ if (!cpld_client)
+ return -ENXIO;
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ if (!strcmp(sub_dev_name, TVP5147_CH0) ||
+ !strcmp(sub_dev_name, TVP5147_CH1))
+ val &= TVP5147_INPUT;
+ else
+ val |= TVP7002_INPUT;
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+ return 0;
+}
+
+/**
+ * setup_vpif_input_channel_mode()
+ * @mux_mode: mux mode. 0 - 1 channel or (1) - 2 channel
+ *
+ * This will setup input mode to one channel (TVP7002) or 2 channel (TVP5147)
+ */
+static int setup_vpif_input_channel_mode(int mux_mode)
+{
+ unsigned long flags;
+ int err = 0;
+ int val;
+ u32 value;
+
+ if (!vpif_vidclkctl_reg || !cpld_client)
+ return -ENXIO;
+
+ val = i2c_smbus_read_byte(cpld_client);
+ if (val < 0)
+ return val;
+
+ spin_lock_irqsave(&vpif_reg_lock, flags);
+ value = __raw_readl(vpif_vidclkctl_reg);
+ if (mux_mode) {
+ val &= VPIF_INPUT_TWO_CHANNEL;
+ value |= VIDCH1CLK;
+ } else {
+ val |= VPIF_INPUT_ONE_CHANNEL;
+ value &= ~VIDCH1CLK;
+ }
+ __raw_writel(value, vpif_vidclkctl_reg);
+ spin_unlock_irqrestore(&vpif_reg_lock, flags);
+
+ err = i2c_smbus_write_byte(cpld_client, val);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .clk_polarity = 0,
+ .hs_polarity = 1,
+ .vs_polarity = 1
+};
+
+#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL)
+
+static struct vpif_subdev_info vpif_capture_sdev_info[] = {
+ {
+ .name = TVP5147_CH0,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5d),
+ .platform_data = &tvp5146_pdata,
+ },
+ .input = INPUT_CVBS_VI2B,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .can_route = 1,
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+ {
+ .name = TVP5147_CH1,
+ .board_info = {
+ I2C_BOARD_INFO("tvp5146", 0x5c),
+ .platform_data = &tvp5146_pdata,
+ },
+ .input = INPUT_SVIDEO_VI2C_VI1C,
+ .output = OUTPUT_10BIT_422_EMBEDDED_SYNC,
+ .can_route = 1,
+ .vpif_if = {
+ .if_type = VPIF_IF_BT656,
+ .hd_pol = 1,
+ .vd_pol = 1,
+ .fid_pol = 0,
+ },
+ },
+};
+
+static const struct vpif_input dm6467_ch0_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "Composite",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH0,
+ },
+};
+
+static const struct vpif_input dm6467_ch1_inputs[] = {
+ {
+ .input = {
+ .index = 0,
+ .name = "S-Video",
+ .type = V4L2_INPUT_TYPE_CAMERA,
+ .std = TVP514X_STD_ALL,
+ },
+ .subdev_name = TVP5147_CH1,
+ },
+};
+
+static struct vpif_capture_config dm646x_vpif_capture_cfg = {
+ .setup_input_path = setup_vpif_input_path,
+ .setup_input_channel_mode = setup_vpif_input_channel_mode,
+ .subdev_info = vpif_capture_sdev_info,
+ .subdev_count = ARRAY_SIZE(vpif_capture_sdev_info),
+ .chan_config[0] = {
+ .inputs = dm6467_ch0_inputs,
+ .input_count = ARRAY_SIZE(dm6467_ch0_inputs),
+ },
+ .chan_config[1] = {
+ .inputs = dm6467_ch1_inputs,
+ .input_count = ARRAY_SIZE(dm6467_ch1_inputs),
+ },
+};
+
+static void __init evm_init_video(void)
+{
+ vpif_vidclkctl_reg = ioremap(VIDCLKCTL_OFFSET, 4);
+ vpif_vsclkdis_reg = ioremap(VSCLKDIS_OFFSET, 4);
+ if (!vpif_vidclkctl_reg || !vpif_vsclkdis_reg) {
+ pr_err("Can't map VPIF VIDCLKCTL or VSCLKDIS registers\n");
+ return;
+ }
+ spin_lock_init(&vpif_reg_lock);
+
+ dm646x_setup_vpif(&dm646x_vpif_display_config,
+ &dm646x_vpif_capture_cfg);
+}
+
+static void __init evm_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_add_driver(&dm6467evm_cpld_driver);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+ evm_init_cpld();
+ evm_init_video();
+}
+
+#define CDCE949_XIN_RATE 27000000
+
+/* CDCE949 support - "lpsc" field is overridden to work as clock number */
+static struct clk cdce_clk_in = {
+ .name = "cdce_xin",
+ .rate = CDCE949_XIN_RATE,
+};
+
+static struct clk_lookup cdce_clks[] = {
+ CLK(NULL, "xin", &cdce_clk_in),
+ CLK(NULL, NULL, NULL),
+};
+
+static void __init cdce_clk_init(void)
+{
+ struct clk_lookup *c;
+ struct clk *clk;
+
+ for (c = cdce_clks; c->clk; c++) {
+ clk = c->clk;
+ clkdev_add(c);
+ clk_register(clk);
+ }
+}
+
+static void __init davinci_map_io(void)
+{
+ dm646x_init();
+ cdce_clk_init();
+}
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+#define DM646X_EVM_PHY_ID "0:01"
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on dm646x, hence they are being
+ * reserved for codecs on the DSP side.
+ */
+static const s16 dm646x_dma_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 4},
+ {13, 3},
+ {24, 4},
+ {30, 2},
+ {54, 3},
+ {-1, -1}
+};
+
+static const s16 dm646x_dma_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 4},
+ {13, 3},
+ {24, 4},
+ {30, 2},
+ {54, 3},
+ {128, 384},
+ {-1, -1}
+};
+
+static struct edma_rsv_info dm646x_edma_rsv[] = {
+ {
+ .rsv_chans = dm646x_dma_rsv_chans,
+ .rsv_slots = dm646x_dma_rsv_slots,
+ },
+};
+
+static __init void evm_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ evm_init_i2c();
+ davinci_serial_init(&uart_config);
+ dm646x_init_mcasp0(&dm646x_evm_snd_data[0]);
+ dm646x_init_mcasp1(&dm646x_evm_snd_data[1]);
+
+ if (machine_is_davinci_dm6467tevm())
+ davinci_nand_data.timing = &dm6467tevm_nandflash_timing;
+
+ platform_device_register(&davinci_nand_device);
+
+ dm646x_init_edma(dm646x_edma_rsv);
+
+ if (HAS_ATA)
+ davinci_init_ide();
+
+ soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID;
+}
+
+#define DM646X_EVM_REF_FREQ 27000000
+#define DM6467T_EVM_REF_FREQ 33000000
+
+void __init dm646x_board_setup_refclk(struct clk *clk)
+{
+ if (machine_is_davinci_dm6467tevm())
+ clk->rate = DM6467T_EVM_REF_FREQ;
+ else
+ clk->rate = DM646X_EVM_REF_FREQ;
+}
+
+MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM")
+ .boot_params = (0x80000100),
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = evm_init,
+MACHINE_END
+
+MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM")
+ .boot_params = (0x80000100),
+ .map_io = davinci_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = evm_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c
new file mode 100644
index 00000000..5f5d7830
--- /dev/null
+++ b/arch/arm/mach-davinci/board-mityomapl138.c
@@ -0,0 +1,574 @@
+/*
+ * Critical Link MityOMAP-L138 SoM
+ *
+ * Copyright (C) 2010 Critical Link LLC - http://www.criticallink.com
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of
+ * any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/nand.h>
+#include <mach/mux.h>
+#include <mach/spi.h>
+
+#define MITYOMAPL138_PHY_ID ""
+
+#define FACTORY_CONFIG_MAGIC 0x012C0138
+#define FACTORY_CONFIG_VERSION 0x00010001
+
+/* Data Held in On-Board I2C device */
+struct factory_config {
+ u32 magic;
+ u32 version;
+ u8 mac[6];
+ u32 fpga_type;
+ u32 spare;
+ u32 serialnumber;
+ char partnum[32];
+};
+
+static struct factory_config factory_config;
+
+struct part_no_info {
+ const char *part_no; /* part number string of interest */
+ int max_freq; /* khz */
+};
+
+static struct part_no_info mityomapl138_pn_info[] = {
+ {
+ .part_no = "L138-C",
+ .max_freq = 300000,
+ },
+ {
+ .part_no = "L138-D",
+ .max_freq = 375000,
+ },
+ {
+ .part_no = "L138-F",
+ .max_freq = 456000,
+ },
+ {
+ .part_no = "1808-C",
+ .max_freq = 300000,
+ },
+ {
+ .part_no = "1808-D",
+ .max_freq = 375000,
+ },
+ {
+ .part_no = "1808-F",
+ .max_freq = 456000,
+ },
+ {
+ .part_no = "1810-D",
+ .max_freq = 375000,
+ },
+};
+
+#ifdef CONFIG_CPU_FREQ
+static void mityomapl138_cpufreq_init(const char *partnum)
+{
+ int i, ret;
+
+ for (i = 0; partnum && i < ARRAY_SIZE(mityomapl138_pn_info); i++) {
+ /*
+ * the part number has additional characters beyond what is
+ * stored in the table. This information is not needed for
+ * determining the speed grade, and would require several
+ * more table entries. Only check the first N characters
+ * for a match.
+ */
+ if (!strncmp(partnum, mityomapl138_pn_info[i].part_no,
+ strlen(mityomapl138_pn_info[i].part_no))) {
+ da850_max_speed = mityomapl138_pn_info[i].max_freq;
+ break;
+ }
+ }
+
+ ret = da850_register_cpufreq("pll0_sysclk3");
+ if (ret)
+ pr_warning("cpufreq registration failed: %d\n", ret);
+}
+#else
+static void mityomapl138_cpufreq_init(const char *partnum) { }
+#endif
+
+static void read_factory_config(struct memory_accessor *a, void *context)
+{
+ int ret;
+ const char *partnum = NULL;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ ret = a->read(a, (char *)&factory_config, 0, sizeof(factory_config));
+ if (ret != sizeof(struct factory_config)) {
+ pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n",
+ ret);
+ goto bad_config;
+ }
+
+ if (factory_config.magic != FACTORY_CONFIG_MAGIC) {
+ pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n",
+ factory_config.magic);
+ goto bad_config;
+ }
+
+ if (factory_config.version != FACTORY_CONFIG_VERSION) {
+ pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n",
+ factory_config.version);
+ goto bad_config;
+ }
+
+ pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac);
+ if (is_valid_ether_addr(factory_config.mac))
+ memcpy(soc_info->emac_pdata->mac_addr,
+ factory_config.mac, ETH_ALEN);
+ else
+ pr_warning("MityOMAPL138: Invalid MAC found "
+ "in factory config block\n");
+
+ partnum = factory_config.partnum;
+ pr_info("MityOMAPL138: Part Number = %s\n", partnum);
+
+bad_config:
+ /* default maximum speed is valid for all platforms */
+ mityomapl138_cpufreq_init(partnum);
+}
+
+static struct at24_platform_data mityomapl138_fd_chip = {
+ .byte_len = 256,
+ .page_size = 8,
+ .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO,
+ .setup = read_factory_config,
+ .context = NULL,
+};
+
+static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = {
+ .bus_freq = 100, /* kHz */
+ .bus_delay = 0, /* usec */
+};
+
+/* TPS65023 voltage regulator support */
+/* 1.2V Core */
+static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = {
+ {
+ .supply = "cvdd",
+ },
+};
+
+/* 1.8V */
+static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = {
+ {
+ .supply = "usb0_vdda18",
+ },
+ {
+ .supply = "usb1_vdda18",
+ },
+ {
+ .supply = "ddr_dvdd18",
+ },
+ {
+ .supply = "sata_vddr",
+ },
+};
+
+/* 1.2V */
+static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = {
+ {
+ .supply = "sata_vdd",
+ },
+ {
+ .supply = "usb_cvdd",
+ },
+ {
+ .supply = "pll0_vdda",
+ },
+ {
+ .supply = "pll1_vdda",
+ },
+};
+
+/* 1.8V Aux LDO, not used */
+static struct regulator_consumer_supply tps65023_ldo1_consumers[] = {
+ {
+ .supply = "1.8v_aux",
+ },
+};
+
+/* FPGA VCC Aux (2.5 or 3.3) LDO */
+static struct regulator_consumer_supply tps65023_ldo2_consumers[] = {
+ {
+ .supply = "vccaux",
+ },
+};
+
+static struct regulator_init_data tps65023_regulator_data[] = {
+ /* dcdc1 */
+ {
+ .constraints = {
+ .min_uV = 1150000,
+ .max_uV = 1350000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc1_consumers),
+ .consumer_supplies = tps65023_dcdc1_consumers,
+ },
+ /* dcdc2 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc2_consumers),
+ .consumer_supplies = tps65023_dcdc2_consumers,
+ },
+ /* dcdc3 */
+ {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc3_consumers),
+ .consumer_supplies = tps65023_dcdc3_consumers,
+ },
+ /* ldo1 */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo1_consumers),
+ .consumer_supplies = tps65023_ldo1_consumers,
+ },
+ /* ldo2 */
+ {
+ .constraints = {
+ .min_uV = 2500000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo2_consumers),
+ .consumer_supplies = tps65023_ldo2_consumers,
+ },
+};
+
+static struct i2c_board_info __initdata mityomap_tps65023_info[] = {
+ {
+ I2C_BOARD_INFO("tps65023", 0x48),
+ .platform_data = &tps65023_regulator_data[0],
+ },
+ {
+ I2C_BOARD_INFO("24c02", 0x50),
+ .platform_data = &mityomapl138_fd_chip,
+ },
+};
+
+static int __init pmic_tps65023_init(void)
+{
+ return i2c_register_board_info(1, mityomap_tps65023_info,
+ ARRAY_SIZE(mityomap_tps65023_info));
+}
+
+/*
+ * SPI Devices:
+ * SPI1_CS0: 8M Flash ST-M25P64-VME6G
+ */
+static struct mtd_partition spi_flash_partitions[] = {
+ [0] = {
+ .name = "ubl",
+ .offset = 0,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "u-boot-env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [3] = {
+ .name = "periph-config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [4] = {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K + SZ_64K,
+ },
+ [5] = {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M + SZ_1M,
+ },
+ [6] = {
+ .name = "fpga",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ },
+ [7] = {
+ .name = "spare",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data mityomapl138_spi_flash_data = {
+ .name = "m25p80",
+ .parts = spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(spi_flash_partitions),
+ .type = "m24p64",
+};
+
+static struct davinci_spi_config spi_eprom_config = {
+ .io_type = SPI_IO_TYPE_DMA,
+ .c2tdelay = 8,
+ .t2cdelay = 8,
+};
+
+static struct spi_board_info mityomapl138_spi_flash_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &mityomapl138_spi_flash_data,
+ .controller_data = &spi_eprom_config,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 30000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+/*
+ * MityDSP-L138 includes a 256 MByte large-page NAND flash
+ * (128K blocks).
+ */
+static struct mtd_partition mityomapl138_nandflash_partition[] = {
+ {
+ .name = "rootfs",
+ .offset = 0,
+ .size = SZ_128M,
+ .mask_flags = 0, /* MTD_WRITEABLE, */
+ },
+ {
+ .name = "homefs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct davinci_nand_pdata mityomapl138_nandflash_data = {
+ .parts = mityomapl138_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16,
+ .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */
+};
+
+static struct resource mityomapl138_nandflash_resource[] = {
+ {
+ .start = DA8XX_AEMIF_CS3_BASE,
+ .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DA8XX_AEMIF_CTL_BASE,
+ .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mityomapl138_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 1,
+ .dev = {
+ .platform_data = &mityomapl138_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource),
+ .resource = mityomapl138_nandflash_resource,
+};
+
+static struct platform_device *mityomapl138_devices[] __initdata = {
+ &mityomapl138_nandflash_device,
+};
+
+static void __init mityomapl138_setup_nand(void)
+{
+ platform_add_devices(mityomapl138_devices,
+ ARRAY_SIZE(mityomapl138_devices));
+}
+
+static struct davinci_uart_config mityomapl138_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static const short mityomap_mii_pins[] = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static const short mityomap_rmii_pins[] = {
+ DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1,
+ DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static void __init mityomapl138_config_emac(void)
+{
+ void __iomem *cfg_chip3_base;
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ soc_info->emac_pdata->rmii_en = 0; /* hardcoded for now */
+
+ cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+ val = __raw_readl(cfg_chip3_base);
+
+ if (soc_info->emac_pdata->rmii_en) {
+ val |= BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_rmii_pins);
+ pr_info("RMII PHY configured\n");
+ } else {
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(mityomap_mii_pins);
+ pr_info("MII PHY configured\n");
+ }
+
+ if (ret) {
+ pr_warning("mii/rmii mux setup failed: %d\n", ret);
+ return;
+ }
+
+ /* configure the CFGCHIP3 register for RMII or MII */
+ __raw_writel(val, cfg_chip3_base);
+
+ soc_info->emac_pdata->phy_id = MITYOMAPL138_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("emac registration failed: %d\n", ret);
+}
+
+static struct davinci_pm_config da850_pm_pdata = {
+ .sleepcount = 128,
+};
+
+static struct platform_device da850_pm_device = {
+ .name = "pm-davinci",
+ .dev = {
+ .platform_data = &da850_pm_pdata,
+ },
+ .id = -1,
+};
+
+static void __init mityomapl138_init(void)
+{
+ int ret;
+
+ /* for now, no special EDMA channels are reserved */
+ ret = da850_register_edma(NULL);
+ if (ret)
+ pr_warning("edma registration failed: %d\n", ret);
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("watchdog registration failed: %d\n", ret);
+
+ davinci_serial_init(&mityomapl138_uart_config);
+
+ ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata);
+ if (ret)
+ pr_warning("i2c0 registration failed: %d\n", ret);
+
+ ret = pmic_tps65023_init();
+ if (ret)
+ pr_warning("TPS65023 PMIC init failed: %d\n", ret);
+
+ mityomapl138_setup_nand();
+
+ ret = da8xx_register_spi(1, mityomapl138_spi_flash_info,
+ ARRAY_SIZE(mityomapl138_spi_flash_info));
+ if (ret)
+ pr_warning("spi 1 registration failed: %d\n", ret);
+
+ mityomapl138_config_emac();
+
+ ret = da8xx_register_rtc();
+ if (ret)
+ pr_warning("rtc setup failed: %d\n", ret);
+
+ ret = da8xx_register_cpuidle();
+ if (ret)
+ pr_warning("cpuidle registration failed: %d\n", ret);
+
+ ret = da850_register_pm(&da850_pm_device);
+ if (ret)
+ pr_warning("da850_evm_init: suspend registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init mityomapl138_console_init(void)
+{
+ if (!machine_is_mityomapl138())
+ return 0;
+
+ return add_preferred_console("ttyS", 1, "115200");
+}
+console_initcall(mityomapl138_console_init);
+#endif
+
+static void __init mityomapl138_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = mityomapl138_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = mityomapl138_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c
new file mode 100644
index 00000000..3e7be2de
--- /dev/null
+++ b/arch/arm/mach-davinci/board-neuros-osd2.c
@@ -0,0 +1,280 @@
+/*
+ * Neuros Technologies OSD2 board support
+ *
+ * Modified from original 644X-EVM board support.
+ * 2008 (c) Neuros Technology, LLC.
+ * 2009 (c) Jorge Luis Zapata Muga <jorgeluis.zapata@gmail.com>
+ * 2009 (c) Andrey A. Porodko <Andrey.Porodko@gmail.com>
+ *
+ * The Neuros OSD 2.0 is the hardware component of the Neuros Open
+ * Internet Television Platform. Hardware is very close to TI
+ * DM644X-EVM board. It has:
+ * DM6446M02 module with 256MB NAND, 256MB RAM, TLV320AIC32 AIC,
+ * USB, Ethernet, SD/MMC, UART, THS8200, TVP7000 for video.
+ * Additionally realtime clock, IR remote control receiver,
+ * IR Blaster based on MSP430 (firmware although is different
+ * from used in DM644X-EVM), internal ATA-6 3.5†HDD drive
+ * with PATA interface, two muxed red-green leds.
+ *
+ * For more information please refer to
+ * http://wiki.neurostechnology.com/index.php/OSD_2.0_HD
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/nand.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+
+#define NEUROS_OSD2_PHY_ID "0:01"
+#define LXT971_PHY_ID 0x001378e2
+#define LXT971_PHY_MASK 0xfffffff0
+
+#define NTOSD2_AUDIOSOC_I2C_ADDR 0x18
+#define NTOSD2_MSP430_I2C_ADDR 0x59
+#define NTOSD2_MSP430_IRQ 2
+
+/* Neuros OSD2 has a Samsung 256 MByte NAND flash (Dev ID of 0xAA,
+ * 2048 blocks in the device, 64 pages per block, 2048 bytes per
+ * page.
+ */
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
+ {
+ /* UBL (a few copies) plus U-Boot */
+ .name = "bootloader",
+ .offset = 0,
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ /* U-Boot environment */
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ .mask_flags = 0,
+ }, {
+ /* Kernel */
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ }, {
+ /* File System */
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+ /* A few blocks at end hold a flash Bad Block Table. */
+};
+
+static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
+ .parts = davinci_ntosd2_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+};
+
+static struct resource davinci_ntosd2_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_ntosd2_nandflash_device = {
+ .name = "davinci_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_ntosd2_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_ntosd2_nandflash_resource),
+ .resource = davinci_ntosd2_nandflash_resource,
+};
+
+static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device davinci_fb_device = {
+ .name = "davincifb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &davinci_fb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = 0,
+};
+
+static struct snd_platform_data dm644x_ntosd2_snd_data;
+
+static struct gpio_led ntosd2_leds[] = {
+ { .name = "led1_green", .gpio = GPIO(10), },
+ { .name = "led1_red", .gpio = GPIO(11), },
+ { .name = "led2_green", .gpio = GPIO(12), },
+ { .name = "led2_red", .gpio = GPIO(13), },
+};
+
+static struct gpio_led_platform_data ntosd2_leds_data = {
+ .num_leds = ARRAY_SIZE(ntosd2_leds),
+ .leds = ntosd2_leds,
+};
+
+static struct platform_device ntosd2_leds_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ntosd2_leds_data,
+ },
+};
+
+
+static struct platform_device *davinci_ntosd2_devices[] __initdata = {
+ &davinci_fb_device,
+ &ntosd2_leds_dev,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_ntosd2_map_io(void)
+{
+ dm644x_init();
+}
+
+/*
+ I2C initialization
+*/
+static struct davinci_i2c_platform_data ntosd2_i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+};
+
+static struct i2c_board_info __initdata ntosd2_i2c_info[] = {
+};
+
+static int ntosd2_init_i2c(void)
+{
+ int status;
+
+ davinci_init_i2c(&ntosd2_i2c_pdata);
+ status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type);
+ if (status == 0) {
+ status = gpio_direction_input(NTOSD2_MSP430_IRQ);
+ if (status == 0) {
+ status = gpio_to_irq(NTOSD2_MSP430_IRQ);
+ if (status > 0) {
+ ntosd2_i2c_info[0].irq = status;
+ i2c_register_board_info(1,
+ ntosd2_i2c_info,
+ ARRAY_SIZE(ntosd2_i2c_info));
+ }
+ }
+ }
+ return status;
+}
+
+static struct davinci_mmc_config davinci_ntosd2_mmc_config = {
+ .wires = 4,
+ .version = MMC_CTLR_VERSION_1
+};
+
+
+#if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+ defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+#define HAS_ATA 1
+#else
+#define HAS_ATA 0
+#endif
+
+#if defined(CONFIG_MTD_NAND_DAVINCI) || \
+ defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
+#define HAS_NAND 1
+#else
+#define HAS_NAND 0
+#endif
+
+static __init void davinci_ntosd2_init(void)
+{
+ struct clk *aemif_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ int status;
+
+ aemif_clk = clk_get(NULL, "aemif");
+ clk_enable(aemif_clk);
+
+ if (HAS_ATA) {
+ if (HAS_NAND)
+ pr_warning("WARNING: both IDE and Flash are "
+ "enabled, but they share AEMIF pins.\n"
+ "\tDisable IDE for NAND/NOR support.\n");
+ davinci_init_ide();
+ } else if (HAS_NAND) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN_DISABLE);
+
+ /* only one device will be jumpered and detected */
+ if (HAS_NAND)
+ platform_device_register(
+ &davinci_ntosd2_nandflash_device);
+ }
+
+ platform_add_devices(davinci_ntosd2_devices,
+ ARRAY_SIZE(davinci_ntosd2_devices));
+
+ /* Initialize I2C interface specific for this board */
+ status = ntosd2_init_i2c();
+ if (status < 0)
+ pr_warning("davinci_ntosd2_init: msp430 irq setup failed:"
+ " %d\n", status);
+
+ davinci_serial_init(&uart_config);
+ dm644x_init_asp(&dm644x_ntosd2_snd_data);
+
+ soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID;
+
+ davinci_setup_usb(1000, 8);
+ /*
+ * Mux the pins to be GPIOs, VLYNQEN is already done at startup.
+ * The AEAWx are five new AEAW pins that can be muxed by separately.
+ * They are a bitmask for GPIO management. According TI
+ * documentation (http://www.ti.com/lit/gpn/tms320dm6446) to employ
+ * gpio(10,11,12,13) for leds any combination of bits works except
+ * four last. So we are to reset all five.
+ */
+ davinci_cfg_reg(DM644X_AEAW0);
+ davinci_cfg_reg(DM644X_AEAW1);
+ davinci_cfg_reg(DM644X_AEAW2);
+ davinci_cfg_reg(DM644X_AEAW3);
+ davinci_cfg_reg(DM644X_AEAW4);
+
+ davinci_setup_mmc(0, &davinci_ntosd2_mmc_config);
+}
+
+MACHINE_START(NEUROS_OSD2, "Neuros OSD2")
+ /* Maintainer: Neuros Technologies <neuros@groups.google.com> */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_ntosd2_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_ntosd2_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c
new file mode 100644
index 00000000..67c38d0e
--- /dev/null
+++ b/arch/arm/mach-davinci/board-omapl138-hawk.c
@@ -0,0 +1,346 @@
+/*
+ * Hawkboard.org based on TI's OMAP-L138 Platform
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of
+ * any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/cp_intc.h>
+#include <mach/da8xx.h>
+#include <mach/mux.h>
+
+#define HAWKBOARD_PHY_ID "0:07"
+#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12)
+#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13)
+
+#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4)
+#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13)
+
+static short omapl138_hawk_mii_pins[] __initdata = {
+ DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3,
+ DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER,
+ DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3,
+ DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ -1
+};
+
+static __init void omapl138_hawk_config_emac(void)
+{
+ void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG);
+ int ret;
+ u32 val;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ val = __raw_readl(cfgchip3);
+ val &= ~BIT(8);
+ ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins);
+ if (ret) {
+ pr_warning("%s: cpgmac/mii mux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ /* configure the CFGCHIP3 register for MII */
+ __raw_writel(val, cfgchip3);
+ pr_info("EMAC: MII PHY configured\n");
+
+ soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID;
+
+ ret = da8xx_register_emac();
+ if (ret)
+ pr_warning("%s: emac registration failed: %d\n",
+ __func__, ret);
+}
+
+/*
+ * The following EDMA channels/slots are not being used by drivers (for
+ * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard,
+ * hence they are being reserved for codecs on the DSP side.
+ */
+static const s16 da850_dma0_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma0_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 8, 6},
+ {24, 4},
+ {30, 50},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_chans[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 2},
+ {-1, -1}
+};
+
+static const s16 da850_dma1_rsv_slots[][2] = {
+ /* (offset, number) */
+ { 0, 28},
+ {30, 90},
+ {-1, -1}
+};
+
+static struct edma_rsv_info da850_edma_cc0_rsv = {
+ .rsv_chans = da850_dma0_rsv_chans,
+ .rsv_slots = da850_dma0_rsv_slots,
+};
+
+static struct edma_rsv_info da850_edma_cc1_rsv = {
+ .rsv_chans = da850_dma1_rsv_chans,
+ .rsv_slots = da850_dma1_rsv_slots,
+};
+
+static struct edma_rsv_info *da850_edma_rsv[2] = {
+ &da850_edma_cc0_rsv,
+ &da850_edma_cc1_rsv,
+};
+
+static const short hawk_mmcsd0_pins[] = {
+ DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD,
+ DA850_GPIO3_12, DA850_GPIO3_13,
+ -1
+};
+
+static int da850_hawk_mmc_get_ro(int index)
+{
+ return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN);
+}
+
+static int da850_hawk_mmc_get_cd(int index)
+{
+ return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN);
+}
+
+static struct davinci_mmc_config da850_mmc_config = {
+ .get_ro = da850_hawk_mmc_get_ro,
+ .get_cd = da850_hawk_mmc_get_cd,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_2,
+};
+
+static __init void omapl138_hawk_mmc_init(void)
+{
+ int ret;
+
+ ret = davinci_cfg_reg_list(hawk_mmcsd0_pins);
+ if (ret) {
+ pr_warning("%s: MMC/SD0 mux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN,
+ GPIOF_DIR_IN, "MMC CD");
+ if (ret < 0) {
+ pr_warning("%s: can not open GPIO %d\n",
+ __func__, DA850_HAWK_MMCSD_CD_PIN);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN,
+ GPIOF_DIR_IN, "MMC WP");
+ if (ret < 0) {
+ pr_warning("%s: can not open GPIO %d\n",
+ __func__, DA850_HAWK_MMCSD_WP_PIN);
+ goto mmc_setup_wp_fail;
+ }
+
+ ret = da8xx_register_mmcsd0(&da850_mmc_config);
+ if (ret) {
+ pr_warning("%s: MMC/SD0 registration failed: %d\n",
+ __func__, ret);
+ goto mmc_setup_mmcsd_fail;
+ }
+
+ return;
+
+mmc_setup_mmcsd_fail:
+ gpio_free(DA850_HAWK_MMCSD_WP_PIN);
+mmc_setup_wp_fail:
+ gpio_free(DA850_HAWK_MMCSD_CD_PIN);
+}
+
+static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id);
+static da8xx_ocic_handler_t hawk_usb_ocic_handler;
+
+static const short da850_hawk_usb11_pins[] = {
+ DA850_GPIO2_4, DA850_GPIO6_13,
+ -1
+};
+
+static int hawk_usb_set_power(unsigned port, int on)
+{
+ gpio_set_value(DA850_USB1_VBUS_PIN, on);
+ return 0;
+}
+
+static int hawk_usb_get_power(unsigned port)
+{
+ return gpio_get_value(DA850_USB1_VBUS_PIN);
+}
+
+static int hawk_usb_get_oci(unsigned port)
+{
+ return !gpio_get_value(DA850_USB1_OC_PIN);
+}
+
+static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler)
+{
+ int irq = gpio_to_irq(DA850_USB1_OC_PIN);
+ int error = 0;
+
+ if (handler != NULL) {
+ hawk_usb_ocic_handler = handler;
+
+ error = request_irq(irq, omapl138_hawk_usb_ocic_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "OHCI over-current indicator", NULL);
+ if (error)
+ pr_err("%s: could not request IRQ to watch "
+ "over-current indicator changes\n", __func__);
+ } else {
+ free_irq(irq, NULL);
+ }
+ return error;
+}
+
+static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = {
+ .set_power = hawk_usb_set_power,
+ .get_power = hawk_usb_get_power,
+ .get_oci = hawk_usb_get_oci,
+ .ocic_notify = hawk_usb_ocic_notify,
+ /* TPS2087 switch @ 5V */
+ .potpgt = (3 + 1) / 2, /* 3 ms max */
+};
+
+static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id)
+{
+ hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1);
+ return IRQ_HANDLED;
+}
+
+static __init void omapl138_hawk_usb_init(void)
+{
+ int ret;
+ u32 cfgchip2;
+
+ ret = davinci_cfg_reg_list(da850_hawk_usb11_pins);
+ if (ret) {
+ pr_warning("%s: USB 1.1 PinMux setup failed: %d\n",
+ __func__, ret);
+ return;
+ }
+
+ /* Setup the Ref. clock frequency for the HAWK at 24 MHz. */
+
+ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+ cfgchip2 &= ~CFGCHIP2_REFFREQ;
+ cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ;
+ __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG));
+
+ ret = gpio_request_one(DA850_USB1_VBUS_PIN,
+ GPIOF_DIR_OUT, "USB1 VBUS");
+ if (ret < 0) {
+ pr_err("%s: failed to request GPIO for USB 1.1 port "
+ "power control: %d\n", __func__, ret);
+ return;
+ }
+
+ ret = gpio_request_one(DA850_USB1_OC_PIN,
+ GPIOF_DIR_IN, "USB1 OC");
+ if (ret < 0) {
+ pr_err("%s: failed to request GPIO for USB 1.1 port "
+ "over-current indicator: %d\n", __func__, ret);
+ goto usb11_setup_oc_fail;
+ }
+
+ ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata);
+ if (ret) {
+ pr_warning("%s: USB 1.1 registration failed: %d\n",
+ __func__, ret);
+ goto usb11_setup_fail;
+ }
+
+ return;
+
+usb11_setup_fail:
+ gpio_free(DA850_USB1_OC_PIN);
+usb11_setup_oc_fail:
+ gpio_free(DA850_USB1_VBUS_PIN);
+}
+
+static struct davinci_uart_config omapl138_hawk_uart_config __initdata = {
+ .enabled_uarts = 0x7,
+};
+
+static __init void omapl138_hawk_init(void)
+{
+ int ret;
+
+ davinci_serial_init(&omapl138_hawk_uart_config);
+
+ omapl138_hawk_config_emac();
+
+ ret = da850_register_edma(da850_edma_rsv);
+ if (ret)
+ pr_warning("%s: EDMA registration failed: %d\n",
+ __func__, ret);
+
+ omapl138_hawk_mmc_init();
+
+ omapl138_hawk_usb_init();
+
+ ret = da8xx_register_watchdog();
+ if (ret)
+ pr_warning("omapl138_hawk_init: "
+ "watchdog registration failed: %d\n",
+ ret);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init omapl138_hawk_console_init(void)
+{
+ if (!machine_is_omapl138_hawkboard())
+ return 0;
+
+ return add_preferred_console("ttyS", 2, "115200");
+}
+console_initcall(omapl138_hawk_console_init);
+#endif
+
+static void __init omapl138_hawk_map_io(void)
+{
+ da850_init();
+}
+
+MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard")
+ .boot_params = (DA8XX_DDR_BASE + 0x100),
+ .map_io = omapl138_hawk_map_io,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = omapl138_hawk_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c
new file mode 100644
index 00000000..61ac96d8
--- /dev/null
+++ b/arch/arm/mach-davinci/board-sffsdr.c
@@ -0,0 +1,159 @@
+/*
+ * Lyrtech SFFSDR board support.
+ *
+ * Copyright (C) 2008 Philip Balister, OpenSDR <philip@opensdr.com>
+ * Copyright (C) 2008 Lyrtech <www.lyrtech.com>
+ *
+ * Based on DV-EVM platform, original copyright follows:
+ *
+ * Copyright (C) 2007 MontaVista Software, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <mach/dm644x.h>
+#include <mach/common.h>
+#include <mach/i2c.h>
+#include <mach/serial.h>
+#include <mach/mux.h>
+#include <mach/usb.h>
+
+#define SFFSDR_PHY_ID "0:01"
+static struct mtd_partition davinci_sffsdr_nandflash_partition[] = {
+ /* U-Boot Environment: Block 0
+ * UBL: Block 1
+ * U-Boot: Blocks 6-7 (256 kb)
+ * Integrity Kernel: Blocks 8-31 (3 Mb)
+ * Integrity Data: Blocks 100-END
+ */
+ {
+ .name = "Linux Kernel",
+ .offset = 32 * SZ_128K,
+ .size = 16 * SZ_128K, /* 2 Mb */
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "Linux ROOT",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * SZ_128K, /* 32 Mb */
+ .mask_flags = 0, /* R/W */
+ },
+};
+
+static struct flash_platform_data davinci_sffsdr_nandflash_data = {
+ .parts = davinci_sffsdr_nandflash_partition,
+ .nr_parts = ARRAY_SIZE(davinci_sffsdr_nandflash_partition),
+};
+
+static struct resource davinci_sffsdr_nandflash_resource[] = {
+ {
+ .start = DM644X_ASYNC_EMIF_DATA_CE0_BASE,
+ .end = DM644X_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = DM644X_ASYNC_EMIF_CONTROL_BASE,
+ .end = DM644X_ASYNC_EMIF_CONTROL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device davinci_sffsdr_nandflash_device = {
+ .name = "davinci_nand", /* Name of driver */
+ .id = 0,
+ .dev = {
+ .platform_data = &davinci_sffsdr_nandflash_data,
+ },
+ .num_resources = ARRAY_SIZE(davinci_sffsdr_nandflash_resource),
+ .resource = davinci_sffsdr_nandflash_resource,
+};
+
+static struct at24_platform_data eeprom_info = {
+ .byte_len = (64*1024) / 8,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info __initdata i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24lc64", 0x50),
+ .platform_data = &eeprom_info,
+ },
+ /* Other I2C devices:
+ * MSP430, addr 0x23 (not used)
+ * PCA9543, addr 0x70 (setup done by U-Boot)
+ * ADS7828, addr 0x48 (ADC for voltage monitoring.)
+ */
+};
+
+static struct davinci_i2c_platform_data i2c_pdata = {
+ .bus_freq = 20 /* kHz */,
+ .bus_delay = 100 /* usec */,
+};
+
+static void __init sffsdr_init_i2c(void)
+{
+ davinci_init_i2c(&i2c_pdata);
+ i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+}
+
+static struct platform_device *davinci_sffsdr_devices[] __initdata = {
+ &davinci_sffsdr_nandflash_device,
+};
+
+static struct davinci_uart_config uart_config __initdata = {
+ .enabled_uarts = (1 << 0),
+};
+
+static void __init davinci_sffsdr_map_io(void)
+{
+ dm644x_init();
+}
+
+static __init void davinci_sffsdr_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ platform_add_devices(davinci_sffsdr_devices,
+ ARRAY_SIZE(davinci_sffsdr_devices));
+ sffsdr_init_i2c();
+ davinci_serial_init(&uart_config);
+ soc_info->emac_pdata->phy_id = SFFSDR_PHY_ID;
+ davinci_setup_usb(0, 0); /* We support only peripheral mode. */
+
+ /* mux VLYNQ pins */
+ davinci_cfg_reg(DM644X_VLYNQEN);
+ davinci_cfg_reg(DM644X_VLYNQWD);
+}
+
+MACHINE_START(SFFSDR, "Lyrtech SFFSDR")
+ /* Maintainer: Hugo Villeneuve hugo.villeneuve@lyrtech.com */
+ .boot_params = (DAVINCI_DDR_BASE + 0x100),
+ .map_io = davinci_sffsdr_map_io,
+ .init_irq = davinci_irq_init,
+ .timer = &davinci_timer,
+ .init_machine = davinci_sffsdr_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
new file mode 100644
index 00000000..1a656e88
--- /dev/null
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -0,0 +1,285 @@
+/*
+ * Texas Instruments TNETV107X EVM Board Support
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/mux.h>
+#include <mach/cp_intc.h>
+#include <mach/tnetv107x.h>
+
+#define EVM_MMC_WP_GPIO 21
+#define EVM_MMC_CD_GPIO 24
+#define EVM_SPI_CS_GPIO 54
+
+static int initialize_gpio(int gpio, char *desc)
+{
+ int ret;
+
+ ret = gpio_request(gpio, desc);
+ if (ret < 0) {
+ pr_err_ratelimited("cannot open %s gpio\n", desc);
+ return -ENOSYS;
+ }
+ gpio_direction_input(gpio);
+ return gpio;
+}
+
+static int mmc_get_cd(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_CD_GPIO, "mmc card detect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 0 : 1;
+}
+
+static int mmc_get_ro(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_WP_GPIO, "mmc write protect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 1 : 0;
+}
+
+static struct davinci_mmc_config mmc_config = {
+ .get_cd = mmc_get_cd,
+ .get_ro = mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_1,
+};
+
+static const short sdio1_pins[] __initdata = {
+ TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1,
+ TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1,
+ TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1,
+ TNETV107X_GPIO21, TNETV107X_GPIO24,
+ -1
+};
+
+static const short uart1_pins[] __initdata = {
+ TNETV107X_UART1_RD, TNETV107X_UART1_TD,
+ -1
+};
+
+static const short ssp_pins[] __initdata = {
+ TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2,
+ TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2,
+ TNETV107X_SSP1_3, -1
+};
+
+static struct mtd_partition nand_partitions[] = {
+ /* bootloader (U-Boot, etc) in first 12 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = (12*SZ_128K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+static struct davinci_nand_pdata nand_config = {
+ .mask_cle = 0x4000,
+ .mask_ale = 0x2000,
+ .parts = nand_partitions,
+ .nr_parts = ARRAY_SIZE(nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 1,
+};
+
+static struct davinci_uart_config serial_config __initconst = {
+ .enabled_uarts = BIT(1),
+};
+
+static const uint32_t keymap[] = {
+ KEY(0, 0, KEY_NUMERIC_1),
+ KEY(0, 1, KEY_NUMERIC_2),
+ KEY(0, 2, KEY_NUMERIC_3),
+ KEY(0, 3, KEY_FN_F1),
+ KEY(0, 4, KEY_MENU),
+
+ KEY(1, 0, KEY_NUMERIC_4),
+ KEY(1, 1, KEY_NUMERIC_5),
+ KEY(1, 2, KEY_NUMERIC_6),
+ KEY(1, 3, KEY_UP),
+ KEY(1, 4, KEY_FN_F2),
+
+ KEY(2, 0, KEY_NUMERIC_7),
+ KEY(2, 1, KEY_NUMERIC_8),
+ KEY(2, 2, KEY_NUMERIC_9),
+ KEY(2, 3, KEY_LEFT),
+ KEY(2, 4, KEY_ENTER),
+
+ KEY(3, 0, KEY_NUMERIC_STAR),
+ KEY(3, 1, KEY_NUMERIC_0),
+ KEY(3, 2, KEY_NUMERIC_POUND),
+ KEY(3, 3, KEY_DOWN),
+ KEY(3, 4, KEY_RIGHT),
+
+ KEY(4, 0, KEY_FN_F3),
+ KEY(4, 1, KEY_FN_F4),
+ KEY(4, 2, KEY_MUTE),
+ KEY(4, 3, KEY_HOME),
+ KEY(4, 4, KEY_BACK),
+
+ KEY(5, 0, KEY_VOLUMEDOWN),
+ KEY(5, 1, KEY_VOLUMEUP),
+ KEY(5, 2, KEY_F1),
+ KEY(5, 3, KEY_F2),
+ KEY(5, 4, KEY_F3),
+};
+
+static const struct matrix_keymap_data keymap_data = {
+ .keymap = keymap,
+ .keymap_size = ARRAY_SIZE(keymap),
+};
+
+static struct matrix_keypad_platform_data keypad_config = {
+ .keymap_data = &keymap_data,
+ .num_row_gpios = 6,
+ .num_col_gpios = 5,
+ .debounce_ms = 0, /* minimum */
+ .active_low = 0, /* pull up realization */
+ .no_autorepeat = 0,
+};
+
+static void spi_select_device(int cs)
+{
+ static int gpio;
+
+ if (!gpio) {
+ int ret;
+ ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel");
+ if (ret < 0) {
+ pr_err("cannot open spi chipsel gpio\n");
+ gpio = -ENOSYS;
+ return;
+ } else {
+ gpio = EVM_SPI_CS_GPIO;
+ gpio_direction_output(gpio, 0);
+ }
+ }
+
+ if (gpio < 0)
+ return;
+
+ return gpio_set_value(gpio, cs ? 1 : 0);
+}
+
+static struct ti_ssp_spi_data spi_master_data = {
+ .num_cs = 2,
+ .select = spi_select_device,
+ .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | SSP_PIN_SEL(1, SSP_DATA) |
+ SSP_PIN_SEL(2, SSP_CHIPSEL) | SSP_PIN_SEL(3, SSP_IN) |
+ SSP_INPUT_SEL(3),
+};
+
+static struct ti_ssp_data ssp_config = {
+ .out_clock = 250 * 1000,
+ .dev_data = {
+ [1] = {
+ .dev_name = "ti-ssp-spi",
+ .pdata = &spi_master_data,
+ .pdata_size = sizeof(spi_master_data),
+ },
+ },
+};
+
+static struct tnetv107x_device_info evm_device_info __initconst = {
+ .serial_config = &serial_config,
+ .mmc_config[1] = &mmc_config, /* controller 1 */
+ .nand_config[0] = &nand_config, /* chip select 0 */
+ .keypad_config = &keypad_config,
+ .ssp_config = &ssp_config,
+};
+
+static struct spi_board_info spi_info[] __initconst = {
+};
+
+static __init void tnetv107x_evm_board_init(void)
+{
+ davinci_cfg_reg_list(sdio1_pins);
+ davinci_cfg_reg_list(uart1_pins);
+ davinci_cfg_reg_list(ssp_pins);
+
+ tnetv107x_devices_init(&evm_device_info);
+
+ spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init tnetv107x_evm_console_init(void)
+{
+ return add_preferred_console("ttyS", 0, "115200");
+}
+console_initcall(tnetv107x_evm_console_init);
+#endif
+
+MACHINE_START(TNETV107X, "TNETV107X EVM")
+ .boot_params = (TNETV107X_DDR_BASE + 0x100),
+ .map_io = tnetv107x_init,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = tnetv107x_evm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c
new file mode 100644
index 00000000..ba8b12b2
--- /dev/null
+++ b/arch/arm/mach-davinci/cdce949.c
@@ -0,0 +1,294 @@
+/*
+ * TI CDCE949 clock synthesizer driver
+ *
+ * Note: This implementation assumes an input of 27MHz to the CDCE.
+ * This is by no means constrained by CDCE hardware although the datasheet
+ * does use this as an example for all illustrations and more importantly:
+ * that is the crystal input on boards it is currently used on.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <mach/clock.h>
+#include <mach/cdce949.h>
+
+#include "clock.h"
+
+static struct i2c_client *cdce_i2c_client;
+static DEFINE_MUTEX(cdce_mutex);
+
+/* CDCE register descriptor */
+struct cdce_reg {
+ u8 addr;
+ u8 val;
+};
+
+/* Per-Output (Y1, Y2 etc.) frequency descriptor */
+struct cdce_freq {
+ /* Frequency in KHz */
+ unsigned long frequency;
+ /*
+ * List of registers to program to obtain a particular frequency.
+ * 0x0 in register address and value is the end of list marker.
+ */
+ struct cdce_reg *reglist;
+};
+
+#define CDCE_FREQ_TABLE_ENTRY(line, out) \
+{ \
+ .reglist = cdce_y ##line## _ ##out, \
+ .frequency = out, \
+}
+
+/* List of CDCE outputs */
+struct cdce_output {
+ /* List of frequencies on this output */
+ struct cdce_freq *freq_table;
+ /* Number of possible frequencies */
+ int size;
+};
+
+/*
+ * Finding out the values to program into CDCE949 registers for a particular
+ * frequency output is not a simple calculation. Have a look at the datasheet
+ * for the details. There is desktop software available to help users with
+ * the calculations. Here, we just depend on the output of that software
+ * (or hand calculations) instead trying to runtime calculate the register
+ * values and inflicting misery on ourselves.
+ */
+static struct cdce_reg cdce_y1_148500[] = {
+ { 0x13, 0x00 },
+ /* program PLL1_0 multiplier */
+ { 0x18, 0xaf },
+ { 0x19, 0x50 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0xc9 },
+ /* program PLL1_11 multiplier */
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0xc9 },
+ /* output state selection */
+ { 0x15, 0x00 },
+ { 0x14, 0xef },
+ /* switch MUX to PLL1 output */
+ { 0x14, 0x6f },
+ { 0x16, 0x06 },
+ /* set P2DIV divider, P3DIV and input crystal */
+ { 0x17, 0x06 },
+ { 0x01, 0x00 },
+ { 0x05, 0x48 },
+ { 0x02, 0x80 },
+ /* enable and disable PLL */
+ { 0x02, 0xbc },
+ { 0x03, 0x01 },
+ { },
+};
+
+static struct cdce_reg cdce_y1_74250[] = {
+ { 0x13, 0x00 },
+ { 0x18, 0xaf },
+ { 0x19, 0x50 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0xc9 },
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0xc9 },
+ /* output state selection */
+ { 0x15, 0x00 },
+ { 0x14, 0xef },
+ /* switch MUX to PLL1 output */
+ { 0x14, 0x6f },
+ { 0x16, 0x06 },
+ /* set P2DIV divider, P3DIV and input crystal */
+ { 0x17, 0x06 },
+ { 0x01, 0x00 },
+ { 0x05, 0x48 },
+ { 0x02, 0x80 },
+ /* enable and disable PLL */
+ { 0x02, 0xbc },
+ { 0x03, 0x02 },
+ { },
+};
+
+static struct cdce_reg cdce_y1_27000[] = {
+ { 0x13, 0x00 },
+ { 0x18, 0x00 },
+ { 0x19, 0x40 },
+ { 0x1a, 0x02 },
+ { 0x1b, 0x08 },
+ { 0x1c, 0x00 },
+ { 0x1d, 0x40 },
+ { 0x1e, 0x02 },
+ { 0x1f, 0x08 },
+ { 0x15, 0x02 },
+ { 0x14, 0xed },
+ { 0x16, 0x01 },
+ { 0x17, 0x01 },
+ { 0x01, 0x00 },
+ { 0x05, 0x50 },
+ { 0x02, 0xb4 },
+ { 0x03, 0x01 },
+ { },
+};
+
+static struct cdce_freq cdce_y1_freqs[] = {
+ CDCE_FREQ_TABLE_ENTRY(1, 148500),
+ CDCE_FREQ_TABLE_ENTRY(1, 74250),
+ CDCE_FREQ_TABLE_ENTRY(1, 27000),
+};
+
+static struct cdce_reg cdce_y5_13500[] = {
+ { 0x27, 0x08 },
+ { 0x28, 0x00 },
+ { 0x29, 0x40 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x08 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_16875[] = {
+ { 0x27, 0x08 },
+ { 0x28, 0x9f },
+ { 0x29, 0xb0 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x89 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_27000[] = {
+ { 0x27, 0x04 },
+ { 0x28, 0x00 },
+ { 0x29, 0x40 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x08 },
+ { 0x24, 0x6f },
+ { },
+};
+static struct cdce_reg cdce_y5_54000[] = {
+ { 0x27, 0x04 },
+ { 0x28, 0xff },
+ { 0x29, 0x80 },
+ { 0x2a, 0x02 },
+ { 0x2b, 0x07 },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_reg cdce_y5_81000[] = {
+ { 0x27, 0x02 },
+ { 0x28, 0xbf },
+ { 0x29, 0xa0 },
+ { 0x2a, 0x03 },
+ { 0x2b, 0x0a },
+ { 0x24, 0x6f },
+ { },
+};
+
+static struct cdce_freq cdce_y5_freqs[] = {
+ CDCE_FREQ_TABLE_ENTRY(5, 13500),
+ CDCE_FREQ_TABLE_ENTRY(5, 16875),
+ CDCE_FREQ_TABLE_ENTRY(5, 27000),
+ CDCE_FREQ_TABLE_ENTRY(5, 54000),
+ CDCE_FREQ_TABLE_ENTRY(5, 81000),
+};
+
+
+static struct cdce_output output_list[] = {
+ [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
+ [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
+};
+
+int cdce_set_rate(struct clk *clk, unsigned long rate)
+{
+ int i, ret = 0;
+ struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
+ struct cdce_reg *regs = NULL;
+
+ if (!cdce_i2c_client)
+ return -ENODEV;
+
+ if (!freq_table)
+ return -EINVAL;
+
+ for (i = 0; i < output_list[clk->lpsc].size; i++) {
+ if (freq_table[i].frequency == rate / 1000) {
+ regs = freq_table[i].reglist;
+ break;
+ }
+ }
+
+ if (!regs)
+ return -EINVAL;
+
+ mutex_lock(&cdce_mutex);
+ for (i = 0; regs[i].addr; i++) {
+ ret = i2c_smbus_write_byte_data(cdce_i2c_client,
+ regs[i].addr | 0x80, regs[i].val);
+ if (ret)
+ break;
+ }
+ mutex_unlock(&cdce_mutex);
+
+ if (!ret)
+ clk->rate = rate;
+
+ return ret;
+}
+
+static int cdce_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ cdce_i2c_client = client;
+ return 0;
+}
+
+static int __devexit cdce_remove(struct i2c_client *client)
+{
+ cdce_i2c_client = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id cdce_id[] = {
+ {"cdce949", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, cdce_id);
+
+static struct i2c_driver cdce_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "cdce949",
+ },
+ .probe = cdce_probe,
+ .remove = __devexit_p(cdce_remove),
+ .id_table = cdce_id,
+};
+
+static int __init cdce_init(void)
+{
+ return i2c_add_driver(&cdce_driver);
+}
+subsys_initcall(cdce_init);
+
+static void __exit cdce_exit(void)
+{
+ i2c_del_driver(&cdce_driver);
+}
+module_exit(cdce_exit);
+
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c
new file mode 100644
index 00000000..e4e3af17
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.c
@@ -0,0 +1,641 @@
+/*
+ * Clock and PLL control for DaVinci devices
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+
+#include <mach/clock.h>
+#include <mach/psc.h>
+#include <mach/cputype.h>
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static unsigned psc_domain(struct clk *clk)
+{
+ return (clk->flags & PSC_DSP)
+ ? DAVINCI_GPSC_DSPDOMAIN
+ : DAVINCI_GPSC_ARMDOMAIN;
+}
+
+static void __clk_enable(struct clk *clk)
+{
+ if (clk->parent)
+ __clk_enable(clk->parent);
+ if (clk->usecount++ == 0 && (clk->flags & CLK_PSC))
+ davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+ PSC_STATE_ENABLE);
+}
+
+static void __clk_disable(struct clk *clk)
+{
+ if (WARN_ON(clk->usecount == 0))
+ return;
+ if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) &&
+ (clk->flags & CLK_PSC))
+ davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc,
+ (clk->flags & PSC_SWRSTDISABLE) ?
+ PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Propagate rate to children */
+static void propagate_rate(struct clk *root)
+{
+ struct clk *clk;
+
+ list_for_each_entry(clk, &root->children, childnode) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ if (clk->set_rate)
+ ret = clk->set_rate(clk, rate);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (ret == 0) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ /* Cannot change parent on enabled clock */
+ if (WARN_ON(clk->usecount))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ clk->parent = parent;
+ list_del_init(&clk->childnode);
+ list_add(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+int clk_register(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (WARN(clk->parent && !clk->parent->rate,
+ "CLK: %s parent %s has no rate!\n",
+ clk->name, clk->parent->name))
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&clk->children);
+
+ mutex_lock(&clocks_mutex);
+ list_add_tail(&clk->node, &clocks);
+ if (clk->parent)
+ list_add_tail(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ /* If rate is already set, use it */
+ if (clk->rate)
+ return 0;
+
+ /* Else, see if there is a way to calculate it */
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ /* Otherwise, default to parent rate */
+ else if (clk->parent)
+ clk->rate = clk->parent->rate;
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ list_del(&clk->node);
+ list_del(&clk->childnode);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+#ifdef CONFIG_DAVINCI_RESET_CLOCKS
+/*
+ * Disable any unused clocks left on by the bootloader
+ */
+static int __init clk_disable_unused(void)
+{
+ struct clk *ck;
+
+ spin_lock_irq(&clockfw_lock);
+ list_for_each_entry(ck, &clocks, node) {
+ if (ck->usecount > 0)
+ continue;
+ if (!(ck->flags & CLK_PSC))
+ continue;
+
+ /* ignore if in Disabled or SwRstDisable states */
+ if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc))
+ continue;
+
+ pr_debug("Clocks: disable unused %s\n", ck->name);
+
+ davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc,
+ (ck->flags & PSC_SWRSTDISABLE) ?
+ PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE);
+ }
+ spin_unlock_irq(&clockfw_lock);
+
+ return 0;
+}
+late_initcall(clk_disable_unused);
+#endif
+
+static unsigned long clk_sysclk_recalc(struct clk *clk)
+{
+ u32 v, plldiv;
+ struct pll_data *pll;
+ unsigned long rate = clk->rate;
+
+ /* If this is the PLL base clock, no more calculations needed */
+ if (clk->pll_data)
+ return rate;
+
+ if (WARN_ON(!clk->parent))
+ return rate;
+
+ rate = clk->parent->rate;
+
+ /* Otherwise, the parent must be a PLL */
+ if (WARN_ON(!clk->parent->pll_data))
+ return rate;
+
+ pll = clk->parent->pll_data;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ rate = pll->input_rate;
+
+ if (!clk->div_reg)
+ return rate;
+
+ v = __raw_readl(pll->base + clk->div_reg);
+ if (v & PLLDIV_EN) {
+ plldiv = (v & pll->div_ratio_mask) + 1;
+ if (plldiv)
+ rate /= plldiv;
+ }
+
+ return rate;
+}
+
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned v;
+ struct pll_data *pll;
+ unsigned long input;
+ unsigned ratio = 0;
+
+ /* If this is the PLL base clock, wrong function to call */
+ if (clk->pll_data)
+ return -EINVAL;
+
+ /* There must be a parent... */
+ if (WARN_ON(!clk->parent))
+ return -EINVAL;
+
+ /* ... the parent must be a PLL... */
+ if (WARN_ON(!clk->parent->pll_data))
+ return -EINVAL;
+
+ /* ... and this clock must have a divider. */
+ if (WARN_ON(!clk->div_reg))
+ return -EINVAL;
+
+ pll = clk->parent->pll_data;
+
+ input = clk->parent->rate;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ input = pll->input_rate;
+
+ if (input > rate) {
+ /*
+ * Can afford to provide an output little higher than requested
+ * only if maximum rate supported by hardware on this sysclk
+ * is known.
+ */
+ if (clk->maxrate) {
+ ratio = DIV_ROUND_CLOSEST(input, rate);
+ if (input / ratio > clk->maxrate)
+ ratio = 0;
+ }
+
+ if (ratio == 0)
+ ratio = DIV_ROUND_UP(input, rate);
+
+ ratio--;
+ }
+
+ if (ratio > pll->div_ratio_mask)
+ return -EINVAL;
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ v = __raw_readl(pll->base + clk->div_reg);
+ v &= ~pll->div_ratio_mask;
+ v |= ratio | PLLDIV_EN;
+ __raw_writel(v, pll->base + clk->div_reg);
+
+ v = __raw_readl(pll->base + PLLCMD);
+ v |= PLLCMD_GOSET;
+ __raw_writel(v, pll->base + PLLCMD);
+
+ do {
+ v = __raw_readl(pll->base + PLLSTAT);
+ } while (v & PLLSTAT_GOSTAT);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_set_sysclk_rate);
+
+static unsigned long clk_leafclk_recalc(struct clk *clk)
+{
+ if (WARN_ON(!clk->parent))
+ return clk->rate;
+
+ return clk->parent->rate;
+}
+
+static unsigned long clk_pllclk_recalc(struct clk *clk)
+{
+ u32 ctrl, mult = 1, prediv = 1, postdiv = 1;
+ u8 bypass;
+ struct pll_data *pll = clk->pll_data;
+ unsigned long rate = clk->rate;
+
+ ctrl = __raw_readl(pll->base + PLLCTL);
+ rate = pll->input_rate = clk->parent->rate;
+
+ if (ctrl & PLLCTL_PLLEN) {
+ bypass = 0;
+ mult = __raw_readl(pll->base + PLLM);
+ if (cpu_is_davinci_dm365())
+ mult = 2 * (mult & PLLM_PLLM_MASK);
+ else
+ mult = (mult & PLLM_PLLM_MASK) + 1;
+ } else
+ bypass = 1;
+
+ if (pll->flags & PLL_HAS_PREDIV) {
+ prediv = __raw_readl(pll->base + PREDIV);
+ if (prediv & PLLDIV_EN)
+ prediv = (prediv & pll->div_ratio_mask) + 1;
+ else
+ prediv = 1;
+ }
+
+ /* pre-divider is fixed, but (some?) chips won't report that */
+ if (cpu_is_davinci_dm355() && pll->num == 1)
+ prediv = 8;
+
+ if (pll->flags & PLL_HAS_POSTDIV) {
+ postdiv = __raw_readl(pll->base + POSTDIV);
+ if (postdiv & PLLDIV_EN)
+ postdiv = (postdiv & pll->div_ratio_mask) + 1;
+ else
+ postdiv = 1;
+ }
+
+ if (!bypass) {
+ rate /= prediv;
+ rate *= mult;
+ rate /= postdiv;
+ }
+
+ pr_debug("PLL%d: input = %lu MHz [ ",
+ pll->num, clk->parent->rate / 1000000);
+ if (bypass)
+ pr_debug("bypass ");
+ if (prediv > 1)
+ pr_debug("/ %d ", prediv);
+ if (mult > 1)
+ pr_debug("* %d ", mult);
+ if (postdiv > 1)
+ pr_debug("/ %d ", postdiv);
+ pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+ return rate;
+}
+
+/**
+ * davinci_set_pllrate - set the output rate of a given PLL.
+ *
+ * Note: Currently tested to work with OMAP-L138 only.
+ *
+ * @pll: pll whose rate needs to be changed.
+ * @prediv: The pre divider value. Passing 0 disables the pre-divider.
+ * @pllm: The multiplier value. Passing 0 leads to multiply-by-one.
+ * @postdiv: The post divider value. Passing 0 disables the post-divider.
+ */
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+ unsigned int mult, unsigned int postdiv)
+{
+ u32 ctrl;
+ unsigned int locktime;
+ unsigned long flags;
+
+ if (pll->base == NULL)
+ return -EINVAL;
+
+ /*
+ * PLL lock time required per OMAP-L138 datasheet is
+ * (2000 * prediv)/sqrt(pllm) OSCIN cycles. We approximate sqrt(pllm)
+ * as 4 and OSCIN cycle as 25 MHz.
+ */
+ if (prediv) {
+ locktime = ((2000 * prediv) / 100);
+ prediv = (prediv - 1) | PLLDIV_EN;
+ } else {
+ locktime = PLL_LOCK_TIME;
+ }
+ if (postdiv)
+ postdiv = (postdiv - 1) | PLLDIV_EN;
+ if (mult)
+ mult = mult - 1;
+
+ /* Protect against simultaneous calls to PLL setting seqeunce */
+ spin_lock_irqsave(&clockfw_lock, flags);
+
+ ctrl = __raw_readl(pll->base + PLLCTL);
+
+ /* Switch the PLL to bypass mode */
+ ctrl &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ udelay(PLL_BYPASS_TIME);
+
+ /* Reset and enable PLL */
+ ctrl &= ~(PLLCTL_PLLRST | PLLCTL_PLLDIS);
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ if (pll->flags & PLL_HAS_PREDIV)
+ __raw_writel(prediv, pll->base + PREDIV);
+
+ __raw_writel(mult, pll->base + PLLM);
+
+ if (pll->flags & PLL_HAS_POSTDIV)
+ __raw_writel(postdiv, pll->base + POSTDIV);
+
+ udelay(PLL_RESET_TIME);
+
+ /* Bring PLL out of reset */
+ ctrl |= PLLCTL_PLLRST;
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ udelay(locktime);
+
+ /* Remove PLL from bypass mode */
+ ctrl |= PLLCTL_PLLEN;
+ __raw_writel(ctrl, pll->base + PLLCTL);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_set_pllrate);
+
+int __init davinci_clk_init(struct clk_lookup *clocks)
+ {
+ struct clk_lookup *c;
+ struct clk *clk;
+ size_t num_clocks = 0;
+
+ for (c = clocks; c->clk; c++) {
+ clk = c->clk;
+
+ if (!clk->recalc) {
+
+ /* Check if clock is a PLL */
+ if (clk->pll_data)
+ clk->recalc = clk_pllclk_recalc;
+
+ /* Else, if it is a PLL-derived clock */
+ else if (clk->flags & CLK_PLL)
+ clk->recalc = clk_sysclk_recalc;
+
+ /* Otherwise, it is a leaf clock (PSC clock) */
+ else if (clk->parent)
+ clk->recalc = clk_leafclk_recalc;
+ }
+
+ if (clk->pll_data) {
+ struct pll_data *pll = clk->pll_data;
+
+ if (!pll->div_ratio_mask)
+ pll->div_ratio_mask = PLLDIV_RATIO_MASK;
+
+ if (pll->phys_base && !pll->base) {
+ pll->base = ioremap(pll->phys_base, SZ_4K);
+ WARN_ON(!pll->base);
+ }
+ }
+
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ if (clk->lpsc)
+ clk->flags |= CLK_PSC;
+
+ clk_register(clk);
+ num_clocks++;
+
+ /* Turn on clocks that Linux doesn't otherwise manage */
+ if (clk->flags & ALWAYS_ENABLED)
+ clk_enable(clk);
+ }
+
+ clkdev_add_table(clocks, num_clocks);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define CLKNAME_MAX 10 /* longest clock name */
+#define NEST_DELTA 2
+#define NEST_MAX 4
+
+static void
+dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
+{
+ char *state;
+ char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
+ struct clk *clk;
+ unsigned i;
+
+ if (parent->flags & CLK_PLL)
+ state = "pll";
+ else if (parent->flags & CLK_PSC)
+ state = "psc";
+ else
+ state = "";
+
+ /* <nest spaces> name <pad to end> */
+ memset(buf, ' ', sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = 0;
+ i = strlen(parent->name);
+ memcpy(buf + nest, parent->name,
+ min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+ seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
+ buf, parent->usecount, state, clk_get_rate(parent));
+ /* REVISIT show device associations too */
+
+ /* cost is now small, but not linear... */
+ list_for_each_entry(clk, &parent->children, childnode) {
+ dump_clock(s, nest + NEST_DELTA, clk);
+ }
+}
+
+static int davinci_ck_show(struct seq_file *m, void *v)
+{
+ struct clk *clk;
+
+ /*
+ * Show clock tree; We trust nonzero usecounts equate to PSC enables...
+ */
+ mutex_lock(&clocks_mutex);
+ list_for_each_entry(clk, &clocks, node)
+ if (!clk->parent)
+ dump_clock(m, 0, clk);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+
+static int davinci_ck_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, davinci_ck_show, NULL);
+}
+
+static const struct file_operations davinci_ck_operations = {
+ .open = davinci_ck_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init davinci_clk_debugfs_init(void)
+{
+ debugfs_create_file("davinci_clocks", S_IFREG | S_IRUGO, NULL, NULL,
+ &davinci_ck_operations);
+ return 0;
+
+}
+device_initcall(davinci_clk_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h
new file mode 100644
index 00000000..0dd22031
--- /dev/null
+++ b/arch/arm/mach-davinci/clock.h
@@ -0,0 +1,132 @@
+/*
+ * TI DaVinci clock definitions
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can 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_DAVINCI_CLOCK_H
+#define __ARCH_ARM_DAVINCI_CLOCK_H
+
+#define DAVINCI_PLL1_BASE 0x01c40800
+#define DAVINCI_PLL2_BASE 0x01c40c00
+#define MAX_PLL 2
+
+/* PLL/Reset register offsets */
+#define PLLCTL 0x100
+#define PLLCTL_PLLEN BIT(0)
+#define PLLCTL_PLLPWRDN BIT(1)
+#define PLLCTL_PLLRST BIT(3)
+#define PLLCTL_PLLDIS BIT(4)
+#define PLLCTL_PLLENSRC BIT(5)
+#define PLLCTL_CLKMODE BIT(8)
+
+#define PLLM 0x110
+#define PLLM_PLLM_MASK 0xff
+
+#define PREDIV 0x114
+#define PLLDIV1 0x118
+#define PLLDIV2 0x11c
+#define PLLDIV3 0x120
+#define POSTDIV 0x128
+#define BPDIV 0x12c
+#define PLLCMD 0x138
+#define PLLSTAT 0x13c
+#define PLLALNCTL 0x140
+#define PLLDCHANGE 0x144
+#define PLLCKEN 0x148
+#define PLLCKSTAT 0x14c
+#define PLLSYSTAT 0x150
+#define PLLDIV4 0x160
+#define PLLDIV5 0x164
+#define PLLDIV6 0x168
+#define PLLDIV7 0x16c
+#define PLLDIV8 0x170
+#define PLLDIV9 0x174
+#define PLLDIV_EN BIT(15)
+#define PLLDIV_RATIO_MASK 0x1f
+
+/*
+ * OMAP-L138 system reference guide recommends a wait for 4 OSCIN/CLKIN
+ * cycles to ensure that the PLLC has switched to bypass mode. Delay of 1us
+ * ensures we are good for all > 4MHz OSCIN/CLKIN inputs. Typically the input
+ * is ~25MHz. Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+/* From OMAP-L138 datasheet table 6-4. Units are micro seconds */
+#define PLL_RESET_TIME 1
+/*
+ * From OMAP-L138 datasheet table 6-4; assuming prediv = 1, sqrt(pllm) = 4
+ * Units are micro seconds.
+ */
+#define PLL_LOCK_TIME 20
+
+#ifndef __ASSEMBLER__
+
+#include <linux/list.h>
+#include <linux/clkdev.h>
+
+#define PLLSTAT_GOSTAT BIT(0)
+#define PLLCMD_GOSET BIT(0)
+
+struct pll_data {
+ u32 phys_base;
+ void __iomem *base;
+ u32 num;
+ u32 flags;
+ u32 input_rate;
+ u32 div_ratio_mask;
+};
+#define PLL_HAS_PREDIV 0x01
+#define PLL_HAS_POSTDIV 0x02
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ unsigned long rate;
+ unsigned long maxrate; /* H/W supported max rate */
+ u8 usecount;
+ u8 lpsc;
+ u8 gpsc;
+ u32 flags;
+ struct clk *parent;
+ struct list_head children; /* list of children */
+ struct list_head childnode; /* parent's child list node */
+ struct pll_data *pll_data;
+ u32 div_reg;
+ unsigned long (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *clk, unsigned long rate);
+ int (*round_rate) (struct clk *clk, unsigned long rate);
+};
+
+/* Clock flags: SoC-specific flags start at BIT(16) */
+#define ALWAYS_ENABLED BIT(1)
+#define CLK_PSC BIT(2)
+#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */
+#define CLK_PLL BIT(4) /* PLL-derived clock */
+#define PRE_PLL BIT(5) /* source is before PLL mult/div */
+#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ } \
+
+int davinci_clk_init(struct clk_lookup *clocks);
+int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
+ unsigned int mult, unsigned int postdiv);
+int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
+
+extern struct platform_device davinci_wdt_device;
+extern void davinci_watchdog_reset(struct platform_device *);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-davinci/common.c b/arch/arm/mach-davinci/common.c
new file mode 100644
index 00000000..1d255739
--- /dev/null
+++ b/arch/arm/mach-davinci/common.c
@@ -0,0 +1,119 @@
+/*
+ * Code commons to all DaVinci SoCs.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/etherdevice.h>
+#include <linux/davinci_emac.h>
+
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/cputype.h>
+
+#include "clock.h"
+
+struct davinci_soc_info davinci_soc_info;
+EXPORT_SYMBOL(davinci_soc_info);
+
+void __iomem *davinci_intc_base;
+int davinci_intc_type;
+
+void davinci_get_mac_addr(struct memory_accessor *mem_acc, void *context)
+{
+ char *mac_addr = davinci_soc_info.emac_pdata->mac_addr;
+ off_t offset = (off_t)context;
+
+ /* Read MAC addr from EEPROM */
+ if (mem_acc->read(mem_acc, mac_addr, offset, ETH_ALEN) == ETH_ALEN)
+ pr_info("Read MAC addr from EEPROM: %pM\n", mac_addr);
+}
+
+static int __init davinci_init_id(struct davinci_soc_info *soc_info)
+{
+ int i;
+ struct davinci_id *dip;
+ u8 variant;
+ u16 part_no;
+ void __iomem *base;
+
+ base = ioremap(soc_info->jtag_id_reg, SZ_4K);
+ if (!base) {
+ pr_err("Unable to map JTAG ID register\n");
+ return -ENOMEM;
+ }
+
+ soc_info->jtag_id = __raw_readl(base);
+ iounmap(base);
+
+ variant = (soc_info->jtag_id & 0xf0000000) >> 28;
+ part_no = (soc_info->jtag_id & 0x0ffff000) >> 12;
+
+ for (i = 0, dip = soc_info->ids; i < soc_info->ids_num;
+ i++, dip++)
+ /* Don't care about the manufacturer right now */
+ if ((dip->part_no == part_no) && (dip->variant == variant)) {
+ soc_info->cpu_id = dip->cpu_id;
+ pr_info("DaVinci %s variant 0x%x\n", dip->name,
+ dip->variant);
+ return 0;
+ }
+
+ pr_err("Unknown DaVinci JTAG ID 0x%x\n", soc_info->jtag_id);
+ return -EINVAL;
+}
+
+void __init davinci_common_init(struct davinci_soc_info *soc_info)
+{
+ int ret;
+
+ if (!soc_info) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ memcpy(&davinci_soc_info, soc_info, sizeof(struct davinci_soc_info));
+
+ if (davinci_soc_info.io_desc && (davinci_soc_info.io_desc_num > 0))
+ iotable_init(davinci_soc_info.io_desc,
+ davinci_soc_info.io_desc_num);
+
+ /*
+ * Normally devicemaps_init() would flush caches and tlb after
+ * mdesc->map_io(), but we must also do it here because of the CPU
+ * revision check below.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ if (!davinci_soc_info.reset)
+ davinci_soc_info.reset = davinci_watchdog_reset;
+
+ /*
+ * We want to check CPU revision early for cpu_is_xxxx() macros.
+ * IO space mapping must be initialized before we can do that.
+ */
+ ret = davinci_init_id(&davinci_soc_info);
+ if (ret < 0)
+ goto err;
+
+ if (davinci_soc_info.cpu_clks) {
+ ret = davinci_clk_init(davinci_soc_info.cpu_clks);
+
+ if (ret != 0)
+ goto err;
+ }
+
+ return;
+
+err:
+ panic("davinci_common_init: SoC Initialization failed\n");
+}
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
new file mode 100644
index 00000000..f83152d6
--- /dev/null
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -0,0 +1,177 @@
+/*
+ * TI Common Platform Interrupt Controller (cp_intc) driver
+ *
+ * Author: Steve Chen <schen@mvista.com>
+ * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/common.h>
+#include <mach/cp_intc.h>
+
+static inline unsigned int cp_intc_read(unsigned offset)
+{
+ return __raw_readl(davinci_intc_base + offset);
+}
+
+static inline void cp_intc_write(unsigned long value, unsigned offset)
+{
+ __raw_writel(value, davinci_intc_base + offset);
+}
+
+static void cp_intc_ack_irq(struct irq_data *d)
+{
+ cp_intc_write(d->irq, CP_INTC_SYS_STAT_IDX_CLR);
+}
+
+/* Disable interrupt */
+static void cp_intc_mask_irq(struct irq_data *d)
+{
+ /* XXX don't know why we need to disable nIRQ here... */
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_CLR);
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_CLR);
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET);
+}
+
+/* Enable interrupt */
+static void cp_intc_unmask_irq(struct irq_data *d)
+{
+ cp_intc_write(d->irq, CP_INTC_SYS_ENABLE_IDX_SET);
+}
+
+static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned reg = BIT_WORD(d->irq);
+ unsigned mask = BIT_MASK(d->irq);
+ unsigned polarity = cp_intc_read(CP_INTC_SYS_POLARITY(reg));
+ unsigned type = cp_intc_read(CP_INTC_SYS_TYPE(reg));
+
+ switch (flow_type) {
+ case IRQ_TYPE_EDGE_RISING:
+ polarity |= mask;
+ type |= mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ polarity &= ~mask;
+ type |= mask;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ polarity |= mask;
+ type &= ~mask;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ polarity &= ~mask;
+ type &= ~mask;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ cp_intc_write(polarity, CP_INTC_SYS_POLARITY(reg));
+ cp_intc_write(type, CP_INTC_SYS_TYPE(reg));
+
+ return 0;
+}
+
+/*
+ * Faking this allows us to to work with suspend functions of
+ * generic drivers which call {enable|disable}_irq_wake for
+ * wake up interrupt sources (eg RTC on DA850).
+ */
+static int cp_intc_set_wake(struct irq_data *d, unsigned int on)
+{
+ return 0;
+}
+
+static struct irq_chip cp_intc_irq_chip = {
+ .name = "cp_intc",
+ .irq_ack = cp_intc_ack_irq,
+ .irq_mask = cp_intc_mask_irq,
+ .irq_unmask = cp_intc_unmask_irq,
+ .irq_set_type = cp_intc_set_irq_type,
+ .irq_set_wake = cp_intc_set_wake,
+};
+
+void __init cp_intc_init(void)
+{
+ unsigned long num_irq = davinci_soc_info.intc_irq_num;
+ u8 *irq_prio = davinci_soc_info.intc_irq_prios;
+ u32 *host_map = davinci_soc_info.intc_host_map;
+ unsigned num_reg = BITS_TO_LONGS(num_irq);
+ int i;
+
+ davinci_intc_type = DAVINCI_INTC_TYPE_CP_INTC;
+ davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_8K);
+ if (WARN_ON(!davinci_intc_base))
+ return;
+
+ cp_intc_write(0, CP_INTC_GLOBAL_ENABLE);
+
+ /* Disable all host interrupts */
+ cp_intc_write(0, CP_INTC_HOST_ENABLE(0));
+
+ /* Disable system interrupts */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(~0, CP_INTC_SYS_ENABLE_CLR(i));
+
+ /* Set to normal mode, no nesting, no priority hold */
+ cp_intc_write(0, CP_INTC_CTRL);
+ cp_intc_write(0, CP_INTC_HOST_CTRL);
+
+ /* Clear system interrupt status */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(~0, CP_INTC_SYS_STAT_CLR(i));
+
+ /* Enable nIRQ (what about nFIQ?) */
+ cp_intc_write(1, CP_INTC_HOST_ENABLE_IDX_SET);
+
+ /*
+ * Priority is determined by host channel: lower channel number has
+ * higher priority i.e. channel 0 has highest priority and channel 31
+ * had the lowest priority.
+ */
+ num_reg = (num_irq + 3) >> 2; /* 4 channels per register */
+ if (irq_prio) {
+ unsigned j, k;
+ u32 val;
+
+ for (k = i = 0; i < num_reg; i++) {
+ for (val = j = 0; j < 4; j++, k++) {
+ val >>= 8;
+ if (k < num_irq)
+ val |= irq_prio[k] << 24;
+ }
+
+ cp_intc_write(val, CP_INTC_CHAN_MAP(i));
+ }
+ } else {
+ /*
+ * Default everything to channel 15 if priority not specified.
+ * Note that channel 0-1 are mapped to nFIQ and channels 2-31
+ * are mapped to nIRQ.
+ */
+ for (i = 0; i < num_reg; i++)
+ cp_intc_write(0x0f0f0f0f, CP_INTC_CHAN_MAP(i));
+ }
+
+ if (host_map)
+ for (i = 0; host_map[i] != -1; i++)
+ cp_intc_write(host_map[i], CP_INTC_HOST_MAP(i));
+
+ /* Set up genirq dispatching for cp_intc */
+ for (i = 0; i < num_irq; i++) {
+ irq_set_chip(i, &cp_intc_irq_chip);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ irq_set_handler(i, handle_edge_irq);
+ }
+
+ /* Enable global interrupt */
+ cp_intc_write(1, CP_INTC_GLOBAL_ENABLE);
+}
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
new file mode 100644
index 00000000..41669ecc
--- /dev/null
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -0,0 +1,248 @@
+/*
+ * CPU frequency scaling for DaVinci
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows:
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <mach/cpufreq.h>
+#include <mach/common.h>
+
+#include "clock.h"
+
+struct davinci_cpufreq {
+ struct device *dev;
+ struct clk *armclk;
+ struct clk *asyncclk;
+ unsigned long asyncrate;
+};
+static struct davinci_cpufreq cpufreq;
+
+static int davinci_verify_speed(struct cpufreq_policy *policy)
+{
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+ struct clk *armclk = cpufreq.armclk;
+
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int davinci_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpufreq.armclk) / 1000;
+}
+
+static int davinci_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ int ret = 0;
+ unsigned int idx;
+ struct cpufreq_freqs freqs;
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct clk *armclk = cpufreq.armclk;
+
+ /*
+ * Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum.
+ */
+ if (target_freq < policy->cpuinfo.min_freq)
+ target_freq = policy->cpuinfo.min_freq;
+ if (target_freq > policy->cpuinfo.max_freq)
+ target_freq = policy->cpuinfo.max_freq;
+
+ freqs.old = davinci_getspeed(0);
+ freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
+
+ ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
+ freqs.new, relation, &idx);
+ if (ret)
+ return -EINVAL;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* if moving to higher frequency, up the voltage beforehand */
+ if (pdata->set_voltage && freqs.new > freqs.old) {
+ ret = pdata->set_voltage(idx);
+ if (ret)
+ goto out;
+ }
+
+ ret = clk_set_rate(armclk, idx);
+ if (ret)
+ goto out;
+
+ if (cpufreq.asyncclk) {
+ ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate);
+ if (ret)
+ goto out;
+ }
+
+ /* if moving to lower freq, lower the voltage after lowering freq */
+ if (pdata->set_voltage && freqs.new < freqs.old)
+ pdata->set_voltage(idx);
+
+out:
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int davinci_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+ struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
+ struct cpufreq_frequency_table *freq_table = pdata->freq_table;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ /* Finish platform specific initialization */
+ if (pdata->init) {
+ result = pdata->init();
+ if (result)
+ return result;
+ }
+
+ policy->cur = policy->min = policy->max = davinci_getspeed(0);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = policy->min;
+ policy->cpuinfo.max_freq = policy->max;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = davinci_getspeed(0);
+
+ /*
+ * Time measurement across the target() function yields ~1500-1800us
+ * time taken with no drivers on notification list.
+ * Setting the latency to 2000 us to accommodate addition of drivers
+ * to pre/post change notification list.
+ */
+ policy->cpuinfo.transition_latency = 2000 * 1000;
+ return 0;
+}
+
+static int davinci_cpu_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ return 0;
+}
+
+static struct freq_attr *davinci_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver davinci_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = davinci_verify_speed,
+ .target = davinci_target,
+ .get = davinci_getspeed,
+ .init = davinci_cpu_init,
+ .exit = davinci_cpu_exit,
+ .name = "davinci",
+ .attr = davinci_cpufreq_attr,
+};
+
+static int __init davinci_cpufreq_probe(struct platform_device *pdev)
+{
+ struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
+ struct clk *asyncclk;
+
+ if (!pdata)
+ return -EINVAL;
+ if (!pdata->freq_table)
+ return -EINVAL;
+
+ cpufreq.dev = &pdev->dev;
+
+ cpufreq.armclk = clk_get(NULL, "arm");
+ if (IS_ERR(cpufreq.armclk)) {
+ dev_err(cpufreq.dev, "Unable to get ARM clock\n");
+ return PTR_ERR(cpufreq.armclk);
+ }
+
+ asyncclk = clk_get(cpufreq.dev, "async");
+ if (!IS_ERR(asyncclk)) {
+ cpufreq.asyncclk = asyncclk;
+ cpufreq.asyncrate = clk_get_rate(asyncclk);
+ }
+
+ return cpufreq_register_driver(&davinci_driver);
+}
+
+static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
+{
+ clk_put(cpufreq.armclk);
+
+ if (cpufreq.asyncclk)
+ clk_put(cpufreq.asyncclk);
+
+ return cpufreq_unregister_driver(&davinci_driver);
+}
+
+static struct platform_driver davinci_cpufreq_driver = {
+ .driver = {
+ .name = "cpufreq-davinci",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(davinci_cpufreq_remove),
+};
+
+static int __init davinci_cpufreq_init(void)
+{
+ return platform_driver_probe(&davinci_cpufreq_driver,
+ davinci_cpufreq_probe);
+}
+late_initcall(davinci_cpufreq_init);
+
diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c
new file mode 100644
index 00000000..bd59f31b
--- /dev/null
+++ b/arch/arm/mach-davinci/cpuidle.c
@@ -0,0 +1,169 @@
+/*
+ * CPU idle for DaVinci SoCs
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * Derived from Marvell Kirkwood CPU idle code
+ * (arch/arm/mach-kirkwood/cpuidle.c)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#include <mach/cpuidle.h>
+#include <mach/memory.h>
+
+#define DAVINCI_CPUIDLE_MAX_STATES 2
+
+struct davinci_ops {
+ void (*enter) (u32 flags);
+ void (*exit) (u32 flags);
+ u32 flags;
+};
+
+/* fields in davinci_ops.flags */
+#define DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN BIT(0)
+
+static struct cpuidle_driver davinci_idle_driver = {
+ .name = "cpuidle-davinci",
+ .owner = THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, davinci_cpuidle_device);
+static void __iomem *ddr2_reg_base;
+
+static void davinci_save_ddr_power(int enter, bool pdown)
+{
+ u32 val;
+
+ val = __raw_readl(ddr2_reg_base + DDR2_SDRCR_OFFSET);
+
+ if (enter) {
+ if (pdown)
+ val |= DDR2_SRPD_BIT;
+ else
+ val &= ~DDR2_SRPD_BIT;
+ val |= DDR2_LPMODEN_BIT;
+ } else {
+ val &= ~(DDR2_SRPD_BIT | DDR2_LPMODEN_BIT);
+ }
+
+ __raw_writel(val, ddr2_reg_base + DDR2_SDRCR_OFFSET);
+}
+
+static void davinci_c2state_enter(u32 flags)
+{
+ davinci_save_ddr_power(1, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static void davinci_c2state_exit(u32 flags)
+{
+ davinci_save_ddr_power(0, !!(flags & DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN));
+}
+
+static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {
+ [1] = {
+ .enter = davinci_c2state_enter,
+ .exit = davinci_c2state_exit,
+ },
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int davinci_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct davinci_ops *ops = cpuidle_get_statedata(state);
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ if (ops && ops->enter)
+ ops->enter(ops->flags);
+ /* Wait for interrupt state */
+ cpu_do_idle();
+ if (ops && ops->exit)
+ ops->exit(ops->flags);
+
+ 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 davinci_cpuidle_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct cpuidle_device *device;
+ struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;
+
+ device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "cannot get platform data\n");
+ return -ENOENT;
+ }
+
+ ddr2_reg_base = pdata->ddr2_ctlr_base;
+
+ ret = cpuidle_register_driver(&davinci_idle_driver);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register driver\n");
+ return ret;
+ }
+
+ /* Wait for interrupt state */
+ device->states[0].enter = davinci_enter_idle;
+ device->states[0].exit_latency = 1;
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "WFI");
+ strcpy(device->states[0].desc, "Wait for interrupt");
+
+ /* Wait for interrupt and DDR self refresh state */
+ device->states[1].enter = davinci_enter_idle;
+ device->states[1].exit_latency = 10;
+ device->states[1].target_residency = 10000;
+ device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[1].name, "DDR SR");
+ strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+ if (pdata->ddr2_pdown)
+ davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
+ cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
+
+ device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
+
+ ret = cpuidle_register_device(device);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register device\n");
+ cpuidle_unregister_driver(&davinci_idle_driver);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct platform_driver davinci_cpuidle_driver = {
+ .driver = {
+ .name = "cpuidle-davinci",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init davinci_cpuidle_init(void)
+{
+ return platform_driver_probe(&davinci_cpuidle_driver,
+ davinci_cpuidle_probe);
+}
+device_initcall(davinci_cpuidle_init);
+
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
new file mode 100644
index 00000000..2ed2f822
--- /dev/null
+++ b/arch/arm/mach-davinci/da830.c
@@ -0,0 +1,1212 @@
+/*
+ * TI DA830/OMAP L137 chip specific setup
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/psc.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/gpio.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Offsets of the 8 compare registers on the da830 */
+#define DA830_CMP12_0 0x60
+#define DA830_CMP12_1 0x64
+#define DA830_CMP12_2 0x68
+#define DA830_CMP12_3 0x6c
+#define DA830_CMP12_4 0x70
+#define DA830_CMP12_5 0x74
+#define DA830_CMP12_6 0x78
+#define DA830_CMP12_7 0x7c
+
+#define DA830_REF_FREQ 24000000
+
+static struct pll_data pll0_data = {
+ .num = 1,
+ .phys_base = DA8XX_PLL0_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DA830_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+ .name = "pll0",
+ .parent = &ref_clk,
+ .pll_data = &pll0_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll0_aux_clk = {
+ .name = "pll0_aux_clk",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+ .name = "pll0_sysclk2",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+ .name = "pll0_sysclk3",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll0_sysclk4 = {
+ .name = "pll0_sysclk4",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+ .name = "pll0_sysclk5",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+ .name = "pll0_sysclk7",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+ .name = "i2c0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+ .name = "timer0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+ .name = "timer1",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+ .name = "arm_rom",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr0_ss_clk = {
+ .name = "scr0_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR0_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr1_ss_clk = {
+ .name = "scr1_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR1_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk scr2_ss_clk = {
+ .name = "scr2_ss",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SCR2_SS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk dmax_clk = {
+ .name = "dmax",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_PRUSS,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc_clk = {
+ .name = "tpcc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPCC,
+ .flags = ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+ .name = "tptc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+ .name = "tptc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk mmcsd_clk = {
+ .name = "mmcsd",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART1,
+ .gpsc = 1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART2,
+ .gpsc = 1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SPI0,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_SPI1,
+ .gpsc = 1,
+};
+
+static struct clk ecap0_clk = {
+ .name = "ecap0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk ecap1_clk = {
+ .name = "ecap1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk ecap2_clk = {
+ .name = "ecap2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_ECAP,
+ .gpsc = 1,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_PWM,
+ .gpsc = 1,
+};
+
+static struct clk eqep0_clk = {
+ .name = "eqep0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_EQEP,
+ .gpsc = 1,
+};
+
+static struct clk eqep1_clk = {
+ .name = "eqep1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_EQEP,
+ .gpsc = 1,
+};
+
+static struct clk lcdc_clk = {
+ .name = "lcdc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_LCDC,
+ .gpsc = 1,
+};
+
+static struct clk mcasp0_clk = {
+ .name = "mcasp0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_McASP0,
+ .gpsc = 1,
+};
+
+static struct clk mcasp1_clk = {
+ .name = "mcasp1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_McASP1,
+ .gpsc = 1,
+};
+
+static struct clk mcasp2_clk = {
+ .name = "mcasp2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA830_LPSC1_McASP2,
+ .gpsc = 1,
+};
+
+static struct clk usb20_clk = {
+ .name = "usb20",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_USB20,
+ .gpsc = 1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll0_sysclk3,
+ .lpsc = DA8XX_LPSC0_EMIF25,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk aintc_clk = {
+ .name = "aintc",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_AINTC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk secu_mgr_clk = {
+ .name = "secu_mgr",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_SECU_MGR,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_CPGMAC,
+ .gpsc = 1,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_GPIO,
+ .gpsc = 1,
+};
+
+static struct clk i2c1_clk = {
+ .name = "i2c1",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_I2C,
+ .gpsc = 1,
+};
+
+static struct clk usb11_clk = {
+ .name = "usb11",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_USB11,
+ .gpsc = 1,
+};
+
+static struct clk emif3_clk = {
+ .name = "emif3",
+ .parent = &pll0_sysclk5,
+ .lpsc = DA8XX_LPSC1_EMIF3C,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll0_sysclk6,
+ .lpsc = DA8XX_LPSC0_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk rmii_clk = {
+ .name = "rmii",
+ .parent = &pll0_sysclk7,
+};
+
+static struct clk_lookup da830_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll0", &pll0_clk),
+ CLK(NULL, "pll0_aux", &pll0_aux_clk),
+ CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
+ CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
+ CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
+ CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
+ CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
+ CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
+ CLK("i2c_davinci.1", NULL, &i2c0_clk),
+ CLK(NULL, "timer0", &timerp64_0_clk),
+ CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK(NULL, "arm_rom", &arm_rom_clk),
+ CLK(NULL, "scr0_ss", &scr0_ss_clk),
+ CLK(NULL, "scr1_ss", &scr1_ss_clk),
+ CLK(NULL, "scr2_ss", &scr2_ss_clk),
+ CLK(NULL, "dmax", &dmax_clk),
+ CLK(NULL, "tpcc", &tpcc_clk),
+ CLK(NULL, "tptc0", &tptc0_clk),
+ CLK(NULL, "tptc1", &tptc1_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK(NULL, "ecap0", &ecap0_clk),
+ CLK(NULL, "ecap1", &ecap1_clk),
+ CLK(NULL, "ecap2", &ecap2_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK("eqep.0", NULL, &eqep0_clk),
+ CLK("eqep.1", NULL, &eqep1_clk),
+ CLK("da8xx_lcdc.0", NULL, &lcdc_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+ CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
+ CLK("davinci-mcasp.2", NULL, &mcasp2_clk),
+ CLK(NULL, "usb20", &usb20_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "aintc", &aintc_clk),
+ CLK(NULL, "secu_mgr", &secu_mgr_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("i2c_davinci.2", NULL, &i2c1_clk),
+ CLK(NULL, "usb11", &usb11_clk),
+ CLK(NULL, "emif3", &emif3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "rmii", &rmii_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config da830_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ MUX_CFG(DA830, GPIO7_14, 0, 0, 0xf, 1, false)
+ MUX_CFG(DA830, RTCK, 0, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_15, 0, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMU_0, 0, 4, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_SDCKE, 0, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_CLK_GLUE, 0, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_CLK, 0, 12, 0xf, 2, false)
+ MUX_CFG(DA830, NEMB_CS_0, 0, 16, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_CAS, 0, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_RAS, 0, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE, 0, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_BA_1, 1, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_BA_0, 1, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_0, 1, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_1, 1, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_2, 1, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_3, 1, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_4, 1, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_5, 1, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO7_0, 1, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_1, 1, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_2, 1, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_3, 1, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_4, 1, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_5, 1, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_6, 1, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_7, 1, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_A_6, 2, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_7, 2, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_8, 2, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_9, 2, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_10, 2, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_11, 2, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_A_12, 2, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_31, 2, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO7_8, 2, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_9, 2, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_10, 2, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_11, 2, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_12, 2, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO7_13, 2, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_13, 2, 24, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_30, 3, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_29, 3, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_28, 3, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_27, 3, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_26, 3, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_25, 3, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_24, 3, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_23, 3, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_22, 4, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_21, 4, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_20, 4, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_19, 4, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_18, 4, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_17, 4, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_16, 4, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_3, 4, 28, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_2, 5, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_0, 5, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_1, 5, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_2, 5, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_3, 5, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_4, 5, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_5, 5, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_6, 5, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO6_0, 5, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_1, 5, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_2, 5, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_3, 5, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_4, 5, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_5, 5, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_6, 5, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_7, 6, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_8, 6, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_9, 6, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_10, 6, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_11, 6, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_12, 6, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_13, 6, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMB_D_14, 6, 28, 0xf, 1, false)
+ MUX_CFG(DA830, GPIO6_7, 6, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_8, 6, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_9, 6, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_10, 6, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_11, 6, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_12, 6, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_13, 6, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO6_14, 6, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMB_D_15, 7, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_1, 7, 4, 0xf, 1, false)
+ MUX_CFG(DA830, NEMB_WE_DQM_0, 7, 8, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_SOMI_0, 7, 12, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_SIMO_0, 7, 16, 0xf, 1, false)
+ MUX_CFG(DA830, SPI0_CLK, 7, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI0_ENA, 7, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI0_SCS_0, 7, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EQEP0I, 7, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP0S, 7, 16, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1I, 7, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NUART0_CTS, 7, 24, 0xf, 2, false)
+ MUX_CFG(DA830, NUART0_RTS, 7, 28, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP0A, 7, 24, 0xf, 4, false)
+ MUX_CFG(DA830, EQEP0B, 7, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO6_15, 7, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_14, 7, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_15, 7, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_0, 7, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_1, 7, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_2, 7, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_3, 7, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_4, 7, 28, 0xf, 8, false)
+ MUX_CFG(DA830, SPI1_SOMI_0, 8, 0, 0xf, 1, false)
+ MUX_CFG(DA830, SPI1_SIMO_0, 8, 4, 0xf, 1, false)
+ MUX_CFG(DA830, SPI1_CLK, 8, 8, 0xf, 1, false)
+ MUX_CFG(DA830, UART0_RXD, 8, 12, 0xf, 1, false)
+ MUX_CFG(DA830, UART0_TXD, 8, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_10, 8, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_11, 8, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NSPI1_ENA, 8, 28, 0xf, 1, false)
+ MUX_CFG(DA830, I2C1_SCL, 8, 0, 0xf, 2, false)
+ MUX_CFG(DA830, I2C1_SDA, 8, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1S, 8, 8, 0xf, 2, false)
+ MUX_CFG(DA830, I2C0_SDA, 8, 12, 0xf, 2, false)
+ MUX_CFG(DA830, I2C0_SCL, 8, 16, 0xf, 2, false)
+ MUX_CFG(DA830, UART2_RXD, 8, 28, 0xf, 2, false)
+ MUX_CFG(DA830, TM64P0_IN12, 8, 12, 0xf, 4, false)
+ MUX_CFG(DA830, TM64P0_OUT12, 8, 16, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO5_5, 8, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_6, 8, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_7, 8, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_8, 8, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_9, 8, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_10, 8, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_11, 8, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO5_12, 8, 28, 0xf, 8, false)
+ MUX_CFG(DA830, NSPI1_SCS_0, 9, 0, 0xf, 1, false)
+ MUX_CFG(DA830, USB0_DRVVBUS, 9, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKX0, 9, 8, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKX0, 9, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AFSX0, 9, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKR0, 9, 20, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKR0, 9, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AFSR0, 9, 28, 0xf, 1, false)
+ MUX_CFG(DA830, UART2_TXD, 9, 0, 0xf, 2, false)
+ MUX_CFG(DA830, AHCLKX2, 9, 8, 0xf, 2, false)
+ MUX_CFG(DA830, ECAP0_APWM0, 9, 12, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_MHZ_50_CLK, 9, 20, 0xf, 2, false)
+ MUX_CFG(DA830, ECAP1_APWM1, 9, 24, 0xf, 2, false)
+ MUX_CFG(DA830, USB_REFCLKIN, 9, 8, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO5_13, 9, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_15, 9, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_11, 9, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_12, 9, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_13, 9, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_14, 9, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_15, 9, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_12, 9, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AMUTE0, 10, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_0, 10, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_1, 10, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_2, 10, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_3, 10, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_4, 10, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_5, 10, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_6, 10, 28, 0xf, 1, false)
+ MUX_CFG(DA830, RMII_TXD_0, 10, 4, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_TXD_1, 10, 8, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_TXEN, 10, 12, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_CRS_DV, 10, 16, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXD_0, 10, 20, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXD_1, 10, 24, 0xf, 2, false)
+ MUX_CFG(DA830, RMII_RXER, 10, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AFSR2, 10, 4, 0xf, 4, false)
+ MUX_CFG(DA830, ACLKX2, 10, 8, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_3, 10, 12, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_2, 10, 16, 0xf, 4, false)
+ MUX_CFG(DA830, AXR2_1, 10, 20, 0xf, 4, false)
+ MUX_CFG(DA830, AFSX2, 10, 24, 0xf, 4, false)
+ MUX_CFG(DA830, ACLKR2, 10, 28, 0xf, 4, false)
+ MUX_CFG(DA830, NRESETOUT, 10, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_0, 10, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_1, 10, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_2, 10, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_3, 10, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_4, 10, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_5, 10, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_6, 10, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AXR0_7, 11, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_8, 11, 4, 0xf, 1, false)
+ MUX_CFG(DA830, UART1_RXD, 11, 8, 0xf, 1, false)
+ MUX_CFG(DA830, UART1_TXD, 11, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR0_11, 11, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AHCLKX1, 11, 20, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKX1, 11, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AFSX1, 11, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MDIO_CLK, 11, 0, 0xf, 2, false)
+ MUX_CFG(DA830, MDIO_D, 11, 4, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_9, 11, 8, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_10, 11, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM0B, 11, 20, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM0A, 11, 24, 0xf, 2, false)
+ MUX_CFG(DA830, EPWMSYNCI, 11, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AXR2_0, 11, 16, 0xf, 4, false)
+ MUX_CFG(DA830, EPWMSYNC0, 11, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO3_7, 11, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_8, 11, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_9, 11, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_10, 11, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_11, 11, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_14, 11, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO3_15, 11, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_10, 11, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AHCLKR1, 12, 0, 0xf, 1, false)
+ MUX_CFG(DA830, ACLKR1, 12, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AFSR1, 12, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AMUTE1, 12, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_0, 12, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_1, 12, 20, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_2, 12, 24, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_3, 12, 28, 0xf, 1, false)
+ MUX_CFG(DA830, ECAP2_APWM2, 12, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EHRPWMGLUETZ, 12, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EQEP1A, 12, 28, 0xf, 2, false)
+ MUX_CFG(DA830, GPIO4_11, 12, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_12, 12, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_13, 12, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_14, 12, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_0, 12, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_1, 12, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_2, 12, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_3, 12, 28, 0xf, 8, false)
+ MUX_CFG(DA830, AXR1_4, 13, 0, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_5, 13, 4, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_6, 13, 8, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_7, 13, 12, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_8, 13, 16, 0xf, 1, false)
+ MUX_CFG(DA830, AXR1_9, 13, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_0, 13, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_1, 13, 28, 0xf, 1, false)
+ MUX_CFG(DA830, EQEP1B, 13, 0, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM2B, 13, 4, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM2A, 13, 8, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM1B, 13, 12, 0xf, 2, false)
+ MUX_CFG(DA830, EPWM1A, 13, 16, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_0, 13, 24, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_1, 13, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_0, 13, 24, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_1, 13, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO4_4, 13, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_5, 13, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_6, 13, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_7, 13, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_8, 13, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO4_9, 13, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_0, 13, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_1, 13, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_D_2, 14, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_3, 14, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_4, 14, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_5, 14, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_6, 14, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_7, 14, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_8, 14, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_9, 14, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MMCSD_DAT_2, 14, 0, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_3, 14, 4, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_4, 14, 8, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_5, 14, 12, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_6, 14, 16, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_DAT_7, 14, 20, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_8, 14, 24, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_9, 14, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_2, 14, 0, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_3, 14, 4, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_4, 14, 8, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_5, 14, 12, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_6, 14, 16, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HD_7, 14, 20, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_8, 14, 24, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_9, 14, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO0_2, 14, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_3, 14, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_4, 14, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_5, 14, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_6, 14, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_7, 14, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_8, 14, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_9, 14, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_D_10, 15, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_11, 15, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_12, 15, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_13, 15, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_14, 15, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_D_15, 15, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_0, 15, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_1, 15, 28, 0xf, 1, false)
+ MUX_CFG(DA830, UHPI_HD_10, 15, 0, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_11, 15, 4, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_12, 15, 8, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_13, 15, 12, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_14, 15, 16, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HD_15, 15, 20, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_7, 15, 24, 0xf, 2, false)
+ MUX_CFG(DA830, MMCSD_CLK, 15, 28, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_10, 15, 0, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_11, 15, 4, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_12, 15, 8, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_13, 15, 12, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_14, 15, 16, 0xf, 4, false)
+ MUX_CFG(DA830, LCD_D_15, 15, 20, 0xf, 4, false)
+ MUX_CFG(DA830, UHPI_HCNTL0, 15, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO0_10, 15, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_11, 15, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_12, 15, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_13, 15, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_14, 15, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO0_15, 15, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_0, 15, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_1, 15, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_A_2, 16, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_3, 16, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_4, 16, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_5, 16, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_6, 16, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_7, 16, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_8, 16, 24, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_9, 16, 28, 0xf, 1, false)
+ MUX_CFG(DA830, MMCSD_CMD, 16, 0, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_6, 16, 4, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_3, 16, 8, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_2, 16, 12, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_1, 16, 16, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_0, 16, 20, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_PCLK, 16, 24, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_HSYNC, 16, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HCNTL1, 16, 0, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO1_2, 16, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_3, 16, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_4, 16, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_5, 16, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_6, 16, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_7, 16, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_8, 16, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_9, 16, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_A_10, 17, 0, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_11, 17, 4, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_A_12, 17, 8, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_BA_1, 17, 12, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_BA_0, 17, 16, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_CLK, 17, 20, 0xf, 1, false)
+ MUX_CFG(DA830, EMA_SDCKE, 17, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CAS, 17, 28, 0xf, 1, false)
+ MUX_CFG(DA830, LCD_VSYNC, 17, 0, 0xf, 2, false)
+ MUX_CFG(DA830, NLCD_AC_ENB_CS, 17, 4, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_MCLK, 17, 8, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_5, 17, 12, 0xf, 2, false)
+ MUX_CFG(DA830, LCD_D_4, 17, 16, 0xf, 2, false)
+ MUX_CFG(DA830, OBSCLK, 17, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NEMA_CS_4, 17, 28, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HHWIL, 17, 12, 0xf, 4, false)
+ MUX_CFG(DA830, AHCLKR2, 17, 20, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO1_10, 17, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_11, 17, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_12, 17, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_13, 17, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_14, 17, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO1_15, 17, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_0, 17, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_1, 17, 28, 0xf, 8, false)
+ MUX_CFG(DA830, NEMA_RAS, 18, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE, 18, 4, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_0, 18, 8, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_2, 18, 12, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_3, 18, 16, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_OE, 18, 20, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE_DQM_1, 18, 24, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_WE_DQM_0, 18, 28, 0xf, 1, false)
+ MUX_CFG(DA830, NEMA_CS_5, 18, 0, 0xf, 2, false)
+ MUX_CFG(DA830, UHPI_HRNW, 18, 4, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HAS, 18, 8, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HCS, 18, 12, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HDS1, 18, 20, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HDS2, 18, 24, 0xf, 2, false)
+ MUX_CFG(DA830, NUHPI_HINT, 18, 28, 0xf, 2, false)
+ MUX_CFG(DA830, AXR0_12, 18, 4, 0xf, 4, false)
+ MUX_CFG(DA830, AMUTE2, 18, 16, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_13, 18, 20, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_14, 18, 24, 0xf, 4, false)
+ MUX_CFG(DA830, AXR0_15, 18, 28, 0xf, 4, false)
+ MUX_CFG(DA830, GPIO2_2, 18, 0, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_3, 18, 4, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_4, 18, 8, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_5, 18, 12, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_6, 18, 16, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_7, 18, 20, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_8, 18, 24, 0xf, 8, false)
+ MUX_CFG(DA830, GPIO2_9, 18, 28, 0xf, 8, false)
+ MUX_CFG(DA830, EMA_WAIT_0, 19, 0, 0xf, 1, false)
+ MUX_CFG(DA830, NUHPI_HRDY, 19, 0, 0xf, 2, false)
+ MUX_CFG(DA830, GPIO2_10, 19, 0, 0xf, 8, false)
+#endif
+};
+
+const short da830_emif25_pins[] __initdata = {
+ DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3,
+ DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7,
+ DA830_EMA_D_8, DA830_EMA_D_9, DA830_EMA_D_10, DA830_EMA_D_11,
+ DA830_EMA_D_12, DA830_EMA_D_13, DA830_EMA_D_14, DA830_EMA_D_15,
+ DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3,
+ DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7,
+ DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11,
+ DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_EMA_CLK,
+ DA830_EMA_SDCKE, DA830_NEMA_CS_4, DA830_NEMA_CS_5, DA830_NEMA_WE,
+ DA830_NEMA_CS_0, DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE,
+ DA830_NEMA_WE_DQM_1, DA830_NEMA_WE_DQM_0, DA830_EMA_WAIT_0,
+ -1
+};
+
+const short da830_spi0_pins[] __initdata = {
+ DA830_SPI0_SOMI_0, DA830_SPI0_SIMO_0, DA830_SPI0_CLK, DA830_NSPI0_ENA,
+ DA830_NSPI0_SCS_0,
+ -1
+};
+
+const short da830_spi1_pins[] __initdata = {
+ DA830_SPI1_SOMI_0, DA830_SPI1_SIMO_0, DA830_SPI1_CLK, DA830_NSPI1_ENA,
+ DA830_NSPI1_SCS_0,
+ -1
+};
+
+const short da830_mmc_sd_pins[] __initdata = {
+ DA830_MMCSD_DAT_0, DA830_MMCSD_DAT_1, DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3, DA830_MMCSD_DAT_4, DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6, DA830_MMCSD_DAT_7, DA830_MMCSD_CLK,
+ DA830_MMCSD_CMD,
+ -1
+};
+
+const short da830_uart0_pins[] __initdata = {
+ DA830_NUART0_CTS, DA830_NUART0_RTS, DA830_UART0_RXD, DA830_UART0_TXD,
+ -1
+};
+
+const short da830_uart1_pins[] __initdata = {
+ DA830_UART1_RXD, DA830_UART1_TXD,
+ -1
+};
+
+const short da830_uart2_pins[] __initdata = {
+ DA830_UART2_RXD, DA830_UART2_TXD,
+ -1
+};
+
+const short da830_usb20_pins[] __initdata = {
+ DA830_USB0_DRVVBUS, DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_usb11_pins[] __initdata = {
+ DA830_USB_REFCLKIN,
+ -1
+};
+
+const short da830_uhpi_pins[] __initdata = {
+ DA830_UHPI_HD_0, DA830_UHPI_HD_1, DA830_UHPI_HD_2, DA830_UHPI_HD_3,
+ DA830_UHPI_HD_4, DA830_UHPI_HD_5, DA830_UHPI_HD_6, DA830_UHPI_HD_7,
+ DA830_UHPI_HD_8, DA830_UHPI_HD_9, DA830_UHPI_HD_10, DA830_UHPI_HD_11,
+ DA830_UHPI_HD_12, DA830_UHPI_HD_13, DA830_UHPI_HD_14, DA830_UHPI_HD_15,
+ DA830_UHPI_HCNTL0, DA830_UHPI_HCNTL1, DA830_UHPI_HHWIL, DA830_UHPI_HRNW,
+ DA830_NUHPI_HAS, DA830_NUHPI_HCS, DA830_NUHPI_HDS1, DA830_NUHPI_HDS2,
+ DA830_NUHPI_HINT, DA830_NUHPI_HRDY,
+ -1
+};
+
+const short da830_cpgmac_pins[] __initdata = {
+ DA830_RMII_TXD_0, DA830_RMII_TXD_1, DA830_RMII_TXEN, DA830_RMII_CRS_DV,
+ DA830_RMII_RXD_0, DA830_RMII_RXD_1, DA830_RMII_RXER, DA830_MDIO_CLK,
+ DA830_MDIO_D,
+ -1
+};
+
+const short da830_emif3c_pins[] __initdata = {
+ DA830_EMB_SDCKE, DA830_EMB_CLK_GLUE, DA830_EMB_CLK, DA830_NEMB_CS_0,
+ DA830_NEMB_CAS, DA830_NEMB_RAS, DA830_NEMB_WE, DA830_EMB_BA_1,
+ DA830_EMB_BA_0, DA830_EMB_A_0, DA830_EMB_A_1, DA830_EMB_A_2,
+ DA830_EMB_A_3, DA830_EMB_A_4, DA830_EMB_A_5, DA830_EMB_A_6,
+ DA830_EMB_A_7, DA830_EMB_A_8, DA830_EMB_A_9, DA830_EMB_A_10,
+ DA830_EMB_A_11, DA830_EMB_A_12, DA830_NEMB_WE_DQM_3,
+ DA830_NEMB_WE_DQM_2, DA830_EMB_D_0, DA830_EMB_D_1, DA830_EMB_D_2,
+ DA830_EMB_D_3, DA830_EMB_D_4, DA830_EMB_D_5, DA830_EMB_D_6,
+ DA830_EMB_D_7, DA830_EMB_D_8, DA830_EMB_D_9, DA830_EMB_D_10,
+ DA830_EMB_D_11, DA830_EMB_D_12, DA830_EMB_D_13, DA830_EMB_D_14,
+ DA830_EMB_D_15, DA830_EMB_D_16, DA830_EMB_D_17, DA830_EMB_D_18,
+ DA830_EMB_D_19, DA830_EMB_D_20, DA830_EMB_D_21, DA830_EMB_D_22,
+ DA830_EMB_D_23, DA830_EMB_D_24, DA830_EMB_D_25, DA830_EMB_D_26,
+ DA830_EMB_D_27, DA830_EMB_D_28, DA830_EMB_D_29, DA830_EMB_D_30,
+ DA830_EMB_D_31, DA830_NEMB_WE_DQM_1, DA830_NEMB_WE_DQM_0,
+ -1
+};
+
+const short da830_mcasp0_pins[] __initdata = {
+ DA830_AHCLKX0, DA830_ACLKX0, DA830_AFSX0,
+ DA830_AHCLKR0, DA830_ACLKR0, DA830_AFSR0, DA830_AMUTE0,
+ DA830_AXR0_0, DA830_AXR0_1, DA830_AXR0_2, DA830_AXR0_3,
+ DA830_AXR0_4, DA830_AXR0_5, DA830_AXR0_6, DA830_AXR0_7,
+ DA830_AXR0_8, DA830_AXR0_9, DA830_AXR0_10, DA830_AXR0_11,
+ DA830_AXR0_12, DA830_AXR0_13, DA830_AXR0_14, DA830_AXR0_15,
+ -1
+};
+
+const short da830_mcasp1_pins[] __initdata = {
+ DA830_AHCLKX1, DA830_ACLKX1, DA830_AFSX1,
+ DA830_AHCLKR1, DA830_ACLKR1, DA830_AFSR1, DA830_AMUTE1,
+ DA830_AXR1_0, DA830_AXR1_1, DA830_AXR1_2, DA830_AXR1_3,
+ DA830_AXR1_4, DA830_AXR1_5, DA830_AXR1_6, DA830_AXR1_7,
+ DA830_AXR1_8, DA830_AXR1_9, DA830_AXR1_10, DA830_AXR1_11,
+ -1
+};
+
+const short da830_mcasp2_pins[] __initdata = {
+ DA830_AHCLKX2, DA830_ACLKX2, DA830_AFSX2,
+ DA830_AHCLKR2, DA830_ACLKR2, DA830_AFSR2, DA830_AMUTE2,
+ DA830_AXR2_0, DA830_AXR2_1, DA830_AXR2_2, DA830_AXR2_3,
+ -1
+};
+
+const short da830_i2c0_pins[] __initdata = {
+ DA830_I2C0_SDA, DA830_I2C0_SCL,
+ -1
+};
+
+const short da830_i2c1_pins[] __initdata = {
+ DA830_I2C1_SCL, DA830_I2C1_SDA,
+ -1
+};
+
+const short da830_lcdcntl_pins[] __initdata = {
+ DA830_LCD_D_0, DA830_LCD_D_1, DA830_LCD_D_2, DA830_LCD_D_3,
+ DA830_LCD_D_4, DA830_LCD_D_5, DA830_LCD_D_6, DA830_LCD_D_7,
+ DA830_LCD_D_8, DA830_LCD_D_9, DA830_LCD_D_10, DA830_LCD_D_11,
+ DA830_LCD_D_12, DA830_LCD_D_13, DA830_LCD_D_14, DA830_LCD_D_15,
+ DA830_LCD_PCLK, DA830_LCD_HSYNC, DA830_LCD_VSYNC, DA830_NLCD_AC_ENB_CS,
+ DA830_LCD_MCLK,
+ -1
+};
+
+const short da830_pwm_pins[] __initdata = {
+ DA830_ECAP0_APWM0, DA830_ECAP1_APWM1, DA830_EPWM0B, DA830_EPWM0A,
+ DA830_EPWMSYNCI, DA830_EPWMSYNC0, DA830_ECAP2_APWM2, DA830_EHRPWMGLUETZ,
+ DA830_EPWM2B, DA830_EPWM2A, DA830_EPWM1B, DA830_EPWM1A,
+ -1
+};
+
+const short da830_ecap0_pins[] __initdata = {
+ DA830_ECAP0_APWM0,
+ -1
+};
+
+const short da830_ecap1_pins[] __initdata = {
+ DA830_ECAP1_APWM1,
+ -1
+};
+
+const short da830_ecap2_pins[] __initdata = {
+ DA830_ECAP2_APWM2,
+ -1
+};
+
+const short da830_eqep0_pins[] __initdata = {
+ DA830_EQEP0I, DA830_EQEP0S, DA830_EQEP0A, DA830_EQEP0B,
+ -1
+};
+
+const short da830_eqep1_pins[] __initdata = {
+ DA830_EQEP1I, DA830_EQEP1S, DA830_EQEP1A, DA830_EQEP1B,
+ -1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da830_default_priorities[DA830_N_CP_INTC_IRQ] = {
+ [IRQ_DA8XX_COMMTX] = 7,
+ [IRQ_DA8XX_COMMRX] = 7,
+ [IRQ_DA8XX_NINT] = 7,
+ [IRQ_DA8XX_EVTOUT0] = 7,
+ [IRQ_DA8XX_EVTOUT1] = 7,
+ [IRQ_DA8XX_EVTOUT2] = 7,
+ [IRQ_DA8XX_EVTOUT3] = 7,
+ [IRQ_DA8XX_EVTOUT4] = 7,
+ [IRQ_DA8XX_EVTOUT5] = 7,
+ [IRQ_DA8XX_EVTOUT6] = 7,
+ [IRQ_DA8XX_EVTOUT7] = 7,
+ [IRQ_DA8XX_CCINT0] = 7,
+ [IRQ_DA8XX_CCERRINT] = 7,
+ [IRQ_DA8XX_TCERRINT0] = 7,
+ [IRQ_DA8XX_AEMIFINT] = 7,
+ [IRQ_DA8XX_I2CINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT1] = 7,
+ [IRQ_DA8XX_ALLINT0] = 7,
+ [IRQ_DA8XX_RTC] = 7,
+ [IRQ_DA8XX_SPINT0] = 7,
+ [IRQ_DA8XX_TINT12_0] = 7,
+ [IRQ_DA8XX_TINT34_0] = 7,
+ [IRQ_DA8XX_TINT12_1] = 7,
+ [IRQ_DA8XX_TINT34_1] = 7,
+ [IRQ_DA8XX_UARTINT0] = 7,
+ [IRQ_DA8XX_KEYMGRINT] = 7,
+ [IRQ_DA830_MPUERR] = 7,
+ [IRQ_DA8XX_CHIPINT0] = 7,
+ [IRQ_DA8XX_CHIPINT1] = 7,
+ [IRQ_DA8XX_CHIPINT2] = 7,
+ [IRQ_DA8XX_CHIPINT3] = 7,
+ [IRQ_DA8XX_TCERRINT1] = 7,
+ [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C0_RX_PULSE] = 7,
+ [IRQ_DA8XX_C0_TX_PULSE] = 7,
+ [IRQ_DA8XX_C0_MISC_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_PULSE] = 7,
+ [IRQ_DA8XX_C1_TX_PULSE] = 7,
+ [IRQ_DA8XX_C1_MISC_PULSE] = 7,
+ [IRQ_DA8XX_MEMERR] = 7,
+ [IRQ_DA8XX_GPIO0] = 7,
+ [IRQ_DA8XX_GPIO1] = 7,
+ [IRQ_DA8XX_GPIO2] = 7,
+ [IRQ_DA8XX_GPIO3] = 7,
+ [IRQ_DA8XX_GPIO4] = 7,
+ [IRQ_DA8XX_GPIO5] = 7,
+ [IRQ_DA8XX_GPIO6] = 7,
+ [IRQ_DA8XX_GPIO7] = 7,
+ [IRQ_DA8XX_GPIO8] = 7,
+ [IRQ_DA8XX_I2CINT1] = 7,
+ [IRQ_DA8XX_LCDINT] = 7,
+ [IRQ_DA8XX_UARTINT1] = 7,
+ [IRQ_DA8XX_MCASPINT] = 7,
+ [IRQ_DA8XX_ALLINT1] = 7,
+ [IRQ_DA8XX_SPINT1] = 7,
+ [IRQ_DA8XX_UHPI_INT1] = 7,
+ [IRQ_DA8XX_USB_INT] = 7,
+ [IRQ_DA8XX_IRQN] = 7,
+ [IRQ_DA8XX_RWAKEUP] = 7,
+ [IRQ_DA8XX_UARTINT2] = 7,
+ [IRQ_DA8XX_DFTSSINT] = 7,
+ [IRQ_DA8XX_EHRPWM0] = 7,
+ [IRQ_DA8XX_EHRPWM0TZ] = 7,
+ [IRQ_DA8XX_EHRPWM1] = 7,
+ [IRQ_DA8XX_EHRPWM1TZ] = 7,
+ [IRQ_DA830_EHRPWM2] = 7,
+ [IRQ_DA830_EHRPWM2TZ] = 7,
+ [IRQ_DA8XX_ECAP0] = 7,
+ [IRQ_DA8XX_ECAP1] = 7,
+ [IRQ_DA8XX_ECAP2] = 7,
+ [IRQ_DA830_EQEP0] = 7,
+ [IRQ_DA830_EQEP1] = 7,
+ [IRQ_DA830_T12CMPINT0_0] = 7,
+ [IRQ_DA830_T12CMPINT1_0] = 7,
+ [IRQ_DA830_T12CMPINT2_0] = 7,
+ [IRQ_DA830_T12CMPINT3_0] = 7,
+ [IRQ_DA830_T12CMPINT4_0] = 7,
+ [IRQ_DA830_T12CMPINT5_0] = 7,
+ [IRQ_DA830_T12CMPINT6_0] = 7,
+ [IRQ_DA830_T12CMPINT7_0] = 7,
+ [IRQ_DA830_T12CMPINT0_1] = 7,
+ [IRQ_DA830_T12CMPINT1_1] = 7,
+ [IRQ_DA830_T12CMPINT2_1] = 7,
+ [IRQ_DA830_T12CMPINT3_1] = 7,
+ [IRQ_DA830_T12CMPINT4_1] = 7,
+ [IRQ_DA830_T12CMPINT5_1] = 7,
+ [IRQ_DA830_T12CMPINT6_1] = 7,
+ [IRQ_DA830_T12CMPINT7_1] = 7,
+ [IRQ_DA8XX_ARMCLKSTOPREQ] = 7,
+};
+
+static struct map_desc da830_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DA8XX_CP_INTC_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE),
+ .length = DA8XX_CP_INTC_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+static u32 da830_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da830_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev1.0",
+ },
+ {
+ .variant = 0x8,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev1.1",
+ },
+ {
+ .variant = 0x9,
+ .part_no = 0xb7df,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DA830,
+ .name = "da830/omap-l137 rev2.0",
+ },
+};
+
+static struct davinci_timer_instance da830_timer_instance[2] = {
+ {
+ .base = DA8XX_TIMER64P0_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_0,
+ .top_irq = IRQ_DA8XX_TINT34_0,
+ .cmp_off = DA830_CMP12_0,
+ .cmp_irq = IRQ_DA830_T12CMPINT0_0,
+ },
+ {
+ .base = DA8XX_TIMER64P1_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_1,
+ .top_irq = IRQ_DA8XX_TINT34_1,
+ .cmp_off = DA830_CMP12_0,
+ .cmp_irq = IRQ_DA830_T12CMPINT0_1,
+ },
+};
+
+/*
+ * T0_BOT: Timer 0, bottom : Used for clock_event & clocksource
+ * T0_TOP: Timer 0, top : Used by DSP
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da830_timer_info = {
+ .timers = da830_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_BOT,
+};
+
+static struct davinci_soc_info davinci_soc_info_da830 = {
+ .io_desc = da830_io_desc,
+ .io_desc_num = ARRAY_SIZE(da830_io_desc),
+ .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
+ .ids = da830_ids,
+ .ids_num = ARRAY_SIZE(da830_ids),
+ .cpu_clks = da830_clks,
+ .psc_bases = da830_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(da830_psc_bases),
+ .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
+ .pinmux_pins = da830_pins,
+ .pinmux_pins_num = ARRAY_SIZE(da830_pins),
+ .intc_base = DA8XX_CP_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_irq_prios = da830_default_priorities,
+ .intc_irq_num = DA830_N_CP_INTC_IRQ,
+ .timer_info = &da830_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DA8XX_GPIO_BASE,
+ .gpio_num = 128,
+ .gpio_irq = IRQ_DA8XX_GPIO0,
+ .serial_dev = &da8xx_serial_device,
+ .emac_pdata = &da8xx_emac_pdata,
+ .reset_device = &da8xx_wdt_device,
+};
+
+void __init da830_init(void)
+{
+ davinci_common_init(&davinci_soc_info_da830);
+
+ da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+ WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module");
+}
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
new file mode 100644
index 00000000..133aac40
--- /dev/null
+++ b/arch/arm/mach-davinci/da850.c
@@ -0,0 +1,1139 @@
+/*
+ * TI DA850/OMAP-L138 chip specific setup
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Derived from: arch/arm/mach-davinci/da830.c
+ * Original Copyrights follow:
+ *
+ * 2009 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/psc.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/cpufreq.h>
+#include <mach/pm.h>
+#include <mach/gpio.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* SoC specific clock flags */
+#define DA850_CLK_ASYNC3 BIT(16)
+
+#define DA850_PLL1_BASE 0x01e1a000
+#define DA850_TIMER64P2_BASE 0x01f0c000
+#define DA850_TIMER64P3_BASE 0x01f0d000
+
+#define DA850_REF_FREQ 24000000
+
+#define CFGCHIP3_ASYNC3_CLKSRC BIT(4)
+#define CFGCHIP3_PLL1_MASTER_LOCK BIT(5)
+#define CFGCHIP0_PLL_MASTER_LOCK BIT(4)
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate);
+static int da850_round_armrate(struct clk *clk, unsigned long rate);
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate);
+
+static struct pll_data pll0_data = {
+ .num = 1,
+ .phys_base = DA8XX_PLL0_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DA850_REF_FREQ,
+};
+
+static struct clk pll0_clk = {
+ .name = "pll0",
+ .parent = &ref_clk,
+ .pll_data = &pll0_data,
+ .flags = CLK_PLL,
+ .set_rate = da850_set_pll0rate,
+};
+
+static struct clk pll0_aux_clk = {
+ .name = "pll0_aux_clk",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll0_sysclk2 = {
+ .name = "pll0_sysclk2",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll0_sysclk3 = {
+ .name = "pll0_sysclk3",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+ .set_rate = davinci_set_sysclk_rate,
+ .maxrate = 100000000,
+};
+
+static struct clk pll0_sysclk4 = {
+ .name = "pll0_sysclk4",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll0_sysclk5 = {
+ .name = "pll0_sysclk5",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll0_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll0_sysclk7 = {
+ .name = "pll0_sysclk7",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct pll_data pll1_data = {
+ .num = 2,
+ .phys_base = DA850_PLL1_BASE,
+ .flags = PLL_HAS_POSTDIV,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll0_sysclk6",
+ .parent = &pll0_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk i2c0_clk = {
+ .name = "i2c0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_0_clk = {
+ .name = "timer0",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk timerp64_1_clk = {
+ .name = "timer1",
+ .parent = &pll0_aux_clk,
+};
+
+static struct clk arm_rom_clk = {
+ .name = "arm_rom",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_ARM_RAM_ROM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc0_clk = {
+ .name = "tpcc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPCC,
+ .flags = ALWAYS_ENABLED | CLK_PSC,
+};
+
+static struct clk tptc0_clk = {
+ .name = "tptc0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tptc1_clk = {
+ .name = "tptc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk tpcc1_clk = {
+ .name = "tpcc1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_TPCC1,
+ .gpsc = 1,
+ .flags = CLK_PSC | ALWAYS_ENABLED,
+};
+
+static struct clk tptc2_clk = {
+ .name = "tptc2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_TPTC2,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART1,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_UART2,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk aintc_clk = {
+ .name = "aintc",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC0_AINTC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_GPIO,
+ .gpsc = 1,
+};
+
+static struct clk i2c1_clk = {
+ .name = "i2c1",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_I2C,
+ .gpsc = 1,
+};
+
+static struct clk emif3_clk = {
+ .name = "emif3",
+ .parent = &pll0_sysclk5,
+ .lpsc = DA8XX_LPSC1_EMIF3C,
+ .gpsc = 1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll0_sysclk6,
+ .lpsc = DA8XX_LPSC0_ARM,
+ .flags = ALWAYS_ENABLED,
+ .set_rate = da850_set_armrate,
+ .round_rate = da850_round_armrate,
+};
+
+static struct clk rmii_clk = {
+ .name = "rmii",
+ .parent = &pll0_sysclk7,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_CPGMAC,
+ .gpsc = 1,
+};
+
+static struct clk mcasp_clk = {
+ .name = "mcasp",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_McASP0,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk lcdc_clk = {
+ .name = "lcdc",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_LCDC,
+ .gpsc = 1,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA850_LPSC1_MMC_SD1,
+ .gpsc = 1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll0_sysclk3,
+ .lpsc = DA8XX_LPSC0_EMIF25,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk usb11_clk = {
+ .name = "usb11",
+ .parent = &pll0_sysclk4,
+ .lpsc = DA8XX_LPSC1_USB11,
+ .gpsc = 1,
+};
+
+static struct clk usb20_clk = {
+ .name = "usb20",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_USB20,
+ .gpsc = 1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC0_SPI0,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll0_sysclk2,
+ .lpsc = DA8XX_LPSC1_SPI1,
+ .gpsc = 1,
+ .flags = DA850_CLK_ASYNC3,
+};
+
+static struct clk_lookup da850_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll0", &pll0_clk),
+ CLK(NULL, "pll0_aux", &pll0_aux_clk),
+ CLK(NULL, "pll0_sysclk2", &pll0_sysclk2),
+ CLK(NULL, "pll0_sysclk3", &pll0_sysclk3),
+ CLK(NULL, "pll0_sysclk4", &pll0_sysclk4),
+ CLK(NULL, "pll0_sysclk5", &pll0_sysclk5),
+ CLK(NULL, "pll0_sysclk6", &pll0_sysclk6),
+ CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK("i2c_davinci.1", NULL, &i2c0_clk),
+ CLK(NULL, "timer0", &timerp64_0_clk),
+ CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK(NULL, "arm_rom", &arm_rom_clk),
+ CLK(NULL, "tpcc0", &tpcc0_clk),
+ CLK(NULL, "tptc0", &tptc0_clk),
+ CLK(NULL, "tptc1", &tptc1_clk),
+ CLK(NULL, "tpcc1", &tpcc1_clk),
+ CLK(NULL, "tptc2", &tptc2_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK(NULL, "aintc", &aintc_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("i2c_davinci.2", NULL, &i2c1_clk),
+ CLK(NULL, "emif3", &emif3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "rmii", &rmii_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp_clk),
+ CLK("da8xx_lcdc.0", NULL, &lcdc_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "usb11", &usb11_clk),
+ CLK(NULL, "usb20", &usb20_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config da850_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ /* UART0 function */
+ MUX_CFG(DA850, NUART0_CTS, 3, 24, 15, 2, false)
+ MUX_CFG(DA850, NUART0_RTS, 3, 28, 15, 2, false)
+ MUX_CFG(DA850, UART0_RXD, 3, 16, 15, 2, false)
+ MUX_CFG(DA850, UART0_TXD, 3, 20, 15, 2, false)
+ /* UART1 function */
+ MUX_CFG(DA850, UART1_RXD, 4, 24, 15, 2, false)
+ MUX_CFG(DA850, UART1_TXD, 4, 28, 15, 2, false)
+ /* UART2 function */
+ MUX_CFG(DA850, UART2_RXD, 4, 16, 15, 2, false)
+ MUX_CFG(DA850, UART2_TXD, 4, 20, 15, 2, false)
+ /* I2C1 function */
+ MUX_CFG(DA850, I2C1_SCL, 4, 16, 15, 4, false)
+ MUX_CFG(DA850, I2C1_SDA, 4, 20, 15, 4, false)
+ /* I2C0 function */
+ MUX_CFG(DA850, I2C0_SDA, 4, 12, 15, 2, false)
+ MUX_CFG(DA850, I2C0_SCL, 4, 8, 15, 2, false)
+ /* EMAC function */
+ MUX_CFG(DA850, MII_TXEN, 2, 4, 15, 8, false)
+ MUX_CFG(DA850, MII_TXCLK, 2, 8, 15, 8, false)
+ MUX_CFG(DA850, MII_COL, 2, 12, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_3, 2, 16, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_2, 2, 20, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_1, 2, 24, 15, 8, false)
+ MUX_CFG(DA850, MII_TXD_0, 2, 28, 15, 8, false)
+ MUX_CFG(DA850, MII_RXCLK, 3, 0, 15, 8, false)
+ MUX_CFG(DA850, MII_RXDV, 3, 4, 15, 8, false)
+ MUX_CFG(DA850, MII_RXER, 3, 8, 15, 8, false)
+ MUX_CFG(DA850, MII_CRS, 3, 12, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_3, 3, 16, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_2, 3, 20, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_1, 3, 24, 15, 8, false)
+ MUX_CFG(DA850, MII_RXD_0, 3, 28, 15, 8, false)
+ MUX_CFG(DA850, MDIO_CLK, 4, 0, 15, 8, false)
+ MUX_CFG(DA850, MDIO_D, 4, 4, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXD_0, 14, 12, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXD_1, 14, 8, 15, 8, false)
+ MUX_CFG(DA850, RMII_TXEN, 14, 16, 15, 8, false)
+ MUX_CFG(DA850, RMII_CRS_DV, 15, 4, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXD_0, 14, 24, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXD_1, 14, 20, 15, 8, false)
+ MUX_CFG(DA850, RMII_RXER, 14, 28, 15, 8, false)
+ MUX_CFG(DA850, RMII_MHZ_50_CLK, 15, 0, 15, 0, false)
+ /* McASP function */
+ MUX_CFG(DA850, ACLKR, 0, 0, 15, 1, false)
+ MUX_CFG(DA850, ACLKX, 0, 4, 15, 1, false)
+ MUX_CFG(DA850, AFSR, 0, 8, 15, 1, false)
+ MUX_CFG(DA850, AFSX, 0, 12, 15, 1, false)
+ MUX_CFG(DA850, AHCLKR, 0, 16, 15, 1, false)
+ MUX_CFG(DA850, AHCLKX, 0, 20, 15, 1, false)
+ MUX_CFG(DA850, AMUTE, 0, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_15, 1, 0, 15, 1, false)
+ MUX_CFG(DA850, AXR_14, 1, 4, 15, 1, false)
+ MUX_CFG(DA850, AXR_13, 1, 8, 15, 1, false)
+ MUX_CFG(DA850, AXR_12, 1, 12, 15, 1, false)
+ MUX_CFG(DA850, AXR_11, 1, 16, 15, 1, false)
+ MUX_CFG(DA850, AXR_10, 1, 20, 15, 1, false)
+ MUX_CFG(DA850, AXR_9, 1, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_8, 1, 28, 15, 1, false)
+ MUX_CFG(DA850, AXR_7, 2, 0, 15, 1, false)
+ MUX_CFG(DA850, AXR_6, 2, 4, 15, 1, false)
+ MUX_CFG(DA850, AXR_5, 2, 8, 15, 1, false)
+ MUX_CFG(DA850, AXR_4, 2, 12, 15, 1, false)
+ MUX_CFG(DA850, AXR_3, 2, 16, 15, 1, false)
+ MUX_CFG(DA850, AXR_2, 2, 20, 15, 1, false)
+ MUX_CFG(DA850, AXR_1, 2, 24, 15, 1, false)
+ MUX_CFG(DA850, AXR_0, 2, 28, 15, 1, false)
+ /* LCD function */
+ MUX_CFG(DA850, LCD_D_7, 16, 8, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_6, 16, 12, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_5, 16, 16, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_4, 16, 20, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_3, 16, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_2, 16, 28, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_1, 17, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_0, 17, 4, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_15, 17, 8, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_14, 17, 12, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_13, 17, 16, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_12, 17, 20, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_11, 17, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_10, 17, 28, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_9, 18, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_D_8, 18, 4, 15, 2, false)
+ MUX_CFG(DA850, LCD_PCLK, 18, 24, 15, 2, false)
+ MUX_CFG(DA850, LCD_HSYNC, 19, 0, 15, 2, false)
+ MUX_CFG(DA850, LCD_VSYNC, 19, 4, 15, 2, false)
+ MUX_CFG(DA850, NLCD_AC_ENB_CS, 19, 24, 15, 2, false)
+ /* MMC/SD0 function */
+ MUX_CFG(DA850, MMCSD0_DAT_0, 10, 8, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_1, 10, 12, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_2, 10, 16, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false)
+ MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false)
+ /* EMIF2.5/EMIFA function */
+ MUX_CFG(DA850, EMA_D_7, 9, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_6, 9, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_5, 9, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_4, 9, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_3, 9, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_2, 9, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_1, 9, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_0, 9, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_1, 12, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_2, 12, 20, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_3, 7, 4, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_4, 7, 8, 15, 1, false)
+ MUX_CFG(DA850, NEMA_WE, 7, 16, 15, 1, false)
+ MUX_CFG(DA850, NEMA_OE, 7, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_0, 12, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_3, 12, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_4, 12, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_5, 12, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_6, 12, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_7, 12, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_8, 11, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_9, 11, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_10, 11, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_11, 11, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_12, 11, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_13, 11, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_14, 11, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_15, 11, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_16, 10, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_17, 10, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_18, 10, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_19, 10, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_20, 10, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_21, 10, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_22, 10, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_A_23, 10, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_8, 8, 28, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_9, 8, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_10, 8, 20, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_11, 8, 16, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_12, 8, 12, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_13, 8, 8, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_14, 8, 4, 15, 1, false)
+ MUX_CFG(DA850, EMA_D_15, 8, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_BA_1, 5, 24, 15, 1, false)
+ MUX_CFG(DA850, EMA_CLK, 6, 0, 15, 1, false)
+ MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false)
+ MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false)
+ /* GPIO function */
+ MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false)
+ MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false)
+ MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false)
+ MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false)
+ MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false)
+ MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false)
+ MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false)
+ MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false)
+#endif
+};
+
+const short da850_i2c0_pins[] __initdata = {
+ DA850_I2C0_SDA, DA850_I2C0_SCL,
+ -1
+};
+
+const short da850_i2c1_pins[] __initdata = {
+ DA850_I2C1_SCL, DA850_I2C1_SDA,
+ -1
+};
+
+const short da850_lcdcntl_pins[] __initdata = {
+ DA850_LCD_D_0, DA850_LCD_D_1, DA850_LCD_D_2, DA850_LCD_D_3,
+ DA850_LCD_D_4, DA850_LCD_D_5, DA850_LCD_D_6, DA850_LCD_D_7,
+ DA850_LCD_D_8, DA850_LCD_D_9, DA850_LCD_D_10, DA850_LCD_D_11,
+ DA850_LCD_D_12, DA850_LCD_D_13, DA850_LCD_D_14, DA850_LCD_D_15,
+ DA850_LCD_PCLK, DA850_LCD_HSYNC, DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS,
+ -1
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = {
+ [IRQ_DA8XX_COMMTX] = 7,
+ [IRQ_DA8XX_COMMRX] = 7,
+ [IRQ_DA8XX_NINT] = 7,
+ [IRQ_DA8XX_EVTOUT0] = 7,
+ [IRQ_DA8XX_EVTOUT1] = 7,
+ [IRQ_DA8XX_EVTOUT2] = 7,
+ [IRQ_DA8XX_EVTOUT3] = 7,
+ [IRQ_DA8XX_EVTOUT4] = 7,
+ [IRQ_DA8XX_EVTOUT5] = 7,
+ [IRQ_DA8XX_EVTOUT6] = 7,
+ [IRQ_DA8XX_EVTOUT7] = 7,
+ [IRQ_DA8XX_CCINT0] = 7,
+ [IRQ_DA8XX_CCERRINT] = 7,
+ [IRQ_DA8XX_TCERRINT0] = 7,
+ [IRQ_DA8XX_AEMIFINT] = 7,
+ [IRQ_DA8XX_I2CINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT0] = 7,
+ [IRQ_DA8XX_MMCSDINT1] = 7,
+ [IRQ_DA8XX_ALLINT0] = 7,
+ [IRQ_DA8XX_RTC] = 7,
+ [IRQ_DA8XX_SPINT0] = 7,
+ [IRQ_DA8XX_TINT12_0] = 7,
+ [IRQ_DA8XX_TINT34_0] = 7,
+ [IRQ_DA8XX_TINT12_1] = 7,
+ [IRQ_DA8XX_TINT34_1] = 7,
+ [IRQ_DA8XX_UARTINT0] = 7,
+ [IRQ_DA8XX_KEYMGRINT] = 7,
+ [IRQ_DA850_MPUADDRERR0] = 7,
+ [IRQ_DA8XX_CHIPINT0] = 7,
+ [IRQ_DA8XX_CHIPINT1] = 7,
+ [IRQ_DA8XX_CHIPINT2] = 7,
+ [IRQ_DA8XX_CHIPINT3] = 7,
+ [IRQ_DA8XX_TCERRINT1] = 7,
+ [IRQ_DA8XX_C0_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C0_RX_PULSE] = 7,
+ [IRQ_DA8XX_C0_TX_PULSE] = 7,
+ [IRQ_DA8XX_C0_MISC_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_THRESH_PULSE] = 7,
+ [IRQ_DA8XX_C1_RX_PULSE] = 7,
+ [IRQ_DA8XX_C1_TX_PULSE] = 7,
+ [IRQ_DA8XX_C1_MISC_PULSE] = 7,
+ [IRQ_DA8XX_MEMERR] = 7,
+ [IRQ_DA8XX_GPIO0] = 7,
+ [IRQ_DA8XX_GPIO1] = 7,
+ [IRQ_DA8XX_GPIO2] = 7,
+ [IRQ_DA8XX_GPIO3] = 7,
+ [IRQ_DA8XX_GPIO4] = 7,
+ [IRQ_DA8XX_GPIO5] = 7,
+ [IRQ_DA8XX_GPIO6] = 7,
+ [IRQ_DA8XX_GPIO7] = 7,
+ [IRQ_DA8XX_GPIO8] = 7,
+ [IRQ_DA8XX_I2CINT1] = 7,
+ [IRQ_DA8XX_LCDINT] = 7,
+ [IRQ_DA8XX_UARTINT1] = 7,
+ [IRQ_DA8XX_MCASPINT] = 7,
+ [IRQ_DA8XX_ALLINT1] = 7,
+ [IRQ_DA8XX_SPINT1] = 7,
+ [IRQ_DA8XX_UHPI_INT1] = 7,
+ [IRQ_DA8XX_USB_INT] = 7,
+ [IRQ_DA8XX_IRQN] = 7,
+ [IRQ_DA8XX_RWAKEUP] = 7,
+ [IRQ_DA8XX_UARTINT2] = 7,
+ [IRQ_DA8XX_DFTSSINT] = 7,
+ [IRQ_DA8XX_EHRPWM0] = 7,
+ [IRQ_DA8XX_EHRPWM0TZ] = 7,
+ [IRQ_DA8XX_EHRPWM1] = 7,
+ [IRQ_DA8XX_EHRPWM1TZ] = 7,
+ [IRQ_DA850_SATAINT] = 7,
+ [IRQ_DA850_TINTALL_2] = 7,
+ [IRQ_DA8XX_ECAP0] = 7,
+ [IRQ_DA8XX_ECAP1] = 7,
+ [IRQ_DA8XX_ECAP2] = 7,
+ [IRQ_DA850_MMCSDINT0_1] = 7,
+ [IRQ_DA850_MMCSDINT1_1] = 7,
+ [IRQ_DA850_T12CMPINT0_2] = 7,
+ [IRQ_DA850_T12CMPINT1_2] = 7,
+ [IRQ_DA850_T12CMPINT2_2] = 7,
+ [IRQ_DA850_T12CMPINT3_2] = 7,
+ [IRQ_DA850_T12CMPINT4_2] = 7,
+ [IRQ_DA850_T12CMPINT5_2] = 7,
+ [IRQ_DA850_T12CMPINT6_2] = 7,
+ [IRQ_DA850_T12CMPINT7_2] = 7,
+ [IRQ_DA850_T12CMPINT0_3] = 7,
+ [IRQ_DA850_T12CMPINT1_3] = 7,
+ [IRQ_DA850_T12CMPINT2_3] = 7,
+ [IRQ_DA850_T12CMPINT3_3] = 7,
+ [IRQ_DA850_T12CMPINT4_3] = 7,
+ [IRQ_DA850_T12CMPINT5_3] = 7,
+ [IRQ_DA850_T12CMPINT6_3] = 7,
+ [IRQ_DA850_T12CMPINT7_3] = 7,
+ [IRQ_DA850_RPIINT] = 7,
+ [IRQ_DA850_VPIFINT] = 7,
+ [IRQ_DA850_CCINT1] = 7,
+ [IRQ_DA850_CCERRINT1] = 7,
+ [IRQ_DA850_TCERRINT2] = 7,
+ [IRQ_DA850_TINTALL_3] = 7,
+ [IRQ_DA850_MCBSP0RINT] = 7,
+ [IRQ_DA850_MCBSP0XINT] = 7,
+ [IRQ_DA850_MCBSP1RINT] = 7,
+ [IRQ_DA850_MCBSP1XINT] = 7,
+ [IRQ_DA8XX_ARMCLKSTOPREQ] = 7,
+};
+
+static struct map_desc da850_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DA8XX_CP_INTC_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_CP_INTC_BASE),
+ .length = DA8XX_CP_INTC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE
+ },
+};
+
+static u32 da850_psc_bases[] = { DA8XX_PSC0_BASE, DA8XX_PSC1_BASE };
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id da850_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb7d1,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA850,
+ .name = "da850/omap-l138",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb7d1,
+ .manufacturer = 0x017, /* 0x02f >> 1 */
+ .cpu_id = DAVINCI_CPU_ID_DA850,
+ .name = "da850/omap-l138/am18x",
+ },
+};
+
+static struct davinci_timer_instance da850_timer_instance[4] = {
+ {
+ .base = DA8XX_TIMER64P0_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_0,
+ .top_irq = IRQ_DA8XX_TINT34_0,
+ },
+ {
+ .base = DA8XX_TIMER64P1_BASE,
+ .bottom_irq = IRQ_DA8XX_TINT12_1,
+ .top_irq = IRQ_DA8XX_TINT34_1,
+ },
+ {
+ .base = DA850_TIMER64P2_BASE,
+ .bottom_irq = IRQ_DA850_TINT12_2,
+ .top_irq = IRQ_DA850_TINT34_2,
+ },
+ {
+ .base = DA850_TIMER64P3_BASE,
+ .bottom_irq = IRQ_DA850_TINT12_3,
+ .top_irq = IRQ_DA850_TINT34_3,
+ },
+};
+
+/*
+ * T0_BOT: Timer 0, bottom : Used for clock_event
+ * T0_TOP: Timer 0, top : Used for clocksource
+ * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ */
+static struct davinci_timer_info da850_timer_info = {
+ .timers = da850_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static void da850_set_async3_src(int pllnum)
+{
+ struct clk *clk, *newparent = pllnum ? &pll1_sysclk2 : &pll0_sysclk2;
+ struct clk_lookup *c;
+ unsigned int v;
+ int ret;
+
+ for (c = da850_clks; c->clk; c++) {
+ clk = c->clk;
+ if (clk->flags & DA850_CLK_ASYNC3) {
+ ret = clk_set_parent(clk, newparent);
+ WARN(ret, "DA850: unable to re-parent clock %s",
+ clk->name);
+ }
+ }
+
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+ if (pllnum)
+ v |= CFGCHIP3_ASYNC3_CLKSRC;
+ else
+ v &= ~CFGCHIP3_ASYNC3_CLKSRC;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Notes:
+ * According to the TRM, minimum PLLM results in maximum power savings.
+ * The OPP definitions below should keep the PLLM as low as possible.
+ *
+ * The output of the PLLM must be between 300 to 600 MHz.
+ */
+struct da850_opp {
+ unsigned int freq; /* in KHz */
+ unsigned int prediv;
+ unsigned int mult;
+ unsigned int postdiv;
+ unsigned int cvdd_min; /* in uV */
+ unsigned int cvdd_max; /* in uV */
+};
+
+static const struct da850_opp da850_opp_456 = {
+ .freq = 456000,
+ .prediv = 1,
+ .mult = 19,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_408 = {
+ .freq = 408000,
+ .prediv = 1,
+ .mult = 17,
+ .postdiv = 1,
+ .cvdd_min = 1300000,
+ .cvdd_max = 1350000,
+};
+
+static const struct da850_opp da850_opp_372 = {
+ .freq = 372000,
+ .prediv = 2,
+ .mult = 31,
+ .postdiv = 1,
+ .cvdd_min = 1200000,
+ .cvdd_max = 1320000,
+};
+
+static const struct da850_opp da850_opp_300 = {
+ .freq = 300000,
+ .prediv = 1,
+ .mult = 25,
+ .postdiv = 2,
+ .cvdd_min = 1200000,
+ .cvdd_max = 1320000,
+};
+
+static const struct da850_opp da850_opp_200 = {
+ .freq = 200000,
+ .prediv = 1,
+ .mult = 25,
+ .postdiv = 3,
+ .cvdd_min = 1100000,
+ .cvdd_max = 1160000,
+};
+
+static const struct da850_opp da850_opp_96 = {
+ .freq = 96000,
+ .prediv = 1,
+ .mult = 20,
+ .postdiv = 5,
+ .cvdd_min = 1000000,
+ .cvdd_max = 1050000,
+};
+
+#define OPP(freq) \
+ { \
+ .index = (unsigned int) &da850_opp_##freq, \
+ .frequency = freq * 1000, \
+ }
+
+static struct cpufreq_frequency_table da850_freq_table[] = {
+ OPP(456),
+ OPP(408),
+ OPP(372),
+ OPP(300),
+ OPP(200),
+ OPP(96),
+ {
+ .index = 0,
+ .frequency = CPUFREQ_TABLE_END,
+ },
+};
+
+#ifdef CONFIG_REGULATOR
+static int da850_set_voltage(unsigned int index);
+static int da850_regulator_init(void);
+#endif
+
+static struct davinci_cpufreq_config cpufreq_info = {
+ .freq_table = da850_freq_table,
+#ifdef CONFIG_REGULATOR
+ .init = da850_regulator_init,
+ .set_voltage = da850_set_voltage,
+#endif
+};
+
+#ifdef CONFIG_REGULATOR
+static struct regulator *cvdd;
+
+static int da850_set_voltage(unsigned int index)
+{
+ struct da850_opp *opp;
+
+ if (!cvdd)
+ return -ENODEV;
+
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+
+ return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
+}
+
+static int da850_regulator_init(void)
+{
+ cvdd = regulator_get(NULL, "cvdd");
+ if (WARN(IS_ERR(cvdd), "Unable to obtain voltage regulator for CVDD;"
+ " voltage scaling unsupported\n")) {
+ return PTR_ERR(cvdd);
+ }
+
+ return 0;
+}
+#endif
+
+static struct platform_device da850_cpufreq_device = {
+ .name = "cpufreq-davinci",
+ .dev = {
+ .platform_data = &cpufreq_info,
+ },
+ .id = -1,
+};
+
+unsigned int da850_max_speed = 300000;
+
+int __init da850_register_cpufreq(char *async_clk)
+{
+ int i;
+
+ /* cpufreq driver can help keep an "async" clock constant */
+ if (async_clk)
+ clk_add_alias("async", da850_cpufreq_device.name,
+ async_clk, NULL);
+ for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
+ if (da850_freq_table[i].frequency <= da850_max_speed) {
+ cpufreq_info.freq_table = &da850_freq_table[i];
+ break;
+ }
+ }
+
+ return platform_device_register(&da850_cpufreq_device);
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+ int i, ret = 0, diff;
+ unsigned int best = (unsigned int) -1;
+ struct cpufreq_frequency_table *table = cpufreq_info.freq_table;
+
+ rate /= 1000; /* convert to kHz */
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ diff = table[i].frequency - rate;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < best) {
+ best = diff;
+ ret = table[i].frequency;
+ }
+ }
+
+ return ret * 1000;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long index)
+{
+ struct clk *pllclk = &pll0_clk;
+
+ return clk_set_rate(pllclk, index);
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long index)
+{
+ unsigned int prediv, mult, postdiv;
+ struct da850_opp *opp;
+ struct pll_data *pll = clk->pll_data;
+ int ret;
+
+ opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
+ prediv = opp->prediv;
+ mult = opp->mult;
+ postdiv = opp->postdiv;
+
+ ret = davinci_set_pllrate(pll, prediv, mult, postdiv);
+ if (WARN_ON(ret))
+ return ret;
+
+ return 0;
+}
+#else
+int __init da850_register_cpufreq(char *async_clk)
+{
+ return 0;
+}
+
+static int da850_set_armrate(struct clk *clk, unsigned long rate)
+{
+ return -EINVAL;
+}
+
+static int da850_set_pll0rate(struct clk *clk, unsigned long armrate)
+{
+ return -EINVAL;
+}
+
+static int da850_round_armrate(struct clk *clk, unsigned long rate)
+{
+ return clk->rate;
+}
+#endif
+
+int da850_register_pm(struct platform_device *pdev)
+{
+ int ret;
+ struct davinci_pm_config *pdata = pdev->dev.platform_data;
+
+ ret = davinci_cfg_reg(DA850_RTC_ALARM);
+ if (ret)
+ return ret;
+
+ pdata->ddr2_ctlr_base = da8xx_get_mem_ctlr();
+ pdata->deepsleep_reg = DA8XX_SYSCFG1_VIRT(DA8XX_DEEPSLEEP_REG);
+ pdata->ddrpsc_num = DA8XX_LPSC1_EMIF3C;
+
+ pdata->cpupll_reg_base = ioremap(DA8XX_PLL0_BASE, SZ_4K);
+ if (!pdata->cpupll_reg_base)
+ return -ENOMEM;
+
+ pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
+ if (!pdata->ddrpll_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpll_mem;
+ }
+
+ pdata->ddrpsc_reg_base = ioremap(DA8XX_PSC1_BASE, SZ_4K);
+ if (!pdata->ddrpsc_reg_base) {
+ ret = -ENOMEM;
+ goto no_ddrpsc_mem;
+ }
+
+ return platform_device_register(pdev);
+
+no_ddrpsc_mem:
+ iounmap(pdata->ddrpll_reg_base);
+no_ddrpll_mem:
+ iounmap(pdata->cpupll_reg_base);
+ return ret;
+}
+
+static struct davinci_soc_info davinci_soc_info_da850 = {
+ .io_desc = da850_io_desc,
+ .io_desc_num = ARRAY_SIZE(da850_io_desc),
+ .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG,
+ .ids = da850_ids,
+ .ids_num = ARRAY_SIZE(da850_ids),
+ .cpu_clks = da850_clks,
+ .psc_bases = da850_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(da850_psc_bases),
+ .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120,
+ .pinmux_pins = da850_pins,
+ .pinmux_pins_num = ARRAY_SIZE(da850_pins),
+ .intc_base = DA8XX_CP_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_irq_prios = da850_default_priorities,
+ .intc_irq_num = DA850_N_CP_INTC_IRQ,
+ .timer_info = &da850_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DA8XX_GPIO_BASE,
+ .gpio_num = 144,
+ .gpio_irq = IRQ_DA8XX_GPIO0,
+ .serial_dev = &da8xx_serial_device,
+ .emac_pdata = &da8xx_emac_pdata,
+ .sram_dma = DA8XX_ARM_RAM_BASE,
+ .sram_len = SZ_8K,
+ .reset_device = &da8xx_wdt_device,
+};
+
+void __init da850_init(void)
+{
+ unsigned int v;
+
+ davinci_common_init(&davinci_soc_info_da850);
+
+ da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K);
+ if (WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"))
+ return;
+
+ da8xx_syscfg1_base = ioremap(DA8XX_SYSCFG1_BASE, SZ_4K);
+ if (WARN(!da8xx_syscfg1_base, "Unable to map syscfg1 module"))
+ return;
+
+ /*
+ * Move the clock source of Async3 domain to PLL1 SYSCLK2.
+ * This helps keeping the peripherals on this domain insulated
+ * from CPU frequency changes caused by DVFS. The firmware sets
+ * both PLL0 and PLL1 to the same frequency so, there should not
+ * be any noticeable change even in non-DVFS use cases.
+ */
+ da850_set_async3_src(1);
+
+ /* Unlock writing to PLL0 registers */
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+ v &= ~CFGCHIP0_PLL_MASTER_LOCK;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG));
+
+ /* Unlock writing to PLL1 registers */
+ v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+ v &= ~CFGCHIP3_PLL1_MASTER_LOCK;
+ __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG));
+}
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
new file mode 100644
index 00000000..fc4e98ea
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -0,0 +1,844 @@
+/*
+ * DA8XX/OMAP L1XX platform device data
+ *
+ * Copyright (c) 2007-2009, MontaVista Software, Inc. <source@mvista.com>
+ * Derived from code that was:
+ * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.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/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/da8xx.h>
+#include <mach/cpuidle.h>
+
+#include "clock.h"
+
+#define DA8XX_TPCC_BASE 0x01c00000
+#define DA8XX_TPTC0_BASE 0x01c08000
+#define DA8XX_TPTC1_BASE 0x01c08400
+#define DA8XX_WDOG_BASE 0x01c21000 /* DA8XX_TIMER64P1_BASE */
+#define DA8XX_I2C0_BASE 0x01c22000
+#define DA8XX_RTC_BASE 0x01c23000
+#define DA8XX_MMCSD0_BASE 0x01c40000
+#define DA8XX_SPI0_BASE 0x01c41000
+#define DA830_SPI1_BASE 0x01e12000
+#define DA8XX_LCD_CNTRL_BASE 0x01e13000
+#define DA850_MMCSD1_BASE 0x01e1b000
+#define DA8XX_EMAC_CPPI_PORT_BASE 0x01e20000
+#define DA8XX_EMAC_CPGMACSS_BASE 0x01e22000
+#define DA8XX_EMAC_CPGMAC_BASE 0x01e23000
+#define DA8XX_EMAC_MDIO_BASE 0x01e24000
+#define DA8XX_I2C1_BASE 0x01e28000
+#define DA850_TPCC1_BASE 0x01e30000
+#define DA850_TPTC2_BASE 0x01e38000
+#define DA850_SPI1_BASE 0x01f0e000
+#define DA8XX_DDR2_CTL_BASE 0xb0000000
+
+#define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000
+#define DA8XX_EMAC_MOD_REG_OFFSET 0x2000
+#define DA8XX_EMAC_RAM_OFFSET 0x0000
+#define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K
+
+#define DA8XX_DMA_SPI0_RX EDMA_CTLR_CHAN(0, 14)
+#define DA8XX_DMA_SPI0_TX EDMA_CTLR_CHAN(0, 15)
+#define DA8XX_DMA_MMCSD0_RX EDMA_CTLR_CHAN(0, 16)
+#define DA8XX_DMA_MMCSD0_TX EDMA_CTLR_CHAN(0, 17)
+#define DA8XX_DMA_SPI1_RX EDMA_CTLR_CHAN(0, 18)
+#define DA8XX_DMA_SPI1_TX EDMA_CTLR_CHAN(0, 19)
+#define DA850_DMA_MMCSD1_RX EDMA_CTLR_CHAN(1, 28)
+#define DA850_DMA_MMCSD1_TX EDMA_CTLR_CHAN(1, 29)
+
+void __iomem *da8xx_syscfg0_base;
+void __iomem *da8xx_syscfg1_base;
+
+static struct plat_serial8250_port da8xx_serial_pdata[] = {
+ {
+ .mapbase = DA8XX_UART0_BASE,
+ .irq = IRQ_DA8XX_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DA8XX_UART1_BASE,
+ .irq = IRQ_DA8XX_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DA8XX_UART2_BASE,
+ .irq = IRQ_DA8XX_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ },
+};
+
+struct platform_device da8xx_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = da8xx_serial_pdata,
+ },
+};
+
+static const s8 da8xx_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1}
+};
+
+static const s8 da8xx_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1}
+};
+
+static const s8 da850_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {-1, -1}
+};
+
+static const s8 da850_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {-1, -1}
+};
+
+static struct edma_soc_info da830_edma_cc0_info = {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = da8xx_queue_tc_mapping,
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+};
+
+static struct edma_soc_info *da830_edma_info[EDMA_MAX_CC] = {
+ &da830_edma_cc0_info,
+};
+
+static struct edma_soc_info da850_edma_cc_info[] = {
+ {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = da8xx_queue_tc_mapping,
+ .queue_priority_mapping = da8xx_queue_priority_mapping,
+ },
+ {
+ .n_channel = 32,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 1,
+ .n_cc = 1,
+ .queue_tc_mapping = da850_queue_tc_mapping,
+ .queue_priority_mapping = da850_queue_priority_mapping,
+ },
+};
+
+static struct edma_soc_info *da850_edma_info[EDMA_MAX_CC] = {
+ &da850_edma_cc_info[0],
+ &da850_edma_cc_info[1],
+};
+
+static struct resource da830_edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = DA8XX_TPCC_BASE,
+ .end = DA8XX_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = DA8XX_TPTC0_BASE,
+ .end = DA8XX_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = DA8XX_TPTC1_BASE,
+ .end = DA8XX_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_DA8XX_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_DA8XX_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource da850_edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = DA8XX_TPCC_BASE,
+ .end = DA8XX_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = DA8XX_TPTC0_BASE,
+ .end = DA8XX_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = DA8XX_TPTC1_BASE,
+ .end = DA8XX_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_cc1",
+ .start = DA850_TPCC1_BASE,
+ .end = DA850_TPCC1_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = DA850_TPTC2_BASE,
+ .end = DA850_TPTC2_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_DA8XX_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_DA8XX_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma1",
+ .start = IRQ_DA850_CCINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma1_err",
+ .start = IRQ_DA850_CCERRINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da830_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev = {
+ .platform_data = da830_edma_info,
+ },
+ .num_resources = ARRAY_SIZE(da830_edma_resources),
+ .resource = da830_edma_resources,
+};
+
+static struct platform_device da850_edma_device = {
+ .name = "edma",
+ .id = -1,
+ .dev = {
+ .platform_data = da850_edma_info,
+ },
+ .num_resources = ARRAY_SIZE(da850_edma_resources),
+ .resource = da850_edma_resources,
+};
+
+int __init da830_register_edma(struct edma_rsv_info *rsv)
+{
+ da830_edma_cc0_info.rsv = rsv;
+
+ return platform_device_register(&da830_edma_device);
+}
+
+int __init da850_register_edma(struct edma_rsv_info *rsv[2])
+{
+ if (rsv) {
+ da850_edma_cc_info[0].rsv = rsv[0];
+ da850_edma_cc_info[1].rsv = rsv[1];
+ }
+
+ return platform_device_register(&da850_edma_device);
+}
+
+static struct resource da8xx_i2c_resources0[] = {
+ {
+ .start = DA8XX_I2C0_BASE,
+ .end = DA8XX_I2C0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_I2CINT0,
+ .end = IRQ_DA8XX_I2CINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_i2c_device0 = {
+ .name = "i2c_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da8xx_i2c_resources0),
+ .resource = da8xx_i2c_resources0,
+};
+
+static struct resource da8xx_i2c_resources1[] = {
+ {
+ .start = DA8XX_I2C1_BASE,
+ .end = DA8XX_I2C1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_I2CINT1,
+ .end = IRQ_DA8XX_I2CINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_i2c_device1 = {
+ .name = "i2c_davinci",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(da8xx_i2c_resources1),
+ .resource = da8xx_i2c_resources1,
+};
+
+int __init da8xx_register_i2c(int instance,
+ struct davinci_i2c_platform_data *pdata)
+{
+ struct platform_device *pdev;
+
+ if (instance == 0)
+ pdev = &da8xx_i2c_device0;
+ else if (instance == 1)
+ pdev = &da8xx_i2c_device1;
+ else
+ return -EINVAL;
+
+ pdev->dev.platform_data = pdata;
+ return platform_device_register(pdev);
+}
+
+static struct resource da8xx_watchdog_resources[] = {
+ {
+ .start = DA8XX_WDOG_BASE,
+ .end = DA8XX_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device da8xx_wdt_device = {
+ .name = "watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_watchdog_resources),
+ .resource = da8xx_watchdog_resources,
+};
+
+int __init da8xx_register_watchdog(void)
+{
+ return platform_device_register(&da8xx_wdt_device);
+}
+
+static struct resource da8xx_emac_resources[] = {
+ {
+ .start = DA8XX_EMAC_CPPI_PORT_BASE,
+ .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_C0_RX_THRESH_PULSE,
+ .end = IRQ_DA8XX_C0_RX_THRESH_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_RX_PULSE,
+ .end = IRQ_DA8XX_C0_RX_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_TX_PULSE,
+ .end = IRQ_DA8XX_C0_TX_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DA8XX_C0_MISC_PULSE,
+ .end = IRQ_DA8XX_C0_MISC_PULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct emac_platform_data da8xx_emac_pdata = {
+ .ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET,
+ .ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET,
+ .ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET,
+ .ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct platform_device da8xx_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &da8xx_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(da8xx_emac_resources),
+ .resource = da8xx_emac_resources,
+};
+
+static struct resource da8xx_mdio_resources[] = {
+ {
+ .start = DA8XX_EMAC_MDIO_BASE,
+ .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device da8xx_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_mdio_resources),
+ .resource = da8xx_mdio_resources,
+};
+
+int __init da8xx_register_emac(void)
+{
+ int ret;
+
+ ret = platform_device_register(&da8xx_mdio_device);
+ if (ret < 0)
+ return ret;
+ ret = platform_device_register(&da8xx_emac_device);
+ if (ret < 0)
+ return ret;
+ ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev),
+ NULL, &da8xx_emac_device.dev);
+ return ret;
+}
+
+static struct resource da830_mcasp1_resources[] = {
+ {
+ .name = "mcasp1",
+ .start = DAVINCI_DA830_MCASP1_REG_BASE,
+ .end = DAVINCI_DA830_MCASP1_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .start = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .start = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .end = DAVINCI_DA830_DMA_MCASP1_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da830_mcasp1_device = {
+ .name = "davinci-mcasp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da830_mcasp1_resources),
+ .resource = da830_mcasp1_resources,
+};
+
+static struct resource da850_mcasp_resources[] = {
+ {
+ .name = "mcasp",
+ .start = DAVINCI_DA8XX_MCASP0_REG_BASE,
+ .end = DAVINCI_DA8XX_MCASP0_REG_BASE + (SZ_1K * 12) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* TX event */
+ {
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AXEVT,
+ .flags = IORESOURCE_DMA,
+ },
+ /* RX event */
+ {
+ .start = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .end = DAVINCI_DA8XX_DMA_MCASP0_AREVT,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da850_mcasp_device = {
+ .name = "davinci-mcasp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da850_mcasp_resources),
+ .resource = da850_mcasp_resources,
+};
+
+static struct platform_device davinci_pcm_device = {
+ .name = "davinci-pcm-audio",
+ .id = -1,
+};
+
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
+{
+ platform_device_register(&davinci_pcm_device);
+
+ /* DA830/OMAP-L137 has 3 instances of McASP */
+ if (cpu_is_davinci_da830() && id == 1) {
+ da830_mcasp1_device.dev.platform_data = pdata;
+ platform_device_register(&da830_mcasp1_device);
+ } else if (cpu_is_davinci_da850()) {
+ da850_mcasp_device.dev.platform_data = pdata;
+ platform_device_register(&da850_mcasp_device);
+ }
+}
+
+static const struct display_panel disp_panel = {
+ QVGA,
+ 16,
+ 16,
+ COLOR_ACTIVE,
+};
+
+static struct lcd_ctrl_config lcd_cfg = {
+ &disp_panel,
+ .ac_bias = 255,
+ .ac_bias_intrpt = 0,
+ .dma_burst_sz = 16,
+ .bpp = 16,
+ .fdd = 255,
+ .tft_alt_mode = 0,
+ .stn_565_mode = 0,
+ .mono_8bit_mode = 0,
+ .invert_line_clock = 1,
+ .invert_frm_clock = 1,
+ .sync_edge = 0,
+ .sync_ctrl = 1,
+ .raster_order = 0,
+};
+
+struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
+ .manu_name = "sharp",
+ .controller_data = &lcd_cfg,
+ .type = "Sharp_LCD035Q3DG01",
+};
+
+struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = {
+ .manu_name = "sharp",
+ .controller_data = &lcd_cfg,
+ .type = "Sharp_LK043T1DG01",
+};
+
+static struct resource da8xx_lcdc_resources[] = {
+ [0] = { /* registers */
+ .start = DA8XX_LCD_CNTRL_BASE,
+ .end = DA8XX_LCD_CNTRL_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* interrupt */
+ .start = IRQ_DA8XX_LCDINT,
+ .end = IRQ_DA8XX_LCDINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_lcdc_device = {
+ .name = "da8xx_lcdc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_lcdc_resources),
+ .resource = da8xx_lcdc_resources,
+};
+
+int __init da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata)
+{
+ da8xx_lcdc_device.dev.platform_data = pdata;
+ return platform_device_register(&da8xx_lcdc_device);
+}
+
+static struct resource da8xx_mmcsd0_resources[] = {
+ { /* registers */
+ .start = DA8XX_MMCSD0_BASE,
+ .end = DA8XX_MMCSD0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA8XX_MMCSDINT0,
+ .end = IRQ_DA8XX_MMCSDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* DMA RX */
+ .start = DA8XX_DMA_MMCSD0_RX,
+ .end = DA8XX_DMA_MMCSD0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ { /* DMA TX */
+ .start = DA8XX_DMA_MMCSD0_TX,
+ .end = DA8XX_DMA_MMCSD0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da8xx_mmcsd0_device = {
+ .name = "davinci_mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources),
+ .resource = da8xx_mmcsd0_resources,
+};
+
+int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config)
+{
+ da8xx_mmcsd0_device.dev.platform_data = config;
+ return platform_device_register(&da8xx_mmcsd0_device);
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+static struct resource da850_mmcsd1_resources[] = {
+ { /* registers */
+ .start = DA850_MMCSD1_BASE,
+ .end = DA850_MMCSD1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* interrupt */
+ .start = IRQ_DA850_MMCSDINT0_1,
+ .end = IRQ_DA850_MMCSDINT0_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* DMA RX */
+ .start = DA850_DMA_MMCSD1_RX,
+ .end = DA850_DMA_MMCSD1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ { /* DMA TX */
+ .start = DA850_DMA_MMCSD1_TX,
+ .end = DA850_DMA_MMCSD1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device da850_mmcsd1_device = {
+ .name = "davinci_mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da850_mmcsd1_resources),
+ .resource = da850_mmcsd1_resources,
+};
+
+int __init da850_register_mmcsd1(struct davinci_mmc_config *config)
+{
+ da850_mmcsd1_device.dev.platform_data = config;
+ return platform_device_register(&da850_mmcsd1_device);
+}
+#endif
+
+static struct resource da8xx_rtc_resources[] = {
+ {
+ .start = DA8XX_RTC_BASE,
+ .end = DA8XX_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ { /* timer irq */
+ .start = IRQ_DA8XX_RTC,
+ .end = IRQ_DA8XX_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* alarm irq */
+ .start = IRQ_DA8XX_RTC,
+ .end = IRQ_DA8XX_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device da8xx_rtc_device = {
+ .name = "omap_rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(da8xx_rtc_resources),
+ .resource = da8xx_rtc_resources,
+};
+
+int da8xx_register_rtc(void)
+{
+ int ret;
+ void __iomem *base;
+
+ base = ioremap(DA8XX_RTC_BASE, SZ_4K);
+ if (WARN_ON(!base))
+ return -ENOMEM;
+
+ /* Unlock the rtc's registers */
+ __raw_writel(0x83e70b13, base + 0x6c);
+ __raw_writel(0x95a4f1e0, base + 0x70);
+
+ iounmap(base);
+
+ ret = platform_device_register(&da8xx_rtc_device);
+ if (!ret)
+ /* Atleast on DA850, RTC is a wakeup source */
+ device_init_wakeup(&da8xx_rtc_device.dev, true);
+
+ return ret;
+}
+
+static void __iomem *da8xx_ddr2_ctlr_base;
+void __iomem * __init da8xx_get_mem_ctlr(void)
+{
+ if (da8xx_ddr2_ctlr_base)
+ return da8xx_ddr2_ctlr_base;
+
+ da8xx_ddr2_ctlr_base = ioremap(DA8XX_DDR2_CTL_BASE, SZ_32K);
+ if (!da8xx_ddr2_ctlr_base)
+ pr_warning("%s: Unable to map DDR2 controller", __func__);
+
+ return da8xx_ddr2_ctlr_base;
+}
+
+static struct resource da8xx_cpuidle_resources[] = {
+ {
+ .start = DA8XX_DDR2_CTL_BASE,
+ .end = DA8XX_DDR2_CTL_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/* DA8XX devices support DDR2 power down */
+static struct davinci_cpuidle_config da8xx_cpuidle_pdata = {
+ .ddr2_pdown = 1,
+};
+
+
+static struct platform_device da8xx_cpuidle_device = {
+ .name = "cpuidle-davinci",
+ .num_resources = ARRAY_SIZE(da8xx_cpuidle_resources),
+ .resource = da8xx_cpuidle_resources,
+ .dev = {
+ .platform_data = &da8xx_cpuidle_pdata,
+ },
+};
+
+int __init da8xx_register_cpuidle(void)
+{
+ da8xx_cpuidle_pdata.ddr2_ctlr_base = da8xx_get_mem_ctlr();
+
+ return platform_device_register(&da8xx_cpuidle_device);
+}
+
+static struct resource da8xx_spi0_resources[] = {
+ [0] = {
+ .start = DA8XX_SPI0_BASE,
+ .end = DA8XX_SPI0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_SPINT0,
+ .end = IRQ_DA8XX_SPINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DA8XX_DMA_SPI0_RX,
+ .end = DA8XX_DMA_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DA8XX_DMA_SPI0_TX,
+ .end = DA8XX_DMA_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource da8xx_spi1_resources[] = {
+ [0] = {
+ .start = DA830_SPI1_BASE,
+ .end = DA830_SPI1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_SPINT1,
+ .end = IRQ_DA8XX_SPINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DA8XX_DMA_SPI1_RX,
+ .end = DA8XX_DMA_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DA8XX_DMA_SPI1_TX,
+ .end = DA8XX_DMA_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct davinci_spi_platform_data da8xx_spi_pdata[] = {
+ [0] = {
+ .version = SPI_VERSION_2,
+ .intr_line = 1,
+ .dma_event_q = EVENTQ_0,
+ },
+ [1] = {
+ .version = SPI_VERSION_2,
+ .intr_line = 1,
+ .dma_event_q = EVENTQ_0,
+ },
+};
+
+static struct platform_device da8xx_spi_device[] = {
+ [0] = {
+ .name = "spi_davinci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(da8xx_spi0_resources),
+ .resource = da8xx_spi0_resources,
+ .dev = {
+ .platform_data = &da8xx_spi_pdata[0],
+ },
+ },
+ [1] = {
+ .name = "spi_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(da8xx_spi1_resources),
+ .resource = da8xx_spi1_resources,
+ .dev = {
+ .platform_data = &da8xx_spi_pdata[1],
+ },
+ },
+};
+
+int __init da8xx_register_spi(int instance, struct spi_board_info *info,
+ unsigned len)
+{
+ int ret;
+
+ if (instance < 0 || instance > 1)
+ return -EINVAL;
+
+ ret = spi_register_board_info(info, len);
+ if (ret)
+ pr_warning("%s: failed to register board info for spi %d :"
+ " %d\n", __func__, instance, ret);
+
+ da8xx_spi_pdata[instance].num_chipselect = len;
+
+ if (instance == 1 && cpu_is_davinci_da850()) {
+ da8xx_spi1_resources[0].start = DA850_SPI1_BASE;
+ da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1;
+ }
+
+ return platform_device_register(&da8xx_spi_device[instance]);
+}
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
new file mode 100644
index 00000000..6162cae7
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -0,0 +1,408 @@
+/*
+ * Texas Instruments TNETV107X SoC devices
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_TPCC_BASE 0x01c00000
+#define TNETV107X_TPTC0_BASE 0x01c10000
+#define TNETV107X_TPTC1_BASE 0x01c10400
+#define TNETV107X_WDOG_BASE 0x08086700
+#define TNETV107X_TSC_BASE 0x08088500
+#define TNETV107X_SDIO0_BASE 0x08088700
+#define TNETV107X_SDIO1_BASE 0x08088800
+#define TNETV107X_KEYPAD_BASE 0x08088a00
+#define TNETV107X_SSP_BASE 0x08088c00
+#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000
+#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x44000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x48000000
+
+/* TNETV107X specific EDMA3 information */
+#define EDMA_TNETV107X_NUM_DMACH 64
+#define EDMA_TNETV107X_NUM_TCC 64
+#define EDMA_TNETV107X_NUM_PARAMENTRY 128
+#define EDMA_TNETV107X_NUM_EVQUE 2
+#define EDMA_TNETV107X_NUM_TC 2
+#define EDMA_TNETV107X_CHMAP_EXIST 0
+#define EDMA_TNETV107X_NUM_REGIONS 4
+#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u
+#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu
+
+#define TNETV107X_DMACH_SDIO0_RX 26
+#define TNETV107X_DMACH_SDIO0_TX 27
+#define TNETV107X_DMACH_SDIO1_RX 28
+#define TNETV107X_DMACH_SDIO1_TX 29
+
+static const s8 edma_tc_mapping[][2] = {
+ /* event queue no TC no */
+ { 0, 0 },
+ { 1, 1 },
+ { -1, -1 }
+};
+
+static const s8 edma_priority_mapping[][2] = {
+ /* event queue no Prio */
+ { 0, 3 },
+ { 1, 7 },
+ { -1, -1 }
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = EDMA_TNETV107X_NUM_DMACH,
+ .n_region = EDMA_TNETV107X_NUM_REGIONS,
+ .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
+ .n_tc = EDMA_TNETV107X_NUM_TC,
+ .n_cc = 1,
+ .queue_tc_mapping = edma_tc_mapping,
+ .queue_priority_mapping = edma_priority_mapping,
+};
+
+static struct edma_soc_info *tnetv107x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = TNETV107X_TPCC_BASE,
+ .end = TNETV107X_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = TNETV107X_TPTC0_BASE,
+ .end = TNETV107X_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = TNETV107X_TPTC1_BASE,
+ .end = TNETV107X_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_TNETV107X_TPCC,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_TNETV107X_TPCC_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device edma_device = {
+ .name = "edma",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+ .dev.platform_data = tnetv107x_edma_info,
+};
+
+static struct plat_serial8250_port serial_data[] = {
+ {
+ .mapbase = TNETV107X_UART0_BASE,
+ .irq = IRQ_TNETV107X_UART0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART1_BASE,
+ .irq = IRQ_TNETV107X_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART2_BASE,
+ .irq = IRQ_TNETV107X_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ },
+};
+
+struct platform_device tnetv107x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = serial_data,
+};
+
+static struct resource mmc0_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO0_BASE,
+ .end = TNETV107X_SDIO0_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static struct resource mmc1_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO1_BASE,
+ .end = TNETV107X_SDIO1_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static u64 mmc0_dma_mask = DMA_BIT_MASK(32);
+static u64 mmc1_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device mmc_devices[2] = {
+ {
+ .name = "davinci_mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+ .resource = mmc0_resources
+ },
+ {
+ .name = "davinci_mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+ .resource = mmc1_resources
+ },
+};
+
+static const u32 emif_windows[] = {
+ TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,
+ TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,
+};
+
+static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };
+
+static struct resource wdt_resources[] = {
+ {
+ .start = TNETV107X_WDOG_BASE,
+ .end = TNETV107X_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tnetv107x_wdt_device = {
+ .name = "tnetv107x_wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
+{
+ struct resource res[2];
+ struct platform_device *pdev;
+ u32 range;
+ int ret;
+
+ /* Figure out the resource range from the ale/cle masks */
+ range = max(data->mask_cle, data->mask_ale);
+ range = PAGE_ALIGN(range + 4) - 1;
+
+ if (range >= emif_window_sizes[chipsel])
+ return -EINVAL;
+
+ pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->name = "davinci_nand";
+ pdev->id = chipsel;
+ pdev->dev.platform_data = data;
+
+ memset(res, 0, sizeof(res));
+
+ res[0].start = emif_windows[chipsel];
+ res[0].end = res[0].start + range;
+ res[0].flags = IORESOURCE_MEM;
+
+ res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE;
+ res[1].end = res[1].start + SZ_4K - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret < 0) {
+ kfree(pdev);
+ return ret;
+ }
+
+ return platform_device_register(pdev);
+}
+
+static struct resource keypad_resources[] = {
+ {
+ .start = TNETV107X_KEYPAD_BASE,
+ .end = TNETV107X_KEYPAD_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ .name = "press",
+ },
+ {
+ .start = IRQ_TNETV107X_KEYPAD_FREE,
+ .flags = IORESOURCE_IRQ,
+ .name = "release",
+ },
+};
+
+static struct platform_device keypad_device = {
+ .name = "tnetv107x-keypad",
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
+
+static struct resource tsc_resources[] = {
+ {
+ .start = TNETV107X_TSC_BASE,
+ .end = TNETV107X_TSC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tsc_device = {
+ .name = "tnetv107x-ts",
+ .num_resources = ARRAY_SIZE(tsc_resources),
+ .resource = tsc_resources,
+};
+
+static struct resource ssp_resources[] = {
+ {
+ .start = TNETV107X_SSP_BASE,
+ .end = TNETV107X_SSP_BASE + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TNETV107X_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ssp_device = {
+ .name = "ti-ssp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ssp_resources),
+ .resource = ssp_resources,
+};
+
+void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
+{
+ int i, error;
+ struct clk *tsc_clk;
+
+ /*
+ * The reset defaults for tnetv107x tsc clock divider is set too high.
+ * This forces the clock down to a range that allows the ADC to
+ * complete sample conversion in time.
+ */
+ tsc_clk = clk_get(NULL, "sys_tsc_clk");
+ if (tsc_clk) {
+ error = clk_set_rate(tsc_clk, 5000000);
+ WARN_ON(error < 0);
+ clk_put(tsc_clk);
+ }
+
+ platform_device_register(&edma_device);
+ platform_device_register(&tnetv107x_wdt_device);
+ platform_device_register(&tsc_device);
+
+ if (info->serial_config)
+ davinci_serial_init(info->serial_config);
+
+ for (i = 0; i < 2; i++)
+ if (info->mmc_config[i]) {
+ mmc_devices[i].dev.platform_data = info->mmc_config[i];
+ platform_device_register(&mmc_devices[i]);
+ }
+
+ for (i = 0; i < 4; i++)
+ if (info->nand_config[i])
+ nand_init(i, info->nand_config[i]);
+
+ if (info->keypad_config) {
+ keypad_device.dev.platform_data = info->keypad_config;
+ platform_device_register(&keypad_device);
+ }
+
+ if (info->ssp_config) {
+ ssp_device.dev.platform_data = info->ssp_config;
+ platform_device_register(&ssp_device);
+ }
+}
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
new file mode 100644
index 00000000..806a2f02
--- /dev/null
+++ b/arch/arm/mach-davinci/devices.c
@@ -0,0 +1,339 @@
+/*
+ * mach-davinci/devices.c
+ *
+ * DaVinci platform device setup/initialization
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/i2c.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/mux.h>
+#include <mach/edma.h>
+#include <mach/mmc.h>
+#include <mach/time.h>
+
+#include "clock.h"
+
+#define DAVINCI_I2C_BASE 0x01C21000
+#define DAVINCI_ATA_BASE 0x01C66000
+#define DAVINCI_MMCSD0_BASE 0x01E10000
+#define DM355_MMCSD0_BASE 0x01E11000
+#define DM355_MMCSD1_BASE 0x01E00000
+#define DM365_MMCSD0_BASE 0x01D11000
+#define DM365_MMCSD1_BASE 0x01D00000
+
+/* System control register offsets */
+#define DM64XX_VDD3P3V_PWDN 0x48
+
+static struct resource i2c_resources[] = {
+ {
+ .start = DAVINCI_I2C_BASE,
+ .end = DAVINCI_I2C_BASE + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device davinci_i2c_device = {
+ .name = "i2c_davinci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(i2c_resources),
+ .resource = i2c_resources,
+};
+
+void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata)
+{
+ if (cpu_is_davinci_dm644x())
+ davinci_cfg_reg(DM644X_I2C);
+
+ davinci_i2c_device.dev.platform_data = pdata;
+ (void) platform_device_register(&davinci_i2c_device);
+}
+
+static struct resource ide_resources[] = {
+ {
+ .start = DAVINCI_ATA_BASE,
+ .end = DAVINCI_ATA_BASE + 0x7ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_IDE,
+ .end = IRQ_IDE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ide_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ide_device = {
+ .name = "palm_bk3710",
+ .id = -1,
+ .resource = ide_resources,
+ .num_resources = ARRAY_SIZE(ide_resources),
+ .dev = {
+ .dma_mask = &ide_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init davinci_init_ide(void)
+{
+ if (cpu_is_davinci_dm644x()) {
+ davinci_cfg_reg(DM644X_HPIEN_DISABLE);
+ davinci_cfg_reg(DM644X_ATAEN);
+ davinci_cfg_reg(DM644X_HDIREN);
+ } else if (cpu_is_davinci_dm646x()) {
+ /* IRQ_DM646X_IDE is the same as IRQ_IDE */
+ davinci_cfg_reg(DM646X_ATAEN);
+ } else {
+ WARN_ON(1);
+ return;
+ }
+
+ platform_device_register(&ide_device);
+}
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+
+static u64 mmcsd0_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource mmcsd0_resources[] = {
+ {
+ /* different on dm355 */
+ .start = DAVINCI_MMCSD0_BASE,
+ .end = DAVINCI_MMCSD0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* IRQs: MMC/SD, then SDIO */
+ {
+ .start = IRQ_MMCINT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* different on dm355 */
+ .start = IRQ_SDIOINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* DMA channels: RX, then TX */
+ {
+ .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT),
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCTXEVT),
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device davinci_mmcsd0_device = {
+ .name = "davinci_mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmcsd0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmcsd0_resources),
+ .resource = mmcsd0_resources,
+};
+
+static u64 mmcsd1_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource mmcsd1_resources[] = {
+ {
+ .start = DM355_MMCSD1_BASE,
+ .end = DM355_MMCSD1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* IRQs: MMC/SD, then SDIO */
+ {
+ .start = IRQ_DM355_MMCINT1,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_DM355_SDIOINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* DMA channels: RX, then TX */
+ {
+ .start = EDMA_CTLR_CHAN(0, 30), /* rx */
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = EDMA_CTLR_CHAN(0, 31), /* tx */
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device davinci_mmcsd1_device = {
+ .name = "davinci_mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmcsd1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmcsd1_resources),
+ .resource = mmcsd1_resources,
+};
+
+
+void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
+{
+ struct platform_device *pdev = NULL;
+
+ if (WARN_ON(cpu_is_davinci_dm646x()))
+ return;
+
+ /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too;
+ * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused.
+ *
+ * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are
+ * not handled right here ...
+ */
+ switch (module) {
+ case 1:
+ if (cpu_is_davinci_dm355()) {
+ /* REVISIT we may not need all these pins if e.g. this
+ * is a hard-wired SDIO device...
+ */
+ davinci_cfg_reg(DM355_SD1_CMD);
+ davinci_cfg_reg(DM355_SD1_CLK);
+ davinci_cfg_reg(DM355_SD1_DATA0);
+ davinci_cfg_reg(DM355_SD1_DATA1);
+ davinci_cfg_reg(DM355_SD1_DATA2);
+ davinci_cfg_reg(DM355_SD1_DATA3);
+ } else if (cpu_is_davinci_dm365()) {
+ void __iomem *pupdctl1 =
+ IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c);
+
+ /* Configure pull down control */
+ __raw_writel((__raw_readl(pupdctl1) & ~0xfc0),
+ pupdctl1);
+
+ mmcsd1_resources[0].start = DM365_MMCSD1_BASE;
+ mmcsd1_resources[0].end = DM365_MMCSD1_BASE +
+ SZ_4K - 1;
+ mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1;
+ } else
+ break;
+
+ pdev = &davinci_mmcsd1_device;
+ break;
+ case 0:
+ if (cpu_is_davinci_dm355()) {
+ mmcsd0_resources[0].start = DM355_MMCSD0_BASE;
+ mmcsd0_resources[0].end = DM355_MMCSD0_BASE + SZ_4K - 1;
+ mmcsd0_resources[2].start = IRQ_DM355_SDIOINT0;
+
+ /* expose all 6 MMC0 signals: CLK, CMD, DATA[0..3] */
+ davinci_cfg_reg(DM355_MMCSD0);
+
+ /* enable RX EDMA */
+ davinci_cfg_reg(DM355_EVT26_MMC0_RX);
+ } else if (cpu_is_davinci_dm365()) {
+ mmcsd0_resources[0].start = DM365_MMCSD0_BASE;
+ mmcsd0_resources[0].end = DM365_MMCSD0_BASE +
+ SZ_4K - 1;
+ mmcsd0_resources[2].start = IRQ_DM365_SDIOINT0;
+ } else if (cpu_is_davinci_dm644x()) {
+ /* REVISIT: should this be in board-init code? */
+ void __iomem *base =
+ IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+
+ /* Power-on 3.3V IO cells */
+ __raw_writel(0, base + DM64XX_VDD3P3V_PWDN);
+ /*Set up the pull regiter for MMC */
+ davinci_cfg_reg(DM644X_MSTK);
+ }
+
+ pdev = &davinci_mmcsd0_device;
+ break;
+ }
+
+ if (WARN_ON(!pdev))
+ return;
+
+ pdev->dev.platform_data = config;
+ platform_device_register(pdev);
+}
+
+#else
+
+void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config)
+{
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static struct resource wdt_resources[] = {
+ {
+ .start = DAVINCI_WDOG_BASE,
+ .end = DAVINCI_WDOG_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device davinci_wdt_device = {
+ .name = "watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void davinci_init_wdt(void)
+{
+ platform_device_register(&davinci_wdt_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct platform_device davinci_pcm_device = {
+ .name = "davinci-pcm-audio",
+ .id = -1,
+};
+
+static void davinci_init_pcm(void)
+{
+ platform_device_register(&davinci_pcm_device);
+}
+
+/*-------------------------------------------------------------------------*/
+
+struct davinci_timer_instance davinci_timer_instance[2] = {
+ {
+ .base = DAVINCI_TIMER0_BASE,
+ .bottom_irq = IRQ_TINT0_TINT12,
+ .top_irq = IRQ_TINT0_TINT34,
+ },
+ {
+ .base = DAVINCI_TIMER1_BASE,
+ .bottom_irq = IRQ_TINT1_TINT12,
+ .top_irq = IRQ_TINT1_TINT34,
+ },
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int __init davinci_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ davinci_init_pcm();
+ davinci_init_wdt();
+
+ return 0;
+}
+arch_initcall(davinci_init_devices);
+
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
new file mode 100644
index 00000000..a3a94e9c
--- /dev/null
+++ b/arch/arm/mach-davinci/dm355.c
@@ -0,0 +1,892 @@
+/*
+ * TI DaVinci DM355 chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <linux/spi/spi.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm355.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/spi.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DM355_UART2_BASE (IO_PHYS + 0x206000)
+
+/*
+ * Device specific clocks
+ */
+#define DM355_REF_FREQ 24000000 /* 24 or 36 MHz */
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+ .flags = PLL_HAS_PREDIV | PLL_HAS_POSTDIV,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+ .flags = PLL_HAS_PREDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ /* FIXME -- crystal rate is board-specific */
+ .rate = DM355_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll1_data,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk vpss_dac_clk = {
+ .name = "vpss_dac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM355_LPSC_VPSS_DAC,
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk vpss_slave_clk = {
+ .name = "vpss_slave",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+static struct clk clkout1_clk = {
+ .name = "clkout1",
+ .parent = &pll1_aux_clk,
+ /* NOTE: clkout1 can be externally gated by muxing GPIO-18 */
+};
+
+static struct clk clkout2_clk = {
+ .name = "clkout2",
+ .parent = &pll1_sysclkbp,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll2_data,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclkbp = {
+ .name = "pll2_sysclkbp",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk clkout3_clk = {
+ .name = "clkout3",
+ .parent = &pll2_sysclkbp,
+ /* NOTE: clkout3 can be externally gated by muxing GPIO-16 */
+};
+
+static struct clk arm_clk = {
+ .name = "arm_clk",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+/*
+ * NOT LISTED below, and not touched by Linux
+ * - in SyncReset state by default
+ * .lpsc = DAVINCI_LPSC_TPCC,
+ * .lpsc = DAVINCI_LPSC_TPTC0,
+ * .lpsc = DAVINCI_LPSC_TPTC1,
+ * .lpsc = DAVINCI_LPSC_DDR_EMIF, .parent = &sysclk2_clk,
+ * .lpsc = DAVINCI_LPSC_MEMSTICK,
+ * - in Enabled state by default
+ * .lpsc = DAVINCI_LPSC_SYSTEM_SUBSYS,
+ * .lpsc = DAVINCI_LPSC_SCR2, // "bus"
+ * .lpsc = DAVINCI_LPSC_SCR3, // "bus"
+ * .lpsc = DAVINCI_LPSC_SCR4, // "bus"
+ * .lpsc = DAVINCI_LPSC_CROSSBAR, // "emulation"
+ * .lpsc = DAVINCI_LPSC_CFG27, // "test"
+ * .lpsc = DAVINCI_LPSC_CFG3, // "test"
+ * .lpsc = DAVINCI_LPSC_CFG5, // "test"
+ */
+
+static struct clk mjcp_clk = {
+ .name = "mjcp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_IMCOP,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_UART2,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk asp0_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_McBSP,
+};
+
+static struct clk asp1_clk = {
+ .name = "asp1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_McBSP1,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_MMC_SD1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_SPI1,
+};
+
+static struct clk spi2_clk = {
+ .name = "spi2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM355_LPSC_SPI2,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk pwm3_clk = {
+ .name = "pwm3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_PWM3,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1, /* REVISIT: why can't this be disabled? */
+};
+
+static struct clk timer3_clk = {
+ .name = "timer3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_TIMER3,
+};
+
+static struct clk rto_clk = {
+ .name = "rto",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM355_LPSC_RTO,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk_lookup dm355_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "vpss_dac", &vpss_dac_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "vpss_slave", &vpss_slave_clk),
+ CLK(NULL, "clkout1", &clkout1_clk),
+ CLK(NULL, "clkout2", &clkout2_clk),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+ CLK(NULL, "clkout3", &clkout3_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "mjcp", &mjcp_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+ CLK("davinci-mcbsp.1", NULL, &asp1_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK("spi_davinci.2", NULL, &spi2_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "pwm3", &pwm3_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, "timer3", &timer3_clk),
+ CLK(NULL, "rto", &rto_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*----------------------------------------------------------------------*/
+
+static u64 dm355_spi0_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource dm355_spi0_resources[] = {
+ {
+ .start = 0x01c66000,
+ .end = 0x01c667ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM355_SPINT0_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct davinci_spi_platform_data dm355_spi0_pdata = {
+ .version = SPI_VERSION_1,
+ .num_chipselect = 2,
+ .cshold_bug = true,
+ .dma_event_q = EVENTQ_1,
+};
+static struct platform_device dm355_spi0_device = {
+ .name = "spi_davinci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dm355_spi0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm355_spi0_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm355_spi0_resources),
+ .resource = dm355_spi0_resources,
+};
+
+void __init dm355_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len)
+{
+ /* for now, assume we need MISO */
+ davinci_cfg_reg(DM355_SPI0_SDI);
+
+ /* not all slaves will be wired up */
+ if (chipselect_mask & BIT(0))
+ davinci_cfg_reg(DM355_SPI0_SDENA0);
+ if (chipselect_mask & BIT(1))
+ davinci_cfg_reg(DM355_SPI0_SDENA1);
+
+ spi_register_board_info(info, len);
+
+ platform_device_register(&dm355_spi0_device);
+}
+
+/*----------------------------------------------------------------------*/
+
+#define INTMUX 0x18
+#define EVTMUX 0x1c
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm355_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM355, MMCSD0, 4, 2, 1, 0, false)
+
+MUX_CFG(DM355, SD1_CLK, 3, 6, 1, 1, false)
+MUX_CFG(DM355, SD1_CMD, 3, 7, 1, 1, false)
+MUX_CFG(DM355, SD1_DATA3, 3, 8, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA2, 3, 10, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA1, 3, 12, 3, 1, false)
+MUX_CFG(DM355, SD1_DATA0, 3, 14, 3, 1, false)
+
+MUX_CFG(DM355, I2C_SDA, 3, 19, 1, 1, false)
+MUX_CFG(DM355, I2C_SCL, 3, 20, 1, 1, false)
+
+MUX_CFG(DM355, MCBSP0_BDX, 3, 0, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_X, 3, 1, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BFSX, 3, 2, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BDR, 3, 3, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_R, 3, 4, 1, 1, false)
+MUX_CFG(DM355, MCBSP0_BFSR, 3, 5, 1, 1, false)
+
+MUX_CFG(DM355, SPI0_SDI, 4, 1, 1, 0, false)
+MUX_CFG(DM355, SPI0_SDENA0, 4, 0, 1, 0, false)
+MUX_CFG(DM355, SPI0_SDENA1, 3, 28, 1, 1, false)
+
+INT_CFG(DM355, INT_EDMA_CC, 2, 1, 1, false)
+INT_CFG(DM355, INT_EDMA_TC0_ERR, 3, 1, 1, false)
+INT_CFG(DM355, INT_EDMA_TC1_ERR, 4, 1, 1, false)
+
+EVT_CFG(DM355, EVT8_ASP1_TX, 0, 1, 0, false)
+EVT_CFG(DM355, EVT9_ASP1_RX, 1, 1, 0, false)
+EVT_CFG(DM355, EVT26_MMC0_RX, 2, 1, 0, false)
+
+MUX_CFG(DM355, VOUT_FIELD, 1, 18, 3, 1, false)
+MUX_CFG(DM355, VOUT_FIELD_G70, 1, 18, 3, 0, false)
+MUX_CFG(DM355, VOUT_HVSYNC, 1, 16, 1, 0, false)
+MUX_CFG(DM355, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false)
+MUX_CFG(DM355, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false)
+
+MUX_CFG(DM355, VIN_PCLK, 0, 14, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_WEN, 0, 13, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_VD, 0, 12, 1, 1, false)
+MUX_CFG(DM355, VIN_CAM_HD, 0, 11, 1, 1, false)
+MUX_CFG(DM355, VIN_YIN_EN, 0, 10, 1, 1, false)
+MUX_CFG(DM355, VIN_CINL_EN, 0, 0, 0xff, 0x55, false)
+MUX_CFG(DM355, VIN_CINH_EN, 0, 8, 3, 3, false)
+#endif
+};
+
+static u8 dm355_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_DM355_CCDC_VDINT0] = 2,
+ [IRQ_DM355_CCDC_VDINT1] = 6,
+ [IRQ_DM355_CCDC_VDINT2] = 6,
+ [IRQ_DM355_IPIPE_HST] = 6,
+ [IRQ_DM355_H3AINT] = 6,
+ [IRQ_DM355_IPIPE_SDR] = 6,
+ [IRQ_DM355_IPIPEIFINT] = 6,
+ [IRQ_DM355_OSDINT] = 7,
+ [IRQ_DM355_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_USBINT] = 4,
+ [IRQ_DM355_RTOINT] = 4,
+ [IRQ_DM355_UARTINT2] = 7,
+ [IRQ_DM355_TINT6] = 7,
+ [IRQ_CCINT0] = 5, /* dma */
+ [IRQ_CCERRINT] = 5, /* dma */
+ [IRQ_TCERRINT0] = 5, /* dma */
+ [IRQ_TCERRINT] = 5, /* dma */
+ [IRQ_DM355_SPINT2_1] = 7,
+ [IRQ_DM355_TINT7] = 4,
+ [IRQ_DM355_SDIOINT0] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_DM355_MMCINT1] = 7,
+ [IRQ_DM355_PWMINT3] = 7,
+ [IRQ_DDRINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_DM355_SDIOINT1] = 4,
+ [IRQ_TINT0_TINT12] = 2, /* clockevent */
+ [IRQ_TINT0_TINT34] = 2, /* clocksource */
+ [IRQ_TINT1_TINT12] = 7, /* DSP timer */
+ [IRQ_TINT1_TINT34] = 7, /* system tick */
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 7,
+ [IRQ_PWMINT2] = 7,
+ [IRQ_I2C] = 3,
+ [IRQ_UARTINT0] = 3,
+ [IRQ_UARTINT1] = 3,
+ [IRQ_DM355_SPINT0_0] = 3,
+ [IRQ_DM355_SPINT0_1] = 3,
+ [IRQ_DM355_GPIO0] = 3,
+ [IRQ_DM355_GPIO1] = 7,
+ [IRQ_DM355_GPIO2] = 4,
+ [IRQ_DM355_GPIO3] = 4,
+ [IRQ_DM355_GPIO4] = 7,
+ [IRQ_DM355_GPIO5] = 7,
+ [IRQ_DM355_GPIO6] = 7,
+ [IRQ_DM355_GPIO7] = 7,
+ [IRQ_DM355_GPIO8] = 7,
+ [IRQ_DM355_GPIO9] = 7,
+ [IRQ_DM355_GPIOBNK0] = 7,
+ [IRQ_DM355_GPIOBNK1] = 7,
+ [IRQ_DM355_GPIOBNK2] = 7,
+ [IRQ_DM355_GPIOBNK3] = 7,
+ [IRQ_DM355_GPIOBNK4] = 7,
+ [IRQ_DM355_GPIOBNK5] = 7,
+ [IRQ_DM355_GPIOBNK6] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/*----------------------------------------------------------------------*/
+
+static const s8
+queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = queue_tc_mapping,
+ .queue_priority_mapping = queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm355_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using (or muxing) TC*_ERR */
+};
+
+static struct platform_device dm355_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm355_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm355_asp1_resources[] = {
+ {
+ .start = DAVINCI_ASP1_BASE,
+ .end = DAVINCI_ASP1_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP1_TX,
+ .end = DAVINCI_DMA_ASP1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP1_RX,
+ .end = DAVINCI_DMA_ASP1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm355_asp1_device = {
+ .name = "davinci-mcbsp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(dm355_asp1_resources),
+ .resource = dm355_asp1_resources,
+};
+
+static void dm355_ccdc_setup_pinmux(void)
+{
+ davinci_cfg_reg(DM355_VIN_PCLK);
+ davinci_cfg_reg(DM355_VIN_CAM_WEN);
+ davinci_cfg_reg(DM355_VIN_CAM_VD);
+ davinci_cfg_reg(DM355_VIN_CAM_HD);
+ davinci_cfg_reg(DM355_VIN_YIN_EN);
+ davinci_cfg_reg(DM355_VIN_CINL_EN);
+ davinci_cfg_reg(DM355_VIN_CINH_EN);
+}
+
+static struct resource dm355_vpss_resources[] = {
+ {
+ /* VPSS BL Base address */
+ .name = "vpss",
+ .start = 0x01c70800,
+ .end = 0x01c70800 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VPSS CLK Base address */
+ .name = "vpss",
+ .start = 0x01c70000,
+ .end = 0x01c70000 + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm355_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm355_vpss",
+ .num_resources = ARRAY_SIZE(dm355_vpss_resources),
+ .resource = dm355_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm355_ccdc_resource[] = {
+ /* CCDC Base address */
+ {
+ .flags = IORESOURCE_MEM,
+ .start = 0x01c70600,
+ .end = 0x01c70600 + 0x1ff,
+ },
+};
+static struct platform_device dm355_ccdc_dev = {
+ .name = "dm355_ccdc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm355_ccdc_resource),
+ .resource = dm355_ccdc_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = dm355_ccdc_setup_pinmux,
+ },
+};
+
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void dm355_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm355_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm355_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb73b,
+ .manufacturer = 0x00f,
+ .cpu_id = DAVINCI_CPU_ID_DM355,
+ .name = "dm355",
+ },
+};
+
+static u32 dm355_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+static struct davinci_timer_info dm355_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm355_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DM355_UART2_BASE,
+ .irq = IRQ_DM355_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm355_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm355_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm355 = {
+ .io_desc = dm355_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm355_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm355_ids,
+ .ids_num = ARRAY_SIZE(dm355_ids),
+ .cpu_clks = dm355_clks,
+ .psc_bases = dm355_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm355_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm355_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm355_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm355_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm355_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 104,
+ .gpio_irq = IRQ_DM355_GPIOBNK0,
+ .serial_dev = &dm355_serial_device,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata)
+{
+ /* we don't use ASP1 IRQs, or we'd need to mux them ... */
+ if (evt_enable & ASP1_TX_EVT_EN)
+ davinci_cfg_reg(DM355_EVT8_ASP1_TX);
+
+ if (evt_enable & ASP1_RX_EVT_EN)
+ davinci_cfg_reg(DM355_EVT9_ASP1_RX);
+
+ dm355_asp1_device.dev.platform_data = pdata;
+ platform_device_register(&dm355_asp1_device);
+}
+
+void __init dm355_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm355);
+}
+
+static int __init dm355_init_devices(void)
+{
+ if (!cpu_is_davinci_dm355())
+ return 0;
+
+ /* Add ccdc clock aliases */
+ clk_add_alias("master", dm355_ccdc_dev.name, "vpss_master", NULL);
+ clk_add_alias("slave", dm355_ccdc_dev.name, "vpss_master", NULL);
+ davinci_cfg_reg(DM355_INT_EDMA_CC);
+ platform_device_register(&dm355_edma_device);
+ platform_device_register(&dm355_vpss_device);
+ platform_device_register(&dm355_ccdc_dev);
+ platform_device_register(&vpfe_capture_dev);
+
+ return 0;
+}
+postcore_initcall(dm355_init_devices);
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
new file mode 100644
index 00000000..4604e72d
--- /dev/null
+++ b/arch/arm/mach-davinci/dm365.c
@@ -0,0 +1,1245 @@
+/*
+ * TI DaVinci DM365 chip specific setup
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm365.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/irqs.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
+#include <mach/spi.h>
+
+
+#include "clock.h"
+#include "mux.h"
+
+#define DM365_REF_FREQ 24000000 /* 24 MHz on the DM365 EVM */
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+ .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+ .flags = PLL_HAS_POSTDIV | PLL_HAS_PREDIV,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DM365_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll1_data,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk clkout0_clk = {
+ .name = "clkout0",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll1_sysclk6",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk pll1_sysclk8 = {
+ .name = "pll1_sysclk8",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .flags = CLK_PLL,
+ .pll_data = &pll2_data,
+};
+
+static struct clk pll2_aux_clk = {
+ .name = "pll2_aux_clk",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk clkout1_clk = {
+ .name = "clkout1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+ .name = "pll2_sysclk2",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll2_sysclk3 = {
+ .name = "pll2_sysclk3",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll2_sysclk4 = {
+ .name = "pll2_sysclk4",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll2_sysclk5 = {
+ .name = "pll2_sysclk5",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll2_sysclk6 = {
+ .name = "pll2_sysclk6",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll2_sysclk7 = {
+ .name = "pll2_sysclk7",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV7,
+};
+
+static struct clk pll2_sysclk8 = {
+ .name = "pll2_sysclk8",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll2_sysclk9 = {
+ .name = "pll2_sysclk9",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk vpss_dac_clk = {
+ .name = "vpss_dac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM365_LPSC_DAC_CLK,
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk5,
+ .lpsc = DM365_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk arm_clk = {
+ .name = "arm_clk",
+ .parent = &pll2_sysclk2,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk mmcsd0_clk = {
+ .name = "mmcsd0",
+ .parent = &pll1_sysclk8,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk mmcsd1_clk = {
+ .name = "mmcsd1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_MMC_SD1,
+};
+
+static struct clk spi0_clk = {
+ .name = "spi0",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk spi1_clk = {
+ .name = "spi1",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI1,
+};
+
+static struct clk spi2_clk = {
+ .name = "spi2",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI2,
+};
+
+static struct clk spi3_clk = {
+ .name = "spi3",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_SPI3,
+};
+
+static struct clk spi4_clk = {
+ .name = "spi4",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM365_LPSC_SPI4,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk pwm3_clk = {
+ .name = "pwm3",
+ .parent = &ref_clk,
+ .lpsc = DM365_LPSC_PWM3,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1,
+};
+
+static struct clk timer3_clk = {
+ .name = "timer3",
+ .parent = &pll1_aux_clk,
+ .lpsc = DM365_LPSC_TIMER3,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_EMAC,
+};
+
+static struct clk voicecodec_clk = {
+ .name = "voice_codec",
+ .parent = &pll2_sysclk4,
+ .lpsc = DM365_LPSC_VOICE_CODEC,
+};
+
+static struct clk asp0_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_McBSP1,
+};
+
+static struct clk rto_clk = {
+ .name = "rto",
+ .parent = &pll1_sysclk4,
+ .lpsc = DM365_LPSC_RTO,
+};
+
+static struct clk mjcp_clk = {
+ .name = "mjcp",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM365_LPSC_MJCP,
+};
+
+static struct clk_lookup dm365_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "clkout0", &clkout0_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
+ CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_aux", &pll2_aux_clk),
+ CLK(NULL, "clkout1", &clkout1_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+ CLK(NULL, "pll2_sysclk3", &pll2_sysclk3),
+ CLK(NULL, "pll2_sysclk4", &pll2_sysclk4),
+ CLK(NULL, "pll2_sysclk5", &pll2_sysclk5),
+ CLK(NULL, "pll2_sysclk6", &pll2_sysclk6),
+ CLK(NULL, "pll2_sysclk7", &pll2_sysclk7),
+ CLK(NULL, "pll2_sysclk8", &pll2_sysclk8),
+ CLK(NULL, "pll2_sysclk9", &pll2_sysclk9),
+ CLK(NULL, "vpss_dac", &vpss_dac_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
+ CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
+ CLK("spi_davinci.0", NULL, &spi0_clk),
+ CLK("spi_davinci.1", NULL, &spi1_clk),
+ CLK("spi_davinci.2", NULL, &spi2_clk),
+ CLK("spi_davinci.3", NULL, &spi3_clk),
+ CLK("spi_davinci.4", NULL, &spi4_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "pwm3", &pwm3_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, "timer3", &timer3_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("davinci_voicecodec", NULL, &voicecodec_clk),
+ CLK("davinci-mcbsp", NULL, &asp0_clk),
+ CLK(NULL, "rto", &rto_clk),
+ CLK(NULL, "mjcp", &mjcp_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+/*----------------------------------------------------------------------*/
+
+#define INTMUX 0x18
+#define EVTMUX 0x1c
+
+
+static const struct mux_config dm365_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM365, MMCSD0, 0, 24, 1, 0, false)
+
+MUX_CFG(DM365, SD1_CLK, 0, 16, 3, 1, false)
+MUX_CFG(DM365, SD1_CMD, 4, 30, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA3, 4, 28, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA2, 4, 26, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA1, 4, 24, 3, 1, false)
+MUX_CFG(DM365, SD1_DATA0, 4, 22, 3, 1, false)
+
+MUX_CFG(DM365, I2C_SDA, 3, 23, 3, 2, false)
+MUX_CFG(DM365, I2C_SCL, 3, 21, 3, 2, false)
+
+MUX_CFG(DM365, AEMIF_AR_A14, 2, 0, 3, 1, false)
+MUX_CFG(DM365, AEMIF_AR_BA0, 2, 0, 3, 2, false)
+MUX_CFG(DM365, AEMIF_A3, 2, 2, 3, 1, false)
+MUX_CFG(DM365, AEMIF_A7, 2, 4, 3, 1, false)
+MUX_CFG(DM365, AEMIF_D15_8, 2, 6, 1, 1, false)
+MUX_CFG(DM365, AEMIF_CE0, 2, 7, 1, 0, false)
+MUX_CFG(DM365, AEMIF_CE1, 2, 8, 1, 0, false)
+MUX_CFG(DM365, AEMIF_WE_OE, 2, 9, 1, 0, false)
+
+MUX_CFG(DM365, MCBSP0_BDX, 0, 23, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_X, 0, 22, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BFSX, 0, 21, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BDR, 0, 20, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_R, 0, 19, 1, 1, false)
+MUX_CFG(DM365, MCBSP0_BFSR, 0, 18, 1, 1, false)
+
+MUX_CFG(DM365, SPI0_SCLK, 3, 28, 1, 1, false)
+MUX_CFG(DM365, SPI0_SDI, 3, 26, 3, 1, false)
+MUX_CFG(DM365, SPI0_SDO, 3, 25, 1, 1, false)
+MUX_CFG(DM365, SPI0_SDENA0, 3, 29, 3, 1, false)
+MUX_CFG(DM365, SPI0_SDENA1, 3, 26, 3, 2, false)
+
+MUX_CFG(DM365, UART0_RXD, 3, 20, 1, 1, false)
+MUX_CFG(DM365, UART0_TXD, 3, 19, 1, 1, false)
+MUX_CFG(DM365, UART1_RXD, 3, 17, 3, 2, false)
+MUX_CFG(DM365, UART1_TXD, 3, 15, 3, 2, false)
+MUX_CFG(DM365, UART1_RTS, 3, 23, 3, 1, false)
+MUX_CFG(DM365, UART1_CTS, 3, 21, 3, 1, false)
+
+MUX_CFG(DM365, EMAC_TX_EN, 3, 17, 3, 1, false)
+MUX_CFG(DM365, EMAC_TX_CLK, 3, 15, 3, 1, false)
+MUX_CFG(DM365, EMAC_COL, 3, 14, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD3, 3, 13, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD2, 3, 12, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD1, 3, 11, 1, 1, false)
+MUX_CFG(DM365, EMAC_TXD0, 3, 10, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD3, 3, 9, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD2, 3, 8, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD1, 3, 7, 1, 1, false)
+MUX_CFG(DM365, EMAC_RXD0, 3, 6, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_CLK, 3, 5, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_DV, 3, 4, 1, 1, false)
+MUX_CFG(DM365, EMAC_RX_ER, 3, 3, 1, 1, false)
+MUX_CFG(DM365, EMAC_CRS, 3, 2, 1, 1, false)
+MUX_CFG(DM365, EMAC_MDIO, 3, 1, 1, 1, false)
+MUX_CFG(DM365, EMAC_MDCLK, 3, 0, 1, 1, false)
+
+MUX_CFG(DM365, KEYSCAN, 2, 0, 0x3f, 0x3f, false)
+
+MUX_CFG(DM365, PWM0, 1, 0, 3, 2, false)
+MUX_CFG(DM365, PWM0_G23, 3, 26, 3, 3, false)
+MUX_CFG(DM365, PWM1, 1, 2, 3, 2, false)
+MUX_CFG(DM365, PWM1_G25, 3, 29, 3, 2, false)
+MUX_CFG(DM365, PWM2_G87, 1, 10, 3, 2, false)
+MUX_CFG(DM365, PWM2_G88, 1, 8, 3, 2, false)
+MUX_CFG(DM365, PWM2_G89, 1, 6, 3, 2, false)
+MUX_CFG(DM365, PWM2_G90, 1, 4, 3, 2, false)
+MUX_CFG(DM365, PWM3_G80, 1, 20, 3, 3, false)
+MUX_CFG(DM365, PWM3_G81, 1, 18, 3, 3, false)
+MUX_CFG(DM365, PWM3_G85, 1, 14, 3, 2, false)
+MUX_CFG(DM365, PWM3_G86, 1, 12, 3, 2, false)
+
+MUX_CFG(DM365, SPI1_SCLK, 4, 2, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDI, 3, 31, 1, 1, false)
+MUX_CFG(DM365, SPI1_SDO, 4, 0, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDENA0, 4, 4, 3, 1, false)
+MUX_CFG(DM365, SPI1_SDENA1, 4, 0, 3, 2, false)
+
+MUX_CFG(DM365, SPI2_SCLK, 4, 10, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDI, 4, 6, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDO, 4, 8, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDENA0, 4, 12, 3, 1, false)
+MUX_CFG(DM365, SPI2_SDENA1, 4, 8, 3, 2, false)
+
+MUX_CFG(DM365, SPI3_SCLK, 0, 0, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDI, 0, 2, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDO, 0, 6, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDENA0, 0, 4, 3, 2, false)
+MUX_CFG(DM365, SPI3_SDENA1, 0, 6, 3, 3, false)
+
+MUX_CFG(DM365, SPI4_SCLK, 4, 18, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDI, 4, 14, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDO, 4, 16, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDENA0, 4, 20, 3, 1, false)
+MUX_CFG(DM365, SPI4_SDENA1, 4, 16, 3, 2, false)
+
+MUX_CFG(DM365, CLKOUT0, 4, 20, 3, 3, false)
+MUX_CFG(DM365, CLKOUT1, 4, 16, 3, 3, false)
+MUX_CFG(DM365, CLKOUT2, 4, 8, 3, 3, false)
+
+MUX_CFG(DM365, GPIO20, 3, 21, 3, 0, false)
+MUX_CFG(DM365, GPIO30, 4, 6, 3, 0, false)
+MUX_CFG(DM365, GPIO31, 4, 8, 3, 0, false)
+MUX_CFG(DM365, GPIO32, 4, 10, 3, 0, false)
+MUX_CFG(DM365, GPIO33, 4, 12, 3, 0, false)
+MUX_CFG(DM365, GPIO40, 4, 26, 3, 0, false)
+MUX_CFG(DM365, GPIO64_57, 2, 6, 1, 0, false)
+
+MUX_CFG(DM365, VOUT_FIELD, 1, 18, 3, 1, false)
+MUX_CFG(DM365, VOUT_FIELD_G81, 1, 18, 3, 0, false)
+MUX_CFG(DM365, VOUT_HVSYNC, 1, 16, 1, 0, false)
+MUX_CFG(DM365, VOUT_COUTL_EN, 1, 0, 0xff, 0x55, false)
+MUX_CFG(DM365, VOUT_COUTH_EN, 1, 8, 0xff, 0x55, false)
+MUX_CFG(DM365, VIN_CAM_WEN, 0, 14, 3, 0, false)
+MUX_CFG(DM365, VIN_CAM_VD, 0, 13, 1, 0, false)
+MUX_CFG(DM365, VIN_CAM_HD, 0, 12, 1, 0, false)
+MUX_CFG(DM365, VIN_YIN4_7_EN, 0, 0, 0xff, 0, false)
+MUX_CFG(DM365, VIN_YIN0_3_EN, 0, 8, 0xf, 0, false)
+
+INT_CFG(DM365, INT_EDMA_CC, 2, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC0_ERR, 3, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC1_ERR, 4, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC2_ERR, 22, 1, 1, false)
+INT_CFG(DM365, INT_EDMA_TC3_ERR, 23, 1, 1, false)
+INT_CFG(DM365, INT_PRTCSS, 10, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_RXTHRESH, 14, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_RXPULSE, 15, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_TXPULSE, 16, 1, 1, false)
+INT_CFG(DM365, INT_EMAC_MISCPULSE, 17, 1, 1, false)
+INT_CFG(DM365, INT_IMX0_ENABLE, 0, 1, 0, false)
+INT_CFG(DM365, INT_IMX0_DISABLE, 0, 1, 1, false)
+INT_CFG(DM365, INT_HDVICP_ENABLE, 0, 1, 1, false)
+INT_CFG(DM365, INT_HDVICP_DISABLE, 0, 1, 0, false)
+INT_CFG(DM365, INT_IMX1_ENABLE, 24, 1, 1, false)
+INT_CFG(DM365, INT_IMX1_DISABLE, 24, 1, 0, false)
+INT_CFG(DM365, INT_NSF_ENABLE, 25, 1, 1, false)
+INT_CFG(DM365, INT_NSF_DISABLE, 25, 1, 0, false)
+
+EVT_CFG(DM365, EVT2_ASP_TX, 0, 1, 0, false)
+EVT_CFG(DM365, EVT3_ASP_RX, 1, 1, 0, false)
+EVT_CFG(DM365, EVT2_VC_TX, 0, 1, 1, false)
+EVT_CFG(DM365, EVT3_VC_RX, 1, 1, 1, false)
+#endif
+};
+
+static u64 dm365_spi0_dma_mask = DMA_BIT_MASK(32);
+
+static struct davinci_spi_platform_data dm365_spi0_pdata = {
+ .version = SPI_VERSION_1,
+ .num_chipselect = 2,
+ .dma_event_q = EVENTQ_3,
+};
+
+static struct resource dm365_spi0_resources[] = {
+ {
+ .start = 0x01c66000,
+ .end = 0x01c667ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_SPIINT0_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = 17,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_spi0_device = {
+ .name = "spi_davinci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &dm365_spi0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &dm365_spi0_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm365_spi0_resources),
+ .resource = dm365_spi0_resources,
+};
+
+void __init dm365_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len)
+{
+ davinci_cfg_reg(DM365_SPI0_SCLK);
+ davinci_cfg_reg(DM365_SPI0_SDI);
+ davinci_cfg_reg(DM365_SPI0_SDO);
+
+ /* not all slaves will be wired up */
+ if (chipselect_mask & BIT(0))
+ davinci_cfg_reg(DM365_SPI0_SDENA0);
+ if (chipselect_mask & BIT(1))
+ davinci_cfg_reg(DM365_SPI0_SDENA1);
+
+ spi_register_board_info(info, len);
+
+ platform_device_register(&dm365_spi0_device);
+}
+
+static struct emac_platform_data dm365_emac_pdata = {
+ .ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM365_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct resource dm365_emac_resources[] = {
+ {
+ .start = DM365_EMAC_BASE,
+ .end = DM365_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_EMAC_RXTHRESH,
+ .end = IRQ_DM365_EMAC_RXTHRESH,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_RXPULSE,
+ .end = IRQ_DM365_EMAC_RXPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_TXPULSE,
+ .end = IRQ_DM365_EMAC_TXPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM365_EMAC_MISCPULSE,
+ .end = IRQ_DM365_EMAC_MISCPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm365_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm365_emac_resources),
+ .resource = dm365_emac_resources,
+};
+
+static struct resource dm365_mdio_resources[] = {
+ {
+ .start = DM365_EMAC_MDIO_BASE,
+ .end = DM365_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_mdio_resources),
+ .resource = dm365_mdio_resources,
+};
+
+static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_VDINT0] = 2,
+ [IRQ_VDINT1] = 6,
+ [IRQ_VDINT2] = 6,
+ [IRQ_HISTINT] = 6,
+ [IRQ_H3AINT] = 6,
+ [IRQ_PRVUINT] = 6,
+ [IRQ_RSZINT] = 6,
+ [IRQ_DM365_INSFINT] = 7,
+ [IRQ_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_DM365_IMCOPINT] = 4,
+ [IRQ_USBINT] = 4,
+ [IRQ_DM365_RTOINT] = 7,
+ [IRQ_DM365_TINT5] = 7,
+ [IRQ_DM365_TINT6] = 5,
+ [IRQ_CCINT0] = 5,
+ [IRQ_CCERRINT] = 5,
+ [IRQ_TCERRINT0] = 5,
+ [IRQ_TCERRINT] = 7,
+ [IRQ_PSCIN] = 4,
+ [IRQ_DM365_SPINT2_1] = 7,
+ [IRQ_DM365_TINT7] = 7,
+ [IRQ_DM365_SDIOINT0] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_DM365_MMCINT1] = 7,
+ [IRQ_DM365_PWMINT3] = 7,
+ [IRQ_AEMIFINT] = 2,
+ [IRQ_DM365_SDIOINT1] = 2,
+ [IRQ_TINT0_TINT12] = 7,
+ [IRQ_TINT0_TINT34] = 7,
+ [IRQ_TINT1_TINT12] = 7,
+ [IRQ_TINT1_TINT34] = 7,
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 3,
+ [IRQ_PWMINT2] = 3,
+ [IRQ_I2C] = 3,
+ [IRQ_UARTINT0] = 3,
+ [IRQ_UARTINT1] = 3,
+ [IRQ_DM365_RTCINT] = 3,
+ [IRQ_DM365_SPIINT0_0] = 3,
+ [IRQ_DM365_SPIINT3_0] = 3,
+ [IRQ_DM365_GPIO0] = 3,
+ [IRQ_DM365_GPIO1] = 7,
+ [IRQ_DM365_GPIO2] = 4,
+ [IRQ_DM365_GPIO3] = 4,
+ [IRQ_DM365_GPIO4] = 7,
+ [IRQ_DM365_GPIO5] = 7,
+ [IRQ_DM365_GPIO6] = 7,
+ [IRQ_DM365_GPIO7] = 7,
+ [IRQ_DM365_EMAC_RXTHRESH] = 7,
+ [IRQ_DM365_EMAC_RXPULSE] = 7,
+ [IRQ_DM365_EMAC_TXPULSE] = 7,
+ [IRQ_DM365_EMAC_MISCPULSE] = 7,
+ [IRQ_DM365_GPIO12] = 7,
+ [IRQ_DM365_GPIO13] = 7,
+ [IRQ_DM365_GPIO14] = 7,
+ [IRQ_DM365_GPIO15] = 7,
+ [IRQ_DM365_KEYINT] = 7,
+ [IRQ_DM365_TCERRINT2] = 7,
+ [IRQ_DM365_TCERRINT3] = 7,
+ [IRQ_DM365_EMUINT] = 7,
+};
+
+/* Four Transfer Controllers on DM365 */
+static const s8
+dm365_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {-1, -1},
+};
+
+static const s8
+dm365_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 7},
+ {1, 7},
+ {2, 7},
+ {3, 0},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 256,
+ .n_tc = 4,
+ .n_cc = 1,
+ .queue_tc_mapping = dm365_queue_tc_mapping,
+ .queue_priority_mapping = dm365_queue_priority_mapping,
+ .default_queue = EVENTQ_3,
+};
+
+static struct edma_soc_info *dm365_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = 0x01c10800,
+ .end = 0x01c10800 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc3",
+ .start = 0x01c10c00,
+ .end = 0x01c10c00 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm365_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm365_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm365_asp_resources[] = {
+ {
+ .start = DAVINCI_DM365_ASP0_BASE,
+ .end = DAVINCI_DM365_ASP0_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_TX,
+ .end = DAVINCI_DMA_ASP0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_RX,
+ .end = DAVINCI_DMA_ASP0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_asp_device = {
+ .name = "davinci-mcbsp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_asp_resources),
+ .resource = dm365_asp_resources,
+};
+
+static struct resource dm365_vc_resources[] = {
+ {
+ .start = DAVINCI_DM365_VC_BASE,
+ .end = DAVINCI_DM365_VC_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_VC_TX,
+ .end = DAVINCI_DMA_VC_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_VC_RX,
+ .end = DAVINCI_DMA_VC_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm365_vc_device = {
+ .name = "davinci_voicecodec",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm365_vc_resources),
+ .resource = dm365_vc_resources,
+};
+
+static struct resource dm365_rtc_resources[] = {
+ {
+ .start = DM365_RTC_BASE,
+ .end = DM365_RTC_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM365_RTCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_rtc_device = {
+ .name = "rtc_davinci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_rtc_resources),
+ .resource = dm365_rtc_resources,
+};
+
+static struct map_desc dm365_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+static struct resource dm365_ks_resources[] = {
+ {
+ /* registers */
+ .start = DM365_KEYSCAN_BASE,
+ .end = DM365_KEYSCAN_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* interrupt */
+ .start = IRQ_DM365_KEYINT,
+ .end = IRQ_DM365_KEYINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm365_ks_device = {
+ .name = "davinci_keyscan",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm365_ks_resources),
+ .resource = dm365_ks_resources,
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm365_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb83e,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM365,
+ .name = "dm365_rev1.1",
+ },
+ {
+ .variant = 0x8,
+ .part_no = 0xb83e,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM365,
+ .name = "dm365_rev1.2",
+ },
+};
+
+static u32 dm365_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+static struct davinci_timer_info dm365_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+#define DM365_UART1_BASE (IO_PHYS + 0x106000)
+
+static struct plat_serial8250_port dm365_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DM365_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm365_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm365_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm365 = {
+ .io_desc = dm365_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm365_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm365_ids,
+ .ids_num = ARRAY_SIZE(dm365_ids),
+ .cpu_clks = dm365_clks,
+ .psc_bases = dm365_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm365_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm365_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm365_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm365_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm365_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 104,
+ .gpio_irq = IRQ_DM365_GPIO0,
+ .gpio_unbanked = 8, /* really 16 ... skip muxed GPIOs */
+ .serial_dev = &dm365_serial_device,
+ .emac_pdata = &dm365_emac_pdata,
+ .sram_dma = 0x00010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm365_init_asp(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM365_MCBSP0_BDX);
+ davinci_cfg_reg(DM365_MCBSP0_X);
+ davinci_cfg_reg(DM365_MCBSP0_BFSX);
+ davinci_cfg_reg(DM365_MCBSP0_BDR);
+ davinci_cfg_reg(DM365_MCBSP0_R);
+ davinci_cfg_reg(DM365_MCBSP0_BFSR);
+ davinci_cfg_reg(DM365_EVT2_ASP_TX);
+ davinci_cfg_reg(DM365_EVT3_ASP_RX);
+ dm365_asp_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_asp_device);
+}
+
+void __init dm365_init_vc(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM365_EVT2_VC_TX);
+ davinci_cfg_reg(DM365_EVT3_VC_RX);
+ dm365_vc_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_vc_device);
+}
+
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata)
+{
+ dm365_ks_device.dev.platform_data = pdata;
+ platform_device_register(&dm365_ks_device);
+}
+
+void __init dm365_init_rtc(void)
+{
+ davinci_cfg_reg(DM365_INT_PRTCSS);
+ platform_device_register(&dm365_rtc_device);
+}
+
+void __init dm365_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm365);
+}
+
+static struct resource dm365_vpss_resources[] = {
+ {
+ /* VPSS ISP5 Base address */
+ .name = "isp5",
+ .start = 0x01c70000,
+ .end = 0x01c70000 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VPSS CLK Base address */
+ .name = "vpss",
+ .start = 0x01c70200,
+ .end = 0x01c70200 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm365_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm365_vpss",
+ .num_resources = ARRAY_SIZE(dm365_vpss_resources),
+ .resource = dm365_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static void dm365_isif_setup_pinmux(void)
+{
+ davinci_cfg_reg(DM365_VIN_CAM_WEN);
+ davinci_cfg_reg(DM365_VIN_CAM_VD);
+ davinci_cfg_reg(DM365_VIN_CAM_HD);
+ davinci_cfg_reg(DM365_VIN_YIN4_7_EN);
+ davinci_cfg_reg(DM365_VIN_YIN0_3_EN);
+}
+
+static struct resource isif_resource[] = {
+ /* ISIF Base address */
+ {
+ .start = 0x01c71000,
+ .end = 0x01c71000 + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ /* ISIF Linearization table 0 */
+ {
+ .start = 0x1C7C000,
+ .end = 0x1C7C000 + 0x2ff,
+ .flags = IORESOURCE_MEM,
+ },
+ /* ISIF Linearization table 1 */
+ {
+ .start = 0x1C7C400,
+ .end = 0x1C7C400 + 0x2ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+static struct platform_device dm365_isif_dev = {
+ .name = "isif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(isif_resource),
+ .resource = isif_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = dm365_isif_setup_pinmux,
+ },
+};
+
+static int __init dm365_init_devices(void)
+{
+ if (!cpu_is_davinci_dm365())
+ return 0;
+
+ davinci_cfg_reg(DM365_INT_EDMA_CC);
+ platform_device_register(&dm365_edma_device);
+
+ platform_device_register(&dm365_mdio_device);
+ platform_device_register(&dm365_emac_device);
+ clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev),
+ NULL, &dm365_emac_device.dev);
+
+ /* Add isif clock alias */
+ clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL);
+ platform_device_register(&dm365_vpss_device);
+ platform_device_register(&dm365_isif_dev);
+ platform_device_register(&vpfe_capture_dev);
+ return 0;
+}
+postcore_initcall(dm365_init_devices);
+
+void dm365_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
new file mode 100644
index 00000000..4c82c271
--- /dev/null
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -0,0 +1,805 @@
+/*
+ * TI DaVinci DM644x chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm644x.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/irqs.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/*
+ * Device specific clocks
+ */
+#define DM644X_REF_FREQ 27000000
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+ .rate = DM644X_REF_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2",
+ .parent = &ref_clk,
+ .pll_data = &pll2_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll2_sysclk2 = {
+ .name = "pll2_sysclk2",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll2_sysclkbp = {
+ .name = "pll2_sysclkbp",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV
+};
+
+static struct clk dsp_clk = {
+ .name = "dsp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DAVINCI_LPSC_GEM,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk vicp_clk = {
+ .name = "vicp",
+ .parent = &pll1_sysclk2,
+ .lpsc = DAVINCI_LPSC_IMCOP,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk vpss_master_clk = {
+ .name = "vpss_master",
+ .parent = &pll1_sysclk3,
+ .lpsc = DAVINCI_LPSC_VPSSMSTR,
+ .flags = CLK_PSC,
+};
+
+static struct clk vpss_slave_clk = {
+ .name = "vpss_slave",
+ .parent = &pll1_sysclk3,
+ .lpsc = DAVINCI_LPSC_VPSSSLV,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_UART2,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_EMAC_WRAPPER,
+};
+
+static struct clk i2c_clk = {
+ .name = "i2c",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_I2C,
+};
+
+static struct clk ide_clk = {
+ .name = "ide",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_ATA,
+};
+
+static struct clk asp_clk = {
+ .name = "asp0",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_McBSP,
+};
+
+static struct clk mmcsd_clk = {
+ .name = "mmcsd",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_MMC_SD,
+};
+
+static struct clk spi_clk = {
+ .name = "spi",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_SPI,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_GPIO,
+};
+
+static struct clk usb_clk = {
+ .name = "usb",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_USB,
+};
+
+static struct clk vlynq_clk = {
+ .name = "vlynq",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_VLYNQ,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk5,
+ .lpsc = DAVINCI_LPSC_AEMIF,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM0,
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM1,
+};
+
+static struct clk pwm2_clk = {
+ .name = "pwm2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_PWM2,
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_aux_clk,
+ .lpsc = DAVINCI_LPSC_TIMER2,
+ .usecount = 1, /* REVISIT: why can't this be disabled? */
+};
+
+static struct clk_lookup dm644x_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll1_sysclkbp", &pll1_sysclkbp),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "pll2_sysclk2", &pll2_sysclk2),
+ CLK(NULL, "pll2_sysclkbp", &pll2_sysclkbp),
+ CLK(NULL, "dsp", &dsp_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "vicp", &vicp_clk),
+ CLK(NULL, "vpss_master", &vpss_master_clk),
+ CLK(NULL, "vpss_slave", &vpss_slave_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK("palm_bk3710", NULL, &ide_clk),
+ CLK("davinci-mcbsp", NULL, &asp_clk),
+ CLK("davinci_mmc.0", NULL, &mmcsd_clk),
+ CLK(NULL, "spi", &spi_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK(NULL, "usb", &usb_clk),
+ CLK(NULL, "vlynq", &vlynq_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "pwm2", &pwm2_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+static struct emac_platform_data dm644x_emac_pdata = {
+ .ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_1,
+};
+
+static struct resource dm644x_emac_resources[] = {
+ {
+ .start = DM644X_EMAC_BASE,
+ .end = DM644X_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EMACINT,
+ .end = IRQ_EMACINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm644x_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm644x_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm644x_emac_resources),
+ .resource = dm644x_emac_resources,
+};
+
+static struct resource dm644x_mdio_resources[] = {
+ {
+ .start = DM644X_EMAC_MDIO_BASE,
+ .end = DM644X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm644x_mdio_resources),
+ .resource = dm644x_mdio_resources,
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm644x_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM644X, HDIREN, 0, 16, 1, 1, true)
+MUX_CFG(DM644X, ATAEN, 0, 17, 1, 1, true)
+MUX_CFG(DM644X, ATAEN_DISABLE, 0, 17, 1, 0, true)
+
+MUX_CFG(DM644X, HPIEN_DISABLE, 0, 29, 1, 0, true)
+
+MUX_CFG(DM644X, AEAW, 0, 0, 31, 31, true)
+MUX_CFG(DM644X, AEAW0, 0, 0, 1, 0, true)
+MUX_CFG(DM644X, AEAW1, 0, 1, 1, 0, true)
+MUX_CFG(DM644X, AEAW2, 0, 2, 1, 0, true)
+MUX_CFG(DM644X, AEAW3, 0, 3, 1, 0, true)
+MUX_CFG(DM644X, AEAW4, 0, 4, 1, 0, true)
+
+MUX_CFG(DM644X, MSTK, 1, 9, 1, 0, false)
+
+MUX_CFG(DM644X, I2C, 1, 7, 1, 1, false)
+
+MUX_CFG(DM644X, MCBSP, 1, 10, 1, 1, false)
+
+MUX_CFG(DM644X, UART1, 1, 1, 1, 1, true)
+MUX_CFG(DM644X, UART2, 1, 2, 1, 1, true)
+
+MUX_CFG(DM644X, PWM0, 1, 4, 1, 1, false)
+
+MUX_CFG(DM644X, PWM1, 1, 5, 1, 1, false)
+
+MUX_CFG(DM644X, PWM2, 1, 6, 1, 1, false)
+
+MUX_CFG(DM644X, VLYNQEN, 0, 15, 1, 1, false)
+MUX_CFG(DM644X, VLSCREN, 0, 14, 1, 1, false)
+MUX_CFG(DM644X, VLYNQWD, 0, 12, 3, 3, false)
+
+MUX_CFG(DM644X, EMACEN, 0, 31, 1, 1, true)
+
+MUX_CFG(DM644X, GPIO3V, 0, 31, 1, 0, true)
+
+MUX_CFG(DM644X, GPIO0, 0, 24, 1, 0, true)
+MUX_CFG(DM644X, GPIO3, 0, 25, 1, 0, false)
+MUX_CFG(DM644X, GPIO43_44, 1, 7, 1, 0, false)
+MUX_CFG(DM644X, GPIO46_47, 0, 22, 1, 0, true)
+
+MUX_CFG(DM644X, RGB666, 0, 22, 1, 1, true)
+
+MUX_CFG(DM644X, LOEEN, 0, 24, 1, 1, true)
+MUX_CFG(DM644X, LFLDEN, 0, 25, 1, 1, false)
+#endif
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 dm644x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_VDINT0] = 2,
+ [IRQ_VDINT1] = 6,
+ [IRQ_VDINT2] = 6,
+ [IRQ_HISTINT] = 6,
+ [IRQ_H3AINT] = 6,
+ [IRQ_PRVUINT] = 6,
+ [IRQ_RSZINT] = 6,
+ [7] = 7,
+ [IRQ_VENCINT] = 6,
+ [IRQ_ASQINT] = 6,
+ [IRQ_IMXINT] = 6,
+ [IRQ_VLCDINT] = 6,
+ [IRQ_USBINT] = 4,
+ [IRQ_EMACINT] = 4,
+ [14] = 7,
+ [15] = 7,
+ [IRQ_CCINT0] = 5, /* dma */
+ [IRQ_CCERRINT] = 5, /* dma */
+ [IRQ_TCERRINT0] = 5, /* dma */
+ [IRQ_TCERRINT] = 5, /* dma */
+ [IRQ_PSCIN] = 7,
+ [21] = 7,
+ [IRQ_IDE] = 4,
+ [23] = 7,
+ [IRQ_MBXINT] = 7,
+ [IRQ_MBRINT] = 7,
+ [IRQ_MMCINT] = 7,
+ [IRQ_SDIOINT] = 7,
+ [28] = 7,
+ [IRQ_DDRINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_VLQINT] = 4,
+ [IRQ_TINT0_TINT12] = 2, /* clockevent */
+ [IRQ_TINT0_TINT34] = 2, /* clocksource */
+ [IRQ_TINT1_TINT12] = 7, /* DSP timer */
+ [IRQ_TINT1_TINT34] = 7, /* system tick */
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 7,
+ [IRQ_PWMINT2] = 7,
+ [IRQ_I2C] = 3,
+ [IRQ_UARTINT0] = 3,
+ [IRQ_UARTINT1] = 3,
+ [IRQ_UARTINT2] = 3,
+ [IRQ_SPINT0] = 3,
+ [IRQ_SPINT1] = 3,
+ [45] = 7,
+ [IRQ_DSP2ARM0] = 4,
+ [IRQ_DSP2ARM1] = 4,
+ [IRQ_GPIO0] = 7,
+ [IRQ_GPIO1] = 7,
+ [IRQ_GPIO2] = 7,
+ [IRQ_GPIO3] = 7,
+ [IRQ_GPIO4] = 7,
+ [IRQ_GPIO5] = 7,
+ [IRQ_GPIO6] = 7,
+ [IRQ_GPIO7] = 7,
+ [IRQ_GPIOBNK0] = 7,
+ [IRQ_GPIOBNK1] = 7,
+ [IRQ_GPIOBNK2] = 7,
+ [IRQ_GPIOBNK3] = 7,
+ [IRQ_GPIOBNK4] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/*----------------------------------------------------------------------*/
+
+static const s8
+queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {-1, -1},
+};
+
+static const s8
+queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 3},
+ {1, 7},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 4,
+ .n_slot = 128,
+ .n_tc = 2,
+ .n_cc = 1,
+ .queue_tc_mapping = queue_tc_mapping,
+ .queue_priority_mapping = queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm644x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm644x_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm644x_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
+static struct resource dm644x_asp_resources[] = {
+ {
+ .start = DAVINCI_ASP0_BASE,
+ .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_TX,
+ .end = DAVINCI_DMA_ASP0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DMA_ASP0_RX,
+ .end = DAVINCI_DMA_ASP0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm644x_asp_device = {
+ .name = "davinci-mcbsp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_asp_resources),
+ .resource = dm644x_asp_resources,
+};
+
+static struct resource dm644x_vpss_resources[] = {
+ {
+ /* VPSS Base address */
+ .name = "vpss",
+ .start = 0x01c73400,
+ .end = 0x01c73400 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_vpss_device = {
+ .name = "vpss",
+ .id = -1,
+ .dev.platform_data = "dm644x_vpss",
+ .num_resources = ARRAY_SIZE(dm644x_vpss_resources),
+ .resource = dm644x_vpss_resources,
+};
+
+static struct resource vpfe_resources[] = {
+ {
+ .start = IRQ_VDINT0,
+ .end = IRQ_VDINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_VDINT1,
+ .end = IRQ_VDINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32);
+static struct resource dm644x_ccdc_resource[] = {
+ /* CCDC Base address */
+ {
+ .start = 0x01c70400,
+ .end = 0x01c70400 + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm644x_ccdc_dev = {
+ .name = "dm644x_ccdc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm644x_ccdc_resource),
+ .resource = dm644x_ccdc_resource,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct platform_device vpfe_capture_dev = {
+ .name = CAPTURE_DRV_NAME,
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpfe_resources),
+ .resource = vpfe_resources,
+ .dev = {
+ .dma_mask = &vpfe_capture_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void dm644x_set_vpfe_config(struct vpfe_config *cfg)
+{
+ vpfe_capture_dev.dev.platform_data = cfg;
+}
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm644x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00008000),
+ .length = SZ_16K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm644x_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb700,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6446,
+ .name = "dm6446",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb700,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6446,
+ .name = "dm6446a",
+ },
+};
+
+static u32 dm644x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+static struct davinci_timer_info dm644x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm644x_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm644x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm644x_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm644x = {
+ .io_desc = dm644x_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm644x_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm644x_ids,
+ .ids_num = ARRAY_SIZE(dm644x_ids),
+ .cpu_clks = dm644x_clks,
+ .psc_bases = dm644x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm644x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm644x_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm644x_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm644x_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 71,
+ .gpio_irq = IRQ_GPIOBNK0,
+ .serial_dev = &dm644x_serial_device,
+ .emac_pdata = &dm644x_emac_pdata,
+ .sram_dma = 0x00008000,
+ .sram_len = SZ_16K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm644x_init_asp(struct snd_platform_data *pdata)
+{
+ davinci_cfg_reg(DM644X_MCBSP);
+ dm644x_asp_device.dev.platform_data = pdata;
+ platform_device_register(&dm644x_asp_device);
+}
+
+void __init dm644x_init(void)
+{
+ davinci_common_init(&davinci_soc_info_dm644x);
+}
+
+static int __init dm644x_init_devices(void)
+{
+ if (!cpu_is_davinci_dm644x())
+ return 0;
+
+ /* Add ccdc clock aliases */
+ clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL);
+ clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL);
+ platform_device_register(&dm644x_edma_device);
+
+ platform_device_register(&dm644x_mdio_device);
+ platform_device_register(&dm644x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev),
+ NULL, &dm644x_emac_device.dev);
+
+ platform_device_register(&dm644x_vpss_device);
+ platform_device_register(&dm644x_ccdc_dev);
+ platform_device_register(&vpfe_capture_dev);
+
+ return 0;
+}
+postcore_initcall(dm644x_init_devices);
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
new file mode 100644
index 00000000..e00d61e2
--- /dev/null
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -0,0 +1,921 @@
+/*
+ * TI DaVinci DM644x chip specific setup
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/dm646x.h>
+#include <mach/cputype.h>
+#include <mach/edma.h>
+#include <mach/irqs.h>
+#include <mach/psc.h>
+#include <mach/mux.h>
+#include <mach/time.h>
+#include <mach/serial.h>
+#include <mach/common.h>
+#include <mach/asp.h>
+
+#include "clock.h"
+#include "mux.h"
+
+#define DAVINCI_VPIF_BASE (0x01C12000)
+#define VDD3P3V_PWDN_OFFSET (0x48)
+#define VSCLKDIS_OFFSET (0x6C)
+
+#define VDD3P3V_VID_MASK (BIT_MASK(3) | BIT_MASK(2) | BIT_MASK(1) |\
+ BIT_MASK(0))
+#define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\
+ BIT_MASK(8))
+
+/*
+ * Device specific clocks
+ */
+#define DM646X_AUX_FREQ 24000000
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = DAVINCI_PLL1_BASE,
+};
+
+static struct pll_data pll2_data = {
+ .num = 2,
+ .phys_base = DAVINCI_PLL2_BASE,
+};
+
+static struct clk ref_clk = {
+ .name = "ref_clk",
+};
+
+static struct clk aux_clkin = {
+ .name = "aux_clkin",
+ .rate = DM646X_AUX_FREQ,
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &ref_clk,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV2,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV3,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV5,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll1_sysclk6",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV6,
+};
+
+static struct clk pll1_sysclk8 = {
+ .name = "pll1_sysclk8",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV8,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV9,
+};
+
+static struct clk pll1_sysclkbp = {
+ .name = "pll1_sysclkbp",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+ .div_reg = BPDIV,
+};
+
+static struct clk pll1_aux_clk = {
+ .name = "pll1_aux_clk",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | PRE_PLL,
+};
+
+static struct clk pll2_clk = {
+ .name = "pll2_clk",
+ .parent = &ref_clk,
+ .pll_data = &pll2_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll2_sysclk1 = {
+ .name = "pll2_sysclk1",
+ .parent = &pll2_clk,
+ .flags = CLK_PLL,
+ .div_reg = PLLDIV1,
+};
+
+static struct clk dsp_clk = {
+ .name = "dsp",
+ .parent = &pll1_sysclk1,
+ .lpsc = DM646X_LPSC_C64X_CPU,
+ .flags = PSC_DSP,
+ .usecount = 1, /* REVISIT how to disable? */
+};
+
+static struct clk arm_clk = {
+ .name = "arm",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_ARM,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_cc_clk = {
+ .name = "edma_cc",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPCC,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc0_clk = {
+ .name = "edma_tc0",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC0,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc1_clk = {
+ .name = "edma_tc1",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC1,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc2_clk = {
+ .name = "edma_tc2",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC2,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk edma_tc3_clk = {
+ .name = "edma_tc3",
+ .parent = &pll1_sysclk2,
+ .lpsc = DM646X_LPSC_TPTC3,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk uart0_clk = {
+ .name = "uart0",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART0,
+};
+
+static struct clk uart1_clk = {
+ .name = "uart1",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART1,
+};
+
+static struct clk uart2_clk = {
+ .name = "uart2",
+ .parent = &aux_clkin,
+ .lpsc = DM646X_LPSC_UART2,
+};
+
+static struct clk i2c_clk = {
+ .name = "I2CCLK",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_I2C,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_GPIO,
+};
+
+static struct clk mcasp0_clk = {
+ .name = "mcasp0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_McASP0,
+};
+
+static struct clk mcasp1_clk = {
+ .name = "mcasp1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_McASP1,
+};
+
+static struct clk aemif_clk = {
+ .name = "aemif",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_AEMIF,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk emac_clk = {
+ .name = "emac",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_EMAC,
+};
+
+static struct clk pwm0_clk = {
+ .name = "pwm0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_PWM0,
+ .usecount = 1, /* REVIST: disabling hangs system */
+};
+
+static struct clk pwm1_clk = {
+ .name = "pwm1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_PWM1,
+ .usecount = 1, /* REVIST: disabling hangs system */
+};
+
+static struct clk timer0_clk = {
+ .name = "timer0",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_TIMER0,
+};
+
+static struct clk timer1_clk = {
+ .name = "timer1",
+ .parent = &pll1_sysclk3,
+ .lpsc = DM646X_LPSC_TIMER1,
+};
+
+static struct clk timer2_clk = {
+ .name = "timer2",
+ .parent = &pll1_sysclk3,
+ .flags = ALWAYS_ENABLED, /* no LPSC, always enabled; c.f. spruep9a */
+};
+
+
+static struct clk ide_clk = {
+ .name = "ide",
+ .parent = &pll1_sysclk4,
+ .lpsc = DAVINCI_LPSC_ATA,
+};
+
+static struct clk vpif0_clk = {
+ .name = "vpif0",
+ .parent = &ref_clk,
+ .lpsc = DM646X_LPSC_VPSSMSTR,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk vpif1_clk = {
+ .name = "vpif1",
+ .parent = &ref_clk,
+ .lpsc = DM646X_LPSC_VPSSSLV,
+ .flags = ALWAYS_ENABLED,
+};
+
+static struct clk_lookup dm646x_clks[] = {
+ CLK(NULL, "ref", &ref_clk),
+ CLK(NULL, "aux", &aux_clkin),
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk8),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclk9),
+ CLK(NULL, "pll1_sysclk", &pll1_sysclkbp),
+ CLK(NULL, "pll1_aux", &pll1_aux_clk),
+ CLK(NULL, "pll2", &pll2_clk),
+ CLK(NULL, "pll2_sysclk1", &pll2_sysclk1),
+ CLK(NULL, "dsp", &dsp_clk),
+ CLK(NULL, "arm", &arm_clk),
+ CLK(NULL, "edma_cc", &edma_cc_clk),
+ CLK(NULL, "edma_tc0", &edma_tc0_clk),
+ CLK(NULL, "edma_tc1", &edma_tc1_clk),
+ CLK(NULL, "edma_tc2", &edma_tc2_clk),
+ CLK(NULL, "edma_tc3", &edma_tc3_clk),
+ CLK(NULL, "uart0", &uart0_clk),
+ CLK(NULL, "uart1", &uart1_clk),
+ CLK(NULL, "uart2", &uart2_clk),
+ CLK("i2c_davinci.1", NULL, &i2c_clk),
+ CLK(NULL, "gpio", &gpio_clk),
+ CLK("davinci-mcasp.0", NULL, &mcasp0_clk),
+ CLK("davinci-mcasp.1", NULL, &mcasp1_clk),
+ CLK(NULL, "aemif", &aemif_clk),
+ CLK("davinci_emac.1", NULL, &emac_clk),
+ CLK(NULL, "pwm0", &pwm0_clk),
+ CLK(NULL, "pwm1", &pwm1_clk),
+ CLK(NULL, "timer0", &timer0_clk),
+ CLK(NULL, "timer1", &timer1_clk),
+ CLK("watchdog", NULL, &timer2_clk),
+ CLK("palm_bk3710", NULL, &ide_clk),
+ CLK(NULL, "vpif0", &vpif0_clk),
+ CLK(NULL, "vpif1", &vpif1_clk),
+ CLK(NULL, NULL, NULL),
+};
+
+static struct emac_platform_data dm646x_emac_pdata = {
+ .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET,
+ .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET,
+ .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET,
+ .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE,
+ .version = EMAC_VERSION_2,
+};
+
+static struct resource dm646x_emac_resources[] = {
+ {
+ .start = DM646X_EMAC_BASE,
+ .end = DM646X_EMAC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DM646X_EMACRXTHINT,
+ .end = IRQ_DM646X_EMACRXTHINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACRXINT,
+ .end = IRQ_DM646X_EMACRXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACTXINT,
+ .end = IRQ_DM646X_EMACTXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_EMACMISCINT,
+ .end = IRQ_DM646X_EMACMISCINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dm646x_emac_device = {
+ .name = "davinci_emac",
+ .id = 1,
+ .dev = {
+ .platform_data = &dm646x_emac_pdata,
+ },
+ .num_resources = ARRAY_SIZE(dm646x_emac_resources),
+ .resource = dm646x_emac_resources,
+};
+
+static struct resource dm646x_mdio_resources[] = {
+ {
+ .start = DM646X_EMAC_MDIO_BASE,
+ .end = DM646X_EMAC_MDIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device dm646x_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm646x_mdio_resources),
+ .resource = dm646x_mdio_resources,
+};
+
+/*
+ * Device specific mux setup
+ *
+ * soc description mux mode mode mux dbg
+ * reg offset mask mode
+ */
+static const struct mux_config dm646x_pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+MUX_CFG(DM646X, ATAEN, 0, 0, 5, 1, true)
+
+MUX_CFG(DM646X, AUDCK1, 0, 29, 1, 0, false)
+
+MUX_CFG(DM646X, AUDCK0, 0, 28, 1, 0, false)
+
+MUX_CFG(DM646X, CRGMUX, 0, 24, 7, 5, true)
+
+MUX_CFG(DM646X, STSOMUX_DISABLE, 0, 22, 3, 0, true)
+
+MUX_CFG(DM646X, STSIMUX_DISABLE, 0, 20, 3, 0, true)
+
+MUX_CFG(DM646X, PTSOMUX_DISABLE, 0, 18, 3, 0, true)
+
+MUX_CFG(DM646X, PTSIMUX_DISABLE, 0, 16, 3, 0, true)
+
+MUX_CFG(DM646X, STSOMUX, 0, 22, 3, 2, true)
+
+MUX_CFG(DM646X, STSIMUX, 0, 20, 3, 2, true)
+
+MUX_CFG(DM646X, PTSOMUX_PARALLEL, 0, 18, 3, 2, true)
+
+MUX_CFG(DM646X, PTSIMUX_PARALLEL, 0, 16, 3, 2, true)
+
+MUX_CFG(DM646X, PTSOMUX_SERIAL, 0, 18, 3, 3, true)
+
+MUX_CFG(DM646X, PTSIMUX_SERIAL, 0, 16, 3, 3, true)
+#endif
+};
+
+static u8 dm646x_default_priorities[DAVINCI_N_AINTC_IRQ] = {
+ [IRQ_DM646X_VP_VERTINT0] = 7,
+ [IRQ_DM646X_VP_VERTINT1] = 7,
+ [IRQ_DM646X_VP_VERTINT2] = 7,
+ [IRQ_DM646X_VP_VERTINT3] = 7,
+ [IRQ_DM646X_VP_ERRINT] = 7,
+ [IRQ_DM646X_RESERVED_1] = 7,
+ [IRQ_DM646X_RESERVED_2] = 7,
+ [IRQ_DM646X_WDINT] = 7,
+ [IRQ_DM646X_CRGENINT0] = 7,
+ [IRQ_DM646X_CRGENINT1] = 7,
+ [IRQ_DM646X_TSIFINT0] = 7,
+ [IRQ_DM646X_TSIFINT1] = 7,
+ [IRQ_DM646X_VDCEINT] = 7,
+ [IRQ_DM646X_USBINT] = 7,
+ [IRQ_DM646X_USBDMAINT] = 7,
+ [IRQ_DM646X_PCIINT] = 7,
+ [IRQ_CCINT0] = 7, /* dma */
+ [IRQ_CCERRINT] = 7, /* dma */
+ [IRQ_TCERRINT0] = 7, /* dma */
+ [IRQ_TCERRINT] = 7, /* dma */
+ [IRQ_DM646X_TCERRINT2] = 7,
+ [IRQ_DM646X_TCERRINT3] = 7,
+ [IRQ_DM646X_IDE] = 7,
+ [IRQ_DM646X_HPIINT] = 7,
+ [IRQ_DM646X_EMACRXTHINT] = 7,
+ [IRQ_DM646X_EMACRXINT] = 7,
+ [IRQ_DM646X_EMACTXINT] = 7,
+ [IRQ_DM646X_EMACMISCINT] = 7,
+ [IRQ_DM646X_MCASP0TXINT] = 7,
+ [IRQ_DM646X_MCASP0RXINT] = 7,
+ [IRQ_AEMIFINT] = 7,
+ [IRQ_DM646X_RESERVED_3] = 7,
+ [IRQ_DM646X_MCASP1TXINT] = 7, /* clockevent */
+ [IRQ_TINT0_TINT34] = 7, /* clocksource */
+ [IRQ_TINT1_TINT12] = 7, /* DSP timer */
+ [IRQ_TINT1_TINT34] = 7, /* system tick */
+ [IRQ_PWMINT0] = 7,
+ [IRQ_PWMINT1] = 7,
+ [IRQ_DM646X_VLQINT] = 7,
+ [IRQ_I2C] = 7,
+ [IRQ_UARTINT0] = 7,
+ [IRQ_UARTINT1] = 7,
+ [IRQ_DM646X_UARTINT2] = 7,
+ [IRQ_DM646X_SPINT0] = 7,
+ [IRQ_DM646X_SPINT1] = 7,
+ [IRQ_DM646X_DSP2ARMINT] = 7,
+ [IRQ_DM646X_RESERVED_4] = 7,
+ [IRQ_DM646X_PSCINT] = 7,
+ [IRQ_DM646X_GPIO0] = 7,
+ [IRQ_DM646X_GPIO1] = 7,
+ [IRQ_DM646X_GPIO2] = 7,
+ [IRQ_DM646X_GPIO3] = 7,
+ [IRQ_DM646X_GPIO4] = 7,
+ [IRQ_DM646X_GPIO5] = 7,
+ [IRQ_DM646X_GPIO6] = 7,
+ [IRQ_DM646X_GPIO7] = 7,
+ [IRQ_DM646X_GPIOBNK0] = 7,
+ [IRQ_DM646X_GPIOBNK1] = 7,
+ [IRQ_DM646X_GPIOBNK2] = 7,
+ [IRQ_DM646X_DDRINT] = 7,
+ [IRQ_DM646X_AEMIFINT] = 7,
+ [IRQ_COMMTX] = 7,
+ [IRQ_COMMRX] = 7,
+ [IRQ_EMUINT] = 7,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Four Transfer Controllers on DM646x */
+static const s8
+dm646x_queue_tc_mapping[][2] = {
+ /* {event queue no, TC no} */
+ {0, 0},
+ {1, 1},
+ {2, 2},
+ {3, 3},
+ {-1, -1},
+};
+
+static const s8
+dm646x_queue_priority_mapping[][2] = {
+ /* {event queue no, Priority} */
+ {0, 4},
+ {1, 0},
+ {2, 5},
+ {3, 1},
+ {-1, -1},
+};
+
+static struct edma_soc_info edma_cc0_info = {
+ .n_channel = 64,
+ .n_region = 6, /* 0-1, 4-7 */
+ .n_slot = 512,
+ .n_tc = 4,
+ .n_cc = 1,
+ .queue_tc_mapping = dm646x_queue_tc_mapping,
+ .queue_priority_mapping = dm646x_queue_priority_mapping,
+};
+
+static struct edma_soc_info *dm646x_edma_info[EDMA_MAX_CC] = {
+ &edma_cc0_info,
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = 0x01c00000,
+ .end = 0x01c00000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = 0x01c10000,
+ .end = 0x01c10000 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = 0x01c10400,
+ .end = 0x01c10400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc2",
+ .start = 0x01c10800,
+ .end = 0x01c10800 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc3",
+ .start = 0x01c10c00,
+ .end = 0x01c10c00 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_CCINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_CCERRINT,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* not using TC*_ERR */
+};
+
+static struct platform_device dm646x_edma_device = {
+ .name = "edma",
+ .id = 0,
+ .dev.platform_data = dm646x_edma_info,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+};
+
+static struct resource dm646x_mcasp0_resources[] = {
+ {
+ .name = "mcasp0",
+ .start = DAVINCI_DM646X_MCASP0_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP0_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* first TX, then RX */
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AXEVT0,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .end = DAVINCI_DM646X_DMA_MCASP0_AREVT0,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource dm646x_mcasp1_resources[] = {
+ {
+ .name = "mcasp1",
+ .start = DAVINCI_DM646X_MCASP1_REG_BASE,
+ .end = DAVINCI_DM646X_MCASP1_REG_BASE + (SZ_1K << 1) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /* DIT mode, only TX event */
+ {
+ .start = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .end = DAVINCI_DM646X_DMA_MCASP1_AXEVT1,
+ .flags = IORESOURCE_DMA,
+ },
+ /* DIT mode, dummy entry */
+ {
+ .start = -1,
+ .end = -1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device dm646x_mcasp0_device = {
+ .name = "davinci-mcasp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm646x_mcasp0_resources),
+ .resource = dm646x_mcasp0_resources,
+};
+
+static struct platform_device dm646x_mcasp1_device = {
+ .name = "davinci-mcasp",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(dm646x_mcasp1_resources),
+ .resource = dm646x_mcasp1_resources,
+};
+
+static struct platform_device dm646x_dit_device = {
+ .name = "spdif-dit",
+ .id = -1,
+};
+
+static u64 vpif_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource vpif_resource[] = {
+ {
+ .start = DAVINCI_VPIF_BASE,
+ .end = DAVINCI_VPIF_BASE + 0x03ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device vpif_dev = {
+ .name = "vpif",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_resource,
+ .num_resources = ARRAY_SIZE(vpif_resource),
+};
+
+static struct resource vpif_display_resource[] = {
+ {
+ .start = IRQ_DM646X_VP_VERTINT2,
+ .end = IRQ_DM646X_VP_VERTINT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_VP_VERTINT3,
+ .end = IRQ_DM646X_VP_VERTINT3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vpif_display_dev = {
+ .name = "vpif_display",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_display_resource,
+ .num_resources = ARRAY_SIZE(vpif_display_resource),
+};
+
+static struct resource vpif_capture_resource[] = {
+ {
+ .start = IRQ_DM646X_VP_VERTINT0,
+ .end = IRQ_DM646X_VP_VERTINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = IRQ_DM646X_VP_VERTINT1,
+ .end = IRQ_DM646X_VP_VERTINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device vpif_capture_dev = {
+ .name = "vpif_capture",
+ .id = -1,
+ .dev = {
+ .dma_mask = &vpif_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = vpif_capture_resource,
+ .num_resources = ARRAY_SIZE(vpif_capture_resource),
+};
+
+/*----------------------------------------------------------------------*/
+
+static struct map_desc dm646x_io_desc[] = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = SRAM_VIRT,
+ .pfn = __phys_to_pfn(0x00010000),
+ .length = SZ_32K,
+ .type = MT_MEMORY_NONCACHED,
+ },
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id dm646x_ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb770,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6467,
+ .name = "dm6467_rev1.x",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb770,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_DM6467,
+ .name = "dm6467_rev3.x",
+ },
+};
+
+static u32 dm646x_psc_bases[] = { DAVINCI_PWR_SLEEP_CNTRL_BASE };
+
+/*
+ * T0_BOT: Timer 0, bottom: clockevent source for hrtimers
+ * T0_TOP: Timer 0, top : clocksource for generic timekeeping
+ * T1_BOT: Timer 1, bottom: (used by DSP in TI DSPLink code)
+ * T1_TOP: Timer 1, top : <unused>
+ */
+static struct davinci_timer_info dm646x_timer_info = {
+ .timers = davinci_timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+static struct plat_serial8250_port dm646x_serial_platform_data[] = {
+ {
+ .mapbase = DAVINCI_UART0_BASE,
+ .irq = IRQ_UARTINT0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART1_BASE,
+ .irq = IRQ_UARTINT1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = DAVINCI_UART2_BASE,
+ .irq = IRQ_DM646X_UARTINT2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0
+ },
+};
+
+static struct platform_device dm646x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = dm646x_serial_platform_data,
+ },
+};
+
+static struct davinci_soc_info davinci_soc_info_dm646x = {
+ .io_desc = dm646x_io_desc,
+ .io_desc_num = ARRAY_SIZE(dm646x_io_desc),
+ .jtag_id_reg = 0x01c40028,
+ .ids = dm646x_ids,
+ .ids_num = ARRAY_SIZE(dm646x_ids),
+ .cpu_clks = dm646x_clks,
+ .psc_bases = dm646x_psc_bases,
+ .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases),
+ .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE,
+ .pinmux_pins = dm646x_pins,
+ .pinmux_pins_num = ARRAY_SIZE(dm646x_pins),
+ .intc_base = DAVINCI_ARM_INTC_BASE,
+ .intc_type = DAVINCI_INTC_TYPE_AINTC,
+ .intc_irq_prios = dm646x_default_priorities,
+ .intc_irq_num = DAVINCI_N_AINTC_IRQ,
+ .timer_info = &dm646x_timer_info,
+ .gpio_type = GPIO_TYPE_DAVINCI,
+ .gpio_base = DAVINCI_GPIO_BASE,
+ .gpio_num = 43, /* Only 33 usable */
+ .gpio_irq = IRQ_DM646X_GPIOBNK0,
+ .serial_dev = &dm646x_serial_device,
+ .emac_pdata = &dm646x_emac_pdata,
+ .sram_dma = 0x10010000,
+ .sram_len = SZ_32K,
+ .reset_device = &davinci_wdt_device,
+};
+
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata)
+{
+ dm646x_mcasp0_device.dev.platform_data = pdata;
+ platform_device_register(&dm646x_mcasp0_device);
+}
+
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata)
+{
+ dm646x_mcasp1_device.dev.platform_data = pdata;
+ platform_device_register(&dm646x_mcasp1_device);
+ platform_device_register(&dm646x_dit_device);
+}
+
+void dm646x_setup_vpif(struct vpif_display_config *display_config,
+ struct vpif_capture_config *capture_config)
+{
+ unsigned int value;
+ void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE);
+
+ value = __raw_readl(base + VSCLKDIS_OFFSET);
+ value &= ~VSCLKDIS_MASK;
+ __raw_writel(value, base + VSCLKDIS_OFFSET);
+
+ value = __raw_readl(base + VDD3P3V_PWDN_OFFSET);
+ value &= ~VDD3P3V_VID_MASK;
+ __raw_writel(value, base + VDD3P3V_PWDN_OFFSET);
+
+ davinci_cfg_reg(DM646X_STSOMUX_DISABLE);
+ davinci_cfg_reg(DM646X_STSIMUX_DISABLE);
+ davinci_cfg_reg(DM646X_PTSOMUX_DISABLE);
+ davinci_cfg_reg(DM646X_PTSIMUX_DISABLE);
+
+ vpif_display_dev.dev.platform_data = display_config;
+ vpif_capture_dev.dev.platform_data = capture_config;
+ platform_device_register(&vpif_dev);
+ platform_device_register(&vpif_display_dev);
+ platform_device_register(&vpif_capture_dev);
+}
+
+int __init dm646x_init_edma(struct edma_rsv_info *rsv)
+{
+ edma_cc0_info.rsv = rsv;
+
+ return platform_device_register(&dm646x_edma_device);
+}
+
+void __init dm646x_init(void)
+{
+ dm646x_board_setup_refclk(&ref_clk);
+ davinci_common_init(&davinci_soc_info_dm646x);
+}
+
+static int __init dm646x_init_devices(void)
+{
+ if (!cpu_is_davinci_dm646x())
+ return 0;
+
+ platform_device_register(&dm646x_mdio_device);
+ platform_device_register(&dm646x_emac_device);
+ clk_add_alias(NULL, dev_name(&dm646x_mdio_device.dev),
+ NULL, &dm646x_emac_device.dev);
+
+ return 0;
+}
+postcore_initcall(dm646x_init_devices);
diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c
new file mode 100644
index 00000000..6b966986
--- /dev/null
+++ b/arch/arm/mach-davinci/dma.c
@@ -0,0 +1,1596 @@
+/*
+ * EDMA3 support for DaVinci
+ *
+ * Copyright (C) 2006-2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/edma.h>
+
+/* Offsets matching "struct edmacc_param" */
+#define PARM_OPT 0x00
+#define PARM_SRC 0x04
+#define PARM_A_B_CNT 0x08
+#define PARM_DST 0x0c
+#define PARM_SRC_DST_BIDX 0x10
+#define PARM_LINK_BCNTRLD 0x14
+#define PARM_SRC_DST_CIDX 0x18
+#define PARM_CCNT 0x1c
+
+#define PARM_SIZE 0x20
+
+/* Offsets for EDMA CC global channel registers and their shadows */
+#define SH_ER 0x00 /* 64 bits */
+#define SH_ECR 0x08 /* 64 bits */
+#define SH_ESR 0x10 /* 64 bits */
+#define SH_CER 0x18 /* 64 bits */
+#define SH_EER 0x20 /* 64 bits */
+#define SH_EECR 0x28 /* 64 bits */
+#define SH_EESR 0x30 /* 64 bits */
+#define SH_SER 0x38 /* 64 bits */
+#define SH_SECR 0x40 /* 64 bits */
+#define SH_IER 0x50 /* 64 bits */
+#define SH_IECR 0x58 /* 64 bits */
+#define SH_IESR 0x60 /* 64 bits */
+#define SH_IPR 0x68 /* 64 bits */
+#define SH_ICR 0x70 /* 64 bits */
+#define SH_IEVAL 0x78
+#define SH_QER 0x80
+#define SH_QEER 0x84
+#define SH_QEECR 0x88
+#define SH_QEESR 0x8c
+#define SH_QSER 0x90
+#define SH_QSECR 0x94
+#define SH_SIZE 0x200
+
+/* Offsets for EDMA CC global registers */
+#define EDMA_REV 0x0000
+#define EDMA_CCCFG 0x0004
+#define EDMA_QCHMAP 0x0200 /* 8 registers */
+#define EDMA_DMAQNUM 0x0240 /* 8 registers (4 on OMAP-L1xx) */
+#define EDMA_QDMAQNUM 0x0260
+#define EDMA_QUETCMAP 0x0280
+#define EDMA_QUEPRI 0x0284
+#define EDMA_EMR 0x0300 /* 64 bits */
+#define EDMA_EMCR 0x0308 /* 64 bits */
+#define EDMA_QEMR 0x0310
+#define EDMA_QEMCR 0x0314
+#define EDMA_CCERR 0x0318
+#define EDMA_CCERRCLR 0x031c
+#define EDMA_EEVAL 0x0320
+#define EDMA_DRAE 0x0340 /* 4 x 64 bits*/
+#define EDMA_QRAE 0x0380 /* 4 registers */
+#define EDMA_QUEEVTENTRY 0x0400 /* 2 x 16 registers */
+#define EDMA_QSTAT 0x0600 /* 2 registers */
+#define EDMA_QWMTHRA 0x0620
+#define EDMA_QWMTHRB 0x0624
+#define EDMA_CCSTAT 0x0640
+
+#define EDMA_M 0x1000 /* global channel registers */
+#define EDMA_ECR 0x1008
+#define EDMA_ECRH 0x100C
+#define EDMA_SHADOW0 0x2000 /* 4 regions shadowing global channels */
+#define EDMA_PARM 0x4000 /* 128 param entries */
+
+#define PARM_OFFSET(param_no) (EDMA_PARM + ((param_no) << 5))
+
+#define EDMA_DCHMAP 0x0100 /* 64 registers */
+#define CHMAP_EXIST BIT(24)
+
+#define EDMA_MAX_DMACH 64
+#define EDMA_MAX_PARAMENTRY 512
+
+/*****************************************************************************/
+
+static void __iomem *edmacc_regs_base[EDMA_MAX_CC];
+
+static inline unsigned int edma_read(unsigned ctlr, int offset)
+{
+ return (unsigned int)__raw_readl(edmacc_regs_base[ctlr] + offset);
+}
+
+static inline void edma_write(unsigned ctlr, int offset, int val)
+{
+ __raw_writel(val, edmacc_regs_base[ctlr] + offset);
+}
+static inline void edma_modify(unsigned ctlr, int offset, unsigned and,
+ unsigned or)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val &= and;
+ val |= or;
+ edma_write(ctlr, offset, val);
+}
+static inline void edma_and(unsigned ctlr, int offset, unsigned and)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val &= and;
+ edma_write(ctlr, offset, val);
+}
+static inline void edma_or(unsigned ctlr, int offset, unsigned or)
+{
+ unsigned val = edma_read(ctlr, offset);
+ val |= or;
+ edma_write(ctlr, offset, val);
+}
+static inline unsigned int edma_read_array(unsigned ctlr, int offset, int i)
+{
+ return edma_read(ctlr, offset + (i << 2));
+}
+static inline void edma_write_array(unsigned ctlr, int offset, int i,
+ unsigned val)
+{
+ edma_write(ctlr, offset + (i << 2), val);
+}
+static inline void edma_modify_array(unsigned ctlr, int offset, int i,
+ unsigned and, unsigned or)
+{
+ edma_modify(ctlr, offset + (i << 2), and, or);
+}
+static inline void edma_or_array(unsigned ctlr, int offset, int i, unsigned or)
+{
+ edma_or(ctlr, offset + (i << 2), or);
+}
+static inline void edma_or_array2(unsigned ctlr, int offset, int i, int j,
+ unsigned or)
+{
+ edma_or(ctlr, offset + ((i*2 + j) << 2), or);
+}
+static inline void edma_write_array2(unsigned ctlr, int offset, int i, int j,
+ unsigned val)
+{
+ edma_write(ctlr, offset + ((i*2 + j) << 2), val);
+}
+static inline unsigned int edma_shadow0_read(unsigned ctlr, int offset)
+{
+ return edma_read(ctlr, EDMA_SHADOW0 + offset);
+}
+static inline unsigned int edma_shadow0_read_array(unsigned ctlr, int offset,
+ int i)
+{
+ return edma_read(ctlr, EDMA_SHADOW0 + offset + (i << 2));
+}
+static inline void edma_shadow0_write(unsigned ctlr, int offset, unsigned val)
+{
+ edma_write(ctlr, EDMA_SHADOW0 + offset, val);
+}
+static inline void edma_shadow0_write_array(unsigned ctlr, int offset, int i,
+ unsigned val)
+{
+ edma_write(ctlr, EDMA_SHADOW0 + offset + (i << 2), val);
+}
+static inline unsigned int edma_parm_read(unsigned ctlr, int offset,
+ int param_no)
+{
+ return edma_read(ctlr, EDMA_PARM + offset + (param_no << 5));
+}
+static inline void edma_parm_write(unsigned ctlr, int offset, int param_no,
+ unsigned val)
+{
+ edma_write(ctlr, EDMA_PARM + offset + (param_no << 5), val);
+}
+static inline void edma_parm_modify(unsigned ctlr, int offset, int param_no,
+ unsigned and, unsigned or)
+{
+ edma_modify(ctlr, EDMA_PARM + offset + (param_no << 5), and, or);
+}
+static inline void edma_parm_and(unsigned ctlr, int offset, int param_no,
+ unsigned and)
+{
+ edma_and(ctlr, EDMA_PARM + offset + (param_no << 5), and);
+}
+static inline void edma_parm_or(unsigned ctlr, int offset, int param_no,
+ unsigned or)
+{
+ edma_or(ctlr, EDMA_PARM + offset + (param_no << 5), or);
+}
+
+static inline void set_bits(int offset, int len, unsigned long *p)
+{
+ for (; len > 0; len--)
+ set_bit(offset + (len - 1), p);
+}
+
+static inline void clear_bits(int offset, int len, unsigned long *p)
+{
+ for (; len > 0; len--)
+ clear_bit(offset + (len - 1), p);
+}
+
+/*****************************************************************************/
+
+/* actual number of DMA channels and slots on this silicon */
+struct edma {
+ /* how many dma resources of each type */
+ unsigned num_channels;
+ unsigned num_region;
+ unsigned num_slots;
+ unsigned num_tc;
+ unsigned num_cc;
+ enum dma_event_q default_queue;
+
+ /* list of channels with no even trigger; terminated by "-1" */
+ const s8 *noevent;
+
+ /* The edma_inuse bit for each PaRAM slot is clear unless the
+ * channel is in use ... by ARM or DSP, for QDMA, or whatever.
+ */
+ DECLARE_BITMAP(edma_inuse, EDMA_MAX_PARAMENTRY);
+
+ /* The edma_unused bit for each channel is clear unless
+ * it is not being used on this platform. It uses a bit
+ * of SOC-specific initialization code.
+ */
+ DECLARE_BITMAP(edma_unused, EDMA_MAX_DMACH);
+
+ unsigned irq_res_start;
+ unsigned irq_res_end;
+
+ struct dma_interrupt_data {
+ void (*callback)(unsigned channel, unsigned short ch_status,
+ void *data);
+ void *data;
+ } intr_data[EDMA_MAX_DMACH];
+};
+
+static struct edma *edma_cc[EDMA_MAX_CC];
+static int arch_num_cc;
+
+/* dummy param set used to (re)initialize parameter RAM slots */
+static const struct edmacc_param dummy_paramset = {
+ .link_bcntrld = 0xffff,
+ .ccnt = 1,
+};
+
+/*****************************************************************************/
+
+static void map_dmach_queue(unsigned ctlr, unsigned ch_no,
+ enum dma_event_q queue_no)
+{
+ int bit = (ch_no & 0x7) * 4;
+
+ /* default to low priority queue */
+ if (queue_no == EVENTQ_DEFAULT)
+ queue_no = edma_cc[ctlr]->default_queue;
+
+ queue_no &= 7;
+ edma_modify_array(ctlr, EDMA_DMAQNUM, (ch_no >> 3),
+ ~(0x7 << bit), queue_no << bit);
+}
+
+static void __init map_queue_tc(unsigned ctlr, int queue_no, int tc_no)
+{
+ int bit = queue_no * 4;
+ edma_modify(ctlr, EDMA_QUETCMAP, ~(0x7 << bit), ((tc_no & 0x7) << bit));
+}
+
+static void __init assign_priority_to_queue(unsigned ctlr, int queue_no,
+ int priority)
+{
+ int bit = queue_no * 4;
+ edma_modify(ctlr, EDMA_QUEPRI, ~(0x7 << bit),
+ ((priority & 0x7) << bit));
+}
+
+/**
+ * map_dmach_param - Maps channel number to param entry number
+ *
+ * This maps the dma channel number to param entry numberter. In
+ * other words using the DMA channel mapping registers a param entry
+ * can be mapped to any channel
+ *
+ * Callers are responsible for ensuring the channel mapping logic is
+ * included in that particular EDMA variant (Eg : dm646x)
+ *
+ */
+static void __init map_dmach_param(unsigned ctlr)
+{
+ int i;
+ for (i = 0; i < EDMA_MAX_DMACH; i++)
+ edma_write_array(ctlr, EDMA_DCHMAP , i , (i << 5));
+}
+
+static inline void
+setup_dma_interrupt(unsigned lch,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(lch);
+ lch = EDMA_CHAN_SLOT(lch);
+
+ if (!callback)
+ edma_shadow0_write_array(ctlr, SH_IECR, lch >> 5,
+ BIT(lch & 0x1f));
+
+ edma_cc[ctlr]->intr_data[lch].callback = callback;
+ edma_cc[ctlr]->intr_data[lch].data = data;
+
+ if (callback) {
+ edma_shadow0_write_array(ctlr, SH_ICR, lch >> 5,
+ BIT(lch & 0x1f));
+ edma_shadow0_write_array(ctlr, SH_IESR, lch >> 5,
+ BIT(lch & 0x1f));
+ }
+}
+
+static int irq2ctlr(int irq)
+{
+ if (irq >= edma_cc[0]->irq_res_start && irq <= edma_cc[0]->irq_res_end)
+ return 0;
+ else if (irq >= edma_cc[1]->irq_res_start &&
+ irq <= edma_cc[1]->irq_res_end)
+ return 1;
+
+ return -1;
+}
+
+/******************************************************************************
+ *
+ * DMA interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_irq_handler(int irq, void *data)
+{
+ int i;
+ int ctlr;
+ unsigned int cnt = 0;
+
+ ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
+
+ dev_dbg(data, "dma_irq_handler\n");
+
+ if ((edma_shadow0_read_array(ctlr, SH_IPR, 0) == 0) &&
+ (edma_shadow0_read_array(ctlr, SH_IPR, 1) == 0))
+ return IRQ_NONE;
+
+ while (1) {
+ int j;
+ if (edma_shadow0_read_array(ctlr, SH_IPR, 0) &
+ edma_shadow0_read_array(ctlr, SH_IER, 0))
+ j = 0;
+ else if (edma_shadow0_read_array(ctlr, SH_IPR, 1) &
+ edma_shadow0_read_array(ctlr, SH_IER, 1))
+ j = 1;
+ else
+ break;
+ dev_dbg(data, "IPR%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_IPR, j));
+ for (i = 0; i < 32; i++) {
+ int k = (j << 5) + i;
+ if ((edma_shadow0_read_array(ctlr, SH_IPR, j) & BIT(i))
+ && (edma_shadow0_read_array(ctlr,
+ SH_IER, j) & BIT(i))) {
+ /* Clear the corresponding IPR bits */
+ edma_shadow0_write_array(ctlr, SH_ICR, j,
+ BIT(i));
+ if (edma_cc[ctlr]->intr_data[k].callback)
+ edma_cc[ctlr]->intr_data[k].callback(
+ k, DMA_COMPLETE,
+ edma_cc[ctlr]->intr_data[k].
+ data);
+ }
+ }
+ cnt++;
+ if (cnt > 10)
+ break;
+ }
+ edma_shadow0_write(ctlr, SH_IEVAL, 1);
+ return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * DMA error interrupt handler
+ *
+ *****************************************************************************/
+static irqreturn_t dma_ccerr_handler(int irq, void *data)
+{
+ int i;
+ int ctlr;
+ unsigned int cnt = 0;
+
+ ctlr = irq2ctlr(irq);
+ if (ctlr < 0)
+ return IRQ_NONE;
+
+ dev_dbg(data, "dma_ccerr_handler\n");
+
+ if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+ (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+ (edma_read(ctlr, EDMA_QEMR) == 0) &&
+ (edma_read(ctlr, EDMA_CCERR) == 0))
+ return IRQ_NONE;
+
+ while (1) {
+ int j = -1;
+ if (edma_read_array(ctlr, EDMA_EMR, 0))
+ j = 0;
+ else if (edma_read_array(ctlr, EDMA_EMR, 1))
+ j = 1;
+ if (j >= 0) {
+ dev_dbg(data, "EMR%d %08x\n", j,
+ edma_read_array(ctlr, EDMA_EMR, j));
+ for (i = 0; i < 32; i++) {
+ int k = (j << 5) + i;
+ if (edma_read_array(ctlr, EDMA_EMR, j) &
+ BIT(i)) {
+ /* Clear the corresponding EMR bits */
+ edma_write_array(ctlr, EDMA_EMCR, j,
+ BIT(i));
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR,
+ j, BIT(i));
+ if (edma_cc[ctlr]->intr_data[k].
+ callback) {
+ edma_cc[ctlr]->intr_data[k].
+ callback(k,
+ DMA_CC_ERROR,
+ edma_cc[ctlr]->intr_data
+ [k].data);
+ }
+ }
+ }
+ } else if (edma_read(ctlr, EDMA_QEMR)) {
+ dev_dbg(data, "QEMR %02x\n",
+ edma_read(ctlr, EDMA_QEMR));
+ for (i = 0; i < 8; i++) {
+ if (edma_read(ctlr, EDMA_QEMR) & BIT(i)) {
+ /* Clear the corresponding IPR bits */
+ edma_write(ctlr, EDMA_QEMCR, BIT(i));
+ edma_shadow0_write(ctlr, SH_QSECR,
+ BIT(i));
+
+ /* NOTE: not reported!! */
+ }
+ }
+ } else if (edma_read(ctlr, EDMA_CCERR)) {
+ dev_dbg(data, "CCERR %08x\n",
+ edma_read(ctlr, EDMA_CCERR));
+ /* FIXME: CCERR.BIT(16) ignored! much better
+ * to just write CCERRCLR with CCERR value...
+ */
+ for (i = 0; i < 8; i++) {
+ if (edma_read(ctlr, EDMA_CCERR) & BIT(i)) {
+ /* Clear the corresponding IPR bits */
+ edma_write(ctlr, EDMA_CCERRCLR, BIT(i));
+
+ /* NOTE: not reported!! */
+ }
+ }
+ }
+ if ((edma_read_array(ctlr, EDMA_EMR, 0) == 0) &&
+ (edma_read_array(ctlr, EDMA_EMR, 1) == 0) &&
+ (edma_read(ctlr, EDMA_QEMR) == 0) &&
+ (edma_read(ctlr, EDMA_CCERR) == 0))
+ break;
+ cnt++;
+ if (cnt > 10)
+ break;
+ }
+ edma_write(ctlr, EDMA_EEVAL, 1);
+ return IRQ_HANDLED;
+}
+
+/******************************************************************************
+ *
+ * Transfer controller error interrupt handlers
+ *
+ *****************************************************************************/
+
+#define tc_errs_handled false /* disabled as long as they're NOPs */
+
+static irqreturn_t dma_tc0err_handler(int irq, void *data)
+{
+ dev_dbg(data, "dma_tc0err_handler\n");
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dma_tc1err_handler(int irq, void *data)
+{
+ dev_dbg(data, "dma_tc1err_handler\n");
+ return IRQ_HANDLED;
+}
+
+static int reserve_contiguous_slots(int ctlr, unsigned int id,
+ unsigned int num_slots,
+ unsigned int start_slot)
+{
+ int i, j;
+ unsigned int count = num_slots;
+ int stop_slot = start_slot;
+ DECLARE_BITMAP(tmp_inuse, EDMA_MAX_PARAMENTRY);
+
+ for (i = start_slot; i < edma_cc[ctlr]->num_slots; ++i) {
+ j = EDMA_CHAN_SLOT(i);
+ if (!test_and_set_bit(j, edma_cc[ctlr]->edma_inuse)) {
+ /* Record our current beginning slot */
+ if (count == num_slots)
+ stop_slot = i;
+
+ count--;
+ set_bit(j, tmp_inuse);
+
+ if (count == 0)
+ break;
+ } else {
+ clear_bit(j, tmp_inuse);
+
+ if (id == EDMA_CONT_PARAMS_FIXED_EXACT) {
+ stop_slot = i;
+ break;
+ } else {
+ count = num_slots;
+ }
+ }
+ }
+
+ /*
+ * We have to clear any bits that we set
+ * if we run out parameter RAM slots, i.e we do find a set
+ * of contiguous parameter RAM slots but do not find the exact number
+ * requested as we may reach the total number of parameter RAM slots
+ */
+ if (i == edma_cc[ctlr]->num_slots)
+ stop_slot = i;
+
+ for (j = start_slot; j < stop_slot; j++)
+ if (test_bit(j, tmp_inuse))
+ clear_bit(j, edma_cc[ctlr]->edma_inuse);
+
+ if (count)
+ return -EBUSY;
+
+ for (j = i - num_slots + 1; j <= i; ++j)
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(j),
+ &dummy_paramset, PARM_SIZE);
+
+ return EDMA_CTLR_CHAN(ctlr, i - num_slots + 1);
+}
+
+static int prepare_unused_channel_list(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int i, ctlr;
+
+ for (i = 0; i < pdev->num_resources; i++) {
+ if ((pdev->resource[i].flags & IORESOURCE_DMA) &&
+ (int)pdev->resource[i].start >= 0) {
+ ctlr = EDMA_CTLR(pdev->resource[i].start);
+ clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start),
+ edma_cc[ctlr]->edma_unused);
+ }
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------*/
+
+static bool unused_chan_list_done;
+
+/* Resource alloc/free: dma channels, parameter RAM slots */
+
+/**
+ * edma_alloc_channel - allocate DMA channel and paired parameter RAM
+ * @channel: specific channel to allocate; negative for "any unmapped channel"
+ * @callback: optional; to be issued on DMA completion or errors
+ * @data: passed to callback
+ * @eventq_no: an EVENTQ_* constant, used to choose which Transfer
+ * Controller (TC) executes requests using this channel. Use
+ * EVENTQ_DEFAULT unless you really need a high priority queue.
+ *
+ * This allocates a DMA channel and its associated parameter RAM slot.
+ * The parameter RAM is initialized to hold a dummy transfer.
+ *
+ * Normal use is to pass a specific channel number as @channel, to make
+ * use of hardware events mapped to that channel. When the channel will
+ * be used only for software triggering or event chaining, channels not
+ * mapped to hardware events (or mapped to unused events) are preferable.
+ *
+ * DMA transfers start from a channel using edma_start(), or by
+ * chaining. When the transfer described in that channel's parameter RAM
+ * slot completes, that slot's data may be reloaded through a link.
+ *
+ * DMA errors are only reported to the @callback associated with the
+ * channel driving that transfer, but transfer completion callbacks can
+ * be sent to another channel under control of the TCC field in
+ * the option word of the transfer's parameter RAM set. Drivers must not
+ * use DMA transfer completion callbacks for channels they did not allocate.
+ * (The same applies to TCC codes used in transfer chaining.)
+ *
+ * Returns the number of the channel, else negative errno.
+ */
+int edma_alloc_channel(int channel,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data,
+ enum dma_event_q eventq_no)
+{
+ unsigned i, done = 0, ctlr = 0;
+ int ret = 0;
+
+ if (!unused_chan_list_done) {
+ /*
+ * Scan all the platform devices to find out the EDMA channels
+ * used and clear them in the unused list, making the rest
+ * available for ARM usage.
+ */
+ ret = bus_for_each_dev(&platform_bus_type, NULL, NULL,
+ prepare_unused_channel_list);
+ if (ret < 0)
+ return ret;
+
+ unused_chan_list_done = true;
+ }
+
+ if (channel >= 0) {
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+ }
+
+ if (channel < 0) {
+ for (i = 0; i < arch_num_cc; i++) {
+ channel = 0;
+ for (;;) {
+ channel = find_next_bit(edma_cc[i]->edma_unused,
+ edma_cc[i]->num_channels,
+ channel);
+ if (channel == edma_cc[i]->num_channels)
+ break;
+ if (!test_and_set_bit(channel,
+ edma_cc[i]->edma_inuse)) {
+ done = 1;
+ ctlr = i;
+ break;
+ }
+ channel++;
+ }
+ if (done)
+ break;
+ }
+ if (!done)
+ return -ENOMEM;
+ } else if (channel >= edma_cc[ctlr]->num_channels) {
+ return -EINVAL;
+ } else if (test_and_set_bit(channel, edma_cc[ctlr]->edma_inuse)) {
+ return -EBUSY;
+ }
+
+ /* ensure access through shadow region 0 */
+ edma_or_array2(ctlr, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
+
+ /* ensure no events are pending */
+ edma_stop(EDMA_CTLR_CHAN(ctlr, channel));
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+ &dummy_paramset, PARM_SIZE);
+
+ if (callback)
+ setup_dma_interrupt(EDMA_CTLR_CHAN(ctlr, channel),
+ callback, data);
+
+ map_dmach_queue(ctlr, channel, eventq_no);
+
+ return EDMA_CTLR_CHAN(ctlr, channel);
+}
+EXPORT_SYMBOL(edma_alloc_channel);
+
+
+/**
+ * edma_free_channel - deallocate DMA channel
+ * @channel: dma channel returned from edma_alloc_channel()
+ *
+ * This deallocates the DMA channel and associated parameter RAM slot
+ * allocated by edma_alloc_channel().
+ *
+ * Callers are responsible for ensuring the channel is inactive, and
+ * will not be reactivated by linking, chaining, or software calls to
+ * edma_start().
+ */
+void edma_free_channel(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel >= edma_cc[ctlr]->num_channels)
+ return;
+
+ setup_dma_interrupt(channel, NULL, NULL);
+ /* REVISIT should probably take out of shadow region 0 */
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(channel),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(channel, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_channel);
+
+/**
+ * edma_alloc_slot - allocate DMA parameter RAM
+ * @slot: specific slot to allocate; negative for "any unused slot"
+ *
+ * This allocates a parameter RAM slot, initializing it to hold a
+ * dummy transfer. Slots allocated using this routine have not been
+ * mapped to a hardware DMA channel, and will normally be used by
+ * linking to them from a slot associated with a DMA channel.
+ *
+ * Normal use is to pass EDMA_SLOT_ANY as the @slot, but specific
+ * slots may be allocated on behalf of DSP firmware.
+ *
+ * Returns the number of the slot, else negative errno.
+ */
+int edma_alloc_slot(unsigned ctlr, int slot)
+{
+ if (slot >= 0)
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < 0) {
+ slot = edma_cc[ctlr]->num_channels;
+ for (;;) {
+ slot = find_next_zero_bit(edma_cc[ctlr]->edma_inuse,
+ edma_cc[ctlr]->num_slots, slot);
+ if (slot == edma_cc[ctlr]->num_slots)
+ return -ENOMEM;
+ if (!test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse))
+ break;
+ }
+ } else if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots) {
+ return -EINVAL;
+ } else if (test_and_set_bit(slot, edma_cc[ctlr]->edma_inuse)) {
+ return -EBUSY;
+ }
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ &dummy_paramset, PARM_SIZE);
+
+ return EDMA_CTLR_CHAN(ctlr, slot);
+}
+EXPORT_SYMBOL(edma_alloc_slot);
+
+/**
+ * edma_free_slot - deallocate DMA parameter RAM
+ * @slot: parameter RAM slot returned from edma_alloc_slot()
+ *
+ * This deallocates the parameter RAM slot allocated by edma_alloc_slot().
+ * Callers are responsible for ensuring the slot is inactive, and will
+ * not be activated.
+ */
+void edma_free_slot(unsigned slot)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots)
+ return;
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(slot, edma_cc[ctlr]->edma_inuse);
+}
+EXPORT_SYMBOL(edma_free_slot);
+
+
+/**
+ * edma_alloc_cont_slots- alloc contiguous parameter RAM slots
+ * The API will return the starting point of a set of
+ * contiguous parameter RAM slots that have been requested
+ *
+ * @id: can only be EDMA_CONT_PARAMS_ANY or EDMA_CONT_PARAMS_FIXED_EXACT
+ * or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ * @count: number of contiguous Paramter RAM slots
+ * @slot - the start value of Parameter RAM slot that should be passed if id
+ * is EDMA_CONT_PARAMS_FIXED_EXACT or EDMA_CONT_PARAMS_FIXED_NOT_EXACT
+ *
+ * If id is EDMA_CONT_PARAMS_ANY then the API starts looking for a set of
+ * contiguous Parameter RAM slots from parameter RAM 64 in the case of
+ * DaVinci SOCs and 32 in the case of DA8xx SOCs.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_EXACT then the API starts looking for a
+ * set of contiguous parameter RAM slots from the "slot" that is passed as an
+ * argument to the API.
+ *
+ * If id is EDMA_CONT_PARAMS_FIXED_NOT_EXACT then the API initially tries
+ * starts looking for a set of contiguous parameter RAMs from the "slot"
+ * that is passed as an argument to the API. On failure the API will try to
+ * find a set of contiguous Parameter RAM slots from the remaining Parameter
+ * RAM slots
+ */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count)
+{
+ /*
+ * The start slot requested should be greater than
+ * the number of channels and lesser than the total number
+ * of slots
+ */
+ if ((id != EDMA_CONT_PARAMS_ANY) &&
+ (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots))
+ return -EINVAL;
+
+ /*
+ * The number of parameter RAM slots requested cannot be less than 1
+ * and cannot be more than the number of slots minus the number of
+ * channels
+ */
+ if (count < 1 || count >
+ (edma_cc[ctlr]->num_slots - edma_cc[ctlr]->num_channels))
+ return -EINVAL;
+
+ switch (id) {
+ case EDMA_CONT_PARAMS_ANY:
+ return reserve_contiguous_slots(ctlr, id, count,
+ edma_cc[ctlr]->num_channels);
+ case EDMA_CONT_PARAMS_FIXED_EXACT:
+ case EDMA_CONT_PARAMS_FIXED_NOT_EXACT:
+ return reserve_contiguous_slots(ctlr, id, count, slot);
+ default:
+ return -EINVAL;
+ }
+
+}
+EXPORT_SYMBOL(edma_alloc_cont_slots);
+
+/**
+ * edma_free_cont_slots - deallocate DMA parameter RAM slots
+ * @slot: first parameter RAM of a set of parameter RAM slots to be freed
+ * @count: the number of contiguous parameter RAM slots to be freed
+ *
+ * This deallocates the parameter RAM slots allocated by
+ * edma_alloc_cont_slots.
+ * Callers/applications need to keep track of sets of contiguous
+ * parameter RAM slots that have been allocated using the edma_alloc_cont_slots
+ * API.
+ * Callers are responsible for ensuring the slots are inactive, and will
+ * not be activated.
+ */
+int edma_free_cont_slots(unsigned slot, int count)
+{
+ unsigned ctlr, slot_to_free;
+ int i;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_channels ||
+ slot >= edma_cc[ctlr]->num_slots ||
+ count < 1)
+ return -EINVAL;
+
+ for (i = slot; i < slot + count; ++i) {
+ ctlr = EDMA_CTLR(i);
+ slot_to_free = EDMA_CHAN_SLOT(i);
+
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot_to_free),
+ &dummy_paramset, PARM_SIZE);
+ clear_bit(slot_to_free, edma_cc[ctlr]->edma_inuse);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(edma_free_cont_slots);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (i) -- read/write partial slots */
+
+/**
+ * edma_set_src - set initial DMA source address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @src_port: physical address of source (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the source address is modified during the DMA transfer
+ * according to edma_set_src_index().
+ */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+ enum address_mode mode, enum fifo_width width)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+ if (mode) {
+ /* set SAM and program FWID */
+ i = (i & ~(EDMA_FWID)) | (SAM | ((width & 0x7) << 8));
+ } else {
+ /* clear SAM */
+ i &= ~SAM;
+ }
+ edma_parm_write(ctlr, PARM_OPT, slot, i);
+
+ /* set the source port address
+ in source register of param structure */
+ edma_parm_write(ctlr, PARM_SRC, slot, src_port);
+ }
+}
+EXPORT_SYMBOL(edma_set_src);
+
+/**
+ * edma_set_dest - set initial DMA destination address in parameter RAM slot
+ * @slot: parameter RAM slot being configured
+ * @dest_port: physical address of destination (memory, controller FIFO, etc)
+ * @addressMode: INCR, except in very rare cases
+ * @fifoWidth: ignored unless @addressMode is FIFO, else specifies the
+ * width to use when addressing the fifo (e.g. W8BIT, W32BIT)
+ *
+ * Note that the destination address is modified during the DMA transfer
+ * according to edma_set_dest_index().
+ */
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+ enum address_mode mode, enum fifo_width width)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ unsigned int i = edma_parm_read(ctlr, PARM_OPT, slot);
+
+ if (mode) {
+ /* set DAM and program FWID */
+ i = (i & ~(EDMA_FWID)) | (DAM | ((width & 0x7) << 8));
+ } else {
+ /* clear DAM */
+ i &= ~DAM;
+ }
+ edma_parm_write(ctlr, PARM_OPT, slot, i);
+ /* set the destination port address
+ in dest register of param structure */
+ edma_parm_write(ctlr, PARM_DST, slot, dest_port);
+ }
+}
+EXPORT_SYMBOL(edma_set_dest);
+
+/**
+ * edma_get_position - returns the current transfer points
+ * @slot: parameter RAM slot being examined
+ * @src: pointer to source port position
+ * @dst: pointer to destination port position
+ *
+ * Returns current source and destination addresses for a particular
+ * parameter RAM slot. Its channel should not be active when this is called.
+ */
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst)
+{
+ struct edmacc_param temp;
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ edma_read_slot(EDMA_CTLR_CHAN(ctlr, slot), &temp);
+ if (src != NULL)
+ *src = temp.src;
+ if (dst != NULL)
+ *dst = temp.dst;
+}
+EXPORT_SYMBOL(edma_get_position);
+
+/**
+ * edma_set_src_index - configure DMA source address indexing
+ * @slot: parameter RAM slot being configured
+ * @src_bidx: byte offset between source arrays in a frame
+ * @src_cidx: byte offset between source frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+ 0xffff0000, src_bidx);
+ edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+ 0xffff0000, src_cidx);
+ }
+}
+EXPORT_SYMBOL(edma_set_src_index);
+
+/**
+ * edma_set_dest_index - configure DMA destination address indexing
+ * @slot: parameter RAM slot being configured
+ * @dest_bidx: byte offset between destination arrays in a frame
+ * @dest_cidx: byte offset between destination frames in a block
+ *
+ * Offsets are specified to support either contiguous or discontiguous
+ * memory transfers, or repeated access to a hardware register, as needed.
+ * When accessing hardware registers, both offsets are normally zero.
+ */
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_SRC_DST_BIDX, slot,
+ 0x0000ffff, dest_bidx << 16);
+ edma_parm_modify(ctlr, PARM_SRC_DST_CIDX, slot,
+ 0x0000ffff, dest_cidx << 16);
+ }
+}
+EXPORT_SYMBOL(edma_set_dest_index);
+
+/**
+ * edma_set_transfer_params - configure DMA transfer parameters
+ * @slot: parameter RAM slot being configured
+ * @acnt: how many bytes per array (at least one)
+ * @bcnt: how many arrays per frame (at least one)
+ * @ccnt: how many frames per block (at least one)
+ * @bcnt_rld: used only for A-Synchronized transfers; this specifies
+ * the value to reload into bcnt when it decrements to zero
+ * @sync_mode: ASYNC or ABSYNC
+ *
+ * See the EDMA3 documentation to understand how to configure and link
+ * transfers using the fields in PaRAM slots. If you are not doing it
+ * all at once with edma_write_slot(), you will use this routine
+ * plus two calls each for source and destination, setting the initial
+ * address and saying how to index that address.
+ *
+ * An example of an A-Synchronized transfer is a serial link using a
+ * single word shift register. In that case, @acnt would be equal to
+ * that word size; the serial controller issues a DMA synchronization
+ * event to transfer each word, and memory access by the DMA transfer
+ * controller will be word-at-a-time.
+ *
+ * An example of an AB-Synchronized transfer is a device using a FIFO.
+ * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
+ * The controller with the FIFO issues DMA synchronization events when
+ * the FIFO threshold is reached, and the DMA transfer controller will
+ * transfer one frame to (or from) the FIFO. It will probably use
+ * efficient burst modes to access memory.
+ */
+void edma_set_transfer_params(unsigned slot,
+ u16 acnt, u16 bcnt, u16 ccnt,
+ u16 bcnt_rld, enum sync_dimension sync_mode)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot < edma_cc[ctlr]->num_slots) {
+ edma_parm_modify(ctlr, PARM_LINK_BCNTRLD, slot,
+ 0x0000ffff, bcnt_rld << 16);
+ if (sync_mode == ASYNC)
+ edma_parm_and(ctlr, PARM_OPT, slot, ~SYNCDIM);
+ else
+ edma_parm_or(ctlr, PARM_OPT, slot, SYNCDIM);
+ /* Set the acount, bcount, ccount registers */
+ edma_parm_write(ctlr, PARM_A_B_CNT, slot, (bcnt << 16) | acnt);
+ edma_parm_write(ctlr, PARM_CCNT, slot, ccnt);
+ }
+}
+EXPORT_SYMBOL(edma_set_transfer_params);
+
+/**
+ * edma_link - link one parameter RAM slot to another
+ * @from: parameter RAM slot originating the link
+ * @to: parameter RAM slot which is the link target
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ */
+void edma_link(unsigned from, unsigned to)
+{
+ unsigned ctlr_from, ctlr_to;
+
+ ctlr_from = EDMA_CTLR(from);
+ from = EDMA_CHAN_SLOT(from);
+ ctlr_to = EDMA_CTLR(to);
+ to = EDMA_CHAN_SLOT(to);
+
+ if (from >= edma_cc[ctlr_from]->num_slots)
+ return;
+ if (to >= edma_cc[ctlr_to]->num_slots)
+ return;
+ edma_parm_modify(ctlr_from, PARM_LINK_BCNTRLD, from, 0xffff0000,
+ PARM_OFFSET(to));
+}
+EXPORT_SYMBOL(edma_link);
+
+/**
+ * edma_unlink - cut link from one parameter RAM slot
+ * @from: parameter RAM slot originating the link
+ *
+ * The originating slot should not be part of any active DMA transfer.
+ * Its link is set to 0xffff.
+ */
+void edma_unlink(unsigned from)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(from);
+ from = EDMA_CHAN_SLOT(from);
+
+ if (from >= edma_cc[ctlr]->num_slots)
+ return;
+ edma_parm_or(ctlr, PARM_LINK_BCNTRLD, from, 0xffff);
+}
+EXPORT_SYMBOL(edma_unlink);
+
+/*-----------------------------------------------------------------------*/
+
+/* Parameter RAM operations (ii) -- read/write whole parameter sets */
+
+/**
+ * edma_write_slot - write parameter RAM data for slot
+ * @slot: number of parameter RAM slot being modified
+ * @param: data to be written into parameter RAM slot
+ *
+ * Use this to assign all parameters of a transfer at once. This
+ * allows more efficient setup of transfers than issuing multiple
+ * calls to set up those parameters in small pieces, and provides
+ * complete control over all transfer options.
+ */
+void edma_write_slot(unsigned slot, const struct edmacc_param *param)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot >= edma_cc[ctlr]->num_slots)
+ return;
+ memcpy_toio(edmacc_regs_base[ctlr] + PARM_OFFSET(slot), param,
+ PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_write_slot);
+
+/**
+ * edma_read_slot - read parameter RAM data from slot
+ * @slot: number of parameter RAM slot being copied
+ * @param: where to store copy of parameter RAM data
+ *
+ * Use this to read data from a parameter RAM slot, perhaps to
+ * save them as a template for later reuse.
+ */
+void edma_read_slot(unsigned slot, struct edmacc_param *param)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(slot);
+ slot = EDMA_CHAN_SLOT(slot);
+
+ if (slot >= edma_cc[ctlr]->num_slots)
+ return;
+ memcpy_fromio(param, edmacc_regs_base[ctlr] + PARM_OFFSET(slot),
+ PARM_SIZE);
+}
+EXPORT_SYMBOL(edma_read_slot);
+
+/*-----------------------------------------------------------------------*/
+
+/* Various EDMA channel control operations */
+
+/**
+ * edma_pause - pause dma on a channel
+ * @channel: on which edma_start() has been called
+ *
+ * This temporarily disables EDMA hardware events on the specified channel,
+ * preventing them from triggering new transfers on its behalf
+ */
+void edma_pause(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EECR, channel >> 5, mask);
+ }
+}
+EXPORT_SYMBOL(edma_pause);
+
+/**
+ * edma_resume - resumes dma on a paused channel
+ * @channel: on which edma_pause() has been called
+ *
+ * This re-enables EDMA hardware events on the specified channel.
+ */
+void edma_resume(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EESR, channel >> 5, mask);
+ }
+}
+EXPORT_SYMBOL(edma_resume);
+
+/**
+ * edma_start - start dma on a channel
+ * @channel: channel being activated
+ *
+ * Channels with event associations will be triggered by their hardware
+ * events, and channels without such associations will be triggered by
+ * software. (At this writing there is no interface for using software
+ * triggers except with channels that don't support hardware triggers.)
+ *
+ * Returns zero on success, else negative errno.
+ */
+int edma_start(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = channel >> 5;
+ unsigned int mask = BIT(channel & 0x1f);
+
+ /* EDMA channels without event association */
+ if (test_bit(channel, edma_cc[ctlr]->edma_unused)) {
+ pr_debug("EDMA: ESR%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_ESR, j));
+ edma_shadow0_write_array(ctlr, SH_ESR, j, mask);
+ return 0;
+ }
+
+ /* EDMA channel with event association */
+ pr_debug("EDMA: ER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_ER, j));
+ /* Clear any pending event or error */
+ edma_write_array(ctlr, EDMA_ECR, j, mask);
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_EESR, j, mask);
+ pr_debug("EDMA: EER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_EER, j));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(edma_start);
+
+/**
+ * edma_stop - stops dma on the channel passed
+ * @channel: channel being deactivated
+ *
+ * When @lch is a channel, any active transfer is paused and
+ * all pending hardware events are cleared. The current transfer
+ * may not be resumed, and the channel's Parameter RAM should be
+ * reinitialized before being reused.
+ */
+void edma_stop(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = channel >> 5;
+ unsigned int mask = BIT(channel & 0x1f);
+
+ edma_shadow0_write_array(ctlr, SH_EECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+
+ pr_debug("EDMA: EER%d %08x\n", j,
+ edma_shadow0_read_array(ctlr, SH_EER, j));
+
+ /* REVISIT: consider guarding against inappropriate event
+ * chaining by overwriting with dummy_paramset.
+ */
+ }
+}
+EXPORT_SYMBOL(edma_stop);
+
+/******************************************************************************
+ *
+ * It cleans ParamEntry qand bring back EDMA to initial state if media has
+ * been removed before EDMA has finished.It is usedful for removable media.
+ * Arguments:
+ * ch_no - channel no
+ *
+ * Return: zero on success, or corresponding error no on failure
+ *
+ * FIXME this should not be needed ... edma_stop() should suffice.
+ *
+ *****************************************************************************/
+
+void edma_clean_channel(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel < edma_cc[ctlr]->num_channels) {
+ int j = (channel >> 5);
+ unsigned int mask = BIT(channel & 0x1f);
+
+ pr_debug("EDMA: EMR%d %08x\n", j,
+ edma_read_array(ctlr, EDMA_EMR, j));
+ edma_shadow0_write_array(ctlr, SH_ECR, j, mask);
+ /* Clear the corresponding EMR bits */
+ edma_write_array(ctlr, EDMA_EMCR, j, mask);
+ /* Clear any SER */
+ edma_shadow0_write_array(ctlr, SH_SECR, j, mask);
+ edma_write(ctlr, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
+ }
+}
+EXPORT_SYMBOL(edma_clean_channel);
+
+/*
+ * edma_clear_event - clear an outstanding event on the DMA channel
+ * Arguments:
+ * channel - channel number
+ */
+void edma_clear_event(unsigned channel)
+{
+ unsigned ctlr;
+
+ ctlr = EDMA_CTLR(channel);
+ channel = EDMA_CHAN_SLOT(channel);
+
+ if (channel >= edma_cc[ctlr]->num_channels)
+ return;
+ if (channel < 32)
+ edma_write(ctlr, EDMA_ECR, BIT(channel));
+ else
+ edma_write(ctlr, EDMA_ECRH, BIT(channel - 32));
+}
+EXPORT_SYMBOL(edma_clear_event);
+
+/*-----------------------------------------------------------------------*/
+
+static int __init edma_probe(struct platform_device *pdev)
+{
+ struct edma_soc_info **info = pdev->dev.platform_data;
+ const s8 (*queue_priority_mapping)[2];
+ const s8 (*queue_tc_mapping)[2];
+ int i, j, off, ln, found = 0;
+ int status = -1;
+ const s16 (*rsv_chans)[2];
+ const s16 (*rsv_slots)[2];
+ int irq[EDMA_MAX_CC] = {0, 0};
+ int err_irq[EDMA_MAX_CC] = {0, 0};
+ struct resource *r[EDMA_MAX_CC] = {NULL};
+ resource_size_t len[EDMA_MAX_CC];
+ char res_name[10];
+ char irq_name[10];
+
+ if (!info)
+ return -ENODEV;
+
+ for (j = 0; j < EDMA_MAX_CC; j++) {
+ sprintf(res_name, "edma_cc%d", j);
+ r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ res_name);
+ if (!r[j] || !info[j]) {
+ if (found)
+ break;
+ else
+ return -ENODEV;
+ } else {
+ found = 1;
+ }
+
+ len[j] = resource_size(r[j]);
+
+ r[j] = request_mem_region(r[j]->start, len[j],
+ dev_name(&pdev->dev));
+ if (!r[j]) {
+ status = -EBUSY;
+ goto fail1;
+ }
+
+ edmacc_regs_base[j] = ioremap(r[j]->start, len[j]);
+ if (!edmacc_regs_base[j]) {
+ status = -EBUSY;
+ goto fail1;
+ }
+
+ edma_cc[j] = kmalloc(sizeof(struct edma), GFP_KERNEL);
+ if (!edma_cc[j]) {
+ status = -ENOMEM;
+ goto fail1;
+ }
+ memset(edma_cc[j], 0, sizeof(struct edma));
+
+ edma_cc[j]->num_channels = min_t(unsigned, info[j]->n_channel,
+ EDMA_MAX_DMACH);
+ edma_cc[j]->num_slots = min_t(unsigned, info[j]->n_slot,
+ EDMA_MAX_PARAMENTRY);
+ edma_cc[j]->num_cc = min_t(unsigned, info[j]->n_cc,
+ EDMA_MAX_CC);
+
+ edma_cc[j]->default_queue = info[j]->default_queue;
+ if (!edma_cc[j]->default_queue)
+ edma_cc[j]->default_queue = EVENTQ_1;
+
+ dev_dbg(&pdev->dev, "DMA REG BASE ADDR=%p\n",
+ edmacc_regs_base[j]);
+
+ for (i = 0; i < edma_cc[j]->num_slots; i++)
+ memcpy_toio(edmacc_regs_base[j] + PARM_OFFSET(i),
+ &dummy_paramset, PARM_SIZE);
+
+ /* Mark all channels as unused */
+ memset(edma_cc[j]->edma_unused, 0xff,
+ sizeof(edma_cc[j]->edma_unused));
+
+ if (info[j]->rsv) {
+
+ /* Clear the reserved channels in unused list */
+ rsv_chans = info[j]->rsv->rsv_chans;
+ if (rsv_chans) {
+ for (i = 0; rsv_chans[i][0] != -1; i++) {
+ off = rsv_chans[i][0];
+ ln = rsv_chans[i][1];
+ clear_bits(off, ln,
+ edma_cc[j]->edma_unused);
+ }
+ }
+
+ /* Set the reserved slots in inuse list */
+ rsv_slots = info[j]->rsv->rsv_slots;
+ if (rsv_slots) {
+ for (i = 0; rsv_slots[i][0] != -1; i++) {
+ off = rsv_slots[i][0];
+ ln = rsv_slots[i][1];
+ set_bits(off, ln,
+ edma_cc[j]->edma_inuse);
+ }
+ }
+ }
+
+ sprintf(irq_name, "edma%d", j);
+ irq[j] = platform_get_irq_byname(pdev, irq_name);
+ edma_cc[j]->irq_res_start = irq[j];
+ status = request_irq(irq[j], dma_irq_handler, 0, "edma",
+ &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ irq[j], status);
+ goto fail;
+ }
+
+ sprintf(irq_name, "edma%d_err", j);
+ err_irq[j] = platform_get_irq_byname(pdev, irq_name);
+ edma_cc[j]->irq_res_end = err_irq[j];
+ status = request_irq(err_irq[j], dma_ccerr_handler, 0,
+ "edma_error", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ err_irq[j], status);
+ goto fail;
+ }
+
+ /* Everything lives on transfer controller 1 until otherwise
+ * specified. This way, long transfers on the low priority queue
+ * started by the codec engine will not cause audio defects.
+ */
+ for (i = 0; i < edma_cc[j]->num_channels; i++)
+ map_dmach_queue(j, i, EVENTQ_1);
+
+ queue_tc_mapping = info[j]->queue_tc_mapping;
+ queue_priority_mapping = info[j]->queue_priority_mapping;
+
+ /* Event queue to TC mapping */
+ for (i = 0; queue_tc_mapping[i][0] != -1; i++)
+ map_queue_tc(j, queue_tc_mapping[i][0],
+ queue_tc_mapping[i][1]);
+
+ /* Event queue priority mapping */
+ for (i = 0; queue_priority_mapping[i][0] != -1; i++)
+ assign_priority_to_queue(j,
+ queue_priority_mapping[i][0],
+ queue_priority_mapping[i][1]);
+
+ /* Map the channel to param entry if channel mapping logic
+ * exist
+ */
+ if (edma_read(j, EDMA_CCCFG) & CHMAP_EXIST)
+ map_dmach_param(j);
+
+ for (i = 0; i < info[j]->n_region; i++) {
+ edma_write_array2(j, EDMA_DRAE, i, 0, 0x0);
+ edma_write_array2(j, EDMA_DRAE, i, 1, 0x0);
+ edma_write_array(j, EDMA_QRAE, i, 0x0);
+ }
+ arch_num_cc++;
+ }
+
+ if (tc_errs_handled) {
+ status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0,
+ "edma_tc0", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d failed --> %d\n",
+ IRQ_TCERRINT0, status);
+ return status;
+ }
+ status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0,
+ "edma_tc1", &pdev->dev);
+ if (status < 0) {
+ dev_dbg(&pdev->dev, "request_irq %d --> %d\n",
+ IRQ_TCERRINT, status);
+ return status;
+ }
+ }
+
+ return 0;
+
+fail:
+ for (i = 0; i < EDMA_MAX_CC; i++) {
+ if (err_irq[i])
+ free_irq(err_irq[i], &pdev->dev);
+ if (irq[i])
+ free_irq(irq[i], &pdev->dev);
+ }
+fail1:
+ for (i = 0; i < EDMA_MAX_CC; i++) {
+ if (r[i])
+ release_mem_region(r[i]->start, len[i]);
+ if (edmacc_regs_base[i])
+ iounmap(edmacc_regs_base[i]);
+ kfree(edma_cc[i]);
+ }
+ return status;
+}
+
+
+static struct platform_driver edma_driver = {
+ .driver.name = "edma",
+};
+
+static int __init edma_init(void)
+{
+ return platform_driver_probe(&edma_driver, edma_probe);
+}
+arch_initcall(edma_init);
+
diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c b/arch/arm/mach-davinci/gpio-tnetv107x.c
new file mode 100644
index 00000000..3fa3e286
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio-tnetv107x.c
@@ -0,0 +1,205 @@
+/*
+ * Texas Instruments TNETV107X GPIO Controller
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/common.h>
+#include <mach/tnetv107x.h>
+
+struct tnetv107x_gpio_regs {
+ u32 idver;
+ u32 data_in[3];
+ u32 data_out[3];
+ u32 direction[3];
+ u32 enable[3];
+};
+
+#define gpio_reg_index(gpio) ((gpio) >> 5)
+#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f)
+
+#define gpio_reg_rmw(reg, mask, val) \
+ __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg))
+
+#define gpio_reg_set_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio))
+
+#define gpio_reg_clear_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0)
+
+#define gpio_reg_get_bit(reg, gpio) \
+ (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio))
+
+#define chip2controller(chip) \
+ container_of(chip, struct davinci_gpio_controller, chip)
+
+#define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32)
+
+static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS];
+
+static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_clear_bit(regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_dir_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(regs->data_out, gpio);
+
+ gpio_reg_clear_bit(regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ int ret;
+
+ ret = gpio_reg_get_bit(regs->data_in, gpio);
+
+ return ret ? 1 : 0;
+}
+
+static void tnetv107x_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(regs->data_out, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int __init tnetv107x_gpio_setup(void)
+{
+ int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct tnetv107x_gpio_regs *regs;
+ struct davinci_gpio_controller *ctlr;
+
+ if (soc_info->gpio_type != GPIO_TYPE_TNETV107X)
+ return 0;
+
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
+ pr_err("GPIO setup: how many GPIOs?\n");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(TNETV107X_N_GPIO < ngpio))
+ ngpio = TNETV107X_N_GPIO;
+
+ regs = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!regs))
+ return -EINVAL;
+
+ for (i = 0, base = 0; base < ngpio; i++, base += 32) {
+ ctlr = &chips[i];
+
+ ctlr->chip.label = "tnetv107x";
+ ctlr->chip.can_sleep = 0;
+ ctlr->chip.base = base;
+ ctlr->chip.ngpio = ngpio - base;
+ if (ctlr->chip.ngpio > 32)
+ ctlr->chip.ngpio = 32;
+
+ ctlr->chip.request = tnetv107x_gpio_request;
+ ctlr->chip.free = tnetv107x_gpio_free;
+ ctlr->chip.direction_input = tnetv107x_gpio_dir_in;
+ ctlr->chip.get = tnetv107x_gpio_get;
+ ctlr->chip.direction_output = tnetv107x_gpio_dir_out;
+ ctlr->chip.set = tnetv107x_gpio_set;
+
+ spin_lock_init(&ctlr->lock);
+
+ ctlr->regs = regs;
+ ctlr->set_data = &regs->data_out[i];
+ ctlr->clr_data = &regs->data_out[i];
+ ctlr->in_data = &regs->data_in[i];
+
+ gpiochip_add(&ctlr->chip);
+ }
+
+ soc_info->gpio_ctlrs = chips;
+ soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+ return 0;
+}
+pure_initcall(tnetv107x_gpio_setup);
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
new file mode 100644
index 00000000..cafbe13a
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio.c
@@ -0,0 +1,460 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006-2007 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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/errno.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/gpio.h>
+
+#include <asm/mach/irq.h>
+
+struct davinci_gpio_regs {
+ u32 dir;
+ u32 out_data;
+ u32 set_data;
+ u32 clr_data;
+ u32 in_data;
+ u32 set_rising;
+ u32 clr_rising;
+ u32 set_falling;
+ u32 clr_falling;
+ u32 intstat;
+};
+
+#define chip2controller(chip) \
+ container_of(chip, struct davinci_gpio_controller, chip)
+
+static struct davinci_gpio_controller chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
+static void __iomem *gpio_base;
+
+static struct davinci_gpio_regs __iomem __init *gpio2regs(unsigned gpio)
+{
+ void __iomem *ptr;
+
+ if (gpio < 32 * 1)
+ ptr = gpio_base + 0x10;
+ else if (gpio < 32 * 2)
+ ptr = gpio_base + 0x38;
+ else if (gpio < 32 * 3)
+ ptr = gpio_base + 0x60;
+ else if (gpio < 32 * 4)
+ ptr = gpio_base + 0x88;
+ else if (gpio < 32 * 5)
+ ptr = gpio_base + 0xb0;
+ else
+ ptr = NULL;
+ return ptr;
+}
+
+static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
+{
+ struct davinci_gpio_regs __iomem *g;
+
+ g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq);
+
+ return g;
+}
+
+static int __init davinci_gpio_irq_setup(void);
+
+/*--------------------------------------------------------------------------*/
+
+/* board setup code *MUST* setup pinmux and enable the GPIO clock. */
+static inline int __davinci_direction(struct gpio_chip *chip,
+ unsigned offset, bool out, int value)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+ unsigned long flags;
+ u32 temp;
+ u32 mask = 1 << offset;
+
+ spin_lock_irqsave(&d->lock, flags);
+ temp = __raw_readl(&g->dir);
+ if (out) {
+ temp &= ~mask;
+ __raw_writel(mask, value ? &g->set_data : &g->clr_data);
+ } else {
+ temp |= mask;
+ }
+ __raw_writel(temp, &g->dir);
+ spin_unlock_irqrestore(&d->lock, flags);
+
+ return 0;
+}
+
+static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
+{
+ return __davinci_direction(chip, offset, false, 0);
+}
+
+static int
+davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
+{
+ return __davinci_direction(chip, offset, true, value);
+}
+
+/*
+ * Read the pin's value (works even if it's set up as output);
+ * returns zero/nonzero.
+ *
+ * Note that changes are synched to the GPIO clock, so reading values back
+ * right after you've set them may give old values.
+ */
+static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+
+ return (1 << offset) & __raw_readl(&g->in_data);
+}
+
+/*
+ * Assuming the pin is muxed as a gpio output, set its output value.
+ */
+static void
+davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+ struct davinci_gpio_regs __iomem *g = d->regs;
+
+ __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
+}
+
+static int __init davinci_gpio_setup(void)
+{
+ int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_gpio_regs *regs;
+
+ if (soc_info->gpio_type != GPIO_TYPE_DAVINCI)
+ return 0;
+
+ /*
+ * The gpio banks conceptually expose a segmented bitmap,
+ * and "ngpio" is one more than the largest zero-based
+ * bit index that's valid.
+ */
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
+ pr_err("GPIO setup: how many GPIOs?\n");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(DAVINCI_N_GPIO < ngpio))
+ ngpio = DAVINCI_N_GPIO;
+
+ gpio_base = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!gpio_base))
+ return -ENOMEM;
+
+ for (i = 0, base = 0; base < ngpio; i++, base += 32) {
+ chips[i].chip.label = "DaVinci";
+
+ chips[i].chip.direction_input = davinci_direction_in;
+ chips[i].chip.get = davinci_gpio_get;
+ chips[i].chip.direction_output = davinci_direction_out;
+ chips[i].chip.set = davinci_gpio_set;
+
+ chips[i].chip.base = base;
+ chips[i].chip.ngpio = ngpio - base;
+ if (chips[i].chip.ngpio > 32)
+ chips[i].chip.ngpio = 32;
+
+ spin_lock_init(&chips[i].lock);
+
+ regs = gpio2regs(base);
+ chips[i].regs = regs;
+ chips[i].set_data = &regs->set_data;
+ chips[i].clr_data = &regs->clr_data;
+ chips[i].in_data = &regs->in_data;
+
+ gpiochip_add(&chips[i].chip);
+ }
+
+ soc_info->gpio_ctlrs = chips;
+ soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+
+ davinci_gpio_irq_setup();
+ return 0;
+}
+pure_initcall(davinci_gpio_setup);
+
+/*--------------------------------------------------------------------------*/
+/*
+ * We expect irqs will normally be set up as input pins, but they can also be
+ * used as output pins ... which is convenient for testing.
+ *
+ * NOTE: The first few GPIOs also have direct INTC hookups in addition
+ * to their GPIOBNK0 irq, with a bit less overhead.
+ *
+ * All those INTC hookups (direct, plus several IRQ banks) can also
+ * serve as EDMA event triggers.
+ */
+
+static void gpio_irq_disable(struct irq_data *d)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ __raw_writel(mask, &g->clr_falling);
+ __raw_writel(mask, &g->clr_rising);
+}
+
+static void gpio_irq_enable(struct irq_data *d)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+ unsigned status = irqd_get_trigger_type(d);
+
+ status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+ if (!status)
+ status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+ if (status & IRQ_TYPE_EDGE_FALLING)
+ __raw_writel(mask, &g->set_falling);
+ if (status & IRQ_TYPE_EDGE_RISING)
+ __raw_writel(mask, &g->set_rising);
+}
+
+static int gpio_irq_type(struct irq_data *d, unsigned trigger)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct irq_chip gpio_irqchip = {
+ .name = "GPIO",
+ .irq_enable = gpio_irq_enable,
+ .irq_disable = gpio_irq_disable,
+ .irq_set_type = gpio_irq_type,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static void
+gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+ struct davinci_gpio_regs __iomem *g;
+ u32 mask = 0xffff;
+ struct davinci_gpio_controller *d;
+
+ d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc);
+ g = (struct davinci_gpio_regs __iomem *)d->regs;
+
+ /* we only care about one bank */
+ if (irq & 1)
+ mask <<= 16;
+
+ /* temporarily mask (level sensitive) parent IRQ */
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ while (1) {
+ u32 status;
+ int n;
+ int res;
+
+ /* ack any irqs */
+ status = __raw_readl(&g->intstat) & mask;
+ if (!status)
+ break;
+ __raw_writel(status, &g->intstat);
+
+ /* now demux them to the right lowlevel handler */
+ n = d->irq_base;
+ if (irq & 1) {
+ n += 16;
+ status >>= 16;
+ }
+
+ while (status) {
+ res = ffs(status);
+ n += res;
+ generic_handle_irq(n - 1);
+ status >>= res;
+ }
+ }
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ /* now it may re-trigger */
+}
+
+static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *d = chip2controller(chip);
+
+ if (d->irq_base >= 0)
+ return d->irq_base + offset;
+ else
+ return -ENODEV;
+}
+
+static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ /* NOTE: we assume for now that only irqs in the first gpio_chip
+ * can provide direct-mapped IRQs to AINTC (up to 32 GPIOs).
+ */
+ if (offset < soc_info->gpio_unbanked)
+ return soc_info->gpio_irq + offset;
+ else
+ return -ENODEV;
+}
+
+static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
+{
+ struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+
+ if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ return -EINVAL;
+
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+ ? &g->set_falling : &g->clr_falling);
+ __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+ ? &g->set_rising : &g->clr_rising);
+
+ return 0;
+}
+
+/*
+ * NOTE: for suspend/resume, probably best to make a platform_device with
+ * suspend_late/resume_resume calls hooking into results of the set_wake()
+ * calls ... so if no gpios are wakeup events the clock can be disabled,
+ * with outputs left at previously set levels, and so that VDD3P3V.IOPWDN0
+ * (dm6446) can be set appropriately for GPIOV33 pins.
+ */
+
+static int __init davinci_gpio_irq_setup(void)
+{
+ unsigned gpio, irq, bank;
+ struct clk *clk;
+ u32 binten = 0;
+ unsigned ngpio, bank_irq;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_gpio_regs __iomem *g;
+
+ ngpio = soc_info->gpio_num;
+
+ bank_irq = soc_info->gpio_irq;
+ if (bank_irq == 0) {
+ printk(KERN_ERR "Don't know first GPIO bank IRQ.\n");
+ return -EINVAL;
+ }
+
+ clk = clk_get(NULL, "gpio");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "Error %ld getting gpio clock?\n",
+ PTR_ERR(clk));
+ return PTR_ERR(clk);
+ }
+ clk_enable(clk);
+
+ /* Arrange gpio_to_irq() support, handling either direct IRQs or
+ * banked IRQs. Having GPIOs in the first GPIO bank use direct
+ * IRQs, while the others use banked IRQs, would need some setup
+ * tweaks to recognize hardware which can do that.
+ */
+ for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
+ chips[bank].chip.to_irq = gpio_to_irq_banked;
+ chips[bank].irq_base = soc_info->gpio_unbanked
+ ? -EINVAL
+ : (soc_info->intc_irq_num + gpio);
+ }
+
+ /*
+ * AINTC can handle direct/unbanked IRQs for GPIOs, with the GPIO
+ * controller only handling trigger modes. We currently assume no
+ * IRQ mux conflicts; gpio_irq_type_unbanked() is only for GPIOs.
+ */
+ if (soc_info->gpio_unbanked) {
+ static struct irq_chip gpio_irqchip_unbanked;
+
+ /* pass "bank 0" GPIO IRQs to AINTC */
+ chips[0].chip.to_irq = gpio_to_irq_unbanked;
+ binten = BIT(0);
+
+ /* AINTC handles mask/unmask; GPIO handles triggering */
+ irq = bank_irq;
+ gpio_irqchip_unbanked = *irq_get_chip(irq);
+ gpio_irqchip_unbanked.name = "GPIO-AINTC";
+ gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
+
+ /* default trigger: both edges */
+ g = gpio2regs(0);
+ __raw_writel(~0, &g->set_falling);
+ __raw_writel(~0, &g->set_rising);
+
+ /* set the direct IRQs up to use that irqchip */
+ for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
+ irq_set_chip(irq, &gpio_irqchip_unbanked);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
+ }
+
+ goto done;
+ }
+
+ /*
+ * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
+ * then chain through our own handler.
+ */
+ for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
+ gpio < ngpio;
+ bank++, bank_irq++) {
+ unsigned i;
+
+ /* disabled by default, enabled only as needed */
+ g = gpio2regs(gpio);
+ __raw_writel(~0, &g->clr_falling);
+ __raw_writel(~0, &g->clr_rising);
+
+ /* set up all irqs in this bank */
+ irq_set_chained_handler(bank_irq, gpio_irq_handler);
+
+ /*
+ * Each chip handles 32 gpios, and each irq bank consists of 16
+ * gpio irqs. Pass the irq bank's corresponding controller to
+ * the chained irq handler.
+ */
+ irq_set_handler_data(bank_irq, &chips[gpio / 32]);
+
+ for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
+ irq_set_chip(irq, &gpio_irqchip);
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_handler(irq, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ binten |= BIT(bank);
+ }
+
+done:
+ /* BINTEN -- per-bank interrupt enable. genirq would also let these
+ * bits be set/cleared dynamically.
+ */
+ __raw_writel(binten, gpio_base + 0x08);
+
+ printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
+
+ return 0;
+}
diff --git a/arch/arm/mach-davinci/include/mach/aemif.h b/arch/arm/mach-davinci/include/mach/aemif.h
new file mode 100644
index 00000000..05b29344
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/aemif.h
@@ -0,0 +1,36 @@
+/*
+ * TI DaVinci AEMIF support
+ *
+ * Copyright 2010 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_AEMIF_H
+#define _MACH_DAVINCI_AEMIF_H
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+
+#define ACR_ASIZE_MASK 0x3
+#define ACR_EW_MASK BIT(30)
+#define ACR_SS_MASK BIT(31)
+
+/* All timings in nanoseconds */
+struct davinci_aemif_timing {
+ u8 wsetup;
+ u8 wstrobe;
+ u8 whold;
+
+ u8 rsetup;
+ u8 rstrobe;
+ u8 rhold;
+
+ u8 ta;
+};
+
+int davinci_aemif_setup_timing(struct davinci_aemif_timing *t,
+ void __iomem *base, unsigned cs);
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
new file mode 100644
index 00000000..9aa24090
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/asp.h
@@ -0,0 +1,137 @@
+/*
+ * <mach/asp.h> - DaVinci Audio Serial Port support
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_H
+
+#include <mach/irqs.h>
+#include <mach/edma.h>
+
+/* Bases of dm644x and dm355 register banks */
+#define DAVINCI_ASP0_BASE 0x01E02000
+#define DAVINCI_ASP1_BASE 0x01E04000
+
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE 0x01D02000
+
+/* Bases of dm646x register banks */
+#define DAVINCI_DM646X_MCASP0_REG_BASE 0x01D01000
+#define DAVINCI_DM646X_MCASP1_REG_BASE 0x01D01800
+
+/* Bases of da850/da830 McASP0 register banks */
+#define DAVINCI_DA8XX_MCASP0_REG_BASE 0x01D00000
+
+/* Bases of da830 McASP1 register banks */
+#define DAVINCI_DA830_MCASP1_REG_BASE 0x01D04000
+
+/* EDMA channels of dm644x and dm355 */
+#define DAVINCI_DMA_ASP0_TX 2
+#define DAVINCI_DMA_ASP0_RX 3
+#define DAVINCI_DMA_ASP1_TX 8
+#define DAVINCI_DMA_ASP1_RX 9
+
+/* EDMA channels of dm646x */
+#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0 6
+#define DAVINCI_DM646X_DMA_MCASP0_AREVT0 9
+#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1 12
+
+/* EDMA channels of da850/da830 McASP0 */
+#define DAVINCI_DA8XX_DMA_MCASP0_AREVT 0
+#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT 1
+
+/* EDMA channels of da830 McASP1 */
+#define DAVINCI_DA830_DMA_MCASP1_AREVT 2
+#define DAVINCI_DA830_DMA_MCASP1_AXEVT 3
+
+/* Interrupts */
+#define DAVINCI_ASP0_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP0_TX_INT IRQ_MBXINT
+#define DAVINCI_ASP1_RX_INT IRQ_MBRINT
+#define DAVINCI_ASP1_TX_INT IRQ_MBXINT
+
+struct snd_platform_data {
+ u32 tx_dma_offset;
+ u32 rx_dma_offset;
+ enum dma_event_q asp_chan_q; /* event queue number for ASP channel */
+ enum dma_event_q ram_chan_q; /* event queue number for RAM channel */
+ unsigned int codec_fmt;
+ /*
+ * Allowing this is more efficient and eliminates left and right swaps
+ * caused by underruns, but will swap the left and right channels
+ * when compared to previous behavior.
+ */
+ unsigned enable_channel_combine:1;
+ unsigned sram_size_playback;
+ unsigned sram_size_capture;
+
+ /*
+ * If McBSP peripheral gets the clock from an external pin,
+ * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR
+ * and MCBSP_CLKS.
+ * Depending on different hardware connections it is possible
+ * to use this setting to change the behaviour of McBSP
+ * driver. The dm365_clk_input_pin enum is available for dm365
+ */
+ int clk_input_pin;
+
+ /*
+ * This flag works when both clock and FS are outputs for the cpu
+ * and makes clock more accurate (FS is not symmetrical and the
+ * clock is very fast.
+ * The clock becoming faster is named
+ * i2s continuous serial clock (I2S_SCK) and it is an externally
+ * visible bit clock.
+ *
+ * first line : WordSelect
+ * second line : ContinuousSerialClock
+ * third line: SerialData
+ *
+ * SYMMETRICAL APPROACH:
+ * _______________________ LEFT
+ * _| RIGHT |______________________|
+ * _ _ _ _ _ _ _ _
+ * _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_
+ * _ _ _ _ _ _ _ _
+ * _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_
+ * \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
+ *
+ * ACCURATE CLOCK APPROACH:
+ * ______________ LEFT
+ * _| RIGHT |_______________________________|
+ * _ _ _ _ _ _ _ _ _
+ * _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| |
+ * _ _ _ _ dummy cycles
+ * _/ \_ ... _/ \_/ \_ ... _/ \__________________
+ * \_/ \_/ \_/ \_/
+ *
+ */
+ bool i2s_accurate_sck;
+
+ /* McASP specific fields */
+ int tdm_slots;
+ u8 op_mode;
+ u8 num_serializer;
+ u8 *serial_dir;
+ u8 version;
+ u8 txnumevt;
+ u8 rxnumevt;
+};
+
+enum {
+ MCASP_VERSION_1 = 0, /* DM646x */
+ MCASP_VERSION_2, /* DA8xx/OMAPL1x */
+};
+
+enum dm365_clk_input_pin {
+ MCBSP_CLKR = 0, /* DM365 */
+ MCBSP_CLKS,
+};
+
+#define INACTIVE_MODE 0
+#define TX_MODE 1
+#define RX_MODE 2
+
+#define DAVINCI_MCASP_IIS_MODE 0
+#define DAVINCI_MCASP_DIT_MODE 1
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/include/mach/cdce949.h b/arch/arm/mach-davinci/include/mach/cdce949.h
new file mode 100644
index 00000000..c73331fa
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cdce949.h
@@ -0,0 +1,19 @@
+/*
+ * TI CDCE949 off-chip clock synthesizer support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CDCE949_H
+#define _MACH_DAVINCI_CDCE949_H
+
+#include <linux/clk.h>
+
+#include <mach/clock.h>
+
+int cdce_set_rate(struct clk *clk, unsigned long rate);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/clkdev.h b/arch/arm/mach-davinci/include/mach/clkdev.h
new file mode 100644
index 00000000..14a50488
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/clkdev.h
@@ -0,0 +1,15 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h
new file mode 100644
index 00000000..a3b04021
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/clock.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-davinci/include/mach/clock.h
+ *
+ * Clock control driver for DaVinci - header file
+ *
+ * Authors: Vladimir Barinov <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DAVINCI_CLOCK_H
+#define __ASM_ARCH_DAVINCI_CLOCK_H
+
+struct clk;
+
+extern int clk_register(struct clk *clk);
+extern void clk_unregister(struct clk *clk);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h
new file mode 100644
index 00000000..a57cba21
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/common.h
@@ -0,0 +1,93 @@
+/*
+ * Header for code common to all DaVinci machines.
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ARCH_ARM_MACH_DAVINCI_COMMON_H
+#define __ARCH_ARM_MACH_DAVINCI_COMMON_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct sys_timer;
+
+extern struct sys_timer davinci_timer;
+
+extern void davinci_irq_init(void);
+extern void __iomem *davinci_intc_base;
+extern int davinci_intc_type;
+
+struct davinci_timer_instance {
+ u32 base;
+ u32 bottom_irq;
+ u32 top_irq;
+ unsigned long cmp_off;
+ unsigned int cmp_irq;
+};
+
+struct davinci_timer_info {
+ struct davinci_timer_instance *timers;
+ unsigned int clockevent_id;
+ unsigned int clocksource_id;
+};
+
+struct davinci_gpio_controller;
+
+/*
+ * SoC info passed into common davinci modules.
+ *
+ * Base addresses in this structure should be physical and not virtual.
+ * Modules that take such base addresses, should internally ioremap() them to
+ * use.
+ */
+struct davinci_soc_info {
+ struct map_desc *io_desc;
+ unsigned long io_desc_num;
+ u32 cpu_id;
+ u32 jtag_id;
+ u32 jtag_id_reg;
+ struct davinci_id *ids;
+ unsigned long ids_num;
+ struct clk_lookup *cpu_clks;
+ u32 *psc_bases;
+ unsigned long psc_bases_num;
+ u32 pinmux_base;
+ const struct mux_config *pinmux_pins;
+ unsigned long pinmux_pins_num;
+ u32 intc_base;
+ int intc_type;
+ u8 *intc_irq_prios;
+ unsigned long intc_irq_num;
+ u32 *intc_host_map;
+ struct davinci_timer_info *timer_info;
+ int gpio_type;
+ u32 gpio_base;
+ unsigned gpio_num;
+ unsigned gpio_irq;
+ unsigned gpio_unbanked;
+ struct davinci_gpio_controller *gpio_ctlrs;
+ int gpio_ctlrs_num;
+ struct platform_device *serial_dev;
+ struct emac_platform_data *emac_pdata;
+ dma_addr_t sram_dma;
+ unsigned sram_len;
+ struct platform_device *reset_device;
+ void (*reset)(struct platform_device *);
+};
+
+extern struct davinci_soc_info davinci_soc_info;
+
+extern void davinci_common_init(struct davinci_soc_info *soc_info);
+extern void davinci_init_ide(void);
+
+/* standard place to map on-chip SRAMs; they *may* support DMA */
+#define SRAM_VIRT 0xfffe0000
+#define SRAM_SIZE SZ_128K
+
+#endif /* __ARCH_ARM_MACH_DAVINCI_COMMON_H */
diff --git a/arch/arm/mach-davinci/include/mach/cp_intc.h b/arch/arm/mach-davinci/include/mach/cp_intc.h
new file mode 100644
index 00000000..4e8190ee
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cp_intc.h
@@ -0,0 +1,56 @@
+/*
+ * TI Common Platform Interrupt Controller (cp_intc) definitions
+ *
+ * Author: Steve Chen <schen@mvista.com>
+ * Copyright (C) 2008-2009, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef __ASM_HARDWARE_CP_INTC_H
+#define __ASM_HARDWARE_CP_INTC_H
+
+#define CP_INTC_REV 0x00
+#define CP_INTC_CTRL 0x04
+#define CP_INTC_HOST_CTRL 0x0C
+#define CP_INTC_GLOBAL_ENABLE 0x10
+#define CP_INTC_GLOBAL_NESTING_LEVEL 0x1C
+#define CP_INTC_SYS_STAT_IDX_SET 0x20
+#define CP_INTC_SYS_STAT_IDX_CLR 0x24
+#define CP_INTC_SYS_ENABLE_IDX_SET 0x28
+#define CP_INTC_SYS_ENABLE_IDX_CLR 0x2C
+#define CP_INTC_GLOBAL_WAKEUP_ENABLE 0x30
+#define CP_INTC_HOST_ENABLE_IDX_SET 0x34
+#define CP_INTC_HOST_ENABLE_IDX_CLR 0x38
+#define CP_INTC_PACING_PRESCALE 0x40
+#define CP_INTC_VECTOR_BASE 0x50
+#define CP_INTC_VECTOR_SIZE 0x54
+#define CP_INTC_VECTOR_NULL 0x58
+#define CP_INTC_PRIO_IDX 0x80
+#define CP_INTC_PRIO_VECTOR 0x84
+#define CP_INTC_SECURE_ENABLE 0x90
+#define CP_INTC_SECURE_PRIO_IDX 0x94
+#define CP_INTC_PACING_PARAM(n) (0x0100 + (n << 4))
+#define CP_INTC_PACING_DEC(n) (0x0104 + (n << 4))
+#define CP_INTC_PACING_MAP(n) (0x0108 + (n << 4))
+#define CP_INTC_SYS_RAW_STAT(n) (0x0200 + (n << 2))
+#define CP_INTC_SYS_STAT_CLR(n) (0x0280 + (n << 2))
+#define CP_INTC_SYS_ENABLE_SET(n) (0x0300 + (n << 2))
+#define CP_INTC_SYS_ENABLE_CLR(n) (0x0380 + (n << 2))
+#define CP_INTC_CHAN_MAP(n) (0x0400 + (n << 2))
+#define CP_INTC_HOST_MAP(n) (0x0800 + (n << 2))
+#define CP_INTC_HOST_PRIO_IDX(n) (0x0900 + (n << 2))
+#define CP_INTC_SYS_POLARITY(n) (0x0D00 + (n << 2))
+#define CP_INTC_SYS_TYPE(n) (0x0D80 + (n << 2))
+#define CP_INTC_WAKEUP_ENABLE(n) (0x0E00 + (n << 2))
+#define CP_INTC_DEBUG_SELECT(n) (0x0F00 + (n << 2))
+#define CP_INTC_SYS_SECURE_ENABLE(n) (0x1000 + (n << 2))
+#define CP_INTC_HOST_NESTING_LEVEL(n) (0x1100 + (n << 2))
+#define CP_INTC_HOST_ENABLE(n) (0x1500 + (n << 2))
+#define CP_INTC_HOST_PRIO_VECTOR(n) (0x1600 + (n << 2))
+#define CP_INTC_VECTOR_ADDR(n) (0x2000 + (n << 2))
+
+void __init cp_intc_init(void);
+
+#endif /* __ASM_HARDWARE_CP_INTC_H */
diff --git a/arch/arm/mach-davinci/include/mach/cpufreq.h b/arch/arm/mach-davinci/include/mach/cpufreq.h
new file mode 100644
index 00000000..3c089cfb
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpufreq.h
@@ -0,0 +1,26 @@
+/*
+ * TI DaVinci CPUFreq platform support.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 _MACH_DAVINCI_CPUFREQ_H
+#define _MACH_DAVINCI_CPUFREQ_H
+
+#include <linux/cpufreq.h>
+
+struct davinci_cpufreq_config {
+ struct cpufreq_frequency_table *freq_table;
+ int (*set_voltage) (unsigned int index);
+ int (*init) (void);
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/cpuidle.h b/arch/arm/mach-davinci/include/mach/cpuidle.h
new file mode 100644
index 00000000..74f088b0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cpuidle.h
@@ -0,0 +1,18 @@
+/*
+ * TI DaVinci cpuidle platform support
+ *
+ * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+#ifndef _MACH_DAVINCI_CPUIDLE_H
+#define _MACH_DAVINCI_CPUIDLE_H
+
+struct davinci_cpuidle_config {
+ u32 ddr2_pdown;
+ void __iomem *ddr2_ctlr_base;
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/cputype.h b/arch/arm/mach-davinci/include/mach/cputype.h
new file mode 100644
index 00000000..957fb87e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/cputype.h
@@ -0,0 +1,94 @@
+/*
+ * DaVinci CPU type detection
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Defines the cpu_is_*() macros for runtime detection of DaVinci
+ * device type. In addition, if support for a given device is not
+ * compiled in to the kernel, the macros return 0 so that
+ * resulting code can be optimized out.
+ *
+ * 2009 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef _ASM_ARCH_CPU_H
+#define _ASM_ARCH_CPU_H
+
+#include <mach/common.h>
+
+struct davinci_id {
+ u8 variant; /* JTAG ID bits 31:28 */
+ u16 part_no; /* JTAG ID bits 27:12 */
+ u16 manufacturer; /* JTAG ID bits 11:1 */
+ u32 cpu_id;
+ char *name;
+};
+
+/* Can use lower 16 bits of cpu id for a variant when required */
+#define DAVINCI_CPU_ID_DM6446 0x64460000
+#define DAVINCI_CPU_ID_DM6467 0x64670000
+#define DAVINCI_CPU_ID_DM355 0x03550000
+#define DAVINCI_CPU_ID_DM365 0x03650000
+#define DAVINCI_CPU_ID_DA830 0x08300000
+#define DAVINCI_CPU_ID_DA850 0x08500000
+#define DAVINCI_CPU_ID_TNETV107X 0x0b8a0000
+
+#define IS_DAVINCI_CPU(type, id) \
+static inline int is_davinci_ ##type(void) \
+{ \
+ return (davinci_soc_info.cpu_id == (id)); \
+}
+
+IS_DAVINCI_CPU(dm644x, DAVINCI_CPU_ID_DM6446)
+IS_DAVINCI_CPU(dm646x, DAVINCI_CPU_ID_DM6467)
+IS_DAVINCI_CPU(dm355, DAVINCI_CPU_ID_DM355)
+IS_DAVINCI_CPU(dm365, DAVINCI_CPU_ID_DM365)
+IS_DAVINCI_CPU(da830, DAVINCI_CPU_ID_DA830)
+IS_DAVINCI_CPU(da850, DAVINCI_CPU_ID_DA850)
+IS_DAVINCI_CPU(tnetv107x, DAVINCI_CPU_ID_TNETV107X)
+
+#ifdef CONFIG_ARCH_DAVINCI_DM644x
+#define cpu_is_davinci_dm644x() is_davinci_dm644x()
+#else
+#define cpu_is_davinci_dm644x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM646x
+#define cpu_is_davinci_dm646x() is_davinci_dm646x()
+#else
+#define cpu_is_davinci_dm646x() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM355
+#define cpu_is_davinci_dm355() is_davinci_dm355()
+#else
+#define cpu_is_davinci_dm355() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DM365
+#define cpu_is_davinci_dm365() is_davinci_dm365()
+#else
+#define cpu_is_davinci_dm365() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA830
+#define cpu_is_davinci_da830() is_davinci_da830()
+#else
+#define cpu_is_davinci_da830() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_DA850
+#define cpu_is_davinci_da850() is_davinci_da850()
+#else
+#define cpu_is_davinci_da850() 0
+#endif
+
+#ifdef CONFIG_ARCH_DAVINCI_TNETV107X
+#define cpu_is_davinci_tnetv107x() is_davinci_tnetv107x()
+#else
+#define cpu_is_davinci_tnetv107x() 0
+#endif
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
new file mode 100644
index 00000000..ad64da71
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -0,0 +1,130 @@
+/*
+ * Chip specific defines for DA8XX/OMAP L1XX SoC
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DAVINCI_DA8XX_H
+#define __ASM_ARCH_DAVINCI_DA8XX_H
+
+#include <video/da8xx-fb.h>
+
+#include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
+#include <linux/spi/spi.h>
+
+#include <mach/serial.h>
+#include <mach/edma.h>
+#include <mach/i2c.h>
+#include <mach/asp.h>
+#include <mach/mmc.h>
+#include <mach/usb.h>
+#include <mach/pm.h>
+#include <mach/spi.h>
+
+extern void __iomem *da8xx_syscfg0_base;
+extern void __iomem *da8xx_syscfg1_base;
+
+/*
+ * If the DA850/OMAP-L138/AM18x SoC on board is of a higher speed grade
+ * (than the regular 300Mhz variant), the board code should set this up
+ * with the supported speed before calling da850_register_cpufreq().
+ */
+extern unsigned int da850_max_speed;
+
+/*
+ * The cp_intc interrupt controller for the da8xx isn't in the same
+ * chunk of physical memory space as the other registers (like it is
+ * on the davincis) so it needs to be mapped separately. It will be
+ * mapped early on when the I/O space is mapped and we'll put it just
+ * before the I/O space in the processor's virtual memory space.
+ */
+#define DA8XX_CP_INTC_BASE 0xfffee000
+#define DA8XX_CP_INTC_SIZE SZ_8K
+#define DA8XX_CP_INTC_VIRT (IO_VIRT - DA8XX_CP_INTC_SIZE - SZ_4K)
+
+#define DA8XX_SYSCFG0_BASE (IO_PHYS + 0x14000)
+#define DA8XX_SYSCFG0_VIRT(x) (da8xx_syscfg0_base + (x))
+#define DA8XX_JTAG_ID_REG 0x18
+#define DA8XX_CFGCHIP0_REG 0x17c
+#define DA8XX_CFGCHIP2_REG 0x184
+#define DA8XX_CFGCHIP3_REG 0x188
+
+#define DA8XX_SYSCFG1_BASE (IO_PHYS + 0x22C000)
+#define DA8XX_SYSCFG1_VIRT(x) (da8xx_syscfg1_base + (x))
+#define DA8XX_DEEPSLEEP_REG 0x8
+
+#define DA8XX_PSC0_BASE 0x01c10000
+#define DA8XX_PLL0_BASE 0x01c11000
+#define DA8XX_TIMER64P0_BASE 0x01c20000
+#define DA8XX_TIMER64P1_BASE 0x01c21000
+#define DA8XX_GPIO_BASE 0x01e26000
+#define DA8XX_PSC1_BASE 0x01e27000
+#define DA8XX_AEMIF_CS2_BASE 0x60000000
+#define DA8XX_AEMIF_CS3_BASE 0x62000000
+#define DA8XX_AEMIF_CTL_BASE 0x68000000
+#define DA8XX_ARM_RAM_BASE 0xffff0000
+
+void __init da830_init(void);
+void __init da850_init(void);
+
+int da830_register_edma(struct edma_rsv_info *rsv);
+int da850_register_edma(struct edma_rsv_info *rsv[2]);
+int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata);
+int da8xx_register_spi(int instance, struct spi_board_info *info, unsigned len);
+int da8xx_register_watchdog(void);
+int da8xx_register_usb20(unsigned mA, unsigned potpgt);
+int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata);
+int da8xx_register_emac(void);
+int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata);
+int da8xx_register_mmcsd0(struct davinci_mmc_config *config);
+int da850_register_mmcsd1(struct davinci_mmc_config *config);
+void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata);
+int da8xx_register_rtc(void);
+int da850_register_cpufreq(char *async_clk);
+int da8xx_register_cpuidle(void);
+void __iomem * __init da8xx_get_mem_ctlr(void);
+int da850_register_pm(struct platform_device *pdev);
+
+extern struct platform_device da8xx_serial_device;
+extern struct emac_platform_data da8xx_emac_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata;
+extern struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata;
+extern struct davinci_spi_platform_data da8xx_spi_pdata[];
+
+extern struct platform_device da8xx_wdt_device;
+
+extern const short da830_emif25_pins[];
+extern const short da830_spi0_pins[];
+extern const short da830_spi1_pins[];
+extern const short da830_mmc_sd_pins[];
+extern const short da830_uart0_pins[];
+extern const short da830_uart1_pins[];
+extern const short da830_uart2_pins[];
+extern const short da830_usb20_pins[];
+extern const short da830_usb11_pins[];
+extern const short da830_uhpi_pins[];
+extern const short da830_cpgmac_pins[];
+extern const short da830_emif3c_pins[];
+extern const short da830_mcasp0_pins[];
+extern const short da830_mcasp1_pins[];
+extern const short da830_mcasp2_pins[];
+extern const short da830_i2c0_pins[];
+extern const short da830_i2c1_pins[];
+extern const short da830_lcdcntl_pins[];
+extern const short da830_pwm_pins[];
+extern const short da830_ecap0_pins[];
+extern const short da830_ecap1_pins[];
+extern const short da830_ecap2_pins[];
+extern const short da830_eqep0_pins[];
+extern const short da830_eqep1_pins[];
+
+extern const short da850_i2c0_pins[];
+extern const short da850_i2c1_pins[];
+extern const short da850_lcdcntl_pins[];
+
+#endif /* __ASM_ARCH_DAVINCI_DA8XX_H */
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
new file mode 100644
index 00000000..f8b7ea4f
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -0,0 +1,91 @@
+/*
+ * Debugging macro for DaVinci
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+/* Modifications
+ * Jan 2009 Chaithrika U S Added senduart, busyuart, waituart
+ * macros, based on debug-8250.S file
+ * but using 32-bit accesses required for
+ * some davinci devices.
+ */
+
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+
+#include <mach/serial.h>
+
+#define UART_SHIFT 2
+
+#define davinci_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define davinci_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
+ .pushsection .data
+davinci_uart_phys: .word 0
+davinci_uart_virt: .word 0
+ .popsection
+
+ .macro addruart, rp, rv
+
+ /* Use davinci_uart_phys/virt if already configured */
+10: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =davinci_uart_v2p(davinci_uart_phys)
+ ldrne \rp, =davinci_uart_phys
+ add \rv, \rp, #4 @ davinci_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
+ bne 99f @ already configured
+
+ /* Check the debug UART address set in uncompress.h */
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+
+ /* Copy uart phys address from decompressor uart info */
+ ldreq \rv, =davinci_uart_v2p(davinci_uart_phys)
+ ldrne \rv, =davinci_uart_phys
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #0]
+ str \rp, [\rv]
+
+ /* Copy uart virt address from decompressor uart info */
+ ldreq \rv, =davinci_uart_v2p(davinci_uart_virt)
+ ldrne \rv, =davinci_uart_virt
+ ldreq \rp, =DAVINCI_UART_INFO
+ ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO)
+ ldr \rp, [\rp, #4]
+ str \rp, [\rv]
+
+ b 10b
+99:
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UART_TX << UART_SHIFT]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+#ifdef FLOW_CONTROL
+1001: ldr \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+#endif
+ .endm
+
diff --git a/arch/arm/mach-davinci/include/mach/dm355.h b/arch/arm/mach-davinci/include/mach/dm355.h
new file mode 100644
index 00000000..36dff4a0
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm355.h
@@ -0,0 +1,32 @@
+/*
+ * Chip specific defines for DM355 SoC
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DM355_H
+#define __ASM_ARCH_DM355_H
+
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM355_ASYNC_EMIF_CONTROL_BASE 0x01E10000
+#define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+
+#define ASP1_TX_EVT_EN 1
+#define ASP1_RX_EVT_EN 2
+
+struct spi_board_info;
+
+void __init dm355_init(void);
+void dm355_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len);
+void __init dm355_init_asp1(u32 evt_enable, struct snd_platform_data *pdata);
+void dm355_set_vpfe_config(struct vpfe_config *cfg);
+
+#endif /* __ASM_ARCH_DM355_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h
new file mode 100644
index 00000000..2563bf4e
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm365.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ *
+ * 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 __ASM_ARCH_DM365_H
+#define __ASM_ARCH_DM665_H
+
+#include <linux/platform_device.h>
+#include <linux/davinci_emac.h>
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <mach/keyscan.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM365_EMAC_BASE (0x01D07000)
+#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000)
+#define DM365_EMAC_CNTRL_OFFSET (0x0000)
+#define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000)
+#define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000)
+#define DM365_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+/* Base of key scan register bank */
+#define DM365_KEYSCAN_BASE (0x01C69400)
+
+#define DM365_RTC_BASE (0x01C69000)
+
+#define DAVINCI_DM365_VC_BASE (0x01D0C000)
+#define DAVINCI_DMA_VC_TX 2
+#define DAVINCI_DMA_VC_RX 3
+
+#define DM365_ASYNC_EMIF_CONTROL_BASE 0x01D10000
+#define DM365_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM365_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+
+void __init dm365_init(void);
+void __init dm365_init_asp(struct snd_platform_data *pdata);
+void __init dm365_init_vc(struct snd_platform_data *pdata);
+void __init dm365_init_ks(struct davinci_ks_platform_data *pdata);
+void __init dm365_init_rtc(void);
+void dm365_init_spi0(unsigned chipselect_mask,
+ struct spi_board_info *info, unsigned len);
+
+void dm365_set_vpfe_config(struct vpfe_config *cfg);
+#endif /* __ASM_ARCH_DM365_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h
new file mode 100644
index 00000000..5a1b26d4
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm644x.h
@@ -0,0 +1,47 @@
+/*
+ * This file contains the processor specific definitions
+ * of the TI DM644x.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ *
+ * 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 __ASM_ARCH_DM644X_H
+#define __ASM_ARCH_DM644X_H
+
+#include <linux/davinci_emac.h>
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <media/davinci/vpfe_capture.h>
+
+#define DM644X_EMAC_BASE (0x01C80000)
+#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000)
+#define DM644X_EMAC_CNTRL_OFFSET (0x0000)
+#define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000)
+#define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000)
+#define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+#define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000
+#define DM644X_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
+#define DM644X_ASYNC_EMIF_DATA_CE1_BASE 0x04000000
+#define DM644X_ASYNC_EMIF_DATA_CE2_BASE 0x06000000
+#define DM644X_ASYNC_EMIF_DATA_CE3_BASE 0x08000000
+
+void __init dm644x_init(void);
+void __init dm644x_init_asp(struct snd_platform_data *pdata);
+void dm644x_set_vpfe_config(struct vpfe_config *cfg);
+
+#endif /* __ASM_ARCH_DM644X_H */
diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h
new file mode 100644
index 00000000..7a27f3f1
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/dm646x.h
@@ -0,0 +1,94 @@
+/*
+ * Chip specific defines for DM646x SoC
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_DM646X_H
+#define __ASM_ARCH_DM646X_H
+
+#include <mach/hardware.h>
+#include <mach/asp.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/clk.h>
+#include <linux/davinci_emac.h>
+
+#define DM646X_EMAC_BASE (0x01C80000)
+#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000)
+#define DM646X_EMAC_CNTRL_OFFSET (0x0000)
+#define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000)
+#define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000)
+#define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000)
+
+#define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000
+#define DM646X_ASYNC_EMIF_CS2_SPACE_BASE 0x42000000
+
+void __init dm646x_init(void);
+void __init dm646x_init_mcasp0(struct snd_platform_data *pdata);
+void __init dm646x_init_mcasp1(struct snd_platform_data *pdata);
+void __init dm646x_board_setup_refclk(struct clk *clk);
+int __init dm646x_init_edma(struct edma_rsv_info *rsv);
+
+void dm646x_video_init(void);
+
+enum vpif_if_type {
+ VPIF_IF_BT656,
+ VPIF_IF_BT1120,
+ VPIF_IF_RAW_BAYER
+};
+
+struct vpif_interface {
+ enum vpif_if_type if_type;
+ unsigned hd_pol:1;
+ unsigned vd_pol:1;
+ unsigned fid_pol:1;
+};
+
+struct vpif_subdev_info {
+ const char *name;
+ struct i2c_board_info board_info;
+ u32 input;
+ u32 output;
+ unsigned can_route:1;
+ struct vpif_interface vpif_if;
+};
+
+struct vpif_display_config {
+ int (*set_clock)(int, int);
+ struct vpif_subdev_info *subdevinfo;
+ int subdev_count;
+ const char **output;
+ int output_count;
+ const char *card_name;
+};
+
+struct vpif_input {
+ struct v4l2_input input;
+ const char *subdev_name;
+};
+
+#define VPIF_CAPTURE_MAX_CHANNELS 2
+
+struct vpif_capture_chan_config {
+ const struct vpif_input *inputs;
+ int input_count;
+};
+
+struct vpif_capture_config {
+ int (*setup_input_channel_mode)(int);
+ int (*setup_input_path)(int, const char *);
+ struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS];
+ struct vpif_subdev_info *subdev_info;
+ int subdev_count;
+ const char *card_name;
+};
+
+void dm646x_setup_vpif(struct vpif_display_config *,
+ struct vpif_capture_config *);
+
+#endif /* __ASM_ARCH_DM646X_H */
diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h
new file mode 100644
index 00000000..20c77f29
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/edma.h
@@ -0,0 +1,262 @@
+/*
+ * TI DAVINCI dma definitions
+ *
+ * Copyright (C) 2006-2009 Texas Instruments.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * This EDMA3 programming framework exposes two basic kinds of resource:
+ *
+ * Channel Triggers transfers, usually from a hardware event but
+ * also manually or by "chaining" from DMA completions.
+ * Each channel is coupled to a Parameter RAM (PaRAM) slot.
+ *
+ * Slot Each PaRAM slot holds a DMA transfer descriptor (PaRAM
+ * "set"), source and destination addresses, a link to a
+ * next PaRAM slot (if any), options for the transfer, and
+ * instructions for updating those addresses. There are
+ * more than twice as many slots as event channels.
+ *
+ * Each PaRAM set describes a sequence of transfers, either for one large
+ * buffer or for several discontiguous smaller buffers. An EDMA transfer
+ * is driven only from a channel, which performs the transfers specified
+ * in its PaRAM slot until there are no more transfers. When that last
+ * transfer completes, the "link" field may be used to reload the channel's
+ * PaRAM slot with a new transfer descriptor.
+ *
+ * The EDMA Channel Controller (CC) maps requests from channels into physical
+ * Transfer Controller (TC) requests when the channel triggers (by hardware
+ * or software events, or by chaining). The two physical DMA channels provided
+ * by the TCs are thus shared by many logical channels.
+ *
+ * DaVinci hardware also has a "QDMA" mechanism which is not currently
+ * supported through this interface. (DSP firmware uses it though.)
+ */
+
+#ifndef EDMA_H_
+#define EDMA_H_
+
+/* PaRAM slots are laid out like this */
+struct edmacc_param {
+ unsigned int opt;
+ unsigned int src;
+ unsigned int a_b_cnt;
+ unsigned int dst;
+ unsigned int src_dst_bidx;
+ unsigned int link_bcntrld;
+ unsigned int src_dst_cidx;
+ unsigned int ccnt;
+};
+
+#define CCINT0_INTERRUPT 16
+#define CCERRINT_INTERRUPT 17
+#define TCERRINT0_INTERRUPT 18
+#define TCERRINT1_INTERRUPT 19
+
+/* fields in edmacc_param.opt */
+#define SAM BIT(0)
+#define DAM BIT(1)
+#define SYNCDIM BIT(2)
+#define STATIC BIT(3)
+#define EDMA_FWID (0x07 << 8)
+#define TCCMODE BIT(11)
+#define EDMA_TCC(t) ((t) << 12)
+#define TCINTEN BIT(20)
+#define ITCINTEN BIT(21)
+#define TCCHEN BIT(22)
+#define ITCCHEN BIT(23)
+
+#define TRWORD (0x7<<2)
+#define PAENTRY (0x1ff<<5)
+
+/* Drivers should avoid using these symbolic names for dm644x
+ * channels, and use platform_device IORESOURCE_DMA resources
+ * instead. (Other DaVinci chips have different peripherals
+ * and thus have different DMA channel mappings.)
+ */
+#define DAVINCI_DMA_MCBSP_TX 2
+#define DAVINCI_DMA_MCBSP_RX 3
+#define DAVINCI_DMA_VPSS_HIST 4
+#define DAVINCI_DMA_VPSS_H3A 5
+#define DAVINCI_DMA_VPSS_PRVU 6
+#define DAVINCI_DMA_VPSS_RSZ 7
+#define DAVINCI_DMA_IMCOP_IMXINT 8
+#define DAVINCI_DMA_IMCOP_VLCDINT 9
+#define DAVINCI_DMA_IMCO_PASQINT 10
+#define DAVINCI_DMA_IMCOP_DSQINT 11
+#define DAVINCI_DMA_SPI_SPIX 16
+#define DAVINCI_DMA_SPI_SPIR 17
+#define DAVINCI_DMA_UART0_URXEVT0 18
+#define DAVINCI_DMA_UART0_UTXEVT0 19
+#define DAVINCI_DMA_UART1_URXEVT1 20
+#define DAVINCI_DMA_UART1_UTXEVT1 21
+#define DAVINCI_DMA_UART2_URXEVT2 22
+#define DAVINCI_DMA_UART2_UTXEVT2 23
+#define DAVINCI_DMA_MEMSTK_MSEVT 24
+#define DAVINCI_DMA_MMCRXEVT 26
+#define DAVINCI_DMA_MMCTXEVT 27
+#define DAVINCI_DMA_I2C_ICREVT 28
+#define DAVINCI_DMA_I2C_ICXEVT 29
+#define DAVINCI_DMA_GPIO_GPINT0 32
+#define DAVINCI_DMA_GPIO_GPINT1 33
+#define DAVINCI_DMA_GPIO_GPINT2 34
+#define DAVINCI_DMA_GPIO_GPINT3 35
+#define DAVINCI_DMA_GPIO_GPINT4 36
+#define DAVINCI_DMA_GPIO_GPINT5 37
+#define DAVINCI_DMA_GPIO_GPINT6 38
+#define DAVINCI_DMA_GPIO_GPINT7 39
+#define DAVINCI_DMA_GPIO_GPBNKINT0 40
+#define DAVINCI_DMA_GPIO_GPBNKINT1 41
+#define DAVINCI_DMA_GPIO_GPBNKINT2 42
+#define DAVINCI_DMA_GPIO_GPBNKINT3 43
+#define DAVINCI_DMA_GPIO_GPBNKINT4 44
+#define DAVINCI_DMA_TIMER0_TINT0 48
+#define DAVINCI_DMA_TIMER1_TINT1 49
+#define DAVINCI_DMA_TIMER2_TINT2 50
+#define DAVINCI_DMA_TIMER3_TINT3 51
+#define DAVINCI_DMA_PWM0 52
+#define DAVINCI_DMA_PWM1 53
+#define DAVINCI_DMA_PWM2 54
+
+/* DA830 specific EDMA3 information */
+#define EDMA_DA830_NUM_DMACH 32
+#define EDMA_DA830_NUM_TCC 32
+#define EDMA_DA830_NUM_PARAMENTRY 128
+#define EDMA_DA830_NUM_EVQUE 2
+#define EDMA_DA830_NUM_TC 2
+#define EDMA_DA830_CHMAP_EXIST 0
+#define EDMA_DA830_NUM_REGIONS 4
+#define DA830_DMACH2EVENT_MAP0 0x000FC03Fu
+#define DA830_DMACH2EVENT_MAP1 0x00000000u
+#define DA830_EDMA_ARM_OWN 0x30FFCCFFu
+
+/*ch_status paramater of callback function possible values*/
+#define DMA_COMPLETE 1
+#define DMA_CC_ERROR 2
+#define DMA_TC1_ERROR 3
+#define DMA_TC2_ERROR 4
+
+enum address_mode {
+ INCR = 0,
+ FIFO = 1
+};
+
+enum fifo_width {
+ W8BIT = 0,
+ W16BIT = 1,
+ W32BIT = 2,
+ W64BIT = 3,
+ W128BIT = 4,
+ W256BIT = 5
+};
+
+enum dma_event_q {
+ EVENTQ_0 = 0,
+ EVENTQ_1 = 1,
+ EVENTQ_2 = 2,
+ EVENTQ_3 = 3,
+ EVENTQ_DEFAULT = -1
+};
+
+enum sync_dimension {
+ ASYNC = 0,
+ ABSYNC = 1
+};
+
+#define EDMA_CTLR_CHAN(ctlr, chan) (((ctlr) << 16) | (chan))
+#define EDMA_CTLR(i) ((i) >> 16)
+#define EDMA_CHAN_SLOT(i) ((i) & 0xffff)
+
+#define EDMA_CHANNEL_ANY -1 /* for edma_alloc_channel() */
+#define EDMA_SLOT_ANY -1 /* for edma_alloc_slot() */
+#define EDMA_CONT_PARAMS_ANY 1001
+#define EDMA_CONT_PARAMS_FIXED_EXACT 1002
+#define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
+
+#define EDMA_MAX_CC 2
+
+/* alloc/free DMA channels and their dedicated parameter RAM slots */
+int edma_alloc_channel(int channel,
+ void (*callback)(unsigned channel, u16 ch_status, void *data),
+ void *data, enum dma_event_q);
+void edma_free_channel(unsigned channel);
+
+/* alloc/free parameter RAM slots */
+int edma_alloc_slot(unsigned ctlr, int slot);
+void edma_free_slot(unsigned slot);
+
+/* alloc/free a set of contiguous parameter RAM slots */
+int edma_alloc_cont_slots(unsigned ctlr, unsigned int id, int slot, int count);
+int edma_free_cont_slots(unsigned slot, int count);
+
+/* calls that operate on part of a parameter RAM slot */
+void edma_set_src(unsigned slot, dma_addr_t src_port,
+ enum address_mode mode, enum fifo_width);
+void edma_set_dest(unsigned slot, dma_addr_t dest_port,
+ enum address_mode mode, enum fifo_width);
+void edma_get_position(unsigned slot, dma_addr_t *src, dma_addr_t *dst);
+void edma_set_src_index(unsigned slot, s16 src_bidx, s16 src_cidx);
+void edma_set_dest_index(unsigned slot, s16 dest_bidx, s16 dest_cidx);
+void edma_set_transfer_params(unsigned slot, u16 acnt, u16 bcnt, u16 ccnt,
+ u16 bcnt_rld, enum sync_dimension sync_mode);
+void edma_link(unsigned from, unsigned to);
+void edma_unlink(unsigned from);
+
+/* calls that operate on an entire parameter RAM slot */
+void edma_write_slot(unsigned slot, const struct edmacc_param *params);
+void edma_read_slot(unsigned slot, struct edmacc_param *params);
+
+/* channel control operations */
+int edma_start(unsigned channel);
+void edma_stop(unsigned channel);
+void edma_clean_channel(unsigned channel);
+void edma_clear_event(unsigned channel);
+void edma_pause(unsigned channel);
+void edma_resume(unsigned channel);
+
+struct edma_rsv_info {
+
+ const s16 (*rsv_chans)[2];
+ const s16 (*rsv_slots)[2];
+};
+
+/* platform_data for EDMA driver */
+struct edma_soc_info {
+
+ /* how many dma resources of each type */
+ unsigned n_channel;
+ unsigned n_region;
+ unsigned n_slot;
+ unsigned n_tc;
+ unsigned n_cc;
+ enum dma_event_q default_queue;
+
+ /* Resource reservation for other cores */
+ struct edma_rsv_info *rsv;
+
+ const s8 (*queue_tc_mapping)[2];
+ const s8 (*queue_priority_mapping)[2];
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S
new file mode 100644
index 00000000..fbdebc7c
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/entry-macro.S
@@ -0,0 +1,51 @@
+/*
+ * Low-level IRQ helper macros for TI DaVinci-based platforms
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <mach/io.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =davinci_intc_base
+ ldr \base, [\base]
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined(CONFIG_AINTC) && defined(CONFIG_CP_INTC)
+ ldr \tmp, =davinci_intc_type
+ ldr \tmp, [\tmp]
+ cmp \tmp, #DAVINCI_INTC_TYPE_CP_INTC
+ beq 1001f
+#endif
+#if defined(CONFIG_AINTC)
+ ldr \tmp, [\base, #0x14]
+ movs \tmp, \tmp, lsr #2
+ sub \irqnr, \tmp, #1
+ b 1002f
+#endif
+#if defined(CONFIG_CP_INTC)
+1001: ldr \irqnr, [\base, #0x80] /* get irq number */
+ and \irqnr, \irqnr, #0xff /* irq is in bits 0-9 */
+ mov \tmp, \irqnr, lsr #3
+ and \tmp, \tmp, #0xfc
+ add \tmp, \tmp, #0x280 /* get the register offset */
+ ldr \irqstat, [\base, \tmp] /* get the intc status */
+ cmp \irqstat, #0x0
+#endif
+1002:
+ .endm
+
+ .macro irq_prio_table
+ .endm
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
new file mode 100644
index 00000000..fbece126
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -0,0 +1,161 @@
+/*
+ * TI DaVinci GPIO Support
+ *
+ * Copyright (c) 2006 David Brownell
+ * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.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 __DAVINCI_GPIO_H
+#define __DAVINCI_GPIO_H
+
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm-generic/gpio.h>
+
+#include <mach/irqs.h>
+#include <mach/common.h>
+
+#define DAVINCI_GPIO_BASE 0x01C67000
+
+enum davinci_gpio_type {
+ GPIO_TYPE_DAVINCI = 0,
+ GPIO_TYPE_TNETV107X,
+};
+
+/*
+ * basic gpio routines
+ *
+ * board-specific init should be done by arch/.../.../board-XXX.c (maybe
+ * initializing banks together) rather than boot loaders; kexec() won't
+ * go through boot loaders.
+ *
+ * the gpio clock will be turned on when gpios are used, and you may also
+ * need to pay attention to PINMUX registers to be sure those pins are
+ * used as gpios, not with other peripherals.
+ *
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1). For documentation,
+ * and maybe for later updates, code may write GPIO(N). These may be
+ * all 1.8V signals, all 3.3V ones, or a mix of the two. A given chip
+ * may not support all the GPIOs in that range.
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip. For now, they won't be usable as IRQ sources.
+ */
+#define GPIO(X) (X) /* 0 <= X <= (DAVINCI_N_GPIO - 1) */
+
+/* Convert GPIO signal to GPIO pin number */
+#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
+
+struct davinci_gpio_controller {
+ struct gpio_chip chip;
+ int irq_base;
+ spinlock_t lock;
+ void __iomem *regs;
+ void __iomem *set_data;
+ void __iomem *clr_data;
+ void __iomem *in_data;
+};
+
+/* The __gpio_to_controller() and __gpio_mask() functions inline to constants
+ * with constant parameters; or in outlined code they execute at runtime.
+ *
+ * You'd access the controller directly when reading or writing more than
+ * one gpio value at a time, and to support wired logic where the value
+ * being driven by the cpu need not match the value read back.
+ *
+ * These are NOT part of the cross-platform GPIO interface
+ */
+static inline struct davinci_gpio_controller *
+__gpio_to_controller(unsigned gpio)
+{
+ struct davinci_gpio_controller *ctlrs = davinci_soc_info.gpio_ctlrs;
+ int index = gpio / 32;
+
+ if (!ctlrs || index >= davinci_soc_info.gpio_ctlrs_num)
+ return NULL;
+
+ return ctlrs + index;
+}
+
+static inline u32 __gpio_mask(unsigned gpio)
+{
+ return 1 << (gpio % 32);
+}
+
+/*
+ * The get/set/clear functions will inline when called with constant
+ * parameters referencing built-in GPIOs, for low-overhead bitbanging.
+ *
+ * gpio_set_value() will inline only on traditional Davinci style controllers
+ * with distinct set/clear registers.
+ *
+ * Otherwise, calls with variable parameters or referencing external
+ * GPIOs (e.g. on GPIO expander chips) use outlined functions.
+ */
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (__builtin_constant_p(value) && gpio < davinci_soc_info.gpio_num) {
+ struct davinci_gpio_controller *ctlr;
+ u32 mask;
+
+ ctlr = __gpio_to_controller(gpio);
+
+ if (ctlr->set_data != ctlr->clr_data) {
+ mask = __gpio_mask(gpio);
+ if (value)
+ __raw_writel(mask, ctlr->set_data);
+ else
+ __raw_writel(mask, ctlr->clr_data);
+ return;
+ }
+ }
+
+ __gpio_set_value(gpio, value);
+}
+
+/* Returns zero or nonzero; works for gpios configured as inputs OR
+ * as outputs, at least for built-in GPIOs.
+ *
+ * NOTE: for built-in GPIOs, changes in reported values are synchronized
+ * to the GPIO clock. This is easily seen after calling gpio_set_value()
+ * and then immediately gpio_get_value(), where the gpio_get_value() will
+ * return the old value until the GPIO clock ticks and the new value gets
+ * latched.
+ */
+static inline int gpio_get_value(unsigned gpio)
+{
+ struct davinci_gpio_controller *ctlr;
+
+ if (!__builtin_constant_p(gpio) || gpio >= davinci_soc_info.gpio_num)
+ return __gpio_get_value(gpio);
+
+ ctlr = __gpio_to_controller(gpio);
+ return __gpio_mask(gpio) & __raw_readl(ctlr->in_data);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ if (__builtin_constant_p(gpio) && gpio < davinci_soc_info.gpio_num)
+ return 0;
+ else
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ /* don't support the reverse mapping */
+ return -ENOSYS;
+}
+
+#endif /* __DAVINCI_GPIO_H */
diff --git a/arch/arm/mach-davinci/include/mach/hardware.h b/arch/arm/mach-davinci/include/mach/hardware.h
new file mode 100644
index 00000000..414e0b93
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/hardware.h
@@ -0,0 +1,41 @@
+/*
+ * Hardware definitions common to all DaVinci family processors
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 2007 (c) Deep Root Systems, LLC. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * Before you add anything to ths file:
+ *
+ * This header is for defines common to ALL DaVinci family chips.
+ * Anything that is chip specific should go in <chipname>.h,
+ * and the chip/board init code should then explicitly include
+ * <chipname>.h
+ */
+#define DAVINCI_SYSTEM_MODULE_BASE 0x01C40000
+
+/*
+ * I/O mapping
+ */
+#define IO_PHYS 0x01c00000UL
+#define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
+#define IO_SIZE 0x00400000
+#define IO_VIRT (IO_PHYS + IO_OFFSET)
+#define io_v2p(va) ((va) - IO_OFFSET)
+#define __IO_ADDRESS(x) ((x) + IO_OFFSET)
+#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x) x
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
+#endif
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-davinci/include/mach/i2c.h b/arch/arm/mach-davinci/include/mach/i2c.h
new file mode 100644
index 00000000..2312d197
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/i2c.h
@@ -0,0 +1,26 @@
+/*
+ * DaVinci I2C controller platform_device info
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+*/
+
+#ifndef __ASM_ARCH_I2C_H
+#define __ASM_ARCH_I2C_H
+
+/* All frequencies are expressed in kHz */
+struct davinci_i2c_platform_data {
+ unsigned int bus_freq; /* standard bus frequency (kHz) */
+ unsigned int bus_delay; /* post-transaction delay (usec) */
+ unsigned int sda_pin; /* GPIO pin ID to use for SDA */
+ unsigned int scl_pin; /* GPIO pin ID to use for SCL */
+};
+
+/* for board setup code */
+void davinci_init_i2c(struct davinci_i2c_platform_data *);
+
+#endif /* __ASM_ARCH_I2C_H */
diff --git a/arch/arm/mach-davinci/include/mach/io.h b/arch/arm/mach-davinci/include/mach/io.h
new file mode 100644
index 00000000..d1b95495
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/io.h
@@ -0,0 +1,32 @@
+/*
+ * DaVinci IO address definitions
+ *
+ * Copied from include/asm/arm/arch-omap/io.h
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+#ifndef __ASSEMBLER__
+#define __arch_ioremap davinci_ioremap
+#define __arch_iounmap davinci_iounmap
+
+void __iomem *davinci_ioremap(unsigned long phys, size_t size,
+ unsigned int type);
+void davinci_iounmap(volatile void __iomem *addr);
+#endif
+#endif /* __ASM_ARCH_IO_H */
diff --git a/arch/arm/mach-davinci/include/mach/irqs.h b/arch/arm/mach-davinci/include/mach/irqs.h
new file mode 100644
index 00000000..ec76c777
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/irqs.h
@@ -0,0 +1,506 @@
+/*
+ * DaVinci interrupt controller definitions
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/* Base address */
+#define DAVINCI_ARM_INTC_BASE 0x01C48000
+
+#define DAVINCI_INTC_TYPE_AINTC 0
+#define DAVINCI_INTC_TYPE_CP_INTC 1
+
+/* Interrupt lines */
+#define IRQ_VDINT0 0
+#define IRQ_VDINT1 1
+#define IRQ_VDINT2 2
+#define IRQ_HISTINT 3
+#define IRQ_H3AINT 4
+#define IRQ_PRVUINT 5
+#define IRQ_RSZINT 6
+#define IRQ_VFOCINT 7
+#define IRQ_VENCINT 8
+#define IRQ_ASQINT 9
+#define IRQ_IMXINT 10
+#define IRQ_VLCDINT 11
+#define IRQ_USBINT 12
+#define IRQ_EMACINT 13
+
+#define IRQ_CCINT0 16
+#define IRQ_CCERRINT 17
+#define IRQ_TCERRINT0 18
+#define IRQ_TCERRINT 19
+#define IRQ_PSCIN 20
+
+#define IRQ_IDE 22
+#define IRQ_HPIINT 23
+#define IRQ_MBXINT 24
+#define IRQ_MBRINT 25
+#define IRQ_MMCINT 26
+#define IRQ_SDIOINT 27
+#define IRQ_MSINT 28
+#define IRQ_DDRINT 29
+#define IRQ_AEMIFINT 30
+#define IRQ_VLQINT 31
+#define IRQ_TINT0_TINT12 32
+#define IRQ_TINT0_TINT34 33
+#define IRQ_TINT1_TINT12 34
+#define IRQ_TINT1_TINT34 35
+#define IRQ_PWMINT0 36
+#define IRQ_PWMINT1 37
+#define IRQ_PWMINT2 38
+#define IRQ_I2C 39
+#define IRQ_UARTINT0 40
+#define IRQ_UARTINT1 41
+#define IRQ_UARTINT2 42
+#define IRQ_SPINT0 43
+#define IRQ_SPINT1 44
+
+#define IRQ_DSP2ARM0 46
+#define IRQ_DSP2ARM1 47
+#define IRQ_GPIO0 48
+#define IRQ_GPIO1 49
+#define IRQ_GPIO2 50
+#define IRQ_GPIO3 51
+#define IRQ_GPIO4 52
+#define IRQ_GPIO5 53
+#define IRQ_GPIO6 54
+#define IRQ_GPIO7 55
+#define IRQ_GPIOBNK0 56
+#define IRQ_GPIOBNK1 57
+#define IRQ_GPIOBNK2 58
+#define IRQ_GPIOBNK3 59
+#define IRQ_GPIOBNK4 60
+#define IRQ_COMMTX 61
+#define IRQ_COMMRX 62
+#define IRQ_EMUINT 63
+
+#define DAVINCI_N_AINTC_IRQ 64
+
+#define ARCH_TIMER_IRQ IRQ_TINT1_TINT34
+
+/* DaVinci DM6467-specific Interrupts */
+#define IRQ_DM646X_VP_VERTINT0 0
+#define IRQ_DM646X_VP_VERTINT1 1
+#define IRQ_DM646X_VP_VERTINT2 2
+#define IRQ_DM646X_VP_VERTINT3 3
+#define IRQ_DM646X_VP_ERRINT 4
+#define IRQ_DM646X_RESERVED_1 5
+#define IRQ_DM646X_RESERVED_2 6
+#define IRQ_DM646X_WDINT 7
+#define IRQ_DM646X_CRGENINT0 8
+#define IRQ_DM646X_CRGENINT1 9
+#define IRQ_DM646X_TSIFINT0 10
+#define IRQ_DM646X_TSIFINT1 11
+#define IRQ_DM646X_VDCEINT 12
+#define IRQ_DM646X_USBINT 13
+#define IRQ_DM646X_USBDMAINT 14
+#define IRQ_DM646X_PCIINT 15
+#define IRQ_DM646X_TCERRINT2 20
+#define IRQ_DM646X_TCERRINT3 21
+#define IRQ_DM646X_IDE 22
+#define IRQ_DM646X_HPIINT 23
+#define IRQ_DM646X_EMACRXTHINT 24
+#define IRQ_DM646X_EMACRXINT 25
+#define IRQ_DM646X_EMACTXINT 26
+#define IRQ_DM646X_EMACMISCINT 27
+#define IRQ_DM646X_MCASP0TXINT 28
+#define IRQ_DM646X_MCASP0RXINT 29
+#define IRQ_DM646X_RESERVED_3 31
+#define IRQ_DM646X_MCASP1TXINT 32
+#define IRQ_DM646X_VLQINT 38
+#define IRQ_DM646X_UARTINT2 42
+#define IRQ_DM646X_SPINT0 43
+#define IRQ_DM646X_SPINT1 44
+#define IRQ_DM646X_DSP2ARMINT 45
+#define IRQ_DM646X_RESERVED_4 46
+#define IRQ_DM646X_PSCINT 47
+#define IRQ_DM646X_GPIO0 48
+#define IRQ_DM646X_GPIO1 49
+#define IRQ_DM646X_GPIO2 50
+#define IRQ_DM646X_GPIO3 51
+#define IRQ_DM646X_GPIO4 52
+#define IRQ_DM646X_GPIO5 53
+#define IRQ_DM646X_GPIO6 54
+#define IRQ_DM646X_GPIO7 55
+#define IRQ_DM646X_GPIOBNK0 56
+#define IRQ_DM646X_GPIOBNK1 57
+#define IRQ_DM646X_GPIOBNK2 58
+#define IRQ_DM646X_DDRINT 59
+#define IRQ_DM646X_AEMIFINT 60
+
+/* DaVinci DM355-specific Interrupts */
+#define IRQ_DM355_CCDC_VDINT0 0
+#define IRQ_DM355_CCDC_VDINT1 1
+#define IRQ_DM355_CCDC_VDINT2 2
+#define IRQ_DM355_IPIPE_HST 3
+#define IRQ_DM355_H3AINT 4
+#define IRQ_DM355_IPIPE_SDR 5
+#define IRQ_DM355_IPIPEIFINT 6
+#define IRQ_DM355_OSDINT 7
+#define IRQ_DM355_VENCINT 8
+#define IRQ_DM355_IMCOPINT 11
+#define IRQ_DM355_RTOINT 13
+#define IRQ_DM355_TINT4 13
+#define IRQ_DM355_TINT2_TINT12 13
+#define IRQ_DM355_UARTINT2 14
+#define IRQ_DM355_TINT5 14
+#define IRQ_DM355_TINT2_TINT34 14
+#define IRQ_DM355_TINT6 15
+#define IRQ_DM355_TINT3_TINT12 15
+#define IRQ_DM355_SPINT1_0 17
+#define IRQ_DM355_SPINT1_1 18
+#define IRQ_DM355_SPINT2_0 19
+#define IRQ_DM355_SPINT2_1 21
+#define IRQ_DM355_TINT7 22
+#define IRQ_DM355_TINT3_TINT34 22
+#define IRQ_DM355_SDIOINT0 23
+#define IRQ_DM355_MMCINT0 26
+#define IRQ_DM355_MSINT 26
+#define IRQ_DM355_MMCINT1 27
+#define IRQ_DM355_PWMINT3 28
+#define IRQ_DM355_SDIOINT1 31
+#define IRQ_DM355_SPINT0_0 42
+#define IRQ_DM355_SPINT0_1 43
+#define IRQ_DM355_GPIO0 44
+#define IRQ_DM355_GPIO1 45
+#define IRQ_DM355_GPIO2 46
+#define IRQ_DM355_GPIO3 47
+#define IRQ_DM355_GPIO4 48
+#define IRQ_DM355_GPIO5 49
+#define IRQ_DM355_GPIO6 50
+#define IRQ_DM355_GPIO7 51
+#define IRQ_DM355_GPIO8 52
+#define IRQ_DM355_GPIO9 53
+#define IRQ_DM355_GPIOBNK0 54
+#define IRQ_DM355_GPIOBNK1 55
+#define IRQ_DM355_GPIOBNK2 56
+#define IRQ_DM355_GPIOBNK3 57
+#define IRQ_DM355_GPIOBNK4 58
+#define IRQ_DM355_GPIOBNK5 59
+#define IRQ_DM355_GPIOBNK6 60
+
+/* DaVinci DM365-specific Interrupts */
+#define IRQ_DM365_INSFINT 7
+#define IRQ_DM365_IMXINT1 8
+#define IRQ_DM365_IMXINT0 10
+#define IRQ_DM365_KLD_ARMINT 10
+#define IRQ_DM365_IMCOPINT 11
+#define IRQ_DM365_RTOINT 13
+#define IRQ_DM365_TINT5 14
+#define IRQ_DM365_TINT6 15
+#define IRQ_DM365_SPINT2_1 21
+#define IRQ_DM365_TINT7 22
+#define IRQ_DM365_SDIOINT0 23
+#define IRQ_DM365_MMCINT1 27
+#define IRQ_DM365_PWMINT3 28
+#define IRQ_DM365_RTCINT 29
+#define IRQ_DM365_SDIOINT1 31
+#define IRQ_DM365_SPIINT0_0 42
+#define IRQ_DM365_SPIINT3_0 43
+#define IRQ_DM365_GPIO0 44
+#define IRQ_DM365_GPIO1 45
+#define IRQ_DM365_GPIO2 46
+#define IRQ_DM365_GPIO3 47
+#define IRQ_DM365_GPIO4 48
+#define IRQ_DM365_GPIO5 49
+#define IRQ_DM365_GPIO6 50
+#define IRQ_DM365_GPIO7 51
+#define IRQ_DM365_EMAC_RXTHRESH 52
+#define IRQ_DM365_EMAC_RXPULSE 53
+#define IRQ_DM365_EMAC_TXPULSE 54
+#define IRQ_DM365_EMAC_MISCPULSE 55
+#define IRQ_DM365_GPIO12 56
+#define IRQ_DM365_GPIO13 57
+#define IRQ_DM365_GPIO14 58
+#define IRQ_DM365_GPIO15 59
+#define IRQ_DM365_ADCINT 59
+#define IRQ_DM365_KEYINT 60
+#define IRQ_DM365_TCERRINT2 61
+#define IRQ_DM365_TCERRINT3 62
+#define IRQ_DM365_EMUINT 63
+
+/* DA8XX interrupts */
+#define IRQ_DA8XX_COMMTX 0
+#define IRQ_DA8XX_COMMRX 1
+#define IRQ_DA8XX_NINT 2
+#define IRQ_DA8XX_EVTOUT0 3
+#define IRQ_DA8XX_EVTOUT1 4
+#define IRQ_DA8XX_EVTOUT2 5
+#define IRQ_DA8XX_EVTOUT3 6
+#define IRQ_DA8XX_EVTOUT4 7
+#define IRQ_DA8XX_EVTOUT5 8
+#define IRQ_DA8XX_EVTOUT6 9
+#define IRQ_DA8XX_EVTOUT7 10
+#define IRQ_DA8XX_CCINT0 11
+#define IRQ_DA8XX_CCERRINT 12
+#define IRQ_DA8XX_TCERRINT0 13
+#define IRQ_DA8XX_AEMIFINT 14
+#define IRQ_DA8XX_I2CINT0 15
+#define IRQ_DA8XX_MMCSDINT0 16
+#define IRQ_DA8XX_MMCSDINT1 17
+#define IRQ_DA8XX_ALLINT0 18
+#define IRQ_DA8XX_RTC 19
+#define IRQ_DA8XX_SPINT0 20
+#define IRQ_DA8XX_TINT12_0 21
+#define IRQ_DA8XX_TINT34_0 22
+#define IRQ_DA8XX_TINT12_1 23
+#define IRQ_DA8XX_TINT34_1 24
+#define IRQ_DA8XX_UARTINT0 25
+#define IRQ_DA8XX_KEYMGRINT 26
+#define IRQ_DA8XX_SECINT 26
+#define IRQ_DA8XX_SECKEYERR 26
+#define IRQ_DA8XX_CHIPINT0 28
+#define IRQ_DA8XX_CHIPINT1 29
+#define IRQ_DA8XX_CHIPINT2 30
+#define IRQ_DA8XX_CHIPINT3 31
+#define IRQ_DA8XX_TCERRINT1 32
+#define IRQ_DA8XX_C0_RX_THRESH_PULSE 33
+#define IRQ_DA8XX_C0_RX_PULSE 34
+#define IRQ_DA8XX_C0_TX_PULSE 35
+#define IRQ_DA8XX_C0_MISC_PULSE 36
+#define IRQ_DA8XX_C1_RX_THRESH_PULSE 37
+#define IRQ_DA8XX_C1_RX_PULSE 38
+#define IRQ_DA8XX_C1_TX_PULSE 39
+#define IRQ_DA8XX_C1_MISC_PULSE 40
+#define IRQ_DA8XX_MEMERR 41
+#define IRQ_DA8XX_GPIO0 42
+#define IRQ_DA8XX_GPIO1 43
+#define IRQ_DA8XX_GPIO2 44
+#define IRQ_DA8XX_GPIO3 45
+#define IRQ_DA8XX_GPIO4 46
+#define IRQ_DA8XX_GPIO5 47
+#define IRQ_DA8XX_GPIO6 48
+#define IRQ_DA8XX_GPIO7 49
+#define IRQ_DA8XX_GPIO8 50
+#define IRQ_DA8XX_I2CINT1 51
+#define IRQ_DA8XX_LCDINT 52
+#define IRQ_DA8XX_UARTINT1 53
+#define IRQ_DA8XX_MCASPINT 54
+#define IRQ_DA8XX_ALLINT1 55
+#define IRQ_DA8XX_SPINT1 56
+#define IRQ_DA8XX_UHPI_INT1 57
+#define IRQ_DA8XX_USB_INT 58
+#define IRQ_DA8XX_IRQN 59
+#define IRQ_DA8XX_RWAKEUP 60
+#define IRQ_DA8XX_UARTINT2 61
+#define IRQ_DA8XX_DFTSSINT 62
+#define IRQ_DA8XX_EHRPWM0 63
+#define IRQ_DA8XX_EHRPWM0TZ 64
+#define IRQ_DA8XX_EHRPWM1 65
+#define IRQ_DA8XX_EHRPWM1TZ 66
+#define IRQ_DA8XX_ECAP0 69
+#define IRQ_DA8XX_ECAP1 70
+#define IRQ_DA8XX_ECAP2 71
+#define IRQ_DA8XX_ARMCLKSTOPREQ 90
+
+/* DA830 specific interrupts */
+#define IRQ_DA830_MPUERR 27
+#define IRQ_DA830_IOPUERR 27
+#define IRQ_DA830_BOOTCFGERR 27
+#define IRQ_DA830_EHRPWM2 67
+#define IRQ_DA830_EHRPWM2TZ 68
+#define IRQ_DA830_EQEP0 72
+#define IRQ_DA830_EQEP1 73
+#define IRQ_DA830_T12CMPINT0_0 74
+#define IRQ_DA830_T12CMPINT1_0 75
+#define IRQ_DA830_T12CMPINT2_0 76
+#define IRQ_DA830_T12CMPINT3_0 77
+#define IRQ_DA830_T12CMPINT4_0 78
+#define IRQ_DA830_T12CMPINT5_0 79
+#define IRQ_DA830_T12CMPINT6_0 80
+#define IRQ_DA830_T12CMPINT7_0 81
+#define IRQ_DA830_T12CMPINT0_1 82
+#define IRQ_DA830_T12CMPINT1_1 83
+#define IRQ_DA830_T12CMPINT2_1 84
+#define IRQ_DA830_T12CMPINT3_1 85
+#define IRQ_DA830_T12CMPINT4_1 86
+#define IRQ_DA830_T12CMPINT5_1 87
+#define IRQ_DA830_T12CMPINT6_1 88
+#define IRQ_DA830_T12CMPINT7_1 89
+
+#define DA830_N_CP_INTC_IRQ 96
+
+/* DA850 speicific interrupts */
+#define IRQ_DA850_MPUADDRERR0 27
+#define IRQ_DA850_MPUPROTERR0 27
+#define IRQ_DA850_IOPUADDRERR0 27
+#define IRQ_DA850_IOPUPROTERR0 27
+#define IRQ_DA850_IOPUADDRERR1 27
+#define IRQ_DA850_IOPUPROTERR1 27
+#define IRQ_DA850_IOPUADDRERR2 27
+#define IRQ_DA850_IOPUPROTERR2 27
+#define IRQ_DA850_BOOTCFG_ADDR_ERR 27
+#define IRQ_DA850_BOOTCFG_PROT_ERR 27
+#define IRQ_DA850_MPUADDRERR1 27
+#define IRQ_DA850_MPUPROTERR1 27
+#define IRQ_DA850_IOPUADDRERR3 27
+#define IRQ_DA850_IOPUPROTERR3 27
+#define IRQ_DA850_IOPUADDRERR4 27
+#define IRQ_DA850_IOPUPROTERR4 27
+#define IRQ_DA850_IOPUADDRERR5 27
+#define IRQ_DA850_IOPUPROTERR5 27
+#define IRQ_DA850_MIOPU_BOOTCFG_ERR 27
+#define IRQ_DA850_SATAINT 67
+#define IRQ_DA850_TINT12_2 68
+#define IRQ_DA850_TINT34_2 68
+#define IRQ_DA850_TINTALL_2 68
+#define IRQ_DA850_MMCSDINT0_1 72
+#define IRQ_DA850_MMCSDINT1_1 73
+#define IRQ_DA850_T12CMPINT0_2 74
+#define IRQ_DA850_T12CMPINT1_2 75
+#define IRQ_DA850_T12CMPINT2_2 76
+#define IRQ_DA850_T12CMPINT3_2 77
+#define IRQ_DA850_T12CMPINT4_2 78
+#define IRQ_DA850_T12CMPINT5_2 79
+#define IRQ_DA850_T12CMPINT6_2 80
+#define IRQ_DA850_T12CMPINT7_2 81
+#define IRQ_DA850_T12CMPINT0_3 82
+#define IRQ_DA850_T12CMPINT1_3 83
+#define IRQ_DA850_T12CMPINT2_3 84
+#define IRQ_DA850_T12CMPINT3_3 85
+#define IRQ_DA850_T12CMPINT4_3 86
+#define IRQ_DA850_T12CMPINT5_3 87
+#define IRQ_DA850_T12CMPINT6_3 88
+#define IRQ_DA850_T12CMPINT7_3 89
+#define IRQ_DA850_RPIINT 91
+#define IRQ_DA850_VPIFINT 92
+#define IRQ_DA850_CCINT1 93
+#define IRQ_DA850_CCERRINT1 94
+#define IRQ_DA850_TCERRINT2 95
+#define IRQ_DA850_TINT12_3 96
+#define IRQ_DA850_TINT34_3 96
+#define IRQ_DA850_TINTALL_3 96
+#define IRQ_DA850_MCBSP0RINT 97
+#define IRQ_DA850_MCBSP0XINT 98
+#define IRQ_DA850_MCBSP1RINT 99
+#define IRQ_DA850_MCBSP1XINT 100
+
+#define DA850_N_CP_INTC_IRQ 101
+
+
+/* TNETV107X specific interrupts */
+#define IRQ_TNETV107X_TDM1_TXDMA 0
+#define IRQ_TNETV107X_EXT_INT_0 1
+#define IRQ_TNETV107X_EXT_INT_1 2
+#define IRQ_TNETV107X_GPIO_INT12 3
+#define IRQ_TNETV107X_GPIO_INT13 4
+#define IRQ_TNETV107X_TIMER_0_TINT12 5
+#define IRQ_TNETV107X_TIMER_1_TINT12 6
+#define IRQ_TNETV107X_UART0 7
+#define IRQ_TNETV107X_TDM1_RXDMA 8
+#define IRQ_TNETV107X_MCDMA_INT0 9
+#define IRQ_TNETV107X_MCDMA_INT1 10
+#define IRQ_TNETV107X_TPCC 11
+#define IRQ_TNETV107X_TPCC_INT0 12
+#define IRQ_TNETV107X_TPCC_INT1 13
+#define IRQ_TNETV107X_TPCC_INT2 14
+#define IRQ_TNETV107X_TPCC_INT3 15
+#define IRQ_TNETV107X_TPTC0 16
+#define IRQ_TNETV107X_TPTC1 17
+#define IRQ_TNETV107X_TIMER_0_TINT34 18
+#define IRQ_TNETV107X_ETHSS 19
+#define IRQ_TNETV107X_TIMER_1_TINT34 20
+#define IRQ_TNETV107X_DSP2ARM_INT0 21
+#define IRQ_TNETV107X_DSP2ARM_INT1 22
+#define IRQ_TNETV107X_ARM_NPMUIRQ 23
+#define IRQ_TNETV107X_USB1 24
+#define IRQ_TNETV107X_VLYNQ 25
+#define IRQ_TNETV107X_UART0_DMATX 26
+#define IRQ_TNETV107X_UART0_DMARX 27
+#define IRQ_TNETV107X_TDM1_TXMCSP 28
+#define IRQ_TNETV107X_SSP 29
+#define IRQ_TNETV107X_MCDMA_INT2 30
+#define IRQ_TNETV107X_MCDMA_INT3 31
+#define IRQ_TNETV107X_TDM_CODECIF_EOT 32
+#define IRQ_TNETV107X_IMCOP_SQR_ARM 33
+#define IRQ_TNETV107X_USB0 34
+#define IRQ_TNETV107X_USB_CDMA 35
+#define IRQ_TNETV107X_LCD 36
+#define IRQ_TNETV107X_KEYPAD 37
+#define IRQ_TNETV107X_KEYPAD_FREE 38
+#define IRQ_TNETV107X_RNG 39
+#define IRQ_TNETV107X_PKA 40
+#define IRQ_TNETV107X_TDM0_TXDMA 41
+#define IRQ_TNETV107X_TDM0_RXDMA 42
+#define IRQ_TNETV107X_TDM0_TXMCSP 43
+#define IRQ_TNETV107X_TDM0_RXMCSP 44
+#define IRQ_TNETV107X_TDM1_RXMCSP 45
+#define IRQ_TNETV107X_SDIO1 46
+#define IRQ_TNETV107X_SDIO0 47
+#define IRQ_TNETV107X_TSC 48
+#define IRQ_TNETV107X_TS 49
+#define IRQ_TNETV107X_UART1 50
+#define IRQ_TNETV107X_MBX_LITE 51
+#define IRQ_TNETV107X_GPIO_INT00 52
+#define IRQ_TNETV107X_GPIO_INT01 53
+#define IRQ_TNETV107X_GPIO_INT02 54
+#define IRQ_TNETV107X_GPIO_INT03 55
+#define IRQ_TNETV107X_UART2 56
+#define IRQ_TNETV107X_UART2_DMATX 57
+#define IRQ_TNETV107X_UART2_DMARX 58
+#define IRQ_TNETV107X_IMCOP_IMX 59
+#define IRQ_TNETV107X_IMCOP_VLCD 60
+#define IRQ_TNETV107X_AES 61
+#define IRQ_TNETV107X_DES 62
+#define IRQ_TNETV107X_SHAMD5 63
+#define IRQ_TNETV107X_TPCC_ERR 68
+#define IRQ_TNETV107X_TPCC_PROT 69
+#define IRQ_TNETV107X_TPTC0_ERR 70
+#define IRQ_TNETV107X_TPTC1_ERR 71
+#define IRQ_TNETV107X_UART0_ERR 72
+#define IRQ_TNETV107X_UART1_ERR 73
+#define IRQ_TNETV107X_AEMIF_ERR 74
+#define IRQ_TNETV107X_DDR_ERR 75
+#define IRQ_TNETV107X_WDTARM_INT0 76
+#define IRQ_TNETV107X_MCDMA_ERR 77
+#define IRQ_TNETV107X_GPIO_ERR 78
+#define IRQ_TNETV107X_MPU_ADDR 79
+#define IRQ_TNETV107X_MPU_PROT 80
+#define IRQ_TNETV107X_IOPU_ADDR 81
+#define IRQ_TNETV107X_IOPU_PROT 82
+#define IRQ_TNETV107X_KEYPAD_ADDR_ERR 83
+#define IRQ_TNETV107X_WDT0_ADDR_ERR 84
+#define IRQ_TNETV107X_WDT1_ADDR_ERR 85
+#define IRQ_TNETV107X_CLKCTL_ADDR_ERR 86
+#define IRQ_TNETV107X_PLL_UNLOCK 87
+#define IRQ_TNETV107X_WDTDSP_INT0 88
+#define IRQ_TNETV107X_SEC_CTRL_VIOLATION 89
+#define IRQ_TNETV107X_KEY_MNG_VIOLATION 90
+#define IRQ_TNETV107X_PBIST_CPU 91
+#define IRQ_TNETV107X_WDTARM 92
+#define IRQ_TNETV107X_PSC 93
+#define IRQ_TNETV107X_MMC0 94
+#define IRQ_TNETV107X_MMC1 95
+
+#define TNETV107X_N_CP_INTC_IRQ 96
+
+/* da850 currently has the most gpio pins (144) */
+#define DAVINCI_N_GPIO 144
+/* da850 currently has the most irqs so use DA850_N_CP_INTC_IRQ */
+#define NR_IRQS (DA850_N_CP_INTC_IRQ + DAVINCI_N_GPIO)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-davinci/include/mach/keyscan.h b/arch/arm/mach-davinci/include/mach/keyscan.h
new file mode 100644
index 00000000..7a560e05
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/keyscan.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 Texas Instruments, Inc
+ *
+ * Author: Miguel Aguilar <miguel.aguilar@ridgerun.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 DAVINCI_KEYSCAN_H
+#define DAVINCI_KEYSCAN_H
+
+#include <linux/io.h>
+
+enum davinci_matrix_types {
+ DAVINCI_KEYSCAN_MATRIX_4X4,
+ DAVINCI_KEYSCAN_MATRIX_5X3,
+};
+
+struct davinci_ks_platform_data {
+ int (*device_enable)(struct device *dev);
+ unsigned short *keymap;
+ u32 keymapsize;
+ u8 rep:1;
+ u8 strobe;
+ u8 interval;
+ u8 matrix_type;
+};
+
+#endif
+
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
new file mode 100644
index 00000000..491249ef
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -0,0 +1,51 @@
+/*
+ * DaVinci memory space definitions
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/**************************************************************************
+ * Included Files
+ **************************************************************************/
+#include <asm/page.h>
+#include <asm/sizes.h>
+
+/**************************************************************************
+ * Definitions
+ **************************************************************************/
+#define DAVINCI_DDR_BASE 0x80000000
+#define DA8XX_DDR_BASE 0xc0000000
+
+#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
+#error Cannot enable DaVinci and DA8XX platforms concurrently
+#elif defined(CONFIG_ARCH_DAVINCI_DA8XX)
+#define PLAT_PHYS_OFFSET DA8XX_DDR_BASE
+#else
+#define PLAT_PHYS_OFFSET DAVINCI_DDR_BASE
+#endif
+
+#define DDR2_SDRCR_OFFSET 0xc
+#define DDR2_SRPD_BIT BIT(23)
+#define DDR2_MCLKSTOPEN_BIT BIT(30)
+#define DDR2_LPMODEN_BIT BIT(31)
+
+/*
+ * Increase size of DMA-consistent memory region
+ */
+#define CONSISTENT_DMA_SIZE (14<<20)
+
+/*
+ * Restrict DMA-able region to workaround silicon bug. The bug
+ * restricts buffers available for DMA to video hardware to be
+ * below 128M
+ */
+#define ARM_DMA_ZONE_SIZE SZ_128M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-davinci/include/mach/mmc.h b/arch/arm/mach-davinci/include/mach/mmc.h
new file mode 100644
index 00000000..d4f1e967
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mmc.h
@@ -0,0 +1,36 @@
+/*
+ * Board-specific MMC configuration
+ */
+
+#ifndef _DAVINCI_MMC_H
+#define _DAVINCI_MMC_H
+
+#include <linux/types.h>
+#include <linux/mmc/host.h>
+
+struct davinci_mmc_config {
+ /* get_cd()/get_wp() may sleep */
+ int (*get_cd)(int module);
+ int (*get_ro)(int module);
+ /* wires == 0 is equivalent to wires == 4 (4-bit parallel) */
+ u8 wires;
+
+ u32 max_freq;
+
+ /* any additional host capabilities: OR'd in to mmc->f_caps */
+ u32 caps;
+
+ /* Version of the MMC/SD controller */
+ u8 version;
+
+ /* Number of sg segments */
+ u8 nr_sg;
+};
+void davinci_setup_mmc(int module, struct davinci_mmc_config *config);
+
+enum {
+ MMC_CTLR_VERSION_1 = 0, /* DM644x and DM355 */
+ MMC_CTLR_VERSION_2, /* DA830 */
+};
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h
new file mode 100644
index 00000000..5d4e0fed
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -0,0 +1,1207 @@
+/*
+ * Table of the DAVINCI register configurations for the PINMUX combinations
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on linux/include/asm-arm/arch-omap/mux.h:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+
+#ifndef __INC_MACH_MUX_H
+#define __INC_MACH_MUX_H
+
+struct mux_config {
+ const char *name;
+ const char *mux_reg_name;
+ const unsigned char mux_reg;
+ const unsigned char mask_offset;
+ const unsigned char mask;
+ const unsigned char mode;
+ bool debug;
+};
+
+enum davinci_dm644x_index {
+ /* ATA and HDDIR functions */
+ DM644X_HDIREN,
+ DM644X_ATAEN,
+ DM644X_ATAEN_DISABLE,
+
+ /* HPI functions */
+ DM644X_HPIEN_DISABLE,
+
+ /* AEAW functions */
+ DM644X_AEAW,
+ DM644X_AEAW0,
+ DM644X_AEAW1,
+ DM644X_AEAW2,
+ DM644X_AEAW3,
+ DM644X_AEAW4,
+
+ /* Memory Stick */
+ DM644X_MSTK,
+
+ /* I2C */
+ DM644X_I2C,
+
+ /* ASP function */
+ DM644X_MCBSP,
+
+ /* UART1 */
+ DM644X_UART1,
+
+ /* UART2 */
+ DM644X_UART2,
+
+ /* PWM0 */
+ DM644X_PWM0,
+
+ /* PWM1 */
+ DM644X_PWM1,
+
+ /* PWM2 */
+ DM644X_PWM2,
+
+ /* VLYNQ function */
+ DM644X_VLYNQEN,
+ DM644X_VLSCREN,
+ DM644X_VLYNQWD,
+
+ /* EMAC and MDIO function */
+ DM644X_EMACEN,
+
+ /* GPIO3V[0:16] pins */
+ DM644X_GPIO3V,
+
+ /* GPIO pins */
+ DM644X_GPIO0,
+ DM644X_GPIO3,
+ DM644X_GPIO43_44,
+ DM644X_GPIO46_47,
+
+ /* VPBE */
+ DM644X_RGB666,
+
+ /* LCD */
+ DM644X_LOEEN,
+ DM644X_LFLDEN,
+};
+
+enum davinci_dm646x_index {
+ /* ATA function */
+ DM646X_ATAEN,
+
+ /* AUDIO Clock */
+ DM646X_AUDCK1,
+ DM646X_AUDCK0,
+
+ /* CRGEN Control */
+ DM646X_CRGMUX,
+
+ /* VPIF Control */
+ DM646X_STSOMUX_DISABLE,
+ DM646X_STSIMUX_DISABLE,
+ DM646X_PTSOMUX_DISABLE,
+ DM646X_PTSIMUX_DISABLE,
+
+ /* TSIF Control */
+ DM646X_STSOMUX,
+ DM646X_STSIMUX,
+ DM646X_PTSOMUX_PARALLEL,
+ DM646X_PTSIMUX_PARALLEL,
+ DM646X_PTSOMUX_SERIAL,
+ DM646X_PTSIMUX_SERIAL,
+};
+
+enum davinci_dm355_index {
+ /* MMC/SD 0 */
+ DM355_MMCSD0,
+
+ /* MMC/SD 1 */
+ DM355_SD1_CLK,
+ DM355_SD1_CMD,
+ DM355_SD1_DATA3,
+ DM355_SD1_DATA2,
+ DM355_SD1_DATA1,
+ DM355_SD1_DATA0,
+
+ /* I2C */
+ DM355_I2C_SDA,
+ DM355_I2C_SCL,
+
+ /* ASP0 function */
+ DM355_MCBSP0_BDX,
+ DM355_MCBSP0_X,
+ DM355_MCBSP0_BFSX,
+ DM355_MCBSP0_BDR,
+ DM355_MCBSP0_R,
+ DM355_MCBSP0_BFSR,
+
+ /* SPI0 */
+ DM355_SPI0_SDI,
+ DM355_SPI0_SDENA0,
+ DM355_SPI0_SDENA1,
+
+ /* IRQ muxing */
+ DM355_INT_EDMA_CC,
+ DM355_INT_EDMA_TC0_ERR,
+ DM355_INT_EDMA_TC1_ERR,
+
+ /* EDMA event muxing */
+ DM355_EVT8_ASP1_TX,
+ DM355_EVT9_ASP1_RX,
+ DM355_EVT26_MMC0_RX,
+
+ /* Video Out */
+ DM355_VOUT_FIELD,
+ DM355_VOUT_FIELD_G70,
+ DM355_VOUT_HVSYNC,
+ DM355_VOUT_COUTL_EN,
+ DM355_VOUT_COUTH_EN,
+
+ /* Video In Pin Mux */
+ DM355_VIN_PCLK,
+ DM355_VIN_CAM_WEN,
+ DM355_VIN_CAM_VD,
+ DM355_VIN_CAM_HD,
+ DM355_VIN_YIN_EN,
+ DM355_VIN_CINL_EN,
+ DM355_VIN_CINH_EN,
+};
+
+enum davinci_dm365_index {
+ /* MMC/SD 0 */
+ DM365_MMCSD0,
+
+ /* MMC/SD 1 */
+ DM365_SD1_CLK,
+ DM365_SD1_CMD,
+ DM365_SD1_DATA3,
+ DM365_SD1_DATA2,
+ DM365_SD1_DATA1,
+ DM365_SD1_DATA0,
+
+ /* I2C */
+ DM365_I2C_SDA,
+ DM365_I2C_SCL,
+
+ /* AEMIF */
+ DM365_AEMIF_AR_A14,
+ DM365_AEMIF_AR_BA0,
+ DM365_AEMIF_A3,
+ DM365_AEMIF_A7,
+ DM365_AEMIF_D15_8,
+ DM365_AEMIF_CE0,
+ DM365_AEMIF_CE1,
+ DM365_AEMIF_WE_OE,
+
+ /* ASP0 function */
+ DM365_MCBSP0_BDX,
+ DM365_MCBSP0_X,
+ DM365_MCBSP0_BFSX,
+ DM365_MCBSP0_BDR,
+ DM365_MCBSP0_R,
+ DM365_MCBSP0_BFSR,
+
+ /* SPI0 */
+ DM365_SPI0_SCLK,
+ DM365_SPI0_SDI,
+ DM365_SPI0_SDO,
+ DM365_SPI0_SDENA0,
+ DM365_SPI0_SDENA1,
+
+ /* UART */
+ DM365_UART0_RXD,
+ DM365_UART0_TXD,
+ DM365_UART1_RXD,
+ DM365_UART1_TXD,
+ DM365_UART1_RTS,
+ DM365_UART1_CTS,
+
+ /* EMAC */
+ DM365_EMAC_TX_EN,
+ DM365_EMAC_TX_CLK,
+ DM365_EMAC_COL,
+ DM365_EMAC_TXD3,
+ DM365_EMAC_TXD2,
+ DM365_EMAC_TXD1,
+ DM365_EMAC_TXD0,
+ DM365_EMAC_RXD3,
+ DM365_EMAC_RXD2,
+ DM365_EMAC_RXD1,
+ DM365_EMAC_RXD0,
+ DM365_EMAC_RX_CLK,
+ DM365_EMAC_RX_DV,
+ DM365_EMAC_RX_ER,
+ DM365_EMAC_CRS,
+ DM365_EMAC_MDIO,
+ DM365_EMAC_MDCLK,
+
+ /* Key Scan */
+ DM365_KEYSCAN,
+
+ /* PWM */
+ DM365_PWM0,
+ DM365_PWM0_G23,
+ DM365_PWM1,
+ DM365_PWM1_G25,
+ DM365_PWM2_G87,
+ DM365_PWM2_G88,
+ DM365_PWM2_G89,
+ DM365_PWM2_G90,
+ DM365_PWM3_G80,
+ DM365_PWM3_G81,
+ DM365_PWM3_G85,
+ DM365_PWM3_G86,
+
+ /* SPI1 */
+ DM365_SPI1_SCLK,
+ DM365_SPI1_SDO,
+ DM365_SPI1_SDI,
+ DM365_SPI1_SDENA0,
+ DM365_SPI1_SDENA1,
+
+ /* SPI2 */
+ DM365_SPI2_SCLK,
+ DM365_SPI2_SDO,
+ DM365_SPI2_SDI,
+ DM365_SPI2_SDENA0,
+ DM365_SPI2_SDENA1,
+
+ /* SPI3 */
+ DM365_SPI3_SCLK,
+ DM365_SPI3_SDO,
+ DM365_SPI3_SDI,
+ DM365_SPI3_SDENA0,
+ DM365_SPI3_SDENA1,
+
+ /* SPI4 */
+ DM365_SPI4_SCLK,
+ DM365_SPI4_SDO,
+ DM365_SPI4_SDI,
+ DM365_SPI4_SDENA0,
+ DM365_SPI4_SDENA1,
+
+ /* Clock */
+ DM365_CLKOUT0,
+ DM365_CLKOUT1,
+ DM365_CLKOUT2,
+
+ /* GPIO */
+ DM365_GPIO20,
+ DM365_GPIO30,
+ DM365_GPIO31,
+ DM365_GPIO32,
+ DM365_GPIO33,
+ DM365_GPIO40,
+ DM365_GPIO64_57,
+
+ /* Video */
+ DM365_VOUT_FIELD,
+ DM365_VOUT_FIELD_G81,
+ DM365_VOUT_HVSYNC,
+ DM365_VOUT_COUTL_EN,
+ DM365_VOUT_COUTH_EN,
+ DM365_VIN_CAM_WEN,
+ DM365_VIN_CAM_VD,
+ DM365_VIN_CAM_HD,
+ DM365_VIN_YIN4_7_EN,
+ DM365_VIN_YIN0_3_EN,
+
+ /* IRQ muxing */
+ DM365_INT_EDMA_CC,
+ DM365_INT_EDMA_TC0_ERR,
+ DM365_INT_EDMA_TC1_ERR,
+ DM365_INT_EDMA_TC2_ERR,
+ DM365_INT_EDMA_TC3_ERR,
+ DM365_INT_PRTCSS,
+ DM365_INT_EMAC_RXTHRESH,
+ DM365_INT_EMAC_RXPULSE,
+ DM365_INT_EMAC_TXPULSE,
+ DM365_INT_EMAC_MISCPULSE,
+ DM365_INT_IMX0_ENABLE,
+ DM365_INT_IMX0_DISABLE,
+ DM365_INT_HDVICP_ENABLE,
+ DM365_INT_HDVICP_DISABLE,
+ DM365_INT_IMX1_ENABLE,
+ DM365_INT_IMX1_DISABLE,
+ DM365_INT_NSF_ENABLE,
+ DM365_INT_NSF_DISABLE,
+
+ /* EDMA event muxing */
+ DM365_EVT2_ASP_TX,
+ DM365_EVT3_ASP_RX,
+ DM365_EVT2_VC_TX,
+ DM365_EVT3_VC_RX,
+ DM365_EVT26_MMC0_RX,
+};
+
+enum da830_index {
+ DA830_GPIO7_14,
+ DA830_RTCK,
+ DA830_GPIO7_15,
+ DA830_EMU_0,
+ DA830_EMB_SDCKE,
+ DA830_EMB_CLK_GLUE,
+ DA830_EMB_CLK,
+ DA830_NEMB_CS_0,
+ DA830_NEMB_CAS,
+ DA830_NEMB_RAS,
+ DA830_NEMB_WE,
+ DA830_EMB_BA_1,
+ DA830_EMB_BA_0,
+ DA830_EMB_A_0,
+ DA830_EMB_A_1,
+ DA830_EMB_A_2,
+ DA830_EMB_A_3,
+ DA830_EMB_A_4,
+ DA830_EMB_A_5,
+ DA830_GPIO7_0,
+ DA830_GPIO7_1,
+ DA830_GPIO7_2,
+ DA830_GPIO7_3,
+ DA830_GPIO7_4,
+ DA830_GPIO7_5,
+ DA830_GPIO7_6,
+ DA830_GPIO7_7,
+ DA830_EMB_A_6,
+ DA830_EMB_A_7,
+ DA830_EMB_A_8,
+ DA830_EMB_A_9,
+ DA830_EMB_A_10,
+ DA830_EMB_A_11,
+ DA830_EMB_A_12,
+ DA830_EMB_D_31,
+ DA830_GPIO7_8,
+ DA830_GPIO7_9,
+ DA830_GPIO7_10,
+ DA830_GPIO7_11,
+ DA830_GPIO7_12,
+ DA830_GPIO7_13,
+ DA830_GPIO3_13,
+ DA830_EMB_D_30,
+ DA830_EMB_D_29,
+ DA830_EMB_D_28,
+ DA830_EMB_D_27,
+ DA830_EMB_D_26,
+ DA830_EMB_D_25,
+ DA830_EMB_D_24,
+ DA830_EMB_D_23,
+ DA830_EMB_D_22,
+ DA830_EMB_D_21,
+ DA830_EMB_D_20,
+ DA830_EMB_D_19,
+ DA830_EMB_D_18,
+ DA830_EMB_D_17,
+ DA830_EMB_D_16,
+ DA830_NEMB_WE_DQM_3,
+ DA830_NEMB_WE_DQM_2,
+ DA830_EMB_D_0,
+ DA830_EMB_D_1,
+ DA830_EMB_D_2,
+ DA830_EMB_D_3,
+ DA830_EMB_D_4,
+ DA830_EMB_D_5,
+ DA830_EMB_D_6,
+ DA830_GPIO6_0,
+ DA830_GPIO6_1,
+ DA830_GPIO6_2,
+ DA830_GPIO6_3,
+ DA830_GPIO6_4,
+ DA830_GPIO6_5,
+ DA830_GPIO6_6,
+ DA830_EMB_D_7,
+ DA830_EMB_D_8,
+ DA830_EMB_D_9,
+ DA830_EMB_D_10,
+ DA830_EMB_D_11,
+ DA830_EMB_D_12,
+ DA830_EMB_D_13,
+ DA830_EMB_D_14,
+ DA830_GPIO6_7,
+ DA830_GPIO6_8,
+ DA830_GPIO6_9,
+ DA830_GPIO6_10,
+ DA830_GPIO6_11,
+ DA830_GPIO6_12,
+ DA830_GPIO6_13,
+ DA830_GPIO6_14,
+ DA830_EMB_D_15,
+ DA830_NEMB_WE_DQM_1,
+ DA830_NEMB_WE_DQM_0,
+ DA830_SPI0_SOMI_0,
+ DA830_SPI0_SIMO_0,
+ DA830_SPI0_CLK,
+ DA830_NSPI0_ENA,
+ DA830_NSPI0_SCS_0,
+ DA830_EQEP0I,
+ DA830_EQEP0S,
+ DA830_EQEP1I,
+ DA830_NUART0_CTS,
+ DA830_NUART0_RTS,
+ DA830_EQEP0A,
+ DA830_EQEP0B,
+ DA830_GPIO6_15,
+ DA830_GPIO5_14,
+ DA830_GPIO5_15,
+ DA830_GPIO5_0,
+ DA830_GPIO5_1,
+ DA830_GPIO5_2,
+ DA830_GPIO5_3,
+ DA830_GPIO5_4,
+ DA830_SPI1_SOMI_0,
+ DA830_SPI1_SIMO_0,
+ DA830_SPI1_CLK,
+ DA830_UART0_RXD,
+ DA830_UART0_TXD,
+ DA830_AXR1_10,
+ DA830_AXR1_11,
+ DA830_NSPI1_ENA,
+ DA830_I2C1_SCL,
+ DA830_I2C1_SDA,
+ DA830_EQEP1S,
+ DA830_I2C0_SDA,
+ DA830_I2C0_SCL,
+ DA830_UART2_RXD,
+ DA830_TM64P0_IN12,
+ DA830_TM64P0_OUT12,
+ DA830_GPIO5_5,
+ DA830_GPIO5_6,
+ DA830_GPIO5_7,
+ DA830_GPIO5_8,
+ DA830_GPIO5_9,
+ DA830_GPIO5_10,
+ DA830_GPIO5_11,
+ DA830_GPIO5_12,
+ DA830_NSPI1_SCS_0,
+ DA830_USB0_DRVVBUS,
+ DA830_AHCLKX0,
+ DA830_ACLKX0,
+ DA830_AFSX0,
+ DA830_AHCLKR0,
+ DA830_ACLKR0,
+ DA830_AFSR0,
+ DA830_UART2_TXD,
+ DA830_AHCLKX2,
+ DA830_ECAP0_APWM0,
+ DA830_RMII_MHZ_50_CLK,
+ DA830_ECAP1_APWM1,
+ DA830_USB_REFCLKIN,
+ DA830_GPIO5_13,
+ DA830_GPIO4_15,
+ DA830_GPIO2_11,
+ DA830_GPIO2_12,
+ DA830_GPIO2_13,
+ DA830_GPIO2_14,
+ DA830_GPIO2_15,
+ DA830_GPIO3_12,
+ DA830_AMUTE0,
+ DA830_AXR0_0,
+ DA830_AXR0_1,
+ DA830_AXR0_2,
+ DA830_AXR0_3,
+ DA830_AXR0_4,
+ DA830_AXR0_5,
+ DA830_AXR0_6,
+ DA830_RMII_TXD_0,
+ DA830_RMII_TXD_1,
+ DA830_RMII_TXEN,
+ DA830_RMII_CRS_DV,
+ DA830_RMII_RXD_0,
+ DA830_RMII_RXD_1,
+ DA830_RMII_RXER,
+ DA830_AFSR2,
+ DA830_ACLKX2,
+ DA830_AXR2_3,
+ DA830_AXR2_2,
+ DA830_AXR2_1,
+ DA830_AFSX2,
+ DA830_ACLKR2,
+ DA830_NRESETOUT,
+ DA830_GPIO3_0,
+ DA830_GPIO3_1,
+ DA830_GPIO3_2,
+ DA830_GPIO3_3,
+ DA830_GPIO3_4,
+ DA830_GPIO3_5,
+ DA830_GPIO3_6,
+ DA830_AXR0_7,
+ DA830_AXR0_8,
+ DA830_UART1_RXD,
+ DA830_UART1_TXD,
+ DA830_AXR0_11,
+ DA830_AHCLKX1,
+ DA830_ACLKX1,
+ DA830_AFSX1,
+ DA830_MDIO_CLK,
+ DA830_MDIO_D,
+ DA830_AXR0_9,
+ DA830_AXR0_10,
+ DA830_EPWM0B,
+ DA830_EPWM0A,
+ DA830_EPWMSYNCI,
+ DA830_AXR2_0,
+ DA830_EPWMSYNC0,
+ DA830_GPIO3_7,
+ DA830_GPIO3_8,
+ DA830_GPIO3_9,
+ DA830_GPIO3_10,
+ DA830_GPIO3_11,
+ DA830_GPIO3_14,
+ DA830_GPIO3_15,
+ DA830_GPIO4_10,
+ DA830_AHCLKR1,
+ DA830_ACLKR1,
+ DA830_AFSR1,
+ DA830_AMUTE1,
+ DA830_AXR1_0,
+ DA830_AXR1_1,
+ DA830_AXR1_2,
+ DA830_AXR1_3,
+ DA830_ECAP2_APWM2,
+ DA830_EHRPWMGLUETZ,
+ DA830_EQEP1A,
+ DA830_GPIO4_11,
+ DA830_GPIO4_12,
+ DA830_GPIO4_13,
+ DA830_GPIO4_14,
+ DA830_GPIO4_0,
+ DA830_GPIO4_1,
+ DA830_GPIO4_2,
+ DA830_GPIO4_3,
+ DA830_AXR1_4,
+ DA830_AXR1_5,
+ DA830_AXR1_6,
+ DA830_AXR1_7,
+ DA830_AXR1_8,
+ DA830_AXR1_9,
+ DA830_EMA_D_0,
+ DA830_EMA_D_1,
+ DA830_EQEP1B,
+ DA830_EPWM2B,
+ DA830_EPWM2A,
+ DA830_EPWM1B,
+ DA830_EPWM1A,
+ DA830_MMCSD_DAT_0,
+ DA830_MMCSD_DAT_1,
+ DA830_UHPI_HD_0,
+ DA830_UHPI_HD_1,
+ DA830_GPIO4_4,
+ DA830_GPIO4_5,
+ DA830_GPIO4_6,
+ DA830_GPIO4_7,
+ DA830_GPIO4_8,
+ DA830_GPIO4_9,
+ DA830_GPIO0_0,
+ DA830_GPIO0_1,
+ DA830_EMA_D_2,
+ DA830_EMA_D_3,
+ DA830_EMA_D_4,
+ DA830_EMA_D_5,
+ DA830_EMA_D_6,
+ DA830_EMA_D_7,
+ DA830_EMA_D_8,
+ DA830_EMA_D_9,
+ DA830_MMCSD_DAT_2,
+ DA830_MMCSD_DAT_3,
+ DA830_MMCSD_DAT_4,
+ DA830_MMCSD_DAT_5,
+ DA830_MMCSD_DAT_6,
+ DA830_MMCSD_DAT_7,
+ DA830_UHPI_HD_8,
+ DA830_UHPI_HD_9,
+ DA830_UHPI_HD_2,
+ DA830_UHPI_HD_3,
+ DA830_UHPI_HD_4,
+ DA830_UHPI_HD_5,
+ DA830_UHPI_HD_6,
+ DA830_UHPI_HD_7,
+ DA830_LCD_D_8,
+ DA830_LCD_D_9,
+ DA830_GPIO0_2,
+ DA830_GPIO0_3,
+ DA830_GPIO0_4,
+ DA830_GPIO0_5,
+ DA830_GPIO0_6,
+ DA830_GPIO0_7,
+ DA830_GPIO0_8,
+ DA830_GPIO0_9,
+ DA830_EMA_D_10,
+ DA830_EMA_D_11,
+ DA830_EMA_D_12,
+ DA830_EMA_D_13,
+ DA830_EMA_D_14,
+ DA830_EMA_D_15,
+ DA830_EMA_A_0,
+ DA830_EMA_A_1,
+ DA830_UHPI_HD_10,
+ DA830_UHPI_HD_11,
+ DA830_UHPI_HD_12,
+ DA830_UHPI_HD_13,
+ DA830_UHPI_HD_14,
+ DA830_UHPI_HD_15,
+ DA830_LCD_D_7,
+ DA830_MMCSD_CLK,
+ DA830_LCD_D_10,
+ DA830_LCD_D_11,
+ DA830_LCD_D_12,
+ DA830_LCD_D_13,
+ DA830_LCD_D_14,
+ DA830_LCD_D_15,
+ DA830_UHPI_HCNTL0,
+ DA830_GPIO0_10,
+ DA830_GPIO0_11,
+ DA830_GPIO0_12,
+ DA830_GPIO0_13,
+ DA830_GPIO0_14,
+ DA830_GPIO0_15,
+ DA830_GPIO1_0,
+ DA830_GPIO1_1,
+ DA830_EMA_A_2,
+ DA830_EMA_A_3,
+ DA830_EMA_A_4,
+ DA830_EMA_A_5,
+ DA830_EMA_A_6,
+ DA830_EMA_A_7,
+ DA830_EMA_A_8,
+ DA830_EMA_A_9,
+ DA830_MMCSD_CMD,
+ DA830_LCD_D_6,
+ DA830_LCD_D_3,
+ DA830_LCD_D_2,
+ DA830_LCD_D_1,
+ DA830_LCD_D_0,
+ DA830_LCD_PCLK,
+ DA830_LCD_HSYNC,
+ DA830_UHPI_HCNTL1,
+ DA830_GPIO1_2,
+ DA830_GPIO1_3,
+ DA830_GPIO1_4,
+ DA830_GPIO1_5,
+ DA830_GPIO1_6,
+ DA830_GPIO1_7,
+ DA830_GPIO1_8,
+ DA830_GPIO1_9,
+ DA830_EMA_A_10,
+ DA830_EMA_A_11,
+ DA830_EMA_A_12,
+ DA830_EMA_BA_1,
+ DA830_EMA_BA_0,
+ DA830_EMA_CLK,
+ DA830_EMA_SDCKE,
+ DA830_NEMA_CAS,
+ DA830_LCD_VSYNC,
+ DA830_NLCD_AC_ENB_CS,
+ DA830_LCD_MCLK,
+ DA830_LCD_D_5,
+ DA830_LCD_D_4,
+ DA830_OBSCLK,
+ DA830_NEMA_CS_4,
+ DA830_UHPI_HHWIL,
+ DA830_AHCLKR2,
+ DA830_GPIO1_10,
+ DA830_GPIO1_11,
+ DA830_GPIO1_12,
+ DA830_GPIO1_13,
+ DA830_GPIO1_14,
+ DA830_GPIO1_15,
+ DA830_GPIO2_0,
+ DA830_GPIO2_1,
+ DA830_NEMA_RAS,
+ DA830_NEMA_WE,
+ DA830_NEMA_CS_0,
+ DA830_NEMA_CS_2,
+ DA830_NEMA_CS_3,
+ DA830_NEMA_OE,
+ DA830_NEMA_WE_DQM_1,
+ DA830_NEMA_WE_DQM_0,
+ DA830_NEMA_CS_5,
+ DA830_UHPI_HRNW,
+ DA830_NUHPI_HAS,
+ DA830_NUHPI_HCS,
+ DA830_NUHPI_HDS1,
+ DA830_NUHPI_HDS2,
+ DA830_NUHPI_HINT,
+ DA830_AXR0_12,
+ DA830_AMUTE2,
+ DA830_AXR0_13,
+ DA830_AXR0_14,
+ DA830_AXR0_15,
+ DA830_GPIO2_2,
+ DA830_GPIO2_3,
+ DA830_GPIO2_4,
+ DA830_GPIO2_5,
+ DA830_GPIO2_6,
+ DA830_GPIO2_7,
+ DA830_GPIO2_8,
+ DA830_GPIO2_9,
+ DA830_EMA_WAIT_0,
+ DA830_NUHPI_HRDY,
+ DA830_GPIO2_10,
+};
+
+enum davinci_da850_index {
+ /* UART0 function */
+ DA850_NUART0_CTS,
+ DA850_NUART0_RTS,
+ DA850_UART0_RXD,
+ DA850_UART0_TXD,
+
+ /* UART1 function */
+ DA850_NUART1_CTS,
+ DA850_NUART1_RTS,
+ DA850_UART1_RXD,
+ DA850_UART1_TXD,
+
+ /* UART2 function */
+ DA850_NUART2_CTS,
+ DA850_NUART2_RTS,
+ DA850_UART2_RXD,
+ DA850_UART2_TXD,
+
+ /* I2C1 function */
+ DA850_I2C1_SCL,
+ DA850_I2C1_SDA,
+
+ /* I2C0 function */
+ DA850_I2C0_SDA,
+ DA850_I2C0_SCL,
+
+ /* EMAC function */
+ DA850_MII_TXEN,
+ DA850_MII_TXCLK,
+ DA850_MII_COL,
+ DA850_MII_TXD_3,
+ DA850_MII_TXD_2,
+ DA850_MII_TXD_1,
+ DA850_MII_TXD_0,
+ DA850_MII_RXER,
+ DA850_MII_CRS,
+ DA850_MII_RXCLK,
+ DA850_MII_RXDV,
+ DA850_MII_RXD_3,
+ DA850_MII_RXD_2,
+ DA850_MII_RXD_1,
+ DA850_MII_RXD_0,
+ DA850_MDIO_CLK,
+ DA850_MDIO_D,
+ DA850_RMII_TXD_0,
+ DA850_RMII_TXD_1,
+ DA850_RMII_TXEN,
+ DA850_RMII_CRS_DV,
+ DA850_RMII_RXD_0,
+ DA850_RMII_RXD_1,
+ DA850_RMII_RXER,
+ DA850_RMII_MHZ_50_CLK,
+
+ /* McASP function */
+ DA850_ACLKR,
+ DA850_ACLKX,
+ DA850_AFSR,
+ DA850_AFSX,
+ DA850_AHCLKR,
+ DA850_AHCLKX,
+ DA850_AMUTE,
+ DA850_AXR_15,
+ DA850_AXR_14,
+ DA850_AXR_13,
+ DA850_AXR_12,
+ DA850_AXR_11,
+ DA850_AXR_10,
+ DA850_AXR_9,
+ DA850_AXR_8,
+ DA850_AXR_7,
+ DA850_AXR_6,
+ DA850_AXR_5,
+ DA850_AXR_4,
+ DA850_AXR_3,
+ DA850_AXR_2,
+ DA850_AXR_1,
+ DA850_AXR_0,
+
+ /* LCD function */
+ DA850_LCD_D_7,
+ DA850_LCD_D_6,
+ DA850_LCD_D_5,
+ DA850_LCD_D_4,
+ DA850_LCD_D_3,
+ DA850_LCD_D_2,
+ DA850_LCD_D_1,
+ DA850_LCD_D_0,
+ DA850_LCD_D_15,
+ DA850_LCD_D_14,
+ DA850_LCD_D_13,
+ DA850_LCD_D_12,
+ DA850_LCD_D_11,
+ DA850_LCD_D_10,
+ DA850_LCD_D_9,
+ DA850_LCD_D_8,
+ DA850_LCD_PCLK,
+ DA850_LCD_HSYNC,
+ DA850_LCD_VSYNC,
+ DA850_NLCD_AC_ENB_CS,
+
+ /* MMC/SD0 function */
+ DA850_MMCSD0_DAT_0,
+ DA850_MMCSD0_DAT_1,
+ DA850_MMCSD0_DAT_2,
+ DA850_MMCSD0_DAT_3,
+ DA850_MMCSD0_CLK,
+ DA850_MMCSD0_CMD,
+
+ /* EMIF2.5/EMIFA function */
+ DA850_EMA_D_7,
+ DA850_EMA_D_6,
+ DA850_EMA_D_5,
+ DA850_EMA_D_4,
+ DA850_EMA_D_3,
+ DA850_EMA_D_2,
+ DA850_EMA_D_1,
+ DA850_EMA_D_0,
+ DA850_EMA_A_1,
+ DA850_EMA_A_2,
+ DA850_NEMA_CS_3,
+ DA850_NEMA_CS_4,
+ DA850_NEMA_WE,
+ DA850_NEMA_OE,
+ DA850_EMA_D_15,
+ DA850_EMA_D_14,
+ DA850_EMA_D_13,
+ DA850_EMA_D_12,
+ DA850_EMA_D_11,
+ DA850_EMA_D_10,
+ DA850_EMA_D_9,
+ DA850_EMA_D_8,
+ DA850_EMA_A_0,
+ DA850_EMA_A_3,
+ DA850_EMA_A_4,
+ DA850_EMA_A_5,
+ DA850_EMA_A_6,
+ DA850_EMA_A_7,
+ DA850_EMA_A_8,
+ DA850_EMA_A_9,
+ DA850_EMA_A_10,
+ DA850_EMA_A_11,
+ DA850_EMA_A_12,
+ DA850_EMA_A_13,
+ DA850_EMA_A_14,
+ DA850_EMA_A_15,
+ DA850_EMA_A_16,
+ DA850_EMA_A_17,
+ DA850_EMA_A_18,
+ DA850_EMA_A_19,
+ DA850_EMA_A_20,
+ DA850_EMA_A_21,
+ DA850_EMA_A_22,
+ DA850_EMA_A_23,
+ DA850_EMA_BA_1,
+ DA850_EMA_CLK,
+ DA850_EMA_WAIT_1,
+ DA850_NEMA_CS_2,
+
+ /* GPIO function */
+ DA850_GPIO2_4,
+ DA850_GPIO2_6,
+ DA850_GPIO2_8,
+ DA850_GPIO2_15,
+ DA850_GPIO3_12,
+ DA850_GPIO3_13,
+ DA850_GPIO4_0,
+ DA850_GPIO4_1,
+ DA850_GPIO6_13,
+ DA850_RTC_ALARM,
+};
+
+enum davinci_tnetv107x_index {
+ TNETV107X_ASR_A00,
+ TNETV107X_GPIO32,
+ TNETV107X_ASR_A01,
+ TNETV107X_GPIO33,
+ TNETV107X_ASR_A02,
+ TNETV107X_GPIO34,
+ TNETV107X_ASR_A03,
+ TNETV107X_GPIO35,
+ TNETV107X_ASR_A04,
+ TNETV107X_GPIO36,
+ TNETV107X_ASR_A05,
+ TNETV107X_GPIO37,
+ TNETV107X_ASR_A06,
+ TNETV107X_GPIO38,
+ TNETV107X_ASR_A07,
+ TNETV107X_GPIO39,
+ TNETV107X_ASR_A08,
+ TNETV107X_GPIO40,
+ TNETV107X_ASR_A09,
+ TNETV107X_GPIO41,
+ TNETV107X_ASR_A10,
+ TNETV107X_GPIO42,
+ TNETV107X_ASR_A11,
+ TNETV107X_BOOT_STRP_0,
+ TNETV107X_ASR_A12,
+ TNETV107X_BOOT_STRP_1,
+ TNETV107X_ASR_A13,
+ TNETV107X_GPIO43,
+ TNETV107X_ASR_A14,
+ TNETV107X_GPIO44,
+ TNETV107X_ASR_A15,
+ TNETV107X_GPIO45,
+ TNETV107X_ASR_A16,
+ TNETV107X_GPIO46,
+ TNETV107X_ASR_A17,
+ TNETV107X_GPIO47,
+ TNETV107X_ASR_A18,
+ TNETV107X_GPIO48,
+ TNETV107X_SDIO1_DATA3_0,
+ TNETV107X_ASR_A19,
+ TNETV107X_GPIO49,
+ TNETV107X_SDIO1_DATA2_0,
+ TNETV107X_ASR_A20,
+ TNETV107X_GPIO50,
+ TNETV107X_SDIO1_DATA1_0,
+ TNETV107X_ASR_A21,
+ TNETV107X_GPIO51,
+ TNETV107X_SDIO1_DATA0_0,
+ TNETV107X_ASR_A22,
+ TNETV107X_GPIO52,
+ TNETV107X_SDIO1_CMD_0,
+ TNETV107X_ASR_A23,
+ TNETV107X_GPIO53,
+ TNETV107X_SDIO1_CLK_0,
+ TNETV107X_ASR_BA_1,
+ TNETV107X_GPIO54,
+ TNETV107X_SYS_PLL_CLK,
+ TNETV107X_ASR_CS0,
+ TNETV107X_ASR_CS1,
+ TNETV107X_ASR_CS2,
+ TNETV107X_TDM_PLL_CLK,
+ TNETV107X_ASR_CS3,
+ TNETV107X_ETH_PHY_CLK,
+ TNETV107X_ASR_D00,
+ TNETV107X_GPIO55,
+ TNETV107X_ASR_D01,
+ TNETV107X_GPIO56,
+ TNETV107X_ASR_D02,
+ TNETV107X_GPIO57,
+ TNETV107X_ASR_D03,
+ TNETV107X_GPIO58,
+ TNETV107X_ASR_D04,
+ TNETV107X_GPIO59_0,
+ TNETV107X_ASR_D05,
+ TNETV107X_GPIO60_0,
+ TNETV107X_ASR_D06,
+ TNETV107X_GPIO61_0,
+ TNETV107X_ASR_D07,
+ TNETV107X_GPIO62_0,
+ TNETV107X_ASR_D08,
+ TNETV107X_GPIO63_0,
+ TNETV107X_ASR_D09,
+ TNETV107X_GPIO64_0,
+ TNETV107X_ASR_D10,
+ TNETV107X_SDIO1_DATA3_1,
+ TNETV107X_ASR_D11,
+ TNETV107X_SDIO1_DATA2_1,
+ TNETV107X_ASR_D12,
+ TNETV107X_SDIO1_DATA1_1,
+ TNETV107X_ASR_D13,
+ TNETV107X_SDIO1_DATA0_1,
+ TNETV107X_ASR_D14,
+ TNETV107X_SDIO1_CMD_1,
+ TNETV107X_ASR_D15,
+ TNETV107X_SDIO1_CLK_1,
+ TNETV107X_ASR_OE,
+ TNETV107X_BOOT_STRP_2,
+ TNETV107X_ASR_RNW,
+ TNETV107X_GPIO29_0,
+ TNETV107X_ASR_WAIT,
+ TNETV107X_GPIO30_0,
+ TNETV107X_ASR_WE,
+ TNETV107X_BOOT_STRP_3,
+ TNETV107X_ASR_WE_DQM0,
+ TNETV107X_GPIO31,
+ TNETV107X_LCD_PD17_0,
+ TNETV107X_ASR_WE_DQM1,
+ TNETV107X_ASR_BA0_0,
+ TNETV107X_VLYNQ_CLK,
+ TNETV107X_GPIO14,
+ TNETV107X_LCD_PD19_0,
+ TNETV107X_VLYNQ_RXD0,
+ TNETV107X_GPIO15,
+ TNETV107X_LCD_PD20_0,
+ TNETV107X_VLYNQ_RXD1,
+ TNETV107X_GPIO16,
+ TNETV107X_LCD_PD21_0,
+ TNETV107X_VLYNQ_TXD0,
+ TNETV107X_GPIO17,
+ TNETV107X_LCD_PD22_0,
+ TNETV107X_VLYNQ_TXD1,
+ TNETV107X_GPIO18,
+ TNETV107X_LCD_PD23_0,
+ TNETV107X_SDIO0_CLK,
+ TNETV107X_GPIO19,
+ TNETV107X_SDIO0_CMD,
+ TNETV107X_GPIO20,
+ TNETV107X_SDIO0_DATA0,
+ TNETV107X_GPIO21,
+ TNETV107X_SDIO0_DATA1,
+ TNETV107X_GPIO22,
+ TNETV107X_SDIO0_DATA2,
+ TNETV107X_GPIO23,
+ TNETV107X_SDIO0_DATA3,
+ TNETV107X_GPIO24,
+ TNETV107X_EMU0,
+ TNETV107X_EMU1,
+ TNETV107X_RTCK,
+ TNETV107X_TRST_N,
+ TNETV107X_TCK,
+ TNETV107X_TDI,
+ TNETV107X_TDO,
+ TNETV107X_TMS,
+ TNETV107X_TDM1_CLK,
+ TNETV107X_TDM1_RX,
+ TNETV107X_TDM1_TX,
+ TNETV107X_TDM1_FS,
+ TNETV107X_KEYPAD_R0,
+ TNETV107X_KEYPAD_R1,
+ TNETV107X_KEYPAD_R2,
+ TNETV107X_KEYPAD_R3,
+ TNETV107X_KEYPAD_R4,
+ TNETV107X_KEYPAD_R5,
+ TNETV107X_KEYPAD_R6,
+ TNETV107X_GPIO12,
+ TNETV107X_KEYPAD_R7,
+ TNETV107X_GPIO10,
+ TNETV107X_KEYPAD_C0,
+ TNETV107X_KEYPAD_C1,
+ TNETV107X_KEYPAD_C2,
+ TNETV107X_KEYPAD_C3,
+ TNETV107X_KEYPAD_C4,
+ TNETV107X_KEYPAD_C5,
+ TNETV107X_KEYPAD_C6,
+ TNETV107X_GPIO13,
+ TNETV107X_TEST_CLK_IN,
+ TNETV107X_KEYPAD_C7,
+ TNETV107X_GPIO11,
+ TNETV107X_SSP0_0,
+ TNETV107X_SCC_DCLK,
+ TNETV107X_LCD_PD20_1,
+ TNETV107X_SSP0_1,
+ TNETV107X_SCC_CS_N,
+ TNETV107X_LCD_PD21_1,
+ TNETV107X_SSP0_2,
+ TNETV107X_SCC_D,
+ TNETV107X_LCD_PD22_1,
+ TNETV107X_SSP0_3,
+ TNETV107X_SCC_RESETN,
+ TNETV107X_LCD_PD23_1,
+ TNETV107X_SSP1_0,
+ TNETV107X_GPIO25,
+ TNETV107X_UART2_CTS,
+ TNETV107X_SSP1_1,
+ TNETV107X_GPIO26,
+ TNETV107X_UART2_RD,
+ TNETV107X_SSP1_2,
+ TNETV107X_GPIO27,
+ TNETV107X_UART2_RTS,
+ TNETV107X_SSP1_3,
+ TNETV107X_GPIO28,
+ TNETV107X_UART2_TD,
+ TNETV107X_UART0_CTS,
+ TNETV107X_UART0_RD,
+ TNETV107X_UART0_RTS,
+ TNETV107X_UART0_TD,
+ TNETV107X_UART1_RD,
+ TNETV107X_UART1_TD,
+ TNETV107X_LCD_AC_NCS,
+ TNETV107X_LCD_HSYNC_RNW,
+ TNETV107X_LCD_VSYNC_A0,
+ TNETV107X_LCD_MCLK,
+ TNETV107X_LCD_PD16_0,
+ TNETV107X_LCD_PCLK_E,
+ TNETV107X_LCD_PD00,
+ TNETV107X_LCD_PD01,
+ TNETV107X_LCD_PD02,
+ TNETV107X_LCD_PD03,
+ TNETV107X_LCD_PD04,
+ TNETV107X_LCD_PD05,
+ TNETV107X_LCD_PD06,
+ TNETV107X_LCD_PD07,
+ TNETV107X_LCD_PD08,
+ TNETV107X_GPIO59_1,
+ TNETV107X_LCD_PD09,
+ TNETV107X_GPIO60_1,
+ TNETV107X_LCD_PD10,
+ TNETV107X_ASR_BA0_1,
+ TNETV107X_GPIO61_1,
+ TNETV107X_LCD_PD11,
+ TNETV107X_GPIO62_1,
+ TNETV107X_LCD_PD12,
+ TNETV107X_GPIO63_1,
+ TNETV107X_LCD_PD13,
+ TNETV107X_GPIO64_1,
+ TNETV107X_LCD_PD14,
+ TNETV107X_GPIO29_1,
+ TNETV107X_LCD_PD15,
+ TNETV107X_GPIO30_1,
+ TNETV107X_EINT0,
+ TNETV107X_GPIO08,
+ TNETV107X_EINT1,
+ TNETV107X_GPIO09,
+ TNETV107X_GPIO00,
+ TNETV107X_LCD_PD20_2,
+ TNETV107X_TDM_CLK_IN_2,
+ TNETV107X_GPIO01,
+ TNETV107X_LCD_PD21_2,
+ TNETV107X_24M_CLK_OUT_1,
+ TNETV107X_GPIO02,
+ TNETV107X_LCD_PD22_2,
+ TNETV107X_GPIO03,
+ TNETV107X_LCD_PD23_2,
+ TNETV107X_GPIO04,
+ TNETV107X_LCD_PD16_1,
+ TNETV107X_USB0_RXERR,
+ TNETV107X_GPIO05,
+ TNETV107X_LCD_PD17_1,
+ TNETV107X_TDM_CLK_IN_1,
+ TNETV107X_GPIO06,
+ TNETV107X_LCD_PD18,
+ TNETV107X_24M_CLK_OUT_2,
+ TNETV107X_GPIO07,
+ TNETV107X_LCD_PD19_1,
+ TNETV107X_USB1_RXERR,
+ TNETV107X_ETH_PLL_CLK,
+ TNETV107X_MDIO,
+ TNETV107X_MDC,
+ TNETV107X_AIC_MUTE_STAT_N,
+ TNETV107X_TDM0_CLK,
+ TNETV107X_AIC_HNS_EN_N,
+ TNETV107X_TDM0_FS,
+ TNETV107X_AIC_HDS_EN_STAT_N,
+ TNETV107X_TDM0_TX,
+ TNETV107X_AIC_HNF_EN_STAT_N,
+ TNETV107X_TDM0_RX,
+};
+
+#define PINMUX(x) (4 * (x))
+
+#ifdef CONFIG_DAVINCI_MUX
+/* setup pin muxing */
+extern int davinci_cfg_reg(unsigned long reg_cfg);
+extern int davinci_cfg_reg_list(const short pins[]);
+#else
+/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
+static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
+static inline int davinci_cfg_reg_list(const short pins[])
+{
+ return 0;
+}
+#endif
+
+#endif /* __INC_MACH_MUX_H */
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
new file mode 100644
index 00000000..02515104
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -0,0 +1,88 @@
+/*
+ * mach-davinci/nand.h
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Ported to 2.6.23 Copyright © 2008 by
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * --------------------------------------------------------------------------
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_NAND_H
+#define __ARCH_ARM_DAVINCI_NAND_H
+
+#include <linux/mtd/nand.h>
+
+#define NANDFCR_OFFSET 0x60
+#define NANDFSR_OFFSET 0x64
+#define NANDF1ECC_OFFSET 0x70
+
+/* 4-bit ECC syndrome registers */
+#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
+#define NAND_4BIT_ECC1_OFFSET 0xc0
+#define NAND_4BIT_ECC2_OFFSET 0xc4
+#define NAND_4BIT_ECC3_OFFSET 0xc8
+#define NAND_4BIT_ECC4_OFFSET 0xcc
+#define NAND_ERR_ADD1_OFFSET 0xd0
+#define NAND_ERR_ADD2_OFFSET 0xd4
+#define NAND_ERR_ERRVAL1_OFFSET 0xd8
+#define NAND_ERR_ERRVAL2_OFFSET 0xdc
+
+/* NOTE: boards don't need to use these address bits
+ * for ALE/CLE unless they support booting from NAND.
+ * They're used unless platform data overrides them.
+ */
+#define MASK_ALE 0x08
+#define MASK_CLE 0x10
+
+struct davinci_nand_pdata { /* platform_data */
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ /* for packages using two chipselects */
+ uint32_t mask_chipsel;
+
+ /* board's default static partition info */
+ struct mtd_partition *parts;
+ unsigned nr_parts;
+
+ /* none == NAND_ECC_NONE (strongly *not* advised!!)
+ * soft == NAND_ECC_SOFT
+ * else == NAND_ECC_HW, according to ecc_bits
+ *
+ * All DaVinci-family chips support 1-bit hardware ECC.
+ * Newer ones also support 4-bit ECC, but are awkward
+ * using it with large page chips.
+ */
+ nand_ecc_modes_t ecc_mode;
+ u8 ecc_bits;
+
+ /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
+ unsigned options;
+
+ /* Main and mirror bbt descriptor overrides */
+ struct nand_bbt_descr *bbt_td;
+ struct nand_bbt_descr *bbt_md;
+
+ /* Access timings */
+ struct davinci_aemif_timing *timing;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-davinci/include/mach/pm.h b/arch/arm/mach-davinci/include/mach/pm.h
new file mode 100644
index 00000000..37b19bf3
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/pm.h
@@ -0,0 +1,54 @@
+/*
+ * TI DaVinci platform support for power management.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 _MACH_DAVINCI_PM_H
+#define _MACH_DAVINCI_PM_H
+
+/*
+ * Caution: Assembly code in sleep.S makes assumtion on the order
+ * of the members of this structure.
+ */
+struct davinci_pm_config {
+ void __iomem *ddr2_ctlr_base;
+ void __iomem *ddrpsc_reg_base;
+ int ddrpsc_num;
+ void __iomem *ddrpll_reg_base;
+ void __iomem *deepsleep_reg;
+ void __iomem *cpupll_reg_base;
+ /*
+ * Note on SLEEPCOUNT:
+ * The SLEEPCOUNT feature is mainly intended for cases in which
+ * the internal oscillator is used. The internal oscillator is
+ * fully disabled in deep sleep mode. When you exist deep sleep
+ * mode, the oscillator will be turned on and will generate very
+ * small oscillations which will not be detected by the deep sleep
+ * counter. Eventually those oscillations will grow to an amplitude
+ * large enough to start incrementing the deep sleep counter.
+ * In this case recommendation from hardware engineers is that the
+ * SLEEPCOUNT be set to 4096. This means that 4096 valid clock cycles
+ * must be detected before the clock is passed to the rest of the
+ * system.
+ * In the case that the internal oscillator is not used and the
+ * clock is generated externally, the SLEEPCOUNT value can be very
+ * small since the clock input is assumed to be stable before SoC
+ * is taken out of deepsleep mode. A value of 128 would be more than
+ * adequate.
+ */
+ int sleepcount;
+};
+
+extern unsigned int davinci_cpu_suspend_sz;
+extern void davinci_cpu_suspend(struct davinci_pm_config *);
+
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
new file mode 100644
index 00000000..a47e6f29
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/psc.h
@@ -0,0 +1,256 @@
+/*
+ * DaVinci Power & Sleep Controller (PSC) defines
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ASM_ARCH_PSC_H
+#define __ASM_ARCH_PSC_H
+
+#define DAVINCI_PWR_SLEEP_CNTRL_BASE 0x01C41000
+
+/* Power and Sleep Controller (PSC) Domains */
+#define DAVINCI_GPSC_ARMDOMAIN 0
+#define DAVINCI_GPSC_DSPDOMAIN 1
+
+#define DAVINCI_LPSC_VPSSMSTR 0
+#define DAVINCI_LPSC_VPSSSLV 1
+#define DAVINCI_LPSC_TPCC 2
+#define DAVINCI_LPSC_TPTC0 3
+#define DAVINCI_LPSC_TPTC1 4
+#define DAVINCI_LPSC_EMAC 5
+#define DAVINCI_LPSC_EMAC_WRAPPER 6
+#define DAVINCI_LPSC_USB 9
+#define DAVINCI_LPSC_ATA 10
+#define DAVINCI_LPSC_VLYNQ 11
+#define DAVINCI_LPSC_UHPI 12
+#define DAVINCI_LPSC_DDR_EMIF 13
+#define DAVINCI_LPSC_AEMIF 14
+#define DAVINCI_LPSC_MMC_SD 15
+#define DAVINCI_LPSC_McBSP 17
+#define DAVINCI_LPSC_I2C 18
+#define DAVINCI_LPSC_UART0 19
+#define DAVINCI_LPSC_UART1 20
+#define DAVINCI_LPSC_UART2 21
+#define DAVINCI_LPSC_SPI 22
+#define DAVINCI_LPSC_PWM0 23
+#define DAVINCI_LPSC_PWM1 24
+#define DAVINCI_LPSC_PWM2 25
+#define DAVINCI_LPSC_GPIO 26
+#define DAVINCI_LPSC_TIMER0 27
+#define DAVINCI_LPSC_TIMER1 28
+#define DAVINCI_LPSC_TIMER2 29
+#define DAVINCI_LPSC_SYSTEM_SUBSYS 30
+#define DAVINCI_LPSC_ARM 31
+#define DAVINCI_LPSC_SCR2 32
+#define DAVINCI_LPSC_SCR3 33
+#define DAVINCI_LPSC_SCR4 34
+#define DAVINCI_LPSC_CROSSBAR 35
+#define DAVINCI_LPSC_CFG27 36
+#define DAVINCI_LPSC_CFG3 37
+#define DAVINCI_LPSC_CFG5 38
+#define DAVINCI_LPSC_GEM 39
+#define DAVINCI_LPSC_IMCOP 40
+
+#define DM355_LPSC_TIMER3 5
+#define DM355_LPSC_SPI1 6
+#define DM355_LPSC_MMC_SD1 7
+#define DM355_LPSC_McBSP1 8
+#define DM355_LPSC_PWM3 10
+#define DM355_LPSC_SPI2 11
+#define DM355_LPSC_RTO 12
+#define DM355_LPSC_VPSS_DAC 41
+
+/* DM365 */
+#define DM365_LPSC_TIMER3 5
+#define DM365_LPSC_SPI1 6
+#define DM365_LPSC_MMC_SD1 7
+#define DM365_LPSC_McBSP1 8
+#define DM365_LPSC_PWM3 10
+#define DM365_LPSC_SPI2 11
+#define DM365_LPSC_RTO 12
+#define DM365_LPSC_TIMER4 17
+#define DM365_LPSC_SPI0 22
+#define DM365_LPSC_SPI3 38
+#define DM365_LPSC_SPI4 39
+#define DM365_LPSC_EMAC 40
+#define DM365_LPSC_VOICE_CODEC 44
+#define DM365_LPSC_DAC_CLK 46
+#define DM365_LPSC_VPSSMSTR 47
+#define DM365_LPSC_MJCP 50
+
+/*
+ * LPSC Assignments
+ */
+#define DM646X_LPSC_ARM 0
+#define DM646X_LPSC_C64X_CPU 1
+#define DM646X_LPSC_HDVICP0 2
+#define DM646X_LPSC_HDVICP1 3
+#define DM646X_LPSC_TPCC 4
+#define DM646X_LPSC_TPTC0 5
+#define DM646X_LPSC_TPTC1 6
+#define DM646X_LPSC_TPTC2 7
+#define DM646X_LPSC_TPTC3 8
+#define DM646X_LPSC_PCI 13
+#define DM646X_LPSC_EMAC 14
+#define DM646X_LPSC_VDCE 15
+#define DM646X_LPSC_VPSSMSTR 16
+#define DM646X_LPSC_VPSSSLV 17
+#define DM646X_LPSC_TSIF0 18
+#define DM646X_LPSC_TSIF1 19
+#define DM646X_LPSC_DDR_EMIF 20
+#define DM646X_LPSC_AEMIF 21
+#define DM646X_LPSC_McASP0 22
+#define DM646X_LPSC_McASP1 23
+#define DM646X_LPSC_CRGEN0 24
+#define DM646X_LPSC_CRGEN1 25
+#define DM646X_LPSC_UART0 26
+#define DM646X_LPSC_UART1 27
+#define DM646X_LPSC_UART2 28
+#define DM646X_LPSC_PWM0 29
+#define DM646X_LPSC_PWM1 30
+#define DM646X_LPSC_I2C 31
+#define DM646X_LPSC_SPI 32
+#define DM646X_LPSC_GPIO 33
+#define DM646X_LPSC_TIMER0 34
+#define DM646X_LPSC_TIMER1 35
+#define DM646X_LPSC_ARM_INTC 45
+
+/* PSC0 defines */
+#define DA8XX_LPSC0_TPCC 0
+#define DA8XX_LPSC0_TPTC0 1
+#define DA8XX_LPSC0_TPTC1 2
+#define DA8XX_LPSC0_EMIF25 3
+#define DA8XX_LPSC0_SPI0 4
+#define DA8XX_LPSC0_MMC_SD 5
+#define DA8XX_LPSC0_AINTC 6
+#define DA8XX_LPSC0_ARM_RAM_ROM 7
+#define DA8XX_LPSC0_SECU_MGR 8
+#define DA8XX_LPSC0_UART0 9
+#define DA8XX_LPSC0_SCR0_SS 10
+#define DA8XX_LPSC0_SCR1_SS 11
+#define DA8XX_LPSC0_SCR2_SS 12
+#define DA8XX_LPSC0_PRUSS 13
+#define DA8XX_LPSC0_ARM 14
+#define DA8XX_LPSC0_GEM 15
+
+/* PSC1 defines */
+#define DA850_LPSC1_TPCC1 0
+#define DA8XX_LPSC1_USB20 1
+#define DA8XX_LPSC1_USB11 2
+#define DA8XX_LPSC1_GPIO 3
+#define DA8XX_LPSC1_UHPI 4
+#define DA8XX_LPSC1_CPGMAC 5
+#define DA8XX_LPSC1_EMIF3C 6
+#define DA8XX_LPSC1_McASP0 7
+#define DA830_LPSC1_McASP1 8
+#define DA850_LPSC1_SATA 8
+#define DA830_LPSC1_McASP2 9
+#define DA8XX_LPSC1_SPI1 10
+#define DA8XX_LPSC1_I2C 11
+#define DA8XX_LPSC1_UART1 12
+#define DA8XX_LPSC1_UART2 13
+#define DA8XX_LPSC1_LCDC 16
+#define DA8XX_LPSC1_PWM 17
+#define DA850_LPSC1_MMC_SD1 18
+#define DA8XX_LPSC1_ECAP 20
+#define DA830_LPSC1_EQEP 21
+#define DA850_LPSC1_TPTC2 21
+#define DA8XX_LPSC1_SCR_P0_SS 24
+#define DA8XX_LPSC1_SCR_P1_SS 25
+#define DA8XX_LPSC1_CR_P3_SS 26
+#define DA8XX_LPSC1_L3_CBA_RAM 31
+
+/* TNETV107X LPSC Assignments */
+#define TNETV107X_LPSC_ARM 0
+#define TNETV107X_LPSC_GEM 1
+#define TNETV107X_LPSC_DDR2_PHY 2
+#define TNETV107X_LPSC_TPCC 3
+#define TNETV107X_LPSC_TPTC0 4
+#define TNETV107X_LPSC_TPTC1 5
+#define TNETV107X_LPSC_RAM 6
+#define TNETV107X_LPSC_MBX_LITE 7
+#define TNETV107X_LPSC_LCD 8
+#define TNETV107X_LPSC_ETHSS 9
+#define TNETV107X_LPSC_AEMIF 10
+#define TNETV107X_LPSC_CHIP_CFG 11
+#define TNETV107X_LPSC_TSC 12
+#define TNETV107X_LPSC_ROM 13
+#define TNETV107X_LPSC_UART2 14
+#define TNETV107X_LPSC_PKTSEC 15
+#define TNETV107X_LPSC_SECCTL 16
+#define TNETV107X_LPSC_KEYMGR 17
+#define TNETV107X_LPSC_KEYPAD 18
+#define TNETV107X_LPSC_GPIO 19
+#define TNETV107X_LPSC_MDIO 20
+#define TNETV107X_LPSC_SDIO0 21
+#define TNETV107X_LPSC_UART0 22
+#define TNETV107X_LPSC_UART1 23
+#define TNETV107X_LPSC_TIMER0 24
+#define TNETV107X_LPSC_TIMER1 25
+#define TNETV107X_LPSC_WDT_ARM 26
+#define TNETV107X_LPSC_WDT_DSP 27
+#define TNETV107X_LPSC_SSP 28
+#define TNETV107X_LPSC_TDM0 29
+#define TNETV107X_LPSC_VLYNQ 30
+#define TNETV107X_LPSC_MCDMA 31
+#define TNETV107X_LPSC_USB0 32
+#define TNETV107X_LPSC_TDM1 33
+#define TNETV107X_LPSC_DEBUGSS 34
+#define TNETV107X_LPSC_ETHSS_RGMII 35
+#define TNETV107X_LPSC_SYSTEM 36
+#define TNETV107X_LPSC_IMCOP 37
+#define TNETV107X_LPSC_SPARE 38
+#define TNETV107X_LPSC_SDIO1 39
+#define TNETV107X_LPSC_USB1 40
+#define TNETV107X_LPSC_USBSS 41
+#define TNETV107X_LPSC_DDR2_EMIF1_VRST 42
+#define TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST 43
+#define TNETV107X_LPSC_MAX 44
+
+/* PSC register offsets */
+#define EPCPR 0x070
+#define PTCMD 0x120
+#define PTSTAT 0x128
+#define PDSTAT 0x200
+#define PDCTL1 0x304
+#define MDSTAT 0x800
+#define MDCTL 0xA00
+
+/* PSC module states */
+#define PSC_STATE_SWRSTDISABLE 0
+#define PSC_STATE_SYNCRST 1
+#define PSC_STATE_DISABLE 2
+#define PSC_STATE_ENABLE 3
+
+#define MDSTAT_STATE_MASK 0x1f
+
+#ifndef __ASSEMBLER__
+
+extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, u32 next_state);
+
+#endif
+
+#endif /* __ASM_ARCH_PSC_H */
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
new file mode 100644
index 00000000..c9e6ce18
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -0,0 +1,57 @@
+/*
+ * DaVinci serial device definitions
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <asm/memory.h>
+
+#include <mach/hardware.h>
+
+/*
+ * Stolen area that contains debug uart physical and virtual addresses. These
+ * addresses are filled in by the uncompress.h code, and are used by the debug
+ * macros in debug-macro.S.
+ *
+ * This area sits just below the page tables (see arch/arm/kernel/head.S).
+ */
+#define DAVINCI_UART_INFO (PLAT_PHYS_OFFSET + 0x3ff8)
+
+#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
+#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
+#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
+
+#define DA8XX_UART0_BASE (IO_PHYS + 0x042000)
+#define DA8XX_UART1_BASE (IO_PHYS + 0x10c000)
+#define DA8XX_UART2_BASE (IO_PHYS + 0x10d000)
+
+#define TNETV107X_UART0_BASE 0x08108100
+#define TNETV107X_UART1_BASE 0x08088400
+#define TNETV107X_UART2_BASE 0x08108300
+
+#define TNETV107X_UART0_VIRT IOMEM(0xfee08100)
+#define TNETV107X_UART1_VIRT IOMEM(0xfed88400)
+#define TNETV107X_UART2_VIRT IOMEM(0xfee08300)
+
+/* DaVinci UART register offsets */
+#define UART_DAVINCI_PWREMU 0x0c
+#define UART_DM646X_SCR 0x10
+#define UART_DM646X_SCR_TX_WATERMARK 0x08
+
+#ifndef __ASSEMBLY__
+struct davinci_uart_config {
+ /* Bit field of UARTs present; bit 0 --> UART1 */
+ unsigned int enabled_uarts;
+};
+
+extern int davinci_serial_init(struct davinci_uart_config *);
+#endif
+
+#endif /* __ASM_ARCH_SERIAL_H */
diff --git a/arch/arm/mach-davinci/include/mach/spi.h b/arch/arm/mach-davinci/include/mach/spi.h
new file mode 100644
index 00000000..7af305b3
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/spi.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2009 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_DAVINCI_SPI_H
+#define __ARCH_ARM_DAVINCI_SPI_H
+
+#include <mach/edma.h>
+
+#define SPI_INTERN_CS 0xFF
+
+enum {
+ SPI_VERSION_1, /* For DM355/DM365/DM6467 */
+ SPI_VERSION_2, /* For DA8xx */
+};
+
+/**
+ * davinci_spi_platform_data - Platform data for SPI master device on DaVinci
+ *
+ * @version: version of the SPI IP. Different DaVinci devices have slightly
+ * varying versions of the same IP.
+ * @num_chipselect: number of chipselects supported by this SPI master
+ * @intr_line: interrupt line used to connect the SPI IP to the ARM interrupt
+ * controller withn the SoC. Possible values are 0 and 1.
+ * @chip_sel: list of GPIOs which can act as chip-selects for the SPI.
+ * SPI_INTERN_CS denotes internal SPI chip-select. Not necessary
+ * to populate if all chip-selects are internal.
+ * @cshold_bug: set this to true if the SPI controller on your chip requires
+ * a write to CSHOLD bit in between transfers (like in DM355).
+ * @dma_event_q: DMA event queue to use if SPI_IO_TYPE_DMA is used for any
+ * device on the bus.
+ */
+struct davinci_spi_platform_data {
+ u8 version;
+ u8 num_chipselect;
+ u8 intr_line;
+ u8 *chip_sel;
+ bool cshold_bug;
+ enum dma_event_q dma_event_q;
+};
+
+/**
+ * davinci_spi_config - Per-chip-select configuration for SPI slave devices
+ *
+ * @wdelay: amount of delay between transmissions. Measured in number of
+ * SPI module clocks.
+ * @odd_parity: polarity of parity flag at the end of transmit data stream.
+ * 0 - odd parity, 1 - even parity.
+ * @parity_enable: enable transmission of parity at end of each transmit
+ * data stream.
+ * @io_type: type of IO transfer. Choose between polled, interrupt and DMA.
+ * @timer_disable: disable chip-select timers (setup and hold)
+ * @c2tdelay: chip-select setup time. Measured in number of SPI module clocks.
+ * @t2cdelay: chip-select hold time. Measured in number of SPI module clocks.
+ * @t2edelay: transmit data finished to SPI ENAn pin inactive time. Measured
+ * in number of SPI clocks.
+ * @c2edelay: chip-select active to SPI ENAn signal active time. Measured in
+ * number of SPI clocks.
+ */
+struct davinci_spi_config {
+ u8 wdelay;
+ u8 odd_parity;
+ u8 parity_enable;
+#define SPI_IO_TYPE_INTR 0
+#define SPI_IO_TYPE_POLL 1
+#define SPI_IO_TYPE_DMA 2
+ u8 io_type;
+ u8 timer_disable;
+ u8 c2tdelay;
+ u8 t2cdelay;
+ u8 t2edelay;
+ u8 c2edelay;
+};
+
+#endif /* __ARCH_ARM_DAVINCI_SPI_H */
diff --git a/arch/arm/mach-davinci/include/mach/sram.h b/arch/arm/mach-davinci/include/mach/sram.h
new file mode 100644
index 00000000..111f7cc7
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/sram.h
@@ -0,0 +1,27 @@
+/*
+ * mach/sram.h - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * This program is free software; you can 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_SRAM_H
+#define __MACH_SRAM_H
+
+/* ARBITRARY: SRAM allocations are multiples of this 2^N size */
+#define SRAM_GRANULARITY 512
+
+/*
+ * SRAM allocations return a CPU virtual address, or NULL on error.
+ * If a DMA address is requested and the SRAM supports DMA, its
+ * mapped address is also returned.
+ *
+ * Errors include SRAM memory not being available, and requesting
+ * DMA mapped SRAM on systems which don't allow that.
+ */
+extern void *sram_alloc(size_t len, dma_addr_t *dma);
+extern void sram_free(void *addr, size_t len);
+
+#endif /* __MACH_SRAM_H */
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
new file mode 100644
index 00000000..e65629c2
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * DaVinci system defines
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/common.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (davinci_soc_info.reset)
+ davinci_soc_info.reset(davinci_soc_info.reset_device);
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
new file mode 100644
index 00000000..1c971d8d
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/time.h
@@ -0,0 +1,35 @@
+/*
+ * Local header file for DaVinci time code.
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
+#define __ARCH_ARM_MACH_DAVINCI_TIME_H
+
+#define DAVINCI_TIMER0_BASE (IO_PHYS + 0x21400)
+#define DAVINCI_TIMER1_BASE (IO_PHYS + 0x21800)
+#define DAVINCI_WDOG_BASE (IO_PHYS + 0x21C00)
+
+enum {
+ T0_BOT,
+ T0_TOP,
+ T1_BOT,
+ T1_TOP,
+ NUM_TIMERS
+};
+
+#define IS_TIMER1(id) (id & 0x2)
+#define IS_TIMER0(id) (!IS_TIMER1(id))
+#define IS_TIMER_TOP(id) ((id & 0x1))
+#define IS_TIMER_BOT(id) (!IS_TIMER_TOP(id))
+
+#define ID_TO_TIMER(id) (IS_TIMER1(id) != 0)
+
+extern struct davinci_timer_instance davinci_timer_instance[];
+
+#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/include/mach/timex.h b/arch/arm/mach-davinci/include/mach/timex.h
new file mode 100644
index 00000000..9b885298
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/timex.h
@@ -0,0 +1,22 @@
+/*
+ * DaVinci timer defines
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * Alert: Not all timers of the DaVinci family run at a frequency of 27MHz,
+ * but we should be fine as long as CLOCK_TICK_RATE or LATCH (see include/
+ * linux/jiffies.h) are not used directly in code. Currently none of the
+ * code relevant to DaVinci platform depends on these values directly.
+ */
+#define CLOCK_TICK_RATE 27000000
+
+#endif /* __ASM_ARCH_TIMEX_H__ */
diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
new file mode 100644
index 00000000..89c1fdc6
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h
@@ -0,0 +1,60 @@
+/*
+ * Texas Instruments TNETV107X SoC Specific Defines
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * 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 __ASM_ARCH_DAVINCI_TNETV107X_H
+#define __ASM_ARCH_DAVINCI_TNETV107X_H
+
+#include <asm/sizes.h>
+
+#define TNETV107X_DDR_BASE 0x80000000
+
+/*
+ * Fixed mapping for early init starts here. If low-level debug is enabled,
+ * this area also gets mapped via io_pg_offset and io_phys by the boot code.
+ * To fit in with the io_pg_offset calculation, the io base address selected
+ * here _must_ be a multiple of 2^20.
+ */
+#define TNETV107X_IO_BASE 0x08000000
+#define TNETV107X_IO_VIRT (IO_VIRT + SZ_1M)
+
+#define TNETV107X_N_GPIO 65
+
+#ifndef __ASSEMBLY__
+
+#include <linux/serial_8250.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/mfd/ti_ssp.h>
+
+#include <mach/mmc.h>
+#include <mach/nand.h>
+#include <mach/serial.h>
+
+struct tnetv107x_device_info {
+ struct davinci_uart_config *serial_config;
+ struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */
+ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */
+ struct matrix_keypad_platform_data *keypad_config;
+ struct ti_ssp_data *ssp_config;
+};
+
+extern struct platform_device tnetv107x_wdt_device;
+extern struct platform_device tnetv107x_serial_device;
+
+extern void __init tnetv107x_init(void);
+extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *);
+extern void __init tnetv107x_irq_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_DAVINCI_TNETV107X_H */
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
new file mode 100644
index 00000000..78d80683
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -0,0 +1,101 @@
+/*
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Initially based on:
+ * arch/arm/plat-omap/include/mach/uncompress.h
+ *
+ * Original copyrights follow.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Rewritten by:
+ * Author: <source@mvista.com>
+ * 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/serial.h>
+
+u32 *uart;
+
+/* PORT_16C550A, in polled non-fifo mode */
+static void putc(char c)
+{
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+ while (!(uart[UART_LSR] & UART_LSR_THRE))
+ barrier();
+}
+
+static inline void set_uart_info(u32 phys, void * __iomem virt)
+{
+ u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
+
+ uart = (u32 *)phys;
+ uart_info[0] = phys;
+ uart_info[1] = (u32)virt;
+}
+
+#define _DEBUG_LL_ENTRY(machine, phys, virt) \
+ if (machine_is_##machine()) { \
+ set_uart_info(phys, virt); \
+ break; \
+ }
+
+#define DEBUG_LL_DAVINCI(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \
+ IO_ADDRESS(DAVINCI_UART##port##_BASE))
+
+#define DEBUG_LL_DA8XX(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \
+ IO_ADDRESS(DA8XX_UART##port##_BASE))
+
+#define DEBUG_LL_TNETV107X(machine, port) \
+ _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \
+ TNETV107X_UART##port##_VIRT)
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ /*
+ * Initialize the port based on the machine ID from the bootloader.
+ * Note that we're using macros here instead of switch statement
+ * as machine_is functions are optimized out for the boards that
+ * are not selected.
+ */
+ do {
+ /* Davinci boards */
+ DEBUG_LL_DAVINCI(davinci_evm, 0);
+ DEBUG_LL_DAVINCI(sffsdr, 0);
+ DEBUG_LL_DAVINCI(neuros_osd2, 0);
+ DEBUG_LL_DAVINCI(davinci_dm355_evm, 0);
+ DEBUG_LL_DAVINCI(dm355_leopard, 0);
+ DEBUG_LL_DAVINCI(davinci_dm6467_evm, 0);
+ DEBUG_LL_DAVINCI(davinci_dm365_evm, 0);
+
+ /* DA8xx boards */
+ DEBUG_LL_DA8XX(davinci_da830_evm, 2);
+ DEBUG_LL_DA8XX(davinci_da850_evm, 2);
+ DEBUG_LL_DA8XX(mityomapl138, 1);
+ DEBUG_LL_DA8XX(omapl138_hawkboard, 2);
+
+ /* TNETV107x boards */
+ DEBUG_LL_TNETV107X(tnetv107x, 1);
+ } while (0);
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-davinci/include/mach/usb.h b/arch/arm/mach-davinci/include/mach/usb.h
new file mode 100644
index 00000000..e0bc4abe
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/usb.h
@@ -0,0 +1,59 @@
+/*
+ * USB related definitions
+ *
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+/* DA8xx CFGCHIP2 (USB 2.0 PHY Control) register bits */
+#define CFGCHIP2_PHYCLKGD (1 << 17)
+#define CFGCHIP2_VBUSSENSE (1 << 16)
+#define CFGCHIP2_RESET (1 << 15)
+#define CFGCHIP2_OTGMODE (3 << 13)
+#define CFGCHIP2_NO_OVERRIDE (0 << 13)
+#define CFGCHIP2_FORCE_HOST (1 << 13)
+#define CFGCHIP2_FORCE_DEVICE (2 << 13)
+#define CFGCHIP2_FORCE_HOST_VBUS_LOW (3 << 13)
+#define CFGCHIP2_USB1PHYCLKMUX (1 << 12)
+#define CFGCHIP2_USB2PHYCLKMUX (1 << 11)
+#define CFGCHIP2_PHYPWRDN (1 << 10)
+#define CFGCHIP2_OTGPWRDN (1 << 9)
+#define CFGCHIP2_DATPOL (1 << 8)
+#define CFGCHIP2_USB1SUSPENDM (1 << 7)
+#define CFGCHIP2_PHY_PLLON (1 << 6) /* override PLL suspend */
+#define CFGCHIP2_SESENDEN (1 << 5) /* Vsess_end comparator */
+#define CFGCHIP2_VBDTCTEN (1 << 4) /* Vbus comparator */
+#define CFGCHIP2_REFFREQ (0xf << 0)
+#define CFGCHIP2_REFFREQ_12MHZ (1 << 0)
+#define CFGCHIP2_REFFREQ_24MHZ (2 << 0)
+#define CFGCHIP2_REFFREQ_48MHZ (3 << 0)
+
+struct da8xx_ohci_root_hub;
+
+typedef void (*da8xx_ocic_handler_t)(struct da8xx_ohci_root_hub *hub,
+ unsigned port);
+
+/* Passed as the platform data to the OHCI driver */
+struct da8xx_ohci_root_hub {
+ /* Switch the port power on/off */
+ int (*set_power)(unsigned port, int on);
+ /* Read the port power status */
+ int (*get_power)(unsigned port);
+ /* Read the port over-current indicator */
+ int (*get_oci)(unsigned port);
+ /* Over-current indicator change notification (pass NULL to disable) */
+ int (*ocic_notify)(da8xx_ocic_handler_t handler);
+
+ /* Time from power on to power good (in 2 ms units) */
+ u8 potpgt;
+};
+
+void davinci_setup_usb(unsigned mA, unsigned potpgt_ms);
+
+#endif /* ifndef __ASM_ARCH_USB_H */
diff --git a/arch/arm/mach-davinci/include/mach/vmalloc.h b/arch/arm/mach-davinci/include/mach/vmalloc.h
new file mode 100644
index 00000000..d49646a8
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/vmalloc.h
@@ -0,0 +1,14 @@
+/*
+ * DaVinci vmalloc definitions
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <mach/hardware.h>
+
+/* Allow vmalloc range until the IO virtual range minus a 2M "hole" */
+#define VMALLOC_END (IO_VIRT - (2<<20))
diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
new file mode 100644
index 00000000..8ea60a8b
--- /dev/null
+++ b/arch/arm/mach-davinci/io.c
@@ -0,0 +1,48 @@
+/*
+ * DaVinci I/O mapping code
+ *
+ * Copyright (C) 2005-2006 Texas Instruments
+ *
+ * This program is free software; you can 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/io.h>
+
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *davinci_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+ struct map_desc *desc = davinci_soc_info.io_desc;
+ int desc_num = davinci_soc_info.io_desc_num;
+ int i;
+
+ for (i = 0; i < desc_num; i++, desc++) {
+ unsigned long iophys = __pfn_to_phys(desc->pfn);
+ unsigned long iosize = desc->length;
+
+ if (p >= iophys && (p + size) <= (iophys + iosize))
+ return __io(desc->virtual + p - iophys);
+ }
+
+ return __arm_ioremap_caller(p, size, type,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(davinci_ioremap);
+
+void davinci_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(davinci_iounmap);
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
new file mode 100644
index 00000000..952dc126
--- /dev/null
+++ b/arch/arm/mach-davinci/irq.c
@@ -0,0 +1,117 @@
+/*
+ * Interrupt handler for DaVinci boards.
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/cputype.h>
+#include <mach/common.h>
+#include <asm/mach/irq.h>
+
+#define FIQ_REG0_OFFSET 0x0000
+#define FIQ_REG1_OFFSET 0x0004
+#define IRQ_REG0_OFFSET 0x0008
+#define IRQ_REG1_OFFSET 0x000C
+#define IRQ_ENT_REG0_OFFSET 0x0018
+#define IRQ_ENT_REG1_OFFSET 0x001C
+#define IRQ_INCTL_REG_OFFSET 0x0020
+#define IRQ_EABASE_REG_OFFSET 0x0024
+#define IRQ_INTPRI0_REG_OFFSET 0x0030
+#define IRQ_INTPRI7_REG_OFFSET 0x004C
+
+static inline void davinci_irq_writel(unsigned long value, int offset)
+{
+ __raw_writel(value, davinci_intc_base + offset);
+}
+
+static __init void
+davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
+ if (!gc) {
+ pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
+ __func__, irq_start);
+ return;
+ }
+
+ ct = gc->chip_types;
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+
+ ct->regs.ack = IRQ_REG0_OFFSET;
+ ct->regs.mask = IRQ_ENT_REG0_OFFSET;
+ irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
+/* ARM Interrupt Controller Initialization */
+void __init davinci_irq_init(void)
+{
+ unsigned i, j;
+ const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
+
+ davinci_intc_type = DAVINCI_INTC_TYPE_AINTC;
+ davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K);
+ if (WARN_ON(!davinci_intc_base))
+ return;
+
+ /* Clear all interrupt requests */
+ davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
+
+ /* Disable all interrupts */
+ davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
+ davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);
+
+ /* Interrupts disabled immediately, IRQ entry reflects all */
+ davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);
+
+ /* we don't use the hardware vector table, just its entry addresses */
+ davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);
+
+ /* Clear all interrupt requests */
+ davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
+ davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
+
+ for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
+ u32 pri;
+
+ for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
+ pri |= (*davinci_def_priorities & 0x07) << j;
+ davinci_irq_writel(pri, i);
+ }
+
+ for (i = 0, j = 0; i < davinci_soc_info.intc_irq_num; i += 32, j += 0x04)
+ davinci_alloc_gc(davinci_intc_base + j, i, 32);
+
+ irq_set_handler(IRQ_TINT1_TINT34, handle_level_irq);
+}
diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
new file mode 100644
index 00000000..f34a8dcd
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.c
@@ -0,0 +1,113 @@
+/*
+ * Utility to set the DAVINCI MUX register from a table in mux.h
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * Based on linux/arch/arm/plat-omap/mux.c:
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include <mach/mux.h>
+#include <mach/common.h>
+
+static void __iomem *pinmux_base;
+
+/*
+ * Sets the DAVINCI MUX register based on the table
+ */
+int __init_or_module davinci_cfg_reg(const unsigned long index)
+{
+ static DEFINE_SPINLOCK(mux_spin_lock);
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ unsigned long flags;
+ const struct mux_config *cfg;
+ unsigned int reg_orig = 0, reg = 0;
+ unsigned int mask, warn = 0;
+
+ if (WARN_ON(!soc_info->pinmux_pins))
+ return -ENODEV;
+
+ if (!pinmux_base) {
+ pinmux_base = ioremap(soc_info->pinmux_base, SZ_4K);
+ if (WARN_ON(!pinmux_base))
+ return -ENOMEM;
+ }
+
+ if (index >= soc_info->pinmux_pins_num) {
+ printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+ index, soc_info->pinmux_pins_num);
+ dump_stack();
+ return -ENODEV;
+ }
+
+ cfg = &soc_info->pinmux_pins[index];
+
+ if (cfg->name == NULL) {
+ printk(KERN_ERR "No entry for the specified index\n");
+ return -ENODEV;
+ }
+
+ /* Update the mux register in question */
+ if (cfg->mask) {
+ unsigned tmp1, tmp2;
+
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ reg_orig = __raw_readl(pinmux_base + cfg->mux_reg);
+
+ mask = (cfg->mask << cfg->mask_offset);
+ tmp1 = reg_orig & mask;
+ reg = reg_orig & ~mask;
+
+ tmp2 = (cfg->mode << cfg->mask_offset);
+ reg |= tmp2;
+
+ if (tmp1 != tmp2)
+ warn = 1;
+
+ __raw_writel(reg, pinmux_base + cfg->mux_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+ }
+
+ if (warn) {
+#ifdef CONFIG_DAVINCI_MUX_WARNINGS
+ printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
+#endif
+ }
+
+#ifdef CONFIG_DAVINCI_MUX_DEBUG
+ if (cfg->debug || warn) {
+ printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
+ printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n",
+ cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
+ }
+#endif
+
+ return 0;
+}
+EXPORT_SYMBOL(davinci_cfg_reg);
+
+int __init_or_module davinci_cfg_reg_list(const short pins[])
+{
+ int i, error = -EINVAL;
+
+ if (pins)
+ for (i = 0; pins[i] >= 0; i++) {
+ error = davinci_cfg_reg(pins[i]);
+ if (error)
+ break;
+ }
+
+ return error;
+}
diff --git a/arch/arm/mach-davinci/mux.h b/arch/arm/mach-davinci/mux.h
new file mode 100644
index 00000000..5aad1e7d
--- /dev/null
+++ b/arch/arm/mach-davinci/mux.h
@@ -0,0 +1,51 @@
+/*
+ * Pin-multiplex helper macros for TI DaVinci family devices
+ *
+ * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright (C) 2008 Texas Instruments.
+ */
+#ifndef _MACH_DAVINCI_MUX_H_
+#define _MACH_DAVINCI_MUX_H_
+
+#include <mach/mux.h>
+
+#define MUX_CFG(soc, desc, muxreg, mode_offset, mode_mask, mux_mode, dbg)\
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "PINMUX"#muxreg, \
+ .mux_reg = PINMUX(muxreg), \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#define INT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "INTMUX", \
+ .mux_reg = INTMUX, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#define EVT_CFG(soc, desc, mode_offset, mode_mask, mux_mode, dbg) \
+[soc##_##desc] = { \
+ .name = #desc, \
+ .debug = dbg, \
+ .mux_reg_name = "EVTMUX", \
+ .mux_reg = EVTMUX, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
+
+#endif /* _MACH_DAVINCI_MUX_H */
diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c
new file mode 100644
index 00000000..04c49f75
--- /dev/null
+++ b/arch/arm/mach-davinci/pm.c
@@ -0,0 +1,159 @@
+/*
+ * DaVinci Power Management Routines
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+
+#include <mach/da8xx.h>
+#include <mach/sram.h>
+#include <mach/pm.h>
+
+#include "clock.h"
+
+#define DEEPSLEEP_SLEEPCOUNT_MASK 0xFFFF
+
+static void (*davinci_sram_suspend) (struct davinci_pm_config *);
+static struct davinci_pm_config *pdata;
+
+static void davinci_sram_push(void *dest, void *src, unsigned int size)
+{
+ memcpy(dest, src, size);
+ flush_icache_range((unsigned long)dest, (unsigned long)(dest + size));
+}
+
+static void davinci_pm_suspend(void)
+{
+ unsigned val;
+
+ if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+ /* Switch CPU PLL to bypass mode */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~(PLLCTL_PLLENSRC | PLLCTL_PLLEN);
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ udelay(PLL_BYPASS_TIME);
+
+ /* Powerdown CPU PLL */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val |= PLLCTL_PLLPWRDN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ }
+
+ /* Configure sleep count in deep sleep register */
+ val = __raw_readl(pdata->deepsleep_reg);
+ val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
+ val |= pdata->sleepcount;
+ __raw_writel(val, pdata->deepsleep_reg);
+
+ /* System goes to sleep in this call */
+ davinci_sram_suspend(pdata);
+
+ if (pdata->cpupll_reg_base != pdata->ddrpll_reg_base) {
+
+ /* put CPU PLL in reset */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLRST;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* put CPU PLL in power down */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLPWRDN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* wait for CPU PLL reset */
+ udelay(PLL_RESET_TIME);
+
+ /* bring CPU PLL out of reset */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val |= PLLCTL_PLLRST;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+
+ /* Wait for CPU PLL to lock */
+ udelay(PLL_LOCK_TIME);
+
+ /* Remove CPU PLL from bypass mode */
+ val = __raw_readl(pdata->cpupll_reg_base + PLLCTL);
+ val &= ~PLLCTL_PLLENSRC;
+ val |= PLLCTL_PLLEN;
+ __raw_writel(val, pdata->cpupll_reg_base + PLLCTL);
+ }
+}
+
+static int davinci_pm_enter(suspend_state_t state)
+{
+ int ret = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ davinci_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static const struct platform_suspend_ops davinci_pm_ops = {
+ .enter = davinci_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init davinci_pm_probe(struct platform_device *pdev)
+{
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(&pdev->dev, "cannot get platform data\n");
+ return -ENOENT;
+ }
+
+ davinci_sram_suspend = sram_alloc(davinci_cpu_suspend_sz, NULL);
+ if (!davinci_sram_suspend) {
+ dev_err(&pdev->dev, "cannot allocate SRAM memory\n");
+ return -ENOMEM;
+ }
+
+ davinci_sram_push(davinci_sram_suspend, davinci_cpu_suspend,
+ davinci_cpu_suspend_sz);
+
+ suspend_set_ops(&davinci_pm_ops);
+
+ return 0;
+}
+
+static int __exit davinci_pm_remove(struct platform_device *pdev)
+{
+ sram_free(davinci_sram_suspend, davinci_cpu_suspend_sz);
+ return 0;
+}
+
+static struct platform_driver davinci_pm_driver = {
+ .driver = {
+ .name = "pm-davinci",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(davinci_pm_remove),
+};
+
+static int __init davinci_pm_init(void)
+{
+ return platform_driver_probe(&davinci_pm_driver, davinci_pm_probe);
+}
+late_initcall(davinci_pm_init);
diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c
new file mode 100644
index 00000000..a4158040
--- /dev/null
+++ b/arch/arm/mach-davinci/psc.c
@@ -0,0 +1,100 @@
+/*
+ * TI DaVinci Power and Sleep Controller (PSC)
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/cputype.h>
+#include <mach/psc.h>
+
+/* Return nonzero iff the domain's clock is active */
+int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
+{
+ void __iomem *psc_base;
+ u32 mdstat;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return 0;
+ }
+
+ psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+ iounmap(psc_base);
+
+ /* if clocked, state can be "Enable" or "SyncReset" */
+ return mdstat & BIT(12);
+}
+
+/* Enable or disable a PSC domain */
+void davinci_psc_config(unsigned int domain, unsigned int ctlr,
+ unsigned int id, u32 next_state)
+{
+ u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl;
+ void __iomem *psc_base;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+ pr_warning("PSC: Bad psc data: 0x%x[%d]\n",
+ (int)soc_info->psc_bases, ctlr);
+ return;
+ }
+
+ psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
+
+ mdctl = __raw_readl(psc_base + MDCTL + 4 * id);
+ mdctl &= ~MDSTAT_STATE_MASK;
+ mdctl |= next_state;
+ __raw_writel(mdctl, psc_base + MDCTL + 4 * id);
+
+ pdstat = __raw_readl(psc_base + PDSTAT);
+ if ((pdstat & 0x00000001) == 0) {
+ pdctl1 = __raw_readl(psc_base + PDCTL1);
+ pdctl1 |= 0x1;
+ __raw_writel(pdctl1, psc_base + PDCTL1);
+
+ ptcmd = 1 << domain;
+ __raw_writel(ptcmd, psc_base + PTCMD);
+
+ do {
+ epcpr = __raw_readl(psc_base + EPCPR);
+ } while ((((epcpr >> domain) & 1) == 0));
+
+ pdctl1 = __raw_readl(psc_base + PDCTL1);
+ pdctl1 |= 0x100;
+ __raw_writel(pdctl1, psc_base + PDCTL1);
+ } else {
+ ptcmd = 1 << domain;
+ __raw_writel(ptcmd, psc_base + PTCMD);
+ }
+
+ do {
+ ptstat = __raw_readl(psc_base + PTSTAT);
+ } while (!(((ptstat >> domain) & 1) == 0));
+
+ do {
+ mdstat = __raw_readl(psc_base + MDSTAT + 4 * id);
+ } while (!((mdstat & MDSTAT_STATE_MASK) == next_state));
+
+ iounmap(psc_base);
+}
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
new file mode 100644
index 00000000..1875740f
--- /dev/null
+++ b/arch/arm/mach-davinci/serial.c
@@ -0,0 +1,115 @@
+/*
+ * TI DaVinci serial driver
+ *
+ * Copyright (C) 2006 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/serial.h>
+#include <mach/cputype.h>
+
+static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+
+ WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset);
+
+ return (unsigned int)__raw_readl(up->membase + offset);
+}
+
+static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
+ int value)
+{
+ offset <<= p->regshift;
+
+ WARN_ONCE(!p->membase, "unmapped write: uart[%d]\n", offset);
+
+ __raw_writel(value, p->membase + offset);
+}
+
+static void __init davinci_serial_reset(struct plat_serial8250_port *p)
+{
+ unsigned int pwremu = 0;
+
+ serial_write_reg(p, UART_IER, 0); /* disable all interrupts */
+
+ /* reset both transmitter and receiver: bits 14,13 = UTRST, URRST */
+ serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
+ mdelay(10);
+
+ pwremu |= (0x3 << 13);
+ pwremu |= 0x1;
+ serial_write_reg(p, UART_DAVINCI_PWREMU, pwremu);
+
+ if (cpu_is_davinci_dm646x())
+ serial_write_reg(p, UART_DM646X_SCR,
+ UART_DM646X_SCR_TX_WATERMARK);
+}
+
+int __init davinci_serial_init(struct davinci_uart_config *info)
+{
+ int i;
+ char name[16];
+ struct clk *uart_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct device *dev = &soc_info->serial_dev->dev;
+ struct plat_serial8250_port *p = dev->platform_data;
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on if not needed.
+ */
+ for (i = 0; p->flags; i++, p++) {
+ if (!(info->enabled_uarts & (1 << i)))
+ continue;
+
+ sprintf(name, "uart%d", i);
+ uart_clk = clk_get(dev, name);
+ if (IS_ERR(uart_clk)) {
+ printk(KERN_ERR "%s:%d: failed to get UART%d clock\n",
+ __func__, __LINE__, i);
+ continue;
+ }
+
+ clk_enable(uart_clk);
+ p->uartclk = clk_get_rate(uart_clk);
+
+ if (!p->membase && p->mapbase) {
+ p->membase = ioremap(p->mapbase, SZ_4K);
+
+ if (p->membase)
+ p->flags &= ~UPF_IOREMAP;
+ else
+ pr_err("uart regs ioremap failed\n");
+ }
+
+ if (p->membase && p->type != PORT_AR7)
+ davinci_serial_reset(p);
+ }
+
+ return platform_device_register(soc_info->serial_dev);
+}
diff --git a/arch/arm/mach-davinci/sleep.S b/arch/arm/mach-davinci/sleep.S
new file mode 100644
index 00000000..5f1e045a
--- /dev/null
+++ b/arch/arm/mach-davinci/sleep.S
@@ -0,0 +1,228 @@
+/*
+ * (C) Copyright 2009, Texas Instruments, Inc. http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr) (1 << (nr))
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/psc.h>
+#include <mach/memory.h>
+
+#include "clock.h"
+
+/* Arbitrary, hardware currently does not update PHYRDY correctly */
+#define PHYRDY_CYCLES 0x1000
+
+/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
+#define PLL_BYPASS_CYCLES (PLL_BYPASS_TIME * 25)
+#define PLL_RESET_CYCLES (PLL_RESET_TIME * 25)
+#define PLL_LOCK_CYCLES (PLL_LOCK_TIME * 25)
+
+#define DEEPSLEEP_SLEEPENABLE_BIT BIT(31)
+
+ .text
+/*
+ * Move DaVinci into deep sleep state
+ *
+ * Note: This code is copied to internal SRAM by PM code. When the DaVinci
+ * wakes up it continues execution at the point it went to sleep.
+ * Register Usage:
+ * r0: contains virtual base for DDR2 controller
+ * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * r2: contains PSC number for DDR2
+ * r3: contains virtual base DDR2 PLL controller
+ * r4: contains virtual address of the DEEPSLEEP register
+ */
+ENTRY(davinci_cpu_suspend)
+ stmfd sp!, {r0-r12, lr} @ save registers on stack
+
+ ldr ip, CACHE_FLUSH
+ blx ip
+
+ ldmia r0, {r0-r4}
+
+ /*
+ * Switch DDR to self-refresh mode.
+ */
+
+ /* calculate SDRCR address */
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_SRPD_BIT
+ orr ip, ip, #DDR2_LPMODEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ orr ip, ip, #DDR2_MCLKSTOPEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ mov ip, #PHYRDY_CYCLES
+1: subs ip, ip, #0x1
+ bne 1b
+
+ /* Disable DDR2 LPSC */
+ mov r7, r0
+ mov r0, #0x2
+ bl davinci_ddr_psc_config
+ mov r0, r7
+
+ /* Disable clock to DDR PHY */
+ ldr ip, [r3, #PLLDIV1]
+ bic ip, ip, #PLLDIV_EN
+ str ip, [r3, #PLLDIV1]
+
+ /* Put the DDR PLL in bypass and power down */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLENSRC
+ bic ip, ip, #PLLCTL_PLLEN
+ str ip, [r3, #PLLCTL]
+
+ /* Wait for PLL to switch to bypass */
+ mov ip, #PLL_BYPASS_CYCLES
+2: subs ip, ip, #0x1
+ bne 2b
+
+ /* Power down the PLL */
+ ldr ip, [r3, #PLLCTL]
+ orr ip, ip, #PLLCTL_PLLPWRDN
+ str ip, [r3, #PLLCTL]
+
+ /* Go to deep sleep */
+ ldr ip, [r4]
+ orr ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+ /* System goes to sleep beyond after this instruction */
+ str ip, [r4]
+
+ /* Wake up from sleep */
+
+ /* Clear sleep enable */
+ ldr ip, [r4]
+ bic ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
+ str ip, [r4]
+
+ /* initialize the DDR PLL controller */
+
+ /* Put PLL in reset */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLRST
+ str ip, [r3, #PLLCTL]
+
+ /* Clear PLL power down */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLPWRDN
+ str ip, [r3, #PLLCTL]
+
+ mov ip, #PLL_RESET_CYCLES
+3: subs ip, ip, #0x1
+ bne 3b
+
+ /* Bring PLL out of reset */
+ ldr ip, [r3, #PLLCTL]
+ orr ip, ip, #PLLCTL_PLLRST
+ str ip, [r3, #PLLCTL]
+
+ /* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
+ mov ip, #PLL_LOCK_CYCLES
+4: subs ip, ip, #0x1
+ bne 4b
+
+ /* Remove PLL from bypass mode */
+ ldr ip, [r3, #PLLCTL]
+ bic ip, ip, #PLLCTL_PLLENSRC
+ orr ip, ip, #PLLCTL_PLLEN
+ str ip, [r3, #PLLCTL]
+
+ /* Start 2x clock to DDR2 */
+
+ ldr ip, [r3, #PLLDIV1]
+ orr ip, ip, #PLLDIV_EN
+ str ip, [r3, #PLLDIV1]
+
+ /* Enable VCLK */
+
+ /* Enable DDR2 LPSC */
+ mov r7, r0
+ mov r0, #0x3
+ bl davinci_ddr_psc_config
+ mov r0, r7
+
+ /* clear MCLKSTOPEN */
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_MCLKSTOPEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ ldr ip, [r0, #DDR2_SDRCR_OFFSET]
+ bic ip, ip, #DDR2_LPMODEN_BIT
+ str ip, [r0, #DDR2_SDRCR_OFFSET]
+
+ /* Restore registers and return */
+ ldmfd sp!, {r0-r12, pc}
+
+ENDPROC(davinci_cpu_suspend)
+
+/*
+ * Disables or Enables DDR2 LPSC
+ * Register Usage:
+ * r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
+ * r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
+ * r2: contains PSC number for DDR2
+ */
+ENTRY(davinci_ddr_psc_config)
+ /* Set next state in mdctl for DDR2 */
+ mov r6, #MDCTL
+ add r6, r6, r2, lsl #2
+ ldr ip, [r1, r6]
+ bic ip, ip, #MDSTAT_STATE_MASK
+ orr ip, ip, r0
+ str ip, [r1, r6]
+
+ /* Enable the Power Domain Transition Command */
+ ldr ip, [r1, #PTCMD]
+ orr ip, ip, #0x1
+ str ip, [r1, #PTCMD]
+
+ /* Check for Transition Complete (PTSTAT) */
+ptstat_done:
+ ldr ip, [r1, #PTSTAT]
+ and ip, ip, #0x1
+ cmp ip, #0x0
+ bne ptstat_done
+
+ /* Check for DDR2 clock disable completion; */
+ mov r6, #MDSTAT
+ add r6, r6, r2, lsl #2
+ddr2clk_stop_done:
+ ldr ip, [r1, r6]
+ and ip, ip, #MDSTAT_STATE_MASK
+ cmp ip, r0
+ bne ddr2clk_stop_done
+
+ mov pc, lr
+ENDPROC(davinci_ddr_psc_config)
+
+CACHE_FLUSH:
+#ifdef CONFIG_CPU_V6
+ .word v6_flush_kern_cache_all
+#else
+ .word arm926_flush_kern_cache_all
+#endif
+
+ENTRY(davinci_cpu_suspend_sz)
+ .word . - davinci_cpu_suspend
+ENDPROC(davinci_cpu_suspend_sz)
diff --git a/arch/arm/mach-davinci/sram.c b/arch/arm/mach-davinci/sram.c
new file mode 100644
index 00000000..db0f7787
--- /dev/null
+++ b/arch/arm/mach-davinci/sram.c
@@ -0,0 +1,71 @@
+/*
+ * mach-davinci/sram.c - DaVinci simple SRAM allocator
+ *
+ * Copyright (C) 2009 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/genalloc.h>
+
+#include <mach/common.h>
+#include <mach/sram.h>
+
+static struct gen_pool *sram_pool;
+
+void *sram_alloc(size_t len, dma_addr_t *dma)
+{
+ unsigned long vaddr;
+ dma_addr_t dma_base = davinci_soc_info.sram_dma;
+
+ if (dma)
+ *dma = 0;
+ if (!sram_pool || (dma && !dma_base))
+ return NULL;
+
+ vaddr = gen_pool_alloc(sram_pool, len);
+ if (!vaddr)
+ return NULL;
+
+ if (dma)
+ *dma = dma_base + (vaddr - SRAM_VIRT);
+ return (void *)vaddr;
+
+}
+EXPORT_SYMBOL(sram_alloc);
+
+void sram_free(void *addr, size_t len)
+{
+ gen_pool_free(sram_pool, (unsigned long) addr, len);
+}
+EXPORT_SYMBOL(sram_free);
+
+
+/*
+ * REVISIT This supports CPU and DMA access to/from SRAM, but it
+ * doesn't (yet?) support some other notable uses of SRAM: as TCM
+ * for data and/or instructions; and holding code needed to enter
+ * and exit suspend states (while DRAM can't be used).
+ */
+static int __init sram_init(void)
+{
+ unsigned len = davinci_soc_info.sram_len;
+ int status = 0;
+
+ if (len) {
+ len = min_t(unsigned, len, SRAM_SIZE);
+ sram_pool = gen_pool_create(ilog2(SRAM_GRANULARITY), -1);
+ if (!sram_pool)
+ status = -ENOMEM;
+ }
+ if (sram_pool)
+ status = gen_pool_add(sram_pool, SRAM_VIRT, len, -1);
+ WARN_ON(status < 0);
+ return status;
+}
+core_initcall(sram_init);
+
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
new file mode 100644
index 00000000..e1969ce9
--- /dev/null
+++ b/arch/arm/mach-davinci/time.c
@@ -0,0 +1,474 @@
+/*
+ * DaVinci timer subsystem
+ *
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <mach/cputype.h>
+#include <mach/time.h>
+#include "clock.h"
+
+static struct clock_event_device clockevent_davinci;
+static unsigned int davinci_clock_tick_rate;
+
+/*
+ * This driver configures the 2 64-bit count-up timers as 4 independent
+ * 32-bit count-up timers used as follows:
+ */
+
+enum {
+ TID_CLOCKEVENT,
+ TID_CLOCKSOURCE,
+};
+
+/* Timer register offsets */
+#define PID12 0x0
+#define TIM12 0x10
+#define TIM34 0x14
+#define PRD12 0x18
+#define PRD34 0x1c
+#define TCR 0x20
+#define TGCR 0x24
+#define WDTCR 0x28
+
+/* Offsets of the 8 compare registers */
+#define CMP12_0 0x60
+#define CMP12_1 0x64
+#define CMP12_2 0x68
+#define CMP12_3 0x6c
+#define CMP12_4 0x70
+#define CMP12_5 0x74
+#define CMP12_6 0x78
+#define CMP12_7 0x7c
+
+/* Timer register bitfields */
+#define TCR_ENAMODE_DISABLE 0x0
+#define TCR_ENAMODE_ONESHOT 0x1
+#define TCR_ENAMODE_PERIODIC 0x2
+#define TCR_ENAMODE_MASK 0x3
+
+#define TGCR_TIMMODE_SHIFT 2
+#define TGCR_TIMMODE_64BIT_GP 0x0
+#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
+#define TGCR_TIMMODE_64BIT_WDOG 0x2
+#define TGCR_TIMMODE_32BIT_CHAINED 0x3
+
+#define TGCR_TIM12RS_SHIFT 0
+#define TGCR_TIM34RS_SHIFT 1
+#define TGCR_RESET 0x0
+#define TGCR_UNRESET 0x1
+#define TGCR_RESET_MASK 0x3
+
+#define WDTCR_WDEN_SHIFT 14
+#define WDTCR_WDEN_DISABLE 0x0
+#define WDTCR_WDEN_ENABLE 0x1
+#define WDTCR_WDKEY_SHIFT 16
+#define WDTCR_WDKEY_SEQ0 0xa5c6
+#define WDTCR_WDKEY_SEQ1 0xda7e
+
+struct timer_s {
+ char *name;
+ unsigned int id;
+ unsigned long period;
+ unsigned long opts;
+ unsigned long flags;
+ void __iomem *base;
+ unsigned long tim_off;
+ unsigned long prd_off;
+ unsigned long enamode_shift;
+ struct irqaction irqaction;
+};
+static struct timer_s timers[];
+
+/* values for 'opts' field of struct timer_s */
+#define TIMER_OPTS_DISABLED 0x01
+#define TIMER_OPTS_ONESHOT 0x02
+#define TIMER_OPTS_PERIODIC 0x04
+#define TIMER_OPTS_STATE_MASK 0x07
+
+#define TIMER_OPTS_USE_COMPARE 0x80000000
+#define USING_COMPARE(t) ((t)->opts & TIMER_OPTS_USE_COMPARE)
+
+static char *id_to_name[] = {
+ [T0_BOT] = "timer0_0",
+ [T0_TOP] = "timer0_1",
+ [T1_BOT] = "timer1_0",
+ [T1_TOP] = "timer1_1",
+};
+
+static int timer32_config(struct timer_s *t)
+{
+ u32 tcr;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+ if (USING_COMPARE(t)) {
+ struct davinci_timer_instance *dtip =
+ soc_info->timer_info->timers;
+ int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id);
+
+ /*
+ * Next interrupt should be the current time reg value plus
+ * the new period (using 32-bit unsigned addition/wrapping
+ * to 0 on overflow). This assumes that the clocksource
+ * is setup to count to 2^32-1 before wrapping around to 0.
+ */
+ __raw_writel(__raw_readl(t->base + t->tim_off) + t->period,
+ t->base + dtip[event_timer].cmp_off);
+ } else {
+ tcr = __raw_readl(t->base + TCR);
+
+ /* disable timer */
+ tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
+ __raw_writel(tcr, t->base + TCR);
+
+ /* reset counter to zero, set new period */
+ __raw_writel(0, t->base + t->tim_off);
+ __raw_writel(t->period, t->base + t->prd_off);
+
+ /* Set enable mode */
+ if (t->opts & TIMER_OPTS_ONESHOT)
+ tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift;
+ else if (t->opts & TIMER_OPTS_PERIODIC)
+ tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
+
+ __raw_writel(tcr, t->base + TCR);
+ }
+ return 0;
+}
+
+static inline u32 timer32_read(struct timer_s *t)
+{
+ return __raw_readl(t->base + t->tim_off);
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_davinci;
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+/* called when 32-bit counter wraps */
+static irqreturn_t freerun_interrupt(int irq, void *dev_id)
+{
+ return IRQ_HANDLED;
+}
+
+static struct timer_s timers[] = {
+ [TID_CLOCKEVENT] = {
+ .name = "clockevent",
+ .opts = TIMER_OPTS_DISABLED,
+ .irqaction = {
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = timer_interrupt,
+ }
+ },
+ [TID_CLOCKSOURCE] = {
+ .name = "free-run counter",
+ .period = ~0,
+ .opts = TIMER_OPTS_PERIODIC,
+ .irqaction = {
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = freerun_interrupt,
+ }
+ },
+};
+
+static void __init timer_init(void)
+{
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
+ void __iomem *base[2];
+ int i;
+
+ /* Global init of each 64-bit timer as a whole */
+ for(i=0; i<2; i++) {
+ u32 tgcr;
+
+ base[i] = ioremap(dtip[i].base, SZ_4K);
+ if (WARN_ON(!base[i]))
+ continue;
+
+ /* Disabled, Internal clock source */
+ __raw_writel(0, base[i] + TCR);
+
+ /* reset both timers, no pre-scaler for timer34 */
+ tgcr = 0;
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Set both timers to unchained 32-bit */
+ tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Unreset timers */
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ __raw_writel(tgcr, base[i] + TGCR);
+
+ /* Init both counters to zero */
+ __raw_writel(0, base[i] + TIM12);
+ __raw_writel(0, base[i] + TIM34);
+ }
+
+ /* Init of each timer as a 32-bit timer */
+ for (i=0; i< ARRAY_SIZE(timers); i++) {
+ struct timer_s *t = &timers[i];
+ int timer = ID_TO_TIMER(t->id);
+ u32 irq;
+
+ t->base = base[timer];
+ if (!t->base)
+ continue;
+
+ if (IS_TIMER_BOT(t->id)) {
+ t->enamode_shift = 6;
+ t->tim_off = TIM12;
+ t->prd_off = PRD12;
+ irq = dtip[timer].bottom_irq;
+ } else {
+ t->enamode_shift = 22;
+ t->tim_off = TIM34;
+ t->prd_off = PRD34;
+ irq = dtip[timer].top_irq;
+ }
+
+ /* Register interrupt */
+ t->irqaction.name = t->name;
+ t->irqaction.dev_id = (void *)t;
+
+ if (t->irqaction.handler != NULL) {
+ irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
+ setup_irq(irq, &t->irqaction);
+ }
+ }
+}
+
+/*
+ * clocksource
+ */
+static cycle_t read_cycles(struct clocksource *cs)
+{
+ struct timer_s *t = &timers[TID_CLOCKSOURCE];
+
+ return (cycles_t)timer32_read(t);
+}
+
+/*
+ * Kernel assumes that sched_clock can be called early but may not have
+ * things ready yet.
+ */
+static cycle_t read_dummy(struct clocksource *cs)
+{
+ return 0;
+}
+
+
+static struct clocksource clocksource_davinci = {
+ .rating = 300,
+ .read = read_dummy,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Overwrite weak default sched_clock with something more precise
+ */
+unsigned long long notrace sched_clock(void)
+{
+ const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
+
+ return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
+ clocksource_davinci.shift);
+}
+
+/*
+ * clockevent
+ */
+static int davinci_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ struct timer_s *t = &timers[TID_CLOCKEVENT];
+
+ t->period = cycles;
+ timer32_config(t);
+ return 0;
+}
+
+static void davinci_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct timer_s *t = &timers[TID_CLOCKEVENT];
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ t->period = davinci_clock_tick_rate / (HZ);
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_PERIODIC;
+ timer32_config(t);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_ONESHOT;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ t->opts &= ~TIMER_OPTS_STATE_MASK;
+ t->opts |= TIMER_OPTS_DISABLED;
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_davinci = {
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = davinci_set_next_event,
+ .set_mode = davinci_set_mode,
+};
+
+
+static void __init davinci_timer_init(void)
+{
+ struct clk *timer_clk;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ unsigned int clockevent_id;
+ unsigned int clocksource_id;
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+ int i;
+
+ clockevent_id = soc_info->timer_info->clockevent_id;
+ clocksource_id = soc_info->timer_info->clocksource_id;
+
+ timers[TID_CLOCKEVENT].id = clockevent_id;
+ timers[TID_CLOCKSOURCE].id = clocksource_id;
+
+ /*
+ * If using same timer for both clock events & clocksource,
+ * a compare register must be used to generate an event interrupt.
+ * This is equivalent to a oneshot timer only (not periodic).
+ */
+ if (clockevent_id == clocksource_id) {
+ struct davinci_timer_instance *dtip =
+ soc_info->timer_info->timers;
+ int event_timer = ID_TO_TIMER(clockevent_id);
+
+ /* Only bottom timers can use compare regs */
+ if (IS_TIMER_TOP(clockevent_id))
+ pr_warning("davinci_timer_init: Invalid use"
+ " of system timers. Results unpredictable.\n");
+ else if ((dtip[event_timer].cmp_off == 0)
+ || (dtip[event_timer].cmp_irq == 0))
+ pr_warning("davinci_timer_init: Invalid timer instance"
+ " setup. Results unpredictable.\n");
+ else {
+ timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE;
+ clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT;
+ }
+ }
+
+ timer_clk = clk_get(NULL, "timer0");
+ BUG_ON(IS_ERR(timer_clk));
+ clk_enable(timer_clk);
+
+ /* init timer hw */
+ timer_init();
+
+ davinci_clock_tick_rate = clk_get_rate(timer_clk);
+
+ /* setup clocksource */
+ clocksource_davinci.read = read_cycles;
+ clocksource_davinci.name = id_to_name[clocksource_id];
+ if (clocksource_register_hz(&clocksource_davinci,
+ davinci_clock_tick_rate))
+ printk(err, clocksource_davinci.name);
+
+ /* setup clockevent */
+ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
+ clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
+ clockevent_davinci.shift);
+ clockevent_davinci.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_davinci);
+ clockevent_davinci.min_delta_ns = 50000; /* 50 usec */
+
+ clockevent_davinci.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_davinci);
+
+ for (i=0; i< ARRAY_SIZE(timers); i++)
+ timer32_config(&timers[i]);
+}
+
+struct sys_timer davinci_timer = {
+ .init = davinci_timer_init,
+};
+
+
+/* reset board using watchdog timer */
+void davinci_watchdog_reset(struct platform_device *pdev)
+{
+ u32 tgcr, wdtcr;
+ void __iomem *base;
+ struct clk *wd_clk;
+
+ base = ioremap(pdev->resource[0].start, SZ_4K);
+ if (WARN_ON(!base))
+ return;
+
+ wd_clk = clk_get(&pdev->dev, NULL);
+ if (WARN_ON(IS_ERR(wd_clk)))
+ return;
+ clk_enable(wd_clk);
+
+ /* disable, internal clock source */
+ __raw_writel(0, base + TCR);
+
+ /* reset timer, set mode to 64-bit watchdog, and unreset */
+ tgcr = 0;
+ __raw_writel(tgcr, base + TGCR);
+ tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT;
+ tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
+ (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
+ __raw_writel(tgcr, base + TGCR);
+
+ /* clear counter and period regs */
+ __raw_writel(0, base + TIM12);
+ __raw_writel(0, base + TIM34);
+ __raw_writel(0, base + PRD12);
+ __raw_writel(0, base + PRD34);
+
+ /* put watchdog in pre-active state */
+ wdtcr = __raw_readl(base + WDTCR);
+ wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ __raw_writel(wdtcr, base + WDTCR);
+
+ /* put watchdog in active state */
+ wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) |
+ (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT);
+ __raw_writel(wdtcr, base + WDTCR);
+
+ /* write an invalid value to the WDKEY field to trigger
+ * a watchdog reset */
+ wdtcr = 0x00004000;
+ __raw_writel(wdtcr, base + WDTCR);
+}
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
new file mode 100644
index 00000000..1b28fdd8
--- /dev/null
+++ b/arch/arm/mach-davinci/tnetv107x.c
@@ -0,0 +1,761 @@
+/*
+ * Texas Instruments TNETV107X SoC Support
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/cputype.h>
+#include <mach/psc.h>
+#include <mach/cp_intc.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_INTC_BASE 0x03000000
+#define TNETV107X_TIMER0_BASE 0x08086500
+#define TNETV107X_TIMER1_BASE 0x08086600
+#define TNETV107X_CHIP_CFG_BASE 0x08087000
+#define TNETV107X_GPIO_BASE 0x08088000
+#define TNETV107X_CLOCK_CONTROL_BASE 0x0808a000
+#define TNETV107X_PSC_BASE 0x0808b000
+
+/* Reference clock frequencies */
+#define OSC_FREQ_ONCHIP (24000 * 1000)
+#define OSC_FREQ_OFFCHIP_SYS (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_ETH (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_TDM (19200 * 1000)
+
+#define N_PLLS 3
+
+/* Clock Control Registers */
+struct clk_ctrl_regs {
+ u32 pll_bypass;
+ u32 _reserved0;
+ u32 gem_lrst;
+ u32 _reserved1;
+ u32 pll_unlock_stat;
+ u32 sys_unlock;
+ u32 eth_unlock;
+ u32 tdm_unlock;
+};
+
+/* SSPLL Registers */
+struct sspll_regs {
+ u32 modes;
+ u32 post_div;
+ u32 pre_div;
+ u32 mult_factor;
+ u32 divider_range;
+ u32 bw_divider;
+ u32 spr_amount;
+ u32 spr_rate_div;
+ u32 diag;
+};
+
+/* Watchdog Timer Registers */
+struct wdt_regs {
+ u32 kick_lock;
+ u32 kick;
+ u32 change_lock;
+ u32 change ;
+ u32 disable_lock;
+ u32 disable;
+ u32 prescale_lock;
+ u32 prescale;
+};
+
+static struct clk_ctrl_regs __iomem *clk_ctrl_regs;
+
+static struct sspll_regs __iomem *sspll_regs[N_PLLS];
+static int sspll_regs_base[N_PLLS] = { 0x40, 0x80, 0xc0 };
+
+/* PLL bypass bit shifts in clk_ctrl_regs->pll_bypass register */
+static u32 bypass_mask[N_PLLS] = { BIT(0), BIT(2), BIT(1) };
+
+/* offchip (external) reference clock frequencies */
+static u32 pll_ext_freq[] = {
+ OSC_FREQ_OFFCHIP_SYS,
+ OSC_FREQ_OFFCHIP_TDM,
+ OSC_FREQ_OFFCHIP_ETH
+};
+
+/* PSC control registers */
+static u32 psc_regs[] = { TNETV107X_PSC_BASE };
+
+/* Host map for interrupt controller */
+static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 };
+
+static unsigned long clk_sspll_recalc(struct clk *clk);
+
+/* Level 1 - the PLLs */
+#define define_pll_clk(cname, pll, divmask, base) \
+ static struct pll_data pll_##cname##_data = { \
+ .num = pll, \
+ .div_ratio_mask = divmask, \
+ .phys_base = base + \
+ TNETV107X_CLOCK_CONTROL_BASE, \
+ }; \
+ static struct clk pll_##cname##_clk = { \
+ .name = "pll_" #cname "_clk", \
+ .pll_data = &pll_##cname##_data, \
+ .flags = CLK_PLL, \
+ .recalc = clk_sspll_recalc, \
+ }
+
+define_pll_clk(sys, 0, 0x1ff, 0x600);
+define_pll_clk(tdm, 1, 0x0ff, 0x200);
+define_pll_clk(eth, 2, 0x0ff, 0x400);
+
+/* Level 2 - divided outputs from the PLLs */
+#define define_pll_div_clk(pll, cname, div) \
+ static struct clk pll##_##cname##_clk = { \
+ .name = #pll "_" #cname "_clk", \
+ .parent = &pll_##pll##_clk, \
+ .flags = CLK_PLL, \
+ .div_reg = PLLDIV##div, \
+ .set_rate = davinci_set_sysclk_rate, \
+ }
+
+define_pll_div_clk(sys, arm1176, 1);
+define_pll_div_clk(sys, dsp, 2);
+define_pll_div_clk(sys, ddr, 3);
+define_pll_div_clk(sys, full, 4);
+define_pll_div_clk(sys, lcd, 5);
+define_pll_div_clk(sys, vlynq_ref, 6);
+define_pll_div_clk(sys, tsc, 7);
+define_pll_div_clk(sys, half, 8);
+
+define_pll_div_clk(eth, 5mhz, 1);
+define_pll_div_clk(eth, 50mhz, 2);
+define_pll_div_clk(eth, 125mhz, 3);
+define_pll_div_clk(eth, 250mhz, 4);
+define_pll_div_clk(eth, 25mhz, 5);
+
+define_pll_div_clk(tdm, 0, 1);
+define_pll_div_clk(tdm, extra, 2);
+define_pll_div_clk(tdm, 1, 3);
+
+
+/* Level 3 - LPSC gated clocks */
+#define __lpsc_clk(cname, _parent, mod, flg) \
+ static struct clk clk_##cname = { \
+ .name = #cname, \
+ .parent = &_parent, \
+ .lpsc = TNETV107X_LPSC_##mod,\
+ .flags = flg, \
+ }
+
+#define lpsc_clk_enabled(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, ALWAYS_ENABLED)
+
+#define lpsc_clk(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, 0)
+
+lpsc_clk_enabled(arm, sys_arm1176_clk, ARM);
+lpsc_clk_enabled(gem, sys_dsp_clk, GEM);
+lpsc_clk_enabled(ddr2_phy, sys_ddr_clk, DDR2_PHY);
+lpsc_clk_enabled(tpcc, sys_full_clk, TPCC);
+lpsc_clk_enabled(tptc0, sys_full_clk, TPTC0);
+lpsc_clk_enabled(tptc1, sys_full_clk, TPTC1);
+lpsc_clk_enabled(ram, sys_full_clk, RAM);
+lpsc_clk_enabled(aemif, sys_full_clk, AEMIF);
+lpsc_clk_enabled(chipcfg, sys_half_clk, CHIP_CFG);
+lpsc_clk_enabled(rom, sys_half_clk, ROM);
+lpsc_clk_enabled(secctl, sys_half_clk, SECCTL);
+lpsc_clk_enabled(keymgr, sys_half_clk, KEYMGR);
+lpsc_clk_enabled(gpio, sys_half_clk, GPIO);
+lpsc_clk_enabled(debugss, sys_half_clk, DEBUGSS);
+lpsc_clk_enabled(system, sys_half_clk, SYSTEM);
+lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST);
+lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST);
+lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM);
+lpsc_clk_enabled(timer1, sys_half_clk, TIMER1);
+
+lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE);
+lpsc_clk(ethss, eth_125mhz_clk, ETHSS);
+lpsc_clk(tsc, sys_tsc_clk, TSC);
+lpsc_clk(uart0, sys_half_clk, UART0);
+lpsc_clk(uart1, sys_half_clk, UART1);
+lpsc_clk(uart2, sys_half_clk, UART2);
+lpsc_clk(pktsec, sys_half_clk, PKTSEC);
+lpsc_clk(keypad, sys_half_clk, KEYPAD);
+lpsc_clk(mdio, sys_half_clk, MDIO);
+lpsc_clk(sdio0, sys_half_clk, SDIO0);
+lpsc_clk(sdio1, sys_half_clk, SDIO1);
+lpsc_clk(timer0, sys_half_clk, TIMER0);
+lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP);
+lpsc_clk(ssp, sys_half_clk, SSP);
+lpsc_clk(tdm0, tdm_0_clk, TDM0);
+lpsc_clk(tdm1, tdm_1_clk, TDM1);
+lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ);
+lpsc_clk(mcdma, sys_half_clk, MCDMA);
+lpsc_clk(usbss, sys_half_clk, USBSS);
+lpsc_clk(usb0, clk_usbss, USB0);
+lpsc_clk(usb1, clk_usbss, USB1);
+lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII);
+lpsc_clk(imcop, sys_dsp_clk, IMCOP);
+lpsc_clk(spare, sys_half_clk, SPARE);
+
+/* LCD needs a full power down to clear controller state */
+__lpsc_clk(lcd, sys_lcd_clk, LCD, PSC_SWRSTDISABLE);
+
+
+/* Level 4 - leaf clocks for LPSC modules shared across drivers */
+static struct clk clk_rng = { .name = "rng", .parent = &clk_pktsec };
+static struct clk clk_pka = { .name = "pka", .parent = &clk_pktsec };
+
+static struct clk_lookup clks[] = {
+ CLK(NULL, "pll_sys_clk", &pll_sys_clk),
+ CLK(NULL, "pll_eth_clk", &pll_eth_clk),
+ CLK(NULL, "pll_tdm_clk", &pll_tdm_clk),
+ CLK(NULL, "sys_arm1176_clk", &sys_arm1176_clk),
+ CLK(NULL, "sys_dsp_clk", &sys_dsp_clk),
+ CLK(NULL, "sys_ddr_clk", &sys_ddr_clk),
+ CLK(NULL, "sys_full_clk", &sys_full_clk),
+ CLK(NULL, "sys_lcd_clk", &sys_lcd_clk),
+ CLK(NULL, "sys_vlynq_ref_clk", &sys_vlynq_ref_clk),
+ CLK(NULL, "sys_tsc_clk", &sys_tsc_clk),
+ CLK(NULL, "sys_half_clk", &sys_half_clk),
+ CLK(NULL, "eth_5mhz_clk", &eth_5mhz_clk),
+ CLK(NULL, "eth_50mhz_clk", &eth_50mhz_clk),
+ CLK(NULL, "eth_125mhz_clk", &eth_125mhz_clk),
+ CLK(NULL, "eth_250mhz_clk", &eth_250mhz_clk),
+ CLK(NULL, "eth_25mhz_clk", &eth_25mhz_clk),
+ CLK(NULL, "tdm_0_clk", &tdm_0_clk),
+ CLK(NULL, "tdm_extra_clk", &tdm_extra_clk),
+ CLK(NULL, "tdm_1_clk", &tdm_1_clk),
+ CLK(NULL, "clk_arm", &clk_arm),
+ CLK(NULL, "clk_gem", &clk_gem),
+ CLK(NULL, "clk_ddr2_phy", &clk_ddr2_phy),
+ CLK(NULL, "clk_tpcc", &clk_tpcc),
+ CLK(NULL, "clk_tptc0", &clk_tptc0),
+ CLK(NULL, "clk_tptc1", &clk_tptc1),
+ CLK(NULL, "clk_ram", &clk_ram),
+ CLK(NULL, "clk_mbx_lite", &clk_mbx_lite),
+ CLK("tnetv107x-fb.0", NULL, &clk_lcd),
+ CLK(NULL, "clk_ethss", &clk_ethss),
+ CLK(NULL, "aemif", &clk_aemif),
+ CLK(NULL, "clk_chipcfg", &clk_chipcfg),
+ CLK("tnetv107x-ts.0", NULL, &clk_tsc),
+ CLK(NULL, "clk_rom", &clk_rom),
+ CLK(NULL, "uart2", &clk_uart2),
+ CLK(NULL, "clk_pktsec", &clk_pktsec),
+ CLK("tnetv107x-rng.0", NULL, &clk_rng),
+ CLK("tnetv107x-pka.0", NULL, &clk_pka),
+ CLK(NULL, "clk_secctl", &clk_secctl),
+ CLK(NULL, "clk_keymgr", &clk_keymgr),
+ CLK("tnetv107x-keypad.0", NULL, &clk_keypad),
+ CLK(NULL, "clk_gpio", &clk_gpio),
+ CLK(NULL, "clk_mdio", &clk_mdio),
+ CLK("davinci_mmc.0", NULL, &clk_sdio0),
+ CLK(NULL, "uart0", &clk_uart0),
+ CLK(NULL, "uart1", &clk_uart1),
+ CLK(NULL, "timer0", &clk_timer0),
+ CLK(NULL, "timer1", &clk_timer1),
+ CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm),
+ CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp),
+ CLK("ti-ssp", NULL, &clk_ssp),
+ CLK(NULL, "clk_tdm0", &clk_tdm0),
+ CLK(NULL, "clk_vlynq", &clk_vlynq),
+ CLK(NULL, "clk_mcdma", &clk_mcdma),
+ CLK(NULL, "clk_usbss", &clk_usbss),
+ CLK(NULL, "clk_usb0", &clk_usb0),
+ CLK(NULL, "clk_usb1", &clk_usb1),
+ CLK(NULL, "clk_tdm1", &clk_tdm1),
+ CLK(NULL, "clk_debugss", &clk_debugss),
+ CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii),
+ CLK(NULL, "clk_system", &clk_system),
+ CLK(NULL, "clk_imcop", &clk_imcop),
+ CLK(NULL, "clk_spare", &clk_spare),
+ CLK("davinci_mmc.1", NULL, &clk_sdio1),
+ CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
+ CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
+ CLK(NULL, NULL, NULL),
+};
+
+static const struct mux_config pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ MUX_CFG(TNETV107X, ASR_A00, 0, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO32, 0, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A01, 0, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO33, 0, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A02, 0, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO34, 0, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A03, 0, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO35, 0, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A04, 0, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO36, 0, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A05, 0, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO37, 0, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A06, 1, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO38, 1, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A07, 1, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO39, 1, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A08, 1, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO40, 1, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A09, 1, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO41, 1, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A10, 1, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO42, 1, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A11, 1, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_0, 1, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A12, 2, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_1, 2, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A13, 2, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO43, 2, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A14, 2, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO44, 2, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A15, 2, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO45, 2, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A16, 2, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO46, 2, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A17, 2, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO47, 2, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A18, 3, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO48, 3, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_0, 3, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A19, 3, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO49, 3, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_0, 3, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A20, 3, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO50, 3, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_0, 3, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A21, 3, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO51, 3, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_0, 3, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A22, 3, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO52, 3, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_0, 3, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A23, 3, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO53, 3, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_0, 3, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_BA_1, 4, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO54, 4, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SYS_PLL_CLK, 4, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS0, 4, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS1, 4, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS2, 4, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM_PLL_CLK, 4, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS3, 4, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ETH_PHY_CLK, 4, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ASR_D00, 4, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO55, 4, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D01, 5, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO56, 5, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D02, 5, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO57, 5, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D03, 5, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO58, 5, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D04, 5, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_0, 5, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D05, 5, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_0, 5, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D06, 5, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO61_0, 5, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D07, 6, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_0, 6, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D08, 6, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_0, 6, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D09, 6, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_0, 6, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D10, 6, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_1, 6, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D11, 6, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_1, 6, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D12, 6, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_1, 6, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D13, 7, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_1, 7, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D14, 7, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_1, 7, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D15, 7, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_1, 7, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_OE, 7, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_2, 7, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_RNW, 7, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_0, 7, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WAIT, 7, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_0, 7, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE, 8, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_3, 8, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM0, 8, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO31, 8, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD17_0, 8, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM1, 8, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_0, 8, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, VLYNQ_CLK, 9, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO14, 9, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD19_0, 9, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD0, 9, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO15, 9, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_0, 9, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD1, 9, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO16, 9, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_0, 9, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD0, 9, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO17, 9, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_0, 9, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD1, 9, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO18, 9, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_0, 9, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, SDIO0_CLK, 10, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO19, 10, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_CMD, 10, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO20, 10, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA0, 10, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO21, 10, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA1, 10, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO22, 10, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA2, 10, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO23, 10, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA3, 10, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO24, 10, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EMU0, 11, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, EMU1, 11, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, RTCK, 12, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TRST_N, 12, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TCK, 12, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDI, 12, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDO, 12, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TMS, 12, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_CLK, 13, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_RX, 13, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_TX, 13, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_FS, 13, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R0, 14, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R1, 14, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R2, 14, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R3, 14, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R4, 14, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R5, 14, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R6, 15, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO12, 15, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_R7, 15, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO10, 15, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_C0, 15, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C1, 15, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C2, 15, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C3, 15, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C4, 16, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C5, 16, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C6, 16, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO13, 16, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TEST_CLK_IN, 16, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, KEYPAD_C7, 16, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO11, 16, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SSP0_0, 17, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_DCLK, 17, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_1, 17, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_1, 17, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_CS_N, 17, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_1, 17, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_2, 17, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_D, 17, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_1, 17, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_3, 17, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_RESETN, 17, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_1, 17, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_0, 18, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO25, 18, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_CTS, 18, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_1, 18, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO26, 18, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RD, 18, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_2, 18, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO27, 18, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RTS, 18, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_3, 18, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO28, 18, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_TD, 18, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, UART0_CTS, 19, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RD, 19, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RTS, 19, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_TD, 19, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_RD, 19, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_TD, 19, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_AC_NCS, 20, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_HSYNC_RNW, 20, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_VSYNC_A0, 20, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_MCLK, 20, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_0, 20, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PCLK_E, 20, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD00, 20, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD01, 21, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD02, 21, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD03, 21, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD04, 21, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD05, 21, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD06, 21, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD07, 22, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD08, 22, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_1, 22, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD09, 22, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_1, 22, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD10, 22, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_1, 22, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO61_1, 22, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD11, 22, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_1, 22, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD12, 22, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_1, 22, 25, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD13, 23, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_1, 23, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD14, 23, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_1, 23, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD15, 23, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_1, 23, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, EINT0, 24, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO08, 24, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EINT1, 24, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO09, 24, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO00, 24, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD20_2, 24, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_2, 24, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO01, 24, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD21_2, 24, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_1, 24, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO02, 24, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD22_2, 24, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO03, 24, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD23_2, 24, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO04, 25, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_1, 25, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB0_RXERR, 25, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO05, 25, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD17_1, 25, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_1, 25, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO06, 25, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD18, 25, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_2, 25, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO07, 25, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD19_1, 25, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB1_RXERR, 25, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ETH_PLL_CLK, 25, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, MDIO, 26, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, MDC, 26, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, AIC_MUTE_STAT_N, 26, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_CLK, 26, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNS_EN_N, 26, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_FS, 26, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HDS_EN_STAT_N, 26, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_TX, 26, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNF_EN_STAT_N, 26, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_RX, 26, 25, 0x1f, 0x04, false)
+#endif
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 irq_prios[TNETV107X_N_CP_INTC_IRQ] = {
+ /* fill in default priority 7 */
+ [0 ... (TNETV107X_N_CP_INTC_IRQ - 1)] = 7,
+ /* now override as needed, e.g. [xxx] = 5 */
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev 1.0",
+ },
+ {
+ .variant = 0x1,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev 1.1/1.2",
+ },
+};
+
+static struct davinci_timer_instance timer_instance[2] = {
+ {
+ .base = TNETV107X_TIMER0_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_0_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_0_TINT34,
+ },
+ {
+ .base = TNETV107X_TIMER1_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_1_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_1_TINT34,
+ },
+};
+
+static struct davinci_timer_info timer_info = {
+ .timers = timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+/*
+ * TNETV107X platforms do not use the static mappings from Davinci
+ * IO_PHYS/IO_VIRT. This SOC's interesting MMRs are at different addresses,
+ * and changing IO_PHYS would break away from existing Davinci SOCs.
+ *
+ * The primary impact of the current model is that IO_ADDRESS() is not to be
+ * used to map registers on TNETV107X.
+ *
+ * 1. The first chunk is for INTC: This needs to be mapped in via iotable
+ * because ioremap() does not seem to be operational at the time when
+ * irqs are initialized. Without this, consistent dma init bombs.
+ *
+ * 2. The second chunk maps in register areas that need to be populated into
+ * davinci_soc_info. Note that alignment restrictions come into play if
+ * low-level debug is enabled (see note in <mach/tnetv107x.h>).
+ */
+static struct map_desc io_desc[] = {
+ { /* INTC */
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_INTC_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ },
+ { /* Most of the rest */
+ .virtual = TNETV107X_IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_IO_BASE),
+ .length = IO_SIZE - SZ_1M,
+ .type = MT_DEVICE
+ },
+};
+
+static unsigned long clk_sspll_recalc(struct clk *clk)
+{
+ int pll;
+ unsigned long mult = 0, prediv = 1, postdiv = 1;
+ unsigned long ref = OSC_FREQ_ONCHIP, ret;
+ u32 tmp;
+
+ if (WARN_ON(!clk->pll_data))
+ return clk->rate;
+
+ if (!clk_ctrl_regs) {
+ void __iomem *tmp;
+
+ tmp = ioremap(TNETV107X_CLOCK_CONTROL_BASE, SZ_4K);
+
+ if (WARN(!tmp, "failed ioremap for clock control regs\n"))
+ return clk->parent ? clk->parent->rate : 0;
+
+ for (pll = 0; pll < N_PLLS; pll++)
+ sspll_regs[pll] = tmp + sspll_regs_base[pll];
+
+ clk_ctrl_regs = tmp;
+ }
+
+ pll = clk->pll_data->num;
+
+ tmp = __raw_readl(&clk_ctrl_regs->pll_bypass);
+ if (!(tmp & bypass_mask[pll])) {
+ mult = __raw_readl(&sspll_regs[pll]->mult_factor);
+ prediv = __raw_readl(&sspll_regs[pll]->pre_div) + 1;
+ postdiv = __raw_readl(&sspll_regs[pll]->post_div) + 1;
+ }
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (tmp & PLLCTL_CLKMODE)
+ ref = pll_ext_freq[pll];
+
+ clk->pll_data->input_rate = ref;
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (!(tmp & PLLCTL_PLLEN))
+ return ref;
+
+ ret = ref;
+ if (mult)
+ ret += ((unsigned long long)ref * mult) / 256;
+
+ ret /= (prediv * postdiv);
+
+ return ret;
+}
+
+static void tnetv107x_watchdog_reset(struct platform_device *pdev)
+{
+ struct wdt_regs __iomem *regs;
+
+ regs = ioremap(pdev->resource[0].start, SZ_4K);
+
+ /* disable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(0, &regs->disable);
+
+ /* program prescale */
+ __raw_writel(0x5a5a, &regs->prescale_lock);
+ __raw_writel(0xa5a5, &regs->prescale_lock);
+ __raw_writel(0, &regs->prescale);
+
+ /* program countdown */
+ __raw_writel(0x6666, &regs->change_lock);
+ __raw_writel(0xbbbb, &regs->change_lock);
+ __raw_writel(1, &regs->change);
+
+ /* enable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(1, &regs->disable);
+
+ /* kick */
+ __raw_writel(0x5555, &regs->kick_lock);
+ __raw_writel(0xaaaa, &regs->kick_lock);
+ __raw_writel(1, &regs->kick);
+}
+
+static struct davinci_soc_info tnetv107x_soc_info = {
+ .io_desc = io_desc,
+ .io_desc_num = ARRAY_SIZE(io_desc),
+ .ids = ids,
+ .ids_num = ARRAY_SIZE(ids),
+ .jtag_id_reg = TNETV107X_CHIP_CFG_BASE + 0x018,
+ .cpu_clks = clks,
+ .psc_bases = psc_regs,
+ .psc_bases_num = ARRAY_SIZE(psc_regs),
+ .pinmux_base = TNETV107X_CHIP_CFG_BASE + 0x150,
+ .pinmux_pins = pins,
+ .pinmux_pins_num = ARRAY_SIZE(pins),
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_base = TNETV107X_INTC_BASE,
+ .intc_irq_prios = irq_prios,
+ .intc_irq_num = TNETV107X_N_CP_INTC_IRQ,
+ .intc_host_map = intc_host_map,
+ .gpio_base = TNETV107X_GPIO_BASE,
+ .gpio_type = GPIO_TYPE_TNETV107X,
+ .gpio_num = TNETV107X_N_GPIO,
+ .timer_info = &timer_info,
+ .serial_dev = &tnetv107x_serial_device,
+ .reset = tnetv107x_watchdog_reset,
+ .reset_device = &tnetv107x_wdt_device,
+};
+
+void __init tnetv107x_init(void)
+{
+ davinci_common_init(&tnetv107x_soc_info);
+}
diff --git a/arch/arm/mach-davinci/usb.c b/arch/arm/mach-davinci/usb.c
new file mode 100644
index 00000000..23d2b6d9
--- /dev/null
+++ b/arch/arm/mach-davinci/usb.c
@@ -0,0 +1,180 @@
+/*
+ * USB
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <linux/usb/musb.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <mach/usb.h>
+
+#define DAVINCI_USB_OTG_BASE 0x01c64000
+
+#define DA8XX_USB0_BASE 0x01e00000
+#define DA8XX_USB1_BASE 0x01e25000
+
+#if defined(CONFIG_USB_MUSB_HDRC) || defined(CONFIG_USB_MUSB_HDRC_MODULE)
+static struct musb_hdrc_eps_bits musb_eps[] = {
+ { "ep1_tx", 8, },
+ { "ep1_rx", 8, },
+ { "ep2_tx", 8, },
+ { "ep2_rx", 8, },
+ { "ep3_tx", 5, },
+ { "ep3_rx", 5, },
+ { "ep4_tx", 5, },
+ { "ep4_rx", 5, },
+};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = true,
+ .dyn_fifo = true,
+ .soft_con = true,
+ .dma = true,
+
+ .num_eps = 5,
+ .dma_channels = 8,
+ .ram_bits = 10,
+ .eps_bits = musb_eps,
+};
+
+static struct musb_hdrc_platform_data usb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ /* OTG requires a Mini-AB connector */
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#elif defined(CONFIG_USB_MUSB_HOST)
+ .mode = MUSB_HOST,
+#endif
+ .clock = "usb",
+ .config = &musb_config,
+};
+
+static struct resource usb_resources[] = {
+ {
+ /* physical address */
+ .start = DAVINCI_USB_OTG_BASE,
+ .end = DAVINCI_USB_OTG_BASE + 0x5ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_USBINT,
+ .flags = IORESOURCE_IRQ,
+ .name = "mc"
+ },
+ {
+ /* placeholder for the dedicated CPPI IRQ */
+ .flags = IORESOURCE_IRQ,
+ .name = "dma"
+ },
+};
+
+static u64 usb_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device usb_dev = {
+ .name = "musb-davinci",
+ .id = -1,
+ .dev = {
+ .platform_data = &usb_data,
+ .dma_mask = &usb_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = usb_resources,
+ .num_resources = ARRAY_SIZE(usb_resources),
+};
+
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
+{
+ usb_data.power = mA > 510 ? 255 : mA / 2;
+ usb_data.potpgt = (potpgt_ms + 1) / 2;
+
+ if (cpu_is_davinci_dm646x()) {
+ /* Override the defaults as DM6467 uses different IRQs. */
+ usb_dev.resource[1].start = IRQ_DM646X_USBINT;
+ usb_dev.resource[2].start = IRQ_DM646X_USBDMAINT;
+ } else /* other devices don't have dedicated CPPI IRQ */
+ usb_dev.num_resources = 2;
+
+ platform_device_register(&usb_dev);
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb20_resources[] = {
+ {
+ .start = DA8XX_USB0_BASE,
+ .end = DA8XX_USB0_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_DA8XX_USB_INT,
+ .flags = IORESOURCE_IRQ,
+ .name = "mc",
+ },
+};
+
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+ usb_data.clock = "usb20";
+ usb_data.power = mA > 510 ? 255 : mA / 2;
+ usb_data.potpgt = (potpgt + 1) / 2;
+
+ usb_dev.resource = da8xx_usb20_resources;
+ usb_dev.num_resources = ARRAY_SIZE(da8xx_usb20_resources);
+ usb_dev.name = "musb-da8xx";
+
+ return platform_device_register(&usb_dev);
+}
+#endif /* CONFIG_DAVINCI_DA8XX */
+
+#else
+
+void __init davinci_setup_usb(unsigned mA, unsigned potpgt_ms)
+{
+}
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+int __init da8xx_register_usb20(unsigned mA, unsigned potpgt)
+{
+ return 0;
+}
+#endif
+
+#endif /* CONFIG_USB_MUSB_HDRC */
+
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+static struct resource da8xx_usb11_resources[] = {
+ [0] = {
+ .start = DA8XX_USB1_BASE,
+ .end = DA8XX_USB1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DA8XX_IRQN,
+ .end = IRQ_DA8XX_IRQN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 da8xx_usb11_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device da8xx_usb11_device = {
+ .name = "ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &da8xx_usb11_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(da8xx_usb11_resources),
+ .resource = da8xx_usb11_resources,
+};
+
+int __init da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata)
+{
+ da8xx_usb11_device.dev.platform_data = pdata;
+ return platform_device_register(&da8xx_usb11_device);
+}
+#endif /* CONFIG_DAVINCI_DA8XX */
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
new file mode 100644
index 00000000..dd937c52
--- /dev/null
+++ b/arch/arm/mach-dove/Kconfig
@@ -0,0 +1,20 @@
+if ARCH_DOVE
+
+menu "Marvell Dove Implementations"
+
+config MACH_DOVE_DB
+ bool "Marvell DB-MV88AP510 Development Board"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell DB-MV88AP510 Development Board.
+
+config MACH_CM_A510
+ bool "CompuLab CM-A510 Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ CompuLab CM-A510 Board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-dove/Makefile b/arch/arm/mach-dove/Makefile
new file mode 100644
index 00000000..fa0f0185
--- /dev/null
+++ b/arch/arm/mach-dove/Makefile
@@ -0,0 +1,4 @@
+obj-y += common.o addr-map.o irq.o pcie.o mpp.o
+
+obj-$(CONFIG_MACH_DOVE_DB) += dove-db-setup.o
+obj-$(CONFIG_MACH_CM_A510) += cm-a510.o
diff --git a/arch/arm/mach-dove/Makefile.boot b/arch/arm/mach-dove/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-dove/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-dove/addr-map.c b/arch/arm/mach-dove/addr-map.c
new file mode 100644
index 00000000..00be4fc2
--- /dev/null
+++ b/arch/arm/mach-dove/addr-map.c
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mach-dove/addr-map.c
+ *
+ * Address map functions for Marvell Dove 88AP510 SoC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR 0x0
+#define TARGET_BOOTROM 0x1
+#define TARGET_CESA 0x3
+#define TARGET_PCIE0 0x4
+#define TARGET_PCIE1 0x8
+#define TARGET_SCRATCHPAD 0xd
+
+#define ATTR_CESA 0x01
+#define ATTR_BOOTROM 0xfd
+#define ATTR_DEV_SPI0_ROM 0xfe
+#define ATTR_DEV_SPI1_ROM 0xfb
+#define ATTR_PCIE_IO 0xe0
+#define ATTR_PCIE_MEM 0xe8
+#define ATTR_SCRATCHPAD 0x0
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_CTRL(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x0)
+#define WIN_BASE(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x4)
+#define WIN_REMAP_LO(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0x8)
+#define WIN_REMAP_HI(n) (BRIDGE_VIRT_BASE + ((n) << 4) + 0xc)
+
+struct mbus_dram_target_info dove_mbus_dram_info;
+
+static inline void __iomem *ddr_map_sc(int i)
+{
+ return (void __iomem *)(DOVE_MC_VIRT_BASE + 0x100 + ((i) << 4));
+}
+
+static int cpu_win_can_remap(int win)
+{
+ if (win < 4)
+ return 1;
+
+ return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+ u8 target, u8 attr, int remap)
+{
+ u32 ctrl;
+
+ base &= 0xffff0000;
+ ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+ writel(base, WIN_BASE(win));
+ writel(ctrl, WIN_CTRL(win));
+ if (cpu_win_can_remap(win)) {
+ if (remap < 0)
+ remap = base;
+ writel(remap & 0xffff0000, WIN_REMAP_LO(win));
+ writel(0, WIN_REMAP_HI(win));
+ }
+}
+
+void __init dove_setup_cpu_mbus(void)
+{
+ int i;
+ int cs;
+
+ /*
+ * First, disable and clear windows.
+ */
+ for (i = 0; i < 8; i++) {
+ writel(0, WIN_BASE(i));
+ writel(0, WIN_CTRL(i));
+ if (cpu_win_can_remap(i)) {
+ writel(0, WIN_REMAP_LO(i));
+ writel(0, WIN_REMAP_HI(i));
+ }
+ }
+
+ /*
+ * Setup windows for PCIe IO+MEM space.
+ */
+ setup_cpu_win(0, DOVE_PCIE0_IO_PHYS_BASE, DOVE_PCIE0_IO_SIZE,
+ TARGET_PCIE0, ATTR_PCIE_IO, DOVE_PCIE0_IO_BUS_BASE);
+ setup_cpu_win(1, DOVE_PCIE1_IO_PHYS_BASE, DOVE_PCIE1_IO_SIZE,
+ TARGET_PCIE1, ATTR_PCIE_IO, DOVE_PCIE1_IO_BUS_BASE);
+ setup_cpu_win(2, DOVE_PCIE0_MEM_PHYS_BASE, DOVE_PCIE0_MEM_SIZE,
+ TARGET_PCIE0, ATTR_PCIE_MEM, -1);
+ setup_cpu_win(3, DOVE_PCIE1_MEM_PHYS_BASE, DOVE_PCIE1_MEM_SIZE,
+ TARGET_PCIE1, ATTR_PCIE_MEM, -1);
+
+ /*
+ * Setup window for CESA engine.
+ */
+ setup_cpu_win(4, DOVE_CESA_PHYS_BASE, DOVE_CESA_SIZE,
+ TARGET_CESA, ATTR_CESA, -1);
+
+ /*
+ * Setup the Window to the BootROM for Standby and Sleep Resume
+ */
+ setup_cpu_win(5, DOVE_BOOTROM_PHYS_BASE, DOVE_BOOTROM_SIZE,
+ TARGET_BOOTROM, ATTR_BOOTROM, -1);
+
+ /*
+ * Setup the Window to the PMU Scratch Pad space
+ */
+ setup_cpu_win(6, DOVE_SCRATCHPAD_PHYS_BASE, DOVE_SCRATCHPAD_SIZE,
+ TARGET_SCRATCHPAD, ATTR_SCRATCHPAD, -1);
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ dove_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ for (i = 0, cs = 0; i < 2; i++) {
+ u32 map = readl(ddr_map_sc(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (map & 1) {
+ struct mbus_dram_window *w;
+
+ w = &dove_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0; /* CS address decoding done inside */
+ /* the DDR controller, no need to */
+ /* provide attributes */
+ w->base = map & 0xff800000;
+ w->size = 0x100000 << (((map & 0x000f0000) >> 16) - 4);
+ }
+ }
+ dove_mbus_dram_info.num_cs = cs;
+}
diff --git a/arch/arm/mach-dove/cm-a510.c b/arch/arm/mach-dove/cm-a510.c
new file mode 100644
index 00000000..03e11f9d
--- /dev/null
+++ b/arch/arm/mach-dove/cm-a510.c
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-dove/cm-a510.c
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Konstantin Sinyuk <kostyas@compulab.co.il>
+ *
+ * Based on Marvell DB-MV88AP510-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/dove.h>
+
+#include "common.h"
+
+static struct mv643xx_eth_platform_data cm_a510_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static struct mv_sata_platform_data cm_a510_sata_data = {
+ .n_ports = 1,
+};
+
+/*
+ * SPI Devices:
+ * SPI0: 1M Flash Winbond w25q32bv
+ */
+static const struct flash_platform_data cm_a510_spi_flash_data = {
+ .type = "w25q32bv",
+};
+
+static struct spi_board_info __initdata cm_a510_spi_flash_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &cm_a510_spi_flash_data,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static int __init cm_a510_pci_init(void)
+{
+ if (machine_is_cm_a510())
+ dove_pcie_init(1, 1);
+
+ return 0;
+}
+
+subsys_initcall(cm_a510_pci_init);
+
+/* Board Init */
+static void __init cm_a510_init(void)
+{
+ /*
+ * Basic Dove setup. Needs to be called early.
+ */
+ dove_init();
+
+ dove_ge00_init(&cm_a510_ge00_data);
+ dove_ehci0_init();
+ dove_ehci1_init();
+ dove_sata_init(&cm_a510_sata_data);
+ dove_sdio0_init();
+ dove_sdio1_init();
+ dove_spi0_init();
+ dove_spi1_init();
+ dove_uart0_init();
+ dove_uart1_init();
+ dove_i2c_init();
+ spi_register_board_info(cm_a510_spi_flash_info,
+ ARRAY_SIZE(cm_a510_spi_flash_info));
+}
+
+MACHINE_START(CM_A510, "Compulab CM-A510 Board")
+ .boot_params = 0x00000100,
+ .init_machine = cm_a510_init,
+ .map_io = dove_map_io,
+ .init_early = dove_init_early,
+ .init_irq = dove_init_irq,
+ .timer = &dove_timer,
+MACHINE_END
diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c
new file mode 100644
index 00000000..46c04498
--- /dev/null
+++ b/arch/arm/mach-dove/common.c
@@ -0,0 +1,297 @@
+/*
+ * arch/arm/mach-dove/common.c
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/mbus.h>
+#include <linux/ata_platform.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/timex.h>
+#include <asm/hardware/cache-tauros2.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/pci.h>
+#include <mach/dove.h>
+#include <mach/bridge-regs.h>
+#include <asm/mach/arch.h>
+#include <linux/irq.h>
+#include <plat/time.h>
+#include <plat/ehci-orion.h>
+#include <plat/common.h>
+#include "common.h"
+
+static int get_tclk(void);
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc dove_io_desc[] __initdata = {
+ {
+ .virtual = DOVE_SB_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_SB_REGS_PHYS_BASE),
+ .length = DOVE_SB_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = DOVE_NB_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
+ .length = DOVE_NB_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = DOVE_PCIE0_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
+ .length = DOVE_PCIE0_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = DOVE_PCIE1_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
+ .length = DOVE_PCIE1_IO_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init dove_map_io(void)
+{
+ iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc));
+}
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+void __init dove_ehci0_init(void)
+{
+ orion_ehci_init(&dove_mbus_dram_info,
+ DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0, EHCI_PHY_NA);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init dove_ehci1_init(void)
+{
+ orion_ehci_1_init(&dove_mbus_dram_info,
+ DOVE_USB1_PHYS_BASE, IRQ_DOVE_USB1);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ orion_ge00_init(eth_data, &dove_mbus_dram_info,
+ DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
+ 0, get_tclk());
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+void __init dove_rtc_init(void)
+{
+ orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
+{
+ orion_sata_init(sata_data, &dove_mbus_dram_info,
+ DOVE_SATA_PHYS_BASE, IRQ_DOVE_SATA);
+
+}
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+void __init dove_uart0_init(void)
+{
+ orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE,
+ IRQ_DOVE_UART_0, get_tclk());
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init dove_uart1_init(void)
+{
+ orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
+ IRQ_DOVE_UART_1, get_tclk());
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+void __init dove_uart2_init(void)
+{
+ orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
+ IRQ_DOVE_UART_2, get_tclk());
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+void __init dove_uart3_init(void)
+{
+ orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
+ IRQ_DOVE_UART_3, get_tclk());
+}
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+void __init dove_spi0_init(void)
+{
+ orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk());
+}
+
+void __init dove_spi1_init(void)
+{
+ orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk());
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+void __init dove_i2c_init(void)
+{
+ orion_i2c_init(DOVE_I2C_PHYS_BASE, IRQ_DOVE_I2C, 10);
+}
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init dove_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+}
+
+static int get_tclk(void)
+{
+ /* use DOVE_RESET_SAMPLE_HI/LO to detect tclk */
+ return 166666667;
+}
+
+static void dove_timer_init(void)
+{
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_DOVE_BRIDGE, get_tclk());
+}
+
+struct sys_timer dove_timer = {
+ .init = dove_timer_init,
+};
+
+/*****************************************************************************
+ * XOR 0
+ ****************************************************************************/
+void __init dove_xor0_init(void)
+{
+ orion_xor0_init(&dove_mbus_dram_info,
+ DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
+ IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
+}
+
+/*****************************************************************************
+ * XOR 1
+ ****************************************************************************/
+void __init dove_xor1_init(void)
+{
+ orion_xor1_init(DOVE_XOR1_PHYS_BASE, DOVE_XOR1_HIGH_PHYS_BASE,
+ IRQ_DOVE_XOR_10, IRQ_DOVE_XOR_11);
+}
+
+/*****************************************************************************
+ * SDIO
+ ****************************************************************************/
+static u64 sdio_dmamask = DMA_BIT_MASK(32);
+
+static struct resource dove_sdio0_resources[] = {
+ {
+ .start = DOVE_SDIO0_PHYS_BASE,
+ .end = DOVE_SDIO0_PHYS_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_DOVE_SDIO0,
+ .end = IRQ_DOVE_SDIO0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dove_sdio0 = {
+ .name = "sdhci-dove",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sdio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = dove_sdio0_resources,
+ .num_resources = ARRAY_SIZE(dove_sdio0_resources),
+};
+
+void __init dove_sdio0_init(void)
+{
+ platform_device_register(&dove_sdio0);
+}
+
+static struct resource dove_sdio1_resources[] = {
+ {
+ .start = DOVE_SDIO1_PHYS_BASE,
+ .end = DOVE_SDIO1_PHYS_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_DOVE_SDIO1,
+ .end = IRQ_DOVE_SDIO1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dove_sdio1 = {
+ .name = "sdhci-dove",
+ .id = 1,
+ .dev = {
+ .dma_mask = &sdio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = dove_sdio1_resources,
+ .num_resources = ARRAY_SIZE(dove_sdio1_resources),
+};
+
+void __init dove_sdio1_init(void)
+{
+ platform_device_register(&dove_sdio1);
+}
+
+void __init dove_init(void)
+{
+ int tclk;
+
+ tclk = get_tclk();
+
+ printk(KERN_INFO "Dove 88AP510 SoC, ");
+ printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init();
+#endif
+ dove_setup_cpu_mbus();
+
+ /* internal devices that every board has */
+ dove_rtc_init();
+ dove_xor0_init();
+ dove_xor1_init();
+}
diff --git a/arch/arm/mach-dove/common.h b/arch/arm/mach-dove/common.h
new file mode 100644
index 00000000..6a2046e4
--- /dev/null
+++ b/arch/arm/mach-dove/common.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-dove/common.h
+ *
+ * Core functions for Marvell Dove 88AP510 System On Chip
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_DOVE_COMMON_H
+#define __ARCH_DOVE_COMMON_H
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+extern struct sys_timer dove_timer;
+extern struct mbus_dram_target_info dove_mbus_dram_info;
+
+/*
+ * Basic Dove init functions used early by machine-setup.
+ */
+void dove_map_io(void);
+void dove_init(void);
+void dove_init_early(void);
+void dove_init_irq(void);
+void dove_setup_cpu_mbus(void);
+void dove_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void dove_sata_init(struct mv_sata_platform_data *sata_data);
+void dove_pcie_init(int init_port0, int init_port1);
+void dove_ehci0_init(void);
+void dove_ehci1_init(void);
+void dove_uart0_init(void);
+void dove_uart1_init(void);
+void dove_uart2_init(void);
+void dove_uart3_init(void);
+void dove_spi0_init(void);
+void dove_spi1_init(void);
+void dove_i2c_init(void);
+void dove_sdio0_init(void);
+void dove_sdio1_init(void);
+
+#endif
diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c
new file mode 100644
index 00000000..2ac34ecf
--- /dev/null
+++ b/arch/arm/mach-dove/dove-db-setup.c
@@ -0,0 +1,103 @@
+/*
+ * arch/arm/mach-dove/dove-db-setup.c
+ *
+ * Marvell DB-MV88AP510-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/pci.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/dove.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data dove_db_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR_DEFAULT,
+};
+
+static struct mv_sata_platform_data dove_db_sata_data = {
+ .n_ports = 1,
+};
+
+/*****************************************************************************
+ * SPI Devices:
+ * SPI0: 4M Flash ST-M25P32-VMF6P
+ ****************************************************************************/
+static const struct flash_platform_data dove_db_spi_flash_data = {
+ .type = "m25p64",
+};
+
+static struct spi_board_info __initdata dove_db_spi_flash_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &dove_db_spi_flash_data,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+static int __init dove_db_pci_init(void)
+{
+ if (machine_is_dove_db())
+ dove_pcie_init(1, 1);
+
+ return 0;
+}
+
+subsys_initcall(dove_db_pci_init);
+
+/*****************************************************************************
+ * Board Init
+ ****************************************************************************/
+static void __init dove_db_init(void)
+{
+ /*
+ * Basic Dove setup. Needs to be called early.
+ */
+ dove_init();
+
+ dove_ge00_init(&dove_db_ge00_data);
+ dove_ehci0_init();
+ dove_ehci1_init();
+ dove_sata_init(&dove_db_sata_data);
+ dove_sdio0_init();
+ dove_sdio1_init();
+ dove_spi0_init();
+ dove_spi1_init();
+ dove_uart0_init();
+ dove_uart1_init();
+ dove_i2c_init();
+ spi_register_board_info(dove_db_spi_flash_info,
+ ARRAY_SIZE(dove_db_spi_flash_info));
+}
+
+MACHINE_START(DOVE_DB, "Marvell DB-MV88AP510-BP Development Board")
+ .boot_params = 0x00000100,
+ .init_machine = dove_db_init,
+ .map_io = dove_map_io,
+ .init_early = dove_init_early,
+ .init_irq = dove_init_irq,
+ .timer = &dove_timer,
+MACHINE_END
diff --git a/arch/arm/mach-dove/include/mach/bridge-regs.h b/arch/arm/mach-dove/include/mach/bridge-regs.h
new file mode 100644
index 00000000..226949dc
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/bridge-regs.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-dove/include/mach/bridge-regs.h
+ *
+ * Mbus-L to Mbus Bridge Registers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/dove.h>
+
+#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0000)
+
+#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_CTRL_PCIE0_LINK 0x00000001
+#define CPU_RESET 0x00000002
+#define CPU_CTRL_PCIE1_LINK 0x00000008
+
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define SOFT_RESET_OUT_EN 0x00000004
+
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SOFT_RESET 0x00000001
+
+#define BRIDGE_INT_TIMER1_CLR (~0x0004)
+
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_CAUSE_LOW_OFF 0x0000
+#define IRQ_MASK_LOW_OFF 0x0004
+#define FIQ_MASK_LOW_OFF 0x0008
+#define ENDPOINT_MASK_LOW_OFF 0x000c
+#define IRQ_CAUSE_HIGH_OFF 0x0010
+#define IRQ_MASK_HIGH_OFF 0x0014
+#define FIQ_MASK_HIGH_OFF 0x0018
+#define ENDPOINT_MASK_HIGH_OFF 0x001c
+#define PCIE_INTERRUPT_MASK_OFF 0x0020
+
+#define IRQ_MASK_LOW (IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)
+#define FIQ_MASK_LOW (IRQ_VIRT_BASE + FIQ_MASK_LOW_OFF)
+#define ENDPOINT_MASK_LOW (IRQ_VIRT_BASE + ENDPOINT_MASK_LOW_OFF)
+#define IRQ_MASK_HIGH (IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)
+#define FIQ_MASK_HIGH (IRQ_VIRT_BASE + FIQ_MASK_HIGH_OFF)
+#define ENDPOINT_MASK_HIGH (IRQ_VIRT_BASE + ENDPOINT_MASK_HIGH_OFF)
+#define PCIE_INTERRUPT_MASK (IRQ_VIRT_BASE + PCIE_INTERRUPT_MASK_OFF)
+
+#define POWER_MANAGEMENT (BRIDGE_VIRT_BASE | 0x011c)
+
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/debug-macro.S b/arch/arm/mach-dove/include/mach/debug-macro.S
new file mode 100644
index 00000000..da8bf2ba
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-dove/include/mach/debug-macro.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 <mach/bridge-regs.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =DOVE_SB_REGS_PHYS_BASE
+ ldr \rv, =DOVE_SB_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
new file mode 100644
index 00000000..b20ec9af
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -0,0 +1,188 @@
+/*
+ * arch/arm/mach-dove/include/mach/dove.h
+ *
+ * Generic definitions for Marvell Dove 88AP510 SoC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_DOVE_H
+#define __ASM_ARCH_DOVE_H
+
+#include <mach/vmalloc.h>
+
+/*
+ * Marvell Dove address maps.
+ *
+ * phys virt size
+ * c8000000 fdb00000 1M Cryptographic SRAM
+ * e0000000 @runtime 128M PCIe-0 Memory space
+ * e8000000 @runtime 128M PCIe-1 Memory space
+ * f1000000 fde00000 8M on-chip south-bridge registers
+ * f1800000 fe600000 8M on-chip north-bridge registers
+ * f2000000 fee00000 1M PCIe-0 I/O space
+ * f2100000 fef00000 1M PCIe-1 I/O space
+ */
+
+#define DOVE_CESA_PHYS_BASE 0xc8000000
+#define DOVE_CESA_VIRT_BASE 0xfdb00000
+#define DOVE_CESA_SIZE SZ_1M
+
+#define DOVE_PCIE0_MEM_PHYS_BASE 0xe0000000
+#define DOVE_PCIE0_MEM_SIZE SZ_128M
+
+#define DOVE_PCIE1_MEM_PHYS_BASE 0xe8000000
+#define DOVE_PCIE1_MEM_SIZE SZ_128M
+
+#define DOVE_BOOTROM_PHYS_BASE 0xf8000000
+#define DOVE_BOOTROM_SIZE SZ_128M
+
+#define DOVE_SCRATCHPAD_PHYS_BASE 0xf0000000
+#define DOVE_SCRATCHPAD_VIRT_BASE 0xfdd00000
+#define DOVE_SCRATCHPAD_SIZE SZ_1M
+
+#define DOVE_SB_REGS_PHYS_BASE 0xf1000000
+#define DOVE_SB_REGS_VIRT_BASE 0xfde00000
+#define DOVE_SB_REGS_SIZE SZ_8M
+
+#define DOVE_NB_REGS_PHYS_BASE 0xf1800000
+#define DOVE_NB_REGS_VIRT_BASE 0xfe600000
+#define DOVE_NB_REGS_SIZE SZ_8M
+
+#define DOVE_PCIE0_IO_PHYS_BASE 0xf2000000
+#define DOVE_PCIE0_IO_VIRT_BASE 0xfee00000
+#define DOVE_PCIE0_IO_BUS_BASE 0x00000000
+#define DOVE_PCIE0_IO_SIZE SZ_1M
+
+#define DOVE_PCIE1_IO_PHYS_BASE 0xf2100000
+#define DOVE_PCIE1_IO_VIRT_BASE 0xfef00000
+#define DOVE_PCIE1_IO_BUS_BASE 0x00100000
+#define DOVE_PCIE1_IO_SIZE SZ_1M
+
+/*
+ * Dove Core Registers Map
+ */
+
+/* SPI, I2C, UART */
+#define DOVE_I2C_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x11000)
+#define DOVE_UART0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12000)
+#define DOVE_UART0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12000)
+#define DOVE_UART1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12100)
+#define DOVE_UART1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12100)
+#define DOVE_UART2_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12200)
+#define DOVE_UART2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12200)
+#define DOVE_UART3_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x12300)
+#define DOVE_UART3_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x12300)
+#define DOVE_SPI0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x10600)
+#define DOVE_SPI1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x14600)
+
+/* North-South Bridge */
+#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x20000)
+
+/* Cryptographic Engine */
+#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x30000)
+
+/* PCIe 0 */
+#define DOVE_PCIE0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x40000)
+
+/* USB */
+#define DOVE_USB0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x50000)
+#define DOVE_USB1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x51000)
+
+/* XOR 0 Engine */
+#define DOVE_XOR0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60800)
+#define DOVE_XOR0_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60800)
+#define DOVE_XOR0_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60A00)
+#define DOVE_XOR0_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60A00)
+
+/* XOR 1 Engine */
+#define DOVE_XOR1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60900)
+#define DOVE_XOR1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60900)
+#define DOVE_XOR1_HIGH_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x60B00)
+#define DOVE_XOR1_HIGH_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x60B00)
+
+/* Gigabit Ethernet */
+#define DOVE_GE00_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x70000)
+
+/* PCIe 1 */
+#define DOVE_PCIE1_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x80000)
+
+/* CAFE */
+#define DOVE_SDIO0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x92000)
+#define DOVE_SDIO1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x90000)
+#define DOVE_CAM_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x94000)
+#define DOVE_CAFE_WIN_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x98000)
+
+/* SATA */
+#define DOVE_SATA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xa0000)
+
+/* I2S/SPDIF */
+#define DOVE_AUD0_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb0000)
+#define DOVE_AUD1_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xb4000)
+
+/* NAND Flash Controller */
+#define DOVE_NFC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xc0000)
+
+/* MPP, GPIO, Reset Sampling */
+#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200)
+#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10)
+#define DOVE_RESET_SAMPLE_LO (DOVE_MPP_VIRT_BASE | 0x014)
+#define DOVE_RESET_SAMPLE_HI (DOVE_MPP_VIRT_BASE | 0x018)
+#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400)
+#define DOVE_GPIO_HI_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0420)
+#define DOVE_GPIO2_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe8400)
+#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
+#define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1)
+#define DOVE_NAND_GPIO_EN (1 << 0)
+#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
+#define DOVE_SPI_GPIO_SEL (1 << 5)
+#define DOVE_UART1_GPIO_SEL (1 << 4)
+#define DOVE_AU1_GPIO_SEL (1 << 3)
+#define DOVE_CAM_GPIO_SEL (1 << 2)
+#define DOVE_SD1_GPIO_SEL (1 << 1)
+#define DOVE_SD0_GPIO_SEL (1 << 0)
+
+/* Power Management */
+#define DOVE_PMU_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0000)
+#define DOVE_PMU_SIG_CTRL (DOVE_PMU_VIRT_BASE + 0x802c)
+
+/* Real Time Clock */
+#define DOVE_RTC_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xd8500)
+
+/* AC97 */
+#define DOVE_AC97_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe0000)
+#define DOVE_AC97_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe0000)
+
+/* Peripheral DMA */
+#define DOVE_PDMA_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xe4000)
+#define DOVE_PDMA_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe4000)
+
+#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C)
+#define DOVE_TWSI_ENABLE_OPTION1 (1 << 7)
+#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030)
+#define DOVE_TWSI_ENABLE_OPTION2 (1 << 20)
+#define DOVE_TWSI_ENABLE_OPTION3 (1 << 21)
+#define DOVE_TWSI_OPTION3_GPIO (1 << 22)
+#define DOVE_SSP_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0xec000)
+#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034)
+#define DOVE_SSP_ON_AU1 (1 << 0)
+#define DOVE_SSP_CLOCK_ENABLE (1 << 1)
+#define DOVE_SSP_BPB_CLOCK_SRC_SSP (1 << 11)
+/* Memory Controller */
+#define DOVE_MC_VIRT_BASE (DOVE_NB_REGS_VIRT_BASE | 0x00000)
+
+/* LCD Controller */
+#define DOVE_LCD_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD1_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x20000)
+#define DOVE_LCD2_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x10000)
+#define DOVE_LCD_DCON_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x30000)
+
+/* Graphic Engine */
+#define DOVE_GPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x40000)
+
+/* Video Engine */
+#define DOVE_VPU_PHYS_BASE (DOVE_NB_REGS_PHYS_BASE | 0x400000)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/entry-macro.S b/arch/arm/mach-dove/include/mach/entry-macro.S
new file mode 100644
index 00000000..e84c78c2
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-dove/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell Dove platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/bridge-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IRQ_VIRT_BASE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ @ check low interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
+ mov \irqnr, #31
+ ands \irqstat, \irqstat, \tmp
+
+ @ if no low interrupts set, check high interrupts
+ ldreq \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+ ldreq \tmp, [\base, #IRQ_MASK_HIGH_OFF]
+ moveq \irqnr, #63
+ andeqs \irqstat, \irqstat, \tmp
+
+ @ find first active interrupt source
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-dove/include/mach/gpio.h b/arch/arm/mach-dove/include/mach/gpio.h
new file mode 100644
index 00000000..e7e5101e
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/gpio.h
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-dove/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-dove/include/mach/hardware.h b/arch/arm/mach-dove/include/mach/hardware.h
new file mode 100644
index 00000000..32b0826e
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/hardware.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-dove/include/mach/hardware.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "dove.h"
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE DOVE_PCIE0_MEM_PHYS_BASE
+
+
+/* Macros below are required for compatibility with PXA AC'97 driver. */
+#define __REG(x) (*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \
+ DOVE_SB_REGS_VIRT_BASE)))
+#define __PREG(x) (((u32)&(x)) - DOVE_SB_REGS_VIRT_BASE + \
+ DOVE_SB_REGS_PHYS_BASE)
+#endif
diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h
new file mode 100644
index 00000000..eb4936ff
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-dove/include/mach/io.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "dove.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \
+ DOVE_PCIE0_IO_VIRT_BASE))
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/irqs.h b/arch/arm/mach-dove/include/mach/irqs.h
new file mode 100644
index 00000000..03d401d2
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/irqs.h
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-dove/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell Dove 88AP510 SoC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * Dove Low Interrupt Controller
+ */
+#define IRQ_DOVE_BRIDGE 0
+#define IRQ_DOVE_H2C 1
+#define IRQ_DOVE_C2H 2
+#define IRQ_DOVE_NAND 3
+#define IRQ_DOVE_PDMA 4
+#define IRQ_DOVE_SPI1 5
+#define IRQ_DOVE_SPI0 6
+#define IRQ_DOVE_UART_0 7
+#define IRQ_DOVE_UART_1 8
+#define IRQ_DOVE_UART_2 9
+#define IRQ_DOVE_UART_3 10
+#define IRQ_DOVE_I2C 11
+#define IRQ_DOVE_GPIO_0_7 12
+#define IRQ_DOVE_GPIO_8_15 13
+#define IRQ_DOVE_GPIO_16_23 14
+#define IRQ_DOVE_PCIE0_ERR 15
+#define IRQ_DOVE_PCIE0 16
+#define IRQ_DOVE_PCIE1_ERR 17
+#define IRQ_DOVE_PCIE1 18
+#define IRQ_DOVE_I2S0 19
+#define IRQ_DOVE_I2S0_ERR 20
+#define IRQ_DOVE_I2S1 21
+#define IRQ_DOVE_I2S1_ERR 22
+#define IRQ_DOVE_USB_ERR 23
+#define IRQ_DOVE_USB0 24
+#define IRQ_DOVE_USB1 25
+#define IRQ_DOVE_GE00_RX 26
+#define IRQ_DOVE_GE00_TX 27
+#define IRQ_DOVE_GE00_MISC 28
+#define IRQ_DOVE_GE00_SUM 29
+#define IRQ_DOVE_GE00_ERR 30
+#define IRQ_DOVE_CRYPTO 31
+
+/*
+ * Dove High Interrupt Controller
+ */
+#define IRQ_DOVE_AC97 32
+#define IRQ_DOVE_PMU 33
+#define IRQ_DOVE_CAM 34
+#define IRQ_DOVE_SDIO0 35
+#define IRQ_DOVE_SDIO1 36
+#define IRQ_DOVE_SDIO0_WAKEUP 37
+#define IRQ_DOVE_SDIO1_WAKEUP 38
+#define IRQ_DOVE_XOR_00 39
+#define IRQ_DOVE_XOR_01 40
+#define IRQ_DOVE_XOR0_ERR 41
+#define IRQ_DOVE_XOR_10 42
+#define IRQ_DOVE_XOR_11 43
+#define IRQ_DOVE_XOR1_ERR 44
+#define IRQ_DOVE_LCD_DCON 45
+#define IRQ_DOVE_LCD1 46
+#define IRQ_DOVE_LCD0 47
+#define IRQ_DOVE_GPU 48
+#define IRQ_DOVE_PERFORM_MNTR 49
+#define IRQ_DOVE_VPRO_DMA1 51
+#define IRQ_DOVE_SSP_TIMER 54
+#define IRQ_DOVE_SSP 55
+#define IRQ_DOVE_MC_L2_ERR 56
+#define IRQ_DOVE_CRYPTO_ERR 59
+#define IRQ_DOVE_GPIO_24_31 60
+#define IRQ_DOVE_HIGH_GPIO 61
+#define IRQ_DOVE_SATA 62
+
+/*
+ * DOVE General Purpose Pins
+ */
+#define IRQ_DOVE_GPIO_START 64
+#define NR_GPIO_IRQS 64
+
+/*
+ * PMU interrupts
+ */
+#define IRQ_DOVE_PMU_START (IRQ_DOVE_GPIO_START + NR_GPIO_IRQS)
+#define NR_PMU_IRQS 7
+#define IRQ_DOVE_RTC (IRQ_DOVE_PMU_START + 5)
+
+#define NR_IRQS (IRQ_DOVE_PMU_START + NR_PMU_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/memory.h b/arch/arm/mach-dove/include/mach/memory.h
new file mode 100644
index 00000000..bbc93fee
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/memory.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-dove/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h
new file mode 100644
index 00000000..3ad9f946
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/pm.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-dove/include/mach/pm.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_PM_H
+#define __ASM_ARCH_PM_H
+
+#include <asm/errno.h>
+#include <mach/irqs.h>
+
+#define CLOCK_GATING_CONTROL (DOVE_PMU_VIRT_BASE + 0x38)
+#define CLOCK_GATING_USB0_MASK (1 << 0)
+#define CLOCK_GATING_USB1_MASK (1 << 1)
+#define CLOCK_GATING_GBE_MASK (1 << 2)
+#define CLOCK_GATING_SATA_MASK (1 << 3)
+#define CLOCK_GATING_PCIE0_MASK (1 << 4)
+#define CLOCK_GATING_PCIE1_MASK (1 << 5)
+#define CLOCK_GATING_SDIO0_MASK (1 << 8)
+#define CLOCK_GATING_SDIO1_MASK (1 << 9)
+#define CLOCK_GATING_NAND_MASK (1 << 10)
+#define CLOCK_GATING_CAMERA_MASK (1 << 11)
+#define CLOCK_GATING_I2S0_MASK (1 << 12)
+#define CLOCK_GATING_I2S1_MASK (1 << 13)
+#define CLOCK_GATING_CRYPTO_MASK (1 << 15)
+#define CLOCK_GATING_AC97_MASK (1 << 21)
+#define CLOCK_GATING_PDMA_MASK (1 << 22)
+#define CLOCK_GATING_XOR0_MASK (1 << 23)
+#define CLOCK_GATING_XOR1_MASK (1 << 24)
+#define CLOCK_GATING_GIGA_PHY_MASK (1 << 30)
+
+#define PMU_INTERRUPT_CAUSE (DOVE_PMU_VIRT_BASE + 0x50)
+#define PMU_INTERRUPT_MASK (DOVE_PMU_VIRT_BASE + 0x54)
+
+static inline int pmu_to_irq(int pin)
+{
+ if (pin < NR_PMU_IRQS)
+ return pin + IRQ_DOVE_PMU_START;
+
+ return -EINVAL;
+}
+
+static inline int irq_to_pmu(int irq)
+{
+ if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
+ return irq - IRQ_DOVE_PMU_START;
+
+ return -EINVAL;
+}
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h
new file mode 100644
index 00000000..356afda5
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/system.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-dove/include/mach/system.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+ /*
+ * Assert soft reset.
+ */
+ writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+ while (1)
+ ;
+}
+
+
+#endif
diff --git a/arch/arm/mach-dove/include/mach/timex.h b/arch/arm/mach-dove/include/mach/timex.h
new file mode 100644
index 00000000..251d5385
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/timex.h
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-dove/include/mach/timex.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-dove/include/mach/uncompress.h b/arch/arm/mach-dove/include/mach/uncompress.h
new file mode 100644
index 00000000..2c5cdd7a
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-dove/include/mach/uncompress.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/dove.h>
+
+#define UART_THR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x0))
+#define UART_LSR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x14))
+
+#define LSR_THRE 0x20
+
+static void putc(const char c)
+{
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ /* Transmit fifo not full? */
+ if (*UART_LSR & LSR_THRE)
+ break;
+ }
+
+ *UART_THR = c;
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-dove/include/mach/vmalloc.h b/arch/arm/mach-dove/include/mach/vmalloc.h
new file mode 100644
index 00000000..a28792cf
--- /dev/null
+++ b/arch/arm/mach-dove/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-dove/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfd800000UL
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
new file mode 100644
index 00000000..f07fd16e
--- /dev/null
+++ b/arch/arm/mach-dove/irq.c
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/mach-dove/irq.c
+ *
+ * Dove IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <asm/mach/arch.h>
+#include <plat/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/pm.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int irqoff;
+ BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO);
+
+ irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 :
+ 3 + irq - IRQ_DOVE_GPIO_24_31;
+
+ orion_gpio_irq_handler(irqoff << 3);
+ if (irq == IRQ_DOVE_HIGH_GPIO) {
+ orion_gpio_irq_handler(40);
+ orion_gpio_irq_handler(48);
+ orion_gpio_irq_handler(56);
+ }
+}
+
+static void pmu_irq_mask(struct irq_data *d)
+{
+ int pin = irq_to_pmu(d->irq);
+ u32 u;
+
+ u = readl(PMU_INTERRUPT_MASK);
+ u &= ~(1 << (pin & 31));
+ writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_unmask(struct irq_data *d)
+{
+ int pin = irq_to_pmu(d->irq);
+ u32 u;
+
+ u = readl(PMU_INTERRUPT_MASK);
+ u |= 1 << (pin & 31);
+ writel(u, PMU_INTERRUPT_MASK);
+}
+
+static void pmu_irq_ack(struct irq_data *d)
+{
+ int pin = irq_to_pmu(d->irq);
+ u32 u;
+
+ u = ~(1 << (pin & 31));
+ writel(u, PMU_INTERRUPT_CAUSE);
+}
+
+static struct irq_chip pmu_irq_chip = {
+ .name = "pmu_irq",
+ .irq_mask = pmu_irq_mask,
+ .irq_unmask = pmu_irq_unmask,
+ .irq_ack = pmu_irq_ack,
+};
+
+static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long cause = readl(PMU_INTERRUPT_CAUSE);
+
+ cause &= readl(PMU_INTERRUPT_MASK);
+ if (cause == 0) {
+ do_bad_IRQ(irq, desc);
+ return;
+ }
+
+ for (irq = 0; irq < NR_PMU_IRQS; irq++) {
+ if (!(cause & (1 << irq)))
+ continue;
+ irq = pmu_to_irq(irq);
+ generic_handle_irq(irq);
+ }
+}
+
+void __init dove_init_irq(void)
+{
+ int i;
+
+ orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
+ orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+
+ /*
+ * Initialize gpiolib for GPIOs 0-71.
+ */
+ orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
+
+ orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START + 32);
+ irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
+
+ orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
+ IRQ_DOVE_GPIO_START + 64);
+
+ /*
+ * Mask and clear PMU interrupts
+ */
+ writel(0, PMU_INTERRUPT_MASK);
+ writel(0, PMU_INTERRUPT_CAUSE);
+
+ for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq);
+ irq_set_status_flags(i, IRQ_LEVEL);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+}
diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c
new file mode 100644
index 00000000..51e0e411
--- /dev/null
+++ b/arch/arm/mach-dove/mpp.c
@@ -0,0 +1,161 @@
+/*
+ * arch/arm/mach-dove/mpp.c
+ *
+ * MPP functions for Marvell Dove SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <plat/mpp.h>
+#include <mach/dove.h>
+#include "mpp.h"
+
+struct dove_mpp_grp {
+ int start;
+ int end;
+};
+
+/* Map a group to a range of GPIO pins in that group */
+static const struct dove_mpp_grp dove_mpp_grp[] = {
+ [MPP_24_39] = {
+ .start = 24,
+ .end = 39,
+ },
+ [MPP_40_45] = {
+ .start = 40,
+ .end = 45,
+ },
+ [MPP_46_51] = {
+ .start = 46,
+ .end = 51,
+ },
+ [MPP_58_61] = {
+ .start = 58,
+ .end = 61,
+ },
+ [MPP_62_63] = {
+ .start = 62,
+ .end = 63,
+ },
+};
+
+/* Enable gpio for a range of pins. mode should be a combination of
+ GPIO_OUTPUT_OK | GPIO_INPUT_OK */
+static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
+{
+ int i;
+
+ for (i = start; i <= end; i++)
+ orion_gpio_set_valid(i, gpio_mode);
+}
+
+/* Dump all the extra MPP registers. The platform code will dump the
+ registers for pins 0-23. */
+static void dove_mpp_dump_regs(void)
+{
+ pr_debug("PMU_CTRL4_CTRL: %08x\n",
+ readl(DOVE_MPP_CTRL4_VIRT_BASE));
+
+ pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
+ readl(DOVE_PMU_MPP_GENERAL_CTRL));
+
+ pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
+}
+
+static void dove_mpp_cfg_nfc(int sel)
+{
+ u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+
+ mpp_gen_cfg &= ~0x1;
+ mpp_gen_cfg |= sel;
+ writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
+
+ dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
+}
+
+static void dove_mpp_cfg_au1(int sel)
+{
+ u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
+ u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
+ u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
+
+ mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
+ ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
+ mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
+ global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
+
+ if (!sel || sel == 0x2)
+ dove_mpp_gpio_mode(52, 57, 0);
+ else
+ dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
+
+ if (sel & 0x1) {
+ global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
+ dove_mpp_gpio_mode(56, 57, 0);
+ }
+ if (sel & 0x2) {
+ mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
+ dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
+ }
+ if (sel & 0x4) {
+ ssp_ctrl1 |= DOVE_SSP_ON_AU1;
+ dove_mpp_gpio_mode(52, 55, 0);
+ }
+ if (sel & 0x8)
+ mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
+
+ writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
+ writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
+ writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
+ writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
+}
+
+/* Configure the group registers, enabling GPIO if sel indicates the
+ pin is to be used for GPIO */
+static void dove_mpp_conf_grp(unsigned int *mpp_grp_list)
+{
+ u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+ int gpio_mode;
+
+ for ( ; *mpp_grp_list; mpp_grp_list++) {
+ unsigned int num = MPP_NUM(*mpp_grp_list);
+ unsigned int sel = MPP_SEL(*mpp_grp_list);
+
+ if (num > MPP_GRP_MAX) {
+ pr_err("dove: invalid MPP GRP number (%u)\n", num);
+ continue;
+ }
+
+ mpp_ctrl4 &= ~(0x1 << num);
+ mpp_ctrl4 |= sel << num;
+
+ gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
+ dove_mpp_gpio_mode(dove_mpp_grp[num].start,
+ dove_mpp_grp[num].end, gpio_mode);
+ }
+ writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
+}
+
+/* Configure the various MPP pins on Dove */
+void __init dove_mpp_conf(unsigned int *mpp_list,
+ unsigned int *mpp_grp_list,
+ unsigned int grp_au1_52_57,
+ unsigned int grp_nfc_64_71)
+{
+ dove_mpp_dump_regs();
+
+ /* Use platform code for pins 0-23 */
+ orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
+
+ dove_mpp_conf_grp(mpp_grp_list);
+ dove_mpp_cfg_au1(grp_au1_52_57);
+ dove_mpp_cfg_nfc(grp_nfc_64_71);
+
+ dove_mpp_dump_regs();
+}
diff --git a/arch/arm/mach-dove/mpp.h b/arch/arm/mach-dove/mpp.h
new file mode 100644
index 00000000..fbec7c52
--- /dev/null
+++ b/arch/arm/mach-dove/mpp.h
@@ -0,0 +1,196 @@
+#ifndef __ARCH_DOVE_MPP_CODED_H
+#define __ARCH_DOVE_MPP_CODED_H
+
+#define MPP(_num, _sel, _in, _out) ( \
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13))
+
+#define MPP0_GPIO0 MPP(0, 0x0, 1, 1)
+#define MPP0_UA2_RTSn MPP(0, 0x2, 0, 0)
+#define MPP0_SDIO0_CD MPP(0, 0x3, 0, 0)
+#define MPP0_LCD0_PWM MPP(0, 0xf, 0, 0)
+
+#define MPP1_GPIO1 MPP(1, 0x0, 1, 1)
+#define MPP1_UA2_CTSn MPP(1, 0x2, 0, 0)
+#define MPP1_SDIO0_WP MPP(1, 0x3, 0, 0)
+#define MPP1_LCD1_PWM MPP(1, 0xf, 0, 0)
+
+#define MPP2_GPIO2 MPP(2, 0x0, 1, 1)
+#define MPP2_SATA_PRESENT MPP(2, 0x1, 0, 0)
+#define MPP2_UA2_TXD MPP(2, 0x2, 0, 0)
+#define MPP2_SDIO0_BUS_POWER MPP(2, 0x3, 0, 0)
+#define MPP2_UA_RTSn1 MPP(2, 0x4, 0, 0)
+
+#define MPP3_GPIO3 MPP(3, 0x0, 1, 1)
+#define MPP3_SATA_ACT MPP(3, 0x1, 0, 0)
+#define MPP3_UA2_RXD MPP(3, 0x2, 0, 0)
+#define MPP3_SDIO0_LED_CTRL MPP(3, 0x3, 0, 0)
+#define MPP3_UA_CTSn1 MPP(3, 0x4, 0, 0)
+#define MPP3_SPI_LCD_CS1 MPP(3, 0xf, 0, 0)
+
+#define MPP4_GPIO4 MPP(4, 0x0, 1, 1)
+#define MPP4_UA3_RTSn MPP(4, 0x2, 0, 0)
+#define MPP4_SDIO1_CD MPP(4, 0x3, 0, 0)
+#define MPP4_SPI_1_MISO MPP(4, 0x4, 0, 0)
+
+#define MPP5_GPIO5 MPP(5, 0x0, 1, 1)
+#define MPP5_UA3_CTSn MPP(5, 0x2, 0, 0)
+#define MPP5_SDIO1_WP MPP(5, 0x3, 0, 0)
+#define MPP5_SPI_1_CS MPP(5, 0x4, 0, 0)
+
+#define MPP6_GPIO6 MPP(6, 0x0, 1, 1)
+#define MPP6_UA3_TXD MPP(6, 0x2, 0, 0)
+#define MPP6_SDIO1_BUS_POWER MPP(6, 0x3, 0, 0)
+#define MPP6_SPI_1_MOSI MPP(6, 0x4, 0, 0)
+
+#define MPP7_GPIO7 MPP(7, 0x0, 1, 1)
+#define MPP7_UA3_RXD MPP(7, 0x2, 0, 0)
+#define MPP7_SDIO1_LED_CTRL MPP(7, 0x3, 0, 0)
+#define MPP7_SPI_1_SCK MPP(7, 0x4, 0, 0)
+
+#define MPP8_GPIO8 MPP(8, 0x0, 1, 1)
+#define MPP8_WD_RST_OUT MPP(8, 0x1, 0, 0)
+
+#define MPP9_GPIO9 MPP(9, 0x0, 1, 1)
+#define MPP9_PEX1_CLKREQn MPP(9, 0x5, 0, 0)
+
+#define MPP10_GPIO10 MPP(10, 0x0, 1, 1)
+#define MPP10_SSP_SCLK MPP(10, 0x5, 0, 0)
+
+#define MPP11_GPIO11 MPP(11, 0x0, 1, 1)
+#define MPP11_SATA_PRESENT MPP(11, 0x1, 0, 0)
+#define MPP11_SATA_ACT MPP(11, 0x2, 0, 0)
+#define MPP11_SDIO0_LED_CTRL MPP(11, 0x3, 0, 0)
+#define MPP11_SDIO1_LED_CTRL MPP(11, 0x4, 0, 0)
+#define MPP11_PEX0_CLKREQn MPP(11, 0x5, 0, 0)
+
+#define MPP12_GPIO12 MPP(12, 0x0, 1, 1)
+#define MPP12_SATA_ACT MPP(12, 0x1, 0, 0)
+#define MPP12_UA2_RTSn MPP(12, 0x2, 0, 0)
+#define MPP12_AD0_I2S_EXT_MCLK MPP(12, 0x3, 0, 0)
+#define MPP12_SDIO1_CD MPP(12, 0x4, 0, 0)
+
+#define MPP13_GPIO13 MPP(13, 0x0, 1, 1)
+#define MPP13_UA2_CTSn MPP(13, 0x2, 0, 0)
+#define MPP13_AD1_I2S_EXT_MCLK MPP(13, 0x3, 0, 0)
+#define MPP13_SDIO1WP MPP(13, 0x4, 0, 0)
+#define MPP13_SSP_EXTCLK MPP(13, 0x5, 0, 0)
+
+#define MPP14_GPIO14 MPP(14, 0x0, 1, 1)
+#define MPP14_UA2_TXD MPP(14, 0x2, 0, 0)
+#define MPP14_SDIO1_BUS_POWER MPP(14, 0x4, 0, 0)
+#define MPP14_SSP_RXD MPP(14, 0x5, 0, 0)
+
+#define MPP15_GPIO15 MPP(15, 0x0, 1, 1)
+#define MPP15_UA2_RXD MPP(15, 0x2, 0, 0)
+#define MPP15_SDIO1_LED_CTRL MPP(15, 0x4, 0, 0)
+#define MPP15_SSP_SFRM MPP(15, 0x5, 0, 0)
+
+#define MPP16_GPIO16 MPP(16, 0x0, 1, 1)
+#define MPP16_UA3_RTSn MPP(16, 0x2, 0, 0)
+#define MPP16_SDIO0_CD MPP(16, 0x3, 0, 0)
+#define MPP16_SPI_LCD_CS1 MPP(16, 0x4, 0, 0)
+#define MPP16_AC97_SDATA_IN1 MPP(16, 0x5, 0, 0)
+
+#define MPP17_GPIO17 MPP(17, 0x0, 1, 1)
+#define MPP17_AC97_SYSCLK_OUT MPP(17, 0x1, 0, 0)
+#define MPP17_UA3_CTSn MPP(17, 0x2, 0, 0)
+#define MPP17_SDIO0_WP MPP(17, 0x3, 0, 0)
+#define MPP17_TW_SDA2 MPP(17, 0x4, 0, 0)
+#define MPP17_AC97_SDATA_IN2 MPP(17, 0x5, 0, 0)
+
+#define MPP18_GPIO18 MPP(18, 0x0, 1, 1)
+#define MPP18_UA3_TXD MPP(18, 0x2, 0, 0)
+#define MPP18_SDIO0_BUS_POWER MPP(18, 0x3, 0, 0)
+#define MPP18_LCD0_PWM MPP(18, 0x4, 0, 0)
+#define MPP18_AC_SDATA_IN3 MPP(18, 0x5, 0, 0)
+
+#define MPP19_GPIO19 MPP(19, 0x0, 1, 1)
+#define MPP19_UA3_RXD MPP(19, 0x2, 0, 0)
+#define MPP19_SDIO0_LED_CTRL MPP(19, 0x3, 0, 0)
+#define MPP19_TW_SCK2 MPP(19, 0x4, 0, 0)
+
+#define MPP20_GPIO20 MPP(20, 0x0, 1, 1)
+#define MPP20_AC97_SYSCLK_OUT MPP(20, 0x1, 0, 0)
+#define MPP20_SPI_LCD_MISO MPP(20, 0x2, 0, 0)
+#define MPP20_SDIO1_CD MPP(20, 0x3, 0, 0)
+#define MPP20_SDIO0_CD MPP(20, 0x5, 0, 0)
+#define MPP20_SPI_1_MISO MPP(20, 0x6, 0, 0)
+
+#define MPP21_GPIO21 MPP(21, 0x0, 1, 1)
+#define MPP21_UA1_RTSn MPP(21, 0x1, 0, 0)
+#define MPP21_SPI_LCD_CS0 MPP(21, 0x2, 0, 0)
+#define MPP21_SDIO1_WP MPP(21, 0x3, 0, 0)
+#define MPP21_SSP_SFRM MPP(21, 0x4, 0, 0)
+#define MPP21_SDIO0_WP MPP(21, 0x5, 0, 0)
+#define MPP21_SPI_1_CS MPP(21, 0x6, 0, 0)
+
+#define MPP22_GPIO22 MPP(22, 0x0, 1, 1)
+#define MPP22_UA1_CTSn MPP(22, 0x1, 0, 0)
+#define MPP22_SPI_LCD_MOSI MPP(22, 0x2, 0, 0)
+#define MPP22_SDIO1_BUS_POWER MPP(22, 0x3, 0, 0)
+#define MPP22_SSP_TXD MPP(22, 0x4, 0, 0)
+#define MPP22_SDIO0_BUS_POWER MPP(22, 0x5, 0, 0)
+#define MPP22_SPI_1_MOSI MPP(22, 0x6, 0, 0)
+
+#define MPP23_GPIO23 MPP(23, 0x0, 1, 1)
+#define MPP23_SPI_LCD_SCK MPP(23, 0x2, 0, 0)
+#define MPP23_SDIO1_LED_CTRL MPP(23, 0x3, 0, 0)
+#define MPP23_SSP_SCLK MPP(23, 0x4, 0, 0)
+#define MPP23_SDIO0_LED_CTRL MPP(23, 0x5, 0, 0)
+#define MPP23_SPI_1_SCK MPP(23, 0x6, 0, 0)
+
+#define MPP_MAX 23
+
+#define MPP_GRP(_grp, _mode) MPP((_grp), (_mode), 0, 0)
+
+/* for MPP groups _num is a group index */
+enum dove_mpp_grp_idx {
+ MPP_24_39 = 2,
+ MPP_40_45 = 0,
+ MPP_46_51 = 1,
+ MPP_58_61 = 5,
+ MPP_62_63 = 4,
+ MPP_GRP_MAX = 5,
+};
+
+#define MPP_GRP_24_39_GPIO MPP_GRP(MPP_24_39, 0x1)
+#define MPP_GRP_24_39_CAM MPP_GRP(MPP_24_39, 0x0)
+
+#define MPP_GRP_40_45_GPIO MPP_GRP(MPP_40_45, 0x1)
+#define MPP_GRP_40_45_SD0 MPP_GRP(MPP_40_45, 0x0)
+
+#define MPP_GRP_46_51_GPIO MPP_GRP(MPP_46_51, 0x1)
+#define MPP_GRP_46_51_SD1 MPP_GRP(MPP_46_51, 0x0)
+
+#define MPP_GRP_58_61_GPIO MPP_GRP(MPP_58_61, 0x1)
+#define MPP_GRP_58_61_SPI MPP_GRP(MPP_58_61, 0x0)
+
+#define MPP_GRP_62_63_GPIO MPP_GRP(MPP_62_63, 0x1)
+#define MPP_GRP_62_63_UA1 MPP_GRP(MPP_62_63, 0x0)
+
+/* The MPP[64:71] control differs from other groups */
+#define MPP_GRP_NFC_64_71_GPO 0x1
+#define MPP_GRP_NFC_64_71_NFC 0x0
+
+/*
+ * The MPP[52:57] functionality is encoded by 4 bits in different
+ * registers. The _num field in this case encodes those bits in
+ * correspodence with Table 135 of 88AP510 Functional specification
+ */
+#define MPP_GRP_AU1_52_57_AU1 0x0
+#define MPP_GRP_AU1_52_57_AU1_GPIO57 0x2
+#define MPP_GRP_AU1_52_57_GPIO 0xa
+#define MPP_GRP_AU1_52_57_TW_GPIO 0xb
+#define MPP_GRP_AU1_52_57_AU1_SSP 0xc
+#define MPP_GRP_AU1_52_57_SSP_GPIO 0xe
+#define MPP_GRP_AU1_52_57_SSP_TW 0xf
+
+void dove_mpp_conf(unsigned int *mpp_list,
+ unsigned int *mpp_grp_list,
+ unsigned int grp_au1_52_57,
+ unsigned int grp_nfc_64_71);
+
+#endif /* __ARCH_DOVE_MPP_CODED_H */
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
new file mode 100644
index 00000000..502d1ca2
--- /dev/null
+++ b/arch/arm/mach-dove/pcie.c
@@ -0,0 +1,238 @@
+/*
+ * arch/arm/mach-dove/pcie.c
+ *
+ * PCIe functions for Marvell Dove 88AP510 SoC
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mbus.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+#include <asm/delay.h>
+#include <plat/pcie.h>
+#include <mach/irqs.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+struct pcie_port {
+ u8 index;
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ char io_space_name[16];
+ char mem_space_name[16];
+ struct resource res[2];
+};
+
+static struct pcie_port pcie_port[2];
+static int num_pcie_ports;
+
+
+static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct pcie_port *pp;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ pp = &pcie_port[nr];
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * Generic PCIe unit setup.
+ */
+ orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+
+ orion_pcie_setup(pp->base, &dove_mbus_dram_info);
+
+ /*
+ * IORESOURCE_IO
+ */
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = DOVE_PCIE0_IO_PHYS_BASE;
+ pp->res[0].end = pp->res[0].start + DOVE_PCIE0_IO_SIZE - 1;
+ } else {
+ pp->res[0].start = DOVE_PCIE1_IO_PHYS_BASE;
+ pp->res[0].end = pp->res[0].start + DOVE_PCIE1_IO_SIZE - 1;
+ }
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = DOVE_PCIE0_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + DOVE_PCIE0_MEM_SIZE - 1;
+ } else {
+ pp->res[1].start = DOVE_PCIE1_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + DOVE_PCIE1_MEM_SIZE - 1;
+ }
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+static struct pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = num_pcie_ports - 1; i >= 0; i--) {
+ int rbus = pcie_port[i].root_bus_nr;
+ if (rbus != -1 && rbus <= bus)
+ break;
+ }
+
+ return i >= 0 ? pcie_port + i : NULL;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+ /*
+ * Don't go out when trying to access nonexisting devices
+ * on the local bus.
+ */
+ if (bus == pp->root_bus_nr && dev > 1)
+ return 0;
+
+ return 1;
+}
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static struct pci_ops pcie_ops = {
+ .read = pcie_rd_conf,
+ .write = pcie_wr_conf,
+};
+
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+ /*
+ * Prevent enumeration of root complex.
+ */
+ if (dev->bus->parent == NULL && dev->devfn == 0) {
+ int i;
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static struct pci_bus __init *
+dove_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr < num_pcie_ports) {
+ bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+static int __init dove_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+ return pp->index ? IRQ_DOVE_PCIE1 : IRQ_DOVE_PCIE0;
+}
+
+static struct hw_pci dove_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = dove_pcie_setup,
+ .scan = dove_pcie_scan_bus,
+ .map_irq = dove_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int index, unsigned long base)
+{
+ printk(KERN_INFO "Dove PCIe port %d: ", index);
+
+ if (orion_pcie_link_up((void __iomem *)base)) {
+ struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+ printk(KERN_INFO "link up\n");
+
+ pp->index = index;
+ pp->root_bus_nr = -1;
+ pp->base = (void __iomem *)base;
+ spin_lock_init(&pp->conf_lock);
+ memset(pp->res, 0, sizeof(pp->res));
+ } else {
+ printk(KERN_INFO "link down, ignoring\n");
+ }
+}
+
+void __init dove_pcie_init(int init_port0, int init_port1)
+{
+ if (init_port0)
+ add_pcie_port(0, DOVE_PCIE0_VIRT_BASE);
+
+ if (init_port1)
+ add_pcie_port(1, DOVE_PCIE1_VIRT_BASE);
+
+ pci_common_init(&dove_pci);
+}
diff --git a/arch/arm/mach-ebsa110/Makefile b/arch/arm/mach-ebsa110/Makefile
new file mode 100644
index 00000000..6520ac83
--- /dev/null
+++ b/arch/arm/mach-ebsa110/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := core.o io.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_LEDS) += leds.o
diff --git a/arch/arm/mach-ebsa110/Makefile.boot b/arch/arm/mach-ebsa110/Makefile.boot
new file mode 100644
index 00000000..23212604
--- /dev/null
+++ b/arch/arm/mach-ebsa110/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000400
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
new file mode 100644
index 00000000..087bc771
--- /dev/null
+++ b/arch/arm/mach-ebsa110/core.c
@@ -0,0 +1,290 @@
+/*
+ * linux/arch/arm/mach-ebsa110/core.c
+ *
+ * Copyright (C) 1998-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Extra MM routines for the EBSA-110 architecture
+ */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/serial_8250.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <asm/mach/time.h>
+
+#define IRQ_MASK 0xfe000000 /* read */
+#define IRQ_MSET 0xfe000000 /* write */
+#define IRQ_STAT 0xff000000 /* read */
+#define IRQ_MCLR 0xff000000 /* write */
+
+static void ebsa110_mask_irq(struct irq_data *d)
+{
+ __raw_writeb(1 << d->irq, IRQ_MCLR);
+}
+
+static void ebsa110_unmask_irq(struct irq_data *d)
+{
+ __raw_writeb(1 << d->irq, IRQ_MSET);
+}
+
+static struct irq_chip ebsa110_irq_chip = {
+ .irq_ack = ebsa110_mask_irq,
+ .irq_mask = ebsa110_mask_irq,
+ .irq_unmask = ebsa110_unmask_irq,
+};
+
+static void __init ebsa110_init_irq(void)
+{
+ unsigned long flags;
+ unsigned int irq;
+
+ local_irq_save(flags);
+ __raw_writeb(0xff, IRQ_MCLR);
+ __raw_writeb(0x55, IRQ_MSET);
+ __raw_writeb(0x00, IRQ_MSET);
+ if (__raw_readb(IRQ_MASK) != 0x55)
+ while (1);
+ __raw_writeb(0xff, IRQ_MCLR); /* clear all interrupt enables */
+ local_irq_restore(flags);
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ irq_set_chip_and_handler(irq, &ebsa110_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+}
+
+static struct map_desc ebsa110_io_desc[] __initdata = {
+ /*
+ * sparse external-decode ISAIO space
+ */
+ { /* IRQ_STAT/IRQ_MCLR */
+ .virtual = IRQ_STAT,
+ .pfn = __phys_to_pfn(TRICK4_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* IRQ_MASK/IRQ_MSET */
+ .virtual = IRQ_MASK,
+ .pfn = __phys_to_pfn(TRICK3_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* SOFT_BASE */
+ .virtual = SOFT_BASE,
+ .pfn = __phys_to_pfn(TRICK1_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ }, { /* PIT_BASE */
+ .virtual = PIT_BASE,
+ .pfn = __phys_to_pfn(TRICK0_PHYS),
+ .length = PGDIR_SIZE,
+ .type = MT_DEVICE
+ },
+
+ /*
+ * self-decode ISAIO space
+ */
+ {
+ .virtual = ISAIO_BASE,
+ .pfn = __phys_to_pfn(ISAIO_PHYS),
+ .length = ISAIO_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = ISAMEM_BASE,
+ .pfn = __phys_to_pfn(ISAMEM_PHYS),
+ .length = ISAMEM_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init ebsa110_map_io(void)
+{
+ iotable_init(ebsa110_io_desc, ARRAY_SIZE(ebsa110_io_desc));
+}
+
+
+#define PIT_CTRL (PIT_BASE + 0x0d)
+#define PIT_T2 (PIT_BASE + 0x09)
+#define PIT_T1 (PIT_BASE + 0x05)
+#define PIT_T0 (PIT_BASE + 0x01)
+
+/*
+ * This is the rate at which your MCLK signal toggles (in Hz)
+ * This was measured on a 10 digit frequency counter sampling
+ * over 1 second.
+ */
+#define MCLK 47894000
+
+/*
+ * This is the rate at which the PIT timers get clocked
+ */
+#define CLKBY7 (MCLK / 7)
+
+/*
+ * This is the counter value. We tick at 200Hz on this platform.
+ */
+#define COUNT ((CLKBY7 + (HZ / 2)) / HZ)
+
+/*
+ * Get the time offset from the system PIT. Note that if we have missed an
+ * interrupt, then the PIT counter will roll over (ie, be negative).
+ * This actually works out to be convenient.
+ */
+static unsigned long ebsa110_gettimeoffset(void)
+{
+ unsigned long offset, count;
+
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ /*
+ * If count > COUNT, make the number negative.
+ */
+ if (count > COUNT)
+ count |= 0xffff0000;
+
+ offset = COUNT;
+ offset -= count;
+
+ /*
+ * `offset' is in units of timer counts. Convert
+ * offset to units of microseconds.
+ */
+ offset = offset * (1000000 / HZ) / COUNT;
+
+ return offset;
+}
+
+static irqreturn_t
+ebsa110_timer_interrupt(int irq, void *dev_id)
+{
+ u32 count;
+
+ /* latch and read timer 1 */
+ __raw_writeb(0x40, PIT_CTRL);
+ count = __raw_readb(PIT_T1);
+ count |= __raw_readb(PIT_T1) << 8;
+
+ count += COUNT;
+
+ __raw_writeb(count & 0xff, PIT_T1);
+ __raw_writeb(count >> 8, PIT_T1);
+
+ timer_tick();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ebsa110_timer_irq = {
+ .name = "EBSA110 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ebsa110_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt.
+ */
+static void __init ebsa110_timer_init(void)
+{
+ /*
+ * Timer 1, mode 2, LSB/MSB
+ */
+ __raw_writeb(0x70, PIT_CTRL);
+ __raw_writeb(COUNT & 0xff, PIT_T1);
+ __raw_writeb(COUNT >> 8, PIT_T1);
+
+ setup_irq(IRQ_EBSA110_TIMER0, &ebsa110_timer_irq);
+}
+
+static struct sys_timer ebsa110_timer = {
+ .init = ebsa110_timer_init,
+ .offset = ebsa110_gettimeoffset,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .iobase = 0x3f8,
+ .irq = 1,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ {
+ .iobase = 0x2f8,
+ .irq = 2,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static struct resource am79c961_resources[] = {
+ {
+ .start = 0x220,
+ .end = 0x238,
+ .flags = IORESOURCE_IO,
+ }, {
+ .start = IRQ_EBSA110_ETHERNET,
+ .end = IRQ_EBSA110_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am79c961_device = {
+ .name = "am79c961",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am79c961_resources),
+ .resource = am79c961_resources,
+};
+
+static struct platform_device *ebsa110_devices[] = {
+ &serial_device,
+ &am79c961_device,
+};
+
+static int __init ebsa110_init(void)
+{
+ return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
+}
+
+arch_initcall(ebsa110_init);
+
+MACHINE_START(EBSA110, "EBSA110")
+ /* Maintainer: Russell King */
+ .boot_params = 0x00000400,
+ .reserve_lp0 = 1,
+ .reserve_lp2 = 1,
+ .soft_reboot = 1,
+ .map_io = ebsa110_map_io,
+ .init_irq = ebsa110_init_irq,
+ .timer = &ebsa110_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ebsa110/include/mach/debug-macro.S b/arch/arm/mach-ebsa110/include/mach/debug-macro.S
new file mode 100644
index 00000000..7ef5690f
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/* arch/arm/mach-ebsa110/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+**/
+
+ .macro addruart, rp, rv
+ mov \rp, #0xf0000000
+ orr \rp, \rp, #0x00000be0
+ mov \rp, \rv
+ .endm
+
+#define UART_SHIFT 2
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-ebsa110/include/mach/entry-macro.S b/arch/arm/mach-ebsa110/include/mach/entry-macro.S
new file mode 100644
index 00000000..cc3e5992
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for ebsa110 platform.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+
+
+#define IRQ_STAT 0xff000000 /* read */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mov \base, #IRQ_STAT
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, stat, base, tmp
+ ldrb \stat, [\base] @ get interrupts
+ mov \irqnr, #0
+ tst \stat, #15
+ addeq \irqnr, \irqnr, #4
+ moveq \stat, \stat, lsr #4
+ tst \stat, #3
+ addeq \irqnr, \irqnr, #2
+ moveq \stat, \stat, lsr #2
+ tst \stat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \stat, \stat, lsr #1
+ tst \stat, #1 @ bit 0 should be set
+ .endm
+
diff --git a/arch/arm/mach-ebsa110/include/mach/hardware.h b/arch/arm/mach-ebsa110/include/mach/hardware.h
new file mode 100644
index 00000000..4b2fb774
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/hardware.h
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/hardware.h
+ *
+ * Copyright (C) 1996-2000 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the hardware definitions of the EBSA-110.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * The EBSA110 has a weird "ISA IO" region:
+ *
+ * Region 0 (addr = 0xf0000000 + io << 2)
+ * --------------------------------------------------------
+ * Physical region IO region
+ * f0000fe0 - f0000ffc 3f8 - 3ff ttyS0
+ * f0000e60 - f0000e64 398 - 399
+ * f0000de0 - f0000dfc 378 - 37f lp0
+ * f0000be0 - f0000bfc 2f8 - 2ff ttyS1
+ *
+ * Region 1 (addr = 0xf0000000 + (io & ~1) << 1 + (io & 1))
+ * --------------------------------------------------------
+ * Physical region IO region
+ * f00014f1 a79 pnp write data
+ * f00007c0 - f00007c1 3e0 - 3e1 pcmcia
+ * f00004f1 279 pnp address
+ * f0000440 - f000046c 220 - 236 eth0
+ * f0000405 203 pnp read data
+ */
+
+#define ISAMEM_PHYS 0xe0000000
+#define ISAMEM_SIZE 0x10000000
+
+#define ISAIO_PHYS 0xf0000000
+#define ISAIO_SIZE PGDIR_SIZE
+
+#define TRICK0_PHYS 0xf2000000
+#define TRICK1_PHYS 0xf2400000
+#define TRICK2_PHYS 0xf2800000
+#define TRICK3_PHYS 0xf2c00000
+#define TRICK4_PHYS 0xf3000000
+#define TRICK5_PHYS 0xf3400000
+#define TRICK6_PHYS 0xf3800000
+#define TRICK7_PHYS 0xf3c00000
+
+#define ISAMEM_BASE 0xe0000000
+#define ISAIO_BASE 0xf0000000
+
+#define PIT_BASE 0xfc000000
+#define SOFT_BASE 0xfd000000
+
+/*
+ * RAM definitions
+ */
+#define UNCACHEABLE_ADDR 0xff000000 /* IRQ_STAT */
+
+#endif
+
diff --git a/arch/arm/mach-ebsa110/include/mach/io.h b/arch/arm/mach-ebsa110/include/mach/io.h
new file mode 100644
index 00000000..f68daa63
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/io.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/io.h
+ *
+ * Copyright (C) 1997,1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 06-Dec-1997 RMK Created.
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+u8 __inb8(unsigned int port);
+void __outb8(u8 val, unsigned int port);
+
+u8 __inb16(unsigned int port);
+void __outb16(u8 val, unsigned int port);
+
+u16 __inw(unsigned int port);
+void __outw(u16 val, unsigned int port);
+
+u32 __inl(unsigned int port);
+void __outl(u32 val, unsigned int port);
+
+u8 __readb(const volatile void __iomem *addr);
+u16 __readw(const volatile void __iomem *addr);
+u32 __readl(const volatile void __iomem *addr);
+
+void __writeb(u8 val, void __iomem *addr);
+void __writew(u16 val, void __iomem *addr);
+void __writel(u32 val, void __iomem *addr);
+
+/*
+ * Argh, someone forgot the IOCS16 line. We therefore have to handle
+ * the byte stearing by selecting the correct byte IO functions here.
+ */
+#ifdef ISA_SIXTEEN_BIT_PERIPHERAL
+#define inb(p) __inb16(p)
+#define outb(v,p) __outb16(v,p)
+#else
+#define inb(p) __inb8(p)
+#define outb(v,p) __outb8(v,p)
+#endif
+
+#define inw(p) __inw(p)
+#define outw(v,p) __outw(v,p)
+
+#define inl(p) __inl(p)
+#define outl(v,p) __outl(v,p)
+
+#define readb(b) __readb(b)
+#define readw(b) __readw(b)
+#define readl(b) __readl(b)
+#define readb_relaxed(addr) readb(addr)
+#define readw_relaxed(addr) readw(addr)
+#define readl_relaxed(addr) readl(addr)
+
+#define writeb(v,b) __writeb(v,b)
+#define writew(v,b) __writew(v,b)
+#define writel(v,b) __writel(v,b)
+
+static inline void __iomem *__arch_ioremap(unsigned long cookie, size_t size,
+ unsigned int flags)
+{
+ return (void __iomem *)cookie;
+}
+
+#define __arch_ioremap __arch_ioremap
+#define __arch_iounmap(cookie) do { } while (0)
+
+extern void insb(unsigned int port, void *buf, int sz);
+extern void insw(unsigned int port, void *buf, int sz);
+extern void insl(unsigned int port, void *buf, int sz);
+
+extern void outsb(unsigned int port, const void *buf, int sz);
+extern void outsw(unsigned int port, const void *buf, int sz);
+extern void outsl(unsigned int port, const void *buf, int sz);
+
+/* can't support writesb atm */
+extern void writesw(void __iomem *addr, const void *data, int wordlen);
+extern void writesl(void __iomem *addr, const void *data, int longlen);
+
+/* can't support readsb atm */
+extern void readsw(const void __iomem *addr, void *data, int wordlen);
+extern void readsl(const void __iomem *addr, void *data, int longlen);
+
+#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/irqs.h b/arch/arm/mach-ebsa110/include/mach/irqs.h
new file mode 100644
index 00000000..a8f3771b
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/irqs.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/irqs.h
+ *
+ * Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define NR_IRQS 8
+
+#define IRQ_EBSA110_PRINTER 0
+#define IRQ_EBSA110_COM1 1
+#define IRQ_EBSA110_COM2 2
+#define IRQ_EBSA110_ETHERNET 3
+#define IRQ_EBSA110_TIMER0 4
+#define IRQ_EBSA110_TIMER1 5
+#define IRQ_EBSA110_PCMCIA 6
+#define IRQ_EBSA110_IMMEDIATE 7
diff --git a/arch/arm/mach-ebsa110/include/mach/memory.h b/arch/arm/mach-ebsa110/include/mach/memory.h
new file mode 100644
index 00000000..8e49066a
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/memory.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/memory.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 20-Oct-1996 RMK Created
+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings
+ * 21-Mar-1999 RMK Renamed to memory.h
+ * RMK Moved TASK_SIZE and PAGE_OFFSET here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+/*
+ * Cache flushing area - SRAM
+ */
+#define FLUSH_BASE_PHYS 0x40000000
+#define FLUSH_BASE 0xdf000000
+
+#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h
new file mode 100644
index 00000000..9a26245b
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/system.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/system.h
+ *
+ * Copyright (C) 1996-2000 Russell King.
+ *
+ * This program is free software; you can 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_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+/*
+ * EBSA110 idling methodology:
+ *
+ * We can not execute the "wait for interrupt" instruction since that
+ * will stop our MCLK signal (which provides the clock for the glue
+ * logic, and therefore the timer interrupt).
+ *
+ * Instead, we spin, polling the IRQ_STAT register for the occurrence
+ * of any interrupt with core clock down to the memory clock.
+ */
+static inline void arch_idle(void)
+{
+ const char *irq_stat = (char *)0xff000000;
+
+ /* disable clock switching */
+ asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
+
+ /* wait for an interrupt to occur */
+ while (!*irq_stat);
+
+ /* enable clock switching */
+ asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
+}
+
+#define arch_reset(mode, cmd) cpu_reset(0x80000000)
+
+#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/timex.h b/arch/arm/mach-ebsa110/include/mach/timex.h
new file mode 100644
index 00000000..4fb43b22
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/timex.h
+ *
+ * Copyright (C) 1997, 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * EBSA110 architecture timex specifications
+ */
+
+/*
+ * On the EBSA, the clock ticks at weird rates.
+ * This is therefore not used to calculate the
+ * divisor.
+ */
+#define CLOCK_TICK_RATE 47894000
+
diff --git a/arch/arm/mach-ebsa110/include/mach/uncompress.h b/arch/arm/mach-ebsa110/include/mach/uncompress.h
new file mode 100644
index 00000000..32041509
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/uncompress.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/uncompress.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King
+ *
+ * This program is free software; you can 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_reg.h>
+
+#define SERIAL_BASE ((unsigned char *)0xf0000be0)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ unsigned char v, *base = SERIAL_BASE;
+
+ do {
+ v = base[UART_LSR << 2];
+ barrier();
+ } while (!(v & UART_LSR_THRE));
+
+ base[UART_TX << 2] = c;
+}
+
+static inline void flush(void)
+{
+ unsigned char v, *base = SERIAL_BASE;
+
+ do {
+ v = base[UART_LSR << 2];
+ barrier();
+ } while ((v & (UART_LSR_TEMT|UART_LSR_THRE)) !=
+ (UART_LSR_TEMT|UART_LSR_THRE));
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-ebsa110/include/mach/vmalloc.h b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
new file mode 100644
index 00000000..ea141b7a
--- /dev/null
+++ b/arch/arm/mach-ebsa110/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-ebsa110/include/mach/vmalloc.h
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VMALLOC_END 0xdf000000UL
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
new file mode 100644
index 00000000..c52e3047
--- /dev/null
+++ b/arch/arm/mach-ebsa110/io.c
@@ -0,0 +1,419 @@
+/*
+ * linux/arch/arm/mach-ebsa110/isamem.c
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * Perform "ISA" memory and IO accesses. The EBSA110 has some "peculiarities"
+ * in the way it handles accesses to odd IO ports on 16-bit devices. These
+ * devices have their D0-D15 lines connected to the processors D0-D15 lines.
+ * Since they expect all byte IO operations to be performed on D0-D7, and the
+ * StrongARM expects to transfer the byte to these odd addresses on D8-D15,
+ * we must use a trick to get the required behaviour.
+ *
+ * The trick employed here is to use long word stores to odd address -1. The
+ * glue logic picks this up as a "trick" access, and asserts the LSB of the
+ * peripherals address bus, thereby accessing the odd IO port. Meanwhile, the
+ * StrongARM transfers its data on D0-D7 as expected.
+ *
+ * Things get more interesting on the pass-1 EBSA110 - the PCMCIA controller
+ * wiring was screwed in such a way that it had limited memory space access.
+ * Luckily, the work-around for this is not too horrible. See
+ * __isamem_convert_addr for the details.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+
+static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
+{
+ u32 ret, a = (u32 __force) addr;
+
+ /*
+ * The PCMCIA controller is wired up as follows:
+ * +---------+---------+---------+---------+---------+---------+
+ * PCMCIA | 2 2 2 2 | 1 1 1 1 | 1 1 1 1 | 1 1 | | |
+ * | 3 2 1 0 | 9 8 7 6 | 5 4 3 2 | 1 0 9 8 | 7 6 5 4 | 3 2 1 0 |
+ * +---------+---------+---------+---------+---------+---------+
+ * CPU | 2 2 2 2 | 2 1 1 1 | 1 1 1 1 | 1 1 1 | | |
+ * | 4 3 2 1 | 0 9 9 8 | 7 6 5 4 | 3 2 0 9 | 8 7 6 5 | 4 3 2 x |
+ * +---------+---------+---------+---------+---------+---------+
+ *
+ * This means that we can access PCMCIA regions as follows:
+ * 0x*10000 -> 0x*1ffff
+ * 0x*70000 -> 0x*7ffff
+ * 0x*90000 -> 0x*9ffff
+ * 0x*f0000 -> 0x*fffff
+ */
+ ret = (a & 0xf803fe) << 1;
+ ret |= (a & 0x03fc00) << 2;
+
+ ret += 0xe8000000;
+
+ if ((a & 0x20000) == (a & 0x40000) >> 1)
+ return (void __iomem *)ret;
+
+ BUG();
+ return NULL;
+}
+
+/*
+ * read[bwl] and write[bwl]
+ */
+u8 __readb(const volatile void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+ u32 ret;
+
+ if ((unsigned long)addr & 1)
+ ret = __raw_readl(a);
+ else
+ ret = __raw_readb(a);
+ return ret;
+}
+
+u16 __readw(const volatile void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ if ((unsigned long)addr & 1)
+ BUG();
+
+ return __raw_readw(a);
+}
+
+u32 __readl(const volatile void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+ u32 ret;
+
+ if ((unsigned long)addr & 3)
+ BUG();
+
+ ret = __raw_readw(a);
+ ret |= __raw_readw(a + 4) << 16;
+ return ret;
+}
+
+EXPORT_SYMBOL(__readb);
+EXPORT_SYMBOL(__readw);
+EXPORT_SYMBOL(__readl);
+
+void readsw(const void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 1);
+
+ __raw_readsw(a, data, len);
+}
+EXPORT_SYMBOL(readsw);
+
+void readsl(const void __iomem *addr, void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 3);
+
+ __raw_readsl(a, data, len);
+}
+EXPORT_SYMBOL(readsl);
+
+void __writeb(u8 val, void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ if ((unsigned long)addr & 1)
+ __raw_writel(val, a);
+ else
+ __raw_writeb(val, a);
+}
+
+void __writew(u16 val, void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ if ((unsigned long)addr & 1)
+ BUG();
+
+ __raw_writew(val, a);
+}
+
+void __writel(u32 val, void __iomem *addr)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ if ((unsigned long)addr & 3)
+ BUG();
+
+ __raw_writew(val, a);
+ __raw_writew(val >> 16, a + 4);
+}
+
+EXPORT_SYMBOL(__writeb);
+EXPORT_SYMBOL(__writew);
+EXPORT_SYMBOL(__writel);
+
+void writesw(void __iomem *addr, const void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 1);
+
+ __raw_writesw(a, data, len);
+}
+EXPORT_SYMBOL(writesw);
+
+void writesl(void __iomem *addr, const void *data, int len)
+{
+ void __iomem *a = __isamem_convert_addr(addr);
+
+ BUG_ON((unsigned long)addr & 3);
+
+ __raw_writesl(a, data, len);
+}
+EXPORT_SYMBOL(writesl);
+
+#define SUPERIO_PORT(p) \
+ (((p) >> 3) == (0x3f8 >> 3) || \
+ ((p) >> 3) == (0x2f8 >> 3) || \
+ ((p) >> 3) == (0x378 >> 3))
+
+/*
+ * We're addressing an 8 or 16-bit peripheral which tranfers
+ * odd addresses on the low ISA byte lane.
+ */
+u8 __inb8(unsigned int port)
+{
+ u32 ret;
+
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ ret = __raw_readb((void __iomem *)ISAIO_BASE + (port << 2));
+ else {
+ void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
+
+ /*
+ * Shame nothing else does
+ */
+ if (port & 1)
+ ret = __raw_readl(a);
+ else
+ ret = __raw_readb(a);
+ }
+ return ret;
+}
+
+/*
+ * We're addressing a 16-bit peripheral which transfers odd
+ * addresses on the high ISA byte lane.
+ */
+u8 __inb16(unsigned int port)
+{
+ unsigned int offset;
+
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ offset = port << 2;
+ else
+ offset = (port & ~1) << 1 | (port & 1);
+
+ return __raw_readb((void __iomem *)ISAIO_BASE + offset);
+}
+
+u16 __inw(unsigned int port)
+{
+ unsigned int offset;
+
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ offset = port << 2;
+ else {
+ offset = port << 1;
+ BUG_ON(port & 1);
+ }
+ return __raw_readw((void __iomem *)ISAIO_BASE + offset);
+}
+
+/*
+ * Fake a 32-bit read with two 16-bit reads. Needed for 3c589.
+ */
+u32 __inl(unsigned int port)
+{
+ void __iomem *a;
+
+ if (SUPERIO_PORT(port) || port & 3)
+ BUG();
+
+ a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
+
+ return __raw_readw(a) | __raw_readw(a + 4) << 16;
+}
+
+EXPORT_SYMBOL(__inb8);
+EXPORT_SYMBOL(__inb16);
+EXPORT_SYMBOL(__inw);
+EXPORT_SYMBOL(__inl);
+
+void __outb8(u8 val, unsigned int port)
+{
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ __raw_writeb(val, (void __iomem *)ISAIO_BASE + (port << 2));
+ else {
+ void __iomem *a = (void __iomem *)ISAIO_BASE + ((port & ~1) << 1);
+
+ /*
+ * Shame nothing else does
+ */
+ if (port & 1)
+ __raw_writel(val, a);
+ else
+ __raw_writeb(val, a);
+ }
+}
+
+void __outb16(u8 val, unsigned int port)
+{
+ unsigned int offset;
+
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ offset = port << 2;
+ else
+ offset = (port & ~1) << 1 | (port & 1);
+
+ __raw_writeb(val, (void __iomem *)ISAIO_BASE + offset);
+}
+
+void __outw(u16 val, unsigned int port)
+{
+ unsigned int offset;
+
+ /*
+ * The SuperIO registers use sane addressing techniques...
+ */
+ if (SUPERIO_PORT(port))
+ offset = port << 2;
+ else {
+ offset = port << 1;
+ BUG_ON(port & 1);
+ }
+ __raw_writew(val, (void __iomem *)ISAIO_BASE + offset);
+}
+
+void __outl(u32 val, unsigned int port)
+{
+ BUG();
+}
+
+EXPORT_SYMBOL(__outb8);
+EXPORT_SYMBOL(__outb16);
+EXPORT_SYMBOL(__outw);
+EXPORT_SYMBOL(__outl);
+
+void outsb(unsigned int port, const void *from, int len)
+{
+ u32 off;
+
+ if (SUPERIO_PORT(port))
+ off = port << 2;
+ else {
+ off = (port & ~1) << 1;
+ if (port & 1)
+ BUG();
+ }
+
+ __raw_writesb((void __iomem *)ISAIO_BASE + off, from, len);
+}
+
+void insb(unsigned int port, void *from, int len)
+{
+ u32 off;
+
+ if (SUPERIO_PORT(port))
+ off = port << 2;
+ else {
+ off = (port & ~1) << 1;
+ if (port & 1)
+ BUG();
+ }
+
+ __raw_readsb((void __iomem *)ISAIO_BASE + off, from, len);
+}
+
+EXPORT_SYMBOL(outsb);
+EXPORT_SYMBOL(insb);
+
+void outsw(unsigned int port, const void *from, int len)
+{
+ u32 off;
+
+ if (SUPERIO_PORT(port))
+ off = port << 2;
+ else {
+ off = (port & ~1) << 1;
+ if (port & 1)
+ BUG();
+ }
+
+ __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len);
+}
+
+void insw(unsigned int port, void *from, int len)
+{
+ u32 off;
+
+ if (SUPERIO_PORT(port))
+ off = port << 2;
+ else {
+ off = (port & ~1) << 1;
+ if (port & 1)
+ BUG();
+ }
+
+ __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len);
+}
+
+EXPORT_SYMBOL(outsw);
+EXPORT_SYMBOL(insw);
+
+/*
+ * We implement these as 16-bit insw/outsw, mainly for
+ * 3c589 cards.
+ */
+void outsl(unsigned int port, const void *from, int len)
+{
+ u32 off = port << 1;
+
+ if (SUPERIO_PORT(port) || port & 3)
+ BUG();
+
+ __raw_writesw((void __iomem *)ISAIO_BASE + off, from, len << 1);
+}
+
+void insl(unsigned int port, void *from, int len)
+{
+ u32 off = port << 1;
+
+ if (SUPERIO_PORT(port) || port & 3)
+ BUG();
+
+ __raw_readsw((void __iomem *)ISAIO_BASE + off, from, len << 1);
+}
+
+EXPORT_SYMBOL(outsl);
+EXPORT_SYMBOL(insl);
diff --git a/arch/arm/mach-ebsa110/leds.c b/arch/arm/mach-ebsa110/leds.c
new file mode 100644
index 00000000..6a6ea57c
--- /dev/null
+++ b/arch/arm/mach-ebsa110/leds.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/mach-ebsa110/leds.c
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * EBSA-110 LED control routines. We use the led as follows:
+ *
+ * - Red - toggles state every 50 timer interrupts
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static spinlock_t leds_lock;
+
+static void ebsa110_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch(ledevt) {
+ case led_timer:
+ *(volatile unsigned char *)SOFT_BASE ^= 128;
+ break;
+
+ default:
+ break;
+ }
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_ebsa110())
+ leds_event = ebsa110_leds_event;
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
new file mode 100644
index 00000000..3a08b18f
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -0,0 +1,201 @@
+if ARCH_EP93XX
+
+menu "Cirrus EP93xx Implementation Options"
+
+config CRUNCH
+ bool "Support for MaverickCrunch"
+ help
+ Enable kernel support for MaverickCrunch.
+
+comment "EP93xx Platforms"
+
+choice
+ prompt "EP93xx first SDRAM bank selection"
+ default EP93XX_SDCE3_SYNC_PHYS_OFFSET
+
+config EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ bool "0x00000000 - SDCE3/SyncBoot"
+ help
+ Select this option if you want support for EP93xx boards with the
+ first SDRAM bank at 0x00000000.
+
+config EP93XX_SDCE0_PHYS_OFFSET
+ bool "0xc0000000 - SDCEO"
+ help
+ Select this option if you want support for EP93xx boards with the
+ first SDRAM bank at 0xc0000000.
+
+config EP93XX_SDCE1_PHYS_OFFSET
+ bool "0xd0000000 - SDCE1"
+ help
+ Select this option if you want support for EP93xx boards with the
+ first SDRAM bank at 0xd0000000.
+
+config EP93XX_SDCE2_PHYS_OFFSET
+ bool "0xe0000000 - SDCE2"
+ help
+ Select this option if you want support for EP93xx boards with the
+ first SDRAM bank at 0xe0000000.
+
+config EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+ bool "0xf0000000 - SDCE3/AsyncBoot"
+ help
+ Select this option if you want support for EP93xx boards with the
+ first SDRAM bank at 0xf0000000.
+
+endchoice
+
+config MACH_ADSSPHERE
+ bool "Support ADS Sphere"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ help
+ Say 'Y' here if you want your kernel to support the ADS
+ Sphere board.
+
+config MACH_EDB93XX
+ bool
+
+config MACH_EDB9301
+ bool "Support Cirrus Logic EDB9301"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9301 Evaluation Board.
+
+config MACH_EDB9302
+ bool "Support Cirrus Logic EDB9302"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9302 Evaluation Board.
+
+config MACH_EDB9302A
+ bool "Support Cirrus Logic EDB9302A"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9302A Evaluation Board.
+
+config MACH_EDB9307
+ bool "Support Cirrus Logic EDB9307"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9307 Evaluation Board.
+
+config MACH_EDB9307A
+ bool "Support Cirrus Logic EDB9307A"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9307A Evaluation Board.
+
+config MACH_EDB9312
+ bool "Support Cirrus Logic EDB9312"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9312 Evaluation Board.
+
+config MACH_EDB9315
+ bool "Support Cirrus Logic EDB9315"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9315 Evaluation Board.
+
+config MACH_EDB9315A
+ bool "Support Cirrus Logic EDB9315A"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ select MACH_EDB93XX
+ help
+ Say 'Y' here if you want your kernel to support the Cirrus
+ Logic EDB9315A Evaluation Board.
+
+config MACH_GESBC9312
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ bool "Support Glomation GESBC-9312-sx"
+ help
+ Say 'Y' here if you want your kernel to support the Glomation
+ GESBC-9312-sx board.
+
+config MACH_MICRO9
+ bool
+
+config MACH_MICRO9H
+ bool "Support Contec Micro9-High"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Micro9-High board.
+
+config MACH_MICRO9M
+ bool "Support Contec Micro9-Mid"
+ depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Micro9-Mid board.
+
+config MACH_MICRO9L
+ bool "Support Contec Micro9-Lite"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Micro9-Lite board.
+
+config MACH_MICRO9S
+ bool "Support Contec Micro9-Slim"
+ depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
+ select MACH_MICRO9
+ help
+ Say 'Y' here if you want your kernel to support the
+ Contec Micro9-Slim board.
+
+config MACH_SIM_ONE
+ bool "Support Simplemachines Sim.One board"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ help
+ Say 'Y' here if you want your kernel to support the
+ Simplemachines Sim.One board.
+
+config MACH_SNAPPER_CL15
+ bool "Support Bluewater Systems Snapper CL15 Module"
+ depends on EP93XX_SDCE0_PHYS_OFFSET
+ help
+ Say 'Y' here if you want your kernel to support the Bluewater
+ Systems Snapper CL15 Module.
+
+config MACH_TS72XX
+ bool "Support Technologic Systems TS-72xx SBC"
+ depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
+ help
+ Say 'Y' here if you want your kernel to support the
+ Technologic Systems TS-72xx board.
+
+choice
+ prompt "Select a UART for early kernel messages"
+
+config EP93XX_EARLY_UART1
+ bool "UART1"
+
+config EP93XX_EARLY_UART2
+ bool "UART2"
+
+config EP93XX_EARLY_UART3
+ bool "UART3"
+
+endchoice
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
new file mode 100644
index 00000000..33ee2c86
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y := core.o clock.o dma-m2p.o gpio.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o
+obj-$(CONFIG_MACH_EDB93XX) += edb93xx.o
+obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
+obj-$(CONFIG_MACH_MICRO9) += micro9.o
+obj-$(CONFIG_MACH_SIM_ONE) += simone.o
+obj-$(CONFIG_MACH_SNAPPER_CL15) += snappercl15.o
+obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot
new file mode 100644
index 00000000..0ad33f15
--- /dev/null
+++ b/arch/arm/mach-ep93xx/Makefile.boot
@@ -0,0 +1,14 @@
+ zreladdr-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00008000
+params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100
+
+ zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000
+params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100
+
+ zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0008000
+params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100
+
+ zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0008000
+params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100
+
+ zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0008000
+params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
new file mode 100644
index 00000000..61b98ce4
--- /dev/null
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ep93xx/adssphere.c
+ * ADS Sphere support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+static struct ep93xx_eth_data __initdata adssphere_eth_data = {
+ .phy_id = 1,
+};
+
+static void __init adssphere_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
+ ep93xx_register_eth(&adssphere_eth_data, 1);
+}
+
+MACHINE_START(ADSSPHERE, "ADS Sphere board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = adssphere_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
new file mode 100644
index 00000000..ca4de710
--- /dev/null
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -0,0 +1,562 @@
+/*
+ * arch/arm/mach-ep93xx/clock.c
+ * Clock control for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+
+#include <asm/div64.h>
+
+
+struct clk {
+ struct clk *parent;
+ unsigned long rate;
+ int users;
+ int sw_locked;
+ void __iomem *enable_reg;
+ u32 enable_mask;
+
+ unsigned long (*get_rate)(struct clk *clk);
+ int (*set_rate)(struct clk *clk, unsigned long rate);
+};
+
+
+static unsigned long get_uart_rate(struct clk *clk);
+
+static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
+static int set_div_rate(struct clk *clk, unsigned long rate);
+static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
+static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
+
+static struct clk clk_xtali = {
+ .rate = EP93XX_EXT_CLK_RATE,
+};
+static struct clk clk_uart1 = {
+ .parent = &clk_xtali,
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
+ .get_rate = get_uart_rate,
+};
+static struct clk clk_uart2 = {
+ .parent = &clk_xtali,
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
+ .get_rate = get_uart_rate,
+};
+static struct clk clk_uart3 = {
+ .parent = &clk_xtali,
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_DEVCFG,
+ .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
+ .get_rate = get_uart_rate,
+};
+static struct clk clk_pll1 = {
+ .parent = &clk_xtali,
+};
+static struct clk clk_f = {
+ .parent = &clk_pll1,
+};
+static struct clk clk_h = {
+ .parent = &clk_pll1,
+};
+static struct clk clk_p = {
+ .parent = &clk_pll1,
+};
+static struct clk clk_pll2 = {
+ .parent = &clk_xtali,
+};
+static struct clk clk_usb_host = {
+ .parent = &clk_pll2,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
+};
+static struct clk clk_keypad = {
+ .parent = &clk_xtali,
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
+ .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
+ .set_rate = set_keytchclk_rate,
+};
+static struct clk clk_spi = {
+ .parent = &clk_xtali,
+ .rate = EP93XX_EXT_CLK_RATE,
+};
+static struct clk clk_pwm = {
+ .parent = &clk_xtali,
+ .rate = EP93XX_EXT_CLK_RATE,
+};
+
+static struct clk clk_video = {
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_VIDCLKDIV,
+ .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
+ .set_rate = set_div_rate,
+};
+
+static struct clk clk_i2s_mclk = {
+ .sw_locked = 1,
+ .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
+ .enable_mask = EP93XX_SYSCON_CLKDIV_ENABLE,
+ .set_rate = set_div_rate,
+};
+
+static struct clk clk_i2s_sclk = {
+ .sw_locked = 1,
+ .parent = &clk_i2s_mclk,
+ .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
+ .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
+ .set_rate = set_i2s_sclk_rate,
+};
+
+static struct clk clk_i2s_lrclk = {
+ .sw_locked = 1,
+ .parent = &clk_i2s_sclk,
+ .enable_reg = EP93XX_SYSCON_I2SCLKDIV,
+ .enable_mask = EP93XX_SYSCON_I2SCLKDIV_SENA,
+ .set_rate = set_i2s_lrclk_rate,
+};
+
+/* DMA Clocks */
+static struct clk clk_m2p0 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
+};
+static struct clk clk_m2p1 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
+};
+static struct clk clk_m2p2 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
+};
+static struct clk clk_m2p3 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
+};
+static struct clk clk_m2p4 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
+};
+static struct clk clk_m2p5 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
+};
+static struct clk clk_m2p6 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
+};
+static struct clk clk_m2p7 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
+};
+static struct clk clk_m2p8 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
+};
+static struct clk clk_m2p9 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
+};
+static struct clk clk_m2m0 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
+};
+static struct clk clk_m2m1 = {
+ .parent = &clk_h,
+ .enable_reg = EP93XX_SYSCON_PWRCNT,
+ .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
+};
+
+#define INIT_CK(dev,con,ck) \
+ { .dev_id = dev, .con_id = con, .clk = ck }
+
+static struct clk_lookup clocks[] = {
+ INIT_CK(NULL, "xtali", &clk_xtali),
+ INIT_CK("apb:uart1", NULL, &clk_uart1),
+ INIT_CK("apb:uart2", NULL, &clk_uart2),
+ INIT_CK("apb:uart3", NULL, &clk_uart3),
+ INIT_CK(NULL, "pll1", &clk_pll1),
+ INIT_CK(NULL, "fclk", &clk_f),
+ INIT_CK(NULL, "hclk", &clk_h),
+ INIT_CK(NULL, "apb_pclk", &clk_p),
+ INIT_CK(NULL, "pll2", &clk_pll2),
+ INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
+ INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
+ INIT_CK("ep93xx-fb", NULL, &clk_video),
+ INIT_CK("ep93xx-spi.0", NULL, &clk_spi),
+ INIT_CK("ep93xx-i2s", "mclk", &clk_i2s_mclk),
+ INIT_CK("ep93xx-i2s", "sclk", &clk_i2s_sclk),
+ INIT_CK("ep93xx-i2s", "lrclk", &clk_i2s_lrclk),
+ INIT_CK(NULL, "pwm_clk", &clk_pwm),
+ INIT_CK(NULL, "m2p0", &clk_m2p0),
+ INIT_CK(NULL, "m2p1", &clk_m2p1),
+ INIT_CK(NULL, "m2p2", &clk_m2p2),
+ INIT_CK(NULL, "m2p3", &clk_m2p3),
+ INIT_CK(NULL, "m2p4", &clk_m2p4),
+ INIT_CK(NULL, "m2p5", &clk_m2p5),
+ INIT_CK(NULL, "m2p6", &clk_m2p6),
+ INIT_CK(NULL, "m2p7", &clk_m2p7),
+ INIT_CK(NULL, "m2p8", &clk_m2p8),
+ INIT_CK(NULL, "m2p9", &clk_m2p9),
+ INIT_CK(NULL, "m2m0", &clk_m2m0),
+ INIT_CK(NULL, "m2m1", &clk_m2m1),
+};
+
+static DEFINE_SPINLOCK(clk_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+ if (!clk->users++) {
+ if (clk->parent)
+ __clk_enable(clk->parent);
+
+ if (clk->enable_reg) {
+ u32 v;
+
+ v = __raw_readl(clk->enable_reg);
+ v |= clk->enable_mask;
+ if (clk->sw_locked)
+ ep93xx_syscon_swlocked_write(v, clk->enable_reg);
+ else
+ __raw_writel(v, clk->enable_reg);
+ }
+ }
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (!clk)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+ if (!--clk->users) {
+ if (clk->enable_reg) {
+ u32 v;
+
+ v = __raw_readl(clk->enable_reg);
+ v &= ~clk->enable_mask;
+ if (clk->sw_locked)
+ ep93xx_syscon_swlocked_write(v, clk->enable_reg);
+ else
+ __raw_writel(v, clk->enable_reg);
+ }
+
+ if (clk->parent)
+ __clk_disable(clk->parent);
+ }
+}
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (!clk)
+ return;
+
+ spin_lock_irqsave(&clk_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clk_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+static unsigned long get_uart_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 value;
+
+ value = __raw_readl(EP93XX_SYSCON_PWRCNT);
+ if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
+ return rate;
+ else
+ return rate / 2;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val;
+ u32 div_bit;
+
+ val = __raw_readl(clk->enable_reg);
+
+ /*
+ * The Key Matrix and ADC clocks are configured using the same
+ * System Controller register. The clock used will be either
+ * 1/4 or 1/16 the external clock rate depending on the
+ * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
+ * bit being set or cleared.
+ */
+ div_bit = clk->enable_mask >> 15;
+
+ if (rate == EP93XX_KEYTCHCLK_DIV4)
+ val |= div_bit;
+ else if (rate == EP93XX_KEYTCHCLK_DIV16)
+ val &= ~div_bit;
+ else
+ return -EINVAL;
+
+ ep93xx_syscon_swlocked_write(val, clk->enable_reg);
+ clk->rate = rate;
+ return 0;
+}
+
+static int calc_clk_div(struct clk *clk, unsigned long rate,
+ int *psel, int *esel, int *pdiv, int *div)
+{
+ struct clk *mclk;
+ unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
+ int i, found = 0, __div = 0, __pdiv = 0;
+
+ /* Don't exceed the maximum rate */
+ max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
+ rate = min(rate, max_rate);
+
+ /*
+ * Try the two pll's and the external clock
+ * Because the valid predividers are 2, 2.5 and 3, we multiply
+ * all the clocks by 2 to avoid floating point math.
+ *
+ * This is based on the algorithm in the ep93xx raster guide:
+ * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
+ *
+ */
+ for (i = 0; i < 3; i++) {
+ if (i == 0)
+ mclk = &clk_xtali;
+ else if (i == 1)
+ mclk = &clk_pll1;
+ else
+ mclk = &clk_pll2;
+ mclk_rate = mclk->rate * 2;
+
+ /* Try each predivider value */
+ for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
+ __div = mclk_rate / (rate * __pdiv);
+ if (__div < 2 || __div > 127)
+ continue;
+
+ actual_rate = mclk_rate / (__pdiv * __div);
+
+ if (!found || abs(actual_rate - rate) < rate_err) {
+ *pdiv = __pdiv - 3;
+ *div = __div;
+ *psel = (i == 2);
+ *esel = (i != 0);
+ clk->parent = mclk;
+ clk->rate = actual_rate;
+ rate_err = abs(actual_rate - rate);
+ found = 1;
+ }
+ }
+ }
+
+ if (!found)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int set_div_rate(struct clk *clk, unsigned long rate)
+{
+ int err, psel = 0, esel = 0, pdiv = 0, div = 0;
+ u32 val;
+
+ err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
+ if (err)
+ return err;
+
+ /* Clear the esel, psel, pdiv and div bits */
+ val = __raw_readl(clk->enable_reg);
+ val &= ~0x7fff;
+
+ /* Set the new esel, psel, pdiv and div bits for the new clock rate */
+ val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
+ (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
+ (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
+ ep93xx_syscon_swlocked_write(val, clk->enable_reg);
+ return 0;
+}
+
+static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned val = __raw_readl(clk->enable_reg);
+
+ if (rate == clk_i2s_mclk.rate / 2)
+ ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV,
+ clk->enable_reg);
+ else if (rate == clk_i2s_mclk.rate / 4)
+ ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV,
+ clk->enable_reg);
+ else
+ return -EINVAL;
+
+ clk_i2s_sclk.rate = rate;
+ return 0;
+}
+
+static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned val = __raw_readl(clk->enable_reg) &
+ ~EP93XX_I2SCLKDIV_LRDIV_MASK;
+
+ if (rate == clk_i2s_sclk.rate / 32)
+ ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
+ clk->enable_reg);
+ else if (rate == clk_i2s_sclk.rate / 64)
+ ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
+ clk->enable_reg);
+ else if (rate == clk_i2s_sclk.rate / 128)
+ ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
+ clk->enable_reg);
+ else
+ return -EINVAL;
+
+ clk_i2s_lrclk.rate = rate;
+ return 0;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->set_rate)
+ return clk->set_rate(clk, rate);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+
+static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+static char pclk_divisors[] = { 1, 2, 4, 8 };
+
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long calc_pll_rate(u32 config_word)
+{
+ unsigned long long rate;
+ int i;
+
+ rate = clk_xtali.rate;
+ rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
+ rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
+ do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
+ for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */
+ rate >>= 1;
+
+ return (unsigned long)rate;
+}
+
+static void __init ep93xx_dma_clock_init(void)
+{
+ clk_m2p0.rate = clk_h.rate;
+ clk_m2p1.rate = clk_h.rate;
+ clk_m2p2.rate = clk_h.rate;
+ clk_m2p3.rate = clk_h.rate;
+ clk_m2p4.rate = clk_h.rate;
+ clk_m2p5.rate = clk_h.rate;
+ clk_m2p6.rate = clk_h.rate;
+ clk_m2p7.rate = clk_h.rate;
+ clk_m2p8.rate = clk_h.rate;
+ clk_m2p9.rate = clk_h.rate;
+ clk_m2m0.rate = clk_h.rate;
+ clk_m2m1.rate = clk_h.rate;
+}
+
+static int __init ep93xx_clock_init(void)
+{
+ u32 value;
+
+ /* Determine the bootloader configured pll1 rate */
+ value = __raw_readl(EP93XX_SYSCON_CLKSET1);
+ if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
+ clk_pll1.rate = clk_xtali.rate;
+ else
+ clk_pll1.rate = calc_pll_rate(value);
+
+ /* Initialize the pll1 derived clocks */
+ clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
+ clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
+ clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+ ep93xx_dma_clock_init();
+
+ /* Determine the bootloader configured pll2 rate */
+ value = __raw_readl(EP93XX_SYSCON_CLKSET2);
+ if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
+ clk_pll2.rate = clk_xtali.rate;
+ else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
+ clk_pll2.rate = calc_pll_rate(value);
+ else
+ clk_pll2.rate = 0;
+
+ /* Initialize the pll2 derived clocks */
+ clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
+
+ /*
+ * EP93xx SSP clock rate was doubled in version E2. For more information
+ * see:
+ * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+ */
+ if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
+ clk_spi.rate /= 2;
+
+ pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
+ clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
+ pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
+ clk_f.rate / 1000000, clk_h.rate / 1000000,
+ clk_p.rate / 1000000);
+
+ clkdev_add_table(clocks, ARRAY_SIZE(clocks));
+ return 0;
+}
+postcore_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
new file mode 100644
index 00000000..6659a0d1
--- /dev/null
+++ b/arch/arm/mach-ep93xx/core.c
@@ -0,0 +1,889 @@
+/*
+ * arch/arm/mach-ep93xx/core.c
+ * Core routines for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Thanks go to Michael Burian and Ray Lehtiniemi for their key
+ * role in the ep93xx linux community.
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/timex.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/termios.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <mach/ep93xx_keypad.h>
+#include <mach/ep93xx_spi.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <asm/hardware/vic.h>
+
+
+/*************************************************************************
+ * Static I/O mappings that are needed for all EP93xx platforms
+ *************************************************************************/
+static struct map_desc ep93xx_io_desc[] __initdata = {
+ {
+ .virtual = EP93XX_AHB_VIRT_BASE,
+ .pfn = __phys_to_pfn(EP93XX_AHB_PHYS_BASE),
+ .length = EP93XX_AHB_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = EP93XX_APB_VIRT_BASE,
+ .pfn = __phys_to_pfn(EP93XX_APB_PHYS_BASE),
+ .length = EP93XX_APB_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init ep93xx_map_io(void)
+{
+ iotable_init(ep93xx_io_desc, ARRAY_SIZE(ep93xx_io_desc));
+}
+
+
+/*************************************************************************
+ * Timer handling for EP93xx
+ *************************************************************************
+ * The ep93xx has four internal timers. Timers 1, 2 (both 16 bit) and
+ * 3 (32 bit) count down at 508 kHz, are self-reloading, and can generate
+ * an interrupt on underflow. Timer 4 (40 bit) counts down at 983.04 kHz,
+ * is free-running, and can't generate interrupts.
+ *
+ * The 508 kHz timers are ideal for use for the timer interrupt, as the
+ * most common values of HZ divide 508 kHz nicely. We pick one of the 16
+ * bit timers (timer 1) since we don't need more than 16 bits of reload
+ * value as long as HZ >= 8.
+ *
+ * The higher clock rate of timer 4 makes it a better choice than the
+ * other timers for use in gettimeoffset(), while the fact that it can't
+ * generate interrupts means we don't have to worry about not being able
+ * to use this timer for something else. We also use timer 4 for keeping
+ * track of lost jiffies.
+ */
+#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
+#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
+#define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04)
+#define EP93XX_TIMER1_CONTROL EP93XX_TIMER_REG(0x08)
+#define EP93XX_TIMER123_CONTROL_ENABLE (1 << 7)
+#define EP93XX_TIMER123_CONTROL_MODE (1 << 6)
+#define EP93XX_TIMER123_CONTROL_CLKSEL (1 << 3)
+#define EP93XX_TIMER1_CLEAR EP93XX_TIMER_REG(0x0c)
+#define EP93XX_TIMER2_LOAD EP93XX_TIMER_REG(0x20)
+#define EP93XX_TIMER2_VALUE EP93XX_TIMER_REG(0x24)
+#define EP93XX_TIMER2_CONTROL EP93XX_TIMER_REG(0x28)
+#define EP93XX_TIMER2_CLEAR EP93XX_TIMER_REG(0x2c)
+#define EP93XX_TIMER4_VALUE_LOW EP93XX_TIMER_REG(0x60)
+#define EP93XX_TIMER4_VALUE_HIGH EP93XX_TIMER_REG(0x64)
+#define EP93XX_TIMER4_VALUE_HIGH_ENABLE (1 << 8)
+#define EP93XX_TIMER3_LOAD EP93XX_TIMER_REG(0x80)
+#define EP93XX_TIMER3_VALUE EP93XX_TIMER_REG(0x84)
+#define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88)
+#define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c)
+
+#define EP93XX_TIMER123_CLOCK 508469
+#define EP93XX_TIMER4_CLOCK 983040
+
+#define TIMER1_RELOAD ((EP93XX_TIMER123_CLOCK / HZ) - 1)
+#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ)
+
+static unsigned int last_jiffy_time;
+
+static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
+{
+ /* Writing any value clears the timer interrupt */
+ __raw_writel(1, EP93XX_TIMER1_CLEAR);
+
+ /* Recover lost jiffies */
+ while ((signed long)
+ (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
+ >= TIMER4_TICKS_PER_JIFFY) {
+ last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
+ timer_tick();
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ep93xx_timer_irq = {
+ .name = "ep93xx timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ep93xx_timer_interrupt,
+};
+
+static void __init ep93xx_timer_init(void)
+{
+ u32 tmode = EP93XX_TIMER123_CONTROL_MODE |
+ EP93XX_TIMER123_CONTROL_CLKSEL;
+
+ /* Enable periodic HZ timer. */
+ __raw_writel(tmode, EP93XX_TIMER1_CONTROL);
+ __raw_writel(TIMER1_RELOAD, EP93XX_TIMER1_LOAD);
+ __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
+ EP93XX_TIMER1_CONTROL);
+
+ /* Enable lost jiffy timer. */
+ __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
+ EP93XX_TIMER4_VALUE_HIGH);
+
+ setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
+}
+
+static unsigned long ep93xx_gettimeoffset(void)
+{
+ int offset;
+
+ offset = __raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time;
+
+ /* Calculate (1000000 / 983040) * offset. */
+ return offset + (53 * offset / 3072);
+}
+
+struct sys_timer ep93xx_timer = {
+ .init = ep93xx_timer_init,
+ .offset = ep93xx_gettimeoffset,
+};
+
+
+/*************************************************************************
+ * EP93xx IRQ handling
+ *************************************************************************/
+extern void ep93xx_gpio_init_irq(void);
+
+void __init ep93xx_init_irq(void)
+{
+ vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0);
+ vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0);
+
+ ep93xx_gpio_init_irq();
+}
+
+
+/*************************************************************************
+ * EP93xx System Controller Software Locked register handling
+ *************************************************************************/
+
+/*
+ * syscon_swlock prevents anything else from writing to the syscon
+ * block while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(syscon_swlock);
+
+void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&syscon_swlock, flags);
+
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(val, reg);
+
+ spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
+
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
+{
+ unsigned long flags;
+ unsigned int val;
+
+ spin_lock_irqsave(&syscon_swlock, flags);
+
+ val = __raw_readl(EP93XX_SYSCON_DEVCFG);
+ val &= ~clear_bits;
+ val |= set_bits;
+ __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+ __raw_writel(val, EP93XX_SYSCON_DEVCFG);
+
+ spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
+
+/**
+ * ep93xx_chip_revision() - returns the EP93xx chip revision
+ *
+ * See <mach/platform.h> for more information.
+ */
+unsigned int ep93xx_chip_revision(void)
+{
+ unsigned int v;
+
+ v = __raw_readl(EP93XX_SYSCON_SYSCFG);
+ v &= EP93XX_SYSCON_SYSCFG_REV_MASK;
+ v >>= EP93XX_SYSCON_SYSCFG_REV_SHIFT;
+ return v;
+}
+
+/*************************************************************************
+ * EP93xx peripheral handling
+ *************************************************************************/
+#define EP93XX_UART_MCR_OFFSET (0x0100)
+
+static void ep93xx_uart_set_mctrl(struct amba_device *dev,
+ void __iomem *base, unsigned int mctrl)
+{
+ unsigned int mcr;
+
+ mcr = 0;
+ if (mctrl & TIOCM_RTS)
+ mcr |= 2;
+ if (mctrl & TIOCM_DTR)
+ mcr |= 1;
+
+ __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
+}
+
+static struct amba_pl010_data ep93xx_uart_data = {
+ .set_mctrl = ep93xx_uart_set_mctrl,
+};
+
+static struct amba_device uart1_device = {
+ .dev = {
+ .init_name = "apb:uart1",
+ .platform_data = &ep93xx_uart_data,
+ },
+ .res = {
+ .start = EP93XX_UART1_PHYS_BASE,
+ .end = EP93XX_UART1_PHYS_BASE + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_EP93XX_UART1, NO_IRQ },
+ .periphid = 0x00041010,
+};
+
+static struct amba_device uart2_device = {
+ .dev = {
+ .init_name = "apb:uart2",
+ .platform_data = &ep93xx_uart_data,
+ },
+ .res = {
+ .start = EP93XX_UART2_PHYS_BASE,
+ .end = EP93XX_UART2_PHYS_BASE + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_EP93XX_UART2, NO_IRQ },
+ .periphid = 0x00041010,
+};
+
+static struct amba_device uart3_device = {
+ .dev = {
+ .init_name = "apb:uart3",
+ .platform_data = &ep93xx_uart_data,
+ },
+ .res = {
+ .start = EP93XX_UART3_PHYS_BASE,
+ .end = EP93XX_UART3_PHYS_BASE + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_EP93XX_UART3, NO_IRQ },
+ .periphid = 0x00041010,
+};
+
+
+static struct resource ep93xx_rtc_resource[] = {
+ {
+ .start = EP93XX_RTC_PHYS_BASE,
+ .end = EP93XX_RTC_PHYS_BASE + 0x10c - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_rtc_device = {
+ .name = "ep93xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_rtc_resource),
+ .resource = ep93xx_rtc_resource,
+};
+
+
+static struct resource ep93xx_ohci_resources[] = {
+ [0] = {
+ .start = EP93XX_USB_PHYS_BASE,
+ .end = EP93XX_USB_PHYS_BASE + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EP93XX_USB,
+ .end = IRQ_EP93XX_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static struct platform_device ep93xx_ohci_device = {
+ .name = "ep93xx-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ep93xx_ohci_device.dev.coherent_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_ohci_resources),
+ .resource = ep93xx_ohci_resources,
+};
+
+
+/*************************************************************************
+ * EP93xx physmap'ed flash
+ *************************************************************************/
+static struct physmap_flash_data ep93xx_flash_data;
+
+static struct resource ep93xx_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ep93xx_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ep93xx_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ep93xx_flash_resource,
+};
+
+/**
+ * ep93xx_register_flash() - Register the external flash device.
+ * @width: bank width in octets
+ * @start: resource start address
+ * @size: resource size
+ */
+void __init ep93xx_register_flash(unsigned int width,
+ resource_size_t start, resource_size_t size)
+{
+ ep93xx_flash_data.width = width;
+
+ ep93xx_flash_resource.start = start;
+ ep93xx_flash_resource.end = start + size - 1;
+
+ platform_device_register(&ep93xx_flash);
+}
+
+
+/*************************************************************************
+ * EP93xx ethernet peripheral handling
+ *************************************************************************/
+static struct ep93xx_eth_data ep93xx_eth_data;
+
+static struct resource ep93xx_eth_resource[] = {
+ {
+ .start = EP93XX_ETHERNET_PHYS_BASE,
+ .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_EP93XX_ETHERNET,
+ .end = IRQ_EP93XX_ETHERNET,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 ep93xx_eth_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ep93xx_eth_device = {
+ .name = "ep93xx-eth",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xx_eth_data,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &ep93xx_eth_dma_mask,
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_eth_resource),
+ .resource = ep93xx_eth_resource,
+};
+
+/**
+ * ep93xx_register_eth - Register the built-in ethernet platform device.
+ * @data: platform specific ethernet configuration (__initdata)
+ * @copy_addr: flag indicating that the MAC address should be copied
+ * from the IndAd registers (as programmed by the bootloader)
+ */
+void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
+{
+ if (copy_addr)
+ memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6);
+
+ ep93xx_eth_data = *data;
+ platform_device_register(&ep93xx_eth_device);
+}
+
+
+/*************************************************************************
+ * EP93xx i2c peripheral handling
+ *************************************************************************/
+static struct i2c_gpio_platform_data ep93xx_i2c_data;
+
+static struct platform_device ep93xx_i2c_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &ep93xx_i2c_data,
+ },
+};
+
+/**
+ * ep93xx_register_i2c - Register the i2c platform device.
+ * @data: platform specific i2c-gpio configuration (__initdata)
+ * @devices: platform specific i2c bus device information (__initdata)
+ * @num: the number of devices on the i2c bus
+ */
+void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
+ struct i2c_board_info *devices, int num)
+{
+ /*
+ * Set the EEPROM interface pin drive type control.
+ * Defines the driver type for the EECLK and EEDAT pins as either
+ * open drain, which will require an external pull-up, or a normal
+ * CMOS driver.
+ */
+ if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
+ pr_warning("sda != EEDAT, open drain has no effect\n");
+ if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
+ pr_warning("scl != EECLK, open drain has no effect\n");
+
+ __raw_writel((data->sda_is_open_drain << 1) |
+ (data->scl_is_open_drain << 0),
+ EP93XX_GPIO_EEDRIVE);
+
+ ep93xx_i2c_data = *data;
+ i2c_register_board_info(0, devices, num);
+ platform_device_register(&ep93xx_i2c_device);
+}
+
+/*************************************************************************
+ * EP93xx SPI peripheral handling
+ *************************************************************************/
+static struct ep93xx_spi_info ep93xx_spi_master_data;
+
+static struct resource ep93xx_spi_resources[] = {
+ {
+ .start = EP93XX_SPI_PHYS_BASE,
+ .end = EP93XX_SPI_PHYS_BASE + 0x18 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EP93XX_SSP,
+ .end = IRQ_EP93XX_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ep93xx_spi_device = {
+ .name = "ep93xx-spi",
+ .id = 0,
+ .dev = {
+ .platform_data = &ep93xx_spi_master_data,
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_spi_resources),
+ .resource = ep93xx_spi_resources,
+};
+
+/**
+ * ep93xx_register_spi() - registers spi platform device
+ * @info: ep93xx board specific spi master info (__initdata)
+ * @devices: SPI devices to register (__initdata)
+ * @num: number of SPI devices to register
+ *
+ * This function registers platform device for the EP93xx SPI controller and
+ * also makes sure that SPI pins are muxed so that I2S is not using those pins.
+ */
+void __init ep93xx_register_spi(struct ep93xx_spi_info *info,
+ struct spi_board_info *devices, int num)
+{
+ /*
+ * When SPI is used, we need to make sure that I2S is muxed off from
+ * SPI pins.
+ */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONSSP);
+
+ ep93xx_spi_master_data = *info;
+ spi_register_board_info(devices, num);
+ platform_device_register(&ep93xx_spi_device);
+}
+
+/*************************************************************************
+ * EP93xx LEDs
+ *************************************************************************/
+static struct gpio_led ep93xx_led_pins[] = {
+ {
+ .name = "platform:grled",
+ .gpio = EP93XX_GPIO_LINE_GRLED,
+ }, {
+ .name = "platform:rdled",
+ .gpio = EP93XX_GPIO_LINE_RDLED,
+ },
+};
+
+static struct gpio_led_platform_data ep93xx_led_data = {
+ .num_leds = ARRAY_SIZE(ep93xx_led_pins),
+ .leds = ep93xx_led_pins,
+};
+
+static struct platform_device ep93xx_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xx_led_data,
+ },
+};
+
+
+/*************************************************************************
+ * EP93xx pwm peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_pwm0_resource[] = {
+ {
+ .start = EP93XX_PWM_PHYS_BASE,
+ .end = EP93XX_PWM_PHYS_BASE + 0x10 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_pwm0_device = {
+ .name = "ep93xx-pwm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ep93xx_pwm0_resource),
+ .resource = ep93xx_pwm0_resource,
+};
+
+static struct resource ep93xx_pwm1_resource[] = {
+ {
+ .start = EP93XX_PWM_PHYS_BASE + 0x20,
+ .end = EP93XX_PWM_PHYS_BASE + 0x30 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_pwm1_device = {
+ .name = "ep93xx-pwm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(ep93xx_pwm1_resource),
+ .resource = ep93xx_pwm1_resource,
+};
+
+void __init ep93xx_register_pwm(int pwm0, int pwm1)
+{
+ if (pwm0)
+ platform_device_register(&ep93xx_pwm0_device);
+
+ /* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */
+ if (pwm1)
+ platform_device_register(&ep93xx_pwm1_device);
+}
+
+int ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
+{
+ int err;
+
+ if (pdev->id == 0) {
+ err = 0;
+ } else if (pdev->id == 1) {
+ err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
+ dev_name(&pdev->dev));
+ if (err)
+ return err;
+ err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
+ if (err)
+ goto fail;
+
+ /* PWM 1 output on EGPIO[14] */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
+ } else {
+ err = -ENODEV;
+ }
+
+ return err;
+
+fail:
+ gpio_free(EP93XX_GPIO_LINE_EGPIO14);
+ return err;
+}
+EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
+
+void ep93xx_pwm_release_gpio(struct platform_device *pdev)
+{
+ if (pdev->id == 1) {
+ gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
+ gpio_free(EP93XX_GPIO_LINE_EGPIO14);
+
+ /* EGPIO[14] used for GPIO */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
+ }
+}
+EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
+
+
+/*************************************************************************
+ * EP93xx video peripheral handling
+ *************************************************************************/
+static struct ep93xxfb_mach_info ep93xxfb_data;
+
+static struct resource ep93xx_fb_resource[] = {
+ {
+ .start = EP93XX_RASTER_PHYS_BASE,
+ .end = EP93XX_RASTER_PHYS_BASE + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_fb_device = {
+ .name = "ep93xx-fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xxfb_data,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .dma_mask = &ep93xx_fb_device.dev.coherent_dma_mask,
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_fb_resource),
+ .resource = ep93xx_fb_resource,
+};
+
+static struct platform_device ep93xx_bl_device = {
+ .name = "ep93xx-bl",
+ .id = -1,
+};
+
+/**
+ * ep93xx_register_fb - Register the framebuffer platform device.
+ * @data: platform specific framebuffer configuration (__initdata)
+ */
+void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
+{
+ ep93xxfb_data = *data;
+ platform_device_register(&ep93xx_fb_device);
+ platform_device_register(&ep93xx_bl_device);
+}
+
+
+/*************************************************************************
+ * EP93xx matrix keypad peripheral handling
+ *************************************************************************/
+static struct ep93xx_keypad_platform_data ep93xx_keypad_data;
+
+static struct resource ep93xx_keypad_resource[] = {
+ {
+ .start = EP93XX_KEY_MATRIX_PHYS_BASE,
+ .end = EP93XX_KEY_MATRIX_PHYS_BASE + 0x0c - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_EP93XX_KEY,
+ .end = IRQ_EP93XX_KEY,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ep93xx_keypad_device = {
+ .name = "ep93xx-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &ep93xx_keypad_data,
+ },
+ .num_resources = ARRAY_SIZE(ep93xx_keypad_resource),
+ .resource = ep93xx_keypad_resource,
+};
+
+/**
+ * ep93xx_register_keypad - Register the keypad platform device.
+ * @data: platform specific keypad configuration (__initdata)
+ */
+void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data)
+{
+ ep93xx_keypad_data = *data;
+ platform_device_register(&ep93xx_keypad_device);
+}
+
+int ep93xx_keypad_acquire_gpio(struct platform_device *pdev)
+{
+ int err;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ err = gpio_request(EP93XX_GPIO_LINE_C(i), dev_name(&pdev->dev));
+ if (err)
+ goto fail_gpio_c;
+ err = gpio_request(EP93XX_GPIO_LINE_D(i), dev_name(&pdev->dev));
+ if (err)
+ goto fail_gpio_d;
+ }
+
+ /* Enable the keypad controller; GPIO ports C and D used for keypad */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+ EP93XX_SYSCON_DEVCFG_GONK);
+
+ return 0;
+
+fail_gpio_d:
+ gpio_free(EP93XX_GPIO_LINE_C(i));
+fail_gpio_c:
+ for ( ; i >= 0; --i) {
+ gpio_free(EP93XX_GPIO_LINE_C(i));
+ gpio_free(EP93XX_GPIO_LINE_D(i));
+ }
+ return err;
+}
+EXPORT_SYMBOL(ep93xx_keypad_acquire_gpio);
+
+void ep93xx_keypad_release_gpio(struct platform_device *pdev)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ gpio_free(EP93XX_GPIO_LINE_C(i));
+ gpio_free(EP93XX_GPIO_LINE_D(i));
+ }
+
+ /* Disable the keypad controller; GPIO ports C and D used for GPIO */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+ EP93XX_SYSCON_DEVCFG_GONK);
+}
+EXPORT_SYMBOL(ep93xx_keypad_release_gpio);
+
+/*************************************************************************
+ * EP93xx I2S audio peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_i2s_resource[] = {
+ {
+ .start = EP93XX_I2S_PHYS_BASE,
+ .end = EP93XX_I2S_PHYS_BASE + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ep93xx_i2s_device = {
+ .name = "ep93xx-i2s",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_i2s_resource),
+ .resource = ep93xx_i2s_resource,
+};
+
+static struct platform_device ep93xx_pcm_device = {
+ .name = "ep93xx-pcm-audio",
+ .id = -1,
+};
+
+void __init ep93xx_register_i2s(void)
+{
+ platform_device_register(&ep93xx_i2s_device);
+ platform_device_register(&ep93xx_pcm_device);
+}
+
+#define EP93XX_SYSCON_DEVCFG_I2S_MASK (EP93XX_SYSCON_DEVCFG_I2SONSSP | \
+ EP93XX_SYSCON_DEVCFG_I2SONAC97)
+
+#define EP93XX_I2SCLKDIV_MASK (EP93XX_SYSCON_I2SCLKDIV_ORIDE | \
+ EP93XX_SYSCON_I2SCLKDIV_SPOL)
+
+int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config)
+{
+ unsigned val;
+
+ /* Sanity check */
+ if (i2s_pins & ~EP93XX_SYSCON_DEVCFG_I2S_MASK)
+ return -EINVAL;
+ if (i2s_config & ~EP93XX_I2SCLKDIV_MASK)
+ return -EINVAL;
+
+ /* Must have only one of I2SONSSP/I2SONAC97 set */
+ if ((i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONSSP) ==
+ (i2s_pins & EP93XX_SYSCON_DEVCFG_I2SONAC97))
+ return -EINVAL;
+
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
+ ep93xx_devcfg_set_bits(i2s_pins);
+
+ /*
+ * This is potentially racy with the clock api for i2s_mclk, sclk and
+ * lrclk. Since the i2s driver is the only user of those clocks we
+ * rely on it to prevent parallel use of this function and the
+ * clock api for the i2s clocks.
+ */
+ val = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
+ val &= ~EP93XX_I2SCLKDIV_MASK;
+ val |= i2s_config;
+ ep93xx_syscon_swlocked_write(val, EP93XX_SYSCON_I2SCLKDIV);
+
+ return 0;
+}
+EXPORT_SYMBOL(ep93xx_i2s_acquire);
+
+void ep93xx_i2s_release(void)
+{
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2S_MASK);
+}
+EXPORT_SYMBOL(ep93xx_i2s_release);
+
+/*************************************************************************
+ * EP93xx AC97 audio peripheral handling
+ *************************************************************************/
+static struct resource ep93xx_ac97_resources[] = {
+ {
+ .start = EP93XX_AAC_PHYS_BASE,
+ .end = EP93XX_AAC_PHYS_BASE + 0xac - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EP93XX_AACINTR,
+ .end = IRQ_EP93XX_AACINTR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ep93xx_ac97_device = {
+ .name = "ep93xx-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ep93xx_ac97_resources),
+ .resource = ep93xx_ac97_resources,
+};
+
+void __init ep93xx_register_ac97(void)
+{
+ /*
+ * Make sure that the AC97 pins are not used by I2S.
+ */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_I2SONAC97);
+
+ platform_device_register(&ep93xx_ac97_device);
+ platform_device_register(&ep93xx_pcm_device);
+}
+
+extern void ep93xx_gpio_init(void);
+
+void __init ep93xx_init_devices(void)
+{
+ /* Disallow access to MaverickCrunch initially */
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
+
+ ep93xx_gpio_init();
+
+ amba_device_register(&uart1_device, &iomem_resource);
+ amba_device_register(&uart2_device, &iomem_resource);
+ amba_device_register(&uart3_device, &iomem_resource);
+
+ platform_device_register(&ep93xx_rtc_device);
+ platform_device_register(&ep93xx_ohci_device);
+ platform_device_register(&ep93xx_leds);
+}
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c
new file mode 100644
index 00000000..a696d354
--- /dev/null
+++ b/arch/arm/mach-ep93xx/dma-m2p.c
@@ -0,0 +1,411 @@
+/*
+ * arch/arm/mach-ep93xx/dma-m2p.c
+ * M2P DMA handling for Cirrus EP93xx chips.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2006 Applied Data Systems
+ *
+ * Copyright (C) 2009 Ryan Mallon <ryan@bluewatersys.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.
+ */
+
+/*
+ * On the EP93xx chip the following peripherals my be allocated to the 10
+ * Memory to Internal Peripheral (M2P) channels (5 transmit + 5 receive).
+ *
+ * I2S contains 3 Tx and 3 Rx DMA Channels
+ * AAC contains 3 Tx and 3 Rx DMA Channels
+ * UART1 contains 1 Tx and 1 Rx DMA Channels
+ * UART2 contains 1 Tx and 1 Rx DMA Channels
+ * UART3 contains 1 Tx and 1 Rx DMA Channels
+ * IrDA contains 1 Tx and 1 Rx DMA Channels
+ *
+ * SSP and IDE use the Memory to Memory (M2M) channels and are not covered
+ * with this implementation.
+ */
+
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+#include <mach/hardware.h>
+
+#define M2P_CONTROL 0x00
+#define M2P_CONTROL_STALL_IRQ_EN (1 << 0)
+#define M2P_CONTROL_NFB_IRQ_EN (1 << 1)
+#define M2P_CONTROL_ERROR_IRQ_EN (1 << 3)
+#define M2P_CONTROL_ENABLE (1 << 4)
+#define M2P_INTERRUPT 0x04
+#define M2P_INTERRUPT_STALL (1 << 0)
+#define M2P_INTERRUPT_NFB (1 << 1)
+#define M2P_INTERRUPT_ERROR (1 << 3)
+#define M2P_PPALLOC 0x08
+#define M2P_STATUS 0x0c
+#define M2P_REMAIN 0x14
+#define M2P_MAXCNT0 0x20
+#define M2P_BASE0 0x24
+#define M2P_MAXCNT1 0x30
+#define M2P_BASE1 0x34
+
+#define STATE_IDLE 0 /* Channel is inactive. */
+#define STATE_STALL 1 /* Channel is active, no buffers pending. */
+#define STATE_ON 2 /* Channel is active, one buffer pending. */
+#define STATE_NEXT 3 /* Channel is active, two buffers pending. */
+
+struct m2p_channel {
+ char *name;
+ void __iomem *base;
+ int irq;
+
+ struct clk *clk;
+ spinlock_t lock;
+
+ void *client;
+ unsigned next_slot:1;
+ struct ep93xx_dma_buffer *buffer_xfer;
+ struct ep93xx_dma_buffer *buffer_next;
+ struct list_head buffers_pending;
+};
+
+static struct m2p_channel m2p_rx[] = {
+ {"m2p1", EP93XX_DMA_BASE + 0x0040, IRQ_EP93XX_DMAM2P1},
+ {"m2p3", EP93XX_DMA_BASE + 0x00c0, IRQ_EP93XX_DMAM2P3},
+ {"m2p5", EP93XX_DMA_BASE + 0x0200, IRQ_EP93XX_DMAM2P5},
+ {"m2p7", EP93XX_DMA_BASE + 0x0280, IRQ_EP93XX_DMAM2P7},
+ {"m2p9", EP93XX_DMA_BASE + 0x0300, IRQ_EP93XX_DMAM2P9},
+ {NULL},
+};
+
+static struct m2p_channel m2p_tx[] = {
+ {"m2p0", EP93XX_DMA_BASE + 0x0000, IRQ_EP93XX_DMAM2P0},
+ {"m2p2", EP93XX_DMA_BASE + 0x0080, IRQ_EP93XX_DMAM2P2},
+ {"m2p4", EP93XX_DMA_BASE + 0x0240, IRQ_EP93XX_DMAM2P4},
+ {"m2p6", EP93XX_DMA_BASE + 0x02c0, IRQ_EP93XX_DMAM2P6},
+ {"m2p8", EP93XX_DMA_BASE + 0x0340, IRQ_EP93XX_DMAM2P8},
+ {NULL},
+};
+
+static void feed_buf(struct m2p_channel *ch, struct ep93xx_dma_buffer *buf)
+{
+ if (ch->next_slot == 0) {
+ writel(buf->size, ch->base + M2P_MAXCNT0);
+ writel(buf->bus_addr, ch->base + M2P_BASE0);
+ } else {
+ writel(buf->size, ch->base + M2P_MAXCNT1);
+ writel(buf->bus_addr, ch->base + M2P_BASE1);
+ }
+ ch->next_slot ^= 1;
+}
+
+static void choose_buffer_xfer(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_buffer *buf;
+
+ ch->buffer_xfer = NULL;
+ if (!list_empty(&ch->buffers_pending)) {
+ buf = list_entry(ch->buffers_pending.next,
+ struct ep93xx_dma_buffer, list);
+ list_del(&buf->list);
+ feed_buf(ch, buf);
+ ch->buffer_xfer = buf;
+ }
+}
+
+static void choose_buffer_next(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_buffer *buf;
+
+ ch->buffer_next = NULL;
+ if (!list_empty(&ch->buffers_pending)) {
+ buf = list_entry(ch->buffers_pending.next,
+ struct ep93xx_dma_buffer, list);
+ list_del(&buf->list);
+ feed_buf(ch, buf);
+ ch->buffer_next = buf;
+ }
+}
+
+static inline void m2p_set_control(struct m2p_channel *ch, u32 v)
+{
+ /*
+ * The control register must be read immediately after being written so
+ * that the internal state machine is correctly updated. See the ep93xx
+ * users' guide for details.
+ */
+ writel(v, ch->base + M2P_CONTROL);
+ readl(ch->base + M2P_CONTROL);
+}
+
+static inline int m2p_channel_state(struct m2p_channel *ch)
+{
+ return (readl(ch->base + M2P_STATUS) >> 4) & 0x3;
+}
+
+static irqreturn_t m2p_irq(int irq, void *dev_id)
+{
+ struct m2p_channel *ch = dev_id;
+ struct ep93xx_dma_m2p_client *cl;
+ u32 irq_status, v;
+ int error = 0;
+
+ cl = ch->client;
+
+ spin_lock(&ch->lock);
+ irq_status = readl(ch->base + M2P_INTERRUPT);
+
+ if (irq_status & M2P_INTERRUPT_ERROR) {
+ writel(M2P_INTERRUPT_ERROR, ch->base + M2P_INTERRUPT);
+ error = 1;
+ }
+
+ if ((irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) == 0) {
+ spin_unlock(&ch->lock);
+ return IRQ_NONE;
+ }
+
+ switch (m2p_channel_state(ch)) {
+ case STATE_IDLE:
+ pr_crit("dma interrupt without a dma buffer\n");
+ BUG();
+ break;
+
+ case STATE_STALL:
+ cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+ if (ch->buffer_next != NULL) {
+ cl->buffer_finished(cl->cookie, ch->buffer_next,
+ 0, error);
+ }
+ choose_buffer_xfer(ch);
+ choose_buffer_next(ch);
+ if (ch->buffer_xfer != NULL)
+ cl->buffer_started(cl->cookie, ch->buffer_xfer);
+ break;
+
+ case STATE_ON:
+ cl->buffer_finished(cl->cookie, ch->buffer_xfer, 0, error);
+ ch->buffer_xfer = ch->buffer_next;
+ choose_buffer_next(ch);
+ cl->buffer_started(cl->cookie, ch->buffer_xfer);
+ break;
+
+ case STATE_NEXT:
+ pr_crit("dma interrupt while next\n");
+ BUG();
+ break;
+ }
+
+ v = readl(ch->base + M2P_CONTROL) & ~(M2P_CONTROL_STALL_IRQ_EN |
+ M2P_CONTROL_NFB_IRQ_EN);
+ if (ch->buffer_xfer != NULL)
+ v |= M2P_CONTROL_STALL_IRQ_EN;
+ if (ch->buffer_next != NULL)
+ v |= M2P_CONTROL_NFB_IRQ_EN;
+ m2p_set_control(ch, v);
+
+ spin_unlock(&ch->lock);
+ return IRQ_HANDLED;
+}
+
+static struct m2p_channel *find_free_channel(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch;
+ int i;
+
+ if (cl->flags & EP93XX_DMA_M2P_RX)
+ ch = m2p_rx;
+ else
+ ch = m2p_tx;
+
+ for (i = 0; ch[i].base; i++) {
+ struct ep93xx_dma_m2p_client *client;
+
+ client = ch[i].client;
+ if (client != NULL) {
+ int port;
+
+ port = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+ if (port == (client->flags &
+ EP93XX_DMA_M2P_PORT_MASK)) {
+ pr_warning("DMA channel already used by %s\n",
+ cl->name ? : "unknown client");
+ return ERR_PTR(-EBUSY);
+ }
+ }
+ }
+
+ for (i = 0; ch[i].base; i++) {
+ if (ch[i].client == NULL)
+ return ch + i;
+ }
+
+ pr_warning("No free DMA channel for %s\n",
+ cl->name ? : "unknown client");
+ return ERR_PTR(-ENODEV);
+}
+
+static void channel_enable(struct m2p_channel *ch)
+{
+ struct ep93xx_dma_m2p_client *cl = ch->client;
+ u32 v;
+
+ clk_enable(ch->clk);
+
+ v = cl->flags & EP93XX_DMA_M2P_PORT_MASK;
+ writel(v, ch->base + M2P_PPALLOC);
+
+ v = cl->flags & EP93XX_DMA_M2P_ERROR_MASK;
+ v |= M2P_CONTROL_ENABLE | M2P_CONTROL_ERROR_IRQ_EN;
+ m2p_set_control(ch, v);
+}
+
+static void channel_disable(struct m2p_channel *ch)
+{
+ u32 v;
+
+ v = readl(ch->base + M2P_CONTROL);
+ v &= ~(M2P_CONTROL_STALL_IRQ_EN | M2P_CONTROL_NFB_IRQ_EN);
+ m2p_set_control(ch, v);
+
+ while (m2p_channel_state(ch) >= STATE_ON)
+ cpu_relax();
+
+ m2p_set_control(ch, 0x0);
+
+ while (m2p_channel_state(ch) == STATE_STALL)
+ cpu_relax();
+
+ clk_disable(ch->clk);
+}
+
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch;
+ int err;
+
+ ch = find_free_channel(cl);
+ if (IS_ERR(ch))
+ return PTR_ERR(ch);
+
+ err = request_irq(ch->irq, m2p_irq, 0, cl->name ? : "dma-m2p", ch);
+ if (err)
+ return err;
+
+ ch->client = cl;
+ ch->next_slot = 0;
+ ch->buffer_xfer = NULL;
+ ch->buffer_next = NULL;
+ INIT_LIST_HEAD(&ch->buffers_pending);
+
+ cl->channel = ch;
+
+ channel_enable(ch);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_register);
+
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ channel_disable(ch);
+ free_irq(ch->irq, ch);
+ ch->client = NULL;
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_client_unregister);
+
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *cl,
+ struct ep93xx_dma_buffer *buf)
+{
+ struct m2p_channel *ch = cl->channel;
+ unsigned long flags;
+ u32 v;
+
+ spin_lock_irqsave(&ch->lock, flags);
+ v = readl(ch->base + M2P_CONTROL);
+ if (ch->buffer_xfer == NULL) {
+ ch->buffer_xfer = buf;
+ feed_buf(ch, buf);
+ cl->buffer_started(cl->cookie, buf);
+
+ v |= M2P_CONTROL_STALL_IRQ_EN;
+ m2p_set_control(ch, v);
+
+ } else if (ch->buffer_next == NULL) {
+ ch->buffer_next = buf;
+ feed_buf(ch, buf);
+
+ v |= M2P_CONTROL_NFB_IRQ_EN;
+ m2p_set_control(ch, v);
+ } else {
+ list_add_tail(&buf->list, &ch->buffers_pending);
+ }
+ spin_unlock_irqrestore(&ch->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit);
+
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *cl,
+ struct ep93xx_dma_buffer *buf)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ list_add_tail(&buf->list, &ch->buffers_pending);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_submit_recursive);
+
+void ep93xx_dma_m2p_flush(struct ep93xx_dma_m2p_client *cl)
+{
+ struct m2p_channel *ch = cl->channel;
+
+ channel_disable(ch);
+ ch->next_slot = 0;
+ ch->buffer_xfer = NULL;
+ ch->buffer_next = NULL;
+ INIT_LIST_HEAD(&ch->buffers_pending);
+ channel_enable(ch);
+}
+EXPORT_SYMBOL_GPL(ep93xx_dma_m2p_flush);
+
+static int init_channel(struct m2p_channel *ch)
+{
+ ch->clk = clk_get(NULL, ch->name);
+ if (IS_ERR(ch->clk))
+ return PTR_ERR(ch->clk);
+
+ spin_lock_init(&ch->lock);
+ ch->client = NULL;
+
+ return 0;
+}
+
+static int __init ep93xx_dma_m2p_init(void)
+{
+ int i;
+ int ret;
+
+ for (i = 0; m2p_rx[i].base; i++) {
+ ret = init_channel(m2p_rx + i);
+ if (ret)
+ return ret;
+ }
+
+ for (i = 0; m2p_tx[i].base; i++) {
+ ret = init_channel(m2p_tx + i);
+ if (ret)
+ return ret;
+ }
+
+ pr_info("M2P DMA subsystem initialized\n");
+ return 0;
+}
+arch_initcall(ep93xx_dma_m2p_init);
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
new file mode 100644
index 00000000..9969bb11
--- /dev/null
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -0,0 +1,326 @@
+/*
+ * arch/arm/mach-ep93xx/edb93xx.c
+ * Cirrus Logic EDB93xx Development Board support.
+ *
+ * EDB93XX, EDB9301, EDB9307A
+ * Copyright (C) 2008-2009 H Hartley Sweeten <hsweeten@visionengravers.com>
+ *
+ * EDB9302
+ * Copyright (C) 2006 George Kashperko <george@chas.com.ua>
+ *
+ * EDB9302A, EDB9315, EDB9315A
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * EDB9307
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * EDB9312
+ * Copyright (C) 2006 Infosys Technologies Limited
+ * Toufeeq Hussain <toufeeq_hussain@infosys.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+
+#include <sound/cs4271.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <mach/ep93xx_spi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+static void __init edb93xx_register_flash(void)
+{
+ if (machine_is_edb9307() || machine_is_edb9312() ||
+ machine_is_edb9315()) {
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
+ } else {
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
+ }
+}
+
+static struct ep93xx_eth_data __initdata edb93xx_eth_data = {
+ .phy_id = 1,
+};
+
+
+/*************************************************************************
+ * EDB93xx i2c peripheral handling
+ *************************************************************************/
+static struct i2c_gpio_platform_data __initdata edb93xx_i2c_gpio_data = {
+ .sda_pin = EP93XX_GPIO_LINE_EEDAT,
+ .sda_is_open_drain = 0,
+ .scl_pin = EP93XX_GPIO_LINE_EECLK,
+ .scl_is_open_drain = 0,
+ .udelay = 0, /* default to 100 kHz */
+ .timeout = 0, /* default to 100 ms */
+};
+
+static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ },
+};
+
+static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ },
+};
+
+static void __init edb93xx_register_i2c(void)
+{
+ if (machine_is_edb9302a() || machine_is_edb9307a() ||
+ machine_is_edb9315a()) {
+ ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
+ edb93xxa_i2c_board_info,
+ ARRAY_SIZE(edb93xxa_i2c_board_info));
+ } else if (machine_is_edb9307() || machine_is_edb9312() ||
+ machine_is_edb9315()) {
+ ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
+ edb93xx_i2c_board_info,
+ ARRAY_SIZE(edb93xx_i2c_board_info));
+ }
+}
+
+
+/*************************************************************************
+ * EDB93xx SPI peripheral handling
+ *************************************************************************/
+static struct cs4271_platform_data edb93xx_cs4271_data = {
+ .gpio_nreset = -EINVAL, /* filled in later */
+};
+
+static int edb93xx_cs4271_hw_setup(struct spi_device *spi)
+{
+ return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6,
+ GPIOF_OUT_INIT_HIGH, spi->modalias);
+}
+
+static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi)
+{
+ gpio_free(EP93XX_GPIO_LINE_EGPIO6);
+}
+
+static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value)
+{
+ gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value);
+}
+
+static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = {
+ .setup = edb93xx_cs4271_hw_setup,
+ .cleanup = edb93xx_cs4271_hw_cleanup,
+ .cs_control = edb93xx_cs4271_hw_cs_control,
+};
+
+static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
+ {
+ .modalias = "cs4271",
+ .platform_data = &edb93xx_cs4271_data,
+ .controller_data = &edb93xx_cs4271_hw,
+ .max_speed_hz = 6000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ },
+};
+
+static struct ep93xx_spi_info edb93xx_spi_info __initdata = {
+ .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info),
+};
+
+static void __init edb93xx_register_spi(void)
+{
+ if (machine_is_edb9301() || machine_is_edb9302())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
+ else if (machine_is_edb9302a() || machine_is_edb9307a())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
+ else if (machine_is_edb9315a())
+ edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
+
+ ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
+ ARRAY_SIZE(edb93xx_spi_board_info));
+}
+
+
+/*************************************************************************
+ * EDB93xx I2S
+ *************************************************************************/
+static int __init edb93xx_has_audio(void)
+{
+ return (machine_is_edb9301() || machine_is_edb9302() ||
+ machine_is_edb9302a() || machine_is_edb9307a() ||
+ machine_is_edb9315a());
+}
+
+static void __init edb93xx_register_i2s(void)
+{
+ if (edb93xx_has_audio()) {
+ ep93xx_register_i2s();
+ }
+}
+
+
+/*************************************************************************
+ * EDB93xx pwm
+ *************************************************************************/
+static void __init edb93xx_register_pwm(void)
+{
+ if (machine_is_edb9301() ||
+ machine_is_edb9302() || machine_is_edb9302a()) {
+ /* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
+ ep93xx_register_pwm(0, 1);
+ } else if (machine_is_edb9307() || machine_is_edb9307a()) {
+ /* EP9307 only has pwm.0 (PWMOUT) */
+ ep93xx_register_pwm(1, 0);
+ } else {
+ /* EP9312 and EP9315 have both */
+ ep93xx_register_pwm(1, 1);
+ }
+}
+
+
+/*************************************************************************
+ * EDB93xx framebuffer
+ *************************************************************************/
+static struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
+ .num_modes = EP93XXFB_USE_MODEDB,
+ .bpp = 16,
+ .flags = 0,
+};
+
+static int __init edb93xx_has_fb(void)
+{
+ /* These platforms have an ep93xx with video capability */
+ return machine_is_edb9307() || machine_is_edb9307a() ||
+ machine_is_edb9312() || machine_is_edb9315() ||
+ machine_is_edb9315a();
+}
+
+static void __init edb93xx_register_fb(void)
+{
+ if (!edb93xx_has_fb())
+ return;
+
+ if (machine_is_edb9307a() || machine_is_edb9315a())
+ edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
+ else
+ edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
+
+ ep93xx_register_fb(&edb93xxfb_info);
+}
+
+
+static void __init edb93xx_init_machine(void)
+{
+ ep93xx_init_devices();
+ edb93xx_register_flash();
+ ep93xx_register_eth(&edb93xx_eth_data, 1);
+ edb93xx_register_i2c();
+ edb93xx_register_spi();
+ edb93xx_register_i2s();
+ edb93xx_register_pwm();
+ edb93xx_register_fb();
+}
+
+
+#ifdef CONFIG_MACH_EDB9301
+MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
+ /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9302
+MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
+ /* Maintainer: George Kashperko <george@chas.com.ua> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9302A
+MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9307
+MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
+ /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9307A
+MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
+ /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
+ .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9312
+MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
+ /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9315
+MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EDB9315A
+MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = edb93xx_init_machine,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
new file mode 100644
index 00000000..9bd3152b
--- /dev/null
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ep93xx/gesbc9312.c
+ * Glomation GESBC-9312-sx support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
+ .phy_id = 1,
+};
+
+static void __init gesbc9312_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_8M);
+ ep93xx_register_eth(&gesbc9312_eth_data, 0);
+}
+
+MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = gesbc9312_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
new file mode 100644
index 00000000..415dce37
--- /dev/null
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -0,0 +1,410 @@
+/*
+ * linux/arch/arm/mach-ep93xx/gpio.c
+ *
+ * Generic EP93xx GPIO handling
+ *
+ * Copyright (c) 2008 Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * Based on code originally from:
+ * linux/arch/arm/mach-ep93xx/core.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.
+ */
+
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+
+/*************************************************************************
+ * Interrupt handling for EP93xx on-chip GPIOs
+ *************************************************************************/
+static unsigned char gpio_int_unmasked[3];
+static unsigned char gpio_int_enabled[3];
+static unsigned char gpio_int_type1[3];
+static unsigned char gpio_int_type2[3];
+static unsigned char gpio_int_debounce[3];
+
+/* Port ordering is: A B F */
+static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c };
+static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 };
+static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
+static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
+static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
+
+static void ep93xx_gpio_update_int_params(unsigned port)
+{
+ BUG_ON(port > 2);
+
+ __raw_writeb(0, EP93XX_GPIO_REG(int_en_register_offset[port]));
+
+ __raw_writeb(gpio_int_type2[port],
+ EP93XX_GPIO_REG(int_type2_register_offset[port]));
+
+ __raw_writeb(gpio_int_type1[port],
+ EP93XX_GPIO_REG(int_type1_register_offset[port]));
+
+ __raw_writeb(gpio_int_unmasked[port] & gpio_int_enabled[port],
+ EP93XX_GPIO_REG(int_en_register_offset[port]));
+}
+
+static inline void ep93xx_gpio_int_mask(unsigned line)
+{
+ gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
+}
+
+static void ep93xx_gpio_int_debounce(unsigned int irq, bool enable)
+{
+ int line = irq_to_gpio(irq);
+ int port = line >> 3;
+ int port_mask = 1 << (line & 7);
+
+ if (enable)
+ gpio_int_debounce[port] |= port_mask;
+ else
+ gpio_int_debounce[port] &= ~port_mask;
+
+ __raw_writeb(gpio_int_debounce[port],
+ EP93XX_GPIO_REG(int_debounce_register_offset[port]));
+}
+
+static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned char status;
+ int i;
+
+ status = __raw_readb(EP93XX_GPIO_A_INT_STATUS);
+ for (i = 0; i < 8; i++) {
+ if (status & (1 << i)) {
+ int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_A(0)) + i;
+ generic_handle_irq(gpio_irq);
+ }
+ }
+
+ status = __raw_readb(EP93XX_GPIO_B_INT_STATUS);
+ for (i = 0; i < 8; i++) {
+ if (status & (1 << i)) {
+ int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_B(0)) + i;
+ generic_handle_irq(gpio_irq);
+ }
+ }
+}
+
+static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ /*
+ * map discontiguous hw irq range to continuous sw irq range:
+ *
+ * IRQ_EP93XX_GPIO{0..7}MUX -> gpio_to_irq(EP93XX_GPIO_LINE_F({0..7})
+ */
+ int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */
+ int gpio_irq = gpio_to_irq(EP93XX_GPIO_LINE_F(0)) + port_f_idx;
+
+ generic_handle_irq(gpio_irq);
+}
+
+static void ep93xx_gpio_irq_ack(struct irq_data *d)
+{
+ int line = irq_to_gpio(d->irq);
+ int port = line >> 3;
+ int port_mask = 1 << (line & 7);
+
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
+ gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+ ep93xx_gpio_update_int_params(port);
+ }
+
+ __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
+{
+ int line = irq_to_gpio(d->irq);
+ int port = line >> 3;
+ int port_mask = 1 << (line & 7);
+
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
+ gpio_int_type2[port] ^= port_mask; /* switch edge direction */
+
+ gpio_int_unmasked[port] &= ~port_mask;
+ ep93xx_gpio_update_int_params(port);
+
+ __raw_writeb(port_mask, EP93XX_GPIO_REG(eoi_register_offset[port]));
+}
+
+static void ep93xx_gpio_irq_mask(struct irq_data *d)
+{
+ int line = irq_to_gpio(d->irq);
+ int port = line >> 3;
+
+ gpio_int_unmasked[port] &= ~(1 << (line & 7));
+ ep93xx_gpio_update_int_params(port);
+}
+
+static void ep93xx_gpio_irq_unmask(struct irq_data *d)
+{
+ int line = irq_to_gpio(d->irq);
+ int port = line >> 3;
+
+ gpio_int_unmasked[port] |= 1 << (line & 7);
+ ep93xx_gpio_update_int_params(port);
+}
+
+/*
+ * gpio_int_type1 controls whether the interrupt is level (0) or
+ * edge (1) triggered, while gpio_int_type2 controls whether it
+ * triggers on low/falling (0) or high/rising (1).
+ */
+static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+ const int gpio = irq_to_gpio(d->irq);
+ const int port = gpio >> 3;
+ const int port_mask = 1 << (gpio & 7);
+ irq_flow_handler_t handler;
+
+ gpio_direction_input(gpio);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ gpio_int_type1[port] |= port_mask;
+ gpio_int_type2[port] |= port_mask;
+ handler = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ gpio_int_type1[port] |= port_mask;
+ gpio_int_type2[port] &= ~port_mask;
+ handler = handle_edge_irq;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ gpio_int_type1[port] &= ~port_mask;
+ gpio_int_type2[port] |= port_mask;
+ handler = handle_level_irq;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ gpio_int_type1[port] &= ~port_mask;
+ gpio_int_type2[port] &= ~port_mask;
+ handler = handle_level_irq;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ gpio_int_type1[port] |= port_mask;
+ /* set initial polarity based on current input level */
+ if (gpio_get_value(gpio))
+ gpio_int_type2[port] &= ~port_mask; /* falling */
+ else
+ gpio_int_type2[port] |= port_mask; /* rising */
+ handler = handle_edge_irq;
+ break;
+ default:
+ pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
+ return -EINVAL;
+ }
+
+ __irq_set_handler_locked(d->irq, handler);
+
+ gpio_int_enabled[port] |= port_mask;
+
+ ep93xx_gpio_update_int_params(port);
+
+ return 0;
+}
+
+static struct irq_chip ep93xx_gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_ack = ep93xx_gpio_irq_ack,
+ .irq_mask_ack = ep93xx_gpio_irq_mask_ack,
+ .irq_mask = ep93xx_gpio_irq_mask,
+ .irq_unmask = ep93xx_gpio_irq_unmask,
+ .irq_set_type = ep93xx_gpio_irq_type,
+};
+
+void __init ep93xx_gpio_init_irq(void)
+{
+ int gpio_irq;
+
+ for (gpio_irq = gpio_to_irq(0);
+ gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
+ irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+ handle_level_irq);
+ set_irq_flags(gpio_irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_EP93XX_GPIO_AB,
+ ep93xx_gpio_ab_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX,
+ ep93xx_gpio_f_irq_handler);
+}
+
+
+/*************************************************************************
+ * gpiolib interface for EP93xx on-chip GPIOs
+ *************************************************************************/
+struct ep93xx_gpio_chip {
+ struct gpio_chip chip;
+
+ void __iomem *data_reg;
+ void __iomem *data_dir_reg;
+};
+
+#define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip)
+
+static int ep93xx_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
+ unsigned long flags;
+ u8 v;
+
+ local_irq_save(flags);
+ v = __raw_readb(ep93xx_chip->data_dir_reg);
+ v &= ~(1 << offset);
+ __raw_writeb(v, ep93xx_chip->data_dir_reg);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int ep93xx_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
+ unsigned long flags;
+ int line;
+ u8 v;
+
+ local_irq_save(flags);
+
+ /* Set the value */
+ v = __raw_readb(ep93xx_chip->data_reg);
+ if (val)
+ v |= (1 << offset);
+ else
+ v &= ~(1 << offset);
+ __raw_writeb(v, ep93xx_chip->data_reg);
+
+ /* Drive as an output */
+ line = chip->base + offset;
+ if (line <= EP93XX_GPIO_LINE_MAX_IRQ) {
+ /* Ports A/B/F */
+ ep93xx_gpio_int_mask(line);
+ ep93xx_gpio_update_int_params(line >> 3);
+ }
+
+ v = __raw_readb(ep93xx_chip->data_dir_reg);
+ v |= (1 << offset);
+ __raw_writeb(v, ep93xx_chip->data_dir_reg);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int ep93xx_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
+
+ return !!(__raw_readb(ep93xx_chip->data_reg) & (1 << offset));
+}
+
+static void ep93xx_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
+ unsigned long flags;
+ u8 v;
+
+ local_irq_save(flags);
+ v = __raw_readb(ep93xx_chip->data_reg);
+ if (val)
+ v |= (1 << offset);
+ else
+ v &= ~(1 << offset);
+ __raw_writeb(v, ep93xx_chip->data_reg);
+ local_irq_restore(flags);
+}
+
+static int ep93xx_gpio_set_debounce(struct gpio_chip *chip,
+ unsigned offset, unsigned debounce)
+{
+ int gpio = chip->base + offset;
+ int irq = gpio_to_irq(gpio);
+
+ if (irq < 0)
+ return -EINVAL;
+
+ ep93xx_gpio_int_debounce(irq, debounce ? true : false);
+
+ return 0;
+}
+
+#define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = ep93xx_gpio_direction_input, \
+ .direction_output = ep93xx_gpio_direction_output, \
+ .get = ep93xx_gpio_get, \
+ .set = ep93xx_gpio_set, \
+ .base = base_gpio, \
+ .ngpio = 8, \
+ }, \
+ .data_reg = EP93XX_GPIO_REG(dr), \
+ .data_dir_reg = EP93XX_GPIO_REG(ddr), \
+ }
+
+static struct ep93xx_gpio_chip ep93xx_gpio_banks[] = {
+ EP93XX_GPIO_BANK("A", 0x00, 0x10, 0),
+ EP93XX_GPIO_BANK("B", 0x04, 0x14, 8),
+ EP93XX_GPIO_BANK("C", 0x08, 0x18, 40),
+ EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24),
+ EP93XX_GPIO_BANK("E", 0x20, 0x24, 32),
+ EP93XX_GPIO_BANK("F", 0x30, 0x34, 16),
+ EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48),
+ EP93XX_GPIO_BANK("H", 0x40, 0x44, 56),
+};
+
+void __init ep93xx_gpio_init(void)
+{
+ int i;
+
+ /* Set Ports C, D, E, G, and H for GPIO use */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+ EP93XX_SYSCON_DEVCFG_GONK |
+ EP93XX_SYSCON_DEVCFG_EONIDE |
+ EP93XX_SYSCON_DEVCFG_GONIDE |
+ EP93XX_SYSCON_DEVCFG_HONIDE);
+
+ for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) {
+ struct gpio_chip *chip = &ep93xx_gpio_banks[i].chip;
+
+ /*
+ * Ports A, B, and F support input debouncing when
+ * used as interrupts.
+ */
+ if (!strcmp(chip->label, "A") ||
+ !strcmp(chip->label, "B") ||
+ !strcmp(chip->label, "F"))
+ chip->set_debounce = ep93xx_gpio_set_debounce;
+
+ gpiochip_add(chip);
+ }
+}
diff --git a/arch/arm/mach-ep93xx/include/mach/clkdev.h b/arch/arm/mach-ep93xx/include/mach/clkdev.h
new file mode 100644
index 00000000..50cb991e
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/clkdev.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/clkdev.h
+ */
+
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/debug-macro.S b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..b25bc907
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/debug-macro.S
+ * Debugging macro include header
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+#include <mach/ep93xx-regs.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =EP93XX_APB_PHYS_BASE @ Physical base
+ ldr \rv, =EP93XX_APB_VIRT_BASE @ virtual base
+ orr \rp, \rp, #0x000c0000
+ orr \rv, \rv, #0x000c0000
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h
new file mode 100644
index 00000000..9be4b2dd
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/dma.h
@@ -0,0 +1,157 @@
+/**
+ * DOC: EP93xx DMA M2P memory to peripheral and peripheral to memory engine
+ *
+ * The EP93xx DMA M2P subsystem handles DMA transfers between memory and
+ * peripherals. DMA M2P channels are available for audio, UARTs and IrDA.
+ * See chapter 10 of the EP93xx users guide for full details on the DMA M2P
+ * engine.
+ *
+ * See sound/soc/ep93xx/ep93xx-pcm.c for an example use of the DMA M2P code.
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+/**
+ * struct ep93xx_dma_buffer - Information about a buffer to be transferred
+ * using the DMA M2P engine
+ *
+ * @list: Entry in DMA buffer list
+ * @bus_addr: Physical address of the buffer
+ * @size: Size of the buffer in bytes
+ */
+struct ep93xx_dma_buffer {
+ struct list_head list;
+ u32 bus_addr;
+ u16 size;
+};
+
+/**
+ * struct ep93xx_dma_m2p_client - Information about a DMA M2P client
+ *
+ * @name: Unique name for this client
+ * @flags: Client flags
+ * @cookie: User data to pass to callback functions
+ * @buffer_started: Non NULL function to call when a transfer is started.
+ * The arguments are the user data cookie and the DMA
+ * buffer which is starting.
+ * @buffer_finished: Non NULL function to call when a transfer is completed.
+ * The arguments are the user data cookie, the DMA buffer
+ * which has completed, and a boolean flag indicating if
+ * the transfer had an error.
+ */
+struct ep93xx_dma_m2p_client {
+ char *name;
+ u8 flags;
+ void *cookie;
+ void (*buffer_started)(void *cookie,
+ struct ep93xx_dma_buffer *buf);
+ void (*buffer_finished)(void *cookie,
+ struct ep93xx_dma_buffer *buf,
+ int bytes, int error);
+
+ /* private: Internal use only */
+ void *channel;
+};
+
+/* DMA M2P ports */
+#define EP93XX_DMA_M2P_PORT_I2S1 0x00
+#define EP93XX_DMA_M2P_PORT_I2S2 0x01
+#define EP93XX_DMA_M2P_PORT_AAC1 0x02
+#define EP93XX_DMA_M2P_PORT_AAC2 0x03
+#define EP93XX_DMA_M2P_PORT_AAC3 0x04
+#define EP93XX_DMA_M2P_PORT_I2S3 0x05
+#define EP93XX_DMA_M2P_PORT_UART1 0x06
+#define EP93XX_DMA_M2P_PORT_UART2 0x07
+#define EP93XX_DMA_M2P_PORT_UART3 0x08
+#define EP93XX_DMA_M2P_PORT_IRDA 0x09
+#define EP93XX_DMA_M2P_PORT_MASK 0x0f
+
+/* DMA M2P client flags */
+#define EP93XX_DMA_M2P_TX 0x00 /* Memory to peripheral */
+#define EP93XX_DMA_M2P_RX 0x10 /* Peripheral to memory */
+
+/*
+ * DMA M2P client error handling flags. See the EP93xx users guide
+ * documentation on the DMA M2P CONTROL register for more details
+ */
+#define EP93XX_DMA_M2P_ABORT_ON_ERROR 0x20 /* Abort on peripheral error */
+#define EP93XX_DMA_M2P_IGNORE_ERROR 0x40 /* Ignore peripheral errors */
+#define EP93XX_DMA_M2P_ERROR_MASK 0x60 /* Mask of error bits */
+
+/**
+ * ep93xx_dma_m2p_client_register - Register a client with the DMA M2P
+ * subsystem
+ *
+ * @m2p: Client information to register
+ * returns 0 on success
+ *
+ * The DMA M2P subsystem allocates a channel and an interrupt line for the DMA
+ * client
+ */
+int ep93xx_dma_m2p_client_register(struct ep93xx_dma_m2p_client *m2p);
+
+/**
+ * ep93xx_dma_m2p_client_unregister - Unregister a client from the DMA M2P
+ * subsystem
+ *
+ * @m2p: Client to unregister
+ *
+ * Any transfers currently in progress will be completed in hardware, but
+ * ignored in software.
+ */
+void ep93xx_dma_m2p_client_unregister(struct ep93xx_dma_m2p_client *m2p);
+
+/**
+ * ep93xx_dma_m2p_submit - Submit a DMA M2P transfer
+ *
+ * @m2p: DMA Client to submit the transfer on
+ * @buf: DMA Buffer to submit
+ *
+ * If the current or next transfer positions are free on the M2P client then
+ * the transfer is started immediately. If not, the transfer is added to the
+ * list of pending transfers. This function must not be called from the
+ * buffer_finished callback for an M2P channel.
+ *
+ */
+void ep93xx_dma_m2p_submit(struct ep93xx_dma_m2p_client *m2p,
+ struct ep93xx_dma_buffer *buf);
+
+/**
+ * ep93xx_dma_m2p_submit_recursive - Put a DMA transfer on the pending list
+ * for an M2P channel
+ *
+ * @m2p: DMA Client to submit the transfer on
+ * @buf: DMA Buffer to submit
+ *
+ * This function must only be called from the buffer_finished callback for an
+ * M2P channel. It is commonly used to add the next transfer in a chained list
+ * of DMA transfers.
+ */
+void ep93xx_dma_m2p_submit_recursive(struct ep93xx_dma_m2p_client *m2p,
+ struct ep93xx_dma_buffer *buf);
+
+/**
+ * ep93xx_dma_m2p_flush - Flush all pending transfers on a DMA M2P client
+ *
+ * @m2p: DMA client to flush transfers on
+ *
+ * Any transfers currently in progress will be completed in hardware, but
+ * ignored in software.
+ *
+ */
+static inline enum dma_transfer_direction
+ep93xx_dma_chan_direction(struct dma_chan *chan)
+{
+ if (!ep93xx_dma_chan_is_m2p(chan))
+ return DMA_NONE;
+
+ /* even channels are for TX, odd for RX */
+ return (chan->chan_id % 2 == 0) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
+}
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/entry-macro.S b/arch/arm/mach-ep93xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..96b85e2c
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/entry-macro.S
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/entry-macro.S
+ * IRQ demultiplexing for EP93xx
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+#include <mach/ep93xx-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =(EP93XX_AHB_VIRT_BASE)
+ orr \base, \base, #0x000b0000
+ mov \irqnr, #0
+ ldr \irqstat, [\base] @ lower 32 interrupts
+ cmp \irqstat, #0
+ bne 1001f
+
+ eor \base, \base, #0x00070000
+ ldr \irqstat, [\base] @ upper 32 interrupts
+ cmp \irqstat, #0
+ beq 1002f
+ mov \irqnr, #0x20
+
+1001:
+ movs \tmp, \irqstat, lsl #16
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+
+ movs \tmp, \irqstat, lsl #8
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #8
+
+ movs \tmp, \irqstat, lsl #4
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #4
+
+ movs \tmp, \irqstat, lsl #2
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #2
+
+ movs \tmp, \irqstat, lsl #1
+ addeq \irqnr, \irqnr, #1
+ orrs \base, \base, #1
+
+1002:
+ .endm
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
new file mode 100644
index 00000000..9ac4d105
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -0,0 +1,229 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+ */
+
+#ifndef __ASM_ARCH_EP93XX_REGS_H
+#define __ASM_ARCH_EP93XX_REGS_H
+
+/*
+ * EP93xx Physical Memory Map:
+ *
+ * The ASDO pin is sampled at system reset to select a synchronous or
+ * asynchronous boot configuration. When ASDO is "1" (i.e. pulled-up)
+ * the synchronous boot mode is selected. When ASDO is "0" (i.e
+ * pulled-down) the asynchronous boot mode is selected.
+ *
+ * In synchronous boot mode nSDCE3 is decoded starting at physical address
+ * 0x00000000 and nCS0 is decoded starting at 0xf0000000. For asynchronous
+ * boot mode they are swapped with nCS0 decoded at 0x00000000 ann nSDCE3
+ * decoded at 0xf0000000.
+ *
+ * There is known errata for the EP93xx dealing with External Memory
+ * Configurations. Please refer to "AN273: EP93xx Silicon Rev E Design
+ * Guidelines" for more information. This document can be found at:
+ *
+ * http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+ */
+
+#define EP93XX_CS0_PHYS_BASE_ASYNC 0x00000000 /* ASDO Pin = 0 */
+#define EP93XX_SDCE3_PHYS_BASE_SYNC 0x00000000 /* ASDO Pin = 1 */
+#define EP93XX_CS1_PHYS_BASE 0x10000000
+#define EP93XX_CS2_PHYS_BASE 0x20000000
+#define EP93XX_CS3_PHYS_BASE 0x30000000
+#define EP93XX_PCMCIA_PHYS_BASE 0x40000000
+#define EP93XX_CS6_PHYS_BASE 0x60000000
+#define EP93XX_CS7_PHYS_BASE 0x70000000
+#define EP93XX_SDCE0_PHYS_BASE 0xc0000000
+#define EP93XX_SDCE1_PHYS_BASE 0xd0000000
+#define EP93XX_SDCE2_PHYS_BASE 0xe0000000
+#define EP93XX_SDCE3_PHYS_BASE_ASYNC 0xf0000000 /* ASDO Pin = 0 */
+#define EP93XX_CS0_PHYS_BASE_SYNC 0xf0000000 /* ASDO Pin = 1 */
+
+/*
+ * EP93xx linux memory map:
+ *
+ * virt phys size
+ * fe800000 5M per-platform mappings
+ * fed00000 80800000 2M APB
+ * fef00000 80000000 1M AHB
+ */
+
+#define EP93XX_AHB_PHYS_BASE 0x80000000
+#define EP93XX_AHB_VIRT_BASE 0xfef00000
+#define EP93XX_AHB_SIZE 0x00100000
+
+#define EP93XX_AHB_PHYS(x) (EP93XX_AHB_PHYS_BASE + (x))
+#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x))
+
+#define EP93XX_APB_PHYS_BASE 0x80800000
+#define EP93XX_APB_VIRT_BASE 0xfed00000
+#define EP93XX_APB_SIZE 0x00200000
+
+#define EP93XX_APB_PHYS(x) (EP93XX_APB_PHYS_BASE + (x))
+#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x))
+
+
+/* AHB peripherals */
+#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000)
+
+#define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000)
+#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000)
+
+#define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000)
+#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
+
+#define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000)
+#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
+
+#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
+
+#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000)
+
+#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000)
+
+#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000)
+
+#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000)
+
+#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000)
+
+#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000)
+
+
+/* APB peripherals */
+#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000)
+
+#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)
+#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
+
+#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
+
+#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
+#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
+#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
+#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
+#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
+#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8)
+
+#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000)
+#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
+
+#define EP93XX_SPI_PHYS_BASE EP93XX_APB_PHYS(0x000a0000)
+#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000)
+
+#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000)
+
+#define EP93XX_UART1_PHYS_BASE EP93XX_APB_PHYS(0x000c0000)
+#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000)
+
+#define EP93XX_UART2_PHYS_BASE EP93XX_APB_PHYS(0x000d0000)
+#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000)
+
+#define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000)
+#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
+
+#define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000)
+#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000)
+
+#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
+#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
+
+#define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000)
+#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
+
+#define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000)
+#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000)
+
+#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000)
+#define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x))
+#define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00)
+#define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04)
+#define EP93XX_SYSCON_PWRCNT_FIR_EN (1<<31)
+#define EP93XX_SYSCON_PWRCNT_UARTBAUD (1<<29)
+#define EP93XX_SYSCON_PWRCNT_USH_EN (1<<28)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M1 (1<<27)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M0 (1<<26)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P8 (1<<25)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P9 (1<<24)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P6 (1<<23)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P7 (1<<22)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P4 (1<<21)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P5 (1<<20)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P2 (1<<19)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P3 (1<<18)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P0 (1<<17)
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 (1<<16)
+#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
+#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
+#define EP93XX_SYSCON_CLKSET1 EP93XX_SYSCON_REG(0x20)
+#define EP93XX_SYSCON_CLKSET1_NBYP1 (1<<23)
+#define EP93XX_SYSCON_CLKSET2 EP93XX_SYSCON_REG(0x24)
+#define EP93XX_SYSCON_CLKSET2_NBYP2 (1<<19)
+#define EP93XX_SYSCON_CLKSET2_PLL2_EN (1<<18)
+#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80)
+#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31)
+#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30)
+#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29)
+#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28)
+#define EP93XX_SYSCON_DEVCFG_GONK (1<<27)
+#define EP93XX_SYSCON_DEVCFG_TONG (1<<26)
+#define EP93XX_SYSCON_DEVCFG_MONG (1<<25)
+#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24)
+#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23)
+#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22)
+#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21)
+#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20)
+#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19)
+#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18)
+#define EP93XX_SYSCON_DEVCFG_TIN (1<<17)
+#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15)
+#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14)
+#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13)
+#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12)
+#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11)
+#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10)
+#define EP93XX_SYSCON_DEVCFG_PONG (1<<9)
+#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8)
+#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7)
+#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6)
+#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4)
+#define EP93XX_SYSCON_DEVCFG_RAS (1<<3)
+#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2)
+#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1)
+#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0)
+#define EP93XX_SYSCON_VIDCLKDIV EP93XX_SYSCON_REG(0x84)
+#define EP93XX_SYSCON_CLKDIV_ENABLE (1<<15)
+#define EP93XX_SYSCON_CLKDIV_ESEL (1<<14)
+#define EP93XX_SYSCON_CLKDIV_PSEL (1<<13)
+#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 8
+#define EP93XX_SYSCON_I2SCLKDIV EP93XX_SYSCON_REG(0x8c)
+#define EP93XX_SYSCON_I2SCLKDIV_SENA (1<<31)
+#define EP93XX_SYSCON_I2SCLKDIV_ORIDE (1<<29)
+#define EP93XX_SYSCON_I2SCLKDIV_SPOL (1<<19)
+#define EP93XX_I2SCLKDIV_SDIV (1 << 16)
+#define EP93XX_I2SCLKDIV_LRDIV32 (0 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV64 (1 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV128 (2 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV_MASK (3 << 17)
+#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
+#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c)
+#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000)
+#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
+#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8)
+#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7)
+#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6)
+#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5)
+#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4)
+#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3)
+#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1)
+#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0)
+#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
+
+#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
+
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
new file mode 100644
index 00000000..1e2f4e97
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h
+ */
+
+#ifndef __ASM_ARCH_EP93XX_KEYPAD_H
+#define __ASM_ARCH_EP93XX_KEYPAD_H
+
+struct matrix_keymap_data;
+
+/* flags for the ep93xx_keypad driver */
+#define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */
+#define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */
+#define EP93XX_KEYPAD_BACK_DRIVE (1<<2) /* back driving mode */
+#define EP93XX_KEYPAD_TEST_MODE (1<<3) /* scan only column 0 */
+#define EP93XX_KEYPAD_KDIV (1<<4) /* 1/4 clock or 1/16 clock */
+#define EP93XX_KEYPAD_AUTOREPEAT (1<<5) /* enable key autorepeat */
+
+/**
+ * struct ep93xx_keypad_platform_data - platform specific device structure
+ * @keymap_data: pointer to &matrix_keymap_data
+ * @debounce: debounce start count; terminal count is 0xff
+ * @prescale: row/column counter pre-scaler load value
+ * @flags: see above
+ */
+struct ep93xx_keypad_platform_data {
+ struct matrix_keymap_data *keymap_data;
+ unsigned int debounce;
+ unsigned int prescale;
+ unsigned int flags;
+};
+
+#define EP93XX_MATRIX_ROWS (8)
+#define EP93XX_MATRIX_COLS (8)
+
+#endif /* __ASM_ARCH_EP93XX_KEYPAD_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h
new file mode 100644
index 00000000..0a37961b
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_MACH_EP93XX_SPI_H
+#define __ASM_MACH_EP93XX_SPI_H
+
+struct spi_device;
+
+/**
+ * struct ep93xx_spi_info - EP93xx specific SPI descriptor
+ * @num_chipselect: number of chip selects on this board, must be
+ * at least one
+ */
+struct ep93xx_spi_info {
+ int num_chipselect;
+};
+
+/**
+ * struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device
+ * @setup: setup the chip select mechanism
+ * @cleanup: cleanup the chip select mechanism
+ * @cs_control: control the device chip select
+ */
+struct ep93xx_spi_chip_ops {
+ int (*setup)(struct spi_device *spi);
+ void (*cleanup)(struct spi_device *spi);
+ void (*cs_control)(struct spi_device *spi, int value);
+};
+
+#endif /* __ASM_MACH_EP93XX_SPI_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/fb.h b/arch/arm/mach-ep93xx/include/mach/fb.h
new file mode 100644
index 00000000..d5ae11d7
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/fb.h
@@ -0,0 +1,56 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/fb.h
+ */
+
+#ifndef __ASM_ARCH_EP93XXFB_H
+#define __ASM_ARCH_EP93XXFB_H
+
+struct platform_device;
+struct fb_videomode;
+struct fb_info;
+
+#define EP93XXFB_USE_MODEDB 0
+
+/* VideoAttributes flags */
+#define EP93XXFB_STATE_MACHINE_ENABLE (1 << 0)
+#define EP93XXFB_PIXEL_CLOCK_ENABLE (1 << 1)
+#define EP93XXFB_VSYNC_ENABLE (1 << 2)
+#define EP93XXFB_PIXEL_DATA_ENABLE (1 << 3)
+#define EP93XXFB_COMPOSITE_SYNC (1 << 4)
+#define EP93XXFB_SYNC_VERT_HIGH (1 << 5)
+#define EP93XXFB_SYNC_HORIZ_HIGH (1 << 6)
+#define EP93XXFB_SYNC_BLANK_HIGH (1 << 7)
+#define EP93XXFB_PCLK_FALLING (1 << 8)
+#define EP93XXFB_ENABLE_AC (1 << 9)
+#define EP93XXFB_ENABLE_LCD (1 << 10)
+#define EP93XXFB_ENABLE_CCIR (1 << 12)
+#define EP93XXFB_USE_PARALLEL_INTERFACE (1 << 13)
+#define EP93XXFB_ENABLE_INTERRUPT (1 << 14)
+#define EP93XXFB_USB_INTERLACE (1 << 16)
+#define EP93XXFB_USE_EQUALIZATION (1 << 17)
+#define EP93XXFB_USE_DOUBLE_HORZ (1 << 18)
+#define EP93XXFB_USE_DOUBLE_VERT (1 << 19)
+#define EP93XXFB_USE_BLANK_PIXEL (1 << 20)
+#define EP93XXFB_USE_SDCSN0 (0 << 21)
+#define EP93XXFB_USE_SDCSN1 (1 << 21)
+#define EP93XXFB_USE_SDCSN2 (2 << 21)
+#define EP93XXFB_USE_SDCSN3 (3 << 21)
+
+#define EP93XXFB_ENABLE (EP93XXFB_STATE_MACHINE_ENABLE | \
+ EP93XXFB_PIXEL_CLOCK_ENABLE | \
+ EP93XXFB_VSYNC_ENABLE | \
+ EP93XXFB_PIXEL_DATA_ENABLE)
+
+struct ep93xxfb_mach_info {
+ unsigned int num_modes;
+ const struct fb_videomode *modes;
+ const struct fb_videomode *default_mode;
+ int bpp;
+ unsigned int flags;
+
+ int (*setup)(struct platform_device *pdev);
+ void (*teardown)(struct platform_device *pdev);
+ void (*blank)(int blank_mode, struct fb_info *info);
+};
+
+#endif /* __ASM_ARCH_EP93XXFB_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h
new file mode 100644
index 00000000..c57152c2
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/gpio.h
@@ -0,0 +1,120 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/gpio.h
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/* GPIO port A. */
+#define EP93XX_GPIO_LINE_A(x) ((x) + 0)
+#define EP93XX_GPIO_LINE_EGPIO0 EP93XX_GPIO_LINE_A(0)
+#define EP93XX_GPIO_LINE_EGPIO1 EP93XX_GPIO_LINE_A(1)
+#define EP93XX_GPIO_LINE_EGPIO2 EP93XX_GPIO_LINE_A(2)
+#define EP93XX_GPIO_LINE_EGPIO3 EP93XX_GPIO_LINE_A(3)
+#define EP93XX_GPIO_LINE_EGPIO4 EP93XX_GPIO_LINE_A(4)
+#define EP93XX_GPIO_LINE_EGPIO5 EP93XX_GPIO_LINE_A(5)
+#define EP93XX_GPIO_LINE_EGPIO6 EP93XX_GPIO_LINE_A(6)
+#define EP93XX_GPIO_LINE_EGPIO7 EP93XX_GPIO_LINE_A(7)
+
+/* GPIO port B. */
+#define EP93XX_GPIO_LINE_B(x) ((x) + 8)
+#define EP93XX_GPIO_LINE_EGPIO8 EP93XX_GPIO_LINE_B(0)
+#define EP93XX_GPIO_LINE_EGPIO9 EP93XX_GPIO_LINE_B(1)
+#define EP93XX_GPIO_LINE_EGPIO10 EP93XX_GPIO_LINE_B(2)
+#define EP93XX_GPIO_LINE_EGPIO11 EP93XX_GPIO_LINE_B(3)
+#define EP93XX_GPIO_LINE_EGPIO12 EP93XX_GPIO_LINE_B(4)
+#define EP93XX_GPIO_LINE_EGPIO13 EP93XX_GPIO_LINE_B(5)
+#define EP93XX_GPIO_LINE_EGPIO14 EP93XX_GPIO_LINE_B(6)
+#define EP93XX_GPIO_LINE_EGPIO15 EP93XX_GPIO_LINE_B(7)
+
+/* GPIO port C. */
+#define EP93XX_GPIO_LINE_C(x) ((x) + 40)
+#define EP93XX_GPIO_LINE_ROW0 EP93XX_GPIO_LINE_C(0)
+#define EP93XX_GPIO_LINE_ROW1 EP93XX_GPIO_LINE_C(1)
+#define EP93XX_GPIO_LINE_ROW2 EP93XX_GPIO_LINE_C(2)
+#define EP93XX_GPIO_LINE_ROW3 EP93XX_GPIO_LINE_C(3)
+#define EP93XX_GPIO_LINE_ROW4 EP93XX_GPIO_LINE_C(4)
+#define EP93XX_GPIO_LINE_ROW5 EP93XX_GPIO_LINE_C(5)
+#define EP93XX_GPIO_LINE_ROW6 EP93XX_GPIO_LINE_C(6)
+#define EP93XX_GPIO_LINE_ROW7 EP93XX_GPIO_LINE_C(7)
+
+/* GPIO port D. */
+#define EP93XX_GPIO_LINE_D(x) ((x) + 24)
+#define EP93XX_GPIO_LINE_COL0 EP93XX_GPIO_LINE_D(0)
+#define EP93XX_GPIO_LINE_COL1 EP93XX_GPIO_LINE_D(1)
+#define EP93XX_GPIO_LINE_COL2 EP93XX_GPIO_LINE_D(2)
+#define EP93XX_GPIO_LINE_COL3 EP93XX_GPIO_LINE_D(3)
+#define EP93XX_GPIO_LINE_COL4 EP93XX_GPIO_LINE_D(4)
+#define EP93XX_GPIO_LINE_COL5 EP93XX_GPIO_LINE_D(5)
+#define EP93XX_GPIO_LINE_COL6 EP93XX_GPIO_LINE_D(6)
+#define EP93XX_GPIO_LINE_COL7 EP93XX_GPIO_LINE_D(7)
+
+/* GPIO port E. */
+#define EP93XX_GPIO_LINE_E(x) ((x) + 32)
+#define EP93XX_GPIO_LINE_GRLED EP93XX_GPIO_LINE_E(0)
+#define EP93XX_GPIO_LINE_RDLED EP93XX_GPIO_LINE_E(1)
+#define EP93XX_GPIO_LINE_DIORn EP93XX_GPIO_LINE_E(2)
+#define EP93XX_GPIO_LINE_IDECS1n EP93XX_GPIO_LINE_E(3)
+#define EP93XX_GPIO_LINE_IDECS2n EP93XX_GPIO_LINE_E(4)
+#define EP93XX_GPIO_LINE_IDEDA0 EP93XX_GPIO_LINE_E(5)
+#define EP93XX_GPIO_LINE_IDEDA1 EP93XX_GPIO_LINE_E(6)
+#define EP93XX_GPIO_LINE_IDEDA2 EP93XX_GPIO_LINE_E(7)
+
+/* GPIO port F. */
+#define EP93XX_GPIO_LINE_F(x) ((x) + 16)
+#define EP93XX_GPIO_LINE_WP EP93XX_GPIO_LINE_F(0)
+#define EP93XX_GPIO_LINE_MCCD1 EP93XX_GPIO_LINE_F(1)
+#define EP93XX_GPIO_LINE_MCCD2 EP93XX_GPIO_LINE_F(2)
+#define EP93XX_GPIO_LINE_MCBVD1 EP93XX_GPIO_LINE_F(3)
+#define EP93XX_GPIO_LINE_MCBVD2 EP93XX_GPIO_LINE_F(4)
+#define EP93XX_GPIO_LINE_VS1 EP93XX_GPIO_LINE_F(5)
+#define EP93XX_GPIO_LINE_READY EP93XX_GPIO_LINE_F(6)
+#define EP93XX_GPIO_LINE_VS2 EP93XX_GPIO_LINE_F(7)
+
+/* GPIO port G. */
+#define EP93XX_GPIO_LINE_G(x) ((x) + 48)
+#define EP93XX_GPIO_LINE_EECLK EP93XX_GPIO_LINE_G(0)
+#define EP93XX_GPIO_LINE_EEDAT EP93XX_GPIO_LINE_G(1)
+#define EP93XX_GPIO_LINE_SLA0 EP93XX_GPIO_LINE_G(2)
+#define EP93XX_GPIO_LINE_SLA1 EP93XX_GPIO_LINE_G(3)
+#define EP93XX_GPIO_LINE_DD12 EP93XX_GPIO_LINE_G(4)
+#define EP93XX_GPIO_LINE_DD13 EP93XX_GPIO_LINE_G(5)
+#define EP93XX_GPIO_LINE_DD14 EP93XX_GPIO_LINE_G(6)
+#define EP93XX_GPIO_LINE_DD15 EP93XX_GPIO_LINE_G(7)
+
+/* GPIO port H. */
+#define EP93XX_GPIO_LINE_H(x) ((x) + 56)
+#define EP93XX_GPIO_LINE_DD0 EP93XX_GPIO_LINE_H(0)
+#define EP93XX_GPIO_LINE_DD1 EP93XX_GPIO_LINE_H(1)
+#define EP93XX_GPIO_LINE_DD2 EP93XX_GPIO_LINE_H(2)
+#define EP93XX_GPIO_LINE_DD3 EP93XX_GPIO_LINE_H(3)
+#define EP93XX_GPIO_LINE_DD4 EP93XX_GPIO_LINE_H(4)
+#define EP93XX_GPIO_LINE_DD5 EP93XX_GPIO_LINE_H(5)
+#define EP93XX_GPIO_LINE_DD6 EP93XX_GPIO_LINE_H(6)
+#define EP93XX_GPIO_LINE_DD7 EP93XX_GPIO_LINE_H(7)
+
+/* maximum value for gpio line identifiers */
+#define EP93XX_GPIO_LINE_MAX EP93XX_GPIO_LINE_H(7)
+
+/* maximum value for irq capable line identifiers */
+#define EP93XX_GPIO_LINE_MAX_IRQ EP93XX_GPIO_LINE_F(7)
+
+/* new generic GPIO API - see Documentation/gpio.txt */
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+/*
+ * Map GPIO A0..A7 (0..7) to irq 64..71,
+ * B0..B7 (7..15) to irq 72..79, and
+ * F0..F7 (16..24) to irq 80..87.
+ */
+#define gpio_to_irq(gpio) \
+ (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
+
+#define irq_to_gpio(irq) ((irq) - gpio_to_irq(0))
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h
new file mode 100644
index 00000000..5a3ce024
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/hardware.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/hardware.h
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/ep93xx-regs.h>
+#include <mach/platform.h>
+
+#define pcibios_assign_all_busses() 0
+
+/*
+ * The EP93xx has two external crystal oscillators. To generate the
+ * required high-frequency clocks, the processor uses two phase-locked-
+ * loops (PLLs) to multiply the incoming external clock signal to much
+ * higher frequencies that are then divided down by programmable dividers
+ * to produce the needed clocks. The PLLs operate independently of one
+ * another.
+ */
+#define EP93XX_EXT_CLK_RATE 14745600
+#define EP93XX_EXT_RTC_RATE 32768
+
+#define EP93XX_KEYTCHCLK_DIV4 (EP93XX_EXT_CLK_RATE / 4)
+#define EP93XX_KEYTCHCLK_DIV16 (EP93XX_EXT_CLK_RATE / 16)
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h
new file mode 100644
index 00000000..594b77f2
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/io.h
+ */
+
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(p) __typesafe_io(p)
+#define __mem_pci(p) (p)
+
+/*
+ * A typesafe __io() variation for variable initialisers
+ */
+#ifdef __ASSEMBLER__
+#define IOMEM(p) p
+#else
+#define IOMEM(p) ((void __iomem __force *)(p))
+#endif
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-ep93xx/include/mach/irqs.h b/arch/arm/mach-ep93xx/include/mach/irqs.h
new file mode 100644
index 00000000..ff98390b
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/irqs.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/irqs.h
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define IRQ_EP93XX_COMMRX 2
+#define IRQ_EP93XX_COMMTX 3
+#define IRQ_EP93XX_TIMER1 4
+#define IRQ_EP93XX_TIMER2 5
+#define IRQ_EP93XX_AACINTR 6
+#define IRQ_EP93XX_DMAM2P0 7
+#define IRQ_EP93XX_DMAM2P1 8
+#define IRQ_EP93XX_DMAM2P2 9
+#define IRQ_EP93XX_DMAM2P3 10
+#define IRQ_EP93XX_DMAM2P4 11
+#define IRQ_EP93XX_DMAM2P5 12
+#define IRQ_EP93XX_DMAM2P6 13
+#define IRQ_EP93XX_DMAM2P7 14
+#define IRQ_EP93XX_DMAM2P8 15
+#define IRQ_EP93XX_DMAM2P9 16
+#define IRQ_EP93XX_DMAM2M0 17
+#define IRQ_EP93XX_DMAM2M1 18
+#define IRQ_EP93XX_GPIO0MUX 19
+#define IRQ_EP93XX_GPIO1MUX 20
+#define IRQ_EP93XX_GPIO2MUX 21
+#define IRQ_EP93XX_GPIO3MUX 22
+#define IRQ_EP93XX_UART1RX 23
+#define IRQ_EP93XX_UART1TX 24
+#define IRQ_EP93XX_UART2RX 25
+#define IRQ_EP93XX_UART2TX 26
+#define IRQ_EP93XX_UART3RX 27
+#define IRQ_EP93XX_UART3TX 28
+#define IRQ_EP93XX_KEY 29
+#define IRQ_EP93XX_TOUCH 30
+#define EP93XX_VIC1_VALID_IRQ_MASK 0x7ffffffc
+
+#define IRQ_EP93XX_EXT0 32
+#define IRQ_EP93XX_EXT1 33
+#define IRQ_EP93XX_EXT2 34
+#define IRQ_EP93XX_64HZ 35
+#define IRQ_EP93XX_WATCHDOG 36
+#define IRQ_EP93XX_RTC 37
+#define IRQ_EP93XX_IRDA 38
+#define IRQ_EP93XX_ETHERNET 39
+#define IRQ_EP93XX_EXT3 40
+#define IRQ_EP93XX_PROG 41
+#define IRQ_EP93XX_1HZ 42
+#define IRQ_EP93XX_VSYNC 43
+#define IRQ_EP93XX_VIDEO_FIFO 44
+#define IRQ_EP93XX_SSP1RX 45
+#define IRQ_EP93XX_SSP1TX 46
+#define IRQ_EP93XX_GPIO4MUX 47
+#define IRQ_EP93XX_GPIO5MUX 48
+#define IRQ_EP93XX_GPIO6MUX 49
+#define IRQ_EP93XX_GPIO7MUX 50
+#define IRQ_EP93XX_TIMER3 51
+#define IRQ_EP93XX_UART1 52
+#define IRQ_EP93XX_SSP 53
+#define IRQ_EP93XX_UART2 54
+#define IRQ_EP93XX_UART3 55
+#define IRQ_EP93XX_USB 56
+#define IRQ_EP93XX_ETHERNET_PME 57
+#define IRQ_EP93XX_DSP 58
+#define IRQ_EP93XX_GPIO_AB 59
+#define IRQ_EP93XX_SAI 60
+#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff
+
+#define NR_EP93XX_IRQS (64 + 24)
+
+#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x))
+#define EP93XX_BOARD_IRQS 32
+
+#define NR_IRQS (NR_EP93XX_IRQS + EP93XX_BOARD_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h b/arch/arm/mach-ep93xx/include/mach/memory.h
new file mode 100644
index 00000000..c9400cf0
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/memory.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#if defined(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+#elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
+#elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)
+#define PLAT_PHYS_OFFSET UL(0xd0000000)
+#elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)
+#define PLAT_PHYS_OFFSET UL(0xe0000000)
+#elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)
+#define PLAT_PHYS_OFFSET UL(0xf0000000)
+#else
+#error "Kconfig bug: No EP93xx PHYS_OFFSET set"
+#endif
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
new file mode 100644
index 00000000..50660455
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/platform.h
+ */
+
+#ifndef __ASSEMBLY__
+
+struct i2c_gpio_platform_data;
+struct i2c_board_info;
+struct spi_board_info;
+struct platform_device;
+struct ep93xxfb_mach_info;
+struct ep93xx_keypad_platform_data;
+struct ep93xx_spi_info;
+
+struct ep93xx_eth_data
+{
+ unsigned char dev_addr[6];
+ unsigned char phy_id;
+};
+
+void ep93xx_map_io(void);
+void ep93xx_init_irq(void);
+
+/* EP93xx System Controller software locked register write */
+void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg);
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits);
+
+static inline void ep93xx_devcfg_set_bits(unsigned int bits)
+{
+ ep93xx_devcfg_set_clear(bits, 0x00);
+}
+
+static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
+{
+ ep93xx_devcfg_set_clear(0x00, bits);
+}
+
+#define EP93XX_CHIP_REV_D0 3
+#define EP93XX_CHIP_REV_D1 4
+#define EP93XX_CHIP_REV_E0 5
+#define EP93XX_CHIP_REV_E1 6
+#define EP93XX_CHIP_REV_E2 7
+
+unsigned int ep93xx_chip_revision(void);
+
+void ep93xx_register_flash(unsigned int width,
+ resource_size_t start, resource_size_t size);
+
+void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
+void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
+ struct i2c_board_info *devices, int num);
+void ep93xx_register_spi(struct ep93xx_spi_info *info,
+ struct spi_board_info *devices, int num);
+void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
+void ep93xx_register_pwm(int pwm0, int pwm1);
+int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
+void ep93xx_pwm_release_gpio(struct platform_device *pdev);
+void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data);
+int ep93xx_keypad_acquire_gpio(struct platform_device *pdev);
+void ep93xx_keypad_release_gpio(struct platform_device *pdev);
+void ep93xx_register_i2s(void);
+int ep93xx_i2s_acquire(unsigned i2s_pins, unsigned i2s_config);
+void ep93xx_i2s_release(void);
+void ep93xx_register_ac97(void);
+
+void ep93xx_init_devices(void);
+extern struct sys_timer ep93xx_timer;
+
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
new file mode 100644
index 00000000..6d661fe9
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/system.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/system.h
+ */
+
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ local_irq_disable();
+
+ /*
+ * Set then clear the SWRST bit to initiate a software reset
+ */
+ ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST);
+ ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST);
+
+ while (1)
+ ;
+}
diff --git a/arch/arm/mach-ep93xx/include/mach/timex.h b/arch/arm/mach-ep93xx/include/mach/timex.h
new file mode 100644
index 00000000..6b3503b0
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/timex.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/timex.h
+ */
+
+#define CLOCK_TICK_RATE 983040
diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
new file mode 100644
index 00000000..0eabec62
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/ts72xx.h
+ */
+
+/*
+ * TS72xx memory map:
+ *
+ * virt phys size
+ * febff000 22000000 4K model number register
+ * febfe000 22400000 4K options register
+ * febfd000 22800000 4K options register #2
+ * febf9000 10800000 4K TS-5620 RTC index register
+ * febf8000 11700000 4K TS-5620 RTC data register
+ */
+
+#define TS72XX_MODEL_PHYS_BASE 0x22000000
+#define TS72XX_MODEL_VIRT_BASE 0xfebff000
+#define TS72XX_MODEL_SIZE 0x00001000
+
+#define TS72XX_MODEL_TS7200 0x00
+#define TS72XX_MODEL_TS7250 0x01
+#define TS72XX_MODEL_TS7260 0x02
+
+
+#define TS72XX_OPTIONS_PHYS_BASE 0x22400000
+#define TS72XX_OPTIONS_VIRT_BASE 0xfebfe000
+#define TS72XX_OPTIONS_SIZE 0x00001000
+
+#define TS72XX_OPTIONS_COM2_RS485 0x02
+#define TS72XX_OPTIONS_MAX197 0x01
+
+
+#define TS72XX_OPTIONS2_PHYS_BASE 0x22800000
+#define TS72XX_OPTIONS2_VIRT_BASE 0xfebfd000
+#define TS72XX_OPTIONS2_SIZE 0x00001000
+
+#define TS72XX_OPTIONS2_TS9420 0x04
+#define TS72XX_OPTIONS2_TS9420_BOOT 0x02
+
+
+#define TS72XX_RTC_INDEX_VIRT_BASE 0xfebf9000
+#define TS72XX_RTC_INDEX_PHYS_BASE 0x10800000
+#define TS72XX_RTC_INDEX_SIZE 0x00001000
+
+#define TS72XX_RTC_DATA_VIRT_BASE 0xfebf8000
+#define TS72XX_RTC_DATA_PHYS_BASE 0x11700000
+#define TS72XX_RTC_DATA_SIZE 0x00001000
+
+#define TS72XX_WDT_CONTROL_PHYS_BASE 0x23800000
+#define TS72XX_WDT_FEED_PHYS_BASE 0x23c00000
+
+#ifndef __ASSEMBLY__
+
+static inline int board_is_ts7200(void)
+{
+ return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7200;
+}
+
+static inline int board_is_ts7250(void)
+{
+ return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7250;
+}
+
+static inline int board_is_ts7260(void)
+{
+ return __raw_readb(TS72XX_MODEL_VIRT_BASE) == TS72XX_MODEL_TS7260;
+}
+
+static inline int is_max197_installed(void)
+{
+ return !!(__raw_readb(TS72XX_OPTIONS_VIRT_BASE) &
+ TS72XX_OPTIONS_MAX197);
+}
+
+static inline int is_ts9420_installed(void)
+{
+ return !!(__raw_readb(TS72XX_OPTIONS2_VIRT_BASE) &
+ TS72XX_OPTIONS2_TS9420);
+}
+#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/uncompress.h b/arch/arm/mach-ep93xx/include/mach/uncompress.h
new file mode 100644
index 00000000..16026c2b
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/uncompress.h
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <mach/ep93xx-regs.h>
+
+static unsigned char __raw_readb(unsigned int ptr)
+{
+ return *((volatile unsigned char *)ptr);
+}
+
+static unsigned int __raw_readl(unsigned int ptr)
+{
+ return *((volatile unsigned int *)ptr);
+}
+
+static void __raw_writeb(unsigned char value, unsigned int ptr)
+{
+ *((volatile unsigned char *)ptr) = value;
+}
+
+static void __raw_writel(unsigned int value, unsigned int ptr)
+{
+ *((volatile unsigned int *)ptr) = value;
+}
+
+#if defined(CONFIG_EP93XX_EARLY_UART1)
+#define UART_BASE EP93XX_UART1_PHYS_BASE
+#elif defined(CONFIG_EP93XX_EARLY_UART2)
+#define UART_BASE EP93XX_UART2_PHYS_BASE
+#elif defined(CONFIG_EP93XX_EARLY_UART3)
+#define UART_BASE EP93XX_UART3_PHYS_BASE
+#else
+#define UART_BASE EP93XX_UART1_PHYS_BASE
+#endif
+
+#define PHYS_UART_DATA (UART_BASE + 0x00)
+#define PHYS_UART_FLAG (UART_BASE + 0x18)
+#define UART_FLAG_TXFF 0x20
+
+static inline void putc(int c)
+{
+ int i;
+
+ for (i = 0; i < 1000; i++) {
+ /* Transmit fifo not full? */
+ if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF))
+ break;
+ }
+
+ __raw_writeb(c, PHYS_UART_DATA);
+}
+
+static inline void flush(void)
+{
+}
+
+
+/*
+ * Some bootloaders don't turn off DMA from the ethernet MAC before
+ * jumping to linux, which means that we might end up with bits of RX
+ * status and packet data scribbled over the uncompressed kernel image.
+ * Work around this by resetting the ethernet MAC before we uncompress.
+ */
+#define PHYS_ETH_SELF_CTL 0x80010020
+#define ETH_SELF_CTL_RESET 0x00000001
+
+static void ethernet_reset(void)
+{
+ unsigned int v;
+
+ /* Reset the ethernet MAC. */
+ v = __raw_readl(PHYS_ETH_SELF_CTL);
+ __raw_writel(v | ETH_SELF_CTL_RESET, PHYS_ETH_SELF_CTL);
+
+ /* Wait for reset to finish. */
+ while (__raw_readl(PHYS_ETH_SELF_CTL) & ETH_SELF_CTL_RESET)
+ ;
+}
+
+
+static void arch_decomp_setup(void)
+{
+ ethernet_reset();
+}
+
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-ep93xx/include/mach/vmalloc.h b/arch/arm/mach-ep93xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..1b3f25d0
--- /dev/null
+++ b/arch/arm/mach-ep93xx/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-ep93xx/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe800000UL
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
new file mode 100644
index 00000000..7adea625
--- /dev/null
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-ep93xx/micro9.c
+ *
+ * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
+ * Manfred Gruber <m.gruber@tirol.com>
+ * Copyright (C) 2009 Contec Steuerungstechnik & Automation GmbH
+ * Hubert Feurstein <hubert.feurstein@contec.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+
+/*************************************************************************
+ * Micro9 NOR Flash
+ *
+ * Micro9-High has up to 64MB of 32-bit flash on CS1
+ * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
+ * Micro9-Lite uses a separate MTD map driver for flash support
+ * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
+ *************************************************************************/
+static unsigned int __init micro9_detect_bootwidth(void)
+{
+ u32 v;
+
+ /* Detect the bus width of the external flash memory */
+ v = __raw_readl(EP93XX_SYSCON_SYSCFG);
+ if (v & EP93XX_SYSCON_SYSCFG_LCSN7)
+ return 4; /* 32-bit */
+ else
+ return 2; /* 16-bit */
+}
+
+static void __init micro9_register_flash(void)
+{
+ unsigned int width;
+
+ if (machine_is_micro9())
+ width = 4;
+ else if (machine_is_micro9m() || machine_is_micro9s())
+ width = micro9_detect_bootwidth();
+ else
+ width = 0;
+
+ if (width)
+ ep93xx_register_flash(width, EP93XX_CS1_PHYS_BASE, SZ_64M);
+}
+
+
+/*************************************************************************
+ * Micro9 Ethernet
+ *************************************************************************/
+static struct ep93xx_eth_data __initdata micro9_eth_data = {
+ .phy_id = 0x1f,
+};
+
+
+static void __init micro9_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_eth(&micro9_eth_data, 1);
+ micro9_register_flash();
+}
+
+
+#ifdef CONFIG_MACH_MICRO9H
+MACHINE_START(MICRO9, "Contec Micro9-High")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = micro9_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9M
+MACHINE_START(MICRO9M, "Contec Micro9-Mid")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = micro9_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9L
+MACHINE_START(MICRO9L, "Contec Micro9-Lite")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = micro9_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_MICRO9S
+MACHINE_START(MICRO9S, "Contec Micro9-Slim")
+ /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = micro9_init_machine,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
new file mode 100644
index 00000000..d96dc1c5
--- /dev/null
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-ep93xx/simone.c
+ * Simplemachines Sim.One support.
+ *
+ * Copyright (C) 2010 Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * Based on the 2.6.24.7 support:
+ * Copyright (C) 2009 Simplemachines
+ * MMC support by Peter Ivanov <ivanovp@gmail.com>, 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct ep93xx_eth_data __initdata simone_eth_data = {
+ .phy_id = 1,
+};
+
+static struct ep93xxfb_mach_info __initdata simone_fb_info = {
+ .num_modes = EP93XXFB_USE_MODEDB,
+ .bpp = 16,
+ .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
+};
+
+static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
+ .sda_pin = EP93XX_GPIO_LINE_EEDAT,
+ .sda_is_open_drain = 0,
+ .scl_pin = EP93XX_GPIO_LINE_EECLK,
+ .scl_is_open_drain = 0,
+ .udelay = 0,
+ .timeout = 0,
+};
+
+static struct i2c_board_info __initdata simone_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ },
+};
+
+static void __init simone_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_8M);
+ ep93xx_register_eth(&simone_eth_data, 1);
+ ep93xx_register_fb(&simone_fb_info);
+ ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
+ ARRAY_SIZE(simone_i2c_board_info));
+ ep93xx_register_ac97();
+}
+
+MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board")
+/* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+ .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = simone_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c
new file mode 100644
index 00000000..ac601fe2
--- /dev/null
+++ b/arch/arm/mach-ep93xx/snappercl15.c
@@ -0,0 +1,171 @@
+/*
+ * arch/arm/mach-ep93xx/snappercl15.c
+ * Bluewater Systems Snapper CL15 system module
+ *
+ * Copyright (C) 2009 Bluewater Systems Ltd
+ * Author: Ryan Mallon <ryan@bluewatersys.com>
+ *
+ * NAND code adapted from driver by:
+ * Andre Renaud <andre@bluewatersys.com>
+ * James R. McKaskill
+ *
+ * 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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/fb.h>
+
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define SNAPPERCL15_NAND_BASE (EP93XX_CS7_PHYS_BASE + SZ_16M)
+
+#define SNAPPERCL15_NAND_WPN (1 << 8) /* Write protect (active low) */
+#define SNAPPERCL15_NAND_ALE (1 << 9) /* Address latch */
+#define SNAPPERCL15_NAND_CLE (1 << 10) /* Command latch */
+#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
+#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
+
+#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
+
+static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ static u16 nand_state = SNAPPERCL15_NAND_WPN;
+ u16 set;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ set = SNAPPERCL15_NAND_CEN | SNAPPERCL15_NAND_WPN;
+
+ if (ctrl & NAND_NCE)
+ set &= ~SNAPPERCL15_NAND_CEN;
+ if (ctrl & NAND_CLE)
+ set |= SNAPPERCL15_NAND_CLE;
+ if (ctrl & NAND_ALE)
+ set |= SNAPPERCL15_NAND_ALE;
+
+ nand_state &= ~(SNAPPERCL15_NAND_CEN |
+ SNAPPERCL15_NAND_CLE |
+ SNAPPERCL15_NAND_ALE);
+ nand_state |= set;
+ __raw_writew(nand_state, NAND_CTRL_ADDR(chip));
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ __raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
+}
+
+static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
+}
+
+static const char *snappercl15_nand_part_probes[] = {"cmdlinepart", NULL};
+
+static struct mtd_partition snappercl15_nand_parts[] = {
+ {
+ .name = "Kernel",
+ .offset = 0,
+ .size = SZ_2M,
+ },
+ {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct platform_nand_data snappercl15_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .part_probe_types = snappercl15_nand_part_probes,
+ .partitions = snappercl15_nand_parts,
+ .nr_partitions = ARRAY_SIZE(snappercl15_nand_parts),
+ .options = NAND_NO_AUTOINCR,
+ .chip_delay = 25,
+ },
+ .ctrl = {
+ .dev_ready = snappercl15_nand_dev_ready,
+ .cmd_ctrl = snappercl15_nand_cmd_ctrl,
+ },
+};
+
+static struct resource snappercl15_nand_resource[] = {
+ {
+ .start = SNAPPERCL15_NAND_BASE,
+ .end = SNAPPERCL15_NAND_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device snappercl15_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev.platform_data = &snappercl15_nand_data,
+ .resource = snappercl15_nand_resource,
+ .num_resources = ARRAY_SIZE(snappercl15_nand_resource),
+};
+
+static struct ep93xx_eth_data __initdata snappercl15_eth_data = {
+ .phy_id = 1,
+};
+
+static struct i2c_gpio_platform_data __initdata snappercl15_i2c_gpio_data = {
+ .sda_pin = EP93XX_GPIO_LINE_EEDAT,
+ .sda_is_open_drain = 0,
+ .scl_pin = EP93XX_GPIO_LINE_EECLK,
+ .scl_is_open_drain = 0,
+ .udelay = 0,
+ .timeout = 0,
+};
+
+static struct i2c_board_info __initdata snappercl15_i2c_data[] = {
+ {
+ /* Audio codec */
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = {
+ .num_modes = EP93XXFB_USE_MODEDB,
+ .bpp = 16,
+};
+
+static void __init snappercl15_init_machine(void)
+{
+ ep93xx_init_devices();
+ ep93xx_register_eth(&snappercl15_eth_data, 1);
+ ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data,
+ ARRAY_SIZE(snappercl15_i2c_data));
+ ep93xx_register_fb(&snappercl15_fb_info);
+ ep93xx_register_i2s();
+ platform_device_register(&snappercl15_nand_device);
+}
+
+MACHINE_START(SNAPPER_CL15, "Bluewater Systems Snapper CL15")
+ /* Maintainer: Ryan Mallon <ryan@bluewatersys.com> */
+ .boot_params = EP93XX_SDCE0_PHYS_BASE + 0x100,
+ .map_io = ep93xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = snappercl15_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
new file mode 100644
index 00000000..c2d2cf40
--- /dev/null
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -0,0 +1,265 @@
+/*
+ * arch/arm/mach-ep93xx/ts72xx.c
+ * Technologic Systems TS72xx SBC support.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/m48t86.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/hardware.h>
+#include <mach/ts72xx.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+
+
+static struct map_desc ts72xx_io_desc[] __initdata = {
+ {
+ .virtual = TS72XX_MODEL_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE),
+ .length = TS72XX_MODEL_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = TS72XX_OPTIONS_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE),
+ .length = TS72XX_OPTIONS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = TS72XX_OPTIONS2_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE),
+ .length = TS72XX_OPTIONS2_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = TS72XX_RTC_INDEX_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE),
+ .length = TS72XX_RTC_INDEX_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = TS72XX_RTC_DATA_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE),
+ .length = TS72XX_RTC_DATA_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+static void __init ts72xx_map_io(void)
+{
+ ep93xx_map_io();
+ iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc));
+}
+
+
+/*************************************************************************
+ * NAND flash
+ *************************************************************************/
+#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
+#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
+
+static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
+ int cmd, unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ void __iomem *addr = chip->IO_ADDR_R;
+ unsigned char bits;
+
+ addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
+
+ bits = __raw_readb(addr) & ~0x07;
+ bits |= (ctrl & NAND_NCE) << 2; /* bit 0 -> bit 2 */
+ bits |= (ctrl & NAND_CLE); /* bit 1 -> bit 1 */
+ bits |= (ctrl & NAND_ALE) >> 2; /* bit 2 -> bit 0 */
+
+ __raw_writeb(bits, addr);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ __raw_writeb(cmd, chip->IO_ADDR_W);
+}
+
+static int ts72xx_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ void __iomem *addr = chip->IO_ADDR_R;
+
+ addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
+
+ return !!(__raw_readb(addr) & 0x20);
+}
+
+static const char *ts72xx_nand_part_probes[] = { "cmdlinepart", NULL };
+
+#define TS72XX_BOOTROM_PART_SIZE (SZ_16K)
+#define TS72XX_REDBOOT_PART_SIZE (SZ_2M + SZ_1M)
+
+static struct mtd_partition ts72xx_nand_parts[] = {
+ {
+ .name = "TS-BOOTROM",
+ .offset = 0,
+ .size = TS72XX_BOOTROM_PART_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "Linux",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0, /* filled in later */
+ }, {
+ .name = "RedBoot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+};
+
+static void ts72xx_nand_set_parts(uint64_t size,
+ struct platform_nand_chip *chip)
+{
+ /* Factory TS-72xx boards only come with 32MiB or 128MiB NAND options */
+ if (size == SZ_32M || size == SZ_128M) {
+ /* Set the "Linux" partition size */
+ ts72xx_nand_parts[1].size = size - TS72XX_REDBOOT_PART_SIZE;
+
+ chip->partitions = ts72xx_nand_parts;
+ chip->nr_partitions = ARRAY_SIZE(ts72xx_nand_parts);
+ } else {
+ pr_warning("Unknown nand disk size:%lluMiB\n", size >> 20);
+ }
+}
+
+static struct platform_nand_data ts72xx_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .chip_delay = 15,
+ .part_probe_types = ts72xx_nand_part_probes,
+ .set_parts = ts72xx_nand_set_parts,
+ },
+ .ctrl = {
+ .cmd_ctrl = ts72xx_nand_hwcontrol,
+ .dev_ready = ts72xx_nand_device_ready,
+ },
+};
+
+static struct resource ts72xx_nand_resource[] = {
+ {
+ .start = 0, /* filled in later */
+ .end = 0, /* filled in later */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ts72xx_nand_flash = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev.platform_data = &ts72xx_nand_data,
+ .resource = ts72xx_nand_resource,
+ .num_resources = ARRAY_SIZE(ts72xx_nand_resource),
+};
+
+
+static void __init ts72xx_register_flash(void)
+{
+ /*
+ * TS7200 has NOR flash all other TS72xx board have NAND flash.
+ */
+ if (board_is_ts7200()) {
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
+ } else {
+ resource_size_t start;
+
+ if (is_ts9420_installed())
+ start = EP93XX_CS7_PHYS_BASE;
+ else
+ start = EP93XX_CS6_PHYS_BASE;
+
+ ts72xx_nand_resource[0].start = start;
+ ts72xx_nand_resource[0].end = start + SZ_16M - 1;
+
+ platform_device_register(&ts72xx_nand_flash);
+ }
+}
+
+
+static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
+{
+ __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
+ return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE);
+}
+
+static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr)
+{
+ __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
+ __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE);
+}
+
+static struct m48t86_ops ts72xx_rtc_ops = {
+ .readbyte = ts72xx_rtc_readbyte,
+ .writebyte = ts72xx_rtc_writebyte,
+};
+
+static struct platform_device ts72xx_rtc_device = {
+ .name = "rtc-m48t86",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts72xx_rtc_ops,
+ },
+ .num_resources = 0,
+};
+
+static struct resource ts72xx_wdt_resources[] = {
+ {
+ .start = TS72XX_WDT_CONTROL_PHYS_BASE,
+ .end = TS72XX_WDT_CONTROL_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = TS72XX_WDT_FEED_PHYS_BASE,
+ .end = TS72XX_WDT_FEED_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ts72xx_wdt_device = {
+ .name = "ts72xx-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ts72xx_wdt_resources),
+ .resource = ts72xx_wdt_resources,
+};
+
+static struct ep93xx_eth_data __initdata ts72xx_eth_data = {
+ .phy_id = 1,
+};
+
+static void __init ts72xx_init_machine(void)
+{
+ ep93xx_init_devices();
+ ts72xx_register_flash();
+ platform_device_register(&ts72xx_rtc_device);
+ platform_device_register(&ts72xx_wdt_device);
+
+ ep93xx_register_eth(&ts72xx_eth_data, 1);
+}
+
+MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
+ .map_io = ts72xx_map_io,
+ .init_irq = ep93xx_init_irq,
+ .timer = &ep93xx_timer,
+ .init_machine = ts72xx_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
new file mode 100644
index 00000000..1435fc31
--- /dev/null
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -0,0 +1,209 @@
+# 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
new file mode 100644
index 00000000..60fe5ecf
--- /dev/null
+++ b/arch/arm/mach-exynos4/Makefile
@@ -0,0 +1,59 @@
+# 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/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot
new file mode 100644
index 00000000..d65956ff
--- /dev/null
+++ b/arch/arm/mach-exynos4/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
new file mode 100644
index 00000000..871f9d50
--- /dev/null
+++ b/arch/arm/mach-exynos4/clock.c
@@ -0,0 +1,1216 @@
+/* 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
new file mode 100644
index 00000000..bfd62146
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -0,0 +1,226 @@
+/* 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
new file mode 100644
index 00000000..a1bd258f
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpufreq.c
@@ -0,0 +1,569 @@
+/* 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
new file mode 100644
index 00000000..bf7e96f2
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -0,0 +1,86 @@
+/* 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-ahci.c b/arch/arm/mach-exynos4/dev-ahci.c
new file mode 100644
index 00000000..f57a3de8
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-ahci.c
@@ -0,0 +1,263 @@
+/* linux/arch/arm/mach-exynos4/dev-ahci.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - AHCI 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>
+
+/* PHY Control Register */
+#define SATA_CTRL0 0x0
+/* PHY Link Control Register */
+#define SATA_CTRL1 0x4
+/* PHY Status Register */
+#define SATA_PHY_STATUS 0x8
+
+#define SATA_CTRL0_RX_DATA_VALID(x) (x << 27)
+#define SATA_CTRL0_SPEED_MODE (1 << 26)
+#define SATA_CTRL0_M_PHY_CAL (1 << 19)
+#define SATA_CTRL0_PHY_CMU_RST_N (1 << 10)
+#define SATA_CTRL0_M_PHY_LN_RST_N (1 << 9)
+#define SATA_CTRL0_PHY_POR_N (1 << 8)
+
+#define SATA_CTRL1_RST_PMALIVE_N (1 << 8)
+#define SATA_CTRL1_RST_RXOOB_N (1 << 7)
+#define SATA_CTRL1_RST_RX_N (1 << 6)
+#define SATA_CTRL1_RST_TX_N (1 << 5)
+
+#define SATA_PHY_STATUS_CMU_OK (1 << 18)
+#define SATA_PHY_STATUS_LANE_OK (1 << 16)
+
+#define LANE0 0x200
+#define COM_LANE 0xA00
+
+#define HOST_PORTS_IMPL 0xC
+#define SCLK_SATA_FREQ (67 * MHZ)
+
+static void __iomem *phy_base, *phy_ctrl;
+
+struct phy_reg {
+ u8 reg;
+ u8 val;
+};
+
+/* SATA PHY setup */
+static const struct phy_reg exynos4_sataphy_cmu[] = {
+ { 0x00, 0x06 }, { 0x02, 0x80 }, { 0x22, 0xa0 }, { 0x23, 0x42 },
+ { 0x2e, 0x04 }, { 0x2f, 0x50 }, { 0x30, 0x70 }, { 0x31, 0x02 },
+ { 0x32, 0x25 }, { 0x33, 0x40 }, { 0x34, 0x01 }, { 0x35, 0x40 },
+ { 0x61, 0x2e }, { 0x63, 0x5e }, { 0x65, 0x42 }, { 0x66, 0xd1 },
+ { 0x67, 0x20 }, { 0x68, 0x28 }, { 0x69, 0x78 }, { 0x6a, 0x04 },
+ { 0x6b, 0xc8 }, { 0x6c, 0x06 },
+};
+
+static const struct phy_reg exynos4_sataphy_lane[] = {
+ { 0x00, 0x02 }, { 0x05, 0x10 }, { 0x06, 0x84 }, { 0x07, 0x04 },
+ { 0x08, 0xe0 }, { 0x10, 0x23 }, { 0x13, 0x05 }, { 0x14, 0x30 },
+ { 0x15, 0x00 }, { 0x17, 0x70 }, { 0x18, 0xf2 }, { 0x19, 0x1e },
+ { 0x1a, 0x18 }, { 0x1b, 0x0d }, { 0x1c, 0x08 }, { 0x50, 0x60 },
+ { 0x51, 0x0f },
+};
+
+static const struct phy_reg exynos4_sataphy_comlane[] = {
+ { 0x01, 0x20 }, { 0x03, 0x40 }, { 0x04, 0x3c }, { 0x05, 0x7d },
+ { 0x06, 0x1d }, { 0x07, 0xcf }, { 0x08, 0x05 }, { 0x09, 0x63 },
+ { 0x0a, 0x29 }, { 0x0b, 0xc4 }, { 0x0c, 0x01 }, { 0x0d, 0x03 },
+ { 0x0e, 0x28 }, { 0x0f, 0x98 }, { 0x10, 0x19 }, { 0x13, 0x80 },
+ { 0x14, 0xf0 }, { 0x15, 0xd0 }, { 0x39, 0xa0 }, { 0x3a, 0xa0 },
+ { 0x3b, 0xa0 }, { 0x3c, 0xa0 }, { 0x3d, 0xa0 }, { 0x3e, 0xa0 },
+ { 0x3f, 0xa0 }, { 0x40, 0x42 }, { 0x42, 0x80 }, { 0x43, 0x58 },
+ { 0x45, 0x44 }, { 0x46, 0x5c }, { 0x47, 0x86 }, { 0x48, 0x8d },
+ { 0x49, 0xd0 }, { 0x4a, 0x09 }, { 0x4b, 0x90 }, { 0x4c, 0x07 },
+ { 0x4d, 0x40 }, { 0x51, 0x20 }, { 0x52, 0x32 }, { 0x7f, 0xd8 },
+ { 0x80, 0x1a }, { 0x81, 0xff }, { 0x82, 0x11 }, { 0x83, 0x00 },
+ { 0x87, 0xf0 }, { 0x87, 0xff }, { 0x87, 0xff }, { 0x87, 0xff },
+ { 0x87, 0xff }, { 0x8c, 0x1c }, { 0x8d, 0xc2 }, { 0x8e, 0xc3 },
+ { 0x8f, 0x3f }, { 0x90, 0x0a }, { 0x96, 0xf8 },
+};
+
+static int wait_for_phy_ready(void __iomem *reg, unsigned long bit)
+{
+ unsigned long timeout;
+
+ /* wait for maximum of 3 sec */
+ timeout = jiffies + msecs_to_jiffies(3000);
+ while (!(__raw_readl(reg) & bit)) {
+ if (time_after(jiffies, timeout))
+ return -1;
+ cpu_relax();
+ }
+ return 0;
+}
+
+static int ahci_phy_init(void __iomem *mmio)
+{
+ int i, ctrl0;
+
+ for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_cmu); i++)
+ __raw_writeb(exynos4_sataphy_cmu[i].val,
+ phy_base + (exynos4_sataphy_cmu[i].reg * 4));
+
+ for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_lane); i++)
+ __raw_writeb(exynos4_sataphy_lane[i].val,
+ phy_base + (LANE0 + exynos4_sataphy_lane[i].reg) * 4);
+
+ for (i = 0; i < ARRAY_SIZE(exynos4_sataphy_comlane); i++)
+ __raw_writeb(exynos4_sataphy_comlane[i].val,
+ phy_base + (COM_LANE + exynos4_sataphy_comlane[i].reg) * 4);
+
+ __raw_writeb(0x07, phy_base);
+
+ ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+ ctrl0 |= SATA_CTRL0_PHY_CMU_RST_N;
+ __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+ if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
+ SATA_PHY_STATUS_CMU_OK) < 0) {
+ printk(KERN_ERR "PHY CMU not ready\n");
+ return -EBUSY;
+ }
+
+ __raw_writeb(0x03, phy_base + (COM_LANE * 4));
+
+ ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+ ctrl0 |= SATA_CTRL0_M_PHY_LN_RST_N;
+ __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+ if (wait_for_phy_ready(phy_ctrl + SATA_PHY_STATUS,
+ SATA_PHY_STATUS_LANE_OK) < 0) {
+ printk(KERN_ERR "PHY LANE not ready\n");
+ return -EBUSY;
+ }
+
+ ctrl0 = __raw_readl(phy_ctrl + SATA_CTRL0);
+ ctrl0 |= SATA_CTRL0_M_PHY_CAL;
+ __raw_writel(ctrl0, phy_ctrl + SATA_CTRL0);
+
+ return 0;
+}
+
+static int exynos4_ahci_init(struct device *dev, void __iomem *mmio)
+{
+ struct clk *clk_sata, *clk_sataphy, *clk_sclk_sata;
+ int val, ret;
+
+ phy_base = ioremap(EXYNOS4_PA_SATAPHY, SZ_64K);
+ if (!phy_base) {
+ dev_err(dev, "failed to allocate memory for SATA PHY\n");
+ return -ENOMEM;
+ }
+
+ phy_ctrl = ioremap(EXYNOS4_PA_SATAPHY_CTRL, SZ_16);
+ if (!phy_ctrl) {
+ dev_err(dev, "failed to allocate memory for SATA PHY CTRL\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ 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, "sataphy");
+ 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_sclk_sata = clk_get(dev, "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 err4;
+ }
+ clk_enable(clk_sclk_sata);
+ clk_set_rate(clk_sclk_sata, SCLK_SATA_FREQ);
+
+ __raw_writel(S5P_PMU_SATA_PHY_CONTROL_EN, S5P_PMU_SATA_PHY_CONTROL);
+
+ /* Enable PHY link control */
+ val = SATA_CTRL1_RST_PMALIVE_N | SATA_CTRL1_RST_RXOOB_N |
+ SATA_CTRL1_RST_RX_N | SATA_CTRL1_RST_TX_N;
+ __raw_writel(val, phy_ctrl + SATA_CTRL1);
+
+ /* Set communication speed as 3Gbps and enable PHY power */
+ val = SATA_CTRL0_RX_DATA_VALID(3) | SATA_CTRL0_SPEED_MODE |
+ SATA_CTRL0_PHY_POR_N;
+ __raw_writel(val, phy_ctrl + SATA_CTRL0);
+
+ /* Port0 is available */
+ __raw_writel(0x1, mmio + HOST_PORTS_IMPL);
+
+ return ahci_phy_init(mmio);
+
+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_base);
+
+ return ret;
+}
+
+static struct ahci_platform_data exynos4_ahci_pdata = {
+ .init = exynos4_ahci_init,
+};
+
+static struct resource exynos4_ahci_resource[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SATA,
+ .end = EXYNOS4_PA_SATA + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SATA,
+ .end = IRQ_SATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 exynos4_ahci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device exynos4_device_ahci = {
+ .name = "ahci",
+ .id = -1,
+ .resource = exynos4_ahci_resource,
+ .num_resources = ARRAY_SIZE(exynos4_ahci_resource),
+ .dev = {
+ .platform_data = &exynos4_ahci_pdata,
+ .dma_mask = &exynos4_ahci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c
new file mode 100644
index 00000000..983069a5
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-audio.c
@@ -0,0 +1,367 @@
+/* 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
new file mode 100644
index 00000000..3273f25d
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-pd.c
@@ -0,0 +1,139 @@
+/* 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
new file mode 100644
index 00000000..3b7cae0f
--- /dev/null
+++ b/arch/arm/mach-exynos4/dev-sysmmu.c
@@ -0,0 +1,232 @@
+/* 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
new file mode 100644
index 00000000..564bb530
--- /dev/null
+++ b/arch/arm/mach-exynos4/dma.c
@@ -0,0 +1,172 @@
+/* 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/headsmp.S b/arch/arm/mach-exynos4/headsmp.S
new file mode 100644
index 00000000..3cdeb364
--- /dev/null
+++ b/arch/arm/mach-exynos4/headsmp.S
@@ -0,0 +1,41 @@
+/*
+ * linux/arch/arm/mach-exynos4/headsmp.S
+ *
+ * Cloned from linux/arch/arm/mach-realview/headsmp.S
+ *
+ * Copyright (c) 2003 ARM Limited
+ * 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/linkage.h>
+#include <linux/init.h>
+
+ __CPUINIT
+
+/*
+ * exynos4 specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(exynos4_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-exynos4/hotplug.c b/arch/arm/mach-exynos4/hotplug.c
new file mode 100644
index 00000000..2b5909e2
--- /dev/null
+++ b/arch/arm/mach-exynos4/hotplug.c
@@ -0,0 +1,130 @@
+/* linux arch/arm/mach-exynos4/hotplug.c
+ *
+ * Cloned from linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, %3\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+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 (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos4/include/mach/debug-macro.S
new file mode 100644
index 00000000..a442ef86
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/debug-macro.S
@@ -0,0 +1,35 @@
+/* linux/arch/arm/mach-exynos4/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x10000 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-exynos4/include/mach/dma.h b/arch/arm/mach-exynos4/include/mach/dma.h
new file mode 100644
index 00000000..81209eb1
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/dma.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos4/include/mach/entry-macro.S b/arch/arm/mach-exynos4/include/mach/entry-macro.S
new file mode 100644
index 00000000..d8f38c2e
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/entry-macro.S
@@ -0,0 +1,84 @@
+/* arch/arm/mach-exynos4/include/mach/entry-macro.S
+ *
+ * Cloned from arch/arm/mach-realview/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for EXYNOS4 platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =gic_cpu_base_addr
+ ldr \base, [\base]
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt if it's
+ * between 30 and 1020. The test_for_ipi routine below will pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the highest
+ * priority enabled interrupt. We then just need to check whether it is in the
+ * valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 = src CPU, 9-0 = int # */
+
+ ldr \tmp, =1021
+
+ bic \irqnr, \irqstat, #0x1c00
+
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+ addne \irqnr, \irqnr, #32
+
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/mach-exynos4/include/mach/gpio.h b/arch/arm/mach-exynos4/include/mach/gpio.h
new file mode 100644
index 00000000..be9266b1
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/gpio.h
@@ -0,0 +1,156 @@
+/* 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/hardware.h b/arch/arm/mach-exynos4/include/mach/hardware.h
new file mode 100644
index 00000000..5109eb23
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-exynos4/include/mach/hardware.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-exynos4/include/mach/io.h b/arch/arm/mach-exynos4/include/mach/io.h
new file mode 100644
index 00000000..d5478d24
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/io.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-exynos4/include/mach/io.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Default IO routines 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_IO_H
+#define __ASM_ARM_ARCH_IO_H __FILE__
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
new file mode 100644
index 00000000..5d037301
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -0,0 +1,160 @@
+/* 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
new file mode 100644
index 00000000..0009e77a
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -0,0 +1,166 @@
+/* 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/memory.h b/arch/arm/mach-exynos4/include/mach/memory.h
new file mode 100644
index 00000000..374ef2cf
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/memory.h
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/memory.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H __FILE__
+
+#define PLAT_PHYS_OFFSET UL(0x40000000)
+
+/* Maximum of 256MiB in one bank */
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 28
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-exynos4/include/mach/pm-core.h b/arch/arm/mach-exynos4/include/mach/pm-core.h
new file mode 100644
index 00000000..f26e46bc
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/pm-core.h
@@ -0,0 +1,49 @@
+/* linux/arch/arm/mach-exynos4/include/mach/pm-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * EXYNOS4210 - PM core support for arch/arm/plat-s5p/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+#include <mach/regs-pmu.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ /* nothing here yet */
+}
+
+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);
+ __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ /* nothing here yet */
+}
diff --git a/arch/arm/mach-exynos4/include/mach/pwm-clock.h b/arch/arm/mach-exynos4/include/mach/pwm-clock.h
new file mode 100644
index 00000000..8e120902
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/pwm-clock.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-exynos4/include/mach/pwm-clock.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
+ *
+ * EXYNOS4 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
new file mode 100644
index 00000000..6e311c11
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -0,0 +1,180 @@
+/* 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
new file mode 100644
index 00000000..1401b216
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-gpio.h
@@ -0,0 +1,42 @@
+/* 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-irq.h b/arch/arm/mach-exynos4/include/mach/regs-irq.h
new file mode 100644
index 00000000..9c7b4bfd
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/gic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos4/include/mach/regs-mct.h
new file mode 100644
index 00000000..ca9c8434
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-mct.h
@@ -0,0 +1,52 @@
+/* arch/arm/mach-exynos4/include/mach/regs-mct.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 MCT configutation
+ *
+ * This program is free software; you can 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_MCT_H
+#define __ASM_ARCH_REGS_MCT_H __FILE__
+
+#include <mach/map.h>
+
+#define EXYNOS4_MCTREG(x) (S5P_VA_SYSTIMER + (x))
+
+#define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100)
+#define EXYNOS4_MCT_G_CNT_U EXYNOS4_MCTREG(0x104)
+#define EXYNOS4_MCT_G_CNT_WSTAT EXYNOS4_MCTREG(0x110)
+
+#define EXYNOS4_MCT_G_COMP0_L EXYNOS4_MCTREG(0x200)
+#define EXYNOS4_MCT_G_COMP0_U EXYNOS4_MCTREG(0x204)
+#define EXYNOS4_MCT_G_COMP0_ADD_INCR EXYNOS4_MCTREG(0x208)
+
+#define EXYNOS4_MCT_G_TCON EXYNOS4_MCTREG(0x240)
+
+#define EXYNOS4_MCT_G_INT_CSTAT EXYNOS4_MCTREG(0x244)
+#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 MCT_L_TCNTB_OFFSET (0x00)
+#define MCT_L_ICNTB_OFFSET (0x08)
+#define MCT_L_TCON_OFFSET (0x20)
+#define MCT_L_INT_CSTAT_OFFSET (0x30)
+#define MCT_L_INT_ENB_OFFSET (0x34)
+#define MCT_L_WSTAT_OFFSET (0x40)
+
+#define MCT_G_TCON_START (1 << 8)
+#define MCT_G_TCON_COMP0_AUTO_INC (1 << 1)
+#define MCT_G_TCON_COMP0_ENABLE (1 << 0)
+
+#define MCT_L_TCON_INTERVAL_MODE (1 << 2)
+#define MCT_L_TCON_INT_START (1 << 1)
+#define MCT_L_TCON_TIMER_START (1 << 0)
+
+#endif /* __ASM_ARCH_REGS_MCT_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mem.h b/arch/arm/mach-exynos4/include/mach/regs-mem.h
new file mode 100644
index 00000000..0368b5a2
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-mem.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - SROMC and DMC 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_MEM_H
+#define __ASM_ARCH_REGS_MEM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_DMC0_MEMCON_OFFSET 0x04
+
+#define S5P_DMC0_MEMTYPE_SHIFT 8
+#define S5P_DMC0_MEMTYPE_MASK 0xF
+
+#endif /* __ASM_ARCH_REGS_MEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
new file mode 100644
index 00000000..a9643371
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
@@ -0,0 +1,165 @@
+/* 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-sysmmu.h b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
new file mode 100644
index 00000000..68ff6ad0
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-sysmmu.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - System MMU register
+ *
+ * This program is free software; you can 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_SYSMMU_H
+#define __ASM_ARCH_REGS_SYSMMU_H __FILE__
+
+#define S5P_MMU_CTRL 0x000
+#define S5P_MMU_CFG 0x004
+#define S5P_MMU_STATUS 0x008
+#define S5P_MMU_FLUSH 0x00C
+#define S5P_PT_BASE_ADDR 0x014
+#define S5P_INT_STATUS 0x018
+#define S5P_INT_CLEAR 0x01C
+#define S5P_PAGE_FAULT_ADDR 0x024
+#define S5P_AW_FAULT_ADDR 0x028
+#define S5P_AR_FAULT_ADDR 0x02C
+#define S5P_DEFAULT_SLAVE_ADDR 0x030
+
+#endif /* __ASM_ARCH_REGS_SYSMMU_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
new file mode 100644
index 00000000..c337cf3a
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
@@ -0,0 +1,64 @@
+/*
+ * 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
new file mode 100644
index 00000000..6a5fbb53
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/sysmmu.h
@@ -0,0 +1,46 @@
+/* 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/include/mach/system.h b/arch/arm/mach-exynos4/include/mach/system.h
new file mode 100644
index 00000000..5e3220c1
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/system.h
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/system.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/system-reset.h>
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-exynos4/include/mach/timex.h b/arch/arm/mach-exynos4/include/mach/timex.h
new file mode 100644
index 00000000..6d138750
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/timex.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-exynos4/include/mach/timex.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * EXYNOS4 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H __FILE__
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-exynos4/include/mach/uncompress.h b/arch/arm/mach-exynos4/include/mach/uncompress.h
new file mode 100644
index 00000000..21d97bcd
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/uncompress.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-exynos4/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H __FILE__
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+
+ /*
+ * For preventing FIFO overrun or infinite loop of UART console,
+ * fifo_max should be the minimum fifo size of all of the UART channels
+ */
+ fifo_mask = S5PV210_UFSTAT_TXMASK;
+ fifo_max = 15 << S5PV210_UFSTAT_TXSHIFT;
+}
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-exynos4/include/mach/vmalloc.h b/arch/arm/mach-exynos4/include/mach/vmalloc.h
new file mode 100644
index 00000000..284330e5
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-exynos4/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Based on arch/arm/mach-s5p6440/include/mach/vmalloc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * EXYNOS4 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H __FILE__
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-exynos4/init.c b/arch/arm/mach-exynos4/init.c
new file mode 100644
index 00000000..a8a83e38
--- /dev/null
+++ b/arch/arm/mach-exynos4/init.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-exynos4/init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
+ [0] = {
+ .name = "uclk1",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->has_fracval = 1;
+ tcfg->clocks = exynos4_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
+ }
+ tcfg->flags |= NO_NEED_CHECK_CLKSRC;
+ }
+
+ s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c
new file mode 100644
index 00000000..5a2758ab
--- /dev/null
+++ b/arch/arm/mach-exynos4/irq-combiner.c
@@ -0,0 +1,124 @@
+/* linux/arch/arm/mach-exynos4/irq-combiner.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/common/gic.c
+ *
+ * IRQ COMBINER 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 <asm/mach/irq.h>
+
+#define COMBINER_ENABLE_SET 0x0
+#define COMBINER_ENABLE_CLEAR 0x4
+#define COMBINER_INT_STATUS 0xC
+
+static DEFINE_SPINLOCK(irq_controller_lock);
+
+struct combiner_chip_data {
+ unsigned int irq_offset;
+ unsigned int irq_mask;
+ void __iomem *base;
+};
+
+static struct combiner_chip_data combiner_data[MAX_COMBINER_NR];
+
+static inline void __iomem *combiner_base(struct irq_data *data)
+{
+ struct combiner_chip_data *combiner_data =
+ irq_data_get_irq_chip_data(data);
+
+ return combiner_data->base;
+}
+
+static void combiner_mask_irq(struct irq_data *data)
+{
+ u32 mask = 1 << (data->irq % 32);
+
+ __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_CLEAR);
+}
+
+static void combiner_unmask_irq(struct irq_data *data)
+{
+ u32 mask = 1 << (data->irq % 32);
+
+ __raw_writel(mask, combiner_base(data) + COMBINER_ENABLE_SET);
+}
+
+static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct combiner_chip_data *chip_data = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
+ unsigned int cascade_irq, combiner_irq;
+ unsigned long status;
+
+ chained_irq_enter(chip, desc);
+
+ spin_lock(&irq_controller_lock);
+ status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
+ spin_unlock(&irq_controller_lock);
+ status &= chip_data->irq_mask;
+
+ if (status == 0)
+ goto out;
+
+ combiner_irq = __ffs(status);
+
+ cascade_irq = combiner_irq + (chip_data->irq_offset & ~31);
+ if (unlikely(cascade_irq >= NR_IRQS))
+ do_bad_IRQ(cascade_irq, desc);
+ else
+ generic_handle_irq(cascade_irq);
+
+ out:
+ chained_irq_exit(chip, desc);
+}
+
+static struct irq_chip combiner_chip = {
+ .name = "COMBINER",
+ .irq_mask = combiner_mask_irq,
+ .irq_unmask = combiner_unmask_irq,
+};
+
+void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
+{
+ if (combiner_nr >= MAX_COMBINER_NR)
+ BUG();
+ if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
+ BUG();
+ irq_set_chained_handler(irq, combiner_handle_cascade_irq);
+}
+
+void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
+ unsigned int irq_start)
+{
+ unsigned int i;
+
+ if (combiner_nr >= MAX_COMBINER_NR)
+ BUG();
+
+ combiner_data[combiner_nr].base = base;
+ combiner_data[combiner_nr].irq_offset = irq_start;
+ combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3);
+
+ /* Disable all interrupts */
+
+ __raw_writel(combiner_data[combiner_nr].irq_mask,
+ base + COMBINER_ENABLE_CLEAR);
+
+ /* Setup the Linux IRQ subsystem */
+
+ for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
+ + MAX_IRQ_IN_COMBINER; i++) {
+ irq_set_chip_and_handler(i, &combiner_chip, handle_level_irq);
+ irq_set_chip_data(i, &combiner_data[combiner_nr]);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+}
diff --git a/arch/arm/mach-exynos4/irq-eint.c b/arch/arm/mach-exynos4/irq-eint.c
new file mode 100644
index 00000000..9d87d2ac
--- /dev/null
+++ b/arch/arm/mach-exynos4/irq-eint.c
@@ -0,0 +1,230 @@
+/* linux/arch/arm/mach-exynos4/irq-eint.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - IRQ EINT support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+
+#include <plat/pm.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/regs-gpio.h>
+
+static DEFINE_SPINLOCK(eint_lock);
+
+static unsigned int eint0_15_data[16];
+
+static unsigned int 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 inline void exynos4_irq_eint_mask(struct irq_data *data)
+{
+ u32 mask;
+
+ spin_lock(&eint_lock);
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask |= eint_irq_to_bit(data->irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ spin_unlock(&eint_lock);
+}
+
+static void exynos4_irq_eint_unmask(struct irq_data *data)
+{
+ u32 mask;
+
+ spin_lock(&eint_lock);
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask &= ~(eint_irq_to_bit(data->irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ spin_unlock(&eint_lock);
+}
+
+static inline void exynos4_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)
+{
+ exynos4_irq_eint_mask(data);
+ exynos4_irq_eint_ack(data);
+}
+
+static int exynos4_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;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -EINVAL;
+ }
+
+ shift = (offs & 0x7) * 4;
+ mask = 0x7 << shift;
+
+ spin_lock(&eint_lock);
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ spin_unlock(&eint_lock);
+
+ switch (offs) {
+ case 0 ... 7:
+ s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+ break;
+ case 8 ... 15:
+ s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+ break;
+ case 16 ... 23:
+ s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+ break;
+ case 24 ... 31:
+ s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+ break;
+ default:
+ printk(KERN_ERR "No such irq number %d", offs);
+ }
+
+ return 0;
+}
+
+static struct irq_chip 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,
+#ifdef CONFIG_PM
+ .irq_set_wake = s3c_irqext_wake,
+#endif
+};
+
+/* exynos4_irq_demux_eint
+ *
+ * This function demuxes the IRQ from from EINTs 16 to 31.
+ * It is designed to be inlined into the specific handler
+ * s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void exynos4_irq_demux_eint(unsigned int start)
+{
+ unsigned int irq;
+
+ u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
+ u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
+
+ status &= ~mask;
+ status &= 0xff;
+
+ while (status) {
+ irq = fls(status) - 1;
+ generic_handle_irq(irq + start);
+ status &= ~(1 << irq);
+ }
+}
+
+static void exynos4_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));
+}
+
+static void exynos4_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);
+
+ generic_handle_irq(*irq_data);
+
+ chip->irq_unmask(&desc->irq_data);
+}
+
+int __init exynos4_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = 0 ; irq <= 31 ; irq++) {
+ irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_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);
+
+ for (irq = 0 ; irq <= 15 ; irq++) {
+ eint0_15_data[irq] = IRQ_EINT(irq);
+
+ irq_set_handler_data(exynos4_get_irq_nr(irq),
+ &eint0_15_data[irq]);
+ irq_set_chained_handler(exynos4_get_irq_nr(irq),
+ exynos4_irq_eint0_15);
+ }
+
+ return 0;
+}
+
+arch_initcall(exynos4_init_irq_eint);
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
new file mode 100644
index 00000000..6bf3d0ab
--- /dev/null
+++ b/arch/arm/mach-exynos4/localtimer.c
@@ -0,0 +1,26 @@
+/* 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-armlex4210.c b/arch/arm/mach-exynos4/mach-armlex4210.c
new file mode 100644
index 00000000..b482c628
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-armlex4210.c
@@ -0,0 +1,215 @@
+/* linux/arch/arm/mach-exynos4/mach-armlex4210.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/gpio.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/smsc911x.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/exynos4.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-srom.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define ARMLEX4210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define ARMLEX4210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define ARMLEX4210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg armlex4210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = ARMLEX4210_UCON_DEFAULT,
+ .ulcon = ARMLEX4210_ULCON_DEFAULT,
+ .ufcon = ARMLEX4210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = ARMLEX4210_UCON_DEFAULT,
+ .ulcon = ARMLEX4210_ULCON_DEFAULT,
+ .ufcon = ARMLEX4210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = ARMLEX4210_UCON_DEFAULT,
+ .ulcon = ARMLEX4210_ULCON_DEFAULT,
+ .ufcon = ARMLEX4210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = ARMLEX4210_UCON_DEFAULT,
+ .ulcon = ARMLEX4210_ULCON_DEFAULT,
+ .ufcon = ARMLEX4210_UFCON_DEFAULT,
+ },
+};
+
+static struct s3c_sdhci_platdata armlex4210_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
+};
+
+static struct s3c_sdhci_platdata armlex4210_hsmmc2_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = EXYNOS4_GPX2(5),
+ .ext_cd_gpio_invert = 1,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .max_width = 4,
+};
+
+static struct s3c_sdhci_platdata armlex4210_hsmmc3_pdata __initdata = {
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+ .max_width = 4,
+};
+
+static void __init armlex4210_sdhci_init(void)
+{
+ s3c_sdhci0_set_platdata(&armlex4210_hsmmc0_pdata);
+ s3c_sdhci2_set_platdata(&armlex4210_hsmmc2_pdata);
+ s3c_sdhci3_set_platdata(&armlex4210_hsmmc3_pdata);
+}
+
+static void __init armlex4210_wlan_init(void)
+{
+ /* enable */
+ s3c_gpio_cfgpin(EXYNOS4_GPX2(0), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(EXYNOS4_GPX2(0), S3C_GPIO_PULL_UP);
+
+ /* reset */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(6), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
+
+ /* wakeup */
+ s3c_gpio_cfgpin(EXYNOS4_GPX1(5), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(EXYNOS4_GPX1(5), S3C_GPIO_PULL_UP);
+}
+
+static struct resource armlex4210_smsc911x_resources[] = {
+ [0] = {
+ .start = EXYNOS4_PA_SROM_BANK(3),
+ .end = EXYNOS4_PA_SROM_BANK(3) + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT(27),
+ .end = IRQ_EINT(27),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ },
+};
+
+static struct smsc911x_platform_config smsc9215_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .mac = {0x00, 0x80, 0x00, 0x23, 0x45, 0x67},
+};
+
+static struct platform_device armlex4210_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(armlex4210_smsc911x_resources),
+ .resource = armlex4210_smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc9215_config,
+ },
+};
+
+static struct platform_device *armlex4210_devices[] __initdata = {
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &exynos4_device_sysmmu,
+ &samsung_asoc_dma,
+ &armlex4210_smsc911x,
+ &exynos4_device_ahci,
+};
+
+static void __init armlex4210_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) |
+ (0 << S5P_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S5P_SROM_BW__ADDRMODE__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 armlex4210_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(armlex4210_uartcfgs,
+ ARRAY_SIZE(armlex4210_uartcfgs));
+}
+
+static void __init armlex4210_machine_init(void)
+{
+ armlex4210_smsc911x_init();
+
+ armlex4210_sdhci_init();
+
+ armlex4210_wlan_init();
+
+ platform_add_devices(armlex4210_devices,
+ ARRAY_SIZE(armlex4210_devices));
+}
+
+MACHINE_START(ARMLEX4210, "ARMLEX4210")
+ /* Maintainer: Alim Akhtar <alim.akhtar@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = armlex4210_map_io,
+ .init_machine = armlex4210_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
new file mode 100644
index 00000000..642702bb
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-nuri.c
@@ -0,0 +1,410 @@
+/*
+ * linux/arch/arm/mach-exynos4/mach-nuri.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/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mmc/host.h>
+#include <linux/fb.h>
+#include <linux/pwm_backlight.h>
+
+#include <video/platform_lcd.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/devs.h>
+#include <plat/sdhci.h>
+#include <plat/ehci.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define NURI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define NURI_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define NURI_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG256 | \
+ S5PV210_UFCON_RXTRIG256)
+
+enum fixed_regulator_id {
+ FIXED_REG_ID_MMC = 0,
+};
+
+static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
+ {
+ .hwport = 0,
+ .ucon = NURI_UCON_DEFAULT,
+ .ulcon = NURI_ULCON_DEFAULT,
+ .ufcon = NURI_UFCON_DEFAULT,
+ },
+ {
+ .hwport = 1,
+ .ucon = NURI_UCON_DEFAULT,
+ .ulcon = NURI_ULCON_DEFAULT,
+ .ufcon = NURI_UFCON_DEFAULT,
+ },
+ {
+ .hwport = 2,
+ .ucon = NURI_UCON_DEFAULT,
+ .ulcon = NURI_ULCON_DEFAULT,
+ .ufcon = NURI_UFCON_DEFAULT,
+ },
+ {
+ .hwport = 3,
+ .ucon = NURI_UCON_DEFAULT,
+ .ulcon = NURI_ULCON_DEFAULT,
+ .ufcon = NURI_UFCON_DEFAULT,
+ },
+};
+
+/* eMMC */
+static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = {
+ .max_width = 8,
+ .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE | MMC_CAP_ERASE),
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply emmc_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+ REGULATOR_SUPPLY("vmmc", "dw_mmc"),
+};
+
+static struct regulator_init_data emmc_fixed_voltage_init_data = {
+ .constraints = {
+ .name = "VMEM_VDD_2.8V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(emmc_supplies),
+ .consumer_supplies = emmc_supplies,
+};
+
+static struct fixed_voltage_config emmc_fixed_voltage_config = {
+ .supply_name = "MASSMEMORY_EN (inverted)",
+ .microvolts = 2800000,
+ .gpio = EXYNOS4_GPL1(1),
+ .enable_high = false,
+ .init_data = &emmc_fixed_voltage_init_data,
+};
+
+static struct platform_device emmc_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = FIXED_REG_ID_MMC,
+ .dev = {
+ .platform_data = &emmc_fixed_voltage_config,
+ },
+};
+
+/* SD */
+static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE,
+ .ext_cd_gpio = EXYNOS4_GPX3(3), /* XEINT_27 */
+ .ext_cd_gpio_invert = 1,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* WLAN */
+static struct s3c_sdhci_platdata nuri_hsmmc3_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static void __init nuri_sdhci_init(void)
+{
+ s3c_sdhci0_set_platdata(&nuri_hsmmc0_data);
+ s3c_sdhci2_set_platdata(&nuri_hsmmc2_data);
+ s3c_sdhci3_set_platdata(&nuri_hsmmc3_data);
+}
+
+/* GPIO KEYS */
+static struct gpio_keys_button nuri_gpio_keys_tables[] = {
+ {
+ .code = KEY_VOLUMEUP,
+ .gpio = EXYNOS4_GPX2(0), /* XEINT16 */
+ .desc = "gpio-keys: KEY_VOLUMEUP",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_VOLUMEDOWN,
+ .gpio = EXYNOS4_GPX2(1), /* XEINT17 */
+ .desc = "gpio-keys: KEY_VOLUMEDOWN",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_POWER,
+ .gpio = EXYNOS4_GPX2(7), /* XEINT23 */
+ .desc = "gpio-keys: KEY_POWER",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data nuri_gpio_keys_data = {
+ .buttons = nuri_gpio_keys_tables,
+ .nbuttons = ARRAY_SIZE(nuri_gpio_keys_tables),
+};
+
+static struct platform_device nuri_gpio_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &nuri_gpio_keys_data,
+ },
+};
+
+static void nuri_lcd_power_on(struct plat_lcd_data *pd, unsigned int power)
+{
+ int gpio = EXYNOS4_GPE1(5);
+
+ gpio_request(gpio, "LVDS_nSHDN");
+ gpio_direction_output(gpio, power);
+ gpio_free(gpio);
+}
+
+static int nuri_bl_init(struct device *dev)
+{
+ int ret, gpio = EXYNOS4_GPE2(3);
+
+ ret = gpio_request(gpio, "LCD_LDO_EN");
+ if (!ret)
+ gpio_direction_output(gpio, 0);
+
+ return ret;
+}
+
+static int nuri_bl_notify(struct device *dev, int brightness)
+{
+ if (brightness < 1)
+ brightness = 0;
+
+ gpio_set_value(EXYNOS4_GPE2(3), 1);
+
+ return brightness;
+}
+
+static void nuri_bl_exit(struct device *dev)
+{
+ gpio_free(EXYNOS4_GPE2(3));
+}
+
+/* nuri pwm backlight */
+static struct platform_pwm_backlight_data nuri_backlight_data = {
+ .pwm_id = 0,
+ .pwm_period_ns = 30000,
+ .max_brightness = 100,
+ .dft_brightness = 50,
+ .init = nuri_bl_init,
+ .notify = nuri_bl_notify,
+ .exit = nuri_bl_exit,
+};
+
+static struct platform_device nuri_backlight_device = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_timer[0].dev,
+ .platform_data = &nuri_backlight_data,
+ },
+};
+
+static struct plat_lcd_data nuri_lcd_platform_data = {
+ .set_power = nuri_lcd_power_on,
+};
+
+static struct platform_device nuri_lcd_device = {
+ .name = "platform-lcd",
+ .id = -1,
+ .dev = {
+ .platform_data = &nuri_lcd_platform_data,
+ },
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+ /* Gyro, To be updated */
+};
+
+/* TSP */
+static u8 mxt_init_vals[] = {
+ /* MXT_GEN_COMMAND(6) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* MXT_GEN_POWER(7) */
+ 0x20, 0xff, 0x32,
+ /* MXT_GEN_ACQUIRE(8) */
+ 0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
+ /* MXT_TOUCH_MULTI(9) */
+ 0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ /* MXT_TOUCH_KEYARRAY(15) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x00,
+ /* MXT_SPT_GPIOPWM(19) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* MXT_PROCI_GRIPFACE(20) */
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
+ 0x0f, 0x0a,
+ /* MXT_PROCG_NOISE(22) */
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
+ 0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
+ /* MXT_TOUCH_PROXIMITY(23) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* MXT_PROCI_ONETOUCH(24) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* MXT_SPT_SELFTEST(25) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ /* MXT_PROCI_TWOTOUCH(27) */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* MXT_SPT_CTECONFIG(28) */
+ 0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
+};
+
+static struct mxt_platform_data mxt_platform_data = {
+ .config = mxt_init_vals,
+ .config_length = ARRAY_SIZE(mxt_init_vals),
+
+ .x_line = 18,
+ .y_line = 11,
+ .x_size = 1024,
+ .y_size = 600,
+ .blen = 0x1,
+ .threshold = 0x28,
+ .voltage = 2800000, /* 2.8V */
+ .orient = MXT_DIAGONAL_COUNTER,
+ .irqflags = IRQF_TRIGGER_FALLING,
+};
+
+static struct s3c2410_platform_i2c i2c3_data __initdata = {
+ .flags = 0,
+ .bus_num = 3,
+ .slave_addr = 0x10,
+ .frequency = 400 * 1000,
+ .sda_delay = 100,
+};
+
+static struct i2c_board_info i2c3_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
+ .platform_data = &mxt_platform_data,
+ .irq = IRQ_EINT(4),
+ },
+};
+
+static void __init nuri_tsp_init(void)
+{
+ int gpio;
+
+ /* TOUCH_INT: XEINT_4 */
+ gpio = EXYNOS4_GPX0(4);
+ gpio_request(gpio, "TOUCH_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+}
+
+/* GPIO I2C 5 (PMIC) */
+static struct i2c_board_info i2c5_devs[] __initdata = {
+ /* max8997, To be updated */
+};
+
+/* USB EHCI */
+static struct s5p_ehci_platdata nuri_ehci_pdata;
+
+static void __init nuri_ehci_init(void)
+{
+ struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
+
+ s5p_ehci_set_platdata(pdata);
+}
+
+static struct platform_device *nuri_devices[] __initdata = {
+ /* Samsung Platform Devices */
+ &emmc_fixed_voltage,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_wdt,
+ &s3c_device_timer[0],
+ &s5p_device_ehci,
+ &s3c_device_i2c3,
+
+ /* NURI Devices */
+ &nuri_gpio_keys,
+ &nuri_lcd_device,
+ &nuri_backlight_device,
+};
+
+static void __init nuri_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
+}
+
+static void __init nuri_machine_init(void)
+{
+ nuri_sdhci_init();
+ nuri_tsp_init();
+
+ i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+ s3c_i2c3_set_platdata(&i2c3_data);
+ i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
+ i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
+
+ nuri_ehci_init();
+ clk_xusbxti.rate = 24000000;
+
+ /* Last */
+ platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
+}
+
+MACHINE_START(NURI, "NURI")
+ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = nuri_map_io,
+ .init_machine = nuri_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
new file mode 100644
index 00000000..e645f7a9
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -0,0 +1,223 @@
+/* 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
new file mode 100644
index 00000000..edd81411
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -0,0 +1,244 @@
+/* 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/mach-universal_c210.c b/arch/arm/mach-exynos4/mach-universal_c210.c
new file mode 100644
index 00000000..97d329ff
--- /dev/null
+++ b/arch/arm/mach-exynos4/mach-universal_c210.c
@@ -0,0 +1,650 @@
+/* linux/arch/arm/mach-exynos4/mach-universal_c210.c
+ *
+ * Copyright (c) 2010 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/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/mfd/max8998.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/max8952.h>
+#include <linux/mmc/host.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/devs.h>
+#include <plat/iic.h>
+#include <plat/sdhci.h>
+
+#include <mach/map.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define UNIVERSAL_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define UNIVERSAL_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define UNIVERSAL_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG256 | \
+ S5PV210_UFCON_RXTRIG256)
+
+static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .ucon = UNIVERSAL_UCON_DEFAULT,
+ .ulcon = UNIVERSAL_ULCON_DEFAULT,
+ .ufcon = UNIVERSAL_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .ucon = UNIVERSAL_UCON_DEFAULT,
+ .ulcon = UNIVERSAL_ULCON_DEFAULT,
+ .ufcon = UNIVERSAL_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .ucon = UNIVERSAL_UCON_DEFAULT,
+ .ulcon = UNIVERSAL_ULCON_DEFAULT,
+ .ufcon = UNIVERSAL_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .ucon = UNIVERSAL_UCON_DEFAULT,
+ .ulcon = UNIVERSAL_ULCON_DEFAULT,
+ .ufcon = UNIVERSAL_UFCON_DEFAULT,
+ },
+};
+
+static struct regulator_consumer_supply max8952_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct max8952_platform_data universal_max8952_pdata __initdata = {
+ .gpio_vid0 = EXYNOS4_GPX0(3),
+ .gpio_vid1 = EXYNOS4_GPX0(4),
+ .gpio_en = -1, /* Not controllable, set "Always High" */
+ .default_mode = 0, /* vid0 = 0, vid1 = 0 */
+ .dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
+ .sync_freq = 0, /* default: fastest */
+ .ramp_speed = 0, /* default: fastest */
+
+ .reg_data = {
+ .constraints = {
+ .name = "VARM_1.2V",
+ .min_uV = 770000,
+ .max_uV = 1400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8952_consumer,
+ },
+};
+
+static struct regulator_consumer_supply lp3974_buck1_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_consumer_supply lp3974_buck2_consumer =
+ REGULATOR_SUPPLY("vddg3d", NULL);
+
+static struct regulator_init_data lp3974_buck1_data = {
+ .constraints = {
+ .name = "VINT_1.1V",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &lp3974_buck1_consumer,
+};
+
+static struct regulator_init_data lp3974_buck2_data = {
+ .constraints = {
+ .name = "VG3D_1.1V",
+ .min_uV = 750000,
+ .max_uV = 1500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &lp3974_buck2_consumer,
+};
+
+static struct regulator_init_data lp3974_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_buck4_data = {
+ .constraints = {
+ .name = "VMEM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo3_data = {
+ .constraints = {
+ .name = "VUSB+MIPI_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo4_data = {
+ .constraints = {
+ .name = "VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo5_data = {
+ .constraints = {
+ .name = "VTF_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo6_data = {
+ .constraints = {
+ .name = "LDO6",
+ .min_uV = 2000000,
+ .max_uV = 2000000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo7_data = {
+ .constraints = {
+ .name = "VLCD+VMIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo8_data = {
+ .constraints = {
+ .name = "VUSB+VDAC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo9_data = {
+ .constraints = {
+ .name = "VCC_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo10_data = {
+ .constraints = {
+ .name = "VPLL_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .boot_on = 1,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo11_data = {
+ .constraints = {
+ .name = "CAM_AF_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo12_data = {
+ .constraints = {
+ .name = "PS_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo13_data = {
+ .constraints = {
+ .name = "VHIC_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo14_data = {
+ .constraints = {
+ .name = "CAM_I_HOST_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo15_data = {
+ .constraints = {
+ .name = "CAM_S_DIG+FM33_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo16_data = {
+ .constraints = {
+ .name = "CAM_S_ANA_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_ldo17_data = {
+ .constraints = {
+ .name = "VCC_3.0V_LCD",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_32khz_ap_data = {
+ .constraints = {
+ .name = "32KHz AP",
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_32khz_cp_data = {
+ .constraints = {
+ .name = "32KHz CP",
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_vichg_data = {
+ .constraints = {
+ .name = "VICHG",
+ .state_mem = {
+ .disabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_esafeout1_data = {
+ .constraints = {
+ .name = "SAFEOUT1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data lp3974_esafeout2_data = {
+ .constraints = {
+ .name = "SAFEOUT2",
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct max8998_regulator_data lp3974_regulators[] = {
+ { MAX8998_LDO2, &lp3974_ldo2_data },
+ { MAX8998_LDO3, &lp3974_ldo3_data },
+ { MAX8998_LDO4, &lp3974_ldo4_data },
+ { MAX8998_LDO5, &lp3974_ldo5_data },
+ { MAX8998_LDO6, &lp3974_ldo6_data },
+ { MAX8998_LDO7, &lp3974_ldo7_data },
+ { MAX8998_LDO8, &lp3974_ldo8_data },
+ { MAX8998_LDO9, &lp3974_ldo9_data },
+ { MAX8998_LDO10, &lp3974_ldo10_data },
+ { MAX8998_LDO11, &lp3974_ldo11_data },
+ { MAX8998_LDO12, &lp3974_ldo12_data },
+ { MAX8998_LDO13, &lp3974_ldo13_data },
+ { MAX8998_LDO14, &lp3974_ldo14_data },
+ { MAX8998_LDO15, &lp3974_ldo15_data },
+ { MAX8998_LDO16, &lp3974_ldo16_data },
+ { MAX8998_LDO17, &lp3974_ldo17_data },
+ { MAX8998_BUCK1, &lp3974_buck1_data },
+ { MAX8998_BUCK2, &lp3974_buck2_data },
+ { MAX8998_BUCK3, &lp3974_buck3_data },
+ { MAX8998_BUCK4, &lp3974_buck4_data },
+ { MAX8998_EN32KHZ_AP, &lp3974_32khz_ap_data },
+ { MAX8998_EN32KHZ_CP, &lp3974_32khz_cp_data },
+ { MAX8998_ENVICHG, &lp3974_vichg_data },
+ { MAX8998_ESAFEOUT1, &lp3974_esafeout1_data },
+ { MAX8998_ESAFEOUT2, &lp3974_esafeout2_data },
+};
+
+static struct max8998_platform_data universal_lp3974_pdata = {
+ .num_regulators = ARRAY_SIZE(lp3974_regulators),
+ .regulators = lp3974_regulators,
+ .buck1_voltage1 = 1100000, /* INT */
+ .buck1_voltage2 = 1000000,
+ .buck1_voltage3 = 1100000,
+ .buck1_voltage4 = 1000000,
+ .buck1_set1 = EXYNOS4_GPX0(5),
+ .buck1_set2 = EXYNOS4_GPX0(6),
+ .buck2_voltage1 = 1200000, /* G3D */
+ .buck2_voltage2 = 1100000,
+ .buck1_default_idx = 0,
+ .buck2_set3 = EXYNOS4_GPE2(0),
+ .buck2_default_idx = 0,
+ .wakeup = true,
+};
+
+/* GPIO I2C 5 (PMIC) */
+static struct i2c_board_info i2c5_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("max8952", 0xC0 >> 1),
+ .platform_data = &universal_max8952_pdata,
+ }, {
+ I2C_BOARD_INFO("lp3974", 0xCC >> 1),
+ .platform_data = &universal_lp3974_pdata,
+ },
+};
+
+/* GPIO KEYS */
+static struct gpio_keys_button universal_gpio_keys_tables[] = {
+ {
+ .code = KEY_VOLUMEUP,
+ .gpio = EXYNOS4_GPX2(0), /* XEINT16 */
+ .desc = "gpio-keys: KEY_VOLUMEUP",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_VOLUMEDOWN,
+ .gpio = EXYNOS4_GPX2(1), /* XEINT17 */
+ .desc = "gpio-keys: KEY_VOLUMEDOWN",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_CONFIG,
+ .gpio = EXYNOS4_GPX2(2), /* XEINT18 */
+ .desc = "gpio-keys: KEY_CONFIG",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_CAMERA,
+ .gpio = EXYNOS4_GPX2(3), /* XEINT19 */
+ .desc = "gpio-keys: KEY_CAMERA",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ }, {
+ .code = KEY_OK,
+ .gpio = EXYNOS4_GPX3(5), /* XEINT29 */
+ .desc = "gpio-keys: KEY_OK",
+ .type = EV_KEY,
+ .active_low = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data universal_gpio_keys_data = {
+ .buttons = universal_gpio_keys_tables,
+ .nbuttons = ARRAY_SIZE(universal_gpio_keys_tables),
+};
+
+static struct platform_device universal_gpio_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &universal_gpio_keys_data,
+ },
+};
+
+/* eMMC */
+static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
+ .max_width = 8,
+ .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE),
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+static struct regulator_consumer_supply mmc0_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
+static struct regulator_init_data mmc0_fixed_voltage_init_data = {
+ .constraints = {
+ .name = "VMEM_VDD_2.8V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies),
+ .consumer_supplies = mmc0_supplies,
+};
+
+static struct fixed_voltage_config mmc0_fixed_voltage_config = {
+ .supply_name = "MASSMEMORY_EN",
+ .microvolts = 2800000,
+ .gpio = EXYNOS4_GPE1(3),
+ .enable_high = true,
+ .init_data = &mmc0_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc0_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &mmc0_fixed_voltage_config,
+ },
+};
+
+/* SD */
+static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE,
+ .ext_cd_gpio = EXYNOS4_GPX3(4), /* XEINT_28 */
+ .ext_cd_gpio_invert = 1,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
+};
+
+/* WiFi */
+static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
+ .max_width = 4,
+ .host_caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_DISABLE,
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+};
+
+static void __init universal_sdhci_init(void)
+{
+ s3c_sdhci0_set_platdata(&universal_hsmmc0_data);
+ s3c_sdhci2_set_platdata(&universal_hsmmc2_data);
+ s3c_sdhci3_set_platdata(&universal_hsmmc3_data);
+}
+
+/* I2C0 */
+static struct i2c_board_info i2c0_devs[] __initdata = {
+ /* Camera, To be updated */
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+ /* Gyro, To be updated */
+};
+
+static struct platform_device *universal_devices[] __initdata = {
+ /* Samsung Platform Devices */
+ &mmc0_fixed_voltage,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_i2c5,
+
+ /* Universal Devices */
+ &universal_gpio_keys,
+ &s5p_device_onenand,
+};
+
+static void __init universal_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
+}
+
+static void __init universal_machine_init(void)
+{
+ universal_sdhci_init();
+
+ i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs));
+ i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+ s3c_i2c5_set_platdata(NULL);
+ i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
+
+ /* Last */
+ platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
+}
+
+MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
+ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = exynos4_init_irq,
+ .map_io = universal_map_io,
+ .init_machine = universal_machine_init,
+ .timer = &exynos4_timer,
+MACHINE_END
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
new file mode 100644
index 00000000..14ac10b7
--- /dev/null
+++ b/arch/arm/mach-exynos4/mct.c
@@ -0,0 +1,421 @@
+/* linux/arch/arm/mach-exynos4/mct.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 MCT(Multi-Core Timer) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * 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 <linux/delay.h>
+#include <linux/percpu.h>
+
+#include <mach/map.h>
+#include <mach/regs-mct.h>
+#include <asm/mach/time.h>
+
+static unsigned long clk_cnt_per_tick;
+static unsigned long clk_rate;
+
+struct mct_clock_event_device {
+ struct clock_event_device *evt;
+ void __iomem *base;
+};
+
+struct mct_clock_event_device mct_tick[2];
+
+static void exynos4_mct_write(unsigned int value, void *addr)
+{
+ void __iomem *stat_addr;
+ u32 mask;
+ u32 i;
+
+ __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;
+ }
+
+ /* Wait maximum 1 ms until written values are applied */
+ for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
+ if (__raw_readl(stat_addr) & mask) {
+ __raw_writel(mask, stat_addr);
+ return;
+ }
+
+ panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
+}
+
+/* Clocksource handling */
+static void exynos4_mct_frc_start(u32 hi, u32 lo)
+{
+ u32 reg;
+
+ exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
+ exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
+
+ reg = __raw_readl(EXYNOS4_MCT_G_TCON);
+ reg |= MCT_G_TCON_START;
+ exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
+}
+
+static cycle_t exynos4_frc_read(struct clocksource *cs)
+{
+ unsigned int lo, hi;
+ u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+
+ do {
+ hi = hi2;
+ lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
+ hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+ } while (hi != hi2);
+
+ return ((cycle_t)hi << 32) | lo;
+}
+
+struct clocksource mct_frc = {
+ .name = "mct-frc",
+ .rating = 400,
+ .read = exynos4_frc_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init exynos4_clocksource_init(void)
+{
+ exynos4_mct_frc_start(0, 0);
+
+ if (clocksource_register_hz(&mct_frc, clk_rate))
+ panic("%s: can't register clocksource\n", mct_frc.name);
+}
+
+static void exynos4_mct_comp0_stop(void)
+{
+ unsigned int tcon;
+
+ tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+ tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
+
+ exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
+ exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
+}
+
+static void exynos4_mct_comp0_start(enum clock_event_mode mode,
+ unsigned long cycles)
+{
+ unsigned int tcon;
+ cycle_t comp_cycle;
+
+ tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+
+ if (mode == CLOCK_EVT_MODE_PERIODIC) {
+ tcon |= MCT_G_TCON_COMP0_AUTO_INC;
+ exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
+ }
+
+ comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
+ exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
+ exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
+
+ exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
+
+ tcon |= MCT_G_TCON_COMP0_ENABLE;
+ exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
+}
+
+static int exynos4_comp_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ exynos4_mct_comp0_start(evt->mode, cycles);
+
+ return 0;
+}
+
+static void exynos4_comp_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ exynos4_mct_comp0_stop();
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device mct_comp_device = {
+ .name = "mct-comp",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 250,
+ .set_next_event = exynos4_comp_set_next_event,
+ .set_mode = exynos4_comp_set_mode,
+};
+
+static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mct_comp_event_irq = {
+ .name = "mct_comp_irq",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = exynos4_mct_comp_isr,
+ .dev_id = &mct_comp_device,
+};
+
+static void exynos4_clockevent_init(void)
+{
+ clk_cnt_per_tick = clk_rate / 2 / HZ;
+
+ clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
+ mct_comp_device.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &mct_comp_device);
+ mct_comp_device.min_delta_ns =
+ clockevent_delta2ns(0xf, &mct_comp_device);
+ mct_comp_device.cpumask = cpumask_of(0);
+ clockevents_register_device(&mct_comp_device);
+
+ setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+/* Clock event handling */
+static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
+{
+ unsigned long tmp;
+ unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
+ void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
+
+ tmp = __raw_readl(addr);
+ if (tmp & mask) {
+ tmp &= ~mask;
+ exynos4_mct_write(tmp, addr);
+ }
+}
+
+static void exynos4_mct_tick_start(unsigned long cycles,
+ struct mct_clock_event_device *mevt)
+{
+ unsigned long tmp;
+
+ exynos4_mct_tick_stop(mevt);
+
+ tmp = (1 << 31) | cycles; /* MCT_L_UPDATE_ICNTB */
+
+ /* update interrupt count buffer */
+ exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
+
+ /* enable MCT tick interrupt */
+ exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
+
+ tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
+ tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
+ MCT_L_TCON_INTERVAL_MODE;
+ exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
+}
+
+static int exynos4_tick_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
+
+ exynos4_mct_tick_start(cycles, mevt);
+
+ return 0;
+}
+
+static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
+
+ exynos4_mct_tick_stop(mevt);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+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;
+
+ /*
+ * This is for supporting oneshot mode.
+ * Mct would generate interrupt periodically
+ * without explicit stopping.
+ */
+ 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);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mct_tick0_event_irq = {
+ .name = "mct_tick0_irq",
+ .flags = IRQF_TIMER | IRQF_NOBALANCING,
+ .handler = exynos4_mct_tick_isr,
+};
+
+static struct irqaction mct_tick1_event_irq = {
+ .name = "mct_tick1_irq",
+ .flags = IRQF_TIMER | IRQF_NOBALANCING,
+ .handler = exynos4_mct_tick_isr,
+};
+
+static void exynos4_mct_tick_init(struct clock_event_device *evt)
+{
+ unsigned int cpu = smp_processor_id();
+
+ 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";
+ }
+
+ 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);
+ evt->max_delta_ns =
+ clockevent_delta2ns(0x7fffffff, evt);
+ evt->min_delta_ns =
+ clockevent_delta2ns(0xf, evt);
+
+ clockevents_register_device(evt);
+
+ exynos4_mct_write(0x1, 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);
+ } 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);
+ }
+}
+
+/* Setup the local clock events for a CPU */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ exynos4_mct_tick_init(evt);
+}
+
+int local_timer_ack(void)
+{
+ return 0;
+}
+
+#endif /* CONFIG_LOCAL_TIMERS */
+
+static void __init exynos4_timer_resources(void)
+{
+ struct clk *mct_clk;
+ mct_clk = clk_get(NULL, "xtal");
+
+ clk_rate = clk_get_rate(mct_clk);
+}
+
+static void __init exynos4_timer_init(void)
+{
+ exynos4_timer_resources();
+ exynos4_clocksource_init();
+ exynos4_clockevent_init();
+}
+
+struct sys_timer exynos4_timer = {
+ .init = exynos4_timer_init,
+};
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
new file mode 100644
index 00000000..c5e65a02
--- /dev/null
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -0,0 +1,175 @@
+/* linux/arch/arm/mach-exynos4/platsmp.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Cloned from linux/arch/arm/mach-vexpress/platsmp.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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+
+extern void exynos4_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+
+volatile int __cpuinitdata pen_release = -1;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ return (void __iomem *)(S5P_VA_SCU);
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ write_pen_release(-1);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID.
+ */
+ write_pen_release(cpu);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * 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();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * 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;
+
+ /* sanity check */
+ if (ncores > NR_CPUS) {
+ printk(KERN_WARNING
+ "EXYNOS4: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base_addr());
+
+ /*
+ * 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);
+}
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c
new file mode 100644
index 00000000..8755ca8d
--- /dev/null
+++ b/arch/arm/mach-exynos4/pm.c
@@ -0,0 +1,429 @@
+/* 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-fimc.c b/arch/arm/mach-exynos4/setup-fimc.c
new file mode 100644
index 00000000..6a45078d
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-fimc.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * Exynos4 camera interface 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/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/camport.h>
+
+int exynos4_fimc_setup_gpio(enum s5p_camport_id id)
+{
+ u32 gpio8, gpio5;
+ u32 sfn;
+ int ret;
+
+ 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 */
+ 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 */
+ sfn = S3C_GPIO_SFN(3);
+ break;
+
+ default:
+ WARN(1, "Wrong camport id: %d\n", id);
+ return -EINVAL;
+ }
+
+ ret = s3c_gpio_cfgall_range(gpio8, 8, sfn, S3C_GPIO_PULL_UP);
+ if (ret)
+ return ret;
+
+ return s3c_gpio_cfgall_range(gpio5, 5, sfn, S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c0.c b/arch/arm/mach-exynos4/setup-i2c0.c
new file mode 100644
index 00000000..d395bd17
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c0.c
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.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);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c1.c b/arch/arm/mach-exynos4/setup-i2c1.c
new file mode 100644
index 00000000..fd7235a4
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c1.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c1.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C1 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ 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-exynos4/setup-i2c2.c
new file mode 100644
index 00000000..2694b19e
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c2.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c2.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C2 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c2_cfg_gpio(struct platform_device *dev)
+{
+ 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-exynos4/setup-i2c3.c
new file mode 100644
index 00000000..379bd306
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c3.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C3 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c3_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPA1(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c4.c b/arch/arm/mach-exynos4/setup-i2c4.c
new file mode 100644
index 00000000..9f3c0485
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c4.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C4 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c4_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c5.c b/arch/arm/mach-exynos4/setup-i2c5.c
new file mode 100644
index 00000000..77e1a1e5
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c5.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c5.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C5 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c5_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPB(6), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-i2c6.c b/arch/arm/mach-exynos4/setup-i2c6.c
new file mode 100644
index 00000000..284d12b7
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c6.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C6 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c6_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(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-exynos4/setup-i2c7.c
new file mode 100644
index 00000000..b7611ee3
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-i2c7.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-exynos4/setup-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *
+ * I2C7 GPIO configuration.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c7_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(EXYNOS4_GPD0(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-exynos4/setup-keypad.c b/arch/arm/mach-exynos4/setup-keypad.c
new file mode 100644
index 00000000..1ee0ebff
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-keypad.c
@@ -0,0 +1,35 @@
+/* linux/arch/arm/mach-exynos4/setup-keypad.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * GPIO configuration for Exynos4 KeyPad 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/gpio.h>
+#include <plat/gpio-cfg.h>
+
+void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
+{
+ /* Keypads can be of various combinations, Just making sure */
+
+ 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));
+
+ /* Set all the necessary GPX3 pins: KP_ROW[8~] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPX3(0), (rows - 8),
+ S3C_GPIO_SFN(3));
+ } else {
+ /* Set all the necessary GPX2 pins: KP_ROW[x] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPX2(0), rows,
+ S3C_GPIO_SFN(3));
+ }
+
+ /* Set all the necessary GPX1 pins to special-function 3: KP_COL[x] */
+ s3c_gpio_cfgrange_nopull(EXYNOS4_GPX1(0), cols, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-exynos4/setup-sdhci-gpio.c b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
new file mode 100644
index 00000000..e8d08bf8
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-sdhci-gpio.c
@@ -0,0 +1,152 @@
+/* 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-sdhci.c b/arch/arm/mach-exynos4/setup-sdhci.c
new file mode 100644
index 00000000..1e83f8cf
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-sdhci.c
@@ -0,0 +1,69 @@
+/* linux/arch/arm/mach-exynos4/setup-sdhci.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *exynos4_hsmmc_clksrcs[4] = {
+ [0] = NULL,
+ [1] = NULL,
+ [2] = "sclk_mmc", /* mmc_bus */
+ [3] = NULL,
+};
+
+void exynos4_setup_sdhci_cfg_card(struct platform_device *dev, void __iomem *r,
+ struct mmc_ios *ios, struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ /* don't need to alter anything according to card-type */
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+
+ /* select base clock source to HCLK */
+
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+
+ /*
+ * clear async mode, enable conflict mask, rx feedback ctrl, SD
+ * clk hold and no use debounce count
+ */
+
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ /* Tx and Rx feedback clock delay control */
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/mach-exynos4/setup-usb-phy.c b/arch/arm/mach-exynos4/setup-usb-phy.c
new file mode 100644
index 00000000..0883c1b8
--- /dev/null
+++ b/arch/arm/mach-exynos4/setup-usb-phy.c
@@ -0,0 +1,136 @@
+/*
+ * 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/sleep.S b/arch/arm/mach-exynos4/sleep.S
new file mode 100644
index 00000000..6b624254
--- /dev/null
+++ b/arch/arm/mach-exynos4/sleep.S
@@ -0,0 +1,76 @@
+/* linux/arch/arm/mach-exynos4/sleep.S
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * EXYNOS4210 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+ .text
+
+ /*
+ * s3c_cpu_save
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(s3c_cpu_save)
+
+ stmfd sp!, { r3 - r12, lr }
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ ldr r0, =pm_cpu_sleep
+ ldr r0, [ r0 ]
+ mov pc, r0
+
+resume_with_mmu:
+ 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
+
+ /*
+ * 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)
+ b cpu_resume
diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c
new file mode 100644
index 00000000..ebb8f38d
--- /dev/null
+++ b/arch/arm/mach-exynos4/time.c
@@ -0,0 +1,301 @@
+/* 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-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig
new file mode 100644
index 00000000..46adca06
--- /dev/null
+++ b/arch/arm/mach-footbridge/Kconfig
@@ -0,0 +1,95 @@
+if ARCH_FOOTBRIDGE
+
+menu "Footbridge Implementations"
+
+config ARCH_CATS
+ bool "CATS"
+ select CLKSRC_I8253
+ select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
+ help
+ Say Y here if you intend to run this kernel on the CATS.
+
+ Saying N will reduce the size of the Footbridge kernel.
+
+config ARCH_PERSONAL_SERVER
+ bool "Compaq Personal Server"
+ select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
+ ---help---
+ Say Y here if you intend to run this kernel on the Compaq
+ Personal Server.
+
+ Saying N will reduce the size of the Footbridge kernel.
+
+ The Compaq Personal Server is not available for purchase.
+ There are no product plans beyond the current research
+ prototypes at this time. Information is available at:
+
+ <http://www.crl.hpl.hp.com/projects/personalserver/>
+
+ If you have any questions or comments about the Compaq Personal
+ Server, send e-mail to <skiff@crl.dec.com>.
+
+config ARCH_EBSA285_ADDIN
+ bool "EBSA285 (addin mode)"
+ select ARCH_EBSA285
+ select FOOTBRIDGE_ADDIN
+ help
+ Say Y here if you intend to run this kernel on the EBSA285 card
+ in addin mode.
+
+ Saying N will reduce the size of the Footbridge kernel.
+
+config ARCH_EBSA285_HOST
+ bool "EBSA285 (host mode)"
+ select ARCH_EBSA285
+ select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
+ help
+ Say Y here if you intend to run this kernel on the EBSA285 card
+ in host ("central function") mode.
+
+ Saying N will reduce the size of the Footbridge kernel.
+
+config ARCH_NETWINDER
+ bool "NetWinder"
+ select CLKSRC_I8253
+ select FOOTBRIDGE_HOST
+ select ISA
+ select ISA_DMA
+ select PCI
+ help
+ Say Y here if you intend to run this kernel on the Rebel.COM
+ NetWinder. Information about this machine can be found at:
+
+ <http://www.netwinder.org/>
+
+ Saying N will reduce the size of the Footbridge kernel.
+
+endmenu
+
+# Footbridge support
+config FOOTBRIDGE
+ bool
+
+# Footbridge in host mode
+config FOOTBRIDGE_HOST
+ bool
+
+# Footbridge in addin mode
+config FOOTBRIDGE_ADDIN
+ bool
+
+# EBSA285 board in either host or addin mode
+config ARCH_EBSA285
+ select ARCH_MAY_HAVE_PC_FDC
+ bool
+
+endif
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
new file mode 100644
index 00000000..3afb1b25
--- /dev/null
+++ b/arch/arm/mach-footbridge/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := common.o dc21285.o dma.o isa-irq.o
+obj-m :=
+obj-n :=
+obj- :=
+
+pci-$(CONFIG_ARCH_CATS) += cats-pci.o
+pci-$(CONFIG_ARCH_EBSA285_HOST) += ebsa285-pci.o
+pci-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
+pci-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
+
+leds-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
+leds-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
+
+obj-$(CONFIG_ARCH_CATS) += cats-hw.o isa-timer.o
+obj-$(CONFIG_ARCH_EBSA285) += ebsa285.o dc21285-timer.o
+obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
+obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o
+
+obj-$(CONFIG_PCI) +=$(pci-y)
+obj-$(CONFIG_LEDS) +=$(leds-y)
+
+obj-$(CONFIG_ISA) += isa.o isa-rtc.o
diff --git a/arch/arm/mach-footbridge/Makefile.boot b/arch/arm/mach-footbridge/Makefile.boot
new file mode 100644
index 00000000..c7e75acf
--- /dev/null
+++ b/arch/arm/mach-footbridge/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
new file mode 100644
index 00000000..5b1a8db7
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/mach-footbridge/cats-hw.c
+ *
+ * CATS machine fixup
+ *
+ * Copyright (C) 1998, 1999 Russell King, Phil Blundell
+ */
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/screen_info.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+#define CFG_PORT 0x370
+#define INDEX_PORT (CFG_PORT)
+#define DATA_PORT (CFG_PORT + 1)
+
+static int __init cats_hw_init(void)
+{
+ if (machine_is_cats()) {
+ /* Set Aladdin to CONFIGURE mode */
+ outb(0x51, CFG_PORT);
+ outb(0x23, CFG_PORT);
+
+ /* Select logical device 3 */
+ outb(0x07, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ /* Set parallel port to DMA channel 3, ECP+EPP1.9,
+ enable EPP timeout */
+ outb(0x74, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ outb(0xf0, INDEX_PORT);
+ outb(0x0f, DATA_PORT);
+
+ outb(0xf1, INDEX_PORT);
+ outb(0x07, DATA_PORT);
+
+ /* Select logical device 4 */
+ outb(0x07, INDEX_PORT);
+ outb(0x04, DATA_PORT);
+
+ /* UART1 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Select logical device 5 */
+ outb(0x07, INDEX_PORT);
+ outb(0x05, DATA_PORT);
+
+ /* UART2 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Set Aladdin to RUN mode */
+ outb(0xbb, CFG_PORT);
+ }
+
+ return 0;
+}
+
+__initcall(cats_hw_init);
+
+/*
+ * CATS uses soft-reboot by default, since
+ * hard reboots fail on early boards.
+ */
+static void __init
+fixup_cats(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ screen_info.orig_video_lines = 25;
+ screen_info.orig_video_points = 16;
+ screen_info.orig_y = 24;
+}
+
+MACHINE_START(CATS, "Chalice-CATS")
+ /* Maintainer: Philip Blundell */
+ .boot_params = 0x00000100,
+ .soft_reboot = 1,
+ .fixup = fixup_cats,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .timer = &isa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c
new file mode 100644
index 00000000..ae3e1c8c
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-pci.c
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/arm/mach-footbridge/cats-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/* cats host-specific stuff */
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+
+static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->irq >= 255)
+ return -1; /* not a valid interrupt. */
+
+ if (dev->irq >= 128)
+ return dev->irq & 0x1f;
+
+ if (dev->irq >= 1 && dev->irq <= 4)
+ return irqmap_cats[dev->irq - 1];
+
+ if (dev->irq != 0)
+ printk("PCI: device %02x:%02x has unknown irq line %x\n",
+ dev->bus->number, dev->devfn, dev->irq);
+
+ return -1;
+}
+
+/*
+ * why not the standard PCI swizzle? does this prevent 4-port tulip
+ * cards being used (ie, pci-pci bridge based cards)?
+ */
+static struct hw_pci cats_pci __initdata = {
+ .swizzle = NULL,
+ .map_irq = cats_map_irq,
+ .nr_controllers = 1,
+ .setup = dc21285_setup,
+ .scan = dc21285_scan_bus,
+ .preinit = dc21285_preinit,
+ .postinit = dc21285_postinit,
+};
+
+static int __init cats_pci_init(void)
+{
+ if (machine_is_cats())
+ pci_common_init(&cats_pci);
+ return 0;
+}
+
+subsys_initcall(cats_pci_init);
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
new file mode 100644
index 00000000..38a44f9b
--- /dev/null
+++ b/arch/arm/mach-footbridge/common.c
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/arm/mach-footbridge/common.c
+ *
+ * Copyright (C) 1998-2000 Russell King, Dave Gilbert.
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/hardware/dec21285.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include "common.h"
+
+unsigned int mem_fclk_21285 = 50000000;
+
+EXPORT_SYMBOL(mem_fclk_21285);
+
+static int __init early_fclk(char *arg)
+{
+ mem_fclk_21285 = simple_strtoul(arg, NULL, 0);
+ return 0;
+}
+
+early_param("mem_fclk_21285", early_fclk);
+
+static int __init parse_tag_memclk(const struct tag *tag)
+{
+ mem_fclk_21285 = tag->u.memclk.fmemclk;
+ return 0;
+}
+
+__tagtable(ATAG_MEMCLK, parse_tag_memclk);
+
+/*
+ * Footbridge IRQ translation table
+ * Converts from our IRQ numbers into FootBridge masks
+ */
+static const int fb_irq_mask[] = {
+ IRQ_MASK_UART_RX, /* 0 */
+ IRQ_MASK_UART_TX, /* 1 */
+ IRQ_MASK_TIMER1, /* 2 */
+ IRQ_MASK_TIMER2, /* 3 */
+ IRQ_MASK_TIMER3, /* 4 */
+ IRQ_MASK_IN0, /* 5 */
+ IRQ_MASK_IN1, /* 6 */
+ IRQ_MASK_IN2, /* 7 */
+ IRQ_MASK_IN3, /* 8 */
+ IRQ_MASK_DOORBELLHOST, /* 9 */
+ IRQ_MASK_DMA1, /* 10 */
+ IRQ_MASK_DMA2, /* 11 */
+ IRQ_MASK_PCI, /* 12 */
+ IRQ_MASK_SDRAMPARITY, /* 13 */
+ IRQ_MASK_I2OINPOST, /* 14 */
+ IRQ_MASK_PCI_ABORT, /* 15 */
+ IRQ_MASK_PCI_SERR, /* 16 */
+ IRQ_MASK_DISCARD_TIMER, /* 17 */
+ IRQ_MASK_PCI_DPERR, /* 18 */
+ IRQ_MASK_PCI_PERR, /* 19 */
+};
+
+static void fb_mask_irq(struct irq_data *d)
+{
+ *CSR_IRQ_DISABLE = fb_irq_mask[_DC21285_INR(d->irq)];
+}
+
+static void fb_unmask_irq(struct irq_data *d)
+{
+ *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(d->irq)];
+}
+
+static struct irq_chip fb_chip = {
+ .irq_ack = fb_mask_irq,
+ .irq_mask = fb_mask_irq,
+ .irq_unmask = fb_unmask_irq,
+};
+
+static void __init __fb_init_irq(void)
+{
+ unsigned int irq;
+
+ /*
+ * setup DC21285 IRQs
+ */
+ *CSR_IRQ_DISABLE = -1;
+ *CSR_FIQ_DISABLE = -1;
+
+ for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
+ irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+}
+
+void __init footbridge_init_irq(void)
+{
+ __fb_init_irq();
+
+ if (!footbridge_cfn_mode())
+ return;
+
+ if (machine_is_ebsa285())
+ /* The following is dependent on which slot
+ * you plug the Southbridge card into. We
+ * currently assume that you plug it into
+ * the right-hand most slot.
+ */
+ isa_init_irq(IRQ_PCI);
+
+ if (machine_is_cats())
+ isa_init_irq(IRQ_IN2);
+
+ if (machine_is_netwinder())
+ isa_init_irq(IRQ_IN3);
+}
+
+/*
+ * Common mapping for all systems. Note that the outbound write flush is
+ * commented out since there is a "No Fix" problem with it. Not mapping
+ * it means that we have extra bullet protection on our feet.
+ */
+static struct map_desc fb_common_io_desc[] __initdata = {
+ {
+ .virtual = ARMCSR_BASE,
+ .pfn = __phys_to_pfn(DC21285_ARMCSR_BASE),
+ .length = ARMCSR_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = XBUS_BASE,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = XBUS_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+/*
+ * The mapping when the footbridge is in host mode. We don't map any of
+ * this when we are in add-in mode.
+ */
+static struct map_desc ebsa285_host_io_desc[] __initdata = {
+#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
+ {
+ .virtual = PCIMEM_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_MEM),
+ .length = PCIMEM_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = PCICFG0_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
+ .length = PCICFG0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = PCICFG1_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
+ .length = PCICFG1_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = PCIIACK_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IACK),
+ .length = PCIIACK_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = PCIO_BASE,
+ .pfn = __phys_to_pfn(DC21285_PCI_IO),
+ .length = PCIO_SIZE,
+ .type = MT_DEVICE,
+ },
+#endif
+};
+
+void __init footbridge_map_io(void)
+{
+ /*
+ * Set up the common mapping first; we need this to
+ * determine whether we're in host mode or not.
+ */
+ iotable_init(fb_common_io_desc, ARRAY_SIZE(fb_common_io_desc));
+
+ /*
+ * Now, work out what we've got to map in addition on this
+ * platform.
+ */
+ if (footbridge_cfn_mode())
+ iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
+}
+
+#ifdef CONFIG_FOOTBRIDGE_ADDIN
+
+static inline unsigned long fb_bus_sdram_offset(void)
+{
+ return *CSR_PCISDRAMBASE & 0xfffffff0;
+}
+
+/*
+ * These two functions convert virtual addresses to PCI addresses and PCI
+ * addresses to virtual addresses. Note that it is only legal to use these
+ * on memory obtained via get_zeroed_page or kmalloc.
+ */
+unsigned long __virt_to_bus(unsigned long res)
+{
+ WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
+
+ return res + (fb_bus_sdram_offset() - PAGE_OFFSET);
+}
+EXPORT_SYMBOL(__virt_to_bus);
+
+unsigned long __bus_to_virt(unsigned long res)
+{
+ res = res - (fb_bus_sdram_offset() - PAGE_OFFSET);
+
+ WARN_ON(res < PAGE_OFFSET || res >= (unsigned long)high_memory);
+
+ return res;
+}
+EXPORT_SYMBOL(__bus_to_virt);
+
+unsigned long __pfn_to_bus(unsigned long pfn)
+{
+ return __pfn_to_phys(pfn) + (fb_bus_sdram_offset() - PHYS_OFFSET);
+}
+EXPORT_SYMBOL(__pfn_to_bus);
+
+unsigned long __bus_to_pfn(unsigned long bus)
+{
+ return __phys_to_pfn(bus - (fb_bus_sdram_offset() - PHYS_OFFSET));
+}
+EXPORT_SYMBOL(__bus_to_pfn);
+
+#endif
diff --git a/arch/arm/mach-footbridge/common.h b/arch/arm/mach-footbridge/common.h
new file mode 100644
index 00000000..b05e662d
--- /dev/null
+++ b/arch/arm/mach-footbridge/common.h
@@ -0,0 +1,10 @@
+
+extern struct sys_timer footbridge_timer;
+extern struct sys_timer isa_timer;
+
+extern void isa_rtc_init(void);
+
+extern void footbridge_map_io(void);
+extern void footbridge_init_irq(void);
+
+extern void isa_init_irq(unsigned int irq);
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
new file mode 100644
index 00000000..121ad1d4
--- /dev/null
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-footbridge/dc21285-timer.c
+ *
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+static cycle_t cksrc_dc21285_read(struct clocksource *cs)
+{
+ return cs->mask - *CSR_TIMER2_VALUE;
+}
+
+static int cksrc_dc21285_enable(struct clocksource *cs)
+{
+ *CSR_TIMER2_LOAD = cs->mask;
+ *CSR_TIMER2_CLR = 0;
+ *CSR_TIMER2_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV16;
+ return 0;
+}
+
+static void cksrc_dc21285_disable(struct clocksource *cs)
+{
+ *CSR_TIMER2_CNTL = 0;
+}
+
+static struct clocksource cksrc_dc21285 = {
+ .name = "dc21285_timer2",
+ .rating = 200,
+ .read = cksrc_dc21285_read,
+ .enable = cksrc_dc21285_enable,
+ .disable = cksrc_dc21285_disable,
+ .mask = CLOCKSOURCE_MASK(24),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void ckevt_dc21285_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *c)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ *CSR_TIMER1_CLR = 0;
+ *CSR_TIMER1_LOAD = (mem_fclk_21285 + 8 * HZ) / (16 * HZ);
+ *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD |
+ TIMER_CNTL_DIV16;
+ break;
+
+ default:
+ *CSR_TIMER1_CNTL = 0;
+ break;
+ }
+}
+
+static struct clock_event_device ckevt_dc21285 = {
+ .name = "dc21285_timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .rating = 200,
+ .irq = IRQ_TIMER1,
+ .set_mode = ckevt_dc21285_set_mode,
+};
+
+static irqreturn_t timer1_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *ce = dev_id;
+
+ *CSR_TIMER1_CLR = 0;
+
+ ce->event_handler(ce);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction footbridge_timer_irq = {
+ .name = "dc21285_timer1",
+ .handler = timer1_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .dev_id = &ckevt_dc21285,
+};
+
+/*
+ * Set up timer interrupt.
+ */
+static void __init footbridge_timer_init(void)
+{
+ struct clock_event_device *ce = &ckevt_dc21285;
+
+ clocksource_register_hz(&cksrc_dc21285, (mem_fclk_21285 + 8) / 16);
+
+ setup_irq(ce->irq, &footbridge_timer_irq);
+
+ clockevents_calc_mult_shift(ce, mem_fclk_21285, 5);
+ ce->max_delta_ns = clockevent_delta2ns(0xffffff, ce);
+ ce->min_delta_ns = clockevent_delta2ns(0x000004, ce);
+ ce->cpumask = cpumask_of(smp_processor_id());
+
+ clockevents_register_device(ce);
+}
+
+struct sys_timer footbridge_timer = {
+ .init = footbridge_timer_init,
+};
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
new file mode 100644
index 00000000..3ffa5484
--- /dev/null
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -0,0 +1,388 @@
+/*
+ * linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285
+ *
+ * Copyright (C) 1998-2001 Russell King
+ * Copyright (C) 1998-2000 Phil Blundell
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
+
+#define MAX_SLOTS 21
+
+#define PCICMD_ABORT ((PCI_STATUS_REC_MASTER_ABORT| \
+ PCI_STATUS_REC_TARGET_ABORT)<<16)
+
+#define PCICMD_ERROR_BITS ((PCI_STATUS_DETECTED_PARITY | \
+ PCI_STATUS_REC_MASTER_ABORT | \
+ PCI_STATUS_REC_TARGET_ABORT | \
+ PCI_STATUS_PARITY) << 16)
+
+extern int setup_arm_irq(int, struct irqaction *);
+extern void pcibios_report_status(u_int status_mask, int warn);
+
+static unsigned long
+dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
+{
+ unsigned long addr = 0;
+
+ if (bus->number == 0) {
+ if (PCI_SLOT(devfn) == 0)
+ /*
+ * For devfn 0, point at the 21285
+ */
+ addr = ARMCSR_BASE;
+ else {
+ devfn -= 1 << 3;
+
+ if (devfn < PCI_DEVFN(MAX_SLOTS, 0))
+ addr = PCICFG0_BASE | 0xc00000 | (devfn << 8);
+ }
+ } else
+ addr = PCICFG1_BASE | (bus->number << 16) | (devfn << 8);
+
+ return addr;
+}
+
+static int
+dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ unsigned long addr = dc21285_base_address(bus, devfn);
+ u32 v = 0xffffffff;
+
+ if (addr)
+ switch (size) {
+ case 1:
+ asm("ldrb %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where) : "cc");
+ break;
+ case 2:
+ asm("ldrh %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where) : "cc");
+ break;
+ case 4:
+ asm("ldr %0, [%1, %2]"
+ : "=r" (v) : "r" (addr), "r" (where) : "cc");
+ break;
+ }
+
+ *value = v;
+
+ v = *CSR_PCICMD;
+ if (v & PCICMD_ABORT) {
+ *CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
+ return -1;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = dc21285_base_address(bus, devfn);
+ u32 v;
+
+ if (addr)
+ switch (size) {
+ case 1:
+ asm("strb %0, [%1, %2]"
+ : : "r" (value), "r" (addr), "r" (where)
+ : "cc");
+ break;
+ case 2:
+ asm("strh %0, [%1, %2]"
+ : : "r" (value), "r" (addr), "r" (where)
+ : "cc");
+ break;
+ case 4:
+ asm("str %0, [%1, %2]"
+ : : "r" (value), "r" (addr), "r" (where)
+ : "cc");
+ break;
+ }
+
+ v = *CSR_PCICMD;
+ if (v & PCICMD_ABORT) {
+ *CSR_PCICMD = v & (0xffff|PCICMD_ABORT);
+ return -1;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops dc21285_ops = {
+ .read = dc21285_read_config,
+ .write = dc21285_write_config,
+};
+
+static struct timer_list serr_timer;
+static struct timer_list perr_timer;
+
+static void dc21285_enable_error(unsigned long __data)
+{
+ switch (__data) {
+ case IRQ_PCI_SERR:
+ del_timer(&serr_timer);
+ break;
+
+ case IRQ_PCI_PERR:
+ del_timer(&perr_timer);
+ break;
+ }
+
+ enable_irq(__data);
+}
+
+/*
+ * Warn on PCI errors.
+ */
+static irqreturn_t dc21285_abort_irq(int irq, void *dev_id)
+{
+ unsigned int cmd;
+ unsigned int status;
+
+ cmd = *CSR_PCICMD;
+ status = cmd >> 16;
+ cmd = cmd & 0xffff;
+
+ if (status & PCI_STATUS_REC_MASTER_ABORT) {
+ printk(KERN_DEBUG "PCI: master abort, pc=0x%08lx\n",
+ instruction_pointer(get_irq_regs()));
+ cmd |= PCI_STATUS_REC_MASTER_ABORT << 16;
+ }
+
+ if (status & PCI_STATUS_REC_TARGET_ABORT) {
+ printk(KERN_DEBUG "PCI: target abort: ");
+ pcibios_report_status(PCI_STATUS_REC_MASTER_ABORT |
+ PCI_STATUS_SIG_TARGET_ABORT |
+ PCI_STATUS_REC_TARGET_ABORT, 1);
+ printk("\n");
+
+ cmd |= PCI_STATUS_REC_TARGET_ABORT << 16;
+ }
+
+ *CSR_PCICMD = cmd;
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dc21285_serr_irq(int irq, void *dev_id)
+{
+ struct timer_list *timer = dev_id;
+ unsigned int cntl;
+
+ printk(KERN_DEBUG "PCI: system error received: ");
+ pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
+ printk("\n");
+
+ cntl = *CSR_SA110_CNTL & 0xffffdf07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+
+ /*
+ * back off this interrupt
+ */
+ disable_irq(irq);
+ timer->expires = jiffies + HZ;
+ add_timer(timer);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dc21285_discard_irq(int irq, void *dev_id)
+{
+ printk(KERN_DEBUG "PCI: discard timer expired\n");
+ *CSR_SA110_CNTL &= 0xffffde07;
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dc21285_dparity_irq(int irq, void *dev_id)
+{
+ unsigned int cmd;
+
+ printk(KERN_DEBUG "PCI: data parity error detected: ");
+ pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+ printk("\n");
+
+ cmd = *CSR_PCICMD & 0xffff;
+ *CSR_PCICMD = cmd | 1 << 24;
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t dc21285_parity_irq(int irq, void *dev_id)
+{
+ struct timer_list *timer = dev_id;
+ unsigned int cmd;
+
+ printk(KERN_DEBUG "PCI: parity error detected: ");
+ pcibios_report_status(PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY, 1);
+ printk("\n");
+
+ cmd = *CSR_PCICMD & 0xffff;
+ *CSR_PCICMD = cmd | 1 << 31;
+
+ /*
+ * back off this interrupt
+ */
+ disable_irq(irq);
+ timer->expires = jiffies + HZ;
+ add_timer(timer);
+
+ return IRQ_HANDLED;
+}
+
+int __init dc21285_setup(int nr, struct pci_sys_data *sys)
+{
+ struct resource *res;
+
+ if (nr || !footbridge_cfn_mode())
+ return 0;
+
+ res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+ if (!res) {
+ printk("out of memory for root bus resources");
+ return 0;
+ }
+
+ res[0].flags = IORESOURCE_MEM;
+ res[0].name = "Footbridge non-prefetch";
+ res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ res[1].name = "Footbridge prefetch";
+
+ allocate_resource(&iomem_resource, &res[1], 0x20000000,
+ 0xa0000000, 0xffffffff, 0x20000000, NULL, NULL);
+ allocate_resource(&iomem_resource, &res[0], 0x40000000,
+ 0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
+
+ sys->resource[0] = &ioport_resource;
+ sys->resource[1] = &res[0];
+ sys->resource[2] = &res[1];
+ sys->mem_offset = DC21285_PCI_MEM;
+
+ return 1;
+}
+
+struct pci_bus * __init dc21285_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(0, &dc21285_ops, sys);
+}
+
+#define dc21285_request_irq(_a, _b, _c, _d, _e) \
+ WARN_ON(request_irq(_a, _b, _c, _d, _e) < 0)
+
+void __init dc21285_preinit(void)
+{
+ unsigned int mem_size, mem_mask;
+ int cfn_mode;
+
+ mem_size = (unsigned int)high_memory - PAGE_OFFSET;
+ for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)
+ if (mem_mask >= mem_size)
+ break;
+
+ /*
+ * These registers need to be set up whether we're the
+ * central function or not.
+ */
+ *CSR_SDRAMBASEMASK = (mem_mask - 1) & 0x0ffc0000;
+ *CSR_SDRAMBASEOFFSET = 0;
+ *CSR_ROMBASEMASK = 0x80000000;
+ *CSR_CSRBASEMASK = 0;
+ *CSR_CSRBASEOFFSET = 0;
+ *CSR_PCIADDR_EXTN = 0;
+
+ cfn_mode = __footbridge_cfn_mode();
+
+ printk(KERN_INFO "PCI: DC21285 footbridge, revision %02lX, in "
+ "%s mode\n", *CSR_CLASSREV & 0xff, cfn_mode ?
+ "central function" : "addin");
+
+ if (footbridge_cfn_mode()) {
+ /*
+ * Clear any existing errors - we aren't
+ * interested in historical data...
+ */
+ *CSR_SA110_CNTL = (*CSR_SA110_CNTL & 0xffffde07) |
+ SA110_CNTL_RXSERR;
+ *CSR_PCICMD = (*CSR_PCICMD & 0xffff) | PCICMD_ERROR_BITS;
+ }
+
+ init_timer(&serr_timer);
+ init_timer(&perr_timer);
+
+ serr_timer.data = IRQ_PCI_SERR;
+ serr_timer.function = dc21285_enable_error;
+ perr_timer.data = IRQ_PCI_PERR;
+ perr_timer.function = dc21285_enable_error;
+
+ /*
+ * We don't care if these fail.
+ */
+ dc21285_request_irq(IRQ_PCI_SERR, dc21285_serr_irq, IRQF_DISABLED,
+ "PCI system error", &serr_timer);
+ dc21285_request_irq(IRQ_PCI_PERR, dc21285_parity_irq, IRQF_DISABLED,
+ "PCI parity error", &perr_timer);
+ dc21285_request_irq(IRQ_PCI_ABORT, dc21285_abort_irq, IRQF_DISABLED,
+ "PCI abort", NULL);
+ dc21285_request_irq(IRQ_DISCARD_TIMER, dc21285_discard_irq, IRQF_DISABLED,
+ "Discard timer", NULL);
+ dc21285_request_irq(IRQ_PCI_DPERR, dc21285_dparity_irq, IRQF_DISABLED,
+ "PCI data parity", NULL);
+
+ if (cfn_mode) {
+ static struct resource csrio;
+
+ csrio.flags = IORESOURCE_IO;
+ csrio.name = "Footbridge";
+
+ allocate_resource(&ioport_resource, &csrio, 128,
+ 0xff00, 0xffff, 128, NULL, NULL);
+
+ /*
+ * Map our SDRAM at a known address in PCI space, just in case
+ * the firmware had other ideas. Using a nonzero base is
+ * necessary, since some VGA cards forcefully use PCI addresses
+ * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
+ */
+ *CSR_PCICSRBASE = 0xf4000000;
+ *CSR_PCICSRIOBASE = csrio.start;
+ *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
+ *CSR_PCIROMBASE = 0;
+ *CSR_PCICMD = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_INVALIDATE | PCICMD_ERROR_BITS;
+ } else if (footbridge_cfn_mode() != 0) {
+ /*
+ * If we are not compiled to accept "add-in" mode, then
+ * we are using a constant virt_to_bus translation which
+ * can not hope to cater for the way the host BIOS has
+ * set up the machine.
+ */
+ panic("PCI: this kernel is compiled for central "
+ "function mode only");
+ }
+}
+
+void __init dc21285_postinit(void)
+{
+ register_isa_ports(DC21285_PCI_MEM, DC21285_PCI_IO, 0);
+}
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
new file mode 100644
index 00000000..e2e0df8b
--- /dev/null
+++ b/arch/arm/mach-footbridge/dma.c
@@ -0,0 +1,57 @@
+/*
+ * linux/arch/arm/kernel/dma-ebsa285.c
+ *
+ * Copyright (C) 1998 Phil Blundell
+ *
+ * DMA functions specific to EBSA-285/CATS architectures
+ *
+ * Changelog:
+ * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c
+ * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have
+ * ISA DMA controllers.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/dma.h>
+#include <asm/scatterlist.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/dec21285.h>
+
+#if 0
+static int fb_dma_request(unsigned int chan, dma_t *dma)
+{
+ return -EINVAL;
+}
+
+static void fb_dma_enable(unsigned int chan, dma_t *dma)
+{
+}
+
+static void fb_dma_disable(unsigned int chan, dma_t *dma)
+{
+}
+
+static struct dma_ops fb_dma_ops = {
+ .type = "fb",
+ .request = fb_dma_request,
+ .enable = fb_dma_enable,
+ .disable = fb_dma_disable,
+};
+#endif
+
+static int __init fb_dma_init(void)
+{
+#if 0
+ dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
+ dma[_DC21285_DMA(1)].d_ops = &fb_dma_ops;
+#endif
+#ifdef CONFIG_ISA_DMA
+ if (footbridge_cfn_mode())
+ isa_init_dma();
+#endif
+ return 0;
+}
+core_initcall(fb_dma_init);
diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c
new file mode 100644
index 00000000..4e10090c
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285-leds.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285-leds.c
+ *
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ * EBSA-285 control routines.
+ *
+ * The EBSA-285 uses the leds as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Amber - On if system is not idle
+ * - Red - currently unused
+ *
+ * Changelog:
+ * 02-05-1999 RMK Various cleanups
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+static char led_state;
+static char hw_led_state;
+
+static DEFINE_SPINLOCK(leds_lock);
+
+static void ebsa285_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN;
+#ifndef CONFIG_LEDS_CPU
+ hw_led_state |= XBUS_LED_AMBER;
+#endif
+ led_state |= LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= XBUS_LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= XBUS_LED_AMBER;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~XBUS_LED_AMBER;
+ break;
+#endif
+
+ case led_halted:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~XBUS_LED_RED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_AMBER;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_AMBER;
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~XBUS_LED_RED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= XBUS_LED_RED;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ *XBUS_LEDS = hw_led_state;
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_ebsa285())
+ leds_event = ebsa285_leds_event;
+
+ leds_event(led_start);
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c
new file mode 100644
index 00000000..e5ab5bdd
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285-pci.c
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
+
+static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+ switch (PCI_FUNC(dev->devfn)) {
+ case 1: return 14;
+ case 2: return 15;
+ case 3: return 12;
+ }
+
+ return irqmap_ebsa285[(slot + pin) & 3];
+}
+
+static struct hw_pci ebsa285_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .map_irq = ebsa285_map_irq,
+ .nr_controllers = 1,
+ .setup = dc21285_setup,
+ .scan = dc21285_scan_bus,
+ .preinit = dc21285_preinit,
+ .postinit = dc21285_postinit,
+};
+
+static int __init ebsa285_init_pci(void)
+{
+ if (machine_is_ebsa285())
+ pci_common_init(&ebsa285_pci);
+ return 0;
+}
+
+subsys_initcall(ebsa285_init_pci);
diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c
new file mode 100644
index 00000000..2ef69ff4
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285.c
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285.c
+ *
+ * EBSA285 machine fixup
+ */
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+MACHINE_START(EBSA285, "EBSA285")
+ /* Maintainer: Russell King */
+ .boot_params = 0x00000100,
+ .video_start = 0x000a0000,
+ .video_end = 0x000bffff,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .timer = &footbridge_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S
new file mode 100644
index 00000000..1be2eeb7
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S
@@ -0,0 +1,56 @@
+/* arch/arm/mach-footbridge/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <asm/hardware/dec21285.h>
+
+#ifndef CONFIG_DEBUG_DC21285_PORT
+ /* For NetWinder debugging */
+ .macro addruart, rp, rv
+ mov \rp, #0x000003f8
+ orr \rv, \rp, #0xff000000 @ virtual
+ orr \rp, \rp, #0x7c000000 @ physical
+ .endm
+
+#define UART_SHIFT 0
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
+
+#else
+#include <mach/hardware.h>
+ /* For EBSA285 debugging */
+ .equ dc21285_high, ARMCSR_BASE & 0xff000000
+ .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+ .macro addruart, rp, rv
+ .if dc21285_low
+ mov \rp, #dc21285_low
+ .else
+ mov \rp, #0
+ .endif
+ orr \rv, \rp, #dc21285_high
+ orr \rp, \rp, #0x42000000
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x160] @ UARTDR
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x178] @ UARTFLG
+ tst \rd, #1 << 3
+ bne 1001b
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+#endif
diff --git a/arch/arm/mach-footbridge/include/mach/entry-macro.S b/arch/arm/mach-footbridge/include/mach/entry-macro.S
new file mode 100644
index 00000000..d3847be0
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/entry-macro.S
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for footbridge-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/hardware/dec21285.h>
+
+ .equ dc21285_high, ARMCSR_BASE & 0xff000000
+ .equ dc21285_low, ARMCSR_BASE & 0x00ffffff
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mov \base, #dc21285_high
+ .if dc21285_low
+ orr \base, \base, #dc21285_low
+ .endif
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #0x180] @ get interrupts
+
+ mov \irqnr, #IRQ_SDRAMPARITY
+ tst \irqstat, #IRQ_MASK_SDRAMPARITY
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_UART_RX
+ movne \irqnr, #IRQ_CONRX
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DMA1
+ movne \irqnr, #IRQ_DMA1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DMA2
+ movne \irqnr, #IRQ_DMA2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN0
+ movne \irqnr, #IRQ_IN0
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN1
+ movne \irqnr, #IRQ_IN1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN2
+ movne \irqnr, #IRQ_IN2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_IN3
+ movne \irqnr, #IRQ_IN3
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI
+ movne \irqnr, #IRQ_PCI
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DOORBELLHOST
+ movne \irqnr, #IRQ_DOORBELLHOST
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_I2OINPOST
+ movne \irqnr, #IRQ_I2OINPOST
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER1
+ movne \irqnr, #IRQ_TIMER1
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER2
+ movne \irqnr, #IRQ_TIMER2
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_TIMER3
+ movne \irqnr, #IRQ_TIMER3
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_UART_TX
+ movne \irqnr, #IRQ_CONTX
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_ABORT
+ movne \irqnr, #IRQ_PCI_ABORT
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_SERR
+ movne \irqnr, #IRQ_PCI_SERR
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_DISCARD_TIMER
+ movne \irqnr, #IRQ_DISCARD_TIMER
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_DPERR
+ movne \irqnr, #IRQ_PCI_DPERR
+ bne 1001f
+
+ tst \irqstat, #IRQ_MASK_PCI_PERR
+ movne \irqnr, #IRQ_PCI_PERR
+1001:
+ .endm
+
diff --git a/arch/arm/mach-footbridge/include/mach/hardware.h b/arch/arm/mach-footbridge/include/mach/hardware.h
new file mode 100644
index 00000000..b6fdf23e
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/hardware.h
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/hardware.h
+ *
+ * Copyright (C) 1998-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the hardware definitions of the EBSA-285.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Virtual Physical Size
+ * 0xff800000 0x40000000 1MB X-Bus
+ * 0xff000000 0x7c000000 1MB PCI I/O space
+ * 0xfe000000 0x42000000 1MB CSR
+ * 0xfd000000 0x78000000 1MB Outbound write flush (not supported)
+ * 0xfc000000 0x79000000 1MB PCI IACK/special space
+ * 0xfb000000 0x7a000000 16MB PCI Config type 1
+ * 0xfa000000 0x7b000000 16MB PCI Config type 0
+ * 0xf9000000 0x50000000 1MB Cache flush
+ * 0xf0000000 0x80000000 16MB ISA memory
+ */
+
+#ifdef CONFIG_MMU
+#define MMU_IO(a, b) (a)
+#else
+#define MMU_IO(a, b) (b)
+#endif
+
+#define XBUS_SIZE 0x00100000
+#define XBUS_BASE MMU_IO(0xff800000, 0x40000000)
+
+#define ARMCSR_SIZE 0x00100000
+#define ARMCSR_BASE MMU_IO(0xfe000000, 0x42000000)
+
+#define WFLUSH_SIZE 0x00100000
+#define WFLUSH_BASE MMU_IO(0xfd000000, 0x78000000)
+
+#define PCIIACK_SIZE 0x00100000
+#define PCIIACK_BASE MMU_IO(0xfc000000, 0x79000000)
+
+#define PCICFG1_SIZE 0x01000000
+#define PCICFG1_BASE MMU_IO(0xfb000000, 0x7a000000)
+
+#define PCICFG0_SIZE 0x01000000
+#define PCICFG0_BASE MMU_IO(0xfa000000, 0x7b000000)
+
+#define PCIMEM_SIZE 0x01000000
+#define PCIMEM_BASE MMU_IO(0xf0000000, 0x80000000)
+
+#define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000))
+#define XBUS_LED_AMBER (1 << 0)
+#define XBUS_LED_GREEN (1 << 1)
+#define XBUS_LED_RED (1 << 2)
+#define XBUS_LED_TOGGLE (1 << 8)
+
+#define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000))
+#define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15)
+#define XBUS_SWITCH_J17_13 ((*XBUS_SWITCH) & (1 << 4))
+#define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5))
+#define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6))
+
+#define UNCACHEABLE_ADDR (ARMCSR_BASE + 0x108)
+
+
+/* PIC irq control */
+#define PIC_LO 0x20
+#define PIC_MASK_LO 0x21
+#define PIC_HI 0xA0
+#define PIC_MASK_HI 0xA1
+
+/* GPIO pins */
+#define GPIO_CCLK 0x800
+#define GPIO_DSCLK 0x400
+#define GPIO_E2CLK 0x200
+#define GPIO_IOLOAD 0x100
+#define GPIO_RED_LED 0x080
+#define GPIO_WDTIMER 0x040
+#define GPIO_DATA 0x020
+#define GPIO_IOCLK 0x010
+#define GPIO_DONE 0x008
+#define GPIO_FAN 0x004
+#define GPIO_GREEN_LED 0x002
+#define GPIO_RESET 0x001
+
+/* CPLD pins */
+#define CPLD_DS_ENABLE 8
+#define CPLD_7111_DISABLE 4
+#define CPLD_UNMUTE 2
+#define CPLD_FLASH_WR_ENABLE 1
+
+#ifndef __ASSEMBLY__
+extern spinlock_t nw_gpio_lock;
+extern void nw_gpio_modify_op(unsigned int mask, unsigned int set);
+extern void nw_gpio_modify_io(unsigned int mask, unsigned int in);
+extern unsigned int nw_gpio_read(void);
+extern void nw_cpld_modify(unsigned int mask, unsigned int set);
+#endif
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0x81000000
+
+#endif
diff --git a/arch/arm/mach-footbridge/include/mach/io.h b/arch/arm/mach-footbridge/include/mach/io.h
new file mode 100644
index 00000000..32e4cc39
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/io.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#ifdef CONFIG_MMU
+#define MMU_IO(a, b) (a)
+#else
+#define MMU_IO(a, b) (b)
+#endif
+
+#define PCIO_SIZE 0x00100000
+#define PCIO_BASE MMU_IO(0xff000000, 0x7c000000)
+
+#define IO_SPACE_LIMIT 0xffff
+
+/*
+ * Translation of various region addresses to virtual addresses
+ */
+#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
+#if 1
+#define __mem_pci(a) (a)
+#else
+
+static inline void __iomem *___mem_pci(void __iomem *p)
+{
+ unsigned long a = (unsigned long)p;
+ BUG_ON(a <= 0xc0000000 || a >= 0xe0000000);
+ return p;
+}
+
+#define __mem_pci(a) ___mem_pci(a)
+#endif
+
+#endif
diff --git a/arch/arm/mach-footbridge/include/mach/irqs.h b/arch/arm/mach-footbridge/include/mach/irqs.h
new file mode 100644
index 00000000..400551e4
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/irqs.h
@@ -0,0 +1,98 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/irqs.h
+ *
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Phil Blundell
+ *
+ * Changelog:
+ * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
+ * 01-Feb-1999 PJB ISA IRQs start at 0 not 16
+ */
+#include <asm/mach-types.h>
+
+#define NR_IRQS 36
+#define NR_DC21285_IRQS 16
+
+#define _ISA_IRQ(x) (0 + (x))
+#define _ISA_INR(x) ((x) - 0)
+#define _DC21285_IRQ(x) (16 + (x))
+#define _DC21285_INR(x) ((x) - 16)
+
+/*
+ * This is a list of all interrupts that the 21285
+ * can generate and we handle.
+ */
+#define IRQ_CONRX _DC21285_IRQ(0)
+#define IRQ_CONTX _DC21285_IRQ(1)
+#define IRQ_TIMER1 _DC21285_IRQ(2)
+#define IRQ_TIMER2 _DC21285_IRQ(3)
+#define IRQ_TIMER3 _DC21285_IRQ(4)
+#define IRQ_IN0 _DC21285_IRQ(5)
+#define IRQ_IN1 _DC21285_IRQ(6)
+#define IRQ_IN2 _DC21285_IRQ(7)
+#define IRQ_IN3 _DC21285_IRQ(8)
+#define IRQ_DOORBELLHOST _DC21285_IRQ(9)
+#define IRQ_DMA1 _DC21285_IRQ(10)
+#define IRQ_DMA2 _DC21285_IRQ(11)
+#define IRQ_PCI _DC21285_IRQ(12)
+#define IRQ_SDRAMPARITY _DC21285_IRQ(13)
+#define IRQ_I2OINPOST _DC21285_IRQ(14)
+#define IRQ_PCI_ABORT _DC21285_IRQ(15)
+#define IRQ_PCI_SERR _DC21285_IRQ(16)
+#define IRQ_DISCARD_TIMER _DC21285_IRQ(17)
+#define IRQ_PCI_DPERR _DC21285_IRQ(18)
+#define IRQ_PCI_PERR _DC21285_IRQ(19)
+
+#define IRQ_ISA_TIMER _ISA_IRQ(0)
+#define IRQ_ISA_KEYBOARD _ISA_IRQ(1)
+#define IRQ_ISA_CASCADE _ISA_IRQ(2)
+#define IRQ_ISA_UART2 _ISA_IRQ(3)
+#define IRQ_ISA_UART _ISA_IRQ(4)
+#define IRQ_ISA_FLOPPY _ISA_IRQ(6)
+#define IRQ_ISA_PRINTER _ISA_IRQ(7)
+#define IRQ_ISA_RTC_ALARM _ISA_IRQ(8)
+#define IRQ_ISA_2 _ISA_IRQ(9)
+#define IRQ_ISA_PS2MOUSE _ISA_IRQ(12)
+#define IRQ_ISA_HARDDISK1 _ISA_IRQ(14)
+#define IRQ_ISA_HARDDISK2 _ISA_IRQ(15)
+
+#define IRQ_MASK_UART_RX (1 << 2)
+#define IRQ_MASK_UART_TX (1 << 3)
+#define IRQ_MASK_TIMER1 (1 << 4)
+#define IRQ_MASK_TIMER2 (1 << 5)
+#define IRQ_MASK_TIMER3 (1 << 6)
+#define IRQ_MASK_IN0 (1 << 8)
+#define IRQ_MASK_IN1 (1 << 9)
+#define IRQ_MASK_IN2 (1 << 10)
+#define IRQ_MASK_IN3 (1 << 11)
+#define IRQ_MASK_DOORBELLHOST (1 << 15)
+#define IRQ_MASK_DMA1 (1 << 16)
+#define IRQ_MASK_DMA2 (1 << 17)
+#define IRQ_MASK_PCI (1 << 18)
+#define IRQ_MASK_SDRAMPARITY (1 << 24)
+#define IRQ_MASK_I2OINPOST (1 << 25)
+#define IRQ_MASK_PCI_ABORT ((1 << 29) | (1 << 30))
+#define IRQ_MASK_PCI_SERR (1 << 23)
+#define IRQ_MASK_DISCARD_TIMER (1 << 27)
+#define IRQ_MASK_PCI_DPERR (1 << 28)
+#define IRQ_MASK_PCI_PERR (1 << 31)
+
+/*
+ * Netwinder interrupt allocations
+ */
+#define IRQ_NETWINDER_ETHER10 IRQ_IN0
+#define IRQ_NETWINDER_ETHER100 IRQ_IN1
+#define IRQ_NETWINDER_VIDCOMP IRQ_IN2
+#define IRQ_NETWINDER_PS2MOUSE _ISA_IRQ(5)
+#define IRQ_NETWINDER_IR _ISA_IRQ(6)
+#define IRQ_NETWINDER_BUTTON _ISA_IRQ(10)
+#define IRQ_NETWINDER_VGA _ISA_IRQ(11)
+#define IRQ_NETWINDER_SOUND _ISA_IRQ(12)
+
+#undef RTC_IRQ
+#define RTC_IRQ IRQ_ISA_RTC_ALARM
+#define I8042_KBD_IRQ IRQ_ISA_KEYBOARD
+#define I8042_AUX_IRQ (machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE)
+#define IRQ_FLOPPYDISK IRQ_ISA_FLOPPY
+
+#define irq_canonicalize(_i) (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA_2 : _i)
diff --git a/arch/arm/mach-footbridge/include/mach/isa-dma.h b/arch/arm/mach-footbridge/include/mach/isa-dma.h
new file mode 100644
index 00000000..5bd4a0d3
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/isa-dma.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/isa-dma.h
+ *
+ * Architecture DMA routines
+ *
+ * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998,1999 Philip Blundell
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+/*
+ * The 21285 has two internal DMA channels; we call these 8 and 9.
+ * On CATS hardware we have an additional eight ISA dma channels
+ * numbered 0..7.
+ */
+#define _ISA_DMA(x) (0+(x))
+#define _DC21285_DMA(x) (8+(x))
+
+#define MAX_DMA_CHANNELS 10
+
+#define DMA_FLOPPY _ISA_DMA(2)
+#define DMA_ISA_CASCADE _ISA_DMA(4)
+
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h
new file mode 100644
index 00000000..5c6df377
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/memory.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/memory.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 20-Oct-1996 RMK Created
+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings.
+ * 17-May-1998 DAG Added __virt_to_bus and __bus_to_virt functions.
+ * 21-Nov-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros.
+ * 21-Mar-1999 RMK Added PAGE_OFFSET for co285 architecture.
+ * Renamed to memory.h
+ * Moved PAGE_OFFSET and TASK_SIZE here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+
+#if defined(CONFIG_FOOTBRIDGE_ADDIN)
+/*
+ * If we may be using add-in footbridge mode, then we must
+ * use the out-of-line translation that makes use of the
+ * PCI BAR
+ */
+#ifndef __ASSEMBLY__
+extern unsigned long __virt_to_bus(unsigned long);
+extern unsigned long __bus_to_virt(unsigned long);
+extern unsigned long __pfn_to_bus(unsigned long);
+extern unsigned long __bus_to_pfn(unsigned long);
+#endif
+#define __virt_to_bus __virt_to_bus
+#define __bus_to_virt __bus_to_virt
+
+#elif defined(CONFIG_FOOTBRIDGE_HOST)
+
+/*
+ * The footbridge is programmed to expose the system RAM at 0xe0000000.
+ * The requirement is that the RAM isn't placed at bus address 0, which
+ * would clash with VGA cards.
+ */
+#define BUS_OFFSET 0xe0000000
+#define __virt_to_bus(x) ((x) + (BUS_OFFSET - PAGE_OFFSET))
+#define __bus_to_virt(x) ((x) - (BUS_OFFSET - PAGE_OFFSET))
+#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
+#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
+
+#else
+
+#error "Undefined footbridge mode"
+
+#endif
+
+/*
+ * Cache flushing area.
+ */
+#define FLUSH_BASE 0xf9000000
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#define FLUSH_BASE_PHYS 0x50000000
+
+#endif
diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h
new file mode 100644
index 00000000..0b293156
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/system.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/system.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can 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 <asm/hardware/dec21285.h>
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (mode == 's') {
+ /*
+ * Jump into the ROM
+ */
+ cpu_reset(0x41000000);
+ } else {
+ if (machine_is_netwinder()) {
+ /* open up the SuperIO chip
+ */
+ outb(0x87, 0x370);
+ outb(0x87, 0x370);
+
+ /* aux function group 1 (logical device 7)
+ */
+ outb(0x07, 0x370);
+ outb(0x07, 0x371);
+
+ /* set GP16 for WD-TIMER output
+ */
+ outb(0xe6, 0x370);
+ outb(0x00, 0x371);
+
+ /* set a RED LED and toggle WD_TIMER for rebooting
+ */
+ outb(0xc4, 0x338);
+ } else {
+ /*
+ * Force the watchdog to do a CPU reset.
+ *
+ * After making sure that the watchdog is disabled
+ * (so we can change the timer registers) we first
+ * enable the timer to autoreload itself. Next, the
+ * timer interval is set really short and any
+ * current interrupt request is cleared (so we can
+ * see an edge transition). Finally, TIMER4 is
+ * enabled as the watchdog.
+ */
+ *CSR_SA110_CNTL &= ~(1 << 13);
+ *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
+ TIMER_CNTL_AUTORELOAD |
+ TIMER_CNTL_DIV16;
+ *CSR_TIMER4_LOAD = 0x2;
+ *CSR_TIMER4_CLR = 0;
+ *CSR_SA110_CNTL |= (1 << 13);
+ }
+ }
+}
diff --git a/arch/arm/mach-footbridge/include/mach/timex.h b/arch/arm/mach-footbridge/include/mach/timex.h
new file mode 100644
index 00000000..d0fea9d6
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/timex.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/timex.h
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * EBSA285 architecture timex specifications
+ */
+
+/*
+ * We assume a constant here; this satisfies the maths in linux/timex.h
+ * and linux/time.h. CLOCK_TICK_RATE is actually system dependent, but
+ * this must be a constant.
+ */
+#define CLOCK_TICK_RATE (50000000/16)
diff --git a/arch/arm/mach-footbridge/include/mach/uncompress.h b/arch/arm/mach-footbridge/include/mach/uncompress.h
new file mode 100644
index 00000000..5dfa4428
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/uncompress.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/uncompress.h
+ *
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/mach-types.h>
+
+/*
+ * Note! This could cause problems on the NetWinder
+ */
+#define DC21285_BASE ((volatile unsigned int *)0x42000160)
+#define SER0_BASE ((volatile unsigned char *)0x7c0003f8)
+
+static inline void putc(char c)
+{
+ if (machine_is_netwinder()) {
+ while ((SER0_BASE[5] & 0x60) != 0x60)
+ barrier();
+ SER0_BASE[0] = c;
+ } else {
+ while (DC21285_BASE[6] & 8);
+ DC21285_BASE[0] = c;
+ }
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-footbridge/include/mach/vmalloc.h b/arch/arm/mach-footbridge/include/mach/vmalloc.h
new file mode 100644
index 00000000..40ba78e5
--- /dev/null
+++ b/arch/arm/mach-footbridge/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-footbridge/include/mach/vmalloc.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
new file mode 100644
index 00000000..c3a0abbc
--- /dev/null
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -0,0 +1,183 @@
+/*
+ * linux/arch/arm/mach-footbridge/irq.c
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 22-Aug-1998 RMK Restructured IRQ routines
+ * 03-Sep-1998 PJB Merged CATS support
+ * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder
+ * 26-Jan-1999 PJB Don't use IACK on CATS
+ * 16-Mar-1999 RMK Added autodetect of ISA PICs
+ */
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/dec21285.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include "common.h"
+
+static void isa_mask_pic_lo_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+}
+
+static void isa_ack_pic_lo_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+ outb(0x20, PIC_LO);
+}
+
+static void isa_unmask_pic_lo_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
+}
+
+static struct irq_chip isa_lo_chip = {
+ .irq_ack = isa_ack_pic_lo_irq,
+ .irq_mask = isa_mask_pic_lo_irq,
+ .irq_unmask = isa_unmask_pic_lo_irq,
+};
+
+static void isa_mask_pic_hi_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+}
+
+static void isa_ack_pic_hi_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+ outb(0x62, PIC_LO);
+ outb(0x20, PIC_HI);
+}
+
+static void isa_unmask_pic_hi_irq(struct irq_data *d)
+{
+ unsigned int mask = 1 << (d->irq & 7);
+
+ outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
+}
+
+static struct irq_chip isa_hi_chip = {
+ .irq_ack = isa_ack_pic_hi_irq,
+ .irq_mask = isa_mask_pic_hi_irq,
+ .irq_unmask = isa_unmask_pic_hi_irq,
+};
+
+static void
+isa_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE;
+
+ if (isa_irq < _ISA_IRQ(0) || isa_irq >= _ISA_IRQ(16)) {
+ do_bad_IRQ(isa_irq, desc);
+ return;
+ }
+
+ generic_handle_irq(isa_irq);
+}
+
+static struct irqaction irq_cascade = {
+ .handler = no_action,
+ .name = "cascade",
+};
+
+static struct resource pic1_resource = {
+ .name = "pic1",
+ .start = 0x20,
+ .end = 0x3f,
+};
+
+static struct resource pic2_resource = {
+ .name = "pic2",
+ .start = 0xa0,
+ .end = 0xbf,
+};
+
+void __init isa_init_irq(unsigned int host_irq)
+{
+ unsigned int irq;
+
+ /*
+ * Setup, and then probe for an ISA PIC
+ * If the PIC is not there, then we
+ * ignore the PIC.
+ */
+ outb(0x11, PIC_LO);
+ outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */
+ outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */
+ outb(0x01, PIC_MASK_LO); /* x86 */
+ outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */
+
+ outb(0x11, PIC_HI);
+ outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */
+ outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */
+ outb(0x01, PIC_MASK_HI); /* x86 */
+ outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */
+
+ outb(0x0b, PIC_LO);
+ outb(0x0b, PIC_HI);
+
+ if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
+ outb(0xff, PIC_MASK_LO);/* mask all IRQs */
+ outb(0xff, PIC_MASK_HI);/* mask all IRQs */
+ } else {
+ printk(KERN_INFO "IRQ: ISA PIC not found\n");
+ host_irq = (unsigned int)-1;
+ }
+
+ if (host_irq != (unsigned int)-1) {
+ for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
+ irq_set_chip_and_handler(irq, &isa_lo_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
+ irq_set_chip_and_handler(irq, &isa_hi_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ request_resource(&ioport_resource, &pic1_resource);
+ request_resource(&ioport_resource, &pic2_resource);
+ setup_irq(IRQ_ISA_CASCADE, &irq_cascade);
+
+ irq_set_chained_handler(host_irq, isa_irq_handler);
+
+ /*
+ * On the NetWinder, don't automatically
+ * enable ISA IRQ11 when it is requested.
+ * There appears to be a missing pull-up
+ * resistor on this line.
+ */
+ if (machine_is_netwinder())
+ set_irq_flags(_ISA_IRQ(11), IRQF_VALID |
+ IRQF_PROBE | IRQF_NOAUTOEN);
+ }
+}
+
+
diff --git a/arch/arm/mach-footbridge/isa-rtc.c b/arch/arm/mach-footbridge/isa-rtc.c
new file mode 100644
index 00000000..07fde405
--- /dev/null
+++ b/arch/arm/mach-footbridge/isa-rtc.c
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-footbridge/isa-rtc.c
+ *
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
+ *
+ * CATS has a real-time clock, though the evaluation board doesn't.
+ *
+ * Changelog:
+ * 21-Mar-1998 RMK Created
+ * 27-Aug-1998 PJB CATS support
+ * 28-Dec-1998 APH Made leds optional
+ * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder
+ * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in
+ */
+
+#define RTC_PORT(x) (0x70+(x))
+#define RTC_ALWAYS_BCD 0
+
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+#include <linux/bcd.h>
+#include <linux/io.h>
+
+#include "common.h"
+
+void __init isa_rtc_init(void)
+{
+ int reg_d, reg_b;
+
+ /*
+ * Probe for the RTC.
+ */
+ reg_d = CMOS_READ(RTC_REG_D);
+
+ /*
+ * make sure the divider is set
+ */
+ CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
+
+ /*
+ * Set control reg B
+ * (24 hour mode, update enabled)
+ */
+ reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
+ reg_b |= 2;
+ CMOS_WRITE(reg_b, RTC_REG_B);
+
+ if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
+ CMOS_READ(RTC_REG_B) == reg_b) {
+ /*
+ * We have a RTC. Check the battery
+ */
+ if ((reg_d & 0x80) == 0)
+ printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
+ }
+}
diff --git a/arch/arm/mach-footbridge/isa-timer.c b/arch/arm/mach-footbridge/isa-timer.c
new file mode 100644
index 00000000..7020f1a3
--- /dev/null
+++ b/arch/arm/mach-footbridge/isa-timer.c
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/mach-footbridge/isa-timer.c
+ *
+ * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/timex.h>
+
+#include <asm/irq.h>
+#include <asm/i8253.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+DEFINE_RAW_SPINLOCK(i8253_lock);
+
+static void pit_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ outb_p(0x34, PIT_MODE);
+ outb_p(PIT_LATCH & 0xff, PIT_CH0);
+ outb_p(PIT_LATCH >> 8, PIT_CH0);
+ break;
+
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ outb_p(0x30, PIT_MODE);
+ outb_p(0, PIT_CH0);
+ outb_p(0, PIT_CH0);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+ local_irq_restore(flags);
+}
+
+static int pit_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ return 0;
+}
+
+static struct clock_event_device pit_ce = {
+ .name = "pit",
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = pit_set_mode,
+ .set_next_event = pit_set_next_event,
+ .shift = 32,
+};
+
+static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *ce = dev_id;
+ ce->event_handler(ce);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction pit_timer_irq = {
+ .name = "pit",
+ .handler = pit_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .dev_id = &pit_ce,
+};
+
+static void __init isa_timer_init(void)
+{
+ pit_ce.cpumask = cpumask_of(smp_processor_id());
+ pit_ce.mult = div_sc(PIT_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
+ pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
+ pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
+
+ clocksource_i8253_init();
+
+ setup_irq(pit_ce.irq, &pit_timer_irq);
+ clockevents_register_device(&pit_ce);
+}
+
+struct sys_timer isa_timer = {
+ .init = isa_timer_init,
+};
diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c
new file mode 100644
index 00000000..4d9276c2
--- /dev/null
+++ b/arch/arm/mach-footbridge/isa.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/mach-footbridge/isa.c
+ *
+ * Copyright (C) 2004 Russell King.
+ *
+ * This program is free software; you can 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/serial_8250.h>
+
+#include <asm/irq.h>
+#include <asm/hardware/dec21285.h>
+
+#include "common.h"
+
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0x70,
+ .end = 0x73,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = IRQ_ISA_RTC_ALARM,
+ .end = IRQ_ISA_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = rtc_resources,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+};
+
+static struct resource serial_resources[] = {
+ [0] = {
+ .start = 0x3f8,
+ .end = 0x3ff,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = 0x2f8,
+ .end = 0x2ff,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .iobase = 0x3f8,
+ .irq = IRQ_ISA_UART,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ {
+ .iobase = 0x2f8,
+ .irq = IRQ_ISA_UART2,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .resource = serial_resources,
+ .num_resources = ARRAY_SIZE(serial_resources),
+};
+
+static int __init footbridge_isa_init(void)
+{
+ int err = 0;
+
+ if (!footbridge_cfn_mode())
+ return 0;
+
+ /* Personal server doesn't have RTC */
+ if (!machine_is_personal_server()) {
+ isa_rtc_init();
+ err = platform_device_register(&rtc_device);
+ if (err)
+ printk(KERN_ERR "Unable to register RTC device: %d\n", err);
+ }
+ err = platform_device_register(&serial_device);
+ if (err)
+ printk(KERN_ERR "Unable to register serial device: %d\n", err);
+ return 0;
+}
+
+arch_initcall(footbridge_isa_init);
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
new file mode 100644
index 00000000..06e514f3
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -0,0 +1,660 @@
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-hw.c
+ *
+ * Netwinder machine fixup
+ *
+ * Copyright (C) 1998, 1999 Russell King, Phil Blundell
+ */
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+#define IRDA_IO_BASE 0x180
+#define GP1_IO_BASE 0x338
+#define GP2_IO_BASE 0x33a
+
+
+#ifdef CONFIG_LEDS
+#define DEFAULT_LEDS 0
+#else
+#define DEFAULT_LEDS GPIO_GREEN_LED
+#endif
+
+/*
+ * Winbond WB83977F accessibility stuff
+ */
+static inline void wb977_open(void)
+{
+ outb(0x87, 0x370);
+ outb(0x87, 0x370);
+}
+
+static inline void wb977_close(void)
+{
+ outb(0xaa, 0x370);
+}
+
+static inline void wb977_wb(int reg, int val)
+{
+ outb(reg, 0x370);
+ outb(val, 0x371);
+}
+
+static inline void wb977_ww(int reg, int val)
+{
+ outb(reg, 0x370);
+ outb(val >> 8, 0x371);
+ outb(reg + 1, 0x370);
+ outb(val & 255, 0x371);
+}
+
+#define wb977_device_select(dev) wb977_wb(0x07, dev)
+#define wb977_device_disable() wb977_wb(0x30, 0x00)
+#define wb977_device_enable() wb977_wb(0x30, 0x01)
+
+/*
+ * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE
+ */
+DEFINE_SPINLOCK(nw_gpio_lock);
+EXPORT_SYMBOL(nw_gpio_lock);
+
+static unsigned int current_gpio_op;
+static unsigned int current_gpio_io;
+static unsigned int current_cpld;
+
+void nw_gpio_modify_op(unsigned int mask, unsigned int set)
+{
+ unsigned int new_gpio, changed;
+
+ new_gpio = (current_gpio_op & ~mask) | set;
+ changed = new_gpio ^ current_gpio_op;
+ current_gpio_op = new_gpio;
+
+ if (changed & 0xff)
+ outb(new_gpio, GP1_IO_BASE);
+ if (changed & 0xff00)
+ outb(new_gpio >> 8, GP2_IO_BASE);
+}
+EXPORT_SYMBOL(nw_gpio_modify_op);
+
+static inline void __gpio_modify_io(int mask, int in)
+{
+ unsigned int new_gpio, changed;
+ int port;
+
+ new_gpio = (current_gpio_io & ~mask) | in;
+ changed = new_gpio ^ current_gpio_io;
+ current_gpio_io = new_gpio;
+
+ changed >>= 1;
+ new_gpio >>= 1;
+
+ wb977_device_select(7);
+
+ for (port = 0xe1; changed && port < 0xe8; changed >>= 1) {
+ wb977_wb(port, new_gpio & 1);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+
+ wb977_device_select(8);
+
+ for (port = 0xe8; changed && port < 0xec; changed >>= 1) {
+ wb977_wb(port, new_gpio & 1);
+
+ port += 1;
+ new_gpio >>= 1;
+ }
+}
+
+void nw_gpio_modify_io(unsigned int mask, unsigned int in)
+{
+ /* Open up the SuperIO chip */
+ wb977_open();
+
+ __gpio_modify_io(mask, in);
+
+ /* Close up the EFER gate */
+ wb977_close();
+}
+EXPORT_SYMBOL(nw_gpio_modify_io);
+
+unsigned int nw_gpio_read(void)
+{
+ return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8;
+}
+EXPORT_SYMBOL(nw_gpio_read);
+
+/*
+ * Initialise the Winbond W83977F global registers
+ */
+static inline void wb977_init_global(void)
+{
+ /*
+ * Enable R/W config registers
+ */
+ wb977_wb(0x26, 0x40);
+
+ /*
+ * Power down FDC (not used)
+ */
+ wb977_wb(0x22, 0xfe);
+
+ /*
+ * GP12, GP11, CIRRX, IRRXH, GP10
+ */
+ wb977_wb(0x2a, 0xc1);
+
+ /*
+ * GP23, GP22, GP21, GP20, GP13
+ */
+ wb977_wb(0x2b, 0x6b);
+
+ /*
+ * GP17, GP16, GP15, GP14
+ */
+ wb977_wb(0x2c, 0x55);
+}
+
+/*
+ * Initialise the Winbond W83977F printer port
+ */
+static inline void wb977_init_printer(void)
+{
+ wb977_device_select(1);
+
+ /*
+ * mode 1 == EPP
+ */
+ wb977_wb(0xf0, 0x01);
+}
+
+/*
+ * Initialise the Winbond W83977F keyboard controller
+ */
+static inline void wb977_init_keyboard(void)
+{
+ wb977_device_select(5);
+
+ /*
+ * Keyboard controller address
+ */
+ wb977_ww(0x60, 0x0060);
+ wb977_ww(0x62, 0x0064);
+
+ /*
+ * Keyboard IRQ 1, active high, edge trigger
+ */
+ wb977_wb(0x70, 1);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * Mouse IRQ 5, active high, edge trigger
+ */
+ wb977_wb(0x72, 5);
+ wb977_wb(0x73, 0x02);
+
+ /*
+ * KBC 8MHz
+ */
+ wb977_wb(0xf0, 0x40);
+
+ /*
+ * Enable device
+ */
+ wb977_device_enable();
+}
+
+/*
+ * Initialise the Winbond W83977F Infra-Red device
+ */
+static inline void wb977_init_irda(void)
+{
+ wb977_device_select(6);
+
+ /*
+ * IR base address
+ */
+ wb977_ww(0x60, IRDA_IO_BASE);
+
+ /*
+ * IRDA IRQ 6, active high, edge trigger
+ */
+ wb977_wb(0x70, 6);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * RX DMA - ISA DMA 0
+ */
+ wb977_wb(0x74, 0x00);
+
+ /*
+ * TX DMA - Disable Tx DMA
+ */
+ wb977_wb(0x75, 0x04);
+
+ /*
+ * Append CRC, Enable bank selection
+ */
+ wb977_wb(0xf0, 0x03);
+
+ /*
+ * Enable device
+ */
+ wb977_device_enable();
+}
+
+/*
+ * Initialise Winbond W83977F general purpose IO
+ */
+static inline void wb977_init_gpio(void)
+{
+ unsigned long flags;
+
+ /*
+ * Set up initial I/O definitions
+ */
+ current_gpio_io = -1;
+ __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER);
+
+ wb977_device_select(7);
+
+ /*
+ * Group1 base address
+ */
+ wb977_ww(0x60, GP1_IO_BASE);
+ wb977_ww(0x62, 0);
+ wb977_ww(0x64, 0);
+
+ /*
+ * GP10 (Orage button) IRQ 10, active high, edge trigger
+ */
+ wb977_wb(0x70, 10);
+ wb977_wb(0x71, 0x02);
+
+ /*
+ * GP10: Debounce filter enabled, IRQ, input
+ */
+ wb977_wb(0xe0, 0x19);
+
+ /*
+ * Enable Group1
+ */
+ wb977_device_enable();
+
+ wb977_device_select(8);
+
+ /*
+ * Group2 base address
+ */
+ wb977_ww(0x60, GP2_IO_BASE);
+
+ /*
+ * Clear watchdog timer regs
+ * - timer disable
+ */
+ wb977_wb(0xf2, 0x00);
+
+ /*
+ * - disable LED, no mouse nor keyboard IRQ
+ */
+ wb977_wb(0xf3, 0x00);
+
+ /*
+ * - timer counting, disable power LED, disable timeouot
+ */
+ wb977_wb(0xf4, 0x00);
+
+ /*
+ * Enable group2
+ */
+ wb977_device_enable();
+
+ /*
+ * Set Group1/Group2 outputs
+ */
+ spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN);
+ spin_unlock_irqrestore(&nw_gpio_lock, flags);
+}
+
+/*
+ * Initialise the Winbond W83977F chip.
+ */
+static void __init wb977_init(void)
+{
+ request_region(0x370, 2, "W83977AF configuration");
+
+ /*
+ * Open up the SuperIO chip
+ */
+ wb977_open();
+
+ /*
+ * Initialise the global registers
+ */
+ wb977_init_global();
+
+ /*
+ * Initialise the various devices in
+ * the multi-IO chip.
+ */
+ wb977_init_printer();
+ wb977_init_keyboard();
+ wb977_init_irda();
+ wb977_init_gpio();
+
+ /*
+ * Close up the EFER gate
+ */
+ wb977_close();
+}
+
+void nw_cpld_modify(unsigned int mask, unsigned int set)
+{
+ int msk;
+
+ current_cpld = (current_cpld & ~mask) | set;
+
+ nw_gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0);
+ nw_gpio_modify_op(GPIO_IOLOAD, 0);
+
+ for (msk = 8; msk; msk >>= 1) {
+ int bit = current_cpld & msk;
+
+ nw_gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0);
+ nw_gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK);
+ }
+
+ nw_gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0);
+ nw_gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK);
+ nw_gpio_modify_op(GPIO_IOLOAD, 0);
+}
+EXPORT_SYMBOL(nw_cpld_modify);
+
+static void __init cpld_init(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE);
+ spin_unlock_irqrestore(&nw_gpio_lock, flags);
+}
+
+static unsigned char rwa_unlock[] __initdata =
+{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b,
+ 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74,
+ 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 };
+
+#ifndef DEBUG
+#define dprintk(x...)
+#else
+#define dprintk(x...) printk(x)
+#endif
+
+#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0)
+
+static inline void rwa010_unlock(void)
+{
+ int i;
+
+ WRITE_RWA(2, 2);
+ mdelay(10);
+
+ for (i = 0; i < sizeof(rwa_unlock); i++) {
+ outb(rwa_unlock[i], 0x279);
+ udelay(10);
+ }
+}
+
+static inline void rwa010_read_ident(void)
+{
+ unsigned char si[9];
+ int i, j;
+
+ WRITE_RWA(3, 0);
+ WRITE_RWA(0, 128);
+
+ outb(1, 0x279);
+
+ mdelay(1);
+
+ dprintk("Identifier: ");
+ for (i = 0; i < 9; i++) {
+ si[i] = 0;
+ for (j = 0; j < 8; j++) {
+ int bit;
+ udelay(250);
+ inb(0x203);
+ udelay(250);
+ bit = inb(0x203);
+ dprintk("%02X ", bit);
+ bit = (bit == 0xaa) ? 1 : 0;
+ si[i] |= bit << j;
+ }
+ dprintk("(%02X) ", si[i]);
+ }
+ dprintk("\n");
+}
+
+static inline void rwa010_global_init(void)
+{
+ WRITE_RWA(6, 2); // Assign a card no = 2
+
+ dprintk("Card no = %d\n", inb(0x203));
+
+ /* disable the modem section of the chip */
+ WRITE_RWA(7, 3);
+ WRITE_RWA(0x30, 0);
+
+ /* disable the cdrom section of the chip */
+ WRITE_RWA(7, 4);
+ WRITE_RWA(0x30, 0);
+
+ /* disable the MPU-401 section of the chip */
+ WRITE_RWA(7, 2);
+ WRITE_RWA(0x30, 0);
+}
+
+static inline void rwa010_game_port_init(void)
+{
+ int i;
+
+ WRITE_RWA(7, 5);
+
+ dprintk("Slider base: ");
+ WRITE_RWA(0x61, 1);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, 2);
+ dprintk("%02X%02X (201)\n", inb(0x203), i);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static inline void rwa010_waveartist_init(int base, int irq, int dma)
+{
+ int i;
+
+ WRITE_RWA(7, 0);
+
+ dprintk("WaveArtist base: ");
+ WRITE_RWA(0x61, base & 255);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, base >> 8);
+ dprintk("%02X%02X (%X),", inb(0x203), i, base);
+
+ WRITE_RWA(0x70, irq);
+ dprintk(" irq: %d (%d),", inb(0x203), irq);
+
+ WRITE_RWA(0x74, dma);
+ dprintk(" dma: %d (%d)\n", inb(0x203), dma);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma)
+{
+ int i;
+
+ WRITE_RWA(7, 1);
+
+ dprintk("SoundBlaster base: ");
+ WRITE_RWA(0x61, sb_base & 255);
+ i = inb(0x203);
+
+ WRITE_RWA(0x60, sb_base >> 8);
+ dprintk("%02X%02X (%X),", inb(0x203), i, sb_base);
+
+ dprintk(" irq: ");
+ WRITE_RWA(0x70, irq);
+ dprintk("%d (%d),", inb(0x203), irq);
+
+ dprintk(" 8-bit DMA: ");
+ WRITE_RWA(0x74, dma);
+ dprintk("%d (%d)\n", inb(0x203), dma);
+
+ dprintk("AdLib base: ");
+ WRITE_RWA(0x63, al_base & 255);
+ i = inb(0x203);
+
+ WRITE_RWA(0x62, al_base >> 8);
+ dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base);
+
+ WRITE_RWA(0x30, 1);
+}
+
+static void rwa010_soundblaster_reset(void)
+{
+ int i;
+
+ outb(1, 0x226);
+ udelay(3);
+ outb(0, 0x226);
+
+ for (i = 0; i < 5; i++) {
+ if (inb(0x22e) & 0x80)
+ break;
+ mdelay(1);
+ }
+ if (i == 5)
+ printk("SoundBlaster: DSP reset failed\n");
+
+ dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a));
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: DSP not ready\n");
+ else {
+ outb(0xe1, 0x22c);
+
+ dprintk("SoundBlaster DSP id: ");
+ i = inb(0x22a);
+ udelay(1);
+ i |= inb(0x22a) << 8;
+ dprintk("%04X\n", i);
+
+ for (i = 0; i < 5; i++) {
+ if ((inb(0x22c) & 0x80) == 0)
+ break;
+ mdelay(1);
+ }
+
+ if (i == 5)
+ printk("SoundBlaster: could not turn speaker off\n");
+
+ outb(0xd3, 0x22c);
+ }
+
+ /* turn on OPL3 */
+ outb(5, 0x38a);
+ outb(1, 0x38b);
+}
+
+static void __init rwa010_init(void)
+{
+ rwa010_unlock();
+ rwa010_read_ident();
+ rwa010_global_init();
+ rwa010_game_port_init();
+ rwa010_waveartist_init(0x250, 3, 7);
+ rwa010_soundblaster_init(0x220, 0x388, 3, 1);
+ rwa010_soundblaster_reset();
+}
+
+/*
+ * Initialise any other hardware after we've got the PCI bus
+ * initialised. We may need the PCI bus to talk to this other
+ * hardware.
+ */
+static int __init nw_hw_init(void)
+{
+ if (machine_is_netwinder()) {
+ unsigned long flags;
+
+ wb977_init();
+ cpld_init();
+ rwa010_init();
+
+ spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
+ spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ }
+ return 0;
+}
+
+__initcall(nw_hw_init);
+
+/*
+ * Older NeTTroms either do not provide a parameters
+ * page, or they don't supply correct information in
+ * the parameter page.
+ */
+static void __init
+fixup_netwinder(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_ISAPNP
+ extern int isapnp_disable;
+
+ /*
+ * We must not use the kernels ISAPnP code
+ * on the NetWinder - it will reset the settings
+ * for the WaveArtist chip and render it inoperable.
+ */
+ isapnp_disable = 1;
+#endif
+}
+
+MACHINE_START(NETWINDER, "Rebel-NetWinder")
+ /* Maintainer: Russell King/Rebel.com */
+ .boot_params = 0x00000100,
+ .video_start = 0x000a0000,
+ .video_end = 0x000bffff,
+ .reserve_lp0 = 1,
+ .reserve_lp2 = 1,
+ .fixup = fixup_netwinder,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .timer = &isa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c
new file mode 100644
index 00000000..00269fe0
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-leds.c
@@ -0,0 +1,139 @@
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-leds.c
+ *
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * NetWinder LED control routines.
+ *
+ * The Netwinder uses the leds as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Red - On if the system is not idle
+ *
+ * Changelog:
+ * 02-05-1999 RMK Various cleanups
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+static char led_state;
+static char hw_led_state;
+
+static DEFINE_SPINLOCK(leds_lock);
+
+static void netwinder_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch (evt) {
+ case led_start:
+ led_state |= LED_STATE_ENABLED;
+ hw_led_state = GPIO_GREEN_LED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= GPIO_GREEN_LED;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+#endif
+
+ case led_halted:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_GREEN_LED;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ default:
+ break;
+ }
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+
+ if (led_state & LED_STATE_ENABLED) {
+ spin_lock_irqsave(&nw_gpio_lock, flags);
+ nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
+ spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ }
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_netwinder())
+ leds_event = netwinder_leds_event;
+
+ leds_event(led_start);
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c
new file mode 100644
index 00000000..e263d6d5
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-pci.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * We now use the slot ID instead of the device identifiers to select
+ * which interrupt is routed where.
+ */
+static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch (slot) {
+ case 0: /* host bridge */
+ return 0;
+
+ case 9: /* CyberPro */
+ return IRQ_NETWINDER_VGA;
+
+ case 10: /* DC21143 */
+ return IRQ_NETWINDER_ETHER100;
+
+ case 12: /* Winbond 553 */
+ return IRQ_ISA_HARDDISK1;
+
+ case 13: /* Winbond 89C940F */
+ return IRQ_NETWINDER_ETHER10;
+
+ default:
+ printk(KERN_ERR "PCI: unknown device in slot %s\n",
+ pci_name(dev));
+ return 0;
+ }
+}
+
+static struct hw_pci netwinder_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .map_irq = netwinder_map_irq,
+ .nr_controllers = 1,
+ .setup = dc21285_setup,
+ .scan = dc21285_scan_bus,
+ .preinit = dc21285_preinit,
+ .postinit = dc21285_postinit,
+};
+
+static int __init netwinder_pci_init(void)
+{
+ if (machine_is_netwinder())
+ pci_common_init(&netwinder_pci);
+ return 0;
+}
+
+subsys_initcall(netwinder_pci_init);
diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c
new file mode 100644
index 00000000..d5fca95a
--- /dev/null
+++ b/arch/arm/mach-footbridge/personal-pci.c
@@ -0,0 +1,56 @@
+/*
+ * linux/arch/arm/mach-footbridge/personal-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+static int irqmap_personal_server[] __initdata = {
+ IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
+ IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
+};
+
+static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char line;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+
+ if (line > 0x40 && line <= 0x5f) {
+ /* line corresponds to the bit controlling this interrupt
+ * in the footbridge. Ignore the first 8 interrupt bits,
+ * look up the rest in the map. IN0 is bit number 8
+ */
+ return irqmap_personal_server[(line & 0x1f) - 8];
+ } else if (line == 0) {
+ /* no interrupt */
+ return 0;
+ } else
+ return irqmap_personal_server[(line - 1) & 3];
+}
+
+static struct hw_pci personal_server_pci __initdata = {
+ .map_irq = personal_server_map_irq,
+ .nr_controllers = 1,
+ .setup = dc21285_setup,
+ .scan = dc21285_scan_bus,
+ .preinit = dc21285_preinit,
+ .postinit = dc21285_postinit,
+};
+
+static int __init personal_pci_init(void)
+{
+ if (machine_is_personal_server())
+ pci_common_init(&personal_server_pci);
+ return 0;
+}
+
+subsys_initcall(personal_pci_init);
diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c
new file mode 100644
index 00000000..3285e91c
--- /dev/null
+++ b/arch/arm/mach-footbridge/personal.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-footbridge/personal.c
+ *
+ * Personal server (Skiff) machine fixup
+ */
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include "common.h"
+
+MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
+ /* Maintainer: Jamey Hicks / George France */
+ .boot_params = 0x00000100,
+ .map_io = footbridge_map_io,
+ .init_irq = footbridge_init_irq,
+ .timer = &footbridge_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-gemini/Kconfig b/arch/arm/mach-gemini/Kconfig
new file mode 100644
index 00000000..6f066ee4
--- /dev/null
+++ b/arch/arm/mach-gemini/Kconfig
@@ -0,0 +1,40 @@
+if ARCH_GEMINI
+
+menu "Cortina Systems Gemini Implementations"
+
+config MACH_NAS4220B
+ bool "Raidsonic NAS-4220-B"
+ select GEMINI_MEM_SWAP
+ help
+ Say Y here if you intend to run this kernel on a
+ Raidsonic NAS-4220-B.
+
+config MACH_RUT100
+ bool "Teltonika RUT100"
+ select GEMINI_MEM_SWAP
+ help
+ Say Y here if you intend to run this kernel on a
+ Teltonika 3G Router RUT100.
+
+config MACH_WBD111
+ bool "Wiliboard WBD-111"
+ select GEMINI_MEM_SWAP
+ help
+ Say Y here if you intend to run this kernel on a
+ Wiliboard WBD-111.
+
+config MACH_WBD222
+ bool "Wiliboard WBD-222"
+ select GEMINI_MEM_SWAP
+ help
+ Say Y here if you intend to run this kernel on a
+ Wiliboard WBD-222.
+
+endmenu
+
+config GEMINI_MEM_SWAP
+ bool "Gemini memory is swapped"
+ help
+ Say Y here if Gemini memory is swapped by bootloader.
+
+endif
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile
new file mode 100644
index 00000000..c5b24b95
--- /dev/null
+++ b/arch/arm/mach-gemini/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := irq.o mm.o time.o devices.o gpio.o
+
+# Board-specific support
+obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o
+obj-$(CONFIG_MACH_RUT100) += board-rut1xx.o
+obj-$(CONFIG_MACH_WBD111) += board-wbd111.o
+obj-$(CONFIG_MACH_WBD222) += board-wbd222.o
diff --git a/arch/arm/mach-gemini/Makefile.boot b/arch/arm/mach-gemini/Makefile.boot
new file mode 100644
index 00000000..22a52c22
--- /dev/null
+++ b/arch/arm/mach-gemini/Makefile.boot
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_GEMINI_MEM_SWAP),y)
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+else
+ zreladdr-y := 0x10008000
+params_phys-y := 0x10000100
+initrd_phys-y := 0x10800000
+endif
diff --git a/arch/arm/mach-gemini/board-nas4220b.c b/arch/arm/mach-gemini/board-nas4220b.c
new file mode 100644
index 00000000..0cf7a07c
--- /dev/null
+++ b/arch/arm/mach-gemini/board-nas4220b.c
@@ -0,0 +1,110 @@
+/*
+ * Support for Raidsonic NAS-4220-B
+ *
+ * Copyright (C) 2009 Janos Laube <janos.dev@gmail.com>
+ *
+ * based on rut1xx.c
+ * Copyright (C) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/mdio-gpio.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+#include "common.h"
+
+static struct sys_timer ib4220b_timer = {
+ .init = gemini_timer_init,
+};
+
+static struct gpio_led ib4220b_leds[] = {
+ {
+ .name = "nas4220b:orange:hdd",
+ .default_trigger = "none",
+ .gpio = 60,
+ },
+ {
+ .name = "nas4220b:green:os",
+ .default_trigger = "heartbeat",
+ .gpio = 62,
+ },
+};
+
+static struct gpio_led_platform_data ib4220b_leds_data = {
+ .num_leds = ARRAY_SIZE(ib4220b_leds),
+ .leds = ib4220b_leds,
+};
+
+static struct platform_device ib4220b_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ib4220b_leds_data,
+ },
+};
+
+static struct gpio_keys_button ib4220b_keys[] = {
+ {
+ .code = KEY_SETUP,
+ .gpio = 61,
+ .active_low = 1,
+ .desc = "Backup Button",
+ .type = EV_KEY,
+ },
+ {
+ .code = KEY_RESTART,
+ .gpio = 63,
+ .active_low = 1,
+ .desc = "Softreset Button",
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data ib4220b_keys_data = {
+ .buttons = ib4220b_keys,
+ .nbuttons = ARRAY_SIZE(ib4220b_keys),
+};
+
+static struct platform_device ib4220b_key_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &ib4220b_keys_data,
+ },
+};
+
+static void __init ib4220b_init(void)
+{
+ gemini_gpio_init();
+ platform_register_uart();
+ platform_register_pflash(SZ_16M, NULL, 0);
+ platform_device_register(&ib4220b_led_device);
+ platform_device_register(&ib4220b_key_device);
+ platform_register_rtc();
+}
+
+MACHINE_START(NAS4220B, "Raidsonic NAS IB-4220-B")
+ .boot_params = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .timer = &ib4220b_timer,
+ .init_machine = ib4220b_init,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/board-rut1xx.c b/arch/arm/mach-gemini/board-rut1xx.c
new file mode 100644
index 00000000..4fa09af9
--- /dev/null
+++ b/arch/arm/mach-gemini/board-rut1xx.c
@@ -0,0 +1,94 @@
+/*
+ * Support for Teltonika RUT1xx
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "common.h"
+
+static struct gpio_keys_button rut1xx_keys[] = {
+ {
+ .code = KEY_SETUP,
+ .gpio = 60,
+ .active_low = 1,
+ .desc = "Reset to defaults",
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data rut1xx_keys_data = {
+ .buttons = rut1xx_keys,
+ .nbuttons = ARRAY_SIZE(rut1xx_keys),
+};
+
+static struct platform_device rut1xx_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &rut1xx_keys_data,
+ },
+};
+
+static struct gpio_led rut100_leds[] = {
+ {
+ .name = "Power",
+ .default_trigger = "heartbeat",
+ .gpio = 17,
+ },
+ {
+ .name = "GSM",
+ .default_trigger = "default-on",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data rut100_leds_data = {
+ .num_leds = ARRAY_SIZE(rut100_leds),
+ .leds = rut100_leds,
+};
+
+static struct platform_device rut1xx_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rut100_leds_data,
+ },
+};
+
+static struct sys_timer rut1xx_timer = {
+ .init = gemini_timer_init,
+};
+
+static void __init rut1xx_init(void)
+{
+ gemini_gpio_init();
+ platform_register_uart();
+ platform_register_pflash(SZ_8M, NULL, 0);
+ platform_device_register(&rut1xx_leds);
+ platform_device_register(&rut1xx_keys_device);
+ platform_register_rtc();
+}
+
+MACHINE_START(RUT100, "Teltonika RUT100")
+ .boot_params = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .timer = &rut1xx_timer,
+ .init_machine = rut1xx_init,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/board-wbd111.c b/arch/arm/mach-gemini/board-wbd111.c
new file mode 100644
index 00000000..88cc422e
--- /dev/null
+++ b/arch/arm/mach-gemini/board-wbd111.c
@@ -0,0 +1,137 @@
+/*
+ * Support for Wiliboard WBD-111
+ *
+ * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/skbuff.h>
+#include <linux/gpio_keys.h>
+#include <linux/mdio-gpio.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+
+#include "common.h"
+
+static struct gpio_keys_button wbd111_keys[] = {
+ {
+ .code = KEY_SETUP,
+ .gpio = 5,
+ .active_low = 1,
+ .desc = "reset",
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data wbd111_keys_data = {
+ .buttons = wbd111_keys,
+ .nbuttons = ARRAY_SIZE(wbd111_keys),
+};
+
+static struct platform_device wbd111_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &wbd111_keys_data,
+ },
+};
+
+static struct gpio_led wbd111_leds[] = {
+ {
+ .name = "L3red",
+ .gpio = 1,
+ },
+ {
+ .name = "L4green",
+ .gpio = 2,
+ },
+ {
+ .name = "L4red",
+ .gpio = 3,
+ },
+ {
+ .name = "L3green",
+ .gpio = 5,
+ },
+};
+
+static struct gpio_led_platform_data wbd111_leds_data = {
+ .num_leds = ARRAY_SIZE(wbd111_leds),
+ .leds = wbd111_leds,
+};
+
+static struct platform_device wbd111_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wbd111_leds_data,
+ },
+};
+
+static struct sys_timer wbd111_timer = {
+ .init = gemini_timer_init,
+};
+
+static struct mtd_partition wbd111_partitions[] = {
+ {
+ .name = "RedBoot",
+ .offset = 0,
+ .size = 0x020000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "kernel",
+ .offset = 0x020000,
+ .size = 0x100000,
+ } , {
+ .name = "rootfs",
+ .offset = 0x120000,
+ .size = 0x6a0000,
+ } , {
+ .name = "VCTL",
+ .offset = 0x7c0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "cfg",
+ .offset = 0x7d0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "FIS",
+ .offset = 0x7e0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }
+};
+#define wbd111_num_partitions ARRAY_SIZE(wbd111_partitions)
+
+static void __init wbd111_init(void)
+{
+ gemini_gpio_init();
+ platform_register_uart();
+ platform_register_pflash(SZ_8M, wbd111_partitions,
+ wbd111_num_partitions);
+ platform_device_register(&wbd111_leds_device);
+ platform_device_register(&wbd111_keys_device);
+ platform_register_rtc();
+}
+
+MACHINE_START(WBD111, "Wiliboard WBD-111")
+ .boot_params = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .timer = &wbd111_timer,
+ .init_machine = wbd111_init,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/board-wbd222.c b/arch/arm/mach-gemini/board-wbd222.c
new file mode 100644
index 00000000..3a220347
--- /dev/null
+++ b/arch/arm/mach-gemini/board-wbd222.c
@@ -0,0 +1,137 @@
+/*
+ * Support for Wiliboard WBD-222
+ *
+ * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/skbuff.h>
+#include <linux/gpio_keys.h>
+#include <linux/mdio-gpio.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+
+#include "common.h"
+
+static struct gpio_keys_button wbd222_keys[] = {
+ {
+ .code = KEY_SETUP,
+ .gpio = 5,
+ .active_low = 1,
+ .desc = "reset",
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data wbd222_keys_data = {
+ .buttons = wbd222_keys,
+ .nbuttons = ARRAY_SIZE(wbd222_keys),
+};
+
+static struct platform_device wbd222_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &wbd222_keys_data,
+ },
+};
+
+static struct gpio_led wbd222_leds[] = {
+ {
+ .name = "L3red",
+ .gpio = 1,
+ },
+ {
+ .name = "L4green",
+ .gpio = 2,
+ },
+ {
+ .name = "L4red",
+ .gpio = 3,
+ },
+ {
+ .name = "L3green",
+ .gpio = 5,
+ },
+};
+
+static struct gpio_led_platform_data wbd222_leds_data = {
+ .num_leds = ARRAY_SIZE(wbd222_leds),
+ .leds = wbd222_leds,
+};
+
+static struct platform_device wbd222_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wbd222_leds_data,
+ },
+};
+
+static struct sys_timer wbd222_timer = {
+ .init = gemini_timer_init,
+};
+
+static struct mtd_partition wbd222_partitions[] = {
+ {
+ .name = "RedBoot",
+ .offset = 0,
+ .size = 0x020000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "kernel",
+ .offset = 0x020000,
+ .size = 0x100000,
+ } , {
+ .name = "rootfs",
+ .offset = 0x120000,
+ .size = 0x6a0000,
+ } , {
+ .name = "VCTL",
+ .offset = 0x7c0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "cfg",
+ .offset = 0x7d0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ } , {
+ .name = "FIS",
+ .offset = 0x7e0000,
+ .size = 0x010000,
+ .mask_flags = MTD_WRITEABLE,
+ }
+};
+#define wbd222_num_partitions ARRAY_SIZE(wbd222_partitions)
+
+static void __init wbd222_init(void)
+{
+ gemini_gpio_init();
+ platform_register_uart();
+ platform_register_pflash(SZ_8M, wbd222_partitions,
+ wbd222_num_partitions);
+ platform_device_register(&wbd222_leds_device);
+ platform_device_register(&wbd222_keys_device);
+ platform_register_rtc();
+}
+
+MACHINE_START(WBD222, "Wiliboard WBD-222")
+ .boot_params = 0x100,
+ .map_io = gemini_map_io,
+ .init_irq = gemini_init_irq,
+ .timer = &wbd222_timer,
+ .init_machine = wbd222_init,
+MACHINE_END
diff --git a/arch/arm/mach-gemini/common.h b/arch/arm/mach-gemini/common.h
new file mode 100644
index 00000000..7670c39a
--- /dev/null
+++ b/arch/arm/mach-gemini/common.h
@@ -0,0 +1,29 @@
+/*
+ * Common Gemini architecture functions
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __GEMINI_COMMON_H__
+#define __GEMINI_COMMON_H__
+
+struct mtd_partition;
+
+extern void gemini_map_io(void);
+extern void gemini_init_irq(void);
+extern void gemini_timer_init(void);
+extern void gemini_gpio_init(void);
+extern void platform_register_rtc(void);
+
+/* Common platform devices registration functions */
+extern int platform_register_uart(void);
+extern int platform_register_pflash(unsigned int size,
+ struct mtd_partition *parts,
+ unsigned int nr_parts);
+
+#endif /* __GEMINI_COMMON_H__ */
diff --git a/arch/arm/mach-gemini/devices.c b/arch/arm/mach-gemini/devices.c
new file mode 100644
index 00000000..5cff2981
--- /dev/null
+++ b/arch/arm/mach-gemini/devices.c
@@ -0,0 +1,118 @@
+/*
+ * Common devices definition for Gemini
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)IO_ADDRESS(GEMINI_UART_BASE),
+ .mapbase = GEMINI_UART_BASE,
+ .irq = IRQ_UART,
+ .uartclk = UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .type = PORT_16550A,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_FIXED_TYPE,
+ },
+ {},
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+int platform_register_uart(void)
+{
+ return platform_device_register(&serial_device);
+}
+
+static struct resource flash_resource = {
+ .start = GEMINI_FLASH_BASE,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data pflash_platform_data = {};
+
+static struct platform_device pflash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pflash_platform_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+int platform_register_pflash(unsigned int size, struct mtd_partition *parts,
+ unsigned int nr_parts)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_STATUS);
+
+ if ((reg & FLASH_TYPE_MASK) != FLASH_TYPE_PARALLEL)
+ return -ENXIO;
+
+ if (reg & FLASH_WIDTH_16BIT)
+ pflash_platform_data.width = 2;
+ else
+ pflash_platform_data.width = 1;
+
+ /* enable parallel flash pins and disable others */
+ reg = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+ reg &= ~PFLASH_PADS_DISABLE;
+ reg |= SFLASH_PADS_DISABLE | NAND_PADS_DISABLE;
+ __raw_writel(reg, IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_MISC_CTRL);
+
+ flash_resource.end = flash_resource.start + size - 1;
+
+ pflash_platform_data.parts = parts;
+ pflash_platform_data.nr_parts = nr_parts;
+
+ return platform_device_register(&pflash_device);
+}
+
+static struct resource gemini_rtc_resources[] = {
+ [0] = {
+ .start = GEMINI_RTC_BASE,
+ .end = GEMINI_RTC_BASE + 0x24,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC,
+ .end = IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device gemini_rtc_device = {
+ .name = "rtc-gemini",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(gemini_rtc_resources),
+ .resource = gemini_rtc_resources,
+};
+
+int __init platform_register_rtc(void)
+{
+ return platform_device_register(&gemini_rtc_device);
+}
+
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
new file mode 100644
index 00000000..fdc7ef13
--- /dev/null
+++ b/arch/arm/mach-gemini/gpio.c
@@ -0,0 +1,230 @@
+/*
+ * Gemini gpiochip and interrupt routines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on plat-mxc/gpio.c:
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#define GPIO_BASE(x) IO_ADDRESS(GEMINI_GPIO_BASE(x))
+
+/* GPIO registers definition */
+#define GPIO_DATA_OUT 0x0
+#define GPIO_DATA_IN 0x4
+#define GPIO_DIR 0x8
+#define GPIO_DATA_SET 0x10
+#define GPIO_DATA_CLR 0x14
+#define GPIO_PULL_EN 0x18
+#define GPIO_PULL_TYPE 0x1C
+#define GPIO_INT_EN 0x20
+#define GPIO_INT_STAT 0x24
+#define GPIO_INT_MASK 0x2C
+#define GPIO_INT_CLR 0x30
+#define GPIO_INT_TYPE 0x34
+#define GPIO_INT_BOTH_EDGE 0x38
+#define GPIO_INT_LEVEL 0x3C
+#define GPIO_DEBOUNCE_EN 0x40
+#define GPIO_DEBOUNCE_PRESCALE 0x44
+
+#define GPIO_PORT_NUM 3
+
+static void _set_gpio_irqenable(unsigned int base, unsigned int index,
+ int enable)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(base + GPIO_INT_EN);
+ reg = (reg & (~(1 << index))) | (!!enable << index);
+ __raw_writel(reg, base + GPIO_INT_EN);
+}
+
+static void gpio_ack_irq(struct irq_data *d)
+{
+ unsigned int gpio = irq_to_gpio(d->irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ __raw_writel(1 << (gpio % 32), base + GPIO_INT_CLR);
+}
+
+static void gpio_mask_irq(struct irq_data *d)
+{
+ unsigned int gpio = irq_to_gpio(d->irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ _set_gpio_irqenable(base, gpio % 32, 0);
+}
+
+static void gpio_unmask_irq(struct irq_data *d)
+{
+ unsigned int gpio = irq_to_gpio(d->irq);
+ unsigned int base = GPIO_BASE(gpio / 32);
+
+ _set_gpio_irqenable(base, gpio % 32, 1);
+}
+
+static int gpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int gpio = irq_to_gpio(d->irq);
+ unsigned int gpio_mask = 1 << (gpio % 32);
+ unsigned int base = GPIO_BASE(gpio / 32);
+ unsigned int reg_both, reg_level, reg_type;
+
+ reg_type = __raw_readl(base + GPIO_INT_TYPE);
+ reg_level = __raw_readl(base + GPIO_INT_LEVEL);
+ reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ reg_type &= ~gpio_mask;
+ reg_both |= gpio_mask;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ reg_type &= ~gpio_mask;
+ reg_both &= ~gpio_mask;
+ reg_level &= ~gpio_mask;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ reg_type &= ~gpio_mask;
+ reg_both &= ~gpio_mask;
+ reg_level |= gpio_mask;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ reg_type |= gpio_mask;
+ reg_level &= ~gpio_mask;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ reg_type |= gpio_mask;
+ reg_level |= gpio_mask;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ __raw_writel(reg_type, base + GPIO_INT_TYPE);
+ __raw_writel(reg_level, base + GPIO_INT_LEVEL);
+ __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
+
+ gpio_ack_irq(d->irq);
+
+ return 0;
+}
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int port = (unsigned int)irq_desc_get_handler_data(desc);
+ unsigned int gpio_irq_no, irq_stat;
+
+ irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT);
+
+ gpio_irq_no = GPIO_IRQ_BASE + port * 32;
+ for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
+
+ if ((irq_stat & 1) == 0)
+ continue;
+
+ generic_handle_irq(gpio_irq_no);
+ }
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_ack = gpio_ack_irq,
+ .irq_mask = gpio_mask_irq,
+ .irq_unmask = gpio_unmask_irq,
+ .irq_set_type = gpio_set_irq_type,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+ unsigned int reg;
+
+ reg = __raw_readl(base + GPIO_DIR);
+ if (dir)
+ reg |= 1 << (offset % 32);
+ else
+ reg &= ~(1 << (offset % 32));
+ __raw_writel(reg, base + GPIO_DIR);
+}
+
+static void gemini_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+
+ if (value)
+ __raw_writel(1 << (offset % 32), base + GPIO_DATA_SET);
+ else
+ __raw_writel(1 << (offset % 32), base + GPIO_DATA_CLR);
+}
+
+static int gemini_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned int base = GPIO_BASE(offset / 32);
+
+ return (__raw_readl(base + GPIO_DATA_IN) >> (offset % 32)) & 1;
+}
+
+static int gemini_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int gemini_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ _set_gpio_direction(chip, offset, 1);
+ gemini_gpio_set(chip, offset, value);
+ return 0;
+}
+
+static struct gpio_chip gemini_gpio_chip = {
+ .label = "Gemini",
+ .direction_input = gemini_gpio_direction_input,
+ .get = gemini_gpio_get,
+ .direction_output = gemini_gpio_direction_output,
+ .set = gemini_gpio_set,
+ .base = 0,
+ .ngpio = GPIO_PORT_NUM * 32,
+};
+
+void __init gemini_gpio_init(void)
+{
+ int i, j;
+
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ /* disable, unmask and clear all interrupts */
+ __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_EN);
+ __raw_writel(0x0, GPIO_BASE(i) + GPIO_INT_MASK);
+ __raw_writel(~0x0, GPIO_BASE(i) + GPIO_INT_CLR);
+
+ for (j = GPIO_IRQ_BASE + i * 32;
+ j < GPIO_IRQ_BASE + (i + 1) * 32; j++) {
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
+ irq_set_handler_data(IRQ_GPIO(i), (void *)i);
+ }
+
+ BUG_ON(gpiochip_add(&gemini_gpio_chip));
+}
diff --git a/arch/arm/mach-gemini/include/mach/debug-macro.S b/arch/arm/mach-gemini/include/mach/debug-macro.S
new file mode 100644
index 00000000..f40e006d
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <mach/hardware.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =GEMINI_UART_BASE @ physical
+ ldr \rv, =IO_ADDRESS(GEMINI_UART_BASE) @ virtual
+ .endm
+
+#define UART_SHIFT 2
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-gemini/include/mach/entry-macro.S b/arch/arm/mach-gemini/include/mach/entry-macro.S
new file mode 100644
index 00000000..1624f91a
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * Low-level IRQ helper macros for Gemini platform.
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+
+#define IRQ_STATUS 0x14
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, =IO_ADDRESS(GEMINI_INTERRUPT_BASE + IRQ_STATUS)
+ ldr \irqnr, [\irqstat]
+ cmp \irqnr, #0
+ beq 2313f
+ mov \tmp, \irqnr
+ mov \irqnr, #0
+2312:
+ tst \tmp, #1
+ bne 2313f
+ add \irqnr, \irqnr, #1
+ mov \tmp, \tmp, lsr #1
+ cmp \irqnr, #31
+ bcc 2312b
+2313:
+ .endm
diff --git a/arch/arm/mach-gemini/include/mach/global_reg.h b/arch/arm/mach-gemini/include/mach/global_reg.h
new file mode 100644
index 00000000..de7ff7e8
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/global_reg.h
@@ -0,0 +1,278 @@
+/*
+ * This file contains the hardware definitions for Gemini.
+ *
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_GLOBAL_REG_H
+#define __MACH_GLOBAL_REG_H
+
+/* Global Word ID Register*/
+#define GLOBAL_ID 0x00
+
+#define CHIP_ID(reg) ((reg) >> 8)
+#define CHIP_REVISION(reg) ((reg) & 0xFF)
+
+/* Global Status Register */
+#define GLOBAL_STATUS 0x04
+
+#define CPU_BIG_ENDIAN (1 << 31)
+#define PLL_OSC_30M (1 << 30) /* else 60MHz */
+
+#define OPERATION_MODE_MASK (0xF << 26)
+#define OPM_IDDQ (0xF << 26)
+#define OPM_NAND (0xE << 26)
+#define OPM_RING (0xD << 26)
+#define OPM_DIRECT_BOOT (0xC << 26)
+#define OPM_USB1_PHY_TEST (0xB << 26)
+#define OPM_USB0_PHY_TEST (0xA << 26)
+#define OPM_SATA1_PHY_TEST (0x9 << 26)
+#define OPM_SATA0_PHY_TEST (0x8 << 26)
+#define OPM_ICE_ARM (0x7 << 26)
+#define OPM_ICE_FARADAY (0x6 << 26)
+#define OPM_PLL_BYPASS (0x5 << 26)
+#define OPM_DEBUG (0x4 << 26)
+#define OPM_BURN_IN (0x3 << 26)
+#define OPM_MBIST (0x2 << 26)
+#define OPM_SCAN (0x1 << 26)
+#define OPM_REAL (0x0 << 26)
+
+#define FLASH_TYPE_MASK (0x3 << 24)
+#define FLASH_TYPE_NAND_2K (0x3 << 24)
+#define FLASH_TYPE_NAND_512 (0x2 << 24)
+#define FLASH_TYPE_PARALLEL (0x1 << 24)
+#define FLASH_TYPE_SERIAL (0x0 << 24)
+/* if parallel */
+#define FLASH_WIDTH_16BIT (1 << 23) /* else 8 bit */
+/* if serial */
+#define FLASH_ATMEL (1 << 23) /* else STM */
+
+#define FLASH_SIZE_MASK (0x3 << 21)
+#define NAND_256M (0x3 << 21) /* and more */
+#define NAND_128M (0x2 << 21)
+#define NAND_64M (0x1 << 21)
+#define NAND_32M (0x0 << 21)
+#define ATMEL_16M (0x3 << 21) /* and more */
+#define ATMEL_8M (0x2 << 21)
+#define ATMEL_4M_2M (0x1 << 21)
+#define ATMEL_1M (0x0 << 21) /* and less */
+#define STM_32M (1 << 22) /* and more */
+#define STM_16M (0 << 22) /* and less */
+
+#define FLASH_PARALLEL_HIGH_PIN_CNT (1 << 20) /* else low pin cnt */
+
+#define CPU_AHB_RATIO_MASK (0x3 << 18)
+#define CPU_AHB_1_1 (0x0 << 18)
+#define CPU_AHB_3_2 (0x1 << 18)
+#define CPU_AHB_24_13 (0x2 << 18)
+#define CPU_AHB_2_1 (0x3 << 18)
+
+#define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130)
+#define AHB_SPEED_TO_REG(x) ((((x - 130)) / 10) << 15)
+
+/* it is posible to override some settings, use >> OVERRIDE_xxxx_SHIFT */
+#define OVERRIDE_FLASH_TYPE_SHIFT 16
+#define OVERRIDE_FLASH_WIDTH_SHIFT 16
+#define OVERRIDE_FLASH_SIZE_SHIFT 16
+#define OVERRIDE_CPU_AHB_RATIO_SHIFT 15
+#define OVERRIDE_AHB_SPEED_SHIFT 15
+
+/* Global PLL Control Register */
+#define GLOBAL_PLL_CTRL 0x08
+
+#define PLL_BYPASS (1 << 31)
+#define PLL_POWER_DOWN (1 << 8)
+#define PLL_CONTROL_Q (0x1F << 0)
+
+/* Global Soft Reset Control Register */
+#define GLOBAL_RESET 0x0C
+
+#define RESET_GLOBAL (1 << 31)
+#define RESET_CPU1 (1 << 30)
+#define RESET_TVE (1 << 28)
+#define RESET_SATA1 (1 << 27)
+#define RESET_SATA0 (1 << 26)
+#define RESET_CIR (1 << 25)
+#define RESET_EXT_DEV (1 << 24)
+#define RESET_WD (1 << 23)
+#define RESET_GPIO2 (1 << 22)
+#define RESET_GPIO1 (1 << 21)
+#define RESET_GPIO0 (1 << 20)
+#define RESET_SSP (1 << 19)
+#define RESET_UART (1 << 18)
+#define RESET_TIMER (1 << 17)
+#define RESET_RTC (1 << 16)
+#define RESET_INT1 (1 << 15)
+#define RESET_INT0 (1 << 14)
+#define RESET_LCD (1 << 13)
+#define RESET_LPC (1 << 12)
+#define RESET_APB (1 << 11)
+#define RESET_DMA (1 << 10)
+#define RESET_USB1 (1 << 9)
+#define RESET_USB0 (1 << 8)
+#define RESET_PCI (1 << 7)
+#define RESET_GMAC1 (1 << 6)
+#define RESET_GMAC0 (1 << 5)
+#define RESET_SECURITY (1 << 4)
+#define RESET_RAID (1 << 3)
+#define RESET_IDE (1 << 2)
+#define RESET_FLASH (1 << 1)
+#define RESET_DRAM (1 << 0)
+
+/* Global IO Pad Driving Capability Control Register */
+#define GLOBAL_IO_DRIVING_CTRL 0x10
+
+#define DRIVING_CURRENT_MASK 0x3
+
+/* here 00-4mA, 01-8mA, 10-12mA, 11-16mA */
+#define GPIO1_PADS_31_28_SHIFT 28
+#define GPIO0_PADS_31_16_SHIFT 26
+#define GPIO0_PADS_15_0_SHIFT 24
+#define PCI_AND_EXT_RESET_PADS_SHIFT 22
+#define IDE_PADS_SHIFT 20
+#define GMAC1_PADS_SHIFT 18
+#define GMAC0_PADS_SHIFT 16
+/* DRAM is not in mA and poorly documented */
+#define DRAM_CLOCK_PADS_SHIFT 8
+#define DRAM_DATA_PADS_SHIFT 4
+#define DRAM_CONTROL_PADS_SHIFT 0
+
+/* Global IO Pad Slew Rate Control Register */
+#define GLOBAL_IO_SLEW_RATE_CTRL 0x14
+
+#define GPIO1_PADS_31_28_SLOW (1 << 10)
+#define GPIO0_PADS_31_16_SLOW (1 << 9)
+#define GPIO0_PADS_15_0_SLOW (1 << 8)
+#define PCI_PADS_SLOW (1 << 7)
+#define IDE_PADS_SLOW (1 << 6)
+#define GMAC1_PADS_SLOW (1 << 5)
+#define GMAC0_PADS_SLOW (1 << 4)
+#define DRAM_CLOCK_PADS_SLOW (1 << 1)
+#define DRAM_IO_PADS_SLOW (1 << 0)
+
+/*
+ * General skew control defines
+ * 16 steps, each step is around 0.2ns
+ */
+#define SKEW_MASK 0xF
+
+/* Global IDE PAD Skew Control Register */
+#define GLOBAL_IDE_SKEW_CTRL 0x18
+
+#define IDE1_HOST_STROBE_DELAY_SHIFT 28
+#define IDE1_DEVICE_STROBE_DELAY_SHIFT 24
+#define IDE1_OUTPUT_IO_SKEW_SHIFT 20
+#define IDE1_INPUT_IO_SKEW_SHIFT 16
+#define IDE0_HOST_STROBE_DELAY_SHIFT 12
+#define IDE0_DEVICE_STROBE_DELAY_SHIFT 8
+#define IDE0_OUTPUT_IO_SKEW_SHIFT 4
+#define IDE0_INPUT_IO_SKEW_SHIFT 0
+
+/* Global GMAC Control Pad Skew Control Register */
+#define GLOBAL_GMAC_CTRL_SKEW_CTRL 0x1C
+
+#define GMAC1_TXC_SKEW_SHIFT 28
+#define GMAC1_TXEN_SKEW_SHIFT 24
+#define GMAC1_RXC_SKEW_SHIFT 20
+#define GMAC1_RXDV_SKEW_SHIFT 16
+#define GMAC0_TXC_SKEW_SHIFT 12
+#define GMAC0_TXEN_SKEW_SHIFT 8
+#define GMAC0_RXC_SKEW_SHIFT 4
+#define GMAC0_RXDV_SKEW_SHIFT 0
+
+/* Global GMAC0 Data PAD Skew Control Register */
+#define GLOBAL_GMAC0_DATA_SKEW_CTRL 0x20
+/* Global GMAC1 Data PAD Skew Control Register */
+#define GLOBAL_GMAC1_DATA_SKEW_CTRL 0x24
+
+#define GMAC_TXD_SKEW_SHIFT(x) (((x) * 4) + 16)
+#define GMAC_RXD_SKEW_SHIFT(x) ((x) * 4)
+
+/* CPU has two AHB busses. */
+
+/* Global Arbitration0 Control Register */
+#define GLOBAL_ARBITRATION0_CTRL 0x28
+
+#define BOOT_CONTROLLER_HIGH_PRIO (1 << 3)
+#define DMA_BUS1_HIGH_PRIO (1 << 2)
+#define CPU0_HIGH_PRIO (1 << 0)
+
+/* Global Arbitration1 Control Register */
+#define GLOBAL_ARBITRATION1_CTRL 0x2C
+
+#define TVE_HIGH_PRIO (1 << 9)
+#define PCI_HIGH_PRIO (1 << 8)
+#define USB1_HIGH_PRIO (1 << 7)
+#define USB0_HIGH_PRIO (1 << 6)
+#define GMAC1_HIGH_PRIO (1 << 5)
+#define GMAC0_HIGH_PRIO (1 << 4)
+#define SECURITY_HIGH_PRIO (1 << 3)
+#define RAID_HIGH_PRIO (1 << 2)
+#define IDE_HIGH_PRIO (1 << 1)
+#define DMA_BUS2_HIGH_PRIO (1 << 0)
+
+/* Common bits for both arbitration registers */
+#define BURST_LENGTH_SHIFT 16
+#define BURST_LENGTH_MASK (0x3F << 16)
+
+/* Miscellaneous Control Register */
+#define GLOBAL_MISC_CTRL 0x30
+
+#define MEMORY_SPACE_SWAP (1 << 31)
+#define USB1_PLUG_MINIB (1 << 30) /* else plug is mini-A */
+#define USB0_PLUG_MINIB (1 << 29)
+#define GMAC_GMII (1 << 28)
+#define GMAC_1_ENABLE (1 << 27)
+/* TODO: define ATA/SATA bits */
+#define USB1_VBUS_ON (1 << 23)
+#define USB0_VBUS_ON (1 << 22)
+#define APB_CLKOUT_ENABLE (1 << 21)
+#define TVC_CLKOUT_ENABLE (1 << 20)
+#define EXT_CLKIN_ENABLE (1 << 19)
+#define PCI_66MHZ (1 << 18) /* else 33 MHz */
+#define PCI_CLKOUT_ENABLE (1 << 17)
+#define LPC_CLKOUT_ENABLE (1 << 16)
+#define USB1_WAKEUP_ON (1 << 15)
+#define USB0_WAKEUP_ON (1 << 14)
+/* TODO: define PCI idle detect bits */
+#define TVC_PADS_ENABLE (1 << 9)
+#define SSP_PADS_ENABLE (1 << 8)
+#define LCD_PADS_ENABLE (1 << 7)
+#define LPC_PADS_ENABLE (1 << 6)
+#define PCI_PADS_ENABLE (1 << 5)
+#define IDE_PADS_ENABLE (1 << 4)
+#define DRAM_PADS_POWER_DOWN (1 << 3)
+#define NAND_PADS_DISABLE (1 << 2)
+#define PFLASH_PADS_DISABLE (1 << 1)
+#define SFLASH_PADS_DISABLE (1 << 0)
+
+/* Global Clock Control Register */
+#define GLOBAL_CLOCK_CTRL 0x34
+
+#define POWER_STATE_G0 (1 << 31)
+#define POWER_STATE_S1 (1 << 30) /* else it is S3/S4 state */
+#define SECURITY_APB_AHB (1 << 29)
+/* else Security APB clk will be 0.75xAHB */
+/* TODO: TVC clock divider */
+#define PCI_CLKRUN_ENABLE (1 << 16)
+#define BOOT_CLK_DISABLE (1 << 13)
+#define TVC_CLK_DISABLE (1 << 12)
+#define FLASH_CLK_DISABLE (1 << 11)
+#define DDR_CLK_DISABLE (1 << 10)
+#define PCI_CLK_DISABLE (1 << 9)
+#define IDE_CLK_DISABLE (1 << 8)
+#define USB1_CLK_DISABLE (1 << 7)
+#define USB0_CLK_DISABLE (1 << 6)
+#define SATA1_CLK_DISABLE (1 << 5)
+#define SATA0_CLK_DISABLE (1 << 4)
+#define GMAC1_CLK_DISABLE (1 << 3)
+#define GMAC0_CLK_DISABLE (1 << 2)
+#define SECURITY_CLK_DISABLE (1 << 1)
+
+/* TODO: other registers definitions if needed */
+
+#endif /* __MACH_GLOBAL_REG_H */
diff --git a/arch/arm/mach-gemini/include/mach/gpio.h b/arch/arm/mach-gemini/include/mach/gpio.h
new file mode 100644
index 00000000..3bc2c70f
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/gpio.h
@@ -0,0 +1,25 @@
+/*
+ * Gemini gpiolib specific defines
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_GPIO_H__
+#define __MACH_GPIO_H__
+
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(x) ((x) + GPIO_IRQ_BASE)
+#define irq_to_gpio(x) ((x) - GPIO_IRQ_BASE)
+
+#endif /* __MACH_GPIO_H__ */
diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h
new file mode 100644
index 00000000..8c950e1d
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/hardware.h
@@ -0,0 +1,74 @@
+/*
+ * This file contains the hardware definitions for Gemini.
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/*
+ * Memory Map definitions
+ */
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define GEMINI_DRAM_BASE 0x00000000
+# define GEMINI_SRAM_BASE 0x70000000
+#else
+# define GEMINI_SRAM_BASE 0x00000000
+# define GEMINI_DRAM_BASE 0x10000000
+#endif
+#define GEMINI_FLASH_BASE 0x30000000
+#define GEMINI_GLOBAL_BASE 0x40000000
+#define GEMINI_WAQTCHDOG_BASE 0x41000000
+#define GEMINI_UART_BASE 0x42000000
+#define GEMINI_TIMER_BASE 0x43000000
+#define GEMINI_LCD_BASE 0x44000000
+#define GEMINI_RTC_BASE 0x45000000
+#define GEMINI_SATA_BASE 0x46000000
+#define GEMINI_LPC_HOST_BASE 0x47000000
+#define GEMINI_LPC_IO_BASE 0x47800000
+#define GEMINI_INTERRUPT_BASE 0x48000000
+/* TODO: Different interrupt controllers when SMP
+ * #define GEMINI_INTERRUPT0_BASE 0x48000000
+ * #define GEMINI_INTERRUPT1_BASE 0x49000000
+ */
+#define GEMINI_SSP_CTRL_BASE 0x4A000000
+#define GEMINI_POWER_CTRL_BASE 0x4B000000
+#define GEMINI_CIR_BASE 0x4C000000
+#define GEMINI_GPIO_BASE(x) (0x4D000000 + (x) * 0x1000000)
+#define GEMINI_PCI_IO_BASE 0x50000000
+#define GEMINI_PCI_MEM_BASE 0x58000000
+#define GEMINI_TOE_BASE 0x60000000
+#define GEMINI_GMAC0_BASE 0x6000A000
+#define GEMINI_GMAC1_BASE 0x6000E000
+#define GEMINI_SECURITY_BASE 0x62000000
+#define GEMINI_IDE0_BASE 0x63000000
+#define GEMINI_IDE1_BASE 0x63400000
+#define GEMINI_RAID_BASE 0x64000000
+#define GEMINI_FLASH_CTRL_BASE 0x65000000
+#define GEMINI_DRAM_CTRL_BASE 0x66000000
+#define GEMINI_GENERAL_DMA_BASE 0x67000000
+#define GEMINI_USB0_BASE 0x68000000
+#define GEMINI_USB1_BASE 0x69000000
+#define GEMINI_BIG_ENDIAN_BASE 0x80000000
+
+#define GEMINI_TIMER1_BASE GEMINI_TIMER_BASE
+#define GEMINI_TIMER2_BASE (GEMINI_TIMER_BASE + 0x10)
+#define GEMINI_TIMER3_BASE (GEMINI_TIMER_BASE + 0x20)
+
+/*
+ * UART Clock when System clk is 150MHz
+ */
+#define UART_CLK 48000000
+
+/*
+ * macro to get at IO space when running virtually
+ */
+#define IO_ADDRESS(x) ((((x) & 0xFFF00000) >> 4) | ((x) & 0x000FFFFF) | 0xF0000000)
+
+#endif
diff --git a/arch/arm/mach-gemini/include/mach/io.h b/arch/arm/mach-gemini/include/mach/io.h
new file mode 100644
index 00000000..c548056b
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/io.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-gemini/include/mach/irqs.h b/arch/arm/mach-gemini/include/mach/irqs.h
new file mode 100644
index 00000000..06bc47e7
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/irqs.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_IRQS_H__
+#define __MACH_IRQS_H__
+
+#define IRQ_SERIRQ1 31
+#define IRQ_SERIRQ0 30
+#define IRQ_PCID 29
+#define IRQ_PCIC 28
+#define IRQ_PCIB 27
+#define IRQ_PWR 26
+#define IRQ_CIR 25
+#define IRQ_GPIO(x) (22 + (x))
+#define IRQ_SSP 21
+#define IRQ_LPC 20
+#define IRQ_LCD 19
+#define IRQ_UART 18
+#define IRQ_RTC 17
+#define IRQ_TIMER3 16
+#define IRQ_TIMER2 15
+#define IRQ_TIMER1 14
+#define IRQ_FLASH 12
+#define IRQ_USB1 11
+#define IRQ_USB0 10
+#define IRQ_DMA 9
+#define IRQ_PCI 8
+#define IRQ_IPSEC 7
+#define IRQ_RAID 6
+#define IRQ_IDE1 5
+#define IRQ_IDE0 4
+#define IRQ_WATCHDOG 3
+#define IRQ_GMAC1 2
+#define IRQ_GMAC0 1
+#define IRQ_IPI 0
+
+#define NORMAL_IRQ_NUM 32
+
+#define GPIO_IRQ_BASE NORMAL_IRQ_NUM
+#define GPIO_IRQ_NUM (3 * 32)
+
+#define ARCH_TIMER_IRQ IRQ_TIMER2
+
+#define NR_IRQS (NORMAL_IRQ_NUM + GPIO_IRQ_NUM)
+
+#endif /* __MACH_IRQS_H__ */
diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h
new file mode 100644
index 00000000..a50915f7
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#ifdef CONFIG_GEMINI_MEM_SWAP
+# define PLAT_PHYS_OFFSET UL(0x00000000)
+#else
+# define PLAT_PHYS_OFFSET UL(0x10000000)
+#endif
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
new file mode 100644
index 00000000..4d9c1f87
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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 __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * Because of broken hardware we have to enable interrupts or the CPU
+ * will never wakeup... Acctualy it is not very good to enable
+ * interrupts here since scheduler can miss a tick, but there is
+ * no other way around this. Platforms that needs it for power saving
+ * should call enable_hlt() in init code, since by default it is
+ * disabled.
+ */
+ local_irq_enable();
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ __raw_writel(RESET_GLOBAL | RESET_CPU1,
+ IO_ADDRESS(GEMINI_GLOBAL_BASE) + GLOBAL_RESET);
+}
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-gemini/include/mach/timex.h b/arch/arm/mach-gemini/include/mach/timex.h
new file mode 100644
index 00000000..dc5690ba
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/timex.h
@@ -0,0 +1,13 @@
+/*
+ * Gemini timex specifications
+ *
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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.
+ */
+
+/* When AHB bus frequency is 150MHz */
+#define CLOCK_TICK_RATE 38000000
diff --git a/arch/arm/mach-gemini/include/mach/uncompress.h b/arch/arm/mach-gemini/include/mach/uncompress.h
new file mode 100644
index 00000000..0efa2624
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/uncompress.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on mach-pxa/include/mach/uncompress.h:
+ * Copyright: (C) 2001 MontaVista Software 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.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE;
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ */
+static inline void putc(char c)
+{
+ while (!(UART[UART_LSR] & UART_LSR_THRE))
+ barrier();
+ UART[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-gemini/include/mach/vmalloc.h b/arch/arm/mach-gemini/include/mach/vmalloc.h
new file mode 100644
index 00000000..45371eb8
--- /dev/null
+++ b/arch/arm/mach-gemini/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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.
+ */
+
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
new file mode 100644
index 00000000..9485a8fd
--- /dev/null
+++ b/arch/arm/mach-gemini/irq.c
@@ -0,0 +1,102 @@
+/*
+ * Interrupt routines for Gemini
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/stddef.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+
+#define IRQ_SOURCE(base_addr) (base_addr + 0x00)
+#define IRQ_MASK(base_addr) (base_addr + 0x04)
+#define IRQ_CLEAR(base_addr) (base_addr + 0x08)
+#define IRQ_TMODE(base_addr) (base_addr + 0x0C)
+#define IRQ_TLEVEL(base_addr) (base_addr + 0x10)
+#define IRQ_STATUS(base_addr) (base_addr + 0x14)
+#define FIQ_SOURCE(base_addr) (base_addr + 0x20)
+#define FIQ_MASK(base_addr) (base_addr + 0x24)
+#define FIQ_CLEAR(base_addr) (base_addr + 0x28)
+#define FIQ_TMODE(base_addr) (base_addr + 0x2C)
+#define FIQ_LEVEL(base_addr) (base_addr + 0x30)
+#define FIQ_STATUS(base_addr) (base_addr + 0x34)
+
+static void gemini_ack_irq(struct irq_data *d)
+{
+ __raw_writel(1 << d->irq, IRQ_CLEAR(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_mask_irq(struct irq_data *d)
+{
+ unsigned int mask;
+
+ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ mask &= ~(1 << d->irq);
+ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static void gemini_unmask_irq(struct irq_data *d)
+{
+ unsigned int mask;
+
+ mask = __raw_readl(IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ mask |= (1 << d->irq);
+ __raw_writel(mask, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
+
+static struct irq_chip gemini_irq_chip = {
+ .name = "INTC",
+ .irq_ack = gemini_ack_irq,
+ .irq_mask = gemini_mask_irq,
+ .irq_unmask = gemini_unmask_irq,
+};
+
+static struct resource irq_resource = {
+ .name = "irq_handler",
+ .start = IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+ .end = IO_ADDRESS(FIQ_STATUS(GEMINI_INTERRUPT_BASE)) + 4,
+};
+
+void __init gemini_init_irq(void)
+{
+ unsigned int i, mode = 0, level = 0;
+
+ /*
+ * Disable arch_idle() by default since it is buggy
+ * For more info see arch/arm/mach-gemini/include/mach/system.h
+ */
+ disable_hlt();
+
+ request_resource(&iomem_resource, &irq_resource);
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_set_chip(i, &gemini_irq_chip);
+ if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) {
+ irq_set_handler(i, handle_edge_irq);
+ mode |= 1 << i;
+ level |= 1 << i;
+ } else {
+ irq_set_handler(i, handle_level_irq);
+ }
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Disable all interrupts */
+ __raw_writel(0, IRQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ __raw_writel(0, FIQ_MASK(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+
+ /* Set interrupt mode */
+ __raw_writel(mode, IRQ_TMODE(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+ __raw_writel(level, IRQ_TLEVEL(IO_ADDRESS(GEMINI_INTERRUPT_BASE)));
+}
diff --git a/arch/arm/mach-gemini/mm.c b/arch/arm/mach-gemini/mm.c
new file mode 100644
index 00000000..51948242
--- /dev/null
+++ b/arch/arm/mach-gemini/mm.c
@@ -0,0 +1,82 @@
+/*
+ * Static mappings for Gemini
+ *
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+/* Page table mapping for I/O region */
+static struct map_desc gemini_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(GEMINI_GLOBAL_BASE),
+ .pfn =__phys_to_pfn(GEMINI_GLOBAL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_UART_BASE),
+ .pfn = __phys_to_pfn(GEMINI_UART_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_TIMER_BASE),
+ .pfn = __phys_to_pfn(GEMINI_TIMER_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_INTERRUPT_BASE),
+ .pfn = __phys_to_pfn(GEMINI_INTERRUPT_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_POWER_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_POWER_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(0)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(1)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(1)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GPIO_BASE(2)),
+ .pfn = __phys_to_pfn(GEMINI_GPIO_BASE(2)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_FLASH_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_FLASH_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_DRAM_CTRL_BASE),
+ .pfn = __phys_to_pfn(GEMINI_DRAM_CTRL_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(GEMINI_GENERAL_DMA_BASE),
+ .pfn = __phys_to_pfn(GEMINI_GENERAL_DMA_BASE),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init gemini_map_io(void)
+{
+ iotable_init(gemini_io_desc, ARRAY_SIZE(gemini_io_desc));
+}
diff --git a/arch/arm/mach-gemini/time.c b/arch/arm/mach-gemini/time.c
new file mode 100644
index 00000000..21dc5a89
--- /dev/null
+++ b/arch/arm/mach-gemini/time.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2001-2006 Storlink, Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/global_reg.h>
+#include <asm/mach/time.h>
+
+/*
+ * Register definitions for the timers
+ */
+#define TIMER_COUNT(BASE_ADDR) (BASE_ADDR + 0x00)
+#define TIMER_LOAD(BASE_ADDR) (BASE_ADDR + 0x04)
+#define TIMER_MATCH1(BASE_ADDR) (BASE_ADDR + 0x08)
+#define TIMER_MATCH2(BASE_ADDR) (BASE_ADDR + 0x0C)
+#define TIMER_CR(BASE_ADDR) (BASE_ADDR + 0x30)
+
+#define TIMER_1_CR_ENABLE (1 << 0)
+#define TIMER_1_CR_CLOCK (1 << 1)
+#define TIMER_1_CR_INT (1 << 2)
+#define TIMER_2_CR_ENABLE (1 << 3)
+#define TIMER_2_CR_CLOCK (1 << 4)
+#define TIMER_2_CR_INT (1 << 5)
+#define TIMER_3_CR_ENABLE (1 << 6)
+#define TIMER_3_CR_CLOCK (1 << 7)
+#define TIMER_3_CR_INT (1 << 8)
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction gemini_timer_irq = {
+ .name = "Gemini Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = gemini_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+void __init gemini_timer_init(void)
+{
+ unsigned int tick_rate, reg_v;
+
+ reg_v = __raw_readl(IO_ADDRESS(GEMINI_GLOBAL_BASE + GLOBAL_STATUS));
+ tick_rate = REG_TO_AHB_SPEED(reg_v) * 1000000;
+
+ printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);
+
+ tick_rate /= 6; /* APB bus run AHB*(1/6) */
+
+ switch(reg_v & CPU_AHB_RATIO_MASK) {
+ case CPU_AHB_1_1:
+ printk(KERN_CONT "(1/1)\n");
+ break;
+ case CPU_AHB_3_2:
+ printk(KERN_CONT "(3/2)\n");
+ break;
+ case CPU_AHB_24_13:
+ printk(KERN_CONT "(24/13)\n");
+ break;
+ case CPU_AHB_2_1:
+ printk(KERN_CONT "(2/1)\n");
+ break;
+ }
+
+ /*
+ * Make irqs happen for the system timer
+ */
+ setup_irq(IRQ_TIMER2, &gemini_timer_irq);
+ /* Start the timer */
+ __raw_writel(tick_rate / HZ, TIMER_COUNT(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ __raw_writel(tick_rate / HZ, TIMER_LOAD(IO_ADDRESS(GEMINI_TIMER2_BASE)));
+ __raw_writel(TIMER_2_CR_ENABLE | TIMER_2_CR_INT, TIMER_CR(IO_ADDRESS(GEMINI_TIMER_BASE)));
+}
diff --git a/arch/arm/mach-h720x/Kconfig b/arch/arm/mach-h720x/Kconfig
new file mode 100644
index 00000000..abf356c0
--- /dev/null
+++ b/arch/arm/mach-h720x/Kconfig
@@ -0,0 +1,40 @@
+if ARCH_H720X
+
+menu "h720x Implementations"
+
+config ARCH_H7201
+ bool "gms30c7201"
+ depends on ARCH_H720X
+ select CPU_H7201
+ select ZONE_DMA
+ help
+ Say Y here if you are using the Hynix GMS30C7201 Reference Board
+
+config ARCH_H7202
+ bool "hms30c7202"
+ select CPU_H7202
+ select ZONE_DMA
+ depends on ARCH_H720X
+ help
+ Say Y here if you are using the Hynix HMS30C7202 Reference Board
+
+endmenu
+
+config CPU_H7201
+ bool
+ help
+ Select code specific to h7201 variants
+
+config CPU_H7202
+ bool
+ help
+ Select code specific to h7202 variants
+config H7202_SERIAL23
+ depends on CPU_H7202
+ bool "Use serial ports 2+3"
+ help
+ Say Y here if you wish to use serial ports 2+3. They share their
+ pins with the keyboard matrix controller, so you have to decide.
+
+
+endif
diff --git a/arch/arm/mach-h720x/Makefile b/arch/arm/mach-h720x/Makefile
new file mode 100644
index 00000000..e4cf7289
--- /dev/null
+++ b/arch/arm/mach-h720x/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := common.o
+obj-m :=
+obj-n :=
+obj- :=
+
+# Specific board support
+
+obj-$(CONFIG_ARCH_H7201) += h7201-eval.o
+obj-$(CONFIG_ARCH_H7202) += h7202-eval.o
+obj-$(CONFIG_CPU_H7201) += cpu-h7201.o
+obj-$(CONFIG_CPU_H7202) += cpu-h7202.o
diff --git a/arch/arm/mach-h720x/Makefile.boot b/arch/arm/mach-h720x/Makefile.boot
new file mode 100644
index 00000000..52984017
--- /dev/null
+++ b/arch/arm/mach-h720x/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-$(CONFIG_ARCH_H720X) := 0x40008000
+
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
new file mode 100644
index 00000000..51d4e44a
--- /dev/null
+++ b/arch/arm/mach-h720x/common.c
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/arm/mach-h720x/common.c
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * common stuff for Hynix h720x processors
+ *
+ * This program is free software; you can 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/mman.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <mach/irqs.h>
+
+#include <asm/mach/dma.h>
+
+#if 0
+#define IRQDBG(args...) printk(args)
+#else
+#define IRQDBG(args...) do {} while(0)
+#endif
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
+
+/*
+ * Return usecs since last timer reload
+ * (timercount * (usecs perjiffie)) / (ticks per jiffie)
+ */
+unsigned long h720x_gettimeoffset(void)
+{
+ return (CPU_REG (TIMER_VIRT, TM0_COUNT) * tick_usec) / LATCH;
+}
+
+/*
+ * mask Global irq's
+ */
+static void mask_global_irq(struct irq_data *d)
+{
+ CPU_REG (IRQC_VIRT, IRQC_IER) &= ~(1 << d->irq);
+}
+
+/*
+ * unmask Global irq's
+ */
+static void unmask_global_irq(struct irq_data *d)
+{
+ CPU_REG (IRQC_VIRT, IRQC_IER) |= (1 << d->irq);
+}
+
+
+/*
+ * ack GPIO irq's
+ * Ack only for edge triggered int's valid
+ */
+static void inline ack_gpio_irq(struct irq_data *d)
+{
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
+ if ( (CPU_REG (reg_base, GPIO_EDGE) & bit))
+ CPU_REG (reg_base, GPIO_CLR) = bit;
+}
+
+/*
+ * mask GPIO irq's
+ */
+static void inline mask_gpio_irq(struct irq_data *d)
+{
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
+ CPU_REG (reg_base, GPIO_MASK) &= ~bit;
+}
+
+/*
+ * unmask GPIO irq's
+ */
+static void inline unmask_gpio_irq(struct irq_data *d)
+{
+ u32 reg_base = GPIO_VIRT(IRQ_TO_REGNO(d->irq));
+ u32 bit = IRQ_TO_BIT(d->irq);
+ CPU_REG (reg_base, GPIO_MASK) |= bit;
+}
+
+static void
+h720x_gpio_handler(unsigned int mask, unsigned int irq,
+ struct irq_desc *desc)
+{
+ IRQDBG("%s irq: %d\n", __func__, irq);
+ while (mask) {
+ if (mask & 1) {
+ IRQDBG("handling irq %d\n", irq);
+ generic_handle_irq(irq);
+ }
+ irq++;
+ mask >>= 1;
+ }
+}
+
+static void
+h720x_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = CPU_REG(GPIO_A_VIRT,GPIO_STAT);
+ irq = IRQ_CHAINED_GPIOA(0);
+ IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
+ h720x_gpio_handler(mask, irq, desc);
+}
+
+static void
+h720x_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+ mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT);
+ irq = IRQ_CHAINED_GPIOB(0);
+ IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
+ h720x_gpio_handler(mask, irq, desc);
+}
+
+static void
+h720x_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = CPU_REG(GPIO_C_VIRT,GPIO_STAT);
+ irq = IRQ_CHAINED_GPIOC(0);
+ IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
+ h720x_gpio_handler(mask, irq, desc);
+}
+
+static void
+h720x_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = CPU_REG(GPIO_D_VIRT,GPIO_STAT);
+ irq = IRQ_CHAINED_GPIOD(0);
+ IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
+ h720x_gpio_handler(mask, irq, desc);
+}
+
+#ifdef CONFIG_CPU_H7202
+static void
+h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = CPU_REG(GPIO_E_VIRT,GPIO_STAT);
+ irq = IRQ_CHAINED_GPIOE(0);
+ IRQDBG("%s mask: 0x%08x irq: %d\n", __func__, mask,irq);
+ h720x_gpio_handler(mask, irq, desc);
+}
+#endif
+
+static struct irq_chip h720x_global_chip = {
+ .irq_ack = mask_global_irq,
+ .irq_mask = mask_global_irq,
+ .irq_unmask = unmask_global_irq,
+};
+
+static struct irq_chip h720x_gpio_chip = {
+ .irq_ack = ack_gpio_irq,
+ .irq_mask = mask_gpio_irq,
+ .irq_unmask = unmask_gpio_irq,
+};
+
+/*
+ * Initialize IRQ's, mask all, enable multiplexed irq's
+ */
+void __init h720x_init_irq (void)
+{
+ int irq;
+
+ /* Mask global irq's */
+ CPU_REG (IRQC_VIRT, IRQC_IER) = 0x0;
+
+ /* Mask all multiplexed irq's */
+ CPU_REG (GPIO_A_VIRT, GPIO_MASK) = 0x0;
+ CPU_REG (GPIO_B_VIRT, GPIO_MASK) = 0x0;
+ CPU_REG (GPIO_C_VIRT, GPIO_MASK) = 0x0;
+ CPU_REG (GPIO_D_VIRT, GPIO_MASK) = 0x0;
+
+ /* Initialize global IRQ's, fast path */
+ for (irq = 0; irq < NR_GLBL_IRQS; irq++) {
+ irq_set_chip_and_handler(irq, &h720x_global_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Initialize multiplexed IRQ's, slow path */
+ for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) {
+ irq_set_chip_and_handler(irq, &h720x_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID );
+ }
+ irq_set_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
+
+#ifdef CONFIG_CPU_H7202
+ for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) {
+ irq_set_chip_and_handler(irq, &h720x_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID );
+ }
+ irq_set_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
+#endif
+
+ /* Enable multiplexed irq's */
+ CPU_REG (IRQC_VIRT, IRQC_IER) = IRQ_ENA_MUX;
+}
+
+static struct map_desc h720x_io_desc[] __initdata = {
+ {
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(IO_PHYS),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/* Initialize io tables */
+void __init h720x_map_io(void)
+{
+ iotable_init(h720x_io_desc,ARRAY_SIZE(h720x_io_desc));
+}
diff --git a/arch/arm/mach-h720x/common.h b/arch/arm/mach-h720x/common.h
new file mode 100644
index 00000000..7dd5fa60
--- /dev/null
+++ b/arch/arm/mach-h720x/common.h
@@ -0,0 +1,29 @@
+/*
+ * linux/arch/arm/mach-h720x/common.h
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Architecture specific stuff for Hynix GMS30C7201 development 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.
+ *
+ */
+
+extern unsigned long h720x_gettimeoffset(void);
+extern void __init h720x_init_irq(void);
+extern void __init h720x_map_io(void);
+
+#ifdef CONFIG_ARCH_H7202
+extern struct sys_timer h7202_timer;
+extern void __init init_hw_h7202(void);
+extern void __init h7202_init_irq(void);
+extern void __init h7202_init_time(void);
+#endif
+
+#ifdef CONFIG_ARCH_H7201
+extern struct sys_timer h7201_timer;
+#endif
diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c
new file mode 100644
index 00000000..24df2a34
--- /dev/null
+++ b/arch/arm/mach-h720x/cpu-h7201.c
@@ -0,0 +1,60 @@
+/*
+ * linux/arch/arm/mach-h720x/cpu-h7201.c
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * processor specific stuff for the Hynix h7201
+ *
+ * This program is free software; you can 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/module.h>
+#include <asm/types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include "common.h"
+/*
+ * Timer interrupt handler
+ */
+static irqreturn_t
+h7201_timer_interrupt(int irq, void *dev_id)
+{
+ CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
+ timer_tick();
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction h7201_timer_irq = {
+ .name = "h7201 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = h7201_timer_interrupt,
+};
+
+/*
+ * Setup TIMER0 as system timer
+ */
+void __init h7201_init_time(void)
+{
+ CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH;
+ CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET;
+ CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START;
+ CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) = ENABLE_TM0_INTR | TIMER_ENABLE_BIT;
+
+ setup_irq(IRQ_TIMER0, &h7201_timer_irq);
+}
+
+struct sys_timer h7201_timer = {
+ .init = h7201_init_time,
+ .offset = h720x_gettimeoffset,
+};
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
new file mode 100644
index 00000000..c37d570b
--- /dev/null
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -0,0 +1,228 @@
+/*
+ * linux/arch/arm/mach-h720x/cpu-h7202.c
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * processor specific stuff for the Hynix h7202
+ *
+ * This program is free software; you can 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/module.h>
+#include <asm/types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include "common.h"
+
+static struct resource h7202ps2_resources[] = {
+ [0] = {
+ .start = 0x8002c000,
+ .end = 0x8002c040,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PS2,
+ .end = IRQ_PS2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device h7202ps2_device = {
+ .name = "h7202ps2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(h7202ps2_resources),
+ .resource = h7202ps2_resources,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void*)SERIAL0_VIRT,
+ .mapbase = SERIAL0_BASE,
+ .irq = IRQ_UART0,
+ .uartclk = 2*1843200,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ {
+ .membase = (void*)SERIAL1_VIRT,
+ .mapbase = SERIAL1_BASE,
+ .irq = IRQ_UART1,
+ .uartclk = 2*1843200,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+#ifdef CONFIG_H7202_SERIAL23
+ {
+ .membase = (void*)SERIAL2_VIRT,
+ .mapbase = SERIAL2_BASE,
+ .irq = IRQ_UART2,
+ .uartclk = 2*1843200,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ {
+ .membase = (void*)SERIAL3_VIRT,
+ .mapbase = SERIAL3_BASE,
+ .irq = IRQ_UART3,
+ .uartclk = 2*1843200,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+#endif
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &h7202ps2_device,
+ &serial_device,
+};
+
+/* Although we have two interrupt lines for the timers, we only have one
+ * status register which clears all pending timer interrupts on reading. So
+ * we have to handle all timer interrupts in one place.
+ */
+static void
+h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int mask, irq;
+
+ mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
+
+ if ( mask & TSTAT_T0INT ) {
+ timer_tick();
+ if( mask == TSTAT_T0INT )
+ return;
+ }
+
+ mask >>= 1;
+ irq = IRQ_TIMER1;
+ while (mask) {
+ if (mask & 1)
+ generic_handle_irq(irq);
+ irq++;
+ mask >>= 1;
+ }
+}
+
+/*
+ * Timer interrupt handler
+ */
+static irqreturn_t
+h7202_timer_interrupt(int irq, void *dev_id)
+{
+ h7202_timerx_demux_handler(0, NULL);
+ return IRQ_HANDLED;
+}
+
+/*
+ * mask multiplexed timer IRQs
+ */
+static void inline __mask_timerx_irq(unsigned int irq)
+{
+ unsigned int bit;
+ bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
+ CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit;
+}
+
+static void inline mask_timerx_irq(struct irq_data *d)
+{
+ __mask_timerx_irq(d->irq);
+}
+
+/*
+ * unmask multiplexed timer IRQs
+ */
+static void inline unmask_timerx_irq(struct irq_data *d)
+{
+ unsigned int bit;
+ bit = 2 << ((d->irq == IRQ_TIMER64B) ? 4 : (d->irq - IRQ_TIMER1));
+ CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit;
+}
+
+static struct irq_chip h7202_timerx_chip = {
+ .irq_ack = mask_timerx_irq,
+ .irq_mask = mask_timerx_irq,
+ .irq_unmask = unmask_timerx_irq,
+};
+
+static struct irqaction h7202_timer_irq = {
+ .name = "h7202 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = h7202_timer_interrupt,
+};
+
+/*
+ * Setup TIMER0 as system timer
+ */
+void __init h7202_init_time(void)
+{
+ CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH;
+ CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET;
+ CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START;
+ CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) = ENABLE_TM0_INTR | TIMER_ENABLE_BIT;
+
+ setup_irq(IRQ_TIMER0, &h7202_timer_irq);
+}
+
+struct sys_timer h7202_timer = {
+ .init = h7202_init_time,
+ .offset = h720x_gettimeoffset,
+};
+
+void __init h7202_init_irq (void)
+{
+ int irq;
+
+ CPU_REG (GPIO_E_VIRT, GPIO_MASK) = 0x0;
+
+ for (irq = IRQ_TIMER1;
+ irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) {
+ __mask_timerx_irq(irq);
+ irq_set_chip_and_handler(irq, &h7202_timerx_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID );
+ }
+ irq_set_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler);
+
+ h720x_init_irq();
+}
+
+void __init init_hw_h7202(void)
+{
+ /* Enable clocks */
+ CPU_REG (PMU_BASE, PMU_PLL_CTRL) |= PLL_2_EN | PLL_1_EN | PLL_3_MUTE;
+
+ CPU_REG (SERIAL0_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+ CPU_REG (SERIAL1_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+#ifdef CONFIG_H7202_SERIAL23
+ CPU_REG (SERIAL2_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+ CPU_REG (SERIAL3_VIRT, SERIAL_ENABLE) = SERIAL_ENABLE_EN;
+ CPU_IO (GPIO_AMULSEL) = AMULSEL_USIN2 | AMULSEL_USOUT2 |
+ AMULSEL_USIN3 | AMULSEL_USOUT3;
+#endif
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+}
diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c
new file mode 100644
index 00000000..629454d7
--- /dev/null
+++ b/arch/arm/mach-h720x/h7201-eval.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-h720x/h7201-eval.c
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Architecture specific stuff for Hynix GMS30C7201 development 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/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/device.h>
+
+#include <asm/setup.h>
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+MACHINE_START(H7201, "Hynix GMS30C7201")
+ /* Maintainer: Robert Schwebel, Pengutronix */
+ .boot_params = 0xc0001000,
+ .map_io = h720x_map_io,
+ .init_irq = h720x_init_irq,
+ .timer = &h7201_timer,
+MACHINE_END
diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c
new file mode 100644
index 00000000..e9f46b69
--- /dev/null
+++ b/arch/arm/mach-h720x/h7202-eval.c
@@ -0,0 +1,79 @@
+/*
+ * linux/arch/arm/mach-h720x/h7202-eval.c
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Architecture specific stuff for Hynix HMS30C7202 development 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/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <asm/setup.h>
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+static struct resource cirrus_resources[] = {
+ [0] = {
+ .start = ETH0_PHYS + 0x300,
+ .end = ETH0_PHYS + 0x300 + 0x10,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CHAINED_GPIOB(8),
+ .end = IRQ_CHAINED_GPIOB(8),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cirrus_device = {
+ .name = "cirrus-cs89x0",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(cirrus_resources),
+ .resource = cirrus_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &cirrus_device,
+};
+
+/*
+ * Hardware init. This is called early in initcalls
+ * Place pin inits here. So you avoid adding ugly
+ * #ifdef stuff to common drivers.
+ * Use this only, if your bootloader is not able
+ * to initialize the pins proper.
+ */
+static void __init init_eval_h7202(void)
+{
+ init_hw_h7202();
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* Enable interrupt on portb bit 8 (ethernet) */
+ CPU_REG (GPIO_B_VIRT, GPIO_POL) &= ~(1 << 8);
+ CPU_REG (GPIO_B_VIRT, GPIO_EN) |= (1 << 8);
+}
+
+MACHINE_START(H7202, "Hynix HMS30C7202")
+ /* Maintainer: Robert Schwebel, Pengutronix */
+ .boot_params = 0x40000100,
+ .map_io = h720x_map_io,
+ .init_irq = h7202_init_irq,
+ .timer = &h7202_timer,
+ .init_machine = init_eval_h7202,
+MACHINE_END
diff --git a/arch/arm/mach-h720x/include/mach/boards.h b/arch/arm/mach-h720x/include/mach/boards.h
new file mode 100644
index 00000000..38b8e0d6
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/boards.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-h720x/include/mach/boards.h
+ *
+ * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * This file contains the board specific defines for various 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.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_INCMACH_H
+#error Do not include this file directly. Include asm/hardware.h instead !
+#endif
+
+/* Hynix H7202 developer board specific device defines */
+#ifdef CONFIG_ARCH_H7202
+
+/* FLASH */
+#define H720X_FLASH_VIRT 0xd0000000
+#define H720X_FLASH_PHYS 0x00000000
+#define H720X_FLASH_SIZE 0x02000000
+
+/* onboard LAN controller */
+# define ETH0_PHYS 0x08000000
+
+/* Touch screen defines */
+/* GPIO Port */
+#define PEN_GPIO GPIO_B_VIRT
+/* Bitmask for pen down interrupt */
+#define PEN_INT_BIT (1<<7)
+/* Bitmask for pen up interrupt */
+#define PEN_ENA_BIT (1<<6)
+/* pen up interrupt */
+#define IRQ_PEN IRQ_MUX_GPIOB(7)
+
+#endif
+
+/* Hynix H7201 developer board specific device defines */
+#if defined (CONFIG_ARCH_H7201)
+/* ROM DISK SPACE */
+#define ROM_DISK_BASE 0xc1800000
+#define ROM_DISK_START 0x41800000
+#define ROM_DISK_SIZE 0x00700000
+
+/* SRAM DISK SPACE */
+#define SRAM_DISK_BASE 0xf1000000
+#define SRAM_DISK_START 0x04000000
+#define SRAM_DISK_SIZE 0x00400000
+#endif
+
diff --git a/arch/arm/mach-h720x/include/mach/debug-macro.S b/arch/arm/mach-h720x/include/mach/debug-macro.S
new file mode 100644
index 00000000..c2093e83
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/debug-macro.S
@@ -0,0 +1,40 @@
+/* arch/arm/mach-h720x/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <mach/hardware.h>
+
+ .equ io_virt, IO_VIRT
+ .equ io_phys, IO_PHYS
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00020000 @ UART1
+ add \rv, \rp, #io_virt @ virtual address
+ add \rp, \rp, #io_phys @ physical base address
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x0] @ UARTDR
+
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
+ bne 1001b
+ .endm
diff --git a/arch/arm/mach-h720x/include/mach/entry-macro.S b/arch/arm/mach-h720x/include/mach/entry-macro.S
new file mode 100644
index 00000000..6d3b917c
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/entry-macro.S
@@ -0,0 +1,66 @@
+/*
+ * arch/arm/mach-h720x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Hynix HMS720x based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined (CONFIG_CPU_H7201) || defined (CONFIG_CPU_H7202)
+ @ we could use the id register on H7202, but this is not
+ @ properly updated when we come back from asm_do_irq
+ @ without a previous return from interrupt
+ @ (see loops below in irq_svc, irq_usr)
+ @ We see unmasked pending ints only, as the masked pending ints
+ @ are not visible here
+
+ mov \base, #0xf0000000 @ base register
+ orr \base, \base, #0x24000 @ irqbase
+ ldr \irqstat, [\base, #0x04] @ get interrupt status
+#if defined (CONFIG_CPU_H7201)
+ ldr \tmp, =0x001fffff
+#else
+ mvn \tmp, #0xc0000000
+#endif
+ and \irqstat, \irqstat, \tmp @ mask out unused ints
+ mov \irqnr, #0
+
+ mov \tmp, #0xff00
+ orr \tmp, \tmp, #0xff
+ tst \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+ moveq \irqstat, \irqstat, lsr #16
+ tst \irqstat, #255
+ addeq \irqnr, \irqnr, #8
+ moveq \irqstat, \irqstat, lsr #8
+ tst \irqstat, #15
+ addeq \irqnr, \irqnr, #4
+ moveq \irqstat, \irqstat, lsr #4
+ tst \irqstat, #3
+ addeq \irqnr, \irqnr, #2
+ moveq \irqstat, \irqstat, lsr #2
+ tst \irqstat, #1
+ addeq \irqnr, \irqnr, #1
+ moveq \irqstat, \irqstat, lsr #1
+ tst \irqstat, #1 @ bit 0 should be set
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
+#else
+#error hynix processor selection missmatch
+#endif
+
diff --git a/arch/arm/mach-h720x/include/mach/h7201-regs.h b/arch/arm/mach-h720x/include/mach/h7201-regs.h
new file mode 100644
index 00000000..611b4947
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/h7201-regs.h
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-h720x/include/mach/h7201-regs.h
+ *
+ * Copyright (C) 2000 Jungjun Kim, Hynix Semiconductor Inc.
+ * (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * (C) 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file contains the hardware definitions of the h720x processors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Do not add implementations specific defines here. This files contains
+ * only defines of the onchip peripherals. Add those defines to boards.h,
+ * which is included by this file.
+ */
+
+#define SERIAL2_VIRT (IO_VIRT + 0x50100)
+#define SERIAL3_VIRT (IO_VIRT + 0x50200)
+
+/*
+ * PCMCIA
+ */
+#define PCMCIA0_ATT_BASE 0xe5000000
+#define PCMCIA0_ATT_SIZE 0x00200000
+#define PCMCIA0_ATT_START 0x20000000
+#define PCMCIA0_MEM_BASE 0xe5200000
+#define PCMCIA0_MEM_SIZE 0x00200000
+#define PCMCIA0_MEM_START 0x24000000
+#define PCMCIA0_IO_BASE 0xe5400000
+#define PCMCIA0_IO_SIZE 0x00200000
+#define PCMCIA0_IO_START 0x28000000
+
+#define PCMCIA1_ATT_BASE 0xe5600000
+#define PCMCIA1_ATT_SIZE 0x00200000
+#define PCMCIA1_ATT_START 0x30000000
+#define PCMCIA1_MEM_BASE 0xe5800000
+#define PCMCIA1_MEM_SIZE 0x00200000
+#define PCMCIA1_MEM_START 0x34000000
+#define PCMCIA1_IO_BASE 0xe5a00000
+#define PCMCIA1_IO_SIZE 0x00200000
+#define PCMCIA1_IO_START 0x38000000
+
+#define PRIME3C_BASE 0xf0050000
+#define PRIME3C_SIZE 0x00001000
+#define PRIME3C_START 0x10000000
+
+/* VGA Controller */
+#define VGA_RAMBASE 0x50
+#define VGA_TIMING0 0x60
+#define VGA_TIMING1 0x64
+#define VGA_TIMING2 0x68
+#define VGA_TIMING3 0x6c
+
+#define LCD_CTRL_VGA_ENABLE 0x00000100
+#define LCD_CTRL_VGA_BPP_MASK 0x00000600
+#define LCD_CTRL_VGA_4BPP 0x00000000
+#define LCD_CTRL_VGA_8BPP 0x00000200
+#define LCD_CTRL_VGA_16BPP 0x00000300
+#define LCD_CTRL_SHARE_DMA 0x00000800
+#define LCD_CTRL_VDE 0x00100000
+#define LCD_CTRL_LPE 0x00400000 /* LCD Power enable */
+#define LCD_CTRL_BLE 0x00800000 /* LCD backlight enable */
+
+#define VGA_PALETTE_BASE (IO_VIRT + 0x10800)
diff --git a/arch/arm/mach-h720x/include/mach/h7202-regs.h b/arch/arm/mach-h720x/include/mach/h7202-regs.h
new file mode 100644
index 00000000..17c12eb3
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/h7202-regs.h
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-h720x/include/mach/h7202-regs.h
+ *
+ * Copyright (C) 2000 Jungjun Kim, Hynix Semiconductor Inc.
+ * (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * (C) 2004 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This file contains the hardware definitions of the h720x processors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Do not add implementations specific defines here. This files contains
+ * only defines of the onchip peripherals. Add those defines to boards.h,
+ * which is included by this file.
+ */
+
+#define SERIAL2_OFS 0x2d000
+#define SERIAL2_BASE (IO_PHYS + SERIAL2_OFS)
+#define SERIAL2_VIRT (IO_VIRT + SERIAL2_OFS)
+#define SERIAL3_OFS 0x2e000
+#define SERIAL3_BASE (IO_PHYS + SERIAL3_OFS)
+#define SERIAL3_VIRT (IO_VIRT + SERIAL3_OFS)
+
+/* Matrix Keyboard Controller */
+#define KBD_VIRT (IO_VIRT + 0x22000)
+#define KBD_KBCR 0x00
+#define KBD_KBSC 0x04
+#define KBD_KBTR 0x08
+#define KBD_KBVR0 0x0C
+#define KBD_KBVR1 0x10
+#define KBD_KBSR 0x18
+
+#define KBD_KBCR_SCANENABLE (1 << 7)
+#define KBD_KBCR_NPOWERDOWN (1 << 2)
+#define KBD_KBCR_CLKSEL_MASK (3)
+#define KBD_KBCR_CLKSEL_PCLK2 0x0
+#define KBD_KBCR_CLKSEL_PCLK128 0x1
+#define KBD_KBCR_CLKSEL_PCLK256 0x2
+#define KBD_KBCR_CLKSEL_PCLK512 0x3
+
+#define KBD_KBSR_INTR (1 << 0)
+#define KBD_KBSR_WAKEUP (1 << 1)
+
+/* USB device controller */
+
+#define USBD_BASE (IO_VIRT + 0x12000)
+#define USBD_LENGTH 0x3C
+
+#define USBD_GCTRL 0x00
+#define USBD_EPCTRL 0x04
+#define USBD_INTMASK 0x08
+#define USBD_INTSTAT 0x0C
+#define USBD_PWR 0x10
+#define USBD_DMARXTX 0x14
+#define USBD_DEVID 0x18
+#define USBD_DEVCLASS 0x1C
+#define USBD_INTCLASS 0x20
+#define USBD_SETUP0 0x24
+#define USBD_SETUP1 0x28
+#define USBD_ENDP0RD 0x2C
+#define USBD_ENDP0WT 0x30
+#define USBD_ENDP1RD 0x34
+#define USBD_ENDP2WT 0x38
+
+/* PS/2 port */
+#define PSDATA 0x00
+#define PSSTAT 0x04
+#define PSSTAT_TXEMPTY (1<<0)
+#define PSSTAT_TXBUSY (1<<1)
+#define PSSTAT_RXFULL (1<<2)
+#define PSSTAT_RXBUSY (1<<3)
+#define PSSTAT_CLKIN (1<<4)
+#define PSSTAT_DATAIN (1<<5)
+#define PSSTAT_PARITY (1<<6)
+
+#define PSCONF 0x08
+#define PSCONF_ENABLE (1<<0)
+#define PSCONF_TXINTEN (1<<2)
+#define PSCONF_RXINTEN (1<<3)
+#define PSCONF_FORCECLKLOW (1<<4)
+#define PSCONF_FORCEDATLOW (1<<5)
+#define PSCONF_LCE (1<<6)
+
+#define PSINTR 0x0C
+#define PSINTR_TXINT (1<<0)
+#define PSINTR_RXINT (1<<1)
+#define PSINTR_PAR (1<<2)
+#define PSINTR_RXTO (1<<3)
+#define PSINTR_TXTO (1<<4)
+
+#define PSTDLO 0x10 /* clk low before start transmission */
+#define PSTPRI 0x14 /* PRI clock */
+#define PSTXMT 0x18 /* maximum transmission time */
+#define PSTREC 0x20 /* maximum receive time */
+#define PSPWDN 0x3c
+
+/* ADC converter */
+#define ADC_BASE (IO_VIRT + 0x29000)
+#define ADC_CR 0x00
+#define ADC_TSCTRL 0x04
+#define ADC_BT_CTRL 0x08
+#define ADC_MC_CTRL 0x0C
+#define ADC_STATUS 0x10
+
+/* ADC control register bits */
+#define ADC_CR_PW_CTRL 0x80
+#define ADC_CR_DIRECTC 0x04
+#define ADC_CR_CONTIME_NO 0x00
+#define ADC_CR_CONTIME_2 0x04
+#define ADC_CR_CONTIME_4 0x08
+#define ADC_CR_CONTIME_ADE 0x0c
+#define ADC_CR_LONGCALTIME 0x01
+
+/* ADC touch panel register bits */
+#define ADC_TSCTRL_ENABLE 0x80
+#define ADC_TSCTRL_INTR 0x40
+#define ADC_TSCTRL_SWBYPSS 0x20
+#define ADC_TSCTRL_SWINVT 0x10
+#define ADC_TSCTRL_S400 0x03
+#define ADC_TSCTRL_S200 0x02
+#define ADC_TSCTRL_S100 0x01
+#define ADC_TSCTRL_S50 0x00
+
+/* ADC Interrupt Status Register bits */
+#define ADC_STATUS_TS_BIT 0x80
+#define ADC_STATUS_MBT_BIT 0x40
+#define ADC_STATUS_BBT_BIT 0x20
+#define ADC_STATUS_MIC_BIT 0x10
+
+/* Touch data registers */
+#define ADC_TS_X0X1 0x30
+#define ADC_TS_X2X3 0x34
+#define ADC_TS_Y0Y1 0x38
+#define ADC_TS_Y2Y3 0x3c
+#define ADC_TS_X4X5 0x40
+#define ADC_TS_X6X7 0x44
+#define ADC_TS_Y4Y5 0x48
+#define ADC_TS_Y6Y7 0x50
+
+/* battery data */
+#define ADC_MB_DATA 0x54
+#define ADC_BB_DATA 0x58
+
+/* Sound data register */
+#define ADC_SD_DAT0 0x60
+#define ADC_SD_DAT1 0x64
+#define ADC_SD_DAT2 0x68
+#define ADC_SD_DAT3 0x6c
+#define ADC_SD_DAT4 0x70
+#define ADC_SD_DAT5 0x74
+#define ADC_SD_DAT6 0x78
+#define ADC_SD_DAT7 0x7c
diff --git a/arch/arm/mach-h720x/include/mach/hardware.h b/arch/arm/mach-h720x/include/mach/hardware.h
new file mode 100644
index 00000000..c55a52c6
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/hardware.h
@@ -0,0 +1,190 @@
+/*
+ * arch/arm/mach-h720x/include/mach/hardware.h
+ *
+ * Copyright (C) 2000 Jungjun Kim, Hynix Semiconductor Inc.
+ * (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ * (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * This file contains the hardware definitions of the h720x processors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Do not add implementations specific defines here. This files contains
+ * only defines of the onchip peripherals. Add those defines to boards.h,
+ * which is included by this file.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#define IOCLK (3686400L)
+
+/* Onchip peripherals */
+
+#define IO_VIRT 0xf0000000 /* IO peripherals */
+#define IO_PHYS 0x80000000
+#define IO_SIZE 0x00050000
+
+#ifdef CONFIG_CPU_H7202
+#include "h7202-regs.h"
+#elif defined CONFIG_CPU_H7201
+#include "h7201-regs.h"
+#else
+#error machine definition mismatch
+#endif
+
+/* Macro to access the CPU IO */
+#define CPU_IO(x) (*(volatile u32*)(x))
+
+/* Macro to access general purpose regs (base, offset) */
+#define CPU_REG(x,y) CPU_IO(x+y)
+
+/* Macro to access irq related regs */
+#define IRQ_REG(x) CPU_REG(IRQC_VIRT,x)
+
+/* CPU registers */
+/* general purpose I/O */
+#define GPIO_VIRT(x) (IO_VIRT + 0x23000 + ((x)<<5))
+#define GPIO_A_VIRT (GPIO_VIRT(0))
+#define GPIO_B_VIRT (GPIO_VIRT(1))
+#define GPIO_C_VIRT (GPIO_VIRT(2))
+#define GPIO_D_VIRT (GPIO_VIRT(3))
+#define GPIO_E_VIRT (GPIO_VIRT(4))
+#define GPIO_AMULSEL (GPIO_VIRT(0) + 0xA4)
+
+#define AMULSEL_USIN2 (1<<5)
+#define AMULSEL_USOUT2 (1<<6)
+#define AMULSEL_USIN3 (1<<13)
+#define AMULSEL_USOUT3 (1<<14)
+#define AMULSEL_IRDIN (1<<15)
+#define AMULSEL_IRDOUT (1<<7)
+
+/* Register offsets general purpose I/O */
+#define GPIO_DATA 0x00
+#define GPIO_DIR 0x04
+#define GPIO_MASK 0x08
+#define GPIO_STAT 0x0C
+#define GPIO_EDGE 0x10
+#define GPIO_CLR 0x14
+#define GPIO_POL 0x18
+#define GPIO_EN 0x1C
+
+/*interrupt controller */
+#define IRQC_VIRT (IO_VIRT + 0x24000)
+/* register offset interrupt controller */
+#define IRQC_IER 0x00
+#define IRQC_ISR 0x04
+
+/* timer unit */
+#define TIMER_VIRT (IO_VIRT + 0x25000)
+/* Register offsets timer unit */
+#define TM0_PERIOD 0x00
+#define TM0_COUNT 0x08
+#define TM0_CTRL 0x10
+#define TM1_PERIOD 0x20
+#define TM1_COUNT 0x28
+#define TM1_CTRL 0x30
+#define TM2_PERIOD 0x40
+#define TM2_COUNT 0x48
+#define TM2_CTRL 0x50
+#define TIMER_TOPCTRL 0x60
+#define TIMER_TOPSTAT 0x64
+#define T64_COUNTL 0x80
+#define T64_COUNTH 0x84
+#define T64_CTRL 0x88
+#define T64_BASEL 0x94
+#define T64_BASEH 0x98
+/* Bitmaks timer unit TOPSTAT reg */
+#define TSTAT_T0INT 0x1
+#define TSTAT_T1INT 0x2
+#define TSTAT_T2INT 0x4
+#define TSTAT_T3INT 0x8
+/* Bit description of TMx_CTRL register */
+#define TM_START 0x1
+#define TM_REPEAT 0x2
+#define TM_RESET 0x4
+/* Bit description of TIMER_CTRL register */
+#define ENABLE_TM0_INTR 0x1
+#define ENABLE_TM1_INTR 0x2
+#define ENABLE_TM2_INTR 0x4
+#define TIMER_ENABLE_BIT 0x8
+#define ENABLE_TIMER64 0x10
+#define ENABLE_TIMER64_INT 0x20
+
+/* PMU & PLL */
+#define PMU_BASE (IO_VIRT + 0x1000)
+#define PMU_MODE 0x00
+#define PMU_STAT 0x20
+#define PMU_PLL_CTRL 0x28
+
+/* PMU Mode bits */
+#define PMU_MODE_SLOW 0x00
+#define PMU_MODE_RUN 0x01
+#define PMU_MODE_IDLE 0x02
+#define PMU_MODE_SLEEP 0x03
+#define PMU_MODE_INIT 0x04
+#define PMU_MODE_DEEPSLEEP 0x07
+#define PMU_MODE_WAKEUP 0x08
+
+/* PMU ... */
+#define PLL_2_EN 0x8000
+#define PLL_1_EN 0x4000
+#define PLL_3_MUTE 0x0080
+
+/* Control bits for PMU/ PLL */
+#define PMU_WARMRESET 0x00010000
+#define PLL_CTRL_MASK23 0x000080ff
+
+/* LCD Controller */
+#define LCD_BASE (IO_VIRT + 0x10000)
+#define LCD_CTRL 0x00
+#define LCD_STATUS 0x04
+#define LCD_STATUS_M 0x08
+#define LCD_INTERRUPT 0x0C
+#define LCD_DBAR 0x10
+#define LCD_DCAR 0x14
+#define LCD_TIMING0 0x20
+#define LCD_TIMING1 0x24
+#define LCD_TIMING2 0x28
+#define LCD_TEST 0x40
+
+/* LCD Control Bits */
+#define LCD_CTRL_LCD_ENABLE 0x00000001
+/* Bits per pixel */
+#define LCD_CTRL_LCD_BPP_MASK 0x00000006
+#define LCD_CTRL_LCD_4BPP 0x00000000
+#define LCD_CTRL_LCD_8BPP 0x00000002
+#define LCD_CTRL_LCD_16BPP 0x00000004
+#define LCD_CTRL_LCD_BW 0x00000008
+#define LCD_CTRL_LCD_TFT 0x00000010
+#define LCD_CTRL_BGR 0x00001000
+#define LCD_CTRL_LCD_VCOMP 0x00080000
+#define LCD_CTRL_LCD_MONO8 0x00200000
+#define LCD_CTRL_LCD_PWR 0x00400000
+#define LCD_CTRL_LCD_BLE 0x00800000
+#define LCD_CTRL_LDBUSEN 0x01000000
+
+/* Palette */
+#define LCD_PALETTE_BASE (IO_VIRT + 0x10400)
+
+/* Serial ports */
+#define SERIAL0_OFS 0x20000
+#define SERIAL0_VIRT (IO_VIRT + SERIAL0_OFS)
+#define SERIAL0_BASE (IO_PHYS + SERIAL0_OFS)
+
+#define SERIAL1_OFS 0x21000
+#define SERIAL1_VIRT (IO_VIRT + SERIAL1_OFS)
+#define SERIAL1_BASE (IO_PHYS + SERIAL1_OFS)
+
+#define SERIAL_ENABLE 0x30
+#define SERIAL_ENABLE_EN (1<<0)
+
+/* General defines to pacify gcc */
+
+#define __ASM_ARCH_HARDWARE_INCMACH_H
+#include "boards.h"
+#undef __ASM_ARCH_HARDWARE_INCMACH_H
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-h720x/include/mach/io.h b/arch/arm/mach-h720x/include/mach/io.h
new file mode 100644
index 00000000..2c8659c2
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-h720x/include/mach/io.h
+ *
+ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ *
+ * Changelog:
+ *
+ * 09-19-2001 JJKIM
+ * Created from arch/arm/mach-l7200/include/mach/io.h
+ *
+ * 03-27-2003 Robert Schwebel <r.schwebel@pengutronix.de>:
+ * re-unified header files for h720x
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/irqs.h b/arch/arm/mach-h720x/include/mach/irqs.h
new file mode 100644
index 00000000..430a92b4
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/irqs.h
@@ -0,0 +1,116 @@
+/*
+ * arch/arm/mach-h720x/include/mach/irqs.h
+ *
+ * Copyright (C) 2000 Jungjun Kim
+ * (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de>
+ * (C) 2003 Thomas Gleixner <tglx@linutronix.de>
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#if defined (CONFIG_CPU_H7201)
+
+#define IRQ_PMU 0 /* 0x000001 */
+#define IRQ_DMA 1 /* 0x000002 */
+#define IRQ_LCD 2 /* 0x000004 */
+#define IRQ_VGA 3 /* 0x000008 */
+#define IRQ_PCMCIA1 4 /* 0x000010 */
+#define IRQ_PCMCIA2 5 /* 0x000020 */
+#define IRQ_AFE 6 /* 0x000040 */
+#define IRQ_AIC 7 /* 0x000080 */
+#define IRQ_KEYBOARD 8 /* 0x000100 */
+#define IRQ_TIMER0 9 /* 0x000200 */
+#define IRQ_RTC 10 /* 0x000400 */
+#define IRQ_SOUND 11 /* 0x000800 */
+#define IRQ_USB 12 /* 0x001000 */
+#define IRQ_IrDA 13 /* 0x002000 */
+#define IRQ_UART0 14 /* 0x004000 */
+#define IRQ_UART1 15 /* 0x008000 */
+#define IRQ_SPI 16 /* 0x010000 */
+#define IRQ_GPIOA 17 /* 0x020000 */
+#define IRQ_GPIOB 18 /* 0x040000 */
+#define IRQ_GPIOC 19 /* 0x080000 */
+#define IRQ_GPIOD 20 /* 0x100000 */
+#define IRQ_CommRX 21 /* 0x200000 */
+#define IRQ_CommTX 22 /* 0x400000 */
+#define IRQ_Soft 23 /* 0x800000 */
+
+#define NR_GLBL_IRQS 24
+
+#define IRQ_CHAINED_GPIOA(x) (NR_GLBL_IRQS + x)
+#define IRQ_CHAINED_GPIOB(x) (IRQ_CHAINED_GPIOA(32) + x)
+#define IRQ_CHAINED_GPIOC(x) (IRQ_CHAINED_GPIOB(32) + x)
+#define IRQ_CHAINED_GPIOD(x) (IRQ_CHAINED_GPIOC(32) + x)
+#define NR_IRQS IRQ_CHAINED_GPIOD(32)
+
+/* Enable mask for multiplexed interrupts */
+#define IRQ_ENA_MUX (1<<IRQ_GPIOA) | (1<<IRQ_GPIOB) \
+ | (1<<IRQ_GPIOC) | (1<<IRQ_GPIOD)
+
+
+#elif defined (CONFIG_CPU_H7202)
+
+#define IRQ_PMU 0 /* 0x00000001 */
+#define IRQ_DMA 1 /* 0x00000002 */
+#define IRQ_LCD 2 /* 0x00000004 */
+#define IRQ_SOUND 3 /* 0x00000008 */
+#define IRQ_I2S 4 /* 0x00000010 */
+#define IRQ_USB 5 /* 0x00000020 */
+#define IRQ_MMC 6 /* 0x00000040 */
+#define IRQ_RTC 7 /* 0x00000080 */
+#define IRQ_UART0 8 /* 0x00000100 */
+#define IRQ_UART1 9 /* 0x00000200 */
+#define IRQ_UART2 10 /* 0x00000400 */
+#define IRQ_UART3 11 /* 0x00000800 */
+#define IRQ_KBD 12 /* 0x00001000 */
+#define IRQ_PS2 13 /* 0x00002000 */
+#define IRQ_AIC 14 /* 0x00004000 */
+#define IRQ_TIMER0 15 /* 0x00008000 */
+#define IRQ_TIMERX 16 /* 0x00010000 */
+#define IRQ_WDT 17 /* 0x00020000 */
+#define IRQ_CAN0 18 /* 0x00040000 */
+#define IRQ_CAN1 19 /* 0x00080000 */
+#define IRQ_EXT0 20 /* 0x00100000 */
+#define IRQ_EXT1 21 /* 0x00200000 */
+#define IRQ_GPIOA 22 /* 0x00400000 */
+#define IRQ_GPIOB 23 /* 0x00800000 */
+#define IRQ_GPIOC 24 /* 0x01000000 */
+#define IRQ_GPIOD 25 /* 0x02000000 */
+#define IRQ_GPIOE 26 /* 0x04000000 */
+#define IRQ_COMMRX 27 /* 0x08000000 */
+#define IRQ_COMMTX 28 /* 0x10000000 */
+#define IRQ_SMC 29 /* 0x20000000 */
+#define IRQ_Soft 30 /* 0x40000000 */
+#define IRQ_RESERVED1 31 /* 0x80000000 */
+#define NR_GLBL_IRQS 32
+
+#define NR_TIMERX_IRQS 3
+
+#define IRQ_CHAINED_GPIOA(x) (NR_GLBL_IRQS + x)
+#define IRQ_CHAINED_GPIOB(x) (IRQ_CHAINED_GPIOA(32) + x)
+#define IRQ_CHAINED_GPIOC(x) (IRQ_CHAINED_GPIOB(32) + x)
+#define IRQ_CHAINED_GPIOD(x) (IRQ_CHAINED_GPIOC(32) + x)
+#define IRQ_CHAINED_GPIOE(x) (IRQ_CHAINED_GPIOD(32) + x)
+#define IRQ_CHAINED_TIMERX(x) (IRQ_CHAINED_GPIOE(32) + x)
+#define IRQ_TIMER1 (IRQ_CHAINED_TIMERX(0))
+#define IRQ_TIMER2 (IRQ_CHAINED_TIMERX(1))
+#define IRQ_TIMER64B (IRQ_CHAINED_TIMERX(2))
+
+#define NR_IRQS (IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS))
+
+/* Enable mask for multiplexed interrupts */
+#define IRQ_ENA_MUX (1<<IRQ_TIMERX) | (1<<IRQ_GPIOA) | (1<<IRQ_GPIOB) | \
+ (1<<IRQ_GPIOC) | (1<<IRQ_GPIOD) | (1<<IRQ_GPIOE) | \
+ (1<<IRQ_TIMERX)
+
+#else
+#error cpu definition mismatch
+#endif
+
+/* decode irq number to register number */
+#define IRQ_TO_REGNO(irq) ((irq - NR_GLBL_IRQS) >> 5)
+#define IRQ_TO_BIT(irq) (1 << ((irq - NR_GLBL_IRQS) % 32))
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/isa-dma.h b/arch/arm/mach-h720x/include/mach/isa-dma.h
new file mode 100644
index 00000000..3eafb3f1
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/isa-dma.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-h720x/include/mach/isa-dma.h
+ *
+ * Architecture DMA routes
+ *
+ * Copyright (C) 1997.1998 Russell King
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#if defined (CONFIG_CPU_H7201)
+#define MAX_DMA_CHANNELS 3
+#elif defined (CONFIG_CPU_H7202)
+#define MAX_DMA_CHANNELS 4
+#else
+#error processor definition missmatch
+#endif
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-h720x/include/mach/memory.h b/arch/arm/mach-h720x/include/mach/memory.h
new file mode 100644
index 00000000..b0b3baec
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/memory.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-h720x/include/mach/memory.h
+ *
+ * Copyright (c) 2000 Jungjun Kim
+ *
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x40000000)
+/*
+ * This is the maximum DMA address that can be DMAd to.
+ * There should not be more than (0xd0000000 - 0xc0000000)
+ * bytes of RAM.
+ */
+#define ARM_DMA_ZONE_SIZE SZ_256M
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h
new file mode 100644
index 00000000..a708d24e
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/system.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-h720x/include/mach/system.h
+ *
+ * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ * arch/arm/mach-h720x/include/mach/system.h
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <mach/hardware.h>
+
+static void arch_idle(void)
+{
+ CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
+ nop();
+ nop();
+ CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
+ nop();
+ nop();
+}
+
+
+static __inline__ void arch_reset(char mode, const char *cmd)
+{
+ CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
+}
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/timex.h b/arch/arm/mach-h720x/include/mach/timex.h
new file mode 100644
index 00000000..3f2f447f
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/timex.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-h720x/include/mach/timex.h
+ * Copyright (C) 2000 Jungjun Kim, Hynix Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_TIMEX
+#define __ASM_ARCH_TIMEX
+
+#define CLOCK_TICK_RATE 3686400
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/uncompress.h b/arch/arm/mach-h720x/include/mach/uncompress.h
new file mode 100644
index 00000000..d6623234
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-h720x/include/mach/uncompress.h
+ *
+ * Copyright (C) 2001-2002 Jungjun Kim
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/hardware.h>
+
+#define LSR 0x14
+#define TEMPTY 0x40
+
+static inline void putc(int c)
+{
+ volatile unsigned char *p = (volatile unsigned char *)(IO_PHYS+0x20000);
+
+ /* wait until transmit buffer is empty */
+ while((p[LSR] & TEMPTY) == 0x0)
+ barrier();
+
+ /* write next character */
+ *p = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-h720x/include/mach/vmalloc.h b/arch/arm/mach-h720x/include/mach/vmalloc.h
new file mode 100644
index 00000000..8520b4a4
--- /dev/null
+++ b/arch/arm/mach-h720x/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-h720x/include/mach/vmalloc.h
+ */
+
+#ifndef __ARCH_ARM_VMALLOC_H
+#define __ARCH_ARM_VMALLOC_H
+
+#define VMALLOC_END 0xd0000000UL
+
+#endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
new file mode 100755
index 00000000..edc9a61c
--- /dev/null
+++ b/arch/arm/mach-imx/Kconfig
@@ -0,0 +1,608 @@
+config IMX_HAVE_DMA_V1
+ bool
+#
+# ARCH_MX31 and ARCH_MX35 are left for compatibility
+# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
+# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
+# more sensible) names are used: SOC_IMX31 and SOC_IMX35
+config ARCH_MX31
+ bool
+
+config ARCH_MX35
+ bool
+
+config SOC_IMX1
+ bool
+ select CPU_ARM920T
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+config SOC_IMX21
+ bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+
+config SOC_IMX25
+ bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_MXC_IOMUX_V3
+ select MXC_AVIC
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_MXC_PWM
+
+config SOC_IMX27
+ bool
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ select MXC_AVIC
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_MXC_PWM
+
+config SOC_IMX31
+ bool
+ select CPU_V6
+ select IMX_HAVE_PLATFORM_MXC_RNGA
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_MX31
+ select MXC_AVIC
+
+config SOC_IMX35
+ bool
+ select CPU_V6
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select HAVE_EPIT
+ select ARCH_MX35
+ select MXC_AVIC
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_MXC_PWM
+
+
+if ARCH_MX1
+
+comment "MX1 platforms:"
+config MACH_MXLADS
+ bool
+
+config ARCH_MX1ADS
+ bool "MX1ADS platform"
+ select MACH_MXLADS
+ select SOC_IMX1
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Say Y here if you are using Motorola MX1ADS/MXLADS boards
+
+config MACH_SCB9328
+ bool "Synertronixx scb9328"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Say Y here if you are using a Synertronixx scb9328 board
+
+config MACH_APF9328
+ bool "APF9328"
+ select SOC_IMX1
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Say Yes here if you are using the Armadeus APF9328 development board
+
+endif
+
+if ARCH_MX2
+
+choice
+ prompt "CPUs:"
+ default MACH_MX21
+
+config MACH_MX21
+ bool "i.MX21 support"
+ help
+ This enables support for Freescale's MX2 based i.MX21 processor.
+
+config MACH_MX27
+ bool "i.MX27 support"
+ help
+ This enables support for Freescale's MX2 based i.MX27 processor.
+
+endchoice
+
+endif
+
+if MACH_MX21
+
+comment "MX21 platforms:"
+
+config MACH_MX21ADS
+ bool "MX21ADS platform"
+ select SOC_IMX21
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ help
+ Include support for MX21ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
+
+if ARCH_MX25
+
+comment "MX25 platforms:"
+
+config MACH_MX25_3DS
+ bool "Support MX25PDK (3DS) Platform"
+ select SOC_IMX25
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMXDI_RTC
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+
+config MACH_EUKREA_CPUIMX25
+ bool "Support Eukrea CPUIMX25 Platform"
+ select SOC_IMX25
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMXDI_RTC
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_ULPI if USB_ULPI
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX25
+ default MACH_EUKREA_MBIMXSD25_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD25_BASEBOARD
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+endif
+
+if MACH_MX27
+
+comment "MX27 platforms:"
+
+config MACH_MX27ADS
+ bool "MX27ADS platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
+ help
+ Include support for MX27ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_PCM038
+ bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for phyCORE-i.MX27 (aka pcm038) platform. This
+ includes specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_PCM038
+ default MACH_PCM970_BASEBOARD
+
+config MACH_PCM970_BASEBOARD
+ bool "PHYTEC PCM970 development board"
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ help
+ This adds board specific devices that can be found on Phytec's
+ PCM970 evaluation board.
+
+endchoice
+
+config MACH_CPUIMX27
+ bool "Eukrea CPUIMX27 module"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Eukrea CPUIMX27 platform. This includes
+ specific configurations for the module and its peripherals.
+
+config MACH_EUKREA_CPUIMX27_USESDHC2
+ bool "CPUIMX27 integrates SDHC2 module"
+ depends on MACH_CPUIMX27
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ help
+ This adds support for the internal SDHC2 used on CPUIMX27
+ for wifi or eMMC.
+
+config MACH_EUKREA_CPUIMX27_USEUART4
+ bool "CPUIMX27 integrates UART4 module"
+ depends on MACH_CPUIMX27
+ help
+ This adds support for the internal UART4 used on CPUIMX27
+ for bluetooth.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_CPUIMX27
+ default MACH_EUKREA_MBIMX27_BASEBOARD
+
+config MACH_EUKREA_MBIMX27_BASEBOARD
+ bool "Eukrea MBIMX27 development board"
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMX27 evaluation board.
+
+endchoice
+
+config MACH_MX27_3DS
+ bool "MX27PDK platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_DEBUG_BOARD
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for MX27PDK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_IMX27_VISSTRIM_M10
+ bool "Vista Silicon i.MX27 Visstrim_m10"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ help
+ Include support for Visstrim_m10 platform and its different variants.
+ This includes specific configurations for the board and its
+ peripherals.
+
+config MACH_IMX27LITE
+ bool "LogicPD MX27 LITEKIT platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ help
+ Include support for MX27 LITEKIT platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_PCA100
+ bool "Phytec phyCARD-s (pca100)"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for phyCARD-s (aka pca100) platform. This
+ includes specific configurations for the module and its peripherals.
+
+config MACH_MXT_TD60
+ bool "Maxtrack i-MXT TD60"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX_FB
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ help
+ Include support for i-MXT (aka td60) platform. This
+ includes specific configurations for the module and its peripherals.
+
+config MACH_IMX27IPCAM
+ bool "IMX27 IPCAM platform"
+ select SOC_IMX27
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for IMX27 IPCAM platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
+
+if ARCH_MX3
+
+comment "MX31 platforms:"
+
+config MACH_MX31ADS
+ bool "Support MX31ADS platforms"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ default y
+ help
+ Include support for MX31ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX31ADS_WM1133_EV1
+ bool "Support Wolfson Microelectronics 1133-EV1 module"
+ depends on MACH_MX31ADS
+ depends on MFD_WM8350_I2C
+ depends on REGULATOR_WM8350
+ select MFD_WM8350_CONFIG_MODE_0
+ select MFD_WM8352_CONFIG_MODE_0
+ help
+ Include support for the Wolfson Microelectronics 1133-EV1 PMU
+ and audio module for the MX31ADS platform.
+
+config MACH_MX31LILLY
+ bool "Support MX31 LILLY-1131 platforms (INCO startec)"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for mx31 based LILLY1131 modules. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_MX31LITE
+ bool "Support MX31 LITEKIT (LogicPD)"
+ select SOC_IMX31
+ select MXC_ULPI if USB_ULPI
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_RTC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for MX31 LITEKIT platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_PCM037
+ bool "Support Phytec pcm037 (i.MX31) platforms"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_MXC_W1
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Phytec pcm037 platform. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_PCM037_EET
+ bool "Support pcm037 EET board extensions"
+ depends on MACH_PCM037
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Add support for PCM037 EET baseboard extensions. If you are using the
+ OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel
+ command-line parameter.
+
+config MACH_MX31_3DS
+ bool "Support MX31PDK (3DS)"
+ select SOC_IMX31
+ select MXC_DEBUG_BOARD
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for MX31PDK (3DS) platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+ bool "Make the MXC NAND driver use the in flash Bad Block Table"
+ depends on MACH_MX31_3DS
+ depends on MTD_NAND_MXC
+ help
+ Enable this if you want that the MXC NAND driver uses the in flash
+ Bad Block Table to know what blocks are bad instead of scanning the
+ entire flash looking for bad block markers.
+
+config MACH_MX31MOBOARD
+ bool "Support mx31moboard platforms (EPFL Mobots group)"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for mx31moboard platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_QONG
+ bool "Support Dave/DENX QongEVB-LITE platform"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for Dave/DENX QongEVB-LITE platform. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_ARMADILLO5X0
+ bool "Support Atmark Armadillo-500 Development Base Board"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_MMC
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Atmark Armadillo-500 platform. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_KZM_ARM11_01
+ bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Include support for KZM-ARM11-01. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_BUG
+ bool "Support Buglabs BUGBase platform"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ default y
+ help
+ Include support for BUGBase 1.3 platform. This includes specific
+ configurations for the board and its peripherals.
+
+comment "MX35 platforms:"
+
+config MACH_PCM043
+ bool "Support Phytec pcm043 (i.MX35) platforms"
+ select SOC_IMX35
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Phytec pcm043 platform. This includes
+ specific configurations for the board and its peripherals.
+
+config MACH_MX35_3DS
+ bool "Support MX35PDK platform"
+ select SOC_IMX35
+ select MXC_DEBUG_BOARD
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ help
+ Include support for MX35PDK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_EUKREA_CPUIMX35
+ bool "Support Eukrea CPUIMX35 Platform"
+ select SOC_IMX35
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Eukrea CPUIMX35 platform. This includes
+ specific configurations for the board and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX35
+ default MACH_EUKREA_MBIMXSD35_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD35_BASEBOARD
+ bool "Eukrea MBIMXSD development board"
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+config MACH_VPR200
+ bool "Support VPR200 platform"
+ select SOC_IMX35
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IPU_CORE
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ help
+ Include support for VPR200 platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
new file mode 100644
index 00000000..e9eb36da
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile
@@ -0,0 +1,63 @@
+obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
+
+obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
+obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
+
+obj-$(CONFIG_ARCH_MX25) += clock-imx25.o mm-imx25.o ehci-imx25.o
+
+obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
+obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
+
+obj-$(CONFIG_SOC_IMX31) += mm-imx31.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx35.o cpu-imx35.o clock-imx35.o ehci-imx35.o
+obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
+
+# Support for CMOS sensor interface
+obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
+
+# i.MX1 based machines
+obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
+obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o
+
+# i.MX21 based machines
+obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
+
+# i.MX25 based machines
+obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
+
+# i.MX27 based machines
+obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
+obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
+obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
+obj-$(CONFIG_MACH_MX27_3DS) += mach-mx27_3ds.o
+obj-$(CONFIG_MACH_IMX27LITE) += mach-imx27lite.o
+obj-$(CONFIG_MACH_IMX27_VISSTRIM_M10) += mach-imx27_visstrim_m10.o
+obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
+obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
+obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
+obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
+obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o
+
+# i.MX31 based machines
+obj-$(CONFIG_MACH_MX31ADS) += mach-mx31ads.o
+obj-$(CONFIG_MACH_MX31LILLY) += mach-mx31lilly.o mx31lilly-db.o
+obj-$(CONFIG_MACH_MX31LITE) += mach-mx31lite.o mx31lite-db.o
+obj-$(CONFIG_MACH_PCM037) += mach-pcm037.o
+obj-$(CONFIG_MACH_PCM037_EET) += mach-pcm037_eet.o
+obj-$(CONFIG_MACH_MX31_3DS) += mach-mx31_3ds.o
+obj-$(CONFIG_MACH_MX31MOBOARD) += mach-mx31moboard.o mx31moboard-devboard.o \
+ mx31moboard-marxbot.o mx31moboard-smartbot.o
+obj-$(CONFIG_MACH_QONG) += mach-qong.o
+obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o
+obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o
+obj-$(CONFIG_MACH_BUG) += mach-bug.o
+
+# i.MX35 based machines
+obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o
+obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
+obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
new file mode 100644
index 00000000..ebee18b3
--- /dev/null
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -0,0 +1,19 @@
+zreladdr-$(CONFIG_ARCH_MX1) := 0x08008000
+params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
+initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
+
+zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
+params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
+initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
+
+zreladdr-$(CONFIG_ARCH_MX25) := 0x80008000
+params_phys-$(CONFIG_ARCH_MX25) := 0x80000100
+initrd_phys-$(CONFIG_ARCH_MX25) := 0x80800000
+
+zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
+params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
+initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
+
+zreladdr-$(CONFIG_ARCH_MX3) := 0x80008000
+params_phys-$(CONFIG_ARCH_MX3) := 0x80000100
+initrd_phys-$(CONFIG_ARCH_MX3) := 0x80800000
diff --git a/arch/arm/mach-imx/cache-l2x0.c b/arch/arm/mach-imx/cache-l2x0.c
new file mode 100644
index 00000000..69d1322a
--- /dev/null
+++ b/arch/arm/mach-imx/cache-l2x0.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ * Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/hardware.h>
+
+static int mxc_init_l2x0(void)
+{
+ void __iomem *l2x0_base;
+ void __iomem *clkctl_base;
+
+ if (!cpu_is_mx31() && !cpu_is_mx35())
+ return 0;
+
+/*
+ * First of all, we must repair broken chip settings. There are some
+ * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
+ * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
+ * Workaraound is to setup the correct register setting prior enabling the
+ * L2 cache. This should not hurt already working CPUs, as they are using the
+ * same value.
+ */
+#define L2_MEM_VAL 0x10
+
+ clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
+ if (clkctl_base != NULL) {
+ writel(0x00000515, clkctl_base + L2_MEM_VAL);
+ iounmap(clkctl_base);
+ } else {
+ pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
+ }
+
+ l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
+ if (IS_ERR(l2x0_base)) {
+ printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
+ PTR_ERR(l2x0_base));
+ return 0;
+ }
+
+ l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+
+ return 0;
+}
+arch_initcall(mxc_init_l2x0);
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
new file mode 100644
index 00000000..dcc41728
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/math64.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
+
+/* CCM register addresses */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_PCDR IO_ADDR_CCM(0x20)
+
+#define CCM_CSCR_CLKO_OFFSET 29
+#define CCM_CSCR_CLKO_MASK (0x7 << 29)
+#define CCM_CSCR_USB_OFFSET 26
+#define CCM_CSCR_USB_MASK (0x7 << 26)
+#define CCM_CSCR_OSC_EN_SHIFT 17
+#define CCM_CSCR_SYSTEM_SEL (1 << 16)
+#define CCM_CSCR_BCLK_OFFSET 10
+#define CCM_CSCR_BCLK_MASK (0xf << 10)
+#define CCM_CSCR_PRESC (1 << 15)
+
+#define CCM_PCDR_PCLK3_OFFSET 16
+#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
+#define CCM_PCDR_PCLK2_OFFSET 4
+#define CCM_PCDR_PCLK2_MASK (0xf << 4)
+#define CCM_PCDR_PCLK1_OFFSET 0
+#define CCM_PCDR_PCLK1_MASK 0xf
+
+#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
+
+/* SCM register addresses */
+#define SCM_GCCR IO_ADDR_SCM(0xc)
+
+#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
+#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
+#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
+#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
+
+static int _clk_enable(struct clk *clk)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ unsigned int reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size,
+ struct clk *parent)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ if (parent == clk_arr[i])
+ return i;
+
+ return -EINVAL;
+}
+
+static unsigned long
+_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit)
+{
+ int div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > limit)
+ div = limit;
+
+ return parent_rate / div;
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->set_rate(clk->parent, rate);
+}
+
+static unsigned long clk16m_get_rate(struct clk *clk)
+{
+ return 16000000;
+}
+
+static struct clk clk16m = {
+ .get_rate = clk16m_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = CCM_CSCR,
+ .enable_shift = CCM_CSCR_OSC_EN_SHIFT,
+ .disable = _clk_disable,
+};
+
+/* in Hz */
+static unsigned long clk32_rate;
+
+static unsigned long clk32_get_rate(struct clk *clk)
+{
+ return clk32_rate;
+}
+
+static struct clk clk32 = {
+ .get_rate = clk32_get_rate,
+};
+
+static unsigned long clk32_premult_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) * 512;
+}
+
+static struct clk clk32_premult = {
+ .parent = &clk32,
+ .get_rate = clk32_premult_get_rate,
+};
+
+static const struct clk *prem_clk_clocks[] = {
+ &clk32_premult,
+ &clk16m,
+};
+
+static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int i;
+ unsigned int reg = __raw_readl(CCM_CSCR);
+
+ i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks),
+ parent);
+
+ switch (i) {
+ case 0:
+ reg &= ~CCM_CSCR_SYSTEM_SEL;
+ break;
+ case 1:
+ reg |= CCM_CSCR_SYSTEM_SEL;
+ break;
+ default:
+ return i;
+ }
+
+ __raw_writel(reg, CCM_CSCR);
+
+ return 0;
+}
+
+static struct clk prem_clk = {
+ .set_parent = prem_clk_set_parent,
+};
+
+static unsigned long system_clk_get_rate(struct clk *clk)
+{
+ return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
+ clk_get_rate(clk->parent));
+}
+
+static struct clk system_clk = {
+ .parent = &prem_clk,
+ .get_rate = system_clk_get_rate,
+};
+
+static unsigned long mcu_clk_get_rate(struct clk *clk)
+{
+ return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
+ clk_get_rate(clk->parent));
+}
+
+static struct clk mcu_clk = {
+ .parent = &clk32_premult,
+ .get_rate = mcu_clk_get_rate,
+};
+
+static unsigned long fclk_get_rate(struct clk *clk)
+{
+ unsigned long fclk = clk_get_rate(clk->parent);
+
+ if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC)
+ fclk /= 2;
+
+ return fclk;
+}
+
+static struct clk fclk = {
+ .parent = &mcu_clk,
+ .get_rate = fclk_get_rate,
+};
+
+/*
+ * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
+ */
+static unsigned long hclk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
+ CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1);
+}
+
+static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_simple_round_rate(clk, rate, 16);
+}
+
+static int hclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ unsigned int reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 16 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_BCLK_MASK;
+ reg |= div << CCM_CSCR_BCLK_OFFSET;
+ __raw_writel(reg, CCM_CSCR);
+
+ return 0;
+}
+
+static struct clk hclk = {
+ .parent = &system_clk,
+ .get_rate = hclk_get_rate,
+ .round_rate = hclk_round_rate,
+ .set_rate = hclk_set_rate,
+};
+
+static unsigned long clk48m_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
+ CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1);
+}
+
+static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_simple_round_rate(clk, rate, 8);
+}
+
+static int clk48m_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ unsigned int reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_USB_MASK;
+ reg |= div << CCM_CSCR_USB_OFFSET;
+ __raw_writel(reg, CCM_CSCR);
+
+ return 0;
+}
+
+static struct clk clk48m = {
+ .parent = &system_clk,
+ .get_rate = clk48m_get_rate,
+ .round_rate = clk48m_round_rate,
+ .set_rate = clk48m_set_rate,
+};
+
+/*
+ * get peripheral clock 1 ( UART[12], Timer[12], PWM )
+ */
+static unsigned long perclk1_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
+ CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1);
+}
+
+static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_simple_round_rate(clk, rate, 16);
+}
+
+static int perclk1_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ unsigned int reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 16 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_PCDR);
+ reg &= ~CCM_PCDR_PCLK1_MASK;
+ reg |= div << CCM_PCDR_PCLK1_OFFSET;
+ __raw_writel(reg, CCM_PCDR);
+
+ return 0;
+}
+
+/*
+ * get peripheral clock 2 ( LCD, SD, SPI[12] )
+ */
+static unsigned long perclk2_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
+ CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1);
+}
+
+static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_simple_round_rate(clk, rate, 16);
+}
+
+static int perclk2_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ unsigned int reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 16 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_PCDR);
+ reg &= ~CCM_PCDR_PCLK2_MASK;
+ reg |= div << CCM_PCDR_PCLK2_OFFSET;
+ __raw_writel(reg, CCM_PCDR);
+
+ return 0;
+}
+
+/*
+ * get peripheral clock 3 ( SSI )
+ */
+static unsigned long perclk3_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
+ CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1);
+}
+
+static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_simple_round_rate(clk, rate, 128);
+}
+
+static int perclk3_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ unsigned int reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 128 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_PCDR);
+ reg &= ~CCM_PCDR_PCLK3_MASK;
+ reg |= div << CCM_PCDR_PCLK3_OFFSET;
+ __raw_writel(reg, CCM_PCDR);
+
+ return 0;
+}
+
+static struct clk perclk[] = {
+ {
+ .id = 0,
+ .parent = &system_clk,
+ .get_rate = perclk1_get_rate,
+ .round_rate = perclk1_round_rate,
+ .set_rate = perclk1_set_rate,
+ }, {
+ .id = 1,
+ .parent = &system_clk,
+ .get_rate = perclk2_get_rate,
+ .round_rate = perclk2_round_rate,
+ .set_rate = perclk2_set_rate,
+ }, {
+ .id = 2,
+ .parent = &system_clk,
+ .get_rate = perclk3_get_rate,
+ .round_rate = perclk3_round_rate,
+ .set_rate = perclk3_set_rate,
+ }
+};
+
+static const struct clk *clko_clocks[] = {
+ &perclk[0],
+ &hclk,
+ &clk48m,
+ &clk16m,
+ &prem_clk,
+ &fclk,
+};
+
+static int clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ int i;
+ unsigned int reg;
+
+ i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent);
+ if (i < 0)
+ return i;
+
+ reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK;
+ reg |= i << CCM_CSCR_CLKO_OFFSET;
+ __raw_writel(reg, CCM_CSCR);
+
+ if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) {
+ clk->set_rate = _clk_parent_set_rate;
+ clk->round_rate = _clk_parent_round_rate;
+ } else {
+ clk->set_rate = NULL;
+ clk->round_rate = NULL;
+ }
+
+ return 0;
+}
+
+static struct clk clko_clk = {
+ .set_parent = clko_set_parent,
+};
+
+static struct clk dma_clk = {
+ .parent = &hclk,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = SCM_GCCR,
+ .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk csi_clk = {
+ .parent = &hclk,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = SCM_GCCR,
+ .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk mma_clk = {
+ .parent = &hclk,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = SCM_GCCR,
+ .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk usbd_clk = {
+ .parent = &clk48m,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = SCM_GCCR,
+ .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpt_clk = {
+ .parent = &perclk[0],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk uart_clk = {
+ .parent = &perclk[0],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk i2c_clk = {
+ .parent = &hclk,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk spi_clk = {
+ .parent = &perclk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk sdhc_clk = {
+ .parent = &perclk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk lcdc_clk = {
+ .parent = &perclk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk mshc_clk = {
+ .parent = &hclk,
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk ssi_clk = {
+ .parent = &perclk[2],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+};
+
+static struct clk rtc_clk = {
+ .parent = &clk32,
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+static struct clk_lookup lookups[] __initdata = {
+ _REGISTER_CLOCK(NULL, "dma", dma_clk)
+ _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK(NULL, "mma", mma_clk)
+ _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+ _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
+ _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
+ _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+ _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
+ _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
+};
+
+int __init mx1_clocks_init(unsigned long fref)
+{
+ unsigned int reg;
+
+ /* disable clocks we are able to */
+ __raw_writel(0, SCM_GCCR);
+
+ clk32_rate = fref;
+ reg = __raw_readl(CCM_CSCR);
+
+ /* detect clock reference for system PLL */
+ if (reg & CCM_CSCR_SYSTEM_SEL) {
+ prem_clk.parent = &clk16m;
+ } else {
+ /* ensure that oscillator is disabled */
+ reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT);
+ __raw_writel(reg, CCM_CSCR);
+ prem_clk.parent = &clk32_premult;
+ }
+
+ /* detect reference for CLKO */
+ reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
+ clko_clk.parent = (struct clk *)clko_clocks[reg];
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ clk_enable(&hclk);
+ clk_enable(&fclk);
+
+ mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
+ MX1_TIM1_INT);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
new file mode 100644
index 00000000..bf30a8c7
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -0,0 +1,1239 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/div64.h>
+
+#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
+
+#define CCM_CSCR_PRESC_OFFSET 29
+#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
+
+#define CCM_CSCR_USB_OFFSET 26
+#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
+#define CCM_CSCR_SD_OFFSET 24
+#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
+#define CCM_CSCR_SPLLRES (1 << 22)
+#define CCM_CSCR_MPLLRES (1 << 21)
+#define CCM_CSCR_SSI2_OFFSET 20
+#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
+#define CCM_CSCR_SSI1_OFFSET 19
+#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
+#define CCM_CSCR_FIR_OFFSET 18
+#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+#define CCM_CSCR_BCLK_OFFSET 10
+#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
+#define CCM_CSCR_IPDIV_OFFSET 9
+#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
+
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN 1
+
+#define CCM_MPCTL0_CPLM (1 << 31)
+#define CCM_MPCTL0_PD_OFFSET 26
+#define CCM_MPCTL0_PD_MASK (0xf << 26)
+#define CCM_MPCTL0_MFD_OFFSET 16
+#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_MPCTL0_MFI_OFFSET 10
+#define CCM_MPCTL0_MFI_MASK (0xf << 10)
+#define CCM_MPCTL0_MFN_OFFSET 0
+#define CCM_MPCTL0_MFN_MASK 0x3ff
+
+#define CCM_MPCTL1_LF (1 << 15)
+#define CCM_MPCTL1_BRMO (1 << 6)
+
+#define CCM_SPCTL0_CPLM (1 << 31)
+#define CCM_SPCTL0_PD_OFFSET 26
+#define CCM_SPCTL0_PD_MASK (0xf << 26)
+#define CCM_SPCTL0_MFD_OFFSET 16
+#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_SPCTL0_MFI_OFFSET 10
+#define CCM_SPCTL0_MFI_MASK (0xf << 10)
+#define CCM_SPCTL0_MFN_OFFSET 0
+#define CCM_SPCTL0_MFN_MASK 0x3ff
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+#define CCM_OSC26MCTL_PEAK_OFFSET 16
+#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
+#define CCM_OSC26MCTL_AGC_OFFSET 8
+#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
+#define CCM_OSC26MCTL_ANATEST_OFFSET 0
+#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
+
+#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
+#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
+#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
+#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
+#define CCM_PCDR0_NFCDIV_OFFSET 12
+#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
+#define CCM_PCDR0_48MDIV_OFFSET 5
+#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
+#define CCM_PCDR0_FIRIDIV_OFFSET 0
+#define CCM_PCDR0_FIRIDIV_MASK 0x1f
+#define CCM_PCDR1_PERDIV4_OFFSET 24
+#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
+#define CCM_PCDR1_PERDIV3_OFFSET 16
+#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
+#define CCM_PCDR1_PERDIV2_OFFSET 8
+#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
+#define CCM_PCDR1_PERDIV1_OFFSET 0
+#define CCM_PCDR1_PERDIV1_MASK 0x3f
+
+#define CCM_PCCR_HCLK_CSI_OFFSET 31
+#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_DMA_OFFSET 30
+#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BROM_OFFSET 28
+#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_EMMA_OFFSET 27
+#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_LCDC_OFFSET 26
+#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
+#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
+#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_HCLK_BMI_OFFSET 23
+#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
+#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
+#define CCM_PCCR_PERCLK4_OFFSET 22
+#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
+#define CCM_PCCR_SLCDC_OFFSET 21
+#define CCM_PCCR_SLCDC_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_BAUD_OFFSET 20
+#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
+#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_NFC_OFFSET 19
+#define CCM_PCCR_NFC_REG CCM_PCCR0
+#define CCM_PCCR_LCDC_OFFSET 18
+#define CCM_PCCR_LCDC_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_BAUD_OFFSET 17
+#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_BAUD_OFFSET 16
+#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
+#define CCM_PCCR_EMMA_OFFSET 15
+#define CCM_PCCR_EMMA_REG CCM_PCCR0
+#define CCM_PCCR_USBOTG_OFFSET 14
+#define CCM_PCCR_USBOTG_REG CCM_PCCR0
+#define CCM_PCCR_DMA_OFFSET 13
+#define CCM_PCCR_DMA_REG CCM_PCCR0
+#define CCM_PCCR_I2C1_OFFSET 12
+#define CCM_PCCR_I2C1_REG CCM_PCCR0
+#define CCM_PCCR_GPIO_OFFSET 11
+#define CCM_PCCR_GPIO_REG CCM_PCCR0
+#define CCM_PCCR_SDHC2_OFFSET 10
+#define CCM_PCCR_SDHC2_REG CCM_PCCR0
+#define CCM_PCCR_SDHC1_OFFSET 9
+#define CCM_PCCR_SDHC1_REG CCM_PCCR0
+#define CCM_PCCR_FIRI_OFFSET 8
+#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
+#define CCM_PCCR_FIRI_REG CCM_PCCR0
+#define CCM_PCCR_SSI2_IPG_OFFSET 7
+#define CCM_PCCR_SSI2_REG CCM_PCCR0
+#define CCM_PCCR_SSI1_IPG_OFFSET 6
+#define CCM_PCCR_SSI1_REG CCM_PCCR0
+#define CCM_PCCR_CSPI2_OFFSET 5
+#define CCM_PCCR_CSPI2_REG CCM_PCCR0
+#define CCM_PCCR_CSPI1_OFFSET 4
+#define CCM_PCCR_CSPI1_REG CCM_PCCR0
+#define CCM_PCCR_UART4_OFFSET 3
+#define CCM_PCCR_UART4_REG CCM_PCCR0
+#define CCM_PCCR_UART3_OFFSET 2
+#define CCM_PCCR_UART3_REG CCM_PCCR0
+#define CCM_PCCR_UART2_OFFSET 1
+#define CCM_PCCR_UART2_REG CCM_PCCR0
+#define CCM_PCCR_UART1_OFFSET 0
+#define CCM_PCCR_UART1_REG CCM_PCCR0
+
+#define CCM_PCCR_OWIRE_OFFSET 31
+#define CCM_PCCR_OWIRE_REG CCM_PCCR1
+#define CCM_PCCR_KPP_OFFSET 30
+#define CCM_PCCR_KPP_REG CCM_PCCR1
+#define CCM_PCCR_RTC_OFFSET 29
+#define CCM_PCCR_RTC_REG CCM_PCCR1
+#define CCM_PCCR_PWM_OFFSET 28
+#define CCM_PCCR_PWM_REG CCM_PCCR1
+#define CCM_PCCR_GPT3_OFFSET 27
+#define CCM_PCCR_GPT3_REG CCM_PCCR1
+#define CCM_PCCR_GPT2_OFFSET 26
+#define CCM_PCCR_GPT2_REG CCM_PCCR1
+#define CCM_PCCR_GPT1_OFFSET 25
+#define CCM_PCCR_GPT1_REG CCM_PCCR1
+#define CCM_PCCR_WDT_OFFSET 24
+#define CCM_PCCR_WDT_REG CCM_PCCR1
+#define CCM_PCCR_CSPI3_OFFSET 23
+#define CCM_PCCR_CSPI3_REG CCM_PCCR1
+
+#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
+#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
+#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
+#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
+#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
+#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
+#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
+#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
+#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
+#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
+#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
+#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
+#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
+#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
+#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
+#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
+#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
+#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
+#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
+#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
+#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
+#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
+#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
+#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
+#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
+#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
+#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
+#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
+#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
+#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
+#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
+#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
+#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
+#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
+#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
+#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
+#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
+
+#define CCM_CCSR_32KSR (1 << 15)
+
+#define CCM_CCSR_CLKMODE1 (1 << 9)
+#define CCM_CCSR_CLKMODE0 (1 << 8)
+
+#define CCM_CCSR_CLKOSEL_OFFSET 0
+#define CCM_CCSR_CLKOSEL_MASK 0x1f
+
+#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long _clk_generic_round_rate(struct clk *clk,
+ unsigned long rate,
+ u32 max_divisor)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > max_divisor)
+ div = max_divisor;
+
+ return parent_rate / div;
+}
+
+static int _clk_spll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg |= CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+
+ while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
+ ;
+ return 0;
+}
+
+static void _clk_spll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+}
+
+
+#define CSCR() (__raw_readl(CCM_CSCR))
+#define PCDR0() (__raw_readl(CCM_PCDR0))
+#define PCDR1() (__raw_readl(CCM_PCDR1))
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ return _clk_generic_round_rate(clk, rate, 64);
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return -EINVAL;
+
+ div = parent_rate / rate;
+ if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg =
+ __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
+ (clk->id << 3));
+ reg |= div << (clk->id << 3);
+ __raw_writel(reg, CCM_PCDR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usb_recalc(struct clk *clk)
+{
+ unsigned long usb_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+
+ return parent_rate / (usb_pdf + 1U);
+}
+
+static unsigned long _clk_usb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ return _clk_generic_round_rate(clk, rate, 8);
+}
+
+static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg = CSCR() & ~CCM_CSCR_USB_MASK;
+ reg |= div << CCM_CSCR_USB_OFFSET;
+ __raw_writel(reg, CCM_CSCR);
+
+ return 0;
+}
+
+static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
+{
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
+
+ return 2UL * parent_rate / pdf;
+}
+
+static unsigned long _clk_ssi1_recalc(struct clk *clk)
+{
+ return _clk_ssix_recalc(clk,
+ (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
+ >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_ssi2_recalc(struct clk *clk)
+{
+ return _clk_ssix_recalc(clk,
+ (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
+ CCM_PCDR0_SSI2BAUDDIV_OFFSET);
+}
+
+static unsigned long _clk_nfc_recalc(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
+ >> CCM_PCDR0_NFCDIV_OFFSET;
+
+ return parent_rate / (nfc_pdf + 1);
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->set_rate(clk->parent, rate);
+}
+
+static unsigned long external_high_reference; /* in Hz */
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz.
+ */
+static struct clk ckih_clk = {
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static unsigned long external_low_reference; /* in Hz */
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+ .get_rate = get_low_reference_clock_rate,
+};
+
+
+static unsigned long _clk_fpm_recalc(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) * 512;
+}
+
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+ .parent = &ckil_clk,
+ .get_rate = _clk_fpm_recalc,
+};
+
+static unsigned long get_mpll_clk(struct clk *clk)
+{
+ uint32_t reg;
+ unsigned long ref_clk;
+ unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+ unsigned long long temp;
+
+ ref_clk = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(CCM_MPCTL0);
+ pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
+
+ mfi = (mfi <= 5) ? 5 : mfi;
+ temp = 2LL * ref_clk * mfn;
+ do_div(temp, mfd + 1);
+ temp = 2LL * ref_clk * mfi + temp;
+ do_div(temp, pdf + 1);
+
+ return (unsigned long)temp;
+}
+
+static struct clk mpll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_mpll_clk,
+};
+
+static unsigned long _clk_fclk_get_rate(struct clk *clk)
+{
+ unsigned long parent_rate;
+ u32 div;
+
+ div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+ parent_rate = clk_get_rate(clk->parent);
+
+ return parent_rate / (div+1);
+}
+
+static struct clk fclk_clk = {
+ .parent = &mpll_clk,
+ .get_rate = _clk_fclk_get_rate
+};
+
+static unsigned long get_spll_clk(struct clk *clk)
+{
+ uint32_t reg;
+ unsigned long ref_clk;
+ unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+ unsigned long long temp;
+
+ ref_clk = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(CCM_SPCTL0);
+ pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
+
+ mfi = (mfi <= 5) ? 5 : mfi;
+ temp = 2LL * ref_clk * mfn;
+ do_div(temp, mfd + 1);
+ temp = 2LL * ref_clk * mfi + temp;
+ do_div(temp, pdf + 1);
+
+ return (unsigned long)temp;
+}
+
+static struct clk spll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_spll_clk,
+ .enable = _clk_spll_enable,
+ .disable = _clk_spll_disable,
+};
+
+static unsigned long get_hclk_clk(struct clk *clk)
+{
+ unsigned long rate;
+ unsigned long bclk_pdf;
+
+ bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
+ >> CCM_CSCR_BCLK_OFFSET;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (bclk_pdf + 1);
+}
+
+static struct clk hclk_clk = {
+ .parent = &fclk_clk,
+ .get_rate = get_hclk_clk,
+};
+
+static unsigned long get_ipg_clk(struct clk *clk)
+{
+ unsigned long rate;
+ unsigned long ipg_pdf;
+
+ ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (ipg_pdf + 1);
+}
+
+static struct clk ipg_clk = {
+ .parent = &hclk_clk,
+ .get_rate = get_ipg_clk,
+};
+
+static unsigned long _clk_perclkx_recalc(struct clk *clk)
+{
+ unsigned long perclk_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return 0;
+
+ perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+
+ return parent_rate / (perclk_pdf + 1);
+}
+
+static struct clk per_clk[] = {
+ {
+ .id = 0,
+ .parent = &mpll_clk,
+ .get_rate = _clk_perclkx_recalc,
+ }, {
+ .id = 1,
+ .parent = &mpll_clk,
+ .get_rate = _clk_perclkx_recalc,
+ }, {
+ .id = 2,
+ .parent = &mpll_clk,
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .get_rate = _clk_perclkx_recalc,
+ /* Enable/Disable done via lcd_clkc[1] */
+ }, {
+ .id = 3,
+ .parent = &mpll_clk,
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .get_rate = _clk_perclkx_recalc,
+ /* Enable/Disable done via csi_clk[1] */
+ },
+};
+
+static struct clk uart_ipg_clk[];
+
+static struct clk uart_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[2],
+ }, {
+ .id = 3,
+ .parent = &per_clk[0],
+ .secondary = &uart_ipg_clk[3],
+ },
+};
+
+static struct clk uart_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART1_REG,
+ .enable_shift = CCM_PCCR_UART1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART2_REG,
+ .enable_shift = CCM_PCCR_UART2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART3_REG,
+ .enable_shift = CCM_PCCR_UART3_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_UART4_REG,
+ .enable_shift = CCM_PCCR_UART4_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_ipg_clk[];
+
+static struct clk gpt_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &gpt_ipg_clk[2],
+ },
+};
+
+static struct clk gpt_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT1_REG,
+ .enable_shift = CCM_PCCR_GPT1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT2_REG,
+ .enable_shift = CCM_PCCR_GPT2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPT3_REG,
+ .enable_shift = CCM_PCCR_GPT3_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk pwm_clk[] = {
+ {
+ .parent = &per_clk[0],
+ .secondary = &pwm_clk[1],
+ }, {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_PWM_REG,
+ .enable_shift = CCM_PCCR_PWM_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk sdhc_ipg_clk[];
+
+static struct clk sdhc_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &sdhc_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &sdhc_ipg_clk[1],
+ },
+};
+
+static struct clk sdhc_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SDHC1_REG,
+ .enable_shift = CCM_PCCR_SDHC1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SDHC2_REG,
+ .enable_shift = CCM_PCCR_SDHC2_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi_ipg_clk[];
+
+static struct clk cspi_clk[] = {
+ {
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[0],
+ }, {
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[1],
+ }, {
+ .id = 2,
+ .parent = &per_clk[1],
+ .secondary = &cspi_ipg_clk[2],
+ },
+};
+
+static struct clk cspi_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI1_REG,
+ .enable_shift = CCM_PCCR_CSPI1_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI2_REG,
+ .enable_shift = CCM_PCCR_CSPI2_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_CSPI3_REG,
+ .enable_shift = CCM_PCCR_CSPI3_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk lcdc_clk[] = {
+ {
+ .parent = &per_clk[2],
+ .secondary = &lcdc_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ }, {
+ .parent = &ipg_clk,
+ .secondary = &lcdc_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_LCDC_REG,
+ .enable_shift = CCM_PCCR_LCDC_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
+ .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk csi_clk[] = {
+ {
+ .parent = &per_clk[3],
+ .secondary = &csi_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_CSI_REG,
+ .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk usb_clk[] = {
+ {
+ .parent = &spll_clk,
+ .secondary = &usb_clk[1],
+ .get_rate = _clk_usb_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_USBOTG_REG,
+ .enable_shift = CCM_PCCR_USBOTG_OFFSET,
+ .disable = _clk_disable,
+ .round_rate = _clk_usb_round_rate,
+ .set_rate = _clk_usb_set_rate,
+ }, {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
+ .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk ssi_ipg_clk[];
+
+static struct clk ssi_clk[] = {
+ {
+ .id = 0,
+ .parent = &mpll_clk,
+ .secondary = &ssi_ipg_clk[0],
+ .get_rate = _clk_ssi1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
+ .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &mpll_clk,
+ .secondary = &ssi_ipg_clk[1],
+ .get_rate = _clk_ssi2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
+ .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk ssi_ipg_clk[] = {
+ {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI1_REG,
+ .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
+ .disable = _clk_disable,
+ }, {
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SSI2_REG,
+ .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+
+static struct clk nfc_clk = {
+ .parent = &fclk_clk,
+ .get_rate = _clk_nfc_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_NFC_REG,
+ .enable_shift = CCM_PCCR_NFC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk dma_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_DMA_REG,
+ .enable_shift = CCM_PCCR_DMA_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &dma_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_DMA_REG,
+ .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk brom_clk = {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_BROM_REG,
+ .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk emma_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_EMMA_REG,
+ .enable_shift = CCM_PCCR_EMMA_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &emma_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
+ .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk slcdc_clk[] = {
+ {
+ .parent = &hclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_SLCDC_REG,
+ .enable_shift = CCM_PCCR_SLCDC_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &slcdc_clk[1],
+ }, {
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
+ .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk wdog_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_WDT_REG,
+ .enable_shift = CCM_PCCR_WDT_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpio_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_GPIO_REG,
+ .enable_shift = CCM_PCCR_GPIO_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk i2c_clk = {
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_I2C1_REG,
+ .enable_shift = CCM_PCCR_I2C1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_KPP_REG,
+ .enable_shift = CCM_PCCR_KPP_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_OWIRE_REG,
+ .enable_shift = CCM_PCCR_OWIRE_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR_RTC_REG,
+ .enable_shift = CCM_PCCR_RTC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+ return _clk_generic_round_rate(clk, rate, 8);
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg = __raw_readl(CCM_PCDR0);
+
+ if (clk->parent == &usb_clk[0]) {
+ reg &= ~CCM_PCDR0_48MDIV_MASK;
+ reg |= div << CCM_PCDR0_48MDIV_OFFSET;
+ }
+ __raw_writel(reg, CCM_PCDR0);
+
+ return 0;
+}
+
+static unsigned long _clk_clko_recalc(struct clk *clk)
+{
+ u32 div = 0;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &usb_clk[0]) /* 48M */
+ div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
+ >> CCM_PCDR0_48MDIV_OFFSET;
+ div++;
+
+ return parent_rate / div;
+}
+
+static struct clk clko_clk;
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
+
+ if (parent == &ckil_clk)
+ reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &fpm_clk)
+ reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ckih_clk)
+ reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == mpll_clk.parent)
+ reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == spll_clk.parent)
+ reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &mpll_clk)
+ reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &spll_clk)
+ reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &fclk_clk)
+ reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &hclk_clk)
+ reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ipg_clk)
+ reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[0])
+ reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[1])
+ reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[2])
+ reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &per_clk[3])
+ reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ssi_clk[0])
+ reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &ssi_clk[1])
+ reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &nfc_clk)
+ reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &usb_clk[0])
+ reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
+ else if (parent == &clko_clk)
+ reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk clko_clk = {
+ .get_rate = _clk_clko_recalc,
+ .set_rate = _clk_clko_set_rate,
+ .round_rate = _clk_clko_round_rate,
+ .set_parent = _clk_clko_set_parent,
+};
+
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+static struct clk_lookup lookups[] = {
+/* It's unlikely that any driver wants one of them directly:
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
+ _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
+ _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
+ _REGISTER_CLOCK(NULL, "spll", spll_clk)
+ _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
+ _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
+*/
+ _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
+ _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
+ _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
+ _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
+ _REGISTER_CLOCK(NULL, "clko", clko_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
+ _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
+ _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
+ _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
+ _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
+ _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
+ _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
+ _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
+ _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
+ _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
+ _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
+ _REGISTER_CLOCK(NULL, "brom", brom_clk)
+ _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
+ _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+ _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+ _REGISTER_CLOCK(NULL, "owire", owire_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+};
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx21_clocks_init(unsigned long lref, unsigned long href)
+{
+ u32 cscr;
+
+ external_low_reference = lref;
+ external_high_reference = href;
+
+ /* detect clock reference for both system PLL */
+ cscr = CSCR();
+ if (cscr & CCM_CSCR_MCU)
+ mpll_clk.parent = &ckih_clk;
+ else
+ mpll_clk.parent = &fpm_clk;
+
+ if (cscr & CCM_CSCR_SP)
+ spll_clk.parent = &ckih_clk;
+ else
+ spll_clk.parent = &fpm_clk;
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* Turn off all clock gates */
+ __raw_writel(0, CCM_PCCR0);
+ __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
+
+ /* This turns of the serial PLL as well */
+ spll_clk.disable(&spll_clk);
+
+ /* This will propagate to all children and init all the clock rates. */
+ clk_enable(&per_clk[0]);
+ clk_enable(&gpio_clk);
+
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+ clk_enable(&uart_clk[0]);
+#endif
+
+ mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
+ MX21_INT_GPT1);
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
new file mode 100644
index 00000000..a65838fc
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+
+#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+
+#define CCM_MPCTL 0x00
+#define CCM_UPCTL 0x04
+#define CCM_CCTL 0x08
+#define CCM_CGCR0 0x0C
+#define CCM_CGCR1 0x10
+#define CCM_CGCR2 0x14
+#define CCM_PCDR0 0x18
+#define CCM_PCDR1 0x1C
+#define CCM_PCDR2 0x20
+#define CCM_PCDR3 0x24
+#define CCM_RCSR 0x28
+#define CCM_CRDR 0x2C
+#define CCM_DCVR0 0x30
+#define CCM_DCVR1 0x34
+#define CCM_DCVR2 0x38
+#define CCM_DCVR3 0x3c
+#define CCM_LTR0 0x40
+#define CCM_LTR1 0x44
+#define CCM_LTR2 0x48
+#define CCM_LTR3 0x4c
+
+static unsigned long get_rate_mpll(void)
+{
+ ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
+
+ return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_upll(void)
+{
+ ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
+
+ return mxc_decode_pll(mpctl, 24000000);
+}
+
+unsigned long get_rate_arm(struct clk *clk)
+{
+ unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ unsigned long rate = get_rate_mpll();
+
+ if (cctl & (1 << 14))
+ rate = (rate * 3) >> 2;
+
+ return rate / ((cctl >> 30) + 1);
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+ unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+
+ return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+ return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_rate_per(int per)
+{
+ unsigned long ofs = (per & 0x3) * 8;
+ unsigned long reg = per & ~0x3;
+ unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
+ unsigned long fref;
+
+ if (readl(CRM_BASE + 0x64) & (1 << per))
+ fref = get_rate_upll();
+ else
+ fref = get_rate_ahb(NULL);
+
+ return fref / (val + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+ return get_rate_per(15);
+}
+
+static unsigned long get_rate_ssi2(struct clk *clk)
+{
+ return get_rate_per(14);
+}
+
+static unsigned long get_rate_ssi1(struct clk *clk)
+{
+ return get_rate_per(13);
+}
+
+static unsigned long get_rate_i2c(struct clk *clk)
+{
+ return get_rate_per(6);
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+ return get_rate_per(8);
+}
+
+static unsigned long get_rate_gpt(struct clk *clk)
+{
+ return get_rate_per(5);
+}
+
+static unsigned long get_rate_lcdc(struct clk *clk)
+{
+ return get_rate_per(7);
+}
+
+static unsigned long get_rate_esdhc1(struct clk *clk)
+{
+ return get_rate_per(3);
+}
+
+static unsigned long get_rate_esdhc2(struct clk *clk)
+{
+ return get_rate_per(4);
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+ return get_rate_per(0);
+}
+
+static unsigned long get_rate_otg(struct clk *clk)
+{
+ unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ unsigned long rate = get_rate_upll();
+
+ return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
+}
+
+static int clk_cgcr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void clk_cgcr_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = CRM_BASE + er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = clk_cgcr_enable, \
+ .disable = clk_cgcr_disable, \
+ .secondary = s, \
+ }
+
+/*
+ * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
+ * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
+ * taken from the Freescale released BSP.
+ *
+ * bit reg offset clock
+ *
+ * 0 CGCR1 0 AUDMUX
+ * 12 CGCR1 12 ESAI
+ * 16 CGCR1 16 GPIO1
+ * 17 CGCR1 17 GPIO2
+ * 18 CGCR1 18 GPIO3
+ * 23 CGCR1 23 I2C1
+ * 24 CGCR1 24 I2C2
+ * 25 CGCR1 25 I2C3
+ * 27 CGCR1 27 IOMUXC
+ * 28 CGCR1 28 KPP
+ * 30 CGCR1 30 OWIRE
+ * 36 CGCR2 4 RTIC
+ * 51 CGCR2 19 WDOG
+ */
+
+DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
+DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
+DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
+DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
+ &esdhc1_ahb_clk);
+DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
+DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
+ &esdhc2_ahb_clk);
+DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
+DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
+DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
+DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
+DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
+DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
+DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
+DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
+DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
+DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
+DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
+DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
+DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
+DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
+ &esdhc1_per_clk);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
+ &esdhc2_per_clk);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
+DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
+DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
+ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
+ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
+ _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
+ _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+ _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
+ _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+};
+
+int __init mx25_clocks_init(void)
+{
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* Turn off all clocks except the ones we need to survive, namely:
+ * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
+ * SCC
+ */
+ __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
+ __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
+ __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+ clk_enable(&uart1_clk);
+#endif
+
+ /* Clock source for lcdc and csi is upll */
+ __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
+ CRM_BASE + 0x64);
+
+ mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
new file mode 100644
index 00000000..583f2515
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -0,0 +1,763 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+
+#include <asm/div64.h>
+
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
+
+/* Register offsets */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
+#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
+#define CCM_PCDR0 IO_ADDR_CCM(0x18)
+#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
+#define CCM_PCCR0 IO_ADDR_CCM(0x20)
+#define CCM_PCCR1 IO_ADDR_CCM(0x24)
+#define CCM_CCSR IO_ADDR_CCM(0x28)
+#define CCM_PMCTL IO_ADDR_CCM(0x2c)
+#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
+#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
+
+#define CCM_CSCR_UPDATE_DIS (1 << 31)
+#define CCM_CSCR_SSI2 (1 << 23)
+#define CCM_CSCR_SSI1 (1 << 22)
+#define CCM_CSCR_VPU (1 << 21)
+#define CCM_CSCR_MSHC (1 << 20)
+#define CCM_CSCR_SPLLRES (1 << 19)
+#define CCM_CSCR_MPLLRES (1 << 18)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN (1 << 0)
+
+/* i.MX27 TO 2+ */
+#define CCM_CSCR_ARM_SRC (1 << 15)
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+static struct clk mpll_main1_clk, mpll_main2_clk;
+
+static int clk_pccr_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ if (!clk->enable_reg)
+ return 0;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void clk_pccr_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ if (!clk->enable_reg)
+ return;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int clk_spll_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg |= CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+
+ while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
+
+ return 0;
+}
+
+static void clk_spll_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+}
+
+static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
+{
+ int cscr = __raw_readl(CCM_CSCR);
+
+ if (clk->parent == parent)
+ return 0;
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ if (parent == &mpll_main1_clk) {
+ cscr |= CCM_CSCR_ARM_SRC;
+ } else {
+ if (parent == &mpll_main2_clk)
+ cscr &= ~CCM_CSCR_ARM_SRC;
+ else
+ return -EINVAL;
+ }
+ __raw_writel(cscr, CCM_CSCR);
+ clk->parent = parent;
+ return 0;
+ }
+ return -ENODEV;
+}
+
+static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
+{
+ int div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 4)
+ div = 4;
+
+ return parent_rate / div;
+}
+
+static int set_rate_cpu(struct clk *clk, unsigned long rate)
+{
+ unsigned int div;
+ uint32_t reg;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div > 4 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ div--;
+
+ reg = __raw_readl(CCM_CSCR);
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ reg &= ~(3 << 12);
+ reg |= div << 12;
+ reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
+ __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
+ } else {
+ printk(KERN_ERR "Can't set CPU frequency!\n");
+ }
+
+ return 0;
+}
+
+static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int set_rate_per(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return -EINVAL;
+
+ div = parent_rate / rate;
+ if (div > 64 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+ div--;
+
+ reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
+ reg |= div << (clk->id << 3);
+ __raw_writel(reg, CCM_PCDR1);
+
+ return 0;
+}
+
+static unsigned long get_rate_usb(struct clk *clk)
+{
+ unsigned long usb_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
+
+ return parent_rate / (usb_pdf + 1U);
+}
+
+static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
+{
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ pdf += 4; /* MX27 TO2+ */
+ else
+ pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
+
+ return 2UL * parent_rate / pdf;
+}
+
+static unsigned long get_rate_ssi1(struct clk *clk)
+{
+ return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
+}
+
+static unsigned long get_rate_ssi2(struct clk *clk)
+{
+ return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
+ else
+ nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
+
+ return parent_rate / (nfc_pdf + 1);
+}
+
+static unsigned long get_rate_vpu(struct clk *clk)
+{
+ unsigned long vpu_pdf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
+ vpu_pdf += 4;
+ } else {
+ vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
+ vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
+ }
+
+ return 2UL * parent_rate / vpu_pdf;
+}
+
+static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->round_rate(clk->parent, rate);
+}
+
+static unsigned long get_rate_parent(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static int set_rate_parent(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->set_rate(clk->parent, rate);
+}
+
+/* in Hz */
+static unsigned long external_high_reference = 26000000;
+
+static unsigned long get_rate_high_reference(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+/* in Hz */
+static unsigned long external_low_reference = 32768;
+
+static unsigned long get_rate_low_reference(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_rate_fpm(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) * 1024;
+}
+
+static unsigned long get_rate_mpll(struct clk *clk)
+{
+ return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
+ clk_get_rate(clk->parent));
+}
+
+static unsigned long get_rate_mpll_main(struct clk *clk)
+{
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ /* i.MX27 TO2:
+ * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
+ * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
+ */
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1)
+ return 2UL * parent_rate / 3UL;
+
+ return parent_rate;
+}
+
+static unsigned long get_rate_spll(struct clk *clk)
+{
+ uint32_t reg;
+ unsigned long rate;
+
+ rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(CCM_SPCTL0);
+
+ /* On TO2 we have to write the value back. Otherwise we
+ * read 0 from this register the next time.
+ */
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ __raw_writel(reg, CCM_SPCTL0);
+
+ return mxc_decode_pll(reg, rate);
+}
+
+static unsigned long get_rate_cpu(struct clk *clk)
+{
+ u32 div;
+ unsigned long rate;
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
+ else
+ div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (div + 1);
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+ unsigned long rate, bclk_pdf;
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
+ else
+ bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (bclk_pdf + 1);
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+ unsigned long rate, ipg_pdf;
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
+ return clk_get_rate(clk->parent);
+ else
+ ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
+
+ rate = clk_get_rate(clk->parent);
+ return rate / (ipg_pdf + 1);
+}
+
+static unsigned long get_rate_per(struct clk *clk)
+{
+ unsigned long perclk_pdf, parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->id < 0 || clk->id > 3)
+ return 0;
+
+ perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
+
+ return parent_rate / (perclk_pdf + 1);
+}
+
+/*
+ * the high frequency external clock reference
+ * Default case is 26MHz. Could be changed at runtime
+ * with a call to change_external_high_reference()
+ */
+static struct clk ckih_clk = {
+ .get_rate = get_rate_high_reference,
+};
+
+static struct clk mpll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_rate_mpll,
+};
+
+/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
+ * It provides the clock source whose rate is same as MPLL
+ */
+static struct clk mpll_main1_clk = {
+ .id = 0,
+ .parent = &mpll_clk,
+ .get_rate = get_rate_mpll_main,
+};
+
+/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
+ * It provides the clock source whose rate is same MPLL * 2 / 3
+ */
+static struct clk mpll_main2_clk = {
+ .id = 1,
+ .parent = &mpll_clk,
+ .get_rate = get_rate_mpll_main,
+};
+
+static struct clk ahb_clk = {
+ .parent = &mpll_main2_clk,
+ .get_rate = get_rate_ahb,
+};
+
+static struct clk ipg_clk = {
+ .parent = &ahb_clk,
+ .get_rate = get_rate_ipg,
+};
+
+static struct clk cpu_clk = {
+ .parent = &mpll_main2_clk,
+ .set_parent = clk_cpu_set_parent,
+ .round_rate = round_rate_cpu,
+ .get_rate = get_rate_cpu,
+ .set_rate = set_rate_cpu,
+};
+
+static struct clk spll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = get_rate_spll,
+ .enable = clk_spll_enable,
+ .disable = clk_spll_disable,
+};
+
+/*
+ * the low frequency external clock reference
+ * Default case is 32.768kHz.
+ */
+static struct clk ckil_clk = {
+ .get_rate = get_rate_low_reference,
+};
+
+/* Output of frequency pre multiplier */
+static struct clk fpm_clk = {
+ .parent = &ckil_clk,
+ .get_rate = get_rate_fpm,
+};
+
+#define PCCR0 CCM_PCCR0
+#define PCCR1 CCM_PCCR1
+
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .enable = clk_pccr_enable, \
+ .disable = clk_pccr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = get_rate_##getsetround, \
+ .set_rate = set_rate_##getsetround, \
+ .round_rate = round_rate_##getsetround, \
+ .enable = clk_pccr_enable, \
+ .disable = clk_pccr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+/* Forward declaration to keep the following list in order */
+static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
+ dma_clk1, lcdc_clk2, vpu_clk1;
+
+/* All clocks we can gate through PCCRx in the order of PCCRx bits */
+DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
+DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
+DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
+DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
+DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
+DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
+DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
+DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
+
+DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
+DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
+DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
+DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
+DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
+DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
+DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
+
+/* Clocks we cannot directly gate, but drivers need their rates */
+DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
+DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
+DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
+DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
+DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
+DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
+DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
+DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
+DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
+DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
+DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
+DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
+DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
+DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
+DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
+DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
+DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
+DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
+DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
+ _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
+ _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
+ _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
+ _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
+ _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
+ _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+ _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+ _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
+ _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
+ _REGISTER_CLOCK(NULL, "dma", dma_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "brom", brom_clk)
+ _REGISTER_CLOCK(NULL, "emma", emma_clk)
+ _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+};
+
+/* Adjust the clock path for TO2 and later */
+static void __init to2_adjust_clocks(void)
+{
+ unsigned long cscr = __raw_readl(CCM_CSCR);
+
+ if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
+ if (cscr & CCM_CSCR_ARM_SRC)
+ cpu_clk.parent = &mpll_main1_clk;
+
+ if (!(cscr & CCM_CSCR_SSI2))
+ ssi1_clk.parent = &spll_clk;
+
+ if (!(cscr & CCM_CSCR_SSI1))
+ ssi1_clk.parent = &spll_clk;
+
+ if (!(cscr & CCM_CSCR_VPU))
+ vpu_clk.parent = &spll_clk;
+ } else {
+ cpu_clk.parent = &mpll_clk;
+ cpu_clk.set_parent = NULL;
+ cpu_clk.round_rate = NULL;
+ cpu_clk.set_rate = NULL;
+ ahb_clk.parent = &mpll_clk;
+
+ per1_clk.parent = &mpll_clk;
+ per2_clk.parent = &mpll_clk;
+ per3_clk.parent = &mpll_clk;
+ per4_clk.parent = &mpll_clk;
+
+ ssi1_clk.parent = &mpll_clk;
+ ssi2_clk.parent = &mpll_clk;
+
+ vpu_clk.parent = &mpll_clk;
+ }
+}
+
+/*
+ * must be called very early to get information about the
+ * available clock rate when the timer framework starts
+ */
+int __init mx27_clocks_init(unsigned long fref)
+{
+ u32 cscr = __raw_readl(CCM_CSCR);
+
+ external_high_reference = fref;
+
+ /* detect clock reference for both system PLLs */
+ if (cscr & CCM_CSCR_MCU)
+ mpll_clk.parent = &ckih_clk;
+ else
+ mpll_clk.parent = &fpm_clk;
+
+ if (cscr & CCM_CSCR_SP)
+ spll_clk.parent = &ckih_clk;
+ else
+ spll_clk.parent = &fpm_clk;
+
+ to2_adjust_clocks();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* Turn off all clocks we do not need */
+ __raw_writel(0, CCM_PCCR0);
+ __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
+
+ spll_clk.disable(&spll_clk);
+
+ /* enable basic clocks */
+ clk_enable(&per1_clk);
+ clk_enable(&gpio_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&iim_clk);
+
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+ clk_enable(&uart1_clk);
+#endif
+
+ mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
+ MX27_INT_GPT1);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c
new file mode 100644
index 00000000..25f343fc
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx31.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <asm/div64.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/mx31.h>
+#include <mach/common.h>
+
+#include "crmregs-imx31.h"
+
+#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64) {
+ min_pre = (div - 1) / 64 + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div <= 8) {
+ *pre = div;
+ *post = 1;
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+static struct clk mcu_pll_clk;
+static struct clk serial_pll_clk;
+static struct clk ipg_clk;
+static struct clk ckih_clk;
+
+static int cgr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (!clk->enable_reg)
+ return 0;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 3 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void cgr_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (!clk->enable_reg)
+ return;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+
+ /* special case for EMI clock */
+ if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
+ reg |= (1 << clk->enable_shift);
+
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long pll_ref_get_rate(void)
+{
+ unsigned long ccmr;
+ unsigned int prcs;
+
+ ccmr = __raw_readl(MXC_CCM_CCMR);
+ prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
+ if (prcs == 0x1)
+ return CKIL_CLK_FREQ * 1024;
+ else
+ return clk_get_rate(&ckih_clk);
+}
+
+static unsigned long usb_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_UPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long serial_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(MXC_CCM_SRPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static unsigned long mcu_pll_get_rate(struct clk *clk)
+{
+ unsigned long reg, ccmr;
+
+ ccmr = __raw_readl(MXC_CCM_CCMR);
+
+ if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
+ return clk_get_rate(&ckih_clk);
+
+ reg = __raw_readl(MXC_CCM_MPCTL);
+
+ return mxc_decode_pll(reg, pll_ref_get_rate());
+}
+
+static int usb_pll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
+ /* No lock bit on MX31, so using max time from spec */
+ udelay(80);
+
+ return 0;
+}
+
+static void usb_pll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+static int serial_pll_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_SPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
+ /* No lock bit on MX31, so using max time from spec */
+ udelay(80);
+
+ return 0;
+}
+
+static void serial_pll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_SPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
+#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
+#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
+
+static unsigned long mcu_main_get_rate(struct clk *clk)
+{
+ u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+
+ if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
+ return clk_get_rate(&serial_pll_clk);
+ else
+ return clk_get_rate(&mcu_pll_clk);
+}
+
+static unsigned long ahb_get_rate(struct clk *clk)
+{
+ unsigned long max_pdf;
+
+ max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
+ MXC_CCM_PDR0_MAX_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (max_pdf + 1);
+}
+
+static unsigned long ipg_get_rate(struct clk *clk)
+{
+ unsigned long ipg_pdf;
+
+ ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
+ MXC_CCM_PDR0_IPG_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ipg_pdf + 1);
+}
+
+static unsigned long nfc_get_rate(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+
+ nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
+ MXC_CCM_PDR0_NFC_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (nfc_pdf + 1);
+}
+
+static unsigned long hsp_get_rate(struct clk *clk)
+{
+ unsigned long hsp_pdf;
+
+ hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
+ MXC_CCM_PDR0_HSP_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (hsp_pdf + 1);
+}
+
+static unsigned long usb_get_rate(struct clk *clk)
+{
+ unsigned long usb_pdf, usb_prepdf;
+
+ usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
+ MXC_CCM_PDR1_USB_PODF_OFFSET);
+ usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
+ MXC_CCM_PDR1_USB_PRDF_OFFSET);
+ return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
+}
+
+static unsigned long csi_get_rate(struct clk *clk)
+{
+ u32 reg, pre, post;
+
+ reg = __raw_readl(MXC_CCM_PDR0);
+ pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
+ MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+ pre++;
+ post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
+ MXC_CCM_PDR0_CSI_PODF_OFFSET;
+ post++;
+ return clk_get_rate(clk->parent) / (pre * post);
+}
+
+static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post, parent = clk_get_rate(clk->parent);
+ u32 div = parent / rate;
+
+ if (parent % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent / (pre * post);
+}
+
+static int csi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+ div = parent / rate;
+
+ if ((parent / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_PDR0) &
+ ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR0);
+
+ return 0;
+}
+
+static unsigned long ssi1_get_rate(struct clk *clk)
+{
+ unsigned long ssi1_pdf, ssi1_prepdf;
+
+ ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
+ MXC_CCM_PDR1_SSI1_PODF_OFFSET);
+ ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
+ MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
+}
+
+static unsigned long ssi2_get_rate(struct clk *clk)
+{
+ unsigned long ssi2_pdf, ssi2_prepdf;
+
+ ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
+ MXC_CCM_PDR1_SSI2_PODF_OFFSET);
+ ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
+ MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
+}
+
+static unsigned long firi_get_rate(struct clk *clk)
+{
+ unsigned long firi_pdf, firi_prepdf;
+
+ firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
+ MXC_CCM_PDR1_FIRI_PODF_OFFSET);
+ firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
+ MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
+ return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
+}
+
+static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent = clk_get_rate(clk->parent);
+ u32 div = parent / rate;
+
+ if (parent % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent / (pre * post);
+
+}
+
+static int firi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
+
+ div = parent / rate;
+
+ if ((parent / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set FIRI clock divider */
+ reg = __raw_readl(MXC_CCM_PDR1) &
+ ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
+ reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
+ reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR1);
+
+ return 0;
+}
+
+static unsigned long mbx_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static unsigned long mstick1_get_rate(struct clk *clk)
+{
+ unsigned long msti_pdf;
+
+ msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
+ MXC_CCM_PDR2_MST1_PDF_OFFSET);
+ return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long mstick2_get_rate(struct clk *clk)
+{
+ unsigned long msti_pdf;
+
+ msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
+ MXC_CCM_PDR2_MST2_PDF_OFFSET);
+ return clk_get_rate(clk->parent) / (msti_pdf + 1);
+}
+
+static unsigned long ckih_rate;
+
+static unsigned long clk_ckih_get_rate(struct clk *clk)
+{
+ return ckih_rate;
+}
+
+static unsigned long clk_ckil_get_rate(struct clk *clk)
+{
+ return CKIL_CLK_FREQ;
+}
+
+static struct clk ckih_clk = {
+ .get_rate = clk_ckih_get_rate,
+};
+
+static struct clk mcu_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = mcu_pll_get_rate,
+};
+
+static struct clk mcu_main_clk = {
+ .parent = &mcu_pll_clk,
+ .get_rate = mcu_main_get_rate,
+};
+
+static struct clk serial_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = serial_pll_get_rate,
+ .enable = serial_pll_enable,
+ .disable = serial_pll_disable,
+};
+
+static struct clk usb_pll_clk = {
+ .parent = &ckih_clk,
+ .get_rate = usb_pll_get_rate,
+ .enable = usb_pll_enable,
+ .disable = usb_pll_disable,
+};
+
+static struct clk ahb_clk = {
+ .parent = &mcu_main_clk,
+ .get_rate = ahb_get_rate,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = getsetround##_get_rate, \
+ .set_rate = getsetround##_set_rate, \
+ .round_rate = getsetround##_round_rate, \
+ .enable = cgr_enable, \
+ .disable = cgr_disable, \
+ .secondary = s, \
+ .parent = p, \
+ }
+
+DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
+
+DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
+DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
+DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
+DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
+
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
+DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
+DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
+
+DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
+DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
+DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit1_clk)
+ _REGISTER_CLOCK(NULL, "epit", epit2_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+ _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+ _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
+ _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
+ _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
+ _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK(NULL, "firi", firi_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "rng", rng_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk1)
+ _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
+ _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
+ _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
+ _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
+};
+
+int __init mx31_clocks_init(unsigned long fref)
+{
+ u32 reg;
+
+ ckih_rate = fref;
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* change the csi_clk parent if necessary */
+ reg = __raw_readl(MXC_CCM_CCMR);
+ if (!(reg & MXC_CCM_CCMR_CSCS))
+ if (clk_set_parent(&csi_clk, &usb_pll_clk))
+ pr_err("%s: error changing csi_clk parent\n", __func__);
+
+
+ /* Turn off all possible clocks */
+ __raw_writel((3 << 4), MXC_CCM_CGR0);
+ __raw_writel(0, MXC_CCM_CGR1);
+ __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
+ 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
+ MX32, but still required to be set */
+ MXC_CCM_CGR2);
+
+ /*
+ * Before turning off usb_pll make sure ipg_per_clk is generated
+ * by ipg_clk and not usb_pll.
+ */
+ __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
+
+ usb_pll_disable(&usb_pll_clk);
+
+ pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
+
+ clk_enable(&gpt_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&iim_clk);
+
+ clk_enable(&serial_pll_clk);
+
+ mx31_read_cpu_rev();
+
+ if (mx31_revision() >= IMX_CHIP_REVISION_2_0) {
+ reg = __raw_readl(MXC_CCM_PMCR1);
+ /* No PLL restart on DVFS switch; enable auto EMI handshake */
+ reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
+ __raw_writel(reg, MXC_CCM_PMCR1);
+ }
+
+ mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
+ MX31_INT_GPT);
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
new file mode 100644
index 00000000..5a4cc1ea
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx35.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define CCM_BASE MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
+
+#define CCM_CCMR 0x00
+#define CCM_PDR0 0x04
+#define CCM_PDR1 0x08
+#define CCM_PDR2 0x0C
+#define CCM_PDR3 0x10
+#define CCM_PDR4 0x14
+#define CCM_RCSR 0x18
+#define CCM_MPCTL 0x1C
+#define CCM_PPCTL 0x20
+#define CCM_ACMR 0x24
+#define CCM_COSR 0x28
+#define CCM_CGR0 0x2C
+#define CCM_CGR1 0x30
+#define CCM_CGR2 0x34
+#define CCM_CGR3 0x38
+
+#ifdef HAVE_SET_RATE_SUPPORT
+static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ min_pre = (div - 1) / maxpost + 1;
+ old_err = 8;
+
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ if (div > (temp_pre * maxpost))
+ break;
+
+ if (div < (temp_pre * temp_pre))
+ continue;
+
+ err = div % temp_pre;
+
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+
+ err = temp_pre - err;
+
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+
+ *post = (div + *pre - 1) / *pre;
+}
+
+/* get the best values for a 3-bit divider combined with a 6-bit divider */
+static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64) {
+ calc_dividers(div, pre, post, 64);
+ } else if (div <= 8) {
+ *pre = div;
+ *post = 1;
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+/* get the best values for two cascaded 3-bit dividers */
+static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 64) {
+ *pre = *post = 8;
+ } else if (div > 8) {
+ calc_dividers(div, pre, post, 8);
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+#endif
+
+static unsigned long get_rate_mpll(void)
+{
+ ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+
+ return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_ppll(void)
+{
+ ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+
+ return mxc_decode_pll(ppctl, 24000000);
+}
+
+struct arm_ahb_div {
+ unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+ { .arm = 1, .ahb = 4, .sel = 0},
+ { .arm = 1, .ahb = 3, .sel = 1},
+ { .arm = 2, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 1, .sel = 0},
+ { .arm = 1, .ahb = 5, .sel = 0},
+ { .arm = 1, .ahb = 8, .sel = 0},
+ { .arm = 1, .ahb = 6, .sel = 1},
+ { .arm = 2, .ahb = 4, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+ { .arm = 4, .ahb = 2, .sel = 0},
+ { .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static unsigned long get_rate_arm(void)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ struct arm_ahb_div *aad;
+ unsigned long fref = get_rate_mpll();
+
+ aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+ if (aad->sel)
+ fref = fref * 3 / 4;
+
+ return fref / aad->arm;
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ struct arm_ahb_div *aad;
+ unsigned long fref = get_rate_arm();
+
+ aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+
+ return fref / aad->ahb;
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+ return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+ unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+ unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+ unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
+
+ if (pdr3 & (1 << 14))
+ return get_rate_arm() / div;
+ else
+ return get_rate_ppll() / div;
+}
+
+static unsigned long get_rate_sdhc(struct clk *clk)
+{
+ unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+ unsigned long div, rate;
+
+ if (pdr3 & (1 << 6))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ switch (clk->id) {
+ default:
+ case 0:
+ div = pdr3 & 0x3f;
+ break;
+ case 1:
+ div = (pdr3 >> 8) & 0x3f;
+ break;
+ case 2:
+ div = (pdr3 >> 16) & 0x3f;
+ break;
+ }
+
+ return rate / (div + 1);
+}
+
+static unsigned long get_rate_mshc(struct clk *clk)
+{
+ unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+ unsigned long div1, div2, rate;
+
+ if (pdr1 & (1 << 7))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ div1 = (pdr1 >> 29) & 0x7;
+ div2 = (pdr1 >> 22) & 0x3f;
+
+ return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_ssi(struct clk *clk)
+{
+ unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+ unsigned long div1, div2, rate;
+
+ if (pdr2 & (1 << 6))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ switch (clk->id) {
+ default:
+ case 0:
+ div1 = pdr2 & 0x3f;
+ div2 = (pdr2 >> 24) & 0x7;
+ break;
+ case 1:
+ div1 = (pdr2 >> 8) & 0x3f;
+ div2 = (pdr2 >> 27) & 0x7;
+ break;
+ }
+
+ return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+ unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+ unsigned long rate;
+
+ if (pdr2 & (1 << 7))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ return rate / (((pdr2 >> 16) & 0x3f) + 1);
+}
+
+static unsigned long get_rate_otg(struct clk *clk)
+{
+ unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+ unsigned long rate;
+
+ if (pdr4 & (1 << 9))
+ rate = get_rate_arm();
+ else
+ rate = get_rate_ppll();
+
+ return rate / (((pdr4 >> 22) & 0x3f) + 1);
+}
+
+static unsigned long get_rate_ipg_per(struct clk *clk)
+{
+ unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+ unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+ unsigned long div;
+
+ if (pdr0 & (1 << 26)) {
+ div = (pdr4 >> 16) & 0x3f;
+ return get_rate_arm() / (div + 1);
+ } else {
+ div = (pdr0 >> 12) & 0x7;
+ return get_rate_ahb(NULL) / (div + 1);
+ }
+}
+
+static unsigned long get_rate_hsp(struct clk *clk)
+{
+ unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
+ unsigned long fref = get_rate_mpll();
+
+ if (fref > 400 * 1000 * 1000) {
+ switch (hsp_podf) {
+ case 0:
+ return fref >> 2;
+ case 1:
+ return fref >> 3;
+ case 2:
+ return fref / 3;
+ }
+ } else {
+ switch (hsp_podf) {
+ case 0:
+ case 2:
+ return fref / 3;
+ case 1:
+ return fref / 6;
+ }
+ }
+
+ return 0;
+}
+
+static int clk_cgr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 3 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void clk_cgr_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = CCM_BASE + er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = clk_cgr_enable, \
+ .disable = clk_cgr_disable, \
+ }
+
+DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL);
+DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL);
+/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); */
+DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL);
+DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL);
+DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL);
+DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL);
+DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
+DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL);
+DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
+
+DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL);
+DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL);
+DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL);
+
+DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL);
+
+static int clk_dummy_enable(struct clk *clk)
+{
+ return 0;
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+ unsigned long div1;
+
+ div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
+
+ return get_rate_ahb(NULL) / div1;
+}
+
+/* NAND Controller: It seems it can't be disabled */
+static struct clk nfc_clk = {
+ .id = 0,
+ .enable_reg = 0,
+ .enable_shift = 0,
+ .get_rate = get_rate_nfc,
+ .set_rate = NULL, /* set_rate_nfc, */
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
+ _REGISTER_CLOCK(NULL, "ata", ata_clk)
+ _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
+ _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
+ _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
+ _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
+ _REGISTER_CLOCK(NULL, "ect", ect_clk)
+ _REGISTER_CLOCK(NULL, "edio", edio_clk)
+ _REGISTER_CLOCK(NULL, "emi", emi_clk)
+ _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
+ _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
+ _REGISTER_CLOCK(NULL, "esai", esai_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
+ _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
+ _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
+ _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+ _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+ _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+ _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
+ _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+ _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
+ _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+ _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+ _REGISTER_CLOCK(NULL, "scc", scc_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+ _REGISTER_CLOCK(NULL, "spba", spba_clk)
+ _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
+ _REGISTER_CLOCK(NULL, "max", max_clk)
+ _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+ _REGISTER_CLOCK(NULL, "csi", csi_clk)
+ _REGISTER_CLOCK(NULL, "iim", iim_clk)
+ _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+ _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+};
+
+int __init mx35_clocks_init()
+{
+ unsigned int cgr2 = 3 << 26, cgr3 = 0;
+
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+ cgr2 |= 3 << 16;
+#endif
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ /* Turn off all clocks except the ones we need to survive, namely:
+ * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
+ */
+ __raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+ __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
+ CCM_BASE + CCM_CGR1);
+
+ /*
+ * Check if we came up in internal boot mode. If yes, we need some
+ * extra clocks turned on, otherwise the MX35 boot ROM code will
+ * hang after a watchdog reset.
+ */
+ if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
+ /* Additionally turn on UART1, SCC, and IIM clocks */
+ cgr2 |= 3 << 16 | 3 << 4;
+ cgr3 |= 3 << 2;
+ }
+
+ __raw_writel(cgr2, CCM_BASE + CCM_CGR2);
+ __raw_writel(cgr3, CCM_BASE + CCM_CGR3);
+
+ clk_enable(&iim_clk);
+ mx35_read_cpu_rev();
+
+#ifdef CONFIG_MXC_USE_EPIT
+ epit_timer_init(&epit1_clk,
+ MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
+ mxc_timer_init(&gpt_clk,
+ MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
+#endif
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c
new file mode 100644
index 00000000..3b117be3
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx27.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * i.MX27 specific CPU detection code
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <mach/hardware.h>
+
+static int cpu_silicon_rev = -1;
+static int cpu_partnumber;
+
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
+
+static void query_silicon_parameter(void)
+{
+ u32 val;
+ /*
+ * now we have access to the IO registers. As we need
+ * the silicon revision very early we read it here to
+ * avoid any further hooks
+ */
+ val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR
+ + SYS_CHIP_ID));
+
+ switch (val >> 28) {
+ case 0:
+ cpu_silicon_rev = IMX_CHIP_REVISION_1_0;
+ break;
+ case 1:
+ cpu_silicon_rev = IMX_CHIP_REVISION_2_0;
+ break;
+ case 2:
+ cpu_silicon_rev = IMX_CHIP_REVISION_2_1;
+ break;
+ default:
+ cpu_silicon_rev = IMX_CHIP_REVISION_UNKNOWN;
+ }
+ cpu_partnumber = (int)((val >> 12) & 0xFFFF);
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx27
+ */
+int mx27_revision(void)
+{
+ if (cpu_silicon_rev == -1)
+ query_silicon_parameter();
+
+ if (cpu_partnumber != 0x8821)
+ return -EINVAL;
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx27_revision);
diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c
new file mode 100644
index 00000000..a3780700
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx31.c
@@ -0,0 +1,57 @@
+/*
+ * MX31 CPU type detection
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/iim.h>
+
+unsigned int mx31_cpu_rev;
+EXPORT_SYMBOL(mx31_cpu_rev);
+
+static struct {
+ u8 srev;
+ const char *name;
+ const char *v;
+ unsigned int rev;
+} mx31_cpu_type[] __initdata = {
+ { .srev = 0x00, .name = "i.MX31(L)", .v = "1.0", .rev = IMX_CHIP_REVISION_1_0 },
+ { .srev = 0x10, .name = "i.MX31", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x11, .name = "i.MX31L", .v = "1.1", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x12, .name = "i.MX31", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x13, .name = "i.MX31L", .v = "1.15", .rev = IMX_CHIP_REVISION_1_1 },
+ { .srev = 0x14, .name = "i.MX31", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x15, .name = "i.MX31L", .v = "1.2", .rev = IMX_CHIP_REVISION_1_2 },
+ { .srev = 0x28, .name = "i.MX31", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 },
+ { .srev = 0x29, .name = "i.MX31L", .v = "2.0", .rev = IMX_CHIP_REVISION_2_0 },
+};
+
+void __init mx31_read_cpu_rev(void)
+{
+ u32 i, srev;
+
+ /* read SREV register from IIM module */
+ srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV));
+
+ for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
+ if (srev == mx31_cpu_type[i].srev) {
+ printk(KERN_INFO
+ "CPU identified as %s, silicon rev %s\n",
+ mx31_cpu_type[i].name, mx31_cpu_type[i].v);
+
+ mx31_cpu_rev = mx31_cpu_type[i].rev;
+ return;
+ }
+
+ mx31_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+
+ printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
+}
diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c
new file mode 100644
index 00000000..6637cd81
--- /dev/null
+++ b/arch/arm/mach-imx/cpu-imx35.c
@@ -0,0 +1,44 @@
+/*
+ * MX35 CPU type detection
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/iim.h>
+
+unsigned int mx35_cpu_rev;
+EXPORT_SYMBOL(mx35_cpu_rev);
+
+void __init mx35_read_cpu_rev(void)
+{
+ u32 rev;
+ char *srev;
+
+ rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
+ switch (rev) {
+ case 0x00:
+ mx35_cpu_rev = IMX_CHIP_REVISION_1_0;
+ srev = "1.0";
+ break;
+ case 0x10:
+ mx35_cpu_rev = IMX_CHIP_REVISION_2_0;
+ srev = "2.0";
+ break;
+ case 0x11:
+ mx35_cpu_rev = IMX_CHIP_REVISION_2_1;
+ srev = "2.1";
+ break;
+ default:
+ mx35_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+ srev = "unknown";
+ }
+
+ printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
+}
diff --git a/arch/arm/mach-imx/crmregs-imx31.h b/arch/arm/mach-imx/crmregs-imx31.h
new file mode 100644
index 00000000..37a8a07b
--- /dev/null
+++ b/arch/arm/mach-imx/crmregs-imx31.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+
+#define CKIH_CLK_FREQ 26000000
+#define CKIH_CLK_FREQ_27MHZ 27000000
+#define CKIL_CLK_FREQ 32768
+
+#define MXC_CCM_BASE MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
+
+/* Register addresses */
+#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64)
+
+/* Register bit definitions */
+#define MXC_CCM_CCMR_WBEN (1 << 27)
+#define MXC_CCM_CCMR_CSCS (1 << 25)
+#define MXC_CCM_CCMR_PERCS (1 << 24)
+#define MXC_CCM_CCMR_SSI1S_OFFSET 18
+#define MXC_CCM_CCMR_SSI1S_MASK (0x3 << 18)
+#define MXC_CCM_CCMR_SSI2S_OFFSET 21
+#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21)
+#define MXC_CCM_CCMR_LPM_OFFSET 14
+#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
+#define MXC_CCM_CCMR_FIRS_OFFSET 11
+#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11)
+#define MXC_CCM_CCMR_UPE (1 << 9)
+#define MXC_CCM_CCMR_SPE (1 << 8)
+#define MXC_CCM_CCMR_MDS (1 << 7)
+#define MXC_CCM_CCMR_SBYCS (1 << 4)
+#define MXC_CCM_CCMR_MPE (1 << 3)
+#define MXC_CCM_CCMR_PRCS_OFFSET 1
+#define MXC_CCM_CCMR_PRCS_MASK (0x3 << 1)
+
+#define MXC_CCM_PDR0_CSI_PODF_OFFSET 26
+#define MXC_CCM_PDR0_CSI_PODF_MASK (0x3F << 26)
+#define MXC_CCM_PDR0_CSI_PRDF_OFFSET 23
+#define MXC_CCM_PDR0_CSI_PRDF_MASK (0x7 << 23)
+#define MXC_CCM_PDR0_PER_PODF_OFFSET 16
+#define MXC_CCM_PDR0_PER_PODF_MASK (0x1F << 16)
+#define MXC_CCM_PDR0_HSP_PODF_OFFSET 11
+#define MXC_CCM_PDR0_HSP_PODF_MASK (0x7 << 11)
+#define MXC_CCM_PDR0_NFC_PODF_OFFSET 8
+#define MXC_CCM_PDR0_NFC_PODF_MASK (0x7 << 8)
+#define MXC_CCM_PDR0_IPG_PODF_OFFSET 6
+#define MXC_CCM_PDR0_IPG_PODF_MASK (0x3 << 6)
+#define MXC_CCM_PDR0_MAX_PODF_OFFSET 3
+#define MXC_CCM_PDR0_MAX_PODF_MASK (0x7 << 3)
+#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0
+#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7
+
+#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30
+#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30)
+#define MXC_CCM_PDR1_USB_PODF_OFFSET 27
+#define MXC_CCM_PDR1_USB_PODF_MASK (0x7 << 27)
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET 24
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK (0x7 << 24)
+#define MXC_CCM_PDR1_FIRI_PODF_OFFSET 18
+#define MXC_CCM_PDR1_FIRI_PODF_MASK (0x3F << 18)
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET 15
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK (0x7 << 15)
+#define MXC_CCM_PDR1_SSI2_PODF_OFFSET 9
+#define MXC_CCM_PDR1_SSI2_PODF_MASK (0x3F << 9)
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET 6
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK (0x7 << 6)
+#define MXC_CCM_PDR1_SSI1_PODF_OFFSET 0
+#define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F
+
+/* Bit definitions for RCSR */
+#define MXC_CCM_RCSR_NF16B 0x80000000
+
+/*
+ * LTR0 register offsets
+ */
+#define MXC_CCM_LTR0_DIV3CK_OFFSET 1
+#define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1)
+#define MXC_CCM_LTR0_DNTHR_OFFSET 16
+#define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16)
+#define MXC_CCM_LTR0_UPTHR_OFFSET 22
+#define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22)
+
+/*
+ * LTR1 register offsets
+ */
+#define MXC_CCM_LTR1_PNCTHR_OFFSET 0
+#define MXC_CCM_LTR1_PNCTHR_MASK 0x3F
+#define MXC_CCM_LTR1_UPCNT_OFFSET 6
+#define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6)
+#define MXC_CCM_LTR1_DNCNT_OFFSET 14
+#define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14)
+#define MXC_CCM_LTR1_LTBRSR_MASK 0x400000
+#define MXC_CCM_LTR1_LTBRSR_OFFSET 22
+#define MXC_CCM_LTR1_LTBRSR 0x400000
+#define MXC_CCM_LTR1_LTBRSH 0x800000
+
+/*
+ * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
+ */
+#define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3)
+#define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << \
+ MXC_CCM_LTR2_WSW_OFFSET((x)))
+#define MXC_CCM_LTR2_EMAC_OFFSET 0
+#define MXC_CCM_LTR2_EMAC_MASK 0x1FF
+
+/*
+ * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
+ */
+#define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3)
+#define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << \
+ MXC_CCM_LTR3_WSW_OFFSET((x)))
+
+#define MXC_CCM_PMCR0_DFSUP1 0x80000000
+#define MXC_CCM_PMCR0_DFSUP1_SPLL (0 << 31)
+#define MXC_CCM_PMCR0_DFSUP1_MPLL (1 << 31)
+#define MXC_CCM_PMCR0_DFSUP0 0x40000000
+#define MXC_CCM_PMCR0_DFSUP0_PLL (0 << 30)
+#define MXC_CCM_PMCR0_DFSUP0_PDR (1 << 30)
+#define MXC_CCM_PMCR0_DFSUP_MASK (0x3 << 30)
+
+#define DVSUP_TURBO 0
+#define DVSUP_HIGH 1
+#define DVSUP_MEDIUM 2
+#define DVSUP_LOW 3
+#define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28)
+#define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28)
+#define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28)
+#define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28)
+#define MXC_CCM_PMCR0_DVSUP_OFFSET 28
+#define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28)
+#define MXC_CCM_PMCR0_UDSC 0x08000000
+#define MXC_CCM_PMCR0_UDSC_MASK (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_UP (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_DOWN (0 << 27)
+
+#define MXC_CCM_PMCR0_VSCNT_1 (0x0 << 24)
+#define MXC_CCM_PMCR0_VSCNT_2 (0x1 << 24)
+#define MXC_CCM_PMCR0_VSCNT_3 (0x2 << 24)
+#define MXC_CCM_PMCR0_VSCNT_4 (0x3 << 24)
+#define MXC_CCM_PMCR0_VSCNT_5 (0x4 << 24)
+#define MXC_CCM_PMCR0_VSCNT_6 (0x5 << 24)
+#define MXC_CCM_PMCR0_VSCNT_7 (0x6 << 24)
+#define MXC_CCM_PMCR0_VSCNT_8 (0x7 << 24)
+#define MXC_CCM_PMCR0_VSCNT_OFFSET 24
+#define MXC_CCM_PMCR0_VSCNT_MASK (0x7 << 24)
+#define MXC_CCM_PMCR0_DVFEV 0x00800000
+#define MXC_CCM_PMCR0_DVFIS 0x00400000
+#define MXC_CCM_PMCR0_LBMI 0x00200000
+#define MXC_CCM_PMCR0_LBFL 0x00100000
+#define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18)
+#define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18)
+#define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18)
+#define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18)
+#define MXC_CCM_PMCR0_LBCF_OFFSET 18
+#define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18)
+#define MXC_CCM_PMCR0_PTVIS 0x00020000
+#define MXC_CCM_PMCR0_UPDTEN 0x00010000
+#define MXC_CCM_PMCR0_UPDTEN_MASK (0x1 << 16)
+#define MXC_CCM_PMCR0_FSVAIM 0x00008000
+#define MXC_CCM_PMCR0_FSVAI_OFFSET 13
+#define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13)
+#define MXC_CCM_PMCR0_DPVCR 0x00001000
+#define MXC_CCM_PMCR0_DPVV 0x00000800
+#define MXC_CCM_PMCR0_WFIM 0x00000400
+#define MXC_CCM_PMCR0_DRCE3 0x00000200
+#define MXC_CCM_PMCR0_DRCE2 0x00000100
+#define MXC_CCM_PMCR0_DRCE1 0x00000080
+#define MXC_CCM_PMCR0_DRCE0 0x00000040
+#define MXC_CCM_PMCR0_DCR 0x00000020
+#define MXC_CCM_PMCR0_DVFEN 0x00000010
+#define MXC_CCM_PMCR0_PTVAIM 0x00000008
+#define MXC_CCM_PMCR0_PTVAI_OFFSET 1
+#define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1)
+#define MXC_CCM_PMCR0_DPTEN 0x00000001
+
+#define MXC_CCM_PMCR1_DVGP_OFFSET 0
+#define MXC_CCM_PMCR1_DVGP_MASK (0xF)
+
+#define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7)
+#define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8)
+
+#define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22)
+#define MXC_CCM_DCVR_ULV_OFFSET 22
+#define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12)
+#define MXC_CCM_DCVR_LLV_OFFSET 12
+#define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2)
+#define MXC_CCM_DCVR_ELV_OFFSET 2
+
+#define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7)
+#define MXC_CCM_PDR2_MST2_PDF_OFFSET 7
+#define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F
+#define MXC_CCM_PDR2_MST1_PDF_OFFSET 0
+
+#define MXC_CCM_COSR_CLKOSEL_MASK 0x0F
+#define MXC_CCM_COSR_CLKOSEL_OFFSET 0
+#define MXC_CCM_COSR_CLKOUTDIV_MASK (0x07 << 6)
+#define MXC_CCM_COSR_CLKOUTDIV_OFFSET 6
+#define MXC_CCM_COSR_CLKOEN (1 << 9)
+
+/*
+ * PMCR0 register offsets
+ */
+#define MXC_CCM_PMCR0_LBFL_OFFSET 20
+#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
+#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
+
+#endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h
new file mode 100644
index 00000000..3aad1e70
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx1.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx_fb_data imx1_imx_fb_data;
+#define imx1_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx1_imx_fb_data, pdata)
+
+extern const struct imx_imx_i2c_data imx1_imx_i2c_data;
+#define imx1_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx1_imx_i2c_data, pdata)
+
+extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[];
+#define imx1_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_3irq(&imx1_imx_uart_data[id], pdata)
+#define imx1_add_imx_uart0(pdata) imx1_add_imx_uart(0, pdata)
+#define imx1_add_imx_uart1(pdata) imx1_add_imx_uart(1, pdata)
+
+extern const struct imx_spi_imx_data imx1_cspi_data[];
+#define imx1_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx1_cspi_data[id], pdata)
+
+#define imx1_add_spi_imx0(pdata) imx1_add_cspi(0, pdata)
+#define imx1_add_spi_imx1(pdata) imx1_add_cspi(1, pdata)
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
new file mode 100644
index 00000000..2628e0c4
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx21.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data;
+#define imx21_add_imx21_hcd(pdata) \
+ imx_add_imx21_hcd(&imx21_imx21_hcd_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx21_imx2_wdt_data;
+#define imx21_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx21_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx21_imx_fb_data;
+#define imx21_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx21_imx_fb_data, pdata)
+
+extern const struct imx_imx_i2c_data imx21_imx_i2c_data;
+#define imx21_add_imx_i2c(pdata) \
+ imx_add_imx_i2c(&imx21_imx_i2c_data, pdata)
+
+extern const struct imx_imx_keypad_data imx21_imx_keypad_data;
+#define imx21_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx21_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx21_imx_ssi_data[];
+#define imx21_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[];
+#define imx21_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata)
+#define imx21_add_imx_uart0(pdata) imx21_add_imx_uart(0, pdata)
+#define imx21_add_imx_uart1(pdata) imx21_add_imx_uart(1, pdata)
+#define imx21_add_imx_uart2(pdata) imx21_add_imx_uart(2, pdata)
+#define imx21_add_imx_uart3(pdata) imx21_add_imx_uart(3, pdata)
+
+extern const struct imx_mxc_mmc_data imx21_mxc_mmc_data[];
+#define imx21_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx21_mxc_mmc_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx21_mxc_nand_data;
+#define imx21_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx21_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_w1_data imx21_mxc_w1_data;
+#define imx21_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx21_mxc_w1_data)
+
+extern const struct imx_spi_imx_data imx21_cspi_data[];
+#define imx21_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx21_cspi_data[id], pdata)
+#define imx21_add_spi_imx0(pdata) imx21_add_cspi(0, pdata)
+#define imx21_add_spi_imx1(pdata) imx21_add_cspi(1, pdata)
diff --git a/arch/arm/mach-imx/devices-imx25.h b/arch/arm/mach-imx/devices-imx25.h
new file mode 100644
index 00000000..efa0761c
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx25.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx25.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx25_fec_data;
+#define imx25_add_fec(pdata) \
+ imx_add_fec(&imx25_fec_data, pdata)
+
+extern const struct imx_flexcan_data imx25_flexcan_data[];
+#define imx25_add_flexcan(id, pdata) \
+ imx_add_flexcan(&imx25_flexcan_data[id], pdata)
+#define imx25_add_flexcan0(pdata) imx25_add_flexcan(0, pdata)
+#define imx25_add_flexcan1(pdata) imx25_add_flexcan(1, pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data;
+#define imx25_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx25_fsl_usb2_udc_data, pdata)
+
+extern struct imx_imxdi_rtc_data imx25_imxdi_rtc_data;
+#define imx25_add_imxdi_rtc(pdata) \
+ imx_add_imxdi_rtc(&imx25_imxdi_rtc_data)
+
+extern const struct imx_imx2_wdt_data imx25_imx2_wdt_data;
+#define imx25_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx25_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx25_imx_fb_data;
+#define imx25_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx25_imx_fb_data, pdata)
+
+extern const struct imx_imx_i2c_data imx25_imx_i2c_data[];
+#define imx25_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
+#define imx25_add_imx_i2c0(pdata) imx25_add_imx_i2c(0, pdata)
+#define imx25_add_imx_i2c1(pdata) imx25_add_imx_i2c(1, pdata)
+#define imx25_add_imx_i2c2(pdata) imx25_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_keypad_data imx25_imx_keypad_data;
+#define imx25_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx25_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx25_imx_ssi_data[];
+#define imx25_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[];
+#define imx25_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata)
+#define imx25_add_imx_uart0(pdata) imx25_add_imx_uart(0, pdata)
+#define imx25_add_imx_uart1(pdata) imx25_add_imx_uart(1, pdata)
+#define imx25_add_imx_uart2(pdata) imx25_add_imx_uart(2, pdata)
+#define imx25_add_imx_uart3(pdata) imx25_add_imx_uart(3, pdata)
+#define imx25_add_imx_uart4(pdata) imx25_add_imx_uart(4, pdata)
+
+extern const struct imx_mx2_camera_data imx25_mx2_camera_data;
+#define imx25_add_mx2_camera(pdata) \
+ imx_add_mx2_camera(&imx25_mx2_camera_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data;
+#define imx25_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx25_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data;
+#define imx25_add_mxc_ehci_hs(pdata) \
+ imx_add_mxc_ehci(&imx25_mxc_ehci_hs_data, pdata)
+
+extern const struct imx_mxc_nand_data imx25_mxc_nand_data;
+#define imx25_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
+
+extern const struct imx_sdhci_esdhc_imx_data imx25_sdhci_esdhc_imx_data[];
+#define imx25_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx25_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx25_cspi_data[];
+#define imx25_add_spi_imx(id, pdata) \
+ imx_add_spi_imx(&imx25_cspi_data[id], pdata)
+#define imx25_add_spi_imx0(pdata) imx25_add_spi_imx(0, pdata)
+#define imx25_add_spi_imx1(pdata) imx25_add_spi_imx(1, pdata)
+#define imx25_add_spi_imx2(pdata) imx25_add_spi_imx(2, pdata)
+
+extern struct imx_mxc_pwm_data imx25_mxc_pwm_data[];
+#define imx25_add_mxc_pwm(id) \
+ imx_add_mxc_pwm(&imx25_mxc_pwm_data[id])
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
new file mode 100644
index 00000000..7f97a3cd
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx27.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx27_fec_data;
+#define imx27_add_fec(pdata) \
+ imx_add_fec(&imx27_fec_data, pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data;
+#define imx27_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx27_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data;
+#define imx27_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx27_imx2_wdt_data)
+
+extern const struct imx_imx_fb_data imx27_imx_fb_data;
+#define imx27_add_imx_fb(pdata) \
+ imx_add_imx_fb(&imx27_imx_fb_data, pdata)
+
+extern const struct imx_imx_i2c_data imx27_imx_i2c_data[];
+#define imx27_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata)
+
+extern const struct imx_imx_keypad_data imx27_imx_keypad_data;
+#define imx27_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx27_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx27_imx_ssi_data[];
+#define imx27_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[];
+#define imx27_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata)
+#define imx27_add_imx_uart0(pdata) imx27_add_imx_uart(0, pdata)
+#define imx27_add_imx_uart1(pdata) imx27_add_imx_uart(1, pdata)
+#define imx27_add_imx_uart2(pdata) imx27_add_imx_uart(2, pdata)
+#define imx27_add_imx_uart3(pdata) imx27_add_imx_uart(3, pdata)
+#define imx27_add_imx_uart4(pdata) imx27_add_imx_uart(4, pdata)
+#define imx27_add_imx_uart5(pdata) imx27_add_imx_uart(5, pdata)
+
+extern const struct imx_mx2_camera_data imx27_mx2_camera_data;
+#define imx27_add_mx2_camera(pdata) \
+ imx_add_mx2_camera(&imx27_mx2_camera_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data;
+#define imx27_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx27_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[];
+#define imx27_add_mxc_ehci_hs(id, pdata) \
+ imx_add_mxc_ehci(&imx27_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_mmc_data imx27_mxc_mmc_data[];
+#define imx27_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx27_mxc_mmc_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx27_mxc_nand_data;
+#define imx27_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx27_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_w1_data imx27_mxc_w1_data;
+#define imx27_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx27_mxc_w1_data)
+
+extern const struct imx_spi_imx_data imx27_cspi_data[];
+#define imx27_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx27_cspi_data[id], pdata)
+#define imx27_add_spi_imx0(pdata) imx27_add_cspi(0, pdata)
+#define imx27_add_spi_imx1(pdata) imx27_add_cspi(1, pdata)
+#define imx27_add_spi_imx2(pdata) imx27_add_cspi(2, pdata)
diff --git a/arch/arm/mach-imx/devices-imx31.h b/arch/arm/mach-imx/devices-imx31.h
new file mode 100644
index 00000000..dbe940d9
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx31.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx31.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data;
+#define imx31_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data;
+#define imx31_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx31_imx2_wdt_data)
+
+extern const struct imx_imx_i2c_data imx31_imx_i2c_data[];
+#define imx31_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
+#define imx31_add_imx_i2c0(pdata) imx31_add_imx_i2c(0, pdata)
+#define imx31_add_imx_i2c1(pdata) imx31_add_imx_i2c(1, pdata)
+#define imx31_add_imx_i2c2(pdata) imx31_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_keypad_data imx31_imx_keypad_data;
+#define imx31_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx31_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx31_imx_ssi_data[];
+#define imx31_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[];
+#define imx31_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata)
+#define imx31_add_imx_uart0(pdata) imx31_add_imx_uart(0, pdata)
+#define imx31_add_imx_uart1(pdata) imx31_add_imx_uart(1, pdata)
+#define imx31_add_imx_uart2(pdata) imx31_add_imx_uart(2, pdata)
+#define imx31_add_imx_uart3(pdata) imx31_add_imx_uart(3, pdata)
+#define imx31_add_imx_uart4(pdata) imx31_add_imx_uart(4, pdata)
+
+extern const struct imx_ipu_core_data imx31_ipu_core_data;
+#define imx31_add_ipu_core(pdata) \
+ imx_add_ipu_core(&imx31_ipu_core_data, pdata)
+#define imx31_alloc_mx3_camera(pdata) \
+ imx_alloc_mx3_camera(&imx31_ipu_core_data, pdata)
+#define imx31_add_mx3_sdc_fb(pdata) \
+ imx_add_mx3_sdc_fb(&imx31_ipu_core_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data;
+#define imx31_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[];
+#define imx31_add_mxc_ehci_hs(id, pdata) \
+ imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[];
+#define imx31_add_mxc_mmc(id, pdata) \
+ imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx31_mxc_nand_data;
+#define imx31_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_rtc_data imx31_mxc_rtc_data;
+#define imx31_add_mxc_rtc(pdata) \
+ imx_add_mxc_rtc(&imx31_mxc_rtc_data)
+
+extern const struct imx_mxc_w1_data imx31_mxc_w1_data;
+#define imx31_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx31_mxc_w1_data)
+
+extern const struct imx_spi_imx_data imx31_cspi_data[];
+#define imx31_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx31_cspi_data[id], pdata)
+#define imx31_add_spi_imx0(pdata) imx31_add_cspi(0, pdata)
+#define imx31_add_spi_imx1(pdata) imx31_add_cspi(1, pdata)
+#define imx31_add_spi_imx2(pdata) imx31_add_cspi(2, pdata)
diff --git a/arch/arm/mach-imx/devices-imx35.h b/arch/arm/mach-imx/devices-imx35.h
new file mode 100644
index 00000000..234cbd3c
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx35.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx35.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx35_fec_data;
+#define imx35_add_fec(pdata) \
+ imx_add_fec(&imx35_fec_data, pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data;
+#define imx35_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_flexcan_data imx35_flexcan_data[];
+#define imx35_add_flexcan(id, pdata) \
+ imx_add_flexcan(&imx35_flexcan_data[id], pdata)
+#define imx35_add_flexcan0(pdata) imx35_add_flexcan(0, pdata)
+#define imx35_add_flexcan1(pdata) imx35_add_flexcan(1, pdata)
+
+extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data;
+#define imx35_add_imx2_wdt(pdata) \
+ imx_add_imx2_wdt(&imx35_imx2_wdt_data)
+
+extern const struct imx_imx_i2c_data imx35_imx_i2c_data[];
+#define imx35_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata)
+#define imx35_add_imx_i2c0(pdata) imx35_add_imx_i2c(0, pdata)
+#define imx35_add_imx_i2c1(pdata) imx35_add_imx_i2c(1, pdata)
+#define imx35_add_imx_i2c2(pdata) imx35_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_keypad_data imx35_imx_keypad_data;
+#define imx35_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx35_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx35_imx_ssi_data[];
+#define imx35_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[];
+#define imx35_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata)
+#define imx35_add_imx_uart0(pdata) imx35_add_imx_uart(0, pdata)
+#define imx35_add_imx_uart1(pdata) imx35_add_imx_uart(1, pdata)
+#define imx35_add_imx_uart2(pdata) imx35_add_imx_uart(2, pdata)
+
+extern const struct imx_ipu_core_data imx35_ipu_core_data;
+#define imx35_add_ipu_core(pdata) \
+ imx_add_ipu_core(&imx35_ipu_core_data, pdata)
+#define imx35_alloc_mx3_camera(pdata) \
+ imx_alloc_mx3_camera(&imx35_ipu_core_data, pdata)
+#define imx35_add_mx3_sdc_fb(pdata) \
+ imx_add_mx3_sdc_fb(&imx35_ipu_core_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data;
+#define imx35_add_mxc_ehci_otg(pdata) \
+ imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data;
+#define imx35_add_mxc_ehci_hs(pdata) \
+ imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata)
+
+extern const struct imx_mxc_nand_data imx35_mxc_nand_data;
+#define imx35_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_w1_data imx35_mxc_w1_data;
+#define imx35_add_mxc_w1(pdata) \
+ imx_add_mxc_w1(&imx35_mxc_w1_data)
+
+extern const struct imx_sdhci_esdhc_imx_data imx35_sdhci_esdhc_imx_data[];
+#define imx35_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx35_cspi_data[];
+#define imx35_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx35_cspi_data[id], pdata)
+#define imx35_add_spi_imx0(pdata) imx35_add_cspi(0, pdata)
+#define imx35_add_spi_imx1(pdata) imx35_add_cspi(1, pdata)
diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c
new file mode 100644
index 00000000..f8aa5be0
--- /dev/null
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -0,0 +1,865 @@
+/*
+ * linux/arch/arm/plat-mxc/dma-v1.c
+ *
+ * i.MX DMA registration and IRQ dispatching
+ *
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
+ * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/scatterlist.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/dma-v1.h>
+
+#define DMA_DCR 0x00 /* Control Register */
+#define DMA_DISR 0x04 /* Interrupt status Register */
+#define DMA_DIMR 0x08 /* Interrupt mask Register */
+#define DMA_DBTOSR 0x0c /* Burst timeout status Register */
+#define DMA_DRTOSR 0x10 /* Request timeout Register */
+#define DMA_DSESR 0x14 /* Transfer Error Status Register */
+#define DMA_DBOSR 0x18 /* Buffer overflow status Register */
+#define DMA_DBTOCR 0x1c /* Burst timeout control Register */
+#define DMA_WSRA 0x40 /* W-Size Register A */
+#define DMA_XSRA 0x44 /* X-Size Register A */
+#define DMA_YSRA 0x48 /* Y-Size Register A */
+#define DMA_WSRB 0x4c /* W-Size Register B */
+#define DMA_XSRB 0x50 /* X-Size Register B */
+#define DMA_YSRB 0x54 /* Y-Size Register B */
+#define DMA_SAR(x) (0x80 + ((x) << 6)) /* Source Address Registers */
+#define DMA_DAR(x) (0x84 + ((x) << 6)) /* Destination Address Registers */
+#define DMA_CNTR(x) (0x88 + ((x) << 6)) /* Count Registers */
+#define DMA_CCR(x) (0x8c + ((x) << 6)) /* Control Registers */
+#define DMA_RSSR(x) (0x90 + ((x) << 6)) /* Request source select Registers */
+#define DMA_BLR(x) (0x94 + ((x) << 6)) /* Burst length Registers */
+#define DMA_RTOR(x) (0x98 + ((x) << 6)) /* Request timeout Registers */
+#define DMA_BUCR(x) (0x98 + ((x) << 6)) /* Bus Utilization Registers */
+#define DMA_CCNR(x) (0x9C + ((x) << 6)) /* Channel counter Registers */
+
+#define DCR_DRST (1<<1)
+#define DCR_DEN (1<<0)
+#define DBTOCR_EN (1<<15)
+#define DBTOCR_CNT(x) ((x) & 0x7fff)
+#define CNTR_CNT(x) ((x) & 0xffffff)
+#define CCR_ACRPT (1<<14)
+#define CCR_DMOD_LINEAR (0x0 << 12)
+#define CCR_DMOD_2D (0x1 << 12)
+#define CCR_DMOD_FIFO (0x2 << 12)
+#define CCR_DMOD_EOBFIFO (0x3 << 12)
+#define CCR_SMOD_LINEAR (0x0 << 10)
+#define CCR_SMOD_2D (0x1 << 10)
+#define CCR_SMOD_FIFO (0x2 << 10)
+#define CCR_SMOD_EOBFIFO (0x3 << 10)
+#define CCR_MDIR_DEC (1<<9)
+#define CCR_MSEL_B (1<<8)
+#define CCR_DSIZ_32 (0x0 << 6)
+#define CCR_DSIZ_8 (0x1 << 6)
+#define CCR_DSIZ_16 (0x2 << 6)
+#define CCR_SSIZ_32 (0x0 << 4)
+#define CCR_SSIZ_8 (0x1 << 4)
+#define CCR_SSIZ_16 (0x2 << 4)
+#define CCR_REN (1<<3)
+#define CCR_RPT (1<<2)
+#define CCR_FRC (1<<1)
+#define CCR_CEN (1<<0)
+#define RTOR_EN (1<<15)
+#define RTOR_CLK (1<<14)
+#define RTOR_PSC (1<<13)
+
+/*
+ * struct imx_dma_channel - i.MX specific DMA extension
+ * @name: name specified by DMA client
+ * @irq_handler: client callback for end of transfer
+ * @err_handler: client callback for error condition
+ * @data: clients context data for callbacks
+ * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
+ * @sg: pointer to the actual read/written chunk for scatter-gather emulation
+ * @resbytes: total residual number of bytes to transfer
+ * (it can be lower or same as sum of SG mapped chunk sizes)
+ * @sgcount: number of chunks to be read/written
+ *
+ * Structure is used for IMX DMA processing. It would be probably good
+ * @struct dma_struct in the future for external interfacing and use
+ * @struct imx_dma_channel only as extension to it.
+ */
+
+struct imx_dma_channel {
+ const char *name;
+ void (*irq_handler) (int, void *);
+ void (*err_handler) (int, void *, int errcode);
+ void (*prog_handler) (int, void *, struct scatterlist *);
+ void *data;
+ unsigned int dma_mode;
+ struct scatterlist *sg;
+ unsigned int resbytes;
+ int dma_num;
+
+ int in_use;
+
+ u32 ccr_from_device;
+ u32 ccr_to_device;
+
+ struct timer_list watchdog;
+
+ int hw_chaining;
+};
+
+static void __iomem *imx_dmav1_baseaddr;
+
+static void imx_dmav1_writel(unsigned val, unsigned offset)
+{
+ __raw_writel(val, imx_dmav1_baseaddr + offset);
+}
+
+static unsigned imx_dmav1_readl(unsigned offset)
+{
+ return __raw_readl(imx_dmav1_baseaddr + offset);
+}
+
+static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
+
+static struct clk *dma_clk;
+
+static int imx_dma_hw_chain(struct imx_dma_channel *imxdma)
+{
+ if (cpu_is_mx27())
+ return imxdma->hw_chaining;
+ else
+ return 0;
+}
+
+/*
+ * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
+ */
+static inline int imx_dma_sg_next(int channel, struct scatterlist *sg)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long now;
+
+ if (!imxdma->name) {
+ printk(KERN_CRIT "%s: called for not allocated channel %d\n",
+ __func__, channel);
+ return 0;
+ }
+
+ now = min(imxdma->resbytes, sg->length);
+ if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP)
+ imxdma->resbytes -= now;
+
+ if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
+ imx_dmav1_writel(sg->dma_address, DMA_DAR(channel));
+ else
+ imx_dmav1_writel(sg->dma_address, DMA_SAR(channel));
+
+ imx_dmav1_writel(now, DMA_CNTR(channel));
+
+ pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
+ "size 0x%08x\n", channel,
+ imx_dmav1_readl(DMA_DAR(channel)),
+ imx_dmav1_readl(DMA_SAR(channel)),
+ imx_dmav1_readl(DMA_CNTR(channel)));
+
+ return now;
+}
+
+/**
+ * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from
+ * device transfer
+ *
+ * @channel: i.MX DMA channel number
+ * @dma_address: the DMA/physical memory address of the linear data block
+ * to transfer
+ * @dma_length: length of the data block in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ * or %DMA_MODE_WRITE from memory to the device
+ *
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ * Zero indicates success.
+ */
+int
+imx_dma_setup_single(int channel, dma_addr_t dma_address,
+ unsigned int dma_length, unsigned int dev_addr,
+ unsigned int dmamode)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+ imxdma->sg = NULL;
+ imxdma->dma_mode = dmamode;
+
+ if (!dma_address) {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
+ channel);
+ return -EINVAL;
+ }
+
+ if (!dma_length) {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
+ channel);
+ return -EINVAL;
+ }
+
+ if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+ pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
+ "dev_addr=0x%08x for read\n",
+ channel, __func__, (unsigned int)dma_address,
+ dma_length, dev_addr);
+
+ imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+ imx_dmav1_writel(dma_address, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
+ } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+ pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
+ "dev_addr=0x%08x for write\n",
+ channel, __func__, (unsigned int)dma_address,
+ dma_length, dev_addr);
+
+ imx_dmav1_writel(dma_address, DMA_SAR(channel));
+ imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_to_device,
+ DMA_CCR(channel));
+ } else {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
+ channel);
+ return -EINVAL;
+ }
+
+ imx_dmav1_writel(dma_length, DMA_CNTR(channel));
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_single);
+
+/**
+ * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
+ * @channel: i.MX DMA channel number
+ * @sg: pointer to the scatter-gather list/vector
+ * @sgcount: scatter-gather list hungs count
+ * @dma_length: total length of the transfer request in bytes
+ * @dev_addr: physical device port address
+ * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
+ * or %DMA_MODE_WRITE from memory to the device
+ *
+ * The function sets up DMA channel state and registers to be ready for
+ * transfer specified by provided parameters. The scatter-gather emulation
+ * is set up according to the parameters.
+ *
+ * The full preparation of the transfer requires setup of more register
+ * by the caller before imx_dma_enable() can be called.
+ *
+ * %BLR(channel) holds transfer burst length in bytes, 0 means 64 bytes
+ *
+ * %RSSR(channel) has to be set to the DMA request line source %DMA_REQ_xxx
+ *
+ * %CCR(channel) has to specify transfer parameters, the next settings is
+ * typical for linear or simple scatter-gather transfers if %DMA_MODE_READ is
+ * specified
+ *
+ * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
+ *
+ * The typical setup for %DMA_MODE_WRITE is specified by next options
+ * combination
+ *
+ * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
+ *
+ * Be careful here and do not mistakenly mix source and target device
+ * port sizes constants, they are really different:
+ * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
+ * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
+ *
+ * Return value: if incorrect parameters are provided -%EINVAL.
+ * Zero indicates success.
+ */
+int
+imx_dma_setup_sg(int channel,
+ struct scatterlist *sg, unsigned int sgcount,
+ unsigned int dma_length, unsigned int dev_addr,
+ unsigned int dmamode)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+ if (imxdma->in_use)
+ return -EBUSY;
+
+ imxdma->sg = sg;
+ imxdma->dma_mode = dmamode;
+ imxdma->resbytes = dma_length;
+
+ if (!sg || !sgcount) {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_sg empty sg list\n",
+ channel);
+ return -EINVAL;
+ }
+
+ if (!sg->length) {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
+ channel);
+ return -EINVAL;
+ }
+
+ if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
+ pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
+ "dev_addr=0x%08x for read\n",
+ channel, __func__, sg, sgcount, dma_length, dev_addr);
+
+ imx_dmav1_writel(dev_addr, DMA_SAR(channel));
+ imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
+ } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
+ pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
+ "dev_addr=0x%08x for write\n",
+ channel, __func__, sg, sgcount, dma_length, dev_addr);
+
+ imx_dmav1_writel(dev_addr, DMA_DAR(channel));
+ imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel));
+ } else {
+ printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
+ channel);
+ return -EINVAL;
+ }
+
+ imx_dma_sg_next(channel, sg);
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_sg);
+
+int
+imx_dma_config_channel(int channel, unsigned int config_port,
+ unsigned int config_mem, unsigned int dmareq, int hw_chaining)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ u32 dreq = 0;
+
+ imxdma->hw_chaining = 0;
+
+ if (hw_chaining) {
+ imxdma->hw_chaining = 1;
+ if (!imx_dma_hw_chain(imxdma))
+ return -EINVAL;
+ }
+
+ if (dmareq)
+ dreq = CCR_REN;
+
+ imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
+ imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
+
+ imx_dmav1_writel(dmareq, DMA_RSSR(channel));
+
+ return 0;
+}
+EXPORT_SYMBOL(imx_dma_config_channel);
+
+void imx_dma_config_burstlen(int channel, unsigned int burstlen)
+{
+ imx_dmav1_writel(burstlen, DMA_BLR(channel));
+}
+EXPORT_SYMBOL(imx_dma_config_burstlen);
+
+/**
+ * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification
+ * handlers
+ * @channel: i.MX DMA channel number
+ * @irq_handler: the pointer to the function called if the transfer
+ * ends successfully
+ * @err_handler: the pointer to the function called if the premature
+ * end caused by error occurs
+ * @data: user specified value to be passed to the handlers
+ */
+int
+imx_dma_setup_handlers(int channel,
+ void (*irq_handler) (int, void *),
+ void (*err_handler) (int, void *, int),
+ void *data)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long flags;
+
+ if (!imxdma->name) {
+ printk(KERN_CRIT "%s: called for not allocated channel %d\n",
+ __func__, channel);
+ return -ENODEV;
+ }
+
+ local_irq_save(flags);
+ imx_dmav1_writel(1 << channel, DMA_DISR);
+ imxdma->irq_handler = irq_handler;
+ imxdma->err_handler = err_handler;
+ imxdma->data = data;
+ local_irq_restore(flags);
+ return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_handlers);
+
+/**
+ * imx_dma_setup_progression_handler - setup i.MX DMA channel progression
+ * handlers
+ * @channel: i.MX DMA channel number
+ * @prog_handler: the pointer to the function called if the transfer progresses
+ */
+int
+imx_dma_setup_progression_handler(int channel,
+ void (*prog_handler) (int, void*, struct scatterlist*))
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long flags;
+
+ if (!imxdma->name) {
+ printk(KERN_CRIT "%s: called for not allocated channel %d\n",
+ __func__, channel);
+ return -ENODEV;
+ }
+
+ local_irq_save(flags);
+ imxdma->prog_handler = prog_handler;
+ local_irq_restore(flags);
+ return 0;
+}
+EXPORT_SYMBOL(imx_dma_setup_progression_handler);
+
+/**
+ * imx_dma_enable - function to start i.MX DMA channel operation
+ * @channel: i.MX DMA channel number
+ *
+ * The channel has to be allocated by driver through imx_dma_request()
+ * or imx_dma_request_by_prio() function.
+ * The transfer parameters has to be set to the channel registers through
+ * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
+ * and registers %BLR(channel), %RSSR(channel) and %CCR(channel) has to
+ * be set prior this function call by the channel user.
+ */
+void imx_dma_enable(int channel)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long flags;
+
+ pr_debug("imxdma%d: imx_dma_enable\n", channel);
+
+ if (!imxdma->name) {
+ printk(KERN_CRIT "%s: called for not allocated channel %d\n",
+ __func__, channel);
+ return;
+ }
+
+ if (imxdma->in_use)
+ return;
+
+ local_irq_save(flags);
+
+ imx_dmav1_writel(1 << channel, DMA_DISR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN |
+ CCR_ACRPT, DMA_CCR(channel));
+
+#ifdef CONFIG_ARCH_MX2
+ if ((cpu_is_mx21() || cpu_is_mx27()) &&
+ imxdma->sg && imx_dma_hw_chain(imxdma)) {
+ imxdma->sg = sg_next(imxdma->sg);
+ if (imxdma->sg) {
+ u32 tmp;
+ imx_dma_sg_next(channel, imxdma->sg);
+ tmp = imx_dmav1_readl(DMA_CCR(channel));
+ imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
+ DMA_CCR(channel));
+ }
+ }
+#endif
+ imxdma->in_use = 1;
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_enable);
+
+/**
+ * imx_dma_disable - stop, finish i.MX DMA channel operatin
+ * @channel: i.MX DMA channel number
+ */
+void imx_dma_disable(int channel)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long flags;
+
+ pr_debug("imxdma%d: imx_dma_disable\n", channel);
+
+ if (imx_dma_hw_chain(imxdma))
+ del_timer(&imxdma->watchdog);
+
+ local_irq_save(flags);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
+ imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN,
+ DMA_CCR(channel));
+ imx_dmav1_writel(1 << channel, DMA_DISR);
+ imxdma->in_use = 0;
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_disable);
+
+#ifdef CONFIG_ARCH_MX2
+static void imx_dma_watchdog(unsigned long chno)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
+
+ imx_dmav1_writel(0, DMA_CCR(chno));
+ imxdma->in_use = 0;
+ imxdma->sg = NULL;
+
+ if (imxdma->err_handler)
+ imxdma->err_handler(chno, imxdma->data, IMX_DMA_ERR_TIMEOUT);
+}
+#endif
+
+static irqreturn_t dma_err_handler(int irq, void *dev_id)
+{
+ int i, disr;
+ struct imx_dma_channel *imxdma;
+ unsigned int err_mask;
+ int errcode;
+
+ disr = imx_dmav1_readl(DMA_DISR);
+
+ err_mask = imx_dmav1_readl(DMA_DBTOSR) |
+ imx_dmav1_readl(DMA_DRTOSR) |
+ imx_dmav1_readl(DMA_DSESR) |
+ imx_dmav1_readl(DMA_DBOSR);
+
+ if (!err_mask)
+ return IRQ_HANDLED;
+
+ imx_dmav1_writel(disr & err_mask, DMA_DISR);
+
+ for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+ if (!(err_mask & (1 << i)))
+ continue;
+ imxdma = &imx_dma_channels[i];
+ errcode = 0;
+
+ if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DBTOSR);
+ errcode |= IMX_DMA_ERR_BURST;
+ }
+ if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DRTOSR);
+ errcode |= IMX_DMA_ERR_REQUEST;
+ }
+ if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DSESR);
+ errcode |= IMX_DMA_ERR_TRANSFER;
+ }
+ if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) {
+ imx_dmav1_writel(1 << i, DMA_DBOSR);
+ errcode |= IMX_DMA_ERR_BUFFER;
+ }
+ if (imxdma->name && imxdma->err_handler) {
+ imxdma->err_handler(i, imxdma->data, errcode);
+ continue;
+ }
+
+ imx_dma_channels[i].sg = NULL;
+
+ printk(KERN_WARNING
+ "DMA timeout on channel %d (%s) -%s%s%s%s\n",
+ i, imxdma->name,
+ errcode & IMX_DMA_ERR_BURST ? " burst" : "",
+ errcode & IMX_DMA_ERR_REQUEST ? " request" : "",
+ errcode & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
+ errcode & IMX_DMA_ERR_BUFFER ? " buffer" : "");
+ }
+ return IRQ_HANDLED;
+}
+
+static void dma_irq_handle_channel(int chno)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
+
+ if (!imxdma->name) {
+ /*
+ * IRQ for an unregistered DMA channel:
+ * let's clear the interrupts and disable it.
+ */
+ printk(KERN_WARNING
+ "spurious IRQ for DMA channel %d\n", chno);
+ return;
+ }
+
+ if (imxdma->sg) {
+ u32 tmp;
+ struct scatterlist *current_sg = imxdma->sg;
+ imxdma->sg = sg_next(imxdma->sg);
+
+ if (imxdma->sg) {
+ imx_dma_sg_next(chno, imxdma->sg);
+
+ tmp = imx_dmav1_readl(DMA_CCR(chno));
+
+ if (imx_dma_hw_chain(imxdma)) {
+ /* FIXME: The timeout should probably be
+ * configurable
+ */
+ mod_timer(&imxdma->watchdog,
+ jiffies + msecs_to_jiffies(500));
+
+ tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
+ imx_dmav1_writel(tmp, DMA_CCR(chno));
+ } else {
+ imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno));
+ tmp |= CCR_CEN;
+ }
+
+ imx_dmav1_writel(tmp, DMA_CCR(chno));
+
+ if (imxdma->prog_handler)
+ imxdma->prog_handler(chno, imxdma->data,
+ current_sg);
+
+ return;
+ }
+
+ if (imx_dma_hw_chain(imxdma)) {
+ del_timer(&imxdma->watchdog);
+ return;
+ }
+ }
+
+ imx_dmav1_writel(0, DMA_CCR(chno));
+ imxdma->in_use = 0;
+ if (imxdma->irq_handler)
+ imxdma->irq_handler(chno, imxdma->data);
+}
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+ int i, disr;
+
+#ifdef CONFIG_ARCH_MX2
+ if (cpu_is_mx21() || cpu_is_mx27())
+ dma_err_handler(irq, dev_id);
+#endif
+
+ disr = imx_dmav1_readl(DMA_DISR);
+
+ pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
+ disr);
+
+ imx_dmav1_writel(disr, DMA_DISR);
+ for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+ if (disr & (1 << i))
+ dma_irq_handle_channel(i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * imx_dma_request - request/allocate specified channel number
+ * @channel: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ */
+int imx_dma_request(int channel, const char *name)
+{
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+ unsigned long flags;
+ int ret = 0;
+
+ /* basic sanity checks */
+ if (!name)
+ return -EINVAL;
+
+ if (channel >= IMX_DMA_CHANNELS) {
+ printk(KERN_CRIT "%s: called for non-existed channel %d\n",
+ __func__, channel);
+ return -EINVAL;
+ }
+
+ local_irq_save(flags);
+ if (imxdma->name) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+ memset(imxdma, 0, sizeof(*imxdma));
+ imxdma->name = name;
+ local_irq_restore(flags); /* request_irq() can block */
+
+#ifdef CONFIG_ARCH_MX2
+ if (cpu_is_mx21() || cpu_is_mx27()) {
+ ret = request_irq(MX2x_INT_DMACH0 + channel,
+ dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ imxdma->name = NULL;
+ pr_crit("Can't register IRQ %d for DMA channel %d\n",
+ MX2x_INT_DMACH0 + channel, channel);
+ return ret;
+ }
+ init_timer(&imxdma->watchdog);
+ imxdma->watchdog.function = &imx_dma_watchdog;
+ imxdma->watchdog.data = channel;
+ }
+#endif
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_dma_request);
+
+/**
+ * imx_dma_free - release previously acquired channel
+ * @channel: i.MX DMA channel number
+ */
+void imx_dma_free(int channel)
+{
+ unsigned long flags;
+ struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
+
+ if (!imxdma->name) {
+ printk(KERN_CRIT
+ "%s: trying to free free channel %d\n",
+ __func__, channel);
+ return;
+ }
+
+ local_irq_save(flags);
+ /* Disable interrupts */
+ imx_dma_disable(channel);
+ imxdma->name = NULL;
+
+#ifdef CONFIG_ARCH_MX2
+ if (cpu_is_mx21() || cpu_is_mx27())
+ free_irq(MX2x_INT_DMACH0 + channel, NULL);
+#endif
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(imx_dma_free);
+
+/**
+ * imx_dma_request_by_prio - find and request some of free channels best
+ * suiting requested priority
+ * @channel: i.MX DMA channel number
+ * @name: the driver/caller own non-%NULL identification
+ *
+ * This function tries to find a free channel in the specified priority group
+ * if the priority cannot be achieved it tries to look for free channel
+ * in the higher and then even lower priority groups.
+ *
+ * Return value: If there is no free channel to allocate, -%ENODEV is returned.
+ * On successful allocation channel is returned.
+ */
+int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio)
+{
+ int i;
+ int best;
+
+ switch (prio) {
+ case (DMA_PRIO_HIGH):
+ best = 8;
+ break;
+ case (DMA_PRIO_MEDIUM):
+ best = 4;
+ break;
+ case (DMA_PRIO_LOW):
+ default:
+ best = 0;
+ break;
+ }
+
+ for (i = best; i < IMX_DMA_CHANNELS; i++)
+ if (!imx_dma_request(i, name))
+ return i;
+
+ for (i = best - 1; i >= 0; i--)
+ if (!imx_dma_request(i, name))
+ return i;
+
+ printk(KERN_ERR "%s: no free DMA channel found\n", __func__);
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(imx_dma_request_by_prio);
+
+static int __init imx_dma_init(void)
+{
+ int ret = 0;
+ int i;
+
+#ifdef CONFIG_ARCH_MX1
+ if (cpu_is_mx1())
+ imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX21
+ if (cpu_is_mx21())
+ imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27())
+ imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
+ else
+#endif
+ return 0;
+
+ dma_clk = clk_get(NULL, "dma");
+ if (IS_ERR(dma_clk))
+ return PTR_ERR(dma_clk);
+ clk_enable(dma_clk);
+
+ /* reset DMA module */
+ imx_dmav1_writel(DCR_DRST, DMA_DCR);
+
+#ifdef CONFIG_ARCH_MX1
+ if (cpu_is_mx1()) {
+ ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ pr_crit("Wow! Can't register IRQ for DMA\n");
+ return ret;
+ }
+
+ ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL);
+ if (ret) {
+ pr_crit("Wow! Can't register ERRIRQ for DMA\n");
+ free_irq(MX1_DMA_INT, NULL);
+ return ret;
+ }
+ }
+#endif
+ /* enable DMA module */
+ imx_dmav1_writel(DCR_DEN, DMA_DCR);
+
+ /* clear all interrupts */
+ imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR);
+
+ /* disable interrupts */
+ imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR);
+
+ for (i = 0; i < IMX_DMA_CHANNELS; i++) {
+ imx_dma_channels[i].sg = NULL;
+ imx_dma_channels[i].dma_num = i;
+ }
+
+ return ret;
+}
+
+arch_initcall(imx_dma_init);
diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c
new file mode 100644
index 00000000..865daf0b
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx25.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET 0x600
+
+#define MX25_OTG_SIC_SHIFT 29
+#define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT)
+#define MX25_OTG_PM_BIT (1 << 24)
+
+#define MX25_H1_SIC_SHIFT 21
+#define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT)
+#define MX25_H1_PM_BIT (1 << 8)
+#define MX25_H1_IPPUE_UP_BIT (1 << 7)
+#define MX25_H1_IPPUE_DOWN_BIT (1 << 6)
+#define MX25_H1_TLL_BIT (1 << 5)
+#define MX25_H1_USBTE_BIT (1 << 4)
+
+int mx25_initialize_usb_hw(int port, unsigned int flags)
+{
+ unsigned int v;
+
+ v = readl(MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX25_OTG_PM_BIT;
+
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX25_H1_SIC_MASK | MX25_H1_PM_BIT | MX25_H1_TLL_BIT |
+ MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT | MX25_H1_IPPUE_UP_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX25_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX25_H1_TLL_BIT;
+
+ if (flags & MXC_EHCI_INTERNAL_PHY)
+ v |= MX25_H1_USBTE_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_DOWN)
+ v |= MX25_H1_IPPUE_DOWN_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_UP)
+ v |= MX25_H1_IPPUE_UP_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(v, MX25_IO_ADDRESS(MX25_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-imx/ehci-imx27.c b/arch/arm/mach-imx/ehci-imx27.c
new file mode 100644
index 00000000..fa69419e
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx27.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET 0x600
+
+#define MX27_OTG_SIC_SHIFT 29
+#define MX27_OTG_SIC_MASK (0x3 << MX27_OTG_SIC_SHIFT)
+#define MX27_OTG_PM_BIT (1 << 24)
+
+#define MX27_H2_SIC_SHIFT 21
+#define MX27_H2_SIC_MASK (0x3 << MX27_H2_SIC_SHIFT)
+#define MX27_H2_PM_BIT (1 << 16)
+#define MX27_H2_DT_BIT (1 << 5)
+
+#define MX27_H1_SIC_SHIFT 13
+#define MX27_H1_SIC_MASK (0x3 << MX27_H1_SIC_SHIFT)
+#define MX27_H1_PM_BIT (1 << 8)
+#define MX27_H1_DT_BIT (1 << 4)
+
+int mx27_initialize_usb_hw(int port, unsigned int flags)
+{
+ unsigned int v;
+
+ v = readl(MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX27_OTG_SIC_MASK | MX27_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_OTG_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX27_OTG_PM_BIT;
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX27_H1_SIC_MASK | MX27_H1_PM_BIT | MX27_H1_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H1_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX27_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX27_H1_DT_BIT;
+
+ break;
+ case 2: /* H2 port */
+ v &= ~(MX27_H2_SIC_MASK | MX27_H2_PM_BIT | MX27_H2_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX27_H2_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX27_H2_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX27_H2_DT_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(v, MX27_IO_ADDRESS(MX27_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-imx/ehci-imx31.c b/arch/arm/mach-imx/ehci-imx31.c
new file mode 100644
index 00000000..faad0f15
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx31.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET 0x600
+
+#define MX31_OTG_SIC_SHIFT 29
+#define MX31_OTG_SIC_MASK (0x3 << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_PM_BIT (1 << 24)
+
+#define MX31_H2_SIC_SHIFT 21
+#define MX31_H2_SIC_MASK (0x3 << MX31_H2_SIC_SHIFT)
+#define MX31_H2_PM_BIT (1 << 16)
+#define MX31_H2_DT_BIT (1 << 5)
+
+#define MX31_H1_SIC_SHIFT 13
+#define MX31_H1_SIC_MASK (0x3 << MX31_H1_SIC_SHIFT)
+#define MX31_H1_PM_BIT (1 << 8)
+#define MX31_H1_DT_BIT (1 << 4)
+
+int mx31_initialize_usb_hw(int port, unsigned int flags)
+{
+ unsigned int v;
+
+ v = readl(MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_OTG_PM_BIT;
+
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX31_H1_DT_BIT;
+
+ break;
+ case 2: /* H2 port */
+ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX31_H2_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX31_H2_DT_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(v, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c
new file mode 100644
index 00000000..001ec397
--- /dev/null
+++ b/arch/arm/mach-imx/ehci-imx35.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET 0x600
+
+#define MX35_OTG_SIC_SHIFT 29
+#define MX35_OTG_SIC_MASK (0x3 << MX35_OTG_SIC_SHIFT)
+#define MX35_OTG_PM_BIT (1 << 24)
+
+#define MX35_H1_SIC_SHIFT 21
+#define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT)
+#define MX35_H1_PM_BIT (1 << 8)
+#define MX35_H1_IPPUE_UP_BIT (1 << 7)
+#define MX35_H1_IPPUE_DOWN_BIT (1 << 6)
+#define MX35_H1_TLL_BIT (1 << 5)
+#define MX35_H1_USBTE_BIT (1 << 4)
+
+int mx35_initialize_usb_hw(int port, unsigned int flags)
+{
+ unsigned int v;
+
+ v = readl(MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX35_OTG_PM_BIT;
+
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
+ MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT;
+
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX35_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX35_H1_TLL_BIT;
+
+ if (flags & MXC_EHCI_INTERNAL_PHY)
+ v |= MX35_H1_USBTE_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_DOWN)
+ v |= MX35_H1_IPPUE_DOWN_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_UP)
+ v |= MX35_H1_IPPUE_UP_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(v, MX35_IO_ADDRESS(MX35_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+ return 0;
+}
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
new file mode 100644
index 00000000..5911281d
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2009-2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/backlight.h>
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx27.h>
+#include <mach/hardware.h>
+#include <mach/audmux.h>
+
+#include "devices-imx27.h"
+
+static const int eukrea_mbimx27_pins[] __initconst = {
+ /* UART2 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART3 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* UART4 */
+#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+#endif
+ /* SDHC1*/
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* display */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /* SPI1 */
+ PD29_PF_CSPI1_SCLK,
+ PD30_PF_CSPI1_MISO,
+ PD31_PF_CSPI1_MOSI,
+ /* SSI4 */
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
+ || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
+ PC16_PF_SSI4_FS,
+ PC17_PF_SSI4_RXD | GPIO_PUEN,
+ PC18_PF_SSI4_TXD | GPIO_PUEN,
+ PC19_PF_SSI4_CLK,
+#endif
+};
+
+static const uint32_t eukrea_mbimx27_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+};
+
+static const struct matrix_keymap_data
+eukrea_mbimx27_keymap_data __initconst = {
+ .keymap = eukrea_mbimx27_keymap,
+ .keymap_size = ARRAY_SIZE(eukrea_mbimx27_keymap),
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_PORTF | 16,
+ },
+ {
+ .name = "led2",
+ .default_trigger = "none",
+ .active_low = 1,
+ .gpio = GPIO_PORTF | 19,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
+ {
+ .mode = {
+ .name = "CMO-QVGA",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = 156000,
+ .hsync_len = 30,
+ .left_margin = 38,
+ .right_margin = 20,
+ .vsync_len = 3,
+ .upper_margin = 15,
+ .lower_margin = 4,
+ },
+ .pcr = 0xFAD08B80,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .hsync_len = 1,
+ .left_margin = 35,
+ .right_margin = 0,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 0,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .hsync_len = 1,
+ .left_margin = 35,
+ .right_margin = 0,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 0,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ },
+};
+
+static const struct imx_fb_platform_data eukrea_mbimx27_fb_data __initconst = {
+ .mode = eukrea_mbimx27_modes,
+ .num_modes = ARRAY_SIZE(eukrea_mbimx27_modes),
+
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00040060,
+};
+
+static void eukrea_mbimx27_bl_set_intensity(int intensity)
+{
+ if (intensity)
+ gpio_direction_output(GPIO_PORTE | 5, 1);
+ else
+ gpio_direction_output(GPIO_PORTE | 5, 0);
+}
+
+static struct generic_bl_info eukrea_mbimx27_bl_info = {
+ .name = "eukrea_mbimx27-bl",
+ .max_intensity = 0xff,
+ .default_intensity = 0xff,
+ .set_bl_intensity = eukrea_mbimx27_bl_set_intensity,
+};
+
+static struct platform_device eukrea_mbimx27_bl_dev = {
+ .name = "generic-bl",
+ .id = 1,
+ .dev = {
+ .platform_data = &eukrea_mbimx27_bl_info,
+ },
+};
+
+static void eukrea_mbimx27_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_PORTA | 25, 1);
+ else
+ gpio_direction_output(GPIO_PORTA | 25, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimx27_lcd_power_data = {
+ .set_power = eukrea_mbimx27_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimx27_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimx27_lcd_power_data,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define ADS7846_PENDOWN (GPIO_PORTD | 25)
+
+static void __maybe_unused ads7846_dev_init(void)
+{
+ if (gpio_request(ADS7846_PENDOWN, "ADS7846 pendown") < 0) {
+ printk(KERN_ERR "can't get ads746 pen down GPIO\n");
+ return;
+ }
+ gpio_direction_input(ADS7846_PENDOWN);
+}
+
+static int ads7846_get_pendown_state(void)
+{
+ return !gpio_get_value(ADS7846_PENDOWN);
+}
+
+static struct ads7846_platform_data ads7846_config __initdata = {
+ .get_pendown_state = ads7846_get_pendown_state,
+ .keep_vref_on = 1,
+};
+
+static struct spi_board_info __maybe_unused
+ eukrea_mbimx27_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "ads7846",
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .irq = IRQ_GPIOD(25),
+ .platform_data = &ads7846_config,
+ .mode = SPI_MODE_2,
+ },
+};
+
+static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
+
+static const struct spi_imx_master eukrea_mbimx27_spi0_data __initconst = {
+ .chipselect = eukrea_mbimx27_spi_cs,
+ .num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
+};
+
+static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &leds_gpio,
+};
+
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
+ .dat3_card_detect = 1,
+};
+
+static const
+struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata __initconst = {
+ .flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx27 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimx27_baseboard_init(void)
+{
+ mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
+ ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
+ || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
+ /* SSI unit master I2S codec connected to SSI_PINS_4*/
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ MXC_AUDMUX_V1_PCR_SYN |
+ MXC_AUDMUX_V1_PCR_TFSDIR |
+ MXC_AUDMUX_V1_PCR_TCLKDIR |
+ MXC_AUDMUX_V1_PCR_RFSDIR |
+ MXC_AUDMUX_V1_PCR_RCLKDIR |
+ MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+ MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+ MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
+ );
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
+ MXC_AUDMUX_V1_PCR_SYN |
+ MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+ );
+#endif
+
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
+ imx27_add_imx_uart3(&uart_pdata);
+#endif
+
+ imx27_add_imx_fb(&eukrea_mbimx27_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc_pdata);
+
+ i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
+
+ imx27_add_imx_ssi(0, &eukrea_mbimx27_ssi_pdata);
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
+ || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ /* ADS7846 Touchscreen controller init */
+ mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
+ ads7846_dev_init();
+#endif
+
+ /* SPI_CS0 init */
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+ imx27_add_spi_imx0(&eukrea_mbimx27_spi0_data);
+ spi_register_board_info(eukrea_mbimx27_spi_board_info,
+ ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
+
+ /* Leds configuration */
+ mxc_gpio_mode(GPIO_PORTF | 16 | GPIO_GPIO | GPIO_OUT);
+ mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
+ /* Backlight */
+ mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
+ gpio_request(GPIO_PORTE | 5, "backlight");
+ platform_device_register(&eukrea_mbimx27_bl_dev);
+ /* LCD Reset */
+ mxc_gpio_mode(GPIO_PORTA | 25 | GPIO_GPIO | GPIO_OUT);
+ gpio_request(GPIO_PORTA | 25, "lcd_enable");
+ platform_device_register(&eukrea_mbimx27_lcd_powerdev);
+
+ imx27_add_imx_keypad(&eukrea_mbimx27_keymap_data);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
new file mode 100644
index 00000000..f9ef04ac
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <video/platform_lcd.h>
+
+#include <mach/hardware.h>
+#include <mach/iomux-mx25.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/mx25.h>
+#include <mach/audmux.h>
+
+#include "devices-imx25.h"
+
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
+ /* LCD */
+ MX25_PAD_LD0__LD0,
+ MX25_PAD_LD1__LD1,
+ MX25_PAD_LD2__LD2,
+ MX25_PAD_LD3__LD3,
+ MX25_PAD_LD4__LD4,
+ MX25_PAD_LD5__LD5,
+ MX25_PAD_LD6__LD6,
+ MX25_PAD_LD7__LD7,
+ MX25_PAD_LD8__LD8,
+ MX25_PAD_LD9__LD9,
+ MX25_PAD_LD10__LD10,
+ MX25_PAD_LD11__LD11,
+ MX25_PAD_LD12__LD12,
+ MX25_PAD_LD13__LD13,
+ MX25_PAD_LD14__LD14,
+ MX25_PAD_LD15__LD15,
+ MX25_PAD_GPIO_E__LD16,
+ MX25_PAD_GPIO_F__LD17,
+ MX25_PAD_HSYNC__HSYNC,
+ MX25_PAD_VSYNC__VSYNC,
+ MX25_PAD_LSCLK__LSCLK,
+ MX25_PAD_OE_ACD__OE_ACD,
+ MX25_PAD_CONTRAST__CONTRAST,
+ /* LCD_PWR */
+ MX25_PAD_PWM__GPIO_1_26,
+ /* LED */
+ MX25_PAD_POWER_FAIL__GPIO_3_19,
+ /* SWITCH */
+ MX25_PAD_VSTBY_ACK__GPIO_3_18,
+ /* UART2 */
+ MX25_PAD_UART2_RTS__UART2_RTS,
+ MX25_PAD_UART2_CTS__UART2_CTS,
+ MX25_PAD_UART2_TXD__UART2_TXD,
+ MX25_PAD_UART2_RXD__UART2_RXD,
+ /* SD1 */
+ MX25_PAD_SD1_CMD__SD1_CMD,
+ MX25_PAD_SD1_CLK__SD1_CLK,
+ MX25_PAD_SD1_DATA0__SD1_DATA0,
+ MX25_PAD_SD1_DATA1__SD1_DATA1,
+ MX25_PAD_SD1_DATA2__SD1_DATA2,
+ MX25_PAD_SD1_DATA3__SD1_DATA3,
+ /* SD1 CD */
+ MX25_PAD_DE_B__GPIO_2_20,
+ /* I2S */
+ MX25_PAD_KPP_COL3__AUD5_TXFS,
+ MX25_PAD_KPP_COL2__AUD5_TXC,
+ MX25_PAD_KPP_COL1__AUD5_RXD,
+ MX25_PAD_KPP_COL0__AUD5_TXD,
+ /* CAN */
+ MX25_PAD_GPIO_D__CAN2_RX,
+ MX25_PAD_GPIO_C__CAN2_TX,
+};
+
+#define GPIO_LED1 83
+#define GPIO_SWITCH1 82
+#define GPIO_SD1CD 52
+#define GPIO_LCDPWR 26
+
+static struct imx_fb_videomode eukrea_mximxsd_modes[] = {
+ {
+ .mode = {
+ .name = "CMO-QVGA",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6500),
+ .left_margin = 30,
+ .right_margin = 38,
+ .upper_margin = 20,
+ .lower_margin = 3,
+ .hsync_len = 15,
+ .vsync_len = 4,
+ },
+ .bpp = 16,
+ .pcr = 0xCAD08B80,
+ }, {
+ .mode = {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .hsync_len = 7,
+ .left_margin = 100,
+ .right_margin = 100,
+ .vsync_len = 7,
+ .upper_margin = 7,
+ .lower_margin = 100,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .hsync_len = 7,
+ .left_margin = 75,
+ .right_margin = 75,
+ .vsync_len = 7,
+ .upper_margin = 7,
+ .lower_margin = 75,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ },
+};
+
+static const struct imx_fb_platform_data eukrea_mximxsd_fb_pdata __initconst = {
+ .mode = eukrea_mximxsd_modes,
+ .num_modes = ARRAY_SIZE(eukrea_mximxsd_modes),
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00040060,
+};
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ else
+ gpio_direction_output(GPIO_LCDPWR, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+ .set_power = eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimxsd_lcd_power_data,
+};
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static const struct gpio_keys_platform_data
+ eukrea_mbimxsd_button_data __initconst = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+ &eukrea_mbimxsd_lcd_powerdev,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
+ .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
+static struct esdhc_platform_data sd1_pdata = {
+ .cd_gpio = GPIO_SD1CD,
+ .wp_gpio = -EINVAL,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx25 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd25_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+ /* SSI unit master I2S codec connected to SSI_AUD5*/
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN |
+ MXC_AUDMUX_V2_PTCR_TFSDIR |
+ MXC_AUDMUX_V2_PTCR_TFSEL(4) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR |
+ MXC_AUDMUX_V2_PTCR_TCSEL(4),
+ MXC_AUDMUX_V2_PDCR_RXDSEL(4)
+ );
+ mxc_audmux_v2_configure_port(4,
+ MXC_AUDMUX_V2_PTCR_SYN,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+ );
+#endif
+
+ imx25_add_imx_uart1(&uart_pdata);
+ imx25_add_imx_fb(&eukrea_mximxsd_fb_pdata);
+ imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx25_add_flexcan1(NULL);
+ imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ gpio_request(GPIO_LCDPWR, "LCDPWR");
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ gpio_free(GPIO_SWITCH1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+}
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
new file mode 100644
index 00000000..4909ea05
--- /dev/null
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <video/platform_lcd.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/audmux.h>
+
+#include "devices-imx35.h"
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ .name = "CMO-QVGA",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6500),
+ .left_margin = 68,
+ .right_margin = 20,
+ .upper_margin = 15,
+ .lower_margin = 4,
+ .hsync_len = 30,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+ {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .left_margin = 100,
+ .right_margin = 100,
+ .upper_margin = 7,
+ .lower_margin = 100,
+ .hsync_len = 7,
+ .vsync_len = 7,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+ {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .left_margin = 75,
+ .right_margin = 75,
+ .upper_margin = 7,
+ .lower_margin = 75,
+ .hsync_len = 7,
+ .vsync_len = 7,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "CMO-QVGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
+ /* LCD */
+ MX35_PAD_LD0__IPU_DISPB_DAT_0,
+ MX35_PAD_LD1__IPU_DISPB_DAT_1,
+ MX35_PAD_LD2__IPU_DISPB_DAT_2,
+ MX35_PAD_LD3__IPU_DISPB_DAT_3,
+ MX35_PAD_LD4__IPU_DISPB_DAT_4,
+ MX35_PAD_LD5__IPU_DISPB_DAT_5,
+ MX35_PAD_LD6__IPU_DISPB_DAT_6,
+ MX35_PAD_LD7__IPU_DISPB_DAT_7,
+ MX35_PAD_LD8__IPU_DISPB_DAT_8,
+ MX35_PAD_LD9__IPU_DISPB_DAT_9,
+ MX35_PAD_LD10__IPU_DISPB_DAT_10,
+ MX35_PAD_LD11__IPU_DISPB_DAT_11,
+ MX35_PAD_LD12__IPU_DISPB_DAT_12,
+ MX35_PAD_LD13__IPU_DISPB_DAT_13,
+ MX35_PAD_LD14__IPU_DISPB_DAT_14,
+ MX35_PAD_LD15__IPU_DISPB_DAT_15,
+ MX35_PAD_LD16__IPU_DISPB_DAT_16,
+ MX35_PAD_LD17__IPU_DISPB_DAT_17,
+ MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+ MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+ MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+ MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+ /* Backlight */
+ MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+ /* LCD_PWR */
+ MX35_PAD_D3_CLS__GPIO1_4,
+ /* LED */
+ MX35_PAD_LD23__GPIO3_29,
+ /* SWITCH */
+ MX35_PAD_LD19__GPIO3_25,
+ /* UART2 */
+ MX35_PAD_CTS2__UART2_CTS,
+ MX35_PAD_RTS2__UART2_RTS,
+ MX35_PAD_TXD2__UART2_TXD_MUX,
+ MX35_PAD_RXD2__UART2_RXD_MUX,
+ /* I2S */
+ MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+ MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+ MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+ MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+ /* CAN2 */
+ MX35_PAD_TX5_RX0__CAN2_TXCAN,
+ MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* SDCARD */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* SD1 CD */
+ MX35_PAD_LD18__GPIO3_24,
+};
+
+#define GPIO_LED1 IMX_GPIO_NR(3, 29)
+#define GPIO_SWITCH1 IMX_GPIO_NR(3, 25)
+#define GPIO_LCDPWR IMX_GPIO_NR(1, 4)
+#define GPIO_SD1CD IMX_GPIO_NR(3, 24)
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ else
+ gpio_direction_output(GPIO_LCDPWR, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+ .set_power = eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimxsd_lcd_power_data,
+};
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static const struct gpio_keys_platform_data
+ eukrea_mbimxsd_button_data __initconst = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+ &eukrea_mbimxsd_lcd_powerdev,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
+ .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
+static struct esdhc_platform_data sd1_pdata = {
+ .cd_gpio = GPIO_SD1CD,
+ .wp_gpio = -EINVAL,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx35 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd35_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+ /* SSI unit master I2S codec connected to SSI_AUD4 */
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN |
+ MXC_AUDMUX_V2_PTCR_TFSDIR |
+ MXC_AUDMUX_V2_PTCR_TFSEL(3) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR |
+ MXC_AUDMUX_V2_PTCR_TCSEL(3),
+ MXC_AUDMUX_V2_PDCR_RXDSEL(3)
+ );
+ mxc_audmux_v2_configure_port(3,
+ MXC_AUDMUX_V2_PTCR_SYN,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+ );
+#endif
+
+ imx35_add_imx_uart1(&uart_pdata);
+ imx35_add_ipu_core(&mx3_ipu_data);
+ imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+ imx35_add_flexcan1(NULL);
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ gpio_request(GPIO_LCDPWR, "LCDPWR");
+ gpio_direction_output(GPIO_LCDPWR, 1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+}
diff --git a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
new file mode 100644
index 00000000..df5f522d
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
@@ -0,0 +1,10 @@
+#ifndef __MACH_DMA_MX1_MX2_H__
+#define __MACH_DMA_MX1_MX2_H__
+/*
+ * Don't use this header in new code, it will go away when all users are
+ * converted to mach/dma-v1.h
+ */
+
+#include <mach/dma-v1.h>
+
+#endif /* ifndef __MACH_DMA_MX1_MX2_H__ */
diff --git a/arch/arm/mach-imx/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h
new file mode 100644
index 00000000..ac6fd713
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-v1.h
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-imx/include/mach/dma-v1.h
+ *
+ * i.MX DMA registration and IRQ dispatching
+ *
+ * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
+ * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_DMA_V1_H__
+#define __MACH_DMA_V1_H__
+
+#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+
+#include <mach/dma.h>
+
+#define IMX_DMA_CHANNELS 16
+
+#define DMA_MODE_READ 0
+#define DMA_MODE_WRITE 1
+#define DMA_MODE_MASK 1
+
+#define MX1_DMA_REG(offset) MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
+
+/* DMA Interrupt Mask Register */
+#define MX1_DMA_DIMR MX1_DMA_REG(0x08)
+
+/* Channel Control Register */
+#define MX1_DMA_CCR(x) MX1_DMA_REG(0x8c + ((x) << 6))
+
+#define IMX_DMA_MEMSIZE_32 (0 << 4)
+#define IMX_DMA_MEMSIZE_8 (1 << 4)
+#define IMX_DMA_MEMSIZE_16 (2 << 4)
+#define IMX_DMA_TYPE_LINEAR (0 << 10)
+#define IMX_DMA_TYPE_2D (1 << 10)
+#define IMX_DMA_TYPE_FIFO (2 << 10)
+
+#define IMX_DMA_ERR_BURST (1 << 0)
+#define IMX_DMA_ERR_REQUEST (1 << 1)
+#define IMX_DMA_ERR_TRANSFER (1 << 2)
+#define IMX_DMA_ERR_BUFFER (1 << 3)
+#define IMX_DMA_ERR_TIMEOUT (1 << 4)
+
+int
+imx_dma_config_channel(int channel, unsigned int config_port,
+ unsigned int config_mem, unsigned int dmareq, int hw_chaining);
+
+void
+imx_dma_config_burstlen(int channel, unsigned int burstlen);
+
+int
+imx_dma_setup_single(int channel, dma_addr_t dma_address,
+ unsigned int dma_length, unsigned int dev_addr,
+ unsigned int dmamode);
+
+
+/*
+ * Use this flag as the dma_length argument to imx_dma_setup_sg()
+ * to create an endless running dma loop. The end of the scatterlist
+ * must be linked to the beginning for this to work.
+ */
+#define IMX_DMA_LENGTH_LOOP ((unsigned int)-1)
+
+int
+imx_dma_setup_sg(int channel, struct scatterlist *sg,
+ unsigned int sgcount, unsigned int dma_length,
+ unsigned int dev_addr, unsigned int dmamode);
+
+int
+imx_dma_setup_handlers(int channel,
+ void (*irq_handler) (int, void *),
+ void (*err_handler) (int, void *, int), void *data);
+
+int
+imx_dma_setup_progression_handler(int channel,
+ void (*prog_handler) (int, void*, struct scatterlist*));
+
+void imx_dma_enable(int channel);
+
+void imx_dma_disable(int channel);
+
+int imx_dma_request(int channel, const char *name);
+
+void imx_dma_free(int channel);
+
+int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
+
+#endif /* __MACH_DMA_V1_H__ */
diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c
new file mode 100644
index 00000000..cf8f8099
--- /dev/null
+++ b/arch/arm/mach-imx/iomux-imx31.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx3.h>
+
+/*
+ * IOMUX register (base) addresses
+ */
+#define IOMUX_BASE MX31_IO_ADDRESS(MX31_IOMUXC_BASE_ADDR)
+#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000)
+#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004)
+#define IOMUXGPR (IOMUX_BASE + 0x008)
+#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C)
+#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154)
+
+static DEFINE_SPINLOCK(gpio_mux_lock);
+
+#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
+
+unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
+/*
+ * set the mode for a IOMUX pin.
+ */
+int mxc_iomux_mode(unsigned int pin_mode)
+{
+ u32 field, l, mode, ret = 0;
+ void __iomem *reg;
+
+ reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
+ field = pin_mode & 0x3;
+ mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
+
+ spin_lock(&gpio_mux_lock);
+
+ l = __raw_readl(reg);
+ l &= ~(0xff << (field * 8));
+ l |= mode << (field * 8);
+ __raw_writel(l, reg);
+
+ spin_unlock(&gpio_mux_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_mode);
+
+/*
+ * This function configures the pad value for a IOMUX pin.
+ */
+void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
+{
+ u32 field, l;
+ void __iomem *reg;
+
+ pin &= IOMUX_PADNUM_MASK;
+ reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
+ field = (pin + 2) % 3;
+
+ pr_debug("%s: reg offset = 0x%x, field = %d\n",
+ __func__, (pin + 2) / 3, field);
+
+ spin_lock(&gpio_mux_lock);
+
+ l = __raw_readl(reg);
+ l &= ~(0x1ff << (field * 10));
+ l |= config << (field * 10);
+ __raw_writel(l, reg);
+
+ spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+/*
+ * allocs a single pin:
+ * - reserves the pin so that it is not claimed by another driver
+ * - setups the iomux according to the configuration
+ */
+int mxc_iomux_alloc_pin(unsigned int pin, const char *label)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+
+ if (pad >= (PIN_MAX + 1)) {
+ printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
+ pad, label ? label : "?");
+ return -EINVAL;
+ }
+
+ if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
+ printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
+ pad, label ? label : "?");
+ return -EBUSY;
+ }
+ mxc_iomux_mode(pin);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_alloc_pin);
+
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
+ const char *label)
+{
+ const unsigned int *p = pin_list;
+ int i;
+ int ret = -EINVAL;
+
+ for (i = 0; i < count; i++) {
+ ret = mxc_iomux_alloc_pin(*p, label);
+ if (ret)
+ goto setup_error;
+ p++;
+ }
+ return 0;
+
+setup_error:
+ mxc_iomux_release_multiple_pins(pin_list, i);
+ return ret;
+}
+EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
+
+void mxc_iomux_release_pin(unsigned int pin)
+{
+ unsigned pad = pin & IOMUX_PADNUM_MASK;
+
+ if (pad < (PIN_MAX + 1))
+ clear_bit(pad, mxc_pin_alloc_map);
+}
+EXPORT_SYMBOL(mxc_iomux_release_pin);
+
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count)
+{
+ const unsigned int *p = pin_list;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ mxc_iomux_release_pin(*p);
+ p++;
+ }
+}
+EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
+
+/*
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ */
+void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
+{
+ u32 l;
+
+ spin_lock(&gpio_mux_lock);
+ l = __raw_readl(IOMUXGPR);
+ if (en)
+ l |= gp;
+ else
+ l &= ~gp;
+
+ __raw_writel(l, IOMUXGPR);
+ spin_unlock(&gpio_mux_lock);
+}
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff --git a/arch/arm/mach-imx/mach-apf9328.c b/arch/arm/mach-imx/mach-apf9328.c
new file mode 100644
index 00000000..15e45c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-apf9328.c
@@ -0,0 +1,144 @@
+/*
+ * linux/arch/arm/mach-imx/mach-apf9328.c
+ *
+ * Copyright (c) 2005-2011 ARMadeus systems <support@armadeus.com>
+ *
+ * This work is based on mach-scb9328.c which is:
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx1.h>
+
+#include "devices-imx1.h"
+
+static const int apf9328_pins[] __initconst = {
+ /* UART1 */
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+ /* UART2 */
+ PB28_PF_UART2_CTS,
+ PB29_PF_UART2_RTS,
+ PB30_PF_UART2_TXD,
+ PB31_PF_UART2_RXD,
+};
+
+/*
+ * The APF9328 can have up to 32MB NOR Flash
+ */
+static struct resource flash_resource = {
+ .start = MX1_CS0_PHYS,
+ .end = MX1_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data apf9328_flash_data = {
+ .width = 2,
+};
+
+static struct platform_device apf9328_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &apf9328_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * APF9328 has a DM9000 Ethernet controller
+ */
+static struct dm9000_plat_data dm9000_setup = {
+ .flags = DM9000_PLATF_16BITONLY
+};
+
+static struct resource dm9000_resources[] = {
+ {
+ .start = MX1_CS4_PHYS + 0x00C00000,
+ .end = MX1_CS4_PHYS + 0x00C00001,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX1_CS4_PHYS + 0x00C00002,
+ .end = MX1_CS4_PHYS + 0x00C00003,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_GPIOB(14),
+ .end = IRQ_GPIOB(14),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct platform_device dm9000x_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000_resources),
+ .resource = dm9000_resources,
+ .dev = {
+ .platform_data = &dm9000_setup,
+ }
+};
+
+/* --- SERIAL RESSOURCE --- */
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+ .flags = 0,
+};
+
+static const struct imxuart_platform_data uart1_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &apf9328_flash_device,
+ &dm9000x_device,
+};
+
+static void __init apf9328_init(void)
+{
+ mxc_gpio_setup_multiple_pins(apf9328_pins,
+ ARRAY_SIZE(apf9328_pins),
+ "APF9328");
+
+ imx1_add_imx_uart0(&uart0_pdata);
+ imx1_add_imx_uart1(&uart1_pdata);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init apf9328_timer_init(void)
+{
+ mx1_clocks_init(32768);
+}
+
+static struct sys_timer apf9328_timer = {
+ .init = apf9328_timer_init,
+};
+
+MACHINE_START(APF9328, "Armadeus APF9328")
+ /* Maintainer: Gwenhael Goavec-Merou, ARMadeus Systems */
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .timer = &apf9328_timer,
+ .init_machine = apf9328_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
new file mode 100644
index 00000000..ffb40ff6
--- /dev/null
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -0,0 +1,565 @@
+/*
+ * armadillo5x0.c
+ *
+ * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * updates in http://alberdroid.blogspot.com/
+ *
+ * Based on Atmark Techno, Inc. armadillo 500 BSP 2008
+ * Based on mx31ads.c and pcm037.c Great Work!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+#include "crmregs-imx31.h"
+
+static int armadillo5x0_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ /* UART2 */
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ /* LAN9118_IRQ */
+ IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO),
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/
+ /* I2C2 */
+ MX31_PIN_CSPI2_MOSI__SCL,
+ MX31_PIN_CSPI2_MISO__SDA,
+ /* OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+ MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+ MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /* USB host 2 */
+ IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+/* USB */
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+ int err;
+
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+ /* Chip already enabled by hardware */
+ /* OTG phy reset*/
+ err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+ if (err) {
+ pr_err("Failed to request the usb otg reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+ if (err) {
+ pr_err("Failed to reset the usb otg phy\n");
+ goto otg_free_reset;
+ }
+
+ gpio_set_value(OTG_RESET, 0/*LOW*/);
+ mdelay(5);
+ gpio_set_value(OTG_RESET, 1/*HIGH*/);
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_DIFF_UNI);
+
+otg_free_reset:
+ gpio_free(OTG_RESET);
+ return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+ int err;
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+ /* Enable the chip */
+ err = gpio_request(USBH2_CS, "USB-H2-CS");
+ if (err) {
+ pr_err("Failed to request the usb host 2 CS gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+ if (err) {
+ pr_err("Failed to drive the usb host 2 CS gpio\n");
+ goto h2_free_cs;
+ }
+
+ /* H2 phy reset*/
+ err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+ if (err) {
+ pr_err("Failed to request the usb host 2 reset gpio\n");
+ goto h2_free_cs;
+ }
+
+ err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+ if (err) {
+ pr_err("Failed to reset the usb host 2 phy\n");
+ goto h2_free_reset;
+ }
+
+ gpio_set_value(USBH2_RESET, 0/*LOW*/);
+ mdelay(5);
+ gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_DIFF_UNI);
+
+h2_free_reset:
+ gpio_free(USBH2_RESET);
+h2_free_cs:
+ gpio_free(USBH2_CS);
+ return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata __initdata = {
+ .init = usbotg_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+/* RTC over I2C*/
+#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4)
+
+static struct i2c_board_info armadillo5x0_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/* GPIO BUTTONS */
+static struct gpio_keys_button armadillo5x0_buttons[] = {
+ {
+ .code = KEY_ENTER, /*28*/
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SCLK0),
+ .active_low = 1,
+ .desc = "menu",
+ .wakeup = 1,
+ }, {
+ .code = KEY_BACK, /*158*/
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SRST0),
+ .active_low = 1,
+ .desc = "back",
+ .wakeup = 1,
+ }
+};
+
+static const struct gpio_keys_platform_data
+ armadillo5x0_button_data __initconst = {
+ .buttons = armadillo5x0_buttons,
+ .nbuttons = ARRAY_SIZE(armadillo5x0_buttons),
+};
+
+/*
+ * NAND Flash
+ */
+static const struct mxc_nand_platform_data
+armadillo5x0_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+/*
+ * MTD NOR Flash
+ */
+static struct mtd_partition armadillo5x0_nor_flash_partitions[] = {
+ {
+ .name = "nor.bootloader",
+ .offset = 0x00000000,
+ .size = 4*32*1024,
+ }, {
+ .name = "nor.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16*128*1024,
+ }, {
+ .name = "nor.userland",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 110*128*1024,
+ }, {
+ .name = "nor.config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1*128*1024,
+ },
+};
+
+static struct physmap_flash_data armadillo5x0_nor_flash_pdata = {
+ .width = 2,
+ .parts = armadillo5x0_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions),
+};
+
+static struct resource armadillo5x0_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MX31_CS0_BASE_ADDR,
+ .end = MX31_CS0_BASE_ADDR + SZ_64M - 1,
+};
+
+static struct platform_device armadillo5x0_nor_flash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &armadillo5x0_nor_flash_resource,
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+ { /* 640x480 @ 60 Hz */
+ .name = "CRT-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 35,
+ .right_margin = 115,
+ .upper_margin = 43,
+ .lower_margin = 1,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {/* 800x600 @ 56 Hz */
+ .name = "CRT-SVGA",
+ .refresh = 56,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000,
+ .left_margin = 30,
+ .right_margin = 108,
+ .upper_margin = 13,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "CRT-VGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+/*
+ * SDHC 1
+ * MMC support
+ */
+static int armadillo5x0_sdhc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static int armadillo5x0_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+ int gpio_det, gpio_wp;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B);
+
+ ret = gpio_request(gpio_det, "sdhc-card-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(gpio_det);
+
+ ret = gpio_request(gpio_wp, "sdhc-write-protect");
+ if (ret)
+ goto err_gpio_free;
+
+ gpio_direction_input(gpio_wp);
+
+ /* When supported the trigger type have to be BOTH */
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "sdhc-detect", data);
+
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(gpio_wp);
+
+err_gpio_free:
+ gpio_free(gpio_det);
+
+ return ret;
+
+}
+
+static void armadillo5x0_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_ATA_DMACK), data);
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_DMACK));
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_ATA_RESET_B));
+}
+
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
+ .get_ro = armadillo5x0_sdhc1_get_ro,
+ .init = armadillo5x0_sdhc1_init,
+ .exit = armadillo5x0_sdhc1_exit,
+};
+
+/*
+ * SMSC 9118
+ * Network support
+ */
+static struct resource armadillo5x0_smc911x_resources[] = {
+ {
+ .start = MX31_CS3_BASE_ADDR,
+ .end = MX31_CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_16BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device armadillo5x0_smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(armadillo5x0_smc911x_resources),
+ .resource = armadillo5x0_smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/* UART device data */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &armadillo5x0_smc911x_device,
+};
+
+/*
+ * Perform board specific initializations
+ */
+static void __init armadillo5x0_init(void)
+{
+ mxc_iomux_setup_multiple_pins(armadillo5x0_pins,
+ ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx_add_gpio_keys(&armadillo5x0_button_data);
+ imx31_add_imx_i2c1(NULL);
+
+ /* Register UART */
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
+
+ /* SMSC9118 IRQ pin */
+ gpio_direction_input(MX31_PIN_GPIO1_0);
+
+ /* Register SDHC */
+ imx31_add_mxc_mmc(0, &sdhc_pdata);
+
+ /* Register FB */
+ imx31_add_ipu_core(&mx3_ipu_data);
+ imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ /* Register NOR Flash */
+ mxc_register_device(&armadillo5x0_nor_flash,
+ &armadillo5x0_nor_flash_pdata);
+
+ /* Register NAND Flash */
+ imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
+
+ /* set NAND page size to 2k if not configured via boot mode pins */
+ __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
+
+ /* RTC */
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(ARMADILLO5X0_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(ARMADILLO5X0_RTC_GPIO) == 0)
+ armadillo5x0_i2c_rtc.irq = gpio_to_irq(ARMADILLO5X0_RTC_GPIO);
+ else
+ gpio_free(ARMADILLO5X0_RTC_GPIO);
+ }
+ if (armadillo5x0_i2c_rtc.irq == 0)
+ pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+ /* USB */
+
+ usbotg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbotg_pdata.otg)
+ imx31_add_mxc_ehci_otg(&usbotg_pdata);
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+}
+
+static void __init armadillo5x0_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer armadillo5x0_timer = {
+ .init = armadillo5x0_timer_init,
+};
+
+MACHINE_START(ARMADILLO5X0, "Armadillo-500")
+ /* Maintainer: Alberto Panizzo */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &armadillo5x0_timer,
+ .init_machine = armadillo5x0_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-bug.c b/arch/arm/mach-imx/mach-bug.c
new file mode 100644
index 00000000..42e4f078
--- /dev/null
+++ b/arch/arm/mach-imx/mach-bug.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/iomux-mx3.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "devices-imx31.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const unsigned int bug_pins[] __initconst = {
+ MX31_PIN_PC_RST__CTS5,
+ MX31_PIN_PC_VS2__RTS5,
+ MX31_PIN_PC_BVD2__TXD5,
+ MX31_PIN_PC_BVD1__RXD5,
+};
+
+static void __init bug_board_init(void)
+{
+ mxc_iomux_setup_multiple_pins(bug_pins,
+ ARRAY_SIZE(bug_pins), "uart-4");
+ imx31_add_imx_uart4(&uart_pdata);
+}
+
+static void __init bug_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer bug_timer = {
+ .init = bug_timer_init,
+};
+
+MACHINE_START(BUG, "BugLabs BUGBase")
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &bug_timer,
+ .init_machine = bug_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
new file mode 100644
index 00000000..46a2e41d
--- /dev/null
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm038.c which is :
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx27.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx27.h"
+
+static const int eukrea_cpuimx27_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART4 */
+#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+#endif
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* SDHC2 */
+#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+#endif
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+ /* Quad UART's IRQ */
+ GPIO_PORTB | 22 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 27 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 30 | GPIO_GPIO | GPIO_IN,
+#endif
+ /* OTG */
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PC9_PF_USBOTG_DATA0,
+ PC10_PF_USBOTG_DATA2,
+ PC11_PF_USBOTG_DATA1,
+ PC12_PF_USBOTG_DATA4,
+ PC13_PF_USBOTG_DATA3,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PE2_PF_USBOTG_DIR,
+ PE24_PF_USBOTG_CLK,
+ PE25_PF_USBOTG_DATA7,
+ /* USBH2 */
+ PA0_PF_USBH2_CLK,
+ PA1_PF_USBH2_DIR,
+ PA2_PF_USBH2_DATA7,
+ PA3_PF_USBH2_NXT,
+ PA4_PF_USBH2_STP,
+ PD19_AF_USBH2_DATA4,
+ PD20_AF_USBH2_DATA3,
+ PD21_AF_USBH2_DATA6,
+ PD22_AF_USBH2_DATA0,
+ PD23_AF_USBH2_DATA2,
+ PD24_AF_USBH2_DATA1,
+ PD26_AF_USBH2_DATA5,
+};
+
+static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
+ .width = 2,
+};
+
+static struct resource eukrea_cpuimx27_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc3ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &eukrea_cpuimx27_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &eukrea_cpuimx27_flash_resource,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct mxc_nand_platform_data
+cpuimx27_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_cpuimx27_nor_mtd_device,
+};
+
+static const struct imxi2c_platform_data cpuimx27_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx27_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x200000),
+ .irq = IRQ_GPIOB(23),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x400000),
+ .irq = IRQ_GPIOB(22),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x800000),
+ .irq = IRQ_GPIOB(27),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX27_CS3_BASE_ADDR + 0x1000000),
+ .irq = IRQ_GPIOB(30),
+ .uartclk = 14745600,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ }
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+#endif
+
+static int eukrea_cpuimx27_otg_init(struct platform_device *pdev)
+{
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = eukrea_cpuimx27_otg_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int eukrea_cpuimx27_usbh2_init(struct platform_device *pdev)
+{
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = eukrea_cpuimx27_usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx27_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx27_otg_mode);
+
+static void __init eukrea_cpuimx27_init(void)
+{
+ mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
+ ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
+
+ imx27_add_imx_uart0(&uart_pdata);
+
+ imx27_add_mxc_nand(&cpuimx27_nand_board_info);
+
+ i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
+
+ imx27_add_imx_i2c(0, &cpuimx27_i2c1_data);
+
+ imx27_add_fec(NULL);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
+
+#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
+ /* SDHC2 can be used for Wifi */
+ imx27_add_mxc_mmc(1, NULL);
+#endif
+#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
+ /* in which case UART4 is also used for Bluetooth */
+ imx27_add_imx_uart3(&uart_pdata);
+#endif
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+ platform_device_register(&serial_device);
+#endif
+
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (otg_pdata.otg)
+ imx27_add_mxc_ehci_otg(&otg_pdata);
+ } else {
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
+ }
+
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
+ eukrea_mbimx27_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx27_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer eukrea_cpuimx27_timer = {
+ .init = eukrea_cpuimx27_timer_init,
+};
+
+MACHINE_START(CPUIMX27, "EUKREA CPUIMX27")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &eukrea_cpuimx27_timer,
+ .init_machine = eukrea_cpuimx27_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-cpuimx35.c b/arch/arm/mach-imx/mach-cpuimx35.c
new file mode 100644
index 00000000..3f8ef825
--- /dev/null
+++ b/arch/arm/mach-imx/mach-cpuimx35.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+
+#include "devices-imx35.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data
+ eukrea_cpuimx35_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+};
+
+#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)
+static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = gpio_to_irq(TSC2007_IRQGPIO),
+ },
+};
+
+static iomux_v3_cfg_t eukrea_cpuimx35_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+ /* I2C1 */
+ MX35_PAD_I2C1_CLK__I2C1_SCL,
+ MX35_PAD_I2C1_DAT__I2C1_SDA,
+ /* TSC2007 IRQ */
+ MX35_PAD_ATA_DA2__GPIO3_2,
+};
+
+static const struct mxc_nand_platform_data
+ eukrea_cpuimx35_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static int eukrea_cpuimx35_otg_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static const struct mxc_usbh_platform_data otg_pdata __initconst = {
+ .init = eukrea_cpuimx35_otg_init,
+ .portsc = MXC_EHCI_MODE_UTMI,
+};
+
+static int eukrea_cpuimx35_usbh1_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+ .init = eukrea_cpuimx35_usbh1_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+ .workaround = FLS_USB2_WORKAROUND_ENGCM09152,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx35_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx35_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init eukrea_cpuimx35_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
+ ARRAY_SIZE(eukrea_cpuimx35_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt(NULL);
+
+ imx35_add_imx_uart0(&uart_pdata);
+ imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
+
+ i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx35_i2c_devices));
+ imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
+
+ if (otg_mode_host)
+ imx35_add_mxc_ehci_otg(&otg_pdata);
+ else
+ imx35_add_fsl_usb2_udc(&otg_device_pdata);
+
+ imx35_add_mxc_ehci_hs(&usbh1_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD
+ eukrea_mbimxsd35_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx35_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer eukrea_cpuimx35_timer = {
+ .init = eukrea_cpuimx35_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
+ /* Maintainer: Eukrea Electromatique */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .timer = &eukrea_cpuimx35_timer,
+ .init_machine = eukrea_cpuimx35_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-eukrea_cpuimx25.c b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
new file mode 100644
index 00000000..148cff28
--- /dev/null
+++ b/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ * Copyright 2010 Eric Bénard - Eukréa Electromatique, <eric@eukrea.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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+#include <mach/iomux-mx25.h>
+
+#include "devices-imx25.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static iomux_v3_cfg_t eukrea_cpuimx25_pads[] = {
+ /* FEC - RMII */
+ MX25_PAD_FEC_MDC__FEC_MDC,
+ MX25_PAD_FEC_MDIO__FEC_MDIO,
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0,
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1,
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0,
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1,
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ /* I2C1 */
+ MX25_PAD_I2C1_CLK__I2C1_CLK,
+ MX25_PAD_I2C1_DAT__I2C1_DAT,
+};
+
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct mxc_nand_platform_data
+eukrea_cpuimx25_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static const struct imxi2c_platform_data
+eukrea_cpuimx25_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx25_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static int eukrea_cpuimx25_otg_init(struct platform_device *pdev)
+{
+ return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static const struct mxc_usbh_platform_data otg_pdata __initconst = {
+ .init = eukrea_cpuimx25_otg_init,
+ .portsc = MXC_EHCI_MODE_UTMI,
+};
+
+static int eukrea_cpuimx25_usbh2_init(struct platform_device *pdev)
+{
+ return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
+}
+
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
+ .init = eukrea_cpuimx25_usbh2_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx25_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx25_otg_mode);
+
+static void __init eukrea_cpuimx25_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
+ ARRAY_SIZE(eukrea_cpuimx25_pads)))
+ printk(KERN_ERR "error setting cpuimx25 pads !\n");
+
+ imx25_add_imx_uart0(&uart_pdata);
+ imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
+ imx25_add_imxdi_rtc(NULL);
+ imx25_add_fec(&mx25_fec_pdata);
+
+ i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx25_i2c_devices));
+ imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data);
+
+ if (otg_mode_host)
+ imx25_add_mxc_ehci_otg(&otg_pdata);
+ else
+ imx25_add_fsl_usb2_udc(&otg_device_pdata);
+
+ imx25_add_mxc_ehci_hs(&usbh2_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD
+ eukrea_mbimxsd25_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx25_timer_init(void)
+{
+ mx25_clocks_init();
+}
+
+static struct sys_timer eukrea_cpuimx25_timer = {
+ .init = eukrea_cpuimx25_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25")
+ /* Maintainer: Eukrea Electromatique */
+ .boot_params = MX25_PHYS_OFFSET + 0x100,
+ .map_io = mx25_map_io,
+ .init_early = imx25_init_early,
+ .init_irq = mx25_init_irq,
+ .timer = &eukrea_cpuimx25_timer,
+ .init_machine = eukrea_cpuimx25_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
new file mode 100644
index 00000000..7ae43b1e
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -0,0 +1,269 @@
+/*
+ * mach-imx27_visstrim_m10.c
+ *
+ * Copyright 2010 Javier Martin <javier.martin@vista-silicon.com>
+ *
+ * Based on mach-pcm038.c, mach-pca100.c, mach-mx27ads.c and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+#include "devices-imx27.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTF + 17)
+#define SDHC1_IRQ IRQ_GPIOB(25)
+
+static const int visstrim_m10_pins[] __initconst = {
+ /* UART1 (console) */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SSI1 */
+ PC20_PF_SSI1_FS,
+ PC21_PF_SSI1_RXD,
+ PC22_PF_SSI1_TXD,
+ PC23_PF_SSI1_CLK,
+ /* SDHC1 */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* Both I2Cs */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* USB OTG */
+ OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ PC9_PF_USBOTG_DATA0,
+ PC11_PF_USBOTG_DATA1,
+ PC10_PF_USBOTG_DATA2,
+ PC13_PF_USBOTG_DATA3,
+ PC12_PF_USBOTG_DATA4,
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PE25_PF_USBOTG_DATA7,
+ PE24_PF_USBOTG_CLK,
+ PE2_PF_USBOTG_DIR,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PB23_PF_USB_PWR,
+ PB24_PF_USB_OC,
+};
+
+/* GPIOs used as events for applications */
+static struct gpio_keys_button visstrim_gpio_keys[] = {
+ {
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .gpio = (GPIO_PORTC + 15),
+ .desc = "Default config",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_RECORD,
+ .gpio = (GPIO_PORTF + 14),
+ .desc = "Record",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_STOP,
+ .gpio = (GPIO_PORTF + 13),
+ .desc = "Stop",
+ .active_low = 0,
+ .wakeup = 1,
+ }
+};
+
+static const struct gpio_keys_platform_data
+ visstrim_gpio_keys_platform_data __initconst = {
+ .buttons = visstrim_gpio_keys,
+ .nbuttons = ARRAY_SIZE(visstrim_gpio_keys),
+};
+
+/* Visstrim_SM10 has a microSD slot connected to sdhc1 */
+static int visstrim_m10_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ ret = request_irq(SDHC1_IRQ, detect_irq, IRQF_TRIGGER_FALLING,
+ "mmc-detect", data);
+ return ret;
+}
+
+static void visstrim_m10_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(SDHC1_IRQ, data);
+}
+
+static const struct imxmmc_platform_data visstrim_m10_sdhc_pdata __initconst = {
+ .init = visstrim_m10_sdhc1_init,
+ .exit = visstrim_m10_sdhc1_exit,
+};
+
+/* Visstrim_SM10 NOR flash */
+static struct physmap_flash_data visstrim_m10_flash_data = {
+ .width = 2,
+};
+
+static struct resource visstrim_m10_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device visstrim_m10_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &visstrim_m10_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &visstrim_m10_flash_resource,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &visstrim_m10_nor_mtd_device,
+};
+
+/* Visstrim_M10 uses UART0 as console */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* I2C */
+static const struct imxi2c_platform_data visstrim_m10_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct pca953x_platform_data visstrim_m10_pca9555_pdata = {
+ .gpio_base = 240, /* After MX27 internal GPIOs */
+ .invert = 0,
+};
+
+static struct i2c_board_info visstrim_m10_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ .platform_data = &visstrim_m10_pca9555_pdata,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic32x4", 0x18),
+ }
+};
+
+/* USB OTG */
+static int otg_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+
+ mdelay(10);
+
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static const struct mxc_usbh_platform_data
+visstrim_m10_usbotg_pdata __initconst = {
+ .init = otg_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+/* SSI */
+static const struct imx_ssi_platform_data visstrim_m10_ssi_pdata __initconst = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static void __init visstrim_m10_board_init(void)
+{
+ int ret;
+
+ ret = mxc_gpio_setup_multiple_pins(visstrim_m10_pins,
+ ARRAY_SIZE(visstrim_m10_pins), "VISSTRIM_M10");
+ if (ret)
+ pr_err("Failed to setup pins (%d)\n", ret);
+
+ imx27_add_imx_ssi(0, &visstrim_m10_ssi_pdata);
+ imx27_add_imx_uart0(&uart_pdata);
+
+ i2c_register_board_info(0, visstrim_m10_i2c_devices,
+ ARRAY_SIZE(visstrim_m10_i2c_devices));
+ imx27_add_imx_i2c(0, &visstrim_m10_i2c_data);
+ imx27_add_imx_i2c(1, &visstrim_m10_i2c_data);
+ imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
+ imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
+ imx27_add_fec(NULL);
+ imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init visstrim_m10_timer_init(void)
+{
+ mx27_clocks_init((unsigned long)25000000);
+}
+
+static struct sys_timer visstrim_m10_timer = {
+ .init = visstrim_m10_timer_init,
+};
+
+MACHINE_START(IMX27_VISSTRIM_M10, "Vista Silicon Visstrim_M10")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &visstrim_m10_timer,
+ .init_machine = visstrim_m10_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx27ipcam.c b/arch/arm/mach-imx/mach-imx27ipcam.c
new file mode 100644
index 00000000..9be6cd6f
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27ipcam.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx27.h>
+
+#include "devices-imx27.h"
+
+static const int mx27ipcam_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+};
+
+static void __init mx27ipcam_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx27ipcam_pins, ARRAY_SIZE(mx27ipcam_pins),
+ "mx27ipcam");
+
+ imx27_add_imx_uart0(NULL);
+ imx27_add_fec(NULL);
+ imx27_add_imx2_wdt(NULL);
+}
+
+static void __init mx27ipcam_timer_init(void)
+{
+ mx27_clocks_init(25000000);
+}
+
+static struct sys_timer mx27ipcam_timer = {
+ .init = mx27ipcam_timer_init,
+};
+
+MACHINE_START(IMX27IPCAM, "Freescale IMX27IPCAM")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &mx27ipcam_timer,
+ .init_machine = mx27ipcam_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
new file mode 100644
index 00000000..84114051
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright 2009 Daniel Schaeffer (daniel.schaeffer@timesys.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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx27.h>
+
+#include "devices-imx27.h"
+
+static const int mx27lite_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init mx27lite_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
+ "imx27lite");
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_fec(NULL);
+}
+
+static void __init mx27lite_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27lite_timer = {
+ .init = mx27lite_timer_init,
+};
+
+MACHINE_START(IMX27LITE, "LogicPD i.MX27LITE")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &mx27lite_timer,
+ .init_machine = mx27lite_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-kzm_arm11_01.c b/arch/arm/mach-imx/mach-kzm_arm11_01.c
new file mode 100644
index 00000000..1ecae20c
--- /dev/null
+++ b/arch/arm/mach-imx/mach-kzm_arm11_01.c
@@ -0,0 +1,278 @@
+/*
+ * KZM-ARM11-01 support
+ * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.org>
+ *
+ * based on code for MX31ADS,
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/types.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/memory.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/clock.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices-imx31.h"
+
+#define KZM_ARM11_IO_ADDRESS(x) (IOMEM( \
+ IMX_IO_P2V_MODULE(x, MX31_CS4) ?: \
+ IMX_IO_P2V_MODULE(x, MX31_CS5)) ?: \
+ MX31_IO_ADDRESS(x))
+
+/*
+ * KZM-ARM11-01 Board Control Registers on FPGA
+ */
+#define KZM_ARM11_CTL1 (MX31_CS4_BASE_ADDR + 0x1000)
+#define KZM_ARM11_CTL2 (MX31_CS4_BASE_ADDR + 0x1001)
+#define KZM_ARM11_RSW1 (MX31_CS4_BASE_ADDR + 0x1002)
+#define KZM_ARM11_BACK_LIGHT (MX31_CS4_BASE_ADDR + 0x1004)
+#define KZM_ARM11_FPGA_REV (MX31_CS4_BASE_ADDR + 0x1008)
+#define KZM_ARM11_7SEG_LED (MX31_CS4_BASE_ADDR + 0x1010)
+#define KZM_ARM11_LEDS (MX31_CS4_BASE_ADDR + 0x1020)
+#define KZM_ARM11_DIPSW2 (MX31_CS4_BASE_ADDR + 0x1003)
+
+/*
+ * External UART for touch panel on FPGA
+ */
+#define KZM_ARM11_16550 (MX31_CS4_BASE_ADDR + 0x1050)
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+/*
+ * KZM-ARM11-01 has an external UART on FPGA
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = KZM_ARM11_IO_ADDRESS(KZM_ARM11_16550),
+ .mapbase = KZM_ARM11_16550,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .irqflags = IRQ_TYPE_EDGE_RISING,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_BUGGY_UART,
+ },
+ {},
+};
+
+static struct resource serial8250_resources[] = {
+ {
+ .start = KZM_ARM11_16550,
+ .end = KZM_ARM11_16550 + 0x10,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(serial8250_resources),
+ .resource = serial8250_resources,
+};
+
+static int __init kzm_init_ext_uart(void)
+{
+ u8 tmp;
+
+ /*
+ * GPIO 1-1: external UART interrupt line
+ */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO));
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "ext-uart-int");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
+
+ /*
+ * Unmask UART interrupt
+ */
+ tmp = __raw_readb(KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+ tmp |= 0x2;
+ __raw_writeb(tmp, KZM_ARM11_IO_ADDRESS(KZM_ARM11_CTL1));
+
+ return platform_device_register(&serial_device);
+}
+#else
+static inline int kzm_init_ext_uart(void)
+{
+ return 0;
+}
+#endif
+
+/*
+ * SMSC LAN9118
+ */
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct smsc911x_platform_config kzm_smsc9118_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct resource kzm_smsc9118_resources[] = {
+ {
+ .start = MX31_CS5_BASE_ADDR,
+ .end = MX31_CS5_BASE_ADDR + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device kzm_smsc9118_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kzm_smsc9118_resources),
+ .resource = kzm_smsc9118_resources,
+ .dev = {
+ .platform_data = &kzm_smsc9118_config,
+ },
+};
+
+static int __init kzm_init_smsc9118(void)
+{
+ /*
+ * GPIO 1-2: SMSC9118 interrupt line
+ */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO));
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2), "smsc9118-int");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_2));
+
+ return platform_device_register(&kzm_smsc9118_device);
+}
+#else
+static inline int kzm_init_smsc9118(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init kzm_init_imx_uart(void)
+{
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
+}
+#else
+static inline void kzm_init_imx_uart(void)
+{
+}
+#endif
+
+static int kzm_pins[] __initdata = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ MX31_PIN_DCD_DCE1__DCD_DCE1,
+ MX31_PIN_RI_DCE1__RI_DCE1,
+ MX31_PIN_DSR_DCE1__DSR_DCE1,
+ MX31_PIN_DTR_DCE1__DTR_DCE1,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_DCD_DTE1__DCD_DTE2,
+ MX31_PIN_RI_DTE1__RI_DTE2,
+ MX31_PIN_DSR_DTE1__DSR_DTE2,
+ MX31_PIN_DTR_DTE1__DTR_DTE2,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init kzm_board_init(void)
+{
+ mxc_iomux_setup_multiple_pins(kzm_pins,
+ ARRAY_SIZE(kzm_pins), "kzm");
+ kzm_init_ext_uart();
+ kzm_init_smsc9118();
+ kzm_init_imx_uart();
+
+ pr_info("Clock input source is 26MHz\n");
+}
+
+/*
+ * This structure defines static mappings for the kzm-arm11-01 board.
+ */
+static struct map_desc kzm_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = MX31_CS5_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
+ .length = MX31_CS5_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+static void __init kzm_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(kzm_io_desc, ARRAY_SIZE(kzm_io_desc));
+}
+
+static void __init kzm_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer kzm_timer = {
+ .init = kzm_timer_init,
+};
+
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = kzm_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &kzm_timer,
+ .init_machine = kzm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
new file mode 100644
index 00000000..38ec5cbb
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -0,0 +1,161 @@
+/*
+ * arch/arm/mach-imx/mach-mx1ads.c
+ *
+ * Initially based on:
+ * linux-2.6.7-imx/arch/arm/mach-imx/scb9328.c
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ *
+ * 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx1.h>
+#include <mach/irqs.h>
+
+#include "devices-imx1.h"
+
+static const int mx1ads_pins[] __initconst = {
+ /* UART1 */
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+ /* UART2 */
+ PB28_PF_UART2_CTS,
+ PB29_PF_UART2_RTS,
+ PB30_PF_UART2_TXD,
+ PB31_PF_UART2_RXD,
+ /* I2C */
+ PA15_PF_I2C_SDA,
+ PA16_PF_I2C_SCL,
+ /* SPI */
+ PC13_PF_SPI1_SPI_RDY,
+ PC14_PF_SPI1_SCLK,
+ PC15_PF_SPI1_SS,
+ PC16_PF_SPI1_MISO,
+ PC17_PF_SPI1_MOSI,
+};
+
+/*
+ * UARTs platform data
+ */
+
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxuart_platform_data uart1_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/*
+ * Physmap flash
+ */
+
+static struct physmap_flash_data mx1ads_flash_data = {
+ .width = 4, /* bankwidth in bytes */
+};
+
+static struct resource flash_resource = {
+ .start = MX1_CS0_PHYS,
+ .end = MX1_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * I2C
+ */
+static struct pcf857x_platform_data pcf857x_data[] = {
+ {
+ .gpio_base = 4 * 32,
+ }, {
+ .gpio_base = 4 * 32 + 16,
+ }
+};
+
+static const struct imxi2c_platform_data mx1ads_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mx1ads_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x22),
+ .platform_data = &pcf857x_data[0],
+ }, {
+ I2C_BOARD_INFO("pcf8575", 0x24),
+ .platform_data = &pcf857x_data[1],
+ },
+};
+
+/*
+ * Board init
+ */
+static void __init mx1ads_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx1ads_pins,
+ ARRAY_SIZE(mx1ads_pins), "mx1ads");
+
+ /* UART */
+ imx1_add_imx_uart0(&uart0_pdata);
+ imx1_add_imx_uart1(&uart1_pdata);
+
+ /* Physmap flash */
+ mxc_register_device(&flash_device, &mx1ads_flash_data);
+
+ /* I2C */
+ i2c_register_board_info(0, mx1ads_i2c_devices,
+ ARRAY_SIZE(mx1ads_i2c_devices));
+
+ imx1_add_imx_i2c(&mx1ads_i2c_data);
+}
+
+static void __init mx1ads_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+struct sys_timer mx1ads_timer = {
+ .init = mx1ads_timer_init,
+};
+
+MACHINE_START(MX1ADS, "Freescale MX1ADS")
+ /* Maintainer: Sascha Hauer, Pengutronix */
+ .boot_params = MX1_PHYS_OFFSET + 0x100,
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .timer = &mx1ads_timer,
+ .init_machine = mx1ads_init,
+MACHINE_END
+
+MACHINE_START(MXLADS, "Freescale MXLADS")
+ .boot_params = MX1_PHYS_OFFSET + 0x100,
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .timer = &mx1ads_timer,
+ .init_machine = mx1ads_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
new file mode 100644
index 00000000..a37fe021
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/iomux-mx21.h>
+
+#include "devices-imx21.h"
+
+/*
+ * Memory-mapped I/O on MX21ADS base board
+ */
+#define MX21ADS_MMIO_BASE_ADDR 0xf5000000
+#define MX21ADS_MMIO_SIZE 0xc00000
+
+#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
+ (MX21ADS_MMIO_BASE_ADDR + (offset))
+
+#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
+#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
+#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
+#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
+#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
+
+/* MX21ADS_IO_REG bit definitions */
+#define MX21ADS_IO_SD_WP 0x0001 /* read */
+#define MX21ADS_IO_TP6 0x0001 /* write */
+#define MX21ADS_IO_SW_SEL 0x0002 /* read */
+#define MX21ADS_IO_TP7 0x0002 /* write */
+#define MX21ADS_IO_RESET_E_UART 0x0004
+#define MX21ADS_IO_RESET_BASE 0x0008
+#define MX21ADS_IO_CSI_CTL2 0x0010
+#define MX21ADS_IO_CSI_CTL1 0x0020
+#define MX21ADS_IO_CSI_CTL0 0x0040
+#define MX21ADS_IO_UART1_EN 0x0080
+#define MX21ADS_IO_UART4_EN 0x0100
+#define MX21ADS_IO_LCDON 0x0200
+#define MX21ADS_IO_IRDA_EN 0x0400
+#define MX21ADS_IO_IRDA_FIR_SEL 0x0800
+#define MX21ADS_IO_IRDA_MD0_B 0x1000
+#define MX21ADS_IO_IRDA_MD1 0x2000
+#define MX21ADS_IO_LED4_ON 0x4000
+#define MX21ADS_IO_LED3_ON 0x8000
+
+static const int mx21ads_pins[] __initconst = {
+
+ /* CS8900A */
+ (GPIO_PORTE | GPIO_GPIO | GPIO_IN | 11),
+
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+
+ /* UART3 (IrDA) - only TXD and RXD */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+
+ /* UART4 */
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+
+ /* LCDC */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA24_PF_REV, /* Sharp panel dedicated signal */
+ PA25_PF_CLS, /* Sharp panel dedicated signal */
+ PA26_PF_PS, /* Sharp panel dedicated signal */
+ PA27_PF_SPL_SPR, /* Sharp panel dedicated signal */
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+
+ /* MMC/SDHC */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+
+ /* NFC */
+ PF0_PF_NRFB,
+ PF1_PF_NFCE,
+ PF2_PF_NFWP,
+ PF3_PF_NFCLE,
+ PF4_PF_NFALE,
+ PF5_PF_NFRE,
+ PF6_PF_NFWE,
+ PF7_PF_NFIO0,
+ PF8_PF_NFIO1,
+ PF9_PF_NFIO2,
+ PF10_PF_NFIO3,
+ PF11_PF_NFIO4,
+ PF12_PF_NFIO5,
+ PF13_PF_NFIO6,
+ PF14_PF_NFIO7,
+};
+
+/* ADS's NOR flash: 2x AM29BDS128HE9VKI on 32-bit bus */
+static struct physmap_flash_data mx21ads_flash_data = {
+ .width = 4,
+};
+
+static struct resource mx21ads_flash_resource = {
+ .start = MX21_CS0_BASE_ADDR,
+ .end = MX21_CS0_BASE_ADDR + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx21ads_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx21ads_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mx21ads_flash_resource,
+};
+
+static const struct imxuart_platform_data uart_pdata_rts __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxuart_platform_data uart_pdata_norts __initconst = {
+};
+
+static int mx21ads_fb_init(struct platform_device *pdev)
+{
+ u16 tmp;
+
+ tmp = __raw_readw(MX21ADS_IO_REG);
+ tmp |= MX21ADS_IO_LCDON;
+ __raw_writew(tmp, MX21ADS_IO_REG);
+ return 0;
+}
+
+static void mx21ads_fb_exit(struct platform_device *pdev)
+{
+ u16 tmp;
+
+ tmp = __raw_readw(MX21ADS_IO_REG);
+ tmp &= ~MX21ADS_IO_LCDON;
+ __raw_writew(tmp, MX21ADS_IO_REG);
+}
+
+/*
+ * Connected is a portrait Sharp-QVGA display
+ * of type: LQ035Q7DB02
+ */
+static struct imx_fb_videomode mx21ads_modes[] = {
+ {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .hsync_len = 2,
+ .left_margin = 6,
+ .right_margin = 16,
+ .vsync_len = 1,
+ .upper_margin = 8,
+ .lower_margin = 10,
+ },
+ .pcr = 0xfb108bc7,
+ .bpp = 16,
+ },
+};
+
+static const struct imx_fb_platform_data mx21ads_fb_data __initconst = {
+ .mode = mx21ads_modes,
+ .num_modes = ARRAY_SIZE(mx21ads_modes),
+
+ .pwmr = 0x00a903ff,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020008,
+
+ .init = mx21ads_fb_init,
+ .exit = mx21ads_fb_exit,
+};
+
+static int mx21ads_sdhc_get_ro(struct device *dev)
+{
+ return (__raw_readw(MX21ADS_IO_REG) & MX21ADS_IO_SD_WP) ? 1 : 0;
+}
+
+static int mx21ads_sdhc_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOD(25), detect_irq,
+ IRQF_TRIGGER_FALLING, "mmc-detect", data);
+}
+
+static void mx21ads_sdhc_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOD(25), data);
+}
+
+static const struct imxmmc_platform_data mx21ads_sdhc_pdata __initconst = {
+ .ocr_avail = MMC_VDD_29_30 | MMC_VDD_30_31, /* 3.0V */
+ .get_ro = mx21ads_sdhc_get_ro,
+ .init = mx21ads_sdhc_init,
+ .exit = mx21ads_sdhc_exit,
+};
+
+static const struct mxc_nand_platform_data
+mx21ads_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct map_desc mx21ads_io_desc[] __initdata = {
+ /*
+ * Memory-mapped I/O on MX21ADS Base board:
+ * - CS8900A Ethernet controller
+ * - ST16C2552CJ UART
+ * - CPU and Base board version
+ * - Base board I/O register
+ */
+ {
+ .virtual = MX21ADS_MMIO_BASE_ADDR,
+ .pfn = __phys_to_pfn(MX21_CS1_BASE_ADDR),
+ .length = MX21ADS_MMIO_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init mx21ads_map_io(void)
+{
+ mx21_map_io();
+ iotable_init(mx21ads_io_desc, ARRAY_SIZE(mx21ads_io_desc));
+}
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mx21ads_nor_mtd_device,
+};
+
+static void __init mx21ads_board_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
+ "mx21ads");
+
+ imx21_add_imx_uart0(&uart_pdata_rts);
+ imx21_add_imx_uart2(&uart_pdata_norts);
+ imx21_add_imx_uart3(&uart_pdata_rts);
+ imx21_add_imx_fb(&mx21ads_fb_data);
+ imx21_add_mxc_mmc(0, &mx21ads_sdhc_pdata);
+ imx21_add_mxc_nand(&mx21ads_nand_board_info);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
+
+static void __init mx21ads_timer_init(void)
+{
+ mx21_clocks_init(32768, 26000000);
+}
+
+static struct sys_timer mx21ads_timer = {
+ .init = mx21ads_timer_init,
+};
+
+MACHINE_START(MX21ADS, "Freescale i.MX21ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX21_PHYS_OFFSET + 0x100,
+ .map_io = mx21ads_map_io,
+ .init_early = imx21_init_early,
+ .init_irq = mx21_init_irq,
+ .timer = &mx21ads_timer,
+ .init_machine = mx21ads_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c
new file mode 100644
index 00000000..58ea3fdf
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx25_3ds.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * This machine is known as:
+ * - i.MX25 3-Stack Development System
+ * - i.MX25 Platform Development Kit (i.MX25 PDK)
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+#include <mach/iomux-mx25.h>
+
+#include "devices-imx25.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static iomux_v3_cfg_t mx25pdk_pads[] = {
+ MX25_PAD_FEC_MDC__FEC_MDC,
+ MX25_PAD_FEC_MDIO__FEC_MDIO,
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0,
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1,
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0,
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1,
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX25_PAD_A17__GPIO_2_3, /* FEC_EN, GPIO 35 */
+ MX25_PAD_D12__GPIO_4_8, /* FEC_RESET_B, GPIO 104 */
+
+ /* LCD */
+ MX25_PAD_LD0__LD0,
+ MX25_PAD_LD1__LD1,
+ MX25_PAD_LD2__LD2,
+ MX25_PAD_LD3__LD3,
+ MX25_PAD_LD4__LD4,
+ MX25_PAD_LD5__LD5,
+ MX25_PAD_LD6__LD6,
+ MX25_PAD_LD7__LD7,
+ MX25_PAD_LD8__LD8,
+ MX25_PAD_LD9__LD9,
+ MX25_PAD_LD10__LD10,
+ MX25_PAD_LD11__LD11,
+ MX25_PAD_LD12__LD12,
+ MX25_PAD_LD13__LD13,
+ MX25_PAD_LD14__LD14,
+ MX25_PAD_LD15__LD15,
+ MX25_PAD_GPIO_E__LD16,
+ MX25_PAD_GPIO_F__LD17,
+ MX25_PAD_HSYNC__HSYNC,
+ MX25_PAD_VSYNC__VSYNC,
+ MX25_PAD_LSCLK__LSCLK,
+ MX25_PAD_OE_ACD__OE_ACD,
+ MX25_PAD_CONTRAST__CONTRAST,
+
+ /* Keypad */
+ MX25_PAD_KPP_ROW0__KPP_ROW0,
+ MX25_PAD_KPP_ROW1__KPP_ROW1,
+ MX25_PAD_KPP_ROW2__KPP_ROW2,
+ MX25_PAD_KPP_ROW3__KPP_ROW3,
+ MX25_PAD_KPP_COL0__KPP_COL0,
+ MX25_PAD_KPP_COL1__KPP_COL1,
+ MX25_PAD_KPP_COL2__KPP_COL2,
+ MX25_PAD_KPP_COL3__KPP_COL3,
+
+ /* SD1 */
+ MX25_PAD_SD1_CMD__SD1_CMD,
+ MX25_PAD_SD1_CLK__SD1_CLK,
+ MX25_PAD_SD1_DATA0__SD1_DATA0,
+ MX25_PAD_SD1_DATA1__SD1_DATA1,
+ MX25_PAD_SD1_DATA2__SD1_DATA2,
+ MX25_PAD_SD1_DATA3__SD1_DATA3,
+ MX25_PAD_A14__GPIO_2_0, /* WriteProtect */
+ MX25_PAD_A15__GPIO_2_1, /* CardDetect */
+
+ /* I2C1 */
+ MX25_PAD_I2C1_CLK__I2C1_CLK,
+ MX25_PAD_I2C1_DAT__I2C1_DAT,
+};
+
+static const struct fec_platform_data mx25_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+#define FEC_ENABLE_GPIO IMX_GPIO_NR(2, 3)
+#define FEC_RESET_B_GPIO IMX_GPIO_NR(4, 8)
+
+static void __init mx25pdk_fec_reset(void)
+{
+ gpio_request(FEC_ENABLE_GPIO, "FEC PHY enable");
+ gpio_request(FEC_RESET_B_GPIO, "FEC PHY reset");
+
+ gpio_direction_output(FEC_ENABLE_GPIO, 0); /* drop PHY power */
+ gpio_direction_output(FEC_RESET_B_GPIO, 0); /* assert reset */
+ udelay(2);
+
+ /* turn on PHY power and lift reset */
+ gpio_set_value(FEC_ENABLE_GPIO, 1);
+ gpio_set_value(FEC_RESET_B_GPIO, 1);
+}
+
+static const struct mxc_nand_platform_data
+mx25pdk_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static struct imx_fb_videomode mx25pdk_modes[] = {
+ {
+ .mode = {
+ .name = "CRT-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39683,
+ .left_margin = 45,
+ .right_margin = 114,
+ .upper_margin = 33,
+ .lower_margin = 11,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ },
+ .bpp = 16,
+ .pcr = 0xFA208B80,
+ },
+};
+
+static const struct imx_fb_platform_data mx25pdk_fb_pdata __initconst = {
+ .mode = mx25pdk_modes,
+ .num_modes = ARRAY_SIZE(mx25pdk_modes),
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+static const uint32_t mx25pdk_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_VOLUMEDOWN),
+ KEY(0, 3, KEY_HOME),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_ENTER),
+ KEY(1, 3, KEY_VOLUMEUP),
+ KEY(2, 0, KEY_F6),
+ KEY(2, 1, KEY_F8),
+ KEY(2, 2, KEY_F9),
+ KEY(2, 3, KEY_F10),
+ KEY(3, 0, KEY_F1),
+ KEY(3, 1, KEY_F2),
+ KEY(3, 2, KEY_F3),
+ KEY(3, 3, KEY_POWER),
+};
+
+static const struct matrix_keymap_data mx25pdk_keymap_data __initconst = {
+ .keymap = mx25pdk_keymap,
+ .keymap_size = ARRAY_SIZE(mx25pdk_keymap),
+};
+
+static int mx25pdk_usbh2_init(struct platform_device *pdev)
+{
+ return mx25_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
+}
+
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
+ .init = mx25pdk_usbh2_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
+static const struct imxi2c_platform_data mx25_3ds_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+#define SD1_GPIO_WP IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_CD IMX_GPIO_NR(2, 1)
+
+static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
+ .wp_gpio = SD1_GPIO_WP,
+ .cd_gpio = SD1_GPIO_CD,
+};
+
+static void __init mx25pdk_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
+ ARRAY_SIZE(mx25pdk_pads));
+
+ imx25_add_imx_uart0(&uart_pdata);
+ imx25_add_fsl_usb2_udc(&otg_device_pdata);
+ imx25_add_mxc_ehci_hs(&usbh2_pdata);
+ imx25_add_mxc_nand(&mx25pdk_nand_board_info);
+ imx25_add_imxdi_rtc(NULL);
+ imx25_add_imx_fb(&mx25pdk_fb_pdata);
+ imx25_add_imx2_wdt(NULL);
+
+ mx25pdk_fec_reset();
+ imx25_add_fec(&mx25_fec_pdata);
+ imx25_add_imx_keypad(&mx25pdk_keymap_data);
+
+ imx25_add_sdhci_esdhc_imx(0, &mx25pdk_esdhc_pdata);
+ imx25_add_imx_i2c0(&mx25_3ds_i2c0_data);
+}
+
+static void __init mx25pdk_timer_init(void)
+{
+ mx25_clocks_init();
+}
+
+static struct sys_timer mx25pdk_timer = {
+ .init = mx25pdk_timer_init,
+};
+
+MACHINE_START(MX25_3DS, "Freescale MX25PDK (3DS)")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX25_PHYS_OFFSET + 0x100,
+ .map_io = mx25_map_io,
+ .init_early = imx25_init_early,
+ .init_irq = mx25_init_irq,
+ .timer = &mx25pdk_timer,
+ .init_machine = mx25pdk_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
new file mode 100644
index 00000000..6e1accf9
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This machine is known as:
+ * - i.MX27 3-Stack Development System
+ * - i.MX27 Platform Development Kit (i.MX27 PDK)
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx27.h>
+#include <mach/ulpi.h>
+#include <mach/irqs.h>
+#include <mach/3ds_debugboard.h>
+
+#include "devices-imx27.h"
+
+#define SD1_EN_GPIO (GPIO_PORTB + 25)
+#define OTG_PHY_RESET_GPIO (GPIO_PORTB + 23)
+#define SPI2_SS0 (GPIO_PORTD + 21)
+#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTC + 28)
+
+static const int mx27pdk_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SDHC1 */
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ SD1_EN_GPIO | GPIO_GPIO | GPIO_OUT,
+ /* OTG */
+ OTG_PHY_RESET_GPIO | GPIO_GPIO | GPIO_OUT,
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PC9_PF_USBOTG_DATA0,
+ PC10_PF_USBOTG_DATA2,
+ PC11_PF_USBOTG_DATA1,
+ PC12_PF_USBOTG_DATA4,
+ PC13_PF_USBOTG_DATA3,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PE2_PF_USBOTG_DIR,
+ PE24_PF_USBOTG_CLK,
+ PE25_PF_USBOTG_DATA7,
+ /* CSPI2 */
+ PD22_PF_CSPI2_SCLK,
+ PD23_PF_CSPI2_MISO,
+ PD24_PF_CSPI2_MOSI,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/*
+ * Matrix keyboard
+ */
+
+static const uint32_t mx27_3ds_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_ENTER),
+ KEY(2, 0, KEY_F6),
+ KEY(2, 1, KEY_F8),
+ KEY(2, 2, KEY_F9),
+ KEY(2, 3, KEY_F10),
+};
+
+static const struct matrix_keymap_data mx27_3ds_keymap_data __initconst = {
+ .keymap = mx27_3ds_keymap,
+ .keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
+};
+
+static int mx27_3ds_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOB(26), detect_irq, IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING, "sdhc1-card-detect", data);
+}
+
+static void mx27_3ds_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOB(26), data);
+}
+
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
+ .init = mx27_3ds_sdhc1_init,
+ .exit = mx27_3ds_sdhc1_exit,
+};
+
+static void mx27_3ds_sdhc1_enable_level_translator(void)
+{
+ /* Turn on TXB0108 OE pin */
+ gpio_request(SD1_EN_GPIO, "sd1_enable");
+ gpio_direction_output(SD1_EN_GPIO, 1);
+}
+
+
+static int otg_phy_init(void)
+{
+ gpio_request(OTG_PHY_RESET_GPIO, "usb-otg-reset");
+ gpio_direction_output(OTG_PHY_RESET_GPIO, 0);
+ mdelay(1);
+ gpio_set_value(OTG_PHY_RESET_GPIO, 1);
+ return 0;
+}
+
+static int mx27_3ds_otg_init(struct platform_device *pdev)
+{
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = mx27_3ds_otg_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init mx27_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", mx27_3ds_otg_mode);
+
+/* Regulators */
+static struct regulator_consumer_supply vmmc1_consumers[] = {
+ REGULATOR_SUPPLY("lcd_2v8", NULL),
+};
+
+static struct regulator_init_data vmmc1_init = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
+ .consumer_supplies = vmmc1_consumers,
+};
+
+static struct regulator_consumer_supply vgen_consumers[] = {
+ REGULATOR_SUPPLY("vdd_lcdio", NULL),
+};
+
+static struct regulator_init_data vgen_init = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
+ .consumer_supplies = vgen_consumers,
+};
+
+static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
+ {
+ .id = MC13783_REG_VMMC1,
+ .init_data = &vmmc1_init,
+ }, {
+ .id = MC13783_REG_VGEN,
+ .init_data = &vgen_init,
+ },
+};
+
+/* MC13783 */
+static struct mc13xxx_platform_data mc13783_pdata = {
+ .regulators = {
+ .regulators = mx27_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
+
+ },
+ .flags = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi2_internal_chipselect[] = {SPI2_SS0};
+
+static const struct spi_imx_master spi2_pdata __initconst = {
+ .chipselect = spi2_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi2_internal_chipselect),
+};
+
+static struct spi_board_info mx27_3ds_spi_devs[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0, /* SS0 */
+ .platform_data = &mc13783_pdata,
+ .irq = IRQ_GPIOC(14),
+ .mode = SPI_CS_HIGH,
+ },
+};
+
+static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static void __init mx27pdk_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
+ "mx27pdk");
+ mx27_3ds_sdhc1_enable_level_translator();
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_fec(NULL);
+ imx27_add_imx_keypad(&mx27_3ds_keymap_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
+ imx27_add_imx2_wdt(NULL);
+ otg_phy_init();
+
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+
+ if (otg_pdata.otg)
+ imx27_add_mxc_ehci_otg(&otg_pdata);
+ }
+
+ if (!otg_mode_host)
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
+
+ imx27_add_spi_imx1(&spi2_pdata);
+ spi_register_board_info(mx27_3ds_spi_devs,
+ ARRAY_SIZE(mx27_3ds_spi_devs));
+
+ if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n");
+ imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data);
+}
+
+static void __init mx27pdk_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mx27pdk_timer = {
+ .init = mx27pdk_timer_init,
+};
+
+MACHINE_START(MX27_3DS, "Freescale MX27PDK")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &mx27pdk_timer,
+ .init_machine = mx27pdk_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
new file mode 100644
index 00000000..1db79506
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx27.h>
+
+#include "devices-imx27.h"
+
+/*
+ * Base address of PBC controller, CS4
+ */
+#define PBC_BASE_ADDRESS 0xf4300000
+#define PBC_REG_ADDR(offset) (void __force __iomem *) \
+ (PBC_BASE_ADDRESS + (offset))
+
+/* When the PBC address connection is fixed in h/w, defined as 1 */
+#define PBC_ADDR_SH 0
+
+/* Offsets for the PBC Controller register */
+/*
+ * PBC Board version register offset
+ */
+#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
+/*
+ * PBC Board control register 1 set address.
+ */
+#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
+/*
+ * PBC Board control register 1 clear address.
+ */
+#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
+
+/* PBC Board Control Register 1 bit definitions */
+#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
+
+/* to determine the correct external crystal reference */
+#define CKIH_27MHZ_BIT_SET (1 << 3)
+
+static const int mx27ads_pins[] __initconst = {
+ /* UART0 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART1 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART2 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* UART3 */
+ PB26_AF_UART4_RTS,
+ PB28_AF_UART4_TXD,
+ PB29_AF_UART4_CTS,
+ PB31_AF_UART4_RXD,
+ /* UART4 */
+ PB18_AF_UART5_TXD,
+ PB19_AF_UART5_RXD,
+ PB20_AF_UART5_CTS,
+ PB21_AF_UART5_RTS,
+ /* UART5 */
+ PB10_AF_UART6_TXD,
+ PB12_AF_UART6_CTS,
+ PB11_AF_UART6_RXD,
+ PB13_AF_UART6_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* FB */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA24_PF_REV,
+ PA25_PF_CLS,
+ PA26_PF_PS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /* OWIRE */
+ PE16_AF_OWIRE,
+ /* SDHC1*/
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ /* SDHC2*/
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+};
+
+static const struct mxc_nand_platform_data
+mx27ads_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+/* ADS's NOR flash */
+static struct physmap_flash_data mx27ads_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx27ads_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mx27ads_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx27ads_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mx27ads_flash_resource,
+};
+
+static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mx27ads_i2c_devices[] = {
+};
+
+void lcd_power(int on)
+{
+ if (on)
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
+ else
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
+}
+
+static struct imx_fb_videomode mx27ads_modes[] = {
+ {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .hsync_len = 1,
+ .left_margin = 9,
+ .right_margin = 16,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ },
+ .bpp = 16,
+ .pcr = 0xFB008BC0,
+ },
+};
+
+static const struct imx_fb_platform_data mx27ads_fb_data __initconst = {
+ .mode = mx27ads_modes,
+ .num_modes = ARRAY_SIZE(mx27ads_modes),
+
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+
+ .lcd_power = lcd_power,
+};
+
+static int mx27ads_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOE(21), detect_irq, IRQF_TRIGGER_RISING,
+ "sdhc1-card-detect", data);
+}
+
+static int mx27ads_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOB(7), detect_irq, IRQF_TRIGGER_RISING,
+ "sdhc2-card-detect", data);
+}
+
+static void mx27ads_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOE(21), data);
+}
+
+static void mx27ads_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOB(7), data);
+}
+
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
+ .init = mx27ads_sdhc1_init,
+ .exit = mx27ads_sdhc1_exit,
+};
+
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
+ .init = mx27ads_sdhc2_init,
+ .exit = mx27ads_sdhc2_exit,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &mx27ads_nor_mtd_device,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init mx27ads_board_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
+ "mx27ads");
+
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+ imx27_add_imx_uart3(&uart_pdata);
+ imx27_add_imx_uart4(&uart_pdata);
+ imx27_add_imx_uart5(&uart_pdata);
+ imx27_add_mxc_nand(&mx27ads_nand_board_info);
+
+ /* only the i2c master 1 is used on this CPU card */
+ i2c_register_board_info(1, mx27ads_i2c_devices,
+ ARRAY_SIZE(mx27ads_i2c_devices));
+ imx27_add_imx_i2c(1, &mx27ads_i2c1_data);
+ imx27_add_imx_fb(&mx27ads_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
+ imx27_add_mxc_mmc(1, &sdhc2_pdata);
+
+ imx27_add_fec(NULL);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_mxc_w1(NULL);
+}
+
+static void __init mx27ads_timer_init(void)
+{
+ unsigned long fref = 26000000;
+
+ if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
+ fref = 27000000;
+
+ mx27_clocks_init(fref);
+}
+
+static struct sys_timer mx27ads_timer = {
+ .init = mx27ads_timer_init,
+};
+
+static struct map_desc mx27ads_io_desc[] __initdata = {
+ {
+ .virtual = PBC_BASE_ADDRESS,
+ .pfn = __phys_to_pfn(MX27_CS4_BASE_ADDR),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init mx27ads_map_io(void)
+{
+ mx27_map_io();
+ iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
+}
+
+MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27ads_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &mx27ads_timer,
+ .init_machine = mx27ads_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
new file mode 100644
index 00000000..b5ecc26d
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/memblock.h>
+
+#include <media/soc_camera.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/3ds_debugboard.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+/* CPLD IRQ line for external uart, external ethernet etc */
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+static int mx31_3ds_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+ /*SPI0*/
+ MX31_PIN_CSPI1_SCLK__SCLK,
+ MX31_PIN_CSPI1_MOSI__MOSI,
+ MX31_PIN_CSPI1_MISO__MISO,
+ MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI1_SS2__SS2, /* CS for LCD */
+ /* SPI 1 */
+ MX31_PIN_CSPI2_SCLK__SCLK,
+ MX31_PIN_CSPI2_MOSI__MOSI,
+ MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0,
+ MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+ /* MC13783 IRQ */
+ IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+ /* USB OTG reset */
+ IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO),
+ /* USB OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+ MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+ MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /*Keyboard*/
+ MX31_PIN_KEY_ROW0_KEY_ROW0,
+ MX31_PIN_KEY_ROW1_KEY_ROW1,
+ MX31_PIN_KEY_ROW2_KEY_ROW2,
+ MX31_PIN_KEY_COL0_KEY_COL0,
+ MX31_PIN_KEY_COL1_KEY_COL1,
+ MX31_PIN_KEY_COL2_KEY_COL2,
+ MX31_PIN_KEY_COL3_KEY_COL3,
+ /* USB Host 2 */
+ IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1),
+ IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1),
+ /* USB Host2 reset */
+ IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO),
+ /* I2C1 */
+ MX31_PIN_I2C_CLK__I2C1_SCL,
+ MX31_PIN_I2C_DAT__I2C1_SDA,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ MX31_PIN_GPIO3_1__GPIO3_1, /* Card detect */
+ MX31_PIN_GPIO3_0__GPIO3_0, /* OE */
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_CONTRAST__CONTRAST,
+ /* CSI */
+ MX31_PIN_CSI_D6__CSI_D6,
+ MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8,
+ MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10,
+ MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12,
+ MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14,
+ MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC,
+ MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
+ MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ MX31_PIN_CSI_D5__GPIO3_5, /* CMOS PWDN */
+ IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_GPIO), /* CMOS reset */
+};
+
+/*
+ * Camera support
+ */
+static phys_addr_t mx3_camera_base __initdata;
+#define MX31_3DS_CAMERA_BUF_SIZE SZ_8M
+
+#define MX31_3DS_GPIO_CAMERA_PW IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
+#define MX31_3DS_GPIO_CAMERA_RST IOMUX_TO_GPIO(MX31_PIN_RI_DTE1)
+
+static struct gpio mx31_3ds_camera_gpios[] = {
+ { MX31_3DS_GPIO_CAMERA_PW, GPIOF_OUT_INIT_HIGH, "camera-power" },
+ { MX31_3DS_GPIO_CAMERA_RST, GPIOF_OUT_INIT_HIGH, "camera-reset" },
+};
+
+static const struct mx3_camera_pdata mx31_3ds_camera_pdata __initconst = {
+ .flags = MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 2600,
+};
+
+static int __init mx31_3ds_init_camera(void)
+{
+ int dma, ret = -ENOMEM;
+ struct platform_device *pdev =
+ imx31_alloc_mx3_camera(&mx31_3ds_camera_pdata);
+
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ if (!mx3_camera_base)
+ goto err;
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx3_camera_base, mx3_camera_base,
+ MX31_3DS_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+ if (!(dma & DMA_MEMORY_MAP))
+ goto err;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+err:
+ platform_device_put(pdev);
+
+ return ret;
+}
+
+static int mx31_3ds_camera_power(struct device *dev, int on)
+{
+ /* enable or disable the camera */
+ pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+ gpio_set_value(MX31_3DS_GPIO_CAMERA_PW, on ? 0 : 1);
+
+ if (!on)
+ goto out;
+
+ /* If enabled, give a reset impulse */
+ gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 0);
+ msleep(20);
+ gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 1);
+ msleep(100);
+
+out:
+ return 0;
+}
+
+static struct i2c_board_info mx31_3ds_i2c_camera = {
+ I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct regulator_bulk_data mx31_3ds_camera_regs[] = {
+ { .supply = "cmos_vcore" },
+ { .supply = "cmos_2v8" },
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+ .bus_id = 0,
+ .board_info = &mx31_3ds_i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = mx31_3ds_camera_power,
+ .regulators = mx31_3ds_camera_regs,
+ .num_regulators = ARRAY_SIZE(mx31_3ds_camera_regs),
+};
+
+static struct platform_device mx31_3ds_ov2640 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_ov2640,
+ },
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+ { /* 480x640 @ 60 Hz */
+ .name = "Epson-VGA",
+ .refresh = 60,
+ .xres = 480,
+ .yres = 640,
+ .pixclock = 41701,
+ .left_margin = 20,
+ .right_margin = 41,
+ .upper_margin = 10,
+ .lower_margin = 5,
+ .hsync_len = 20,
+ .vsync_len = 10,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "Epson-VGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+/* LCD */
+static struct l4f00242t03_pdata mx31_3ds_l4f00242t03_pdata = {
+ .reset_gpio = IOMUX_TO_GPIO(MX31_PIN_LCS1),
+ .data_enable_gpio = IOMUX_TO_GPIO(MX31_PIN_SER_RS),
+ .core_supply = "lcd_2v8",
+ .io_supply = "vdd_lcdio",
+};
+
+/*
+ * Support for SD card slot in personality board
+ */
+#define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+
+static struct gpio mx31_3ds_sdhc1_gpios[] = {
+ { MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" },
+ { MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" },
+};
+
+static int mx31_3ds_sdhc1_init(struct device *dev,
+ irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request_array(mx31_3ds_sdhc1_gpios,
+ ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+ if (ret) {
+ pr_warning("Unable to request the SD/MMC GPIOs.\n");
+ return ret;
+ }
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+ detect_irq, IRQF_DISABLED |
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ "sdhc1-detect", data);
+ if (ret) {
+ pr_warning("Unable to request the SD/MMC card-detect IRQ.\n");
+ goto gpio_free;
+ }
+
+ return 0;
+
+gpio_free:
+ gpio_free_array(mx31_3ds_sdhc1_gpios,
+ ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+ return ret;
+}
+
+static void mx31_3ds_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data);
+ gpio_free_array(mx31_3ds_sdhc1_gpios,
+ ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+}
+
+static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd)
+{
+ /*
+ * While the voltage stuff is done by the driver, activate the
+ * Buffer Enable Pin only if there is a card in slot to fix the card
+ * voltage issue caused by bi-directional chip TXB0108 on 3Stack.
+ * Done here because at this stage we have for sure a debounced value
+ * of the presence of the card, showed by the value of vdd.
+ * 7 == ilog2(MMC_VDD_165_195)
+ */
+ if (vdd > 7)
+ gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1);
+ else
+ gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+ .init = mx31_3ds_sdhc1_init,
+ .exit = mx31_3ds_sdhc1_exit,
+ .setpower = mx31_3ds_sdhc1_setpower,
+};
+
+/*
+ * Matrix keyboard
+ */
+
+static const uint32_t mx31_3ds_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_ENTER),
+ KEY(2, 0, KEY_F6),
+ KEY(2, 1, KEY_F8),
+ KEY(2, 2, KEY_F9),
+ KEY(2, 3, KEY_F10),
+};
+
+static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = {
+ .keymap = mx31_3ds_keymap,
+ .keymap_size = ARRAY_SIZE(mx31_3ds_keymap),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+ .constraints = {
+ .boot_on = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data gpo_init = {
+ .constraints = {
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_consumer_supply vmmc2_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"),
+};
+
+static struct regulator_init_data vmmc2_init = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers),
+ .consumer_supplies = vmmc2_consumers,
+};
+
+static struct regulator_consumer_supply vmmc1_consumers[] = {
+ REGULATOR_SUPPLY("lcd_2v8", NULL),
+ REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vmmc1_init = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
+ .consumer_supplies = vmmc1_consumers,
+};
+
+static struct regulator_consumer_supply vgen_consumers[] = {
+ REGULATOR_SUPPLY("vdd_lcdio", NULL),
+};
+
+static struct regulator_init_data vgen_init = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
+ .consumer_supplies = vgen_consumers,
+};
+
+static struct regulator_consumer_supply vvib_consumers[] = {
+ REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vvib_init = {
+ .constraints = {
+ .min_uV = 1300000,
+ .max_uV = 1300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
+ .consumer_supplies = vvib_consumers,
+};
+
+static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
+ {
+ .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */
+ .init_data = &pwgtx_init,
+ }, {
+ .id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */
+ .init_data = &pwgtx_init,
+ }, {
+
+ .id = MC13783_REG_GPO1, /* Turn on 1.8V */
+ .init_data = &gpo_init,
+ }, {
+ .id = MC13783_REG_GPO3, /* Turn on 3.3V */
+ .init_data = &gpo_init,
+ }, {
+ .id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */
+ .init_data = &vmmc2_init,
+ }, {
+ .id = MC13783_REG_VMMC1, /* Power LCD, CMOS, FM, GPS, Accel. */
+ .init_data = &vmmc1_init,
+ }, {
+ .id = MC13783_REG_VGEN, /* Power LCD */
+ .init_data = &vgen_init,
+ }, {
+ .id = MC13783_REG_VVIB, /* Power CMOS */
+ .init_data = &vvib_init,
+ },
+};
+
+/* MC13783 */
+static struct mc13xxx_platform_data mc13783_pdata = {
+ .regulators = {
+ .regulators = mx31_3ds_regulators,
+ .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+ },
+ .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
+};
+
+/* SPI */
+static int spi0_internal_chipselect[] = {
+ MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+ .chipselect = spi0_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi0_internal_chipselect),
+};
+
+static int spi1_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+ .chipselect = spi1_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 1, /* SS2 */
+ .platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .mode = SPI_CS_HIGH,
+ }, {
+ .modalias = "l4f00242t03",
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0, /* SS2 */
+ .platform_data = &mx31_3ds_l4f00242t03_pdata,
+ },
+};
+
+/*
+ * NAND Flash
+ */
+static const struct mxc_nand_platform_data
+mx31_3ds_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+ .flash_bbt = 1,
+#endif
+};
+
+/*
+ * USB OTG
+ */
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
+#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP)
+
+static int mx31_3ds_usbotg_init(void)
+{
+ int err;
+
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+ err = gpio_request(USBOTG_RST_B, "otgusb-reset");
+ if (err) {
+ pr_err("Failed to request the USB OTG reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBOTG_RST_B, 0);
+ if (err) {
+ pr_err("Failed to drive the USB OTG reset gpio\n");
+ goto usbotg_free_reset;
+ }
+
+ mdelay(1);
+ gpio_set_value(USBOTG_RST_B, 1);
+ return 0;
+
+usbotg_free_reset:
+ gpio_free(USBOTG_RST_B);
+ return err;
+}
+
+static int mx31_3ds_otg_init(struct platform_device *pdev)
+{
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static int mx31_3ds_host2_init(struct platform_device *pdev)
+{
+ int err;
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_VS2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG);
+
+ err = gpio_request(USBH2_RST_B, "usbh2-reset");
+ if (err) {
+ pr_err("Failed to request the USB Host 2 reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBH2_RST_B, 0);
+ if (err) {
+ pr_err("Failed to drive the USB Host 2 reset gpio\n");
+ goto usbotg_free_reset;
+ }
+
+ mdelay(1);
+ gpio_set_value(USBH2_RST_B, 1);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+
+usbotg_free_reset:
+ gpio_free(USBH2_RST_B);
+ return err;
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = mx31_3ds_otg_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = mx31_3ds_host2_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data usbotg_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init mx31_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", mx31_3ds_otg_mode);
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx31_3ds_ov2640,
+};
+
+static void __init mx31_3ds_init(void)
+{
+ int ret;
+
+ mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+ "mx31_3ds");
+
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
+
+ imx31_add_spi_imx1(&spi1_pdata);
+ spi_register_board_info(mx31_3ds_spi_devs,
+ ARRAY_SIZE(mx31_3ds_spi_devs));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx31_add_imx_keypad(&mx31_3ds_keymap_data);
+
+ mx31_3ds_usbotg_init();
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (otg_pdata.otg)
+ imx31_add_mxc_ehci_otg(&otg_pdata);
+ }
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+ if (!otg_mode_host)
+ imx31_add_fsl_usb2_udc(&usbotg_pdata);
+
+ if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ printk(KERN_WARNING "Init of the debug board failed, all "
+ "devices on the debug board are unusable.\n");
+ imx31_add_imx2_wdt(NULL);
+ imx31_add_imx_i2c0(&mx31_3ds_i2c0_data);
+ imx31_add_mxc_mmc(0, &sdhc1_pdata);
+
+ imx31_add_spi_imx0(&spi0_pdata);
+ imx31_add_ipu_core(&mx3_ipu_data);
+ imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ /* CSI */
+ /* Camera power: default - off */
+ ret = gpio_request_array(mx31_3ds_camera_gpios,
+ ARRAY_SIZE(mx31_3ds_camera_gpios));
+ if (ret) {
+ pr_err("Failed to request camera gpios");
+ iclink_ov2640.power = NULL;
+ }
+
+ mx31_3ds_init_camera();
+}
+
+static void __init mx31_3ds_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31_3ds_timer = {
+ .init = mx31_3ds_timer_init,
+};
+
+static void __init mx31_3ds_reserve(void)
+{
+ /* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
+ mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE,
+ MX31_3DS_CAMERA_BUF_SIZE);
+ memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
+ memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &mx31_3ds_timer,
+ .init_machine = mx31_3ds_init,
+ .reserve = mx31_3ds_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
new file mode 100644
index 00000000..f4dee025
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/board-mx31ads.h>
+#include <mach/iomux-mx3.h>
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#include "devices-imx31.h"
+
+/* PBC Board interrupt status register */
+#define PBC_INTSTATUS 0x000016
+
+/* PBC Board interrupt current status register */
+#define PBC_INTCURR_STATUS 0x000018
+
+/* PBC Interrupt mask register set address */
+#define PBC_INTMASK_SET 0x00001A
+
+/* PBC Interrupt mask register clear address */
+#define PBC_INTMASK_CLEAR 0x00001C
+
+/* External UART A */
+#define PBC_SC16C652_UARTA 0x010000
+
+/* External UART B */
+#define PBC_SC16C652_UARTB 0x010010
+
+#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11)
+
+#define MXC_MAX_EXP_IO_LINES 16
+
+/*
+ * The serial port definition structure.
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
+ .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA),
+ .irq = EXPIO_INT_XUART_INTA,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+ }, {
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
+ .mapbase = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB),
+ .irq = EXPIO_INT_XUART_INTB,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+ },
+ {},
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static int __init mxc_init_extuart(void)
+{
+ return platform_device_register(&serial_device);
+}
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static unsigned int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
+ imx31_add_imx_uart0(&uart_pdata);
+}
+
+static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ imr_val = __raw_readw(PBC_INTMASK_SET_REG);
+ int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
+
+ expio_irq = MXC_EXP_IO_BASE;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ if ((int_valid & 1) == 0)
+ continue;
+
+ generic_handle_irq(expio_irq);
+ }
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param d an expio virtual irq description
+ */
+static void expio_mask_irq(struct irq_data *d)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+ /* mask the interrupt */
+ __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+ __raw_readw(PBC_INTMASK_CLEAR_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param d an expio virtual irq description
+ */
+static void expio_ack_irq(struct irq_data *d)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, PBC_INTSTATUS_REG);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param d an expio virtual irq description
+ */
+static void expio_unmask_irq(struct irq_data *d)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+ /* unmask the interrupt */
+ __raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .name = "EXPIO(CPLD)",
+ .irq_ack = expio_ack_irq,
+ .irq_mask = expio_mask_irq,
+ .irq_unmask = expio_unmask_irq,
+};
+
+static void __init mx31ads_init_expio(void)
+{
+ int i;
+
+ printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio");
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
+ __raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+}
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+/* This section defines setup for the Wolfson Microelectronics
+ * 1133-EV1 PMU/audio board. When other PMU boards are supported the
+ * regulator definitions may be shared with them, but for now they can
+ * only be used with this board so would generate warnings about
+ * unused statics and some of the configuration is specific to this
+ * module.
+ */
+
+/* CPU */
+static struct regulator_consumer_supply sw1a_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_init_data sw1a_data = {
+ .constraints = {
+ .name = "SW1A",
+ .min_uV = 1275000,
+ .max_uV = 1600000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .state_mem = {
+ .uV = 1400000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+ .consumer_supplies = sw1a_consumers,
+};
+
+/* System IO - High */
+static struct regulator_init_data viohi_data = {
+ .constraints = {
+ .name = "VIOHO",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .state_mem = {
+ .uV = 2800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* System IO - Low */
+static struct regulator_init_data violo_data = {
+ .constraints = {
+ .name = "VIOLO",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* DDR RAM */
+static struct regulator_init_data sw2a_data = {
+ .constraints = {
+ .name = "SW2A",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .state_disk = {
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 0,
+ },
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+static struct regulator_init_data ldo1_data = {
+ .constraints = {
+ .name = "VCAM/VMMC1/VMMC2",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_consumer_supply ldo2_consumers[] = {
+ { .supply = "AVDD", .dev_name = "1-001a" },
+ { .supply = "HPVDD", .dev_name = "1-001a" },
+};
+
+/* CODEC and SIM */
+static struct regulator_init_data ldo2_data = {
+ .constraints = {
+ .name = "VESIM/VSIM/AVDD",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers),
+ .consumer_supplies = ldo2_consumers,
+};
+
+/* General */
+static struct regulator_init_data vdig_data = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = 1500000,
+ .max_uV = 1500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+/* Tranceivers */
+static struct regulator_init_data ldo4_data = {
+ .constraints = {
+ .name = "VRF1/CVDD_2.775",
+ .min_uV = 2500000,
+ .max_uV = 2500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct wm8350_led_platform_data wm8350_led_data = {
+ .name = "wm8350:white",
+ .default_trigger = "heartbeat",
+ .max_uA = 27899,
+};
+
+static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
+ .vmid_discharge_msecs = 1000,
+ .drain_msecs = 30,
+ .cap_discharge_msecs = 700,
+ .vmid_charge_msecs = 700,
+ .vmid_s_curve = WM8350_S_CURVE_SLOW,
+ .dis_out4 = WM8350_DISCHARGE_SLOW,
+ .dis_out3 = WM8350_DISCHARGE_SLOW,
+ .dis_out2 = WM8350_DISCHARGE_SLOW,
+ .dis_out1 = WM8350_DISCHARGE_SLOW,
+ .vroi_out4 = WM8350_TIE_OFF_500R,
+ .vroi_out3 = WM8350_TIE_OFF_500R,
+ .vroi_out2 = WM8350_TIE_OFF_500R,
+ .vroi_out1 = WM8350_TIE_OFF_500R,
+ .vroi_enable = 0,
+ .codec_current_on = WM8350_CODEC_ISEL_1_0,
+ .codec_current_standby = WM8350_CODEC_ISEL_0_5,
+ .codec_current_charge = WM8350_CODEC_ISEL_1_5,
+};
+
+static int mx31_wm8350_init(struct wm8350 *wm8350)
+{
+ wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data);
+ wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data);
+ wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data);
+
+ /* LEDs */
+ wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1,
+ WM8350_DC5_ERRACT_SHUTDOWN_CONV);
+ wm8350_isink_set_flash(wm8350, WM8350_ISINK_A,
+ WM8350_ISINK_FLASH_DISABLE,
+ WM8350_ISINK_FLASH_TRIG_BIT,
+ WM8350_ISINK_FLASH_DUR_32MS,
+ WM8350_ISINK_FLASH_ON_INSTANT,
+ WM8350_ISINK_FLASH_OFF_INSTANT,
+ WM8350_ISINK_FLASH_MODE_EN);
+ wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5,
+ WM8350_ISINK_MODE_BOOST,
+ WM8350_ISINK_ILIM_NORMAL,
+ WM8350_DC5_RMP_20V,
+ WM8350_DC5_FBSRC_ISINKA);
+ wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A,
+ &wm8350_led_data);
+
+ wm8350->codec.platform_data = &imx32ads_wm8350_setup;
+
+ regulator_has_full_constraints();
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata mx31_wm8350_pdata = {
+ .init = mx31_wm8350_init,
+ .irq_base = MXC_BOARD_IRQ_START + MXC_MAX_EXP_IO_LINES,
+};
+#endif
+
+static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = {
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+ {
+ I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &mx31_wm8350_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ },
+#endif
+};
+
+static void mxc_init_i2c(void)
+{
+ i2c_register_board_info(1, mx31ads_i2c1_devices,
+ ARRAY_SIZE(mx31ads_i2c1_devices));
+
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
+
+ imx31_add_imx_i2c1(NULL);
+}
+
+static unsigned int ssi_pins[] = {
+ MX31_PIN_SFS5__SFS5,
+ MX31_PIN_SCK5__SCK5,
+ MX31_PIN_SRXD5__SRXD5,
+ MX31_PIN_STXD5__STXD5,
+};
+
+static void mxc_init_audio(void)
+{
+ imx31_add_imx_ssi(0, NULL);
+ mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
+}
+
+/* static mappings */
+static struct map_desc mx31ads_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE / 2,
+ .type = MT_DEVICE
+ },
+};
+
+static void __init mx31ads_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
+}
+
+static void __init mx31ads_init_irq(void)
+{
+ mx31_init_irq();
+ mx31ads_init_expio();
+}
+
+static void __init mx31ads_init(void)
+{
+ mxc_init_extuart();
+ mxc_init_imx_uart();
+ mxc_init_i2c();
+ mxc_init_audio();
+}
+
+static void __init mx31ads_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31ads_timer = {
+ .init = mx31ads_timer_init,
+};
+
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31ads_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31ads_init_irq,
+ .timer = &mx31ads_timer,
+ .init_machine = mx31ads_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx31lilly.c b/arch/arm/mach-imx/mach-mx31lilly.c
new file mode 100644
index 00000000..410e676a
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31lilly.c
@@ -0,0 +1,302 @@
+/*
+ * LILLY-1131 module support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains module-specific initialization routines for LILLY-1131.
+ * Initialization of peripherals found on the baseboard is implemented in the
+ * appropriate baseboard support code.
+ */
+
+/* SMSC ethernet support */
+
+static struct resource smsc91x_resources[] = {
+ {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO1_0),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT |
+ SMSC911X_SAVE_MAC_ADDRESS |
+ SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc91x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc91x_resources),
+ .resource = smsc91x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ }
+};
+
+/* NOR flash */
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource nor_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+/* USB */
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbh1_init(struct platform_device *pdev)
+{
+ int pins[] = {
+ MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+ MX31_PIN_CSPI1_MISO__USBH1_RXDP,
+ MX31_PIN_CSPI1_SS0__USBH1_TXDM,
+ MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+ MX31_PIN_CSPI1_SS2__USBH1_RCV,
+ MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+ MX31_PIN_CSPI1_SPI_RDY__USBH1_FS,
+ };
+
+ mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1");
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+ int pins[] = {
+ MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+ MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+ MX31_PIN_USBH2_CLK__USBH2_CLK,
+ MX31_PIN_USBH2_DIR__USBH2_DIR,
+ MX31_PIN_USBH2_NXT__USBH2_NXT,
+ MX31_PIN_USBH2_STP__USBH2_STP,
+ };
+
+ mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+ /* chip select */
+ mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+ "USBH2_CS");
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+ .init = usbh1_init,
+ .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static void lilly1131_usb_init(void)
+{
+ imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+}
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(1),
+ MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13xxx_platform_data mc13783_pdata __initdata = {
+ .flags = MC13XXX_USE_RTC | MC13XXX_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info mc13783_dev __initdata = {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smsc91x_device,
+ &physmap_flash_device,
+};
+
+static int mx31lilly_baseboard;
+core_param(mx31lilly_baseboard, mx31lilly_baseboard, int, 0444);
+
+static void __init mx31lilly_board_init(void)
+{
+ switch (mx31lilly_baseboard) {
+ case MX31LILLY_NOBOARD:
+ break;
+ case MX31LILLY_DB:
+ mx31lilly_db_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31lilly_baseboard type %d\n",
+ mx31lilly_baseboard);
+ }
+
+ mxc_iomux_alloc_pin(MX31_PIN_CS4__CS4, "Ethernet CS");
+
+ /* SPI */
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SCLK__SCLK, "SPI1_CLK");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MOSI__MOSI, "SPI1_TX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_MISO__MISO, "SPI1_RX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, "SPI1_RDY");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS0__SS0, "SPI1_SS0");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS1__SS1, "SPI1_SS1");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI1_SS2__SS2, "SPI1_SS2");
+
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SCLK__SCLK, "SPI2_CLK");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MOSI__MOSI, "SPI2_TX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_MISO__MISO, "SPI2_RX");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SPI_RDY__SPI_RDY, "SPI2_RDY");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS0__SS0, "SPI2_SS0");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1");
+ mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2");
+
+ imx31_add_spi_imx0(&spi0_pdata);
+ imx31_add_spi_imx1(&spi1_pdata);
+ spi_register_board_info(&mc13783_dev, 1);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* USB */
+ lilly1131_usb_init();
+}
+
+static void __init mx31lilly_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31lilly_timer = {
+ .init = mx31lilly_timer_init,
+};
+
+MACHINE_START(LILLY1131, "INCO startec LILLY-1131")
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &mx31lilly_timer,
+ .init_machine = mx31lilly_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx31lite.c b/arch/arm/mach-imx/mach-mx31lite.c
new file mode 100644
index 00000000..ac9b4cad
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31lite.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/board-mx31lite.h>
+#include <mach/iomux-mx3.h>
+#include <mach/irqs.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains the module-specific initialization routines.
+ */
+
+static unsigned int mx31lite_pins[] = {
+ /* LAN9117 IRQ pin */
+ IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO),
+ /* SPI 1 */
+ MX31_PIN_CSPI2_SCLK__SCLK,
+ MX31_PIN_CSPI2_MOSI__MOSI,
+ MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0,
+ MX31_PIN_CSPI2_SS1__SS1,
+ MX31_PIN_CSPI2_SS2__SS2,
+};
+
+static const struct mxc_nand_platform_data
+mx31lite_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_16BIT,
+};
+
+static struct resource smsc911x_resources[] = {
+ {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 0x100,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_SFS6),
+ .end = IOMUX_TO_IRQ(MX31_PIN_SFS6),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smsc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+};
+
+/*
+ * SPI
+ *
+ * The MC13783 is the only hard-wired SPI device on the module.
+ */
+
+static int spi_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13xxx_platform_data mc13783_pdata __initdata = {
+ .flags = MC13XXX_USE_RTC |
+ MC13XXX_USE_REGULATOR,
+};
+
+static struct spi_board_info mc13783_spi_dev __initdata = {
+ .modalias = "mc13783",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+/*
+ * USB
+ */
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbh2_init(struct platform_device *pdev)
+{
+ int pins[] = {
+ MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+ MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+ MX31_PIN_USBH2_CLK__USBH2_CLK,
+ MX31_PIN_USBH2_DIR__USBH2_DIR,
+ MX31_PIN_USBH2_NXT__USBH2_NXT,
+ MX31_PIN_USBH2_STP__USBH2_STP,
+ };
+
+ mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+ /* chip select */
+ mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+ "USBH2_CS");
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+/*
+ * NOR flash
+ */
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource nor_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+
+
+/*
+ * This structure defines the MX31 memory map.
+ */
+static struct map_desc mx31lite_io_desc[] __initdata = {
+ {
+ .virtual = MX31_CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
+ .length = MX31_CS4_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+/*
+ * Set up static virtual mappings.
+ */
+void __init mx31lite_map_io(void)
+{
+ mx31_map_io();
+ iotable_init(mx31lite_io_desc, ARRAY_SIZE(mx31lite_io_desc));
+}
+
+static int mx31lite_baseboard;
+core_param(mx31lite_baseboard, mx31lite_baseboard, int, 0444);
+
+static void __init mx31lite_init(void)
+{
+ int ret;
+
+ switch (mx31lite_baseboard) {
+ case MX31LITE_NOBOARD:
+ break;
+ case MX31LITE_DB:
+ mx31lite_db_init();
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31lite_baseboard type %d\n",
+ mx31lite_baseboard);
+ }
+
+ mxc_iomux_setup_multiple_pins(mx31lite_pins, ARRAY_SIZE(mx31lite_pins),
+ "mx31lite");
+
+ /* NOR and NAND flash */
+ platform_device_register(&physmap_flash_device);
+ imx31_add_mxc_nand(&mx31lite_nand_board_info);
+
+ imx31_add_spi_imx1(&spi1_pdata);
+ spi_register_board_info(&mc13783_spi_dev, 1);
+
+ /* USB */
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+ /* SMSC9117 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_SFS6), "sms9117-irq");
+ if (ret)
+ pr_warning("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+ platform_device_register(&smsc911x_device);
+ }
+}
+
+static void __init mx31lite_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31lite_timer = {
+ .init = mx31lite_timer_init,
+};
+
+MACHINE_START(MX31LITE, "LogicPD i.MX31 SOM")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31lite_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &mx31lite_timer,
+ .init_machine = mx31lite_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
new file mode 100644
index 00000000..eaa51e49
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -0,0 +1,583 @@
+/*
+ * Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/memory.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
+#include <linux/memblock.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/board-mx31moboard.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+static unsigned int moboard_pins[] = {
+ /* UART0 */
+ MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
+ MX31_PIN_CTS1__GPIO2_7,
+ /* UART4 */
+ MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
+ MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
+ /* I2C0 */
+ MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
+ /* I2C1 */
+ MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
+ MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
+ /* USB reset */
+ MX31_PIN_GPIO1_0__GPIO1_0,
+ /* USB OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
+ MX31_PIN_USB_OC__GPIO1_30,
+ /* USB H2 */
+ MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+ MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+ MX31_PIN_STXD3__USBH2_DATA2, MX31_PIN_SRXD3__USBH2_DATA3,
+ MX31_PIN_SCK3__USBH2_DATA4, MX31_PIN_SFS3__USBH2_DATA5,
+ MX31_PIN_STXD6__USBH2_DATA6, MX31_PIN_SRXD6__USBH2_DATA7,
+ MX31_PIN_USBH2_CLK__USBH2_CLK, MX31_PIN_USBH2_DIR__USBH2_DIR,
+ MX31_PIN_USBH2_NXT__USBH2_NXT, MX31_PIN_USBH2_STP__USBH2_STP,
+ MX31_PIN_SCK6__GPIO1_25,
+ /* LEDs */
+ MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
+ MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
+ /* SPI1 */
+ MX31_PIN_CSPI2_MOSI__MOSI, MX31_PIN_CSPI2_MISO__MISO,
+ MX31_PIN_CSPI2_SCLK__SCLK, MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS0__SS0, MX31_PIN_CSPI2_SS2__SS2,
+ /* Atlas IRQ */
+ MX31_PIN_GPIO1_3__GPIO1_3,
+ /* SPI2 */
+ MX31_PIN_CSPI3_MOSI__MOSI, MX31_PIN_CSPI3_MISO__MISO,
+ MX31_PIN_CSPI3_SCLK__SCLK, MX31_PIN_CSPI3_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI2_SS1__CSPI3_SS1,
+};
+
+static struct physmap_flash_data mx31moboard_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx31moboard_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx31moboard_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx31moboard_flash_data,
+ },
+ .resource = &mx31moboard_flash_resource,
+ .num_resources = 1,
+};
+
+static int moboard_uart0_init(struct platform_device *pdev)
+{
+ int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
+ if (ret)
+ return ret;
+
+ ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+ if (ret)
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+
+ return ret;
+}
+
+static void moboard_uart0_exit(struct platform_device *pdev)
+{
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+}
+
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+ .init = moboard_uart0_init,
+ .exit = moboard_uart0_exit,
+};
+
+static const struct imxuart_platform_data uart4_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data moboard_i2c0_data __initconst = {
+ .bitrate = 400000,
+};
+
+static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static int moboard_spi1_cs[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master moboard_spi1_pdata __initconst = {
+ .chipselect = moboard_spi1_cs,
+ .num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
+};
+
+static struct regulator_consumer_supply sdhc_consumers[] = {
+ {
+ .dev_name = "mxc-mmc.0",
+ .supply = "sdhc0_vcc",
+ },
+ {
+ .dev_name = "mxc-mmc.1",
+ .supply = "sdhc1_vcc",
+ },
+};
+
+static struct regulator_init_data sdhc_vreg_data = {
+ .constraints = {
+ .min_uV = 2700000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhc_consumers),
+ .consumer_supplies = sdhc_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+ {
+ .dev_name = "mx3_camera.0",
+ .supply = "cam_vcc",
+ },
+};
+
+static struct regulator_init_data cam_vreg_data = {
+ .constraints = {
+ .min_uV = 2700000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+ .consumer_supplies = cam_consumers,
+};
+
+static struct mc13xxx_regulator_init_data moboard_regulators[] = {
+ {
+ .id = MC13783_REG_VMMC1,
+ .init_data = &sdhc_vreg_data,
+ },
+ {
+ .id = MC13783_REG_VCAM,
+ .init_data = &cam_vreg_data,
+ },
+};
+
+static struct mc13783_led_platform_data moboard_led[] = {
+ {
+ .id = MC13783_LED_R1,
+ .name = "coreboard-led-4:red",
+ .max_current = 2,
+ },
+ {
+ .id = MC13783_LED_G1,
+ .name = "coreboard-led-4:green",
+ .max_current = 2,
+ },
+ {
+ .id = MC13783_LED_B1,
+ .name = "coreboard-led-4:blue",
+ .max_current = 2,
+ },
+ {
+ .id = MC13783_LED_R2,
+ .name = "coreboard-led-5:red",
+ .max_current = 3,
+ },
+ {
+ .id = MC13783_LED_G2,
+ .name = "coreboard-led-5:green",
+ .max_current = 3,
+ },
+ {
+ .id = MC13783_LED_B2,
+ .name = "coreboard-led-5:blue",
+ .max_current = 3,
+ },
+};
+
+static struct mc13783_leds_platform_data moboard_leds = {
+ .num_leds = ARRAY_SIZE(moboard_led),
+ .led = moboard_led,
+ .flags = MC13783_LED_SLEWLIMTC,
+ .abmode = MC13783_LED_AB_DISABLED,
+ .tc1_period = MC13783_LED_PERIOD_10MS,
+ .tc2_period = MC13783_LED_PERIOD_10MS,
+};
+
+static struct mc13xxx_platform_data moboard_pmic = {
+ .regulators = {
+ .regulators = moboard_regulators,
+ .num_regulators = ARRAY_SIZE(moboard_regulators),
+ },
+ .leds = &moboard_leds,
+ .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
+ MC13XXX_USE_ADC | MC13XXX_USE_LED,
+};
+
+static struct spi_board_info moboard_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .max_speed_hz = 300000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &moboard_pmic,
+ .mode = SPI_CS_HIGH,
+ },
+};
+
+static int moboard_spi2_cs[] = {
+ MXC_SPI_CS(1),
+};
+
+static const struct spi_imx_master moboard_spi2_pdata __initconst = {
+ .chipselect = moboard_spi2_cs,
+ .num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
+};
+
+#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
+#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
+
+static int moboard_sdhc1_get_ro(struct device *dev)
+{
+ return !gpio_get_value(SDHC1_WP);
+}
+
+static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC1_CD, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC1_CD);
+
+ ret = gpio_request(SDHC1_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC1_WP);
+
+ ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "sdhc1-card-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(SDHC1_WP);
+err_gpio_free:
+ gpio_free(SDHC1_CD);
+
+ return ret;
+}
+
+static void moboard_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(SDHC1_CD), data);
+ gpio_free(SDHC1_WP);
+ gpio_free(SDHC1_CD);
+}
+
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
+ .get_ro = moboard_sdhc1_get_ro,
+ .init = moboard_sdhc1_init,
+ .exit = moboard_sdhc1_exit,
+};
+
+/*
+ * this pin is dedicated for all mx31moboard systems, so we do it here
+ */
+#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS)
+
+#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static void usb_xcvr_reset(void)
+{
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
+
+ gpio_request(OTG_EN_B, "usb-udc-en");
+ gpio_direction_output(OTG_EN_B, 0);
+ gpio_request(USBH2_EN_B, "usbh2-en");
+ gpio_direction_output(USBH2_EN_B, 0);
+
+ gpio_request(USB_RESET_B, "usb-reset");
+ gpio_direction_output(USB_RESET_B, 0);
+ mdelay(1);
+ gpio_set_value(USB_RESET_B, 1);
+ mdelay(1);
+}
+
+static int moboard_usbh2_init_hw(struct platform_device *pdev)
+{
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = moboard_usbh2_init_hw,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static int __init moboard_usbh2_init(void)
+{
+ struct platform_device *pdev;
+
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (!usbh2_pdata.otg)
+ return -ENODEV;
+
+ pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+static struct gpio_led mx31moboard_leds[] = {
+ {
+ .name = "coreboard-led-0:red:running",
+ .default_trigger = "heartbeat",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SVEN0),
+ }, {
+ .name = "coreboard-led-1:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_STX0),
+ }, {
+ .name = "coreboard-led-2:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SRX0),
+ }, {
+ .name = "coreboard-led-3:red",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
+ },
+};
+
+static struct gpio_led_platform_data mx31moboard_led_pdata = {
+ .num_leds = ARRAY_SIZE(mx31moboard_leds),
+ .leds = mx31moboard_leds,
+};
+
+static struct platform_device mx31moboard_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mx31moboard_led_pdata,
+ },
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx31moboard_flash,
+ &mx31moboard_leds_device,
+};
+
+static struct mx3_camera_pdata camera_pdata __initdata = {
+ .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 4800,
+};
+
+static phys_addr_t mx3_camera_base __initdata;
+#define MX3_CAMERA_BUF_SIZE SZ_4M
+
+static int __init mx31moboard_init_cam(void)
+{
+ int dma, ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ imx31_add_ipu_core(&mx3_ipu_data);
+
+ pdev = imx31_alloc_mx3_camera(&camera_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx3_camera_base, mx3_camera_base,
+ MX3_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ goto err;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+err:
+ platform_device_put(pdev);
+
+ return ret;
+
+}
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx31moboard_init(void)
+{
+ mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
+ "moboard");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx31_add_imx_uart0(&uart0_pdata);
+ imx31_add_imx_uart4(&uart4_pdata);
+
+ imx31_add_imx_i2c0(&moboard_i2c0_data);
+ imx31_add_imx_i2c1(&moboard_i2c1_data);
+
+ imx31_add_spi_imx1(&moboard_spi1_pdata);
+ imx31_add_spi_imx2(&moboard_spi2_pdata);
+
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
+ spi_register_board_info(moboard_spi_board_info,
+ ARRAY_SIZE(moboard_spi_board_info));
+
+ imx31_add_mxc_mmc(0, &sdhc1_pdata);
+
+ mx31moboard_init_cam();
+
+ usb_xcvr_reset();
+
+ moboard_usbh2_init();
+
+ switch (mx31moboard_baseboard) {
+ case MX31NOBOARD:
+ break;
+ case MX31DEVBOARD:
+ mx31moboard_devboard_init();
+ break;
+ case MX31MARXBOT:
+ mx31moboard_marxbot_init();
+ break;
+ case MX31SMARTBOT:
+ case MX31EYEBOT:
+ mx31moboard_smartbot_init(mx31moboard_baseboard);
+ break;
+ default:
+ printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
+ mx31moboard_baseboard);
+ }
+}
+
+static void __init mx31moboard_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer mx31moboard_timer = {
+ .init = mx31moboard_timer_init,
+};
+
+static void __init mx31moboard_reserve(void)
+{
+ /* reserve 4 MiB for mx3-camera */
+ mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
+ MX3_CAMERA_BUF_SIZE);
+ memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+ memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
+ /* Maintainer: Valentin Longchamp, EPFL Mobots group */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .reserve = mx31moboard_reserve,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &mx31moboard_timer,
+ .init_machine = mx31moboard_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c
new file mode 100644
index 00000000..882880ac
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx35_3ds.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This machine is known as:
+ * - i.MX35 3-Stack Development System
+ * - i.MX35 Platform Development Kit (i.MX35 PDK)
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+#include <mach/3ds_debugboard.h>
+
+#include "devices-imx35.h"
+
+#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct physmap_flash_data mx35pdk_flash_data = {
+ .width = 2,
+};
+
+static struct resource mx35pdk_flash_resource = {
+ .start = MX35_CS0_BASE_ADDR,
+ .end = MX35_CS0_BASE_ADDR + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device mx35pdk_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mx35pdk_flash_data,
+ },
+ .resource = &mx35pdk_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mx35pdk_flash,
+};
+
+static iomux_v3_cfg_t mx35pdk_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+ /* USBOTG */
+ MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+ MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+ /* USBH1 */
+ MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+ MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+ /* SDCARD */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* I2C1 */
+ MX35_PAD_I2C1_CLK__I2C1_SCL,
+ MX35_PAD_I2C1_DAT__I2C1_SDA,
+};
+
+static int mx35_3ds_otg_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
+}
+
+/* OTG config */
+static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .workaround = FLS_USB2_WORKAROUND_ENGCM09152,
+/*
+ * ENGCM09152 also requires a hardware change.
+ * Please check the MX35 Chip Errata document for details.
+ */
+};
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = mx35_3ds_otg_init,
+ .portsc = MXC_EHCI_MODE_UTMI,
+};
+
+static int mx35_3ds_usbh_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY);
+}
+
+/* USB HOST config */
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
+ .init = mx35_3ds_usbh_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static int otg_mode_host;
+
+static int __init mx35_3ds_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", mx35_3ds_otg_mode);
+
+static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx35_3ds_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt(NULL);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx35_add_imx_uart0(&uart_pdata);
+
+ if (otg_mode_host)
+ imx35_add_mxc_ehci_otg(&otg_pdata);
+
+ imx35_add_mxc_ehci_hs(&usb_host_pdata);
+
+ if (!otg_mode_host)
+ imx35_add_fsl_usb2_udc(&usb_otg_pdata);
+
+ imx35_add_mxc_nand(&mx35pdk_nand_board_info);
+ imx35_add_sdhci_esdhc_imx(0, NULL);
+
+ if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ pr_warn("Init of the debugboard failed, all "
+ "devices on the debugboard are unusable.\n");
+ imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
+}
+
+static void __init mx35pdk_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer mx35pdk_timer = {
+ .init = mx35pdk_timer_init,
+};
+
+MACHINE_START(MX35_3DS, "Freescale MX35PDK")
+ /* Maintainer: Freescale Semiconductor, Inc */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .timer = &mx35pdk_timer,
+ .init_machine = mx35_3ds_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
new file mode 100644
index 00000000..27745415
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <linux/gpio.h>
+#include <mach/iomux-mx27.h>
+#include <linux/i2c/pca953x.h>
+
+#include "devices-imx27.h"
+
+static const int mxt_td60_pins[] __initconst = {
+ /* UART0 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART1 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART2 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C1 */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* FB */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA25_PF_CLS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /* OWIRE */
+ PE16_AF_OWIRE,
+ /* SDHC1*/
+ PE18_PF_SD1_D0,
+ PE19_PF_SD1_D1,
+ PE20_PF_SD1_D2,
+ PE21_PF_SD1_D3,
+ PE22_PF_SD1_CMD,
+ PE23_PF_SD1_CLK,
+ PF8_AF_ATA_IORDY,
+ /* SDHC2*/
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+};
+
+static const struct mxc_nand_platform_data
+mxt_td60_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static const struct imxi2c_platform_data mxt_td60_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+/* PCA9557 */
+static int mxt_td60_pca9557_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ static int mxt_td60_gpio_value[] = {
+ -1, -1, -1, -1, -1, -1, -1, 1
+ };
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(mxt_td60_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MXT_TD60 GPIO Exp");
+ if (mxt_td60_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ mxt_td60_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data mxt_td60_pca9557_pdata = {
+ .gpio_base = 240, /* place PCA9557 after all MX27 gpio pins */
+ .invert = 0, /* Do not invert */
+ .setup = mxt_td60_pca9557_setup,
+};
+
+static struct i2c_board_info mxt_td60_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9557", 0x18),
+ .platform_data = &mxt_td60_pca9557_pdata,
+ },
+};
+
+static const struct imxi2c_platform_data mxt_td60_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxt_td60_i2c2_devices[] = {
+};
+
+static struct imx_fb_videomode mxt_td60_modes[] = {
+ {
+ .mode = {
+ .name = "Chimei LW700AT9003",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 30303,
+ .hsync_len = 64,
+ .left_margin = 0x67,
+ .right_margin = 0x68,
+ .vsync_len = 16,
+ .upper_margin = 0x0f,
+ .lower_margin = 0x0f,
+ },
+ .bpp = 16,
+ .pcr = 0xFA208B83,
+ },
+};
+
+static const struct imx_fb_platform_data mxt_td60_fb_data __initconst = {
+ .mode = mxt_td60_modes,
+ .num_modes = ARRAY_SIZE(mxt_td60_modes),
+
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+static int mxt_td60_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ return request_irq(IRQ_GPIOF(8), detect_irq, IRQF_TRIGGER_FALLING,
+ "sdhc1-card-detect", data);
+}
+
+static void mxt_td60_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOF(8), data);
+}
+
+static const struct imxmmc_platform_data sdhc1_pdata __initconst = {
+ .init = mxt_td60_sdhc1_init,
+ .exit = mxt_td60_sdhc1_exit,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init mxt_td60_board_init(void)
+{
+ mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
+ "MXT_TD60");
+
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+ imx27_add_mxc_nand(&mxt_td60_nand_board_info);
+
+ i2c_register_board_info(0, mxt_td60_i2c_devices,
+ ARRAY_SIZE(mxt_td60_i2c_devices));
+
+ i2c_register_board_info(1, mxt_td60_i2c2_devices,
+ ARRAY_SIZE(mxt_td60_i2c2_devices));
+
+ imx27_add_imx_i2c(0, &mxt_td60_i2c0_data);
+ imx27_add_imx_i2c(1, &mxt_td60_i2c1_data);
+ imx27_add_imx_fb(&mxt_td60_fb_data);
+ imx27_add_mxc_mmc(0, &sdhc1_pdata);
+ imx27_add_fec(NULL);
+}
+
+static void __init mxt_td60_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer mxt_td60_timer = {
+ .init = mxt_td60_timer_init,
+};
+
+MACHINE_START(MXT_TD60, "Maxtrack i-MXT TD60")
+ /* maintainer: Maxtrack Industrial */
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &mxt_td60_timer,
+ .init_machine = mxt_td60_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
new file mode 100644
index 00000000..bbddc5a1
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -0,0 +1,442 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2009 Sascha Hauer (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx27.h>
+#include <asm/mach/time.h>
+#include <mach/audmux.h>
+#include <mach/irqs.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx27.h"
+
+#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
+#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
+#define SPI1_SS0 (GPIO_PORTD + 28)
+#define SPI1_SS1 (GPIO_PORTD + 27)
+#define SD2_CD (GPIO_PORTC + 29)
+
+static const int pca100_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* SDHC */
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+ SD2_CD | GPIO_GPIO | GPIO_IN,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* SSI1 */
+ PC20_PF_SSI1_FS,
+ PC21_PF_SSI1_RXD,
+ PC22_PF_SSI1_TXD,
+ PC23_PF_SSI1_CLK,
+ /* onboard I2C */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* external I2C */
+ PD17_PF_I2C_DATA,
+ PD18_PF_I2C_CLK,
+ /* SPI1 */
+ PD25_PF_CSPI1_RDY,
+ PD29_PF_CSPI1_SCLK,
+ PD30_PF_CSPI1_MISO,
+ PD31_PF_CSPI1_MOSI,
+ /* OTG */
+ OTG_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PC9_PF_USBOTG_DATA0,
+ PC10_PF_USBOTG_DATA2,
+ PC11_PF_USBOTG_DATA1,
+ PC12_PF_USBOTG_DATA4,
+ PC13_PF_USBOTG_DATA3,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PE2_PF_USBOTG_DIR,
+ PE24_PF_USBOTG_CLK,
+ PE25_PF_USBOTG_DATA7,
+ /* USBH2 */
+ USBH2_PHY_CS_GPIO | GPIO_GPIO | GPIO_OUT,
+ PA0_PF_USBH2_CLK,
+ PA1_PF_USBH2_DIR,
+ PA2_PF_USBH2_DATA7,
+ PA3_PF_USBH2_NXT,
+ PA4_PF_USBH2_STP,
+ PD19_AF_USBH2_DATA4,
+ PD20_AF_USBH2_DATA3,
+ PD21_AF_USBH2_DATA6,
+ PD22_AF_USBH2_DATA0,
+ PD23_AF_USBH2_DATA2,
+ PD24_AF_USBH2_DATA1,
+ PD26_AF_USBH2_DATA5,
+ /* display */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA26_PF_PS,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA31_PF_OE_ACD,
+ /* free GPIO */
+ GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN, /* GPIO0_IRQ */
+ GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN, /* GPIO1_IRQ */
+ GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN, /* GPIO2_IRQ */
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct mxc_nand_platform_data
+pca100_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pca100_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("lm75", 0x4a),
+ }
+};
+
+static struct spi_eeprom at25320 = {
+ .name = "at25320an",
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = EE_ADDR2,
+};
+
+static struct spi_board_info pca100_spi_board_info[] __initdata = {
+ {
+ .modalias = "at25",
+ .max_speed_hz = 30000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &at25320,
+ },
+};
+
+static int pca100_spi_cs[] = {SPI1_SS0, SPI1_SS1};
+
+static const struct spi_imx_master pca100_spi0_data __initconst = {
+ .chipselect = pca100_spi_cs,
+ .num_chipselect = ARRAY_SIZE(pca100_spi_cs),
+};
+
+static void pca100_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+ mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT);
+ gpio_set_value(GPIO_PORTC + 20, 1);
+ udelay(2);
+ gpio_set_value(GPIO_PORTC + 20, 0);
+ mxc_gpio_mode(PC20_PF_SSI1_FS);
+ msleep(2);
+}
+
+static void pca100_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+ mxc_gpio_mode(GPIO_PORTC | 20 | GPIO_GPIO | GPIO_OUT); /* FS */
+ gpio_set_value(GPIO_PORTC + 20, 0);
+ mxc_gpio_mode(GPIO_PORTC | 22 | GPIO_GPIO | GPIO_OUT); /* TX */
+ gpio_set_value(GPIO_PORTC + 22, 0);
+ mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_OUT); /* reset */
+ gpio_set_value(GPIO_PORTC + 28, 0);
+ udelay(10);
+ gpio_set_value(GPIO_PORTC + 28, 1);
+ mxc_gpio_mode(PC20_PF_SSI1_FS);
+ mxc_gpio_mode(PC22_PF_SSI1_TXD);
+ msleep(2);
+}
+
+static const struct imx_ssi_platform_data pca100_ssi_pdata __initconst = {
+ .ac97_reset = pca100_ac97_cold_reset,
+ .ac97_warm_reset = pca100_ac97_warm_reset,
+ .flags = IMX_SSI_USE_AC97,
+};
+
+static int pca100_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = request_irq(IRQ_GPIOC(29), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "imx-mmc-detect", data);
+ if (ret)
+ printk(KERN_ERR
+ "pca100: Failed to reuest irq for sd/mmc detection\n");
+
+ return ret;
+}
+
+static void pca100_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOC(29), data);
+}
+
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
+ .init = pca100_sdhc2_init,
+ .exit = pca100_sdhc2_exit,
+};
+
+static int otg_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+
+ mdelay(10);
+
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = otg_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int usbh2_phy_init(struct platform_device *pdev)
+{
+ gpio_set_value(USBH2_PHY_CS_GPIO, 0);
+
+ mdelay(10);
+
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = usbh2_phy_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init pca100_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", pca100_otg_mode);
+
+/* framebuffer info */
+static struct imx_fb_videomode pca100_fb_modes[] = {
+ {
+ .mode = {
+ .name = "EMERGING-ETV570G0DHU",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39722, /* in ps (25.175 MHz) */
+ .hsync_len = 30,
+ .left_margin = 114,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 32,
+ .lower_margin = 0,
+ },
+ /*
+ * TFT
+ * Pixel pol active high
+ * HSYNC active low
+ * VSYNC active low
+ * use HSYNC for ACD count
+ * line clock disable while idle
+ * always enable line clock even if no data
+ */
+ .pcr = 0xf0c08080,
+ .bpp = 16,
+ },
+};
+
+static const struct imx_fb_platform_data pca100_fb_data __initconst = {
+ .mode = pca100_fb_modes,
+ .num_modes = ARRAY_SIZE(pca100_fb_modes),
+
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+static void __init pca100_init(void)
+{
+ int ret;
+
+ /* SSI unit */
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V1_PCR_TFCSEL(3) |
+ MXC_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */
+ MXC_AUDMUX_V1_PCR_RXDSEL(3));
+ mxc_audmux_v1_configure_port(3,
+ MXC_AUDMUX_V1_PCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V1_PCR_TFCSEL(0) |
+ MXC_AUDMUX_V1_PCR_TFSDIR |
+ MXC_AUDMUX_V1_PCR_RXDSEL(0));
+
+ ret = mxc_gpio_setup_multiple_pins(pca100_pins,
+ ARRAY_SIZE(pca100_pins), "PCA100");
+ if (ret)
+ printk(KERN_ERR "pca100: Failed to setup pins (%d)\n", ret);
+
+ imx27_add_imx_ssi(0, &pca100_ssi_pdata);
+
+ imx27_add_imx_uart0(&uart_pdata);
+
+ imx27_add_mxc_mmc(1, &sdhc_pdata);
+
+ imx27_add_mxc_nand(&pca100_nand_board_info);
+
+ /* only the i2c master 1 is used on this CPU card */
+ i2c_register_board_info(1, pca100_i2c_devices,
+ ARRAY_SIZE(pca100_i2c_devices));
+
+ imx27_add_imx_i2c(1, &pca100_i2c1_data);
+
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN);
+ mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN);
+ spi_register_board_info(pca100_spi_board_info,
+ ARRAY_SIZE(pca100_spi_board_info));
+ imx27_add_spi_imx0(&pca100_spi0_data);
+
+ gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
+ gpio_direction_output(OTG_PHY_CS_GPIO, 1);
+ gpio_request(USBH2_PHY_CS_GPIO, "usb-host2-cs");
+ gpio_direction_output(USBH2_PHY_CS_GPIO, 1);
+
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+
+ if (otg_pdata.otg)
+ imx27_add_mxc_ehci_otg(&otg_pdata);
+ } else {
+ gpio_set_value(OTG_PHY_CS_GPIO, 0);
+ imx27_add_fsl_usb2_udc(&otg_device_pdata);
+ }
+
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
+
+ if (usbh2_pdata.otg)
+ imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+ imx27_add_imx_fb(&pca100_fb_data);
+
+ imx27_add_fec(NULL);
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
+}
+
+static void __init pca100_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pca100_timer = {
+ .init = pca100_timer_init,
+};
+
+MACHINE_START(PCA100, "phyCARD-i.MX27")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .init_machine = pca100_init,
+ .timer = &pca100_timer,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
new file mode 100644
index 00000000..89c213b8
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -0,0 +1,696 @@
+/*
+ * Copyright (C) 2008 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/gfp.h>
+#include <linux/memblock.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+#include "pcm037.h"
+
+static enum pcm037_board_variant pcm037_instance = PCM037_PCM970;
+
+static int __init pcm037_variant_setup(char *str)
+{
+ if (!strcmp("eet", str))
+ pcm037_instance = PCM037_EET;
+ else if (strcmp("pcm970", str))
+ pr_warning("Unknown pcm037 baseboard variant %s\n", str);
+
+ return 1;
+}
+
+/* Supported values: "pcm970" (default) and "eet" */
+__setup("pcm037_variant=", pcm037_variant_setup);
+
+enum pcm037_board_variant pcm037_variant(void)
+{
+ return pcm037_instance;
+}
+
+/* UART1 with RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_handshake_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+};
+
+/* UART1 without RTS/CTS handshake signals */
+static unsigned int pcm037_uart1_pins[] = {
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+};
+
+static unsigned int pcm037_pins[] = {
+ /* I2C */
+ MX31_PIN_CSPI2_MOSI__SCL,
+ MX31_PIN_CSPI2_MISO__SDA,
+ MX31_PIN_CSPI2_SS2__I2C3_SDA,
+ MX31_PIN_CSPI2_SCLK__I2C3_SCL,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO), /* card detect */
+ IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_GPIO), /* write protect */
+ /* SPI1 */
+ MX31_PIN_CSPI1_MOSI__MOSI,
+ MX31_PIN_CSPI1_MISO__MISO,
+ MX31_PIN_CSPI1_SCLK__SCLK,
+ MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI1_SS0__SS0,
+ MX31_PIN_CSPI1_SS1__SS1,
+ MX31_PIN_CSPI1_SS2__SS2,
+ /* UART2 */
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ /* UART3 */
+ MX31_PIN_CSPI3_MOSI__RXD3,
+ MX31_PIN_CSPI3_MISO__TXD3,
+ MX31_PIN_CSPI3_SCLK__RTS3,
+ MX31_PIN_CSPI3_SPI_RDY__CTS3,
+ /* LAN9217 irq pin */
+ IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO),
+ /* Onewire */
+ MX31_PIN_BATT_LINE__OWIRE,
+ /* Framebuffer */
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ MX31_PIN_D3_REV__D3_REV,
+ MX31_PIN_CONTRAST__CONTRAST,
+ MX31_PIN_D3_SPL__D3_SPL,
+ MX31_PIN_D3_CLS__D3_CLS,
+ MX31_PIN_LCS0__GPI03_23,
+ /* CSI */
+ IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO),
+ MX31_PIN_CSI_D6__CSI_D6,
+ MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8,
+ MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10,
+ MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12,
+ MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14,
+ MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC,
+ MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
+ MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ /* GPIO */
+ IOMUX_MODE(MX31_PIN_ATA_DMACK, IOMUX_CONFIG_GPIO),
+ /* OTG */
+ MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+ MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+ MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+ MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+ MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+ MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+ MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+ MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+ MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+ MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+ MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+ MX31_PIN_USBOTG_STP__USBOTG_STP,
+ /* USB host 2 */
+ IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+ IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
+};
+
+static struct physmap_flash_data pcm037_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm037_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm037_flash_data,
+ },
+ .resource = &pcm037_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct resource smsc911x_resources[] = {
+ {
+ .start = MX31_CS1_BASE_ADDR + 0x300,
+ .end = MX31_CS1_BASE_ADDR + 0x300 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+ .end = IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY |
+ SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device pcm037_eth = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+ .bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+ .start = MX31_CS4_BASE_ADDR,
+ .end = MX31_CS4_BASE_ADDR + 512 * 1024 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm037_sram_device = {
+ .name = "mtd-ram",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_sram_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_sram_resource,
+};
+
+static const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
+ .bitrate = 20000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static int pcm037_camera_power(struct device *dev, int on)
+{
+ /* disable or enable the camera in X7 or X8 PCM970 connector */
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on);
+ return 0;
+}
+
+static struct i2c_board_info pcm037_i2c_camera[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ }, {
+ I2C_BOARD_INFO("mt9v022", 0x48),
+ },
+};
+
+static struct soc_camera_link iclink_mt9v022 = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .board_info = &pcm037_i2c_camera[1],
+ .i2c_adapter_id = 2,
+};
+
+static struct soc_camera_link iclink_mt9t031 = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = pcm037_camera_power,
+ .board_info = &pcm037_i2c_camera[0],
+ .i2c_adapter_id = 2,
+};
+
+static struct i2c_board_info pcm037_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }
+};
+
+static struct platform_device pcm037_mt9t031 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_mt9t031,
+ },
+};
+
+static struct platform_device pcm037_mt9v022 = {
+ .name = "soc-camera-pdrv",
+ .id = 1,
+ .dev = {
+ .platform_data = &iclink_mt9v022,
+ },
+};
+
+/* Not connected by default */
+#ifdef PCM970_SDHC_RW_SWITCH
+static int pcm970_sdhc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_SFS6));
+}
+#endif
+
+#define SDHC1_GPIO_WP IOMUX_TO_GPIO(MX31_PIN_SFS6)
+#define SDHC1_GPIO_DET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static int pcm970_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC1_GPIO_DET, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC1_GPIO_DET);
+
+#ifdef PCM970_SDHC_RW_SWITCH
+ ret = gpio_request(SDHC1_GPIO_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC1_GPIO_WP);
+#endif
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "sdhc-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+#ifdef PCM970_SDHC_RW_SWITCH
+ gpio_free(SDHC1_GPIO_WP);
+err_gpio_free:
+#endif
+ gpio_free(SDHC1_GPIO_DET);
+
+ return ret;
+}
+
+static void pcm970_sdhc1_exit(struct device *dev, void *data)
+{
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_SCK6), data);
+ gpio_free(SDHC1_GPIO_DET);
+ gpio_free(SDHC1_GPIO_WP);
+}
+
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
+#ifdef PCM970_SDHC_RW_SWITCH
+ .get_ro = pcm970_sdhc1_get_ro,
+#endif
+ .init = pcm970_sdhc1_init,
+ .exit = pcm970_sdhc1_exit,
+};
+
+struct mx3_camera_pdata camera_pdata __initdata = {
+ .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+ .mclk_10khz = 2000,
+};
+
+static phys_addr_t mx3_camera_base __initdata;
+#define MX3_CAMERA_BUF_SIZE SZ_4M
+
+static int __init pcm037_init_camera(void)
+{
+ int dma, ret = -ENOMEM;
+ struct platform_device *pdev = imx31_alloc_mx3_camera(&camera_pdata);
+
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ dma = dma_declare_coherent_memory(&pdev->dev,
+ mx3_camera_base, mx3_camera_base,
+ MX3_CAMERA_BUF_SIZE,
+ DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+ if (!(dma & DMA_MEMORY_MAP))
+ goto err;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+err:
+ platform_device_put(pdev);
+
+ return ret;
+}
+
+static struct platform_device *devices[] __initdata = {
+ &pcm037_flash,
+ &pcm037_sram_device,
+ &pcm037_mt9t031,
+ &pcm037_mt9v022,
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz Sharp */
+ .name = "Sharp-LQ035Q7DH06-QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
+ FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "TX090",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 7,
+ .lower_margin = 40,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "CMEL-OLED",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+ .name = "Sharp-LQ035Q7DH06-QVGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct resource pcm970_sja1000_resources[] = {
+ {
+ .start = MX31_CS5_BASE_ADDR,
+ .end = MX31_CS5_BASE_ADDR + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+ .end = IOMUX_TO_IRQ(IOMUX_PIN(48, 105)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+struct sja1000_platform_data pcm970_sja1000_platform_data = {
+ .osc_freq = 16000000,
+ .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
+ .cdr = CDR_CBP,
+};
+
+static struct platform_device pcm970_sja1000 = {
+ .name = "sja1000_platform",
+ .dev = {
+ .platform_data = &pcm970_sja1000_platform_data,
+ },
+ .resource = pcm970_sja1000_resources,
+ .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
+static int pcm037_otg_init(struct platform_device *pdev)
+{
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = pcm037_otg_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int pcm037_usbh2_init(struct platform_device *pdev)
+{
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+ .init = pcm037_usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init pcm037_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", pcm037_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init pcm037_init(void)
+{
+ int ret;
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
+
+ mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins),
+ "pcm037");
+
+#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS \
+ | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG); /* USBH2_DATA0 */
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG); /* USBH2_DATA1 */
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */
+ mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */
+ mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */
+ mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */
+ mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */
+
+ if (pcm037_variant() == PCM037_EET)
+ mxc_iomux_setup_multiple_pins(pcm037_uart1_pins,
+ ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1");
+ else
+ mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins,
+ ARRAY_SIZE(pcm037_uart1_handshake_pins),
+ "pcm037_uart1");
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx31_add_imx2_wdt(NULL);
+ imx31_add_imx_uart0(&uart_pdata);
+ /* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */
+ imx31_add_imx_uart1(&uart_pdata);
+ imx31_add_imx_uart2(&uart_pdata);
+
+ imx31_add_mxc_w1(NULL);
+
+ /* LAN9217 IRQ pin */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1), "lan9217-irq");
+ if (ret)
+ pr_warning("could not get LAN irq gpio\n");
+ else {
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO3_1));
+ platform_device_register(&pcm037_eth);
+ }
+
+
+ /* I2C adapters and devices */
+ i2c_register_board_info(1, pcm037_i2c_devices,
+ ARRAY_SIZE(pcm037_i2c_devices));
+
+ imx31_add_imx_i2c1(&pcm037_i2c1_data);
+ imx31_add_imx_i2c2(&pcm037_i2c2_data);
+
+ imx31_add_mxc_nand(&pcm037_nand_board_info);
+ imx31_add_mxc_mmc(0, &sdhc_pdata);
+ imx31_add_ipu_core(&mx3_ipu_data);
+ imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ /* CSI */
+ /* Camera power: default - off */
+ ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power");
+ if (!ret)
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1);
+ else
+ iclink_mt9t031.power = NULL;
+
+ pcm037_init_camera();
+
+ platform_device_register(&pcm970_sja1000);
+
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (otg_pdata.otg)
+ imx31_add_mxc_ehci_otg(&otg_pdata);
+ }
+
+ usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (usbh2_pdata.otg)
+ imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+ if (!otg_mode_host)
+ imx31_add_fsl_usb2_udc(&otg_device_pdata);
+
+}
+
+static void __init pcm037_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+struct sys_timer pcm037_timer = {
+ .init = pcm037_timer_init,
+};
+
+static void __init pcm037_reserve(void)
+{
+ /* reserve 4 MiB for mx3-camera */
+ mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
+ MX3_CAMERA_BUF_SIZE);
+ memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+ memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(PCM037, "Phytec Phycore pcm037")
+ /* Maintainer: Pengutronix */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .reserve = pcm037_reserve,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &pcm037_timer,
+ .init_machine = pcm037_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm037_eet.c b/arch/arm/mach-imx/mach-pcm037_eet.c
new file mode 100644
index 00000000..1b7606be
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm037_eet.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2009
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+
+#include <asm/mach-types.h>
+
+#include "pcm037.h"
+#include "devices-imx31.h"
+
+static unsigned int pcm037_eet_pins[] = {
+ /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
+ IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO),
+ /* GPIO keys */
+ IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), /* 0 */
+ IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), /* 1 */
+ IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO), /* 2 */
+ IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), /* 3 */
+ IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO), /* 32 */
+ IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO), /* 33 */
+ IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO), /* 34 */
+ IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO), /* 35 */
+ IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO), /* 38 */
+ IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO), /* 39 */
+ IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO), /* 50 */
+ IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_GPIO), /* 51 */
+ IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_GPIO), /* 52 */
+ IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_GPIO), /* 53 */
+
+ /* LEDs */
+ IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_CONFIG_GPIO), /* 44 */
+ IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_GPIO), /* 45 */
+ IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_GPIO), /* 55 */
+ IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_GPIO), /* 56 */
+};
+
+/* SPI */
+static struct spi_board_info pcm037_spi_dev[] = {
+ {
+ .modalias = "dac124s085",
+ .max_speed_hz = 400000,
+ .bus_num = 0,
+ .chip_select = 0, /* Index in pcm037_spi1_cs[] */
+ .mode = SPI_CPHA,
+ },
+};
+
+/* Platform Data for MXC CSPI */
+static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
+
+static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
+ .chipselect = pcm037_spi1_cs,
+ .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
+};
+
+/* GPIO-keys input device */
+static struct gpio_keys_button pcm037_gpio_keys[] = {
+ {
+ .type = EV_KEY,
+ .code = KEY_L,
+ .gpio = 0,
+ .desc = "Wheel Manual",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_A,
+ .gpio = 1,
+ .desc = "Wheel AF",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_V,
+ .gpio = 2,
+ .desc = "Wheel View",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_M,
+ .gpio = 3,
+ .desc = "Wheel Menu",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_UP,
+ .gpio = 32,
+ .desc = "Nav Pad Up",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_RIGHT,
+ .gpio = 33,
+ .desc = "Nav Pad Right",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_DOWN,
+ .gpio = 34,
+ .desc = "Nav Pad Down",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_LEFT,
+ .gpio = 35,
+ .desc = "Nav Pad Left",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_ENTER,
+ .gpio = 38,
+ .desc = "Nav Pad Ok",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = KEY_O,
+ .gpio = 39,
+ .desc = "Wheel Off",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = BTN_FORWARD,
+ .gpio = 50,
+ .desc = "Focus Forward",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = BTN_BACK,
+ .gpio = 51,
+ .desc = "Focus Backward",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = BTN_MIDDLE,
+ .gpio = 52,
+ .desc = "Release Half",
+ .wakeup = 0,
+ }, {
+ .type = EV_KEY,
+ .code = BTN_EXTRA,
+ .gpio = 53,
+ .desc = "Release Full",
+ .wakeup = 0,
+ },
+};
+
+static const struct gpio_keys_platform_data
+ pcm037_gpio_keys_platform_data __initconst = {
+ .buttons = pcm037_gpio_keys,
+ .nbuttons = ARRAY_SIZE(pcm037_gpio_keys),
+ .rep = 0, /* No auto-repeat */
+};
+
+static int __init eet_init_devices(void)
+{
+ if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET)
+ return 0;
+
+ mxc_iomux_setup_multiple_pins(pcm037_eet_pins,
+ ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet");
+
+ /* SPI */
+ spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev));
+ imx31_add_spi_imx0(&pcm037_spi1_pdata);
+
+ imx_add_gpio_keys(&pcm037_gpio_keys_platform_data);
+
+ return 0;
+}
+late_initcall(eet_init_devices);
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
new file mode 100644
index 00000000..853bb871
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2007 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/io.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-pcm038.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx27.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx27.h"
+
+static const int pcm038_pins[] __initconst = {
+ /* UART1 */
+ PE12_PF_UART1_TXD,
+ PE13_PF_UART1_RXD,
+ PE14_PF_UART1_CTS,
+ PE15_PF_UART1_RTS,
+ /* UART2 */
+ PE3_PF_UART2_CTS,
+ PE4_PF_UART2_RTS,
+ PE6_PF_UART2_TXD,
+ PE7_PF_UART2_RXD,
+ /* UART3 */
+ PE8_PF_UART3_TXD,
+ PE9_PF_UART3_RXD,
+ PE10_PF_UART3_CTS,
+ PE11_PF_UART3_RTS,
+ /* FEC */
+ PD0_AIN_FEC_TXD0,
+ PD1_AIN_FEC_TXD1,
+ PD2_AIN_FEC_TXD2,
+ PD3_AIN_FEC_TXD3,
+ PD4_AOUT_FEC_RX_ER,
+ PD5_AOUT_FEC_RXD1,
+ PD6_AOUT_FEC_RXD2,
+ PD7_AOUT_FEC_RXD3,
+ PD8_AF_FEC_MDIO,
+ PD9_AIN_FEC_MDC,
+ PD10_AOUT_FEC_CRS,
+ PD11_AOUT_FEC_TX_CLK,
+ PD12_AOUT_FEC_RXD0,
+ PD13_AOUT_FEC_RX_DV,
+ PD14_AOUT_FEC_RX_CLK,
+ PD15_AOUT_FEC_COL,
+ PD16_AIN_FEC_TX_ER,
+ PF23_AIN_FEC_TX_EN,
+ /* I2C2 */
+ PC5_PF_I2C2_SDA,
+ PC6_PF_I2C2_SCL,
+ /* SPI1 */
+ PD25_PF_CSPI1_RDY,
+ PD29_PF_CSPI1_SCLK,
+ PD30_PF_CSPI1_MISO,
+ PD31_PF_CSPI1_MOSI,
+ /* SSI1 */
+ PC20_PF_SSI1_FS,
+ PC21_PF_SSI1_RXD,
+ PC22_PF_SSI1_TXD,
+ PC23_PF_SSI1_CLK,
+ /* SSI4 */
+ PC16_PF_SSI4_FS,
+ PC17_PF_SSI4_RXD,
+ PC18_PF_SSI4_TXD,
+ PC19_PF_SSI4_CLK,
+ /* USB host */
+ PA0_PF_USBH2_CLK,
+ PA1_PF_USBH2_DIR,
+ PA2_PF_USBH2_DATA7,
+ PA3_PF_USBH2_NXT,
+ PA4_PF_USBH2_STP,
+ PD19_AF_USBH2_DATA4,
+ PD20_AF_USBH2_DATA3,
+ PD21_AF_USBH2_DATA6,
+ PD22_AF_USBH2_DATA0,
+ PD23_AF_USBH2_DATA2,
+ PD24_AF_USBH2_DATA1,
+ PD26_AF_USBH2_DATA5,
+};
+
+/*
+ * Phytec's PCM038 comes with 2MiB battery buffered SRAM,
+ * 16 bit width
+ */
+
+static struct platdata_mtd_ram pcm038_sram_data = {
+ .bankwidth = 2,
+};
+
+static struct resource pcm038_sram_resource = {
+ .start = MX27_CS1_BASE_ADDR,
+ .end = MX27_CS1_BASE_ADDR + 512 * 1024 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_sram_mtd_device = {
+ .name = "mtd-ram",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_sram_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_sram_resource,
+};
+
+/*
+ * Phytec's phyCORE-i.MX27 comes with 32MiB flash,
+ * 16 bit width
+ */
+static struct physmap_flash_data pcm038_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm038_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm038_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm038_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &pcm038_flash_resource,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct mxc_nand_platform_data
+pcm038_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &pcm038_nor_mtd_device,
+ &pcm038_sram_mtd_device,
+};
+
+/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
+ * setup other stuffs to access the sram. */
+static void __init pcm038_init_sram(void)
+{
+ mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
+}
+
+static const struct imxi2c_platform_data pcm038_i2c1_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm038_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("lm75", 0x4a),
+ }
+};
+
+static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
+
+static const struct spi_imx_master pcm038_spi0_data __initconst = {
+ .chipselect = pcm038_spi_cs,
+ .num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
+};
+
+static struct regulator_consumer_supply sdhc1_consumers[] = {
+ {
+ .dev_name = "mxc-mmc.1",
+ .supply = "sdhc_vcc",
+ },
+};
+
+static struct regulator_init_data sdhc1_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdhc1_consumers),
+ .consumer_supplies = sdhc1_consumers,
+};
+
+static struct regulator_consumer_supply cam_consumers[] = {
+ {
+ .dev = NULL,
+ .supply = "imx_cam_vcc",
+ },
+};
+
+static struct regulator_init_data cam_data = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3400000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_FAST,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cam_consumers),
+ .consumer_supplies = cam_consumers,
+};
+
+static struct mc13xxx_regulator_init_data pcm038_regulators[] = {
+ {
+ .id = MC13783_REG_VCAM,
+ .init_data = &cam_data,
+ }, {
+ .id = MC13783_REG_VMMC1,
+ .init_data = &sdhc1_data,
+ },
+};
+
+static struct mc13xxx_platform_data pcm038_pmic = {
+ .regulators = {
+ .regulators = pcm038_regulators,
+ .num_regulators = ARRAY_SIZE(pcm038_regulators),
+ },
+ .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
+ MC13783_USE_TOUCHSCREEN,
+};
+
+static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+ {
+ .modalias = "mc13783",
+ .irq = IRQ_GPIOB(23),
+ .max_speed_hz = 300000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &pcm038_pmic,
+ .mode = SPI_CS_HIGH,
+ }
+};
+
+static int pcm038_usbh2_init(struct platform_device *pdev)
+{
+ return mx27_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static const struct mxc_usbh_platform_data usbh2_pdata __initconst = {
+ .init = pcm038_usbh2_init,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static void __init pcm038_init(void)
+{
+ mxc_gpio_setup_multiple_pins(pcm038_pins, ARRAY_SIZE(pcm038_pins),
+ "PCM038");
+
+ pcm038_init_sram();
+
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+
+ mxc_gpio_mode(PE16_AF_OWIRE);
+ imx27_add_mxc_nand(&pcm038_nand_board_info);
+
+ /* only the i2c master 1 is used on this CPU card */
+ i2c_register_board_info(1, pcm038_i2c_devices,
+ ARRAY_SIZE(pcm038_i2c_devices));
+
+ imx27_add_imx_i2c(1, &pcm038_i2c1_data);
+
+ /* PE18 for user-LED D40 */
+ mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
+
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+
+ /* MC13783 IRQ */
+ mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
+
+ imx27_add_spi_imx0(&pcm038_spi0_data);
+ spi_register_board_info(pcm038_spi_board_info,
+ ARRAY_SIZE(pcm038_spi_board_info));
+
+ imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+ imx27_add_fec(NULL);
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx27_add_imx2_wdt(NULL);
+ imx27_add_mxc_w1(NULL);
+
+#ifdef CONFIG_MACH_PCM970_BASEBOARD
+ pcm970_baseboard_init();
+#endif
+}
+
+static void __init pcm038_timer_init(void)
+{
+ mx27_clocks_init(26000000);
+}
+
+static struct sys_timer pcm038_timer = {
+ .init = pcm038_timer_init,
+};
+
+MACHINE_START(PCM038, "phyCORE-i.MX27")
+ .boot_params = MX27_PHYS_OFFSET + 0x100,
+ .map_io = mx27_map_io,
+ .init_early = imx27_init_early,
+ .init_irq = mx27_init_irq,
+ .timer = &pcm038_timer,
+ .init_machine = pcm038_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
new file mode 100644
index 00000000..02644162
--- /dev/null
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/smc911x.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/ulpi.h>
+#include <mach/audmux.h>
+
+#include "devices-imx35.h"
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 240x320 @ 60 Hz */
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 185925,
+ .left_margin = 9,
+ .right_margin = 16,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | FB_SYNC_CLK_INVERT | FB_SYNC_CLK_IDLE_EN,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 240x320 @ 60 Hz */
+ .name = "TX090",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 7,
+ .lower_margin = 40,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "Sharp-LQ035Q7",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data pcm043_flash_data = {
+ .width = 2,
+};
+
+static struct resource pcm043_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm043_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm043_flash_data,
+ },
+ .resource = &pcm043_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
+ .bitrate = 50000,
+};
+
+static struct at24_platform_data board_eeprom = {
+ .byte_len = 4096,
+ .page_size = 32,
+ .flags = AT24_FLAG_ADDR16,
+};
+
+static struct i2c_board_info pcm043_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
+ .platform_data = &board_eeprom,
+ }, {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &pcm043_flash,
+};
+
+static iomux_v3_cfg_t pcm043_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* UART2 */
+ MX35_PAD_CTS2__UART2_CTS,
+ MX35_PAD_RTS2__UART2_RTS,
+ MX35_PAD_TXD2__UART2_TXD_MUX,
+ MX35_PAD_RXD2__UART2_RXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+ /* I2C1 */
+ MX35_PAD_I2C1_CLK__I2C1_SCL,
+ MX35_PAD_I2C1_DAT__I2C1_SDA,
+ /* Display */
+ MX35_PAD_LD0__IPU_DISPB_DAT_0,
+ MX35_PAD_LD1__IPU_DISPB_DAT_1,
+ MX35_PAD_LD2__IPU_DISPB_DAT_2,
+ MX35_PAD_LD3__IPU_DISPB_DAT_3,
+ MX35_PAD_LD4__IPU_DISPB_DAT_4,
+ MX35_PAD_LD5__IPU_DISPB_DAT_5,
+ MX35_PAD_LD6__IPU_DISPB_DAT_6,
+ MX35_PAD_LD7__IPU_DISPB_DAT_7,
+ MX35_PAD_LD8__IPU_DISPB_DAT_8,
+ MX35_PAD_LD9__IPU_DISPB_DAT_9,
+ MX35_PAD_LD10__IPU_DISPB_DAT_10,
+ MX35_PAD_LD11__IPU_DISPB_DAT_11,
+ MX35_PAD_LD12__IPU_DISPB_DAT_12,
+ MX35_PAD_LD13__IPU_DISPB_DAT_13,
+ MX35_PAD_LD14__IPU_DISPB_DAT_14,
+ MX35_PAD_LD15__IPU_DISPB_DAT_15,
+ MX35_PAD_LD16__IPU_DISPB_DAT_16,
+ MX35_PAD_LD17__IPU_DISPB_DAT_17,
+ MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+ MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+ MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+ MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+ MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+ MX35_PAD_D3_REV__IPU_DISPB_D3_REV,
+ MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS,
+ /* gpio */
+ MX35_PAD_ATA_CS0__GPIO2_6,
+ /* USB host */
+ MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+ MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+ /* SSI */
+ MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+ MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+ MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+ MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+ /* CAN2 */
+ MX35_PAD_TX5_RX0__CAN2_TXCAN,
+ MX35_PAD_TX4_RX1__CAN2_RXCAN,
+ /* esdhc */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+ MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
+};
+
+#define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31)
+#define AC97_GPIO_TXD IMX_GPIO_NR(2, 28)
+#define AC97_GPIO_RESET IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_WP IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD IMX_GPIO_NR(2, 24)
+
+static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+ iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+ int ret;
+
+ ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+ if (ret) {
+ printk("failed to get GPIO_TXFS: %d\n", ret);
+ return;
+ }
+
+ mxc_iomux_v3_setup_pad(txfs_gpio);
+
+ /* warm reset */
+ gpio_direction_output(AC97_GPIO_TXFS, 1);
+ udelay(2);
+ gpio_set_value(AC97_GPIO_TXFS, 0);
+
+ gpio_free(AC97_GPIO_TXFS);
+ mxc_iomux_v3_setup_pad(txfs);
+}
+
+static void pcm043_ac97_cold_reset(struct snd_ac97 *ac97)
+{
+ iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+ iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+ iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28;
+ iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
+ iomux_v3_cfg_t reset_gpio = MX35_PAD_SD2_CMD__GPIO2_0;
+ int ret;
+
+ ret = gpio_request(AC97_GPIO_TXFS, "SSI");
+ if (ret)
+ goto err1;
+
+ ret = gpio_request(AC97_GPIO_TXD, "SSI");
+ if (ret)
+ goto err2;
+
+ ret = gpio_request(AC97_GPIO_RESET, "SSI");
+ if (ret)
+ goto err3;
+
+ mxc_iomux_v3_setup_pad(txfs_gpio);
+ mxc_iomux_v3_setup_pad(txd_gpio);
+ mxc_iomux_v3_setup_pad(reset_gpio);
+
+ gpio_direction_output(AC97_GPIO_TXFS, 0);
+ gpio_direction_output(AC97_GPIO_TXD, 0);
+
+ /* cold reset */
+ gpio_direction_output(AC97_GPIO_RESET, 0);
+ udelay(10);
+ gpio_direction_output(AC97_GPIO_RESET, 1);
+
+ mxc_iomux_v3_setup_pad(txd);
+ mxc_iomux_v3_setup_pad(txfs);
+
+ gpio_free(AC97_GPIO_RESET);
+err3:
+ gpio_free(AC97_GPIO_TXD);
+err2:
+ gpio_free(AC97_GPIO_TXFS);
+err1:
+ if (ret)
+ printk("%s failed with %d\n", __func__, ret);
+ mdelay(1);
+}
+
+static const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
+ .ac97_reset = pcm043_ac97_cold_reset,
+ .ac97_warm_reset = pcm043_ac97_warm_reset,
+ .flags = IMX_SSI_USE_AC97,
+};
+
+static const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+};
+
+static int pcm043_otg_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+ .init = pcm043_otg_init,
+ .portsc = MXC_EHCI_MODE_UTMI,
+};
+
+static int pcm043_usbh1_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+ MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+ .init = pcm043_usbh1_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
+static int otg_mode_host;
+
+static int __init pcm043_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", pcm043_otg_mode);
+
+static struct esdhc_platform_data sd1_pdata = {
+ .wp_gpio = SD1_GPIO_WP,
+ .cd_gpio = SD1_GPIO_CD,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init pcm043_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(pcm043_pads, ARRAY_SIZE(pcm043_pads));
+
+ mxc_audmux_v2_configure_port(3,
+ MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V2_PTCR_TFSEL(0) |
+ MXC_AUDMUX_V2_PTCR_TFSDIR,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0));
+
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN | /* 4wire mode */
+ MXC_AUDMUX_V2_PTCR_TCSEL(3) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */
+ MXC_AUDMUX_V2_PDCR_RXDSEL(3));
+
+ imx35_add_fec(NULL);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx35_add_imx2_wdt(NULL);
+
+ imx35_add_imx_uart0(&uart_pdata);
+ imx35_add_mxc_nand(&pcm037_nand_board_info);
+ imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
+
+ imx35_add_imx_uart1(&uart_pdata);
+
+ i2c_register_board_info(0, pcm043_i2c_devices,
+ ARRAY_SIZE(pcm043_i2c_devices));
+
+ imx35_add_imx_i2c0(&pcm043_i2c0_data);
+
+ imx35_add_ipu_core(&mx3_ipu_data);
+ imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ if (otg_mode_host) {
+ otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (otg_pdata.otg)
+ imx35_add_mxc_ehci_otg(&otg_pdata);
+ }
+ imx35_add_mxc_ehci_hs(&usbh1_pdata);
+
+ if (!otg_mode_host)
+ imx35_add_fsl_usb2_udc(&otg_device_pdata);
+
+ imx35_add_flexcan1(NULL);
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
+}
+
+static void __init pcm043_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer pcm043_timer = {
+ .init = pcm043_timer_init,
+};
+
+MACHINE_START(PCM043, "Phytec Phycore pcm043")
+ /* Maintainer: Pengutronix */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .timer = &pcm043_timer,
+ .init_machine = pcm043_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c
new file mode 100644
index 00000000..c1632871
--- /dev/null
+++ b/arch/arm/mach-imx/mach-qong.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices-imx31.h"
+
+/* FPGA defines */
+#define QONG_FPGA_VERSION(major, minor, rev) \
+ (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF))
+
+#define QONG_FPGA_BASEADDR MX31_CS1_BASE_ADDR
+#define QONG_FPGA_PERIPH_SIZE (1 << 24)
+
+#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR
+#define QONG_FPGA_CTRL_SIZE 0x10
+/* FPGA control registers */
+#define QONG_FPGA_CTRL_VERSION 0x00
+
+#define QONG_DNET_ID 1
+#define QONG_DNET_BASEADDR \
+ (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE)
+#define QONG_DNET_SIZE 0x00001000
+
+#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1)
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int uart_pins[] = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1
+};
+
+static inline void __init mxc_init_imx_uart(void)
+{
+ mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
+ "uart-0");
+ imx31_add_imx_uart0(&uart_pdata);
+}
+
+static struct resource dnet_resources[] = {
+ {
+ .name = "dnet-memory",
+ .start = QONG_DNET_BASEADDR,
+ .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = QONG_FPGA_IRQ,
+ .end = QONG_FPGA_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dnet_device = {
+ .name = "dnet",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dnet_resources),
+ .resource = dnet_resources,
+};
+
+static int __init qong_init_dnet(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dnet_device);
+ return ret;
+}
+
+/* MTD NOR flash */
+
+static struct physmap_flash_data qong_flash_data = {
+ .width = 2,
+};
+
+static struct resource qong_flash_resource = {
+ .start = MX31_CS0_BASE_ADDR,
+ .end = MX31_CS0_BASE_ADDR + SZ_128M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nor_mtd_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &qong_flash_data,
+ },
+ .resource = &qong_flash_resource,
+ .num_resources = 1,
+};
+
+static void qong_init_nor_mtd(void)
+{
+ (void)platform_device_register(&qong_nor_mtd_device);
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
+ else
+ writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int qong_nand_device_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+}
+
+static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ if (chip >= 0)
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+ else
+ gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
+}
+
+static struct platform_nand_data qong_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_delay = 20,
+ .options = 0,
+ },
+ .ctrl = {
+ .cmd_ctrl = qong_nand_cmd_ctrl,
+ .dev_ready = qong_nand_device_ready,
+ .select_chip = qong_nand_select_chip,
+ }
+};
+
+static struct resource qong_nand_resource = {
+ .start = MX31_CS3_BASE_ADDR,
+ .end = MX31_CS3_BASE_ADDR + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device qong_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &qong_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &qong_nand_resource,
+};
+
+static void __init qong_init_nand_mtd(void)
+{
+ /* init CS */
+ mx31_setup_weimcs(3, 0x00004f00, 0x20013b31, 0x00020800);
+ mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true);
+
+ /* enable pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable"))
+ gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
+
+ /* ready/busy pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB));
+
+ /* write protect pin */
+ mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO));
+ if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp"))
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B));
+
+ platform_device_register(&qong_nand_device);
+}
+
+static void __init qong_init_fpga(void)
+{
+ void __iomem *regs;
+ u32 fpga_ver;
+
+ regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE);
+ if (!regs) {
+ printk(KERN_ERR "%s: failed to map registers, aborting.\n",
+ __func__);
+ return;
+ }
+
+ fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION);
+ iounmap(regs);
+ printk(KERN_INFO "Qong FPGA version %d.%d.%d\n",
+ (fpga_ver & 0xF000) >> 12,
+ (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF);
+ if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) {
+ printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based "
+ "devices won't be registered!\n");
+ return;
+ }
+
+ /* register FPGA-based devices */
+ qong_init_nand_mtd();
+ qong_init_dnet();
+}
+
+/*
+ * Board specific initialization.
+ */
+static void __init qong_init(void)
+{
+ mxc_init_imx_uart();
+ qong_init_nor_mtd();
+ qong_init_fpga();
+}
+
+static void __init qong_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer qong_timer = {
+ .init = qong_timer_init,
+};
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+ /* Maintainer: DENX Software Engineering GmbH */
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx31_map_io,
+ .init_early = imx31_init_early,
+ .init_irq = mx31_init_irq,
+ .timer = &qong_timer,
+ .init_machine = qong_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
new file mode 100644
index 00000000..dcaee043
--- /dev/null
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -0,0 +1,155 @@
+/*
+ * linux/arch/arm/mach-mx1/mach-scb9328.c
+ *
+ * Copyright (c) 2004 Sascha Hauer <saschahauer@web.de>
+ * Copyright (c) 2006-2008 Juergen Beisert <jbeisert@netscape.net>
+ *
+ * This program is free software; you can 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/mtd/physmap.h>
+#include <linux/interrupt.h>
+#include <linux/dm9000.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx1.h>
+
+#include "devices-imx1.h"
+
+/*
+ * This scb9328 has a 32MiB flash
+ */
+static struct resource flash_resource = {
+ .start = MX1_CS0_PHYS,
+ .end = MX1_CS0_PHYS + (32 * 1024 * 1024) - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data scb_flash_data = {
+ .width = 2,
+};
+
+static struct platform_device scb_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &scb_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/*
+ * scb9328 has a DM9000 network controller
+ * connected to CS5, with 16 bit data path
+ * and interrupt connected to GPIO 3
+ */
+
+/*
+ * internal datapath is fixed 16 bit
+ */
+static struct dm9000_plat_data dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+/*
+ * the DM9000 drivers wants two defined address spaces
+ * to gain access to address latch registers and the data path.
+ */
+static struct resource dm9000x_resources[] = {
+ {
+ .name = "address area",
+ .start = MX1_CS5_PHYS,
+ .end = MX1_CS5_PHYS + 1,
+ .flags = IORESOURCE_MEM, /* address access */
+ }, {
+ .name = "data area",
+ .start = MX1_CS5_PHYS + 4,
+ .end = MX1_CS5_PHYS + 5,
+ .flags = IORESOURCE_MEM, /* data access */
+ }, {
+ .start = IRQ_GPIOC(3),
+ .end = IRQ_GPIOC(3),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct platform_device dm9000x_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000x_resources),
+ .resource = dm9000x_resources,
+ .dev = {
+ .platform_data = &dm9000_platdata,
+ }
+};
+
+static const int mxc_uart1_pins[] = {
+ PC9_PF_UART1_CTS,
+ PC10_PF_UART1_RTS,
+ PC11_PF_UART1_TXD,
+ PC12_PF_UART1_RXD,
+};
+
+static int uart1_mxc_init(struct platform_device *pdev)
+{
+ return mxc_gpio_setup_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins), "UART1");
+}
+
+static void uart1_mxc_exit(struct platform_device *pdev)
+{
+ mxc_gpio_release_multiple_pins(mxc_uart1_pins,
+ ARRAY_SIZE(mxc_uart1_pins));
+}
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .init = uart1_mxc_init,
+ .exit = uart1_mxc_exit,
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &scb_flash_device,
+ &dm9000x_device,
+};
+
+/*
+ * scb9328_init - Init the CPU card itself
+ */
+static void __init scb9328_init(void)
+{
+ imx1_add_imx_uart0(&uart_pdata);
+
+ printk(KERN_INFO"Scb9328: Adding devices\n");
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init scb9328_timer_init(void)
+{
+ mx1_clocks_init(32000);
+}
+
+static struct sys_timer scb9328_timer = {
+ .init = scb9328_timer_init,
+};
+
+MACHINE_START(SCB9328, "Synertronixx scb9328")
+ /* Sascha Hauer */
+ .boot_params = 0x08000100,
+ .map_io = mx1_map_io,
+ .init_early = imx1_init_early,
+ .init_irq = mx1_init_irq,
+ .timer = &scb9328_timer,
+ .init_machine = scb9328_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
new file mode 100644
index 00000000..d74e3473
--- /dev/null
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ * Copyright 2010 Creative Product Design
+ *
+ * Derived from mx35 3stack.
+ * Original author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mfd/mc13xxx.h>
+
+#include "devices-imx35.h"
+
+#define GPIO_LCDPWR IMX_GPIO_NR(1, 2)
+#define GPIO_PMIC_INT IMX_GPIO_NR(2, 0)
+
+#define GPIO_BUTTON1 IMX_GPIO_NR(1, 4)
+#define GPIO_BUTTON2 IMX_GPIO_NR(1, 5)
+#define GPIO_BUTTON3 IMX_GPIO_NR(1, 7)
+#define GPIO_BUTTON4 IMX_GPIO_NR(1, 8)
+#define GPIO_BUTTON5 IMX_GPIO_NR(1, 9)
+#define GPIO_BUTTON6 IMX_GPIO_NR(1, 10)
+#define GPIO_BUTTON7 IMX_GPIO_NR(1, 11)
+#define GPIO_BUTTON8 IMX_GPIO_NR(1, 12)
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ /* 800x480 @ 60 Hz */
+ .name = "PT0708048",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(33260),
+ .left_margin = 50,
+ .right_margin = 156,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 1, /* note: DE only display */
+ .vsync_len = 1, /* note: DE only display */
+ .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /* 800x480 @ 60 Hz */
+ .name = "CTP-CLAA070LC0ACW",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(27000),
+ .left_margin = 50,
+ .right_margin = 50, /* whole line should have 900 clocks */
+ .upper_margin = 10,
+ .lower_margin = 10, /* whole frame should have 500 lines */
+ .hsync_len = 1, /* note: DE only display */
+ .vsync_len = 1, /* note: DE only display */
+ .sync = FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+ .name = "PT0708048",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data vpr200_flash_data = {
+ .width = 2,
+};
+
+static struct resource vpr200_flash_resource = {
+ .start = MX35_CS0_BASE_ADDR,
+ .end = MX35_CS0_BASE_ADDR + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device vpr200_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &vpr200_flash_data,
+ },
+ .resource = &vpr200_flash_resource,
+ .num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data
+ vpr200_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+#define VPR_KEY_DEBOUNCE 500
+static struct gpio_keys_button vpr200_gpio_keys_table[] = {
+ {KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE},
+ {KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE},
+ {KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE},
+};
+
+static const struct gpio_keys_platform_data
+ vpr200_gpio_keys_data __initconst = {
+ .buttons = vpr200_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table),
+};
+
+static struct mc13xxx_platform_data vpr200_pmic = {
+ .flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN,
+};
+
+static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
+ .bitrate = 50000,
+};
+
+static struct at24_platform_data vpr200_eeprom = {
+ .byte_len = 2048 / 8,
+ .page_size = 1,
+};
+
+static struct i2c_board_info vpr200_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
+ .platform_data = &vpr200_eeprom,
+ }, {
+ I2C_BOARD_INFO("mc13892", 0x08),
+ .platform_data = &vpr200_pmic,
+ .irq = gpio_to_irq(GPIO_PMIC_INT),
+ }
+};
+
+static iomux_v3_cfg_t vpr200_pads[] = {
+ /* UART1 */
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* UART3 */
+ MX35_PAD_ATA_DATA10__UART3_RXD_MUX,
+ MX35_PAD_ATA_DATA11__UART3_TXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+ /* Display */
+ MX35_PAD_LD0__IPU_DISPB_DAT_0,
+ MX35_PAD_LD1__IPU_DISPB_DAT_1,
+ MX35_PAD_LD2__IPU_DISPB_DAT_2,
+ MX35_PAD_LD3__IPU_DISPB_DAT_3,
+ MX35_PAD_LD4__IPU_DISPB_DAT_4,
+ MX35_PAD_LD5__IPU_DISPB_DAT_5,
+ MX35_PAD_LD6__IPU_DISPB_DAT_6,
+ MX35_PAD_LD7__IPU_DISPB_DAT_7,
+ MX35_PAD_LD8__IPU_DISPB_DAT_8,
+ MX35_PAD_LD9__IPU_DISPB_DAT_9,
+ MX35_PAD_LD10__IPU_DISPB_DAT_10,
+ MX35_PAD_LD11__IPU_DISPB_DAT_11,
+ MX35_PAD_LD12__IPU_DISPB_DAT_12,
+ MX35_PAD_LD13__IPU_DISPB_DAT_13,
+ MX35_PAD_LD14__IPU_DISPB_DAT_14,
+ MX35_PAD_LD15__IPU_DISPB_DAT_15,
+ MX35_PAD_LD16__IPU_DISPB_DAT_16,
+ MX35_PAD_LD17__IPU_DISPB_DAT_17,
+ MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+ MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+ MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+ /* LCD Enable */
+ MX35_PAD_D3_VSYNC__GPIO1_2,
+ /* USBOTG */
+ MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+ MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+ /* SDCARD */
+ MX35_PAD_SD1_CMD__ESDHC1_CMD,
+ MX35_PAD_SD1_CLK__ESDHC1_CLK,
+ MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* PMIC */
+ MX35_PAD_GPIO2_0__GPIO2_0,
+ /* GPIO keys */
+ MX35_PAD_SCKR__GPIO1_4,
+ MX35_PAD_COMPARE__GPIO1_5,
+ MX35_PAD_SCKT__GPIO1_7,
+ MX35_PAD_FST__GPIO1_8,
+ MX35_PAD_HCKT__GPIO1_9,
+ MX35_PAD_TX5_RX0__GPIO1_10,
+ MX35_PAD_TX4_RX1__GPIO1_11,
+ MX35_PAD_TX3_RX2__GPIO1_12,
+};
+
+/* USB Device config */
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+ .workaround = FLS_USB2_WORKAROUND_ENGCM09152,
+};
+
+static int vpr200_usbh_init(struct platform_device *pdev)
+{
+ return mx35_initialize_usb_hw(pdev->id,
+ MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY);
+}
+
+/* USB HOST config */
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
+ .init = vpr200_usbh_init,
+ .portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &vpr200_flash,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init vpr200_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
+
+ imx35_add_fec(NULL);
+ imx35_add_imx2_wdt(NULL);
+ imx_add_gpio_keys(&vpr200_gpio_keys_data);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ if (0 != gpio_request(GPIO_LCDPWR, "LCDPWR"))
+ printk(KERN_WARNING "vpr200: Couldn't get LCDPWR gpio\n");
+ else
+ gpio_direction_output(GPIO_LCDPWR, 0);
+
+ if (0 != gpio_request(GPIO_PMIC_INT, "PMIC_INT"))
+ printk(KERN_WARNING "vpr200: Couldn't get PMIC_INT gpio\n");
+ else
+ gpio_direction_input(GPIO_PMIC_INT);
+
+ imx35_add_imx_uart0(NULL);
+ imx35_add_imx_uart2(NULL);
+
+ imx35_add_ipu_core(&mx3_ipu_data);
+ imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+ imx35_add_fsl_usb2_udc(&otg_device_pdata);
+ imx35_add_mxc_ehci_hs(&usb_host_pdata);
+
+ imx35_add_mxc_nand(&vpr200_nand_board_info);
+ imx35_add_sdhci_esdhc_imx(0, NULL);
+
+ i2c_register_board_info(0, vpr200_i2c_devices,
+ ARRAY_SIZE(vpr200_i2c_devices));
+
+ imx35_add_imx_i2c0(&vpr200_i2c0_data);
+}
+
+static void __init vpr200_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer vpr200_timer = {
+ .init = vpr200_timer_init,
+};
+
+MACHINE_START(VPR200, "VPR200")
+ /* Maintainer: Creative Product Design */
+ .map_io = mx35_map_io,
+ .init_early = imx35_init_early,
+ .init_irq = mx35_init_irq,
+ .timer = &vpr200_timer,
+ .init_machine = vpr200_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c
new file mode 100644
index 00000000..2e482ba5
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -0,0 +1,58 @@
+/*
+ * author: Sascha Hauer
+ * Created: april 20th, 2004
+ * Copyright: Synertronixx GmbH
+ *
+ * Common code for i.MX1 machines
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <mach/iomux-v1.h>
+
+static struct map_desc imx_io_desc[] __initdata = {
+ imx_map_entry(MX1, IO, MT_DEVICE),
+};
+
+void __init mx1_map_io(void)
+{
+ iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
+}
+
+void __init imx1_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX1);
+ mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
+ imx_iomuxv1_init(MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
+ MX1_NUM_GPIO_PORT);
+}
+
+static struct mxc_gpio_port imx1_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 0, 1, MX1_GPIO_INT_PORTA),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 1, 2, MX1_GPIO_INT_PORTB),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 2, 3, MX1_GPIO_INT_PORTC),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX1, 3, 4, MX1_GPIO_INT_PORTD),
+};
+
+void __init mx1_init_irq(void)
+{
+ mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx1_gpio_ports, ARRAY_SIZE(imx1_gpio_ports));
+}
diff --git a/arch/arm/mach-imx/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
new file mode 100644
index 00000000..7a0c500a
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-imx/mm-imx21.c
+ *
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <mach/iomux-v1.h>
+
+/* MX21 memory map definition */
+static struct map_desc imx21_io_desc[] __initdata = {
+ /*
+ * this fixed mapping covers:
+ * - AIPI1
+ * - AIPI2
+ * - AITC
+ * - ROM Patch
+ * - and some reserved space
+ */
+ imx_map_entry(MX21, AIPI, MT_DEVICE),
+ /*
+ * this fixed mapping covers:
+ * - CSI
+ * - ATA
+ */
+ imx_map_entry(MX21, SAHB1, MT_DEVICE),
+ /*
+ * this fixed mapping covers:
+ * - EMI
+ */
+ imx_map_entry(MX21, X_MEMC, MT_DEVICE),
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx21_map_io(void)
+{
+ iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc));
+}
+
+void __init imx21_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX21);
+ mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
+ imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR),
+ MX21_NUM_GPIO_PORT);
+}
+
+static struct mxc_gpio_port imx21_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX21, 0, 1, MX21_INT_GPIO),
+ DEFINE_IMX_GPIO_PORT(MX21, 1, 2),
+ DEFINE_IMX_GPIO_PORT(MX21, 2, 3),
+ DEFINE_IMX_GPIO_PORT(MX21, 3, 4),
+ DEFINE_IMX_GPIO_PORT(MX21, 4, 5),
+ DEFINE_IMX_GPIO_PORT(MX21, 5, 6),
+};
+
+void __init mx21_init_irq(void)
+{
+ mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
+}
diff --git a/arch/arm/mach-imx/mm-imx25.c b/arch/arm/mach-imx/mm-imx25.c
new file mode 100644
index 00000000..02f7b5c7
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx25.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 1999,2000 Arm Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * - add MX31 specific definitions
+ *
+ * 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.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mx25.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+/*
+ * This table defines static virtual address mappings for I/O regions.
+ * These are the mappings common across all MX25 boards.
+ */
+static struct map_desc mx25_io_desc[] __initdata = {
+ imx_map_entry(MX25, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX25, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX25, AIPS2, MT_DEVICE_NONSHARED),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx25_map_io(void)
+{
+ iotable_init(mx25_io_desc, ARRAY_SIZE(mx25_io_desc));
+}
+
+void __init imx25_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX25);
+ mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx25_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 0, 1, MX25_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 1, 2, MX25_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 2, 3, MX25_INT_GPIO3),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX25, 3, 4, MX25_INT_GPIO4),
+};
+
+void __init mx25_init_irq(void)
+{
+ mxc_init_irq(MX25_IO_ADDRESS(MX25_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx25_gpio_ports, ARRAY_SIZE(imx25_gpio_ports));
+}
+
diff --git a/arch/arm/mach-imx/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
new file mode 100644
index 00000000..a6761a39
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-imx/mm-imx27.c
+ *
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+#include <mach/iomux-v1.h>
+
+/* MX27 memory map definition */
+static struct map_desc imx27_io_desc[] __initdata = {
+ /*
+ * this fixed mapping covers:
+ * - AIPI1
+ * - AIPI2
+ * - AITC
+ * - ROM Patch
+ * - and some reserved space
+ */
+ imx_map_entry(MX27, AIPI, MT_DEVICE),
+ /*
+ * this fixed mapping covers:
+ * - CSI
+ * - ATA
+ */
+ imx_map_entry(MX27, SAHB1, MT_DEVICE),
+ /*
+ * this fixed mapping covers:
+ * - EMI
+ */
+ imx_map_entry(MX27, X_MEMC, MT_DEVICE),
+};
+
+/*
+ * Initialize the memory map. It is called during the
+ * system startup to create static physical to virtual
+ * memory map for the IO modules.
+ */
+void __init mx27_map_io(void)
+{
+ iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc));
+}
+
+void __init imx27_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX27);
+ mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
+ imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR),
+ MX27_NUM_GPIO_PORT);
+}
+
+static struct mxc_gpio_port imx27_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX27, 0, 1, MX27_INT_GPIO),
+ DEFINE_IMX_GPIO_PORT(MX27, 1, 2),
+ DEFINE_IMX_GPIO_PORT(MX27, 2, 3),
+ DEFINE_IMX_GPIO_PORT(MX27, 3, 4),
+ DEFINE_IMX_GPIO_PORT(MX27, 4, 5),
+ DEFINE_IMX_GPIO_PORT(MX27, 5, 6),
+};
+
+void __init mx27_init_irq(void)
+{
+ mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
+}
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
new file mode 100644
index 00000000..86b9b458
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1999,2000 Arm Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * - add MX31 specific definitions
+ *
+ * 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.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+static struct map_desc mx31_io_desc[] __initdata = {
+ imx_map_entry(MX31, X_MEMC, MT_DEVICE),
+ imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx31_map_io(void)
+{
+ iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
+}
+
+void __init imx31_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX31);
+ mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx31_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
+};
+
+void __init mx31_init_irq(void)
+{
+ mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx31_gpio_ports, ARRAY_SIZE(imx31_gpio_ports));
+}
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
new file mode 100644
index 00000000..c880e6d1
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999,2000 Arm Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * - add MX31 specific definitions
+ *
+ * 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.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+static struct map_desc mx35_io_desc[] __initdata = {
+ imx_map_entry(MX35, X_MEMC, MT_DEVICE),
+ imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
+ imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+void __init mx35_map_io(void)
+{
+ iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
+}
+
+void __init imx35_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX35);
+ mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx35_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
+ DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
+};
+
+void __init mx35_init_irq(void)
+{
+ mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+ mxc_gpio_init(imx35_gpio_ports, ARRAY_SIZE(imx35_gpio_ports));
+}
diff --git a/arch/arm/mach-imx/mx1-camera-fiq-ksym.c b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
new file mode 100644
index 00000000..b09ee12a
--- /dev/null
+++ b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
@@ -0,0 +1,18 @@
+/*
+ * Exported ksyms of ARCH_MX1
+ *
+ * Copyright (C) 2008, Darius Augulis <augulis.darius@gmail.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/module.h>
+
+#include <mach/mx1_camera.h>
+
+/* IMX camera FIQ handler */
+EXPORT_SYMBOL(mx1_camera_sof_fiq_start);
+EXPORT_SYMBOL(mx1_camera_sof_fiq_end);
diff --git a/arch/arm/mach-imx/mx1-camera-fiq.S b/arch/arm/mach-imx/mx1-camera-fiq.S
new file mode 100644
index 00000000..9c69aa65
--- /dev/null
+++ b/arch/arm/mach-imx/mx1-camera-fiq.S
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on linux/arch/arm/lib/floppydma.S
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .global mx1_camera_sof_fiq_end
+ .global mx1_camera_sof_fiq_start
+mx1_camera_sof_fiq_start:
+ @ enable dma
+ ldr r12, [r9]
+ orr r12, r12, #0x00000001
+ str r12, [r9]
+ @ unmask DMA interrupt
+ ldr r12, [r8]
+ bic r12, r12, r13
+ str r12, [r8]
+ @ disable SOF interrupt
+ ldr r12, [r10]
+ bic r12, r12, #0x00010000
+ str r12, [r10]
+ @ clear SOF flag
+ mov r12, #0x00010000
+ str r12, [r11]
+ @ return from FIQ
+ subs pc, lr, #4
+mx1_camera_sof_fiq_end:
diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c
new file mode 100644
index 00000000..7d26f766
--- /dev/null
+++ b/arch/arm/mach-imx/mx31lilly-db.c
@@ -0,0 +1,216 @@
+/*
+ * LILLY-1131 development board support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LILLY-1131 development board. If you design an own baseboard for the
+ * module, use this file as base for support code.
+ */
+
+static unsigned int lilly_db_board_pins[] __initdata = {
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ MX31_PIN_CTS2__CTS2,
+ MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2,
+ MX31_PIN_RXD2__RXD2,
+ MX31_PIN_CSPI3_MOSI__RXD3,
+ MX31_PIN_CSPI3_MISO__TXD3,
+ MX31_PIN_CSPI3_SCLK__RTS3,
+ MX31_PIN_CSPI3_SPI_RDY__CTS3,
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+ MX31_PIN_LD0__LD0,
+ MX31_PIN_LD1__LD1,
+ MX31_PIN_LD2__LD2,
+ MX31_PIN_LD3__LD3,
+ MX31_PIN_LD4__LD4,
+ MX31_PIN_LD5__LD5,
+ MX31_PIN_LD6__LD6,
+ MX31_PIN_LD7__LD7,
+ MX31_PIN_LD8__LD8,
+ MX31_PIN_LD9__LD9,
+ MX31_PIN_LD10__LD10,
+ MX31_PIN_LD11__LD11,
+ MX31_PIN_LD12__LD12,
+ MX31_PIN_LD13__LD13,
+ MX31_PIN_LD14__LD14,
+ MX31_PIN_LD15__LD15,
+ MX31_PIN_LD16__LD16,
+ MX31_PIN_LD17__LD17,
+ MX31_PIN_VSYNC3__VSYNC3,
+ MX31_PIN_HSYNC__HSYNC,
+ MX31_PIN_FPSHIFT__FPSHIFT,
+ MX31_PIN_DRDY0__DRDY0,
+ MX31_PIN_CONTRAST__CONTRAST,
+};
+
+/* UART */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC support */
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+}
+
+static int gpio_det, gpio_wp;
+
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int mxc_mmc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
+
+ ret = gpio_request(gpio_det, "MMC detect");
+ if (ret)
+ return ret;
+
+ ret = gpio_request(gpio_wp, "MMC w/p");
+ if (ret)
+ goto exit_free_det;
+
+ gpio_direction_input(gpio_det);
+ gpio_direction_input(gpio_wp);
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "MMC detect", data);
+ if (ret)
+ goto exit_free_wp;
+
+ return 0;
+
+exit_free_wp:
+ gpio_free(gpio_wp);
+
+exit_free_det:
+ gpio_free(gpio_det);
+
+ return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+ gpio_free(gpio_det);
+ gpio_free(gpio_wp);
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+}
+
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
+ .get_ro = mxc_mmc1_get_ro,
+ .init = mxc_mmc1_init,
+ .exit = mxc_mmc1_exit,
+};
+
+/* Framebuffer support */
+static const struct ipu_platform_data ipu_data __initconst = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb = {
+ /* 640x480 TFT panel (IPS-056T) */
+ .name = "CRT-VGA",
+ .refresh = 64,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 30000,
+ .left_margin = 200,
+ .right_margin = 2,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct mx3fb_platform_data fb_pdata __initdata = {
+ .name = "CRT-VGA",
+ .mode = &fb_modedb,
+ .num_modes = 1,
+};
+
+#define LCD_VCC_EN_GPIO (7)
+
+static void __init mx31lilly_init_fb(void)
+{
+ if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) {
+ printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n");
+ return;
+ }
+
+ imx31_add_ipu_core(&ipu_data);
+ imx31_add_mx3_sdc_fb(&fb_pdata);
+ gpio_direction_output(LCD_VCC_EN_GPIO, 1);
+}
+
+void __init mx31lilly_db_init(void)
+{
+ mxc_iomux_setup_multiple_pins(lilly_db_board_pins,
+ ARRAY_SIZE(lilly_db_board_pins),
+ "development board pins");
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
+ imx31_add_imx_uart2(&uart_pdata);
+ imx31_add_mxc_mmc(0, &mmc_pdata);
+ mx31lilly_init_fb();
+}
diff --git a/arch/arm/mach-imx/mx31lite-db.c b/arch/arm/mach-imx/mx31lite-db.c
new file mode 100644
index 00000000..5aa053ed
--- /dev/null
+++ b/arch/arm/mach-imx/mx31lite-db.c
@@ -0,0 +1,203 @@
+/*
+ * LogicPD i.MX31 SOM-LV development board support
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * based on code for other MX31 boards,
+ *
+ * Copyright 2005-2007 Freescale Semiconductor
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lite.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'.
+ * If you design an own baseboard for the module, use this file as base
+ * for support code.
+ */
+
+static unsigned int litekit_db_board_pins[] __initdata = {
+ /* UART1 */
+ MX31_PIN_CTS1__CTS1,
+ MX31_PIN_RTS1__RTS1,
+ MX31_PIN_TXD1__TXD1,
+ MX31_PIN_RXD1__RXD1,
+ /* SPI 0 */
+ MX31_PIN_CSPI1_SCLK__SCLK,
+ MX31_PIN_CSPI1_MOSI__MOSI,
+ MX31_PIN_CSPI1_MISO__MISO,
+ MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+ MX31_PIN_CSPI1_SS0__SS0,
+ MX31_PIN_CSPI1_SS1__SS1,
+ MX31_PIN_CSPI1_SS2__SS2,
+ /* SDHC1 */
+ MX31_PIN_SD1_DATA0__SD1_DATA0,
+ MX31_PIN_SD1_DATA1__SD1_DATA1,
+ MX31_PIN_SD1_DATA2__SD1_DATA2,
+ MX31_PIN_SD1_DATA3__SD1_DATA3,
+ MX31_PIN_SD1_CLK__SD1_CLK,
+ MX31_PIN_SD1_CMD__SD1_CMD,
+};
+
+/* UART */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC */
+
+static int gpio_det, gpio_wp;
+
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS)
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+ return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6));
+}
+
+static int mxc_mmc1_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
+ gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
+
+ ret = gpio_request(gpio_det, "MMC detect");
+ if (ret)
+ return ret;
+
+ ret = gpio_request(gpio_wp, "MMC w/p");
+ if (ret)
+ goto exit_free_det;
+
+ gpio_direction_input(gpio_det);
+ gpio_direction_input(gpio_wp);
+
+ ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "MMC detect", data);
+ if (ret)
+ goto exit_free_wp;
+
+ return 0;
+
+exit_free_wp:
+ gpio_free(gpio_wp);
+
+exit_free_det:
+ gpio_free(gpio_det);
+
+ return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+ gpio_free(gpio_det);
+ gpio_free(gpio_wp);
+ free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
+}
+
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
+ .get_ro = mxc_mmc1_get_ro,
+ .init = mxc_mmc1_init,
+ .exit = mxc_mmc1_exit,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+ MXC_SPI_CS(0),
+ MXC_SPI_CS(1),
+ MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+ .chipselect = spi_internal_chipselect,
+ .num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+/* GPIO LEDs */
+
+static struct gpio_led litekit_leds[] = {
+ {
+ .name = "GPIO0",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_COMPARE),
+ .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ },
+ {
+ .name = "GPIO1",
+ .gpio = IOMUX_TO_GPIO(MX31_PIN_CAPTURE),
+ .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ }
+};
+
+static struct gpio_led_platform_data litekit_led_platform_data = {
+ .leds = litekit_leds,
+ .num_leds = ARRAY_SIZE(litekit_leds),
+};
+
+static struct platform_device litekit_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &litekit_led_platform_data,
+ },
+};
+
+void __init mx31lite_db_init(void)
+{
+ mxc_iomux_setup_multiple_pins(litekit_db_board_pins,
+ ARRAY_SIZE(litekit_db_board_pins),
+ "development board pins");
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_mxc_mmc(0, &mmc_pdata);
+ imx31_add_spi_imx0(&spi0_pdata);
+ platform_device_register(&litekit_led_device);
+ imx31_add_imx2_wdt(NULL);
+ imx31_add_mxc_rtc(NULL);
+}
diff --git a/arch/arm/mach-imx/mx31moboard-devboard.c b/arch/arm/mach-imx/mx31moboard-devboard.c
new file mode 100644
index 00000000..0aa25364
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-devboard.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/hardware.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+static unsigned int devboard_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+ /* SDHC2 */
+ MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
+ MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
+ MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
+ MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
+ /* USB H1 */
+ MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+ MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+ MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+ MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+ MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+ /* SEL */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
+#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
+
+static int devboard_sdhc2_get_ro(struct device *dev)
+{
+ return !gpio_get_value(SDHC2_WP);
+}
+
+static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC2_CD, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC2_CD);
+
+ ret = gpio_request(SDHC2_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC2_WP);
+
+ ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "sdhc2-card-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(SDHC2_WP);
+err_gpio_free:
+ gpio_free(SDHC2_CD);
+
+ return ret;
+}
+
+static void devboard_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(SDHC2_CD), data);
+ gpio_free(SDHC2_WP);
+ gpio_free(SDHC2_CD);
+}
+
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
+ .get_ro = devboard_sdhc2_get_ro,
+ .init = devboard_sdhc2_init,
+ .exit = devboard_sdhc2_exit,
+};
+
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void devboard_init_sel_gpios(void)
+{
+ if (!gpio_request(SEL0, "sel0")) {
+ gpio_direction_input(SEL0);
+ gpio_export(SEL0, true);
+ }
+
+ if (!gpio_request(SEL1, "sel1")) {
+ gpio_direction_input(SEL1);
+ gpio_export(SEL1, true);
+ }
+
+ if (!gpio_request(SEL2, "sel2")) {
+ gpio_direction_input(SEL2);
+ gpio_export(SEL2, true);
+ }
+
+ if (!gpio_request(SEL3, "sel3")) {
+ gpio_direction_input(SEL3);
+ gpio_export(SEL3, true);
+ }
+}
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int devboard_usbh1_hw_init(struct platform_device *pdev)
+{
+ mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int devboard_isp1105_init(struct otg_transceiver *otg)
+{
+ int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+ if (ret)
+ return ret;
+ /* single ended */
+ gpio_direction_output(USBH1_MODE, 0);
+
+ ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+ if (ret) {
+ gpio_free(USBH1_MODE);
+ return ret;
+ }
+ gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+ return 0;
+}
+
+
+static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+ if (on)
+ gpio_set_value(USBH1_VBUSEN_B, 0);
+ else
+ gpio_set_value(USBH1_VBUSEN_B, 1);
+
+ return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
+ .init = devboard_usbh1_hw_init,
+ .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static int __init devboard_usbh1_init(void)
+{
+ struct otg_transceiver *otg;
+ struct platform_device *pdev;
+
+ otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+ if (!otg)
+ return -ENOMEM;
+
+ otg->label = "ISP1105";
+ otg->init = devboard_isp1105_init;
+ otg->set_vbus = devboard_isp1105_set_vbus;
+
+ usbh1_pdata.otg = otg;
+
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_devboard_init(void)
+{
+ printk(KERN_INFO "Initializing mx31devboard peripherals\n");
+
+ mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins),
+ "devboard");
+
+ imx31_add_imx_uart1(&uart_pdata);
+
+ imx31_add_mxc_mmc(1, &sdhc2_pdata);
+
+ devboard_init_sel_gpios();
+
+ imx31_add_fsl_usb2_udc(&usb_pdata);
+
+ devboard_usbh1_init();
+}
diff --git a/arch/arm/mach-imx/mx31moboard-marxbot.c b/arch/arm/mach-imx/mx31moboard-marxbot.c
new file mode 100644
index 00000000..bb639cbd
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-marxbot.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include <media/soc_camera.h>
+
+#include "devices-imx31.h"
+
+static unsigned int marxbot_pins[] = {
+ /* SDHC2 */
+ MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
+ MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
+ MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
+ MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
+ /* CSI */
+ MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ MX31_PIN_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5,
+ MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
+ MX31_PIN_TXD2__GPIO1_28,
+ /* dsPIC resets */
+ MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
+ /*battery detection */
+ MX31_PIN_LCS0__GPIO3_23,
+ /* USB H1 */
+ MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+ MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+ MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+ MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+ MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+ /* SEL */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+};
+
+#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
+#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
+
+static int marxbot_sdhc2_get_ro(struct device *dev)
+{
+ return !gpio_get_value(SDHC2_WP);
+}
+
+static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+ void *data)
+{
+ int ret;
+
+ ret = gpio_request(SDHC2_CD, "sdhc-detect");
+ if (ret)
+ return ret;
+
+ gpio_direction_input(SDHC2_CD);
+
+ ret = gpio_request(SDHC2_WP, "sdhc-wp");
+ if (ret)
+ goto err_gpio_free;
+ gpio_direction_input(SDHC2_WP);
+
+ ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "sdhc2-card-detect", data);
+ if (ret)
+ goto err_gpio_free_2;
+
+ return 0;
+
+err_gpio_free_2:
+ gpio_free(SDHC2_WP);
+err_gpio_free:
+ gpio_free(SDHC2_CD);
+
+ return ret;
+}
+
+static void marxbot_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(SDHC2_CD), data);
+ gpio_free(SDHC2_WP);
+ gpio_free(SDHC2_CD);
+}
+
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
+ .get_ro = marxbot_sdhc2_get_ro,
+ .init = marxbot_sdhc2_init,
+ .exit = marxbot_sdhc2_exit,
+};
+
+#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_STXD5)
+#define DSPICS_RST_B IOMUX_TO_GPIO(MX31_PIN_SRXD5)
+
+static void dspics_resets_init(void)
+{
+ if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+ gpio_direction_output(TRSLAT_RST_B, 0);
+ gpio_export(TRSLAT_RST_B, false);
+ }
+
+ if (!gpio_request(DSPICS_RST_B, "dspics-rst")) {
+ gpio_direction_output(DSPICS_RST_B, 0);
+ gpio_export(DSPICS_RST_B, false);
+ }
+}
+
+static struct spi_board_info marxbot_spi_board_info[] __initdata = {
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 300000,
+ .bus_num = 1,
+ .chip_select = 1, /* according spi1_cs[] ! */
+ },
+};
+
+#define TURRETCAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define BASECAM_POWER IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
+#define TURRETCAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+#define BASECAM_RST_B IOMUX_TO_GPIO(MX31_PIN_CSI_D4)
+#define CAM_CHOICE IOMUX_TO_GPIO(MX31_PIN_TXD2)
+
+static int marxbot_basecam_power(struct device *dev, int on)
+{
+ gpio_set_value(BASECAM_POWER, !on);
+ return 0;
+}
+
+static int marxbot_basecam_reset(struct device *dev)
+{
+ gpio_set_value(BASECAM_RST_B, 0);
+ udelay(100);
+ gpio_set_value(BASECAM_RST_B, 1);
+ return 0;
+}
+
+static struct i2c_board_info marxbot_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ },
+};
+
+static struct soc_camera_link base_iclink = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = marxbot_basecam_power,
+ .reset = marxbot_basecam_reset,
+ .board_info = &marxbot_i2c_devices[0],
+ .i2c_adapter_id = 0,
+};
+
+static struct platform_device marxbot_camera[] = {
+ {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &base_iclink,
+ },
+ },
+};
+
+static struct platform_device *marxbot_cameras[] __initdata = {
+ &marxbot_camera[0],
+};
+
+static int __init marxbot_cam_init(void)
+{
+ int ret = gpio_request(CAM_CHOICE, "cam-choice");
+ if (ret)
+ return ret;
+ gpio_direction_output(CAM_CHOICE, 0);
+
+ ret = gpio_request(BASECAM_RST_B, "basecam-reset");
+ if (ret)
+ return ret;
+ gpio_direction_output(BASECAM_RST_B, 1);
+ ret = gpio_request(BASECAM_POWER, "basecam-standby");
+ if (ret)
+ return ret;
+ gpio_direction_output(BASECAM_POWER, 0);
+
+ ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset");
+ if (ret)
+ return ret;
+ gpio_direction_output(TURRETCAM_RST_B, 1);
+ ret = gpio_request(TURRETCAM_POWER, "turretcam-standby");
+ if (ret)
+ return ret;
+ gpio_direction_output(TURRETCAM_POWER, 0);
+
+ return 0;
+}
+
+#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void marxbot_init_sel_gpios(void)
+{
+ if (!gpio_request(SEL0, "sel0")) {
+ gpio_direction_input(SEL0);
+ gpio_export(SEL0, true);
+ }
+
+ if (!gpio_request(SEL1, "sel1")) {
+ gpio_direction_input(SEL1);
+ gpio_export(SEL1, true);
+ }
+
+ if (!gpio_request(SEL2, "sel2")) {
+ gpio_direction_input(SEL2);
+ gpio_export(SEL2, true);
+ }
+
+ if (!gpio_request(SEL3, "sel3")) {
+ gpio_direction_input(SEL3);
+ gpio_export(SEL3, true);
+ }
+}
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+ PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int marxbot_usbh1_hw_init(struct platform_device *pdev)
+{
+ mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+ mdelay(10);
+
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+#define USBH1_VBUSEN_B IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int marxbot_isp1105_init(struct otg_transceiver *otg)
+{
+ int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+ if (ret)
+ return ret;
+ /* single ended */
+ gpio_direction_output(USBH1_MODE, 0);
+
+ ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+ if (ret) {
+ gpio_free(USBH1_MODE);
+ return ret;
+ }
+ gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+ return 0;
+}
+
+
+static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+ if (on)
+ gpio_set_value(USBH1_VBUSEN_B, 0);
+ else
+ gpio_set_value(USBH1_VBUSEN_B, 1);
+
+ return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
+ .init = marxbot_usbh1_hw_init,
+ .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static int __init marxbot_usbh1_init(void)
+{
+ struct otg_transceiver *otg;
+ struct platform_device *pdev;
+
+ otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+ if (!otg)
+ return -ENOMEM;
+
+ otg->label = "ISP1105";
+ otg->init = marxbot_isp1105_init;
+ otg->set_vbus = marxbot_isp1105_set_vbus;
+
+ usbh1_pdata.otg = otg;
+
+ pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_marxbot_init(void)
+{
+ printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
+
+ mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
+ "marxbot");
+
+ marxbot_init_sel_gpios();
+
+ dspics_resets_init();
+
+ imx31_add_mxc_mmc(1, &sdhc2_pdata);
+
+ spi_register_board_info(marxbot_spi_board_info,
+ ARRAY_SIZE(marxbot_spi_board_info));
+
+ marxbot_cam_init();
+ platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras));
+
+ /* battery present pin */
+ gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present");
+ gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+ gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
+
+ imx31_add_fsl_usb2_udc(&usb_pdata);
+
+ marxbot_usbh1_init();
+}
diff --git a/arch/arm/mach-imx/mx31moboard-smartbot.c b/arch/arm/mach-imx/mx31moboard-smartbot.c
new file mode 100644
index 00000000..fabb801e
--- /dev/null
+++ b/arch/arm/mach-imx/mx31moboard-smartbot.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
+#include <mach/ulpi.h>
+
+#include <media/soc_camera.h>
+
+#include "devices-imx31.h"
+
+static unsigned int smartbot_pins[] = {
+ /* UART1 */
+ MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+ MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+ /* CSI */
+ MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5,
+ MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7,
+ MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9,
+ MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11,
+ MX31_PIN_CSI_D12__CSI_D12, MX31_PIN_CSI_D13__CSI_D13,
+ MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15,
+ MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK,
+ MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC,
+ MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
+ /* ENABLES */
+ MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
+ MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define CAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define CAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+
+static int smartbot_cam_power(struct device *dev, int on)
+{
+ gpio_set_value(CAM_POWER, !on);
+ return 0;
+}
+
+static int smartbot_cam_reset(struct device *dev)
+{
+ gpio_set_value(CAM_RST_B, 0);
+ udelay(100);
+ gpio_set_value(CAM_RST_B, 1);
+ return 0;
+}
+
+static struct i2c_board_info smartbot_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("mt9t031", 0x5d),
+ },
+};
+
+static struct soc_camera_link base_iclink = {
+ .bus_id = 0, /* Must match with the camera ID */
+ .power = smartbot_cam_power,
+ .reset = smartbot_cam_reset,
+ .board_info = &smartbot_i2c_devices[0],
+ .i2c_adapter_id = 0,
+};
+
+static struct platform_device smartbot_camera[] = {
+ {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &base_iclink,
+ },
+ },
+};
+
+static struct platform_device *smartbot_cameras[] __initdata = {
+ &smartbot_camera[0],
+};
+
+static int __init smartbot_cam_init(void)
+{
+ int ret = gpio_request(CAM_RST_B, "cam-reset");
+ if (ret)
+ return ret;
+ gpio_direction_output(CAM_RST_B, 1);
+ ret = gpio_request(CAM_POWER, "cam-standby");
+ if (ret)
+ return ret;
+ gpio_direction_output(CAM_POWER, 0);
+
+ return 0;
+}
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+#if defined(CONFIG_USB_ULPI)
+
+static int smartbot_otg_init(struct platform_device *pdev)
+{
+ return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data otg_host_pdata __initdata = {
+ .init = smartbot_otg_init,
+ .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static int __init smartbot_otg_host_init(void)
+{
+ struct platform_device *pdev;
+
+ otg_host_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT);
+ if (!otg_host_pdata.otg)
+ return -ENODEV;
+
+ pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+#else
+static inline int smartbot_otg_host_init(void) { return 0; }
+#endif
+
+#define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
+#define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
+#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
+#define TRSLAT_SRC_CHOICE IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+
+static void smartbot_resets_init(void)
+{
+ if (!gpio_request(POWER_EN, "power-enable")) {
+ gpio_direction_output(POWER_EN, 0);
+ gpio_export(POWER_EN, false);
+ }
+
+ if (!gpio_request(DSPIC_RST_B, "dspic-rst")) {
+ gpio_direction_output(DSPIC_RST_B, 0);
+ gpio_export(DSPIC_RST_B, false);
+ }
+
+ if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+ gpio_direction_output(TRSLAT_RST_B, 0);
+ gpio_export(TRSLAT_RST_B, false);
+ }
+
+ if (!gpio_request(TRSLAT_SRC_CHOICE, "translator-src-choice")) {
+ gpio_direction_output(TRSLAT_SRC_CHOICE, 0);
+ gpio_export(TRSLAT_SRC_CHOICE, false);
+ }
+}
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_smartbot_init(int board)
+{
+ printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
+
+ mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
+ "smartbot");
+
+ imx31_add_imx_uart1(&uart_pdata);
+
+ switch (board) {
+ case MX31SMARTBOT:
+ imx31_add_fsl_usb2_udc(&usb_pdata);
+ break;
+ case MX31EYEBOT:
+ smartbot_otg_host_init();
+ break;
+ default:
+ printk(KERN_WARNING "Unknown board %d, USB OTG not initialized",
+ board);
+ }
+
+ smartbot_resets_init();
+
+ smartbot_cam_init();
+ platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras));
+}
diff --git a/arch/arm/mach-imx/pcm037.h b/arch/arm/mach-imx/pcm037.h
new file mode 100644
index 00000000..d6929721
--- /dev/null
+++ b/arch/arm/mach-imx/pcm037.h
@@ -0,0 +1,11 @@
+#ifndef __PCM037_H__
+#define __PCM037_H__
+
+enum pcm037_board_variant {
+ PCM037_PCM970,
+ PCM037_EET,
+};
+
+extern enum pcm037_board_variant pcm037_variant(void);
+
+#endif
diff --git a/arch/arm/mach-imx/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
new file mode 100644
index 00000000..99afbc3f
--- /dev/null
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/can/platform/sja1000.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx27.h>
+#include <mach/hardware.h>
+
+#include "devices-imx27.h"
+
+static const int pcm970_pins[] __initconst = {
+ /* SDHC */
+ PB4_PF_SD2_D0,
+ PB5_PF_SD2_D1,
+ PB6_PF_SD2_D2,
+ PB7_PF_SD2_D3,
+ PB8_PF_SD2_CMD,
+ PB9_PF_SD2_CLK,
+ /* display */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA24_PF_REV,
+ PA25_PF_CLS,
+ PA26_PF_PS,
+ PA27_PF_SPL_SPR,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA30_PF_CONTRAST,
+ PA31_PF_OE_ACD,
+ /*
+ * it seems the data line misses a pullup, so we must enable
+ * the internal pullup as a local workaround
+ */
+ PD17_PF_I2C_DATA | GPIO_PUEN,
+ PD18_PF_I2C_CLK,
+ /* Camera */
+ PB10_PF_CSI_D0,
+ PB11_PF_CSI_D1,
+ PB12_PF_CSI_D2,
+ PB13_PF_CSI_D3,
+ PB14_PF_CSI_D4,
+ PB15_PF_CSI_MCLK,
+ PB16_PF_CSI_PIXCLK,
+ PB17_PF_CSI_D5,
+ PB18_PF_CSI_D6,
+ PB19_PF_CSI_D7,
+ PB20_PF_CSI_VSYNC,
+ PB21_PF_CSI_HSYNC,
+};
+
+static int pcm970_sdhc2_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO_PORTC + 28);
+}
+
+static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
+{
+ int ret;
+
+ ret = request_irq(IRQ_GPIOC(29), detect_irq, IRQF_TRIGGER_FALLING,
+ "imx-mmc-detect", data);
+ if (ret)
+ return ret;
+
+ ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
+ if (ret) {
+ free_irq(IRQ_GPIOC(29), data);
+ return ret;
+ }
+
+ gpio_direction_input(GPIO_PORTC + 28);
+
+ return 0;
+}
+
+static void pcm970_sdhc2_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIOC(29), data);
+ gpio_free(GPIO_PORTC + 28);
+}
+
+static const struct imxmmc_platform_data sdhc_pdata __initconst = {
+ .get_ro = pcm970_sdhc2_get_ro,
+ .init = pcm970_sdhc2_init,
+ .exit = pcm970_sdhc2_exit,
+};
+
+static struct imx_fb_videomode pcm970_modes[] = {
+ {
+ .mode = {
+ .name = "Sharp-LQ035Q7",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 188679, /* in ps (5.3MHz) */
+ .hsync_len = 7,
+ .left_margin = 5,
+ .right_margin = 16,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 9,
+ },
+ /*
+ * - HSYNC active high
+ * - VSYNC active high
+ * - clk notenabled while idle
+ * - clock not inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pcr = 0xF00080C0,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "TX090",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 38255,
+ .left_margin = 144,
+ .right_margin = 0,
+ .upper_margin = 7,
+ .lower_margin = 40,
+ .hsync_len = 96,
+ .vsync_len = 1,
+ },
+ /*
+ * - HSYNC active low (1 << 22)
+ * - VSYNC active low (1 << 23)
+ * - clk notenabled while idle
+ * - clock not inverted
+ * - data not inverted
+ * - data enable low active
+ * - enable sharp mode
+ */
+ .pcr = 0xF0008080 | (1<<22) | (1<<23) | (1<<19),
+ .bpp = 32,
+ },
+};
+
+static const struct imx_fb_platform_data pcm038_fb_data __initconst = {
+ .mode = pcm970_modes,
+ .num_modes = ARRAY_SIZE(pcm970_modes),
+
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
+static struct resource pcm970_sja1000_resources[] = {
+ {
+ .start = MX27_CS4_BASE_ADDR,
+ .end = MX27_CS4_BASE_ADDR + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_GPIOE(19),
+ .end = IRQ_GPIOE(19),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct sja1000_platform_data pcm970_sja1000_platform_data = {
+ .osc_freq = 16000000,
+ .ocr = OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
+ .cdr = CDR_CBP,
+};
+
+static struct platform_device pcm970_sja1000 = {
+ .name = "sja1000_platform",
+ .dev = {
+ .platform_data = &pcm970_sja1000_platform_data,
+ },
+ .resource = pcm970_sja1000_resources,
+ .num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
+};
+
+/*
+ * system init for baseboard usage. Will be called by pcm038 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init pcm970_baseboard_init(void)
+{
+ mxc_gpio_setup_multiple_pins(pcm970_pins, ARRAY_SIZE(pcm970_pins),
+ "PCM970");
+
+ imx27_add_imx_fb(&pcm038_fb_data);
+ mxc_gpio_mode(GPIO_PORTC | 28 | GPIO_GPIO | GPIO_IN);
+ imx27_add_mxc_mmc(1, &sdhc_pdata);
+ platform_device_register(&pcm970_sja1000);
+}
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
new file mode 100644
index 00000000..acf17691
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -0,0 +1,49 @@
+/*
+ * i.MX27 Power Management Routines
+ *
+ * Based on Freescale's BSP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+#include <mach/mx27.h>
+
+static int mx27_suspend_enter(suspend_state_t state)
+{
+ u32 cscr;
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ /* Clear MPEN and SPEN to disable MPLL/SPLL */
+ cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
+ cscr &= 0xFFFFFFFC;
+ __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
+ /* Executes WFI */
+ arch_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct platform_suspend_ops mx27_suspend_ops = {
+ .enter = mx27_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init mx27_pm_init(void)
+{
+ if (!cpu_is_mx27())
+ return 0;
+
+ suspend_set_ops(&mx27_suspend_ops);
+ return 0;
+}
+
+device_initcall(mx27_pm_init);
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
new file mode 100644
index 00000000..dfd18f3b
--- /dev/null
+++ b/arch/arm/mach-integrator/Kconfig
@@ -0,0 +1,37 @@
+if ARCH_INTEGRATOR
+
+menu "Integrator Options"
+
+config ARCH_INTEGRATOR_AP
+ bool "Support Integrator/AP and Integrator/PP2 platforms"
+ select CLKSRC_MMIO
+ select MIGHT_HAVE_PCI
+ help
+ Include support for the ARM(R) Integrator/AP and
+ Integrator/PP2 platforms.
+
+config ARCH_INTEGRATOR_CP
+ bool "Support Integrator/CP platform"
+ select ARCH_CINTEGRATOR
+ select ARM_TIMER_SP804
+ select PLAT_VERSATILE_CLCD
+ help
+ Include support for the ARM(R) Integrator CP platform.
+
+config ARCH_CINTEGRATOR
+ bool
+
+config INTEGRATOR_IMPD1
+ tristate "Include support for Integrator/IM-PD1"
+ depends on ARCH_INTEGRATOR_AP
+ help
+ The IM-PD1 is an add-on logic module for the Integrator which
+ allows ARM(R) Ltd PrimeCells to be developed and evaluated.
+ The IM-PD1 can be found on the Integrator/PP2 platform.
+
+ To compile this driver as a module, choose M here: the
+ module will be called impd1.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
new file mode 100644
index 00000000..ebeef966
--- /dev/null
+++ b/arch/arm/mach-integrator/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := core.o lm.o
+obj-$(CONFIG_ARCH_INTEGRATOR_AP) += integrator_ap.o
+obj-$(CONFIG_ARCH_INTEGRATOR_CP) += integrator_cp.o
+
+obj-$(CONFIG_LEDS) += leds.o
+obj-$(CONFIG_PCI) += pci_v3.o pci.o
+obj-$(CONFIG_CPU_FREQ_INTEGRATOR) += cpu.o
+obj-$(CONFIG_INTEGRATOR_IMPD1) += impd1.o
diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot
new file mode 100644
index 00000000..c7e75acf
--- /dev/null
+++ b/arch/arm/mach-integrator/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
new file mode 100644
index 00000000..a08f9b02
--- /dev/null
+++ b/arch/arm/mach-integrator/common.h
@@ -0,0 +1,2 @@
+void integrator_init_early(void);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
new file mode 100644
index 00000000..77315b99
--- /dev/null
+++ b/arch/arm/mach-integrator/core.c
@@ -0,0 +1,236 @@
+/*
+ * linux/arch/arm/mach-integrator/core.c
+ *
+ * Copyright (C) 2000-2003 Deep Blue Solutions 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/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/memblock.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/termios.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/irq.h>
+#include <mach/cm.h>
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach/time.h>
+#include <asm/pgtable.h>
+
+static struct amba_pl010_data integrator_uart_data;
+
+static struct amba_device rtc_device = {
+ .dev = {
+ .init_name = "mb:15",
+ },
+ .res = {
+ .start = INTEGRATOR_RTC_BASE,
+ .end = INTEGRATOR_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_RTCINT, NO_IRQ },
+ .periphid = 0x00041030,
+};
+
+static struct amba_device uart0_device = {
+ .dev = {
+ .init_name = "mb:16",
+ .platform_data = &integrator_uart_data,
+ },
+ .res = {
+ .start = INTEGRATOR_UART0_BASE,
+ .end = INTEGRATOR_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_UARTINT0, NO_IRQ },
+ .periphid = 0x0041010,
+};
+
+static struct amba_device uart1_device = {
+ .dev = {
+ .init_name = "mb:17",
+ .platform_data = &integrator_uart_data,
+ },
+ .res = {
+ .start = INTEGRATOR_UART1_BASE,
+ .end = INTEGRATOR_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_UARTINT1, NO_IRQ },
+ .periphid = 0x0041010,
+};
+
+static struct amba_device kmi0_device = {
+ .dev = {
+ .init_name = "mb:18",
+ },
+ .res = {
+ .start = KMI0_BASE,
+ .end = KMI0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_KMIINT0, NO_IRQ },
+ .periphid = 0x00041050,
+};
+
+static struct amba_device kmi1_device = {
+ .dev = {
+ .init_name = "mb:19",
+ },
+ .res = {
+ .start = KMI1_BASE,
+ .end = KMI1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_KMIINT1, NO_IRQ },
+ .periphid = 0x00041050,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &rtc_device,
+ &uart0_device,
+ &uart1_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk clk24mhz = {
+ .rate = 24000000,
+};
+
+static struct clk uartclk = {
+ .rate = 14745600,
+};
+
+static struct clk dummy_apb_pclk;
+
+static struct clk_lookup lookups[] = {
+ { /* Bus clock */
+ .con_id = "apb_pclk",
+ .clk = &dummy_apb_pclk,
+ }, { /* UART0 */
+ .dev_id = "mb:16",
+ .clk = &uartclk,
+ }, { /* UART1 */
+ .dev_id = "mb:17",
+ .clk = &uartclk,
+ }, { /* KMI0 */
+ .dev_id = "mb:18",
+ .clk = &clk24mhz,
+ }, { /* KMI1 */
+ .dev_id = "mb:19",
+ .clk = &clk24mhz,
+ }, { /* MMCI - IntegratorCP */
+ .dev_id = "mb:1c",
+ .clk = &uartclk,
+ }
+};
+
+void __init integrator_init_early(void)
+{
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
+
+static int __init integrator_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+ return 0;
+}
+
+arch_initcall(integrator_init);
+
+/*
+ * On the Integrator platform, the port RTS and DTR are provided by
+ * bits in the following SC_CTRLS register bits:
+ * RTS DTR
+ * UART0 7 6
+ * UART1 5 4
+ */
+#define SC_CTRLC IO_ADDRESS(INTEGRATOR_SC_CTRLC)
+#define SC_CTRLS IO_ADDRESS(INTEGRATOR_SC_CTRLS)
+
+static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)
+{
+ unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
+
+ if (dev == &uart0_device) {
+ rts_mask = 1 << 4;
+ dtr_mask = 1 << 5;
+ } else {
+ rts_mask = 1 << 6;
+ dtr_mask = 1 << 7;
+ }
+
+ if (mctrl & TIOCM_RTS)
+ ctrlc |= rts_mask;
+ else
+ ctrls |= rts_mask;
+
+ if (mctrl & TIOCM_DTR)
+ ctrlc |= dtr_mask;
+ else
+ ctrls |= dtr_mask;
+
+ __raw_writel(ctrls, SC_CTRLS);
+ __raw_writel(ctrlc, SC_CTRLC);
+}
+
+static struct amba_pl010_data integrator_uart_data = {
+ .set_mctrl = integrator_uart_set_mctrl,
+};
+
+#define CM_CTRL IO_ADDRESS(INTEGRATOR_HDR_CTRL)
+
+static DEFINE_SPINLOCK(cm_lock);
+
+/**
+ * cm_control - update the CM_CTRL register.
+ * @mask: bits to change
+ * @set: bits to set
+ */
+void cm_control(u32 mask, u32 set)
+{
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&cm_lock, flags);
+ val = readl(CM_CTRL) & ~mask;
+ writel(val | set, CM_CTRL);
+ spin_unlock_irqrestore(&cm_lock, flags);
+}
+
+EXPORT_SYMBOL(cm_control);
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+ memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
new file mode 100644
index 00000000..fbb45777
--- /dev/null
+++ b/arch/arm/mach-integrator/cpu.c
@@ -0,0 +1,224 @@
+/*
+ * linux/arch/arm/mach-integrator/cpu.c
+ *
+ * Copyright (C) 2001-2002 Deep Blue Solutions 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.
+ *
+ * CPU support functions
+ */
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/icst.h>
+
+static struct cpufreq_driver integrator_driver;
+
+#define CM_ID IO_ADDRESS(INTEGRATOR_HDR_ID)
+#define CM_OSC IO_ADDRESS(INTEGRATOR_HDR_OSC)
+#define CM_STAT IO_ADDRESS(INTEGRATOR_HDR_STAT)
+#define CM_LOCK IO_ADDRESS(INTEGRATOR_HDR_LOCK)
+
+static const struct icst_params lclk_params = {
+ .ref = 24000000,
+ .vco_max = ICST525_VCO_MAX_5V,
+ .vco_min = ICST525_VCO_MIN,
+ .vd_min = 8,
+ .vd_max = 132,
+ .rd_min = 24,
+ .rd_max = 24,
+ .s2div = icst525_s2div,
+ .idx2s = icst525_idx2s,
+};
+
+static const struct icst_params cclk_params = {
+ .ref = 24000000,
+ .vco_max = ICST525_VCO_MAX_5V,
+ .vco_min = ICST525_VCO_MIN,
+ .vd_min = 12,
+ .vd_max = 160,
+ .rd_min = 24,
+ .rd_max = 24,
+ .s2div = icst525_s2div,
+ .idx2s = icst525_idx2s,
+};
+
+/*
+ * Validate the speed policy.
+ */
+static int integrator_verify_policy(struct cpufreq_policy *policy)
+{
+ struct icst_vco vco;
+
+ cpufreq_verify_within_limits(policy,
+ policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ vco = icst_hz_to_vco(&cclk_params, policy->max * 1000);
+ policy->max = icst_hz(&cclk_params, vco) / 1000;
+
+ vco = icst_hz_to_vco(&cclk_params, policy->min * 1000);
+ policy->min = icst_hz(&cclk_params, vco) / 1000;
+
+ cpufreq_verify_within_limits(policy,
+ policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ return 0;
+}
+
+
+static int integrator_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ cpumask_t cpus_allowed;
+ int cpu = policy->cpu;
+ struct icst_vco vco;
+ struct cpufreq_freqs freqs;
+ u_int cm_osc;
+
+ /*
+ * Save this threads cpus_allowed mask.
+ */
+ cpus_allowed = current->cpus_allowed;
+
+ /*
+ * Bind to the specified CPU. When this call returns,
+ * we should be running on the right CPU.
+ */
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ BUG_ON(cpu != smp_processor_id());
+
+ /* get current setting */
+ cm_osc = __raw_readl(CM_OSC);
+
+ if (machine_is_integrator()) {
+ vco.s = (cm_osc >> 8) & 7;
+ } else if (machine_is_cintegrator()) {
+ vco.s = 1;
+ }
+ vco.v = cm_osc & 255;
+ vco.r = 22;
+ freqs.old = icst_hz(&cclk_params, vco) / 1000;
+
+ /* icst_hz_to_vco rounds down -- so we need the next
+ * larger freq in case of CPUFREQ_RELATION_L.
+ */
+ if (relation == CPUFREQ_RELATION_L)
+ target_freq += 999;
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+ vco = icst_hz_to_vco(&cclk_params, target_freq * 1000);
+ freqs.new = icst_hz(&cclk_params, vco) / 1000;
+
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new) {
+ set_cpus_allowed(current, cpus_allowed);
+ return 0;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ cm_osc = __raw_readl(CM_OSC);
+
+ if (machine_is_integrator()) {
+ cm_osc &= 0xfffff800;
+ cm_osc |= vco.s << 8;
+ } else if (machine_is_cintegrator()) {
+ cm_osc &= 0xffffff00;
+ }
+ cm_osc |= vco.v;
+
+ __raw_writel(0xa05f, CM_LOCK);
+ __raw_writel(cm_osc, CM_OSC);
+ __raw_writel(0, CM_LOCK);
+
+ /*
+ * Restore the CPUs allowed mask.
+ */
+ set_cpus_allowed(current, cpus_allowed);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static unsigned int integrator_get(unsigned int cpu)
+{
+ cpumask_t cpus_allowed;
+ unsigned int current_freq;
+ u_int cm_osc;
+ struct icst_vco vco;
+
+ cpus_allowed = current->cpus_allowed;
+
+ set_cpus_allowed(current, cpumask_of_cpu(cpu));
+ BUG_ON(cpu != smp_processor_id());
+
+ /* detect memory etc. */
+ cm_osc = __raw_readl(CM_OSC);
+
+ if (machine_is_integrator()) {
+ vco.s = (cm_osc >> 8) & 7;
+ } else {
+ vco.s = 1;
+ }
+ vco.v = cm_osc & 255;
+ vco.r = 22;
+
+ current_freq = icst_hz(&cclk_params, vco) / 1000; /* current freq */
+
+ set_cpus_allowed(current, cpus_allowed);
+
+ return current_freq;
+}
+
+static int integrator_cpufreq_init(struct cpufreq_policy *policy)
+{
+
+ /* set default policy and cpuinfo */
+ policy->cpuinfo.max_freq = 160000;
+ policy->cpuinfo.min_freq = 12000;
+ policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */
+ policy->cur = policy->min = policy->max = integrator_get(policy->cpu);
+
+ return 0;
+}
+
+static struct cpufreq_driver integrator_driver = {
+ .verify = integrator_verify_policy,
+ .target = integrator_set_target,
+ .get = integrator_get,
+ .init = integrator_cpufreq_init,
+ .name = "integrator",
+};
+
+static int __init integrator_cpu_init(void)
+{
+ return cpufreq_register_driver(&integrator_driver);
+}
+
+static void __exit integrator_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&integrator_driver);
+}
+
+MODULE_AUTHOR ("Russell M. King");
+MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs");
+MODULE_LICENSE ("GPL");
+
+module_init(integrator_cpu_init);
+module_exit(integrator_cpu_exit);
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
new file mode 100644
index 00000000..8cbb75a9
--- /dev/null
+++ b/arch/arm/mach-integrator/impd1.c
@@ -0,0 +1,482 @@
+/*
+ * linux/arch/arm/mach-integrator/impd1.c
+ *
+ * Copyright (C) 2003 Deep Blue Solutions 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.
+ *
+ * This file provides the core support for the IM-PD1 module.
+ *
+ * Module / boot parameters.
+ * lmid=n impd1.lmid=n - set the logic module position in stack to 'n'
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/clkdev.h>
+
+#include <asm/hardware/icst.h>
+#include <mach/lm.h>
+#include <mach/impd1.h>
+#include <asm/sizes.h>
+
+static int module_id;
+
+module_param_named(lmid, module_id, int, 0444);
+MODULE_PARM_DESC(lmid, "logic module stack position");
+
+struct impd1_module {
+ void __iomem *base;
+ struct clk vcos[2];
+ struct clk_lookup *clks[3];
+};
+
+static const struct icst_params impd1_vco_params = {
+ .ref = 24000000, /* 24 MHz */
+ .vco_max = ICST525_VCO_MAX_3V,
+ .vco_min = ICST525_VCO_MIN,
+ .vd_min = 12,
+ .vd_max = 519,
+ .rd_min = 3,
+ .rd_max = 120,
+ .s2div = icst525_s2div,
+ .idx2s = icst525_idx2s,
+};
+
+static void impd1_setvco(struct clk *clk, struct icst_vco vco)
+{
+ struct impd1_module *impd1 = clk->data;
+ u32 val = vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, impd1->base + IMPD1_LOCK);
+ writel(val, clk->vcoreg);
+ writel(0, impd1->base + IMPD1_LOCK);
+
+#ifdef DEBUG
+ vco.v = val & 0x1ff;
+ vco.r = (val >> 9) & 0x7f;
+ vco.s = (val >> 16) & 7;
+
+ pr_debug("IM-PD1: VCO%d clock is %ld Hz\n",
+ vconr, icst525_hz(&impd1_vco_params, vco));
+#endif
+}
+
+static const struct clk_ops impd1_clk_ops = {
+ .round = icst_clk_round,
+ .set = icst_clk_set,
+ .setvco = impd1_setvco,
+};
+
+void impd1_tweak_control(struct device *dev, u32 mask, u32 val)
+{
+ struct impd1_module *impd1 = dev_get_drvdata(dev);
+ u32 cur;
+
+ val &= mask;
+ cur = readl(impd1->base + IMPD1_CTRL) & ~mask;
+ writel(cur | val, impd1->base + IMPD1_CTRL);
+}
+
+EXPORT_SYMBOL(impd1_tweak_control);
+
+/*
+ * CLCD support
+ */
+#define PANEL PROSPECTOR
+
+#define LTM10C209 1
+#define PROSPECTOR 2
+#define SVGA 3
+#define VGA 4
+
+#if PANEL == VGA
+#define PANELTYPE vga
+static struct clcd_panel vga = {
+ .mode = {
+ .name = "VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .connector = IMPD1_CTRL_DISP_VGA,
+ .bpp = 16,
+ .grayscale = 0,
+};
+
+#elif PANEL == SVGA
+#define PANELTYPE svga
+static struct clcd_panel svga = {
+ .mode = {
+ .name = "SVGA",
+ .refresh = 0,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 27778,
+ .left_margin = 20,
+ .right_margin = 20,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 164,
+ .vsync_len = 62,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .connector = IMPD1_CTRL_DISP_VGA,
+ .caps = CLCD_CAP_5551,
+ .bpp = 16,
+ .grayscale = 0,
+};
+
+#elif PANEL == PROSPECTOR
+#define PANELTYPE prospector
+static struct clcd_panel prospector = {
+ .mode = {
+ .name = "PROSPECTOR",
+ .refresh = 0,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 40000,
+ .left_margin = 33,
+ .right_margin = 64,
+ .upper_margin = 36,
+ .lower_margin = 7,
+ .hsync_len = 64,
+ .vsync_len = 25,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .fixedtimings = 1,
+ .connector = IMPD1_CTRL_DISP_LCD,
+ .bpp = 16,
+ .grayscale = 0,
+};
+
+#elif PANEL == LTM10C209
+#define PANELTYPE ltm10c209
+/*
+ * Untested.
+ */
+static struct clcd_panel ltm10c209 = {
+ .mode = {
+ .name = "LTM10C209",
+ .refresh = 0,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 40000,
+ .left_margin = 20,
+ .right_margin = 20,
+ .upper_margin = 19,
+ .lower_margin = 19,
+ .hsync_len = 20,
+ .vsync_len = 10,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD,
+ .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .fixedtimings = 1,
+ .connector = IMPD1_CTRL_DISP_LCD,
+ .bpp = 16,
+ .grayscale = 0,
+};
+#endif
+
+/*
+ * Disable all display connectors on the interface module.
+ */
+static void impd1fb_clcd_disable(struct clcd_fb *fb)
+{
+ impd1_tweak_control(fb->dev->dev.parent, IMPD1_CTRL_DISP_MASK, 0);
+}
+
+/*
+ * Enable the relevant connector on the interface module.
+ */
+static void impd1fb_clcd_enable(struct clcd_fb *fb)
+{
+ impd1_tweak_control(fb->dev->dev.parent, IMPD1_CTRL_DISP_MASK,
+ fb->panel->connector | IMPD1_CTRL_DISP_ENABLE);
+}
+
+static int impd1fb_clcd_setup(struct clcd_fb *fb)
+{
+ unsigned long framebase = fb->dev->res.start + 0x01000000;
+ unsigned long framesize = SZ_1M;
+ int ret = 0;
+
+ fb->panel = &PANELTYPE;
+
+ if (!request_mem_region(framebase, framesize, "clcd framebuffer")) {
+ printk(KERN_ERR "IM-PD1: unable to reserve framebuffer\n");
+ return -EBUSY;
+ }
+
+ fb->fb.screen_base = ioremap(framebase, framesize);
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "IM-PD1: unable to map framebuffer\n");
+ ret = -ENOMEM;
+ goto free_buffer;
+ }
+
+ fb->fb.fix.smem_start = framebase;
+ fb->fb.fix.smem_len = framesize;
+
+ return 0;
+
+ free_buffer:
+ release_mem_region(framebase, framesize);
+ return ret;
+}
+
+static int impd1fb_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ unsigned long start, size;
+
+ start = vma->vm_pgoff + (fb->fb.fix.smem_start >> PAGE_SHIFT);
+ size = vma->vm_end - vma->vm_start;
+
+ return remap_pfn_range(vma, vma->vm_start, start, size,
+ vma->vm_page_prot);
+}
+
+static void impd1fb_clcd_remove(struct clcd_fb *fb)
+{
+ iounmap(fb->fb.screen_base);
+ release_mem_region(fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static struct clcd_board impd1_clcd_data = {
+ .name = "IM-PD/1",
+ .caps = CLCD_CAP_5551 | CLCD_CAP_888,
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .disable = impd1fb_clcd_disable,
+ .enable = impd1fb_clcd_enable,
+ .setup = impd1fb_clcd_setup,
+ .mmap = impd1fb_clcd_mmap,
+ .remove = impd1fb_clcd_remove,
+};
+
+struct impd1_device {
+ unsigned long offset;
+ unsigned int irq[2];
+ unsigned int id;
+ void *platform_data;
+};
+
+static struct impd1_device impd1_devs[] = {
+ {
+ .offset = 0x03000000,
+ .id = 0x00041190,
+ }, {
+ .offset = 0x00100000,
+ .irq = { 1 },
+ .id = 0x00141011,
+ }, {
+ .offset = 0x00200000,
+ .irq = { 2 },
+ .id = 0x00141011,
+ }, {
+ .offset = 0x00300000,
+ .irq = { 3 },
+ .id = 0x00041022,
+ }, {
+ .offset = 0x00400000,
+ .irq = { 4 },
+ .id = 0x00041061,
+ }, {
+ .offset = 0x00500000,
+ .irq = { 5 },
+ .id = 0x00041061,
+ }, {
+ .offset = 0x00600000,
+ .irq = { 6 },
+ .id = 0x00041130,
+ }, {
+ .offset = 0x00700000,
+ .irq = { 7, 8 },
+ .id = 0x00041181,
+ }, {
+ .offset = 0x00800000,
+ .irq = { 9 },
+ .id = 0x00041041,
+ }, {
+ .offset = 0x01000000,
+ .irq = { 11 },
+ .id = 0x00041110,
+ .platform_data = &impd1_clcd_data,
+ }
+};
+
+static struct clk fixed_14745600 = {
+ .rate = 14745600,
+};
+
+static int impd1_probe(struct lm_device *dev)
+{
+ struct impd1_module *impd1;
+ int i, ret;
+
+ if (dev->id != module_id)
+ return -EINVAL;
+
+ if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
+ return -EBUSY;
+
+ impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL);
+ if (!impd1) {
+ ret = -ENOMEM;
+ goto release_lm;
+ }
+
+ impd1->base = ioremap(dev->resource.start, SZ_4K);
+ if (!impd1->base) {
+ ret = -ENOMEM;
+ goto free_impd1;
+ }
+
+ lm_set_drvdata(dev, impd1);
+
+ printk("IM-PD1 found at 0x%08lx\n",
+ (unsigned long)dev->resource.start);
+
+ for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) {
+ impd1->vcos[i].ops = &impd1_clk_ops,
+ impd1->vcos[i].owner = THIS_MODULE,
+ impd1->vcos[i].params = &impd1_vco_params,
+ impd1->vcos[i].data = impd1;
+ }
+ impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1;
+ impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2;
+
+ impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000",
+ dev->id);
+ impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100",
+ dev->id);
+ impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200",
+ dev->id);
+ for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
+ clkdev_add(impd1->clks[i]);
+
+ for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) {
+ struct impd1_device *idev = impd1_devs + i;
+ struct amba_device *d;
+ unsigned long pc_base;
+
+ pc_base = dev->resource.start + idev->offset;
+
+ d = kzalloc(sizeof(struct amba_device), GFP_KERNEL);
+ if (!d)
+ continue;
+
+ dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
+ d->dev.parent = &dev->dev;
+ d->res.start = dev->resource.start + idev->offset;
+ d->res.end = d->res.start + SZ_4K - 1;
+ d->res.flags = IORESOURCE_MEM;
+ d->irq[0] = dev->irq;
+ d->irq[1] = dev->irq;
+ d->periphid = idev->id;
+ d->dev.platform_data = idev->platform_data;
+
+ ret = amba_device_register(d, &dev->resource);
+ if (ret) {
+ dev_err(&d->dev, "unable to register device: %d\n", ret);
+ kfree(d);
+ }
+ }
+
+ return 0;
+
+ free_impd1:
+ if (impd1 && impd1->base)
+ iounmap(impd1->base);
+ kfree(impd1);
+ release_lm:
+ release_mem_region(dev->resource.start, SZ_4K);
+ return ret;
+}
+
+static int impd1_remove_one(struct device *dev, void *data)
+{
+ device_unregister(dev);
+ return 0;
+}
+
+static void impd1_remove(struct lm_device *dev)
+{
+ struct impd1_module *impd1 = lm_get_drvdata(dev);
+ int i;
+
+ device_for_each_child(&dev->dev, NULL, impd1_remove_one);
+
+ for (i = 0; i < ARRAY_SIZE(impd1->clks); i++)
+ clkdev_drop(impd1->clks[i]);
+
+ lm_set_drvdata(dev, NULL);
+
+ iounmap(impd1->base);
+ kfree(impd1);
+ release_mem_region(dev->resource.start, SZ_4K);
+}
+
+static struct lm_driver impd1_driver = {
+ .drv = {
+ .name = "impd1",
+ },
+ .probe = impd1_probe,
+ .remove = impd1_remove,
+};
+
+static int __init impd1_init(void)
+{
+ return lm_driver_register(&impd1_driver);
+}
+
+static void __exit impd1_exit(void)
+{
+ lm_driver_unregister(&impd1_driver);
+}
+
+module_init(impd1_init);
+module_exit(impd1_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Integrator/IM-PD1 logic module core driver");
+MODULE_AUTHOR("Deep Blue Solutions Ltd");
diff --git a/arch/arm/mach-integrator/include/mach/bits.h b/arch/arm/mach-integrator/include/mach/bits.h
new file mode 100644
index 00000000..09b024e0
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/bits.h
@@ -0,0 +1,61 @@
+/*
+ * 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ * from .s file by awk -f s2h.awk
+ */
+/* Bit field definitions
+ * Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __bits_h
+#define __bits_h 1
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#endif
+
+/* END */
diff --git a/arch/arm/mach-integrator/include/mach/clkdev.h b/arch/arm/mach-integrator/include/mach/clkdev.h
new file mode 100644
index 00000000..bfe07679
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/clkdev.h
@@ -0,0 +1,26 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <linux/module.h>
+#include <plat/clock.h>
+
+struct clk {
+ unsigned long rate;
+ const struct clk_ops *ops;
+ struct module *owner;
+ const struct icst_params *params;
+ void __iomem *vcoreg;
+ void *data;
+};
+
+static inline int __clk_get(struct clk *clk)
+{
+ return try_module_get(clk->owner);
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+
+#endif
diff --git a/arch/arm/mach-integrator/include/mach/cm.h b/arch/arm/mach-integrator/include/mach/cm.h
new file mode 100644
index 00000000..445d57ad
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/cm.h
@@ -0,0 +1,36 @@
+/*
+ * update the core module control register.
+ */
+void cm_control(u32, u32);
+
+#define CM_CTRL_LED (1 << 0)
+#define CM_CTRL_nMBDET (1 << 1)
+#define CM_CTRL_REMAP (1 << 2)
+#define CM_CTRL_RESET (1 << 3)
+
+/*
+ * Integrator/AP,PP2 specific
+ */
+#define CM_CTRL_HIGHVECTORS (1 << 4)
+#define CM_CTRL_BIGENDIAN (1 << 5)
+#define CM_CTRL_FASTBUS (1 << 6)
+#define CM_CTRL_SYNC (1 << 7)
+
+/*
+ * ARM926/946/966 Integrator/CP specific
+ */
+#define CM_CTRL_LCDBIASEN (1 << 8)
+#define CM_CTRL_LCDBIASUP (1 << 9)
+#define CM_CTRL_LCDBIASDN (1 << 10)
+#define CM_CTRL_LCDMUXSEL_MASK (7 << 11)
+#define CM_CTRL_LCDMUXSEL_GENLCD (1 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA565_TFT555 (2 << 11)
+#define CM_CTRL_LCDMUXSEL_SHARPLCD (3 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA555_TFT555 (4 << 11)
+#define CM_CTRL_LCDEN0 (1 << 14)
+#define CM_CTRL_LCDEN1 (1 << 15)
+#define CM_CTRL_STATIC1 (1 << 16)
+#define CM_CTRL_STATIC2 (1 << 17)
+#define CM_CTRL_STATIC (1 << 18)
+#define CM_CTRL_n24BITEN (1 << 19)
+#define CM_CTRL_EBIWP (1 << 20)
diff --git a/arch/arm/mach-integrator/include/mach/debug-macro.S b/arch/arm/mach-integrator/include/mach/debug-macro.S
new file mode 100644
index 00000000..a1f598fd
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/debug-macro.S
@@ -0,0 +1,20 @@
+/* arch/arm/mach-integrator/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x16000000 @ physical base address
+ mov \rv, #0xf0000000 @ virtual base
+ add \rv, \rv, #0x16000000 >> 4
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-integrator/include/mach/entry-macro.S b/arch/arm/mach-integrator/include/mach/entry-macro.S
new file mode 100644
index 00000000..3d029c9f
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/entry-macro.S
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-integrator/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Integrator platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* FIXME: should not be using soo many LDRs here */
+ ldr \base, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+ mov \irqnr, #IRQ_PIC_START
+ ldr \irqstat, [\base, #IRQ_STATUS] @ get masked status
+ ldr \base, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+ teq \irqstat, #0
+ ldreq \irqstat, [\base, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+ moveq \irqnr, #IRQ_CIC_START
+
+1001: tst \irqstat, #15
+ bne 1002f
+ add \irqnr, \irqnr, #4
+ movs \irqstat, \irqstat, lsr #4
+ bne 1001b
+1002: tst \irqstat, #1
+ bne 1003f
+ add \irqnr, \irqnr, #1
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
+ .endm
+
diff --git a/arch/arm/mach-integrator/include/mach/hardware.h b/arch/arm/mach-integrator/include/mach/hardware.h
new file mode 100644
index 00000000..57f51ba1
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/hardware.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-integrator/include/mach/hardware.h
+ *
+ * This file contains the hardware definitions of the Integrator.
+ *
+ * Copyright (C) 1999 ARM Limited.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE 0xF0000000 // VA of IO
+#define IO_SIZE 0x0B000000 // How much?
+#define IO_START INTEGRATOR_HDR_BASE // PA of IO
+
+#define PCIMEM_BASE PCI_MEMORY_VADDR
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x6000
+#define PCIBIOS_MIN_MEM 0x00100000
+
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+#define IO_ADDRESS(x) (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
+#else
+#define IO_ADDRESS(x) (x)
+#endif
+
+#define __io_address(n) ((void __iomem *)IO_ADDRESS(n))
+
+#endif
+
diff --git a/arch/arm/mach-integrator/include/mach/impd1.h b/arch/arm/mach-integrator/include/mach/impd1.h
new file mode 100644
index 00000000..d75de4b1
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/impd1.h
@@ -0,0 +1,18 @@
+#define IMPD1_OSC1 0x00
+#define IMPD1_OSC2 0x04
+#define IMPD1_LOCK 0x08
+#define IMPD1_LEDS 0x0c
+#define IMPD1_INT 0x10
+#define IMPD1_SW 0x14
+#define IMPD1_CTRL 0x18
+
+#define IMPD1_CTRL_DISP_LCD (0 << 0)
+#define IMPD1_CTRL_DISP_VGA (1 << 0)
+#define IMPD1_CTRL_DISP_LCD1 (2 << 0)
+#define IMPD1_CTRL_DISP_ENABLE (1 << 2)
+#define IMPD1_CTRL_DISP_MASK (7 << 0)
+
+struct device;
+
+void impd1_tweak_control(struct device *dev, u32 mask, u32 val);
+
diff --git a/arch/arm/mach-integrator/include/mach/io.h b/arch/arm/mach-integrator/include/mach/io.h
new file mode 100644
index 00000000..f21bb549
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/io.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-integrator/include/mach/io.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+/*
+ * WARNING: this has to mirror definitions in platform.h
+ */
+#define PCI_MEMORY_VADDR 0xe8000000
+#define PCI_CONFIG_VADDR 0xec000000
+#define PCI_V3_VADDR 0xed000000
+#define PCI_IO_VADDR 0xee000000
+
+#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h
new file mode 100644
index 00000000..1fbe6d19
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/irqs.h
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/mach-integrator/include/mach/irqs.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+/*
+ * Interrupt numbers
+ */
+#define IRQ_PIC_START 0
+#define IRQ_SOFTINT 0
+#define IRQ_UARTINT0 1
+#define IRQ_UARTINT1 2
+#define IRQ_KMIINT0 3
+#define IRQ_KMIINT1 4
+#define IRQ_TIMERINT0 5
+#define IRQ_TIMERINT1 6
+#define IRQ_TIMERINT2 7
+#define IRQ_RTCINT 8
+#define IRQ_AP_EXPINT0 9
+#define IRQ_AP_EXPINT1 10
+#define IRQ_AP_EXPINT2 11
+#define IRQ_AP_EXPINT3 12
+#define IRQ_AP_PCIINT0 13
+#define IRQ_AP_PCIINT1 14
+#define IRQ_AP_PCIINT2 15
+#define IRQ_AP_PCIINT3 16
+#define IRQ_AP_V3INT 17
+#define IRQ_AP_CPINT0 18
+#define IRQ_AP_CPINT1 19
+#define IRQ_AP_LBUSTIMEOUT 20
+#define IRQ_AP_APCINT 21
+#define IRQ_CP_CLCDCINT 22
+#define IRQ_CP_MMCIINT0 23
+#define IRQ_CP_MMCIINT1 24
+#define IRQ_CP_AACIINT 25
+#define IRQ_CP_CPPLDINT 26
+#define IRQ_CP_ETHINT 27
+#define IRQ_CP_TSPENINT 28
+#define IRQ_PIC_END 31
+
+#define IRQ_CIC_START 32
+#define IRQ_CM_SOFTINT 32
+#define IRQ_CM_COMMRX 33
+#define IRQ_CM_COMMTX 34
+#define IRQ_CIC_END 34
+
+/*
+ * IntegratorCP only
+ */
+#define IRQ_SIC_START 35
+#define IRQ_SIC_CP_SOFTINT 35
+#define IRQ_SIC_CP_RI0 36
+#define IRQ_SIC_CP_RI1 37
+#define IRQ_SIC_CP_CARDIN 38
+#define IRQ_SIC_CP_LMINT0 39
+#define IRQ_SIC_CP_LMINT1 40
+#define IRQ_SIC_CP_LMINT2 41
+#define IRQ_SIC_CP_LMINT3 42
+#define IRQ_SIC_CP_LMINT4 43
+#define IRQ_SIC_CP_LMINT5 44
+#define IRQ_SIC_CP_LMINT6 45
+#define IRQ_SIC_CP_LMINT7 46
+#define IRQ_SIC_END 46
+
+#define NR_IRQS 47
+
diff --git a/arch/arm/mach-integrator/include/mach/lm.h b/arch/arm/mach-integrator/include/mach/lm.h
new file mode 100644
index 00000000..28186b6f
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/lm.h
@@ -0,0 +1,23 @@
+
+struct lm_device {
+ struct device dev;
+ struct resource resource;
+ unsigned int irq;
+ unsigned int id;
+};
+
+struct lm_driver {
+ struct device_driver drv;
+ int (*probe)(struct lm_device *);
+ void (*remove)(struct lm_device *);
+ int (*suspend)(struct lm_device *, pm_message_t);
+ int (*resume)(struct lm_device *);
+};
+
+int lm_driver_register(struct lm_driver *drv);
+void lm_driver_unregister(struct lm_driver *drv);
+
+int lm_device_register(struct lm_device *dev);
+
+#define lm_get_drvdata(lm) dev_get_drvdata(&(lm)->dev)
+#define lm_set_drvdata(lm,d) dev_set_drvdata(&(lm)->dev, d)
diff --git a/arch/arm/mach-integrator/include/mach/memory.h b/arch/arm/mach-integrator/include/mach/memory.h
new file mode 100644
index 00000000..334d5e27
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/memory.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-integrator/include/mach/memory.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#define BUS_OFFSET UL(0x80000000)
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
+#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
+#define __pfn_to_bus(x) (__pfn_to_phys(x) + (BUS_OFFSET - PHYS_OFFSET))
+#define __bus_to_pfn(x) __phys_to_pfn((x) - (BUS_OFFSET - PHYS_OFFSET))
+
+#endif
diff --git a/arch/arm/mach-integrator/include/mach/platform.h b/arch/arm/mach-integrator/include/mach/platform.h
new file mode 100644
index 00000000..5e6ea5cf
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/platform.h
@@ -0,0 +1,414 @@
+/*
+ * 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ * from .s file by awk -f s2h.awk
+ */
+/**************************************************************************
+ * * Copyright © ARM Limited 1998. All rights reserved.
+ * ***********************************************************************/
+/* ************************************************************************
+ *
+ * Integrator address map
+ *
+ * ***********************************************************************/
+
+#ifndef __address_h
+#define __address_h 1
+
+/* ========================================================================
+ * Integrator definitions
+ * ========================================================================
+ * ------------------------------------------------------------------------
+ * Memory definitions
+ * ------------------------------------------------------------------------
+ * Integrator memory map
+ *
+ */
+#define INTEGRATOR_BOOT_ROM_LO 0x00000000
+#define INTEGRATOR_BOOT_ROM_HI 0x20000000
+#define INTEGRATOR_BOOT_ROM_BASE INTEGRATOR_BOOT_ROM_HI /* Normal position */
+#define INTEGRATOR_BOOT_ROM_SIZE SZ_512K
+
+/*
+ * New Core Modules have different amounts of SSRAM, the amount of SSRAM
+ * fitted can be found in HDR_STAT.
+ *
+ * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to
+ * the minimum amount of SSRAM fitted on any core module.
+ *
+ * New Core Modules also alias the SSRAM.
+ *
+ */
+#define INTEGRATOR_SSRAM_BASE 0x00000000
+#define INTEGRATOR_SSRAM_ALIAS_BASE 0x10800000
+#define INTEGRATOR_SSRAM_SIZE SZ_256K
+
+#define INTEGRATOR_FLASH_BASE 0x24000000
+#define INTEGRATOR_FLASH_SIZE SZ_32M
+
+#define INTEGRATOR_MBRD_SSRAM_BASE 0x28000000
+#define INTEGRATOR_MBRD_SSRAM_SIZE SZ_512K
+
+/*
+ * SDRAM is a SIMM therefore the size is not known.
+ *
+ */
+#define INTEGRATOR_SDRAM_BASE 0x00040000
+
+#define INTEGRATOR_SDRAM_ALIAS_BASE 0x80000000
+#define INTEGRATOR_HDR0_SDRAM_BASE 0x80000000
+#define INTEGRATOR_HDR1_SDRAM_BASE 0x90000000
+#define INTEGRATOR_HDR2_SDRAM_BASE 0xA0000000
+#define INTEGRATOR_HDR3_SDRAM_BASE 0xB0000000
+
+/*
+ * Logic expansion modules
+ *
+ */
+#define INTEGRATOR_LOGIC_MODULES_BASE 0xC0000000
+#define INTEGRATOR_LOGIC_MODULE0_BASE 0xC0000000
+#define INTEGRATOR_LOGIC_MODULE1_BASE 0xD0000000
+#define INTEGRATOR_LOGIC_MODULE2_BASE 0xE0000000
+#define INTEGRATOR_LOGIC_MODULE3_BASE 0xF0000000
+
+/* ------------------------------------------------------------------------
+ * Integrator header card registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define INTEGRATOR_HDR_ID_OFFSET 0x00
+#define INTEGRATOR_HDR_PROC_OFFSET 0x04
+#define INTEGRATOR_HDR_OSC_OFFSET 0x08
+#define INTEGRATOR_HDR_CTRL_OFFSET 0x0C
+#define INTEGRATOR_HDR_STAT_OFFSET 0x10
+#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
+#define INTEGRATOR_HDR_SDRAM_OFFSET 0x20
+#define INTEGRATOR_HDR_INIT_OFFSET 0x24 /* CM9x6 */
+#define INTEGRATOR_HDR_IC_OFFSET 0x40
+#define INTEGRATOR_HDR_SPDBASE_OFFSET 0x100
+#define INTEGRATOR_HDR_SPDTOP_OFFSET 0x200
+
+#define INTEGRATOR_HDR_BASE 0x10000000
+#define INTEGRATOR_HDR_ID (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET)
+#define INTEGRATOR_HDR_PROC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET)
+#define INTEGRATOR_HDR_OSC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET)
+#define INTEGRATOR_HDR_CTRL (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET)
+#define INTEGRATOR_HDR_STAT (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET)
+#define INTEGRATOR_HDR_LOCK (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET)
+#define INTEGRATOR_HDR_SDRAM (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET)
+#define INTEGRATOR_HDR_INIT (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET)
+#define INTEGRATOR_HDR_IC (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET)
+#define INTEGRATOR_HDR_SPDBASE (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET)
+#define INTEGRATOR_HDR_SPDTOP (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET)
+
+#define INTEGRATOR_HDR_CTRL_LED 0x01
+#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02
+#define INTEGRATOR_HDR_CTRL_REMAP 0x04
+#define INTEGRATOR_HDR_CTRL_RESET 0x08
+#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10
+#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN 0x20
+#define INTEGRATOR_HDR_CTRL_FASTBUS 0x40
+#define INTEGRATOR_HDR_CTRL_SYNC 0x80
+
+#define INTEGRATOR_HDR_OSC_CORE_10MHz 0x102
+#define INTEGRATOR_HDR_OSC_CORE_15MHz 0x107
+#define INTEGRATOR_HDR_OSC_CORE_20MHz 0x10C
+#define INTEGRATOR_HDR_OSC_CORE_25MHz 0x111
+#define INTEGRATOR_HDR_OSC_CORE_30MHz 0x116
+#define INTEGRATOR_HDR_OSC_CORE_35MHz 0x11B
+#define INTEGRATOR_HDR_OSC_CORE_40MHz 0x120
+#define INTEGRATOR_HDR_OSC_CORE_45MHz 0x125
+#define INTEGRATOR_HDR_OSC_CORE_50MHz 0x12A
+#define INTEGRATOR_HDR_OSC_CORE_55MHz 0x12F
+#define INTEGRATOR_HDR_OSC_CORE_60MHz 0x134
+#define INTEGRATOR_HDR_OSC_CORE_65MHz 0x139
+#define INTEGRATOR_HDR_OSC_CORE_70MHz 0x13E
+#define INTEGRATOR_HDR_OSC_CORE_75MHz 0x143
+#define INTEGRATOR_HDR_OSC_CORE_80MHz 0x148
+#define INTEGRATOR_HDR_OSC_CORE_85MHz 0x14D
+#define INTEGRATOR_HDR_OSC_CORE_90MHz 0x152
+#define INTEGRATOR_HDR_OSC_CORE_95MHz 0x157
+#define INTEGRATOR_HDR_OSC_CORE_100MHz 0x15C
+#define INTEGRATOR_HDR_OSC_CORE_105MHz 0x161
+#define INTEGRATOR_HDR_OSC_CORE_110MHz 0x166
+#define INTEGRATOR_HDR_OSC_CORE_115MHz 0x16B
+#define INTEGRATOR_HDR_OSC_CORE_120MHz 0x170
+#define INTEGRATOR_HDR_OSC_CORE_125MHz 0x175
+#define INTEGRATOR_HDR_OSC_CORE_130MHz 0x17A
+#define INTEGRATOR_HDR_OSC_CORE_135MHz 0x17F
+#define INTEGRATOR_HDR_OSC_CORE_140MHz 0x184
+#define INTEGRATOR_HDR_OSC_CORE_145MHz 0x189
+#define INTEGRATOR_HDR_OSC_CORE_150MHz 0x18E
+#define INTEGRATOR_HDR_OSC_CORE_155MHz 0x193
+#define INTEGRATOR_HDR_OSC_CORE_160MHz 0x198
+#define INTEGRATOR_HDR_OSC_CORE_MASK 0x7FF
+
+#define INTEGRATOR_HDR_OSC_MEM_10MHz 0x10C000
+#define INTEGRATOR_HDR_OSC_MEM_15MHz 0x116000
+#define INTEGRATOR_HDR_OSC_MEM_20MHz 0x120000
+#define INTEGRATOR_HDR_OSC_MEM_25MHz 0x12A000
+#define INTEGRATOR_HDR_OSC_MEM_30MHz 0x134000
+#define INTEGRATOR_HDR_OSC_MEM_33MHz 0x13A000
+#define INTEGRATOR_HDR_OSC_MEM_40MHz 0x148000
+#define INTEGRATOR_HDR_OSC_MEM_50MHz 0x15C000
+#define INTEGRATOR_HDR_OSC_MEM_60MHz 0x170000
+#define INTEGRATOR_HDR_OSC_MEM_66MHz 0x17C000
+#define INTEGRATOR_HDR_OSC_MEM_MASK 0x7FF000
+
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0 0x0
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0 0x0800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6 0x1000000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00 0x1800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK 0x1800000
+
+#define INTEGRATOR_HDR_SDRAM_SPD_OK (1 << 5)
+
+
+/* ------------------------------------------------------------------------
+ * Integrator system registers
+ * ------------------------------------------------------------------------
+ *
+ */
+
+/*
+ * System Controller
+ *
+ */
+#define INTEGRATOR_SC_ID_OFFSET 0x00
+#define INTEGRATOR_SC_OSC_OFFSET 0x04
+#define INTEGRATOR_SC_CTRLS_OFFSET 0x08
+#define INTEGRATOR_SC_CTRLC_OFFSET 0x0C
+#define INTEGRATOR_SC_DEC_OFFSET 0x10
+#define INTEGRATOR_SC_ARB_OFFSET 0x14
+#define INTEGRATOR_SC_PCIENABLE_OFFSET 0x18
+#define INTEGRATOR_SC_LOCK_OFFSET 0x1C
+
+#define INTEGRATOR_SC_BASE 0x11000000
+#define INTEGRATOR_SC_ID (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
+#define INTEGRATOR_SC_OSC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
+#define INTEGRATOR_SC_CTRLS (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define INTEGRATOR_SC_CTRLC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define INTEGRATOR_SC_DEC (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
+#define INTEGRATOR_SC_ARB (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
+#define INTEGRATOR_SC_PCIENABLE (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
+#define INTEGRATOR_SC_LOCK (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
+
+#define INTEGRATOR_SC_OSC_SYS_10MHz 0x20
+#define INTEGRATOR_SC_OSC_SYS_15MHz 0x34
+#define INTEGRATOR_SC_OSC_SYS_20MHz 0x48
+#define INTEGRATOR_SC_OSC_SYS_25MHz 0x5C
+#define INTEGRATOR_SC_OSC_SYS_33MHz 0x7C
+#define INTEGRATOR_SC_OSC_SYS_MASK 0xFF
+
+#define INTEGRATOR_SC_OSC_PCI_25MHz 0x100
+#define INTEGRATOR_SC_OSC_PCI_33MHz 0x0
+#define INTEGRATOR_SC_OSC_PCI_MASK 0x100
+
+#define INTEGRATOR_SC_CTRL_SOFTRST (1 << 0)
+#define INTEGRATOR_SC_CTRL_nFLVPPEN (1 << 1)
+#define INTEGRATOR_SC_CTRL_nFLWP (1 << 2)
+#define INTEGRATOR_SC_CTRL_URTS0 (1 << 4)
+#define INTEGRATOR_SC_CTRL_UDTR0 (1 << 5)
+#define INTEGRATOR_SC_CTRL_URTS1 (1 << 6)
+#define INTEGRATOR_SC_CTRL_UDTR1 (1 << 7)
+
+/*
+ * External Bus Interface
+ *
+ */
+#define INTEGRATOR_EBI_BASE 0x12000000
+
+#define INTEGRATOR_EBI_CSR0_OFFSET 0x00
+#define INTEGRATOR_EBI_CSR1_OFFSET 0x04
+#define INTEGRATOR_EBI_CSR2_OFFSET 0x08
+#define INTEGRATOR_EBI_CSR3_OFFSET 0x0C
+#define INTEGRATOR_EBI_LOCK_OFFSET 0x20
+
+#define INTEGRATOR_EBI_CSR0 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
+#define INTEGRATOR_EBI_CSR1 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define INTEGRATOR_EBI_CSR2 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
+#define INTEGRATOR_EBI_CSR3 (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
+#define INTEGRATOR_EBI_LOCK (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+#define INTEGRATOR_EBI_8_BIT 0x00
+#define INTEGRATOR_EBI_16_BIT 0x01
+#define INTEGRATOR_EBI_32_BIT 0x02
+#define INTEGRATOR_EBI_WRITE_ENABLE 0x04
+#define INTEGRATOR_EBI_SYNC 0x08
+#define INTEGRATOR_EBI_WS_2 0x00
+#define INTEGRATOR_EBI_WS_3 0x10
+#define INTEGRATOR_EBI_WS_4 0x20
+#define INTEGRATOR_EBI_WS_5 0x30
+#define INTEGRATOR_EBI_WS_6 0x40
+#define INTEGRATOR_EBI_WS_7 0x50
+#define INTEGRATOR_EBI_WS_8 0x60
+#define INTEGRATOR_EBI_WS_9 0x70
+#define INTEGRATOR_EBI_WS_10 0x80
+#define INTEGRATOR_EBI_WS_11 0x90
+#define INTEGRATOR_EBI_WS_12 0xA0
+#define INTEGRATOR_EBI_WS_13 0xB0
+#define INTEGRATOR_EBI_WS_14 0xC0
+#define INTEGRATOR_EBI_WS_15 0xD0
+#define INTEGRATOR_EBI_WS_16 0xE0
+#define INTEGRATOR_EBI_WS_17 0xF0
+
+
+#define INTEGRATOR_CT_BASE 0x13000000 /* Counter/Timers */
+#define INTEGRATOR_IC_BASE 0x14000000 /* Interrupt Controller */
+#define INTEGRATOR_RTC_BASE 0x15000000 /* Real Time Clock */
+#define INTEGRATOR_UART0_BASE 0x16000000 /* UART 0 */
+#define INTEGRATOR_UART1_BASE 0x17000000 /* UART 1 */
+#define INTEGRATOR_KBD_BASE 0x18000000 /* Keyboard */
+#define INTEGRATOR_MOUSE_BASE 0x19000000 /* Mouse */
+
+/*
+ * LED's & Switches
+ *
+ */
+#define INTEGRATOR_DBG_ALPHA_OFFSET 0x00
+#define INTEGRATOR_DBG_LEDS_OFFSET 0x04
+#define INTEGRATOR_DBG_SWITCH_OFFSET 0x08
+
+#define INTEGRATOR_DBG_BASE 0x1A000000
+#define INTEGRATOR_DBG_ALPHA (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
+#define INTEGRATOR_DBG_LEDS (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
+#define INTEGRATOR_DBG_SWITCH (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
+
+#define INTEGRATOR_AP_GPIO_BASE 0x1B000000 /* GPIO */
+
+#define INTEGRATOR_CP_MMC_BASE 0x1C000000 /* MMC */
+#define INTEGRATOR_CP_AACI_BASE 0x1D000000 /* AACI */
+#define INTEGRATOR_CP_ETH_BASE 0xC8000000 /* Ethernet */
+#define INTEGRATOR_CP_GPIO_BASE 0xC9000000 /* GPIO */
+#define INTEGRATOR_CP_SIC_BASE 0xCA000000 /* SIC */
+#define INTEGRATOR_CP_CTL_BASE 0xCB000000 /* CP system control */
+
+/* ------------------------------------------------------------------------
+ * KMI keyboard/mouse definitions
+ * ------------------------------------------------------------------------
+ */
+/* PS2 Keyboard interface */
+#define KMI0_BASE INTEGRATOR_KBD_BASE
+
+/* PS2 Mouse interface */
+#define KMI1_BASE INTEGRATOR_MOUSE_BASE
+
+/* KMI definitions are now in include/asm-arm/hardware/amba_kmi.h -- rmk */
+
+/* ------------------------------------------------------------------------
+ * Where in the memory map does PCI live?
+ * ------------------------------------------------------------------------
+ * This represents a fairly liberal usage of address space. Even though
+ * the V3 only has two windows (therefore we need to map stuff on the fly),
+ * we maintain the same addresses, even if they're not mapped.
+ *
+ */
+#define PHYS_PCI_MEM_BASE 0x40000000 /* 512M to xxx */
+/* unused 256M from A0000000-AFFFFFFF might be used for I2O ???
+ */
+#define PHYS_PCI_IO_BASE 0x60000000 /* 16M to xxx */
+/* unused (128-16)M from B1000000-B7FFFFFF
+ */
+#define PHYS_PCI_CONFIG_BASE 0x61000000 /* 16M to xxx */
+/* unused ((128-16)M - 64K) from XXX
+ */
+#define PHYS_PCI_V3_BASE 0x62000000
+
+/* ------------------------------------------------------------------------
+ * Integrator Interrupt Controllers
+ * ------------------------------------------------------------------------
+ *
+ * Offsets from interrupt controller base
+ *
+ * System Controller interrupt controller base is
+ *
+ * INTEGRATOR_IC_BASE + (header_number << 6)
+ *
+ * Core Module interrupt controller base is
+ *
+ * INTEGRATOR_HDR_IC
+ *
+ */
+#define IRQ_STATUS 0
+#define IRQ_RAW_STATUS 0x04
+#define IRQ_ENABLE 0x08
+#define IRQ_ENABLE_SET 0x08
+#define IRQ_ENABLE_CLEAR 0x0C
+
+#define INT_SOFT_SET 0x10
+#define INT_SOFT_CLEAR 0x14
+
+#define FIQ_STATUS 0x20
+#define FIQ_RAW_STATUS 0x24
+#define FIQ_ENABLE 0x28
+#define FIQ_ENABLE_SET 0x28
+#define FIQ_ENABLE_CLEAR 0x2C
+
+
+/* ------------------------------------------------------------------------
+ * Interrupts
+ * ------------------------------------------------------------------------
+ *
+ *
+ * Each Core Module has two interrupts controllers, one on the core module
+ * itself and one in the system controller on the motherboard. The
+ * READ_INT macro in target.s reads both interrupt controllers and returns
+ * a 32 bit bitmask, bits 0 to 23 are interrupts from the system controller
+ * and bits 24 to 31 are from the core module.
+ *
+ * The following definitions relate to the bitmask returned by READ_INT.
+ *
+ */
+
+/* ------------------------------------------------------------------------
+ * LED's
+ * ------------------------------------------------------------------------
+ *
+ */
+#define GREEN_LED 0x01
+#define YELLOW_LED 0x02
+#define RED_LED 0x04
+#define GREEN_LED_2 0x08
+#define ALL_LEDS 0x0F
+
+#define LED_BANK INTEGRATOR_DBG_LEDS
+
+/*
+ * Timer definitions
+ *
+ * Only use timer 1 & 2
+ * (both run at 24MHz and will need the clock divider set to 16).
+ *
+ * Timer 0 runs at bus frequency
+ */
+
+#define INTEGRATOR_TIMER0_BASE INTEGRATOR_CT_BASE
+#define INTEGRATOR_TIMER1_BASE (INTEGRATOR_CT_BASE + 0x100)
+#define INTEGRATOR_TIMER2_BASE (INTEGRATOR_CT_BASE + 0x200)
+
+#define TICKS_PER_uSEC 24
+
+/*
+ * These are useconds NOT ticks.
+ *
+ */
+#define mSEC_1 1000
+#define mSEC_10 (mSEC_1 * 10)
+
+#define INTEGRATOR_CSR_BASE 0x10000000
+#define INTEGRATOR_CSR_SIZE 0x10000000
+
+#endif
diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h
new file mode 100644
index 00000000..e1551b8d
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/system.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-integrator/include/mach/system.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/cm.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ cm_control(CM_CTRL_RESET, CM_CTRL_RESET);
+}
+
+#endif
diff --git a/arch/arm/mach-integrator/include/mach/timex.h b/arch/arm/mach-integrator/include/mach/timex.h
new file mode 100644
index 00000000..1dcb4202
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/timex.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-integrator/include/mach/timex.h
+ *
+ * Integrator architecture timex specifications
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+/*
+ * ??
+ */
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-integrator/include/mach/uncompress.h b/arch/arm/mach-integrator/include/mach/uncompress.h
new file mode 100644
index 00000000..30452f00
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-integrator/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+#define AMBA_UART_DR (*(volatile unsigned char *)0x16000000)
+#define AMBA_UART_LCRH (*(volatile unsigned char *)0x16000008)
+#define AMBA_UART_LCRM (*(volatile unsigned char *)0x1600000c)
+#define AMBA_UART_LCRL (*(volatile unsigned char *)0x16000010)
+#define AMBA_UART_CR (*(volatile unsigned char *)0x16000014)
+#define AMBA_UART_FR (*(volatile unsigned char *)0x16000018)
+
+/*
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = c;
+}
+
+static inline void flush(void)
+{
+ while (AMBA_UART_FR & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-integrator/include/mach/vmalloc.h b/arch/arm/mach-integrator/include/mach/vmalloc.h
new file mode 100644
index 00000000..2f5a2baf
--- /dev/null
+++ b/arch/arm/mach-integrator/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-integrator/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
new file mode 100644
index 00000000..fcf0ae95
--- /dev/null
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -0,0 +1,467 @@
+/*
+ * linux/arch/arm/mach-integrator/integrator_ap.c
+ *
+ * Copyright (C) 2000-2003 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/syscore_ops.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/param.h> /* HZ */
+#include <asm/mach-types.h>
+
+#include <mach/lm.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <plat/fpga-irq.h>
+
+#include "common.h"
+
+/*
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE __io_address(INTEGRATOR_IC_BASE)
+#define VA_SC_BASE __io_address(INTEGRATOR_SC_BASE)
+#define VA_EBI_BASE __io_address(INTEGRATOR_EBI_BASE)
+#define VA_CMIC_BASE __io_address(INTEGRATOR_HDR_IC)
+
+/*
+ * Logical Physical
+ * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
+ * ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
+ * ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
+ * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
+ * ef000000 Cache flush
+ * f1000000 10000000 Core module registers
+ * f1100000 11000000 System controller registers
+ * f1200000 12000000 EBI registers
+ * f1300000 13000000 Counter/Timer
+ * f1400000 14000000 Interrupt controller
+ * f1600000 16000000 UART 0
+ * f1700000 17000000 UART 1
+ * f1a00000 1a000000 Debug LEDs
+ * f1b00000 1b000000 GPIO
+ */
+
+static struct map_desc ap_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_AP_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_AP_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_MEMORY_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_MEM_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_CONFIG_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_CONFIG_BASE),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_V3_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = PCI_IO_VADDR,
+ .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init ap_map_io(void)
+{
+ iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
+}
+
+#define INTEGRATOR_SC_VALID_INT 0x003fffff
+
+static struct fpga_irq_data sc_irq_data = {
+ .base = VA_IC_BASE,
+ .irq_start = 0,
+ .chip.name = "SC",
+};
+
+static void __init ap_init_irq(void)
+{
+ /* Disable all interrupts initially. */
+ /* Do the core module ones */
+ writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+
+ /* do the header card stuff next */
+ writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+ fpga_irq_init(-1, INTEGRATOR_SC_VALID_INT, &sc_irq_data);
+}
+
+#ifdef CONFIG_PM
+static unsigned long ic_irq_enable;
+
+static int irq_suspend(void)
+{
+ ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
+ return 0;
+}
+
+static void irq_resume(void)
+{
+ /* disable all irq sources */
+ writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+ writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+ writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+#else
+#define irq_suspend NULL
+#define irq_resume NULL
+#endif
+
+static struct syscore_ops irq_syscore_ops = {
+ .suspend = irq_suspend,
+ .resume = irq_resume,
+};
+
+static int __init irq_syscore_init(void)
+{
+ register_syscore_ops(&irq_syscore_ops);
+
+ return 0;
+}
+
+device_initcall(irq_syscore_init);
+
+/*
+ * Flash handling.
+ */
+#define SC_CTRLC (VA_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define SC_CTRLS (VA_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+static int ap_flash_init(struct platform_device *dev)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+ tmp = readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, EBI_CSR1);
+
+ if (!(readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
+ writel(0xa05f, EBI_LOCK);
+ writel(tmp, EBI_CSR1);
+ writel(0, EBI_LOCK);
+ }
+ return 0;
+}
+
+static void ap_flash_exit(struct platform_device *dev)
+{
+ u32 tmp;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
+
+ tmp = readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
+ writel(tmp, EBI_CSR1);
+
+ if (readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
+ writel(0xa05f, EBI_LOCK);
+ writel(tmp, EBI_CSR1);
+ writel(0, EBI_LOCK);
+ }
+}
+
+static void ap_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
+
+ writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
+}
+
+static struct physmap_flash_data ap_flash_data = {
+ .width = 4,
+ .init = ap_flash_init,
+ .exit = ap_flash_exit,
+ .set_vpp = ap_flash_set_vpp,
+};
+
+static struct resource cfi_flash_resource = {
+ .start = INTEGRATOR_FLASH_BASE,
+ .end = INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cfi_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ap_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &cfi_flash_resource,
+};
+
+static void __init ap_init(void)
+{
+ unsigned long sc_dec;
+ int i;
+
+ platform_device_register(&cfi_flash_device);
+
+ sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET);
+ for (i = 0; i < 4; i++) {
+ struct lm_device *lmdev;
+
+ if ((sc_dec & (16 << i)) == 0)
+ continue;
+
+ lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
+ if (!lmdev)
+ continue;
+
+ lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
+ lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
+ lmdev->resource.flags = IORESOURCE_MEM;
+ lmdev->irq = IRQ_AP_EXPINT0 + i;
+ lmdev->id = i;
+
+ lm_device_register(lmdev);
+ }
+}
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE IO_ADDRESS(INTEGRATOR_TIMER2_BASE)
+
+/*
+ * How long is the timer interval?
+ */
+#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10)
+#if TIMER_INTERVAL >= 0x100000
+#define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC)
+#elif TIMER_INTERVAL >= 0x10000
+#define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC)
+#else
+#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
+#endif
+
+static unsigned long timer_reload;
+
+static void integrator_clocksource_init(u32 khz)
+{
+ void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
+ u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+
+ if (khz >= 1500) {
+ khz /= 16;
+ ctrl |= TIMER_CTRL_DIV16;
+ }
+
+ writel(0xffff, base + TIMER_LOAD);
+ writel(ctrl, base + TIMER_CTRL);
+
+ clocksource_mmio_init(base + TIMER_VALUE, "timer2",
+ khz * 1000, 200, 16, clocksource_mmio_readl_down);
+}
+
+static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* clear the interrupt */
+ writel(1, clkevt_base + TIMER_INTCLR);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+ u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
+
+ BUG_ON(mode == CLOCK_EVT_MODE_ONESHOT);
+
+ if (mode == CLOCK_EVT_MODE_PERIODIC) {
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+ writel(timer_reload, clkevt_base + TIMER_LOAD);
+ ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+ }
+
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+}
+
+static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
+{
+ unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+ writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+ writel(next, clkevt_base + TIMER_LOAD);
+ writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+ return 0;
+}
+
+static struct clock_event_device integrator_clockevent = {
+ .name = "timer1",
+ .shift = 34,
+ .features = CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = clkevt_set_mode,
+ .set_next_event = clkevt_set_next_event,
+ .rating = 300,
+ .cpumask = cpu_all_mask,
+};
+
+static struct irqaction integrator_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = integrator_timer_interrupt,
+ .dev_id = &integrator_clockevent,
+};
+
+static void integrator_clockevent_init(u32 khz)
+{
+ struct clock_event_device *evt = &integrator_clockevent;
+ unsigned int ctrl = 0;
+
+ if (khz * 1000 > 0x100000 * HZ) {
+ khz /= 256;
+ ctrl |= TIMER_CTRL_DIV256;
+ } else if (khz * 1000 > 0x10000 * HZ) {
+ khz /= 16;
+ ctrl |= TIMER_CTRL_DIV16;
+ }
+
+ timer_reload = khz * 1000 / HZ;
+ writel(ctrl, clkevt_base + TIMER_CTRL);
+
+ evt->irq = IRQ_TIMERINT1;
+ evt->mult = div_sc(khz, NSEC_PER_MSEC, evt->shift);
+ evt->max_delta_ns = clockevent_delta2ns(0xffff, evt);
+ evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
+
+ setup_irq(IRQ_TIMERINT1, &integrator_timer_irq);
+ clockevents_register_device(evt);
+}
+
+/*
+ * Set up timer(s).
+ */
+static void __init ap_init_timer(void)
+{
+ u32 khz = TICKS_PER_uSEC * 1000;
+
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+ integrator_clocksource_init(khz);
+ integrator_clockevent_init(khz);
+}
+
+static struct sys_timer ap_timer = {
+ .init = ap_init_timer,
+};
+
+MACHINE_START(INTEGRATOR, "ARM-Integrator")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = 0x00000100,
+ .reserve = integrator_reserve,
+ .map_io = ap_map_io,
+ .init_early = integrator_init_early,
+ .init_irq = ap_init_irq,
+ .timer = &ap_timer,
+ .init_machine = ap_init,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
new file mode 100644
index 00000000..4eb03ab5
--- /dev/null
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -0,0 +1,502 @@
+/*
+ * linux/arch/arm/mach-integrator/integrator_cp.c
+ *
+ * Copyright (C) 2003 Deep Blue Solutions 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.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/string.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
+#include <linux/amba/clcd.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/gfp.h>
+#include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.h>
+
+#include <mach/cm.h>
+#include <mach/lm.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <asm/hardware/timer-sp.h>
+
+#include <plat/clcd.h>
+#include <plat/fpga-irq.h>
+#include <plat/sched_clock.h>
+
+#include "common.h"
+
+#define INTCP_PA_FLASH_BASE 0x24000000
+#define INTCP_FLASH_SIZE SZ_32M
+
+#define INTCP_PA_CLCD_BASE 0xc0000000
+
+#define INTCP_VA_CIC_BASE __io_address(INTEGRATOR_HDR_BASE + 0x40)
+#define INTCP_VA_PIC_BASE __io_address(INTEGRATOR_IC_BASE)
+#define INTCP_VA_SIC_BASE __io_address(INTEGRATOR_CP_SIC_BASE)
+
+#define INTCP_ETH_SIZE 0x10
+
+#define INTCP_VA_CTRL_BASE IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)
+#define INTCP_FLASHPROG 0x04
+#define CINTEGRATOR_FLASHPROG_FLVPPEN (1 << 0)
+#define CINTEGRATOR_FLASHPROG_FLWREN (1 << 1)
+
+/*
+ * Logical Physical
+ * f1000000 10000000 Core module registers
+ * f1100000 11000000 System controller registers
+ * f1200000 12000000 EBI registers
+ * f1300000 13000000 Counter/Timer
+ * f1400000 14000000 Interrupt controller
+ * f1600000 16000000 UART 0
+ * f1700000 17000000 UART 1
+ * f1a00000 1a000000 Debug LEDs
+ * fc900000 c9000000 GPIO
+ * fca00000 ca000000 SIC
+ * fcb00000 cb000000 CP system control
+ */
+
+static struct map_desc intcp_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(INTEGRATOR_HDR_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_HDR_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_SC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_SC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_EBI_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_EBI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CT_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CT_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_IC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_IC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_UART1_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_UART1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_DBG_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_DBG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CP_GPIO_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CP_GPIO_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
+ .pfn = __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init intcp_map_io(void)
+{
+ iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
+}
+
+static struct fpga_irq_data cic_irq_data = {
+ .base = INTCP_VA_CIC_BASE,
+ .irq_start = IRQ_CIC_START,
+ .chip.name = "CIC",
+};
+
+static struct fpga_irq_data pic_irq_data = {
+ .base = INTCP_VA_PIC_BASE,
+ .irq_start = IRQ_PIC_START,
+ .chip.name = "PIC",
+};
+
+static struct fpga_irq_data sic_irq_data = {
+ .base = INTCP_VA_SIC_BASE,
+ .irq_start = IRQ_SIC_START,
+ .chip.name = "SIC",
+};
+
+static void __init intcp_init_irq(void)
+{
+ u32 pic_mask, sic_mask;
+
+ pic_mask = ~((~0u) << (11 - IRQ_PIC_START));
+ pic_mask |= (~((~0u) << (29 - 22))) << 22;
+ sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
+
+ /*
+ * Disable all interrupt sources
+ */
+ writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
+ writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
+ writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
+
+ fpga_irq_init(-1, pic_mask, &pic_irq_data);
+
+ fpga_irq_init(-1, ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)),
+ &cic_irq_data);
+
+ fpga_irq_init(IRQ_CP_CPPLDINT, sic_mask, &sic_irq_data);
+}
+
+/*
+ * Clock handling
+ */
+#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
+#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c)
+
+static const struct icst_params cp_auxvco_params = {
+ .ref = 24000000,
+ .vco_max = ICST525_VCO_MAX_5V,
+ .vco_min = ICST525_VCO_MIN,
+ .vd_min = 8,
+ .vd_max = 263,
+ .rd_min = 3,
+ .rd_max = 65,
+ .s2div = icst525_s2div,
+ .idx2s = icst525_idx2s,
+};
+
+static void cp_auxvco_set(struct clk *clk, struct icst_vco vco)
+{
+ u32 val;
+
+ val = readl(clk->vcoreg) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, CM_LOCK);
+ writel(val, clk->vcoreg);
+ writel(0, CM_LOCK);
+}
+
+static const struct clk_ops cp_auxclk_ops = {
+ .round = icst_clk_round,
+ .set = icst_clk_set,
+ .setvco = cp_auxvco_set,
+};
+
+static struct clk cp_auxclk = {
+ .ops = &cp_auxclk_ops,
+ .params = &cp_auxvco_params,
+ .vcoreg = CM_AUXOSC,
+};
+
+static struct clk sp804_clk = {
+ .rate = 1000000,
+};
+
+static struct clk_lookup cp_lookups[] = {
+ { /* CLCD */
+ .dev_id = "mb:c0",
+ .clk = &cp_auxclk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .clk = &sp804_clk,
+ },
+};
+
+/*
+ * Flash handling.
+ */
+static int intcp_flash_init(struct platform_device *dev)
+{
+ u32 val;
+
+ val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+ val |= CINTEGRATOR_FLASHPROG_FLWREN;
+ writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+
+ return 0;
+}
+
+static void intcp_flash_exit(struct platform_device *dev)
+{
+ u32 val;
+
+ val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+ val &= ~(CINTEGRATOR_FLASHPROG_FLVPPEN|CINTEGRATOR_FLASHPROG_FLWREN);
+ writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+}
+
+static void intcp_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ u32 val;
+
+ val = readl(INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+ if (on)
+ val |= CINTEGRATOR_FLASHPROG_FLVPPEN;
+ else
+ val &= ~CINTEGRATOR_FLASHPROG_FLVPPEN;
+ writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
+}
+
+static struct physmap_flash_data intcp_flash_data = {
+ .width = 4,
+ .init = intcp_flash_init,
+ .exit = intcp_flash_exit,
+ .set_vpp = intcp_flash_set_vpp,
+};
+
+static struct resource intcp_flash_resource = {
+ .start = INTCP_PA_FLASH_BASE,
+ .end = INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device intcp_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &intcp_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &intcp_flash_resource,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = INTEGRATOR_CP_ETH_BASE,
+ .end = INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CP_ETHINT,
+ .end = IRQ_CP_ETHINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *intcp_devs[] __initdata = {
+ &intcp_flash_device,
+ &smc91x_device,
+};
+
+/*
+ * It seems that the card insertion interrupt remains active after
+ * we've acknowledged it. We therefore ignore the interrupt, and
+ * rely on reading it from the SIC. This also means that we must
+ * clear the latched interrupt.
+ */
+static unsigned int mmc_status(struct device *dev)
+{
+ unsigned int status = readl(IO_ADDRESS(0xca000000 + 4));
+ writel(8, IO_ADDRESS(INTEGRATOR_CP_CTL_BASE + 8));
+
+ return status & 8;
+}
+
+static struct mmci_platform_data mmc_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = mmc_status,
+ .gpio_wp = -1,
+ .gpio_cd = -1,
+};
+
+static struct amba_device mmc_device = {
+ .dev = {
+ .init_name = "mb:1c",
+ .platform_data = &mmc_data,
+ },
+ .res = {
+ .start = INTEGRATOR_CP_MMC_BASE,
+ .end = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
+ .periphid = 0,
+};
+
+static struct amba_device aaci_device = {
+ .dev = {
+ .init_name = "mb:1d",
+ },
+ .res = {
+ .start = INTEGRATOR_CP_AACI_BASE,
+ .end = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_CP_AACIINT, NO_IRQ },
+ .periphid = 0,
+};
+
+
+/*
+ * CLCD support
+ */
+/*
+ * Ensure VGA is selected.
+ */
+static void cp_clcd_enable(struct clcd_fb *fb)
+{
+ struct fb_var_screeninfo *var = &fb->fb.var;
+ u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
+
+ if (var->bits_per_pixel <= 8 ||
+ (var->bits_per_pixel == 16 && var->green.length == 5))
+ /* Pseudocolor, RGB555, BGR555 */
+ val |= CM_CTRL_LCDMUXSEL_VGA555_TFT555;
+ else if (fb->fb.var.bits_per_pixel <= 16)
+ /* truecolor RGB565 */
+ val |= CM_CTRL_LCDMUXSEL_VGA565_TFT555;
+ else
+ val = 0; /* no idea for this, don't trust the docs */
+
+ cm_control(CM_CTRL_LCDMUXSEL_MASK|
+ CM_CTRL_LCDEN0|
+ CM_CTRL_LCDEN1|
+ CM_CTRL_STATIC1|
+ CM_CTRL_STATIC2|
+ CM_CTRL_STATIC|
+ CM_CTRL_n24BITEN, val);
+}
+
+static int cp_clcd_setup(struct clcd_fb *fb)
+{
+ fb->panel = versatile_clcd_get_panel("VGA");
+ if (!fb->panel)
+ return -EINVAL;
+
+ return versatile_clcd_setup_dma(fb, SZ_1M);
+}
+
+static struct clcd_board clcd_data = {
+ .name = "Integrator/CP",
+ .caps = CLCD_CAP_5551 | CLCD_CAP_RGB565 | CLCD_CAP_888,
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .enable = cp_clcd_enable,
+ .setup = cp_clcd_setup,
+ .mmap = versatile_clcd_mmap_dma,
+ .remove = versatile_clcd_remove_dma,
+};
+
+static struct amba_device clcd_device = {
+ .dev = {
+ .init_name = "mb:c0",
+ .coherent_dma_mask = ~0,
+ .platform_data = &clcd_data,
+ },
+ .res = {
+ .start = INTCP_PA_CLCD_BASE,
+ .end = INTCP_PA_CLCD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .dma_mask = ~0,
+ .irq = { IRQ_CP_CLCDCINT, NO_IRQ },
+ .periphid = 0,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &mmc_device,
+ &aaci_device,
+ &clcd_device,
+};
+
+#define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)
+
+static void __init intcp_init_early(void)
+{
+ clkdev_add_table(cp_lookups, ARRAY_SIZE(cp_lookups));
+
+ integrator_init_early();
+
+#ifdef CONFIG_PLAT_VERSATILE_SCHED_CLOCK
+ versatile_sched_clock_init(REFCOUNTER, 24000000);
+#endif
+}
+
+static void __init intcp_init(void)
+{
+ int i;
+
+ platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+}
+
+#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
+#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
+#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
+
+static void __init intcp_timer_init(void)
+{
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+
+ sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
+ sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
+}
+
+static struct sys_timer cp_timer = {
+ .init = intcp_timer_init,
+};
+
+MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = 0x00000100,
+ .reserve = integrator_reserve,
+ .map_io = intcp_map_io,
+ .init_early = intcp_init_early,
+ .init_irq = intcp_init_irq,
+ .timer = &cp_timer,
+ .init_machine = intcp_init,
+MACHINE_END
diff --git a/arch/arm/mach-integrator/leds.c b/arch/arm/mach-integrator/leds.c
new file mode 100644
index 00000000..28be186a
--- /dev/null
+++ b/arch/arm/mach-integrator/leds.c
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/arm/mach-integrator/leds.c
+ *
+ * Integrator/AP and Integrator/CP LED control routines
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+#include <mach/cm.h>
+
+static int saved_leds;
+
+static void integrator_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ const unsigned int dbg_base = IO_ADDRESS(INTEGRATOR_DBG_BASE);
+ unsigned int update_alpha_leds;
+
+ // yup, change the LEDs
+ local_irq_save(flags);
+ update_alpha_leds = 0;
+
+ switch(ledevt) {
+ case led_idle_start:
+ cm_control(CM_CTRL_LED, 0);
+ break;
+
+ case led_idle_end:
+ cm_control(CM_CTRL_LED, CM_CTRL_LED);
+ break;
+
+ case led_timer:
+ saved_leds ^= GREEN_LED;
+ update_alpha_leds = 1;
+ break;
+
+ case led_red_on:
+ saved_leds |= RED_LED;
+ update_alpha_leds = 1;
+ break;
+
+ case led_red_off:
+ saved_leds &= ~RED_LED;
+ update_alpha_leds = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (update_alpha_leds) {
+ while (__raw_readl(dbg_base + INTEGRATOR_DBG_ALPHA_OFFSET) & 1);
+ __raw_writel(saved_leds, dbg_base + INTEGRATOR_DBG_LEDS_OFFSET);
+ }
+ local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_integrator() || machine_is_cintegrator())
+ leds_event = integrator_leds_event;
+
+ return 0;
+}
+
+core_initcall(leds_init);
diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
new file mode 100644
index 00000000..f52c7af3
--- /dev/null
+++ b/arch/arm/mach-integrator/lm.c
@@ -0,0 +1,99 @@
+/*
+ * linux/arch/arm/mach-integrator/lm.c
+ *
+ * Copyright (C) 2003 Deep Blue Solutions 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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <mach/lm.h>
+
+#define to_lm_device(d) container_of(d, struct lm_device, dev)
+#define to_lm_driver(d) container_of(d, struct lm_driver, drv)
+
+static int lm_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static int lm_bus_probe(struct device *dev)
+{
+ struct lm_device *lmdev = to_lm_device(dev);
+ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
+
+ return lmdrv->probe(lmdev);
+}
+
+static int lm_bus_remove(struct device *dev)
+{
+ struct lm_device *lmdev = to_lm_device(dev);
+ struct lm_driver *lmdrv = to_lm_driver(dev->driver);
+
+ if (lmdrv->remove)
+ lmdrv->remove(lmdev);
+ return 0;
+}
+
+static struct bus_type lm_bustype = {
+ .name = "logicmodule",
+ .match = lm_match,
+ .probe = lm_bus_probe,
+ .remove = lm_bus_remove,
+// .suspend = lm_bus_suspend,
+// .resume = lm_bus_resume,
+};
+
+static int __init lm_init(void)
+{
+ return bus_register(&lm_bustype);
+}
+
+postcore_initcall(lm_init);
+
+int lm_driver_register(struct lm_driver *drv)
+{
+ drv->drv.bus = &lm_bustype;
+ return driver_register(&drv->drv);
+}
+
+void lm_driver_unregister(struct lm_driver *drv)
+{
+ driver_unregister(&drv->drv);
+}
+
+static void lm_device_release(struct device *dev)
+{
+ struct lm_device *d = to_lm_device(dev);
+
+ kfree(d);
+}
+
+int lm_device_register(struct lm_device *dev)
+{
+ int ret;
+
+ dev->dev.release = lm_device_release;
+ dev->dev.bus = &lm_bustype;
+
+ ret = dev_set_name(&dev->dev, "lm%d", dev->id);
+ if (ret)
+ return ret;
+ dev->resource.name = dev_name(&dev->dev);
+
+ ret = request_resource(&iomem_resource, &dev->resource);
+ if (ret == 0) {
+ ret = device_register(&dev->dev);
+ if (ret)
+ release_resource(&dev->resource);
+ }
+ return ret;
+}
+
+EXPORT_SYMBOL(lm_driver_register);
+EXPORT_SYMBOL(lm_driver_unregister);
diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
new file mode 100644
index 00000000..2fdb9543
--- /dev/null
+++ b/arch/arm/mach-integrator/pci.c
@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/mach-integrator/pci-integrator.c
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ *
+ *
+ * PCI functions for Integrator
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * A small note about bridges and interrupts. The DECchip 21050 (and
+ * later) adheres to the PCI-PCI bridge specification. This says that
+ * the interrupts on the other side of a bridge are swizzled in the
+ * following manner:
+ *
+ * Dev Interrupt Interrupt
+ * Pin on Pin on
+ * Device Connector
+ *
+ * 4 A A
+ * B B
+ * C C
+ * D D
+ *
+ * 5 A B
+ * B C
+ * C D
+ * D A
+ *
+ * 6 A C
+ * B D
+ * C A
+ * D B
+ *
+ * 7 A D
+ * B A
+ * C B
+ * D C
+ *
+ * Where A = pin 1, B = pin 2 and so on and pin=0 = default = A.
+ * Thus, each swizzle is ((pin-1) + (device#-4)) % 4
+ */
+
+/*
+ * This routine handles multiple bridges.
+ */
+static u8 __init integrator_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ int pin = *pinp;
+
+ if (pin == 0)
+ pin = 1;
+
+ while (dev->bus->self) {
+ pin = pci_swizzle_interrupt_pin(dev, pin);
+ /*
+ * move up the chain of bridges, swizzling as we go.
+ */
+ dev = dev->bus->self;
+ }
+ *pinp = pin;
+
+ return PCI_SLOT(dev->devfn);
+}
+
+static int irq_tab[4] __initdata = {
+ IRQ_AP_PCIINT0, IRQ_AP_PCIINT1, IRQ_AP_PCIINT2, IRQ_AP_PCIINT3
+};
+
+/*
+ * map the specified device/slot/pin to an IRQ. This works out such
+ * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
+ */
+static int __init integrator_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int intnr = ((slot - 9) + (pin - 1)) & 3;
+
+ return irq_tab[intnr];
+}
+
+extern void pci_v3_init(void *);
+
+static struct hw_pci integrator_pci __initdata = {
+ .swizzle = integrator_swizzle,
+ .map_irq = integrator_map_irq,
+ .setup = pci_v3_setup,
+ .nr_controllers = 1,
+ .scan = pci_v3_scan_bus,
+ .preinit = pci_v3_preinit,
+ .postinit = pci_v3_postinit,
+};
+
+static int __init integrator_pci_init(void)
+{
+ if (machine_is_integrator())
+ pci_common_init(&integrator_pci);
+ return 0;
+}
+
+subsys_initcall(integrator_pci_init);
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
new file mode 100644
index 00000000..6467d99f
--- /dev/null
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -0,0 +1,609 @@
+/*
+ * linux/arch/arm/mach-integrator/pci_v3.c
+ *
+ * PCI functions for V3 host PCI bridge
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000-2001 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/pci.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/irq.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/irq_regs.h>
+
+#include <asm/hardware/pci_v3.h>
+
+/*
+ * The V3 PCI interface chip in Integrator provides several windows from
+ * local bus memory into the PCI memory areas. Unfortunately, there
+ * are not really enough windows for our usage, therefore we reuse
+ * one of the windows for access to PCI configuration space. The
+ * memory map is as follows:
+ *
+ * Local Bus Memory Usage
+ *
+ * 40000000 - 4FFFFFFF PCI memory. 256M non-prefetchable
+ * 50000000 - 5FFFFFFF PCI memory. 256M prefetchable
+ * 60000000 - 60FFFFFF PCI IO. 16M
+ * 61000000 - 61FFFFFF PCI Configuration. 16M
+ *
+ * There are three V3 windows, each described by a pair of V3 registers.
+ * These are LB_BASE0/LB_MAP0, LB_BASE1/LB_MAP1 and LB_BASE2/LB_MAP2.
+ * Base0 and Base1 can be used for any type of PCI memory access. Base2
+ * can be used either for PCI I/O or for I20 accesses. By default, uHAL
+ * uses this only for PCI IO space.
+ *
+ * Normally these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
+ * Mem 50000000 - 5FFFFFFF LB_BASE1/LB_MAP1
+ * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
+ * Cfg 61000000 - 61FFFFFF
+ *
+ * This means that I20 and PCI configuration space accesses will fail.
+ * When PCI configuration accesses are needed (via the uHAL PCI
+ * configuration space primitives) we must remap the spaces as follows:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 40000000 - 4FFFFFFF LB_BASE0/LB_MAP0
+ * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0
+ * IO 60000000 - 60FFFFFF LB_BASE2/LB_MAP2
+ * Cfg 61000000 - 61FFFFFF LB_BASE1/LB_MAP1
+ *
+ * To make this work, the code depends on overlapping windows working.
+ * The V3 chip translates an address by checking its range within
+ * each of the BASE/MAP pairs in turn (in ascending register number
+ * order). It will use the first matching pair. So, for example,
+ * if the same address is mapped by both LB_BASE0/LB_MAP0 and
+ * LB_BASE1/LB_MAP1, the V3 will use the translation from
+ * LB_BASE0/LB_MAP0.
+ *
+ * To allow PCI Configuration space access, the code enlarges the
+ * window mapped by LB_BASE0/LB_MAP0 from 256M to 512M. This occludes
+ * the windows currently mapped by LB_BASE1/LB_MAP1 so that it can
+ * be remapped for use by configuration cycles.
+ *
+ * At the end of the PCI Configuration space accesses,
+ * LB_BASE1/LB_MAP1 is reset to map PCI Memory. Finally the window
+ * mapped by LB_BASE0/LB_MAP0 is reduced in size from 512M to 256M to
+ * reveal the now restored LB_BASE1/LB_MAP1 window.
+ *
+ * NOTE: We do not set up I2O mapping. I suspect that this is only
+ * for an intelligent (target) device. Using I2O disables most of
+ * the mappings into PCI memory.
+ */
+
+// V3 access routines
+#define v3_writeb(o,v) __raw_writeb(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readb(o) (__raw_readb(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define v3_writew(o,v) __raw_writew(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readw(o) (__raw_readw(PCI_V3_VADDR + (unsigned int)(o)))
+
+#define v3_writel(o,v) __raw_writel(v, PCI_V3_VADDR + (unsigned int)(o))
+#define v3_readl(o) (__raw_readl(PCI_V3_VADDR + (unsigned int)(o)))
+
+/*============================================================================
+ *
+ * routine: uHALir_PCIMakeConfigAddress()
+ *
+ * parameters: bus = which bus
+ * device = which device
+ * function = which function
+ * offset = configuration space register we are interested in
+ *
+ * description: this routine will generate a platform dependent config
+ * address.
+ *
+ * calls: none
+ *
+ * returns: configuration address to play on the PCI bus
+ *
+ * To generate the appropriate PCI configuration cycles in the PCI
+ * configuration address space, you present the V3 with the following pattern
+ * (which is very nearly a type 1 (except that the lower two bits are 00 and
+ * not 01). In order for this mapping to work you need to set up one of
+ * the local to PCI aperatures to 16Mbytes in length translating to
+ * PCI configuration space starting at 0x0000.0000.
+ *
+ * PCI configuration cycles look like this:
+ *
+ * Type 0:
+ *
+ * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
+ * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 31:11 Device select bit.
+ * 10:8 Function number
+ * 7:2 Register number
+ *
+ * Type 1:
+ *
+ * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
+ * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 31:24 reserved
+ * 23:16 bus number (8 bits = 128 possible buses)
+ * 15:11 Device number (5 bits)
+ * 10:8 function number
+ * 7:2 register number
+ *
+ */
+static DEFINE_SPINLOCK(v3_lock);
+
+#define PCI_BUS_NONMEM_START 0x00000000
+#define PCI_BUS_NONMEM_SIZE SZ_256M
+
+#define PCI_BUS_PREMEM_START PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE
+#define PCI_BUS_PREMEM_SIZE SZ_256M
+
+#if PCI_BUS_NONMEM_START & 0x000fffff
+#error PCI_BUS_NONMEM_START must be megabyte aligned
+#endif
+#if PCI_BUS_PREMEM_START & 0x000fffff
+#error PCI_BUS_PREMEM_START must be megabyte aligned
+#endif
+
+#undef V3_LB_BASE_PREFETCH
+#define V3_LB_BASE_PREFETCH 0
+
+static unsigned long v3_open_config_window(struct pci_bus *bus,
+ unsigned int devfn, int offset)
+{
+ unsigned int address, mapaddress, busnr;
+
+ busnr = bus->number;
+
+ /*
+ * Trap out illegal values
+ */
+ if (offset > 255)
+ BUG();
+ if (busnr > 255)
+ BUG();
+ if (devfn > 255)
+ BUG();
+
+ if (busnr == 0) {
+ int slot = PCI_SLOT(devfn);
+
+ /*
+ * local bus segment so need a type 0 config cycle
+ *
+ * build the PCI configuration "address" with one-hot in
+ * A31-A11
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 are 0 (0)
+ */
+ address = PCI_FUNC(devfn) << 8;
+ mapaddress = V3_LB_MAP_TYPE_CONFIG;
+
+ if (slot > 12)
+ /*
+ * high order bits are handled by the MAP register
+ */
+ mapaddress |= 1 << (slot - 5);
+ else
+ /*
+ * low order bits handled directly in the address
+ */
+ address |= 1 << (slot + 11);
+ } else {
+ /*
+ * not the local bus segment so need a type 1 config cycle
+ *
+ * address:
+ * 23:16 = bus number
+ * 15:11 = slot number (7:3 of devfn)
+ * 10:8 = func number (2:0 of devfn)
+ *
+ * mapaddress:
+ * 3:1 = config cycle (101)
+ * 0 = PCI A1 & A0 from host bus (1)
+ */
+ mapaddress = V3_LB_MAP_TYPE_CONFIG | V3_LB_MAP_AD_LOW_EN;
+ address = (busnr << 16) | (devfn << 8);
+ }
+
+ /*
+ * Set up base0 to see all 512Mbytes of memory space (not
+ * prefetchable), this frees up base1 for re-use by
+ * configuration memory
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_512MB | V3_LB_BASE_ENABLE);
+
+ /*
+ * Set up base1/map1 to point into configuration space.
+ */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_CONFIG_BASE) |
+ V3_LB_BASE_ADR_SIZE_16MB | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, mapaddress);
+
+ return PCI_CONFIG_VADDR + address + offset;
+}
+
+static void v3_close_config_window(void)
+{
+ /*
+ * Reassign base1 for use by prefetchable PCI memory
+ */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+ /*
+ * And shrink base0 back to a 256M window (NOTE: MAP0 already correct)
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+}
+
+static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ unsigned long addr;
+ unsigned long flags;
+ u32 v;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(bus, devfn, where);
+
+ switch (size) {
+ case 1:
+ v = __raw_readb(addr);
+ break;
+
+ case 2:
+ v = __raw_readw(addr);
+ break;
+
+ default:
+ v = __raw_readl(addr);
+ break;
+ }
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ unsigned long addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v3_lock, flags);
+ addr = v3_open_config_window(bus, devfn, where);
+
+ switch (size) {
+ case 1:
+ __raw_writeb((u8)val, addr);
+ __raw_readb(addr);
+ break;
+
+ case 2:
+ __raw_writew((u16)val, addr);
+ __raw_readw(addr);
+ break;
+
+ case 4:
+ __raw_writel(val, addr);
+ __raw_readl(addr);
+ break;
+ }
+
+ v3_close_config_window();
+ spin_unlock_irqrestore(&v3_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_v3_ops = {
+ .read = v3_read_config,
+ .write = v3_write_config,
+};
+
+static struct resource non_mem = {
+ .name = "PCI non-prefetchable",
+ .start = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
+ .end = PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+ .name = "PCI prefetchable",
+ .start = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
+ .end = PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_v3_setup_resources(struct resource **resource)
+{
+ if (request_resource(&iomem_resource, &non_mem)) {
+ printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+ "memory region\n");
+ return -EBUSY;
+ }
+ if (request_resource(&iomem_resource, &pre_mem)) {
+ release_resource(&non_mem);
+ printk(KERN_ERR "PCI: unable to allocate prefetchable "
+ "memory region\n");
+ return -EBUSY;
+ }
+
+ /*
+ * bus->resource[0] is the IO resource for this bus
+ * bus->resource[1] is the mem resource for this bus
+ * bus->resource[2] is the prefetch mem resource for this bus
+ */
+ resource[0] = &ioport_resource;
+ resource[1] = &non_mem;
+ resource[2] = &pre_mem;
+
+ return 1;
+}
+
+/*
+ * These don't seem to be implemented on the Integrator I have, which
+ * means I can't get additional information on the reason for the pm2fb
+ * problems. I suppose I'll just have to mind-meld with the machine. ;)
+ */
+#define SC_PCI IO_ADDRESS(INTEGRATOR_SC_PCIENABLE)
+#define SC_LBFADDR IO_ADDRESS(INTEGRATOR_SC_BASE + 0x20)
+#define SC_LBFCODE IO_ADDRESS(INTEGRATOR_SC_BASE + 0x24)
+
+static int
+v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+ unsigned long instr = *(unsigned long *)pc;
+#if 0
+ char buf[128];
+
+ sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
+ addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
+ v3_readb(V3_LB_ISTAT));
+ printk(KERN_DEBUG "%s", buf);
+#endif
+
+ v3_writeb(V3_LB_ISTAT, 0);
+ __raw_writel(3, SC_PCI);
+
+ /*
+ * If the instruction being executed was a read,
+ * make it look like it read all-ones.
+ */
+ if ((instr & 0x0c100000) == 0x04100000) {
+ int reg = (instr >> 12) & 15;
+ unsigned long val;
+
+ if (instr & 0x00400000)
+ val = 255;
+ else
+ val = -1;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+
+ if ((instr & 0x0e100090) == 0x00100090) {
+ int reg = (instr >> 12) & 15;
+
+ regs->uregs[reg] = -1;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+
+ return 1;
+}
+
+static irqreturn_t v3_irq(int dummy, void *devid)
+{
+#ifdef CONFIG_DEBUG_LL
+ struct pt_regs *regs = get_irq_regs();
+ unsigned long pc = instruction_pointer(regs);
+ unsigned long instr = *(unsigned long *)pc;
+ char buf[128];
+ extern void printascii(const char *);
+
+ sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
+ "ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
+ __raw_readl(SC_LBFADDR),
+ __raw_readl(SC_LBFCODE) & 255,
+ v3_readb(V3_LB_ISTAT));
+ printascii(buf);
+#endif
+
+ v3_writew(V3_PCI_STAT, 0xf000);
+ v3_writeb(V3_LB_ISTAT, 0);
+ __raw_writel(3, SC_PCI);
+
+#ifdef CONFIG_DEBUG_LL
+ /*
+ * If the instruction being executed was a read,
+ * make it look like it read all-ones.
+ */
+ if ((instr & 0x0c100000) == 0x04100000) {
+ int reg = (instr >> 16) & 15;
+ sprintf(buf, " reg%d = %08lx\n", reg, regs->uregs[reg]);
+ printascii(buf);
+ }
+#endif
+ return IRQ_HANDLED;
+}
+
+int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ if (nr == 0) {
+ sys->mem_offset = PHYS_PCI_MEM_BASE;
+ ret = pci_v3_setup_resources(sys->resource);
+ }
+
+ return ret;
+}
+
+struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
+}
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP? - pci bus address
+ */
+void __init pci_v3_preinit(void)
+{
+ unsigned long flags;
+ unsigned int temp;
+ int ret;
+
+ /*
+ * Hook in our fault handler for PCI errors
+ */
+ hook_fault_code(4, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
+ hook_fault_code(6, v3_pci_fault, SIGBUS, 0, "external abort on linefetch");
+ hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+ hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+
+ spin_lock_irqsave(&v3_lock, flags);
+
+ /*
+ * Unlock V3 registers, but only if they were previously locked.
+ */
+ if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
+ v3_writew(V3_SYSTEM, 0xa05f);
+
+ /*
+ * Setup window 0 - PCI non-prefetchable memory
+ * Local: 0x40000000 Bus: 0x00000000 Size: 256MB
+ */
+ v3_writel(V3_LB_BASE0, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP0, v3_addr_to_lb_map(PCI_BUS_NONMEM_START) |
+ V3_LB_MAP_TYPE_MEM);
+
+ /*
+ * Setup window 1 - PCI prefetchable memory
+ * Local: 0x50000000 Bus: 0x10000000 Size: 256MB
+ */
+ v3_writel(V3_LB_BASE1, v3_addr_to_lb_base(PHYS_PCI_MEM_BASE + SZ_256M) |
+ V3_LB_BASE_ADR_SIZE_256MB | V3_LB_BASE_PREFETCH |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP1, v3_addr_to_lb_map(PCI_BUS_PREMEM_START) |
+ V3_LB_MAP_TYPE_MEM_MULTIPLE);
+
+ /*
+ * Setup window 2 - PCI IO
+ */
+ v3_writel(V3_LB_BASE2, v3_addr_to_lb_base2(PHYS_PCI_IO_BASE) |
+ V3_LB_BASE_ENABLE);
+ v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
+
+ /*
+ * Disable PCI to host IO cycles
+ */
+ temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN;
+ temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS;
+ v3_writew(V3_PCI_CFG, temp);
+
+ printk(KERN_DEBUG "FIFO_CFG: %04x FIFO_PRIO: %04x\n",
+ v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY));
+
+ /*
+ * Set the V3 FIFO such that writes have higher priority than
+ * reads, and local bus write causes local bus read fifo flush.
+ * Same for PCI.
+ */
+ v3_writew(V3_FIFO_PRIORITY, 0x0a0a);
+
+ /*
+ * Re-lock the system register.
+ */
+ temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK;
+ v3_writew(V3_SYSTEM, temp);
+
+ /*
+ * Clear any error conditions, and enable write errors.
+ */
+ v3_writeb(V3_LB_ISTAT, 0);
+ v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
+ v3_writeb(V3_LB_IMASK, 0x28);
+ __raw_writel(3, SC_PCI);
+
+ /*
+ * Grab the PCI error interrupt.
+ */
+ ret = request_irq(IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
+ if (ret)
+ printk(KERN_ERR "PCI: unable to grab PCI error "
+ "interrupt: %d\n", ret);
+
+ spin_unlock_irqrestore(&v3_lock, flags);
+}
+
+void __init pci_v3_postinit(void)
+{
+ unsigned int pci_cmd;
+
+ pci_cmd = PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+ v3_writew(V3_PCI_CMD, pci_cmd);
+
+ v3_writeb(V3_LB_ISTAT, ~0x40);
+ v3_writeb(V3_LB_IMASK, 0x68);
+
+#if 0
+ ret = request_irq(IRQ_AP_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
+ if (ret)
+ printk(KERN_ERR "PCI: unable to grab local bus timeout "
+ "interrupt: %d\n", ret);
+#endif
+
+ register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
+}
diff --git a/arch/arm/mach-iop13xx/Kconfig b/arch/arm/mach-iop13xx/Kconfig
new file mode 100644
index 00000000..40c2d689
--- /dev/null
+++ b/arch/arm/mach-iop13xx/Kconfig
@@ -0,0 +1,20 @@
+if ARCH_IOP13XX
+
+menu "IOP13XX Implementation Options"
+
+comment "IOP13XX Platform Support"
+
+config MACH_IQ81340SC
+ bool "Enable IQ81340SC Hardware Support"
+ help
+ Say Y here if you want to support running on the Intel IQ81340SC
+ evaluation kit.
+
+config MACH_IQ81340MC
+ bool "Enable IQ81340MC Hardware Support"
+ help
+ Say Y here if you want to support running on the Intel IQ81340MC
+ evaluation kit.
+
+endmenu
+endif
diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile
new file mode 100644
index 00000000..cad015fe
--- /dev/null
+++ b/arch/arm/mach-iop13xx/Makefile
@@ -0,0 +1,13 @@
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_IOP13XX) += setup.o
+obj-$(CONFIG_ARCH_IOP13XX) += irq.o
+obj-$(CONFIG_ARCH_IOP13XX) += pci.o
+obj-$(CONFIG_ARCH_IOP13XX) += io.o
+obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o
+obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
+obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o
+obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/arm/mach-iop13xx/Makefile.boot b/arch/arm/mach-iop13xx/Makefile.boot
new file mode 100644
index 00000000..0b0e19fd
--- /dev/null
+++ b/arch/arm/mach-iop13xx/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-iop13xx/include/mach/adma.h b/arch/arm/mach-iop13xx/include/mach/adma.h
new file mode 100644
index 00000000..6d3782d8
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/adma.h
@@ -0,0 +1,647 @@
+/*
+ * Copyright(c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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.
+ *
+ */
+#ifndef _ADMA_H
+#define _ADMA_H
+#include <linux/types.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iop_adma.h>
+
+#define ADMA_ACCR(chan) (chan->mmr_base + 0x0)
+#define ADMA_ACSR(chan) (chan->mmr_base + 0x4)
+#define ADMA_ADAR(chan) (chan->mmr_base + 0x8)
+#define ADMA_IIPCR(chan) (chan->mmr_base + 0x18)
+#define ADMA_IIPAR(chan) (chan->mmr_base + 0x1c)
+#define ADMA_IIPUAR(chan) (chan->mmr_base + 0x20)
+#define ADMA_ANDAR(chan) (chan->mmr_base + 0x24)
+#define ADMA_ADCR(chan) (chan->mmr_base + 0x28)
+#define ADMA_CARMD(chan) (chan->mmr_base + 0x2c)
+#define ADMA_ABCR(chan) (chan->mmr_base + 0x30)
+#define ADMA_DLADR(chan) (chan->mmr_base + 0x34)
+#define ADMA_DUADR(chan) (chan->mmr_base + 0x38)
+#define ADMA_SLAR(src, chan) (chan->mmr_base + (0x3c + (src << 3)))
+#define ADMA_SUAR(src, chan) (chan->mmr_base + (0x40 + (src << 3)))
+
+struct iop13xx_adma_src {
+ u32 src_addr;
+ union {
+ u32 upper_src_addr;
+ struct {
+ unsigned int pq_upper_src_addr:24;
+ unsigned int pq_dmlt:8;
+ };
+ };
+};
+
+struct iop13xx_adma_desc_ctrl {
+ unsigned int int_en:1;
+ unsigned int xfer_dir:2;
+ unsigned int src_select:4;
+ unsigned int zero_result:1;
+ unsigned int block_fill_en:1;
+ unsigned int crc_gen_en:1;
+ unsigned int crc_xfer_dis:1;
+ unsigned int crc_seed_fetch_dis:1;
+ unsigned int status_write_back_en:1;
+ unsigned int endian_swap_en:1;
+ unsigned int reserved0:2;
+ unsigned int pq_update_xfer_en:1;
+ unsigned int dual_xor_en:1;
+ unsigned int pq_xfer_en:1;
+ unsigned int p_xfer_dis:1;
+ unsigned int reserved1:10;
+ unsigned int relax_order_en:1;
+ unsigned int no_snoop_en:1;
+};
+
+struct iop13xx_adma_byte_count {
+ unsigned int byte_count:24;
+ unsigned int host_if:3;
+ unsigned int reserved:2;
+ unsigned int zero_result_err_q:1;
+ unsigned int zero_result_err:1;
+ unsigned int tx_complete:1;
+};
+
+struct iop13xx_adma_desc_hw {
+ u32 next_desc;
+ union {
+ u32 desc_ctrl;
+ struct iop13xx_adma_desc_ctrl desc_ctrl_field;
+ };
+ union {
+ u32 crc_addr;
+ u32 block_fill_data;
+ u32 q_dest_addr;
+ };
+ union {
+ u32 byte_count;
+ struct iop13xx_adma_byte_count byte_count_field;
+ };
+ union {
+ u32 dest_addr;
+ u32 p_dest_addr;
+ };
+ union {
+ u32 upper_dest_addr;
+ u32 pq_upper_dest_addr;
+ };
+ struct iop13xx_adma_src src[1];
+};
+
+struct iop13xx_adma_desc_dual_xor {
+ u32 next_desc;
+ u32 desc_ctrl;
+ u32 reserved;
+ u32 byte_count;
+ u32 h_dest_addr;
+ u32 h_upper_dest_addr;
+ u32 src0_addr;
+ u32 upper_src0_addr;
+ u32 src1_addr;
+ u32 upper_src1_addr;
+ u32 h_src_addr;
+ u32 h_upper_src_addr;
+ u32 d_src_addr;
+ u32 d_upper_src_addr;
+ u32 d_dest_addr;
+ u32 d_upper_dest_addr;
+};
+
+struct iop13xx_adma_desc_pq_update {
+ u32 next_desc;
+ u32 desc_ctrl;
+ u32 reserved;
+ u32 byte_count;
+ u32 p_dest_addr;
+ u32 p_upper_dest_addr;
+ u32 src0_addr;
+ u32 upper_src0_addr;
+ u32 src1_addr;
+ u32 upper_src1_addr;
+ u32 p_src_addr;
+ u32 p_upper_src_addr;
+ u32 q_src_addr;
+ struct {
+ unsigned int q_upper_src_addr:24;
+ unsigned int q_dmlt:8;
+ };
+ u32 q_dest_addr;
+ u32 q_upper_dest_addr;
+};
+
+static inline int iop_adma_get_max_xor(void)
+{
+ return 16;
+}
+
+#define iop_adma_get_max_pq iop_adma_get_max_xor
+
+static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
+{
+ return __raw_readl(ADMA_ADAR(chan));
+}
+
+static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
+ u32 next_desc_addr)
+{
+ __raw_writel(next_desc_addr, ADMA_ANDAR(chan));
+}
+
+#define ADMA_STATUS_BUSY (1 << 13)
+
+static inline char iop_chan_is_busy(struct iop_adma_chan *chan)
+{
+ if (__raw_readl(ADMA_ACSR(chan)) &
+ ADMA_STATUS_BUSY)
+ return 1;
+ else
+ return 0;
+}
+
+static inline int
+iop_chan_get_desc_align(struct iop_adma_chan *chan, int num_slots)
+{
+ return 1;
+}
+#define iop_desc_is_aligned(x, y) 1
+
+static inline int
+iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
+{
+ *slots_per_op = 1;
+ return 1;
+}
+
+#define iop_chan_interrupt_slot_count(s, c) iop_chan_memcpy_slot_count(0, s)
+
+static inline int
+iop_chan_memset_slot_count(size_t len, int *slots_per_op)
+{
+ *slots_per_op = 1;
+ return 1;
+}
+
+static inline int
+iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op)
+{
+ static const char slot_count_table[] = { 1, 2, 2, 2,
+ 2, 3, 3, 3,
+ 3, 4, 4, 4,
+ 4, 5, 5, 5,
+ };
+ *slots_per_op = slot_count_table[src_cnt - 1];
+ return *slots_per_op;
+}
+
+#define ADMA_MAX_BYTE_COUNT (16 * 1024 * 1024)
+#define IOP_ADMA_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
+#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
+#define IOP_ADMA_XOR_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
+#define IOP_ADMA_PQ_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
+#define iop_chan_zero_sum_slot_count(l, s, o) iop_chan_xor_slot_count(l, s, o)
+#define iop_chan_pq_slot_count iop_chan_xor_slot_count
+#define iop_chan_pq_zero_sum_slot_count iop_chan_xor_slot_count
+
+static inline u32 iop_desc_get_dest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->dest_addr;
+}
+
+static inline u32 iop_desc_get_qdest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->q_dest_addr;
+}
+
+static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->byte_count_field.byte_count;
+}
+
+static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ int src_idx)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->src[src_idx].src_addr;
+}
+
+static inline u32 iop_desc_get_src_count(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->desc_ctrl_field.src_select + 1;
+}
+
+static inline void
+iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+ hw_desc->crc_addr = 0;
+}
+
+static inline void
+iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.block_fill_en = 1;
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+ hw_desc->crc_addr = 0;
+}
+
+/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
+static inline void
+iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.src_select = src_cnt - 1;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+ hw_desc->crc_addr = 0;
+
+}
+#define iop_desc_init_null_xor(d, s, i) iop_desc_init_xor(d, s, i)
+
+/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
+static inline int
+iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.src_select = src_cnt - 1;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.zero_result = 1;
+ u_desc_ctrl.field.status_write_back_en = 1;
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+ hw_desc->crc_addr = 0;
+
+ return 1;
+}
+
+static inline void
+iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.src_select = src_cnt - 1;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.pq_xfer_en = 1;
+ u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+}
+
+static inline int iop_desc_is_pq(struct iop_adma_desc_slot *desc)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = hw_desc->desc_ctrl;
+ return u_desc_ctrl.field.pq_xfer_en;
+}
+
+static inline void
+iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
+ unsigned long flags)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ union {
+ u32 value;
+ struct iop13xx_adma_desc_ctrl field;
+ } u_desc_ctrl;
+
+ u_desc_ctrl.value = 0;
+ u_desc_ctrl.field.src_select = src_cnt - 1;
+ u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
+ u_desc_ctrl.field.zero_result = 1;
+ u_desc_ctrl.field.status_write_back_en = 1;
+ u_desc_ctrl.field.pq_xfer_en = 1;
+ u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
+ u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
+ hw_desc->desc_ctrl = u_desc_ctrl.value;
+}
+
+static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ u32 byte_count)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ hw_desc->byte_count = byte_count;
+}
+
+static inline void
+iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
+{
+ int slots_per_op = desc->slots_per_op;
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
+ int i = 0;
+
+ if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
+ hw_desc->byte_count = len;
+ } else {
+ do {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
+ i += slots_per_op;
+ } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
+
+ if (len) {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iter->byte_count = len;
+ }
+ }
+}
+
+#define iop_desc_set_pq_zero_sum_byte_count iop_desc_set_zero_sum_byte_count
+
+static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan,
+ dma_addr_t addr)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ hw_desc->dest_addr = addr;
+ hw_desc->upper_dest_addr = 0;
+}
+
+static inline void
+iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+
+ hw_desc->dest_addr = addr[0];
+ hw_desc->q_dest_addr = addr[1];
+ hw_desc->upper_dest_addr = 0;
+}
+
+static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
+ dma_addr_t addr)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ hw_desc->src[0].src_addr = addr;
+ hw_desc->src[0].upper_src_addr = 0;
+}
+
+static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
+ int src_idx, dma_addr_t addr)
+{
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
+ int i = 0;
+
+ do {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ iter->src[src_idx].src_addr = addr;
+ iter->src[src_idx].upper_src_addr = 0;
+ slot_cnt -= slots_per_op;
+ if (slot_cnt) {
+ i += slots_per_op;
+ addr += IOP_ADMA_XOR_MAX_BYTE_COUNT;
+ }
+ } while (slot_cnt);
+}
+
+static inline void
+iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
+ dma_addr_t addr, unsigned char coef)
+{
+ int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
+ struct iop13xx_adma_src *src;
+ int i = 0;
+
+ do {
+ iter = iop_hw_desc_slot_idx(hw_desc, i);
+ src = &iter->src[src_idx];
+ src->src_addr = addr;
+ src->pq_upper_src_addr = 0;
+ src->pq_dmlt = coef;
+ slot_cnt -= slots_per_op;
+ if (slot_cnt) {
+ i += slots_per_op;
+ addr += IOP_ADMA_PQ_MAX_BYTE_COUNT;
+ }
+ } while (slot_cnt);
+}
+
+static inline void
+iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
+ struct iop_adma_chan *chan)
+{
+ iop_desc_init_memcpy(desc, 1);
+ iop_desc_set_byte_count(desc, chan, 0);
+ iop_desc_set_dest_addr(desc, chan, 0);
+ iop_desc_set_memcpy_src_addr(desc, 0);
+}
+
+#define iop_desc_set_zero_sum_src_addr iop_desc_set_xor_src_addr
+#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
+
+static inline void
+iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
+ dma_addr_t *src)
+{
+ iop_desc_set_xor_src_addr(desc, pq_idx, src[pq_idx]);
+ iop_desc_set_xor_src_addr(desc, pq_idx+1, src[pq_idx+1]);
+}
+
+static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
+ u32 next_desc_addr)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+
+ iop_paranoia(hw_desc->next_desc);
+ hw_desc->next_desc = next_desc_addr;
+}
+
+static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ return hw_desc->next_desc;
+}
+
+static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ hw_desc->next_desc = 0;
+}
+
+static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
+ u32 val)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ hw_desc->block_fill_data = val;
+}
+
+static inline enum sum_check_flags
+iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
+{
+ struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
+ struct iop13xx_adma_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
+ struct iop13xx_adma_byte_count byte_count = hw_desc->byte_count_field;
+ enum sum_check_flags flags;
+
+ BUG_ON(!(byte_count.tx_complete && desc_ctrl.zero_result));
+
+ flags = byte_count.zero_result_err_q << SUM_CHECK_Q;
+ flags |= byte_count.zero_result_err << SUM_CHECK_P;
+
+ return flags;
+}
+
+static inline void iop_chan_append(struct iop_adma_chan *chan)
+{
+ u32 adma_accr;
+
+ adma_accr = __raw_readl(ADMA_ACCR(chan));
+ adma_accr |= 0x2;
+ __raw_writel(adma_accr, ADMA_ACCR(chan));
+}
+
+static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
+{
+ return __raw_readl(ADMA_ACSR(chan));
+}
+
+static inline void iop_chan_disable(struct iop_adma_chan *chan)
+{
+ u32 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
+ adma_chan_ctrl &= ~0x1;
+ __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
+}
+
+static inline void iop_chan_enable(struct iop_adma_chan *chan)
+{
+ u32 adma_chan_ctrl;
+
+ adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
+ adma_chan_ctrl |= 0x1;
+ __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
+}
+
+static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(ADMA_ACSR(chan));
+ status &= (1 << 12);
+ __raw_writel(status, ADMA_ACSR(chan));
+}
+
+static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(ADMA_ACSR(chan));
+ status &= (1 << 11);
+ __raw_writel(status, ADMA_ACSR(chan));
+}
+
+static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
+{
+ u32 status = __raw_readl(ADMA_ACSR(chan));
+ status &= (1 << 9) | (1 << 5) | (1 << 4) | (1 << 3);
+ __raw_writel(status, ADMA_ACSR(chan));
+}
+
+static inline int
+iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
+{
+ return test_bit(9, &status);
+}
+
+static inline int
+iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return test_bit(5, &status);
+}
+
+static inline int
+iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return test_bit(4, &status);
+}
+
+static inline int
+iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return test_bit(3, &status);
+}
+
+static inline int
+iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+static inline int
+iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+static inline int
+iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
+{
+ return 0;
+}
+
+#endif /* _ADMA_H */
diff --git a/arch/arm/mach-iop13xx/include/mach/debug-macro.S b/arch/arm/mach-iop13xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..e664466d
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/debug-macro.S
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-iop13xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00002300
+ orr \rp, \rp, #0x00000040
+ orr \rv, \rp, #0xfe000000 @ virtual
+ orr \rv, \rv, #0x00e80000
+ orr \rp, \rp, #0xff000000 @ physical
+ orr \rp, \rp, #0x00d80000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-iop13xx/include/mach/entry-macro.S b/arch/arm/mach-iop13xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..a624a787
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/entry-macro.S
@@ -0,0 +1,45 @@
+/*
+ * iop13xx low level irq macros
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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.
+ *
+ */
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mrc p15, 0, \tmp, c15, c1, 0
+ orr \tmp, \tmp, #(1 << 6)
+ mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
+ .endm
+
+ /*
+ * Note: a 1-cycle window exists where iintvec will return the value
+ * of iintbase, so we explicitly check for "bad zeros"
+ */
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mrc p6, 0, \irqnr, c3, c2, 0 @ Read IINTVEC
+ cmp \irqnr, #0
+ mrceq p6, 0, \irqnr, c3, c2, 0 @ Re-read on potentially bad zero
+ adds \irqstat, \irqnr, #1 @ Check for 0xffffffff
+ movne \irqnr, \irqnr, lsr #2 @ Convert to irqnr
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ mrc p15, 0, \tmp1, c15, c1, 0
+ ands \tmp2, \tmp1, #(1 << 6)
+ bicne \tmp1, \tmp1, #(1 << 6)
+ mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
+ .endm
diff --git a/arch/arm/mach-iop13xx/include/mach/hardware.h b/arch/arm/mach-iop13xx/include/mach/hardware.h
new file mode 100644
index 00000000..8e1d5628
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/hardware.h
@@ -0,0 +1,28 @@
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+#include <asm/types.h>
+
+#define pcibios_assign_all_busses() 1
+
+#ifndef __ASSEMBLY__
+extern unsigned long iop13xx_pcibios_min_io;
+extern unsigned long iop13xx_pcibios_min_mem;
+extern u16 iop13xx_dev_id(void);
+extern void iop13xx_set_atu_mmr_bases(void);
+#endif
+
+#define PCIBIOS_MIN_IO (iop13xx_pcibios_min_io)
+#define PCIBIOS_MIN_MEM (iop13xx_pcibios_min_mem)
+
+/*
+ * Generic chipset bits
+ *
+ */
+#include "iop13xx.h"
+
+/*
+ * Board specific bits
+ */
+#include "iq81340.h"
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-iop13xx/include/mach/io.h b/arch/arm/mach-iop13xx/include/mach/io.h
new file mode 100644
index 00000000..dffb234b
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/io.h
@@ -0,0 +1,41 @@
+/*
+ * iop13xx custom ioremap implementation
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __iop13xx_io(a)
+#define __mem_pci(a) (a)
+#define __mem_isa(a) (a)
+
+extern void __iomem * __iop13xx_io(unsigned long io_addr);
+extern void __iomem *__iop13xx_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype);
+extern void __iop13xx_iounmap(void __iomem *addr);
+
+extern u32 iop13xx_atue_mem_base;
+extern u32 iop13xx_atux_mem_base;
+extern size_t iop13xx_atue_mem_size;
+extern size_t iop13xx_atux_mem_size;
+
+#define __arch_ioremap __iop13xx_ioremap
+#define __arch_iounmap __iop13xx_iounmap
+
+#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/iop13xx.h b/arch/arm/mach-iop13xx/include/mach/iop13xx.h
new file mode 100644
index 00000000..52b7fab7
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/iop13xx.h
@@ -0,0 +1,526 @@
+#ifndef _IOP13XX_HW_H_
+#define _IOP13XX_HW_H_
+
+#ifndef __ASSEMBLY__
+/* The ATU offsets can change based on the strapping */
+extern u32 iop13xx_atux_pmmr_offset;
+extern u32 iop13xx_atue_pmmr_offset;
+void iop13xx_init_irq(void);
+void iop13xx_map_io(void);
+void iop13xx_platform_init(void);
+void iop13xx_add_tpmi_devices(void);
+void iop13xx_init_irq(void);
+
+/* CPUID CP6 R0 Page 0 */
+static inline int iop13xx_cpu_id(void)
+{
+ int id;
+ asm volatile("mrc p6, 0, %0, c0, c0, 0":"=r" (id));
+ return id;
+}
+
+/* WDTCR CP6 R7 Page 9 */
+static inline u32 read_wdtcr(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val));
+ return val;
+}
+static inline void write_wdtcr(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val));
+}
+
+/* WDTSR CP6 R8 Page 9 */
+static inline u32 read_wdtsr(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val));
+ return val;
+}
+static inline void write_wdtsr(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val));
+}
+
+/* RCSR - Reset Cause Status Register */
+static inline u32 read_rcsr(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c0, c1, 0":"=r" (val));
+ return val;
+}
+
+extern unsigned long get_iop_tick_rate(void);
+#endif
+
+/*
+ * IOP13XX I/O and Mem space regions for PCI autoconfiguration
+ */
+#define IOP13XX_MAX_RAM_SIZE 0x80000000UL /* 2GB */
+#define IOP13XX_PCI_OFFSET IOP13XX_MAX_RAM_SIZE
+
+/* PCI MAP
+ * bus range cpu phys cpu virt note
+ * 0x0000.0000 + 2GB (n/a) (n/a) inbound, 1:1 mapping with Physical RAM
+ * 0x8000.0000 + 928M 0x1.8000.0000 (ioremap) PCIX outbound memory window
+ * 0x8000.0000 + 928M 0x2.8000.0000 (ioremap) PCIE outbound memory window
+ *
+ * IO MAP
+ * 0x1000 + 64K 0x0.fffb.1000 0xfec6.1000 PCIX outbound i/o window
+ * 0x1000 + 64K 0x0.fffd.1000 0xfed7.1000 PCIE outbound i/o window
+ */
+#define IOP13XX_PCIX_IO_WINDOW_SIZE 0x10000UL
+#define IOP13XX_PCIX_LOWER_IO_PA 0xfffb0000UL
+#define IOP13XX_PCIX_LOWER_IO_VA 0xfec60000UL
+#define IOP13XX_PCIX_LOWER_IO_BA 0x0UL /* OIOTVR */
+#define IOP13XX_PCIX_IO_BUS_OFFSET 0x1000UL
+#define IOP13XX_PCIX_UPPER_IO_PA (IOP13XX_PCIX_LOWER_IO_PA +\
+ IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
+#define IOP13XX_PCIX_UPPER_IO_VA (IOP13XX_PCIX_LOWER_IO_VA +\
+ IOP13XX_PCIX_IO_WINDOW_SIZE - 1)
+#define IOP13XX_PCIX_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+ (IOP13XX_PCIX_LOWER_IO_PA\
+ - IOP13XX_PCIX_LOWER_IO_VA))
+
+#define IOP13XX_PCIX_MEM_PHYS_OFFSET 0x100000000ULL
+#define IOP13XX_PCIX_MEM_WINDOW_SIZE 0x3a000000UL
+#define IOP13XX_PCIX_LOWER_MEM_BA (PHYS_OFFSET + IOP13XX_PCI_OFFSET)
+#define IOP13XX_PCIX_LOWER_MEM_PA (IOP13XX_PCIX_MEM_PHYS_OFFSET +\
+ IOP13XX_PCIX_LOWER_MEM_BA)
+#define IOP13XX_PCIX_UPPER_MEM_PA (IOP13XX_PCIX_LOWER_MEM_PA +\
+ IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PCIX_UPPER_MEM_BA (IOP13XX_PCIX_LOWER_MEM_BA +\
+ IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
+
+#define IOP13XX_PCIX_MEM_COOKIE 0x80000000UL
+#define IOP13XX_PCIX_LOWER_MEM_RA IOP13XX_PCIX_MEM_COOKIE
+#define IOP13XX_PCIX_UPPER_MEM_RA (IOP13XX_PCIX_LOWER_MEM_RA +\
+ IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PCIX_MEM_OFFSET (IOP13XX_PCIX_MEM_COOKIE -\
+ IOP13XX_PCIX_LOWER_MEM_BA)
+
+/* PCI-E ranges */
+#define IOP13XX_PCIE_IO_WINDOW_SIZE 0x10000UL
+#define IOP13XX_PCIE_LOWER_IO_PA 0xfffd0000UL
+#define IOP13XX_PCIE_LOWER_IO_VA 0xfed70000UL
+#define IOP13XX_PCIE_LOWER_IO_BA 0x0UL /* OIOTVR */
+#define IOP13XX_PCIE_IO_BUS_OFFSET 0x1000UL
+#define IOP13XX_PCIE_UPPER_IO_PA (IOP13XX_PCIE_LOWER_IO_PA +\
+ IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+#define IOP13XX_PCIE_UPPER_IO_VA (IOP13XX_PCIE_LOWER_IO_VA +\
+ IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+#define IOP13XX_PCIE_UPPER_IO_BA (IOP13XX_PCIE_LOWER_IO_BA +\
+ IOP13XX_PCIE_IO_WINDOW_SIZE - 1)
+#define IOP13XX_PCIE_IO_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+ (IOP13XX_PCIE_LOWER_IO_PA\
+ - IOP13XX_PCIE_LOWER_IO_VA))
+
+#define IOP13XX_PCIE_MEM_PHYS_OFFSET 0x200000000ULL
+#define IOP13XX_PCIE_MEM_WINDOW_SIZE 0x3a000000UL
+#define IOP13XX_PCIE_LOWER_MEM_BA (PHYS_OFFSET + IOP13XX_PCI_OFFSET)
+#define IOP13XX_PCIE_LOWER_MEM_PA (IOP13XX_PCIE_MEM_PHYS_OFFSET +\
+ IOP13XX_PCIE_LOWER_MEM_BA)
+#define IOP13XX_PCIE_UPPER_MEM_PA (IOP13XX_PCIE_LOWER_MEM_PA +\
+ IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PCIE_UPPER_MEM_BA (IOP13XX_PCIE_LOWER_MEM_BA +\
+ IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
+
+/* All 0xc000.0000 - 0xfdff.ffff addresses belong to PCIe */
+#define IOP13XX_PCIE_MEM_COOKIE 0xc0000000UL
+#define IOP13XX_PCIE_LOWER_MEM_RA IOP13XX_PCIE_MEM_COOKIE
+#define IOP13XX_PCIE_UPPER_MEM_RA (IOP13XX_PCIE_LOWER_MEM_RA +\
+ IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PCIE_MEM_OFFSET (IOP13XX_PCIE_MEM_COOKIE -\
+ IOP13XX_PCIE_LOWER_MEM_BA)
+
+/* PBI Ranges */
+#define IOP13XX_PBI_LOWER_MEM_PA 0xf0000000UL
+#define IOP13XX_PBI_MEM_WINDOW_SIZE 0x04000000UL
+#define IOP13XX_PBI_MEM_COOKIE 0xfa000000UL
+#define IOP13XX_PBI_LOWER_MEM_RA IOP13XX_PBI_MEM_COOKIE
+#define IOP13XX_PBI_UPPER_MEM_RA (IOP13XX_PBI_LOWER_MEM_RA +\
+ IOP13XX_PBI_MEM_WINDOW_SIZE - 1)
+
+/*
+ * IOP13XX chipset registers
+ */
+#define IOP13XX_PMMR_PHYS_MEM_BASE 0xffd80000UL /* PMMR phys. address */
+#define IOP13XX_PMMR_VIRT_MEM_BASE 0xfee80000UL /* PMMR phys. address */
+#define IOP13XX_PMMR_MEM_WINDOW_SIZE 0x80000
+#define IOP13XX_PMMR_UPPER_MEM_VA (IOP13XX_PMMR_VIRT_MEM_BASE +\
+ IOP13XX_PMMR_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PMMR_UPPER_MEM_PA (IOP13XX_PMMR_PHYS_MEM_BASE +\
+ IOP13XX_PMMR_MEM_WINDOW_SIZE - 1)
+#define IOP13XX_PMMR_VIRT_TO_PHYS(addr) (u32) ((u32) addr +\
+ (IOP13XX_PMMR_PHYS_MEM_BASE\
+ - IOP13XX_PMMR_VIRT_MEM_BASE))
+#define IOP13XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
+ (IOP13XX_PMMR_PHYS_MEM_BASE\
+ - IOP13XX_PMMR_VIRT_MEM_BASE))
+#define IOP13XX_REG_ADDR32(reg) (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
+#define IOP13XX_REG_ADDR16(reg) (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
+#define IOP13XX_REG_ADDR8(reg) (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
+#define IOP13XX_REG_ADDR32_PHYS(reg) (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
+#define IOP13XX_REG_ADDR16_PHYS(reg) (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
+#define IOP13XX_REG_ADDR8_PHYS(reg) (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
+#define IOP13XX_PMMR_SIZE 0x00080000
+
+/*=================== Defines for Platform Devices =====================*/
+#define IOP13XX_UART0_PHYS (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002300)
+#define IOP13XX_UART1_PHYS (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002340)
+#define IOP13XX_UART0_VIRT (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002300)
+#define IOP13XX_UART1_VIRT (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002340)
+
+#define IOP13XX_I2C0_PHYS (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002500)
+#define IOP13XX_I2C1_PHYS (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002520)
+#define IOP13XX_I2C2_PHYS (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002540)
+#define IOP13XX_I2C0_VIRT (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002500)
+#define IOP13XX_I2C1_VIRT (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002520)
+#define IOP13XX_I2C2_VIRT (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002540)
+
+/* ATU selection flags */
+/* IOP13XX_INIT_ATU_DEFAULT = Rely on CONFIG_IOP13XX_ATU* */
+#define IOP13XX_INIT_ATU_DEFAULT (0)
+#define IOP13XX_INIT_ATU_ATUX (1 << 0)
+#define IOP13XX_INIT_ATU_ATUE (1 << 1)
+#define IOP13XX_INIT_ATU_NONE (1 << 2)
+
+/* UART selection flags */
+/* IOP13XX_INIT_UART_DEFAULT = Rely on CONFIG_IOP13XX_UART* */
+#define IOP13XX_INIT_UART_DEFAULT (0)
+#define IOP13XX_INIT_UART_0 (1 << 0)
+#define IOP13XX_INIT_UART_1 (1 << 1)
+
+/* I2C selection flags */
+/* IOP13XX_INIT_I2C_DEFAULT = Rely on CONFIG_IOP13XX_I2C* */
+#define IOP13XX_INIT_I2C_DEFAULT (0)
+#define IOP13XX_INIT_I2C_0 (1 << 0)
+#define IOP13XX_INIT_I2C_1 (1 << 1)
+#define IOP13XX_INIT_I2C_2 (1 << 2)
+
+/* ADMA selection flags */
+/* INIT_ADMA_DEFAULT = Rely on CONFIG_IOP13XX_ADMA* */
+#define IOP13XX_INIT_ADMA_DEFAULT (0)
+#define IOP13XX_INIT_ADMA_0 (1 << 0)
+#define IOP13XX_INIT_ADMA_1 (1 << 1)
+#define IOP13XX_INIT_ADMA_2 (1 << 2)
+
+/* Platform devices */
+#define IQ81340_NUM_UART 2
+#define IQ81340_NUM_I2C 3
+#define IQ81340_NUM_PHYS_MAP_FLASH 1
+#define IQ81340_NUM_ADMA 3
+#define IQ81340_MAX_PLAT_DEVICES (IQ81340_NUM_UART + \
+ IQ81340_NUM_I2C + \
+ IQ81340_NUM_PHYS_MAP_FLASH + \
+ IQ81340_NUM_ADMA)
+
+/*========================== PMMR offsets for key registers ============*/
+#define IOP13XX_ATU0_PMMR_OFFSET 0x00048000
+#define IOP13XX_ATU1_PMMR_OFFSET 0x0004c000
+#define IOP13XX_ATU2_PMMR_OFFSET 0x0004d000
+#define IOP13XX_ADMA0_PMMR_OFFSET 0x00000000
+#define IOP13XX_ADMA1_PMMR_OFFSET 0x00000200
+#define IOP13XX_ADMA2_PMMR_OFFSET 0x00000400
+#define IOP13XX_PBI_PMMR_OFFSET 0x00001580
+#define IOP13XX_MU_PMMR_OFFSET 0x00004000
+#define IOP13XX_ESSR0_PMMR_OFFSET 0x00002188
+#define IOP13XX_ESSR0 IOP13XX_REG_ADDR32(0x00002188)
+
+#define IOP13XX_ESSR0_IFACE_MASK 0x00004000 /* Interface PCI-X / PCI-E */
+#define IOP13XX_CONTROLLER_ONLY (1 << 14)
+#define IOP13XX_INTERFACE_SEL_PCIX (1 << 15)
+
+#define IOP13XX_PMON_PMMR_OFFSET 0x0001A000
+#define IOP13XX_PMON_BASE (IOP13XX_PMMR_VIRT_MEM_BASE +\
+ IOP13XX_PMON_PMMR_OFFSET)
+#define IOP13XX_PMON_PHYSBASE (IOP13XX_PMMR_PHYS_MEM_BASE +\
+ IOP13XX_PMON_PMMR_OFFSET)
+
+#define IOP13XX_PMON_CMD0 (IOP13XX_PMON_BASE + 0x0)
+#define IOP13XX_PMON_EVR0 (IOP13XX_PMON_BASE + 0x4)
+#define IOP13XX_PMON_STS0 (IOP13XX_PMON_BASE + 0x8)
+#define IOP13XX_PMON_DATA0 (IOP13XX_PMON_BASE + 0xC)
+
+#define IOP13XX_PMON_CMD3 (IOP13XX_PMON_BASE + 0x30)
+#define IOP13XX_PMON_EVR3 (IOP13XX_PMON_BASE + 0x34)
+#define IOP13XX_PMON_STS3 (IOP13XX_PMON_BASE + 0x38)
+#define IOP13XX_PMON_DATA3 (IOP13XX_PMON_BASE + 0x3C)
+
+#define IOP13XX_PMON_CMD7 (IOP13XX_PMON_BASE + 0x70)
+#define IOP13XX_PMON_EVR7 (IOP13XX_PMON_BASE + 0x74)
+#define IOP13XX_PMON_STS7 (IOP13XX_PMON_BASE + 0x78)
+#define IOP13XX_PMON_DATA7 (IOP13XX_PMON_BASE + 0x7C)
+
+#define IOP13XX_PMONEN (IOP13XX_PMMR_VIRT_MEM_BASE + 0x4E040)
+#define IOP13XX_PMONSTAT (IOP13XX_PMMR_VIRT_MEM_BASE + 0x4E044)
+
+/*================================ATU===================================*/
+#define IOP13XX_ATUX_OFFSET(ofs) IOP13XX_REG_ADDR32(\
+ iop13xx_atux_pmmr_offset + (ofs))
+
+#define IOP13XX_ATUX_DID IOP13XX_REG_ADDR16(\
+ iop13xx_atux_pmmr_offset + 0x2)
+
+#define IOP13XX_ATUX_ATUCMD IOP13XX_REG_ADDR16(\
+ iop13xx_atux_pmmr_offset + 0x4)
+#define IOP13XX_ATUX_ATUSR IOP13XX_REG_ADDR16(\
+ iop13xx_atux_pmmr_offset + 0x6)
+
+#define IOP13XX_ATUX_IABAR0 IOP13XX_ATUX_OFFSET(0x10)
+#define IOP13XX_ATUX_IAUBAR0 IOP13XX_ATUX_OFFSET(0x14)
+#define IOP13XX_ATUX_IABAR1 IOP13XX_ATUX_OFFSET(0x18)
+#define IOP13XX_ATUX_IAUBAR1 IOP13XX_ATUX_OFFSET(0x1c)
+#define IOP13XX_ATUX_IABAR2 IOP13XX_ATUX_OFFSET(0x20)
+#define IOP13XX_ATUX_IAUBAR2 IOP13XX_ATUX_OFFSET(0x24)
+#define IOP13XX_ATUX_IALR0 IOP13XX_ATUX_OFFSET(0x40)
+#define IOP13XX_ATUX_IATVR0 IOP13XX_ATUX_OFFSET(0x44)
+#define IOP13XX_ATUX_IAUTVR0 IOP13XX_ATUX_OFFSET(0x48)
+#define IOP13XX_ATUX_IALR1 IOP13XX_ATUX_OFFSET(0x4c)
+#define IOP13XX_ATUX_IATVR1 IOP13XX_ATUX_OFFSET(0x50)
+#define IOP13XX_ATUX_IAUTVR1 IOP13XX_ATUX_OFFSET(0x54)
+#define IOP13XX_ATUX_IALR2 IOP13XX_ATUX_OFFSET(0x58)
+#define IOP13XX_ATUX_IATVR2 IOP13XX_ATUX_OFFSET(0x5c)
+#define IOP13XX_ATUX_IAUTVR2 IOP13XX_ATUX_OFFSET(0x60)
+#define IOP13XX_ATUX_ATUCR IOP13XX_ATUX_OFFSET(0x70)
+#define IOP13XX_ATUX_PCSR IOP13XX_ATUX_OFFSET(0x74)
+#define IOP13XX_ATUX_ATUISR IOP13XX_ATUX_OFFSET(0x78)
+#define IOP13XX_ATUX_PCIXSR IOP13XX_ATUX_OFFSET(0xD4)
+#define IOP13XX_ATUX_IABAR3 IOP13XX_ATUX_OFFSET(0x200)
+#define IOP13XX_ATUX_IAUBAR3 IOP13XX_ATUX_OFFSET(0x204)
+#define IOP13XX_ATUX_IALR3 IOP13XX_ATUX_OFFSET(0x208)
+#define IOP13XX_ATUX_IATVR3 IOP13XX_ATUX_OFFSET(0x20c)
+#define IOP13XX_ATUX_IAUTVR3 IOP13XX_ATUX_OFFSET(0x210)
+
+#define IOP13XX_ATUX_OIOBAR IOP13XX_ATUX_OFFSET(0x300)
+#define IOP13XX_ATUX_OIOWTVR IOP13XX_ATUX_OFFSET(0x304)
+#define IOP13XX_ATUX_OUMBAR0 IOP13XX_ATUX_OFFSET(0x308)
+#define IOP13XX_ATUX_OUMWTVR0 IOP13XX_ATUX_OFFSET(0x30c)
+#define IOP13XX_ATUX_OUMBAR1 IOP13XX_ATUX_OFFSET(0x310)
+#define IOP13XX_ATUX_OUMWTVR1 IOP13XX_ATUX_OFFSET(0x314)
+#define IOP13XX_ATUX_OUMBAR2 IOP13XX_ATUX_OFFSET(0x318)
+#define IOP13XX_ATUX_OUMWTVR2 IOP13XX_ATUX_OFFSET(0x31c)
+#define IOP13XX_ATUX_OUMBAR3 IOP13XX_ATUX_OFFSET(0x320)
+#define IOP13XX_ATUX_OUMWTVR3 IOP13XX_ATUX_OFFSET(0x324)
+#define IOP13XX_ATUX_OUDMABAR IOP13XX_ATUX_OFFSET(0x328)
+#define IOP13XX_ATUX_OUMSIBAR IOP13XX_ATUX_OFFSET(0x32c)
+#define IOP13XX_ATUX_OCCAR IOP13XX_ATUX_OFFSET(0x330)
+#define IOP13XX_ATUX_OCCDR IOP13XX_ATUX_OFFSET(0x334)
+
+#define IOP13XX_ATUX_ATUCR_OUT_EN (1 << 1)
+#define IOP13XX_ATUX_PCSR_CENTRAL_RES (1 << 25)
+#define IOP13XX_ATUX_PCSR_P_RSTOUT (1 << 21)
+#define IOP13XX_ATUX_PCSR_OUT_Q_BUSY (1 << 15)
+#define IOP13XX_ATUX_PCSR_IN_Q_BUSY (1 << 14)
+#define IOP13XX_ATUX_PCSR_FREQ_OFFSET (16)
+
+#define IOP13XX_ATUX_STAT_PCI_IFACE_ERR (1 << 18)
+#define IOP13XX_ATUX_STAT_VPD_ADDR (1 << 17)
+#define IOP13XX_ATUX_STAT_INT_PAR_ERR (1 << 16)
+#define IOP13XX_ATUX_STAT_CFG_WRITE (1 << 15)
+#define IOP13XX_ATUX_STAT_ERR_COR (1 << 14)
+#define IOP13XX_ATUX_STAT_TX_SCEM (1 << 13)
+#define IOP13XX_ATUX_STAT_REC_SCEM (1 << 12)
+#define IOP13XX_ATUX_STAT_POWER_TRAN (1 << 11)
+#define IOP13XX_ATUX_STAT_TX_SERR (1 << 10)
+#define IOP13XX_ATUX_STAT_DET_PAR_ERR (1 << 9 )
+#define IOP13XX_ATUX_STAT_BIST (1 << 8 )
+#define IOP13XX_ATUX_STAT_INT_REC_MABORT (1 << 7 )
+#define IOP13XX_ATUX_STAT_REC_SERR (1 << 4 )
+#define IOP13XX_ATUX_STAT_EXT_REC_MABORT (1 << 3 )
+#define IOP13XX_ATUX_STAT_EXT_REC_TABORT (1 << 2 )
+#define IOP13XX_ATUX_STAT_EXT_SIG_TABORT (1 << 1 )
+#define IOP13XX_ATUX_STAT_MASTER_DATA_PAR (1 << 0 )
+
+#define IOP13XX_ATUX_PCIXSR_BUS_NUM (8)
+#define IOP13XX_ATUX_PCIXSR_DEV_NUM (3)
+#define IOP13XX_ATUX_PCIXSR_FUNC_NUM (0)
+
+#define IOP13XX_ATUX_IALR_DISABLE 0x00000001
+#define IOP13XX_ATUX_OUMBAR_ENABLE 0x80000000
+
+#define IOP13XX_ATUE_OFFSET(ofs) IOP13XX_REG_ADDR32(\
+ iop13xx_atue_pmmr_offset + (ofs))
+
+#define IOP13XX_ATUE_DID IOP13XX_REG_ADDR16(\
+ iop13xx_atue_pmmr_offset + 0x2)
+#define IOP13XX_ATUE_ATUCMD IOP13XX_REG_ADDR16(\
+ iop13xx_atue_pmmr_offset + 0x4)
+#define IOP13XX_ATUE_ATUSR IOP13XX_REG_ADDR16(\
+ iop13xx_atue_pmmr_offset + 0x6)
+
+#define IOP13XX_ATUE_IABAR0 IOP13XX_ATUE_OFFSET(0x10)
+#define IOP13XX_ATUE_IAUBAR0 IOP13XX_ATUE_OFFSET(0x14)
+#define IOP13XX_ATUE_IABAR1 IOP13XX_ATUE_OFFSET(0x18)
+#define IOP13XX_ATUE_IAUBAR1 IOP13XX_ATUE_OFFSET(0x1c)
+#define IOP13XX_ATUE_IABAR2 IOP13XX_ATUE_OFFSET(0x20)
+#define IOP13XX_ATUE_IAUBAR2 IOP13XX_ATUE_OFFSET(0x24)
+#define IOP13XX_ATUE_IALR0 IOP13XX_ATUE_OFFSET(0x40)
+#define IOP13XX_ATUE_IATVR0 IOP13XX_ATUE_OFFSET(0x44)
+#define IOP13XX_ATUE_IAUTVR0 IOP13XX_ATUE_OFFSET(0x48)
+#define IOP13XX_ATUE_IALR1 IOP13XX_ATUE_OFFSET(0x4c)
+#define IOP13XX_ATUE_IATVR1 IOP13XX_ATUE_OFFSET(0x50)
+#define IOP13XX_ATUE_IAUTVR1 IOP13XX_ATUE_OFFSET(0x54)
+#define IOP13XX_ATUE_IALR2 IOP13XX_ATUE_OFFSET(0x58)
+#define IOP13XX_ATUE_IATVR2 IOP13XX_ATUE_OFFSET(0x5c)
+#define IOP13XX_ATUE_IAUTVR2 IOP13XX_ATUE_OFFSET(0x60)
+#define IOP13XX_ATUE_PE_LSTS IOP13XX_REG_ADDR16(\
+ iop13xx_atue_pmmr_offset + 0xe2)
+#define IOP13XX_ATUE_OIOWTVR IOP13XX_ATUE_OFFSET(0x304)
+#define IOP13XX_ATUE_OUMBAR0 IOP13XX_ATUE_OFFSET(0x308)
+#define IOP13XX_ATUE_OUMWTVR0 IOP13XX_ATUE_OFFSET(0x30c)
+#define IOP13XX_ATUE_OUMBAR1 IOP13XX_ATUE_OFFSET(0x310)
+#define IOP13XX_ATUE_OUMWTVR1 IOP13XX_ATUE_OFFSET(0x314)
+#define IOP13XX_ATUE_OUMBAR2 IOP13XX_ATUE_OFFSET(0x318)
+#define IOP13XX_ATUE_OUMWTVR2 IOP13XX_ATUE_OFFSET(0x31c)
+#define IOP13XX_ATUE_OUMBAR3 IOP13XX_ATUE_OFFSET(0x320)
+#define IOP13XX_ATUE_OUMWTVR3 IOP13XX_ATUE_OFFSET(0x324)
+
+#define IOP13XX_ATUE_ATUCR IOP13XX_ATUE_OFFSET(0x70)
+#define IOP13XX_ATUE_PCSR IOP13XX_ATUE_OFFSET(0x74)
+#define IOP13XX_ATUE_ATUISR IOP13XX_ATUE_OFFSET(0x78)
+#define IOP13XX_ATUE_OIOBAR IOP13XX_ATUE_OFFSET(0x300)
+#define IOP13XX_ATUE_OCCAR IOP13XX_ATUE_OFFSET(0x32c)
+#define IOP13XX_ATUE_OCCDR IOP13XX_ATUE_OFFSET(0x330)
+
+#define IOP13XX_ATUE_PIE_STS IOP13XX_ATUE_OFFSET(0x384)
+#define IOP13XX_ATUE_PIE_MSK IOP13XX_ATUE_OFFSET(0x388)
+
+#define IOP13XX_ATUE_ATUCR_IVM (1 << 6)
+#define IOP13XX_ATUE_ATUCR_OUT_EN (1 << 1)
+#define IOP13XX_ATUE_OCCAR_BUS_NUM (24)
+#define IOP13XX_ATUE_OCCAR_DEV_NUM (19)
+#define IOP13XX_ATUE_OCCAR_FUNC_NUM (16)
+#define IOP13XX_ATUE_OCCAR_EXT_REG (8)
+#define IOP13XX_ATUE_OCCAR_REG (2)
+
+#define IOP13XX_ATUE_PCSR_BUS_NUM (24)
+#define IOP13XX_ATUE_PCSR_DEV_NUM (19)
+#define IOP13XX_ATUE_PCSR_FUNC_NUM (16)
+#define IOP13XX_ATUE_PCSR_OUT_Q_BUSY (1 << 15)
+#define IOP13XX_ATUE_PCSR_IN_Q_BUSY (1 << 14)
+#define IOP13XX_ATUE_PCSR_END_POINT (1 << 13)
+#define IOP13XX_ATUE_PCSR_LLRB_BUSY (1 << 12)
+
+#define IOP13XX_ATUE_PCSR_BUS_NUM_MASK (0xff)
+#define IOP13XX_ATUE_PCSR_DEV_NUM_MASK (0x1f)
+#define IOP13XX_ATUE_PCSR_FUNC_NUM_MASK (0x7)
+
+#define IOP13XX_ATUE_PCSR_CORE_RESET (8)
+#define IOP13XX_ATUE_PCSR_FUNC_NUM (16)
+
+#define IOP13XX_ATUE_LSTS_TRAINING (1 << 11)
+#define IOP13XX_ATUE_STAT_SLOT_PWR_MSG (1 << 28)
+#define IOP13XX_ATUE_STAT_PME (1 << 27)
+#define IOP13XX_ATUE_STAT_HOT_PLUG_MSG (1 << 26)
+#define IOP13XX_ATUE_STAT_IVM (1 << 25)
+#define IOP13XX_ATUE_STAT_BIST (1 << 24)
+#define IOP13XX_ATUE_STAT_CFG_WRITE (1 << 18)
+#define IOP13XX_ATUE_STAT_VPD_ADDR (1 << 17)
+#define IOP13XX_ATUE_STAT_POWER_TRAN (1 << 16)
+#define IOP13XX_ATUE_STAT_HALT_ON_ERROR (1 << 13)
+#define IOP13XX_ATUE_STAT_ROOT_SYS_ERR (1 << 12)
+#define IOP13XX_ATUE_STAT_ROOT_ERR_MSG (1 << 11)
+#define IOP13XX_ATUE_STAT_PCI_IFACE_ERR (1 << 10)
+#define IOP13XX_ATUE_STAT_ERR_COR (1 << 9 )
+#define IOP13XX_ATUE_STAT_ERR_UNCOR (1 << 8 )
+#define IOP13XX_ATUE_STAT_CRS (1 << 7 )
+#define IOP13XX_ATUE_STAT_LNK_DWN (1 << 6 )
+#define IOP13XX_ATUE_STAT_INT_REC_MABORT (1 << 5 )
+#define IOP13XX_ATUE_STAT_DET_PAR_ERR (1 << 4 )
+#define IOP13XX_ATUE_STAT_EXT_REC_MABORT (1 << 3 )
+#define IOP13XX_ATUE_STAT_SIG_TABORT (1 << 2 )
+#define IOP13XX_ATUE_STAT_EXT_REC_TABORT (1 << 1 )
+#define IOP13XX_ATUE_STAT_MASTER_DATA_PAR (1 << 0 )
+
+#define IOP13XX_ATUE_ESTAT_REC_UNSUPPORTED_COMP_REQ (1 << 31)
+#define IOP13XX_ATUE_ESTAT_REC_COMPLETER_ABORT (1 << 30)
+#define IOP13XX_ATUE_ESTAT_TX_POISONED_TLP (1 << 29)
+#define IOP13XX_ATUE_ESTAT_TX_PAR_ERR (1 << 28)
+#define IOP13XX_ATUE_ESTAT_REC_UNSUPPORTED_REQ (1 << 20)
+#define IOP13XX_ATUE_ESTAT_REC_ECRC_ERR (1 << 19)
+#define IOP13XX_ATUE_ESTAT_REC_MALFORMED_TLP (1 << 18)
+#define IOP13XX_ATUE_ESTAT_TX_RECEIVER_OVERFLOW (1 << 17)
+#define IOP13XX_ATUE_ESTAT_REC_UNEXPECTED_COMP (1 << 16)
+#define IOP13XX_ATUE_ESTAT_INT_COMP_ABORT (1 << 15)
+#define IOP13XX_ATUE_ESTAT_COMP_TIMEOUT (1 << 14)
+#define IOP13XX_ATUE_ESTAT_FLOW_CONTROL_ERR (1 << 13)
+#define IOP13XX_ATUE_ESTAT_REC_POISONED_TLP (1 << 12)
+#define IOP13XX_ATUE_ESTAT_DATA_LNK_ERR (1 << 4 )
+#define IOP13XX_ATUE_ESTAT_TRAINING_ERR (1 << 0 )
+
+#define IOP13XX_ATUE_IALR_DISABLE (0x00000001)
+#define IOP13XX_ATUE_OUMBAR_ENABLE (0x80000000)
+#define IOP13XX_ATU_OUMBAR_FUNC_NUM (28)
+#define IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK (0x7)
+/*=======================================================================*/
+
+/*============================MESSAGING UNIT=============================*/
+#define IOP13XX_MU_OFFSET(ofs) IOP13XX_REG_ADDR32(IOP13XX_MU_PMMR_OFFSET +\
+ (ofs))
+
+#define IOP13XX_MU_IMR0 IOP13XX_MU_OFFSET(0x10)
+#define IOP13XX_MU_IMR1 IOP13XX_MU_OFFSET(0x14)
+#define IOP13XX_MU_OMR0 IOP13XX_MU_OFFSET(0x18)
+#define IOP13XX_MU_OMR1 IOP13XX_MU_OFFSET(0x1C)
+#define IOP13XX_MU_IDR IOP13XX_MU_OFFSET(0x20)
+#define IOP13XX_MU_IISR IOP13XX_MU_OFFSET(0x24)
+#define IOP13XX_MU_IIMR IOP13XX_MU_OFFSET(0x28)
+#define IOP13XX_MU_ODR IOP13XX_MU_OFFSET(0x2C)
+#define IOP13XX_MU_OISR IOP13XX_MU_OFFSET(0x30)
+#define IOP13XX_MU_OIMR IOP13XX_MU_OFFSET(0x34)
+#define IOP13XX_MU_IRCSR IOP13XX_MU_OFFSET(0x38)
+#define IOP13XX_MU_ORCSR IOP13XX_MU_OFFSET(0x3C)
+#define IOP13XX_MU_MIMR IOP13XX_MU_OFFSET(0x48)
+#define IOP13XX_MU_MUCR IOP13XX_MU_OFFSET(0x50)
+#define IOP13XX_MU_QBAR IOP13XX_MU_OFFSET(0x54)
+#define IOP13XX_MU_MUBAR IOP13XX_MU_OFFSET(0x84)
+
+#define IOP13XX_MU_WINDOW_SIZE (8 * 1024)
+#define IOP13XX_MU_BASE_PHYS (0xff000000)
+#define IOP13XX_MU_BASE_PCI (0xff000000)
+#define IOP13XX_MU_MIMR_PCI (IOP13XX_MU_BASE_PCI + 0x48)
+#define IOP13XX_MU_MIMR_CORE_SELECT (15)
+/*=======================================================================*/
+
+/*==============================ADMA UNITS===============================*/
+#define IOP13XX_ADMA_PHYS_BASE(chan) IOP13XX_REG_ADDR32_PHYS((chan << 9))
+#define IOP13XX_ADMA_UPPER_PA(chan) (IOP13XX_ADMA_PHYS_BASE(chan) + 0xc0)
+
+/*==============================XSI BRIDGE===============================*/
+#define IOP13XX_XBG_BECSR IOP13XX_REG_ADDR32(0x178c)
+#define IOP13XX_XBG_BERAR IOP13XX_REG_ADDR32(0x1790)
+#define IOP13XX_XBG_BERUAR IOP13XX_REG_ADDR32(0x1794)
+#define is_atue_occdr_error(x) ((__raw_readl(IOP13XX_XBG_BERAR) == \
+ IOP13XX_PMMR_VIRT_TO_PHYS(\
+ IOP13XX_ATUE_OCCDR))\
+ && (__raw_readl(IOP13XX_XBG_BECSR) & 1))
+#define is_atux_occdr_error(x) ((__raw_readl(IOP13XX_XBG_BERAR) == \
+ IOP13XX_PMMR_VIRT_TO_PHYS(\
+ IOP13XX_ATUX_OCCDR))\
+ && (__raw_readl(IOP13XX_XBG_BECSR) & 1))
+/*=======================================================================*/
+
+#define IOP13XX_PBI_OFFSET(ofs) IOP13XX_REG_ADDR32(IOP13XX_PBI_PMMR_OFFSET +\
+ (ofs))
+
+#define IOP13XX_PBI_CR IOP13XX_PBI_OFFSET(0x0)
+#define IOP13XX_PBI_SR IOP13XX_PBI_OFFSET(0x4)
+#define IOP13XX_PBI_BAR0 IOP13XX_PBI_OFFSET(0x8)
+#define IOP13XX_PBI_LR0 IOP13XX_PBI_OFFSET(0xc)
+#define IOP13XX_PBI_BAR1 IOP13XX_PBI_OFFSET(0x10)
+#define IOP13XX_PBI_LR1 IOP13XX_PBI_OFFSET(0x14)
+
+#define IOP13XX_PROCESSOR_FREQ IOP13XX_REG_ADDR32(0x2180)
+
+/* Watchdog timer definitions */
+#define IOP_WDTCR_EN_ARM 0x1e1e1e1e
+#define IOP_WDTCR_EN 0xe1e1e1e1
+#define IOP_WDTCR_DIS_ARM 0x1f1f1f1f
+#define IOP_WDTCR_DIS 0xf1f1f1f1
+#define IOP_RCSR_WDT (1 << 5) /* reset caused by watchdog timer */
+#define IOP13XX_WDTSR_WRITE_EN (1 << 31) /* used to speed up reset requests */
+#define IOP13XX_WDTCR_IB_RESET (1 << 0)
+
+#endif /* _IOP13XX_HW_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/iq81340.h b/arch/arm/mach-iop13xx/include/mach/iq81340.h
new file mode 100644
index 00000000..ba2cf931
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/iq81340.h
@@ -0,0 +1,28 @@
+#ifndef _IQ81340_H_
+#define _IQ81340_H_
+
+#define IQ81340_PCE_BAR0 IOP13XX_PBI_LOWER_MEM_RA
+#define IQ81340_PCE_BAR1 (IQ81340_PCE_BAR0 + 0x02000000)
+
+#define IQ81340_FLASHBASE IQ81340_PCE_BAR0 /* Flash */
+
+#define IQ81340_PCE_BAR1_OFFSET(a) (IQ81340_PCE_BAR1 + (a))
+
+#define IQ81340_PRD_CODE IQ81340_PCE_BAR1_OFFSET(0)
+#define IQ81340_BRD_STEP IQ81340_PCE_BAR1_OFFSET(0x10000)
+#define IQ81340_CPLD_REV IQ81340_PCE_BAR1_OFFSET(0x20000)
+#define IQ81340_LED IQ81340_PCE_BAR1_OFFSET(0x30000)
+#define IQ81340_LHEX IQ81340_PCE_BAR1_OFFSET(0x40000)
+#define IQ81340_RHEX IQ81340_PCE_BAR1_OFFSET(0x50000)
+#define IQ81340_BUZZER IQ81340_PCE_BAR1_OFFSET(0x60000)
+#define IQ81340_32K_NVRAM IQ81340_PCE_BAR1_OFFSET(0x70000)
+#define IQ81340_256K_NVRAM IQ81340_PCE_BAR1_OFFSET(0x80000)
+#define IQ81340_ROTARY_SW IQ81340_PCE_BAR1_OFFSET(0xd0000)
+#define IQ81340_BATT_STAT IQ81340_PCE_BAR1_OFFSET(0xf0000)
+#define IQ81340_CMP_FLSH IQ81340_PCE_BAR1_OFFSET(0x1000000) /* 16MB */
+
+#define PBI_CF_IDE_BASE (IQ81340_CMP_FLSH)
+#define PBI_CF_BAR_ADDR (IOP13XX_PBI_BAR1)
+
+
+#endif /* _IQ81340_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/irqs.h b/arch/arm/mach-iop13xx/include/mach/irqs.h
new file mode 100644
index 00000000..054e7acb
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/irqs.h
@@ -0,0 +1,196 @@
+#ifndef _IOP13XX_IRQS_H_
+#define _IOP13XX_IRQS_H_
+
+#ifndef __ASSEMBLER__
+#include <linux/types.h>
+
+/* INTPND0 CP6 R0 Page 3
+ */
+static inline u32 read_intpnd_0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c0, c3, 0":"=r" (val));
+ return val;
+}
+
+/* INTPND1 CP6 R1 Page 3
+ */
+static inline u32 read_intpnd_1(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c1, c3, 0":"=r" (val));
+ return val;
+}
+
+/* INTPND2 CP6 R2 Page 3
+ */
+static inline u32 read_intpnd_2(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c2, c3, 0":"=r" (val));
+ return val;
+}
+
+/* INTPND3 CP6 R3 Page 3
+ */
+static inline u32 read_intpnd_3(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c3, c3, 0":"=r" (val));
+ return val;
+}
+#endif
+
+#define INTBASE 0
+#define INTSIZE_4 1
+
+/*
+ * iop34x chipset interrupts
+ */
+#define IOP13XX_IRQ(x) (IOP13XX_IRQ_OFS + (x))
+
+/*
+ * On IRQ or FIQ register
+ */
+#define IRQ_IOP13XX_ADMA0_EOT (0)
+#define IRQ_IOP13XX_ADMA0_EOC (1)
+#define IRQ_IOP13XX_ADMA1_EOT (2)
+#define IRQ_IOP13XX_ADMA1_EOC (3)
+#define IRQ_IOP13XX_ADMA2_EOT (4)
+#define IRQ_IOP13XX_ADMA2_EOC (5)
+#define IRQ_IOP134_WATCHDOG (6)
+#define IRQ_IOP13XX_RSVD_7 (7)
+#define IRQ_IOP13XX_TIMER0 (8)
+#define IRQ_IOP13XX_TIMER1 (9)
+#define IRQ_IOP13XX_I2C_0 (10)
+#define IRQ_IOP13XX_I2C_1 (11)
+#define IRQ_IOP13XX_MSG (12)
+#define IRQ_IOP13XX_MSGIBQ (13)
+#define IRQ_IOP13XX_ATU_IM (14)
+#define IRQ_IOP13XX_ATU_BIST (15)
+#define IRQ_IOP13XX_PPMU (16)
+#define IRQ_IOP13XX_COREPMU (17)
+#define IRQ_IOP13XX_CORECACHE (18)
+#define IRQ_IOP13XX_RSVD_19 (19)
+#define IRQ_IOP13XX_RSVD_20 (20)
+#define IRQ_IOP13XX_RSVD_21 (21)
+#define IRQ_IOP13XX_RSVD_22 (22)
+#define IRQ_IOP13XX_RSVD_23 (23)
+#define IRQ_IOP13XX_XINT0 (24)
+#define IRQ_IOP13XX_XINT1 (25)
+#define IRQ_IOP13XX_XINT2 (26)
+#define IRQ_IOP13XX_XINT3 (27)
+#define IRQ_IOP13XX_XINT4 (28)
+#define IRQ_IOP13XX_XINT5 (29)
+#define IRQ_IOP13XX_XINT6 (30)
+#define IRQ_IOP13XX_XINT7 (31)
+ /* IINTSRC1 bit */
+#define IRQ_IOP13XX_XINT8 (32) /* 0 */
+#define IRQ_IOP13XX_XINT9 (33) /* 1 */
+#define IRQ_IOP13XX_XINT10 (34) /* 2 */
+#define IRQ_IOP13XX_XINT11 (35) /* 3 */
+#define IRQ_IOP13XX_XINT12 (36) /* 4 */
+#define IRQ_IOP13XX_XINT13 (37) /* 5 */
+#define IRQ_IOP13XX_XINT14 (38) /* 6 */
+#define IRQ_IOP13XX_XINT15 (39) /* 7 */
+#define IRQ_IOP13XX_RSVD_40 (40) /* 8 */
+#define IRQ_IOP13XX_RSVD_41 (41) /* 9 */
+#define IRQ_IOP13XX_RSVD_42 (42) /* 10 */
+#define IRQ_IOP13XX_RSVD_43 (43) /* 11 */
+#define IRQ_IOP13XX_RSVD_44 (44) /* 12 */
+#define IRQ_IOP13XX_RSVD_45 (45) /* 13 */
+#define IRQ_IOP13XX_RSVD_46 (46) /* 14 */
+#define IRQ_IOP13XX_RSVD_47 (47) /* 15 */
+#define IRQ_IOP13XX_RSVD_48 (48) /* 16 */
+#define IRQ_IOP13XX_RSVD_49 (49) /* 17 */
+#define IRQ_IOP13XX_RSVD_50 (50) /* 18 */
+#define IRQ_IOP13XX_UART0 (51) /* 19 */
+#define IRQ_IOP13XX_UART1 (52) /* 20 */
+#define IRQ_IOP13XX_PBIE (53) /* 21 */
+#define IRQ_IOP13XX_ATU_CRW (54) /* 22 */
+#define IRQ_IOP13XX_ATU_ERR (55) /* 23 */
+#define IRQ_IOP13XX_MCU_ERR (56) /* 24 */
+#define IRQ_IOP13XX_ADMA0_ERR (57) /* 25 */
+#define IRQ_IOP13XX_ADMA1_ERR (58) /* 26 */
+#define IRQ_IOP13XX_ADMA2_ERR (59) /* 27 */
+#define IRQ_IOP13XX_RSVD_60 (60) /* 28 */
+#define IRQ_IOP13XX_RSVD_61 (61) /* 29 */
+#define IRQ_IOP13XX_MSG_ERR (62) /* 30 */
+#define IRQ_IOP13XX_RSVD_63 (63) /* 31 */
+ /* IINTSRC2 bit */
+#define IRQ_IOP13XX_INTERPROC (64) /* 0 */
+#define IRQ_IOP13XX_RSVD_65 (65) /* 1 */
+#define IRQ_IOP13XX_RSVD_66 (66) /* 2 */
+#define IRQ_IOP13XX_RSVD_67 (67) /* 3 */
+#define IRQ_IOP13XX_RSVD_68 (68) /* 4 */
+#define IRQ_IOP13XX_RSVD_69 (69) /* 5 */
+#define IRQ_IOP13XX_RSVD_70 (70) /* 6 */
+#define IRQ_IOP13XX_RSVD_71 (71) /* 7 */
+#define IRQ_IOP13XX_RSVD_72 (72) /* 8 */
+#define IRQ_IOP13XX_RSVD_73 (73) /* 9 */
+#define IRQ_IOP13XX_RSVD_74 (74) /* 10 */
+#define IRQ_IOP13XX_RSVD_75 (75) /* 11 */
+#define IRQ_IOP13XX_RSVD_76 (76) /* 12 */
+#define IRQ_IOP13XX_RSVD_77 (77) /* 13 */
+#define IRQ_IOP13XX_RSVD_78 (78) /* 14 */
+#define IRQ_IOP13XX_RSVD_79 (79) /* 15 */
+#define IRQ_IOP13XX_RSVD_80 (80) /* 16 */
+#define IRQ_IOP13XX_RSVD_81 (81) /* 17 */
+#define IRQ_IOP13XX_RSVD_82 (82) /* 18 */
+#define IRQ_IOP13XX_RSVD_83 (83) /* 19 */
+#define IRQ_IOP13XX_RSVD_84 (84) /* 20 */
+#define IRQ_IOP13XX_RSVD_85 (85) /* 21 */
+#define IRQ_IOP13XX_RSVD_86 (86) /* 22 */
+#define IRQ_IOP13XX_RSVD_87 (87) /* 23 */
+#define IRQ_IOP13XX_RSVD_88 (88) /* 24 */
+#define IRQ_IOP13XX_RSVD_89 (89) /* 25 */
+#define IRQ_IOP13XX_RSVD_90 (90) /* 26 */
+#define IRQ_IOP13XX_RSVD_91 (91) /* 27 */
+#define IRQ_IOP13XX_RSVD_92 (92) /* 28 */
+#define IRQ_IOP13XX_RSVD_93 (93) /* 29 */
+#define IRQ_IOP13XX_SIB_ERR (94) /* 30 */
+#define IRQ_IOP13XX_SRAM_ERR (95) /* 31 */
+ /* IINTSRC3 bit */
+#define IRQ_IOP13XX_I2C_2 (96) /* 0 */
+#define IRQ_IOP13XX_ATUE_BIST (97) /* 1 */
+#define IRQ_IOP13XX_ATUE_CRW (98) /* 2 */
+#define IRQ_IOP13XX_ATUE_ERR (99) /* 3 */
+#define IRQ_IOP13XX_IMU (100) /* 4 */
+#define IRQ_IOP13XX_RSVD_101 (101) /* 5 */
+#define IRQ_IOP13XX_RSVD_102 (102) /* 6 */
+#define IRQ_IOP13XX_TPMI0_OUT (103) /* 7 */
+#define IRQ_IOP13XX_TPMI1_OUT (104) /* 8 */
+#define IRQ_IOP13XX_TPMI2_OUT (105) /* 9 */
+#define IRQ_IOP13XX_TPMI3_OUT (106) /* 10 */
+#define IRQ_IOP13XX_ATUE_IMA (107) /* 11 */
+#define IRQ_IOP13XX_ATUE_IMB (108) /* 12 */
+#define IRQ_IOP13XX_ATUE_IMC (109) /* 13 */
+#define IRQ_IOP13XX_ATUE_IMD (110) /* 14 */
+#define IRQ_IOP13XX_MU_MSI_TB (111) /* 15 */
+#define IRQ_IOP13XX_RSVD_112 (112) /* 16 */
+#define IRQ_IOP13XX_INBD_MSI (113) /* 17 */
+#define IRQ_IOP13XX_RSVD_114 (114) /* 18 */
+#define IRQ_IOP13XX_RSVD_115 (115) /* 19 */
+#define IRQ_IOP13XX_RSVD_116 (116) /* 20 */
+#define IRQ_IOP13XX_RSVD_117 (117) /* 21 */
+#define IRQ_IOP13XX_RSVD_118 (118) /* 22 */
+#define IRQ_IOP13XX_RSVD_119 (119) /* 23 */
+#define IRQ_IOP13XX_RSVD_120 (120) /* 24 */
+#define IRQ_IOP13XX_RSVD_121 (121) /* 25 */
+#define IRQ_IOP13XX_RSVD_122 (122) /* 26 */
+#define IRQ_IOP13XX_RSVD_123 (123) /* 27 */
+#define IRQ_IOP13XX_RSVD_124 (124) /* 28 */
+#define IRQ_IOP13XX_RSVD_125 (125) /* 29 */
+#define IRQ_IOP13XX_RSVD_126 (126) /* 30 */
+#define IRQ_IOP13XX_HPI (127) /* 31 */
+
+#ifdef CONFIG_PCI_MSI
+#define IRQ_IOP13XX_MSI_0 (IRQ_IOP13XX_HPI + 1)
+#define NR_IOP13XX_IRQS (IRQ_IOP13XX_MSI_0 + 128)
+#else
+#define NR_IOP13XX_IRQS (IRQ_IOP13XX_HPI + 1)
+#endif
+
+#define NR_IRQS NR_IOP13XX_IRQS
+
+#endif /* _IOP13XX_IRQ_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
new file mode 100644
index 00000000..1afa99ef
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -0,0 +1,72 @@
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <mach/hardware.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#ifndef __ASSEMBLY__
+
+#if defined(CONFIG_ARCH_IOP13XX)
+#define IOP13XX_PMMR_V_START (IOP13XX_PMMR_VIRT_MEM_BASE)
+#define IOP13XX_PMMR_V_END (IOP13XX_PMMR_VIRT_MEM_BASE + IOP13XX_PMMR_SIZE)
+#define IOP13XX_PMMR_P_START (IOP13XX_PMMR_PHYS_MEM_BASE)
+#define IOP13XX_PMMR_P_END (IOP13XX_PMMR_PHYS_MEM_BASE + IOP13XX_PMMR_SIZE)
+
+static inline dma_addr_t __virt_to_lbus(unsigned long x)
+{
+ return x + IOP13XX_PMMR_PHYS_MEM_BASE - IOP13XX_PMMR_VIRT_MEM_BASE;
+}
+
+static inline unsigned long __lbus_to_virt(dma_addr_t x)
+{
+ return x + IOP13XX_PMMR_VIRT_MEM_BASE - IOP13XX_PMMR_PHYS_MEM_BASE;
+}
+
+#define __is_lbus_dma(a) \
+ ((a) >= IOP13XX_PMMR_P_START && (a) < IOP13XX_PMMR_P_END)
+
+#define __is_lbus_virt(a) \
+ ((a) >= IOP13XX_PMMR_V_START && (a) < IOP13XX_PMMR_V_END)
+
+/* Device is an lbus device if it is on the platform bus of the IOP13XX */
+#define is_lbus_device(dev) \
+ (dev && strncmp(dev->bus->name, "platform", 8) == 0)
+
+#define __arch_dma_to_virt(dev, addr) \
+ ({ \
+ unsigned long __virt; \
+ dma_addr_t __dma = addr; \
+ if (is_lbus_device(dev) && __is_lbus_dma(__dma)) \
+ __virt = __lbus_to_virt(__dma); \
+ else \
+ __virt = __phys_to_virt(__dma); \
+ (void *)__virt; \
+ })
+
+#define __arch_virt_to_dma(dev, addr) \
+ ({ \
+ unsigned long __virt = (unsigned long)addr; \
+ dma_addr_t __dma; \
+ if (is_lbus_device(dev) && __is_lbus_virt(__virt)) \
+ __dma = __virt_to_lbus(__virt); \
+ else \
+ __dma = __virt_to_phys(__virt); \
+ __dma; \
+ })
+
+#define __arch_pfn_to_dma(dev, pfn) \
+ ({ \
+ /* __is_lbus_virt() can never be true for RAM pages */ \
+ (dma_addr_t)__pfn_to_phys(pfn); \
+ })
+
+#define __arch_dma_to_pfn(dev, addr) __phys_to_pfn(addr)
+
+#endif /* CONFIG_ARCH_IOP13XX */
+#endif /* !ASSEMBLY */
+
+#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/msi.h b/arch/arm/mach-iop13xx/include/mach/msi.h
new file mode 100644
index 00000000..b80c5ae1
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/msi.h
@@ -0,0 +1,11 @@
+#ifndef _IOP13XX_MSI_H_
+#define _IOP13XX_MSI_H_
+#ifdef CONFIG_PCI_MSI
+void iop13xx_msi_init(void);
+#else
+static inline void iop13xx_msi_init(void)
+{
+ return;
+}
+#endif
+#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
new file mode 100644
index 00000000..59f42b53
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -0,0 +1,57 @@
+#ifndef _IOP13XX_PCI_H_
+#define _IOP13XX_PCI_H_
+#include <linux/io.h>
+#include <mach/irqs.h>
+
+struct pci_sys_data;
+struct hw_pci;
+int iop13xx_pci_setup(int nr, struct pci_sys_data *sys);
+struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *);
+void iop13xx_atu_select(struct hw_pci *plat_pci);
+void iop13xx_pci_init(void);
+void iop13xx_map_pci_memory(void);
+
+#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY | \
+ PCI_STATUS_SIG_TARGET_ABORT | \
+ PCI_STATUS_REC_TARGET_ABORT | \
+ PCI_STATUS_REC_TARGET_ABORT | \
+ PCI_STATUS_REC_MASTER_ABORT | \
+ PCI_STATUS_SIG_SYSTEM_ERROR | \
+ PCI_STATUS_DETECTED_PARITY)
+
+#define IOP13XX_ATUE_ATUISR_ERROR (IOP13XX_ATUE_STAT_HALT_ON_ERROR | \
+ IOP13XX_ATUE_STAT_ROOT_SYS_ERR | \
+ IOP13XX_ATUE_STAT_PCI_IFACE_ERR | \
+ IOP13XX_ATUE_STAT_ERR_COR | \
+ IOP13XX_ATUE_STAT_ERR_UNCOR | \
+ IOP13XX_ATUE_STAT_CRS | \
+ IOP13XX_ATUE_STAT_DET_PAR_ERR | \
+ IOP13XX_ATUE_STAT_EXT_REC_MABORT | \
+ IOP13XX_ATUE_STAT_SIG_TABORT | \
+ IOP13XX_ATUE_STAT_EXT_REC_TABORT | \
+ IOP13XX_ATUE_STAT_MASTER_DATA_PAR)
+
+#define IOP13XX_ATUX_ATUISR_ERROR (IOP13XX_ATUX_STAT_TX_SCEM | \
+ IOP13XX_ATUX_STAT_REC_SCEM | \
+ IOP13XX_ATUX_STAT_TX_SERR | \
+ IOP13XX_ATUX_STAT_DET_PAR_ERR | \
+ IOP13XX_ATUX_STAT_INT_REC_MABORT | \
+ IOP13XX_ATUX_STAT_REC_SERR | \
+ IOP13XX_ATUX_STAT_EXT_REC_MABORT | \
+ IOP13XX_ATUX_STAT_EXT_REC_TABORT | \
+ IOP13XX_ATUX_STAT_EXT_SIG_TABORT | \
+ IOP13XX_ATUX_STAT_MASTER_DATA_PAR)
+
+/* PCI interrupts
+ */
+#define ATUX_INTA IRQ_IOP13XX_XINT0
+#define ATUX_INTB IRQ_IOP13XX_XINT1
+#define ATUX_INTC IRQ_IOP13XX_XINT2
+#define ATUX_INTD IRQ_IOP13XX_XINT3
+
+#define ATUE_INTA IRQ_IOP13XX_ATUE_IMA
+#define ATUE_INTB IRQ_IOP13XX_ATUE_IMB
+#define ATUE_INTC IRQ_IOP13XX_ATUE_IMC
+#define ATUE_INTD IRQ_IOP13XX_ATUE_IMD
+
+#endif /* _IOP13XX_PCI_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h
new file mode 100644
index 00000000..d0c66ef4
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-iop13xx/include/mach/system.h
+ *
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <mach/iop13xx.h>
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Reset the internal bus (warning both cores are reset)
+ */
+ write_wdtcr(IOP_WDTCR_EN_ARM);
+ write_wdtcr(IOP_WDTCR_EN);
+ write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET);
+ write_wdtcr(0x1000);
+
+ for(;;);
+}
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
new file mode 100644
index 00000000..f1c00d6d
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/time.h
@@ -0,0 +1,123 @@
+#ifndef _IOP13XX_TIME_H_
+#define _IOP13XX_TIME_H_
+#define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0
+
+#define IOP_TMR_EN 0x02
+#define IOP_TMR_RELOAD 0x04
+#define IOP_TMR_PRIVILEGED 0x08
+#define IOP_TMR_RATIO_1_1 0x00
+
+#define IOP13XX_XSI_FREQ_RATIO_MASK (3 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_2 (0 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_3 (1 << 19)
+#define IOP13XX_XSI_FREQ_RATIO_4 (2 << 19)
+#define IOP13XX_CORE_FREQ_MASK (7 << 16)
+#define IOP13XX_CORE_FREQ_600 (0 << 16)
+#define IOP13XX_CORE_FREQ_667 (1 << 16)
+#define IOP13XX_CORE_FREQ_800 (2 << 16)
+#define IOP13XX_CORE_FREQ_933 (3 << 16)
+#define IOP13XX_CORE_FREQ_1000 (4 << 16)
+#define IOP13XX_CORE_FREQ_1200 (5 << 16)
+
+void iop_init_time(unsigned long tickrate);
+
+static inline unsigned long iop13xx_core_freq(void)
+{
+ unsigned long freq = __raw_readl(IOP13XX_PROCESSOR_FREQ);
+ freq &= IOP13XX_CORE_FREQ_MASK;
+ switch (freq) {
+ case IOP13XX_CORE_FREQ_600:
+ return 600000000;
+ case IOP13XX_CORE_FREQ_667:
+ return 667000000;
+ case IOP13XX_CORE_FREQ_800:
+ return 800000000;
+ case IOP13XX_CORE_FREQ_933:
+ return 933000000;
+ case IOP13XX_CORE_FREQ_1000:
+ return 1000000000;
+ case IOP13XX_CORE_FREQ_1200:
+ return 1200000000;
+ default:
+ printk("%s: warning unknown frequency, defaulting to 800Mhz\n",
+ __func__);
+ }
+
+ return 800000000;
+}
+
+static inline unsigned long iop13xx_xsi_bus_ratio(void)
+{
+ unsigned long ratio = __raw_readl(IOP13XX_PROCESSOR_FREQ);
+ ratio &= IOP13XX_XSI_FREQ_RATIO_MASK;
+ switch (ratio) {
+ case IOP13XX_XSI_FREQ_RATIO_2:
+ return 2;
+ case IOP13XX_XSI_FREQ_RATIO_3:
+ return 3;
+ case IOP13XX_XSI_FREQ_RATIO_4:
+ return 4;
+ default:
+ printk("%s: warning unknown ratio, defaulting to 2\n",
+ __func__);
+ }
+
+ return 2;
+}
+
+static inline u32 read_tmr0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c0, c9, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tmr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val));
+}
+
+static inline void write_tmr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (val));
+}
+
+static inline u32 read_tcr0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c2, c9, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tcr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c9, 0" : : "r" (val));
+}
+
+static inline u32 read_tcr1(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val));
+ return val;
+}
+
+static inline void write_tcr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c3, c9, 0" : : "r" (val));
+}
+
+static inline void write_trr0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val));
+}
+
+static inline void write_trr1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (val));
+}
+
+static inline void write_tisr(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (val));
+}
+#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/timex.h b/arch/arm/mach-iop13xx/include/mach/timex.h
new file mode 100644
index 00000000..45fb2745
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/timex.h
@@ -0,0 +1 @@
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-iop13xx/include/mach/uncompress.h b/arch/arm/mach-iop13xx/include/mach/uncompress.h
new file mode 100644
index 00000000..fa4f8052
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/uncompress.h
@@ -0,0 +1,23 @@
+#include <asm/types.h>
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+#define UART_BASE ((volatile u32 *)IOP13XX_UART1_PHYS)
+#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
+
+static inline void putc(char c)
+{
+ while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+ UART_BASE[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-iop13xx/include/mach/vmalloc.h b/arch/arm/mach-iop13xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..c5345674
--- /dev/null
+++ b/arch/arm/mach-iop13xx/include/mach/vmalloc.h
@@ -0,0 +1,4 @@
+#ifndef _VMALLOC_H_
+#define _VMALLOC_H_
+#define VMALLOC_END 0xfa000000UL
+#endif
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
new file mode 100644
index 00000000..48642e66
--- /dev/null
+++ b/arch/arm/mach-iop13xx/io.c
@@ -0,0 +1,113 @@
+/*
+ * iop13xx custom ioremap implementation
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+void * __iomem __iop13xx_io(unsigned long io_addr)
+{
+ void __iomem * io_virt;
+
+ switch (io_addr) {
+ case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
+ io_virt = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(io_addr);
+ break;
+ case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
+ io_virt = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(io_addr);
+ break;
+ default:
+ BUG();
+ }
+
+ return io_virt;
+}
+EXPORT_SYMBOL(__iop13xx_io);
+
+void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype)
+{
+ void __iomem * retval;
+
+ switch (cookie) {
+ case IOP13XX_PCIX_LOWER_MEM_RA ... IOP13XX_PCIX_UPPER_MEM_RA:
+ if (unlikely(!iop13xx_atux_mem_base))
+ retval = NULL;
+ else
+ retval = (void *)(iop13xx_atux_mem_base +
+ (cookie - IOP13XX_PCIX_LOWER_MEM_RA));
+ break;
+ case IOP13XX_PCIE_LOWER_MEM_RA ... IOP13XX_PCIE_UPPER_MEM_RA:
+ if (unlikely(!iop13xx_atue_mem_base))
+ retval = NULL;
+ else
+ retval = (void *)(iop13xx_atue_mem_base +
+ (cookie - IOP13XX_PCIE_LOWER_MEM_RA));
+ break;
+ case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
+ retval = __arm_ioremap_caller(IOP13XX_PBI_LOWER_MEM_PA +
+ (cookie - IOP13XX_PBI_LOWER_MEM_RA),
+ size, mtype, __builtin_return_address(0));
+ break;
+ case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
+ retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
+ break;
+ case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA:
+ retval = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(cookie);
+ break;
+ case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA:
+ retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
+ break;
+ default:
+ retval = __arm_ioremap_caller(cookie, size, mtype,
+ __builtin_return_address(0));
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(__iop13xx_ioremap);
+
+void __iop13xx_iounmap(void __iomem *addr)
+{
+ extern void __iounmap(volatile void __iomem *addr);
+
+ if (iop13xx_atue_mem_base)
+ if (addr >= (void __iomem *) iop13xx_atue_mem_base &&
+ addr < (void __iomem *) (iop13xx_atue_mem_base +
+ iop13xx_atue_mem_size))
+ goto skip;
+
+ if (iop13xx_atux_mem_base)
+ if (addr >= (void __iomem *) iop13xx_atux_mem_base &&
+ addr < (void __iomem *) (iop13xx_atux_mem_base +
+ iop13xx_atux_mem_size))
+ goto skip;
+
+ switch ((u32) addr) {
+ case IOP13XX_PCIE_LOWER_IO_VA ... IOP13XX_PCIE_UPPER_IO_VA:
+ case IOP13XX_PCIX_LOWER_IO_VA ... IOP13XX_PCIX_UPPER_IO_VA:
+ case IOP13XX_PMMR_VIRT_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_VA:
+ goto skip;
+ }
+ __iounmap(addr);
+
+skip:
+ return;
+}
+EXPORT_SYMBOL(__iop13xx_iounmap);
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
new file mode 100644
index 00000000..9b5a63f5
--- /dev/null
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -0,0 +1,99 @@
+/*
+ * iq81340mc board support
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/pci.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/pci.h>
+#include <asm/mach/time.h>
+#include <mach/time.h>
+
+extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */
+
+static int __init
+iq81340mc_pcix_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+ switch (idsel) {
+ case 1:
+ switch (pin) {
+ case 1: return ATUX_INTB;
+ case 2: return ATUX_INTC;
+ case 3: return ATUX_INTD;
+ case 4: return ATUX_INTA;
+ default: return -1;
+ }
+ case 2:
+ switch (pin) {
+ case 1: return ATUX_INTC;
+ case 2: return ATUX_INTD;
+ case 3: return ATUX_INTC;
+ case 4: return ATUX_INTD;
+ default: return -1;
+ }
+ default: return -1;
+ }
+}
+
+static struct hw_pci iq81340mc_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 0,
+ .setup = iop13xx_pci_setup,
+ .map_irq = iq81340mc_pcix_map_irq,
+ .scan = iop13xx_scan_bus,
+ .preinit = iop13xx_pci_init,
+};
+
+static int __init iq81340mc_pci_init(void)
+{
+ iop13xx_atu_select(&iq81340mc_pci);
+ pci_common_init(&iq81340mc_pci);
+ iop13xx_map_pci_memory();
+
+ return 0;
+}
+
+static void __init iq81340mc_init(void)
+{
+ iop13xx_platform_init();
+ iq81340mc_pci_init();
+ iop13xx_add_tpmi_devices();
+}
+
+static void __init iq81340mc_timer_init(void)
+{
+ unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+ printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq);
+ iop_init_time(bus_freq);
+}
+
+static struct sys_timer iq81340mc_timer = {
+ .init = iq81340mc_timer_init,
+};
+
+MACHINE_START(IQ81340MC, "Intel IQ81340MC")
+ /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
+ .boot_params = 0x00000100,
+ .map_io = iop13xx_map_io,
+ .init_irq = iop13xx_init_irq,
+ .timer = &iq81340mc_timer,
+ .init_machine = iq81340mc_init,
+MACHINE_END
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
new file mode 100644
index 00000000..df3492a9
--- /dev/null
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -0,0 +1,101 @@
+/*
+ * iq81340sc board support
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/pci.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/pci.h>
+#include <asm/mach/time.h>
+#include <mach/time.h>
+
+extern int init_atu;
+
+static int __init
+iq81340sc_atux_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+ WARN_ON(idsel < 1 || idsel > 2);
+
+ switch (idsel) {
+ case 1:
+ switch (pin) {
+ case 1: return ATUX_INTB;
+ case 2: return ATUX_INTC;
+ case 3: return ATUX_INTD;
+ case 4: return ATUX_INTA;
+ default: return -1;
+ }
+ case 2:
+ switch (pin) {
+ case 1: return ATUX_INTC;
+ case 2: return ATUX_INTC;
+ case 3: return ATUX_INTC;
+ case 4: return ATUX_INTC;
+ default: return -1;
+ }
+ default: return -1;
+ }
+}
+
+static struct hw_pci iq81340sc_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 0,
+ .setup = iop13xx_pci_setup,
+ .scan = iop13xx_scan_bus,
+ .map_irq = iq81340sc_atux_map_irq,
+ .preinit = iop13xx_pci_init
+};
+
+static int __init iq81340sc_pci_init(void)
+{
+ iop13xx_atu_select(&iq81340sc_pci);
+ pci_common_init(&iq81340sc_pci);
+ iop13xx_map_pci_memory();
+
+ return 0;
+}
+
+static void __init iq81340sc_init(void)
+{
+ iop13xx_platform_init();
+ iq81340sc_pci_init();
+ iop13xx_add_tpmi_devices();
+}
+
+static void __init iq81340sc_timer_init(void)
+{
+ unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
+ printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq);
+ iop_init_time(bus_freq);
+}
+
+static struct sys_timer iq81340sc_timer = {
+ .init = iq81340sc_timer_init,
+};
+
+MACHINE_START(IQ81340SC, "Intel IQ81340SC")
+ /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
+ .boot_params = 0x00000100,
+ .map_io = iop13xx_map_io,
+ .init_irq = iop13xx_init_irq,
+ .timer = &iq81340sc_timer,
+ .init_machine = iq81340sc_init,
+MACHINE_END
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
new file mode 100644
index 00000000..bc739701
--- /dev/null
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -0,0 +1,240 @@
+/*
+ * iop13xx IRQ handling / support functions
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/sysctl.h>
+#include <asm/uaccess.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/msi.h>
+
+/* INTCTL0 CP6 R0 Page 4
+ */
+static u32 read_intctl_0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c0, c4, 0":"=r" (val));
+ return val;
+}
+static void write_intctl_0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c4, 0"::"r" (val));
+}
+
+/* INTCTL1 CP6 R1 Page 4
+ */
+static u32 read_intctl_1(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c1, c4, 0":"=r" (val));
+ return val;
+}
+static void write_intctl_1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c1, c4, 0"::"r" (val));
+}
+
+/* INTCTL2 CP6 R2 Page 4
+ */
+static u32 read_intctl_2(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c2, c4, 0":"=r" (val));
+ return val;
+}
+static void write_intctl_2(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c4, 0"::"r" (val));
+}
+
+/* INTCTL3 CP6 R3 Page 4
+ */
+static u32 read_intctl_3(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c3, c4, 0":"=r" (val));
+ return val;
+}
+static void write_intctl_3(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c3, c4, 0"::"r" (val));
+}
+
+/* INTSTR0 CP6 R0 Page 5
+ */
+static void write_intstr_0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c5, 0"::"r" (val));
+}
+
+/* INTSTR1 CP6 R1 Page 5
+ */
+static void write_intstr_1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c1, c5, 0"::"r" (val));
+}
+
+/* INTSTR2 CP6 R2 Page 5
+ */
+static void write_intstr_2(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c5, 0"::"r" (val));
+}
+
+/* INTSTR3 CP6 R3 Page 5
+ */
+static void write_intstr_3(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c3, c5, 0"::"r" (val));
+}
+
+/* INTBASE CP6 R0 Page 2
+ */
+static void write_intbase(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c2, 0"::"r" (val));
+}
+
+/* INTSIZE CP6 R2 Page 2
+ */
+static void write_intsize(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c2, 0"::"r" (val));
+}
+
+/* 0 = Interrupt Masked and 1 = Interrupt not masked */
+static void
+iop13xx_irq_mask0 (struct irq_data *d)
+{
+ write_intctl_0(read_intctl_0() & ~(1 << (d->irq - 0)));
+}
+
+static void
+iop13xx_irq_mask1 (struct irq_data *d)
+{
+ write_intctl_1(read_intctl_1() & ~(1 << (d->irq - 32)));
+}
+
+static void
+iop13xx_irq_mask2 (struct irq_data *d)
+{
+ write_intctl_2(read_intctl_2() & ~(1 << (d->irq - 64)));
+}
+
+static void
+iop13xx_irq_mask3 (struct irq_data *d)
+{
+ write_intctl_3(read_intctl_3() & ~(1 << (d->irq - 96)));
+}
+
+static void
+iop13xx_irq_unmask0(struct irq_data *d)
+{
+ write_intctl_0(read_intctl_0() | (1 << (d->irq - 0)));
+}
+
+static void
+iop13xx_irq_unmask1(struct irq_data *d)
+{
+ write_intctl_1(read_intctl_1() | (1 << (d->irq - 32)));
+}
+
+static void
+iop13xx_irq_unmask2(struct irq_data *d)
+{
+ write_intctl_2(read_intctl_2() | (1 << (d->irq - 64)));
+}
+
+static void
+iop13xx_irq_unmask3(struct irq_data *d)
+{
+ write_intctl_3(read_intctl_3() | (1 << (d->irq - 96)));
+}
+
+static struct irq_chip iop13xx_irqchip1 = {
+ .name = "IOP13xx-1",
+ .irq_ack = iop13xx_irq_mask0,
+ .irq_mask = iop13xx_irq_mask0,
+ .irq_unmask = iop13xx_irq_unmask0,
+};
+
+static struct irq_chip iop13xx_irqchip2 = {
+ .name = "IOP13xx-2",
+ .irq_ack = iop13xx_irq_mask1,
+ .irq_mask = iop13xx_irq_mask1,
+ .irq_unmask = iop13xx_irq_unmask1,
+};
+
+static struct irq_chip iop13xx_irqchip3 = {
+ .name = "IOP13xx-3",
+ .irq_ack = iop13xx_irq_mask2,
+ .irq_mask = iop13xx_irq_mask2,
+ .irq_unmask = iop13xx_irq_unmask2,
+};
+
+static struct irq_chip iop13xx_irqchip4 = {
+ .name = "IOP13xx-4",
+ .irq_ack = iop13xx_irq_mask3,
+ .irq_mask = iop13xx_irq_mask3,
+ .irq_unmask = iop13xx_irq_unmask3,
+};
+
+extern void iop_init_cp6_handler(void);
+
+void __init iop13xx_init_irq(void)
+{
+ unsigned int i;
+
+ iop_init_cp6_handler();
+
+ /* disable all interrupts */
+ write_intctl_0(0);
+ write_intctl_1(0);
+ write_intctl_2(0);
+ write_intctl_3(0);
+
+ /* treat all as IRQ */
+ write_intstr_0(0);
+ write_intstr_1(0);
+ write_intstr_2(0);
+ write_intstr_3(0);
+
+ /* initialize the interrupt vector generator */
+ write_intbase(INTBASE);
+ write_intsize(INTSIZE_4);
+
+ for(i = 0; i <= IRQ_IOP13XX_HPI; i++) {
+ if (i < 32)
+ irq_set_chip(i, &iop13xx_irqchip1);
+ else if (i < 64)
+ irq_set_chip(i, &iop13xx_irqchip2);
+ else if (i < 96)
+ irq_set_chip(i, &iop13xx_irqchip3);
+ else
+ irq_set_chip(i, &iop13xx_irqchip4);
+
+ irq_set_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+
+ iop13xx_msi_init();
+}
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
new file mode 100644
index 00000000..560d5b2d
--- /dev/null
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -0,0 +1,193 @@
+/*
+ * arch/arm/mach-iop13xx/msi.c
+ *
+ * PCI MSI support for the iop13xx processor
+ *
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/pci.h>
+#include <linux/msi.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+
+#define IOP13XX_NUM_MSI_IRQS 128
+static DECLARE_BITMAP(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
+
+/* IMIPR0 CP6 R8 Page 1
+ */
+static u32 read_imipr_0(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c8, c1, 0":"=r" (val));
+ return val;
+}
+static void write_imipr_0(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c8, c1, 0"::"r" (val));
+}
+
+/* IMIPR1 CP6 R9 Page 1
+ */
+static u32 read_imipr_1(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c9, c1, 0":"=r" (val));
+ return val;
+}
+static void write_imipr_1(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c9, c1, 0"::"r" (val));
+}
+
+/* IMIPR2 CP6 R10 Page 1
+ */
+static u32 read_imipr_2(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c10, c1, 0":"=r" (val));
+ return val;
+}
+static void write_imipr_2(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c10, c1, 0"::"r" (val));
+}
+
+/* IMIPR3 CP6 R11 Page 1
+ */
+static u32 read_imipr_3(void)
+{
+ u32 val;
+ asm volatile("mrc p6, 0, %0, c11, c1, 0":"=r" (val));
+ return val;
+}
+static void write_imipr_3(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c11, c1, 0"::"r" (val));
+}
+
+static u32 (*read_imipr[])(void) = {
+ read_imipr_0,
+ read_imipr_1,
+ read_imipr_2,
+ read_imipr_3,
+};
+
+static void (*write_imipr[])(u32) = {
+ write_imipr_0,
+ write_imipr_1,
+ write_imipr_2,
+ write_imipr_3,
+};
+
+static void iop13xx_msi_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i, j;
+ unsigned long status;
+
+ /* read IMIPR registers and find any active interrupts,
+ * then call ISR for each active interrupt
+ */
+ for (i = 0; i < ARRAY_SIZE(read_imipr); i++) {
+ status = (read_imipr[i])();
+ if (!status)
+ continue;
+
+ do {
+ j = find_first_bit(&status, 32);
+ (write_imipr[i])(1 << j); /* write back to clear bit */
+ generic_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i));
+ status = (read_imipr[i])();
+ } while (status);
+ }
+}
+
+void __init iop13xx_msi_init(void)
+{
+ irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
+}
+
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+ int irq, pos;
+
+again:
+ pos = find_first_zero_bit(msi_irq_in_use, IOP13XX_NUM_MSI_IRQS);
+ irq = IRQ_IOP13XX_MSI_0 + pos;
+ if (irq > NR_IRQS)
+ return -ENOSPC;
+ /* test_and_set_bit operates on 32-bits at a time */
+ if (test_and_set_bit(pos, msi_irq_in_use))
+ goto again;
+
+ dynamic_irq_init(irq);
+
+ return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+ int pos = irq - IRQ_IOP13XX_MSI_0;
+
+ dynamic_irq_cleanup(irq);
+
+ clear_bit(pos, msi_irq_in_use);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ destroy_irq(irq);
+}
+
+static void iop13xx_msi_nop(struct irq_data *d)
+{
+ return;
+}
+
+static struct irq_chip iop13xx_msi_chip = {
+ .name = "PCI-MSI",
+ .irq_ack = iop13xx_msi_nop,
+ .irq_enable = unmask_msi_irq,
+ .irq_disable = mask_msi_irq,
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+};
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+ int id, irq = create_irq();
+ struct msi_msg msg;
+
+ if (irq < 0)
+ return irq;
+
+ irq_set_msi_desc(irq, desc);
+
+ msg.address_hi = 0x0;
+ msg.address_lo = IOP13XX_MU_MIMR_PCI;
+
+ id = iop13xx_cpu_id();
+ msg.data = (id << IOP13XX_MU_MIMR_CORE_SELECT) | (irq & 0x7f);
+
+ write_msi_msg(irq, &msg);
+ irq_set_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq);
+
+ return 0;
+}
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
new file mode 100644
index 00000000..ba3dae35
--- /dev/null
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -0,0 +1,1133 @@
+/*
+ * iop13xx PCI support
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/signal.h>
+#include <asm/mach/pci.h>
+#include <mach/pci.h>
+
+#define IOP13XX_PCI_DEBUG 0
+#define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x)))
+
+u32 iop13xx_atux_pmmr_offset; /* This offset can change based on strapping */
+u32 iop13xx_atue_pmmr_offset; /* This offset can change based on strapping */
+static struct pci_bus *pci_bus_atux = 0;
+static struct pci_bus *pci_bus_atue = 0;
+u32 iop13xx_atue_mem_base;
+u32 iop13xx_atux_mem_base;
+size_t iop13xx_atue_mem_size;
+size_t iop13xx_atux_mem_size;
+unsigned long iop13xx_pcibios_min_io = 0;
+unsigned long iop13xx_pcibios_min_mem = 0;
+
+EXPORT_SYMBOL(iop13xx_atue_mem_base);
+EXPORT_SYMBOL(iop13xx_atux_mem_base);
+EXPORT_SYMBOL(iop13xx_atue_mem_size);
+EXPORT_SYMBOL(iop13xx_atux_mem_size);
+
+int init_atu = 0; /* Flag to select which ATU(s) to initialize / disable */
+static unsigned long atux_trhfa_timeout = 0; /* Trhfa = RST# high to first
+ access */
+
+/* Scan the initialized busses and ioremap the requested memory range
+ */
+void iop13xx_map_pci_memory(void)
+{
+ int atu;
+ struct pci_bus *bus;
+ struct pci_dev *dev;
+ resource_size_t end = 0;
+
+ for (atu = 0; atu < 2; atu++) {
+ bus = atu ? pci_bus_atue : pci_bus_atux;
+ if (bus) {
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ int i;
+ int max = 7;
+
+ if (dev->subordinate)
+ max = DEVICE_COUNT_RESOURCE;
+
+ for (i = 0; i < max; i++) {
+ struct resource *res = &dev->resource[i];
+ if (res->flags & IORESOURCE_MEM)
+ end = max(res->end, end);
+ }
+ }
+
+ switch(atu) {
+ case 0:
+ iop13xx_atux_mem_size =
+ (end - IOP13XX_PCIX_LOWER_MEM_RA) + 1;
+
+ /* 16MB align the request */
+ if (iop13xx_atux_mem_size & (SZ_16M - 1)) {
+ iop13xx_atux_mem_size &= ~(SZ_16M - 1);
+ iop13xx_atux_mem_size += SZ_16M;
+ }
+
+ if (end) {
+ iop13xx_atux_mem_base =
+ (u32) __arm_ioremap_pfn(
+ __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
+ , 0, iop13xx_atux_mem_size, MT_DEVICE);
+ if (!iop13xx_atux_mem_base) {
+ printk("%s: atux allocation "
+ "failed\n", __func__);
+ BUG();
+ }
+ } else
+ iop13xx_atux_mem_size = 0;
+ PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n",
+ __func__, atu, iop13xx_atux_mem_size,
+ iop13xx_atux_mem_base);
+ break;
+ case 1:
+ iop13xx_atue_mem_size =
+ (end - IOP13XX_PCIE_LOWER_MEM_RA) + 1;
+
+ /* 16MB align the request */
+ if (iop13xx_atue_mem_size & (SZ_16M - 1)) {
+ iop13xx_atue_mem_size &= ~(SZ_16M - 1);
+ iop13xx_atue_mem_size += SZ_16M;
+ }
+
+ if (end) {
+ iop13xx_atue_mem_base =
+ (u32) __arm_ioremap_pfn(
+ __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
+ , 0, iop13xx_atue_mem_size, MT_DEVICE);
+ if (!iop13xx_atue_mem_base) {
+ printk("%s: atue allocation "
+ "failed\n", __func__);
+ BUG();
+ }
+ } else
+ iop13xx_atue_mem_size = 0;
+ PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n",
+ __func__, atu, iop13xx_atue_mem_size,
+ iop13xx_atue_mem_base);
+ break;
+ }
+
+ printk("%s: Initialized (%uM @ resource/virtual: %08lx/%08x)\n",
+ atu ? "ATUE" : "ATUX",
+ (atu ? iop13xx_atue_mem_size : iop13xx_atux_mem_size) /
+ SZ_1M,
+ atu ? IOP13XX_PCIE_LOWER_MEM_RA :
+ IOP13XX_PCIX_LOWER_MEM_RA,
+ atu ? iop13xx_atue_mem_base :
+ iop13xx_atux_mem_base);
+ end = 0;
+ }
+
+ }
+}
+
+static int iop13xx_atu_function(int atu)
+{
+ int func = 0;
+ /* the function number depends on the value of the
+ * IOP13XX_INTERFACE_SEL_PCIX reset strap
+ * see C-Spec section 3.17
+ */
+ switch(atu) {
+ case IOP13XX_INIT_ATU_ATUX:
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+ func = 5;
+ else
+ func = 0;
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+ func = 0;
+ else
+ func = 5;
+ break;
+ default:
+ BUG();
+ }
+
+ return func;
+}
+
+/* iop13xx_atux_cfg_address - format a configuration address for atux
+ * @bus: Target bus to access
+ * @devfn: Combined device number and function number
+ * @where: Desired register's address offset
+ *
+ * Convert the parameters to a configuration address formatted
+ * according the PCI-X 2.0 specification
+ */
+static u32 iop13xx_atux_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ u32 addr;
+
+ if (sys->busnr == bus->number)
+ addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
+ else
+ addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
+
+ addr |= PCI_FUNC(devfn) << 8 | ((where & 0xff) & ~3);
+ addr |= ((where & 0xf00) >> 8) << 24; /* upper register number */
+
+ return addr;
+}
+
+/* iop13xx_atue_cfg_address - format a configuration address for atue
+ * @bus: Target bus to access
+ * @devfn: Combined device number and function number
+ * @where: Desired register's address offset
+ *
+ * Convert the parameters to an address usable by the ATUE_OCCAR
+ */
+static u32 iop13xx_atue_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ u32 addr;
+
+ PRINTK("iop13xx_atue_cfg_address: bus: %d dev: %d func: %d",
+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ addr = ((u32) bus->number) << IOP13XX_ATUE_OCCAR_BUS_NUM |
+ ((u32) PCI_SLOT(devfn)) << IOP13XX_ATUE_OCCAR_DEV_NUM |
+ ((u32) PCI_FUNC(devfn)) << IOP13XX_ATUE_OCCAR_FUNC_NUM |
+ (where & ~0x3);
+
+ if (sys->busnr != bus->number)
+ addr |= 1; /* type 1 access */
+
+ return addr;
+}
+
+/* This routine checks the status of the last configuration cycle. If an error
+ * was detected it returns >0, else it returns a 0. The errors being checked
+ * are parity, master abort, target abort (master and target). These types of
+ * errors occur during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop13xx_atux_pci_status(int clear)
+{
+ unsigned int status;
+ int err = 0;
+
+ /*
+ * Check the status registers.
+ */
+ status = __raw_readw(IOP13XX_ATUX_ATUSR);
+ if (status & IOP_PCI_STATUS_ERROR)
+ {
+ PRINTK("\t\t\tPCI error: ATUSR %#08x", status);
+ if(clear)
+ __raw_writew(status & IOP_PCI_STATUS_ERROR,
+ IOP13XX_ATUX_ATUSR);
+ err = 1;
+ }
+ status = __raw_readl(IOP13XX_ATUX_ATUISR);
+ if (status & IOP13XX_ATUX_ATUISR_ERROR)
+ {
+ PRINTK("\t\t\tPCI error interrupt: ATUISR %#08x", status);
+ if(clear)
+ __raw_writel(status & IOP13XX_ATUX_ATUISR_ERROR,
+ IOP13XX_ATUX_ATUISR);
+ err = 1;
+ }
+ return err;
+}
+
+/* Simply write the address register and read the configuration
+ * data. Note that the data dependency on %0 encourages an abort
+ * to be detected before we return.
+ */
+static u32 iop13xx_atux_read(unsigned long addr)
+{
+ u32 val;
+
+ __asm__ __volatile__(
+ "str %1, [%2]\n\t"
+ "ldr %0, [%3]\n\t"
+ "mov %0, %0\n\t"
+ : "=r" (val)
+ : "r" (addr), "r" (IOP13XX_ATUX_OCCAR), "r" (IOP13XX_ATUX_OCCDR));
+
+ return val;
+}
+
+/* The read routines must check the error status of the last configuration
+ * cycle. If there was an error, the routine returns all hex f's.
+ */
+static int
+iop13xx_atux_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where);
+ u32 val = iop13xx_atux_read(addr) >> ((where & 3) * 8);
+
+ if (iop13xx_atux_pci_status(1) || is_atux_occdr_error()) {
+ __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3,
+ IOP13XX_XBG_BECSR);
+ val = 0xffffffff;
+ }
+
+ *value = val;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop13xx_atux_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where);
+ u32 val;
+
+ if (size != 4) {
+ val = iop13xx_atux_read(addr);
+ if (!iop13xx_atux_pci_status(1) == 0)
+ return PCIBIOS_SUCCESSFUL;
+
+ where = (where & 3) * 8;
+
+ if (size == 1)
+ val &= ~(0xff << where);
+ else
+ val &= ~(0xffff << where);
+
+ __raw_writel(val | value << where, IOP13XX_ATUX_OCCDR);
+ } else {
+ __raw_writel(addr, IOP13XX_ATUX_OCCAR);
+ __raw_writel(value, IOP13XX_ATUX_OCCDR);
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop13xx_atux_ops = {
+ .read = iop13xx_atux_read_config,
+ .write = iop13xx_atux_write_config,
+};
+
+/* This routine checks the status of the last configuration cycle. If an error
+ * was detected it returns >0, else it returns a 0. The errors being checked
+ * are parity, master abort, target abort (master and target). These types of
+ * errors occur during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop13xx_atue_pci_status(int clear)
+{
+ unsigned int status;
+ int err = 0;
+
+ /*
+ * Check the status registers.
+ */
+
+ /* standard pci status register */
+ status = __raw_readw(IOP13XX_ATUE_ATUSR);
+ if (status & IOP_PCI_STATUS_ERROR) {
+ PRINTK("\t\t\tPCI error: ATUSR %#08x", status);
+ if(clear)
+ __raw_writew(status & IOP_PCI_STATUS_ERROR,
+ IOP13XX_ATUE_ATUSR);
+ err++;
+ }
+
+ /* check the normal status bits in the ATUISR */
+ status = __raw_readl(IOP13XX_ATUE_ATUISR);
+ if (status & IOP13XX_ATUE_ATUISR_ERROR) {
+ PRINTK("\t\t\tPCI error: ATUISR %#08x", status);
+ if (clear)
+ __raw_writew(status & IOP13XX_ATUE_ATUISR_ERROR,
+ IOP13XX_ATUE_ATUISR);
+ err++;
+
+ /* check the PCI-E status if the ATUISR reports an interface error */
+ if (status & IOP13XX_ATUE_STAT_PCI_IFACE_ERR) {
+ /* get the unmasked errors */
+ status = __raw_readl(IOP13XX_ATUE_PIE_STS) &
+ ~(__raw_readl(IOP13XX_ATUE_PIE_MSK));
+
+ if (status) {
+ PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x",
+ __raw_readl(IOP13XX_ATUE_PIE_STS));
+ err++;
+ } else {
+ PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x",
+ __raw_readl(IOP13XX_ATUE_PIE_STS));
+ PRINTK("\t\t\tPCI-E error: ATUE_PIE_MSK %#08x",
+ __raw_readl(IOP13XX_ATUE_PIE_MSK));
+ BUG();
+ }
+
+ if(clear)
+ __raw_writel(status, IOP13XX_ATUE_PIE_STS);
+ }
+ }
+
+ return err;
+}
+
+static int
+iop13xx_pcie_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+ WARN_ON(idsel != 0);
+
+ switch (pin) {
+ case 1: return ATUE_INTA;
+ case 2: return ATUE_INTB;
+ case 3: return ATUE_INTC;
+ case 4: return ATUE_INTD;
+ default: return -1;
+ }
+}
+
+static u32 iop13xx_atue_read(unsigned long addr)
+{
+ u32 val;
+
+ __raw_writel(addr, IOP13XX_ATUE_OCCAR);
+ val = __raw_readl(IOP13XX_ATUE_OCCDR);
+
+ rmb();
+
+ return val;
+}
+
+/* The read routines must check the error status of the last configuration
+ * cycle. If there was an error, the routine returns all hex f's.
+ */
+static int
+iop13xx_atue_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ u32 val;
+ unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);
+
+ /* Hide device numbers > 0 on the local PCI-E bus (Type 0 access) */
+ if (!PCI_SLOT(devfn) || (addr & 1)) {
+ val = iop13xx_atue_read(addr) >> ((where & 3) * 8);
+ if( iop13xx_atue_pci_status(1) || is_atue_occdr_error() ) {
+ __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3,
+ IOP13XX_XBG_BECSR);
+ val = 0xffffffff;
+ }
+
+ PRINTK("addr=%#0lx, val=%#010x", addr, val);
+ } else
+ val = 0xffffffff;
+
+ *value = val;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop13xx_atue_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);
+ u32 val;
+
+ if (size != 4) {
+ val = iop13xx_atue_read(addr);
+ if (!iop13xx_atue_pci_status(1) == 0)
+ return PCIBIOS_SUCCESSFUL;
+
+ where = (where & 3) * 8;
+
+ if (size == 1)
+ val &= ~(0xff << where);
+ else
+ val &= ~(0xffff << where);
+
+ __raw_writel(val | value << where, IOP13XX_ATUE_OCCDR);
+ } else {
+ __raw_writel(addr, IOP13XX_ATUE_OCCAR);
+ __raw_writel(value, IOP13XX_ATUE_OCCDR);
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop13xx_atue_ops = {
+ .read = iop13xx_atue_read_config,
+ .write = iop13xx_atue_write_config,
+};
+
+/* When a PCI device does not exist during config cycles, the XScale gets a
+ * bus error instead of returning 0xffffffff. We can't rely on the ATU status
+ * bits to tell us that it was indeed a configuration cycle that caused this
+ * error especially in the case when the ATUE link is down. Instead we rely
+ * on data from the south XSI bridge to validate the abort
+ */
+int
+iop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ PRINTK("Data abort: address = 0x%08lx "
+ "fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx",
+ addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+ PRINTK("IOP13XX_XBG_BECSR: %#10x", __raw_readl(IOP13XX_XBG_BECSR));
+ PRINTK("IOP13XX_XBG_BERAR: %#10x", __raw_readl(IOP13XX_XBG_BERAR));
+ PRINTK("IOP13XX_XBG_BERUAR: %#10x", __raw_readl(IOP13XX_XBG_BERUAR));
+
+ /* If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+
+ if (is_atue_occdr_error() || is_atux_occdr_error())
+ return 0;
+ else
+ return 1;
+}
+
+/* Scan an IOP13XX PCI bus. nr selects which ATU we use.
+ */
+struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ int which_atu;
+ struct pci_bus *bus = NULL;
+
+ switch (init_atu) {
+ case IOP13XX_INIT_ATU_ATUX:
+ which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX;
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE;
+ break;
+ case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE):
+ which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX;
+ break;
+ default:
+ which_atu = 0;
+ }
+
+ if (!which_atu) {
+ BUG();
+ return NULL;
+ }
+
+ switch (which_atu) {
+ case IOP13XX_INIT_ATU_ATUX:
+ if (time_after_eq(jiffies + msecs_to_jiffies(1000),
+ atux_trhfa_timeout)) /* ensure not wrap */
+ while(time_before(jiffies, atux_trhfa_timeout))
+ udelay(100);
+
+ bus = pci_bus_atux = pci_scan_bus(sys->busnr,
+ &iop13xx_atux_ops,
+ sys);
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ bus = pci_bus_atue = pci_scan_bus(sys->busnr,
+ &iop13xx_atue_ops,
+ sys);
+ break;
+ }
+
+ return bus;
+}
+
+/* This function is called from iop13xx_pci_init() after assigning valid
+ * values to iop13xx_atue_pmmr_offset. This is the location for common
+ * setup of ATUE for all IOP13XX implementations.
+ */
+void __init iop13xx_atue_setup(void)
+{
+ int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUE);
+ u32 reg_val;
+
+#ifdef CONFIG_PCI_MSI
+ /* BAR 0 (inbound msi window) */
+ __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);
+ __raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUE_IALR0);
+ __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUE_IATVR0);
+ __raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUE_IABAR0);
+#endif
+
+ /* BAR 1 (1:1 mapping with Physical RAM) */
+ /* Set limit and enable */
+ __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,
+ IOP13XX_ATUE_IALR1);
+ __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);
+
+ /* Set base at the top of the reserved address space */
+ __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |
+ PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUE_IABAR1);
+
+ /* 1:1 mapping with physical ram
+ * (leave big endian byte swap disabled)
+ */
+ __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);
+ __raw_writel(PHYS_OFFSET, IOP13XX_ATUE_IATVR1);
+
+ /* Outbound window 1 (PCIX/PCIE memory window) */
+ /* 32 bit Address Space */
+ __raw_writel(0x0, IOP13XX_ATUE_OUMWTVR1);
+ /* PA[35:32] */
+ __raw_writel(IOP13XX_ATUE_OUMBAR_ENABLE |
+ (IOP13XX_PCIE_MEM_PHYS_OFFSET >> 32),
+ IOP13XX_ATUE_OUMBAR1);
+
+ /* Setup the I/O Bar
+ * A[35-16] in 31-12
+ */
+ __raw_writel(((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000),
+ IOP13XX_ATUE_OIOBAR);
+ __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);
+
+ /* clear startup errors */
+ iop13xx_atue_pci_status(1);
+
+ /* OIOBAR function number
+ */
+ reg_val = __raw_readl(IOP13XX_ATUE_OIOBAR);
+ reg_val &= ~0x7;
+ reg_val |= func;
+ __raw_writel(reg_val, IOP13XX_ATUE_OIOBAR);
+
+ /* OUMBAR function numbers
+ */
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);
+
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);
+
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);
+
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);
+
+ /* Enable inbound and outbound cycles
+ */
+ reg_val = __raw_readw(IOP13XX_ATUE_ATUCMD);
+ reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ __raw_writew(reg_val, IOP13XX_ATUE_ATUCMD);
+
+ reg_val = __raw_readl(IOP13XX_ATUE_ATUCR);
+ reg_val |= IOP13XX_ATUE_ATUCR_OUT_EN |
+ IOP13XX_ATUE_ATUCR_IVM;
+ __raw_writel(reg_val, IOP13XX_ATUE_ATUCR);
+}
+
+void __init iop13xx_atue_disable(void)
+{
+ u32 reg_val;
+
+ __raw_writew(0x0, IOP13XX_ATUE_ATUCMD);
+ __raw_writel(IOP13XX_ATUE_ATUCR_IVM, IOP13XX_ATUE_ATUCR);
+
+ /* wait for cycles to quiesce */
+ while (__raw_readl(IOP13XX_ATUE_PCSR) & (IOP13XX_ATUE_PCSR_OUT_Q_BUSY |
+ IOP13XX_ATUE_PCSR_IN_Q_BUSY |
+ IOP13XX_ATUE_PCSR_LLRB_BUSY))
+ cpu_relax();
+
+ /* BAR 0 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUE_IAUBAR0);
+ __raw_writel(0x0, IOP13XX_ATUE_IABAR0);
+ __raw_writel(0x0, IOP13XX_ATUE_IAUTVR0);
+ __raw_writel(0x0, IOP13XX_ATUE_IATVR0);
+ __raw_writel(0x0, IOP13XX_ATUE_IALR0);
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);
+ reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);
+
+ /* BAR 1 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);
+ __raw_writel(0x0, IOP13XX_ATUE_IABAR1);
+ __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);
+ __raw_writel(0x0, IOP13XX_ATUE_IATVR1);
+ __raw_writel(0x0, IOP13XX_ATUE_IALR1);
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);
+ reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);
+
+ /* BAR 2 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUE_IAUBAR2);
+ __raw_writel(0x0, IOP13XX_ATUE_IABAR2);
+ __raw_writel(0x0, IOP13XX_ATUE_IAUTVR2);
+ __raw_writel(0x0, IOP13XX_ATUE_IATVR2);
+ __raw_writel(0x0, IOP13XX_ATUE_IALR2);
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);
+ reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);
+
+ /* BAR 3 ( Disabled ) */
+ reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);
+ reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);
+
+ /* Setup the I/O Bar
+ * A[35-16] in 31-12
+ */
+ __raw_writel((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000,
+ IOP13XX_ATUE_OIOBAR);
+ __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);
+}
+
+/* This function is called from iop13xx_pci_init() after assigning valid
+ * values to iop13xx_atux_pmmr_offset. This is the location for common
+ * setup of ATUX for all IOP13XX implementations.
+ */
+void __init iop13xx_atux_setup(void)
+{
+ u32 reg_val;
+ int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX);
+
+ /* Take PCI-X bus out of reset if bootloader hasn't already.
+ * According to spec, we should wait for 2^25 PCI clocks to meet
+ * the PCI timing parameter Trhfa (RST# high to first access).
+ * This is rarely necessary and often ignored.
+ */
+ reg_val = __raw_readl(IOP13XX_ATUX_PCSR);
+ if (reg_val & IOP13XX_ATUX_PCSR_P_RSTOUT) {
+ int msec = (reg_val >> IOP13XX_ATUX_PCSR_FREQ_OFFSET) & 0x7;
+ msec = 1000 / (8-msec); /* bits 100=133MHz, 111=>33MHz */
+ __raw_writel(reg_val & ~IOP13XX_ATUX_PCSR_P_RSTOUT,
+ IOP13XX_ATUX_PCSR);
+ atux_trhfa_timeout = jiffies + msecs_to_jiffies(msec);
+ }
+ else
+ atux_trhfa_timeout = jiffies;
+
+#ifdef CONFIG_PCI_MSI
+ /* BAR 0 (inbound msi window) */
+ __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);
+ __raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUX_IALR0);
+ __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUX_IATVR0);
+ __raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUX_IABAR0);
+#endif
+
+ /* BAR 1 (1:1 mapping with Physical RAM) */
+ /* Set limit and enable */
+ __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,
+ IOP13XX_ATUX_IALR1);
+ __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);
+
+ /* Set base at the top of the reserved address space */
+ __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |
+ PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUX_IABAR1);
+
+ /* 1:1 mapping with physical ram
+ * (leave big endian byte swap disabled)
+ */
+ __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);
+ __raw_writel(PHYS_OFFSET, IOP13XX_ATUX_IATVR1);
+
+ /* Outbound window 1 (PCIX/PCIE memory window) */
+ /* 32 bit Address Space */
+ __raw_writel(0x0, IOP13XX_ATUX_OUMWTVR1);
+ /* PA[35:32] */
+ __raw_writel(IOP13XX_ATUX_OUMBAR_ENABLE |
+ IOP13XX_PCIX_MEM_PHYS_OFFSET >> 32,
+ IOP13XX_ATUX_OUMBAR1);
+
+ /* Setup the I/O Bar
+ * A[35-16] in 31-12
+ */
+ __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,
+ IOP13XX_ATUX_OIOBAR);
+ __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);
+
+ /* clear startup errors */
+ iop13xx_atux_pci_status(1);
+
+ /* OIOBAR function number
+ */
+ reg_val = __raw_readl(IOP13XX_ATUX_OIOBAR);
+ reg_val &= ~0x7;
+ reg_val |= func;
+ __raw_writel(reg_val, IOP13XX_ATUX_OIOBAR);
+
+ /* OUMBAR function numbers
+ */
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0);
+
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1);
+
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2);
+
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3);
+ reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
+ IOP13XX_ATU_OUMBAR_FUNC_NUM);
+ reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3);
+
+ /* Enable inbound and outbound cycles
+ */
+ reg_val = __raw_readw(IOP13XX_ATUX_ATUCMD);
+ reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ __raw_writew(reg_val, IOP13XX_ATUX_ATUCMD);
+
+ reg_val = __raw_readl(IOP13XX_ATUX_ATUCR);
+ reg_val |= IOP13XX_ATUX_ATUCR_OUT_EN;
+ __raw_writel(reg_val, IOP13XX_ATUX_ATUCR);
+}
+
+void __init iop13xx_atux_disable(void)
+{
+ u32 reg_val;
+
+ __raw_writew(0x0, IOP13XX_ATUX_ATUCMD);
+ __raw_writel(0x0, IOP13XX_ATUX_ATUCR);
+
+ /* wait for cycles to quiesce */
+ while (__raw_readl(IOP13XX_ATUX_PCSR) & (IOP13XX_ATUX_PCSR_OUT_Q_BUSY |
+ IOP13XX_ATUX_PCSR_IN_Q_BUSY))
+ cpu_relax();
+
+ /* BAR 0 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUX_IAUBAR0);
+ __raw_writel(0x0, IOP13XX_ATUX_IABAR0);
+ __raw_writel(0x0, IOP13XX_ATUX_IAUTVR0);
+ __raw_writel(0x0, IOP13XX_ATUX_IATVR0);
+ __raw_writel(0x0, IOP13XX_ATUX_IALR0);
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0);
+ reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0);
+
+ /* BAR 1 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);
+ __raw_writel(0x0, IOP13XX_ATUX_IABAR1);
+ __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);
+ __raw_writel(0x0, IOP13XX_ATUX_IATVR1);
+ __raw_writel(0x0, IOP13XX_ATUX_IALR1);
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1);
+ reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1);
+
+ /* BAR 2 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUX_IAUBAR2);
+ __raw_writel(0x0, IOP13XX_ATUX_IABAR2);
+ __raw_writel(0x0, IOP13XX_ATUX_IAUTVR2);
+ __raw_writel(0x0, IOP13XX_ATUX_IATVR2);
+ __raw_writel(0x0, IOP13XX_ATUX_IALR2);
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2);
+ reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2);
+
+ /* BAR 3 ( Disabled ) */
+ __raw_writel(0x0, IOP13XX_ATUX_IAUBAR3);
+ __raw_writel(0x0, IOP13XX_ATUX_IABAR3);
+ __raw_writel(0x0, IOP13XX_ATUX_IAUTVR3);
+ __raw_writel(0x0, IOP13XX_ATUX_IATVR3);
+ __raw_writel(0x0, IOP13XX_ATUX_IALR3);
+ reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3);
+ reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
+ __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3);
+
+ /* Setup the I/O Bar
+ * A[35-16] in 31-12
+ */
+ __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,
+ IOP13XX_ATUX_OIOBAR);
+ __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);
+}
+
+void __init iop13xx_set_atu_mmr_bases(void)
+{
+ /* Based on ESSR0, determine the ATU X/E offsets */
+ switch(__raw_readl(IOP13XX_ESSR0) &
+ (IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX)) {
+ /* both asserted */
+ case 0:
+ iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;
+ iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
+ break;
+ /* IOP13XX_CONTROLLER_ONLY = deasserted
+ * IOP13XX_INTERFACE_SEL_PCIX = asserted
+ */
+ case IOP13XX_CONTROLLER_ONLY:
+ iop13xx_atux_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;
+ iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
+ break;
+ /* IOP13XX_CONTROLLER_ONLY = asserted
+ * IOP13XX_INTERFACE_SEL_PCIX = deasserted
+ */
+ case IOP13XX_INTERFACE_SEL_PCIX:
+ iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;
+ iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
+ break;
+ /* both deasserted */
+ case IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX:
+ iop13xx_atux_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
+ iop13xx_atue_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;
+ break;
+ default:
+ BUG();
+ }
+}
+
+void __init iop13xx_atu_select(struct hw_pci *plat_pci)
+{
+ int i;
+
+ /* set system defaults
+ * note: if "iop13xx_init_atu=" is specified this autodetect
+ * sequence will be bypassed
+ */
+ if (init_atu == IOP13XX_INIT_ATU_DEFAULT) {
+ /* check for single/dual interface */
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) {
+ /* ATUE must be present check the device id
+ * to see if ATUX is present.
+ */
+ init_atu |= IOP13XX_INIT_ATU_ATUE;
+ switch (__raw_readw(IOP13XX_ATUE_DID) & 0xf0) {
+ case 0x70:
+ case 0x80:
+ case 0xc0:
+ init_atu |= IOP13XX_INIT_ATU_ATUX;
+ break;
+ }
+ } else {
+ /* ATUX must be present check the device id
+ * to see if ATUE is present.
+ */
+ init_atu |= IOP13XX_INIT_ATU_ATUX;
+ switch (__raw_readw(IOP13XX_ATUX_DID) & 0xf0) {
+ case 0x70:
+ case 0x80:
+ case 0xc0:
+ init_atu |= IOP13XX_INIT_ATU_ATUE;
+ break;
+ }
+ }
+
+ /* check central resource and root complex capability */
+ if (init_atu & IOP13XX_INIT_ATU_ATUX)
+ if (!(__raw_readl(IOP13XX_ATUX_PCSR) &
+ IOP13XX_ATUX_PCSR_CENTRAL_RES))
+ init_atu &= ~IOP13XX_INIT_ATU_ATUX;
+
+ if (init_atu & IOP13XX_INIT_ATU_ATUE)
+ if (__raw_readl(IOP13XX_ATUE_PCSR) &
+ IOP13XX_ATUE_PCSR_END_POINT)
+ init_atu &= ~IOP13XX_INIT_ATU_ATUE;
+ }
+
+ for (i = 0; i < 2; i++) {
+ if((init_atu & (1 << i)) == (1 << i))
+ plat_pci->nr_controllers++;
+ }
+}
+
+void __init iop13xx_pci_init(void)
+{
+ /* clear pre-existing south bridge errors */
+ __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR);
+
+ /* Setup the Min Address for PCI memory... */
+ iop13xx_pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA;
+
+ /* if Linux is given control of an ATU
+ * clear out its prior configuration,
+ * otherwise do not touch the registers
+ */
+ if (init_atu & IOP13XX_INIT_ATU_ATUE) {
+ iop13xx_atue_disable();
+ iop13xx_atue_setup();
+ }
+
+ if (init_atu & IOP13XX_INIT_ATU_ATUX) {
+ iop13xx_atux_disable();
+ iop13xx_atux_setup();
+ }
+
+ hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, 0,
+ "imprecise external abort");
+}
+
+/* initialize the pci memory space. handle any combination of
+ * atue and atux enabled/disabled
+ */
+int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ struct resource *res;
+ int which_atu;
+ u32 pcixsr, pcsr;
+
+ if (nr > 1)
+ return 0;
+
+ res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ panic("PCI: unable to alloc resources");
+
+
+ /* 'nr' assumptions:
+ * ATUX is always 0
+ * ATUE is 1 when ATUX is also enabled
+ * ATUE is 0 when ATUX is disabled
+ */
+ switch(init_atu) {
+ case IOP13XX_INIT_ATU_ATUX:
+ which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX;
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE;
+ break;
+ case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE):
+ which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX;
+ break;
+ default:
+ which_atu = 0;
+ }
+
+ if (!which_atu) {
+ kfree(res);
+ return 0;
+ }
+
+ switch(which_atu) {
+ case IOP13XX_INIT_ATU_ATUX:
+ pcixsr = __raw_readl(IOP13XX_ATUX_PCIXSR);
+ pcixsr &= ~0xffff;
+ pcixsr |= sys->busnr << IOP13XX_ATUX_PCIXSR_BUS_NUM |
+ 0 << IOP13XX_ATUX_PCIXSR_DEV_NUM |
+ iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX)
+ << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
+ __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
+
+ res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
+ res[0].end = IOP13XX_PCIX_UPPER_IO_PA;
+ res[0].name = "IQ81340 ATUX PCI I/O Space";
+ res[0].flags = IORESOURCE_IO;
+
+ res[1].start = IOP13XX_PCIX_LOWER_MEM_RA;
+ res[1].end = IOP13XX_PCIX_UPPER_MEM_RA;
+ res[1].name = "IQ81340 ATUX PCI Memory Space";
+ res[1].flags = IORESOURCE_MEM;
+ sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
+ sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
+ break;
+ case IOP13XX_INIT_ATU_ATUE:
+ /* Note: the function number field in the PCSR is ro */
+ pcsr = __raw_readl(IOP13XX_ATUE_PCSR);
+ pcsr &= ~(0xfff8 << 16);
+ pcsr |= sys->busnr << IOP13XX_ATUE_PCSR_BUS_NUM |
+ 0 << IOP13XX_ATUE_PCSR_DEV_NUM;
+
+ __raw_writel(pcsr, IOP13XX_ATUE_PCSR);
+
+ res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
+ res[0].end = IOP13XX_PCIE_UPPER_IO_PA;
+ res[0].name = "IQ81340 ATUE PCI I/O Space";
+ res[0].flags = IORESOURCE_IO;
+
+ res[1].start = IOP13XX_PCIE_LOWER_MEM_RA;
+ res[1].end = IOP13XX_PCIE_UPPER_MEM_RA;
+ res[1].name = "IQ81340 ATUE PCI Memory Space";
+ res[1].flags = IORESOURCE_MEM;
+ sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
+ sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
+ sys->map_irq = iop13xx_pcie_map_irq;
+ break;
+ default:
+ kfree(res);
+ return 0;
+ }
+
+ request_resource(&ioport_resource, &res[0]);
+ request_resource(&iomem_resource, &res[1]);
+
+ sys->resource[0] = &res[0];
+ sys->resource[1] = &res[1];
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+u16 iop13xx_dev_id(void)
+{
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+ return __raw_readw(IOP13XX_ATUE_DID);
+ else
+ return __raw_readw(IOP13XX_ATUX_DID);
+}
+
+static int __init iop13xx_init_atu_setup(char *str)
+{
+ init_atu = IOP13XX_INIT_ATU_NONE;
+ if (str) {
+ while (*str != '\0') {
+ switch (*str) {
+ case 'x':
+ case 'X':
+ init_atu |= IOP13XX_INIT_ATU_ATUX;
+ init_atu &= ~IOP13XX_INIT_ATU_NONE;
+ break;
+ case 'e':
+ case 'E':
+ init_atu |= IOP13XX_INIT_ATU_ATUE;
+ init_atu &= ~IOP13XX_INIT_ATU_NONE;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ PRINTK("\"iop13xx_init_atu\" malformed at "
+ "character: \'%c\'", *str);
+ *(str + 1) = '\0';
+ init_atu = IOP13XX_INIT_ATU_DEFAULT;
+ }
+ str++;
+ }
+ }
+ return 1;
+}
+
+__setup("iop13xx_init_atu", iop13xx_init_atu_setup);
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
new file mode 100644
index 00000000..a5b98972
--- /dev/null
+++ b/arch/arm/mach-iop13xx/setup.c
@@ -0,0 +1,608 @@
+/*
+ * iop13xx platform Initialization
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+#ifdef CONFIG_MTD_PHYSMAP
+#include <linux/mtd/physmap.h>
+#endif
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/hardware/iop_adma.h>
+
+#define IOP13XX_UART_XTAL 33334000
+#define IOP13XX_SETUP_DEBUG 0
+#define PRINTK(x...) ((void)(IOP13XX_SETUP_DEBUG && printk(x)))
+
+/* Standard IO mapping for all IOP13XX based systems
+ */
+static struct map_desc iop13xx_std_desc[] __initdata = {
+ { /* mem mapped registers */
+ .virtual = IOP13XX_PMMR_VIRT_MEM_BASE,
+ .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE),
+ .length = IOP13XX_PMMR_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCIE IO space */
+ .virtual = IOP13XX_PCIE_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA),
+ .length = IOP13XX_PCIX_IO_WINDOW_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCIX IO space */
+ .virtual = IOP13XX_PCIX_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA),
+ .length = IOP13XX_PCIX_IO_WINDOW_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct resource iop13xx_uart0_resources[] = {
+ [0] = {
+ .start = IOP13XX_UART0_PHYS,
+ .end = IOP13XX_UART0_PHYS + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_UART0,
+ .end = IRQ_IOP13XX_UART0,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_uart1_resources[] = {
+ [0] = {
+ .start = IOP13XX_UART1_PHYS,
+ .end = IOP13XX_UART1_PHYS + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_UART1,
+ .end = IRQ_IOP13XX_UART1,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct plat_serial8250_port iop13xx_uart0_data[] = {
+ {
+ .membase = (char*)(IOP13XX_UART0_VIRT),
+ .mapbase = (IOP13XX_UART0_PHYS),
+ .irq = IRQ_IOP13XX_UART0,
+ .uartclk = IOP13XX_UART_XTAL,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct plat_serial8250_port iop13xx_uart1_data[] = {
+ {
+ .membase = (char*)(IOP13XX_UART1_VIRT),
+ .mapbase = (IOP13XX_UART1_PHYS),
+ .irq = IRQ_IOP13XX_UART1,
+ .uartclk = IOP13XX_UART_XTAL,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_SKIP_TEST,
+ },
+ { },
+};
+
+/* The ids are fixed up later in iop13xx_platform_init */
+static struct platform_device iop13xx_uart0 = {
+ .name = "serial8250",
+ .id = 0,
+ .dev.platform_data = iop13xx_uart0_data,
+ .num_resources = 2,
+ .resource = iop13xx_uart0_resources,
+};
+
+static struct platform_device iop13xx_uart1 = {
+ .name = "serial8250",
+ .id = 0,
+ .dev.platform_data = iop13xx_uart1_data,
+ .num_resources = 2,
+ .resource = iop13xx_uart1_resources
+};
+
+static struct resource iop13xx_i2c_0_resources[] = {
+ [0] = {
+ .start = IOP13XX_I2C0_PHYS,
+ .end = IOP13XX_I2C0_PHYS + 0x18,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_I2C_0,
+ .end = IRQ_IOP13XX_I2C_0,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_i2c_1_resources[] = {
+ [0] = {
+ .start = IOP13XX_I2C1_PHYS,
+ .end = IOP13XX_I2C1_PHYS + 0x18,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_I2C_1,
+ .end = IRQ_IOP13XX_I2C_1,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_i2c_2_resources[] = {
+ [0] = {
+ .start = IOP13XX_I2C2_PHYS,
+ .end = IOP13XX_I2C2_PHYS + 0x18,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_I2C_2,
+ .end = IRQ_IOP13XX_I2C_2,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+/* I2C controllers. The IOP13XX uses the same block as the IOP3xx, so
+ * we just use the same device name.
+ */
+
+/* The ids are fixed up later in iop13xx_platform_init */
+static struct platform_device iop13xx_i2c_0_controller = {
+ .name = "IOP3xx-I2C",
+ .id = 0,
+ .num_resources = 2,
+ .resource = iop13xx_i2c_0_resources
+};
+
+static struct platform_device iop13xx_i2c_1_controller = {
+ .name = "IOP3xx-I2C",
+ .id = 0,
+ .num_resources = 2,
+ .resource = iop13xx_i2c_1_resources
+};
+
+static struct platform_device iop13xx_i2c_2_controller = {
+ .name = "IOP3xx-I2C",
+ .id = 0,
+ .num_resources = 2,
+ .resource = iop13xx_i2c_2_resources
+};
+
+#ifdef CONFIG_MTD_PHYSMAP
+/* PBI Flash Device
+ */
+static struct physmap_flash_data iq8134x_flash_data = {
+ .width = 2,
+};
+
+static struct resource iq8134x_flash_resource = {
+ .start = IQ81340_FLASHBASE,
+ .end = 0,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq8134x_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = { .platform_data = &iq8134x_flash_data, },
+ .num_resources = 1,
+ .resource = &iq8134x_flash_resource,
+};
+
+static unsigned long iq8134x_probe_flash_size(void)
+{
+ uint8_t __iomem *flash_addr = ioremap(IQ81340_FLASHBASE, PAGE_SIZE);
+ int i;
+ char query[3];
+ unsigned long size = 0;
+ int width = iq8134x_flash_data.width;
+
+ if (flash_addr) {
+ /* send CFI 'query' command */
+ writew(0x98, flash_addr);
+
+ /* check for CFI compliance */
+ for (i = 0; i < 3 * width; i += width)
+ query[i / width] = readb(flash_addr + (0x10 * width) + i);
+
+ /* read the size */
+ if (memcmp(query, "QRY", 3) == 0)
+ size = 1 << readb(flash_addr + (0x27 * width));
+
+ /* send CFI 'read array' command */
+ writew(0xff, flash_addr);
+
+ iounmap(flash_addr);
+ }
+
+ return size;
+}
+#endif
+
+/* ADMA Channels */
+static struct resource iop13xx_adma_0_resources[] = {
+ [0] = {
+ .start = IOP13XX_ADMA_PHYS_BASE(0),
+ .end = IOP13XX_ADMA_UPPER_PA(0),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_ADMA0_EOT,
+ .end = IRQ_IOP13XX_ADMA0_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_IOP13XX_ADMA0_EOC,
+ .end = IRQ_IOP13XX_ADMA0_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_IOP13XX_ADMA0_ERR,
+ .end = IRQ_IOP13XX_ADMA0_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_adma_1_resources[] = {
+ [0] = {
+ .start = IOP13XX_ADMA_PHYS_BASE(1),
+ .end = IOP13XX_ADMA_UPPER_PA(1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_ADMA1_EOT,
+ .end = IRQ_IOP13XX_ADMA1_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_IOP13XX_ADMA1_EOC,
+ .end = IRQ_IOP13XX_ADMA1_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_IOP13XX_ADMA1_ERR,
+ .end = IRQ_IOP13XX_ADMA1_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_adma_2_resources[] = {
+ [0] = {
+ .start = IOP13XX_ADMA_PHYS_BASE(2),
+ .end = IOP13XX_ADMA_UPPER_PA(2),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP13XX_ADMA2_EOT,
+ .end = IRQ_IOP13XX_ADMA2_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_IOP13XX_ADMA2_EOC,
+ .end = IRQ_IOP13XX_ADMA2_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_IOP13XX_ADMA2_ERR,
+ .end = IRQ_IOP13XX_ADMA2_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(64);
+static struct iop_adma_platform_data iop13xx_adma_0_data = {
+ .hw_id = 0,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct iop_adma_platform_data iop13xx_adma_1_data = {
+ .hw_id = 1,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct iop_adma_platform_data iop13xx_adma_2_data = {
+ .hw_id = 2,
+ .pool_size = PAGE_SIZE,
+};
+
+/* The ids are fixed up later in iop13xx_platform_init */
+static struct platform_device iop13xx_adma_0_channel = {
+ .name = "iop-adma",
+ .id = 0,
+ .num_resources = 4,
+ .resource = iop13xx_adma_0_resources,
+ .dev = {
+ .dma_mask = &iop13xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop13xx_adma_0_data,
+ },
+};
+
+static struct platform_device iop13xx_adma_1_channel = {
+ .name = "iop-adma",
+ .id = 0,
+ .num_resources = 4,
+ .resource = iop13xx_adma_1_resources,
+ .dev = {
+ .dma_mask = &iop13xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop13xx_adma_1_data,
+ },
+};
+
+static struct platform_device iop13xx_adma_2_channel = {
+ .name = "iop-adma",
+ .id = 0,
+ .num_resources = 4,
+ .resource = iop13xx_adma_2_resources,
+ .dev = {
+ .dma_mask = &iop13xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop13xx_adma_2_data,
+ },
+};
+
+void __init iop13xx_map_io(void)
+{
+ /* Initialize the Static Page Table maps */
+ iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc));
+}
+
+static int init_uart;
+static int init_i2c;
+static int init_adma;
+
+void __init iop13xx_platform_init(void)
+{
+ int i;
+ u32 uart_idx, i2c_idx, adma_idx, plat_idx;
+ struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES];
+
+ /* set the bases so we can read the device id */
+ iop13xx_set_atu_mmr_bases();
+
+ memset(iop13xx_devices, 0, sizeof(iop13xx_devices));
+
+ if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
+ switch (iop13xx_dev_id()) {
+ /* enable both uarts on iop341 */
+ case 0x3380:
+ case 0x3384:
+ case 0x3388:
+ case 0x338c:
+ init_uart |= IOP13XX_INIT_UART_0;
+ init_uart |= IOP13XX_INIT_UART_1;
+ break;
+ /* only enable uart 1 */
+ default:
+ init_uart |= IOP13XX_INIT_UART_1;
+ }
+ }
+
+ if (init_i2c == IOP13XX_INIT_I2C_DEFAULT) {
+ switch (iop13xx_dev_id()) {
+ /* enable all i2c units on iop341 and iop342 */
+ case 0x3380:
+ case 0x3384:
+ case 0x3388:
+ case 0x338c:
+ case 0x3382:
+ case 0x3386:
+ case 0x338a:
+ case 0x338e:
+ init_i2c |= IOP13XX_INIT_I2C_0;
+ init_i2c |= IOP13XX_INIT_I2C_1;
+ init_i2c |= IOP13XX_INIT_I2C_2;
+ break;
+ /* only enable i2c 1 and 2 */
+ default:
+ init_i2c |= IOP13XX_INIT_I2C_1;
+ init_i2c |= IOP13XX_INIT_I2C_2;
+ }
+ }
+
+ if (init_adma == IOP13XX_INIT_ADMA_DEFAULT) {
+ init_adma |= IOP13XX_INIT_ADMA_0;
+ init_adma |= IOP13XX_INIT_ADMA_1;
+ init_adma |= IOP13XX_INIT_ADMA_2;
+ }
+
+ plat_idx = 0;
+ uart_idx = 0;
+ i2c_idx = 0;
+
+ /* uart 1 (if enabled) is ttyS0 */
+ if (init_uart & IOP13XX_INIT_UART_1) {
+ PRINTK("Adding uart1 to platform device list\n");
+ iop13xx_uart1.id = uart_idx++;
+ iop13xx_devices[plat_idx++] = &iop13xx_uart1;
+ }
+ if (init_uart & IOP13XX_INIT_UART_0) {
+ PRINTK("Adding uart0 to platform device list\n");
+ iop13xx_uart0.id = uart_idx++;
+ iop13xx_devices[plat_idx++] = &iop13xx_uart0;
+ }
+
+ for(i = 0; i < IQ81340_NUM_I2C; i++) {
+ if ((init_i2c & (1 << i)) && IOP13XX_SETUP_DEBUG)
+ printk("Adding i2c%d to platform device list\n", i);
+ switch(init_i2c & (1 << i)) {
+ case IOP13XX_INIT_I2C_0:
+ iop13xx_i2c_0_controller.id = i2c_idx++;
+ iop13xx_devices[plat_idx++] =
+ &iop13xx_i2c_0_controller;
+ break;
+ case IOP13XX_INIT_I2C_1:
+ iop13xx_i2c_1_controller.id = i2c_idx++;
+ iop13xx_devices[plat_idx++] =
+ &iop13xx_i2c_1_controller;
+ break;
+ case IOP13XX_INIT_I2C_2:
+ iop13xx_i2c_2_controller.id = i2c_idx++;
+ iop13xx_devices[plat_idx++] =
+ &iop13xx_i2c_2_controller;
+ break;
+ }
+ }
+
+ /* initialize adma channel ids and capabilities */
+ adma_idx = 0;
+ for (i = 0; i < IQ81340_NUM_ADMA; i++) {
+ struct iop_adma_platform_data *plat_data;
+ if ((init_adma & (1 << i)) && IOP13XX_SETUP_DEBUG)
+ printk(KERN_INFO
+ "Adding adma%d to platform device list\n", i);
+ switch (init_adma & (1 << i)) {
+ case IOP13XX_INIT_ADMA_0:
+ iop13xx_adma_0_channel.id = adma_idx++;
+ iop13xx_devices[plat_idx++] = &iop13xx_adma_0_channel;
+ plat_data = &iop13xx_adma_0_data;
+ dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
+ dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
+ dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
+ break;
+ case IOP13XX_INIT_ADMA_1:
+ iop13xx_adma_1_channel.id = adma_idx++;
+ iop13xx_devices[plat_idx++] = &iop13xx_adma_1_channel;
+ plat_data = &iop13xx_adma_1_data;
+ dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
+ dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
+ dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
+ break;
+ case IOP13XX_INIT_ADMA_2:
+ iop13xx_adma_2_channel.id = adma_idx++;
+ iop13xx_devices[plat_idx++] = &iop13xx_adma_2_channel;
+ plat_data = &iop13xx_adma_2_data;
+ dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR, plat_data->cap_mask);
+ dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
+ dma_cap_set(DMA_MEMSET, plat_data->cap_mask);
+ dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
+ dma_cap_set(DMA_PQ, plat_data->cap_mask);
+ dma_cap_set(DMA_PQ_VAL, plat_data->cap_mask);
+ break;
+ }
+ }
+
+#ifdef CONFIG_MTD_PHYSMAP
+ iq8134x_flash_resource.end = iq8134x_flash_resource.start +
+ iq8134x_probe_flash_size() - 1;
+ if (iq8134x_flash_resource.end > iq8134x_flash_resource.start)
+ iop13xx_devices[plat_idx++] = &iq8134x_flash;
+ else
+ printk(KERN_ERR "%s: Failed to probe flash size\n", __func__);
+#endif
+
+ platform_add_devices(iop13xx_devices, plat_idx);
+}
+
+static int __init iop13xx_init_uart_setup(char *str)
+{
+ if (str) {
+ while (*str != '\0') {
+ switch(*str) {
+ case '0':
+ init_uart |= IOP13XX_INIT_UART_0;
+ break;
+ case '1':
+ init_uart |= IOP13XX_INIT_UART_1;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ PRINTK("\"iop13xx_init_uart\" malformed"
+ " at character: \'%c\'", *str);
+ *(str + 1) = '\0';
+ init_uart = IOP13XX_INIT_UART_DEFAULT;
+ }
+ str++;
+ }
+ }
+ return 1;
+}
+
+static int __init iop13xx_init_i2c_setup(char *str)
+{
+ if (str) {
+ while (*str != '\0') {
+ switch(*str) {
+ case '0':
+ init_i2c |= IOP13XX_INIT_I2C_0;
+ break;
+ case '1':
+ init_i2c |= IOP13XX_INIT_I2C_1;
+ break;
+ case '2':
+ init_i2c |= IOP13XX_INIT_I2C_2;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ PRINTK("\"iop13xx_init_i2c\" malformed"
+ " at character: \'%c\'", *str);
+ *(str + 1) = '\0';
+ init_i2c = IOP13XX_INIT_I2C_DEFAULT;
+ }
+ str++;
+ }
+ }
+ return 1;
+}
+
+static int __init iop13xx_init_adma_setup(char *str)
+{
+ if (str) {
+ while (*str != '\0') {
+ switch (*str) {
+ case '0':
+ init_adma |= IOP13XX_INIT_ADMA_0;
+ break;
+ case '1':
+ init_adma |= IOP13XX_INIT_ADMA_1;
+ break;
+ case '2':
+ init_adma |= IOP13XX_INIT_ADMA_2;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ PRINTK("\"iop13xx_init_adma\" malformed"
+ " at character: \'%c\'", *str);
+ *(str + 1) = '\0';
+ init_adma = IOP13XX_INIT_ADMA_DEFAULT;
+ }
+ str++;
+ }
+ }
+ return 1;
+}
+
+__setup("iop13xx_init_adma", iop13xx_init_adma_setup);
+__setup("iop13xx_init_uart", iop13xx_init_uart_setup);
+__setup("iop13xx_init_i2c", iop13xx_init_i2c_setup);
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
new file mode 100644
index 00000000..6fdad7a0
--- /dev/null
+++ b/arch/arm/mach-iop13xx/tpmi.c
@@ -0,0 +1,256 @@
+/*
+ * iop13xx tpmi device resources
+ * Copyright (c) 2005-2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
+#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
+#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
+#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
+#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
+#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1)
+#define IOP13XX_TPMI_MEM_SIZE (255)
+#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1)
+#define IOP13XX_TPMI_RESOURCE_MMR 0
+#define IOP13XX_TPMI_RESOURCE_MEM 1
+#define IOP13XX_TPMI_RESOURCE_CTRL 2
+#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
+#define IOP13XX_TPMI_RESOURCE_IRQ 4
+
+static struct resource iop13xx_tpmi_0_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
+ .end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(0),
+ .end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(0),
+ .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+ .start = IOP13XX_TPMI_IOP_CTRL(0),
+ .end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI0_OUT,
+ .end = IRQ_IOP13XX_TPMI0_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_1_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(1),
+ .end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(1),
+ .end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(1),
+ .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+ .start = IOP13XX_TPMI_IOP_CTRL(1),
+ .end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI1_OUT,
+ .end = IRQ_IOP13XX_TPMI1_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_2_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(2),
+ .end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(2),
+ .end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(2),
+ .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+ .start = IOP13XX_TPMI_IOP_CTRL(2),
+ .end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI2_OUT,
+ .end = IRQ_IOP13XX_TPMI2_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop13xx_tpmi_3_resources[] = {
+ [IOP13XX_TPMI_RESOURCE_MMR] = {
+ .start = IOP13XX_TPMI_MMR(3),
+ .end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_MEM] = {
+ .start = IOP13XX_TPMI_MEM(3),
+ .end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_CTRL] = {
+ .start = IOP13XX_TPMI_CTRL(3),
+ .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
+ .start = IOP13XX_TPMI_IOP_CTRL(3),
+ .end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
+ .flags = IORESOURCE_MEM,
+ },
+ [IOP13XX_TPMI_RESOURCE_IRQ] = {
+ .start = IRQ_IOP13XX_TPMI3_OUT,
+ .end = IRQ_IOP13XX_TPMI3_OUT,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+u64 iop13xx_tpmi_mask = DMA_BIT_MASK(64);
+static struct platform_device iop13xx_tpmi_0_device = {
+ .name = "iop-tpmi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
+ .resource = iop13xx_tpmi_0_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ },
+};
+
+static struct platform_device iop13xx_tpmi_1_device = {
+ .name = "iop-tpmi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
+ .resource = iop13xx_tpmi_1_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ },
+};
+
+static struct platform_device iop13xx_tpmi_2_device = {
+ .name = "iop-tpmi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
+ .resource = iop13xx_tpmi_2_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ },
+};
+
+static struct platform_device iop13xx_tpmi_3_device = {
+ .name = "iop-tpmi",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
+ .resource = iop13xx_tpmi_3_resources,
+ .dev = {
+ .dma_mask = &iop13xx_tpmi_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ },
+};
+
+__init void iop13xx_add_tpmi_devices(void)
+{
+ unsigned short device_id;
+
+ /* tpmi's not present on iop341 or iop342 */
+ if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
+ /* ATUE must be present */
+ device_id = __raw_readw(IOP13XX_ATUE_DID);
+ else
+ /* ATUX must be present */
+ device_id = __raw_readw(IOP13XX_ATUX_DID);
+
+ switch (device_id) {
+ /* iop34[1|2] 0-tpmi */
+ case 0x3380:
+ case 0x3384:
+ case 0x3388:
+ case 0x338c:
+ case 0x3382:
+ case 0x3386:
+ case 0x338a:
+ case 0x338e:
+ return;
+ /* iop348 1-tpmi */
+ case 0x3310:
+ case 0x3312:
+ case 0x3314:
+ case 0x3318:
+ case 0x331a:
+ case 0x331c:
+ case 0x33c0:
+ case 0x33c2:
+ case 0x33c4:
+ case 0x33c8:
+ case 0x33ca:
+ case 0x33cc:
+ case 0x33b0:
+ case 0x33b2:
+ case 0x33b4:
+ case 0x33b8:
+ case 0x33ba:
+ case 0x33bc:
+ case 0x3320:
+ case 0x3322:
+ case 0x3324:
+ case 0x3328:
+ case 0x332a:
+ case 0x332c:
+ platform_device_register(&iop13xx_tpmi_0_device);
+ return;
+ default:
+ platform_device_register(&iop13xx_tpmi_0_device);
+ platform_device_register(&iop13xx_tpmi_1_device);
+ platform_device_register(&iop13xx_tpmi_2_device);
+ platform_device_register(&iop13xx_tpmi_3_device);
+ return;
+ }
+}
diff --git a/arch/arm/mach-iop32x/Kconfig b/arch/arm/mach-iop32x/Kconfig
new file mode 100644
index 00000000..5e8c6f7d
--- /dev/null
+++ b/arch/arm/mach-iop32x/Kconfig
@@ -0,0 +1,46 @@
+if ARCH_IOP32X
+
+menu "IOP32x Implementation Options"
+
+comment "IOP32x Platform Types"
+
+config MACH_EP80219
+ bool
+
+config MACH_GLANTANK
+ bool "Enable support for the IO-Data GLAN Tank"
+ help
+ Say Y here if you want to run your kernel on the GLAN Tank
+ NAS appliance or machines from IO-Data's HDL-Gxxx, HDL-GWxxx
+ and HDL-GZxxx series.
+
+config ARCH_IQ80321
+ bool "Enable support for IQ80321"
+ help
+ Say Y here if you want to run your kernel on the Intel IQ80321
+ evaluation kit for the IOP321 processor.
+
+config ARCH_IQ31244
+ bool "Enable support for EP80219/IQ31244"
+ select MACH_EP80219
+ help
+ Say Y here if you want to run your kernel on the Intel EP80219
+ evaluation kit for the Intel 80219 processor (a IOP321 variant)
+ or the IQ31244 evaluation kit for the IOP321 processor.
+
+config MACH_N2100
+ bool "Enable support for the Thecus n2100"
+ help
+ Say Y here if you want to run your kernel on the Thecus n2100
+ NAS appliance.
+
+config MACH_EM7210
+ bool "Enable support for the Lanner EM7210"
+ help
+ Say Y here if you want to run your kernel on the Lanner EM7210
+ board. Say also Y here if you have a SS4000e Baxter Creek NAS
+ appliance."
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-iop32x/Makefile b/arch/arm/mach-iop32x/Makefile
new file mode 100644
index 00000000..cfdf8a13
--- /dev/null
+++ b/arch/arm/mach-iop32x/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_MACH_GLANTANK) += glantank.o
+obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
+obj-$(CONFIG_ARCH_IQ31244) += iq31244.o
+obj-$(CONFIG_MACH_N2100) += n2100.o
+obj-$(CONFIG_MACH_EM7210) += em7210.o
diff --git a/arch/arm/mach-iop32x/Makefile.boot b/arch/arm/mach-iop32x/Makefile.boot
new file mode 100644
index 00000000..47000dcc
--- /dev/null
+++ b/arch/arm/mach-iop32x/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0xa0008000
+params_phys-y := 0xa0000100
+initrd_phys-y := 0xa0800000
diff --git a/arch/arm/mach-iop32x/em7210.c b/arch/arm/mach-iop32x/em7210.c
new file mode 100644
index 00000000..779f924a
--- /dev/null
+++ b/arch/arm/mach-iop32x/em7210.c
@@ -0,0 +1,211 @@
+/*
+ * arch/arm/mach-iop32x/em7210.c
+ *
+ * Board support code for the Lanner EM7210 platforms.
+ *
+ * Based on arch/arm/mach-iop32x/iq31244.c file.
+ *
+ * Copyright (C) 2007 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <mach/time.h>
+
+static void __init em7210_timer_init(void)
+{
+ /* http://www.kwaak.net/fotos/fotos-nas/slide_24.html */
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+}
+
+static struct sys_timer em7210_timer = {
+ .init = em7210_timer_init,
+};
+
+/*
+ * EM7210 RTC
+ */
+static struct i2c_board_info __initdata em7210_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+ },
+};
+
+/*
+ * EM7210 I/O
+ */
+static struct map_desc em7210_io_desc[] __initdata = {
+ { /* on-board devices */
+ .virtual = IQ31244_UART,
+ .pfn = __phys_to_pfn(IQ31244_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init em7210_map_io(void)
+{
+ iop3xx_map_io();
+ iotable_init(em7210_io_desc, ARRAY_SIZE(em7210_io_desc));
+}
+
+
+/*
+ * EM7210 PCI
+ */
+#define INTA IRQ_IOP32X_XINT0
+#define INTB IRQ_IOP32X_XINT1
+#define INTC IRQ_IOP32X_XINT2
+#define INTD IRQ_IOP32X_XINT3
+
+static int __init
+em7210_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[][4] = {
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {INTB, INTB, INTB, INTB}, /* console / uart */
+ {INTA, INTA, INTA, INTA}, /* 1st 82541 */
+ {INTD, INTD, INTD, INTD}, /* 2nd 82541 */
+ {INTC, INTC, INTC, INTC}, /* GD31244 */
+ {INTD, INTA, INTA, INTA}, /* mini-PCI */
+ {INTD, INTC, INTA, INTA}, /* NEC USB */
+ };
+
+ if (pin < 1 || pin > 4)
+ return -1;
+
+ return pci_irq_table[slot % 6][pin - 1];
+}
+
+static struct hw_pci em7210_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = em7210_pci_map_irq,
+};
+
+static int __init em7210_pci_init(void)
+{
+ if (machine_is_em7210())
+ pci_common_init(&em7210_pci);
+
+ return 0;
+}
+
+subsys_initcall(em7210_pci_init);
+
+
+/*
+ * EM7210 Flash
+ */
+static struct physmap_flash_data em7210_flash_data = {
+ .width = 2,
+};
+
+static struct resource em7210_flash_resource = {
+ .start = 0xf0000000,
+ .end = 0xf1ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device em7210_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &em7210_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &em7210_flash_resource,
+};
+
+
+/*
+ * EM7210 UART
+ * The physical address of the serial port is 0xfe800000,
+ * so it can be used for physical and virtual address.
+ */
+static struct plat_serial8250_port em7210_serial_port[] = {
+ {
+ .mapbase = IQ31244_UART,
+ .membase = (char *)IQ31244_UART,
+ .irq = IRQ_IOP32X_XINT1,
+ .flags = UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = 1843200,
+ },
+ { },
+};
+
+static struct resource em7210_uart_resource = {
+ .start = IQ31244_UART,
+ .end = IQ31244_UART + 7,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device em7210_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = em7210_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &em7210_uart_resource,
+};
+
+void em7210_power_off(void)
+{
+ *IOP3XX_GPOE &= 0xfe;
+ *IOP3XX_GPOD |= 0x01;
+}
+
+static void __init em7210_init_machine(void)
+{
+ platform_device_register(&em7210_serial_device);
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&em7210_flash_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+
+ i2c_register_board_info(0, em7210_i2c_devices,
+ ARRAY_SIZE(em7210_i2c_devices));
+
+
+ pm_power_off = em7210_power_off;
+}
+
+MACHINE_START(EM7210, "Lanner EM7210")
+ .boot_params = 0xa0000100,
+ .map_io = em7210_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &em7210_timer,
+ .init_machine = em7210_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/glantank.c b/arch/arm/mach-iop32x/glantank.c
new file mode 100644
index 00000000..c6b6f9c5
--- /dev/null
+++ b/arch/arm/mach-iop32x/glantank.c
@@ -0,0 +1,215 @@
+/*
+ * arch/arm/mach-iop32x/glantank.c
+ *
+ * Board support code for the GLAN Tank.
+ *
+ * Copyright (C) 2006, 2007 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/f75375s.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <mach/time.h>
+
+/*
+ * GLAN Tank timer tick configuration.
+ */
+static void __init glantank_timer_init(void)
+{
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+}
+
+static struct sys_timer glantank_timer = {
+ .init = glantank_timer_init,
+};
+
+
+/*
+ * GLAN Tank I/O.
+ */
+static struct map_desc glantank_io_desc[] __initdata = {
+ { /* on-board devices */
+ .virtual = GLANTANK_UART,
+ .pfn = __phys_to_pfn(GLANTANK_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init glantank_map_io(void)
+{
+ iop3xx_map_io();
+ iotable_init(glantank_io_desc, ARRAY_SIZE(glantank_io_desc));
+}
+
+
+/*
+ * GLAN Tank PCI.
+ */
+#define INTA IRQ_IOP32X_XINT0
+#define INTB IRQ_IOP32X_XINT1
+#define INTC IRQ_IOP32X_XINT2
+#define INTD IRQ_IOP32X_XINT3
+
+static int __init
+glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[][4] = {
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {INTD, INTD, INTD, INTD}, /* UART (8250) */
+ {INTA, INTA, INTA, INTA}, /* Ethernet (E1000) */
+ {INTB, INTB, INTB, INTB}, /* IDE (AEC6280R) */
+ {INTC, INTC, INTC, INTC}, /* USB (NEC) */
+ };
+
+ BUG_ON(pin < 1 || pin > 4);
+
+ return pci_irq_table[slot % 4][pin - 1];
+}
+
+static struct hw_pci glantank_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = glantank_pci_map_irq,
+};
+
+static int __init glantank_pci_init(void)
+{
+ if (machine_is_glantank())
+ pci_common_init(&glantank_pci);
+
+ return 0;
+}
+
+subsys_initcall(glantank_pci_init);
+
+
+/*
+ * GLAN Tank machine initialization.
+ */
+static struct physmap_flash_data glantank_flash_data = {
+ .width = 2,
+};
+
+static struct resource glantank_flash_resource = {
+ .start = 0xf0000000,
+ .end = 0xf007ffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device glantank_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &glantank_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &glantank_flash_resource,
+};
+
+static struct plat_serial8250_port glantank_serial_port[] = {
+ {
+ .mapbase = GLANTANK_UART,
+ .membase = (char *)GLANTANK_UART,
+ .irq = IRQ_IOP32X_XINT3,
+ .flags = UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = 1843200,
+ },
+ { },
+};
+
+static struct resource glantank_uart_resource = {
+ .start = GLANTANK_UART,
+ .end = GLANTANK_UART + 7,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device glantank_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = glantank_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &glantank_uart_resource,
+};
+
+static struct f75375s_platform_data glantank_f75375s = {
+ .pwm = { 255, 255 },
+ .pwm_enable = { 0, 0 },
+};
+
+static struct i2c_board_info __initdata glantank_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("f75375", 0x2e),
+ .platform_data = &glantank_f75375s,
+ },
+};
+
+static void glantank_power_off(void)
+{
+ __raw_writeb(0x01, 0xfe8d0004);
+
+ while (1)
+ ;
+}
+
+static void __init glantank_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&glantank_flash_device);
+ platform_device_register(&glantank_serial_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+
+ i2c_register_board_info(0, glantank_i2c_devices,
+ ARRAY_SIZE(glantank_i2c_devices));
+
+ pm_power_off = glantank_power_off;
+}
+
+MACHINE_START(GLANTANK, "GLAN Tank")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = 0xa0000100,
+ .map_io = glantank_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &glantank_timer,
+ .init_machine = glantank_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/include/mach/adma.h b/arch/arm/mach-iop32x/include/mach/adma.h
new file mode 100644
index 00000000..5ed92037
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/adma.h
@@ -0,0 +1,5 @@
+#ifndef IOP32X_ADMA_H
+#define IOP32X_ADMA_H
+#include <asm/hardware/iop3xx-adma.h>
+#endif
+
diff --git a/arch/arm/mach-iop32x/include/mach/debug-macro.S b/arch/arm/mach-iop32x/include/mach/debug-macro.S
new file mode 100644
index 00000000..ff9e76c0
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro addruart, rp, rv
+ mov \rp, #0xfe000000 @ physical as well as virtual
+ orr \rp, \rp, #0x00800000 @ location of the UART
+ mov \rv, \rp
+ .endm
+
+#define UART_SHIFT 0
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
new file mode 100644
index 00000000..b02fb56b
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/entry-macro.S
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IOP32x-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/iop32x.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mrc p15, 0, \tmp, c15, c1, 0
+ orr \tmp, \tmp, #(1 << 6)
+ mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
+ mrc p15, 0, \tmp, c15, c1, 0
+ mov \tmp, \tmp
+ sub pc, pc, #4 @ cp_wait
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC
+ cmp \irqstat, #0
+ clzne \irqnr, \irqstat
+ rsbne \irqnr, \irqnr, #31
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ mrc p15, 0, \tmp1, c15, c1, 0
+ ands \tmp2, \tmp1, #(1 << 6)
+ bicne \tmp1, \tmp1, #(1 << 6)
+ mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
+ .endm
diff --git a/arch/arm/mach-iop32x/include/mach/glantank.h b/arch/arm/mach-iop32x/include/mach/glantank.h
new file mode 100644
index 00000000..958eb91c
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/glantank.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/glantank.h
+ *
+ * IO-Data GLAN Tank board registers
+ */
+
+#ifndef __GLANTANK_H
+#define __GLANTANK_H
+
+#define GLANTANK_UART 0xfe800000 /* UART */
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/gpio.h b/arch/arm/mach-iop32x/include/mach/gpio.h
new file mode 100644
index 00000000..708f4ec9
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_IOP32X_GPIO_H
+#define __ASM_ARCH_IOP32X_GPIO_H
+
+#include <asm/hardware/iop3xx-gpio.h>
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/hardware.h b/arch/arm/mach-iop32x/include/mach/hardware.h
new file mode 100644
index 00000000..d559c4e6
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/hardware.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/hardware.h
+ */
+
+#ifndef __HARDWARE_H
+#define __HARDWARE_H
+
+#include <asm/types.h>
+
+/*
+ * Note about PCI IO space mappings
+ *
+ * To make IO space accesses efficient, we store virtual addresses in
+ * the IO resources.
+ *
+ * The PCI IO space is located at virtual 0xfe000000 from physical
+ * 0x90000000. The PCI BARs must be programmed with physical addresses,
+ * but when we read them, we convert them to virtual addresses. See
+ * arch/arm/plat-iop/pci.c.
+ */
+#define pcibios_assign_all_busses() 1
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+
+#ifndef __ASSEMBLY__
+void iop32x_init_irq(void);
+#endif
+
+
+/*
+ * Generic chipset bits
+ */
+#include "iop32x.h"
+
+/*
+ * Board specific bits
+ */
+#include "glantank.h"
+#include "iq80321.h"
+#include "iq31244.h"
+#include "n2100.h"
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/io.h b/arch/arm/mach-iop32x/include/mach/io.h
new file mode 100644
index 00000000..059c783c
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/io.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/io.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __IO_H
+#define __IO_H
+
+#include <asm/hardware/iop3xx.h>
+
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype);
+extern void __iop3xx_iounmap(void __iomem *addr);
+
+#define IO_SPACE_LIMIT 0xffffffff
+#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
+#define __mem_pci(a) (a)
+
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
new file mode 100644
index 00000000..941f363a
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/iop32x.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/iop32x.h
+ *
+ * Intel IOP32X Chip definitions
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can 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 __IOP32X_H
+#define __IOP32X_H
+
+/*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c4 + (reg))
+#define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
+
+#include <asm/hardware/iop3xx.h>
+
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ physical ram on top of pci in the memory map
+ */
+#define IOP32X_MAX_RAM_SIZE 0x40000000UL
+#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/iq31244.h b/arch/arm/mach-iop32x/include/mach/iq31244.h
new file mode 100644
index 00000000..6b6b369e
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/iq31244.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/iq31244.h
+ *
+ * Intel IQ31244 evaluation board registers
+ */
+
+#ifndef __IQ31244_H
+#define __IQ31244_H
+
+#define IQ31244_UART 0xfe800000 /* UART #1 */
+#define IQ31244_7SEG_1 0xfe840000 /* 7-Segment MSB */
+#define IQ31244_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */
+#define IQ31244_ROTARY_SW 0xfe8d0000 /* Rotary Switch */
+#define IQ31244_BATT_STAT 0xfe8f0000 /* Battery Status */
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/iq80321.h b/arch/arm/mach-iop32x/include/mach/iq80321.h
new file mode 100644
index 00000000..498819b7
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/iq80321.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/iq80321.h
+ *
+ * Intel IQ80321 evaluation board registers
+ */
+
+#ifndef __IQ80321_H
+#define __IQ80321_H
+
+#define IQ80321_UART 0xfe800000 /* UART #1 */
+#define IQ80321_7SEG_1 0xfe840000 /* 7-Segment MSB */
+#define IQ80321_7SEG_0 0xfe850000 /* 7-Segment LSB (WO) */
+#define IQ80321_ROTARY_SW 0xfe8d0000 /* Rotary Switch */
+#define IQ80321_BATT_STAT 0xfe8f0000 /* Battery Status */
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
new file mode 100644
index 00000000..33573e09
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/irqs.h
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright: (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can 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 __IRQS_H
+#define __IRQS_H
+
+/*
+ * IOP80321 chipset interrupts
+ */
+#define IRQ_IOP32X_DMA0_EOT 0
+#define IRQ_IOP32X_DMA0_EOC 1
+#define IRQ_IOP32X_DMA1_EOT 2
+#define IRQ_IOP32X_DMA1_EOC 3
+#define IRQ_IOP32X_AA_EOT 6
+#define IRQ_IOP32X_AA_EOC 7
+#define IRQ_IOP32X_CORE_PMON 8
+#define IRQ_IOP32X_TIMER0 9
+#define IRQ_IOP32X_TIMER1 10
+#define IRQ_IOP32X_I2C_0 11
+#define IRQ_IOP32X_I2C_1 12
+#define IRQ_IOP32X_MESSAGING 13
+#define IRQ_IOP32X_ATU_BIST 14
+#define IRQ_IOP32X_PERFMON 15
+#define IRQ_IOP32X_CORE_PMU 16
+#define IRQ_IOP32X_BIU_ERR 17
+#define IRQ_IOP32X_ATU_ERR 18
+#define IRQ_IOP32X_MCU_ERR 19
+#define IRQ_IOP32X_DMA0_ERR 20
+#define IRQ_IOP32X_DMA1_ERR 21
+#define IRQ_IOP32X_AA_ERR 23
+#define IRQ_IOP32X_MSG_ERR 24
+#define IRQ_IOP32X_SSP 25
+#define IRQ_IOP32X_XINT0 27
+#define IRQ_IOP32X_XINT1 28
+#define IRQ_IOP32X_XINT2 29
+#define IRQ_IOP32X_XINT3 30
+#define IRQ_IOP32X_HPI 31
+
+#define NR_IRQS 32
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/memory.h b/arch/arm/mach-iop32x/include/mach/memory.h
new file mode 100644
index 00000000..169cc239
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/memory.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/memory.h
+ */
+
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0xa0000000)
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/n2100.h b/arch/arm/mach-iop32x/include/mach/n2100.h
new file mode 100644
index 00000000..40b8a532
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/n2100.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/n2100.h
+ *
+ * Thecus N2100 board registers
+ */
+
+#ifndef __N2100_H
+#define __N2100_H
+
+#define N2100_UART 0xfe800000 /* UART */
+
+#define N2100_COPY_BUTTON IOP3XX_GPIO_LINE(0)
+#define N2100_PCA9532_RESET IOP3XX_GPIO_LINE(2)
+#define N2100_RESET_BUTTON IOP3XX_GPIO_LINE(3)
+#define N2100_HARDWARE_RESET IOP3XX_GPIO_LINE(4)
+#define N2100_POWER_BUTTON IOP3XX_GPIO_LINE(5)
+
+
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h
new file mode 100644
index 00000000..a4b808fe
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/system.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/system.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/mach-types.h>
+#include <asm/hardware/iop3xx.h>
+#include <mach/n2100.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ local_irq_disable();
+
+ if (machine_is_n2100()) {
+ gpio_line_set(N2100_HARDWARE_RESET, GPIO_LOW);
+ gpio_line_config(N2100_HARDWARE_RESET, GPIO_OUT);
+ while (1)
+ ;
+ }
+
+ *IOP3XX_PCSR = 0x30;
+
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+}
diff --git a/arch/arm/mach-iop32x/include/mach/time.h b/arch/arm/mach-iop32x/include/mach/time.h
new file mode 100644
index 00000000..0f28c994
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/time.h
@@ -0,0 +1,4 @@
+#ifndef _IOP32X_TIME_H_
+#define _IOP32X_TIME_H_
+#define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0
+#endif
diff --git a/arch/arm/mach-iop32x/include/mach/timex.h b/arch/arm/mach-iop32x/include/mach/timex.h
new file mode 100644
index 00000000..7262ab81
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/timex.h
@@ -0,0 +1,6 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/timex.h
+ *
+ * IOP32x architecture timex specifications
+ */
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-iop32x/include/mach/uncompress.h b/arch/arm/mach-iop32x/include/mach/uncompress.h
new file mode 100644
index 00000000..4fd71549
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/uncompress.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/uncompress.h
+ */
+
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+volatile u8 *uart_base;
+
+#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
+
+static inline void putc(char c)
+{
+ while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+ uart_base[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ if (machine_is_iq80321())
+ uart_base = (volatile u8 *)IQ80321_UART;
+ else if (machine_is_iq31244() || machine_is_em7210())
+ uart_base = (volatile u8 *)IQ31244_UART;
+ else
+ uart_base = (volatile u8 *)0xfe800000;
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-iop32x/include/mach/vmalloc.h b/arch/arm/mach-iop32x/include/mach/vmalloc.h
new file mode 100644
index 00000000..c4862d48
--- /dev/null
+++ b/arch/arm/mach-iop32x/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-iop32x/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe000000UL
diff --git a/arch/arm/mach-iop32x/iq31244.c b/arch/arm/mach-iop32x/iq31244.c
new file mode 100644
index 00000000..fde962c0
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq31244.c
@@ -0,0 +1,335 @@
+/*
+ * arch/arm/mach-iop32x/iq31244.c
+ *
+ * Board support code for the Intel EP80219 and IQ31244 platforms.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright 2003 (c) MontaVista, Software, Inc.
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <mach/time.h>
+
+/*
+ * Until March of 2007 iq31244 platforms and ep80219 platforms shared the
+ * same machine id, and the processor type was used to select board type.
+ * However this assumption breaks for an iq80219 board which is an iop219
+ * processor on an iq31244 board. The force_ep80219 flag has been added
+ * for old boot loaders using the iq31244 machine id for an ep80219 platform.
+ */
+static int force_ep80219;
+
+static int is_80219(void)
+{
+ return !!((read_cpuid_id() & 0xffffffe0) == 0x69052e20);
+}
+
+static int is_ep80219(void)
+{
+ if (machine_is_ep80219() || force_ep80219)
+ return 1;
+ else
+ return 0;
+}
+
+
+/*
+ * EP80219/IQ31244 timer tick configuration.
+ */
+static void __init iq31244_timer_init(void)
+{
+ if (is_ep80219()) {
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+ } else {
+ /* 33.000 MHz crystal. */
+ iop_init_time(198000000);
+ }
+}
+
+static struct sys_timer iq31244_timer = {
+ .init = iq31244_timer_init,
+};
+
+
+/*
+ * IQ31244 I/O.
+ */
+static struct map_desc iq31244_io_desc[] __initdata = {
+ { /* on-board devices */
+ .virtual = IQ31244_UART,
+ .pfn = __phys_to_pfn(IQ31244_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init iq31244_map_io(void)
+{
+ iop3xx_map_io();
+ iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc));
+}
+
+
+/*
+ * EP80219/IQ31244 PCI.
+ */
+static int __init
+ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (slot == 0) {
+ /* CFlash */
+ irq = IRQ_IOP32X_XINT1;
+ } else if (slot == 1) {
+ /* 82551 Pro 100 */
+ irq = IRQ_IOP32X_XINT0;
+ } else if (slot == 2) {
+ /* PCI-X Slot */
+ irq = IRQ_IOP32X_XINT3;
+ } else if (slot == 3) {
+ /* SATA */
+ irq = IRQ_IOP32X_XINT2;
+ } else {
+ printk(KERN_ERR "ep80219_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci ep80219_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = ep80219_pci_map_irq,
+};
+
+static int __init
+iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (slot == 0) {
+ /* CFlash */
+ irq = IRQ_IOP32X_XINT1;
+ } else if (slot == 1) {
+ /* SATA */
+ irq = IRQ_IOP32X_XINT2;
+ } else if (slot == 2) {
+ /* PCI-X Slot */
+ irq = IRQ_IOP32X_XINT3;
+ } else if (slot == 3) {
+ /* 82546 GigE */
+ irq = IRQ_IOP32X_XINT0;
+ } else {
+ printk(KERN_ERR "iq31244_pci_map_irq called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci iq31244_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = iq31244_pci_map_irq,
+};
+
+static int __init iq31244_pci_init(void)
+{
+ if (is_ep80219())
+ pci_common_init(&ep80219_pci);
+ else if (machine_is_iq31244()) {
+ if (is_80219()) {
+ printk("note: iq31244 board type has been selected\n");
+ printk("note: to select ep80219 operation:\n");
+ printk("\t1/ specify \"force_ep80219\" on the kernel"
+ " command line\n");
+ printk("\t2/ update boot loader to pass"
+ " the ep80219 id: %d\n", MACH_TYPE_EP80219);
+ }
+ pci_common_init(&iq31244_pci);
+ }
+
+ return 0;
+}
+
+subsys_initcall(iq31244_pci_init);
+
+
+/*
+ * IQ31244 machine initialisation.
+ */
+static struct physmap_flash_data iq31244_flash_data = {
+ .width = 2,
+};
+
+static struct resource iq31244_flash_resource = {
+ .start = 0xf0000000,
+ .end = 0xf07fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq31244_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &iq31244_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &iq31244_flash_resource,
+};
+
+static struct plat_serial8250_port iq31244_serial_port[] = {
+ {
+ .mapbase = IQ31244_UART,
+ .membase = (char *)IQ31244_UART,
+ .irq = IRQ_IOP32X_XINT1,
+ .flags = UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = 1843200,
+ },
+ { },
+};
+
+static struct resource iq31244_uart_resource = {
+ .start = IQ31244_UART,
+ .end = IQ31244_UART + 7,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq31244_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = iq31244_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &iq31244_uart_resource,
+};
+
+/*
+ * This function will send a SHUTDOWN_COMPLETE message to the PIC
+ * controller over I2C. We are not using the i2c subsystem since
+ * we are going to power off and it may be removed
+ */
+void ep80219_power_off(void)
+{
+ /*
+ * Send the Address byte w/ the start condition
+ */
+ *IOP3XX_IDBR1 = 0x60;
+ *IOP3XX_ICR1 = 0xE9;
+ mdelay(1);
+
+ /*
+ * Send the START_MSG byte w/ no start or stop condition
+ */
+ *IOP3XX_IDBR1 = 0x0F;
+ *IOP3XX_ICR1 = 0xE8;
+ mdelay(1);
+
+ /*
+ * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or
+ * stop condition
+ */
+ *IOP3XX_IDBR1 = 0x03;
+ *IOP3XX_ICR1 = 0xE8;
+ mdelay(1);
+
+ /*
+ * Send an ignored byte w/ stop condition
+ */
+ *IOP3XX_IDBR1 = 0x00;
+ *IOP3XX_ICR1 = 0xEA;
+
+ while (1)
+ ;
+}
+
+static void __init iq31244_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&iq31244_flash_device);
+ platform_device_register(&iq31244_serial_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+
+ if (is_ep80219())
+ pm_power_off = ep80219_power_off;
+
+ if (!is_80219())
+ platform_device_register(&iop3xx_aau_channel);
+}
+
+static int __init force_ep80219_setup(char *str)
+{
+ force_ep80219 = 1;
+ return 1;
+}
+
+__setup("force_ep80219", force_ep80219_setup);
+
+MACHINE_START(IQ31244, "Intel IQ31244")
+ /* Maintainer: Intel Corp. */
+ .boot_params = 0xa0000100,
+ .map_io = iq31244_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &iq31244_timer,
+ .init_machine = iq31244_init_machine,
+MACHINE_END
+
+/* There should have been an ep80219 machine identifier from the beginning.
+ * Boot roms older than March 2007 do not know the ep80219 machine id. Pass
+ * "force_ep80219" on the kernel command line, otherwise iq31244 operation
+ * will be selected.
+ */
+MACHINE_START(EP80219, "Intel EP80219")
+ /* Maintainer: Intel Corp. */
+ .boot_params = 0xa0000100,
+ .map_io = iq31244_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &iq31244_timer,
+ .init_machine = iq31244_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/iq80321.c b/arch/arm/mach-iop32x/iq80321.c
new file mode 100644
index 00000000..3a95950e
--- /dev/null
+++ b/arch/arm/mach-iop32x/iq80321.c
@@ -0,0 +1,194 @@
+/*
+ * arch/arm/mach-iop32x/iq80321.c
+ *
+ * Board support code for the Intel IQ80321 platform.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <mach/time.h>
+
+/*
+ * IQ80321 timer tick configuration.
+ */
+static void __init iq80321_timer_init(void)
+{
+ /* 33.333 MHz crystal. */
+ iop_init_time(200000000);
+}
+
+static struct sys_timer iq80321_timer = {
+ .init = iq80321_timer_init,
+};
+
+
+/*
+ * IQ80321 I/O.
+ */
+static struct map_desc iq80321_io_desc[] __initdata = {
+ { /* on-board devices */
+ .virtual = IQ80321_UART,
+ .pfn = __phys_to_pfn(IQ80321_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init iq80321_map_io(void)
+{
+ iop3xx_map_io();
+ iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc));
+}
+
+
+/*
+ * IQ80321 PCI.
+ */
+static int __init
+iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if ((slot == 2 || slot == 6) && pin == 1) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP32X_XINT2;
+ } else if ((slot == 2 || slot == 6) && pin == 2) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP32X_XINT3;
+ } else if ((slot == 2 || slot == 6) && pin == 3) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP32X_XINT0;
+ } else if ((slot == 2 || slot == 6) && pin == 4) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP32X_XINT1;
+ } else if (slot == 4 || slot == 8) {
+ /* Gig-E */
+ irq = IRQ_IOP32X_XINT0;
+ } else {
+ printk(KERN_ERR "iq80321_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci iq80321_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = iq80321_pci_map_irq,
+};
+
+static int __init iq80321_pci_init(void)
+{
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80321())
+ pci_common_init(&iq80321_pci);
+
+ return 0;
+}
+
+subsys_initcall(iq80321_pci_init);
+
+
+/*
+ * IQ80321 machine initialisation.
+ */
+static struct physmap_flash_data iq80321_flash_data = {
+ .width = 1,
+};
+
+static struct resource iq80321_flash_resource = {
+ .start = 0xf0000000,
+ .end = 0xf07fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80321_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &iq80321_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &iq80321_flash_resource,
+};
+
+static struct plat_serial8250_port iq80321_serial_port[] = {
+ {
+ .mapbase = IQ80321_UART,
+ .membase = (char *)IQ80321_UART,
+ .irq = IRQ_IOP32X_XINT1,
+ .flags = UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = 1843200,
+ },
+ { },
+};
+
+static struct resource iq80321_uart_resource = {
+ .start = IQ80321_UART,
+ .end = IQ80321_UART + 7,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80321_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = iq80321_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &iq80321_uart_resource,
+};
+
+static void __init iq80321_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&iq80321_flash_device);
+ platform_device_register(&iq80321_serial_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+ platform_device_register(&iop3xx_aau_channel);
+}
+
+MACHINE_START(IQ80321, "Intel IQ80321")
+ /* Maintainer: Intel Corp. */
+ .boot_params = 0xa0000100,
+ .map_io = iq80321_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &iq80321_timer,
+ .init_machine = iq80321_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
new file mode 100644
index 00000000..d7ee2789
--- /dev/null
+++ b/arch/arm/mach-iop32x/irq.c
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-iop32x/irq.c
+ *
+ * Generic IOP32X IRQ handling functionality
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can 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/list.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+static u32 iop32x_mask;
+
+static void intctl_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static void intstr_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
+}
+
+static void
+iop32x_irq_mask(struct irq_data *d)
+{
+ iop32x_mask &= ~(1 << d->irq);
+ intctl_write(iop32x_mask);
+}
+
+static void
+iop32x_irq_unmask(struct irq_data *d)
+{
+ iop32x_mask |= 1 << d->irq;
+ intctl_write(iop32x_mask);
+}
+
+struct irq_chip ext_chip = {
+ .name = "IOP32x",
+ .irq_ack = iop32x_irq_mask,
+ .irq_mask = iop32x_irq_mask,
+ .irq_unmask = iop32x_irq_unmask,
+};
+
+void __init iop32x_init_irq(void)
+{
+ int i;
+
+ iop_init_cp6_handler();
+
+ intctl_write(0);
+ intstr_write(0);
+ if (machine_is_glantank() ||
+ machine_is_iq80321() ||
+ machine_is_iq31244() ||
+ machine_is_n2100() ||
+ machine_is_em7210())
+ *IOP3XX_PCIIRSR = 0x0f;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+}
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
new file mode 100644
index 00000000..626aa375
--- /dev/null
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -0,0 +1,335 @@
+/*
+ * arch/arm/mach-iop32x/n2100.c
+ *
+ * Board support code for the Thecus N2100 platform.
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ * Copyright 2003 (c) MontaVista, Software, Inc.
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/f75375s.h>
+#include <linux/leds-pca9532.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pm.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <mach/time.h>
+
+/*
+ * N2100 timer tick configuration.
+ */
+static void __init n2100_timer_init(void)
+{
+ /* 33.000 MHz crystal. */
+ iop_init_time(198000000);
+}
+
+static struct sys_timer n2100_timer = {
+ .init = n2100_timer_init,
+};
+
+
+/*
+ * N2100 I/O.
+ */
+static struct map_desc n2100_io_desc[] __initdata = {
+ { /* on-board devices */
+ .virtual = N2100_UART,
+ .pfn = __phys_to_pfn(N2100_UART),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init n2100_map_io(void)
+{
+ iop3xx_map_io();
+ iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc));
+}
+
+
+/*
+ * N2100 PCI.
+ */
+static int __init
+n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (PCI_SLOT(dev->devfn) == 1) {
+ /* RTL8110SB #1 */
+ irq = IRQ_IOP32X_XINT0;
+ } else if (PCI_SLOT(dev->devfn) == 2) {
+ /* RTL8110SB #2 */
+ irq = IRQ_IOP32X_XINT3;
+ } else if (PCI_SLOT(dev->devfn) == 3) {
+ /* Sil3512 */
+ irq = IRQ_IOP32X_XINT2;
+ } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) {
+ /* VT6212 INTA */
+ irq = IRQ_IOP32X_XINT1;
+ } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) {
+ /* VT6212 INTB */
+ irq = IRQ_IOP32X_XINT0;
+ } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) {
+ /* VT6212 INTC */
+ irq = IRQ_IOP32X_XINT2;
+ } else if (PCI_SLOT(dev->devfn) == 5) {
+ /* Mini-PCI slot */
+ irq = IRQ_IOP32X_XINT3;
+ } else {
+ printk(KERN_ERR "n2100_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci n2100_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = n2100_pci_map_irq,
+};
+
+/*
+ * Both r8169 chips on the n2100 exhibit PCI parity problems. Set
+ * the ->broken_parity_status flag for both ports so that the r8169
+ * driver knows it should ignore error interrupts.
+ */
+static void n2100_fixup_r8169(struct pci_dev *dev)
+{
+ if (dev->bus->number == 0 &&
+ (dev->devfn == PCI_DEVFN(1, 0) ||
+ dev->devfn == PCI_DEVFN(2, 0)))
+ dev->broken_parity_status = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169);
+
+static int __init n2100_pci_init(void)
+{
+ if (machine_is_n2100())
+ pci_common_init(&n2100_pci);
+
+ return 0;
+}
+
+subsys_initcall(n2100_pci_init);
+
+
+/*
+ * N2100 machine initialisation.
+ */
+static struct physmap_flash_data n2100_flash_data = {
+ .width = 2,
+};
+
+static struct resource n2100_flash_resource = {
+ .start = 0xf0000000,
+ .end = 0xf0ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device n2100_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &n2100_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &n2100_flash_resource,
+};
+
+
+static struct plat_serial8250_port n2100_serial_port[] = {
+ {
+ .mapbase = N2100_UART,
+ .membase = (char *)N2100_UART,
+ .irq = 0,
+ .flags = UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = 1843200,
+ },
+ { },
+};
+
+static struct resource n2100_uart_resource = {
+ .start = N2100_UART,
+ .end = N2100_UART + 7,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device n2100_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = n2100_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &n2100_uart_resource,
+};
+
+static struct f75375s_platform_data n2100_f75375s = {
+ .pwm = { 255, 255 },
+ .pwm_enable = { 0, 0 },
+};
+
+static struct pca9532_platform_data n2100_leds = {
+ .leds = {
+ { .name = "n2100:red:satafail0",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+ { .name = "n2100:red:satafail1",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+ { .name = "n2100:blue:usb",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+ { .type = PCA9532_TYPE_NONE },
+
+ { .type = PCA9532_TYPE_NONE },
+ { .type = PCA9532_TYPE_NONE },
+ { .type = PCA9532_TYPE_NONE },
+ { .name = "n2100:red:usb",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+
+ { .type = PCA9532_TYPE_NONE }, /* power OFF gpio */
+ { .type = PCA9532_TYPE_NONE }, /* reset gpio */
+ { .type = PCA9532_TYPE_NONE },
+ { .type = PCA9532_TYPE_NONE },
+
+ { .type = PCA9532_TYPE_NONE },
+ { .name = "n2100:orange:system",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+ { .name = "n2100:red:system",
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_LED,
+ },
+ { .name = "N2100 beeper" ,
+ .state = PCA9532_OFF,
+ .type = PCA9532_TYPE_N2100_BEEP,
+ },
+ },
+ .psc = { 0, 0 },
+ .pwm = { 0, 0 },
+};
+
+static struct i2c_board_info __initdata n2100_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372b", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("f75375", 0x2e),
+ .platform_data = &n2100_f75375s,
+ },
+ {
+ I2C_BOARD_INFO("pca9532", 0x60),
+ .platform_data = &n2100_leds,
+ },
+};
+
+/*
+ * Pull PCA9532 GPIO #8 low to power off the machine.
+ */
+static void n2100_power_off(void)
+{
+ local_irq_disable();
+
+ /* Start condition, I2C address of PCA9532, write transaction. */
+ *IOP3XX_IDBR0 = 0xc0;
+ *IOP3XX_ICR0 = 0xe9;
+ mdelay(1);
+
+ /* Write address 0x08. */
+ *IOP3XX_IDBR0 = 0x08;
+ *IOP3XX_ICR0 = 0xe8;
+ mdelay(1);
+
+ /* Write data 0x01, stop condition. */
+ *IOP3XX_IDBR0 = 0x01;
+ *IOP3XX_ICR0 = 0xea;
+
+ while (1)
+ ;
+}
+
+
+static struct timer_list power_button_poll_timer;
+
+static void power_button_poll(unsigned long dummy)
+{
+ if (gpio_line_get(N2100_POWER_BUTTON) == 0) {
+ ctrl_alt_del();
+ return;
+ }
+
+ power_button_poll_timer.expires = jiffies + (HZ / 10);
+ add_timer(&power_button_poll_timer);
+}
+
+
+static void __init n2100_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&n2100_flash_device);
+ platform_device_register(&n2100_serial_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+
+ i2c_register_board_info(0, n2100_i2c_devices,
+ ARRAY_SIZE(n2100_i2c_devices));
+
+ pm_power_off = n2100_power_off;
+
+ init_timer(&power_button_poll_timer);
+ power_button_poll_timer.function = power_button_poll;
+ power_button_poll_timer.expires = jiffies + (HZ / 10);
+ add_timer(&power_button_poll_timer);
+}
+
+MACHINE_START(N2100, "Thecus N2100")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = 0xa0000100,
+ .map_io = n2100_map_io,
+ .init_irq = iop32x_init_irq,
+ .timer = &n2100_timer,
+ .init_machine = n2100_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig
new file mode 100644
index 00000000..9aa016bb
--- /dev/null
+++ b/arch/arm/mach-iop33x/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_IOP33X
+
+menu "IOP33x Implementation Options"
+
+comment "IOP33x Platform Types"
+
+config ARCH_IQ80331
+ bool "Enable support for IQ80331"
+ help
+ Say Y here if you want to run your kernel on the Intel IQ80331
+ evaluation kit for the IOP331 chipset.
+
+config MACH_IQ80332
+ bool "Enable support for IQ80332"
+ help
+ Say Y here if you want to run your kernel on the Intel IQ80332
+ evaluation kit for the IOP332 chipset.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile
new file mode 100644
index 00000000..90081d8c
--- /dev/null
+++ b/arch/arm/mach-iop33x/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o uart.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_IQ80331) += iq80331.o
+obj-$(CONFIG_MACH_IQ80332) += iq80332.o
diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-iop33x/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-iop33x/include/mach/adma.h b/arch/arm/mach-iop33x/include/mach/adma.h
new file mode 100644
index 00000000..4b92f795
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/adma.h
@@ -0,0 +1,5 @@
+#ifndef IOP33X_ADMA_H
+#define IOP33X_ADMA_H
+#include <asm/hardware/iop3xx-adma.h>
+#endif
+
diff --git a/arch/arm/mach-iop33x/include/mach/debug-macro.S b/arch/arm/mach-iop33x/include/mach/debug-macro.S
new file mode 100644
index 00000000..40c500dd
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00ff0000
+ orr \rp, \rp, #0x0000f700
+ orr \rv, #0xfe000000 @ virtual
+ orr \rp, #0xff000000 @ physical
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-iop33x/include/mach/entry-macro.S b/arch/arm/mach-iop33x/include/mach/entry-macro.S
new file mode 100644
index 00000000..4e1f7282
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/entry-macro.S
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IOP33x-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/iop33x.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mrc p15, 0, \tmp, c15, c1, 0
+ orr \tmp, \tmp, #(1 << 6)
+ mcr p15, 0, \tmp, c15, c1, 0 @ Enable cp6 access
+ mrc p15, 0, \tmp, c15, c1, 0
+ mov \tmp, \tmp
+ sub pc, pc, #4 @ cp_wait
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mrc p6, 0, \irqstat, c14, c0, 0 @ Read IINTVEC
+ cmp \irqstat, #0
+ mrceq p6, 0, \irqstat, c14, c0, 0 @ erratum 63 workaround
+ adds \irqnr, \irqstat, #1
+ movne \irqnr, \irqstat, lsr #2
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ mrc p15, 0, \tmp1, c15, c1, 0
+ ands \tmp2, \tmp1, #(1 << 6)
+ bicne \tmp1, \tmp1, #(1 << 6)
+ mcrne p15, 0, \tmp1, c15, c1, 0 @ Disable cp6 access
+ .endm
diff --git a/arch/arm/mach-iop33x/include/mach/gpio.h b/arch/arm/mach-iop33x/include/mach/gpio.h
new file mode 100644
index 00000000..ddd55bba
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_IOP33X_GPIO_H
+#define __ASM_ARCH_IOP33X_GPIO_H
+
+#include <asm/hardware/iop3xx-gpio.h>
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/hardware.h b/arch/arm/mach-iop33x/include/mach/hardware.h
new file mode 100644
index 00000000..8c10e430
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/hardware.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/hardware.h
+ */
+
+#ifndef __HARDWARE_H
+#define __HARDWARE_H
+
+#include <asm/types.h>
+
+/*
+ * Note about PCI IO space mappings
+ *
+ * To make IO space accesses efficient, we store virtual addresses in
+ * the IO resources.
+ *
+ * The PCI IO space is located at virtual 0xfe000000 from physical
+ * 0x90000000. The PCI BARs must be programmed with physical addresses,
+ * but when we read them, we convert them to virtual addresses. See
+ * arch/arm/mach-iop3xx/iop3xx-pci.c
+ */
+#define pcibios_assign_all_busses() 1
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+
+#ifndef __ASSEMBLY__
+void iop33x_init_irq(void);
+
+extern struct platform_device iop33x_uart0_device;
+extern struct platform_device iop33x_uart1_device;
+#endif
+
+
+/*
+ * Generic chipset bits
+ *
+ */
+#include "iop33x.h"
+
+/*
+ * Board specific bits
+ */
+#include "iq80331.h"
+#include "iq80332.h"
+
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/io.h b/arch/arm/mach-iop33x/include/mach/io.h
new file mode 100644
index 00000000..39e893e9
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/io.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/io.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __IO_H
+#define __IO_H
+
+#include <asm/hardware/iop3xx.h>
+
+extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype);
+extern void __iop3xx_iounmap(void __iomem *addr);
+
+#define IO_SPACE_LIMIT 0xffffffff
+#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
+#define __mem_pci(a) (a)
+
+#define __arch_ioremap __iop3xx_ioremap
+#define __arch_iounmap __iop3xx_iounmap
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h
new file mode 100644
index 00000000..a89c0a23
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/iop33x.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/iop33x.h
+ *
+ * Intel IOP33X Chip definitions
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2003, 2004 Intel Corp.
+ *
+ * This program is free software; you can 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 __IOP33X_H
+#define __IOP33X_H
+
+/*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1780 + (reg))
+#define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07d0 + (reg))
+
+#include <asm/hardware/iop3xx.h>
+
+/* UARTs */
+#define IOP33X_UART0_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1700)
+#define IOP33X_UART0_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1700)
+#define IOP33X_UART1_PHYS (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740)
+#define IOP33X_UART1_VIRT (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740)
+
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ pci on top of physical ram in memory map
+ */
+#define IOP33X_MAX_RAM_SIZE 0x80000000UL
+#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
+
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iq80331.h b/arch/arm/mach-iop33x/include/mach/iq80331.h
new file mode 100644
index 00000000..fe406b01
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/iq80331.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/iq80331.h
+ *
+ * Intel IQ80331 evaluation board registers
+ */
+
+#ifndef __IQ80331_H
+#define __IQ80331_H
+
+#define IQ80331_7SEG_1 0xce840000 /* 7-Segment MSB */
+#define IQ80331_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */
+#define IQ80331_ROTARY_SW 0xce8d0000 /* Rotary Switch */
+#define IQ80331_BATT_STAT 0xce8f0000 /* Battery Status */
+
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iq80332.h b/arch/arm/mach-iop33x/include/mach/iq80332.h
new file mode 100644
index 00000000..8325d71f
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/iq80332.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/iq80332.h
+ *
+ * Intel IQ80332 evaluation board registers
+ */
+
+#ifndef __IQ80332_H
+#define __IQ80332_H
+
+#define IQ80332_7SEG_1 0xce840000 /* 7-Segment MSB */
+#define IQ80332_7SEG_0 0xce850000 /* 7-Segment LSB (WO) */
+#define IQ80332_ROTARY_SW 0xce8d0000 /* Rotary Switch */
+#define IQ80332_BATT_STAT 0xce8f0000 /* Battery Status */
+
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/irqs.h b/arch/arm/mach-iop33x/include/mach/irqs.h
new file mode 100644
index 00000000..707628a6
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/irqs.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/irqs.h
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright: (C) 2003 Intel Corp.
+ *
+ * This program is free software; you can 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 __IRQS_H
+#define __IRQS_H
+
+/*
+ * IOP80331 chipset interrupts
+ */
+#define IRQ_IOP33X_DMA0_EOT 0
+#define IRQ_IOP33X_DMA0_EOC 1
+#define IRQ_IOP33X_DMA1_EOT 2
+#define IRQ_IOP33X_DMA1_EOC 3
+#define IRQ_IOP33X_AA_EOT 6
+#define IRQ_IOP33X_AA_EOC 7
+#define IRQ_IOP33X_TIMER0 8
+#define IRQ_IOP33X_TIMER1 9
+#define IRQ_IOP33X_I2C_0 10
+#define IRQ_IOP33X_I2C_1 11
+#define IRQ_IOP33X_MSG 12
+#define IRQ_IOP33X_MSGIBQ 13
+#define IRQ_IOP33X_ATU_BIST 14
+#define IRQ_IOP33X_PERFMON 15
+#define IRQ_IOP33X_CORE_PMU 16
+#define IRQ_IOP33X_XINT0 24
+#define IRQ_IOP33X_XINT1 25
+#define IRQ_IOP33X_XINT2 26
+#define IRQ_IOP33X_XINT3 27
+#define IRQ_IOP33X_XINT8 32
+#define IRQ_IOP33X_XINT9 33
+#define IRQ_IOP33X_XINT10 34
+#define IRQ_IOP33X_XINT11 35
+#define IRQ_IOP33X_XINT12 36
+#define IRQ_IOP33X_XINT13 37
+#define IRQ_IOP33X_XINT14 38
+#define IRQ_IOP33X_XINT15 39
+#define IRQ_IOP33X_UART0 51
+#define IRQ_IOP33X_UART1 52
+#define IRQ_IOP33X_PBIE 53
+#define IRQ_IOP33X_ATU_CRW 54
+#define IRQ_IOP33X_ATU_ERR 55
+#define IRQ_IOP33X_MCU_ERR 56
+#define IRQ_IOP33X_DMA0_ERR 57
+#define IRQ_IOP33X_DMA1_ERR 58
+#define IRQ_IOP33X_AA_ERR 60
+#define IRQ_IOP33X_MSG_ERR 62
+#define IRQ_IOP33X_HPI 63
+
+#define NR_IRQS 64
+
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/memory.h b/arch/arm/mach-iop33x/include/mach/memory.h
new file mode 100644
index 00000000..8e1daf70
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/memory.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/memory.h
+ */
+
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h
new file mode 100644
index 00000000..f192a34b
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/system.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/system.h
+ *
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/hardware/iop3xx.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ *IOP3XX_PCSR = 0x30;
+
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+}
diff --git a/arch/arm/mach-iop33x/include/mach/time.h b/arch/arm/mach-iop33x/include/mach/time.h
new file mode 100644
index 00000000..4ac4d766
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/time.h
@@ -0,0 +1,4 @@
+#ifndef _IOP33X_TIME_H_
+#define _IOP33X_TIME_H_
+#define IRQ_IOP_TIMER0 IRQ_IOP33X_TIMER0
+#endif
diff --git a/arch/arm/mach-iop33x/include/mach/timex.h b/arch/arm/mach-iop33x/include/mach/timex.h
new file mode 100644
index 00000000..54c58909
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/timex.h
@@ -0,0 +1,6 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/timex.h
+ *
+ * IOP3xx architecture timex specifications
+ */
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-iop33x/include/mach/uncompress.h b/arch/arm/mach-iop33x/include/mach/uncompress.h
new file mode 100644
index 00000000..f99bb848
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/uncompress.h
+ */
+
+#include <asm/types.h>
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+#include <mach/hardware.h>
+
+volatile u32 *uart_base;
+
+#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
+
+static inline void putc(char c)
+{
+ while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+ uart_base[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ if (machine_is_iq80331() || machine_is_iq80332())
+ uart_base = (volatile u32 *)IOP33X_UART0_PHYS;
+ else
+ uart_base = (volatile u32 *)0xfe800000;
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-iop33x/include/mach/vmalloc.h b/arch/arm/mach-iop33x/include/mach/vmalloc.h
new file mode 100644
index 00000000..48331dc2
--- /dev/null
+++ b/arch/arm/mach-iop33x/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-iop33x/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe000000UL
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
new file mode 100644
index 00000000..c565f8d1
--- /dev/null
+++ b/arch/arm/mach-iop33x/iq80331.c
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mach-iop33x/iq80331.c
+ *
+ * Board support code for the Intel IQ80331 platform.
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <mach/time.h>
+
+/*
+ * IQ80331 timer tick configuration.
+ */
+static void __init iq80331_timer_init(void)
+{
+ /* D-Step parts run at a higher internal bus frequency */
+ if (*IOP3XX_ATURID >= 0xa)
+ iop_init_time(333000000);
+ else
+ iop_init_time(266000000);
+}
+
+static struct sys_timer iq80331_timer = {
+ .init = iq80331_timer_init,
+};
+
+
+/*
+ * IQ80331 PCI.
+ */
+static int __init
+iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (slot == 1 && pin == 1) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP33X_XINT1;
+ } else if (slot == 1 && pin == 2) {
+ /* PCI-X Slot INTB */
+ irq = IRQ_IOP33X_XINT2;
+ } else if (slot == 1 && pin == 3) {
+ /* PCI-X Slot INTC */
+ irq = IRQ_IOP33X_XINT3;
+ } else if (slot == 1 && pin == 4) {
+ /* PCI-X Slot INTD */
+ irq = IRQ_IOP33X_XINT0;
+ } else if (slot == 2) {
+ /* GigE */
+ irq = IRQ_IOP33X_XINT2;
+ } else {
+ printk(KERN_ERR "iq80331_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci iq80331_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = iq80331_pci_map_irq,
+};
+
+static int __init iq80331_pci_init(void)
+{
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80331())
+ pci_common_init(&iq80331_pci);
+
+ return 0;
+}
+
+subsys_initcall(iq80331_pci_init);
+
+
+/*
+ * IQ80331 machine initialisation.
+ */
+static struct physmap_flash_data iq80331_flash_data = {
+ .width = 1,
+};
+
+static struct resource iq80331_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc07fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80331_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &iq80331_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &iq80331_flash_resource,
+};
+
+static void __init iq80331_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&iop33x_uart0_device);
+ platform_device_register(&iop33x_uart1_device);
+ platform_device_register(&iq80331_flash_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+ platform_device_register(&iop3xx_aau_channel);
+}
+
+MACHINE_START(IQ80331, "Intel IQ80331")
+ /* Maintainer: Intel Corp. */
+ .boot_params = 0x00000100,
+ .map_io = iop3xx_map_io,
+ .init_irq = iop33x_init_irq,
+ .timer = &iq80331_timer,
+ .init_machine = iq80331_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
new file mode 100644
index 00000000..36a9efb2
--- /dev/null
+++ b/arch/arm/mach-iop33x/iq80332.c
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mach-iop33x/iq80332.c
+ *
+ * Board support code for the Intel IQ80332 platform.
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * 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/mm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/pci.h>
+#include <asm/mach/time.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <mach/time.h>
+
+/*
+ * IQ80332 timer tick configuration.
+ */
+static void __init iq80332_timer_init(void)
+{
+ /* D-Step parts and the iop333 run at a higher internal bus frequency */
+ if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374)
+ iop_init_time(333000000);
+ else
+ iop_init_time(266000000);
+}
+
+static struct sys_timer iq80332_timer = {
+ .init = iq80332_timer_init,
+};
+
+
+/*
+ * IQ80332 PCI.
+ */
+static int __init
+iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (slot == 4 && pin == 1) {
+ /* PCI-X Slot INTA */
+ irq = IRQ_IOP33X_XINT0;
+ } else if (slot == 4 && pin == 2) {
+ /* PCI-X Slot INTB */
+ irq = IRQ_IOP33X_XINT1;
+ } else if (slot == 4 && pin == 3) {
+ /* PCI-X Slot INTC */
+ irq = IRQ_IOP33X_XINT2;
+ } else if (slot == 4 && pin == 4) {
+ /* PCI-X Slot INTD */
+ irq = IRQ_IOP33X_XINT3;
+ } else if (slot == 6) {
+ /* GigE */
+ irq = IRQ_IOP33X_XINT2;
+ } else {
+ printk(KERN_ERR "iq80332_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+static struct hw_pci iq80332_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .nr_controllers = 1,
+ .setup = iop3xx_pci_setup,
+ .preinit = iop3xx_pci_preinit_cond,
+ .scan = iop3xx_pci_scan_bus,
+ .map_irq = iq80332_pci_map_irq,
+};
+
+static int __init iq80332_pci_init(void)
+{
+ if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
+ machine_is_iq80332())
+ pci_common_init(&iq80332_pci);
+
+ return 0;
+}
+
+subsys_initcall(iq80332_pci_init);
+
+
+/*
+ * IQ80332 machine initialisation.
+ */
+static struct physmap_flash_data iq80332_flash_data = {
+ .width = 1,
+};
+
+static struct resource iq80332_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc07fffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device iq80332_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &iq80332_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &iq80332_flash_resource,
+};
+
+static void __init iq80332_init_machine(void)
+{
+ platform_device_register(&iop3xx_i2c0_device);
+ platform_device_register(&iop3xx_i2c1_device);
+ platform_device_register(&iop33x_uart0_device);
+ platform_device_register(&iop33x_uart1_device);
+ platform_device_register(&iq80332_flash_device);
+ platform_device_register(&iop3xx_dma_0_channel);
+ platform_device_register(&iop3xx_dma_1_channel);
+ platform_device_register(&iop3xx_aau_channel);
+}
+
+MACHINE_START(IQ80332, "Intel IQ80332")
+ /* Maintainer: Intel Corp. */
+ .boot_params = 0x00000100,
+ .map_io = iop3xx_map_io,
+ .init_irq = iop33x_init_irq,
+ .timer = &iq80332_timer,
+ .init_machine = iq80332_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
new file mode 100644
index 00000000..f7f5d3e4
--- /dev/null
+++ b/arch/arm/mach-iop33x/irq.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/mach-iop33x/irq.c
+ *
+ * Generic IOP331 IRQ handling functionality
+ *
+ * Author: Dave Jiang <dave.jiang@intel.com>
+ * Copyright (C) 2003 Intel Corp.
+ *
+ * This program is free software; you can 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/list.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+static u32 iop33x_mask0;
+static u32 iop33x_mask1;
+
+static void intctl0_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
+}
+
+static void intctl1_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val));
+}
+
+static void intstr0_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val));
+}
+
+static void intstr1_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val));
+}
+
+static void intbase_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val));
+}
+
+static void intsize_write(u32 val)
+{
+ asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val));
+}
+
+static void
+iop33x_irq_mask1 (struct irq_data *d)
+{
+ iop33x_mask0 &= ~(1 << d->irq);
+ intctl0_write(iop33x_mask0);
+}
+
+static void
+iop33x_irq_mask2 (struct irq_data *d)
+{
+ iop33x_mask1 &= ~(1 << (d->irq - 32));
+ intctl1_write(iop33x_mask1);
+}
+
+static void
+iop33x_irq_unmask1(struct irq_data *d)
+{
+ iop33x_mask0 |= 1 << d->irq;
+ intctl0_write(iop33x_mask0);
+}
+
+static void
+iop33x_irq_unmask2(struct irq_data *d)
+{
+ iop33x_mask1 |= (1 << (d->irq - 32));
+ intctl1_write(iop33x_mask1);
+}
+
+struct irq_chip iop33x_irqchip1 = {
+ .name = "IOP33x-1",
+ .irq_ack = iop33x_irq_mask1,
+ .irq_mask = iop33x_irq_mask1,
+ .irq_unmask = iop33x_irq_unmask1,
+};
+
+struct irq_chip iop33x_irqchip2 = {
+ .name = "IOP33x-2",
+ .irq_ack = iop33x_irq_mask2,
+ .irq_mask = iop33x_irq_mask2,
+ .irq_unmask = iop33x_irq_unmask2,
+};
+
+void __init iop33x_init_irq(void)
+{
+ int i;
+
+ iop_init_cp6_handler();
+
+ intctl0_write(0);
+ intctl1_write(0);
+ intstr0_write(0);
+ intstr1_write(0);
+ intbase_write(0);
+ intsize_write(1);
+ if (machine_is_iq80331())
+ *IOP3XX_PCIIRSR = 0x0f;
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_set_chip_and_handler(i,
+ (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
+ }
+}
diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c
new file mode 100644
index 00000000..cdae24e4
--- /dev/null
+++ b/arch/arm/mach-iop33x/uart.c
@@ -0,0 +1,104 @@
+/*
+ * arch/arm/mach-iop33x/uart.c
+ *
+ * Author: Dave Jiang (dave.jiang@intel.com)
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iop3xx.h>
+#include <asm/mach/arch.h>
+
+#define IOP33X_UART_XTAL 33334000
+
+static struct plat_serial8250_port iop33x_uart0_data[] = {
+ {
+ .membase = (char *)IOP33X_UART0_VIRT,
+ .mapbase = IOP33X_UART0_PHYS,
+ .irq = IRQ_IOP33X_UART0,
+ .uartclk = IOP33X_UART_XTAL,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct resource iop33x_uart0_resources[] = {
+ [0] = {
+ .start = IOP33X_UART0_PHYS,
+ .end = IOP33X_UART0_PHYS + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP33X_UART0,
+ .end = IRQ_IOP33X_UART0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device iop33x_uart0_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = iop33x_uart0_data,
+ },
+ .num_resources = 2,
+ .resource = iop33x_uart0_resources,
+};
+
+
+static struct resource iop33x_uart1_resources[] = {
+ [0] = {
+ .start = IOP33X_UART1_PHYS,
+ .end = IOP33X_UART1_PHYS + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP33X_UART1,
+ .end = IRQ_IOP33X_UART1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct plat_serial8250_port iop33x_uart1_data[] = {
+ {
+ .membase = (char *)IOP33X_UART1_VIRT,
+ .mapbase = IOP33X_UART1_PHYS,
+ .irq = IRQ_IOP33X_UART1,
+ .uartclk = IOP33X_UART_XTAL,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_SKIP_TEST,
+ },
+ { },
+};
+
+struct platform_device iop33x_uart1_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = iop33x_uart1_data,
+ },
+ .num_resources = 2,
+ .resource = iop33x_uart1_resources,
+};
diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig
new file mode 100644
index 00000000..08d2707f
--- /dev/null
+++ b/arch/arm/mach-ixp2000/Kconfig
@@ -0,0 +1,72 @@
+
+if ARCH_IXP2000
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+ bool
+ default y
+
+menu "Intel IXP2400/2800 Implementation Options"
+
+comment "IXP2400/2800 Platforms"
+
+config ARCH_ENP2611
+ bool "Support Radisys ENP-2611"
+ help
+ Say 'Y' here if you want your kernel to support the Radisys
+ ENP2611 PCI network processing card. For more information on
+ this card, see <file:Documentation/arm/IXP2000>.
+
+config ARCH_IXDP2400
+ bool "Support Intel IXDP2400"
+ help
+ Say 'Y' here if you want your kernel to support the Intel
+ IXDP2400 reference platform. For more information on
+ this platform, see <file:Documentation/arm/IXP2000>.
+
+config ARCH_IXDP2800
+ bool "Support Intel IXDP2800"
+ help
+ Say 'Y' here if you want your kernel to support the Intel
+ IXDP2800 reference platform. For more information on
+ this platform, see <file:Documentation/arm/IXP2000>.
+
+config ARCH_IXDP2X00
+ bool
+ depends on ARCH_IXDP2400 || ARCH_IXDP2800
+ default y
+
+config ARCH_IXDP2401
+ bool "Support Intel IXDP2401"
+ help
+ Say 'Y' here if you want your kernel to support the Intel
+ IXDP2401 reference platform. For more information on
+ this platform, see <file:Documentation/arm/IXP2000>.
+
+config ARCH_IXDP2801
+ bool "Support Intel IXDP2801 and IXDP28x5"
+ help
+ Say 'Y' here if you want your kernel to support the Intel
+ IXDP2801/2805/2855 reference platforms. For more information on
+ this platform, see <file:Documentation/arm/IXP2000>.
+
+config MACH_IXDP28X5
+ bool
+ depends on ARCH_IXDP2801
+ default y
+
+config ARCH_IXDP2X01
+ bool
+ depends on ARCH_IXDP2401 || ARCH_IXDP2801
+ default y
+
+config IXP2000_SUPPORT_BROKEN_PCI_IO
+ bool "Support broken PCI I/O on older IXP2000s"
+ default y
+ help
+ Say 'N' here if you only intend to run your kernel on an
+ IXP2000 B0 or later model and do not need the PCI I/O
+ byteswap workaround. Say 'Y' otherwise.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ixp2000/Makefile b/arch/arm/mach-ixp2000/Makefile
new file mode 100644
index 00000000..1e6139d4
--- /dev/null
+++ b/arch/arm/mach-ixp2000/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y := core.o pci.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_ENP2611) += enp2611.o
+obj-$(CONFIG_ARCH_IXDP2400) += ixdp2400.o
+obj-$(CONFIG_ARCH_IXDP2800) += ixdp2800.o
+obj-$(CONFIG_ARCH_IXDP2X00) += ixdp2x00.o
+obj-$(CONFIG_ARCH_IXDP2X01) += ixdp2x01.o
+
diff --git a/arch/arm/mach-ixp2000/Makefile.boot b/arch/arm/mach-ixp2000/Makefile.boot
new file mode 100644
index 00000000..d84c5807
--- /dev/null
+++ b/arch/arm/mach-ixp2000/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
new file mode 100644
index 00000000..4068166c
--- /dev/null
+++ b/arch/arm/mach-ixp2000/core.c
@@ -0,0 +1,516 @@
+/*
+ * arch/arm/mach-ixp2000/core.c
+ *
+ * Common routines used by all IXP2400/2800 based platforms.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (C) MontaVista Software, Inc.
+ *
+ * Based on work Copyright (C) 2002-2003 Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/serial_8250.h>
+#include <linux/mm.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include <mach/gpio.h>
+
+static DEFINE_SPINLOCK(ixp2000_slowport_lock);
+static unsigned long ixp2000_slowport_irq_flags;
+
+/*************************************************************************
+ * Slowport access routines
+ *************************************************************************/
+void ixp2000_acquire_slowport(struct slowport_cfg *new_cfg, struct slowport_cfg *old_cfg)
+{
+ spin_lock_irqsave(&ixp2000_slowport_lock, ixp2000_slowport_irq_flags);
+
+ old_cfg->CCR = *IXP2000_SLOWPORT_CCR;
+ old_cfg->WTC = *IXP2000_SLOWPORT_WTC2;
+ old_cfg->RTC = *IXP2000_SLOWPORT_RTC2;
+ old_cfg->PCR = *IXP2000_SLOWPORT_PCR;
+ old_cfg->ADC = *IXP2000_SLOWPORT_ADC;
+
+ ixp2000_reg_write(IXP2000_SLOWPORT_CCR, new_cfg->CCR);
+ ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, new_cfg->WTC);
+ ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, new_cfg->RTC);
+ ixp2000_reg_write(IXP2000_SLOWPORT_PCR, new_cfg->PCR);
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, new_cfg->ADC);
+}
+
+void ixp2000_release_slowport(struct slowport_cfg *old_cfg)
+{
+ ixp2000_reg_write(IXP2000_SLOWPORT_CCR, old_cfg->CCR);
+ ixp2000_reg_write(IXP2000_SLOWPORT_WTC2, old_cfg->WTC);
+ ixp2000_reg_write(IXP2000_SLOWPORT_RTC2, old_cfg->RTC);
+ ixp2000_reg_write(IXP2000_SLOWPORT_PCR, old_cfg->PCR);
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_ADC, old_cfg->ADC);
+
+ spin_unlock_irqrestore(&ixp2000_slowport_lock,
+ ixp2000_slowport_irq_flags);
+}
+
+/*************************************************************************
+ * Chip specific mappings shared by all IXP2000 systems
+ *************************************************************************/
+static struct map_desc ixp2000_io_desc[] __initdata = {
+ {
+ .virtual = IXP2000_CAP_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
+ .length = IXP2000_CAP_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_INTCTL_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
+ .length = IXP2000_INTCTL_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_PCI_CREG_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
+ .length = IXP2000_PCI_CREG_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_PCI_CSR_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
+ .length = IXP2000_PCI_CSR_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_MSF_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
+ .length = IXP2000_MSF_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
+ .length = IXP2000_SCRATCH_RING_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_SRAM0_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
+ .length = IXP2000_SRAM0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_PCI_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
+ .length = IXP2000_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_PCI_CFG0_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
+ .length = IXP2000_PCI_CFG0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IXP2000_PCI_CFG1_VIRT_BASE,
+ .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
+ .length = IXP2000_PCI_CFG1_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+void __init ixp2000_map_io(void)
+{
+ iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
+
+ /* Set slowport to 8-bit mode. */
+ ixp2000_reg_wrb(IXP2000_SLOWPORT_FRM, 1);
+}
+
+
+/*************************************************************************
+ * Serial port support for IXP2000
+ *************************************************************************/
+static struct plat_serial8250_port ixp2000_serial_port[] = {
+ {
+ .mapbase = IXP2000_UART_PHYS_BASE,
+ .membase = (char *)(IXP2000_UART_VIRT_BASE + 3),
+ .irq = IRQ_IXP2000_UART,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 50000000,
+ },
+ { },
+};
+
+static struct resource ixp2000_uart_resource = {
+ .start = IXP2000_UART_PHYS_BASE,
+ .end = IXP2000_UART_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixp2000_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = ixp2000_serial_port,
+ },
+ .num_resources = 1,
+ .resource = &ixp2000_uart_resource,
+};
+
+void __init ixp2000_uart_init(void)
+{
+ platform_device_register(&ixp2000_serial_device);
+}
+
+
+/*************************************************************************
+ * Timer-tick functions for IXP2000
+ *************************************************************************/
+static unsigned ticks_per_jiffy;
+static unsigned ticks_per_usec;
+static unsigned next_jiffy_time;
+static volatile unsigned long *missing_jiffy_timer_csr;
+
+unsigned long ixp2000_gettimeoffset (void)
+{
+ unsigned long offset;
+
+ offset = next_jiffy_time - *missing_jiffy_timer_csr;
+
+ return offset / ticks_per_usec;
+}
+
+static irqreturn_t ixp2000_timer_interrupt(int irq, void *dev_id)
+{
+ /* clear timer 1 */
+ ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
+
+ while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr)
+ >= ticks_per_jiffy) {
+ timer_tick();
+ next_jiffy_time -= ticks_per_jiffy;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ixp2000_timer_irq = {
+ .name = "IXP2000 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ixp2000_timer_interrupt,
+};
+
+void __init ixp2000_init_time(unsigned long tick_rate)
+{
+ ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
+ ticks_per_usec = tick_rate / 1000000;
+
+ /*
+ * We use timer 1 as our timer interrupt.
+ */
+ ixp2000_reg_write(IXP2000_T1_CLR, 0);
+ ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
+ ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
+
+ /*
+ * We use a second timer as a monotonic counter for tracking
+ * missed jiffies. The IXP2000 has four timers, but if we're
+ * on an A-step IXP2800, timer 2 and 3 don't work, so on those
+ * chips we use timer 4. Timer 4 is the only timer that can
+ * be used for the watchdog, so we use timer 2 if we're on a
+ * non-buggy chip.
+ */
+ if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+ printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
+
+ ixp2000_reg_write(IXP2000_T4_CLR, 0);
+ ixp2000_reg_write(IXP2000_T4_CLD, -1);
+ ixp2000_reg_wrb(IXP2000_T4_CTL, (1 << 7));
+ missing_jiffy_timer_csr = IXP2000_T4_CSR;
+ } else {
+ ixp2000_reg_write(IXP2000_T2_CLR, 0);
+ ixp2000_reg_write(IXP2000_T2_CLD, -1);
+ ixp2000_reg_wrb(IXP2000_T2_CTL, (1 << 7));
+ missing_jiffy_timer_csr = IXP2000_T2_CSR;
+ }
+ next_jiffy_time = 0xffffffff;
+
+ /* register for interrupt */
+ setup_irq(IRQ_IXP2000_TIMER1, &ixp2000_timer_irq);
+}
+
+/*************************************************************************
+ * GPIO helpers
+ *************************************************************************/
+static unsigned long GPIO_IRQ_falling_edge;
+static unsigned long GPIO_IRQ_rising_edge;
+static unsigned long GPIO_IRQ_level_low;
+static unsigned long GPIO_IRQ_level_high;
+
+static void update_gpio_int_csrs(void)
+{
+ ixp2000_reg_write(IXP2000_GPIO_FEDR, GPIO_IRQ_falling_edge);
+ ixp2000_reg_write(IXP2000_GPIO_REDR, GPIO_IRQ_rising_edge);
+ ixp2000_reg_write(IXP2000_GPIO_LSLR, GPIO_IRQ_level_low);
+ ixp2000_reg_wrb(IXP2000_GPIO_LSHR, GPIO_IRQ_level_high);
+}
+
+void gpio_line_config(int line, int direction)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (direction == GPIO_OUT) {
+ /* if it's an output, it ain't an interrupt anymore */
+ GPIO_IRQ_falling_edge &= ~(1 << line);
+ GPIO_IRQ_rising_edge &= ~(1 << line);
+ GPIO_IRQ_level_low &= ~(1 << line);
+ GPIO_IRQ_level_high &= ~(1 << line);
+ update_gpio_int_csrs();
+
+ ixp2000_reg_wrb(IXP2000_GPIO_PDSR, 1 << line);
+ } else if (direction == GPIO_IN) {
+ ixp2000_reg_wrb(IXP2000_GPIO_PDCR, 1 << line);
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_line_config);
+
+
+/*************************************************************************
+ * IRQ handling IXP2000
+ *************************************************************************/
+static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i;
+ unsigned long status = *IXP2000_GPIO_INST;
+
+ for (i = 0; i <= 7; i++) {
+ if (status & (1<<i)) {
+ generic_handle_irq(i + IRQ_IXP2000_GPIO0);
+ }
+ }
+}
+
+static int ixp2000_GPIO_irq_type(struct irq_data *d, unsigned int type)
+{
+ int line = d->irq - IRQ_IXP2000_GPIO0;
+
+ /*
+ * First, configure this GPIO line as an input.
+ */
+ ixp2000_reg_write(IXP2000_GPIO_PDCR, 1 << line);
+
+ /*
+ * Then, set the proper trigger type.
+ */
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ GPIO_IRQ_falling_edge |= 1 << line;
+ else
+ GPIO_IRQ_falling_edge &= ~(1 << line);
+ if (type & IRQ_TYPE_EDGE_RISING)
+ GPIO_IRQ_rising_edge |= 1 << line;
+ else
+ GPIO_IRQ_rising_edge &= ~(1 << line);
+ if (type & IRQ_TYPE_LEVEL_LOW)
+ GPIO_IRQ_level_low |= 1 << line;
+ else
+ GPIO_IRQ_level_low &= ~(1 << line);
+ if (type & IRQ_TYPE_LEVEL_HIGH)
+ GPIO_IRQ_level_high |= 1 << line;
+ else
+ GPIO_IRQ_level_high &= ~(1 << line);
+ update_gpio_int_csrs();
+
+ return 0;
+}
+
+static void ixp2000_GPIO_irq_mask_ack(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ ixp2000_reg_write(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+
+ ixp2000_reg_write(IXP2000_GPIO_EDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ ixp2000_reg_write(IXP2000_GPIO_LDSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+ ixp2000_reg_wrb(IXP2000_GPIO_INST, (1 << (irq - IRQ_IXP2000_GPIO0)));
+}
+
+static void ixp2000_GPIO_irq_mask(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ ixp2000_reg_wrb(IXP2000_GPIO_INCR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+}
+
+static void ixp2000_GPIO_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0)));
+}
+
+static struct irq_chip ixp2000_GPIO_irq_chip = {
+ .irq_ack = ixp2000_GPIO_irq_mask_ack,
+ .irq_mask = ixp2000_GPIO_irq_mask,
+ .irq_unmask = ixp2000_GPIO_irq_unmask,
+ .irq_set_type = ixp2000_GPIO_irq_type,
+};
+
+static void ixp2000_pci_irq_mask(struct irq_data *d)
+{
+ unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
+ if (d->irq == IRQ_IXP2000_PCIA)
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 26)));
+ else if (d->irq == IRQ_IXP2000_PCIB)
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, (temp & ~(1 << 27)));
+}
+
+static void ixp2000_pci_irq_unmask(struct irq_data *d)
+{
+ unsigned long temp = *IXP2000_PCI_XSCALE_INT_ENABLE;
+ if (d->irq == IRQ_IXP2000_PCIA)
+ ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 26)));
+ else if (d->irq == IRQ_IXP2000_PCIB)
+ ixp2000_reg_write(IXP2000_PCI_XSCALE_INT_ENABLE, (temp | (1 << 27)));
+}
+
+/*
+ * Error interrupts. These are used extensively by the microengine drivers
+ */
+static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i;
+ unsigned long status = *IXP2000_IRQ_ERR_STATUS;
+
+ for(i = 31; i >= 0; i--) {
+ if(status & (1 << i)) {
+ generic_handle_irq(IRQ_IXP2000_DRAM0_MIN_ERR + i);
+ }
+ }
+}
+
+static void ixp2000_err_irq_mask(struct irq_data *d)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_CLR,
+ (1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static void ixp2000_err_irq_unmask(struct irq_data *d)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ERR_ENABLE_SET,
+ (1 << (d->irq - IRQ_IXP2000_DRAM0_MIN_ERR)));
+}
+
+static struct irq_chip ixp2000_err_irq_chip = {
+ .irq_ack = ixp2000_err_irq_mask,
+ .irq_mask = ixp2000_err_irq_mask,
+ .irq_unmask = ixp2000_err_irq_unmask
+};
+
+static struct irq_chip ixp2000_pci_irq_chip = {
+ .irq_ack = ixp2000_pci_irq_mask,
+ .irq_mask = ixp2000_pci_irq_mask,
+ .irq_unmask = ixp2000_pci_irq_unmask
+};
+
+static void ixp2000_irq_mask(struct irq_data *d)
+{
+ ixp2000_reg_wrb(IXP2000_IRQ_ENABLE_CLR, (1 << d->irq));
+}
+
+static void ixp2000_irq_unmask(struct irq_data *d)
+{
+ ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << d->irq));
+}
+
+static struct irq_chip ixp2000_irq_chip = {
+ .irq_ack = ixp2000_irq_mask,
+ .irq_mask = ixp2000_irq_mask,
+ .irq_unmask = ixp2000_irq_unmask
+};
+
+void __init ixp2000_init_irq(void)
+{
+ int irq;
+
+ /*
+ * Mask all sources
+ */
+ ixp2000_reg_write(IXP2000_IRQ_ENABLE_CLR, 0xffffffff);
+ ixp2000_reg_write(IXP2000_FIQ_ENABLE_CLR, 0xffffffff);
+
+ /* clear all GPIO edge/level detects */
+ ixp2000_reg_write(IXP2000_GPIO_REDR, 0);
+ ixp2000_reg_write(IXP2000_GPIO_FEDR, 0);
+ ixp2000_reg_write(IXP2000_GPIO_LSHR, 0);
+ ixp2000_reg_write(IXP2000_GPIO_LSLR, 0);
+ ixp2000_reg_write(IXP2000_GPIO_INCR, -1);
+
+ /* clear PCI interrupt sources */
+ ixp2000_reg_wrb(IXP2000_PCI_XSCALE_INT_ENABLE, 0);
+
+ /*
+ * Certain bits in the IRQ status register of the
+ * IXP2000 are reserved. Instead of trying to map
+ * things non 1:1 from bit position to IRQ number,
+ * we mark the reserved IRQs as invalid. This makes
+ * our mask/unmask code much simpler.
+ */
+ for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
+ if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
+ irq_set_chip_and_handler(irq, &ixp2000_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ } else set_irq_flags(irq, 0);
+ }
+
+ for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
+ if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
+ IXP2000_VALID_ERR_IRQ_MASK) {
+ irq_set_chip_and_handler(irq, &ixp2000_err_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ else
+ set_irq_flags(irq, 0);
+ }
+ irq_set_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
+
+ for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
+ irq_set_chip_and_handler(irq, &ixp2000_GPIO_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ irq_set_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler);
+
+ /*
+ * Enable PCI irqs. The actual PCI[AB] decoding is done in
+ * entry-macro.S, so we don't need a chained handler for the
+ * PCI interrupt source.
+ */
+ ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI));
+ for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) {
+ irq_set_chip_and_handler(irq, &ixp2000_pci_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
+
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c
new file mode 100644
index 00000000..88663ab1
--- /dev/null
+++ b/arch/arm/mach-ixp2000/enp2611.c
@@ -0,0 +1,263 @@
+/*
+ * arch/arm/mach-ixp2000/enp2611.c
+ *
+ * Radisys ENP-2611 support.
+ *
+ * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The
+ * original version carries the following notices:
+ *
+ * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002-2003 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+/*************************************************************************
+ * ENP-2611 timer tick configuration
+ *************************************************************************/
+static void __init enp2611_timer_init(void)
+{
+ ixp2000_init_time(50 * 1000 * 1000);
+}
+
+static struct sys_timer enp2611_timer = {
+ .init = enp2611_timer_init,
+ .offset = ixp2000_gettimeoffset,
+};
+
+
+/*************************************************************************
+ * ENP-2611 I/O
+ *************************************************************************/
+static struct map_desc enp2611_io_desc[] __initdata = {
+ {
+ .virtual = ENP2611_CALEB_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
+ .length = ENP2611_CALEB_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = ENP2611_PM3386_0_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
+ .length = ENP2611_PM3386_0_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = ENP2611_PM3386_1_VIRT_BASE,
+ .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
+ .length = ENP2611_PM3386_1_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+void __init enp2611_map_io(void)
+{
+ ixp2000_map_io();
+ iotable_init(enp2611_io_desc, ARRAY_SIZE(enp2611_io_desc));
+}
+
+
+/*************************************************************************
+ * ENP-2611 PCI
+ *************************************************************************/
+static int enp2611_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ sys->mem_offset = 0xe0000000;
+ ixp2000_pci_setup(nr, sys);
+ return 1;
+}
+
+static void __init enp2611_pci_preinit(void)
+{
+ ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
+ ixp2000_pci_preinit();
+ pcibios_setup("firmware");
+}
+
+static inline int enp2611_pci_valid_device(struct pci_bus *bus,
+ unsigned int devfn)
+{
+ /* The 82559 ethernet controller appears at both PCI:1:0:0 and
+ * PCI:1:2:0, so let's pretend the second one isn't there.
+ */
+ if (bus->number == 0x01 && devfn == 0x10)
+ return 0;
+
+ return 1;
+}
+
+static int enp2611_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ if (enp2611_pci_valid_device(bus, devfn))
+ return ixp2000_pci_read_config(bus, devfn, where, size, value);
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static int enp2611_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ if (enp2611_pci_valid_device(bus, devfn))
+ return ixp2000_pci_write_config(bus, devfn, where, size, value);
+
+ return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+static struct pci_ops enp2611_pci_ops = {
+ .read = enp2611_pci_read_config,
+ .write = enp2611_pci_write_config
+};
+
+static struct pci_bus * __init enp2611_pci_scan_bus(int nr,
+ struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &enp2611_pci_ops, sys);
+}
+
+static int __init enp2611_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 0) {
+ /* IXP2400. */
+ irq = IRQ_IXP2000_PCIA;
+ } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 1) {
+ /* 21555 non-transparent bridge. */
+ irq = IRQ_IXP2000_PCIB;
+ } else if (dev->bus->number == 0 && PCI_SLOT(dev->devfn) == 4) {
+ /* PCI2050B transparent bridge. */
+ irq = -1;
+ } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 0) {
+ /* 82559 ethernet. */
+ irq = IRQ_IXP2000_PCIA;
+ } else if (dev->bus->number == 1 && PCI_SLOT(dev->devfn) == 1) {
+ /* SPI-3 option board. */
+ irq = IRQ_IXP2000_PCIB;
+ } else {
+ printk(KERN_ERR "enp2611_pci_map_irq() called for unknown "
+ "device PCI:%d:%d:%d\n", dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+ irq = -1;
+ }
+
+ return irq;
+}
+
+struct hw_pci enp2611_pci __initdata = {
+ .nr_controllers = 1,
+ .setup = enp2611_pci_setup,
+ .preinit = enp2611_pci_preinit,
+ .scan = enp2611_pci_scan_bus,
+ .map_irq = enp2611_pci_map_irq,
+};
+
+int __init enp2611_pci_init(void)
+{
+ if (machine_is_enp2611())
+ pci_common_init(&enp2611_pci);
+
+ return 0;
+}
+
+subsys_initcall(enp2611_pci_init);
+
+
+/*************************************************************************
+ * ENP-2611 Machine Initialization
+ *************************************************************************/
+static struct flash_platform_data enp2611_flash_platform_data = {
+ .map_name = "cfi_probe",
+ .width = 1,
+};
+
+static struct ixp2000_flash_data enp2611_flash_data = {
+ .platform_data = &enp2611_flash_platform_data,
+ .nr_banks = 1
+};
+
+static struct resource enp2611_flash_resource = {
+ .start = 0xc4000000,
+ .end = 0xc4000000 + 0x00ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device enp2611_flash = {
+ .name = "IXP2000-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &enp2611_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &enp2611_flash_resource,
+};
+
+static struct ixp2000_i2c_pins enp2611_i2c_gpio_pins = {
+ .sda_pin = ENP2611_GPIO_SDA,
+ .scl_pin = ENP2611_GPIO_SCL,
+};
+
+static struct platform_device enp2611_i2c_controller = {
+ .name = "IXP2000-I2C",
+ .id = 0,
+ .dev = {
+ .platform_data = &enp2611_i2c_gpio_pins
+ },
+ .num_resources = 0
+};
+
+static struct platform_device *enp2611_devices[] __initdata = {
+ &enp2611_flash,
+ &enp2611_i2c_controller
+};
+
+static void __init enp2611_init_machine(void)
+{
+ platform_add_devices(enp2611_devices, ARRAY_SIZE(enp2611_devices));
+ ixp2000_uart_init();
+}
+
+
+MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board")
+ /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
+ .boot_params = 0x00000100,
+ .map_io = enp2611_map_io,
+ .init_irq = ixp2000_init_irq,
+ .timer = &enp2611_timer,
+ .init_machine = enp2611_init_machine,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-ixp2000/include/mach/debug-macro.S b/arch/arm/mach-ixp2000/include/mach/debug-macro.S
new file mode 100644
index 00000000..0ef533b2
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/debug-macro.S
@@ -0,0 +1,25 @@
+/* arch/arm/mach-ixp2000/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00030000
+#ifdef __ARMEB__
+ orr \rp, \rp, #0x00000003
+#endif
+ orr \rv, \rp, #0xfe000000 @ virtual base
+ orr \rv, \rv, #0x00f00000
+ orr \rp, \rp, #0xc0000000 @ Physical base
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-ixp2000/include/mach/enp2611.h b/arch/arm/mach-ixp2000/include/mach/enp2611.h
new file mode 100644
index 00000000..9ce36900
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/enp2611.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/enp2611.h
+ *
+ * Register and other defines for Radisys ENP-2611
+ *
+ * Created 2004 by Lennert Buytenhek from the ixdp2x01 code. The
+ * original version carries the following notices:
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ */
+
+#ifndef __ENP2611_H
+#define __ENP2611_H
+
+#define ENP2611_CALEB_PHYS_BASE 0xc5000000
+#define ENP2611_CALEB_VIRT_BASE 0xfe000000
+#define ENP2611_CALEB_SIZE 0x00100000
+
+#define ENP2611_PM3386_0_PHYS_BASE 0xc6000000
+#define ENP2611_PM3386_0_VIRT_BASE 0xfe100000
+#define ENP2611_PM3386_0_SIZE 0x00100000
+
+#define ENP2611_PM3386_1_PHYS_BASE 0xc6400000
+#define ENP2611_PM3386_1_VIRT_BASE 0xfe200000
+#define ENP2611_PM3386_1_SIZE 0x00100000
+
+#define ENP2611_GPIO_SCL 7
+#define ENP2611_GPIO_SDA 6
+
+#define IRQ_ENP2611_THERMAL IRQ_IXP2000_GPIO4
+#define IRQ_ENP2611_OPTION_BOARD IRQ_IXP2000_GPIO3
+#define IRQ_ENP2611_CALEB IRQ_IXP2000_GPIO2
+#define IRQ_ENP2611_PM3386_1 IRQ_IXP2000_GPIO1
+#define IRQ_ENP2611_PM3386_0 IRQ_IXP2000_GPIO0
+
+
+#endif
diff --git a/arch/arm/mach-ixp2000/include/mach/entry-macro.S b/arch/arm/mach-ixp2000/include/mach/entry-macro.S
new file mode 100644
index 00000000..5850ffc8
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/entry-macro.S
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IXP2000-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \irqnr, #0x0 @clear out irqnr as default
+ mov \base, #0xfe000000
+ orr \base, \base, #0x00e00000
+ orr \base, \base, #0x08
+ ldr \irqstat, [\base] @ get interrupts
+
+ cmp \irqstat, #0
+ beq 1001f
+
+ clz \irqnr, \irqstat
+ mov \base, #31
+ subs \irqnr, \base, \irqnr
+
+ /*
+ * We handle PCIA and PCIB here so we don't have an
+ * extra layer of code just to check these two bits.
+ */
+ cmp \irqnr, #IRQ_IXP2000_PCI
+ bne 1001f
+
+ mov \base, #0xfe000000
+ orr \base, \base, #0x00c00000
+ orr \base, \base, #0x00000100
+ orr \base, \base, #0x00000058
+ ldr \irqstat, [\base]
+
+ mov \tmp, #(1<<26)
+ tst \irqstat, \tmp
+ movne \irqnr, #IRQ_IXP2000_PCIA
+ bne 1001f
+
+ mov \tmp, #(1<<27)
+ tst \irqstat, \tmp
+ movne \irqnr, #IRQ_IXP2000_PCIB
+
+1001:
+ .endm
+
diff --git a/arch/arm/mach-ixp2000/include/mach/gpio.h b/arch/arm/mach-ixp2000/include/mach/gpio.h
new file mode 100644
index 00000000..4a88d2c3
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/gpio.h
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software, you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * IXP2000 GPIO in/out, edge/level detection for IRQs:
+ * IRQs are generated on Falling-edge, Rising-Edge, Level-low, Level-High
+ * or both Falling-edge and Rising-edge.
+ * This must be called *before* the corresponding IRQ is registerd.
+ * Use this instead of directly setting the GPIO registers.
+ * GPIOs may also be used as GPIOs (e.g. for emulating i2c/smb)
+ */
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#ifndef __ASSEMBLY__
+
+#define GPIO_IN 0
+#define GPIO_OUT 1
+
+#define IXP2000_GPIO_LOW 0
+#define IXP2000_GPIO_HIGH 1
+
+extern void gpio_line_config(int line, int direction);
+
+static inline int gpio_line_get(int line)
+{
+ return (((*IXP2000_GPIO_PLR) >> line) & 1);
+}
+
+static inline void gpio_line_set(int line, int value)
+{
+ if (value == IXP2000_GPIO_HIGH) {
+ ixp2000_reg_write(IXP2000_GPIO_POSR, 1 << line);
+ } else if (value == IXP2000_GPIO_LOW) {
+ ixp2000_reg_write(IXP2000_GPIO_POCR, 1 << line);
+ }
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* ASM_ARCH_IXP2000_GPIO_H_ */
diff --git a/arch/arm/mach-ixp2000/include/mach/hardware.h b/arch/arm/mach-ixp2000/include/mach/hardware.h
new file mode 100644
index 00000000..f033de4e
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/hardware.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/hardware.h
+ *
+ * Hardware definitions for IXP2400/2800 based systems
+ *
+ * Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright (C) 2001-2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#define __ASM_ARCH_HARDWARE_H__
+
+/*
+ * This needs to be platform-specific?
+ */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+
+#include "ixp2000-regs.h" /* Chipset Registers */
+
+#define pcibios_assign_all_busses() 0
+
+/*
+ * Platform helper functions
+ */
+#include "platform.h"
+
+/*
+ * Platform-specific bits
+ */
+#include "enp2611.h" /* ENP-2611 */
+#include "ixdp2x00.h" /* IXDP2400/2800 */
+#include "ixdp2x01.h" /* IXDP2401/2801 */
+
+#endif /* _ASM_ARCH_HARDWARE_H__ */
diff --git a/arch/arm/mach-ixp2000/include/mach/io.h b/arch/arm/mach-ixp2000/include/mach/io.h
new file mode 100644
index 00000000..859e5849
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/io.h
@@ -0,0 +1,134 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/io.h
+ *
+ * Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyrgiht (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+#define __mem_pci(a) (a)
+
+/*
+ * The A? revisions of the IXP2000s assert byte lanes for PCI I/O
+ * transactions the other way round (MEM transactions don't have this
+ * issue), so if we want to support those models, we need to override
+ * the standard I/O functions.
+ *
+ * B0 and later have a bit that can be set to 1 to get the proper
+ * behavior for I/O transactions, which then allows us to use the
+ * standard I/O functions. This is what we do if the user does not
+ * explicitly ask for support for pre-B0.
+ */
+#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+#define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+
+#define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3)
+#define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2)
+
+#define outb(v,p) __raw_writeb((v),alignb(___io(p)))
+#define outw(v,p) __raw_writew((v),alignw(___io(p)))
+#define outl(v,p) __raw_writel((v),___io(p))
+
+#define inb(p) ({ unsigned int __v = __raw_readb(alignb(___io(p))); __v; })
+#define inw(p) \
+ ({ unsigned int __v = (__raw_readw(alignw(___io(p)))); __v; })
+#define inl(p) \
+ ({ unsigned int __v = (__raw_readl(___io(p))); __v; })
+
+#define outsb(p,d,l) __raw_writesb(alignb(___io(p)),d,l)
+#define outsw(p,d,l) __raw_writesw(alignw(___io(p)),d,l)
+#define outsl(p,d,l) __raw_writesl(___io(p),d,l)
+
+#define insb(p,d,l) __raw_readsb(alignb(___io(p)),d,l)
+#define insw(p,d,l) __raw_readsw(alignw(___io(p)),d,l)
+#define insl(p,d,l) __raw_readsl(___io(p),d,l)
+
+#define __is_io_address(p) ((((unsigned long)(p)) & ~(IXP2000_PCI_IO_SIZE - 1)) == IXP2000_PCI_IO_VIRT_BASE)
+
+#define ioread8(p) \
+ ({ \
+ unsigned int __v; \
+ \
+ if (__is_io_address(p)) { \
+ __v = __raw_readb(alignb(p)); \
+ } else { \
+ __v = __raw_readb(p); \
+ } \
+ \
+ __v; \
+ }) \
+
+#define ioread16(p) \
+ ({ \
+ unsigned int __v; \
+ \
+ if (__is_io_address(p)) { \
+ __v = __raw_readw(alignw(p)); \
+ } else { \
+ __v = le16_to_cpu(__raw_readw(p)); \
+ } \
+ \
+ __v; \
+ })
+
+#define ioread32(p) \
+ ({ \
+ unsigned int __v; \
+ \
+ if (__is_io_address(p)) { \
+ __v = __raw_readl(p); \
+ } else { \
+ __v = le32_to_cpu(__raw_readl(p)); \
+ } \
+ \
+ __v; \
+ })
+
+#define iowrite8(v,p) \
+ ({ \
+ if (__is_io_address(p)) { \
+ __raw_writeb((v), alignb(p)); \
+ } else { \
+ __raw_writeb((v), p); \
+ } \
+ })
+
+#define iowrite16(v,p) \
+ ({ \
+ if (__is_io_address(p)) { \
+ __raw_writew((v), alignw(p)); \
+ } else { \
+ __raw_writew(cpu_to_le16(v), p); \
+ } \
+ })
+
+#define iowrite32(v,p) \
+ ({ \
+ if (__is_io_address(p)) { \
+ __raw_writel((v), p); \
+ } else { \
+ __raw_writel(cpu_to_le32(v), p); \
+ } \
+ })
+
+#define ioport_map(port, nr) ___io(port)
+
+#define ioport_unmap(addr)
+#else
+#define __io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE))
+#endif
+
+
+#endif
diff --git a/arch/arm/mach-ixp2000/include/mach/irqs.h b/arch/arm/mach-ixp2000/include/mach/irqs.h
new file mode 100644
index 00000000..bee96bca
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/irqs.h
@@ -0,0 +1,207 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/irqs.h
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IRQS_H
+#define _IRQS_H
+
+/*
+ * Do NOT add #ifdef MACHINE_FOO in here.
+ * Simpy add your machine IRQs here and increase NR_IRQS if needed to
+ * hold your machine's IRQ table.
+ */
+
+/*
+ * Some interrupt numbers go unused b/c the IRQ mask/ummask/status
+ * register has those bit reserved. We just mark those interrupts
+ * as invalid and this allows us to do mask/unmask with a single
+ * shift operation instead of having to map the IRQ number to
+ * a HW IRQ number.
+ */
+#define IRQ_IXP2000_SOFT_INT 0 /* soft interrupt */
+#define IRQ_IXP2000_ERRSUM 1 /* OR of all bits in ErrorStatus reg*/
+#define IRQ_IXP2000_UART 2
+#define IRQ_IXP2000_GPIO 3
+#define IRQ_IXP2000_TIMER1 4
+#define IRQ_IXP2000_TIMER2 5
+#define IRQ_IXP2000_TIMER3 6
+#define IRQ_IXP2000_TIMER4 7
+#define IRQ_IXP2000_PMU 8
+#define IRQ_IXP2000_SPF 9 /* Slow port framer IRQ */
+#define IRQ_IXP2000_DMA1 10
+#define IRQ_IXP2000_DMA2 11
+#define IRQ_IXP2000_DMA3 12
+#define IRQ_IXP2000_PCI_DOORBELL 13
+#define IRQ_IXP2000_ME_ATTN 14
+#define IRQ_IXP2000_PCI 15 /* PCI INTA or INTB */
+#define IRQ_IXP2000_THDA0 16 /* thread 0-31A */
+#define IRQ_IXP2000_THDA1 17 /* thread 32-63A, IXP2800 only */
+#define IRQ_IXP2000_THDA2 18 /* thread 64-95A */
+#define IRQ_IXP2000_THDA3 19 /* thread 96-127A, IXP2800 only */
+#define IRQ_IXP2000_THDB0 24 /* thread 0-31B */
+#define IRQ_IXP2000_THDB1 25 /* thread 32-63B, IXP2800 only */
+#define IRQ_IXP2000_THDB2 26 /* thread 64-95B */
+#define IRQ_IXP2000_THDB3 27 /* thread 96-127B, IXP2800 only */
+
+/* define generic GPIOs */
+#define IRQ_IXP2000_GPIO0 32
+#define IRQ_IXP2000_GPIO1 33
+#define IRQ_IXP2000_GPIO2 34
+#define IRQ_IXP2000_GPIO3 35
+#define IRQ_IXP2000_GPIO4 36
+#define IRQ_IXP2000_GPIO5 37
+#define IRQ_IXP2000_GPIO6 38
+#define IRQ_IXP2000_GPIO7 39
+
+/* split off the 2 PCI sources */
+#define IRQ_IXP2000_PCIA 40
+#define IRQ_IXP2000_PCIB 41
+
+/* Int sources from IRQ_ERROR_STATUS */
+#define IRQ_IXP2000_DRAM0_MIN_ERR 42
+#define IRQ_IXP2000_DRAM0_MAJ_ERR 43
+#define IRQ_IXP2000_DRAM1_MIN_ERR 44
+#define IRQ_IXP2000_DRAM1_MAJ_ERR 45
+#define IRQ_IXP2000_DRAM2_MIN_ERR 46
+#define IRQ_IXP2000_DRAM2_MAJ_ERR 47
+/* 48-57 reserved */
+#define IRQ_IXP2000_SRAM0_ERR 58
+#define IRQ_IXP2000_SRAM1_ERR 59
+#define IRQ_IXP2000_SRAM2_ERR 60
+#define IRQ_IXP2000_SRAM3_ERR 61
+/* 62-65 reserved */
+#define IRQ_IXP2000_MEDIA_ERR 66
+#define IRQ_IXP2000_PCI_ERR 67
+#define IRQ_IXP2000_SP_INT 68
+
+#define NR_IXP2000_IRQS 69
+
+#define IXP2000_BOARD_IRQ(x) (NR_IXP2000_IRQS + (x))
+
+#define IXP2000_BOARD_IRQ_MASK(irq) (1 << (irq - NR_IXP2000_IRQS))
+
+#define IXP2000_ERR_IRQ_MASK(irq) ( 1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))
+#define IXP2000_VALID_ERR_IRQ_MASK (\
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM0_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM1_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MIN_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_DRAM2_MAJ_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM0_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM1_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM2_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SRAM3_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_MEDIA_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_PCI_ERR) | \
+ IXP2000_ERR_IRQ_MASK(IRQ_IXP2000_SP_INT) )
+
+/*
+ * This allows for all the on-chip sources plus up to 32 CPLD based
+ * IRQs. Should be more than enough.
+ */
+#define IXP2000_BOARD_IRQS 32
+#define NR_IRQS (NR_IXP2000_IRQS + IXP2000_BOARD_IRQS)
+
+
+/*
+ * IXDP2400 specific IRQs
+ */
+#define IRQ_IXDP2400_INGRESS_NPU IXP2000_BOARD_IRQ(0)
+#define IRQ_IXDP2400_ENET IXP2000_BOARD_IRQ(1)
+#define IRQ_IXDP2400_MEDIA_PCI IXP2000_BOARD_IRQ(2)
+#define IRQ_IXDP2400_MEDIA_SP IXP2000_BOARD_IRQ(3)
+#define IRQ_IXDP2400_SF_PCI IXP2000_BOARD_IRQ(4)
+#define IRQ_IXDP2400_SF_SP IXP2000_BOARD_IRQ(5)
+#define IRQ_IXDP2400_PMC IXP2000_BOARD_IRQ(6)
+#define IRQ_IXDP2400_TVM IXP2000_BOARD_IRQ(7)
+
+#define NR_IXDP2400_IRQS ((IRQ_IXDP2400_TVM)+1)
+#define IXDP2400_NR_IRQS NR_IXDP2400_IRQS - NR_IXP2000_IRQS
+
+/* IXDP2800 specific IRQs */
+#define IRQ_IXDP2800_EGRESS_ENET IXP2000_BOARD_IRQ(0)
+#define IRQ_IXDP2800_INGRESS_NPU IXP2000_BOARD_IRQ(1)
+#define IRQ_IXDP2800_PMC IXP2000_BOARD_IRQ(2)
+#define IRQ_IXDP2800_FABRIC_PCI IXP2000_BOARD_IRQ(3)
+#define IRQ_IXDP2800_FABRIC IXP2000_BOARD_IRQ(4)
+#define IRQ_IXDP2800_MEDIA IXP2000_BOARD_IRQ(5)
+
+#define NR_IXDP2800_IRQS ((IRQ_IXDP2800_MEDIA)+1)
+#define IXDP2800_NR_IRQS NR_IXDP2800_IRQS - NR_IXP2000_IRQS
+
+/*
+ * IRQs on both IXDP2x01 boards
+ */
+#define IRQ_IXDP2X01_SPCI_DB_0 IXP2000_BOARD_IRQ(2)
+#define IRQ_IXDP2X01_SPCI_DB_1 IXP2000_BOARD_IRQ(3)
+#define IRQ_IXDP2X01_SPCI_PMC_INTA IXP2000_BOARD_IRQ(4)
+#define IRQ_IXDP2X01_SPCI_PMC_INTB IXP2000_BOARD_IRQ(5)
+#define IRQ_IXDP2X01_SPCI_PMC_INTC IXP2000_BOARD_IRQ(6)
+#define IRQ_IXDP2X01_SPCI_PMC_INTD IXP2000_BOARD_IRQ(7)
+#define IRQ_IXDP2X01_SPCI_FIC_INT IXP2000_BOARD_IRQ(8)
+#define IRQ_IXDP2X01_IPMI_FROM IXP2000_BOARD_IRQ(16)
+#define IRQ_IXDP2X01_125US IXP2000_BOARD_IRQ(17)
+#define IRQ_IXDP2X01_DB_0_ADD IXP2000_BOARD_IRQ(18)
+#define IRQ_IXDP2X01_DB_1_ADD IXP2000_BOARD_IRQ(19)
+#define IRQ_IXDP2X01_UART1 IXP2000_BOARD_IRQ(21)
+#define IRQ_IXDP2X01_UART2 IXP2000_BOARD_IRQ(22)
+#define IRQ_IXDP2X01_FIC_ADD_INT IXP2000_BOARD_IRQ(24)
+#define IRQ_IXDP2X01_CS8900 IXP2000_BOARD_IRQ(25)
+#define IRQ_IXDP2X01_BBSRAM IXP2000_BOARD_IRQ(26)
+
+#define IXDP2X01_VALID_IRQ_MASK ( \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_0) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_DB_1) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTA) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTB) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTC) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_PMC_INTD) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_SPCI_FIC_INT) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_IPMI_FROM) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_125US) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_0_ADD) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_DB_1_ADD) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART1) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_UART2) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_FIC_ADD_INT) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_CS8900) | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2X01_BBSRAM) )
+
+/*
+ * IXDP2401 specific IRQs
+ */
+#define IRQ_IXDP2401_INTA_82546 IXP2000_BOARD_IRQ(0)
+#define IRQ_IXDP2401_INTB_82546 IXP2000_BOARD_IRQ(1)
+
+#define IXDP2401_VALID_IRQ_MASK ( \
+ IXDP2X01_VALID_IRQ_MASK | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTA_82546) |\
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2401_INTB_82546))
+
+/*
+ * IXDP2801-specific IRQs
+ */
+#define IRQ_IXDP2801_RIV IXP2000_BOARD_IRQ(0)
+#define IRQ_IXDP2801_CNFG_MEDIA IXP2000_BOARD_IRQ(27)
+#define IRQ_IXDP2801_CLOCK_REF IXP2000_BOARD_IRQ(28)
+
+#define IXDP2801_VALID_IRQ_MASK ( \
+ IXDP2X01_VALID_IRQ_MASK | \
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_RIV) |\
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CNFG_MEDIA) |\
+ IXP2000_BOARD_IRQ_MASK(IRQ_IXDP2801_CLOCK_REF))
+
+#define NR_IXDP2X01_IRQS ((IRQ_IXDP2801_CLOCK_REF) + 1)
+
+#endif /*_IRQS_H*/
diff --git a/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h b/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h
new file mode 100644
index 00000000..5df8479d
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/ixdp2x00.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/ixdp2x00.h
+ *
+ * Register and other defines for IXDP2[48]00 platforms
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ */
+#ifndef _IXDP2X00_H_
+#define _IXDP2X00_H_
+
+/*
+ * On board CPLD memory map
+ */
+#define IXDP2X00_PHYS_CPLD_BASE 0xc7000000
+#define IXDP2X00_VIRT_CPLD_BASE 0xfe000000
+#define IXDP2X00_CPLD_SIZE 0x00100000
+
+
+#define IXDP2X00_CPLD_REG(x) \
+ (volatile unsigned long *)(IXDP2X00_VIRT_CPLD_BASE | x)
+
+/*
+ * IXDP2400 CPLD registers
+ */
+#define IXDP2400_CPLD_SYSLED IXDP2X00_CPLD_REG(0x0)
+#define IXDP2400_CPLD_DISP_DATA IXDP2X00_CPLD_REG(0x4)
+#define IXDP2400_CPLD_CLOCK_SPEED IXDP2X00_CPLD_REG(0x8)
+#define IXDP2400_CPLD_INT_STAT IXDP2X00_CPLD_REG(0xc)
+#define IXDP2400_CPLD_REV IXDP2X00_CPLD_REG(0x10)
+#define IXDP2400_CPLD_SYS_CLK_M IXDP2X00_CPLD_REG(0x14)
+#define IXDP2400_CPLD_SYS_CLK_N IXDP2X00_CPLD_REG(0x18)
+#define IXDP2400_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x48)
+
+/*
+ * IXDP2800 CPLD registers
+ */
+#define IXDP2800_CPLD_INT_STAT IXDP2X00_CPLD_REG(0x0)
+#define IXDP2800_CPLD_INT_MASK IXDP2X00_CPLD_REG(0x140)
+
+
+#define IXDP2X00_GPIO_I2C_ENABLE 0x02
+#define IXDP2X00_GPIO_SCL 0x07
+#define IXDP2X00_GPIO_SDA 0x06
+
+/*
+ * PCI devfns for on-board devices. We need these to be able to
+ * properly translate IRQs and for device removal.
+ */
+#define IXDP2400_SLAVE_ENET_DEVFN 0x18 /* Bus 1 */
+#define IXDP2400_MASTER_ENET_DEVFN 0x20 /* Bus 1 */
+#define IXDP2400_MEDIA_DEVFN 0x28 /* Bus 1 */
+#define IXDP2400_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */
+
+#define IXDP2800_SLAVE_ENET_DEVFN 0x20 /* Bus 1 */
+#define IXDP2800_MASTER_ENET_DEVFN 0x18 /* Bus 1 */
+#define IXDP2800_SWITCH_FABRIC_DEVFN 0x30 /* Bus 1 */
+
+#define IXDP2X00_P2P_DEVFN 0x20 /* Bus 0 */
+#define IXDP2X00_21555_DEVFN 0x30 /* Bus 0 */
+#define IXDP2X00_SLAVE_NPU_DEVFN 0x28 /* Bus 1 */
+#define IXDP2X00_PMC_DEVFN 0x38 /* Bus 1 */
+#define IXDP2X00_MASTER_NPU_DEVFN 0x38 /* Bus 1 */
+
+#ifndef __ASSEMBLY__
+/*
+ * The master NPU is always PCI master.
+ */
+static inline unsigned int ixdp2x00_master_npu(void)
+{
+ return !!ixp2000_is_pcimaster();
+}
+
+/*
+ * Helper functions used by ixdp2400 and ixdp2800 specific code
+ */
+void ixdp2x00_init_irq(volatile unsigned long*, volatile unsigned long *, unsigned long);
+void ixdp2x00_slave_pci_postinit(void);
+void ixdp2x00_init_machine(void);
+void ixdp2x00_map_io(void);
+
+#endif
+
+#endif /*_IXDP2X00_H_ */
diff --git a/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h b/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h
new file mode 100644
index 00000000..4c1f0408
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/ixdp2x01.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/ixdp2x01.h
+ *
+ * Platform definitions for IXDP2X01 && IXDP2801 systems
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (c) MontaVista Software, Inc.
+ *
+ * Based on original code Copyright (c) 2002-2003 Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __IXDP2X01_H__
+#define __IXDP2X01_H__
+
+#define IXDP2X01_PHYS_CPLD_BASE 0xc6024000
+#define IXDP2X01_VIRT_CPLD_BASE 0xfe000000
+#define IXDP2X01_CPLD_REGION_SIZE 0x00100000
+
+#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
+#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
+
+#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40)
+#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40)
+
+#define IXDP2X01_UART2_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x60)
+#define IXDP2X01_UART2_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x60)
+
+#define IXDP2X01_CS8900_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x80)
+#define IXDP2X01_CS8900_VIRT_END (IXDP2X01_CS8900_VIRT_BASE + 16)
+
+#define IXDP2X01_CPLD_RESET_REG IXDP2X01_CPLD_VIRT_REG(0x00)
+#define IXDP2X01_INT_MASK_SET_REG IXDP2X01_CPLD_VIRT_REG(0x08)
+#define IXDP2X01_INT_STAT_REG IXDP2X01_CPLD_VIRT_REG(0x0C)
+#define IXDP2X01_INT_RAW_REG IXDP2X01_CPLD_VIRT_REG(0x10)
+#define IXDP2X01_INT_MASK_CLR_REG IXDP2X01_INT_RAW_REG
+#define IXDP2X01_INT_SIM_REG IXDP2X01_CPLD_VIRT_REG(0x14)
+
+#define IXDP2X01_CPLD_FLASH_REG IXDP2X01_CPLD_VIRT_REG(0x20)
+
+#define IXDP2X01_CPLD_FLASH_INTERN 0x8000
+#define IXDP2X01_CPLD_FLASH_BANK_MASK 0xF
+#define IXDP2X01_FLASH_WINDOW_BITS 25
+#define IXDP2X01_FLASH_WINDOW_SIZE (1 << IXDP2X01_FLASH_WINDOW_BITS)
+#define IXDP2X01_FLASH_WINDOW_MASK (IXDP2X01_FLASH_WINDOW_SIZE - 1)
+
+#define IXDP2X01_UART_CLK 1843200
+
+#define IXDP2X01_GPIO_I2C_ENABLE 0x02
+#define IXDP2X01_GPIO_SCL 0x07
+#define IXDP2X01_GPIO_SDA 0x06
+
+#endif /* __IXDP2x01_H__ */
diff --git a/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h b/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
new file mode 100644
index 00000000..822f63f2
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
@@ -0,0 +1,451 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/ixp2000-regs.h
+ *
+ * Chipset register definitions for IXP2400/2800 based systems.
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, 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.
+ */
+#ifndef _IXP2000_REGS_H_
+#define _IXP2000_REGS_H_
+
+/*
+ * IXP2000 linux memory map:
+ *
+ * virt phys size
+ * fb000000 db000000 16M PCI CFG1
+ * fc000000 da000000 16M PCI CFG0
+ * fd000000 d8000000 16M PCI I/O
+ * fe[0-7]00000 8M per-platform mappings
+ * fe900000 80000000 1M SRAM #0 (first MB)
+ * fea00000 cb400000 1M SCRATCH ring get/put
+ * feb00000 c8000000 1M MSF
+ * fec00000 df000000 1M PCI CSRs
+ * fed00000 de000000 1M PCI CREG
+ * fee00000 d6000000 1M INTCTL
+ * fef00000 c0000000 1M CAP
+ */
+
+/*
+ * Static I/O regions.
+ *
+ * Most of the registers are clumped in 4K regions spread throughout
+ * the 0xc0000000 -> 0xc0100000 address range, but we just map in
+ * the whole range using a single 1 MB section instead of small
+ * 4K pages.
+ *
+ * CAP stands for CSR Access Proxy.
+ *
+ * If you change the virtual address of this mapping, please propagate
+ * the change to arch/arm/kernel/debug.S, which hardcodes the virtual
+ * address of the UART located in this region.
+ */
+
+#define IXP2000_CAP_PHYS_BASE 0xc0000000
+#define IXP2000_CAP_VIRT_BASE 0xfef00000
+#define IXP2000_CAP_SIZE 0x00100000
+
+/*
+ * Addresses for specific on-chip peripherals.
+ */
+#define IXP2000_SLOWPORT_CSR_VIRT_BASE 0xfef80000
+#define IXP2000_GLOBAL_REG_VIRT_BASE 0xfef04000
+#define IXP2000_UART_PHYS_BASE 0xc0030000
+#define IXP2000_UART_VIRT_BASE 0xfef30000
+#define IXP2000_TIMER_VIRT_BASE 0xfef20000
+#define IXP2000_UENGINE_CSR_VIRT_BASE 0xfef18000
+#define IXP2000_GPIO_VIRT_BASE 0xfef10000
+
+/*
+ * Devices outside of the 0xc0000000 -> 0xc0100000 range. The virtual
+ * addresses of the INTCTL and PCI_CSR mappings are hardcoded in
+ * entry-macro.S, so if you ever change these please propagate
+ * the change.
+ */
+#define IXP2000_INTCTL_PHYS_BASE 0xd6000000
+#define IXP2000_INTCTL_VIRT_BASE 0xfee00000
+#define IXP2000_INTCTL_SIZE 0x00100000
+
+#define IXP2000_PCI_CREG_PHYS_BASE 0xde000000
+#define IXP2000_PCI_CREG_VIRT_BASE 0xfed00000
+#define IXP2000_PCI_CREG_SIZE 0x00100000
+
+#define IXP2000_PCI_CSR_PHYS_BASE 0xdf000000
+#define IXP2000_PCI_CSR_VIRT_BASE 0xfec00000
+#define IXP2000_PCI_CSR_SIZE 0x00100000
+
+#define IXP2000_MSF_PHYS_BASE 0xc8000000
+#define IXP2000_MSF_VIRT_BASE 0xfeb00000
+#define IXP2000_MSF_SIZE 0x00100000
+
+#define IXP2000_SCRATCH_RING_PHYS_BASE 0xcb400000
+#define IXP2000_SCRATCH_RING_VIRT_BASE 0xfea00000
+#define IXP2000_SCRATCH_RING_SIZE 0x00100000
+
+#define IXP2000_SRAM0_PHYS_BASE 0x80000000
+#define IXP2000_SRAM0_VIRT_BASE 0xfe900000
+#define IXP2000_SRAM0_SIZE 0x00100000
+
+#define IXP2000_PCI_IO_PHYS_BASE 0xd8000000
+#define IXP2000_PCI_IO_VIRT_BASE 0xfd000000
+#define IXP2000_PCI_IO_SIZE 0x01000000
+
+#define IXP2000_PCI_CFG0_PHYS_BASE 0xda000000
+#define IXP2000_PCI_CFG0_VIRT_BASE 0xfc000000
+#define IXP2000_PCI_CFG0_SIZE 0x01000000
+
+#define IXP2000_PCI_CFG1_PHYS_BASE 0xdb000000
+#define IXP2000_PCI_CFG1_VIRT_BASE 0xfb000000
+#define IXP2000_PCI_CFG1_SIZE 0x01000000
+
+/*
+ * Timers
+ */
+#define IXP2000_TIMER_REG(x) ((volatile unsigned long*)(IXP2000_TIMER_VIRT_BASE | (x)))
+/* Timer control */
+#define IXP2000_T1_CTL IXP2000_TIMER_REG(0x00)
+#define IXP2000_T2_CTL IXP2000_TIMER_REG(0x04)
+#define IXP2000_T3_CTL IXP2000_TIMER_REG(0x08)
+#define IXP2000_T4_CTL IXP2000_TIMER_REG(0x0c)
+/* Store initial value */
+#define IXP2000_T1_CLD IXP2000_TIMER_REG(0x10)
+#define IXP2000_T2_CLD IXP2000_TIMER_REG(0x14)
+#define IXP2000_T3_CLD IXP2000_TIMER_REG(0x18)
+#define IXP2000_T4_CLD IXP2000_TIMER_REG(0x1c)
+/* Read current value */
+#define IXP2000_T1_CSR IXP2000_TIMER_REG(0x20)
+#define IXP2000_T2_CSR IXP2000_TIMER_REG(0x24)
+#define IXP2000_T3_CSR IXP2000_TIMER_REG(0x28)
+#define IXP2000_T4_CSR IXP2000_TIMER_REG(0x2c)
+/* Clear associated timer interrupt */
+#define IXP2000_T1_CLR IXP2000_TIMER_REG(0x30)
+#define IXP2000_T2_CLR IXP2000_TIMER_REG(0x34)
+#define IXP2000_T3_CLR IXP2000_TIMER_REG(0x38)
+#define IXP2000_T4_CLR IXP2000_TIMER_REG(0x3c)
+/* Timer watchdog enable for T4 */
+#define IXP2000_TWDE IXP2000_TIMER_REG(0x40)
+
+#define WDT_ENABLE 0x00000001
+#define TIMER_DIVIDER_256 0x00000008
+#define TIMER_ENABLE 0x00000080
+#define IRQ_MASK_TIMER1 (1 << 4)
+
+/*
+ * Interrupt controller registers
+ */
+#define IXP2000_INTCTL_REG(x) (volatile unsigned long*)(IXP2000_INTCTL_VIRT_BASE | (x))
+#define IXP2000_IRQ_STATUS IXP2000_INTCTL_REG(0x08)
+#define IXP2000_IRQ_ENABLE IXP2000_INTCTL_REG(0x10)
+#define IXP2000_IRQ_ENABLE_SET IXP2000_INTCTL_REG(0x10)
+#define IXP2000_IRQ_ENABLE_CLR IXP2000_INTCTL_REG(0x18)
+#define IXP2000_FIQ_ENABLE_CLR IXP2000_INTCTL_REG(0x14)
+#define IXP2000_IRQ_ERR_STATUS IXP2000_INTCTL_REG(0x24)
+#define IXP2000_IRQ_ERR_ENABLE_SET IXP2000_INTCTL_REG(0x2c)
+#define IXP2000_FIQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x30)
+#define IXP2000_IRQ_ERR_ENABLE_CLR IXP2000_INTCTL_REG(0x34)
+#define IXP2000_IRQ_THD_RAW_STATUS_A_0 IXP2000_INTCTL_REG(0x60)
+#define IXP2000_IRQ_THD_RAW_STATUS_A_1 IXP2000_INTCTL_REG(0x64)
+#define IXP2000_IRQ_THD_RAW_STATUS_A_2 IXP2000_INTCTL_REG(0x68)
+#define IXP2000_IRQ_THD_RAW_STATUS_A_3 IXP2000_INTCTL_REG(0x6c)
+#define IXP2000_IRQ_THD_RAW_STATUS_B_0 IXP2000_INTCTL_REG(0x80)
+#define IXP2000_IRQ_THD_RAW_STATUS_B_1 IXP2000_INTCTL_REG(0x84)
+#define IXP2000_IRQ_THD_RAW_STATUS_B_2 IXP2000_INTCTL_REG(0x88)
+#define IXP2000_IRQ_THD_RAW_STATUS_B_3 IXP2000_INTCTL_REG(0x8c)
+#define IXP2000_IRQ_THD_STATUS_A_0 IXP2000_INTCTL_REG(0xe0)
+#define IXP2000_IRQ_THD_STATUS_A_1 IXP2000_INTCTL_REG(0xe4)
+#define IXP2000_IRQ_THD_STATUS_A_2 IXP2000_INTCTL_REG(0xe8)
+#define IXP2000_IRQ_THD_STATUS_A_3 IXP2000_INTCTL_REG(0xec)
+#define IXP2000_IRQ_THD_STATUS_B_0 IXP2000_INTCTL_REG(0x100)
+#define IXP2000_IRQ_THD_STATUS_B_1 IXP2000_INTCTL_REG(0x104)
+#define IXP2000_IRQ_THD_STATUS_B_2 IXP2000_INTCTL_REG(0x108)
+#define IXP2000_IRQ_THD_STATUS_B_3 IXP2000_INTCTL_REG(0x10c)
+#define IXP2000_IRQ_THD_ENABLE_SET_A_0 IXP2000_INTCTL_REG(0x160)
+#define IXP2000_IRQ_THD_ENABLE_SET_A_1 IXP2000_INTCTL_REG(0x164)
+#define IXP2000_IRQ_THD_ENABLE_SET_A_2 IXP2000_INTCTL_REG(0x168)
+#define IXP2000_IRQ_THD_ENABLE_SET_A_3 IXP2000_INTCTL_REG(0x16c)
+#define IXP2000_IRQ_THD_ENABLE_SET_B_0 IXP2000_INTCTL_REG(0x180)
+#define IXP2000_IRQ_THD_ENABLE_SET_B_1 IXP2000_INTCTL_REG(0x184)
+#define IXP2000_IRQ_THD_ENABLE_SET_B_2 IXP2000_INTCTL_REG(0x188)
+#define IXP2000_IRQ_THD_ENABLE_SET_B_3 IXP2000_INTCTL_REG(0x18c)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_0 IXP2000_INTCTL_REG(0x1e0)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_1 IXP2000_INTCTL_REG(0x1e4)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_2 IXP2000_INTCTL_REG(0x1e8)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_A_3 IXP2000_INTCTL_REG(0x1ec)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_0 IXP2000_INTCTL_REG(0x200)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_1 IXP2000_INTCTL_REG(0x204)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_2 IXP2000_INTCTL_REG(0x208)
+#define IXP2000_IRQ_THD_ENABLE_CLEAR_B_3 IXP2000_INTCTL_REG(0x20c)
+
+/*
+ * Mask of valid IRQs in the 32-bit IRQ register. We use
+ * this to mark certain IRQs as being invalid.
+ */
+#define IXP2000_VALID_IRQ_MASK 0x0f0fffff
+
+/*
+ * PCI config register access from core
+ */
+#define IXP2000_PCI_CREG(x) (volatile unsigned long*)(IXP2000_PCI_CREG_VIRT_BASE | (x))
+#define IXP2000_PCI_CMDSTAT IXP2000_PCI_CREG(0x04)
+#define IXP2000_PCI_CSR_BAR IXP2000_PCI_CREG(0x10)
+#define IXP2000_PCI_SRAM_BAR IXP2000_PCI_CREG(0x14)
+#define IXP2000_PCI_SDRAM_BAR IXP2000_PCI_CREG(0x18)
+
+/*
+ * PCI CSRs
+ */
+#define IXP2000_PCI_CSR(x) (volatile unsigned long*)(IXP2000_PCI_CSR_VIRT_BASE | (x))
+
+/*
+ * PCI outbound interrupts
+ */
+#define IXP2000_PCI_OUT_INT_STATUS IXP2000_PCI_CSR(0x30)
+#define IXP2000_PCI_OUT_INT_MASK IXP2000_PCI_CSR(0x34)
+/*
+ * PCI communications
+ */
+#define IXP2000_PCI_MAILBOX0 IXP2000_PCI_CSR(0x50)
+#define IXP2000_PCI_MAILBOX1 IXP2000_PCI_CSR(0x54)
+#define IXP2000_PCI_MAILBOX2 IXP2000_PCI_CSR(0x58)
+#define IXP2000_PCI_MAILBOX3 IXP2000_PCI_CSR(0x5C)
+#define IXP2000_XSCALE_DOORBELL IXP2000_PCI_CSR(0x60)
+#define IXP2000_XSCALE_DOORBELL_SETUP IXP2000_PCI_CSR(0x64)
+#define IXP2000_PCI_DOORBELL IXP2000_PCI_CSR(0x70)
+#define IXP2000_PCI_DOORBELL_SETUP IXP2000_PCI_CSR(0x74)
+
+/*
+ * DMA engines
+ */
+#define IXP2000_PCI_CH1_BYTE_CNT IXP2000_PCI_CSR(0x80)
+#define IXP2000_PCI_CH1_ADDR IXP2000_PCI_CSR(0x84)
+#define IXP2000_PCI_CH1_DRAM_ADDR IXP2000_PCI_CSR(0x88)
+#define IXP2000_PCI_CH1_DESC_PTR IXP2000_PCI_CSR(0x8C)
+#define IXP2000_PCI_CH1_CNTRL IXP2000_PCI_CSR(0x90)
+#define IXP2000_PCI_CH1_ME_PARAM IXP2000_PCI_CSR(0x94)
+#define IXP2000_PCI_CH2_BYTE_CNT IXP2000_PCI_CSR(0xA0)
+#define IXP2000_PCI_CH2_ADDR IXP2000_PCI_CSR(0xA4)
+#define IXP2000_PCI_CH2_DRAM_ADDR IXP2000_PCI_CSR(0xA8)
+#define IXP2000_PCI_CH2_DESC_PTR IXP2000_PCI_CSR(0xAC)
+#define IXP2000_PCI_CH2_CNTRL IXP2000_PCI_CSR(0xB0)
+#define IXP2000_PCI_CH2_ME_PARAM IXP2000_PCI_CSR(0xB4)
+#define IXP2000_PCI_CH3_BYTE_CNT IXP2000_PCI_CSR(0xC0)
+#define IXP2000_PCI_CH3_ADDR IXP2000_PCI_CSR(0xC4)
+#define IXP2000_PCI_CH3_DRAM_ADDR IXP2000_PCI_CSR(0xC8)
+#define IXP2000_PCI_CH3_DESC_PTR IXP2000_PCI_CSR(0xCC)
+#define IXP2000_PCI_CH3_CNTRL IXP2000_PCI_CSR(0xD0)
+#define IXP2000_PCI_CH3_ME_PARAM IXP2000_PCI_CSR(0xD4)
+#define IXP2000_DMA_INF_MODE IXP2000_PCI_CSR(0xE0)
+/*
+ * Size masks for BARs
+ */
+#define IXP2000_PCI_SRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0xFC)
+#define IXP2000_PCI_DRAM_BASE_ADDR_MASK IXP2000_PCI_CSR(0x100)
+/*
+ * Control and uEngine related
+ */
+#define IXP2000_PCI_CONTROL IXP2000_PCI_CSR(0x13C)
+#define IXP2000_PCI_ADDR_EXT IXP2000_PCI_CSR(0x140)
+#define IXP2000_PCI_ME_PUSH_STATUS IXP2000_PCI_CSR(0x148)
+#define IXP2000_PCI_ME_PUSH_EN IXP2000_PCI_CSR(0x14C)
+#define IXP2000_PCI_ERR_STATUS IXP2000_PCI_CSR(0x150)
+#define IXP2000_PCI_ERR_ENABLE IXP2000_PCI_CSR(0x154)
+/*
+ * Inbound PCI interrupt control
+ */
+#define IXP2000_PCI_XSCALE_INT_STATUS IXP2000_PCI_CSR(0x158)
+#define IXP2000_PCI_XSCALE_INT_ENABLE IXP2000_PCI_CSR(0x15C)
+
+#define IXP2000_PCICNTL_PNR (1<<17) /* PCI not Reset bit of PCI_CONTROL */
+#define IXP2000_PCICNTL_PCF (1<<28) /* PCI Central function bit */
+#define IXP2000_XSCALE_INT (1<<1) /* Interrupt from XScale to PCI */
+
+/* These are from the IRQ register in the PCI ISR register */
+#define PCI_CONTROL_BE_DEO (1 << 22) /* Big Endian Data Enable Out */
+#define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */
+#define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */
+#define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */
+#define PCI_CONTROL_IEE (1 << 17) /* I/O cycle Endian swap Enable */
+
+#define IXP2000_PCI_RST_REL (1 << 2)
+#define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF)
+#define CFG_PCI_BOOT_HOST (1 << 2)
+#define CFG_BOOT_PROM (1 << 1)
+
+/*
+ * SlowPort CSRs
+ *
+ * The slowport is used to access things like flash, SONET framer control
+ * ports, slave microprocessors, CPLDs, and others of chip memory mapped
+ * peripherals.
+ */
+#define SLOWPORT_CSR(x) (volatile unsigned long*)(IXP2000_SLOWPORT_CSR_VIRT_BASE | (x))
+
+#define IXP2000_SLOWPORT_CCR SLOWPORT_CSR(0x00)
+#define IXP2000_SLOWPORT_WTC1 SLOWPORT_CSR(0x04)
+#define IXP2000_SLOWPORT_WTC2 SLOWPORT_CSR(0x08)
+#define IXP2000_SLOWPORT_RTC1 SLOWPORT_CSR(0x0c)
+#define IXP2000_SLOWPORT_RTC2 SLOWPORT_CSR(0x10)
+#define IXP2000_SLOWPORT_FSR SLOWPORT_CSR(0x14)
+#define IXP2000_SLOWPORT_PCR SLOWPORT_CSR(0x18)
+#define IXP2000_SLOWPORT_ADC SLOWPORT_CSR(0x1C)
+#define IXP2000_SLOWPORT_FAC SLOWPORT_CSR(0x20)
+#define IXP2000_SLOWPORT_FRM SLOWPORT_CSR(0x24)
+#define IXP2000_SLOWPORT_FIN SLOWPORT_CSR(0x28)
+
+/*
+ * CCR values.
+ * The CCR configures the clock division for the slowport interface.
+ */
+#define SLOWPORT_CCR_DIV_1 0x00
+#define SLOWPORT_CCR_DIV_2 0x01
+#define SLOWPORT_CCR_DIV_4 0x02
+#define SLOWPORT_CCR_DIV_6 0x03
+#define SLOWPORT_CCR_DIV_8 0x04
+#define SLOWPORT_CCR_DIV_10 0x05
+#define SLOWPORT_CCR_DIV_12 0x06
+#define SLOWPORT_CCR_DIV_14 0x07
+#define SLOWPORT_CCR_DIV_16 0x08
+#define SLOWPORT_CCR_DIV_18 0x09
+#define SLOWPORT_CCR_DIV_20 0x0a
+#define SLOWPORT_CCR_DIV_22 0x0b
+#define SLOWPORT_CCR_DIV_24 0x0c
+#define SLOWPORT_CCR_DIV_26 0x0d
+#define SLOWPORT_CCR_DIV_28 0x0e
+#define SLOWPORT_CCR_DIV_30 0x0f
+
+/*
+ * PCR values. PCR configure the mode of the interface.
+ */
+#define SLOWPORT_MODE_FLASH 0x00
+#define SLOWPORT_MODE_LUCENT 0x01
+#define SLOWPORT_MODE_PMC_SIERRA 0x02
+#define SLOWPORT_MODE_INTEL_UP 0x03
+#define SLOWPORT_MODE_MOTOROLA_UP 0x04
+
+/*
+ * ADC values. Defines data and address bus widths.
+ */
+#define SLOWPORT_ADDR_WIDTH_8 0x00
+#define SLOWPORT_ADDR_WIDTH_16 0x01
+#define SLOWPORT_ADDR_WIDTH_24 0x02
+#define SLOWPORT_ADDR_WIDTH_32 0x03
+#define SLOWPORT_DATA_WIDTH_8 0x00
+#define SLOWPORT_DATA_WIDTH_16 0x10
+#define SLOWPORT_DATA_WIDTH_24 0x20
+#define SLOWPORT_DATA_WIDTH_32 0x30
+
+/*
+ * Masks and shifts for various fields in the WTC and RTC registers.
+ */
+#define SLOWPORT_WRTC_MASK_HD 0x0003
+#define SLOWPORT_WRTC_MASK_PW 0x003c
+#define SLOWPORT_WRTC_MASK_SU 0x03c0
+
+#define SLOWPORT_WRTC_SHIFT_HD 0x00
+#define SLOWPORT_WRTC_SHIFT_SU 0x02
+#define SLOWPORT_WRTC_SHFIT_PW 0x06
+
+
+/*
+ * GPIO registers & GPIO interface.
+ */
+#define IXP2000_GPIO_REG(x) ((volatile unsigned long*)(IXP2000_GPIO_VIRT_BASE+(x)))
+#define IXP2000_GPIO_PLR IXP2000_GPIO_REG(0x00)
+#define IXP2000_GPIO_PDPR IXP2000_GPIO_REG(0x04)
+#define IXP2000_GPIO_PDSR IXP2000_GPIO_REG(0x08)
+#define IXP2000_GPIO_PDCR IXP2000_GPIO_REG(0x0c)
+#define IXP2000_GPIO_POPR IXP2000_GPIO_REG(0x10)
+#define IXP2000_GPIO_POSR IXP2000_GPIO_REG(0x14)
+#define IXP2000_GPIO_POCR IXP2000_GPIO_REG(0x18)
+#define IXP2000_GPIO_REDR IXP2000_GPIO_REG(0x1c)
+#define IXP2000_GPIO_FEDR IXP2000_GPIO_REG(0x20)
+#define IXP2000_GPIO_EDSR IXP2000_GPIO_REG(0x24)
+#define IXP2000_GPIO_LSHR IXP2000_GPIO_REG(0x28)
+#define IXP2000_GPIO_LSLR IXP2000_GPIO_REG(0x2c)
+#define IXP2000_GPIO_LDSR IXP2000_GPIO_REG(0x30)
+#define IXP2000_GPIO_INER IXP2000_GPIO_REG(0x34)
+#define IXP2000_GPIO_INSR IXP2000_GPIO_REG(0x38)
+#define IXP2000_GPIO_INCR IXP2000_GPIO_REG(0x3c)
+#define IXP2000_GPIO_INST IXP2000_GPIO_REG(0x40)
+
+/*
+ * "Global" registers...whatever that's supposed to mean.
+ */
+#define GLOBAL_REG_BASE (IXP2000_GLOBAL_REG_VIRT_BASE + 0x0a00)
+#define GLOBAL_REG(x) (volatile unsigned long*)(GLOBAL_REG_BASE | (x))
+
+#define IXP2000_MAJ_PROD_TYPE_MASK 0x001F0000
+#define IXP2000_MAJ_PROD_TYPE_IXP2000 0x00000000
+#define IXP2000_MIN_PROD_TYPE_MASK 0x0000FF00
+#define IXP2000_MIN_PROD_TYPE_IXP2400 0x00000200
+#define IXP2000_MIN_PROD_TYPE_IXP2850 0x00000100
+#define IXP2000_MIN_PROD_TYPE_IXP2800 0x00000000
+#define IXP2000_MAJ_REV_MASK 0x000000F0
+#define IXP2000_MIN_REV_MASK 0x0000000F
+#define IXP2000_PROD_ID_MASK 0xFFFFFFFF
+
+#define IXP2000_PRODUCT_ID GLOBAL_REG(0x00)
+#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04)
+#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08)
+#define IXP2000_RESET0 GLOBAL_REG(0x0c)
+#define IXP2000_RESET1 GLOBAL_REG(0x10)
+#define IXP2000_CCR GLOBAL_REG(0x14)
+#define IXP2000_STRAP_OPTIONS GLOBAL_REG(0x18)
+
+#define RSTALL (1 << 16)
+#define WDT_RESET_ENABLE 0x01000000
+
+
+/*
+ * MSF registers. The IXP2400 and IXP2800 have somewhat different MSF
+ * units, but the registers that differ between the two don't overlap,
+ * so we can have one register list for both.
+ */
+#define IXP2000_MSF_REG(x) ((volatile unsigned long*)(IXP2000_MSF_VIRT_BASE + (x)))
+#define IXP2000_MSF_RX_CONTROL IXP2000_MSF_REG(0x0000)
+#define IXP2000_MSF_TX_CONTROL IXP2000_MSF_REG(0x0004)
+#define IXP2000_MSF_INTERRUPT_STATUS IXP2000_MSF_REG(0x0008)
+#define IXP2000_MSF_INTERRUPT_ENABLE IXP2000_MSF_REG(0x000c)
+#define IXP2000_MSF_CSIX_TYPE_MAP IXP2000_MSF_REG(0x0010)
+#define IXP2000_MSF_FC_EGRESS_STATUS IXP2000_MSF_REG(0x0014)
+#define IXP2000_MSF_FC_INGRESS_STATUS IXP2000_MSF_REG(0x0018)
+#define IXP2000_MSF_HWM_CONTROL IXP2000_MSF_REG(0x0024)
+#define IXP2000_MSF_FC_STATUS_OVERRIDE IXP2000_MSF_REG(0x0028)
+#define IXP2000_MSF_CLOCK_CONTROL IXP2000_MSF_REG(0x002c)
+#define IXP2000_MSF_RX_PORT_MAP IXP2000_MSF_REG(0x0040)
+#define IXP2000_MSF_RBUF_ELEMENT_DONE IXP2000_MSF_REG(0x0044)
+#define IXP2000_MSF_RX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0048)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_0 IXP2000_MSF_REG(0x0050)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_1 IXP2000_MSF_REG(0x0054)
+#define IXP2000_MSF_RX_THREAD_FREELIST_TIMEOUT_2 IXP2000_MSF_REG(0x0058)
+#define IXP2000_MSF_TX_SEQUENCE_0 IXP2000_MSF_REG(0x0060)
+#define IXP2000_MSF_TX_SEQUENCE_1 IXP2000_MSF_REG(0x0064)
+#define IXP2000_MSF_TX_SEQUENCE_2 IXP2000_MSF_REG(0x0068)
+#define IXP2000_MSF_TX_MPHY_POLL_LIMIT IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_TX_CALENDAR_LENGTH IXP2000_MSF_REG(0x0070)
+#define IXP2000_MSF_RX_UP_CONTROL_0 IXP2000_MSF_REG(0x0080)
+#define IXP2000_MSF_RX_UP_CONTROL_1 IXP2000_MSF_REG(0x0084)
+#define IXP2000_MSF_RX_UP_CONTROL_2 IXP2000_MSF_REG(0x0088)
+#define IXP2000_MSF_RX_UP_CONTROL_3 IXP2000_MSF_REG(0x008c)
+#define IXP2000_MSF_TX_UP_CONTROL_0 IXP2000_MSF_REG(0x0090)
+#define IXP2000_MSF_TX_UP_CONTROL_1 IXP2000_MSF_REG(0x0094)
+#define IXP2000_MSF_TX_UP_CONTROL_2 IXP2000_MSF_REG(0x0098)
+#define IXP2000_MSF_TX_UP_CONTROL_3 IXP2000_MSF_REG(0x009c)
+#define IXP2000_MSF_TRAIN_DATA IXP2000_MSF_REG(0x00a0)
+#define IXP2000_MSF_TRAIN_CALENDAR IXP2000_MSF_REG(0x00a4)
+#define IXP2000_MSF_TRAIN_FLOW_CONTROL IXP2000_MSF_REG(0x00a8)
+#define IXP2000_MSF_TX_CALENDAR_0 IXP2000_MSF_REG(0x1000)
+#define IXP2000_MSF_RX_PORT_CALENDAR_STATUS IXP2000_MSF_REG(0x1400)
+
+
+#endif /* _IXP2000_H_ */
diff --git a/arch/arm/mach-ixp2000/include/mach/memory.h b/arch/arm/mach-ixp2000/include/mach/memory.h
new file mode 100644
index 00000000..5f0c4fd4
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/memory.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/memory.h
+ *
+ * Copyright (c) 2002 Intel Corp.
+ * Copyright (c) 2003-2004 MontaVista Software, 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.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#include <mach/ixp2000-regs.h>
+
+#define IXP2000_PCI_SDRAM_OFFSET (*IXP2000_PCI_SDRAM_BAR & 0xfffffff0)
+
+#define __phys_to_bus(x) ((x) + (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+#define __bus_to_phys(x) ((x) - (IXP2000_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+
+#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
+
+#endif
+
diff --git a/arch/arm/mach-ixp2000/include/mach/platform.h b/arch/arm/mach-ixp2000/include/mach/platform.h
new file mode 100644
index 00000000..42182c79
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/platform.h
@@ -0,0 +1,152 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/platform.h
+ *
+ * Various bits of code used by platform-level code.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long ixp2000_reg_read(volatile void *reg)
+{
+ return *((volatile unsigned long *)reg);
+}
+
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
+
+/*
+ * On the IXP2400, we can't use XCB=000 due to chip bugs. We use
+ * XCB=101 instead, but that makes all I/O accesses bufferable. This
+ * is not a problem in general, but we do have to be slightly more
+ * careful because I/O writes are no longer automatically flushed out
+ * of the write buffer.
+ *
+ * In cases where we want to make sure that a write has been flushed
+ * out of the write buffer before we proceed, for example when masking
+ * a device interrupt before re-enabling IRQs in CPSR, we can use this
+ * function, ixp2000_reg_wrb, which performs a write, a readback, and
+ * issues a dummy instruction dependent on the value of the readback
+ * (mov rX, rX) to make sure that the readback has completed before we
+ * continue.
+ */
+static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
+{
+ unsigned long dummy;
+
+ *((volatile unsigned long *)reg) = val;
+
+ dummy = *((volatile unsigned long *)reg);
+ __asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+/*
+ * Boards may multiplex different devices on the 2nd channel of
+ * the slowport interface that each need different configuration
+ * settings. For example, the IXDP2400 uses channel 2 on the interface
+ * to access the CPLD, the switch fabric card, and the media card. Each
+ * one needs a different mode so drivers must save/restore the mode
+ * before and after each operation.
+ *
+ * acquire_slowport(&your_config);
+ * ...
+ * do slowport operations
+ * ...
+ * release_slowport();
+ *
+ * Note that while you have the slowport, you are holding a spinlock,
+ * so your code should be written as if you explicitly acquired a lock.
+ *
+ * The configuration only affects device 2 on the slowport, so the
+ * MTD map driver does not acquire/release the slowport.
+ */
+struct slowport_cfg {
+ unsigned long CCR; /* Clock divide */
+ unsigned long WTC; /* Write Timing Control */
+ unsigned long RTC; /* Read Timing Control */
+ unsigned long PCR; /* Protocol Control Register */
+ unsigned long ADC; /* Address/Data Width Control */
+};
+
+
+void ixp2000_acquire_slowport(struct slowport_cfg *, struct slowport_cfg *);
+void ixp2000_release_slowport(struct slowport_cfg *);
+
+/*
+ * IXP2400 A0/A1 and IXP2800 A0/A1/A2 have broken slowport that requires
+ * tweaking of addresses in the MTD driver.
+ */
+static inline unsigned ixp2000_has_broken_slowport(void)
+{
+ unsigned long id = *IXP2000_PRODUCT_ID;
+ unsigned long id_prod = id & (IXP2000_MAJ_PROD_TYPE_MASK |
+ IXP2000_MIN_PROD_TYPE_MASK);
+ return (((id_prod ==
+ /* fixed in IXP2400-B0 */
+ (IXP2000_MAJ_PROD_TYPE_IXP2000 |
+ IXP2000_MIN_PROD_TYPE_IXP2400)) &&
+ ((id & IXP2000_MAJ_REV_MASK) == 0)) ||
+ ((id_prod ==
+ /* fixed in IXP2800-B0 */
+ (IXP2000_MAJ_PROD_TYPE_IXP2000 |
+ IXP2000_MIN_PROD_TYPE_IXP2800)) &&
+ ((id & IXP2000_MAJ_REV_MASK) == 0)) ||
+ ((id_prod ==
+ /* fixed in IXP2850-B0 */
+ (IXP2000_MAJ_PROD_TYPE_IXP2000 |
+ IXP2000_MIN_PROD_TYPE_IXP2850)) &&
+ ((id & IXP2000_MAJ_REV_MASK) == 0)));
+}
+
+static inline unsigned int ixp2000_has_flash(void)
+{
+ return ((*IXP2000_STRAP_OPTIONS) & (CFG_BOOT_PROM));
+}
+
+static inline unsigned int ixp2000_is_pcimaster(void)
+{
+ return ((*IXP2000_STRAP_OPTIONS) & (CFG_PCI_BOOT_HOST));
+}
+
+void ixp2000_map_io(void);
+void ixp2000_uart_init(void);
+void ixp2000_init_irq(void);
+void ixp2000_init_time(unsigned long);
+unsigned long ixp2000_gettimeoffset(void);
+
+struct pci_sys_data;
+
+u32 *ixp2000_pci_config_addr(unsigned int bus, unsigned int devfn, int where);
+void ixp2000_pci_preinit(void);
+int ixp2000_pci_setup(int, struct pci_sys_data*);
+struct pci_bus* ixp2000_pci_scan_bus(int, struct pci_sys_data*);
+int ixp2000_pci_read_config(struct pci_bus*, unsigned int, int, int, u32 *);
+int ixp2000_pci_write_config(struct pci_bus*, unsigned int, int, int, u32);
+
+/*
+ * Several of the IXP2000 systems have banked flash so we need to extend the
+ * flash_platform_data structure with some private pointers
+ */
+struct ixp2000_flash_data {
+ struct flash_platform_data *platform_data;
+ int nr_banks;
+ unsigned long (*bank_setup)(unsigned long);
+};
+
+struct ixp2000_i2c_pins {
+ unsigned long sda_pin;
+ unsigned long scl_pin;
+};
+
+
+#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h
new file mode 100644
index 00000000..de370992
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/system.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/system.h
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyricht (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ local_irq_disable();
+
+ /*
+ * Reset flash banking register so that we are pointing at
+ * RedBoot bank.
+ */
+ if (machine_is_ixdp2401()) {
+ ixp2000_reg_write(IXDP2X01_CPLD_FLASH_REG,
+ ((0 >> IXDP2X01_FLASH_WINDOW_BITS)
+ | IXDP2X01_CPLD_FLASH_INTERN));
+ ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0xffffffff);
+ }
+
+ /*
+ * On IXDP2801 we need to write this magic sequence to the CPLD
+ * to cause a complete reset of the CPU and all external devices
+ * and move the flash bank register back to 0.
+ */
+ if (machine_is_ixdp2801() || machine_is_ixdp28x5()) {
+ unsigned long reset_reg = *IXDP2X01_CPLD_RESET_REG;
+
+ reset_reg = 0x55AA0000 | (reset_reg & 0x0000FFFF);
+ ixp2000_reg_write(IXDP2X01_CPLD_RESET_REG, reset_reg);
+ ixp2000_reg_wrb(IXDP2X01_CPLD_RESET_REG, 0x80000000);
+ }
+
+ ixp2000_reg_wrb(IXP2000_RESET0, RSTALL);
+}
diff --git a/arch/arm/mach-ixp2000/include/mach/timex.h b/arch/arm/mach-ixp2000/include/mach/timex.h
new file mode 100644
index 00000000..835e659f
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/timex.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/timex.h
+ *
+ * IXP2000 architecture timex specifications
+ */
+
+
+/*
+ * Default clock is 50MHz APB, but platform code can override this
+ */
+#define CLOCK_TICK_RATE 50000000
+
+
diff --git a/arch/arm/mach-ixp2000/include/mach/uncompress.h b/arch/arm/mach-ixp2000/include/mach/uncompress.h
new file mode 100644
index 00000000..ce363087
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/uncompress.h
+ *
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ * 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/serial_reg.h>
+
+#define UART_BASE 0xc0030000
+
+#define PHYS(x) ((volatile unsigned long *)(UART_BASE + x))
+
+#define UARTDR PHYS(0x00) /* Transmit reg dlab=0 */
+#define UARTDLL PHYS(0x00) /* Divisor Latch reg dlab=1*/
+#define UARTDLM PHYS(0x04) /* Divisor Latch reg dlab=1*/
+#define UARTIER PHYS(0x04) /* Interrupt enable reg */
+#define UARTFCR PHYS(0x08) /* FIFO control reg dlab =0*/
+#define UARTLCR PHYS(0x0c) /* Control reg */
+#define UARTSR PHYS(0x14) /* Status reg */
+
+
+static inline void putc(int c)
+{
+ int j = 0x1000;
+
+ while (--j && !(*UARTSR & UART_LSR_THRE))
+ barrier();
+
+ *UARTDR = c;
+}
+
+static inline void flush(void)
+{
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-ixp2000/include/mach/vmalloc.h b/arch/arm/mach-ixp2000/include/mach/vmalloc.h
new file mode 100644
index 00000000..61c8dae2
--- /dev/null
+++ b/arch/arm/mach-ixp2000/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-ixp2000/include/mach/vmalloc.h
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright 2002 Intel Corp.
+ *
+ * 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.
+ *
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_END 0xfb000000UL
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c
new file mode 100644
index 00000000..dfffc1e8
--- /dev/null
+++ b/arch/arm/mach-ixp2000/ixdp2400.c
@@ -0,0 +1,179 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2400.c
+ *
+ * IXDP2400 platform support
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/arch.h>
+
+/*************************************************************************
+ * IXDP2400 timer tick
+ *************************************************************************/
+static void __init ixdp2400_timer_init(void)
+{
+ int numerator, denominator;
+ int denom_array[] = {2, 4, 8, 16, 1, 2, 4, 8};
+
+ numerator = (*(IXDP2400_CPLD_SYS_CLK_M) & 0xFF) *2;
+ denominator = denom_array[(*(IXDP2400_CPLD_SYS_CLK_N) & 0x7)];
+
+ ixp2000_init_time(((3125000 * numerator) / (denominator)) / 2);
+}
+
+static struct sys_timer ixdp2400_timer = {
+ .init = ixdp2400_timer_init,
+ .offset = ixp2000_gettimeoffset,
+};
+
+/*************************************************************************
+ * IXDP2400 PCI
+ *************************************************************************/
+void __init ixdp2400_pci_preinit(void)
+{
+ ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000);
+ ixp2000_pci_preinit();
+ pcibios_setup("firmware");
+}
+
+int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ sys->mem_offset = 0xe0000000;
+
+ ixp2000_pci_setup(nr, sys);
+
+ return 1;
+}
+
+static int __init ixdp2400_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (ixdp2x00_master_npu()) {
+
+ /*
+ * Root bus devices. Slave NPU is only one with interrupt.
+ * Everything else, we just return -1 b/c nothing else
+ * on the root bus has interrupts.
+ */
+ if(!dev->bus->self) {
+ if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN )
+ return IRQ_IXDP2400_INGRESS_NPU;
+
+ return -1;
+ }
+
+ /*
+ * Bridge behind the PMC slot.
+ * NOTE: Only INTA from the PMC slot is routed. VERY BAD.
+ */
+ if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN &&
+ dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN &&
+ !dev->bus->parent->self->bus->parent)
+ return IRQ_IXDP2400_PMC;
+
+ /*
+ * Device behind the first bridge
+ */
+ if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) {
+ switch(dev->devfn) {
+ case IXDP2400_MASTER_ENET_DEVFN:
+ return IRQ_IXDP2400_ENET;
+
+ case IXDP2400_MEDIA_DEVFN:
+ return IRQ_IXDP2400_MEDIA_PCI;
+
+ case IXDP2400_SWITCH_FABRIC_DEVFN:
+ return IRQ_IXDP2400_SF_PCI;
+
+ case IXDP2X00_PMC_DEVFN:
+ return IRQ_IXDP2400_PMC;
+ }
+ }
+
+ return -1;
+ } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
+}
+
+
+static void ixdp2400_pci_postinit(void)
+{
+ struct pci_dev *dev;
+
+ if (ixdp2x00_master_npu()) {
+ dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ } else {
+ dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+
+ ixdp2x00_slave_pci_postinit();
+ }
+}
+
+static struct hw_pci ixdp2400_pci __initdata = {
+ .nr_controllers = 1,
+ .setup = ixdp2400_pci_setup,
+ .preinit = ixdp2400_pci_preinit,
+ .postinit = ixdp2400_pci_postinit,
+ .scan = ixp2000_pci_scan_bus,
+ .map_irq = ixdp2400_pci_map_irq,
+};
+
+int __init ixdp2400_pci_init(void)
+{
+ if (machine_is_ixdp2400())
+ pci_common_init(&ixdp2400_pci);
+
+ return 0;
+}
+
+subsys_initcall(ixdp2400_pci_init);
+
+void __init ixdp2400_init_irq(void)
+{
+ ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS);
+}
+
+MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x00000100,
+ .map_io = ixdp2x00_map_io,
+ .init_irq = ixdp2400_init_irq,
+ .timer = &ixdp2400_timer,
+ .init_machine = ixdp2x00_init_machine,
+MACHINE_END
+
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c
new file mode 100644
index 00000000..cd4c9bcf
--- /dev/null
+++ b/arch/arm/mach-ixp2000/ixdp2800.c
@@ -0,0 +1,294 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2800.c
+ *
+ * IXDP2800 platform support
+ *
+ * Original Author: Jeffrey Daly <jeffrey.daly@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/arch.h>
+
+/*************************************************************************
+ * IXDP2800 timer tick
+ *************************************************************************/
+
+static void __init ixdp2800_timer_init(void)
+{
+ ixp2000_init_time(50000000);
+}
+
+static struct sys_timer ixdp2800_timer = {
+ .init = ixdp2800_timer_init,
+ .offset = ixp2000_gettimeoffset,
+};
+
+/*************************************************************************
+ * IXDP2800 PCI
+ *************************************************************************/
+static void __init ixdp2800_slave_disable_pci_master(void)
+{
+ *IXP2000_PCI_CMDSTAT &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+}
+
+static void __init ixdp2800_master_wait_for_slave(void)
+{
+ volatile u32 *addr;
+
+ printk(KERN_INFO "IXDP2800: waiting for slave NPU to configure "
+ "its BAR sizes\n");
+
+ addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_BASE_ADDRESS_1);
+ do {
+ *addr = 0xffffffff;
+ cpu_relax();
+ } while (*addr != 0xfe000008);
+
+ addr = ixp2000_pci_config_addr(0, IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_BASE_ADDRESS_2);
+ do {
+ *addr = 0xffffffff;
+ cpu_relax();
+ } while (*addr != 0xc0000008);
+
+ /*
+ * Configure the slave's SDRAM BAR by hand.
+ */
+ *addr = 0x40000008;
+}
+
+static void __init ixdp2800_slave_wait_for_master_enable(void)
+{
+ printk(KERN_INFO "IXDP2800: waiting for master NPU to enable us\n");
+
+ while ((*IXP2000_PCI_CMDSTAT & PCI_COMMAND_MASTER) == 0)
+ cpu_relax();
+}
+
+void __init ixdp2800_pci_preinit(void)
+{
+ printk("ixdp2x00_pci_preinit called\n");
+
+ *IXP2000_PCI_ADDR_EXT = 0x0001e000;
+
+ if (!ixdp2x00_master_npu())
+ ixdp2800_slave_disable_pci_master();
+
+ *IXP2000_PCI_SRAM_BASE_ADDR_MASK = (0x2000000 - 1) & ~0x3ffff;
+ *IXP2000_PCI_DRAM_BASE_ADDR_MASK = (0x40000000 - 1) & ~0xfffff;
+
+ ixp2000_pci_preinit();
+
+ if (ixdp2x00_master_npu()) {
+ /*
+ * Wait until the slave set its SRAM/SDRAM BAR sizes
+ * correctly before we proceed to scan and enumerate
+ * the bus.
+ */
+ ixdp2800_master_wait_for_slave();
+
+ /*
+ * We configure the SDRAM BARs by hand because they
+ * are 1G and fall outside of the regular allocated
+ * PCI address space.
+ */
+ *IXP2000_PCI_SDRAM_BAR = 0x00000008;
+ } else {
+ /*
+ * Wait for the master to complete scanning the bus
+ * and assigning resources before we proceed to scan
+ * the bus ourselves. Set pci=firmware to honor the
+ * master's resource assignment.
+ */
+ ixdp2800_slave_wait_for_master_enable();
+ pcibios_setup("firmware");
+ }
+}
+
+/*
+ * We assign the SDRAM BARs for the two IXP2800 CPUs by hand, outside
+ * of the regular PCI window, because there's only 512M of outbound PCI
+ * memory window on each IXP, while we need 1G for each of the BARs.
+ */
+static void __devinit ixp2800_pci_fixup(struct pci_dev *dev)
+{
+ if (machine_is_ixdp2800()) {
+ dev->resource[2].start = 0;
+ dev->resource[2].end = 0;
+ dev->resource[2].flags = 0;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP2800, ixp2800_pci_fixup);
+
+static int __init ixdp2800_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ sys->mem_offset = 0x00000000;
+
+ ixp2000_pci_setup(nr, sys);
+
+ return 1;
+}
+
+static int __init ixdp2800_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (ixdp2x00_master_npu()) {
+
+ /*
+ * Root bus devices. Slave NPU is only one with interrupt.
+ * Everything else, we just return -1 which is invalid.
+ */
+ if(!dev->bus->self) {
+ if(dev->devfn == IXDP2X00_SLAVE_NPU_DEVFN )
+ return IRQ_IXDP2800_INGRESS_NPU;
+
+ return -1;
+ }
+
+ /*
+ * Bridge behind the PMC slot.
+ */
+ if(dev->bus->self->devfn == IXDP2X00_PMC_DEVFN &&
+ dev->bus->parent->self->devfn == IXDP2X00_P2P_DEVFN &&
+ !dev->bus->parent->self->bus->parent)
+ return IRQ_IXDP2800_PMC;
+
+ /*
+ * Device behind the first bridge
+ */
+ if(dev->bus->self->devfn == IXDP2X00_P2P_DEVFN) {
+ switch(dev->devfn) {
+ case IXDP2X00_PMC_DEVFN:
+ return IRQ_IXDP2800_PMC;
+
+ case IXDP2800_MASTER_ENET_DEVFN:
+ return IRQ_IXDP2800_EGRESS_ENET;
+
+ case IXDP2800_SWITCH_FABRIC_DEVFN:
+ return IRQ_IXDP2800_FABRIC;
+ }
+ }
+
+ return -1;
+ } else return IRQ_IXP2000_PCIB; /* Slave NIC interrupt */
+}
+
+static void __init ixdp2800_master_enable_slave(void)
+{
+ volatile u32 *addr;
+
+ printk(KERN_INFO "IXDP2800: enabling slave NPU\n");
+
+ addr = (volatile u32 *)ixp2000_pci_config_addr(0,
+ IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_COMMAND);
+
+ *addr |= PCI_COMMAND_MASTER;
+}
+
+static void __init ixdp2800_master_wait_for_slave_bus_scan(void)
+{
+ volatile u32 *addr;
+
+ printk(KERN_INFO "IXDP2800: waiting for slave to finish bus scan\n");
+
+ addr = (volatile u32 *)ixp2000_pci_config_addr(0,
+ IXDP2X00_SLAVE_NPU_DEVFN,
+ PCI_COMMAND);
+ while ((*addr & PCI_COMMAND_MEMORY) == 0)
+ cpu_relax();
+}
+
+static void __init ixdp2800_slave_signal_bus_scan_completion(void)
+{
+ printk(KERN_INFO "IXDP2800: bus scan done, signaling master\n");
+ *IXP2000_PCI_CMDSTAT |= PCI_COMMAND_MEMORY;
+}
+
+static void __init ixdp2800_pci_postinit(void)
+{
+ if (!ixdp2x00_master_npu()) {
+ ixdp2x00_slave_pci_postinit();
+ ixdp2800_slave_signal_bus_scan_completion();
+ }
+}
+
+struct __initdata hw_pci ixdp2800_pci __initdata = {
+ .nr_controllers = 1,
+ .setup = ixdp2800_pci_setup,
+ .preinit = ixdp2800_pci_preinit,
+ .postinit = ixdp2800_pci_postinit,
+ .scan = ixp2000_pci_scan_bus,
+ .map_irq = ixdp2800_pci_map_irq,
+};
+
+int __init ixdp2800_pci_init(void)
+{
+ if (machine_is_ixdp2800()) {
+ struct pci_dev *dev;
+
+ pci_common_init(&ixdp2800_pci);
+ if (ixdp2x00_master_npu()) {
+ dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+
+ ixdp2800_master_enable_slave();
+ ixdp2800_master_wait_for_slave_bus_scan();
+ } else {
+ dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+ }
+
+ return 0;
+}
+
+subsys_initcall(ixdp2800_pci_init);
+
+void __init ixdp2800_init_irq(void)
+{
+ ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS);
+}
+
+MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x00000100,
+ .map_io = ixdp2x00_map_io,
+ .init_irq = ixdp2800_init_irq,
+ .timer = &ixdp2800_timer,
+ .init_machine = ixdp2x00_init_machine,
+MACHINE_END
+
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
new file mode 100644
index 00000000..235638f8
--- /dev/null
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -0,0 +1,307 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2x00.c
+ *
+ * Code common to IXDP2400 and IXDP2800 platforms.
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/arch.h>
+
+#include <mach/gpio.h>
+
+
+/*************************************************************************
+ * IXDP2x00 IRQ Initialization
+ *************************************************************************/
+static volatile unsigned long *board_irq_mask;
+static volatile unsigned long *board_irq_stat;
+static unsigned long board_irq_count;
+
+#ifdef CONFIG_ARCH_IXDP2400
+/*
+ * Slowport configuration for accessing CPLD registers on IXDP2x00
+ */
+static struct slowport_cfg slowport_cpld_cfg = {
+ .CCR = SLOWPORT_CCR_DIV_2,
+ .WTC = 0x00000070,
+ .RTC = 0x00000070,
+ .PCR = SLOWPORT_MODE_FLASH,
+ .ADC = SLOWPORT_ADDR_WIDTH_24 | SLOWPORT_DATA_WIDTH_8
+};
+#endif
+
+static void ixdp2x00_irq_mask(struct irq_data *d)
+{
+ unsigned long dummy;
+ static struct slowport_cfg old_cfg;
+
+ /*
+ * This is ugly in common code but really don't know
+ * of a better way to handle it. :(
+ */
+#ifdef CONFIG_ARCH_IXDP2400
+ if (machine_is_ixdp2400())
+ ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
+#endif
+
+ dummy = *board_irq_mask;
+ dummy |= IXP2000_BOARD_IRQ_MASK(d->irq);
+ ixp2000_reg_wrb(board_irq_mask, dummy);
+
+#ifdef CONFIG_ARCH_IXDP2400
+ if (machine_is_ixdp2400())
+ ixp2000_release_slowport(&old_cfg);
+#endif
+}
+
+static void ixdp2x00_irq_unmask(struct irq_data *d)
+{
+ unsigned long dummy;
+ static struct slowport_cfg old_cfg;
+
+#ifdef CONFIG_ARCH_IXDP2400
+ if (machine_is_ixdp2400())
+ ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
+#endif
+
+ dummy = *board_irq_mask;
+ dummy &= ~IXP2000_BOARD_IRQ_MASK(d->irq);
+ ixp2000_reg_wrb(board_irq_mask, dummy);
+
+ if (machine_is_ixdp2400())
+ ixp2000_release_slowport(&old_cfg);
+}
+
+static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ volatile u32 ex_interrupt = 0;
+ static struct slowport_cfg old_cfg;
+ int i;
+
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+#ifdef CONFIG_ARCH_IXDP2400
+ if (machine_is_ixdp2400())
+ ixp2000_acquire_slowport(&slowport_cpld_cfg, &old_cfg);
+#endif
+ ex_interrupt = *board_irq_stat & 0xff;
+ if (machine_is_ixdp2400())
+ ixp2000_release_slowport(&old_cfg);
+
+ if(!ex_interrupt) {
+ printk(KERN_ERR "Spurious IXDP2x00 CPLD interrupt!\n");
+ return;
+ }
+
+ for(i = 0; i < board_irq_count; i++) {
+ if(ex_interrupt & (1 << i)) {
+ int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
+ generic_handle_irq(cpld_irq);
+ }
+ }
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+static struct irq_chip ixdp2x00_cpld_irq_chip = {
+ .irq_ack = ixdp2x00_irq_mask,
+ .irq_mask = ixdp2x00_irq_mask,
+ .irq_unmask = ixdp2x00_irq_unmask
+};
+
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
+{
+ unsigned int irq;
+
+ ixp2000_init_irq();
+
+ if (!ixdp2x00_master_npu())
+ return;
+
+ board_irq_stat = stat_reg;
+ board_irq_mask = mask_reg;
+ board_irq_count = nr_of_irqs;
+
+ *board_irq_mask = 0xffffffff;
+
+ for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) {
+ irq_set_chip_and_handler(irq, &ixdp2x00_cpld_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ /* Hook into PCI interrupt */
+ irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
+}
+
+/*************************************************************************
+ * IXDP2x00 memory map
+ *************************************************************************/
+static struct map_desc ixdp2x00_io_desc __initdata = {
+ .virtual = IXDP2X00_VIRT_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X00_PHYS_CPLD_BASE),
+ .length = IXDP2X00_CPLD_SIZE,
+ .type = MT_DEVICE
+};
+
+void __init ixdp2x00_map_io(void)
+{
+ ixp2000_map_io();
+
+ iotable_init(&ixdp2x00_io_desc, 1);
+}
+
+/*************************************************************************
+ * IXDP2x00-common PCI init
+ *
+ * The IXDP2[48]00 has a horrid PCI bus layout. Basically the board
+ * contains two NPUs (ingress and egress) connected over PCI, both running
+ * instances of the kernel. So far so good. Peers on the PCI bus running
+ * Linux is a common design in telecom systems. The problem is that instead
+ * of all the devices being controlled by a single host, different
+ * devices are controlled by different NPUs on the same bus, leading to
+ * multiple hosts on the bus. The exact bus layout looks like:
+ *
+ * Bus 0
+ * Master NPU <-------------------+-------------------> Slave NPU
+ * |
+ * |
+ * P2P
+ * |
+ *
+ * Bus 1 |
+ * <--+------+---------+---------+------+-->
+ * | | | | |
+ * | | | | |
+ * ... Dev PMC Media Eth0 Eth1 ...
+ *
+ * The master controls all but Eth1, which is controlled by the
+ * slave. What this means is that the both the master and the slave
+ * have to scan the bus, but only one of them can enumerate the bus.
+ * In addition, after the bus is scanned, each kernel must remove
+ * the device(s) it does not control from the PCI dev list otherwise
+ * a driver on each NPU will try to manage it and we will have horrible
+ * conflicts. Oh..and the slave NPU needs to see the master NPU
+ * for Intel's drivers to work properly. Closed source drivers...
+ *
+ * The way we deal with this is fairly simple but ugly:
+ *
+ * 1) Let master scan and enumerate the bus completely.
+ * 2) Master deletes Eth1 from device list.
+ * 3) Slave scans bus and then deletes all but Eth1 (Eth0 on slave)
+ * from device list.
+ * 4) Find HW designers and LART them.
+ *
+ * The boards also do not do normal PCI IRQ routing, or any sort of
+ * sensical swizzling, so we just need to check where on the bus a
+ * device sits and figure out to which CPLD pin the interrupt is routed.
+ * See ixdp2[48]00.c files.
+ *
+ *************************************************************************/
+void ixdp2x00_slave_pci_postinit(void)
+{
+ struct pci_dev *dev;
+
+ /*
+ * Remove PMC device is there is one
+ */
+ if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) {
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+
+ dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN);
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+}
+
+/**************************************************************************
+ * IXDP2x00 Machine Setup
+ *************************************************************************/
+static struct flash_platform_data ixdp2x00_platform_data = {
+ .map_name = "cfi_probe",
+ .width = 1,
+};
+
+static struct ixp2000_flash_data ixdp2x00_flash_data = {
+ .platform_data = &ixdp2x00_platform_data,
+ .nr_banks = 1
+};
+
+static struct resource ixdp2x00_flash_resource = {
+ .start = 0xc4000000,
+ .end = 0xc4000000 + 0x00ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp2x00_flash = {
+ .name = "IXP2000-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp2x00_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ixdp2x00_flash_resource,
+};
+
+static struct ixp2000_i2c_pins ixdp2x00_i2c_gpio_pins = {
+ .sda_pin = IXDP2X00_GPIO_SDA,
+ .scl_pin = IXDP2X00_GPIO_SCL,
+};
+
+static struct platform_device ixdp2x00_i2c_controller = {
+ .name = "IXP2000-I2C",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp2x00_i2c_gpio_pins,
+ },
+ .num_resources = 0
+};
+
+static struct platform_device *ixdp2x00_devices[] __initdata = {
+ &ixdp2x00_flash,
+ &ixdp2x00_i2c_controller
+};
+
+void __init ixdp2x00_init_machine(void)
+{
+ gpio_line_set(IXDP2X00_GPIO_I2C_ENABLE, 1);
+ gpio_line_config(IXDP2X00_GPIO_I2C_ENABLE, GPIO_OUT);
+
+ platform_add_devices(ixdp2x00_devices, ARRAY_SIZE(ixdp2x00_devices));
+ ixp2000_uart_init();
+}
+
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
new file mode 100644
index 00000000..84835b20
--- /dev/null
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -0,0 +1,451 @@
+/*
+ * arch/arm/mach-ixp2000/ixdp2x01.c
+ *
+ * Code common to Intel IXDP2401 and IXDP2801 platforms
+ *
+ * Original Author: Andrzej Mialkowski <andrzej.mialkowski@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002-2003 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+/*************************************************************************
+ * IXDP2x01 IRQ Handling
+ *************************************************************************/
+static void ixdp2x01_irq_mask(struct irq_data *d)
+{
+ ixp2000_reg_wrb(IXDP2X01_INT_MASK_SET_REG,
+ IXP2000_BOARD_IRQ_MASK(d->irq));
+}
+
+static void ixdp2x01_irq_unmask(struct irq_data *d)
+{
+ ixp2000_reg_write(IXDP2X01_INT_MASK_CLR_REG,
+ IXP2000_BOARD_IRQ_MASK(d->irq));
+}
+
+static u32 valid_irq_mask;
+
+static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u32 ex_interrupt;
+ int i;
+
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+ ex_interrupt = *IXDP2X01_INT_STAT_REG & valid_irq_mask;
+
+ if (!ex_interrupt) {
+ printk(KERN_ERR "Spurious IXDP2X01 CPLD interrupt!\n");
+ return;
+ }
+
+ for (i = 0; i < IXP2000_BOARD_IRQS; i++) {
+ if (ex_interrupt & (1 << i)) {
+ int cpld_irq = IXP2000_BOARD_IRQ(0) + i;
+ generic_handle_irq(cpld_irq);
+ }
+ }
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+static struct irq_chip ixdp2x01_irq_chip = {
+ .irq_mask = ixdp2x01_irq_mask,
+ .irq_ack = ixdp2x01_irq_mask,
+ .irq_unmask = ixdp2x01_irq_unmask
+};
+
+/*
+ * We only do anything if we are the master NPU on the board.
+ * The slave NPU only has the ethernet chip going directly to
+ * the PCIB interrupt input.
+ */
+void __init ixdp2x01_init_irq(void)
+{
+ int irq = 0;
+
+ /* initialize chip specific interrupts */
+ ixp2000_init_irq();
+
+ if (machine_is_ixdp2401())
+ valid_irq_mask = IXDP2401_VALID_IRQ_MASK;
+ else
+ valid_irq_mask = IXDP2801_VALID_IRQ_MASK;
+
+ /* Mask all interrupts from CPLD, disable simulation */
+ ixp2000_reg_write(IXDP2X01_INT_MASK_SET_REG, 0xffffffff);
+ ixp2000_reg_wrb(IXDP2X01_INT_SIM_REG, 0);
+
+ for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
+ if (irq & valid_irq_mask) {
+ irq_set_chip_and_handler(irq, &ixdp2x01_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ } else {
+ set_irq_flags(irq, 0);
+ }
+ }
+
+ /* Hook into PCI interrupts */
+ irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
+}
+
+
+/*************************************************************************
+ * IXDP2x01 memory map
+ *************************************************************************/
+static struct map_desc ixdp2x01_io_desc __initdata = {
+ .virtual = IXDP2X01_VIRT_CPLD_BASE,
+ .pfn = __phys_to_pfn(IXDP2X01_PHYS_CPLD_BASE),
+ .length = IXDP2X01_CPLD_REGION_SIZE,
+ .type = MT_DEVICE
+};
+
+static void __init ixdp2x01_map_io(void)
+{
+ ixp2000_map_io();
+ iotable_init(&ixdp2x01_io_desc, 1);
+}
+
+
+/*************************************************************************
+ * IXDP2x01 serial ports
+ *************************************************************************/
+static struct plat_serial8250_port ixdp2x01_serial_port1[] = {
+ {
+ .mapbase = (unsigned long)IXDP2X01_UART1_PHYS_BASE,
+ .membase = (char *)IXDP2X01_UART1_VIRT_BASE,
+ .irq = IRQ_IXDP2X01_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ .uartclk = IXDP2X01_UART_CLK,
+ },
+ { }
+};
+
+static struct resource ixdp2x01_uart_resource1 = {
+ .start = IXDP2X01_UART1_PHYS_BASE,
+ .end = IXDP2X01_UART1_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp2x01_serial_device1 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = ixdp2x01_serial_port1,
+ },
+ .num_resources = 1,
+ .resource = &ixdp2x01_uart_resource1,
+};
+
+static struct plat_serial8250_port ixdp2x01_serial_port2[] = {
+ {
+ .mapbase = (unsigned long)IXDP2X01_UART2_PHYS_BASE,
+ .membase = (char *)IXDP2X01_UART2_VIRT_BASE,
+ .irq = IRQ_IXDP2X01_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ .uartclk = IXDP2X01_UART_CLK,
+ },
+ { }
+};
+
+static struct resource ixdp2x01_uart_resource2 = {
+ .start = IXDP2X01_UART2_PHYS_BASE,
+ .end = IXDP2X01_UART2_PHYS_BASE + 0xffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp2x01_serial_device2 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = ixdp2x01_serial_port2,
+ },
+ .num_resources = 1,
+ .resource = &ixdp2x01_uart_resource2,
+};
+
+static void ixdp2x01_uart_init(void)
+{
+ platform_device_register(&ixdp2x01_serial_device1);
+ platform_device_register(&ixdp2x01_serial_device2);
+}
+
+
+/*************************************************************************
+ * IXDP2x01 timer tick configuration
+ *************************************************************************/
+static unsigned int ixdp2x01_clock;
+
+static int __init ixdp2x01_clock_setup(char *str)
+{
+ ixdp2x01_clock = simple_strtoul(str, NULL, 10);
+
+ return 1;
+}
+
+__setup("ixdp2x01_clock=", ixdp2x01_clock_setup);
+
+static void __init ixdp2x01_timer_init(void)
+{
+ if (!ixdp2x01_clock)
+ ixdp2x01_clock = 50000000;
+
+ ixp2000_init_time(ixdp2x01_clock);
+}
+
+static struct sys_timer ixdp2x01_timer = {
+ .init = ixdp2x01_timer_init,
+ .offset = ixp2000_gettimeoffset,
+};
+
+/*************************************************************************
+ * IXDP2x01 PCI
+ *************************************************************************/
+void __init ixdp2x01_pci_preinit(void)
+{
+ ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000);
+ ixp2000_pci_preinit();
+ pcibios_setup("firmware");
+}
+
+#define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
+
+static int __init ixdp2x01_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u8 bus = dev->bus->number;
+ u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin);
+ struct pci_bus *tmp_bus = dev->bus;
+
+ /* Primary bus, no interrupts here */
+ if (bus == 0) {
+ return -1;
+ }
+
+ /* Lookup first leaf in bus tree */
+ while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL)) {
+ tmp_bus = tmp_bus->parent;
+ }
+
+ /* Select between known bridges */
+ switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) {
+ /* Device is located after first MB bridge */
+ case 0x0008:
+ if (tmp_bus == dev->bus) {
+ /* Device is located directly after first MB bridge */
+ switch (devpin) {
+ case DEVPIN(1, 1): /* Onboard 82546 ch 0 */
+ if (machine_is_ixdp2401())
+ return IRQ_IXDP2401_INTA_82546;
+ return -1;
+ case DEVPIN(1, 2): /* Onboard 82546 ch 1 */
+ if (machine_is_ixdp2401())
+ return IRQ_IXDP2401_INTB_82546;
+ return -1;
+ case DEVPIN(0, 1): /* PMC INTA# */
+ return IRQ_IXDP2X01_SPCI_PMC_INTA;
+ case DEVPIN(0, 2): /* PMC INTB# */
+ return IRQ_IXDP2X01_SPCI_PMC_INTB;
+ case DEVPIN(0, 3): /* PMC INTC# */
+ return IRQ_IXDP2X01_SPCI_PMC_INTC;
+ case DEVPIN(0, 4): /* PMC INTD# */
+ return IRQ_IXDP2X01_SPCI_PMC_INTD;
+ }
+ }
+ break;
+ case 0x0010:
+ if (tmp_bus == dev->bus) {
+ /* Device is located directly after second MB bridge */
+ /* Secondary bus of second bridge */
+ switch (devpin) {
+ case DEVPIN(0, 1): /* DB#0 */
+ return IRQ_IXDP2X01_SPCI_DB_0;
+ case DEVPIN(1, 1): /* DB#1 */
+ return IRQ_IXDP2X01_SPCI_DB_1;
+ }
+ } else {
+ /* Device is located indirectly after second MB bridge */
+ /* Not supported now */
+ }
+ break;
+ }
+
+ return -1;
+}
+
+
+static int ixdp2x01_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ sys->mem_offset = 0xe0000000;
+
+ if (machine_is_ixdp2801() || machine_is_ixdp28x5())
+ sys->mem_offset -= ((*IXP2000_PCI_ADDR_EXT & 0xE000) << 16);
+
+ return ixp2000_pci_setup(nr, sys);
+}
+
+struct hw_pci ixdp2x01_pci __initdata = {
+ .nr_controllers = 1,
+ .setup = ixdp2x01_pci_setup,
+ .preinit = ixdp2x01_pci_preinit,
+ .scan = ixp2000_pci_scan_bus,
+ .map_irq = ixdp2x01_pci_map_irq,
+};
+
+int __init ixdp2x01_pci_init(void)
+{
+ if (machine_is_ixdp2401() || machine_is_ixdp2801() ||\
+ machine_is_ixdp28x5())
+ pci_common_init(&ixdp2x01_pci);
+
+ return 0;
+}
+
+subsys_initcall(ixdp2x01_pci_init);
+
+/*************************************************************************
+ * IXDP2x01 Machine Initialization
+ *************************************************************************/
+static struct flash_platform_data ixdp2x01_flash_platform_data = {
+ .map_name = "cfi_probe",
+ .width = 1,
+};
+
+static unsigned long ixdp2x01_flash_bank_setup(unsigned long ofs)
+{
+ ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
+ ((ofs >> IXDP2X01_FLASH_WINDOW_BITS) | IXDP2X01_CPLD_FLASH_INTERN));
+ return (ofs & IXDP2X01_FLASH_WINDOW_MASK);
+}
+
+static struct ixp2000_flash_data ixdp2x01_flash_data = {
+ .platform_data = &ixdp2x01_flash_platform_data,
+ .bank_setup = ixdp2x01_flash_bank_setup
+};
+
+static struct resource ixdp2x01_flash_resource = {
+ .start = 0xc4000000,
+ .end = 0xc4000000 + 0x01ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp2x01_flash = {
+ .name = "IXP2000-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp2x01_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ixdp2x01_flash_resource,
+};
+
+static struct ixp2000_i2c_pins ixdp2x01_i2c_gpio_pins = {
+ .sda_pin = IXDP2X01_GPIO_SDA,
+ .scl_pin = IXDP2X01_GPIO_SCL,
+};
+
+static struct platform_device ixdp2x01_i2c_controller = {
+ .name = "IXP2000-I2C",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp2x01_i2c_gpio_pins,
+ },
+ .num_resources = 0
+};
+
+static struct platform_device *ixdp2x01_devices[] __initdata = {
+ &ixdp2x01_flash,
+ &ixdp2x01_i2c_controller
+};
+
+static void __init ixdp2x01_init_machine(void)
+{
+ ixp2000_reg_wrb(IXDP2X01_CPLD_FLASH_REG,
+ (IXDP2X01_CPLD_FLASH_BANK_MASK | IXDP2X01_CPLD_FLASH_INTERN));
+
+ ixdp2x01_flash_data.nr_banks =
+ ((*IXDP2X01_CPLD_FLASH_REG & IXDP2X01_CPLD_FLASH_BANK_MASK) + 1);
+
+ platform_add_devices(ixdp2x01_devices, ARRAY_SIZE(ixdp2x01_devices));
+ ixp2000_uart_init();
+ ixdp2x01_uart_init();
+}
+
+
+#ifdef CONFIG_ARCH_IXDP2401
+MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x00000100,
+ .map_io = ixdp2x01_map_io,
+ .init_irq = ixdp2x01_init_irq,
+ .timer = &ixdp2x01_timer,
+ .init_machine = ixdp2x01_init_machine,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_IXDP2801
+MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x00000100,
+ .map_io = ixdp2x01_map_io,
+ .init_irq = ixdp2x01_init_irq,
+ .timer = &ixdp2x01_timer,
+ .init_machine = ixdp2x01_init_machine,
+MACHINE_END
+
+/*
+ * IXDP28x5 is basically an IXDP2801 with a different CPU but Intel
+ * changed the machine ID in the bootloader
+ */
+MACHINE_START(IXDP28X5, "Intel IXDP2805/2855 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x00000100,
+ .map_io = ixdp2x01_map_io,
+ .init_irq = ixdp2x01_init_irq,
+ .timer = &ixdp2x01_timer,
+ .init_machine = ixdp2x01_init_machine,
+MACHINE_END
+#endif
+
+
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
new file mode 100644
index 00000000..f797c5f5
--- /dev/null
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -0,0 +1,246 @@
+/*
+ * arch/arm/mach-ixp2000/pci.c
+ *
+ * PCI routines for IXDP2400/IXDP2800 boards
+ *
+ * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Maintained by: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2002 Intel Corp.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+
+#include <asm/mach/pci.h>
+
+static volatile int pci_master_aborts = 0;
+
+static int clear_master_aborts(void);
+
+u32 *
+ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
+{
+ u32 *paddress;
+
+ if (PCI_SLOT(devfn) > 7)
+ return 0;
+
+ /* Must be dword aligned */
+ where &= ~3;
+
+ /*
+ * For top bus, generate type 0, else type 1
+ */
+ if (!bus_nr) {
+ /* only bits[23:16] are used for IDSEL */
+ paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE
+ | (1 << (PCI_SLOT(devfn) + 16))
+ | (PCI_FUNC(devfn) << 8) | where);
+ } else {
+ paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE
+ | (bus_nr << 16)
+ | (PCI_SLOT(devfn) << 11)
+ | (PCI_FUNC(devfn) << 8) | where);
+ }
+
+ return paddress;
+}
+
+/*
+ * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
+ * 0 and 3 are not valid indexes...
+ */
+static u32 bytemask[] = {
+ /*0*/ 0,
+ /*1*/ 0xff,
+ /*2*/ 0xffff,
+ /*3*/ 0,
+ /*4*/ 0xffffffff,
+};
+
+
+int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ u32 n;
+ u32 *addr;
+
+ n = where % 4;
+
+ addr = ixp2000_pci_config_addr(bus->number, devfn, where);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ pci_master_aborts = 0;
+ *value = (*addr >> (8*n)) & bytemask[size];
+ if (pci_master_aborts) {
+ pci_master_aborts = 0;
+ *value = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checks by calling clear_master_aborts() b/c the
+ * assumption is that the caller did a read first to make sure a device
+ * exists.
+ */
+int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ u32 mask;
+ u32 *addr;
+ u32 temp;
+
+ mask = ~(bytemask[size] << ((where % 0x4) * 8));
+ addr = ixp2000_pci_config_addr(bus->number, devfn, where);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ temp = (u32) (value) << ((where % 0x4) * 8);
+ *addr = (*addr & mask) | temp;
+
+ clear_master_aborts();
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static struct pci_ops ixp2000_pci_ops = {
+ .read = ixp2000_pci_read_config,
+ .write = ixp2000_pci_write_config
+};
+
+struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
+{
+ return pci_scan_bus(sysdata->busnr, &ixp2000_pci_ops, sysdata);
+}
+
+
+int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+
+ volatile u32 temp;
+ unsigned long flags;
+
+ pci_master_aborts = 1;
+
+ local_irq_save(flags);
+ temp = *(IXP2000_PCI_CONTROL);
+ if (temp & ((1 << 8) | (1 << 5))) {
+ ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
+ }
+
+ temp = *(IXP2000_PCI_CMDSTAT);
+ if (temp & (1 << 29)) {
+ while (temp & (1 << 29)) {
+ ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
+ temp = *(IXP2000_PCI_CMDSTAT);
+ }
+ }
+ local_irq_restore(flags);
+
+ /*
+ * If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+
+ return 0;
+}
+
+int
+clear_master_aborts(void)
+{
+ volatile u32 temp;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ temp = *(IXP2000_PCI_CONTROL);
+ if (temp & ((1 << 8) | (1 << 5))) {
+ ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
+ }
+
+ temp = *(IXP2000_PCI_CMDSTAT);
+ if (temp & (1 << 29)) {
+ while (temp & (1 << 29)) {
+ ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
+ temp = *(IXP2000_PCI_CMDSTAT);
+ }
+ }
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+void __init
+ixp2000_pci_preinit(void)
+{
+#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
+ /*
+ * Configure the PCI unit to properly byteswap I/O transactions,
+ * and verify that it worked.
+ */
+ ixp2000_reg_write(IXP2000_PCI_CONTROL,
+ (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));
+
+ if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
+ panic("IXP2000: PCI I/O is broken on this ixp model, and "
+ "the needed workaround has not been configured in");
+#endif
+
+ hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0,
+ "PCI config cycle to non-existent device");
+}
+
+
+/*
+ * IXP2000 systems often have large resource requirements, so we just
+ * use our own resource space.
+ */
+static struct resource ixp2000_pci_mem_space = {
+ .start = 0xe0000000,
+ .end = 0xffffffff,
+ .flags = IORESOURCE_MEM,
+ .name = "PCI Mem Space"
+};
+
+static struct resource ixp2000_pci_io_space = {
+ .start = 0x00010000,
+ .end = 0x0001ffff,
+ .flags = IORESOURCE_IO,
+ .name = "PCI I/O Space"
+};
+
+int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ if (nr >= 1)
+ return 0;
+
+ sys->resource[0] = &ixp2000_pci_io_space;
+ sys->resource[1] = &ixp2000_pci_mem_space;
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
diff --git a/arch/arm/mach-ixp23xx/Kconfig b/arch/arm/mach-ixp23xx/Kconfig
new file mode 100644
index 00000000..982670ec
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Kconfig
@@ -0,0 +1,25 @@
+if ARCH_IXP23XX
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+ bool
+ default y
+
+menu "Intel IXP23xx Implementation Options"
+
+comment "IXP23xx Platforms"
+
+config MACH_ESPRESSO
+ bool "Support IP Fabrics Double Espresso platform"
+ help
+
+config MACH_IXDP2351
+ bool "Support Intel IXDP2351 platform"
+ help
+
+config MACH_ROADRUNNER
+ bool "Support ADI RoadRunner platform"
+ help
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ixp23xx/Makefile b/arch/arm/mach-ixp23xx/Makefile
new file mode 100644
index 00000000..288b371b
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+obj-y := core.o pci.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_MACH_ESPRESSO) += espresso.o
+obj-$(CONFIG_MACH_IXDP2351) += ixdp2351.o
+obj-$(CONFIG_MACH_ROADRUNNER) += roadrunner.o
diff --git a/arch/arm/mach-ixp23xx/Makefile.boot b/arch/arm/mach-ixp23xx/Makefile.boot
new file mode 100644
index 00000000..d5561ad1
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
new file mode 100644
index 00000000..a1bee33d
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -0,0 +1,446 @@
+/*
+ * arch/arm/mach-ixp23xx/core.c
+ *
+ * Core routines for IXP23xx chips
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2004 (c) Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+
+
+/*************************************************************************
+ * Chip specific mappings shared by all IXP23xx systems
+ *************************************************************************/
+static struct map_desc ixp23xx_io_desc[] __initdata = {
+ { /* XSI-CPP CSRs */
+ .virtual = IXP23XX_XSI2CPP_CSR_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_XSI2CPP_CSR_PHYS),
+ .length = IXP23XX_XSI2CPP_CSR_SIZE,
+ .type = MT_DEVICE,
+ }, { /* Expansion Bus Config */
+ .virtual = IXP23XX_EXP_CFG_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_EXP_CFG_PHYS),
+ .length = IXP23XX_EXP_CFG_SIZE,
+ .type = MT_DEVICE,
+ }, { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACS,.... */
+ .virtual = IXP23XX_PERIPHERAL_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_PERIPHERAL_PHYS),
+ .length = IXP23XX_PERIPHERAL_SIZE,
+ .type = MT_DEVICE,
+ }, { /* CAP CSRs */
+ .virtual = IXP23XX_CAP_CSR_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_CAP_CSR_PHYS),
+ .length = IXP23XX_CAP_CSR_SIZE,
+ .type = MT_DEVICE,
+ }, { /* MSF CSRs */
+ .virtual = IXP23XX_MSF_CSR_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_MSF_CSR_PHYS),
+ .length = IXP23XX_MSF_CSR_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCI I/O Space */
+ .virtual = IXP23XX_PCI_IO_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_PCI_IO_PHYS),
+ .length = IXP23XX_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCI Config Space */
+ .virtual = IXP23XX_PCI_CFG_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_PCI_CFG_PHYS),
+ .length = IXP23XX_PCI_CFG_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCI local CFG CSRs */
+ .virtual = IXP23XX_PCI_CREG_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_PCI_CREG_PHYS),
+ .length = IXP23XX_PCI_CREG_SIZE,
+ .type = MT_DEVICE,
+ }, { /* PCI MEM Space */
+ .virtual = IXP23XX_PCI_MEM_VIRT,
+ .pfn = __phys_to_pfn(IXP23XX_PCI_MEM_PHYS),
+ .length = IXP23XX_PCI_MEM_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+void __init ixp23xx_map_io(void)
+{
+ iotable_init(ixp23xx_io_desc, ARRAY_SIZE(ixp23xx_io_desc));
+}
+
+
+/***************************************************************************
+ * IXP23xx Interrupt Handling
+ ***************************************************************************/
+enum ixp23xx_irq_type {
+ IXP23XX_IRQ_LEVEL, IXP23XX_IRQ_EDGE
+};
+
+static void ixp23xx_config_irq(unsigned int, enum ixp23xx_irq_type);
+
+static int ixp23xx_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ int line = d->irq - IRQ_IXP23XX_GPIO6 + 6;
+ u32 int_style;
+ enum ixp23xx_irq_type irq_type;
+ volatile u32 *int_reg;
+
+ /*
+ * Only GPIOs 6-15 are wired to interrupts on IXP23xx
+ */
+ if (line < 6 || line > 15)
+ return -EINVAL;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_BOTH:
+ int_style = IXP23XX_GPIO_STYLE_TRANSITIONAL;
+ irq_type = IXP23XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ int_style = IXP23XX_GPIO_STYLE_RISING_EDGE;
+ irq_type = IXP23XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ int_style = IXP23XX_GPIO_STYLE_FALLING_EDGE;
+ irq_type = IXP23XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ int_style = IXP23XX_GPIO_STYLE_ACTIVE_HIGH;
+ irq_type = IXP23XX_IRQ_LEVEL;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ int_style = IXP23XX_GPIO_STYLE_ACTIVE_LOW;
+ irq_type = IXP23XX_IRQ_LEVEL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ixp23xx_config_irq(d->irq, irq_type);
+
+ if (line >= 8) { /* pins 8-15 */
+ line -= 8;
+ int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT2R;
+ } else { /* pins 0-7 */
+ int_reg = (volatile u32 *)IXP23XX_GPIO_GPIT1R;
+ }
+
+ /*
+ * Clear pending interrupts
+ */
+ *IXP23XX_GPIO_GPISR = (1 << line);
+
+ /* Clear the style for the appropriate pin */
+ *int_reg &= ~(IXP23XX_GPIO_STYLE_MASK <<
+ (line * IXP23XX_GPIO_STYLE_SIZE));
+
+ /* Set the new style */
+ *int_reg |= (int_style << (line * IXP23XX_GPIO_STYLE_SIZE));
+
+ return 0;
+}
+
+static void ixp23xx_irq_mask(struct irq_data *d)
+{
+ volatile unsigned long *intr_reg;
+ unsigned int irq = d->irq;
+
+ if (irq >= 56)
+ irq += 8;
+
+ intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+ *intr_reg &= ~(1 << (irq % 32));
+}
+
+static void ixp23xx_irq_ack(struct irq_data *d)
+{
+ int line = d->irq - IRQ_IXP23XX_GPIO6 + 6;
+
+ if ((line < 6) || (line > 15))
+ return;
+
+ *IXP23XX_GPIO_GPISR = (1 << line);
+}
+
+/*
+ * Level triggered interrupts on GPIO lines can only be cleared when the
+ * interrupt condition disappears.
+ */
+static void ixp23xx_irq_level_unmask(struct irq_data *d)
+{
+ volatile unsigned long *intr_reg;
+ unsigned int irq = d->irq;
+
+ ixp23xx_irq_ack(d);
+
+ if (irq >= 56)
+ irq += 8;
+
+ intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+ *intr_reg |= (1 << (irq % 32));
+}
+
+static void ixp23xx_irq_edge_unmask(struct irq_data *d)
+{
+ volatile unsigned long *intr_reg;
+ unsigned int irq = d->irq;
+
+ if (irq >= 56)
+ irq += 8;
+
+ intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+ *intr_reg |= (1 << (irq % 32));
+}
+
+static struct irq_chip ixp23xx_irq_level_chip = {
+ .irq_ack = ixp23xx_irq_mask,
+ .irq_mask = ixp23xx_irq_mask,
+ .irq_unmask = ixp23xx_irq_level_unmask,
+ .irq_set_type = ixp23xx_irq_set_type
+};
+
+static struct irq_chip ixp23xx_irq_edge_chip = {
+ .irq_ack = ixp23xx_irq_ack,
+ .irq_mask = ixp23xx_irq_mask,
+ .irq_unmask = ixp23xx_irq_edge_unmask,
+ .irq_set_type = ixp23xx_irq_set_type
+};
+
+static void ixp23xx_pci_irq_mask(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ *IXP23XX_PCI_XSCALE_INT_ENABLE &= ~(1 << (IRQ_IXP23XX_INTA + 27 - irq));
+}
+
+static void ixp23xx_pci_irq_unmask(struct irq_data *d)
+{
+ unsigned int irq = d->irq;
+
+ *IXP23XX_PCI_XSCALE_INT_ENABLE |= (1 << (IRQ_IXP23XX_INTA + 27 - irq));
+}
+
+/*
+ * TODO: Should this just be done at ASM level?
+ */
+static void pci_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u32 pci_interrupt;
+ unsigned int irqno;
+
+ pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS;
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ /* See which PCI_INTA, or PCI_INTB interrupted */
+ if (pci_interrupt & (1 << 26)) {
+ irqno = IRQ_IXP23XX_INTB;
+ } else if (pci_interrupt & (1 << 27)) {
+ irqno = IRQ_IXP23XX_INTA;
+ } else {
+ BUG();
+ }
+
+ generic_handle_irq(irqno);
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+static struct irq_chip ixp23xx_pci_irq_chip = {
+ .irq_ack = ixp23xx_pci_irq_mask,
+ .irq_mask = ixp23xx_pci_irq_mask,
+ .irq_unmask = ixp23xx_pci_irq_unmask
+};
+
+static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type)
+{
+ switch (type) {
+ case IXP23XX_IRQ_LEVEL:
+ irq_set_chip_and_handler(irq, &ixp23xx_irq_level_chip,
+ handle_level_irq);
+ break;
+ case IXP23XX_IRQ_EDGE:
+ irq_set_chip_and_handler(irq, &ixp23xx_irq_edge_chip,
+ handle_edge_irq);
+ break;
+ }
+ set_irq_flags(irq, IRQF_VALID);
+}
+
+void __init ixp23xx_init_irq(void)
+{
+ int irq;
+
+ /* Route everything to IRQ */
+ *IXP23XX_INTR_SEL1 = 0x0;
+ *IXP23XX_INTR_SEL2 = 0x0;
+ *IXP23XX_INTR_SEL3 = 0x0;
+ *IXP23XX_INTR_SEL4 = 0x0;
+
+ /* Mask all sources */
+ *IXP23XX_INTR_EN1 = 0x0;
+ *IXP23XX_INTR_EN2 = 0x0;
+ *IXP23XX_INTR_EN3 = 0x0;
+ *IXP23XX_INTR_EN4 = 0x0;
+
+ /*
+ * Configure all IRQs for level-sensitive operation
+ */
+ for (irq = 0; irq <= NUM_IXP23XX_RAW_IRQS; irq++) {
+ ixp23xx_config_irq(irq, IXP23XX_IRQ_LEVEL);
+ }
+
+ for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) {
+ irq_set_chip_and_handler(irq, &ixp23xx_pci_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler);
+}
+
+
+/*************************************************************************
+ * Timer-tick functions for IXP23xx
+ *************************************************************************/
+#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC)
+
+static unsigned long next_jiffy_time;
+
+static unsigned long
+ixp23xx_gettimeoffset(void)
+{
+ unsigned long elapsed;
+
+ elapsed = *IXP23XX_TIMER_CONT - (next_jiffy_time - LATCH);
+
+ return elapsed / CLOCK_TICKS_PER_USEC;
+}
+
+static irqreturn_t
+ixp23xx_timer_interrupt(int irq, void *dev_id)
+{
+ /* Clear Pending Interrupt by writing '1' to it */
+ *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
+ while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) {
+ timer_tick();
+ next_jiffy_time += LATCH;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ixp23xx_timer_irq = {
+ .name = "IXP23xx Timer Tick",
+ .handler = ixp23xx_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+};
+
+void __init ixp23xx_init_timer(void)
+{
+ /* Clear Pending Interrupt by writing '1' to it */
+ *IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
+
+ /* Setup the Timer counter value */
+ *IXP23XX_TIMER1_RELOAD =
+ (LATCH & ~IXP23XX_TIMER_RELOAD_MASK) | IXP23XX_TIMER_ENABLE;
+
+ *IXP23XX_TIMER_CONT = 0;
+ next_jiffy_time = LATCH;
+
+ /* Connect the interrupt handler and enable the interrupt */
+ setup_irq(IRQ_IXP23XX_TIMER1, &ixp23xx_timer_irq);
+}
+
+struct sys_timer ixp23xx_timer = {
+ .init = ixp23xx_init_timer,
+ .offset = ixp23xx_gettimeoffset,
+};
+
+
+/*************************************************************************
+ * IXP23xx Platform Initialization
+ *************************************************************************/
+static struct resource ixp23xx_uart_resources[] = {
+ {
+ .start = IXP23XX_UART1_PHYS,
+ .end = IXP23XX_UART1_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = IXP23XX_UART2_PHYS,
+ .end = IXP23XX_UART2_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct plat_serial8250_port ixp23xx_uart_data[] = {
+ {
+ .mapbase = IXP23XX_UART1_PHYS,
+ .membase = (char *)(IXP23XX_UART1_VIRT + 3),
+ .irq = IRQ_IXP23XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP23XX_UART_XTAL,
+ }, {
+ .mapbase = IXP23XX_UART2_PHYS,
+ .membase = (char *)(IXP23XX_UART2_VIRT + 3),
+ .irq = IRQ_IXP23XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP23XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device ixp23xx_uart = {
+ .name = "serial8250",
+ .id = 0,
+ .dev.platform_data = ixp23xx_uart_data,
+ .num_resources = 2,
+ .resource = ixp23xx_uart_resources,
+};
+
+static struct platform_device *ixp23xx_devices[] __initdata = {
+ &ixp23xx_uart,
+};
+
+void __init ixp23xx_sys_init(void)
+{
+ *IXP23XX_EXP_UNIT_FUSE |= 0xf;
+ platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
+}
diff --git a/arch/arm/mach-ixp23xx/espresso.c b/arch/arm/mach-ixp23xx/espresso.c
new file mode 100644
index 00000000..e25e5fe1
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/espresso.c
@@ -0,0 +1,93 @@
+/*
+ * arch/arm/mach-ixp23xx/espresso.c
+ *
+ * Double Espresso-specific routines
+ *
+ * Author: Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+
+static int __init espresso_pci_init(void)
+{
+ if (machine_is_espresso())
+ ixp23xx_pci_slave_init();
+
+ return 0;
+};
+subsys_initcall(espresso_pci_init);
+
+static struct physmap_flash_data espresso_flash_data = {
+ .width = 2,
+};
+
+static struct resource espresso_flash_resource = {
+ .start = 0x90000000,
+ .end = 0x91ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device espresso_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &espresso_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &espresso_flash_resource,
+};
+
+static void __init espresso_init(void)
+{
+ platform_device_register(&espresso_flash);
+
+ /*
+ * Mark flash as writeable.
+ */
+ IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+
+ ixp23xx_sys_init();
+}
+
+MACHINE_START(ESPRESSO, "IP Fabrics Double Espresso")
+ /* Maintainer: Lennert Buytenhek */
+ .map_io = ixp23xx_map_io,
+ .init_irq = ixp23xx_init_irq,
+ .timer = &ixp23xx_timer,
+ .boot_params = 0x00000100,
+ .init_machine = espresso_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp23xx/include/mach/debug-macro.S b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..f7c6eef7
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/debug-macro.S
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <mach/ixp23xx.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =IXP23XX_PERIPHERAL_PHYS @ physical
+ ldr \rv, =IXP23XX_PERIPHERAL_VIRT @ virtual
+#ifdef __ARMEB__
+ orr \rp, \rp, #0x00000003
+ orr \rv, \rv, #0x00000003
+#endif
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-ixp23xx/include/mach/entry-macro.S b/arch/arm/mach-ixp23xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..3f5338a7
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/entry-macro.S
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/entry-macro.S
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, =(IXP23XX_INTC_VIRT + IXP23XX_INTR_IRQ_ENC_ST_OFFSET)
+ ldr \irqnr, [\irqnr] @ get interrupt number
+ cmp \irqnr, #0x0 @ spurious interrupt ?
+ movne \irqnr, \irqnr, lsr #2 @ skip unwanted low order bits
+ subne \irqnr, \irqnr, #1 @ convert to 0 based
+
+#if 0
+ cmp \irqnr, #IRQ_IXP23XX_PCI_INT_RPH
+ bne 1001f
+ mov \irqnr, #IRQ_IXP23XX_INTA
+
+ ldr \irqnr, =0xf5000030
+
+ mov \tmp, #(1<<26)
+ tst \irqnr, \tmp
+ movne \irqnr, #IRQ_IXP23XX_INTB
+
+ mov \tmp, #(1<<27)
+ tst \irqnr, \tmp
+ movne \irqnr, #IRQ_IXP23XX_INTA
+1001:
+#endif
+ .endm
diff --git a/arch/arm/mach-ixp23xx/include/mach/hardware.h b/arch/arm/mach-ixp23xx/include/mach/hardware.h
new file mode 100644
index 00000000..57b508bf
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/hardware.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/hardware.h
+ *
+ * Copyright (C) 2002-2004 Intel Corporation.
+ * Copyricht (C) 2005 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Hardware definitions for IXP23XX based systems
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* PCI IO info */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0xe0000000
+
+#include "ixp23xx.h"
+
+#define pcibios_assign_all_busses() 0
+
+/*
+ * Platform helper functions
+ */
+#include "platform.h"
+
+/*
+ * Platform-specific headers
+ */
+#include "ixdp2351.h"
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/io.h b/arch/arm/mach-ixp23xx/include/mach/io.h
new file mode 100644
index 00000000..a1749d0f
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/io.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/io.h
+ *
+ * Original Author: Naeem M Afzal <naeem.m.afzal@intel.com>
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2003-2005 Intel Corp.
+ * Copyright (C) 2005 MontaVista Software, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(p) ((void __iomem*)((p) + IXP23XX_PCI_IO_VIRT))
+#define __mem_pci(a) (a)
+
+static inline void __iomem *
+ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned int mtype)
+{
+ if (addr >= IXP23XX_PCI_MEM_START &&
+ addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) {
+ if (addr + size > IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE)
+ return NULL;
+
+ return (void __iomem *)
+ ((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT);
+ }
+
+ return __arm_ioremap(addr, size, mtype);
+}
+
+static inline void
+ixp23xx_iounmap(void __iomem *addr)
+{
+ if ((((u32)addr) >= IXP23XX_PCI_MEM_VIRT) &&
+ (((u32)addr) < IXP23XX_PCI_MEM_VIRT + IXP23XX_PCI_MEM_SIZE))
+ return;
+
+ __iounmap(addr);
+}
+
+#define __arch_ioremap ixp23xx_ioremap
+#define __arch_iounmap ixp23xx_iounmap
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/irqs.h b/arch/arm/mach-ixp23xx/include/mach/irqs.h
new file mode 100644
index 00000000..3af33a04
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/irqs.h
@@ -0,0 +1,223 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/irqs.h
+ *
+ * IRQ definitions for IXP23XX based systems
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ *
+ * Copyright (C) 2003-2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NR_IXP23XX_IRQS IRQ_IXP23XX_INTB+1
+#define IRQ_IXP23XX_EXTIRQS NR_IXP23XX_IRQS
+
+
+#define IRQ_IXP23XX_DBG0 0 /* Debug/Execution/MBox */
+#define IRQ_IXP23XX_DBG1 1 /* Debug/Execution/MBox */
+#define IRQ_IXP23XX_NPE_TRG 2 /* npe_trigger */
+#define IRQ_IXP23XX_TIMER1 3 /* Timer[0] */
+#define IRQ_IXP23XX_TIMER2 4 /* Timer[1] */
+#define IRQ_IXP23XX_TIMESTAMP 5 /* Timer[2], Time-stamp */
+#define IRQ_IXP23XX_WDOG 6 /* Time[3], Watchdog Timer */
+#define IRQ_IXP23XX_PCI_DBELL 7 /* PCI Doorbell */
+#define IRQ_IXP23XX_PCI_DMA1 8 /* PCI DMA Channel 1 */
+#define IRQ_IXP23XX_PCI_DMA2 9 /* PCI DMA Channel 2 */
+#define IRQ_IXP23XX_PCI_DMA3 10 /* PCI DMA Channel 3 */
+#define IRQ_IXP23XX_PCI_INT_RPH 11 /* pcxg_pci_int_rph */
+#define IRQ_IXP23XX_CPP_PMU 12 /* xpxg_pm_int_rpl */
+#define IRQ_IXP23XX_SWINT0 13 /* S/W Interrupt0 */
+#define IRQ_IXP23XX_SWINT1 14 /* S/W Interrupt1 */
+#define IRQ_IXP23XX_UART2 15 /* UART1 Interrupt */
+#define IRQ_IXP23XX_UART1 16 /* UART0 Interrupt */
+#define IRQ_IXP23XX_XSI_PMU_ROLLOVER 17 /* AHB Performance M. Unit counter rollover */
+#define IRQ_IXP23XX_XSI_AHB_PM0 18 /* intr_pm_o */
+#define IRQ_IXP23XX_XSI_AHB_ECE0 19 /* intr_ece_o */
+#define IRQ_IXP23XX_XSI_AHB_GASKET 20 /* gas_intr_o */
+#define IRQ_IXP23XX_XSI_CPP 21 /* xsi2cpp_int */
+#define IRQ_IXP23XX_CPP_XSI 22 /* cpp2xsi_int */
+#define IRQ_IXP23XX_ME_ATTN0 23 /* ME_ATTN */
+#define IRQ_IXP23XX_ME_ATTN1 24 /* ME_ATTN */
+#define IRQ_IXP23XX_ME_ATTN2 25 /* ME_ATTN */
+#define IRQ_IXP23XX_ME_ATTN3 26 /* ME_ATTN */
+#define IRQ_IXP23XX_PCI_ERR_RPH 27 /* PCXG_PCI_ERR_RPH */
+#define IRQ_IXP23XX_D0XG_ECC_CORR 28 /* D0XG_DRAM_ECC_CORR */
+#define IRQ_IXP23XX_D0XG_ECC_UNCORR 29 /* D0XG_DRAM_ECC_UNCORR */
+#define IRQ_IXP23XX_SRAM_ERR1 30 /* SRAM1_ERR */
+#define IRQ_IXP23XX_SRAM_ERR0 31 /* SRAM0_ERR */
+#define IRQ_IXP23XX_MEDIA_ERR 32 /* MEDIA_ERR */
+#define IRQ_IXP23XX_STH_DRAM_ECC_MAJ 33 /* STH_DRAM0_ECC_MAJ */
+#define IRQ_IXP23XX_GPIO6 34 /* GPIO0 interrupts */
+#define IRQ_IXP23XX_GPIO7 35 /* GPIO1 interrupts */
+#define IRQ_IXP23XX_GPIO8 36 /* GPIO2 interrupts */
+#define IRQ_IXP23XX_GPIO9 37 /* GPIO3 interrupts */
+#define IRQ_IXP23XX_GPIO10 38 /* GPIO4 interrupts */
+#define IRQ_IXP23XX_GPIO11 39 /* GPIO5 interrupts */
+#define IRQ_IXP23XX_GPIO12 40 /* GPIO6 interrupts */
+#define IRQ_IXP23XX_GPIO13 41 /* GPIO7 interrupts */
+#define IRQ_IXP23XX_GPIO14 42 /* GPIO8 interrupts */
+#define IRQ_IXP23XX_GPIO15 43 /* GPIO9 interrupts */
+#define IRQ_IXP23XX_SHAC_RING0 44 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING1 45 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING2 46 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING3 47 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING4 48 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING5 49 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING6 50 /* SHAC RING Full */
+#define IRQ_IXP23XX_SHAC_RING7 51 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING8 52 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING9 53 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING10 54 /* SHAC Ring Full */
+#define IRQ_IXP23XX_SHAC_RING11 55 /* SHAC Ring Full */
+#define IRQ_IXP23XX_ME_THREAD_A0_ME0 56 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A1_ME0 57 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A2_ME0 58 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A3_ME0 59 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A4_ME0 60 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A5_ME0 61 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A6_ME0 62 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A7_ME0 63 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A8_ME1 64 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A9_ME1 65 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A10_ME1 66 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A11_ME1 67 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A12_ME1 68 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A13_ME1 69 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A14_ME1 70 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A15_ME1 71 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A16_ME2 72 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A17_ME2 73 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A18_ME2 74 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A19_ME2 75 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A20_ME2 76 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A21_ME2 77 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A22_ME2 78 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A23_ME2 79 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A24_ME3 80 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A25_ME3 81 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A26_ME3 82 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A27_ME3 83 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A28_ME3 84 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A29_ME3 85 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A30_ME3 86 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_A31_ME3 87 /* ME_THREAD_A */
+#define IRQ_IXP23XX_ME_THREAD_B0_ME0 88 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B1_ME0 89 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B2_ME0 90 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B3_ME0 91 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B4_ME0 92 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B5_ME0 93 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B6_ME0 94 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B7_ME0 95 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B8_ME1 96 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B9_ME1 97 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B10_ME1 98 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B11_ME1 99 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B12_ME1 100 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B13_ME1 101 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B14_ME1 102 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B15_ME1 103 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B16_ME2 104 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B17_ME2 105 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B18_ME2 106 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B19_ME2 107 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B20_ME2 108 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B21_ME2 109 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B22_ME2 110 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B23_ME2 111 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B24_ME3 112 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B25_ME3 113 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B26_ME3 114 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B27_ME3 115 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B28_ME3 116 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B29_ME3 117 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B30_ME3 118 /* ME_THREAD_B */
+#define IRQ_IXP23XX_ME_THREAD_B31_ME3 119 /* ME_THREAD_B */
+
+#define NUM_IXP23XX_RAW_IRQS 120
+
+#define IRQ_IXP23XX_INTA 120 /* Indirect pcxg_pci_int_rph */
+#define IRQ_IXP23XX_INTB 121 /* Indirect pcxg_pci_int_rph */
+
+#define NR_IXP23XX_IRQ (IRQ_IXP23XX_INTB + 1)
+
+/*
+ * We default to 32 per-board IRQs. Increase this number if you need
+ * more, but keep it realistic.
+ */
+#define NR_IXP23XX_MACH_IRQS 32
+
+#define NR_IRQS (NR_IXP23XX_IRQS + NR_IXP23XX_MACH_IRQS)
+
+#define IXP23XX_MACH_IRQ(irq) (NR_IXP23XX_IRQ + (irq))
+
+
+/*
+ * IXDP2351-specific interrupts
+ */
+
+/*
+ * External PCI interrupts signaled through INTB
+ *
+ */
+#define IXDP2351_INTB_IRQ_BASE 0
+#define IRQ_IXDP2351_INTA_82546 IXP23XX_MACH_IRQ(0)
+#define IRQ_IXDP2351_INTB_82546 IXP23XX_MACH_IRQ(1)
+#define IRQ_IXDP2351_SPCI_DB_0 IXP23XX_MACH_IRQ(2)
+#define IRQ_IXDP2351_SPCI_DB_1 IXP23XX_MACH_IRQ(3)
+#define IRQ_IXDP2351_SPCI_PMC_INTA IXP23XX_MACH_IRQ(4)
+#define IRQ_IXDP2351_SPCI_PMC_INTB IXP23XX_MACH_IRQ(5)
+#define IRQ_IXDP2351_SPCI_PMC_INTC IXP23XX_MACH_IRQ(6)
+#define IRQ_IXDP2351_SPCI_PMC_INTD IXP23XX_MACH_IRQ(7)
+#define IRQ_IXDP2351_SPCI_FIC IXP23XX_MACH_IRQ(8)
+
+#define IXDP2351_INTB_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(0))
+#define IXDP2351_INTB_IRQ_MASK(irq) (1 << IXDP2351_INTB_IRQ_BIT(irq))
+#define IXDP2351_INTB_IRQ_VALID 0x01FF
+#define IXDP2351_INTB_IRQ_NUM 16
+
+/*
+ * Other external interrupts signaled through INTA
+ */
+#define IXDP2351_INTA_IRQ_BASE 16
+#define IRQ_IXDP2351_IPMI_FROM IXP23XX_MACH_IRQ(16)
+#define IRQ_IXDP2351_125US IXP23XX_MACH_IRQ(17)
+#define IRQ_IXDP2351_DB_0_ADD IXP23XX_MACH_IRQ(18)
+#define IRQ_IXDP2351_DB_1_ADD IXP23XX_MACH_IRQ(19)
+#define IRQ_IXDP2351_DEBUG1 IXP23XX_MACH_IRQ(20)
+#define IRQ_IXDP2351_ADD_UART IXP23XX_MACH_IRQ(21)
+#define IRQ_IXDP2351_FIC_ADD IXP23XX_MACH_IRQ(24)
+#define IRQ_IXDP2351_CS8900 IXP23XX_MACH_IRQ(25)
+#define IRQ_IXDP2351_BBSRAM IXP23XX_MACH_IRQ(26)
+#define IRQ_IXDP2351_CONFIG_MEDIA IXP23XX_MACH_IRQ(27)
+#define IRQ_IXDP2351_CLOCK_REF IXP23XX_MACH_IRQ(28)
+#define IRQ_IXDP2351_A10_NP IXP23XX_MACH_IRQ(29)
+#define IRQ_IXDP2351_A11_NP IXP23XX_MACH_IRQ(30)
+#define IRQ_IXDP2351_DEBUG_NP IXP23XX_MACH_IRQ(31)
+
+#define IXDP2351_INTA_IRQ_BIT(irq) (irq - IXP23XX_MACH_IRQ(16))
+#define IXDP2351_INTA_IRQ_MASK(irq) (1 << IXDP2351_INTA_IRQ_BIT(irq))
+#define IXDP2351_INTA_IRQ_VALID 0xFF3F
+#define IXDP2351_INTA_IRQ_NUM 16
+
+
+/*
+ * ADI RoadRunner IRQs
+ */
+#define IRQ_ROADRUNNER_PCI_INTA IRQ_IXP23XX_INTA
+#define IRQ_ROADRUNNER_PCI_INTB IRQ_IXP23XX_INTB
+#define IRQ_ROADRUNNER_PCI_INTC IRQ_IXP23XX_GPIO11
+#define IRQ_ROADRUNNER_PCI_INTD IRQ_IXP23XX_GPIO12
+
+/*
+ * Put new board definitions here
+ */
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h b/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h
new file mode 100644
index 00000000..66395102
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/ixdp2351.h
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/ixdp2351.h
+ *
+ * Register and other defines for IXDP2351
+ *
+ * Copyright (c) 2002-2004 Intel Corp.
+ * Copytight (c) 2005 MontaVista Software, 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.
+ */
+
+#ifndef __ASM_ARCH_IXDP2351_H
+#define __ASM_ARCH_IXDP2351_H
+
+/*
+ * NP module memory map
+ */
+#define IXDP2351_NP_PHYS_BASE (IXP23XX_EXP_BUS_CS4_BASE)
+#define IXDP2351_NP_PHYS_SIZE 0x00100000
+#define IXDP2351_NP_VIRT_BASE 0xeff00000
+
+#define IXDP2351_VIRT_CS8900_BASE (IXDP2351_NP_VIRT_BASE)
+#define IXDP2351_VIRT_CS8900_END (IXDP2351_VIRT_CS8900_BASE + 16)
+
+#define IXDP2351_VIRT_NP_CPLD_BASE (IXP23XX_EXP_BUS_CS4_BASE_VIRT + 0x00010000)
+
+#define IXDP2351_NP_CPLD_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_NP_CPLD_BASE + reg))
+
+#define IXDP2351_NP_CPLD_RESET1_REG IXDP2351_NP_CPLD_REG(0x00)
+#define IXDP2351_NP_CPLD_LED_REG IXDP2351_NP_CPLD_REG(0x02)
+#define IXDP2351_NP_CPLD_VERSION_REG IXDP2351_NP_CPLD_REG(0x04)
+
+/*
+ * Base board module memory map
+ */
+
+#define IXDP2351_BB_BASE_PHYS (IXP23XX_EXP_BUS_CS5_BASE)
+#define IXDP2351_BB_SIZE 0x01000000
+#define IXDP2351_BB_BASE_VIRT (0xee000000)
+
+#define IXDP2351_BB_AREA_BASE(offset) (IXDP2351_BB_BASE_VIRT + offset)
+
+#define IXDP2351_VIRT_NVRAM_BASE IXDP2351_BB_AREA_BASE(0x0)
+#define IXDP2351_NVRAM_SIZE (0x20000)
+
+#define IXDP2351_VIRT_MB_IXF1104_BASE IXDP2351_BB_AREA_BASE(0x00020000)
+#define IXDP2351_VIRT_ADD_UART_BASE IXDP2351_BB_AREA_BASE(0x000240C0)
+#define IXDP2351_VIRT_FIC_BASE IXDP2351_BB_AREA_BASE(0x00200000)
+#define IXDP2351_VIRT_DB0_BASE IXDP2351_BB_AREA_BASE(0x00400000)
+#define IXDP2351_VIRT_DB1_BASE IXDP2351_BB_AREA_BASE(0x00600000)
+#define IXDP2351_VIRT_CPLD_BASE IXDP2351_BB_AREA_BASE(0x00024000)
+
+/*
+ * On board CPLD registers
+ */
+#define IXDP2351_CPLD_BB_REG(reg) ((volatile u16 *)(IXDP2351_VIRT_CPLD_BASE + reg))
+
+#define IXDP2351_CPLD_RESET0_REG IXDP2351_CPLD_BB_REG(0x00)
+#define IXDP2351_CPLD_RESET1_REG IXDP2351_CPLD_BB_REG(0x04)
+
+#define IXDP2351_CPLD_RESET1_MAGIC 0x55AA
+#define IXDP2351_CPLD_RESET1_ENABLE 0x8000
+
+#define IXDP2351_CPLD_FPGA_CONFIG_REG IXDP2351_CPLD_BB_REG(0x08)
+#define IXDP2351_CPLD_INTB_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x10)
+#define IXDP2351_CPLD_INTA_MASK_SET_REG IXDP2351_CPLD_BB_REG(0x14)
+#define IXDP2351_CPLD_INTB_STAT_REG IXDP2351_CPLD_BB_REG(0x18)
+#define IXDP2351_CPLD_INTA_STAT_REG IXDP2351_CPLD_BB_REG(0x1C)
+#define IXDP2351_CPLD_INTB_RAW_REG IXDP2351_CPLD_BB_REG(0x20) /* read */
+#define IXDP2351_CPLD_INTA_RAW_REG IXDP2351_CPLD_BB_REG(0x24) /* read */
+#define IXDP2351_CPLD_INTB_MASK_CLR_REG IXDP2351_CPLD_INTB_RAW_REG /* write */
+#define IXDP2351_CPLD_INTA_MASK_CLR_REG IXDP2351_CPLD_INTA_RAW_REG /* write */
+#define IXDP2351_CPLD_INTB_SIM_REG IXDP2351_CPLD_BB_REG(0x28)
+#define IXDP2351_CPLD_INTA_SIM_REG IXDP2351_CPLD_BB_REG(0x2C)
+ /* Interrupt bits are defined in irqs.h */
+#define IXDP2351_CPLD_BB_GBE0_REG IXDP2351_CPLD_BB_REG(0x30)
+#define IXDP2351_CPLD_BB_GBE1_REG IXDP2351_CPLD_BB_REG(0x34)
+
+/* #define IXDP2351_CPLD_BB_MISC_REG IXDP2351_CPLD_REG(0x1C) */
+/* #define IXDP2351_CPLD_BB_MISC_REV_MASK 0xFF */
+/* #define IXDP2351_CPLD_BB_GDXCS0_REG IXDP2351_CPLD_REG(0x24) */
+/* #define IXDP2351_CPLD_BB_GDXCS1_REG IXDP2351_CPLD_REG(0x28) */
+/* #define IXDP2351_CPLD_BB_CLOCK_REG IXDP2351_CPLD_REG(0x04) */
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h b/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h
new file mode 100644
index 00000000..6d02481b
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/ixp23xx.h
@@ -0,0 +1,298 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/ixp23xx.h
+ *
+ * Register definitions for IXP23XX
+ *
+ * Copyright (C) 2003-2005 Intel Corporation.
+ * Copyright (C) 2005 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can 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_IXP23XX_H
+#define __ASM_ARCH_IXP23XX_H
+
+/*
+ * IXP2300 linux memory map:
+ *
+ * virt phys size
+ * fffd0000 a0000000 64K XSI2CPP_CSR
+ * fffc0000 c4000000 4K EXP_CFG
+ * fff00000 c8000000 64K PERIPHERAL
+ * fe000000 1c0000000 16M CAP_CSR
+ * fd000000 1c8000000 16M MSF_CSR
+ * fb000000 16M ---
+ * fa000000 1d8000000 32M PCI_IO
+ * f8000000 1da000000 32M PCI_CFG
+ * f6000000 1de000000 32M PCI_CREG
+ * f4000000 32M ---
+ * f0000000 1e0000000 64M PCI_MEM
+ * e[c-f]000000 per-platform mappings
+ */
+
+
+/****************************************************************************
+ * Static mappings.
+ ****************************************************************************/
+#define IXP23XX_XSI2CPP_CSR_PHYS 0xa0000000
+#define IXP23XX_XSI2CPP_CSR_VIRT 0xfffd0000
+#define IXP23XX_XSI2CPP_CSR_SIZE 0x00010000
+
+#define IXP23XX_EXP_CFG_PHYS 0xc4000000
+#define IXP23XX_EXP_CFG_VIRT 0xfffc0000
+#define IXP23XX_EXP_CFG_SIZE 0x00001000
+
+#define IXP23XX_PERIPHERAL_PHYS 0xc8000000
+#define IXP23XX_PERIPHERAL_VIRT 0xfff00000
+#define IXP23XX_PERIPHERAL_SIZE 0x00010000
+
+#define IXP23XX_CAP_CSR_PHYS 0x1c0000000ULL
+#define IXP23XX_CAP_CSR_VIRT 0xfe000000
+#define IXP23XX_CAP_CSR_SIZE 0x01000000
+
+#define IXP23XX_MSF_CSR_PHYS 0x1c8000000ULL
+#define IXP23XX_MSF_CSR_VIRT 0xfd000000
+#define IXP23XX_MSF_CSR_SIZE 0x01000000
+
+#define IXP23XX_PCI_IO_PHYS 0x1d8000000ULL
+#define IXP23XX_PCI_IO_VIRT 0xfa000000
+#define IXP23XX_PCI_IO_SIZE 0x02000000
+
+#define IXP23XX_PCI_CFG_PHYS 0x1da000000ULL
+#define IXP23XX_PCI_CFG_VIRT 0xf8000000
+#define IXP23XX_PCI_CFG_SIZE 0x02000000
+#define IXP23XX_PCI_CFG0_VIRT IXP23XX_PCI_CFG_VIRT
+#define IXP23XX_PCI_CFG1_VIRT (IXP23XX_PCI_CFG_VIRT + 0x01000000)
+
+#define IXP23XX_PCI_CREG_PHYS 0x1de000000ULL
+#define IXP23XX_PCI_CREG_VIRT 0xf6000000
+#define IXP23XX_PCI_CREG_SIZE 0x02000000
+#define IXP23XX_PCI_CSR_VIRT (IXP23XX_PCI_CREG_VIRT + 0x01000000)
+
+#define IXP23XX_PCI_MEM_START 0xe0000000
+#define IXP23XX_PCI_MEM_PHYS 0x1e0000000ULL
+#define IXP23XX_PCI_MEM_VIRT 0xf0000000
+#define IXP23XX_PCI_MEM_SIZE 0x04000000
+
+
+/****************************************************************************
+ * XSI2CPP CSRs.
+ ****************************************************************************/
+#define IXP23XX_XSI2CPP_REG(x) ((volatile unsigned long *)(IXP23XX_XSI2CPP_CSR_VIRT + (x)))
+#define IXP23XX_CPP2XSI_CURR_XFER_REG3 IXP23XX_XSI2CPP_REG(0xf8)
+#define IXP23XX_CPP2XSI_ADDR_31 (1 << 19)
+#define IXP23XX_CPP2XSI_PSH_OFF (1 << 20)
+#define IXP23XX_CPP2XSI_COH_OFF (1 << 21)
+
+
+/****************************************************************************
+ * Expansion Bus Config.
+ ****************************************************************************/
+#define IXP23XX_EXP_CFG_REG(x) ((volatile unsigned long *)(IXP23XX_EXP_CFG_VIRT + (x)))
+#define IXP23XX_EXP_CS0 IXP23XX_EXP_CFG_REG(0x00)
+#define IXP23XX_EXP_CS1 IXP23XX_EXP_CFG_REG(0x04)
+#define IXP23XX_EXP_CS2 IXP23XX_EXP_CFG_REG(0x08)
+#define IXP23XX_EXP_CS3 IXP23XX_EXP_CFG_REG(0x0c)
+#define IXP23XX_EXP_CS4 IXP23XX_EXP_CFG_REG(0x10)
+#define IXP23XX_EXP_CS5 IXP23XX_EXP_CFG_REG(0x14)
+#define IXP23XX_EXP_CS6 IXP23XX_EXP_CFG_REG(0x18)
+#define IXP23XX_EXP_CS7 IXP23XX_EXP_CFG_REG(0x1c)
+#define IXP23XX_FLASH_WRITABLE (0x2)
+#define IXP23XX_FLASH_BUS8 (0x1)
+
+#define IXP23XX_EXP_CFG0 IXP23XX_EXP_CFG_REG(0x20)
+#define IXP23XX_EXP_CFG1 IXP23XX_EXP_CFG_REG(0x24)
+#define IXP23XX_EXP_CFG0_MEM_MAP (1 << 31)
+#define IXP23XX_EXP_CFG0_XSCALE_SPEED_SEL (3 << 22)
+#define IXP23XX_EXP_CFG0_XSCALE_SPEED_EN (1 << 21)
+#define IXP23XX_EXP_CFG0_CPP_SPEED_SEL (3 << 19)
+#define IXP23XX_EXP_CFG0_CPP_SPEED_EN (1 << 18)
+#define IXP23XX_EXP_CFG0_PCI_SWIN (3 << 16)
+#define IXP23XX_EXP_CFG0_PCI_DWIN (3 << 14)
+#define IXP23XX_EXP_CFG0_PCI33_MODE (1 << 13)
+#define IXP23XX_EXP_CFG0_QDR_SPEED_SEL (1 << 12)
+#define IXP23XX_EXP_CFG0_CPP_DIV_SEL (1 << 5)
+#define IXP23XX_EXP_CFG0_XSI_NOT_PRES (1 << 4)
+#define IXP23XX_EXP_CFG0_PROM_BOOT (1 << 3)
+#define IXP23XX_EXP_CFG0_PCI_ARB (1 << 2)
+#define IXP23XX_EXP_CFG0_PCI_HOST (1 << 1)
+#define IXP23XX_EXP_CFG0_FLASH_WIDTH (1 << 0)
+
+#define IXP23XX_EXP_UNIT_FUSE IXP23XX_EXP_CFG_REG(0x28)
+#define IXP23XX_EXP_MSF_MUX IXP23XX_EXP_CFG_REG(0x30)
+#define IXP23XX_EXP_CFG_FUSE IXP23XX_EXP_CFG_REG(0x34)
+
+#define IXP23XX_EXP_BUS_PHYS 0x90000000
+#define IXP23XX_EXP_BUS_WINDOW_SIZE 0x01000000
+
+#define IXP23XX_EXP_BUS_CS0_BASE (IXP23XX_EXP_BUS_PHYS + 0x00000000)
+#define IXP23XX_EXP_BUS_CS1_BASE (IXP23XX_EXP_BUS_PHYS + 0x01000000)
+#define IXP23XX_EXP_BUS_CS2_BASE (IXP23XX_EXP_BUS_PHYS + 0x02000000)
+#define IXP23XX_EXP_BUS_CS3_BASE (IXP23XX_EXP_BUS_PHYS + 0x03000000)
+#define IXP23XX_EXP_BUS_CS4_BASE (IXP23XX_EXP_BUS_PHYS + 0x04000000)
+#define IXP23XX_EXP_BUS_CS5_BASE (IXP23XX_EXP_BUS_PHYS + 0x05000000)
+#define IXP23XX_EXP_BUS_CS6_BASE (IXP23XX_EXP_BUS_PHYS + 0x06000000)
+#define IXP23XX_EXP_BUS_CS7_BASE (IXP23XX_EXP_BUS_PHYS + 0x07000000)
+
+
+/****************************************************************************
+ * Peripherals.
+ ****************************************************************************/
+#define IXP23XX_UART1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x0000)
+#define IXP23XX_UART2_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x1000)
+#define IXP23XX_PMU_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x2000)
+#define IXP23XX_INTC_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x3000)
+#define IXP23XX_GPIO_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x4000)
+#define IXP23XX_TIMER_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x5000)
+#define IXP23XX_NPE0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x6000)
+#define IXP23XX_DSR_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x7000)
+#define IXP23XX_NPE1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x8000)
+#define IXP23XX_ETH0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0x9000)
+#define IXP23XX_ETH1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xA000)
+#define IXP23XX_GIG0_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xB000)
+#define IXP23XX_GIG1_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xC000)
+#define IXP23XX_DDRS_VIRT (IXP23XX_PERIPHERAL_VIRT + 0xD000)
+
+#define IXP23XX_UART1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x0000)
+#define IXP23XX_UART2_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x1000)
+#define IXP23XX_PMU_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x2000)
+#define IXP23XX_INTC_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x3000)
+#define IXP23XX_GPIO_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x4000)
+#define IXP23XX_TIMER_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x5000)
+#define IXP23XX_NPE0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x6000)
+#define IXP23XX_DSR_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x7000)
+#define IXP23XX_NPE1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x8000)
+#define IXP23XX_ETH0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0x9000)
+#define IXP23XX_ETH1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xA000)
+#define IXP23XX_GIG0_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xB000)
+#define IXP23XX_GIG1_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xC000)
+#define IXP23XX_DDRS_PHYS (IXP23XX_PERIPHERAL_PHYS + 0xD000)
+
+
+/****************************************************************************
+ * Interrupt controller.
+ ****************************************************************************/
+#define IXP23XX_INTC_REG(x) ((volatile unsigned long *)(IXP23XX_INTC_VIRT + (x)))
+#define IXP23XX_INTR_ST1 IXP23XX_INTC_REG(0x00)
+#define IXP23XX_INTR_ST2 IXP23XX_INTC_REG(0x04)
+#define IXP23XX_INTR_ST3 IXP23XX_INTC_REG(0x08)
+#define IXP23XX_INTR_ST4 IXP23XX_INTC_REG(0x0c)
+#define IXP23XX_INTR_EN1 IXP23XX_INTC_REG(0x10)
+#define IXP23XX_INTR_EN2 IXP23XX_INTC_REG(0x14)
+#define IXP23XX_INTR_EN3 IXP23XX_INTC_REG(0x18)
+#define IXP23XX_INTR_EN4 IXP23XX_INTC_REG(0x1c)
+#define IXP23XX_INTR_SEL1 IXP23XX_INTC_REG(0x20)
+#define IXP23XX_INTR_SEL2 IXP23XX_INTC_REG(0x24)
+#define IXP23XX_INTR_SEL3 IXP23XX_INTC_REG(0x28)
+#define IXP23XX_INTR_SEL4 IXP23XX_INTC_REG(0x2c)
+#define IXP23XX_INTR_IRQ_ST1 IXP23XX_INTC_REG(0x30)
+#define IXP23XX_INTR_IRQ_ST2 IXP23XX_INTC_REG(0x34)
+#define IXP23XX_INTR_IRQ_ST3 IXP23XX_INTC_REG(0x38)
+#define IXP23XX_INTR_IRQ_ST4 IXP23XX_INTC_REG(0x3c)
+#define IXP23XX_INTR_IRQ_ENC_ST_OFFSET 0x54
+
+
+/****************************************************************************
+ * GPIO.
+ ****************************************************************************/
+#define IXP23XX_GPIO_REG(x) ((volatile unsigned long *)(IXP23XX_GPIO_VIRT + (x)))
+#define IXP23XX_GPIO_GPOUTR IXP23XX_GPIO_REG(0x00)
+#define IXP23XX_GPIO_GPOER IXP23XX_GPIO_REG(0x04)
+#define IXP23XX_GPIO_GPINR IXP23XX_GPIO_REG(0x08)
+#define IXP23XX_GPIO_GPISR IXP23XX_GPIO_REG(0x0c)
+#define IXP23XX_GPIO_GPIT1R IXP23XX_GPIO_REG(0x10)
+#define IXP23XX_GPIO_GPIT2R IXP23XX_GPIO_REG(0x14)
+#define IXP23XX_GPIO_GPCLKR IXP23XX_GPIO_REG(0x18)
+#define IXP23XX_GPIO_GPDBSELR IXP23XX_GPIO_REG(0x1c)
+
+#define IXP23XX_GPIO_STYLE_MASK 0x7
+#define IXP23XX_GPIO_STYLE_ACTIVE_HIGH 0x0
+#define IXP23XX_GPIO_STYLE_ACTIVE_LOW 0x1
+#define IXP23XX_GPIO_STYLE_RISING_EDGE 0x2
+#define IXP23XX_GPIO_STYLE_FALLING_EDGE 0x3
+#define IXP23XX_GPIO_STYLE_TRANSITIONAL 0x4
+
+#define IXP23XX_GPIO_STYLE_SIZE 3
+
+
+/****************************************************************************
+ * Timer.
+ ****************************************************************************/
+#define IXP23XX_TIMER_REG(x) ((volatile unsigned long *)(IXP23XX_TIMER_VIRT + (x)))
+#define IXP23XX_TIMER_CONT IXP23XX_TIMER_REG(0x00)
+#define IXP23XX_TIMER1_TIMESTAMP IXP23XX_TIMER_REG(0x04)
+#define IXP23XX_TIMER1_RELOAD IXP23XX_TIMER_REG(0x08)
+#define IXP23XX_TIMER2_TIMESTAMP IXP23XX_TIMER_REG(0x0c)
+#define IXP23XX_TIMER2_RELOAD IXP23XX_TIMER_REG(0x10)
+#define IXP23XX_TIMER_WDOG IXP23XX_TIMER_REG(0x14)
+#define IXP23XX_TIMER_WDOG_EN IXP23XX_TIMER_REG(0x18)
+#define IXP23XX_TIMER_WDOG_KEY IXP23XX_TIMER_REG(0x1c)
+#define IXP23XX_TIMER_WDOG_KEY_MAGIC 0x482e
+#define IXP23XX_TIMER_STATUS IXP23XX_TIMER_REG(0x20)
+#define IXP23XX_TIMER_SOFT_RESET IXP23XX_TIMER_REG(0x24)
+#define IXP23XX_TIMER_SOFT_RESET_EN IXP23XX_TIMER_REG(0x28)
+
+#define IXP23XX_TIMER_ENABLE (1 << 0)
+#define IXP23XX_TIMER_ONE_SHOT (1 << 1)
+/* Low order bits of reload value ignored */
+#define IXP23XX_TIMER_RELOAD_MASK (0x3)
+#define IXP23XX_TIMER_DISABLED (0x0)
+#define IXP23XX_TIMER1_INT_PEND (1 << 0)
+#define IXP23XX_TIMER2_INT_PEND (1 << 1)
+#define IXP23XX_TIMER_STATUS_TS_PEND (1 << 2)
+#define IXP23XX_TIMER_STATUS_WDOG_PEND (1 << 3)
+#define IXP23XX_TIMER_STATUS_WARM_RESET (1 << 4)
+
+
+/****************************************************************************
+ * CAP CSRs.
+ ****************************************************************************/
+#define IXP23XX_GLOBAL_REG(x) ((volatile unsigned long *)(IXP23XX_CAP_CSR_VIRT + 0x4a00 + (x)))
+#define IXP23XX_PRODUCT_ID IXP23XX_GLOBAL_REG(0x00)
+#define IXP23XX_MISC_CONTROL IXP23XX_GLOBAL_REG(0x04)
+#define IXP23XX_MSF_CLK_CNTRL IXP23XX_GLOBAL_REG(0x08)
+#define IXP23XX_RESET0 IXP23XX_GLOBAL_REG(0x0c)
+#define IXP23XX_RESET1 IXP23XX_GLOBAL_REG(0x10)
+#define IXP23XX_STRAP_OPTIONS IXP23XX_GLOBAL_REG(0x18)
+
+#define IXP23XX_ENABLE_WATCHDOG (1 << 24)
+#define IXP23XX_SHPC_INIT_COMP (1 << 21)
+#define IXP23XX_RST_ALL (1 << 16)
+#define IXP23XX_RESET_PCI (1 << 2)
+#define IXP23XX_PCI_UNIT_RESET (1 << 1)
+#define IXP23XX_XSCALE_RESET (1 << 0)
+
+#define IXP23XX_UENGINE_CSR_VIRT_BASE (IXP23XX_CAP_CSR_VIRT + 0x18000)
+
+
+/****************************************************************************
+ * PCI CSRs.
+ ****************************************************************************/
+#define IXP23XX_PCI_CREG(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + (x)))
+#define IXP23XX_PCI_CMDSTAT IXP23XX_PCI_CREG(0x04)
+#define IXP23XX_PCI_SRAM_BAR IXP23XX_PCI_CREG(0x14)
+#define IXP23XX_PCI_SDRAM_BAR IXP23XX_PCI_CREG(0x18)
+
+
+#define IXP23XX_PCI_CSR(x) ((volatile unsigned long *)(IXP23XX_PCI_CREG_VIRT + 0x01000000 + (x)))
+#define IXP23XX_PCI_OUT_INT_STATUS IXP23XX_PCI_CSR(0x0030)
+#define IXP23XX_PCI_OUT_INT_MASK IXP23XX_PCI_CSR(0x0034)
+#define IXP23XX_PCI_SRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x00fc)
+#define IXP23XX_PCI_DRAM_BASE_ADDR_MASK IXP23XX_PCI_CSR(0x0100)
+#define IXP23XX_PCI_CONTROL IXP23XX_PCI_CSR(0x013c)
+#define IXP23XX_PCI_ADDR_EXT IXP23XX_PCI_CSR(0x0140)
+#define IXP23XX_PCI_ME_PUSH_STATUS IXP23XX_PCI_CSR(0x0148)
+#define IXP23XX_PCI_ME_PUSH_EN IXP23XX_PCI_CSR(0x014c)
+#define IXP23XX_PCI_ERR_STATUS IXP23XX_PCI_CSR(0x0150)
+#define IXP23XX_PCI_ERROR_STATUS IXP23XX_PCI_CSR(0x0150)
+#define IXP23XX_PCI_ERR_ENABLE IXP23XX_PCI_CSR(0x0154)
+#define IXP23XX_PCI_XSCALE_INT_STATUS IXP23XX_PCI_CSR(0x0158)
+#define IXP23XX_PCI_XSCALE_INT_ENABLE IXP23XX_PCI_CSR(0x015c)
+#define IXP23XX_PCI_CPP_ADDR_BITS IXP23XX_PCI_CSR(0x0160)
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/memory.h b/arch/arm/mach-ixp23xx/include/mach/memory.h
new file mode 100644
index 00000000..6cf0704e
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/memory.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/memory.h
+ *
+ * Copyright (c) 2003-2004 Intel Corp.
+ *
+ * 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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <mach/hardware.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET (0x00000000)
+
+#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
+
+#define __phys_to_bus(x) ((x) + (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+#define __bus_to_phys(x) ((x) - (IXP23XX_PCI_SDRAM_OFFSET - PHYS_OFFSET))
+
+#define __virt_to_bus(v) __phys_to_bus(__virt_to_phys(v))
+#define __bus_to_virt(b) __phys_to_virt(__bus_to_phys(b))
+#define __pfn_to_bus(p) __phys_to_bus(__pfn_to_phys(p))
+#define __bus_to_pfn(b) __phys_to_pfn(__bus_to_phys(b))
+
+#define arch_is_coherent() 1
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/platform.h b/arch/arm/mach-ixp23xx/include/mach/platform.h
new file mode 100644
index 00000000..db9d9416
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/platform.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/platform.h
+ *
+ * Various bits of code used by platform-level code.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASSEMBLY__
+
+static inline unsigned long ixp2000_reg_read(volatile void *reg)
+{
+ return *((volatile unsigned long *)reg);
+}
+
+static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
+
+static inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
+{
+ *((volatile unsigned long *)reg) = val;
+}
+
+struct pci_sys_data;
+
+void ixp23xx_map_io(void);
+void ixp23xx_init_irq(void);
+void ixp23xx_sys_init(void);
+int ixp23xx_pci_setup(int, struct pci_sys_data *);
+void ixp23xx_pci_preinit(void);
+struct pci_bus *ixp23xx_pci_scan_bus(int, struct pci_sys_data*);
+void ixp23xx_pci_slave_init(void);
+
+extern struct sys_timer ixp23xx_timer;
+
+#define IXP23XX_UART_XTAL 14745600
+
+#ifndef __ASSEMBLY__
+/*
+ * Is system memory on the XSI or CPP bus?
+ */
+static inline unsigned ixp23xx_cpp_boot(void)
+{
+ return (*IXP23XX_EXP_CFG0 & IXP23XX_EXP_CFG0_XSI_NOT_PRES);
+}
+#endif
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h
new file mode 100644
index 00000000..8920ff2d
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/system.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/system.h
+ *
+ * Copyright (C) 2003 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+static inline void arch_idle(void)
+{
+#if 0
+ if (!hlt_counter)
+ cpu_do_idle();
+#endif
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /* First try machine specific support */
+ if (machine_is_ixdp2351()) {
+ *IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_MAGIC;
+ (void) *IXDP2351_CPLD_RESET1_REG;
+ *IXDP2351_CPLD_RESET1_REG = IXDP2351_CPLD_RESET1_ENABLE;
+ }
+
+ /* Use on-chip reset capability */
+ *IXP23XX_RESET0 |= IXP23XX_RST_ALL;
+}
diff --git a/arch/arm/mach-ixp23xx/include/mach/time.h b/arch/arm/mach-ixp23xx/include/mach/time.h
new file mode 100644
index 00000000..b61dafc8
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/time.h
@@ -0,0 +1,3 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/time.h
+ */
diff --git a/arch/arm/mach-ixp23xx/include/mach/timex.h b/arch/arm/mach-ixp23xx/include/mach/timex.h
new file mode 100644
index 00000000..e341e9cf
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/timex.h
@@ -0,0 +1,7 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/timex.h
+ *
+ * XScale architecture timex specifications
+ */
+
+#define CLOCK_TICK_RATE 75000000
diff --git a/arch/arm/mach-ixp23xx/include/mach/uncompress.h b/arch/arm/mach-ixp23xx/include/mach/uncompress.h
new file mode 100644
index 00000000..8b4c358d
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/uncompress.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/uncompress.h
+ *
+ * Copyright (C) 2002-2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/ixp23xx.h>
+#include <linux/serial_reg.h>
+
+#define UART_BASE ((volatile u32 *)IXP23XX_UART1_PHYS)
+
+static inline void putc(char c)
+{
+ int j;
+
+ for (j = 0; j < 0x1000; j++) {
+ if (UART_BASE[UART_LSR] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ UART_BASE[UART_TX] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+
+#endif
diff --git a/arch/arm/mach-ixp23xx/include/mach/vmalloc.h b/arch/arm/mach-ixp23xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..896c56a1
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-ixp23xx/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ *
+ * NPU mappings end at 0xf0000000 and we allocate 64MB for board
+ * specific static I/O.
+ */
+
+#define VMALLOC_END (0xec000000UL)
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
new file mode 100644
index 00000000..8dcba17c
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -0,0 +1,336 @@
+/*
+ * arch/arm/mach-ixp23xx/ixdp2351.c
+ *
+ * IXDP2351 board-specific routines
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2004 (c) Intel Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+
+/*
+ * IXDP2351 Interrupt Handling
+ */
+static void ixdp2351_inta_mask(struct irq_data *d)
+{
+ *IXDP2351_CPLD_INTA_MASK_SET_REG = IXDP2351_INTA_IRQ_MASK(d->irq);
+}
+
+static void ixdp2351_inta_unmask(struct irq_data *d)
+{
+ *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(d->irq);
+}
+
+static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u16 ex_interrupt =
+ *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID;
+ int i;
+
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+ for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) {
+ if (ex_interrupt & (1 << i)) {
+ int cpld_irq =
+ IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i);
+ generic_handle_irq(cpld_irq);
+ }
+ }
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+static struct irq_chip ixdp2351_inta_chip = {
+ .irq_ack = ixdp2351_inta_mask,
+ .irq_mask = ixdp2351_inta_mask,
+ .irq_unmask = ixdp2351_inta_unmask
+};
+
+static void ixdp2351_intb_mask(struct irq_data *d)
+{
+ *IXDP2351_CPLD_INTB_MASK_SET_REG = IXDP2351_INTB_IRQ_MASK(d->irq);
+}
+
+static void ixdp2351_intb_unmask(struct irq_data *d)
+{
+ *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(d->irq);
+}
+
+static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc)
+{
+ u16 ex_interrupt =
+ *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID;
+ int i;
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) {
+ if (ex_interrupt & (1 << i)) {
+ int cpld_irq =
+ IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i);
+ generic_handle_irq(cpld_irq);
+ }
+ }
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+static struct irq_chip ixdp2351_intb_chip = {
+ .irq_ack = ixdp2351_intb_mask,
+ .irq_mask = ixdp2351_intb_mask,
+ .irq_unmask = ixdp2351_intb_unmask
+};
+
+void __init ixdp2351_init_irq(void)
+{
+ int irq;
+
+ /* Mask all interrupts from CPLD, disable simulation */
+ *IXDP2351_CPLD_INTA_MASK_SET_REG = (u16) -1;
+ *IXDP2351_CPLD_INTB_MASK_SET_REG = (u16) -1;
+ *IXDP2351_CPLD_INTA_SIM_REG = 0;
+ *IXDP2351_CPLD_INTB_SIM_REG = 0;
+
+ ixp23xx_init_irq();
+
+ for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE);
+ irq <
+ IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + IXDP2351_INTA_IRQ_NUM);
+ irq++) {
+ if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) {
+ set_irq_flags(irq, IRQF_VALID);
+ irq_set_chip_and_handler(irq, &ixdp2351_inta_chip,
+ handle_level_irq);
+ }
+ }
+
+ for (irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE);
+ irq <
+ IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + IXDP2351_INTB_IRQ_NUM);
+ irq++) {
+ if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) {
+ set_irq_flags(irq, IRQF_VALID);
+ irq_set_chip_and_handler(irq, &ixdp2351_intb_chip,
+ handle_level_irq);
+ }
+ }
+
+ irq_set_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler);
+ irq_set_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler);
+}
+
+/*
+ * IXDP2351 PCI
+ */
+
+/*
+ * This board does not do normal PCI IRQ routing, or any
+ * sort of swizzling, so we just need to check where on the
+ * bus the device is and figure out what CPLD pin it is
+ * being routed to.
+ */
+#define DEVPIN(dev, pin) ((pin) | ((dev) << 3))
+
+static int __init ixdp2351_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u8 bus = dev->bus->number;
+ u32 devpin = DEVPIN(PCI_SLOT(dev->devfn), pin);
+ struct pci_bus *tmp_bus = dev->bus;
+
+ /* Primary bus, no interrupts here */
+ if (!bus)
+ return -1;
+
+ /* Lookup first leaf in bus tree */
+ while ((tmp_bus->parent != NULL) && (tmp_bus->parent->parent != NULL))
+ tmp_bus = tmp_bus->parent;
+
+ /* Select between known bridges */
+ switch (tmp_bus->self->devfn | (tmp_bus->self->bus->number << 8)) {
+ /* Device is located after first bridge */
+ case 0x0008:
+ if (tmp_bus == dev->bus) {
+ /* Device is located directy after first bridge */
+ switch (devpin) {
+ /* Onboard 82546 */
+ case DEVPIN(1, 1): /* Onboard 82546 ch 0 */
+ return IRQ_IXDP2351_INTA_82546;
+ case DEVPIN(1, 2): /* Onboard 82546 ch 1 */
+ return IRQ_IXDP2351_INTB_82546;
+ /* PMC SLOT */
+ case DEVPIN(0, 1): /* PMCP INTA# */
+ case DEVPIN(2, 4): /* PMCS INTD# */
+ return IRQ_IXDP2351_SPCI_PMC_INTA;
+ case DEVPIN(0, 2): /* PMCP INTB# */
+ case DEVPIN(2, 1): /* PMCS INTA# */
+ return IRQ_IXDP2351_SPCI_PMC_INTB;
+ case DEVPIN(0, 3): /* PMCP INTC# */
+ case DEVPIN(2, 2): /* PMCS INTB# */
+ return IRQ_IXDP2351_SPCI_PMC_INTC;
+ case DEVPIN(0, 4): /* PMCP INTD# */
+ case DEVPIN(2, 3): /* PMCS INTC# */
+ return IRQ_IXDP2351_SPCI_PMC_INTD;
+ }
+ } else {
+ /* Device is located indirectly after first bridge */
+ /* Not supported now */
+ return -1;
+ }
+ break;
+ case 0x0010:
+ if (tmp_bus == dev->bus) {
+ /* Device is located directy after second bridge */
+ /* Secondary bus of second bridge */
+ switch (devpin) {
+ case DEVPIN(0, 1): /* DB#0 */
+ case DEVPIN(0, 2):
+ case DEVPIN(0, 3):
+ case DEVPIN(0, 4):
+ return IRQ_IXDP2351_SPCI_DB_0;
+ case DEVPIN(1, 1): /* DB#1 */
+ case DEVPIN(1, 2):
+ case DEVPIN(1, 3):
+ case DEVPIN(1, 4):
+ return IRQ_IXDP2351_SPCI_DB_1;
+ case DEVPIN(2, 1): /* FIC1 */
+ case DEVPIN(2, 2):
+ case DEVPIN(2, 3):
+ case DEVPIN(2, 4):
+ case DEVPIN(3, 1): /* FIC2 */
+ case DEVPIN(3, 2):
+ case DEVPIN(3, 3):
+ case DEVPIN(3, 4):
+ return IRQ_IXDP2351_SPCI_FIC;
+ }
+ } else {
+ /* Device is located indirectly after second bridge */
+ /* Not supported now */
+ return -1;
+ }
+ break;
+ }
+
+ return -1;
+}
+
+struct hw_pci ixdp2351_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = ixp23xx_pci_preinit,
+ .setup = ixp23xx_pci_setup,
+ .scan = ixp23xx_pci_scan_bus,
+ .map_irq = ixdp2351_map_irq,
+};
+
+int __init ixdp2351_pci_init(void)
+{
+ if (machine_is_ixdp2351())
+ pci_common_init(&ixdp2351_pci);
+
+ return 0;
+}
+
+subsys_initcall(ixdp2351_pci_init);
+
+/*
+ * IXDP2351 Static Mapped I/O
+ */
+static struct map_desc ixdp2351_io_desc[] __initdata = {
+ {
+ .virtual = IXDP2351_NP_VIRT_BASE,
+ .pfn = __phys_to_pfn((u64)IXDP2351_NP_PHYS_BASE),
+ .length = IXDP2351_NP_PHYS_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IXDP2351_BB_BASE_VIRT,
+ .pfn = __phys_to_pfn((u64)IXDP2351_BB_BASE_PHYS),
+ .length = IXDP2351_BB_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init ixdp2351_map_io(void)
+{
+ ixp23xx_map_io();
+ iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc));
+}
+
+static struct physmap_flash_data ixdp2351_flash_data = {
+ .width = 1,
+};
+
+static struct resource ixdp2351_flash_resource = {
+ .start = 0x90000000,
+ .end = 0x93ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp2351_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp2351_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ixdp2351_flash_resource,
+};
+
+static void __init ixdp2351_init(void)
+{
+ platform_device_register(&ixdp2351_flash);
+
+ /*
+ * Mark flash as writeable
+ */
+ IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
+
+ ixp23xx_sys_init();
+}
+
+MACHINE_START(IXDP2351, "Intel IXDP2351 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixdp2351_map_io,
+ .init_irq = ixdp2351_init_irq,
+ .timer = &ixp23xx_timer,
+ .boot_params = 0x00000100,
+ .init_machine = ixdp2351_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
new file mode 100644
index 00000000..563819a8
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -0,0 +1,288 @@
+/*
+ * arch/arm/mach-ixp23xx/pci.c
+ *
+ * PCI routines for IXP23XX based systems
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc.
+ *
+ * based on original code:
+ *
+ * Author: Naeem Afzal <naeem.m.afzal@intel.com>
+ * Copyright 2002-2005 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <mach/hardware.h>
+
+extern int (*external_fault) (unsigned long, struct pt_regs *);
+
+static volatile int pci_master_aborts = 0;
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+int clear_master_aborts(void);
+
+static u32
+*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
+{
+ u32 *paddress;
+
+ /*
+ * Must be dword aligned
+ */
+ where &= ~3;
+
+ /*
+ * For top bus, generate type 0, else type 1
+ */
+ if (!bus_nr) {
+ if (PCI_SLOT(devfn) >= 8)
+ return 0;
+
+ paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT
+ | (1 << (PCI_SLOT(devfn) + 16))
+ | (PCI_FUNC(devfn) << 8) | where);
+ } else {
+ paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT
+ | (bus_nr << 16)
+ | (PCI_SLOT(devfn) << 11)
+ | (PCI_FUNC(devfn) << 8) | where);
+ }
+
+ return paddress;
+}
+
+/*
+ * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
+ * 0 and 3 are not valid indexes...
+ */
+static u32 bytemask[] = {
+ /*0*/ 0,
+ /*1*/ 0xff,
+ /*2*/ 0xffff,
+ /*3*/ 0,
+ /*4*/ 0xffffffff,
+};
+
+static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ u32 n;
+ u32 *addr;
+
+ n = where % 4;
+
+ DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where,
+ bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ pci_master_aborts = 0;
+ *value = (*addr >> (8*n)) & bytemask[size];
+ if (pci_master_aborts) {
+ pci_master_aborts = 0;
+ *value = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * We don't do error checking on the address for writes.
+ * It's assumed that the user checked for the device existing first
+ * by doing a read first.
+ */
+static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ u32 mask;
+ u32 *addr;
+ u32 temp;
+
+ mask = ~(bytemask[size] << ((where % 0x4) * 8));
+ addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ temp = (u32) (value) << ((where % 0x4) * 8);
+ *addr = (*addr & mask) | temp;
+
+ clear_master_aborts();
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops ixp23xx_pci_ops = {
+ .read = ixp23xx_pci_read_config,
+ .write = ixp23xx_pci_write_config,
+};
+
+struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
+{
+ return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
+}
+
+int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ volatile unsigned long temp;
+ unsigned long flags;
+
+ pci_master_aborts = 1;
+
+ local_irq_save(flags);
+ temp = *IXP23XX_PCI_CONTROL;
+
+ /*
+ * master abort and cmd tgt err
+ */
+ if (temp & ((1 << 8) | (1 << 5)))
+ *IXP23XX_PCI_CONTROL = temp;
+
+ temp = *IXP23XX_PCI_CMDSTAT;
+
+ if (temp & (1 << 29))
+ *IXP23XX_PCI_CMDSTAT = temp;
+ local_irq_restore(flags);
+
+ /*
+ * If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+
+ return 0;
+}
+
+int clear_master_aborts(void)
+{
+ volatile u32 temp;
+
+ temp = *IXP23XX_PCI_CONTROL;
+
+ /*
+ * master abort and cmd tgt err
+ */
+ if (temp & ((1 << 8) | (1 << 5)))
+ *IXP23XX_PCI_CONTROL = temp;
+
+ temp = *IXP23XX_PCI_CMDSTAT;
+
+ if (temp & (1 << 29))
+ *IXP23XX_PCI_CMDSTAT = temp;
+
+ return 0;
+}
+
+static void __init ixp23xx_pci_common_init(void)
+{
+#ifdef __ARMEB__
+ *IXP23XX_PCI_CONTROL |= 0x20000; /* set I/O swapping */
+#endif
+ /*
+ * ADDR_31 needs to be clear for PCI memory access to CPP memory
+ */
+ *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31;
+ *IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF;
+
+ /*
+ * Select correct memory for PCI inbound transactions
+ */
+ if (ixp23xx_cpp_boot()) {
+ *IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
+ } else {
+ *IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);
+
+ /*
+ * Enable coherency on A2 silicon.
+ */
+ if (arch_is_coherent())
+ *IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
+ }
+}
+
+void __init ixp23xx_pci_preinit(void)
+{
+ ixp23xx_pci_common_init();
+
+ hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0,
+ "PCI config cycle to non-existent device");
+
+ *IXP23XX_PCI_ADDR_EXT = 0x0000e000;
+}
+
+/*
+ * Prevent PCI layer from seeing the inbound host-bridge resources
+ */
+static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev)
+{
+ int i;
+
+ dev->class &= 0xff;
+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx);
+
+/*
+ * IXP2300 systems often have large resource requirements, so we just
+ * use our own resource space.
+ */
+static struct resource ixp23xx_pci_mem_space = {
+ .start = IXP23XX_PCI_MEM_START,
+ .end = IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "PCI Mem Space"
+};
+
+static struct resource ixp23xx_pci_io_space = {
+ .start = 0x00000100,
+ .end = 0x01ffffff,
+ .flags = IORESOURCE_IO,
+ .name = "PCI I/O Space"
+};
+
+int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ if (nr >= 1)
+ return 0;
+
+ sys->resource[0] = &ixp23xx_pci_io_space;
+ sys->resource[1] = &ixp23xx_pci_mem_space;
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+void __init ixp23xx_pci_slave_init(void)
+{
+ ixp23xx_pci_common_init();
+}
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
new file mode 100644
index 00000000..8fe0c627
--- /dev/null
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -0,0 +1,179 @@
+/*
+ * arch/arm/mach-ixp23xx/roadrunner.c
+ *
+ * RoadRunner board-specific routines
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2005 (c) MontaVista Software, Inc.
+ *
+ * Based on 2.4 code Copyright 2005 (c) ADI Engineering Corporation
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/bitops.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Interrupt mapping
+ */
+#define INTA IRQ_ROADRUNNER_PCI_INTA
+#define INTB IRQ_ROADRUNNER_PCI_INTB
+#define INTC IRQ_ROADRUNNER_PCI_INTC
+#define INTD IRQ_ROADRUNNER_PCI_INTD
+
+#define INTC_PIN IXP23XX_GPIO_PIN_11
+#define INTD_PIN IXP23XX_GPIO_PIN_12
+
+static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
+{
+ static int pci_card_slot_irq[] = {INTB, INTC, INTD, INTA};
+ static int pmc_card_slot_irq[] = {INTA, INTB, INTC, INTD};
+ static int usb_irq[] = {INTB, INTC, INTD, -1};
+ static int mini_pci_1_irq[] = {INTB, INTC, -1, -1};
+ static int mini_pci_2_irq[] = {INTC, INTD, -1, -1};
+
+ switch(dev->bus->number) {
+ case 0:
+ switch(dev->devfn) {
+ case 0x0: // PCI-PCI bridge
+ break;
+ case 0x8: // PCI Card Slot
+ return pci_card_slot_irq[pin - 1];
+ case 0x10: // PMC Slot
+ return pmc_card_slot_irq[pin - 1];
+ case 0x18: // PMC Slot Secondary Agent
+ break;
+ case 0x20: // IXP Processor
+ break;
+ default:
+ return NO_IRQ;
+ }
+ break;
+
+ case 1:
+ switch(dev->devfn) {
+ case 0x0: // IDE Controller
+ return (pin == 1) ? INTC : -1;
+ case 0x8: // USB fun 0
+ case 0x9: // USB fun 1
+ case 0xa: // USB fun 2
+ return usb_irq[pin - 1];
+ case 0x10: // Mini PCI 1
+ return mini_pci_1_irq[pin-1];
+ case 0x18: // Mini PCI 2
+ return mini_pci_2_irq[pin-1];
+ case 0x20: // MEM slot
+ return (pin == 1) ? INTA : -1;
+ default:
+ return NO_IRQ;
+ }
+ break;
+
+ default:
+ return NO_IRQ;
+ }
+
+ return NO_IRQ;
+}
+
+static void __init roadrunner_pci_preinit(void)
+{
+ irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
+
+ ixp23xx_pci_preinit();
+}
+
+static struct hw_pci roadrunner_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = roadrunner_pci_preinit,
+ .setup = ixp23xx_pci_setup,
+ .scan = ixp23xx_pci_scan_bus,
+ .map_irq = roadrunner_map_irq,
+};
+
+static int __init roadrunner_pci_init(void)
+{
+ if (machine_is_roadrunner())
+ pci_common_init(&roadrunner_pci);
+
+ return 0;
+};
+
+subsys_initcall(roadrunner_pci_init);
+
+static struct physmap_flash_data roadrunner_flash_data = {
+ .width = 2,
+};
+
+static struct resource roadrunner_flash_resource = {
+ .start = 0x90000000,
+ .end = 0x93ffffff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device roadrunner_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &roadrunner_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &roadrunner_flash_resource,
+};
+
+static void __init roadrunner_init(void)
+{
+ platform_device_register(&roadrunner_flash);
+
+ /*
+ * Mark flash as writeable
+ */
+ IXP23XX_EXP_CS0[0] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[1] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[2] |= IXP23XX_FLASH_WRITABLE;
+ IXP23XX_EXP_CS0[3] |= IXP23XX_FLASH_WRITABLE;
+
+ ixp23xx_sys_init();
+}
+
+MACHINE_START(ROADRUNNER, "ADI Engineering RoadRunner Development Platform")
+ /* Maintainer: Deepak Saxena */
+ .map_io = ixp23xx_map_io,
+ .init_irq = ixp23xx_init_irq,
+ .timer = &ixp23xx_timer,
+ .boot_params = 0x00000100,
+ .init_machine = roadrunner_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
new file mode 100644
index 00000000..6f991c5a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -0,0 +1,226 @@
+if ARCH_IXP4XX
+
+config ARCH_SUPPORTS_BIG_ENDIAN
+ bool
+ default y
+
+menu "Intel IXP4xx Implementation Options"
+
+comment "IXP4xx Platforms"
+
+config MACH_NSLU2
+ bool
+ prompt "Linksys NSLU2"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Linksys's
+ NSLU2 NAS device. For more information on this platform,
+ see http://www.nslu2-linux.org
+
+config MACH_AVILA
+ bool "Avila"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support the Gateworks
+ Avila Network Platform. For more information on this platform,
+ see <file:Documentation/arm/IXP4xx>.
+
+config MACH_LOFT
+ bool "Loft"
+ depends on MACH_AVILA
+ help
+ Say 'Y' here if you want your kernel to support the Giant
+ Shoulder Inc Loft board (a minor variation on the standard
+ Gateworks Avila Network Platform).
+
+config ARCH_ADI_COYOTE
+ bool "Coyote"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support the ADI
+ Engineering Coyote Gateway Reference Platform. For more
+ information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_GATEWAY7001
+ bool "Gateway 7001"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Gateway's
+ 7001 Access Point. For more information on this platform,
+ see http://openwrt.org
+
+config MACH_WG302V2
+ bool "Netgear WG302 v2 / WAG302 v2"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Netgear's
+ WG302 v2 or WAG302 v2 Access Points. For more information
+ on this platform, see http://openwrt.org
+
+config ARCH_IXDP425
+ bool "IXDP425"
+ help
+ Say 'Y' here if you want your kernel to support Intel's
+ IXDP425 Development Platform (Also known as Richfield).
+ For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_IXDPG425
+ bool "IXDPG425"
+ help
+ Say 'Y' here if you want your kernel to support Intel's
+ IXDPG425 Development Platform (Also known as Montajade).
+ For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_IXDP465
+ bool "IXDP465"
+ help
+ Say 'Y' here if you want your kernel to support Intel's
+ IXDP465 Development Platform (Also known as BMP).
+ For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_GORAMO_MLR
+ bool "GORAMO Multi Link Router"
+ help
+ Say 'Y' here if you want your kernel to support GORAMO
+ MultiLink router.
+
+config MACH_KIXRP435
+ bool "KIXRP435"
+ help
+ Say 'Y' here if you want your kernel to support Intel's
+ KIXRP435 Reference Platform.
+ For more information on this platform, see <file:Documentation/arm/IXP4xx>.
+
+#
+# IXCDP1100 is the exact same HW as IXDP425, but with a different machine
+# number from the bootloader due to marketing monkeys, so we just enable it
+# by default if IXDP425 is enabled.
+#
+config ARCH_IXCDP1100
+ bool
+ depends on ARCH_IXDP425
+ default y
+
+config ARCH_PRPMC1100
+ bool "PrPMC1100"
+ help
+ Say 'Y' here if you want your kernel to support the Motorola
+ PrPCM1100 Processor Mezanine Module. For more information on
+ this platform, see <file:Documentation/arm/IXP4xx>.
+
+config MACH_NAS100D
+ bool
+ prompt "NAS100D"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Iomega's
+ NAS 100d device. For more information on this platform,
+ see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
+
+config MACH_DSMG600
+ bool
+ prompt "D-Link DSM-G600 RevA"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support D-Link's
+ DSM-G600 RevA device. For more information on this platform,
+ see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
+
+config ARCH_IXDP4XX
+ bool
+ depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
+ default y
+
+config MACH_FSG
+ bool
+ prompt "Freecom FSG-3"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Freecom's
+ FSG-3 device. For more information on this platform,
+ see http://www.nslu2-linux.org/wiki/FSG3/HomePage
+
+config MACH_ARCOM_VULCAN
+ bool
+ prompt "Arcom/Eurotech Vulcan"
+ select PCI
+ help
+ Say 'Y' here if you want your kernel to support Arcom's
+ Vulcan board.
+
+#
+# Certain registers and IRQs are only enabled if supporting IXP465 CPUs
+#
+config CPU_IXP46X
+ bool
+ depends on MACH_IXDP465
+ default y
+
+config CPU_IXP43X
+ bool
+ depends on MACH_KIXRP435
+ default y
+
+config MACH_GTWX5715
+ bool "Gemtek WX5715 (Linksys WRV54G)"
+ depends on ARCH_IXP4XX
+ select PCI
+ help
+ This board is currently inside the Linksys WRV54G Gateways.
+
+ IXP425 - 266mhz
+ 32mb SDRAM
+ 8mb Flash
+ miniPCI slot 0 does not have a card connector soldered to the board
+ miniPCI slot 1 has an ISL3880 802.11g card (Prism54)
+ npe0 is connected to a Kendin KS8995M Switch (4 ports)
+ npe1 is the "wan" port
+ "Console" UART is available on J11 as console
+ "High Speed" UART is n/c (as far as I can tell)
+ 20 Pin ARM/Xscale JTAG interface on J2
+
+comment "IXP4xx Options"
+
+config IXP4XX_INDIRECT_PCI
+ bool "Use indirect PCI memory access"
+ depends on PCI
+ help
+ IXP4xx provides two methods of accessing PCI memory space:
+
+ 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
+ To access PCI via this space, we simply ioremap() the BAR
+ into the kernel and we can use the standard read[bwl]/write[bwl]
+ macros. This is the preferred method due to speed but it
+ limits the system to just 64MB of PCI memory. This can be
+ problematic if using video cards and other memory-heavy devices.
+
+ 2) If > 64MB of memory space is required, the IXP4xx can be
+ configured to use indirect registers to access the whole PCI
+ memory space. This currently allows for up to 1 GB (0x10000000
+ to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
+ is that every PCI access requires three local register accesses
+ plus a spinlock, but in some cases the performance hit is
+ acceptable. In addition, you cannot mmap() PCI devices in this
+ case due to the indirect nature of the PCI window.
+
+ By default, the direct method is used. Choose this option if you
+ need to use the indirect method instead. If you don't know
+ what you need, leave this option unselected.
+
+config IXP4XX_QMGR
+ tristate "IXP4xx Queue Manager support"
+ help
+ This driver supports IXP4xx built-in hardware queue manager
+ and is automatically selected by Ethernet and HSS drivers.
+
+config IXP4XX_NPE
+ tristate "IXP4xx Network Processor Engine support"
+ select HOTPLUG
+ select FW_LOADER
+ help
+ This driver supports IXP4xx built-in network coprocessors
+ and is automatically selected by Ethernet and HSS drivers.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
new file mode 100644
index 00000000..d807fc36
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -0,0 +1,39 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-pci-y :=
+obj-pci-n :=
+
+obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o
+obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o
+obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
+obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
+obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
+obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
+obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
+obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
+obj-pci-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o
+obj-pci-$(CONFIG_MACH_WG302V2) += wg302v2-pci.o
+obj-pci-$(CONFIG_MACH_FSG) += fsg-pci.o
+obj-pci-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-pci.o
+
+obj-y += common.o
+
+obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o
+obj-$(CONFIG_MACH_AVILA) += avila-setup.o
+obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
+obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
+obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
+obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o
+obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o
+obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o
+obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-setup.o
+obj-$(CONFIG_MACH_WG302V2) += wg302v2-setup.o
+obj-$(CONFIG_MACH_FSG) += fsg-setup.o
+obj-$(CONFIG_MACH_GORAMO_MLR) += goramo_mlr.o
+obj-$(CONFIG_MACH_ARCOM_VULCAN) += vulcan-setup.o
+
+obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
+obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx_qmgr.o
+obj-$(CONFIG_IXP4XX_NPE) += ixp4xx_npe.o
diff --git a/arch/arm/mach-ixp4xx/Makefile.boot b/arch/arm/mach-ixp4xx/Makefile.boot
new file mode 100644
index 00000000..d84c5807
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+
diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c
new file mode 100644
index 00000000..162043ff
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/mach-ixp4xx/avila-pci.c
+ *
+ * Gateworks Avila board-level PCI initialization
+ *
+ * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
+ *
+ * Based on ixdp-pci.c
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#define AVILA_MAX_DEV 4
+#define LOFT_MAX_DEV 6
+#define IRQ_LINES 4
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 11
+#define INTB 10
+#define INTC 9
+#define INTD 8
+
+void __init avila_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[IRQ_LINES] = {
+ IXP4XX_GPIO_IRQ(INTA),
+ IXP4XX_GPIO_IRQ(INTB),
+ IXP4XX_GPIO_IRQ(INTC),
+ IXP4XX_GPIO_IRQ(INTD)
+ };
+
+ if (slot >= 1 &&
+ slot <= (machine_is_loft() ? LOFT_MAX_DEV : AVILA_MAX_DEV) &&
+ pin >= 1 && pin <= IRQ_LINES)
+ return pci_irq_table[(slot + pin - 2) % 4];
+
+ return -1;
+}
+
+struct hw_pci avila_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = avila_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = avila_map_irq,
+};
+
+int __init avila_pci_init(void)
+{
+ if (machine_is_avila() || machine_is_loft())
+ pci_common_init(&avila_pci);
+ return 0;
+}
+
+subsys_initcall(avila_pci_init);
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
new file mode 100644
index 00000000..73745ff1
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -0,0 +1,189 @@
+/*
+ * arch/arm/mach-ixp4xx/avila-setup.c
+ *
+ * Gateworks Avila board-setup
+ *
+ * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
+ *
+ * Based on ixdp-setup.c
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/i2c-gpio.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#define AVILA_SDA_PIN 7
+#define AVILA_SCL_PIN 6
+
+static struct flash_platform_data avila_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource avila_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device avila_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &avila_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &avila_flash_resource,
+};
+
+static struct i2c_gpio_platform_data avila_i2c_gpio_data = {
+ .sda_pin = AVILA_SDA_PIN,
+ .scl_pin = AVILA_SCL_PIN,
+};
+
+static struct platform_device avila_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &avila_i2c_gpio_data,
+ },
+};
+
+static struct resource avila_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct plat_serial8250_port avila_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device avila_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = avila_uart_data,
+ .num_resources = 2,
+ .resource = avila_uart_resources
+};
+
+static struct resource avila_pata_resources[] = {
+ {
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "intrq",
+ .start = IRQ_IXP4XX_GPIO12,
+ .end = IRQ_IXP4XX_GPIO12,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ixp4xx_pata_data avila_pata_data = {
+ .cs0_bits = 0xbfff0043,
+ .cs1_bits = 0xbfff0043,
+};
+
+static struct platform_device avila_pata = {
+ .name = "pata_ixp4xx_cf",
+ .id = 0,
+ .dev.platform_data = &avila_pata_data,
+ .num_resources = ARRAY_SIZE(avila_pata_resources),
+ .resource = avila_pata_resources,
+};
+
+static struct platform_device *avila_devices[] __initdata = {
+ &avila_i2c_gpio,
+ &avila_flash,
+ &avila_uart
+};
+
+static void __init avila_init(void)
+{
+ ixp4xx_sys_init();
+
+ avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ avila_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ platform_add_devices(avila_devices, ARRAY_SIZE(avila_devices));
+
+ avila_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(1);
+ avila_pata_resources[0].end = IXP4XX_EXP_BUS_END(1);
+
+ avila_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
+ avila_pata_resources[1].end = IXP4XX_EXP_BUS_END(2);
+
+ avila_pata_data.cs0_cfg = IXP4XX_EXP_CS1;
+ avila_pata_data.cs1_cfg = IXP4XX_EXP_CS2;
+
+ platform_device_register(&avila_pata);
+
+}
+
+MACHINE_START(AVILA, "Gateworks Avila Network Platform")
+ /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = avila_init,
+MACHINE_END
+
+ /*
+ * Loft is functionally equivalent to Avila except that it has a
+ * different number for the maximum PCI devices. The MACHINE
+ * structure below is identical to Avila except for the comment.
+ */
+#ifdef CONFIG_MACH_LOFT
+MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
+ /* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = avila_init,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
new file mode 100644
index 00000000..e9a58939
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -0,0 +1,493 @@
+/*
+ * arch/arm/mach-ixp4xx/common-pci.c
+ *
+ * IXP4XX PCI routines for all platforms
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003 Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <asm/dma-mapping.h>
+
+#include <asm/cputype.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <mach/hardware.h>
+
+
+/*
+ * IXP4xx PCI read function is dependent on whether we are
+ * running A0 or B0 (AppleGate) silicon.
+ */
+int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
+
+/*
+ * Base address for PCI regsiter region
+ */
+unsigned long ixp4xx_pci_reg_base = 0;
+
+/*
+ * PCI cfg an I/O routines are done by programming a
+ * command/byte enable register, and then read/writing
+ * the data from a data regsiter. We need to ensure
+ * these transactions are atomic or we will end up
+ * with corrupt data on the bus or in a driver.
+ */
+static DEFINE_SPINLOCK(ixp4xx_pci_lock);
+
+/*
+ * Read from PCI config space
+ */
+static void crp_read(u32 ad_cbe, u32 *data)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+ *PCI_CRP_AD_CBE = ad_cbe;
+ *data = *PCI_CRP_RDATA;
+ spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+}
+
+/*
+ * Write to PCI config space
+ */
+static void crp_write(u32 ad_cbe, u32 data)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+ *PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
+ *PCI_CRP_WDATA = data;
+ spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+}
+
+static inline int check_master_abort(void)
+{
+ /* check Master Abort bit after access */
+ unsigned long isr = *PCI_ISR;
+
+ if (isr & PCI_ISR_PFE) {
+ /* make sure the Master Abort bit is reset */
+ *PCI_ISR = PCI_ISR_PFE;
+ pr_debug("%s failed\n", __func__);
+ return 1;
+ }
+
+ return 0;
+}
+
+int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
+{
+ unsigned long flags;
+ int retval = 0;
+ int i;
+
+ spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+
+ *PCI_NP_AD = addr;
+
+ /*
+ * PCI workaround - only works if NP PCI space reads have
+ * no side effects!!! Read 8 times. last one will be good.
+ */
+ for (i = 0; i < 8; i++) {
+ *PCI_NP_CBE = cmd;
+ *data = *PCI_NP_RDATA;
+ *data = *PCI_NP_RDATA;
+ }
+
+ if(check_master_abort())
+ retval = 1;
+
+ spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+ return retval;
+}
+
+int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
+{
+ unsigned long flags;
+ int retval = 0;
+
+ spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+
+ *PCI_NP_AD = addr;
+
+ /* set up and execute the read */
+ *PCI_NP_CBE = cmd;
+
+ /* the result of the read is now in NP_RDATA */
+ *data = *PCI_NP_RDATA;
+
+ if(check_master_abort())
+ retval = 1;
+
+ spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+ return retval;
+}
+
+int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
+{
+ unsigned long flags;
+ int retval = 0;
+
+ spin_lock_irqsave(&ixp4xx_pci_lock, flags);
+
+ *PCI_NP_AD = addr;
+
+ /* set up the write */
+ *PCI_NP_CBE = cmd;
+
+ /* execute the write by writing to NP_WDATA */
+ *PCI_NP_WDATA = data;
+
+ if(check_master_abort())
+ retval = 1;
+
+ spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
+ return retval;
+}
+
+static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
+{
+ u32 addr;
+ if (!bus_num) {
+ /* type 0 */
+ addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) |
+ (where & ~3);
+ } else {
+ /* type 1 */
+ addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) |
+ ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
+ }
+ return addr;
+}
+
+/*
+ * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
+ * 0 and 3 are not valid indexes...
+ */
+static u32 bytemask[] = {
+ /*0*/ 0,
+ /*1*/ 0xff,
+ /*2*/ 0xffff,
+ /*3*/ 0,
+ /*4*/ 0xffffffff,
+};
+
+static u32 local_byte_lane_enable_bits(u32 n, int size)
+{
+ if (size == 1)
+ return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
+ if (size == 2)
+ return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
+ if (size == 4)
+ return 0;
+ return 0xffffffff;
+}
+
+static int local_read_config(int where, int size, u32 *value)
+{
+ u32 n, data;
+ pr_debug("local_read_config from %d size %d\n", where, size);
+ n = where % 4;
+ crp_read(where & ~3, &data);
+ *value = (data >> (8*n)) & bytemask[size];
+ pr_debug("local_read_config read %#x\n", *value);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int local_write_config(int where, int size, u32 value)
+{
+ u32 n, byte_enables, data;
+ pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
+ n = where % 4;
+ byte_enables = local_byte_lane_enable_bits(n, size);
+ if (byte_enables == 0xffffffff)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ data = value << (8*n);
+ crp_write((where & ~3) | byte_enables, data);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static u32 byte_lane_enable_bits(u32 n, int size)
+{
+ if (size == 1)
+ return (0xf & ~BIT(n)) << 4;
+ if (size == 2)
+ return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
+ if (size == 4)
+ return 0;
+ return 0xffffffff;
+}
+
+static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
+{
+ u32 n, byte_enables, addr, data;
+ u8 bus_num = bus->number;
+
+ pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
+ bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ *value = 0xffffffff;
+ n = where % 4;
+ byte_enables = byte_lane_enable_bits(n, size);
+ if (byte_enables == 0xffffffff)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ addr = ixp4xx_config_addr(bus_num, devfn, where);
+ if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = (data >> (8*n)) & bytemask[size];
+ pr_debug("read_config_byte read %#x\n", *value);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
+{
+ u32 n, byte_enables, addr, data;
+ u8 bus_num = bus->number;
+
+ pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
+ size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+ n = where % 4;
+ byte_enables = byte_lane_enable_bits(n, size);
+ if (byte_enables == 0xffffffff)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ addr = ixp4xx_config_addr(bus_num, devfn, where);
+ data = value << (8*n);
+ if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops ixp4xx_ops = {
+ .read = ixp4xx_pci_read_config,
+ .write = ixp4xx_pci_write_config,
+};
+
+/*
+ * PCI abort handler
+ */
+static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ u32 isr, status;
+
+ isr = *PCI_ISR;
+ local_read_config(PCI_STATUS, 2, &status);
+ pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
+ "status = %#x\n", addr, isr, status);
+
+ /* make sure the Master Abort bit is reset */
+ *PCI_ISR = PCI_ISR_PFE;
+ status |= PCI_STATUS_REC_MASTER_ABORT;
+ local_write_config(PCI_STATUS, 2, status);
+
+ /*
+ * If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+
+ return 0;
+}
+
+
+/*
+ * Setup DMA mask to 64MB on PCI devices. Ignore all other devices.
+ */
+static int ixp4xx_pci_platform_notify(struct device *dev)
+{
+ if(dev->bus == &pci_bus_type) {
+ *dev->dma_mask = SZ_64M - 1;
+ dev->coherent_dma_mask = SZ_64M - 1;
+ dmabounce_register_dev(dev, 2048, 4096);
+ }
+ return 0;
+}
+
+static int ixp4xx_pci_platform_notify_remove(struct device *dev)
+{
+ if(dev->bus == &pci_bus_type) {
+ dmabounce_unregister_dev(dev);
+ }
+ return 0;
+}
+
+int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+{
+ return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
+}
+
+void __init ixp4xx_pci_preinit(void)
+{
+ unsigned long cpuid = read_cpuid_id();
+
+ /*
+ * Determine which PCI read method to use.
+ * Rev 0 IXP425 requires workaround.
+ */
+ if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
+ printk("PCI: IXP42x A0 silicon detected - "
+ "PCI Non-Prefetch Workaround Enabled\n");
+ ixp4xx_pci_read = ixp4xx_pci_read_errata;
+ } else
+ ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
+
+
+ /* hook in our fault handler for PCI errors */
+ hook_fault_code(16+6, abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+
+ pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
+
+ /*
+ * We use identity AHB->PCI address translation
+ * in the 0x48000000 to 0x4bffffff address space
+ */
+ *PCI_PCIMEMBASE = 0x48494A4B;
+
+ /*
+ * We also use identity PCI->AHB address translation
+ * in 4 16MB BARs that begin at the physical memory start
+ */
+ *PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
+ ((PHYS_OFFSET & 0xFF000000) >> 8) +
+ ((PHYS_OFFSET & 0xFF000000) >> 16) +
+ ((PHYS_OFFSET & 0xFF000000) >> 24) +
+ 0x00010203;
+
+ if (*PCI_CSR & PCI_CSR_HOST) {
+ printk("PCI: IXP4xx is host\n");
+
+ pr_debug("setup BARs in controller\n");
+
+ /*
+ * We configure the PCI inbound memory windows to be
+ * 1:1 mapped to SDRAM
+ */
+ local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
+ local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
+ local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
+ local_write_config(PCI_BASE_ADDRESS_3, 4, PHYS_OFFSET + SZ_48M);
+
+ /*
+ * Enable CSR window at 64 MiB to allow PCI masters
+ * to continue prefetching past 64 MiB boundary.
+ */
+ local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
+
+ /*
+ * Enable the IO window to be way up high, at 0xfffffc00
+ */
+ local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
+ } else {
+ printk("PCI: IXP4xx is target - No bus scan performed\n");
+ }
+
+ printk("PCI: IXP4xx Using %s access for memory space\n",
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ "direct"
+#else
+ "indirect"
+#endif
+ );
+
+ pr_debug("clear error bits in ISR\n");
+ *PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
+
+ /*
+ * Set Initialize Complete in PCI Control Register: allow IXP4XX to
+ * respond to PCI configuration cycles. Specify that the AHB bus is
+ * operating in big endian mode. Set up byte lane swapping between
+ * little-endian PCI and the big-endian AHB bus
+ */
+#ifdef __ARMEB__
+ *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
+#else
+ *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
+#endif
+
+ pr_debug("DONE\n");
+}
+
+int ixp4xx_setup(int nr, struct pci_sys_data *sys)
+{
+ struct resource *res;
+
+ if (nr >= 1)
+ return 0;
+
+ res = kzalloc(sizeof(*res) * 2, GFP_KERNEL);
+ if (res == NULL) {
+ /*
+ * If we're out of memory this early, something is wrong,
+ * so we might as well catch it here.
+ */
+ panic("PCI: unable to allocate resources?\n");
+ }
+
+ local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+
+ res[0].name = "PCI I/O Space";
+ res[0].start = 0x00000000;
+ res[0].end = 0x0000ffff;
+ res[0].flags = IORESOURCE_IO;
+
+ res[1].name = "PCI Memory Space";
+ res[1].start = PCIBIOS_MIN_MEM;
+ res[1].end = PCIBIOS_MAX_MEM;
+ res[1].flags = IORESOURCE_MEM;
+
+ request_resource(&ioport_resource, &res[0]);
+ request_resource(&iomem_resource, &res[1]);
+
+ sys->resource[0] = &res[0];
+ sys->resource[1] = &res[1];
+ sys->resource[2] = NULL;
+
+ platform_notify = ixp4xx_pci_platform_notify;
+ platform_notify_remove = ixp4xx_pci_platform_notify_remove;
+
+ return 1;
+}
+
+struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys);
+}
+
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+ if (mask >= SZ_64M - 1)
+ return 0;
+
+ return -EIO;
+}
+
+EXPORT_SYMBOL(ixp4xx_pci_read);
+EXPORT_SYMBOL(ixp4xx_pci_write);
+EXPORT_SYMBOL(dma_set_coherent_mask);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
new file mode 100644
index 00000000..07772575
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -0,0 +1,502 @@
+/*
+ * arch/arm/mach-ixp4xx/common.c
+ *
+ * Generic code shared across all IXP4XX platforms
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright 2002 (c) Intel Corporation
+ * Copyright 2003-2004 (c) MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <mach/udc.h>
+#include <mach/hardware.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/sched_clock.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+static void __init ixp4xx_clocksource_init(void);
+static void __init ixp4xx_clockevent_init(void);
+static struct clock_event_device clockevent_ixp4xx;
+
+/*************************************************************************
+ * IXP4xx chipset I/O mapping
+ *************************************************************************/
+static struct map_desc ixp4xx_io_desc[] __initdata = {
+ { /* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
+ .virtual = IXP4XX_PERIPHERAL_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
+ .length = IXP4XX_PERIPHERAL_REGION_SIZE,
+ .type = MT_DEVICE
+ }, { /* Expansion Bus Config Registers */
+ .virtual = IXP4XX_EXP_CFG_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
+ .length = IXP4XX_EXP_CFG_REGION_SIZE,
+ .type = MT_DEVICE
+ }, { /* PCI Registers */
+ .virtual = IXP4XX_PCI_CFG_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
+ .length = IXP4XX_PCI_CFG_REGION_SIZE,
+ .type = MT_DEVICE
+ },
+#ifdef CONFIG_DEBUG_LL
+ { /* Debug UART mapping */
+ .virtual = IXP4XX_DEBUG_UART_BASE_VIRT,
+ .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
+ .length = IXP4XX_DEBUG_UART_REGION_SIZE,
+ .type = MT_DEVICE
+ }
+#endif
+};
+
+void __init ixp4xx_map_io(void)
+{
+ iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
+}
+
+
+/*************************************************************************
+ * IXP4xx chipset IRQ handling
+ *
+ * TODO: GPIO IRQs should be marked invalid until the user of the IRQ
+ * (be it PCI or something else) configures that GPIO line
+ * as an IRQ.
+ **************************************************************************/
+enum ixp4xx_irq_type {
+ IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
+};
+
+/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */
+static unsigned long long ixp4xx_irq_edge = 0;
+
+/*
+ * IRQ -> GPIO mapping table
+ */
+static signed char irq2gpio[32] = {
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, -1, -1,
+};
+
+int gpio_to_irq(int gpio)
+{
+ int irq;
+
+ for (irq = 0; irq < 32; irq++) {
+ if (irq2gpio[irq] == gpio)
+ return irq;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned int irq)
+{
+ int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL;
+
+ if (gpio == -1)
+ return -EINVAL;
+
+ return gpio;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
+static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ int line = irq2gpio[d->irq];
+ u32 int_style;
+ enum ixp4xx_irq_type irq_type;
+ volatile u32 *int_reg;
+
+ /*
+ * Only for GPIO IRQs
+ */
+ if (line < 0)
+ return -EINVAL;
+
+ switch (type){
+ case IRQ_TYPE_EDGE_BOTH:
+ int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
+ irq_type = IXP4XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
+ irq_type = IXP4XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
+ irq_type = IXP4XX_IRQ_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
+ irq_type = IXP4XX_IRQ_LEVEL;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
+ irq_type = IXP4XX_IRQ_LEVEL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (irq_type == IXP4XX_IRQ_EDGE)
+ ixp4xx_irq_edge |= (1 << d->irq);
+ else
+ ixp4xx_irq_edge &= ~(1 << d->irq);
+
+ if (line >= 8) { /* pins 8-15 */
+ line -= 8;
+ int_reg = IXP4XX_GPIO_GPIT2R;
+ } else { /* pins 0-7 */
+ int_reg = IXP4XX_GPIO_GPIT1R;
+ }
+
+ /* Clear the style for the appropriate pin */
+ *int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
+ (line * IXP4XX_GPIO_STYLE_SIZE));
+
+ *IXP4XX_GPIO_GPISR = (1 << line);
+
+ /* Set the new style */
+ *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
+
+ /* Configure the line as an input */
+ gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN);
+
+ return 0;
+}
+
+static void ixp4xx_irq_mask(struct irq_data *d)
+{
+ if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
+ *IXP4XX_ICMR2 &= ~(1 << (d->irq - 32));
+ else
+ *IXP4XX_ICMR &= ~(1 << d->irq);
+}
+
+static void ixp4xx_irq_ack(struct irq_data *d)
+{
+ int line = (d->irq < 32) ? irq2gpio[d->irq] : -1;
+
+ if (line >= 0)
+ *IXP4XX_GPIO_GPISR = (1 << line);
+}
+
+/*
+ * Level triggered interrupts on GPIO lines can only be cleared when the
+ * interrupt condition disappears.
+ */
+static void ixp4xx_irq_unmask(struct irq_data *d)
+{
+ if (!(ixp4xx_irq_edge & (1 << d->irq)))
+ ixp4xx_irq_ack(d);
+
+ if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
+ *IXP4XX_ICMR2 |= (1 << (d->irq - 32));
+ else
+ *IXP4XX_ICMR |= (1 << d->irq);
+}
+
+static struct irq_chip ixp4xx_irq_chip = {
+ .name = "IXP4xx",
+ .irq_ack = ixp4xx_irq_ack,
+ .irq_mask = ixp4xx_irq_mask,
+ .irq_unmask = ixp4xx_irq_unmask,
+ .irq_set_type = ixp4xx_set_irq_type,
+};
+
+void __init ixp4xx_init_irq(void)
+{
+ int i = 0;
+
+ /* Route all sources to IRQ instead of FIQ */
+ *IXP4XX_ICLR = 0x0;
+
+ /* Disable all interrupt */
+ *IXP4XX_ICMR = 0x0;
+
+ if (cpu_is_ixp46x() || cpu_is_ixp43x()) {
+ /* Route upper 32 sources to IRQ instead of FIQ */
+ *IXP4XX_ICLR2 = 0x00;
+
+ /* Disable upper 32 interrupts */
+ *IXP4XX_ICMR2 = 0x00;
+ }
+
+ /* Default to all level triggered */
+ for(i = 0; i < NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &ixp4xx_irq_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
+
+
+/*************************************************************************
+ * IXP4xx timer tick
+ * We use OS timer1 on the CPU for the timer tick and the timestamp
+ * counter as a source of real clock ticks to account for missed jiffies.
+ *************************************************************************/
+
+static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* Clear Pending Interrupt by writing '1' to it */
+ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ixp4xx_timer_irq = {
+ .name = "timer1",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = ixp4xx_timer_interrupt,
+ .dev_id = &clockevent_ixp4xx,
+};
+
+void __init ixp4xx_timer_init(void)
+{
+ /* Reset/disable counter */
+ *IXP4XX_OSRT1 = 0;
+
+ /* Clear Pending Interrupt by writing '1' to it */
+ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
+
+ /* Reset time-stamp counter */
+ *IXP4XX_OSTS = 0;
+
+ /* Connect the interrupt handler and enable the interrupt */
+ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
+
+ ixp4xx_clocksource_init();
+ ixp4xx_clockevent_init();
+}
+
+struct sys_timer ixp4xx_timer = {
+ .init = ixp4xx_timer_init,
+};
+
+static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
+
+void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
+{
+ memcpy(&ixp4xx_udc_info, info, sizeof *info);
+}
+
+static struct resource ixp4xx_udc_resources[] = {
+ [0] = {
+ .start = 0xc800b000,
+ .end = 0xc800bfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IXP4XX_USB,
+ .end = IRQ_IXP4XX_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * USB device controller. The IXP4xx uses the same controller as PXA25X,
+ * so we just use the same device.
+ */
+static struct platform_device ixp4xx_udc_device = {
+ .name = "pxa25x-udc",
+ .id = -1,
+ .num_resources = 2,
+ .resource = ixp4xx_udc_resources,
+ .dev = {
+ .platform_data = &ixp4xx_udc_info,
+ },
+};
+
+static struct platform_device *ixp4xx_devices[] __initdata = {
+ &ixp4xx_udc_device,
+};
+
+static struct resource ixp46x_i2c_resources[] = {
+ [0] = {
+ .start = 0xc8011000,
+ .end = 0xc801101c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IXP4XX_I2C,
+ .end = IRQ_IXP4XX_I2C,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+/*
+ * I2C controller. The IXP46x uses the same block as the IOP3xx, so
+ * we just use the same device name.
+ */
+static struct platform_device ixp46x_i2c_controller = {
+ .name = "IOP3xx-I2C",
+ .id = 0,
+ .num_resources = 2,
+ .resource = ixp46x_i2c_resources
+};
+
+static struct platform_device *ixp46x_devices[] __initdata = {
+ &ixp46x_i2c_controller
+};
+
+unsigned long ixp4xx_exp_bus_size;
+EXPORT_SYMBOL(ixp4xx_exp_bus_size);
+
+void __init ixp4xx_sys_init(void)
+{
+ ixp4xx_exp_bus_size = SZ_16M;
+
+ platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
+
+ if (cpu_is_ixp46x()) {
+ int region;
+
+ platform_add_devices(ixp46x_devices,
+ ARRAY_SIZE(ixp46x_devices));
+
+ for (region = 0; region < 7; region++) {
+ if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
+ ixp4xx_exp_bus_size = SZ_32M;
+ break;
+ }
+ }
+ }
+
+ printk("IXP4xx: Using %luMiB expansion bus window size\n",
+ ixp4xx_exp_bus_size >> 20);
+}
+
+/*
+ * sched_clock()
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = *IXP4XX_OSTS;
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace ixp4xx_update_sched_clock(void)
+{
+ u32 cyc = *IXP4XX_OSTS;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/*
+ * clocksource
+ */
+
+static cycle_t ixp4xx_clocksource_read(struct clocksource *c)
+{
+ return *IXP4XX_OSTS;
+}
+
+unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
+EXPORT_SYMBOL(ixp4xx_timer_freq);
+static void __init ixp4xx_clocksource_init(void)
+{
+ init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
+
+ clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
+ ixp4xx_clocksource_read);
+}
+
+/*
+ * clockevents
+ */
+static int ixp4xx_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
+
+ *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
+
+ return 0;
+}
+
+static void ixp4xx_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
+ unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
+ opts = IXP4XX_OST_ENABLE;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* period set by 'set next_event' */
+ osrt = 0;
+ opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ opts &= ~IXP4XX_OST_ENABLE;
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ opts |= IXP4XX_OST_ENABLE;
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ default:
+ osrt = opts = 0;
+ break;
+ }
+
+ *IXP4XX_OSRT1 = osrt | opts;
+}
+
+static struct clock_event_device clockevent_ixp4xx = {
+ .name = "ixp4xx timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .shift = 24,
+ .set_mode = ixp4xx_set_mode,
+ .set_next_event = ixp4xx_set_next_event,
+};
+
+static void __init ixp4xx_clockevent_init(void)
+{
+ clockevent_ixp4xx.mult = div_sc(IXP4XX_TIMER_FREQ, NSEC_PER_SEC,
+ clockevent_ixp4xx.shift);
+ clockevent_ixp4xx.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);
+ clockevent_ixp4xx.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_ixp4xx);
+ clockevent_ixp4xx.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_ixp4xx);
+}
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
new file mode 100644
index 00000000..37fda7d6
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-ixp4xx/coyote-pci.c
+ *
+ * PCI setup routines for ADI Engineering Coyote platform
+ *
+ * Copyright (C) 2002 Jungo Software Technologies.
+ * Copyright (C) 2003 MontaVista Softwrae, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@mvista.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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+#define SLOT0_DEVID 14
+#define SLOT1_DEVID 15
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define SLOT0_INTA 6
+#define SLOT1_INTA 11
+
+void __init coyote_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init coyote_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == SLOT0_DEVID)
+ return IXP4XX_GPIO_IRQ(SLOT0_INTA);
+ else if (slot == SLOT1_DEVID)
+ return IXP4XX_GPIO_IRQ(SLOT1_INTA);
+ else return -1;
+}
+
+struct hw_pci coyote_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = coyote_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = coyote_map_irq,
+};
+
+int __init coyote_pci_init(void)
+{
+ if (machine_is_adi_coyote())
+ pci_common_init(&coyote_pci);
+ return 0;
+}
+
+subsys_initcall(coyote_pci_init);
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
new file mode 100644
index 00000000..355e3de3
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -0,0 +1,134 @@
+/*
+ * arch/arm/mach-ixp4xx/coyote-setup.c
+ *
+ * Board setup for ADI Engineering and IXDGP425 boards
+ *
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#define COYOTE_IDE_BASE_PHYS IXP4XX_EXP_BUS_BASE(3)
+#define COYOTE_IDE_BASE_VIRT 0xFFFE1000
+#define COYOTE_IDE_REGION_SIZE 0x1000
+
+#define COYOTE_IDE_DATA_PORT 0xFFFE10E0
+#define COYOTE_IDE_CTRL_PORT 0xFFFE10FC
+#define COYOTE_IDE_ERROR_PORT 0xFFFE10E2
+#define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5
+
+static struct flash_platform_data coyote_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource coyote_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device coyote_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &coyote_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &coyote_flash_resource,
+};
+
+static struct resource coyote_uart_resource = {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port coyote_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device coyote_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = coyote_uart_data,
+ },
+ .num_resources = 1,
+ .resource = &coyote_uart_resource,
+};
+
+static struct platform_device *coyote_devices[] __initdata = {
+ &coyote_flash,
+ &coyote_uart
+};
+
+static void __init coyote_init(void)
+{
+ ixp4xx_sys_init();
+
+ coyote_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ coyote_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
+ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ if (machine_is_ixdpg425()) {
+ coyote_uart_data[0].membase =
+ (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET);
+ coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS;
+ coyote_uart_data[0].irq = IRQ_IXP4XX_UART1;
+ }
+
+ platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
+}
+
+#ifdef CONFIG_ARCH_ADI_COYOTE
+MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = coyote_init,
+MACHINE_END
+#endif
+
+/*
+ * IXDPG425 is identical to Coyote except for which serial port
+ * is connected.
+ */
+#ifdef CONFIG_MACH_IXDPG425
+MACHINE_START(IXDPG425, "Intel IXDPG425")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = coyote_init,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c
new file mode 100644
index 00000000..c7612010
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c
@@ -0,0 +1,80 @@
+/*
+ * DSM-G600 board-level PCI initialization
+ *
+ * Copyright (C) 2006 Tower Technologies
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV 4
+#define IRQ_LINES 3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 11
+#define INTB 10
+#define INTC 9
+#define INTD 8
+#define INTE 7
+#define INTF 6
+
+void __init dsmg600_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[MAX_DEV][IRQ_LINES] = {
+ { IXP4XX_GPIO_IRQ(INTE), -1, -1 },
+ { IXP4XX_GPIO_IRQ(INTA), -1, -1 },
+ { IXP4XX_GPIO_IRQ(INTB), IXP4XX_GPIO_IRQ(INTC),
+ IXP4XX_GPIO_IRQ(INTD) },
+ { IXP4XX_GPIO_IRQ(INTF), -1, -1 },
+ };
+
+ if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+ return pci_irq_table[slot - 1][pin - 1];
+
+ return -1;
+}
+
+struct hw_pci __initdata dsmg600_pci = {
+ .nr_controllers = 1,
+ .preinit = dsmg600_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = dsmg600_map_irq,
+};
+
+int __init dsmg600_pci_init(void)
+{
+ if (machine_is_dsmg600())
+ pci_common_init(&dsmg600_pci);
+
+ return 0;
+}
+
+subsys_initcall(dsmg600_pci_init);
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
new file mode 100644
index 00000000..d398229c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -0,0 +1,287 @@
+/*
+ * DSM-G600 board-setup
+ *
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ * Copyright (C) 2006 Tower Technologies
+ *
+ * based on ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * based on nslu2-power.c:
+ * Copyright (C) 2005 Tower Technologies
+ * based on nslu2-io.c:
+ * Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Author: Michael Westerhof <mwester@dls.net>
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ */
+
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/reboot.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/time.h>
+#include <asm/gpio.h>
+
+#define DSMG600_SDA_PIN 5
+#define DSMG600_SCL_PIN 4
+
+/* DSM-G600 Timer Setting */
+#define DSMG600_FREQ 66000000
+
+/* Buttons */
+#define DSMG600_PB_GPIO 15 /* power button */
+#define DSMG600_RB_GPIO 3 /* reset button */
+
+/* Power control */
+#define DSMG600_PO_GPIO 2 /* power off */
+
+/* LEDs */
+#define DSMG600_LED_PWR_GPIO 0
+#define DSMG600_LED_WLAN_GPIO 14
+
+static struct flash_platform_data dsmg600_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource dsmg600_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device dsmg600_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev.platform_data = &dsmg600_flash_data,
+ .num_resources = 1,
+ .resource = &dsmg600_flash_resource,
+};
+
+static struct i2c_gpio_platform_data dsmg600_i2c_gpio_data = {
+ .sda_pin = DSMG600_SDA_PIN,
+ .scl_pin = DSMG600_SCL_PIN,
+};
+
+static struct platform_device dsmg600_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &dsmg600_i2c_gpio_data,
+ },
+};
+
+static struct i2c_board_info __initdata dsmg600_i2c_board_info [] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static struct gpio_led dsmg600_led_pins[] = {
+ {
+ .name = "dsmg600:green:power",
+ .gpio = DSMG600_LED_PWR_GPIO,
+ },
+ {
+ .name = "dsmg600:green:wlan",
+ .gpio = DSMG600_LED_WLAN_GPIO,
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data dsmg600_led_data = {
+ .num_leds = ARRAY_SIZE(dsmg600_led_pins),
+ .leds = dsmg600_led_pins,
+};
+
+static struct platform_device dsmg600_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &dsmg600_led_data,
+};
+
+static struct resource dsmg600_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port dsmg600_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device dsmg600_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = dsmg600_uart_data,
+ .num_resources = ARRAY_SIZE(dsmg600_uart_resources),
+ .resource = dsmg600_uart_resources,
+};
+
+static struct platform_device *dsmg600_devices[] __initdata = {
+ &dsmg600_i2c_gpio,
+ &dsmg600_flash,
+ &dsmg600_leds,
+};
+
+static void dsmg600_power_off(void)
+{
+ /* enable the pwr cntl gpio */
+ gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT);
+
+ /* poweroff */
+ gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+/* This is used to make sure the power-button pusher is serious. The button
+ * must be held until the value of this counter reaches zero.
+ */
+static int power_button_countdown;
+
+/* Must hold the button down for at least this many counts to be processed */
+#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
+
+static void dsmg600_power_handler(unsigned long data);
+static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
+
+static void dsmg600_power_handler(unsigned long data)
+{
+ /* This routine is called twice per second to check the
+ * state of the power button.
+ */
+
+ if (gpio_get_value(DSMG600_PB_GPIO)) {
+
+ /* IO Pin is 1 (button pushed) */
+ if (power_button_countdown > 0)
+ power_button_countdown--;
+
+ } else {
+
+ /* Done on button release, to allow for auto-power-on mods. */
+ if (power_button_countdown == 0) {
+ /* Signal init to do the ctrlaltdel action,
+ * this will bypass init if it hasn't started
+ * and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ /* Change the state of the power LED to "blink" */
+ gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+ } else {
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+ }
+ }
+
+ mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset, it shuts the machine down directly. */
+ machine_power_off();
+
+ return IRQ_HANDLED;
+}
+
+static void __init dsmg600_timer_init(void)
+{
+ /* The xtal on this machine is non-standard. */
+ ixp4xx_timer_freq = DSMG600_FREQ;
+
+ /* Call standard timer_init function. */
+ ixp4xx_timer_init();
+}
+
+static struct sys_timer dsmg600_timer = {
+ .init = dsmg600_timer_init,
+};
+
+static void __init dsmg600_init(void)
+{
+ ixp4xx_sys_init();
+
+ /* Make sure that GPIO14 and GPIO15 are not used as clocks */
+ *IXP4XX_GPIO_GPCLKR = 0;
+
+ dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ dsmg600_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ i2c_register_board_info(0, dsmg600_i2c_board_info,
+ ARRAY_SIZE(dsmg600_i2c_board_info));
+
+ /* The UART is required on the DSM-G600 (Redboot cannot use the
+ * NIC) -- do it here so that it does *not* get removed if
+ * platform_add_devices fails!
+ */
+ (void)platform_device_register(&dsmg600_uart);
+
+ platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
+
+ pm_power_off = dsmg600_power_off;
+
+ if (request_irq(gpio_to_irq(DSMG600_RB_GPIO), &dsmg600_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "DSM-G600 reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(DSMG600_RB_GPIO));
+ }
+
+ /* The power button on the D-Link DSM-G600 is on GPIO 15, but
+ * it cannot handle interrupts on that GPIO line. So we'll
+ * have to poll it with a kernel timer.
+ */
+
+ /* Make sure that the power button GPIO is set up as an input */
+ gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
+
+ /* Set the initial value for the power button IRQ handler */
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+
+ mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
+}
+
+MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
+ /* Maintainer: www.nslu2-linux.org */
+ .boot_params = 0x00000100,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &dsmg600_timer,
+ .init_machine = dsmg600_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c
new file mode 100644
index 00000000..44ccde9d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-pci.c
@@ -0,0 +1,76 @@
+/*
+ * arch/arch/mach-ixp4xx/fsg-pci.c
+ *
+ * FSG board-level PCI initialization
+ *
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV 3
+#define IRQ_LINES 3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 6
+#define INTB 7
+#define INTC 5
+
+void __init fsg_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init fsg_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[IRQ_LINES] = {
+ IXP4XX_GPIO_IRQ(INTC),
+ IXP4XX_GPIO_IRQ(INTB),
+ IXP4XX_GPIO_IRQ(INTA),
+ };
+
+ int irq = -1;
+ slot -= 11;
+
+ if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+ irq = pci_irq_table[slot - 1];
+ printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
+ __func__, slot, pin, irq);
+
+ return irq;
+}
+
+struct hw_pci fsg_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = fsg_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = fsg_map_irq,
+};
+
+int __init fsg_pci_init(void)
+{
+ if (machine_is_fsg())
+ pci_common_init(&fsg_pci);
+ return 0;
+}
+
+subsys_initcall(fsg_pci_init);
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
new file mode 100644
index 00000000..727ee39c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -0,0 +1,279 @@
+/*
+ * arch/arm/mach-ixp4xx/fsg-setup.c
+ *
+ * FSG board-setup
+ *
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ *
+ * based on ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * based on nslu2-power.c
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/if_ether.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/reboot.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/gpio.h>
+
+#define FSG_SDA_PIN 12
+#define FSG_SCL_PIN 13
+
+#define FSG_SB_GPIO 4 /* sync button */
+#define FSG_RB_GPIO 9 /* reset button */
+#define FSG_UB_GPIO 10 /* usb button */
+
+static struct flash_platform_data fsg_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource fsg_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device fsg_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsg_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &fsg_flash_resource,
+};
+
+static struct i2c_gpio_platform_data fsg_i2c_gpio_data = {
+ .sda_pin = FSG_SDA_PIN,
+ .scl_pin = FSG_SCL_PIN,
+};
+
+static struct platform_device fsg_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsg_i2c_gpio_data,
+ },
+};
+
+static struct i2c_board_info __initdata fsg_i2c_board_info [] = {
+ {
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ },
+};
+
+static struct resource fsg_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port fsg_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device fsg_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = fsg_uart_data,
+ },
+ .num_resources = ARRAY_SIZE(fsg_uart_resources),
+ .resource = fsg_uart_resources,
+};
+
+static struct platform_device fsg_leds = {
+ .name = "fsg-led",
+ .id = -1,
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info fsg_plat_eth[] = {
+ {
+ .phy = 5,
+ .rxq = 3,
+ .txreadyq = 20,
+ }, {
+ .phy = 4,
+ .rxq = 4,
+ .txreadyq = 21,
+ }
+};
+
+static struct platform_device fsg_eth[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev = {
+ .platform_data = fsg_plat_eth,
+ },
+ }, {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEC,
+ .dev = {
+ .platform_data = fsg_plat_eth + 1,
+ },
+ }
+};
+
+static struct platform_device *fsg_devices[] __initdata = {
+ &fsg_i2c_gpio,
+ &fsg_flash,
+ &fsg_leds,
+ &fsg_eth[0],
+ &fsg_eth[1],
+};
+
+static irqreturn_t fsg_power_handler(int irq, void *dev_id)
+{
+ /* Signal init to do the ctrlaltdel action, this will bypass init if
+ * it hasn't started and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t fsg_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset which does an emergency reboot. */
+ printk(KERN_INFO "Restarting system.\n");
+ machine_restart(NULL);
+
+ /* This should never be reached. */
+ return IRQ_HANDLED;
+}
+
+static void __init fsg_init(void)
+{
+ uint8_t __iomem *f;
+
+ ixp4xx_sys_init();
+
+ fsg_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ fsg_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ /* Configure CS2 for operation, 8bit and writable */
+ *IXP4XX_EXP_CS2 = 0xbfff0002;
+
+ i2c_register_board_info(0, fsg_i2c_board_info,
+ ARRAY_SIZE(fsg_i2c_board_info));
+
+ /* This is only useful on a modified machine, but it is valuable
+ * to have it first in order to see debug messages, and so that
+ * it does *not* get removed if platform_add_devices fails!
+ */
+ (void)platform_device_register(&fsg_uart);
+
+ platform_add_devices(fsg_devices, ARRAY_SIZE(fsg_devices));
+
+ if (request_irq(gpio_to_irq(FSG_RB_GPIO), &fsg_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "FSG reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(FSG_RB_GPIO));
+ }
+
+ if (request_irq(gpio_to_irq(FSG_SB_GPIO), &fsg_power_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "FSG power button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Power Button IRQ %d not available\n",
+ gpio_to_irq(FSG_SB_GPIO));
+ }
+
+ /*
+ * Map in a portion of the flash and read the MAC addresses.
+ * Since it is stored in BE in the flash itself, we need to
+ * byteswap it if we're in LE mode.
+ */
+ f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000);
+ if (f) {
+#ifdef __ARMEB__
+ int i;
+ for (i = 0; i < 6; i++) {
+ fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i);
+ fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i);
+ }
+#else
+
+ /*
+ Endian-swapped reads from unaligned addresses are
+ required to extract the two MACs from the big-endian
+ Redboot config area in flash.
+ */
+
+ fsg_plat_eth[0].hwaddr[0] = readb(f + 0x3C0421);
+ fsg_plat_eth[0].hwaddr[1] = readb(f + 0x3C0420);
+ fsg_plat_eth[0].hwaddr[2] = readb(f + 0x3C0427);
+ fsg_plat_eth[0].hwaddr[3] = readb(f + 0x3C0426);
+ fsg_plat_eth[0].hwaddr[4] = readb(f + 0x3C0425);
+ fsg_plat_eth[0].hwaddr[5] = readb(f + 0x3C0424);
+
+ fsg_plat_eth[1].hwaddr[0] = readb(f + 0x3C0439);
+ fsg_plat_eth[1].hwaddr[1] = readb(f + 0x3C043F);
+ fsg_plat_eth[1].hwaddr[2] = readb(f + 0x3C043E);
+ fsg_plat_eth[1].hwaddr[3] = readb(f + 0x3C043D);
+ fsg_plat_eth[1].hwaddr[4] = readb(f + 0x3C043C);
+ fsg_plat_eth[1].hwaddr[5] = readb(f + 0x3C0443);
+#endif
+ iounmap(f);
+ }
+ printk(KERN_INFO "FSG: Using MAC address %pM for port 0\n",
+ fsg_plat_eth[0].hwaddr);
+ printk(KERN_INFO "FSG: Using MAC address %pM for port 1\n",
+ fsg_plat_eth[1].hwaddr);
+
+}
+
+MACHINE_START(FSG, "Freecom FSG-3")
+ /* Maintainer: www.nslu2-linux.org */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = fsg_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
new file mode 100644
index 00000000..fc112416
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c
@@ -0,0 +1,63 @@
+/*
+ * arch/arch/mach-ixp4xx/gateway7001-pci.c
+ *
+ * PCI setup routines for Gateway 7001
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-pci.c:
+ * Copyright (C) 2002 Jungo Software Technologies.
+ * Copyright (C) 2003 MontaVista Softwrae, Inc.
+ *
+ * Maintainer: Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <asm/mach/pci.h>
+
+void __init gateway7001_pci_preinit(void)
+{
+ irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == 1)
+ return IRQ_IXP4XX_GPIO11;
+ else if (slot == 2)
+ return IRQ_IXP4XX_GPIO10;
+ else return -1;
+}
+
+struct hw_pci gateway7001_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = gateway7001_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = gateway7001_map_irq,
+};
+
+int __init gateway7001_pci_init(void)
+{
+ if (machine_is_gateway7001())
+ pci_common_init(&gateway7001_pci);
+ return 0;
+}
+
+subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
new file mode 100644
index 00000000..9dc0b4ea
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/mach-ixp4xx/gateway7001-setup.c
+ *
+ * Board setup for the Gateway 7001 board
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-setup.c:
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Imre Kaloz <Kaloz@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data gateway7001_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource gateway7001_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gateway7001_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &gateway7001_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &gateway7001_flash_resource,
+};
+
+static struct resource gateway7001_uart_resource = {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port gateway7001_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device gateway7001_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = gateway7001_uart_data,
+ },
+ .num_resources = 1,
+ .resource = &gateway7001_uart_resource,
+};
+
+static struct platform_device *gateway7001_devices[] __initdata = {
+ &gateway7001_flash,
+ &gateway7001_uart
+};
+
+static void __init gateway7001_init(void)
+{
+ ixp4xx_sys_init();
+
+ gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
+ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
+}
+
+#ifdef CONFIG_MACH_GATEWAY7001
+MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = gateway7001_init,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
new file mode 100644
index 00000000..3e8c0e33
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -0,0 +1,504 @@
+/*
+ * Goramo MultiLink router platform code
+ * Copyright (C) 2006-2009 Krzysztof Halasa <khc@pm.waw.pl>
+ */
+
+#include <linux/delay.h>
+#include <linux/hdlc.h>
+#include <linux/i2c-gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/serial_8250.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/pci.h>
+
+#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
+#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
+#define SLOT_MPCI 0x0D /* IDSEL = AD19 */
+#define SLOT_NEC 0x0E /* IDSEL = AD18 */
+
+/* GPIO lines */
+#define GPIO_SCL 0
+#define GPIO_SDA 1
+#define GPIO_STR 2
+#define GPIO_IRQ_NEC 3
+#define GPIO_IRQ_ETHA 4
+#define GPIO_IRQ_ETHB 5
+#define GPIO_HSS0_DCD_N 6
+#define GPIO_HSS1_DCD_N 7
+#define GPIO_UART0_DCD 8
+#define GPIO_UART1_DCD 9
+#define GPIO_HSS0_CTS_N 10
+#define GPIO_HSS1_CTS_N 11
+#define GPIO_IRQ_MPCI 12
+#define GPIO_HSS1_RTS_N 13
+#define GPIO_HSS0_RTS_N 14
+/* GPIO15 is not connected */
+
+/* Control outputs from 74HC4094 */
+#define CONTROL_HSS0_CLK_INT 0
+#define CONTROL_HSS1_CLK_INT 1
+#define CONTROL_HSS0_DTR_N 2
+#define CONTROL_HSS1_DTR_N 3
+#define CONTROL_EXT 4
+#define CONTROL_AUTO_RESET 5
+#define CONTROL_PCI_RESET_N 6
+#define CONTROL_EEPROM_WC_N 7
+
+/* offsets from start of flash ROM = 0x50000000 */
+#define CFG_ETH0_ADDRESS 0x40 /* 6 bytes */
+#define CFG_ETH1_ADDRESS 0x46 /* 6 bytes */
+#define CFG_REV 0x4C /* u32 */
+#define CFG_SDRAM_SIZE 0x50 /* u32 */
+#define CFG_SDRAM_CONF 0x54 /* u32 */
+#define CFG_SDRAM_MODE 0x58 /* u32 */
+#define CFG_SDRAM_REFRESH 0x5C /* u32 */
+
+#define CFG_HW_BITS 0x60 /* u32 */
+#define CFG_HW_USB_PORTS 0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
+#define CFG_HW_HAS_PCI_SLOT 0x00000008
+#define CFG_HW_HAS_ETH0 0x00000010
+#define CFG_HW_HAS_ETH1 0x00000020
+#define CFG_HW_HAS_HSS0 0x00000040
+#define CFG_HW_HAS_HSS1 0x00000080
+#define CFG_HW_HAS_UART0 0x00000100
+#define CFG_HW_HAS_UART1 0x00000200
+#define CFG_HW_HAS_EEPROM 0x00000400
+
+#define FLASH_CMD_READ_ARRAY 0xFF
+#define FLASH_CMD_READ_ID 0x90
+#define FLASH_SER_OFF 0x102 /* 0x81 in 16-bit mode */
+
+static u32 hw_bits = 0xFFFFFFFD; /* assume all hardware present */;
+static u8 control_value;
+
+static void set_scl(u8 value)
+{
+ gpio_line_set(GPIO_SCL, !!value);
+ udelay(3);
+}
+
+static void set_sda(u8 value)
+{
+ gpio_line_set(GPIO_SDA, !!value);
+ udelay(3);
+}
+
+static void set_str(u8 value)
+{
+ gpio_line_set(GPIO_STR, !!value);
+ udelay(3);
+}
+
+static inline void set_control(int line, int value)
+{
+ if (value)
+ control_value |= (1 << line);
+ else
+ control_value &= ~(1 << line);
+}
+
+
+static void output_control(void)
+{
+ int i;
+
+ gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
+
+ for (i = 0; i < 8; i++) {
+ set_scl(0);
+ set_sda(control_value & (0x80 >> i)); /* MSB first */
+ set_scl(1); /* active edge */
+ }
+
+ set_str(1);
+ set_str(0);
+
+ set_scl(0);
+ set_sda(1); /* Be ready for START */
+ set_scl(1);
+}
+
+
+static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
+
+static int hss_set_clock(int port, unsigned int clock_type)
+{
+ int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
+
+ switch (clock_type) {
+ case CLOCK_DEFAULT:
+ case CLOCK_EXT:
+ set_control(ctrl_int, 0);
+ output_control();
+ return CLOCK_EXT;
+
+ case CLOCK_INT:
+ set_control(ctrl_int, 1);
+ output_control();
+ return CLOCK_INT;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static irqreturn_t hss_dcd_irq(int irq, void *pdev)
+{
+ int i, port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
+ gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+ set_carrier_cb_tab[port](pdev, !i);
+ return IRQ_HANDLED;
+}
+
+
+static int hss_open(int port, void *pdev,
+ void (*set_carrier_cb)(void *pdev, int carrier))
+{
+ int i, irq;
+
+ if (!port)
+ irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
+ else
+ irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
+
+ gpio_line_get(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N, &i);
+ set_carrier_cb(pdev, !i);
+
+ set_carrier_cb_tab[!!port] = set_carrier_cb;
+
+ if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
+ printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
+ irq, i);
+ return i;
+ }
+
+ set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
+ output_control();
+ gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
+ return 0;
+}
+
+static void hss_close(int port, void *pdev)
+{
+ free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
+ IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
+ set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
+
+ set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
+ output_control();
+ gpio_line_set(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
+}
+
+
+/* Flash memory */
+static struct flash_platform_data flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device device_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = { .platform_data = &flash_data },
+ .num_resources = 1,
+ .resource = &flash_resource,
+};
+
+
+/* I^2C interface */
+static struct i2c_gpio_platform_data i2c_data = {
+ .sda_pin = GPIO_SDA,
+ .scl_pin = GPIO_SCL,
+};
+
+static struct platform_device device_i2c = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = { .platform_data = &i2c_data },
+};
+
+
+/* IXP425 2 UART ports */
+static struct resource uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char __iomem *)IXP4XX_UART1_BASE_VIRT +
+ REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char __iomem *)IXP4XX_UART2_BASE_VIRT +
+ REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device device_uarts = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = uart_data,
+ .num_resources = 2,
+ .resource = uart_resources,
+};
+
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info eth_plat[] = {
+ {
+ .phy = 0,
+ .rxq = 3,
+ .txreadyq = 32,
+ }, {
+ .phy = 1,
+ .rxq = 4,
+ .txreadyq = 33,
+ }
+};
+
+static struct platform_device device_eth_tab[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev.platform_data = eth_plat,
+ }, {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEC,
+ .dev.platform_data = eth_plat + 1,
+ }
+};
+
+
+/* IXP425 2 synchronous serial ports */
+static struct hss_plat_info hss_plat[] = {
+ {
+ .set_clock = hss_set_clock,
+ .open = hss_open,
+ .close = hss_close,
+ .txreadyq = 34,
+ }, {
+ .set_clock = hss_set_clock,
+ .open = hss_open,
+ .close = hss_close,
+ .txreadyq = 35,
+ }
+};
+
+static struct platform_device device_hss_tab[] = {
+ {
+ .name = "ixp4xx_hss",
+ .id = 0,
+ .dev.platform_data = hss_plat,
+ }, {
+ .name = "ixp4xx_hss",
+ .id = 1,
+ .dev.platform_data = hss_plat + 1,
+ }
+};
+
+
+static struct platform_device *device_tab[6] __initdata = {
+ &device_flash, /* index 0 */
+};
+
+static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
+{
+#ifdef __ARMEB__
+ return __raw_readb(flash + addr);
+#else
+ return __raw_readb(flash + (addr ^ 3));
+#endif
+}
+
+static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
+{
+#ifdef __ARMEB__
+ return __raw_readw(flash + addr);
+#else
+ return __raw_readw(flash + (addr ^ 2));
+#endif
+}
+
+static void __init gmlr_init(void)
+{
+ u8 __iomem *flash;
+ int i, devices = 1; /* flash */
+
+ ixp4xx_sys_init();
+
+ if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
+ printk(KERN_ERR "goramo-mlr: unable to access system"
+ " configuration data\n");
+ else {
+ system_rev = __raw_readl(flash + CFG_REV);
+ hw_bits = __raw_readl(flash + CFG_HW_BITS);
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ eth_plat[0].hwaddr[i] =
+ flash_readb(flash, CFG_ETH0_ADDRESS + i);
+ eth_plat[1].hwaddr[i] =
+ flash_readb(flash, CFG_ETH1_ADDRESS + i);
+ }
+
+ __raw_writew(FLASH_CMD_READ_ID, flash);
+ system_serial_high = flash_readw(flash, FLASH_SER_OFF);
+ system_serial_high <<= 16;
+ system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
+ system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
+ system_serial_low <<= 16;
+ system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
+ __raw_writew(FLASH_CMD_READ_ARRAY, flash);
+
+ iounmap(flash);
+ }
+
+ switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
+ case CFG_HW_HAS_UART0:
+ memset(&uart_data[1], 0, sizeof(uart_data[1]));
+ device_uarts.num_resources = 1;
+ break;
+
+ case CFG_HW_HAS_UART1:
+ device_uarts.dev.platform_data = &uart_data[1];
+ device_uarts.resource = &uart_resources[1];
+ device_uarts.num_resources = 1;
+ break;
+ }
+ if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
+ device_tab[devices++] = &device_uarts; /* max index 1 */
+
+ if (hw_bits & CFG_HW_HAS_ETH0)
+ device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
+ if (hw_bits & CFG_HW_HAS_ETH1)
+ device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
+
+ if (hw_bits & CFG_HW_HAS_HSS0)
+ device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
+ if (hw_bits & CFG_HW_HAS_HSS1)
+ device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
+
+ if (hw_bits & CFG_HW_HAS_EEPROM)
+ device_tab[devices++] = &device_i2c; /* max index 6 */
+
+ gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_STR, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_HSS0_RTS_N, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
+ gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
+ gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
+
+ set_control(CONTROL_HSS0_DTR_N, 1);
+ set_control(CONTROL_HSS1_DTR_N, 1);
+ set_control(CONTROL_EEPROM_WC_N, 1);
+ set_control(CONTROL_PCI_RESET_N, 1);
+ output_control();
+
+ msleep(1); /* Wait for PCI devices to initialize */
+
+ flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ platform_add_devices(device_tab, devices);
+}
+
+
+#ifdef CONFIG_PCI
+static void __init gmlr_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static void __init gmlr_pci_postinit(void)
+{
+ if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
+ (hw_bits & CFG_HW_USB_PORTS) < 5) {
+ /* need to adjust number of USB ports on NEC chip */
+ u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
+ if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
+ value &= ~7;
+ value |= (hw_bits & CFG_HW_USB_PORTS);
+ ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
+ }
+ }
+}
+
+static int __init gmlr_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch(slot) {
+ case SLOT_ETHA: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
+ case SLOT_ETHB: return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
+ case SLOT_NEC: return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
+ default: return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
+ }
+}
+
+static struct hw_pci gmlr_hw_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = gmlr_pci_preinit,
+ .postinit = gmlr_pci_postinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = gmlr_map_irq,
+};
+
+static int __init gmlr_pci_init(void)
+{
+ if (machine_is_goramo_mlr() &&
+ (hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
+ pci_common_init(&gmlr_hw_pci);
+ return 0;
+}
+
+subsys_initcall(gmlr_pci_init);
+#endif /* CONFIG_PCI */
+
+
+MACHINE_START(GORAMO_MLR, "MultiLink")
+ /* Maintainer: Krzysztof Halasa */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = gmlr_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
new file mode 100644
index 00000000..38cc0725
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -0,0 +1,85 @@
+/*
+ * arch/arm/mach-ixp4xx/gtwx5715-pci.c
+ *
+ * Gemtek GTWX5715 (Linksys WRV54G) board setup
+ *
+ * Copyright (C) 2004 George T. Joseph
+ * Derived from Coyote
+ *
+ * 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/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/mach/pci.h>
+
+#define SLOT0_DEVID 0
+#define SLOT1_DEVID 1
+#define INTA 10 /* slot 1 has INTA and INTB crossed */
+#define INTB 11
+
+/*
+ * Slot 0 isn't actually populated with a card connector but
+ * we initialize it anyway in case a future version has the
+ * slot populated or someone with good soldering skills has
+ * some free time.
+ */
+void __init gtwx5715_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+
+static int __init gtwx5715_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int rc = -1;
+
+ if ((slot == SLOT0_DEVID && pin == 1) ||
+ (slot == SLOT1_DEVID && pin == 2))
+ rc = IXP4XX_GPIO_IRQ(INTA);
+ else if ((slot == SLOT0_DEVID && pin == 2) ||
+ (slot == SLOT1_DEVID && pin == 1))
+ rc = IXP4XX_GPIO_IRQ(INTB);
+
+ printk(KERN_INFO "%s: Mapped slot %d pin %d to IRQ %d\n",
+ __func__, slot, pin, rc);
+ return rc;
+}
+
+struct hw_pci gtwx5715_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = gtwx5715_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = gtwx5715_map_irq,
+};
+
+int __init gtwx5715_pci_init(void)
+{
+ if (machine_is_gtwx5715())
+ pci_common_init(&gtwx5715_pci);
+
+ return 0;
+}
+
+subsys_initcall(gtwx5715_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
new file mode 100644
index 00000000..77abead3
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -0,0 +1,174 @@
+/*
+ * arch/arm/mach-ixp4xx/gtwx5715-setup.c
+ *
+ * Gemtek GTWX5715 (Linksys WRV54G) board setup
+ *
+ * Copyright (C) 2004 George T. Joseph
+ * Derived from Coyote
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+/* GPIO 5,6,7 and 12 are hard wired to the Kendin KS8995M Switch
+ and operate as an SPI type interface. The details of the interface
+ are available on Kendin/Micrel's web site. */
+
+#define GTWX5715_KSSPI_SELECT 5
+#define GTWX5715_KSSPI_TXD 6
+#define GTWX5715_KSSPI_CLOCK 7
+#define GTWX5715_KSSPI_RXD 12
+
+/* The "reset" button is wired to GPIO 3.
+ The GPIO is brought "low" when the button is pushed. */
+
+#define GTWX5715_BUTTON_GPIO 3
+
+/* Board Label Front Label
+ LED1 Power
+ LED2 Wireless-G
+ LED3 not populated but could be
+ LED4 Internet
+ LED5 - LED8 Controlled by KS8995M Switch
+ LED9 DMZ */
+
+#define GTWX5715_LED1_GPIO 2
+#define GTWX5715_LED2_GPIO 9
+#define GTWX5715_LED3_GPIO 8
+#define GTWX5715_LED4_GPIO 1
+#define GTWX5715_LED9_GPIO 4
+
+/*
+ * Xscale UART registers are 32 bits wide with only the least
+ * significant 8 bits having any meaning. From a configuration
+ * perspective, this means 2 things...
+ *
+ * Setting .regshift = 2 so that the standard 16550 registers
+ * line up on every 4th byte.
+ *
+ * Shifting the register start virtual address +3 bytes when
+ * compiled big-endian. Since register writes are done on a
+ * single byte basis, if the shift isn't done the driver will
+ * write the value into the most significant byte of the register,
+ * which is ignored, instead of the least significant.
+ */
+
+#ifdef __ARMEB__
+#define REG_OFFSET 3
+#else
+#define REG_OFFSET 0
+#endif
+
+/*
+ * Only the second or "console" uart is connected on the gtwx5715.
+ */
+
+static struct resource gtwx5715_uart_resources[] = {
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_IXP4XX_UART2,
+ .end = IRQ_IXP4XX_UART2,
+ .flags = IORESOURCE_IRQ,
+ },
+ { },
+};
+
+
+static struct plat_serial8250_port gtwx5715_uart_platform_data[] = {
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device gtwx5715_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = gtwx5715_uart_platform_data,
+ },
+ .num_resources = 2,
+ .resource = gtwx5715_uart_resources,
+};
+
+static struct flash_platform_data gtwx5715_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource gtwx5715_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gtwx5715_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &gtwx5715_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &gtwx5715_flash_resource,
+};
+
+static struct platform_device *gtwx5715_devices[] __initdata = {
+ &gtwx5715_uart_device,
+ &gtwx5715_flash,
+};
+
+static void __init gtwx5715_init(void)
+{
+ ixp4xx_sys_init();
+
+ gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
+
+ platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices));
+}
+
+
+MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)")
+ /* Maintainer: George Joseph */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = gtwx5715_init,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/cpu.h b/arch/arm/mach-ixp4xx/include/mach/cpu.h
new file mode 100644
index 00000000..b2ef65db
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/cpu.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/cpu.h
+ *
+ * IXP4XX cpu type detection
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __ASM_ARCH_CPU_H__
+#define __ASM_ARCH_CPU_H__
+
+#include <asm/cputype.h>
+
+/* Processor id value in CP15 Register 0 */
+#define IXP42X_PROCESSOR_ID_VALUE 0x690541c0 /* including unused 0x690541Ex */
+#define IXP42X_PROCESSOR_ID_MASK 0xffffffc0
+
+#define IXP43X_PROCESSOR_ID_VALUE 0x69054040
+#define IXP43X_PROCESSOR_ID_MASK 0xfffffff0
+
+#define IXP46X_PROCESSOR_ID_VALUE 0x69054200 /* including IXP455 */
+#define IXP46X_PROCESSOR_ID_MASK 0xfffffff0
+
+#define cpu_is_ixp42x_rev_a0() ((read_cpuid_id() & (IXP42X_PROCESSOR_ID_MASK | 0xF)) == \
+ IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp42x() ((read_cpuid_id() & IXP42X_PROCESSOR_ID_MASK) == \
+ IXP42X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp43x() ((read_cpuid_id() & IXP43X_PROCESSOR_ID_MASK) == \
+ IXP43X_PROCESSOR_ID_VALUE)
+#define cpu_is_ixp46x() ((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
+ IXP46X_PROCESSOR_ID_VALUE)
+
+static inline u32 ixp4xx_read_feature_bits(void)
+{
+ u32 val = ~*IXP4XX_EXP_CFG2;
+
+ if (cpu_is_ixp42x_rev_a0())
+ return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
+ IXP4XX_FEATURE_AES);
+ if (cpu_is_ixp42x())
+ return val & IXP42X_FEATURE_MASK;
+ if (cpu_is_ixp43x())
+ return val & IXP43X_FEATURE_MASK;
+ return val & IXP46X_FEATURE_MASK;
+}
+
+static inline void ixp4xx_write_feature_bits(u32 value)
+{
+ *IXP4XX_EXP_CFG2 = ~value;
+}
+
+#endif /* _ASM_ARCH_CPU_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/debug-macro.S b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..b974a49c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/debug-macro.S
@@ -0,0 +1,26 @@
+/* arch/arm/mach-ixp4xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+ .macro addruart, rp, rv
+#ifdef __ARMEB__
+ mov \rp, #3 @ Uart regs are at off set of 3 if
+ @ byte writes used - Big Endian.
+#else
+ mov \rp, #0
+#endif
+ orr \rv, \rp, #0xff000000 @ virtual
+ orr \rv, \rv, #0x00b00000
+ orr \rp, \rp, #0xc8000000 @ physical
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-ixp4xx/include/mach/entry-macro.S b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..f2e14e94
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for IXP4xx-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
+ ldr \irqstat, [\irqstat] @ get interrupts
+ cmp \irqstat, #0
+ beq 1001f @ upper IRQ?
+ clz \irqnr, \irqstat
+ mov \base, #31
+ sub \irqnr, \base, \irqnr
+ b 1002f @ lower IRQ being
+ @ handled
+
+1001:
+ /*
+ * IXP465/IXP435 has an upper IRQ status register
+ */
+#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
+ ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
+ ldr \irqstat, [\irqstat] @ get upper interrupts
+ mov \irqnr, #63
+ clz \irqstat, \irqstat
+ cmp \irqstat, #32
+ subne \irqnr, \irqnr, \irqstat
+#endif
+1002:
+ .endm
+
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/gpio.h b/arch/arm/mach-ixp4xx/include/mach/gpio.h
new file mode 100644
index 00000000..a5f87ded
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/gpio.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/gpio.h
+ *
+ * IXP4XX GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Milan Svoboda <msvoboda@ra.rockwell.com>
+ * Based on PXA implementation by Philipp Zabel <philipp.zabel@gmail.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 __ASM_ARCH_IXP4XX_GPIO_H
+#define __ASM_ARCH_IXP4XX_GPIO_H
+
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+ return 0;
+}
+
+static inline void gpio_free(unsigned gpio)
+{
+ might_sleep();
+
+ return;
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ gpio_line_config(gpio, IXP4XX_GPIO_IN);
+ return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int level)
+{
+ gpio_line_set(gpio, level);
+ gpio_line_config(gpio, IXP4XX_GPIO_OUT);
+ return 0;
+}
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ int value;
+
+ gpio_line_get(gpio, &value);
+
+ return value;
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ gpio_line_set(gpio, value);
+}
+
+#include <asm-generic/gpio.h> /* cansleep wrappers */
+
+extern int gpio_to_irq(int gpio);
+extern int irq_to_gpio(unsigned int irq);
+
+#endif
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
new file mode 100644
index 00000000..8138371c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/hardware.h
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*
+ * Hardware definitions for IXP4xx based systems
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#define __ASM_ARCH_HARDWARE_H__
+
+#define PCIBIOS_MIN_IO 0x00001000
+#ifdef CONFIG_IXP4XX_INDIRECT_PCI
+#define PCIBIOS_MIN_MEM 0x10000000 /* 1 GB of indirect PCI MMIO space */
+#define PCIBIOS_MAX_MEM 0x4FFFFFFF
+#else
+#define PCIBIOS_MIN_MEM 0x48000000 /* 64 MB of PCI MMIO space */
+#define PCIBIOS_MAX_MEM 0x4BFFFFFF
+#endif
+
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
+
+#define pcibios_assign_all_busses() 1
+
+/* Register locations and bits */
+#include "ixp4xx-regs.h"
+
+#ifndef __ASSEMBLER__
+#include <mach/cpu.h>
+#endif
+
+/* Platform helper functions and definitions */
+#include "platform.h"
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
new file mode 100644
index 00000000..57b5410c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -0,0 +1,526 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/io.h
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * Copyright (C) 2002-2005 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <linux/bitops.h>
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0x0000ffff
+
+extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
+extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
+
+
+/*
+ * IXP4xx provides two methods of accessing PCI memory space:
+ *
+ * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
+ * To access PCI via this space, we simply ioremap() the BAR
+ * into the kernel and we can use the standard read[bwl]/write[bwl]
+ * macros. This is the preffered method due to speed but it
+ * limits the system to just 64MB of PCI memory. This can be
+ * problematic if using video cards and other memory-heavy targets.
+ *
+ * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
+ * registers to access the whole 4 GB of PCI memory space (as we do below
+ * for I/O transactions). This allows currently for up to 1 GB (0x10000000
+ * to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
+ * every PCI access requires three local register accesses plus a spinlock,
+ * but in some cases the performance hit is acceptable. In addition, you
+ * cannot mmap() PCI devices in this case.
+ */
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+
+#define __mem_pci(a) (a)
+
+#else
+
+/*
+ * In the case of using indirect PCI, we simply return the actual PCI
+ * address and our read/write implementation use that to drive the
+ * access registers. If something outside of PCI is ioremap'd, we
+ * fallback to the default.
+ */
+
+static inline int is_pci_memory(u32 addr)
+{
+ return (addr >= PCIBIOS_MIN_MEM) && (addr <= 0x4FFFFFFF);
+}
+
+static inline void __iomem * __indirect_ioremap(unsigned long addr, size_t size,
+ unsigned int mtype)
+{
+ if (!is_pci_memory(addr))
+ return __arm_ioremap(addr, size, mtype);
+
+ return (void __iomem *)addr;
+}
+
+static inline void __indirect_iounmap(void __iomem *addr)
+{
+ if (!is_pci_memory((__force u32)addr))
+ __iounmap(addr);
+}
+
+#define __arch_ioremap __indirect_ioremap
+#define __arch_iounmap __indirect_iounmap
+
+#define writeb(v, p) __indirect_writeb(v, p)
+#define writew(v, p) __indirect_writew(v, p)
+#define writel(v, p) __indirect_writel(v, p)
+
+#define writesb(p, v, l) __indirect_writesb(p, v, l)
+#define writesw(p, v, l) __indirect_writesw(p, v, l)
+#define writesl(p, v, l) __indirect_writesl(p, v, l)
+
+#define readb(p) __indirect_readb(p)
+#define readw(p) __indirect_readw(p)
+#define readl(p) __indirect_readl(p)
+
+#define readsb(p, v, l) __indirect_readsb(p, v, l)
+#define readsw(p, v, l) __indirect_readsw(p, v, l)
+#define readsl(p, v, l) __indirect_readsl(p, v, l)
+
+static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
+{
+ u32 addr = (u32)p;
+ u32 n, byte_enables, data;
+
+ if (!is_pci_memory(addr)) {
+ __raw_writeb(value, addr);
+ return;
+ }
+
+ n = addr % 4;
+ byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
+ data = value << (8*n);
+ ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
+}
+
+static inline void __indirect_writesb(volatile void __iomem *bus_addr,
+ const u8 *vaddr, int count)
+{
+ while (count--)
+ writeb(*vaddr++, bus_addr);
+}
+
+static inline void __indirect_writew(u16 value, volatile void __iomem *p)
+{
+ u32 addr = (u32)p;
+ u32 n, byte_enables, data;
+
+ if (!is_pci_memory(addr)) {
+ __raw_writew(value, addr);
+ return;
+ }
+
+ n = addr % 4;
+ byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
+ data = value << (8*n);
+ ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
+}
+
+static inline void __indirect_writesw(volatile void __iomem *bus_addr,
+ const u16 *vaddr, int count)
+{
+ while (count--)
+ writew(*vaddr++, bus_addr);
+}
+
+static inline void __indirect_writel(u32 value, volatile void __iomem *p)
+{
+ u32 addr = (__force u32)p;
+
+ if (!is_pci_memory(addr)) {
+ __raw_writel(value, p);
+ return;
+ }
+
+ ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
+}
+
+static inline void __indirect_writesl(volatile void __iomem *bus_addr,
+ const u32 *vaddr, int count)
+{
+ while (count--)
+ writel(*vaddr++, bus_addr);
+}
+
+static inline unsigned char __indirect_readb(const volatile void __iomem *p)
+{
+ u32 addr = (u32)p;
+ u32 n, byte_enables, data;
+
+ if (!is_pci_memory(addr))
+ return __raw_readb(addr);
+
+ n = addr % 4;
+ byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
+ if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
+ return 0xff;
+
+ return data >> (8*n);
+}
+
+static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
+ u8 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = readb(bus_addr);
+}
+
+static inline unsigned short __indirect_readw(const volatile void __iomem *p)
+{
+ u32 addr = (u32)p;
+ u32 n, byte_enables, data;
+
+ if (!is_pci_memory(addr))
+ return __raw_readw(addr);
+
+ n = addr % 4;
+ byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
+ if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
+ return 0xffff;
+
+ return data>>(8*n);
+}
+
+static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
+ u16 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = readw(bus_addr);
+}
+
+static inline unsigned long __indirect_readl(const volatile void __iomem *p)
+{
+ u32 addr = (__force u32)p;
+ u32 data;
+
+ if (!is_pci_memory(addr))
+ return __raw_readl(p);
+
+ if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
+ return 0xffffffff;
+
+ return data;
+}
+
+static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
+ u32 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = readl(bus_addr);
+}
+
+
+/*
+ * We can use the built-in functions b/c they end up calling writeb/readb
+ */
+#define memset_io(c,v,l) _memset_io((c),(v),(l))
+#define memcpy_fromio(a,c,l) _memcpy_fromio((a),(c),(l))
+#define memcpy_toio(c,a,l) _memcpy_toio((c),(a),(l))
+
+#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
+
+#ifndef CONFIG_PCI
+
+#define __io(v) __typesafe_io(v)
+
+#else
+
+/*
+ * IXP4xx does not have a transparent cpu -> PCI I/O translation
+ * window. Instead, it has a set of registers that must be tweaked
+ * with the proper byte lanes, command types, and address for the
+ * transaction. This means that we need to override the default
+ * I/O functions.
+ */
+
+static inline void outb(u8 value, u32 addr)
+{
+ u32 n, byte_enables, data;
+ n = addr % 4;
+ byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
+ data = value << (8*n);
+ ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
+}
+
+static inline void outsb(u32 io_addr, const u8 *vaddr, u32 count)
+{
+ while (count--)
+ outb(*vaddr++, io_addr);
+}
+
+static inline void outw(u16 value, u32 addr)
+{
+ u32 n, byte_enables, data;
+ n = addr % 4;
+ byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
+ data = value << (8*n);
+ ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
+}
+
+static inline void outsw(u32 io_addr, const u16 *vaddr, u32 count)
+{
+ while (count--)
+ outw(cpu_to_le16(*vaddr++), io_addr);
+}
+
+static inline void outl(u32 value, u32 addr)
+{
+ ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
+}
+
+static inline void outsl(u32 io_addr, const u32 *vaddr, u32 count)
+{
+ while (count--)
+ outl(cpu_to_le32(*vaddr++), io_addr);
+}
+
+static inline u8 inb(u32 addr)
+{
+ u32 n, byte_enables, data;
+ n = addr % 4;
+ byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
+ if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
+ return 0xff;
+
+ return data >> (8*n);
+}
+
+static inline void insb(u32 io_addr, u8 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = inb(io_addr);
+}
+
+static inline u16 inw(u32 addr)
+{
+ u32 n, byte_enables, data;
+ n = addr % 4;
+ byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
+ if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
+ return 0xffff;
+
+ return data>>(8*n);
+}
+
+static inline void insw(u32 io_addr, u16 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = le16_to_cpu(inw(io_addr));
+}
+
+static inline u32 inl(u32 addr)
+{
+ u32 data;
+ if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
+ return 0xffffffff;
+
+ return data;
+}
+
+static inline void insl(u32 io_addr, u32 *vaddr, u32 count)
+{
+ while (count--)
+ *vaddr++ = le32_to_cpu(inl(io_addr));
+}
+
+#define PIO_OFFSET 0x10000UL
+#define PIO_MASK 0x0ffffUL
+
+#define __is_io_address(p) (((unsigned long)p >= PIO_OFFSET) && \
+ ((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
+
+#define ioread8(p) ioread8(p)
+static inline unsigned int ioread8(const void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ return (unsigned int)inb(port & PIO_MASK);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ return (unsigned int)__raw_readb(addr);
+#else
+ return (unsigned int)__indirect_readb(addr);
+#endif
+}
+
+#define ioread8_rep(p, v, c) ioread8_rep(p, v, c)
+static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ insb(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_readsb(addr, vaddr, count);
+#else
+ __indirect_readsb(addr, vaddr, count);
+#endif
+}
+
+#define ioread16(p) ioread16(p)
+static inline unsigned int ioread16(const void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ return (unsigned int)inw(port & PIO_MASK);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ return le16_to_cpu((__force __le16)__raw_readw(addr));
+#else
+ return (unsigned int)__indirect_readw(addr);
+#endif
+}
+
+#define ioread16_rep(p, v, c) ioread16_rep(p, v, c)
+static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
+ u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ insw(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_readsw(addr, vaddr, count);
+#else
+ __indirect_readsw(addr, vaddr, count);
+#endif
+}
+
+#define ioread32(p) ioread32(p)
+static inline unsigned int ioread32(const void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ return (unsigned int)inl(port & PIO_MASK);
+ else {
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ return le32_to_cpu((__force __le32)__raw_readl(addr));
+#else
+ return (unsigned int)__indirect_readl(addr);
+#endif
+ }
+}
+
+#define ioread32_rep(p, v, c) ioread32_rep(p, v, c)
+static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
+ u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ insl(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_readsl(addr, vaddr, count);
+#else
+ __indirect_readsl(addr, vaddr, count);
+#endif
+}
+
+#define iowrite8(v, p) iowrite8(v, p)
+static inline void iowrite8(u8 value, void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outb(value, port & PIO_MASK);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writeb(value, addr);
+#else
+ __indirect_writeb(value, addr);
+#endif
+}
+
+#define iowrite8_rep(p, v, c) iowrite8_rep(p, v, c)
+static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
+ u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outsb(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writesb(addr, vaddr, count);
+#else
+ __indirect_writesb(addr, vaddr, count);
+#endif
+}
+
+#define iowrite16(v, p) iowrite16(v, p)
+static inline void iowrite16(u16 value, void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outw(value, port & PIO_MASK);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writew(cpu_to_le16(value), addr);
+#else
+ __indirect_writew(value, addr);
+#endif
+}
+
+#define iowrite16_rep(p, v, c) iowrite16_rep(p, v, c)
+static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
+ u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outsw(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writesw(addr, vaddr, count);
+#else
+ __indirect_writesw(addr, vaddr, count);
+#endif
+}
+
+#define iowrite32(v, p) iowrite32(v, p)
+static inline void iowrite32(u32 value, void __iomem *addr)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outl(value, port & PIO_MASK);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writel((u32 __force)cpu_to_le32(value), addr);
+#else
+ __indirect_writel(value, addr);
+#endif
+}
+
+#define iowrite32_rep(p, v, c) iowrite32_rep(p, v, c)
+static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
+ u32 count)
+{
+ unsigned long port = (unsigned long __force)addr;
+ if (__is_io_address(port))
+ outsl(port & PIO_MASK, vaddr, count);
+ else
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ __raw_writesl(addr, vaddr, count);
+#else
+ __indirect_writesl(addr, vaddr, count);
+#endif
+}
+
+#define ioport_map(port, nr) ((void __iomem*)(port + PIO_OFFSET))
+#define ioport_unmap(addr)
+#endif /* CONFIG_PCI */
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/irqs.h b/arch/arm/mach-ixp4xx/include/mach/irqs.h
new file mode 100644
index 00000000..7e6d4cce
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/irqs.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/irqs.h
+ *
+ * IRQ definitions for IXP4XX based systems
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ARCH_IXP4XX_IRQS_H_
+#define _ARCH_IXP4XX_IRQS_H_
+
+#define IRQ_IXP4XX_NPEA 0
+#define IRQ_IXP4XX_NPEB 1
+#define IRQ_IXP4XX_NPEC 2
+#define IRQ_IXP4XX_QM1 3
+#define IRQ_IXP4XX_QM2 4
+#define IRQ_IXP4XX_TIMER1 5
+#define IRQ_IXP4XX_GPIO0 6
+#define IRQ_IXP4XX_GPIO1 7
+#define IRQ_IXP4XX_PCI_INT 8
+#define IRQ_IXP4XX_PCI_DMA1 9
+#define IRQ_IXP4XX_PCI_DMA2 10
+#define IRQ_IXP4XX_TIMER2 11
+#define IRQ_IXP4XX_USB 12
+#define IRQ_IXP4XX_UART2 13
+#define IRQ_IXP4XX_TIMESTAMP 14
+#define IRQ_IXP4XX_UART1 15
+#define IRQ_IXP4XX_WDOG 16
+#define IRQ_IXP4XX_AHB_PMU 17
+#define IRQ_IXP4XX_XSCALE_PMU 18
+#define IRQ_IXP4XX_GPIO2 19
+#define IRQ_IXP4XX_GPIO3 20
+#define IRQ_IXP4XX_GPIO4 21
+#define IRQ_IXP4XX_GPIO5 22
+#define IRQ_IXP4XX_GPIO6 23
+#define IRQ_IXP4XX_GPIO7 24
+#define IRQ_IXP4XX_GPIO8 25
+#define IRQ_IXP4XX_GPIO9 26
+#define IRQ_IXP4XX_GPIO10 27
+#define IRQ_IXP4XX_GPIO11 28
+#define IRQ_IXP4XX_GPIO12 29
+#define IRQ_IXP4XX_SW_INT1 30
+#define IRQ_IXP4XX_SW_INT2 31
+#define IRQ_IXP4XX_USB_HOST 32
+#define IRQ_IXP4XX_I2C 33
+#define IRQ_IXP4XX_SSP 34
+#define IRQ_IXP4XX_TSYNC 35
+#define IRQ_IXP4XX_EAU_DONE 36
+#define IRQ_IXP4XX_SHA_DONE 37
+#define IRQ_IXP4XX_SWCP_PE 58
+#define IRQ_IXP4XX_QM_PE 60
+#define IRQ_IXP4XX_MCU_ECC 61
+#define IRQ_IXP4XX_EXP_PE 62
+
+#define _IXP4XX_GPIO_IRQ(n) (IRQ_IXP4XX_GPIO ## n)
+#define IXP4XX_GPIO_IRQ(n) _IXP4XX_GPIO_IRQ(n)
+
+/*
+ * Only first 32 sources are valid if running on IXP42x systems
+ */
+#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
+#define NR_IRQS 64
+#else
+#define NR_IRQS 32
+#endif
+
+#define XSCALE_PMU_IRQ (IRQ_IXP4XX_XSCALE_PMU)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h b/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
new file mode 100644
index 00000000..292d55ed
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
@@ -0,0 +1,78 @@
+/*
+ * PTP 1588 clock using the IXP46X
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _IXP46X_TS_H_
+#define _IXP46X_TS_H_
+
+#define DEFAULT_ADDEND 0xF0000029
+#define TICKS_NS_SHIFT 4
+
+struct ixp46x_channel_ctl {
+ u32 ch_control; /* 0x40 Time Synchronization Channel Control */
+ u32 ch_event; /* 0x44 Time Synchronization Channel Event */
+ u32 tx_snap_lo; /* 0x48 Transmit Snapshot Low Register */
+ u32 tx_snap_hi; /* 0x4C Transmit Snapshot High Register */
+ u32 rx_snap_lo; /* 0x50 Receive Snapshot Low Register */
+ u32 rx_snap_hi; /* 0x54 Receive Snapshot High Register */
+ u32 src_uuid_lo; /* 0x58 Source UUID0 Low Register */
+ u32 src_uuid_hi; /* 0x5C Sequence Identifier/Source UUID0 High */
+};
+
+struct ixp46x_ts_regs {
+ u32 control; /* 0x00 Time Sync Control Register */
+ u32 event; /* 0x04 Time Sync Event Register */
+ u32 addend; /* 0x08 Time Sync Addend Register */
+ u32 accum; /* 0x0C Time Sync Accumulator Register */
+ u32 test; /* 0x10 Time Sync Test Register */
+ u32 unused; /* 0x14 */
+ u32 rsystime_lo; /* 0x18 RawSystemTime_Low Register */
+ u32 rsystime_hi; /* 0x1C RawSystemTime_High Register */
+ u32 systime_lo; /* 0x20 SystemTime_Low Register */
+ u32 systime_hi; /* 0x24 SystemTime_High Register */
+ u32 trgt_lo; /* 0x28 TargetTime_Low Register */
+ u32 trgt_hi; /* 0x2C TargetTime_High Register */
+ u32 asms_lo; /* 0x30 Auxiliary Slave Mode Snapshot Low */
+ u32 asms_hi; /* 0x34 Auxiliary Slave Mode Snapshot High */
+ u32 amms_lo; /* 0x38 Auxiliary Master Mode Snapshot Low */
+ u32 amms_hi; /* 0x3C Auxiliary Master Mode Snapshot High */
+
+ struct ixp46x_channel_ctl channel[3];
+};
+
+/* 0x00 Time Sync Control Register Bits */
+#define TSCR_AMM (1<<3)
+#define TSCR_ASM (1<<2)
+#define TSCR_TTM (1<<1)
+#define TSCR_RST (1<<0)
+
+/* 0x04 Time Sync Event Register Bits */
+#define TSER_SNM (1<<3)
+#define TSER_SNS (1<<2)
+#define TTIPEND (1<<1)
+
+/* 0x40 Time Synchronization Channel Control Register Bits */
+#define MASTER_MODE (1<<0)
+#define TIMESTAMP_ALL (1<<1)
+
+/* 0x44 Time Synchronization Channel Event Register Bits */
+#define TX_SNAPSHOT_LOCKED (1<<0)
+#define RX_SNAPSHOT_LOCKED (1<<1)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
new file mode 100644
index 00000000..97c530f6
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -0,0 +1,660 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+ *
+ * Register definitions for IXP4xx chipset. This file contains
+ * register location and bit definitions only. Platform specific
+ * definitions and helper function declarations are in platform.h
+ * and machine-name.h.
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ASM_ARM_IXP4XX_H_
+#define _ASM_ARM_IXP4XX_H_
+
+/*
+ * IXP4xx Linux Memory Map:
+ *
+ * Phy Size Virt Description
+ * =========================================================================
+ *
+ * 0x00000000 0x10000000(max) PAGE_OFFSET System RAM
+ *
+ * 0x48000000 0x04000000 ioremap'd PCI Memory Space
+ *
+ * 0x50000000 0x10000000 ioremap'd EXP BUS
+ *
+ * 0x6000000 0x00004000 ioremap'd QMgr
+ *
+ * 0xC0000000 0x00001000 0xffbff000 PCI CFG
+ *
+ * 0xC4000000 0x00001000 0xffbfe000 EXP CFG
+ *
+ * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
+ */
+
+/*
+ * Queue Manager
+ */
+#define IXP4XX_QMGR_BASE_PHYS (0x60000000)
+#define IXP4XX_QMGR_REGION_SIZE (0x00004000)
+
+/*
+ * Expansion BUS Configuration registers
+ */
+#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
+#define IXP4XX_EXP_CFG_BASE_VIRT (0xFFBFE000)
+#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
+
+/*
+ * PCI Config registers
+ */
+#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
+#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFF000)
+#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
+
+/*
+ * Peripheral space
+ */
+#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
+#define IXP4XX_PERIPHERAL_BASE_VIRT (0xFFBEB000)
+#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
+
+/*
+ * Debug UART
+ *
+ * This is basically a remap of UART1 into a region that is section
+ * aligned so that it * can be used with the low-level debug code.
+ */
+#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
+#define IXP4XX_DEBUG_UART_BASE_VIRT (0xffb00000)
+#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
+
+#define IXP4XX_EXP_CS0_OFFSET 0x00
+#define IXP4XX_EXP_CS1_OFFSET 0x04
+#define IXP4XX_EXP_CS2_OFFSET 0x08
+#define IXP4XX_EXP_CS3_OFFSET 0x0C
+#define IXP4XX_EXP_CS4_OFFSET 0x10
+#define IXP4XX_EXP_CS5_OFFSET 0x14
+#define IXP4XX_EXP_CS6_OFFSET 0x18
+#define IXP4XX_EXP_CS7_OFFSET 0x1C
+#define IXP4XX_EXP_CFG0_OFFSET 0x20
+#define IXP4XX_EXP_CFG1_OFFSET 0x24
+#define IXP4XX_EXP_CFG2_OFFSET 0x28
+#define IXP4XX_EXP_CFG3_OFFSET 0x2C
+
+/*
+ * Expansion Bus Controller registers.
+ */
+#define IXP4XX_EXP_REG(x) ((volatile u32 *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
+
+#define IXP4XX_EXP_CS0 IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
+#define IXP4XX_EXP_CS1 IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
+#define IXP4XX_EXP_CS2 IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET)
+#define IXP4XX_EXP_CS3 IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
+#define IXP4XX_EXP_CS4 IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
+#define IXP4XX_EXP_CS5 IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
+#define IXP4XX_EXP_CS6 IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)
+#define IXP4XX_EXP_CS7 IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
+
+#define IXP4XX_EXP_CFG0 IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET)
+#define IXP4XX_EXP_CFG1 IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET)
+#define IXP4XX_EXP_CFG2 IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET)
+#define IXP4XX_EXP_CFG3 IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
+
+
+/*
+ * Peripheral Space Register Region Base Addresses
+ */
+#define IXP4XX_UART1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
+#define IXP4XX_UART2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
+#define IXP4XX_PMU_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
+#define IXP4XX_INTC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
+#define IXP4XX_GPIO_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
+#define IXP4XX_TIMER_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
+#define IXP4XX_NPEA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
+#define IXP4XX_NPEB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
+#define IXP4XX_NPEC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
+#define IXP4XX_EthB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
+#define IXP4XX_EthC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
+#define IXP4XX_USB_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
+#define IXP4XX_EthB1_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
+#define IXP4XX_EthB2_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
+#define IXP4XX_EthB3_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
+#define IXP4XX_I2C_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
+#define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
+
+
+#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
+#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
+#define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
+#define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
+#define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
+#define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
+#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000)
+#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000)
+#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000)
+#define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
+#define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
+#define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
+/* ixp46X only */
+#define IXP4XX_EthA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
+#define IXP4XX_EthB1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
+#define IXP4XX_EthB2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
+#define IXP4XX_EthB3_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
+#define IXP4XX_TIMESYNC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
+#define IXP4XX_I2C_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
+#define IXP4XX_SSP_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
+
+/*
+ * Constants to make it easy to access Interrupt Controller registers
+ */
+#define IXP4XX_ICPR_OFFSET 0x00 /* Interrupt Status */
+#define IXP4XX_ICMR_OFFSET 0x04 /* Interrupt Enable */
+#define IXP4XX_ICLR_OFFSET 0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP4XX_ICIP_OFFSET 0x0C /* IRQ Status */
+#define IXP4XX_ICFP_OFFSET 0x10 /* FIQ Status */
+#define IXP4XX_ICHR_OFFSET 0x14 /* Interrupt Priority */
+#define IXP4XX_ICIH_OFFSET 0x18 /* IRQ Highest Pri Int */
+#define IXP4XX_ICFH_OFFSET 0x1C /* FIQ Highest Pri Int */
+
+/*
+ * IXP465-only
+ */
+#define IXP4XX_ICPR2_OFFSET 0x20 /* Interrupt Status 2 */
+#define IXP4XX_ICMR2_OFFSET 0x24 /* Interrupt Enable 2 */
+#define IXP4XX_ICLR2_OFFSET 0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2_OFFSET 0x2C /* IRQ Status */
+#define IXP4XX_ICFP2_OFFSET 0x30 /* FIQ Status */
+#define IXP4XX_ICEEN_OFFSET 0x34 /* Error High Pri Enable */
+
+
+/*
+ * Interrupt Controller Register Definitions.
+ */
+
+#define IXP4XX_INTC_REG(x) ((volatile u32 *)(IXP4XX_INTC_BASE_VIRT+(x)))
+
+#define IXP4XX_ICPR IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
+#define IXP4XX_ICMR IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
+#define IXP4XX_ICLR IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
+#define IXP4XX_ICIP IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
+#define IXP4XX_ICFP IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
+#define IXP4XX_ICHR IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
+#define IXP4XX_ICIH IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET)
+#define IXP4XX_ICFH IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
+#define IXP4XX_ICPR2 IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
+#define IXP4XX_ICMR2 IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
+#define IXP4XX_ICLR2 IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
+#define IXP4XX_ICIP2 IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
+#define IXP4XX_ICFP2 IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
+#define IXP4XX_ICEEN IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
+
+/*
+ * Constants to make it easy to access GPIO registers
+ */
+#define IXP4XX_GPIO_GPOUTR_OFFSET 0x00
+#define IXP4XX_GPIO_GPOER_OFFSET 0x04
+#define IXP4XX_GPIO_GPINR_OFFSET 0x08
+#define IXP4XX_GPIO_GPISR_OFFSET 0x0C
+#define IXP4XX_GPIO_GPIT1R_OFFSET 0x10
+#define IXP4XX_GPIO_GPIT2R_OFFSET 0x14
+#define IXP4XX_GPIO_GPCLKR_OFFSET 0x18
+#define IXP4XX_GPIO_GPDBSELR_OFFSET 0x1C
+
+/*
+ * GPIO Register Definitions.
+ * [Only perform 32bit reads/writes]
+ */
+#define IXP4XX_GPIO_REG(x) ((volatile u32 *)(IXP4XX_GPIO_BASE_VIRT+(x)))
+
+#define IXP4XX_GPIO_GPOUTR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
+#define IXP4XX_GPIO_GPOER IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
+#define IXP4XX_GPIO_GPINR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
+#define IXP4XX_GPIO_GPISR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
+#define IXP4XX_GPIO_GPIT1R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
+#define IXP4XX_GPIO_GPIT2R IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
+#define IXP4XX_GPIO_GPCLKR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
+#define IXP4XX_GPIO_GPDBSELR IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
+
+/*
+ * GPIO register bit definitions
+ */
+
+/* Interrupt styles
+ */
+#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH 0x0
+#define IXP4XX_GPIO_STYLE_ACTIVE_LOW 0x1
+#define IXP4XX_GPIO_STYLE_RISING_EDGE 0x2
+#define IXP4XX_GPIO_STYLE_FALLING_EDGE 0x3
+#define IXP4XX_GPIO_STYLE_TRANSITIONAL 0x4
+
+/*
+ * Mask used to clear interrupt styles
+ */
+#define IXP4XX_GPIO_STYLE_CLEAR 0x7
+#define IXP4XX_GPIO_STYLE_SIZE 3
+
+/*
+ * Constants to make it easy to access Timer Control/Status registers
+ */
+#define IXP4XX_OSTS_OFFSET 0x00 /* Continious TimeStamp */
+#define IXP4XX_OST1_OFFSET 0x04 /* Timer 1 Timestamp */
+#define IXP4XX_OSRT1_OFFSET 0x08 /* Timer 1 Reload */
+#define IXP4XX_OST2_OFFSET 0x0C /* Timer 2 Timestamp */
+#define IXP4XX_OSRT2_OFFSET 0x10 /* Timer 2 Reload */
+#define IXP4XX_OSWT_OFFSET 0x14 /* Watchdog Timer */
+#define IXP4XX_OSWE_OFFSET 0x18 /* Watchdog Enable */
+#define IXP4XX_OSWK_OFFSET 0x1C /* Watchdog Key */
+#define IXP4XX_OSST_OFFSET 0x20 /* Timer Status */
+
+/*
+ * Operating System Timer Register Definitions.
+ */
+
+#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
+
+#define IXP4XX_OSTS IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
+#define IXP4XX_OST1 IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
+#define IXP4XX_OSRT1 IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
+#define IXP4XX_OST2 IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
+#define IXP4XX_OSRT2 IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
+#define IXP4XX_OSWT IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
+#define IXP4XX_OSWE IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
+#define IXP4XX_OSWK IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
+#define IXP4XX_OSST IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
+
+/*
+ * Timer register values and bit definitions
+ */
+#define IXP4XX_OST_ENABLE 0x00000001
+#define IXP4XX_OST_ONE_SHOT 0x00000002
+/* Low order bits of reload value ignored */
+#define IXP4XX_OST_RELOAD_MASK 0x00000003
+#define IXP4XX_OST_DISABLED 0x00000000
+#define IXP4XX_OSST_TIMER_1_PEND 0x00000001
+#define IXP4XX_OSST_TIMER_2_PEND 0x00000002
+#define IXP4XX_OSST_TIMER_TS_PEND 0x00000004
+#define IXP4XX_OSST_TIMER_WDOG_PEND 0x00000008
+#define IXP4XX_OSST_TIMER_WARM_RESET 0x00000010
+
+#define IXP4XX_WDT_KEY 0x0000482E
+
+#define IXP4XX_WDT_RESET_ENABLE 0x00000001
+#define IXP4XX_WDT_IRQ_ENABLE 0x00000002
+#define IXP4XX_WDT_COUNT_ENABLE 0x00000004
+
+
+/*
+ * Constants to make it easy to access PCI Control/Status registers
+ */
+#define PCI_NP_AD_OFFSET 0x00
+#define PCI_NP_CBE_OFFSET 0x04
+#define PCI_NP_WDATA_OFFSET 0x08
+#define PCI_NP_RDATA_OFFSET 0x0c
+#define PCI_CRP_AD_CBE_OFFSET 0x10
+#define PCI_CRP_WDATA_OFFSET 0x14
+#define PCI_CRP_RDATA_OFFSET 0x18
+#define PCI_CSR_OFFSET 0x1c
+#define PCI_ISR_OFFSET 0x20
+#define PCI_INTEN_OFFSET 0x24
+#define PCI_DMACTRL_OFFSET 0x28
+#define PCI_AHBMEMBASE_OFFSET 0x2c
+#define PCI_AHBIOBASE_OFFSET 0x30
+#define PCI_PCIMEMBASE_OFFSET 0x34
+#define PCI_AHBDOORBELL_OFFSET 0x38
+#define PCI_PCIDOORBELL_OFFSET 0x3C
+#define PCI_ATPDMA0_AHBADDR_OFFSET 0x40
+#define PCI_ATPDMA0_PCIADDR_OFFSET 0x44
+#define PCI_ATPDMA0_LENADDR_OFFSET 0x48
+#define PCI_ATPDMA1_AHBADDR_OFFSET 0x4C
+#define PCI_ATPDMA1_PCIADDR_OFFSET 0x50
+#define PCI_ATPDMA1_LENADDR_OFFSET 0x54
+
+/*
+ * PCI Control/Status Registers
+ */
+#define IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
+
+#define PCI_NP_AD IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
+#define PCI_NP_CBE IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
+#define PCI_NP_WDATA IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
+#define PCI_NP_RDATA IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
+#define PCI_CRP_AD_CBE IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
+#define PCI_CRP_WDATA IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
+#define PCI_CRP_RDATA IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
+#define PCI_CSR IXP4XX_PCI_CSR(PCI_CSR_OFFSET)
+#define PCI_ISR IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
+#define PCI_INTEN IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
+#define PCI_DMACTRL IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
+#define PCI_AHBMEMBASE IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
+#define PCI_AHBIOBASE IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
+#define PCI_PCIMEMBASE IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
+#define PCI_AHBDOORBELL IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
+#define PCI_PCIDOORBELL IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
+#define PCI_ATPDMA0_AHBADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
+#define PCI_ATPDMA0_PCIADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
+#define PCI_ATPDMA0_LENADDR IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
+#define PCI_ATPDMA1_AHBADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
+#define PCI_ATPDMA1_PCIADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
+#define PCI_ATPDMA1_LENADDR IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
+
+/*
+ * PCI register values and bit definitions
+ */
+
+/* CSR bit definitions */
+#define PCI_CSR_HOST 0x00000001
+#define PCI_CSR_ARBEN 0x00000002
+#define PCI_CSR_ADS 0x00000004
+#define PCI_CSR_PDS 0x00000008
+#define PCI_CSR_ABE 0x00000010
+#define PCI_CSR_DBT 0x00000020
+#define PCI_CSR_ASE 0x00000100
+#define PCI_CSR_IC 0x00008000
+
+/* ISR (Interrupt status) Register bit definitions */
+#define PCI_ISR_PSE 0x00000001
+#define PCI_ISR_PFE 0x00000002
+#define PCI_ISR_PPE 0x00000004
+#define PCI_ISR_AHBE 0x00000008
+#define PCI_ISR_APDC 0x00000010
+#define PCI_ISR_PADC 0x00000020
+#define PCI_ISR_ADB 0x00000040
+#define PCI_ISR_PDB 0x00000080
+
+/* INTEN (Interrupt Enable) Register bit definitions */
+#define PCI_INTEN_PSE 0x00000001
+#define PCI_INTEN_PFE 0x00000002
+#define PCI_INTEN_PPE 0x00000004
+#define PCI_INTEN_AHBE 0x00000008
+#define PCI_INTEN_APDC 0x00000010
+#define PCI_INTEN_PADC 0x00000020
+#define PCI_INTEN_ADB 0x00000040
+#define PCI_INTEN_PDB 0x00000080
+
+/*
+ * Shift value for byte enable on NP cmd/byte enable register
+ */
+#define IXP4XX_PCI_NP_CBE_BESL 4
+
+/*
+ * PCI commands supported by NP access unit
+ */
+#define NP_CMD_IOREAD 0x2
+#define NP_CMD_IOWRITE 0x3
+#define NP_CMD_CONFIGREAD 0xa
+#define NP_CMD_CONFIGWRITE 0xb
+#define NP_CMD_MEMREAD 0x6
+#define NP_CMD_MEMWRITE 0x7
+
+/*
+ * Constants for CRP access into local config space
+ */
+#define CRP_AD_CBE_BESL 20
+#define CRP_AD_CBE_WRITE 0x00010000
+
+
+/*
+ * USB Device Controller
+ *
+ * These are used by the USB gadget driver, so they don't follow the
+ * IXP4XX_ naming convetions.
+ *
+ */
+# define IXP4XX_USB_REG(x) (*((volatile u32 *)(x)))
+
+/* UDC Undocumented - Reserved1 */
+#define UDC_RES1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0004)
+/* UDC Undocumented - Reserved2 */
+#define UDC_RES2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0008)
+/* UDC Undocumented - Reserved3 */
+#define UDC_RES3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x000C)
+/* UDC Control Register */
+#define UDCCR IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0000)
+/* UDC Endpoint 0 Control/Status Register */
+#define UDCCS0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0010)
+/* UDC Endpoint 1 (IN) Control/Status Register */
+#define UDCCS1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0014)
+/* UDC Endpoint 2 (OUT) Control/Status Register */
+#define UDCCS2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0018)
+/* UDC Endpoint 3 (IN) Control/Status Register */
+#define UDCCS3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x001C)
+/* UDC Endpoint 4 (OUT) Control/Status Register */
+#define UDCCS4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0020)
+/* UDC Endpoint 5 (Interrupt) Control/Status Register */
+#define UDCCS5 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0024)
+/* UDC Endpoint 6 (IN) Control/Status Register */
+#define UDCCS6 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0028)
+/* UDC Endpoint 7 (OUT) Control/Status Register */
+#define UDCCS7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x002C)
+/* UDC Endpoint 8 (IN) Control/Status Register */
+#define UDCCS8 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0030)
+/* UDC Endpoint 9 (OUT) Control/Status Register */
+#define UDCCS9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0034)
+/* UDC Endpoint 10 (Interrupt) Control/Status Register */
+#define UDCCS10 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0038)
+/* UDC Endpoint 11 (IN) Control/Status Register */
+#define UDCCS11 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x003C)
+/* UDC Endpoint 12 (OUT) Control/Status Register */
+#define UDCCS12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0040)
+/* UDC Endpoint 13 (IN) Control/Status Register */
+#define UDCCS13 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0044)
+/* UDC Endpoint 14 (OUT) Control/Status Register */
+#define UDCCS14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0048)
+/* UDC Endpoint 15 (Interrupt) Control/Status Register */
+#define UDCCS15 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x004C)
+/* UDC Frame Number Register High */
+#define UFNRH IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0060)
+/* UDC Frame Number Register Low */
+#define UFNRL IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0064)
+/* UDC Byte Count Reg 2 */
+#define UBCR2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0068)
+/* UDC Byte Count Reg 4 */
+#define UBCR4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x006c)
+/* UDC Byte Count Reg 7 */
+#define UBCR7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0070)
+/* UDC Byte Count Reg 9 */
+#define UBCR9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0074)
+/* UDC Byte Count Reg 12 */
+#define UBCR12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0078)
+/* UDC Byte Count Reg 14 */
+#define UBCR14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x007c)
+/* UDC Endpoint 0 Data Register */
+#define UDDR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0080)
+/* UDC Endpoint 1 Data Register */
+#define UDDR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0100)
+/* UDC Endpoint 2 Data Register */
+#define UDDR2 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0180)
+/* UDC Endpoint 3 Data Register */
+#define UDDR3 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0200)
+/* UDC Endpoint 4 Data Register */
+#define UDDR4 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0400)
+/* UDC Endpoint 5 Data Register */
+#define UDDR5 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00A0)
+/* UDC Endpoint 6 Data Register */
+#define UDDR6 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0600)
+/* UDC Endpoint 7 Data Register */
+#define UDDR7 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0680)
+/* UDC Endpoint 8 Data Register */
+#define UDDR8 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0700)
+/* UDC Endpoint 9 Data Register */
+#define UDDR9 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0900)
+/* UDC Endpoint 10 Data Register */
+#define UDDR10 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00C0)
+/* UDC Endpoint 11 Data Register */
+#define UDDR11 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0B00)
+/* UDC Endpoint 12 Data Register */
+#define UDDR12 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0B80)
+/* UDC Endpoint 13 Data Register */
+#define UDDR13 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0C00)
+/* UDC Endpoint 14 Data Register */
+#define UDDR14 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0E00)
+/* UDC Endpoint 15 Data Register */
+#define UDDR15 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x00E0)
+/* UDC Interrupt Control Register 0 */
+#define UICR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0050)
+/* UDC Interrupt Control Register 1 */
+#define UICR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0054)
+/* UDC Status Interrupt Register 0 */
+#define USIR0 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x0058)
+/* UDC Status Interrupt Register 1 */
+#define USIR1 IXP4XX_USB_REG(IXP4XX_USB_BASE_VIRT+0x005C)
+
+#define UDCCR_UDE (1 << 0) /* UDC enable */
+#define UDCCR_UDA (1 << 1) /* UDC active */
+#define UDCCR_RSM (1 << 2) /* Device resume */
+#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
+#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
+#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
+#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
+#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
+
+#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
+#define UDCCS0_IPR (1 << 1) /* IN packet ready */
+#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
+#define UDCCS0_SST (1 << 4) /* Sent stall */
+#define UDCCS0_FST (1 << 5) /* Force stall */
+#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
+#define UDCCS0_SA (1 << 7) /* Setup active */
+
+#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_BI_SST (1 << 4) /* Sent stall */
+#define UDCCS_BI_FST (1 << 5) /* Force stall */
+#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
+
+#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_BO_DME (1 << 3) /* DMA enable */
+#define UDCCS_BO_SST (1 << 4) /* Sent stall */
+#define UDCCS_BO_FST (1 << 5) /* Force stall */
+#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
+
+#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
+
+#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
+#define UDCCS_IO_DME (1 << 3) /* DMA enable */
+#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
+
+#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_INT_SST (1 << 4) /* Sent stall */
+#define UDCCS_INT_FST (1 << 5) /* Force stall */
+#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
+
+#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
+#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
+#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
+#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
+#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
+#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
+#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
+#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
+
+#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
+#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
+#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
+#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
+#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
+#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
+#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
+#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
+
+#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */
+#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */
+#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */
+#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */
+#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */
+#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */
+#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */
+#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */
+
+#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */
+#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */
+#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */
+#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */
+#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */
+#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */
+#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */
+#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */
+
+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
+
+/* "fuse" bits of IXP_EXP_CFG2 */
+/* All IXP4xx CPUs */
+#define IXP4XX_FEATURE_RCOMP (1 << 0)
+#define IXP4XX_FEATURE_USB_DEVICE (1 << 1)
+#define IXP4XX_FEATURE_HASH (1 << 2)
+#define IXP4XX_FEATURE_AES (1 << 3)
+#define IXP4XX_FEATURE_DES (1 << 4)
+#define IXP4XX_FEATURE_HDLC (1 << 5)
+#define IXP4XX_FEATURE_AAL (1 << 6)
+#define IXP4XX_FEATURE_HSS (1 << 7)
+#define IXP4XX_FEATURE_UTOPIA (1 << 8)
+#define IXP4XX_FEATURE_NPEB_ETH0 (1 << 9)
+#define IXP4XX_FEATURE_NPEC_ETH (1 << 10)
+#define IXP4XX_FEATURE_RESET_NPEA (1 << 11)
+#define IXP4XX_FEATURE_RESET_NPEB (1 << 12)
+#define IXP4XX_FEATURE_RESET_NPEC (1 << 13)
+#define IXP4XX_FEATURE_PCI (1 << 14)
+#define IXP4XX_FEATURE_UTOPIA_PHY_LIMIT (3 << 16)
+#define IXP4XX_FEATURE_XSCALE_MAX_FREQ (3 << 22)
+#define IXP42X_FEATURE_MASK (IXP4XX_FEATURE_RCOMP | \
+ IXP4XX_FEATURE_USB_DEVICE | \
+ IXP4XX_FEATURE_HASH | \
+ IXP4XX_FEATURE_AES | \
+ IXP4XX_FEATURE_DES | \
+ IXP4XX_FEATURE_HDLC | \
+ IXP4XX_FEATURE_AAL | \
+ IXP4XX_FEATURE_HSS | \
+ IXP4XX_FEATURE_UTOPIA | \
+ IXP4XX_FEATURE_NPEB_ETH0 | \
+ IXP4XX_FEATURE_NPEC_ETH | \
+ IXP4XX_FEATURE_RESET_NPEA | \
+ IXP4XX_FEATURE_RESET_NPEB | \
+ IXP4XX_FEATURE_RESET_NPEC | \
+ IXP4XX_FEATURE_PCI | \
+ IXP4XX_FEATURE_UTOPIA_PHY_LIMIT | \
+ IXP4XX_FEATURE_XSCALE_MAX_FREQ)
+
+
+/* IXP43x/46x CPUs */
+#define IXP4XX_FEATURE_ECC_TIMESYNC (1 << 15)
+#define IXP4XX_FEATURE_USB_HOST (1 << 18)
+#define IXP4XX_FEATURE_NPEA_ETH (1 << 19)
+#define IXP43X_FEATURE_MASK (IXP42X_FEATURE_MASK | \
+ IXP4XX_FEATURE_ECC_TIMESYNC | \
+ IXP4XX_FEATURE_USB_HOST | \
+ IXP4XX_FEATURE_NPEA_ETH)
+
+/* IXP46x CPU (including IXP455) only */
+#define IXP4XX_FEATURE_NPEB_ETH_1_TO_3 (1 << 20)
+#define IXP4XX_FEATURE_RSA (1 << 21)
+#define IXP46X_FEATURE_MASK (IXP43X_FEATURE_MASK | \
+ IXP4XX_FEATURE_NPEB_ETH_1_TO_3 | \
+ IXP4XX_FEATURE_RSA)
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h
new file mode 100644
index 00000000..34e79404
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/memory.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/memory.h
+ *
+ * Copyright (c) 2001-2004 MontaVista Software, Inc.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/sizes.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#ifdef CONFIG_PCI
+#define ARM_DMA_ZONE_SIZE SZ_64M
+#endif
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/arch/arm/mach-ixp4xx/include/mach/npe.h
new file mode 100644
index 00000000..e320db24
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/npe.h
@@ -0,0 +1,39 @@
+#ifndef __IXP4XX_NPE_H
+#define __IXP4XX_NPE_H
+
+#include <linux/kernel.h>
+
+extern const char *npe_names[];
+
+struct npe_regs {
+ u32 exec_addr, exec_data, exec_status_cmd, exec_count;
+ u32 action_points[4];
+ u32 watchpoint_fifo, watch_count;
+ u32 profile_count;
+ u32 messaging_status, messaging_control;
+ u32 mailbox_status, /*messaging_*/ in_out_fifo;
+};
+
+struct npe {
+ struct resource *mem_res;
+ struct npe_regs __iomem *regs;
+ u32 regs_phys;
+ int id;
+ int valid;
+};
+
+
+static inline const char *npe_name(struct npe *npe)
+{
+ return npe_names[npe->id];
+}
+
+int npe_running(struct npe *npe);
+int npe_send_message(struct npe *npe, const void *msg, const char *what);
+int npe_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what);
+int npe_load_firmware(struct npe *npe, const char *name, struct device *dev);
+struct npe *npe_request(unsigned id);
+void npe_release(struct npe *npe);
+
+#endif /* __IXP4XX_NPE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
new file mode 100644
index 00000000..e824c02c
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/platform.h
+ *
+ * Constants and functions that are useful to IXP4xx platform-specific code
+ * and device drivers.
+ *
+ * Copyright (C) 2004 MontaVista Software, Inc.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <mach/hardware.h>"
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+
+#ifndef __ARMEB__
+#define REG_OFFSET 0
+#else
+#define REG_OFFSET 3
+#endif
+
+/*
+ * Expansion bus memory regions
+ */
+#define IXP4XX_EXP_BUS_BASE_PHYS (0x50000000)
+
+/*
+ * The expansion bus on the IXP4xx can be configured for either 16 or
+ * 32MB windows and the CS offset for each region changes based on the
+ * current configuration. This means that we cannot simply hardcode
+ * each offset. ixp4xx_sys_init() looks at the expansion bus configuration
+ * as setup by the bootloader to determine our window size.
+ */
+extern unsigned long ixp4xx_exp_bus_size;
+
+#define IXP4XX_EXP_BUS_BASE(region)\
+ (IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
+
+#define IXP4XX_EXP_BUS_END(region)\
+ (IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
+
+/* Those macros can be used to adjust timing and configure
+ * other features for each region.
+ */
+
+#define IXP4XX_EXP_BUS_RECOVERY_T(x) (((x) & 0x0f) << 16)
+#define IXP4XX_EXP_BUS_HOLD_T(x) (((x) & 0x03) << 20)
+#define IXP4XX_EXP_BUS_STROBE_T(x) (((x) & 0x0f) << 22)
+#define IXP4XX_EXP_BUS_SETUP_T(x) (((x) & 0x03) << 26)
+#define IXP4XX_EXP_BUS_ADDR_T(x) (((x) & 0x03) << 28)
+#define IXP4XX_EXP_BUS_SIZE(x) (((x) & 0x0f) << 10)
+#define IXP4XX_EXP_BUS_CYCLES(x) (((x) & 0x03) << 14)
+
+#define IXP4XX_EXP_BUS_CS_EN (1L << 31)
+#define IXP4XX_EXP_BUS_BYTE_RD16 (1L << 6)
+#define IXP4XX_EXP_BUS_HRDY_POL (1L << 5)
+#define IXP4XX_EXP_BUS_MUX_EN (1L << 4)
+#define IXP4XX_EXP_BUS_SPLT_EN (1L << 3)
+#define IXP4XX_EXP_BUS_WR_EN (1L << 1)
+#define IXP4XX_EXP_BUS_BYTE_EN (1L << 0)
+
+#define IXP4XX_EXP_BUS_CYCLES_INTEL 0x00
+#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA 0x01
+#define IXP4XX_EXP_BUS_CYCLES_HPI 0x02
+
+#define IXP4XX_FLASH_WRITABLE (0x2)
+#define IXP4XX_FLASH_DEFAULT (0xbcd23c40)
+#define IXP4XX_FLASH_WRITE (0xbcd23c42)
+
+/*
+ * Clock Speed Definitions.
+ */
+#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
+#define IXP4XX_UART_XTAL 14745600
+
+/*
+ * This structure provide a means for the board setup code
+ * to give information to th pata_ixp4xx driver. It is
+ * passed as platform_data.
+ */
+struct ixp4xx_pata_data {
+ volatile u32 *cs0_cfg;
+ volatile u32 *cs1_cfg;
+ unsigned long cs0_bits;
+ unsigned long cs1_bits;
+ void __iomem *cs0;
+ void __iomem *cs1;
+};
+
+struct sys_timer;
+
+#define IXP4XX_ETH_NPEA 0x00
+#define IXP4XX_ETH_NPEB 0x10
+#define IXP4XX_ETH_NPEC 0x20
+
+/* Information about built-in Ethernet MAC interfaces */
+struct eth_plat_info {
+ u8 phy; /* MII PHY ID, 0 - 31 */
+ u8 rxq; /* configurable, currently 0 - 31 only */
+ u8 txreadyq;
+ u8 hwaddr[6];
+};
+
+/* Information about built-in HSS (synchronous serial) interfaces */
+struct hss_plat_info {
+ int (*set_clock)(int port, unsigned int clock_type);
+ int (*open)(int port, void *pdev,
+ void (*set_carrier_cb)(void *pdev, int carrier));
+ void (*close)(int port, void *pdev);
+ u8 txreadyq;
+};
+
+/*
+ * Frequency of clock used for primary clocksource
+ */
+extern unsigned long ixp4xx_timer_freq;
+
+/*
+ * Functions used by platform-level setup code
+ */
+extern void ixp4xx_map_io(void);
+extern void ixp4xx_init_irq(void);
+extern void ixp4xx_sys_init(void);
+extern void ixp4xx_timer_init(void);
+extern struct sys_timer ixp4xx_timer;
+extern void ixp4xx_pci_preinit(void);
+struct pci_sys_data;
+extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
+extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys);
+
+/*
+ * GPIO-functions
+ */
+/*
+ * The following converted to the real HW bits the gpio_line_config
+ */
+/* GPIO pin types */
+#define IXP4XX_GPIO_OUT 0x1
+#define IXP4XX_GPIO_IN 0x2
+
+/* GPIO signal types */
+#define IXP4XX_GPIO_LOW 0
+#define IXP4XX_GPIO_HIGH 1
+
+/* GPIO Clocks */
+#define IXP4XX_GPIO_CLK_0 14
+#define IXP4XX_GPIO_CLK_1 15
+
+static inline void gpio_line_config(u8 line, u32 direction)
+{
+ if (direction == IXP4XX_GPIO_IN)
+ *IXP4XX_GPIO_GPOER |= (1 << line);
+ else
+ *IXP4XX_GPIO_GPOER &= ~(1 << line);
+}
+
+static inline void gpio_line_get(u8 line, int *value)
+{
+ *value = (*IXP4XX_GPIO_GPINR >> line) & 0x1;
+}
+
+static inline void gpio_line_set(u8 line, int value)
+{
+ if (value == IXP4XX_GPIO_HIGH)
+ *IXP4XX_GPIO_GPOUTR |= (1 << line);
+ else if (value == IXP4XX_GPIO_LOW)
+ *IXP4XX_GPIO_GPOUTR &= ~(1 << line);
+}
+
+#endif // __ASSEMBLY__
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
new file mode 100644
index 00000000..9e7cad2d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/qmgr.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#ifndef IXP4XX_QMGR_H
+#define IXP4XX_QMGR_H
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#define DEBUG_QMGR 0
+
+#define HALF_QUEUES 32
+#define QUEUES 64
+#define MAX_QUEUE_LENGTH 4 /* in dwords */
+
+#define QUEUE_STAT1_EMPTY 1 /* queue status bits */
+#define QUEUE_STAT1_NEARLY_EMPTY 2
+#define QUEUE_STAT1_NEARLY_FULL 4
+#define QUEUE_STAT1_FULL 8
+#define QUEUE_STAT2_UNDERFLOW 1
+#define QUEUE_STAT2_OVERFLOW 2
+
+#define QUEUE_WATERMARK_0_ENTRIES 0
+#define QUEUE_WATERMARK_1_ENTRY 1
+#define QUEUE_WATERMARK_2_ENTRIES 2
+#define QUEUE_WATERMARK_4_ENTRIES 3
+#define QUEUE_WATERMARK_8_ENTRIES 4
+#define QUEUE_WATERMARK_16_ENTRIES 5
+#define QUEUE_WATERMARK_32_ENTRIES 6
+#define QUEUE_WATERMARK_64_ENTRIES 7
+
+/* queue interrupt request conditions */
+#define QUEUE_IRQ_SRC_EMPTY 0
+#define QUEUE_IRQ_SRC_NEARLY_EMPTY 1
+#define QUEUE_IRQ_SRC_NEARLY_FULL 2
+#define QUEUE_IRQ_SRC_FULL 3
+#define QUEUE_IRQ_SRC_NOT_EMPTY 4
+#define QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY 5
+#define QUEUE_IRQ_SRC_NOT_NEARLY_FULL 6
+#define QUEUE_IRQ_SRC_NOT_FULL 7
+
+struct qmgr_regs {
+ u32 acc[QUEUES][MAX_QUEUE_LENGTH]; /* 0x000 - 0x3FF */
+ u32 stat1[4]; /* 0x400 - 0x40F */
+ u32 stat2[2]; /* 0x410 - 0x417 */
+ u32 statne_h; /* 0x418 - queue nearly empty */
+ u32 statf_h; /* 0x41C - queue full */
+ u32 irqsrc[4]; /* 0x420 - 0x42F IRC source */
+ u32 irqen[2]; /* 0x430 - 0x437 IRQ enabled */
+ u32 irqstat[2]; /* 0x438 - 0x43F - IRQ access only */
+ u32 reserved[1776];
+ u32 sram[2048]; /* 0x2000 - 0x3FFF - config and buffer */
+};
+
+void qmgr_set_irq(unsigned int queue, int src,
+ void (*handler)(void *pdev), void *pdev);
+void qmgr_enable_irq(unsigned int queue);
+void qmgr_disable_irq(unsigned int queue);
+
+/* request_ and release_queue() must be called from non-IRQ context */
+
+#if DEBUG_QMGR
+extern char qmgr_queue_descs[QUEUES][32];
+
+int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+ unsigned int nearly_empty_watermark,
+ unsigned int nearly_full_watermark,
+ const char *desc_format, const char* name);
+#else
+int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+ unsigned int nearly_empty_watermark,
+ unsigned int nearly_full_watermark);
+#define qmgr_request_queue(queue, len, nearly_empty_watermark, \
+ nearly_full_watermark, desc_format, name) \
+ __qmgr_request_queue(queue, len, nearly_empty_watermark, \
+ nearly_full_watermark)
+#endif
+
+void qmgr_release_queue(unsigned int queue);
+
+
+static inline void qmgr_put_entry(unsigned int queue, u32 val)
+{
+ extern struct qmgr_regs __iomem *qmgr_regs;
+#if DEBUG_QMGR
+ BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+ printk(KERN_DEBUG "Queue %s(%i) put %X\n",
+ qmgr_queue_descs[queue], queue, val);
+#endif
+ __raw_writel(val, &qmgr_regs->acc[queue][0]);
+}
+
+static inline u32 qmgr_get_entry(unsigned int queue)
+{
+ u32 val;
+ extern struct qmgr_regs __iomem *qmgr_regs;
+ val = __raw_readl(&qmgr_regs->acc[queue][0]);
+#if DEBUG_QMGR
+ BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+ printk(KERN_DEBUG "Queue %s(%i) get %X\n",
+ qmgr_queue_descs[queue], queue, val);
+#endif
+ return val;
+}
+
+static inline int __qmgr_get_stat1(unsigned int queue)
+{
+ extern struct qmgr_regs __iomem *qmgr_regs;
+ return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
+ >> ((queue & 7) << 2)) & 0xF;
+}
+
+static inline int __qmgr_get_stat2(unsigned int queue)
+{
+ extern struct qmgr_regs __iomem *qmgr_regs;
+ BUG_ON(queue >= HALF_QUEUES);
+ return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
+ >> ((queue & 0xF) << 1)) & 0x3;
+}
+
+/**
+ * qmgr_stat_empty() - checks if a hardware queue is empty
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is empty.
+ */
+static inline int qmgr_stat_empty(unsigned int queue)
+{
+ BUG_ON(queue >= HALF_QUEUES);
+ return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
+}
+
+/**
+ * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is below low watermark.
+ */
+static inline int qmgr_stat_below_low_watermark(unsigned int queue)
+{
+ extern struct qmgr_regs __iomem *qmgr_regs;
+ if (queue >= HALF_QUEUES)
+ return (__raw_readl(&qmgr_regs->statne_h) >>
+ (queue - HALF_QUEUES)) & 0x01;
+ return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
+}
+
+/**
+ * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is above high watermark
+ */
+static inline int qmgr_stat_above_high_watermark(unsigned int queue)
+{
+ BUG_ON(queue >= HALF_QUEUES);
+ return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
+}
+
+/**
+ * qmgr_stat_full() - checks if a hardware queue is full
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue is full.
+ */
+static inline int qmgr_stat_full(unsigned int queue)
+{
+ extern struct qmgr_regs __iomem *qmgr_regs;
+ if (queue >= HALF_QUEUES)
+ return (__raw_readl(&qmgr_regs->statf_h) >>
+ (queue - HALF_QUEUES)) & 0x01;
+ return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
+}
+
+/**
+ * qmgr_stat_underflow() - checks if a hardware queue experienced underflow
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue experienced underflow.
+ */
+static inline int qmgr_stat_underflow(unsigned int queue)
+{
+ return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW;
+}
+
+/**
+ * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
+ * @queue: queue number
+ *
+ * Returns non-zero value if the queue experienced overflow.
+ */
+static inline int qmgr_stat_overflow(unsigned int queue)
+{
+ return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW;
+}
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h
new file mode 100644
index 00000000..54c0af7f
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/system.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/system.h
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ /* ixp4xx does not implement the XScale PWRMODE register,
+ * so it must not call cpu_do_idle() here.
+ */
+#if 0
+ cpu_do_idle();
+#endif
+}
+
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if ( 1 && mode == 's') {
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+ } else {
+ /* Use on-chip reset capability */
+
+ /* set the "key" register to enable access to
+ * "timer" and "enable" registers
+ */
+ *IXP4XX_OSWK = IXP4XX_WDT_KEY;
+
+ /* write 0 to the timer register for an immediate reset */
+ *IXP4XX_OSWT = 0;
+
+ *IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
+ }
+}
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/timex.h b/arch/arm/mach-ixp4xx/include/mach/timex.h
new file mode 100644
index 00000000..c9e930f2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/timex.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/timex.h
+ *
+ */
+
+#include <mach/hardware.h>
+
+/*
+ * We use IXP425 General purpose timer for our timer needs, it runs at
+ * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the
+ * timer register ignores the bottom 2 bits of the LATCH value.
+ */
+#define IXP4XX_TIMER_FREQ 66666000
+#define CLOCK_TICK_RATE \
+ (((IXP4XX_TIMER_FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ)
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
new file mode 100644
index 00000000..80d6da2e
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/udc.h
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/udc.h
+ *
+ */
+#include <asm/mach/udc_pxa2xx.h>
+
+extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
+
diff --git a/arch/arm/mach-ixp4xx/include/mach/uncompress.h b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
new file mode 100644
index 00000000..219d7c1d
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/uncompress.h
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _ARCH_UNCOMPRESS_H_
+#define _ARCH_UNCOMPRESS_H_
+
+#include "ixp4xx-regs.h"
+#include <asm/mach-types.h>
+#include <linux/serial_reg.h>
+
+#define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
+
+volatile u32* uart_base;
+
+static inline void putc(int c)
+{
+ /* Check THRE and TEMT bits before we transmit the character.
+ */
+ while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+
+ *uart_base = c;
+}
+
+static void flush(void)
+{
+}
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ /*
+ * Some boards are using UART2 as console
+ */
+ if (machine_is_adi_coyote() || machine_is_gtwx5715() ||
+ machine_is_gateway7001() || machine_is_wg302v2())
+ uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS;
+ else
+ uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS;
+}
+
+/*
+ * arch_id is a variable in decompress_kernel()
+ */
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/vmalloc.h b/arch/arm/mach-ixp4xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..9bcd64d5
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-ixp4xx/include/mach/vmalloc.h
+ */
+#define VMALLOC_END (0xff000000UL)
+
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
new file mode 100644
index 00000000..58f40041
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-ixp4xx/ixdp425-pci.c
+ *
+ * IXDP425 board-level PCI initialization
+ *
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <asm/mach/pci.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV 4
+#define IRQ_LINES 4
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 11
+#define INTB 10
+#define INTC 9
+#define INTD 8
+
+
+void __init ixdp425_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init ixdp425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[IRQ_LINES] = {
+ IXP4XX_GPIO_IRQ(INTA),
+ IXP4XX_GPIO_IRQ(INTB),
+ IXP4XX_GPIO_IRQ(INTC),
+ IXP4XX_GPIO_IRQ(INTD)
+ };
+
+ if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+ return pci_irq_table[(slot + pin - 2) % 4];
+
+ return -1;
+}
+
+struct hw_pci ixdp425_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = ixdp425_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = ixdp425_map_irq,
+};
+
+int __init ixdp425_pci_init(void)
+{
+ if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
+ machine_is_ixdp465() || machine_is_kixrp435())
+ pci_common_init(&ixdp425_pci);
+ return 0;
+}
+
+subsys_initcall(ixdp425_pci_init);
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
new file mode 100644
index 00000000..dca4f7f9
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -0,0 +1,295 @@
+/*
+ * arch/arm/mach-ixp4xx/ixdp425-setup.c
+ *
+ * IXDP425/IXCDP1100 board-setup
+ *
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/i2c-gpio.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#define IXDP425_SDA_PIN 7
+#define IXDP425_SCL_PIN 6
+
+/* NAND Flash pins */
+#define IXDP425_NAND_NCE_PIN 12
+
+#define IXDP425_NAND_CMD_BYTE 0x01
+#define IXDP425_NAND_ADDR_BYTE 0x02
+
+static struct flash_platform_data ixdp425_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource ixdp425_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp425_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp425_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ixdp425_flash_resource,
+};
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+
+const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ixdp425_partitions[] = {
+ {
+ .name = "ixp400 NAND FS 0",
+ .offset = 0,
+ .size = SZ_8M
+ }, {
+ .name = "ixp400 NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static void
+ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ int offset = (int)this->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_NCE) {
+ gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_LOW);
+ udelay(5);
+ } else
+ gpio_line_set(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_HIGH);
+
+ offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0;
+ offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0;
+ this->priv = (void *)offset;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W + offset);
+}
+
+static struct platform_nand_data ixdp425_flash_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_delay = 30,
+ .options = NAND_NO_AUTOINCR,
+ .part_probe_types = part_probes,
+ .partitions = ixdp425_partitions,
+ .nr_partitions = ARRAY_SIZE(ixdp425_partitions),
+ },
+ .ctrl = {
+ .cmd_ctrl = ixdp425_flash_nand_cmd_ctrl
+ }
+};
+
+static struct resource ixdp425_flash_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ixdp425_flash_nand = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &ixdp425_flash_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &ixdp425_flash_nand_resource,
+};
+#endif /* CONFIG_MTD_NAND_PLATFORM */
+
+static struct i2c_gpio_platform_data ixdp425_i2c_gpio_data = {
+ .sda_pin = IXDP425_SDA_PIN,
+ .scl_pin = IXDP425_SCL_PIN,
+};
+
+static struct platform_device ixdp425_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &ixdp425_i2c_gpio_data,
+ },
+};
+
+static struct resource ixdp425_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct plat_serial8250_port ixdp425_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device ixdp425_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = ixdp425_uart_data,
+ .num_resources = 2,
+ .resource = ixdp425_uart_resources
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info ixdp425_plat_eth[] = {
+ {
+ .phy = 0,
+ .rxq = 3,
+ .txreadyq = 20,
+ }, {
+ .phy = 1,
+ .rxq = 4,
+ .txreadyq = 21,
+ }
+};
+
+static struct platform_device ixdp425_eth[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev.platform_data = ixdp425_plat_eth,
+ }, {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEC,
+ .dev.platform_data = ixdp425_plat_eth + 1,
+ }
+};
+
+static struct platform_device *ixdp425_devices[] __initdata = {
+ &ixdp425_i2c_gpio,
+ &ixdp425_flash,
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+ &ixdp425_flash_nand,
+#endif
+ &ixdp425_uart,
+ &ixdp425_eth[0],
+ &ixdp425_eth[1],
+};
+
+static void __init ixdp425_init(void)
+{
+ ixp4xx_sys_init();
+
+ ixdp425_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ ixdp425_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+ ixdp425_flash_nand_resource.start = IXP4XX_EXP_BUS_BASE(3),
+ ixdp425_flash_nand_resource.end = IXP4XX_EXP_BUS_BASE(3) + 0x10 - 1;
+
+ gpio_line_config(IXDP425_NAND_NCE_PIN, IXP4XX_GPIO_OUT);
+
+ /* Configure expansion bus for NAND Flash */
+ *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_STROBE_T(1) | /* extend by 1 clock */
+ IXP4XX_EXP_BUS_CYCLES(0) | /* Intel cycles */
+ IXP4XX_EXP_BUS_SIZE(0) | /* 512bytes addr space*/
+ IXP4XX_EXP_BUS_WR_EN |
+ IXP4XX_EXP_BUS_BYTE_EN; /* 8 bit data bus */
+#endif
+
+ if (cpu_is_ixp43x()) {
+ ixdp425_uart.num_resources = 1;
+ ixdp425_uart_data[1].flags = 0;
+ }
+
+ platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
+}
+
+#ifdef CONFIG_ARCH_IXDP425
+MACHINE_START(IXDP425, "Intel IXDP425 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = ixdp425_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_IXDP465
+MACHINE_START(IXDP465, "Intel IXDP465 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = ixdp425_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PRPMC1100
+MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = ixdp425_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_KIXRP435
+MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
+ /* Maintainer: MontaVista Software, Inc. */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = ixdp425_init,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
new file mode 100644
index 00000000..e64f6d04
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-ixp4xx/ixdpg425-pci.c
+ *
+ * PCI setup routines for Intel IXDPG425 Platform
+ *
+ * Copyright (C) 2004 MontaVista Softwrae, Inc.
+ *
+ * Maintainer: Deepak Saxena <dsaxena@plexity.net>
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <asm/mach/pci.h>
+
+void __init ixdpg425_pci_preinit(void)
+{
+ irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init ixdpg425_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == 12 || slot == 13)
+ return IRQ_IXP4XX_GPIO7;
+ else if (slot == 14)
+ return IRQ_IXP4XX_GPIO6;
+ else return -1;
+}
+
+struct hw_pci ixdpg425_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = ixdpg425_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = ixdpg425_map_irq,
+};
+
+int __init ixdpg425_pci_init(void)
+{
+ if (machine_is_ixdpg425())
+ pci_common_init(&ixdpg425_pci);
+ return 0;
+}
+
+subsys_initcall(ixdpg425_pci_init);
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
new file mode 100644
index 00000000..a17ed792
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -0,0 +1,735 @@
+/*
+ * Intel IXP4xx Network Processor Engine driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * The code is based on publicly available information:
+ * - Intel IXP4xx Developer's Manual and other e-papers
+ * - Intel IXP400 Access Library Software (BSD license)
+ * - previous works by Christian Hohnstaedt <chohnstaedt@innominate.com>
+ * Thanks, Christian.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <mach/npe.h>
+
+#define DEBUG_MSG 0
+#define DEBUG_FW 0
+
+#define NPE_COUNT 3
+#define MAX_RETRIES 1000 /* microseconds */
+#define NPE_42X_DATA_SIZE 0x800 /* in dwords */
+#define NPE_46X_DATA_SIZE 0x1000
+#define NPE_A_42X_INSTR_SIZE 0x1000
+#define NPE_B_AND_C_42X_INSTR_SIZE 0x800
+#define NPE_46X_INSTR_SIZE 0x1000
+#define REGS_SIZE 0x1000
+
+#define NPE_PHYS_REG 32
+
+#define FW_MAGIC 0xFEEDF00D
+#define FW_BLOCK_TYPE_INSTR 0x0
+#define FW_BLOCK_TYPE_DATA 0x1
+#define FW_BLOCK_TYPE_EOF 0xF
+
+/* NPE exec status (read) and command (write) */
+#define CMD_NPE_STEP 0x01
+#define CMD_NPE_START 0x02
+#define CMD_NPE_STOP 0x03
+#define CMD_NPE_CLR_PIPE 0x04
+#define CMD_CLR_PROFILE_CNT 0x0C
+#define CMD_RD_INS_MEM 0x10 /* instruction memory */
+#define CMD_WR_INS_MEM 0x11
+#define CMD_RD_DATA_MEM 0x12 /* data memory */
+#define CMD_WR_DATA_MEM 0x13
+#define CMD_RD_ECS_REG 0x14 /* exec access register */
+#define CMD_WR_ECS_REG 0x15
+
+#define STAT_RUN 0x80000000
+#define STAT_STOP 0x40000000
+#define STAT_CLEAR 0x20000000
+#define STAT_ECS_K 0x00800000 /* pipeline clean */
+
+#define NPE_STEVT 0x1B
+#define NPE_STARTPC 0x1C
+#define NPE_REGMAP 0x1E
+#define NPE_CINDEX 0x1F
+
+#define INSTR_WR_REG_SHORT 0x0000C000
+#define INSTR_WR_REG_BYTE 0x00004000
+#define INSTR_RD_FIFO 0x0F888220
+#define INSTR_RESET_MBOX 0x0FAC8210
+
+#define ECS_BG_CTXT_REG_0 0x00 /* Background Executing Context */
+#define ECS_BG_CTXT_REG_1 0x01 /* Stack level */
+#define ECS_BG_CTXT_REG_2 0x02
+#define ECS_PRI_1_CTXT_REG_0 0x04 /* Priority 1 Executing Context */
+#define ECS_PRI_1_CTXT_REG_1 0x05 /* Stack level */
+#define ECS_PRI_1_CTXT_REG_2 0x06
+#define ECS_PRI_2_CTXT_REG_0 0x08 /* Priority 2 Executing Context */
+#define ECS_PRI_2_CTXT_REG_1 0x09 /* Stack level */
+#define ECS_PRI_2_CTXT_REG_2 0x0A
+#define ECS_DBG_CTXT_REG_0 0x0C /* Debug Executing Context */
+#define ECS_DBG_CTXT_REG_1 0x0D /* Stack level */
+#define ECS_DBG_CTXT_REG_2 0x0E
+#define ECS_INSTRUCT_REG 0x11 /* NPE Instruction Register */
+
+#define ECS_REG_0_ACTIVE 0x80000000 /* all levels */
+#define ECS_REG_0_NEXTPC_MASK 0x1FFF0000 /* BG/PRI1/PRI2 levels */
+#define ECS_REG_0_LDUR_BITS 8
+#define ECS_REG_0_LDUR_MASK 0x00000700 /* all levels */
+#define ECS_REG_1_CCTXT_BITS 16
+#define ECS_REG_1_CCTXT_MASK 0x000F0000 /* all levels */
+#define ECS_REG_1_SELCTXT_BITS 0
+#define ECS_REG_1_SELCTXT_MASK 0x0000000F /* all levels */
+#define ECS_DBG_REG_2_IF 0x00100000 /* debug level */
+#define ECS_DBG_REG_2_IE 0x00080000 /* debug level */
+
+/* NPE watchpoint_fifo register bit */
+#define WFIFO_VALID 0x80000000
+
+/* NPE messaging_status register bit definitions */
+#define MSGSTAT_OFNE 0x00010000 /* OutFifoNotEmpty */
+#define MSGSTAT_IFNF 0x00020000 /* InFifoNotFull */
+#define MSGSTAT_OFNF 0x00040000 /* OutFifoNotFull */
+#define MSGSTAT_IFNE 0x00080000 /* InFifoNotEmpty */
+#define MSGSTAT_MBINT 0x00100000 /* Mailbox interrupt */
+#define MSGSTAT_IFINT 0x00200000 /* InFifo interrupt */
+#define MSGSTAT_OFINT 0x00400000 /* OutFifo interrupt */
+#define MSGSTAT_WFINT 0x00800000 /* WatchFifo interrupt */
+
+/* NPE messaging_control register bit definitions */
+#define MSGCTL_OUT_FIFO 0x00010000 /* enable output FIFO */
+#define MSGCTL_IN_FIFO 0x00020000 /* enable input FIFO */
+#define MSGCTL_OUT_FIFO_WRITE 0x01000000 /* enable FIFO + WRITE */
+#define MSGCTL_IN_FIFO_WRITE 0x02000000
+
+/* NPE mailbox_status value for reset */
+#define RESET_MBOX_STAT 0x0000F0F0
+
+const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
+
+#define print_npe(pri, npe, fmt, ...) \
+ printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
+
+#if DEBUG_MSG
+#define debug_msg(npe, fmt, ...) \
+ print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
+#else
+#define debug_msg(npe, fmt, ...)
+#endif
+
+static struct {
+ u32 reg, val;
+} ecs_reset[] = {
+ { ECS_BG_CTXT_REG_0, 0xA0000000 },
+ { ECS_BG_CTXT_REG_1, 0x01000000 },
+ { ECS_BG_CTXT_REG_2, 0x00008000 },
+ { ECS_PRI_1_CTXT_REG_0, 0x20000080 },
+ { ECS_PRI_1_CTXT_REG_1, 0x01000000 },
+ { ECS_PRI_1_CTXT_REG_2, 0x00008000 },
+ { ECS_PRI_2_CTXT_REG_0, 0x20000080 },
+ { ECS_PRI_2_CTXT_REG_1, 0x01000000 },
+ { ECS_PRI_2_CTXT_REG_2, 0x00008000 },
+ { ECS_DBG_CTXT_REG_0, 0x20000000 },
+ { ECS_DBG_CTXT_REG_1, 0x00000000 },
+ { ECS_DBG_CTXT_REG_2, 0x001E0000 },
+ { ECS_INSTRUCT_REG, 0x1003C00F },
+};
+
+static struct npe npe_tab[NPE_COUNT] = {
+ {
+ .id = 0,
+ .regs = (struct npe_regs __iomem *)IXP4XX_NPEA_BASE_VIRT,
+ .regs_phys = IXP4XX_NPEA_BASE_PHYS,
+ }, {
+ .id = 1,
+ .regs = (struct npe_regs __iomem *)IXP4XX_NPEB_BASE_VIRT,
+ .regs_phys = IXP4XX_NPEB_BASE_PHYS,
+ }, {
+ .id = 2,
+ .regs = (struct npe_regs __iomem *)IXP4XX_NPEC_BASE_VIRT,
+ .regs_phys = IXP4XX_NPEC_BASE_PHYS,
+ }
+};
+
+int npe_running(struct npe *npe)
+{
+ return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
+}
+
+static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
+{
+ __raw_writel(data, &npe->regs->exec_data);
+ __raw_writel(addr, &npe->regs->exec_addr);
+ __raw_writel(cmd, &npe->regs->exec_status_cmd);
+}
+
+static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
+{
+ __raw_writel(addr, &npe->regs->exec_addr);
+ __raw_writel(cmd, &npe->regs->exec_status_cmd);
+ /* Iintroduce extra read cycles after issuing read command to NPE
+ so that we read the register after the NPE has updated it.
+ This is to overcome race condition between XScale and NPE */
+ __raw_readl(&npe->regs->exec_data);
+ __raw_readl(&npe->regs->exec_data);
+ return __raw_readl(&npe->regs->exec_data);
+}
+
+static void npe_clear_active(struct npe *npe, u32 reg)
+{
+ u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
+ npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
+}
+
+static void npe_start(struct npe *npe)
+{
+ /* ensure only Background Context Stack Level is active */
+ npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
+ npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
+ npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
+
+ __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+ __raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
+}
+
+static void npe_stop(struct npe *npe)
+{
+ __raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
+ __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
+}
+
+static int __must_check npe_debug_instr(struct npe *npe, u32 instr, u32 ctx,
+ u32 ldur)
+{
+ u32 wc;
+ int i;
+
+ /* set the Active bit, and the LDUR, in the debug level */
+ npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
+ ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
+
+ /* set CCTXT at ECS DEBUG L3 to specify in which context to execute
+ the instruction, and set SELCTXT at ECS DEBUG Level to specify
+ which context store to access.
+ Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
+ */
+ npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
+ (ctx << ECS_REG_1_CCTXT_BITS) |
+ (ctx << ECS_REG_1_SELCTXT_BITS));
+
+ /* clear the pipeline */
+ __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+
+ /* load NPE instruction into the instruction register */
+ npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
+
+ /* we need this value later to wait for completion of NPE execution
+ step */
+ wc = __raw_readl(&npe->regs->watch_count);
+
+ /* issue a Step One command via the Execution Control register */
+ __raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
+
+ /* Watch Count register increments when NPE completes an instruction */
+ for (i = 0; i < MAX_RETRIES; i++) {
+ if (wc != __raw_readl(&npe->regs->watch_count))
+ return 0;
+ udelay(1);
+ }
+
+ print_npe(KERN_ERR, npe, "reset: npe_debug_instr(): timeout\n");
+ return -ETIMEDOUT;
+}
+
+static int __must_check npe_logical_reg_write8(struct npe *npe, u32 addr,
+ u8 val, u32 ctx)
+{
+ /* here we build the NPE assembler instruction: mov8 d0, #0 */
+ u32 instr = INSTR_WR_REG_BYTE | /* OpCode */
+ addr << 9 | /* base Operand */
+ (val & 0x1F) << 4 | /* lower 5 bits to immediate data */
+ (val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
+ return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int __must_check npe_logical_reg_write16(struct npe *npe, u32 addr,
+ u16 val, u32 ctx)
+{
+ /* here we build the NPE assembler instruction: mov16 d0, #0 */
+ u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
+ addr << 9 | /* base Operand */
+ (val & 0x1F) << 4 | /* lower 5 bits to immediate data */
+ (val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
+ return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
+}
+
+static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
+ u32 val, u32 ctx)
+{
+ /* write in 16 bit steps first the high and then the low value */
+ if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
+ return -ETIMEDOUT;
+ return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
+}
+
+static int npe_reset(struct npe *npe)
+{
+ u32 val, ctl, exec_count, ctx_reg2;
+ int i;
+
+ ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
+ 0x3F3FFFFF;
+
+ /* disable parity interrupt */
+ __raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
+
+ /* pre exec - debug instruction */
+ /* turn off the halt bit by clearing Execution Count register. */
+ exec_count = __raw_readl(&npe->regs->exec_count);
+ __raw_writel(0, &npe->regs->exec_count);
+ /* ensure that IF and IE are on (temporarily), so that we don't end up
+ stepping forever */
+ ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
+ npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
+ ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
+
+ /* clear the FIFOs */
+ while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
+ ;
+ while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
+ /* read from the outFIFO until empty */
+ print_npe(KERN_DEBUG, npe, "npe_reset: read FIFO = 0x%X\n",
+ __raw_readl(&npe->regs->in_out_fifo));
+
+ while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
+ /* step execution of the NPE intruction to read inFIFO using
+ the Debug Executing Context stack */
+ if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
+ return -ETIMEDOUT;
+
+ /* reset the mailbox reg from the XScale side */
+ __raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
+ /* from NPE side */
+ if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
+ return -ETIMEDOUT;
+
+ /* Reset the physical registers in the NPE register file */
+ for (val = 0; val < NPE_PHYS_REG; val++) {
+ if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
+ return -ETIMEDOUT;
+ /* address is either 0 or 4 */
+ if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
+ return -ETIMEDOUT;
+ }
+
+ /* Reset the context store = each context's Context Store registers */
+
+ /* Context 0 has no STARTPC. Instead, this value is used to set NextPC
+ for Background ECS, to set where NPE starts executing code */
+ val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
+ val &= ~ECS_REG_0_NEXTPC_MASK;
+ val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
+ npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
+
+ for (i = 0; i < 16; i++) {
+ if (i) { /* Context 0 has no STEVT nor STARTPC */
+ /* STEVT = off, 0x80 */
+ if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
+ return -ETIMEDOUT;
+ if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
+ return -ETIMEDOUT;
+ }
+ /* REGMAP = d0->p0, d8->p2, d16->p4 */
+ if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
+ return -ETIMEDOUT;
+ if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
+ return -ETIMEDOUT;
+ }
+
+ /* post exec */
+ /* clear active bit in debug level */
+ npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
+ /* clear the pipeline */
+ __raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
+ /* restore previous values */
+ __raw_writel(exec_count, &npe->regs->exec_count);
+ npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
+
+ /* write reset values to Execution Context Stack registers */
+ for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
+ npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
+ ecs_reset[val].val);
+
+ /* clear the profile counter */
+ __raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
+
+ __raw_writel(0, &npe->regs->exec_count);
+ __raw_writel(0, &npe->regs->action_points[0]);
+ __raw_writel(0, &npe->regs->action_points[1]);
+ __raw_writel(0, &npe->regs->action_points[2]);
+ __raw_writel(0, &npe->regs->action_points[3]);
+ __raw_writel(0, &npe->regs->watch_count);
+
+ val = ixp4xx_read_feature_bits();
+ /* reset the NPE */
+ ixp4xx_write_feature_bits(val &
+ ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
+ /* deassert reset */
+ ixp4xx_write_feature_bits(val |
+ (IXP4XX_FEATURE_RESET_NPEA << npe->id));
+ for (i = 0; i < MAX_RETRIES; i++) {
+ if (ixp4xx_read_feature_bits() &
+ (IXP4XX_FEATURE_RESET_NPEA << npe->id))
+ break; /* NPE is back alive */
+ udelay(1);
+ }
+ if (i == MAX_RETRIES)
+ return -ETIMEDOUT;
+
+ npe_stop(npe);
+
+ /* restore NPE configuration bus Control Register - parity settings */
+ __raw_writel(ctl, &npe->regs->messaging_control);
+ return 0;
+}
+
+
+int npe_send_message(struct npe *npe, const void *msg, const char *what)
+{
+ const u32 *send = msg;
+ int cycles = 0;
+
+ debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
+ what, send[0], send[1]);
+
+ if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
+ debug_msg(npe, "NPE input FIFO not empty\n");
+ return -EIO;
+ }
+
+ __raw_writel(send[0], &npe->regs->in_out_fifo);
+
+ if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
+ debug_msg(npe, "NPE input FIFO full\n");
+ return -EIO;
+ }
+
+ __raw_writel(send[1], &npe->regs->in_out_fifo);
+
+ while ((cycles < MAX_RETRIES) &&
+ (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
+ udelay(1);
+ cycles++;
+ }
+
+ if (cycles == MAX_RETRIES) {
+ debug_msg(npe, "Timeout sending message\n");
+ return -ETIMEDOUT;
+ }
+
+#if DEBUG_MSG > 1
+ debug_msg(npe, "Sending a message took %i cycles\n", cycles);
+#endif
+ return 0;
+}
+
+int npe_recv_message(struct npe *npe, void *msg, const char *what)
+{
+ u32 *recv = msg;
+ int cycles = 0, cnt = 0;
+
+ debug_msg(npe, "Trying to receive message %s\n", what);
+
+ while (cycles < MAX_RETRIES) {
+ if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
+ recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
+ if (cnt == 2)
+ break;
+ } else {
+ udelay(1);
+ cycles++;
+ }
+ }
+
+ switch(cnt) {
+ case 1:
+ debug_msg(npe, "Received [%08X]\n", recv[0]);
+ break;
+ case 2:
+ debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
+ break;
+ }
+
+ if (cycles == MAX_RETRIES) {
+ debug_msg(npe, "Timeout waiting for message\n");
+ return -ETIMEDOUT;
+ }
+
+#if DEBUG_MSG > 1
+ debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
+#endif
+ return 0;
+}
+
+int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
+{
+ int result;
+ u32 *send = msg, recv[2];
+
+ if ((result = npe_send_message(npe, msg, what)) != 0)
+ return result;
+ if ((result = npe_recv_message(npe, recv, what)) != 0)
+ return result;
+
+ if ((recv[0] != send[0]) || (recv[1] != send[1])) {
+ debug_msg(npe, "Message %s: unexpected message received\n",
+ what);
+ return -EIO;
+ }
+ return 0;
+}
+
+
+int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
+{
+ const struct firmware *fw_entry;
+
+ struct dl_block {
+ u32 type;
+ u32 offset;
+ } *blk;
+
+ struct dl_image {
+ u32 magic;
+ u32 id;
+ u32 size;
+ union {
+ u32 data[0];
+ struct dl_block blocks[0];
+ };
+ } *image;
+
+ struct dl_codeblock {
+ u32 npe_addr;
+ u32 size;
+ u32 data[0];
+ } *cb;
+
+ int i, j, err, data_size, instr_size, blocks, table_end;
+ u32 cmd;
+
+ if ((err = request_firmware(&fw_entry, name, dev)) != 0)
+ return err;
+
+ err = -EINVAL;
+ if (fw_entry->size < sizeof(struct dl_image)) {
+ print_npe(KERN_ERR, npe, "incomplete firmware file\n");
+ goto err;
+ }
+ image = (struct dl_image*)fw_entry->data;
+
+#if DEBUG_FW
+ print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n",
+ image->magic, image->id, image->size, image->size * 4);
+#endif
+
+ if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
+ image->id = swab32(image->id);
+ image->size = swab32(image->size);
+ } else if (image->magic != FW_MAGIC) {
+ print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n",
+ image->magic);
+ goto err;
+ }
+ if ((image->size * 4 + sizeof(struct dl_image)) != fw_entry->size) {
+ print_npe(KERN_ERR, npe,
+ "inconsistent size of firmware file\n");
+ goto err;
+ }
+ if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
+ print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n");
+ goto err;
+ }
+ if (image->magic == swab32(FW_MAGIC))
+ for (i = 0; i < image->size; i++)
+ image->data[i] = swab32(image->data[i]);
+
+ if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
+ print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
+ "IXP42x\n");
+ goto err;
+ }
+
+ if (npe_running(npe)) {
+ print_npe(KERN_INFO, npe, "unable to load firmware, NPE is "
+ "already running\n");
+ err = -EBUSY;
+ goto err;
+ }
+#if 0
+ npe_stop(npe);
+ npe_reset(npe);
+#endif
+
+ print_npe(KERN_INFO, npe, "firmware functionality 0x%X, "
+ "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
+ (image->id >> 8) & 0xFF, image->id & 0xFF);
+
+ if (cpu_is_ixp42x()) {
+ if (!npe->id)
+ instr_size = NPE_A_42X_INSTR_SIZE;
+ else
+ instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
+ data_size = NPE_42X_DATA_SIZE;
+ } else {
+ instr_size = NPE_46X_INSTR_SIZE;
+ data_size = NPE_46X_DATA_SIZE;
+ }
+
+ for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
+ blocks++)
+ if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
+ break;
+ if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
+ print_npe(KERN_INFO, npe, "firmware EOF block marker not "
+ "found\n");
+ goto err;
+ }
+
+#if DEBUG_FW
+ print_npe(KERN_DEBUG, npe, "%i firmware blocks found\n", blocks);
+#endif
+
+ table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
+ for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
+ if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
+ || blk->offset < table_end) {
+ print_npe(KERN_INFO, npe, "invalid offset 0x%X of "
+ "firmware block #%i\n", blk->offset, i);
+ goto err;
+ }
+
+ cb = (struct dl_codeblock*)&image->data[blk->offset];
+ if (blk->type == FW_BLOCK_TYPE_INSTR) {
+ if (cb->npe_addr + cb->size > instr_size)
+ goto too_big;
+ cmd = CMD_WR_INS_MEM;
+ } else if (blk->type == FW_BLOCK_TYPE_DATA) {
+ if (cb->npe_addr + cb->size > data_size)
+ goto too_big;
+ cmd = CMD_WR_DATA_MEM;
+ } else {
+ print_npe(KERN_INFO, npe, "invalid firmware block #%i "
+ "type 0x%X\n", i, blk->type);
+ goto err;
+ }
+ if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
+ print_npe(KERN_INFO, npe, "firmware block #%i doesn't "
+ "fit in firmware image: type %c, start 0x%X,"
+ " length 0x%X\n", i,
+ blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+ cb->npe_addr, cb->size);
+ goto err;
+ }
+
+ for (j = 0; j < cb->size; j++)
+ npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
+ }
+
+ npe_start(npe);
+ if (!npe_running(npe))
+ print_npe(KERN_ERR, npe, "unable to start\n");
+ release_firmware(fw_entry);
+ return 0;
+
+too_big:
+ print_npe(KERN_INFO, npe, "firmware block #%i doesn't fit in NPE "
+ "memory: type %c, start 0x%X, length 0x%X\n", i,
+ blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
+ cb->npe_addr, cb->size);
+err:
+ release_firmware(fw_entry);
+ return err;
+}
+
+
+struct npe *npe_request(unsigned id)
+{
+ if (id < NPE_COUNT)
+ if (npe_tab[id].valid)
+ if (try_module_get(THIS_MODULE))
+ return &npe_tab[id];
+ return NULL;
+}
+
+void npe_release(struct npe *npe)
+{
+ module_put(THIS_MODULE);
+}
+
+
+static int __init npe_init_module(void)
+{
+
+ int i, found = 0;
+
+ for (i = 0; i < NPE_COUNT; i++) {
+ struct npe *npe = &npe_tab[i];
+ if (!(ixp4xx_read_feature_bits() &
+ (IXP4XX_FEATURE_RESET_NPEA << i)))
+ continue; /* NPE already disabled or not present */
+ if (!(npe->mem_res = request_mem_region(npe->regs_phys,
+ REGS_SIZE,
+ npe_name(npe)))) {
+ print_npe(KERN_ERR, npe,
+ "failed to request memory region\n");
+ continue;
+ }
+
+ if (npe_reset(npe))
+ continue;
+ npe->valid = 1;
+ found++;
+ }
+
+ if (!found)
+ return -ENODEV;
+ return 0;
+}
+
+static void __exit npe_cleanup_module(void)
+{
+ int i;
+
+ for (i = 0; i < NPE_COUNT; i++)
+ if (npe_tab[i].mem_res) {
+ npe_reset(&npe_tab[i]);
+ release_resource(npe_tab[i].mem_res);
+ }
+}
+
+module_init(npe_init_module);
+module_exit(npe_cleanup_module);
+
+MODULE_AUTHOR("Krzysztof Halasa");
+MODULE_LICENSE("GPL v2");
+
+EXPORT_SYMBOL(npe_names);
+EXPORT_SYMBOL(npe_running);
+EXPORT_SYMBOL(npe_request);
+EXPORT_SYMBOL(npe_release);
+EXPORT_SYMBOL(npe_load_firmware);
+EXPORT_SYMBOL(npe_send_message);
+EXPORT_SYMBOL(npe_recv_message);
+EXPORT_SYMBOL(npe_send_recv_message);
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
new file mode 100644
index 00000000..852f7c9f
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -0,0 +1,382 @@
+/*
+ * Intel IXP4xx Queue Manager driver for Linux
+ *
+ * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ */
+
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <mach/qmgr.h>
+
+struct qmgr_regs __iomem *qmgr_regs;
+static struct resource *mem_res;
+static spinlock_t qmgr_lock;
+static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
+static void (*irq_handlers[QUEUES])(void *pdev);
+static void *irq_pdevs[QUEUES];
+
+#if DEBUG_QMGR
+char qmgr_queue_descs[QUEUES][32];
+#endif
+
+void qmgr_set_irq(unsigned int queue, int src,
+ void (*handler)(void *pdev), void *pdev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&qmgr_lock, flags);
+ if (queue < HALF_QUEUES) {
+ u32 __iomem *reg;
+ int bit;
+ BUG_ON(src > QUEUE_IRQ_SRC_NOT_FULL);
+ reg = &qmgr_regs->irqsrc[queue >> 3]; /* 8 queues per u32 */
+ bit = (queue % 8) * 4; /* 3 bits + 1 reserved bit per queue */
+ __raw_writel((__raw_readl(reg) & ~(7 << bit)) | (src << bit),
+ reg);
+ } else
+ /* IRQ source for queues 32-63 is fixed */
+ BUG_ON(src != QUEUE_IRQ_SRC_NOT_NEARLY_EMPTY);
+
+ irq_handlers[queue] = handler;
+ irq_pdevs[queue] = pdev;
+ spin_unlock_irqrestore(&qmgr_lock, flags);
+}
+
+
+static irqreturn_t qmgr_irq1_a0(int irq, void *pdev)
+{
+ int i, ret = 0;
+ u32 en_bitmap, src, stat;
+
+ /* ACK - it may clear any bits so don't rely on it */
+ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]);
+
+ en_bitmap = qmgr_regs->irqen[0];
+ while (en_bitmap) {
+ i = __fls(en_bitmap); /* number of the last "low" queue */
+ en_bitmap &= ~BIT(i);
+ src = qmgr_regs->irqsrc[i >> 3];
+ stat = qmgr_regs->stat1[i >> 3];
+ if (src & 4) /* the IRQ condition is inverted */
+ stat = ~stat;
+ if (stat & BIT(src & 3)) {
+ irq_handlers[i](irq_pdevs[i]);
+ ret = IRQ_HANDLED;
+ }
+ }
+ return ret;
+}
+
+
+static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
+{
+ int i, ret = 0;
+ u32 req_bitmap;
+
+ /* ACK - it may clear any bits so don't rely on it */
+ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]);
+
+ req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h;
+ while (req_bitmap) {
+ i = __fls(req_bitmap); /* number of the last "high" queue */
+ req_bitmap &= ~BIT(i);
+ irq_handlers[HALF_QUEUES + i](irq_pdevs[HALF_QUEUES + i]);
+ ret = IRQ_HANDLED;
+ }
+ return ret;
+}
+
+
+static irqreturn_t qmgr_irq(int irq, void *pdev)
+{
+ int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1);
+ u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
+
+ if (!req_bitmap)
+ return 0;
+ __raw_writel(req_bitmap, &qmgr_regs->irqstat[half]); /* ACK */
+
+ while (req_bitmap) {
+ i = __fls(req_bitmap); /* number of the last queue */
+ req_bitmap &= ~BIT(i);
+ i += half * HALF_QUEUES;
+ irq_handlers[i](irq_pdevs[i]);
+ }
+ return IRQ_HANDLED;
+}
+
+
+void qmgr_enable_irq(unsigned int queue)
+{
+ unsigned long flags;
+ int half = queue / 32;
+ u32 mask = 1 << (queue & (HALF_QUEUES - 1));
+
+ spin_lock_irqsave(&qmgr_lock, flags);
+ __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) | mask,
+ &qmgr_regs->irqen[half]);
+ spin_unlock_irqrestore(&qmgr_lock, flags);
+}
+
+void qmgr_disable_irq(unsigned int queue)
+{
+ unsigned long flags;
+ int half = queue / 32;
+ u32 mask = 1 << (queue & (HALF_QUEUES - 1));
+
+ spin_lock_irqsave(&qmgr_lock, flags);
+ __raw_writel(__raw_readl(&qmgr_regs->irqen[half]) & ~mask,
+ &qmgr_regs->irqen[half]);
+ __raw_writel(mask, &qmgr_regs->irqstat[half]); /* clear */
+ spin_unlock_irqrestore(&qmgr_lock, flags);
+}
+
+static inline void shift_mask(u32 *mask)
+{
+ mask[3] = mask[3] << 1 | mask[2] >> 31;
+ mask[2] = mask[2] << 1 | mask[1] >> 31;
+ mask[1] = mask[1] << 1 | mask[0] >> 31;
+ mask[0] <<= 1;
+}
+
+#if DEBUG_QMGR
+int qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+ unsigned int nearly_empty_watermark,
+ unsigned int nearly_full_watermark,
+ const char *desc_format, const char* name)
+#else
+int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
+ unsigned int nearly_empty_watermark,
+ unsigned int nearly_full_watermark)
+#endif
+{
+ u32 cfg, addr = 0, mask[4]; /* in 16-dwords */
+ int err;
+
+ BUG_ON(queue >= QUEUES);
+
+ if ((nearly_empty_watermark | nearly_full_watermark) & ~7)
+ return -EINVAL;
+
+ switch (len) {
+ case 16:
+ cfg = 0 << 24;
+ mask[0] = 0x1;
+ break;
+ case 32:
+ cfg = 1 << 24;
+ mask[0] = 0x3;
+ break;
+ case 64:
+ cfg = 2 << 24;
+ mask[0] = 0xF;
+ break;
+ case 128:
+ cfg = 3 << 24;
+ mask[0] = 0xFF;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ cfg |= nearly_empty_watermark << 26;
+ cfg |= nearly_full_watermark << 29;
+ len /= 16; /* in 16-dwords: 1, 2, 4 or 8 */
+ mask[1] = mask[2] = mask[3] = 0;
+
+ if (!try_module_get(THIS_MODULE))
+ return -ENODEV;
+
+ spin_lock_irq(&qmgr_lock);
+ if (__raw_readl(&qmgr_regs->sram[queue])) {
+ err = -EBUSY;
+ goto err;
+ }
+
+ while (1) {
+ if (!(used_sram_bitmap[0] & mask[0]) &&
+ !(used_sram_bitmap[1] & mask[1]) &&
+ !(used_sram_bitmap[2] & mask[2]) &&
+ !(used_sram_bitmap[3] & mask[3]))
+ break; /* found free space */
+
+ addr++;
+ shift_mask(mask);
+ if (addr + len > ARRAY_SIZE(qmgr_regs->sram)) {
+ printk(KERN_ERR "qmgr: no free SRAM space for"
+ " queue %i\n", queue);
+ err = -ENOMEM;
+ goto err;
+ }
+ }
+
+ used_sram_bitmap[0] |= mask[0];
+ used_sram_bitmap[1] |= mask[1];
+ used_sram_bitmap[2] |= mask[2];
+ used_sram_bitmap[3] |= mask[3];
+ __raw_writel(cfg | (addr << 14), &qmgr_regs->sram[queue]);
+#if DEBUG_QMGR
+ snprintf(qmgr_queue_descs[queue], sizeof(qmgr_queue_descs[0]),
+ desc_format, name);
+ printk(KERN_DEBUG "qmgr: requested queue %s(%i) addr = 0x%02X\n",
+ qmgr_queue_descs[queue], queue, addr);
+#endif
+ spin_unlock_irq(&qmgr_lock);
+ return 0;
+
+err:
+ spin_unlock_irq(&qmgr_lock);
+ module_put(THIS_MODULE);
+ return err;
+}
+
+void qmgr_release_queue(unsigned int queue)
+{
+ u32 cfg, addr, mask[4];
+
+ BUG_ON(queue >= QUEUES); /* not in valid range */
+
+ spin_lock_irq(&qmgr_lock);
+ cfg = __raw_readl(&qmgr_regs->sram[queue]);
+ addr = (cfg >> 14) & 0xFF;
+
+ BUG_ON(!addr); /* not requested */
+
+ switch ((cfg >> 24) & 3) {
+ case 0: mask[0] = 0x1; break;
+ case 1: mask[0] = 0x3; break;
+ case 2: mask[0] = 0xF; break;
+ case 3: mask[0] = 0xFF; break;
+ }
+
+ mask[1] = mask[2] = mask[3] = 0;
+
+ while (addr--)
+ shift_mask(mask);
+
+#if DEBUG_QMGR
+ printk(KERN_DEBUG "qmgr: releasing queue %s(%i)\n",
+ qmgr_queue_descs[queue], queue);
+ qmgr_queue_descs[queue][0] = '\x0';
+#endif
+
+ while ((addr = qmgr_get_entry(queue)))
+ printk(KERN_ERR "qmgr: released queue %i not empty: 0x%08X\n",
+ queue, addr);
+
+ __raw_writel(0, &qmgr_regs->sram[queue]);
+
+ used_sram_bitmap[0] &= ~mask[0];
+ used_sram_bitmap[1] &= ~mask[1];
+ used_sram_bitmap[2] &= ~mask[2];
+ used_sram_bitmap[3] &= ~mask[3];
+ irq_handlers[queue] = NULL; /* catch IRQ bugs */
+ spin_unlock_irq(&qmgr_lock);
+
+ module_put(THIS_MODULE);
+}
+
+static int qmgr_init(void)
+{
+ int i, err;
+ irq_handler_t handler1, handler2;
+
+ mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
+ IXP4XX_QMGR_REGION_SIZE,
+ "IXP4xx Queue Manager");
+ if (mem_res == NULL)
+ return -EBUSY;
+
+ qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
+ if (qmgr_regs == NULL) {
+ err = -ENOMEM;
+ goto error_map;
+ }
+
+ /* reset qmgr registers */
+ for (i = 0; i < 4; i++) {
+ __raw_writel(0x33333333, &qmgr_regs->stat1[i]);
+ __raw_writel(0, &qmgr_regs->irqsrc[i]);
+ }
+ for (i = 0; i < 2; i++) {
+ __raw_writel(0, &qmgr_regs->stat2[i]);
+ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[i]); /* clear */
+ __raw_writel(0, &qmgr_regs->irqen[i]);
+ }
+
+ __raw_writel(0xFFFFFFFF, &qmgr_regs->statne_h);
+ __raw_writel(0, &qmgr_regs->statf_h);
+
+ for (i = 0; i < QUEUES; i++)
+ __raw_writel(0, &qmgr_regs->sram[i]);
+
+ if (cpu_is_ixp42x_rev_a0()) {
+ handler1 = qmgr_irq1_a0;
+ handler2 = qmgr_irq2_a0;
+ } else
+ handler1 = handler2 = qmgr_irq;
+
+ err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager",
+ NULL);
+ if (err) {
+ printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
+ IRQ_IXP4XX_QM1, err);
+ goto error_irq;
+ }
+
+ err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager",
+ NULL);
+ if (err) {
+ printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
+ IRQ_IXP4XX_QM2, err);
+ goto error_irq2;
+ }
+
+ used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
+ spin_lock_init(&qmgr_lock);
+
+ printk(KERN_INFO "IXP4xx Queue Manager initialized.\n");
+ return 0;
+
+error_irq2:
+ free_irq(IRQ_IXP4XX_QM1, NULL);
+error_irq:
+ iounmap(qmgr_regs);
+error_map:
+ release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
+ return err;
+}
+
+static void qmgr_remove(void)
+{
+ free_irq(IRQ_IXP4XX_QM1, NULL);
+ free_irq(IRQ_IXP4XX_QM2, NULL);
+ synchronize_irq(IRQ_IXP4XX_QM1);
+ synchronize_irq(IRQ_IXP4XX_QM2);
+ iounmap(qmgr_regs);
+ release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
+}
+
+module_init(qmgr_init);
+module_exit(qmgr_remove);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Krzysztof Halasa");
+
+EXPORT_SYMBOL(qmgr_regs);
+EXPORT_SYMBOL(qmgr_set_irq);
+EXPORT_SYMBOL(qmgr_enable_irq);
+EXPORT_SYMBOL(qmgr_disable_irq);
+#if DEBUG_QMGR
+EXPORT_SYMBOL(qmgr_queue_descs);
+EXPORT_SYMBOL(qmgr_request_queue);
+#else
+EXPORT_SYMBOL(__qmgr_request_queue);
+#endif
+EXPORT_SYMBOL(qmgr_release_queue);
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
new file mode 100644
index 00000000..428d1202
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-pci.c
+ *
+ * NAS 100d board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV 3
+#define IRQ_LINES 3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 11
+#define INTB 10
+#define INTC 9
+#define INTD 8
+#define INTE 7
+
+void __init nas100d_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[MAX_DEV][IRQ_LINES] = {
+ { IXP4XX_GPIO_IRQ(INTA), -1, -1 },
+ { IXP4XX_GPIO_IRQ(INTB), -1, -1 },
+ { IXP4XX_GPIO_IRQ(INTC), IXP4XX_GPIO_IRQ(INTD),
+ IXP4XX_GPIO_IRQ(INTE) },
+ };
+
+ if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+ return pci_irq_table[slot - 1][pin - 1];
+
+ return -1;
+}
+
+struct hw_pci __initdata nas100d_pci = {
+ .nr_controllers = 1,
+ .preinit = nas100d_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = nas100d_map_irq,
+};
+
+int __init nas100d_pci_init(void)
+{
+ if (machine_is_nas100d())
+ pci_common_init(&nas100d_pci);
+
+ return 0;
+}
+
+subsys_initcall(nas100d_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
new file mode 100644
index 00000000..f18fee74
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -0,0 +1,322 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-setup.c
+ *
+ * NAS 100d board-setup
+ *
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ *
+ * based on ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * based on nas100d-power.c:
+ * Copyright (C) 2005 Tower Technologies
+ * based on nas100d-io.c
+ * Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/if_ether.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/reboot.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/gpio.h>
+
+#define NAS100D_SDA_PIN 5
+#define NAS100D_SCL_PIN 6
+
+/* Buttons */
+#define NAS100D_PB_GPIO 14 /* power button */
+#define NAS100D_RB_GPIO 4 /* reset button */
+
+/* Power control */
+#define NAS100D_PO_GPIO 12 /* power off */
+
+/* LEDs */
+#define NAS100D_LED_WLAN_GPIO 0
+#define NAS100D_LED_DISK_GPIO 3
+#define NAS100D_LED_PWR_GPIO 15
+
+static struct flash_platform_data nas100d_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource nas100d_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nas100d_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev.platform_data = &nas100d_flash_data,
+ .num_resources = 1,
+ .resource = &nas100d_flash_resource,
+};
+
+static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static struct gpio_led nas100d_led_pins[] = {
+ {
+ .name = "nas100d:green:wlan",
+ .gpio = NAS100D_LED_WLAN_GPIO,
+ .active_low = true,
+ },
+ {
+ .name = "nas100d:blue:power", /* (off=flashing) */
+ .gpio = NAS100D_LED_PWR_GPIO,
+ .active_low = true,
+ },
+ {
+ .name = "nas100d:yellow:disk",
+ .gpio = NAS100D_LED_DISK_GPIO,
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data nas100d_led_data = {
+ .num_leds = ARRAY_SIZE(nas100d_led_pins),
+ .leds = nas100d_led_pins,
+};
+
+static struct platform_device nas100d_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &nas100d_led_data,
+};
+
+static struct i2c_gpio_platform_data nas100d_i2c_gpio_data = {
+ .sda_pin = NAS100D_SDA_PIN,
+ .scl_pin = NAS100D_SCL_PIN,
+};
+
+static struct platform_device nas100d_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &nas100d_i2c_gpio_data,
+ },
+};
+
+static struct resource nas100d_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port nas100d_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device nas100d_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = nas100d_uart_data,
+ .num_resources = 2,
+ .resource = nas100d_uart_resources,
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info nas100d_plat_eth[] = {
+ {
+ .phy = 0,
+ .rxq = 3,
+ .txreadyq = 20,
+ }
+};
+
+static struct platform_device nas100d_eth[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev.platform_data = nas100d_plat_eth,
+ }
+};
+
+static struct platform_device *nas100d_devices[] __initdata = {
+ &nas100d_i2c_gpio,
+ &nas100d_flash,
+ &nas100d_leds,
+ &nas100d_eth[0],
+};
+
+static void nas100d_power_off(void)
+{
+ /* This causes the box to drop the power and go dead. */
+
+ /* enable the pwr cntl gpio */
+ gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT);
+
+ /* do the deed */
+ gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+/* This is used to make sure the power-button pusher is serious. The button
+ * must be held until the value of this counter reaches zero.
+ */
+static int power_button_countdown;
+
+/* Must hold the button down for at least this many counts to be processed */
+#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
+
+static void nas100d_power_handler(unsigned long data);
+static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler, 0, 0);
+
+static void nas100d_power_handler(unsigned long data)
+{
+ /* This routine is called twice per second to check the
+ * state of the power button.
+ */
+
+ if (gpio_get_value(NAS100D_PB_GPIO)) {
+
+ /* IO Pin is 1 (button pushed) */
+ if (power_button_countdown > 0)
+ power_button_countdown--;
+
+ } else {
+
+ /* Done on button release, to allow for auto-power-on mods. */
+ if (power_button_countdown == 0) {
+ /* Signal init to do the ctrlaltdel action,
+ * this will bypass init if it hasn't started
+ * and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ /* Change the state of the power LED to "blink" */
+ gpio_line_set(NAS100D_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
+ } else {
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+ }
+ }
+
+ mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
+}
+
+static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset, it shuts the machine down directly. */
+ machine_power_off();
+
+ return IRQ_HANDLED;
+}
+
+static void __init nas100d_init(void)
+{
+ uint8_t __iomem *f;
+ int i;
+
+ ixp4xx_sys_init();
+
+ /* gpio 14 and 15 are _not_ clocks */
+ *IXP4XX_GPIO_GPCLKR = 0;
+
+ nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ nas100d_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ i2c_register_board_info(0, nas100d_i2c_board_info,
+ ARRAY_SIZE(nas100d_i2c_board_info));
+
+ /*
+ * This is only useful on a modified machine, but it is valuable
+ * to have it first in order to see debug messages, and so that
+ * it does *not* get removed if platform_add_devices fails!
+ */
+ (void)platform_device_register(&nas100d_uart);
+
+ platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
+
+ pm_power_off = nas100d_power_off;
+
+ if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "NAS100D reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(NAS100D_RB_GPIO));
+ }
+
+ /* The power button on the Iomega NAS100d is on GPIO 14, but
+ * it cannot handle interrupts on that GPIO line. So we'll
+ * have to poll it with a kernel timer.
+ */
+
+ /* Make sure that the power button GPIO is set up as an input */
+ gpio_line_config(NAS100D_PB_GPIO, IXP4XX_GPIO_IN);
+
+ /* Set the initial value for the power button IRQ handler */
+ power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
+
+ mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
+
+ /*
+ * Map in a portion of the flash and read the MAC address.
+ * Since it is stored in BE in the flash itself, we need to
+ * byteswap it if we're in LE mode.
+ */
+ f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x1000000);
+ if (f) {
+ for (i = 0; i < 6; i++)
+#ifdef __ARMEB__
+ nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + i);
+#else
+ nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + (i^3));
+#endif
+ iounmap(f);
+ }
+ printk(KERN_INFO "NAS100D: Using MAC address %pM for port 0\n",
+ nas100d_plat_eth[0].hwaddr);
+
+}
+
+MACHINE_START(NAS100D, "Iomega NAS 100d")
+ /* Maintainer: www.nslu2-linux.org */
+ .boot_params = 0x00000100,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .init_machine = nas100d_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
new file mode 100644
index 00000000..2e85f76b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -0,0 +1,72 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-pci.c
+ *
+ * NSLU2 board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#define MAX_DEV 3
+#define IRQ_LINES 3
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 11
+#define INTB 10
+#define INTC 9
+#define INTD 8
+
+void __init nslu2_pci_preinit(void)
+{
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static int pci_irq_table[IRQ_LINES] = {
+ IXP4XX_GPIO_IRQ(INTA),
+ IXP4XX_GPIO_IRQ(INTB),
+ IXP4XX_GPIO_IRQ(INTC),
+ };
+
+ if (slot >= 1 && slot <= MAX_DEV && pin >= 1 && pin <= IRQ_LINES)
+ return pci_irq_table[(slot + pin - 2) % IRQ_LINES];
+
+ return -1;
+}
+
+struct hw_pci __initdata nslu2_pci = {
+ .nr_controllers = 1,
+ .preinit = nslu2_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = nslu2_map_irq,
+};
+
+int __init nslu2_pci_init(void) /* monkey see, monkey do */
+{
+ if (machine_is_nslu2())
+ pci_common_init(&nslu2_pci);
+
+ return 0;
+}
+
+subsys_initcall(nslu2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
new file mode 100644
index 00000000..f79b62eb
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -0,0 +1,308 @@
+/*
+ * arch/arm/mach-ixp4xx/nslu2-setup.c
+ *
+ * NSLU2 board-setup
+ *
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ *
+ * based on ixdp425-setup.c:
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ * based on nslu2-power.c:
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * Author: Mark Rakes <mrakes at mac.com>
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/if_ether.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/leds.h>
+#include <linux/reboot.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/io.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/time.h>
+#include <asm/gpio.h>
+
+#define NSLU2_SDA_PIN 7
+#define NSLU2_SCL_PIN 6
+
+/* NSLU2 Timer */
+#define NSLU2_FREQ 66000000
+
+/* Buttons */
+#define NSLU2_PB_GPIO 5 /* power button */
+#define NSLU2_PO_GPIO 8 /* power off */
+#define NSLU2_RB_GPIO 12 /* reset button */
+
+/* Buzzer */
+#define NSLU2_GPIO_BUZZ 4
+
+/* LEDs */
+#define NSLU2_LED_RED_GPIO 0
+#define NSLU2_LED_GRN_GPIO 1
+#define NSLU2_LED_DISK1_GPIO 3
+#define NSLU2_LED_DISK2_GPIO 2
+
+static struct flash_platform_data nslu2_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource nslu2_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nslu2_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev.platform_data = &nslu2_flash_data,
+ .num_resources = 1,
+ .resource = &nslu2_flash_resource,
+};
+
+static struct i2c_gpio_platform_data nslu2_i2c_gpio_data = {
+ .sda_pin = NSLU2_SDA_PIN,
+ .scl_pin = NSLU2_SCL_PIN,
+};
+
+static struct i2c_board_info __initdata nslu2_i2c_board_info [] = {
+ {
+ I2C_BOARD_INFO("x1205", 0x6f),
+ },
+};
+
+static struct gpio_led nslu2_led_pins[] = {
+ {
+ .name = "nslu2:green:ready",
+ .gpio = NSLU2_LED_GRN_GPIO,
+ },
+ {
+ .name = "nslu2:red:status",
+ .gpio = NSLU2_LED_RED_GPIO,
+ },
+ {
+ .name = "nslu2:green:disk-1",
+ .gpio = NSLU2_LED_DISK1_GPIO,
+ .active_low = true,
+ },
+ {
+ .name = "nslu2:green:disk-2",
+ .gpio = NSLU2_LED_DISK2_GPIO,
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data nslu2_led_data = {
+ .num_leds = ARRAY_SIZE(nslu2_led_pins),
+ .leds = nslu2_led_pins,
+};
+
+static struct platform_device nslu2_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &nslu2_led_data,
+};
+
+static struct platform_device nslu2_i2c_gpio = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &nslu2_i2c_gpio_data,
+ },
+};
+
+static struct platform_device nslu2_beeper = {
+ .name = "ixp4xx-beeper",
+ .id = NSLU2_GPIO_BUZZ,
+ .num_resources = 0,
+};
+
+static struct resource nslu2_uart_resources[] = {
+ {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct plat_serial8250_port nslu2_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { }
+};
+
+static struct platform_device nslu2_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = nslu2_uart_data,
+ .num_resources = 2,
+ .resource = nslu2_uart_resources,
+};
+
+/* Built-in 10/100 Ethernet MAC interfaces */
+static struct eth_plat_info nslu2_plat_eth[] = {
+ {
+ .phy = 1,
+ .rxq = 3,
+ .txreadyq = 20,
+ }
+};
+
+static struct platform_device nslu2_eth[] = {
+ {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev.platform_data = nslu2_plat_eth,
+ }
+};
+
+static struct platform_device *nslu2_devices[] __initdata = {
+ &nslu2_i2c_gpio,
+ &nslu2_flash,
+ &nslu2_beeper,
+ &nslu2_leds,
+ &nslu2_eth[0],
+};
+
+static void nslu2_power_off(void)
+{
+ /* This causes the box to drop the power and go dead. */
+
+ /* enable the pwr cntl gpio */
+ gpio_line_config(NSLU2_PO_GPIO, IXP4XX_GPIO_OUT);
+
+ /* do the deed */
+ gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static irqreturn_t nslu2_power_handler(int irq, void *dev_id)
+{
+ /* Signal init to do the ctrlaltdel action, this will bypass init if
+ * it hasn't started and do a kernel_restart.
+ */
+ ctrl_alt_del();
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t nslu2_reset_handler(int irq, void *dev_id)
+{
+ /* This is the paper-clip reset, it shuts the machine down directly.
+ */
+ machine_power_off();
+
+ return IRQ_HANDLED;
+}
+
+static void __init nslu2_timer_init(void)
+{
+ /* The xtal on this machine is non-standard. */
+ ixp4xx_timer_freq = NSLU2_FREQ;
+
+ /* Call standard timer_init function. */
+ ixp4xx_timer_init();
+}
+
+static struct sys_timer nslu2_timer = {
+ .init = nslu2_timer_init,
+};
+
+static void __init nslu2_init(void)
+{
+ uint8_t __iomem *f;
+ int i;
+
+ ixp4xx_sys_init();
+
+ nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ nslu2_flash_resource.end =
+ IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+ i2c_register_board_info(0, nslu2_i2c_board_info,
+ ARRAY_SIZE(nslu2_i2c_board_info));
+
+ /*
+ * This is only useful on a modified machine, but it is valuable
+ * to have it first in order to see debug messages, and so that
+ * it does *not* get removed if platform_add_devices fails!
+ */
+ (void)platform_device_register(&nslu2_uart);
+
+ platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
+
+ pm_power_off = nslu2_power_off;
+
+ if (request_irq(gpio_to_irq(NSLU2_RB_GPIO), &nslu2_reset_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_LOW,
+ "NSLU2 reset button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+ gpio_to_irq(NSLU2_RB_GPIO));
+ }
+
+ if (request_irq(gpio_to_irq(NSLU2_PB_GPIO), &nslu2_power_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_HIGH,
+ "NSLU2 power button", NULL) < 0) {
+
+ printk(KERN_DEBUG "Power Button IRQ %d not available\n",
+ gpio_to_irq(NSLU2_PB_GPIO));
+ }
+
+ /*
+ * Map in a portion of the flash and read the MAC address.
+ * Since it is stored in BE in the flash itself, we need to
+ * byteswap it if we're in LE mode.
+ */
+ f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x40000);
+ if (f) {
+ for (i = 0; i < 6; i++)
+#ifdef __ARMEB__
+ nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + i);
+#else
+ nslu2_plat_eth[0].hwaddr[i] = readb(f + 0x3FFB0 + (i^3));
+#endif
+ iounmap(f);
+ }
+ printk(KERN_INFO "NSLU2: Using MAC address %pM for port 0\n",
+ nslu2_plat_eth[0].hwaddr);
+
+}
+
+MACHINE_START(NSLU2, "Linksys NSLU2")
+ /* Maintainer: www.nslu2-linux.org */
+ .boot_params = 0x00000100,
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &nslu2_timer,
+ .init_machine = nslu2_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c
new file mode 100644
index 00000000..03bdec51
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/vulcan-pci.c
@@ -0,0 +1,73 @@
+/*
+ * arch/arch/mach-ixp4xx/vulcan-pci.c
+ *
+ * Vulcan board-level PCI initialization
+ *
+ * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org>
+ *
+ * based on ixdp425-pci.c:
+ * Copyright (C) 2002 Intel Corporation.
+ * Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define INTA 2
+#define INTB 3
+
+void __init vulcan_pci_preinit(void)
+{
+#ifndef CONFIG_IXP4XX_INDIRECT_PCI
+ /*
+ * Cardbus bridge wants way more than the SoC can actually offer,
+ * and leaves the whole PCI bus in a mess. Artificially limit it
+ * to 8MB per region. Of course indirect mode doesn't have this
+ * limitation...
+ */
+ pci_cardbus_mem_size = SZ_8M;
+ pr_info("Vulcan PCI: limiting CardBus memory size to %dMB\n",
+ (int)(pci_cardbus_mem_size >> 20));
+#endif
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ ixp4xx_pci_preinit();
+}
+
+static int __init vulcan_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == 1)
+ return IXP4XX_GPIO_IRQ(INTA);
+
+ if (slot == 2)
+ return IXP4XX_GPIO_IRQ(INTB);
+
+ return -1;
+}
+
+struct hw_pci vulcan_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = vulcan_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = vulcan_map_irq,
+};
+
+int __init vulcan_pci_init(void)
+{
+ if (machine_is_arcom_vulcan())
+ pci_common_init(&vulcan_pci);
+ return 0;
+}
+
+subsys_initcall(vulcan_pci_init);
diff --git a/arch/arm/mach-ixp4xx/vulcan-setup.c b/arch/arm/mach-ixp4xx/vulcan-setup.c
new file mode 100644
index 00000000..4e72cfdd
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/vulcan-setup.c
@@ -0,0 +1,244 @@
+/*
+ * arch/arm/mach-ixp4xx/vulcan-setup.c
+ *
+ * Arcom/Eurotech Vulcan board-setup
+ *
+ * Copyright (C) 2010 Marc Zyngier <maz@misterjones.org>
+ *
+ * based on fsg-setup.c:
+ * Copyright (C) 2008 Rod Whitby <rod@whitby.id.au>
+ */
+
+#include <linux/if_ether.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+#include <linux/w1-gpio.h>
+#include <linux/mtd/plat-ram.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data vulcan_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource vulcan_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device vulcan_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &vulcan_flash_data,
+ },
+ .resource = &vulcan_flash_resource,
+ .num_resources = 1,
+};
+
+static struct platdata_mtd_ram vulcan_sram_data = {
+ .mapname = "Vulcan SRAM",
+ .bankwidth = 1,
+};
+
+static struct resource vulcan_sram_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device vulcan_sram = {
+ .name = "mtd-ram",
+ .id = 0,
+ .dev = {
+ .platform_data = &vulcan_sram_data,
+ },
+ .resource = &vulcan_sram_resource,
+ .num_resources = 1,
+};
+
+static struct resource vulcan_uart_resources[] = {
+ [0] = {
+ .start = IXP4XX_UART1_BASE_PHYS,
+ .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct plat_serial8250_port vulcan_uart_data[] = {
+ [0] = {
+ .mapbase = IXP4XX_UART1_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ [1] = {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ [2] = {
+ .irq = IXP4XX_GPIO_IRQ(4),
+ .irqflags = IRQF_TRIGGER_LOW,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .uartclk = 1843200,
+ },
+ [3] = {
+ .irq = IXP4XX_GPIO_IRQ(4),
+ .irqflags = IRQF_TRIGGER_LOW,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .uartclk = 1843200,
+ },
+ { }
+};
+
+static struct platform_device vulcan_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = vulcan_uart_data,
+ },
+ .resource = vulcan_uart_resources,
+ .num_resources = ARRAY_SIZE(vulcan_uart_resources),
+};
+
+static struct eth_plat_info vulcan_plat_eth[] = {
+ [0] = {
+ .phy = 0,
+ .rxq = 3,
+ .txreadyq = 20,
+ },
+ [1] = {
+ .phy = 1,
+ .rxq = 4,
+ .txreadyq = 21,
+ },
+};
+
+static struct platform_device vulcan_eth[] = {
+ [0] = {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEB,
+ .dev = {
+ .platform_data = &vulcan_plat_eth[0],
+ },
+ },
+ [1] = {
+ .name = "ixp4xx_eth",
+ .id = IXP4XX_ETH_NPEC,
+ .dev = {
+ .platform_data = &vulcan_plat_eth[1],
+ },
+ },
+};
+
+static struct resource vulcan_max6369_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device vulcan_max6369 = {
+ .name = "max6369_wdt",
+ .id = -1,
+ .resource = &vulcan_max6369_resource,
+ .num_resources = 1,
+};
+
+static struct w1_gpio_platform_data vulcan_w1_gpio_pdata = {
+ .pin = 14,
+};
+
+static struct platform_device vulcan_w1_gpio = {
+ .name = "w1-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &vulcan_w1_gpio_pdata,
+ },
+};
+
+static struct platform_device *vulcan_devices[] __initdata = {
+ &vulcan_uart,
+ &vulcan_flash,
+ &vulcan_sram,
+ &vulcan_max6369,
+ &vulcan_eth[0],
+ &vulcan_eth[1],
+ &vulcan_w1_gpio,
+};
+
+static void __init vulcan_init(void)
+{
+ ixp4xx_sys_init();
+
+ /* Flash is spread over both CS0 and CS1 */
+ vulcan_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ vulcan_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+ *IXP4XX_EXP_CS0 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_STROBE_T(3) |
+ IXP4XX_EXP_BUS_SIZE(0xF) |
+ IXP4XX_EXP_BUS_BYTE_RD16 |
+ IXP4XX_EXP_BUS_WR_EN;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ /* SRAM on CS2, (256kB, 8bit, writable) */
+ vulcan_sram_resource.start = IXP4XX_EXP_BUS_BASE(2);
+ vulcan_sram_resource.end = IXP4XX_EXP_BUS_BASE(2) + SZ_256K - 1;
+ *IXP4XX_EXP_CS2 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_STROBE_T(1) |
+ IXP4XX_EXP_BUS_HOLD_T(2) |
+ IXP4XX_EXP_BUS_SIZE(9) |
+ IXP4XX_EXP_BUS_SPLT_EN |
+ IXP4XX_EXP_BUS_WR_EN |
+ IXP4XX_EXP_BUS_BYTE_EN;
+
+ /* XR16L2551 on CS3 (Moto style, 512 bytes, 8bits, writable) */
+ vulcan_uart_resources[2].start = IXP4XX_EXP_BUS_BASE(3);
+ vulcan_uart_resources[2].end = IXP4XX_EXP_BUS_BASE(3) + 16 - 1;
+ vulcan_uart_data[2].mapbase = vulcan_uart_resources[2].start;
+ vulcan_uart_data[3].mapbase = vulcan_uart_data[2].mapbase + 8;
+ *IXP4XX_EXP_CS3 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_STROBE_T(3) |
+ IXP4XX_EXP_BUS_CYCLES(IXP4XX_EXP_BUS_CYCLES_MOTOROLA)|
+ IXP4XX_EXP_BUS_WR_EN |
+ IXP4XX_EXP_BUS_BYTE_EN;
+
+ /* GPIOS on CS4 (512 bytes, 8bits, writable) */
+ *IXP4XX_EXP_CS4 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_WR_EN |
+ IXP4XX_EXP_BUS_BYTE_EN;
+
+ /* max6369 on CS5 (512 bytes, 8bits, writable) */
+ vulcan_max6369_resource.start = IXP4XX_EXP_BUS_BASE(5);
+ vulcan_max6369_resource.end = IXP4XX_EXP_BUS_BASE(5);
+ *IXP4XX_EXP_CS5 = IXP4XX_EXP_BUS_CS_EN |
+ IXP4XX_EXP_BUS_WR_EN |
+ IXP4XX_EXP_BUS_BYTE_EN;
+
+ platform_add_devices(vulcan_devices, ARRAY_SIZE(vulcan_devices));
+}
+
+MACHINE_START(ARCOM_VULCAN, "Arcom/Eurotech Vulcan")
+ /* Maintainer: Marc Zyngier <maz@misterjones.org> */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = vulcan_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
new file mode 100644
index 00000000..17f3cf59
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -0,0 +1,63 @@
+/*
+ * arch/arch/mach-ixp4xx/wg302v2-pci.c
+ *
+ * PCI setup routines for the Netgear WG302 v2 and WAG302 v2
+ *
+ * Copyright (C) 2007 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * based on coyote-pci.c:
+ * Copyright (C) 2002 Jungo Software Technologies.
+ * Copyright (C) 2003 MontaVista Software, Inc.
+ *
+ * Maintainer: Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <asm/mach/pci.h>
+
+void __init wg302v2_pci_preinit(void)
+{
+ irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW);
+
+ ixp4xx_pci_preinit();
+}
+
+static int __init wg302v2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot == 1)
+ return IRQ_IXP4XX_GPIO8;
+ else if (slot == 2)
+ return IRQ_IXP4XX_GPIO9;
+ else return -1;
+}
+
+struct hw_pci wg302v2_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = wg302v2_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = ixp4xx_setup,
+ .scan = ixp4xx_scan_bus,
+ .map_irq = wg302v2_map_irq,
+};
+
+int __init wg302v2_pci_init(void)
+{
+ if (machine_is_wg302v2())
+ pci_common_init(&wg302v2_pci);
+ return 0;
+}
+
+subsys_initcall(wg302v2_pci_init);
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
new file mode 100644
index 00000000..5d148c7b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/mach-ixp4xx/wg302-setup.c
+ *
+ * Board setup for the Netgear WG302 v2 and WAG302 v2
+ *
+ * Copyright (C) 2007 Imre Kaloz <Kaloz@openwrt.org>
+ *
+ * based on coyote-setup.c:
+ * Copyright (C) 2003-2005 MontaVista Software, Inc.
+ *
+ * Author: Imre Kaloz <kaloz@openwrt.org>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data wg302v2_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+};
+
+static struct resource wg302v2_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device wg302v2_flash = {
+ .name = "IXP4XX-Flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &wg302v2_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &wg302v2_flash_resource,
+};
+
+static struct resource wg302v2_uart_resource = {
+ .start = IXP4XX_UART2_BASE_PHYS,
+ .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port wg302v2_uart_data[] = {
+ {
+ .mapbase = IXP4XX_UART2_BASE_PHYS,
+ .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+ .irq = IRQ_IXP4XX_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = IXP4XX_UART_XTAL,
+ },
+ { },
+};
+
+static struct platform_device wg302v2_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = wg302v2_uart_data,
+ },
+ .num_resources = 1,
+ .resource = &wg302v2_uart_resource,
+};
+
+static struct platform_device *wg302v2_devices[] __initdata = {
+ &wg302v2_flash,
+ &wg302v2_uart,
+};
+
+static void __init wg302v2_init(void)
+{
+ ixp4xx_sys_init();
+
+ wg302v2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+ wg302v2_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
+ *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
+ *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
+
+ platform_add_devices(wg302v2_devices, ARRAY_SIZE(wg302v2_devices));
+}
+
+#ifdef CONFIG_MACH_WG302V2
+MACHINE_START(WG302V2, "Netgear WG302 v2 / WAG302 v2")
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+ .map_io = ixp4xx_map_io,
+ .init_irq = ixp4xx_init_irq,
+ .timer = &ixp4xx_timer,
+ .boot_params = 0x0100,
+ .init_machine = wg302v2_init,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
new file mode 100644
index 00000000..7fc603b4
--- /dev/null
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -0,0 +1,135 @@
+if ARCH_KIRKWOOD
+
+menu "Marvell Kirkwood Implementations"
+
+config MACH_DB88F6281_BP
+ bool "Marvell DB-88F6281-BP Development Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell DB-88F6281-BP Development Board.
+
+config MACH_RD88F6192_NAS
+ bool "Marvell RD-88F6192-NAS Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell RD-88F6192-NAS Reference Board.
+
+config MACH_RD88F6281
+ bool "Marvell RD-88F6281 Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell RD-88F6281 Reference Board.
+
+config MACH_MV88F6281GTW_GE
+ bool "Marvell 88F6281 GTW GE Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell 88F6281 GTW GE Board.
+
+config MACH_SHEEVAPLUG
+ bool "Marvell SheevaPlug Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell SheevaPlug Reference Board.
+
+config MACH_ESATA_SHEEVAPLUG
+ bool "Marvell eSATA SheevaPlug Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell eSATA SheevaPlug Reference Board.
+
+config MACH_GURUPLUG
+ bool "Marvell GuruPlug Reference Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell GuruPlug Reference Board.
+
+config MACH_TS219
+ bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and
+ TS-219P+ Turbo NAS devices.
+
+config MACH_TS41X
+ bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo
+ NAS devices.
+
+config MACH_DOCKSTAR
+ bool "Seagate FreeAgent DockStar"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Seagate FreeAgent DockStar.
+
+config MACH_OPENRD
+ bool
+
+config MACH_OPENRD_BASE
+ bool "Marvell OpenRD Base Board"
+ select MACH_OPENRD
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell OpenRD Base Board.
+
+config MACH_OPENRD_CLIENT
+ bool "Marvell OpenRD Client Board"
+ select MACH_OPENRD
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell OpenRD Client Board.
+
+config MACH_OPENRD_ULTIMATE
+ bool "Marvell OpenRD Ultimate Board"
+ select MACH_OPENRD
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell OpenRD Ultimate Board.
+
+config MACH_NETSPACE_V2
+ bool "LaCie Network Space v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Network Space v2 NAS.
+
+config MACH_INETSPACE_V2
+ bool "LaCie Internet Space v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Internet Space v2 NAS.
+
+config MACH_NETSPACE_MAX_V2
+ bool "LaCie Network Space Max v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Network Space Max v2 NAS.
+
+config MACH_D2NET_V2
+ bool "LaCie d2 Network v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie d2 Network v2 NAS.
+
+config MACH_NET2BIG_V2
+ bool "LaCie 2Big Network v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie 2Big Network v2 NAS.
+
+config MACH_NET5BIG_V2
+ bool "LaCie 5Big Network v2 NAS Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie 5Big Network v2 NAS.
+
+config MACH_T5325
+ bool "HP t5325 Thin Client"
+ help
+ Say 'Y' here if you want your kernel to support the
+ HP t5325 Thin Client.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
new file mode 100644
index 00000000..5dcaa81a
--- /dev/null
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -0,0 +1,22 @@
+obj-y += common.o addr-map.o irq.o pcie.o mpp.o
+
+obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
+obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
+obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o
+obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o
+obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o
+obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o
+obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o
+obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o
+obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o
+obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o
+obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o
+obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o
+obj-$(CONFIG_MACH_T5325) += t5325-setup.o
+
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-kirkwood/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
new file mode 100644
index 00000000..8d03bcef
--- /dev/null
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -0,0 +1,153 @@
+/*
+ * arch/arm/mach-kirkwood/addr-map.c
+ *
+ * Address map functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR 0
+#define TARGET_DEV_BUS 1
+#define TARGET_SRAM 3
+#define TARGET_PCIE 4
+#define ATTR_DEV_SPI_ROM 0x1e
+#define ATTR_DEV_BOOT 0x1d
+#define ATTR_DEV_NAND 0x2f
+#define ATTR_DEV_CS3 0x37
+#define ATTR_DEV_CS2 0x3b
+#define ATTR_DEV_CS1 0x3d
+#define ATTR_DEV_CS0 0x3e
+#define ATTR_PCIE_IO 0xe0
+#define ATTR_PCIE_MEM 0xe8
+#define ATTR_PCIE1_IO 0xd0
+#define ATTR_PCIE1_MEM 0xd8
+#define ATTR_SRAM 0x01
+
+/*
+ * Helpers to get DDR bank info
+ */
+#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
+#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
+#define WIN_CTRL_OFF 0x0000
+#define WIN_BASE_OFF 0x0004
+#define WIN_REMAP_LO_OFF 0x0008
+#define WIN_REMAP_HI_OFF 0x000c
+
+
+struct mbus_dram_target_info kirkwood_mbus_dram_info;
+
+static int __init cpu_win_can_remap(int win)
+{
+ if (win < 4)
+ return 1;
+
+ return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+ u8 target, u8 attr, int remap)
+{
+ void __iomem *addr = (void __iomem *)WIN_OFF(win);
+ u32 ctrl;
+
+ base &= 0xffff0000;
+ ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+ writel(base, addr + WIN_BASE_OFF);
+ writel(ctrl, addr + WIN_CTRL_OFF);
+ if (cpu_win_can_remap(win)) {
+ if (remap < 0)
+ remap = base;
+
+ writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+}
+
+void __init kirkwood_setup_cpu_mbus(void)
+{
+ void __iomem *addr;
+ int i;
+ int cs;
+
+ /*
+ * First, disable and clear windows.
+ */
+ for (i = 0; i < 8; i++) {
+ addr = (void __iomem *)WIN_OFF(i);
+
+ writel(0, addr + WIN_BASE_OFF);
+ writel(0, addr + WIN_CTRL_OFF);
+ if (cpu_win_can_remap(i)) {
+ writel(0, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+ }
+
+ /*
+ * Setup windows for PCIe IO+MEM space.
+ */
+ setup_cpu_win(0, KIRKWOOD_PCIE_IO_PHYS_BASE, KIRKWOOD_PCIE_IO_SIZE,
+ TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
+ setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
+ TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
+ setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
+ TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
+ setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
+ TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
+
+ /*
+ * Setup window for NAND controller.
+ */
+ setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
+ TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
+
+ /*
+ * Setup window for SRAM.
+ */
+ setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
+ TARGET_SRAM, ATTR_SRAM, -1);
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ kirkwood_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ addr = (void __iomem *)DDR_WINDOW_CPU_BASE;
+
+ for (i = 0, cs = 0; i < 4; i++) {
+ u32 base = readl(addr + DDR_BASE_CS_OFF(i));
+ u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (size & 1) {
+ struct mbus_dram_window *w;
+
+ w = &kirkwood_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ w->base = base & 0xffff0000;
+ w->size = (size | 0x0000ffff) + 1;
+ }
+ }
+ kirkwood_mbus_dram_info.num_cs = cs;
+}
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
new file mode 100644
index 00000000..c5dbbb35
--- /dev/null
+++ b/arch/arm/mach-kirkwood/common.c
@@ -0,0 +1,537 @@
+/*
+ * arch/arm/mach-kirkwood/common.c
+ *
+ * Core functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/nand.h>
+#include <linux/dma-mapping.h>
+#include <net/dsa.h>
+#include <asm/page.h>
+#include <asm/timex.h>
+#include <asm/kexec.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <mach/bridge-regs.h>
+#include <plat/audio.h>
+#include <plat/cache-feroceon-l2.h>
+#include <plat/mvsdio.h>
+#include <plat/orion_nand.h>
+#include <plat/ehci-orion.h>
+#include <plat/common.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc kirkwood_io_desc[] __initdata = {
+ {
+ .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
+ .length = KIRKWOOD_PCIE_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
+ .length = KIRKWOOD_PCIE1_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = KIRKWOOD_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
+ .length = KIRKWOOD_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init kirkwood_map_io(void)
+{
+ iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
+}
+
+/*
+ * Default clock control bits. Any bit _not_ set in this variable
+ * will be cleared from the hardware after platform devices have been
+ * registered. Some reserved bits must be set to 1.
+ */
+unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
+
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+void __init kirkwood_ehci_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_USB0;
+ orion_ehci_init(&kirkwood_mbus_dram_info,
+ USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA);
+}
+
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ kirkwood_clk_ctrl |= CGC_GE0;
+
+ orion_ge00_init(eth_data, &kirkwood_mbus_dram_info,
+ GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
+ IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
+}
+
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
+{
+
+ kirkwood_clk_ctrl |= CGC_GE1;
+
+ orion_ge01_init(eth_data, &kirkwood_mbus_dram_info,
+ GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
+ IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
+}
+
+
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
+{
+ orion_ge00_switch_init(d, irq);
+}
+
+
+/*****************************************************************************
+ * NAND flash
+ ****************************************************************************/
+static struct resource kirkwood_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KIRKWOOD_NAND_MEM_PHYS_BASE,
+ .end = KIRKWOOD_NAND_MEM_PHYS_BASE +
+ KIRKWOOD_NAND_MEM_SIZE - 1,
+};
+
+static struct orion_nand_data kirkwood_nand_data = {
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+};
+
+static struct platform_device kirkwood_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &kirkwood_nand_data,
+ },
+ .resource = &kirkwood_nand_resource,
+ .num_resources = 1,
+};
+
+void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts,
+ int chip_delay)
+{
+ kirkwood_clk_ctrl |= CGC_RUNIT;
+ kirkwood_nand_data.parts = parts;
+ kirkwood_nand_data.nr_parts = nr_parts;
+ kirkwood_nand_data.chip_delay = chip_delay;
+ platform_device_register(&kirkwood_nand_flash);
+}
+
+void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts,
+ int (*dev_ready)(struct mtd_info *))
+{
+ kirkwood_clk_ctrl |= CGC_RUNIT;
+ kirkwood_nand_data.parts = parts;
+ kirkwood_nand_data.nr_parts = nr_parts;
+ kirkwood_nand_data.dev_ready = dev_ready;
+ platform_device_register(&kirkwood_nand_flash);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static void __init kirkwood_rtc_init(void)
+{
+ orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
+}
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
+{
+ kirkwood_clk_ctrl |= CGC_SATA0;
+ if (sata_data->n_ports > 1)
+ kirkwood_clk_ctrl |= CGC_SATA1;
+
+ orion_sata_init(sata_data, &kirkwood_mbus_dram_info,
+ SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
+}
+
+
+/*****************************************************************************
+ * SD/SDIO/MMC
+ ****************************************************************************/
+static struct resource mvsdio_resources[] = {
+ [0] = {
+ .start = SDIO_PHYS_BASE,
+ .end = SDIO_PHYS_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KIRKWOOD_SDIO,
+ .end = IRQ_KIRKWOOD_SDIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device kirkwood_sdio = {
+ .name = "mvsdio",
+ .id = -1,
+ .dev = {
+ .dma_mask = &mvsdio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mvsdio_resources),
+ .resource = mvsdio_resources,
+};
+
+void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
+ mvsdio_data->clock = 100000000;
+ else
+ mvsdio_data->clock = 200000000;
+ mvsdio_data->dram = &kirkwood_mbus_dram_info;
+ kirkwood_clk_ctrl |= CGC_SDIO;
+ kirkwood_sdio.dev.platform_data = mvsdio_data;
+ platform_device_register(&kirkwood_sdio);
+}
+
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+void __init kirkwood_spi_init()
+{
+ kirkwood_clk_ctrl |= CGC_RUNIT;
+ orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
+}
+
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+void __init kirkwood_i2c_init(void)
+{
+ orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+
+void __init kirkwood_uart0_init(void)
+{
+ orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+ IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
+}
+
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init kirkwood_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
+}
+
+/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+void __init kirkwood_crypto_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_CRYPTO;
+ orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
+ KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
+}
+
+
+/*****************************************************************************
+ * XOR0
+ ****************************************************************************/
+static void __init kirkwood_xor0_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_XOR0;
+
+ orion_xor0_init(&kirkwood_mbus_dram_info,
+ XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
+ IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
+}
+
+
+/*****************************************************************************
+ * XOR1
+ ****************************************************************************/
+static void __init kirkwood_xor1_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_XOR1;
+
+ orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
+ IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
+}
+
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static void __init kirkwood_wdt_init(void)
+{
+ orion_wdt_init(kirkwood_tclk);
+}
+
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init kirkwood_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+}
+
+int kirkwood_tclk;
+
+static int __init kirkwood_find_tclk(void)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+
+ if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID)
+ if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0)
+ return 200000000;
+
+ return 166666667;
+}
+
+static void __init kirkwood_timer_init(void)
+{
+ kirkwood_tclk = kirkwood_find_tclk();
+
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk);
+}
+
+struct sys_timer kirkwood_timer = {
+ .init = kirkwood_timer_init,
+};
+
+/*****************************************************************************
+ * Audio
+ ****************************************************************************/
+static struct resource kirkwood_i2s_resources[] = {
+ [0] = {
+ .start = AUDIO_PHYS_BASE,
+ .end = AUDIO_PHYS_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KIRKWOOD_I2S,
+ .end = IRQ_KIRKWOOD_I2S,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct kirkwood_asoc_platform_data kirkwood_i2s_data = {
+ .dram = &kirkwood_mbus_dram_info,
+ .burst = 128,
+};
+
+static struct platform_device kirkwood_i2s_device = {
+ .name = "kirkwood-i2s",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kirkwood_i2s_resources),
+ .resource = kirkwood_i2s_resources,
+ .dev = {
+ .platform_data = &kirkwood_i2s_data,
+ },
+};
+
+static struct platform_device kirkwood_pcm_device = {
+ .name = "kirkwood-pcm-audio",
+ .id = -1,
+};
+
+void __init kirkwood_audio_init(void)
+{
+ kirkwood_clk_ctrl |= CGC_AUDIO;
+ platform_device_register(&kirkwood_i2s_device);
+ platform_device_register(&kirkwood_pcm_device);
+}
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+/*
+ * Identify device ID and revision.
+ */
+static char * __init kirkwood_id(void)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+
+ if (dev == MV88F6281_DEV_ID) {
+ if (rev == MV88F6281_REV_Z0)
+ return "MV88F6281-Z0";
+ else if (rev == MV88F6281_REV_A0)
+ return "MV88F6281-A0";
+ else if (rev == MV88F6281_REV_A1)
+ return "MV88F6281-A1";
+ else
+ return "MV88F6281-Rev-Unsupported";
+ } else if (dev == MV88F6192_DEV_ID) {
+ if (rev == MV88F6192_REV_Z0)
+ return "MV88F6192-Z0";
+ else if (rev == MV88F6192_REV_A0)
+ return "MV88F6192-A0";
+ else if (rev == MV88F6192_REV_A1)
+ return "MV88F6192-A1";
+ else
+ return "MV88F6192-Rev-Unsupported";
+ } else if (dev == MV88F6180_DEV_ID) {
+ if (rev == MV88F6180_REV_A0)
+ return "MV88F6180-Rev-A0";
+ else if (rev == MV88F6180_REV_A1)
+ return "MV88F6180-Rev-A1";
+ else
+ return "MV88F6180-Rev-Unsupported";
+ } else if (dev == MV88F6282_DEV_ID) {
+ if (rev == MV88F6282_REV_A0)
+ return "MV88F6282-Rev-A0";
+ else
+ return "MV88F6282-Rev-Unsupported";
+ } else {
+ return "Device-Unknown";
+ }
+}
+
+static void __init kirkwood_l2_init(void)
+{
+#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
+ writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
+ feroceon_l2_init(1);
+#else
+ writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
+ feroceon_l2_init(0);
+#endif
+}
+
+void __init kirkwood_init(void)
+{
+ printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
+ kirkwood_id(), kirkwood_tclk);
+ kirkwood_i2s_data.tclk = kirkwood_tclk;
+
+ /*
+ * Disable propagation of mbus errors to the CPU local bus,
+ * as this causes mbus errors (which can occur for example
+ * for PCI aborts) to throw CPU aborts, which we're not set
+ * up to deal with.
+ */
+ writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+
+ kirkwood_setup_cpu_mbus();
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+ kirkwood_l2_init();
+#endif
+
+ /* internal devices that every board has */
+ kirkwood_rtc_init();
+ kirkwood_wdt_init();
+ kirkwood_xor0_init();
+ kirkwood_xor1_init();
+ kirkwood_crypto_init();
+
+#ifdef CONFIG_KEXEC
+ kexec_reinit = kirkwood_enable_pcie;
+#endif
+}
+
+static int __init kirkwood_clock_gate(void)
+{
+ unsigned int curr = readl(CLOCK_GATING_CTRL);
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+ printk(KERN_DEBUG "Gating clock of unused units\n");
+ printk(KERN_DEBUG "before: 0x%08x\n", curr);
+
+ /* Make sure those units are accessible */
+ writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
+
+ /* For SATA: first shutdown the phy */
+ if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
+ /* Disable PLL and IVREF */
+ writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
+ }
+ if (!(kirkwood_clk_ctrl & CGC_SATA1)) {
+ /* Disable PLL and IVREF */
+ writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2);
+ /* Disable PHY */
+ writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL);
+ }
+
+ /* For PCIe: first shutdown the phy */
+ if (!(kirkwood_clk_ctrl & CGC_PEX0)) {
+ writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL);
+ while (1)
+ if (readl(PCIE_STATUS) & 0x1)
+ break;
+ writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
+ }
+
+ /* For PCIe 1: first shutdown the phy */
+ if (dev == MV88F6282_DEV_ID) {
+ if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
+ writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
+ while (1)
+ if (readl(PCIE1_STATUS) & 0x1)
+ break;
+ writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
+ }
+ } else /* keep this bit set for devices that don't have PCIe1 */
+ kirkwood_clk_ctrl |= CGC_PEX1;
+
+ /* Now gate clock the required units */
+ writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
+ printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
+
+ return 0;
+}
+late_initcall(kirkwood_clock_gate);
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
new file mode 100644
index 00000000..b9b0f096
--- /dev/null
+++ b/arch/arm/mach-kirkwood/common.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-kirkwood/common.h
+ *
+ * Core functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_KIRKWOOD_COMMON_H
+#define __ARCH_KIRKWOOD_COMMON_H
+
+struct dsa_platform_data;
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+struct mvsdio_platform_data;
+struct mtd_partition;
+struct mtd_info;
+struct kirkwood_asoc_platform_data;
+
+#define KW_PCIE0 (1 << 0)
+#define KW_PCIE1 (1 << 1)
+
+/*
+ * Basic Kirkwood init functions used early by machine-setup.
+ */
+void kirkwood_map_io(void);
+void kirkwood_init(void);
+void kirkwood_init_early(void);
+void kirkwood_init_irq(void);
+
+extern struct mbus_dram_target_info kirkwood_mbus_dram_info;
+void kirkwood_setup_cpu_mbus(void);
+
+void kirkwood_enable_pcie(void);
+void kirkwood_pcie_id(u32 *dev, u32 *rev);
+
+void kirkwood_ehci_init(void);
+void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
+void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
+void kirkwood_pcie_init(unsigned int portmask);
+void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
+void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
+void kirkwood_spi_init(void);
+void kirkwood_i2c_init(void);
+void kirkwood_uart0_init(void);
+void kirkwood_uart1_init(void);
+void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay);
+void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *));
+void kirkwood_audio_init(void);
+
+extern int kirkwood_tclk;
+extern struct sys_timer kirkwood_timer;
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#endif
diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c
new file mode 100644
index 00000000..f68d33f1
--- /dev/null
+++ b/arch/arm/mach-kirkwood/cpuidle.c
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-kirkwood/cpuidle.c
+ *
+ * CPU idle Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The cpu idle uses wait-for-interrupt and DDR self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and DDR self refresh
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+#include <mach/kirkwood.h>
+
+#define KIRKWOOD_MAX_STATES 2
+
+static struct cpuidle_driver kirkwood_idle_driver = {
+ .name = "kirkwood_idle",
+ .owner = THIS_MODULE,
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
+
+/* Actual code that puts the SoC in different idle states */
+static int kirkwood_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+ if (state == &dev->states[0])
+ /* Wait for interrupt state */
+ cpu_do_idle();
+ else if (state == &dev->states[1]) {
+ /*
+ * Following write will put DDR in self refresh.
+ * Note that we have 256 cycles before DDR puts it
+ * self in self-refresh, so the wait-for-interrupt
+ * call afterwards won't get the DDR from self refresh
+ * mode.
+ */
+ writel(0x7, DDR_OPERATION_BASE);
+ 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;
+}
+
+/* Initialize CPU idle by registering the idle states */
+static int kirkwood_init_cpuidle(void)
+{
+ struct cpuidle_device *device;
+
+ cpuidle_register_driver(&kirkwood_idle_driver);
+
+ device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
+ device->state_count = KIRKWOOD_MAX_STATES;
+
+ /* Wait for interrupt state */
+ device->states[0].enter = kirkwood_enter_idle;
+ device->states[0].exit_latency = 1;
+ device->states[0].target_residency = 10000;
+ device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[0].name, "WFI");
+ strcpy(device->states[0].desc, "Wait for interrupt");
+
+ /* Wait for interrupt and DDR self refresh state */
+ device->states[1].enter = kirkwood_enter_idle;
+ device->states[1].exit_latency = 10;
+ device->states[1].target_residency = 10000;
+ device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+ strcpy(device->states[1].name, "DDR SR");
+ strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
+
+ if (cpuidle_register_device(device)) {
+ printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+device_initcall(kirkwood_init_cpuidle);
diff --git a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c
new file mode 100644
index 00000000..043cfd5e
--- /dev/null
+++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c
@@ -0,0 +1,230 @@
+/*
+ * arch/arm/mach-kirkwood/d2net_v2-setup.c
+ *
+ * LaCie d2 Network Space v2 Board Setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-ns2.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_v2_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_PUSH_BUTTON 34
+#define D2NET_V2_GPIO_POWER_SWITCH_ON 13
+#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15
+
+#define D2NET_V2_SWITCH_POWER_ON 0x1
+#define D2NET_V2_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button d2net_v2_buttons[] = {
+ [0] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_ON,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON,
+ .desc = "Back power switch (on|auto)",
+ .active_low = 0,
+ },
+ [1] = {
+ .type = EV_SW,
+ .code = D2NET_V2_SWITCH_POWER_OFF,
+ .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF,
+ .desc = "Back power switch (auto|off)",
+ .active_low = 0,
+ },
+ [2] = {
+ .code = KEY_POWER,
+ .gpio = D2NET_V2_GPIO_PUSH_BUTTON,
+ .desc = "Front Push Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data d2net_v2_button_data = {
+ .buttons = d2net_v2_buttons,
+ .nbuttons = ARRAY_SIZE(d2net_v2_buttons),
+};
+
+static struct platform_device d2net_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_RED_LED 12
+
+static struct gpio_led d2net_v2_gpio_led_pins[] = {
+ {
+ .name = "d2net_v2:red:fail",
+ .gpio = D2NET_V2_GPIO_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data d2net_v2_gpio_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins),
+ .leds = d2net_v2_gpio_led_pins,
+};
+
+static struct platform_device d2net_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_gpio_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * Dual-GPIO CPLD LEDs
+ ****************************************************************************/
+
+#define D2NET_V2_GPIO_BLUE_LED_SLOW 29
+#define D2NET_V2_GPIO_BLUE_LED_CMD 30
+
+static struct ns2_led d2net_v2_led_pins[] = {
+ {
+ .name = "d2net_v2:blue:sata",
+ .cmd = D2NET_V2_GPIO_BLUE_LED_CMD,
+ .slow = D2NET_V2_GPIO_BLUE_LED_SLOW,
+ },
+};
+
+static struct ns2_led_platform_data d2net_v2_leds_data = {
+ .num_leds = ARRAY_SIZE(d2net_v2_led_pins),
+ .leds = d2net_v2_led_pins,
+};
+
+static struct platform_device d2net_v2_leds = {
+ .name = "leds-ns2",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_v2_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int d2net_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Request power-off */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP13_GPIO, /* Rear power switch (on|auto) */
+ MPP14_GPIO, /* USB fuse */
+ MPP15_GPIO, /* Rear power switch (auto|off) */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP21_SATA0_ACTn,
+ MPP24_GPIO, /* USB mode select */
+ MPP26_GPIO, /* USB device vbus */
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */
+ MPP35_GPIO, /* Inhibit power-off */
+ 0
+};
+
+#define D2NET_V2_GPIO_POWER_OFF 7
+
+static void d2net_v2_power_off(void)
+{
+ gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init d2net_v2_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(d2net_v2_mpp_config);
+
+ lacie_v2_hdd_power_init(1);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&d2net_v2_ge00_data);
+ kirkwood_sata_init(&d2net_v2_sata_data);
+ kirkwood_uart0_init();
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+
+ platform_device_register(&d2net_v2_leds);
+ platform_device_register(&d2net_v2_gpio_leds);
+ platform_device_register(&d2net_v2_gpio_buttons);
+
+ if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = d2net_v2_power_off;
+ else
+ pr_err("d2net_v2: failed to configure power-off GPIO\n");
+}
+
+MACHINE_START(D2NET_V2, "LaCie d2 Network v2")
+ .boot_params = 0x00000100,
+ .init_machine = d2net_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
new file mode 100644
index 00000000..bff04e04
--- /dev/null
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+ *
+ * Marvell DB-88F6281-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition db88f6281_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data db88f6281_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mvsdio_platform_data db88f6281_mvsdio_data = {
+ .gpio_write_protect = 37,
+ .gpio_card_detect = 38,
+};
+
+static unsigned int db88f6281_mpp_config[] __initdata = {
+ MPP0_NF_IO2,
+ MPP1_NF_IO3,
+ MPP2_NF_IO4,
+ MPP3_NF_IO5,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP37_GPIO,
+ MPP38_GPIO,
+ 0
+};
+
+static void __init db88f6281_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(db88f6281_mpp_config);
+
+ kirkwood_nand_init(ARRAY_AND_SIZE(db88f6281_nand_parts), 25);
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&db88f6281_ge00_data);
+ kirkwood_sata_init(&db88f6281_sata_data);
+ kirkwood_uart0_init();
+ kirkwood_sdio_init(&db88f6281_mvsdio_data);
+}
+
+static int __init db88f6281_pci_init(void)
+{
+ if (machine_is_db88f6281_bp()) {
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID)
+ kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
+ else
+ kirkwood_pcie_init(KW_PCIE0);
+ }
+ return 0;
+}
+subsys_initcall(db88f6281_pci_init);
+
+MACHINE_START(DB88F6281_BP, "Marvell DB-88F6281-BP Development Board")
+ /* Maintainer: Saeed Bishara <saeed@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = db88f6281_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c
new file mode 100644
index 00000000..f14dfb85
--- /dev/null
+++ b/arch/arm/mach-kirkwood/dockstar-setup.c
@@ -0,0 +1,111 @@
+/*
+ * arch/arm/mach-kirkwood/dockstar-setup.c
+ *
+ * Seagate FreeAgent DockStar Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition dockstar_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data dockstar_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct gpio_led dockstar_led_pins[] = {
+ {
+ .name = "dockstar:green:health",
+ .default_trigger = "default-on",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
+ .name = "dockstar:orange:misc",
+ .default_trigger = "none",
+ .gpio = 47,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data dockstar_led_data = {
+ .leds = dockstar_led_pins,
+ .num_leds = ARRAY_SIZE(dockstar_led_pins),
+};
+
+static struct platform_device dockstar_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &dockstar_led_data,
+ }
+};
+
+static unsigned int dockstar_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED green */
+ MPP47_GPIO, /* LED orange */
+ 0
+};
+
+static void __init dockstar_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+
+ /* setup gpio pin select */
+ kirkwood_mpp_conf(dockstar_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25);
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&dockstar_ge00_data);
+
+ platform_device_register(&dockstar_leds);
+}
+
+MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar")
+ .boot_params = 0x00000100,
+ .init_machine = dockstar_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c
new file mode 100644
index 00000000..41d1b406
--- /dev/null
+++ b/arch/arm/mach-kirkwood/guruplug-setup.c
@@ -0,0 +1,130 @@
+/*
+ * arch/arm/mach-kirkwood/guruplug-setup.c
+ *
+ * Marvell GuruPlug Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition guruplug_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data guruplug_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data guruplug_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(1),
+};
+
+static struct mv_sata_platform_data guruplug_sata_data = {
+ .n_ports = 1,
+};
+
+static struct mvsdio_platform_data guruplug_mvsdio_data = {
+ /* unfortunately the CD signal has not been connected */
+};
+
+static struct gpio_led guruplug_led_pins[] = {
+ {
+ .name = "guruplug:red:health",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
+ .name = "guruplug:green:health",
+ .gpio = 47,
+ .active_low = 1,
+ },
+ {
+ .name = "guruplug:red:wmode",
+ .gpio = 48,
+ .active_low = 1,
+ },
+ {
+ .name = "guruplug:green:wmode",
+ .gpio = 49,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data guruplug_led_data = {
+ .leds = guruplug_led_pins,
+ .num_leds = ARRAY_SIZE(guruplug_led_pins),
+};
+
+static struct platform_device guruplug_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &guruplug_led_data,
+ }
+};
+
+static unsigned int guruplug_mpp_config[] __initdata = {
+ MPP46_GPIO, /* M_RLED */
+ MPP47_GPIO, /* M_GLED */
+ MPP48_GPIO, /* B_RLED */
+ MPP49_GPIO, /* B_GLED */
+ 0
+};
+
+static void __init guruplug_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(guruplug_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(guruplug_nand_parts), 25);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&guruplug_ge00_data);
+ kirkwood_ge01_init(&guruplug_ge01_data);
+ kirkwood_sata_init(&guruplug_sata_data);
+ kirkwood_sdio_init(&guruplug_mvsdio_data);
+
+ platform_device_register(&guruplug_leds);
+}
+
+MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board")
+ /* Maintainer: Siddarth Gore <gores@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = guruplug_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
new file mode 100644
index 00000000..957bd799
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+ *
+ * Mbus-L to Mbus Bridge Registers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/kirkwood.h>
+
+#define CPU_CONFIG (BRIDGE_VIRT_BASE | 0x0100)
+#define CPU_CONFIG_ERROR_PROP 0x00000004
+
+#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define CPU_RESET 0x00000002
+
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define WDT_RESET_OUT_EN 0x00000002
+#define SOFT_RESET_OUT_EN 0x00000004
+
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SOFT_RESET 0x00000001
+
+#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE | 0x0110)
+#define WDT_INT_REQ 0x0008
+
+#define BRIDGE_INT_TIMER1_CLR (~0x0004)
+
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_CAUSE_LOW_OFF 0x0000
+#define IRQ_MASK_LOW_OFF 0x0004
+#define IRQ_CAUSE_HIGH_OFF 0x0010
+#define IRQ_MASK_HIGH_OFF 0x0014
+
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
+
+#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
+#define L2_WRITETHROUGH 0x00000010
+
+#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c)
+#define CGC_GE0 (1 << 0)
+#define CGC_PEX0 (1 << 2)
+#define CGC_USB0 (1 << 3)
+#define CGC_SDIO (1 << 4)
+#define CGC_TSU (1 << 5)
+#define CGC_DUNIT (1 << 6)
+#define CGC_RUNIT (1 << 7)
+#define CGC_XOR0 (1 << 8)
+#define CGC_AUDIO (1 << 9)
+#define CGC_SATA0 (1 << 14)
+#define CGC_SATA1 (1 << 15)
+#define CGC_XOR1 (1 << 16)
+#define CGC_CRYPTO (1 << 17)
+#define CGC_PEX1 (1 << 18)
+#define CGC_GE1 (1 << 19)
+#define CGC_TDM (1 << 20)
+#define CGC_RESERVED (0x6 << 21)
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/debug-macro.S b/arch/arm/mach-kirkwood/include/mach/debug-macro.S
new file mode 100644
index 00000000..db06ae43
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/debug-macro.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 <mach/bridge-regs.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =KIRKWOOD_REGS_PHYS_BASE
+ ldr \rv, =KIRKWOOD_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-kirkwood/include/mach/entry-macro.S b/arch/arm/mach-kirkwood/include/mach/entry-macro.S
new file mode 100644
index 00000000..8939d36f
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/entry-macro.S
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell Kirkwood platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/bridge-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IRQ_VIRT_BASE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ @ check low interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
+ mov \irqnr, #31
+ ands \irqstat, \irqstat, \tmp
+ bne 1001f
+
+ @ if no low interrupts set, check high interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF]
+ mov \irqnr, #63
+ ands \irqstat, \irqstat, \tmp
+
+ @ find first active interrupt source
+1001: clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-kirkwood/include/mach/gpio.h b/arch/arm/mach-kirkwood/include/mach/gpio.h
new file mode 100644
index 00000000..84f340b5
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/gpio.h
@@ -0,0 +1,9 @@
+/*
+ * arch/asm-arm/mach-kirkwood/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-kirkwood/include/mach/hardware.h b/arch/arm/mach-kirkwood/include/mach/hardware.h
new file mode 100644
index 00000000..cde85283
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/hardware.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "kirkwood.h"
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE KIRKWOOD_PCIE_MEM_PHYS_BASE /* mem base for VGA */
+
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/io.h b/arch/arm/mach-kirkwood/include/mach/io.h
new file mode 100644
index 00000000..1aaddc36
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/io.h
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/io.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "kirkwood.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)((addr - KIRKWOOD_PCIE_IO_BUS_BASE)
+ + KIRKWOOD_PCIE_IO_VIRT_BASE);
+}
+
+static inline void __iomem *
+__arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype)
+{
+ void __iomem *retval;
+ unsigned long offs = paddr - KIRKWOOD_REGS_PHYS_BASE;
+ if (mtype == MT_DEVICE && size && offs < KIRKWOOD_REGS_SIZE &&
+ size <= KIRKWOOD_REGS_SIZE && offs + size <= KIRKWOOD_REGS_SIZE) {
+ retval = (void __iomem *)KIRKWOOD_REGS_VIRT_BASE + offs;
+ } else {
+ retval = __arm_ioremap(paddr, size, mtype);
+ }
+
+ return retval;
+}
+
+static inline void
+__arch_iounmap(void __iomem *addr)
+{
+ if (addr < (void __iomem *)KIRKWOOD_REGS_VIRT_BASE ||
+ addr >= (void __iomem *)(KIRKWOOD_REGS_VIRT_BASE + KIRKWOOD_REGS_SIZE))
+ __iounmap(addr);
+}
+
+#define __arch_ioremap __arch_ioremap
+#define __arch_iounmap __arch_iounmap
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
new file mode 100644
index 00000000..2bf8161e
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * Low Interrupt Controller
+ */
+#define IRQ_KIRKWOOD_HIGH_SUM 0
+#define IRQ_KIRKWOOD_BRIDGE 1
+#define IRQ_KIRKWOOD_HOST2CPU 2
+#define IRQ_KIRKWOOD_CPU2HOST 3
+#define IRQ_KIRKWOOD_XOR_00 5
+#define IRQ_KIRKWOOD_XOR_01 6
+#define IRQ_KIRKWOOD_XOR_10 7
+#define IRQ_KIRKWOOD_XOR_11 8
+#define IRQ_KIRKWOOD_PCIE 9
+#define IRQ_KIRKWOOD_PCIE1 10
+#define IRQ_KIRKWOOD_GE00_SUM 11
+#define IRQ_KIRKWOOD_GE01_SUM 15
+#define IRQ_KIRKWOOD_USB 19
+#define IRQ_KIRKWOOD_SATA 21
+#define IRQ_KIRKWOOD_CRYPTO 22
+#define IRQ_KIRKWOOD_SPI 23
+#define IRQ_KIRKWOOD_I2S 24
+#define IRQ_KIRKWOOD_TS_0 26
+#define IRQ_KIRKWOOD_SDIO 28
+#define IRQ_KIRKWOOD_TWSI 29
+#define IRQ_KIRKWOOD_AVB 30
+#define IRQ_KIRKWOOD_TDMI 31
+
+/*
+ * High Interrupt Controller
+ */
+#define IRQ_KIRKWOOD_UART_0 33
+#define IRQ_KIRKWOOD_UART_1 34
+#define IRQ_KIRKWOOD_GPIO_LOW_0_7 35
+#define IRQ_KIRKWOOD_GPIO_LOW_8_15 36
+#define IRQ_KIRKWOOD_GPIO_LOW_16_23 37
+#define IRQ_KIRKWOOD_GPIO_LOW_24_31 38
+#define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39
+#define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40
+#define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41
+#define IRQ_KIRKWOOD_GE00_ERR 46
+#define IRQ_KIRKWOOD_GE01_ERR 47
+#define IRQ_KIRKWOOD_RTC 53
+
+/*
+ * KIRKWOOD General Purpose Pins
+ */
+#define IRQ_KIRKWOOD_GPIO_START 64
+#define NR_GPIO_IRQS 50
+
+#define NR_IRQS (IRQ_KIRKWOOD_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
new file mode 100644
index 00000000..010bdeb4
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -0,0 +1,138 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/kirkwood.h
+ *
+ * Generic definitions for Marvell Kirkwood SoC flavors:
+ * 88F6180, 88F6192 and 88F6281.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_KIRKWOOD_H
+#define __ASM_ARCH_KIRKWOOD_H
+
+/*
+ * Marvell Kirkwood address maps.
+ *
+ * phys
+ * e0000000 PCIe #0 Memory space
+ * e8000000 PCIe #1 Memory space
+ * f1000000 on-chip peripheral registers
+ * f2000000 PCIe #0 I/O space
+ * f3000000 PCIe #1 I/O space
+ * f4000000 NAND controller address window
+ * f5000000 Security Accelerator SRAM
+ *
+ * virt phys size
+ * fed00000 f1000000 1M on-chip peripheral registers
+ * fee00000 f2000000 1M PCIe #0 I/O space
+ * fef00000 f3000000 1M PCIe #1 I/O space
+ */
+
+#define KIRKWOOD_SRAM_PHYS_BASE 0xf5000000
+#define KIRKWOOD_SRAM_SIZE SZ_2K
+
+#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000
+#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
+
+#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
+#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000
+#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
+
+#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
+#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
+#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
+#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
+
+#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
+#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000
+#define KIRKWOOD_REGS_SIZE SZ_1M
+
+#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
+#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
+#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
+
+#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xe8000000
+#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xe8000000
+#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M
+
+/*
+ * Register Map
+ */
+#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x00000)
+#define DDR_WINDOW_CPU_BASE (DDR_VIRT_BASE | 0x1500)
+#define DDR_OPERATION_BASE (DDR_VIRT_BASE | 0x1418)
+
+#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x10000)
+#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x10000)
+#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE | 0x0030)
+#define DEVICE_ID (DEV_BUS_VIRT_BASE | 0x0034)
+#define GPIO_LOW_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0100)
+#define GPIO_HIGH_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0140)
+#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0300)
+#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x0600)
+#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
+#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
+#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
+#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
+#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
+
+#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000)
+
+#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000)
+
+#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
+#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
+#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
+#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
+#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE | 0x70)
+#define PCIE1_STATUS (PCIE1_VIRT_BASE | 0x1a04)
+
+#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
+
+#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60800)
+#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60800)
+#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60900)
+#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60900)
+#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60A00)
+#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60A00)
+#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x60B00)
+#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x60B00)
+
+#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x70000)
+#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x74000)
+
+#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x80000)
+#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x80000)
+#define SATA0_IF_CTRL (SATA_VIRT_BASE | 0x2050)
+#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE | 0x2330)
+#define SATA1_IF_CTRL (SATA_VIRT_BASE | 0x4050)
+#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE | 0x4330)
+
+#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x90000)
+
+#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0xA0000)
+#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0xA0000)
+
+/*
+ * Supported devices and revisions.
+ */
+#define MV88F6281_DEV_ID 0x6281
+#define MV88F6281_REV_Z0 0
+#define MV88F6281_REV_A0 2
+#define MV88F6281_REV_A1 3
+
+#define MV88F6192_DEV_ID 0x6192
+#define MV88F6192_REV_Z0 0
+#define MV88F6192_REV_A0 2
+#define MV88F6192_REV_A1 3
+
+#define MV88F6180_DEV_ID 0x6180
+#define MV88F6180_REV_A0 2
+#define MV88F6180_REV_A1 3
+
+#define MV88F6282_DEV_ID 0x6282
+#define MV88F6282_REV_A0 0
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
new file mode 100644
index 00000000..24b536eb
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/leds-netxbig.h
+ *
+ * Platform data structure for netxbig LED driver
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_LEDS_NETXBIG_H
+#define __MACH_LEDS_NETXBIG_H
+
+struct netxbig_gpio_ext {
+ unsigned *addr;
+ int num_addr;
+ unsigned *data;
+ int num_data;
+ unsigned enable;
+};
+
+enum netxbig_led_mode {
+ NETXBIG_LED_OFF,
+ NETXBIG_LED_ON,
+ NETXBIG_LED_SATA,
+ NETXBIG_LED_TIMER1,
+ NETXBIG_LED_TIMER2,
+ NETXBIG_LED_MODE_NUM,
+};
+
+#define NETXBIG_LED_INVALID_MODE NETXBIG_LED_MODE_NUM
+
+struct netxbig_led_timer {
+ unsigned long delay_on;
+ unsigned long delay_off;
+ enum netxbig_led_mode mode;
+};
+
+struct netxbig_led {
+ const char *name;
+ const char *default_trigger;
+ int mode_addr;
+ int *mode_val;
+ int bright_addr;
+};
+
+struct netxbig_led_platform_data {
+ struct netxbig_gpio_ext *gpio_ext;
+ struct netxbig_led_timer *timer;
+ int num_timer;
+ struct netxbig_led *leds;
+ int num_leds;
+};
+
+#endif /* __MACH_LEDS_NETXBIG_H */
diff --git a/arch/arm/mach-kirkwood/include/mach/leds-ns2.h b/arch/arm/mach-kirkwood/include/mach/leds-ns2.h
new file mode 100644
index 00000000..e21272e5
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/leds-ns2.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/leds-ns2.h
+ *
+ * Platform data structure for Network Space v2 LED driver
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_LEDS_NS2_H
+#define __MACH_LEDS_NS2_H
+
+struct ns2_led {
+ const char *name;
+ const char *default_trigger;
+ unsigned cmd;
+ unsigned slow;
+};
+
+struct ns2_led_platform_data {
+ int num_leds;
+ struct ns2_led *leds;
+};
+
+#endif /* __MACH_LEDS_NS2_H */
diff --git a/arch/arm/mach-kirkwood/include/mach/memory.h b/arch/arm/mach-kirkwood/include/mach/memory.h
new file mode 100644
index 00000000..4600b44e
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/memory.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h
new file mode 100644
index 00000000..7568e95d
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/system.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/system.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+ /*
+ * Assert soft reset.
+ */
+ writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+ while (1)
+ ;
+}
+
+
+#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/timex.h b/arch/arm/mach-kirkwood/include/mach/timex.h
new file mode 100644
index 00000000..c923cd16
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/timex.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/timex.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
+
diff --git a/arch/arm/mach-kirkwood/include/mach/uncompress.h b/arch/arm/mach-kirkwood/include/mach/uncompress.h
new file mode 100644
index 00000000..75d5497d
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/uncompress.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/kirkwood.h>
+
+#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-kirkwood/include/mach/vmalloc.h b/arch/arm/mach-kirkwood/include/mach/vmalloc.h
new file mode 100644
index 00000000..bf162ca3
--- /dev/null
+++ b/arch/arm/mach-kirkwood/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-kirkwood/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe800000UL
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c
new file mode 100644
index 00000000..05d193a2
--- /dev/null
+++ b/arch/arm/mach-kirkwood/irq.c
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-kirkwood/irq.c
+ *
+ * Kirkwood IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/bridge-regs.h>
+#include <plat/irq.h>
+#include <asm/gpio.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7);
+ BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23);
+
+ orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3);
+}
+
+void __init kirkwood_init_irq(void)
+{
+ orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
+ orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+
+ /*
+ * Initialize gpiolib for GPIOs 0-49.
+ */
+ orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0,
+ IRQ_KIRKWOOD_GPIO_START);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler);
+
+ orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0,
+ IRQ_KIRKWOOD_GPIO_START + 32);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23,
+ gpio_irq_handler);
+}
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c
new file mode 100644
index 00000000..285edab7
--- /dev/null
+++ b/arch/arm/mach-kirkwood/lacie_v2-common.c
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/gpio.h>
+#include <asm/mach/time.h>
+#include <mach/kirkwood.h>
+#include <mach/irqs.h>
+#include <plat/time.h>
+#include "common.h"
+
+/*****************************************************************************
+ * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005)
+ ****************************************************************************/
+
+static struct mtd_partition lacie_v2_flash_parts[] = {
+ {
+ .name = "u-boot",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+};
+
+static const struct flash_platform_data lacie_v2_flash = {
+ .type = "mx25l4005a",
+ .name = "spi_flash",
+ .parts = lacie_v2_flash_parts,
+ .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts),
+};
+
+static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &lacie_v2_flash,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+void __init lacie_v2_register_flash(void)
+{
+ spi_register_board_info(lacie_v2_spi_slave_info,
+ ARRAY_SIZE(lacie_v2_spi_slave_info));
+ kirkwood_spi_init();
+}
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+static struct at24_platform_data at24c04 = {
+ .byte_len = SZ_4K / 8,
+ .page_size = 16,
+};
+
+/*
+ * i2c addr | chip | description
+ * 0x50 | HT24LC04 | eeprom (512B)
+ */
+
+static struct i2c_board_info __initdata lacie_v2_i2c_info[] = {
+ {
+ I2C_BOARD_INFO("24c04", 0x50),
+ .platform_data = &at24c04,
+ }
+};
+
+void __init lacie_v2_register_i2c_devices(void)
+{
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, lacie_v2_i2c_info,
+ ARRAY_SIZE(lacie_v2_i2c_info));
+}
+
+/*****************************************************************************
+ * Hard Disk power
+ ****************************************************************************/
+
+static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 };
+
+void __init lacie_v2_hdd_power_init(int hdd_num)
+{
+ int i;
+ int err;
+
+ /* Power up all hard disks. */
+ for (i = 0; i < hdd_num; i++) {
+ err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL);
+ if (err == 0) {
+ err = gpio_direction_output(
+ lacie_v2_gpio_hdd_power[i], 1);
+ /* Free the HDD power GPIOs. This allow user-space to
+ * configure them via the gpiolib sysfs interface. */
+ gpio_free(lacie_v2_gpio_hdd_power[i]);
+ }
+ if (err)
+ pr_err("Failed to power up HDD%d\n", i + 1);
+ }
+}
diff --git a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h
new file mode 100644
index 00000000..fc64f578
--- /dev/null
+++ b/arch/arm/mach-kirkwood/lacie_v2-common.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-kirkwood/lacie_v2-common.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H
+
+void lacie_v2_register_flash(void);
+void lacie_v2_register_i2c_devices(void);
+void lacie_v2_hdd_power_init(int hdd_num);
+
+#endif
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
new file mode 100644
index 00000000..b0a7d979
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-kirkwood/mpp.c
+ *
+ * MPP functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include <plat/mpp.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init kirkwood_variant(void)
+{
+ u32 dev, rev;
+
+ kirkwood_pcie_id(&dev, &rev);
+
+ if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) ||
+ (dev == MV88F6282_DEV_ID))
+ return MPP_F6281_MASK;
+ if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
+ return MPP_F6192_MASK;
+ if (dev == MV88F6180_DEV_ID)
+ return MPP_F6180_MASK;
+
+ printk(KERN_ERR "MPP setup: unknown kirkwood variant "
+ "(dev %#x rev %#x)\n", dev, rev);
+ return 0;
+}
+
+void __init kirkwood_mpp_conf(unsigned int *mpp_list)
+{
+ orion_mpp_conf(mpp_list, kirkwood_variant(),
+ MPP_MAX, DEV_BUS_VIRT_BASE);
+}
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h
new file mode 100644
index 00000000..7afccf47
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mpp.h
@@ -0,0 +1,347 @@
+/*
+ * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins
+ *
+ * Copyright 2009: Marvell Technology Group Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __KIRKWOOD_MPP_H
+#define __KIRKWOOD_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281, _F6282) ( \
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13) | \
+ /* available on F6180 */ ((!!(_F6180)) << 14) | \
+ /* available on F6190 */ ((!!(_F6190)) << 15) | \
+ /* available on F6192 */ ((!!(_F6192)) << 16) | \
+ /* available on F6281 */ ((!!(_F6281)) << 17) | \
+ /* available on F6282 */ ((!!(_F6282)) << 18))
+
+ /* num sel i o 6180 6190 6192 6281 6282 */
+
+#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0, 0 )
+#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0, 0 )
+#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0, 0 )
+#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1, 0 )
+#define MPP_F6282_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP0_NF_IO2 MPP( 0, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP1_NF_IO3 MPP( 1, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP2_NF_IO4 MPP( 2, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP3_NF_IO5 MPP( 3, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP3_SPI_MISO MPP( 3, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP4_NF_IO6 MPP( 4, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP4_UART0_RXD MPP( 4, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP4_LCD_VGA_HSYNC MPP( 4, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP4_PTP_CLK MPP( 4, 0xd, 0, 0, 1, 1, 1, 1, 0 )
+
+#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP5_NF_IO7 MPP( 5, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP5_LCD_VGA_VSYNC MPP( 5, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 0, 1, 1, 1, 1, 0 )
+
+#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP7_LCD_PWM MPP( 7, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP8_TW0_SDA MPP( 8, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP8_MII0_RXERR MPP( 8, 0x4, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP8_PTP_CLK MPP( 8, 0xc, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP8_MII0_COL MPP( 8, 0xd, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP9_TW0_SCK MPP( 9, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP9_UART0_CTS MPP( 9, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP9_UART1_CTS MPP( 9, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP9_MII0_CRS MPP( 9, 0xd, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 0, 1, 1, 1, 1, 0 )
+
+#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP11_SPI_MISO MPP( 11, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP11_UART0_RXD MPP( 11, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP11_PTP_CLK MPP( 11, 0xd, 0, 0, 1, 1, 1, 1, 0 )
+#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+
+#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP12_SD_CLK MPP( 12, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP12_TW1_SDA MPP( 12, 0xd, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP13_SD_CMD MPP( 13, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP13_AU_SPDIFRMCLK MPP( 13, 0xa, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP13_LCDPWM MPP( 13, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP14_SD_D0 MPP( 14, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP14_UART1_RXD MPP( 14, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP14_AU_SPDIFI MPP( 14, 0xa, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP14_AU_I2SDI MPP( 14, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP14_MII0_COL MPP( 14, 0xd, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP15_SD_D1 MPP( 15, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP15_SPI_CSn MPP( 15, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP16_SD_D2 MPP( 16, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP16_UART0_CTS MPP( 16, 0x2, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP16_UART1_RXD MPP( 16, 0x3, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP16_LCD_EXT_REF_CLK MPP( 16, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP16_MII0_CRS MPP( 16, 0xd, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP17_SD_D3 MPP( 17, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP17_SATA1_ACTn MPP( 17, 0xa, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP17_TW1_SCK MPP( 17, 0xd, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP18_NF_IO0 MPP( 18, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+#define MPP18_PEX0_CLKREQ MPP( 18, 0x2, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1, 1 )
+#define MPP19_NF_IO1 MPP( 19, 0x1, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP20_TSMP0 MPP( 20, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP20_GE1_TXD0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP20_AU_SPDIFI MPP( 20, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP20_LCD_D0 MPP( 20, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP21_TSMP1 MPP( 21, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP21_GE1_TXD1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP21_AU_SPDIFO MPP( 21, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP21_LCD_D1 MPP( 21, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP22_TSMP2 MPP( 22, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP22_GE1_TXD2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP22_AU_SPDIFRMKCLK MPP( 22, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP22_LCD_D2 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP23_TSMP3 MPP( 23, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP23_GE1_TXD3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP23_AU_I2SBCLK MPP( 23, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP23_LCD_D3 MPP( 23, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP24_TSMP4 MPP( 24, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP24_TDM_SPI_CS0 MPP( 24, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP24_GE1_RXD0 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP24_AU_I2SDO MPP( 24, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP24_LCD_D4 MPP( 24, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP25_TSMP5 MPP( 25, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP25_GE1_RXD1 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP25_AU_I2SLRCLK MPP( 25, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP25_LCD_D5 MPP( 25, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP26_TSMP6 MPP( 26, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP26_GE1_RXD2 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP26_AU_I2SMCLK MPP( 26, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP26_LCD_D6 MPP( 26, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP27_TSMP7 MPP( 27, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP27_GE1_RXD3 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP27_AU_I2SDI MPP( 27, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP27_LCD_D7 MPP( 27, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP28_TSMP8 MPP( 28, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP28_GE1_COL MPP( 28, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP28_AU_EXTCLK MPP( 28, 0x4, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP28_LCD_D8 MPP( 28, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP29_TSMP9 MPP( 29, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP29_GE1_TCLK MPP( 29, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP29_LCD_D9 MPP( 29, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP30_TSMP10 MPP( 30, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP30_TDM_PCLK MPP( 30, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP30_GE1_RXCTL MPP( 30, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP30_LCD_D10 MPP( 30, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP31_TSMP11 MPP( 31, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP31_TDM_FS MPP( 31, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP31_GE1_RXCLK MPP( 31, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP31_LCD_D11 MPP( 31, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP32_TSMP12 MPP( 32, 0x1, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP32_TDM_DRX MPP( 32, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP32_GE1_TCLKOUT MPP( 32, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP32_LCD_D12 MPP( 32, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP33_GPO MPP( 33, 0x0, 0, 1, 0, 1, 1, 1, 1 )
+#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP33_GE1_TXCTL MPP( 33, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP33_LCD_D13 MPP( 33, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1, 1 )
+#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP34_GE1_TXEN MPP( 34, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP34_SATA1_ACTn MPP( 34, 0x5, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP34_LCD_D14 MPP( 34, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1, 1 )
+#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 0, 0, 0, 1, 1, 1 )
+#define MPP35_GE1_RXERR MPP( 35, 0x3, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 0, 0, 1, 1, 1, 1 )
+#define MPP35_LCD_D15 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP35_MII0_RXERR MPP( 35, 0xc, 0, 0, 1, 1, 1, 1, 1 )
+
+#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP36_TSMP0 MPP( 36, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP36_AU_SPDIFI MPP( 36, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP36_TW1_SDA MPP( 36, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP37_TSMP1 MPP( 37, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP37_AU_SPDIFO MPP( 37, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP37_TW1_SCK MPP( 37, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP38_TSMP2 MPP( 38, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP38_AU_SPDIFRMLCLK MPP( 38, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP38_LCD_D18 MPP( 38, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP39_TSMP3 MPP( 39, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP39_AU_I2SBCLK MPP( 39, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP39_LCD_D19 MPP( 39, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP40_TSMP4 MPP( 40, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP40_AU_I2SDO MPP( 40, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP40_LCD_D20 MPP( 40, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP41_TSMP5 MPP( 41, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP41_AU_I2SLRCLK MPP( 41, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP41_LCD_D21 MPP( 41, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP42_TSMP6 MPP( 42, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP42_AU_I2SMCLK MPP( 42, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP42_LCD_D22 MPP( 42, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP43_TSMP7 MPP( 43, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP43_AU_I2SDI MPP( 43, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP43_LCD_D23 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1, 1 )
+#define MPP44_TSMP8 MPP( 44, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP44_AU_EXTCLK MPP( 44, 0x4, 0, 0, 1, 0, 0, 1, 1 )
+#define MPP44_LCD_CLK MPP( 44, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1, 1 )
+#define MPP45_TSMP9 MPP( 45, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP45_TDM_PCLK MPP( 45, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP245_LCD_E MPP( 45, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1, 1 )
+#define MPP46_TSMP10 MPP( 46, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP46_TDM_FS MPP( 46, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP46_LCD_HSYNC MPP( 46, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1, 1 )
+#define MPP47_TSMP11 MPP( 47, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP47_TDM_DRX MPP( 47, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP47_LCD_VSYNC MPP( 47, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1, 1 )
+#define MPP48_TSMP12 MPP( 48, 0x1, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP48_LCD_D16 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1, 0 )
+#define MPP49_GPO MPP( 49, 0x0, 0, 1, 0, 0, 0, 0, 1 )
+#define MPP49_TSMP9 MPP( 49, 0x1, 0, 0, 0, 0, 0, 1, 0 )
+#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 0, 0, 0, 0, 1, 1 )
+#define MPP49_PTP_CLK MPP( 49, 0x5, 0, 0, 0, 0, 0, 1, 0 )
+#define MPP49_PEX0_CLKREQ MPP( 49, 0xa, 0, 0, 0, 0, 0, 0, 1 )
+#define MPP49_LCD_D17 MPP( 49, 0xb, 0, 0, 0, 0, 0, 0, 1 )
+
+#define MPP_MAX 49
+
+void kirkwood_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
new file mode 100644
index 00000000..00cca22e
--- /dev/null
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -0,0 +1,172 @@
+/*
+ * arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+ *
+ * Marvell 88F6281 GTW GE Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/timer.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data mv88f6281gtw_ge_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data mv88f6281gtw_ge_switch_chip_data = {
+ .port_names[0] = "lan1",
+ .port_names[1] = "lan2",
+ .port_names[2] = "lan3",
+ .port_names[3] = "lan4",
+ .port_names[4] = "wan",
+ .port_names[5] = "cpu",
+};
+
+static struct dsa_platform_data mv88f6281gtw_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &mv88f6281gtw_ge_switch_chip_data,
+};
+
+static const struct flash_platform_data mv88f6281gtw_ge_spi_slave_data = {
+ .type = "mx25l12805d",
+};
+
+static struct spi_board_info __initdata mv88f6281gtw_ge_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &mv88f6281gtw_ge_spi_slave_data,
+ .irq = -1,
+ .max_speed_hz = 50000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = 47,
+ .desc = "SWR Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_WPS_BUTTON,
+ .gpio = 46,
+ .desc = "WPS Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mv88f6281gtw_ge_button_data = {
+ .buttons = mv88f6281gtw_ge_button_pins,
+ .nbuttons = ARRAY_SIZE(mv88f6281gtw_ge_button_pins),
+};
+
+static struct platform_device mv88f6281gtw_ge_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &mv88f6281gtw_ge_button_data,
+ },
+};
+
+static struct gpio_led mv88f6281gtw_ge_led_pins[] = {
+ {
+ .name = "gtw:green:Status",
+ .gpio = 20,
+ .active_low = 0,
+ }, {
+ .name = "gtw:red:Status",
+ .gpio = 21,
+ .active_low = 0,
+ }, {
+ .name = "gtw:green:USB",
+ .gpio = 12,
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data mv88f6281gtw_ge_led_data = {
+ .leds = mv88f6281gtw_ge_led_pins,
+ .num_leds = ARRAY_SIZE(mv88f6281gtw_ge_led_pins),
+};
+
+static struct platform_device mv88f6281gtw_ge_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mv88f6281gtw_ge_led_data,
+ },
+};
+
+static unsigned int mv88f6281gtw_ge_mpp_config[] __initdata = {
+ MPP12_GPO, /* Status#_USB pin */
+ MPP20_GPIO, /* Status#_GLED pin */
+ MPP21_GPIO, /* Status#_RLED pin */
+ MPP46_GPIO, /* WPS_Switch pin */
+ MPP47_GPIO, /* SW_Init pin */
+ 0
+};
+
+static void __init mv88f6281gtw_ge_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(mv88f6281gtw_ge_mpp_config);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&mv88f6281gtw_ge_ge00_data);
+ kirkwood_ge00_switch_init(&mv88f6281gtw_ge_switch_plat_data, NO_IRQ);
+ spi_register_board_info(mv88f6281gtw_ge_spi_slave_info,
+ ARRAY_SIZE(mv88f6281gtw_ge_spi_slave_info));
+ kirkwood_spi_init();
+ kirkwood_uart0_init();
+ platform_device_register(&mv88f6281gtw_ge_leds);
+ platform_device_register(&mv88f6281gtw_ge_buttons);
+}
+
+static int __init mv88f6281gtw_ge_pci_init(void)
+{
+ if (machine_is_mv88f6281gtw_ge())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(mv88f6281gtw_ge_pci_init);
+
+MACHINE_START(MV88F6281GTW_GE, "Marvell 88F6281 GTW GE Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = mv88f6281gtw_ge_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c
new file mode 100644
index 00000000..7cdab577
--- /dev/null
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -0,0 +1,290 @@
+/*
+ * arch/arm/mach-kirkwood/netspace_v2-setup.c
+ *
+ * LaCie Network Space v2 board setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ * Copyright (C) 2009 Benoît Canet <benoit.canet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <linux/gpio-fan.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-ns2.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data netspace_v2_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data netspace_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NETSPACE_V2_PUSH_BUTTON 32
+
+static struct gpio_keys_button netspace_v2_buttons[] = {
+ [0] = {
+ .code = KEY_POWER,
+ .gpio = NETSPACE_V2_PUSH_BUTTON,
+ .desc = "Power push button",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data netspace_v2_button_data = {
+ .buttons = netspace_v2_buttons,
+ .nbuttons = ARRAY_SIZE(netspace_v2_buttons),
+};
+
+static struct platform_device netspace_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &netspace_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+#define NETSPACE_V2_GPIO_RED_LED 12
+
+static struct gpio_led netspace_v2_gpio_led_pins[] = {
+ {
+ .name = "ns_v2:red:fail",
+ .gpio = NETSPACE_V2_GPIO_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data netspace_v2_gpio_leds_data = {
+ .num_leds = ARRAY_SIZE(netspace_v2_gpio_led_pins),
+ .leds = netspace_v2_gpio_led_pins,
+};
+
+static struct platform_device netspace_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &netspace_v2_gpio_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * Dual-GPIO CPLD LEDs
+ ****************************************************************************/
+
+#define NETSPACE_V2_GPIO_BLUE_LED_SLOW 29
+#define NETSPACE_V2_GPIO_BLUE_LED_CMD 30
+
+static struct ns2_led netspace_v2_led_pins[] = {
+ {
+ .name = "ns_v2:blue:sata",
+ .cmd = NETSPACE_V2_GPIO_BLUE_LED_CMD,
+ .slow = NETSPACE_V2_GPIO_BLUE_LED_SLOW,
+ },
+};
+
+static struct ns2_led_platform_data netspace_v2_leds_data = {
+ .num_leds = ARRAY_SIZE(netspace_v2_led_pins),
+ .leds = netspace_v2_led_pins,
+};
+
+static struct platform_device netspace_v2_leds = {
+ .name = "leds-ns2",
+ .id = -1,
+ .dev = {
+ .platform_data = &netspace_v2_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO fan
+ ****************************************************************************/
+
+/* Designed for fan 40x40x16: ADDA AD0412LB-D50 6000rpm@12v */
+static struct gpio_fan_speed netspace_max_v2_fan_speed[] = {
+ { 0, 0 },
+ { 1500, 15 },
+ { 1700, 14 },
+ { 1800, 13 },
+ { 2100, 12 },
+ { 3100, 11 },
+ { 3300, 10 },
+ { 4300, 9 },
+ { 5500, 8 },
+};
+
+static unsigned netspace_max_v2_fan_ctrl[] = { 22, 7, 33, 23 };
+
+static struct gpio_fan_alarm netspace_max_v2_fan_alarm = {
+ .gpio = 25,
+ .active_low = 1,
+};
+
+static struct gpio_fan_platform_data netspace_max_v2_fan_data = {
+ .num_ctrl = ARRAY_SIZE(netspace_max_v2_fan_ctrl),
+ .ctrl = netspace_max_v2_fan_ctrl,
+ .alarm = &netspace_max_v2_fan_alarm,
+ .num_speed = ARRAY_SIZE(netspace_max_v2_fan_speed),
+ .speed = netspace_max_v2_fan_speed,
+};
+
+static struct platform_device netspace_max_v2_gpio_fan = {
+ .name = "gpio-fan",
+ .id = -1,
+ .dev = {
+ .platform_data = &netspace_max_v2_fan_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int netspace_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Fan speed (bit 1) */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_GPO, /* Red led */
+ MPP14_GPIO, /* USB fuse */
+ MPP16_GPIO, /* SATA 0 power */
+ MPP17_GPIO, /* SATA 1 power */
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP22_GPIO, /* Fan speed (bit 0) */
+ MPP23_GPIO, /* Fan power */
+ MPP24_GPIO, /* USB mode select */
+ MPP25_GPIO, /* Fan rotation fail */
+ MPP26_GPIO, /* USB device vbus */
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* Blue led (slow register) */
+ MPP30_GPIO, /* Blue led (command register) */
+ MPP31_GPIO, /* Board power off */
+ MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */
+ MPP33_GPO, /* Fan speed (bit 2) */
+ 0
+};
+
+#define NETSPACE_V2_GPIO_POWER_OFF 31
+
+static void netspace_v2_power_off(void)
+{
+ gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init netspace_v2_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(netspace_v2_mpp_config);
+
+ if (machine_is_netspace_max_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(1);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&netspace_v2_ge00_data);
+ kirkwood_sata_init(&netspace_v2_sata_data);
+ kirkwood_uart0_init();
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+
+ platform_device_register(&netspace_v2_leds);
+ platform_device_register(&netspace_v2_gpio_leds);
+ platform_device_register(&netspace_v2_gpio_buttons);
+ if (machine_is_netspace_max_v2())
+ platform_device_register(&netspace_max_v2_gpio_fan);
+
+ if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = netspace_v2_power_off;
+ else
+ pr_err("netspace_v2: failed to configure power-off GPIO\n");
+}
+
+#ifdef CONFIG_MACH_NETSPACE_V2
+MACHINE_START(NETSPACE_V2, "LaCie Network Space v2")
+ .boot_params = 0x00000100,
+ .init_machine = netspace_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_INETSPACE_V2
+MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2")
+ .boot_params = 0x00000100,
+ .init_machine = netspace_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_NETSPACE_MAX_V2
+MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2")
+ .boot_params = 0x00000100,
+ .init_machine = netspace_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
new file mode 100644
index 00000000..6be627de
--- /dev/null
+++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c
@@ -0,0 +1,420 @@
+/*
+ * arch/arm/mach-kirkwood/netxbig_v2-setup.c
+ *
+ * LaCie 2Big and 5Big Network v2 board setup
+ *
+ * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <mach/leds-netxbig.h>
+#include "common.h"
+#include "mpp.h"
+#include "lacie_v2-common.h"
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data netxbig_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NETXBIG_V2_GPIO_SWITCH_POWER_ON 13
+#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF 15
+#define NETXBIG_V2_GPIO_FUNC_BUTTON 34
+
+#define NETXBIG_V2_SWITCH_POWER_ON 0x1
+#define NETXBIG_V2_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button netxbig_v2_buttons[] = {
+ [0] = {
+ .type = EV_SW,
+ .code = NETXBIG_V2_SWITCH_POWER_ON,
+ .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_ON,
+ .desc = "Back power switch (on|auto)",
+ .active_low = 1,
+ },
+ [1] = {
+ .type = EV_SW,
+ .code = NETXBIG_V2_SWITCH_POWER_OFF,
+ .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_OFF,
+ .desc = "Back power switch (auto|off)",
+ .active_low = 1,
+ },
+ [2] = {
+ .code = KEY_OPTION,
+ .gpio = NETXBIG_V2_GPIO_FUNC_BUTTON,
+ .desc = "Function button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data netxbig_v2_button_data = {
+ .buttons = netxbig_v2_buttons,
+ .nbuttons = ARRAY_SIZE(netxbig_v2_buttons),
+};
+
+static struct platform_device netxbig_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &netxbig_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * GPIO extension LEDs
+ ****************************************************************************/
+
+/*
+ * The LEDs are controlled by a CPLD and can be configured through a GPIO
+ * extension bus:
+ *
+ * - address register : bit [0-2] -> GPIO [47-49]
+ * - data register : bit [0-2] -> GPIO [44-46]
+ * - enable register : GPIO 29
+ */
+
+static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
+static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
+
+static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
+ .addr = netxbig_v2_gpio_ext_addr,
+ .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
+ .data = netxbig_v2_gpio_ext_data,
+ .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
+ .enable = 29,
+};
+
+/*
+ * Address register selection:
+ *
+ * addr | register
+ * ----------------------------
+ * 0 | front LED
+ * 1 | front LED brightness
+ * 2 | SATA LED brightness
+ * 3 | SATA0 LED
+ * 4 | SATA1 LED
+ * 5 | SATA2 LED
+ * 6 | SATA3 LED
+ * 7 | SATA4 LED
+ *
+ * Data register configuration:
+ *
+ * data | LED brightness
+ * -------------------------------------------------
+ * 0 | min (off)
+ * - | -
+ * 7 | max
+ *
+ * data | front LED mode
+ * -------------------------------------------------
+ * 0 | fix off
+ * 1 | fix blue on
+ * 2 | fix red on
+ * 3 | blink blue on=1 sec and blue off=1 sec
+ * 4 | blink red on=1 sec and red off=1 sec
+ * 5 | blink blue on=2.5 sec and red on=0.5 sec
+ * 6 | blink blue on=1 sec and red on=1 sec
+ * 7 | blink blue on=0.5 sec and blue off=2.5 sec
+ *
+ * data | SATA LED mode
+ * -------------------------------------------------
+ * 0 | fix off
+ * 1 | SATA activity blink
+ * 2 | fix red on
+ * 3 | blink blue on=1 sec and blue off=1 sec
+ * 4 | blink red on=1 sec and red off=1 sec
+ * 5 | blink blue on=2.5 sec and red on=0.5 sec
+ * 6 | blink blue on=1 sec and red on=1 sec
+ * 7 | fix blue on
+ */
+
+static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 2,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 4,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
+
+static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 1,
+ [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = 7,
+};
+
+static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
+ [NETXBIG_LED_OFF] = 0,
+ [NETXBIG_LED_ON] = 7,
+ [NETXBIG_LED_SATA] = 1,
+ [NETXBIG_LED_TIMER1] = 3,
+ [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE,
+};
+
+static struct netxbig_led_timer netxbig_v2_led_timer[] = {
+ [0] = {
+ .delay_on = 500,
+ .delay_off = 500,
+ .mode = NETXBIG_LED_TIMER1,
+ },
+ [1] = {
+ .delay_on = 500,
+ .delay_off = 1000,
+ .mode = NETXBIG_LED_TIMER2,
+ },
+};
+
+#define NETXBIG_LED(_name, maddr, mval, baddr) \
+ { .name = _name, \
+ .mode_addr = maddr, \
+ .mode_val = mval, \
+ .bright_addr = baddr }
+
+static struct netxbig_led net2big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+};
+
+static struct netxbig_led_platform_data net2big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net2big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl),
+};
+
+static struct netxbig_led net5big_v2_leds_ctrl[] = {
+ NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1),
+ NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1),
+ NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2),
+ NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
+ NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2),
+};
+
+static struct netxbig_led_platform_data net5big_v2_leds_data = {
+ .gpio_ext = &netxbig_v2_gpio_ext,
+ .timer = netxbig_v2_led_timer,
+ .num_timer = ARRAY_SIZE(netxbig_v2_led_timer),
+ .leds = net5big_v2_leds_ctrl,
+ .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl),
+};
+
+static struct platform_device netxbig_v2_leds = {
+ .name = "leds-netxbig",
+ .id = -1,
+ .dev = {
+ .platform_data = &net2big_v2_leds_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int net2big_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Request power-off */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP13_GPIO, /* Rear power switch (on|auto) */
+ MPP14_GPIO, /* USB fuse alarm */
+ MPP15_GPIO, /* Rear power switch (auto|off) */
+ MPP16_GPIO, /* SATA HDD1 power */
+ MPP17_GPIO, /* SATA HDD2 power */
+ MPP20_SATA1_ACTn,
+ MPP21_SATA0_ACTn,
+ MPP24_GPIO, /* USB mode select */
+ MPP26_GPIO, /* USB device vbus */
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* GPIO extension ALE */
+ MPP34_GPIO, /* Rear Push button */
+ MPP35_GPIO, /* Inhibit switch power-off */
+ MPP36_GPIO, /* SATA HDD1 presence */
+ MPP37_GPIO, /* SATA HDD2 presence */
+ MPP40_GPIO, /* eSATA presence */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
+ 0
+};
+
+static unsigned int net5big_v2_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_GPO, /* Request power-off */
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP13_GPIO, /* Rear power switch (on|auto) */
+ MPP14_GPIO, /* USB fuse alarm */
+ MPP15_GPIO, /* Rear power switch (auto|off) */
+ MPP16_GPIO, /* SATA HDD1 power */
+ MPP17_GPIO, /* SATA HDD2 power */
+ MPP20_GE1_TXD0,
+ MPP21_GE1_TXD1,
+ MPP22_GE1_TXD2,
+ MPP23_GE1_TXD3,
+ MPP24_GE1_RXD0,
+ MPP25_GE1_RXD1,
+ MPP26_GE1_RXD2,
+ MPP27_GE1_RXD3,
+ MPP28_GPIO, /* USB enable host vbus */
+ MPP29_GPIO, /* GPIO extension ALE */
+ MPP30_GE1_RXCTL,
+ MPP31_GE1_RXCLK,
+ MPP32_GE1_TCLKOUT,
+ MPP33_GE1_TXCTL,
+ MPP34_GPIO, /* Rear Push button */
+ MPP35_GPIO, /* Inhibit switch power-off */
+ MPP36_GPIO, /* SATA HDD1 presence */
+ MPP37_GPIO, /* SATA HDD2 presence */
+ MPP38_GPIO, /* SATA HDD3 presence */
+ MPP39_GPIO, /* SATA HDD4 presence */
+ MPP40_GPIO, /* SATA HDD5 presence */
+ MPP41_GPIO, /* SATA HDD3 power */
+ MPP42_GPIO, /* SATA HDD4 power */
+ MPP43_GPIO, /* SATA HDD5 power */
+ MPP44_GPIO, /* GPIO extension (data 0) */
+ MPP45_GPIO, /* GPIO extension (data 1) */
+ MPP46_GPIO, /* GPIO extension (data 2) */
+ MPP47_GPIO, /* GPIO extension (addr 0) */
+ MPP48_GPIO, /* GPIO extension (addr 1) */
+ MPP49_GPIO, /* GPIO extension (addr 2) */
+ 0
+};
+
+#define NETXBIG_V2_GPIO_POWER_OFF 7
+
+static void netxbig_v2_power_off(void)
+{
+ gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1);
+}
+
+static void __init netxbig_v2_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ if (machine_is_net2big_v2())
+ kirkwood_mpp_conf(net2big_v2_mpp_config);
+ else
+ kirkwood_mpp_conf(net5big_v2_mpp_config);
+
+ if (machine_is_net2big_v2())
+ lacie_v2_hdd_power_init(2);
+ else
+ lacie_v2_hdd_power_init(5);
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&netxbig_v2_ge00_data);
+ if (machine_is_net5big_v2())
+ kirkwood_ge01_init(&netxbig_v2_ge01_data);
+ kirkwood_sata_init(&netxbig_v2_sata_data);
+ kirkwood_uart0_init();
+ lacie_v2_register_flash();
+ lacie_v2_register_i2c_devices();
+
+ if (machine_is_net5big_v2())
+ netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
+ platform_device_register(&netxbig_v2_leds);
+ platform_device_register(&netxbig_v2_gpio_buttons);
+
+ if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = netxbig_v2_power_off;
+ else
+ pr_err("netxbig_v2: failed to configure power-off GPIO\n");
+}
+
+#ifdef CONFIG_MACH_NET2BIG_V2
+MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
+ .boot_params = 0x00000100,
+ .init_machine = netxbig_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_NET5BIG_V2
+MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
+ .boot_params = 0x00000100,
+ .init_machine = netxbig_v2_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
new file mode 100644
index 00000000..f69beeff
--- /dev/null
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -0,0 +1,248 @@
+/*
+ * arch/arm/mach-kirkwood/openrd-setup.c
+ *
+ * Marvell OpenRD (Base|Client|Ultimate) Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition openrd_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data openrd_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data openrd_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(24),
+};
+
+static struct mv_sata_platform_data openrd_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mvsdio_platform_data openrd_mvsdio_data = {
+ .gpio_card_detect = 29, /* MPP29 used as SD card detect */
+};
+
+static unsigned int openrd_mpp_config[] __initdata = {
+ MPP12_SD_CLK,
+ MPP13_SD_CMD,
+ MPP14_SD_D0,
+ MPP15_SD_D1,
+ MPP16_SD_D2,
+ MPP17_SD_D3,
+ MPP28_GPIO,
+ MPP29_GPIO,
+ MPP34_GPIO,
+ 0
+};
+
+/* Configure MPP for UART1 */
+static unsigned int openrd_uart1_mpp_config[] __initdata = {
+ MPP13_UART1_TXD,
+ MPP14_UART1_RXD,
+ 0
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("cs42l51", 0x4a),
+ },
+};
+
+static int __initdata uart1;
+
+static int __init sd_uart_selection(char *str)
+{
+ uart1 = -EINVAL;
+
+ /* Default is SD. Change if required, for UART */
+ if (!str)
+ return 0;
+
+ if (!strncmp(str, "232", 3)) {
+ uart1 = 232;
+ } else if (!strncmp(str, "485", 3)) {
+ /* OpenRD-Base doesn't have RS485. Treat is as an
+ * unknown argument & just have default setting -
+ * which is SD */
+ if (machine_is_openrd_base()) {
+ uart1 = -ENODEV;
+ return 1;
+ }
+
+ uart1 = 485;
+ }
+ return 1;
+}
+/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */
+__setup("kw_openrd_init_uart1=", sd_uart_selection);
+
+static int __init uart1_mpp_config(void)
+{
+ kirkwood_mpp_conf(openrd_uart1_mpp_config);
+
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 selection"
+ ", gpio: 34\n");
+ return -EIO;
+ }
+
+ if (gpio_request(28, "RS232_RS485_SEL")) {
+ printk(KERN_ERR "GPIO request failed for RS232/RS485 selection"
+ ", gpio# 28\n");
+ gpio_free(34);
+ return -EIO;
+ }
+
+ /* Select UART1
+ * Pin # 34: 0 => UART1, 1 => SD */
+ gpio_direction_output(34, 0);
+
+ /* Select RS232 OR RS485
+ * Pin # 28: 0 => RS232, 1 => RS485 */
+ if (uart1 == 232)
+ gpio_direction_output(28, 0);
+ else
+ gpio_direction_output(28, 1);
+
+ gpio_free(34);
+ gpio_free(28);
+
+ return 0;
+}
+
+static void __init openrd_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(openrd_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(openrd_nand_parts), 25);
+
+ kirkwood_ehci_init();
+
+ if (machine_is_openrd_ultimate()) {
+ openrd_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
+ openrd_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1);
+ }
+
+ kirkwood_ge00_init(&openrd_ge00_data);
+ if (!machine_is_openrd_base())
+ kirkwood_ge01_init(&openrd_ge01_data);
+
+ kirkwood_sata_init(&openrd_sata_data);
+
+ kirkwood_i2c_init();
+
+ if (machine_is_openrd_client() || machine_is_openrd_ultimate()) {
+ i2c_register_board_info(0, i2c_board_info,
+ ARRAY_SIZE(i2c_board_info));
+ kirkwood_audio_init();
+ }
+
+ if (uart1 <= 0) {
+ if (uart1 < 0)
+ printk(KERN_ERR "Invalid kernel parameter to select "
+ "UART1. Defaulting to SD. ERROR CODE: %d\n",
+ uart1);
+
+ /* Select SD
+ * Pin # 34: 0 => UART1, 1 => SD */
+ if (gpio_request(34, "SD_UART1_SEL")) {
+ printk(KERN_ERR "GPIO request failed for SD/UART1 "
+ "selection, gpio: 34\n");
+ } else {
+
+ gpio_direction_output(34, 1);
+ gpio_free(34);
+ kirkwood_sdio_init(&openrd_mvsdio_data);
+ }
+ } else {
+ if (!uart1_mpp_config())
+ kirkwood_uart1_init();
+ }
+}
+
+static int __init openrd_pci_init(void)
+{
+ if (machine_is_openrd_base() ||
+ machine_is_openrd_client() ||
+ machine_is_openrd_ultimate())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(openrd_pci_init);
+
+#ifdef CONFIG_MACH_OPENRD_BASE
+MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board")
+ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+ .boot_params = 0x00000100,
+ .init_machine = openrd_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_OPENRD_CLIENT
+MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board")
+ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+ .boot_params = 0x00000100,
+ .init_machine = openrd_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_OPENRD_ULTIMATE
+MACHINE_START(OPENRD_ULTIMATE, "Marvell OpenRD Ultimate Board")
+ /* Maintainer: Dhaval Vasa <dhaval.vasa@einfochips.com> */
+ .boot_params = 0x00000100,
+ .init_machine = openrd_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
new file mode 100644
index 00000000..ca294ff6
--- /dev/null
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -0,0 +1,282 @@
+/*
+ * arch/arm/mach-kirkwood/pcie.c
+ *
+ * PCIe functions for Marvell Kirkwood SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mbus.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+
+void kirkwood_enable_pcie(void)
+{
+ u32 curr = readl(CLOCK_GATING_CTRL);
+ if (!(curr & CGC_PEX0))
+ writel(curr | CGC_PEX0, CLOCK_GATING_CTRL);
+}
+
+void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+ kirkwood_enable_pcie();
+ *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
+ *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
+}
+
+struct pcie_port {
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ int irq;
+ struct resource res[2];
+};
+
+static int pcie_port_map[2];
+static int num_pcie_ports;
+
+static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ return sys->private_data;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+ /*
+ * Don't go out when trying to access --
+ * 1. nonexisting device on local bus
+ * 2. where there's no device connected (no link)
+ */
+ if (bus == pp->root_bus_nr && dev == 0)
+ return 1;
+
+ if (!orion_pcie_link_up(pp->base))
+ return 0;
+
+ if (bus == pp->root_bus_nr && dev != 1)
+ return 0;
+
+ return 1;
+}
+
+
+/*
+ * PCIe config cycles are done by programming the PCIE_CONF_ADDR register
+ * and then reading the PCIE_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct pcie_port *pp = bus_to_port(bus);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct pcie_port *pp = bus_to_port(bus);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static struct pci_ops pcie_ops = {
+ .read = pcie_rd_conf,
+ .write = pcie_wr_conf,
+};
+
+static void __init pcie0_ioresources_init(struct pcie_port *pp)
+{
+ pp->base = (void __iomem *)PCIE_VIRT_BASE;
+ pp->irq = IRQ_KIRKWOOD_PCIE;
+
+ /*
+ * IORESOURCE_IO
+ */
+ pp->res[0].name = "PCIe 0 I/O Space";
+ pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
+ pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
+ pp->res[0].flags = IORESOURCE_IO;
+
+ /*
+ * IORESOURCE_MEM
+ */
+ pp->res[1].name = "PCIe 0 MEM";
+ pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
+ pp->res[1].flags = IORESOURCE_MEM;
+}
+
+static void __init pcie1_ioresources_init(struct pcie_port *pp)
+{
+ pp->base = (void __iomem *)PCIE1_VIRT_BASE;
+ pp->irq = IRQ_KIRKWOOD_PCIE1;
+
+ /*
+ * IORESOURCE_IO
+ */
+ pp->res[0].name = "PCIe 1 I/O Space";
+ pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE;
+ pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
+ pp->res[0].flags = IORESOURCE_IO;
+
+ /*
+ * IORESOURCE_MEM
+ */
+ pp->res[1].name = "PCIe 1 MEM";
+ pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
+ pp->res[1].flags = IORESOURCE_MEM;
+}
+
+static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ extern unsigned int kirkwood_clk_ctrl;
+ struct pcie_port *pp;
+ int index;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ index = pcie_port_map[nr];
+ printk(KERN_INFO "PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
+
+ pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ panic("PCIe: failed to allocate pcie_port data");
+ sys->private_data = pp;
+ pp->root_bus_nr = sys->busnr;
+ spin_lock_init(&pp->conf_lock);
+
+ switch (index) {
+ case 0:
+ kirkwood_clk_ctrl |= CGC_PEX0;
+ pcie0_ioresources_init(pp);
+ break;
+ case 1:
+ kirkwood_clk_ctrl |= CGC_PEX1;
+ pcie1_ioresources_init(pp);
+ break;
+ default:
+ panic("PCIe setup: invalid controller %d", index);
+ }
+
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe%d IO resource failed\n", index);
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe%d Memory resource failed\n", index);
+
+ sys->resource[0] = &pp->res[0];
+ sys->resource[1] = &pp->res[1];
+ sys->resource[2] = NULL;
+ sys->io_offset = 0;
+
+ /*
+ * Generic PCIe unit setup.
+ */
+ orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+
+ orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info);
+
+ return 1;
+}
+
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+ /*
+ * Prevent enumeration of root complex.
+ */
+ if (dev->bus->parent == NULL && dev->devfn == 0) {
+ int i;
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static struct pci_bus __init *
+kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr < num_pcie_ports) {
+ bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct pcie_port *pp = bus_to_port(dev->bus);
+
+ return pp->irq;
+}
+
+static struct hw_pci kirkwood_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .setup = kirkwood_pcie_setup,
+ .scan = kirkwood_pcie_scan_bus,
+ .map_irq = kirkwood_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int index, unsigned long base)
+{
+ printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
+
+ if (orion_pcie_link_up((void __iomem *)base)) {
+ printk(KERN_INFO "link up\n");
+ pcie_port_map[num_pcie_ports++] = index;
+ } else
+ printk(KERN_INFO "link down, ignoring\n");
+}
+
+void __init kirkwood_pcie_init(unsigned int portmask)
+{
+ if (portmask & KW_PCIE0)
+ add_pcie_port(0, PCIE_VIRT_BASE);
+
+ if (portmask & KW_PCIE1)
+ add_pcie_port(1, PCIE1_VIRT_BASE);
+
+ kirkwood_pci.nr_controllers = num_pcie_ports;
+ pci_common_init(&kirkwood_pci);
+}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
new file mode 100644
index 00000000..75c6601b
--- /dev/null
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+ *
+ * Marvell RD-88F6192-NAS Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+
+#define RD88F6192_GPIO_USB_VBUS 10
+
+static struct mv643xx_eth_platform_data rd88f6192_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data rd88f6192_sata_data = {
+ .n_ports = 2,
+};
+
+static const struct flash_platform_data rd88F6192_spi_slave_data = {
+ .type = "m25p128",
+};
+
+static struct spi_board_info __initdata rd88F6192_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &rd88F6192_spi_slave_data,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static void __init rd88f6192_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+
+ orion_gpio_set_valid(RD88F6192_GPIO_USB_VBUS, 1);
+ if (gpio_request(RD88F6192_GPIO_USB_VBUS, "USB VBUS") != 0 ||
+ gpio_direction_output(RD88F6192_GPIO_USB_VBUS, 1) != 0)
+ pr_err("RD-88F6192-NAS: failed to setup USB VBUS GPIO\n");
+
+ kirkwood_ehci_init();
+ kirkwood_ge00_init(&rd88f6192_ge00_data);
+ kirkwood_sata_init(&rd88f6192_sata_data);
+ spi_register_board_info(rd88F6192_spi_slave_info,
+ ARRAY_SIZE(rd88F6192_spi_slave_info));
+ kirkwood_spi_init();
+ kirkwood_uart0_init();
+}
+
+static int __init rd88f6192_pci_init(void)
+{
+ if (machine_is_rd88f6192_nas())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(rd88f6192_pci_init);
+
+MACHINE_START(RD88F6192_NAS, "Marvell RD-88F6192-NAS Development Board")
+ /* Maintainer: Saeed Bishara <saeed@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f6192_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
new file mode 100644
index 00000000..0f75494d
--- /dev/null
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -0,0 +1,124 @@
+/*
+ * arch/arm/mach-kirkwood/rd88f6281-setup.c
+ *
+ * Marvell RD-88F6281 Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/partitions.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition rd88f6281_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_2M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data rd88f6281_switch_chip_data = {
+ .port_names[0] = "lan1",
+ .port_names[1] = "lan2",
+ .port_names[2] = "lan3",
+ .port_names[3] = "lan4",
+ .port_names[5] = "cpu",
+};
+
+static struct dsa_platform_data rd88f6281_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f6281_switch_chip_data,
+};
+
+static struct mv643xx_eth_platform_data rd88f6281_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(11),
+};
+
+static struct mv_sata_platform_data rd88f6281_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mvsdio_platform_data rd88f6281_mvsdio_data = {
+ .gpio_card_detect = 28,
+};
+
+static unsigned int rd88f6281_mpp_config[] __initdata = {
+ MPP28_GPIO,
+ 0
+};
+
+static void __init rd88f6281_init(void)
+{
+ u32 dev, rev;
+
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(rd88f6281_mpp_config);
+
+ kirkwood_nand_init(ARRAY_AND_SIZE(rd88f6281_nand_parts), 25);
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&rd88f6281_ge00_data);
+ kirkwood_pcie_id(&dev, &rev);
+ if (rev == MV88F6281_REV_A0) {
+ rd88f6281_switch_chip_data.sw_addr = 10;
+ kirkwood_ge01_init(&rd88f6281_ge01_data);
+ } else {
+ rd88f6281_switch_chip_data.port_names[4] = "wan";
+ }
+ kirkwood_ge00_switch_init(&rd88f6281_switch_plat_data, NO_IRQ);
+
+ kirkwood_sata_init(&rd88f6281_sata_data);
+ kirkwood_sdio_init(&rd88f6281_mvsdio_data);
+ kirkwood_uart0_init();
+}
+
+static int __init rd88f6281_pci_init(void)
+{
+ if (machine_is_rd88f6281())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(rd88f6281_pci_init);
+
+MACHINE_START(RD88F6281, "Marvell RD-88F6281 Reference Board")
+ /* Maintainer: Saeed Bishara <saeed@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f6281_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
new file mode 100644
index 00000000..17de0bf5
--- /dev/null
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -0,0 +1,159 @@
+/*
+ * arch/arm/mach-kirkwood/sheevaplug-setup.c
+ *
+ * Marvell SheevaPlug Reference Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include <plat/mvsdio.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mtd_partition sheevaplug_nand_parts[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_1M
+ }, {
+ .name = "uImage",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static struct mv643xx_eth_platform_data sheevaplug_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv_sata_platform_data sheeva_esata_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mvsdio_platform_data sheevaplug_mvsdio_data = {
+ /* unfortunately the CD signal has not been connected */
+};
+
+static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
+ .gpio_write_protect = 44, /* MPP44 used as SD write protect */
+ .gpio_card_detect = 47, /* MPP47 used as SD card detect */
+};
+
+static struct gpio_led sheevaplug_led_pins[] = {
+ {
+ .name = "plug:red:misc",
+ .default_trigger = "none",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
+ .name = "plug:green:health",
+ .default_trigger = "default-on",
+ .gpio = 49,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data sheevaplug_led_data = {
+ .leds = sheevaplug_led_pins,
+ .num_leds = ARRAY_SIZE(sheevaplug_led_pins),
+};
+
+static struct platform_device sheevaplug_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &sheevaplug_led_data,
+ }
+};
+
+static unsigned int sheevaplug_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED Red */
+ MPP49_GPIO, /* LED */
+ 0
+};
+
+static unsigned int sheeva_esata_mpp_config[] __initdata = {
+ MPP29_GPIO, /* USB Power Enable */
+ MPP44_GPIO, /* SD Write Protect */
+ MPP47_GPIO, /* SD Card Detect */
+ MPP49_GPIO, /* LED Green */
+ 0
+};
+
+static void __init sheevaplug_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+
+ /* setup gpio pin select */
+ if (machine_is_sheeva_esata())
+ kirkwood_mpp_conf(sheeva_esata_mpp_config);
+ else
+ kirkwood_mpp_conf(sheevaplug_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_nand_init(ARRAY_AND_SIZE(sheevaplug_nand_parts), 25);
+
+ if (gpio_request(29, "USB Power Enable") != 0 ||
+ gpio_direction_output(29, 1) != 0)
+ printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n");
+ kirkwood_ehci_init();
+
+ kirkwood_ge00_init(&sheevaplug_ge00_data);
+
+ /* honor lower power consumption for plugs with out eSATA */
+ if (machine_is_sheeva_esata())
+ kirkwood_sata_init(&sheeva_esata_sata_data);
+
+ /* enable sd wp and sd cd on plugs with esata */
+ if (machine_is_sheeva_esata())
+ kirkwood_sdio_init(&sheeva_esata_mvsdio_data);
+ else
+ kirkwood_sdio_init(&sheevaplug_mvsdio_data);
+
+ platform_device_register(&sheevaplug_leds);
+}
+
+#ifdef CONFIG_MACH_SHEEVAPLUG
+MACHINE_START(SHEEVAPLUG, "Marvell SheevaPlug Reference Board")
+ /* Maintainer: shadi Ammouri <shadi@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = sheevaplug_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_ESATA_SHEEVAPLUG
+MACHINE_START(ESATA_SHEEVAPLUG, "Marvell eSATA SheevaPlug Reference Board")
+ .boot_params = 0x00000100,
+ .init_machine = sheevaplug_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
new file mode 100644
index 00000000..e6b9b1b2
--- /dev/null
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -0,0 +1,210 @@
+/*
+ *
+ * HP t5325 Thin Client setup
+ *
+ * Copyright (C) 2010 Martin Michlmayr <tbm@cyrius.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/i2c.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <sound/alc5623.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+
+struct mtd_partition hp_t5325_partitions[] = {
+ {
+ .name = "u-boot env",
+ .size = SZ_64K,
+ .offset = SZ_512K + SZ_256K,
+ },
+ {
+ .name = "permanent u-boot env",
+ .size = SZ_64K,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "HP env",
+ .size = SZ_64K,
+ .offset = MTDPART_OFS_APPEND,
+ },
+ {
+ .name = "u-boot",
+ .size = SZ_512K,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "SSD firmware",
+ .size = SZ_256K,
+ .offset = SZ_512K,
+ },
+};
+
+const struct flash_platform_data hp_t5325_flash = {
+ .type = "mx25l8005",
+ .name = "spi_flash",
+ .parts = hp_t5325_partitions,
+ .nr_parts = ARRAY_SIZE(hp_t5325_partitions),
+};
+
+struct spi_board_info __initdata hp_t5325_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &hp_t5325_flash,
+ .irq = -1,
+ },
+};
+
+static struct mv643xx_eth_platform_data hp_t5325_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data hp_t5325_sata_data = {
+ .n_ports = 2,
+};
+
+static struct gpio_keys_button hp_t5325_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = 45,
+ .desc = "Power",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data hp_t5325_button_data = {
+ .buttons = hp_t5325_buttons,
+ .nbuttons = ARRAY_SIZE(hp_t5325_buttons),
+};
+
+static struct platform_device hp_t5325_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &hp_t5325_button_data,
+ }
+};
+
+static unsigned int hp_t5325_mpp_config[] __initdata = {
+ MPP0_NF_IO2,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_NF_IO6,
+ MPP5_NF_IO7,
+ MPP6_SYSRST_OUTn,
+ MPP7_SPI_SCn,
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP12_SD_CLK,
+ MPP13_GPIO,
+ MPP14_GPIO,
+ MPP15_GPIO,
+ MPP16_GPIO,
+ MPP17_GPIO,
+ MPP18_NF_IO0,
+ MPP19_NF_IO1,
+ MPP20_GPIO,
+ MPP21_GPIO,
+ MPP22_GPIO,
+ MPP23_GPIO,
+ MPP32_GPIO,
+ MPP33_GE1_TXCTL,
+ MPP39_AU_I2SBCLK,
+ MPP40_AU_I2SDO,
+ MPP43_AU_I2SDI,
+ MPP41_AU_I2SLRCLK,
+ MPP42_AU_I2SMCLK,
+ MPP45_GPIO, /* Power button */
+ MPP48_GPIO, /* Board power off */
+ 0
+};
+
+static struct alc5623_platform_data alc5621_data = {
+ .add_ctrl = 0x3700,
+ .jack_det_ctrl = 0x4810,
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("alc5621", 0x1a),
+ .platform_data = &alc5621_data,
+ },
+};
+
+#define HP_T5325_GPIO_POWER_OFF 48
+
+static void hp_t5325_power_off(void)
+{
+ gpio_set_value(HP_T5325_GPIO_POWER_OFF, 1);
+}
+
+static void __init hp_t5325_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(hp_t5325_mpp_config);
+
+ kirkwood_uart0_init();
+ spi_register_board_info(hp_t5325_spi_slave_info,
+ ARRAY_SIZE(hp_t5325_spi_slave_info));
+ kirkwood_spi_init();
+ kirkwood_i2c_init();
+ kirkwood_ge00_init(&hp_t5325_ge00_data);
+ kirkwood_sata_init(&hp_t5325_sata_data);
+ kirkwood_ehci_init();
+ platform_device_register(&hp_t5325_button_device);
+
+ i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info));
+ kirkwood_audio_init();
+
+ if (gpio_request(HP_T5325_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(HP_T5325_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = hp_t5325_power_off;
+ else
+ pr_err("t5325: failed to configure power-off GPIO\n");
+}
+
+static int __init hp_t5325_pci_init(void)
+{
+ if (machine_is_t5325())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(hp_t5325_pci_init);
+
+MACHINE_START(T5325, "HP t5325 Thin Client")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .boot_params = 0x00000100,
+ .init_machine = hp_t5325_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
new file mode 100644
index 00000000..68f32f2b
--- /dev/null
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -0,0 +1,141 @@
+/*
+ *
+ * QNAP TS-11x/TS-21x Turbo NAS Board Setup
+ *
+ * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx1x-common.h"
+
+static struct i2c_board_info __initdata qnap_ts219_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data qnap_ts219_sata_data = {
+ .n_ports = 2,
+};
+
+static struct gpio_keys_button qnap_ts219_buttons[] = {
+ {
+ .code = KEY_COPY,
+ .gpio = 15,
+ .desc = "USB Copy",
+ .active_low = 1,
+ },
+ {
+ .code = KEY_RESTART,
+ .gpio = 16,
+ .desc = "Reset",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts219_button_data = {
+ .buttons = qnap_ts219_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts219_buttons),
+};
+
+static struct platform_device qnap_ts219_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts219_button_data,
+ }
+};
+
+static unsigned int qnap_ts219_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP4_SATA1_ACTn,
+ MPP5_SATA0_ACTn,
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP13_UART1_TXD, /* PIC controller */
+ MPP14_UART1_RXD, /* PIC controller */
+ MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */
+ MPP16_GPIO, /* Reset button (on devices with 88F6281) */
+ MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
+ MPP37_GPIO, /* Reset button (on devices with 88F6282) */
+ MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */
+ MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */
+ 0
+};
+
+static void __init qnap_ts219_init(void)
+{
+ u32 dev, rev;
+
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(qnap_ts219_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_uart1_init(); /* A PIC controller is connected here. */
+ qnap_tsx1x_register_flash();
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, &qnap_ts219_i2c_rtc, 1);
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID) {
+ qnap_ts219_buttons[0].gpio = 43; /* USB Copy button */
+ qnap_ts219_buttons[1].gpio = 37; /* Reset button */
+ qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
+ }
+
+ kirkwood_ge00_init(&qnap_ts219_ge00_data);
+ kirkwood_sata_init(&qnap_ts219_sata_data);
+ kirkwood_ehci_init();
+ platform_device_register(&qnap_ts219_button_device);
+
+ pm_power_off = qnap_tsx1x_power_off;
+
+}
+
+static int __init ts219_pci_init(void)
+{
+ if (machine_is_ts219())
+ kirkwood_pcie_init(KW_PCIE0);
+
+ return 0;
+}
+subsys_initcall(ts219_pci_init);
+
+MACHINE_START(TS219, "QNAP TS-119/TS-219")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts219_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
new file mode 100644
index 00000000..d5d00997
--- /dev/null
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -0,0 +1,185 @@
+/*
+ *
+ * QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup
+ *
+ * Copyright (C) 2009-2010 Martin Michlmayr <tbm@cyrius.com>
+ * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx1x-common.h"
+
+/* for the PCIe reset workaround */
+#include <plat/pcie.h>
+
+
+#define QNAP_TS41X_JUMPER_JP1 45
+
+static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv_sata_platform_data qnap_ts41x_sata_data = {
+ .n_ports = 2,
+};
+
+static struct gpio_keys_button qnap_ts41x_buttons[] = {
+ {
+ .code = KEY_COPY,
+ .gpio = 43,
+ .desc = "USB Copy",
+ .active_low = 1,
+ },
+ {
+ .code = KEY_RESTART,
+ .gpio = 37,
+ .desc = "Reset",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts41x_button_data = {
+ .buttons = qnap_ts41x_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts41x_buttons),
+};
+
+static struct platform_device qnap_ts41x_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts41x_button_data,
+ }
+};
+
+static unsigned int qnap_ts41x_mpp_config[] __initdata = {
+ MPP0_SPI_SCn,
+ MPP1_SPI_MOSI,
+ MPP2_SPI_SCK,
+ MPP3_SPI_MISO,
+ MPP6_SYSRST_OUTn,
+ MPP7_PEX_RST_OUTn,
+ MPP8_TW0_SDA,
+ MPP9_TW0_SCK,
+ MPP10_UART0_TXD,
+ MPP11_UART0_RXD,
+ MPP13_UART1_TXD, /* PIC controller */
+ MPP14_UART1_RXD, /* PIC controller */
+ MPP15_SATA0_ACTn,
+ MPP16_SATA1_ACTn,
+ MPP20_GE1_TXD0,
+ MPP21_GE1_TXD1,
+ MPP22_GE1_TXD2,
+ MPP23_GE1_TXD3,
+ MPP24_GE1_RXD0,
+ MPP25_GE1_RXD1,
+ MPP26_GE1_RXD2,
+ MPP27_GE1_RXD3,
+ MPP30_GE1_RXCTL,
+ MPP31_GE1_RXCLK,
+ MPP32_GE1_TCLKOUT,
+ MPP33_GE1_TXCTL,
+ MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */
+ MPP37_GPIO, /* Reset button */
+ MPP43_GPIO, /* USB Copy button */
+ MPP44_GPIO, /* Board ID: 0: TS-419U, 1: TS-419 */
+ MPP45_GPIO, /* JP1: 0: LCD, 1: serial console */
+ MPP46_GPIO, /* External SATA HDD1 error indicator */
+ MPP47_GPIO, /* External SATA HDD2 error indicator */
+ MPP48_GPIO, /* External SATA HDD3 error indicator */
+ MPP49_GPIO, /* External SATA HDD4 error indicator */
+ 0
+};
+
+static void __init qnap_ts41x_init(void)
+{
+ u32 dev, rev;
+
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ kirkwood_init();
+ kirkwood_mpp_conf(qnap_ts41x_mpp_config);
+
+ kirkwood_uart0_init();
+ kirkwood_uart1_init(); /* A PIC controller is connected here. */
+ qnap_tsx1x_register_flash();
+ kirkwood_i2c_init();
+ i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1);
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID) {
+ qnap_ts41x_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0);
+ qnap_ts41x_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1);
+ }
+ kirkwood_ge00_init(&qnap_ts41x_ge00_data);
+ kirkwood_ge01_init(&qnap_ts41x_ge01_data);
+
+ kirkwood_sata_init(&qnap_ts41x_sata_data);
+ kirkwood_ehci_init();
+ platform_device_register(&qnap_ts41x_button_device);
+
+ pm_power_off = qnap_tsx1x_power_off;
+
+ if (gpio_request(QNAP_TS41X_JUMPER_JP1, "JP1") == 0)
+ gpio_export(QNAP_TS41X_JUMPER_JP1, 0);
+}
+
+static int __init ts41x_pci_init(void)
+{
+ if (machine_is_ts41x()) {
+ u32 dev, rev;
+
+ /*
+ * Without this explicit reset, the PCIe SATA controller
+ * (Marvell 88sx7042/sata_mv) is known to stop working
+ * after a few minutes.
+ */
+ orion_pcie_reset((void __iomem *)PCIE_VIRT_BASE);
+
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID)
+ kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
+ else
+ kirkwood_pcie_init(KW_PCIE0);
+ }
+
+ return 0;
+}
+subsys_initcall(ts41x_pci_init);
+
+MACHINE_START(TS41X, "QNAP TS-41x")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts41x_init,
+ .map_io = kirkwood_map_io,
+ .init_early = kirkwood_init_early,
+ .init_irq = kirkwood_init_irq,
+ .timer = &kirkwood_timer,
+MACHINE_END
diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c
new file mode 100644
index 00000000..24294b2b
--- /dev/null
+++ b/arch/arm/mach-kirkwood/tsx1x-common.c
@@ -0,0 +1,113 @@
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/serial_reg.h>
+#include <mach/kirkwood.h>
+#include "common.h"
+
+/*
+ * QNAP TS-x1x Boards flash
+ */
+
+/****************************************************************************
+ * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the
+ * partitions on the device because we want to keep compatibility with
+ * the QNAP firmware.
+ * Layout as used by QNAP:
+ * 0x00000000-0x00080000 : "U-Boot"
+ * 0x00200000-0x00400000 : "Kernel"
+ * 0x00400000-0x00d00000 : "RootFS"
+ * 0x00d00000-0x01000000 : "RootFS2"
+ * 0x00080000-0x000c0000 : "U-Boot Config"
+ * 0x000c0000-0x00200000 : "NAS Config"
+ *
+ * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout
+ * used by the QNAP TS-109/TS-209.
+ *
+ ***************************************************************************/
+
+struct mtd_partition qnap_tsx1x_partitions[] = {
+ {
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0x00200000,
+ }, {
+ .name = "RootFS1",
+ .size = 0x00900000,
+ .offset = 0x00400000,
+ }, {
+ .name = "RootFS2",
+ .size = 0x00300000,
+ .offset = 0x00d00000,
+ }, {
+ .name = "U-Boot Config",
+ .size = 0x00040000,
+ .offset = 0x00080000,
+ }, {
+ .name = "NAS Config",
+ .size = 0x00140000,
+ .offset = 0x000c0000,
+ },
+};
+
+const struct flash_platform_data qnap_tsx1x_flash = {
+ .type = "m25p128",
+ .name = "spi_flash",
+ .parts = qnap_tsx1x_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_tsx1x_partitions),
+};
+
+struct spi_board_info __initdata qnap_tsx1x_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &qnap_tsx1x_flash,
+ .irq = -1,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+void __init qnap_tsx1x_register_flash(void)
+{
+ spi_register_board_info(qnap_tsx1x_spi_slave_info,
+ ARRAY_SIZE(qnap_tsx1x_spi_slave_info));
+ kirkwood_spi_init();
+}
+
+
+/*****************************************************************************
+ * QNAP TS-x1x specific power off method via UART1-attached PIC
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+void qnap_tsx1x_power_off(void)
+{
+ /* 19200 baud divisor */
+ const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack UART1 and reset into sane state (19200,8n1) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x03, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x00, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* send the power-off command 'A' to PIC */
+ writel('A', UART1_REG(TX));
+}
+
diff --git a/arch/arm/mach-kirkwood/tsx1x-common.h b/arch/arm/mach-kirkwood/tsx1x-common.h
new file mode 100644
index 00000000..7fa03736
--- /dev/null
+++ b/arch/arm/mach-kirkwood/tsx1x-common.h
@@ -0,0 +1,7 @@
+#ifndef __ARCH_KIRKWOOD_TSX1X_COMMON_H
+#define __ARCH_KIRKWOOD_TSX1X_COMMON_H
+
+extern void __init qnap_tsx1x_register_flash(void);
+extern void qnap_tsx1x_power_off(void);
+
+#endif
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
new file mode 100644
index 00000000..f5c39a8c
--- /dev/null
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -0,0 +1,26 @@
+if ARCH_KS8695
+
+menu "Kendin/Micrel KS8695 Implementations"
+
+config MACH_KS8695
+ bool "KS8695 development board"
+ select MIGHT_HAVE_PCI
+ help
+ Say 'Y' here if you want your kernel to run on the original
+ Kendin-Micrel KS8695 development board.
+
+config MACH_DSM320
+ bool "DSM-320 Wireless Media Player"
+ help
+ Say 'Y' here if you want your kernel to run on the D-Link
+ DSM-320 Wireless Media Player.
+
+config MACH_ACS5K
+ bool "Brivo Systems LLC, ACS-5000 Master board"
+ help
+ say 'Y' here if you want your kernel to run on the Brivo
+ Systems LLC, ACS-5000 Master board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
new file mode 100644
index 00000000..7e3e8160
--- /dev/null
+++ b/arch/arm/mach-ks8695/Makefile
@@ -0,0 +1,20 @@
+# arch/arm/mach-ks8695/Makefile
+#
+# Makefile for KS8695 architecture support
+#
+
+obj-y := cpu.o irq.o time.o gpio.o devices.o
+obj-m :=
+obj-n :=
+obj- :=
+
+# PCI support is optional
+obj-$(CONFIG_PCI) += pci.o
+
+# LEDs
+obj-$(CONFIG_LEDS) += leds.o
+
+# Board-specific support
+obj-$(CONFIG_MACH_KS8695) += board-micrel.o
+obj-$(CONFIG_MACH_DSM320) += board-dsm320.o
+obj-$(CONFIG_MACH_ACS5K) += board-acs5k.o
diff --git a/arch/arm/mach-ks8695/Makefile.boot b/arch/arm/mach-ks8695/Makefile.boot
new file mode 100644
index 00000000..48eb2cb3
--- /dev/null
+++ b/arch/arm/mach-ks8695/Makefile.boot
@@ -0,0 +1,8 @@
+# Note: the following conditions must always be true:
+# ZRELADDR == virt_to_phys(TEXTADDR)
+# PARAMS_PHYS must be within 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
new file mode 100644
index 00000000..3ca4f8e6
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-acs5k.c
@@ -0,0 +1,231 @@
+/*
+ * arch/arm/mach-ks8695/board-acs5k.c
+ *
+ * Brivo Systems LLC, ACS-5000 Master Board
+ *
+ * Copyright 2008 Simtec Electronics
+ * Daniel Silverstone <dsilvers@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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pca953x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/devices.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
+ .sda_pin = 4,
+ .scl_pin = 5,
+ .udelay = 10,
+};
+
+static struct platform_device acs5k_i2c_device = {
+ .name = "i2c-gpio",
+ .id = -1,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &acs5k_i2c_device_platdata,
+ },
+};
+
+static int acs5k_pca9555_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ static int acs5k_gpio_value[] = {
+ -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, -1, 0, 1, 0, -1, -1
+ };
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(acs5k_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "ACS-5000 GPIO Expander");
+ if (acs5k_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ acs5k_gpio_value[n]);
+ gpio_export(gpio_base + n, 0); /* Export, direction locked down */
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data acs5k_i2c_pca9555_platdata = {
+ .gpio_base = 16, /* Start directly after the CPU's GPIO */
+ .invert = 0, /* Do not invert */
+ .setup = acs5k_pca9555_setup,
+};
+
+static struct i2c_board_info acs5k_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ .platform_data = &acs5k_i2c_pca9555_platdata,
+ },
+};
+
+static void __devinit acs5k_i2c_init(void)
+{
+ /* The gpio interface */
+ platform_device_register(&acs5k_i2c_device);
+ /* I2C devices */
+ i2c_register_board_info(0, acs5k_i2c_devs,
+ ARRAY_SIZE(acs5k_i2c_devs));
+}
+
+static struct mtd_partition acs5k_nor_partitions[] = {
+ [0] = {
+ .name = "Boot Agent and config",
+ .size = SZ_256K,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "Kernel",
+ .size = SZ_1M,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "SquashFS1",
+ .size = SZ_2M,
+ .offset = SZ_256K + SZ_1M,
+ },
+ [3] = {
+ .name = "SquashFS2",
+ .size = SZ_4M + SZ_2M,
+ .offset = SZ_256K + SZ_1M + SZ_2M,
+ },
+ [4] = {
+ .name = "Data",
+ .size = SZ_16M + SZ_4M + SZ_2M + SZ_512K, /* 22.5 MB */
+ .offset = SZ_256K + SZ_8M + SZ_1M,
+ }
+};
+
+static struct physmap_flash_data acs5k_nor_pdata = {
+ .width = 4,
+ .nr_parts = ARRAY_SIZE(acs5k_nor_partitions),
+ .parts = acs5k_nor_partitions,
+};
+
+static struct resource acs5k_nor_resource[] = {
+ [0] = {
+ .start = SZ_32M, /* We expect the bootloader to map
+ * the flash here.
+ */
+ .end = SZ_32M + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SZ_32M + SZ_16M,
+ .end = SZ_32M + SZ_32M - SZ_256K - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device acs5k_device_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(acs5k_nor_resource),
+ .resource = acs5k_nor_resource,
+ .dev = {
+ .platform_data = &acs5k_nor_pdata,
+ },
+};
+
+static void __init acs5k_register_nor(void)
+{
+ int ret;
+
+ if (acs5k_nor_partitions[0].mask_flags == 0)
+ printk(KERN_WARNING "Warning: Unprotecting bootloader and configuration partition\n");
+
+ ret = platform_device_register(&acs5k_device_nor);
+ if (ret < 0)
+ printk(KERN_ERR "failed to register physmap-flash device\n");
+}
+
+static int __init acs5k_protection_setup(char *s)
+{
+ /* We can't allocate anything here but we should be able
+ * to trivially parse s and decide if we can protect the
+ * bootloader partition or not
+ */
+ if (strcmp(s, "no") == 0)
+ acs5k_nor_partitions[0].mask_flags = 0;
+
+ return 1;
+}
+
+__setup("protect_bootloader=", acs5k_protection_setup);
+
+static void __init acs5k_init_gpio(void)
+{
+ int i;
+
+ ks8695_register_gpios();
+ for (i = 0; i < 4; ++i)
+ gpio_request(i, "ACS5K IRQ");
+ gpio_request(7, "ACS5K KS_FRDY");
+ for (i = 8; i < 16; ++i)
+ gpio_request(i, "ACS5K Unused");
+
+ gpio_request(3, "ACS5K CAN Control");
+ gpio_request(6, "ACS5K Heartbeat");
+ gpio_direction_output(3, 1); /* Default CAN_RESET high */
+ gpio_direction_output(6, 0); /* Default KS8695_ACTIVE low */
+ gpio_export(3, 0); /* export CAN_RESET as output only */
+ gpio_export(6, 0); /* export KS8695_ACTIVE as output only */
+}
+
+static void __init acs5k_init(void)
+{
+ acs5k_init_gpio();
+
+ /* Network device */
+ ks8695_add_device_lan(); /* eth0 = LAN */
+ ks8695_add_device_wan(); /* ethX = WAN */
+
+ /* NOR devices */
+ acs5k_register_nor();
+
+ /* I2C bus */
+ acs5k_i2c_init();
+}
+
+MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
+ /* Maintainer: Simtec Electronics. */
+ .boot_params = KS8695_SDRAM_PA + 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = acs5k_init,
+ .timer = &ks8695_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c
new file mode 100644
index 00000000..ada92b6b
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-dsm320.c
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/mach-ks8695/board-dsm320.c
+ *
+ * DSM-320 D-Link Wireless Media Player, board support.
+ *
+ * Copyright 2008 Simtec Electronics
+ * Daniel Silverstone <dsilvers@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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/devices.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PCI
+static int dsm320_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch (slot) {
+ case 0:
+ /* PCI-AHB bridge? */
+ return KS8695_IRQ_EXTERN0;
+ case 18:
+ /* Mini PCI slot */
+ return KS8695_IRQ_EXTERN2;
+ case 20:
+ /* RealMAGIC chip */
+ return KS8695_IRQ_EXTERN0;
+ }
+ BUG();
+}
+
+static struct ks8695_pci_cfg __initdata dsm320_pci = {
+ .mode = KS8695_MODE_MINIPCI,
+ .map_irq = dsm320_pci_map_irq,
+};
+
+static void __init dsm320_register_pci(void)
+{
+ /* Initialise the GPIO lines for interrupt mode */
+ /* RealMAGIC */
+ ks8695_gpio_interrupt(KS8695_GPIO_0, IRQ_TYPE_LEVEL_LOW);
+ /* MiniPCI Slot */
+ ks8695_gpio_interrupt(KS8695_GPIO_2, IRQ_TYPE_LEVEL_LOW);
+
+ ks8695_init_pci(&dsm320_pci);
+}
+
+#else
+static inline void __init dsm320_register_pci(void) { }
+#endif
+
+static struct physmap_flash_data dsm320_nor_pdata = {
+ .width = 4,
+ .nr_parts = 0,
+};
+
+static struct resource dsm320_nor_resource[] = {
+ [0] = {
+ .start = SZ_32M, /* We expect the bootloader to map
+ * the flash here.
+ */
+ .end = SZ_32M + SZ_4M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device dsm320_device_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dsm320_nor_resource),
+ .resource = dsm320_nor_resource,
+ .dev = {
+ .platform_data = &dsm320_nor_pdata,
+ },
+};
+
+void __init dsm320_register_nor(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dsm320_device_nor);
+ if (ret < 0)
+ printk(KERN_ERR "failed to register physmap-flash device\n");
+}
+
+static void __init dsm320_init(void)
+{
+ /* GPIO registration */
+ ks8695_register_gpios();
+
+ /* PCI registration */
+ dsm320_register_pci();
+
+ /* Network device */
+ ks8695_add_device_lan(); /* eth0 = LAN */
+
+ /* NOR devices */
+ dsm320_register_nor();
+}
+
+MACHINE_START(DSM320, "D-Link DSM-320 Wireless Media Player")
+ /* Maintainer: Simtec Electronics. */
+ .boot_params = KS8695_SDRAM_PA + 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = dsm320_init,
+ .timer = &ks8695_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
new file mode 100644
index 00000000..c7ad09bd
--- /dev/null
+++ b/arch/arm/mach-ks8695/board-micrel.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-ks8695/board-micrel.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/gpio.h>
+#include <mach/devices.h>
+
+#include "generic.h"
+
+#ifdef CONFIG_PCI
+static int micrel_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return KS8695_IRQ_EXTERN0;
+}
+
+static struct ks8695_pci_cfg __initdata micrel_pci = {
+ .mode = KS8695_MODE_MINIPCI,
+ .map_irq = micrel_pci_map_irq,
+};
+#endif
+
+
+static void __init micrel_init(void)
+{
+ printk(KERN_INFO "Micrel KS8695 Development Board initializing\n");
+
+ ks8695_register_gpios();
+
+#ifdef CONFIG_PCI
+ ks8695_init_pci(&micrel_pci);
+#endif
+
+ /* Add devices */
+ ks8695_add_device_wan(); /* eth0 = WAN */
+ ks8695_add_device_lan(); /* eth1 = LAN */
+}
+
+MACHINE_START(KS8695, "KS8695 Centaur Development Board")
+ /* Maintainer: Micrel Semiconductor Inc. */
+ .boot_params = KS8695_SDRAM_PA + 0x100,
+ .map_io = ks8695_map_io,
+ .init_irq = ks8695_init_irq,
+ .init_machine = micrel_init,
+ .timer = &ks8695_timer,
+MACHINE_END
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
new file mode 100644
index 00000000..7f3f2405
--- /dev/null
+++ b/arch/arm/mach-ks8695/cpu.c
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/mach-ks8695/cpu.c
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-misc.h>
+
+
+static struct __initdata map_desc ks8695_io_desc[] = {
+ {
+ .virtual = KS8695_IO_VA,
+ .pfn = __phys_to_pfn(KS8695_IO_PA),
+ .length = KS8695_IO_SIZE,
+ .type = MT_DEVICE,
+ }
+};
+
+static void __init ks8695_processor_info(void)
+{
+ unsigned long id, rev;
+
+ id = __raw_readl(KS8695_MISC_VA + KS8695_DID);
+ rev = __raw_readl(KS8695_MISC_VA + KS8695_RID);
+
+ printk("KS8695 ID=%04lx SubID=%02lx Revision=%02lx\n", (id & DID_ID), (rev & RID_SUBID), (rev & RID_REVISION));
+}
+
+static unsigned int sysclk[8] = { 125000000, 100000000, 62500000, 50000000, 41700000, 33300000, 31300000, 25000000 };
+static unsigned int cpuclk[8] = { 166000000, 166000000, 83000000, 83000000, 55300000, 55300000, 41500000, 41500000 };
+
+static void __init ks8695_clock_info(void)
+{
+ unsigned int scdc = __raw_readl(KS8695_SYS_VA + KS8695_CLKCON) & CLKCON_SCDC;
+
+ printk("Clocks: System %u MHz, CPU %u MHz\n",
+ sysclk[scdc] / 1000000, cpuclk[scdc] / 1000000);
+}
+
+void __init ks8695_map_io(void)
+{
+ iotable_init(ks8695_io_desc, ARRAY_SIZE(ks8695_io_desc));
+
+ ks8695_processor_info();
+ ks8695_clock_info();
+}
diff --git a/arch/arm/mach-ks8695/devices.c b/arch/arm/mach-ks8695/devices.c
new file mode 100644
index 00000000..b89fb6d4
--- /dev/null
+++ b/arch/arm/mach-ks8695/devices.c
@@ -0,0 +1,217 @@
+/*
+ * arch/arm/mach-ks8695/devices.c
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/regs-wan.h>
+#include <mach/regs-lan.h>
+#include <mach/regs-hpna.h>
+#include <mach/regs-switch.h>
+#include <mach/regs-misc.h>
+
+
+/* --------------------------------------------------------------------
+ * Ethernet
+ * -------------------------------------------------------------------- */
+
+static u64 eth_dmamask = 0xffffffffUL;
+
+static struct resource ks8695_wan_resources[] = {
+ [0] = {
+ .start = KS8695_WAN_PA,
+ .end = KS8695_WAN_PA + 0x00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "WAN RX",
+ .start = KS8695_IRQ_WAN_RX_STATUS,
+ .end = KS8695_IRQ_WAN_RX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "WAN TX",
+ .start = KS8695_IRQ_WAN_TX_STATUS,
+ .end = KS8695_IRQ_WAN_TX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = "WAN Link",
+ .start = KS8695_IRQ_WAN_LINK,
+ .end = KS8695_IRQ_WAN_LINK,
+ .flags = IORESOURCE_IRQ,
+ },
+ [4] = {
+ .name = "WAN PHY",
+ .start = KS8695_MISC_PA,
+ .end = KS8695_MISC_PA + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ks8695_wan_device = {
+ .name = "ks8695_ether",
+ .id = 0,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = ks8695_wan_resources,
+ .num_resources = ARRAY_SIZE(ks8695_wan_resources),
+};
+
+
+static struct resource ks8695_lan_resources[] = {
+ [0] = {
+ .start = KS8695_LAN_PA,
+ .end = KS8695_LAN_PA + 0x00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "LAN RX",
+ .start = KS8695_IRQ_LAN_RX_STATUS,
+ .end = KS8695_IRQ_LAN_RX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "LAN TX",
+ .start = KS8695_IRQ_LAN_TX_STATUS,
+ .end = KS8695_IRQ_LAN_TX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = "LAN SWITCH",
+ .start = KS8695_SWITCH_PA,
+ .end = KS8695_SWITCH_PA + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ks8695_lan_device = {
+ .name = "ks8695_ether",
+ .id = 1,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = ks8695_lan_resources,
+ .num_resources = ARRAY_SIZE(ks8695_lan_resources),
+};
+
+
+static struct resource ks8695_hpna_resources[] = {
+ [0] = {
+ .start = KS8695_HPNA_PA,
+ .end = KS8695_HPNA_PA + 0x00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "HPNA RX",
+ .start = KS8695_IRQ_HPNA_RX_STATUS,
+ .end = KS8695_IRQ_HPNA_RX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "HPNA TX",
+ .start = KS8695_IRQ_HPNA_TX_STATUS,
+ .end = KS8695_IRQ_HPNA_TX_STATUS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ks8695_hpna_device = {
+ .name = "ks8695_ether",
+ .id = 2,
+ .dev = {
+ .dma_mask = &eth_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = ks8695_hpna_resources,
+ .num_resources = ARRAY_SIZE(ks8695_hpna_resources),
+};
+
+void __init ks8695_add_device_wan(void)
+{
+ platform_device_register(&ks8695_wan_device);
+}
+
+void __init ks8695_add_device_lan(void)
+{
+ platform_device_register(&ks8695_lan_device);
+}
+
+void __init ks8696_add_device_hpna(void)
+{
+ platform_device_register(&ks8695_hpna_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * Watchdog
+ * -------------------------------------------------------------------- */
+
+static struct platform_device ks8695_wdt_device = {
+ .name = "ks8695_wdt",
+ .id = -1,
+ .num_resources = 0,
+};
+
+static void __init ks8695_add_device_watchdog(void)
+{
+ platform_device_register(&ks8695_wdt_device);
+}
+
+
+/* --------------------------------------------------------------------
+ * LEDs
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_LEDS)
+short ks8695_leds_cpu = -1;
+short ks8695_leds_timer = -1;
+
+void __init ks8695_init_leds(u8 cpu_led, u8 timer_led)
+{
+ /* Enable GPIO to access the LEDs */
+ gpio_direction_output(cpu_led, 1);
+ gpio_direction_output(timer_led, 1);
+
+ ks8695_leds_cpu = cpu_led;
+ ks8695_leds_timer = timer_led;
+}
+#else
+void __init ks8695_init_leds(u8 cpu_led, u8 timer_led) {}
+#endif
+
+/* -------------------------------------------------------------------- */
+
+/*
+ * These devices are always present and don't need any board-specific
+ * setup.
+ */
+static int __init ks8695_add_standard_devices(void)
+{
+ ks8695_add_device_watchdog();
+ return 0;
+}
+
+arch_initcall(ks8695_add_standard_devices);
diff --git a/arch/arm/mach-ks8695/generic.h b/arch/arm/mach-ks8695/generic.h
new file mode 100644
index 00000000..2fbfab8d
--- /dev/null
+++ b/arch/arm/mach-ks8695/generic.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-ks8695/generic.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec 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.
+*/
+
+extern __init void ks8695_map_io(void);
+extern __init void ks8695_init_irq(void);
+extern struct sys_timer ks8695_timer;
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
new file mode 100644
index 00000000..31e45650
--- /dev/null
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -0,0 +1,319 @@
+/*
+ * arch/arm/mach-ks8695/gpio.c
+ *
+ * Copyright (C) 2006 Andrew Victor
+ * Updated to GPIOLIB, Copyright 2008 Simtec Electronics
+ * Daniel Silverstone <dsilvers@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/mm.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+/*
+ * Configure a GPIO line for either GPIO function, or its internal
+ * function (Interrupt, Timer, etc).
+ */
+static void ks8695_gpio_mode(unsigned int pin, short gpio)
+{
+ unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
+ unsigned long x, flags;
+
+ if (pin > KS8695_GPIO_5) /* only GPIO 0..5 have internal functions */
+ return;
+
+ local_irq_save(flags);
+
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
+ if (gpio) /* GPIO: set bit to 0 */
+ x &= ~enable[pin];
+ else /* Internal function: set bit to 1 */
+ x |= enable[pin];
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
+
+ local_irq_restore(flags);
+}
+
+
+static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+int ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
+{
+ unsigned long x, flags;
+
+ if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ /* set pin as input */
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+ x &= ~IOPM(pin);
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+ local_irq_restore(flags);
+
+ /* Set IRQ triggering type */
+ irq_set_irq_type(gpio_irq[pin], type);
+
+ /* enable interrupt mode */
+ ks8695_gpio_mode(pin, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(ks8695_gpio_interrupt);
+
+
+
+/* .... Generic GPIO interface .............................................. */
+
+/*
+ * Configure the GPIO line as an input.
+ */
+static int ks8695_gpio_direction_input(struct gpio_chip *gc, unsigned int pin)
+{
+ unsigned long x, flags;
+
+ if (pin > KS8695_GPIO_15)
+ return -EINVAL;
+
+ /* set pin to GPIO mode */
+ ks8695_gpio_mode(pin, 1);
+
+ local_irq_save(flags);
+
+ /* set pin as input */
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+ x &= ~IOPM(pin);
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+
+/*
+ * Configure the GPIO line as an output, with default state.
+ */
+static int ks8695_gpio_direction_output(struct gpio_chip *gc,
+ unsigned int pin, int state)
+{
+ unsigned long x, flags;
+
+ if (pin > KS8695_GPIO_15)
+ return -EINVAL;
+
+ /* set pin to GPIO mode */
+ ks8695_gpio_mode(pin, 1);
+
+ local_irq_save(flags);
+
+ /* set line state */
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+ if (state)
+ x |= IOPD(pin);
+ else
+ x &= ~IOPD(pin);
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
+
+ /* set pin as output */
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+ x |= IOPM(pin);
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+
+/*
+ * Set the state of an output GPIO line.
+ */
+static void ks8695_gpio_set_value(struct gpio_chip *gc,
+ unsigned int pin, int state)
+{
+ unsigned long x, flags;
+
+ if (pin > KS8695_GPIO_15)
+ return;
+
+ local_irq_save(flags);
+
+ /* set output line state */
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+ if (state)
+ x |= IOPD(pin);
+ else
+ x &= ~IOPD(pin);
+ __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
+
+ local_irq_restore(flags);
+}
+
+
+/*
+ * Read the state of a GPIO line.
+ */
+static int ks8695_gpio_get_value(struct gpio_chip *gc, unsigned int pin)
+{
+ unsigned long x;
+
+ if (pin > KS8695_GPIO_15)
+ return -EINVAL;
+
+ x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+ return (x & IOPD(pin)) != 0;
+}
+
+
+/*
+ * Map GPIO line to IRQ number.
+ */
+static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin)
+{
+ if (pin > KS8695_GPIO_3) /* only GPIO 0..3 can generate IRQ */
+ return -EINVAL;
+
+ return gpio_irq[pin];
+}
+
+/*
+ * Map IRQ number to GPIO line.
+ */
+int irq_to_gpio(unsigned int irq)
+{
+ if ((irq < KS8695_IRQ_EXTERN0) || (irq > KS8695_IRQ_EXTERN3))
+ return -EINVAL;
+
+ return (irq - KS8695_IRQ_EXTERN0);
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
+/* GPIOLIB interface */
+
+static struct gpio_chip ks8695_gpio_chip = {
+ .label = "KS8695",
+ .direction_input = ks8695_gpio_direction_input,
+ .direction_output = ks8695_gpio_direction_output,
+ .get = ks8695_gpio_get_value,
+ .set = ks8695_gpio_set_value,
+ .to_irq = ks8695_gpio_to_irq,
+ .base = 0,
+ .ngpio = 16,
+ .can_sleep = 0,
+};
+
+/* Register the GPIOs */
+void ks8695_register_gpios(void)
+{
+ if (gpiochip_add(&ks8695_gpio_chip))
+ printk(KERN_ERR "Unable to register core GPIOs\n");
+}
+
+/* .... Debug interface ..................................................... */
+
+#ifdef CONFIG_DEBUG_FS
+
+static int ks8695_gpio_show(struct seq_file *s, void *unused)
+{
+ unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
+ unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM };
+ unsigned long mode, ctrl, data;
+ int i;
+
+ mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
+ ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
+ data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
+
+ seq_printf(s, "Pin\tI/O\tFunction\tState\n\n");
+
+ for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) {
+ seq_printf(s, "%i:\t", i);
+
+ seq_printf(s, "%s\t", (mode & IOPM(i)) ? "Output" : "Input");
+
+ if (i <= KS8695_GPIO_3) {
+ if (ctrl & enable[i]) {
+ seq_printf(s, "EXT%i ", i);
+
+ switch ((ctrl & intmask[i]) >> (4 * i)) {
+ case IOPC_TM_LOW:
+ seq_printf(s, "(Low)"); break;
+ case IOPC_TM_HIGH:
+ seq_printf(s, "(High)"); break;
+ case IOPC_TM_RISING:
+ seq_printf(s, "(Rising)"); break;
+ case IOPC_TM_FALLING:
+ seq_printf(s, "(Falling)"); break;
+ case IOPC_TM_EDGE:
+ seq_printf(s, "(Edges)"); break;
+ }
+ }
+ else
+ seq_printf(s, "GPIO\t");
+ }
+ else if (i <= KS8695_GPIO_5) {
+ if (ctrl & enable[i])
+ seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4);
+ else
+ seq_printf(s, "GPIO\t");
+ }
+ else
+ seq_printf(s, "GPIO\t");
+
+ seq_printf(s, "\t");
+
+ seq_printf(s, "%i\n", (data & IOPD(i)) ? 1 : 0);
+ }
+ return 0;
+}
+
+static int ks8695_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ks8695_gpio_show, NULL);
+}
+
+static const struct file_operations ks8695_gpio_operations = {
+ .open = ks8695_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init ks8695_gpio_debugfs_init(void)
+{
+ /* /sys/kernel/debug/ks8695_gpio */
+ (void) debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL, &ks8695_gpio_operations);
+ return 0;
+}
+postcore_initcall(ks8695_gpio_debugfs_init);
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/debug-macro.S b/arch/arm/mach-ks8695/include/mach/debug-macro.S
new file mode 100644
index 00000000..bf516adf
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/debug-macro.S
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - Debug macros
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/regs-uart.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =KS8695_UART_PA @ physical base address
+ ldr \rv, =KS8695_UART_VA @ virtual base address
+ .endm
+
+ .macro senduart, rd, rx
+ str \rd, [\rx, #KS8695_URTH] @ Write to Transmit Holding Register
+ .endm
+
+ .macro busyuart, rd, rx
+1001: ldr \rd, [\rx, #KS8695_URLS] @ Read Line Status Register
+ tst \rd, #URLS_URTE @ Holding & Shift registers empty?
+ beq 1001b
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #KS8695_URLS] @ Read Line Status Register
+ tst \rd, #URLS_URTHRE @ Holding Register empty?
+ beq 1001b
+ .endm
diff --git a/arch/arm/mach-ks8695/include/mach/devices.h b/arch/arm/mach-ks8695/include/mach/devices.h
new file mode 100644
index 00000000..2744fecb
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/devices.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/devices.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This program is free software; you can 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_DEVICES_H
+#define __ASM_ARCH_DEVICES_H
+
+#include <linux/pci.h>
+
+ /* Ethernet */
+extern void __init ks8695_add_device_wan(void);
+extern void __init ks8695_add_device_lan(void);
+extern void __init ks8695_add_device_hpna(void);
+
+ /* LEDs */
+extern short ks8695_leds_cpu;
+extern short ks8695_leds_timer;
+extern void __init ks8695_init_leds(u8 cpu_led, u8 timer_led);
+
+ /* PCI */
+#define KS8695_MODE_PCI 0
+#define KS8695_MODE_MINIPCI 1
+#define KS8695_MODE_CARDBUS 2
+
+struct ks8695_pci_cfg {
+ short mode;
+ int (*map_irq)(struct pci_dev *, u8, u8);
+};
+extern __init void ks8695_init_pci(struct ks8695_pci_cfg *);
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/entry-macro.S b/arch/arm/mach-ks8695/include/mach/entry-macro.S
new file mode 100644
index 00000000..b4fe0c11
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/entry-macro.S
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * Low-level IRQ helper macros for KS8695
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =KS8695_IRQ_VA @ Base address of interrupt controller
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #KS8695_INTMS] @ Mask Status register
+
+ teq \irqstat, #0
+ beq 1001f
+
+ mov \irqnr, #0
+
+ tst \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tst \irqstat, #0x0f
+ moveq \irqstat, \irqstat, lsr #4
+ addeq \irqnr, \irqnr, #4
+ tst \irqstat, #0x03
+ moveq \irqstat, \irqstat, lsr #2
+ addeq \irqnr, \irqnr, #2
+ tst \irqstat, #0x01
+ addeqs \irqnr, \irqnr, #1
+1001:
+ .endm
diff --git a/arch/arm/mach-ks8695/include/mach/gpio.h b/arch/arm/mach-ks8695/include/mach/gpio.h
new file mode 100644
index 00000000..86312d47
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/gpio.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/gpio.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This program is free software; you can 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_
+
+#include <linux/kernel.h>
+
+#define KS8695_GPIO_0 0
+#define KS8695_GPIO_1 1
+#define KS8695_GPIO_2 2
+#define KS8695_GPIO_3 3
+#define KS8695_GPIO_4 4
+#define KS8695_GPIO_5 5
+#define KS8695_GPIO_6 6
+#define KS8695_GPIO_7 7
+#define KS8695_GPIO_8 8
+#define KS8695_GPIO_9 9
+#define KS8695_GPIO_10 10
+#define KS8695_GPIO_11 11
+#define KS8695_GPIO_12 12
+#define KS8695_GPIO_13 13
+#define KS8695_GPIO_14 14
+#define KS8695_GPIO_15 15
+
+/*
+ * Configure GPIO pin as external interrupt source.
+ */
+extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
+
+/*
+ * Map IRQ number to GPIO line.
+ */
+extern int irq_to_gpio(unsigned int irq);
+
+#include <asm-generic/gpio.h>
+
+/* If it turns out that we need to optimise GPIO access for the
+ * Micrel's GPIOs, then these can be changed to check their argument
+ * directly as static inlines. However for now it's probably not
+ * worthwhile.
+ */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_to_irq __gpio_to_irq
+
+/* Register the GPIOs */
+extern void ks8695_register_gpios(void);
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/hardware.h b/arch/arm/mach-ks8695/include/mach/hardware.h
new file mode 100644
index 00000000..e0f911d9
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/hardware.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/hardware.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - 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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/*
+ * Clocks are derived from MCLK, which is 25Mhz
+ */
+#define KS8695_CLOCK_RATE 25000000
+
+/*
+ * Physical RAM address.
+ */
+#define KS8695_SDRAM_PA 0x00000000
+
+
+/*
+ * We map an entire MiB with the System Configuration Registers in even
+ * though only 64KiB is needed. This makes it easier for use with the
+ * head debug code as the initial MMU setup only deals in L1 sections.
+ */
+#define KS8695_IO_PA 0x03F00000
+#define KS8695_IO_VA 0xF0000000
+#define KS8695_IO_SIZE SZ_1M
+
+#define KS8695_PCIMEM_PA 0x60000000
+#define KS8695_PCIMEM_SIZE SZ_512M
+
+#define KS8695_PCIIO_PA 0x80000000
+#define KS8695_PCIIO_SIZE SZ_64K
+
+
+/*
+ * PCI support
+ */
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0
+#define PCIBIOS_MIN_MEM 0
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/io.h b/arch/arm/mach-ks8695/include/mach/io.h
new file mode 100644
index 00000000..a7a63ac3
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/io.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/io.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/irqs.h b/arch/arm/mach-ks8695/include/mach/irqs.h
new file mode 100644
index 00000000..86fc9e6c
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/irqs.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/irqs.h
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+
+#define NR_IRQS 32
+
+/*
+ * IRQ definitions
+ */
+#define KS8695_IRQ_COMM_RX 0
+#define KS8695_IRQ_COMM_TX 1
+#define KS8695_IRQ_EXTERN0 2
+#define KS8695_IRQ_EXTERN1 3
+#define KS8695_IRQ_EXTERN2 4
+#define KS8695_IRQ_EXTERN3 5
+#define KS8695_IRQ_TIMER0 6
+#define KS8695_IRQ_TIMER1 7
+#define KS8695_IRQ_UART_TX 8
+#define KS8695_IRQ_UART_RX 9
+#define KS8695_IRQ_UART_LINE_STATUS 10
+#define KS8695_IRQ_UART_MODEM_STATUS 11
+#define KS8695_IRQ_LAN_RX_STOP 12
+#define KS8695_IRQ_LAN_TX_STOP 13
+#define KS8695_IRQ_LAN_RX_BUF 14
+#define KS8695_IRQ_LAN_TX_BUF 15
+#define KS8695_IRQ_LAN_RX_STATUS 16
+#define KS8695_IRQ_LAN_TX_STATUS 17
+#define KS8695_IRQ_HPNA_RX_STOP 18
+#define KS8695_IRQ_HPNA_TX_STOP 19
+#define KS8695_IRQ_HPNA_RX_BUF 20
+#define KS8695_IRQ_HPNA_TX_BUF 21
+#define KS8695_IRQ_HPNA_RX_STATUS 22
+#define KS8695_IRQ_HPNA_TX_STATUS 23
+#define KS8695_IRQ_BUS_ERROR 24
+#define KS8695_IRQ_WAN_RX_STOP 25
+#define KS8695_IRQ_WAN_TX_STOP 26
+#define KS8695_IRQ_WAN_RX_BUF 27
+#define KS8695_IRQ_WAN_TX_BUF 28
+#define KS8695_IRQ_WAN_RX_STATUS 29
+#define KS8695_IRQ_WAN_TX_STATUS 30
+#define KS8695_IRQ_WAN_LINK 31
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
new file mode 100644
index 00000000..f7e1b9bc
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/memory.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 Memory definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <mach/hardware.h>
+
+/*
+ * Physical SRAM offset.
+ */
+#define PLAT_PHYS_OFFSET KS8695_SDRAM_PA
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_PCI
+
+/* PCI mappings */
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET + KS8695_PCIMEM_PA)
+#define __bus_to_virt(x) ((x) - KS8695_PCIMEM_PA + PAGE_OFFSET)
+
+/* Platform-bus mapping */
+extern struct bus_type platform_bus_type;
+#define is_lbus_device(dev) (dev && dev->bus == &platform_bus_type)
+#define __arch_dma_to_virt(dev, x) ({ (void *) (is_lbus_device(dev) ? \
+ __phys_to_virt(x) : __bus_to_virt(x)); })
+#define __arch_virt_to_dma(dev, x) ({ is_lbus_device(dev) ? \
+ (dma_addr_t)__virt_to_phys(x) : (dma_addr_t)__virt_to_bus(x); })
+#define __arch_pfn_to_dma(dev, pfn) \
+ ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
+ if (!is_lbus_device(dev)) \
+ __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
+ __dma; })
+
+#define __arch_dma_to_pfn(dev, x) \
+ ({ dma_addr_t __dma = x; \
+ if (!is_lbus_device(dev)) \
+ __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \
+ __phys_to_pfn(__dma); \
+ })
+
+#endif
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-gpio.h b/arch/arm/mach-ks8695/include/mach/regs-gpio.h
new file mode 100644
index 00000000..90614a7d
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-gpio.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-gpio.h
+ *
+ * Copyright (C) 2007 Andrew Victor
+ *
+ * KS8695 - GPIO control registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_GPIO_H
+#define KS8695_GPIO_H
+
+#define KS8695_GPIO_OFFSET (0xF0000 + 0xE600)
+#define KS8695_GPIO_VA (KS8695_IO_VA + KS8695_GPIO_OFFSET)
+#define KS8695_GPIO_PA (KS8695_IO_PA + KS8695_GPIO_OFFSET)
+
+
+#define KS8695_IOPM (0x00) /* I/O Port Mode Register */
+#define KS8695_IOPC (0x04) /* I/O Port Control Register */
+#define KS8695_IOPD (0x08) /* I/O Port Data Register */
+
+
+/* Port Mode Register */
+#define IOPM(x) (1 << (x)) /* Mode for GPIO Pin x */
+
+/* Port Control Register */
+#define IOPC_IOTIM1EN (1 << 17) /* GPIO Pin for Timer1 Enable */
+#define IOPC_IOTIM0EN (1 << 16) /* GPIO Pin for Timer0 Enable */
+#define IOPC_IOEINT3EN (1 << 15) /* GPIO Pin for External/Soft Interrupt 3 Enable */
+#define IOPC_IOEINT3TM (7 << 12) /* GPIO Pin for External/Soft Interrupt 3 Trigger Mode */
+#define IOPC_IOEINT3_MODE(x) ((x) << 12)
+#define IOPC_IOEINT2EN (1 << 11) /* GPIO Pin for External/Soft Interrupt 2 Enable */
+#define IOPC_IOEINT2TM (7 << 8) /* GPIO Pin for External/Soft Interrupt 2 Trigger Mode */
+#define IOPC_IOEINT2_MODE(x) ((x) << 8)
+#define IOPC_IOEINT1EN (1 << 7) /* GPIO Pin for External/Soft Interrupt 1 Enable */
+#define IOPC_IOEINT1TM (7 << 4) /* GPIO Pin for External/Soft Interrupt 1 Trigger Mode */
+#define IOPC_IOEINT1_MODE(x) ((x) << 4)
+#define IOPC_IOEINT0EN (1 << 3) /* GPIO Pin for External/Soft Interrupt 0 Enable */
+#define IOPC_IOEINT0TM (7 << 0) /* GPIO Pin for External/Soft Interrupt 0 Trigger Mode */
+#define IOPC_IOEINT0_MODE(x) ((x) << 0)
+
+ /* Trigger Modes */
+#define IOPC_TM_LOW (0) /* Level Detection (Active Low) */
+#define IOPC_TM_HIGH (1) /* Level Detection (Active High) */
+#define IOPC_TM_RISING (2) /* Rising Edge Detection */
+#define IOPC_TM_FALLING (4) /* Falling Edge Detection */
+#define IOPC_TM_EDGE (6) /* Both Edge Detection */
+
+/* Port Data Register */
+#define IOPD(x) (1 << (x)) /* Signal Level of GPIO Pin x */
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-hpna.h b/arch/arm/mach-ks8695/include/mach/regs-hpna.h
new file mode 100644
index 00000000..815ce5c2
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-hpna.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-wan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - HPNA Registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_HPNA_H
+#define KS8695_HPNA_H
+
+#define KS8695_HPNA_OFFSET (0xF0000 + 0xA000)
+#define KS8695_HPNA_VA (KS8695_IO_VA + KS8695_HPNA_OFFSET)
+#define KS8695_HPNA_PA (KS8695_IO_PA + KS8695_HPNA_OFFSET)
+
+
+/*
+ * HPNA registers
+ */
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-irq.h b/arch/arm/mach-ks8695/include/mach/regs-irq.h
new file mode 100644
index 00000000..352b7e87
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-irq.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-irq.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - IRQ registers and bit definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_IRQ_H
+#define KS8695_IRQ_H
+
+#define KS8695_IRQ_OFFSET (0xF0000 + 0xE200)
+#define KS8695_IRQ_VA (KS8695_IO_VA + KS8695_IRQ_OFFSET)
+#define KS8695_IRQ_PA (KS8695_IO_PA + KS8695_IRQ_OFFSET)
+
+
+/*
+ * Interrupt Controller registers
+ */
+#define KS8695_INTMC (0x00) /* Mode Control Register */
+#define KS8695_INTEN (0x04) /* Interrupt Enable Register */
+#define KS8695_INTST (0x08) /* Interrupt Status Register */
+#define KS8695_INTPW (0x0c) /* Interrupt Priority (WAN MAC) */
+#define KS8695_INTPH (0x10) /* Interrupt Priority (HPNA) [KS8695 only] */
+#define KS8695_INTPL (0x14) /* Interrupt Priority (LAN MAC) */
+#define KS8695_INTPT (0x18) /* Interrupt Priority (Timer) */
+#define KS8695_INTPU (0x1c) /* Interrupt Priority (UART) */
+#define KS8695_INTPE (0x20) /* Interrupt Priority (External Interrupt) */
+#define KS8695_INTPC (0x24) /* Interrupt Priority (Communications Channel) */
+#define KS8695_INTPBE (0x28) /* Interrupt Priority (Bus Error Response) */
+#define KS8695_INTMS (0x2c) /* Interrupt Mask Status Register */
+#define KS8695_INTHPF (0x30) /* Interrupt Pending Highest Priority (FIQ) */
+#define KS8695_INTHPI (0x34) /* Interrupt Pending Highest Priority (IRQ) */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-lan.h b/arch/arm/mach-ks8695/include/mach/regs-lan.h
new file mode 100644
index 00000000..82c5f379
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-lan.h
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-lan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - LAN Registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_LAN_H
+#define KS8695_LAN_H
+
+#define KS8695_LAN_OFFSET (0xF0000 + 0x8000)
+#define KS8695_LAN_VA (KS8695_IO_VA + KS8695_LAN_OFFSET)
+#define KS8695_LAN_PA (KS8695_IO_PA + KS8695_LAN_OFFSET)
+
+
+/*
+ * LAN registers
+ */
+#define KS8695_LMDTXC (0x00) /* DMA Transmit Control */
+#define KS8695_LMDRXC (0x04) /* DMA Receive Control */
+#define KS8695_LMDTSC (0x08) /* DMA Transmit Start Command */
+#define KS8695_LMDRSC (0x0c) /* DMA Receive Start Command */
+#define KS8695_LTDLB (0x10) /* Transmit Descriptor List Base Address */
+#define KS8695_LRDLB (0x14) /* Receive Descriptor List Base Address */
+#define KS8695_LMAL (0x18) /* MAC Station Address Low */
+#define KS8695_LMAH (0x1c) /* MAC Station Address High */
+#define KS8695_LMAAL(n) (0x80 + ((n)*8)) /* MAC Additional Station Address (0..15) Low */
+#define KS8695_LMAAH(n) (0x84 + ((n)*8)) /* MAC Additional Station Address (0..15) High */
+
+
+/* DMA Transmit Control Register */
+#define LMDTXC_LMTRST (1 << 31) /* Soft Reset */
+#define LMDTXC_LMTBS (0x3f << 24) /* Transmit Burst Size */
+#define LMDTXC_LMTUCG (1 << 18) /* Transmit UDP Checksum Generate */
+#define LMDTXC_LMTTCG (1 << 17) /* Transmit TCP Checksum Generate */
+#define LMDTXC_LMTICG (1 << 16) /* Transmit IP Checksum Generate */
+#define LMDTXC_LMTFCE (1 << 9) /* Transmit Flow Control Enable */
+#define LMDTXC_LMTLB (1 << 8) /* Loopback mode */
+#define LMDTXC_LMTEP (1 << 2) /* Transmit Enable Padding */
+#define LMDTXC_LMTAC (1 << 1) /* Transmit Add CRC */
+#define LMDTXC_LMTE (1 << 0) /* TX Enable */
+
+/* DMA Receive Control Register */
+#define LMDRXC_LMRBS (0x3f << 24) /* Receive Burst Size */
+#define LMDRXC_LMRUCC (1 << 18) /* Receive UDP Checksum check */
+#define LMDRXC_LMRTCG (1 << 17) /* Receive TCP Checksum check */
+#define LMDRXC_LMRICG (1 << 16) /* Receive IP Checksum check */
+#define LMDRXC_LMRFCE (1 << 9) /* Receive Flow Control Enable */
+#define LMDRXC_LMRB (1 << 6) /* Receive Broadcast */
+#define LMDRXC_LMRM (1 << 5) /* Receive Multicast */
+#define LMDRXC_LMRU (1 << 4) /* Receive Unicast */
+#define LMDRXC_LMRERR (1 << 3) /* Receive Error Frame */
+#define LMDRXC_LMRA (1 << 2) /* Receive All */
+#define LMDRXC_LMRE (1 << 1) /* RX Enable */
+
+/* Additional Station Address High */
+#define LMAAH_E (1 << 31) /* Address Enabled */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-mem.h b/arch/arm/mach-ks8695/include/mach/regs-mem.h
new file mode 100644
index 00000000..55806bc6
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-mem.h
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-mem.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - Memory Controller registers and bit definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_MEM_H
+#define KS8695_MEM_H
+
+#define KS8695_MEM_OFFSET (0xF0000 + 0x4000)
+#define KS8695_MEM_VA (KS8695_IO_VA + KS8695_MEM_OFFSET)
+#define KS8695_MEM_PA (KS8695_IO_PA + KS8695_MEM_OFFSET)
+
+
+/*
+ * Memory Controller Registers
+ */
+#define KS8695_EXTACON0 (0x00) /* External I/O 0 Access Control */
+#define KS8695_EXTACON1 (0x04) /* External I/O 1 Access Control */
+#define KS8695_EXTACON2 (0x08) /* External I/O 2 Access Control */
+#define KS8695_ROMCON0 (0x10) /* ROM/SRAM/Flash 1 Control Register */
+#define KS8695_ROMCON1 (0x14) /* ROM/SRAM/Flash 2 Control Register */
+#define KS8695_ERGCON (0x20) /* External I/O and ROM/SRAM/Flash General Register */
+#define KS8695_SDCON0 (0x30) /* SDRAM Control Register 0 */
+#define KS8695_SDCON1 (0x34) /* SDRAM Control Register 1 */
+#define KS8695_SDGCON (0x38) /* SDRAM General Control */
+#define KS8695_SDBCON (0x3c) /* SDRAM Buffer Control */
+#define KS8695_REFTIM (0x40) /* SDRAM Refresh Timer */
+
+
+/* External I/O Access Control Registers */
+#define EXTACON_EBNPTR (0x3ff << 22) /* Last Address Pointer */
+#define EXTACON_EBBPTR (0x3ff << 12) /* Base Pointer */
+#define EXTACON_EBTACT (7 << 9) /* Write Enable/Output Enable Active Time */
+#define EXTACON_EBTCOH (7 << 6) /* Chip Select Hold Time */
+#define EXTACON_EBTACS (7 << 3) /* Address Setup Time before ECSN */
+#define EXTACON_EBTCOS (7 << 0) /* Chip Select Time before OEN */
+
+/* ROM/SRAM/Flash Control Register */
+#define ROMCON_RBNPTR (0x3ff << 22) /* Next Pointer */
+#define ROMCON_RBBPTR (0x3ff << 12) /* Base Pointer */
+#define ROMCON_RBTACC (7 << 4) /* Access Cycle Time */
+#define ROMCON_RBTPA (3 << 2) /* Page Address Access Time */
+#define ROMCON_PMC (3 << 0) /* Page Mode Configuration */
+#define PMC_NORMAL (0 << 0)
+#define PMC_4WORD (1 << 0)
+#define PMC_8WORD (2 << 0)
+#define PMC_16WORD (3 << 0)
+
+/* External I/O and ROM/SRAM/Flash General Register */
+#define ERGCON_TMULT (3 << 28) /* Time Multiplier */
+#define ERGCON_DSX2 (3 << 20) /* Data Width (External I/O Bank 2) */
+#define ERGCON_DSX1 (3 << 18) /* Data Width (External I/O Bank 1) */
+#define ERGCON_DSX0 (3 << 16) /* Data Width (External I/O Bank 0) */
+#define ERGCON_DSR1 (3 << 2) /* Data Width (ROM/SRAM/Flash Bank 1) */
+#define ERGCON_DSR0 (3 << 0) /* Data Width (ROM/SRAM/Flash Bank 0) */
+
+/* SDRAM Control Register */
+#define SDCON_DBNPTR (0x3ff << 22) /* Last Address Pointer */
+#define SDCON_DBBPTR (0x3ff << 12) /* Base Pointer */
+#define SDCON_DBCAB (3 << 8) /* Column Address Bits */
+#define SDCON_DBBNUM (1 << 3) /* Number of Banks */
+#define SDCON_DBDBW (3 << 1) /* Data Bus Width */
+
+/* SDRAM General Control Register */
+#define SDGCON_SDTRC (3 << 2) /* RAS to CAS latency */
+#define SDGCON_SDCAS (3 << 0) /* CAS latency */
+
+/* SDRAM Buffer Control Register */
+#define SDBCON_SDESTA (1 << 31) /* SDRAM Engine Status */
+#define SDBCON_RBUFBDIS (1 << 24) /* Read Buffer Burst Enable */
+#define SDBCON_WFIFOEN (1 << 23) /* Write FIFO Enable */
+#define SDBCON_RBUFEN (1 << 22) /* Read Buffer Enable */
+#define SDBCON_FLUSHWFIFO (1 << 21) /* Flush Write FIFO */
+#define SDBCON_RBUFINV (1 << 20) /* Read Buffer Invalidate */
+#define SDBCON_SDINI (3 << 16) /* SDRAM Initialization Control */
+#define SDBCON_SDMODE (0x3fff << 0) /* SDRAM Mode Register Value Program */
+
+/* SDRAM Refresh Timer Register */
+#define REFTIM_REFTIM (0xffff << 0) /* Refresh Timer Value */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-misc.h b/arch/arm/mach-ks8695/include/mach/regs-misc.h
new file mode 100644
index 00000000..2740c524
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-misc.h
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-misc.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - Miscellaneous Registers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_MISC_H
+#define KS8695_MISC_H
+
+#define KS8695_MISC_OFFSET (0xF0000 + 0xEA00)
+#define KS8695_MISC_VA (KS8695_IO_VA + KS8695_MISC_OFFSET)
+#define KS8695_MISC_PA (KS8695_IO_PA + KS8695_MISC_OFFSET)
+
+
+/*
+ * Miscellaneous registers
+ */
+#define KS8695_DID (0x00) /* Device ID */
+#define KS8695_RID (0x04) /* Revision ID */
+#define KS8695_HMC (0x08) /* HPNA Miscellaneous Control [KS8695 only] */
+#define KS8695_WMC (0x0c) /* WAN Miscellaneous Control */
+#define KS8695_WPPM (0x10) /* WAN PHY Power Management */
+#define KS8695_PPS (0x1c) /* PHY PowerSave */
+
+/* Device ID Register */
+#define DID_ID (0xffff << 0) /* Device ID */
+
+/* Revision ID Register */
+#define RID_SUBID (0xf << 4) /* Sub-Device ID */
+#define RID_REVISION (0xf << 0) /* Revision ID */
+
+/* HPNA Miscellaneous Control Register */
+#define HMC_HSS (1 << 1) /* Speed */
+#define HMC_HDS (1 << 0) /* Duplex */
+
+/* WAN Miscellaneous Control Register */
+#define WMC_WANC (1 << 30) /* Auto-negotiation complete */
+#define WMC_WANR (1 << 29) /* Auto-negotiation restart */
+#define WMC_WANAP (1 << 28) /* Advertise Pause */
+#define WMC_WANA100F (1 << 27) /* Advertise 100 FDX */
+#define WMC_WANA100H (1 << 26) /* Advertise 100 HDX */
+#define WMC_WANA10F (1 << 25) /* Advertise 10 FDX */
+#define WMC_WANA10H (1 << 24) /* Advertise 10 HDX */
+#define WMC_WLS (1 << 23) /* Link status */
+#define WMC_WDS (1 << 22) /* Duplex status */
+#define WMC_WSS (1 << 21) /* Speed status */
+#define WMC_WLPP (1 << 20) /* Link Partner Pause */
+#define WMC_WLP100F (1 << 19) /* Link Partner 100 FDX */
+#define WMC_WLP100H (1 << 18) /* Link Partner 100 HDX */
+#define WMC_WLP10F (1 << 17) /* Link Partner 10 FDX */
+#define WMC_WLP10H (1 << 16) /* Link Partner 10 HDX */
+#define WMC_WAND (1 << 15) /* Auto-negotiation disable */
+#define WMC_WANF100 (1 << 14) /* Force 100 */
+#define WMC_WANFF (1 << 13) /* Force FDX */
+#define WMC_WLED1S (7 << 4) /* LED1 Select */
+#define WLED1S_SPEED (0 << 4)
+#define WLED1S_LINK (1 << 4)
+#define WLED1S_DUPLEX (2 << 4)
+#define WLED1S_COLLISION (3 << 4)
+#define WLED1S_ACTIVITY (4 << 4)
+#define WLED1S_FDX_COLLISION (5 << 4)
+#define WLED1S_LINK_ACTIVITY (6 << 4)
+#define WMC_WLED0S (7 << 0) /* LED0 Select */
+#define WLED0S_SPEED (0 << 0)
+#define WLED0S_LINK (1 << 0)
+#define WLED0S_DUPLEX (2 << 0)
+#define WLED0S_COLLISION (3 << 0)
+#define WLED0S_ACTIVITY (4 << 0)
+#define WLED0S_FDX_COLLISION (5 << 0)
+#define WLED0S_LINK_ACTIVITY (6 << 0)
+
+/* WAN PHY Power Management Register */
+#define WPPM_WLPBK (1 << 14) /* Local Loopback */
+#define WPPM_WRLPKB (1 << 13) /* Remove Loopback */
+#define WPPM_WPI (1 << 12) /* PHY isolate */
+#define WPPM_WFL (1 << 10) /* Force link */
+#define WPPM_MDIXS (1 << 9) /* MDIX Status */
+#define WPPM_FEF (1 << 8) /* Far End Fault */
+#define WPPM_AMDIXP (1 << 7) /* Auto MDIX Parameter */
+#define WPPM_TXDIS (1 << 6) /* Disable transmitter */
+#define WPPM_DFEF (1 << 5) /* Disable Far End Fault */
+#define WPPM_PD (1 << 4) /* Power Down */
+#define WPPM_DMDX (1 << 3) /* Disable Auto MDI/MDIX */
+#define WPPM_FMDX (1 << 2) /* Force MDIX */
+#define WPPM_LPBK (1 << 1) /* MAX Loopback */
+
+/* PHY Power Save Register */
+#define PPS_PPSM (1 << 0) /* PHY Power Save Mode */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-pci.h b/arch/arm/mach-ks8695/include/mach/regs-pci.h
new file mode 100644
index 00000000..75a9db6e
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-pci.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-pci.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - PCI bridge registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define KS8695_PCI_OFFSET (0xF0000 + 0x2000)
+#define KS8695_PCI_VA (KS8695_IO_VA + KS8695_PCI_OFFSET)
+#define KS8695_PCI_PA (KS8695_IO_PA + KS8695_PCI_OFFSET)
+
+
+#define KS8695_CRCFID (0x000) /* Configuration: Identification */
+#define KS8695_CRCFCS (0x004) /* Configuration: Command and Status */
+#define KS8695_CRCFRV (0x008) /* Configuration: Revision */
+#define KS8695_CRCFLT (0x00C) /* Configuration: Latency Timer */
+#define KS8695_CRCBMA (0x010) /* Configuration: Base Memory Address */
+#define KS8695_CRCSID (0x02C) /* Configuration: Subsystem ID */
+#define KS8695_CRCFIT (0x03C) /* Configuration: Interrupt */
+#define KS8695_PBCA (0x100) /* Bridge Configuration Address */
+#define KS8695_PBCD (0x104) /* Bridge Configuration Data */
+#define KS8695_PBM (0x200) /* Bridge Mode */
+#define KS8695_PBCS (0x204) /* Bridge Control and Status */
+#define KS8695_PMBA (0x208) /* Bridge Memory Base Address */
+#define KS8695_PMBAC (0x20C) /* Bridge Memory Base Address Control */
+#define KS8695_PMBAM (0x210) /* Bridge Memory Base Address Mask */
+#define KS8695_PMBAT (0x214) /* Bridge Memory Base Address Translation */
+#define KS8695_PIOBA (0x218) /* Bridge I/O Base Address */
+#define KS8695_PIOBAC (0x21C) /* Bridge I/O Base Address Control */
+#define KS8695_PIOBAM (0x220) /* Bridge I/O Base Address Mask */
+#define KS8695_PIOBAT (0x224) /* Bridge I/O Base Address Translation */
+
+
+/* Configuration: Identification */
+
+/* Configuration: Command and Status */
+
+/* Configuration: Revision */
+
+
+
+#define CFRV_GUEST (1 << 23)
+
+#define PBCA_TYPE1 (1)
+#define PBCA_ENABLE (1 << 31)
+
+
diff --git a/arch/arm/mach-ks8695/include/mach/regs-switch.h b/arch/arm/mach-ks8695/include/mach/regs-switch.h
new file mode 100644
index 00000000..97e8acb1
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-switch.h
@@ -0,0 +1,66 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-switch.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - Switch Registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_SWITCH_H
+#define KS8695_SWITCH_H
+
+#define KS8695_SWITCH_OFFSET (0xF0000 + 0xe800)
+#define KS8695_SWITCH_VA (KS8695_IO_VA + KS8695_SWITCH_OFFSET)
+#define KS8695_SWITCH_PA (KS8695_IO_PA + KS8695_SWITCH_OFFSET)
+
+
+/*
+ * Switch registers
+ */
+#define KS8695_SEC0 (0x00) /* Switch Engine Control 0 */
+#define KS8695_SEC1 (0x04) /* Switch Engine Control 1 */
+#define KS8695_SEC2 (0x08) /* Switch Engine Control 2 */
+
+#define KS8695_SEPXCZ(x,z) (0x0c + (((x)-1)*3 + ((z)-1))*4) /* Port Configuration Registers */
+
+#define KS8695_SEP12AN (0x48) /* Port 1 & 2 Auto-Negotiation */
+#define KS8695_SEP34AN (0x4c) /* Port 3 & 4 Auto-Negotiation */
+#define KS8695_SEIAC (0x50) /* Indirect Access Control */
+#define KS8695_SEIADH2 (0x54) /* Indirect Access Data High 2 */
+#define KS8695_SEIADH1 (0x58) /* Indirect Access Data High 1 */
+#define KS8695_SEIADL (0x5c) /* Indirect Access Data Low */
+#define KS8695_SEAFC (0x60) /* Advance Feature Control */
+#define KS8695_SEDSCPH (0x64) /* TOS Priority High */
+#define KS8695_SEDSCPL (0x68) /* TOS Priority Low */
+#define KS8695_SEMAH (0x6c) /* Switch Engine MAC Address High */
+#define KS8695_SEMAL (0x70) /* Switch Engine MAC Address Low */
+#define KS8695_LPPM12 (0x74) /* Port 1 & 2 PHY Power Management */
+#define KS8695_LPPM34 (0x78) /* Port 3 & 4 PHY Power Management */
+
+
+/* Switch Engine Control 0 */
+#define SEC0_LLED1S (7 << 25) /* LED1 Select */
+#define LLED1S_SPEED (0 << 25)
+#define LLED1S_LINK (1 << 25)
+#define LLED1S_DUPLEX (2 << 25)
+#define LLED1S_COLLISION (3 << 25)
+#define LLED1S_ACTIVITY (4 << 25)
+#define LLED1S_FDX_COLLISION (5 << 25)
+#define LLED1S_LINK_ACTIVITY (6 << 25)
+#define SEC0_LLED0S (7 << 22) /* LED0 Select */
+#define LLED0S_SPEED (0 << 22)
+#define LLED0S_LINK (1 << 22)
+#define LLED0S_DUPLEX (2 << 22)
+#define LLED0S_COLLISION (3 << 22)
+#define LLED0S_ACTIVITY (4 << 22)
+#define LLED0S_FDX_COLLISION (5 << 22)
+#define LLED0S_LINK_ACTIVITY (6 << 22)
+#define SEC0_ENABLE (1 << 0) /* Enable Switch */
+
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-sys.h b/arch/arm/mach-ks8695/include/mach/regs-sys.h
new file mode 100644
index 00000000..57c20be0
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-sys.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-sys.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - System control registers and bit definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_SYS_H
+#define KS8695_SYS_H
+
+#define KS8695_SYS_OFFSET (0xF0000 + 0x0000)
+#define KS8695_SYS_VA (KS8695_IO_VA + KS8695_SYS_OFFSET)
+#define KS8695_SYS_PA (KS8695_IO_PA + KS8695_SYS_OFFSET)
+
+
+#define KS8695_SYSCFG (0x00) /* System Configuration Register */
+#define KS8695_CLKCON (0x04) /* System Clock and Bus Control Register */
+
+
+/* System Configuration Register */
+#define SYSCFG_SPRBP (0x3ff << 16) /* Register Bank Base Pointer */
+
+/* System Clock and Bus Control Register */
+#define CLKCON_SFMODE (1 << 8) /* System Fast Mode for Simulation */
+#define CLKCON_SCDC (7 << 0) /* System Clock Divider Select */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-timer.h b/arch/arm/mach-ks8695/include/mach/regs-timer.h
new file mode 100644
index 00000000..e620cda9
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-timer.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-timer.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - Timer registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_TIMER_H
+#define KS8695_TIMER_H
+
+#define KS8695_TMR_OFFSET (0xF0000 + 0xE400)
+#define KS8695_TMR_VA (KS8695_IO_VA + KS8695_TMR_OFFSET)
+#define KS8695_TMR_PA (KS8695_IO_PA + KS8695_TMR_OFFSET)
+
+
+/*
+ * Timer registers
+ */
+#define KS8695_TMCON (0x00) /* Timer Control Register */
+#define KS8695_T1TC (0x04) /* Timer 1 Timeout Count Register */
+#define KS8695_T0TC (0x08) /* Timer 0 Timeout Count Register */
+#define KS8695_T1PD (0x0C) /* Timer 1 Pulse Count Register */
+#define KS8695_T0PD (0x10) /* Timer 0 Pulse Count Register */
+
+
+/* Timer Control Register */
+#define TMCON_T1EN (1 << 1) /* Timer 1 Enable */
+#define TMCON_T0EN (1 << 0) /* Timer 0 Enable */
+
+/* Timer0 Timeout Counter Register */
+#define T0TC_WATCHDOG (0xff) /* Enable watchdog mode */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-uart.h b/arch/arm/mach-ks8695/include/mach/regs-uart.h
new file mode 100644
index 00000000..8581fbc6
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-uart.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-uart.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - UART register and bit 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 KS8695_UART_H
+#define KS8695_UART_H
+
+#define KS8695_UART_OFFSET (0xF0000 + 0xE000)
+#define KS8695_UART_VA (KS8695_IO_VA + KS8695_UART_OFFSET)
+#define KS8695_UART_PA (KS8695_IO_PA + KS8695_UART_OFFSET)
+
+
+/*
+ * UART registers
+ */
+#define KS8695_URRB (0x00) /* Receive Buffer Register */
+#define KS8695_URTH (0x04) /* Transmit Holding Register */
+#define KS8695_URFC (0x08) /* FIFO Control Register */
+#define KS8695_URLC (0x0C) /* Line Control Register */
+#define KS8695_URMC (0x10) /* Modem Control Register */
+#define KS8695_URLS (0x14) /* Line Status Register */
+#define KS8695_URMS (0x18) /* Modem Status Register */
+#define KS8695_URBD (0x1C) /* Baud Rate Divisor Register */
+#define KS8695_USR (0x20) /* Status Register */
+
+
+/* FIFO Control Register */
+#define URFC_URFRT (3 << 6) /* Receive FIFO Trigger Level */
+#define URFC_URFRT_1 (0 << 6)
+#define URFC_URFRT_4 (1 << 6)
+#define URFC_URFRT_8 (2 << 6)
+#define URFC_URFRT_14 (3 << 6)
+#define URFC_URTFR (1 << 2) /* Transmit FIFO Reset */
+#define URFC_URRFR (1 << 1) /* Receive FIFO Reset */
+#define URFC_URFE (1 << 0) /* FIFO Enable */
+
+/* Line Control Register */
+#define URLC_URSBC (1 << 6) /* Set Break Condition */
+#define URLC_PARITY (7 << 3) /* Parity */
+#define URPE_NONE (0 << 3)
+#define URPE_ODD (1 << 3)
+#define URPE_EVEN (3 << 3)
+#define URPE_MARK (5 << 3)
+#define URPE_SPACE (7 << 3)
+#define URLC_URSB (1 << 2) /* Stop Bits */
+#define URLC_URCL (3 << 0) /* Character Length */
+#define URCL_5 (0 << 0)
+#define URCL_6 (1 << 0)
+#define URCL_7 (2 << 0)
+#define URCL_8 (3 << 0)
+
+/* Modem Control Register */
+#define URMC_URLB (1 << 4) /* Loop-back mode */
+#define URMC_UROUT2 (1 << 3) /* OUT2 signal */
+#define URMC_UROUT1 (1 << 2) /* OUT1 signal */
+#define URMC_URRTS (1 << 1) /* Request to Send */
+#define URMC_URDTR (1 << 0) /* Data Terminal Ready */
+
+/* Line Status Register */
+#define URLS_URRFE (1 << 7) /* Receive FIFO Error */
+#define URLS_URTE (1 << 6) /* Transmit Empty */
+#define URLS_URTHRE (1 << 5) /* Transmit Holding Register Empty */
+#define URLS_URBI (1 << 4) /* Break Interrupt */
+#define URLS_URFE (1 << 3) /* Framing Error */
+#define URLS_URPE (1 << 2) /* Parity Error */
+#define URLS_URROE (1 << 1) /* Receive Overrun Error */
+#define URLS_URDR (1 << 0) /* Receive Data Ready */
+
+/* Modem Status Register */
+#define URMS_URDCD (1 << 7) /* Data Carrier Detect */
+#define URMS_URRI (1 << 6) /* Ring Indicator */
+#define URMS_URDSR (1 << 5) /* Data Set Ready */
+#define URMS_URCTS (1 << 4) /* Clear to Send */
+#define URMS_URDDCD (1 << 3) /* Delta Data Carrier Detect */
+#define URMS_URTERI (1 << 2) /* Trailing Edge Ring Indicator */
+#define URMS_URDDST (1 << 1) /* Delta Data Set Ready */
+#define URMS_URDCTS (1 << 0) /* Delta Clear to Send */
+
+/* Status Register */
+#define USR_UTI (1 << 0) /* Timeout Indication */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-wan.h b/arch/arm/mach-ks8695/include/mach/regs-wan.h
new file mode 100644
index 00000000..c475bed2
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/regs-wan.h
@@ -0,0 +1,65 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/regs-wan.h
+ *
+ * Copyright (C) 2006 Andrew Victor
+ *
+ * KS8695 - WAN Registers and bit definitions.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef KS8695_WAN_H
+#define KS8695_WAN_H
+
+#define KS8695_WAN_OFFSET (0xF0000 + 0x6000)
+#define KS8695_WAN_VA (KS8695_IO_VA + KS8695_WAN_OFFSET)
+#define KS8695_WAN_PA (KS8695_IO_PA + KS8695_WAN_OFFSET)
+
+
+/*
+ * WAN registers
+ */
+#define KS8695_WMDTXC (0x00) /* DMA Transmit Control */
+#define KS8695_WMDRXC (0x04) /* DMA Receive Control */
+#define KS8695_WMDTSC (0x08) /* DMA Transmit Start Command */
+#define KS8695_WMDRSC (0x0c) /* DMA Receive Start Command */
+#define KS8695_WTDLB (0x10) /* Transmit Descriptor List Base Address */
+#define KS8695_WRDLB (0x14) /* Receive Descriptor List Base Address */
+#define KS8695_WMAL (0x18) /* MAC Station Address Low */
+#define KS8695_WMAH (0x1c) /* MAC Station Address High */
+#define KS8695_WMAAL(n) (0x80 + ((n)*8)) /* MAC Additional Station Address (0..15) Low */
+#define KS8695_WMAAH(n) (0x84 + ((n)*8)) /* MAC Additional Station Address (0..15) High */
+
+
+/* DMA Transmit Control Register */
+#define WMDTXC_WMTRST (1 << 31) /* Soft Reset */
+#define WMDTXC_WMTBS (0x3f << 24) /* Transmit Burst Size */
+#define WMDTXC_WMTUCG (1 << 18) /* Transmit UDP Checksum Generate */
+#define WMDTXC_WMTTCG (1 << 17) /* Transmit TCP Checksum Generate */
+#define WMDTXC_WMTICG (1 << 16) /* Transmit IP Checksum Generate */
+#define WMDTXC_WMTFCE (1 << 9) /* Transmit Flow Control Enable */
+#define WMDTXC_WMTLB (1 << 8) /* Loopback mode */
+#define WMDTXC_WMTEP (1 << 2) /* Transmit Enable Padding */
+#define WMDTXC_WMTAC (1 << 1) /* Transmit Add CRC */
+#define WMDTXC_WMTE (1 << 0) /* TX Enable */
+
+/* DMA Receive Control Register */
+#define WMDRXC_WMRBS (0x3f << 24) /* Receive Burst Size */
+#define WMDRXC_WMRUCC (1 << 18) /* Receive UDP Checksum check */
+#define WMDRXC_WMRTCG (1 << 17) /* Receive TCP Checksum check */
+#define WMDRXC_WMRICG (1 << 16) /* Receive IP Checksum check */
+#define WMDRXC_WMRFCE (1 << 9) /* Receive Flow Control Enable */
+#define WMDRXC_WMRB (1 << 6) /* Receive Broadcast */
+#define WMDRXC_WMRM (1 << 5) /* Receive Multicast */
+#define WMDRXC_WMRU (1 << 4) /* Receive Unicast */
+#define WMDRXC_WMRERR (1 << 3) /* Receive Error Frame */
+#define WMDRXC_WMRA (1 << 2) /* Receive All */
+#define WMDRXC_WMRE (1 << 0) /* RX Enable */
+
+/* Additional Station Address High */
+#define WMAAH_E (1 << 31) /* Address Enabled */
+
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h
new file mode 100644
index 00000000..fb1dda9b
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/system.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-s3c2410/include/mach/system.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * KS8695 - System function defines and includes
+ *
+ * This program is free software; you can 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_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/regs-timer.h>
+
+static void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks,
+ */
+ cpu_do_idle();
+
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ unsigned int reg;
+
+ if (mode == 's')
+ cpu_reset(0);
+
+ /* disable timer0 */
+ reg = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(reg & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+
+ /* enable watchdog mode */
+ __raw_writel((10 << 8) | T0TC_WATCHDOG, KS8695_TMR_VA + KS8695_T0TC);
+
+ /* re-enable timer0 */
+ __raw_writel(reg | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/timex.h b/arch/arm/mach-ks8695/include/mach/timex.h
new file mode 100644
index 00000000..10f71637
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/timex.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * KS8695 - Time Parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#include <mach/hardware.h>
+
+#define CLOCK_TICK_RATE KS8695_CLOCK_RATE
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h
new file mode 100644
index 00000000..9495cb4d
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/uncompress.h
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec Electronics
+ *
+ * KS8695 - Kernel uncompressor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <linux/io.h>
+#include <mach/regs-uart.h>
+
+static void putc(char c)
+{
+ while (!(__raw_readl(KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE))
+ barrier();
+
+ __raw_writel(c, KS8695_UART_PA + KS8695_URTH);
+}
+
+static inline void flush(void)
+{
+ while (!(__raw_readl(KS8695_UART_PA + KS8695_URLS) & URLS_URTE))
+ barrier();
+}
+
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-ks8695/include/mach/vmalloc.h b/arch/arm/mach-ks8695/include/mach/vmalloc.h
new file mode 100644
index 00000000..744ac66b
--- /dev/null
+++ b/arch/arm/mach-ks8695/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-ks8695/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2006 Ben Dooks
+ * Copyright (C) 2006 Simtec Electronics <linux@simtec.co.uk>
+ *
+ * KS8695 vmalloc 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_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (KS8695_IO_VA & PGDIR_MASK)
+
+#endif
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
new file mode 100644
index 00000000..a78092dc
--- /dev/null
+++ b/arch/arm/mach-ks8695/irq.c
@@ -0,0 +1,177 @@
+/*
+ * arch/arm/mach-ks8695/irq.c
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+static void ks8695_irq_mask(struct irq_data *d)
+{
+ unsigned long inten;
+
+ inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
+ inten &= ~(1 << d->irq);
+
+ __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
+}
+
+static void ks8695_irq_unmask(struct irq_data *d)
+{
+ unsigned long inten;
+
+ inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
+ inten |= (1 << d->irq);
+
+ __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
+}
+
+static void ks8695_irq_ack(struct irq_data *d)
+{
+ __raw_writel((1 << d->irq), KS8695_IRQ_VA + KS8695_INTST);
+}
+
+
+static struct irq_chip ks8695_irq_level_chip;
+static struct irq_chip ks8695_irq_edge_chip;
+
+
+static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ unsigned long ctrl, mode;
+ unsigned short level_triggered = 0;
+
+ ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ mode = IOPC_TM_HIGH;
+ level_triggered = 1;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ mode = IOPC_TM_LOW;
+ level_triggered = 1;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ mode = IOPC_TM_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ mode = IOPC_TM_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ mode = IOPC_TM_EDGE;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (d->irq) {
+ case KS8695_IRQ_EXTERN0:
+ ctrl &= ~IOPC_IOEINT0TM;
+ ctrl |= IOPC_IOEINT0_MODE(mode);
+ break;
+ case KS8695_IRQ_EXTERN1:
+ ctrl &= ~IOPC_IOEINT1TM;
+ ctrl |= IOPC_IOEINT1_MODE(mode);
+ break;
+ case KS8695_IRQ_EXTERN2:
+ ctrl &= ~IOPC_IOEINT2TM;
+ ctrl |= IOPC_IOEINT2_MODE(mode);
+ break;
+ case KS8695_IRQ_EXTERN3:
+ ctrl &= ~IOPC_IOEINT3TM;
+ ctrl |= IOPC_IOEINT3_MODE(mode);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (level_triggered) {
+ irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
+ handle_level_irq);
+ }
+ else {
+ irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
+ handle_edge_irq);
+ }
+
+ __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
+ return 0;
+}
+
+static struct irq_chip ks8695_irq_level_chip = {
+ .irq_ack = ks8695_irq_mask,
+ .irq_mask = ks8695_irq_mask,
+ .irq_unmask = ks8695_irq_unmask,
+ .irq_set_type = ks8695_irq_set_type,
+};
+
+static struct irq_chip ks8695_irq_edge_chip = {
+ .irq_ack = ks8695_irq_ack,
+ .irq_mask = ks8695_irq_mask,
+ .irq_unmask = ks8695_irq_unmask,
+ .irq_set_type = ks8695_irq_set_type,
+};
+
+void __init ks8695_init_irq(void)
+{
+ unsigned int irq;
+
+ /* Disable all interrupts initially */
+ __raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
+ __raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ switch (irq) {
+ /* Level-triggered interrupts */
+ case KS8695_IRQ_BUS_ERROR:
+ case KS8695_IRQ_UART_MODEM_STATUS:
+ case KS8695_IRQ_UART_LINE_STATUS:
+ case KS8695_IRQ_UART_RX:
+ case KS8695_IRQ_COMM_TX:
+ case KS8695_IRQ_COMM_RX:
+ irq_set_chip_and_handler(irq,
+ &ks8695_irq_level_chip,
+ handle_level_irq);
+ break;
+
+ /* Edge-triggered interrupts */
+ default:
+ /* clear pending bit */
+ ks8695_irq_ack(irq_get_irq_data(irq));
+ irq_set_chip_and_handler(irq,
+ &ks8695_irq_edge_chip,
+ handle_edge_irq);
+ }
+
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-ks8695/leds.c b/arch/arm/mach-ks8695/leds.c
new file mode 100644
index 00000000..184ef74e
--- /dev/null
+++ b/arch/arm/mach-ks8695/leds.c
@@ -0,0 +1,93 @@
+/*
+ * LED driver for KS8695-based boards.
+ *
+ * Copyright (C) Andrew Victor
+ *
+ * This program is free software; you can 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/init.h>
+
+#include <asm/leds.h>
+#include <mach/devices.h>
+#include <mach/gpio.h>
+
+
+static inline void ks8695_led_on(unsigned int led)
+{
+ gpio_set_value(led, 0);
+}
+
+static inline void ks8695_led_off(unsigned int led)
+{
+ gpio_set_value(led, 1);
+}
+
+static inline void ks8695_led_toggle(unsigned int led)
+{
+ unsigned long is_off = gpio_get_value(led);
+ if (is_off)
+ ks8695_led_on(led);
+ else
+ ks8695_led_off(led);
+}
+
+
+/*
+ * Handle LED events.
+ */
+static void ks8695_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch(evt) {
+ case led_start: /* System startup */
+ ks8695_led_on(ks8695_leds_cpu);
+ break;
+
+ case led_stop: /* System stop / suspend */
+ ks8695_led_off(ks8695_leds_cpu);
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer: /* Every 50 timer ticks */
+ ks8695_led_toggle(ks8695_leds_timer);
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start: /* Entering idle state */
+ ks8695_led_off(ks8695_leds_cpu);
+ break;
+
+ case led_idle_end: /* Exit idle state */
+ ks8695_led_on(ks8695_leds_cpu);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ local_irq_restore(flags);
+}
+
+
+static int __init leds_init(void)
+{
+ if ((ks8695_leds_timer == -1) || (ks8695_leds_cpu == -1))
+ return -ENODEV;
+
+ leds_event = ks8695_leds_event;
+
+ leds_event(led_start);
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
new file mode 100644
index 00000000..5fcd082a
--- /dev/null
+++ b/arch/arm/mach-ks8695/pci.c
@@ -0,0 +1,329 @@
+/*
+ * arch/arm/mach-ks8695/pci.c
+ *
+ * Copyright (C) 2003, Micrel Semiconductors
+ * Copyright (C) 2006, Greg Ungerer <gerg@snapgear.com>
+ * Copyright (C) 2006, Ben Dooks
+ * Copyright (C) 2007, Andrew Victor
+ *
+ * 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/pci.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/signal.h>
+#include <asm/mach/pci.h>
+#include <mach/hardware.h>
+
+#include <mach/devices.h>
+#include <mach/regs-pci.h>
+
+
+static int pci_dbg;
+static int pci_cfg_dbg;
+
+
+static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
+{
+ unsigned long pbca;
+
+ pbca = PBCA_ENABLE | (where & ~3);
+ pbca |= PCI_SLOT(devfn) << 11 ;
+ pbca |= PCI_FUNC(devfn) << 8;
+ pbca |= bus_nr << 16;
+
+ if (bus_nr == 0) {
+ /* use Type-0 transaction */
+ __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA);
+ } else {
+ /* use Type-1 transaction */
+ __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA);
+ }
+}
+
+
+/*
+ * The KS8695 datasheet prohibits anything other than 32bit accesses
+ * to the IO registers, so all our configuration must be done with
+ * 32bit operations, and the correct bit masking and shifting.
+ */
+
+static int ks8695_pci_readconfig(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 *value)
+{
+ ks8695_pci_setupconfig(bus->number, devfn, where);
+
+ *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
+
+ switch (size) {
+ case 4:
+ break;
+ case 2:
+ *value = *value >> ((where & 2) * 8);
+ *value &= 0xffff;
+ break;
+ case 1:
+ *value = *value >> ((where & 3) * 8);
+ *value &= 0xff;
+ break;
+ }
+
+ if (pci_cfg_dbg) {
+ printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
+ bus->number, devfn, where, size, *value,
+ __raw_readl(KS8695_PCI_VA + KS8695_PBCD));
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int ks8695_pci_writeconfig(struct pci_bus *bus,
+ unsigned int devfn, int where, int size, u32 value)
+{
+ unsigned long tmp;
+
+ if (pci_cfg_dbg) {
+ printk("write: %d,%08x,%02x,%d: %08x\n",
+ bus->number, devfn, where, size, value);
+ }
+
+ ks8695_pci_setupconfig(bus->number, devfn, where);
+
+ switch (size) {
+ case 4:
+ __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
+ break;
+ case 2:
+ tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
+ tmp &= ~(0xffff << ((where & 2) * 8));
+ tmp |= value << ((where & 2) * 8);
+
+ __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
+ break;
+ case 1:
+ tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
+ tmp &= ~(0xff << ((where & 3) * 8));
+ tmp |= value << ((where & 3) * 8);
+
+ __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static void ks8695_local_writeconfig(int where, u32 value)
+{
+ ks8695_pci_setupconfig(0, 0, where);
+ __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
+}
+
+static struct pci_ops ks8695_pci_ops = {
+ .read = ks8695_pci_readconfig,
+ .write = ks8695_pci_writeconfig,
+};
+
+static struct pci_bus* __init ks8695_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &ks8695_pci_ops, sys);
+}
+
+static struct resource pci_mem = {
+ .name = "PCI Memory space",
+ .start = KS8695_PCIMEM_PA,
+ .end = KS8695_PCIMEM_PA + (KS8695_PCIMEM_SIZE - 1),
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource pci_io = {
+ .name = "PCI IO space",
+ .start = KS8695_PCIIO_PA,
+ .end = KS8695_PCIIO_PA + (KS8695_PCIIO_SIZE - 1),
+ .flags = IORESOURCE_IO,
+};
+
+static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ if (nr > 0)
+ return 0;
+
+ request_resource(&iomem_resource, &pci_mem);
+ request_resource(&ioport_resource, &pci_io);
+
+ sys->resource[0] = &pci_io;
+ sys->resource[1] = &pci_mem;
+ sys->resource[2] = NULL;
+
+ /* Assign and enable processor bridge */
+ ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
+
+ /* Enable bus-master & Memory Space access */
+ ks8695_local_writeconfig(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
+
+ /* Set cache-line size & latency. */
+ ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
+
+ /* Reserve PCI memory space for PCI-AHB resources */
+ if (!request_mem_region(KS8695_PCIMEM_PA, SZ_64M, "PCI-AHB Bridge")) {
+ printk(KERN_ERR "Cannot allocate PCI-AHB Bridge memory.\n");
+ return -EBUSY;
+ }
+
+ return 1;
+}
+
+static inline unsigned int size_mask(unsigned long size)
+{
+ return (~size) + 1;
+}
+
+static int ks8695_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ unsigned long pc = instruction_pointer(regs);
+ unsigned long instr = *(unsigned long *)pc;
+ unsigned long cmdstat;
+
+ cmdstat = __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS);
+
+ printk(KERN_ERR "PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
+ addr, fsr, regs->ARM_pc, regs->ARM_lr,
+ cmdstat & (PCI_STATUS_SIG_TARGET_ABORT << 16) ? "GenTarget" : " ",
+ cmdstat & (PCI_STATUS_REC_TARGET_ABORT << 16) ? "RecvTarget" : " ",
+ cmdstat & (PCI_STATUS_REC_MASTER_ABORT << 16) ? "MasterAbort" : " ",
+ cmdstat & (PCI_STATUS_SIG_SYSTEM_ERROR << 16) ? "SysError" : " ",
+ cmdstat & (PCI_STATUS_DETECTED_PARITY << 16) ? "Parity" : " "
+ );
+
+ __raw_writel(cmdstat, KS8695_PCI_VA + KS8695_CRCFCS);
+
+ /*
+ * If the instruction being executed was a read,
+ * make it look like it read all-ones.
+ */
+ if ((instr & 0x0c100000) == 0x04100000) {
+ int reg = (instr >> 12) & 15;
+ unsigned long val;
+
+ if (instr & 0x00400000)
+ val = 255;
+ else
+ val = -1;
+
+ regs->uregs[reg] = val;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+
+ if ((instr & 0x0e100090) == 0x00100090) {
+ int reg = (instr >> 12) & 15;
+
+ regs->uregs[reg] = -1;
+ regs->ARM_pc += 4;
+ return 0;
+ }
+
+ return 1;
+}
+
+static void __init ks8695_pci_preinit(void)
+{
+ /* make software reset to avoid freeze if PCI bus was messed up */
+ __raw_writel(0x80000000, KS8695_PCI_VA + KS8695_PBCS);
+
+ /* stage 1 initialization, subid, subdevice = 0x0001 */
+ __raw_writel(0x00010001, KS8695_PCI_VA + KS8695_CRCSID);
+
+ /* stage 2 initialization */
+ /* prefetch limits with 16 words, retry enable */
+ __raw_writel(0x40000000, KS8695_PCI_VA + KS8695_PBCS);
+
+ /* configure memory mapping */
+ __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBA);
+ __raw_writel(size_mask(KS8695_PCIMEM_SIZE), KS8695_PCI_VA + KS8695_PMBAM);
+ __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBAT);
+ __raw_writel(0, KS8695_PCI_VA + KS8695_PMBAC);
+
+ /* configure IO mapping */
+ __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBA);
+ __raw_writel(size_mask(KS8695_PCIIO_SIZE), KS8695_PCI_VA + KS8695_PIOBAM);
+ __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBAT);
+ __raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC);
+
+ /* hook in fault handlers */
+ hook_fault_code(8, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+ hook_fault_code(10, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
+}
+
+static void ks8695_show_pciregs(void)
+{
+ if (!pci_dbg)
+ return;
+
+ printk(KERN_INFO "PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFID));
+ printk(KERN_INFO "PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS));
+ printk(KERN_INFO "PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFRV));
+ printk(KERN_INFO "PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFLT));
+ printk(KERN_INFO "PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCBMA));
+ printk(KERN_INFO "PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCSID));
+ printk(KERN_INFO "PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFIT));
+
+ printk(KERN_INFO "PCI: PBM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBM));
+ printk(KERN_INFO "PCI: PBCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBCS));
+
+ printk(KERN_INFO "PCI: PMBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBA));
+ printk(KERN_INFO "PCI: PMBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAC));
+ printk(KERN_INFO "PCI: PMBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAM));
+ printk(KERN_INFO "PCI: PMBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAT));
+
+ printk(KERN_INFO "PCI: PIOBA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBA));
+ printk(KERN_INFO "PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAC));
+ printk(KERN_INFO "PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAM));
+ printk(KERN_INFO "PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAT));
+}
+
+
+static struct hw_pci ks8695_pci __initdata = {
+ .nr_controllers = 1,
+ .preinit = ks8695_pci_preinit,
+ .setup = ks8695_pci_setup,
+ .scan = ks8695_pci_scan_bus,
+ .postinit = NULL,
+ .swizzle = pci_std_swizzle,
+ .map_irq = NULL,
+};
+
+void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg)
+{
+ if (__raw_readl(KS8695_PCI_VA + KS8695_CRCFRV) & CFRV_GUEST) {
+ printk("PCI: KS8695 in guest mode, not initialising\n");
+ return;
+ }
+
+ printk(KERN_INFO "PCI: Initialising\n");
+ ks8695_show_pciregs();
+
+ /* set Mode */
+ __raw_writel(cfg->mode << 29, KS8695_PCI_VA + KS8695_PBM);
+
+ ks8695_pci.map_irq = cfg->map_irq; /* board-specific map_irq method */
+
+ pci_common_init(&ks8695_pci);
+}
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
new file mode 100644
index 00000000..69c072c2
--- /dev/null
+++ b/arch/arm/mach-ks8695/time.c
@@ -0,0 +1,111 @@
+/*
+ * arch/arm/mach-ks8695/time.c
+ *
+ * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
+ * Copyright (C) 2006 Simtec 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/regs-timer.h>
+#include <mach/regs-irq.h>
+
+#include "generic.h"
+
+/*
+ * Returns number of ms since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long ks8695_gettimeoffset (void)
+{
+ unsigned long elapsed, tick2, intpending;
+
+ /*
+ * Get the current number of ticks. Note that there is a race
+ * condition between us reading the timer and checking for an
+ * interrupt. We solve this by ensuring that the counter has not
+ * reloaded between our two reads.
+ */
+ elapsed = __raw_readl(KS8695_TMR_VA + KS8695_T1TC) + __raw_readl(KS8695_TMR_VA + KS8695_T1PD);
+ do {
+ tick2 = elapsed;
+ intpending = __raw_readl(KS8695_IRQ_VA + KS8695_INTST) & (1 << KS8695_IRQ_TIMER1);
+ elapsed = __raw_readl(KS8695_TMR_VA + KS8695_T1TC) + __raw_readl(KS8695_TMR_VA + KS8695_T1PD);
+ } while (elapsed > tick2);
+
+ /* Convert to number of ticks expired (not remaining) */
+ elapsed = (CLOCK_TICK_RATE / HZ) - elapsed;
+
+ /* Is interrupt pending? If so, then timer has been reloaded already. */
+ if (intpending)
+ elapsed += (CLOCK_TICK_RATE / HZ);
+
+ /* Convert ticks to usecs */
+ return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*
+ * IRQ handler for the timer.
+ */
+static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction ks8695_timer_irq = {
+ .name = "ks8695_tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = ks8695_timer_interrupt,
+};
+
+static void ks8695_timer_setup(void)
+{
+ unsigned long tmout = CLOCK_TICK_RATE / HZ;
+ unsigned long tmcon;
+
+ /* disable timer1 */
+ tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
+ __raw_writel(tmcon & ~TMCON_T1EN, KS8695_TMR_VA + KS8695_TMCON);
+
+ __raw_writel(tmout / 2, KS8695_TMR_VA + KS8695_T1TC);
+ __raw_writel(tmout / 2, KS8695_TMR_VA + KS8695_T1PD);
+
+ /* re-enable timer1 */
+ __raw_writel(tmcon | TMCON_T1EN, KS8695_TMR_VA + KS8695_TMCON);
+}
+
+static void __init ks8695_timer_init (void)
+{
+ ks8695_timer_setup();
+
+ /* Enable timer interrupts */
+ setup_irq(KS8695_IRQ_TIMER1, &ks8695_timer_irq);
+}
+
+struct sys_timer ks8695_timer = {
+ .init = ks8695_timer_init,
+ .offset = ks8695_gettimeoffset,
+ .resume = ks8695_timer_setup,
+};
diff --git a/arch/arm/mach-l7200/include/mach/debug-macro.S b/arch/arm/mach-l7200/include/mach/debug-macro.S
new file mode 100644
index 00000000..b0a2db77
--- /dev/null
+++ b/arch/arm/mach-l7200/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-l7200/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .equ io_virt, IO_BASE
+ .equ io_phys, IO_START
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00044000 @ UART1
+@ mov \rp, #0x00045000 @ UART2
+ add \rv, \rp, #io_virt @ virtual address
+ add \rp, \rp, #io_phys @ physical base address
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x0] @ UARTDR
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
+ bne 1001b
+ .endm
diff --git a/arch/arm/mach-loki/Kconfig b/arch/arm/mach-loki/Kconfig
new file mode 100644
index 00000000..0045bdd7
--- /dev/null
+++ b/arch/arm/mach-loki/Kconfig
@@ -0,0 +1,13 @@
+if ARCH_LOKI
+
+menu "Marvell Loki (88RC8480) Implementations"
+
+config MACH_LB88RC8480
+ bool "Marvell LB88RC8480 Development Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell LB88RC8480 Development Board.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-loki/Makefile b/arch/arm/mach-loki/Makefile
new file mode 100644
index 00000000..d43233ee
--- /dev/null
+++ b/arch/arm/mach-loki/Makefile
@@ -0,0 +1,3 @@
+obj-y += common.o addr-map.o irq.o
+
+obj-$(CONFIG_MACH_LB88RC8480) += lb88rc8480-setup.o
diff --git a/arch/arm/mach-loki/Makefile.boot b/arch/arm/mach-loki/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-loki/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-loki/addr-map.c b/arch/arm/mach-loki/addr-map.c
new file mode 100644
index 00000000..b9537c97
--- /dev/null
+++ b/arch/arm/mach-loki/addr-map.c
@@ -0,0 +1,122 @@
+/*
+ * arch/arm/mach-loki/addr-map.c
+ *
+ * Address map functions for Marvell Loki (88RC8480) SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR 0
+#define TARGET_DEV_BUS 1
+#define TARGET_PCIE0 3
+#define TARGET_PCIE1 4
+#define ATTR_DEV_BOOT 0x0f
+#define ATTR_DEV_CS2 0x1b
+#define ATTR_DEV_CS1 0x1d
+#define ATTR_DEV_CS0 0x1e
+#define ATTR_PCIE_IO 0x51
+#define ATTR_PCIE_MEM 0x59
+
+/*
+ * Helpers to get DDR bank info
+ */
+#define DDR_SIZE_CS(n) DDR_REG(0x1500 + ((n) << 3))
+#define DDR_BASE_CS(n) DDR_REG(0x1504 + ((n) << 3))
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define BRIDGE_REG(x) (BRIDGE_VIRT_BASE | (x))
+#define CPU_WIN_CTRL(n) BRIDGE_REG(0x000 | ((n) << 4))
+#define CPU_WIN_BASE(n) BRIDGE_REG(0x004 | ((n) << 4))
+#define CPU_WIN_REMAP_LO(n) BRIDGE_REG(0x008 | ((n) << 4))
+#define CPU_WIN_REMAP_HI(n) BRIDGE_REG(0x00c | ((n) << 4))
+
+
+struct mbus_dram_target_info loki_mbus_dram_info;
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+ u8 target, u8 attr, int remap)
+{
+ u32 ctrl;
+
+ base &= 0xffff0000;
+ ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (1 << 5) | target;
+
+ writel(base, CPU_WIN_BASE(win));
+ writel(ctrl, CPU_WIN_CTRL(win));
+ if (win < 2) {
+ if (remap < 0)
+ remap = base;
+
+ writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
+ writel(0, CPU_WIN_REMAP_HI(win));
+ }
+}
+
+void __init loki_setup_cpu_mbus(void)
+{
+ int i;
+ int cs;
+
+ /*
+ * First, disable and clear windows.
+ */
+ for (i = 0; i < 8; i++) {
+ writel(0, CPU_WIN_BASE(i));
+ writel(0, CPU_WIN_CTRL(i));
+ if (i < 2) {
+ writel(0, CPU_WIN_REMAP_LO(i));
+ writel(0, CPU_WIN_REMAP_HI(i));
+ }
+ }
+
+ /*
+ * Setup windows for PCIe IO+MEM space.
+ */
+ setup_cpu_win(2, LOKI_PCIE0_MEM_PHYS_BASE, LOKI_PCIE0_MEM_SIZE,
+ TARGET_PCIE0, ATTR_PCIE_MEM, -1);
+ setup_cpu_win(3, LOKI_PCIE1_MEM_PHYS_BASE, LOKI_PCIE1_MEM_SIZE,
+ TARGET_PCIE1, ATTR_PCIE_MEM, -1);
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ loki_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ for (i = 0, cs = 0; i < 4; i++) {
+ u32 base = readl(DDR_BASE_CS(i));
+ u32 size = readl(DDR_SIZE_CS(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (size & 1) {
+ struct mbus_dram_window *w;
+
+ w = &loki_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ w->base = base & 0xffff0000;
+ w->size = (size | 0x0000ffff) + 1;
+ }
+ }
+ loki_mbus_dram_info.num_cs = cs;
+}
+
+void __init loki_setup_dev_boot_win(u32 base, u32 size)
+{
+ setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
+}
diff --git a/arch/arm/mach-loki/common.c b/arch/arm/mach-loki/common.c
new file mode 100644
index 00000000..5f02664d
--- /dev/null
+++ b/arch/arm/mach-loki/common.c
@@ -0,0 +1,162 @@
+/*
+ * arch/arm/mach-loki/common.c
+ *
+ * Core functions for Marvell Loki (88RC8480) SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/dma-mapping.h>
+#include <asm/page.h>
+#include <asm/timex.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/bridge-regs.h>
+#include <mach/loki.h>
+#include <plat/orion_nand.h>
+#include <plat/time.h>
+#include <plat/common.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc loki_io_desc[] __initdata = {
+ {
+ .virtual = LOKI_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(LOKI_REGS_PHYS_BASE),
+ .length = LOKI_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init loki_map_io(void)
+{
+ iotable_init(loki_io_desc, ARRAY_SIZE(loki_io_desc));
+}
+
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ writel(0x00079220, GE0_VIRT_BASE + 0x20b0);
+
+ orion_ge00_init(eth_data, &loki_mbus_dram_info,
+ GE0_PHYS_BASE, IRQ_LOKI_GBE_A_INT,
+ 0, LOKI_TCLK);
+}
+
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ writel(0x00079220, GE1_VIRT_BASE + 0x20b0);
+
+ orion_ge01_init(eth_data, &loki_mbus_dram_info,
+ GE1_PHYS_BASE, IRQ_LOKI_GBE_B_INT,
+ 0, LOKI_TCLK);
+}
+
+
+/*****************************************************************************
+ * SAS/SATA
+ ****************************************************************************/
+static struct resource loki_sas_resources[] = {
+ {
+ .name = "mvsas0 mem",
+ .start = SAS0_PHYS_BASE,
+ .end = SAS0_PHYS_BASE + 0x01ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "mvsas0 irq",
+ .start = IRQ_LOKI_SAS_A,
+ .end = IRQ_LOKI_SAS_A,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "mvsas1 mem",
+ .start = SAS1_PHYS_BASE,
+ .end = SAS1_PHYS_BASE + 0x01ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "mvsas1 irq",
+ .start = IRQ_LOKI_SAS_B,
+ .end = IRQ_LOKI_SAS_B,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device loki_sas = {
+ .name = "mvsas",
+ .id = 0,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(loki_sas_resources),
+ .resource = loki_sas_resources,
+};
+
+void __init loki_sas_init(void)
+{
+ writel(0x8300f707, DDR_REG(0x1424));
+ platform_device_register(&loki_sas);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+void __init loki_uart0_init(void)
+{
+ orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+ IRQ_LOKI_UART0, LOKI_TCLK);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init loki_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_LOKI_UART1, LOKI_TCLK);
+}
+
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init loki_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+}
+
+static void loki_timer_init(void)
+{
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_LOKI_BRIDGE, LOKI_TCLK);
+}
+
+struct sys_timer loki_timer = {
+ .init = loki_timer_init,
+};
+
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+void __init loki_init(void)
+{
+ printk(KERN_INFO "Loki ID: 88RC8480. TCLK=%d.\n", LOKI_TCLK);
+
+ loki_setup_cpu_mbus();
+}
diff --git a/arch/arm/mach-loki/common.h b/arch/arm/mach-loki/common.h
new file mode 100644
index 00000000..a315dcf8
--- /dev/null
+++ b/arch/arm/mach-loki/common.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-loki/common.h
+ *
+ * Core functions for Marvell Loki (88RC8480) SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_LOKI_COMMON_H
+#define __ARCH_LOKI_COMMON_H
+
+struct mv643xx_eth_platform_data;
+
+/*
+ * Basic Loki init functions used early by machine-setup.
+ */
+void loki_map_io(void);
+void loki_init(void);
+void loki_init_early(void);
+void loki_init_irq(void);
+
+extern struct mbus_dram_target_info loki_mbus_dram_info;
+void loki_setup_cpu_mbus(void);
+void loki_setup_dev_boot_win(u32 base, u32 size);
+
+void loki_ge0_init(struct mv643xx_eth_platform_data *eth_data);
+void loki_ge1_init(struct mv643xx_eth_platform_data *eth_data);
+void loki_sas_init(void);
+void loki_uart0_init(void);
+void loki_uart1_init(void);
+
+extern struct sys_timer loki_timer;
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/bridge-regs.h b/arch/arm/mach-loki/include/mach/bridge-regs.h
new file mode 100644
index 00000000..fd877320
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/bridge-regs.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-loki/include/mach/bridge-regs.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/loki.h>
+
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define SOFT_RESET_OUT_EN 0x00000004
+
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SOFT_RESET 0x00000001
+
+#define BRIDGE_INT_TIMER1_CLR 0x0004
+
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_CAUSE_OFF 0x0000
+#define IRQ_MASK_OFF 0x0004
+
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/debug-macro.S b/arch/arm/mach-loki/include/mach/debug-macro.S
new file mode 100644
index 00000000..cc90d99a
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-loki/include/mach/debug-macro.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 <mach/loki.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =LOKI_REGS_PHYS_BASE
+ ldr \rv, =LOKI_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-loki/include/mach/entry-macro.S b/arch/arm/mach-loki/include/mach/entry-macro.S
new file mode 100644
index 00000000..bc917ed3
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/entry-macro.S
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-loki/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell Loki (88RC8480) platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/bridge-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IRQ_VIRT_BASE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #IRQ_CAUSE_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_OFF]
+ mov \irqnr, #0
+ ands \irqstat, \irqstat, \tmp
+ clzne \irqnr, \irqstat
+ rsbne \irqnr, \irqnr, #31
+ .endm
diff --git a/arch/arm/mach-loki/include/mach/hardware.h b/arch/arm/mach-loki/include/mach/hardware.h
new file mode 100644
index 00000000..d7bfc8f1
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/hardware.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-loki/include/mach/hardware.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "loki.h"
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/io.h b/arch/arm/mach-loki/include/mach/io.h
new file mode 100644
index 00000000..a373cd58
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/io.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-loki/include/mach/io.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "loki.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)((addr - LOKI_PCIE0_IO_PHYS_BASE)
+ + LOKI_PCIE0_IO_VIRT_BASE);
+}
+
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/irqs.h b/arch/arm/mach-loki/include/mach/irqs.h
new file mode 100644
index 00000000..9fbd3326
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/irqs.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-loki/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell Loki (88RC8480) SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include "loki.h" /* need GPIO_MAX */
+
+/*
+ * Interrupt Controller
+ */
+#define IRQ_LOKI_PCIE_A_CPU_DRBL 0
+#define IRQ_LOKI_CPU_PCIE_A_DRBL 1
+#define IRQ_LOKI_PCIE_B_CPU_DRBL 2
+#define IRQ_LOKI_CPU_PCIE_B_DRBL 3
+#define IRQ_LOKI_COM_A_ERR 6
+#define IRQ_LOKI_COM_A_IN 7
+#define IRQ_LOKI_COM_A_OUT 8
+#define IRQ_LOKI_COM_B_ERR 9
+#define IRQ_LOKI_COM_B_IN 10
+#define IRQ_LOKI_COM_B_OUT 11
+#define IRQ_LOKI_DMA_A 12
+#define IRQ_LOKI_DMA_B 13
+#define IRQ_LOKI_SAS_A 14
+#define IRQ_LOKI_SAS_B 15
+#define IRQ_LOKI_DDR 16
+#define IRQ_LOKI_XOR 17
+#define IRQ_LOKI_BRIDGE 18
+#define IRQ_LOKI_PCIE_A_ERR 20
+#define IRQ_LOKI_PCIE_A_INT 21
+#define IRQ_LOKI_PCIE_B_ERR 22
+#define IRQ_LOKI_PCIE_B_INT 23
+#define IRQ_LOKI_GBE_A_INT 24
+#define IRQ_LOKI_GBE_B_INT 25
+#define IRQ_LOKI_DEV_ERR 26
+#define IRQ_LOKI_UART0 27
+#define IRQ_LOKI_UART1 28
+#define IRQ_LOKI_TWSI 29
+#define IRQ_LOKI_GPIO_23_0 30
+#define IRQ_LOKI_GPIO_25_24 31
+
+/*
+ * Loki General Purpose Pins
+ */
+#define IRQ_LOKI_GPIO_START 32
+#define NR_GPIO_IRQS GPIO_MAX
+
+#define NR_IRQS (IRQ_LOKI_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/loki.h b/arch/arm/mach-loki/include/mach/loki.h
new file mode 100644
index 00000000..bfca7c26
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/loki.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-loki/include/mach/loki.h
+ *
+ * Generic definitions for Marvell Loki (88RC8480) SoC flavors
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_LOKI_H
+#define __ASM_ARCH_LOKI_H
+
+/*
+ * Marvell Loki (88RC8480) address maps.
+ *
+ * phys
+ * d0000000 on-chip peripheral registers
+ * e0000000 PCIe 0 Memory space
+ * e8000000 PCIe 1 Memory space
+ * f0000000 PCIe 0 I/O space
+ * f0100000 PCIe 1 I/O space
+ *
+ * virt phys size
+ * fed00000 d0000000 1M on-chip peripheral registers
+ * fee00000 f0000000 64K PCIe 0 I/O space
+ * fef00000 f0100000 64K PCIe 1 I/O space
+ */
+
+#define LOKI_REGS_PHYS_BASE 0xd0000000
+#define LOKI_REGS_VIRT_BASE 0xfed00000
+#define LOKI_REGS_SIZE SZ_1M
+
+#define LOKI_PCIE0_IO_PHYS_BASE 0xf0000000
+#define LOKI_PCIE0_IO_VIRT_BASE 0xfee00000
+#define LOKI_PCIE0_IO_BUS_BASE 0x00000000
+#define LOKI_PCIE0_IO_SIZE SZ_64K
+
+#define LOKI_PCIE1_IO_PHYS_BASE 0xf0100000
+#define LOKI_PCIE1_IO_VIRT_BASE 0xfef00000
+#define LOKI_PCIE1_IO_BUS_BASE 0x00000000
+#define LOKI_PCIE1_IO_SIZE SZ_64K
+
+#define LOKI_PCIE0_MEM_PHYS_BASE 0xe0000000
+#define LOKI_PCIE0_MEM_SIZE SZ_128M
+
+#define LOKI_PCIE1_MEM_PHYS_BASE 0xe8000000
+#define LOKI_PCIE1_MEM_SIZE SZ_128M
+
+/*
+ * Register Map
+ */
+#define DEV_BUS_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x10000)
+#define DEV_BUS_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x10000)
+#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
+#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
+#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
+#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
+
+#define BRIDGE_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x20000)
+
+#define PCIE0_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x30000)
+
+#define PCIE1_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0x40000)
+
+#define SAS0_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x80000)
+
+#define SAS1_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0x90000)
+
+#define GE0_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0xa0000)
+#define GE0_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xa0000)
+
+#define GE1_PHYS_BASE (LOKI_REGS_PHYS_BASE | 0xb0000)
+#define GE1_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xb0000)
+
+#define DDR_VIRT_BASE (LOKI_REGS_VIRT_BASE | 0xf0000)
+#define DDR_REG(x) (DDR_VIRT_BASE | (x))
+
+
+#define GPIO_MAX 8
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/memory.h b/arch/arm/mach-loki/include/mach/memory.h
new file mode 100644
index 00000000..66366657
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/memory.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-loki/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/system.h b/arch/arm/mach-loki/include/mach/system.h
new file mode 100644
index 00000000..71895199
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/system.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-loki/include/mach/system.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+ /*
+ * Assert soft reset.
+ */
+ writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+ while (1)
+ ;
+}
+
+
+#endif
diff --git a/arch/arm/mach-loki/include/mach/timex.h b/arch/arm/mach-loki/include/mach/timex.h
new file mode 100644
index 00000000..9df21091
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/timex.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/mach-loki/include/mach/timex.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
+
+#define LOKI_TCLK 180000000
diff --git a/arch/arm/mach-loki/include/mach/uncompress.h b/arch/arm/mach-loki/include/mach/uncompress.h
new file mode 100644
index 00000000..90b2a7e6
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-loki/include/mach/uncompress.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/loki.h>
+
+#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-loki/include/mach/vmalloc.h b/arch/arm/mach-loki/include/mach/vmalloc.h
new file mode 100644
index 00000000..5dcbd865
--- /dev/null
+++ b/arch/arm/mach-loki/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-loki/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe800000UL
diff --git a/arch/arm/mach-loki/irq.c b/arch/arm/mach-loki/irq.c
new file mode 100644
index 00000000..76b211bf
--- /dev/null
+++ b/arch/arm/mach-loki/irq.c
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-loki/irq.c
+ *
+ * Marvell Loki (88RC8480) IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/bridge-regs.h>
+#include <plat/irq.h>
+#include "common.h"
+
+void __init loki_init_irq(void)
+{
+ orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_OFF));
+}
diff --git a/arch/arm/mach-loki/lb88rc8480-setup.c b/arch/arm/mach-loki/lb88rc8480-setup.c
new file mode 100644
index 00000000..35eae4e6
--- /dev/null
+++ b/arch/arm/mach-loki/lb88rc8480-setup.c
@@ -0,0 +1,99 @@
+/*
+ * arch/arm/mach-loki/lb88rc8480-setup.c
+ *
+ * Marvell LB88RC8480 Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/loki.h>
+#include "common.h"
+
+#define LB88RC8480_FLASH_BOOT_CS_BASE 0xf8000000
+#define LB88RC8480_FLASH_BOOT_CS_SIZE SZ_128M
+
+#define LB88RC8480_NOR_BOOT_BASE 0xff000000
+#define LB88RC8480_NOR_BOOT_SIZE SZ_16M
+
+static struct mtd_partition lb88rc8480_boot_flash_parts[] = {
+ {
+ .name = "kernel",
+ .offset = 0,
+ .size = SZ_2M,
+ }, {
+ .name = "root-fs",
+ .offset = SZ_2M,
+ .size = (SZ_8M + SZ_4M + SZ_1M),
+ }, {
+ .name = "u-boot",
+ .offset = (SZ_8M + SZ_4M + SZ_2M + SZ_1M),
+ .size = SZ_1M,
+ },
+};
+
+static struct physmap_flash_data lb88rc8480_boot_flash_data = {
+ .parts = lb88rc8480_boot_flash_parts,
+ .nr_parts = ARRAY_SIZE(lb88rc8480_boot_flash_parts),
+ .width = 1, /* 8 bit bus width */
+};
+
+static struct resource lb88rc8480_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LB88RC8480_NOR_BOOT_BASE,
+ .end = LB88RC8480_NOR_BOOT_BASE + LB88RC8480_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lb88rc8480_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lb88rc8480_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &lb88rc8480_boot_flash_resource,
+};
+
+static struct mv643xx_eth_platform_data lb88rc8480_ge0_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(1),
+ .mac_addr = { 0x00, 0x50, 0x43, 0x11, 0x22, 0x33 },
+};
+
+static void __init lb88rc8480_init(void)
+{
+ /*
+ * Basic setup. Needs to be called early.
+ */
+ loki_init();
+
+ loki_ge0_init(&lb88rc8480_ge0_data);
+ loki_sas_init();
+ loki_uart0_init();
+ loki_uart1_init();
+
+ loki_setup_dev_boot_win(LB88RC8480_FLASH_BOOT_CS_BASE,
+ LB88RC8480_FLASH_BOOT_CS_SIZE);
+ platform_device_register(&lb88rc8480_boot_flash);
+}
+
+MACHINE_START(LB88RC8480, "Marvell LB88RC8480 Development Board")
+ /* Maintainer: Ke Wei <kewei@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = lb88rc8480_init,
+ .map_io = loki_map_io,
+ .init_early = loki_init_early,
+ .init_irq = loki_init_irq,
+ .timer = &loki_timer,
+MACHINE_END
diff --git a/arch/arm/mach-lpc32xx/Kconfig b/arch/arm/mach-lpc32xx/Kconfig
new file mode 100644
index 00000000..fde66350
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/Kconfig
@@ -0,0 +1,33 @@
+if ARCH_LPC32XX
+
+menu "Individual UART enable selections"
+
+config ARCH_LPC32XX_UART3_SELECT
+ bool "Add support for standard UART3"
+ help
+ Adds support for standard UART 3 when the 8250 serial support
+ is enabled.
+
+config ARCH_LPC32XX_UART4_SELECT
+ bool "Add support for standard UART4"
+ help
+ Adds support for standard UART 4 when the 8250 serial support
+ is enabled.
+
+config ARCH_LPC32XX_UART5_SELECT
+ bool "Add support for standard UART5"
+ default y
+ help
+ Adds support for standard UART 5 when the 8250 serial support
+ is enabled.
+
+config ARCH_LPC32XX_UART6_SELECT
+ bool "Add support for standard UART6"
+ help
+ Adds support for standard UART 6 when the 8250 serial support
+ is enabled.
+
+endmenu
+
+endif
+
diff --git a/arch/arm/mach-lpc32xx/Makefile b/arch/arm/mach-lpc32xx/Makefile
new file mode 100644
index 00000000..a5fc5d0e
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := timer.o irq.o common.o serial.o clock.o
+obj-y += gpiolib.o pm.o suspend.o
+obj-y += phy3250.o
+
diff --git a/arch/arm/mach-lpc32xx/Makefile.boot b/arch/arm/mach-lpc32xx/Makefile.boot
new file mode 100644
index 00000000..b796b41e
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x82000000
+
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
new file mode 100644
index 00000000..da0e6498
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -0,0 +1,1136 @@
+/*
+ * arch/arm/mach-lpc32xx/clock.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+/*
+ * LPC32xx clock management driver overview
+ *
+ * The LPC32XX contains a number of high level system clocks that can be
+ * generated from different sources. These system clocks are used to
+ * generate the CPU and bus rates and the individual peripheral clocks in
+ * the system. When Linux is started by the boot loader, the system
+ * clocks are already running. Stopping a system clock during normal
+ * Linux operation should never be attempted, as peripherals that require
+ * those clocks will quit working (ie, DRAM).
+ *
+ * The LPC32xx high level clock tree looks as follows. Clocks marked with
+ * an asterisk are always on and cannot be disabled. Clocks marked with
+ * an ampersand can only be disabled in CPU suspend mode. Clocks marked
+ * with a caret are always on if it is the selected clock for the SYSCLK
+ * source. The clock that isn't used for SYSCLK can be enabled and
+ * disabled normally.
+ * 32KHz oscillator*
+ * / | \
+ * RTC* PLL397^ TOUCH
+ * /
+ * Main oscillator^ /
+ * | \ /
+ * | SYSCLK&
+ * | \
+ * | \
+ * USB_PLL HCLK_PLL&
+ * | | |
+ * USB host/device PCLK& |
+ * | |
+ * Peripherals
+ *
+ * The CPU and chip bus rates are derived from the HCLK PLL, which can
+ * generate various clock rates up to 266MHz and beyond. The internal bus
+ * rates (PCLK and HCLK) are generated from dividers based on the HCLK
+ * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate,
+ * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high
+ * level clocks are based on either HCLK or PCLK, but have their own
+ * dividers as part of the IP itself. Because of this, the system clock
+ * rates should not be changed.
+ *
+ * The HCLK PLL is clocked from SYSCLK, which can be derived from the
+ * main oscillator or PLL397. PLL397 generates a rate that is 397 times
+ * the 32KHz oscillator rate. The main oscillator runs at the selected
+ * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate
+ * is normally 13MHz, but depends on the selection of external crystals
+ * or oscillators. If USB operation is required, the main oscillator must
+ * be used in the system.
+ *
+ * Switching SYSCLK between sources during normal Linux operation is not
+ * supported. SYSCLK is preset in the bootloader. Because of the
+ * complexities of clock management during clock frequency changes,
+ * there are some limitations to the clock driver explained below:
+ * - The PLL397 and main oscillator can be enabled and disabled by the
+ * clk_enable() and clk_disable() functions unless SYSCLK is based
+ * on that clock. This allows the other oscillator that isn't driving
+ * the HCLK PLL to be used as another system clock that can be routed
+ * to an external pin.
+ * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with
+ * this driver.
+ * - HCLK and PCLK rates cannot be changed as part of this driver.
+ * - Most peripherals have their own dividers are part of the peripheral
+ * block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates
+ * will also impact the individual peripheral rates.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "clock.h"
+#include "common.h"
+
+static struct clk clk_armpll;
+static struct clk clk_usbpll;
+static DEFINE_MUTEX(clkm_lock);
+
+/*
+ * Post divider values for PLLs based on selected register value
+ */
+static const u32 pll_postdivs[4] = {1, 2, 4, 8};
+
+static unsigned long local_return_parent_rate(struct clk *clk)
+{
+ /*
+ * If a clock has a rate of 0, then it inherits it's parent
+ * clock rate
+ */
+ while (clk->rate == 0)
+ clk = clk->parent;
+
+ return clk->rate;
+}
+
+/* 32KHz clock has a fixed rate and is not stoppable */
+static struct clk osc_32KHz = {
+ .rate = LPC32XX_CLOCK_OSC_FREQ,
+ .get_rate = local_return_parent_rate,
+};
+
+static int local_pll397_enable(struct clk *clk, int enable)
+{
+ u32 reg;
+ unsigned long timeout = 1 + msecs_to_jiffies(10);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
+
+ if (enable == 0) {
+ reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
+ __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
+ } else {
+ /* Enable PLL397 */
+ reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
+ __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
+
+ /* Wait for PLL397 lock */
+ while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
+ LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
+ (timeout > jiffies))
+ cpu_relax();
+
+ if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
+ LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int local_oscmain_enable(struct clk *clk, int enable)
+{
+ u32 reg;
+ unsigned long timeout = 1 + msecs_to_jiffies(10);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
+
+ if (enable == 0) {
+ reg |= LPC32XX_CLKPWR_MOSC_DISABLE;
+ __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
+ } else {
+ /* Enable main oscillator */
+ reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE;
+ __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
+
+ /* Wait for main oscillator to start */
+ while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
+ LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
+ (timeout > jiffies))
+ cpu_relax();
+
+ if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
+ LPC32XX_CLKPWR_MOSC_DISABLE) != 0)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct clk osc_pll397 = {
+ .parent = &osc_32KHz,
+ .enable = local_pll397_enable,
+ .rate = LPC32XX_CLOCK_OSC_FREQ * 397,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk osc_main = {
+ .enable = local_oscmain_enable,
+ .rate = LPC32XX_MAIN_OSC_FREQ,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_sys;
+
+/*
+ * Convert a PLL register value to a PLL output frequency
+ */
+u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval)
+{
+ struct clk_pll_setup pllcfg;
+
+ pllcfg.cco_bypass_b15 = 0;
+ pllcfg.direct_output_b14 = 0;
+ pllcfg.fdbk_div_ctrl_b13 = 0;
+ if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0)
+ pllcfg.cco_bypass_b15 = 1;
+ if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0)
+ pllcfg.direct_output_b14 = 1;
+ if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0)
+ pllcfg.fdbk_div_ctrl_b13 = 1;
+ pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF);
+ pllcfg.pll_n = 1 + ((regval >> 9) & 0x3);
+ pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)];
+
+ return clk_check_pll_setup(inputclk, &pllcfg);
+}
+
+/*
+ * Setup the HCLK PLL with a PLL structure
+ */
+static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup)
+{
+ u32 tv, tmp = 0;
+
+ if (PllSetup->analog_on != 0)
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP;
+ if (PllSetup->cco_bypass_b15 != 0)
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS;
+ if (PllSetup->direct_output_b14 != 0)
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS;
+ if (PllSetup->fdbk_div_ctrl_b13 != 0)
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK;
+
+ tv = ffs(PllSetup->pll_p) - 1;
+ if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3))
+ return 0;
+
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv);
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1);
+ tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1);
+
+ return tmp;
+}
+
+/*
+ * Update the ARM core PLL frequency rate variable from the actual PLL setting
+ */
+static void local_update_armpll_rate(void)
+{
+ u32 clkin, pllreg;
+
+ clkin = clk_armpll.parent->rate;
+ pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
+
+ clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg);
+}
+
+/*
+ * Find a PLL configuration for the selected input frequency
+ */
+static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq,
+ struct clk_pll_setup *pllsetup)
+{
+ u32 ifreq, freqtol, m, n, p, fclkout;
+
+ /* Determine frequency tolerance limits */
+ freqtol = target_freq / 250;
+ ifreq = pllin_freq;
+
+ /* Is direct bypass mode possible? */
+ if (abs(pllin_freq - target_freq) <= freqtol) {
+ pllsetup->analog_on = 0;
+ pllsetup->cco_bypass_b15 = 1;
+ pllsetup->direct_output_b14 = 1;
+ pllsetup->fdbk_div_ctrl_b13 = 1;
+ pllsetup->pll_p = pll_postdivs[0];
+ pllsetup->pll_n = 1;
+ pllsetup->pll_m = 1;
+ return clk_check_pll_setup(ifreq, pllsetup);
+ } else if (target_freq <= ifreq) {
+ pllsetup->analog_on = 0;
+ pllsetup->cco_bypass_b15 = 1;
+ pllsetup->direct_output_b14 = 0;
+ pllsetup->fdbk_div_ctrl_b13 = 1;
+ pllsetup->pll_n = 1;
+ pllsetup->pll_m = 1;
+ for (p = 0; p <= 3; p++) {
+ pllsetup->pll_p = pll_postdivs[p];
+ fclkout = clk_check_pll_setup(ifreq, pllsetup);
+ if (abs(target_freq - fclkout) <= freqtol)
+ return fclkout;
+ }
+ }
+
+ /* Is direct mode possible? */
+ pllsetup->analog_on = 1;
+ pllsetup->cco_bypass_b15 = 0;
+ pllsetup->direct_output_b14 = 1;
+ pllsetup->fdbk_div_ctrl_b13 = 0;
+ pllsetup->pll_p = pll_postdivs[0];
+ for (m = 1; m <= 256; m++) {
+ for (n = 1; n <= 4; n++) {
+ /* Compute output frequency for this value */
+ pllsetup->pll_n = n;
+ pllsetup->pll_m = m;
+ fclkout = clk_check_pll_setup(ifreq,
+ pllsetup);
+ if (abs(target_freq - fclkout) <=
+ freqtol)
+ return fclkout;
+ }
+ }
+
+ /* Is integer mode possible? */
+ pllsetup->analog_on = 1;
+ pllsetup->cco_bypass_b15 = 0;
+ pllsetup->direct_output_b14 = 0;
+ pllsetup->fdbk_div_ctrl_b13 = 1;
+ for (m = 1; m <= 256; m++) {
+ for (n = 1; n <= 4; n++) {
+ for (p = 0; p < 4; p++) {
+ /* Compute output frequency */
+ pllsetup->pll_p = pll_postdivs[p];
+ pllsetup->pll_n = n;
+ pllsetup->pll_m = m;
+ fclkout = clk_check_pll_setup(
+ ifreq, pllsetup);
+ if (abs(target_freq - fclkout) <= freqtol)
+ return fclkout;
+ }
+ }
+ }
+
+ /* Try non-integer mode */
+ pllsetup->analog_on = 1;
+ pllsetup->cco_bypass_b15 = 0;
+ pllsetup->direct_output_b14 = 0;
+ pllsetup->fdbk_div_ctrl_b13 = 0;
+ for (m = 1; m <= 256; m++) {
+ for (n = 1; n <= 4; n++) {
+ for (p = 0; p < 4; p++) {
+ /* Compute output frequency */
+ pllsetup->pll_p = pll_postdivs[p];
+ pllsetup->pll_n = n;
+ pllsetup->pll_m = m;
+ fclkout = clk_check_pll_setup(
+ ifreq, pllsetup);
+ if (abs(target_freq - fclkout) <= freqtol)
+ return fclkout;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static struct clk clk_armpll = {
+ .parent = &clk_sys,
+ .get_rate = local_return_parent_rate,
+};
+
+/*
+ * Setup the USB PLL with a PLL structure
+ */
+static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
+{
+ u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF;
+ reg |= tmp;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ return clk_check_pll_setup(clk_usbpll.parent->rate,
+ pHCLKPllSetup);
+}
+
+static int local_usbpll_enable(struct clk *clk, int enable)
+{
+ u32 reg;
+ int ret = -ENODEV;
+ unsigned long timeout = 1 + msecs_to_jiffies(10);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+
+ if (enable == 0) {
+ reg &= ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
+ LPC32XX_CLKPWR_USBCTRL_CLK_EN2);
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+ } else if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP) {
+ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ /* Wait for PLL lock */
+ while ((timeout > jiffies) & (ret == -ENODEV)) {
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+ if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
+ ret = 0;
+ }
+
+ if (ret == 0) {
+ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+ }
+ }
+
+ return ret;
+}
+
+static unsigned long local_usbpll_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 clkin, usbdiv;
+ struct clk_pll_setup pllsetup;
+
+ /*
+ * Unlike other clocks, this clock has a KHz input rate, so bump
+ * it up to work with the PLL function
+ */
+ rate = rate * 1000;
+
+ clkin = clk->parent->rate;
+ usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
+ LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
+ clkin = clkin / usbdiv;
+
+ /* Try to find a good rate setup */
+ if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
+ return 0;
+
+ return clk_check_pll_setup(clkin, &pllsetup);
+}
+
+static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 clkin, reg, usbdiv;
+ struct clk_pll_setup pllsetup;
+
+ /*
+ * Unlike other clocks, this clock has a KHz input rate, so bump
+ * it up to work with the PLL function
+ */
+ rate = rate * 1000;
+
+ clkin = clk->get_rate(clk);
+ usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
+ LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
+ clkin = clkin / usbdiv;
+
+ /* Try to find a good rate setup */
+ if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
+ return -EINVAL;
+
+ local_usbpll_enable(clk, 0);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ pllsetup.analog_on = 1;
+ local_clk_usbpll_setup(&pllsetup);
+
+ clk->rate = clk_check_pll_setup(clkin, &pllsetup);
+
+ reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
+ reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN2;
+ __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
+
+ return 0;
+}
+
+static struct clk clk_usbpll = {
+ .parent = &osc_main,
+ .set_rate = local_usbpll_set_rate,
+ .enable = local_usbpll_enable,
+ .rate = 48000, /* In KHz */
+ .get_rate = local_return_parent_rate,
+ .round_rate = local_usbpll_round_rate,
+};
+
+static u32 clk_get_hclk_div(void)
+{
+ static const u32 hclkdivs[4] = {1, 2, 4, 4};
+ return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(
+ __raw_readl(LPC32XX_CLKPWR_HCLK_DIV))];
+}
+
+static struct clk clk_hclk = {
+ .parent = &clk_armpll,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_pclk = {
+ .parent = &clk_armpll,
+ .get_rate = local_return_parent_rate,
+};
+
+static int local_onoff_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(clk->enable_reg);
+
+ if (enable == 0)
+ tmp &= ~clk->enable_mask;
+ else
+ tmp |= clk->enable_mask;
+
+ __raw_writel(tmp, clk->enable_reg);
+
+ return 0;
+}
+
+/* Peripheral clock sources */
+static struct clk clk_timer0 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+ .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_timer1 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+ .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_timer2 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+ .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_timer3 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
+ .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_wdt = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_TIMER_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_vfp9 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_DEBUG_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT,
+ .get_rate = local_return_parent_rate,
+};
+static struct clk clk_dma = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_DMA_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_uart3 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_uart4 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_uart5 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_uart6 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_i2c0 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_i2c1 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_i2c2 = {
+ .parent = &clk_pclk,
+ .enable = local_onoff_enable,
+ .enable_reg = io_p2v(LPC32XX_USB_BASE + 0xFF4),
+ .enable_mask = 0x4,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_ssp0 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_ssp1 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_kscan = {
+ .parent = &osc_32KHz,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_KEY_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_nand = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_i2s0 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_i2s1 = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_net = {
+ .parent = &clk_hclk,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_MACCLK_CTRL,
+ .enable_mask = (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN |
+ LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN |
+ LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN),
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_rtc = {
+ .parent = &osc_32KHz,
+ .rate = 1, /* 1 Hz */
+ .get_rate = local_return_parent_rate,
+};
+
+static struct clk clk_usbd = {
+ .parent = &clk_usbpll,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_USB_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static int tsc_onoff_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+
+ /* Make sure 32KHz clock is the selected clock */
+ tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+ tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
+ __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+
+ if (enable == 0)
+ __raw_writel(0, clk->enable_reg);
+ else
+ __raw_writel(clk->enable_mask, clk->enable_reg);
+
+ return 0;
+}
+
+static struct clk clk_tsc = {
+ .parent = &osc_32KHz,
+ .enable = tsc_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
+static int mmc_onoff_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
+ ~LPC32XX_CLKPWR_MSCARD_SDCARD_EN;
+
+ /* If rate is 0, disable clock */
+ if (enable != 0)
+ tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN;
+
+ __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
+
+ return 0;
+}
+
+static unsigned long mmc_get_rate(struct clk *clk)
+{
+ u32 div, rate, oldclk;
+
+ /* The MMC clock must be on when accessing an MMC register */
+ oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
+ __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
+ LPC32XX_CLKPWR_MS_CTRL);
+ div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
+ __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL);
+
+ /* Get the parent clock rate */
+ rate = clk->parent->get_rate(clk->parent);
+
+ /* Get the MMC controller clock divider value */
+ div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
+
+ if (!div)
+ div = 1;
+
+ return rate / div;
+}
+
+static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long div, prate;
+
+ /* Get the parent clock rate */
+ prate = clk->parent->get_rate(clk->parent);
+
+ if (rate >= prate)
+ return prate;
+
+ div = prate / rate;
+ if (div > 0xf)
+ div = 0xf;
+
+ return prate / div;
+}
+
+static int mmc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 oldclk, tmp;
+ unsigned long prate, div, crate = mmc_round_rate(clk, rate);
+
+ prate = clk->parent->get_rate(clk->parent);
+
+ div = prate / crate;
+
+ /* The MMC clock must be on when accessing an MMC register */
+ oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
+ __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
+ LPC32XX_CLKPWR_MS_CTRL);
+ tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
+ ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
+ tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div);
+ __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
+
+ __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL);
+
+ return 0;
+}
+
+static struct clk clk_mmc = {
+ .parent = &clk_armpll,
+ .set_rate = mmc_set_rate,
+ .get_rate = mmc_get_rate,
+ .round_rate = mmc_round_rate,
+ .enable = mmc_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_MS_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
+};
+
+static unsigned long clcd_get_rate(struct clk *clk)
+{
+ u32 tmp, div, rate, oldclk;
+
+ /* The LCD clock must be on when accessing an LCD register */
+ oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
+ __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
+ LPC32XX_CLKPWR_LCDCLK_CTRL);
+ tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
+ __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
+
+ rate = clk->parent->get_rate(clk->parent);
+
+ /* Only supports internal clocking */
+ if (tmp & TIM2_BCD)
+ return rate;
+
+ div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22);
+ tmp = rate / (2 + div);
+
+ return tmp;
+}
+
+static int clcd_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 tmp, prate, div, oldclk;
+
+ /* The LCD clock must be on when accessing an LCD register */
+ oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
+ __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
+ LPC32XX_CLKPWR_LCDCLK_CTRL);
+
+ tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD;
+ prate = clk->parent->get_rate(clk->parent);
+
+ if (rate < prate) {
+ /* Find closest divider */
+ div = prate / rate;
+ if (div >= 2) {
+ div -= 2;
+ tmp &= ~TIM2_BCD;
+ }
+
+ tmp &= ~(0xF800001F);
+ tmp |= (div & 0x1F);
+ tmp |= (((div >> 5) & 0x1F) << 27);
+ }
+
+ __raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
+ __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
+
+ return 0;
+}
+
+static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 prate, div;
+
+ prate = clk->parent->get_rate(clk->parent);
+
+ if (rate >= prate)
+ rate = prate;
+ else {
+ div = prate / rate;
+ if (div > 0x3ff)
+ div = 0x3ff;
+
+ rate = prate / div;
+ }
+
+ return rate;
+}
+
+static struct clk clk_lcd = {
+ .parent = &clk_hclk,
+ .set_rate = clcd_set_rate,
+ .get_rate = clcd_get_rate,
+ .round_rate = clcd_round_rate,
+ .enable = local_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_LCDCLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
+};
+
+static inline void clk_lock(void)
+{
+ mutex_lock(&clkm_lock);
+}
+
+static inline void clk_unlock(void)
+{
+ mutex_unlock(&clkm_lock);
+}
+
+static void local_clk_disable(struct clk *clk)
+{
+ WARN_ON(clk->usecount == 0);
+
+ /* Don't attempt to disable clock if it has no users */
+ if (clk->usecount > 0) {
+ clk->usecount--;
+
+ /* Only disable clock when it has no more users */
+ if ((clk->usecount == 0) && (clk->enable))
+ clk->enable(clk, 0);
+
+ /* Check parent clocks, they may need to be disabled too */
+ if (clk->parent)
+ local_clk_disable(clk->parent);
+ }
+}
+
+static int local_clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ /* Enable parent clocks first and update use counts */
+ if (clk->parent)
+ ret = local_clk_enable(clk->parent);
+
+ if (!ret) {
+ /* Only enable clock if it's currently disabled */
+ if ((clk->usecount == 0) && (clk->enable))
+ ret = clk->enable(clk, 1);
+
+ if (!ret)
+ clk->usecount++;
+ else if (clk->parent)
+ local_clk_disable(clk->parent);
+ }
+
+ return ret;
+}
+
+/*
+ * clk_enable - inform the system when the clock source should be running.
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret;
+
+ clk_lock();
+ ret = local_clk_enable(clk);
+ clk_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/*
+ * clk_disable - inform the system when the clock source is no longer required
+ */
+void clk_disable(struct clk *clk)
+{
+ clk_lock();
+ local_clk_disable(clk);
+ clk_unlock();
+}
+EXPORT_SYMBOL(clk_disable);
+
+/*
+ * clk_get_rate - obtain the current clock rate (in Hz) for a clock source
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ clk_lock();
+ rate = clk->get_rate(clk);
+ clk_unlock();
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/*
+ * clk_set_rate - set the clock rate for a clock source
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ /*
+ * Most system clocks can only be enabled or disabled, with
+ * the actual rate set as part of the peripheral dividers
+ * instead of high level clock control
+ */
+ if (clk->set_rate) {
+ clk_lock();
+ ret = clk->set_rate(clk, rate);
+ clk_unlock();
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * clk_round_rate - adjust a rate to the exact rate a clock can provide
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ clk_lock();
+
+ if (clk->round_rate)
+ rate = clk->round_rate(clk, rate);
+ else
+ rate = clk->get_rate(clk);
+
+ clk_unlock();
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/*
+ * clk_set_parent - set the parent clock source for this clock
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ /* Clock re-parenting is not supported */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/*
+ * clk_get_parent - get the parent clock source for this clock
+ */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = (d), \
+ .con_id = (n), \
+ .clk = &(c), \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "osc_32KHz", osc_32KHz)
+ _REGISTER_CLOCK(NULL, "osc_pll397", osc_pll397)
+ _REGISTER_CLOCK(NULL, "osc_main", osc_main)
+ _REGISTER_CLOCK(NULL, "sys_ck", clk_sys)
+ _REGISTER_CLOCK(NULL, "arm_pll_ck", clk_armpll)
+ _REGISTER_CLOCK(NULL, "ck_pll5", clk_usbpll)
+ _REGISTER_CLOCK(NULL, "hclk_ck", clk_hclk)
+ _REGISTER_CLOCK(NULL, "pclk_ck", clk_pclk)
+ _REGISTER_CLOCK(NULL, "timer0_ck", clk_timer0)
+ _REGISTER_CLOCK(NULL, "timer1_ck", clk_timer1)
+ _REGISTER_CLOCK(NULL, "timer2_ck", clk_timer2)
+ _REGISTER_CLOCK(NULL, "timer3_ck", clk_timer3)
+ _REGISTER_CLOCK(NULL, "vfp9_ck", clk_vfp9)
+ _REGISTER_CLOCK(NULL, "clk_dmac", clk_dma)
+ _REGISTER_CLOCK("pnx4008-watchdog", NULL, clk_wdt)
+ _REGISTER_CLOCK(NULL, "uart3_ck", clk_uart3)
+ _REGISTER_CLOCK(NULL, "uart4_ck", clk_uart4)
+ _REGISTER_CLOCK(NULL, "uart5_ck", clk_uart5)
+ _REGISTER_CLOCK(NULL, "uart6_ck", clk_uart6)
+ _REGISTER_CLOCK("pnx-i2c.0", NULL, clk_i2c0)
+ _REGISTER_CLOCK("pnx-i2c.1", NULL, clk_i2c1)
+ _REGISTER_CLOCK("pnx-i2c.2", NULL, clk_i2c2)
+ _REGISTER_CLOCK("dev:ssp0", NULL, clk_ssp0)
+ _REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1)
+ _REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
+ _REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
+ _REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0)
+ _REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1)
+ _REGISTER_CLOCK("lpc32xx-ts", NULL, clk_tsc)
+ _REGISTER_CLOCK("dev:mmc0", "MCLK", clk_mmc)
+ _REGISTER_CLOCK("lpc-net.0", NULL, clk_net)
+ _REGISTER_CLOCK("dev:clcd", NULL, clk_lcd)
+ _REGISTER_CLOCK("lpc32xx_udc", "ck_usbd", clk_usbd)
+ _REGISTER_CLOCK("lpc32xx_rtc", NULL, clk_rtc)
+};
+
+static int __init clk_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
+
+ /*
+ * Setup muxed SYSCLK for HCLK PLL base -this selects the
+ * parent clock used for the ARM PLL and is used to derive
+ * the many system clock rates in the device.
+ */
+ if (clk_is_sysclk_mainosc() != 0)
+ clk_sys.parent = &osc_main;
+ else
+ clk_sys.parent = &osc_pll397;
+
+ clk_sys.rate = clk_sys.parent->rate;
+
+ /* Compute the current ARM PLL and USB PLL frequencies */
+ local_update_armpll_rate();
+
+ /* Compute HCLK and PCLK bus rates */
+ clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div();
+ clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div();
+
+ /*
+ * Enable system clocks - this step is somewhat formal, as the
+ * clocks are already running, but it does get the clock data
+ * inline with the actual system state. Never disable these
+ * clocks as they will only stop if the system is going to sleep.
+ * In that case, the chip/system power management functions will
+ * handle clock gating.
+ */
+ if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk))
+ printk(KERN_ERR "Error enabling system HCLK and PCLK\n");
+
+ /*
+ * Timers 0 and 1 were enabled and are being used by the high
+ * resolution tick function prior to this driver being initialized.
+ * Tag them now as used.
+ */
+ if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1))
+ printk(KERN_ERR "Error enabling timer tick clocks\n");
+
+ return 0;
+}
+core_initcall(clk_init);
+
diff --git a/arch/arm/mach-lpc32xx/clock.h b/arch/arm/mach-lpc32xx/clock.h
new file mode 100644
index 00000000..c0a84343
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/clock.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-lpc32xx/clock.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __LPC32XX_CLOCK_H
+#define __LPC32XX_CLOCK_H
+
+struct clk {
+ struct list_head node;
+ struct clk *parent;
+ u32 rate;
+ u32 usecount;
+
+ int (*set_rate) (struct clk *, unsigned long);
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ unsigned long (*get_rate) (struct clk *clk);
+ int (*enable) (struct clk *, int);
+
+ /* Register address and bit mask for simple clocks */
+ void __iomem *enable_reg;
+ u32 enable_mask;
+};
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
new file mode 100644
index 00000000..ee24dc28
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -0,0 +1,271 @@
+/*
+ * arch/arm/mach-lpc32xx/common.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/i2c-pnx.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/i2c.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+/*
+ * Watchdog timer
+ */
+static struct resource watchdog_resources[] = {
+ [0] = {
+ .start = LPC32XX_WDTIM_BASE,
+ .end = LPC32XX_WDTIM_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device lpc32xx_watchdog_device = {
+ .name = "pnx4008-watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(watchdog_resources),
+ .resource = watchdog_resources,
+};
+
+/*
+ * I2C busses
+ */
+static struct i2c_pnx_data i2c0_data = {
+ .name = I2C_CHIP_NAME "1",
+ .base = LPC32XX_I2C1_BASE,
+ .irq = IRQ_LPC32XX_I2C_1,
+};
+
+static struct i2c_pnx_data i2c1_data = {
+ .name = I2C_CHIP_NAME "2",
+ .base = LPC32XX_I2C2_BASE,
+ .irq = IRQ_LPC32XX_I2C_2,
+};
+
+static struct i2c_pnx_data i2c2_data = {
+ .name = "USB-I2C",
+ .base = LPC32XX_OTG_I2C_BASE,
+ .irq = IRQ_LPC32XX_USB_I2C,
+};
+
+struct platform_device lpc32xx_i2c0_device = {
+ .name = "pnx-i2c",
+ .id = 0,
+ .dev = {
+ .platform_data = &i2c0_data,
+ },
+};
+
+struct platform_device lpc32xx_i2c1_device = {
+ .name = "pnx-i2c",
+ .id = 1,
+ .dev = {
+ .platform_data = &i2c1_data,
+ },
+};
+
+struct platform_device lpc32xx_i2c2_device = {
+ .name = "pnx-i2c",
+ .id = 2,
+ .dev = {
+ .platform_data = &i2c2_data,
+ },
+};
+
+/*
+ * Returns the unique ID for the device
+ */
+void lpc32xx_get_uid(u32 devid[4])
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2));
+}
+
+/*
+ * Returns SYSCLK source
+ * 0 = PLL397, 1 = main oscillator
+ */
+int clk_is_sysclk_mainosc(void)
+{
+ if ((__raw_readl(LPC32XX_CLKPWR_SYSCLK_CTRL) &
+ LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX) == 0)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * System reset via the watchdog timer
+ */
+void lpc32xx_watchdog_reset(void)
+{
+ /* Make sure WDT clocks are enabled */
+ __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
+ LPC32XX_CLKPWR_TIMER_CLK_CTRL);
+
+ /* Instant assert of RESETOUT_N with pulse length 1mS */
+ __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18));
+ __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC));
+}
+
+/*
+ * Detects and returns IRAM size for the device variation
+ */
+#define LPC32XX_IRAM_BANK_SIZE SZ_128K
+static u32 iram_size;
+u32 lpc32xx_return_iram_size(void)
+{
+ if (iram_size == 0) {
+ u32 savedval1, savedval2;
+ void __iomem *iramptr1, *iramptr2;
+
+ iramptr1 = io_p2v(LPC32XX_IRAM_BASE);
+ iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE);
+ savedval1 = __raw_readl(iramptr1);
+ savedval2 = __raw_readl(iramptr2);
+
+ if (savedval1 == savedval2) {
+ __raw_writel(savedval2 + 1, iramptr2);
+ if (__raw_readl(iramptr1) == savedval2 + 1)
+ iram_size = LPC32XX_IRAM_BANK_SIZE;
+ else
+ iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
+ __raw_writel(savedval2, iramptr2);
+ } else
+ iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
+ }
+
+ return iram_size;
+}
+
+/*
+ * Computes PLL rate from PLL register and input clock
+ */
+u32 clk_check_pll_setup(u32 ifreq, struct clk_pll_setup *pllsetup)
+{
+ u32 ilfreq, p, m, n, fcco, fref, cfreq;
+ int mode;
+
+ /*
+ * PLL requirements
+ * ifreq must be >= 1MHz and <= 20MHz
+ * FCCO must be >= 156MHz and <= 320MHz
+ * FREF must be >= 1MHz and <= 27MHz
+ * Assume the passed input data is not valid
+ */
+
+ ilfreq = ifreq;
+ m = pllsetup->pll_m;
+ n = pllsetup->pll_n;
+ p = pllsetup->pll_p;
+
+ mode = (pllsetup->cco_bypass_b15 << 2) |
+ (pllsetup->direct_output_b14 << 1) |
+ pllsetup->fdbk_div_ctrl_b13;
+
+ switch (mode) {
+ case 0x0: /* Non-integer mode */
+ cfreq = (m * ilfreq) / (2 * p * n);
+ fcco = (m * ilfreq) / n;
+ fref = ilfreq / n;
+ break;
+
+ case 0x1: /* integer mode */
+ cfreq = (m * ilfreq) / n;
+ fcco = (m * ilfreq) / (n * 2 * p);
+ fref = ilfreq / n;
+ break;
+
+ case 0x2:
+ case 0x3: /* Direct mode */
+ cfreq = (m * ilfreq) / n;
+ fcco = cfreq;
+ fref = ilfreq / n;
+ break;
+
+ case 0x4:
+ case 0x5: /* Bypass mode */
+ cfreq = ilfreq / (2 * p);
+ fcco = 156000000;
+ fref = 1000000;
+ break;
+
+ case 0x6:
+ case 0x7: /* Direct bypass mode */
+ default:
+ cfreq = ilfreq;
+ fcco = 156000000;
+ fref = 1000000;
+ break;
+ }
+
+ if (fcco < 156000000 || fcco > 320000000)
+ cfreq = 0;
+
+ if (fref < 1000000 || fref > 27000000)
+ cfreq = 0;
+
+ return (u32) cfreq;
+}
+
+u32 clk_get_pclk_div(void)
+{
+ return 1 + ((__raw_readl(LPC32XX_CLKPWR_HCLK_DIV) >> 2) & 0x1F);
+}
+
+static struct map_desc lpc32xx_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(LPC32XX_AHB0_START),
+ .pfn = __phys_to_pfn(LPC32XX_AHB0_START),
+ .length = LPC32XX_AHB0_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = IO_ADDRESS(LPC32XX_AHB1_START),
+ .pfn = __phys_to_pfn(LPC32XX_AHB1_START),
+ .length = LPC32XX_AHB1_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = IO_ADDRESS(LPC32XX_FABAPB_START),
+ .pfn = __phys_to_pfn(LPC32XX_FABAPB_START),
+ .length = LPC32XX_FABAPB_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = IO_ADDRESS(LPC32XX_IRAM_BASE),
+ .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE),
+ .length = (LPC32XX_IRAM_BANK_SIZE * 2),
+ .type = MT_DEVICE
+ },
+};
+
+void __init lpc32xx_map_io(void)
+{
+ iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc));
+}
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
new file mode 100644
index 00000000..f82211fd
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/mach-lpc32xx/common.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2009-2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __LPC32XX_COMMON_H
+#define __LPC32XX_COMMON_H
+
+#include <linux/platform_device.h>
+
+/*
+ * Arch specific platform device structures
+ */
+extern struct platform_device lpc32xx_watchdog_device;
+extern struct platform_device lpc32xx_i2c0_device;
+extern struct platform_device lpc32xx_i2c1_device;
+extern struct platform_device lpc32xx_i2c2_device;
+
+/*
+ * Other arch specific structures and functions
+ */
+extern struct sys_timer lpc32xx_timer;
+extern void __init lpc32xx_init_irq(void);
+extern void __init lpc32xx_map_io(void);
+extern void __init lpc32xx_serial_init(void);
+extern void __init lpc32xx_gpio_init(void);
+
+/*
+ * Structure used for setting up and querying the PLLS
+ */
+struct clk_pll_setup {
+ int analog_on;
+ int cco_bypass_b15;
+ int direct_output_b14;
+ int fdbk_div_ctrl_b13;
+ int pll_p;
+ int pll_n;
+ u32 pll_m;
+};
+
+extern int clk_is_sysclk_mainosc(void);
+extern u32 clk_check_pll_setup(u32 ifreq, struct clk_pll_setup *pllsetup);
+extern u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval);
+extern u32 clk_get_pclk_div(void);
+
+/*
+ * Returns the LPC32xx unique 128-bit chip ID
+ */
+extern void lpc32xx_get_uid(u32 devid[4]);
+
+extern void lpc32xx_watchdog_reset(void);
+extern u32 lpc32xx_return_iram_size(void);
+
+/*
+ * Pointers used for sizing and copying suspend function data
+ */
+extern int lpc32xx_sys_suspend(void);
+extern int lpc32xx_sys_suspend_sz;
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/gpiolib.c b/arch/arm/mach-lpc32xx/gpiolib.c
new file mode 100644
index 00000000..69061ea8
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/gpiolib.c
@@ -0,0 +1,446 @@
+/*
+ * arch/arm/mach-lpc32xx/gpiolib.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+#define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000)
+#define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004)
+#define LPC32XX_GPIO_P3_OUTP_CLR _GPREG(0x008)
+#define LPC32XX_GPIO_P3_OUTP_STATE _GPREG(0x00C)
+#define LPC32XX_GPIO_P2_DIR_SET _GPREG(0x010)
+#define LPC32XX_GPIO_P2_DIR_CLR _GPREG(0x014)
+#define LPC32XX_GPIO_P2_DIR_STATE _GPREG(0x018)
+#define LPC32XX_GPIO_P2_INP_STATE _GPREG(0x01C)
+#define LPC32XX_GPIO_P2_OUTP_SET _GPREG(0x020)
+#define LPC32XX_GPIO_P2_OUTP_CLR _GPREG(0x024)
+#define LPC32XX_GPIO_P2_MUX_SET _GPREG(0x028)
+#define LPC32XX_GPIO_P2_MUX_CLR _GPREG(0x02C)
+#define LPC32XX_GPIO_P2_MUX_STATE _GPREG(0x030)
+#define LPC32XX_GPIO_P0_INP_STATE _GPREG(0x040)
+#define LPC32XX_GPIO_P0_OUTP_SET _GPREG(0x044)
+#define LPC32XX_GPIO_P0_OUTP_CLR _GPREG(0x048)
+#define LPC32XX_GPIO_P0_OUTP_STATE _GPREG(0x04C)
+#define LPC32XX_GPIO_P0_DIR_SET _GPREG(0x050)
+#define LPC32XX_GPIO_P0_DIR_CLR _GPREG(0x054)
+#define LPC32XX_GPIO_P0_DIR_STATE _GPREG(0x058)
+#define LPC32XX_GPIO_P1_INP_STATE _GPREG(0x060)
+#define LPC32XX_GPIO_P1_OUTP_SET _GPREG(0x064)
+#define LPC32XX_GPIO_P1_OUTP_CLR _GPREG(0x068)
+#define LPC32XX_GPIO_P1_OUTP_STATE _GPREG(0x06C)
+#define LPC32XX_GPIO_P1_DIR_SET _GPREG(0x070)
+#define LPC32XX_GPIO_P1_DIR_CLR _GPREG(0x074)
+#define LPC32XX_GPIO_P1_DIR_STATE _GPREG(0x078)
+
+#define GPIO012_PIN_TO_BIT(x) (1 << (x))
+#define GPIO3_PIN_TO_BIT(x) (1 << ((x) + 25))
+#define GPO3_PIN_TO_BIT(x) (1 << (x))
+#define GPIO012_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
+#define GPIO3_PIN_IN_SHIFT(x) ((x) == 5 ? 24 : 10 + (x))
+#define GPIO3_PIN_IN_SEL(x, y) ((x) >> GPIO3_PIN_IN_SHIFT(y))
+#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1)
+#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
+
+struct gpio_regs {
+ void __iomem *inp_state;
+ void __iomem *outp_set;
+ void __iomem *outp_clr;
+ void __iomem *dir_set;
+ void __iomem *dir_clr;
+};
+
+/*
+ * GPIO names
+ */
+static const char *gpio_p0_names[LPC32XX_GPIO_P0_MAX] = {
+ "p0.0", "p0.1", "p0.2", "p0.3",
+ "p0.4", "p0.5", "p0.6", "p0.7"
+};
+
+static const char *gpio_p1_names[LPC32XX_GPIO_P1_MAX] = {
+ "p1.0", "p1.1", "p1.2", "p1.3",
+ "p1.4", "p1.5", "p1.6", "p1.7",
+ "p1.8", "p1.9", "p1.10", "p1.11",
+ "p1.12", "p1.13", "p1.14", "p1.15",
+ "p1.16", "p1.17", "p1.18", "p1.19",
+ "p1.20", "p1.21", "p1.22", "p1.23",
+};
+
+static const char *gpio_p2_names[LPC32XX_GPIO_P2_MAX] = {
+ "p2.0", "p2.1", "p2.2", "p2.3",
+ "p2.4", "p2.5", "p2.6", "p2.7",
+ "p2.8", "p2.9", "p2.10", "p2.11",
+ "p2.12"
+};
+
+static const char *gpio_p3_names[LPC32XX_GPIO_P3_MAX] = {
+ "gpi000", "gpio01", "gpio02", "gpio03",
+ "gpio04", "gpio05"
+};
+
+static const char *gpi_p3_names[LPC32XX_GPI_P3_MAX] = {
+ "gpi00", "gpi01", "gpi02", "gpi03",
+ "gpi04", "gpi05", "gpi06", "gpi07",
+ "gpi08", "gpi09", NULL, NULL,
+ NULL, NULL, NULL, "gpi15",
+ "gpi16", "gpi17", "gpi18", "gpi19",
+ "gpi20", "gpi21", "gpi22", "gpi23",
+ "gpi24", "gpi25", "gpi26", "gpi27"
+};
+
+static const char *gpo_p3_names[LPC32XX_GPO_P3_MAX] = {
+ "gpo00", "gpo01", "gpo02", "gpo03",
+ "gpo04", "gpo05", "gpo06", "gpo07",
+ "gpo08", "gpo09", "gpo10", "gpo11",
+ "gpo12", "gpo13", "gpo14", "gpo15",
+ "gpo16", "gpo17", "gpo18", "gpo19",
+ "gpo20", "gpo21", "gpo22", "gpo23"
+};
+
+static struct gpio_regs gpio_grp_regs_p0 = {
+ .inp_state = LPC32XX_GPIO_P0_INP_STATE,
+ .outp_set = LPC32XX_GPIO_P0_OUTP_SET,
+ .outp_clr = LPC32XX_GPIO_P0_OUTP_CLR,
+ .dir_set = LPC32XX_GPIO_P0_DIR_SET,
+ .dir_clr = LPC32XX_GPIO_P0_DIR_CLR,
+};
+
+static struct gpio_regs gpio_grp_regs_p1 = {
+ .inp_state = LPC32XX_GPIO_P1_INP_STATE,
+ .outp_set = LPC32XX_GPIO_P1_OUTP_SET,
+ .outp_clr = LPC32XX_GPIO_P1_OUTP_CLR,
+ .dir_set = LPC32XX_GPIO_P1_DIR_SET,
+ .dir_clr = LPC32XX_GPIO_P1_DIR_CLR,
+};
+
+static struct gpio_regs gpio_grp_regs_p2 = {
+ .inp_state = LPC32XX_GPIO_P2_INP_STATE,
+ .outp_set = LPC32XX_GPIO_P2_OUTP_SET,
+ .outp_clr = LPC32XX_GPIO_P2_OUTP_CLR,
+ .dir_set = LPC32XX_GPIO_P2_DIR_SET,
+ .dir_clr = LPC32XX_GPIO_P2_DIR_CLR,
+};
+
+static struct gpio_regs gpio_grp_regs_p3 = {
+ .inp_state = LPC32XX_GPIO_P3_INP_STATE,
+ .outp_set = LPC32XX_GPIO_P3_OUTP_SET,
+ .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR,
+ .dir_set = LPC32XX_GPIO_P2_DIR_SET,
+ .dir_clr = LPC32XX_GPIO_P2_DIR_CLR,
+};
+
+struct lpc32xx_gpio_chip {
+ struct gpio_chip chip;
+ struct gpio_regs *gpio_grp;
+};
+
+static inline struct lpc32xx_gpio_chip *to_lpc32xx_gpio(
+ struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct lpc32xx_gpio_chip, chip);
+}
+
+static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
+ unsigned pin, int input)
+{
+ if (input)
+ __raw_writel(GPIO012_PIN_TO_BIT(pin),
+ group->gpio_grp->dir_clr);
+ else
+ __raw_writel(GPIO012_PIN_TO_BIT(pin),
+ group->gpio_grp->dir_set);
+}
+
+static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
+ unsigned pin, int input)
+{
+ u32 u = GPIO3_PIN_TO_BIT(pin);
+
+ if (input)
+ __raw_writel(u, group->gpio_grp->dir_clr);
+ else
+ __raw_writel(u, group->gpio_grp->dir_set);
+}
+
+static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
+ unsigned pin, int high)
+{
+ if (high)
+ __raw_writel(GPIO012_PIN_TO_BIT(pin),
+ group->gpio_grp->outp_set);
+ else
+ __raw_writel(GPIO012_PIN_TO_BIT(pin),
+ group->gpio_grp->outp_clr);
+}
+
+static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
+ unsigned pin, int high)
+{
+ u32 u = GPIO3_PIN_TO_BIT(pin);
+
+ if (high)
+ __raw_writel(u, group->gpio_grp->outp_set);
+ else
+ __raw_writel(u, group->gpio_grp->outp_clr);
+}
+
+static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
+ unsigned pin, int high)
+{
+ if (high)
+ __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
+ else
+ __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
+}
+
+static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
+ unsigned pin)
+{
+ return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
+ pin);
+}
+
+static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
+ unsigned pin)
+{
+ int state = __raw_readl(group->gpio_grp->inp_state);
+
+ /*
+ * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
+ * to bits 10..14, while GPIOP3-5 is mapped to bit 24.
+ */
+ return GPIO3_PIN_IN_SEL(state, pin);
+}
+
+static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
+ unsigned pin)
+{
+ return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
+}
+
+/*
+ * GENERIC_GPIO primitives.
+ */
+static int lpc32xx_gpio_dir_input_p012(struct gpio_chip *chip,
+ unsigned pin)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_dir_p012(group, pin, 1);
+
+ return 0;
+}
+
+static int lpc32xx_gpio_dir_input_p3(struct gpio_chip *chip,
+ unsigned pin)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_dir_p3(group, pin, 1);
+
+ return 0;
+}
+
+static int lpc32xx_gpio_dir_in_always(struct gpio_chip *chip,
+ unsigned pin)
+{
+ return 0;
+}
+
+static int lpc32xx_gpio_get_value_p012(struct gpio_chip *chip, unsigned pin)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ return __get_gpio_state_p012(group, pin);
+}
+
+static int lpc32xx_gpio_get_value_p3(struct gpio_chip *chip, unsigned pin)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ return __get_gpio_state_p3(group, pin);
+}
+
+static int lpc32xx_gpi_get_value(struct gpio_chip *chip, unsigned pin)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ return __get_gpi_state_p3(group, pin);
+}
+
+static int lpc32xx_gpio_dir_output_p012(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_dir_p012(group, pin, 0);
+
+ return 0;
+}
+
+static int lpc32xx_gpio_dir_output_p3(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_dir_p3(group, pin, 0);
+
+ return 0;
+}
+
+static int lpc32xx_gpio_dir_out_always(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ return 0;
+}
+
+static void lpc32xx_gpio_set_value_p012(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_level_p012(group, pin, value);
+}
+
+static void lpc32xx_gpio_set_value_p3(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpio_level_p3(group, pin, value);
+}
+
+static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
+ int value)
+{
+ struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
+
+ __set_gpo_level_p3(group, pin, value);
+}
+
+static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
+{
+ if (pin < chip->ngpio)
+ return 0;
+
+ return -EINVAL;
+}
+
+static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
+ {
+ .chip = {
+ .label = "gpio_p0",
+ .direction_input = lpc32xx_gpio_dir_input_p012,
+ .get = lpc32xx_gpio_get_value_p012,
+ .direction_output = lpc32xx_gpio_dir_output_p012,
+ .set = lpc32xx_gpio_set_value_p012,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPIO_P0_GRP,
+ .ngpio = LPC32XX_GPIO_P0_MAX,
+ .names = gpio_p0_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p0,
+ },
+ {
+ .chip = {
+ .label = "gpio_p1",
+ .direction_input = lpc32xx_gpio_dir_input_p012,
+ .get = lpc32xx_gpio_get_value_p012,
+ .direction_output = lpc32xx_gpio_dir_output_p012,
+ .set = lpc32xx_gpio_set_value_p012,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPIO_P1_GRP,
+ .ngpio = LPC32XX_GPIO_P1_MAX,
+ .names = gpio_p1_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p1,
+ },
+ {
+ .chip = {
+ .label = "gpio_p2",
+ .direction_input = lpc32xx_gpio_dir_input_p012,
+ .get = lpc32xx_gpio_get_value_p012,
+ .direction_output = lpc32xx_gpio_dir_output_p012,
+ .set = lpc32xx_gpio_set_value_p012,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPIO_P2_GRP,
+ .ngpio = LPC32XX_GPIO_P2_MAX,
+ .names = gpio_p2_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p2,
+ },
+ {
+ .chip = {
+ .label = "gpio_p3",
+ .direction_input = lpc32xx_gpio_dir_input_p3,
+ .get = lpc32xx_gpio_get_value_p3,
+ .direction_output = lpc32xx_gpio_dir_output_p3,
+ .set = lpc32xx_gpio_set_value_p3,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPIO_P3_GRP,
+ .ngpio = LPC32XX_GPIO_P3_MAX,
+ .names = gpio_p3_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p3,
+ },
+ {
+ .chip = {
+ .label = "gpi_p3",
+ .direction_input = lpc32xx_gpio_dir_in_always,
+ .get = lpc32xx_gpi_get_value,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPI_P3_GRP,
+ .ngpio = LPC32XX_GPI_P3_MAX,
+ .names = gpi_p3_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p3,
+ },
+ {
+ .chip = {
+ .label = "gpo_p3",
+ .direction_output = lpc32xx_gpio_dir_out_always,
+ .set = lpc32xx_gpo_set_value,
+ .request = lpc32xx_gpio_request,
+ .base = LPC32XX_GPO_P3_GRP,
+ .ngpio = LPC32XX_GPO_P3_MAX,
+ .names = gpo_p3_names,
+ .can_sleep = 0,
+ },
+ .gpio_grp = &gpio_grp_regs_p3,
+ },
+};
+
+void __init lpc32xx_gpio_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++)
+ gpiochip_add(&lpc32xx_gpiochip[i].chip);
+}
diff --git a/arch/arm/mach-lpc32xx/include/mach/clkdev.h b/arch/arm/mach-lpc32xx/include/mach/clkdev.h
new file mode 100644
index 00000000..9bf0637e
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/clkdev.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/clkdev.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_CLKDEV_H
+#define __ASM_ARCH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/debug-macro.S b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..629e744a
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/debug-macro.S
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/debug-macro.S
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+/*
+ * Debug output is hardcoded to standard UART 5
+*/
+
+ .macro addruart, rp, rv
+ ldreq \rp, =0x40090000
+ ldrne \rv, =0xF4090000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..870227c9
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/entry-macro.S
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#define LPC32XX_INTC_MASKED_STATUS_OFS 0x8
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IO_ADDRESS(LPC32XX_MIC_BASE)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+/*
+ * Return IRQ number in irqnr. Also return processor Z flag status in CPSR
+ * as set if an interrupt is pending.
+ */
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #LPC32XX_INTC_MASKED_STATUS_OFS]
+ clz \irqnr, \irqstat
+ rsb \irqnr, \irqnr, #31
+ teq \irqstat, #0
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
diff --git a/arch/arm/mach-lpc32xx/include/mach/gpio.h b/arch/arm/mach-lpc32xx/include/mach/gpio.h
new file mode 100644
index 00000000..67d03da1
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/gpio.h
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/gpio.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+/*
+ * Note!
+ * Muxed GP pins need to be setup to the GP state in the board level
+ * code prior to using this driver.
+ * GPI pins : 28xP3 group
+ * GPO pins : 24xP3 group
+ * GPIO pins: 8xP0 group, 24xP1 group, 13xP2 group, 6xP3 group
+ */
+
+#define LPC32XX_GPIO_P0_MAX 8
+#define LPC32XX_GPIO_P1_MAX 24
+#define LPC32XX_GPIO_P2_MAX 13
+#define LPC32XX_GPIO_P3_MAX 6
+#define LPC32XX_GPI_P3_MAX 28
+#define LPC32XX_GPO_P3_MAX 24
+
+#define LPC32XX_GPIO_P0_GRP 0
+#define LPC32XX_GPIO_P1_GRP (LPC32XX_GPIO_P0_GRP + LPC32XX_GPIO_P0_MAX)
+#define LPC32XX_GPIO_P2_GRP (LPC32XX_GPIO_P1_GRP + LPC32XX_GPIO_P1_MAX)
+#define LPC32XX_GPIO_P3_GRP (LPC32XX_GPIO_P2_GRP + LPC32XX_GPIO_P2_MAX)
+#define LPC32XX_GPI_P3_GRP (LPC32XX_GPIO_P3_GRP + LPC32XX_GPIO_P3_MAX)
+#define LPC32XX_GPO_P3_GRP (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
+
+/*
+ * A specific GPIO can be selected with this macro
+ * ie, GPIO_05 can be selected with LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
+ * See the LPC32x0 User's guide for GPIO group numbers
+ */
+#define LPC32XX_GPIO(x, y) ((x) + (y))
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/hardware.h b/arch/arm/mach-lpc32xx/include/mach/hardware.h
new file mode 100644
index 00000000..33e1dde3
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/hardware.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/hardware.h
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.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.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/*
+ * Start of virtual addresses for IO devices
+ */
+#define IO_BASE 0xF0000000
+
+/*
+ * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
+ */
+#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
+ IO_BASE)
+
+#define io_p2v(x) ((void __iomem *) (unsigned long) IO_ADDRESS(x))
+#define io_v2p(x) ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/i2c.h b/arch/arm/mach-lpc32xx/include/mach/i2c.h
new file mode 100644
index 00000000..034dc928
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/i2c.h
@@ -0,0 +1,63 @@
+/*
+ * PNX4008-specific tweaks for I2C IP3204 block
+ *
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARCH_I2C_H
+#define __ASM_ARCH_I2C_H
+
+enum {
+ mstatus_tdi = 0x00000001,
+ mstatus_afi = 0x00000002,
+ mstatus_nai = 0x00000004,
+ mstatus_drmi = 0x00000008,
+ mstatus_active = 0x00000020,
+ mstatus_scl = 0x00000040,
+ mstatus_sda = 0x00000080,
+ mstatus_rff = 0x00000100,
+ mstatus_rfe = 0x00000200,
+ mstatus_tff = 0x00000400,
+ mstatus_tfe = 0x00000800,
+};
+
+enum {
+ mcntrl_tdie = 0x00000001,
+ mcntrl_afie = 0x00000002,
+ mcntrl_naie = 0x00000004,
+ mcntrl_drmie = 0x00000008,
+ mcntrl_daie = 0x00000020,
+ mcntrl_rffie = 0x00000040,
+ mcntrl_tffie = 0x00000080,
+ mcntrl_reset = 0x00000100,
+ mcntrl_cdbmode = 0x00000400,
+};
+
+enum {
+ rw_bit = 1 << 0,
+ start_bit = 1 << 8,
+ stop_bit = 1 << 9,
+};
+
+#define I2C_REG_RX(a) ((a)->ioaddr) /* Rx FIFO reg (RO) */
+#define I2C_REG_TX(a) ((a)->ioaddr) /* Tx FIFO reg (WO) */
+#define I2C_REG_STS(a) ((a)->ioaddr + 0x04) /* Status reg (RO) */
+#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08) /* Ctl reg */
+#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c) /* Clock divider low */
+#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10) /* Clock divider high */
+#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14) /* I2C address */
+#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18) /* Rx FIFO level (RO) */
+#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c) /* Tx FIFO level (RO) */
+#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20) /* Num of bytes Rx-ed (RO) */
+#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24) /* Num of bytes Tx-ed (RO) */
+#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28) /* Tx slave FIFO (RO) */
+#define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c) /* Tx slave FIFO level (RO) */
+
+#define I2C_CHIP_NAME "PNX4008-I2C"
+
+#endif /* __ASM_ARCH_I2C_H */
diff --git a/arch/arm/mach-lpc32xx/include/mach/io.h b/arch/arm/mach-lpc32xx/include/mach/io.h
new file mode 100644
index 00000000..9b59ab5c
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/io.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/io.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h
new file mode 100644
index 00000000..9e3b90df
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/irqs.h
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/irqs.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_ARCH_IRQS_H
+#define __ASM_ARM_ARCH_IRQS_H
+
+#define LPC32XX_SIC1_IRQ(n) (32 + (n))
+#define LPC32XX_SIC2_IRQ(n) (64 + (n))
+
+/*
+ * MIC interrupts
+ */
+#define IRQ_LPC32XX_SUB1IRQ 0
+#define IRQ_LPC32XX_SUB2IRQ 1
+#define IRQ_LPC32XX_PWM3 3
+#define IRQ_LPC32XX_PWM4 4
+#define IRQ_LPC32XX_HSTIMER 5
+#define IRQ_LPC32XX_WATCH 6
+#define IRQ_LPC32XX_UART_IIR3 7
+#define IRQ_LPC32XX_UART_IIR4 8
+#define IRQ_LPC32XX_UART_IIR5 9
+#define IRQ_LPC32XX_UART_IIR6 10
+#define IRQ_LPC32XX_FLASH 11
+#define IRQ_LPC32XX_SD1 13
+#define IRQ_LPC32XX_LCD 14
+#define IRQ_LPC32XX_SD0 15
+#define IRQ_LPC32XX_TIMER0 16
+#define IRQ_LPC32XX_TIMER1 17
+#define IRQ_LPC32XX_TIMER2 18
+#define IRQ_LPC32XX_TIMER3 19
+#define IRQ_LPC32XX_SSP0 20
+#define IRQ_LPC32XX_SSP1 21
+#define IRQ_LPC32XX_I2S0 22
+#define IRQ_LPC32XX_I2S1 23
+#define IRQ_LPC32XX_UART_IIR7 24
+#define IRQ_LPC32XX_UART_IIR2 25
+#define IRQ_LPC32XX_UART_IIR1 26
+#define IRQ_LPC32XX_MSTIMER 27
+#define IRQ_LPC32XX_DMA 28
+#define IRQ_LPC32XX_ETHERNET 29
+#define IRQ_LPC32XX_SUB1FIQ 30
+#define IRQ_LPC32XX_SUB2FIQ 31
+
+/*
+ * SIC1 interrupts start at offset 32
+ */
+#define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1)
+#define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2)
+#define IRQ_LPC32XX_GPI_28 LPC32XX_SIC1_IRQ(4)
+#define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6)
+#define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7)
+#define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8)
+#define IRQ_LPC32XX_SPI2 LPC32XX_SIC1_IRQ(12)
+#define IRQ_LPC32XX_PLLUSB LPC32XX_SIC1_IRQ(13)
+#define IRQ_LPC32XX_PLLHCLK LPC32XX_SIC1_IRQ(14)
+#define IRQ_LPC32XX_PLL397 LPC32XX_SIC1_IRQ(17)
+#define IRQ_LPC32XX_I2C_2 LPC32XX_SIC1_IRQ(18)
+#define IRQ_LPC32XX_I2C_1 LPC32XX_SIC1_IRQ(19)
+#define IRQ_LPC32XX_RTC LPC32XX_SIC1_IRQ(20)
+#define IRQ_LPC32XX_KEY LPC32XX_SIC1_IRQ(22)
+#define IRQ_LPC32XX_SPI1 LPC32XX_SIC1_IRQ(23)
+#define IRQ_LPC32XX_SW LPC32XX_SIC1_IRQ(24)
+#define IRQ_LPC32XX_USB_OTG_TIMER LPC32XX_SIC1_IRQ(25)
+#define IRQ_LPC32XX_USB_OTG_ATX LPC32XX_SIC1_IRQ(26)
+#define IRQ_LPC32XX_USB_HOST LPC32XX_SIC1_IRQ(27)
+#define IRQ_LPC32XX_USB_DEV_DMA LPC32XX_SIC1_IRQ(28)
+#define IRQ_LPC32XX_USB_DEV_LP LPC32XX_SIC1_IRQ(29)
+#define IRQ_LPC32XX_USB_DEV_HP LPC32XX_SIC1_IRQ(30)
+#define IRQ_LPC32XX_USB_I2C LPC32XX_SIC1_IRQ(31)
+
+/*
+ * SIC2 interrupts start at offset 64
+ */
+#define IRQ_LPC32XX_GPIO_00 LPC32XX_SIC2_IRQ(0)
+#define IRQ_LPC32XX_GPIO_01 LPC32XX_SIC2_IRQ(1)
+#define IRQ_LPC32XX_GPIO_02 LPC32XX_SIC2_IRQ(2)
+#define IRQ_LPC32XX_GPIO_03 LPC32XX_SIC2_IRQ(3)
+#define IRQ_LPC32XX_GPIO_04 LPC32XX_SIC2_IRQ(4)
+#define IRQ_LPC32XX_GPIO_05 LPC32XX_SIC2_IRQ(5)
+#define IRQ_LPC32XX_SPI2_DATAIN LPC32XX_SIC2_IRQ(6)
+#define IRQ_LPC32XX_U2_HCTS LPC32XX_SIC2_IRQ(7)
+#define IRQ_LPC32XX_P0_P1_IRQ LPC32XX_SIC2_IRQ(8)
+#define IRQ_LPC32XX_GPI_08 LPC32XX_SIC2_IRQ(9)
+#define IRQ_LPC32XX_GPI_09 LPC32XX_SIC2_IRQ(10)
+#define IRQ_LPC32XX_GPI_19 LPC32XX_SIC2_IRQ(11)
+#define IRQ_LPC32XX_U7_HCTS LPC32XX_SIC2_IRQ(12)
+#define IRQ_LPC32XX_GPI_07 LPC32XX_SIC2_IRQ(15)
+#define IRQ_LPC32XX_SDIO LPC32XX_SIC2_IRQ(18)
+#define IRQ_LPC32XX_U5_RX LPC32XX_SIC2_IRQ(19)
+#define IRQ_LPC32XX_SPI1_DATAIN LPC32XX_SIC2_IRQ(20)
+#define IRQ_LPC32XX_GPI_00 LPC32XX_SIC2_IRQ(22)
+#define IRQ_LPC32XX_GPI_01 LPC32XX_SIC2_IRQ(23)
+#define IRQ_LPC32XX_GPI_02 LPC32XX_SIC2_IRQ(24)
+#define IRQ_LPC32XX_GPI_03 LPC32XX_SIC2_IRQ(25)
+#define IRQ_LPC32XX_GPI_04 LPC32XX_SIC2_IRQ(26)
+#define IRQ_LPC32XX_GPI_05 LPC32XX_SIC2_IRQ(27)
+#define IRQ_LPC32XX_GPI_06 LPC32XX_SIC2_IRQ(28)
+#define IRQ_LPC32XX_SYSCLK LPC32XX_SIC2_IRQ(31)
+
+#define NR_IRQS 96
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/memory.h b/arch/arm/mach-lpc32xx/include/mach/memory.h
new file mode 100644
index 00000000..a647dd62
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/memory.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/memory.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset of bank 0
+ */
+#define PLAT_PHYS_OFFSET UL(0x80000000)
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/include/mach/platform.h
new file mode 100644
index 00000000..14ea8d1a
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/platform.h
@@ -0,0 +1,694 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/platform.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_PLATFORM_H
+#define __ASM_ARCH_PLATFORM_H
+
+#define _SBF(f, v) ((v) << (f))
+#define _BIT(n) _SBF(n, 1)
+
+/*
+ * AHB 0 physical base addresses
+ */
+#define LPC32XX_SLC_BASE 0x20020000
+#define LPC32XX_SSP0_BASE 0x20084000
+#define LPC32XX_SPI1_BASE 0x20088000
+#define LPC32XX_SSP1_BASE 0x2008C000
+#define LPC32XX_SPI2_BASE 0x20090000
+#define LPC32XX_I2S0_BASE 0x20094000
+#define LPC32XX_SD_BASE 0x20098000
+#define LPC32XX_I2S1_BASE 0x2009C000
+#define LPC32XX_MLC_BASE 0x200A8000
+#define LPC32XX_AHB0_START LPC32XX_SLC_BASE
+#define LPC32XX_AHB0_SIZE 0x00089000
+
+/*
+ * AHB 1 physical base addresses
+ */
+#define LPC32XX_DMA_BASE 0x31000000
+#define LPC32XX_USB_BASE 0x31020000
+#define LPC32XX_USBH_BASE 0x31020000
+#define LPC32XX_USB_OTG_BASE 0x31020000
+#define LPC32XX_OTG_I2C_BASE 0x31020300
+#define LPC32XX_LCD_BASE 0x31040000
+#define LPC32XX_ETHERNET_BASE 0x31060000
+#define LPC32XX_EMC_BASE 0x31080000
+#define LPC32XX_ETB_CFG_BASE 0x310C0000
+#define LPC32XX_ETB_DATA_BASE 0x310E0000
+#define LPC32XX_AHB1_START LPC32XX_DMA_BASE
+#define LPC32XX_AHB1_SIZE 0x000E1000
+
+/*
+ * FAB physical base addresses
+ */
+#define LPC32XX_CLK_PM_BASE 0x40004000
+#define LPC32XX_MIC_BASE 0x40008000
+#define LPC32XX_SIC1_BASE 0x4000C000
+#define LPC32XX_SIC2_BASE 0x40010000
+#define LPC32XX_HS_UART1_BASE 0x40014000
+#define LPC32XX_HS_UART2_BASE 0x40018000
+#define LPC32XX_HS_UART7_BASE 0x4001C000
+#define LPC32XX_RTC_BASE 0x40024000
+#define LPC32XX_RTC_RAM_BASE 0x40024080
+#define LPC32XX_GPIO_BASE 0x40028000
+#define LPC32XX_PWM3_BASE 0x4002C000
+#define LPC32XX_PWM4_BASE 0x40030000
+#define LPC32XX_MSTIM_BASE 0x40034000
+#define LPC32XX_HSTIM_BASE 0x40038000
+#define LPC32XX_WDTIM_BASE 0x4003C000
+#define LPC32XX_DEBUG_CTRL_BASE 0x40040000
+#define LPC32XX_TIMER0_BASE 0x40044000
+#define LPC32XX_ADC_BASE 0x40048000
+#define LPC32XX_TIMER1_BASE 0x4004C000
+#define LPC32XX_KSCAN_BASE 0x40050000
+#define LPC32XX_UART_CTRL_BASE 0x40054000
+#define LPC32XX_TIMER2_BASE 0x40058000
+#define LPC32XX_PWM1_BASE 0x4005C000
+#define LPC32XX_PWM2_BASE 0x4005C004
+#define LPC32XX_TIMER3_BASE 0x40060000
+
+/*
+ * APB physical base addresses
+ */
+#define LPC32XX_UART3_BASE 0x40080000
+#define LPC32XX_UART4_BASE 0x40088000
+#define LPC32XX_UART5_BASE 0x40090000
+#define LPC32XX_UART6_BASE 0x40098000
+#define LPC32XX_I2C1_BASE 0x400A0000
+#define LPC32XX_I2C2_BASE 0x400A8000
+
+/*
+ * FAB and APB base and sizing
+ */
+#define LPC32XX_FABAPB_START LPC32XX_CLK_PM_BASE
+#define LPC32XX_FABAPB_SIZE 0x000A5000
+
+/*
+ * Internal memory bases and sizes
+ */
+#define LPC32XX_IRAM_BASE 0x08000000
+#define LPC32XX_IROM_BASE 0x0C000000
+
+/*
+ * External Static Memory Bank Address Space Bases
+ */
+#define LPC32XX_EMC_CS0_BASE 0xE0000000
+#define LPC32XX_EMC_CS1_BASE 0xE1000000
+#define LPC32XX_EMC_CS2_BASE 0xE2000000
+#define LPC32XX_EMC_CS3_BASE 0xE3000000
+
+/*
+ * External SDRAM Memory Bank Address Space Bases
+ */
+#define LPC32XX_EMC_DYCS0_BASE 0x80000000
+#define LPC32XX_EMC_DYCS1_BASE 0xA0000000
+
+/*
+ * Clock and crystal information
+ */
+#define LPC32XX_MAIN_OSC_FREQ 13000000
+#define LPC32XX_CLOCK_OSC_FREQ 32768
+
+/*
+ * Clock and Power control register offsets
+ */
+#define _PMREG(x) io_p2v(LPC32XX_CLK_PM_BASE +\
+ (x))
+#define LPC32XX_CLKPWR_DEBUG_CTRL _PMREG(0x000)
+#define LPC32XX_CLKPWR_BOOTMAP _PMREG(0x014)
+#define LPC32XX_CLKPWR_P01_ER _PMREG(0x018)
+#define LPC32XX_CLKPWR_USBCLK_PDIV _PMREG(0x01C)
+#define LPC32XX_CLKPWR_INT_ER _PMREG(0x020)
+#define LPC32XX_CLKPWR_INT_RS _PMREG(0x024)
+#define LPC32XX_CLKPWR_INT_SR _PMREG(0x028)
+#define LPC32XX_CLKPWR_INT_AP _PMREG(0x02C)
+#define LPC32XX_CLKPWR_PIN_ER _PMREG(0x030)
+#define LPC32XX_CLKPWR_PIN_RS _PMREG(0x034)
+#define LPC32XX_CLKPWR_PIN_SR _PMREG(0x038)
+#define LPC32XX_CLKPWR_PIN_AP _PMREG(0x03C)
+#define LPC32XX_CLKPWR_HCLK_DIV _PMREG(0x040)
+#define LPC32XX_CLKPWR_PWR_CTRL _PMREG(0x044)
+#define LPC32XX_CLKPWR_PLL397_CTRL _PMREG(0x048)
+#define LPC32XX_CLKPWR_MAIN_OSC_CTRL _PMREG(0x04C)
+#define LPC32XX_CLKPWR_SYSCLK_CTRL _PMREG(0x050)
+#define LPC32XX_CLKPWR_LCDCLK_CTRL _PMREG(0x054)
+#define LPC32XX_CLKPWR_HCLKPLL_CTRL _PMREG(0x058)
+#define LPC32XX_CLKPWR_ADC_CLK_CTRL_1 _PMREG(0x060)
+#define LPC32XX_CLKPWR_USB_CTRL _PMREG(0x064)
+#define LPC32XX_CLKPWR_SDRAMCLK_CTRL _PMREG(0x068)
+#define LPC32XX_CLKPWR_DDR_LAP_NOM _PMREG(0x06C)
+#define LPC32XX_CLKPWR_DDR_LAP_COUNT _PMREG(0x070)
+#define LPC32XX_CLKPWR_DDR_LAP_DELAY _PMREG(0x074)
+#define LPC32XX_CLKPWR_SSP_CLK_CTRL _PMREG(0x078)
+#define LPC32XX_CLKPWR_I2S_CLK_CTRL _PMREG(0x07C)
+#define LPC32XX_CLKPWR_MS_CTRL _PMREG(0x080)
+#define LPC32XX_CLKPWR_MACCLK_CTRL _PMREG(0x090)
+#define LPC32XX_CLKPWR_TEST_CLK_SEL _PMREG(0x0A4)
+#define LPC32XX_CLKPWR_SFW_INT _PMREG(0x0A8)
+#define LPC32XX_CLKPWR_I2C_CLK_CTRL _PMREG(0x0AC)
+#define LPC32XX_CLKPWR_KEY_CLK_CTRL _PMREG(0x0B0)
+#define LPC32XX_CLKPWR_ADC_CLK_CTRL _PMREG(0x0B4)
+#define LPC32XX_CLKPWR_PWM_CLK_CTRL _PMREG(0x0B8)
+#define LPC32XX_CLKPWR_TIMER_CLK_CTRL _PMREG(0x0BC)
+#define LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1 _PMREG(0x0C0)
+#define LPC32XX_CLKPWR_SPI_CLK_CTRL _PMREG(0x0C4)
+#define LPC32XX_CLKPWR_NAND_CLK_CTRL _PMREG(0x0C8)
+#define LPC32XX_CLKPWR_UART3_CLK_CTRL _PMREG(0x0D0)
+#define LPC32XX_CLKPWR_UART4_CLK_CTRL _PMREG(0x0D4)
+#define LPC32XX_CLKPWR_UART5_CLK_CTRL _PMREG(0x0D8)
+#define LPC32XX_CLKPWR_UART6_CLK_CTRL _PMREG(0x0DC)
+#define LPC32XX_CLKPWR_IRDA_CLK_CTRL _PMREG(0x0E0)
+#define LPC32XX_CLKPWR_UART_CLK_CTRL _PMREG(0x0E4)
+#define LPC32XX_CLKPWR_DMA_CLK_CTRL _PMREG(0x0E8)
+#define LPC32XX_CLKPWR_AUTOCLOCK _PMREG(0x0EC)
+#define LPC32XX_CLKPWR_DEVID(x) _PMREG(0x130 + (x))
+
+/*
+ * clkpwr_debug_ctrl register definitions
+*/
+#define LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT _BIT(4)
+
+/*
+ * clkpwr_bootmap register definitions
+ */
+#define LPC32XX_CLKPWR_BOOTMAP_SEL_BIT _BIT(1)
+
+/*
+ * clkpwr_start_gpio register bit definitions
+ */
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO23_BIT _BIT(31)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO22_BIT _BIT(30)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO21_BIT _BIT(29)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO20_BIT _BIT(28)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO19_BIT _BIT(27)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO18_BIT _BIT(26)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO17_BIT _BIT(25)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO16_BIT _BIT(24)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO15_BIT _BIT(23)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO14_BIT _BIT(22)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO13_BIT _BIT(21)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO12_BIT _BIT(20)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO11_BIT _BIT(19)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO10_BIT _BIT(18)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO9_BIT _BIT(17)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO8_BIT _BIT(16)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO7_BIT _BIT(15)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO6_BIT _BIT(14)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO5_BIT _BIT(13)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO4_BIT _BIT(12)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO3_BIT _BIT(11)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO2_BIT _BIT(10)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO1_BIT _BIT(9)
+#define LPC32XX_CLKPWR_GPIOSRC_P1IO0_BIT _BIT(8)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO7_BIT _BIT(7)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO6_BIT _BIT(6)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO5_BIT _BIT(5)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO4_BIT _BIT(4)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO3_BIT _BIT(3)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO2_BIT _BIT(2)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO1_BIT _BIT(1)
+#define LPC32XX_CLKPWR_GPIOSRC_P0IO0_BIT _BIT(0)
+
+/*
+ * clkpwr_usbclk_pdiv register definitions
+ */
+#define LPC32XX_CLKPWR_USBPDIV_PLL_MASK 0xF
+
+/*
+ * clkpwr_start_int, clkpwr_start_raw_sts_int, clkpwr_start_sts_int,
+ * clkpwr_start_pol_int, register bit definitions
+ */
+#define LPC32XX_CLKPWR_INTSRC_ADC_BIT _BIT(31)
+#define LPC32XX_CLKPWR_INTSRC_TS_P_BIT _BIT(30)
+#define LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT _BIT(29)
+#define LPC32XX_CLKPWR_INTSRC_USBAHNEEDCLK_BIT _BIT(26)
+#define LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT _BIT(25)
+#define LPC32XX_CLKPWR_INTSRC_RTC_BIT _BIT(24)
+#define LPC32XX_CLKPWR_INTSRC_USBNEEDCLK_BIT _BIT(23)
+#define LPC32XX_CLKPWR_INTSRC_USB_BIT _BIT(22)
+#define LPC32XX_CLKPWR_INTSRC_I2C_BIT _BIT(21)
+#define LPC32XX_CLKPWR_INTSRC_USBOTGTIMER_BIT _BIT(20)
+#define LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT _BIT(19)
+#define LPC32XX_CLKPWR_INTSRC_KEY_BIT _BIT(16)
+#define LPC32XX_CLKPWR_INTSRC_MAC_BIT _BIT(7)
+#define LPC32XX_CLKPWR_INTSRC_P0P1_BIT _BIT(6)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT _BIT(5)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT _BIT(4)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT _BIT(3)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT _BIT(2)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT _BIT(1)
+#define LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT _BIT(0)
+
+/*
+ * clkpwr_start_pin, clkpwr_start_raw_sts_pin, clkpwr_start_sts_pin,
+ * clkpwr_start_pol_pin register bit definitions
+ */
+#define LPC32XX_CLKPWR_EXTSRC_U7_RX_BIT _BIT(31)
+#define LPC32XX_CLKPWR_EXTSRC_U7_HCTS_BIT _BIT(30)
+#define LPC32XX_CLKPWR_EXTSRC_U6_IRRX_BIT _BIT(28)
+#define LPC32XX_CLKPWR_EXTSRC_U5_RX_BIT _BIT(26)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT _BIT(25)
+#define LPC32XX_CLKPWR_EXTSRC_U3_RX_BIT _BIT(24)
+#define LPC32XX_CLKPWR_EXTSRC_U2_HCTS_BIT _BIT(23)
+#define LPC32XX_CLKPWR_EXTSRC_U2_RX_BIT _BIT(22)
+#define LPC32XX_CLKPWR_EXTSRC_U1_RX_BIT _BIT(21)
+#define LPC32XX_CLKPWR_EXTSRC_MSDIO_INT_BIT _BIT(18)
+#define LPC32XX_CLKPWR_EXTSRC_MSDIO_SRT_BIT _BIT(17)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT _BIT(16)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT _BIT(15)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT _BIT(14)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT _BIT(13)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT _BIT(12)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT _BIT(11)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT _BIT(10)
+#define LPC32XX_CLKPWR_EXTSRC_SYSCLKEN_BIT _BIT(9)
+#define LPC32XX_CLKPWR_EXTSRC_SPI1_DATIN_BIT _BIT(8)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT _BIT(7)
+#define LPC32XX_CLKPWR_EXTSRC_SPI2_DATIN_BIT _BIT(6)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT _BIT(5)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT _BIT(4)
+#define LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT _BIT(3)
+
+/*
+ * clkpwr_hclk_div register definitions
+ */
+#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_STOP (0x0 << 7)
+#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_NORM (0x1 << 7)
+#define LPC32XX_CLKPWR_HCLKDIV_DDRCLK_HALF (0x2 << 7)
+#define LPC32XX_CLKPWR_HCLKDIV_PCLK_DIV(n) (((n) & 0x1F) << 2)
+#define LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(n) ((n) & 0x3)
+
+/*
+ * clkpwr_pwr_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_CTRL_FORCE_PCLK _BIT(10)
+#define LPC32XX_CLKPWR_SDRAM_SELF_RFSH _BIT(9)
+#define LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH _BIT(8)
+#define LPC32XX_CLKPWR_AUTO_SDRAM_SELF_RFSH _BIT(7)
+#define LPC32XX_CLKPWR_HIGHCORE_STATE_BIT _BIT(5)
+#define LPC32XX_CLKPWR_SYSCLKEN_STATE_BIT _BIT(4)
+#define LPC32XX_CLKPWR_SYSCLKEN_GPIO_EN _BIT(3)
+#define LPC32XX_CLKPWR_SELECT_RUN_MODE _BIT(2)
+#define LPC32XX_CLKPWR_HIGHCORE_GPIO_EN _BIT(1)
+#define LPC32XX_CLKPWR_STOP_MODE_CTRL _BIT(0)
+
+/*
+ * clkpwr_pll397_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_PLL397_MSLOCK_STS _BIT(10)
+#define LPC32XX_CLKPWR_PLL397_BYPASS _BIT(9)
+#define LPC32XX_CLKPWR_PLL397_BIAS_NORM 0x000
+#define LPC32XX_CLKPWR_PLL397_BIAS_N12_5 0x040
+#define LPC32XX_CLKPWR_PLL397_BIAS_N25 0x080
+#define LPC32XX_CLKPWR_PLL397_BIAS_N37_5 0x0C0
+#define LPC32XX_CLKPWR_PLL397_BIAS_P12_5 0x100
+#define LPC32XX_CLKPWR_PLL397_BIAS_P25 0x140
+#define LPC32XX_CLKPWR_PLL397_BIAS_P37_5 0x180
+#define LPC32XX_CLKPWR_PLL397_BIAS_P50 0x1C0
+#define LPC32XX_CLKPWR_PLL397_BIAS_MASK 0x1C0
+#define LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS _BIT(1)
+#define LPC32XX_CLKPWR_SYSCTRL_PLL397_STS _BIT(0)
+
+/*
+ * clkpwr_main_osc_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_MOSC_ADD_CAP(n) (((n) & 0x7F) << 2)
+#define LPC32XX_CLKPWR_MOSC_CAP_MASK (0x7F << 2)
+#define LPC32XX_CLKPWR_TEST_MODE _BIT(1)
+#define LPC32XX_CLKPWR_MOSC_DISABLE _BIT(0)
+
+/*
+ * clkpwr_sysclk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_SYSCTRL_BP_TRIG(n) (((n) & 0x3FF) << 2)
+#define LPC32XX_CLKPWR_SYSCTRL_BP_MASK (0x3FF << 2)
+#define LPC32XX_CLKPWR_SYSCTRL_USEPLL397 _BIT(1)
+#define LPC32XX_CLKPWR_SYSCTRL_SYSCLKMUX _BIT(0)
+
+/*
+ * clkpwr_lcdclk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT12 0x000
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16 0x040
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT15 0x080
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT24 0x0C0
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN4M 0x100
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_STN8C 0x140
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN4M 0x180
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_DSTN8C 0x1C0
+#define LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK 0x01C0
+#define LPC32XX_CLKPWR_LCDCTRL_CLK_EN 0x020
+#define LPC32XX_CLKPWR_LCDCTRL_SET_PSCALE(n) ((n - 1) & 0x1F)
+#define LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK 0x001F
+
+/*
+ * clkpwr_hclkpll_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_HCLKPLL_POWER_UP _BIT(16)
+#define LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS _BIT(15)
+#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS _BIT(14)
+#define LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK _BIT(13)
+#define LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(n) (((n) & 0x3) << 11)
+#define LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(n) (((n) & 0x3) << 9)
+#define LPC32XX_CLKPWR_HCLKPLL_PLLM(n) (((n) & 0xFF) << 1)
+#define LPC32XX_CLKPWR_HCLKPLL_PLL_STS _BIT(0)
+
+/*
+ * clkpwr_adc_clk_ctrl_1 register definitions
+ */
+#define LPC32XX_CLKPWR_ADCCTRL1_RTDIV(n) (((n) & 0xFF) << 0)
+#define LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL _BIT(8)
+
+/*
+ * clkpwr_usb_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_USBCTRL_HCLK_EN _BIT(24)
+#define LPC32XX_CLKPWR_USBCTRL_USBI2C_EN _BIT(23)
+#define LPC32XX_CLKPWR_USBCTRL_USBDVND_EN _BIT(22)
+#define LPC32XX_CLKPWR_USBCTRL_USBHSTND_EN _BIT(21)
+#define LPC32XX_CLKPWR_USBCTRL_PU_ADD (0x0 << 19)
+#define LPC32XX_CLKPWR_USBCTRL_BUS_KEEPER (0x1 << 19)
+#define LPC32XX_CLKPWR_USBCTRL_PD_ADD (0x3 << 19)
+#define LPC32XX_CLKPWR_USBCTRL_CLK_EN2 _BIT(18)
+#define LPC32XX_CLKPWR_USBCTRL_CLK_EN1 _BIT(17)
+#define LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP _BIT(16)
+#define LPC32XX_CLKPWR_USBCTRL_CCO_BYPASS _BIT(15)
+#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_BYPASS _BIT(14)
+#define LPC32XX_CLKPWR_USBCTRL_FDBK_SEL_FCLK _BIT(13)
+#define LPC32XX_CLKPWR_USBCTRL_POSTDIV_2POW(n) (((n) & 0x3) << 11)
+#define LPC32XX_CLKPWR_USBCTRL_PREDIV_PLUS1(n) (((n) & 0x3) << 9)
+#define LPC32XX_CLKPWR_USBCTRL_FDBK_PLUS1(n) (((n) & 0xFF) << 1)
+#define LPC32XX_CLKPWR_USBCTRL_PLL_STS _BIT(0)
+
+/*
+ * clkpwr_sdramclk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_CLK _BIT(22)
+#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW _BIT(21)
+#define LPC32XX_CLKPWR_SDRCLK_FASTSLEW_DAT _BIT(20)
+#define LPC32XX_CLKPWR_SDRCLK_SW_DDR_RESET _BIT(19)
+#define LPC32XX_CLKPWR_SDRCLK_HCLK_DLY(n) (((n) & 0x1F) << 14)
+#define LPC32XX_CLKPWR_SDRCLK_DLY_ADDR_STS _BIT(13)
+#define LPC32XX_CLKPWR_SDRCLK_SENS_FACT(n) (((n) & 0x7) << 10)
+#define LPC32XX_CLKPWR_SDRCLK_USE_CAL _BIT(9)
+#define LPC32XX_CLKPWR_SDRCLK_DO_CAL _BIT(8)
+#define LPC32XX_CLKPWR_SDRCLK_CAL_ON_RTC _BIT(7)
+#define LPC32XX_CLKPWR_SDRCLK_DQS_DLY(n) (((n) & 0x1F) << 2)
+#define LPC32XX_CLKPWR_SDRCLK_USE_DDR _BIT(1)
+#define LPC32XX_CLKPWR_SDRCLK_CLK_DIS _BIT(0)
+
+/*
+ * clkpwr_ssp_blk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1RX _BIT(5)
+#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP1TX _BIT(4)
+#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0RX _BIT(3)
+#define LPC32XX_CLKPWR_SSPCTRL_DMA_SSP0TX _BIT(2)
+#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN _BIT(1)
+#define LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN _BIT(0)
+
+/*
+ * clkpwr_i2s_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_I2SCTRL_I2S1_RX_FOR_TX _BIT(6)
+#define LPC32XX_CLKPWR_I2SCTRL_I2S1_TX_FOR_RX _BIT(5)
+#define LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA _BIT(4)
+#define LPC32XX_CLKPWR_I2SCTRL_I2S0_RX_FOR_TX _BIT(3)
+#define LPC32XX_CLKPWR_I2SCTRL_I2S0_TX_FOR_RX _BIT(2)
+#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN _BIT(1)
+#define LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN _BIT(0)
+
+/*
+ * clkpwr_ms_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS _BIT(10)
+#define LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN _BIT(9)
+#define LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS _BIT(8)
+#define LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS _BIT(7)
+#define LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS _BIT(6)
+#define LPC32XX_CLKPWR_MSCARD_SDCARD_EN _BIT(5)
+#define LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(n) ((n) & 0xF)
+
+/*
+ * clkpwr_macclk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_MACCTRL_NO_ENET_PIS 0x00
+#define LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS 0x08
+#define LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS 0x18
+#define LPC32XX_CLKPWR_MACCTRL_PINS_MSK 0x18
+#define LPC32XX_CLKPWR_MACCTRL_DMACLK_EN _BIT(2)
+#define LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN _BIT(1)
+#define LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN _BIT(0)
+
+/*
+ * clkpwr_test_clk_sel register definitions
+ */
+#define LPC32XX_CLKPWR_TESTCLK1_SEL_PERCLK (0x0 << 5)
+#define LPC32XX_CLKPWR_TESTCLK1_SEL_RTC (0x1 << 5)
+#define LPC32XX_CLKPWR_TESTCLK1_SEL_MOSC (0x2 << 5)
+#define LPC32XX_CLKPWR_TESTCLK1_SEL_MASK (0x3 << 5)
+#define LPC32XX_CLKPWR_TESTCLK_TESTCLK1_EN _BIT(4)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_HCLK (0x0 << 1)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_PERCLK (0x1 << 1)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_USBCLK (0x2 << 1)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC (0x5 << 1)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_PLL397 (0x7 << 1)
+#define LPC32XX_CLKPWR_TESTCLK2_SEL_MASK (0x7 << 1)
+#define LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN _BIT(0)
+
+/*
+ * clkpwr_sw_int register definitions
+ */
+#define LPC32XX_CLKPWR_SW_INT(n) (_BIT(0) | (((n) & 0x7F) << 1))
+#define LPC32XX_CLKPWR_SW_GET_ARG(n) (((n) & 0xFE) >> 1)
+
+/*
+ * clkpwr_i2c_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE _BIT(4)
+#define LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE _BIT(3)
+#define LPC32XX_CLKPWR_I2CCLK_I2C1HI_DRIVE _BIT(2)
+#define LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN _BIT(1)
+#define LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN _BIT(0)
+
+/*
+ * clkpwr_key_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN 0x1
+
+/*
+ * clkpwr_adc_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN 0x1
+
+/*
+ * clkpwr_pwm_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(n) (((n) & 0xF) << 8)
+#define LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(n) (((n) & 0xF) << 4)
+#define LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK 0x8
+#define LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN 0x4
+#define LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK 0x2
+#define LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN 0x1
+
+/*
+ * clkpwr_timer_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_PWMCLK_HSTIMER_EN 0x2
+#define LPC32XX_CLKPWR_PWMCLK_WDOG_EN 0x1
+
+/*
+ * clkpwr_timers_pwms_clk_ctrl_1 register definitions
+ */
+#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN 0x20
+#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN 0x10
+#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN 0x08
+#define LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN 0x04
+#define LPC32XX_CLKPWR_TMRPWMCLK_PWM4_EN 0x02
+#define LPC32XX_CLKPWR_TMRPWMCLK_PWM3_EN 0x01
+
+/*
+ * clkpwr_spi_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_SPICLK_SET_SPI2DATIO 0x80
+#define LPC32XX_CLKPWR_SPICLK_SET_SPI2CLK 0x40
+#define LPC32XX_CLKPWR_SPICLK_USE_SPI2 0x20
+#define LPC32XX_CLKPWR_SPICLK_SPI2CLK_EN 0x10
+#define LPC32XX_CLKPWR_SPICLK_SET_SPI1DATIO 0x08
+#define LPC32XX_CLKPWR_SPICLK_SET_SPI1CLK 0x04
+#define LPC32XX_CLKPWR_SPICLK_USE_SPI1 0x02
+#define LPC32XX_CLKPWR_SPICLK_SPI1CLK_EN 0x01
+
+/*
+ * clkpwr_nand_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC 0x20
+#define LPC32XX_CLKPWR_NANDCLK_DMA_RNB 0x10
+#define LPC32XX_CLKPWR_NANDCLK_DMA_INT 0x08
+#define LPC32XX_CLKPWR_NANDCLK_SEL_SLC 0x04
+#define LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN 0x02
+#define LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN 0x01
+
+/*
+ * clkpwr_uart3_clk_ctrl, clkpwr_uart4_clk_ctrl, clkpwr_uart5_clk_ctrl
+ * and clkpwr_uart6_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_UART_Y_DIV(y) ((y) & 0xFF)
+#define LPC32XX_CLKPWR_UART_X_DIV(x) (((x) & 0xFF) << 8)
+#define LPC32XX_CLKPWR_UART_USE_HCLK _BIT(16)
+
+/*
+ * clkpwr_irda_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_IRDA_Y_DIV(y) ((y) & 0xFF)
+#define LPC32XX_CLKPWR_IRDA_X_DIV(x) (((x) & 0xFF) << 8)
+
+/*
+ * clkpwr_uart_clk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN _BIT(3)
+#define LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN _BIT(2)
+#define LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN _BIT(1)
+#define LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN _BIT(0)
+
+/*
+ * clkpwr_dmaclk_ctrl register definitions
+ */
+#define LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN 0x1
+
+/*
+ * clkpwr_autoclock register definitions
+ */
+#define LPC32XX_CLKPWR_AUTOCLK_USB_EN 0x40
+#define LPC32XX_CLKPWR_AUTOCLK_IRAM_EN 0x02
+#define LPC32XX_CLKPWR_AUTOCLK_IROM_EN 0x01
+
+/*
+ * Interrupt controller register offsets
+ */
+#define LPC32XX_INTC_MASK(x) io_p2v((x) + 0x00)
+#define LPC32XX_INTC_RAW_STAT(x) io_p2v((x) + 0x04)
+#define LPC32XX_INTC_STAT(x) io_p2v((x) + 0x08)
+#define LPC32XX_INTC_POLAR(x) io_p2v((x) + 0x0C)
+#define LPC32XX_INTC_ACT_TYPE(x) io_p2v((x) + 0x10)
+#define LPC32XX_INTC_TYPE(x) io_p2v((x) + 0x14)
+
+/*
+ * Timer/counter register offsets
+ */
+#define LCP32XX_TIMER_IR(x) io_p2v((x) + 0x00)
+#define LCP32XX_TIMER_TCR(x) io_p2v((x) + 0x04)
+#define LCP32XX_TIMER_TC(x) io_p2v((x) + 0x08)
+#define LCP32XX_TIMER_PR(x) io_p2v((x) + 0x0C)
+#define LCP32XX_TIMER_PC(x) io_p2v((x) + 0x10)
+#define LCP32XX_TIMER_MCR(x) io_p2v((x) + 0x14)
+#define LCP32XX_TIMER_MR0(x) io_p2v((x) + 0x18)
+#define LCP32XX_TIMER_MR1(x) io_p2v((x) + 0x1C)
+#define LCP32XX_TIMER_MR2(x) io_p2v((x) + 0x20)
+#define LCP32XX_TIMER_MR3(x) io_p2v((x) + 0x24)
+#define LCP32XX_TIMER_CCR(x) io_p2v((x) + 0x28)
+#define LCP32XX_TIMER_CR0(x) io_p2v((x) + 0x2C)
+#define LCP32XX_TIMER_CR1(x) io_p2v((x) + 0x30)
+#define LCP32XX_TIMER_CR2(x) io_p2v((x) + 0x34)
+#define LCP32XX_TIMER_CR3(x) io_p2v((x) + 0x38)
+#define LCP32XX_TIMER_EMR(x) io_p2v((x) + 0x3C)
+#define LCP32XX_TIMER_CTCR(x) io_p2v((x) + 0x70)
+
+/*
+ * ir register definitions
+ */
+#define LCP32XX_TIMER_CNTR_MTCH_BIT(n) (1 << ((n) & 0x3))
+#define LCP32XX_TIMER_CNTR_CAPT_BIT(n) (1 << (4 + ((n) & 0x3)))
+
+/*
+ * tcr register definitions
+ */
+#define LCP32XX_TIMER_CNTR_TCR_EN 0x1
+#define LCP32XX_TIMER_CNTR_TCR_RESET 0x2
+
+/*
+ * mcr register definitions
+ */
+#define LCP32XX_TIMER_CNTR_MCR_MTCH(n) (0x1 << ((n) * 3))
+#define LCP32XX_TIMER_CNTR_MCR_RESET(n) (0x1 << (((n) * 3) + 1))
+#define LCP32XX_TIMER_CNTR_MCR_STOP(n) (0x1 << (((n) * 3) + 2))
+
+/*
+ * Standard UART register offsets
+ */
+#define LPC32XX_UART_DLL_FIFO(x) io_p2v((x) + 0x00)
+#define LPC32XX_UART_DLM_IER(x) io_p2v((x) + 0x04)
+#define LPC32XX_UART_IIR_FCR(x) io_p2v((x) + 0x08)
+#define LPC32XX_UART_LCR(x) io_p2v((x) + 0x0C)
+#define LPC32XX_UART_MODEM_CTRL(x) io_p2v((x) + 0x10)
+#define LPC32XX_UART_LSR(x) io_p2v((x) + 0x14)
+#define LPC32XX_UART_MODEM_STATUS(x) io_p2v((x) + 0x18)
+#define LPC32XX_UART_RXLEV(x) io_p2v((x) + 0x1C)
+
+/*
+ * UART control structure offsets
+ */
+#define _UCREG(x) io_p2v(\
+ LPC32XX_UART_CTRL_BASE + (x))
+#define LPC32XX_UARTCTL_CTRL _UCREG(0x00)
+#define LPC32XX_UARTCTL_CLKMODE _UCREG(0x04)
+#define LPC32XX_UARTCTL_CLOOP _UCREG(0x08)
+
+/*
+ * ctrl register definitions
+ */
+#define LPC32XX_UART_U3_MD_CTRL_EN _BIT(11)
+#define LPC32XX_UART_IRRX6_INV_EN _BIT(10)
+#define LPC32XX_UART_HDPX_EN _BIT(9)
+#define LPC32XX_UART_UART6_IRDAMOD_BYPASS _BIT(5)
+#define LPC32XX_RT_IRTX6_INV_EN _BIT(4)
+#define LPC32XX_RT_IRTX6_INV_MIR_EN _BIT(3)
+#define LPC32XX_RT_RX_IRPULSE_3_16_115K _BIT(2)
+#define LPC32XX_RT_TX_IRPULSE_3_16_115K _BIT(1)
+#define LPC32XX_UART_U5_ROUTE_TO_USB _BIT(0)
+
+/*
+ * clkmode register definitions
+ */
+#define LPC32XX_UART_ENABLED_CLOCKS(n) (((n) >> 16) & 0x7F)
+#define LPC32XX_UART_ENABLED_CLOCK(n, u) (((n) >> (16 + (u))) & 0x1)
+#define LPC32XX_UART_ENABLED_CLKS_ANY _BIT(14)
+#define LPC32XX_UART_CLKMODE_OFF 0x0
+#define LPC32XX_UART_CLKMODE_ON 0x1
+#define LPC32XX_UART_CLKMODE_AUTO 0x2
+#define LPC32XX_UART_CLKMODE_MASK(u) (0x3 << ((((u) - 3) * 2) + 4))
+#define LPC32XX_UART_CLKMODE_LOAD(m, u) ((m) << ((((u) - 3) * 2) + 4))
+
+/*
+ * GPIO Module Register offsets
+ */
+#define _GPREG(x) io_p2v(LPC32XX_GPIO_BASE + (x))
+#define LPC32XX_GPIO_P_MUX_SET _GPREG(0x100)
+#define LPC32XX_GPIO_P_MUX_CLR _GPREG(0x104)
+#define LPC32XX_GPIO_P_MUX_STATE _GPREG(0x108)
+#define LPC32XX_GPIO_P3_MUX_SET _GPREG(0x110)
+#define LPC32XX_GPIO_P3_MUX_CLR _GPREG(0x114)
+#define LPC32XX_GPIO_P3_MUX_STATE _GPREG(0x118)
+#define LPC32XX_GPIO_P0_MUX_SET _GPREG(0x120)
+#define LPC32XX_GPIO_P0_MUX_CLR _GPREG(0x124)
+#define LPC32XX_GPIO_P0_MUX_STATE _GPREG(0x128)
+#define LPC32XX_GPIO_P1_MUX_SET _GPREG(0x130)
+#define LPC32XX_GPIO_P1_MUX_CLR _GPREG(0x134)
+#define LPC32XX_GPIO_P1_MUX_STATE _GPREG(0x138)
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/system.h b/arch/arm/mach-lpc32xx/include/mach/system.h
new file mode 100644
index 00000000..df3b0dea
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/system.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/system.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ extern void lpc32xx_watchdog_reset(void);
+
+ switch (mode) {
+ case 's':
+ case 'h':
+ printk(KERN_CRIT "RESET: Rebooting system\n");
+
+ /* Disable interrupts */
+ local_irq_disable();
+
+ lpc32xx_watchdog_reset();
+ break;
+
+ default:
+ /* Do nothing */
+ break;
+ }
+
+ /* Wait for watchdog to reset system */
+ while (1)
+ ;
+}
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/timex.h b/arch/arm/mach-lpc32xx/include/mach/timex.h
new file mode 100644
index 00000000..8d4066b1
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/timex.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/timex.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/*
+ * Rate in Hz of the main system oscillator. This value should match
+ * the value 'MAIN_OSC_FREQ' in platform.h
+ */
+#define CLOCK_TICK_RATE 13000000
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/uncompress.h b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
new file mode 100644
index 00000000..c142487d
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/uncompress.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_ARCH_UNCOMPRESS_H
+#define __ASM_ARM_ARCH_UNCOMPRESS_H
+
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+/*
+ * Uncompress output is hardcoded to standard UART 5
+ */
+
+#define UART_FIFO_CTL_TX_RESET (1 << 2)
+#define UART_STATUS_TX_MT (1 << 6)
+
+#define _UARTREG(x) (void __iomem *)(LPC32XX_UART5_BASE + (x))
+
+#define LPC32XX_UART_DLLFIFO_O 0x00
+#define LPC32XX_UART_IIRFCR_O 0x08
+#define LPC32XX_UART_LSR_O 0x14
+
+static inline void putc(int ch)
+{
+ /* Wait for transmit FIFO to empty */
+ while ((__raw_readl(_UARTREG(LPC32XX_UART_LSR_O)) &
+ UART_STATUS_TX_MT) == 0)
+ ;
+
+ __raw_writel((u32) ch, _UARTREG(LPC32XX_UART_DLLFIFO_O));
+}
+
+static inline void flush(void)
+{
+ __raw_writel(__raw_readl(_UARTREG(LPC32XX_UART_IIRFCR_O)) |
+ UART_FIFO_CTL_TX_RESET, _UARTREG(LPC32XX_UART_IIRFCR_O));
+}
+
+/* NULL functions; we don't presently need them */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/vmalloc.h b/arch/arm/mach-lpc32xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..d1d936c7
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/include/mach/vmalloc.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-lpc32xx/include/mach/vmalloc.h
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF0000000
+
+#endif
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
new file mode 100644
index 00000000..c74de01a
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -0,0 +1,447 @@
+/*
+ * arch/arm/mach-lpc32xx/irq.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+/*
+ * Default value representing the Activation polarity of all internal
+ * interrupt sources
+ */
+#define MIC_APR_DEFAULT 0x3FF0EFE0
+#define SIC1_APR_DEFAULT 0xFBD27186
+#define SIC2_APR_DEFAULT 0x801810C0
+
+/*
+ * Default value representing the Activation Type of all internal
+ * interrupt sources. All are level sensitive.
+ */
+#define MIC_ATR_DEFAULT 0x00000000
+#define SIC1_ATR_DEFAULT 0x00026000
+#define SIC2_ATR_DEFAULT 0x00000000
+
+struct lpc32xx_event_group_regs {
+ void __iomem *enab_reg;
+ void __iomem *edge_reg;
+ void __iomem *maskstat_reg;
+ void __iomem *rawstat_reg;
+};
+
+static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = {
+ .enab_reg = LPC32XX_CLKPWR_INT_ER,
+ .edge_reg = LPC32XX_CLKPWR_INT_AP,
+ .maskstat_reg = LPC32XX_CLKPWR_INT_SR,
+ .rawstat_reg = LPC32XX_CLKPWR_INT_RS,
+};
+
+static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = {
+ .enab_reg = LPC32XX_CLKPWR_PIN_ER,
+ .edge_reg = LPC32XX_CLKPWR_PIN_AP,
+ .maskstat_reg = LPC32XX_CLKPWR_PIN_SR,
+ .rawstat_reg = LPC32XX_CLKPWR_PIN_RS,
+};
+
+struct lpc32xx_event_info {
+ const struct lpc32xx_event_group_regs *event_group;
+ u32 mask;
+};
+
+/*
+ * Maps an IRQ number to and event mask and register
+ */
+static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
+ [IRQ_LPC32XX_GPI_08] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT,
+ },
+ [IRQ_LPC32XX_GPI_09] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT,
+ },
+ [IRQ_LPC32XX_GPI_19] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT,
+ },
+ [IRQ_LPC32XX_GPI_07] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT,
+ },
+ [IRQ_LPC32XX_GPI_00] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT,
+ },
+ [IRQ_LPC32XX_GPI_01] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT,
+ },
+ [IRQ_LPC32XX_GPI_02] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT,
+ },
+ [IRQ_LPC32XX_GPI_03] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT,
+ },
+ [IRQ_LPC32XX_GPI_04] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT,
+ },
+ [IRQ_LPC32XX_GPI_05] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT,
+ },
+ [IRQ_LPC32XX_GPI_06] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
+ },
+ [IRQ_LPC32XX_GPI_28] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_00] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_01] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_02] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_03] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_04] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT,
+ },
+ [IRQ_LPC32XX_GPIO_05] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT,
+ },
+ [IRQ_LPC32XX_KEY] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT,
+ },
+ [IRQ_LPC32XX_USB_OTG_ATX] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT,
+ },
+ [IRQ_LPC32XX_USB_HOST] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT,
+ },
+ [IRQ_LPC32XX_RTC] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT,
+ },
+ [IRQ_LPC32XX_MSTIMER] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT,
+ },
+ [IRQ_LPC32XX_TS_AUX] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT,
+ },
+ [IRQ_LPC32XX_TS_P] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT,
+ },
+ [IRQ_LPC32XX_TS_IRQ] = {
+ .event_group = &lpc32xx_event_int_regs,
+ .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT,
+ },
+};
+
+static void get_controller(unsigned int irq, unsigned int *base,
+ unsigned int *irqbit)
+{
+ if (irq < 32) {
+ *base = LPC32XX_MIC_BASE;
+ *irqbit = 1 << irq;
+ } else if (irq < 64) {
+ *base = LPC32XX_SIC1_BASE;
+ *irqbit = 1 << (irq - 32);
+ } else {
+ *base = LPC32XX_SIC2_BASE;
+ *irqbit = 1 << (irq - 64);
+ }
+}
+
+static void lpc32xx_mask_irq(struct irq_data *d)
+{
+ unsigned int reg, ctrl, mask;
+
+ get_controller(d->irq, &ctrl, &mask);
+
+ reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask;
+ __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
+}
+
+static void lpc32xx_unmask_irq(struct irq_data *d)
+{
+ unsigned int reg, ctrl, mask;
+
+ get_controller(d->irq, &ctrl, &mask);
+
+ reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask;
+ __raw_writel(reg, LPC32XX_INTC_MASK(ctrl));
+}
+
+static void lpc32xx_ack_irq(struct irq_data *d)
+{
+ unsigned int ctrl, mask;
+
+ get_controller(d->irq, &ctrl, &mask);
+
+ __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl));
+
+ /* Also need to clear pending wake event */
+ if (lpc32xx_events[d->irq].mask != 0)
+ __raw_writel(lpc32xx_events[d->irq].mask,
+ lpc32xx_events[d->irq].event_group->rawstat_reg);
+}
+
+static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level,
+ int use_edge)
+{
+ unsigned int reg, ctrl, mask;
+
+ get_controller(irq, &ctrl, &mask);
+
+ /* Activation level, high or low */
+ reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl));
+ if (use_high_level)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl));
+
+ /* Activation type, edge or level */
+ reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl));
+ if (use_edge)
+ reg |= mask;
+ else
+ reg &= ~mask;
+ __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl));
+
+ /* Use same polarity for the wake events */
+ if (lpc32xx_events[irq].mask != 0) {
+ reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg);
+
+ if (use_high_level)
+ reg |= lpc32xx_events[irq].mask;
+ else
+ reg &= ~lpc32xx_events[irq].mask;
+
+ __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg);
+ }
+}
+
+static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ /* Rising edge sensitive */
+ __lpc32xx_set_irq_type(d->irq, 1, 1);
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ /* Falling edge sensitive */
+ __lpc32xx_set_irq_type(d->irq, 0, 1);
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ /* Low level sensitive */
+ __lpc32xx_set_irq_type(d->irq, 0, 0);
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ /* High level sensitive */
+ __lpc32xx_set_irq_type(d->irq, 1, 0);
+ break;
+
+ /* Other modes are not supported */
+ default:
+ return -EINVAL;
+ }
+
+ /* Ok to use the level handler for all types */
+ irq_set_handler(d->irq, handle_level_irq);
+
+ return 0;
+}
+
+static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
+{
+ unsigned long eventreg;
+
+ if (lpc32xx_events[d->irq].mask != 0) {
+ eventreg = __raw_readl(lpc32xx_events[d->irq].
+ event_group->enab_reg);
+
+ if (state)
+ eventreg |= lpc32xx_events[d->irq].mask;
+ else {
+ eventreg &= ~lpc32xx_events[d->irq].mask;
+
+ /*
+ * When disabling the wakeup, clear the latched
+ * event
+ */
+ __raw_writel(lpc32xx_events[d->irq].mask,
+ lpc32xx_events[d->irq].
+ event_group->rawstat_reg);
+ }
+
+ __raw_writel(eventreg,
+ lpc32xx_events[d->irq].event_group->enab_reg);
+
+ return 0;
+ }
+
+ /* Clear event */
+ __raw_writel(lpc32xx_events[d->irq].mask,
+ lpc32xx_events[d->irq].event_group->rawstat_reg);
+
+ return -ENODEV;
+}
+
+static void __init lpc32xx_set_default_mappings(unsigned int apr,
+ unsigned int atr, unsigned int offset)
+{
+ unsigned int i;
+
+ /* Set activation levels for each interrupt */
+ i = 0;
+ while (i < 32) {
+ __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1),
+ ((atr >> i) & 0x1));
+ i++;
+ }
+}
+
+static struct irq_chip lpc32xx_irq_chip = {
+ .irq_ack = lpc32xx_ack_irq,
+ .irq_mask = lpc32xx_mask_irq,
+ .irq_unmask = lpc32xx_unmask_irq,
+ .irq_set_type = lpc32xx_set_irq_type,
+ .irq_set_wake = lpc32xx_irq_wake
+};
+
+static void lpc32xx_sic1_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE));
+
+ while (ints != 0) {
+ int irqno = fls(ints) - 1;
+
+ ints &= ~(1 << irqno);
+
+ generic_handle_irq(LPC32XX_SIC1_IRQ(irqno));
+ }
+}
+
+static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE));
+
+ while (ints != 0) {
+ int irqno = fls(ints) - 1;
+
+ ints &= ~(1 << irqno);
+
+ generic_handle_irq(LPC32XX_SIC2_IRQ(irqno));
+ }
+}
+
+void __init lpc32xx_init_irq(void)
+{
+ unsigned int i;
+
+ /* Setup MIC */
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
+ __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE));
+ __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE));
+
+ /* Setup SIC1 */
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
+ __raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
+ __raw_writel(SIC1_ATR_DEFAULT,
+ LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
+
+ /* Setup SIC2 */
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
+ __raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
+ __raw_writel(SIC2_ATR_DEFAULT,
+ LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
+
+ /* Configure supported IRQ's */
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_set_chip_and_handler(i, &lpc32xx_irq_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ /* Set default mappings */
+ lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0);
+ lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32);
+ lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64);
+
+ /* mask all interrupts except SUBIRQ */
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE));
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
+ __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
+
+ /* MIC SUBIRQx interrupts will route handling to the chain handlers */
+ irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
+ irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
+
+ /* Initially disable all wake events */
+ __raw_writel(0, LPC32XX_CLKPWR_P01_ER);
+ __raw_writel(0, LPC32XX_CLKPWR_INT_ER);
+ __raw_writel(0, LPC32XX_CLKPWR_PIN_ER);
+
+ /*
+ * Default wake activation polarities, all pin sources are low edge
+ * triggered
+ */
+ __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT |
+ LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT |
+ LPC32XX_CLKPWR_INTSRC_RTC_BIT,
+ LPC32XX_CLKPWR_INT_AP);
+ __raw_writel(0, LPC32XX_CLKPWR_PIN_AP);
+
+ /* Clear latched wake event states */
+ __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS),
+ LPC32XX_CLKPWR_PIN_RS);
+ __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS),
+ LPC32XX_CLKPWR_INT_RS);
+}
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
new file mode 100644
index 00000000..7993b096
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -0,0 +1,390 @@
+/*
+ * arch/arm/mach-lpc32xx/phy3250.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/amba/pl022.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+/*
+ * Mapped GPIOLIB GPIOs
+ */
+#define SPI0_CS_GPIO LPC32XX_GPIO(LPC32XX_GPIO_P3_GRP, 5)
+#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0)
+#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4)
+#define LED_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 1)
+
+/*
+ * AMBA LCD controller
+ */
+static struct clcd_panel conn_lcd_panel = {
+ .mode = {
+ .name = "QVGA portrait",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 191828,
+ .left_margin = 22,
+ .right_margin = 11,
+ .upper_margin = 2,
+ .lower_margin = 1,
+ .hsync_len = 5,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = (TIM2_IVS | TIM2_IHS),
+ .cntl = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) |
+ CNTL_LCDBPP16_565),
+ .bpp = 16,
+};
+#define PANEL_SIZE (3 * SZ_64K)
+
+static int lpc32xx_clcd_setup(struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
+ PANEL_SIZE, &dma, GFP_KERNEL);
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = PANEL_SIZE;
+ fb->panel = &conn_lcd_panel;
+
+ if (gpio_request(LCD_POWER_GPIO, "LCD power"))
+ printk(KERN_ERR "Error requesting gpio %u",
+ LCD_POWER_GPIO);
+ else if (gpio_direction_output(LCD_POWER_GPIO, 1))
+ printk(KERN_ERR "Error setting gpio %u to output",
+ LCD_POWER_GPIO);
+
+ if (gpio_request(BKL_POWER_GPIO, "LCD backlight power"))
+ printk(KERN_ERR "Error requesting gpio %u",
+ BKL_POWER_GPIO);
+ else if (gpio_direction_output(BKL_POWER_GPIO, 1))
+ printk(KERN_ERR "Error setting gpio %u to output",
+ BKL_POWER_GPIO);
+
+ return 0;
+}
+
+static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base, fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+static void lpc32xx_clcd_remove(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+/*
+ * On some early LCD modules (1307.0), the backlight logic is inverted.
+ * For those board variants, swap the disable and enable states for
+ * BKL_POWER_GPIO.
+*/
+static void clcd_disable(struct clcd_fb *fb)
+{
+ gpio_set_value(BKL_POWER_GPIO, 0);
+ gpio_set_value(LCD_POWER_GPIO, 0);
+}
+
+static void clcd_enable(struct clcd_fb *fb)
+{
+ gpio_set_value(BKL_POWER_GPIO, 1);
+ gpio_set_value(LCD_POWER_GPIO, 1);
+}
+
+static struct clcd_board lpc32xx_clcd_data = {
+ .name = "Phytec LCD",
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .disable = clcd_disable,
+ .enable = clcd_enable,
+ .setup = lpc32xx_clcd_setup,
+ .mmap = lpc32xx_clcd_mmap,
+ .remove = lpc32xx_clcd_remove,
+};
+
+static struct amba_device lpc32xx_clcd_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "dev:clcd",
+ .platform_data = &lpc32xx_clcd_data,
+ },
+ .res = {
+ .start = LPC32XX_LCD_BASE,
+ .end = (LPC32XX_LCD_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ .dma_mask = ~0,
+ .irq = {IRQ_LPC32XX_LCD, NO_IRQ},
+};
+
+/*
+ * AMBA SSP (SPI)
+ */
+static void phy3250_spi_cs_set(u32 control)
+{
+ gpio_set_value(SPI0_CS_GPIO, (int) control);
+}
+
+static struct pl022_config_chip spi0_chip_info = {
+ .com_mode = INTERRUPT_TRANSFER,
+ .iface = SSP_INTERFACE_MOTOROLA_SPI,
+ .hierarchy = SSP_MASTER,
+ .slave_tx_disable = 0,
+ .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
+ .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
+ .ctrl_len = SSP_BITS_8,
+ .wait_state = SSP_MWIRE_WAIT_ZERO,
+ .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
+ .cs_control = phy3250_spi_cs_set,
+};
+
+static struct pl022_ssp_controller lpc32xx_ssp0_data = {
+ .bus_id = 0,
+ .num_chipselect = 1,
+ .enable_dma = 0,
+};
+
+static struct amba_device lpc32xx_ssp0_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "dev:ssp0",
+ .platform_data = &lpc32xx_ssp0_data,
+ },
+ .res = {
+ .start = LPC32XX_SSP0_BASE,
+ .end = (LPC32XX_SSP0_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ .dma_mask = ~0,
+ .irq = {IRQ_LPC32XX_SSP0, NO_IRQ},
+};
+
+/* AT25 driver registration */
+static int __init phy3250_spi_board_register(void)
+{
+#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
+ static struct spi_board_info info[] = {
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .controller_data = &spi0_chip_info,
+ },
+ };
+
+#else
+ static struct spi_eeprom eeprom = {
+ .name = "at25256a",
+ .byte_len = 0x8000,
+ .page_size = 64,
+ .flags = EE_ADDR2,
+ };
+
+ static struct spi_board_info info[] = {
+ {
+ .modalias = "at25",
+ .max_speed_hz = 5000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .platform_data = &eeprom,
+ .controller_data = &spi0_chip_info,
+ },
+ };
+#endif
+ return spi_register_board_info(info, ARRAY_SIZE(info));
+}
+arch_initcall(phy3250_spi_board_register);
+
+static struct i2c_board_info __initdata phy3250_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static struct gpio_led phy_leds[] = {
+ {
+ .name = "led0",
+ .gpio = LED_GPIO,
+ .active_low = 1,
+ .default_trigger = "heartbeat",
+ },
+};
+
+static struct gpio_led_platform_data led_data = {
+ .leds = phy_leds,
+ .num_leds = ARRAY_SIZE(phy_leds),
+};
+
+static struct platform_device lpc32xx_gpio_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &led_data,
+};
+
+static struct platform_device *phy3250_devs[] __initdata = {
+ &lpc32xx_i2c0_device,
+ &lpc32xx_i2c1_device,
+ &lpc32xx_i2c2_device,
+ &lpc32xx_watchdog_device,
+ &lpc32xx_gpio_led_device,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &lpc32xx_clcd_device,
+ &lpc32xx_ssp0_device,
+};
+
+/*
+ * Board specific functions
+ */
+static void __init phy3250_board_init(void)
+{
+ u32 tmp;
+ int i;
+
+ lpc32xx_gpio_init();
+
+ /* Register GPIOs used on this board */
+ if (gpio_request(SPI0_CS_GPIO, "spi0 cs"))
+ printk(KERN_ERR "Error requesting gpio %u",
+ SPI0_CS_GPIO);
+ else if (gpio_direction_output(SPI0_CS_GPIO, 1))
+ printk(KERN_ERR "Error setting gpio %u to output",
+ SPI0_CS_GPIO);
+
+ /* Setup network interface for RMII mode */
+ tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
+ tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
+ tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
+ __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
+
+ /* Setup SLC NAND controller muxing */
+ __raw_writel(LPC32XX_CLKPWR_NANDCLK_SEL_SLC,
+ LPC32XX_CLKPWR_NAND_CLK_CTRL);
+
+ /* Setup LCD muxing to RGB565 */
+ tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) &
+ ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK |
+ LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK);
+ tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16;
+ __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL);
+
+ /* Set up I2C pull levels */
+ tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
+ tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE |
+ LPC32XX_CLKPWR_I2CCLK_I2C2HI_DRIVE;
+ __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
+
+ /* Disable IrDA pulsing support on UART6 */
+ tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
+ tmp |= LPC32XX_UART_UART6_IRDAMOD_BYPASS;
+ __raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
+
+ /* Enable DMA for I2S1 channel */
+ tmp = __raw_readl(LPC32XX_CLKPWR_I2S_CLK_CTRL);
+ tmp = LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA;
+ __raw_writel(tmp, LPC32XX_CLKPWR_I2S_CLK_CTRL);
+
+ lpc32xx_serial_init();
+
+ /*
+ * AMBA peripheral clocks need to be enabled prior to AMBA device
+ * detection or a data fault will occur, so enable the clocks
+ * here. However, we don't want to enable them if the peripheral
+ * isn't included in the image
+ */
+#ifdef CONFIG_FB_ARMCLCD
+ tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
+ __raw_writel((tmp | LPC32XX_CLKPWR_LCDCTRL_CLK_EN),
+ LPC32XX_CLKPWR_LCDCLK_CTRL);
+#endif
+#ifdef CONFIG_SPI_PL022
+ tmp = __raw_readl(LPC32XX_CLKPWR_SSP_CLK_CTRL);
+ __raw_writel((tmp | LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN),
+ LPC32XX_CLKPWR_SSP_CLK_CTRL);
+#endif
+
+ platform_add_devices(phy3250_devs, ARRAY_SIZE(phy3250_devs));
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+ /* Test clock needed for UDA1380 initial init */
+ __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC |
+ LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN,
+ LPC32XX_CLKPWR_TEST_CLK_SEL);
+
+ i2c_register_board_info(0, phy3250_i2c_board_info,
+ ARRAY_SIZE(phy3250_i2c_board_info));
+}
+
+static int __init lpc32xx_display_uid(void)
+{
+ u32 uid[4];
+
+ lpc32xx_get_uid(uid);
+
+ printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n",
+ uid[3], uid[2], uid[1], uid[0]);
+
+ return 1;
+}
+arch_initcall(lpc32xx_display_uid);
+
+MACHINE_START(PHY3250, "Phytec 3250 board with the LPC3250 Microcontroller")
+ /* Maintainer: Kevin Wells, NXP Semiconductors */
+ .boot_params = 0x80000100,
+ .map_io = lpc32xx_map_io,
+ .init_irq = lpc32xx_init_irq,
+ .timer = &lpc32xx_timer,
+ .init_machine = phy3250_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c
new file mode 100644
index 00000000..b9c80597
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/pm.c
@@ -0,0 +1,146 @@
+/*
+ * arch/arm/mach-lpc32xx/pm.c
+ *
+ * Original authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ * Modified by Kevin Wells <kevin.wells@nxp.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+/*
+ * LPC32XX CPU and system power management
+ *
+ * The LCP32XX has three CPU modes for controlling system power: run,
+ * direct-run, and halt modes. When switching between halt and run modes,
+ * the CPU transistions through direct-run mode. For Linux, direct-run
+ * mode is not used in normal operation. Halt mode is used when the
+ * system is fully suspended.
+ *
+ * Run mode:
+ * The ARM CPU clock (HCLK_PLL), HCLK bus clock, and PCLK bus clocks are
+ * derived from the HCLK PLL. The HCLK and PCLK bus rates are divided from
+ * the HCLK_PLL rate. Linux runs in this mode.
+ *
+ * Direct-run mode:
+ * The ARM CPU clock, HCLK bus clock, and PCLK bus clocks are driven from
+ * SYSCLK. SYSCLK is usually around 13MHz, but may vary based on SYSCLK
+ * source or the frequency of the main oscillator. In this mode, the
+ * HCLK_PLL can be safely enabled, changed, or disabled.
+ *
+ * Halt mode:
+ * SYSCLK is gated off and the CPU and system clocks are halted.
+ * Peripherals based on the 32KHz oscillator clock (ie, RTC, touch,
+ * key scanner, etc.) still operate if enabled. In this state, an enabled
+ * system event (ie, GPIO state change, RTC match, key press, etc.) will
+ * wake the system up back into direct-run mode.
+ *
+ * DRAM refresh
+ * DRAM clocking and refresh are slightly different for systems with DDR
+ * DRAM or regular SDRAM devices. If SDRAM is used in the system, the
+ * SDRAM will still be accessible in direct-run mode. In DDR based systems,
+ * a transition to direct-run mode will stop all DDR accesses (no clocks).
+ * Because of this, the code to switch power modes and the code to enter
+ * and exit DRAM self-refresh modes must not be executed in DRAM. A small
+ * section of IRAM is used instead for this.
+ *
+ * Suspend is handled with the following logic:
+ * Backup a small area of IRAM used for the suspend code
+ * Copy suspend code to IRAM
+ * Transfer control to code in IRAM
+ * Places DRAMs in self-refresh mode
+ * Enter direct-run mode
+ * Save state of HCLK_PLL PLL
+ * Disable HCLK_PLL PLL
+ * Enter halt mode - CPU and buses will stop
+ * System enters direct-run mode when an enabled event occurs
+ * HCLK PLL state is restored
+ * Run mode is entered
+ * DRAMS are placed back into normal mode
+ * Code execution returns from IRAM
+ * IRAM code are used for suspend is restored
+ * Suspend mode is exited
+ */
+
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+#include "clock.h"
+
+#define TEMP_IRAM_AREA IO_ADDRESS(LPC32XX_IRAM_BASE)
+
+/*
+ * Both STANDBY and MEM suspend states are handled the same with no
+ * loss of CPU or memory state
+ */
+static int lpc32xx_pm_enter(suspend_state_t state)
+{
+ int (*lpc32xx_suspend_ptr) (void);
+ void *iram_swap_area;
+
+ /* Allocate some space for temporary IRAM storage */
+ iram_swap_area = kmalloc(lpc32xx_sys_suspend_sz, GFP_KERNEL);
+ if (!iram_swap_area) {
+ printk(KERN_ERR
+ "PM Suspend: cannot allocate memory to save portion "
+ "of SRAM\n");
+ return -ENOMEM;
+ }
+
+ /* Backup a small area of IRAM used for the suspend code */
+ memcpy(iram_swap_area, (void *) TEMP_IRAM_AREA,
+ lpc32xx_sys_suspend_sz);
+
+ /*
+ * Copy code to suspend system into IRAM. The suspend code
+ * needs to run from IRAM as DRAM may no longer be available
+ * when the PLL is stopped.
+ */
+ memcpy((void *) TEMP_IRAM_AREA, &lpc32xx_sys_suspend,
+ lpc32xx_sys_suspend_sz);
+ flush_icache_range((unsigned long)TEMP_IRAM_AREA,
+ (unsigned long)(TEMP_IRAM_AREA) + lpc32xx_sys_suspend_sz);
+
+ /* Transfer to suspend code in IRAM */
+ lpc32xx_suspend_ptr = (void *) TEMP_IRAM_AREA;
+ flush_cache_all();
+ (void) lpc32xx_suspend_ptr();
+
+ /* Restore original IRAM contents */
+ memcpy((void *) TEMP_IRAM_AREA, iram_swap_area,
+ lpc32xx_sys_suspend_sz);
+
+ kfree(iram_swap_area);
+
+ return 0;
+}
+
+static const struct platform_suspend_ops lpc32xx_pm_ops = {
+ .valid = suspend_valid_only_mem,
+ .enter = lpc32xx_pm_enter,
+};
+
+#define EMC_DYN_MEM_CTRL_OFS 0x20
+#define EMC_SRMMC (1 << 3)
+#define EMC_CTRL_REG io_p2v(LPC32XX_EMC_BASE + EMC_DYN_MEM_CTRL_OFS)
+static int __init lpc32xx_pm_init(void)
+{
+ /*
+ * Setup SDRAM self-refresh clock to automatically disable o
+ * start of self-refresh. This only needs to be done once.
+ */
+ __raw_writel(__raw_readl(EMC_CTRL_REG) | EMC_SRMMC, EMC_CTRL_REG);
+
+ suspend_set_ops(&lpc32xx_pm_ops);
+
+ return 0;
+}
+arch_initcall(lpc32xx_pm_init);
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
new file mode 100644
index 00000000..f2735281
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -0,0 +1,208 @@
+/*
+ * arch/arm/mach-lpc32xx/serial.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+#define LPC32XX_SUART_FIFO_SIZE 64
+
+/* Standard 8250/16550 compatible serial ports */
+static struct plat_serial8250_port serial_std_platform_data[] = {
+#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT
+ {
+ .membase = io_p2v(LPC32XX_UART5_BASE),
+ .mapbase = LPC32XX_UART5_BASE,
+ .irq = IRQ_LPC32XX_UART_IIR5,
+ .uartclk = LPC32XX_MAIN_OSC_FREQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART |
+ UPF_SKIP_TEST,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
+ {
+ .membase = io_p2v(LPC32XX_UART3_BASE),
+ .mapbase = LPC32XX_UART3_BASE,
+ .irq = IRQ_LPC32XX_UART_IIR3,
+ .uartclk = LPC32XX_MAIN_OSC_FREQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART |
+ UPF_SKIP_TEST,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
+ {
+ .membase = io_p2v(LPC32XX_UART4_BASE),
+ .mapbase = LPC32XX_UART4_BASE,
+ .irq = IRQ_LPC32XX_UART_IIR4,
+ .uartclk = LPC32XX_MAIN_OSC_FREQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART |
+ UPF_SKIP_TEST,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
+ {
+ .membase = io_p2v(LPC32XX_UART6_BASE),
+ .mapbase = LPC32XX_UART6_BASE,
+ .irq = IRQ_LPC32XX_UART_IIR6,
+ .uartclk = LPC32XX_MAIN_OSC_FREQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM32,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART |
+ UPF_SKIP_TEST,
+ },
+#endif
+ { },
+};
+
+struct uartinit {
+ char *uart_ck_name;
+ u32 ck_mode_mask;
+ void __iomem *pdiv_clk_reg;
+ resource_size_t mapbase;
+};
+
+static struct uartinit uartinit_data[] __initdata = {
+#ifdef CONFIG_ARCH_LPC32XX_UART5_SELECT
+ {
+ .uart_ck_name = "uart5_ck",
+ .ck_mode_mask =
+ LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5),
+ .pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL,
+ .mapbase = LPC32XX_UART5_BASE,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
+ {
+ .uart_ck_name = "uart3_ck",
+ .ck_mode_mask =
+ LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3),
+ .pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL,
+ .mapbase = LPC32XX_UART3_BASE,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
+ {
+ .uart_ck_name = "uart4_ck",
+ .ck_mode_mask =
+ LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4),
+ .pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL,
+ .mapbase = LPC32XX_UART4_BASE,
+ },
+#endif
+#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
+ {
+ .uart_ck_name = "uart6_ck",
+ .ck_mode_mask =
+ LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6),
+ .pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL,
+ .mapbase = LPC32XX_UART6_BASE,
+ },
+#endif
+};
+
+static struct platform_device serial_std_platform_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_std_platform_data,
+ },
+};
+
+static struct platform_device *lpc32xx_serial_devs[] __initdata = {
+ &serial_std_platform_device,
+};
+
+void __init lpc32xx_serial_init(void)
+{
+ u32 tmp, clkmodes = 0;
+ struct clk *clk;
+ unsigned int puart;
+ int i, j;
+
+ /* UART clocks are off, let clock driver manage them */
+ __raw_writel(0, LPC32XX_CLKPWR_UART_CLK_CTRL);
+
+ for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
+ clk = clk_get(NULL, uartinit_data[i].uart_ck_name);
+ if (!IS_ERR(clk)) {
+ clk_enable(clk);
+ serial_std_platform_data[i].uartclk =
+ clk_get_rate(clk);
+ }
+
+ /* Fall back on main osc rate if clock rate return fails */
+ if (serial_std_platform_data[i].uartclk == 0)
+ serial_std_platform_data[i].uartclk =
+ LPC32XX_MAIN_OSC_FREQ;
+
+ /* Setup UART clock modes for all UARTs, disable autoclock */
+ clkmodes |= uartinit_data[i].ck_mode_mask;
+
+ /* pre-UART clock divider set to 1 */
+ __raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg);
+
+ /*
+ * Force a flush of the RX FIFOs to work around a
+ * HW bug
+ */
+ puart = uartinit_data[i].mapbase;
+ __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
+ __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
+ j = LPC32XX_SUART_FIFO_SIZE;
+ while (j--)
+ tmp = __raw_readl(
+ LPC32XX_UART_DLL_FIFO(puart));
+ __raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
+ }
+
+ /* This needs to be done after all UART clocks are setup */
+ __raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE);
+ for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
+ /* Force a flush of the RX FIFOs to work around a HW bug */
+ puart = serial_std_platform_data[i].mapbase;
+ __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
+ __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
+ j = LPC32XX_SUART_FIFO_SIZE;
+ while (j--)
+ tmp = __raw_readl(LPC32XX_UART_DLL_FIFO(puart));
+ __raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
+ }
+
+ /* Disable UART5->USB transparent mode or USB won't work */
+ tmp = __raw_readl(LPC32XX_UARTCTL_CTRL);
+ tmp &= ~LPC32XX_UART_U5_ROUTE_TO_USB;
+ __raw_writel(tmp, LPC32XX_UARTCTL_CTRL);
+
+ platform_add_devices(lpc32xx_serial_devs,
+ ARRAY_SIZE(lpc32xx_serial_devs));
+}
diff --git a/arch/arm/mach-lpc32xx/suspend.S b/arch/arm/mach-lpc32xx/suspend.S
new file mode 100644
index 00000000..374f9f07
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/suspend.S
@@ -0,0 +1,151 @@
+/*
+ * arch/arm/mach-lpc32xx/suspend.S
+ *
+ * Original authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
+ * Modified by Kevin Wells <kevin.wells@nxp.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/platform.h>
+#include <mach/hardware.h>
+
+/* Using named register defines makes the code easier to follow */
+#define WORK1_REG r0
+#define WORK2_REG r1
+#define SAVED_HCLK_DIV_REG r2
+#define SAVED_HCLK_PLL_REG r3
+#define SAVED_DRAM_CLKCTRL_REG r4
+#define SAVED_PWR_CTRL_REG r5
+#define CLKPWRBASE_REG r6
+#define EMCBASE_REG r7
+
+#define LPC32XX_EMC_STATUS_OFFS 0x04
+#define LPC32XX_EMC_STATUS_BUSY 0x1
+#define LPC32XX_EMC_STATUS_SELF_RFSH 0x4
+
+#define LPC32XX_CLKPWR_PWR_CTRL_OFFS 0x44
+#define LPC32XX_CLKPWR_HCLK_DIV_OFFS 0x40
+#define LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS 0x58
+
+#define CLKPWR_PCLK_DIV_MASK 0xFFFFFE7F
+
+ .text
+
+ENTRY(lpc32xx_sys_suspend)
+ @ Save a copy of the used registers in IRAM, r0 is corrupted
+ adr r0, tmp_stack_end
+ stmfd r0!, {r3 - r7, sp, lr}
+
+ @ Load a few common register addresses
+ adr WORK1_REG, reg_bases
+ ldr CLKPWRBASE_REG, [WORK1_REG, #0]
+ ldr EMCBASE_REG, [WORK1_REG, #4]
+
+ ldr SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+ orr WORK1_REG, SAVED_PWR_CTRL_REG, #LPC32XX_CLKPWR_SDRAM_SELF_RFSH
+
+ @ Wait for SDRAM busy status to go busy and then idle
+ @ This guarantees a small windows where DRAM isn't busy
+1:
+ ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
+ and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
+ cmp WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
+ bne 1b @ Branch while idle
+2:
+ ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
+ and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
+ cmp WORK2_REG, #LPC32XX_EMC_STATUS_BUSY
+ beq 2b @ Branch until idle
+
+ @ Setup self-refresh with support for manual exit of
+ @ self-refresh mode
+ str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+ orr WORK2_REG, WORK1_REG, #LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
+ str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+ str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+
+ @ Wait for self-refresh acknowledge, clocks to the DRAM device
+ @ will automatically stop on start of self-refresh
+3:
+ ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
+ and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
+ cmp WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
+ bne 3b @ Branch until self-refresh mode starts
+
+ @ Enter direct-run mode from run mode
+ bic WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_SELECT_RUN_MODE
+ str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+
+ @ Safe disable of DRAM clock in EMC block, prevents DDR sync
+ @ issues on restart
+ ldr SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_HCLK_DIV_OFFS]
+ and WORK2_REG, SAVED_HCLK_DIV_REG, #CLKPWR_PCLK_DIV_MASK
+ str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLK_DIV_OFFS]
+
+ @ Save HCLK PLL state and disable HCLK PLL
+ ldr SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
+ bic WORK2_REG, SAVED_HCLK_PLL_REG, #LPC32XX_CLKPWR_HCLKPLL_POWER_UP
+ str WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
+
+ @ Enter stop mode until an enabled event occurs
+ orr WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL
+ str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+ .rept 9
+ nop
+ .endr
+
+ @ Clear stop status
+ bic WORK1_REG, WORK1_REG, #LPC32XX_CLKPWR_STOP_MODE_CTRL
+
+ @ Restore original HCLK PLL value and wait for PLL lock
+ str SAVED_HCLK_PLL_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
+4:
+ ldr WORK2_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_HCLKPLL_CTRL_OFFS]
+ and WORK2_REG, WORK2_REG, #LPC32XX_CLKPWR_HCLKPLL_PLL_STS
+ bne 4b
+
+ @ Re-enter run mode with self-refresh flag cleared, but no DRAM
+ @ update yet. DRAM is still in self-refresh
+ str SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+
+ @ Restore original DRAM clock mode to restore DRAM clocks
+ str SAVED_HCLK_DIV_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_HCLK_DIV_OFFS]
+
+ @ Clear self-refresh mode
+ orr WORK1_REG, SAVED_PWR_CTRL_REG,\
+ #LPC32XX_CLKPWR_UPD_SDRAM_SELF_RFSH
+ str WORK1_REG, [CLKPWRBASE_REG, #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+ str SAVED_PWR_CTRL_REG, [CLKPWRBASE_REG,\
+ #LPC32XX_CLKPWR_PWR_CTRL_OFFS]
+
+ @ Wait for EMC to clear self-refresh mode
+5:
+ ldr WORK2_REG, [EMCBASE_REG, #LPC32XX_EMC_STATUS_OFFS]
+ and WORK2_REG, WORK2_REG, #LPC32XX_EMC_STATUS_SELF_RFSH
+ bne 5b @ Branch until self-refresh has exited
+
+ @ restore regs and return
+ adr r0, tmp_stack
+ ldmfd r0!, {r3 - r7, sp, pc}
+
+reg_bases:
+ .long IO_ADDRESS(LPC32XX_CLK_PM_BASE)
+ .long IO_ADDRESS(LPC32XX_EMC_BASE)
+
+tmp_stack:
+ .long 0, 0, 0, 0, 0, 0, 0
+tmp_stack_end:
+
+ENTRY(lpc32xx_sys_suspend_sz)
+ .word . - lpc32xx_sys_suspend
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
new file mode 100644
index 00000000..b42c909b
--- /dev/null
+++ b/arch/arm/mach-lpc32xx/timer.c
@@ -0,0 +1,168 @@
+/*
+ * arch/arm/mach-lpc32xx/timer.c
+ *
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2009 - 2010 NXP Semiconductors
+ * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
+ * Ed Schouten <e.schouten@fontys.nl>
+ * Laurens Timmermans <l.timmermans@fontys.nl>
+ *
+ * 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.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/err.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include "common.h"
+
+static int lpc32xx_clkevt_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET,
+ LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+ __raw_writel(delta, LCP32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
+ __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
+ LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+
+ return 0;
+}
+
+static void lpc32xx_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ WARN_ON(1);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /*
+ * Disable the timer. When using oneshot, we must also
+ * disable the timer to wait for the first call to
+ * set_next_event().
+ */
+ __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device lpc32xx_clkevt = {
+ .name = "lpc32xx_clkevt",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 300,
+ .set_next_event = lpc32xx_clkevt_next_event,
+ .set_mode = lpc32xx_clkevt_mode,
+};
+
+static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &lpc32xx_clkevt;
+
+ /* Clear match */
+ __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0),
+ LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction lpc32xx_timer_irq = {
+ .name = "LPC32XX Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = lpc32xx_timer_interrupt,
+};
+
+/*
+ * The clock management driver isn't initialized at this point, so the
+ * clocks need to be enabled here manually and then tagged as used in
+ * the clock driver initialization
+ */
+static void __init lpc32xx_timer_init(void)
+{
+ u32 clkrate, pllreg;
+
+ /* Enable timer clock */
+ __raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN |
+ LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
+ LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1);
+
+ /*
+ * The clock driver isn't initialized at this point. So determine if
+ * the SYSCLK is driven from the PLL397 or main oscillator and then use
+ * it to compute the PLL frequency and the PCLK divider to get the base
+ * timer rates. This rate is needed to compute the tick rate.
+ */
+ if (clk_is_sysclk_mainosc() != 0)
+ clkrate = LPC32XX_MAIN_OSC_FREQ;
+ else
+ clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ;
+
+ /* Get ARM HCLKPLL register and convert it into a frequency */
+ pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
+ clkrate = clk_get_pllrate_from_reg(clkrate, pllreg);
+
+ /* Get PCLK divider and divide ARM PLL clock by it to get timer rate */
+ clkrate = clkrate / clk_get_pclk_div();
+
+ /* Initial timer setup */
+ __raw_writel(0, LCP32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
+ __raw_writel(LCP32XX_TIMER_CNTR_MTCH_BIT(0),
+ LCP32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
+ __raw_writel(1, LCP32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
+ __raw_writel(LCP32XX_TIMER_CNTR_MCR_MTCH(0) |
+ LCP32XX_TIMER_CNTR_MCR_STOP(0) |
+ LCP32XX_TIMER_CNTR_MCR_RESET(0),
+ LCP32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
+
+ /* Setup tick interrupt */
+ setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);
+
+ /* Setup the clockevent structure. */
+ lpc32xx_clkevt.mult = div_sc(clkrate, NSEC_PER_SEC,
+ lpc32xx_clkevt.shift);
+ lpc32xx_clkevt.max_delta_ns = clockevent_delta2ns(-1,
+ &lpc32xx_clkevt);
+ lpc32xx_clkevt.min_delta_ns = clockevent_delta2ns(1,
+ &lpc32xx_clkevt) + 1;
+ lpc32xx_clkevt.cpumask = cpumask_of(0);
+ clockevents_register_device(&lpc32xx_clkevt);
+
+ /* Use timer1 as clock source. */
+ __raw_writel(LCP32XX_TIMER_CNTR_TCR_RESET,
+ LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+ __raw_writel(0, LCP32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
+ __raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
+ __raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
+ LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
+
+ clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
+ "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
+}
+
+struct sys_timer lpc32xx_timer = {
+ .init = &lpc32xx_timer_init,
+};
+
diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig
new file mode 100644
index 00000000..67793a69
--- /dev/null
+++ b/arch/arm/mach-mmp/Kconfig
@@ -0,0 +1,99 @@
+if ARCH_MMP
+
+menu "Marvell PXA168/910/MMP2 Implmentations"
+
+config MACH_ASPENITE
+ bool "Marvell's PXA168 Aspenite Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Aspenite Development Board.
+
+config MACH_ZYLONITE2
+ bool "Marvell's PXA168 Zylonite2 Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Zylonite2 Development Board.
+
+config MACH_AVENGERS_LITE
+ bool "Marvell's PXA168 Avengers Lite Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Avengers Lite Development Board.
+
+config MACH_TAVOREVB
+ bool "Marvell's PXA910 TavorEVB Development Board"
+ select CPU_PXA910
+ help
+ Say 'Y' here if you want to support the Marvell PXA910-based
+ TavorEVB Development Board.
+
+config MACH_TTC_DKB
+ bool "Marvell's PXA910 TavorEVB Development Board"
+ select CPU_PXA910
+ help
+ Say 'Y' here if you want to support the Marvell PXA910-based
+ TTC_DKB Development Board.
+
+config MACH_BROWNSTONE
+ bool "Marvell's Brownstone Development Platform"
+ depends on !CPU_MOHAWK
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-based
+ Brown Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv7 architecture.
+
+config MACH_FLINT
+ bool "Marvell's Flint Development Platform"
+ depends on !CPU_MOHAWK
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-based
+ Flint Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv7 architecture.
+
+config MACH_MARVELL_JASPER
+ bool "Marvell's Jasper Development Platform"
+ depends on !CPU_MOHAWK
+ select CPU_MMP2
+ help
+ Say 'Y' here if you want to support the Marvell MMP2-base
+ Jasper Development Platform.
+ MMP2-based board can't be co-existed with PXA168-based &
+ PXA910-based development board. Since MMP2 is compatible to
+ ARMv7 architecture.
+
+config MACH_TETON_BGA
+ bool "Marvell's PXA168 Teton BGA Development Board"
+ select CPU_PXA168
+ help
+ Say 'Y' here if you want to support the Marvell PXA168-based
+ Teton BGA Development Board.
+
+endmenu
+
+config CPU_PXA168
+ bool
+ select CPU_MOHAWK
+ help
+ Select code specific to PXA168
+
+config CPU_PXA910
+ bool
+ select CPU_MOHAWK
+ help
+ Select code specific to PXA910
+
+config CPU_MMP2
+ bool
+ select CPU_PJ4
+ help
+ Select code specific to MMP2. MMP2 is ARMv7 compatible.
+endif
diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile
new file mode 100644
index 00000000..5c683821
--- /dev/null
+++ b/arch/arm/mach-mmp/Makefile
@@ -0,0 +1,21 @@
+#
+# Makefile for Marvell's PXA168 processors line
+#
+
+obj-y += common.o clock.o devices.o time.o
+
+# SoC support
+obj-$(CONFIG_CPU_PXA168) += pxa168.o irq-pxa168.o
+obj-$(CONFIG_CPU_PXA910) += pxa910.o irq-pxa168.o
+obj-$(CONFIG_CPU_MMP2) += mmp2.o irq-mmp2.o
+
+# board support
+obj-$(CONFIG_MACH_ASPENITE) += aspenite.o
+obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o
+obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o
+obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
+obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o
+obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o
+obj-$(CONFIG_MACH_FLINT) += flint.o
+obj-$(CONFIG_MACH_MARVELL_JASPER) += jasper.o
+obj-$(CONFIG_MACH_TETON_BGA) += teton_bga.o
diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot
new file mode 100644
index 00000000..574a4aa8
--- /dev/null
+++ b/arch/arm/mach-mmp/Makefile.boot
@@ -0,0 +1 @@
+ zreladdr-y := 0x00008000
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
new file mode 100644
index 00000000..06b5fa85
--- /dev/null
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -0,0 +1,253 @@
+/*
+ * linux/arch/arm/mach-mmp/aspenite.c
+ *
+ * Support for the Marvell PXA168-based Aspenite and Zylonite2
+ * Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/gpio.h>
+#include <video/pxa168fb.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
+
+#include "common.h"
+
+static unsigned long common_pin_config[] __initdata = {
+ /* Data Flash Interface */
+ GPIO0_DFI_D15,
+ GPIO1_DFI_D14,
+ GPIO2_DFI_D13,
+ GPIO3_DFI_D12,
+ GPIO4_DFI_D11,
+ GPIO5_DFI_D10,
+ GPIO6_DFI_D9,
+ GPIO7_DFI_D8,
+ GPIO8_DFI_D7,
+ GPIO9_DFI_D6,
+ GPIO10_DFI_D5,
+ GPIO11_DFI_D4,
+ GPIO12_DFI_D3,
+ GPIO13_DFI_D2,
+ GPIO14_DFI_D1,
+ GPIO15_DFI_D0,
+
+ /* Static Memory Controller */
+ GPIO18_SMC_nCS0,
+ GPIO34_SMC_nCS1,
+ GPIO23_SMC_nLUA,
+ GPIO25_SMC_nLLA,
+ GPIO28_SMC_RDY,
+ GPIO29_SMC_SCLK,
+ GPIO35_SMC_BE1,
+ GPIO36_SMC_BE2,
+ GPIO27_GPIO, /* Ethernet IRQ */
+
+ /* UART1 */
+ GPIO107_UART1_RXD,
+ GPIO108_UART1_TXD,
+
+ /* SSP1 */
+ GPIO113_I2S_MCLK,
+ GPIO114_I2S_FRM,
+ GPIO115_I2S_BCLK,
+ GPIO116_I2S_RXD,
+ GPIO117_I2S_TXD,
+
+ /* LCD */
+ GPIO56_LCD_FCLK_RD,
+ GPIO57_LCD_LCLK_A0,
+ GPIO58_LCD_PCLK_WR,
+ GPIO59_LCD_DENA_BIAS,
+ GPIO60_LCD_DD0,
+ GPIO61_LCD_DD1,
+ GPIO62_LCD_DD2,
+ GPIO63_LCD_DD3,
+ GPIO64_LCD_DD4,
+ GPIO65_LCD_DD5,
+ GPIO66_LCD_DD6,
+ GPIO67_LCD_DD7,
+ GPIO68_LCD_DD8,
+ GPIO69_LCD_DD9,
+ GPIO70_LCD_DD10,
+ GPIO71_LCD_DD11,
+ GPIO72_LCD_DD12,
+ GPIO73_LCD_DD13,
+ GPIO74_LCD_DD14,
+ GPIO75_LCD_DD15,
+ GPIO76_LCD_DD16,
+ GPIO77_LCD_DD17,
+ GPIO78_LCD_DD18,
+ GPIO79_LCD_DD19,
+ GPIO80_LCD_DD20,
+ GPIO81_LCD_DD21,
+ GPIO82_LCD_DD22,
+ GPIO83_LCD_DD23,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+ GPIO121_KP_MKIN4,
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(27),
+ .end = gpio_to_irq(27),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct mtd_partition aspenite_nand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_8M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (SZ_2M + SZ_1M),
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_48M,
+ .mask_flags = 0,
+ }
+};
+
+static struct pxa3xx_nand_platform_data aspenite_nand_info = {
+ .enable_arbiter = 1,
+ .parts = aspenite_nand_partitions,
+ .nr_parts = ARRAY_SIZE(aspenite_nand_partitions),
+};
+
+static struct i2c_board_info aspenite_i2c_info[] __initdata = {
+ { I2C_BOARD_INFO("wm8753", 0x1b), },
+};
+
+static struct fb_videomode video_modes[] = {
+ [0] = {
+ .pixclock = 30120,
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .hsync_len = 1,
+ .left_margin = 215,
+ .right_margin = 40,
+ .vsync_len = 1,
+ .upper_margin = 34,
+ .lower_margin = 10,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ },
+};
+
+struct pxa168fb_mach_info aspenite_lcd_info = {
+ .id = "Graphic Frame",
+ .modes = video_modes,
+ .num_modes = ARRAY_SIZE(video_modes),
+ .pix_fmt = PIX_FMT_RGB565,
+ .io_pin_allocation_mode = PIN_MODE_DUMB_24,
+ .dumb_mode = DUMB_MODE_RGB888,
+ .active = 1,
+ .panel_rbswap = 0,
+ .invert_pixclock = 0,
+};
+
+static unsigned int aspenite_matrix_key_map[] = {
+ KEY(0, 6, KEY_UP), /* SW 4 */
+ KEY(0, 7, KEY_DOWN), /* SW 5 */
+ KEY(1, 6, KEY_LEFT), /* SW 6 */
+ KEY(1, 7, KEY_RIGHT), /* SW 7 */
+ KEY(4, 6, KEY_ENTER), /* SW 8 */
+ KEY(4, 7, KEY_ESC), /* SW 9 */
+};
+
+static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 8,
+ .matrix_key_map = aspenite_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(aspenite_matrix_key_map),
+ .debounce_interval = 30,
+};
+
+static void __init common_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+ /* on-chip devices */
+ pxa168_add_uart(1);
+ pxa168_add_twsi(1, NULL, ARRAY_AND_SIZE(aspenite_i2c_info));
+ pxa168_add_ssp(1);
+ pxa168_add_nand(&aspenite_nand_info);
+ pxa168_add_fb(&aspenite_lcd_info);
+ pxa168_add_keypad(&aspenite_keypad_info);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = common_init,
+MACHINE_END
+
+MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = common_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c
new file mode 100644
index 00000000..39f0878d
--- /dev/null
+++ b/arch/arm/mach-mmp/avengers_lite.c
@@ -0,0 +1,48 @@
+/*
+ * linux/arch/arm/mach-mmp/avengers_lite.c
+ *
+ * Support for the Marvell PXA168-based Avengers lite Development Platform.
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/irqs.h>
+
+
+#include "common.h"
+#include <linux/delay.h>
+
+/* Avengers lite MFP configurations */
+static unsigned long avengers_lite_pin_config_V16F[] __initdata = {
+ /* DEBUG_UART */
+ GPIO88_UART2_TXD,
+ GPIO89_UART2_RXD,
+};
+
+static void __init avengers_lite_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(avengers_lite_pin_config_V16F));
+
+ /* on-chip devices */
+ pxa168_add_uart(2);
+}
+
+MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
+ .map_io = mmp_map_io,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = avengers_lite_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c
new file mode 100644
index 00000000..7bb78fd5
--- /dev/null
+++ b/arch/arm/mach-mmp/brownstone.c
@@ -0,0 +1,204 @@
+/*
+ * linux/arch/arm/mach-mmp/brownstone.c
+ *
+ * Support for the Marvell Brownstone Development Platform.
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max8925.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40)
+
+#define GPIO_5V_ENABLE (89)
+
+static unsigned long brownstone_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO29_UART1_RXD,
+ GPIO30_UART1_TXD,
+
+ /* UART3 */
+ GPIO51_UART3_RXD,
+ GPIO52_UART3_TXD,
+
+ /* DFI */
+ GPIO168_DFI_D0,
+ GPIO167_DFI_D1,
+ GPIO166_DFI_D2,
+ GPIO165_DFI_D3,
+ GPIO107_DFI_D4,
+ GPIO106_DFI_D5,
+ GPIO105_DFI_D6,
+ GPIO104_DFI_D7,
+ GPIO111_DFI_D8,
+ GPIO164_DFI_D9,
+ GPIO163_DFI_D10,
+ GPIO162_DFI_D11,
+ GPIO161_DFI_D12,
+ GPIO110_DFI_D13,
+ GPIO109_DFI_D14,
+ GPIO108_DFI_D15,
+ GPIO143_ND_nCS0,
+ GPIO144_ND_nCS1,
+ GPIO147_ND_nWE,
+ GPIO148_ND_nRE,
+ GPIO150_ND_ALE,
+ GPIO149_ND_CLE,
+ GPIO112_ND_RDY0,
+ GPIO160_ND_RDY1,
+
+ /* PMIC */
+ PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+
+ /* MMC0 */
+ GPIO131_MMC1_DAT3 | MFP_PULL_HIGH,
+ GPIO132_MMC1_DAT2 | MFP_PULL_HIGH,
+ GPIO133_MMC1_DAT1 | MFP_PULL_HIGH,
+ GPIO134_MMC1_DAT0 | MFP_PULL_HIGH,
+ GPIO136_MMC1_CMD | MFP_PULL_HIGH,
+ GPIO139_MMC1_CLK,
+ GPIO140_MMC1_CD | MFP_PULL_LOW,
+ GPIO141_MMC1_WP | MFP_PULL_LOW,
+
+ /* MMC1 */
+ GPIO37_MMC2_DAT3 | MFP_PULL_HIGH,
+ GPIO38_MMC2_DAT2 | MFP_PULL_HIGH,
+ GPIO39_MMC2_DAT1 | MFP_PULL_HIGH,
+ GPIO40_MMC2_DAT0 | MFP_PULL_HIGH,
+ GPIO41_MMC2_CMD | MFP_PULL_HIGH,
+ GPIO42_MMC2_CLK,
+
+ /* MMC2 */
+ GPIO165_MMC3_DAT7 | MFP_PULL_HIGH,
+ GPIO162_MMC3_DAT6 | MFP_PULL_HIGH,
+ GPIO166_MMC3_DAT5 | MFP_PULL_HIGH,
+ GPIO163_MMC3_DAT4 | MFP_PULL_HIGH,
+ GPIO167_MMC3_DAT3 | MFP_PULL_HIGH,
+ GPIO164_MMC3_DAT2 | MFP_PULL_HIGH,
+ GPIO168_MMC3_DAT1 | MFP_PULL_HIGH,
+ GPIO111_MMC3_DAT0 | MFP_PULL_HIGH,
+ GPIO112_MMC3_CMD | MFP_PULL_HIGH,
+ GPIO151_MMC3_CLK,
+
+ /* 5V regulator */
+ GPIO89_GPIO,
+};
+
+static struct regulator_consumer_supply max8649_supply[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data max8649_init_data = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 1150000,
+ .max_uV = 1280000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8649_supply[0],
+};
+
+static struct max8649_platform_data brownstone_max8649_info = {
+ .mode = 2, /* VID1 = 1, VID0 = 0 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8649_init_data,
+};
+
+static struct regulator_consumer_supply brownstone_v_5vp_supplies[] = {
+ REGULATOR_SUPPLY("v_5vp", NULL),
+};
+
+static struct regulator_init_data brownstone_v_5vp_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(brownstone_v_5vp_supplies),
+ .consumer_supplies = brownstone_v_5vp_supplies,
+};
+
+static struct fixed_voltage_config brownstone_v_5vp = {
+ .supply_name = "v_5vp",
+ .microvolts = 5000000,
+ .gpio = GPIO_5V_ENABLE,
+ .enable_high = 1,
+ .enabled_at_boot = 1,
+ .init_data = &brownstone_v_5vp_data,
+};
+
+static struct platform_device brownstone_v_5vp_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &brownstone_v_5vp,
+ },
+};
+
+static struct max8925_platform_data brownstone_max8925_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+static struct i2c_board_info brownstone_twsi1_info[] = {
+ [0] = {
+ .type = "max8649",
+ .addr = 0x60,
+ .platform_data = &brownstone_max8649_info,
+ },
+ [1] = {
+ .type = "max8925",
+ .addr = 0x3c,
+ .irq = IRQ_MMP2_PMIC,
+ .platform_data = &brownstone_max8925_info,
+ },
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
+ .max_speed = 25000000,
+};
+
+static void __init brownstone_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(brownstone_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(3);
+ mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info));
+ mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+
+ /* enable 5v regulator */
+ platform_device_register(&brownstone_v_5vp_device);
+}
+
+MACHINE_START(BROWNSTONE, "Brownstone Development Platform")
+ /* Maintainer: Haojian Zhuang <haojian.zhuang@marvell.com> */
+ .map_io = mmp_map_io,
+ .nr_irqs = BROWNSTONE_NR_IRQS,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = brownstone_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/clock.c b/arch/arm/mach-mmp/clock.c
new file mode 100644
index 00000000..886e0564
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/mach-mmp/clock.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/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-apbc.h>
+#include "clock.h"
+
+static void apbc_clk_enable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(clk->fnclksel);
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+static void apbc_clk_disable(struct clk *clk)
+{
+ __raw_writel(0, clk->clk_rst);
+}
+
+struct clkops apbc_clk_ops = {
+ .enable = apbc_clk_enable,
+ .disable = apbc_clk_disable,
+};
+
+static void apmu_clk_enable(struct clk *clk)
+{
+ __raw_writel(clk->enable_val, clk->clk_rst);
+}
+
+static void apmu_clk_disable(struct clk *clk)
+{
+ __raw_writel(0, clk->clk_rst);
+}
+
+struct clkops apmu_clk_ops = {
+ .enable = apmu_clk_enable,
+ .disable = apmu_clk_disable,
+};
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ clk->ops->enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ clk->ops->disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ if (clk->ops->getrate)
+ rate = clk->ops->getrate(clk);
+ else
+ rate = clk->rate;
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
diff --git a/arch/arm/mach-mmp/clock.h b/arch/arm/mach-mmp/clock.h
new file mode 100644
index 00000000..9b027d74
--- /dev/null
+++ b/arch/arm/mach-mmp/clock.h
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/arm/mach-mmp/clock.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clkdev.h>
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*getrate)(struct clk *);
+};
+
+struct clk {
+ const struct clkops *ops;
+
+ void __iomem *clk_rst; /* clock reset control register */
+ int fnclksel; /* functional clock select (APBC) */
+ uint32_t enable_val; /* value for clock enable (APMU) */
+ unsigned long rate;
+ int enabled;
+};
+
+extern struct clkops apbc_clk_ops;
+extern struct clkops apmu_clk_ops;
+
+#define APBC_CLK(_name, _reg, _fnclksel, _rate) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APBC_##_reg, \
+ .fnclksel = _fnclksel, \
+ .rate = _rate, \
+ .ops = &apbc_clk_ops, \
+}
+
+#define APBC_CLK_OPS(_name, _reg, _fnclksel, _rate, _ops) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APBC_##_reg, \
+ .fnclksel = _fnclksel, \
+ .rate = _rate, \
+ .ops = _ops, \
+}
+
+#define APMU_CLK(_name, _reg, _eval, _rate) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APMU_##_reg, \
+ .enable_val = _eval, \
+ .rate = _rate, \
+ .ops = &apmu_clk_ops, \
+}
+
+#define APMU_CLK_OPS(_name, _reg, _eval, _rate, _ops) \
+struct clk clk_##_name = { \
+ .clk_rst = (void __iomem *)APMU_##_reg, \
+ .enable_val = _eval, \
+ .rate = _rate, \
+ .ops = _ops, \
+}
+
+#define INIT_CLKREG(_clk, _devname, _conname) \
+ { \
+ .clk = _clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
+extern struct clk clk_pxa168_gpio;
+extern struct clk clk_pxa168_timers;
diff --git a/arch/arm/mach-mmp/common.c b/arch/arm/mach-mmp/common.c
new file mode 100644
index 00000000..0ec0ca80
--- /dev/null
+++ b/arch/arm/mach-mmp/common.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-mmp/common.c
+ *
+ * Code common to PXA168 processor lines
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <mach/addr-map.h>
+#include <mach/cputype.h>
+
+#include "common.h"
+
+#define MMP_CHIPID (AXI_VIRT_BASE + 0x82c00)
+
+unsigned int mmp_chip_id;
+EXPORT_SYMBOL(mmp_chip_id);
+
+static struct map_desc standard_io_desc[] __initdata = {
+ {
+ .pfn = __phys_to_pfn(APB_PHYS_BASE),
+ .virtual = APB_VIRT_BASE,
+ .length = APB_PHYS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .pfn = __phys_to_pfn(AXI_PHYS_BASE),
+ .virtual = AXI_VIRT_BASE,
+ .length = AXI_PHYS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init mmp_map_io(void)
+{
+ iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+
+ /* this is early, initialize mmp_chip_id here */
+ mmp_chip_id = __raw_readl(MMP_CHIPID);
+}
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
new file mode 100644
index 00000000..ec8d65de
--- /dev/null
+++ b/arch/arm/mach-mmp/common.h
@@ -0,0 +1,8 @@
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+struct sys_timer;
+
+extern void timer_init(int irq);
+
+extern void __init icu_init_irq(void);
+extern void __init mmp_map_io(void);
diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c
new file mode 100644
index 00000000..191d9dea
--- /dev/null
+++ b/arch/arm/mach-mmp/devices.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-mmp/devices.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/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/irq.h>
+#include <mach/devices.h>
+
+int __init pxa_register_device(struct pxa_device_desc *desc,
+ void *data, size_t size)
+{
+ struct platform_device *pdev;
+ struct resource res[2 + MAX_RESOURCE_DMA];
+ int i, ret = 0, nres = 0;
+
+ pdev = platform_device_alloc(desc->drv_name, desc->id);
+ if (pdev == NULL)
+ return -ENOMEM;
+
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ memset(res, 0, sizeof(res));
+
+ if (desc->start != -1ul && desc->size > 0) {
+ res[nres].start = desc->start;
+ res[nres].end = desc->start + desc->size - 1;
+ res[nres].flags = IORESOURCE_MEM;
+ nres++;
+ }
+
+ if (desc->irq != NO_IRQ) {
+ res[nres].start = desc->irq;
+ res[nres].end = desc->irq;
+ res[nres].flags = IORESOURCE_IRQ;
+ nres++;
+ }
+
+ for (i = 0; i < MAX_RESOURCE_DMA; i++, nres++) {
+ if (desc->dma[i] == 0)
+ break;
+
+ res[nres].start = desc->dma[i];
+ res[nres].end = desc->dma[i];
+ res[nres].flags = IORESOURCE_DMA;
+ }
+
+ ret = platform_device_add_resources(pdev, res, nres);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+
+ if (data && size) {
+ ret = platform_device_add_data(pdev, data, size);
+ if (ret) {
+ platform_device_put(pdev);
+ return ret;
+ }
+ }
+
+ return platform_device_add(pdev);
+}
diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c
new file mode 100644
index 00000000..c4fd806b
--- /dev/null
+++ b/arch/arm/mach-mmp/flint.c
@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/mach-mmp/flint.c
+ *
+ * Support for the Marvell Flint Development Platform.
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+#define FLINT_NR_IRQS (IRQ_BOARD_START + 48)
+
+static unsigned long flint_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO45_UART1_RXD,
+ GPIO46_UART1_TXD,
+
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+
+ /* SMC */
+ GPIO151_SMC_SCLK,
+ GPIO145_SMC_nCS0,
+ GPIO146_SMC_nCS1,
+ GPIO152_SMC_BE0,
+ GPIO153_SMC_BE1,
+ GPIO154_SMC_IRQ,
+ GPIO113_SMC_RDY,
+
+ /*Ethernet*/
+ GPIO155_GPIO,
+
+ /* DFI */
+ GPIO168_DFI_D0,
+ GPIO167_DFI_D1,
+ GPIO166_DFI_D2,
+ GPIO165_DFI_D3,
+ GPIO107_DFI_D4,
+ GPIO106_DFI_D5,
+ GPIO105_DFI_D6,
+ GPIO104_DFI_D7,
+ GPIO111_DFI_D8,
+ GPIO164_DFI_D9,
+ GPIO163_DFI_D10,
+ GPIO162_DFI_D11,
+ GPIO161_DFI_D12,
+ GPIO110_DFI_D13,
+ GPIO109_DFI_D14,
+ GPIO108_DFI_D15,
+ GPIO143_ND_nCS0,
+ GPIO144_ND_nCS1,
+ GPIO147_ND_nWE,
+ GPIO148_ND_nRE,
+ GPIO150_ND_ALE,
+ GPIO149_ND_CLE,
+ GPIO112_ND_RDY0,
+ GPIO160_ND_RDY1,
+};
+
+static struct smc91x_platdata flint_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(155),
+ .end = gpio_to_irq(155),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &flint_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init flint_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(flint_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(2);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(FLINT, "Flint Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = FLINT_NR_IRQS,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = flint_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h
new file mode 100644
index 00000000..3254089a
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/addr-map.h
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/addr-map.h
+ *
+ * Common address 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_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/* APB - Application Subsystem Peripheral Bus
+ *
+ * NOTE: the DMA controller registers are actually on the AXI fabric #1
+ * slave port to AHB/APB bridge, due to its close relationship to those
+ * peripherals on APB, let's count it into the ABP mapping area.
+ */
+#define APB_PHYS_BASE 0xd4000000
+#define APB_VIRT_BASE 0xfe000000
+#define APB_PHYS_SIZE 0x00200000
+
+#define AXI_PHYS_BASE 0xd4200000
+#define AXI_VIRT_BASE 0xfe200000
+#define AXI_PHYS_SIZE 0x00200000
+
+/* Static Memory Controller - Chip Select 0 and 1 */
+#define SMC_CS0_PHYS_BASE 0x80000000
+#define SMC_CS0_PHYS_SIZE 0x10000000
+#define SMC_CS1_PHYS_BASE 0x90000000
+#define SMC_CS1_PHYS_SIZE 0x10000000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
diff --git a/arch/arm/mach-mmp/include/mach/clkdev.h b/arch/arm/mach-mmp/include/mach/clkdev.h
new file mode 100644
index 00000000..2fb354e5
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* __ASM_MACH_CLKDEV_H */
diff --git a/arch/arm/mach-mmp/include/mach/cputype.h b/arch/arm/mach-mmp/include/mach/cputype.h
new file mode 100644
index 00000000..8a3b56df
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/cputype.h
@@ -0,0 +1,55 @@
+#ifndef __ASM_MACH_CPUTYPE_H
+#define __ASM_MACH_CPUTYPE_H
+
+#include <asm/cputype.h>
+
+/*
+ * CPU Stepping CPU_ID CHIP_ID
+ *
+ * PXA168 S0 0x56158400 0x0000C910
+ * PXA168 A0 0x56158400 0x00A0A168
+ * PXA910 Y1 0x56158400 0x00F2C920
+ * PXA910 A0 0x56158400 0x00F2C910
+ * PXA910 A1 0x56158400 0x00A0C910
+ * PXA920 Y0 0x56158400 0x00F2C920
+ * PXA920 A0 0x56158400 0x00A0C920
+ * PXA920 A1 0x56158400 0x00A1C920
+ * MMP2 Z0 0x560f5811 0x00F00410
+ * MMP2 Z1 0x560f5811 0x00E00410
+ * MMP2 A0 0x560f5811 0x00A0A610
+ */
+
+extern unsigned int mmp_chip_id;
+
+#ifdef CONFIG_CPU_PXA168
+static inline int cpu_is_pxa168(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ ((mmp_chip_id & 0xfff) == 0x168);
+}
+#else
+#define cpu_is_pxa168() (0)
+#endif
+
+/* cpu_is_pxa910() is shared on both pxa910 and pxa920 */
+#ifdef CONFIG_CPU_PXA910
+static inline int cpu_is_pxa910(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x84) &&
+ (((mmp_chip_id & 0xfff) == 0x910) ||
+ ((mmp_chip_id & 0xfff) == 0x920));
+}
+#else
+#define cpu_is_pxa910() (0)
+#endif
+
+#ifdef CONFIG_CPU_MMP2
+static inline int cpu_is_mmp2(void)
+{
+ return (((read_cpuid_id() >> 8) & 0xff) == 0x58);
+}
+#else
+#define cpu_is_mmp2() (0)
+#endif
+
+#endif /* __ASM_MACH_CPUTYPE_H */
diff --git a/arch/arm/mach-mmp/include/mach/debug-macro.S b/arch/arm/mach-mmp/include/mach/debug-macro.S
new file mode 100644
index 00000000..7e2ebd3e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/* arch/arm/mach-mmp/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copied from arch/arm/mach-pxa/include/mach/debug.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 <mach/addr-map.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =APB_PHYS_BASE @ physical
+ ldr \rv, =APB_VIRT_BASE @ virtual
+ orr \rp, \rp, #0x00017000
+ orr \rv, \rv, #0x00017000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mmp/include/mach/devices.h b/arch/arm/mach-mmp/include/mach/devices.h
new file mode 100644
index 00000000..d0ec7dae
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/devices.h
@@ -0,0 +1,53 @@
+#ifndef __MACH_DEVICE_H
+#define __MACH_DEVICE_H
+
+#include <linux/types.h>
+
+#define MAX_RESOURCE_DMA 2
+
+/* structure for describing the on-chip devices */
+struct pxa_device_desc {
+ const char *dev_name;
+ const char *drv_name;
+ int id;
+ int irq;
+ unsigned long start;
+ unsigned long size;
+ int dma[MAX_RESOURCE_DMA];
+};
+
+#define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc pxa168_device_##_name __initdata = { \
+ .dev_name = "pxa168-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_PXA168_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+};
+
+#define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc pxa910_device_##_name __initdata = { \
+ .dev_name = "pxa910-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_PXA910_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+};
+
+#define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \
+struct pxa_device_desc mmp2_device_##_name __initdata = { \
+ .dev_name = "mmp2-" #_name, \
+ .drv_name = _drv, \
+ .id = _id, \
+ .irq = IRQ_MMP2_##_irq, \
+ .start = _start, \
+ .size = _size, \
+ .dma = { _dma }, \
+}
+
+extern int pxa_register_device(struct pxa_device_desc *, void *, size_t);
+#endif /* __MACH_DEVICE_H */
diff --git a/arch/arm/mach-mmp/include/mach/dma.h b/arch/arm/mach-mmp/include/mach/dma.h
new file mode 100644
index 00000000..1d691454
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/dma.h
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/dma.h
+ */
+
+#ifndef __ASM_MACH_DMA_H
+#define __ASM_MACH_DMA_H
+
+#include <mach/addr-map.h>
+
+#define DMAC_REGS_VIRT (APB_VIRT_BASE + 0x00000)
+
+#include <plat/dma.h>
+#endif /* __ASM_MACH_DMA_H */
diff --git a/arch/arm/mach-mmp/include/mach/entry-macro.S b/arch/arm/mach-mmp/include/mach/entry-macro.S
new file mode 100644
index 00000000..c42d9d4e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/entry-macro.S
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/entry-macro.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 <mach/regs-icu.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mrc p15, 0, \tmp, c0, c0, 0 @ CPUID
+ and \tmp, \tmp, #0xff00
+ cmp \tmp, #0x5800
+ ldr \base, =ICU_VIRT_BASE
+ addne \base, \base, #0x10c @ PJ1 AP INT SEL register
+ addeq \base, \base, #0x104 @ PJ4 IRQ SEL register
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \tmp, [\base, #0]
+ and \irqnr, \tmp, #0x3f
+ tst \tmp, #(1 << 6)
+ .endm
diff --git a/arch/arm/mach-mmp/include/mach/gpio.h b/arch/arm/mach-mmp/include/mach/gpio.h
new file mode 100644
index 00000000..7bfb827f
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/gpio.h
@@ -0,0 +1,36 @@
+#ifndef __ASM_MACH_GPIO_H
+#define __ASM_MACH_GPIO_H
+
+#include <mach/addr-map.h>
+#include <mach/irqs.h>
+#include <asm-generic/gpio.h>
+
+#define GPIO_REGS_VIRT (APB_VIRT_BASE + 0x19000)
+
+#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x) (*((volatile u32 *)(GPIO_REGS_VIRT + (x))))
+
+#define NR_BUILTIN_GPIO IRQ_GPIO_NUM
+
+#define gpio_to_bank(gpio) ((gpio) >> 5)
+#define gpio_to_irq(gpio) (IRQ_GPIO_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - IRQ_GPIO_START)
+
+
+#define __gpio_is_inverted(gpio) (0)
+#define __gpio_is_occupied(gpio) (0)
+
+/* NOTE: these macros are defined here to make optimization of
+ * gpio_{get,set}_value() to work when 'gpio' is a constant.
+ * Usage of these macros otherwise is no longer recommended,
+ * use generic GPIO API whenever possible.
+ */
+#define GPIO_bit(gpio) (1 << ((gpio) & 0x1f))
+
+#define GPLR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x00)
+#define GPDR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x0c)
+#define GPSR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x18)
+#define GPCR(x) GPIO_REG(BANK_OFF(gpio_to_bank(x)) + 0x24)
+
+#include <plat/gpio.h>
+#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-mmp/include/mach/hardware.h b/arch/arm/mach-mmp/include/mach/hardware.h
new file mode 100644
index 00000000..99264a5c
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/hardware.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-mmp/include/mach/io.h b/arch/arm/mach-mmp/include/mach/io.h
new file mode 100644
index 00000000..e7adf3d0
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/io.h
@@ -0,0 +1,21 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/io.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h
new file mode 100644
index 00000000..a09d328e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/irqs.h
@@ -0,0 +1,229 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+/*
+ * Interrupt numbers for PXA168
+ */
+#define IRQ_PXA168_NONE (-1)
+#define IRQ_PXA168_SSP4 0
+#define IRQ_PXA168_SSP3 1
+#define IRQ_PXA168_SSP2 2
+#define IRQ_PXA168_SSP1 3
+#define IRQ_PXA168_PMIC_INT 4
+#define IRQ_PXA168_RTC_INT 5
+#define IRQ_PXA168_RTC_ALARM 6
+#define IRQ_PXA168_TWSI0 7
+#define IRQ_PXA168_GPU 8
+#define IRQ_PXA168_KEYPAD 9
+#define IRQ_PXA168_ONEWIRE 12
+#define IRQ_PXA168_TIMER1 13
+#define IRQ_PXA168_TIMER2 14
+#define IRQ_PXA168_TIMER3 15
+#define IRQ_PXA168_CMU 16
+#define IRQ_PXA168_SSP5 17
+#define IRQ_PXA168_MSP_WAKEUP 19
+#define IRQ_PXA168_CF_WAKEUP 20
+#define IRQ_PXA168_XD_WAKEUP 21
+#define IRQ_PXA168_MFU 22
+#define IRQ_PXA168_MSP 23
+#define IRQ_PXA168_CF 24
+#define IRQ_PXA168_XD 25
+#define IRQ_PXA168_DDR_INT 26
+#define IRQ_PXA168_UART1 27
+#define IRQ_PXA168_UART2 28
+#define IRQ_PXA168_UART3 29
+#define IRQ_PXA168_WDT 35
+#define IRQ_PXA168_MAIN_PMU 36
+#define IRQ_PXA168_FRQ_CHANGE 38
+#define IRQ_PXA168_SDH1 39
+#define IRQ_PXA168_SDH2 40
+#define IRQ_PXA168_LCD 41
+#define IRQ_PXA168_CI 42
+#define IRQ_PXA168_USB1 44
+#define IRQ_PXA168_NAND 45
+#define IRQ_PXA168_HIFI_DMA 46
+#define IRQ_PXA168_DMA_INT0 47
+#define IRQ_PXA168_DMA_INT1 48
+#define IRQ_PXA168_GPIOX 49
+#define IRQ_PXA168_USB2 51
+#define IRQ_PXA168_AC97 57
+#define IRQ_PXA168_TWSI1 58
+#define IRQ_PXA168_AP_PMU 60
+#define IRQ_PXA168_SM_INT 63
+
+/*
+ * Interrupt numbers for PXA910
+ */
+#define IRQ_PXA910_NONE (-1)
+#define IRQ_PXA910_AIRQ 0
+#define IRQ_PXA910_SSP3 1
+#define IRQ_PXA910_SSP2 2
+#define IRQ_PXA910_SSP1 3
+#define IRQ_PXA910_PMIC_INT 4
+#define IRQ_PXA910_RTC_INT 5
+#define IRQ_PXA910_RTC_ALARM 6
+#define IRQ_PXA910_TWSI0 7
+#define IRQ_PXA910_GPU 8
+#define IRQ_PXA910_KEYPAD 9
+#define IRQ_PXA910_ROTARY 10
+#define IRQ_PXA910_TRACKBALL 11
+#define IRQ_PXA910_ONEWIRE 12
+#define IRQ_PXA910_AP1_TIMER1 13
+#define IRQ_PXA910_AP1_TIMER2 14
+#define IRQ_PXA910_AP1_TIMER3 15
+#define IRQ_PXA910_IPC_AP0 16
+#define IRQ_PXA910_IPC_AP1 17
+#define IRQ_PXA910_IPC_AP2 18
+#define IRQ_PXA910_IPC_AP3 19
+#define IRQ_PXA910_IPC_AP4 20
+#define IRQ_PXA910_IPC_CP0 21
+#define IRQ_PXA910_IPC_CP1 22
+#define IRQ_PXA910_IPC_CP2 23
+#define IRQ_PXA910_IPC_CP3 24
+#define IRQ_PXA910_IPC_CP4 25
+#define IRQ_PXA910_L2_DDR 26
+#define IRQ_PXA910_UART2 27
+#define IRQ_PXA910_UART3 28
+#define IRQ_PXA910_AP2_TIMER1 29
+#define IRQ_PXA910_AP2_TIMER2 30
+#define IRQ_PXA910_CP2_TIMER1 31
+#define IRQ_PXA910_CP2_TIMER2 32
+#define IRQ_PXA910_CP2_TIMER3 33
+#define IRQ_PXA910_GSSP 34
+#define IRQ_PXA910_CP2_WDT 35
+#define IRQ_PXA910_MAIN_PMU 36
+#define IRQ_PXA910_CP_FREQ_CHG 37
+#define IRQ_PXA910_AP_FREQ_CHG 38
+#define IRQ_PXA910_MMC 39
+#define IRQ_PXA910_AEU 40
+#define IRQ_PXA910_LCD 41
+#define IRQ_PXA910_CCIC 42
+#define IRQ_PXA910_IRE 43
+#define IRQ_PXA910_USB1 44
+#define IRQ_PXA910_NAND 45
+#define IRQ_PXA910_HIFI_DMA 46
+#define IRQ_PXA910_DMA_INT0 47
+#define IRQ_PXA910_DMA_INT1 48
+#define IRQ_PXA910_AP_GPIO 49
+#define IRQ_PXA910_AP2_TIMER3 50
+#define IRQ_PXA910_USB2 51
+#define IRQ_PXA910_TWSI1 54
+#define IRQ_PXA910_CP_GPIO 55
+#define IRQ_PXA910_UART1 59 /* Slow UART */
+#define IRQ_PXA910_AP_PMU 60
+#define IRQ_PXA910_SM_INT 63 /* from PinMux */
+
+/*
+ * Interrupt numbers for MMP2
+ */
+#define IRQ_MMP2_NONE (-1)
+#define IRQ_MMP2_SSP1 0
+#define IRQ_MMP2_SSP2 1
+#define IRQ_MMP2_SSPA1 2
+#define IRQ_MMP2_SSPA2 3
+#define IRQ_MMP2_PMIC_MUX 4 /* PMIC & Charger */
+#define IRQ_MMP2_RTC_MUX 5
+#define IRQ_MMP2_TWSI1 7
+#define IRQ_MMP2_GPU 8
+#define IRQ_MMP2_KEYPAD 9
+#define IRQ_MMP2_ROTARY 10
+#define IRQ_MMP2_TRACKBALL 11
+#define IRQ_MMP2_ONEWIRE 12
+#define IRQ_MMP2_TIMER1 13
+#define IRQ_MMP2_TIMER2 14
+#define IRQ_MMP2_TIMER3 15
+#define IRQ_MMP2_RIPC 16
+#define IRQ_MMP2_TWSI_MUX 17 /* TWSI2 ~ TWSI6 */
+#define IRQ_MMP2_HDMI 19
+#define IRQ_MMP2_SSP3 20
+#define IRQ_MMP2_SSP4 21
+#define IRQ_MMP2_USB_HS1 22
+#define IRQ_MMP2_USB_HS2 23
+#define IRQ_MMP2_UART3 24
+#define IRQ_MMP2_UART1 27
+#define IRQ_MMP2_UART2 28
+#define IRQ_MMP2_MIPI_DSI 29
+#define IRQ_MMP2_CI2 30
+#define IRQ_MMP2_PMU_TIMER1 31
+#define IRQ_MMP2_PMU_TIMER2 32
+#define IRQ_MMP2_PMU_TIMER3 33
+#define IRQ_MMP2_USB_FS 34
+#define IRQ_MMP2_MISC_MUX 35
+#define IRQ_MMP2_WDT1 36
+#define IRQ_MMP2_NAND_DMA 37
+#define IRQ_MMP2_USIM 38
+#define IRQ_MMP2_MMC 39
+#define IRQ_MMP2_WTM 40
+#define IRQ_MMP2_LCD 41
+#define IRQ_MMP2_CI 42
+#define IRQ_MMP2_IRE 43
+#define IRQ_MMP2_USB_OTG 44
+#define IRQ_MMP2_NAND 45
+#define IRQ_MMP2_UART4 46
+#define IRQ_MMP2_DMA_FIQ 47
+#define IRQ_MMP2_DMA_RIQ 48
+#define IRQ_MMP2_GPIO 49
+#define IRQ_MMP2_SSP_MUX 51
+#define IRQ_MMP2_MMC2 52
+#define IRQ_MMP2_MMC3 53
+#define IRQ_MMP2_MMC4 54
+#define IRQ_MMP2_MIPI_HSI 55
+#define IRQ_MMP2_MSP 58
+#define IRQ_MMP2_MIPI_SLIM_DMA 59
+#define IRQ_MMP2_PJ4_FREQ_CHG 60
+#define IRQ_MMP2_MIPI_SLIM 62
+#define IRQ_MMP2_SM 63
+
+#define IRQ_MMP2_MUX_BASE 64
+
+/* secondary interrupt of INT #4 */
+#define IRQ_MMP2_PMIC_BASE (IRQ_MMP2_MUX_BASE)
+#define IRQ_MMP2_CHARGER (IRQ_MMP2_PMIC_BASE + 0)
+#define IRQ_MMP2_PMIC (IRQ_MMP2_PMIC_BASE + 1)
+
+/* secondary interrupt of INT #5 */
+#define IRQ_MMP2_RTC_BASE (IRQ_MMP2_PMIC_BASE + 2)
+#define IRQ_MMP2_RTC_ALARM (IRQ_MMP2_RTC_BASE + 0)
+#define IRQ_MMP2_RTC (IRQ_MMP2_RTC_BASE + 1)
+
+/* secondary interrupt of INT #17 */
+#define IRQ_MMP2_TWSI_BASE (IRQ_MMP2_RTC_BASE + 2)
+#define IRQ_MMP2_TWSI2 (IRQ_MMP2_TWSI_BASE + 0)
+#define IRQ_MMP2_TWSI3 (IRQ_MMP2_TWSI_BASE + 1)
+#define IRQ_MMP2_TWSI4 (IRQ_MMP2_TWSI_BASE + 2)
+#define IRQ_MMP2_TWSI5 (IRQ_MMP2_TWSI_BASE + 3)
+#define IRQ_MMP2_TWSI6 (IRQ_MMP2_TWSI_BASE + 4)
+
+/* secondary interrupt of INT #35 */
+#define IRQ_MMP2_MISC_BASE (IRQ_MMP2_TWSI_BASE + 5)
+#define IRQ_MMP2_PERF (IRQ_MMP2_MISC_BASE + 0)
+#define IRQ_MMP2_L2_PA_ECC (IRQ_MMP2_MISC_BASE + 1)
+#define IRQ_MMP2_L2_ECC (IRQ_MMP2_MISC_BASE + 2)
+#define IRQ_MMP2_L2_UECC (IRQ_MMP2_MISC_BASE + 3)
+#define IRQ_MMP2_DDR (IRQ_MMP2_MISC_BASE + 4)
+#define IRQ_MMP2_FAB0_TIMEOUT (IRQ_MMP2_MISC_BASE + 5)
+#define IRQ_MMP2_FAB1_TIMEOUT (IRQ_MMP2_MISC_BASE + 6)
+#define IRQ_MMP2_FAB2_TIMEOUT (IRQ_MMP2_MISC_BASE + 7)
+#define IRQ_MMP2_THERMAL (IRQ_MMP2_MISC_BASE + 9)
+#define IRQ_MMP2_MAIN_PMU (IRQ_MMP2_MISC_BASE + 10)
+#define IRQ_MMP2_WDT2 (IRQ_MMP2_MISC_BASE + 11)
+#define IRQ_MMP2_CORESIGHT (IRQ_MMP2_MISC_BASE + 12)
+#define IRQ_MMP2_COMMTX (IRQ_MMP2_MISC_BASE + 13)
+#define IRQ_MMP2_COMMRX (IRQ_MMP2_MISC_BASE + 14)
+
+/* secondary interrupt of INT #51 */
+#define IRQ_MMP2_SSP_BASE (IRQ_MMP2_MISC_BASE + 15)
+#define IRQ_MMP2_SSP1_SRDY (IRQ_MMP2_SSP_BASE + 0)
+#define IRQ_MMP2_SSP3_SRDY (IRQ_MMP2_SSP_BASE + 1)
+
+#define IRQ_MMP2_MUX_END (IRQ_MMP2_SSP_BASE + 2)
+
+#define IRQ_GPIO_START 128
+#define IRQ_GPIO_NUM 192
+#define IRQ_GPIO(x) (IRQ_GPIO_START + (x))
+
+#define IRQ_BOARD_START (IRQ_GPIO_START + IRQ_GPIO_NUM)
+
+#define NR_IRQS (IRQ_BOARD_START)
+
+#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h
new file mode 100644
index 00000000..d68b50a2
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/memory.h
@@ -0,0 +1,14 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/memory.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-mmp2.h b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
new file mode 100644
index 00000000..4ad38629
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-mmp2.h
@@ -0,0 +1,395 @@
+#ifndef __ASM_MACH_MFP_MMP2_H
+#define __ASM_MACH_MFP_MMP2_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 13)
+#define MFP_DRIVE_SLOW (0x2 << 13)
+#define MFP_DRIVE_MEDIUM (0x4 << 13)
+#define MFP_DRIVE_FAST (0x6 << 13)
+
+/* GPIO */
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF1)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF1)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF1)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF1)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF1)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF1)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF1)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF1)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF1)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF1)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF1)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF1)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO MFP_CFG(GPIO127, AF0)
+#define GPIO128_GPIO MFP_CFG(GPIO128, AF0)
+#define GPIO129_GPIO MFP_CFG(GPIO129, AF0)
+#define GPIO130_GPIO MFP_CFG(GPIO130, AF0)
+#define GPIO131_GPIO MFP_CFG(GPIO131, AF0)
+#define GPIO132_GPIO MFP_CFG(GPIO132, AF0)
+#define GPIO133_GPIO MFP_CFG(GPIO133, AF0)
+#define GPIO134_GPIO MFP_CFG(GPIO134, AF0)
+#define GPIO135_GPIO MFP_CFG(GPIO135, AF0)
+#define GPIO136_GPIO MFP_CFG(GPIO136, AF0)
+#define GPIO137_GPIO MFP_CFG(GPIO137, AF0)
+#define GPIO138_GPIO MFP_CFG(GPIO138, AF0)
+#define GPIO139_GPIO MFP_CFG(GPIO139, AF0)
+#define GPIO140_GPIO MFP_CFG(GPIO140, AF0)
+#define GPIO141_GPIO MFP_CFG(GPIO141, AF0)
+#define GPIO142_GPIO MFP_CFG(GPIO142, AF1)
+#define GPIO143_GPIO MFP_CFG(GPIO143, AF1)
+#define GPIO144_GPIO MFP_CFG(GPIO144, AF1)
+#define GPIO145_GPIO MFP_CFG(GPIO145, AF1)
+#define GPIO146_GPIO MFP_CFG(GPIO146, AF1)
+#define GPIO147_GPIO MFP_CFG(GPIO147, AF1)
+#define GPIO148_GPIO MFP_CFG(GPIO148, AF1)
+#define GPIO149_GPIO MFP_CFG(GPIO149, AF1)
+#define GPIO150_GPIO MFP_CFG(GPIO150, AF1)
+#define GPIO151_GPIO MFP_CFG(GPIO151, AF1)
+#define GPIO152_GPIO MFP_CFG(GPIO152, AF1)
+#define GPIO153_GPIO MFP_CFG(GPIO153, AF1)
+#define GPIO154_GPIO MFP_CFG(GPIO154, AF1)
+#define GPIO155_GPIO MFP_CFG(GPIO155, AF1)
+#define GPIO156_GPIO MFP_CFG(GPIO156, AF1)
+#define GPIO157_GPIO MFP_CFG(GPIO157, AF1)
+#define GPIO158_GPIO MFP_CFG(GPIO158, AF1)
+#define GPIO159_GPIO MFP_CFG(GPIO159, AF1)
+#define GPIO160_GPIO MFP_CFG(GPIO160, AF1)
+#define GPIO161_GPIO MFP_CFG(GPIO161, AF1)
+#define GPIO162_GPIO MFP_CFG(GPIO162, AF1)
+#define GPIO163_GPIO MFP_CFG(GPIO163, AF1)
+#define GPIO164_GPIO MFP_CFG(GPIO164, AF1)
+#define GPIO165_GPIO MFP_CFG(GPIO165, AF1)
+#define GPIO166_GPIO MFP_CFG(GPIO166, AF1)
+#define GPIO167_GPIO MFP_CFG(GPIO167, AF1)
+#define GPIO168_GPIO MFP_CFG(GPIO168, AF1)
+
+/* DFI */
+#define GPIO108_DFI_D15 MFP_CFG(GPIO108, AF0)
+#define GPIO109_DFI_D14 MFP_CFG(GPIO109, AF0)
+#define GPIO110_DFI_D13 MFP_CFG(GPIO110, AF0)
+#define GPIO161_DFI_D12 MFP_CFG(GPIO161, AF0)
+#define GPIO162_DFI_D11 MFP_CFG(GPIO162, AF0)
+#define GPIO163_DFI_D10 MFP_CFG(GPIO163, AF0)
+#define GPIO164_DFI_D9 MFP_CFG(GPIO164, AF0)
+#define GPIO111_DFI_D8 MFP_CFG(GPIO111, AF0)
+#define GPIO104_DFI_D7 MFP_CFG(GPIO104, AF0)
+#define GPIO105_DFI_D6 MFP_CFG(GPIO105, AF0)
+#define GPIO106_DFI_D5 MFP_CFG(GPIO106, AF0)
+#define GPIO107_DFI_D4 MFP_CFG(GPIO107, AF0)
+#define GPIO165_DFI_D3 MFP_CFG(GPIO165, AF0)
+#define GPIO166_DFI_D2 MFP_CFG(GPIO166, AF0)
+#define GPIO167_DFI_D1 MFP_CFG(GPIO167, AF0)
+#define GPIO168_DFI_D0 MFP_CFG(GPIO168, AF0)
+#define GPIO143_ND_nCS0 MFP_CFG(GPIO143, AF0)
+#define GPIO144_ND_nCS1 MFP_CFG(GPIO144, AF0)
+#define GPIO147_ND_nWE MFP_CFG(GPIO147, AF0)
+#define GPIO148_ND_nRE MFP_CFG(GPIO148, AF0)
+#define GPIO150_ND_ALE MFP_CFG(GPIO150, AF0)
+#define GPIO149_ND_CLE MFP_CFG(GPIO149, AF0)
+#define GPIO112_ND_RDY0 MFP_CFG(GPIO112, AF0)
+#define GPIO160_ND_RDY1 MFP_CFG(GPIO160, AF0)
+
+/* Static Memory Controller */
+#define GPIO145_SMC_nCS0 MFP_CFG(GPIO145, AF0)
+#define GPIO146_SMC_nCS1 MFP_CFG(GPIO146, AF0)
+#define GPIO152_SMC_BE0 MFP_CFG(GPIO152, AF0)
+#define GPIO153_SMC_BE1 MFP_CFG(GPIO153, AF0)
+#define GPIO154_SMC_IRQ MFP_CFG(GPIO154, AF0)
+#define GPIO113_SMC_RDY MFP_CFG(GPIO113, AF0)
+#define GPIO151_SMC_SCLK MFP_CFG(GPIO151, AF0)
+
+/* Ethernet */
+#define GPIO155_SM_ADVMUX MFP_CFG(GPIO155, AF2)
+
+/* UART1 */
+#define GPIO45_UART1_RXD MFP_CFG(GPIO45, AF1)
+#define GPIO46_UART1_TXD MFP_CFG(GPIO46, AF1)
+#define GPIO29_UART1_RXD MFP_CFG(GPIO29, AF1)
+#define GPIO30_UART1_TXD MFP_CFG(GPIO30, AF1)
+#define GPIO31_UART1_CTS MFP_CFG(GPIO31, AF1)
+#define GPIO32_UART1_RTS MFP_CFG(GPIO32, AF1)
+
+/* UART2 */
+#define GPIO47_UART2_RXD MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART2_TXD MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART2_CTS MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART2_RTS MFP_CFG(GPIO50, AF1)
+
+/* UART3 */
+#define GPIO51_UART3_RXD MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART3_TXD MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART3_CTS MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART3_RTS MFP_CFG(GPIO54, AF1)
+
+/* MMC1 */
+#define GPIO124_MMC1_DAT7 MFP_CFG_DRV(GPIO124, AF1, FAST)
+#define GPIO125_MMC1_DAT6 MFP_CFG_DRV(GPIO125, AF1, FAST)
+#define GPIO129_MMC1_DAT5 MFP_CFG_DRV(GPIO129, AF1, FAST)
+#define GPIO130_MMC1_DAT4 MFP_CFG_DRV(GPIO130, AF1, FAST)
+#define GPIO131_MMC1_DAT3 MFP_CFG_DRV(GPIO131, AF1, FAST)
+#define GPIO132_MMC1_DAT2 MFP_CFG_DRV(GPIO132, AF1, FAST)
+#define GPIO133_MMC1_DAT1 MFP_CFG_DRV(GPIO133, AF1, FAST)
+#define GPIO134_MMC1_DAT0 MFP_CFG_DRV(GPIO134, AF1, FAST)
+#define GPIO136_MMC1_CMD MFP_CFG_DRV(GPIO136, AF1, FAST)
+#define GPIO139_MMC1_CLK MFP_CFG_DRV(GPIO139, AF1, FAST)
+#define GPIO140_MMC1_CD MFP_CFG_DRV(GPIO140, AF1, FAST)
+#define GPIO141_MMC1_WP MFP_CFG_DRV(GPIO141, AF1, FAST)
+
+/*MMC2*/
+#define GPIO37_MMC2_DAT3 MFP_CFG_DRV(GPIO37, AF1, FAST)
+#define GPIO38_MMC2_DAT2 MFP_CFG_DRV(GPIO38, AF1, FAST)
+#define GPIO39_MMC2_DAT1 MFP_CFG_DRV(GPIO39, AF1, FAST)
+#define GPIO40_MMC2_DAT0 MFP_CFG_DRV(GPIO40, AF1, FAST)
+#define GPIO41_MMC2_CMD MFP_CFG_DRV(GPIO41, AF1, FAST)
+#define GPIO42_MMC2_CLK MFP_CFG_DRV(GPIO42, AF1, FAST)
+
+/*MMC3*/
+#define GPIO165_MMC3_DAT7 MFP_CFG_DRV(GPIO165, AF2, FAST)
+#define GPIO162_MMC3_DAT6 MFP_CFG_DRV(GPIO162, AF2, FAST)
+#define GPIO166_MMC3_DAT5 MFP_CFG_DRV(GPIO166, AF2, FAST)
+#define GPIO163_MMC3_DAT4 MFP_CFG_DRV(GPIO163, AF2, FAST)
+#define GPIO167_MMC3_DAT3 MFP_CFG_DRV(GPIO167, AF2, FAST)
+#define GPIO164_MMC3_DAT2 MFP_CFG_DRV(GPIO164, AF2, FAST)
+#define GPIO168_MMC3_DAT1 MFP_CFG_DRV(GPIO168, AF2, FAST)
+#define GPIO111_MMC3_DAT0 MFP_CFG_DRV(GPIO111, AF2, FAST)
+#define GPIO112_MMC3_CMD MFP_CFG_DRV(GPIO112, AF2, FAST)
+#define GPIO151_MMC3_CLK MFP_CFG_DRV(GPIO151, AF2, FAST)
+
+/* LCD */
+#define GPIO74_LCD_FCLK MFP_CFG_DRV(GPIO74, AF1, FAST)
+#define GPIO75_LCD_LCLK MFP_CFG_DRV(GPIO75, AF1, FAST)
+#define GPIO76_LCD_PCLK MFP_CFG_DRV(GPIO76, AF1, FAST)
+#define GPIO77_LCD_DENA MFP_CFG_DRV(GPIO77, AF1, FAST)
+#define GPIO78_LCD_DD0 MFP_CFG_DRV(GPIO78, AF1, FAST)
+#define GPIO79_LCD_DD1 MFP_CFG_DRV(GPIO79, AF1, FAST)
+#define GPIO80_LCD_DD2 MFP_CFG_DRV(GPIO80, AF1, FAST)
+#define GPIO81_LCD_DD3 MFP_CFG_DRV(GPIO81, AF1, FAST)
+#define GPIO82_LCD_DD4 MFP_CFG_DRV(GPIO82, AF1, FAST)
+#define GPIO83_LCD_DD5 MFP_CFG_DRV(GPIO83, AF1, FAST)
+#define GPIO84_LCD_DD6 MFP_CFG_DRV(GPIO84, AF1, FAST)
+#define GPIO85_LCD_DD7 MFP_CFG_DRV(GPIO85, AF1, FAST)
+#define GPIO86_LCD_DD8 MFP_CFG_DRV(GPIO86, AF1, FAST)
+#define GPIO87_LCD_DD9 MFP_CFG_DRV(GPIO87, AF1, FAST)
+#define GPIO88_LCD_DD10 MFP_CFG_DRV(GPIO88, AF1, FAST)
+#define GPIO89_LCD_DD11 MFP_CFG_DRV(GPIO89, AF1, FAST)
+#define GPIO90_LCD_DD12 MFP_CFG_DRV(GPIO90, AF1, FAST)
+#define GPIO91_LCD_DD13 MFP_CFG_DRV(GPIO91, AF1, FAST)
+#define GPIO92_LCD_DD14 MFP_CFG_DRV(GPIO92, AF1, FAST)
+#define GPIO93_LCD_DD15 MFP_CFG_DRV(GPIO93, AF1, FAST)
+#define GPIO94_LCD_DD16 MFP_CFG_DRV(GPIO94, AF1, FAST)
+#define GPIO95_LCD_DD17 MFP_CFG_DRV(GPIO95, AF1, FAST)
+#define GPIO96_LCD_DD18 MFP_CFG_DRV(GPIO96, AF1, FAST)
+#define GPIO97_LCD_DD19 MFP_CFG_DRV(GPIO97, AF1, FAST)
+#define GPIO98_LCD_DD20 MFP_CFG_DRV(GPIO98, AF1, FAST)
+#define GPIO99_LCD_DD21 MFP_CFG_DRV(GPIO99, AF1, FAST)
+#define GPIO100_LCD_DD22 MFP_CFG_DRV(GPIO100, AF1, FAST)
+#define GPIO101_LCD_DD23 MFP_CFG_DRV(GPIO101, AF1, FAST)
+#define GPIO94_SPI_DCLK MFP_CFG_DRV(GPIO94, AF3, FAST)
+#define GPIO95_SPI_CS0 MFP_CFG_DRV(GPIO95, AF3, FAST)
+#define GPIO96_SPI_DIN MFP_CFG_DRV(GPIO96, AF3, FAST)
+#define GPIO97_SPI_DOUT MFP_CFG_DRV(GPIO97, AF3, FAST)
+#define GPIO98_LCD_RST MFP_CFG_DRV(GPIO98, AF0, FAST)
+
+#define GPIO114_MN_CLK_OUT MFP_CFG_DRV(GPIO114, AF1, FAST)
+
+/*LCD TV path*/
+#define GPIO124_LCD_DD24 MFP_CFG_DRV(GPIO124, AF2, FAST)
+#define GPIO125_LCD_DD25 MFP_CFG_DRV(GPIO125, AF2, FAST)
+#define GPIO126_LCD_DD33 MFP_CFG_DRV(GPIO126, AF2, FAST)
+#define GPIO127_LCD_DD26 MFP_CFG_DRV(GPIO127, AF2, FAST)
+#define GPIO128_LCD_DD27 MFP_CFG_DRV(GPIO128, AF2, FAST)
+#define GPIO129_LCD_DD28 MFP_CFG_DRV(GPIO129, AF2, FAST)
+#define GPIO130_LCD_DD29 MFP_CFG_DRV(GPIO130, AF2, FAST)
+#define GPIO135_LCD_DD30 MFP_CFG_DRV(GPIO135, AF2, FAST)
+#define GPIO137_LCD_DD31 MFP_CFG_DRV(GPIO137, AF2, FAST)
+#define GPIO138_LCD_DD32 MFP_CFG_DRV(GPIO138, AF2, FAST)
+#define GPIO140_LCD_DD34 MFP_CFG_DRV(GPIO140, AF2, FAST)
+#define GPIO141_LCD_DD35 MFP_CFG_DRV(GPIO141, AF2, FAST)
+
+/* I2C */
+#define GPIO43_TWSI2_SCL MFP_CFG_DRV(GPIO43, AF1, SLOW)
+#define GPIO44_TWSI2_SDA MFP_CFG_DRV(GPIO44, AF1, SLOW)
+#define GPIO71_TWSI3_SCL MFP_CFG_DRV(GPIO71, AF1, SLOW)
+#define GPIO72_TWSI3_SDA MFP_CFG_DRV(GPIO72, AF1, SLOW)
+#define TWSI4_SCL MFP_CFG_DRV(TWSI4_SCL, AF0, SLOW)
+#define TWSI4_SDA MFP_CFG_DRV(TWSI4_SDA, AF0, SLOW)
+#define GPIO99_TWSI5_SCL MFP_CFG_DRV(GPIO99, AF4, SLOW)
+#define GPIO100_TWSI5_SDA MFP_CFG_DRV(GPIO100, AF4, SLOW)
+#define GPIO97_TWSI6_SCL MFP_CFG_DRV(GPIO97, AF2, SLOW)
+#define GPIO98_TWSI6_SDA MFP_CFG_DRV(GPIO98, AF2, SLOW)
+
+/* SSPA1 */
+#define GPIO24_I2S_SYSCLK MFP_CFG(GPIO24, AF1)
+#define GPIO25_I2S_BITCLK MFP_CFG(GPIO25, AF1)
+#define GPIO26_I2S_SYNC MFP_CFG(GPIO26, AF1)
+#define GPIO27_I2S_DATA_OUT MFP_CFG(GPIO27, AF1)
+#define GPIO28_I2S_SDATA_IN MFP_CFG(GPIO28, AF1)
+#define GPIO114_I2S_MCLK MFP_CFG(GPIO114, AF1)
+
+/* SSPA2 */
+#define GPIO33_SSPA2_CLK MFP_CFG(GPIO33, AF1)
+#define GPIO34_SSPA2_FRM MFP_CFG(GPIO34, AF1)
+#define GPIO35_SSPA2_TXD MFP_CFG(GPIO35, AF1)
+#define GPIO36_SSPA2_RXD MFP_CFG(GPIO36, AF1)
+
+/* Keypad */
+#define GPIO00_KP_MKIN0 MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0 MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1 MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1 MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2 MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2 MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3 MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3 MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4 MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4 MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5 MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5 MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6 MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6 MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7 MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7 MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1 MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2 MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3 MFP_CFG(GPIO19, AF1)
+#define GPIO20_KP_DKIN4 MFP_CFG(GPIO20, AF1)
+#define GPIO21_KP_DKIN5 MFP_CFG(GPIO21, AF1)
+#define GPIO22_KP_DKIN6 MFP_CFG(GPIO22, AF1)
+#define GPIO23_KP_DKIN7 MFP_CFG(GPIO23, AF1)
+
+/* CAMERA */
+#define GPIO59_CCIC_IN7 MFP_CFG_DRV(GPIO59, AF1, FAST)
+#define GPIO60_CCIC_IN6 MFP_CFG_DRV(GPIO60, AF1, FAST)
+#define GPIO61_CCIC_IN5 MFP_CFG_DRV(GPIO61, AF1, FAST)
+#define GPIO62_CCIC_IN4 MFP_CFG_DRV(GPIO62, AF1, FAST)
+#define GPIO63_CCIC_IN3 MFP_CFG_DRV(GPIO63, AF1, FAST)
+#define GPIO64_CCIC_IN2 MFP_CFG_DRV(GPIO64, AF1, FAST)
+#define GPIO65_CCIC_IN1 MFP_CFG_DRV(GPIO65, AF1, FAST)
+#define GPIO66_CCIC_IN0 MFP_CFG_DRV(GPIO66, AF1, FAST)
+#define GPIO67_CAM_HSYNC MFP_CFG_DRV(GPIO67, AF1, FAST)
+#define GPIO68_CAM_VSYNC MFP_CFG_DRV(GPIO68, AF1, FAST)
+#define GPIO69_CAM_MCLK MFP_CFG_DRV(GPIO69, AF1, FAST)
+#define GPIO70_CAM_PCLK MFP_CFG_DRV(GPIO70, AF1, FAST)
+
+/* PMIC */
+#define PMIC_PMIC_INT MFP_CFG(PMIC_INT, AF0)
+
+#endif /* __ASM_MACH_MFP_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
new file mode 100644
index 00000000..713be155
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa168.h
@@ -0,0 +1,308 @@
+#ifndef __ASM_MACH_MFP_PXA168_H
+#define __ASM_MACH_MFP_PXA168_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 13)
+#define MFP_DRIVE_SLOW (0x1 << 13)
+#define MFP_DRIVE_MEDIUM (0x2 << 13)
+#define MFP_DRIVE_FAST (0x3 << 13)
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+
+#define MFP_CFG(pin, af) \
+ (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ (MFP_LPM_INPUT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+/* GPIO */
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF5)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF5)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF5)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF5)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF5)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF5)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF5)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF5)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF5)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF5)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF5)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF5)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF5)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF5)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF5)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF5)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF5)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF5)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF5)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF5)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF5)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF5)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF5)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF5)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF5)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF5)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF5)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF5)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF5)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF5)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+
+/* DFI */
+#define GPIO0_DFI_D15 MFP_CFG(GPIO0, AF0)
+#define GPIO1_DFI_D14 MFP_CFG(GPIO1, AF0)
+#define GPIO2_DFI_D13 MFP_CFG(GPIO2, AF0)
+#define GPIO3_DFI_D12 MFP_CFG(GPIO3, AF0)
+#define GPIO4_DFI_D11 MFP_CFG(GPIO4, AF0)
+#define GPIO5_DFI_D10 MFP_CFG(GPIO5, AF0)
+#define GPIO6_DFI_D9 MFP_CFG(GPIO6, AF0)
+#define GPIO7_DFI_D8 MFP_CFG(GPIO7, AF0)
+#define GPIO8_DFI_D7 MFP_CFG(GPIO8, AF0)
+#define GPIO9_DFI_D6 MFP_CFG(GPIO9, AF0)
+#define GPIO10_DFI_D5 MFP_CFG(GPIO10, AF0)
+#define GPIO11_DFI_D4 MFP_CFG(GPIO11, AF0)
+#define GPIO12_DFI_D3 MFP_CFG(GPIO12, AF0)
+#define GPIO13_DFI_D2 MFP_CFG(GPIO13, AF0)
+#define GPIO14_DFI_D1 MFP_CFG(GPIO14, AF0)
+#define GPIO15_DFI_D0 MFP_CFG(GPIO15, AF0)
+
+#define GPIO30_DFI_ADDR0 MFP_CFG(GPIO30, AF0)
+#define GPIO31_DFI_ADDR1 MFP_CFG(GPIO31, AF0)
+#define GPIO32_DFI_ADDR2 MFP_CFG(GPIO32, AF0)
+#define GPIO33_DFI_ADDR3 MFP_CFG(GPIO33, AF0)
+
+/* NAND */
+#define GPIO16_ND_nCS0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_ND_nWE MFP_CFG(GPIO17, AF0)
+#define GPIO21_ND_ALE MFP_CFG(GPIO21, AF0)
+#define GPIO22_ND_CLE MFP_CFG(GPIO22, AF0)
+#define GPIO24_ND_nRE MFP_CFG(GPIO24, AF0)
+#define GPIO26_ND_RnB1 MFP_CFG(GPIO26, AF1)
+#define GPIO27_ND_RnB2 MFP_CFG(GPIO27, AF1)
+
+/* Static Memory Controller */
+#define GPIO18_SMC_nCS0 MFP_CFG(GPIO18, AF3)
+#define GPIO18_SMC_nCS1 MFP_CFG(GPIO18, AF2)
+#define GPIO16_SMC_nCS0 MFP_CFG(GPIO16, AF2)
+#define GPIO16_SMC_nCS1 MFP_CFG(GPIO16, AF3)
+#define GPIO19_SMC_nCS0 MFP_CFG(GPIO19, AF0)
+#define GPIO20_SMC_nCS1 MFP_CFG(GPIO20, AF2)
+#define GPIO23_SMC_nLUA MFP_CFG(GPIO23, AF0)
+#define GPIO25_SMC_nLLA MFP_CFG(GPIO25, AF0)
+#define GPIO27_SMC_IRQ MFP_CFG(GPIO27, AF0)
+#define GPIO28_SMC_RDY MFP_CFG(GPIO28, AF0)
+#define GPIO29_SMC_SCLK MFP_CFG(GPIO29, AF0)
+#define GPIO34_SMC_nCS1 MFP_CFG(GPIO34, AF2)
+#define GPIO35_SMC_BE1 MFP_CFG(GPIO35, AF2)
+#define GPIO36_SMC_BE2 MFP_CFG(GPIO36, AF2)
+
+/* Compact Flash */
+#define GPIO19_CF_nCE1 MFP_CFG(GPIO19, AF3)
+#define GPIO20_CF_nCE2 MFP_CFG(GPIO20, AF3)
+#define GPIO23_CF_nALE MFP_CFG(GPIO23, AF3)
+#define GPIO25_CF_nRESET MFP_CFG(GPIO25, AF3)
+#define GPIO28_CF_RDY MFP_CFG(GPIO28, AF3)
+#define GPIO29_CF_STSCH MFP_CFG(GPIO29, AF3)
+#define GPIO30_CF_nREG MFP_CFG(GPIO30, AF3)
+#define GPIO31_CF_nIOIS16 MFP_CFG(GPIO31, AF3)
+#define GPIO32_CF_nCD1 MFP_CFG(GPIO32, AF3)
+#define GPIO33_CF_nCD2 MFP_CFG(GPIO33, AF3)
+
+/* UART */
+#define GPIO88_UART2_TXD MFP_CFG(GPIO88, AF2)
+#define GPIO89_UART2_RXD MFP_CFG(GPIO89, AF2)
+#define GPIO107_UART1_TXD MFP_CFG_DRV(GPIO107, AF1, FAST)
+#define GPIO107_UART1_RXD MFP_CFG_DRV(GPIO107, AF2, FAST)
+#define GPIO108_UART1_RXD MFP_CFG_DRV(GPIO108, AF1, FAST)
+#define GPIO108_UART1_TXD MFP_CFG_DRV(GPIO108, AF2, FAST)
+#define GPIO109_UART1_CTS MFP_CFG(GPIO109, AF1)
+#define GPIO109_UART1_RTS MFP_CFG(GPIO109, AF2)
+#define GPIO110_UART1_RTS MFP_CFG(GPIO110, AF1)
+#define GPIO110_UART1_CTS MFP_CFG(GPIO110, AF2)
+#define GPIO111_UART1_RI MFP_CFG(GPIO111, AF1)
+#define GPIO111_UART1_DSR MFP_CFG(GPIO111, AF2)
+#define GPIO112_UART1_DTR MFP_CFG(GPIO111, AF1)
+#define GPIO112_UART1_DCD MFP_CFG(GPIO112, AF2)
+
+/* MMC1 */
+#define GPIO37_MMC1_DAT7 MFP_CFG(GPIO37, AF1)
+#define GPIO38_MMC1_DAT6 MFP_CFG(GPIO38, AF1)
+#define GPIO54_MMC1_DAT5 MFP_CFG(GPIO54, AF1)
+#define GPIO48_MMC1_DAT4 MFP_CFG(GPIO48, AF1)
+#define GPIO51_MMC1_DAT3 MFP_CFG(GPIO51, AF1)
+#define GPIO52_MMC1_DAT2 MFP_CFG(GPIO52, AF1)
+#define GPIO40_MMC1_DAT1 MFP_CFG(GPIO40, AF1)
+#define GPIO41_MMC1_DAT0 MFP_CFG(GPIO41, AF1)
+#define GPIO49_MMC1_CMD MFP_CFG(GPIO49, AF1)
+#define GPIO43_MMC1_CLK MFP_CFG(GPIO43, AF1)
+#define GPIO53_MMC1_CD MFP_CFG(GPIO53, AF1)
+#define GPIO46_MMC1_WP MFP_CFG(GPIO46, AF1)
+
+/* LCD */
+#define GPIO84_LCD_CS MFP_CFG(GPIO84, AF1)
+#define GPIO60_LCD_DD0 MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCD_DD1 MFP_CFG(GPIO61, AF1)
+#define GPIO70_LCD_DD10 MFP_CFG(GPIO70, AF1)
+#define GPIO71_LCD_DD11 MFP_CFG(GPIO71, AF1)
+#define GPIO72_LCD_DD12 MFP_CFG(GPIO72, AF1)
+#define GPIO73_LCD_DD13 MFP_CFG(GPIO73, AF1)
+#define GPIO74_LCD_DD14 MFP_CFG(GPIO74, AF1)
+#define GPIO75_LCD_DD15 MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCD_DD16 MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCD_DD17 MFP_CFG(GPIO77, AF1)
+#define GPIO78_LCD_DD18 MFP_CFG(GPIO78, AF1)
+#define GPIO79_LCD_DD19 MFP_CFG(GPIO79, AF1)
+#define GPIO62_LCD_DD2 MFP_CFG(GPIO62, AF1)
+#define GPIO80_LCD_DD20 MFP_CFG(GPIO80, AF1)
+#define GPIO81_LCD_DD21 MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_DD22 MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_DD23 MFP_CFG(GPIO83, AF1)
+#define GPIO63_LCD_DD3 MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCD_DD4 MFP_CFG(GPIO64, AF1)
+#define GPIO65_LCD_DD5 MFP_CFG(GPIO65, AF1)
+#define GPIO66_LCD_DD6 MFP_CFG(GPIO66, AF1)
+#define GPIO67_LCD_DD7 MFP_CFG(GPIO67, AF1)
+#define GPIO68_LCD_DD8 MFP_CFG(GPIO68, AF1)
+#define GPIO69_LCD_DD9 MFP_CFG(GPIO69, AF1)
+#define GPIO59_LCD_DENA_BIAS MFP_CFG(GPIO59, AF1)
+#define GPIO56_LCD_FCLK_RD MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCD_LCLK_A0 MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCD_PCLK_WR MFP_CFG(GPIO58, AF1)
+#define GPIO85_LCD_VSYNC MFP_CFG(GPIO85, AF1)
+
+/* I2C */
+#define GPIO105_CI2C_SDA MFP_CFG(GPIO105, AF1)
+#define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1)
+
+/* I2S */
+#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6)
+#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1)
+#define GPIO115_I2S_BCLK MFP_CFG(GPIO115,AF1)
+#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2)
+#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2)
+
+/* PWM */
+#define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1)
+#define GPIO97_PWM2_OUT MFP_CFG(GPIO97, AF1)
+#define GPIO98_PWM1_OUT MFP_CFG(GPIO98, AF1)
+#define GPIO104_PWM4_OUT MFP_CFG(GPIO104, AF1)
+#define GPIO106_PWM2_OUT MFP_CFG(GPIO106, AF2)
+#define GPIO74_PWM4_OUT MFP_CFG(GPIO74, AF2)
+#define GPIO75_PWM3_OUT MFP_CFG(GPIO75, AF2)
+#define GPIO76_PWM2_OUT MFP_CFG(GPIO76, AF2)
+#define GPIO77_PWM1_OUT MFP_CFG(GPIO77, AF2)
+#define GPIO82_PWM4_OUT MFP_CFG(GPIO82, AF2)
+#define GPIO83_PWM3_OUT MFP_CFG(GPIO83, AF2)
+#define GPIO84_PWM2_OUT MFP_CFG(GPIO84, AF2)
+#define GPIO85_PWM1_OUT MFP_CFG(GPIO85, AF2)
+#define GPIO84_PWM1_OUT MFP_CFG(GPIO84, AF4)
+#define GPIO122_PWM3_OUT MFP_CFG(GPIO122, AF3)
+#define GPIO123_PWM1_OUT MFP_CFG(GPIO123, AF1)
+#define GPIO124_PWM2_OUT MFP_CFG(GPIO124, AF1)
+#define GPIO125_PWM3_OUT MFP_CFG(GPIO125, AF1)
+#define GPIO126_PWM4_OUT MFP_CFG(GPIO126, AF1)
+#define GPIO86_PWM1_OUT MFP_CFG(GPIO86, AF2)
+#define GPIO86_PWM2_OUT MFP_CFG(GPIO86, AF3)
+
+/* Keypad */
+#define GPIO109_KP_MKIN1 MFP_CFG(GPIO109, AF7)
+#define GPIO110_KP_MKIN0 MFP_CFG(GPIO110, AF7)
+#define GPIO111_KP_MKOUT7 MFP_CFG(GPIO111, AF7)
+#define GPIO112_KP_MKOUT6 MFP_CFG(GPIO112, AF7)
+#define GPIO121_KP_MKIN4 MFP_CFG(GPIO121, AF7)
+
+#endif /* __ASM_MACH_MFP_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
new file mode 100644
index 00000000..fbd7ee8e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp-pxa910.h
@@ -0,0 +1,170 @@
+#ifndef __ASM_MACH_MFP_PXA910_H
+#define __ASM_MACH_MFP_PXA910_H
+
+#include <mach/mfp.h>
+
+#define MFP_DRIVE_VERY_SLOW (0x0 << 13)
+#define MFP_DRIVE_SLOW (0x2 << 13)
+#define MFP_DRIVE_MEDIUM (0x4 << 13)
+#define MFP_DRIVE_FAST (0x6 << 13)
+
+/* UART2 */
+#define GPIO47_UART2_RXD MFP_CFG(GPIO47, AF6)
+#define GPIO48_UART2_TXD MFP_CFG(GPIO48, AF6)
+
+/* UART3 */
+#define GPIO31_UART3_RXD MFP_CFG(GPIO31, AF4)
+#define GPIO32_UART3_TXD MFP_CFG(GPIO32, AF4)
+
+/*IRDA*/
+#define GPIO51_IRDA_SHDN MFP_CFG(GPIO51, AF0)
+
+/* SMC */
+#define SM_nCS0_nCS0 MFP_CFG(SM_nCS0, AF0)
+#define SM_ADV_SM_ADV MFP_CFG(SM_ADV, AF0)
+#define SM_SCLK_SM_SCLK MFP_CFG(SM_SCLK, AF0)
+#define SM_SCLK_SM_SCLK MFP_CFG(SM_SCLK, AF0)
+#define SM_BE0_SM_BE0 MFP_CFG(SM_BE0, AF1)
+#define SM_BE1_SM_BE1 MFP_CFG(SM_BE1, AF1)
+
+/* I2C */
+#define GPIO53_CI2C_SCL MFP_CFG(GPIO53, AF2)
+#define GPIO54_CI2C_SDA MFP_CFG(GPIO54, AF2)
+
+/* SSP1 (I2S) */
+#define GPIO24_SSP1_SDATA_IN MFP_CFG_DRV(GPIO24, AF1, MEDIUM)
+#define GPIO21_SSP1_BITCLK MFP_CFG_DRV(GPIO21, AF1, MEDIUM)
+#define GPIO20_SSP1_SYSCLK MFP_CFG_DRV(GPIO20, AF1, MEDIUM)
+#define GPIO22_SSP1_SYNC MFP_CFG_DRV(GPIO22, AF1, MEDIUM)
+#define GPIO23_SSP1_DATA_OUT MFP_CFG_DRV(GPIO23, AF1, MEDIUM)
+#define GPIO124_MN_CLK_OUT MFP_CFG_DRV(GPIO124, AF1, MEDIUM)
+#define GPIO123_CLK_REQ MFP_CFG_DRV(GPIO123, AF0, MEDIUM)
+
+/* DFI */
+#define DF_IO0_ND_IO0 MFP_CFG(DF_IO0, AF0)
+#define DF_IO1_ND_IO1 MFP_CFG(DF_IO1, AF0)
+#define DF_IO2_ND_IO2 MFP_CFG(DF_IO2, AF0)
+#define DF_IO3_ND_IO3 MFP_CFG(DF_IO3, AF0)
+#define DF_IO4_ND_IO4 MFP_CFG(DF_IO4, AF0)
+#define DF_IO5_ND_IO5 MFP_CFG(DF_IO5, AF0)
+#define DF_IO6_ND_IO6 MFP_CFG(DF_IO6, AF0)
+#define DF_IO7_ND_IO7 MFP_CFG(DF_IO7, AF0)
+#define DF_IO8_ND_IO8 MFP_CFG(DF_IO8, AF0)
+#define DF_IO9_ND_IO9 MFP_CFG(DF_IO9, AF0)
+#define DF_IO10_ND_IO10 MFP_CFG(DF_IO10, AF0)
+#define DF_IO11_ND_IO11 MFP_CFG(DF_IO11, AF0)
+#define DF_IO12_ND_IO12 MFP_CFG(DF_IO12, AF0)
+#define DF_IO13_ND_IO13 MFP_CFG(DF_IO13, AF0)
+#define DF_IO14_ND_IO14 MFP_CFG(DF_IO14, AF0)
+#define DF_IO15_ND_IO15 MFP_CFG(DF_IO15, AF0)
+#define DF_nCS0_SM_nCS2_nCS0 MFP_CFG(DF_nCS0_SM_nCS2, AF0)
+#define DF_ALE_SM_WEn_ND_ALE MFP_CFG(DF_ALE_SM_WEn, AF1)
+#define DF_CLE_SM_OEn_ND_CLE MFP_CFG(DF_CLE_SM_OEn, AF0)
+#define DF_WEn_DF_WEn MFP_CFG(DF_WEn, AF1)
+#define DF_REn_DF_REn MFP_CFG(DF_REn, AF1)
+#define DF_RDY0_DF_RDY0 MFP_CFG(DF_RDY0, AF0)
+
+/*keypad*/
+#define GPIO00_KP_MKIN0 MFP_CFG(GPIO0, AF1)
+#define GPIO01_KP_MKOUT0 MFP_CFG(GPIO1, AF1)
+#define GPIO02_KP_MKIN1 MFP_CFG(GPIO2, AF1)
+#define GPIO03_KP_MKOUT1 MFP_CFG(GPIO3, AF1)
+#define GPIO04_KP_MKIN2 MFP_CFG(GPIO4, AF1)
+#define GPIO05_KP_MKOUT2 MFP_CFG(GPIO5, AF1)
+#define GPIO06_KP_MKIN3 MFP_CFG(GPIO6, AF1)
+#define GPIO07_KP_MKOUT3 MFP_CFG(GPIO7, AF1)
+#define GPIO08_KP_MKIN4 MFP_CFG(GPIO8, AF1)
+#define GPIO09_KP_MKOUT4 MFP_CFG(GPIO9, AF1)
+#define GPIO10_KP_MKIN5 MFP_CFG(GPIO10, AF1)
+#define GPIO11_KP_MKOUT5 MFP_CFG(GPIO11, AF1)
+#define GPIO12_KP_MKIN6 MFP_CFG(GPIO12, AF1)
+#define GPIO13_KP_MKOUT6 MFP_CFG(GPIO13, AF1)
+#define GPIO14_KP_MKIN7 MFP_CFG(GPIO14, AF1)
+#define GPIO15_KP_MKOUT7 MFP_CFG(GPIO15, AF1)
+#define GPIO16_KP_DKIN0 MFP_CFG(GPIO16, AF1)
+#define GPIO17_KP_DKIN1 MFP_CFG(GPIO17, AF1)
+#define GPIO18_KP_DKIN2 MFP_CFG(GPIO18, AF1)
+#define GPIO19_KP_DKIN3 MFP_CFG(GPIO19, AF1)
+
+/* LCD */
+#define GPIO81_LCD_FCLK MFP_CFG(GPIO81, AF1)
+#define GPIO82_LCD_LCLK MFP_CFG(GPIO82, AF1)
+#define GPIO83_LCD_PCLK MFP_CFG(GPIO83, AF1)
+#define GPIO84_LCD_DENA MFP_CFG(GPIO84, AF1)
+#define GPIO85_LCD_DD0 MFP_CFG(GPIO85, AF1)
+#define GPIO86_LCD_DD1 MFP_CFG(GPIO86, AF1)
+#define GPIO87_LCD_DD2 MFP_CFG(GPIO87, AF1)
+#define GPIO88_LCD_DD3 MFP_CFG(GPIO88, AF1)
+#define GPIO89_LCD_DD4 MFP_CFG(GPIO89, AF1)
+#define GPIO90_LCD_DD5 MFP_CFG(GPIO90, AF1)
+#define GPIO91_LCD_DD6 MFP_CFG(GPIO91, AF1)
+#define GPIO92_LCD_DD7 MFP_CFG(GPIO92, AF1)
+#define GPIO93_LCD_DD8 MFP_CFG(GPIO93, AF1)
+#define GPIO94_LCD_DD9 MFP_CFG(GPIO94, AF1)
+#define GPIO95_LCD_DD10 MFP_CFG(GPIO95, AF1)
+#define GPIO96_LCD_DD11 MFP_CFG(GPIO96, AF1)
+#define GPIO97_LCD_DD12 MFP_CFG(GPIO97, AF1)
+#define GPIO98_LCD_DD13 MFP_CFG(GPIO98, AF1)
+#define GPIO100_LCD_DD14 MFP_CFG(GPIO100, AF1)
+#define GPIO101_LCD_DD15 MFP_CFG(GPIO101, AF1)
+#define GPIO102_LCD_DD16 MFP_CFG(GPIO102, AF1)
+#define GPIO103_LCD_DD17 MFP_CFG(GPIO103, AF1)
+#define GPIO104_LCD_DD18 MFP_CFG(GPIO104, AF1)
+#define GPIO105_LCD_DD19 MFP_CFG(GPIO105, AF1)
+#define GPIO106_LCD_DD20 MFP_CFG(GPIO106, AF1)
+#define GPIO107_LCD_DD21 MFP_CFG(GPIO107, AF1)
+#define GPIO108_LCD_DD22 MFP_CFG(GPIO108, AF1)
+#define GPIO109_LCD_DD23 MFP_CFG(GPIO109, AF1)
+
+#define GPIO104_LCD_SPIDOUT MFP_CFG(GPIO104, AF3)
+#define GPIO105_LCD_SPIDIN MFP_CFG(GPIO105, AF3)
+#define GPIO107_LCD_CS1 MFP_CFG(GPIO107, AF3)
+#define GPIO108_LCD_DCLK MFP_CFG(GPIO108, AF3)
+
+#define GPIO106_LCD_RESET MFP_CFG(GPIO106, AF0)
+
+/*smart panel*/
+#define GPIO82_LCD_A0 MFP_CFG(GPIO82, AF0)
+#define GPIO83_LCD_WR MFP_CFG(GPIO83, AF0)
+#define GPIO103_LCD_CS MFP_CFG(GPIO103, AF0)
+
+/*1wire*/
+#define GPIO106_1WIRE MFP_CFG(GPIO106, AF3)
+
+/*CCIC*/
+#define GPIO67_CCIC_IN7 MFP_CFG_DRV(GPIO67, AF1, MEDIUM)
+#define GPIO68_CCIC_IN6 MFP_CFG_DRV(GPIO68, AF1, MEDIUM)
+#define GPIO69_CCIC_IN5 MFP_CFG_DRV(GPIO69, AF1, MEDIUM)
+#define GPIO70_CCIC_IN4 MFP_CFG_DRV(GPIO70, AF1, MEDIUM)
+#define GPIO71_CCIC_IN3 MFP_CFG_DRV(GPIO71, AF1, MEDIUM)
+#define GPIO72_CCIC_IN2 MFP_CFG_DRV(GPIO72, AF1, MEDIUM)
+#define GPIO73_CCIC_IN1 MFP_CFG_DRV(GPIO73, AF1, MEDIUM)
+#define GPIO74_CCIC_IN0 MFP_CFG_DRV(GPIO74, AF1, MEDIUM)
+#define GPIO75_CAM_HSYNC MFP_CFG_DRV(GPIO75, AF1, MEDIUM)
+#define GPIO76_CAM_VSYNC MFP_CFG_DRV(GPIO76, AF1, MEDIUM)
+#define GPIO77_CAM_MCLK MFP_CFG_DRV(GPIO77, AF1, MEDIUM)
+#define GPIO78_CAM_PCLK MFP_CFG_DRV(GPIO78, AF1, MEDIUM)
+
+/* MMC1 */
+#define MMC1_DAT7_MMC1_DAT7 MFP_CFG_DRV(MMC1_DAT7, AF0, MEDIUM)
+#define MMC1_DAT6_MMC1_DAT6 MFP_CFG_DRV(MMC1_DAT6, AF0, MEDIUM)
+#define MMC1_DAT5_MMC1_DAT5 MFP_CFG_DRV(MMC1_DAT5, AF0, MEDIUM)
+#define MMC1_DAT4_MMC1_DAT4 MFP_CFG_DRV(MMC1_DAT4, AF0, MEDIUM)
+#define MMC1_DAT3_MMC1_DAT3 MFP_CFG_DRV(MMC1_DAT3, AF0, MEDIUM)
+#define MMC1_DAT2_MMC1_DAT2 MFP_CFG_DRV(MMC1_DAT2, AF0, MEDIUM)
+#define MMC1_DAT1_MMC1_DAT1 MFP_CFG_DRV(MMC1_DAT1, AF0, MEDIUM)
+#define MMC1_DAT0_MMC1_DAT0 MFP_CFG_DRV(MMC1_DAT0, AF0, MEDIUM)
+#define MMC1_CMD_MMC1_CMD MFP_CFG_DRV(MMC1_CMD, AF0, MEDIUM)
+#define MMC1_CLK_MMC1_CLK MFP_CFG_DRV(MMC1_CLK, AF0, MEDIUM)
+#define MMC1_CD_MMC1_CD MFP_CFG_DRV(MMC1_CD, AF0, MEDIUM)
+#define MMC1_WP_MMC1_WP MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
+
+/* PWM */
+#define GPIO27_PWM3_AF2 MFP_CFG(GPIO27, AF2)
+#define GPIO51_PWM2_OUT MFP_CFG(GPIO51, AF2)
+#define GPIO117_PWM1_OUT MFP_CFG(GPIO117, AF2)
+#define GPIO118_PWM2_OUT MFP_CFG(GPIO118, AF2)
+#define GPIO119_PWM3_OUT MFP_CFG(GPIO119, AF2)
+#define GPIO120_PWM4_OUT MFP_CFG(GPIO120, AF2)
+
+#endif /* __ASM_MACH MFP_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/mfp.h b/arch/arm/mach-mmp/include/mach/mfp.h
new file mode 100644
index 00000000..62e510e8
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mfp.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_MFP_H
+#define __ASM_MACH_MFP_H
+
+#include <plat/mfp.h>
+
+/*
+ * NOTE: the MFPR register bit definitions on PXA168 processor lines are a
+ * bit different from those on PXA3xx. Bit [7:10] are now reserved, which
+ * were SLEEP_OE_N, SLEEP_DATA, SLEEP_SEL and the LSB of DRIVE bits.
+ *
+ * To cope with this difference and re-use the pxa3xx mfp code as much as
+ * possible, we make the following compromise:
+ *
+ * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT)
+ * 2. DRIVE strength definitions redefined to include the reserved bit
+ * - the reserved bit differs between pxa168 and pxa910, and the
+ * MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h
+ * 3. Override MFP_CFG() and MFP_CFG_DRV()
+ * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X()
+ */
+
+#undef MFP_CFG
+#undef MFP_CFG_DRV
+#undef MFP_CFG_LPM
+#undef MFP_CFG_X
+#undef MFP_CFG_DEFAULT
+
+#define MFP_CFG(pin, af) \
+ (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_MEDIUM)
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ (MFP_LPM_FLOAT | MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DRIVE_##drv)
+
+#endif /* __ASM_MACH_MFP_H */
diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h
new file mode 100644
index 00000000..2cbf6df0
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/mmp2.h
@@ -0,0 +1,89 @@
+#ifndef __ASM_MACH_MMP2_H
+#define __ASM_MACH_MMP2_H
+
+#include <plat/sdhci.h>
+
+struct sys_timer;
+
+extern struct sys_timer mmp2_timer;
+extern void __init mmp2_init_icu(void);
+extern void __init mmp2_init_irq(void);
+extern void mmp2_clear_pmic_int(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <mach/devices.h>
+
+extern struct pxa_device_desc mmp2_device_uart1;
+extern struct pxa_device_desc mmp2_device_uart2;
+extern struct pxa_device_desc mmp2_device_uart3;
+extern struct pxa_device_desc mmp2_device_uart4;
+extern struct pxa_device_desc mmp2_device_twsi1;
+extern struct pxa_device_desc mmp2_device_twsi2;
+extern struct pxa_device_desc mmp2_device_twsi3;
+extern struct pxa_device_desc mmp2_device_twsi4;
+extern struct pxa_device_desc mmp2_device_twsi5;
+extern struct pxa_device_desc mmp2_device_twsi6;
+extern struct pxa_device_desc mmp2_device_sdh0;
+extern struct pxa_device_desc mmp2_device_sdh1;
+extern struct pxa_device_desc mmp2_device_sdh2;
+extern struct pxa_device_desc mmp2_device_sdh3;
+
+static inline int mmp2_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &mmp2_device_uart1; break;
+ case 2: d = &mmp2_device_uart2; break;
+ case 3: d = &mmp2_device_uart3; break;
+ case 4: d = &mmp2_device_uart4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int mmp2_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 1: d = &mmp2_device_twsi1; break;
+ case 2: d = &mmp2_device_twsi2; break;
+ case 3: d = &mmp2_device_twsi3; break;
+ case 4: d = &mmp2_device_twsi4; break;
+ case 5: d = &mmp2_device_twsi5; break;
+ case 6: d = &mmp2_device_twsi6; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id - 1, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int mmp2_add_sdhost(int id, struct sdhci_pxa_platdata *data)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 0: d = &mmp2_device_sdh0; break;
+ case 1: d = &mmp2_device_sdh1; break;
+ case 2: d = &mmp2_device_sdh2; break;
+ case 3: d = &mmp2_device_sdh3; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_MMP2_H */
+
diff --git a/arch/arm/mach-mmp/include/mach/pxa168.h b/arch/arm/mach-mmp/include/mach/pxa168.h
new file mode 100644
index 00000000..a52b3d2f
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa168.h
@@ -0,0 +1,120 @@
+#ifndef __ASM_MACH_PXA168_H
+#define __ASM_MACH_PXA168_H
+
+struct sys_timer;
+
+extern struct sys_timer pxa168_timer;
+extern void __init pxa168_init_irq(void);
+extern void pxa168_clear_keypad_wakeup(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <mach/devices.h>
+#include <plat/pxa3xx_nand.h>
+#include <video/pxa168fb.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/cputype.h>
+
+extern struct pxa_device_desc pxa168_device_uart1;
+extern struct pxa_device_desc pxa168_device_uart2;
+extern struct pxa_device_desc pxa168_device_twsi0;
+extern struct pxa_device_desc pxa168_device_twsi1;
+extern struct pxa_device_desc pxa168_device_pwm1;
+extern struct pxa_device_desc pxa168_device_pwm2;
+extern struct pxa_device_desc pxa168_device_pwm3;
+extern struct pxa_device_desc pxa168_device_pwm4;
+extern struct pxa_device_desc pxa168_device_ssp1;
+extern struct pxa_device_desc pxa168_device_ssp2;
+extern struct pxa_device_desc pxa168_device_ssp3;
+extern struct pxa_device_desc pxa168_device_ssp4;
+extern struct pxa_device_desc pxa168_device_ssp5;
+extern struct pxa_device_desc pxa168_device_nand;
+extern struct pxa_device_desc pxa168_device_fb;
+extern struct pxa_device_desc pxa168_device_keypad;
+
+static inline int pxa168_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_uart1; break;
+ case 2: d = &pxa168_device_uart2; break;
+ }
+
+ if (d == NULL)
+ return -EINVAL;
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 0: d = &pxa168_device_twsi0; break;
+ case 1: d = &pxa168_device_twsi1; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa168_add_pwm(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_pwm1; break;
+ case 2: d = &pxa168_device_pwm2; break;
+ case 3: d = &pxa168_device_pwm3; break;
+ case 4: d = &pxa168_device_pwm4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_ssp(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa168_device_ssp1; break;
+ case 2: d = &pxa168_device_ssp2; break;
+ case 3: d = &pxa168_device_ssp3; break;
+ case 4: d = &pxa168_device_ssp4; break;
+ case 5: d = &pxa168_device_ssp5; break;
+ default:
+ return -EINVAL;
+ }
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa168_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+ return pxa_register_device(&pxa168_device_nand, info, sizeof(*info));
+}
+
+static inline int pxa168_add_fb(struct pxa168fb_mach_info *mi)
+{
+ return pxa_register_device(&pxa168_device_fb, mi, sizeof(*mi));
+}
+
+static inline int pxa168_add_keypad(struct pxa27x_keypad_platform_data *data)
+{
+ if (cpu_is_pxa168())
+ data->clear_wakeup_event = pxa168_clear_keypad_wakeup;
+
+ return pxa_register_device(&pxa168_device_keypad, data, sizeof(*data));
+}
+
+#endif /* __ASM_MACH_PXA168_H */
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
new file mode 100644
index 00000000..91be7559
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -0,0 +1,79 @@
+#ifndef __ASM_MACH_PXA910_H
+#define __ASM_MACH_PXA910_H
+
+struct sys_timer;
+
+extern struct sys_timer pxa910_timer;
+extern void __init pxa910_init_irq(void);
+
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <mach/devices.h>
+#include <plat/pxa3xx_nand.h>
+
+extern struct pxa_device_desc pxa910_device_uart1;
+extern struct pxa_device_desc pxa910_device_uart2;
+extern struct pxa_device_desc pxa910_device_twsi0;
+extern struct pxa_device_desc pxa910_device_twsi1;
+extern struct pxa_device_desc pxa910_device_pwm1;
+extern struct pxa_device_desc pxa910_device_pwm2;
+extern struct pxa_device_desc pxa910_device_pwm3;
+extern struct pxa_device_desc pxa910_device_pwm4;
+extern struct pxa_device_desc pxa910_device_nand;
+
+static inline int pxa910_add_uart(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa910_device_uart1; break;
+ case 2: d = &pxa910_device_uart2; break;
+ }
+
+ if (d == NULL)
+ return -EINVAL;
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa910_add_twsi(int id, struct i2c_pxa_platform_data *data,
+ struct i2c_board_info *info, unsigned size)
+{
+ struct pxa_device_desc *d = NULL;
+ int ret;
+
+ switch (id) {
+ case 0: d = &pxa910_device_twsi0; break;
+ case 1: d = &pxa910_device_twsi1; break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = i2c_register_board_info(id, info, size);
+ if (ret)
+ return ret;
+
+ return pxa_register_device(d, data, sizeof(*data));
+}
+
+static inline int pxa910_add_pwm(int id)
+{
+ struct pxa_device_desc *d = NULL;
+
+ switch (id) {
+ case 1: d = &pxa910_device_pwm1; break;
+ case 2: d = &pxa910_device_pwm2; break;
+ case 3: d = &pxa910_device_pwm3; break;
+ case 4: d = &pxa910_device_pwm4; break;
+ default:
+ return -EINVAL;
+ }
+
+ return pxa_register_device(d, NULL, 0);
+}
+
+static inline int pxa910_add_nand(struct pxa3xx_nand_platform_data *info)
+{
+ return pxa_register_device(&pxa910_device_nand, info, sizeof(*info));
+}
+#endif /* __ASM_MACH_PXA910_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
new file mode 100644
index 00000000..1a965853
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -0,0 +1,121 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apbc.h
+ *
+ * Application Peripheral Bus Clock Unit
+ *
+ * This program is free software; you can 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_MACH_REGS_APBC_H
+#define __ASM_MACH_REGS_APBC_H
+
+#include <mach/addr-map.h>
+
+#define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000)
+#define APBC_REG(x) (APBC_VIRT_BASE + (x))
+
+/*
+ * APB clock register offsets for PXA168
+ */
+#define APBC_PXA168_UART1 APBC_REG(0x000)
+#define APBC_PXA168_UART2 APBC_REG(0x004)
+#define APBC_PXA168_GPIO APBC_REG(0x008)
+#define APBC_PXA168_PWM1 APBC_REG(0x00c)
+#define APBC_PXA168_PWM2 APBC_REG(0x010)
+#define APBC_PXA168_PWM3 APBC_REG(0x014)
+#define APBC_PXA168_PWM4 APBC_REG(0x018)
+#define APBC_PXA168_RTC APBC_REG(0x028)
+#define APBC_PXA168_TWSI0 APBC_REG(0x02c)
+#define APBC_PXA168_KPC APBC_REG(0x030)
+#define APBC_PXA168_TIMERS APBC_REG(0x034)
+#define APBC_PXA168_AIB APBC_REG(0x03c)
+#define APBC_PXA168_SW_JTAG APBC_REG(0x040)
+#define APBC_PXA168_ONEWIRE APBC_REG(0x048)
+#define APBC_PXA168_ASFAR APBC_REG(0x050)
+#define APBC_PXA168_ASSAR APBC_REG(0x054)
+#define APBC_PXA168_TWSI1 APBC_REG(0x06c)
+#define APBC_PXA168_UART3 APBC_REG(0x070)
+#define APBC_PXA168_AC97 APBC_REG(0x084)
+#define APBC_PXA168_SSP1 APBC_REG(0x81c)
+#define APBC_PXA168_SSP2 APBC_REG(0x820)
+#define APBC_PXA168_SSP3 APBC_REG(0x84c)
+#define APBC_PXA168_SSP4 APBC_REG(0x858)
+#define APBC_PXA168_SSP5 APBC_REG(0x85c)
+
+/*
+ * APB Clock register offsets for PXA910
+ */
+#define APBC_PXA910_UART0 APBC_REG(0x000)
+#define APBC_PXA910_UART1 APBC_REG(0x004)
+#define APBC_PXA910_GPIO APBC_REG(0x008)
+#define APBC_PXA910_PWM1 APBC_REG(0x00c)
+#define APBC_PXA910_PWM2 APBC_REG(0x010)
+#define APBC_PXA910_PWM3 APBC_REG(0x014)
+#define APBC_PXA910_PWM4 APBC_REG(0x018)
+#define APBC_PXA910_SSP1 APBC_REG(0x01c)
+#define APBC_PXA910_SSP2 APBC_REG(0x020)
+#define APBC_PXA910_IPC APBC_REG(0x024)
+#define APBC_PXA910_TWSI0 APBC_REG(0x02c)
+#define APBC_PXA910_KPC APBC_REG(0x030)
+#define APBC_PXA910_TIMERS APBC_REG(0x034)
+#define APBC_PXA910_TBROT APBC_REG(0x038)
+#define APBC_PXA910_AIB APBC_REG(0x03c)
+#define APBC_PXA910_SW_JTAG APBC_REG(0x040)
+#define APBC_PXA910_TIMERS1 APBC_REG(0x044)
+#define APBC_PXA910_ONEWIRE APBC_REG(0x048)
+#define APBC_PXA910_SSP3 APBC_REG(0x04c)
+#define APBC_PXA910_ASFAR APBC_REG(0x050)
+#define APBC_PXA910_ASSAR APBC_REG(0x054)
+
+/*
+ * APB Clock register offsets for MMP2
+ */
+#define APBC_MMP2_RTC APBC_REG(0x000)
+#define APBC_MMP2_TWSI1 APBC_REG(0x004)
+#define APBC_MMP2_TWSI2 APBC_REG(0x008)
+#define APBC_MMP2_TWSI3 APBC_REG(0x00c)
+#define APBC_MMP2_TWSI4 APBC_REG(0x010)
+#define APBC_MMP2_ONEWIRE APBC_REG(0x014)
+#define APBC_MMP2_KPC APBC_REG(0x018)
+#define APBC_MMP2_TB_ROTARY APBC_REG(0x01c)
+#define APBC_MMP2_SW_JTAG APBC_REG(0x020)
+#define APBC_MMP2_TIMERS APBC_REG(0x024)
+#define APBC_MMP2_UART1 APBC_REG(0x02c)
+#define APBC_MMP2_UART2 APBC_REG(0x030)
+#define APBC_MMP2_UART3 APBC_REG(0x034)
+#define APBC_MMP2_GPIO APBC_REG(0x038)
+#define APBC_MMP2_PWM0 APBC_REG(0x03c)
+#define APBC_MMP2_PWM1 APBC_REG(0x040)
+#define APBC_MMP2_PWM2 APBC_REG(0x044)
+#define APBC_MMP2_PWM3 APBC_REG(0x048)
+#define APBC_MMP2_SSP0 APBC_REG(0x04c)
+#define APBC_MMP2_SSP1 APBC_REG(0x050)
+#define APBC_MMP2_SSP2 APBC_REG(0x054)
+#define APBC_MMP2_SSP3 APBC_REG(0x058)
+#define APBC_MMP2_SSP4 APBC_REG(0x05c)
+#define APBC_MMP2_SSP5 APBC_REG(0x060)
+#define APBC_MMP2_AIB APBC_REG(0x064)
+#define APBC_MMP2_ASFAR APBC_REG(0x068)
+#define APBC_MMP2_ASSAR APBC_REG(0x06c)
+#define APBC_MMP2_USIM APBC_REG(0x070)
+#define APBC_MMP2_MPMU APBC_REG(0x074)
+#define APBC_MMP2_IPC APBC_REG(0x078)
+#define APBC_MMP2_TWSI5 APBC_REG(0x07c)
+#define APBC_MMP2_TWSI6 APBC_REG(0x080)
+#define APBC_MMP2_TWSI_INTSTS APBC_REG(0x084)
+#define APBC_MMP2_UART4 APBC_REG(0x088)
+#define APBC_MMP2_RIPC APBC_REG(0x08c)
+#define APBC_MMP2_THSENS1 APBC_REG(0x090) /* Thermal Sensor */
+#define APBC_MMP2_THSENS_INTSTS APBC_REG(0x0a4)
+
+/* Common APB clock register bit definitions */
+#define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */
+#define APBC_FNCLK (1 << 1) /* Functional Clock Enable */
+#define APBC_RST (1 << 2) /* Reset Generation */
+
+/* Functional Clock Selection Mask */
+#define APBC_FNCLKSEL(x) (((x) & 0xf) << 4)
+
+#endif /* __ASM_MACH_REGS_APBC_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h
new file mode 100644
index 00000000..f7011ef7
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-apmu.h
+ *
+ * Application Subsystem Power Management Unit
+ *
+ * This program is free software; you can 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_MACH_REGS_APMU_H
+#define __ASM_MACH_REGS_APMU_H
+
+#include <mach/addr-map.h>
+
+#define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800)
+#define APMU_REG(x) (APMU_VIRT_BASE + (x))
+
+/* Clock Reset Control */
+#define APMU_IRE APMU_REG(0x048)
+#define APMU_LCD APMU_REG(0x04c)
+#define APMU_CCIC APMU_REG(0x050)
+#define APMU_SDH0 APMU_REG(0x054)
+#define APMU_SDH1 APMU_REG(0x058)
+#define APMU_USB APMU_REG(0x05c)
+#define APMU_NAND APMU_REG(0x060)
+#define APMU_DMA APMU_REG(0x064)
+#define APMU_GEU APMU_REG(0x068)
+#define APMU_BUS APMU_REG(0x06c)
+#define APMU_SDH2 APMU_REG(0x0e8)
+#define APMU_SDH3 APMU_REG(0x0ec)
+
+#define APMU_FNCLK_EN (1 << 4)
+#define APMU_AXICLK_EN (1 << 3)
+#define APMU_FNRST_DIS (1 << 1)
+#define APMU_AXIRST_DIS (1 << 0)
+
+/* Wake Clear Register */
+#define APMU_WAKE_CLR APMU_REG(0x07c)
+
+#define APMU_PXA168_KP_WAKE_CLR (1 << 7)
+#define APMU_PXA168_CFI_WAKE_CLR (1 << 6)
+#define APMU_PXA168_XD_WAKE_CLR (1 << 5)
+#define APMU_PXA168_MSP_WAKE_CLR (1 << 4)
+#define APMU_PXA168_SD4_WAKE_CLR (1 << 3)
+#define APMU_PXA168_SD3_WAKE_CLR (1 << 2)
+#define APMU_PXA168_SD2_WAKE_CLR (1 << 1)
+#define APMU_PXA168_SD1_WAKE_CLR (1 << 0)
+
+#endif /* __ASM_MACH_REGS_APMU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-icu.h b/arch/arm/mach-mmp/include/mach/regs-icu.h
new file mode 100644
index 00000000..f882d918
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-icu.h
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-icu.h
+ *
+ * Interrupt Control Unit
+ *
+ * This program is free software; you can 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_MACH_ICU_H
+#define __ASM_MACH_ICU_H
+
+#include <mach/addr-map.h>
+
+#define ICU_VIRT_BASE (AXI_VIRT_BASE + 0x82000)
+#define ICU_REG(x) (ICU_VIRT_BASE + (x))
+
+#define ICU_INT_CONF(n) ICU_REG((n) << 2)
+#define ICU_INT_CONF_MASK (0xf)
+
+/************ PXA168/PXA910 (MMP) *********************/
+#define ICU_INT_CONF_AP_INT (1 << 6)
+#define ICU_INT_CONF_CP_INT (1 << 5)
+#define ICU_INT_CONF_IRQ (1 << 4)
+
+#define ICU_AP_FIQ_SEL_INT_NUM ICU_REG(0x108) /* AP FIQ Selected Interrupt */
+#define ICU_AP_IRQ_SEL_INT_NUM ICU_REG(0x10C) /* AP IRQ Selected Interrupt */
+#define ICU_AP_GBL_IRQ_MSK ICU_REG(0x114) /* AP Global Interrupt Mask */
+#define ICU_INT_STATUS_0 ICU_REG(0x128) /* Interrupt Stuats 0 */
+#define ICU_INT_STATUS_1 ICU_REG(0x12C) /* Interrupt Status 1 */
+
+/************************** MMP2 ***********************/
+
+/*
+ * IRQ0/FIQ0 is routed to SP IRQ/FIQ.
+ * IRQ1 is routed to PJ4 IRQ, and IRQ2 is routes to PJ4 FIQ.
+ */
+#define ICU_INT_ROUTE_SP_IRQ (1 << 4)
+#define ICU_INT_ROUTE_PJ4_IRQ (1 << 5)
+#define ICU_INT_ROUTE_PJ4_FIQ (1 << 6)
+
+#define MMP2_ICU_PJ4_IRQ_STATUS0 ICU_REG(0x138)
+#define MMP2_ICU_PJ4_IRQ_STATUS1 ICU_REG(0x13c)
+#define MMP2_ICU_PJ4_FIQ_STATUS0 ICU_REG(0x140)
+#define MMP2_ICU_PJ4_FIQ_STATUS1 ICU_REG(0x144)
+
+#define MMP2_ICU_INT4_STATUS ICU_REG(0x150)
+#define MMP2_ICU_INT5_STATUS ICU_REG(0x154)
+#define MMP2_ICU_INT17_STATUS ICU_REG(0x158)
+#define MMP2_ICU_INT35_STATUS ICU_REG(0x15c)
+#define MMP2_ICU_INT51_STATUS ICU_REG(0x160)
+
+#define MMP2_ICU_INT4_MASK ICU_REG(0x168)
+#define MMP2_ICU_INT5_MASK ICU_REG(0x16C)
+#define MMP2_ICU_INT17_MASK ICU_REG(0x170)
+#define MMP2_ICU_INT35_MASK ICU_REG(0x174)
+#define MMP2_ICU_INT51_MASK ICU_REG(0x178)
+
+#define MMP2_ICU_SP_IRQ_SEL ICU_REG(0x100)
+#define MMP2_ICU_PJ4_IRQ_SEL ICU_REG(0x104)
+#define MMP2_ICU_PJ4_FIQ_SEL ICU_REG(0x108)
+
+#define MMP2_ICU_INVERT ICU_REG(0x164)
+
+#define MMP2_ICU_INV_PMIC (1 << 0)
+#define MMP2_ICU_INV_PERF (1 << 1)
+#define MMP2_ICU_INV_COMMTX (1 << 2)
+#define MMP2_ICU_INV_COMMRX (1 << 3)
+
+#endif /* __ASM_MACH_ICU_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-smc.h b/arch/arm/mach-mmp/include/mach/regs-smc.h
new file mode 100644
index 00000000..e484d40d
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-smc.h
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-smc.h
+ *
+ * Static Memory Controller 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 __ASM_MACH_REGS_SMC_H
+#define __ASM_MACH_REGS_SMC_H
+
+#include <mach/addr-map.h>
+
+#define SMC_VIRT_BASE (AXI_VIRT_BASE + 0x83800)
+#define SMC_REG(x) (SMC_VIRT_BASE + (x))
+
+#define SMC_MSC0 SMC_REG(0x0020)
+#define SMC_MSC1 SMC_REG(0x0024)
+#define SMC_SXCNFG0 SMC_REG(0x0030)
+#define SMC_SXCNFG1 SMC_REG(0x0034)
+#define SMC_MEMCLKCFG SMC_REG(0x0068)
+#define SMC_CSDFICFG0 SMC_REG(0x0090)
+#define SMC_CSDFICFG1 SMC_REG(0x0094)
+#define SMC_CLK_RET_DEL SMC_REG(0x00b0)
+#define SMC_ADV_RET_DEL SMC_REG(0x00b4)
+#define SMC_CSADRMAP0 SMC_REG(0x00c0)
+#define SMC_CSADRMAP1 SMC_REG(0x00c4)
+#define SMC_WE_AP0 SMC_REG(0x00e0)
+#define SMC_WE_AP1 SMC_REG(0x00e4)
+#define SMC_OE_AP0 SMC_REG(0x00f0)
+#define SMC_OE_AP1 SMC_REG(0x00f4)
+#define SMC_ADV_AP0 SMC_REG(0x0100)
+#define SMC_ADV_AP1 SMC_REG(0x0104)
+
+#endif /* __ASM_MACH_REGS_SMC_H */
diff --git a/arch/arm/mach-mmp/include/mach/regs-timers.h b/arch/arm/mach-mmp/include/mach/regs-timers.h
new file mode 100644
index 00000000..45589fec
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-timers.h
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/regs-timers.h
+ *
+ * Timers Module
+ *
+ * This program is free software; you can 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_MACH_REGS_TIMERS_H
+#define __ASM_MACH_REGS_TIMERS_H
+
+#include <mach/addr-map.h>
+
+#define TIMERS1_VIRT_BASE (APB_VIRT_BASE + 0x14000)
+#define TIMERS2_VIRT_BASE (APB_VIRT_BASE + 0x16000)
+
+#define TMR_CCR (0x0000)
+#define TMR_TN_MM(n, m) (0x0004 + ((n) << 3) + (((n) + (m)) << 2))
+#define TMR_CR(n) (0x0028 + ((n) << 2))
+#define TMR_SR(n) (0x0034 + ((n) << 2))
+#define TMR_IER(n) (0x0040 + ((n) << 2))
+#define TMR_PLVR(n) (0x004c + ((n) << 2))
+#define TMR_PLCR(n) (0x0058 + ((n) << 2))
+#define TMR_WMER (0x0064)
+#define TMR_WMR (0x0068)
+#define TMR_WVR (0x006c)
+#define TMR_WSR (0x0070)
+#define TMR_ICR(n) (0x0074 + ((n) << 2))
+#define TMR_WICR (0x0080)
+#define TMR_CER (0x0084)
+#define TMR_CMR (0x0088)
+#define TMR_ILR(n) (0x008c + ((n) << 2))
+#define TMR_WCR (0x0098)
+#define TMR_WFAR (0x009c)
+#define TMR_WSAR (0x00A0)
+#define TMR_CVWR(n) (0x00A4 + ((n) << 2))
+
+#define TMR_CCR_CS_0(x) (((x) & 0x3) << 0)
+#define TMR_CCR_CS_1(x) (((x) & 0x7) << 2)
+#define TMR_CCR_CS_2(x) (((x) & 0x3) << 5)
+
+#endif /* __ASM_MACH_REGS_TIMERS_H */
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
new file mode 100644
index 00000000..1a8a25ed
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/system.h
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/system.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_SYSTEM_H
+#define __ASM_MACH_SYSTEM_H
+
+#include <mach/cputype.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (cpu_is_pxa168())
+ cpu_reset(0xffff0000);
+ else
+ cpu_reset(0);
+}
+#endif /* __ASM_MACH_SYSTEM_H */
diff --git a/arch/arm/mach-mmp/include/mach/teton_bga.h b/arch/arm/mach-mmp/include/mach/teton_bga.h
new file mode 100644
index 00000000..61a539b2
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/teton_bga.h
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/teton_bga.h
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_TETON_BGA_H
+#define __ASM_MACH_TETON_BGA_H
+
+/* GPIOs */
+#define MMC_PWENA_GPIO 27
+#define USBHPENB_GPIO 55
+#define RTC_INT_GPIO 78
+#define LCD_VBLK_EN_GPIO 79
+#define LCD_DVDD_EN_GPIO 80
+#define RST_WIFI_GPIO 81
+#define CF_PWEN_GPIO 82
+#define USB_OC_GPIO 83
+#define PWM_GPIO 84
+#define USBHPENA_GPIO 85
+#define TS_INT_GPIO 86
+#define CIR_GPIO 108
+
+#endif /* __ASM_MACH_TETON_BGA_H */
diff --git a/arch/arm/mach-mmp/include/mach/timex.h b/arch/arm/mach-mmp/include/mach/timex.h
new file mode 100644
index 00000000..70c9f1d8
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/timex.h
@@ -0,0 +1,13 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/timex.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifdef CONFIG_CPU_MMP2
+#define CLOCK_TICK_RATE 6500000
+#else
+#define CLOCK_TICK_RATE 3250000
+#endif
diff --git a/arch/arm/mach-mmp/include/mach/uncompress.h b/arch/arm/mach-mmp/include/mach/uncompress.h
new file mode 100644
index 00000000..d6daeb7e
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/uncompress.h
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-mmp/include/mach/uncompress.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/addr-map.h>
+#include <asm/mach-types.h>
+
+#define UART1_BASE (APB_PHYS_BASE + 0x36000)
+#define UART2_BASE (APB_PHYS_BASE + 0x17000)
+#define UART3_BASE (APB_PHYS_BASE + 0x18000)
+
+volatile unsigned long *UART;
+
+static inline void putc(char c)
+{
+ /* UART enabled? */
+ if (!(UART[UART_IER] & UART_IER_UUE))
+ return;
+
+ while (!(UART[UART_LSR] & UART_LSR_THRE))
+ barrier();
+
+ UART[UART_TX] = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+ /* default to UART2 */
+ UART = (unsigned long *)UART2_BASE;
+
+ if (machine_is_avengers_lite())
+ UART = (unsigned long *)UART3_BASE;
+}
+
+/*
+ * nothing to do
+ */
+
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-mmp/include/mach/vmalloc.h b/arch/arm/mach-mmp/include/mach/vmalloc.h
new file mode 100644
index 00000000..1d0bac00
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * linux/arch/arm/mach-mmp/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe000000UL
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
new file mode 100644
index 00000000..d21c5441
--- /dev/null
+++ b/arch/arm/mach-mmp/irq-mmp2.c
@@ -0,0 +1,157 @@
+/*
+ * linux/arch/arm/mach-mmp/irq-mmp2.c
+ *
+ * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ * Copyright: Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-icu.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+static void icu_mask_irq(struct irq_data *d)
+{
+ uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
+
+ r &= ~ICU_INT_ROUTE_PJ4_IRQ;
+ __raw_writel(r, ICU_INT_CONF(d->irq));
+}
+
+static void icu_unmask_irq(struct irq_data *d)
+{
+ uint32_t r = __raw_readl(ICU_INT_CONF(d->irq));
+
+ r |= ICU_INT_ROUTE_PJ4_IRQ;
+ __raw_writel(r, ICU_INT_CONF(d->irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+ .name = "icu_irq",
+ .irq_mask = icu_mask_irq,
+ .irq_mask_ack = icu_mask_irq,
+ .irq_unmask = icu_unmask_irq,
+};
+
+static void pmic_irq_ack(struct irq_data *d)
+{
+ if (d->irq == IRQ_MMP2_PMIC)
+ mmp2_clear_pmic_int();
+}
+
+#define SECOND_IRQ_MASK(_name_, irq_base, prefix) \
+static void _name_##_mask_irq(struct irq_data *d) \
+{ \
+ uint32_t r; \
+ r = __raw_readl(prefix##_MASK) | (1 << (d->irq - irq_base)); \
+ __raw_writel(r, prefix##_MASK); \
+}
+
+#define SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
+static void _name_##_unmask_irq(struct irq_data *d) \
+{ \
+ uint32_t r; \
+ r = __raw_readl(prefix##_MASK) & ~(1 << (d->irq - irq_base)); \
+ __raw_writel(r, prefix##_MASK); \
+}
+
+#define SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
+static void _name_##_irq_demux(unsigned int irq, struct irq_desc *desc) \
+{ \
+ unsigned long status, mask, n; \
+ mask = __raw_readl(prefix##_MASK); \
+ while (1) { \
+ status = __raw_readl(prefix##_STATUS) & ~mask; \
+ if (status == 0) \
+ break; \
+ n = find_first_bit(&status, BITS_PER_LONG); \
+ while (n < BITS_PER_LONG) { \
+ generic_handle_irq(irq_base + n); \
+ n = find_next_bit(&status, BITS_PER_LONG, n+1); \
+ } \
+ } \
+}
+
+#define SECOND_IRQ_CHIP(_name_, irq_base, prefix) \
+SECOND_IRQ_MASK(_name_, irq_base, prefix) \
+SECOND_IRQ_UNMASK(_name_, irq_base, prefix) \
+SECOND_IRQ_DEMUX(_name_, irq_base, prefix) \
+static struct irq_chip _name_##_irq_chip = { \
+ .name = #_name_, \
+ .irq_mask = _name_##_mask_irq, \
+ .irq_unmask = _name_##_unmask_irq, \
+}
+
+SECOND_IRQ_CHIP(pmic, IRQ_MMP2_PMIC_BASE, MMP2_ICU_INT4);
+SECOND_IRQ_CHIP(rtc, IRQ_MMP2_RTC_BASE, MMP2_ICU_INT5);
+SECOND_IRQ_CHIP(twsi, IRQ_MMP2_TWSI_BASE, MMP2_ICU_INT17);
+SECOND_IRQ_CHIP(misc, IRQ_MMP2_MISC_BASE, MMP2_ICU_INT35);
+SECOND_IRQ_CHIP(ssp, IRQ_MMP2_SSP_BASE, MMP2_ICU_INT51);
+
+static void init_mux_irq(struct irq_chip *chip, int start, int num)
+{
+ int irq;
+
+ for (irq = start; num > 0; irq++, num--) {
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ /* mask and clear the IRQ */
+ chip->irq_mask(d);
+ if (chip->irq_ack)
+ chip->irq_ack(d);
+
+ irq_set_chip(irq, chip);
+ set_irq_flags(irq, IRQF_VALID);
+ irq_set_handler(irq, handle_level_irq);
+ }
+}
+
+void __init mmp2_init_icu(void)
+{
+ int irq;
+
+ for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
+ icu_mask_irq(irq_get_irq_data(irq));
+ irq_set_chip(irq, &icu_irq_chip);
+ set_irq_flags(irq, IRQF_VALID);
+
+ switch (irq) {
+ case IRQ_MMP2_PMIC_MUX:
+ case IRQ_MMP2_RTC_MUX:
+ case IRQ_MMP2_TWSI_MUX:
+ case IRQ_MMP2_MISC_MUX:
+ case IRQ_MMP2_SSP_MUX:
+ break;
+ default:
+ irq_set_handler(irq, handle_level_irq);
+ break;
+ }
+ }
+
+ /* NOTE: IRQ_MMP2_PMIC requires the PMIC MFPR register
+ * to be written to clear the interrupt
+ */
+ pmic_irq_chip.irq_ack = pmic_irq_ack;
+
+ init_mux_irq(&pmic_irq_chip, IRQ_MMP2_PMIC_BASE, 2);
+ init_mux_irq(&rtc_irq_chip, IRQ_MMP2_RTC_BASE, 2);
+ init_mux_irq(&twsi_irq_chip, IRQ_MMP2_TWSI_BASE, 5);
+ init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
+ init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
+
+ irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
+}
diff --git a/arch/arm/mach-mmp/irq-pxa168.c b/arch/arm/mach-mmp/irq-pxa168.c
new file mode 100644
index 00000000..89706a0d
--- /dev/null
+++ b/arch/arm/mach-mmp/irq-pxa168.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-mmp/irq.c
+ *
+ * Generic IRQ handling, GPIO IRQ demultiplexing, etc.
+ *
+ * Author: Bin Yang <bin.yang@marvell.com>
+ * Created: Sep 30, 2008
+ * Copyright: Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/regs-icu.h>
+
+#include "common.h"
+
+#define IRQ_ROUTE_TO_AP (ICU_INT_CONF_AP_INT | ICU_INT_CONF_IRQ)
+
+#define PRIORITY_DEFAULT 0x1
+#define PRIORITY_NONE 0x0 /* means IRQ disabled */
+
+static void icu_mask_irq(struct irq_data *d)
+{
+ __raw_writel(PRIORITY_NONE, ICU_INT_CONF(d->irq));
+}
+
+static void icu_unmask_irq(struct irq_data *d)
+{
+ __raw_writel(IRQ_ROUTE_TO_AP | PRIORITY_DEFAULT, ICU_INT_CONF(d->irq));
+}
+
+static struct irq_chip icu_irq_chip = {
+ .name = "icu_irq",
+ .irq_ack = icu_mask_irq,
+ .irq_mask = icu_mask_irq,
+ .irq_unmask = icu_unmask_irq,
+};
+
+void __init icu_init_irq(void)
+{
+ int irq;
+
+ for (irq = 0; irq < 64; irq++) {
+ icu_mask_irq(irq_get_irq_data(irq));
+ irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c
new file mode 100644
index 00000000..24172a0a
--- /dev/null
+++ b/arch/arm/mach-mmp/jasper.c
@@ -0,0 +1,179 @@
+/*
+ * linux/arch/arm/mach-mmp/jasper.c
+ *
+ * Support for the Marvell Jasper Development Platform.
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max8649.h>
+#include <linux/mfd/max8925.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-mmp2.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+
+#define JASPER_NR_IRQS (IRQ_BOARD_START + 48)
+
+static unsigned long jasper_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO29_UART1_RXD,
+ GPIO30_UART1_TXD,
+
+ /* UART3 */
+ GPIO51_UART3_RXD,
+ GPIO52_UART3_TXD,
+
+ /* DFI */
+ GPIO168_DFI_D0,
+ GPIO167_DFI_D1,
+ GPIO166_DFI_D2,
+ GPIO165_DFI_D3,
+ GPIO107_DFI_D4,
+ GPIO106_DFI_D5,
+ GPIO105_DFI_D6,
+ GPIO104_DFI_D7,
+ GPIO111_DFI_D8,
+ GPIO164_DFI_D9,
+ GPIO163_DFI_D10,
+ GPIO162_DFI_D11,
+ GPIO161_DFI_D12,
+ GPIO110_DFI_D13,
+ GPIO109_DFI_D14,
+ GPIO108_DFI_D15,
+ GPIO143_ND_nCS0,
+ GPIO144_ND_nCS1,
+ GPIO147_ND_nWE,
+ GPIO148_ND_nRE,
+ GPIO150_ND_ALE,
+ GPIO149_ND_CLE,
+ GPIO112_ND_RDY0,
+ GPIO160_ND_RDY1,
+
+ /* PMIC */
+ PMIC_PMIC_INT | MFP_LPM_EDGE_FALL,
+
+ /* MMC1 */
+ GPIO131_MMC1_DAT3,
+ GPIO132_MMC1_DAT2,
+ GPIO133_MMC1_DAT1,
+ GPIO134_MMC1_DAT0,
+ GPIO136_MMC1_CMD,
+ GPIO139_MMC1_CLK,
+ GPIO140_MMC1_CD,
+ GPIO141_MMC1_WP,
+
+ /* MMC2 */
+ GPIO37_MMC2_DAT3,
+ GPIO38_MMC2_DAT2,
+ GPIO39_MMC2_DAT1,
+ GPIO40_MMC2_DAT0,
+ GPIO41_MMC2_CMD,
+ GPIO42_MMC2_CLK,
+
+ /* MMC3 */
+ GPIO165_MMC3_DAT7,
+ GPIO162_MMC3_DAT6,
+ GPIO166_MMC3_DAT5,
+ GPIO163_MMC3_DAT4,
+ GPIO167_MMC3_DAT3,
+ GPIO164_MMC3_DAT2,
+ GPIO168_MMC3_DAT1,
+ GPIO111_MMC3_DAT0,
+ GPIO112_MMC3_CMD,
+ GPIO151_MMC3_CLK,
+};
+
+static struct regulator_consumer_supply max8649_supply[] = {
+ REGULATOR_SUPPLY("vcc_core", NULL),
+};
+
+static struct regulator_init_data max8649_init_data = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 1150000,
+ .max_uV = 1280000,
+ .always_on = 1,
+ .boot_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max8649_supply[0],
+};
+
+static struct max8649_platform_data jasper_max8649_info = {
+ .mode = 2, /* VID1 = 1, VID0 = 0 */
+ .extclk = 0,
+ .ramp_timing = MAX8649_RAMP_32MV,
+ .regulator = &max8649_init_data,
+};
+
+static struct max8925_backlight_pdata jasper_backlight_data = {
+ .dual_string = 0,
+};
+
+static struct max8925_power_pdata jasper_power_data = {
+ .batt_detect = 0, /* can't detect battery by ID pin */
+ .topoff_threshold = MAX8925_TOPOFF_THR_10PER,
+ .fast_charge = MAX8925_FCHG_1000MA,
+};
+
+static struct max8925_platform_data jasper_max8925_info = {
+ .backlight = &jasper_backlight_data,
+ .power = &jasper_power_data,
+ .irq_base = IRQ_BOARD_START,
+};
+
+static struct i2c_board_info jasper_twsi1_info[] = {
+ [0] = {
+ .type = "max8649",
+ .addr = 0x60,
+ .platform_data = &jasper_max8649_info,
+ },
+ [1] = {
+ .type = "max8925",
+ .addr = 0x3c,
+ .irq = IRQ_MMP2_PMIC,
+ .platform_data = &jasper_max8925_info,
+ },
+};
+
+static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = {
+ .max_speed = 25000000,
+};
+
+static void __init jasper_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(jasper_pin_config));
+
+ /* on-chip devices */
+ mmp2_add_uart(1);
+ mmp2_add_uart(3);
+ mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(jasper_twsi1_info));
+ mmp2_add_sdhost(0, &mmp2_sdh_platdata_mmc0); /* SD/MMC */
+
+ regulator_has_full_constraints();
+}
+
+MACHINE_START(MARVELL_JASPER, "Jasper Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = JASPER_NR_IRQS,
+ .init_irq = mmp2_init_irq,
+ .timer = &mmp2_timer,
+ .init_machine = jasper_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c
new file mode 100644
index 00000000..8e6c3ac7
--- /dev/null
+++ b/arch/arm/mach-mmp/mmp2.c
@@ -0,0 +1,229 @@
+/*
+ * linux/arch/arm/mach-mmp/mmp2.c
+ *
+ * code name MMP2
+ *
+ * Copyright (C) 2009 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/hardware/cache-tauros2.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/gpio.h>
+#include <mach/devices.h>
+#include <mach/mmp2.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x9c)
+
+static struct mfp_addr_map mmp2_addr_map[] __initdata = {
+
+ MFP_ADDR_X(GPIO0, GPIO58, 0x54),
+ MFP_ADDR_X(GPIO59, GPIO73, 0x280),
+ MFP_ADDR_X(GPIO74, GPIO101, 0x170),
+
+ MFP_ADDR(GPIO102, 0x0),
+ MFP_ADDR(GPIO103, 0x4),
+ MFP_ADDR(GPIO104, 0x1fc),
+ MFP_ADDR(GPIO105, 0x1f8),
+ MFP_ADDR(GPIO106, 0x1f4),
+ MFP_ADDR(GPIO107, 0x1f0),
+ MFP_ADDR(GPIO108, 0x21c),
+ MFP_ADDR(GPIO109, 0x218),
+ MFP_ADDR(GPIO110, 0x214),
+ MFP_ADDR(GPIO111, 0x200),
+ MFP_ADDR(GPIO112, 0x244),
+ MFP_ADDR(GPIO113, 0x25c),
+ MFP_ADDR(GPIO114, 0x164),
+ MFP_ADDR_X(GPIO115, GPIO122, 0x260),
+
+ MFP_ADDR(GPIO123, 0x148),
+ MFP_ADDR_X(GPIO124, GPIO141, 0xc),
+
+ MFP_ADDR(GPIO142, 0x8),
+ MFP_ADDR_X(GPIO143, GPIO151, 0x220),
+ MFP_ADDR_X(GPIO152, GPIO153, 0x248),
+ MFP_ADDR_X(GPIO154, GPIO155, 0x254),
+ MFP_ADDR_X(GPIO156, GPIO159, 0x14c),
+
+ MFP_ADDR(GPIO160, 0x250),
+ MFP_ADDR(GPIO161, 0x210),
+ MFP_ADDR(GPIO162, 0x20c),
+ MFP_ADDR(GPIO163, 0x208),
+ MFP_ADDR(GPIO164, 0x204),
+ MFP_ADDR(GPIO165, 0x1ec),
+ MFP_ADDR(GPIO166, 0x1e8),
+ MFP_ADDR(GPIO167, 0x1e4),
+ MFP_ADDR(GPIO168, 0x1e0),
+
+ MFP_ADDR_X(TWSI1_SCL, TWSI1_SDA, 0x140),
+ MFP_ADDR_X(TWSI4_SCL, TWSI4_SDA, 0x2bc),
+
+ MFP_ADDR(PMIC_INT, 0x2c4),
+ MFP_ADDR(CLK_REQ, 0x160),
+
+ MFP_ADDR_END,
+};
+
+void mmp2_clear_pmic_int(void)
+{
+ unsigned long mfpr_pmic, data;
+
+ mfpr_pmic = APB_VIRT_BASE + 0x1e000 + 0x2c4;
+ data = __raw_readl(mfpr_pmic);
+ __raw_writel(data | (1 << 6), mfpr_pmic);
+ __raw_writel(data, mfpr_pmic);
+}
+
+static void __init mmp2_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_MMP2_GPIO);
+
+ /* unmask GPIO edge detection for all 6 banks -- APMASKx */
+ for (i = 0; i < 6; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_MMP2_GPIO, 0, 167, NULL);
+}
+
+void __init mmp2_init_irq(void)
+{
+ mmp2_init_icu();
+ mmp2_init_gpio();
+}
+
+static void sdhc_clk_enable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = __raw_readl(clk->clk_rst);
+ clk_rst |= clk->enable_val;
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+static void sdhc_clk_disable(struct clk *clk)
+{
+ uint32_t clk_rst;
+
+ clk_rst = __raw_readl(clk->clk_rst);
+ clk_rst &= ~clk->enable_val;
+ __raw_writel(clk_rst, clk->clk_rst);
+}
+
+struct clkops sdhc_clk_ops = {
+ .enable = sdhc_clk_enable,
+ .disable = sdhc_clk_disable,
+};
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, MMP2_UART1, 1, 26000000);
+static APBC_CLK(uart2, MMP2_UART2, 1, 26000000);
+static APBC_CLK(uart3, MMP2_UART3, 1, 26000000);
+static APBC_CLK(uart4, MMP2_UART4, 1, 26000000);
+static APBC_CLK(twsi1, MMP2_TWSI1, 0, 26000000);
+static APBC_CLK(twsi2, MMP2_TWSI2, 0, 26000000);
+static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000);
+static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000);
+static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000);
+static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000);
+
+static APMU_CLK(nand, NAND, 0xbf, 100000000);
+static APMU_CLK_OPS(sdh0, SDH0, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh1, SDH1, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh2, SDH2, 0x1b, 200000000, &sdhc_clk_ops);
+static APMU_CLK_OPS(sdh3, SDH3, 0x1b, 200000000, &sdhc_clk_ops);
+
+static struct clk_lookup mmp2_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_uart3, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_uart4, "pxa2xx-uart.3", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi2, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_twsi3, "pxa2xx-i2c.2", NULL),
+ INIT_CLKREG(&clk_twsi4, "pxa2xx-i2c.3", NULL),
+ INIT_CLKREG(&clk_twsi5, "pxa2xx-i2c.4", NULL),
+ INIT_CLKREG(&clk_twsi6, "pxa2xx-i2c.5", NULL),
+ INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_sdh0, "sdhci-pxa.0", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh1, "sdhci-pxa.1", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh2, "sdhci-pxa.2", "PXA-SDHCLK"),
+ INIT_CLKREG(&clk_sdh3, "sdhci-pxa.3", "PXA-SDHCLK"),
+};
+
+static int __init mmp2_init(void)
+{
+ if (cpu_is_mmp2()) {
+#ifdef CONFIG_CACHE_TAUROS2
+ tauros2_init();
+#endif
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(mmp2_addr_map);
+ pxa_init_dma(IRQ_MMP2_DMA_RIQ, 16);
+ clkdev_add_table(ARRAY_AND_SIZE(mmp2_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(mmp2_init);
+
+static void __init mmp2_timer_init(void)
+{
+ unsigned long clk_rst;
+
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_MMP2_TIMERS);
+
+ /*
+ * enable bus/functional clock, enable 6.5MHz (divider 4),
+ * release reset
+ */
+ clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
+ __raw_writel(clk_rst, APBC_MMP2_TIMERS);
+
+ timer_init(IRQ_MMP2_TIMER1);
+}
+
+struct sys_timer mmp2_timer = {
+ .init = mmp2_timer_init,
+};
+
+/* on-chip devices */
+MMP2_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4030000, 0x30, 4, 5);
+MMP2_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4017000, 0x30, 20, 21);
+MMP2_DEVICE(uart3, "pxa2xx-uart", 2, UART3, 0xd4018000, 0x30, 22, 23);
+MMP2_DEVICE(uart4, "pxa2xx-uart", 3, UART4, 0xd4016000, 0x30, 18, 19);
+MMP2_DEVICE(twsi1, "pxa2xx-i2c", 0, TWSI1, 0xd4011000, 0x70);
+MMP2_DEVICE(twsi2, "pxa2xx-i2c", 1, TWSI2, 0xd4031000, 0x70);
+MMP2_DEVICE(twsi3, "pxa2xx-i2c", 2, TWSI3, 0xd4032000, 0x70);
+MMP2_DEVICE(twsi4, "pxa2xx-i2c", 3, TWSI4, 0xd4033000, 0x70);
+MMP2_DEVICE(twsi5, "pxa2xx-i2c", 4, TWSI5, 0xd4033800, 0x70);
+MMP2_DEVICE(twsi6, "pxa2xx-i2c", 5, TWSI6, 0xd4034000, 0x70);
+MMP2_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x100, 28, 29);
+MMP2_DEVICE(sdh0, "sdhci-pxa", 0, MMC, 0xd4280000, 0x120);
+MMP2_DEVICE(sdh1, "sdhci-pxa", 1, MMC2, 0xd4280800, 0x120);
+MMP2_DEVICE(sdh2, "sdhci-pxa", 2, MMC3, 0xd4281000, 0x120);
+MMP2_DEVICE(sdh3, "sdhci-pxa", 3, MMC4, 0xd4281800, 0x120);
+
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
new file mode 100644
index 00000000..ab9f9991
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -0,0 +1,165 @@
+/*
+ * linux/arch/arm/mach-mmp/pxa168.c
+ *
+ * Code specific to PXA168
+ *
+ * This program is free software; you can 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/list.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/cputype.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/devices.h>
+#include <mach/mfp.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa168_mfp_addr_map[] __initdata =
+{
+ MFP_ADDR_X(GPIO0, GPIO36, 0x04c),
+ MFP_ADDR_X(GPIO37, GPIO55, 0x000),
+ MFP_ADDR_X(GPIO56, GPIO123, 0x0e0),
+ MFP_ADDR_X(GPIO124, GPIO127, 0x0f4),
+
+ MFP_ADDR_END,
+};
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa168_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA168_GPIO);
+
+ /* unmask GPIO edge detection for all 4 banks - APMASKx */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_PXA168_GPIOX, 0, 127, NULL);
+}
+
+void __init pxa168_init_irq(void)
+{
+ icu_init_irq();
+ pxa168_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA168_UART1, 1, 14745600);
+static APBC_CLK(uart2, PXA168_UART2, 1, 14745600);
+static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PXA168_PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PXA168_PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PXA168_PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PXA168_PWM4, 1, 13000000);
+static APBC_CLK(ssp1, PXA168_SSP1, 4, 0);
+static APBC_CLK(ssp2, PXA168_SSP2, 4, 0);
+static APBC_CLK(ssp3, PXA168_SSP3, 4, 0);
+static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
+static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
+static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
+
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
+static APMU_CLK(lcd, LCD, 0x7f, 312000000);
+
+/* device and clock bindings */
+static struct clk_lookup pxa168_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_pwm1, "pxa168-pwm.0", NULL),
+ INIT_CLKREG(&clk_pwm2, "pxa168-pwm.1", NULL),
+ INIT_CLKREG(&clk_pwm3, "pxa168-pwm.2", NULL),
+ INIT_CLKREG(&clk_pwm4, "pxa168-pwm.3", NULL),
+ INIT_CLKREG(&clk_ssp1, "pxa168-ssp.0", NULL),
+ INIT_CLKREG(&clk_ssp2, "pxa168-ssp.1", NULL),
+ INIT_CLKREG(&clk_ssp3, "pxa168-ssp.2", NULL),
+ INIT_CLKREG(&clk_ssp4, "pxa168-ssp.3", NULL),
+ INIT_CLKREG(&clk_ssp5, "pxa168-ssp.4", NULL),
+ INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_lcd, "pxa168-fb", NULL),
+ INIT_CLKREG(&clk_keypad, "pxa27x-keypad", NULL),
+};
+
+static int __init pxa168_init(void)
+{
+ if (cpu_is_pxa168()) {
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(pxa168_mfp_addr_map);
+ pxa_init_dma(IRQ_PXA168_DMA_INT0, 32);
+ clkdev_add_table(ARRAY_AND_SIZE(pxa168_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(pxa168_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa168_timer_init(void)
+{
+ /* this is early, we have to initialize the CCU registers by
+ * ourselves instead of using clk_* API. Clock rate is defined
+ * by APBC_TIMERS_CLK_RST (3.25MHz) and enabled free-running
+ */
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA168_TIMERS);
+
+ /* 3.25MHz, bus/functional clock enabled, release reset */
+ __raw_writel(TIMER_CLK_RST, APBC_PXA168_TIMERS);
+
+ timer_init(IRQ_PXA168_TIMER1);
+}
+
+struct sys_timer pxa168_timer = {
+ .init = pxa168_timer_init,
+};
+
+void pxa168_clear_keypad_wakeup(void)
+{
+ uint32_t val;
+ uint32_t mask = APMU_PXA168_KP_WAKE_CLR;
+
+ /* wake event clear is needed in order to clear keypad interrupt */
+ val = __raw_readl(APMU_WAKE_CLR);
+ __raw_writel(val | mask, APMU_WAKE_CLR);
+}
+
+/* on-chip devices */
+PXA168_DEVICE(uart1, "pxa2xx-uart", 0, UART1, 0xd4017000, 0x30, 21, 22);
+PXA168_DEVICE(uart2, "pxa2xx-uart", 1, UART2, 0xd4018000, 0x30, 23, 24);
+PXA168_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
+PXA168_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
+PXA168_DEVICE(pwm1, "pxa168-pwm", 0, NONE, 0xd401a000, 0x10);
+PXA168_DEVICE(pwm2, "pxa168-pwm", 1, NONE, 0xd401a400, 0x10);
+PXA168_DEVICE(pwm3, "pxa168-pwm", 2, NONE, 0xd401a800, 0x10);
+PXA168_DEVICE(pwm4, "pxa168-pwm", 3, NONE, 0xd401ac00, 0x10);
+PXA168_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
+PXA168_DEVICE(ssp1, "pxa168-ssp", 0, SSP1, 0xd401b000, 0x40, 52, 53);
+PXA168_DEVICE(ssp2, "pxa168-ssp", 1, SSP2, 0xd401c000, 0x40, 54, 55);
+PXA168_DEVICE(ssp3, "pxa168-ssp", 2, SSP3, 0xd401f000, 0x40, 56, 57);
+PXA168_DEVICE(ssp4, "pxa168-ssp", 3, SSP4, 0xd4020000, 0x40, 58, 59);
+PXA168_DEVICE(ssp5, "pxa168-ssp", 4, SSP5, 0xd4021000, 0x40, 60, 61);
+PXA168_DEVICE(fb, "pxa168-fb", -1, LCD, 0xd420b000, 0x1c8);
+PXA168_DEVICE(keypad, "pxa27x-keypad", -1, KEYPAD, 0xd4012000, 0x4c);
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
new file mode 100644
index 00000000..1464607a
--- /dev/null
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -0,0 +1,182 @@
+/*
+ * linux/arch/arm/mach-mmp/pxa910.c
+ *
+ * Code specific to PXA910
+ *
+ * This program is free software; you can 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/list.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <mach/addr-map.h>
+#include <mach/regs-apbc.h>
+#include <mach/regs-apmu.h>
+#include <mach/cputype.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/dma.h>
+#include <mach/mfp.h>
+#include <mach/devices.h>
+
+#include "common.h"
+#include "clock.h"
+
+#define MFPR_VIRT_BASE (APB_VIRT_BASE + 0x1e000)
+
+static struct mfp_addr_map pxa910_mfp_addr_map[] __initdata =
+{
+ MFP_ADDR_X(GPIO0, GPIO54, 0xdc),
+ MFP_ADDR_X(GPIO67, GPIO98, 0x1b8),
+ MFP_ADDR_X(GPIO100, GPIO109, 0x238),
+
+ MFP_ADDR(GPIO123, 0xcc),
+ MFP_ADDR(GPIO124, 0xd0),
+
+ MFP_ADDR(DF_IO0, 0x40),
+ MFP_ADDR(DF_IO1, 0x3c),
+ MFP_ADDR(DF_IO2, 0x38),
+ MFP_ADDR(DF_IO3, 0x34),
+ MFP_ADDR(DF_IO4, 0x30),
+ MFP_ADDR(DF_IO5, 0x2c),
+ MFP_ADDR(DF_IO6, 0x28),
+ MFP_ADDR(DF_IO7, 0x24),
+ MFP_ADDR(DF_IO8, 0x20),
+ MFP_ADDR(DF_IO9, 0x1c),
+ MFP_ADDR(DF_IO10, 0x18),
+ MFP_ADDR(DF_IO11, 0x14),
+ MFP_ADDR(DF_IO12, 0x10),
+ MFP_ADDR(DF_IO13, 0xc),
+ MFP_ADDR(DF_IO14, 0x8),
+ MFP_ADDR(DF_IO15, 0x4),
+
+ MFP_ADDR(DF_nCS0_SM_nCS2, 0x44),
+ MFP_ADDR(DF_nCS1_SM_nCS3, 0x48),
+ MFP_ADDR(SM_nCS0, 0x4c),
+ MFP_ADDR(SM_nCS1, 0x50),
+ MFP_ADDR(DF_WEn, 0x54),
+ MFP_ADDR(DF_REn, 0x58),
+ MFP_ADDR(DF_CLE_SM_OEn, 0x5c),
+ MFP_ADDR(DF_ALE_SM_WEn, 0x60),
+ MFP_ADDR(SM_SCLK, 0x64),
+ MFP_ADDR(DF_RDY0, 0x68),
+ MFP_ADDR(SM_BE0, 0x6c),
+ MFP_ADDR(SM_BE1, 0x70),
+ MFP_ADDR(SM_ADV, 0x74),
+ MFP_ADDR(DF_RDY1, 0x78),
+ MFP_ADDR(SM_ADVMUX, 0x7c),
+ MFP_ADDR(SM_RDY, 0x80),
+
+ MFP_ADDR_X(MMC1_DAT7, MMC1_WP, 0x84),
+
+ MFP_ADDR_END,
+};
+
+#define APMASK(i) (GPIO_REGS_VIRT + BANK_OFF(i) + 0x09c)
+
+static void __init pxa910_init_gpio(void)
+{
+ int i;
+
+ /* enable GPIO clock */
+ __raw_writel(APBC_APBCLK | APBC_FNCLK, APBC_PXA910_GPIO);
+
+ /* unmask GPIO edge detection for all 4 banks - APMASKx */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xffffffff, APMASK(i));
+
+ pxa_init_gpio(IRQ_PXA910_AP_GPIO, 0, 127, NULL);
+}
+
+void __init pxa910_init_irq(void)
+{
+ icu_init_irq();
+ pxa910_init_gpio();
+}
+
+/* APB peripheral clocks */
+static APBC_CLK(uart1, PXA910_UART0, 1, 14745600);
+static APBC_CLK(uart2, PXA910_UART1, 1, 14745600);
+static APBC_CLK(twsi0, PXA168_TWSI0, 1, 33000000);
+static APBC_CLK(twsi1, PXA168_TWSI1, 1, 33000000);
+static APBC_CLK(pwm1, PXA910_PWM1, 1, 13000000);
+static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
+static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
+static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
+
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
+static APMU_CLK(u2o, USB, 0x1b, 480000000);
+
+/* device and clock bindings */
+static struct clk_lookup pxa910_clkregs[] = {
+ INIT_CLKREG(&clk_uart1, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_uart2, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_twsi0, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_twsi1, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_pwm1, "pxa910-pwm.0", NULL),
+ INIT_CLKREG(&clk_pwm2, "pxa910-pwm.1", NULL),
+ INIT_CLKREG(&clk_pwm3, "pxa910-pwm.2", NULL),
+ INIT_CLKREG(&clk_pwm4, "pxa910-pwm.3", NULL),
+ INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
+};
+
+static int __init pxa910_init(void)
+{
+ if (cpu_is_pxa910()) {
+ mfp_init_base(MFPR_VIRT_BASE);
+ mfp_init_addr(pxa910_mfp_addr_map);
+ pxa_init_dma(IRQ_PXA910_DMA_INT0, 32);
+ clkdev_add_table(ARRAY_AND_SIZE(pxa910_clkregs));
+ }
+
+ return 0;
+}
+postcore_initcall(pxa910_init);
+
+/* system timer - clock enabled, 3.25MHz */
+#define TIMER_CLK_RST (APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(3))
+
+static void __init pxa910_timer_init(void)
+{
+ /* reset and configure */
+ __raw_writel(APBC_APBCLK | APBC_RST, APBC_PXA910_TIMERS);
+ __raw_writel(TIMER_CLK_RST, APBC_PXA910_TIMERS);
+
+ timer_init(IRQ_PXA910_AP1_TIMER1);
+}
+
+struct sys_timer pxa910_timer = {
+ .init = pxa910_timer_init,
+};
+
+/* on-chip devices */
+
+/* NOTE: there are totally 3 UARTs on PXA910:
+ *
+ * UART1 - Slow UART (can be used both by AP and CP)
+ * UART2/3 - Fast UART
+ *
+ * To be backward compatible with the legacy FFUART/BTUART/STUART sequence,
+ * they are re-ordered as:
+ *
+ * pxa910_device_uart1 - UART2 as FFUART
+ * pxa910_device_uart2 - UART3 as BTUART
+ *
+ * UART1 is not used by AP for the moment.
+ */
+PXA910_DEVICE(uart1, "pxa2xx-uart", 0, UART2, 0xd4017000, 0x30, 21, 22);
+PXA910_DEVICE(uart2, "pxa2xx-uart", 1, UART3, 0xd4018000, 0x30, 23, 24);
+PXA910_DEVICE(twsi0, "pxa2xx-i2c", 0, TWSI0, 0xd4011000, 0x28);
+PXA910_DEVICE(twsi1, "pxa2xx-i2c", 1, TWSI1, 0xd4025000, 0x28);
+PXA910_DEVICE(pwm1, "pxa910-pwm", 0, NONE, 0xd401a000, 0x10);
+PXA910_DEVICE(pwm2, "pxa910-pwm", 1, NONE, 0xd401a400, 0x10);
+PXA910_DEVICE(pwm3, "pxa910-pwm", 2, NONE, 0xd401a800, 0x10);
+PXA910_DEVICE(pwm4, "pxa910-pwm", 3, NONE, 0xd401ac00, 0x10);
+PXA910_DEVICE(nand, "pxa3xx-nand", -1, NAND, 0xd4283000, 0x80, 97, 99);
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
new file mode 100644
index 00000000..c296b75c
--- /dev/null
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -0,0 +1,106 @@
+/*
+ * linux/arch/arm/mach-mmp/tavorevb.c
+ *
+ * Support for the Marvell PXA910-based TavorEVB Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa910.h>
+#include <mach/pxa910.h>
+#include <mach/gpio.h>
+
+#include "common.h"
+
+static unsigned long tavorevb_pin_config[] __initdata = {
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+
+ /* SMC */
+ SM_nCS0_nCS0,
+ SM_ADV_SM_ADV,
+ SM_SCLK_SM_SCLK,
+ SM_SCLK_SM_SCLK,
+ SM_BE0_SM_BE0,
+ SM_BE1_SM_BE1,
+
+ /* DFI */
+ DF_IO0_ND_IO0,
+ DF_IO1_ND_IO1,
+ DF_IO2_ND_IO2,
+ DF_IO3_ND_IO3,
+ DF_IO4_ND_IO4,
+ DF_IO5_ND_IO5,
+ DF_IO6_ND_IO6,
+ DF_IO7_ND_IO7,
+ DF_IO8_ND_IO8,
+ DF_IO9_ND_IO9,
+ DF_IO10_ND_IO10,
+ DF_IO11_ND_IO11,
+ DF_IO12_ND_IO12,
+ DF_IO13_ND_IO13,
+ DF_IO14_ND_IO14,
+ DF_IO15_ND_IO15,
+ DF_nCS0_SM_nCS2_nCS0,
+ DF_ALE_SM_WEn_ND_ALE,
+ DF_CLE_SM_OEn_ND_CLE,
+ DF_WEn_DF_WEn,
+ DF_REn_DF_REn,
+ DF_RDY0_DF_RDY0,
+};
+
+static struct smc91x_platdata tavorevb_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = SMC_CS1_PHYS_BASE + 0x300,
+ .end = SMC_CS1_PHYS_BASE + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(80),
+ .end = gpio_to_irq(80),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &tavorevb_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init tavorevb_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(tavorevb_pin_config));
+
+ /* on-chip devices */
+ pxa910_add_uart(1);
+
+ /* off-chip devices */
+ platform_device_register(&smc91x_device);
+}
+
+MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
+ .map_io = mmp_map_io,
+ .init_irq = pxa910_init_irq,
+ .timer = &pxa910_timer,
+ .init_machine = tavorevb_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c
new file mode 100644
index 00000000..bbe4727b
--- /dev/null
+++ b/arch/arm/mach-mmp/teton_bga.c
@@ -0,0 +1,89 @@
+/*
+ * linux/arch/arm/mach-mmp/teton_bga.c
+ *
+ * Support for the Marvell PXA168 Teton BGA Development Platform.
+ *
+ * Author: Mark F. Brown <mark.brown314@gmail.com>
+ *
+ * This code is based on aspenite.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <plat/pxa27x_keypad.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa168.h>
+#include <mach/pxa168.h>
+#include <mach/teton_bga.h>
+
+#include "common.h"
+
+static unsigned long teton_bga_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO107_UART1_TXD,
+ GPIO108_UART1_RXD,
+
+ /* Keypad */
+ GPIO109_KP_MKIN1,
+ GPIO110_KP_MKIN0,
+ GPIO111_KP_MKOUT7,
+ GPIO112_KP_MKOUT6,
+
+ /* I2C Bus */
+ GPIO105_CI2C_SDA,
+ GPIO106_CI2C_SCL,
+
+ /* RTC */
+ GPIO78_GPIO,
+};
+
+static unsigned int teton_bga_matrix_key_map[] = {
+ KEY(0, 6, KEY_ESC),
+ KEY(0, 7, KEY_ENTER),
+ KEY(1, 6, KEY_LEFT),
+ KEY(1, 7, KEY_RIGHT),
+};
+
+static struct pxa27x_keypad_platform_data teton_bga_keypad_info __initdata = {
+ .matrix_key_rows = 2,
+ .matrix_key_cols = 8,
+ .matrix_key_map = teton_bga_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(teton_bga_matrix_key_map),
+ .debounce_interval = 30,
+};
+
+static struct i2c_board_info teton_bga_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68),
+ .irq = gpio_to_irq(RTC_INT_GPIO)
+ },
+};
+
+static void __init teton_bga_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(teton_bga_pin_config));
+
+ /* on-chip devices */
+ pxa168_add_uart(1);
+ pxa168_add_keypad(&teton_bga_keypad_info);
+ pxa168_add_twsi(0, NULL, ARRAY_AND_SIZE(teton_bga_i2c_info));
+}
+
+MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = IRQ_BOARD_START,
+ .init_irq = pxa168_init_irq,
+ .timer = &pxa168_timer,
+ .init_machine = teton_bga_init,
+MACHINE_END
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
new file mode 100644
index 00000000..99833b94
--- /dev/null
+++ b/arch/arm/mach-mmp/time.c
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-mmp/time.c
+ *
+ * Support for clocksource and clockevents
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ * All rights reserved.
+ *
+ * 2008-04-11: Jason Chagas <Jason.chagas@marvell.com>
+ * 2008-10-08: Bin Yang <bin.yang@marvell.com>
+ *
+ * The timers module actually includes three timers, each timer with up to
+ * three match comparators. Timer #0 is used here in free-running mode as
+ * the clock source, and match comparator #1 used as clock event 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/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+
+#include <asm/sched_clock.h>
+#include <mach/addr-map.h>
+#include <mach/regs-timers.h>
+#include <mach/regs-apbc.h>
+#include <mach/irqs.h>
+#include <mach/cputype.h>
+#include <asm/mach/time.h>
+
+#include "clock.h"
+
+#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
+
+#define MAX_DELTA (0xfffffffe)
+#define MIN_DELTA (16)
+
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * FIXME: the timer needs some delay to stablize the counter capture
+ */
+static inline uint32_t timer_read(void)
+{
+ int delay = 100;
+
+ __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0));
+
+ while (delay--)
+ cpu_relax();
+
+ return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0));
+}
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = timer_read();
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mmp_update_sched_clock(void)
+{
+ u32 cyc = timer_read();
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* disable and clear pending interrupt status */
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+ __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0));
+ c->event_handler(c);
+ return IRQ_HANDLED;
+}
+
+static int timer_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ unsigned long flags, next;
+
+ local_irq_save(flags);
+
+ /* clear pending interrupt status and enable */
+ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
+ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0));
+
+ next = timer_read() + delta;
+ __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0));
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static void timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* disable the matching interrupt */
+ __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0));
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+ local_irq_restore(flags);
+}
+
+static struct clock_event_device ckevt = {
+ .name = "clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 200,
+ .set_next_event = timer_set_next_event,
+ .set_mode = timer_set_mode,
+};
+
+static cycle_t clksrc_read(struct clocksource *cs)
+{
+ return timer_read();
+}
+
+static struct clocksource cksrc = {
+ .name = "clocksource",
+ .rating = 200,
+ .read = clksrc_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init timer_config(void)
+{
+ uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR);
+ uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER);
+ uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR);
+
+ __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
+
+ ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3);
+ __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
+
+ /* free-running mode */
+ __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR);
+
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */
+ __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */
+ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
+
+ /* enable timer counter */
+ __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER);
+}
+
+static struct irqaction timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = timer_interrupt,
+ .dev_id = &ckevt,
+};
+
+void __init timer_init(int irq)
+{
+ timer_config();
+
+ init_sched_clock(&cd, mmp_update_sched_clock, 32, CLOCK_TICK_RATE);
+
+ ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift);
+ ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt);
+ ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt);
+ ckevt.cpumask = cpumask_of(0);
+
+ setup_irq(irq, &timer_irq);
+
+ clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
+ clockevents_register_device(&ckevt);
+}
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
new file mode 100644
index 00000000..e411039e
--- /dev/null
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -0,0 +1,133 @@
+/*
+ * linux/arch/arm/mach-mmp/ttc_dkb.c
+ *
+ * Support for the Marvell PXA910-based TTC_DKB Development Platform.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <mach/addr-map.h>
+#include <mach/mfp-pxa910.h>
+#include <mach/pxa910.h>
+
+#include "common.h"
+
+#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 24)
+
+static unsigned long ttc_dkb_pin_config[] __initdata = {
+ /* UART2 */
+ GPIO47_UART2_RXD,
+ GPIO48_UART2_TXD,
+
+ /* DFI */
+ DF_IO0_ND_IO0,
+ DF_IO1_ND_IO1,
+ DF_IO2_ND_IO2,
+ DF_IO3_ND_IO3,
+ DF_IO4_ND_IO4,
+ DF_IO5_ND_IO5,
+ DF_IO6_ND_IO6,
+ DF_IO7_ND_IO7,
+ DF_IO8_ND_IO8,
+ DF_IO9_ND_IO9,
+ DF_IO10_ND_IO10,
+ DF_IO11_ND_IO11,
+ DF_IO12_ND_IO12,
+ DF_IO13_ND_IO13,
+ DF_IO14_ND_IO14,
+ DF_IO15_ND_IO15,
+ DF_nCS0_SM_nCS2_nCS0,
+ DF_ALE_SM_WEn_ND_ALE,
+ DF_CLE_SM_OEn_ND_CLE,
+ DF_WEn_DF_WEn,
+ DF_REn_DF_REn,
+ DF_RDY0_DF_RDY0,
+};
+
+static struct mtd_partition ttc_dkb_onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_8M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (SZ_2M + SZ_1M),
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_48M,
+ .mask_flags = 0,
+ }
+};
+
+static struct onenand_platform_data ttc_dkb_onenand_info = {
+ .parts = ttc_dkb_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(ttc_dkb_onenand_partitions),
+};
+
+static struct resource ttc_dkb_resource_onenand[] = {
+ [0] = {
+ .start = SMC_CS0_PHYS_BASE,
+ .end = SMC_CS0_PHYS_BASE + SZ_1M,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ttc_dkb_device_onenand = {
+ .name = "onenand-flash",
+ .id = -1,
+ .resource = ttc_dkb_resource_onenand,
+ .num_resources = ARRAY_SIZE(ttc_dkb_resource_onenand),
+ .dev = {
+ .platform_data = &ttc_dkb_onenand_info,
+ },
+};
+
+static struct platform_device *ttc_dkb_devices[] = {
+ &ttc_dkb_device_onenand,
+};
+
+static void __init ttc_dkb_init(void)
+{
+ mfp_config(ARRAY_AND_SIZE(ttc_dkb_pin_config));
+
+ /* on-chip devices */
+ pxa910_add_uart(1);
+
+ /* off-chip devices */
+ platform_add_devices(ARRAY_AND_SIZE(ttc_dkb_devices));
+}
+
+MACHINE_START(TTC_DKB, "PXA910-based TTC_DKB Development Platform")
+ .map_io = mmp_map_io,
+ .nr_irqs = TTCDKB_NR_IRQS,
+ .init_irq = pxa910_init_irq,
+ .timer = &pxa910_timer,
+ .init_machine = ttc_dkb_init,
+MACHINE_END
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
new file mode 100644
index 00000000..1516896e
--- /dev/null
+++ b/arch/arm/mach-msm/Kconfig
@@ -0,0 +1,213 @@
+if ARCH_MSM
+
+choice
+ prompt "Qualcomm MSM SoC Type"
+ default ARCH_MSM7X00A
+
+config ARCH_MSM7X00A
+ bool "MSM7x00A / MSM7x01A"
+ select MACH_TROUT if !MACH_HALIBUT
+ select ARCH_MSM_ARM11
+ select MSM_SMD
+ select MSM_SMD_PKG3
+ select CPU_V6
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
+
+config ARCH_MSM7X30
+ bool "MSM7x30"
+ select MACH_MSM7X30_SURF # if !
+ select ARCH_MSM_SCORPION
+ select MSM_SMD
+ select MSM_VIC
+ select CPU_V7
+ select MSM_GPIOMUX
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
+
+config ARCH_QSD8X50
+ bool "QSD8X50"
+ select MACH_QSD8X50_SURF if !MACH_QSD8X50A_ST1_5
+ select ARCH_MSM_SCORPION
+ select MSM_SMD
+ select MSM_VIC
+ select CPU_V7
+ select MSM_GPIOMUX
+ select MSM_PROC_COMM
+ select HAS_MSM_DEBUG_UART_PHYS
+
+config ARCH_MSM8X60
+ bool "MSM8X60"
+ select MACH_MSM8X60_SURF if (!MACH_MSM8X60_RUMI3 && !MACH_MSM8X60_SIM \
+ && !MACH_MSM8X60_FFA)
+ select ARCH_MSM_SCORPIONMP
+ select ARM_GIC
+ select CPU_V7
+ select MSM_V2_TLMM
+ select MSM_GPIOMUX
+ select MSM_SCM if SMP
+
+config ARCH_MSM8960
+ bool "MSM8960"
+ select ARCH_MSM_SCORPIONMP
+ select MACH_MSM8960_SIM if (!MACH_MSM8960_RUMI3)
+ select ARM_GIC
+ select CPU_V7
+ select MSM_V2_TLMM
+ select MSM_GPIOMUX
+ select MSM_SCM if SMP
+
+endchoice
+
+config MSM_SOC_REV_A
+ bool
+config ARCH_MSM_SCORPIONMP
+ bool
+
+config ARCH_MSM_ARM11
+ bool
+config ARCH_MSM_SCORPION
+ bool
+
+config HAS_MSM_DEBUG_UART_PHYS
+ bool
+
+config MSM_VIC
+ bool
+
+menu "Qualcomm MSM Board Type"
+
+config MACH_HALIBUT
+ depends on ARCH_MSM
+ depends on ARCH_MSM7X00A
+ bool "Halibut Board (QCT SURF7201A)"
+ help
+ Support for the Qualcomm SURF7201A eval board.
+
+config MACH_TROUT
+ depends on ARCH_MSM
+ depends on ARCH_MSM7X00A
+ bool "HTC Dream (aka trout)"
+ help
+ Support for the HTC Dream, T-Mobile G1, Android ADP1 devices.
+
+config MACH_MSM7X30_SURF
+ depends on ARCH_MSM7X30
+ bool "MSM7x30 SURF"
+ help
+ Support for the Qualcomm MSM7x30 SURF eval board.
+
+config MACH_QSD8X50_SURF
+ depends on ARCH_QSD8X50
+ bool "QSD8x50 SURF"
+ help
+ Support for the Qualcomm QSD8x50 SURF eval board.
+
+config MACH_QSD8X50A_ST1_5
+ depends on ARCH_QSD8X50
+ select MSM_SOC_REV_A
+ bool "QSD8x50A ST1.5"
+ help
+ Support for the Qualcomm ST1.5.
+
+config MACH_MSM8X60_RUMI3
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 RUMI3"
+ help
+ Support for the Qualcomm MSM8x60 RUMI3 emulator.
+
+config MACH_MSM8X60_SURF
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 SURF"
+ help
+ Support for the Qualcomm MSM8x60 SURF eval board.
+
+config MACH_MSM8X60_SIM
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 Simulator"
+ help
+ Support for the Qualcomm MSM8x60 simulator.
+
+config MACH_MSM8X60_FFA
+ depends on ARCH_MSM8X60
+ bool "MSM8x60 FFA"
+ help
+ Support for the Qualcomm MSM8x60 FFA eval board.
+
+config MACH_MSM8960_SIM
+ depends on ARCH_MSM8960
+ bool "MSM8960 Simulator"
+ help
+ Support for the Qualcomm MSM8960 simulator.
+
+config MACH_MSM8960_RUMI3
+ depends on ARCH_MSM8960
+ bool "MSM8960 RUMI3"
+ help
+ Support for the Qualcomm MSM8960 RUMI3 emulator.
+
+endmenu
+
+config MSM_IOMMU
+ bool "MSM IOMMU Support"
+ depends on ARCH_MSM8X60 || ARCH_MSM8960
+ select IOMMU_API
+ default n
+ help
+ Support for the IOMMUs found on certain Qualcomm SOCs.
+ These IOMMUs allow virtualization of the address space used by most
+ cores within the multimedia subsystem.
+
+ If unsure, say N here.
+
+config IOMMU_PGTABLES_L2
+ def_bool y
+ depends on MSM_IOMMU && MMU && SMP && CPU_DCACHE_DISABLE=n
+
+config MSM_DEBUG_UART
+ int
+ default 1 if MSM_DEBUG_UART1
+ default 2 if MSM_DEBUG_UART2
+ default 3 if MSM_DEBUG_UART3
+
+if HAS_MSM_DEBUG_UART_PHYS
+choice
+ prompt "Debug UART"
+
+ default MSM_DEBUG_UART_NONE
+
+ config MSM_DEBUG_UART_NONE
+ bool "None"
+
+ config MSM_DEBUG_UART1
+ bool "UART1"
+
+ config MSM_DEBUG_UART2
+ bool "UART2"
+
+ config MSM_DEBUG_UART3
+ bool "UART3"
+endchoice
+endif
+
+config MSM_SMD_PKG3
+ bool
+
+config MSM_PROC_COMM
+ bool
+
+config MSM_SMD
+ bool
+
+config MSM_GPIOMUX
+ bool
+
+config MSM_V2_TLMM
+ bool
+
+config IOMMU_API
+ bool
+
+config MSM_SCM
+ bool
+endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
new file mode 100644
index 00000000..9519fd28
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile
@@ -0,0 +1,39 @@
+obj-y += io.o idle.o timer.o
+obj-y += clock.o
+obj-$(CONFIG_DEBUG_FS) += clock-debug.o
+
+obj-$(CONFIG_MSM_VIC) += irq-vic.o
+obj-$(CONFIG_MSM_IOMMU) += iommu.o iommu_dev.o devices-iommu.o
+
+obj-$(CONFIG_ARCH_MSM7X00A) += dma.o irq.o acpuclock-arm11.o
+obj-$(CONFIG_ARCH_MSM7X30) += dma.o
+obj-$(CONFIG_ARCH_QSD8X50) += dma.o sirc.o
+
+obj-$(CONFIG_MSM_PROC_COMM) += proc_comm.o clock-pcom.o vreg.o
+
+obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
+obj-$(CONFIG_MSM_SMD) += last_radio_log.o
+obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o
+
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+
+obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
+obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o
+obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
+obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
+obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
+obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o
+obj-$(CONFIG_ARCH_MSM8960) += board-msm8960.o devices-msm8960.o
+
+obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o
+obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o
+ifdef CONFIG_MSM_V2_TLMM
+ifndef CONFIG_ARCH_MSM8960
+# TODO: TLMM Mapping issues need to be resolved
+obj-y += gpio-v2.o
+endif
+else
+obj-y += gpio.o
+endif
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
new file mode 100644
index 00000000..24dfbf8c
--- /dev/null
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x10008000
+params_phys-y := 0x10000100
+initrd_phys-y := 0x10800000
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
new file mode 100644
index 00000000..805d4ee5
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock-arm11.c
@@ -0,0 +1,525 @@
+/* arch/arm/mach-msm/acpuclock.c
+ *
+ * MSM architecture clock driver
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include "proc_comm.h"
+#include "acpuclock.h"
+
+
+#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
+#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
+#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
+
+/*
+ * ARM11 clock configuration for specific ACPU speeds
+ */
+
+#define ACPU_PLL_TCXO -1
+#define ACPU_PLL_0 0
+#define ACPU_PLL_1 1
+#define ACPU_PLL_2 2
+#define ACPU_PLL_3 3
+
+#define PERF_SWITCH_DEBUG 0
+#define PERF_SWITCH_STEP_DEBUG 0
+
+struct clock_state
+{
+ struct clkctl_acpu_speed *current_speed;
+ struct mutex lock;
+ uint32_t acpu_switch_time_us;
+ uint32_t max_speed_delta_khz;
+ uint32_t vdd_switch_time_us;
+ unsigned long power_collapse_khz;
+ unsigned long wait_for_irq_khz;
+};
+
+static struct clk *ebi1_clk;
+static struct clock_state drv_state = { 0 };
+
+static void __init acpuclk_init(void);
+
+/* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */
+enum {
+ VDD_0 = 0,
+ VDD_1 = 1,
+ VDD_2 = 2,
+ VDD_3 = 3,
+ VDD_4 = 3,
+ VDD_5 = 3,
+ VDD_6 = 3,
+ VDD_7 = 7,
+ VDD_END
+};
+
+struct clkctl_acpu_speed {
+ unsigned int a11clk_khz;
+ int pll;
+ unsigned int a11clk_src_sel;
+ unsigned int a11clk_src_div;
+ unsigned int ahbclk_khz;
+ unsigned int ahbclk_div;
+ int vdd;
+ unsigned int axiclk_khz;
+ unsigned long lpj; /* loops_per_jiffy */
+/* Index in acpu_freq_tbl[] for steppings. */
+ short down;
+ short up;
+};
+
+/*
+ * ACPU speed table. Complete table is shown but certain speeds are commented
+ * out to optimized speed switching. Initialize loops_per_jiffy to 0.
+ *
+ * Table stepping up/down is optimized for 256mhz jumps while staying on the
+ * same PLL.
+ */
+#if (0)
+static struct clkctl_acpu_speed acpu_freq_tbl[] = {
+ { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 },
+ { 61440, ACPU_PLL_0, 4, 3, 61440, 0, VDD_0, 30720, 0, 0, 8 },
+ { 81920, ACPU_PLL_0, 4, 2, 40960, 1, VDD_0, 61440, 0, 0, 8 },
+ { 96000, ACPU_PLL_1, 1, 7, 48000, 1, VDD_0, 61440, 0, 0, 9 },
+ { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 8 },
+ { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 12 },
+ { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 11 },
+ { 192000, ACPU_PLL_1, 1, 3, 64000, 2, VDD_3, 61440, 0, 0, 12 },
+ { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 12 },
+ { 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 },
+ { 264000, ACPU_PLL_2, 2, 3, 88000, 2, VDD_5, 128000, 0, 6, 13 },
+ { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 6, 13 },
+ { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 },
+ { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#else /* Table of freq we currently use. */
+static struct clkctl_acpu_speed acpu_freq_tbl[] = {
+ { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 },
+ { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 },
+ { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 },
+ { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 },
+ { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 },
+ { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 },
+ { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 },
+ { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+#endif
+
+
+#ifdef CONFIG_CPU_FREQ_TABLE
+static struct cpufreq_frequency_table freq_table[] = {
+ { 0, 122880 },
+ { 1, 128000 },
+ { 2, 245760 },
+ { 3, 384000 },
+ { 4, 528000 },
+ { 5, CPUFREQ_TABLE_END },
+};
+#endif
+
+static int pc_pll_request(unsigned id, unsigned on)
+{
+ int res;
+ on = !!on;
+
+#if PERF_SWITCH_DEBUG
+ if (on)
+ printk(KERN_DEBUG "Enabling PLL %d\n", id);
+ else
+ printk(KERN_DEBUG "Disabling PLL %d\n", id);
+#endif
+
+ res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
+ if (res < 0)
+ return res;
+
+#if PERF_SWITCH_DEBUG
+ if (on)
+ printk(KERN_DEBUG "PLL %d enabled\n", id);
+ else
+ printk(KERN_DEBUG "PLL %d disabled\n", id);
+#endif
+ return res;
+}
+
+
+/*----------------------------------------------------------------------------
+ * ARM11 'owned' clock control
+ *---------------------------------------------------------------------------*/
+
+unsigned long acpuclk_power_collapse(void) {
+ int ret = acpuclk_get_rate();
+ ret *= 1000;
+ if (ret > drv_state.power_collapse_khz)
+ acpuclk_set_rate(drv_state.power_collapse_khz, 1);
+ return ret;
+}
+
+unsigned long acpuclk_get_wfi_rate(void)
+{
+ return drv_state.wait_for_irq_khz;
+}
+
+unsigned long acpuclk_wait_for_irq(void) {
+ int ret = acpuclk_get_rate();
+ ret *= 1000;
+ if (ret > drv_state.wait_for_irq_khz)
+ acpuclk_set_rate(drv_state.wait_for_irq_khz, 1);
+ return ret;
+}
+
+static int acpuclk_set_vdd_level(int vdd)
+{
+ uint32_t current_vdd;
+
+ current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07;
+
+#if PERF_SWITCH_DEBUG
+ printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n",
+ current_vdd, vdd);
+#endif
+ writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR);
+ udelay(drv_state.vdd_switch_time_us);
+ if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) {
+#if PERF_SWITCH_DEBUG
+ printk(KERN_ERR "acpuclock: VDD set failed\n");
+#endif
+ return -EIO;
+ }
+
+#if PERF_SWITCH_DEBUG
+ printk(KERN_DEBUG "acpuclock: VDD switched\n");
+#endif
+ return 0;
+}
+
+/* Set proper dividers for the given clock speed. */
+static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) {
+ uint32_t reg_clkctl, reg_clksel, clk_div;
+
+ /* AHB_CLK_DIV */
+ clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03;
+ /*
+ * If the new clock divider is higher than the previous, then
+ * program the divider before switching the clock
+ */
+ if (hunt_s->ahbclk_div > clk_div) {
+ reg_clksel = readl(A11S_CLK_SEL_ADDR);
+ reg_clksel &= ~(0x3 << 1);
+ reg_clksel |= (hunt_s->ahbclk_div << 1);
+ writel(reg_clksel, A11S_CLK_SEL_ADDR);
+ }
+ if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) {
+ /* SRC0 */
+
+ /* Program clock source */
+ reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+ reg_clkctl &= ~(0x07 << 4);
+ reg_clkctl |= (hunt_s->a11clk_src_sel << 4);
+ writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+ /* Program clock divider */
+ reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+ reg_clkctl &= ~0xf;
+ reg_clkctl |= hunt_s->a11clk_src_div;
+ writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+ /* Program clock source selection */
+ reg_clksel = readl(A11S_CLK_SEL_ADDR);
+ reg_clksel |= 1; /* CLK_SEL_SRC1NO == SRC1 */
+ writel(reg_clksel, A11S_CLK_SEL_ADDR);
+ } else {
+ /* SRC1 */
+
+ /* Program clock source */
+ reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+ reg_clkctl &= ~(0x07 << 12);
+ reg_clkctl |= (hunt_s->a11clk_src_sel << 12);
+ writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+ /* Program clock divider */
+ reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+ reg_clkctl &= ~(0xf << 8);
+ reg_clkctl |= (hunt_s->a11clk_src_div << 8);
+ writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+ /* Program clock source selection */
+ reg_clksel = readl(A11S_CLK_SEL_ADDR);
+ reg_clksel &= ~1; /* CLK_SEL_SRC1NO == SRC0 */
+ writel(reg_clksel, A11S_CLK_SEL_ADDR);
+ }
+
+ /*
+ * If the new clock divider is lower than the previous, then
+ * program the divider after switching the clock
+ */
+ if (hunt_s->ahbclk_div < clk_div) {
+ reg_clksel = readl(A11S_CLK_SEL_ADDR);
+ reg_clksel &= ~(0x3 << 1);
+ reg_clksel |= (hunt_s->ahbclk_div << 1);
+ writel(reg_clksel, A11S_CLK_SEL_ADDR);
+ }
+}
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse)
+{
+ uint32_t reg_clkctl;
+ struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s;
+ int rc = 0;
+ unsigned int plls_enabled = 0, pll;
+
+ strt_s = cur_s = drv_state.current_speed;
+
+ WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n");
+ if (cur_s == NULL)
+ return -ENOENT;
+
+ if (rate == (cur_s->a11clk_khz * 1000))
+ return 0;
+
+ for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) {
+ if (tgt_s->a11clk_khz == (rate / 1000))
+ break;
+ }
+
+ if (tgt_s->a11clk_khz == 0)
+ return -EINVAL;
+
+ /* Choose the highest speed speed at or below 'rate' with same PLL. */
+ if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) {
+ while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll)
+ tgt_s--;
+ }
+
+ if (strt_s->pll != ACPU_PLL_TCXO)
+ plls_enabled |= 1 << strt_s->pll;
+
+ if (!for_power_collapse) {
+ mutex_lock(&drv_state.lock);
+ if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) {
+ rc = pc_pll_request(tgt_s->pll, 1);
+ if (rc < 0) {
+ pr_err("PLL%d enable failed (%d)\n",
+ tgt_s->pll, rc);
+ goto out;
+ }
+ plls_enabled |= 1 << tgt_s->pll;
+ }
+ /* Increase VDD if needed. */
+ if (tgt_s->vdd > cur_s->vdd) {
+ if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) {
+ printk(KERN_ERR "Unable to switch ACPU vdd\n");
+ goto out;
+ }
+ }
+ }
+
+ /* Set wait states for CPU between frequency changes */
+ reg_clkctl = readl(A11S_CLK_CNTL_ADDR);
+ reg_clkctl |= (100 << 16); /* set WT_ST_CNT */
+ writel(reg_clkctl, A11S_CLK_CNTL_ADDR);
+
+#if PERF_SWITCH_DEBUG
+ printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n",
+ strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000);
+#endif
+
+ while (cur_s != tgt_s) {
+ /*
+ * Always jump to target freq if within 256mhz, regulardless of
+ * PLL. If differnece is greater, use the predefinied
+ * steppings in the table.
+ */
+ int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz));
+ if (d > drv_state.max_speed_delta_khz) {
+ /* Step up or down depending on target vs current. */
+ int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ?
+ cur_s->up : cur_s->down;
+ if (clk_index < 0) { /* This should not happen. */
+ printk(KERN_ERR "cur:%u target: %u\n",
+ cur_s->a11clk_khz, tgt_s->a11clk_khz);
+ rc = -EINVAL;
+ goto out;
+ }
+ cur_s = &acpu_freq_tbl[clk_index];
+ } else {
+ cur_s = tgt_s;
+ }
+#if PERF_SWITCH_STEP_DEBUG
+ printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n",
+ __FUNCTION__, cur_s->a11clk_khz, cur_s->pll);
+#endif
+ if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO
+ && !(plls_enabled & (1 << cur_s->pll))) {
+ rc = pc_pll_request(cur_s->pll, 1);
+ if (rc < 0) {
+ pr_err("PLL%d enable failed (%d)\n",
+ cur_s->pll, rc);
+ goto out;
+ }
+ plls_enabled |= 1 << cur_s->pll;
+ }
+
+ acpuclk_set_div(cur_s);
+ drv_state.current_speed = cur_s;
+ /* Re-adjust lpj for the new clock speed. */
+ loops_per_jiffy = cur_s->lpj;
+ udelay(drv_state.acpu_switch_time_us);
+ }
+
+ /* Nothing else to do for power collapse. */
+ if (for_power_collapse)
+ return 0;
+
+ /* Disable PLLs we are not using anymore. */
+ plls_enabled &= ~(1 << tgt_s->pll);
+ for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++)
+ if (plls_enabled & (1 << pll)) {
+ rc = pc_pll_request(pll, 0);
+ if (rc < 0) {
+ pr_err("PLL%d disable failed (%d)\n", pll, rc);
+ goto out;
+ }
+ }
+
+ /* Change the AXI bus frequency if we can. */
+ if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
+ rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000);
+ if (rc < 0)
+ pr_err("Setting AXI min rate failed!\n");
+ }
+
+ /* Drop VDD level if we can. */
+ if (tgt_s->vdd < strt_s->vdd) {
+ if (acpuclk_set_vdd_level(tgt_s->vdd) < 0)
+ printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n");
+ }
+
+#if PERF_SWITCH_DEBUG
+ printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__);
+#endif
+out:
+ if (!for_power_collapse)
+ mutex_unlock(&drv_state.lock);
+ return rc;
+}
+
+static void __init acpuclk_init(void)
+{
+ struct clkctl_acpu_speed *speed;
+ uint32_t div, sel;
+ int rc;
+
+ /*
+ * Determine the rate of ACPU clock
+ */
+
+ if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */
+ /* CLK_SRC0_SEL */
+ sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7;
+ /* CLK_SRC0_DIV */
+ div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f;
+ } else {
+ /* CLK_SRC1_SEL */
+ sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07;
+ /* CLK_SRC1_DIV */
+ div = readl(A11S_CLK_CNTL_ADDR) & 0x0f;
+ }
+
+ for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) {
+ if (speed->a11clk_src_sel == sel
+ && (speed->a11clk_src_div == div))
+ break;
+ }
+ if (speed->a11clk_khz == 0) {
+ printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n");
+ return;
+ }
+
+ drv_state.current_speed = speed;
+
+ rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000);
+ if (rc < 0)
+ pr_err("Setting AXI min rate failed!\n");
+
+ printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz);
+}
+
+unsigned long acpuclk_get_rate(void)
+{
+ WARN_ONCE(drv_state.current_speed == NULL,
+ "acpuclk_get_rate: not initialized\n");
+ if (drv_state.current_speed)
+ return drv_state.current_speed->a11clk_khz;
+ else
+ return 0;
+}
+
+uint32_t acpuclk_get_switch_time(void)
+{
+ return drv_state.acpu_switch_time_us;
+}
+
+/*----------------------------------------------------------------------------
+ * Clock driver initialization
+ *---------------------------------------------------------------------------*/
+
+/* Initialize the lpj field in the acpu_freq_tbl. */
+static void __init lpj_init(void)
+{
+ int i;
+ const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
+ for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) {
+ acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
+ base_clk->a11clk_khz,
+ acpu_freq_tbl[i].a11clk_khz);
+ }
+}
+
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
+{
+ pr_info("acpu_clock_init()\n");
+
+ ebi1_clk = clk_get(NULL, "ebi1_clk");
+
+ mutex_init(&drv_state.lock);
+ drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us;
+ drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz;
+ drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
+ drv_state.power_collapse_khz = clkdata->power_collapse_khz;
+ drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
+ acpuclk_init();
+ lpj_init();
+#ifdef CONFIG_CPU_FREQ_TABLE
+ cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
+#endif
+}
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h
new file mode 100644
index 00000000..415de2eb
--- /dev/null
+++ b/arch/arm/mach-msm/acpuclock.h
@@ -0,0 +1,32 @@
+/* arch/arm/mach-msm/acpuclock.h
+ *
+ * MSM architecture clock driver header
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ * Author: San Mehat <san@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_MSM_ACPUCLOCK_H
+#define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H
+
+int acpuclk_set_rate(unsigned long rate, int for_power_collapse);
+unsigned long acpuclk_get_rate(void);
+uint32_t acpuclk_get_switch_time(void);
+unsigned long acpuclk_wait_for_irq(void);
+unsigned long acpuclk_power_collapse(void);
+unsigned long acpuclk_get_wfi_rate(void);
+
+
+#endif
+
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c
new file mode 100644
index 00000000..18a3c97b
--- /dev/null
+++ b/arch/arm/mach-msm/board-halibut.c
@@ -0,0 +1,102 @@
+/* linux/arch/arm/mach-msm/board-halibut.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/setup.h>
+
+#include <mach/irqs.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "devices.h"
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = 0x9C004300,
+ .end = 0x9C004400,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSM_GPIO_TO_INT(49),
+ .end = MSM_GPIO_TO_INT(49),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_uart3,
+ &msm_device_smd,
+ &msm_device_nand,
+ &msm_device_hsusb,
+ &msm_device_i2c,
+ &smc91x_device,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init halibut_init_irq(void)
+{
+ msm_init_irq();
+}
+
+static void __init halibut_init(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks=1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = (101*1024*1024);
+}
+
+static void __init halibut_map_io(void)
+{
+ msm_map_common_io();
+ msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
+}
+
+MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
+ .boot_params = 0x10000100,
+ .fixup = halibut_fixup,
+ .map_io = halibut_map_io,
+ .init_irq = halibut_init_irq,
+ .init_machine = halibut_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c
new file mode 100644
index 00000000..7a9a03eb
--- /dev/null
+++ b/arch/arm/mach-msm/board-mahimahi.c
@@ -0,0 +1,83 @@
+/* linux/arch/arm/mach-msm/board-mahimahi.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2009 HTC Corporation.
+ * Author: Dima Zavin <dima@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+
+#include "board-mahimahi.h"
+#include "devices.h"
+#include "proc_comm.h"
+
+static uint debug_uart;
+
+module_param_named(debug_uart, debug_uart, uint, 0);
+
+static struct platform_device *devices[] __initdata = {
+#if !defined(CONFIG_MSM_SERIAL_DEBUGGER)
+ &msm_device_uart1,
+#endif
+ &msm_device_uart_dm1,
+ &msm_device_nand,
+};
+
+static void __init mahimahi_init(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 2;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+ mi->bank[0].size = (219*1024*1024);
+ mi->bank[1].start = MSM_HIGHMEM_BASE;
+ mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE);
+ mi->bank[1].size = MSM_HIGHMEM_SIZE;
+}
+
+static void __init mahimahi_map_io(void)
+{
+ msm_map_common_io();
+ msm_clock_init();
+}
+
+extern struct sys_timer msm_timer;
+
+MACHINE_START(MAHIMAHI, "mahimahi")
+ .boot_params = 0x20000100,
+ .fixup = mahimahi_fixup,
+ .map_io = mahimahi_map_io,
+ .init_irq = msm_init_irq,
+ .init_machine = mahimahi_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
new file mode 100644
index 00000000..c03f269e
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/power_supply.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/setup.h>
+#ifdef CONFIG_CACHE_L2X0
+#include <asm/hardware/cache-l2x0.h>
+#endif
+
+#include <mach/vreg.h>
+#include <mach/mpp.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "devices.h"
+#include "socinfo.h"
+#include "clock.h"
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = 0x9C004300,
+ .end = 0x9C0043ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MSM_GPIO_TO_INT(132),
+ .end = MSM_GPIO_TO_INT(132),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_uart3,
+ &msm_device_smd,
+ &msm_device_dmov,
+ &msm_device_nand,
+ &smc91x_device,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init msm7x2x_init_irq(void)
+{
+ msm_init_irq();
+}
+
+static void __init msm7x2x_init(void)
+{
+ if (socinfo_init() < 0)
+ BUG();
+
+ if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) {
+ smc91x_resources[0].start = 0x98000300;
+ smc91x_resources[0].end = 0x980003ff;
+ smc91x_resources[1].start = MSM_GPIO_TO_INT(85);
+ smc91x_resources[1].end = MSM_GPIO_TO_INT(85);
+ if (gpio_tlmm_config(GPIO_CFG(85, 0,
+ GPIO_INPUT,
+ GPIO_PULL_DOWN,
+ GPIO_2MA),
+ GPIO_ENABLE)) {
+ printk(KERN_ERR
+ "%s: Err: Config GPIO-85 INT\n",
+ __func__);
+ }
+ }
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init msm7x2x_map_io(void)
+{
+ msm_map_common_io();
+ /* Technically dependent on the SoC but using machine_is
+ * macros since socinfo is not available this early and there
+ * are plans to restructure the code which will eliminate the
+ * need for socinfo.
+ */
+ if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa())
+ msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27);
+
+ if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa())
+ msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25);
+
+#ifdef CONFIG_CACHE_L2X0
+ if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) {
+ /* 7x27 has 256KB L2 cache:
+ 64Kb/Way and 4-Way Associativity;
+ R/W latency: 3 cycles;
+ evmon/parity/share disabled. */
+ l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000);
+ }
+#endif
+}
+
+MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x2x_map_io,
+ .init_irq = msm7x2x_init_irq,
+ .init_machine = msm7x2x_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x2x_map_io,
+ .init_irq = msm7x2x_init_irq,
+ .init_machine = msm7x2x_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x2x_map_io,
+ .init_irq = msm7x2x_init_irq,
+ .init_machine = msm7x2x_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x2x_map_io,
+ .init_irq = msm7x2x_init_irq,
+ .init_machine = msm7x2x_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
new file mode 100644
index 00000000..b7a84966
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -0,0 +1,130 @@
+/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/usb/msm_hsusb.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/memory.h>
+#include <asm/setup.h>
+
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+
+#include <mach/vreg.h>
+#include "devices.h"
+#include "gpiomux.h"
+#include "proc_comm.h"
+
+extern struct sys_timer msm_timer;
+
+static int hsusb_phy_init_seq[] = {
+ 0x30, 0x32, /* Enable and set Pre-Emphasis Depth to 20% */
+ 0x02, 0x36, /* Disable CDR Auto Reset feature */
+ -1
+};
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+ .phy_init_seq = hsusb_phy_init_seq,
+ .mode = USB_PERIPHERAL,
+ .otg_control = OTG_PHY_CONTROL,
+};
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+#ifdef CONFIG_SERIAL_MSM_CONSOLE
+ [49] = { /* UART2 RFR */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [50] = { /* UART2 CTS */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [51] = { /* UART2 RX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+ [52] = { /* UART2 TX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_2 | GPIOMUX_VALID,
+ },
+#endif
+};
+
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
+ &msm_device_uart2,
+#endif
+ &msm_device_smd,
+ &msm_device_otg,
+ &msm_device_hsusb,
+ &msm_device_hsusb_host,
+};
+
+static void __init msm7x30_init_irq(void)
+{
+ msm_init_irq();
+}
+
+static void __init msm7x30_init(void)
+{
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_hsusb.dev.parent = &msm_device_otg.dev;
+ msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init msm7x30_map_io(void)
+{
+ msm_map_msm7x30_io();
+ msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30);
+}
+
+MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x30_map_io,
+ .init_irq = msm7x30_init_irq,
+ .init_machine = msm7x30_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x30_map_io,
+ .init_irq = msm7x30_init_irq,
+ .init_machine = msm7x30_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = msm7x30_map_io,
+ .init_irq = msm7x30_init_irq,
+ .init_machine = msm7x30_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
new file mode 100644
index 00000000..35c7ceeb
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -0,0 +1,91 @@
+/* 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+#include "devices.h"
+
+static void __init msm8960_map_io(void)
+{
+ msm_map_msm8960_io();
+}
+
+static void __init msm8960_init_irq(void)
+{
+ unsigned int i;
+ gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+ (void *)MSM_QGIC_CPU_BASE);
+
+ /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+ writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+ if (machine_is_msm8960_rumi3())
+ writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+
+ /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+ * as they are configured as level, which does not play nice with
+ * handle_percpu_irq.
+ */
+ for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+ if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+ irq_set_handler(i, handle_percpu_irq);
+ }
+}
+
+static struct platform_device *sim_devices[] __initdata = {
+ &msm8960_device_uart_gsbi2,
+};
+
+static struct platform_device *rumi3_devices[] __initdata = {
+ &msm8960_device_uart_gsbi5,
+};
+
+static void __init msm8960_sim_init(void)
+{
+ platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
+}
+
+static void __init msm8960_rumi3_init(void)
+{
+ platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
+}
+
+MACHINE_START(MSM8960_SIM, "QCT MSM8960 SIMULATOR")
+ .map_io = msm8960_map_io,
+ .init_irq = msm8960_init_irq,
+ .timer = &msm_timer,
+ .init_machine = msm8960_sim_init,
+MACHINE_END
+
+MACHINE_START(MSM8960_RUMI3, "QCT MSM8960 RUMI3")
+ .map_io = msm8960_map_io,
+ .init_irq = msm8960_init_irq,
+ .timer = &msm_timer,
+ .init_machine = msm8960_rumi3_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
new file mode 100644
index 00000000..1163b6fd
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/gic.h>
+
+#include <mach/board.h>
+#include <mach/msm_iomap.h>
+
+
+static void __init msm8x60_map_io(void)
+{
+ msm_map_msm8x60_io();
+}
+
+static void __init msm8x60_init_irq(void)
+{
+ unsigned int i;
+
+ gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE,
+ (void *)MSM_QGIC_CPU_BASE);
+
+ /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+ writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+ /* RUMI does not adhere to GIC spec by enabling STIs by default.
+ * Enable/clear is supposed to be RO for STIs, but is RW on RUMI.
+ */
+ if (!machine_is_msm8x60_sim())
+ writel(0x0000FFFF, MSM_QGIC_DIST_BASE + GIC_DIST_ENABLE_SET);
+
+ /* FIXME: Not installing AVS_SVICINT and AVS_SVICINTSWDONE yet
+ * as they are configured as level, which does not play nice with
+ * handle_percpu_irq.
+ */
+ for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
+ if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
+ irq_set_handler(i, handle_percpu_irq);
+ }
+}
+
+static void __init msm8x60_init(void)
+{
+}
+
+MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
new file mode 100644
index 00000000..6a96911b
--- /dev/null
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -0,0 +1,209 @@
+/* Copyright (c) 2009-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/usb/msm_hsusb.h>
+#include <linux/err.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/irqs.h>
+#include <mach/sirc.h>
+#include <mach/gpio.h>
+#include <mach/vreg.h>
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+extern struct sys_timer msm_timer;
+
+static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300;
+static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156;
+
+/* Leave smc91x resources empty here, as we'll fill them in
+ * at run-time: they vary from board to board, and the true
+ * configuration won't be known until boot.
+ */
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static int __init msm_init_smc91x(void)
+{
+ if (machine_is_qsd8x50_surf()) {
+ smc91x_resources[0].start = qsd8x50_surf_smc91x_base;
+ smc91x_resources[0].end = qsd8x50_surf_smc91x_base + 0xff;
+ smc91x_resources[1].start =
+ gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+ smc91x_resources[1].end =
+ gpio_to_irq(qsd8x50_surf_smc91x_gpio);
+ platform_device_register(&smc91x_device);
+ }
+
+ return 0;
+}
+module_init(msm_init_smc91x);
+
+static int hsusb_phy_init_seq[] = {
+ 0x08, 0x31, /* Increase HS Driver Amplitude */
+ 0x20, 0x32, /* Enable and set Pre-Emphasis Depth to 10% */
+ -1
+};
+
+static struct msm_otg_platform_data msm_otg_pdata = {
+ .phy_init_seq = hsusb_phy_init_seq,
+ .mode = USB_PERIPHERAL,
+ .otg_control = OTG_PHY_CONTROL,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_uart3,
+ &msm_device_smd,
+ &msm_device_otg,
+ &msm_device_hsusb,
+ &msm_device_hsusb_host,
+};
+
+static struct msm_mmc_gpio sdc1_gpio_cfg[] = {
+ {51, "sdc1_dat_3"},
+ {52, "sdc1_dat_2"},
+ {53, "sdc1_dat_1"},
+ {54, "sdc1_dat_0"},
+ {55, "sdc1_cmd"},
+ {56, "sdc1_clk"}
+};
+
+static struct vreg *vreg_mmc;
+static unsigned long vreg_sts;
+
+static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
+{
+ int rc = 0;
+ struct platform_device *pdev;
+
+ pdev = container_of(dv, struct platform_device, dev);
+
+ if (vdd == 0) {
+ if (!vreg_sts)
+ return 0;
+
+ clear_bit(pdev->id, &vreg_sts);
+
+ if (!vreg_sts) {
+ rc = vreg_disable(vreg_mmc);
+ if (rc)
+ pr_err("vreg_mmc disable failed for slot "
+ "%d: %d\n", pdev->id, rc);
+ }
+ return 0;
+ }
+
+ if (!vreg_sts) {
+ rc = vreg_set_level(vreg_mmc, 2900);
+ if (rc)
+ pr_err("vreg_mmc set level failed for slot %d: %d\n",
+ pdev->id, rc);
+ rc = vreg_enable(vreg_mmc);
+ if (rc)
+ pr_err("vreg_mmc enable failed for slot %d: %d\n",
+ pdev->id, rc);
+ }
+ set_bit(pdev->id, &vreg_sts);
+ return 0;
+}
+
+static struct msm_mmc_gpio_data sdc1_gpio = {
+ .gpio = sdc1_gpio_cfg,
+ .size = ARRAY_SIZE(sdc1_gpio_cfg),
+};
+
+static struct msm_mmc_platform_data qsd8x50_sdc1_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .translate_vdd = msm_sdcc_setup_power,
+ .gpio_data = &sdc1_gpio,
+};
+
+static void __init qsd8x50_init_mmc(void)
+{
+ vreg_mmc = vreg_get(NULL, "gp5");
+
+ if (IS_ERR(vreg_mmc)) {
+ pr_err("vreg get for vreg_mmc failed (%ld)\n",
+ PTR_ERR(vreg_mmc));
+ return;
+ }
+
+ msm_add_sdcc(1, &qsd8x50_sdc1_data, 0, 0);
+}
+
+static void __init qsd8x50_map_io(void)
+{
+ msm_map_qsd8x50_io();
+ msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);
+}
+
+static void __init qsd8x50_init_irq(void)
+{
+ msm_init_irq();
+ msm_init_sirc();
+}
+
+static void __init qsd8x50_init(void)
+{
+ msm_device_otg.dev.platform_data = &msm_otg_pdata;
+ msm_device_hsusb.dev.parent = &msm_device_otg.dev;
+ msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ qsd8x50_init_mmc();
+}
+
+MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = qsd8x50_map_io,
+ .init_irq = qsd8x50_init_irq,
+ .init_machine = qsd8x50_init,
+ .timer = &msm_timer,
+MACHINE_END
+
+MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .map_io = qsd8x50_map_io,
+ .init_irq = qsd8x50_init_irq,
+ .init_machine = qsd8x50_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
new file mode 100644
index 00000000..68f930f0
--- /dev/null
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -0,0 +1,114 @@
+/* linux/arch/arm/mach-msm/board-sapphire.c
+ * Copyright (C) 2007-2009 HTC Corporation.
+ * Author: Thomas Tsai <thomas_tsai@htc.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sysdev.h>
+
+#include <linux/delay.h>
+
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/system.h>
+#include <mach/system.h>
+#include <mach/vreg.h>
+#include <mach/board.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/setup.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "gpio_chip.h"
+#include "board-sapphire.h"
+#include "proc_comm.h"
+#include "devices.h"
+
+void msm_init_irq(void);
+void msm_init_gpio(void);
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_smd,
+ &msm_device_dmov,
+ &msm_device_nand,
+ &msm_device_uart1,
+ &msm_device_uart3,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init sapphire_init_irq(void)
+{
+ msm_init_irq();
+}
+
+static void __init sapphire_init(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static struct map_desc sapphire_io_desc[] __initdata = {
+ {
+ .virtual = SAPPHIRE_CPLD_BASE,
+ .pfn = __phys_to_pfn(SAPPHIRE_CPLD_START),
+ .length = SAPPHIRE_CPLD_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ }
+};
+
+static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ int smi_sz = parse_tag_smi((const struct tag *)tags);
+
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+ if (smi_sz == 32) {
+ mi->bank[0].size = (84*1024*1024);
+ } else if (smi_sz == 64) {
+ mi->bank[0].size = (101*1024*1024);
+ } else {
+ /* Give a default value when not get smi size */
+ smi_sz = 64;
+ mi->bank[0].size = (101*1024*1024);
+ }
+}
+
+static void __init sapphire_map_io(void)
+{
+ msm_map_common_io();
+ iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc));
+ msm_clock_init();
+}
+
+MACHINE_START(SAPPHIRE, "sapphire")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+ .fixup = sapphire_fixup,
+ .map_io = sapphire_map_io,
+ .init_irq = sapphire_init_irq,
+ .init_machine = sapphire_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c
new file mode 100644
index 00000000..87e1d01e
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-gpio.c
@@ -0,0 +1,233 @@
+/*
+ * linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2005 HP Labs
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2009 Pavel Machek <pavel@ucw.cz>
+ *
+ * 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/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include "board-trout.h"
+
+static uint8_t trout_int_mask[2] = {
+ [0] = 0xff, /* mask all interrupts */
+ [1] = 0xff,
+};
+static uint8_t trout_sleep_int_mask[] = {
+ [0] = 0xff,
+ [1] = 0xff,
+};
+
+struct msm_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *reg; /* Base of register bank */
+ u8 shadow;
+};
+
+#define to_msm_gpio_chip(c) container_of(c, struct msm_gpio_chip, chip)
+
+static int msm_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
+ unsigned mask = 1 << offset;
+
+ return !!(readb(msm_gpio->reg) & mask);
+}
+
+static void msm_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
+ unsigned mask = 1 << offset;
+
+ if (val)
+ msm_gpio->shadow |= mask;
+ else
+ msm_gpio->shadow &= ~mask;
+
+ writeb(msm_gpio->shadow, msm_gpio->reg);
+}
+
+static int msm_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ msm_gpiolib_set(chip, offset, 0);
+ return 0;
+}
+
+static int msm_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ msm_gpiolib_set(chip, offset, val);
+ return 0;
+}
+
+static int trout_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return TROUT_GPIO_TO_INT(offset + chip->base);
+}
+
+#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = msm_gpiolib_direction_input,\
+ .direction_output = msm_gpiolib_direction_output, \
+ .get = msm_gpiolib_get, \
+ .set = msm_gpiolib_set, \
+ .to_irq = trout_gpio_to_irq, \
+ .base = base_gpio, \
+ .ngpio = 8, \
+ }, \
+ .reg = (void *) reg_num + TROUT_CPLD_BASE, \
+ .shadow = shadow_val, \
+ }
+
+static struct msm_gpio_chip msm_gpio_banks[] = {
+#if defined(CONFIG_MSM_DEBUG_UART1)
+ /* H2W pins <-> UART1 */
+ TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x40),
+#else
+ /* H2W pins <-> UART3, Bluetooth <-> UART1 */
+ TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x80),
+#endif
+ /* I2C pull */
+ TROUT_GPIO_BANK("MISC3", 0x02, TROUT_GPIO_MISC3_BASE, 0x04),
+ TROUT_GPIO_BANK("MISC4", 0x04, TROUT_GPIO_MISC4_BASE, 0),
+ /* mmdi 32k en */
+ TROUT_GPIO_BANK("MISC5", 0x06, TROUT_GPIO_MISC5_BASE, 0x04),
+ TROUT_GPIO_BANK("INT2", 0x08, TROUT_GPIO_INT2_BASE, 0),
+ TROUT_GPIO_BANK("MISC1", 0x0a, TROUT_GPIO_MISC1_BASE, 0),
+ TROUT_GPIO_BANK("VIRTUAL", 0x12, TROUT_GPIO_VIRTUAL_BASE, 0),
+};
+
+static void trout_gpio_irq_ack(struct irq_data *d)
+{
+ int bank = TROUT_INT_TO_BANK(d->irq);
+ uint8_t mask = TROUT_INT_TO_MASK(d->irq);
+ int reg = TROUT_BANK_TO_STAT_REG(bank);
+ /*printk(KERN_INFO "trout_gpio_irq_ack irq %d\n", d->irq);*/
+ writeb(mask, TROUT_CPLD_BASE + reg);
+}
+
+static void trout_gpio_irq_mask(struct irq_data *d)
+{
+ unsigned long flags;
+ uint8_t reg_val;
+ int bank = TROUT_INT_TO_BANK(d->irq);
+ uint8_t mask = TROUT_INT_TO_MASK(d->irq);
+ int reg = TROUT_BANK_TO_MASK_REG(bank);
+
+ local_irq_save(flags);
+ reg_val = trout_int_mask[bank] |= mask;
+ /*printk(KERN_INFO "trout_gpio_irq_mask irq %d => %d:%02x\n",
+ d->irq, bank, reg_val);*/
+ writeb(reg_val, TROUT_CPLD_BASE + reg);
+ local_irq_restore(flags);
+}
+
+static void trout_gpio_irq_unmask(struct irq_data *d)
+{
+ unsigned long flags;
+ uint8_t reg_val;
+ int bank = TROUT_INT_TO_BANK(d->irq);
+ uint8_t mask = TROUT_INT_TO_MASK(d->irq);
+ int reg = TROUT_BANK_TO_MASK_REG(bank);
+
+ local_irq_save(flags);
+ reg_val = trout_int_mask[bank] &= ~mask;
+ /*printk(KERN_INFO "trout_gpio_irq_unmask irq %d => %d:%02x\n",
+ d->irq, bank, reg_val);*/
+ writeb(reg_val, TROUT_CPLD_BASE + reg);
+ local_irq_restore(flags);
+}
+
+int trout_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned long flags;
+ int bank = TROUT_INT_TO_BANK(d->irq);
+ uint8_t mask = TROUT_INT_TO_MASK(d->irq);
+
+ local_irq_save(flags);
+ if(on)
+ trout_sleep_int_mask[bank] &= ~mask;
+ else
+ trout_sleep_int_mask[bank] |= mask;
+ local_irq_restore(flags);
+ return 0;
+}
+
+static void trout_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int j, m;
+ unsigned v;
+ int bank;
+ int stat_reg;
+ int int_base = TROUT_INT_START;
+ uint8_t int_mask;
+
+ for (bank = 0; bank < 2; bank++) {
+ stat_reg = TROUT_BANK_TO_STAT_REG(bank);
+ v = readb(TROUT_CPLD_BASE + stat_reg);
+ int_mask = trout_int_mask[bank];
+ if (v & int_mask) {
+ writeb(v & int_mask, TROUT_CPLD_BASE + stat_reg);
+ printk(KERN_ERR "trout_gpio_irq_handler: got masked "
+ "interrupt: %d:%02x\n", bank, v & int_mask);
+ }
+ v &= ~int_mask;
+ while (v) {
+ m = v & -v;
+ j = fls(m) - 1;
+ /*printk(KERN_INFO "msm_gpio_irq_handler %d:%02x %02x b"
+ "it %d irq %d\n", bank, v, m, j, int_base + j);*/
+ v &= ~m;
+ generic_handle_irq(int_base + j);
+ }
+ int_base += TROUT_INT_BANK0_COUNT;
+ }
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+}
+
+static struct irq_chip trout_gpio_irq_chip = {
+ .name = "troutgpio",
+ .irq_ack = trout_gpio_irq_ack,
+ .irq_mask = trout_gpio_irq_mask,
+ .irq_unmask = trout_gpio_irq_unmask,
+ .irq_set_wake = trout_gpio_irq_set_wake,
+};
+
+/*
+ * Called from the processor-specific init to enable GPIO pin support.
+ */
+int __init trout_init_gpio(void)
+{
+ int i;
+ for(i = TROUT_INT_START; i <= TROUT_INT_END; i++) {
+ irq_set_chip_and_handler(i, &trout_gpio_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
+ gpiochip_add(&msm_gpio_banks[i].chip);
+
+ irq_set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH);
+ irq_set_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler);
+ irq_set_irq_wake(MSM_GPIO_TO_INT(17), 1);
+
+ return 0;
+}
+
+postcore_initcall(trout_init_gpio);
+
diff --git a/arch/arm/mach-msm/board-trout-mmc.c b/arch/arm/mach-msm/board-trout-mmc.c
new file mode 100644
index 00000000..f7a97247
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-mmc.c
@@ -0,0 +1,186 @@
+/* linux/arch/arm/mach-msm/board-trout-mmc.c
+** Author: Brian Swetland <swetland@google.com>
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#include <mach/vreg.h>
+
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+#include "board-trout.h"
+
+#include "proc_comm.h"
+
+#define DEBUG_SDSLOT_VDD 1
+
+/* ---- COMMON ---- */
+static void config_gpio_table(uint32_t *table, int len)
+{
+ int n;
+ unsigned id;
+ for(n = 0; n < len; n++) {
+ id = table[n];
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0);
+ }
+}
+
+/* ---- SDCARD ---- */
+
+static uint32_t sdcard_on_gpio_table[] = {
+ PCOM_GPIO_CFG(62, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA), /* CLK */
+ PCOM_GPIO_CFG(63, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* CMD */
+ PCOM_GPIO_CFG(64, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT3 */
+ PCOM_GPIO_CFG(65, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT2 */
+ PCOM_GPIO_CFG(66, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT1 */
+ PCOM_GPIO_CFG(67, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT0 */
+};
+
+static uint32_t sdcard_off_gpio_table[] = {
+ PCOM_GPIO_CFG(62, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CLK */
+ PCOM_GPIO_CFG(63, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CMD */
+ PCOM_GPIO_CFG(64, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT3 */
+ PCOM_GPIO_CFG(65, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT2 */
+ PCOM_GPIO_CFG(66, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT1 */
+ PCOM_GPIO_CFG(67, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT0 */
+};
+
+static uint opt_disable_sdcard;
+
+static int __init trout_disablesdcard_setup(char *str)
+{
+ int cal = simple_strtol(str, NULL, 0);
+
+ opt_disable_sdcard = cal;
+ return 1;
+}
+
+__setup("board_trout.disable_sdcard=", trout_disablesdcard_setup);
+
+static struct vreg *vreg_sdslot; /* SD slot power */
+
+struct mmc_vdd_xlat {
+ int mask;
+ int level;
+};
+
+static struct mmc_vdd_xlat mmc_vdd_table[] = {
+ { MMC_VDD_165_195, 1800 },
+ { MMC_VDD_20_21, 2050 },
+ { MMC_VDD_21_22, 2150 },
+ { MMC_VDD_22_23, 2250 },
+ { MMC_VDD_23_24, 2350 },
+ { MMC_VDD_24_25, 2450 },
+ { MMC_VDD_25_26, 2550 },
+ { MMC_VDD_26_27, 2650 },
+ { MMC_VDD_27_28, 2750 },
+ { MMC_VDD_28_29, 2850 },
+ { MMC_VDD_29_30, 2950 },
+};
+
+static unsigned int sdslot_vdd = 0xffffffff;
+static unsigned int sdslot_vreg_enabled;
+
+static uint32_t trout_sdslot_switchvdd(struct device *dev, unsigned int vdd)
+{
+ int i, rc;
+
+ BUG_ON(!vreg_sdslot);
+
+ if (vdd == sdslot_vdd)
+ return 0;
+
+ sdslot_vdd = vdd;
+
+ if (vdd == 0) {
+#if DEBUG_SDSLOT_VDD
+ printk("%s: Disabling SD slot power\n", __func__);
+#endif
+ config_gpio_table(sdcard_off_gpio_table,
+ ARRAY_SIZE(sdcard_off_gpio_table));
+ vreg_disable(vreg_sdslot);
+ sdslot_vreg_enabled = 0;
+ return 0;
+ }
+
+ if (!sdslot_vreg_enabled) {
+ rc = vreg_enable(vreg_sdslot);
+ if (rc) {
+ printk(KERN_ERR "%s: Error enabling vreg (%d)\n",
+ __func__, rc);
+ }
+ config_gpio_table(sdcard_on_gpio_table,
+ ARRAY_SIZE(sdcard_on_gpio_table));
+ sdslot_vreg_enabled = 1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mmc_vdd_table); i++) {
+ if (mmc_vdd_table[i].mask == (1 << vdd)) {
+#if DEBUG_SDSLOT_VDD
+ printk("%s: Setting level to %u\n",
+ __func__, mmc_vdd_table[i].level);
+#endif
+ rc = vreg_set_level(vreg_sdslot,
+ mmc_vdd_table[i].level);
+ if (rc) {
+ printk(KERN_ERR
+ "%s: Error setting vreg level (%d)\n",
+ __func__, rc);
+ }
+ return 0;
+ }
+ }
+
+ printk(KERN_ERR "%s: Invalid VDD %d specified\n", __func__, vdd);
+ return 0;
+}
+
+static unsigned int trout_sdslot_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) gpio_get_value(TROUT_GPIO_SDMC_CD_N);
+ return (!status);
+}
+
+#define TROUT_MMC_VDD MMC_VDD_165_195 | MMC_VDD_20_21 | MMC_VDD_21_22 \
+ | MMC_VDD_22_23 | MMC_VDD_23_24 | MMC_VDD_24_25 \
+ | MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 \
+ | MMC_VDD_28_29 | MMC_VDD_29_30
+
+static struct msm_mmc_platform_data trout_sdslot_data = {
+ .ocr_mask = TROUT_MMC_VDD,
+ .status = trout_sdslot_status,
+ .translate_vdd = trout_sdslot_switchvdd,
+};
+
+int __init trout_init_mmc(unsigned int sys_rev)
+{
+ sdslot_vreg_enabled = 0;
+
+ vreg_sdslot = vreg_get(0, "gp6");
+ if (IS_ERR(vreg_sdslot))
+ return PTR_ERR(vreg_sdslot);
+
+ irq_set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1);
+
+ if (!opt_disable_sdcard)
+ msm_add_sdcc(2, &trout_sdslot_data,
+ TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 0);
+ else
+ printk(KERN_INFO "trout: SD-Card interface disabled\n");
+ return 0;
+}
+
diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c
new file mode 100644
index 00000000..729bb49a
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-panel.c
@@ -0,0 +1,297 @@
+/* linux/arch/arm/mach-msm/board-trout-mddi.c
+** Author: Brian Swetland <swetland@google.com>
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/mach-types.h>
+
+#include <mach/msm_fb.h>
+#include <mach/vreg.h>
+
+#include "board-trout.h"
+#include "proc_comm.h"
+#include "devices.h"
+
+#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255
+
+#define MDDI_CLIENT_CORE_BASE 0x108000
+#define LCD_CONTROL_BLOCK_BASE 0x110000
+#define SPI_BLOCK_BASE 0x120000
+#define I2C_BLOCK_BASE 0x130000
+#define PWM_BLOCK_BASE 0x140000
+#define GPIO_BLOCK_BASE 0x150000
+#define SYSTEM_BLOCK1_BASE 0x160000
+#define SYSTEM_BLOCK2_BASE 0x170000
+
+
+#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
+#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)
+#define PWM0OFF (PWM_BLOCK_BASE|0x1C)
+
+#define V_VDDE2E_VDD2_GPIO 0
+#define MDDI_RST_N 82
+
+#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)
+#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)
+#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)
+#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)
+#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)
+#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)
+#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)
+#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)
+#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)
+#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)
+#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)
+#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)
+#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)
+#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)
+#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)
+#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)
+#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)
+#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)
+#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)
+#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)
+#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)
+#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)
+
+#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)
+#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)
+#define START (LCD_CONTROL_BLOCK_BASE|0x08)
+#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)
+#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)
+#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)
+#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)
+#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)
+#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)
+#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)
+#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)
+#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)
+#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)
+#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)
+#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)
+#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)
+#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)
+#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)
+#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)
+#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)
+#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)
+#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)
+#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)
+#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)
+#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)
+#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)
+#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)
+#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)
+#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)
+#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)
+#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)
+#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)
+#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)
+#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)
+#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)
+
+#define SSICTL (SPI_BLOCK_BASE|0x00)
+#define SSITIME (SPI_BLOCK_BASE|0x04)
+#define SSITX (SPI_BLOCK_BASE|0x08)
+#define SSIRX (SPI_BLOCK_BASE|0x0C)
+#define SSIINTC (SPI_BLOCK_BASE|0x10)
+#define SSIINTS (SPI_BLOCK_BASE|0x14)
+#define SSIDBG1 (SPI_BLOCK_BASE|0x18)
+#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)
+#define SSIID (SPI_BLOCK_BASE|0x20)
+
+#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)
+#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)
+#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)
+#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)
+#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
+
+#define GPIODATA (GPIO_BLOCK_BASE|0x00)
+#define GPIODIR (GPIO_BLOCK_BASE|0x04)
+#define GPIOIS (GPIO_BLOCK_BASE|0x08)
+#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)
+#define GPIOIEV (GPIO_BLOCK_BASE|0x10)
+#define GPIOIE (GPIO_BLOCK_BASE|0x14)
+#define GPIORIS (GPIO_BLOCK_BASE|0x18)
+#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)
+#define GPIOIC (GPIO_BLOCK_BASE|0x20)
+#define GPIOOMS (GPIO_BLOCK_BASE|0x24)
+#define GPIOPC (GPIO_BLOCK_BASE|0x28)
+#define GPIOID (GPIO_BLOCK_BASE|0x30)
+
+#define SPI_WRITE(reg, val) \
+ { SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \
+ { 0, 5 },
+
+#define SPI_WRITE1(reg) \
+ { SSITX, (reg) & 0xff }, \
+ { 0, 5 },
+
+struct mddi_table {
+ uint32_t reg;
+ uint32_t value;
+};
+static struct mddi_table mddi_toshiba_init_table[] = {
+ { DPSET0, 0x09e90046 },
+ { DPSET1, 0x00000118 },
+ { DPSUS, 0x00000000 },
+ { DPRUN, 0x00000001 },
+ { 1, 14 }, /* msleep 14 */
+ { SYSCKENA, 0x00000001 },
+ { CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */
+
+ { GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */
+ { GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */
+ { GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */
+ { GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */
+ { WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */
+
+ { GPIOIBE, 0x000003FF },
+ { GPIOIS, 0x00000000 },
+ { GPIOIC, 0x000003FF },
+ { GPIOIE, 0x00000000 },
+
+ { GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
+ { 1, 1 }, /* msleep 1 */
+ { GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */
+ { DRAMPWR, 0x00000001 }, /* eDRAM power */
+};
+
+#define GPIOSEL_VWAKEINT (1U << 0)
+#define INTMASK_VWAKEOUT (1U << 0)
+
+
+static struct clk *gp_clk;
+static int trout_new_backlight = 1;
+static struct vreg *vreg_mddi_1v5;
+static struct vreg *vreg_lcm_2v85;
+
+static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,
+ struct mddi_table *table, size_t count)
+{
+ int i;
+ for (i = 0; i < count; i++) {
+ uint32_t reg = table[i].reg;
+ uint32_t value = table[i].value;
+
+ if (reg == 0)
+ udelay(value);
+ else if (reg == 1)
+ msleep(value);
+ else
+ client_data->remote_write(client_data, value, reg);
+ }
+}
+
+static int trout_mddi_toshiba_client_init(
+ struct msm_mddi_bridge_platform_data *bridge_data,
+ struct msm_mddi_client_data *client_data)
+{
+ int panel_id;
+
+ client_data->auto_hibernate(client_data, 0);
+ trout_process_mddi_table(client_data, mddi_toshiba_init_table,
+ ARRAY_SIZE(mddi_toshiba_init_table));
+ client_data->auto_hibernate(client_data, 1);
+ panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;
+ if (panel_id > 1) {
+ printk(KERN_WARNING "unknown panel id at mddi_enable\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int trout_mddi_toshiba_client_uninit(
+ struct msm_mddi_bridge_platform_data *bridge_data,
+ struct msm_mddi_client_data *client_data)
+{
+ return 0;
+}
+
+static struct resource resources_msm_fb[] = {
+ {
+ .start = MSM_FB_BASE,
+ .end = MSM_FB_BASE + MSM_FB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct msm_mddi_bridge_platform_data toshiba_client_data = {
+ .init = trout_mddi_toshiba_client_init,
+ .uninit = trout_mddi_toshiba_client_uninit,
+ .fb_data = {
+ .xres = 320,
+ .yres = 480,
+ .width = 45,
+ .height = 67,
+ .output_format = 0,
+ },
+};
+
+static struct msm_mddi_platform_data mddi_pdata = {
+ .clk_rate = 122880000,
+ .fb_resource = resources_msm_fb,
+ .num_clients = 1,
+ .client_platform_data = {
+ {
+ .product_id = (0xd263 << 16 | 0),
+ .name = "mddi_c_d263_0000",
+ .id = 0,
+ .client_data = &toshiba_client_data,
+ .clk_rate = 0,
+ },
+ },
+};
+
+int __init trout_init_panel(void)
+{
+ int rc;
+
+ if (!machine_is_trout())
+ return 0;
+ vreg_mddi_1v5 = vreg_get(0, "gp2");
+ if (IS_ERR(vreg_mddi_1v5))
+ return PTR_ERR(vreg_mddi_1v5);
+ vreg_lcm_2v85 = vreg_get(0, "gp4");
+ if (IS_ERR(vreg_lcm_2v85))
+ return PTR_ERR(vreg_lcm_2v85);
+
+ trout_new_backlight = system_rev >= 5;
+ if (trout_new_backlight) {
+ uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,
+ GPIO_NO_PULL, GPIO_8MA);
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
+ } else {
+ uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,
+ GPIO_NO_PULL, GPIO_8MA);
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);
+
+ gp_clk = clk_get(NULL, "gp_clk");
+ if (IS_ERR(gp_clk)) {
+ printk(KERN_ERR "trout_init_panel: could not get gp"
+ "clock\n");
+ gp_clk = NULL;
+ }
+ rc = clk_set_rate(gp_clk, 19200000);
+ if (rc)
+ printk(KERN_ERR "trout_init_panel: set clock rate "
+ "failed\n");
+ }
+
+ rc = platform_device_register(&msm_device_mdp);
+ if (rc)
+ return rc;
+ msm_device_mddi0.dev.platform_data = &mddi_pdata;
+ return platform_device_register(&msm_device_mddi0);
+}
+
+device_initcall(trout_init_panel);
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
new file mode 100644
index 00000000..81438677
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout.c
@@ -0,0 +1,102 @@
+/* linux/arch/arm/mach-msm/board-trout.c
+ *
+ * Copyright (C) 2009 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+
+#include <mach/board.h>
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+
+#include "devices.h"
+#include "board-trout.h"
+
+extern int trout_init_mmc(unsigned int);
+
+static struct platform_device *devices[] __initdata = {
+ &msm_device_uart3,
+ &msm_device_smd,
+ &msm_device_nand,
+ &msm_device_hsusb,
+ &msm_device_i2c,
+};
+
+extern struct sys_timer msm_timer;
+
+static void __init trout_init_irq(void)
+{
+ msm_init_irq();
+}
+
+static void __init trout_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = (101*1024*1024);
+}
+
+static void __init trout_init(void)
+{
+ int rc;
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+#ifdef CONFIG_MMC
+ rc = trout_init_mmc(system_rev);
+ if (rc)
+ printk(KERN_CRIT "%s: MMC init failure (%d)\n", __func__, rc);
+#endif
+
+}
+
+static struct map_desc trout_io_desc[] __initdata = {
+ {
+ .virtual = TROUT_CPLD_BASE,
+ .pfn = __phys_to_pfn(TROUT_CPLD_START),
+ .length = TROUT_CPLD_SIZE,
+ .type = MT_DEVICE_NONSHARED
+ }
+};
+
+static void __init trout_map_io(void)
+{
+ msm_map_common_io();
+ iotable_init(trout_io_desc, ARRAY_SIZE(trout_io_desc));
+
+#ifdef CONFIG_MSM_DEBUG_UART3
+ /* route UART3 to the "H2W" extended usb connector */
+ writeb(0x80, TROUT_CPLD_BASE + 0x00);
+#endif
+
+ msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a);
+}
+
+MACHINE_START(TROUT, "HTC Dream")
+ .boot_params = 0x10000100,
+ .fixup = trout_fixup,
+ .map_io = trout_map_io,
+ .init_irq = trout_init_irq,
+ .init_machine = trout_init,
+ .timer = &msm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-trout.h b/arch/arm/mach-msm/board-trout.h
new file mode 100644
index 00000000..651851c3
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout.h
@@ -0,0 +1,162 @@
+/* linux/arch/arm/mach-msm/board-trout.h
+** Author: Brian Swetland <swetland@google.com>
+*/
+#ifndef __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
+#define __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
+
+#include <mach/board.h>
+
+#define MSM_SMI_BASE 0x00000000
+#define MSM_SMI_SIZE 0x00800000
+
+#define MSM_EBI_BASE 0x10000000
+#define MSM_EBI_SIZE 0x06e00000
+
+#define MSM_PMEM_GPU0_BASE 0x00000000
+#define MSM_PMEM_GPU0_SIZE 0x00700000
+
+#define MSM_PMEM_MDP_BASE 0x02000000
+#define MSM_PMEM_MDP_SIZE 0x00800000
+
+#define MSM_PMEM_ADSP_BASE 0x02800000
+#define MSM_PMEM_ADSP_SIZE 0x00800000
+
+#define MSM_PMEM_CAMERA_BASE 0x03000000
+#define MSM_PMEM_CAMERA_SIZE 0x00800000
+
+#define MSM_FB_BASE 0x03800000
+#define MSM_FB_SIZE 0x00100000
+
+#define MSM_LINUX_BASE MSM_EBI_BASE
+#define MSM_LINUX_SIZE 0x06500000
+
+#define MSM_PMEM_GPU1_SIZE 0x800000
+#define MSM_PMEM_GPU1_BASE (MSM_RAM_CONSOLE_BASE - MSM_PMEM_GPU1_SIZE)
+
+#define MSM_RAM_CONSOLE_BASE (MSM_EBI_BASE + 0x6d00000)
+#define MSM_RAM_CONSOLE_SIZE (128 * SZ_1K)
+
+#if (MSM_FB_BASE + MSM_FB_SIZE) >= (MSM_PMEM_GPU1_BASE)
+#error invalid memory map
+#endif
+
+#define DECLARE_MSM_IOMAP
+#include <mach/msm_iomap.h>
+
+#define TROUT_4_BALL_UP_0 1
+#define TROUT_4_BALL_LEFT_0 18
+#define TROUT_4_BALL_DOWN_0 57
+#define TROUT_4_BALL_RIGHT_0 91
+
+#define TROUT_5_BALL_UP_0 94
+#define TROUT_5_BALL_LEFT_0 18
+#define TROUT_5_BALL_DOWN_0 90
+#define TROUT_5_BALL_RIGHT_0 19
+
+#define TROUT_POWER_KEY 20
+
+#define TROUT_4_TP_LS_EN 19
+#define TROUT_5_TP_LS_EN 1
+
+#define TROUT_CPLD_BASE 0xE8100000
+#define TROUT_CPLD_START 0x98000000
+#define TROUT_CPLD_SIZE SZ_4K
+
+#define TROUT_GPIO_CABLE_IN1 (83)
+#define TROUT_GPIO_CABLE_IN2 (49)
+
+#define TROUT_GPIO_START (128)
+
+#define TROUT_GPIO_INT_MASK0_REG (0x0c)
+#define TROUT_GPIO_INT_STAT0_REG (0x0e)
+#define TROUT_GPIO_INT_MASK1_REG (0x14)
+#define TROUT_GPIO_INT_STAT1_REG (0x10)
+
+#define TROUT_GPIO_HAPTIC_PWM (28)
+#define TROUT_GPIO_PS_HOLD (25)
+
+#define TROUT_GPIO_MISC2_BASE (TROUT_GPIO_START + 0x00)
+#define TROUT_GPIO_MISC3_BASE (TROUT_GPIO_START + 0x08)
+#define TROUT_GPIO_MISC4_BASE (TROUT_GPIO_START + 0x10)
+#define TROUT_GPIO_MISC5_BASE (TROUT_GPIO_START + 0x18)
+#define TROUT_GPIO_INT2_BASE (TROUT_GPIO_START + 0x20)
+#define TROUT_GPIO_MISC1_BASE (TROUT_GPIO_START + 0x28)
+#define TROUT_GPIO_VIRTUAL_BASE (TROUT_GPIO_START + 0x30)
+#define TROUT_GPIO_INT5_BASE (TROUT_GPIO_START + 0x48)
+
+#define TROUT_GPIO_CHARGER_EN (TROUT_GPIO_MISC2_BASE + 0)
+#define TROUT_GPIO_ISET (TROUT_GPIO_MISC2_BASE + 1)
+#define TROUT_GPIO_H2W_DAT_DIR (TROUT_GPIO_MISC2_BASE + 2)
+#define TROUT_GPIO_H2W_CLK_DIR (TROUT_GPIO_MISC2_BASE + 3)
+#define TROUT_GPIO_H2W_DAT_GPO (TROUT_GPIO_MISC2_BASE + 4)
+#define TROUT_GPIO_H2W_CLK_GPO (TROUT_GPIO_MISC2_BASE + 5)
+#define TROUT_GPIO_H2W_SEL0 (TROUT_GPIO_MISC2_BASE + 6)
+#define TROUT_GPIO_H2W_SEL1 (TROUT_GPIO_MISC2_BASE + 7)
+
+#define TROUT_GPIO_SPOTLIGHT_EN (TROUT_GPIO_MISC3_BASE + 0)
+#define TROUT_GPIO_FLASH_EN (TROUT_GPIO_MISC3_BASE + 1)
+#define TROUT_GPIO_I2C_PULL (TROUT_GPIO_MISC3_BASE + 2)
+#define TROUT_GPIO_TP_I2C_PULL (TROUT_GPIO_MISC3_BASE + 3)
+#define TROUT_GPIO_TP_EN (TROUT_GPIO_MISC3_BASE + 4)
+#define TROUT_GPIO_JOG_EN (TROUT_GPIO_MISC3_BASE + 5)
+#define TROUT_GPIO_UI_LED_EN (TROUT_GPIO_MISC3_BASE + 6)
+#define TROUT_GPIO_QTKEY_LED_EN (TROUT_GPIO_MISC3_BASE + 7)
+
+#define TROUT_GPIO_VCM_PWDN (TROUT_GPIO_MISC4_BASE + 0)
+#define TROUT_GPIO_USB_H2W_SW (TROUT_GPIO_MISC4_BASE + 1)
+#define TROUT_GPIO_COMPASS_RST_N (TROUT_GPIO_MISC4_BASE + 2)
+#define TROUT_GPIO_HAPTIC_EN_UP (TROUT_GPIO_MISC4_BASE + 3)
+#define TROUT_GPIO_HAPTIC_EN_MAIN (TROUT_GPIO_MISC4_BASE + 4)
+#define TROUT_GPIO_USB_PHY_RST_N (TROUT_GPIO_MISC4_BASE + 5)
+#define TROUT_GPIO_WIFI_PA_RESETX (TROUT_GPIO_MISC4_BASE + 6)
+#define TROUT_GPIO_WIFI_EN (TROUT_GPIO_MISC4_BASE + 7)
+
+#define TROUT_GPIO_BT_32K_EN (TROUT_GPIO_MISC5_BASE + 0)
+#define TROUT_GPIO_MAC_32K_EN (TROUT_GPIO_MISC5_BASE + 1)
+#define TROUT_GPIO_MDDI_32K_EN (TROUT_GPIO_MISC5_BASE + 2)
+#define TROUT_GPIO_COMPASS_32K_EN (TROUT_GPIO_MISC5_BASE + 3)
+
+#define TROUT_GPIO_NAVI_ACT_N (TROUT_GPIO_INT2_BASE + 0)
+#define TROUT_GPIO_COMPASS_IRQ (TROUT_GPIO_INT2_BASE + 1)
+#define TROUT_GPIO_SLIDING_DET (TROUT_GPIO_INT2_BASE + 2)
+#define TROUT_GPIO_AUD_HSMIC_DET_N (TROUT_GPIO_INT2_BASE + 3)
+#define TROUT_GPIO_SD_DOOR_N (TROUT_GPIO_INT2_BASE + 4)
+#define TROUT_GPIO_CAM_BTN_STEP1_N (TROUT_GPIO_INT2_BASE + 5)
+#define TROUT_GPIO_CAM_BTN_STEP2_N (TROUT_GPIO_INT2_BASE + 6)
+#define TROUT_GPIO_TP_ATT_N (TROUT_GPIO_INT2_BASE + 7)
+#define TROUT_GPIO_BANK0_FIRST_INT_SOURCE (TROUT_GPIO_NAVI_ACT_N)
+#define TROUT_GPIO_BANK0_LAST_INT_SOURCE (TROUT_GPIO_TP_ATT_N)
+
+#define TROUT_GPIO_H2W_DAT_GPI (TROUT_GPIO_MISC1_BASE + 0)
+#define TROUT_GPIO_H2W_CLK_GPI (TROUT_GPIO_MISC1_BASE + 1)
+#define TROUT_GPIO_CPLD128_VER_0 (TROUT_GPIO_MISC1_BASE + 4)
+#define TROUT_GPIO_CPLD128_VER_1 (TROUT_GPIO_MISC1_BASE + 5)
+#define TROUT_GPIO_CPLD128_VER_2 (TROUT_GPIO_MISC1_BASE + 6)
+#define TROUT_GPIO_CPLD128_VER_3 (TROUT_GPIO_MISC1_BASE + 7)
+
+#define TROUT_GPIO_SDMC_CD_N (TROUT_GPIO_VIRTUAL_BASE + 0)
+#define TROUT_GPIO_END (TROUT_GPIO_SDMC_CD_N)
+#define TROUT_GPIO_BANK1_FIRST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
+#define TROUT_GPIO_BANK1_LAST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
+
+#define TROUT_GPIO_VIRTUAL_TO_REAL_OFFSET \
+ (TROUT_GPIO_INT5_BASE - TROUT_GPIO_VIRTUAL_BASE)
+
+#define TROUT_INT_START (NR_MSM_IRQS + NR_GPIO_IRQS)
+#define TROUT_INT_BANK0_COUNT (8)
+#define TROUT_INT_BANK1_START (TROUT_INT_START + TROUT_INT_BANK0_COUNT)
+#define TROUT_INT_BANK1_COUNT (1)
+#define TROUT_INT_END (TROUT_INT_START + TROUT_INT_BANK0_COUNT + \
+ TROUT_INT_BANK1_COUNT - 1)
+#define TROUT_GPIO_TO_INT(n) (((n) <= TROUT_GPIO_BANK0_LAST_INT_SOURCE) ? \
+ (TROUT_INT_START - TROUT_GPIO_BANK0_FIRST_INT_SOURCE + (n)) : \
+ (TROUT_INT_BANK1_START - TROUT_GPIO_BANK1_FIRST_INT_SOURCE + (n)))
+
+#define TROUT_INT_TO_BANK(n) ((n - TROUT_INT_START) / TROUT_INT_BANK0_COUNT)
+#define TROUT_INT_TO_MASK(n) (1U << ((n - TROUT_INT_START) & 7))
+#define TROUT_BANK_TO_MASK_REG(bank) \
+ (bank ? TROUT_GPIO_INT_MASK1_REG : TROUT_GPIO_INT_MASK0_REG)
+#define TROUT_BANK_TO_STAT_REG(bank) \
+ (bank ? TROUT_GPIO_INT_STAT1_REG : TROUT_GPIO_INT_STAT0_REG)
+
+#endif /* GUARD */
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h
new file mode 100644
index 00000000..14104453
--- /dev/null
+++ b/arch/arm/mach-msm/clock-7x30.h
@@ -0,0 +1,155 @@
+/* Copyright (c) 2009, 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_CLOCK_7X30_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H
+
+enum {
+ L_7X30_NONE_CLK = -1,
+ L_7X30_ADM_CLK,
+ L_7X30_I2C_CLK,
+ L_7X30_I2C_2_CLK,
+ L_7X30_QUP_I2C_CLK,
+ L_7X30_UART1DM_CLK,
+ L_7X30_UART1DM_P_CLK,
+ L_7X30_UART2DM_CLK,
+ L_7X30_UART2DM_P_CLK,
+ L_7X30_EMDH_CLK,
+ L_7X30_EMDH_P_CLK,
+ L_7X30_PMDH_CLK,
+ L_7X30_PMDH_P_CLK,
+ L_7X30_GRP_2D_CLK,
+ L_7X30_GRP_2D_P_CLK,
+ L_7X30_GRP_3D_SRC_CLK,
+ L_7X30_GRP_3D_CLK,
+ L_7X30_GRP_3D_P_CLK,
+ L_7X30_IMEM_CLK,
+ L_7X30_SDC1_CLK,
+ L_7X30_SDC1_P_CLK,
+ L_7X30_SDC2_CLK,
+ L_7X30_SDC2_P_CLK,
+ L_7X30_SDC3_CLK,
+ L_7X30_SDC3_P_CLK,
+ L_7X30_SDC4_CLK,
+ L_7X30_SDC4_P_CLK,
+ L_7X30_MDP_CLK,
+ L_7X30_MDP_P_CLK,
+ L_7X30_MDP_LCDC_PCLK_CLK,
+ L_7X30_MDP_LCDC_PAD_PCLK_CLK,
+ L_7X30_MDP_VSYNC_CLK,
+ L_7X30_MI2S_CODEC_RX_M_CLK,
+ L_7X30_MI2S_CODEC_RX_S_CLK,
+ L_7X30_MI2S_CODEC_TX_M_CLK,
+ L_7X30_MI2S_CODEC_TX_S_CLK,
+ L_7X30_MI2S_M_CLK,
+ L_7X30_MI2S_S_CLK,
+ L_7X30_LPA_CODEC_CLK,
+ L_7X30_LPA_CORE_CLK,
+ L_7X30_LPA_P_CLK,
+ L_7X30_MIDI_CLK,
+ L_7X30_MDC_CLK,
+ L_7X30_ROTATOR_IMEM_CLK,
+ L_7X30_ROTATOR_P_CLK,
+ L_7X30_SDAC_M_CLK,
+ L_7X30_SDAC_CLK,
+ L_7X30_UART1_CLK,
+ L_7X30_UART2_CLK,
+ L_7X30_UART3_CLK,
+ L_7X30_TV_CLK,
+ L_7X30_TV_DAC_CLK,
+ L_7X30_TV_ENC_CLK,
+ L_7X30_HDMI_CLK,
+ L_7X30_TSIF_REF_CLK,
+ L_7X30_TSIF_P_CLK,
+ L_7X30_USB_HS_SRC_CLK,
+ L_7X30_USB_HS_CLK,
+ L_7X30_USB_HS_CORE_CLK,
+ L_7X30_USB_HS_P_CLK,
+ L_7X30_USB_HS2_CLK,
+ L_7X30_USB_HS2_CORE_CLK,
+ L_7X30_USB_HS2_P_CLK,
+ L_7X30_USB_HS3_CLK,
+ L_7X30_USB_HS3_CORE_CLK,
+ L_7X30_USB_HS3_P_CLK,
+ L_7X30_VFE_CLK,
+ L_7X30_VFE_P_CLK,
+ L_7X30_VFE_MDC_CLK,
+ L_7X30_VFE_CAMIF_CLK,
+ L_7X30_CAMIF_PAD_P_CLK,
+ L_7X30_CAM_M_CLK,
+ L_7X30_JPEG_CLK,
+ L_7X30_JPEG_P_CLK,
+ L_7X30_VPE_CLK,
+ L_7X30_MFC_CLK,
+ L_7X30_MFC_DIV2_CLK,
+ L_7X30_MFC_P_CLK,
+ L_7X30_SPI_CLK,
+ L_7X30_SPI_P_CLK,
+ L_7X30_CSI0_CLK,
+ L_7X30_CSI0_VFE_CLK,
+ L_7X30_CSI0_P_CLK,
+ L_7X30_CSI1_CLK,
+ L_7X30_CSI1_VFE_CLK,
+ L_7X30_CSI1_P_CLK,
+ L_7X30_GLBL_ROOT_CLK,
+
+ L_7X30_AXI_LI_VG_CLK,
+ L_7X30_AXI_LI_GRP_CLK,
+ L_7X30_AXI_LI_JPEG_CLK,
+ L_7X30_AXI_GRP_2D_CLK,
+ L_7X30_AXI_MFC_CLK,
+ L_7X30_AXI_VPE_CLK,
+ L_7X30_AXI_LI_VFE_CLK,
+ L_7X30_AXI_LI_APPS_CLK,
+ L_7X30_AXI_MDP_CLK,
+ L_7X30_AXI_IMEM_CLK,
+ L_7X30_AXI_LI_ADSP_A_CLK,
+ L_7X30_AXI_ROTATOR_CLK,
+
+ L_7X30_NR_CLKS
+};
+
+struct clk_ops;
+extern struct clk_ops clk_ops_7x30;
+
+struct clk_ops *clk_7x30_is_local(uint32_t id);
+int clk_7x30_init(void);
+
+void pll_enable(uint32_t pll);
+void pll_disable(uint32_t pll);
+
+extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable);
+
+#define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) { \
+ .con_id = clk_name, \
+ .dev_id = clk_dev, \
+ .clk = &(struct clk){ \
+ .id = L_7X30_##clk_id, \
+ .remote_id = P_##clk_id, \
+ .flags = clk_flags, \
+ .dbg_name = #clk_id, \
+ }, \
+ }
+
+#define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) { \
+ .con_id = clk_name, \
+ .dev_id = clk_dev, \
+ .clk = &(struct clk){ \
+ .id = L_7X30_##l_id, \
+ .remote_id = P_##r_id, \
+ .flags = clk_flags, \
+ .dbg_name = #l_id, \
+ .ops = &clk_ops_pcom, \
+ }, \
+ }
+
+#endif
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
new file mode 100644
index 00000000..4886404d
--- /dev/null
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/clk.h>
+#include "clock.h"
+
+static int clock_debug_rate_set(void *data, u64 val)
+{
+ struct clk *clock = data;
+ int ret;
+
+ /* Only increases to max rate will succeed, but that's actually good
+ * for debugging purposes so we don't check for error. */
+ if (clock->flags & CLK_MAX)
+ clk_set_max_rate(clock, val);
+ if (clock->flags & CLK_MIN)
+ ret = clk_set_min_rate(clock, val);
+ else
+ ret = clk_set_rate(clock, val);
+ if (ret != 0)
+ printk(KERN_ERR "clk_set%s_rate failed (%d)\n",
+ (clock->flags & CLK_MIN) ? "_min" : "", ret);
+ return ret;
+}
+
+static int clock_debug_rate_get(void *data, u64 *val)
+{
+ struct clk *clock = data;
+ *val = clk_get_rate(clock);
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get,
+ clock_debug_rate_set, "%llu\n");
+
+static int clock_debug_enable_set(void *data, u64 val)
+{
+ struct clk *clock = data;
+ int rc = 0;
+
+ if (val)
+ rc = clock->ops->enable(clock->id);
+ else
+ clock->ops->disable(clock->id);
+
+ return rc;
+}
+
+static int clock_debug_enable_get(void *data, u64 *val)
+{
+ struct clk *clock = data;
+
+ *val = clock->ops->is_enabled(clock->id);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
+ clock_debug_enable_set, "%llu\n");
+
+static int clock_debug_local_get(void *data, u64 *val)
+{
+ struct clk *clock = data;
+
+ *val = clock->ops->is_local(clock->id);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get,
+ NULL, "%llu\n");
+
+static struct dentry *debugfs_base;
+
+int __init clock_debug_init(void)
+{
+ debugfs_base = debugfs_create_dir("clk", NULL);
+ if (!debugfs_base)
+ return -ENOMEM;
+ return 0;
+}
+
+int __init clock_debug_add(struct clk *clock)
+{
+ char temp[50], *ptr;
+ struct dentry *clk_dir;
+
+ if (!debugfs_base)
+ return -ENOMEM;
+
+ strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
+ for (ptr = temp; *ptr; ptr++)
+ *ptr = tolower(*ptr);
+
+ clk_dir = debugfs_create_dir(temp, debugfs_base);
+ if (!clk_dir)
+ return -ENOMEM;
+
+ if (!debugfs_create_file("rate", S_IRUGO | S_IWUSR, clk_dir,
+ clock, &clock_rate_fops))
+ goto error;
+
+ if (!debugfs_create_file("enable", S_IRUGO | S_IWUSR, clk_dir,
+ clock, &clock_enable_fops))
+ goto error;
+
+ if (!debugfs_create_file("is_local", S_IRUGO, clk_dir, clock,
+ &clock_local_fops))
+ goto error;
+ return 0;
+error:
+ debugfs_remove_recursive(clk_dir);
+ return -ENOMEM;
+}
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
new file mode 100644
index 00000000..63b71131
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/ctype.h>
+#include <linux/stddef.h>
+#include <mach/clk.h>
+
+#include "proc_comm.h"
+#include "clock.h"
+#include "clock-pcom.h"
+
+/*
+ * glue for the proc_comm interface
+ */
+int pc_clk_enable(unsigned id)
+{
+ int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+void pc_clk_disable(unsigned id)
+{
+ msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
+}
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action)
+{
+ int rc;
+
+ if (action == CLK_RESET_ASSERT)
+ rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL);
+ else
+ rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL);
+
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_rate(unsigned id, unsigned rate)
+{
+ /* The rate _might_ be rounded off to the nearest KHz value by the
+ * remote function. So a return value of 0 doesn't necessarily mean
+ * that the exact rate was set successfully.
+ */
+ int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_min_rate(unsigned id, unsigned rate)
+{
+ int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_max_rate(unsigned id, unsigned rate)
+{
+ int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+int pc_clk_set_flags(unsigned id, unsigned flags)
+{
+ int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
+ if (rc < 0)
+ return rc;
+ else
+ return (int)id < 0 ? -EINVAL : 0;
+}
+
+unsigned pc_clk_get_rate(unsigned id)
+{
+ if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
+ return 0;
+ else
+ return id;
+}
+
+unsigned pc_clk_is_enabled(unsigned id)
+{
+ if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
+ return 0;
+ else
+ return id;
+}
+
+long pc_clk_round_rate(unsigned id, unsigned rate)
+{
+
+ /* Not really supported; pc_clk_set_rate() does rounding on it's own. */
+ return rate;
+}
+
+static bool pc_clk_is_local(unsigned id)
+{
+ return false;
+}
+
+struct clk_ops clk_ops_pcom = {
+ .enable = pc_clk_enable,
+ .disable = pc_clk_disable,
+ .auto_off = pc_clk_disable,
+ .reset = pc_clk_reset,
+ .set_rate = pc_clk_set_rate,
+ .set_min_rate = pc_clk_set_min_rate,
+ .set_max_rate = pc_clk_set_max_rate,
+ .set_flags = pc_clk_set_flags,
+ .get_rate = pc_clk_get_rate,
+ .is_enabled = pc_clk_is_enabled,
+ .round_rate = pc_clk_round_rate,
+ .is_local = pc_clk_is_local,
+};
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h
new file mode 100644
index 00000000..974d0032
--- /dev/null
+++ b/arch/arm/mach-msm/clock-pcom.h
@@ -0,0 +1,140 @@
+/* Copyright (c) 2009, 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_CLOCK_PCOM_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H
+
+/* clock IDs used by the modem processor */
+
+#define P_ACPU_CLK 0 /* Applications processor clock */
+#define P_ADM_CLK 1 /* Applications data mover clock */
+#define P_ADSP_CLK 2 /* ADSP clock */
+#define P_EBI1_CLK 3 /* External bus interface 1 clock */
+#define P_EBI2_CLK 4 /* External bus interface 2 clock */
+#define P_ECODEC_CLK 5 /* External CODEC clock */
+#define P_EMDH_CLK 6 /* External MDDI host clock */
+#define P_GP_CLK 7 /* General purpose clock */
+#define P_GRP_3D_CLK 8 /* Graphics clock */
+#define P_I2C_CLK 9 /* I2C clock */
+#define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
+#define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
+#define P_IMEM_CLK 12 /* Internal graphics memory clock */
+#define P_MDC_CLK 13 /* MDDI client clock */
+#define P_MDP_CLK 14 /* Mobile display processor clock */
+#define P_PBUS_CLK 15 /* Peripheral bus clock */
+#define P_PCM_CLK 16 /* PCM clock */
+#define P_PMDH_CLK 17 /* Primary MDDI host clock */
+#define P_SDAC_CLK 18 /* Stereo DAC clock */
+#define P_SDC1_CLK 19 /* Secure Digital Card clocks */
+#define P_SDC1_P_CLK 20
+#define P_SDC2_CLK 21
+#define P_SDC2_P_CLK 22
+#define P_SDC3_CLK 23
+#define P_SDC3_P_CLK 24
+#define P_SDC4_CLK 25
+#define P_SDC4_P_CLK 26
+#define P_TSIF_CLK 27 /* Transport Stream Interface clocks */
+#define P_TSIF_REF_CLK 28
+#define P_TV_DAC_CLK 29 /* TV clocks */
+#define P_TV_ENC_CLK 30
+#define P_UART1_CLK 31 /* UART clocks */
+#define P_UART2_CLK 32
+#define P_UART3_CLK 33
+#define P_UART1DM_CLK 34
+#define P_UART2DM_CLK 35
+#define P_USB_HS_CLK 36 /* High speed USB core clock */
+#define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */
+#define P_USB_OTG_CLK 38 /* Full speed USB clock */
+#define P_VDC_CLK 39 /* Video controller clock */
+#define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */
+#define P_VFE_CLK 41 /* VFE MDDI client clock */
+#define P_MDP_LCDC_PCLK_CLK 42
+#define P_MDP_LCDC_PAD_PCLK_CLK 43
+#define P_MDP_VSYNC_CLK 44
+#define P_SPI_CLK 45
+#define P_VFE_AXI_CLK 46
+#define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */
+#define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */
+#define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */
+#define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */
+#define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */
+#define P_USB_PHY_CLK 52 /* USB PHY clock */
+#define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */
+#define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */
+#define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */
+#define P_CAM_M_CLK 56
+#define P_CAMIF_PAD_P_CLK 57
+#define P_GRP_2D_CLK 58
+#define P_GRP_2D_P_CLK 59
+#define P_I2S_CLK 60
+#define P_JPEG_CLK 61
+#define P_JPEG_P_CLK 62
+#define P_LPA_CODEC_CLK 63
+#define P_LPA_CORE_CLK 64
+#define P_LPA_P_CLK 65
+#define P_MDC_IO_CLK 66
+#define P_MDC_P_CLK 67
+#define P_MFC_CLK 68
+#define P_MFC_DIV2_CLK 69
+#define P_MFC_P_CLK 70
+#define P_QUP_I2C_CLK 71
+#define P_ROTATOR_IMEM_CLK 72
+#define P_ROTATOR_P_CLK 73
+#define P_VFE_CAMIF_CLK 74
+#define P_VFE_P_CLK 75
+#define P_VPE_CLK 76
+#define P_I2C_2_CLK 77
+#define P_MI2S_CODEC_RX_S_CLK 78
+#define P_MI2S_CODEC_RX_M_CLK 79
+#define P_MI2S_CODEC_TX_S_CLK 80
+#define P_MI2S_CODEC_TX_M_CLK 81
+#define P_PMDH_P_CLK 82
+#define P_EMDH_P_CLK 83
+#define P_SPI_P_CLK 84
+#define P_TSIF_P_CLK 85
+#define P_MDP_P_CLK 86
+#define P_SDAC_M_CLK 87
+#define P_MI2S_S_CLK 88
+#define P_MI2S_M_CLK 89
+#define P_AXI_ROTATOR_CLK 90
+#define P_HDMI_CLK 91
+#define P_CSI0_CLK 92
+#define P_CSI0_VFE_CLK 93
+#define P_CSI0_P_CLK 94
+#define P_CSI1_CLK 95
+#define P_CSI1_VFE_CLK 96
+#define P_CSI1_P_CLK 97
+#define P_GSBI_CLK 98
+#define P_GSBI_P_CLK 99
+#define P_CE_CLK 100 /* Crypto engine */
+#define P_CODEC_SSBI_CLK 101
+
+#define P_NR_CLKS 102
+
+struct clk_ops;
+extern struct clk_ops clk_ops_pcom;
+
+int pc_clk_reset(unsigned id, enum clk_reset_action action);
+
+#define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \
+ .con_id = clk_name, \
+ .dev_id = clk_dev, \
+ .clk = &(struct clk){ \
+ .id = P_##clk_id, \
+ .remote_id = P_##clk_id, \
+ .ops = &clk_ops_pcom, \
+ .flags = clk_flags, \
+ .dbg_name = #clk_id, \
+ }, \
+ }
+
+#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
new file mode 100644
index 00000000..22a53766
--- /dev/null
+++ b/arch/arm/mach-msm/clock.c
@@ -0,0 +1,184 @@
+/* arch/arm/mach-msm/clock.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/pm_qos_params.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/clkdev.h>
+
+#include "clock.h"
+
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(clocks);
+
+/*
+ * Standard clock functions defined in include/linux/clk.h
+ */
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&clocks_lock, flags);
+ clk->count++;
+ if (clk->count == 1)
+ clk->ops->enable(clk->id);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&clocks_lock, flags);
+ BUG_ON(clk->count == 0);
+ clk->count--;
+ if (clk->count == 0)
+ clk->ops->disable(clk->id);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_reset(struct clk *clk, enum clk_reset_action action)
+{
+ return clk->ops->reset(clk->remote_id, action);
+}
+EXPORT_SYMBOL(clk_reset);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->ops->get_rate(clk->id);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+ if (clk->flags & CLKFLAG_MAX) {
+ ret = clk->ops->set_max_rate(clk->id, rate);
+ if (ret)
+ return ret;
+ }
+ if (clk->flags & CLKFLAG_MIN) {
+ ret = clk->ops->set_min_rate(clk->id, rate);
+ if (ret)
+ return ret;
+ }
+
+ if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN)
+ return ret;
+
+ return clk->ops->set_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->ops->round_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_min_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->ops->set_min_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_min_rate);
+
+int clk_set_max_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->ops->set_max_rate(clk->id, rate);
+}
+EXPORT_SYMBOL(clk_set_max_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return ERR_PTR(-ENOSYS);
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_flags(struct clk *clk, unsigned long flags)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+ return clk->ops->set_flags(clk->id, flags);
+}
+EXPORT_SYMBOL(clk_set_flags);
+
+/* EBI1 is the only shared clock that several clients want to vote on as of
+ * this commit. If this changes in the future, then it might be better to
+ * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more
+ * generic to support different clocks.
+ */
+static struct clk *ebi1_clk;
+
+void __init msm_clock_init(struct clk_lookup *clock_tbl, unsigned num_clocks)
+{
+ unsigned n;
+
+ mutex_lock(&clocks_mutex);
+ for (n = 0; n < num_clocks; n++) {
+ clkdev_add(&clock_tbl[n]);
+ list_add_tail(&clock_tbl[n].clk->list, &clocks);
+ }
+ mutex_unlock(&clocks_mutex);
+
+ ebi1_clk = clk_get(NULL, "ebi1_clk");
+ BUG_ON(ebi1_clk == NULL);
+
+}
+
+/* The bootloader and/or AMSS may have left various clocks enabled.
+ * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
+ * not been explicitly enabled by a clk_enable() call.
+ */
+static int __init clock_late_init(void)
+{
+ unsigned long flags;
+ struct clk *clk;
+ unsigned count = 0;
+
+ clock_debug_init();
+ mutex_lock(&clocks_mutex);
+ list_for_each_entry(clk, &clocks, list) {
+ clock_debug_add(clk);
+ if (clk->flags & CLKFLAG_AUTO_OFF) {
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (!clk->count) {
+ count++;
+ clk->ops->auto_off(clk->id);
+ }
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ }
+ }
+ mutex_unlock(&clocks_mutex);
+ pr_info("clock_late_init() disabled %d unused clocks\n", count);
+ return 0;
+}
+
+late_initcall(clock_late_init);
+
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
new file mode 100644
index 00000000..2c007f60
--- /dev/null
+++ b/arch/arm/mach-msm/clock.h
@@ -0,0 +1,72 @@
+/* arch/arm/mach-msm/clock.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
+#define __ARCH_ARM_MACH_MSM_CLOCK_H
+
+#include <linux/init.h>
+#include <linux/list.h>
+#include <mach/clk.h>
+
+#define CLKFLAG_INVERT 0x00000001
+#define CLKFLAG_NOINVERT 0x00000002
+#define CLKFLAG_NONEST 0x00000004
+#define CLKFLAG_NORESET 0x00000008
+
+#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
+#define CLKFLAG_AUTO_OFF 0x00000200
+#define CLKFLAG_MIN 0x00000400
+#define CLKFLAG_MAX 0x00000800
+
+struct clk_ops {
+ int (*enable)(unsigned id);
+ void (*disable)(unsigned id);
+ void (*auto_off)(unsigned id);
+ int (*reset)(unsigned id, enum clk_reset_action action);
+ int (*set_rate)(unsigned id, unsigned rate);
+ int (*set_min_rate)(unsigned id, unsigned rate);
+ int (*set_max_rate)(unsigned id, unsigned rate);
+ int (*set_flags)(unsigned id, unsigned flags);
+ unsigned (*get_rate)(unsigned id);
+ unsigned (*is_enabled)(unsigned id);
+ long (*round_rate)(unsigned id, unsigned rate);
+ bool (*is_local)(unsigned id);
+};
+
+struct clk {
+ uint32_t id;
+ uint32_t remote_id;
+ uint32_t count;
+ uint32_t flags;
+ struct clk_ops *ops;
+ const char *dbg_name;
+ struct list_head list;
+};
+
+#define OFF CLKFLAG_AUTO_OFF
+#define CLK_MIN CLKFLAG_MIN
+#define CLK_MAX CLKFLAG_MAX
+#define CLK_MINMAX (CLK_MIN | CLK_MAX)
+
+#ifdef CONFIG_DEBUG_FS
+int __init clock_debug_init(void);
+int __init clock_debug_add(struct clk *clock);
+#else
+static inline int __init clock_debug_init(void) { return 0; }
+static inline int __init clock_debug_add(struct clk *clock) { return 0; }
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/devices-iommu.c b/arch/arm/mach-msm/devices-iommu.c
new file mode 100644
index 00000000..24030d0d
--- /dev/null
+++ b/arch/arm/mach-msm/devices-iommu.c
@@ -0,0 +1,911 @@
+/* Copyright (c) 2010-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/bootmem.h>
+#include <mach/irqs.h>
+#include <mach/iommu.h>
+
+static struct resource msm_iommu_jpegd_resources[] = {
+ {
+ .start = 0x07300000,
+ .end = 0x07300000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_JPEGD_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+ .end = SMMU_JPEGD_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vpe_resources[] = {
+ {
+ .start = 0x07400000,
+ .end = 0x07400000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VPE_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VPE_CB_SC_SECURE_IRQ,
+ .end = SMMU_VPE_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_mdp0_resources[] = {
+ {
+ .start = 0x07500000,
+ .end = 0x07500000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_MDP0_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_MDP0_CB_SC_SECURE_IRQ,
+ .end = SMMU_MDP0_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_mdp1_resources[] = {
+ {
+ .start = 0x07600000,
+ .end = 0x07600000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_MDP1_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_MDP1_CB_SC_SECURE_IRQ,
+ .end = SMMU_MDP1_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_rot_resources[] = {
+ {
+ .start = 0x07700000,
+ .end = 0x07700000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_ROT_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_ROT_CB_SC_SECURE_IRQ,
+ .end = SMMU_ROT_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_ijpeg_resources[] = {
+ {
+ .start = 0x07800000,
+ .end = 0x07800000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_IJPEG_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+ .end = SMMU_IJPEG_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vfe_resources[] = {
+ {
+ .start = 0x07900000,
+ .end = 0x07900000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VFE_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VFE_CB_SC_SECURE_IRQ,
+ .end = SMMU_VFE_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vcodec_a_resources[] = {
+ {
+ .start = 0x07A00000,
+ .end = 0x07A00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+ .end = SMMU_VCODEC_A_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_vcodec_b_resources[] = {
+ {
+ .start = 0x07B00000,
+ .end = 0x07B00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+ .end = SMMU_VCODEC_B_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_gfx3d_resources[] = {
+ {
+ .start = 0x07C00000,
+ .end = 0x07C00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX3D_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX3D_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_gfx2d0_resources[] = {
+ {
+ .start = 0x07D00000,
+ .end = 0x07D00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX2D0_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource msm_iommu_gfx2d1_resources[] = {
+ {
+ .start = 0x07E00000,
+ .end = 0x07E00000 + SZ_1M - 1,
+ .name = "physbase",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "nonsecure_irq",
+ .start = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
+ .end = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "secure_irq",
+ .start = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
+ .end = SMMU_GFX2D1_CB_SC_SECURE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msm_root_iommu_dev = {
+ .name = "msm_iommu",
+ .id = -1,
+};
+
+static struct msm_iommu_dev jpegd_iommu = {
+ .name = "jpegd",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev vpe_iommu = {
+ .name = "vpe",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev mdp0_iommu = {
+ .name = "mdp0",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev mdp1_iommu = {
+ .name = "mdp1",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev rot_iommu = {
+ .name = "rot",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev ijpeg_iommu = {
+ .name = "ijpeg",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev vfe_iommu = {
+ .name = "vfe",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev vcodec_a_iommu = {
+ .name = "vcodec_a",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev vcodec_b_iommu = {
+ .name = "vcodec_b",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev gfx3d_iommu = {
+ .name = "gfx3d",
+ .ncb = 3,
+};
+
+static struct msm_iommu_dev gfx2d0_iommu = {
+ .name = "gfx2d0",
+ .ncb = 2,
+};
+
+static struct msm_iommu_dev gfx2d1_iommu = {
+ .name = "gfx2d1",
+ .ncb = 2,
+};
+
+static struct platform_device msm_device_iommu_jpegd = {
+ .name = "msm_iommu",
+ .id = 0,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_jpegd_resources),
+ .resource = msm_iommu_jpegd_resources,
+};
+
+static struct platform_device msm_device_iommu_vpe = {
+ .name = "msm_iommu",
+ .id = 1,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vpe_resources),
+ .resource = msm_iommu_vpe_resources,
+};
+
+static struct platform_device msm_device_iommu_mdp0 = {
+ .name = "msm_iommu",
+ .id = 2,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_mdp0_resources),
+ .resource = msm_iommu_mdp0_resources,
+};
+
+static struct platform_device msm_device_iommu_mdp1 = {
+ .name = "msm_iommu",
+ .id = 3,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_mdp1_resources),
+ .resource = msm_iommu_mdp1_resources,
+};
+
+static struct platform_device msm_device_iommu_rot = {
+ .name = "msm_iommu",
+ .id = 4,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_rot_resources),
+ .resource = msm_iommu_rot_resources,
+};
+
+static struct platform_device msm_device_iommu_ijpeg = {
+ .name = "msm_iommu",
+ .id = 5,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_ijpeg_resources),
+ .resource = msm_iommu_ijpeg_resources,
+};
+
+static struct platform_device msm_device_iommu_vfe = {
+ .name = "msm_iommu",
+ .id = 6,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vfe_resources),
+ .resource = msm_iommu_vfe_resources,
+};
+
+static struct platform_device msm_device_iommu_vcodec_a = {
+ .name = "msm_iommu",
+ .id = 7,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vcodec_a_resources),
+ .resource = msm_iommu_vcodec_a_resources,
+};
+
+static struct platform_device msm_device_iommu_vcodec_b = {
+ .name = "msm_iommu",
+ .id = 8,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_vcodec_b_resources),
+ .resource = msm_iommu_vcodec_b_resources,
+};
+
+static struct platform_device msm_device_iommu_gfx3d = {
+ .name = "msm_iommu",
+ .id = 9,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx3d_resources),
+ .resource = msm_iommu_gfx3d_resources,
+};
+
+static struct platform_device msm_device_iommu_gfx2d0 = {
+ .name = "msm_iommu",
+ .id = 10,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx2d0_resources),
+ .resource = msm_iommu_gfx2d0_resources,
+};
+
+struct platform_device msm_device_iommu_gfx2d1 = {
+ .name = "msm_iommu",
+ .id = 11,
+ .dev = {
+ .parent = &msm_root_iommu_dev.dev,
+ },
+ .num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources),
+ .resource = msm_iommu_gfx2d1_resources,
+};
+
+static struct msm_iommu_ctx_dev jpegd_src_ctx = {
+ .name = "jpegd_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev jpegd_dst_ctx = {
+ .name = "jpegd_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_src_ctx = {
+ .name = "vpe_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev vpe_dst_ctx = {
+ .name = "vpe_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg1_ctx = {
+ .name = "mdp_vg1",
+ .num = 0,
+ .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb1_ctx = {
+ .name = "mdp_rgb1",
+ .num = 1,
+ .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_vg2_ctx = {
+ .name = "mdp_vg2",
+ .num = 0,
+ .mids = {0, 2, -1}
+};
+
+static struct msm_iommu_ctx_dev mdp_rgb2_ctx = {
+ .name = "mdp_rgb2",
+ .num = 1,
+ .mids = {1, 3, 4, 5, 6, 7, 8, 9, 10, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_src_ctx = {
+ .name = "rot_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev rot_dst_ctx = {
+ .name = "rot_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_src_ctx = {
+ .name = "ijpeg_src",
+ .num = 0,
+ .mids = {0, -1}
+};
+
+static struct msm_iommu_ctx_dev ijpeg_dst_ctx = {
+ .name = "ijpeg_dst",
+ .num = 1,
+ .mids = {1, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_imgwr_ctx = {
+ .name = "vfe_imgwr",
+ .num = 0,
+ .mids = {2, 3, 4, 5, 6, 7, 8, -1}
+};
+
+static struct msm_iommu_ctx_dev vfe_misc_ctx = {
+ .name = "vfe_misc",
+ .num = 1,
+ .mids = {0, 1, 9, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_stream_ctx = {
+ .name = "vcodec_a_stream",
+ .num = 0,
+ .mids = {2, 5, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_a_mm1_ctx = {
+ .name = "vcodec_a_mm1",
+ .num = 1,
+ .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = {
+ .name = "vcodec_b_mm2",
+ .num = 0,
+ .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_user_ctx = {
+ .name = "gfx3d_user",
+ .num = 0,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx3d_priv_ctx = {
+ .name = "gfx3d_priv",
+ .num = 1,
+ .mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = {
+ .name = "gfx2d0_2d0",
+ .num = 0,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
+};
+
+static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = {
+ .name = "gfx2d1_2d1",
+ .num = 0,
+ .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1}
+};
+
+static struct platform_device msm_device_jpegd_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 0,
+ .dev = {
+ .parent = &msm_device_iommu_jpegd.dev,
+ },
+};
+
+static struct platform_device msm_device_jpegd_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 1,
+ .dev = {
+ .parent = &msm_device_iommu_jpegd.dev,
+ },
+};
+
+static struct platform_device msm_device_vpe_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 2,
+ .dev = {
+ .parent = &msm_device_iommu_vpe.dev,
+ },
+};
+
+static struct platform_device msm_device_vpe_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 3,
+ .dev = {
+ .parent = &msm_device_iommu_vpe.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_vg1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 4,
+ .dev = {
+ .parent = &msm_device_iommu_mdp0.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_rgb1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 5,
+ .dev = {
+ .parent = &msm_device_iommu_mdp0.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_vg2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 6,
+ .dev = {
+ .parent = &msm_device_iommu_mdp1.dev,
+ },
+};
+
+static struct platform_device msm_device_mdp_rgb2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 7,
+ .dev = {
+ .parent = &msm_device_iommu_mdp1.dev,
+ },
+};
+
+static struct platform_device msm_device_rot_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 8,
+ .dev = {
+ .parent = &msm_device_iommu_rot.dev,
+ },
+};
+
+static struct platform_device msm_device_rot_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 9,
+ .dev = {
+ .parent = &msm_device_iommu_rot.dev,
+ },
+};
+
+static struct platform_device msm_device_ijpeg_src_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 10,
+ .dev = {
+ .parent = &msm_device_iommu_ijpeg.dev,
+ },
+};
+
+static struct platform_device msm_device_ijpeg_dst_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 11,
+ .dev = {
+ .parent = &msm_device_iommu_ijpeg.dev,
+ },
+};
+
+static struct platform_device msm_device_vfe_imgwr_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 12,
+ .dev = {
+ .parent = &msm_device_iommu_vfe.dev,
+ },
+};
+
+static struct platform_device msm_device_vfe_misc_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 13,
+ .dev = {
+ .parent = &msm_device_iommu_vfe.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_a_stream_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 14,
+ .dev = {
+ .parent = &msm_device_iommu_vcodec_a.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_a_mm1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 15,
+ .dev = {
+ .parent = &msm_device_iommu_vcodec_a.dev,
+ },
+};
+
+static struct platform_device msm_device_vcodec_b_mm2_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 16,
+ .dev = {
+ .parent = &msm_device_iommu_vcodec_b.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d_user_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 17,
+ .dev = {
+ .parent = &msm_device_iommu_gfx3d.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx3d_priv_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 18,
+ .dev = {
+ .parent = &msm_device_iommu_gfx3d.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx2d0_2d0_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 19,
+ .dev = {
+ .parent = &msm_device_iommu_gfx2d0.dev,
+ },
+};
+
+static struct platform_device msm_device_gfx2d1_2d1_ctx = {
+ .name = "msm_iommu_ctx",
+ .id = 20,
+ .dev = {
+ .parent = &msm_device_iommu_gfx2d1.dev,
+ },
+};
+
+static struct platform_device *msm_iommu_devs[] = {
+ &msm_device_iommu_jpegd,
+ &msm_device_iommu_vpe,
+ &msm_device_iommu_mdp0,
+ &msm_device_iommu_mdp1,
+ &msm_device_iommu_rot,
+ &msm_device_iommu_ijpeg,
+ &msm_device_iommu_vfe,
+ &msm_device_iommu_vcodec_a,
+ &msm_device_iommu_vcodec_b,
+ &msm_device_iommu_gfx3d,
+ &msm_device_iommu_gfx2d0,
+ &msm_device_iommu_gfx2d1,
+};
+
+static struct msm_iommu_dev *msm_iommu_data[] = {
+ &jpegd_iommu,
+ &vpe_iommu,
+ &mdp0_iommu,
+ &mdp1_iommu,
+ &rot_iommu,
+ &ijpeg_iommu,
+ &vfe_iommu,
+ &vcodec_a_iommu,
+ &vcodec_b_iommu,
+ &gfx3d_iommu,
+ &gfx2d0_iommu,
+ &gfx2d1_iommu,
+};
+
+static struct platform_device *msm_iommu_ctx_devs[] = {
+ &msm_device_jpegd_src_ctx,
+ &msm_device_jpegd_dst_ctx,
+ &msm_device_vpe_src_ctx,
+ &msm_device_vpe_dst_ctx,
+ &msm_device_mdp_vg1_ctx,
+ &msm_device_mdp_rgb1_ctx,
+ &msm_device_mdp_vg2_ctx,
+ &msm_device_mdp_rgb2_ctx,
+ &msm_device_rot_src_ctx,
+ &msm_device_rot_dst_ctx,
+ &msm_device_ijpeg_src_ctx,
+ &msm_device_ijpeg_dst_ctx,
+ &msm_device_vfe_imgwr_ctx,
+ &msm_device_vfe_misc_ctx,
+ &msm_device_vcodec_a_stream_ctx,
+ &msm_device_vcodec_a_mm1_ctx,
+ &msm_device_vcodec_b_mm2_ctx,
+ &msm_device_gfx3d_user_ctx,
+ &msm_device_gfx3d_priv_ctx,
+ &msm_device_gfx2d0_2d0_ctx,
+ &msm_device_gfx2d1_2d1_ctx,
+};
+
+static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = {
+ &jpegd_src_ctx,
+ &jpegd_dst_ctx,
+ &vpe_src_ctx,
+ &vpe_dst_ctx,
+ &mdp_vg1_ctx,
+ &mdp_rgb1_ctx,
+ &mdp_vg2_ctx,
+ &mdp_rgb2_ctx,
+ &rot_src_ctx,
+ &rot_dst_ctx,
+ &ijpeg_src_ctx,
+ &ijpeg_dst_ctx,
+ &vfe_imgwr_ctx,
+ &vfe_misc_ctx,
+ &vcodec_a_stream_ctx,
+ &vcodec_a_mm1_ctx,
+ &vcodec_b_mm2_ctx,
+ &gfx3d_user_ctx,
+ &gfx3d_priv_ctx,
+ &gfx2d0_2d0_ctx,
+ &gfx2d1_2d1_ctx,
+};
+
+static int __init msm8x60_iommu_init(void)
+{
+ int ret, i;
+
+ ret = platform_device_register(&msm_root_iommu_dev);
+ if (ret != 0) {
+ pr_err("Failed to register root IOMMU device!\n");
+ goto failure;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); i++) {
+ ret = platform_device_add_data(msm_iommu_devs[i],
+ msm_iommu_data[i],
+ sizeof(struct msm_iommu_dev));
+ if (ret != 0) {
+ pr_err("platform_device_add_data failed, "
+ "i = %d\n", i);
+ goto failure_unwind;
+ }
+
+ ret = platform_device_register(msm_iommu_devs[i]);
+
+ if (ret != 0) {
+ pr_err("platform_device_register iommu failed, "
+ "i = %d\n", i);
+ goto failure_unwind;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++) {
+ ret = platform_device_add_data(msm_iommu_ctx_devs[i],
+ msm_iommu_ctx_data[i],
+ sizeof(*msm_iommu_ctx_devs[i]));
+ if (ret != 0) {
+ pr_err("platform_device_add_data iommu failed, "
+ "i = %d\n", i);
+ goto failure_unwind2;
+ }
+
+ ret = platform_device_register(msm_iommu_ctx_devs[i]);
+ if (ret != 0) {
+ pr_err("platform_device_register ctx failed, "
+ "i = %d\n", i);
+ goto failure_unwind2;
+ }
+ }
+ return 0;
+
+failure_unwind2:
+ while (--i >= 0)
+ platform_device_unregister(msm_iommu_ctx_devs[i]);
+failure_unwind:
+ while (--i >= 0)
+ platform_device_unregister(msm_iommu_devs[i]);
+
+ platform_device_unregister(&msm_root_iommu_dev);
+failure:
+ return ret;
+}
+
+static void __exit msm8x60_iommu_exit(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_ctx_devs); i++)
+ platform_device_unregister(msm_iommu_ctx_devs[i]);
+
+ for (i = 0; i < ARRAY_SIZE(msm_iommu_devs); ++i)
+ platform_device_unregister(msm_iommu_devs[i]);
+
+ platform_device_unregister(&msm_root_iommu_dev);
+}
+
+subsys_initcall(msm8x60_iommu_init);
+module_exit(msm8x60_iommu_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c
new file mode 100644
index 00000000..c4f5e26f
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm7x00.c
@@ -0,0 +1,465 @@
+/* linux/arch/arm/mach-msm/devices.c
+ *
+ * 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/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/clkdev.h>
+
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include "clock.h"
+#include "clock-pcom.h"
+#include <mach/mmc.h>
+
+static struct resource resources_uart1[] = {
+ {
+ .start = INT_UART1,
+ .end = INT_UART1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART1_PHYS,
+ .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "uart_resource"
+ },
+};
+
+static struct resource resources_uart2[] = {
+ {
+ .start = INT_UART2,
+ .end = INT_UART2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART2_PHYS,
+ .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "uart_resource"
+ },
+};
+
+static struct resource resources_uart3[] = {
+ {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART3_PHYS,
+ .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "uart_resource"
+ },
+};
+
+struct platform_device msm_device_uart1 = {
+ .name = "msm_serial",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_uart1),
+ .resource = resources_uart1,
+};
+
+struct platform_device msm_device_uart2 = {
+ .name = "msm_serial",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_uart2),
+ .resource = resources_uart2,
+};
+
+struct platform_device msm_device_uart3 = {
+ .name = "msm_serial",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(resources_uart3),
+ .resource = resources_uart3,
+};
+
+static struct resource resources_i2c[] = {
+ {
+ .start = MSM_I2C_PHYS,
+ .end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_PWB_I2C,
+ .end = INT_PWB_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_i2c = {
+ .name = "msm_i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_i2c),
+ .resource = resources_i2c,
+};
+
+static struct resource resources_hsusb[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb = {
+ .name = "msm_hsusb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb),
+ .resource = resources_hsusb,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct flash_platform_data msm_nand_data = {
+ .parts = NULL,
+ .nr_parts = 0,
+};
+
+static struct resource resources_nand[] = {
+ [0] = {
+ .start = 7,
+ .end = 7,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device msm_device_nand = {
+ .name = "msm_nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_nand),
+ .resource = resources_nand,
+ .dev = {
+ .platform_data = &msm_nand_data,
+ },
+};
+
+struct platform_device msm_device_smd = {
+ .name = "msm_smd",
+ .id = -1,
+};
+
+static struct resource resources_sdc1[] = {
+ {
+ .start = MSM_SDC1_PHYS,
+ .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC1_0,
+ .end = INT_SDC1_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC1_1,
+ .end = INT_SDC1_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc2[] = {
+ {
+ .start = MSM_SDC2_PHYS,
+ .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC2_0,
+ .end = INT_SDC2_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC2_1,
+ .end = INT_SDC2_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc3[] = {
+ {
+ .start = MSM_SDC3_PHYS,
+ .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC3_0,
+ .end = INT_SDC3_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC3_1,
+ .end = INT_SDC3_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc4[] = {
+ {
+ .start = MSM_SDC4_PHYS,
+ .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC4_0,
+ .end = INT_SDC4_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC4_1,
+ .end = INT_SDC4_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device msm_device_sdc1 = {
+ .name = "msm_sdcc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_sdc1),
+ .resource = resources_sdc1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc2 = {
+ .name = "msm_sdcc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(resources_sdc2),
+ .resource = resources_sdc2,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc3 = {
+ .name = "msm_sdcc",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(resources_sdc3),
+ .resource = resources_sdc3,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc4 = {
+ .name = "msm_sdcc",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(resources_sdc4),
+ .resource = resources_sdc4,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device *msm_sdcc_devices[] __initdata = {
+ &msm_device_sdc1,
+ &msm_device_sdc2,
+ &msm_device_sdc3,
+ &msm_device_sdc4,
+};
+
+int __init msm_add_sdcc(unsigned int controller,
+ struct msm_mmc_platform_data *plat,
+ unsigned int stat_irq, unsigned long stat_irq_flags)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+
+ if (controller < 1 || controller > 4)
+ return -EINVAL;
+
+ pdev = msm_sdcc_devices[controller-1];
+ pdev->dev.platform_data = plat;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
+ if (!res)
+ return -EINVAL;
+ else if (stat_irq) {
+ res->start = res->end = stat_irq;
+ res->flags &= ~IORESOURCE_DISABLED;
+ res->flags |= stat_irq_flags;
+ }
+
+ return platform_device_register(pdev);
+}
+
+static struct resource resources_mddi0[] = {
+ {
+ .start = MSM_PMDH_PHYS,
+ .end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MDDI_PRI,
+ .end = INT_MDDI_PRI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource resources_mddi1[] = {
+ {
+ .start = MSM_EMDH_PHYS,
+ .end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MDDI_EXT,
+ .end = INT_MDDI_EXT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_mddi0 = {
+ .name = "msm_mddi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_mddi0),
+ .resource = resources_mddi0,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_mddi1 = {
+ .name = "msm_mddi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_mddi1),
+ .resource = resources_mddi1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_mdp[] = {
+ {
+ .start = MSM_MDP_PHYS,
+ .end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1,
+ .name = "mdp",
+ .flags = IORESOURCE_MEM
+ },
+ {
+ .start = INT_MDP,
+ .end = INT_MDP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_mdp = {
+ .name = "msm_mdp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_mdp),
+ .resource = resources_mdp,
+};
+
+struct clk_lookup msm_clocks_7x01a[] = {
+ CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
+ CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0),
+ CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
+ CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
+ CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF),
+ CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
+ CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF),
+ CLK_PCOM("i2c_clk", I2C_CLK, "msm_i2c.0", 0),
+ CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
+ CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
+ CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
+ CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
+ CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
+ CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0),
+ CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
+ CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
+ CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
+ CLK_PCOM("sdc_clk", SDC1_CLK, "msm_sdcc.1", OFF),
+ CLK_PCOM("sdc_pclk", SDC1_P_CLK, "msm_sdcc.1", OFF),
+ CLK_PCOM("sdc_clk", SDC2_CLK, "msm_sdcc.2", OFF),
+ CLK_PCOM("sdc_pclk", SDC2_P_CLK, "msm_sdcc.2", OFF),
+ CLK_PCOM("sdc_clk", SDC3_CLK, "msm_sdcc.3", OFF),
+ CLK_PCOM("sdc_pclk", SDC3_P_CLK, "msm_sdcc.3", OFF),
+ CLK_PCOM("sdc_clk", SDC4_CLK, "msm_sdcc.4", OFF),
+ CLK_PCOM("sdc_pclk", SDC4_P_CLK, "msm_sdcc.4", OFF),
+ CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
+ CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
+ CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
+ CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
+ CLK_PCOM("uart_clk", UART1_CLK, "msm_serial.0", OFF),
+ CLK_PCOM("uart_clk", UART2_CLK, "msm_serial.1", 0),
+ CLK_PCOM("uart_clk", UART3_CLK, "msm_serial.2", OFF),
+ CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF),
+ CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0),
+ CLK_PCOM("usb_hs_clk", USB_HS_CLK, "msm_hsusb", OFF),
+ CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, "msm_hsusb", OFF),
+ CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
+ CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ),
+ CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
+ CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
+};
+
+unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a);
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
new file mode 100644
index 00000000..09b4f140
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/dma-mapping.h>
+#include <linux/clkdev.h>
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+#include "smd_private.h"
+
+#include <asm/mach/flash.h>
+
+#include "clock-pcom.h"
+#include "clock-7x30.h"
+
+#include <mach/mmc.h>
+
+static struct resource resources_uart2[] = {
+ {
+ .start = INT_UART2,
+ .end = INT_UART2,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART2_PHYS,
+ .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "uart_resource"
+ },
+};
+
+struct platform_device msm_device_uart2 = {
+ .name = "msm_serial",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_uart2),
+ .resource = resources_uart2,
+};
+
+struct platform_device msm_device_smd = {
+ .name = "msm_smd",
+ .id = -1,
+};
+
+static struct resource resources_otg[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_otg = {
+ .name = "msm_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_otg),
+ .resource = resources_otg,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_hsusb[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb = {
+ .name = "msm_hsusb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb),
+ .resource = resources_hsusb,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static u64 dma_mask = 0xffffffffULL;
+static struct resource resources_hsusb_host[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb_host = {
+ .name = "msm_hsusb_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb_host),
+ .resource = resources_hsusb_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffffULL,
+ },
+};
+
+struct clk_lookup msm_clocks_7x30[] = {
+ CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0),
+ CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0),
+ CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF),
+ CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
+ CLK_PCOM("codec_ssbi_clk", CODEC_SSBI_CLK, NULL, 0),
+ CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
+ CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
+ CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
+ CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF),
+ CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
+ CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0),
+ CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0),
+ CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
+ CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0),
+ CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK, NULL, 0),
+ CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0),
+ CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
+ CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF),
+ CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF),
+ CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0),
+ CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0),
+ CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0),
+ CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
+ CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
+ CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0),
+ CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
+ CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0),
+ CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+ CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+ CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
+ CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0),
+ CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0),
+ CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0),
+ CLK_PCOM("mi2s_m_clk", MI2S_M_CLK, NULL, 0),
+ CLK_PCOM("mi2s_s_clk", MI2S_S_CLK, NULL, 0),
+ CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0),
+ CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0),
+ CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0),
+ CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0),
+ CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
+ CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
+ CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0),
+ CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF),
+ CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF),
+ CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
+ CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
+ CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0),
+ CLK_7X30S("tv_src_clk", TV_CLK, TV_ENC_CLK, NULL, 0),
+ CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
+ CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
+ CLK_PCOM("uart_clk", UART2_CLK, "msm_serial.1", 0),
+ CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
+ CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, OFF),
+ CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
+ CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, 0),
+ CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0),
+ CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, 0),
+ CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF),
+ CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0),
+
+ /* 7x30 v2 hardware only. */
+ CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0),
+ CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0),
+ CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0),
+};
+
+unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
+
diff --git a/arch/arm/mach-msm/devices-msm8960.c b/arch/arm/mach-msm/devices-msm8960.c
new file mode 100644
index 00000000..d9e1f264
--- /dev/null
+++ b/arch/arm/mach-msm/devices-msm8960.c
@@ -0,0 +1,85 @@
+/* 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/dma-mapping.h>
+#include <mach/irqs-8960.h>
+#include <mach/board.h>
+
+#include "devices.h"
+
+#define MSM_GSBI2_PHYS 0x16100000
+#define MSM_UART2DM_PHYS (MSM_GSBI2_PHYS + 0x40000)
+
+#define MSM_GSBI5_PHYS 0x16400000
+#define MSM_UART5DM_PHYS (MSM_GSBI5_PHYS + 0x40000)
+
+static struct resource resources_uart_gsbi2[] = {
+ {
+ .start = GSBI2_UARTDM_IRQ,
+ .end = GSBI2_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART2DM_PHYS,
+ .end = MSM_UART2DM_PHYS + PAGE_SIZE - 1,
+ .name = "uart_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI2_PHYS,
+ .end = MSM_GSBI2_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8960_device_uart_gsbi2 = {
+ .name = "msm_serial",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi2),
+ .resource = resources_uart_gsbi2,
+};
+
+static struct resource resources_uart_gsbi5[] = {
+ {
+ .start = GSBI5_UARTDM_IRQ,
+ .end = GSBI5_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART5DM_PHYS,
+ .end = MSM_UART5DM_PHYS + PAGE_SIZE - 1,
+ .name = "uart_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI5_PHYS,
+ .end = MSM_GSBI5_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8960_device_uart_gsbi5 = {
+ .name = "msm_serial",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi5),
+ .resource = resources_uart_gsbi5,
+};
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
new file mode 100644
index 00000000..12d8deb7
--- /dev/null
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/clkdev.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/irqs.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include <mach/board.h>
+
+#include "devices.h"
+
+#include <asm/mach/flash.h>
+
+#include <mach/mmc.h>
+#include "clock-pcom.h"
+
+static struct resource resources_uart3[] = {
+ {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART3_PHYS,
+ .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "uart_resource"
+ },
+};
+
+struct platform_device msm_device_uart3 = {
+ .name = "msm_serial",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(resources_uart3),
+ .resource = resources_uart3,
+};
+
+struct platform_device msm_device_smd = {
+ .name = "msm_smd",
+ .id = -1,
+};
+
+static struct resource resources_otg[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_otg = {
+ .name = "msm_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_otg),
+ .resource = resources_otg,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource resources_hsusb[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb = {
+ .name = "msm_hsusb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb),
+ .resource = resources_hsusb,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static u64 dma_mask = 0xffffffffULL;
+static struct resource resources_hsusb_host[] = {
+ {
+ .start = MSM_HSUSB_PHYS,
+ .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_HS,
+ .end = INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsusb_host = {
+ .name = "msm_hsusb_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsusb_host),
+ .resource = resources_hsusb_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffffULL,
+ },
+};
+
+static struct resource resources_sdc1[] = {
+ {
+ .start = MSM_SDC1_PHYS,
+ .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC1_0,
+ .end = INT_SDC1_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC1_1,
+ .end = INT_SDC1_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc2[] = {
+ {
+ .start = MSM_SDC2_PHYS,
+ .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC2_0,
+ .end = INT_SDC2_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC2_1,
+ .end = INT_SDC2_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc3[] = {
+ {
+ .start = MSM_SDC3_PHYS,
+ .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC3_0,
+ .end = INT_SDC3_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC3_1,
+ .end = INT_SDC3_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct resource resources_sdc4[] = {
+ {
+ .start = MSM_SDC4_PHYS,
+ .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_SDC4_0,
+ .end = INT_SDC4_0,
+ .flags = IORESOURCE_IRQ,
+ .name = "cmd_irq",
+ },
+ {
+ .start = INT_SDC4_1,
+ .end = INT_SDC4_1,
+ .flags = IORESOURCE_IRQ,
+ .name = "pio_irq",
+ },
+ {
+ .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED,
+ .name = "status_irq"
+ },
+ {
+ .start = 8,
+ .end = 8,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device msm_device_sdc1 = {
+ .name = "msm_sdcc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_sdc1),
+ .resource = resources_sdc1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc2 = {
+ .name = "msm_sdcc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(resources_sdc2),
+ .resource = resources_sdc2,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc3 = {
+ .name = "msm_sdcc",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(resources_sdc3),
+ .resource = resources_sdc3,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device msm_device_sdc4 = {
+ .name = "msm_sdcc",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(resources_sdc4),
+ .resource = resources_sdc4,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device *msm_sdcc_devices[] __initdata = {
+ &msm_device_sdc1,
+ &msm_device_sdc2,
+ &msm_device_sdc3,
+ &msm_device_sdc4,
+};
+
+int __init msm_add_sdcc(unsigned int controller,
+ struct msm_mmc_platform_data *plat,
+ unsigned int stat_irq, unsigned long stat_irq_flags)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+
+ if (controller < 1 || controller > 4)
+ return -EINVAL;
+
+ pdev = msm_sdcc_devices[controller-1];
+ pdev->dev.platform_data = plat;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq");
+ if (!res)
+ return -EINVAL;
+ else if (stat_irq) {
+ res->start = res->end = stat_irq;
+ res->flags &= ~IORESOURCE_DISABLED;
+ res->flags |= stat_irq_flags;
+ }
+
+ return platform_device_register(pdev);
+}
+
+struct clk_lookup msm_clocks_8x50[] = {
+ CLK_PCOM("adm_clk", ADM_CLK, NULL, 0),
+ CLK_PCOM("ce_clk", CE_CLK, NULL, 0),
+ CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN),
+ CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0),
+ CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0),
+ CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX),
+ CLK_PCOM("gp_clk", GP_CLK, NULL, 0),
+ CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0),
+ CLK_PCOM("i2c_clk", I2C_CLK, NULL, 0),
+ CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
+ CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
+ CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF),
+ CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0),
+ CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX),
+ CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF),
+ CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0),
+ CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0),
+ CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0),
+ CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN),
+ CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0),
+ CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF),
+ CLK_PCOM("sdc_clk", SDC1_CLK, "msm_sdcc.1", OFF),
+ CLK_PCOM("sdc_pclk", SDC1_P_CLK, "msm_sdcc.1", OFF),
+ CLK_PCOM("sdc_clk", SDC2_CLK, "msm_sdcc.2", OFF),
+ CLK_PCOM("sdc_pclk", SDC2_P_CLK, "msm_sdcc.2", OFF),
+ CLK_PCOM("sdc_clk", SDC3_CLK, "msm_sdcc.3", OFF),
+ CLK_PCOM("sdc_pclk", SDC3_P_CLK, "msm_sdcc.3", OFF),
+ CLK_PCOM("sdc_clk", SDC4_CLK, "msm_sdcc.4", OFF),
+ CLK_PCOM("sdc_pclk", SDC4_P_CLK, "msm_sdcc.4", OFF),
+ CLK_PCOM("spi_clk", SPI_CLK, NULL, 0),
+ CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0),
+ CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
+ CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0),
+ CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0),
+ CLK_PCOM("uart_clk", UART1_CLK, NULL, OFF),
+ CLK_PCOM("uart_clk", UART2_CLK, NULL, 0),
+ CLK_PCOM("uart_clk", UART3_CLK, "msm_serial.2", OFF),
+ CLK_PCOM("uartdm_clk", UART1DM_CLK, NULL, OFF),
+ CLK_PCOM("uartdm_clk", UART2DM_CLK, NULL, 0),
+ CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0),
+ CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN),
+ CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF),
+ CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
+ CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF),
+ CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF),
+ CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0),
+};
+
+unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
+
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
new file mode 100644
index 00000000..9545c196
--- /dev/null
+++ b/arch/arm/mach-msm/devices.h
@@ -0,0 +1,58 @@
+/* linux/arch/arm/mach-msm/devices.h
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
+#define __ARCH_ARM_MACH_MSM_DEVICES_H
+
+#include <linux/clkdev.h>
+
+#include "clock.h"
+
+extern struct platform_device msm_device_uart1;
+extern struct platform_device msm_device_uart2;
+extern struct platform_device msm_device_uart3;
+
+extern struct platform_device msm8960_device_uart_gsbi2;
+extern struct platform_device msm8960_device_uart_gsbi5;
+
+extern struct platform_device msm_device_sdc1;
+extern struct platform_device msm_device_sdc2;
+extern struct platform_device msm_device_sdc3;
+extern struct platform_device msm_device_sdc4;
+
+extern struct platform_device msm_device_hsusb;
+extern struct platform_device msm_device_otg;
+extern struct platform_device msm_device_hsusb_host;
+
+extern struct platform_device msm_device_i2c;
+
+extern struct platform_device msm_device_smd;
+
+extern struct platform_device msm_device_nand;
+
+extern struct platform_device msm_device_mddi0;
+extern struct platform_device msm_device_mddi1;
+extern struct platform_device msm_device_mdp;
+
+extern struct clk_lookup msm_clocks_7x01a[];
+extern unsigned msm_num_clocks_7x01a;
+
+extern struct clk_lookup msm_clocks_7x30[];
+extern unsigned msm_num_clocks_7x30;
+
+extern struct clk_lookup msm_clocks_8x50[];
+extern unsigned msm_num_clocks_8x50;
+
+#endif
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c
new file mode 100644
index 00000000..02cae5e2
--- /dev/null
+++ b/arch/arm/mach-msm/dma.c
@@ -0,0 +1,271 @@
+/* linux/arch/arm/mach-msm/dma.c
+ *
+ * Copyright (C) 2007 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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/completion.h>
+#include <mach/dma.h>
+
+#define MSM_DMOV_CHANNEL_COUNT 16
+
+enum {
+ MSM_DMOV_PRINT_ERRORS = 1,
+ MSM_DMOV_PRINT_IO = 2,
+ MSM_DMOV_PRINT_FLOW = 4
+};
+
+static DEFINE_SPINLOCK(msm_dmov_lock);
+static struct clk *msm_dmov_clk;
+static unsigned int channel_active;
+static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
+static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
+unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
+
+#define MSM_DMOV_DPRINTF(mask, format, args...) \
+ do { \
+ if ((mask) & msm_dmov_print_mask) \
+ printk(KERN_ERR format, args); \
+ } while (0)
+#define PRINT_ERROR(format, args...) \
+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
+#define PRINT_IO(format, args...) \
+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
+#define PRINT_FLOW(format, args...) \
+ MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
+
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
+{
+ writel((graceful << 31), DMOV_FLUSH0(id));
+}
+
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
+{
+ unsigned long irq_flags;
+ unsigned int status;
+
+ spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+ if (!channel_active)
+ clk_enable(msm_dmov_clk);
+ dsb();
+ status = readl(DMOV_STATUS(id));
+ if (list_empty(&ready_commands[id]) &&
+ (status & DMOV_STATUS_CMD_PTR_RDY)) {
+#if 0
+ if (list_empty(&active_commands[id])) {
+ PRINT_FLOW("msm_dmov_enqueue_cmd(%d), enable interrupt\n", id);
+ writel(DMOV_CONFIG_IRQ_EN, DMOV_CONFIG(id));
+ }
+#endif
+ if (cmd->execute_func)
+ cmd->execute_func(cmd);
+ PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
+ list_add_tail(&cmd->list, &active_commands[id]);
+ if (!channel_active)
+ enable_irq(INT_ADM_AARM);
+ channel_active |= 1U << id;
+ writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+ } else {
+ if (!channel_active)
+ clk_disable(msm_dmov_clk);
+ if (list_empty(&active_commands[id]))
+ PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status);
+
+ PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status %x\n", id, status);
+ list_add_tail(&cmd->list, &ready_commands[id]);
+ }
+ spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+}
+
+struct msm_dmov_exec_cmdptr_cmd {
+ struct msm_dmov_cmd dmov_cmd;
+ struct completion complete;
+ unsigned id;
+ unsigned int result;
+ struct msm_dmov_errdata err;
+};
+
+static void
+dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
+ unsigned int result,
+ struct msm_dmov_errdata *err)
+{
+ struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
+ cmd->result = result;
+ if (result != 0x80000002 && err)
+ memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
+
+ complete(&cmd->complete);
+}
+
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
+{
+ struct msm_dmov_exec_cmdptr_cmd cmd;
+
+ PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
+
+ cmd.dmov_cmd.cmdptr = cmdptr;
+ cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
+ cmd.dmov_cmd.execute_func = NULL;
+ cmd.id = id;
+ init_completion(&cmd.complete);
+
+ msm_dmov_enqueue_cmd(id, &cmd.dmov_cmd);
+ wait_for_completion(&cmd.complete);
+
+ if (cmd.result != 0x80000002) {
+ PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
+ PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
+ id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
+ return -EIO;
+ }
+ PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
+ return 0;
+}
+
+
+static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
+{
+ unsigned int int_status, mask, id;
+ unsigned long irq_flags;
+ unsigned int ch_status;
+ unsigned int ch_result;
+ struct msm_dmov_cmd *cmd;
+
+ spin_lock_irqsave(&msm_dmov_lock, irq_flags);
+
+ int_status = readl(DMOV_ISR); /* read and clear interrupt */
+ PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
+
+ while (int_status) {
+ mask = int_status & -int_status;
+ id = fls(mask) - 1;
+ PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
+ int_status &= ~mask;
+ ch_status = readl(DMOV_STATUS(id));
+ if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
+ PRINT_FLOW("msm_datamover_irq_handler id %d, result not valid %x\n", id, ch_status);
+ continue;
+ }
+ do {
+ ch_result = readl(DMOV_RSLT(id));
+ if (list_empty(&active_commands[id])) {
+ PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
+ "with no active command, status %x, result %x\n",
+ id, ch_status, ch_result);
+ cmd = NULL;
+ } else
+ cmd = list_entry(active_commands[id].next, typeof(*cmd), list);
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
+ if (ch_result & DMOV_RSLT_DONE) {
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
+ id, ch_status);
+ PRINT_IO("msm_datamover_irq_handler id %d, got result "
+ "for %p, result %x\n", id, cmd, ch_result);
+ if (cmd) {
+ list_del(&cmd->list);
+ dsb();
+ cmd->complete_func(cmd, ch_result, NULL);
+ }
+ }
+ if (ch_result & DMOV_RSLT_FLUSH) {
+ struct msm_dmov_errdata errdata;
+
+ errdata.flush[0] = readl(DMOV_FLUSH0(id));
+ errdata.flush[1] = readl(DMOV_FLUSH1(id));
+ errdata.flush[2] = readl(DMOV_FLUSH2(id));
+ errdata.flush[3] = readl(DMOV_FLUSH3(id));
+ errdata.flush[4] = readl(DMOV_FLUSH4(id));
+ errdata.flush[5] = readl(DMOV_FLUSH5(id));
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+ PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
+ if (cmd) {
+ list_del(&cmd->list);
+ dsb();
+ cmd->complete_func(cmd, ch_result, &errdata);
+ }
+ }
+ if (ch_result & DMOV_RSLT_ERROR) {
+ struct msm_dmov_errdata errdata;
+
+ errdata.flush[0] = readl(DMOV_FLUSH0(id));
+ errdata.flush[1] = readl(DMOV_FLUSH1(id));
+ errdata.flush[2] = readl(DMOV_FLUSH2(id));
+ errdata.flush[3] = readl(DMOV_FLUSH3(id));
+ errdata.flush[4] = readl(DMOV_FLUSH4(id));
+ errdata.flush[5] = readl(DMOV_FLUSH5(id));
+
+ PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+ PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
+ if (cmd) {
+ list_del(&cmd->list);
+ dsb();
+ cmd->complete_func(cmd, ch_result, &errdata);
+ }
+ /* this does not seem to work, once we get an error */
+ /* the datamover will no longer accept commands */
+ writel(0, DMOV_FLUSH0(id));
+ }
+ ch_status = readl(DMOV_STATUS(id));
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+ if ((ch_status & DMOV_STATUS_CMD_PTR_RDY) && !list_empty(&ready_commands[id])) {
+ cmd = list_entry(ready_commands[id].next, typeof(*cmd), list);
+ list_del(&cmd->list);
+ list_add_tail(&cmd->list, &active_commands[id]);
+ if (cmd->execute_func)
+ cmd->execute_func(cmd);
+ PRINT_FLOW("msm_datamover_irq_handler id %d, start command\n", id);
+ writel(cmd->cmdptr, DMOV_CMD_PTR(id));
+ }
+ } while (ch_status & DMOV_STATUS_RSLT_VALID);
+ if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
+ channel_active &= ~(1U << id);
+ PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
+ }
+
+ if (!channel_active) {
+ disable_irq_nosync(INT_ADM_AARM);
+ clk_disable(msm_dmov_clk);
+ }
+
+ spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
+ return IRQ_HANDLED;
+}
+
+static int __init msm_init_datamover(void)
+{
+ int i;
+ int ret;
+ struct clk *clk;
+
+ for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
+ INIT_LIST_HEAD(&ready_commands[i]);
+ INIT_LIST_HEAD(&active_commands[i]);
+ writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
+ }
+ clk = clk_get(NULL, "adm_clk");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ msm_dmov_clk = clk;
+ ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
+ if (ret)
+ return ret;
+ disable_irq(INT_ADM_AARM);
+ return 0;
+}
+
+arch_initcall(msm_init_datamover);
+
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c
new file mode 100644
index 00000000..cc9c4fd7
--- /dev/null
+++ b/arch/arm/mach-msm/gpio-v2.c
@@ -0,0 +1,433 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/msm_iomap.h>
+#include "gpiomux.h"
+
+/* Bits of interest in the GPIO_IN_OUT register.
+ */
+enum {
+ GPIO_IN = 0,
+ GPIO_OUT = 1
+};
+
+/* Bits of interest in the GPIO_INTR_STATUS register.
+ */
+enum {
+ INTR_STATUS = 0,
+};
+
+/* Bits of interest in the GPIO_CFG register.
+ */
+enum {
+ GPIO_OE = 9,
+};
+
+/* Bits of interest in the GPIO_INTR_CFG register.
+ * When a GPIO triggers, two separate decisions are made, controlled
+ * by two separate flags.
+ *
+ * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS
+ * register for that GPIO will be updated to reflect the triggering of that
+ * gpio. If this bit is 0, this register will not be updated.
+ * - Second, INTR_ENABLE controls whether an interrupt is triggered.
+ *
+ * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt
+ * can be triggered but the status register will not reflect it.
+ */
+enum {
+ INTR_ENABLE = 0,
+ INTR_POL_CTL = 1,
+ INTR_DECT_CTL = 2,
+ INTR_RAW_STATUS_EN = 3,
+};
+
+/* Codes of interest in GPIO_INTR_CFG_SU.
+ */
+enum {
+ TARGET_PROC_SCORPION = 4,
+ TARGET_PROC_NONE = 7,
+};
+
+
+#define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio)))
+#define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio)))
+#define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio)))
+#define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio)))
+#define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio)))
+
+/**
+ * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure
+ *
+ * @enabled_irqs: a bitmap used to optimize the summary-irq handler. By
+ * keeping track of which gpios are unmasked as irq sources, we avoid
+ * having to do readl calls on hundreds of iomapped registers each time
+ * the summary interrupt fires in order to locate the active interrupts.
+ *
+ * @wake_irqs: a bitmap for tracking which interrupt lines are enabled
+ * as wakeup sources. When the device is suspended, interrupts which are
+ * not wakeup sources are disabled.
+ *
+ * @dual_edge_irqs: a bitmap used to track which irqs are configured
+ * as dual-edge, as this is not supported by the hardware and requires
+ * some special handling in the driver.
+ */
+struct msm_gpio_dev {
+ struct gpio_chip gpio_chip;
+ DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS);
+ DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS);
+ DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS);
+};
+
+static DEFINE_SPINLOCK(tlmm_lock);
+
+static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
+{
+ return container_of(chip, struct msm_gpio_dev, gpio_chip);
+}
+
+static inline void set_gpio_bits(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) | n, reg);
+}
+
+static inline void clear_gpio_bits(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) & ~n, reg);
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN);
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset));
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset,
+ int val)
+{
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ msm_gpio_set(chip, offset, val);
+ set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ msm_gpiomux_put(chip->base + offset);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq)
+{
+ return irq - MSM_GPIO_TO_INT(chip->base);
+}
+
+static struct msm_gpio_dev msm_gpio = {
+ .gpio_chip = {
+ .base = 0,
+ .ngpio = NR_GPIO_IRQS,
+ .direction_input = msm_gpio_direction_input,
+ .direction_output = msm_gpio_direction_output,
+ .get = msm_gpio_get,
+ .set = msm_gpio_set,
+ .to_irq = msm_gpio_to_irq,
+ .request = msm_gpio_request,
+ .free = msm_gpio_free,
+ },
+};
+
+/* For dual-edge interrupts in software, since the hardware has no
+ * such support:
+ *
+ * At appropriate moments, this function may be called to flip the polarity
+ * settings of both-edge irq lines to try and catch the next edge.
+ *
+ * The attempt is considered successful if:
+ * - the status bit goes high, indicating that an edge was caught, or
+ * - the input value of the gpio doesn't change during the attempt.
+ * If the value changes twice during the process, that would cause the first
+ * test to fail but would force the second, as two opposite
+ * transitions would cause a detection no matter the polarity setting.
+ *
+ * The do-loop tries to sledge-hammer closed the timing hole between
+ * the initial value-read and the polarity-write - if the line value changes
+ * during that window, an interrupt is lost, the new polarity setting is
+ * incorrect, and the first success test will fail, causing a retry.
+ *
+ * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c.
+ */
+static void msm_gpio_update_dual_edge_pos(unsigned gpio)
+{
+ int loop_limit = 100;
+ unsigned val, val2, intstat;
+
+ do {
+ val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
+ if (val)
+ clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
+ else
+ set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio));
+ val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN);
+ intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS);
+ if (intstat || val == val2)
+ return;
+ } while (loop_limit-- > 0);
+ pr_err("dual-edge irq failed to stabilize, "
+ "interrupts dropped. %#08x != %#08x\n",
+ val, val2);
+}
+
+static void msm_gpio_irq_ack(struct irq_data *d)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+
+ writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
+ if (test_bit(gpio, msm_gpio.dual_edge_irqs))
+ msm_gpio_update_dual_edge_pos(gpio);
+}
+
+static void msm_gpio_irq_mask(struct irq_data *d)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio));
+ clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+ __clear_bit(gpio, msm_gpio.enabled_irqs);
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(struct irq_data *d)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+ __set_bit(gpio, msm_gpio.enabled_irqs);
+ set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio));
+ writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio));
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+ unsigned long irq_flags;
+ uint32_t bits;
+
+ spin_lock_irqsave(&tlmm_lock, irq_flags);
+
+ bits = readl(GPIO_INTR_CFG(gpio));
+
+ if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+ bits |= BIT(INTR_DECT_CTL);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ __set_bit(gpio, msm_gpio.dual_edge_irqs);
+ else
+ __clear_bit(gpio, msm_gpio.dual_edge_irqs);
+ } else {
+ bits &= ~BIT(INTR_DECT_CTL);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ __clear_bit(gpio, msm_gpio.dual_edge_irqs);
+ }
+
+ if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+ bits |= BIT(INTR_POL_CTL);
+ else
+ bits &= ~BIT(INTR_POL_CTL);
+
+ writel(bits, GPIO_INTR_CFG(gpio));
+
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ msm_gpio_update_dual_edge_pos(gpio);
+
+ spin_unlock_irqrestore(&tlmm_lock, irq_flags);
+
+ return 0;
+}
+
+/*
+ * When the summary IRQ is raised, any number of GPIO lines may be high.
+ * It is the job of the summary handler to find all those GPIO lines
+ * which have been set as summary IRQ lines and which are triggered,
+ * and to call their interrupt handlers.
+ */
+static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long i;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+
+ for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
+ i < NR_GPIO_IRQS;
+ i = find_next_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS, i + 1)) {
+ if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS))
+ generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
+ i));
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
+
+ if (on) {
+ if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
+ irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+ set_bit(gpio, msm_gpio.wake_irqs);
+ } else {
+ clear_bit(gpio, msm_gpio.wake_irqs);
+ if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
+ irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+ }
+
+ return 0;
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msmgpio",
+ .irq_mask = msm_gpio_irq_mask,
+ .irq_unmask = msm_gpio_irq_unmask,
+ .irq_ack = msm_gpio_irq_ack,
+ .irq_set_type = msm_gpio_irq_set_type,
+ .irq_set_wake = msm_gpio_irq_set_wake,
+};
+
+static int __devinit msm_gpio_probe(struct platform_device *dev)
+{
+ int i, irq, ret;
+
+ bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
+ bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS);
+ bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS);
+ msm_gpio.gpio_chip.label = dev->name;
+ ret = gpiochip_add(&msm_gpio.gpio_chip);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
+ irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
+ irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
+ msm_summary_irq_handler);
+ return 0;
+}
+
+static int __devexit msm_gpio_remove(struct platform_device *dev)
+{
+ int ret = gpiochip_remove(&msm_gpio.gpio_chip);
+
+ if (ret < 0)
+ return ret;
+
+ irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+
+ return 0;
+}
+
+static struct platform_driver msm_gpio_driver = {
+ .probe = msm_gpio_probe,
+ .remove = __devexit_p(msm_gpio_remove),
+ .driver = {
+ .name = "msmgpio",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_device msm_device_gpio = {
+ .name = "msmgpio",
+ .id = -1,
+};
+
+static int __init msm_gpio_init(void)
+{
+ int rc;
+
+ rc = platform_driver_register(&msm_gpio_driver);
+ if (!rc) {
+ rc = platform_device_register(&msm_device_gpio);
+ if (rc)
+ platform_driver_unregister(&msm_gpio_driver);
+ }
+
+ return rc;
+}
+
+static void __exit msm_gpio_exit(void)
+{
+ platform_device_unregister(&msm_device_gpio);
+ platform_driver_unregister(&msm_gpio_driver);
+}
+
+postcore_initcall(msm_gpio_init);
+module_exit(msm_gpio_exit);
+
+MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
+MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:msmgpio");
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
new file mode 100644
index 00000000..5ea273b0
--- /dev/null
+++ b/arch/arm/mach-msm/gpio.c
@@ -0,0 +1,376 @@
+/* linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * 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/bitops.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include "gpio_hw.h"
+#include "gpiomux.h"
+
+#define FIRST_GPIO_IRQ MSM_GPIO_TO_INT(0)
+
+#define MSM_GPIO_BANK(bank, first, last) \
+ { \
+ .regs = { \
+ .out = MSM_GPIO_OUT_##bank, \
+ .in = MSM_GPIO_IN_##bank, \
+ .int_status = MSM_GPIO_INT_STATUS_##bank, \
+ .int_clear = MSM_GPIO_INT_CLEAR_##bank, \
+ .int_en = MSM_GPIO_INT_EN_##bank, \
+ .int_edge = MSM_GPIO_INT_EDGE_##bank, \
+ .int_pos = MSM_GPIO_INT_POS_##bank, \
+ .oe = MSM_GPIO_OE_##bank, \
+ }, \
+ .chip = { \
+ .base = (first), \
+ .ngpio = (last) - (first) + 1, \
+ .get = msm_gpio_get, \
+ .set = msm_gpio_set, \
+ .direction_input = msm_gpio_direction_input, \
+ .direction_output = msm_gpio_direction_output, \
+ .to_irq = msm_gpio_to_irq, \
+ .request = msm_gpio_request, \
+ .free = msm_gpio_free, \
+ } \
+ }
+
+#define MSM_GPIO_BROKEN_INT_CLEAR 1
+
+struct msm_gpio_regs {
+ void __iomem *out;
+ void __iomem *in;
+ void __iomem *int_status;
+ void __iomem *int_clear;
+ void __iomem *int_en;
+ void __iomem *int_edge;
+ void __iomem *int_pos;
+ void __iomem *oe;
+};
+
+struct msm_gpio_chip {
+ spinlock_t lock;
+ struct gpio_chip chip;
+ struct msm_gpio_regs regs;
+#if MSM_GPIO_BROKEN_INT_CLEAR
+ unsigned int_status_copy;
+#endif
+ unsigned int both_edge_detect;
+ unsigned int int_enable[2]; /* 0: awake, 1: sleep */
+};
+
+static int msm_gpio_write(struct msm_gpio_chip *msm_chip,
+ unsigned offset, unsigned on)
+{
+ unsigned mask = BIT(offset);
+ unsigned val;
+
+ val = readl(msm_chip->regs.out);
+ if (on)
+ writel(val | mask, msm_chip->regs.out);
+ else
+ writel(val & ~mask, msm_chip->regs.out);
+ return 0;
+}
+
+static void msm_gpio_update_both_edge_detect(struct msm_gpio_chip *msm_chip)
+{
+ int loop_limit = 100;
+ unsigned pol, val, val2, intstat;
+ do {
+ val = readl(msm_chip->regs.in);
+ pol = readl(msm_chip->regs.int_pos);
+ pol = (pol & ~msm_chip->both_edge_detect) |
+ (~val & msm_chip->both_edge_detect);
+ writel(pol, msm_chip->regs.int_pos);
+ intstat = readl(msm_chip->regs.int_status);
+ val2 = readl(msm_chip->regs.in);
+ if (((val ^ val2) & msm_chip->both_edge_detect & ~intstat) == 0)
+ return;
+ } while (loop_limit-- > 0);
+ printk(KERN_ERR "msm_gpio_update_both_edge_detect, "
+ "failed to reach stable state %x != %x\n", val, val2);
+}
+
+static int msm_gpio_clear_detect_status(struct msm_gpio_chip *msm_chip,
+ unsigned offset)
+{
+ unsigned bit = BIT(offset);
+
+#if MSM_GPIO_BROKEN_INT_CLEAR
+ /* Save interrupts that already triggered before we loose them. */
+ /* Any interrupt that triggers between the read of int_status */
+ /* and the write to int_clear will still be lost though. */
+ msm_chip->int_status_copy |= readl(msm_chip->regs.int_status);
+ msm_chip->int_status_copy &= ~bit;
+#endif
+ writel(bit, msm_chip->regs.int_clear);
+ msm_gpio_update_both_edge_detect(msm_chip);
+ return 0;
+}
+
+static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ writel(readl(msm_chip->regs.oe) & ~BIT(offset), msm_chip->regs.oe);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int
+msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_write(msm_chip, offset, value);
+ writel(readl(msm_chip->regs.oe) | BIT(offset), msm_chip->regs.oe);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_chip;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ return (readl(msm_chip->regs.in) & (1U << offset)) ? 1 : 0;
+}
+
+static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_chip *msm_chip;
+ unsigned long irq_flags;
+
+ msm_chip = container_of(chip, struct msm_gpio_chip, chip);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_write(msm_chip, offset, value);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return MSM_GPIO_TO_INT(chip->base + offset);
+}
+
+#ifdef CONFIG_MSM_GPIOMUX
+static int msm_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ return msm_gpiomux_get(chip->base + offset);
+}
+
+static void msm_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ msm_gpiomux_put(chip->base + offset);
+}
+#else
+#define msm_gpio_request NULL
+#define msm_gpio_free NULL
+#endif
+
+struct msm_gpio_chip msm_gpio_chips[] = {
+#if defined(CONFIG_ARCH_MSM7X00A)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 121),
+#elif defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X27)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 132),
+#elif defined(CONFIG_ARCH_MSM7X30)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 43),
+ MSM_GPIO_BANK(2, 44, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 106),
+ MSM_GPIO_BANK(5, 107, 133),
+ MSM_GPIO_BANK(6, 134, 150),
+ MSM_GPIO_BANK(7, 151, 181),
+#elif defined(CONFIG_ARCH_QSD8X50)
+ MSM_GPIO_BANK(0, 0, 15),
+ MSM_GPIO_BANK(1, 16, 42),
+ MSM_GPIO_BANK(2, 43, 67),
+ MSM_GPIO_BANK(3, 68, 94),
+ MSM_GPIO_BANK(4, 95, 103),
+ MSM_GPIO_BANK(5, 104, 121),
+ MSM_GPIO_BANK(6, 122, 152),
+ MSM_GPIO_BANK(7, 153, 164),
+#endif
+};
+
+static void msm_gpio_irq_ack(struct irq_data *d)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ msm_gpio_clear_detect_status(msm_chip,
+ d->irq - gpio_to_irq(msm_chip->chip.base));
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_mask(struct irq_data *d)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
+ unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ /* level triggered interrupts are also latched */
+ if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+ msm_gpio_clear_detect_status(msm_chip, offset);
+ msm_chip->int_enable[0] &= ~BIT(offset);
+ writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(struct irq_data *d)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
+ unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ /* level triggered interrupts are also latched */
+ if (!(readl(msm_chip->regs.int_edge) & BIT(offset)))
+ msm_gpio_clear_detect_status(msm_chip, offset);
+ msm_chip->int_enable[0] |= BIT(offset);
+ writel(msm_chip->int_enable[0], msm_chip->regs.int_en);
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
+ unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+
+ if (on)
+ msm_chip->int_enable[1] |= BIT(offset);
+ else
+ msm_chip->int_enable[1] &= ~BIT(offset);
+
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_chip *msm_chip = irq_data_get_irq_chip_data(d);
+ unsigned offset = d->irq - gpio_to_irq(msm_chip->chip.base);
+ unsigned val, mask = BIT(offset);
+
+ spin_lock_irqsave(&msm_chip->lock, irq_flags);
+ val = readl(msm_chip->regs.int_edge);
+ if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+ writel(val | mask, msm_chip->regs.int_edge);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ } else {
+ writel(val & ~mask, msm_chip->regs.int_edge);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ }
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+ msm_chip->both_edge_detect |= mask;
+ msm_gpio_update_both_edge_detect(msm_chip);
+ } else {
+ msm_chip->both_edge_detect &= ~mask;
+ val = readl(msm_chip->regs.int_pos);
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+ writel(val | mask, msm_chip->regs.int_pos);
+ else
+ writel(val & ~mask, msm_chip->regs.int_pos);
+ }
+ spin_unlock_irqrestore(&msm_chip->lock, irq_flags);
+ return 0;
+}
+
+static void msm_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i, j, mask;
+ unsigned val;
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+ struct msm_gpio_chip *msm_chip = &msm_gpio_chips[i];
+ val = readl(msm_chip->regs.int_status);
+ val &= msm_chip->int_enable[0];
+ while (val) {
+ mask = val & -val;
+ j = fls(mask) - 1;
+ /* printk("%s %08x %08x bit %d gpio %d irq %d\n",
+ __func__, v, m, j, msm_chip->chip.start + j,
+ FIRST_GPIO_IRQ + msm_chip->chip.start + j); */
+ val &= ~mask;
+ generic_handle_irq(FIRST_GPIO_IRQ +
+ msm_chip->chip.base + j);
+ }
+ }
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msmgpio",
+ .irq_ack = msm_gpio_irq_ack,
+ .irq_mask = msm_gpio_irq_mask,
+ .irq_unmask = msm_gpio_irq_unmask,
+ .irq_set_wake = msm_gpio_irq_set_wake,
+ .irq_set_type = msm_gpio_irq_set_type,
+};
+
+static int __init msm_init_gpio(void)
+{
+ int i, j = 0;
+
+ for (i = FIRST_GPIO_IRQ; i < FIRST_GPIO_IRQ + NR_GPIO_IRQS; i++) {
+ if (i - FIRST_GPIO_IRQ >=
+ msm_gpio_chips[j].chip.base +
+ msm_gpio_chips[j].chip.ngpio)
+ j++;
+ irq_set_chip_data(i, &msm_gpio_chips[j]);
+ irq_set_chip_and_handler(i, &msm_gpio_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_chips); i++) {
+ spin_lock_init(&msm_gpio_chips[i].lock);
+ writel(0, msm_gpio_chips[i].regs.int_en);
+ gpiochip_add(&msm_gpio_chips[i].chip);
+ }
+
+ irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+ irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+ irq_set_irq_wake(INT_GPIO_GROUP1, 1);
+ irq_set_irq_wake(INT_GPIO_GROUP2, 2);
+ return 0;
+}
+
+postcore_initcall(msm_init_gpio);
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644
index 00000000..6b506603
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw.h
@@ -0,0 +1,278 @@
+/* arch/arm/mach-msm/gpio_hw.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+/* see 80-VA736-2 Rev C pp 695-751
+**
+** These are actually the *shadow* gpio registers, since the
+** real ones (which allow full access) are only available to the
+** ARM9 side of the world.
+**
+** Since the _BASE need to be page-aligned when we're mapping them
+** to virtual addresses, adjust for the additional offset in these
+** macros.
+*/
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define MSM_GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define MSM_GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X25) ||\
+ defined(CONFIG_ARCH_MSM7X27)
+
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0)
+
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 42-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-43 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 103-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x10) /* gpio 121-104 */
+#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0x14) /* gpio 152-122 */
+#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x18) /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x20)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x24)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x28)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x2C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x30)
+#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x50)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x58)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x5C)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xC4)
+#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xE4)
+#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xF0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xF4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xF8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xFC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0x100)
+#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0x104)
+#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x108)
+
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+
+/* output value */
+#define MSM_GPIO_OUT_0 MSM_GPIO1_REG(0x00) /* gpio 15-0 */
+#define MSM_GPIO_OUT_1 MSM_GPIO2_REG(0x00) /* gpio 43-16 */
+#define MSM_GPIO_OUT_2 MSM_GPIO1_REG(0x04) /* gpio 67-44 */
+#define MSM_GPIO_OUT_3 MSM_GPIO1_REG(0x08) /* gpio 94-68 */
+#define MSM_GPIO_OUT_4 MSM_GPIO1_REG(0x0C) /* gpio 106-95 */
+#define MSM_GPIO_OUT_5 MSM_GPIO1_REG(0x50) /* gpio 133-107 */
+#define MSM_GPIO_OUT_6 MSM_GPIO1_REG(0xC4) /* gpio 150-134 */
+#define MSM_GPIO_OUT_7 MSM_GPIO1_REG(0x214) /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define MSM_GPIO_OE_0 MSM_GPIO1_REG(0x10)
+#define MSM_GPIO_OE_1 MSM_GPIO2_REG(0x08)
+#define MSM_GPIO_OE_2 MSM_GPIO1_REG(0x14)
+#define MSM_GPIO_OE_3 MSM_GPIO1_REG(0x18)
+#define MSM_GPIO_OE_4 MSM_GPIO1_REG(0x1C)
+#define MSM_GPIO_OE_5 MSM_GPIO1_REG(0x54)
+#define MSM_GPIO_OE_6 MSM_GPIO1_REG(0xC8)
+#define MSM_GPIO_OE_7 MSM_GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define MSM_GPIO_IN_0 MSM_GPIO1_REG(0x34)
+#define MSM_GPIO_IN_1 MSM_GPIO2_REG(0x20)
+#define MSM_GPIO_IN_2 MSM_GPIO1_REG(0x38)
+#define MSM_GPIO_IN_3 MSM_GPIO1_REG(0x3C)
+#define MSM_GPIO_IN_4 MSM_GPIO1_REG(0x40)
+#define MSM_GPIO_IN_5 MSM_GPIO1_REG(0x44)
+#define MSM_GPIO_IN_6 MSM_GPIO1_REG(0xCC)
+#define MSM_GPIO_IN_7 MSM_GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrup */
+#define MSM_GPIO_INT_EDGE_0 MSM_GPIO1_REG(0x60)
+#define MSM_GPIO_INT_EDGE_1 MSM_GPIO2_REG(0x50)
+#define MSM_GPIO_INT_EDGE_2 MSM_GPIO1_REG(0x64)
+#define MSM_GPIO_INT_EDGE_3 MSM_GPIO1_REG(0x68)
+#define MSM_GPIO_INT_EDGE_4 MSM_GPIO1_REG(0x6C)
+#define MSM_GPIO_INT_EDGE_5 MSM_GPIO1_REG(0xC0)
+#define MSM_GPIO_INT_EDGE_6 MSM_GPIO1_REG(0xD0)
+#define MSM_GPIO_INT_EDGE_7 MSM_GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define MSM_GPIO_INT_POS_0 MSM_GPIO1_REG(0x70)
+#define MSM_GPIO_INT_POS_1 MSM_GPIO2_REG(0x58)
+#define MSM_GPIO_INT_POS_2 MSM_GPIO1_REG(0x74)
+#define MSM_GPIO_INT_POS_3 MSM_GPIO1_REG(0x78)
+#define MSM_GPIO_INT_POS_4 MSM_GPIO1_REG(0x7C)
+#define MSM_GPIO_INT_POS_5 MSM_GPIO1_REG(0xBC)
+#define MSM_GPIO_INT_POS_6 MSM_GPIO1_REG(0xD4)
+#define MSM_GPIO_INT_POS_7 MSM_GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define MSM_GPIO_INT_EN_0 MSM_GPIO1_REG(0x80)
+#define MSM_GPIO_INT_EN_1 MSM_GPIO2_REG(0x60)
+#define MSM_GPIO_INT_EN_2 MSM_GPIO1_REG(0x84)
+#define MSM_GPIO_INT_EN_3 MSM_GPIO1_REG(0x88)
+#define MSM_GPIO_INT_EN_4 MSM_GPIO1_REG(0x8C)
+#define MSM_GPIO_INT_EN_5 MSM_GPIO1_REG(0xB8)
+#define MSM_GPIO_INT_EN_6 MSM_GPIO1_REG(0xD8)
+#define MSM_GPIO_INT_EN_7 MSM_GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define MSM_GPIO_INT_CLEAR_0 MSM_GPIO1_REG(0x90)
+#define MSM_GPIO_INT_CLEAR_1 MSM_GPIO2_REG(0x68)
+#define MSM_GPIO_INT_CLEAR_2 MSM_GPIO1_REG(0x94)
+#define MSM_GPIO_INT_CLEAR_3 MSM_GPIO1_REG(0x98)
+#define MSM_GPIO_INT_CLEAR_4 MSM_GPIO1_REG(0x9C)
+#define MSM_GPIO_INT_CLEAR_5 MSM_GPIO1_REG(0xB4)
+#define MSM_GPIO_INT_CLEAR_6 MSM_GPIO1_REG(0xDC)
+#define MSM_GPIO_INT_CLEAR_7 MSM_GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define MSM_GPIO_INT_STATUS_0 MSM_GPIO1_REG(0xA0)
+#define MSM_GPIO_INT_STATUS_1 MSM_GPIO2_REG(0x70)
+#define MSM_GPIO_INT_STATUS_2 MSM_GPIO1_REG(0xA4)
+#define MSM_GPIO_INT_STATUS_3 MSM_GPIO1_REG(0xA8)
+#define MSM_GPIO_INT_STATUS_4 MSM_GPIO1_REG(0xAC)
+#define MSM_GPIO_INT_STATUS_5 MSM_GPIO1_REG(0xB0)
+#define MSM_GPIO_INT_STATUS_6 MSM_GPIO1_REG(0xE0)
+#define MSM_GPIO_INT_STATUS_7 MSM_GPIO1_REG(0x234)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-8x50.c b/arch/arm/mach-msm/gpiomux-8x50.c
new file mode 100644
index 00000000..f7a4ea59
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-8x50.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+#if defined(CONFIG_MMC_MSM) || defined(CONFIG_MMC_MSM_MODULE)
+ #define SDCC_DAT_0_3_CMD_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_UP\
+ | GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
+ #define SDCC_CLK_ACTV_CFG (GPIOMUX_VALID | GPIOMUX_PULL_NONE\
+ | GPIOMUX_FUNC_1 | GPIOMUX_DRV_8MA)
+#else
+ #define SDCC_DAT_0_3_CMD_ACTV_CFG 0
+ #define SDCC_CLK_ACTV_CFG 0
+#endif
+
+#define SDC1_SUSPEND_CONFIG (GPIOMUX_VALID | GPIOMUX_PULL_DOWN\
+ | GPIOMUX_FUNC_GPIO | GPIOMUX_DRV_2MA)
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
+ [86] = { /* UART3 RX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+ },
+ [87] = { /* UART3 TX */
+ .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
+ GPIOMUX_FUNC_1 | GPIOMUX_VALID,
+ },
+ /* SDC1 data[3:0] & CMD */
+ [51 ... 55] = {
+ .active = SDCC_DAT_0_3_CMD_ACTV_CFG,
+ .suspended = SDC1_SUSPEND_CONFIG
+ },
+ /* SDC1 CLK */
+ [56] = {
+ .active = SDCC_CLK_ACTV_CFG,
+ .suspended = SDC1_SUSPEND_CONFIG
+ },
+};
diff --git a/arch/arm/mach-msm/gpiomux-8x60.c b/arch/arm/mach-msm/gpiomux-8x60.c
new file mode 100644
index 00000000..7b380b31
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-8x60.c
@@ -0,0 +1,19 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include "gpiomux.h"
+
+struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
diff --git a/arch/arm/mach-msm/gpiomux-v1.c b/arch/arm/mach-msm/gpiomux-v1.c
new file mode 100644
index 00000000..27de2abd
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v1.c
@@ -0,0 +1,33 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/kernel.h>
+#include "gpiomux.h"
+#include "proc_comm.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+ unsigned tlmm_config = (val & ~GPIOMUX_CTL_MASK) |
+ ((gpio & 0x3ff) << 4);
+ unsigned tlmm_disable = 0;
+ int rc;
+
+ rc = msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+ &tlmm_config, &tlmm_disable);
+ if (rc)
+ pr_err("%s: unexpected proc_comm failure %d: %08x %08x\n",
+ __func__, rc, tlmm_config, tlmm_disable);
+}
diff --git a/arch/arm/mach-msm/gpiomux-v1.h b/arch/arm/mach-msm/gpiomux-v1.h
new file mode 100644
index 00000000..71d86feb
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v1.h
@@ -0,0 +1,67 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V1_H
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIOMUX_NGPIOS 182
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define GPIOMUX_NGPIOS 165
+#else
+#define GPIOMUX_NGPIOS 133
+#endif
+
+typedef u32 gpiomux_config_t;
+
+enum {
+ GPIOMUX_DRV_2MA = 0UL << 17,
+ GPIOMUX_DRV_4MA = 1UL << 17,
+ GPIOMUX_DRV_6MA = 2UL << 17,
+ GPIOMUX_DRV_8MA = 3UL << 17,
+ GPIOMUX_DRV_10MA = 4UL << 17,
+ GPIOMUX_DRV_12MA = 5UL << 17,
+ GPIOMUX_DRV_14MA = 6UL << 17,
+ GPIOMUX_DRV_16MA = 7UL << 17,
+};
+
+enum {
+ GPIOMUX_FUNC_GPIO = 0UL,
+ GPIOMUX_FUNC_1 = 1UL,
+ GPIOMUX_FUNC_2 = 2UL,
+ GPIOMUX_FUNC_3 = 3UL,
+ GPIOMUX_FUNC_4 = 4UL,
+ GPIOMUX_FUNC_5 = 5UL,
+ GPIOMUX_FUNC_6 = 6UL,
+ GPIOMUX_FUNC_7 = 7UL,
+ GPIOMUX_FUNC_8 = 8UL,
+ GPIOMUX_FUNC_9 = 9UL,
+ GPIOMUX_FUNC_A = 10UL,
+ GPIOMUX_FUNC_B = 11UL,
+ GPIOMUX_FUNC_C = 12UL,
+ GPIOMUX_FUNC_D = 13UL,
+ GPIOMUX_FUNC_E = 14UL,
+ GPIOMUX_FUNC_F = 15UL,
+};
+
+enum {
+ GPIOMUX_PULL_NONE = 0UL << 15,
+ GPIOMUX_PULL_DOWN = 1UL << 15,
+ GPIOMUX_PULL_KEEPER = 2UL << 15,
+ GPIOMUX_PULL_UP = 3UL << 15,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux-v2.c b/arch/arm/mach-msm/gpiomux-v2.c
new file mode 100644
index 00000000..273396d2
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v2.c
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/io.h>
+#include <mach/msm_iomap.h>
+#include "gpiomux.h"
+
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+{
+ writel(val & ~GPIOMUX_CTL_MASK,
+ MSM_TLMM_BASE + 0x1000 + (0x10 * gpio));
+}
diff --git a/arch/arm/mach-msm/gpiomux-v2.h b/arch/arm/mach-msm/gpiomux-v2.h
new file mode 100644
index 00000000..3bf10e7f
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux-v2.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_V2_H
+
+#define GPIOMUX_NGPIOS 173
+
+typedef u16 gpiomux_config_t;
+
+enum {
+ GPIOMUX_DRV_2MA = 0UL << 6,
+ GPIOMUX_DRV_4MA = 1UL << 6,
+ GPIOMUX_DRV_6MA = 2UL << 6,
+ GPIOMUX_DRV_8MA = 3UL << 6,
+ GPIOMUX_DRV_10MA = 4UL << 6,
+ GPIOMUX_DRV_12MA = 5UL << 6,
+ GPIOMUX_DRV_14MA = 6UL << 6,
+ GPIOMUX_DRV_16MA = 7UL << 6,
+};
+
+enum {
+ GPIOMUX_FUNC_GPIO = 0UL << 2,
+ GPIOMUX_FUNC_1 = 1UL << 2,
+ GPIOMUX_FUNC_2 = 2UL << 2,
+ GPIOMUX_FUNC_3 = 3UL << 2,
+ GPIOMUX_FUNC_4 = 4UL << 2,
+ GPIOMUX_FUNC_5 = 5UL << 2,
+ GPIOMUX_FUNC_6 = 6UL << 2,
+ GPIOMUX_FUNC_7 = 7UL << 2,
+ GPIOMUX_FUNC_8 = 8UL << 2,
+ GPIOMUX_FUNC_9 = 9UL << 2,
+ GPIOMUX_FUNC_A = 10UL << 2,
+ GPIOMUX_FUNC_B = 11UL << 2,
+ GPIOMUX_FUNC_C = 12UL << 2,
+ GPIOMUX_FUNC_D = 13UL << 2,
+ GPIOMUX_FUNC_E = 14UL << 2,
+ GPIOMUX_FUNC_F = 15UL << 2,
+};
+
+enum {
+ GPIOMUX_PULL_NONE = 0UL,
+ GPIOMUX_PULL_DOWN = 1UL,
+ GPIOMUX_PULL_KEEPER = 2UL,
+ GPIOMUX_PULL_UP = 3UL,
+};
+
+#endif
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
new file mode 100644
index 00000000..53af21ab
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -0,0 +1,96 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include "gpiomux.h"
+
+static DEFINE_SPINLOCK(gpiomux_lock);
+
+int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+ gpiomux_config_t setting;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+
+ if (active & GPIOMUX_VALID)
+ cfg->active = active;
+
+ if (suspended & GPIOMUX_VALID)
+ cfg->suspended = suspended;
+
+ setting = cfg->ref ? active : suspended;
+ if (setting & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, setting);
+
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_write);
+
+int msm_gpiomux_get(unsigned gpio)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+ if (cfg->ref++ == 0 && cfg->active & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, cfg->active);
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_get);
+
+int msm_gpiomux_put(unsigned gpio)
+{
+ struct msm_gpiomux_config *cfg = msm_gpiomux_configs + gpio;
+ unsigned long irq_flags;
+
+ if (gpio >= GPIOMUX_NGPIOS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&gpiomux_lock, irq_flags);
+ BUG_ON(cfg->ref == 0);
+ if (--cfg->ref == 0 && cfg->suspended & GPIOMUX_VALID)
+ __msm_gpiomux_write(gpio, cfg->suspended);
+ spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
+ return 0;
+}
+EXPORT_SYMBOL(msm_gpiomux_put);
+
+static int __init gpiomux_init(void)
+{
+ unsigned n;
+
+ for (n = 0; n < GPIOMUX_NGPIOS; ++n) {
+ msm_gpiomux_configs[n].ref = 0;
+ if (!(msm_gpiomux_configs[n].suspended & GPIOMUX_VALID))
+ continue;
+ __msm_gpiomux_write(n, msm_gpiomux_configs[n].suspended);
+ }
+ return 0;
+}
+postcore_initcall(gpiomux_init);
diff --git a/arch/arm/mach-msm/gpiomux.h b/arch/arm/mach-msm/gpiomux.h
new file mode 100644
index 00000000..b178d9cb
--- /dev/null
+++ b/arch/arm/mach-msm/gpiomux.h
@@ -0,0 +1,114 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIOMUX_H
+#define __ARCH_ARM_MACH_MSM_GPIOMUX_H
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+
+#if defined(CONFIG_MSM_V2_TLMM)
+#include "gpiomux-v2.h"
+#else
+#include "gpiomux-v1.h"
+#endif
+
+/**
+ * struct msm_gpiomux_config: gpiomux settings for one gpio line.
+ *
+ * A complete gpiomux config is the bitwise-or of a drive-strength,
+ * function, and pull. For functions other than GPIO, the OE
+ * is hard-wired according to the function. For GPIO mode,
+ * OE is controlled by gpiolib.
+ *
+ * Available settings differ by target; see the gpiomux header
+ * specific to your target arch for available configurations.
+ *
+ * @active: The configuration to be installed when the line is
+ * active, or its reference count is > 0.
+ * @suspended: The configuration to be installed when the line
+ * is suspended, or its reference count is 0.
+ * @ref: The reference count of the line. For internal use of
+ * the gpiomux framework only.
+ */
+struct msm_gpiomux_config {
+ gpiomux_config_t active;
+ gpiomux_config_t suspended;
+ unsigned ref;
+};
+
+/**
+ * @GPIOMUX_VALID: If set, the config field contains 'good data'.
+ * The absence of this bit will prevent the gpiomux
+ * system from applying the configuration under all
+ * circumstances.
+ */
+enum {
+ GPIOMUX_VALID = BIT(sizeof(gpiomux_config_t) * BITS_PER_BYTE - 1),
+ GPIOMUX_CTL_MASK = GPIOMUX_VALID,
+};
+
+#ifdef CONFIG_MSM_GPIOMUX
+
+/* Each architecture must provide its own instance of this table.
+ * To avoid having gpiomux manage any given gpio, one or both of
+ * the entries can avoid setting GPIOMUX_VALID - the absence
+ * of that flag will prevent the configuration from being applied
+ * during state transitions.
+ */
+extern struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS];
+
+/* Increment a gpio's reference count, possibly activating the line. */
+int __must_check msm_gpiomux_get(unsigned gpio);
+
+/* Decrement a gpio's reference count, possibly suspending the line. */
+int msm_gpiomux_put(unsigned gpio);
+
+/* Install a new configuration to the gpio line. To avoid overwriting
+ * a configuration, leave the VALID bit out.
+ */
+int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended);
+
+/* Architecture-internal function for use by the framework only.
+ * This function can assume the following:
+ * - the gpio value has passed a bounds-check
+ * - the gpiomux spinlock has been obtained
+ *
+ * This function is not for public consumption. External users
+ * should use msm_gpiomux_write.
+ */
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val);
+#else
+static inline int __must_check msm_gpiomux_get(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int msm_gpiomux_put(unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+static inline int msm_gpiomux_write(unsigned gpio,
+ gpiomux_config_t active,
+ gpiomux_config_t suspended)
+{
+ return -ENOSYS;
+}
+#endif
+#endif
diff --git a/arch/arm/mach-msm/headsmp.S b/arch/arm/mach-msm/headsmp.S
new file mode 100644
index 00000000..0c631a9f
--- /dev/null
+++ b/arch/arm/mach-msm/headsmp.S
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/mach-realview/headsmp.S
+ *
+ * Copyright (c) 2003 ARM Limited
+ * 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/linkage.h>
+#include <linux/init.h>
+
+ __CPUINIT
+
+/*
+ * MSM specific entry point for secondary CPUs. This provides
+ * a "holding pen" into which all secondary cores are held until we're
+ * ready for them to initialise.
+ */
+ENTRY(msm_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+ .align
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
new file mode 100644
index 00000000..5a31f70d
--- /dev/null
+++ b/arch/arm/mach-msm/hotplug.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ /* Just flush the cache. Changing the coherency is not yet
+ * available on msm. */
+ flush_cache_all();
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ /* Just enter wfi for now. TODO: Properly shut off the cpu. */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm("wfi"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * The trouble is, letting people know about this is not really
+ * possible, since we are currently running incoherently, and
+ * therefore cannot safely call printk() or anything else
+ */
+ pr_debug("CPU%u: spurious wakeup call\n", cpu);
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S
new file mode 100644
index 00000000..6a94f052
--- /dev/null
+++ b/arch/arm/mach-msm/idle.S
@@ -0,0 +1,36 @@
+/* arch/arm/mach-msm/include/mach/idle.S
+ *
+ * Idle processing for MSM7K - work around bugs with SWFI.
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated.
+ * Copyright (C) 2007 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>
+
+ENTRY(arch_idle)
+#ifdef CONFIG_MSM7X00A_IDLE
+ mrc p15, 0, r1, c1, c0, 0 /* read current CR */
+ bic r0, r1, #(1 << 2) /* clear dcache bit */
+ bic r0, r0, #(1 << 12) /* clear icache bit */
+ mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
+
+ mov r0, #0 /* prepare wfi value */
+ mcr p15, 0, r0, c7, c10, 0 /* flush the cache */
+ mcr p15, 0, r0, c7, c10, 4 /* memory barrier */
+ mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */
+
+ mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */
+#endif
+ mov pc, lr
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
new file mode 100644
index 00000000..2ce8f1f2
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -0,0 +1,50 @@
+/* arch/arm/mach-msm/include/mach/board.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_BOARD_H
+#define __ASM_ARCH_MSM_BOARD_H
+
+#include <linux/types.h>
+#include <mach/mmc.h>
+
+/* platform device data structures */
+
+struct msm_acpu_clock_platform_data
+{
+ uint32_t acpu_switch_time_us;
+ uint32_t max_speed_delta_khz;
+ uint32_t vdd_switch_time_us;
+ unsigned long power_collapse_khz;
+ unsigned long wait_for_irq_khz;
+};
+
+struct clk_lookup;
+
+extern struct sys_timer msm_timer;
+
+/* common init routines for use by arch/arm/mach-msm/board-*.c */
+
+void __init msm_add_devices(void);
+void __init msm_map_common_io(void);
+void __init msm_init_irq(void);
+void __init msm_init_gpio(void);
+void __init msm_clock_init(struct clk_lookup *clock_tbl, unsigned num_clocks);
+void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *);
+int __init msm_add_sdcc(unsigned int controller,
+ struct msm_mmc_platform_data *plat,
+ unsigned int stat_irq, unsigned long stat_irq_flags);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h
new file mode 100644
index 00000000..e8d38428
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clk.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2009, 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 __MACH_CLK_H
+#define __MACH_CLK_H
+
+/* Magic rate value for use with PM QOS to request the board's maximum
+ * supported AXI rate. PM QOS will only pass positive s32 rate values
+ * through to the clock driver, so INT_MAX is used.
+ */
+#define MSM_AXI_MAX_FREQ LONG_MAX
+
+enum clk_reset_action {
+ CLK_RESET_DEASSERT = 0,
+ CLK_RESET_ASSERT = 1
+};
+
+struct clk;
+
+/* Rate is minimum clock rate in Hz */
+int clk_set_min_rate(struct clk *clk, unsigned long rate);
+
+/* Rate is maximum clock rate in Hz */
+int clk_set_max_rate(struct clk *clk, unsigned long rate);
+
+/* Assert/Deassert reset to a hardware block associated with a clock */
+int clk_reset(struct clk *clk, enum clk_reset_action action);
+
+/* Set clock-specific configuration parameters */
+int clk_set_flags(struct clk *clk, unsigned long flags);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/clkdev.h b/arch/arm/mach-msm/include/mach/clkdev.h
new file mode 100644
index 00000000..f87a57b5
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/* 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_CLKDEV_H
+#define __ASM_ARCH_MSM_CLKDEV_H
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk) { return 1; }
+static inline void __clk_put(struct clk *clk) { }
+#endif
diff --git a/arch/arm/mach-msm/include/mach/cpu.h b/arch/arm/mach-msm/include/mach/cpu.h
new file mode 100644
index 00000000..a9481b08
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/cpu.h
@@ -0,0 +1,54 @@
+/* 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_CPU_H__
+#define __ARCH_ARM_MACH_MSM_CPU_H__
+
+/* TODO: For now, only one CPU can be compiled at a time. */
+
+#define cpu_is_msm7x01() 0
+#define cpu_is_msm7x30() 0
+#define cpu_is_qsd8x50() 0
+#define cpu_is_msm8x60() 0
+#define cpu_is_msm8960() 0
+
+#ifdef CONFIG_ARCH_MSM7X00A
+# undef cpu_is_msm7x01
+# define cpu_is_msm7x01() 1
+#endif
+
+#ifdef CONFIG_ARCH_MSM7X30
+# undef cpu_is_msm7x30
+# define cpu_is_msm7x30() 1
+#endif
+
+#ifdef CONFIG_ARCH_QSD8X50
+# undef cpu_is_qsd8x50
+# define cpu_is_qsd8x50() 1
+#endif
+
+#ifdef CONFIG_ARCH_MSM8X60
+# undef cpu_is_msm8x60
+# define cpu_is_msm8x60() 1
+#endif
+
+#ifdef CONFIG_ARCH_MSM8960
+# undef cpu_is_msm8960
+# define cpu_is_msm8960() 1
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/debug-macro.S b/arch/arm/mach-msm/include/mach/debug-macro.S
new file mode 100644
index 00000000..646b99eb
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/debug-macro.S
@@ -0,0 +1,53 @@
+/* arch/arm/mach-msm7200/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+
+#include <mach/hardware.h>
+#include <mach/msm_iomap.h>
+
+#if defined(CONFIG_HAS_MSM_DEBUG_UART_PHYS) && !defined(CONFIG_MSM_DEBUG_UART_NONE)
+ .macro addruart, rp, rv
+ ldr \rp, =MSM_DEBUG_UART_PHYS
+ ldr \rv, =MSM_DEBUG_UART_BASE
+ .endm
+
+ .macro senduart,rd,rx
+ teq \rx, #0
+ strne \rd, [\rx, #0x0C]
+ .endm
+
+ .macro waituart,rd,rx
+ @ wait for TX_READY
+1001: ldr \rd, [\rx, #0x08]
+ tst \rd, #0x04
+ beq 1001b
+ .endm
+#else
+ .macro addruart, rp, rv
+ mov \rv, #0xff000000
+ orr \rv, \rv, #0x00f00000
+ .endm
+
+ .macro senduart,rd,rx
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+#endif
+
+ .macro busyuart,rd,rx
+ .endm
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
new file mode 100644
index 00000000..05583f56
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -0,0 +1,177 @@
+/* linux/include/asm-arm/arch-msm/dma.h
+ *
+ * Copyright (C) 2007 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_ARCH_MSM_DMA_H
+
+#include <linux/list.h>
+#include <mach/msm_iomap.h>
+
+struct msm_dmov_errdata {
+ uint32_t flush[6];
+};
+
+struct msm_dmov_cmd {
+ struct list_head list;
+ unsigned int cmdptr;
+ void (*complete_func)(struct msm_dmov_cmd *cmd,
+ unsigned int result,
+ struct msm_dmov_errdata *err);
+ void (*execute_func)(struct msm_dmov_cmd *cmd);
+ void *data;
+};
+
+#ifndef CONFIG_ARCH_MSM8X60
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
+#else
+static inline
+void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) { }
+static inline
+void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful) { }
+static inline
+int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) { return -EIO; }
+#endif
+
+
+#define DMOV_SD0(off, ch) (MSM_DMOV_BASE + 0x0000 + (off) + ((ch) << 2))
+#define DMOV_SD1(off, ch) (MSM_DMOV_BASE + 0x0400 + (off) + ((ch) << 2))
+#define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2))
+#define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define DMOV_SD_AARM DMOV_SD2
+#else
+#define DMOV_SD_AARM DMOV_SD3
+#endif
+
+#define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch)
+#define DMOV_CMD_LIST (0 << 29) /* does not work */
+#define DMOV_CMD_PTR_LIST (1 << 29) /* works */
+#define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */
+#define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */
+#define DMOV_CMD_ADDR(addr) ((addr) >> 3)
+
+#define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch)
+#define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */
+#define DMOV_RSLT_ERROR (1 << 3)
+#define DMOV_RSLT_FLUSH (1 << 2)
+#define DMOV_RSLT_DONE (1 << 1) /* top pointer done */
+#define DMOV_RSLT_USER (1 << 0) /* command with FR force result */
+
+#define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch)
+#define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch)
+#define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch)
+#define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch)
+#define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch)
+#define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch)
+
+#define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch)
+#define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29))
+#define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3)
+#define DMOV_STATUS_RSLT_VALID (1 << 1)
+#define DMOV_STATUS_CMD_PTR_RDY (1 << 0)
+
+#define DMOV_ISR DMOV_SD_AARM(0x380, 0)
+
+#define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch)
+#define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2)
+#define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1)
+#define DMOV_CONFIG_IRQ_EN (1 << 0)
+
+/* channel assignments */
+
+#define DMOV_NAND_CHAN 7
+#define DMOV_NAND_CRCI_CMD 5
+#define DMOV_NAND_CRCI_DATA 4
+
+#define DMOV_SDC1_CHAN 8
+#define DMOV_SDC1_CRCI 6
+
+#define DMOV_SDC2_CHAN 8
+#define DMOV_SDC2_CRCI 7
+
+#define DMOV_TSIF_CHAN 10
+#define DMOV_TSIF_CRCI 10
+
+#define DMOV_USB_CHAN 11
+
+/* no client rate control ifc (eg, ram) */
+#define DMOV_NONE_CRCI 0
+
+
+/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
+ * is going to walk a list of 32bit pointers as described below. Each
+ * pointer points to a *array* of dmov_s, etc structs. The last pointer
+ * in the list is marked with CMD_PTR_LP. The last struct in each array
+ * is marked with CMD_LC (see below).
+ */
+#define CMD_PTR_ADDR(addr) ((addr) >> 3)
+#define CMD_PTR_LP (1 << 31) /* last pointer */
+#define CMD_PTR_PT (3 << 29) /* ? */
+
+/* Single Item Mode */
+typedef struct {
+ unsigned cmd;
+ unsigned src;
+ unsigned dst;
+ unsigned len;
+} dmov_s;
+
+/* Scatter/Gather Mode */
+typedef struct {
+ unsigned cmd;
+ unsigned src_dscr;
+ unsigned dst_dscr;
+ unsigned _reserved;
+} dmov_sg;
+
+/* Box mode */
+typedef struct {
+ uint32_t cmd;
+ uint32_t src_row_addr;
+ uint32_t dst_row_addr;
+ uint32_t src_dst_len;
+ uint32_t num_rows;
+ uint32_t row_offset;
+} dmov_box;
+
+/* bits for the cmd field of the above structures */
+
+#define CMD_LC (1 << 31) /* last command */
+#define CMD_FR (1 << 22) /* force result -- does not work? */
+#define CMD_OCU (1 << 21) /* other channel unblock */
+#define CMD_OCB (1 << 20) /* other channel block */
+#define CMD_TCB (1 << 19) /* ? */
+#define CMD_DAH (1 << 18) /* destination address hold -- does not work?*/
+#define CMD_SAH (1 << 17) /* source address hold -- does not work? */
+
+#define CMD_MODE_SINGLE (0 << 0) /* dmov_s structure used */
+#define CMD_MODE_SG (1 << 0) /* untested */
+#define CMD_MODE_IND_SG (2 << 0) /* untested */
+#define CMD_MODE_BOX (3 << 0) /* untested */
+
+#define CMD_DST_SWAP_BYTES (1 << 14) /* exchange each byte n with byte n+1 */
+#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
+#define CMD_DST_SWAP_WORDS (1 << 16) /* exchange each word n with word n+1 */
+
+#define CMD_SRC_SWAP_BYTES (1 << 11) /* exchange each byte n with byte n+1 */
+#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
+#define CMD_SRC_SWAP_WORDS (1 << 13) /* exchange each word n with word n+1 */
+
+#define CMD_DST_CRCI(n) (((n) & 15) << 7)
+#define CMD_SRC_CRCI(n) (((n) & 15) << 3)
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
new file mode 100644
index 00000000..12467157
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S
@@ -0,0 +1,88 @@
+/*
+ * Low-level IRQ helper macros
+ *
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =gic_cpu_base_addr
+ ldr \base, [\base]
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Migrated the code from ARM MP port to be more consistent
+ * with interrupt processing , the following still holds true
+ * however, all interrupts are treated the same regardless of
+ * if they are local IPI or PPI
+ *
+ * Interrupts 0-15 are IPI
+ * 16-31 are PPI
+ * (16-18 are the timers)
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * A simple read from the controller will tell us the number of the
+ * highest priority enabled interrupt. We then just need to check
+ * whether it is in the valid range for an IRQ (0-1020 inclusive).
+ *
+ * Base ARM code assumes that the local (private) peripheral interrupts
+ * are not valid, we treat them differently, in that the privates are
+ * handled like normal shared interrupts with the exception that only
+ * one processor can register the interrupt and the handler must be
+ * the same for all processors.
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \irqstat, [\base, #GIC_CPU_INTACK] /* bits 12-10 =srcCPU,
+ 9-0 =int # */
+
+ bic \irqnr, \irqstat, #0x1c00 @mask src
+ cmp \irqnr, #15
+ ldr \tmp, =1021
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #16
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
diff --git a/arch/arm/mach-msm/include/mach/entry-macro-vic.S b/arch/arm/mach-msm/include/mach/entry-macro-vic.S
new file mode 100644
index 00000000..70563ed1
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/entry-macro-vic.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <mach/msm_iomap.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ enable imprecise aborts
+ cpsie a
+ mov \base, #MSM_VIC_BASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ @ 0xD0 has irq# or old irq# if the irq has been handled
+ @ 0xD4 has irq# or -1 if none pending *but* if you just
+ @ read 0xD4 you never get the first irq for some reason
+ ldr \irqnr, [\base, #0xD0]
+ ldr \irqnr, [\base, #0xD4]
+ cmp \irqnr, #0xffffffff
+ .endm
diff --git a/arch/arm/mach-msm/include/mach/entry-macro.S b/arch/arm/mach-msm/include/mach/entry-macro.S
new file mode 100644
index 00000000..b16f082e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/entry-macro.S
@@ -0,0 +1,23 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#if defined(CONFIG_ARM_GIC)
+#include <mach/entry-macro-qgic.S>
+#else
+#include <mach/entry-macro-vic.S>
+#endif
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
new file mode 100644
index 00000000..36ad50d3
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+ * Author: Mike Lockwood <lockwood@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 __ASM_ARCH_MSM_GPIO_H
+#define __ASM_ARCH_MSM_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#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
+
+#endif /* __ASM_ARCH_MSM_GPIO_H */
diff --git a/arch/arm/mach-msm/include/mach/hardware.h b/arch/arm/mach-msm/include/mach/hardware.h
new file mode 100644
index 00000000..2d126091
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-msm/include/mach/hardware.h
+ *
+ * Copyright (C) 2007 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_ARCH_MSM_HARDWARE_H
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h
new file mode 100644
index 00000000..dc1b9287
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/io.h
@@ -0,0 +1,36 @@
+/* arch/arm/mach-msm/include/mach/io.h
+ *
+ * Copyright (C) 2007 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_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __arch_ioremap __msm_ioremap
+#define __arch_iounmap __iounmap
+
+void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype);
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+void msm_map_qsd8x50_io(void);
+void msm_map_msm7x30_io(void);
+void msm_map_msm8x60_io(void);
+void msm_map_msm8960_io(void);
+
+extern unsigned int msm_shared_ram_phys;
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h
new file mode 100644
index 00000000..5c7c955e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu.h
@@ -0,0 +1,120 @@
+/* Copyright (c) 2010-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef MSM_IOMMU_H
+#define MSM_IOMMU_H
+
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+
+/* Sharability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NON_SH 0x0
+#define MSM_IOMMU_ATTR_SH 0x4
+
+/* Cacheability attributes of MSM IOMMU mappings */
+#define MSM_IOMMU_ATTR_NONCACHED 0x0
+#define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1
+#define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2
+#define MSM_IOMMU_ATTR_CACHED_WT 0x3
+
+/* Mask for the cache policy attribute */
+#define MSM_IOMMU_CP_MASK 0x03
+
+/* Maximum number of Machine IDs that we are allowing to be mapped to the same
+ * context bank. The number of MIDs mapped to the same CB does not affect
+ * performance, but there is a practical limit on how many distinct MIDs may
+ * be present. These mappings are typically determined at design time and are
+ * not expected to change at run time.
+ */
+#define MAX_NUM_MIDS 32
+
+/**
+ * struct msm_iommu_dev - a single IOMMU hardware instance
+ * name Human-readable name given to this IOMMU HW instance
+ * ncb Number of context banks present on this IOMMU HW instance
+ */
+struct msm_iommu_dev {
+ const char *name;
+ int ncb;
+};
+
+/**
+ * struct msm_iommu_ctx_dev - an IOMMU context bank instance
+ * name Human-readable name given to this context bank
+ * num Index of this context bank within the hardware
+ * mids List of Machine IDs that are to be mapped into this context
+ * bank, terminated by -1. The MID is a set of signals on the
+ * AXI bus that identifies the function associated with a specific
+ * memory request. (See ARM spec).
+ */
+struct msm_iommu_ctx_dev {
+ const char *name;
+ int num;
+ int mids[MAX_NUM_MIDS];
+};
+
+
+/**
+ * struct msm_iommu_drvdata - A single IOMMU hardware instance
+ * @base: IOMMU config port base address (VA)
+ * @ncb The number of contexts on this IOMMU
+ * @irq: Interrupt number
+ * @clk: The bus clock for this IOMMU hardware instance
+ * @pclk: The clock for the IOMMU bus interconnect
+ *
+ * A msm_iommu_drvdata holds the global driver data about a single piece
+ * of an IOMMU hardware instance.
+ */
+struct msm_iommu_drvdata {
+ void __iomem *base;
+ int irq;
+ int ncb;
+ struct clk *clk;
+ struct clk *pclk;
+};
+
+/**
+ * struct msm_iommu_ctx_drvdata - an IOMMU context bank instance
+ * @num: Hardware context number of this context
+ * @pdev: Platform device associated wit this HW instance
+ * @attached_elm: List element for domains to track which devices are
+ * attached to them
+ *
+ * A msm_iommu_ctx_drvdata holds the driver data for a single context bank
+ * within each IOMMU hardware instance
+ */
+struct msm_iommu_ctx_drvdata {
+ int num;
+ struct platform_device *pdev;
+ struct list_head attached_elm;
+};
+
+/*
+ * Look up an IOMMU context device by its context name. NULL if none found.
+ * Useful for testing and drivers that do not yet fully have IOMMU stuff in
+ * their platform devices.
+ */
+struct device *msm_iommu_get_ctx(const char *ctx_name);
+
+/*
+ * Interrupt handler for the IOMMU context fault interrupt. Hooking the
+ * interrupt is not supported in the API yet, but this will print an error
+ * message and dump useful IOMMU registers.
+ */
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id);
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
new file mode 100644
index 00000000..fc160101
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h
@@ -0,0 +1,1865 @@
+/* Copyright (c) 2010-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+#define __ARCH_ARM_MACH_MSM_IOMMU_HW_8XXX_H
+
+#define CTX_SHIFT 12
+
+#define GET_GLOBAL_REG(reg, base) (readl((base) + (reg)))
+#define GET_CTX_REG(reg, base, ctx) \
+ (readl((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+#define SET_GLOBAL_REG(reg, base, val) writel((val), ((base) + (reg)))
+
+#define SET_CTX_REG(reg, base, ctx, val) \
+ writel((val), ((base) + (reg) + ((ctx) << CTX_SHIFT)))
+
+/* Wrappers for numbered registers */
+#define SET_GLOBAL_REG_N(b, n, r, v) SET_GLOBAL_REG(b, ((r) + (n << 2)), (v))
+#define GET_GLOBAL_REG_N(b, n, r) GET_GLOBAL_REG(b, ((r) + (n << 2)))
+
+/* Field wrappers */
+#define GET_GLOBAL_FIELD(b, r, F) GET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT)
+#define GET_CONTEXT_FIELD(b, c, r, F) \
+ GET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT)
+
+#define SET_GLOBAL_FIELD(b, r, F, v) \
+ SET_FIELD(((b) + (r)), F##_MASK, F##_SHIFT, (v))
+#define SET_CONTEXT_FIELD(b, c, r, F, v) \
+ SET_FIELD(((b) + (r) + ((c) << CTX_SHIFT)), F##_MASK, F##_SHIFT, (v))
+
+#define GET_FIELD(addr, mask, shift) ((readl(addr) >> (shift)) & (mask))
+
+#define SET_FIELD(addr, mask, shift, v) \
+do { \
+ int t = readl(addr); \
+ writel((t & ~((mask) << (shift))) + (((v) & (mask)) << (shift)), addr);\
+} while (0)
+
+
+#define NUM_FL_PTE 4096
+#define NUM_SL_PTE 256
+#define NUM_TEX_CLASS 8
+
+/* First-level page table bits */
+#define FL_BASE_MASK 0xFFFFFC00
+#define FL_TYPE_TABLE (1 << 0)
+#define FL_TYPE_SECT (2 << 0)
+#define FL_SUPERSECTION (1 << 18)
+#define FL_AP_WRITE (1 << 10)
+#define FL_AP_READ (1 << 11)
+#define FL_SHARED (1 << 16)
+#define FL_BUFFERABLE (1 << 2)
+#define FL_CACHEABLE (1 << 3)
+#define FL_TEX0 (1 << 12)
+#define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20)
+#define FL_NG (1 << 17)
+
+/* Second-level page table bits */
+#define SL_BASE_MASK_LARGE 0xFFFF0000
+#define SL_BASE_MASK_SMALL 0xFFFFF000
+#define SL_TYPE_LARGE (1 << 0)
+#define SL_TYPE_SMALL (2 << 0)
+#define SL_AP0 (1 << 4)
+#define SL_AP1 (2 << 4)
+#define SL_SHARED (1 << 10)
+#define SL_BUFFERABLE (1 << 2)
+#define SL_CACHEABLE (1 << 3)
+#define SL_TEX0 (1 << 6)
+#define SL_OFFSET(va) (((va) & 0xFF000) >> 12)
+#define SL_NG (1 << 11)
+
+/* Memory type and cache policy attributes */
+#define MT_SO 0
+#define MT_DEV 1
+#define MT_NORMAL 2
+#define CP_NONCACHED 0
+#define CP_WB_WA 1
+#define CP_WT 2
+#define CP_WB_NWA 3
+
+/* Global register setters / getters */
+#define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v))
+#define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v))
+#define SET_TLBRSW(b, v) SET_GLOBAL_REG(TLBRSW, (b), (v))
+#define SET_TLBTR0(b, v) SET_GLOBAL_REG(TLBTR0, (b), (v))
+#define SET_TLBTR1(b, v) SET_GLOBAL_REG(TLBTR1, (b), (v))
+#define SET_TLBTR2(b, v) SET_GLOBAL_REG(TLBTR2, (b), (v))
+#define SET_TESTBUSCR(b, v) SET_GLOBAL_REG(TESTBUSCR, (b), (v))
+#define SET_GLOBAL_TLBIALL(b, v) SET_GLOBAL_REG(GLOBAL_TLBIALL, (b), (v))
+#define SET_TLBIVMID(b, v) SET_GLOBAL_REG(TLBIVMID, (b), (v))
+#define SET_CR(b, v) SET_GLOBAL_REG(CR, (b), (v))
+#define SET_EAR(b, v) SET_GLOBAL_REG(EAR, (b), (v))
+#define SET_ESR(b, v) SET_GLOBAL_REG(ESR, (b), (v))
+#define SET_ESRRESTORE(b, v) SET_GLOBAL_REG(ESRRESTORE, (b), (v))
+#define SET_ESYNR0(b, v) SET_GLOBAL_REG(ESYNR0, (b), (v))
+#define SET_ESYNR1(b, v) SET_GLOBAL_REG(ESYNR1, (b), (v))
+#define SET_RPU_ACR(b, v) SET_GLOBAL_REG(RPU_ACR, (b), (v))
+
+#define GET_M2VCBR_N(b, N) GET_GLOBAL_REG_N(M2VCBR_N, N, (b))
+#define GET_CBACR_N(b, N) GET_GLOBAL_REG_N(CBACR_N, N, (b))
+#define GET_TLBTR0(b) GET_GLOBAL_REG(TLBTR0, (b))
+#define GET_TLBTR1(b) GET_GLOBAL_REG(TLBTR1, (b))
+#define GET_TLBTR2(b) GET_GLOBAL_REG(TLBTR2, (b))
+#define GET_TESTBUSCR(b) GET_GLOBAL_REG(TESTBUSCR, (b))
+#define GET_GLOBAL_TLBIALL(b) GET_GLOBAL_REG(GLOBAL_TLBIALL, (b))
+#define GET_TLBIVMID(b) GET_GLOBAL_REG(TLBIVMID, (b))
+#define GET_CR(b) GET_GLOBAL_REG(CR, (b))
+#define GET_EAR(b) GET_GLOBAL_REG(EAR, (b))
+#define GET_ESR(b) GET_GLOBAL_REG(ESR, (b))
+#define GET_ESRRESTORE(b) GET_GLOBAL_REG(ESRRESTORE, (b))
+#define GET_ESYNR0(b) GET_GLOBAL_REG(ESYNR0, (b))
+#define GET_ESYNR1(b) GET_GLOBAL_REG(ESYNR1, (b))
+#define GET_REV(b) GET_GLOBAL_REG(REV, (b))
+#define GET_IDR(b) GET_GLOBAL_REG(IDR, (b))
+#define GET_RPU_ACR(b) GET_GLOBAL_REG(RPU_ACR, (b))
+
+
+/* Context register setters/getters */
+#define SET_SCTLR(b, c, v) SET_CTX_REG(SCTLR, (b), (c), (v))
+#define SET_ACTLR(b, c, v) SET_CTX_REG(ACTLR, (b), (c), (v))
+#define SET_CONTEXTIDR(b, c, v) SET_CTX_REG(CONTEXTIDR, (b), (c), (v))
+#define SET_TTBR0(b, c, v) SET_CTX_REG(TTBR0, (b), (c), (v))
+#define SET_TTBR1(b, c, v) SET_CTX_REG(TTBR1, (b), (c), (v))
+#define SET_TTBCR(b, c, v) SET_CTX_REG(TTBCR, (b), (c), (v))
+#define SET_PAR(b, c, v) SET_CTX_REG(PAR, (b), (c), (v))
+#define SET_FSR(b, c, v) SET_CTX_REG(FSR, (b), (c), (v))
+#define SET_FSRRESTORE(b, c, v) SET_CTX_REG(FSRRESTORE, (b), (c), (v))
+#define SET_FAR(b, c, v) SET_CTX_REG(FAR, (b), (c), (v))
+#define SET_FSYNR0(b, c, v) SET_CTX_REG(FSYNR0, (b), (c), (v))
+#define SET_FSYNR1(b, c, v) SET_CTX_REG(FSYNR1, (b), (c), (v))
+#define SET_PRRR(b, c, v) SET_CTX_REG(PRRR, (b), (c), (v))
+#define SET_NMRR(b, c, v) SET_CTX_REG(NMRR, (b), (c), (v))
+#define SET_TLBLKCR(b, c, v) SET_CTX_REG(TLBLCKR, (b), (c), (v))
+#define SET_V2PSR(b, c, v) SET_CTX_REG(V2PSR, (b), (c), (v))
+#define SET_TLBFLPTER(b, c, v) SET_CTX_REG(TLBFLPTER, (b), (c), (v))
+#define SET_TLBSLPTER(b, c, v) SET_CTX_REG(TLBSLPTER, (b), (c), (v))
+#define SET_BFBCR(b, c, v) SET_CTX_REG(BFBCR, (b), (c), (v))
+#define SET_CTX_TLBIALL(b, c, v) SET_CTX_REG(CTX_TLBIALL, (b), (c), (v))
+#define SET_TLBIASID(b, c, v) SET_CTX_REG(TLBIASID, (b), (c), (v))
+#define SET_TLBIVA(b, c, v) SET_CTX_REG(TLBIVA, (b), (c), (v))
+#define SET_TLBIVAA(b, c, v) SET_CTX_REG(TLBIVAA, (b), (c), (v))
+#define SET_V2PPR(b, c, v) SET_CTX_REG(V2PPR, (b), (c), (v))
+#define SET_V2PPW(b, c, v) SET_CTX_REG(V2PPW, (b), (c), (v))
+#define SET_V2PUR(b, c, v) SET_CTX_REG(V2PUR, (b), (c), (v))
+#define SET_V2PUW(b, c, v) SET_CTX_REG(V2PUW, (b), (c), (v))
+#define SET_RESUME(b, c, v) SET_CTX_REG(RESUME, (b), (c), (v))
+
+#define GET_SCTLR(b, c) GET_CTX_REG(SCTLR, (b), (c))
+#define GET_ACTLR(b, c) GET_CTX_REG(ACTLR, (b), (c))
+#define GET_CONTEXTIDR(b, c) GET_CTX_REG(CONTEXTIDR, (b), (c))
+#define GET_TTBR0(b, c) GET_CTX_REG(TTBR0, (b), (c))
+#define GET_TTBR1(b, c) GET_CTX_REG(TTBR1, (b), (c))
+#define GET_TTBCR(b, c) GET_CTX_REG(TTBCR, (b), (c))
+#define GET_PAR(b, c) GET_CTX_REG(PAR, (b), (c))
+#define GET_FSR(b, c) GET_CTX_REG(FSR, (b), (c))
+#define GET_FSRRESTORE(b, c) GET_CTX_REG(FSRRESTORE, (b), (c))
+#define GET_FAR(b, c) GET_CTX_REG(FAR, (b), (c))
+#define GET_FSYNR0(b, c) GET_CTX_REG(FSYNR0, (b), (c))
+#define GET_FSYNR1(b, c) GET_CTX_REG(FSYNR1, (b), (c))
+#define GET_PRRR(b, c) GET_CTX_REG(PRRR, (b), (c))
+#define GET_NMRR(b, c) GET_CTX_REG(NMRR, (b), (c))
+#define GET_TLBLCKR(b, c) GET_CTX_REG(TLBLCKR, (b), (c))
+#define GET_V2PSR(b, c) GET_CTX_REG(V2PSR, (b), (c))
+#define GET_TLBFLPTER(b, c) GET_CTX_REG(TLBFLPTER, (b), (c))
+#define GET_TLBSLPTER(b, c) GET_CTX_REG(TLBSLPTER, (b), (c))
+#define GET_BFBCR(b, c) GET_CTX_REG(BFBCR, (b), (c))
+#define GET_CTX_TLBIALL(b, c) GET_CTX_REG(CTX_TLBIALL, (b), (c))
+#define GET_TLBIASID(b, c) GET_CTX_REG(TLBIASID, (b), (c))
+#define GET_TLBIVA(b, c) GET_CTX_REG(TLBIVA, (b), (c))
+#define GET_TLBIVAA(b, c) GET_CTX_REG(TLBIVAA, (b), (c))
+#define GET_V2PPR(b, c) GET_CTX_REG(V2PPR, (b), (c))
+#define GET_V2PPW(b, c) GET_CTX_REG(V2PPW, (b), (c))
+#define GET_V2PUR(b, c) GET_CTX_REG(V2PUR, (b), (c))
+#define GET_V2PUW(b, c) GET_CTX_REG(V2PUW, (b), (c))
+#define GET_RESUME(b, c) GET_CTX_REG(RESUME, (b), (c))
+
+
+/* Global field setters / getters */
+/* Global Field Setters: */
+/* CBACR_N */
+#define SET_RWVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID, v)
+#define SET_RWE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE, v)
+#define SET_RWGE(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE, v)
+#define SET_CBVMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID, v)
+#define SET_IRPTNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX, v)
+
+
+/* M2VCBR_N */
+#define SET_VMID(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID, v)
+#define SET_CBNDX(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX, v)
+#define SET_BYPASSD(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD, v)
+#define SET_BPRCOSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH, v)
+#define SET_BPRCISH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH, v)
+#define SET_BPRCNSH(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH, v)
+#define SET_BPSHCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG, v)
+#define SET_NSCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG, v)
+#define SET_BPMTCFG(b, n, v) SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG, v)
+#define SET_BPMEMTYPE(b, n, v) \
+ SET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE, v)
+
+
+/* CR */
+#define SET_RPUE(b, v) SET_GLOBAL_FIELD(b, CR, RPUE, v)
+#define SET_RPUERE(b, v) SET_GLOBAL_FIELD(b, CR, RPUERE, v)
+#define SET_RPUEIE(b, v) SET_GLOBAL_FIELD(b, CR, RPUEIE, v)
+#define SET_DCDEE(b, v) SET_GLOBAL_FIELD(b, CR, DCDEE, v)
+#define SET_CLIENTPD(b, v) SET_GLOBAL_FIELD(b, CR, CLIENTPD, v)
+#define SET_STALLD(b, v) SET_GLOBAL_FIELD(b, CR, STALLD, v)
+#define SET_TLBLKCRWE(b, v) SET_GLOBAL_FIELD(b, CR, TLBLKCRWE, v)
+#define SET_CR_TLBIALLCFG(b, v) SET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG, v)
+#define SET_TLBIVMIDCFG(b, v) SET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG, v)
+#define SET_CR_HUME(b, v) SET_GLOBAL_FIELD(b, CR, CR_HUME, v)
+
+
+/* ESR */
+#define SET_CFG(b, v) SET_GLOBAL_FIELD(b, ESR, CFG, v)
+#define SET_BYPASS(b, v) SET_GLOBAL_FIELD(b, ESR, BYPASS, v)
+#define SET_ESR_MULTI(b, v) SET_GLOBAL_FIELD(b, ESR, ESR_MULTI, v)
+
+
+/* ESYNR0 */
+#define SET_ESYNR0_AMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID, v)
+#define SET_ESYNR0_APID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID, v)
+#define SET_ESYNR0_ABID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID, v)
+#define SET_ESYNR0_AVMID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID, v)
+#define SET_ESYNR0_ATID(b, v) SET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID, v)
+
+
+/* ESYNR1 */
+#define SET_ESYNR1_AMEMTYPE(b, v) \
+ SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE, v)
+#define SET_ESYNR1_ASHARED(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED, v)
+#define SET_ESYNR1_AINNERSHARED(b, v) \
+ SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED, v)
+#define SET_ESYNR1_APRIV(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV, v)
+#define SET_ESYNR1_APROTNS(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS, v)
+#define SET_ESYNR1_AINST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST, v)
+#define SET_ESYNR1_AWRITE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE, v)
+#define SET_ESYNR1_ABURST(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST, v)
+#define SET_ESYNR1_ALEN(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN, v)
+#define SET_ESYNR1_ASIZE(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE, v)
+#define SET_ESYNR1_ALOCK(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK, v)
+#define SET_ESYNR1_AOOO(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO, v)
+#define SET_ESYNR1_AFULL(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL, v)
+#define SET_ESYNR1_AC(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC, v)
+#define SET_ESYNR1_DCD(b, v) SET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD, v)
+
+
+/* TESTBUSCR */
+#define SET_TBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBE, v)
+#define SET_SPDMBE(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE, v)
+#define SET_WGSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL, v)
+#define SET_TBLSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL, v)
+#define SET_TBHSEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL, v)
+#define SET_SPDM0SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL, v)
+#define SET_SPDM1SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL, v)
+#define SET_SPDM2SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL, v)
+#define SET_SPDM3SEL(b, v) SET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL, v)
+
+
+/* TLBIVMID */
+#define SET_TLBIVMID_VMID(b, v) SET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID, v)
+
+
+/* TLBRSW */
+#define SET_TLBRSW_INDEX(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBRSW_INDEX, v)
+#define SET_TLBBFBS(b, v) SET_GLOBAL_FIELD(b, TLBRSW, TLBBFBS, v)
+
+
+/* TLBTR0 */
+#define SET_PR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PR, v)
+#define SET_PW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, PW, v)
+#define SET_UR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UR, v)
+#define SET_UW(b, v) SET_GLOBAL_FIELD(b, TLBTR0, UW, v)
+#define SET_XN(b, v) SET_GLOBAL_FIELD(b, TLBTR0, XN, v)
+#define SET_NSDESC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, NSDESC, v)
+#define SET_ISH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, ISH, v)
+#define SET_SH(b, v) SET_GLOBAL_FIELD(b, TLBTR0, SH, v)
+#define SET_MT(b, v) SET_GLOBAL_FIELD(b, TLBTR0, MT, v)
+#define SET_DPSIZR(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZR, v)
+#define SET_DPSIZC(b, v) SET_GLOBAL_FIELD(b, TLBTR0, DPSIZC, v)
+
+
+/* TLBTR1 */
+#define SET_TLBTR1_VMID(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID, v)
+#define SET_TLBTR1_PA(b, v) SET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA, v)
+
+
+/* TLBTR2 */
+#define SET_TLBTR2_ASID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID, v)
+#define SET_TLBTR2_V(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V, v)
+#define SET_TLBTR2_NSTID(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID, v)
+#define SET_TLBTR2_NV(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV, v)
+#define SET_TLBTR2_VA(b, v) SET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA, v)
+
+
+/* Global Field Getters */
+/* CBACR_N */
+#define GET_RWVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWVMID)
+#define GET_RWE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWE)
+#define GET_RWGE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), RWGE)
+#define GET_CBVMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), CBVMID)
+#define GET_IRPTNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(CBACR_N), IRPTNDX)
+
+
+/* M2VCBR_N */
+#define GET_VMID(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), VMID)
+#define GET_CBNDX(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), CBNDX)
+#define GET_BYPASSD(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BYPASSD)
+#define GET_BPRCOSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCOSH)
+#define GET_BPRCISH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCISH)
+#define GET_BPRCNSH(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPRCNSH)
+#define GET_BPSHCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPSHCFG)
+#define GET_NSCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), NSCFG)
+#define GET_BPMTCFG(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMTCFG)
+#define GET_BPMEMTYPE(b, n) GET_GLOBAL_FIELD(b, (n<<2)|(M2VCBR_N), BPMEMTYPE)
+
+
+/* CR */
+#define GET_RPUE(b) GET_GLOBAL_FIELD(b, CR, RPUE)
+#define GET_RPUERE(b) GET_GLOBAL_FIELD(b, CR, RPUERE)
+#define GET_RPUEIE(b) GET_GLOBAL_FIELD(b, CR, RPUEIE)
+#define GET_DCDEE(b) GET_GLOBAL_FIELD(b, CR, DCDEE)
+#define GET_CLIENTPD(b) GET_GLOBAL_FIELD(b, CR, CLIENTPD)
+#define GET_STALLD(b) GET_GLOBAL_FIELD(b, CR, STALLD)
+#define GET_TLBLKCRWE(b) GET_GLOBAL_FIELD(b, CR, TLBLKCRWE)
+#define GET_CR_TLBIALLCFG(b) GET_GLOBAL_FIELD(b, CR, CR_TLBIALLCFG)
+#define GET_TLBIVMIDCFG(b) GET_GLOBAL_FIELD(b, CR, TLBIVMIDCFG)
+#define GET_CR_HUME(b) GET_GLOBAL_FIELD(b, CR, CR_HUME)
+
+
+/* ESR */
+#define GET_CFG(b) GET_GLOBAL_FIELD(b, ESR, CFG)
+#define GET_BYPASS(b) GET_GLOBAL_FIELD(b, ESR, BYPASS)
+#define GET_ESR_MULTI(b) GET_GLOBAL_FIELD(b, ESR, ESR_MULTI)
+
+
+/* ESYNR0 */
+#define GET_ESYNR0_AMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AMID)
+#define GET_ESYNR0_APID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_APID)
+#define GET_ESYNR0_ABID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ABID)
+#define GET_ESYNR0_AVMID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_AVMID)
+#define GET_ESYNR0_ATID(b) GET_GLOBAL_FIELD(b, ESYNR0, ESYNR0_ATID)
+
+
+/* ESYNR1 */
+#define GET_ESYNR1_AMEMTYPE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AMEMTYPE)
+#define GET_ESYNR1_ASHARED(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASHARED)
+#define GET_ESYNR1_AINNERSHARED(b) \
+ GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINNERSHARED)
+#define GET_ESYNR1_APRIV(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APRIV)
+#define GET_ESYNR1_APROTNS(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_APROTNS)
+#define GET_ESYNR1_AINST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AINST)
+#define GET_ESYNR1_AWRITE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AWRITE)
+#define GET_ESYNR1_ABURST(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ABURST)
+#define GET_ESYNR1_ALEN(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALEN)
+#define GET_ESYNR1_ASIZE(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ASIZE)
+#define GET_ESYNR1_ALOCK(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_ALOCK)
+#define GET_ESYNR1_AOOO(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AOOO)
+#define GET_ESYNR1_AFULL(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AFULL)
+#define GET_ESYNR1_AC(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_AC)
+#define GET_ESYNR1_DCD(b) GET_GLOBAL_FIELD(b, ESYNR1, ESYNR1_DCD)
+
+
+/* IDR */
+#define GET_NM2VCBMT(b) GET_GLOBAL_FIELD(b, IDR, NM2VCBMT)
+#define GET_HTW(b) GET_GLOBAL_FIELD(b, IDR, HTW)
+#define GET_HUM(b) GET_GLOBAL_FIELD(b, IDR, HUM)
+#define GET_TLBSIZE(b) GET_GLOBAL_FIELD(b, IDR, TLBSIZE)
+#define GET_NCB(b) GET_GLOBAL_FIELD(b, IDR, NCB)
+#define GET_NIRPT(b) GET_GLOBAL_FIELD(b, IDR, NIRPT)
+
+
+/* REV */
+#define GET_MAJOR(b) GET_GLOBAL_FIELD(b, REV, MAJOR)
+#define GET_MINOR(b) GET_GLOBAL_FIELD(b, REV, MINOR)
+
+
+/* TESTBUSCR */
+#define GET_TBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBE)
+#define GET_SPDMBE(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDMBE)
+#define GET_WGSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, WGSEL)
+#define GET_TBLSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBLSEL)
+#define GET_TBHSEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, TBHSEL)
+#define GET_SPDM0SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM0SEL)
+#define GET_SPDM1SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM1SEL)
+#define GET_SPDM2SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM2SEL)
+#define GET_SPDM3SEL(b) GET_GLOBAL_FIELD(b, TESTBUSCR, SPDM3SEL)
+
+
+/* TLBIVMID */
+#define GET_TLBIVMID_VMID(b) GET_GLOBAL_FIELD(b, TLBIVMID, TLBIVMID_VMID)
+
+
+/* TLBTR0 */
+#define GET_PR(b) GET_GLOBAL_FIELD(b, TLBTR0, PR)
+#define GET_PW(b) GET_GLOBAL_FIELD(b, TLBTR0, PW)
+#define GET_UR(b) GET_GLOBAL_FIELD(b, TLBTR0, UR)
+#define GET_UW(b) GET_GLOBAL_FIELD(b, TLBTR0, UW)
+#define GET_XN(b) GET_GLOBAL_FIELD(b, TLBTR0, XN)
+#define GET_NSDESC(b) GET_GLOBAL_FIELD(b, TLBTR0, NSDESC)
+#define GET_ISH(b) GET_GLOBAL_FIELD(b, TLBTR0, ISH)
+#define GET_SH(b) GET_GLOBAL_FIELD(b, TLBTR0, SH)
+#define GET_MT(b) GET_GLOBAL_FIELD(b, TLBTR0, MT)
+#define GET_DPSIZR(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZR)
+#define GET_DPSIZC(b) GET_GLOBAL_FIELD(b, TLBTR0, DPSIZC)
+
+
+/* TLBTR1 */
+#define GET_TLBTR1_VMID(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_VMID)
+#define GET_TLBTR1_PA(b) GET_GLOBAL_FIELD(b, TLBTR1, TLBTR1_PA)
+
+
+/* TLBTR2 */
+#define GET_TLBTR2_ASID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_ASID)
+#define GET_TLBTR2_V(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_V)
+#define GET_TLBTR2_NSTID(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NSTID)
+#define GET_TLBTR2_NV(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_NV)
+#define GET_TLBTR2_VA(b) GET_GLOBAL_FIELD(b, TLBTR2, TLBTR2_VA)
+
+
+/* Context Register setters / getters */
+/* Context Register setters */
+/* ACTLR */
+#define SET_CFERE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFERE, v)
+#define SET_CFEIE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFEIE, v)
+#define SET_PTSHCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG, v)
+#define SET_RCOSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCOSH, v)
+#define SET_RCISH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCISH, v)
+#define SET_RCNSH(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, RCNSH, v)
+#define SET_PRIVCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG, v)
+#define SET_DNA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNA, v)
+#define SET_DNLV2PA(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA, v)
+#define SET_TLBMCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG, v)
+#define SET_CFCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, CFCFG, v)
+#define SET_TIPCF(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, TIPCF, v)
+#define SET_V2PCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG, v)
+#define SET_HUME(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, HUME, v)
+#define SET_PTMTCFG(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG, v)
+#define SET_PTMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE, v)
+
+
+/* BFBCR */
+#define SET_BFBDFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE, v)
+#define SET_BFBSFE(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE, v)
+#define SET_SFVS(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SFVS, v)
+#define SET_FLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, FLVIC, v)
+#define SET_SLVIC(b, c, v) SET_CONTEXT_FIELD(b, c, BFBCR, SLVIC, v)
+
+
+/* CONTEXTIDR */
+#define SET_CONTEXTIDR_ASID(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID, v)
+#define SET_CONTEXTIDR_PROCID(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID, v)
+
+
+/* FSR */
+#define SET_TF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TF, v)
+#define SET_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, AFF, v)
+#define SET_APF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, APF, v)
+#define SET_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, TLBMF, v)
+#define SET_HTWDEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWDEEF, v)
+#define SET_HTWSEEF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, HTWSEEF, v)
+#define SET_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MHF, v)
+#define SET_SL(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SL, v)
+#define SET_SS(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, SS, v)
+#define SET_MULTI(b, c, v) SET_CONTEXT_FIELD(b, c, FSR, MULTI, v)
+
+
+/* FSYNR0 */
+#define SET_AMID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, AMID, v)
+#define SET_APID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, APID, v)
+#define SET_ABID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ABID, v)
+#define SET_ATID(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR0, ATID, v)
+
+
+/* FSYNR1 */
+#define SET_AMEMTYPE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE, v)
+#define SET_ASHARED(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED, v)
+#define SET_AINNERSHARED(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED, v)
+#define SET_APRIV(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APRIV, v)
+#define SET_APROTNS(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS, v)
+#define SET_AINST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AINST, v)
+#define SET_AWRITE(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE, v)
+#define SET_ABURST(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ABURST, v)
+#define SET_ALEN(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALEN, v)
+#define SET_FSYNR1_ASIZE(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE, v)
+#define SET_ALOCK(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK, v)
+#define SET_AFULL(b, c, v) SET_CONTEXT_FIELD(b, c, FSYNR1, AFULL, v)
+
+
+/* NMRR */
+#define SET_ICPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC0, v)
+#define SET_ICPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC1, v)
+#define SET_ICPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC2, v)
+#define SET_ICPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC3, v)
+#define SET_ICPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC4, v)
+#define SET_ICPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC5, v)
+#define SET_ICPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC6, v)
+#define SET_ICPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, ICPC7, v)
+#define SET_OCPC0(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC0, v)
+#define SET_OCPC1(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC1, v)
+#define SET_OCPC2(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC2, v)
+#define SET_OCPC3(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC3, v)
+#define SET_OCPC4(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC4, v)
+#define SET_OCPC5(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC5, v)
+#define SET_OCPC6(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC6, v)
+#define SET_OCPC7(b, c, v) SET_CONTEXT_FIELD(b, c, NMRR, OCPC7, v)
+
+
+/* PAR */
+#define SET_FAULT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT, v)
+
+#define SET_FAULT_TF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TF, v)
+#define SET_FAULT_AFF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF, v)
+#define SET_FAULT_APF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_APF, v)
+#define SET_FAULT_TLBMF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF, v)
+#define SET_FAULT_HTWDEEF(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF, v)
+#define SET_FAULT_HTWSEEF(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF, v)
+#define SET_FAULT_MHF(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF, v)
+#define SET_FAULT_SL(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SL, v)
+#define SET_FAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, FAULT_SS, v)
+
+#define SET_NOFAULT_SS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SS, v)
+#define SET_NOFAULT_MT(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_MT, v)
+#define SET_NOFAULT_SH(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_SH, v)
+#define SET_NOFAULT_NS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NS, v)
+#define SET_NOFAULT_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NOFAULT_NOS, v)
+#define SET_NPFAULT_PA(b, c, v) SET_CONTEXT_FIELD(b, c, PAR, NPFAULT_PA, v)
+
+
+/* PRRR */
+#define SET_MTC0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC0, v)
+#define SET_MTC1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC1, v)
+#define SET_MTC2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC2, v)
+#define SET_MTC3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC3, v)
+#define SET_MTC4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC4, v)
+#define SET_MTC5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC5, v)
+#define SET_MTC6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC6, v)
+#define SET_MTC7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, MTC7, v)
+#define SET_SHDSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH0, v)
+#define SET_SHDSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHDSH1, v)
+#define SET_SHNMSH0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0, v)
+#define SET_SHNMSH1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1, v)
+#define SET_NOS0(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS0, v)
+#define SET_NOS1(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS1, v)
+#define SET_NOS2(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS2, v)
+#define SET_NOS3(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS3, v)
+#define SET_NOS4(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS4, v)
+#define SET_NOS5(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS5, v)
+#define SET_NOS6(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS6, v)
+#define SET_NOS7(b, c, v) SET_CONTEXT_FIELD(b, c, PRRR, NOS7, v)
+
+
+/* RESUME */
+#define SET_TNR(b, c, v) SET_CONTEXT_FIELD(b, c, RESUME, TNR, v)
+
+
+/* SCTLR */
+#define SET_M(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, M, v)
+#define SET_TRE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, TRE, v)
+#define SET_AFE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFE, v)
+#define SET_HAF(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, HAF, v)
+#define SET_BE(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, BE, v)
+#define SET_AFFD(b, c, v) SET_CONTEXT_FIELD(b, c, SCTLR, AFFD, v)
+
+
+/* TLBLKCR */
+#define SET_LKE(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, LKE, v)
+#define SET_TLBLKCR_TLBIALLCFG(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG, v)
+#define SET_TLBIASIDCFG(b, c, v) \
+ SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG, v)
+#define SET_TLBIVAACFG(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG, v)
+#define SET_FLOOR(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR, v)
+#define SET_VICTIM(b, c, v) SET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM, v)
+
+
+/* TTBCR */
+#define SET_N(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, N, v)
+#define SET_PD0(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD0, v)
+#define SET_PD1(b, c, v) SET_CONTEXT_FIELD(b, c, TTBCR, PD1, v)
+
+
+/* TTBR0 */
+#define SET_TTBR0_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH, v)
+#define SET_TTBR0_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH, v)
+#define SET_TTBR0_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN, v)
+#define SET_TTBR0_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS, v)
+#define SET_TTBR0_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL, v)
+#define SET_TTBR0_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA, v)
+
+
+/* TTBR1 */
+#define SET_TTBR1_IRGNH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH, v)
+#define SET_TTBR1_SH(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH, v)
+#define SET_TTBR1_ORGN(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN, v)
+#define SET_TTBR1_NOS(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS, v)
+#define SET_TTBR1_IRGNL(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL, v)
+#define SET_TTBR1_PA(b, c, v) SET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA, v)
+
+
+/* V2PSR */
+#define SET_HIT(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, HIT, v)
+#define SET_INDEX(b, c, v) SET_CONTEXT_FIELD(b, c, V2PSR, INDEX, v)
+
+
+/* Context Register getters */
+/* ACTLR */
+#define GET_CFERE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFERE)
+#define GET_CFEIE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFEIE)
+#define GET_PTSHCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTSHCFG)
+#define GET_RCOSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCOSH)
+#define GET_RCISH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCISH)
+#define GET_RCNSH(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, RCNSH)
+#define GET_PRIVCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PRIVCFG)
+#define GET_DNA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNA)
+#define GET_DNLV2PA(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, DNLV2PA)
+#define GET_TLBMCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TLBMCFG)
+#define GET_CFCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, CFCFG)
+#define GET_TIPCF(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, TIPCF)
+#define GET_V2PCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, V2PCFG)
+#define GET_HUME(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, HUME)
+#define GET_PTMTCFG(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMTCFG)
+#define GET_PTMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, ACTLR, PTMEMTYPE)
+
+/* BFBCR */
+#define GET_BFBDFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBDFE)
+#define GET_BFBSFE(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, BFBSFE)
+#define GET_SFVS(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SFVS)
+#define GET_FLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, FLVIC)
+#define GET_SLVIC(b, c) GET_CONTEXT_FIELD(b, c, BFBCR, SLVIC)
+
+
+/* CONTEXTIDR */
+#define GET_CONTEXTIDR_ASID(b, c) \
+ GET_CONTEXT_FIELD(b, c, CONTEXTIDR, CONTEXTIDR_ASID)
+#define GET_CONTEXTIDR_PROCID(b, c) GET_CONTEXT_FIELD(b, c, CONTEXTIDR, PROCID)
+
+
+/* FSR */
+#define GET_TF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TF)
+#define GET_AFF(b, c) GET_CONTEXT_FIELD(b, c, FSR, AFF)
+#define GET_APF(b, c) GET_CONTEXT_FIELD(b, c, FSR, APF)
+#define GET_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, FSR, TLBMF)
+#define GET_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWDEEF)
+#define GET_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, FSR, HTWSEEF)
+#define GET_MHF(b, c) GET_CONTEXT_FIELD(b, c, FSR, MHF)
+#define GET_SL(b, c) GET_CONTEXT_FIELD(b, c, FSR, SL)
+#define GET_SS(b, c) GET_CONTEXT_FIELD(b, c, FSR, SS)
+#define GET_MULTI(b, c) GET_CONTEXT_FIELD(b, c, FSR, MULTI)
+
+
+/* FSYNR0 */
+#define GET_AMID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, AMID)
+#define GET_APID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, APID)
+#define GET_ABID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ABID)
+#define GET_ATID(b, c) GET_CONTEXT_FIELD(b, c, FSYNR0, ATID)
+
+
+/* FSYNR1 */
+#define GET_AMEMTYPE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AMEMTYPE)
+#define GET_ASHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ASHARED)
+#define GET_AINNERSHARED(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINNERSHARED)
+#define GET_APRIV(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APRIV)
+#define GET_APROTNS(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, APROTNS)
+#define GET_AINST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AINST)
+#define GET_AWRITE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AWRITE)
+#define GET_ABURST(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ABURST)
+#define GET_ALEN(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALEN)
+#define GET_FSYNR1_ASIZE(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, FSYNR1_ASIZE)
+#define GET_ALOCK(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, ALOCK)
+#define GET_AFULL(b, c) GET_CONTEXT_FIELD(b, c, FSYNR1, AFULL)
+
+
+/* NMRR */
+#define GET_ICPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC0)
+#define GET_ICPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC1)
+#define GET_ICPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC2)
+#define GET_ICPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC3)
+#define GET_ICPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC4)
+#define GET_ICPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC5)
+#define GET_ICPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC6)
+#define GET_ICPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, ICPC7)
+#define GET_OCPC0(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC0)
+#define GET_OCPC1(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC1)
+#define GET_OCPC2(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC2)
+#define GET_OCPC3(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC3)
+#define GET_OCPC4(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC4)
+#define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5)
+#define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6)
+#define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7)
+#define NMRR_ICP(nmrr, n) (((nmrr) & (3 << ((n) * 2))) >> ((n) * 2))
+#define NMRR_OCP(nmrr, n) (((nmrr) & (3 << ((n) * 2 + 16))) >> \
+ ((n) * 2 + 16))
+
+/* PAR */
+#define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT)
+
+#define GET_FAULT_TF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TF)
+#define GET_FAULT_AFF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_AFF)
+#define GET_FAULT_APF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_APF)
+#define GET_FAULT_TLBMF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_TLBMF)
+#define GET_FAULT_HTWDEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWDEEF)
+#define GET_FAULT_HTWSEEF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_HTWSEEF)
+#define GET_FAULT_MHF(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_MHF)
+#define GET_FAULT_SL(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SL)
+#define GET_FAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT_SS)
+
+#define GET_NOFAULT_SS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SS)
+#define GET_NOFAULT_MT(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_MT)
+#define GET_NOFAULT_SH(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_SH)
+#define GET_NOFAULT_NS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NS)
+#define GET_NOFAULT_NOS(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NOFAULT_NOS)
+#define GET_NPFAULT_PA(b, c) GET_CONTEXT_FIELD(b, c, PAR, PAR_NPFAULT_PA)
+
+
+/* PRRR */
+#define GET_MTC0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC0)
+#define GET_MTC1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC1)
+#define GET_MTC2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC2)
+#define GET_MTC3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC3)
+#define GET_MTC4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC4)
+#define GET_MTC5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC5)
+#define GET_MTC6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC6)
+#define GET_MTC7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, MTC7)
+#define GET_SHDSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH0)
+#define GET_SHDSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHDSH1)
+#define GET_SHNMSH0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH0)
+#define GET_SHNMSH1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, SHNMSH1)
+#define GET_NOS0(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS0)
+#define GET_NOS1(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS1)
+#define GET_NOS2(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS2)
+#define GET_NOS3(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS3)
+#define GET_NOS4(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS4)
+#define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5)
+#define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6)
+#define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7)
+#define PRRR_NOS(prrr, n) ((prrr) & (1 << ((n) + 24)) ? 1 : 0)
+#define PRRR_MT(prrr, n) ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2)))
+
+
+/* RESUME */
+#define GET_TNR(b, c) GET_CONTEXT_FIELD(b, c, RESUME, TNR)
+
+
+/* SCTLR */
+#define GET_M(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, M)
+#define GET_TRE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, TRE)
+#define GET_AFE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFE)
+#define GET_HAF(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, HAF)
+#define GET_BE(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, BE)
+#define GET_AFFD(b, c) GET_CONTEXT_FIELD(b, c, SCTLR, AFFD)
+
+
+/* TLBLKCR */
+#define GET_LKE(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, LKE)
+#define GET_TLBLCKR_TLBIALLCFG(b, c) \
+ GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBLCKR_TLBIALLCFG)
+#define GET_TLBIASIDCFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIASIDCFG)
+#define GET_TLBIVAACFG(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, TLBIVAACFG)
+#define GET_FLOOR(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, FLOOR)
+#define GET_VICTIM(b, c) GET_CONTEXT_FIELD(b, c, TLBLKCR, VICTIM)
+
+
+/* TTBCR */
+#define GET_N(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, N)
+#define GET_PD0(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD0)
+#define GET_PD1(b, c) GET_CONTEXT_FIELD(b, c, TTBCR, PD1)
+
+
+/* TTBR0 */
+#define GET_TTBR0_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNH)
+#define GET_TTBR0_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_SH)
+#define GET_TTBR0_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_ORGN)
+#define GET_TTBR0_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_NOS)
+#define GET_TTBR0_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_IRGNL)
+#define GET_TTBR0_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR0, TTBR0_PA)
+
+
+/* TTBR1 */
+#define GET_TTBR1_IRGNH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNH)
+#define GET_TTBR1_SH(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_SH)
+#define GET_TTBR1_ORGN(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_ORGN)
+#define GET_TTBR1_NOS(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_NOS)
+#define GET_TTBR1_IRGNL(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_IRGNL)
+#define GET_TTBR1_PA(b, c) GET_CONTEXT_FIELD(b, c, TTBR1, TTBR1_PA)
+
+
+/* V2PSR */
+#define GET_HIT(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, HIT)
+#define GET_INDEX(b, c) GET_CONTEXT_FIELD(b, c, V2PSR, INDEX)
+
+
+/* Global Registers */
+#define M2VCBR_N (0xFF000)
+#define CBACR_N (0xFF800)
+#define TLBRSW (0xFFE00)
+#define TLBTR0 (0xFFE80)
+#define TLBTR1 (0xFFE84)
+#define TLBTR2 (0xFFE88)
+#define TESTBUSCR (0xFFE8C)
+#define GLOBAL_TLBIALL (0xFFF00)
+#define TLBIVMID (0xFFF04)
+#define CR (0xFFF80)
+#define EAR (0xFFF84)
+#define ESR (0xFFF88)
+#define ESRRESTORE (0xFFF8C)
+#define ESYNR0 (0xFFF90)
+#define ESYNR1 (0xFFF94)
+#define REV (0xFFFF4)
+#define IDR (0xFFFF8)
+#define RPU_ACR (0xFFFFC)
+
+
+/* Context Bank Registers */
+#define SCTLR (0x000)
+#define ACTLR (0x004)
+#define CONTEXTIDR (0x008)
+#define TTBR0 (0x010)
+#define TTBR1 (0x014)
+#define TTBCR (0x018)
+#define PAR (0x01C)
+#define FSR (0x020)
+#define FSRRESTORE (0x024)
+#define FAR (0x028)
+#define FSYNR0 (0x02C)
+#define FSYNR1 (0x030)
+#define PRRR (0x034)
+#define NMRR (0x038)
+#define TLBLCKR (0x03C)
+#define V2PSR (0x040)
+#define TLBFLPTER (0x044)
+#define TLBSLPTER (0x048)
+#define BFBCR (0x04C)
+#define CTX_TLBIALL (0x800)
+#define TLBIASID (0x804)
+#define TLBIVA (0x808)
+#define TLBIVAA (0x80C)
+#define V2PPR (0x810)
+#define V2PPW (0x814)
+#define V2PUR (0x818)
+#define V2PUW (0x81C)
+#define RESUME (0x820)
+
+
+/* Global Register Fields */
+/* CBACRn */
+#define RWVMID (RWVMID_MASK << RWVMID_SHIFT)
+#define RWE (RWE_MASK << RWE_SHIFT)
+#define RWGE (RWGE_MASK << RWGE_SHIFT)
+#define CBVMID (CBVMID_MASK << CBVMID_SHIFT)
+#define IRPTNDX (IRPTNDX_MASK << IRPTNDX_SHIFT)
+
+
+/* CR */
+#define RPUE (RPUE_MASK << RPUE_SHIFT)
+#define RPUERE (RPUERE_MASK << RPUERE_SHIFT)
+#define RPUEIE (RPUEIE_MASK << RPUEIE_SHIFT)
+#define DCDEE (DCDEE_MASK << DCDEE_SHIFT)
+#define CLIENTPD (CLIENTPD_MASK << CLIENTPD_SHIFT)
+#define STALLD (STALLD_MASK << STALLD_SHIFT)
+#define TLBLKCRWE (TLBLKCRWE_MASK << TLBLKCRWE_SHIFT)
+#define CR_TLBIALLCFG (CR_TLBIALLCFG_MASK << CR_TLBIALLCFG_SHIFT)
+#define TLBIVMIDCFG (TLBIVMIDCFG_MASK << TLBIVMIDCFG_SHIFT)
+#define CR_HUME (CR_HUME_MASK << CR_HUME_SHIFT)
+
+
+/* ESR */
+#define CFG (CFG_MASK << CFG_SHIFT)
+#define BYPASS (BYPASS_MASK << BYPASS_SHIFT)
+#define ESR_MULTI (ESR_MULTI_MASK << ESR_MULTI_SHIFT)
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID (ESYNR0_AMID_MASK << ESYNR0_AMID_SHIFT)
+#define ESYNR0_APID (ESYNR0_APID_MASK << ESYNR0_APID_SHIFT)
+#define ESYNR0_ABID (ESYNR0_ABID_MASK << ESYNR0_ABID_SHIFT)
+#define ESYNR0_AVMID (ESYNR0_AVMID_MASK << ESYNR0_AVMID_SHIFT)
+#define ESYNR0_ATID (ESYNR0_ATID_MASK << ESYNR0_ATID_SHIFT)
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE (ESYNR1_AMEMTYPE_MASK << ESYNR1_AMEMTYPE_SHIFT)
+#define ESYNR1_ASHARED (ESYNR1_ASHARED_MASK << ESYNR1_ASHARED_SHIFT)
+#define ESYNR1_AINNERSHARED (ESYNR1_AINNERSHARED_MASK<< \
+ ESYNR1_AINNERSHARED_SHIFT)
+#define ESYNR1_APRIV (ESYNR1_APRIV_MASK << ESYNR1_APRIV_SHIFT)
+#define ESYNR1_APROTNS (ESYNR1_APROTNS_MASK << ESYNR1_APROTNS_SHIFT)
+#define ESYNR1_AINST (ESYNR1_AINST_MASK << ESYNR1_AINST_SHIFT)
+#define ESYNR1_AWRITE (ESYNR1_AWRITE_MASK << ESYNR1_AWRITE_SHIFT)
+#define ESYNR1_ABURST (ESYNR1_ABURST_MASK << ESYNR1_ABURST_SHIFT)
+#define ESYNR1_ALEN (ESYNR1_ALEN_MASK << ESYNR1_ALEN_SHIFT)
+#define ESYNR1_ASIZE (ESYNR1_ASIZE_MASK << ESYNR1_ASIZE_SHIFT)
+#define ESYNR1_ALOCK (ESYNR1_ALOCK_MASK << ESYNR1_ALOCK_SHIFT)
+#define ESYNR1_AOOO (ESYNR1_AOOO_MASK << ESYNR1_AOOO_SHIFT)
+#define ESYNR1_AFULL (ESYNR1_AFULL_MASK << ESYNR1_AFULL_SHIFT)
+#define ESYNR1_AC (ESYNR1_AC_MASK << ESYNR1_AC_SHIFT)
+#define ESYNR1_DCD (ESYNR1_DCD_MASK << ESYNR1_DCD_SHIFT)
+
+
+/* IDR */
+#define NM2VCBMT (NM2VCBMT_MASK << NM2VCBMT_SHIFT)
+#define HTW (HTW_MASK << HTW_SHIFT)
+#define HUM (HUM_MASK << HUM_SHIFT)
+#define TLBSIZE (TLBSIZE_MASK << TLBSIZE_SHIFT)
+#define NCB (NCB_MASK << NCB_SHIFT)
+#define NIRPT (NIRPT_MASK << NIRPT_SHIFT)
+
+
+/* M2VCBRn */
+#define VMID (VMID_MASK << VMID_SHIFT)
+#define CBNDX (CBNDX_MASK << CBNDX_SHIFT)
+#define BYPASSD (BYPASSD_MASK << BYPASSD_SHIFT)
+#define BPRCOSH (BPRCOSH_MASK << BPRCOSH_SHIFT)
+#define BPRCISH (BPRCISH_MASK << BPRCISH_SHIFT)
+#define BPRCNSH (BPRCNSH_MASK << BPRCNSH_SHIFT)
+#define BPSHCFG (BPSHCFG_MASK << BPSHCFG_SHIFT)
+#define NSCFG (NSCFG_MASK << NSCFG_SHIFT)
+#define BPMTCFG (BPMTCFG_MASK << BPMTCFG_SHIFT)
+#define BPMEMTYPE (BPMEMTYPE_MASK << BPMEMTYPE_SHIFT)
+
+
+/* REV */
+#define IDR_MINOR (MINOR_MASK << MINOR_SHIFT)
+#define IDR_MAJOR (MAJOR_MASK << MAJOR_SHIFT)
+
+
+/* TESTBUSCR */
+#define TBE (TBE_MASK << TBE_SHIFT)
+#define SPDMBE (SPDMBE_MASK << SPDMBE_SHIFT)
+#define WGSEL (WGSEL_MASK << WGSEL_SHIFT)
+#define TBLSEL (TBLSEL_MASK << TBLSEL_SHIFT)
+#define TBHSEL (TBHSEL_MASK << TBHSEL_SHIFT)
+#define SPDM0SEL (SPDM0SEL_MASK << SPDM0SEL_SHIFT)
+#define SPDM1SEL (SPDM1SEL_MASK << SPDM1SEL_SHIFT)
+#define SPDM2SEL (SPDM2SEL_MASK << SPDM2SEL_SHIFT)
+#define SPDM3SEL (SPDM3SEL_MASK << SPDM3SEL_SHIFT)
+
+
+/* TLBIVMID */
+#define TLBIVMID_VMID (TLBIVMID_VMID_MASK << TLBIVMID_VMID_SHIFT)
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX (TLBRSW_INDEX_MASK << TLBRSW_INDEX_SHIFT)
+#define TLBBFBS (TLBBFBS_MASK << TLBBFBS_SHIFT)
+
+
+/* TLBTR0 */
+#define PR (PR_MASK << PR_SHIFT)
+#define PW (PW_MASK << PW_SHIFT)
+#define UR (UR_MASK << UR_SHIFT)
+#define UW (UW_MASK << UW_SHIFT)
+#define XN (XN_MASK << XN_SHIFT)
+#define NSDESC (NSDESC_MASK << NSDESC_SHIFT)
+#define ISH (ISH_MASK << ISH_SHIFT)
+#define SH (SH_MASK << SH_SHIFT)
+#define MT (MT_MASK << MT_SHIFT)
+#define DPSIZR (DPSIZR_MASK << DPSIZR_SHIFT)
+#define DPSIZC (DPSIZC_MASK << DPSIZC_SHIFT)
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID (TLBTR1_VMID_MASK << TLBTR1_VMID_SHIFT)
+#define TLBTR1_PA (TLBTR1_PA_MASK << TLBTR1_PA_SHIFT)
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID (TLBTR2_ASID_MASK << TLBTR2_ASID_SHIFT)
+#define TLBTR2_V (TLBTR2_V_MASK << TLBTR2_V_SHIFT)
+#define TLBTR2_NSTID (TLBTR2_NSTID_MASK << TLBTR2_NSTID_SHIFT)
+#define TLBTR2_NV (TLBTR2_NV_MASK << TLBTR2_NV_SHIFT)
+#define TLBTR2_VA (TLBTR2_VA_MASK << TLBTR2_VA_SHIFT)
+
+
+/* Context Register Fields */
+/* ACTLR */
+#define CFERE (CFERE_MASK << CFERE_SHIFT)
+#define CFEIE (CFEIE_MASK << CFEIE_SHIFT)
+#define PTSHCFG (PTSHCFG_MASK << PTSHCFG_SHIFT)
+#define RCOSH (RCOSH_MASK << RCOSH_SHIFT)
+#define RCISH (RCISH_MASK << RCISH_SHIFT)
+#define RCNSH (RCNSH_MASK << RCNSH_SHIFT)
+#define PRIVCFG (PRIVCFG_MASK << PRIVCFG_SHIFT)
+#define DNA (DNA_MASK << DNA_SHIFT)
+#define DNLV2PA (DNLV2PA_MASK << DNLV2PA_SHIFT)
+#define TLBMCFG (TLBMCFG_MASK << TLBMCFG_SHIFT)
+#define CFCFG (CFCFG_MASK << CFCFG_SHIFT)
+#define TIPCF (TIPCF_MASK << TIPCF_SHIFT)
+#define V2PCFG (V2PCFG_MASK << V2PCFG_SHIFT)
+#define HUME (HUME_MASK << HUME_SHIFT)
+#define PTMTCFG (PTMTCFG_MASK << PTMTCFG_SHIFT)
+#define PTMEMTYPE (PTMEMTYPE_MASK << PTMEMTYPE_SHIFT)
+
+
+/* BFBCR */
+#define BFBDFE (BFBDFE_MASK << BFBDFE_SHIFT)
+#define BFBSFE (BFBSFE_MASK << BFBSFE_SHIFT)
+#define SFVS (SFVS_MASK << SFVS_SHIFT)
+#define FLVIC (FLVIC_MASK << FLVIC_SHIFT)
+#define SLVIC (SLVIC_MASK << SLVIC_SHIFT)
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID (CONTEXTIDR_ASID_MASK << CONTEXTIDR_ASID_SHIFT)
+#define PROCID (PROCID_MASK << PROCID_SHIFT)
+
+
+/* FSR */
+#define TF (TF_MASK << TF_SHIFT)
+#define AFF (AFF_MASK << AFF_SHIFT)
+#define APF (APF_MASK << APF_SHIFT)
+#define TLBMF (TLBMF_MASK << TLBMF_SHIFT)
+#define HTWDEEF (HTWDEEF_MASK << HTWDEEF_SHIFT)
+#define HTWSEEF (HTWSEEF_MASK << HTWSEEF_SHIFT)
+#define MHF (MHF_MASK << MHF_SHIFT)
+#define SL (SL_MASK << SL_SHIFT)
+#define SS (SS_MASK << SS_SHIFT)
+#define MULTI (MULTI_MASK << MULTI_SHIFT)
+
+
+/* FSYNR0 */
+#define AMID (AMID_MASK << AMID_SHIFT)
+#define APID (APID_MASK << APID_SHIFT)
+#define ABID (ABID_MASK << ABID_SHIFT)
+#define ATID (ATID_MASK << ATID_SHIFT)
+
+
+/* FSYNR1 */
+#define AMEMTYPE (AMEMTYPE_MASK << AMEMTYPE_SHIFT)
+#define ASHARED (ASHARED_MASK << ASHARED_SHIFT)
+#define AINNERSHARED (AINNERSHARED_MASK << AINNERSHARED_SHIFT)
+#define APRIV (APRIV_MASK << APRIV_SHIFT)
+#define APROTNS (APROTNS_MASK << APROTNS_SHIFT)
+#define AINST (AINST_MASK << AINST_SHIFT)
+#define AWRITE (AWRITE_MASK << AWRITE_SHIFT)
+#define ABURST (ABURST_MASK << ABURST_SHIFT)
+#define ALEN (ALEN_MASK << ALEN_SHIFT)
+#define FSYNR1_ASIZE (FSYNR1_ASIZE_MASK << FSYNR1_ASIZE_SHIFT)
+#define ALOCK (ALOCK_MASK << ALOCK_SHIFT)
+#define AFULL (AFULL_MASK << AFULL_SHIFT)
+
+
+/* NMRR */
+#define ICPC0 (ICPC0_MASK << ICPC0_SHIFT)
+#define ICPC1 (ICPC1_MASK << ICPC1_SHIFT)
+#define ICPC2 (ICPC2_MASK << ICPC2_SHIFT)
+#define ICPC3 (ICPC3_MASK << ICPC3_SHIFT)
+#define ICPC4 (ICPC4_MASK << ICPC4_SHIFT)
+#define ICPC5 (ICPC5_MASK << ICPC5_SHIFT)
+#define ICPC6 (ICPC6_MASK << ICPC6_SHIFT)
+#define ICPC7 (ICPC7_MASK << ICPC7_SHIFT)
+#define OCPC0 (OCPC0_MASK << OCPC0_SHIFT)
+#define OCPC1 (OCPC1_MASK << OCPC1_SHIFT)
+#define OCPC2 (OCPC2_MASK << OCPC2_SHIFT)
+#define OCPC3 (OCPC3_MASK << OCPC3_SHIFT)
+#define OCPC4 (OCPC4_MASK << OCPC4_SHIFT)
+#define OCPC5 (OCPC5_MASK << OCPC5_SHIFT)
+#define OCPC6 (OCPC6_MASK << OCPC6_SHIFT)
+#define OCPC7 (OCPC7_MASK << OCPC7_SHIFT)
+
+
+/* PAR */
+#define FAULT (FAULT_MASK << FAULT_SHIFT)
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF (FAULT_TF_MASK << FAULT_TF_SHIFT)
+#define FAULT_AFF (FAULT_AFF_MASK << FAULT_AFF_SHIFT)
+#define FAULT_APF (FAULT_APF_MASK << FAULT_APF_SHIFT)
+#define FAULT_TLBMF (FAULT_TLBMF_MASK << FAULT_TLBMF_SHIFT)
+#define FAULT_HTWDEEF (FAULT_HTWDEEF_MASK << FAULT_HTWDEEF_SHIFT)
+#define FAULT_HTWSEEF (FAULT_HTWSEEF_MASK << FAULT_HTWSEEF_SHIFT)
+#define FAULT_MHF (FAULT_MHF_MASK << FAULT_MHF_SHIFT)
+#define FAULT_SL (FAULT_SL_MASK << FAULT_SL_SHIFT)
+#define FAULT_SS (FAULT_SS_MASK << FAULT_SS_SHIFT)
+
+/* If NO fault is present, the following fields are in effect */
+/* (FAULT remains as before) */
+#define PAR_NOFAULT_SS (PAR_NOFAULT_SS_MASK << PAR_NOFAULT_SS_SHIFT)
+#define PAR_NOFAULT_MT (PAR_NOFAULT_MT_MASK << PAR_NOFAULT_MT_SHIFT)
+#define PAR_NOFAULT_SH (PAR_NOFAULT_SH_MASK << PAR_NOFAULT_SH_SHIFT)
+#define PAR_NOFAULT_NS (PAR_NOFAULT_NS_MASK << PAR_NOFAULT_NS_SHIFT)
+#define PAR_NOFAULT_NOS (PAR_NOFAULT_NOS_MASK << PAR_NOFAULT_NOS_SHIFT)
+#define PAR_NPFAULT_PA (PAR_NPFAULT_PA_MASK << PAR_NPFAULT_PA_SHIFT)
+
+
+/* PRRR */
+#define MTC0 (MTC0_MASK << MTC0_SHIFT)
+#define MTC1 (MTC1_MASK << MTC1_SHIFT)
+#define MTC2 (MTC2_MASK << MTC2_SHIFT)
+#define MTC3 (MTC3_MASK << MTC3_SHIFT)
+#define MTC4 (MTC4_MASK << MTC4_SHIFT)
+#define MTC5 (MTC5_MASK << MTC5_SHIFT)
+#define MTC6 (MTC6_MASK << MTC6_SHIFT)
+#define MTC7 (MTC7_MASK << MTC7_SHIFT)
+#define SHDSH0 (SHDSH0_MASK << SHDSH0_SHIFT)
+#define SHDSH1 (SHDSH1_MASK << SHDSH1_SHIFT)
+#define SHNMSH0 (SHNMSH0_MASK << SHNMSH0_SHIFT)
+#define SHNMSH1 (SHNMSH1_MASK << SHNMSH1_SHIFT)
+#define NOS0 (NOS0_MASK << NOS0_SHIFT)
+#define NOS1 (NOS1_MASK << NOS1_SHIFT)
+#define NOS2 (NOS2_MASK << NOS2_SHIFT)
+#define NOS3 (NOS3_MASK << NOS3_SHIFT)
+#define NOS4 (NOS4_MASK << NOS4_SHIFT)
+#define NOS5 (NOS5_MASK << NOS5_SHIFT)
+#define NOS6 (NOS6_MASK << NOS6_SHIFT)
+#define NOS7 (NOS7_MASK << NOS7_SHIFT)
+
+
+/* RESUME */
+#define TNR (TNR_MASK << TNR_SHIFT)
+
+
+/* SCTLR */
+#define M (M_MASK << M_SHIFT)
+#define TRE (TRE_MASK << TRE_SHIFT)
+#define AFE (AFE_MASK << AFE_SHIFT)
+#define HAF (HAF_MASK << HAF_SHIFT)
+#define BE (BE_MASK << BE_SHIFT)
+#define AFFD (AFFD_MASK << AFFD_SHIFT)
+
+
+/* TLBIASID */
+#define TLBIASID_ASID (TLBIASID_ASID_MASK << TLBIASID_ASID_SHIFT)
+
+
+/* TLBIVA */
+#define TLBIVA_ASID (TLBIVA_ASID_MASK << TLBIVA_ASID_SHIFT)
+#define TLBIVA_VA (TLBIVA_VA_MASK << TLBIVA_VA_SHIFT)
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA (TLBIVAA_VA_MASK << TLBIVAA_VA_SHIFT)
+
+
+/* TLBLCKR */
+#define LKE (LKE_MASK << LKE_SHIFT)
+#define TLBLCKR_TLBIALLCFG (TLBLCKR_TLBIALLCFG_MASK<<TLBLCKR_TLBIALLCFG_SHIFT)
+#define TLBIASIDCFG (TLBIASIDCFG_MASK << TLBIASIDCFG_SHIFT)
+#define TLBIVAACFG (TLBIVAACFG_MASK << TLBIVAACFG_SHIFT)
+#define FLOOR (FLOOR_MASK << FLOOR_SHIFT)
+#define VICTIM (VICTIM_MASK << VICTIM_SHIFT)
+
+
+/* TTBCR */
+#define N (N_MASK << N_SHIFT)
+#define PD0 (PD0_MASK << PD0_SHIFT)
+#define PD1 (PD1_MASK << PD1_SHIFT)
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH (TTBR0_IRGNH_MASK << TTBR0_IRGNH_SHIFT)
+#define TTBR0_SH (TTBR0_SH_MASK << TTBR0_SH_SHIFT)
+#define TTBR0_ORGN (TTBR0_ORGN_MASK << TTBR0_ORGN_SHIFT)
+#define TTBR0_NOS (TTBR0_NOS_MASK << TTBR0_NOS_SHIFT)
+#define TTBR0_IRGNL (TTBR0_IRGNL_MASK << TTBR0_IRGNL_SHIFT)
+#define TTBR0_PA (TTBR0_PA_MASK << TTBR0_PA_SHIFT)
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH (TTBR1_IRGNH_MASK << TTBR1_IRGNH_SHIFT)
+#define TTBR1_SH (TTBR1_SH_MASK << TTBR1_SH_SHIFT)
+#define TTBR1_ORGN (TTBR1_ORGN_MASK << TTBR1_ORGN_SHIFT)
+#define TTBR1_NOS (TTBR1_NOS_MASK << TTBR1_NOS_SHIFT)
+#define TTBR1_IRGNL (TTBR1_IRGNL_MASK << TTBR1_IRGNL_SHIFT)
+#define TTBR1_PA (TTBR1_PA_MASK << TTBR1_PA_SHIFT)
+
+
+/* V2PSR */
+#define HIT (HIT_MASK << HIT_SHIFT)
+#define INDEX (INDEX_MASK << INDEX_SHIFT)
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX (V2Pxx_INDEX_MASK << V2Pxx_INDEX_SHIFT)
+#define V2Pxx_VA (V2Pxx_VA_MASK << V2Pxx_VA_SHIFT)
+
+
+/* Global Register Masks */
+/* CBACRn */
+#define RWVMID_MASK 0x1F
+#define RWE_MASK 0x01
+#define RWGE_MASK 0x01
+#define CBVMID_MASK 0x1F
+#define IRPTNDX_MASK 0xFF
+
+
+/* CR */
+#define RPUE_MASK 0x01
+#define RPUERE_MASK 0x01
+#define RPUEIE_MASK 0x01
+#define DCDEE_MASK 0x01
+#define CLIENTPD_MASK 0x01
+#define STALLD_MASK 0x01
+#define TLBLKCRWE_MASK 0x01
+#define CR_TLBIALLCFG_MASK 0x01
+#define TLBIVMIDCFG_MASK 0x01
+#define CR_HUME_MASK 0x01
+
+
+/* ESR */
+#define CFG_MASK 0x01
+#define BYPASS_MASK 0x01
+#define ESR_MULTI_MASK 0x01
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_MASK 0xFF
+#define ESYNR0_APID_MASK 0x1F
+#define ESYNR0_ABID_MASK 0x07
+#define ESYNR0_AVMID_MASK 0x1F
+#define ESYNR0_ATID_MASK 0xFF
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_MASK 0x07
+#define ESYNR1_ASHARED_MASK 0x01
+#define ESYNR1_AINNERSHARED_MASK 0x01
+#define ESYNR1_APRIV_MASK 0x01
+#define ESYNR1_APROTNS_MASK 0x01
+#define ESYNR1_AINST_MASK 0x01
+#define ESYNR1_AWRITE_MASK 0x01
+#define ESYNR1_ABURST_MASK 0x01
+#define ESYNR1_ALEN_MASK 0x0F
+#define ESYNR1_ASIZE_MASK 0x01
+#define ESYNR1_ALOCK_MASK 0x03
+#define ESYNR1_AOOO_MASK 0x01
+#define ESYNR1_AFULL_MASK 0x01
+#define ESYNR1_AC_MASK 0x01
+#define ESYNR1_DCD_MASK 0x01
+
+
+/* IDR */
+#define NM2VCBMT_MASK 0x1FF
+#define HTW_MASK 0x01
+#define HUM_MASK 0x01
+#define TLBSIZE_MASK 0x0F
+#define NCB_MASK 0xFF
+#define NIRPT_MASK 0xFF
+
+
+/* M2VCBRn */
+#define VMID_MASK 0x1F
+#define CBNDX_MASK 0xFF
+#define BYPASSD_MASK 0x01
+#define BPRCOSH_MASK 0x01
+#define BPRCISH_MASK 0x01
+#define BPRCNSH_MASK 0x01
+#define BPSHCFG_MASK 0x03
+#define NSCFG_MASK 0x03
+#define BPMTCFG_MASK 0x01
+#define BPMEMTYPE_MASK 0x07
+
+
+/* REV */
+#define MINOR_MASK 0x0F
+#define MAJOR_MASK 0x0F
+
+
+/* TESTBUSCR */
+#define TBE_MASK 0x01
+#define SPDMBE_MASK 0x01
+#define WGSEL_MASK 0x03
+#define TBLSEL_MASK 0x03
+#define TBHSEL_MASK 0x03
+#define SPDM0SEL_MASK 0x0F
+#define SPDM1SEL_MASK 0x0F
+#define SPDM2SEL_MASK 0x0F
+#define SPDM3SEL_MASK 0x0F
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_MASK 0x1F
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_MASK 0xFF
+#define TLBBFBS_MASK 0x03
+
+
+/* TLBTR0 */
+#define PR_MASK 0x01
+#define PW_MASK 0x01
+#define UR_MASK 0x01
+#define UW_MASK 0x01
+#define XN_MASK 0x01
+#define NSDESC_MASK 0x01
+#define ISH_MASK 0x01
+#define SH_MASK 0x01
+#define MT_MASK 0x07
+#define DPSIZR_MASK 0x07
+#define DPSIZC_MASK 0x07
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_MASK 0x1F
+#define TLBTR1_PA_MASK 0x000FFFFF
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_MASK 0xFF
+#define TLBTR2_V_MASK 0x01
+#define TLBTR2_NSTID_MASK 0x01
+#define TLBTR2_NV_MASK 0x01
+#define TLBTR2_VA_MASK 0x000FFFFF
+
+
+/* Global Register Shifts */
+/* CBACRn */
+#define RWVMID_SHIFT 0
+#define RWE_SHIFT 8
+#define RWGE_SHIFT 9
+#define CBVMID_SHIFT 16
+#define IRPTNDX_SHIFT 24
+
+
+/* CR */
+#define RPUE_SHIFT 0
+#define RPUERE_SHIFT 1
+#define RPUEIE_SHIFT 2
+#define DCDEE_SHIFT 3
+#define CLIENTPD_SHIFT 4
+#define STALLD_SHIFT 5
+#define TLBLKCRWE_SHIFT 6
+#define CR_TLBIALLCFG_SHIFT 7
+#define TLBIVMIDCFG_SHIFT 8
+#define CR_HUME_SHIFT 9
+
+
+/* ESR */
+#define CFG_SHIFT 0
+#define BYPASS_SHIFT 1
+#define ESR_MULTI_SHIFT 31
+
+
+/* ESYNR0 */
+#define ESYNR0_AMID_SHIFT 0
+#define ESYNR0_APID_SHIFT 8
+#define ESYNR0_ABID_SHIFT 13
+#define ESYNR0_AVMID_SHIFT 16
+#define ESYNR0_ATID_SHIFT 24
+
+
+/* ESYNR1 */
+#define ESYNR1_AMEMTYPE_SHIFT 0
+#define ESYNR1_ASHARED_SHIFT 3
+#define ESYNR1_AINNERSHARED_SHIFT 4
+#define ESYNR1_APRIV_SHIFT 5
+#define ESYNR1_APROTNS_SHIFT 6
+#define ESYNR1_AINST_SHIFT 7
+#define ESYNR1_AWRITE_SHIFT 8
+#define ESYNR1_ABURST_SHIFT 10
+#define ESYNR1_ALEN_SHIFT 12
+#define ESYNR1_ASIZE_SHIFT 16
+#define ESYNR1_ALOCK_SHIFT 20
+#define ESYNR1_AOOO_SHIFT 22
+#define ESYNR1_AFULL_SHIFT 24
+#define ESYNR1_AC_SHIFT 30
+#define ESYNR1_DCD_SHIFT 31
+
+
+/* IDR */
+#define NM2VCBMT_SHIFT 0
+#define HTW_SHIFT 9
+#define HUM_SHIFT 10
+#define TLBSIZE_SHIFT 12
+#define NCB_SHIFT 16
+#define NIRPT_SHIFT 24
+
+
+/* M2VCBRn */
+#define VMID_SHIFT 0
+#define CBNDX_SHIFT 8
+#define BYPASSD_SHIFT 16
+#define BPRCOSH_SHIFT 17
+#define BPRCISH_SHIFT 18
+#define BPRCNSH_SHIFT 19
+#define BPSHCFG_SHIFT 20
+#define NSCFG_SHIFT 22
+#define BPMTCFG_SHIFT 24
+#define BPMEMTYPE_SHIFT 25
+
+
+/* REV */
+#define MINOR_SHIFT 0
+#define MAJOR_SHIFT 4
+
+
+/* TESTBUSCR */
+#define TBE_SHIFT 0
+#define SPDMBE_SHIFT 1
+#define WGSEL_SHIFT 8
+#define TBLSEL_SHIFT 12
+#define TBHSEL_SHIFT 14
+#define SPDM0SEL_SHIFT 16
+#define SPDM1SEL_SHIFT 20
+#define SPDM2SEL_SHIFT 24
+#define SPDM3SEL_SHIFT 28
+
+
+/* TLBIMID */
+#define TLBIVMID_VMID_SHIFT 0
+
+
+/* TLBRSW */
+#define TLBRSW_INDEX_SHIFT 0
+#define TLBBFBS_SHIFT 8
+
+
+/* TLBTR0 */
+#define PR_SHIFT 0
+#define PW_SHIFT 1
+#define UR_SHIFT 2
+#define UW_SHIFT 3
+#define XN_SHIFT 4
+#define NSDESC_SHIFT 6
+#define ISH_SHIFT 7
+#define SH_SHIFT 8
+#define MT_SHIFT 9
+#define DPSIZR_SHIFT 16
+#define DPSIZC_SHIFT 20
+
+
+/* TLBTR1 */
+#define TLBTR1_VMID_SHIFT 0
+#define TLBTR1_PA_SHIFT 12
+
+
+/* TLBTR2 */
+#define TLBTR2_ASID_SHIFT 0
+#define TLBTR2_V_SHIFT 8
+#define TLBTR2_NSTID_SHIFT 9
+#define TLBTR2_NV_SHIFT 10
+#define TLBTR2_VA_SHIFT 12
+
+
+/* Context Register Masks */
+/* ACTLR */
+#define CFERE_MASK 0x01
+#define CFEIE_MASK 0x01
+#define PTSHCFG_MASK 0x03
+#define RCOSH_MASK 0x01
+#define RCISH_MASK 0x01
+#define RCNSH_MASK 0x01
+#define PRIVCFG_MASK 0x03
+#define DNA_MASK 0x01
+#define DNLV2PA_MASK 0x01
+#define TLBMCFG_MASK 0x03
+#define CFCFG_MASK 0x01
+#define TIPCF_MASK 0x01
+#define V2PCFG_MASK 0x03
+#define HUME_MASK 0x01
+#define PTMTCFG_MASK 0x01
+#define PTMEMTYPE_MASK 0x07
+
+
+/* BFBCR */
+#define BFBDFE_MASK 0x01
+#define BFBSFE_MASK 0x01
+#define SFVS_MASK 0x01
+#define FLVIC_MASK 0x0F
+#define SLVIC_MASK 0x0F
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_MASK 0xFF
+#define PROCID_MASK 0x00FFFFFF
+
+
+/* FSR */
+#define TF_MASK 0x01
+#define AFF_MASK 0x01
+#define APF_MASK 0x01
+#define TLBMF_MASK 0x01
+#define HTWDEEF_MASK 0x01
+#define HTWSEEF_MASK 0x01
+#define MHF_MASK 0x01
+#define SL_MASK 0x01
+#define SS_MASK 0x01
+#define MULTI_MASK 0x01
+
+
+/* FSYNR0 */
+#define AMID_MASK 0xFF
+#define APID_MASK 0x1F
+#define ABID_MASK 0x07
+#define ATID_MASK 0xFF
+
+
+/* FSYNR1 */
+#define AMEMTYPE_MASK 0x07
+#define ASHARED_MASK 0x01
+#define AINNERSHARED_MASK 0x01
+#define APRIV_MASK 0x01
+#define APROTNS_MASK 0x01
+#define AINST_MASK 0x01
+#define AWRITE_MASK 0x01
+#define ABURST_MASK 0x01
+#define ALEN_MASK 0x0F
+#define FSYNR1_ASIZE_MASK 0x07
+#define ALOCK_MASK 0x03
+#define AFULL_MASK 0x01
+
+
+/* NMRR */
+#define ICPC0_MASK 0x03
+#define ICPC1_MASK 0x03
+#define ICPC2_MASK 0x03
+#define ICPC3_MASK 0x03
+#define ICPC4_MASK 0x03
+#define ICPC5_MASK 0x03
+#define ICPC6_MASK 0x03
+#define ICPC7_MASK 0x03
+#define OCPC0_MASK 0x03
+#define OCPC1_MASK 0x03
+#define OCPC2_MASK 0x03
+#define OCPC3_MASK 0x03
+#define OCPC4_MASK 0x03
+#define OCPC5_MASK 0x03
+#define OCPC6_MASK 0x03
+#define OCPC7_MASK 0x03
+
+
+/* PAR */
+#define FAULT_MASK 0x01
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_MASK 0x01
+#define FAULT_AFF_MASK 0x01
+#define FAULT_APF_MASK 0x01
+#define FAULT_TLBMF_MASK 0x01
+#define FAULT_HTWDEEF_MASK 0x01
+#define FAULT_HTWSEEF_MASK 0x01
+#define FAULT_MHF_MASK 0x01
+#define FAULT_SL_MASK 0x01
+#define FAULT_SS_MASK 0x01
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_MASK 0x01
+#define PAR_NOFAULT_MT_MASK 0x07
+#define PAR_NOFAULT_SH_MASK 0x01
+#define PAR_NOFAULT_NS_MASK 0x01
+#define PAR_NOFAULT_NOS_MASK 0x01
+#define PAR_NPFAULT_PA_MASK 0x000FFFFF
+
+
+/* PRRR */
+#define MTC0_MASK 0x03
+#define MTC1_MASK 0x03
+#define MTC2_MASK 0x03
+#define MTC3_MASK 0x03
+#define MTC4_MASK 0x03
+#define MTC5_MASK 0x03
+#define MTC6_MASK 0x03
+#define MTC7_MASK 0x03
+#define SHDSH0_MASK 0x01
+#define SHDSH1_MASK 0x01
+#define SHNMSH0_MASK 0x01
+#define SHNMSH1_MASK 0x01
+#define NOS0_MASK 0x01
+#define NOS1_MASK 0x01
+#define NOS2_MASK 0x01
+#define NOS3_MASK 0x01
+#define NOS4_MASK 0x01
+#define NOS5_MASK 0x01
+#define NOS6_MASK 0x01
+#define NOS7_MASK 0x01
+
+
+/* RESUME */
+#define TNR_MASK 0x01
+
+
+/* SCTLR */
+#define M_MASK 0x01
+#define TRE_MASK 0x01
+#define AFE_MASK 0x01
+#define HAF_MASK 0x01
+#define BE_MASK 0x01
+#define AFFD_MASK 0x01
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_MASK 0xFF
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_MASK 0xFF
+#define TLBIVA_VA_MASK 0x000FFFFF
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_MASK 0x000FFFFF
+
+
+/* TLBLCKR */
+#define LKE_MASK 0x01
+#define TLBLCKR_TLBIALLCFG_MASK 0x01
+#define TLBIASIDCFG_MASK 0x01
+#define TLBIVAACFG_MASK 0x01
+#define FLOOR_MASK 0xFF
+#define VICTIM_MASK 0xFF
+
+
+/* TTBCR */
+#define N_MASK 0x07
+#define PD0_MASK 0x01
+#define PD1_MASK 0x01
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_MASK 0x01
+#define TTBR0_SH_MASK 0x01
+#define TTBR0_ORGN_MASK 0x03
+#define TTBR0_NOS_MASK 0x01
+#define TTBR0_IRGNL_MASK 0x01
+#define TTBR0_PA_MASK 0x0003FFFF
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_MASK 0x01
+#define TTBR1_SH_MASK 0x01
+#define TTBR1_ORGN_MASK 0x03
+#define TTBR1_NOS_MASK 0x01
+#define TTBR1_IRGNL_MASK 0x01
+#define TTBR1_PA_MASK 0x0003FFFF
+
+
+/* V2PSR */
+#define HIT_MASK 0x01
+#define INDEX_MASK 0xFF
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_MASK 0xFF
+#define V2Pxx_VA_MASK 0x000FFFFF
+
+
+/* Context Register Shifts */
+/* ACTLR */
+#define CFERE_SHIFT 0
+#define CFEIE_SHIFT 1
+#define PTSHCFG_SHIFT 2
+#define RCOSH_SHIFT 4
+#define RCISH_SHIFT 5
+#define RCNSH_SHIFT 6
+#define PRIVCFG_SHIFT 8
+#define DNA_SHIFT 10
+#define DNLV2PA_SHIFT 11
+#define TLBMCFG_SHIFT 12
+#define CFCFG_SHIFT 14
+#define TIPCF_SHIFT 15
+#define V2PCFG_SHIFT 16
+#define HUME_SHIFT 18
+#define PTMTCFG_SHIFT 20
+#define PTMEMTYPE_SHIFT 21
+
+
+/* BFBCR */
+#define BFBDFE_SHIFT 0
+#define BFBSFE_SHIFT 1
+#define SFVS_SHIFT 2
+#define FLVIC_SHIFT 4
+#define SLVIC_SHIFT 8
+
+
+/* CONTEXTIDR */
+#define CONTEXTIDR_ASID_SHIFT 0
+#define PROCID_SHIFT 8
+
+
+/* FSR */
+#define TF_SHIFT 1
+#define AFF_SHIFT 2
+#define APF_SHIFT 3
+#define TLBMF_SHIFT 4
+#define HTWDEEF_SHIFT 5
+#define HTWSEEF_SHIFT 6
+#define MHF_SHIFT 7
+#define SL_SHIFT 16
+#define SS_SHIFT 30
+#define MULTI_SHIFT 31
+
+
+/* FSYNR0 */
+#define AMID_SHIFT 0
+#define APID_SHIFT 8
+#define ABID_SHIFT 13
+#define ATID_SHIFT 24
+
+
+/* FSYNR1 */
+#define AMEMTYPE_SHIFT 0
+#define ASHARED_SHIFT 3
+#define AINNERSHARED_SHIFT 4
+#define APRIV_SHIFT 5
+#define APROTNS_SHIFT 6
+#define AINST_SHIFT 7
+#define AWRITE_SHIFT 8
+#define ABURST_SHIFT 10
+#define ALEN_SHIFT 12
+#define FSYNR1_ASIZE_SHIFT 16
+#define ALOCK_SHIFT 20
+#define AFULL_SHIFT 24
+
+
+/* NMRR */
+#define ICPC0_SHIFT 0
+#define ICPC1_SHIFT 2
+#define ICPC2_SHIFT 4
+#define ICPC3_SHIFT 6
+#define ICPC4_SHIFT 8
+#define ICPC5_SHIFT 10
+#define ICPC6_SHIFT 12
+#define ICPC7_SHIFT 14
+#define OCPC0_SHIFT 16
+#define OCPC1_SHIFT 18
+#define OCPC2_SHIFT 20
+#define OCPC3_SHIFT 22
+#define OCPC4_SHIFT 24
+#define OCPC5_SHIFT 26
+#define OCPC6_SHIFT 28
+#define OCPC7_SHIFT 30
+
+
+/* PAR */
+#define FAULT_SHIFT 0
+/* If a fault is present, these are the
+same as the fault fields in the FAR */
+#define FAULT_TF_SHIFT 1
+#define FAULT_AFF_SHIFT 2
+#define FAULT_APF_SHIFT 3
+#define FAULT_TLBMF_SHIFT 4
+#define FAULT_HTWDEEF_SHIFT 5
+#define FAULT_HTWSEEF_SHIFT 6
+#define FAULT_MHF_SHIFT 7
+#define FAULT_SL_SHIFT 16
+#define FAULT_SS_SHIFT 30
+
+/* If NO fault is present, the following
+ * fields are in effect
+ * (FAULT remains as before) */
+#define PAR_NOFAULT_SS_SHIFT 1
+#define PAR_NOFAULT_MT_SHIFT 4
+#define PAR_NOFAULT_SH_SHIFT 7
+#define PAR_NOFAULT_NS_SHIFT 9
+#define PAR_NOFAULT_NOS_SHIFT 10
+#define PAR_NPFAULT_PA_SHIFT 12
+
+
+/* PRRR */
+#define MTC0_SHIFT 0
+#define MTC1_SHIFT 2
+#define MTC2_SHIFT 4
+#define MTC3_SHIFT 6
+#define MTC4_SHIFT 8
+#define MTC5_SHIFT 10
+#define MTC6_SHIFT 12
+#define MTC7_SHIFT 14
+#define SHDSH0_SHIFT 16
+#define SHDSH1_SHIFT 17
+#define SHNMSH0_SHIFT 18
+#define SHNMSH1_SHIFT 19
+#define NOS0_SHIFT 24
+#define NOS1_SHIFT 25
+#define NOS2_SHIFT 26
+#define NOS3_SHIFT 27
+#define NOS4_SHIFT 28
+#define NOS5_SHIFT 29
+#define NOS6_SHIFT 30
+#define NOS7_SHIFT 31
+
+
+/* RESUME */
+#define TNR_SHIFT 0
+
+
+/* SCTLR */
+#define M_SHIFT 0
+#define TRE_SHIFT 1
+#define AFE_SHIFT 2
+#define HAF_SHIFT 3
+#define BE_SHIFT 4
+#define AFFD_SHIFT 5
+
+
+/* TLBIASID */
+#define TLBIASID_ASID_SHIFT 0
+
+
+/* TLBIVA */
+#define TLBIVA_ASID_SHIFT 0
+#define TLBIVA_VA_SHIFT 12
+
+
+/* TLBIVAA */
+#define TLBIVAA_VA_SHIFT 12
+
+
+/* TLBLCKR */
+#define LKE_SHIFT 0
+#define TLBLCKR_TLBIALLCFG_SHIFT 1
+#define TLBIASIDCFG_SHIFT 2
+#define TLBIVAACFG_SHIFT 3
+#define FLOOR_SHIFT 8
+#define VICTIM_SHIFT 8
+
+
+/* TTBCR */
+#define N_SHIFT 3
+#define PD0_SHIFT 4
+#define PD1_SHIFT 5
+
+
+/* TTBR0 */
+#define TTBR0_IRGNH_SHIFT 0
+#define TTBR0_SH_SHIFT 1
+#define TTBR0_ORGN_SHIFT 3
+#define TTBR0_NOS_SHIFT 5
+#define TTBR0_IRGNL_SHIFT 6
+#define TTBR0_PA_SHIFT 14
+
+
+/* TTBR1 */
+#define TTBR1_IRGNH_SHIFT 0
+#define TTBR1_SH_SHIFT 1
+#define TTBR1_ORGN_SHIFT 3
+#define TTBR1_NOS_SHIFT 5
+#define TTBR1_IRGNL_SHIFT 6
+#define TTBR1_PA_SHIFT 14
+
+
+/* V2PSR */
+#define HIT_SHIFT 0
+#define INDEX_SHIFT 8
+
+
+/* V2Pxx */
+#define V2Pxx_INDEX_SHIFT 0
+#define V2Pxx_VA_SHIFT 12
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h
new file mode 100644
index 00000000..f1fe7061
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_7X00_H
+#define __ASM_ARCH_MSM_IRQS_7X00_H
+
+/* MSM ARM11 Interrupt Numbers */
+/* See 80-VE113-1 A, pp219-221 */
+
+#define INT_A9_M2A_0 0
+#define INT_A9_M2A_1 1
+#define INT_A9_M2A_2 2
+#define INT_A9_M2A_3 3
+#define INT_A9_M2A_4 4
+#define INT_A9_M2A_5 5
+#define INT_A9_M2A_6 6
+#define INT_GP_TIMER_EXP 7
+#define INT_DEBUG_TIMER_EXP 8
+#define INT_UART1 9
+#define INT_UART2 10
+#define INT_UART3 11
+#define INT_UART1_RX 12
+#define INT_UART2_RX 13
+#define INT_UART3_RX 14
+#define INT_USB_OTG 15
+#define INT_MDDI_PRI 16
+#define INT_MDDI_EXT 17
+#define INT_MDDI_CLIENT 18
+#define INT_MDP 19
+#define INT_GRAPHICS 20
+#define INT_ADM_AARM 21
+#define INT_ADSP_A11 22
+#define INT_ADSP_A9_A11 23
+#define INT_SDC1_0 24
+#define INT_SDC1_1 25
+#define INT_SDC2_0 26
+#define INT_SDC2_1 27
+#define INT_KEYSENSE 28
+#define INT_TCHSCRN_SSBI 29
+#define INT_TCHSCRN1 30
+#define INT_TCHSCRN2 31
+
+#define INT_GPIO_GROUP1 (32 + 0)
+#define INT_GPIO_GROUP2 (32 + 1)
+#define INT_PWB_I2C (32 + 2)
+#define INT_SOFTRESET (32 + 3)
+#define INT_NAND_WR_ER_DONE (32 + 4)
+#define INT_NAND_OP_DONE (32 + 5)
+#define INT_PBUS_ARM11 (32 + 6)
+#define INT_AXI_MPU_SMI (32 + 7)
+#define INT_AXI_MPU_EBI1 (32 + 8)
+#define INT_AD_HSSD (32 + 9)
+#define INT_ARM11_PMU (32 + 10)
+#define INT_ARM11_DMA (32 + 11)
+#define INT_TSIF_IRQ (32 + 12)
+#define INT_UART1DM_IRQ (32 + 13)
+#define INT_UART1DM_RX (32 + 14)
+#define INT_USB_HS (32 + 15)
+#define INT_SDC3_0 (32 + 16)
+#define INT_SDC3_1 (32 + 17)
+#define INT_SDC4_0 (32 + 18)
+#define INT_SDC4_1 (32 + 19)
+#define INT_UART2DM_RX (32 + 20)
+#define INT_UART2DM_IRQ (32 + 21)
+
+/* 22-31 are reserved */
+
+#define NR_MSM_IRQS 64
+#define NR_GPIO_IRQS 122
+#define NR_BOARD_IRQS 64
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h
new file mode 100644
index 00000000..1f159026
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h
@@ -0,0 +1,153 @@
+/* Copyright (c) 2009, 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_IRQS_7X30_H
+#define __ASM_ARCH_MSM_IRQS_7X30_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_DEBUG_TIMER_EXP 0
+#define INT_GPT0_TIMER_EXP 1
+#define INT_GPT1_TIMER_EXP 2
+#define INT_WDT0_ACCSCSSBARK 3
+#define INT_WDT1_ACCSCSSBARK 4
+#define INT_AVS_SVIC 5
+#define INT_AVS_SVIC_SW_DONE 6
+#define INT_SC_DBG_RX_FULL 7
+#define INT_SC_DBG_TX_EMPTY 8
+#define INT_ARM11_PM 9
+#define INT_AVS_REQ_DOWN 10
+#define INT_AVS_REQ_UP 11
+#define INT_SC_ACG 12
+/* SCSS_VICFIQSTS0[13:15] are RESERVED */
+#define INT_L2_SVICCPUIRPTREQ 16
+#define INT_L2_SVICDMANSIRPTREQ 17
+#define INT_L2_SVICDMASIRPTREQ 18
+#define INT_L2_SVICSLVIRPTREQ 19
+#define INT_AD5A_MPROC_APPS_0 20
+#define INT_AD5A_MPROC_APPS_1 21
+#define INT_A9_M2A_0 22
+#define INT_A9_M2A_1 23
+#define INT_A9_M2A_2 24
+#define INT_A9_M2A_3 25
+#define INT_A9_M2A_4 26
+#define INT_A9_M2A_5 27
+#define INT_A9_M2A_6 28
+#define INT_A9_M2A_7 29
+#define INT_A9_M2A_8 30
+#define INT_A9_M2A_9 31
+
+#define INT_AXI_EBI1_SC (32 + 0)
+#define INT_IMEM_ERR (32 + 1)
+#define INT_AXI_EBI0_SC (32 + 2)
+#define INT_PBUS_SC_IRQC (32 + 3)
+#define INT_PERPH_BUS_BPM (32 + 4)
+#define INT_CC_TEMP_SENSE (32 + 5)
+#define INT_UXMC_EBI0 (32 + 6)
+#define INT_UXMC_EBI1 (32 + 7)
+#define INT_EBI2_OP_DONE (32 + 8)
+#define INT_EBI2_WR_ER_DONE (32 + 9)
+#define INT_TCSR_SPSS_CE (32 + 10)
+#define INT_EMDH (32 + 11)
+#define INT_PMDH (32 + 12)
+#define INT_MDC (32 + 13)
+#define INT_MIDI_TO_SUPSS (32 + 14)
+#define INT_LPA_2 (32 + 15)
+#define INT_GPIO_GROUP1_SECURE (32 + 16)
+#define INT_GPIO_GROUP2_SECURE (32 + 17)
+#define INT_GPIO_GROUP1 (32 + 18)
+#define INT_GPIO_GROUP2 (32 + 19)
+#define INT_MPRPH_SOFTRESET (32 + 20)
+#define INT_PWB_I2C (32 + 21)
+#define INT_PWB_I2C_2 (32 + 22)
+#define INT_TSSC_SAMPLE (32 + 23)
+#define INT_TSSC_PENUP (32 + 24)
+#define INT_TCHSCRN_SSBI (32 + 25)
+#define INT_FM_RDS (32 + 26)
+#define INT_KEYSENSE (32 + 27)
+#define INT_USB_OTG_HS (32 + 28)
+#define INT_USB_OTG_HS2 (32 + 29)
+#define INT_USB_OTG_HS3 (32 + 30)
+#define INT_CSI (32 + 31)
+
+#define INT_SPI_OUTPUT (64 + 0)
+#define INT_SPI_INPUT (64 + 1)
+#define INT_SPI_ERROR (64 + 2)
+#define INT_UART1 (64 + 3)
+#define INT_UART1_RX (64 + 4)
+#define INT_UART2 (64 + 5)
+#define INT_UART2_RX (64 + 6)
+#define INT_UART3 (64 + 7)
+#define INT_UART3_RX (64 + 8)
+#define INT_UART1DM_IRQ (64 + 9)
+#define INT_UART1DM_RX (64 + 10)
+#define INT_UART2DM_IRQ (64 + 11)
+#define INT_UART2DM_RX (64 + 12)
+#define INT_TSIF (64 + 13)
+#define INT_ADM_SC1 (64 + 14)
+#define INT_ADM_SC2 (64 + 15)
+#define INT_MDP (64 + 16)
+#define INT_VPE (64 + 17)
+#define INT_GRP_2D (64 + 18)
+#define INT_GRP_3D (64 + 19)
+#define INT_ROTATOR (64 + 20)
+#define INT_MFC720 (64 + 21)
+#define INT_JPEG (64 + 22)
+#define INT_VFE (64 + 23)
+#define INT_TV_ENC (64 + 24)
+#define INT_PMIC_SSBI (64 + 25)
+#define INT_MPM_1 (64 + 26)
+#define INT_TCSR_SPSS_SAMPLE (64 + 27)
+#define INT_TCSR_SPSS_PENUP (64 + 28)
+#define INT_MPM_2 (64 + 29)
+#define INT_SDC1_0 (64 + 30)
+#define INT_SDC1_1 (64 + 31)
+
+#define INT_SDC3_0 (96 + 0)
+#define INT_SDC3_1 (96 + 1)
+#define INT_SDC2_0 (96 + 2)
+#define INT_SDC2_1 (96 + 3)
+#define INT_SDC4_0 (96 + 4)
+#define INT_SDC4_1 (96 + 5)
+#define INT_PWB_QUP_IN (96 + 6)
+#define INT_PWB_QUP_OUT (96 + 7)
+#define INT_PWB_QUP_ERR (96 + 8)
+#define INT_SCSS_WDT0_BITE (96 + 9)
+/* SCSS_VICFIQSTS3[10:31] are RESERVED */
+
+/* Retrofit universal macro names */
+#define INT_ADM_AARM INT_ADM_SC2
+#define INT_USB_HS INT_USB_OTG_HS
+#define INT_USB_OTG INT_USB_OTG_HS
+#define INT_TCHSCRN1 INT_TSSC_SAMPLE
+#define INT_TCHSCRN2 INT_TSSC_PENUP
+#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP
+#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0
+#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1
+#define INT_MDDI_EXT INT_EMDH
+#define INT_MDDI_PRI INT_PMDH
+#define INT_MDDI_CLIENT INT_MDC
+#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE
+#define INT_NAND_OP_DONE INT_EBI2_OP_DONE
+
+#define NR_MSM_IRQS 128
+#define NR_GPIO_IRQS 182
+#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
+#define NR_PMIC8058_GPIO_IRQS 40
+#define NR_PMIC8058_MPP_IRQS 12
+#define NR_PMIC8058_MISC_IRQS 8
+#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\
+ NR_PMIC8058_MPP_IRQS +\
+ NR_PMIC8058_MISC_IRQS)
+#define NR_BOARD_IRQS NR_PMIC8058_IRQS
+
+#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */
diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h
new file mode 100644
index 00000000..81ab2a67
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8960.h
@@ -0,0 +1,277 @@
+/* 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_IRQS_8960_H
+#define __ASM_ARCH_MSM_IRQS_8960_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15: STI/SGI (software triggered/generated interrupts)
+ 16-31: PPI (private peripheral interrupts)
+ 32+: SPI (shared peripheral interrupts) */
+
+#define GIC_PPI_START 16
+#define GIC_SPI_START 32
+
+#define INT_VGIC (GIC_PPI_START + 0)
+#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 1)
+#define INT_GP_TIMER_EXP (GIC_PPI_START + 2)
+#define INT_GP_TIMER2_EXP (GIC_PPI_START + 3)
+#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 4)
+#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 5)
+#define AVS_SVICINT (GIC_PPI_START + 6)
+#define AVS_SVICINTSWDONE (GIC_PPI_START + 7)
+#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 8)
+#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 9)
+#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 10)
+#define SC_AVSCPUXDOWN (GIC_PPI_START + 11)
+#define SC_AVSCPUXUP (GIC_PPI_START + 12)
+#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 13)
+#define SC_SICCPUXEXTFAULTIRPTREQ (GIC_PPI_START + 14)
+/* PPI 15 is unused */
+
+#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0)
+#define SC_SICL2IRPTREQ (GIC_SPI_START + 1)
+#define SC_SICL2PERFMONIRPTREQ (GIC_SPI_START + 2)
+#define SC_SICAGCIRPTREQ (GIC_SPI_START + 3)
+#define TLMM_APCC_DIR_CONN_IRQ_0 (GIC_SPI_START + 4)
+#define TLMM_APCC_DIR_CONN_IRQ_1 (GIC_SPI_START + 5)
+#define TLMM_APCC_DIR_CONN_IRQ_2 (GIC_SPI_START + 6)
+#define TLMM_APCC_DIR_CONN_IRQ_3 (GIC_SPI_START + 7)
+#define TLMM_APCC_DIR_CONN_IRQ_4 (GIC_SPI_START + 8)
+#define TLMM_APCC_DIR_CONN_IRQ_5 (GIC_SPI_START + 9)
+#define TLMM_APCC_DIR_CONN_IRQ_6 (GIC_SPI_START + 10)
+#define TLMM_APCC_DIR_CONN_IRQ_7 (GIC_SPI_START + 11)
+#define TLMM_APCC_DIR_CONN_IRQ_8 (GIC_SPI_START + 12)
+#define TLMM_APCC_DIR_CONN_IRQ_9 (GIC_SPI_START + 13)
+#define PM8921_SEC_IRQ_103 (GIC_SPI_START + 14)
+#define PM8018_SEC_IRQ_106 (GIC_SPI_START + 15)
+#define TLMM_APCC_SUMMARY_IRQ (GIC_SPI_START + 16)
+#define SPDM_RT_1_IRQ (GIC_SPI_START + 17)
+#define SPDM_DIAG_IRQ (GIC_SPI_START + 18)
+#define RPM_APCC_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19)
+#define RPM_APCC_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20)
+#define RPM_APCC_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21)
+#define RPM_APCC_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22)
+#define RPM_APCC_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23)
+#define RPM_APCC_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24)
+#define RPM_APCC_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25)
+#define RPM_APCC_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26)
+#define SSBI2_2_SC_CPU0_SECURE_IRQ (GIC_SPI_START + 27)
+#define SSBI2_2_SC_CPU0_NON_SECURE_IRQ (GIC_SPI_START + 28)
+#define SSBI2_1_SC_CPU0_SECURE_IRQ (GIC_SPI_START + 29)
+#define SSBI2_1_SC_CPU0_NON_SECURE_IRQ (GIC_SPI_START + 30)
+#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31)
+#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32)
+#define SLIMBUS0_CORE_EE1_IRQ (GIC_SPI_START + 33)
+#define SLIMBUS0_BAM_EE1_IRQ (GIC_SPI_START + 34)
+#define Q6FW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 35)
+#define Q6SW_WDOG_EXPIRED_IRQ (GIC_SPI_START + 36)
+#define MSS_TO_APPS_IRQ_0 (GIC_SPI_START + 37)
+#define MSS_TO_APPS_IRQ_1 (GIC_SPI_START + 38)
+#define MSS_TO_APPS_IRQ_2 (GIC_SPI_START + 39)
+#define MSS_TO_APPS_IRQ_3 (GIC_SPI_START + 40)
+#define MSS_TO_APPS_IRQ_4 (GIC_SPI_START + 41)
+#define MSS_TO_APPS_IRQ_5 (GIC_SPI_START + 42)
+#define MSS_TO_APPS_IRQ_6 (GIC_SPI_START + 43)
+#define MSS_TO_APPS_IRQ_7 (GIC_SPI_START + 44)
+#define MSS_TO_APPS_IRQ_8 (GIC_SPI_START + 45)
+#define MSS_TO_APPS_IRQ_9 (GIC_SPI_START + 46)
+#define VPE_IRQ (GIC_SPI_START + 47)
+#define VFE_IRQ (GIC_SPI_START + 48)
+#define VCODEC_IRQ (GIC_SPI_START + 49)
+#define TV_ENC_IRQ (GIC_SPI_START + 50)
+#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51)
+#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52)
+#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53)
+#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54)
+#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55)
+#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56)
+#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57)
+#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58)
+#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59)
+#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60)
+#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61)
+#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62)
+#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63)
+#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64)
+#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65)
+#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66)
+#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67)
+#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68)
+#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69)
+#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70)
+#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71)
+#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72)
+#define ROT_IRQ (GIC_SPI_START + 73)
+#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74)
+#define MDP_IRQ (GIC_SPI_START + 75)
+#define JPEGD_IRQ (GIC_SPI_START + 76)
+#define JPEG_IRQ (GIC_SPI_START + 77)
+#define MMSS_IMEM_IRQ (GIC_SPI_START + 78)
+#define HDMI_IRQ (GIC_SPI_START + 79)
+#define GFX3D_IRQ (GIC_SPI_START + 80)
+#define GFX2D0_IRQ (GIC_SPI_START + 81)
+#define DSI1_IRQ (GIC_SPI_START + 82)
+#define CSI_1_IRQ (GIC_SPI_START + 83)
+#define CSI_0_IRQ (GIC_SPI_START + 84)
+#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85)
+#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86)
+#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87)
+#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88)
+#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89)
+#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90)
+#define TOP_IMEM_IRQ (GIC_SPI_START + 91)
+#define FABRIC_SYS_IRQ (GIC_SPI_START + 92)
+#define FABRIC_APPS_IRQ (GIC_SPI_START + 93)
+#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94)
+#define SDC4_BAM_IRQ (GIC_SPI_START + 95)
+#define SDC3_BAM_IRQ (GIC_SPI_START + 96)
+#define SDC2_BAM_IRQ (GIC_SPI_START + 97)
+#define SDC1_BAM_IRQ (GIC_SPI_START + 98)
+#define FABRIC_SPS_IRQ (GIC_SPI_START + 99)
+#define USB1_HS_IRQ (GIC_SPI_START + 100)
+#define SDC4_IRQ_0 (GIC_SPI_START + 101)
+#define SDC3_IRQ_0 (GIC_SPI_START + 102)
+#define SDC2_IRQ_0 (GIC_SPI_START + 103)
+#define SDC1_IRQ_0 (GIC_SPI_START + 104)
+#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
+#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106)
+#define SPS_MTI_0 (GIC_SPI_START + 107)
+#define SPS_MTI_1 (GIC_SPI_START + 108)
+#define SPS_MTI_2 (GIC_SPI_START + 109)
+#define SPS_MTI_3 (GIC_SPI_START + 110)
+#define SPS_MTI_4 (GIC_SPI_START + 111)
+#define SPS_MTI_5 (GIC_SPI_START + 112)
+#define SPS_MTI_6 (GIC_SPI_START + 113)
+#define SPS_MTI_7 (GIC_SPI_START + 114)
+#define SPS_MTI_8 (GIC_SPI_START + 115)
+#define SPS_MTI_9 (GIC_SPI_START + 116)
+#define SPS_MTI_10 (GIC_SPI_START + 117)
+#define SPS_MTI_11 (GIC_SPI_START + 118)
+#define SPS_MTI_12 (GIC_SPI_START + 119)
+#define SPS_MTI_13 (GIC_SPI_START + 120)
+#define SPS_MTI_14 (GIC_SPI_START + 121)
+#define SPS_MTI_15 (GIC_SPI_START + 122)
+#define SPS_MTI_16 (GIC_SPI_START + 123)
+#define SPS_MTI_17 (GIC_SPI_START + 124)
+#define SPS_MTI_18 (GIC_SPI_START + 125)
+#define SPS_MTI_19 (GIC_SPI_START + 126)
+#define SPS_MTI_20 (GIC_SPI_START + 127)
+#define SPS_MTI_21 (GIC_SPI_START + 128)
+#define SPS_MTI_22 (GIC_SPI_START + 129)
+#define SPS_MTI_23 (GIC_SPI_START + 130)
+#define SPS_MTI_24 (GIC_SPI_START + 131)
+#define SPS_MTI_25 (GIC_SPI_START + 132)
+#define SPS_MTI_26 (GIC_SPI_START + 133)
+#define SPS_MTI_27 (GIC_SPI_START + 134)
+#define SPS_MTI_28 (GIC_SPI_START + 135)
+#define SPS_MTI_29 (GIC_SPI_START + 136)
+#define SPS_MTI_30 (GIC_SPI_START + 137)
+#define SPS_MTI_31 (GIC_SPI_START + 138)
+#define CSIPHY_4LN_IRQ (GIC_SPI_START + 139)
+#define CSIPHY_2LN_IRQ (GIC_SPI_START + 140)
+#define USB2_IRQ (GIC_SPI_START + 141)
+#define USB1_IRQ (GIC_SPI_START + 142)
+#define TSSC_SSBI_IRQ (GIC_SPI_START + 143)
+#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144)
+#define TSSC_PENUP_IRQ (GIC_SPI_START + 145)
+#define GSBI1_UARTDM_IRQ (GIC_SPI_START + 146)
+#define GSBI1_QUP_IRQ (GIC_SPI_START + 147)
+#define GSBI2_UARTDM_IRQ (GIC_SPI_START + 148)
+#define GSBI2_QUP_IRQ (GIC_SPI_START + 149)
+#define GSBI3_UARTDM_IRQ (GIC_SPI_START + 150)
+#define GSBI3_QUP_IRQ (GIC_SPI_START + 151)
+#define GSBI4_UARTDM_IRQ (GIC_SPI_START + 152)
+#define GSBI4_QUP_IRQ (GIC_SPI_START + 153)
+#define GSBI5_UARTDM_IRQ (GIC_SPI_START + 154)
+#define GSBI5_QUP_IRQ (GIC_SPI_START + 155)
+#define GSBI6_UARTDM_IRQ (GIC_SPI_START + 156)
+#define GSBI6_QUP_IRQ (GIC_SPI_START + 157)
+#define GSBI7_UARTDM_IRQ (GIC_SPI_START + 158)
+#define GSBI7_QUP_IRQ (GIC_SPI_START + 159)
+#define GSBI8_UARTDM_IRQ (GIC_SPI_START + 160)
+#define GSBI8_QUP_IRQ (GIC_SPI_START + 161)
+#define TSIF_TSPP_IRQ (GIC_SPI_START + 162)
+#define TSIF_BAM_IRQ (GIC_SPI_START + 163)
+#define TSIF2_IRQ (GIC_SPI_START + 164)
+#define TSIF1_IRQ (GIC_SPI_START + 165)
+#define DSI2_IRQ (GIC_SPI_START + 166)
+#define ISPIF_IRQ (GIC_SPI_START + 167)
+#define MSMC_SC_SEC_TMR_IRQ (GIC_SPI_START + 168)
+#define MSMC_SC_SEC_WDOG_BARK_IRQ (GIC_SPI_START + 169)
+#define INT_ADM0_SCSS_0_IRQ (GIC_SPI_START + 170)
+#define INT_ADM0_SCSS_1_IRQ (GIC_SPI_START + 171)
+#define INT_ADM0_SCSS_2_IRQ (GIC_SPI_START + 172)
+#define INT_ADM0_SCSS_3_IRQ (GIC_SPI_START + 173)
+#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174)
+#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175)
+#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176)
+#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177)
+#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178)
+#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179)
+#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180)
+#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181)
+#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182)
+#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183)
+#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184)
+#define HSDDRX_EBI1CH0_IRQ (GIC_SPI_START + 185)
+#define HSDDRX_EBI1CH1_IRQ (GIC_SPI_START + 186)
+#define SDC5_BAM_IRQ (GIC_SPI_START + 187)
+#define SDC5_IRQ_0 (GIC_SPI_START + 188)
+#define GSBI9_UARTDM_IRQ (GIC_SPI_START + 189)
+#define GSBI9_QUP_IRQ (GIC_SPI_START + 190)
+#define GSBI10_UARTDM_IRQ (GIC_SPI_START + 191)
+#define GSBI10_QUP_IRQ (GIC_SPI_START + 192)
+#define GSBI11_UARTDM_IRQ (GIC_SPI_START + 193)
+#define GSBI11_QUP_IRQ (GIC_SPI_START + 194)
+#define GSBI12_UARTDM_IRQ (GIC_SPI_START + 195)
+#define GSBI12_QUP_IRQ (GIC_SPI_START + 196)
+#define RIVA_APSS_LTECOEX_IRQ (GIC_SPI_START + 197)
+#define RIVA_APSS_SPARE_IRQ (GIC_SPI_START + 198)
+#define RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ (GIC_SPI_START + 199)
+#define RIVA_ASS_RESET_DONE_IRQ (GIC_SPI_START + 200)
+#define RIVA_APSS_ASIC_IRQ (GIC_SPI_START + 201)
+#define RIVA_APPS_WLAN_RX_DATA_AVAIL_IRQ (GIC_SPI_START + 202)
+#define RIVA_APPS_WLAN_DATA_XFER_DONE_IRQ (GIC_SPI_START + 203)
+#define RIVA_APPS_WLAM_SMSM_IRQ (GIC_SPI_START + 204)
+#define RIVA_APPS_LOG_CTRL_IRQ (GIC_SPI_START + 205)
+#define RIVA_APPS_FM_CTRL_IRQ (GIC_SPI_START + 206)
+#define RIVA_APPS_HCI_IRQ (GIC_SPI_START + 207)
+#define RIVA_APPS_WLAN_CTRL_IRQ (GIC_SPI_START + 208)
+#define A2_BAM_IRQ (GIC_SPI_START + 209)
+#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210)
+#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211)
+#define GFX2D1_IRQ (GIC_SPI_START + 212)
+#define PPSS_WDOG_TIMER_IRQ (GIC_SPI_START + 213)
+#define SPS_SLIMBUS_CORE_EE0_IRQ (GIC_SPI_START + 214)
+#define SPS_SLIMBUS_BAM_EE0_IRQ (GIC_SPI_START + 215)
+#define QDSS_ETB_IRQ (GIC_SPI_START + 216)
+#define QDSS_CTI2KPSS_CPU1_IRQ (GIC_SPI_START + 217)
+#define QDSS_CTI2KPSS_CPU0_IRQ (GIC_SPI_START + 218)
+#define TLMM_APCC_DIR_CONN_IRQ_16 (GIC_SPI_START + 219)
+#define TLMM_APCC_DIR_CONN_IRQ_17 (GIC_SPI_START + 220)
+#define TLMM_APCC_DIR_CONN_IRQ_18 (GIC_SPI_START + 221)
+#define TLMM_APCC_DIR_CONN_IRQ_19 (GIC_SPI_START + 222)
+#define TLMM_APCC_DIR_CONN_IRQ_20 (GIC_SPI_START + 223)
+#define TLMM_APCC_DIR_CONN_IRQ_21 (GIC_SPI_START + 224)
+#define PM8921_SEC_IRQ_104 (GIC_SPI_START + 225)
+#define PM8018_SEC_IRQ_107 (GIC_SPI_START + 226)
+
+/* For now, use the maximum number of interrupts until a pending GIC issue
+ * is sorted out */
+#define NR_MSM_IRQS 1020
+#define NR_BOARD_IRQS 0
+#define NR_GPIO_IRQS 0
+
+#endif
+
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h
new file mode 100644
index 00000000..26adbe0e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h
@@ -0,0 +1,88 @@
+/* Copyright (c) 2008-2009, 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_IRQS_8XXX_H
+#define __ASM_ARCH_MSM_IRQS_8XXX_H
+
+/* MSM ACPU Interrupt Numbers */
+
+#define INT_A9_M2A_0 0
+#define INT_A9_M2A_1 1
+#define INT_A9_M2A_2 2
+#define INT_A9_M2A_3 3
+#define INT_A9_M2A_4 4
+#define INT_A9_M2A_5 5
+#define INT_A9_M2A_6 6
+#define INT_GP_TIMER_EXP 7
+#define INT_DEBUG_TIMER_EXP 8
+#define INT_SIRC_0 9
+#define INT_SDC3_0 10
+#define INT_SDC3_1 11
+#define INT_SDC4_0 12
+#define INT_SDC4_1 13
+#define INT_AD6_EXT_VFR 14
+#define INT_USB_OTG 15
+#define INT_MDDI_PRI 16
+#define INT_MDDI_EXT 17
+#define INT_MDDI_CLIENT 18
+#define INT_MDP 19
+#define INT_GRAPHICS 20
+#define INT_ADM_AARM 21
+#define INT_ADSP_A11 22
+#define INT_ADSP_A9_A11 23
+#define INT_SDC1_0 24
+#define INT_SDC1_1 25
+#define INT_SDC2_0 26
+#define INT_SDC2_1 27
+#define INT_KEYSENSE 28
+#define INT_TCHSCRN_SSBI 29
+#define INT_TCHSCRN1 30
+#define INT_TCHSCRN2 31
+
+#define INT_TCSR_MPRPH_SC1 (32 + 0)
+#define INT_USB_FS2 (32 + 1)
+#define INT_PWB_I2C (32 + 2)
+#define INT_SOFTRESET (32 + 3)
+#define INT_NAND_WR_ER_DONE (32 + 4)
+#define INT_NAND_OP_DONE (32 + 5)
+#define INT_TCSR_MPRPH_SC2 (32 + 6)
+#define INT_OP_PEN (32 + 7)
+#define INT_AD_HSSD (32 + 8)
+#define INT_ARM11_PM (32 + 9)
+#define INT_SDMA_NON_SECURE (32 + 10)
+#define INT_TSIF_IRQ (32 + 11)
+#define INT_UART1DM_IRQ (32 + 12)
+#define INT_UART1DM_RX (32 + 13)
+#define INT_SDMA_SECURE (32 + 14)
+#define INT_SI2S_SLAVE (32 + 15)
+#define INT_SC_I2CPU (32 + 16)
+#define INT_SC_DBG_RDTRFULL (32 + 17)
+#define INT_SC_DBG_WDTRFULL (32 + 18)
+#define INT_SCPLL_CTL_DONE (32 + 19)
+#define INT_UART2DM_IRQ (32 + 20)
+#define INT_UART2DM_RX (32 + 21)
+#define INT_VDC_MEC (32 + 22)
+#define INT_VDC_DB (32 + 23)
+#define INT_VDC_AXI (32 + 24)
+#define INT_VFE (32 + 25)
+#define INT_USB_HS (32 + 26)
+#define INT_AUDIO_OUT0 (32 + 27)
+#define INT_AUDIO_OUT1 (32 + 28)
+#define INT_CRYPTO (32 + 29)
+#define INT_AD6M_IDLE (32 + 30)
+#define INT_SIRC_1 (32 + 31)
+
+#define NR_GPIO_IRQS 165
+#define NR_MSM_IRQS 64
+#define NR_BOARD_IRQS 64
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h
new file mode 100644
index 00000000..f65841c7
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h
@@ -0,0 +1,258 @@
+/* Copyright (c) 2010 Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_8X60_H
+#define __ASM_ARCH_MSM_IRQS_8X60_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15: STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+: SPI (shared peripheral interrupts)
+ */
+
+#define GIC_PPI_START 16
+#define GIC_SPI_START 32
+
+#define INT_DEBUG_TIMER_EXP (GIC_PPI_START + 0)
+#define INT_GP_TIMER_EXP (GIC_PPI_START + 1)
+#define INT_GP_TIMER2_EXP (GIC_PPI_START + 2)
+#define WDT0_ACCSCSSNBARK_INT (GIC_PPI_START + 3)
+#define WDT1_ACCSCSSNBARK_INT (GIC_PPI_START + 4)
+#define AVS_SVICINT (GIC_PPI_START + 5)
+#define AVS_SVICINTSWDONE (GIC_PPI_START + 6)
+#define CPU_DBGCPUXCOMMRXFULL (GIC_PPI_START + 7)
+#define CPU_DBGCPUXCOMMTXEMPTY (GIC_PPI_START + 8)
+#define CPU_SICCPUXPERFMONIRPTREQ (GIC_PPI_START + 9)
+#define SC_AVSCPUXDOWN (GIC_PPI_START + 10)
+#define SC_AVSCPUXUP (GIC_PPI_START + 11)
+#define SC_SICCPUXACGIRPTREQ (GIC_PPI_START + 12)
+/* PPI 13 to 15 are unused */
+
+
+#define SC_SICMPUIRPTREQ (GIC_SPI_START + 0)
+#define SC_SICL2IRPTREQ (GIC_SPI_START + 1)
+#define SC_SICL2ACGIRPTREQ (GIC_SPI_START + 2)
+#define NC (GIC_SPI_START + 3)
+#define TLMM_SCSS_DIR_CONN_IRQ_0 (GIC_SPI_START + 4)
+#define TLMM_SCSS_DIR_CONN_IRQ_1 (GIC_SPI_START + 5)
+#define TLMM_SCSS_DIR_CONN_IRQ_2 (GIC_SPI_START + 6)
+#define TLMM_SCSS_DIR_CONN_IRQ_3 (GIC_SPI_START + 7)
+#define TLMM_SCSS_DIR_CONN_IRQ_4 (GIC_SPI_START + 8)
+#define TLMM_SCSS_DIR_CONN_IRQ_5 (GIC_SPI_START + 9)
+#define TLMM_SCSS_DIR_CONN_IRQ_6 (GIC_SPI_START + 10)
+#define TLMM_SCSS_DIR_CONN_IRQ_7 (GIC_SPI_START + 11)
+#define TLMM_SCSS_DIR_CONN_IRQ_8 (GIC_SPI_START + 12)
+#define TLMM_SCSS_DIR_CONN_IRQ_9 (GIC_SPI_START + 13)
+#define PM8058_SEC_IRQ_N (GIC_SPI_START + 14)
+#define PM8901_SEC_IRQ_N (GIC_SPI_START + 15)
+#define TLMM_SCSS_SUMMARY_IRQ (GIC_SPI_START + 16)
+#define SPDM_RT_1_IRQ (GIC_SPI_START + 17)
+#define SPDM_DIAG_IRQ (GIC_SPI_START + 18)
+#define RPM_SCSS_CPU0_GP_HIGH_IRQ (GIC_SPI_START + 19)
+#define RPM_SCSS_CPU0_GP_MEDIUM_IRQ (GIC_SPI_START + 20)
+#define RPM_SCSS_CPU0_GP_LOW_IRQ (GIC_SPI_START + 21)
+#define RPM_SCSS_CPU0_WAKE_UP_IRQ (GIC_SPI_START + 22)
+#define RPM_SCSS_CPU1_GP_HIGH_IRQ (GIC_SPI_START + 23)
+#define RPM_SCSS_CPU1_GP_MEDIUM_IRQ (GIC_SPI_START + 24)
+#define RPM_SCSS_CPU1_GP_LOW_IRQ (GIC_SPI_START + 25)
+#define RPM_SCSS_CPU1_WAKE_UP_IRQ (GIC_SPI_START + 26)
+#define SSBI2_2_SC_CPU0_SECURE_INT (GIC_SPI_START + 27)
+#define SSBI2_2_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 28)
+#define SSBI2_1_SC_CPU0_SECURE_INT (GIC_SPI_START + 29)
+#define SSBI2_1_SC_CPU0_NON_SECURE_INT (GIC_SPI_START + 30)
+#define MSMC_SC_SEC_CE_IRQ (GIC_SPI_START + 31)
+#define MSMC_SC_PRI_CE_IRQ (GIC_SPI_START + 32)
+#define MARM_FIQ (GIC_SPI_START + 33)
+#define MARM_IRQ (GIC_SPI_START + 34)
+#define MARM_L2CC_IRQ (GIC_SPI_START + 35)
+#define MARM_WDOG_EXPIRED (GIC_SPI_START + 36)
+#define MARM_SCSS_GP_IRQ_0 (GIC_SPI_START + 37)
+#define MARM_SCSS_GP_IRQ_1 (GIC_SPI_START + 38)
+#define MARM_SCSS_GP_IRQ_2 (GIC_SPI_START + 39)
+#define MARM_SCSS_GP_IRQ_3 (GIC_SPI_START + 40)
+#define MARM_SCSS_GP_IRQ_4 (GIC_SPI_START + 41)
+#define MARM_SCSS_GP_IRQ_5 (GIC_SPI_START + 42)
+#define MARM_SCSS_GP_IRQ_6 (GIC_SPI_START + 43)
+#define MARM_SCSS_GP_IRQ_7 (GIC_SPI_START + 44)
+#define MARM_SCSS_GP_IRQ_8 (GIC_SPI_START + 45)
+#define MARM_SCSS_GP_IRQ_9 (GIC_SPI_START + 46)
+#define VPE_IRQ (GIC_SPI_START + 47)
+#define VFE_IRQ (GIC_SPI_START + 48)
+#define VCODEC_IRQ (GIC_SPI_START + 49)
+#define TV_ENC_IRQ (GIC_SPI_START + 50)
+#define SMMU_VPE_CB_SC_SECURE_IRQ (GIC_SPI_START + 51)
+#define SMMU_VPE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 52)
+#define SMMU_VFE_CB_SC_SECURE_IRQ (GIC_SPI_START + 53)
+#define SMMU_VFE_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 54)
+#define SMMU_VCODEC_B_CB_SC_SECURE_IRQ (GIC_SPI_START + 55)
+#define SMMU_VCODEC_B_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 56)
+#define SMMU_VCODEC_A_CB_SC_SECURE_IRQ (GIC_SPI_START + 57)
+#define SMMU_VCODEC_A_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 58)
+#define SMMU_ROT_CB_SC_SECURE_IRQ (GIC_SPI_START + 59)
+#define SMMU_ROT_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 60)
+#define SMMU_MDP1_CB_SC_SECURE_IRQ (GIC_SPI_START + 61)
+#define SMMU_MDP1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 62)
+#define SMMU_MDP0_CB_SC_SECURE_IRQ (GIC_SPI_START + 63)
+#define SMMU_MDP0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 64)
+#define SMMU_JPEGD_CB_SC_SECURE_IRQ (GIC_SPI_START + 65)
+#define SMMU_JPEGD_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 66)
+#define SMMU_IJPEG_CB_SC_SECURE_IRQ (GIC_SPI_START + 67)
+#define SMMU_IJPEG_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 68)
+#define SMMU_GFX3D_CB_SC_SECURE_IRQ (GIC_SPI_START + 69)
+#define SMMU_GFX3D_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 70)
+#define SMMU_GFX2D0_CB_SC_SECURE_IRQ (GIC_SPI_START + 71)
+#define SMMU_GFX2D0_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 72)
+#define ROT_IRQ (GIC_SPI_START + 73)
+#define MMSS_FABRIC_IRQ (GIC_SPI_START + 74)
+#define MDP_IRQ (GIC_SPI_START + 75)
+#define JPEGD_IRQ (GIC_SPI_START + 76)
+#define JPEG_IRQ (GIC_SPI_START + 77)
+#define MMSS_IMEM_IRQ (GIC_SPI_START + 78)
+#define HDMI_IRQ (GIC_SPI_START + 79)
+#define GFX3D_IRQ (GIC_SPI_START + 80)
+#define GFX2D0_IRQ (GIC_SPI_START + 81)
+#define DSI_IRQ (GIC_SPI_START + 82)
+#define CSI_1_IRQ (GIC_SPI_START + 83)
+#define CSI_0_IRQ (GIC_SPI_START + 84)
+#define LPASS_SCSS_AUDIO_IF_OUT0_IRQ (GIC_SPI_START + 85)
+#define LPASS_SCSS_MIDI_IRQ (GIC_SPI_START + 86)
+#define LPASS_Q6SS_WDOG_EXPIRED (GIC_SPI_START + 87)
+#define LPASS_SCSS_GP_LOW_IRQ (GIC_SPI_START + 88)
+#define LPASS_SCSS_GP_MEDIUM_IRQ (GIC_SPI_START + 89)
+#define LPASS_SCSS_GP_HIGH_IRQ (GIC_SPI_START + 90)
+#define TOP_IMEM_IRQ (GIC_SPI_START + 91)
+#define FABRIC_SYS_IRQ (GIC_SPI_START + 92)
+#define FABRIC_APPS_IRQ (GIC_SPI_START + 93)
+#define USB1_HS_BAM_IRQ (GIC_SPI_START + 94)
+#define SDC4_BAM_IRQ (GIC_SPI_START + 95)
+#define SDC3_BAM_IRQ (GIC_SPI_START + 96)
+#define SDC2_BAM_IRQ (GIC_SPI_START + 97)
+#define SDC1_BAM_IRQ (GIC_SPI_START + 98)
+#define FABRIC_SPS_IRQ (GIC_SPI_START + 99)
+#define USB1_HS_IRQ (GIC_SPI_START + 100)
+#define SDC4_IRQ_0 (GIC_SPI_START + 101)
+#define SDC3_IRQ_0 (GIC_SPI_START + 102)
+#define SDC2_IRQ_0 (GIC_SPI_START + 103)
+#define SDC1_IRQ_0 (GIC_SPI_START + 104)
+#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
+#define SPS_SEC_VIOL_IRQ (GIC_SPI_START + 106)
+#define SPS_MTI_0 (GIC_SPI_START + 107)
+#define SPS_MTI_1 (GIC_SPI_START + 108)
+#define SPS_MTI_2 (GIC_SPI_START + 109)
+#define SPS_MTI_3 (GIC_SPI_START + 110)
+#define SPS_MTI_4 (GIC_SPI_START + 111)
+#define SPS_MTI_5 (GIC_SPI_START + 112)
+#define SPS_MTI_6 (GIC_SPI_START + 113)
+#define SPS_MTI_7 (GIC_SPI_START + 114)
+#define SPS_MTI_8 (GIC_SPI_START + 115)
+#define SPS_MTI_9 (GIC_SPI_START + 116)
+#define SPS_MTI_10 (GIC_SPI_START + 117)
+#define SPS_MTI_11 (GIC_SPI_START + 118)
+#define SPS_MTI_12 (GIC_SPI_START + 119)
+#define SPS_MTI_13 (GIC_SPI_START + 120)
+#define SPS_MTI_14 (GIC_SPI_START + 121)
+#define SPS_MTI_15 (GIC_SPI_START + 122)
+#define SPS_MTI_16 (GIC_SPI_START + 123)
+#define SPS_MTI_17 (GIC_SPI_START + 124)
+#define SPS_MTI_18 (GIC_SPI_START + 125)
+#define SPS_MTI_19 (GIC_SPI_START + 126)
+#define SPS_MTI_20 (GIC_SPI_START + 127)
+#define SPS_MTI_21 (GIC_SPI_START + 128)
+#define SPS_MTI_22 (GIC_SPI_START + 129)
+#define SPS_MTI_23 (GIC_SPI_START + 130)
+#define SPS_MTI_24 (GIC_SPI_START + 131)
+#define SPS_MTI_25 (GIC_SPI_START + 132)
+#define SPS_MTI_26 (GIC_SPI_START + 133)
+#define SPS_MTI_27 (GIC_SPI_START + 134)
+#define SPS_MTI_28 (GIC_SPI_START + 135)
+#define SPS_MTI_29 (GIC_SPI_START + 136)
+#define SPS_MTI_30 (GIC_SPI_START + 137)
+#define SPS_MTI_31 (GIC_SPI_START + 138)
+#define UXMC_EBI2_WR_ER_DONE_IRQ (GIC_SPI_START + 139)
+#define UXMC_EBI2_OP_DONE_IRQ (GIC_SPI_START + 140)
+#define USB2_IRQ (GIC_SPI_START + 141)
+#define USB1_IRQ (GIC_SPI_START + 142)
+#define TSSC_SSBI_IRQ (GIC_SPI_START + 143)
+#define TSSC_SAMPLE_IRQ (GIC_SPI_START + 144)
+#define TSSC_PENUP_IRQ (GIC_SPI_START + 145)
+#define INT_UART1DM_IRQ (GIC_SPI_START + 146)
+#define GSBI1_QUP_IRQ (GIC_SPI_START + 147)
+#define INT_UART2DM_IRQ (GIC_SPI_START + 148)
+#define GSBI2_QUP_IRQ (GIC_SPI_START + 149)
+#define INT_UART3DM_IRQ (GIC_SPI_START + 150)
+#define GSBI3_QUP_IRQ (GIC_SPI_START + 151)
+#define INT_UART4DM_IRQ (GIC_SPI_START + 152)
+#define GSBI4_QUP_IRQ (GIC_SPI_START + 153)
+#define INT_UART5DM_IRQ (GIC_SPI_START + 154)
+#define GSBI5_QUP_IRQ (GIC_SPI_START + 155)
+#define INT_UART6DM_IRQ (GIC_SPI_START + 156)
+#define GSBI6_QUP_IRQ (GIC_SPI_START + 157)
+#define INT_UART7DM_IRQ (GIC_SPI_START + 158)
+#define GSBI7_QUP_IRQ (GIC_SPI_START + 159)
+#define INT_UART8DM_IRQ (GIC_SPI_START + 160)
+#define GSBI8_QUP_IRQ (GIC_SPI_START + 161)
+#define TSIF_TSPP_IRQ (GIC_SPI_START + 162)
+#define TSIF_BAM_IRQ (GIC_SPI_START + 163)
+#define TSIF2_IRQ (GIC_SPI_START + 164)
+#define TSIF1_IRQ (GIC_SPI_START + 165)
+#define INT_ADM1_MASTER (GIC_SPI_START + 166)
+#define INT_ADM1_AARM (GIC_SPI_START + 167)
+#define INT_ADM1_SD2 (GIC_SPI_START + 168)
+#define INT_ADM1_SD3 (GIC_SPI_START + 169)
+#define INT_ADM0_MASTER (GIC_SPI_START + 170)
+#define INT_ADM0_AARM (GIC_SPI_START + 171)
+#define INT_ADM0_SD2 (GIC_SPI_START + 172)
+#define INT_ADM0_SD3 (GIC_SPI_START + 173)
+#define CC_SCSS_WDT1CPU1BITEEXPIRED (GIC_SPI_START + 174)
+#define CC_SCSS_WDT1CPU0BITEEXPIRED (GIC_SPI_START + 175)
+#define CC_SCSS_WDT0CPU1BITEEXPIRED (GIC_SPI_START + 176)
+#define CC_SCSS_WDT0CPU0BITEEXPIRED (GIC_SPI_START + 177)
+#define TSENS_UPPER_LOWER_INT (GIC_SPI_START + 178)
+#define SSBI2_2_SC_CPU1_SECURE_INT (GIC_SPI_START + 179)
+#define SSBI2_2_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 180)
+#define SSBI2_1_SC_CPU1_SECURE_INT (GIC_SPI_START + 181)
+#define SSBI2_1_SC_CPU1_NON_SECURE_INT (GIC_SPI_START + 182)
+#define XPU_SUMMARY_IRQ (GIC_SPI_START + 183)
+#define BUS_EXCEPTION_SUMMARY_IRQ (GIC_SPI_START + 184)
+#define HSDDRX_SMICH0_IRQ (GIC_SPI_START + 185)
+#define HSDDRX_EBI1_IRQ (GIC_SPI_START + 186)
+#define SDC5_BAM_IRQ (GIC_SPI_START + 187)
+#define SDC5_IRQ_0 (GIC_SPI_START + 188)
+#define INT_UART9DM_IRQ (GIC_SPI_START + 189)
+#define GSBI9_QUP_IRQ (GIC_SPI_START + 190)
+#define INT_UART10DM_IRQ (GIC_SPI_START + 191)
+#define GSBI10_QUP_IRQ (GIC_SPI_START + 192)
+#define INT_UART11DM_IRQ (GIC_SPI_START + 193)
+#define GSBI11_QUP_IRQ (GIC_SPI_START + 194)
+#define INT_UART12DM_IRQ (GIC_SPI_START + 195)
+#define GSBI12_QUP_IRQ (GIC_SPI_START + 196)
+
+/*SPI 197 to 209 arent used in 8x60*/
+#define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210)
+#define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211)
+
+/*SPI 212 to 216 arent used in 8x60*/
+#define SMPSS_SPARE_1 (GIC_SPI_START + 217)
+#define SMPSS_SPARE_2 (GIC_SPI_START + 218)
+#define SMPSS_SPARE_3 (GIC_SPI_START + 219)
+#define SMPSS_SPARE_4 (GIC_SPI_START + 220)
+#define SMPSS_SPARE_5 (GIC_SPI_START + 221)
+#define SMPSS_SPARE_6 (GIC_SPI_START + 222)
+#define SMPSS_SPARE_7 (GIC_SPI_START + 223)
+
+#define NR_GPIO_IRQS 173
+#define NR_MSM_IRQS 256
+#define NR_BOARD_IRQS 0
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h
new file mode 100644
index 00000000..3cd78b16
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/irqs.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IRQS_H
+#define __ASM_ARCH_MSM_IRQS_H
+
+#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "irqs-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "irqs-8x50.h"
+#include "sirc.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "irqs-8x60.h"
+#elif defined(CONFIG_ARCH_MSM8960)
+/* TODO: Make these not generic. */
+#include "irqs-8960.h"
+#elif defined(CONFIG_ARCH_MSM_ARM11)
+#include "irqs-7x00.h"
+#else
+#error "Unknown architecture specification"
+#endif
+
+#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS)
+#define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n))
+#define MSM_INT_TO_REG(base, irq) (base + irq / 32)
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
new file mode 100644
index 00000000..f2f8d299
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -0,0 +1,35 @@
+/* arch/arm/mach-msm/include/mach/memory.h
+ *
+ * Copyright (C) 2007 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_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/* physical offset of RAM */
+#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+#elif defined(CONFIG_ARCH_QSD8X50)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
+#elif defined(CONFIG_ARCH_MSM7X30)
+#define PLAT_PHYS_OFFSET UL(0x00200000)
+#elif defined(CONFIG_ARCH_MSM8X60)
+#define PLAT_PHYS_OFFSET UL(0x40200000)
+#elif defined(CONFIG_ARCH_MSM8960)
+#define PLAT_PHYS_OFFSET UL(0x40200000)
+#else
+#define PLAT_PHYS_OFFSET UL(0x10000000)
+#endif
+
+#endif
+
diff --git a/arch/arm/mach-msm/include/mach/mmc.h b/arch/arm/mach-msm/include/mach/mmc.h
new file mode 100644
index 00000000..5631b51c
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/mmc.h
@@ -0,0 +1,37 @@
+/*
+ * 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 msm_mmc_gpio {
+ unsigned no;
+ const char *name;
+};
+
+struct msm_mmc_gpio_data {
+ struct msm_mmc_gpio *gpio;
+ u8 size;
+};
+
+struct msm_mmc_platform_data {
+ unsigned int ocr_mask; /* available voltages */
+ 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);
+ struct msm_mmc_gpio_data *gpio_data;
+};
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h
new file mode 100644
index 00000000..1f4fc81b
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_fb.h
@@ -0,0 +1,147 @@
+/* arch/arm/mach-msm/include/mach/msm_fb.h
+ *
+ * Internal shared definitions for various MSM framebuffer parts.
+ *
+ * Copyright (C) 2007 Google Incorporated
+ *
+ * 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 _MSM_FB_H_
+#define _MSM_FB_H_
+
+#include <linux/device.h>
+
+struct mddi_info;
+
+struct msm_fb_data {
+ int xres; /* x resolution in pixels */
+ int yres; /* y resolution in pixels */
+ int width; /* disply width in mm */
+ int height; /* display height in mm */
+ unsigned output_format;
+};
+
+struct msmfb_callback {
+ void (*func)(struct msmfb_callback *);
+};
+
+enum {
+ MSM_MDDI_PMDH_INTERFACE,
+ MSM_MDDI_EMDH_INTERFACE,
+ MSM_EBI2_INTERFACE,
+};
+
+#define MSMFB_CAP_PARTIAL_UPDATES (1 << 0)
+
+struct msm_panel_data {
+ /* turns off the fb memory */
+ int (*suspend)(struct msm_panel_data *);
+ /* turns on the fb memory */
+ int (*resume)(struct msm_panel_data *);
+ /* turns off the panel */
+ int (*blank)(struct msm_panel_data *);
+ /* turns on the panel */
+ int (*unblank)(struct msm_panel_data *);
+ void (*wait_vsync)(struct msm_panel_data *);
+ void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *);
+ void (*clear_vsync)(struct msm_panel_data *);
+ /* from the enum above */
+ unsigned interface_type;
+ /* data to be passed to the fb driver */
+ struct msm_fb_data *fb_data;
+
+ /* capabilities supported by the panel */
+ uint32_t caps;
+};
+
+struct msm_mddi_client_data {
+ void (*suspend)(struct msm_mddi_client_data *);
+ void (*resume)(struct msm_mddi_client_data *);
+ void (*activate_link)(struct msm_mddi_client_data *);
+ void (*remote_write)(struct msm_mddi_client_data *, uint32_t val,
+ uint32_t reg);
+ uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg);
+ void (*auto_hibernate)(struct msm_mddi_client_data *, int);
+ /* custom data that needs to be passed from the board file to a
+ * particular client */
+ void *private_client_data;
+ struct resource *fb_resource;
+ /* from the list above */
+ unsigned interface_type;
+};
+
+struct msm_mddi_platform_data {
+ unsigned int clk_rate;
+ void (*power_client)(struct msm_mddi_client_data *, int on);
+
+ /* fixup the mfr name, product id */
+ void (*fixup)(uint16_t *mfr_name, uint16_t *product_id);
+
+ struct resource *fb_resource; /*optional*/
+ /* number of clients in the list that follows */
+ int num_clients;
+ /* array of client information of clients */
+ struct {
+ unsigned product_id; /* mfr id in top 16 bits, product id
+ * in lower 16 bits
+ */
+ char *name; /* the device name will be the platform
+ * device name registered for the client,
+ * it should match the name of the associated
+ * driver
+ */
+ unsigned id; /* id for mddi client device node, will also
+ * be used as device id of panel devices, if
+ * the client device will have multiple panels
+ * space must be left here for them
+ */
+ void *client_data; /* required private client data */
+ unsigned int clk_rate; /* optional: if the client requires a
+ * different mddi clk rate
+ */
+ } client_platform_data[];
+};
+
+struct mdp_blit_req;
+struct fb_info;
+struct mdp_device {
+ struct device dev;
+ void (*dma)(struct mdp_device *mpd, uint32_t addr,
+ uint32_t stride, uint32_t w, uint32_t h, uint32_t x,
+ uint32_t y, struct msmfb_callback *callback, int interface);
+ void (*dma_wait)(struct mdp_device *mdp);
+ int (*blit)(struct mdp_device *mdp, struct fb_info *fb,
+ struct mdp_blit_req *req);
+ void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
+};
+
+struct class_interface;
+int register_mdp_client(struct class_interface *class_intf);
+
+/**** private client data structs go below this line ***/
+
+struct msm_mddi_bridge_platform_data {
+ /* from board file */
+ int (*init)(struct msm_mddi_bridge_platform_data *,
+ struct msm_mddi_client_data *);
+ int (*uninit)(struct msm_mddi_bridge_platform_data *,
+ struct msm_mddi_client_data *);
+ /* passed to panel for use by the fb driver */
+ int (*blank)(struct msm_mddi_bridge_platform_data *,
+ struct msm_mddi_client_data *);
+ int (*unblank)(struct msm_mddi_bridge_platform_data *,
+ struct msm_mddi_client_data *);
+ struct msm_fb_data fb_data;
+};
+
+
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
new file mode 100644
index 00000000..8f99d976
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h
@@ -0,0 +1,129 @@
+/* arch/arm/mach-msm/include/mach/msm_iomap.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_7X00_H
+#define __ASM_ARCH_MSM_IOMAP_7X00_H
+
+#include <asm/sizes.h>
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#ifdef __ASSEMBLY__
+#define IOMEM(x) x
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
+#endif
+
+#define MSM_VIC_BASE IOMEM(0xE0000000)
+#define MSM_VIC_PHYS 0xC0000000
+#define MSM_VIC_SIZE SZ_4K
+
+#define MSM7X00_CSR_PHYS 0xC0100000
+#define MSM7X00_CSR_SIZE SZ_4K
+
+#define MSM_DMOV_BASE IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS 0xA9700000
+#define MSM_DMOV_SIZE SZ_4K
+
+#define MSM_GPIO1_BASE IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS 0xA9200000
+#define MSM_GPIO1_SIZE SZ_4K
+
+#define MSM_GPIO2_BASE IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS 0xA9300000
+#define MSM_GPIO2_SIZE SZ_4K
+
+#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS 0xA8600000
+#define MSM_CLK_CTL_SIZE SZ_4K
+
+#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS 0x01F00000
+#define MSM_SHARED_RAM_SIZE SZ_1M
+
+#define MSM_UART1_PHYS 0xA9A00000
+#define MSM_UART1_SIZE SZ_4K
+
+#define MSM_UART2_PHYS 0xA9B00000
+#define MSM_UART2_SIZE SZ_4K
+
+#define MSM_UART3_PHYS 0xA9C00000
+#define MSM_UART3_SIZE SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE 0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE SZ_4K
+#endif
+
+#define MSM_SDC1_PHYS 0xA0400000
+#define MSM_SDC1_SIZE SZ_4K
+
+#define MSM_SDC2_PHYS 0xA0500000
+#define MSM_SDC2_SIZE SZ_4K
+
+#define MSM_SDC3_PHYS 0xA0600000
+#define MSM_SDC3_SIZE SZ_4K
+
+#define MSM_SDC4_PHYS 0xA0700000
+#define MSM_SDC4_SIZE SZ_4K
+
+#define MSM_I2C_PHYS 0xA9900000
+#define MSM_I2C_SIZE SZ_4K
+
+#define MSM_HSUSB_PHYS 0xA0800000
+#define MSM_HSUSB_SIZE SZ_4K
+
+#define MSM_PMDH_PHYS 0xAA600000
+#define MSM_PMDH_SIZE SZ_4K
+
+#define MSM_EMDH_PHYS 0xAA700000
+#define MSM_EMDH_SIZE SZ_4K
+
+#define MSM_MDP_PHYS 0xAA200000
+#define MSM_MDP_SIZE 0x000F0000
+
+#define MSM_MDC_PHYS 0xAA500000
+#define MSM_MDC_SIZE SZ_1M
+
+#define MSM_AD5_PHYS 0xAC000000
+#define MSM_AD5_SIZE (SZ_1M*13)
+
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
new file mode 100644
index 00000000..4d84be15
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_7X30_H
+#define __ASM_ARCH_MSM_IOMAP_7X30_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_VIC_BASE IOMEM(0xE0000000)
+#define MSM_VIC_PHYS 0xC0080000
+#define MSM_VIC_SIZE SZ_4K
+
+#define MSM7X30_CSR_PHYS 0xC0100000
+#define MSM7X30_CSR_SIZE SZ_4K
+
+#define MSM_DMOV_BASE IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS 0xAC400000
+#define MSM_DMOV_SIZE SZ_4K
+
+#define MSM_GPIO1_BASE IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS 0xAC001000
+#define MSM_GPIO1_SIZE SZ_4K
+
+#define MSM_GPIO2_BASE IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS 0xAC101000
+#define MSM_GPIO2_SIZE SZ_4K
+
+#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS 0xAB800000
+#define MSM_CLK_CTL_SIZE SZ_4K
+
+#define MSM_CLK_CTL_SH2_BASE IOMEM(0xE0006000)
+#define MSM_CLK_CTL_SH2_PHYS 0xABA01000
+#define MSM_CLK_CTL_SH2_SIZE SZ_4K
+
+#define MSM_ACC_BASE IOMEM(0xE0007000)
+#define MSM_ACC_PHYS 0xC0101000
+#define MSM_ACC_SIZE SZ_4K
+
+#define MSM_SAW_BASE IOMEM(0xE0008000)
+#define MSM_SAW_PHYS 0xC0102000
+#define MSM_SAW_SIZE SZ_4K
+
+#define MSM_GCC_BASE IOMEM(0xE0009000)
+#define MSM_GCC_PHYS 0xC0182000
+#define MSM_GCC_SIZE SZ_4K
+
+#define MSM_TCSR_BASE IOMEM(0xE000A000)
+#define MSM_TCSR_PHYS 0xAB600000
+#define MSM_TCSR_SIZE SZ_4K
+
+#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS 0x00100000
+#define MSM_SHARED_RAM_SIZE SZ_1M
+
+#define MSM_UART1_PHYS 0xACA00000
+#define MSM_UART1_SIZE SZ_4K
+
+#define MSM_UART2_PHYS 0xACB00000
+#define MSM_UART2_SIZE SZ_4K
+
+#define MSM_UART3_PHYS 0xACC00000
+#define MSM_UART3_SIZE SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE 0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE SZ_4K
+#endif
+
+#define MSM_MDC_BASE IOMEM(0xE0200000)
+#define MSM_MDC_PHYS 0xAA500000
+#define MSM_MDC_SIZE SZ_1M
+
+#define MSM_AD5_BASE IOMEM(0xE0300000)
+#define MSM_AD5_PHYS 0xA7000000
+#define MSM_AD5_SIZE (SZ_1M*13)
+
+#define MSM_HSUSB_PHYS 0xA3600000
+#define MSM_HSUSB_SIZE SZ_1K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8960.h b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
new file mode 100644
index 00000000..3c9d9602
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8960.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8960_H
+#define __ASM_ARCH_MSM_IOMAP_8960_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+
+#define MSM8960_QGIC_DIST_PHYS 0x02000000
+#define MSM8960_QGIC_DIST_SIZE SZ_4K
+
+#define MSM8960_QGIC_CPU_PHYS 0x02002000
+#define MSM8960_QGIC_CPU_SIZE SZ_4K
+
+#define MSM8960_TMR_PHYS 0x0200A000
+#define MSM8960_TMR_SIZE SZ_4K
+
+#define MSM8960_TMR0_PHYS 0x0208A000
+#define MSM8960_TMR0_SIZE SZ_4K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
new file mode 100644
index 00000000..d4143201
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011 Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8X50_H
+#define __ASM_ARCH_MSM_IOMAP_8X50_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM_VIC_BASE IOMEM(0xE0000000)
+#define MSM_VIC_PHYS 0xAC000000
+#define MSM_VIC_SIZE SZ_4K
+
+#define QSD8X50_CSR_PHYS 0xAC100000
+#define QSD8X50_CSR_SIZE SZ_4K
+
+#define MSM_DMOV_BASE IOMEM(0xE0002000)
+#define MSM_DMOV_PHYS 0xA9700000
+#define MSM_DMOV_SIZE SZ_4K
+
+#define MSM_GPIO1_BASE IOMEM(0xE0003000)
+#define MSM_GPIO1_PHYS 0xA9000000
+#define MSM_GPIO1_SIZE SZ_4K
+
+#define MSM_GPIO2_BASE IOMEM(0xE0004000)
+#define MSM_GPIO2_PHYS 0xA9100000
+#define MSM_GPIO2_SIZE SZ_4K
+
+#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
+#define MSM_CLK_CTL_PHYS 0xA8600000
+#define MSM_CLK_CTL_SIZE SZ_4K
+
+#define MSM_SIRC_BASE IOMEM(0xE1006000)
+#define MSM_SIRC_PHYS 0xAC200000
+#define MSM_SIRC_SIZE SZ_4K
+
+#define MSM_SCPLL_BASE IOMEM(0xE1007000)
+#define MSM_SCPLL_PHYS 0xA8800000
+#define MSM_SCPLL_SIZE SZ_4K
+
+#ifdef CONFIG_MSM_SOC_REV_A
+#define MSM_SMI_BASE 0xE0000000
+#else
+#define MSM_SMI_BASE 0x00000000
+#endif
+
+#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
+#define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000)
+#define MSM_SHARED_RAM_SIZE SZ_1M
+
+#define MSM_UART1_PHYS 0xA9A00000
+#define MSM_UART1_SIZE SZ_4K
+
+#define MSM_UART2_PHYS 0xA9B00000
+#define MSM_UART2_SIZE SZ_4K
+
+#define MSM_UART3_PHYS 0xA9C00000
+#define MSM_UART3_SIZE SZ_4K
+
+#ifdef CONFIG_MSM_DEBUG_UART
+#define MSM_DEBUG_UART_BASE 0xE1000000
+#if CONFIG_MSM_DEBUG_UART == 1
+#define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 2
+#define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS
+#elif CONFIG_MSM_DEBUG_UART == 3
+#define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS
+#endif
+#define MSM_DEBUG_UART_SIZE SZ_4K
+#endif
+
+#define MSM_MDC_BASE IOMEM(0xE0200000)
+#define MSM_MDC_PHYS 0xAA500000
+#define MSM_MDC_SIZE SZ_1M
+
+#define MSM_AD5_BASE IOMEM(0xE0300000)
+#define MSM_AD5_PHYS 0xAC000000
+#define MSM_AD5_SIZE (SZ_1M*13)
+
+
+#define MSM_I2C_SIZE SZ_4K
+#define MSM_I2C_PHYS 0xA9900000
+
+#define MSM_HSUSB_PHYS 0xA0800000
+#define MSM_HSUSB_SIZE SZ_1K
+
+#define MSM_NAND_PHYS 0xA0A00000
+
+
+#define MSM_TSIF_PHYS (0xa0100000)
+#define MSM_TSIF_SIZE (0x200)
+
+#define MSM_TSSC_PHYS 0xAA300000
+
+#define MSM_UART1DM_PHYS 0xA0200000
+#define MSM_UART2DM_PHYS 0xA0900000
+
+
+#define MSM_SDC1_PHYS 0xA0300000
+#define MSM_SDC1_SIZE SZ_4K
+
+#define MSM_SDC2_PHYS 0xA0400000
+#define MSM_SDC2_SIZE SZ_4K
+
+#define MSM_SDC3_PHYS 0xA0500000
+#define MSM_SDC3_SIZE SZ_4K
+
+#define MSM_SDC4_PHYS 0xA0600000
+#define MSM_SDC4_SIZE SZ_4K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
new file mode 100644
index 00000000..3b19b8f2
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_8X60_H
+#define __ASM_ARCH_MSM_IOMAP_8X60_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSM8X60_QGIC_DIST_PHYS 0x02080000
+#define MSM8X60_QGIC_DIST_SIZE SZ_4K
+
+#define MSM8X60_QGIC_CPU_PHYS 0x02081000
+#define MSM8X60_QGIC_CPU_SIZE SZ_4K
+
+#define MSM_ACC_BASE IOMEM(0xF0002000)
+#define MSM_ACC_PHYS 0x02001000
+#define MSM_ACC_SIZE SZ_4K
+
+#define MSM_GCC_BASE IOMEM(0xF0003000)
+#define MSM_GCC_PHYS 0x02082000
+#define MSM_GCC_SIZE SZ_4K
+
+#define MSM_TLMM_BASE IOMEM(0xF0004000)
+#define MSM_TLMM_PHYS 0x00800000
+#define MSM_TLMM_SIZE SZ_16K
+
+#define MSM_SHARED_RAM_BASE IOMEM(0xF0100000)
+#define MSM_SHARED_RAM_SIZE SZ_1M
+
+#define MSM8X60_TMR_PHYS 0x02000000
+#define MSM8X60_TMR_SIZE SZ_4K
+
+#define MSM8X60_TMR0_PHYS 0x02040000
+#define MSM8X60_TMR0_SIZE SZ_4K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
new file mode 100644
index 00000000..2f494b6a
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * The MSM peripherals are spread all over across 768MB of physical
+ * space, which makes just having a simple IO_ADDRESS macro to slide
+ * them into the right virtual location rough. Instead, we will
+ * provide a master phys->virt mapping for peripherals here.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_IOMAP_H
+#define __ASM_ARCH_MSM_IOMAP_H
+
+#include <asm/sizes.h>
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * MSM_VIC_BASE must be an value that can be loaded via a "mov"
+ * instruction, otherwise entry-macro.S will not compile.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#ifdef __ASSEMBLY__
+#define IOMEM(x) x
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
+#endif
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#include "msm_iomap-7x30.h"
+#elif defined(CONFIG_ARCH_QSD8X50)
+#include "msm_iomap-8x50.h"
+#elif defined(CONFIG_ARCH_MSM8X60)
+#include "msm_iomap-8x60.h"
+#else
+#include "msm_iomap-7x00.h"
+#endif
+
+#include "msm_iomap-8960.h"
+
+/* Virtual addresses shared across all MSM targets. */
+#define MSM_CSR_BASE IOMEM(0xE0001000)
+#define MSM_QGIC_DIST_BASE IOMEM(0xF0000000)
+#define MSM_QGIC_CPU_BASE IOMEM(0xF0001000)
+#define MSM_TMR_BASE IOMEM(0xF0200000)
+#define MSM_TMR0_BASE IOMEM(0xF0201000)
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h
new file mode 100644
index 00000000..029463ec
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_smd.h
@@ -0,0 +1,109 @@
+/* linux/include/asm-arm/arch-msm/msm_smd.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_ARCH_MSM_SMD_H
+#define __ASM_ARCH_MSM_SMD_H
+
+typedef struct smd_channel smd_channel_t;
+
+extern int (*msm_check_for_modem_crash)(void);
+
+/* warning: notify() may be called before open returns */
+int smd_open(const char *name, smd_channel_t **ch, void *priv,
+ void (*notify)(void *priv, unsigned event));
+
+#define SMD_EVENT_DATA 1
+#define SMD_EVENT_OPEN 2
+#define SMD_EVENT_CLOSE 3
+
+int smd_close(smd_channel_t *ch);
+
+/* passing a null pointer for data reads and discards */
+int smd_read(smd_channel_t *ch, void *data, int len);
+
+/* Write to stream channels may do a partial write and return
+** the length actually written.
+** Write to packet channels will never do a partial write --
+** it will return the requested length written or an error.
+*/
+int smd_write(smd_channel_t *ch, const void *data, int len);
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len);
+
+int smd_write_avail(smd_channel_t *ch);
+int smd_read_avail(smd_channel_t *ch);
+
+/* Returns the total size of the current packet being read.
+** Returns 0 if no packets available or a stream channel.
+*/
+int smd_cur_packet_size(smd_channel_t *ch);
+
+/* used for tty unthrottling and the like -- causes the notify()
+** callback to be called from the same lock context as is used
+** when it is called from channel updates
+*/
+void smd_kick(smd_channel_t *ch);
+
+
+#if 0
+/* these are interruptable waits which will block you until the specified
+** number of bytes are readable or writable.
+*/
+int smd_wait_until_readable(smd_channel_t *ch, int bytes);
+int smd_wait_until_writable(smd_channel_t *ch, int bytes);
+#endif
+
+typedef enum {
+ SMD_PORT_DS = 0,
+ SMD_PORT_DIAG,
+ SMD_PORT_RPC_CALL,
+ SMD_PORT_RPC_REPLY,
+ SMD_PORT_BT,
+ SMD_PORT_CONTROL,
+ SMD_PORT_MEMCPY_SPARE1,
+ SMD_PORT_DATA1,
+ SMD_PORT_DATA2,
+ SMD_PORT_DATA3,
+ SMD_PORT_DATA4,
+ SMD_PORT_DATA5,
+ SMD_PORT_DATA6,
+ SMD_PORT_DATA7,
+ SMD_PORT_DATA8,
+ SMD_PORT_DATA9,
+ SMD_PORT_DATA10,
+ SMD_PORT_DATA11,
+ SMD_PORT_DATA12,
+ SMD_PORT_DATA13,
+ SMD_PORT_DATA14,
+ SMD_PORT_DATA15,
+ SMD_PORT_DATA16,
+ SMD_PORT_DATA17,
+ SMD_PORT_DATA18,
+ SMD_PORT_DATA19,
+ SMD_PORT_DATA20,
+ SMD_PORT_GPS_NMEA,
+ SMD_PORT_BRIDGE_1,
+ SMD_PORT_BRIDGE_2,
+ SMD_PORT_BRIDGE_3,
+ SMD_PORT_BRIDGE_4,
+ SMD_PORT_BRIDGE_5,
+ SMD_PORT_LOOPBACK,
+ SMD_PORT_CS_APPS_MODEM,
+ SMD_PORT_CS_APPS_DSP,
+ SMD_PORT_CS_MODEM_DSP,
+ SMD_NUM_PORTS,
+} smd_port_id_type;
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h
new file mode 100644
index 00000000..ef55868a
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/sirc.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2008-2009, 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_SIRC_H
+#define __ASM_ARCH_MSM_SIRC_H
+
+struct sirc_regs_t {
+ void *int_enable;
+ void *int_enable_clear;
+ void *int_enable_set;
+ void *int_type;
+ void *int_polarity;
+ void *int_clear;
+};
+
+struct sirc_cascade_regs {
+ void *int_status;
+ unsigned int cascade_irq;
+};
+
+void msm_init_sirc(void);
+void msm_sirc_enter_sleep(void);
+void msm_sirc_exit_sleep(void);
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+
+#include <mach/msm_iomap.h>
+
+/*
+ * Secondary interrupt controller interrupts
+ */
+
+#define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS)
+
+#define INT_UART1 (FIRST_SIRC_IRQ + 0)
+#define INT_UART2 (FIRST_SIRC_IRQ + 1)
+#define INT_UART3 (FIRST_SIRC_IRQ + 2)
+#define INT_UART1_RX (FIRST_SIRC_IRQ + 3)
+#define INT_UART2_RX (FIRST_SIRC_IRQ + 4)
+#define INT_UART3_RX (FIRST_SIRC_IRQ + 5)
+#define INT_SPI_INPUT (FIRST_SIRC_IRQ + 6)
+#define INT_SPI_OUTPUT (FIRST_SIRC_IRQ + 7)
+#define INT_SPI_ERROR (FIRST_SIRC_IRQ + 8)
+#define INT_GPIO_GROUP1 (FIRST_SIRC_IRQ + 9)
+#define INT_GPIO_GROUP2 (FIRST_SIRC_IRQ + 10)
+#define INT_GPIO_GROUP1_SECURE (FIRST_SIRC_IRQ + 11)
+#define INT_GPIO_GROUP2_SECURE (FIRST_SIRC_IRQ + 12)
+#define INT_AVS_SVIC (FIRST_SIRC_IRQ + 13)
+#define INT_AVS_REQ_UP (FIRST_SIRC_IRQ + 14)
+#define INT_AVS_REQ_DOWN (FIRST_SIRC_IRQ + 15)
+#define INT_PBUS_ERR (FIRST_SIRC_IRQ + 16)
+#define INT_AXI_ERR (FIRST_SIRC_IRQ + 17)
+#define INT_SMI_ERR (FIRST_SIRC_IRQ + 18)
+#define INT_EBI1_ERR (FIRST_SIRC_IRQ + 19)
+#define INT_IMEM_ERR (FIRST_SIRC_IRQ + 20)
+#define INT_TEMP_SENSOR (FIRST_SIRC_IRQ + 21)
+#define INT_TV_ENC (FIRST_SIRC_IRQ + 22)
+#define INT_GRP2D (FIRST_SIRC_IRQ + 23)
+#define INT_GSBI_QUP (FIRST_SIRC_IRQ + 24)
+#define INT_SC_ACG (FIRST_SIRC_IRQ + 25)
+#define INT_WDT0 (FIRST_SIRC_IRQ + 26)
+#define INT_WDT1 (FIRST_SIRC_IRQ + 27)
+
+#if defined(CONFIG_MSM_SOC_REV_A)
+#define NR_SIRC_IRQS 28
+#define SIRC_MASK 0x0FFFFFFF
+#else
+#define NR_SIRC_IRQS 23
+#define SIRC_MASK 0x007FFFFF
+#endif
+
+#define LAST_SIRC_IRQ (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1)
+
+#define SPSS_SIRC_INT_SELECT (MSM_SIRC_BASE + 0x00)
+#define SPSS_SIRC_INT_ENABLE (MSM_SIRC_BASE + 0x04)
+#define SPSS_SIRC_INT_ENABLE_CLEAR (MSM_SIRC_BASE + 0x08)
+#define SPSS_SIRC_INT_ENABLE_SET (MSM_SIRC_BASE + 0x0C)
+#define SPSS_SIRC_INT_TYPE (MSM_SIRC_BASE + 0x10)
+#define SPSS_SIRC_INT_POLARITY (MSM_SIRC_BASE + 0x14)
+#define SPSS_SIRC_SECURITY (MSM_SIRC_BASE + 0x18)
+#define SPSS_SIRC_IRQ_STATUS (MSM_SIRC_BASE + 0x1C)
+#define SPSS_SIRC_IRQ1_STATUS (MSM_SIRC_BASE + 0x20)
+#define SPSS_SIRC_RAW_STATUS (MSM_SIRC_BASE + 0x24)
+#define SPSS_SIRC_INT_CLEAR (MSM_SIRC_BASE + 0x28)
+#define SPSS_SIRC_SOFT_INT (MSM_SIRC_BASE + 0x2C)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
new file mode 100644
index 00000000..d2e83f42
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-msm/include/mach/system.h
+ *
+ * Copyright (C) 2007 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 <mach/hardware.h>
+
+void arch_idle(void);
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ for (;;) ; /* depends on IPC w/ other core */
+}
+
+/* low level hardware reset hook -- for example, hitting the
+ * PSHOLD line on the PMIC to hard reset the system
+ */
+extern void (*msm_hw_reset_hook)(void);
diff --git a/arch/arm/mach-msm/include/mach/timex.h b/arch/arm/mach-msm/include/mach/timex.h
new file mode 100644
index 00000000..a62e6b21
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/timex.h
@@ -0,0 +1,21 @@
+/* arch/arm/mach-msm/include/mach/timex.h
+ *
+ * Copyright (C) 2007 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_ARCH_MSM_TIMEX_H
+#define __ASM_ARCH_MSM_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/uncompress.h b/arch/arm/mach-msm/include/mach/uncompress.h
new file mode 100644
index 00000000..d94292c2
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/uncompress.h
@@ -0,0 +1,43 @@
+/* arch/arm/mach-msm/include/mach/uncompress.h
+ *
+ * Copyright (C) 2007 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_ARCH_MSM_UNCOMPRESS_H
+
+#include "hardware.h"
+#include "linux/io.h"
+#include "mach/msm_iomap.h"
+
+static void putc(int c)
+{
+#if defined(MSM_DEBUG_UART_PHYS)
+ unsigned base = MSM_DEBUG_UART_PHYS;
+ while (!(readl(base + 0x08) & 0x04)) ;
+ writel(c, base + 0x0c);
+#endif
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+static inline void arch_decomp_wdog(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/vmalloc.h b/arch/arm/mach-msm/include/mach/vmalloc.h
new file mode 100644
index 00000000..d138448e
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/* arch/arm/mach-msm/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2007 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_ARCH_MSM_VMALLOC_H
+#define __ASM_ARCH_MSM_VMALLOC_H
+
+#define VMALLOC_END 0xd0000000UL
+
+#endif
+
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h
new file mode 100644
index 00000000..6626e786
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/vreg.h
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/arch-msm/vreg.h
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_VREG_H
+#define __ARCH_ARM_MACH_MSM_VREG_H
+
+struct vreg;
+
+struct vreg *vreg_get(struct device *dev, const char *id);
+void vreg_put(struct vreg *vreg);
+
+int vreg_enable(struct vreg *vreg);
+int vreg_disable(struct vreg *vreg);
+int vreg_set_level(struct vreg *vreg, unsigned mv);
+
+#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
new file mode 100644
index 00000000..cec6ed1c
--- /dev/null
+++ b/arch/arm/mach-msm/io.c
@@ -0,0 +1,180 @@
+/* arch/arm/mach-msm/io.c
+ *
+ * MSM7K, QSD io support
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <mach/msm_iomap.h>
+#include <asm/mach/map.h>
+
+#include <mach/board.h>
+
+#define MSM_CHIP_DEVICE(name, chip) { \
+ .virtual = (unsigned long) MSM_##name##_BASE, \
+ .pfn = __phys_to_pfn(chip##_##name##_PHYS), \
+ .length = chip##_##name##_SIZE, \
+ .type = MT_DEVICE_NONSHARED, \
+ }
+
+#define MSM_DEVICE(name) MSM_CHIP_DEVICE(name, MSM)
+
+#if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \
+ || defined(CONFIG_ARCH_MSM7X25)
+static struct map_desc msm_io_desc[] __initdata = {
+ MSM_DEVICE(VIC),
+ MSM_CHIP_DEVICE(CSR, MSM7X00),
+ MSM_DEVICE(DMOV),
+ MSM_DEVICE(GPIO1),
+ MSM_DEVICE(GPIO2),
+ MSM_DEVICE(CLK_CTL),
+#ifdef CONFIG_MSM_DEBUG_UART
+ MSM_DEVICE(DEBUG_UART),
+#endif
+#ifdef CONFIG_ARCH_MSM7X30
+ MSM_DEVICE(GCC),
+#endif
+ {
+ .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
+ .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+ .length = MSM_SHARED_RAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init msm_map_common_io(void)
+{
+ /* Make sure the peripheral register window is closed, since
+ * we will use PTE flags (TEX[1]=1,B=0,C=1) to determine which
+ * pages are peripheral interface or not.
+ */
+ asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0));
+ iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc));
+}
+#endif
+
+#ifdef CONFIG_ARCH_QSD8X50
+static struct map_desc qsd8x50_io_desc[] __initdata = {
+ MSM_DEVICE(VIC),
+ MSM_CHIP_DEVICE(CSR, QSD8X50),
+ MSM_DEVICE(DMOV),
+ MSM_DEVICE(GPIO1),
+ MSM_DEVICE(GPIO2),
+ MSM_DEVICE(CLK_CTL),
+ MSM_DEVICE(SIRC),
+ MSM_DEVICE(SCPLL),
+ MSM_DEVICE(AD5),
+ MSM_DEVICE(MDC),
+#ifdef CONFIG_MSM_DEBUG_UART
+ MSM_DEVICE(DEBUG_UART),
+#endif
+ {
+ .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
+ .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+ .length = MSM_SHARED_RAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init msm_map_qsd8x50_io(void)
+{
+ iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc));
+}
+#endif /* CONFIG_ARCH_QSD8X50 */
+
+#ifdef CONFIG_ARCH_MSM8X60
+static struct map_desc msm8x60_io_desc[] __initdata = {
+ MSM_CHIP_DEVICE(QGIC_DIST, MSM8X60),
+ MSM_CHIP_DEVICE(QGIC_CPU, MSM8X60),
+ MSM_CHIP_DEVICE(TMR, MSM8X60),
+ MSM_CHIP_DEVICE(TMR0, MSM8X60),
+ MSM_DEVICE(ACC),
+ MSM_DEVICE(GCC),
+};
+
+void __init msm_map_msm8x60_io(void)
+{
+ iotable_init(msm8x60_io_desc, ARRAY_SIZE(msm8x60_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM8X60 */
+
+#ifdef CONFIG_ARCH_MSM8960
+static struct map_desc msm8960_io_desc[] __initdata = {
+ MSM_CHIP_DEVICE(QGIC_DIST, MSM8960),
+ MSM_CHIP_DEVICE(QGIC_CPU, MSM8960),
+ MSM_CHIP_DEVICE(TMR, MSM8960),
+ MSM_CHIP_DEVICE(TMR0, MSM8960),
+};
+
+void __init msm_map_msm8960_io(void)
+{
+ iotable_init(msm8960_io_desc, ARRAY_SIZE(msm8960_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM8960 */
+
+#ifdef CONFIG_ARCH_MSM7X30
+static struct map_desc msm7x30_io_desc[] __initdata = {
+ MSM_DEVICE(VIC),
+ MSM_CHIP_DEVICE(CSR, MSM7X30),
+ MSM_DEVICE(DMOV),
+ MSM_DEVICE(GPIO1),
+ MSM_DEVICE(GPIO2),
+ MSM_DEVICE(CLK_CTL),
+ MSM_DEVICE(CLK_CTL_SH2),
+ MSM_DEVICE(AD5),
+ MSM_DEVICE(MDC),
+ MSM_DEVICE(ACC),
+ MSM_DEVICE(SAW),
+ MSM_DEVICE(GCC),
+ MSM_DEVICE(TCSR),
+#ifdef CONFIG_MSM_DEBUG_UART
+ MSM_DEVICE(DEBUG_UART),
+#endif
+ {
+ .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
+ .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
+ .length = MSM_SHARED_RAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init msm_map_msm7x30_io(void)
+{
+ iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
+
+void __iomem *
+__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+ if (mtype == MT_DEVICE) {
+ /* The peripherals in the 88000000 - D0000000 range
+ * are only accessible by type MT_DEVICE_NONSHARED.
+ * Adjust mtype as necessary to make this "just work."
+ */
+ if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000))
+ mtype = MT_DEVICE_NONSHARED;
+ }
+
+ return __arm_ioremap_caller(phys_addr, size, mtype,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__msm_ioremap);
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c
new file mode 100644
index 00000000..1a584e07
--- /dev/null
+++ b/arch/arm/mach-msm/iommu.c
@@ -0,0 +1,731 @@
+/* Copyright (c) 2010-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/iommu.h>
+#include <linux/clk.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sizes.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+
+#define MRC(reg, processor, op1, crn, crm, op2) \
+__asm__ __volatile__ ( \
+" mrc " #processor "," #op1 ", %0," #crn "," #crm "," #op2 "\n" \
+: "=r" (reg))
+
+#define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0)
+#define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1)
+
+static int msm_iommu_tex_class[4];
+
+DEFINE_SPINLOCK(msm_iommu_lock);
+
+struct msm_priv {
+ unsigned long *pgtable;
+ struct list_head list_attached;
+};
+
+static int __enable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+ int ret;
+
+ ret = clk_enable(drvdata->pclk);
+ if (ret)
+ goto fail;
+
+ if (drvdata->clk) {
+ ret = clk_enable(drvdata->clk);
+ if (ret)
+ clk_disable(drvdata->pclk);
+ }
+fail:
+ return ret;
+}
+
+static void __disable_clocks(struct msm_iommu_drvdata *drvdata)
+{
+ if (drvdata->clk)
+ clk_disable(drvdata->clk);
+ clk_disable(drvdata->pclk);
+}
+
+static int __flush_iotlb(struct iommu_domain *domain)
+{
+ struct msm_priv *priv = domain->priv;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ int ret = 0;
+#ifndef CONFIG_IOMMU_PGTABLES_L2
+ unsigned long *fl_table = priv->pgtable;
+ int i;
+
+ if (!list_empty(&priv->list_attached)) {
+ dmac_flush_range(fl_table, fl_table + SZ_16K);
+
+ for (i = 0; i < NUM_FL_PTE; i++)
+ if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) {
+ void *sl_table = __va(fl_table[i] &
+ FL_BASE_MASK);
+ dmac_flush_range(sl_table, sl_table + SZ_4K);
+ }
+ }
+#endif
+
+ list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) {
+ if (!ctx_drvdata->pdev || !ctx_drvdata->pdev->dev.parent)
+ BUG();
+
+ iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+ BUG_ON(!iommu_drvdata);
+
+ ret = __enable_clocks(iommu_drvdata);
+ if (ret)
+ goto fail;
+
+ SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0);
+ __disable_clocks(iommu_drvdata);
+ }
+fail:
+ return ret;
+}
+
+static void __reset_context(void __iomem *base, int ctx)
+{
+ SET_BPRCOSH(base, ctx, 0);
+ SET_BPRCISH(base, ctx, 0);
+ SET_BPRCNSH(base, ctx, 0);
+ SET_BPSHCFG(base, ctx, 0);
+ SET_BPMTCFG(base, ctx, 0);
+ SET_ACTLR(base, ctx, 0);
+ SET_SCTLR(base, ctx, 0);
+ SET_FSRRESTORE(base, ctx, 0);
+ SET_TTBR0(base, ctx, 0);
+ SET_TTBR1(base, ctx, 0);
+ SET_TTBCR(base, ctx, 0);
+ SET_BFBCR(base, ctx, 0);
+ SET_PAR(base, ctx, 0);
+ SET_FAR(base, ctx, 0);
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_TLBFLPTER(base, ctx, 0);
+ SET_TLBSLPTER(base, ctx, 0);
+ SET_TLBLKCR(base, ctx, 0);
+ SET_PRRR(base, ctx, 0);
+ SET_NMRR(base, ctx, 0);
+}
+
+static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable)
+{
+ unsigned int prrr, nmrr;
+ __reset_context(base, ctx);
+
+ /* Set up HTW mode */
+ /* TLB miss configuration: perform HTW on miss */
+ SET_TLBMCFG(base, ctx, 0x3);
+
+ /* V2P configuration: HTW for access */
+ SET_V2PCFG(base, ctx, 0x3);
+
+ SET_TTBCR(base, ctx, 0);
+ SET_TTBR0_PA(base, ctx, (pgtable >> 14));
+
+ /* Invalidate the TLB for this context */
+ SET_CTX_TLBIALL(base, ctx, 0);
+
+ /* Set interrupt number to "secure" interrupt */
+ SET_IRPTNDX(base, ctx, 0);
+
+ /* Enable context fault interrupt */
+ SET_CFEIE(base, ctx, 1);
+
+ /* Stall access on a context fault and let the handler deal with it */
+ SET_CFCFG(base, ctx, 1);
+
+ /* Redirect all cacheable requests to L2 slave port. */
+ SET_RCISH(base, ctx, 1);
+ SET_RCOSH(base, ctx, 1);
+ SET_RCNSH(base, ctx, 1);
+
+ /* Turn on TEX Remap */
+ SET_TRE(base, ctx, 1);
+
+ /* Set TEX remap attributes */
+ RCP15_PRRR(prrr);
+ RCP15_NMRR(nmrr);
+ SET_PRRR(base, ctx, prrr);
+ SET_NMRR(base, ctx, nmrr);
+
+ /* Turn on BFB prefetch */
+ SET_BFBDFE(base, ctx, 1);
+
+#ifdef CONFIG_IOMMU_PGTABLES_L2
+ /* Configure page tables as inner-cacheable and shareable to reduce
+ * the TLB miss penalty.
+ */
+ SET_TTBR0_SH(base, ctx, 1);
+ SET_TTBR1_SH(base, ctx, 1);
+
+ SET_TTBR0_NOS(base, ctx, 1);
+ SET_TTBR1_NOS(base, ctx, 1);
+
+ SET_TTBR0_IRGNH(base, ctx, 0); /* WB, WA */
+ SET_TTBR0_IRGNL(base, ctx, 1);
+
+ SET_TTBR1_IRGNH(base, ctx, 0); /* WB, WA */
+ SET_TTBR1_IRGNL(base, ctx, 1);
+
+ SET_TTBR0_ORGN(base, ctx, 1); /* WB, WA */
+ SET_TTBR1_ORGN(base, ctx, 1); /* WB, WA */
+#endif
+
+ /* Enable the MMU */
+ SET_M(base, ctx, 1);
+}
+
+static int msm_iommu_domain_init(struct iommu_domain *domain)
+{
+ struct msm_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+ if (!priv)
+ goto fail_nomem;
+
+ INIT_LIST_HEAD(&priv->list_attached);
+ priv->pgtable = (unsigned long *)__get_free_pages(GFP_KERNEL,
+ get_order(SZ_16K));
+
+ if (!priv->pgtable)
+ goto fail_nomem;
+
+ memset(priv->pgtable, 0, SZ_16K);
+ domain->priv = priv;
+ return 0;
+
+fail_nomem:
+ kfree(priv);
+ return -ENOMEM;
+}
+
+static void msm_iommu_domain_destroy(struct iommu_domain *domain)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ int i;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+ priv = domain->priv;
+ domain->priv = NULL;
+
+ if (priv) {
+ fl_table = priv->pgtable;
+
+ for (i = 0; i < NUM_FL_PTE; i++)
+ if ((fl_table[i] & 0x03) == FL_TYPE_TABLE)
+ free_page((unsigned long) __va(((fl_table[i]) &
+ FL_BASE_MASK)));
+
+ free_pages((unsigned long)priv->pgtable, get_order(SZ_16K));
+ priv->pgtable = NULL;
+ }
+
+ kfree(priv);
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_ctx_dev *ctx_dev;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ struct msm_iommu_ctx_drvdata *tmp_drvdata;
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+
+ if (!priv || !dev) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ iommu_drvdata = dev_get_drvdata(dev->parent);
+ ctx_drvdata = dev_get_drvdata(dev);
+ ctx_dev = dev->platform_data;
+
+ if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!list_empty(&ctx_drvdata->attached_elm)) {
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm)
+ if (tmp_drvdata == ctx_drvdata) {
+ ret = -EBUSY;
+ goto fail;
+ }
+
+ ret = __enable_clocks(iommu_drvdata);
+ if (ret)
+ goto fail;
+
+ __program_context(iommu_drvdata->base, ctx_dev->num,
+ __pa(priv->pgtable));
+
+ __disable_clocks(iommu_drvdata);
+ list_add(&(ctx_drvdata->attached_elm), &priv->list_attached);
+ ret = __flush_iotlb(domain);
+
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static void msm_iommu_detach_dev(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_ctx_dev *ctx_dev;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+ priv = domain->priv;
+
+ if (!priv || !dev)
+ goto fail;
+
+ iommu_drvdata = dev_get_drvdata(dev->parent);
+ ctx_drvdata = dev_get_drvdata(dev);
+ ctx_dev = dev->platform_data;
+
+ if (!iommu_drvdata || !ctx_drvdata || !ctx_dev)
+ goto fail;
+
+ ret = __flush_iotlb(domain);
+ if (ret)
+ goto fail;
+
+ ret = __enable_clocks(iommu_drvdata);
+ if (ret)
+ goto fail;
+
+ __reset_context(iommu_drvdata->base, ctx_dev->num);
+ __disable_clocks(iommu_drvdata);
+ list_del_init(&ctx_drvdata->attached_elm);
+
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+}
+
+static int msm_iommu_map(struct iommu_domain *domain, unsigned long va,
+ phys_addr_t pa, int order, int prot)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ unsigned long *fl_pte;
+ unsigned long fl_offset;
+ unsigned long *sl_table;
+ unsigned long *sl_pte;
+ unsigned long sl_offset;
+ unsigned int pgprot;
+ size_t len = 0x1000UL << order;
+ int ret = 0, tex, sh;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0;
+ tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK];
+
+ if (tex < 0 || tex > NUM_TEX_CLASS - 1) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ priv = domain->priv;
+ if (!priv) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ fl_table = priv->pgtable;
+
+ if (len != SZ_16M && len != SZ_1M &&
+ len != SZ_64K && len != SZ_4K) {
+ pr_debug("Bad size: %d\n", len);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!fl_table) {
+ pr_debug("Null page table\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (len == SZ_16M || len == SZ_1M) {
+ pgprot = sh ? FL_SHARED : 0;
+ pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0;
+ pgprot |= tex & 0x02 ? FL_CACHEABLE : 0;
+ pgprot |= tex & 0x04 ? FL_TEX0 : 0;
+ } else {
+ pgprot = sh ? SL_SHARED : 0;
+ pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0;
+ pgprot |= tex & 0x02 ? SL_CACHEABLE : 0;
+ pgprot |= tex & 0x04 ? SL_TEX0 : 0;
+ }
+
+ fl_offset = FL_OFFSET(va); /* Upper 12 bits */
+ fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
+
+ if (len == SZ_16M) {
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION |
+ FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT |
+ FL_SHARED | FL_NG | pgprot;
+ }
+
+ if (len == SZ_1M)
+ *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | FL_NG |
+ FL_TYPE_SECT | FL_SHARED | pgprot;
+
+ /* Need a 2nd level table */
+ if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) {
+ unsigned long *sl;
+ sl = (unsigned long *) __get_free_pages(GFP_ATOMIC,
+ get_order(SZ_4K));
+
+ if (!sl) {
+ pr_debug("Could not allocate second level table\n");
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ memset(sl, 0, SZ_4K);
+ *fl_pte = ((((int)__pa(sl)) & FL_BASE_MASK) | FL_TYPE_TABLE);
+ }
+
+ sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+ sl_offset = SL_OFFSET(va);
+ sl_pte = sl_table + sl_offset;
+
+
+ if (len == SZ_4K)
+ *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | SL_NG |
+ SL_SHARED | SL_TYPE_SMALL | pgprot;
+
+ if (len == SZ_64K) {
+ int i;
+
+ for (i = 0; i < 16; i++)
+ *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 |
+ SL_NG | SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot;
+ }
+
+ ret = __flush_iotlb(domain);
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va,
+ int order)
+{
+ struct msm_priv *priv;
+ unsigned long flags;
+ unsigned long *fl_table;
+ unsigned long *fl_pte;
+ unsigned long fl_offset;
+ unsigned long *sl_table;
+ unsigned long *sl_pte;
+ unsigned long sl_offset;
+ size_t len = 0x1000UL << order;
+ int i, ret = 0;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+
+ if (!priv) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ fl_table = priv->pgtable;
+
+ if (len != SZ_16M && len != SZ_1M &&
+ len != SZ_64K && len != SZ_4K) {
+ pr_debug("Bad length: %d\n", len);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (!fl_table) {
+ pr_debug("Null page table\n");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ fl_offset = FL_OFFSET(va); /* Upper 12 bits */
+ fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */
+
+ if (*fl_pte == 0) {
+ pr_debug("First level PTE is 0\n");
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ /* Unmap supersection */
+ if (len == SZ_16M)
+ for (i = 0; i < 16; i++)
+ *(fl_pte+i) = 0;
+
+ if (len == SZ_1M)
+ *fl_pte = 0;
+
+ sl_table = (unsigned long *) __va(((*fl_pte) & FL_BASE_MASK));
+ sl_offset = SL_OFFSET(va);
+ sl_pte = sl_table + sl_offset;
+
+ if (len == SZ_64K) {
+ for (i = 0; i < 16; i++)
+ *(sl_pte+i) = 0;
+ }
+
+ if (len == SZ_4K)
+ *sl_pte = 0;
+
+ if (len == SZ_4K || len == SZ_64K) {
+ int used = 0;
+
+ for (i = 0; i < NUM_SL_PTE; i++)
+ if (sl_table[i])
+ used = 1;
+ if (!used) {
+ free_page((unsigned long)sl_table);
+ *fl_pte = 0;
+ }
+ }
+
+ ret = __flush_iotlb(domain);
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain,
+ unsigned long va)
+{
+ struct msm_priv *priv;
+ struct msm_iommu_drvdata *iommu_drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata;
+ unsigned int par;
+ unsigned long flags;
+ void __iomem *base;
+ phys_addr_t ret = 0;
+ int ctx;
+
+ spin_lock_irqsave(&msm_iommu_lock, flags);
+
+ priv = domain->priv;
+ if (list_empty(&priv->list_attached))
+ goto fail;
+
+ ctx_drvdata = list_entry(priv->list_attached.next,
+ struct msm_iommu_ctx_drvdata, attached_elm);
+ iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent);
+
+ base = iommu_drvdata->base;
+ ctx = ctx_drvdata->num;
+
+ ret = __enable_clocks(iommu_drvdata);
+ if (ret)
+ goto fail;
+
+ /* Invalidate context TLB */
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_V2PPR(base, ctx, va & V2Pxx_VA);
+
+ par = GET_PAR(base, ctx);
+
+ /* We are dealing with a supersection */
+ if (GET_NOFAULT_SS(base, ctx))
+ ret = (par & 0xFF000000) | (va & 0x00FFFFFF);
+ else /* Upper 20 bits from PAR, lower 12 from VA */
+ ret = (par & 0xFFFFF000) | (va & 0x00000FFF);
+
+ if (GET_FAULT(base, ctx))
+ ret = 0;
+
+ __disable_clocks(iommu_drvdata);
+fail:
+ spin_unlock_irqrestore(&msm_iommu_lock, flags);
+ return ret;
+}
+
+static int msm_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return 0;
+}
+
+static void print_ctx_regs(void __iomem *base, int ctx)
+{
+ unsigned int fsr = GET_FSR(base, ctx);
+ pr_err("FAR = %08x PAR = %08x\n",
+ GET_FAR(base, ctx), GET_PAR(base, ctx));
+ pr_err("FSR = %08x [%s%s%s%s%s%s%s%s%s%s]\n", fsr,
+ (fsr & 0x02) ? "TF " : "",
+ (fsr & 0x04) ? "AFF " : "",
+ (fsr & 0x08) ? "APF " : "",
+ (fsr & 0x10) ? "TLBMF " : "",
+ (fsr & 0x20) ? "HTWDEEF " : "",
+ (fsr & 0x40) ? "HTWSEEF " : "",
+ (fsr & 0x80) ? "MHF " : "",
+ (fsr & 0x10000) ? "SL " : "",
+ (fsr & 0x40000000) ? "SS " : "",
+ (fsr & 0x80000000) ? "MULTI " : "");
+
+ pr_err("FSYNR0 = %08x FSYNR1 = %08x\n",
+ GET_FSYNR0(base, ctx), GET_FSYNR1(base, ctx));
+ pr_err("TTBR0 = %08x TTBR1 = %08x\n",
+ GET_TTBR0(base, ctx), GET_TTBR1(base, ctx));
+ pr_err("SCTLR = %08x ACTLR = %08x\n",
+ GET_SCTLR(base, ctx), GET_ACTLR(base, ctx));
+ pr_err("PRRR = %08x NMRR = %08x\n",
+ GET_PRRR(base, ctx), GET_NMRR(base, ctx));
+}
+
+irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
+{
+ struct msm_iommu_drvdata *drvdata = dev_id;
+ void __iomem *base;
+ unsigned int fsr;
+ int i, ret;
+
+ spin_lock(&msm_iommu_lock);
+
+ if (!drvdata) {
+ pr_err("Invalid device ID in context interrupt handler\n");
+ goto fail;
+ }
+
+ base = drvdata->base;
+
+ pr_err("Unexpected IOMMU page fault!\n");
+ pr_err("base = %08x\n", (unsigned int) base);
+
+ ret = __enable_clocks(drvdata);
+ if (ret)
+ goto fail;
+
+ for (i = 0; i < drvdata->ncb; i++) {
+ fsr = GET_FSR(base, i);
+ if (fsr) {
+ pr_err("Fault occurred in context %d.\n", i);
+ pr_err("Interesting registers:\n");
+ print_ctx_regs(base, i);
+ SET_FSR(base, i, 0x4000000F);
+ }
+ }
+ __disable_clocks(drvdata);
+fail:
+ spin_unlock(&msm_iommu_lock);
+ return 0;
+}
+
+static struct iommu_ops msm_iommu_ops = {
+ .domain_init = msm_iommu_domain_init,
+ .domain_destroy = msm_iommu_domain_destroy,
+ .attach_dev = msm_iommu_attach_dev,
+ .detach_dev = msm_iommu_detach_dev,
+ .map = msm_iommu_map,
+ .unmap = msm_iommu_unmap,
+ .iova_to_phys = msm_iommu_iova_to_phys,
+ .domain_has_cap = msm_iommu_domain_has_cap
+};
+
+static int __init get_tex_class(int icp, int ocp, int mt, int nos)
+{
+ int i = 0;
+ unsigned int prrr = 0;
+ unsigned int nmrr = 0;
+ int c_icp, c_ocp, c_mt, c_nos;
+
+ RCP15_PRRR(prrr);
+ RCP15_NMRR(nmrr);
+
+ for (i = 0; i < NUM_TEX_CLASS; i++) {
+ c_nos = PRRR_NOS(prrr, i);
+ c_mt = PRRR_MT(prrr, i);
+ c_icp = NMRR_ICP(nmrr, i);
+ c_ocp = NMRR_OCP(nmrr, i);
+
+ if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+static void __init setup_iommu_tex_classes(void)
+{
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] =
+ get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] =
+ get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] =
+ get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1);
+
+ msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] =
+ get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1);
+}
+
+static int __init msm_iommu_init(void)
+{
+ setup_iommu_tex_classes();
+ register_iommu(&msm_iommu_ops);
+ return 0;
+}
+
+subsys_initcall(msm_iommu_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c
new file mode 100644
index 00000000..8e8fb079
--- /dev/null
+++ b/arch/arm/mach-msm/iommu_dev.c
@@ -0,0 +1,422 @@
+/* Copyright (c) 2010-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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/iommu.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <mach/iommu_hw-8xxx.h>
+#include <mach/iommu.h>
+#include <mach/clk.h>
+
+struct iommu_ctx_iter_data {
+ /* input */
+ const char *name;
+
+ /* output */
+ struct device *dev;
+};
+
+static struct platform_device *msm_iommu_root_dev;
+
+static int each_iommu_ctx(struct device *dev, void *data)
+{
+ struct iommu_ctx_iter_data *res = data;
+ struct msm_iommu_ctx_dev *c = dev->platform_data;
+
+ if (!res || !c || !c->name || !res->name)
+ return -EINVAL;
+
+ if (!strcmp(res->name, c->name)) {
+ res->dev = dev;
+ return 1;
+ }
+ return 0;
+}
+
+static int each_iommu(struct device *dev, void *data)
+{
+ return device_for_each_child(dev, data, each_iommu_ctx);
+}
+
+struct device *msm_iommu_get_ctx(const char *ctx_name)
+{
+ struct iommu_ctx_iter_data r;
+ int found;
+
+ if (!msm_iommu_root_dev) {
+ pr_err("No root IOMMU device.\n");
+ goto fail;
+ }
+
+ r.name = ctx_name;
+ found = device_for_each_child(&msm_iommu_root_dev->dev, &r, each_iommu);
+
+ if (!found) {
+ pr_err("Could not find context <%s>\n", ctx_name);
+ goto fail;
+ }
+
+ return r.dev;
+fail:
+ return NULL;
+}
+EXPORT_SYMBOL(msm_iommu_get_ctx);
+
+static void msm_iommu_reset(void __iomem *base, int ncb)
+{
+ int ctx;
+
+ SET_RPUE(base, 0);
+ SET_RPUEIE(base, 0);
+ SET_ESRRESTORE(base, 0);
+ SET_TBE(base, 0);
+ SET_CR(base, 0);
+ SET_SPDMBE(base, 0);
+ SET_TESTBUSCR(base, 0);
+ SET_TLBRSW(base, 0);
+ SET_GLOBAL_TLBIALL(base, 0);
+ SET_RPU_ACR(base, 0);
+ SET_TLBLKCRWE(base, 1);
+
+ for (ctx = 0; ctx < ncb; ctx++) {
+ SET_BPRCOSH(base, ctx, 0);
+ SET_BPRCISH(base, ctx, 0);
+ SET_BPRCNSH(base, ctx, 0);
+ SET_BPSHCFG(base, ctx, 0);
+ SET_BPMTCFG(base, ctx, 0);
+ SET_ACTLR(base, ctx, 0);
+ SET_SCTLR(base, ctx, 0);
+ SET_FSRRESTORE(base, ctx, 0);
+ SET_TTBR0(base, ctx, 0);
+ SET_TTBR1(base, ctx, 0);
+ SET_TTBCR(base, ctx, 0);
+ SET_BFBCR(base, ctx, 0);
+ SET_PAR(base, ctx, 0);
+ SET_FAR(base, ctx, 0);
+ SET_CTX_TLBIALL(base, ctx, 0);
+ SET_TLBFLPTER(base, ctx, 0);
+ SET_TLBSLPTER(base, ctx, 0);
+ SET_TLBLKCR(base, ctx, 0);
+ SET_PRRR(base, ctx, 0);
+ SET_NMRR(base, ctx, 0);
+ SET_CONTEXTIDR(base, ctx, 0);
+ }
+}
+
+static int msm_iommu_probe(struct platform_device *pdev)
+{
+ struct resource *r, *r2;
+ struct clk *iommu_clk;
+ struct clk *iommu_pclk;
+ struct msm_iommu_drvdata *drvdata;
+ struct msm_iommu_dev *iommu_dev = pdev->dev.platform_data;
+ void __iomem *regs_base;
+ resource_size_t len;
+ int ret, irq, par;
+
+ if (pdev->id == -1) {
+ msm_iommu_root_dev = pdev;
+ return 0;
+ }
+
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+
+ if (!drvdata) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ if (!iommu_dev) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ iommu_pclk = clk_get(NULL, "smmu_pclk");
+ if (IS_ERR(iommu_pclk)) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ ret = clk_enable(iommu_pclk);
+ if (ret)
+ goto fail_enable;
+
+ iommu_clk = clk_get(&pdev->dev, "iommu_clk");
+
+ if (!IS_ERR(iommu_clk)) {
+ if (clk_get_rate(iommu_clk) == 0)
+ clk_set_min_rate(iommu_clk, 1);
+
+ ret = clk_enable(iommu_clk);
+ if (ret) {
+ clk_put(iommu_clk);
+ goto fail_pclk;
+ }
+ } else
+ iommu_clk = NULL;
+
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "physbase");
+
+ if (!r) {
+ ret = -ENODEV;
+ goto fail_clk;
+ }
+
+ len = resource_size(r);
+
+ r2 = request_mem_region(r->start, len, r->name);
+ if (!r2) {
+ pr_err("Could not request memory region: start=%p, len=%d\n",
+ (void *) r->start, len);
+ ret = -EBUSY;
+ goto fail_clk;
+ }
+
+ regs_base = ioremap(r2->start, len);
+
+ if (!regs_base) {
+ pr_err("Could not ioremap: start=%p, len=%d\n",
+ (void *) r2->start, len);
+ ret = -EBUSY;
+ goto fail_mem;
+ }
+
+ irq = platform_get_irq_byname(pdev, "secure_irq");
+ if (irq < 0) {
+ ret = -ENODEV;
+ goto fail_io;
+ }
+
+ msm_iommu_reset(regs_base, iommu_dev->ncb);
+
+ SET_M(regs_base, 0, 1);
+ SET_PAR(regs_base, 0, 0);
+ SET_V2PCFG(regs_base, 0, 1);
+ SET_V2PPR(regs_base, 0, 0);
+ par = GET_PAR(regs_base, 0);
+ SET_V2PCFG(regs_base, 0, 0);
+ SET_M(regs_base, 0, 0);
+
+ if (!par) {
+ pr_err("%s: Invalid PAR value detected\n", iommu_dev->name);
+ ret = -ENODEV;
+ goto fail_io;
+ }
+
+ ret = request_irq(irq, msm_iommu_fault_handler, 0,
+ "msm_iommu_secure_irpt_handler", drvdata);
+ if (ret) {
+ pr_err("Request IRQ %d failed with ret=%d\n", irq, ret);
+ goto fail_io;
+ }
+
+
+ drvdata->pclk = iommu_pclk;
+ drvdata->clk = iommu_clk;
+ drvdata->base = regs_base;
+ drvdata->irq = irq;
+ drvdata->ncb = iommu_dev->ncb;
+
+ pr_info("device %s mapped at %p, irq %d with %d ctx banks\n",
+ iommu_dev->name, regs_base, irq, iommu_dev->ncb);
+
+ platform_set_drvdata(pdev, drvdata);
+
+ if (iommu_clk)
+ clk_disable(iommu_clk);
+
+ clk_disable(iommu_pclk);
+
+ return 0;
+fail_io:
+ iounmap(regs_base);
+fail_mem:
+ release_mem_region(r->start, len);
+fail_clk:
+ if (iommu_clk) {
+ clk_disable(iommu_clk);
+ clk_put(iommu_clk);
+ }
+fail_pclk:
+ clk_disable(iommu_pclk);
+fail_enable:
+ clk_put(iommu_pclk);
+fail:
+ kfree(drvdata);
+ return ret;
+}
+
+static int msm_iommu_remove(struct platform_device *pdev)
+{
+ struct msm_iommu_drvdata *drv = NULL;
+
+ drv = platform_get_drvdata(pdev);
+ if (drv) {
+ if (drv->clk)
+ clk_put(drv->clk);
+ clk_put(drv->pclk);
+ memset(drv, 0, sizeof(*drv));
+ kfree(drv);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return 0;
+}
+
+static int msm_iommu_ctx_probe(struct platform_device *pdev)
+{
+ struct msm_iommu_ctx_dev *c = pdev->dev.platform_data;
+ struct msm_iommu_drvdata *drvdata;
+ struct msm_iommu_ctx_drvdata *ctx_drvdata = NULL;
+ int i, ret;
+ if (!c || !pdev->dev.parent) {
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ drvdata = dev_get_drvdata(pdev->dev.parent);
+
+ if (!drvdata) {
+ ret = -ENODEV;
+ goto fail;
+ }
+
+ ctx_drvdata = kzalloc(sizeof(*ctx_drvdata), GFP_KERNEL);
+ if (!ctx_drvdata) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ ctx_drvdata->num = c->num;
+ ctx_drvdata->pdev = pdev;
+
+ INIT_LIST_HEAD(&ctx_drvdata->attached_elm);
+ platform_set_drvdata(pdev, ctx_drvdata);
+
+ ret = clk_enable(drvdata->pclk);
+ if (ret)
+ goto fail;
+
+ if (drvdata->clk) {
+ ret = clk_enable(drvdata->clk);
+ if (ret) {
+ clk_disable(drvdata->pclk);
+ goto fail;
+ }
+ }
+
+ /* Program the M2V tables for this context */
+ for (i = 0; i < MAX_NUM_MIDS; i++) {
+ int mid = c->mids[i];
+ if (mid == -1)
+ break;
+
+ SET_M2VCBR_N(drvdata->base, mid, 0);
+ SET_CBACR_N(drvdata->base, c->num, 0);
+
+ /* Set VMID = 0 */
+ SET_VMID(drvdata->base, mid, 0);
+
+ /* Set the context number for that MID to this context */
+ SET_CBNDX(drvdata->base, mid, c->num);
+
+ /* Set MID associated with this context bank to 0*/
+ SET_CBVMID(drvdata->base, c->num, 0);
+
+ /* Set the ASID for TLB tagging for this context */
+ SET_CONTEXTIDR_ASID(drvdata->base, c->num, c->num);
+
+ /* Set security bit override to be Non-secure */
+ SET_NSCFG(drvdata->base, mid, 3);
+ }
+
+ if (drvdata->clk)
+ clk_disable(drvdata->clk);
+ clk_disable(drvdata->pclk);
+
+ dev_info(&pdev->dev, "context %s using bank %d\n", c->name, c->num);
+ return 0;
+fail:
+ kfree(ctx_drvdata);
+ return ret;
+}
+
+static int msm_iommu_ctx_remove(struct platform_device *pdev)
+{
+ struct msm_iommu_ctx_drvdata *drv = NULL;
+ drv = platform_get_drvdata(pdev);
+ if (drv) {
+ memset(drv, 0, sizeof(struct msm_iommu_ctx_drvdata));
+ kfree(drv);
+ platform_set_drvdata(pdev, NULL);
+ }
+ return 0;
+}
+
+static struct platform_driver msm_iommu_driver = {
+ .driver = {
+ .name = "msm_iommu",
+ },
+ .probe = msm_iommu_probe,
+ .remove = msm_iommu_remove,
+};
+
+static struct platform_driver msm_iommu_ctx_driver = {
+ .driver = {
+ .name = "msm_iommu_ctx",
+ },
+ .probe = msm_iommu_ctx_probe,
+ .remove = msm_iommu_ctx_remove,
+};
+
+static int __init msm_iommu_driver_init(void)
+{
+ int ret;
+ ret = platform_driver_register(&msm_iommu_driver);
+ if (ret != 0) {
+ pr_err("Failed to register IOMMU driver\n");
+ goto error;
+ }
+
+ ret = platform_driver_register(&msm_iommu_ctx_driver);
+ if (ret != 0) {
+ pr_err("Failed to register IOMMU context driver\n");
+ goto error;
+ }
+
+error:
+ return ret;
+}
+
+static void __exit msm_iommu_driver_exit(void)
+{
+ platform_driver_unregister(&msm_iommu_ctx_driver);
+ platform_driver_unregister(&msm_iommu_driver);
+}
+
+subsys_initcall(msm_iommu_driver_init);
+module_exit(msm_iommu_driver_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stepan Moskovchenko <stepanm@codeaurora.org>");
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
new file mode 100644
index 00000000..1b54f807
--- /dev/null
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+enum {
+ IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0,
+ IRQ_DEBUG_SLEEP_INT = 1U << 1,
+ IRQ_DEBUG_SLEEP_ABORT = 1U << 2,
+ IRQ_DEBUG_SLEEP = 1U << 3,
+ IRQ_DEBUG_SLEEP_REQUEST = 1U << 4,
+};
+static int msm_irq_debug_mask;
+module_param_named(debug_mask, msm_irq_debug_mask, int,
+ S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define VIC_REG(off) (MSM_VIC_BASE + (off))
+#define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4)
+#define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3)
+
+#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT2 VIC_REG(0x0008) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT3 VIC_REG(0x000C) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_EN0 VIC_REG(0x0010)
+#define VIC_INT_EN1 VIC_REG(0x0014)
+#define VIC_INT_EN2 VIC_REG(0x0018)
+#define VIC_INT_EN3 VIC_REG(0x001C)
+#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
+#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
+#define VIC_INT_ENCLEAR2 VIC_REG(0x0028)
+#define VIC_INT_ENCLEAR3 VIC_REG(0x002C)
+#define VIC_INT_ENSET0 VIC_REG(0x0030)
+#define VIC_INT_ENSET1 VIC_REG(0x0034)
+#define VIC_INT_ENSET2 VIC_REG(0x0038)
+#define VIC_INT_ENSET3 VIC_REG(0x003C)
+#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_TYPE2 VIC_REG(0x0048) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_TYPE3 VIC_REG(0x004C) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY2 VIC_REG(0x0058) /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY3 VIC_REG(0x005C) /* 1: NEG, 0: POS */
+#define VIC_NO_PEND_VAL VIC_REG(0x0060)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064)
+#define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */
+#define VIC_CONFIG VIC_REG(0x006C) /* 1: USE SC VIC */
+#else
+#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
+#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
+#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
+#endif
+
+#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
+#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
+#define VIC_IRQ_STATUS2 VIC_REG(0x0088)
+#define VIC_IRQ_STATUS3 VIC_REG(0x008C)
+#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
+#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
+#define VIC_FIQ_STATUS2 VIC_REG(0x0098)
+#define VIC_FIQ_STATUS3 VIC_REG(0x009C)
+#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
+#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
+#define VIC_RAW_STATUS2 VIC_REG(0x00A8)
+#define VIC_RAW_STATUS3 VIC_REG(0x00AC)
+#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
+#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
+#define VIC_INT_CLEAR2 VIC_REG(0x00B8)
+#define VIC_INT_CLEAR3 VIC_REG(0x00BC)
+#define VIC_SOFTINT0 VIC_REG(0x00C0)
+#define VIC_SOFTINT1 VIC_REG(0x00C4)
+#define VIC_SOFTINT2 VIC_REG(0x00C8)
+#define VIC_SOFTINT3 VIC_REG(0x00CC)
+#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
+#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
+#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
+
+#if defined(CONFIG_ARCH_MSM_SCORPION)
+#define VIC_FIQ_VEC_RD VIC_REG(0x00DC)
+#define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0)
+#define VIC_FIQ_VEC_WR VIC_REG(0x00E4)
+#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8)
+#define VIC_IRQ_IN_STACK VIC_REG(0x00EC)
+#define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0)
+#define VIC_FIQ_IN_STACK VIC_REG(0x00F4)
+#define VIC_TEST_BUS_SEL VIC_REG(0x00F8)
+#define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC)
+#else
+#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
+#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
+#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
+#endif
+
+#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
+#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define VIC_NUM_REGS 4
+#else
+#define VIC_NUM_REGS 2
+#endif
+
+#if VIC_NUM_REGS == 2
+#define DPRINT_REGS(base_reg, format, ...) \
+ printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
+ readl(base_reg ## 0), readl(base_reg ## 1))
+#define DPRINT_ARRAY(array, format, ...) \
+ printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \
+ array[0], array[1])
+#elif VIC_NUM_REGS == 4
+#define DPRINT_REGS(base_reg, format, ...) \
+ printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
+ readl(base_reg ## 0), readl(base_reg ## 1), \
+ readl(base_reg ## 2), readl(base_reg ## 3))
+#define DPRINT_ARRAY(array, format, ...) \
+ printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \
+ array[0], array[1], \
+ array[2], array[3])
+#else
+#error "VIC_NUM_REGS set to illegal value"
+#endif
+
+static uint32_t msm_irq_smsm_wake_enable[2];
+static struct {
+ uint32_t int_en[2];
+ uint32_t int_type;
+ uint32_t int_polarity;
+ uint32_t int_select;
+} msm_irq_shadow_reg[VIC_NUM_REGS];
+static uint32_t msm_irq_idle_disable[VIC_NUM_REGS];
+
+#define SMSM_FAKE_IRQ (0xff)
+static uint8_t msm_irq_to_smsm[NR_IRQS] = {
+ [INT_MDDI_EXT] = 1,
+ [INT_MDDI_PRI] = 2,
+ [INT_MDDI_CLIENT] = 3,
+ [INT_USB_OTG] = 4,
+
+ [INT_PWB_I2C] = 5,
+ [INT_SDC1_0] = 6,
+ [INT_SDC1_1] = 7,
+ [INT_SDC2_0] = 8,
+
+ [INT_SDC2_1] = 9,
+ [INT_ADSP_A9_A11] = 10,
+ [INT_UART1] = 11,
+ [INT_UART2] = 12,
+
+ [INT_UART3] = 13,
+ [INT_UART1_RX] = 14,
+ [INT_UART2_RX] = 15,
+ [INT_UART3_RX] = 16,
+
+ [INT_UART1DM_IRQ] = 17,
+ [INT_UART1DM_RX] = 18,
+ [INT_KEYSENSE] = 19,
+#if !defined(CONFIG_ARCH_MSM7X30)
+ [INT_AD_HSSD] = 20,
+#endif
+
+ [INT_NAND_WR_ER_DONE] = 21,
+ [INT_NAND_OP_DONE] = 22,
+ [INT_TCHSCRN1] = 23,
+ [INT_TCHSCRN2] = 24,
+
+ [INT_TCHSCRN_SSBI] = 25,
+ [INT_USB_HS] = 26,
+ [INT_UART2DM_RX] = 27,
+ [INT_UART2DM_IRQ] = 28,
+
+ [INT_SDC4_1] = 29,
+ [INT_SDC4_0] = 30,
+ [INT_SDC3_1] = 31,
+ [INT_SDC3_0] = 32,
+
+ /* fake wakeup interrupts */
+ [INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
+ [INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
+ [INT_A9_M2A_0] = SMSM_FAKE_IRQ,
+ [INT_A9_M2A_1] = SMSM_FAKE_IRQ,
+ [INT_A9_M2A_5] = SMSM_FAKE_IRQ,
+ [INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
+ [INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
+ [INT_ADSP_A11] = SMSM_FAKE_IRQ,
+#ifdef CONFIG_ARCH_QSD8X50
+ [INT_SIRC_0] = SMSM_FAKE_IRQ,
+ [INT_SIRC_1] = SMSM_FAKE_IRQ,
+#endif
+};
+
+static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val)
+{
+ int i;
+
+ for (i = 0; i < VIC_NUM_REGS; i++)
+ writel(val, base + (i * 4));
+}
+
+static void msm_irq_ack(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, d->irq);
+ writel(1 << (d->irq & 31), reg);
+}
+
+static void msm_irq_mask(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, d->irq);
+ unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
+ uint32_t mask = 1UL << (d->irq & 31);
+ int smsm_irq = msm_irq_to_smsm[d->irq];
+
+ msm_irq_shadow_reg[index].int_en[0] &= ~mask;
+ writel(mask, reg);
+ if (smsm_irq == 0)
+ msm_irq_idle_disable[index] &= ~mask;
+ else {
+ mask = 1UL << (smsm_irq - 1);
+ msm_irq_smsm_wake_enable[0] &= ~mask;
+ }
+}
+
+static void msm_irq_unmask(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, d->irq);
+ unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
+ uint32_t mask = 1UL << (d->irq & 31);
+ int smsm_irq = msm_irq_to_smsm[d->irq];
+
+ msm_irq_shadow_reg[index].int_en[0] |= mask;
+ writel(mask, reg);
+
+ if (smsm_irq == 0)
+ msm_irq_idle_disable[index] |= mask;
+ else {
+ mask = 1UL << (smsm_irq - 1);
+ msm_irq_smsm_wake_enable[0] |= mask;
+ }
+}
+
+static int msm_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
+ uint32_t mask = 1UL << (d->irq & 31);
+ int smsm_irq = msm_irq_to_smsm[d->irq];
+
+ if (smsm_irq == 0) {
+ printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", d->irq);
+ return -EINVAL;
+ }
+ if (on)
+ msm_irq_shadow_reg[index].int_en[1] |= mask;
+ else
+ msm_irq_shadow_reg[index].int_en[1] &= ~mask;
+
+ if (smsm_irq == SMSM_FAKE_IRQ)
+ return 0;
+
+ mask = 1UL << (smsm_irq - 1);
+ if (on)
+ msm_irq_smsm_wake_enable[1] |= mask;
+ else
+ msm_irq_smsm_wake_enable[1] &= ~mask;
+ return 0;
+}
+
+static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, d->irq);
+ void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, d->irq);
+ unsigned index = VIC_INT_TO_REG_INDEX(d->irq);
+ int b = 1 << (d->irq & 31);
+ uint32_t polarity;
+ uint32_t type;
+
+ polarity = msm_irq_shadow_reg[index].int_polarity;
+ if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+ polarity |= b;
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+ polarity &= ~b;
+ writel(polarity, preg);
+ msm_irq_shadow_reg[index].int_polarity = polarity;
+
+ type = msm_irq_shadow_reg[index].int_type;
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+ type |= b;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ }
+ if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
+ type &= ~b;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ }
+ writel(type, treg);
+ msm_irq_shadow_reg[index].int_type = type;
+ return 0;
+}
+
+static struct irq_chip msm_irq_chip = {
+ .name = "msm",
+ .irq_disable = msm_irq_mask,
+ .irq_ack = msm_irq_ack,
+ .irq_mask = msm_irq_mask,
+ .irq_unmask = msm_irq_unmask,
+ .irq_set_wake = msm_irq_set_wake,
+ .irq_set_type = msm_irq_set_type,
+};
+
+void __init msm_init_irq(void)
+{
+ unsigned n;
+
+ /* select level interrupts */
+ msm_irq_write_all_regs(VIC_INT_TYPE0, 0);
+
+ /* select highlevel interrupts */
+ msm_irq_write_all_regs(VIC_INT_POLARITY0, 0);
+
+ /* select IRQ for all INTs */
+ msm_irq_write_all_regs(VIC_INT_SELECT0, 0);
+
+ /* disable all INTs */
+ msm_irq_write_all_regs(VIC_INT_EN0, 0);
+
+ /* don't use vic */
+ writel(0, VIC_CONFIG);
+
+ /* enable interrupt controller */
+ writel(3, VIC_INT_MASTEREN);
+
+ for (n = 0; n < NR_MSM_IRQS; n++) {
+ irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
+ set_irq_flags(n, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
new file mode 100644
index 00000000..ea514be3
--- /dev/null
+++ b/arch/arm/mach-msm/irq.c
@@ -0,0 +1,151 @@
+/* linux/arch/arm/mach-msm/irq.c
+ *
+ * Copyright (C) 2007 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/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <mach/msm_iomap.h>
+
+#define VIC_REG(off) (MSM_VIC_BASE + (off))
+
+#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */
+#define VIC_INT_EN0 VIC_REG(0x0010)
+#define VIC_INT_EN1 VIC_REG(0x0014)
+#define VIC_INT_ENCLEAR0 VIC_REG(0x0020)
+#define VIC_INT_ENCLEAR1 VIC_REG(0x0024)
+#define VIC_INT_ENSET0 VIC_REG(0x0030)
+#define VIC_INT_ENSET1 VIC_REG(0x0034)
+#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */
+#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */
+#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */
+#define VIC_NO_PEND_VAL VIC_REG(0x0060)
+#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */
+#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */
+#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */
+#define VIC_IRQ_STATUS0 VIC_REG(0x0080)
+#define VIC_IRQ_STATUS1 VIC_REG(0x0084)
+#define VIC_FIQ_STATUS0 VIC_REG(0x0090)
+#define VIC_FIQ_STATUS1 VIC_REG(0x0094)
+#define VIC_RAW_STATUS0 VIC_REG(0x00A0)
+#define VIC_RAW_STATUS1 VIC_REG(0x00A4)
+#define VIC_INT_CLEAR0 VIC_REG(0x00B0)
+#define VIC_INT_CLEAR1 VIC_REG(0x00B4)
+#define VIC_SOFTINT0 VIC_REG(0x00C0)
+#define VIC_SOFTINT1 VIC_REG(0x00C4)
+#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */
+#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */
+#define VIC_IRQ_VEC_WR VIC_REG(0x00D8)
+#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0)
+#define VIC_IRQ_IN_STACK VIC_REG(0x00E4)
+#define VIC_TEST_BUS_SEL VIC_REG(0x00E8)
+
+#define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4))
+#define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4))
+
+static void msm_irq_ack(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_CLEAR0 + ((d->irq & 32) ? 4 : 0);
+ writel(1 << (d->irq & 31), reg);
+}
+
+static void msm_irq_mask(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_ENCLEAR0 + ((d->irq & 32) ? 4 : 0);
+ writel(1 << (d->irq & 31), reg);
+}
+
+static void msm_irq_unmask(struct irq_data *d)
+{
+ void __iomem *reg = VIC_INT_ENSET0 + ((d->irq & 32) ? 4 : 0);
+ writel(1 << (d->irq & 31), reg);
+}
+
+static int msm_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ return -EINVAL;
+}
+
+static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ void __iomem *treg = VIC_INT_TYPE0 + ((d->irq & 32) ? 4 : 0);
+ void __iomem *preg = VIC_INT_POLARITY0 + ((d->irq & 32) ? 4 : 0);
+ int b = 1 << (d->irq & 31);
+
+ if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+ writel(readl(preg) | b, preg);
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH))
+ writel(readl(preg) & (~b), preg);
+
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+ writel(readl(treg) | b, treg);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ }
+ if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
+ writel(readl(treg) & (~b), treg);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ }
+ return 0;
+}
+
+static struct irq_chip msm_irq_chip = {
+ .name = "msm",
+ .irq_ack = msm_irq_ack,
+ .irq_mask = msm_irq_mask,
+ .irq_unmask = msm_irq_unmask,
+ .irq_set_wake = msm_irq_set_wake,
+ .irq_set_type = msm_irq_set_type,
+};
+
+void __init msm_init_irq(void)
+{
+ unsigned n;
+
+ /* select level interrupts */
+ writel(0, VIC_INT_TYPE0);
+ writel(0, VIC_INT_TYPE1);
+
+ /* select highlevel interrupts */
+ writel(0, VIC_INT_POLARITY0);
+ writel(0, VIC_INT_POLARITY1);
+
+ /* select IRQ for all INTs */
+ writel(0, VIC_INT_SELECT0);
+ writel(0, VIC_INT_SELECT1);
+
+ /* disable all INTs */
+ writel(0, VIC_INT_EN0);
+ writel(0, VIC_INT_EN1);
+
+ /* don't use 1136 vic */
+ writel(0, VIC_CONFIG);
+
+ /* enable interrupt controller */
+ writel(1, VIC_INT_MASTEREN);
+
+ for (n = 0; n < NR_MSM_IRQS; n++) {
+ irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
+ set_irq_flags(n, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c
new file mode 100644
index 00000000..1e243f46
--- /dev/null
+++ b/arch/arm/mach-msm/last_radio_log.c
@@ -0,0 +1,83 @@
+/* arch/arm/mach-msm/last_radio_log.c
+ *
+ * Extract the log from a modem crash though SMEM
+ *
+ * Copyright (C) 2007 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/module.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+
+#include "smd_private.h"
+
+static void *radio_log_base;
+static size_t radio_log_size;
+
+extern void *smem_item(unsigned id, unsigned *size);
+
+static ssize_t last_radio_log_read(struct file *file, char __user *buf,
+ size_t len, loff_t *offset)
+{
+ loff_t pos = *offset;
+ ssize_t count;
+
+ if (pos >= radio_log_size)
+ return 0;
+
+ count = min(len, (size_t)(radio_log_size - pos));
+ if (copy_to_user(buf, radio_log_base + pos, count)) {
+ pr_err("%s: copy to user failed\n", __func__);
+ return -EFAULT;
+ }
+
+ *offset += count;
+ return count;
+}
+
+static struct file_operations last_radio_log_fops = {
+ .read = last_radio_log_read,
+ .llseek = default_llseek,
+};
+
+void msm_init_last_radio_log(struct module *owner)
+{
+ struct proc_dir_entry *entry;
+
+ if (last_radio_log_fops.owner) {
+ pr_err("%s: already claimed\n", __func__);
+ return;
+ }
+
+ radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size);
+ if (!radio_log_base) {
+ pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__);
+ return;
+ }
+
+ entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL);
+ if (!entry) {
+ pr_err("%s: could not create proc entry for radio log\n",
+ __func__);
+ return;
+ }
+
+ pr_err("%s: last radio log is %d bytes long\n", __func__,
+ radio_log_size);
+ last_radio_log_fops.owner = owner;
+ entry->proc_fops = &last_radio_log_fops;
+ entry->size = radio_log_size;
+}
+EXPORT_SYMBOL(msm_init_last_radio_log);
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
new file mode 100644
index 00000000..2034098c
--- /dev/null
+++ b/arch/arm/mach-msm/platsmp.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/hardware/gic.h>
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+
+#include <mach/msm_iomap.h>
+
+#include "scm-boot.h"
+
+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0
+#define SCSS_CPU1CORE_RESET 0xD80
+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64
+
+/* Mask for edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */
+#define GIC_PPI_EDGE_MASK 0xFFFFD7FF
+
+extern void msm_secondary_startup(void);
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen".
+ */
+volatile int pen_release = -1;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /* Configure edge-triggered PPIs */
+ writel(GIC_PPI_EDGE_MASK, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4);
+
+ /*
+ * 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);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ pen_release = -1;
+ smp_wmb();
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+static __cpuinit void prepare_cold_cpu(unsigned int cpu)
+{
+ int ret;
+ ret = scm_set_boot_addr(virt_to_phys(msm_secondary_startup),
+ SCM_FLAG_COLDBOOT_CPU1);
+ if (ret == 0) {
+ void *sc1_base_ptr;
+ sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2);
+ if (sc1_base_ptr) {
+ writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL);
+ writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET);
+ writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP);
+ iounmap(sc1_base_ptr);
+ }
+ } else
+ printk(KERN_DEBUG "Failed to set secondary core boot "
+ "address\n");
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+ static int cold_boot_done;
+
+ /* Only need to bring cpu out of reset this way once */
+ if (cold_boot_done == false) {
+ prepare_cold_cpu(cpu);
+ cold_boot_done = true;
+ }
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ *
+ * Note that "pen_release" is the hardware CPU ID, whereas
+ * "cpu" is Linux's internal ID.
+ */
+ pen_release = cpu;
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * 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();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system. The msm8x60
+ * does not support the ARM SCU, so just set the possible cpu mask to
+ * NR_CPUS.
+ */
+void __init smp_init_cpus(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < NR_CPUS; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+}
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
new file mode 100644
index 00000000..67e701c7
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -0,0 +1,130 @@
+/* arch/arm/mach-msm/proc_comm.c
+ *
+ * Copyright (C) 2007-2008 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <mach/msm_iomap.h>
+#include <mach/system.h>
+
+#include "proc_comm.h"
+
+static inline void msm_a2m_int(uint32_t irq)
+{
+#if defined(CONFIG_ARCH_MSM7X30)
+ writel(1 << irq, MSM_GCC_BASE + 0x8);
+#else
+ writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+#endif
+}
+
+static inline void notify_other_proc_comm(void)
+{
+ msm_a2m_int(6);
+}
+
+#define APP_COMMAND 0x00
+#define APP_STATUS 0x04
+#define APP_DATA1 0x08
+#define APP_DATA2 0x0C
+
+#define MDM_COMMAND 0x10
+#define MDM_STATUS 0x14
+#define MDM_DATA1 0x18
+#define MDM_DATA2 0x1C
+
+static DEFINE_SPINLOCK(proc_comm_lock);
+
+/* The higher level SMD support will install this to
+ * provide a way to check for and handle modem restart.
+ */
+int (*msm_check_for_modem_crash)(void);
+
+/* Poll for a state change, checking for possible
+ * modem crashes along the way (so we don't wait
+ * forever while the ARM9 is blowing up).
+ *
+ * Return an error in the event of a modem crash and
+ * restart so the msm_proc_comm() routine can restart
+ * the operation from the beginning.
+ */
+static int proc_comm_wait_for(void __iomem *addr, unsigned value)
+{
+ for (;;) {
+ if (readl(addr) == value)
+ return 0;
+
+ if (msm_check_for_modem_crash)
+ if (msm_check_for_modem_crash())
+ return -EAGAIN;
+ }
+}
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
+{
+ void __iomem *base = MSM_SHARED_RAM_BASE;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&proc_comm_lock, flags);
+
+ for (;;) {
+ if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
+ continue;
+
+ writel(cmd, base + APP_COMMAND);
+ writel(data1 ? *data1 : 0, base + APP_DATA1);
+ writel(data2 ? *data2 : 0, base + APP_DATA2);
+
+ notify_other_proc_comm();
+
+ if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
+ continue;
+
+ if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
+ if (data1)
+ *data1 = readl(base + APP_DATA1);
+ if (data2)
+ *data2 = readl(base + APP_DATA2);
+ ret = 0;
+ } else {
+ ret = -EIO;
+ }
+ break;
+ }
+
+ writel(PCOM_CMD_IDLE, base + APP_COMMAND);
+
+ spin_unlock_irqrestore(&proc_comm_lock, flags);
+
+ return ret;
+}
+
+/*
+ * We need to wait for the ARM9 to at least partially boot
+ * up before we can continue. Since the ARM9 does resource
+ * allocation, if we dont' wait we could end up crashing or in
+ * and unknown state. This function should be called early to
+ * wait on the ARM9.
+ */
+void __init proc_comm_boot_wait(void)
+{
+ void __iomem *base = MSM_SHARED_RAM_BASE;
+
+ proc_comm_wait_for(base + MDM_STATUS, PCOM_READY);
+
+}
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h
new file mode 100644
index 00000000..12da4cac
--- /dev/null
+++ b/arch/arm/mach-msm/proc_comm.h
@@ -0,0 +1,258 @@
+/* arch/arm/mach-msm/proc_comm.h
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
+
+#include <linux/init.h>
+
+enum {
+ PCOM_CMD_IDLE = 0x0,
+ PCOM_CMD_DONE,
+ PCOM_RESET_APPS,
+ PCOM_RESET_CHIP,
+ PCOM_CONFIG_NAND_MPU,
+ PCOM_CONFIG_USB_CLKS,
+ PCOM_GET_POWER_ON_STATUS,
+ PCOM_GET_WAKE_UP_STATUS,
+ PCOM_GET_BATT_LEVEL,
+ PCOM_CHG_IS_CHARGING,
+ PCOM_POWER_DOWN,
+ PCOM_USB_PIN_CONFIG,
+ PCOM_USB_PIN_SEL,
+ PCOM_SET_RTC_ALARM,
+ PCOM_NV_READ,
+ PCOM_NV_WRITE,
+ PCOM_GET_UUID_HIGH,
+ PCOM_GET_UUID_LOW,
+ PCOM_GET_HW_ENTROPY,
+ PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
+ PCOM_CLKCTL_RPC_ENABLE,
+ PCOM_CLKCTL_RPC_DISABLE,
+ PCOM_CLKCTL_RPC_RESET,
+ PCOM_CLKCTL_RPC_SET_FLAGS,
+ PCOM_CLKCTL_RPC_SET_RATE,
+ PCOM_CLKCTL_RPC_MIN_RATE,
+ PCOM_CLKCTL_RPC_MAX_RATE,
+ PCOM_CLKCTL_RPC_RATE,
+ PCOM_CLKCTL_RPC_PLL_REQUEST,
+ PCOM_CLKCTL_RPC_ENABLED,
+ PCOM_VREG_SWITCH,
+ PCOM_VREG_SET_LEVEL,
+ PCOM_GPIO_TLMM_CONFIG_GROUP,
+ PCOM_GPIO_TLMM_UNCONFIG_GROUP,
+ PCOM_NV_WRITE_BYTES_4_7,
+ PCOM_CONFIG_DISP,
+ PCOM_GET_FTM_BOOT_COUNT,
+ PCOM_RPC_GPIO_TLMM_CONFIG_EX,
+ PCOM_PM_MPP_CONFIG,
+ PCOM_GPIO_IN,
+ PCOM_GPIO_OUT,
+ PCOM_RESET_MODEM,
+ PCOM_RESET_CHIP_IMM,
+ PCOM_PM_VID_EN,
+ PCOM_VREG_PULLDOWN,
+ PCOM_GET_MODEM_VERSION,
+ PCOM_CLK_REGIME_SEC_RESET,
+ PCOM_CLK_REGIME_SEC_RESET_ASSERT,
+ PCOM_CLK_REGIME_SEC_RESET_DEASSERT,
+ PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP,
+ PCOM_CLK_REGIME_SEC_ENABLE,
+ PCOM_CLK_REGIME_SEC_DISABLE,
+ PCOM_CLK_REGIME_SEC_IS_ON,
+ PCOM_CLK_REGIME_SEC_SEL_CLK_INV,
+ PCOM_CLK_REGIME_SEC_SEL_CLK_SRC,
+ PCOM_CLK_REGIME_SEC_SEL_CLK_DIV,
+ PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE,
+ PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE,
+ PCOM_CLK_REGIME_SEC_SEL_SPEED,
+ PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP,
+ PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP,
+ PCOM_CLK_REGIME_SEC_USB_XTAL_ON,
+ PCOM_CLK_REGIME_SEC_USB_XTAL_OFF,
+ PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE,
+ PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK,
+ PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ,
+ PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ,
+ PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ,
+ PCOM_CLK_REGIME_SEC_SEL_VFE_SRC,
+ PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK,
+ PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK,
+ PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF,
+ PCOM_CLK_REGIME_SEC_VFE_RAIL_ON,
+ PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF,
+ PCOM_CLK_REGIME_SEC_GRP_RAIL_ON,
+ PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF,
+ PCOM_CLK_REGIME_SEC_VDC_RAIL_ON,
+ PCOM_CLK_REGIME_SEC_LCD_CTRL,
+ PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE,
+ PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE,
+ PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP,
+ PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER,
+ PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP,
+ PCOM_GPIO_CONFIG,
+ PCOM_GPIO_CONFIGURE_GROUP,
+ PCOM_GPIO_TLMM_SET_PORT,
+ PCOM_GPIO_TLMM_CONFIG_EX,
+ PCOM_SET_FTM_BOOT_COUNT,
+ PCOM_RESERVED0,
+ PCOM_RESERVED1,
+ PCOM_CUSTOMER_CMD1,
+ PCOM_CUSTOMER_CMD2,
+ PCOM_CUSTOMER_CMD3,
+ PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE,
+ PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE,
+ PCOM_CLK_REGIME_SEC_RAIL_DISABLE,
+ PCOM_CLK_REGIME_SEC_RAIL_ENABLE,
+ PCOM_CLK_REGIME_SEC_RAIL_CONTROL,
+ PCOM_SET_SW_WATCHDOG_STATE,
+ PCOM_PM_MPP_CONFIG_DIGITAL_INPUT,
+ PCOM_PM_MPP_CONFIG_I_SINK,
+ PCOM_RESERVED_101,
+ PCOM_MSM_HSUSB_PHY_RESET,
+ PCOM_GET_BATT_MV_LEVEL,
+ PCOM_CHG_USB_IS_PC_CONNECTED,
+ PCOM_CHG_USB_IS_CHARGER_CONNECTED,
+ PCOM_CHG_USB_IS_DISCONNECTED,
+ PCOM_CHG_USB_IS_AVAILABLE,
+ PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ,
+ PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY,
+ PCOM_CLKCTL_RPC_RESET_ASSERT,
+ PCOM_CLKCTL_RPC_RESET_DEASSERT,
+ PCOM_CLKCTL_RPC_RAIL_ON,
+ PCOM_CLKCTL_RPC_RAIL_OFF,
+ PCOM_CLKCTL_RPC_RAIL_ENABLE,
+ PCOM_CLKCTL_RPC_RAIL_DISABLE,
+ PCOM_CLKCTL_RPC_RAIL_CONTROL,
+ PCOM_CLKCTL_RPC_MIN_MSMC1,
+ PCOM_NUM_CMDS,
+};
+
+enum {
+ PCOM_INVALID_STATUS = 0x0,
+ PCOM_READY,
+ PCOM_CMD_RUNNING,
+ PCOM_CMD_SUCCESS,
+ PCOM_CMD_FAIL,
+ PCOM_CMD_FAIL_FALSE_RETURNED,
+ PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER,
+ PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT,
+ PCOM_CMD_FAIL_CMD_UNREGISTERED,
+ PCOM_CMD_FAIL_CMD_LOCKED,
+ PCOM_CMD_FAIL_SERVER_NOT_YET_READY,
+ PCOM_CMD_FAIL_BAD_DESTINATION,
+ PCOM_CMD_FAIL_SERVER_RESET,
+ PCOM_CMD_FAIL_SMSM_NOT_INIT,
+ PCOM_CMD_FAIL_PROC_COMM_BUSY,
+ PCOM_CMD_FAIL_PROC_COMM_NOT_INIT,
+
+};
+
+/* List of VREGs that support the Pull Down Resistor setting. */
+enum vreg_pdown_id {
+ PM_VREG_PDOWN_MSMA_ID,
+ PM_VREG_PDOWN_MSMP_ID,
+ PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
+ PM_VREG_PDOWN_MSMC1_ID, /* Not supported in PM6620 */
+ PM_VREG_PDOWN_MSMC2_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_GP3_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_MSME2_ID, /* Supported in PM7500 and Panoramix only */
+ PM_VREG_PDOWN_GP4_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_GP1_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_TCXO_ID,
+ PM_VREG_PDOWN_PA_ID,
+ PM_VREG_PDOWN_RFTX_ID,
+ PM_VREG_PDOWN_RFRX1_ID,
+ PM_VREG_PDOWN_RFRX2_ID,
+ PM_VREG_PDOWN_SYNT_ID,
+ PM_VREG_PDOWN_WLAN_ID,
+ PM_VREG_PDOWN_USB_ID,
+ PM_VREG_PDOWN_MMC_ID,
+ PM_VREG_PDOWN_RUIM_ID,
+ PM_VREG_PDOWN_MSMC0_ID, /* Supported in PM6610 only */
+ PM_VREG_PDOWN_GP2_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_GP5_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_GP6_ID, /* Supported in PM7500 only */
+ PM_VREG_PDOWN_RF_ID,
+ PM_VREG_PDOWN_RF_VCO_ID,
+ PM_VREG_PDOWN_MPLL_ID,
+ PM_VREG_PDOWN_S2_ID,
+ PM_VREG_PDOWN_S3_ID,
+ PM_VREG_PDOWN_RFUBM_ID,
+
+ /* new for HAN */
+ PM_VREG_PDOWN_RF1_ID,
+ PM_VREG_PDOWN_RF2_ID,
+ PM_VREG_PDOWN_RFA_ID,
+ PM_VREG_PDOWN_CDC2_ID,
+ PM_VREG_PDOWN_RFTX2_ID,
+ PM_VREG_PDOWN_USIM_ID,
+ PM_VREG_PDOWN_USB2P6_ID,
+ PM_VREG_PDOWN_USB3P3_ID,
+ PM_VREG_PDOWN_INVALID_ID,
+
+ /* backward compatible enums only */
+ PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
+ PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
+ PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
+ PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
+ PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
+ PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
+
+ PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
+ PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
+ PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
+ PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
+ PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
+};
+
+enum {
+ PCOM_CLKRGM_APPS_RESET_USB_PHY = 34,
+ PCOM_CLKRGM_APPS_RESET_USBH = 37,
+};
+
+/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
+
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
+ ((((gpio) & 0x3FF) << 4) | \
+ ((func) & 0xf) | \
+ (((dir) & 0x1) << 14) | \
+ (((pull) & 0x3) << 15) | \
+ (((drvstr) & 0xF) << 17))
+
+int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
+void __init proc_comm_boot_wait(void);
+
+#endif
diff --git a/arch/arm/mach-msm/scm-boot.c b/arch/arm/mach-msm/scm-boot.c
new file mode 100644
index 00000000..45cee3e4
--- /dev/null
+++ b/arch/arm/mach-msm/scm-boot.c
@@ -0,0 +1,39 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "scm.h"
+#include "scm-boot.h"
+
+/*
+ * Set the cold/warm boot address for one of the CPU cores.
+ */
+int scm_set_boot_addr(phys_addr_t addr, int flags)
+{
+ struct {
+ unsigned int flags;
+ phys_addr_t addr;
+ } cmd;
+
+ cmd.addr = addr;
+ cmd.flags = flags;
+ return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
+ &cmd, sizeof(cmd), NULL, 0);
+}
+EXPORT_SYMBOL(scm_set_boot_addr);
diff --git a/arch/arm/mach-msm/scm-boot.h b/arch/arm/mach-msm/scm-boot.h
new file mode 100644
index 00000000..7be32ff5
--- /dev/null
+++ b/arch/arm/mach-msm/scm-boot.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_SCM_BOOT_H
+#define __MACH_SCM_BOOT_H
+
+#define SCM_BOOT_ADDR 0x1
+#define SCM_FLAG_COLDBOOT_CPU1 0x1
+#define SCM_FLAG_WARMBOOT_CPU1 0x2
+#define SCM_FLAG_WARMBOOT_CPU0 0x4
+
+int scm_set_boot_addr(phys_addr_t addr, int flags);
+
+#endif
diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c
new file mode 100644
index 00000000..232f97a0
--- /dev/null
+++ b/arch/arm/mach-msm/scm.c
@@ -0,0 +1,293 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+
+#include <asm/cacheflush.h>
+
+#include "scm.h"
+
+/* Cache line size for msm8x60 */
+#define CACHELINESIZE 32
+
+#define SCM_ENOMEM -5
+#define SCM_EOPNOTSUPP -4
+#define SCM_EINVAL_ADDR -3
+#define SCM_EINVAL_ARG -2
+#define SCM_ERROR -1
+#define SCM_INTERRUPTED 1
+
+static DEFINE_MUTEX(scm_lock);
+
+/**
+ * struct scm_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_get_command_buffer()
+ *
+ * An SCM command is laid out in memory as follows:
+ *
+ * ------------------- <--- struct scm_command
+ * | command header |
+ * ------------------- <--- scm_get_command_buffer()
+ * | command buffer |
+ * ------------------- <--- struct scm_response and
+ * | response header | scm_command_to_response()
+ * ------------------- <--- scm_get_response_buffer()
+ * | response buffer |
+ * -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_command {
+ u32 len;
+ u32 buf_offset;
+ u32 resp_hdr_offset;
+ u32 id;
+ u32 buf[0];
+};
+
+/**
+ * struct scm_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_response {
+ u32 len;
+ u32 buf_offset;
+ u32 is_complete;
+};
+
+/**
+ * alloc_scm_command() - Allocate an SCM command
+ * @cmd_size: size of the command buffer
+ * @resp_size: size of the response buffer
+ *
+ * Allocate an SCM command, including enough room for the command
+ * and response headers as well as the command and response buffers.
+ *
+ * Returns a valid &scm_command on success or %NULL if the allocation fails.
+ */
+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
+{
+ struct scm_command *cmd;
+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
+ resp_size;
+
+ cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
+ if (cmd) {
+ cmd->len = len;
+ cmd->buf_offset = offsetof(struct scm_command, buf);
+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ }
+ return cmd;
+}
+
+/**
+ * free_scm_command() - Free an SCM command
+ * @cmd: command to free
+ *
+ * Free an SCM command.
+ */
+static inline void free_scm_command(struct scm_command *cmd)
+{
+ kfree(cmd);
+}
+
+/**
+ * scm_command_to_response() - Get a pointer to a scm_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_response *scm_command_to_response(
+ const struct scm_command *cmd)
+{
+ return (void *)cmd + cmd->resp_hdr_offset;
+}
+
+/**
+ * scm_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_get_command_buffer(const struct scm_command *cmd)
+{
+ return (void *)cmd->buf;
+}
+
+/**
+ * scm_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_get_response_buffer(const struct scm_response *rsp)
+{
+ return (void *)rsp + rsp->buf_offset;
+}
+
+static int scm_remap_error(int err)
+{
+ switch (err) {
+ case SCM_ERROR:
+ return -EIO;
+ case SCM_EINVAL_ADDR:
+ case SCM_EINVAL_ARG:
+ return -EINVAL;
+ case SCM_EOPNOTSUPP:
+ return -EOPNOTSUPP;
+ case SCM_ENOMEM:
+ return -ENOMEM;
+ }
+ return -EINVAL;
+}
+
+static u32 smc(u32 cmd_addr)
+{
+ int context_id;
+ register u32 r0 asm("r0") = 1;
+ register u32 r1 asm("r1") = (u32)&context_id;
+ register u32 r2 asm("r2") = cmd_addr;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r0")
+ __asmeq("%2", "r1")
+ __asmeq("%3", "r2")
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0)
+ : "r" (r0), "r" (r1), "r" (r2)
+ : "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ return r0;
+}
+
+static int __scm_call(const struct scm_command *cmd)
+{
+ int ret;
+ u32 cmd_addr = virt_to_phys(cmd);
+
+ /*
+ * Flush the entire cache here so callers don't have to remember
+ * to flush the cache when passing physical addresses to the secure
+ * side in the buffer.
+ */
+ flush_cache_all();
+ ret = smc(cmd_addr);
+ if (ret < 0)
+ ret = scm_remap_error(ret);
+
+ return ret;
+}
+
+/**
+ * scm_call() - Send an SCM command
+ * @svc_id: service identifier
+ * @cmd_id: command identifier
+ * @cmd_buf: command buffer
+ * @cmd_len: length of the command buffer
+ * @resp_buf: response buffer
+ * @resp_len: length of the response buffer
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ */
+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len)
+{
+ int ret;
+ struct scm_command *cmd;
+ struct scm_response *rsp;
+
+ cmd = alloc_scm_command(cmd_len, resp_len);
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->id = (svc_id << 10) | cmd_id;
+ if (cmd_buf)
+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
+
+ mutex_lock(&scm_lock);
+ ret = __scm_call(cmd);
+ mutex_unlock(&scm_lock);
+ if (ret)
+ goto out;
+
+ rsp = scm_command_to_response(cmd);
+ do {
+ u32 start = (u32)rsp;
+ u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
+ start &= ~(CACHELINESIZE - 1);
+ while (start < end) {
+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+ : "memory");
+ start += CACHELINESIZE;
+ }
+ } while (!rsp->is_complete);
+
+ if (resp_buf)
+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
+out:
+ free_scm_command(cmd);
+ return ret;
+}
+EXPORT_SYMBOL(scm_call);
+
+u32 scm_get_version(void)
+{
+ int context_id;
+ static u32 version = -1;
+ register u32 r0 asm("r0");
+ register u32 r1 asm("r1");
+
+ if (version != -1)
+ return version;
+
+ mutex_lock(&scm_lock);
+
+ r0 = 0x1 << 8;
+ r1 = (u32)&context_id;
+ do {
+ asm volatile(
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r0")
+ __asmeq("%3", "r1")
+ "smc #0 @ switch to secure world\n"
+ : "=r" (r0), "=r" (r1)
+ : "r" (r0), "r" (r1)
+ : "r2", "r3");
+ } while (r0 == SCM_INTERRUPTED);
+
+ version = r1;
+ mutex_unlock(&scm_lock);
+
+ return version;
+}
+EXPORT_SYMBOL(scm_get_version);
diff --git a/arch/arm/mach-msm/scm.h b/arch/arm/mach-msm/scm.h
new file mode 100644
index 00000000..00b31ea5
--- /dev/null
+++ b/arch/arm/mach-msm/scm.h
@@ -0,0 +1,25 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_SCM_H
+#define __MACH_SCM_H
+
+#define SCM_SVC_BOOT 0x1
+#define SCM_SVC_PIL 0x2
+
+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
+ void *resp_buf, size_t resp_len);
+
+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
+
+extern u32 scm_get_version(void);
+
+#endif
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
new file mode 100644
index 00000000..689e78c9
--- /dev/null
+++ b/arch/arm/mach-msm/sirc.c
@@ -0,0 +1,172 @@
+/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+
+static unsigned int int_enable;
+static unsigned int wake_enable;
+
+static struct sirc_regs_t sirc_regs = {
+ .int_enable = SPSS_SIRC_INT_ENABLE,
+ .int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR,
+ .int_enable_set = SPSS_SIRC_INT_ENABLE_SET,
+ .int_type = SPSS_SIRC_INT_TYPE,
+ .int_polarity = SPSS_SIRC_INT_POLARITY,
+ .int_clear = SPSS_SIRC_INT_CLEAR,
+};
+
+static struct sirc_cascade_regs sirc_reg_table[] = {
+ {
+ .int_status = SPSS_SIRC_IRQ_STATUS,
+ .cascade_irq = INT_SIRC_0,
+ }
+};
+
+/* Mask off the given interrupt. Keep the int_enable mask in sync with
+ the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_mask(struct irq_data *d)
+{
+ unsigned int mask;
+
+ mask = 1 << (d->irq - FIRST_SIRC_IRQ);
+ writel(mask, sirc_regs.int_enable_clear);
+ int_enable &= ~mask;
+ return;
+}
+
+/* Unmask the given interrupt. Keep the int_enable mask in sync with
+ the enable reg, so it can be restored after power collapse. */
+static void sirc_irq_unmask(struct irq_data *d)
+{
+ unsigned int mask;
+
+ mask = 1 << (d->irq - FIRST_SIRC_IRQ);
+ writel(mask, sirc_regs.int_enable_set);
+ int_enable |= mask;
+ return;
+}
+
+static void sirc_irq_ack(struct irq_data *d)
+{
+ unsigned int mask;
+
+ mask = 1 << (d->irq - FIRST_SIRC_IRQ);
+ writel(mask, sirc_regs.int_clear);
+ return;
+}
+
+static int sirc_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned int mask;
+
+ /* Used to set the interrupt enable mask during power collapse. */
+ mask = 1 << (d->irq - FIRST_SIRC_IRQ);
+ if (on)
+ wake_enable |= mask;
+ else
+ wake_enable &= ~mask;
+
+ return 0;
+}
+
+static int sirc_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ unsigned int mask;
+ unsigned int val;
+
+ mask = 1 << (d->irq - FIRST_SIRC_IRQ);
+ val = readl(sirc_regs.int_polarity);
+
+ if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING))
+ val |= mask;
+ else
+ val &= ~mask;
+
+ writel(val, sirc_regs.int_polarity);
+
+ val = readl(sirc_regs.int_type);
+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+ val |= mask;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ } else {
+ val &= ~mask;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ }
+
+ writel(val, sirc_regs.int_type);
+
+ return 0;
+}
+
+/* Finds the pending interrupt on the passed cascade irq and redrives it */
+static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int reg = 0;
+ unsigned int sirq;
+ unsigned int status;
+
+ while ((reg < ARRAY_SIZE(sirc_reg_table)) &&
+ (sirc_reg_table[reg].cascade_irq != irq))
+ reg++;
+
+ status = readl(sirc_reg_table[reg].int_status);
+ status &= SIRC_MASK;
+ if (status == 0)
+ return;
+
+ for (sirq = 0;
+ (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0);
+ sirq++)
+ ;
+ generic_handle_irq(sirq+FIRST_SIRC_IRQ);
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+}
+
+static struct irq_chip sirc_irq_chip = {
+ .name = "sirc",
+ .irq_ack = sirc_irq_ack,
+ .irq_mask = sirc_irq_mask,
+ .irq_unmask = sirc_irq_unmask,
+ .irq_set_wake = sirc_irq_set_wake,
+ .irq_set_type = sirc_irq_set_type,
+};
+
+void __init msm_init_sirc(void)
+{
+ int i;
+
+ int_enable = 0;
+ wake_enable = 0;
+
+ for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
+ irq_set_chip_and_handler(i, &sirc_irq_chip, handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
+ irq_set_chained_handler(sirc_reg_table[i].cascade_irq,
+ sirc_irq_handler);
+ irq_set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
+ }
+ return;
+}
+
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
new file mode 100644
index 00000000..657be732
--- /dev/null
+++ b/arch/arm/mach-msm/smd.c
@@ -0,0 +1,1041 @@
+/* arch/arm/mach-msm/smd.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+
+#include <mach/msm_smd.h>
+#include <mach/system.h>
+
+#include "smd_private.h"
+#include "proc_comm.h"
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#define CONFIG_QDSP6 1
+#endif
+
+void (*msm_hw_reset_hook)(void);
+
+#define MODULE_NAME "msm_smd"
+
+enum {
+ MSM_SMD_DEBUG = 1U << 0,
+ MSM_SMSM_DEBUG = 1U << 0,
+};
+
+static int msm_smd_debug_mask;
+
+struct shared_info {
+ int ready;
+ unsigned state;
+};
+
+static unsigned dummy_state[SMSM_STATE_COUNT];
+
+static struct shared_info smd_info = {
+ .state = (unsigned) &dummy_state,
+};
+
+module_param_named(debug_mask, msm_smd_debug_mask,
+ int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static unsigned last_heap_free = 0xffffffff;
+
+static inline void notify_other_smsm(void)
+{
+ msm_a2m_int(5);
+#ifdef CONFIG_QDSP6
+ msm_a2m_int(8);
+#endif
+}
+
+static inline void notify_modem_smd(void)
+{
+ msm_a2m_int(0);
+}
+
+static inline void notify_dsp_smd(void)
+{
+ msm_a2m_int(8);
+}
+
+static void smd_diag(void)
+{
+ char *x;
+
+ x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+ if (x != 0) {
+ x[SZ_DIAG_ERR_MSG - 1] = 0;
+ pr_debug("DIAG '%s'\n", x);
+ }
+}
+
+/* call when SMSM_RESET flag is set in the A9's smsm_state */
+static void handle_modem_crash(void)
+{
+ pr_err("ARM9 has CRASHED\n");
+ smd_diag();
+
+ /* hard reboot if possible */
+ if (msm_hw_reset_hook)
+ msm_hw_reset_hook();
+
+ /* in this case the modem or watchdog should reboot us */
+ for (;;)
+ ;
+}
+
+uint32_t raw_smsm_get_state(enum smsm_state_item item)
+{
+ return readl(smd_info.state + item * 4);
+}
+
+static int check_for_modem_crash(void)
+{
+ if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) {
+ handle_modem_crash();
+ return -1;
+ }
+ return 0;
+}
+
+/* the spinlock is used to synchronize between the
+ * irq handler and code that mutates the channel
+ * list or fiddles with channel state
+ */
+DEFINE_SPINLOCK(smd_lock);
+DEFINE_SPINLOCK(smem_lock);
+
+/* the mutex is used during open() and close()
+ * operations to avoid races while creating or
+ * destroying smd_channel structures
+ */
+static DEFINE_MUTEX(smd_creation_mutex);
+
+static int smd_initialized;
+
+LIST_HEAD(smd_ch_closed_list);
+LIST_HEAD(smd_ch_list_modem);
+LIST_HEAD(smd_ch_list_dsp);
+
+static unsigned char smd_ch_allocated[64];
+static struct work_struct probe_work;
+
+/* how many bytes are available for reading */
+static int smd_stream_read_avail(struct smd_channel *ch)
+{
+ return (ch->recv->head - ch->recv->tail) & ch->fifo_mask;
+}
+
+/* how many bytes we are free to write */
+static int smd_stream_write_avail(struct smd_channel *ch)
+{
+ return ch->fifo_mask -
+ ((ch->send->head - ch->send->tail) & ch->fifo_mask);
+}
+
+static int smd_packet_read_avail(struct smd_channel *ch)
+{
+ if (ch->current_packet) {
+ int n = smd_stream_read_avail(ch);
+ if (n > ch->current_packet)
+ n = ch->current_packet;
+ return n;
+ } else {
+ return 0;
+ }
+}
+
+static int smd_packet_write_avail(struct smd_channel *ch)
+{
+ int n = smd_stream_write_avail(ch);
+ return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0;
+}
+
+static int ch_is_open(struct smd_channel *ch)
+{
+ return (ch->recv->state == SMD_SS_OPENED) &&
+ (ch->send->state == SMD_SS_OPENED);
+}
+
+/* provide a pointer and length to readable data in the fifo */
+static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr)
+{
+ unsigned head = ch->recv->head;
+ unsigned tail = ch->recv->tail;
+ *ptr = (void *) (ch->recv_data + tail);
+
+ if (tail <= head)
+ return head - tail;
+ else
+ return ch->fifo_size - tail;
+}
+
+/* advance the fifo read pointer after data from ch_read_buffer is consumed */
+static void ch_read_done(struct smd_channel *ch, unsigned count)
+{
+ BUG_ON(count > smd_stream_read_avail(ch));
+ ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask;
+ ch->send->fTAIL = 1;
+}
+
+/* basic read interface to ch_read_{buffer,done} used
+ * by smd_*_read() and update_packet_state()
+ * will read-and-discard if the _data pointer is null
+ */
+static int ch_read(struct smd_channel *ch, void *_data, int len)
+{
+ void *ptr;
+ unsigned n;
+ unsigned char *data = _data;
+ int orig_len = len;
+
+ while (len > 0) {
+ n = ch_read_buffer(ch, &ptr);
+ if (n == 0)
+ break;
+
+ if (n > len)
+ n = len;
+ if (_data)
+ memcpy(data, ptr, n);
+
+ data += n;
+ len -= n;
+ ch_read_done(ch, n);
+ }
+
+ return orig_len - len;
+}
+
+static void update_stream_state(struct smd_channel *ch)
+{
+ /* streams have no special state requiring updating */
+}
+
+static void update_packet_state(struct smd_channel *ch)
+{
+ unsigned hdr[5];
+ int r;
+
+ /* can't do anything if we're in the middle of a packet */
+ if (ch->current_packet != 0)
+ return;
+
+ /* don't bother unless we can get the full header */
+ if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
+ return;
+
+ r = ch_read(ch, hdr, SMD_HEADER_SIZE);
+ BUG_ON(r != SMD_HEADER_SIZE);
+
+ ch->current_packet = hdr[0];
+}
+
+/* provide a pointer and length to next free space in the fifo */
+static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr)
+{
+ unsigned head = ch->send->head;
+ unsigned tail = ch->send->tail;
+ *ptr = (void *) (ch->send_data + head);
+
+ if (head < tail) {
+ return tail - head - 1;
+ } else {
+ if (tail == 0)
+ return ch->fifo_size - head - 1;
+ else
+ return ch->fifo_size - head;
+ }
+}
+
+/* advace the fifo write pointer after freespace
+ * from ch_write_buffer is filled
+ */
+static void ch_write_done(struct smd_channel *ch, unsigned count)
+{
+ BUG_ON(count > smd_stream_write_avail(ch));
+ ch->send->head = (ch->send->head + count) & ch->fifo_mask;
+ ch->send->fHEAD = 1;
+}
+
+static void ch_set_state(struct smd_channel *ch, unsigned n)
+{
+ if (n == SMD_SS_OPENED) {
+ ch->send->fDSR = 1;
+ ch->send->fCTS = 1;
+ ch->send->fCD = 1;
+ } else {
+ ch->send->fDSR = 0;
+ ch->send->fCTS = 0;
+ ch->send->fCD = 0;
+ }
+ ch->send->state = n;
+ ch->send->fSTATE = 1;
+ ch->notify_other_cpu();
+}
+
+static void do_smd_probe(void)
+{
+ struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+ if (shared->heap_info.free_offset != last_heap_free) {
+ last_heap_free = shared->heap_info.free_offset;
+ schedule_work(&probe_work);
+ }
+}
+
+static void smd_state_change(struct smd_channel *ch,
+ unsigned last, unsigned next)
+{
+ ch->last_state = next;
+
+ pr_debug("ch %d %d -> %d\n", ch->n, last, next);
+
+ switch (next) {
+ case SMD_SS_OPENING:
+ ch->recv->tail = 0;
+ case SMD_SS_OPENED:
+ if (ch->send->state != SMD_SS_OPENED)
+ ch_set_state(ch, SMD_SS_OPENED);
+ ch->notify(ch->priv, SMD_EVENT_OPEN);
+ break;
+ case SMD_SS_FLUSHING:
+ case SMD_SS_RESET:
+ /* we should force them to close? */
+ default:
+ ch->notify(ch->priv, SMD_EVENT_CLOSE);
+ }
+}
+
+static void handle_smd_irq(struct list_head *list, void (*notify)(void))
+{
+ unsigned long flags;
+ struct smd_channel *ch;
+ int do_notify = 0;
+ unsigned ch_flags;
+ unsigned tmp;
+
+ spin_lock_irqsave(&smd_lock, flags);
+ list_for_each_entry(ch, list, ch_list) {
+ ch_flags = 0;
+ if (ch_is_open(ch)) {
+ if (ch->recv->fHEAD) {
+ ch->recv->fHEAD = 0;
+ ch_flags |= 1;
+ do_notify |= 1;
+ }
+ if (ch->recv->fTAIL) {
+ ch->recv->fTAIL = 0;
+ ch_flags |= 2;
+ do_notify |= 1;
+ }
+ if (ch->recv->fSTATE) {
+ ch->recv->fSTATE = 0;
+ ch_flags |= 4;
+ do_notify |= 1;
+ }
+ }
+ tmp = ch->recv->state;
+ if (tmp != ch->last_state)
+ smd_state_change(ch, ch->last_state, tmp);
+ if (ch_flags) {
+ ch->update_state(ch);
+ ch->notify(ch->priv, SMD_EVENT_DATA);
+ }
+ }
+ if (do_notify)
+ notify();
+ spin_unlock_irqrestore(&smd_lock, flags);
+ do_smd_probe();
+}
+
+static irqreturn_t smd_modem_irq_handler(int irq, void *data)
+{
+ handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+ return IRQ_HANDLED;
+}
+
+#if defined(CONFIG_QDSP6)
+static irqreturn_t smd_dsp_irq_handler(int irq, void *data)
+{
+ handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+ return IRQ_HANDLED;
+}
+#endif
+
+static void smd_fake_irq_handler(unsigned long arg)
+{
+ handle_smd_irq(&smd_ch_list_modem, notify_modem_smd);
+ handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd);
+}
+
+static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0);
+
+static inline int smd_need_int(struct smd_channel *ch)
+{
+ if (ch_is_open(ch)) {
+ if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE)
+ return 1;
+ if (ch->recv->state != ch->last_state)
+ return 1;
+ }
+ return 0;
+}
+
+void smd_sleep_exit(void)
+{
+ unsigned long flags;
+ struct smd_channel *ch;
+ int need_int = 0;
+
+ spin_lock_irqsave(&smd_lock, flags);
+ list_for_each_entry(ch, &smd_ch_list_modem, ch_list) {
+ if (smd_need_int(ch)) {
+ need_int = 1;
+ break;
+ }
+ }
+ list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) {
+ if (smd_need_int(ch)) {
+ need_int = 1;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&smd_lock, flags);
+ do_smd_probe();
+
+ if (need_int) {
+ if (msm_smd_debug_mask & MSM_SMD_DEBUG)
+ pr_info("smd_sleep_exit need interrupt\n");
+ tasklet_schedule(&smd_fake_irq_tasklet);
+ }
+}
+
+
+void smd_kick(smd_channel_t *ch)
+{
+ unsigned long flags;
+ unsigned tmp;
+
+ spin_lock_irqsave(&smd_lock, flags);
+ ch->update_state(ch);
+ tmp = ch->recv->state;
+ if (tmp != ch->last_state) {
+ ch->last_state = tmp;
+ if (tmp == SMD_SS_OPENED)
+ ch->notify(ch->priv, SMD_EVENT_OPEN);
+ else
+ ch->notify(ch->priv, SMD_EVENT_CLOSE);
+ }
+ ch->notify(ch->priv, SMD_EVENT_DATA);
+ ch->notify_other_cpu();
+ spin_unlock_irqrestore(&smd_lock, flags);
+}
+
+static int smd_is_packet(int chn, unsigned type)
+{
+ type &= SMD_KIND_MASK;
+ if (type == SMD_KIND_PACKET)
+ return 1;
+ if (type == SMD_KIND_STREAM)
+ return 0;
+
+ /* older AMSS reports SMD_KIND_UNKNOWN always */
+ if ((chn > 4) || (chn == 1))
+ return 1;
+ else
+ return 0;
+}
+
+static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
+{
+ void *ptr;
+ const unsigned char *buf = _data;
+ unsigned xfer;
+ int orig_len = len;
+
+ if (len < 0)
+ return -EINVAL;
+
+ while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
+ if (!ch_is_open(ch))
+ break;
+ if (xfer > len)
+ xfer = len;
+ memcpy(ptr, buf, xfer);
+ ch_write_done(ch, xfer);
+ len -= xfer;
+ buf += xfer;
+ if (len == 0)
+ break;
+ }
+
+ ch->notify_other_cpu();
+
+ return orig_len - len;
+}
+
+static int smd_packet_write(smd_channel_t *ch, const void *_data, int len)
+{
+ unsigned hdr[5];
+
+ if (len < 0)
+ return -EINVAL;
+
+ if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE))
+ return -ENOMEM;
+
+ hdr[0] = len;
+ hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0;
+
+ smd_stream_write(ch, hdr, sizeof(hdr));
+ smd_stream_write(ch, _data, len);
+
+ return len;
+}
+
+static int smd_stream_read(smd_channel_t *ch, void *data, int len)
+{
+ int r;
+
+ if (len < 0)
+ return -EINVAL;
+
+ r = ch_read(ch, data, len);
+ if (r > 0)
+ ch->notify_other_cpu();
+
+ return r;
+}
+
+static int smd_packet_read(smd_channel_t *ch, void *data, int len)
+{
+ unsigned long flags;
+ int r;
+
+ if (len < 0)
+ return -EINVAL;
+
+ if (len > ch->current_packet)
+ len = ch->current_packet;
+
+ r = ch_read(ch, data, len);
+ if (r > 0)
+ ch->notify_other_cpu();
+
+ spin_lock_irqsave(&smd_lock, flags);
+ ch->current_packet -= r;
+ update_packet_state(ch);
+ spin_unlock_irqrestore(&smd_lock, flags);
+
+ return r;
+}
+
+static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type)
+{
+ struct smd_channel *ch;
+
+ ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL);
+ if (ch == 0) {
+ pr_err("smd_alloc_channel() out of memory\n");
+ return -1;
+ }
+ ch->n = cid;
+
+ if (_smd_alloc_channel(ch)) {
+ kfree(ch);
+ return -1;
+ }
+
+ ch->fifo_mask = ch->fifo_size - 1;
+ ch->type = type;
+
+ if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+ ch->notify_other_cpu = notify_modem_smd;
+ else
+ ch->notify_other_cpu = notify_dsp_smd;
+
+ if (smd_is_packet(cid, type)) {
+ ch->read = smd_packet_read;
+ ch->write = smd_packet_write;
+ ch->read_avail = smd_packet_read_avail;
+ ch->write_avail = smd_packet_write_avail;
+ ch->update_state = update_packet_state;
+ } else {
+ ch->read = smd_stream_read;
+ ch->write = smd_stream_write;
+ ch->read_avail = smd_stream_read_avail;
+ ch->write_avail = smd_stream_write_avail;
+ ch->update_state = update_stream_state;
+ }
+
+ if ((type & 0xff) == 0)
+ memcpy(ch->name, "SMD_", 4);
+ else
+ memcpy(ch->name, "DSP_", 4);
+ memcpy(ch->name + 4, name, 20);
+ ch->name[23] = 0;
+ ch->pdev.name = ch->name;
+ ch->pdev.id = -1;
+
+ pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n",
+ ch->n, ch->fifo_size, ch->name);
+
+ mutex_lock(&smd_creation_mutex);
+ list_add(&ch->ch_list, &smd_ch_closed_list);
+ mutex_unlock(&smd_creation_mutex);
+
+ platform_device_register(&ch->pdev);
+ return 0;
+}
+
+static void smd_channel_probe_worker(struct work_struct *work)
+{
+ struct smd_alloc_elm *shared;
+ unsigned ctype;
+ unsigned type;
+ unsigned n;
+
+ shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+ if (!shared) {
+ pr_err("cannot find allocation table\n");
+ return;
+ }
+ for (n = 0; n < 64; n++) {
+ if (smd_ch_allocated[n])
+ continue;
+ if (!shared[n].ref_count)
+ continue;
+ if (!shared[n].name[0])
+ continue;
+ ctype = shared[n].ctype;
+ type = ctype & SMD_TYPE_MASK;
+
+ /* DAL channels are stream but neither the modem,
+ * nor the DSP correctly indicate this. Fixup manually.
+ */
+ if (!memcmp(shared[n].name, "DAL", 3))
+ ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM;
+
+ type = shared[n].ctype & SMD_TYPE_MASK;
+ if ((type == SMD_TYPE_APPS_MODEM) ||
+ (type == SMD_TYPE_APPS_DSP))
+ if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype))
+ smd_ch_allocated[n] = 1;
+ }
+}
+
+static void do_nothing_notify(void *priv, unsigned flags)
+{
+}
+
+struct smd_channel *smd_get_channel(const char *name)
+{
+ struct smd_channel *ch;
+
+ mutex_lock(&smd_creation_mutex);
+ list_for_each_entry(ch, &smd_ch_closed_list, ch_list) {
+ if (!strcmp(name, ch->name)) {
+ list_del(&ch->ch_list);
+ mutex_unlock(&smd_creation_mutex);
+ return ch;
+ }
+ }
+ mutex_unlock(&smd_creation_mutex);
+
+ return NULL;
+}
+
+int smd_open(const char *name, smd_channel_t **_ch,
+ void *priv, void (*notify)(void *, unsigned))
+{
+ struct smd_channel *ch;
+ unsigned long flags;
+
+ if (smd_initialized == 0) {
+ pr_info("smd_open() before smd_init()\n");
+ return -ENODEV;
+ }
+
+ ch = smd_get_channel(name);
+ if (!ch)
+ return -ENODEV;
+
+ if (notify == 0)
+ notify = do_nothing_notify;
+
+ ch->notify = notify;
+ ch->current_packet = 0;
+ ch->last_state = SMD_SS_CLOSED;
+ ch->priv = priv;
+
+ *_ch = ch;
+
+ spin_lock_irqsave(&smd_lock, flags);
+
+ if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM)
+ list_add(&ch->ch_list, &smd_ch_list_modem);
+ else
+ list_add(&ch->ch_list, &smd_ch_list_dsp);
+
+ /* If the remote side is CLOSING, we need to get it to
+ * move to OPENING (which we'll do by moving from CLOSED to
+ * OPENING) and then get it to move from OPENING to
+ * OPENED (by doing the same state change ourselves).
+ *
+ * Otherwise, it should be OPENING and we can move directly
+ * to OPENED so that it will follow.
+ */
+ if (ch->recv->state == SMD_SS_CLOSING) {
+ ch->send->head = 0;
+ ch_set_state(ch, SMD_SS_OPENING);
+ } else {
+ ch_set_state(ch, SMD_SS_OPENED);
+ }
+ spin_unlock_irqrestore(&smd_lock, flags);
+ smd_kick(ch);
+
+ return 0;
+}
+
+int smd_close(smd_channel_t *ch)
+{
+ unsigned long flags;
+
+ if (ch == 0)
+ return -1;
+
+ spin_lock_irqsave(&smd_lock, flags);
+ ch->notify = do_nothing_notify;
+ list_del(&ch->ch_list);
+ ch_set_state(ch, SMD_SS_CLOSED);
+ spin_unlock_irqrestore(&smd_lock, flags);
+
+ mutex_lock(&smd_creation_mutex);
+ list_add(&ch->ch_list, &smd_ch_closed_list);
+ mutex_unlock(&smd_creation_mutex);
+
+ return 0;
+}
+
+int smd_read(smd_channel_t *ch, void *data, int len)
+{
+ return ch->read(ch, data, len);
+}
+
+int smd_write(smd_channel_t *ch, const void *data, int len)
+{
+ return ch->write(ch, data, len);
+}
+
+int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
+{
+ unsigned long flags;
+ int res;
+ spin_lock_irqsave(&smd_lock, flags);
+ res = ch->write(ch, data, len);
+ spin_unlock_irqrestore(&smd_lock, flags);
+ return res;
+}
+
+int smd_read_avail(smd_channel_t *ch)
+{
+ return ch->read_avail(ch);
+}
+
+int smd_write_avail(smd_channel_t *ch)
+{
+ return ch->write_avail(ch);
+}
+
+int smd_wait_until_readable(smd_channel_t *ch, int bytes)
+{
+ return -1;
+}
+
+int smd_wait_until_writable(smd_channel_t *ch, int bytes)
+{
+ return -1;
+}
+
+int smd_cur_packet_size(smd_channel_t *ch)
+{
+ return ch->current_packet;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+void *smem_alloc(unsigned id, unsigned size)
+{
+ return smem_find(id, size);
+}
+
+void *smem_item(unsigned id, unsigned *size)
+{
+ struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+ struct smem_heap_entry *toc = shared->heap_toc;
+
+ if (id >= SMEM_NUM_ITEMS)
+ return 0;
+
+ if (toc[id].allocated) {
+ *size = toc[id].size;
+ return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset);
+ } else {
+ *size = 0;
+ }
+
+ return 0;
+}
+
+void *smem_find(unsigned id, unsigned size_in)
+{
+ unsigned size;
+ void *ptr;
+
+ ptr = smem_item(id, &size);
+ if (!ptr)
+ return 0;
+
+ size_in = ALIGN(size_in, 8);
+ if (size_in != size) {
+ pr_err("smem_find(%d, %d): wrong size %d\n",
+ id, size_in, size);
+ return 0;
+ }
+
+ return ptr;
+}
+
+static irqreturn_t smsm_irq_handler(int irq, void *data)
+{
+ unsigned long flags;
+ unsigned apps, modm;
+
+ spin_lock_irqsave(&smem_lock, flags);
+
+ apps = raw_smsm_get_state(SMSM_STATE_APPS);
+ modm = raw_smsm_get_state(SMSM_STATE_MODEM);
+
+ if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+ pr_info("<SM %08x %08x>\n", apps, modm);
+ if (modm & SMSM_RESET)
+ handle_modem_crash();
+
+ do_smd_probe();
+
+ spin_unlock_irqrestore(&smem_lock, flags);
+ return IRQ_HANDLED;
+}
+
+int smsm_change_state(enum smsm_state_item item,
+ uint32_t clear_mask, uint32_t set_mask)
+{
+ unsigned long addr = smd_info.state + item * 4;
+ unsigned long flags;
+ unsigned state;
+
+ if (!smd_info.ready)
+ return -EIO;
+
+ spin_lock_irqsave(&smem_lock, flags);
+
+ if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+ handle_modem_crash();
+
+ state = (readl(addr) & ~clear_mask) | set_mask;
+ writel(state, addr);
+
+ if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+ pr_info("smsm_change_state %d %x\n", item, state);
+ notify_other_smsm();
+
+ spin_unlock_irqrestore(&smem_lock, flags);
+
+ return 0;
+}
+
+uint32_t smsm_get_state(enum smsm_state_item item)
+{
+ unsigned long flags;
+ uint32_t rv;
+
+ spin_lock_irqsave(&smem_lock, flags);
+
+ rv = readl(smd_info.state + item * 4);
+
+ if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET))
+ handle_modem_crash();
+
+ spin_unlock_irqrestore(&smem_lock, flags);
+
+ return rv;
+}
+
+#ifdef CONFIG_ARCH_MSM_SCORPION
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+ struct msm_dem_slave_data *ptr;
+
+ ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr));
+ if (ptr == NULL) {
+ pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n");
+ return -EIO;
+ }
+ if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+ pr_info("smsm_set_sleep_duration %d -> %d\n",
+ ptr->sleep_time, delay);
+ ptr->sleep_time = delay;
+ return 0;
+}
+
+#else
+
+int smsm_set_sleep_duration(uint32_t delay)
+{
+ uint32_t *ptr;
+
+ ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+ if (ptr == NULL) {
+ pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n");
+ return -EIO;
+ }
+ if (msm_smd_debug_mask & MSM_SMSM_DEBUG)
+ pr_info("smsm_set_sleep_duration %d -> %d\n",
+ *ptr, delay);
+ *ptr = delay;
+ return 0;
+}
+
+#endif
+
+int smd_core_init(void)
+{
+ int r;
+
+ /* wait for essential items to be initialized */
+ for (;;) {
+ unsigned size;
+ void *state;
+ state = smem_item(SMEM_SMSM_SHARED_STATE, &size);
+ if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) {
+ smd_info.state = (unsigned)state;
+ break;
+ }
+ }
+
+ smd_info.ready = 1;
+
+ r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler,
+ IRQF_TRIGGER_RISING, "smd_dev", 0);
+ if (r < 0)
+ return r;
+ r = enable_irq_wake(INT_A9_M2A_0);
+ if (r < 0)
+ pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n");
+
+ r = request_irq(INT_A9_M2A_5, smsm_irq_handler,
+ IRQF_TRIGGER_RISING, "smsm_dev", 0);
+ if (r < 0) {
+ free_irq(INT_A9_M2A_0, 0);
+ return r;
+ }
+ r = enable_irq_wake(INT_A9_M2A_5);
+ if (r < 0)
+ pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n");
+
+#if defined(CONFIG_QDSP6)
+ r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler,
+ IRQF_TRIGGER_RISING, "smd_dsp", 0);
+ if (r < 0) {
+ free_irq(INT_A9_M2A_0, 0);
+ free_irq(INT_A9_M2A_5, 0);
+ return r;
+ }
+#endif
+
+ /* check for any SMD channels that may already exist */
+ do_smd_probe();
+
+ /* indicate that we're up and running */
+ smsm_change_state(SMSM_STATE_APPS,
+ ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN);
+#ifdef CONFIG_ARCH_MSM_SCORPION
+ smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0);
+#endif
+
+ return 0;
+}
+
+static int __devinit msm_smd_probe(struct platform_device *pdev)
+{
+ /*
+ * If we haven't waited for the ARM9 to boot up till now,
+ * then we need to wait here. Otherwise this should just
+ * return immediately.
+ */
+ proc_comm_boot_wait();
+
+ INIT_WORK(&probe_work, smd_channel_probe_worker);
+
+ if (smd_core_init()) {
+ pr_err("smd_core_init() failed\n");
+ return -1;
+ }
+
+ do_smd_probe();
+
+ msm_check_for_modem_crash = check_for_modem_crash;
+
+ msm_init_last_radio_log(THIS_MODULE);
+
+ smd_initialized = 1;
+
+ return 0;
+}
+
+static struct platform_driver msm_smd_driver = {
+ .probe = msm_smd_probe,
+ .driver = {
+ .name = MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_smd_init(void)
+{
+ return platform_driver_register(&msm_smd_driver);
+}
+
+module_init(msm_smd_init);
+
+MODULE_DESCRIPTION("MSM Shared Memory Core");
+MODULE_AUTHOR("Brian Swetland <swetland@google.com>");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c
new file mode 100644
index 00000000..8736afff
--- /dev/null
+++ b/arch/arm/mach-msm/smd_debug.c
@@ -0,0 +1,318 @@
+/* arch/arm/mach-msm/smd_debug.c
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/list.h>
+
+#include <mach/msm_iomap.h>
+
+#include "smd_private.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+static char *chstate(unsigned n)
+{
+ switch (n) {
+ case SMD_SS_CLOSED:
+ return "CLOSED";
+ case SMD_SS_OPENING:
+ return "OPENING";
+ case SMD_SS_OPENED:
+ return "OPENED";
+ case SMD_SS_FLUSHING:
+ return "FLUSHING";
+ case SMD_SS_CLOSING:
+ return "CLOSING";
+ case SMD_SS_RESET:
+ return "RESET";
+ case SMD_SS_RESET_OPENING:
+ return "ROPENING";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+
+static int dump_ch(char *buf, int max, struct smd_channel *ch)
+{
+ volatile struct smd_half_channel *s = ch->send;
+ volatile struct smd_half_channel *r = ch->recv;
+
+ return scnprintf(
+ buf, max,
+ "ch%02d:"
+ " %8s(%05d/%05d) %c%c%c%c%c%c%c <->"
+ " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n,
+ chstate(s->state), s->tail, s->head,
+ s->fDSR ? 'D' : 'd',
+ s->fCTS ? 'C' : 'c',
+ s->fCD ? 'C' : 'c',
+ s->fRI ? 'I' : 'i',
+ s->fHEAD ? 'W' : 'w',
+ s->fTAIL ? 'R' : 'r',
+ s->fSTATE ? 'S' : 's',
+ chstate(r->state), r->tail, r->head,
+ r->fDSR ? 'D' : 'd',
+ r->fCTS ? 'R' : 'r',
+ r->fCD ? 'C' : 'c',
+ r->fRI ? 'I' : 'i',
+ r->fHEAD ? 'W' : 'w',
+ r->fTAIL ? 'R' : 'r',
+ r->fSTATE ? 'S' : 's',
+ ch->name
+ );
+}
+
+static int debug_read_stat(char *buf, int max)
+{
+ char *msg;
+ int i = 0;
+
+ msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG);
+
+ if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET)
+ i += scnprintf(buf + i, max - i,
+ "smsm: ARM9 HAS CRASHED\n");
+
+ i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n",
+ raw_smsm_get_state(SMSM_STATE_MODEM),
+ raw_smsm_get_state(SMSM_STATE_APPS));
+#ifdef CONFIG_ARCH_MSM_SCORPION
+ i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x "
+ "qdsp6: %08x power: %08x time: %08x\n",
+ raw_smsm_get_state(SMSM_STATE_APPS_DEM),
+ raw_smsm_get_state(SMSM_STATE_MODEM_DEM),
+ raw_smsm_get_state(SMSM_STATE_QDSP6_DEM),
+ raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM),
+ raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM));
+#endif
+ if (msg) {
+ msg[SZ_DIAG_ERR_MSG - 1] = 0;
+ i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg);
+ }
+ return i;
+}
+
+static int debug_read_mem(char *buf, int max)
+{
+ unsigned n;
+ struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+ struct smem_heap_entry *toc = shared->heap_toc;
+ int i = 0;
+
+ i += scnprintf(buf + i, max - i,
+ "heap: init=%d free=%d remain=%d\n",
+ shared->heap_info.initialized,
+ shared->heap_info.free_offset,
+ shared->heap_info.heap_remaining);
+
+ for (n = 0; n < SMEM_NUM_ITEMS; n++) {
+ if (toc[n].allocated == 0)
+ continue;
+ i += scnprintf(buf + i, max - i,
+ "%04d: offset %08x size %08x\n",
+ n, toc[n].offset, toc[n].size);
+ }
+ return i;
+}
+
+static int debug_read_ch(char *buf, int max)
+{
+ struct smd_channel *ch;
+ unsigned long flags;
+ int i = 0;
+
+ spin_lock_irqsave(&smd_lock, flags);
+ list_for_each_entry(ch, &smd_ch_list_dsp, ch_list)
+ i += dump_ch(buf + i, max - i, ch);
+ list_for_each_entry(ch, &smd_ch_list_modem, ch_list)
+ i += dump_ch(buf + i, max - i, ch);
+ list_for_each_entry(ch, &smd_ch_closed_list, ch_list)
+ i += dump_ch(buf + i, max - i, ch);
+ spin_unlock_irqrestore(&smd_lock, flags);
+
+ return i;
+}
+
+static int debug_read_version(char *buf, int max)
+{
+ struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE;
+ unsigned version = shared->version[VERSION_MODEM];
+ return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff);
+}
+
+static int debug_read_build_id(char *buf, int max)
+{
+ unsigned size;
+ void *data;
+
+ data = smem_item(SMEM_HW_SW_BUILD_ID, &size);
+ if (!data)
+ return 0;
+
+ if (size >= max)
+ size = max;
+ memcpy(buf, data, size);
+
+ return size;
+}
+
+static int debug_read_alloc_tbl(char *buf, int max)
+{
+ struct smd_alloc_elm *shared;
+ int n, i = 0;
+
+ shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64);
+
+ for (n = 0; n < 64; n++) {
+ if (shared[n].ref_count == 0)
+ continue;
+ i += scnprintf(buf + i, max - i,
+ "%03d: %-20s cid=%02d type=%03d "
+ "kind=%02d ref_count=%d\n",
+ n, shared[n].name, shared[n].cid,
+ shared[n].ctype & 0xff,
+ (shared[n].ctype >> 8) & 0xf,
+ shared[n].ref_count);
+ }
+
+ return i;
+}
+
+#define DEBUG_BUFMAX 4096
+static char debug_buffer[DEBUG_BUFMAX];
+
+static ssize_t debug_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int (*fill)(char *buf, int max) = file->private_data;
+ int bsize = fill(debug_buffer, DEBUG_BUFMAX);
+ return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize);
+}
+
+static int debug_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static const struct file_operations debug_ops = {
+ .read = debug_read,
+ .open = debug_open,
+ .llseek = default_llseek,
+};
+
+static void debug_create(const char *name, mode_t mode,
+ struct dentry *dent,
+ int (*fill)(char *buf, int max))
+{
+ debugfs_create_file(name, mode, dent, fill, &debug_ops);
+}
+
+static int smd_debugfs_init(void)
+{
+ struct dentry *dent;
+
+ dent = debugfs_create_dir("smd", 0);
+ if (IS_ERR(dent))
+ return 1;
+
+ debug_create("ch", 0444, dent, debug_read_ch);
+ debug_create("stat", 0444, dent, debug_read_stat);
+ debug_create("mem", 0444, dent, debug_read_mem);
+ debug_create("version", 0444, dent, debug_read_version);
+ debug_create("tbl", 0444, dent, debug_read_alloc_tbl);
+ debug_create("build", 0444, dent, debug_read_build_id);
+
+ return 0;
+}
+
+late_initcall(smd_debugfs_init);
+#endif
+
+
+#define MAX_NUM_SLEEP_CLIENTS 64
+#define MAX_SLEEP_NAME_LEN 8
+
+#define NUM_GPIO_INT_REGISTERS 6
+#define GPIO_SMEM_NUM_GROUPS 2
+#define GPIO_SMEM_MAX_PC_INTERRUPTS 8
+
+struct tramp_gpio_save {
+ unsigned int enable;
+ unsigned int detect;
+ unsigned int polarity;
+};
+
+struct tramp_gpio_smem {
+ uint16_t num_fired[GPIO_SMEM_NUM_GROUPS];
+ uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS];
+ uint32_t enabled[NUM_GPIO_INT_REGISTERS];
+ uint32_t detection[NUM_GPIO_INT_REGISTERS];
+ uint32_t polarity[NUM_GPIO_INT_REGISTERS];
+};
+
+
+void smsm_print_sleep_info(void)
+{
+ unsigned long flags;
+ uint32_t *ptr;
+#ifndef CONFIG_ARCH_MSM_SCORPION
+ struct tramp_gpio_smem *gpio;
+ struct smsm_interrupt_info *int_info;
+#endif
+
+
+ spin_lock_irqsave(&smem_lock, flags);
+
+ ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr));
+ if (ptr)
+ pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr);
+
+ ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr));
+ if (ptr)
+ pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr);
+
+ ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr));
+ if (ptr)
+ pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr);
+
+#ifndef CONFIG_ARCH_MSM_SCORPION
+ int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info));
+ if (int_info)
+ pr_info("SMEM_SMSM_INT_INFO %x %x %x\n",
+ int_info->interrupt_mask,
+ int_info->pending_interrupts,
+ int_info->wakeup_reason);
+
+ gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio));
+ if (gpio) {
+ int i;
+ for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++)
+ pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n",
+ i, gpio->enabled[i], gpio->detection[i],
+ gpio->polarity[i]);
+
+ for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++)
+ pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n",
+ i, gpio->num_fired[i], gpio->fired[i][0],
+ gpio->fired[i][1]);
+ }
+#else
+#endif
+ spin_unlock_irqrestore(&smem_lock, flags);
+}
+
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h
new file mode 100644
index 00000000..727bfe68
--- /dev/null
+++ b/arch/arm/mach-msm/smd_private.h
@@ -0,0 +1,403 @@
+/* arch/arm/mach-msm/smd_private.h
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2007 QUALCOMM Incorporated
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+#define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_
+
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <mach/msm_iomap.h>
+
+struct smem_heap_info {
+ unsigned initialized;
+ unsigned free_offset;
+ unsigned heap_remaining;
+ unsigned reserved;
+};
+
+struct smem_heap_entry {
+ unsigned allocated;
+ unsigned offset;
+ unsigned size;
+ unsigned reserved;
+};
+
+struct smem_proc_comm {
+ unsigned command;
+ unsigned status;
+ unsigned data1;
+ unsigned data2;
+};
+
+#define PC_APPS 0
+#define PC_MODEM 1
+
+#define VERSION_SMD 0
+#define VERSION_QDSP6 4
+#define VERSION_APPS_SBL 6
+#define VERSION_MODEM_SBL 7
+#define VERSION_APPS 8
+#define VERSION_MODEM 9
+
+struct smem_shared {
+ struct smem_proc_comm proc_comm[4];
+ unsigned version[32];
+ struct smem_heap_info heap_info;
+ struct smem_heap_entry heap_toc[512];
+};
+
+#define SMSM_V1_SIZE (sizeof(unsigned) * 8)
+#define SMSM_V2_SIZE (sizeof(unsigned) * 4)
+
+#ifdef CONFIG_MSM_SMD_PKG3
+struct smsm_interrupt_info {
+ uint32_t interrupt_mask;
+ uint32_t pending_interrupts;
+ uint32_t wakeup_reason;
+};
+#else
+#define DEM_MAX_PORT_NAME_LEN (20)
+struct msm_dem_slave_data {
+ uint32_t sleep_time;
+ uint32_t interrupt_mask;
+ uint32_t resources_used;
+ uint32_t reserved1;
+
+ uint32_t wakeup_reason;
+ uint32_t pending_interrupts;
+ uint32_t rpc_prog;
+ uint32_t rpc_proc;
+ char smd_port_name[DEM_MAX_PORT_NAME_LEN];
+ uint32_t reserved2;
+};
+#endif
+
+#define SZ_DIAG_ERR_MSG 0xC8
+#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
+#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
+#define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE
+#define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL
+
+#define SMSM_INIT 0x00000001
+#define SMSM_SMDINIT 0x00000008
+#define SMSM_RPCINIT 0x00000020
+#define SMSM_RESET 0x00000040
+#define SMSM_RSA 0x00000080
+#define SMSM_RUN 0x00000100
+#define SMSM_PWRC 0x00000200
+#define SMSM_TIMEWAIT 0x00000400
+#define SMSM_TIMEINIT 0x00000800
+#define SMSM_PWRC_EARLY_EXIT 0x00001000
+#define SMSM_WFPI 0x00002000
+#define SMSM_SLEEP 0x00004000
+#define SMSM_SLEEPEXIT 0x00008000
+#define SMSM_APPS_REBOOT 0x00020000
+#define SMSM_SYSTEM_POWER_DOWN 0x00040000
+#define SMSM_SYSTEM_REBOOT 0x00080000
+#define SMSM_SYSTEM_DOWNLOAD 0x00100000
+#define SMSM_PWRC_SUSPEND 0x00200000
+#define SMSM_APPS_SHUTDOWN 0x00400000
+#define SMSM_SMD_LOOPBACK 0x00800000
+#define SMSM_RUN_QUIET 0x01000000
+#define SMSM_MODEM_WAIT 0x02000000
+#define SMSM_MODEM_BREAK 0x04000000
+#define SMSM_MODEM_CONTINUE 0x08000000
+#define SMSM_UNKNOWN 0x80000000
+
+#define SMSM_WKUP_REASON_RPC 0x00000001
+#define SMSM_WKUP_REASON_INT 0x00000002
+#define SMSM_WKUP_REASON_GPIO 0x00000004
+#define SMSM_WKUP_REASON_TIMER 0x00000008
+#define SMSM_WKUP_REASON_ALARM 0x00000010
+#define SMSM_WKUP_REASON_RESET 0x00000020
+
+#ifdef CONFIG_ARCH_MSM7X00A
+enum smsm_state_item {
+ SMSM_STATE_APPS = 1,
+ SMSM_STATE_MODEM = 3,
+ SMSM_STATE_COUNT,
+};
+#else
+enum smsm_state_item {
+ SMSM_STATE_APPS,
+ SMSM_STATE_MODEM,
+ SMSM_STATE_HEXAGON,
+ SMSM_STATE_APPS_DEM,
+ SMSM_STATE_MODEM_DEM,
+ SMSM_STATE_QDSP6_DEM,
+ SMSM_STATE_POWER_MASTER_DEM,
+ SMSM_STATE_TIME_MASTER_DEM,
+ SMSM_STATE_COUNT,
+};
+#endif
+
+void *smem_alloc(unsigned id, unsigned size);
+int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask);
+uint32_t smsm_get_state(enum smsm_state_item item);
+int smsm_set_sleep_duration(uint32_t delay);
+void smsm_print_sleep_info(void);
+
+#define SMEM_NUM_SMD_CHANNELS 64
+
+typedef enum {
+ /* fixed items */
+ SMEM_PROC_COMM = 0,
+ SMEM_HEAP_INFO,
+ SMEM_ALLOCATION_TABLE,
+ SMEM_VERSION_INFO,
+ SMEM_HW_RESET_DETECT,
+ SMEM_AARM_WARM_BOOT,
+ SMEM_DIAG_ERR_MESSAGE,
+ SMEM_SPINLOCK_ARRAY,
+ SMEM_MEMORY_BARRIER_LOCATION,
+
+ /* dynamic items */
+ SMEM_AARM_PARTITION_TABLE,
+ SMEM_AARM_BAD_BLOCK_TABLE,
+ SMEM_RESERVE_BAD_BLOCKS,
+ SMEM_WM_UUID,
+ SMEM_CHANNEL_ALLOC_TBL,
+ SMEM_SMD_BASE_ID,
+ SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+ SMEM_SMEM_LOG_EVENTS,
+ SMEM_SMEM_STATIC_LOG_IDX,
+ SMEM_SMEM_STATIC_LOG_EVENTS,
+ SMEM_SMEM_SLOW_CLOCK_SYNC,
+ SMEM_SMEM_SLOW_CLOCK_VALUE,
+ SMEM_BIO_LED_BUF,
+ SMEM_SMSM_SHARED_STATE,
+ SMEM_SMSM_INT_INFO,
+ SMEM_SMSM_SLEEP_DELAY,
+ SMEM_SMSM_LIMIT_SLEEP,
+ SMEM_SLEEP_POWER_COLLAPSE_DISABLED,
+ SMEM_KEYPAD_KEYS_PRESSED,
+ SMEM_KEYPAD_STATE_UPDATED,
+ SMEM_KEYPAD_STATE_IDX,
+ SMEM_GPIO_INT,
+ SMEM_MDDI_LCD_IDX,
+ SMEM_MDDI_HOST_DRIVER_STATE,
+ SMEM_MDDI_LCD_DISP_STATE,
+ SMEM_LCD_CUR_PANEL,
+ SMEM_MARM_BOOT_SEGMENT_INFO,
+ SMEM_AARM_BOOT_SEGMENT_INFO,
+ SMEM_SLEEP_STATIC,
+ SMEM_SCORPION_FREQUENCY,
+ SMEM_SMD_PROFILES,
+ SMEM_TSSC_BUSY,
+ SMEM_HS_SUSPEND_FILTER_INFO,
+ SMEM_BATT_INFO,
+ SMEM_APPS_BOOT_MODE,
+ SMEM_VERSION_FIRST,
+ SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
+ SMEM_OSS_RRCASN1_BUF1,
+ SMEM_OSS_RRCASN1_BUF2,
+ SMEM_ID_VENDOR0,
+ SMEM_ID_VENDOR1,
+ SMEM_ID_VENDOR2,
+ SMEM_HW_SW_BUILD_ID,
+ SMEM_SMD_BLOCK_PORT_BASE_ID,
+ SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+ SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS,
+ SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS,
+ SMEM_SCLK_CONVERSION,
+ SMEM_SMD_SMSM_INTR_MUX,
+ SMEM_SMSM_CPU_INTR_MASK,
+ SMEM_APPS_DEM_SLAVE_DATA,
+ SMEM_QDSP6_DEM_SLAVE_DATA,
+ SMEM_CLKREGIM_BSP,
+ SMEM_CLKREGIM_SOURCES,
+ SMEM_SMD_FIFO_BASE_ID,
+ SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS,
+ SMEM_POWER_ON_STATUS_INFO,
+ SMEM_DAL_AREA,
+ SMEM_SMEM_LOG_POWER_IDX,
+ SMEM_SMEM_LOG_POWER_WRAP,
+ SMEM_SMEM_LOG_POWER_EVENTS,
+ SMEM_ERR_CRASH_LOG,
+ SMEM_ERR_F3_TRACE_LOG,
+ SMEM_NUM_ITEMS,
+} smem_mem_type;
+
+
+#define SMD_SS_CLOSED 0x00000000
+#define SMD_SS_OPENING 0x00000001
+#define SMD_SS_OPENED 0x00000002
+#define SMD_SS_FLUSHING 0x00000003
+#define SMD_SS_CLOSING 0x00000004
+#define SMD_SS_RESET 0x00000005
+#define SMD_SS_RESET_OPENING 0x00000006
+
+#define SMD_BUF_SIZE 8192
+#define SMD_CHANNELS 64
+
+#define SMD_HEADER_SIZE 20
+
+struct smd_alloc_elm {
+ char name[20];
+ uint32_t cid;
+ uint32_t ctype;
+ uint32_t ref_count;
+};
+
+struct smd_half_channel {
+ unsigned state;
+ unsigned char fDSR;
+ unsigned char fCTS;
+ unsigned char fCD;
+ unsigned char fRI;
+ unsigned char fHEAD;
+ unsigned char fTAIL;
+ unsigned char fSTATE;
+ unsigned char fUNUSED;
+ unsigned tail;
+ unsigned head;
+} __attribute__(( aligned(4), packed ));
+
+/* Only used on SMD package v3 on msm7201a */
+struct smd_shared_v1 {
+ struct smd_half_channel ch0;
+ unsigned char data0[SMD_BUF_SIZE];
+ struct smd_half_channel ch1;
+ unsigned char data1[SMD_BUF_SIZE];
+};
+
+/* Used on SMD package v4 */
+struct smd_shared_v2 {
+ struct smd_half_channel ch0;
+ struct smd_half_channel ch1;
+};
+
+struct smd_channel {
+ volatile struct smd_half_channel *send;
+ volatile struct smd_half_channel *recv;
+ unsigned char *send_data;
+ unsigned char *recv_data;
+
+ unsigned fifo_mask;
+ unsigned fifo_size;
+ unsigned current_packet;
+ unsigned n;
+
+ struct list_head ch_list;
+
+ void *priv;
+ void (*notify)(void *priv, unsigned flags);
+
+ int (*read)(struct smd_channel *ch, void *data, int len);
+ int (*write)(struct smd_channel *ch, const void *data, int len);
+ int (*read_avail)(struct smd_channel *ch);
+ int (*write_avail)(struct smd_channel *ch);
+
+ void (*update_state)(struct smd_channel *ch);
+ unsigned last_state;
+ void (*notify_other_cpu)(void);
+ unsigned type;
+
+ char name[32];
+ struct platform_device pdev;
+};
+
+#define SMD_TYPE_MASK 0x0FF
+#define SMD_TYPE_APPS_MODEM 0x000
+#define SMD_TYPE_APPS_DSP 0x001
+#define SMD_TYPE_MODEM_DSP 0x002
+
+#define SMD_KIND_MASK 0xF00
+#define SMD_KIND_UNKNOWN 0x000
+#define SMD_KIND_STREAM 0x100
+#define SMD_KIND_PACKET 0x200
+
+extern struct list_head smd_ch_closed_list;
+extern struct list_head smd_ch_list_modem;
+extern struct list_head smd_ch_list_dsp;
+
+extern spinlock_t smd_lock;
+extern spinlock_t smem_lock;
+
+void *smem_find(unsigned id, unsigned size);
+void *smem_item(unsigned id, unsigned *size);
+uint32_t raw_smsm_get_state(enum smsm_state_item item);
+
+extern void msm_init_last_radio_log(struct module *);
+
+#ifdef CONFIG_MSM_SMD_PKG3
+/*
+ * This allocator assumes an SMD Package v3 which only exists on
+ * MSM7x00 SoC's.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+ struct smd_shared_v1 *shared1;
+
+ shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1));
+ if (!shared1) {
+ pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n);
+ return -1;
+ }
+ ch->send = &shared1->ch0;
+ ch->recv = &shared1->ch1;
+ ch->send_data = shared1->data0;
+ ch->recv_data = shared1->data1;
+ ch->fifo_size = SMD_BUF_SIZE;
+ return 0;
+}
+#else
+/*
+ * This allocator assumes an SMD Package v4, the most common
+ * and the default.
+ */
+static inline int _smd_alloc_channel(struct smd_channel *ch)
+{
+ struct smd_shared_v2 *shared2;
+ void *buffer;
+ unsigned buffer_sz;
+
+ shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2));
+ buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz);
+
+ if (!buffer)
+ return -1;
+
+ /* buffer must be a power-of-two size */
+ if (buffer_sz & (buffer_sz - 1))
+ return -1;
+
+ buffer_sz /= 2;
+ ch->send = &shared2->ch0;
+ ch->recv = &shared2->ch1;
+ ch->send_data = buffer;
+ ch->recv_data = buffer + buffer_sz;
+ ch->fifo_size = buffer_sz;
+ return 0;
+}
+#endif /* CONFIG_MSM_SMD_PKG3 */
+
+#if defined(CONFIG_ARCH_MSM7X30)
+static inline void msm_a2m_int(uint32_t irq)
+{
+ writel(1 << irq, MSM_GCC_BASE + 0x8);
+}
+#else
+static inline void msm_a2m_int(uint32_t irq)
+{
+ writel(1, MSM_CSR_BASE + 0x400 + (irq * 4));
+}
+#endif /* CONFIG_ARCH_MSM7X30 */
+
+
+#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
new file mode 100644
index 00000000..63621f15
--- /dev/null
+++ b/arch/arm/mach-msm/timer.c
@@ -0,0 +1,318 @@
+/* linux/arch/arm/mach-msm/timer.c
+ *
+ * Copyright (C) 2007 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/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
+#include <mach/msm_iomap.h>
+#include <mach/cpu.h>
+
+#define TIMER_MATCH_VAL 0x0000
+#define TIMER_COUNT_VAL 0x0004
+#define TIMER_ENABLE 0x0008
+#define TIMER_ENABLE_CLR_ON_MATCH_EN 2
+#define TIMER_ENABLE_EN 1
+#define TIMER_CLEAR 0x000C
+#define DGT_CLK_CTL 0x0034
+enum {
+ DGT_CLK_CTL_DIV_1 = 0,
+ DGT_CLK_CTL_DIV_2 = 1,
+ DGT_CLK_CTL_DIV_3 = 2,
+ DGT_CLK_CTL_DIV_4 = 3,
+};
+#define CSR_PROTECTION 0x0020
+#define CSR_PROTECTION_EN 1
+
+#define GPT_HZ 32768
+
+enum timer_location {
+ LOCAL_TIMER = 0,
+ GLOBAL_TIMER = 1,
+};
+
+#define MSM_GLOBAL_TIMER MSM_CLOCK_DGT
+
+/* TODO: Remove these ifdefs */
+#if defined(CONFIG_ARCH_QSD8X50)
+#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM7X30)
+#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
+#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
+#else
+#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
+#define MSM_DGT_SHIFT (5)
+#endif
+
+struct msm_clock {
+ struct clock_event_device clockevent;
+ struct clocksource clocksource;
+ struct irqaction irq;
+ void __iomem *regbase;
+ uint32_t freq;
+ uint32_t shift;
+ void __iomem *global_counter;
+ void __iomem *local_counter;
+};
+
+enum {
+ MSM_CLOCK_GPT,
+ MSM_CLOCK_DGT,
+ NR_TIMERS,
+};
+
+
+static struct msm_clock msm_clocks[];
+static struct clock_event_device *local_clock_event;
+
+static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+ if (smp_processor_id() != 0)
+ evt = local_clock_event;
+ if (evt->event_handler == NULL)
+ return IRQ_HANDLED;
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static cycle_t msm_read_timer_count(struct clocksource *cs)
+{
+ struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource);
+
+ /*
+ * Shift timer count down by a constant due to unreliable lower bits
+ * on some targets.
+ */
+ return readl(clk->global_counter) >> clk->shift;
+}
+
+static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt)
+{
+#ifdef CONFIG_SMP
+ int i;
+ for (i = 0; i < NR_TIMERS; i++)
+ if (evt == &(msm_clocks[i].clockevent))
+ return &msm_clocks[i];
+ return &msm_clocks[MSM_GLOBAL_TIMER];
+#else
+ return container_of(evt, struct msm_clock, clockevent);
+#endif
+}
+
+static int msm_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ struct msm_clock *clock = clockevent_to_clock(evt);
+ uint32_t now = readl(clock->local_counter);
+ uint32_t alarm = now + (cycles << clock->shift);
+
+ writel(alarm, clock->regbase + TIMER_MATCH_VAL);
+ return 0;
+}
+
+static void msm_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct msm_clock *clock = clockevent_to_clock(evt);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ writel(0, clock->regbase + TIMER_ENABLE);
+ break;
+ }
+}
+
+static struct msm_clock msm_clocks[] = {
+ [MSM_CLOCK_GPT] = {
+ .clockevent = {
+ .name = "gp_timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 200,
+ .set_next_event = msm_timer_set_next_event,
+ .set_mode = msm_timer_set_mode,
+ },
+ .clocksource = {
+ .name = "gp_timer",
+ .rating = 200,
+ .read = msm_read_timer_count,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+ .irq = {
+ .name = "gp_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+ .handler = msm_timer_interrupt,
+ .dev_id = &msm_clocks[0].clockevent,
+ .irq = INT_GP_TIMER_EXP
+ },
+ .freq = GPT_HZ,
+ },
+ [MSM_CLOCK_DGT] = {
+ .clockevent = {
+ .name = "dg_timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32 + MSM_DGT_SHIFT,
+ .rating = 300,
+ .set_next_event = msm_timer_set_next_event,
+ .set_mode = msm_timer_set_mode,
+ },
+ .clocksource = {
+ .name = "dg_timer",
+ .rating = 300,
+ .read = msm_read_timer_count,
+ .mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT)),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+ .irq = {
+ .name = "dg_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_RISING,
+ .handler = msm_timer_interrupt,
+ .dev_id = &msm_clocks[1].clockevent,
+ .irq = INT_DEBUG_TIMER_EXP
+ },
+ .freq = DGT_HZ >> MSM_DGT_SHIFT,
+ .shift = MSM_DGT_SHIFT,
+ }
+};
+
+static void __init msm_timer_init(void)
+{
+ int i;
+ int res;
+ int global_offset = 0;
+
+ if (cpu_is_msm7x01()) {
+ msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
+ msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
+ } else if (cpu_is_msm7x30()) {
+ msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE + 0x04;
+ msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x24;
+ } else if (cpu_is_qsd8x50()) {
+ msm_clocks[MSM_CLOCK_GPT].regbase = MSM_CSR_BASE;
+ msm_clocks[MSM_CLOCK_DGT].regbase = MSM_CSR_BASE + 0x10;
+ } else if (cpu_is_msm8x60() || cpu_is_msm8960()) {
+ msm_clocks[MSM_CLOCK_GPT].regbase = MSM_TMR_BASE + 0x04;
+ msm_clocks[MSM_CLOCK_DGT].regbase = MSM_TMR_BASE + 0x24;
+
+ /* Use CPU0's timer as the global timer. */
+ global_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
+ } else
+ BUG();
+
+#ifdef CONFIG_ARCH_MSM_SCORPIONMP
+ writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
+ struct msm_clock *clock = &msm_clocks[i];
+ struct clock_event_device *ce = &clock->clockevent;
+ struct clocksource *cs = &clock->clocksource;
+
+ clock->local_counter = clock->regbase + TIMER_COUNT_VAL;
+ clock->global_counter = clock->local_counter + global_offset;
+
+ writel(0, clock->regbase + TIMER_ENABLE);
+ writel(0, clock->regbase + TIMER_CLEAR);
+ writel(~0, clock->regbase + TIMER_MATCH_VAL);
+
+ ce->mult = div_sc(clock->freq, NSEC_PER_SEC, ce->shift);
+ /* allow at least 10 seconds to notice that the timer wrapped */
+ ce->max_delta_ns =
+ clockevent_delta2ns(0xf0000000 >> clock->shift, ce);
+ /* 4 gets rounded down to 3 */
+ ce->min_delta_ns = clockevent_delta2ns(4, ce);
+ ce->cpumask = cpumask_of(0);
+
+ res = clocksource_register_hz(cs, clock->freq);
+ if (res)
+ printk(KERN_ERR "msm_timer_init: clocksource_register "
+ "failed for %s\n", cs->name);
+
+ res = setup_irq(clock->irq.irq, &clock->irq);
+ if (res)
+ printk(KERN_ERR "msm_timer_init: setup_irq "
+ "failed for %s\n", cs->name);
+
+ clockevents_register_device(ce);
+ }
+}
+
+#ifdef CONFIG_SMP
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
+
+ /* Use existing clock_event for cpu 0 */
+ if (!smp_processor_id())
+ return 0;
+
+ writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+
+ if (!local_clock_event) {
+ writel(0, clock->regbase + TIMER_ENABLE);
+ writel(0, clock->regbase + TIMER_CLEAR);
+ writel(~0, clock->regbase + TIMER_MATCH_VAL);
+ }
+ evt->irq = clock->irq.irq;
+ evt->name = "local_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ evt->rating = clock->clockevent.rating;
+ evt->set_mode = msm_timer_set_mode;
+ evt->set_next_event = msm_timer_set_next_event;
+ evt->shift = clock->clockevent.shift;
+ evt->mult = div_sc(clock->freq, NSEC_PER_SEC, evt->shift);
+ evt->max_delta_ns =
+ clockevent_delta2ns(0xf0000000 >> clock->shift, evt);
+ evt->min_delta_ns = clockevent_delta2ns(4, evt);
+
+ local_clock_event = evt;
+
+ gic_enable_ppi(clock->irq.irq);
+
+ clockevents_register_device(evt);
+ return 0;
+}
+
+inline int local_timer_ack(void)
+{
+ return 1;
+}
+
+#endif
+
+struct sys_timer msm_timer = {
+ .init = msm_timer_init
+};
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c
new file mode 100644
index 00000000..a9103bc6
--- /dev/null
+++ b/arch/arm/mach-msm/vreg.c
@@ -0,0 +1,219 @@
+/* arch/arm/mach-msm/vreg.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ * Author: Brian Swetland <swetland@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/string.h>
+#include <mach/vreg.h>
+
+#include "proc_comm.h"
+
+struct vreg {
+ const char *name;
+ unsigned id;
+ int status;
+ unsigned refcnt;
+};
+
+#define VREG(_name, _id, _status, _refcnt) \
+ { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt }
+
+static struct vreg vregs[] = {
+ VREG("msma", 0, 0, 0),
+ VREG("msmp", 1, 0, 0),
+ VREG("msme1", 2, 0, 0),
+ VREG("msmc1", 3, 0, 0),
+ VREG("msmc2", 4, 0, 0),
+ VREG("gp3", 5, 0, 0),
+ VREG("msme2", 6, 0, 0),
+ VREG("gp4", 7, 0, 0),
+ VREG("gp1", 8, 0, 0),
+ VREG("tcxo", 9, 0, 0),
+ VREG("pa", 10, 0, 0),
+ VREG("rftx", 11, 0, 0),
+ VREG("rfrx1", 12, 0, 0),
+ VREG("rfrx2", 13, 0, 0),
+ VREG("synt", 14, 0, 0),
+ VREG("wlan", 15, 0, 0),
+ VREG("usb", 16, 0, 0),
+ VREG("boost", 17, 0, 0),
+ VREG("mmc", 18, 0, 0),
+ VREG("ruim", 19, 0, 0),
+ VREG("msmc0", 20, 0, 0),
+ VREG("gp2", 21, 0, 0),
+ VREG("gp5", 22, 0, 0),
+ VREG("gp6", 23, 0, 0),
+ VREG("rf", 24, 0, 0),
+ VREG("rf_vco", 26, 0, 0),
+ VREG("mpll", 27, 0, 0),
+ VREG("s2", 28, 0, 0),
+ VREG("s3", 29, 0, 0),
+ VREG("rfubm", 30, 0, 0),
+ VREG("ncp", 31, 0, 0),
+ VREG("gp7", 32, 0, 0),
+ VREG("gp8", 33, 0, 0),
+ VREG("gp9", 34, 0, 0),
+ VREG("gp10", 35, 0, 0),
+ VREG("gp11", 36, 0, 0),
+ VREG("gp12", 37, 0, 0),
+ VREG("gp13", 38, 0, 0),
+ VREG("gp14", 39, 0, 0),
+ VREG("gp15", 40, 0, 0),
+ VREG("gp16", 41, 0, 0),
+ VREG("gp17", 42, 0, 0),
+ VREG("s4", 43, 0, 0),
+ VREG("usb2", 44, 0, 0),
+ VREG("wlan2", 45, 0, 0),
+ VREG("xo_out", 46, 0, 0),
+ VREG("lvsw0", 47, 0, 0),
+ VREG("lvsw1", 48, 0, 0),
+};
+
+struct vreg *vreg_get(struct device *dev, const char *id)
+{
+ int n;
+ for (n = 0; n < ARRAY_SIZE(vregs); n++) {
+ if (!strcmp(vregs[n].name, id))
+ return vregs + n;
+ }
+ return ERR_PTR(-ENOENT);
+}
+
+void vreg_put(struct vreg *vreg)
+{
+}
+
+int vreg_enable(struct vreg *vreg)
+{
+ unsigned id = vreg->id;
+ unsigned enable = 1;
+
+ if (vreg->refcnt == 0)
+ vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+ if ((vreg->refcnt < UINT_MAX) && (!vreg->status))
+ vreg->refcnt++;
+
+ return vreg->status;
+}
+
+int vreg_disable(struct vreg *vreg)
+{
+ unsigned id = vreg->id;
+ unsigned enable = 0;
+
+ if (!vreg->refcnt)
+ return 0;
+
+ if (vreg->refcnt == 1)
+ vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
+
+ if (!vreg->status)
+ vreg->refcnt--;
+
+ return vreg->status;
+}
+
+int vreg_set_level(struct vreg *vreg, unsigned mv)
+{
+ unsigned id = vreg->id;
+
+ vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
+ return vreg->status;
+}
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int vreg_debug_set(void *data, u64 val)
+{
+ struct vreg *vreg = data;
+ switch (val) {
+ case 0:
+ vreg_disable(vreg);
+ break;
+ case 1:
+ vreg_enable(vreg);
+ break;
+ default:
+ vreg_set_level(vreg, val);
+ break;
+ }
+ return 0;
+}
+
+static int vreg_debug_get(void *data, u64 *val)
+{
+ struct vreg *vreg = data;
+
+ if (!vreg->status)
+ *val = 0;
+ else
+ *val = 1;
+
+ return 0;
+}
+
+static int vreg_debug_count_set(void *data, u64 val)
+{
+ struct vreg *vreg = data;
+ if (val > UINT_MAX)
+ val = UINT_MAX;
+ vreg->refcnt = val;
+ return 0;
+}
+
+static int vreg_debug_count_get(void *data, u64 *val)
+{
+ struct vreg *vreg = data;
+
+ *val = vreg->refcnt;
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get,
+ vreg_debug_count_set, "%llu\n");
+
+static int __init vreg_debug_init(void)
+{
+ struct dentry *dent;
+ int n;
+ char name[32];
+ const char *refcnt_name = "_refcnt";
+
+ dent = debugfs_create_dir("vreg", 0);
+ if (IS_ERR(dent))
+ return 0;
+
+ for (n = 0; n < ARRAY_SIZE(vregs); n++) {
+ (void) debugfs_create_file(vregs[n].name, 0644,
+ dent, vregs + n, &vreg_fops);
+
+ strlcpy(name, vregs[n].name, sizeof(name));
+ strlcat(name, refcnt_name, sizeof(name));
+ (void) debugfs_create_file(name, 0644,
+ dent, vregs + n, &vreg_count_fops);
+ }
+
+ return 0;
+}
+
+device_initcall(vreg_debug_init);
+#endif
diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig
new file mode 100644
index 00000000..f2d309d0
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/Kconfig
@@ -0,0 +1,25 @@
+if ARCH_MV78XX0
+
+menu "Marvell MV78xx0 Implementations"
+
+config MACH_DB78X00_BP
+ bool "Marvell DB-78x00-BP Development Board"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell DB-78x00-BP Development Board.
+
+config MACH_RD78X00_MASA
+ bool "Marvell RD-78x00-mASA Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell RD-78x00-mASA Reference Design.
+
+config MACH_TERASTATION_WXL
+ bool "Buffalo WLX (Terastation Duo) NAS"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo WXL Nas.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-mv78xx0/Makefile b/arch/arm/mach-mv78xx0/Makefile
new file mode 100644
index 00000000..67a13f9b
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/Makefile
@@ -0,0 +1,4 @@
+obj-y += common.o addr-map.o mpp.o irq.o pcie.o
+obj-$(CONFIG_MACH_DB78X00_BP) += db78x00-bp-setup.o
+obj-$(CONFIG_MACH_RD78X00_MASA) += rd78x00-masa-setup.o
+obj-$(CONFIG_MACH_TERASTATION_WXL) += buffalo-wxl-setup.o
diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-mv78xx0/addr-map.c b/arch/arm/mach-mv78xx0/addr-map.c
new file mode 100644
index 00000000..311d5b0e
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/addr-map.c
@@ -0,0 +1,156 @@
+/*
+ * arch/arm/mach-mv78xx0/addr-map.c
+ *
+ * Address map functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include "common.h"
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR 0
+#define TARGET_DEV_BUS 1
+#define TARGET_PCIE0 4
+#define TARGET_PCIE1 8
+#define TARGET_PCIE(i) ((i) ? TARGET_PCIE1 : TARGET_PCIE0)
+#define ATTR_DEV_SPI_ROM 0x1f
+#define ATTR_DEV_BOOT 0x2f
+#define ATTR_DEV_CS3 0x37
+#define ATTR_DEV_CS2 0x3b
+#define ATTR_DEV_CS1 0x3d
+#define ATTR_DEV_CS0 0x3e
+#define ATTR_PCIE_IO(l) (0xf0 & ~(0x10 << (l)))
+#define ATTR_PCIE_MEM(l) (0xf8 & ~(0x10 << (l)))
+
+/*
+ * Helpers to get DDR bank info
+ */
+#define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3))
+#define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3))
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define WIN0_OFF(n) (BRIDGE_VIRT_BASE + 0x0000 + ((n) << 4))
+#define WIN8_OFF(n) (BRIDGE_VIRT_BASE + 0x0900 + (((n) - 8) << 4))
+#define WIN_CTRL_OFF 0x0000
+#define WIN_BASE_OFF 0x0004
+#define WIN_REMAP_LO_OFF 0x0008
+#define WIN_REMAP_HI_OFF 0x000c
+
+
+struct mbus_dram_target_info mv78xx0_mbus_dram_info;
+
+static void __init __iomem *win_cfg_base(int win)
+{
+ /*
+ * Find the control register base address for this window.
+ *
+ * BRIDGE_VIRT_BASE points to the right (CPU0's or CPU1's)
+ * MBUS bridge depending on which CPU core we're running on,
+ * so we don't need to take that into account here.
+ */
+
+ return (void __iomem *)((win < 8) ? WIN0_OFF(win) : WIN8_OFF(win));
+}
+
+static int __init cpu_win_can_remap(int win)
+{
+ if (win < 8)
+ return 1;
+
+ return 0;
+}
+
+static void __init setup_cpu_win(int win, u32 base, u32 size,
+ u8 target, u8 attr, int remap)
+{
+ void __iomem *addr = win_cfg_base(win);
+ u32 ctrl;
+
+ base &= 0xffff0000;
+ ctrl = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
+
+ writel(base, addr + WIN_BASE_OFF);
+ writel(ctrl, addr + WIN_CTRL_OFF);
+ if (cpu_win_can_remap(win)) {
+ if (remap < 0)
+ remap = base;
+
+ writel(remap & 0xffff0000, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+}
+
+void __init mv78xx0_setup_cpu_mbus(void)
+{
+ void __iomem *addr;
+ int i;
+ int cs;
+
+ /*
+ * First, disable and clear windows.
+ */
+ for (i = 0; i < 14; i++) {
+ addr = win_cfg_base(i);
+
+ writel(0, addr + WIN_BASE_OFF);
+ writel(0, addr + WIN_CTRL_OFF);
+ if (cpu_win_can_remap(i)) {
+ writel(0, addr + WIN_REMAP_LO_OFF);
+ writel(0, addr + WIN_REMAP_HI_OFF);
+ }
+ }
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ mv78xx0_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ if (mv78xx0_core_index() == 0)
+ addr = (void __iomem *)DDR_WINDOW_CPU0_BASE;
+ else
+ addr = (void __iomem *)DDR_WINDOW_CPU1_BASE;
+
+ for (i = 0, cs = 0; i < 4; i++) {
+ u32 base = readl(addr + DDR_BASE_CS_OFF(i));
+ u32 size = readl(addr + DDR_SIZE_CS_OFF(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (size & 1) {
+ struct mbus_dram_window *w;
+
+ w = &mv78xx0_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ w->base = base & 0xffff0000;
+ w->size = (size | 0x0000ffff) + 1;
+ }
+ }
+ mv78xx0_mbus_dram_info.num_cs = cs;
+}
+
+void __init mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
+ int maj, int min)
+{
+ setup_cpu_win(window, base, size, TARGET_PCIE(maj),
+ ATTR_PCIE_IO(min), -1);
+}
+
+void __init mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
+ int maj, int min)
+{
+ setup_cpu_win(window, base, size, TARGET_PCIE(maj),
+ ATTR_PCIE_MEM(min), -1);
+}
diff --git a/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
new file mode 100644
index 00000000..20f3f125
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/mach-mv78xx0/buffalo-wxl-setup.c
+ *
+ * Buffalo WXL (Terastation Duo) Setup routines
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/i2c.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "mpp.h"
+
+
+/* This arch has 2 Giga Ethernet */
+
+static struct mv643xx_eth_platform_data db78x00_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+
+/* 2 SATA controller supporting HotPlug */
+
+static struct mv_sata_platform_data db78x00_sata_data = {
+ .n_ports = 2,
+};
+
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
+static unsigned int wxl_mpp_config[] __initdata = {
+ MPP0_GE1_TXCLK,
+ MPP1_GE1_TXCTL,
+ MPP2_GE1_RXCTL,
+ MPP3_GE1_RXCLK,
+ MPP4_GE1_TXD0,
+ MPP5_GE1_TXD1,
+ MPP6_GE1_TXD2,
+ MPP7_GE1_TXD3,
+ MPP8_GE1_RXD0,
+ MPP9_GE1_RXD1,
+ MPP10_GE1_RXD2,
+ MPP11_GE1_RXD3,
+ MPP12_GPIO,
+ MPP13_SYSRST_OUTn,
+ MPP14_SATA1_ACTn,
+ MPP15_SATA0_ACTn,
+ MPP16_GPIO,
+ MPP17_GPIO,
+ MPP18_GPIO,
+ MPP19_GPIO,
+ MPP20_GPIO,
+ MPP21_GPIO,
+ MPP22_GPIO,
+ MPP23_GPIO,
+ MPP24_UA2_TXD,
+ MPP25_UA2_RXD,
+ MPP26_UA2_CTSn,
+ MPP27_UA2_RTSn,
+ MPP28_GPIO,
+ MPP29_SYSRST_OUTn,
+ MPP30_GPIO,
+ MPP31_GPIO,
+ MPP32_GPIO,
+ MPP33_GPIO,
+ MPP34_GPIO,
+ MPP35_GPIO,
+ MPP36_GPIO,
+ MPP37_GPIO,
+ MPP38_GPIO,
+ MPP39_GPIO,
+ MPP40_UNUSED,
+ MPP41_UNUSED,
+ MPP42_UNUSED,
+ MPP43_UNUSED,
+ MPP44_UNUSED,
+ MPP45_UNUSED,
+ MPP46_UNUSED,
+ MPP47_UNUSED,
+ MPP48_SATA1_ACTn,
+ MPP49_SATA0_ACTn,
+ 0
+};
+
+
+static void __init wxl_init(void)
+{
+ /*
+ * Basic MV78xx0 setup. Needs to be called early.
+ */
+ mv78xx0_init();
+ mv78xx0_mpp_conf(wxl_mpp_config);
+
+ /*
+ * Partition on-chip peripherals between the two CPU cores.
+ */
+ mv78xx0_ehci0_init();
+ mv78xx0_ehci1_init();
+ mv78xx0_ehci2_init();
+ mv78xx0_ge00_init(&db78x00_ge00_data);
+ mv78xx0_ge01_init(&db78x00_ge01_data);
+ mv78xx0_sata_init(&db78x00_sata_data);
+ mv78xx0_uart0_init();
+ mv78xx0_uart1_init();
+ mv78xx0_uart2_init();
+ mv78xx0_uart3_init();
+ mv78xx0_i2c_init();
+ i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
+}
+
+static int __init wxl_pci_init(void)
+{
+ if (machine_is_terastation_wxl()) {
+ /*
+ * Assign the x16 PCIe slot on the board to CPU core
+ * #0, and let CPU core #1 have the four x1 slots.
+ */
+ if (mv78xx0_core_index() == 0)
+ mv78xx0_pcie_init(0, 1);
+ else
+ mv78xx0_pcie_init(1, 0);
+ }
+
+ return 0;
+}
+subsys_initcall(wxl_pci_init);
+
+MACHINE_START(TERASTATION_WXL, "Buffalo Nas WXL")
+ /* Maintainer: Sebastien Requiem <sebastien@requiem.fr> */
+ .boot_params = 0x00000100,
+ .init_machine = wxl_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .timer = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c
new file mode 100644
index 00000000..d90e244e
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/common.c
@@ -0,0 +1,404 @@
+/*
+ * arch/arm/mach-mv78xx0/common.c
+ *
+ * Core functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/ata_platform.h>
+#include <linux/ethtool.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/mv78xx0.h>
+#include <mach/bridge-regs.h>
+#include <plat/cache-feroceon-l2.h>
+#include <plat/ehci-orion.h>
+#include <plat/orion_nand.h>
+#include <plat/time.h>
+#include <plat/common.h>
+#include "common.h"
+
+static int get_tclk(void);
+
+/*****************************************************************************
+ * Common bits
+ ****************************************************************************/
+int mv78xx0_core_index(void)
+{
+ u32 extra;
+
+ /*
+ * Read Extra Features register.
+ */
+ __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (extra));
+
+ return !!(extra & 0x00004000);
+}
+
+static int get_hclk(void)
+{
+ int hclk;
+
+ /*
+ * HCLK tick rate is configured by DEV_D[7:5] pins.
+ */
+ switch ((readl(SAMPLE_AT_RESET_LOW) >> 5) & 7) {
+ case 0:
+ hclk = 166666667;
+ break;
+ case 1:
+ hclk = 200000000;
+ break;
+ case 2:
+ hclk = 266666667;
+ break;
+ case 3:
+ hclk = 333333333;
+ break;
+ case 4:
+ hclk = 400000000;
+ break;
+ default:
+ panic("unknown HCLK PLL setting: %.8x\n",
+ readl(SAMPLE_AT_RESET_LOW));
+ }
+
+ return hclk;
+}
+
+static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk)
+{
+ u32 cfg;
+
+ /*
+ * Core #0 PCLK/L2CLK is configured by bits [13:8], core #1
+ * PCLK/L2CLK by bits [19:14].
+ */
+ if (core_index == 0) {
+ cfg = (readl(SAMPLE_AT_RESET_LOW) >> 8) & 0x3f;
+ } else {
+ cfg = (readl(SAMPLE_AT_RESET_LOW) >> 14) & 0x3f;
+ }
+
+ /*
+ * Bits [11:8] ([17:14] for core #1) configure the PCLK:HCLK
+ * ratio (1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6).
+ */
+ *pclk = ((u64)hclk * (2 + (cfg & 0xf))) >> 1;
+
+ /*
+ * Bits [13:12] ([19:18] for core #1) configure the PCLK:L2CLK
+ * ratio (1, 2, 3).
+ */
+ *l2clk = *pclk / (((cfg >> 4) & 3) + 1);
+}
+
+static int get_tclk(void)
+{
+ int tclk;
+
+ /*
+ * TCLK tick rate is configured by DEV_A[2:0] strap pins.
+ */
+ switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) {
+ case 1:
+ tclk = 166666667;
+ break;
+ case 3:
+ tclk = 200000000;
+ break;
+ default:
+ panic("unknown TCLK PLL setting: %.8x\n",
+ readl(SAMPLE_AT_RESET_HIGH));
+ }
+
+ return tclk;
+}
+
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc mv78xx0_io_desc[] __initdata = {
+ {
+ .virtual = MV78XX0_CORE_REGS_VIRT_BASE,
+ .pfn = 0,
+ .length = MV78XX0_CORE_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = MV78XX0_PCIE_IO_VIRT_BASE(0),
+ .pfn = __phys_to_pfn(MV78XX0_PCIE_IO_PHYS_BASE(0)),
+ .length = MV78XX0_PCIE_IO_SIZE * 8,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = MV78XX0_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(MV78XX0_REGS_PHYS_BASE),
+ .length = MV78XX0_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init mv78xx0_map_io(void)
+{
+ unsigned long phys;
+
+ /*
+ * Map the right set of per-core registers depending on
+ * which core we are running on.
+ */
+ if (mv78xx0_core_index() == 0) {
+ phys = MV78XX0_CORE0_REGS_PHYS_BASE;
+ } else {
+ phys = MV78XX0_CORE1_REGS_PHYS_BASE;
+ }
+ mv78xx0_io_desc[0].pfn = __phys_to_pfn(phys);
+
+ iotable_init(mv78xx0_io_desc, ARRAY_SIZE(mv78xx0_io_desc));
+}
+
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+void __init mv78xx0_ehci0_init(void)
+{
+ orion_ehci_init(&mv78xx0_mbus_dram_info,
+ USB0_PHYS_BASE, IRQ_MV78XX0_USB_0, EHCI_PHY_NA);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init mv78xx0_ehci1_init(void)
+{
+ orion_ehci_1_init(&mv78xx0_mbus_dram_info,
+ USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
+}
+
+
+/*****************************************************************************
+ * EHCI2
+ ****************************************************************************/
+void __init mv78xx0_ehci2_init(void)
+{
+ orion_ehci_2_init(&mv78xx0_mbus_dram_info,
+ USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
+}
+
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ orion_ge00_init(eth_data, &mv78xx0_mbus_dram_info,
+ GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
+ IRQ_MV78XX0_GE_ERR, get_tclk());
+}
+
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ orion_ge01_init(eth_data, &mv78xx0_mbus_dram_info,
+ GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
+ NO_IRQ, get_tclk());
+}
+
+
+/*****************************************************************************
+ * GE10
+ ****************************************************************************/
+void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ u32 dev, rev;
+
+ /*
+ * On the Z0, ge10 and ge11 are internally connected back
+ * to back, and not brought out.
+ */
+ mv78xx0_pcie_id(&dev, &rev);
+ if (dev == MV78X00_Z0_DEV_ID) {
+ eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+ eth_data->speed = SPEED_1000;
+ eth_data->duplex = DUPLEX_FULL;
+ }
+
+ orion_ge10_init(eth_data, &mv78xx0_mbus_dram_info,
+ GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
+ NO_IRQ, get_tclk());
+}
+
+
+/*****************************************************************************
+ * GE11
+ ****************************************************************************/
+void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ u32 dev, rev;
+
+ /*
+ * On the Z0, ge10 and ge11 are internally connected back
+ * to back, and not brought out.
+ */
+ mv78xx0_pcie_id(&dev, &rev);
+ if (dev == MV78X00_Z0_DEV_ID) {
+ eth_data->phy_addr = MV643XX_ETH_PHY_NONE;
+ eth_data->speed = SPEED_1000;
+ eth_data->duplex = DUPLEX_FULL;
+ }
+
+ orion_ge11_init(eth_data, &mv78xx0_mbus_dram_info,
+ GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
+ NO_IRQ, get_tclk());
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+void __init mv78xx0_i2c_init(void)
+{
+ orion_i2c_init(I2C_0_PHYS_BASE, IRQ_MV78XX0_I2C_0, 8);
+ orion_i2c_1_init(I2C_1_PHYS_BASE, IRQ_MV78XX0_I2C_1, 8);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
+{
+ orion_sata_init(sata_data, &mv78xx0_mbus_dram_info,
+ SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+void __init mv78xx0_uart0_init(void)
+{
+ orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+ IRQ_MV78XX0_UART_0, get_tclk());
+}
+
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init mv78xx0_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_MV78XX0_UART_1, get_tclk());
+}
+
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+void __init mv78xx0_uart2_init(void)
+{
+ orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
+ IRQ_MV78XX0_UART_2, get_tclk());
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+void __init mv78xx0_uart3_init(void)
+{
+ orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
+ IRQ_MV78XX0_UART_3, get_tclk());
+}
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init mv78xx0_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+}
+
+static void mv78xx0_timer_init(void)
+{
+ orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_MV78XX0_TIMER_1, get_tclk());
+}
+
+struct sys_timer mv78xx0_timer = {
+ .init = mv78xx0_timer_init,
+};
+
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+static char * __init mv78xx0_id(void)
+{
+ u32 dev, rev;
+
+ mv78xx0_pcie_id(&dev, &rev);
+
+ if (dev == MV78X00_Z0_DEV_ID) {
+ if (rev == MV78X00_REV_Z0)
+ return "MV78X00-Z0";
+ else
+ return "MV78X00-Rev-Unsupported";
+ } else if (dev == MV78100_DEV_ID) {
+ if (rev == MV78100_REV_A0)
+ return "MV78100-A0";
+ else if (rev == MV78100_REV_A1)
+ return "MV78100-A1";
+ else
+ return "MV78100-Rev-Unsupported";
+ } else if (dev == MV78200_DEV_ID) {
+ if (rev == MV78100_REV_A0)
+ return "MV78200-A0";
+ else
+ return "MV78200-Rev-Unsupported";
+ } else {
+ return "Device-Unknown";
+ }
+}
+
+static int __init is_l2_writethrough(void)
+{
+ return !!(readl(CPU_CONTROL) & L2_WRITETHROUGH);
+}
+
+void __init mv78xx0_init(void)
+{
+ int core_index;
+ int hclk;
+ int pclk;
+ int l2clk;
+ int tclk;
+
+ core_index = mv78xx0_core_index();
+ hclk = get_hclk();
+ get_pclk_l2clk(hclk, core_index, &pclk, &l2clk);
+ tclk = get_tclk();
+
+ printk(KERN_INFO "%s ", mv78xx0_id());
+ printk("core #%d, ", core_index);
+ printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000);
+ printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000);
+ printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000);
+ printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000);
+
+ mv78xx0_setup_cpu_mbus();
+
+#ifdef CONFIG_CACHE_FEROCEON_L2
+ feroceon_l2_init(is_l2_writethrough());
+#endif
+}
diff --git a/arch/arm/mach-mv78xx0/common.h b/arch/arm/mach-mv78xx0/common.h
new file mode 100644
index 00000000..632e63d6
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/common.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-mv78xx0/common.h
+ *
+ * Core functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_MV78XX0_COMMON_H
+#define __ARCH_MV78XX0_COMMON_H
+
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+/*
+ * Basic MV78xx0 init functions used early by machine-setup.
+ */
+int mv78xx0_core_index(void);
+void mv78xx0_map_io(void);
+void mv78xx0_init(void);
+void mv78xx0_init_early(void);
+void mv78xx0_init_irq(void);
+
+extern struct mbus_dram_target_info mv78xx0_mbus_dram_info;
+void mv78xx0_setup_cpu_mbus(void);
+void mv78xx0_setup_pcie_io_win(int window, u32 base, u32 size,
+ int maj, int min);
+void mv78xx0_setup_pcie_mem_win(int window, u32 base, u32 size,
+ int maj, int min);
+
+void mv78xx0_pcie_id(u32 *dev, u32 *rev);
+
+void mv78xx0_ehci0_init(void);
+void mv78xx0_ehci1_init(void);
+void mv78xx0_ehci2_init(void);
+void mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data);
+void mv78xx0_pcie_init(int init_port0, int init_port1);
+void mv78xx0_sata_init(struct mv_sata_platform_data *sata_data);
+void mv78xx0_uart0_init(void);
+void mv78xx0_uart1_init(void);
+void mv78xx0_uart2_init(void);
+void mv78xx0_uart3_init(void);
+void mv78xx0_i2c_init(void);
+
+extern struct sys_timer mv78xx0_timer;
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/db78x00-bp-setup.c b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
new file mode 100644
index 00000000..df5aebe5
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/db78x00-bp-setup.c
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/mach-mv78xx0/db78x00-bp-setup.c
+ *
+ * Marvell DB-78x00-BP Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/i2c.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data db78x00_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(9),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge10_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(10),
+};
+
+static struct mv643xx_eth_platform_data db78x00_ge11_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(11),
+};
+
+static struct mv_sata_platform_data db78x00_sata_data = {
+ .n_ports = 2,
+};
+
+static struct i2c_board_info __initdata db78x00_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+
+static void __init db78x00_init(void)
+{
+ /*
+ * Basic MV78xx0 setup. Needs to be called early.
+ */
+ mv78xx0_init();
+
+ /*
+ * Partition on-chip peripherals between the two CPU cores.
+ */
+ if (mv78xx0_core_index() == 0) {
+ mv78xx0_ehci0_init();
+ mv78xx0_ehci1_init();
+ mv78xx0_ehci2_init();
+ mv78xx0_ge00_init(&db78x00_ge00_data);
+ mv78xx0_ge01_init(&db78x00_ge01_data);
+ mv78xx0_ge10_init(&db78x00_ge10_data);
+ mv78xx0_ge11_init(&db78x00_ge11_data);
+ mv78xx0_sata_init(&db78x00_sata_data);
+ mv78xx0_uart0_init();
+ mv78xx0_uart2_init();
+ mv78xx0_i2c_init();
+ i2c_register_board_info(0, &db78x00_i2c_rtc, 1);
+ } else {
+ mv78xx0_uart1_init();
+ mv78xx0_uart3_init();
+ }
+}
+
+static int __init db78x00_pci_init(void)
+{
+ if (machine_is_db78x00_bp()) {
+ /*
+ * Assign the x16 PCIe slot on the board to CPU core
+ * #0, and let CPU core #1 have the four x1 slots.
+ */
+ if (mv78xx0_core_index() == 0)
+ mv78xx0_pcie_init(0, 1);
+ else
+ mv78xx0_pcie_init(1, 0);
+ }
+
+ return 0;
+}
+subsys_initcall(db78x00_pci_init);
+
+MACHINE_START(DB78X00_BP, "Marvell DB-78x00-BP Development Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = db78x00_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .timer = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
new file mode 100644
index 00000000..c64dbb96
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/bridge-regs.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/mv78xx0.h>
+
+#define CPU_CONTROL (BRIDGE_VIRT_BASE | 0x0104)
+#define L2_WRITETHROUGH 0x00020000
+
+#define RSTOUTn_MASK (BRIDGE_VIRT_BASE | 0x0108)
+#define SOFT_RESET_OUT_EN 0x00000004
+
+#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE | 0x010c)
+#define SOFT_RESET 0x00000001
+
+#define BRIDGE_INT_TIMER1_CLR (~0x0004)
+
+#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200)
+#define IRQ_CAUSE_ERR_OFF 0x0000
+#define IRQ_CAUSE_LOW_OFF 0x0004
+#define IRQ_CAUSE_HIGH_OFF 0x0008
+#define IRQ_MASK_ERR_OFF 0x000c
+#define IRQ_MASK_LOW_OFF 0x0010
+#define IRQ_MASK_HIGH_OFF 0x0014
+
+#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/debug-macro.S b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
new file mode 100644
index 00000000..04891428
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/debug-macro.S
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/debug-macro.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 <mach/mv78xx0.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =MV78XX0_REGS_PHYS_BASE
+ ldr \rv, =MV78XX0_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
new file mode 100644
index 00000000..66ae2d29
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Marvell MV78xx0 platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/bridge-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IRQ_VIRT_BASE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ @ check low interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_LOW_OFF]
+ mov \irqnr, #31
+ ands \irqstat, \irqstat, \tmp
+ bne 1001f
+
+ @ if no low interrupts set, check high interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF]
+ mov \irqnr, #63
+ ands \irqstat, \irqstat, \tmp
+ bne 1001f
+
+ @ if no high interrupts set, check error interrupts
+ ldr \irqstat, [\base, #IRQ_CAUSE_ERR_OFF]
+ ldr \tmp, [\base, #IRQ_MASK_ERR_OFF]
+ mov \irqnr, #95
+ ands \irqstat, \irqstat, \tmp
+
+ @ find first active interrupt source
+1001: clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-mv78xx0/include/mach/gpio.h b/arch/arm/mach-mv78xx0/include/mach/gpio.h
new file mode 100644
index 00000000..77e1b843
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/gpio.h
@@ -0,0 +1,9 @@
+/*
+ * arch/asm-arm/mach-mv78xx0/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-mv78xx0/include/mach/hardware.h b/arch/arm/mach-mv78xx0/include/mach/hardware.h
new file mode 100644
index 00000000..5d887557
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/hardware.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "mv78xx0.h"
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE MV78XX0_PCIE_MEM_PHYS_BASE /* mem base for VGA */
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/io.h b/arch/arm/mach-mv78xx0/include/mach/io.h
new file mode 100644
index 00000000..450e0e1a
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/io.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/io.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "mv78xx0.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)((addr - MV78XX0_PCIE_IO_PHYS_BASE(0))
+ + MV78XX0_PCIE_IO_VIRT_BASE(0));
+}
+
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/irqs.h b/arch/arm/mach-mv78xx0/include/mach/irqs.h
new file mode 100644
index 00000000..fa1d4221
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/irqs.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/irqs.h
+ *
+ * IRQ definitions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * MV78xx0 Low Interrupt Controller
+ */
+#define IRQ_MV78XX0_ERR 0
+#define IRQ_MV78XX0_SPI 1
+#define IRQ_MV78XX0_I2C_0 2
+#define IRQ_MV78XX0_I2C_1 3
+#define IRQ_MV78XX0_IDMA_0 4
+#define IRQ_MV78XX0_IDMA_1 5
+#define IRQ_MV78XX0_IDMA_2 6
+#define IRQ_MV78XX0_IDMA_3 7
+#define IRQ_MV78XX0_TIMER_0 8
+#define IRQ_MV78XX0_TIMER_1 9
+#define IRQ_MV78XX0_TIMER_2 10
+#define IRQ_MV78XX0_TIMER_3 11
+#define IRQ_MV78XX0_UART_0 12
+#define IRQ_MV78XX0_UART_1 13
+#define IRQ_MV78XX0_UART_2 14
+#define IRQ_MV78XX0_UART_3 15
+#define IRQ_MV78XX0_USB_0 16
+#define IRQ_MV78XX0_USB_1 17
+#define IRQ_MV78XX0_USB_2 18
+#define IRQ_MV78XX0_CRYPTO 19
+#define IRQ_MV78XX0_SDIO_0 20
+#define IRQ_MV78XX0_SDIO_1 21
+#define IRQ_MV78XX0_XOR_0 22
+#define IRQ_MV78XX0_XOR_1 23
+#define IRQ_MV78XX0_I2S_0 24
+#define IRQ_MV78XX0_I2S_1 25
+#define IRQ_MV78XX0_SATA 26
+#define IRQ_MV78XX0_TDMI 27
+
+/*
+ * MV78xx0 High Interrupt Controller
+ */
+#define IRQ_MV78XX0_PCIE_00 32
+#define IRQ_MV78XX0_PCIE_01 33
+#define IRQ_MV78XX0_PCIE_02 34
+#define IRQ_MV78XX0_PCIE_03 35
+#define IRQ_MV78XX0_PCIE_10 36
+#define IRQ_MV78XX0_PCIE_11 37
+#define IRQ_MV78XX0_PCIE_12 38
+#define IRQ_MV78XX0_PCIE_13 39
+#define IRQ_MV78XX0_GE00_SUM 40
+#define IRQ_MV78XX0_GE00_RX 41
+#define IRQ_MV78XX0_GE00_TX 42
+#define IRQ_MV78XX0_GE00_MISC 43
+#define IRQ_MV78XX0_GE01_SUM 44
+#define IRQ_MV78XX0_GE01_RX 45
+#define IRQ_MV78XX0_GE01_TX 46
+#define IRQ_MV78XX0_GE01_MISC 47
+#define IRQ_MV78XX0_GE10_SUM 48
+#define IRQ_MV78XX0_GE10_RX 49
+#define IRQ_MV78XX0_GE10_TX 50
+#define IRQ_MV78XX0_GE10_MISC 51
+#define IRQ_MV78XX0_GE11_SUM 52
+#define IRQ_MV78XX0_GE11_RX 53
+#define IRQ_MV78XX0_GE11_TX 54
+#define IRQ_MV78XX0_GE11_MISC 55
+#define IRQ_MV78XX0_GPIO_0_7 56
+#define IRQ_MV78XX0_GPIO_8_15 57
+#define IRQ_MV78XX0_GPIO_16_23 58
+#define IRQ_MV78XX0_GPIO_24_31 59
+#define IRQ_MV78XX0_DB_IN 60
+#define IRQ_MV78XX0_DB_OUT 61
+
+/*
+ * MV78xx0 Error Interrupt Controller
+ */
+#define IRQ_MV78XX0_GE_ERR 70
+
+/*
+ * MV78XX0 General Purpose Pins
+ */
+#define IRQ_MV78XX0_GPIO_START 96
+#define NR_GPIO_IRQS 32
+
+#define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/memory.h b/arch/arm/mach-mv78xx0/include/mach/memory.h
new file mode 100644
index 00000000..a648c51f
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/memory.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/memory.h
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
new file mode 100644
index 00000000..36744971
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
@@ -0,0 +1,121 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/mv78xx0.h
+ *
+ * Generic definitions for Marvell MV78xx0 SoC flavors:
+ * MV781x0 and MV782x0.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_MV78XX0_H
+#define __ASM_ARCH_MV78XX0_H
+
+/*
+ * Marvell MV78xx0 address maps.
+ *
+ * phys
+ * c0000000 PCIe Memory space
+ * f0800000 PCIe #0 I/O space
+ * f0900000 PCIe #1 I/O space
+ * f0a00000 PCIe #2 I/O space
+ * f0b00000 PCIe #3 I/O space
+ * f0c00000 PCIe #4 I/O space
+ * f0d00000 PCIe #5 I/O space
+ * f0e00000 PCIe #6 I/O space
+ * f0f00000 PCIe #7 I/O space
+ * f1000000 on-chip peripheral registers
+ *
+ * virt phys size
+ * fe400000 f102x000 16K core-specific peripheral registers
+ * fe700000 f0800000 1M PCIe #0 I/O space
+ * fe800000 f0900000 1M PCIe #1 I/O space
+ * fe900000 f0a00000 1M PCIe #2 I/O space
+ * fea00000 f0b00000 1M PCIe #3 I/O space
+ * feb00000 f0c00000 1M PCIe #4 I/O space
+ * fec00000 f0d00000 1M PCIe #5 I/O space
+ * fed00000 f0e00000 1M PCIe #6 I/O space
+ * fee00000 f0f00000 1M PCIe #7 I/O space
+ * fef00000 f1000000 1M on-chip peripheral registers
+ */
+#define MV78XX0_CORE0_REGS_PHYS_BASE 0xf1020000
+#define MV78XX0_CORE1_REGS_PHYS_BASE 0xf1024000
+#define MV78XX0_CORE_REGS_VIRT_BASE 0xfe400000
+#define MV78XX0_CORE_REGS_SIZE SZ_16K
+
+#define MV78XX0_PCIE_IO_PHYS_BASE(i) (0xf0800000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_VIRT_BASE(i) (0xfe700000 + ((i) << 20))
+#define MV78XX0_PCIE_IO_SIZE SZ_1M
+
+#define MV78XX0_REGS_PHYS_BASE 0xf1000000
+#define MV78XX0_REGS_VIRT_BASE 0xfef00000
+#define MV78XX0_REGS_SIZE SZ_1M
+
+#define MV78XX0_PCIE_MEM_PHYS_BASE 0xc0000000
+#define MV78XX0_PCIE_MEM_SIZE 0x30000000
+
+/*
+ * Core-specific peripheral registers.
+ */
+#define BRIDGE_VIRT_BASE (MV78XX0_CORE_REGS_VIRT_BASE)
+
+/*
+ * Register Map
+ */
+#define DDR_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x00000)
+#define DDR_WINDOW_CPU0_BASE (DDR_VIRT_BASE | 0x1500)
+#define DDR_WINDOW_CPU1_BASE (DDR_VIRT_BASE | 0x1570)
+
+#define DEV_BUS_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x10000)
+#define DEV_BUS_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x10000)
+#define SAMPLE_AT_RESET_LOW (DEV_BUS_VIRT_BASE | 0x0030)
+#define SAMPLE_AT_RESET_HIGH (DEV_BUS_VIRT_BASE | 0x0034)
+#define GPIO_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x0100)
+#define I2C_0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1000)
+#define I2C_1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x1100)
+#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2000)
+#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2000)
+#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2100)
+#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
+#define UART2_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2200)
+#define UART2_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2200)
+#define UART3_PHYS_BASE (DEV_BUS_PHYS_BASE | 0x2300)
+#define UART3_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2300)
+
+#define GE10_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x30000)
+#define GE11_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x34000)
+
+#define PCIE00_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x40000)
+#define PCIE01_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x44000)
+#define PCIE02_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x48000)
+#define PCIE03_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x4c000)
+
+#define USB0_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x50000)
+#define USB1_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x51000)
+#define USB2_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x52000)
+
+#define GE00_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x70000)
+#define GE01_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0x74000)
+
+#define PCIE10_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x80000)
+#define PCIE11_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x84000)
+#define PCIE12_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x88000)
+#define PCIE13_VIRT_BASE (MV78XX0_REGS_VIRT_BASE | 0x8c000)
+
+#define SATA_PHYS_BASE (MV78XX0_REGS_PHYS_BASE | 0xa0000)
+
+/*
+ * Supported devices and revisions.
+ */
+#define MV78X00_Z0_DEV_ID 0x6381
+#define MV78X00_REV_Z0 1
+
+#define MV78100_DEV_ID 0x7810
+#define MV78100_REV_A0 1
+#define MV78100_REV_A1 2
+
+#define MV78200_DEV_ID 0x7820
+#define MV78200_REV_A0 1
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h
new file mode 100644
index 00000000..66e7ce4e
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/system.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/system.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
+
+ /*
+ * Assert soft reset.
+ */
+ writel(SOFT_RESET, SYSTEM_SOFT_RESET);
+
+ while (1)
+ ;
+}
+
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/timex.h b/arch/arm/mach-mv78xx0/include/mach/timex.h
new file mode 100644
index 00000000..0e8c443c
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/timex.h
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/timex.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-mv78xx0/include/mach/uncompress.h b/arch/arm/mach-mv78xx0/include/mach/uncompress.h
new file mode 100644
index 00000000..36526429
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/uncompress.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/uncompress.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/mv78xx0.h>
+
+#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-mv78xx0/include/mach/vmalloc.h b/arch/arm/mach-mv78xx0/include/mach/vmalloc.h
new file mode 100644
index 00000000..ba26fe98
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-mv78xx0/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfe000000UL
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
new file mode 100644
index 00000000..3e24431b
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-mv78xx0/irq.c
+ *
+ * MV78xx0 IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <asm/gpio.h>
+#include <mach/bridge-regs.h>
+#include <plat/irq.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31);
+
+ orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3);
+}
+
+void __init mv78xx0_init_irq(void)
+{
+ orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF));
+ orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF));
+ orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF));
+
+ /*
+ * Initialize gpiolib for GPIOs 0-31. (The GPIO interrupt mask
+ * registers for core #1 are at an offset of 0x18 from those of
+ * core #0.)
+ */
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE,
+ mv78xx0_core_index() ? 0x18 : 0,
+ IRQ_MV78XX0_GPIO_START);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
+}
diff --git a/arch/arm/mach-mv78xx0/mpp.c b/arch/arm/mach-mv78xx0/mpp.c
new file mode 100644
index 00000000..59b7686b
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mpp.c
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-mv78x00/mpp.c
+ *
+ * MPP functions for Marvell MV78x00 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <plat/mpp.h>
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int __init mv78xx0_variant(void)
+{
+ u32 dev, rev;
+
+ mv78xx0_pcie_id(&dev, &rev);
+
+ if (dev == MV78100_DEV_ID && rev >= MV78100_REV_A0)
+ return MPP_78100_A0_MASK;
+
+ printk(KERN_ERR "MPP setup: unknown mv78x00 variant "
+ "(dev %#x rev %#x)\n", dev, rev);
+ return 0;
+}
+
+void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
+{
+ orion_mpp_conf(mpp_list, mv78xx0_variant(),
+ MPP_MAX, DEV_BUS_VIRT_BASE);
+}
diff --git a/arch/arm/mach-mv78xx0/mpp.h b/arch/arm/mach-mv78xx0/mpp.h
new file mode 100644
index 00000000..3752302a
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/mpp.h
@@ -0,0 +1,341 @@
+/*
+ * linux/arch/arm/mach-mv78xx0/mpp.h -- Multi Purpose Pins
+ *
+ *
+ * sebastien requiem <sebastien@requiem.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MV78X00_MPP_H
+#define __MV78X00_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _78100_A0) (\
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13) | \
+ /* available on A0 */ ((!!(_78100_A0)) << 14))
+
+ /* num sel i o 78100_A0 */
+
+#define MPP_78100_A0_MASK MPP(0, 0x0, 0, 0, 1)
+
+#define MPP0_GPIO MPP(0, 0x0, 1, 1, 1)
+#define MPP0_GE0_COL MPP(0, 0x1, 0, 0, 1)
+#define MPP0_GE1_TXCLK MPP(0, 0x2, 0, 0, 1)
+#define MPP0_UNUSED MPP(0, 0x3, 0, 0, 1)
+
+#define MPP1_GPIO MPP(1, 0x0, 1, 1, 1)
+#define MPP1_GE0_RXERR MPP(1, 0x1, 0, 0, 1)
+#define MPP1_GE1_TXCTL MPP(1, 0x2, 0, 0, 1)
+#define MPP1_UNUSED MPP(1, 0x3, 0, 0, 1)
+
+#define MPP2_GPIO MPP(2, 0x0, 1, 1, 1)
+#define MPP2_GE0_CRS MPP(2, 0x1, 0, 0, 1)
+#define MPP2_GE1_RXCTL MPP(2, 0x2, 0, 0, 1)
+#define MPP2_UNUSED MPP(2, 0x3, 0, 0, 1)
+
+#define MPP3_GPIO MPP(3, 0x0, 1, 1, 1)
+#define MPP3_GE0_TXERR MPP(3, 0x1, 0, 0, 1)
+#define MPP3_GE1_RXCLK MPP(3, 0x2, 0, 0, 1)
+#define MPP3_UNUSED MPP(3, 0x3, 0, 0, 1)
+
+#define MPP4_GPIO MPP(4, 0x0, 1, 1, 1)
+#define MPP4_GE0_TXD4 MPP(4, 0x1, 0, 0, 1)
+#define MPP4_GE1_TXD0 MPP(4, 0x2, 0, 0, 1)
+#define MPP4_UNUSED MPP(4, 0x3, 0, 0, 1)
+
+#define MPP5_GPIO MPP(5, 0x0, 1, 1, 1)
+#define MPP5_GE0_TXD5 MPP(5, 0x1, 0, 0, 1)
+#define MPP5_GE1_TXD1 MPP(5, 0x2, 0, 0, 1)
+#define MPP5_UNUSED MPP(5, 0x3, 0, 0, 1)
+
+#define MPP6_GPIO MPP(6, 0x0, 1, 1, 1)
+#define MPP6_GE0_TXD6 MPP(6, 0x1, 0, 0, 1)
+#define MPP6_GE1_TXD2 MPP(6, 0x2, 0, 0, 1)
+#define MPP6_UNUSED MPP(6, 0x3, 0, 0, 1)
+
+#define MPP7_GPIO MPP(7, 0x0, 1, 1, 1)
+#define MPP7_GE0_TXD7 MPP(7, 0x1, 0, 0, 1)
+#define MPP7_GE1_TXD3 MPP(7, 0x2, 0, 0, 1)
+#define MPP7_UNUSED MPP(7, 0x3, 0, 0, 1)
+
+#define MPP8_GPIO MPP(8, 0x0, 1, 1, 1)
+#define MPP8_GE0_RXD4 MPP(8, 0x1, 0, 0, 1)
+#define MPP8_GE1_RXD0 MPP(8, 0x2, 0, 0, 1)
+#define MPP8_UNUSED MPP(8, 0x3, 0, 0, 1)
+
+#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1)
+#define MPP9_GE0_RXD5 MPP(9, 0x1, 0, 0, 1)
+#define MPP9_GE1_RXD1 MPP(9, 0x2, 0, 0, 1)
+#define MPP9_UNUSED MPP(9, 0x3, 0, 0, 1)
+
+#define MPP10_GPIO MPP(10, 0x0, 1, 1, 1)
+#define MPP10_GE0_RXD6 MPP(10, 0x1, 0, 0, 1)
+#define MPP10_GE1_RXD2 MPP(10, 0x2, 0, 0, 1)
+#define MPP10_UNUSED MPP(10, 0x3, 0, 0, 1)
+
+#define MPP11_GPIO MPP(11, 0x0, 1, 1, 1)
+#define MPP11_GE0_RXD7 MPP(11, 0x1, 0, 0, 1)
+#define MPP11_GE1_RXD3 MPP(11, 0x2, 0, 0, 1)
+#define MPP11_UNUSED MPP(11, 0x3, 0, 0, 1)
+
+#define MPP12_GPIO MPP(12, 0x0, 1, 1, 1)
+#define MPP12_M_BB MPP(12, 0x3, 0, 0, 1)
+#define MPP12_UA0_CTSn MPP(12, 0x4, 0, 0, 1)
+#define MPP12_NAND_FLASH_REn0 MPP(12, 0x5, 0, 0, 1)
+#define MPP12_TDM0_SCSn MPP(12, 0X6, 0, 0, 1)
+#define MPP12_UNUSED MPP(12, 0x1, 0, 0, 1)
+
+#define MPP13_GPIO MPP(13, 0x0, 1, 1, 1)
+#define MPP13_SYSRST_OUTn MPP(13, 0x3, 0, 0, 1)
+#define MPP13_UA0_RTSn MPP(13, 0x4, 0, 0, 1)
+#define MPP13_NAN_FLASH_WEn0 MPP(13, 0x5, 0, 0, 1)
+#define MPP13_TDM_SCLK MPP(13, 0x6, 0, 0, 1)
+#define MPP13_UNUSED MPP(13, 0x1, 0, 0, 1)
+
+#define MPP14_GPIO MPP(14, 0x0, 1, 1, 1)
+#define MPP14_SATA1_ACTn MPP(14, 0x3, 0, 0, 1)
+#define MPP14_UA1_CTSn MPP(14, 0x4, 0, 0, 1)
+#define MPP14_NAND_FLASH_REn1 MPP(14, 0x5, 0, 0, 1)
+#define MPP14_TDM_SMOSI MPP(14, 0x6, 0, 0, 1)
+#define MPP14_UNUSED MPP(14, 0x1, 0, 0, 1)
+
+#define MPP15_GPIO MPP(15, 0x0, 1, 1, 1)
+#define MPP15_SATA0_ACTn MPP(15, 0x3, 0, 0, 1)
+#define MPP15_UA1_RTSn MPP(15, 0x4, 0, 0, 1)
+#define MPP15_NAND_FLASH_WEn1 MPP(15, 0x5, 0, 0, 1)
+#define MPP15_TDM_SMISO MPP(15, 0x6, 0, 0, 1)
+#define MPP15_UNUSED MPP(15, 0x1, 0, 0, 1)
+
+#define MPP16_GPIO MPP(16, 0x0, 1, 1, 1)
+#define MPP16_SATA1_PRESENTn MPP(16, 0x3, 0, 0, 1)
+#define MPP16_UA2_TXD MPP(16, 0x4, 0, 0, 1)
+#define MPP16_NAND_FLASH_REn3 MPP(16, 0x5, 0, 0, 1)
+#define MPP16_TDM_INTn MPP(16, 0x6, 0, 0, 1)
+#define MPP16_UNUSED MPP(16, 0x1, 0, 0, 1)
+
+
+#define MPP17_GPIO MPP(17, 0x0, 1, 1, 1)
+#define MPP17_SATA0_PRESENTn MPP(17, 0x3, 0, 0, 1)
+#define MPP17_UA2_RXD MPP(17, 0x4, 0, 0, 1)
+#define MPP17_NAND_FLASH_WEn3 MPP(17, 0x5, 0, 0, 1)
+#define MPP17_TDM_RSTn MPP(17, 0x6, 0, 0, 1)
+#define MPP17_UNUSED MPP(17, 0x1, 0, 0, 1)
+
+
+#define MPP18_GPIO MPP(18, 0x0, 1, 1, 1)
+#define MPP18_UA0_CTSn MPP(18, 0x4, 0, 0, 1)
+#define MPP18_BOOT_FLASH_REn MPP(18, 0x5, 0, 0, 1)
+#define MPP18_UNUSED MPP(18, 0x1, 0, 0, 1)
+
+
+
+#define MPP19_GPIO MPP(19, 0x0, 1, 1, 1)
+#define MPP19_UA0_CTSn MPP(19, 0x4, 0, 0, 1)
+#define MPP19_BOOT_FLASH_WEn MPP(19, 0x5, 0, 0, 1)
+#define MPP19_UNUSED MPP(19, 0x1, 0, 0, 1)
+
+
+#define MPP20_GPIO MPP(20, 0x0, 1, 1, 1)
+#define MPP20_UA1_CTSs MPP(20, 0x4, 0, 0, 1)
+#define MPP20_TDM_PCLK MPP(20, 0x6, 0, 0, 0)
+#define MPP20_UNUSED MPP(20, 0x1, 0, 0, 1)
+
+
+
+#define MPP21_GPIO MPP(21, 0x0, 1, 1, 1)
+#define MPP21_UA1_CTSs MPP(21, 0x4, 0, 0, 1)
+#define MPP21_TDM_FSYNC MPP(21, 0x6, 0, 0, 0)
+#define MPP21_UNUSED MPP(21, 0x1, 0, 0, 1)
+
+
+
+#define MPP22_GPIO MPP(22, 0x0, 1, 1, 1)
+#define MPP22_UA3_TDX MPP(22, 0x4, 0, 0, 1)
+#define MPP22_NAND_FLASH_REn2 MPP(22, 0x5, 0, 0, 1)
+#define MPP22_TDM_DRX MPP(22, 0x6, 0, 0, 1)
+#define MPP22_UNUSED MPP(22, 0x1, 0, 0, 1)
+
+
+
+#define MPP23_GPIO MPP(23, 0x0, 1, 1, 1)
+#define MPP23_UA3_RDX MPP(23, 0x4, 0, 0, 1)
+#define MPP23_NAND_FLASH_WEn2 MPP(23, 0x5, 0, 0, 1)
+#define MPP23_TDM_DTX MPP(23, 0x6, 0, 0, 1)
+#define MPP23_UNUSED MPP(23, 0x1, 0, 0, 1)
+
+
+#define MPP24_GPIO MPP(24, 0x0, 1, 1, 1)
+#define MPP24_UA2_TXD MPP(24, 0x4, 0, 0, 1)
+#define MPP24_TDM_INTn MPP(24, 0x6, 0, 0, 1)
+#define MPP24_UNUSED MPP(24, 0x1, 0, 0, 1)
+
+
+#define MPP25_GPIO MPP(25, 0x0, 1, 1, 1)
+#define MPP25_UA2_RXD MPP(25, 0x4, 0, 0, 1)
+#define MPP25_TDM_RSTn MPP(25, 0x6, 0, 0, 1)
+#define MPP25_UNUSED MPP(25, 0x1, 0, 0, 1)
+
+
+#define MPP26_GPIO MPP(26, 0x0, 1, 1, 1)
+#define MPP26_UA2_CTSn MPP(26, 0x4, 0, 0, 1)
+#define MPP26_TDM_PCLK MPP(26, 0x6, 0, 0, 1)
+#define MPP26_UNUSED MPP(26, 0x1, 0, 0, 1)
+
+
+#define MPP27_GPIO MPP(27, 0x0, 1, 1, 1)
+#define MPP27_UA2_RTSn MPP(27, 0x4, 0, 0, 1)
+#define MPP27_TDM_FSYNC MPP(27, 0x6, 0, 0, 1)
+#define MPP27_UNUSED MPP(27, 0x1, 0, 0, 1)
+
+
+#define MPP28_GPIO MPP(28, 0x0, 1, 1, 1)
+#define MPP28_UA3_TXD MPP(28, 0x4, 0, 0, 1)
+#define MPP28_TDM_DRX MPP(28, 0x6, 0, 0, 1)
+#define MPP28_UNUSED MPP(28, 0x1, 0, 0, 1)
+
+#define MPP29_GPIO MPP(29, 0x0, 1, 1, 1)
+#define MPP29_UA3_RXD MPP(29, 0x4, 0, 0, 1)
+#define MPP29_SYSRST_OUTn MPP(29, 0x5, 0, 0, 1)
+#define MPP29_TDM_DTX MPP(29, 0x6, 0, 0, 1)
+#define MPP29_UNUSED MPP(29, 0x1, 0, 0, 1)
+
+#define MPP30_GPIO MPP(30, 0x0, 1, 1, 1)
+#define MPP30_UA3_CTSn MPP(30, 0x4, 0, 0, 1)
+#define MPP30_UNUSED MPP(30, 0x1, 0, 0, 1)
+
+#define MPP31_GPIO MPP(31, 0x0, 1, 1, 1)
+#define MPP31_UA3_RTSn MPP(31, 0x4, 0, 0, 1)
+#define MPP31_TDM1_SCSn MPP(31, 0x6, 0, 0, 1)
+#define MPP31_UNUSED MPP(31, 0x1, 0, 0, 1)
+
+
+#define MPP32_GPIO MPP(32, 0x1, 1, 1, 1)
+#define MPP32_UA3_TDX MPP(32, 0x4, 0, 0, 1)
+#define MPP32_SYSRST_OUTn MPP(32, 0x5, 0, 0, 1)
+#define MPP32_TDM0_RXQ MPP(32, 0x6, 0, 0, 1)
+#define MPP32_UNUSED MPP(32, 0x3, 0, 0, 1)
+
+
+#define MPP33_GPIO MPP(33, 0x1, 1, 1, 1)
+#define MPP33_UA3_RDX MPP(33, 0x4, 0, 0, 1)
+#define MPP33_TDM0_TXQ MPP(33, 0x6, 0, 0, 1)
+#define MPP33_UNUSED MPP(33, 0x3, 0, 0, 1)
+
+
+
+#define MPP34_GPIO MPP(34, 0x1, 1, 1, 1)
+#define MPP34_UA2_TDX MPP(34, 0x4, 0, 0, 1)
+#define MPP34_TDM1_RXQ MPP(34, 0x6, 0, 0, 1)
+#define MPP34_UNUSED MPP(34, 0x3, 0, 0, 1)
+
+
+
+#define MPP35_GPIO MPP(35, 0x1, 1, 1, 1)
+#define MPP35_UA2_RDX MPP(35, 0x4, 0, 0, 1)
+#define MPP35_TDM1_TXQ MPP(35, 0x6, 0, 0, 1)
+#define MPP35_UNUSED MPP(35, 0x3, 0, 0, 1)
+
+#define MPP36_GPIO MPP(36, 0x1, 1, 1, 1)
+#define MPP36_UA0_CTSn MPP(36, 0x2, 0, 0, 1)
+#define MPP36_UA2_TDX MPP(36, 0x4, 0, 0, 1)
+#define MPP36_TDM0_SCSn MPP(36, 0x6, 0, 0, 1)
+#define MPP36_UNUSED MPP(36, 0x3, 0, 0, 1)
+
+
+#define MPP37_GPIO MPP(37, 0x1, 1, 1, 1)
+#define MPP37_UA0_RTSn MPP(37, 0x2, 0, 0, 1)
+#define MPP37_UA2_RXD MPP(37, 0x4, 0, 0, 1)
+#define MPP37_SYSRST_OUTn MPP(37, 0x5, 0, 0, 1)
+#define MPP37_TDM_SCLK MPP(37, 0x6, 0, 0, 1)
+#define MPP37_UNUSED MPP(37, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP38_GPIO MPP(38, 0x1, 1, 1, 1)
+#define MPP38_UA1_CTSn MPP(38, 0x2, 0, 0, 1)
+#define MPP38_UA3_TXD MPP(38, 0x4, 0, 0, 1)
+#define MPP38_SYSRST_OUTn MPP(38, 0x5, 0, 0, 1)
+#define MPP38_TDM_SMOSI MPP(38, 0x6, 0, 0, 1)
+#define MPP38_UNUSED MPP(38, 0x3, 0, 0, 1)
+
+
+
+
+#define MPP39_GPIO MPP(39, 0x1, 1, 1, 1)
+#define MPP39_UA1_RTSn MPP(39, 0x2, 0, 0, 1)
+#define MPP39_UA3_RXD MPP(39, 0x4, 0, 0, 1)
+#define MPP39_SYSRST_OUTn MPP(39, 0x5, 0, 0, 1)
+#define MPP39_TDM_SMISO MPP(39, 0x6, 0, 0, 1)
+#define MPP39_UNUSED MPP(39, 0x3, 0, 0, 1)
+
+
+
+#define MPP40_GPIO MPP(40, 0x1, 1, 1, 1)
+#define MPP40_TDM_INTn MPP(40, 0x6, 0, 0, 1)
+#define MPP40_UNUSED MPP(40, 0x0, 0, 0, 1)
+
+
+
+#define MPP41_GPIO MPP(41, 0x1, 1, 1, 1)
+#define MPP41_TDM_RSTn MPP(41, 0x6, 0, 0, 1)
+#define MPP41_UNUSED MPP(41, 0x0, 0, 0, 1)
+
+
+
+#define MPP42_GPIO MPP(42, 0x1, 1, 1, 1)
+#define MPP42_TDM_PCLK MPP(42, 0x6, 0, 0, 1)
+#define MPP42_UNUSED MPP(42, 0x0, 0, 0, 1)
+
+
+
+#define MPP43_GPIO MPP(43, 0x1, 1, 1, 1)
+#define MPP43_TDM_FSYNC MPP(43, 0x6, 0, 0, 1)
+#define MPP43_UNUSED MPP(43, 0x0, 0, 0, 1)
+
+
+
+#define MPP44_GPIO MPP(44, 0x1, 1, 1, 1)
+#define MPP44_TDM_DRX MPP(44, 0x6, 0, 0, 1)
+#define MPP44_UNUSED MPP(44, 0x0, 0, 0, 1)
+
+
+
+#define MPP45_GPIO MPP(45, 0x1, 1, 1, 1)
+#define MPP45_SATA0_ACTn MPP(45, 0x3, 0, 0, 1)
+#define MPP45_TDM_DRX MPP(45, 0x6, 0, 0, 1)
+#define MPP45_UNUSED MPP(45, 0x0, 0, 0, 1)
+
+
+#define MPP46_GPIO MPP(46, 0x1, 1, 1, 1)
+#define MPP46_TDM_SCSn MPP(46, 0x6, 0, 0, 1)
+#define MPP46_UNUSED MPP(46, 0x0, 0, 0, 1)
+
+
+#define MPP47_GPIO MPP(47, 0x1, 1, 1, 1)
+#define MPP47_UNUSED MPP(47, 0x0, 0, 0, 1)
+
+
+
+#define MPP48_GPIO MPP(48, 0x1, 1, 1, 1)
+#define MPP48_SATA1_ACTn MPP(48, 0x3, 0, 0, 1)
+#define MPP48_UNUSED MPP(48, 0x2, 0, 0, 1)
+
+
+
+#define MPP49_GPIO MPP(49, 0x1, 1, 1, 1)
+#define MPP49_SATA0_ACTn MPP(49, 0x3, 0, 0, 1)
+#define MPP49_M_BB MPP(49, 0x4, 0, 0, 1)
+#define MPP49_UNUSED MPP(49, 0x2, 0, 0, 1)
+
+
+#define MPP_MAX 49
+
+void mv78xx0_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
new file mode 100644
index 00000000..a560439d
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -0,0 +1,319 @@
+/*
+ * arch/arm/mach-mv78xx0/pcie.c
+ *
+ * PCIe functions for Marvell MV78xx0 SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mbus.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include "common.h"
+
+struct pcie_port {
+ u8 maj;
+ u8 min;
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ char io_space_name[16];
+ char mem_space_name[16];
+ struct resource res[2];
+};
+
+static struct pcie_port pcie_port[8];
+static int num_pcie_ports;
+static struct resource pcie_io_space;
+static struct resource pcie_mem_space;
+
+
+void __init mv78xx0_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id((void __iomem *)PCIE00_VIRT_BASE);
+ *rev = orion_pcie_rev((void __iomem *)PCIE00_VIRT_BASE);
+}
+
+static void __init mv78xx0_pcie_preinit(void)
+{
+ int i;
+ u32 size_each;
+ u32 start;
+ int win;
+
+ pcie_io_space.name = "PCIe I/O Space";
+ pcie_io_space.start = MV78XX0_PCIE_IO_PHYS_BASE(0);
+ pcie_io_space.end =
+ MV78XX0_PCIE_IO_PHYS_BASE(0) + MV78XX0_PCIE_IO_SIZE * 8 - 1;
+ pcie_io_space.flags = IORESOURCE_IO;
+ if (request_resource(&iomem_resource, &pcie_io_space))
+ panic("can't allocate PCIe I/O space");
+
+ pcie_mem_space.name = "PCIe MEM Space";
+ pcie_mem_space.start = MV78XX0_PCIE_MEM_PHYS_BASE;
+ pcie_mem_space.end =
+ MV78XX0_PCIE_MEM_PHYS_BASE + MV78XX0_PCIE_MEM_SIZE - 1;
+ pcie_mem_space.flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pcie_mem_space))
+ panic("can't allocate PCIe MEM space");
+
+ for (i = 0; i < num_pcie_ports; i++) {
+ struct pcie_port *pp = pcie_port + i;
+
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d.%d I/O", pp->maj, pp->min);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ pp->res[0].start = MV78XX0_PCIE_IO_PHYS_BASE(i);
+ pp->res[0].end = pp->res[0].start + MV78XX0_PCIE_IO_SIZE - 1;
+ pp->res[0].flags = IORESOURCE_IO;
+
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d.%d MEM", pp->maj, pp->min);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ pp->res[1].flags = IORESOURCE_MEM;
+ }
+
+ switch (num_pcie_ports) {
+ case 0:
+ size_each = 0;
+ break;
+
+ case 1:
+ size_each = 0x30000000;
+ break;
+
+ case 2 ... 3:
+ size_each = 0x10000000;
+ break;
+
+ case 4 ... 6:
+ size_each = 0x08000000;
+ break;
+
+ case 7:
+ size_each = 0x04000000;
+ break;
+
+ default:
+ panic("invalid number of PCIe ports");
+ }
+
+ start = MV78XX0_PCIE_MEM_PHYS_BASE;
+ for (i = 0; i < num_pcie_ports; i++) {
+ struct pcie_port *pp = pcie_port + i;
+
+ pp->res[1].start = start;
+ pp->res[1].end = start + size_each - 1;
+ start += size_each;
+ }
+
+ for (i = 0; i < num_pcie_ports; i++) {
+ struct pcie_port *pp = pcie_port + i;
+
+ if (request_resource(&pcie_io_space, &pp->res[0]))
+ panic("can't allocate PCIe I/O sub-space");
+
+ if (request_resource(&pcie_mem_space, &pp->res[1]))
+ panic("can't allocate PCIe MEM sub-space");
+ }
+
+ win = 0;
+ for (i = 0; i < num_pcie_ports; i++) {
+ struct pcie_port *pp = pcie_port + i;
+
+ mv78xx0_setup_pcie_io_win(win++, pp->res[0].start,
+ pp->res[0].end - pp->res[0].start + 1,
+ pp->maj, pp->min);
+
+ mv78xx0_setup_pcie_mem_win(win++, pp->res[1].start,
+ pp->res[1].end - pp->res[1].start + 1,
+ pp->maj, pp->min);
+ }
+}
+
+static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct pcie_port *pp;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ pp = &pcie_port[nr];
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * Generic PCIe unit setup.
+ */
+ orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+ orion_pcie_setup(pp->base, &mv78xx0_mbus_dram_info);
+
+ sys->resource[0] = &pp->res[0];
+ sys->resource[1] = &pp->res[1];
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+static struct pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = num_pcie_ports - 1; i >= 0; i--) {
+ int rbus = pcie_port[i].root_bus_nr;
+ if (rbus != -1 && rbus <= bus)
+ break;
+ }
+
+ return i >= 0 ? pcie_port + i : NULL;
+}
+
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
+{
+ /*
+ * Don't go out when trying to access nonexisting devices
+ * on the local bus.
+ */
+ if (bus == pp->root_bus_nr && dev > 1)
+ return 0;
+
+ return 1;
+}
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static struct pci_ops pcie_ops = {
+ .read = pcie_rd_conf,
+ .write = pcie_wr_conf,
+};
+
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+ /*
+ * Prevent enumeration of root complex.
+ */
+ if (dev->bus->parent == NULL && dev->devfn == 0) {
+ int i;
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static struct pci_bus __init *
+mv78xx0_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr < num_pcie_ports) {
+ bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+static int __init mv78xx0_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+ return IRQ_MV78XX0_PCIE_00 + (pp->maj << 2) + pp->min;
+}
+
+static struct hw_pci mv78xx0_pci __initdata = {
+ .nr_controllers = 8,
+ .preinit = mv78xx0_pcie_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = mv78xx0_pcie_setup,
+ .scan = mv78xx0_pcie_scan_bus,
+ .map_irq = mv78xx0_pcie_map_irq,
+};
+
+static void __init add_pcie_port(int maj, int min, unsigned long base)
+{
+ printk(KERN_INFO "MV78xx0 PCIe port %d.%d: ", maj, min);
+
+ if (orion_pcie_link_up((void __iomem *)base)) {
+ struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+ printk("link up\n");
+
+ pp->maj = maj;
+ pp->min = min;
+ pp->root_bus_nr = -1;
+ pp->base = (void __iomem *)base;
+ spin_lock_init(&pp->conf_lock);
+ memset(pp->res, 0, sizeof(pp->res));
+ } else {
+ printk("link down, ignoring\n");
+ }
+}
+
+void __init mv78xx0_pcie_init(int init_port0, int init_port1)
+{
+ if (init_port0) {
+ add_pcie_port(0, 0, PCIE00_VIRT_BASE);
+ if (!orion_pcie_x4_mode((void __iomem *)PCIE00_VIRT_BASE)) {
+ add_pcie_port(0, 1, PCIE01_VIRT_BASE);
+ add_pcie_port(0, 2, PCIE02_VIRT_BASE);
+ add_pcie_port(0, 3, PCIE03_VIRT_BASE);
+ }
+ }
+
+ if (init_port1) {
+ add_pcie_port(1, 0, PCIE10_VIRT_BASE);
+ if (!orion_pcie_x4_mode((void __iomem *)PCIE10_VIRT_BASE)) {
+ add_pcie_port(1, 1, PCIE11_VIRT_BASE);
+ add_pcie_port(1, 2, PCIE12_VIRT_BASE);
+ add_pcie_port(1, 3, PCIE13_VIRT_BASE);
+ }
+ }
+
+ pci_common_init(&mv78xx0_pci);
+}
diff --git a/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
new file mode 100644
index 00000000..d927f14c
--- /dev/null
+++ b/arch/arm/mach-mv78xx0/rd78x00-masa-setup.c
@@ -0,0 +1,87 @@
+/*
+ * arch/arm/mach-mv78x00/rd78x00-masa-setup.c
+ *
+ * Marvell RD-78x00-mASA Development Board Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <mach/mv78xx0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge00_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge01_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(9),
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge10_data = {
+};
+
+static struct mv643xx_eth_platform_data rd78x00_masa_ge11_data = {
+};
+
+static struct mv_sata_platform_data rd78x00_masa_sata_data = {
+ .n_ports = 2,
+};
+
+static void __init rd78x00_masa_init(void)
+{
+ /*
+ * Basic MV78x00 setup. Needs to be called early.
+ */
+ mv78xx0_init();
+
+ /*
+ * Partition on-chip peripherals between the two CPU cores.
+ */
+ if (mv78xx0_core_index() == 0) {
+ mv78xx0_ehci0_init();
+ mv78xx0_ehci1_init();
+ mv78xx0_ge00_init(&rd78x00_masa_ge00_data);
+ mv78xx0_ge10_init(&rd78x00_masa_ge10_data);
+ mv78xx0_sata_init(&rd78x00_masa_sata_data);
+ mv78xx0_uart0_init();
+ mv78xx0_uart2_init();
+ } else {
+ mv78xx0_ehci2_init();
+ mv78xx0_ge01_init(&rd78x00_masa_ge01_data);
+ mv78xx0_ge11_init(&rd78x00_masa_ge11_data);
+ mv78xx0_uart1_init();
+ mv78xx0_uart3_init();
+ }
+}
+
+static int __init rd78x00_pci_init(void)
+{
+ /*
+ * Assign all PCIe devices to CPU core #0.
+ */
+ if (machine_is_rd78x00_masa() && mv78xx0_core_index() == 0)
+ mv78xx0_pcie_init(1, 1);
+
+ return 0;
+}
+subsys_initcall(rd78x00_pci_init);
+
+MACHINE_START(RD78X00_MASA, "Marvell RD-78x00-MASA Development Board")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd78x00_masa_init,
+ .map_io = mv78xx0_map_io,
+ .init_early = mv78xx0_init_early,
+ .init_irq = mv78xx0_init_irq,
+ .timer = &mv78xx0_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
new file mode 100755
index 00000000..acac8d32
--- /dev/null
+++ b/arch/arm/mach-mx5/Kconfig
@@ -0,0 +1,263 @@
+if ARCH_MX503 || ARCH_MX51
+# ARCH_MX5/50/53 are left to mark places where prevent multi-soc in single
+# image. So for most time, SOC_IMX50/51/53 should be used.
+
+config ARCH_MX5
+ bool
+
+config ARCH_MX50
+ bool
+
+config ARCH_MX53
+ bool
+
+config SOC_IMX50
+ bool
+ select CPU_V7
+ select ARM_L1_CACHE_SHIFT_6
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_HAS_CPUFREQ
+ select ARCH_MX5
+ select ARCH_MX50
+ select ARCH_HAS_RNGC
+
+config SOC_IMX51
+ bool
+ select CPU_V7
+ select ARM_L1_CACHE_SHIFT_6
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_HAS_CPUFREQ
+ select ARCH_MX5
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_MXC_PWM
+ select IMX_HAVE_PLATFORM_IMX_IPUV3
+ select IMX_HAVE_PLATFORM_IMX_TVE
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_IIM
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+
+config SOC_IMX53
+ bool
+ select CPU_V7
+ select ARM_L1_CACHE_SHIFT_6
+ select MXC_TZIC
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MX5
+ select ARCH_MX53
+ select ARCH_HAS_CPUFREQ
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_MXC_PWM
+ select IMX_HAVE_PLATFORM_IMX_IPUV3
+ select IMX_HAVE_PLATFORM_IMX_TVE
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_IIM
+ select IMX_HAVE_PLATFORM_LDB
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_IMX_ESAI
+
+if ARCH_MX50_SUPPORTED
+#comment "i.MX50 machines:"
+
+config MACH_MX50_RDP
+ bool "Support MX50 reference design platform"
+ select SOC_IMX50
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX_DCP
+ select IMX_HAVE_PLATFORM_RANDOM_RNGC
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+ help
+ Include support for MX50 reference design platform (RDP) board. This
+ includes specific configurations for the board and its peripherals.
+
+endif # ARCH_MX50_SUPPORTED
+
+if ARCH_MX51
+comment "i.MX51 machines:"
+
+config MACH_MX51_BABBAGE
+ bool "Support MX51 BABBAGE platforms"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for MX51 Babbage platform, also known as MX51EVK in
+ u-boot. This includes specific configurations for the board and its
+ peripherals.
+
+config MACH_MX51_3DS
+ bool "Support MX51PDK (3DS)"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_DEBUG_BOARD
+ help
+ Include support for MX51PDK (3DS) platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_EUKREA_CPUIMX51
+ bool "Support Eukrea CPUIMX51 module"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ help
+ Include support for Eukrea CPUIMX51 platform. This includes
+ specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX51
+ default MACH_EUKREA_MBIMX51_BASEBOARD
+
+config MACH_EUKREA_MBIMX51_BASEBOARD
+ prompt "Eukrea MBIMX51 development board"
+ bool
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMX51 evaluation board.
+
+endchoice
+
+config MACH_EUKREA_CPUIMX51SD
+ bool "Support Eukrea CPUIMX51SD module"
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ help
+ Include support for Eukrea CPUIMX51SD platform. This includes
+ specific configurations for the module and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX51SD
+ default MACH_EUKREA_MBIMXSD51_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD51_BASEBOARD
+ prompt "Eukrea MBIMXSD development board"
+ bool
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
+config MX51_EFIKA_COMMON
+ bool
+ select SOC_IMX51
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select MXC_ULPI if USB_ULPI
+
+config MACH_MX51_EFIKAMX
+ bool "Support MX51 Genesi Efika MX nettop"
+ select MX51_EFIKA_COMMON
+ help
+ Include support for Genesi Efika MX nettop. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX51_EFIKASB
+ bool "Support MX51 Genesi Efika Smartbook"
+ select MX51_EFIKA_COMMON
+ help
+ Include support for Genesi Efika Smartbook. This includes specific
+ configurations for the board and its peripherals.
+
+endif # ARCH_MX51
+
+if ARCH_MX53_SUPPORTED
+comment "i.MX53 machines:"
+
+config MACH_MX53_EVK
+ bool "Support MX53 EVK platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_MXC_GPU
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_AHCI
+ help
+ Include support for MX53 EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_SMD
+ bool "Support MX53 SMD platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_MXC_GPU
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_IMX_SRTC
+ select IMX_HAVE_PLATFORM_AHCI
+ help
+ Include support for MX53 SMD platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_LOCO
+ bool "Support MX53 LOCO platforms"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_SRTC
+ select IMX_HAVE_PLATFORM_MXC_GPU
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
+ select IMX_HAVE_PLATFORM_AHCI
+ help
+ Include support for MX53 LOCO platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX53_ARD
+ bool "Support MX53 ARD platform"
+ select SOC_IMX53
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_GPU
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_AHCI
+ help
+ Include support for MX53 ARD platform. This includes specific
+ configurations for the board and its peripherals.
+endif # ARCH_MX53_SUPPORTED
+
+config MACH_IMX_BLUETOOTH_RFKILL
+ tristate "i.MX Bluetooth rfkill interface support"
+ depends on RFKILL
+ ---help---
+ Say Y to get the standard rfkill interface of Bluetooth
+endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
new file mode 100755
index 00000000..8dbcf863
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile
@@ -0,0 +1,28 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y := cpu.o mm.o devices.o ehci.o bus_freq.o sdram_autogating.o \
+pm.o system.o suspend.o usb_dr.o usb_h1.o usb_h2.o cpu_regulator-mx5.o
+
+obj-$(CONFIG_SOC_IMX50) += clock_mx50.o mm-mx50.o mx50_wfi.o mx50_suspend.o mx50_freq.o mx50_ddr_freq.o
+obj-$(CONFIG_SOC_IMX51) += clock.o
+obj-$(CONFIG_SOC_IMX53) += clock.o
+
+obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o cpu_op-mx53.o cpu_op-mx50.o
+obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o mx51_babbage_pmic_mc13892.o
+obj-$(CONFIG_MACH_MX51_3DS) += board-mx51_3ds.o
+obj-$(CONFIG_MACH_MX53_EVK) += board-mx53_evk.o
+obj-$(CONFIG_MACH_MX53_SMD) += board-mx53_smd.o mx53_smd_pmic_da9053.o
+obj-$(CONFIG_MACH_IMX_BLUETOOTH_RFKILL) += imx_bt_rfkill.o
+obj-$(CONFIG_MACH_MX53_LOCO) += board-mx53_loco.o mx53_loco_pmic_da9053.o mx53_loco_pmic_mc34708.o
+obj-$(CONFIG_MACH_MX53_ARD) += board-mx53_ard.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX51) += board-cpuimx51.o
+obj-$(CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD) += eukrea_mbimx51-baseboard.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += board-cpuimx51sd.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd-baseboard.o
+obj-$(CONFIG_MX51_EFIKA_COMMON) += mx51_efika.o
+obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
+obj-$(CONFIG_MACH_MX51_EFIKASB) += board-mx51_efikasb.o
+obj-$(CONFIG_MACH_MX50_RDP) += board-mx50_rdp.o mx50_rdp_pmic_mc13892.o
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
new file mode 100644
index 00000000..e928be1b
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -0,0 +1,9 @@
+ zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000
+params_phys-$(CONFIG_ARCH_MX50) := 0x70000100
+initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000
+ zreladdr-$(CONFIG_ARCH_MX51) := 0x90008000
+params_phys-$(CONFIG_ARCH_MX51) := 0x90000100
+initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
+ zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000
+params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
+initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
new file mode 100644
index 00000000..4efa02ee
--- /dev/null
+++ b/arch/arm/mach-mx5/board-cpuimx51.c
@@ -0,0 +1,304 @@
+/*
+ *
+ * Copyright (C) 2010 Eric Bénard <eric@eukrea.com>
+ *
+ * based on board-mx51_babbage.c which is
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define CPUIMX51_USBH1_STP IMX_GPIO_NR(1, 27)
+#define CPUIMX51_QUARTA_GPIO IMX_GPIO_NR(3, 28)
+#define CPUIMX51_QUARTB_GPIO IMX_GPIO_NR(3, 25)
+#define CPUIMX51_QUARTC_GPIO IMX_GPIO_NR(3, 26)
+#define CPUIMX51_QUARTD_GPIO IMX_GPIO_NR(3, 27)
+#define CPUIMX51_QUARTA_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO)
+#define CPUIMX51_QUARTB_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO)
+#define CPUIMX51_QUARTC_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO)
+#define CPUIMX51_QUARTD_IRQ (MXC_INTERNAL_IRQS + CPUIMX51_QUARTD_GPIO)
+#define CPUIMX51_QUART_XTAL 14745600
+#define CPUIMX51_QUART_REGSHIFT 17
+
+/* USB_CTRL_1 */
+#define MX51_USB_CTRL_1_OFFSET 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+
+#define MX51_USB_PLLDIV_12_MHZ 0x00
+#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
+#define MX51_USB_PLL_DIV_24_MHZ 0x02
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x400000),
+ .irq = CPUIMX51_QUARTA_IRQ,
+ .irqflags = IRQF_TRIGGER_HIGH,
+ .uartclk = CPUIMX51_QUART_XTAL,
+ .regshift = CPUIMX51_QUART_REGSHIFT,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x800000),
+ .irq = CPUIMX51_QUARTB_IRQ,
+ .irqflags = IRQF_TRIGGER_HIGH,
+ .uartclk = CPUIMX51_QUART_XTAL,
+ .regshift = CPUIMX51_QUART_REGSHIFT,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x1000000),
+ .irq = CPUIMX51_QUARTC_IRQ,
+ .irqflags = IRQF_TRIGGER_HIGH,
+ .uartclk = CPUIMX51_QUART_XTAL,
+ .regshift = CPUIMX51_QUART_REGSHIFT,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000),
+ .irq = CPUIMX51_QUARTD_IRQ,
+ .irqflags = IRQF_TRIGGER_HIGH,
+ .uartclk = CPUIMX51_QUART_XTAL,
+ .regshift = CPUIMX51_QUART_REGSHIFT,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ }, {
+ }
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &serial_device,
+};
+
+static iomux_v3_cfg_t eukrea_cpuimx51_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* I2C2 */
+ MX51_PAD_GPIO1_2__I2C2_SCL,
+ MX51_PAD_GPIO1_3__I2C2_SDA,
+ MX51_PAD_NANDF_D10__GPIO3_30,
+
+ /* QUART IRQ */
+ MX51_PAD_NANDF_D15__GPIO3_25,
+ MX51_PAD_NANDF_D14__GPIO3_26,
+ MX51_PAD_NANDF_D13__GPIO3_27,
+ MX51_PAD_NANDF_D12__GPIO3_28,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+ MX51_PAD_USBH1_STP__USBH1_STP,
+};
+
+static const struct mxc_nand_platform_data
+ eukrea_cpuimx51_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const
+struct imxi2c_platform_data eukrea_cpuimx51_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx51_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+/* This function is board specific as the bit mask for the plldiv will also
+be different for other Freescale SoCs, thus a common bitmask is not
+possible and cannot get place in /plat-mxc/ehci.c.*/
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_19_2_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
+}
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* The clock for the USBH1 ULPI port will come externally from the PHY. */
+ v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
+ __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_ITC_NO_THRESHOLD);
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+};
+
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .init = initialize_usbh1_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx51_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx51_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init eukrea_cpuimx51_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51_pads,
+ ARRAY_SIZE(eukrea_cpuimx51_pads));
+
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_mxc_nand(&eukrea_cpuimx51_nand_board_info);
+
+ gpio_request(CPUIMX51_QUARTA_GPIO, "quarta_irq");
+ gpio_direction_input(CPUIMX51_QUARTA_GPIO);
+ gpio_free(CPUIMX51_QUARTA_GPIO);
+ gpio_request(CPUIMX51_QUARTB_GPIO, "quartb_irq");
+ gpio_direction_input(CPUIMX51_QUARTB_GPIO);
+ gpio_free(CPUIMX51_QUARTB_GPIO);
+ gpio_request(CPUIMX51_QUARTC_GPIO, "quartc_irq");
+ gpio_direction_input(CPUIMX51_QUARTC_GPIO);
+ gpio_free(CPUIMX51_QUARTC_GPIO);
+ gpio_request(CPUIMX51_QUARTD_GPIO, "quartd_irq");
+ gpio_direction_input(CPUIMX51_QUARTD_GPIO);
+ gpio_free(CPUIMX51_QUARTD_GPIO);
+
+ imx51_add_fec(NULL);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx51_add_imx_i2c(1, &eukrea_cpuimx51_i2c_data);
+ i2c_register_board_info(1, eukrea_cpuimx51_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx51_i2c_devices));
+
+ if (otg_mode_host)
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ else {
+ initialize_otg_port(NULL);
+ mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
+ }
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMX51_BASEBOARD
+ eukrea_mbimx51_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx51_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = eukrea_cpuimx51_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")
+ /* Maintainer: Eric Bénard <eric@eukrea.com> */
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &mxc_timer,
+ .init_machine = eukrea_cpuimx51_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
new file mode 100644
index 00000000..5ef25a59
--- /dev/null
+++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
@@ -0,0 +1,338 @@
+/*
+ *
+ * Copyright (C) 2010 Eric Bénard <eric@eukrea.com>
+ *
+ * based on board-mx51_babbage.c which is
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c-gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+#include "cpu_op-mx51.h"
+
+#define USBH1_RST IMX_GPIO_NR(2, 28)
+#define ETH_RST IMX_GPIO_NR(2, 31)
+#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 12)
+#define CAN_IRQGPIO IMX_GPIO_NR(1, 1)
+#define CAN_RST IMX_GPIO_NR(4, 15)
+#define CAN_NCS IMX_GPIO_NR(4, 24)
+#define CAN_RXOBF IMX_GPIO_NR(1, 4)
+#define CAN_RX1BF IMX_GPIO_NR(1, 6)
+#define CAN_TXORTS IMX_GPIO_NR(1, 7)
+#define CAN_TX1RTS IMX_GPIO_NR(1, 8)
+#define CAN_TX2RTS IMX_GPIO_NR(1, 9)
+#define I2C_SCL IMX_GPIO_NR(4, 16)
+#define I2C_SDA IMX_GPIO_NR(4, 17)
+
+/* USB_CTRL_1 */
+#define MX51_USB_CTRL_1_OFFSET 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+
+#define MX51_USB_PLLDIV_12_MHZ 0x00
+#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
+#define MX51_USB_PLL_DIV_24_MHZ 0x02
+
+static iomux_v3_cfg_t eukrea_cpuimx51sd_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+ MX51_PAD_USBH1_STP__USBH1_STP,
+ MX51_PAD_EIM_CS3__GPIO2_28, /* PHY nRESET */
+
+ /* FEC */
+ MX51_PAD_EIM_DTACK__GPIO2_31, /* PHY nRESET */
+
+ /* HSI2C */
+ MX51_PAD_I2C1_CLK__GPIO4_16,
+ MX51_PAD_I2C1_DAT__GPIO4_17,
+
+ /* CAN */
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+ MX51_PAD_CSPI1_SS0__GPIO4_24, /* nCS */
+ MX51_PAD_CSI2_PIXCLK__GPIO4_15, /* nReset */
+ MX51_PAD_GPIO1_1__GPIO1_1, /* IRQ */
+ MX51_PAD_GPIO1_4__GPIO1_4, /* Control signals */
+ MX51_PAD_GPIO1_6__GPIO1_6,
+ MX51_PAD_GPIO1_7__GPIO1_7,
+ MX51_PAD_GPIO1_8__GPIO1_8,
+ MX51_PAD_GPIO1_9__GPIO1_9,
+
+ /* Touchscreen */
+ /* IRQ */
+ _MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+};
+
+static struct i2c_board_info eukrea_cpuimx51sd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("tsc2007", 0x49),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = gpio_to_irq(TSC2007_IRQGPIO),
+ },
+};
+
+static const struct mxc_nand_platform_data
+ eukrea_cpuimx51sd_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+/* This function is board specific as the bit mask for the plldiv will also
+be different for other Freescale SoCs, thus a common bitmask is not
+possible and cannot get place in /plat-mxc/ehci.c.*/
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_19_2_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
+}
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* The clock for the USBH1 ULPI port will come from the PHY. */
+ v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
+ __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN,
+ usbother_base + MX51_USB_CTRL_1_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_ITC_NO_THRESHOLD);
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+};
+
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .init = initialize_usbh1_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx51sd_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx51sd_otg_mode);
+
+static struct i2c_gpio_platform_data pdata = {
+ .sda_pin = I2C_SDA,
+ .sda_is_open_drain = 0,
+ .scl_pin = I2C_SCL,
+ .scl_is_open_drain = 0,
+ .udelay = 2,
+};
+
+static struct platform_device hsi2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev.platform_data = &pdata,
+};
+
+static struct mcp251x_platform_data mcp251x_info = {
+ .oscillator_frequency = 24E6,
+};
+
+static struct spi_board_info cpuimx51sd_spi_device[] = {
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 10000000,
+ .bus_num = 0,
+ .mode = SPI_MODE_0,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .irq = gpio_to_irq(CAN_IRQGPIO)
+ },
+};
+
+static int cpuimx51sd_spi1_cs[] = {
+ CAN_NCS,
+};
+
+static const struct spi_imx_master cpuimx51sd_ecspi1_pdata __initconst = {
+ .chipselect = cpuimx51sd_spi1_cs,
+ .num_chipselect = ARRAY_SIZE(cpuimx51sd_spi1_cs),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &hsi2c_gpio_device,
+};
+
+static void __init eukrea_cpuimx51sd_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads,
+ ARRAY_SIZE(eukrea_cpuimx51sd_pads));
+
+#if defined(CONFIG_CPU_FREQ_IMX)
+ get_cpu_op = mx51_get_cpu_op;
+#endif
+
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info);
+
+ gpio_request(ETH_RST, "eth_rst");
+ gpio_set_value(ETH_RST, 1);
+ imx51_add_fec(NULL);
+
+ gpio_request(CAN_IRQGPIO, "can_irq");
+ gpio_direction_input(CAN_IRQGPIO);
+ gpio_free(CAN_IRQGPIO);
+ gpio_request(CAN_NCS, "can_ncs");
+ gpio_direction_output(CAN_NCS, 1);
+ gpio_free(CAN_NCS);
+ gpio_request(CAN_RST, "can_rst");
+ gpio_direction_output(CAN_RST, 0);
+ msleep(20);
+ gpio_set_value(CAN_RST, 1);
+ imx51_add_ecspi(0, &cpuimx51sd_ecspi1_pdata);
+ spi_register_board_info(cpuimx51sd_spi_device,
+ ARRAY_SIZE(cpuimx51sd_spi_device));
+
+ gpio_request(TSC2007_IRQGPIO, "tsc2007_irq");
+ gpio_direction_input(TSC2007_IRQGPIO);
+ gpio_free(TSC2007_IRQGPIO);
+
+ i2c_register_board_info(0, eukrea_cpuimx51sd_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx51sd_i2c_devices));
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ if (otg_mode_host)
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ else {
+ initialize_otg_port(NULL);
+ mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
+ }
+
+ gpio_request(USBH1_RST, "usb_rst");
+ gpio_direction_output(USBH1_RST, 0);
+ msleep(20);
+ gpio_set_value(USBH1_RST, 1);
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD
+ eukrea_mbimxsd51_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx51sd_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = eukrea_cpuimx51sd_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
+ /* Maintainer: Eric Bénard <eric@eukrea.com> */
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &mxc_timer,
+ .init_machine = eukrea_cpuimx51sd_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx50_rdp.c b/arch/arm/mach-mx5/board-mx50_rdp.c
new file mode 100755
index 00000000..f191d1c4
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx50_rdp.c
@@ -0,0 +1,905 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx50.h>
+#include <mach/epdc.h>
+#include <mach/mxc_dvfs.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx50.h"
+#include "cpu_op-mx50.h"
+#include "devices.h"
+#include "usb.h"
+#include "crm_regs.h"
+
+#define FEC_EN IMX_GPIO_NR(6, 23)
+#define FEC_RESET_B IMX_GPIO_NR(4, 12)
+#define MX50_RDP_CSPI_CS0 IMX_GPIO_NR(4, 13)
+#define MX50_RDP_CSPI_CS1 IMX_GPIO_NR(4, 11)
+#define MX50_RDP_EPDC_D0 IMX_GPIO_NR(3, 0)
+#define MX50_RDP_EPDC_D1 IMX_GPIO_NR(3, 1)
+#define MX50_RDP_EPDC_D2 IMX_GPIO_NR(3, 2)
+#define MX50_RDP_EPDC_D3 IMX_GPIO_NR(3, 3)
+#define MX50_RDP_EPDC_D4 IMX_GPIO_NR(3, 4)
+#define MX50_RDP_EPDC_D5 IMX_GPIO_NR(3, 5)
+#define MX50_RDP_EPDC_D6 IMX_GPIO_NR(3, 6)
+#define MX50_RDP_EPDC_D7 IMX_GPIO_NR(3, 7)
+#define MX50_RDP_EPDC_GDCLK IMX_GPIO_NR(3, 16)
+#define MX50_RDP_EPDC_GDSP IMX_GPIO_NR(3, 17)
+#define MX50_RDP_EPDC_GDOE IMX_GPIO_NR(3, 18)
+#define MX50_RDP_EPDC_GDRL IMX_GPIO_NR(3, 19)
+#define MX50_RDP_EPDC_SDCLK IMX_GPIO_NR(3, 20)
+#define MX50_RDP_EPDC_SDOEZ IMX_GPIO_NR(3, 21)
+#define MX50_RDP_EPDC_SDOED IMX_GPIO_NR(3, 22)
+#define MX50_RDP_EPDC_SDOE IMX_GPIO_NR(3, 23)
+#define MX50_RDP_EPDC_SDLE IMX_GPIO_NR(3, 24)
+#define MX50_RDP_EPDC_SDCLKN IMX_GPIO_NR(3, 25)
+#define MX50_RDP_EPDC_SDSHR IMX_GPIO_NR(3, 26)
+#define MX50_RDP_EPDC_PWRCOM IMX_GPIO_NR(3, 27)
+#define MX50_RDP_EPDC_PWRSTAT IMX_GPIO_NR(3, 28)
+#define MX50_RDP_EPDC_PWRCTRL0 IMX_GPIO_NR(3, 29)
+#define MX50_RDP_EPDC_PWRCTRL1 IMX_GPIO_NR(3, 30)
+#define MX50_RDP_EPDC_PWRCTRL2 IMX_GPIO_NR(3, 31)
+#define MX50_RDP_EPDC_PWRCTRL3 IMX_GPIO_NR(4, 20)
+#define MX50_RDP_EPDC_BDR0 IMX_GPIO_NR(4, 23)
+#define MX50_RDP_EPDC_BDR1 IMX_GPIO_NR(4, 24)
+#define MX50_RDP_EPDC_SDCE0 IMX_GPIO_NR(4, 25)
+#define MX50_RDP_EPDC_SDCE1 IMX_GPIO_NR(4, 26)
+#define MX50_RDP_EPDC_SDCE2 IMX_GPIO_NR(4, 27)
+#define MX50_RDP_EPDC_SDCE3 IMX_GPIO_NR(4, 28)
+#define MX50_RDP_EPDC_SDCE4 IMX_GPIO_NR(4, 29)
+#define MX50_RDP_EPDC_SDCE5 IMX_GPIO_NR(4, 30)
+#define MX50_RDP_EPDC_PMIC_WAKE IMX_GPIO_NR(6, 16)
+#define MX50_RDP_EPDC_PMIC_INT IMX_GPIO_NR(6, 17)
+#define MX50_RDP_EPDC_VCOM IMX_GPIO_NR(4, 21)
+#define MX50_RDP_SD1_WP IMX_GPIO_NR(4, 19) /*GPIO_4_19 */
+#define MX50_RDP_SD1_CD IMX_GPIO_NR(1, 27) /*GPIO_1_27 */
+#define MX50_RDP_SD2_WP IMX_GPIO_NR(5, 16) /*GPIO_5_16 */
+#define MX50_RDP_SD2_CD IMX_GPIO_NR(5, 17) /*GPIO_5_17 */
+#define MX50_RDP_SD3_WP IMX_GPIO_NR(5, 28) /*GPIO_5_28 */
+#define MX50_RDP_USB_OTG_PWR IMX_GPIO_NR(6, 25) /*GPIO_6_25*/
+
+extern int mx50_rdp_init_mc13892(void);
+extern void mx5_cpu_regulator_init(void);
+extern char *lp_reg_id;
+extern char *gp_reg_id;
+static int max17135_regulator_init(struct max17135 *max17135);
+
+static iomux_v3_cfg_t mx50_rdp_pads[] __initdata = {
+ /* SD1 */
+ MX50_PAD_ECSPI2_SS0__GPIO_4_19,
+ MX50_PAD_EIM_CRE__GPIO_1_27,
+ MX50_PAD_SD1_CMD__SD1_CMD,
+
+ MX50_PAD_SD1_CLK__SD1_CLK,
+ MX50_PAD_SD1_D0__SD1_D0,
+ MX50_PAD_SD1_D1__SD1_D1,
+ MX50_PAD_SD1_D2__SD1_D2,
+ MX50_PAD_SD1_D3__SD1_D3,
+
+ /* SD2 */
+ MX50_PAD_SD2_CD__GPIO_5_17,
+ MX50_PAD_SD2_WP__GPIO_5_16,
+ MX50_PAD_SD2_CMD__SD2_CMD,
+ MX50_PAD_SD2_CLK__SD2_CLK,
+ MX50_PAD_SD2_D0__SD2_D0,
+ MX50_PAD_SD2_D1__SD2_D1,
+ MX50_PAD_SD2_D2__SD2_D2,
+ MX50_PAD_SD2_D3__SD2_D3,
+ MX50_PAD_SD2_D4__SD2_D4,
+ MX50_PAD_SD2_D5__SD2_D5,
+ MX50_PAD_SD2_D6__SD2_D6,
+ MX50_PAD_SD2_D7__SD2_D7,
+
+ /* SD3 */
+ MX50_PAD_SD3_CMD__SD3_CMD,
+ MX50_PAD_SD3_CLK__SD3_CLK,
+ MX50_PAD_SD3_D0__SD3_D0,
+ MX50_PAD_SD3_D1__SD3_D1,
+ MX50_PAD_SD3_D2__SD3_D2,
+ MX50_PAD_SD3_D3__SD3_D3,
+ MX50_PAD_SD3_D4__SD3_D4,
+ MX50_PAD_SD3_D5__SD3_D5,
+ MX50_PAD_SD3_D6__SD3_D6,
+ MX50_PAD_SD3_D7__SD3_D7,
+
+ /* PWR_INT */
+ MX50_PAD_ECSPI2_MISO__GPIO_4_18,
+
+ /* UART pad setting */
+ MX50_PAD_UART1_TXD__UART1_TXD,
+ MX50_PAD_UART1_RXD__UART1_RXD,
+ MX50_PAD_UART1_RTS__UART1_RTS,
+ MX50_PAD_UART2_TXD__UART2_TXD,
+ MX50_PAD_UART2_RXD__UART2_RXD,
+ MX50_PAD_UART2_CTS__UART2_CTS,
+ MX50_PAD_UART2_RTS__UART2_RTS,
+
+ MX50_PAD_I2C1_SCL__I2C1_SCL,
+ MX50_PAD_I2C1_SDA__I2C1_SDA,
+ MX50_PAD_I2C2_SCL__I2C2_SCL,
+ MX50_PAD_I2C2_SDA__I2C2_SDA,
+
+ /* EPDC pins */
+ MX50_PAD_EPDC_PWRSTAT__GPIO_3_28,
+ MX50_PAD_EPDC_VCOM0__GPIO_4_21,
+ MX50_PAD_EPDC_PWRCTRL0__GPIO_3_29,
+
+ MX50_PAD_DISP_D8__DISP_D8,
+ MX50_PAD_DISP_D9__DISP_D9,
+ MX50_PAD_DISP_D10__DISP_D10,
+ MX50_PAD_DISP_D11__DISP_D11,
+ MX50_PAD_DISP_D12__DISP_D12,
+ MX50_PAD_DISP_D13__DISP_D13,
+ MX50_PAD_DISP_D14__DISP_D14,
+ MX50_PAD_DISP_D15__DISP_D15,
+ MX50_PAD_DISP_RS__ELCDIF_VSYNC,
+
+ /* EPD PMIC WAKEUP */
+ MX50_PAD_UART4_TXD__GPIO_6_16,
+
+ /* EPD PMIC intr */
+ MX50_PAD_UART4_RXD__GPIO_6_17,
+
+ MX50_PAD_EPITO__USBH1_PWR,
+ /* Need to comment below line if
+ * one needs to debug owire.
+ */
+ MX50_PAD_OWIRE__USBH1_OC,
+ /* using gpio to control otg pwr */
+ MX50_PAD_PWM2__GPIO_6_25,
+ MX50_PAD_I2C3_SCL__USBOTG_OC,
+
+ MX50_PAD_SSI_RXC__FEC_MDIO,
+ MX50_PAD_SSI_RXFS__FEC_MDC,
+ MX50_PAD_DISP_D0__FEC_TXCLK,
+ MX50_PAD_DISP_D1__FEC_RX_ER,
+ MX50_PAD_DISP_D2__FEC_RX_DV,
+ MX50_PAD_DISP_D3__FEC_RXD1,
+ MX50_PAD_DISP_D4__FEC_RXD0,
+ MX50_PAD_DISP_D5__FEC_TX_EN,
+ MX50_PAD_DISP_D6__FEC_TXD1,
+ MX50_PAD_DISP_D7__FEC_TXD0,
+ MX50_PAD_I2C3_SDA__GPIO_6_23,
+ MX50_PAD_ECSPI1_SCLK__GPIO_4_12,
+
+ MX50_PAD_CSPI_SS0__CSPI_SS0,
+ MX50_PAD_ECSPI1_MOSI__CSPI_SS1,
+ MX50_PAD_CSPI_MOSI__CSPI_MOSI,
+ MX50_PAD_CSPI_MISO__CSPI_MISO,
+
+ /* SGTL500_OSC_EN */
+ MX50_PAD_UART1_CTS__GPIO_6_8,
+
+ /* SGTL_AMP_SHDN */
+ MX50_PAD_UART3_RXD__GPIO_6_15,
+
+ /* Keypad */
+ MX50_PAD_KEY_COL0__KEY_COL0,
+ MX50_PAD_KEY_ROW0__KEY_ROW0,
+ MX50_PAD_KEY_COL1__KEY_COL1,
+ MX50_PAD_KEY_ROW1__KEY_ROW1,
+ MX50_PAD_KEY_COL2__KEY_COL2,
+ MX50_PAD_KEY_ROW2__KEY_ROW2,
+ MX50_PAD_KEY_COL3__KEY_COL3,
+ MX50_PAD_KEY_ROW3__KEY_ROW3,
+ MX50_PAD_EIM_DA0__KEY_COL4,
+ MX50_PAD_EIM_DA1__KEY_ROW4,
+ MX50_PAD_EIM_DA2__KEY_COL5,
+ MX50_PAD_EIM_DA3__KEY_ROW5,
+ MX50_PAD_EIM_DA4__KEY_COL6,
+ MX50_PAD_EIM_DA5__KEY_ROW6,
+ MX50_PAD_EIM_DA6__KEY_COL7,
+ MX50_PAD_EIM_DA7__KEY_ROW7,
+ /*EIM pads */
+ MX50_PAD_EIM_DA8__GPIO_1_8,
+ MX50_PAD_EIM_DA9__GPIO_1_9,
+ MX50_PAD_EIM_DA10__GPIO_1_10,
+ MX50_PAD_EIM_DA11__GPIO_1_11,
+ MX50_PAD_EIM_DA12__GPIO_1_12,
+ MX50_PAD_EIM_DA13__GPIO_1_13,
+ MX50_PAD_EIM_DA14__GPIO_1_14,
+ MX50_PAD_EIM_DA15__GPIO_1_15,
+ MX50_PAD_EIM_CS2__GPIO_1_16,
+ MX50_PAD_EIM_CS1__GPIO_1_17,
+ MX50_PAD_EIM_CS0__GPIO_1_18,
+ MX50_PAD_EIM_EB0__GPIO_1_19,
+ MX50_PAD_EIM_EB1__GPIO_1_20,
+ MX50_PAD_EIM_WAIT__GPIO_1_21,
+ MX50_PAD_EIM_BCLK__GPIO_1_22,
+ MX50_PAD_EIM_RDY__GPIO_1_23,
+ MX50_PAD_EIM_OE__GPIO_1_24,
+};
+
+/* Serial ports */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct fec_platform_data fec_data __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX50_RDP_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX50_RDP_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX50_RDP_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX50_RDP_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX50_RDP_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ regulator_has_full_constraints();
+
+ return 0;
+}
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0x48),
+ .platform_data = &max17135_pdata,
+ },
+ {
+ .type = "mma8450",
+ .addr = 0x1c,
+ },
+ {
+ .type = "eeprom",
+ .addr = 0x50,
+ },
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX50_RDP_EPDC_D0, "epdc_d0");
+ ret |= gpio_request(MX50_RDP_EPDC_D1, "epdc_d1");
+ ret |= gpio_request(MX50_RDP_EPDC_D2, "epdc_d2");
+ ret |= gpio_request(MX50_RDP_EPDC_D3, "epdc_d3");
+ ret |= gpio_request(MX50_RDP_EPDC_D4, "epdc_d4");
+ ret |= gpio_request(MX50_RDP_EPDC_D5, "epdc_d5");
+ ret |= gpio_request(MX50_RDP_EPDC_D6, "epdc_d6");
+ ret |= gpio_request(MX50_RDP_EPDC_D7, "epdc_d7");
+ ret |= gpio_request(MX50_RDP_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX50_RDP_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX50_RDP_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX50_RDP_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX50_RDP_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX50_RDP_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX50_RDP_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX50_RDP_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX50_RDP_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX50_RDP_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX50_RDP_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX50_RDP_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX50_RDP_EPDC_D0);
+ gpio_free(MX50_RDP_EPDC_D1);
+ gpio_free(MX50_RDP_EPDC_D2);
+ gpio_free(MX50_RDP_EPDC_D3);
+ gpio_free(MX50_RDP_EPDC_D4);
+ gpio_free(MX50_RDP_EPDC_D5);
+ gpio_free(MX50_RDP_EPDC_D6);
+ gpio_free(MX50_RDP_EPDC_D7);
+ gpio_free(MX50_RDP_EPDC_GDCLK);
+ gpio_free(MX50_RDP_EPDC_GDSP);
+ gpio_free(MX50_RDP_EPDC_GDOE);
+ gpio_free(MX50_RDP_EPDC_GDRL);
+ gpio_free(MX50_RDP_EPDC_SDCLK);
+ gpio_free(MX50_RDP_EPDC_SDOE);
+ gpio_free(MX50_RDP_EPDC_SDLE);
+ gpio_free(MX50_RDP_EPDC_SDSHR);
+ gpio_free(MX50_RDP_EPDC_BDR0);
+ gpio_free(MX50_RDP_EPDC_SDCE0);
+ gpio_free(MX50_RDP_EPDC_SDCE1);
+ gpio_free(MX50_RDP_EPDC_SDCE2);
+}
+
+static iomux_v3_cfg_t mx50_epdc_pads_enabled[] = {
+ MX50_PAD_EPDC_D0__EPDC_D0,
+ MX50_PAD_EPDC_D1__EPDC_D1,
+ MX50_PAD_EPDC_D2__EPDC_D2,
+ MX50_PAD_EPDC_D3__EPDC_D3,
+ MX50_PAD_EPDC_D4__EPDC_D4,
+ MX50_PAD_EPDC_D5__EPDC_D5,
+ MX50_PAD_EPDC_D6__EPDC_D6,
+ MX50_PAD_EPDC_D7__EPDC_D7,
+ MX50_PAD_EPDC_GDCLK__EPDC_GDCLK,
+ MX50_PAD_EPDC_GDSP__EPDC_GDSP,
+ MX50_PAD_EPDC_GDOE__EPDC_GDOE,
+ MX50_PAD_EPDC_GDRL__EPDC_GDRL,
+ MX50_PAD_EPDC_SDCLK__EPDC_SDCLK,
+ MX50_PAD_EPDC_SDOE__EPDC_SDOE,
+ MX50_PAD_EPDC_SDLE__EPDC_SDLE,
+ MX50_PAD_EPDC_SDSHR__EPDC_SDSHR,
+ MX50_PAD_EPDC_BDR0__EPDC_BDR0,
+ MX50_PAD_EPDC_SDCE0__EPDC_SDCE0,
+ MX50_PAD_EPDC_SDCE1__EPDC_SDCE1,
+ MX50_PAD_EPDC_SDCE2__EPDC_SDCE2,
+};
+
+static iomux_v3_cfg_t mx50_epdc_pads_disabled[] = {
+ MX50_PAD_EPDC_D0__GPIO_3_0,
+ MX50_PAD_EPDC_D1__GPIO_3_1,
+ MX50_PAD_EPDC_D2__GPIO_3_2,
+ MX50_PAD_EPDC_D3__GPIO_3_3,
+ MX50_PAD_EPDC_D4__GPIO_3_4,
+ MX50_PAD_EPDC_D5__GPIO_3_5,
+ MX50_PAD_EPDC_D6__GPIO_3_6,
+ MX50_PAD_EPDC_D7__GPIO_3_7,
+ MX50_PAD_EPDC_GDCLK__GPIO_3_16,
+ MX50_PAD_EPDC_GDSP__GPIO_3_17,
+ MX50_PAD_EPDC_GDOE__GPIO_3_18,
+ MX50_PAD_EPDC_GDRL__GPIO_3_19,
+ MX50_PAD_EPDC_SDCLK__GPIO_3_20,
+ MX50_PAD_EPDC_SDOE__GPIO_3_23,
+ MX50_PAD_EPDC_SDLE__GPIO_3_24,
+ MX50_PAD_EPDC_SDSHR__GPIO_3_26,
+ MX50_PAD_EPDC_BDR0__GPIO_4_23,
+ MX50_PAD_EPDC_SDCE0__GPIO_4_25,
+ MX50_PAD_EPDC_SDCE1__GPIO_4_26,
+ MX50_PAD_EPDC_SDCE2__GPIO_4_27,
+};
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx50_epdc_pads_enabled, \
+ ARRAY_SIZE(mx50_epdc_pads_enabled));
+
+ gpio_direction_input(MX50_RDP_EPDC_D0);
+ gpio_direction_input(MX50_RDP_EPDC_D1);
+ gpio_direction_input(MX50_RDP_EPDC_D2);
+ gpio_direction_input(MX50_RDP_EPDC_D3);
+ gpio_direction_input(MX50_RDP_EPDC_D4);
+ gpio_direction_input(MX50_RDP_EPDC_D5);
+ gpio_direction_input(MX50_RDP_EPDC_D6);
+ gpio_direction_input(MX50_RDP_EPDC_D7);
+ gpio_direction_input(MX50_RDP_EPDC_GDCLK);
+ gpio_direction_input(MX50_RDP_EPDC_GDSP);
+ gpio_direction_input(MX50_RDP_EPDC_GDOE);
+ gpio_direction_input(MX50_RDP_EPDC_GDRL);
+ gpio_direction_input(MX50_RDP_EPDC_SDCLK);
+ gpio_direction_input(MX50_RDP_EPDC_SDOE);
+ gpio_direction_input(MX50_RDP_EPDC_SDLE);
+ gpio_direction_input(MX50_RDP_EPDC_SDSHR);
+ gpio_direction_input(MX50_RDP_EPDC_BDR0);
+ gpio_direction_input(MX50_RDP_EPDC_SDCE0);
+ gpio_direction_input(MX50_RDP_EPDC_SDCE1);
+ gpio_direction_input(MX50_RDP_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx50_epdc_pads_disabled, \
+ ARRAY_SIZE(mx50_epdc_pads_disabled));
+
+ gpio_direction_output(MX50_RDP_EPDC_D0, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D1, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D2, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D3, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D4, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D5, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D6, 0);
+ gpio_direction_output(MX50_RDP_EPDC_D7, 0);
+ gpio_direction_output(MX50_RDP_EPDC_GDCLK, 0);
+ gpio_direction_output(MX50_RDP_EPDC_GDSP, 0);
+ gpio_direction_output(MX50_RDP_EPDC_GDOE, 0);
+ gpio_direction_output(MX50_RDP_EPDC_GDRL, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDCLK, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDOE, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDLE, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDSHR, 0);
+ gpio_direction_output(MX50_RDP_EPDC_BDR0, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDCE0, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDCE1, 0);
+ gpio_direction_output(MX50_RDP_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static inline void mx50_rdp_fec_reset(void)
+{
+ gpio_request(FEC_EN, "fec-en");
+ gpio_direction_output(FEC_EN, 0);
+ gpio_request(FEC_RESET_B, "fec-reset_b");
+ gpio_direction_output(FEC_RESET_B, 0);
+ msleep(1);
+ gpio_set_value(FEC_RESET_B, 1);
+}
+
+static const struct imxi2c_platform_data i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct mxc_gpu_platform_data gpu_data __initdata = {
+ .z160_revision = 1,
+};
+
+static int mx50_rdp_spi_cs[] = {
+ MX50_RDP_CSPI_CS0,
+ MX50_RDP_CSPI_CS1,
+};
+
+static const struct spi_imx_master mx50_rdp_spi_pdata __initconst = {
+ .chipselect = mx50_rdp_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx50_rdp_spi_cs),
+};
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx50_gpmi_nand[] __initdata = {
+ MX50_PIN_EIM_DA8__NANDF_CLE,
+ MX50_PIN_EIM_DA9__NANDF_ALE,
+ MX50_PIN_EIM_DA10__NANDF_CE0,
+ MX50_PIN_EIM_DA11__NANDF_CE1,
+ MX50_PIN_EIM_DA12__NANDF_CE2,
+ MX50_PIN_EIM_DA13__NANDF_CE3,
+ MX50_PAD_EIM_DA14__NANDF_READY,
+ MX50_PIN_EIM_DA15__NANDF_DQS,
+ MX50_PIN_SD3_D4__NANDF_D0,
+ MX50_PIN_SD3_D5__NANDF_D1,
+ MX50_PIN_SD3_D6__NANDF_D2,
+ MX50_PIN_SD3_D7__NANDF_D3,
+ MX50_PIN_SD3_D0__NANDF_D4,
+ MX50_PIN_SD3_D1__NANDF_D5,
+ MX50_PIN_SD3_D2__NANDF_D6,
+ MX50_PIN_SD3_D3__NANDF_D7,
+ MX50_PIN_SD3_CLK__NANDF_RDN,
+ MX50_PIN_SD3_CMD__NANDF_WRN,
+ MX50_PIN_SD3_WP__NANDF_RESETN,
+};
+
+static int gpmi_nfc_platform_init(void)
+{
+ return mxc_iomux_v3_setup_multiple_pads(mx50_gpmi_nand,
+ ARRAY_SIZE(mx50_gpmi_nand));
+}
+
+static struct gpmi_nfc_platform_data mx50_gpmi_nfc_platform_data __initdata = {
+ .platform_init = gpmi_nfc_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+};
+
+
+static struct mxc_dvfs_platform_data rdp_dvfscore_data = {
+ .reg_id = "cpu_vddgp",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .gpc_vcr_offset = MXC_GPC_VCR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static struct mxc_regulator_platform_data rdp_regulator_data = {
+ .cpu_reg_id = "cpu_vddgp",
+ .vcc_reg_id = "lp_vcc",
+};
+
+static const struct esdhc_platform_data mx50_rdp_sd1_data __initconst = {
+ .cd_gpio = MX50_RDP_SD1_CD,
+ .wp_gpio = MX50_RDP_SD1_WP,
+};
+
+static const struct esdhc_platform_data mx50_rdp_sd2_data __initconst = {
+ .cd_gpio = MX50_RDP_SD2_CD,
+ .wp_gpio = MX50_RDP_SD2_WP,
+};
+
+static const struct esdhc_platform_data mx50_rdp_sd3_data __initconst = {
+ .wp_gpio = MX50_RDP_SD3_WP,
+ .always_present = 1,
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static void mx50_rdp_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX50_RDP_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(MX50_RDP_USB_OTG_PWR, 0);
+}
+
+static void __init mx50_rdp_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX50_IO_ADDRESS(MX50_OTG_BASE_ADDR);
+ ret = gpio_request(MX50_RDP_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO OTG_VBUS: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX50_RDP_USB_OTG_PWR, 0);
+
+ mx5_set_otghost_vbus_func(mx50_rdp_usbotg_vbus);
+ mx5_usb_dr_init();
+ mx5_usbh1_init();
+}
+/*
+ * Board specific initialization.
+ */
+static void __init mx50_rdp_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx50_rdp_pads,
+ ARRAY_SIZE(mx50_rdp_pads));
+
+ pr_info("CPU is iMX50 Revision %u\n",
+ mx50_revision());
+
+ gp_reg_id = rdp_regulator_data.cpu_reg_id;
+ lp_reg_id = rdp_regulator_data.vcc_reg_id;
+
+ imx50_add_cspi(3, &mx50_rdp_spi_pdata);
+
+ imx50_add_dma();
+ imx50_add_imx_uart(0, NULL);
+ imx50_add_imx_uart(1, NULL);
+ imx50_add_srtc();
+ imx50_add_imx_pxp();
+ imx50_add_imx_pxp_client();
+ mx50_rdp_fec_reset();
+ imx50_add_fec(&fec_data);
+ imx50_add_gpmi(&mx50_gpmi_nfc_platform_data);
+ imx50_add_imx_i2c(0, &i2c_data);
+ imx50_add_imx_i2c(1, &i2c_data);
+ imx50_add_imx_i2c(2, &i2c_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ mxc_register_device(&max17135_sensor_device, NULL);
+ imx50_add_imx_epdc(&epdc_data);
+ imx50_add_mxc_gpu(&gpu_data);
+ imx50_add_sdhci_esdhc_imx(0, &mx50_rdp_sd1_data);
+ imx50_add_sdhci_esdhc_imx(1, &mx50_rdp_sd2_data);
+ imx50_add_sdhci_esdhc_imx(2, &mx50_rdp_sd3_data);
+ imx50_add_otp();
+ imx50_add_viim();
+ imx50_add_dcp();
+ imx50_add_rngb();
+ imx50_add_perfmon();
+ mx50_rdp_init_mc13892();
+
+ imx50_add_dvfs_core(&rdp_dvfscore_data);
+
+ imx50_add_busfreq();
+
+ mx50_rdp_init_usb();
+
+ mx5_cpu_regulator_init();
+}
+
+static void __init mx50_rdp_timer_init(void)
+{
+ mx50_clocks_init(32768, 24000000, 22579200);
+}
+
+static struct sys_timer mx50_rdp_timer = {
+ .init = mx50_rdp_timer_init,
+};
+
+MACHINE_START(MX50_RDP, "Freescale MX50 Reference Design Platform")
+ .fixup = fixup_mxc_board,
+ .map_io = mx50_map_io,
+ .init_early = imx50_init_early,
+ .init_irq = mx50_init_irq,
+ .timer = &mx50_rdp_timer,
+ .init_machine = mx50_rdp_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
new file mode 100644
index 00000000..b51f08ea
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_3ds.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx51.h>
+#include <mach/3ds_debugboard.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define EXPIO_PARENT_INT (MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
+#define MX51_3DS_ECSPI2_CS (GPIO_PORTC + 28)
+
+static iomux_v3_cfg_t mx51_3ds_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+ MX51_PAD_EIM_D25__UART2_CTS,
+ MX51_PAD_EIM_D26__UART2_RTS,
+
+ /* UART3 */
+ MX51_PAD_UART3_RXD__UART3_RXD,
+ MX51_PAD_UART3_TXD__UART3_TXD,
+ MX51_PAD_EIM_D24__UART3_CTS,
+ MX51_PAD_EIM_D27__UART3_RTS,
+
+ /* CPLD PARENT IRQ PIN */
+ MX51_PAD_GPIO1_6__GPIO1_6,
+
+ /* KPP */
+ MX51_PAD_KEY_ROW0__KEY_ROW0,
+ MX51_PAD_KEY_ROW1__KEY_ROW1,
+ MX51_PAD_KEY_ROW2__KEY_ROW2,
+ MX51_PAD_KEY_ROW3__KEY_ROW3,
+ MX51_PAD_KEY_COL0__KEY_COL0,
+ MX51_PAD_KEY_COL1__KEY_COL1,
+ MX51_PAD_KEY_COL2__KEY_COL2,
+ MX51_PAD_KEY_COL3__KEY_COL3,
+ MX51_PAD_KEY_COL4__KEY_COL4,
+ MX51_PAD_KEY_COL5__KEY_COL5,
+
+ /* eCSPI2 */
+ MX51_PAD_NANDF_RB2__ECSPI2_SCLK,
+ MX51_PAD_NANDF_RB3__ECSPI2_MISO,
+ MX51_PAD_NANDF_D15__ECSPI2_MOSI,
+ MX51_PAD_NANDF_D12__GPIO3_28,
+
+ MX51_PAD_GPIO1_7__SPDIF_OUT,
+};
+
+/* Serial ports */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int mx51_3ds_board_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(0, 1, KEY_2),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_F1),
+ KEY(0, 4, KEY_UP),
+ KEY(0, 5, KEY_F2),
+
+ KEY(1, 0, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(1, 2, KEY_6),
+ KEY(1, 3, KEY_LEFT),
+ KEY(1, 4, KEY_SELECT),
+ KEY(1, 5, KEY_RIGHT),
+
+ KEY(2, 0, KEY_7),
+ KEY(2, 1, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(2, 3, KEY_F3),
+ KEY(2, 4, KEY_DOWN),
+ KEY(2, 5, KEY_F4),
+
+ KEY(3, 0, KEY_0),
+ KEY(3, 1, KEY_OK),
+ KEY(3, 2, KEY_ESC),
+ KEY(3, 3, KEY_ENTER),
+ KEY(3, 4, KEY_MENU),
+ KEY(3, 5, KEY_BACK)
+};
+
+static const struct matrix_keymap_data mx51_3ds_map_data __initconst = {
+ .keymap = mx51_3ds_board_keymap,
+ .keymap_size = ARRAY_SIZE(mx51_3ds_board_keymap),
+};
+
+static int mx51_3ds_spi2_cs[] = {
+ MXC_SPI_CS(0),
+ MX51_3DS_ECSPI2_CS,
+};
+
+static const struct spi_imx_master mx51_3ds_ecspi2_pdata __initconst = {
+ .chipselect = mx51_3ds_spi2_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_3ds_spi2_cs),
+};
+
+static struct spi_board_info mx51_3ds_spi_nor_device[] = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,},
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0, /* tx clk from CKIH1 for 44.1K */
+ .spdif_clk_48000 = 7, /* tx clk from CKIH2 for 48k and 32k */
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx51_3ds_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51_3ds_pads,
+ ARRAY_SIZE(mx51_3ds_pads));
+
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+
+ imx51_add_ecspi(1, &mx51_3ds_ecspi2_pdata);
+ spi_register_board_info(mx51_3ds_spi_nor_device,
+ ARRAY_SIZE(mx51_3ds_spi_nor_device));
+
+ if (mxc_expio_init(MX51_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ printk(KERN_WARNING "Init of the debugboard failed, all "
+ "devices on the board are unusable.\n");
+
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+ imx51_add_imx_keypad(&mx51_3ds_map_data);
+ imx51_add_imx2_wdt(0, NULL);
+
+ imx51_add_spdif(&mxc_spdif_data);
+ imx51_add_spdif_dai();
+ imx51_add_spdif_audio_device();
+}
+
+static void __init mx51_3ds_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx51_3ds_timer = {
+ .init = mx51_3ds_timer_init,
+};
+
+MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &mx51_3ds_timer,
+ .init_machine = mx51_3ds_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
new file mode 100755
index 00000000..f8661ff5
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
+#include <linux/fec.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_dvfs.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+#include "crm_regs.h"
+#include "cpu_op-mx51.h"
+
+#define BABBAGE_USB_HUB_RESET IMX_GPIO_NR(1, 7)
+#define BABBAGE_USBH1_STP IMX_GPIO_NR(1, 27)
+#define BABBAGE_PHY_RESET IMX_GPIO_NR(2, 5)
+#define BABBAGE_VGA_RESET IMX_GPIO_NR(2, 13)
+#define BABBAGE_FEC_PHY_RESET IMX_GPIO_NR(2, 14)
+#define BABBAGE_POWER_KEY IMX_GPIO_NR(2, 21)
+#define BABBAGE_ECSPI1_CS0 IMX_GPIO_NR(4, 24)
+#define BABBAGE_ECSPI1_CS1 IMX_GPIO_NR(4, 25)
+#define MX51_BBG_SD1_CD IMX_GPIO_NR(1, 0)
+#define MX51_BBG_SD1_WP IMX_GPIO_NR(1, 1)
+#define MX51_BBG_SD2_CD IMX_GPIO_NR(1, 6)
+#define MX51_BBG_SD2_WP IMX_GPIO_NR(1, 5)
+#define BABBAGE_AUDAMP_STBY IMX_GPIO_NR(2, 17)
+#define BABBAGE_HEADPHONE_DET IMX_GPIO_NR(3, 26)
+#define BABBAGE_AUDIO_CLK_EN IMX_GPIO_NR(4, 26)
+#define BABBAGE_OSC_EN_B IMX_GPIO_NR(2, 2)
+
+#define BABBAGE_26M_OSC_EN IMX_GPIO_NR(3, 1)
+#define BABBAGE_LVDS_POWER_DOWN IMX_GPIO_NR(3, 3) /* GPIO_3_3 */
+#define BABBAGE_DISP_BRIGHTNESS_CTL IMX_GPIO_NR(3, 4) /* GPIO_3_4 */
+#define BABBAGE_DVI_RESET IMX_GPIO_NR(3, 5) /* GPIO_3_5 */
+#define BABBAGE_DVI_POWER IMX_GPIO_NR(3, 6) /* GPIO_3_6 */
+#define BABBAGE_HEADPHONE_DET IMX_GPIO_NR(3, 26) /* GPIO_3_26 */
+#define BABBAGE_DVI_DET IMX_GPIO_NR(3, 28) /* GPIO_3_28 */
+
+#define BABBAGE_LCD_3V3_ON IMX_GPIO_NR(4, 9) /* GPIO_4_9 */
+#define BABBAGE_LCD_5V_ON IMX_GPIO_NR(4, 10) /* GPIO_4_10 */
+#define BABBAGE_DVI_I2C_EN IMX_GPIO_NR(4, 14) /* GPIO_4_14 */
+
+/* USB_CTRL_1 */
+#define MX51_USB_CTRL_1_OFFSET 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+
+#define MX51_USB_PLLDIV_12_MHZ 0x00
+#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
+#define MX51_USB_PLL_DIV_24_MHZ 0x02
+
+extern char *lp_reg_id;
+extern char *gp_reg_id;
+extern void mx5_cpu_regulator_init(void);
+
+static struct gpio_keys_button babbage_buttons[] = {
+ {
+ .gpio = BABBAGE_POWER_KEY,
+ .code = BTN_0,
+ .desc = "PWR",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static const struct gpio_keys_platform_data imx_button_data __initconst = {
+ .buttons = babbage_buttons,
+ .nbuttons = ARRAY_SIZE(babbage_buttons),
+};
+
+static iomux_v3_cfg_t mx51babbage_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+
+ /* UART3 */
+ MX51_PAD_EIM_D25__UART3_RXD,
+ MX51_PAD_EIM_D26__UART3_TXD,
+ MX51_PAD_EIM_D27__UART3_RTS,
+ MX51_PAD_EIM_D24__UART3_CTS,
+
+ /* I2C1 */
+ MX51_PAD_EIM_D16__I2C1_SDA,
+ MX51_PAD_EIM_D19__I2C1_SCL,
+
+ /* I2C2 */
+ MX51_PAD_KEY_COL4__I2C2_SCL,
+ MX51_PAD_KEY_COL5__I2C2_SDA,
+
+ /* HSI2C */
+ MX51_PAD_I2C1_CLK__I2C1_CLK,
+ MX51_PAD_I2C1_DAT__I2C1_DAT,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+
+ /* USB HUB reset line*/
+ MX51_PAD_GPIO1_7__GPIO1_7,
+
+ /* FEC */
+ MX51_PAD_EIM_EB2__FEC_MDIO,
+ MX51_PAD_EIM_EB3__FEC_RDATA1,
+ MX51_PAD_EIM_CS2__FEC_RDATA2,
+ MX51_PAD_EIM_CS3__FEC_RDATA3,
+ MX51_PAD_EIM_CS4__FEC_RX_ER,
+ MX51_PAD_EIM_CS5__FEC_CRS,
+ MX51_PAD_NANDF_RB2__FEC_COL,
+ MX51_PAD_NANDF_RB3__FEC_RX_CLK,
+ MX51_PAD_NANDF_D9__FEC_RDATA0,
+ MX51_PAD_NANDF_D8__FEC_TDATA0,
+ MX51_PAD_NANDF_CS2__FEC_TX_ER,
+ MX51_PAD_NANDF_CS3__FEC_MDC,
+ MX51_PAD_NANDF_CS4__FEC_TDATA1,
+ MX51_PAD_NANDF_CS5__FEC_TDATA2,
+ MX51_PAD_NANDF_CS6__FEC_TDATA3,
+ MX51_PAD_NANDF_CS7__FEC_TX_EN,
+ MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
+
+ /* FEC PHY reset line */
+ MX51_PAD_EIM_A20__GPIO2_14,
+
+ MX51_PAD_GPIO1_0__GPIO1_0,
+ MX51_PAD_GPIO1_1__GPIO1_1,
+ MX51_PAD_GPIO1_5__GPIO1_5,
+ MX51_PAD_GPIO1_6__GPIO1_6,
+ /* SD 1 */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SD 2 */
+ MX51_PAD_SD2_CMD__SD2_CMD,
+ MX51_PAD_SD2_CLK__SD2_CLK,
+ MX51_PAD_SD2_DATA0__SD2_DATA0,
+ MX51_PAD_SD2_DATA1__SD2_DATA1,
+ MX51_PAD_SD2_DATA2__SD2_DATA2,
+ MX51_PAD_SD2_DATA3__SD2_DATA3,
+
+ /* eCSPI1 */
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+ MX51_PAD_CSPI1_SS0__ECSPI1_SS0,
+ MX51_PAD_CSPI1_SS0__GPIO4_24,
+ MX51_PAD_CSPI1_SS1__GPIO4_25,
+ MX51_PAD_CSPI1_RDY__GPIO4_26,
+ MX51_PAD_CSPI1_SS1__ECSPI1_SS1,
+
+ /* Display */
+ MX51_PAD_EIM_A19__GPIO2_13,
+ MX51_PAD_DI1_D0_CS__GPIO3_3,
+ MX51_PAD_DISPB2_SER_DIN__GPIO3_5,
+ MX51_PAD_DISPB2_SER_DIO__GPIO3_6,
+ MX51_PAD_NANDF_D14__GPIO3_26,
+ MX51_PAD_NANDF_D12__GPIO3_28,
+ MX51_PAD_CSI2_D12__GPIO4_9,
+ MX51_PAD_CSI2_D13__GPIO4_10,
+ MX51_PAD_CSI2_HSYNC__GPIO4_14,
+
+ MX51_PAD_DI_GP4__DI2_PIN15,
+ MX51_PAD_GPIO1_2__PWM1_PWMO,
+
+#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL
+ MX51_PAD_DISP1_DAT22__DISP2_DAT16,
+ MX51_PAD_DISP1_DAT23__DISP2_DAT17,
+
+ MX51_PAD_DI1_D1_CS__GPIO3_4,
+#endif
+ MX51_PAD_EIM_LBA__GPIO3_1,
+ MX51_PAD_AUD3_BB_TXD__AUD3_TXD,
+ MX51_PAD_AUD3_BB_RXD__AUD3_RXD,
+ MX51_PAD_AUD3_BB_CK__AUD3_TXC,
+ MX51_PAD_AUD3_BB_FS__AUD3_TXFS,
+
+ MX51_PAD_OWIRE_LINE__SPDIF_OUT,
+};
+
+static struct mxc_dvfs_platform_data bbg_dvfscore_data = {
+ .reg_id = "cpu_vcc",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .gpc_vcr_offset = MXC_GPC_VCR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 30,
+};
+
+static struct mxc_regulator_platform_data bbg_regulator_data = {
+ .cpu_reg_id = "cpu_vcc",
+};
+
+/* Serial ports */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data babbage_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data babbage_hsi2c_data = {
+ .bitrate = 400000,
+};
+
+static const struct esdhc_platform_data mx51_bbg_sd1_data __initconst = {
+ .wp_gpio = MX51_BBG_SD1_WP,
+ .cd_gpio = MX51_BBG_SD1_CD,
+};
+
+static const struct esdhc_platform_data mx51_bbg_sd2_data __initconst = {
+ .wp_gpio = MX51_BBG_SD2_WP,
+ .cd_gpio = MX51_BBG_SD2_CD,
+};
+
+static void babbage_suspend_enter(void)
+{
+}
+
+static void babbage_suspend_exit(void)
+{
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+}
+
+static struct mxc_pm_platform_data babbage_pm_data = {
+ .suspend_enter = babbage_suspend_enter,
+ .suspend_exit = babbage_suspend_exit,
+};
+
+static int gpio_usbh1_active(void)
+{
+ iomux_v3_cfg_t usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO1_27;
+ iomux_v3_cfg_t phyreset_gpio = MX51_PAD_EIM_D21__GPIO2_5;
+ int ret;
+
+ /* Set USBH1_STP to GPIO and toggle it */
+ mxc_iomux_v3_setup_pad(usbh1stp_gpio);
+ ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp");
+
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_USBH1_STP__GPIO_1_27: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(BABBAGE_USBH1_STP, 0);
+ gpio_set_value(BABBAGE_USBH1_STP, 1);
+ msleep(100);
+ gpio_free(BABBAGE_USBH1_STP);
+
+ /* De-assert USB PHY RESETB */
+ mxc_iomux_v3_setup_pad(phyreset_gpio);
+ ret = gpio_request(BABBAGE_PHY_RESET, "phy_reset");
+
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_EIM_D21__GPIO_2_5: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(BABBAGE_PHY_RESET, 1);
+ return 0;
+}
+
+static inline void babbage_usbhub_reset(void)
+{
+ int ret;
+
+ /* Bring USB hub out of reset */
+ ret = gpio_request(BABBAGE_USB_HUB_RESET, "GPIO1_7");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_USB_HUB_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(BABBAGE_USB_HUB_RESET, 0);
+
+ /* USB HUB RESET - De-assert USB HUB RESET_N */
+ msleep(1);
+ gpio_set_value(BABBAGE_USB_HUB_RESET, 0);
+ msleep(1);
+ gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
+}
+
+static inline void babbage_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request_one(BABBAGE_FEC_PHY_RESET,
+ GPIOF_OUT_INIT_LOW, "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ msleep(1);
+ gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
+}
+
+/* This function is board specific as the bit mask for the plldiv will also
+be different for other Freescale SoCs, thus a common bitmask is not
+possible and cannot get place in /plat-mxc/ehci.c.*/
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_19_2_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(0, MXC_EHCI_INTERNAL_PHY);
+}
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ /* The clock for the USBH1 ULPI port will come externally from the PHY. */
+ v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
+ __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(1, MXC_EHCI_POWER_PINS_ENABLED |
+ MXC_EHCI_ITC_NO_THRESHOLD);
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+};
+
+static struct fsl_usb2_platform_data usb_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .init = initialize_usbh1_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init babbage_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", babbage_otg_mode);
+
+static struct spi_board_info mx51_babbage_spi_board_info[] __initdata = {
+ {
+ .modalias = "mtd_dataflash",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,
+ },
+};
+
+static int mx51_babbage_spi_cs[] = {
+ BABBAGE_ECSPI1_CS0,
+ BABBAGE_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx51_babbage_spi_pdata __initconst = {
+ .chipselect = mx51_babbage_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_babbage_spi_cs),
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct ipuv3_fb_platform_data bbg_fb_data[] = {
+ {
+ .disp_dev = "dvi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "1024x768M-16@60",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+ .rev = 2,
+};
+
+static struct platform_pwm_backlight_data bbg_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 78770,
+};
+
+static struct fsl_mxc_tve_platform_data tve_data = {
+ .dac_reg = "VVIDEO",
+};
+
+static void vga_reset(void)
+{
+
+ gpio_set_value(BABBAGE_VGA_RESET, 0);
+ msleep(50);
+ /* do reset */
+ gpio_set_value(BABBAGE_VGA_RESET, 1);
+ msleep(10); /* tRES >= 50us */
+ gpio_set_value(BABBAGE_VGA_RESET, 0);
+}
+
+static struct fsl_mxc_lcd_platform_data vga_data = {
+ .core_reg = "VCAM",
+ .io_reg = "VGEN3",
+ .analog_reg = "VAUDIO",
+ .reset = vga_reset,
+};
+
+static void ddc_dvi_init(void)
+{
+ /* enable DVI I2C */
+ gpio_set_value(BABBAGE_DVI_I2C_EN, 1);
+}
+
+static int ddc_dvi_update(void)
+{
+ /* DVI cable state */
+ if (gpio_get_value(BABBAGE_DVI_DET) == 1)
+ return 1;
+ else
+ return 0;
+}
+
+static struct fsl_mxc_dvi_platform_data bbg_ddc_dvi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .init = ddc_dvi_init,
+ .update = ddc_dvi_update,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "sgtl5000",
+ .addr = 0x0a,
+ },
+ {
+ .type = "mxc_dvi",
+ .addr = 0x50,
+ .irq = gpio_to_irq(BABBAGE_DVI_DET),
+ .platform_data = &bbg_ddc_dvi_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c_hs_board_info[] __initdata = {
+ {
+ .type = "ch7026",
+ .addr = 0x75,
+ .platform_data = &vga_data,
+ },
+};
+
+static struct mxc_gpu_platform_data gpu_data __initdata;
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ struct tag *t;
+ struct tag *mem_tag = 0;
+ int total_mem = SZ_512M;
+ int left_mem = 0;
+ int gpu_mem = SZ_64M;
+ int fb_mem = 0;
+ char *str;
+
+ for_each_tag(mem_tag, tags) {
+ if (mem_tag->hdr.tag == ATAG_MEM) {
+ total_mem = mem_tag->u.mem.size;
+ left_mem = total_mem - gpu_mem - fb_mem;
+ break;
+ }
+ }
+
+ for_each_tag(t, tags) {
+ if (t->hdr.tag == ATAG_CMDLINE) {
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "mem=");
+ if (str != NULL) {
+ str += 4;
+ left_mem = memparse(str, &str);
+ if (left_mem == 0 || left_mem > total_mem)
+ left_mem = total_mem - gpu_mem - fb_mem;
+ }
+
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "gpu_memory=");
+ if (str != NULL) {
+ str += 11;
+ gpu_mem = memparse(str, &str);
+ }
+
+ break;
+ }
+ }
+
+ if (mem_tag) {
+ fb_mem = total_mem - left_mem - gpu_mem;
+ if (fb_mem < 0) {
+ gpu_mem = total_mem - left_mem;
+ fb_mem = 0;
+ }
+ mem_tag->u.mem.size = left_mem;
+
+ /*reserve memory for gpu*/
+ gpu_data.reserved_mem_base =
+ mem_tag->u.mem.start + left_mem;
+ gpu_data.reserved_mem_size = gpu_mem;
+
+ /* reserver memory for fb */
+ bbg_fb_data[0].res_base[0] = gpu_data.reserved_mem_base
+ + gpu_data.reserved_mem_size;
+ bbg_fb_data[0].res_size[0] = fb_mem;
+ }
+}
+
+static struct imx_ssi_platform_data bbg_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+extern int mx51_babbage_init_mc13892(void);
+static int bbg_sgtl5000_init(void)
+{
+ gpio_request(BABBAGE_AUDAMP_STBY, "audio_amp");
+ gpio_direction_input(BABBAGE_AUDAMP_STBY);
+
+ /* Enable OSC_CKIH1_EN for audio */
+ gpio_request(BABBAGE_AUDIO_CLK_EN, "audio_clk");
+ gpio_direction_output(BABBAGE_AUDIO_CLK_EN, 0);
+ gpio_set_value(BABBAGE_AUDIO_CLK_EN, 0);
+
+ return 0;
+}
+
+static struct mxc_audio_platform_data bbg_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .init = bbg_sgtl5000_init,
+ .sysclk = 26000000,
+ .hp_gpio = BABBAGE_HEADPHONE_DET,
+ .hp_active_low = 1,
+};
+
+static struct platform_device bbg_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0, /* tx clk from CKIH1 for 44.1K */
+ .spdif_clk_48000 = 7, /* tx clk from CKIH2 for 48k and 32k */
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx51_babbage_init(void)
+{
+ int i;
+
+ iomux_v3_cfg_t usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+ iomux_v3_cfg_t power_key = _MX51_PAD_EIM_A27__GPIO2_21 |
+ MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP);
+
+ mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
+ ARRAY_SIZE(mx51babbage_pads));
+
+ gp_reg_id = bbg_regulator_data.cpu_reg_id;
+ lp_reg_id = bbg_regulator_data.vcc_reg_id;
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+
+ imx51_add_imx_uart(0, &uart_pdata);
+ imx51_add_imx_uart(1, &uart_pdata);
+ imx51_add_imx_uart(2, &uart_pdata);
+
+ imx51_add_srtc();
+
+ babbage_fec_reset();
+ imx51_add_fec(NULL);
+
+ imx51_add_ipuv3(0, &ipu_data);
+ for (i = 0; i < ARRAY_SIZE(bbg_fb_data); i++)
+ imx51_add_ipuv3fb(i, &bbg_fb_data[i]);
+ imx51_add_lcdif(&lcdif_data);
+ imx51_add_vpu();
+ imx51_add_tve(&tve_data);
+ imx51_add_v4l2_output(0);
+
+ imx51_add_mxc_pwm(0);
+ imx51_add_mxc_pwm_backlight(0, &bbg_pwm_backlight_data);
+
+ /* Set the PAD settings for the pwr key. */
+ mxc_iomux_v3_setup_pad(power_key);
+ imx51_add_gpio_keys(&imx_button_data);
+
+ imx51_add_imx_i2c(0, &babbage_i2c_data);
+ imx51_add_imx_i2c(1, &babbage_i2c_data);
+
+ imx51_add_spdif(&mxc_spdif_data);
+ imx51_add_spdif_dai();
+ imx51_add_spdif_audio_device();
+
+ mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
+ mxc_register_device(&mxc_pm_device, &babbage_pm_data);
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+
+ vga_data.core_reg = NULL;
+ vga_data.io_reg = NULL;
+ vga_data.analog_reg = NULL;
+
+ i2c_register_board_info(3, mxc_i2c_hs_board_info,
+ ARRAY_SIZE(mxc_i2c_hs_board_info));
+
+ /*if (otg_mode_host)
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ else {
+ initialize_otg_port(NULL);
+ mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
+ }
+
+ gpio_usbh1_active();
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);*/
+ /* setback USBH1_STP to be function */
+ mxc_iomux_v3_setup_pad(usbh1stp);
+ babbage_usbhub_reset();
+
+ imx51_add_sdhci_esdhc_imx(0, &mx51_bbg_sd1_data);
+ imx51_add_sdhci_esdhc_imx(1, &mx51_bbg_sd2_data);
+
+ spi_register_board_info(mx51_babbage_spi_board_info,
+ ARRAY_SIZE(mx51_babbage_spi_board_info));
+
+ imx51_add_ecspi(0, &mx51_babbage_spi_pdata);
+ imx51_add_imx2_wdt(0, NULL);
+ imx51_add_mxc_gpu(&gpu_data);
+
+ /* this call required to release IRAM partition held by ROM during boot,
+ * even if SCC2 driver is not part of the image
+ */
+ imx51_add_mxc_scc2();
+
+ if (mx51_revision() >= IMX_CHIP_REVISION_3_0) {
+ /* DVI_I2C_ENB = 0 tristates the DVI I2C level shifter */
+ gpio_request(BABBAGE_DVI_I2C_EN, "dvi-i2c-en");
+ gpio_direction_output(BABBAGE_DVI_I2C_EN, 0);
+ }
+
+ /* Deassert VGA reset to free i2c bus */
+ gpio_request(BABBAGE_VGA_RESET, "vga-reset");
+ gpio_direction_output(BABBAGE_VGA_RESET, 1);
+
+ /* LCD related gpio */
+ gpio_request(BABBAGE_DISP_BRIGHTNESS_CTL, "disp-brightness-ctl");
+ gpio_request(BABBAGE_LVDS_POWER_DOWN, "lvds-power-down");
+ gpio_request(BABBAGE_LCD_3V3_ON, "lcd-3v3-on");
+ gpio_request(BABBAGE_LCD_5V_ON, "lcd-5v-on");
+ gpio_direction_output(BABBAGE_DISP_BRIGHTNESS_CTL, 0);
+ gpio_direction_output(BABBAGE_LVDS_POWER_DOWN, 0);
+ gpio_direction_output(BABBAGE_LCD_3V3_ON, 0);
+ gpio_direction_output(BABBAGE_LCD_5V_ON, 0);
+
+ /* DI0-LVDS */
+ gpio_set_value(BABBAGE_LVDS_POWER_DOWN, 0);
+ msleep(1);
+ gpio_set_value(BABBAGE_LVDS_POWER_DOWN, 1);
+ gpio_set_value(BABBAGE_LCD_3V3_ON, 1);
+ gpio_set_value(BABBAGE_LCD_5V_ON, 1);
+
+ /* DVI Detect */
+ gpio_request(BABBAGE_DVI_DET, "dvi-detect");
+ gpio_direction_input(BABBAGE_DVI_DET);
+ /* DVI Reset - Assert for i2c disabled mode */
+ gpio_request(BABBAGE_DVI_RESET, "dvi-reset");
+ gpio_direction_output(BABBAGE_DVI_RESET, 0);
+ /* DVI Power-down */
+ gpio_request(BABBAGE_DVI_POWER, "dvi-power");
+ gpio_direction_output(BABBAGE_DVI_POWER, 1);
+
+ gpio_request(BABBAGE_26M_OSC_EN, "26M-OSC-CLK");
+ gpio_direction_output(BABBAGE_26M_OSC_EN, 1);
+
+ /* OSC_EN */
+ gpio_request(BABBAGE_OSC_EN_B, "osc-en");
+ gpio_direction_output(BABBAGE_OSC_EN_B, 1);
+
+ /* WVGA Reset */
+ gpio_set_value(BABBAGE_DISP_BRIGHTNESS_CTL, 1);
+
+ mx51_babbage_init_mc13892();
+ mxc_register_device(&bbg_audio_device, &bbg_audio_data);
+ imx51_add_imx_ssi(1, &bbg_ssi_pdata);
+
+ imx51_add_dvfs_core(&bbg_dvfscore_data);
+ imx51_add_busfreq();
+ mx5_cpu_regulator_init();
+}
+
+static void __init mx51_babbage_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx51_babbage_timer = {
+ .init = mx51_babbage_timer_init,
+};
+
+MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
+ /* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
+ .fixup = fixup_mxc_board,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &mx51_babbage_timer,
+ .init_machine = mx51_babbage_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_efikamx.c b/arch/arm/mach-mx5/board-mx51_efikamx.c
new file mode 100644
index 00000000..6e362315
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_efikamx.c
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ *
+ * based on code from the following
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved.
+ * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+#include "efika.h"
+
+#define EFIKAMX_PCBID0 IMX_GPIO_NR(3, 16)
+#define EFIKAMX_PCBID1 IMX_GPIO_NR(3, 17)
+#define EFIKAMX_PCBID2 IMX_GPIO_NR(3, 11)
+
+#define EFIKAMX_BLUE_LED IMX_GPIO_NR(3, 13)
+#define EFIKAMX_GREEN_LED IMX_GPIO_NR(3, 14)
+#define EFIKAMX_RED_LED IMX_GPIO_NR(3, 15)
+
+#define EFIKAMX_POWER_KEY IMX_GPIO_NR(2, 31)
+
+/* board 1.1 doesn't have same reset gpio */
+#define EFIKAMX_RESET1_1 IMX_GPIO_NR(3, 2)
+#define EFIKAMX_RESET IMX_GPIO_NR(1, 4)
+
+#define EFIKAMX_POWEROFF IMX_GPIO_NR(4, 13)
+
+#define EFIKAMX_PMIC IMX_GPIO_NR(1, 6)
+
+/* the pci ids pin have pull up. they're driven low according to board id */
+#define MX51_PAD_PCBID0 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PCBID1 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PCBID2 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE)
+
+static iomux_v3_cfg_t mx51efikamx_pads[] = {
+ /* board id */
+ MX51_PAD_PCBID0,
+ MX51_PAD_PCBID1,
+ MX51_PAD_PCBID2,
+
+ /* leds */
+ MX51_PAD_CSI1_D9__GPIO3_13,
+ MX51_PAD_CSI1_VSYNC__GPIO3_14,
+ MX51_PAD_CSI1_HSYNC__GPIO3_15,
+
+ /* power key */
+ MX51_PAD_PWRKEY,
+
+ /* reset */
+ MX51_PAD_DI1_PIN13__GPIO3_2,
+ MX51_PAD_GPIO1_4__GPIO1_4,
+
+ /* power off */
+ MX51_PAD_CSI2_VSYNC__GPIO4_13,
+};
+
+/* PCBID2 PCBID1 PCBID0 STATE
+ 1 1 1 ER1:rev1.1
+ 1 1 0 ER2:rev1.2
+ 1 0 1 ER3:rev1.3
+ 1 0 0 ER4:rev1.4
+*/
+static void __init mx51_efikamx_board_id(void)
+{
+ int id;
+
+ /* things are taking time to settle */
+ msleep(150);
+
+ gpio_request(EFIKAMX_PCBID0, "pcbid0");
+ gpio_direction_input(EFIKAMX_PCBID0);
+ gpio_request(EFIKAMX_PCBID1, "pcbid1");
+ gpio_direction_input(EFIKAMX_PCBID1);
+ gpio_request(EFIKAMX_PCBID2, "pcbid2");
+ gpio_direction_input(EFIKAMX_PCBID2);
+
+ id = gpio_get_value(EFIKAMX_PCBID0);
+ id |= gpio_get_value(EFIKAMX_PCBID1) << 1;
+ id |= gpio_get_value(EFIKAMX_PCBID2) << 2;
+
+ switch (id) {
+ case 7:
+ system_rev = 0x11;
+ break;
+ case 6:
+ system_rev = 0x12;
+ break;
+ case 5:
+ system_rev = 0x13;
+ break;
+ case 4:
+ system_rev = 0x14;
+ break;
+ default:
+ system_rev = 0x10;
+ break;
+ }
+
+ if ((system_rev == 0x10)
+ || (system_rev == 0x12)
+ || (system_rev == 0x14)) {
+ printk(KERN_WARNING
+ "EfikaMX: Unsupported board revision 1.%u!\n",
+ system_rev & 0xf);
+ }
+}
+
+static struct gpio_led mx51_efikamx_leds[] = {
+ {
+ .name = "efikamx:green",
+ .default_trigger = "default-on",
+ .gpio = EFIKAMX_GREEN_LED,
+ },
+ {
+ .name = "efikamx:red",
+ .default_trigger = "ide-disk",
+ .gpio = EFIKAMX_RED_LED,
+ },
+ {
+ .name = "efikamx:blue",
+ .default_trigger = "mmc0",
+ .gpio = EFIKAMX_BLUE_LED,
+ },
+};
+
+static struct gpio_led_platform_data mx51_efikamx_leds_data = {
+ .leds = mx51_efikamx_leds,
+ .num_leds = ARRAY_SIZE(mx51_efikamx_leds),
+};
+
+static struct platform_device mx51_efikamx_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mx51_efikamx_leds_data,
+ },
+};
+
+static struct gpio_keys_button mx51_efikamx_powerkey[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = EFIKAMX_POWER_KEY,
+ .type = EV_PWR,
+ .desc = "Power Button (CM)",
+ .wakeup = 1,
+ .debounce_interval = 10, /* ms */
+ },
+};
+
+static const struct gpio_keys_platform_data mx51_efikamx_powerkey_data __initconst = {
+ .buttons = mx51_efikamx_powerkey,
+ .nbuttons = ARRAY_SIZE(mx51_efikamx_powerkey),
+};
+
+void mx51_efikamx_reset(void)
+{
+ if (system_rev == 0x11)
+ gpio_direction_output(EFIKAMX_RESET1_1, 0);
+ else
+ gpio_direction_output(EFIKAMX_RESET, 0);
+}
+
+static struct regulator *pwgt1, *pwgt2, *coincell;
+
+static void mx51_efikamx_power_off(void)
+{
+ if (!IS_ERR(coincell))
+ regulator_disable(coincell);
+
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_disable(pwgt2);
+ regulator_disable(pwgt1);
+ }
+ gpio_direction_output(EFIKAMX_POWEROFF, 1);
+}
+
+static int __init mx51_efikamx_power_init(void)
+{
+ if (machine_is_mx51_efikamx()) {
+ pwgt1 = regulator_get(NULL, "pwgt1");
+ pwgt2 = regulator_get(NULL, "pwgt2");
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_enable(pwgt1);
+ regulator_enable(pwgt2);
+ }
+ gpio_request(EFIKAMX_POWEROFF, "poweroff");
+ pm_power_off = mx51_efikamx_power_off;
+
+ /* enable coincell charger. maybe need a small power driver ? */
+ coincell = regulator_get(NULL, "coincell");
+ if (!IS_ERR(coincell)) {
+ regulator_set_voltage(coincell, 3000000, 3000000);
+ regulator_enable(coincell);
+ }
+
+ regulator_has_full_constraints();
+ }
+
+ return 0;
+}
+late_initcall(mx51_efikamx_power_init);
+
+static void __init mx51_efikamx_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51efikamx_pads,
+ ARRAY_SIZE(mx51efikamx_pads));
+ efika_board_common_init();
+
+ mx51_efikamx_board_id();
+
+ /* on < 1.2 boards both SD controllers are used */
+ if (system_rev < 0x12) {
+ imx51_add_sdhci_esdhc_imx(1, NULL);
+ mx51_efikamx_leds[2].default_trigger = "mmc1";
+ }
+
+ platform_device_register(&mx51_efikamx_leds_device);
+ imx_add_gpio_keys(&mx51_efikamx_powerkey_data);
+
+ if (system_rev == 0x11) {
+ gpio_request(EFIKAMX_RESET1_1, "reset");
+ gpio_direction_output(EFIKAMX_RESET1_1, 1);
+ } else {
+ gpio_request(EFIKAMX_RESET, "reset");
+ gpio_direction_output(EFIKAMX_RESET, 1);
+ }
+
+ /*
+ * enable wifi by default only on mx
+ * sb and mx have same wlan pin but the value to enable it are
+ * different :/
+ */
+ gpio_request(EFIKA_WLAN_EN, "wlan_en");
+ gpio_direction_output(EFIKA_WLAN_EN, 0);
+ msleep(10);
+
+ gpio_request(EFIKA_WLAN_RESET, "wlan_rst");
+ gpio_direction_output(EFIKA_WLAN_RESET, 0);
+ msleep(10);
+ gpio_set_value(EFIKA_WLAN_RESET, 1);
+}
+
+static void __init mx51_efikamx_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 24576000);
+}
+
+static struct sys_timer mx51_efikamx_timer = {
+ .init = mx51_efikamx_timer_init,
+};
+
+MACHINE_START(MX51_EFIKAMX, "Genesi EfikaMX nettop")
+ /* Maintainer: Amit Kucheria <amit.kucheria@linaro.org> */
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .timer = &mx51_efikamx_timer,
+ .init_machine = mx51_efikamx_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx51_efikasb.c b/arch/arm/mach-mx5/board-mx51_efikasb.c
new file mode 100644
index 00000000..474fc6e4
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_efikasb.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * based on code from the following
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved.
+ * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <mach/ulpi.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+#include "efika.h"
+
+#define EFIKASB_USBH2_STP IMX_GPIO_NR(2, 20)
+#define EFIKASB_GREEN_LED IMX_GPIO_NR(1, 3)
+#define EFIKASB_WHITE_LED IMX_GPIO_NR(2, 25)
+#define EFIKASB_PCBID0 IMX_GPIO_NR(2, 28)
+#define EFIKASB_PCBID1 IMX_GPIO_NR(2, 29)
+#define EFIKASB_PWRKEY IMX_GPIO_NR(2, 31)
+#define EFIKASB_LID IMX_GPIO_NR(3, 14)
+#define EFIKASB_POWEROFF IMX_GPIO_NR(4, 13)
+#define EFIKASB_RFKILL IMX_GPIO_NR(3, 1)
+
+#define MX51_PAD_PWRKEY IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, PAD_CTL_PUS_100K_UP | PAD_CTL_PKE)
+
+static iomux_v3_cfg_t mx51efikasb_pads[] = {
+ /* USB HOST2 */
+ MX51_PAD_EIM_D16__USBH2_DATA0,
+ MX51_PAD_EIM_D17__USBH2_DATA1,
+ MX51_PAD_EIM_D18__USBH2_DATA2,
+ MX51_PAD_EIM_D19__USBH2_DATA3,
+ MX51_PAD_EIM_D20__USBH2_DATA4,
+ MX51_PAD_EIM_D21__USBH2_DATA5,
+ MX51_PAD_EIM_D22__USBH2_DATA6,
+ MX51_PAD_EIM_D23__USBH2_DATA7,
+ MX51_PAD_EIM_A24__USBH2_CLK,
+ MX51_PAD_EIM_A25__USBH2_DIR,
+ MX51_PAD_EIM_A26__USBH2_STP,
+ MX51_PAD_EIM_A27__USBH2_NXT,
+
+ /* leds */
+ MX51_PAD_EIM_CS0__GPIO2_25,
+ MX51_PAD_GPIO1_3__GPIO1_3,
+
+ /* pcb id */
+ MX51_PAD_EIM_CS3__GPIO2_28,
+ MX51_PAD_EIM_CS4__GPIO2_29,
+
+ /* lid */
+ MX51_PAD_CSI1_VSYNC__GPIO3_14,
+
+ /* power key*/
+ MX51_PAD_PWRKEY,
+
+ /* wifi/bt button */
+ MX51_PAD_DI1_PIN12__GPIO3_1,
+
+ /* power off */
+ MX51_PAD_CSI2_VSYNC__GPIO4_13,
+
+ /* wdog reset */
+ MX51_PAD_GPIO1_4__WDOG1_WDOG_B,
+
+ /* BT */
+ MX51_PAD_EIM_A17__GPIO2_11,
+};
+
+static int initialize_usbh2_port(struct platform_device *pdev)
+{
+ iomux_v3_cfg_t usbh2stp = MX51_PAD_EIM_A26__USBH2_STP;
+ iomux_v3_cfg_t usbh2gpio = MX51_PAD_EIM_A26__GPIO2_20;
+
+ mxc_iomux_v3_setup_pad(usbh2gpio);
+ gpio_request(EFIKASB_USBH2_STP, "usbh2_stp");
+ gpio_direction_output(EFIKASB_USBH2_STP, 0);
+ msleep(1);
+ gpio_set_value(EFIKASB_USBH2_STP, 1);
+ msleep(1);
+
+ gpio_free(EFIKASB_USBH2_STP);
+ mxc_iomux_v3_setup_pad(usbh2stp);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(pdev->id, MXC_EHCI_ITC_NO_THRESHOLD);
+}
+
+static struct mxc_usbh_platform_data usbh2_config = {
+ .init = initialize_usbh2_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static void __init mx51_efikasb_usb(void)
+{
+ usbh2_config.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT | ULPI_OTG_EXTVBUSIND);
+ if (usbh2_config.otg)
+ mxc_register_device(&mxc_usbh2_device, &usbh2_config);
+}
+
+static struct gpio_led mx51_efikasb_leds[] = {
+ {
+ .name = "efikasb:green",
+ .default_trigger = "default-on",
+ .gpio = EFIKASB_GREEN_LED,
+ .active_low = 1,
+ },
+ {
+ .name = "efikasb:white",
+ .default_trigger = "caps",
+ .gpio = EFIKASB_WHITE_LED,
+ },
+};
+
+static struct gpio_led_platform_data mx51_efikasb_leds_data = {
+ .leds = mx51_efikasb_leds,
+ .num_leds = ARRAY_SIZE(mx51_efikasb_leds),
+};
+
+static struct platform_device mx51_efikasb_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mx51_efikasb_leds_data,
+ },
+};
+
+static struct gpio_keys_button mx51_efikasb_keys[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = EFIKASB_PWRKEY,
+ .type = EV_PWR,
+ .desc = "Power Button",
+ .wakeup = 1,
+ .debounce_interval = 10, /* ms */
+ },
+ {
+ .code = SW_LID,
+ .gpio = EFIKASB_LID,
+ .type = EV_SW,
+ .desc = "Lid Switch",
+ },
+ {
+ /* SW_RFKILLALL vs KEY_RFKILL ? */
+ .code = SW_RFKILL_ALL,
+ .gpio = EFIKASB_RFKILL,
+ .type = EV_SW,
+ .desc = "rfkill",
+ },
+};
+
+static const struct gpio_keys_platform_data mx51_efikasb_keys_data __initconst = {
+ .buttons = mx51_efikasb_keys,
+ .nbuttons = ARRAY_SIZE(mx51_efikasb_keys),
+};
+
+static struct regulator *pwgt1, *pwgt2;
+
+static void mx51_efikasb_power_off(void)
+{
+ gpio_set_value(EFIKA_USB_PHY_RESET, 0);
+
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_disable(pwgt2);
+ regulator_disable(pwgt1);
+ }
+ gpio_direction_output(EFIKASB_POWEROFF, 1);
+}
+
+static int __init mx51_efikasb_power_init(void)
+{
+ if (machine_is_mx51_efikasb()) {
+ pwgt1 = regulator_get(NULL, "pwgt1");
+ pwgt2 = regulator_get(NULL, "pwgt2");
+ if (!IS_ERR(pwgt1) && !IS_ERR(pwgt2)) {
+ regulator_enable(pwgt1);
+ regulator_enable(pwgt2);
+ }
+ gpio_request(EFIKASB_POWEROFF, "poweroff");
+ pm_power_off = mx51_efikasb_power_off;
+
+ regulator_has_full_constraints();
+ }
+
+ return 0;
+}
+late_initcall(mx51_efikasb_power_init);
+
+/* 01 R1.3 board
+ 10 R2.0 board */
+static void __init mx51_efikasb_board_id(void)
+{
+ int id;
+
+ gpio_request(EFIKASB_PCBID0, "pcb id0");
+ gpio_direction_input(EFIKASB_PCBID0);
+ gpio_request(EFIKASB_PCBID1, "pcb id1");
+ gpio_direction_input(EFIKASB_PCBID1);
+
+ id = gpio_get_value(EFIKASB_PCBID0);
+ id |= gpio_get_value(EFIKASB_PCBID1) << 1;
+
+ switch (id) {
+ default:
+ break;
+ case 1:
+ system_rev = 0x13;
+ break;
+ case 2:
+ system_rev = 0x20;
+ break;
+ }
+}
+
+static void __init efikasb_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51efikasb_pads,
+ ARRAY_SIZE(mx51efikasb_pads));
+ efika_board_common_init();
+
+ mx51_efikasb_board_id();
+ mx51_efikasb_usb();
+ imx51_add_sdhci_esdhc_imx(1, NULL);
+
+ platform_device_register(&mx51_efikasb_leds_device);
+ imx_add_gpio_keys(&mx51_efikasb_keys_data);
+
+}
+
+static void __init mx51_efikasb_timer_init(void)
+{
+ mx51_clocks_init(32768, 24000000, 22579200, 24576000);
+}
+
+static struct sys_timer mx51_efikasb_timer = {
+ .init = mx51_efikasb_timer_init,
+};
+
+MACHINE_START(MX51_EFIKASB, "Genesi Efika Smartbook")
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .init_machine = efikasb_board_init,
+ .timer = &mx51_efikasb_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c
new file mode 100755
index 00000000..7774b73f
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx53_ard.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/mxcfb.h>
+#include <linux/ipu.h>
+#include <linux/pwm_backlight.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx53.h>
+#include <mach/ipu-v3.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "crm_regs.h"
+#include "devices-imx53.h"
+
+#define ARD_SD1_CD IMX_GPIO_NR(1, 1)
+#define ARD_SD1_WP IMX_GPIO_NR(1, 9)
+#define ARD_SD2_CD IMX_GPIO_NR(1, 4)
+#define ARD_SD2_WP IMX_GPIO_NR(1, 2)
+#define ARD_ESAI_INT IMX_GPIO_NR(2, 4)
+#define ARD_TS_INT IMX_GPIO_NR(7, 12)
+#define ARD_ETHERNET_INT_B IMX_GPIO_NR(2, 31)
+
+/* Start directly after the CPU's GPIO*/
+#define MAX7310_BASE_ADDR 224 /* 7x32 */
+#define ARD_BACKLIGHT_ON MAX7310_BASE_ADDR
+#define ARD_SPARE (MAX7310_BASE_ADDR + 1)
+#define ARD_CPU_PER_RST_B (MAX7310_BASE_ADDR + 2)
+#define ARD_MAIN_PER_RST_B (MAX7310_BASE_ADDR + 3)
+#define ARD_IPOD_RST_B (MAX7310_BASE_ADDR + 4)
+#define ARD_MLB_RST_B (MAX7310_BASE_ADDR + 5)
+#define ARD_SSI_STEERING (MAX7310_BASE_ADDR + 6)
+#define ARD_GPS_RST_B (MAX7310_BASE_ADDR + 7)
+
+extern char *gp_reg_id;
+extern char *lp_reg_id;
+extern void mx5_cpu_regulator_init(void);
+
+static iomux_v3_cfg_t mx53_ard_pads[] = {
+ /* UART */
+ MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
+ MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+ MX53_PAD_PATA_DIOR__UART2_RTS,
+ MX53_PAD_PATA_INTRQ__UART2_CTS,
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+ MX53_PAD_PATA_DA_1__UART3_CTS,
+ MX53_PAD_PATA_DA_2__UART3_RTS,
+
+ /* SDHC1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+ MX53_PAD_PATA_DATA8__ESDHC1_DAT4,
+ MX53_PAD_PATA_DATA9__ESDHC1_DAT5,
+ MX53_PAD_PATA_DATA10__ESDHC1_DAT6,
+ MX53_PAD_PATA_DATA11__ESDHC1_DAT7,
+ MX53_PAD_GPIO_1__GPIO1_1,
+ MX53_PAD_GPIO_9__GPIO1_9,
+
+ /* SDHC2 */
+ MX53_PAD_SD2_CLK__ESDHC2_CLK,
+ MX53_PAD_SD2_CMD__ESDHC2_CMD,
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0,
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1,
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2,
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3,
+ MX53_PAD_PATA_DATA12__ESDHC2_DAT4,
+ MX53_PAD_PATA_DATA13__ESDHC2_DAT5,
+ MX53_PAD_PATA_DATA14__ESDHC2_DAT6,
+ MX53_PAD_PATA_DATA15__ESDHC2_DAT7,
+ MX53_PAD_GPIO_4__GPIO1_4,
+ MX53_PAD_GPIO_2__GPIO1_2,
+
+ /* WEIM for CS1 */
+ /* ETHERNET_INT_B */
+ MX53_PAD_EIM_EB3__GPIO2_31,
+ MX53_PAD_EIM_D16__EMI_WEIM_D_16,
+ MX53_PAD_EIM_D17__EMI_WEIM_D_17,
+ MX53_PAD_EIM_D18__EMI_WEIM_D_18,
+ MX53_PAD_EIM_D19__EMI_WEIM_D_19,
+ MX53_PAD_EIM_D20__EMI_WEIM_D_20,
+ MX53_PAD_EIM_D21__EMI_WEIM_D_21,
+ MX53_PAD_EIM_D22__EMI_WEIM_D_22,
+ MX53_PAD_EIM_D23__EMI_WEIM_D_23,
+ MX53_PAD_EIM_D24__EMI_WEIM_D_24,
+ MX53_PAD_EIM_D25__EMI_WEIM_D_25,
+ MX53_PAD_EIM_D26__EMI_WEIM_D_26,
+ MX53_PAD_EIM_D27__EMI_WEIM_D_27,
+ MX53_PAD_EIM_D28__EMI_WEIM_D_28,
+ MX53_PAD_EIM_D29__EMI_WEIM_D_29,
+ MX53_PAD_EIM_D30__EMI_WEIM_D_30,
+ MX53_PAD_EIM_D31__EMI_WEIM_D_31,
+ MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0,
+ MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1,
+ MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2,
+ MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3,
+ MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4,
+ MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5,
+ MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6,
+ MX53_PAD_EIM_OE__EMI_WEIM_OE,
+ MX53_PAD_EIM_RW__EMI_WEIM_RW,
+ MX53_PAD_EIM_CS1__EMI_WEIM_CS_1,
+ /* I2C2 */
+ MX53_PAD_EIM_EB2__I2C2_SCL,
+ MX53_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* I2C3 */
+ MX53_PAD_GPIO_3__I2C3_SCL,
+ MX53_PAD_GPIO_16__I2C3_SDA,
+
+ /* TOUCH_INT_B */
+ MX53_PAD_GPIO_17__GPIO7_12,
+
+ /* MAINBRD_SPDIF_IN */
+ MX53_PAD_KEY_COL3__SPDIF_IN1,
+ /* LVDS */
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+ /* PWM */
+ MX53_PAD_DISP0_DAT8__PWM1_PWMO,
+ MX53_PAD_DISP0_DAT9__PWM2_PWMO
+};
+
+/* Config CS1 settings for ethernet controller */
+static void weim_cs_config(void)
+{
+ u32 reg;
+ void __iomem *weim_base, *iomuxc_base;
+ weim_base = ioremap(MX53_WEIM_BASE_ADDR, SZ_4K);
+ iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K);
+
+ /* CS1 timings for LAN9220 */
+ writel(0x20001, (weim_base + 0x18));
+ writel(0x0, (weim_base + 0x1C));
+ writel(0x16000202, (weim_base + 0x20));
+ writel(0x00000002, (weim_base + 0x24));
+ writel(0x16002082, (weim_base + 0x28));
+ writel(0x00000000, (weim_base + 0x2C));
+ writel(0x00000000, (weim_base + 0x90));
+
+ /* specify 64 MB on CS1 and CS0 on GPR1 */
+ reg = readl(iomuxc_base + 0x4);
+ reg &= ~0x3F;
+ reg |= 0x1B;
+ writel(reg, (iomuxc_base + 0x4));
+ iounmap(iomuxc_base);
+ iounmap(weim_base);
+}
+
+static struct resource ard_smsc911x_resources[] = {
+ {
+ .start = MX53_CS1_BASE_ADDR,
+ .end = MX53_CS1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = gpio_to_irq(ARD_ETHERNET_INT_B),
+ .end = gpio_to_irq(ARD_ETHERNET_INT_B),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+struct smsc911x_platform_config ard_smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct platform_device ard_smsc_lan9220_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ard_smsc911x_resources),
+ .resource = ard_smsc911x_resources,
+};
+
+static iomux_v3_cfg_t mx53_ard_esai_pads[] = {
+ MX53_PAD_FEC_MDIO__ESAI1_SCKR,
+ MX53_PAD_FEC_REF_CLK__ESAI1_FSR,
+ MX53_PAD_FEC_CRS_DV__ESAI1_SCKT,
+ MX53_PAD_FEC_RXD1__ESAI1_FST,
+ MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2,
+ MX53_PAD_GPIO_5__ESAI1_TX2_RX3,
+ MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1,
+ MX53_PAD_GPIO_8__ESAI1_TX5_RX0,
+ MX53_PAD_NANDF_CS2__ESAI1_TX0,
+ MX53_PAD_NANDF_CS3__ESAI1_TX1,
+ MX53_PAD_PATA_DATA4__GPIO2_4,
+};
+
+void ard_gpio_activate_esai_ports(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_ard_esai_pads,
+ ARRAY_SIZE(mx53_ard_esai_pads));
+ /* ESAI_INT */
+ gpio_request(ARD_ESAI_INT, "esai-int");
+ gpio_direction_input(ARD_ESAI_INT);
+
+}
+
+static struct imx_esai_platform_data esai_data = {
+ .flags = IMX_ESAI_NET,
+};
+
+static struct platform_device mxc_alsa_surround_device = {
+ .name = "imx-cs42888",
+};
+
+static struct mxc_audio_platform_data mxc_surround_audio_data = {
+ .ext_ram = 1,
+ .sysclk = 24576000,
+};
+
+static struct mxc_audio_codec_platform_data cs42888_data = {
+ .rates = (SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000),
+};
+
+static int imx53_init_audio(void)
+{
+ ard_gpio_activate_esai_ports();
+
+ mxc_register_device(&mxc_alsa_surround_device,
+ &mxc_surround_audio_data);
+ imx53_add_imx_esai(0, &esai_data);
+
+ return 0;
+}
+
+static int mx53_ard_max7310_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ static int max7310_gpio_value[] = {
+ 1, 1, 1, 1, 0, 0, 0, 0,
+ };
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ /* Export, direction locked down */
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data mx53_i2c_max7310_platdata = {
+ .gpio_base = MAX7310_BASE_ADDR,
+ .invert = 0, /* Do not invert */
+ .setup = mx53_ard_max7310_setup,
+};
+
+static const struct imxuart_platform_data mx53_ard_uart_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct esdhc_platform_data mx53_ard_sd1_data __initconst = {
+ .cd_gpio = ARD_SD1_CD,
+ .wp_gpio = ARD_SD1_WP,
+};
+
+static const struct esdhc_platform_data mx53_ard_sd2_data __initconst = {
+ .cd_gpio = ARD_SD2_CD,
+ .wp_gpio = ARD_SD2_WP,
+};
+
+static struct imxi2c_platform_data mx53_ard_i2c1_data = {
+ .bitrate = 50000,
+};
+
+static struct imxi2c_platform_data mx53_ard_i2c2_data = {
+ .bitrate = 400000,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "cs42888",
+ .addr = 0x48,
+ .platform_data = (void *)&cs42888_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max11801", 0x49),
+ .irq = gpio_to_irq(ARD_TS_INT),
+ },
+ {
+ .type = "max7310",
+ .addr = 0x18,
+ .platform_data = &mx53_i2c_max7310_platdata,
+ },
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 0,
+ .spdif_rx = 1,
+ .spdif_clk_44100 = 0, /* tx clk from CKIH1 for 44.1K */
+ .spdif_clk_48000 = 7, /* tx clk from CKIH2 for 48k and 32k */
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct mxc_regulator_platform_data ard_regulator_data = {
+ .cpu_reg_id = "SW1",
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static inline void mx53_ard_init_uart(void)
+{
+ imx53_add_imx_uart(0, NULL);
+ imx53_add_imx_uart(1, &mx53_ard_uart_data);
+ imx53_add_imx_uart(2, &mx53_ard_uart_data);
+}
+
+static struct ipuv3_fb_platform_data ard_fb_data[] = {
+ {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+ {
+ .disp_dev = "vga",
+ .interface_pix_fmt = IPU_PIX_FMT_GBR24,
+ .mode_str = "VGA-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+ .rev = 3,
+};
+
+static struct platform_pwm_backlight_data ard_pwm1_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct platform_pwm_backlight_data ard_pwm2_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct fsl_mxc_tve_platform_data tve_data = {
+ .dac_reg = "LDO4",
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SIN0,
+};
+
+static void __init mx53_ard_io_init(void)
+{
+ /* MX53 ARD board */
+ pr_info("MX53 ARD board \n");
+ gpio_request(ARD_ETHERNET_INT_B, "eth-int-b");
+ gpio_direction_input(ARD_ETHERNET_INT_B);
+}
+
+static int __initdata enable_ard_vga = { 0 };
+static int __init ard_vga_setup(char *__unused)
+{
+ enable_ard_vga = 1;
+ printk(KERN_INFO "Enable MX53 ARD VGA\n");
+ return cpu_is_mx53();
+}
+__setup("ard-vga", ard_vga_setup);
+
+static void __init mx53_ard_board_init(void)
+{
+ int i;
+ mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads,
+ ARRAY_SIZE(mx53_ard_pads));
+
+ /* setup VGA PINs */
+ if (enable_ard_vga) {
+ iomux_v3_cfg_t vga;
+ vga = MX53_PAD_EIM_OE__IPU_DI1_PIN7;
+ mxc_iomux_v3_setup_pad(vga);
+ vga = MX53_PAD_EIM_RW__IPU_DI1_PIN8;
+ mxc_iomux_v3_setup_pad(vga);
+ }
+
+ gp_reg_id = ard_regulator_data.cpu_reg_id;
+ lp_reg_id = ard_regulator_data.vcc_reg_id;
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ mx53_ard_init_uart();
+
+ imx53_add_ipuv3(0, &ipu_data);
+ for (i = 0; i < ARRAY_SIZE(ard_fb_data); i++)
+ imx53_add_ipuv3fb(i, &ard_fb_data[i]);
+
+ imx53_add_vpu();
+ imx53_add_ldb(&ldb_data);
+ imx53_add_tve(&tve_data);
+ imx53_add_v4l2_output(0);
+
+ imx53_add_mxc_pwm(0);
+ imx53_add_mxc_pwm_backlight(0, &ard_pwm1_backlight_data);
+ imx53_add_mxc_pwm(1);
+ imx53_add_mxc_pwm_backlight(1, &ard_pwm2_backlight_data);
+
+ imx53_add_srtc();
+ imx53_add_imx2_wdt(0, NULL);
+ imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data);
+ imx53_add_sdhci_esdhc_imx(1, &mx53_ard_sd2_data);
+ mxc_register_device(&imx_ahci_device_hwmon, NULL);
+
+ weim_cs_config();
+ mx53_ard_io_init();
+ mxc_register_device(&ard_smsc_lan9220_device, &ard_smsc911x_config);
+ imx53_add_imx_i2c(1, &mx53_ard_i2c1_data);
+ imx53_add_imx_i2c(2, &mx53_ard_i2c2_data);
+
+ imx53_add_spdif(&mxc_spdif_data);
+ imx53_add_spdif_dai();
+ imx53_add_spdif_audio_device();
+
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+ imx53_init_audio();
+
+ mx5_cpu_regulator_init();
+
+ /* this call required to release SCC RAM partition held by ROM
+ * during boot, even if SCC2 driver is not part of the image
+ */
+ imx53_add_mxc_scc2();
+}
+
+static void __init mx53_ard_timer_init(void)
+{
+ mx53_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx53_ard_timer = {
+ .init = mx53_ard_timer_init,
+};
+
+MACHINE_START(MX53_ARD, "Freescale MX53 ARD Board")
+ .fixup = fixup_mxc_board,
+ .map_io = mx53_map_io,
+ .init_early = imx53_init_early,
+ .init_irq = mx53_init_irq,
+ .timer = &mx53_ard_timer,
+ .init_machine = mx53_ard_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
new file mode 100755
index 00000000..be703204
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -0,0 +1,808 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/fec.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mxcfb.h>
+#include <linux/ipu.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx53.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_dvfs.h>
+
+#include "crm_regs.h"
+#include "devices-imx53.h"
+#include "devices.h"
+
+#define MX53_EVK_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+#define EVK_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define EVK_HP_DETECT IMX_GPIO_NR(2, 5) /* GPIO_2_5 */
+#define EVK_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define EVK_SD3_CD IMX_GPIO_NR(3, 11) /* GPIO_3_11 */
+#define EVK_SD3_WP IMX_GPIO_NR(3, 12) /* GPIO_3_12 */
+#define EVK_SD1_CD IMX_GPIO_NR(3, 13) /* GPIO_3_13 */
+#define EVK_SD1_WP IMX_GPIO_NR(3, 14) /* GPIO_3_14 */
+#define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define EVK_DISP0_PD IMX_GPIO_NR(3, 24) /* GPIO_3_24 */
+#define EVK_TS_INT IMX_GPIO_NR(3, 26) /* GPIO_3_26 */
+#define EVK_DISP0_I2C_EN IMX_GPIO_NR(3, 28) /* GPIO_3_28 */
+#define EVK_DISP0_DET_INT IMX_GPIO_NR(3, 31) /* GPIO_3_31 */
+#define EVK_CAM_RESET IMX_GPIO_NR(4, 0) /* GPIO_4_0 */
+#define EVK_ESAI_RESET IMX_GPIO_NR(4, 2) /* GPIO_4_2 */
+#define EVK_CAN2_EN2 IMX_GPIO_NR(4, 4) /* GPIO_4_4 */
+#define EVK_12V_EN IMX_GPIO_NR(4, 5) /* GPIO_4_5 */
+#define EVK_DISP0_RESET IMX_GPIO_NR(5, 0) /* GPIO_5_0 */
+#define EVK_USB_HUB_RESET IMX_GPIO_NR(5, 20) /* GPIO_5_20 */
+#define EVK_TVIN_PWR IMX_GPIO_NR(5, 23) /* GPIO_5_23 */
+#define EVK_CAN2_EN1 IMX_GPIO_NR(5, 24) /* GPIO_5_24 */
+#define EVK_TVIN_RESET IMX_GPIO_NR(5, 25) /* GPIO_5_25 */
+#define EVK_OTG_VBUS IMX_GPIO_NR(6, 6) /* GPIO_6_6 */
+#define EVK_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+#define EVK_USBH1_VBUS IMX_GPIO_NR(7, 8) /* GPIO_7_8 */
+#define EVK_PMIC_INT IMX_GPIO_NR(7, 11) /* GPIO_7_11 */
+#define EVK_CAN1_EN1 IMX_GPIO_NR(7, 12) /* GPIO_7_12 */
+#define EVK_CAN1_EN2 IMX_GPIO_NR(7, 13) /* GPIO_7_13 */
+
+#define ARM2_SD1_CD IMX_GPIO_NR(1, 1) /* GPIO_1_1 */
+#define ARM2_OTG_VBUS IMX_GPIO_NR(3, 22) /* GPIO_3_22 */
+#define ARM2_LCD_CONTRAST IMX_GPIO_NR(4, 20) /* GPIO_4_20 */
+
+extern char *lp_reg_id;
+extern char *gp_reg_id;
+extern void mx5_cpu_regulator_init(void);
+
+static iomux_v3_cfg_t mx53common_pads[] = {
+ MX53_PAD_EIM_WAIT__GPIO5_0,
+
+ MX53_PAD_EIM_OE__IPU_DI1_PIN7,
+ MX53_PAD_EIM_RW__IPU_DI1_PIN8,
+
+ MX53_PAD_EIM_A25__IPU_DI0_D1_CS,
+
+ MX53_PAD_EIM_D16__ECSPI1_SCLK,
+ MX53_PAD_EIM_D17__ECSPI1_MISO,
+ MX53_PAD_EIM_D18__ECSPI1_MOSI,
+
+ MX53_PAD_EIM_D20__IPU_SER_DISP0_CS,
+
+ MX53_PAD_EIM_D23__IPU_DI0_D0_CS,
+
+ MX53_PAD_EIM_D24__GPIO3_24,
+ MX53_PAD_EIM_D26__GPIO3_26,
+
+ MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS,
+
+ MX53_PAD_EIM_D30__IPU_DI0_PIN11,
+ MX53_PAD_EIM_D31__IPU_DI0_PIN12,
+
+ MX53_PAD_PATA_DA_1__GPIO7_7,
+ MX53_PAD_PATA_DATA4__GPIO2_4,
+ MX53_PAD_PATA_DATA5__GPIO2_5,
+ MX53_PAD_PATA_DATA6__GPIO2_6,
+
+ MX53_PAD_SD2_CLK__ESDHC2_CLK,
+ MX53_PAD_SD2_CMD__ESDHC2_CMD,
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0,
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1,
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2,
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3,
+ MX53_PAD_PATA_DATA12__ESDHC2_DAT4,
+ MX53_PAD_PATA_DATA13__ESDHC2_DAT5,
+ MX53_PAD_PATA_DATA14__ESDHC2_DAT6,
+ MX53_PAD_PATA_DATA15__ESDHC2_DAT7,
+
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX,
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX,
+
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+ MX53_PAD_PATA_DIOR__UART2_RTS,
+ MX53_PAD_PATA_INTRQ__UART2_CTS,
+
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
+
+ MX53_PAD_CSI0_DAT7__GPIO5_25,
+
+ MX53_PAD_GPIO_2__MLB_MLBDAT,
+ MX53_PAD_GPIO_3__MLB_MLBCLK,
+
+ MX53_PAD_GPIO_6__MLB_MLBSIG,
+
+ MX53_PAD_GPIO_4__GPIO1_4,
+ MX53_PAD_GPIO_7__GPIO1_7,
+ MX53_PAD_GPIO_8__GPIO1_8,
+
+ MX53_PAD_GPIO_10__GPIO4_0,
+
+ MX53_PAD_KEY_COL2__CAN1_TXCAN,
+ MX53_PAD_KEY_ROW2__CAN1_RXCAN,
+
+ /* CAN1 -- EN */
+ MX53_PAD_GPIO_18__GPIO7_13,
+ /* CAN1 -- STBY */
+ MX53_PAD_GPIO_17__GPIO7_12,
+ /* CAN1 -- NERR */
+ MX53_PAD_GPIO_5__GPIO1_5,
+
+ MX53_PAD_KEY_COL4__CAN2_TXCAN,
+ MX53_PAD_KEY_ROW4__CAN2_RXCAN,
+
+ /* CAN2 -- EN */
+ MX53_PAD_CSI0_DAT6__GPIO5_24,
+ /* CAN2 -- STBY */
+ MX53_PAD_GPIO_14__GPIO4_4,
+ /* CAN2 -- NERR */
+ MX53_PAD_CSI0_DAT4__GPIO5_22,
+
+ MX53_PAD_GPIO_11__GPIO4_1,
+ MX53_PAD_GPIO_12__GPIO4_2,
+ MX53_PAD_GPIO_13__GPIO4_3,
+ MX53_PAD_GPIO_16__GPIO7_11,
+ MX53_PAD_GPIO_19__GPIO4_5,
+
+ /* DI0 display clock */
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
+
+ /* DI0 data enable */
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
+ /* DI0 HSYNC */
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
+ /* DI0 VSYNC */
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
+
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
+
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+
+ /* audio and CSI clock out */
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK,
+
+ MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12,
+ MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13,
+ MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14,
+ MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15,
+ MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16,
+ MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17,
+ MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18,
+ MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19,
+
+ MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC,
+ MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC,
+ MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK,
+ /* Camera low power */
+ MX53_PAD_CSI0_DAT5__GPIO5_23,
+
+ /* esdhc1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+
+ /* esdhc3 */
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+
+ /* FEC pins */
+ MX53_PAD_FEC_MDIO__FEC_MDIO,
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+ MX53_PAD_FEC_MDC__FEC_MDC,
+
+ MX53_PAD_CSI0_DAT8__I2C1_SDA,
+ MX53_PAD_CSI0_DAT9__I2C1_SCL,
+
+ MX53_PAD_KEY_COL3__I2C2_SCL,
+ MX53_PAD_KEY_ROW3__I2C2_SDA,
+};
+
+static iomux_v3_cfg_t mx53evk_pads[] = {
+ /* USB OTG USB_OC */
+ MX53_PAD_EIM_A24__GPIO5_4,
+
+ /* USB OTG USB_PWR */
+ MX53_PAD_EIM_A23__GPIO6_6,
+
+ /* DISPB0_SER_CLK */
+ MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK,
+
+ /* DI0_PIN1 */
+ MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN,
+
+ /* DISP0 I2C ENABLE */
+ MX53_PAD_EIM_D28__GPIO3_28,
+
+ /* DISP0 DET */
+ MX53_PAD_EIM_D31__GPIO3_31,
+
+ /* SDHC1 SD_CD */
+ MX53_PAD_EIM_DA13__GPIO3_13,
+
+ /* SDHC1 SD_WP */
+ MX53_PAD_EIM_DA14__GPIO3_14,
+
+ /* SDHC3 SD_CD */
+ MX53_PAD_EIM_DA11__GPIO3_11,
+
+ /* SDHC3 SD_WP */
+ MX53_PAD_EIM_DA12__GPIO3_12,
+
+ /* PWM backlight */
+ MX53_PAD_GPIO_1__PWM2_PWMO,
+
+ /* USB HOST USB_PWR */
+ MX53_PAD_PATA_DA_2__GPIO7_8,
+
+ /* USB HOST USB_RST */
+ MX53_PAD_CSI0_DATA_EN__GPIO5_20,
+
+ /* USB HOST CARD_ON */
+ MX53_PAD_EIM_DA15__GPIO3_15,
+
+ /* USB HOST CARD_RST */
+ MX53_PAD_PATA_DATA7__GPIO2_7,
+
+ /* USB HOST WAN_WAKE */
+ MX53_PAD_EIM_D25__GPIO3_25,
+
+ /* FEC_RST */
+ MX53_PAD_PATA_DA_0__GPIO7_6,
+};
+
+static iomux_v3_cfg_t mx53arm2_pads[] = {
+ /* USB OTG USB_OC */
+ MX53_PAD_EIM_D21__GPIO3_21,
+
+ /* USB OTG USB_PWR */
+ MX53_PAD_EIM_D22__GPIO3_22,
+
+ /* SDHC1 SD_CD */
+ MX53_PAD_GPIO_1__GPIO1_1,
+
+ /* gpio backlight */
+ MX53_PAD_DI0_PIN4__GPIO4_20,
+};
+
+static iomux_v3_cfg_t mx53_nand_pads[] = {
+ MX53_PAD_NANDF_CLE__EMI_NANDF_CLE,
+ MX53_PAD_NANDF_ALE__EMI_NANDF_ALE,
+ MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B,
+ MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B,
+ MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B,
+ MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0,
+ MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0,
+ MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 ,
+ MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2,
+ MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 ,
+ MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0,
+ MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1,
+ MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2,
+ MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3,
+ MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4,
+ MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5,
+ MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6,
+ MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7,
+};
+
+static const struct imxuart_platform_data mx53_evk_uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct ipuv3_fb_platform_data evk_fb_data[] = {
+ {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "vga",
+ .interface_pix_fmt = IPU_PIX_FMT_GBR24,
+ .mode_str = "VGA-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+ .rev = 3,
+};
+
+static struct platform_pwm_backlight_data evk_pwm_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct fsl_mxc_tve_platform_data tve_data = {
+ .dac_reg = "VVIDEO",
+};
+
+static inline void mx53_evk_init_uart(void)
+{
+ imx53_add_imx_uart(0, NULL);
+ imx53_add_imx_uart(1, &mx53_evk_uart_pdata);
+ imx53_add_imx_uart(2, NULL);
+}
+
+static const struct imxi2c_platform_data mx53_evk_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static inline void mx53_evk_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW,
+ "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ msleep(1);
+ gpio_set_value(MX53_EVK_FEC_PHY_RST, 1);
+}
+
+static struct fec_platform_data mx53_evk_fec_pdata = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct spi_board_info mx53_evk_spi_board_info[] __initdata = {
+ {
+ .modalias = "mtd_dataflash",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = NULL,
+ },
+};
+
+static int mx53_evk_spi_cs[] = {
+ EVK_ECSPI1_CS0,
+ EVK_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx53_evk_spi_data __initconst = {
+ .chipselect = mx53_evk_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx53_evk_spi_cs),
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+};
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(EVK_DISP0_RESET, 0);
+ msleep(10);
+ gpio_set_value(EVK_DISP0_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .reset = sii902x_hdmi_reset,
+};
+
+static void ddc_dvi_init(void)
+{
+ /* enable DVI I2C */
+ gpio_set_value(EVK_DISP0_I2C_EN, 1);
+}
+
+static int ddc_dvi_update(void)
+{
+ /* DVI cable state */
+ if (gpio_get_value(EVK_DISP0_DET_INT) == 1)
+ return 1;
+ else
+ return 0;
+}
+
+static struct fsl_mxc_dvi_platform_data evk_ddc_dvi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .init = ddc_dvi_init,
+ .update = ddc_dvi_update,
+ .analog_regulator = "VSD",
+};
+
+/* TO DO add platform data */
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "sgtl5000-i2c",
+ .addr = 0x0a,
+ },
+ {
+ .type = "tsc2007",
+ .addr = 0x48,
+ .irq = gpio_to_irq(EVK_TS_INT),
+ },
+ {
+ .type = "backlight-i2c",
+ .addr = 0x2c,
+ },
+ {
+ .type = "mxc_dvi",
+ .addr = 0x50,
+ .irq = gpio_to_irq(EVK_DISP0_DET_INT),
+ .platform_data = &evk_ddc_dvi_data,
+ },
+ {
+ .type = "sii902x",
+ .addr = 0x39,
+ .irq = gpio_to_irq(EVK_DISP0_DET_INT),
+ .platform_data = &sii902x_hdmi_data,
+ },
+};
+
+static struct mxc_dvfs_platform_data evk_dvfs_core_data = {
+ .reg_id = "SW1",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .gpc_vcr_offset = MXC_GPC_VCR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 30,
+};
+
+static const struct esdhc_platform_data mx53_evk_sd1_data __initconst = {
+ .cd_gpio = EVK_SD1_CD,
+ .wp_gpio = EVK_SD1_WP,
+};
+
+static const struct esdhc_platform_data mx53_evk_sd3_data __initconst = {
+ .cd_gpio = EVK_SD3_CD,
+ .wp_gpio = EVK_SD3_WP,
+};
+
+static int __initdata enable_spdif = { 0 };
+static int __init spdif_setup(char *__unused)
+{
+ enable_spdif = 1;
+ return 1;
+}
+__setup("spdif", spdif_setup);
+
+static void __init mx53_evk_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53common_pads,
+ ARRAY_SIZE(mx53common_pads));
+
+ if (board_is_mx53_arm2()) {
+ /* MX53 ARM2 CPU board */
+ pr_info("MX53 ARM2 board \n");
+ mxc_iomux_v3_setup_multiple_pads(mx53arm2_pads,
+ ARRAY_SIZE(mx53arm2_pads));
+
+ /* Config GPIO for OTG VBus */
+ gpio_request(ARM2_OTG_VBUS, "otg-vbus");
+ gpio_direction_output(ARM2_OTG_VBUS, 1);
+
+ gpio_request(ARM2_SD1_CD, "sdhc1-cd");
+ gpio_direction_input(ARM2_SD1_CD); /* SD1 CD */
+
+ gpio_request(ARM2_LCD_CONTRAST, "lcd-contrast");
+ gpio_direction_output(ARM2_LCD_CONTRAST, 1);
+ } else {
+ /* MX53 EVK board */
+ pr_info("MX53 EVK board \n");
+ mxc_iomux_v3_setup_multiple_pads(mx53evk_pads,
+ ARRAY_SIZE(mx53evk_pads));
+
+ /* Host1 Vbus with GPIO high */
+ gpio_request(EVK_USBH1_VBUS, "usbh1-vbus");
+ gpio_direction_output(EVK_USBH1_VBUS, 1);
+ /* shutdown the Host1 Vbus when system bring up,
+ * Vbus will be opened in Host1 driver's probe function */
+ gpio_set_value(EVK_USBH1_VBUS, 0);
+
+ /* USB HUB RESET - De-assert USB HUB RESET_N */
+ gpio_request(EVK_USB_HUB_RESET, "usb-hub-reset");
+ gpio_direction_output(EVK_USB_HUB_RESET, 0);
+ msleep(1);
+ gpio_set_value(EVK_USB_HUB_RESET, 1);
+
+ /* Config GPIO for OTG VBus */
+ gpio_request(EVK_OTG_VBUS, "otg-vbus");
+ gpio_direction_output(EVK_OTG_VBUS, 0);
+ if (board_is_mx53_evk_a()) /*rev A,"1" disable, "0" enable vbus*/
+ gpio_set_value(EVK_OTG_VBUS, 1);
+ else if (board_is_mx53_evk_b()) /* rev B,"0" disable,"1" enable Vbus*/
+ gpio_set_value(EVK_OTG_VBUS, 0);
+
+ gpio_request(EVK_SD1_CD, "sdhc1-cd");
+ gpio_direction_input(EVK_SD1_CD); /* SD1 CD */
+ gpio_request(EVK_SD1_WP, "sdhc1-wp");
+ gpio_direction_input(EVK_SD1_WP); /* SD1 WP */
+
+ /* SD3 CD */
+ gpio_request(EVK_SD3_CD, "sdhc3-cd");
+ gpio_direction_input(EVK_SD3_CD);
+
+ /* SD3 WP */
+ gpio_request(EVK_SD3_WP, "sdhc3-wp");
+ gpio_direction_input(EVK_SD3_WP);
+
+ /* reset FEC PHY */
+ gpio_request(EVK_FEC_PHY_RST, "fec-phy-reset");
+ gpio_direction_output(EVK_FEC_PHY_RST, 0);
+ msleep(1);
+ gpio_set_value(EVK_FEC_PHY_RST, 1);
+
+ gpio_request(EVK_ESAI_RESET, "fesai-reset");
+ gpio_direction_output(EVK_ESAI_RESET, 0);
+ }
+
+ /* DISP0 Detect */
+ gpio_request(EVK_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(EVK_DISP0_DET_INT);
+ /* DISP0 Reset - Assert for i2c disabled mode */
+ gpio_request(EVK_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(EVK_DISP0_RESET, 0);
+
+ /* DISP0 Power-down */
+ gpio_request(EVK_DISP0_PD, "disp0-pd");
+ gpio_direction_output(EVK_DISP0_PD, 1);
+
+ /* DISP0 I2C enable */
+ gpio_request(EVK_DISP0_I2C_EN, "disp0-i2c");
+ gpio_direction_output(EVK_DISP0_I2C_EN, 0);
+
+ mxc_iomux_v3_setup_multiple_pads(mx53_nand_pads,
+ ARRAY_SIZE(mx53_nand_pads));
+
+ gpio_request(EVK_PMIC_INT, "pmic-int");
+ gpio_direction_input(EVK_PMIC_INT); /*PMIC_INT*/
+
+ /* headphone_det_b */
+ gpio_request(EVK_HP_DETECT, "hp-detect");
+ gpio_direction_input(EVK_HP_DETECT);
+
+ /* power key */
+
+ /* LCD related gpio */
+
+ /* Camera reset */
+ gpio_request(EVK_CAM_RESET, "cam-reset");
+ gpio_direction_output(EVK_CAM_RESET, 1);
+
+ /* TVIN reset */
+ gpio_request(EVK_TVIN_RESET, "tvin-reset");
+ gpio_direction_output(EVK_TVIN_RESET, 0);
+ msleep(5);
+ gpio_set_value(EVK_TVIN_RESET, 1);
+
+ /* TVin power down */
+ gpio_request(EVK_TVIN_PWR, "tvin-pwr");
+ gpio_direction_output(EVK_TVIN_PWR, 0);
+
+ /* CAN1 enable GPIO*/
+ gpio_request(EVK_CAN1_EN1, "can1-en1");
+ gpio_direction_output(EVK_CAN1_EN1, 0);
+
+ gpio_request(EVK_CAN1_EN2, "can1-en2");
+ gpio_direction_output(EVK_CAN1_EN2, 0);
+
+ /* CAN2 enable GPIO*/
+ gpio_request(EVK_CAN2_EN1, "can2-en1");
+ gpio_direction_output(EVK_CAN2_EN1, 0);
+
+ gpio_request(EVK_CAN2_EN2, "can2-en2");
+ gpio_direction_output(EVK_CAN2_EN2, 0);
+
+ if (enable_spdif) {
+ iomux_v3_cfg_t spdif_pin = MX53_PAD_GPIO_19__SPDIF_OUT1;
+ mxc_iomux_v3_setup_pad(spdif_pin);
+ } else {
+ /* GPIO for 12V */
+ gpio_request(EVK_12V_EN, "12v-en");
+ gpio_direction_output(EVK_12V_EN, 0);
+ }
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0, /* tx clk from CKIH1 for 44.1K */
+ .spdif_clk_48000 = 7, /* tx clk from CKIH2 for 48k and 32k */
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct mxc_regulator_platform_data evk_regulator_data = {
+ .cpu_reg_id = "SW1",
+ .vcc_reg_id = "SW2",
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init mx53_evk_board_init(void)
+{
+ int i;
+
+ mx53_evk_io_init();
+
+ gp_reg_id = evk_regulator_data.cpu_reg_id;
+ lp_reg_id = evk_regulator_data.vcc_reg_id;
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+
+ mx53_evk_init_uart();
+ imx53_add_srtc();
+ mx53_evk_fec_reset();
+ imx53_add_fec(&mx53_evk_fec_pdata);
+
+ imx53_add_ipuv3(0, &ipu_data);
+ for (i = 0; i < ARRAY_SIZE(evk_fb_data); i++)
+ imx53_add_ipuv3fb(i, &evk_fb_data[i]);
+ imx53_add_vpu();
+ imx53_add_tve(&tve_data);
+ imx53_add_v4l2_output(0);
+
+ if (!board_is_mx53_arm2()) {
+ imx53_add_mxc_pwm(1);
+ imx53_add_mxc_pwm_backlight(0, &evk_pwm_backlight_data);
+ }
+
+ imx53_add_dvfs_core(&evk_dvfs_core_data);
+ imx53_add_busfreq();
+ imx53_add_imx_i2c(0, &mx53_evk_i2c_data);
+ imx53_add_imx_i2c(1, &mx53_evk_i2c_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+
+ imx53_add_sdhci_esdhc_imx(0, &mx53_evk_sd1_data);
+ imx53_add_sdhci_esdhc_imx(2, &mx53_evk_sd3_data);
+ mxc_register_device(&imx_ahci_device_hwmon, NULL);
+
+ spi_register_board_info(mx53_evk_spi_board_info,
+ ARRAY_SIZE(mx53_evk_spi_board_info));
+ imx53_add_ecspi(0, &mx53_evk_spi_data);
+ imx53_add_imx2_wdt(0, NULL);
+
+ imx53_add_spdif(&mxc_spdif_data);
+ imx53_add_spdif_dai();
+ imx53_add_spdif_audio_device();
+
+ mx5_cpu_regulator_init();
+
+ /* this call required to release SCC RAM partition held by ROM
+ * during boot, even if SCC2 driver is not part of the image
+ */
+ imx53_add_mxc_scc2();
+}
+
+static void __init mx53_evk_timer_init(void)
+{
+ mx53_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx53_evk_timer = {
+ .init = mx53_evk_timer_init,
+};
+
+MACHINE_START(MX53_EVK, "Freescale MX53 EVK Board")
+ .fixup = fixup_mxc_board,
+ .map_io = mx53_map_io,
+ .init_early = imx53_init_early,
+ .init_irq = mx53_init_irq,
+ .timer = &mx53_evk_timer,
+ .init_machine = mx53_evk_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
new file mode 100755
index 00000000..257933af
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -0,0 +1,787 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/fec.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <linux/mxcfb.h>
+#include <linux/ipu.h>
+#include <linux/pwm_backlight.h>
+#include <linux/ahci_platform.h>
+#include <linux/gpio_keys.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx53.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/ahci_sata.h>
+#include <mach/mxc.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include "crm_regs.h"
+#include "devices-imx53.h"
+#include "devices.h"
+#include "usb.h"
+
+#define MX53_LOCO_POWER IMX_GPIO_NR(1, 8)
+#define LOCO_HEADPHONE_DET IMX_GPIO_NR(2, 5)
+#define MX53_LOCO_UI1 IMX_GPIO_NR(2, 14)
+#define MX53_LOCO_UI2 IMX_GPIO_NR(2, 15)
+#define MX53_LOCO_SD3_CD IMX_GPIO_NR(3, 11)
+#define MX53_LOCO_SD3_WP IMX_GPIO_NR(3, 12)
+#define MX53_LOCO_SD1_CD IMX_GPIO_NR(3, 13)
+#define LOCO_DISP0_PWR IMX_GPIO_NR(3, 24)
+#define LOCO_DISP0_DET_INT IMX_GPIO_NR(3, 31)
+#define LOCO_DISP0_RESET IMX_GPIO_NR(5, 0)
+#define LOCO_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+#define LOCO_USBH1_VBUS IMX_GPIO_NR(7, 8)
+
+#define MX53_LOCO_MC34708_IRQ_REVA IMX_GPIO_NR(5, 30)
+#define MX53_LOCO_MC34708_IRQ_REVB IMX_GPIO_NR(5, 23)
+
+static struct clk *sata_clk, *sata_ref_clk;
+static u32 mx53_loco_mc34708_irq;
+
+extern void __iomem *arm_plat_base;
+extern void __iomem *gpc_base;
+extern void __iomem *ccm_base;
+extern void __iomem *imx_otg_base;
+extern char *lp_reg_id;
+extern char *gp_reg_id;
+extern void mx5_cpu_regulator_init(void);
+extern int __init mx53_loco_init_da9052(void);
+extern int __init mx53_loco_init_mc34708(u32 int_gpio);
+
+static iomux_v3_cfg_t mx53_loco_pads[] = {
+ /* FEC */
+ MX53_PAD_FEC_MDC__FEC_MDC,
+ MX53_PAD_FEC_MDIO__FEC_MDIO,
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+ /* FEC_nRST */
+ MX53_PAD_PATA_DA_0__GPIO7_6,
+ /* FEC_nINT */
+ MX53_PAD_PATA_DATA4__GPIO2_4,
+ /* AUDMUX5 */
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
+ /* I2C2 */
+ MX53_PAD_KEY_COL3__I2C2_SCL,
+ MX53_PAD_KEY_ROW3__I2C2_SDA,
+ /* SD1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* SD1_CD */
+ MX53_PAD_EIM_DA13__GPIO3_13,
+ /* SD3 */
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
+ /* SD3_CD */
+ MX53_PAD_EIM_DA11__GPIO3_11,
+ /* SD3_WP */
+ MX53_PAD_EIM_DA12__GPIO3_12,
+ /* VGA */
+ MX53_PAD_EIM_OE__IPU_DI1_PIN7,
+ MX53_PAD_EIM_RW__IPU_DI1_PIN8,
+ /* DISPLB */
+ MX53_PAD_EIM_D20__IPU_SER_DISP0_CS,
+ MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK,
+ MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN,
+ MX53_PAD_EIM_D23__IPU_DI0_D0_CS,
+ /* DISP0_POWER_EN */
+ MX53_PAD_EIM_D24__GPIO3_24,
+ /* DISP0 DET INT */
+ MX53_PAD_EIM_D31__GPIO3_31,
+ /* LVDS */
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+ /* I2C1 */
+ MX53_PAD_CSI0_DAT8__I2C1_SDA,
+ MX53_PAD_CSI0_DAT9__I2C1_SCL,
+ /* UART1 */
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX,
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX,
+ /* CSI0 */
+ MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12,
+ MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13,
+ MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14,
+ MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15,
+ MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16,
+ MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17,
+ MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18,
+ MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19,
+ MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC,
+ MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC,
+ MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK,
+ /* DISPLAY */
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
+ /* Audio CLK*/
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK,
+ /* PWM */
+ MX53_PAD_GPIO_1__PWM2_PWMO,
+ /* SPDIF */
+ MX53_PAD_GPIO_7__SPDIF_PLOCK,
+ MX53_PAD_GPIO_17__SPDIF_OUT1,
+ /* GPIO */
+ MX53_PAD_PATA_DA_1__GPIO7_7,
+ MX53_PAD_PATA_DA_2__GPIO7_8,
+ MX53_PAD_PATA_DATA5__GPIO2_5,
+ MX53_PAD_PATA_DATA6__GPIO2_6,
+ MX53_PAD_PATA_DATA14__GPIO2_14,
+ MX53_PAD_PATA_DATA15__GPIO2_15,
+ MX53_PAD_PATA_INTRQ__GPIO7_2,
+ MX53_PAD_EIM_WAIT__GPIO5_0,
+ MX53_PAD_NANDF_WP_B__GPIO6_9,
+ MX53_PAD_NANDF_RB0__GPIO6_10,
+ MX53_PAD_NANDF_CS1__GPIO6_14,
+ MX53_PAD_NANDF_CS2__GPIO6_15,
+ MX53_PAD_NANDF_CS3__GPIO6_16,
+ MX53_PAD_GPIO_5__GPIO1_5,
+ MX53_PAD_GPIO_16__GPIO7_11,
+ MX53_PAD_GPIO_8__GPIO1_8,
+};
+
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+}
+
+static const struct gpio_keys_button loco_buttons[] __initconst = {
+ GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 1),
+ GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
+ GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static const struct gpio_keys_platform_data loco_button_data __initconst = {
+ .buttons = (struct gpio_keys_button *)loco_buttons,
+ .nbuttons = ARRAY_SIZE(loco_buttons),
+};
+
+static inline void mx53_loco_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request(LOCO_FEC_PHY_RST, "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(LOCO_FEC_PHY_RST, 0);
+ msleep(1);
+ gpio_set_value(LOCO_FEC_PHY_RST, 1);
+}
+
+static struct fec_platform_data mx53_loco_fec_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ .type = "mma8450",
+ .addr = 0x1C,
+ },
+};
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(LOCO_DISP0_RESET, 0);
+ msleep(10);
+ gpio_set_value(LOCO_DISP0_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .reset = sii902x_hdmi_reset,
+};
+
+static void loco_suspend_enter(void)
+{
+ /* da9053 suspend preparation */
+}
+
+static void loco_suspend_exit(void)
+{
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+ /* da9053 resmue resore */
+}
+
+static struct mxc_pm_platform_data loco_pm_data = {
+ .suspend_enter = loco_suspend_enter,
+ .suspend_exit = loco_suspend_exit,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "sgtl5000",
+ .addr = 0x0a,
+ },
+ {
+ .type = "sii902x",
+ .addr = 0x39,
+ .irq = gpio_to_irq(LOCO_DISP0_DET_INT),
+ .platform_data = &sii902x_hdmi_data,
+ },
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct ipuv3_fb_platform_data loco_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "vga",
+ .interface_pix_fmt = IPU_PIX_FMT_GBR24,
+ .mode_str = "VGA-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+ .rev = 3,
+};
+
+static struct platform_pwm_backlight_data loco_pwm_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct fsl_mxc_tve_platform_data tve_data = {
+ .dac_reg = "DA9052_LDO7",
+};
+
+static struct mxc_dvfs_platform_data loco_dvfs_core_data = {
+ .reg_id = "cpu_vddgp",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .gpc_vcr_offset = MXC_GPC_VCR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 30,
+};
+
+static const struct esdhc_platform_data mx53_loco_sd1_data __initconst = {
+ .cd_gpio = MX53_LOCO_SD1_CD,
+};
+
+static const struct esdhc_platform_data mx53_loco_sd3_data __initconst = {
+ .cd_gpio = MX53_LOCO_SD3_CD,
+ .wp_gpio = MX53_LOCO_SD3_WP,
+};
+
+static void mx53_loco_usbh1_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(LOCO_USBH1_VBUS, 1);
+ else
+ gpio_set_value(LOCO_USBH1_VBUS, 0);
+}
+
+static void __init mx53_loco_io_init(void)
+{
+ int ret;
+
+ arm_plat_base = MX53_IO_ADDRESS(MX53_ARM_BASE_ADDR);
+ gpc_base = MX53_IO_ADDRESS(MX53_GPC_BASE_ADDR);
+ ccm_base = MX53_IO_ADDRESS(MX53_CCM_BASE_ADDR);
+ imx_otg_base = MX53_IO_ADDRESS(MX53_OTG_BASE_ADDR);
+
+ mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
+ ARRAY_SIZE(mx53_loco_pads));
+
+ /* Sii902x HDMI controller */
+ ret = gpio_request(LOCO_DISP0_RESET, "disp0-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_LOCO_DISP0_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(LOCO_DISP0_RESET, 0);
+
+ ret = gpio_request(LOCO_DISP0_DET_INT, "disp0-detect");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_LOCO_DISP0_DET_INT: %d\n", ret);
+ return;
+ }
+ gpio_direction_input(LOCO_DISP0_DET_INT);
+
+ /* enable disp0 power */
+ ret = gpio_request(LOCO_DISP0_PWR, "disp0-power-en");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_LOCO_DISP0_PWR: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(LOCO_DISP0_PWR, 1);
+
+ /* usb host1 vbus */
+ ret = gpio_request(LOCO_USBH1_VBUS, "usbh1-vbus");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO LOCO_USBH1_VBUS: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(LOCO_USBH1_VBUS, 0);
+}
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx53_loco_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ sata_ref_clk = clk_get(NULL, "usb_phy1_clk");
+ if (IS_ERR(sata_ref_clk)) {
+ dev_err(dev, "no sata ref clock.\n");
+ ret = PTR_ERR(sata_ref_clk);
+ goto release_sata_clk;
+ }
+ ret = clk_enable(sata_ref_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata ref clock.\n");
+ goto put_sata_ref_clk;
+ }
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb_clk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_ref_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+
+release_sata_ref_clk:
+ clk_disable(sata_ref_clk);
+put_sata_ref_clk:
+ clk_put(sata_ref_clk);
+release_sata_clk:
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+static void mx53_loco_sata_exit(struct device *dev)
+{
+ clk_disable(sata_ref_clk);
+ clk_put(sata_ref_clk);
+
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+}
+
+static struct ahci_platform_data mx53_loco_sata_data = {
+ .init = mx53_loco_sata_init,
+ .exit = mx53_loco_sata_exit,
+};
+
+static struct mxc_audio_platform_data loco_audio_data;
+
+static int loco_sgtl5000_init(void)
+{
+ struct clk *ssi_ext1;
+ int rate;
+
+ ssi_ext1 = clk_get(NULL, "ssi_ext1_clk");
+ if (IS_ERR(ssi_ext1)) {
+ return -1;
+ }
+ rate = clk_round_rate(ssi_ext1, 24000000);
+ if (rate < 8000000 || rate > 27000000) {
+ printk(KERN_ERR "Error: SGTL5000 mclk freq %d out of range!\n",
+ rate);
+ clk_put(ssi_ext1);
+ return -1;
+ }
+
+ loco_audio_data.sysclk = rate;
+ clk_set_rate(ssi_ext1, rate);
+ clk_enable(ssi_ext1);
+
+ return 0;
+}
+
+static struct imx_ssi_platform_data loco_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data loco_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 5,
+ .init = loco_sgtl5000_init,
+ .hp_gpio = LOCO_HEADPHONE_DET,
+ .hp_active_low = 1,
+};
+
+static struct platform_device loco_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+static void mxc_iim_enable_fuse(void)
+{
+ u32 reg;
+ if (!ccm_base)
+ return;
+ /* enable fuse blown */
+ reg = readl(ccm_base + 0x64);
+ reg |= 0x10;
+ writel(reg, ccm_base + 0x64);
+}
+
+static void mxc_iim_disable_fuse(void)
+{
+ u32 reg;
+ if (!ccm_base)
+ return;
+ /* enable fuse blown */
+ reg = readl(ccm_base + 0x64);
+ reg &= ~0x10;
+ writel(reg, ccm_base + 0x64);
+}
+
+static struct mxc_iim_platform_data iim_data = {
+ .bank_start = MXC_IIM_MX53_BANK_START_ADDR,
+ .bank_end = MXC_IIM_MX53_BANK_END_ADDR,
+ .enable_fuse = mxc_iim_enable_fuse,
+ .disable_fuse = mxc_iim_disable_fuse,
+};
+
+static struct mxc_gpu_platform_data gpu_data __initdata;
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SIN0,
+};
+
+static struct mxc_regulator_platform_data loco_regulator_data = {
+ .cpu_reg_id = "cpu_vddgp",
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ struct tag *t;
+ struct tag *mem_tag = 0;
+ int total_mem = SZ_1G;
+ int left_mem = 0;
+ int gpu_mem = SZ_128M;
+ int fb_mem = SZ_32M;
+ char *str;
+
+ for_each_tag(mem_tag, tags) {
+ if (mem_tag->hdr.tag == ATAG_MEM) {
+ total_mem = mem_tag->u.mem.size;
+ left_mem = total_mem - gpu_mem - fb_mem;
+ break;
+ }
+ }
+
+ for_each_tag(t, tags) {
+ if (t->hdr.tag == ATAG_CMDLINE) {
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "mem=");
+ if (str != NULL) {
+ str += 4;
+ left_mem = memparse(str, &str);
+ if (left_mem == 0 || left_mem > total_mem)
+ left_mem = total_mem - gpu_mem - fb_mem;
+ }
+
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "gpu_memory=");
+ if (str != NULL) {
+ str += 11;
+ gpu_mem = memparse(str, &str);
+ }
+
+ break;
+ }
+ }
+
+ if (mem_tag) {
+ fb_mem = total_mem - left_mem - gpu_mem;
+ if (fb_mem < 0) {
+ gpu_mem = total_mem - left_mem;
+ fb_mem = 0;
+ }
+ mem_tag->u.mem.size = left_mem;
+
+ /* reserve memory for gpu */
+ gpu_data.reserved_mem_base =
+ mem_tag->u.mem.start + left_mem;
+ gpu_data.reserved_mem_size = gpu_mem;
+
+ /* reserver memory for fb */
+ loco_fb_data[0].res_base[0] = gpu_data.reserved_mem_base
+ + gpu_data.reserved_mem_size;
+ loco_fb_data[0].res_size[0] = fb_mem;
+ }
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = -1, /* No source for 44.1K */
+ /* Source from CCM spdif_clk (24M) for 48k and 32k
+ * It's not accurate: for 48Khz it is actually 46875Hz (2.3% off)
+ */
+ .spdif_clk_48000 = 1,
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static void __init mx53_loco_board_init(void)
+{
+ int i, ret;
+ iomux_v3_cfg_t mc34708_int = MX53_PAD_CSI0_DAT12__GPIO5_30;
+
+ mx53_loco_io_init();
+ gp_reg_id = loco_regulator_data.cpu_reg_id;
+ lp_reg_id = loco_regulator_data.vcc_reg_id;
+
+ imx53_add_imx_uart(0, NULL);
+ mx53_loco_fec_reset();
+ imx53_add_fec(&mx53_loco_fec_data);
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+
+ mxc_register_device(&mxc_pm_device, &loco_pm_data);
+
+ imx53_add_ipuv3(0, &ipu_data);
+
+ for (i = 0; i < ARRAY_SIZE(loco_fb_data); i++)
+ imx53_add_ipuv3fb(i, &loco_fb_data[i]);
+
+ imx53_add_vpu();
+ imx53_add_lcdif(&lcdif_data);
+ imx53_add_ldb(&ldb_data);
+ imx53_add_tve(&tve_data);
+ imx53_add_v4l2_output(0);
+
+ imx53_add_mxc_pwm(1);
+ imx53_add_mxc_pwm_backlight(0, &loco_pwm_backlight_data);
+
+ imx53_add_imx2_wdt(0, NULL);
+ imx53_add_srtc();
+ imx53_add_imx_i2c(0, &mx53_loco_i2c_data);
+ imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
+ if (board_is_mx53_loco_mc34708()) {
+ if (board_is_rev(IMX_BOARD_REV_2)) {/*Board RevA*/
+ mc34708_int = MX53_PAD_CSI0_DAT12__GPIO5_30;
+ mx53_loco_mc34708_irq = MX53_LOCO_MC34708_IRQ_REVA;
+ } else if (board_is_rev(IMX_BOARD_REV_4)) {/*Board RevB*/
+ mc34708_int = MX53_PAD_CSI0_DAT5__GPIO5_23;
+ mx53_loco_mc34708_irq = MX53_LOCO_MC34708_IRQ_REVB;
+ }
+ mxc_iomux_v3_setup_pad(mc34708_int);
+ ret = gpio_request(mx53_loco_mc34708_irq, "mc34708-int");
+ if (ret) {
+ printk(KERN_ERR"request mc34708-int error!!\n");
+ return;
+ } else {
+ gpio_direction_input(mx53_loco_mc34708_irq);
+ mx53_loco_init_mc34708(mx53_loco_mc34708_irq);
+ }
+
+ } else {
+ mx53_loco_init_da9052();
+ }
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+
+ imx53_add_sdhci_esdhc_imx(0, &mx53_loco_sd1_data);
+ imx53_add_sdhci_esdhc_imx(2, &mx53_loco_sd3_data);
+ imx53_add_ahci(0, &mx53_loco_sata_data);
+ mxc_register_device(&imx_ahci_device_hwmon, NULL);
+ imx53_add_iim(&iim_data);
+
+ /* USB */
+ mx5_usb_dr_init();
+ mx5_set_host1_vbus_func(mx53_loco_usbh1_vbus);
+ mx5_usbh1_init();
+
+ mxc_register_device(&loco_audio_device, &loco_audio_data);
+ imx53_add_imx_ssi(1, &loco_ssi_pdata);
+
+ imx53_add_spdif(&mxc_spdif_data);
+ imx53_add_spdif_dai();
+ imx53_add_spdif_audio_device();
+
+ /*GPU*/
+ if (mx53_revision() >= IMX_CHIP_REVISION_2_0)
+ gpu_data.z160_revision = 1;
+ else
+ gpu_data.z160_revision = 0;
+ imx53_add_mxc_gpu(&gpu_data);
+ imx_add_gpio_keys(&loco_button_data);
+
+ /* this call required to release SCC RAM partition held by ROM
+ * during boot, even if SCC2 driver is not part of the image
+ */
+ imx53_add_mxc_scc2();
+ imx53_add_dvfs_core(&loco_dvfs_core_data);
+ imx53_add_busfreq();
+ mx5_cpu_regulator_init();
+}
+
+static void __init mx53_loco_timer_init(void)
+{
+ mx53_clocks_init(32768, 24000000, 0, 0);
+}
+
+static struct sys_timer mx53_loco_timer = {
+ .init = mx53_loco_timer_init,
+};
+
+MACHINE_START(MX53_LOCO, "Freescale MX53 LOCO Board")
+ .fixup = fixup_mxc_board,
+ .map_io = mx53_map_io,
+ .init_early = imx53_init_early,
+ .init_irq = mx53_init_irq,
+ .timer = &mx53_loco_timer,
+ .init_machine = mx53_loco_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c
new file mode 100755
index 00000000..50fec073
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx53_smd.c
@@ -0,0 +1,855 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/fec.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c/mpr.h>
+#include <linux/fsl_devices.h>
+#include <linux/ahci_platform.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/pwm_backlight.h>
+#include <linux/mxcfb.h>
+#include <linux/ipu.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/ipu-v3.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx53.h>
+#include <mach/ahci_sata.h>
+#include <mach/imx_rfkill.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "crm_regs.h"
+#include "devices-imx53.h"
+#include "devices.h"
+#include "usb.h"
+
+
+#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+#define MX53_SMD_SD1_CD IMX_GPIO_NR(3, 13)
+#define MX53_SMD_SD1_WP IMX_GPIO_NR(4, 11)
+#define MX53_SMD_HDMI_RESET_B IMX_GPIO_NR(5, 0)
+#define MX53_SMD_MODEM_RESET_B IMX_GPIO_NR(5, 2)
+#define MX53_SMD_KEY_INT IMX_GPIO_NR(5, 4)
+#define MX53_SMD_HDMI_INT IMX_GPIO_NR(6, 12)
+#define MX53_SMD_CAP_TCH_INT1 IMX_GPIO_NR(3, 20)
+#define MX53_SMD_SATA_PWR_EN IMX_GPIO_NR(3, 3)
+#define MX53_SMD_OTG_VBUS IMX_GPIO_NR(7, 8)
+#define MX53_SMD_NONKEY IMX_GPIO_NR(1, 8)
+#define MX53_SMD_UI1 IMX_GPIO_NR(2, 14)
+#define MX53_SMD_UI2 IMX_GPIO_NR(2, 15)
+#define MX53_SMD_HEADPHONE_DEC IMX_GPIO_NR(2, 5)
+#define MX53_SMD_OSC_CKIH1_EN IMX_GPIO_NR(6, 11)
+#define MX53_SMD_DCDC1V8_EN IMX_GPIO_NR(3, 1)
+#define MX53_SMD_DCDC5V_BB_EN IMX_GPIO_NR(4, 14)
+#define MX53_SMD_ALS_INT IMX_GPIO_NR(3, 22)
+#define MX53_SMD_BT_RESET IMX_GPIO_NR(3, 28)
+#define MX53_SMD_CSI0_RST IMX_GPIO_NR(6, 9)
+#define MX53_SMD_CSI0_PWN IMX_GPIO_NR(6, 10)
+#define MX53_SMD_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define MX53_SMD_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+
+static struct clk *sata_clk, *sata_ref_clk;
+
+extern char *lp_reg_id;
+extern char *gp_reg_id;
+extern void mx5_cpu_regulator_init(void);
+extern int mx53_smd_init_da9052(void);
+extern void mx5_cpu_regulator_init(void);
+
+static iomux_v3_cfg_t mx53_smd_pads[] = {
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX,
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX,
+
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+ MX53_PAD_PATA_DA_1__UART3_CTS,
+ MX53_PAD_PATA_DA_2__UART3_RTS,
+ /* I2C1 */
+ MX53_PAD_CSI0_DAT8__I2C1_SDA,
+ MX53_PAD_CSI0_DAT9__I2C1_SCL,
+ /* I2C2 */
+ MX53_PAD_KEY_COL3__I2C2_SCL,
+ MX53_PAD_KEY_ROW3__I2C2_SDA,
+ /* I2C3 */
+ MX53_PAD_GPIO_3__I2C3_SCL,
+ MX53_PAD_GPIO_6__I2C3_SDA,
+
+ /* CSPI1 */
+ MX53_PAD_EIM_EB2__ECSPI1_SS0,
+ MX53_PAD_EIM_D16__ECSPI1_SCLK,
+ MX53_PAD_EIM_D17__ECSPI1_MISO,
+ MX53_PAD_EIM_D18__ECSPI1_MOSI,
+ MX53_PAD_EIM_D19__ECSPI1_SS1,
+ MX53_PAD_EIM_EB2__GPIO2_30,
+ MX53_PAD_EIM_D19__GPIO3_19,
+
+ /* SD1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* SD1_CD */
+ MX53_PAD_EIM_DA13__GPIO3_13,
+ /* SD1_WP */
+ MX53_PAD_KEY_ROW2__GPIO4_11,
+
+ /* SD2 */
+ MX53_PAD_SD2_CMD__ESDHC2_CMD,
+ MX53_PAD_SD2_CLK__ESDHC2_CLK,
+ MX53_PAD_SD2_DATA0__ESDHC2_DAT0,
+ MX53_PAD_SD2_DATA1__ESDHC2_DAT1,
+ MX53_PAD_SD2_DATA2__ESDHC2_DAT2,
+ MX53_PAD_SD2_DATA3__ESDHC2_DAT3,
+
+ /* SD3 */
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
+
+ /* SATA_PWR_EN */
+ MX53_PAD_EIM_DA3__GPIO3_3,
+
+ /* USB_OTG_OC */
+ MX53_PAD_EIM_DA12__GPIO3_12,
+ /* USB_HUB_RESET_B */
+ MX53_PAD_EIM_DA14__GPIO3_14,
+ /* USB_OTG_PWR_EN */
+ MX53_PAD_PATA_DA_2__GPIO7_8,
+
+ /* OSC_CKIH1_EN, for audio codec clk */
+ MX53_PAD_NANDF_CS0__GPIO6_11,
+
+ /* AUDMUX3 */
+ MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+
+ /* AUDMUX5 */
+ MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC,
+ MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD,
+ MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS,
+ MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD,
+
+ /* AUD_AMP_STBY_B */
+ MX53_PAD_EIM_DA2__GPIO3_2,
+
+ /* DCDC1V8_EN */
+ MX53_PAD_EIM_DA1__GPIO3_1,
+ /* DCDC5V_BB_EN */
+ MX53_PAD_KEY_COL4__GPIO4_14,
+ /*SSI_EXT1_CLK*/
+ MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK,
+ /* PWM */
+ MX53_PAD_GPIO_1__PWM2_PWMO,
+ /* CSI0 */
+ MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12,
+ MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13,
+ MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14,
+ MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15,
+ MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16,
+ MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17,
+ MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18,
+ MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19,
+ MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC,
+ MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC,
+ MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK,
+ /* DISPLAY */
+ MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
+ MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
+ MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
+ MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
+ MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
+ MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
+ MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
+ MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
+ MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
+ MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
+ MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
+ MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
+ MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
+ MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
+ MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
+ MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
+ MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
+ MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
+ MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
+ MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
+ MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
+ MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
+ MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
+ MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
+ MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
+ MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
+ MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
+ MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
+ /* LDVS */
+ MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+ MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+ MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+ MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+ MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+ MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+ MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+ MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+ MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+ MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+
+ MX53_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+}
+
+static struct gpio_keys_button smd_buttons[] = {
+ GPIO_BUTTON(MX53_SMD_NONKEY, KEY_POWER, 1, "power", 0),
+ GPIO_BUTTON(MX53_SMD_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
+ GPIO_BUTTON(MX53_SMD_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static struct gpio_keys_platform_data smd_button_data = {
+ .buttons = smd_buttons,
+ .nbuttons = ARRAY_SIZE(smd_buttons),
+};
+
+static struct platform_device smd_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &smd_button_data,
+ }
+};
+
+static void __init smd_add_device_buttons(void)
+{
+ platform_device_register(&smd_button_device);
+}
+#else
+static void __init smd_add_device_buttons(void) {}
+#endif
+
+static const struct imxuart_platform_data mx53_smd_uart_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mx53_smd_init_uart(void)
+{
+ imx53_add_imx_uart(0, NULL);
+ imx53_add_imx_uart(1, NULL);
+ imx53_add_imx_uart(2, &mx53_smd_uart_data);
+}
+
+static inline void mx53_smd_fec_reset(void)
+{
+ int ret;
+
+ /* reset FEC PHY */
+ ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(SMD_FEC_PHY_RST, 0);
+ msleep(1);
+ gpio_set_value(SMD_FEC_PHY_RST, 1);
+}
+
+static struct fec_platform_data mx53_smd_fec_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = {
+ .bitrate = 100000,
+};
+
+static void smd_suspend_enter(void)
+{
+ /* da9053 suspend preparation */
+}
+
+static void smd_suspend_exit(void)
+{
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+ /* da9053 resmue resore */
+}
+
+static struct mxc_pm_platform_data smd_pm_data = {
+ .suspend_enter = smd_suspend_enter,
+ .suspend_exit = smd_suspend_exit,
+};
+
+
+static const struct esdhc_platform_data mx53_smd_sd1_data __initconst = {
+ .cd_gpio = MX53_SMD_SD1_CD,
+ .wp_gpio = MX53_SMD_SD1_WP,
+};
+
+static const struct esdhc_platform_data mx53_smd_sd2_data __initconst = {
+ .always_present = 1,
+};
+
+static const struct esdhc_platform_data mx53_smd_sd3_data __initconst = {
+ .always_present = 1,
+};
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .analog_regulator = "DA9052_LDO7",
+ .core_regulator = "DA9052_LDO9",
+ .mclk = 24000000,
+ .csi = 0,
+};
+
+static struct fsl_mxc_lightsensor_platform_data ls_data = {
+ .rext = 700, /* calibration: 499K->700K */
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ .type = "mma8451",
+ .addr = 0x1C,
+ },
+ {
+ .type = "ov3640",
+ .addr = 0x3C,
+ .platform_data = (void *)&camera_data,
+ },
+
+};
+
+static u16 smd_touchkey_martix[4] = {
+ KEY_BACK, KEY_HOME, KEY_MENU, KEY_SEARCH,
+};
+
+static struct mpr121_platform_data mpr121_keyboard_platdata = {
+ .keycount = ARRAY_SIZE(smd_touchkey_martix),
+ .vdd_uv = 3300000,
+ .matrix = smd_touchkey_martix,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "sgtl5000",
+ .addr = 0x0a,
+ },
+ {
+ .type = "mpr121_touchkey",
+ .addr = 0x5a,
+ .irq = gpio_to_irq(MX53_SMD_KEY_INT),
+ .platform_data = &mpr121_keyboard_platdata,
+ },
+};
+
+static int mx53_smd_spi_cs[] = {
+ MX53_SMD_ECSPI1_CS0,
+ MX53_SMD_ECSPI1_CS1,
+};
+
+static struct spi_imx_master mx53_smd_spi_data = {
+ .chipselect = mx53_smd_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx53_smd_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00040000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+#endif
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &m25p32_spi_flash_data,
+ }
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+}
+
+static void mxc_iim_enable_fuse(void)
+{
+ u32 reg;
+ if (!ccm_base)
+ return;
+ /* enable fuse blown */
+ reg = readl(ccm_base + 0x64);
+ reg |= 0x10;
+ writel(reg, ccm_base + 0x64);
+}
+
+static void mxc_iim_disable_fuse(void)
+{
+ u32 reg;
+ if (!ccm_base)
+ return;
+ /* enable fuse blown */
+ reg = readl(ccm_base + 0x64);
+ reg &= ~0x10;
+ writel(reg, ccm_base + 0x64);
+}
+
+
+static struct mxc_iim_platform_data iim_data = {
+ .bank_start = MXC_IIM_MX53_BANK_START_ADDR,
+ .bank_end = MXC_IIM_MX53_BANK_END_ADDR,
+ .enable_fuse = mxc_iim_enable_fuse,
+ .disable_fuse = mxc_iim_disable_fuse,
+};
+
+
+static void sii9022_hdmi_reset(void)
+{
+ gpio_set_value(MX53_SMD_HDMI_RESET_B, 0);
+ msleep(10);
+ gpio_set_value(MX53_SMD_HDMI_RESET_B, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .reset = sii9022_hdmi_reset,
+ .analog_reg = "DA9052_LDO2",
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ .type = "sii902x",
+ .addr = 0x39,
+ .irq = gpio_to_irq(MX53_SMD_HDMI_INT),
+ .platform_data = &sii902x_hdmi_data,
+ },
+ {
+ I2C_BOARD_INFO("p1003_ts", 0x41),
+ .irq = gpio_to_irq(MX53_SMD_CAP_TCH_INT1),
+ },
+ {
+ .type = "isl29023",
+ .addr = 0x44,
+ .irq = gpio_to_irq(MX53_SMD_ALS_INT),
+ .platform_data = &ls_data,
+ },
+
+};
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx53_smd_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ /* Enable SATA PWR */
+ ret = gpio_request(MX53_SMD_SATA_PWR_EN, "ahci-sata-pwr");
+ if (ret) {
+ printk(KERN_ERR "failed to get SATA_PWR_EN: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(MX53_SMD_SATA_PWR_EN, 1);
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ sata_ref_clk = clk_get(NULL, "usb_phy1_clk");
+ if (IS_ERR(sata_ref_clk)) {
+ dev_err(dev, "no sata ref clock.\n");
+ ret = PTR_ERR(sata_ref_clk);
+ goto release_sata_clk;
+ }
+ ret = clk_enable(sata_ref_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata ref clock.\n");
+ goto put_sata_ref_clk;
+ }
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb_clk");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_ref_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+
+release_sata_ref_clk:
+ clk_disable(sata_ref_clk);
+put_sata_ref_clk:
+ clk_put(sata_ref_clk);
+release_sata_clk:
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+static void mx53_smd_sata_exit(struct device *dev)
+{
+ clk_disable(sata_ref_clk);
+ clk_put(sata_ref_clk);
+
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+}
+
+static struct ahci_platform_data mx53_smd_sata_data = {
+ .init = mx53_smd_sata_init,
+ .exit = mx53_smd_sata_exit,
+};
+
+static void mx53_smd_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX53_SMD_OTG_VBUS, 1);
+ else
+ gpio_set_value(MX53_SMD_OTG_VBUS, 0);
+}
+
+static void __init mx53_smd_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX53_IO_ADDRESS(MX53_OTG_BASE_ADDR);
+ ret = gpio_request(MX53_SMD_OTG_VBUS, "usb-pwr");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO SMD_OTG_VBUS: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX53_SMD_OTG_VBUS, 0);
+
+ mx5_set_otghost_vbus_func(mx53_smd_usbotg_vbus);
+ mx5_usb_dr_init();
+ mx5_usbh1_init();
+}
+
+static void mx53_smd_bt_reset(void)
+{
+ gpio_request(MX53_SMD_BT_RESET, "bt-reset");
+ gpio_direction_output(MX53_SMD_BT_RESET, 0);
+ /* pull down reset pin at least >5ms */
+ mdelay(6);
+ /* pull up after power supply BT */
+ gpio_set_value(MX53_SMD_BT_RESET, 1);
+ gpio_free(MX53_SMD_BT_RESET);
+ msleep(100);
+ /* Bluetooth need some time to reset */
+}
+
+static int mx53_smd_bt_power_change(int status)
+{
+ struct regulator *wifi_bt_pwren;
+
+ wifi_bt_pwren = regulator_get(NULL, "wifi_bt");
+ if (IS_ERR(wifi_bt_pwren)) {
+ printk(KERN_ERR "%s: regulator_get error\n", __func__);
+ return -1;
+ }
+
+ if (status) {
+ regulator_enable(wifi_bt_pwren);
+ mx53_smd_bt_reset();
+ } else
+ regulator_disable(wifi_bt_pwren);
+
+ return 0;
+}
+
+static struct platform_device imx_bt_rfkill = {
+ .name = "imx_bt_rfkill",
+};
+
+static struct imx_bt_rfkill_platform_data imx_bt_rfkill_data = {
+ .power_change = mx53_smd_bt_power_change,
+};
+
+static struct mxc_audio_platform_data smd_audio_data;
+
+static int smd_sgtl5000_init(void)
+{
+ smd_audio_data.sysclk = 22579200;
+
+ /* Enable OSC_CKIH1_EN for audio */
+ gpio_request(MX53_SMD_OSC_CKIH1_EN, "osc-en");
+ gpio_direction_output(MX53_SMD_OSC_CKIH1_EN, 1);
+ return 0;
+}
+
+static struct mxc_audio_platform_data smd_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 5,
+ .init = smd_sgtl5000_init,
+ .hp_gpio = MX53_SMD_HEADPHONE_DEC,
+ .hp_active_low = 1,
+};
+
+static struct platform_device smd_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+static struct imx_ssi_platform_data smd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct ipuv3_fb_platform_data smd_fb_data[] = {
+ {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "hdmi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "1024x768M-16@60",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data = {
+ .rev = 3,
+ .csi_clk[0] = "ssi_ext1_clk",
+};
+
+static struct platform_pwm_backlight_data mxc_pwm_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 0,
+ .disp_id = 1,
+ .ext_ref = 1,
+ .mode = LDB_SIN1,
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0, /* Souce from CKIH1 for 44.1K */
+ /* Source from CCM spdif_clk (24M) for 48k and 32k
+ * It's not accurate
+ */
+ .spdif_clk_48000 = 1,
+ .spdif_div_44100 = 8,
+ .spdif_div_48000 = 8,
+ .spdif_div_32000 = 12,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct mxc_regulator_platform_data smd_regulator_data = {
+ .cpu_reg_id = "DA9052_BUCK_CORE",
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init mx53_smd_board_init(void)
+{
+ int i;
+
+ mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
+ ARRAY_SIZE(mx53_smd_pads));
+
+ gp_reg_id = smd_regulator_data.cpu_reg_id;
+ lp_reg_id = smd_regulator_data.vcc_reg_id;
+
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+
+ mx53_smd_init_uart();
+ mx53_smd_fec_reset();
+ mxc_register_device(&mxc_pm_device, &smd_pm_data);
+ imx53_add_fec(&mx53_smd_fec_data);
+ imx53_add_imx2_wdt(0, NULL);
+ imx53_add_srtc();
+ imx53_add_imx_i2c(0, &mx53_smd_i2c_data);
+ imx53_add_imx_i2c(1, &mx53_smd_i2c_data);
+ imx53_add_imx_i2c(2, &mx53_smd_i2c_data);
+ imx53_add_ecspi(0, &mx53_smd_spi_data);
+
+ imx53_add_ipuv3(0, &ipu_data);
+ for (i = 0; i < ARRAY_SIZE(smd_fb_data); i++)
+ imx53_add_ipuv3fb(i, &smd_fb_data[i]);
+ imx53_add_lcdif(&lcdif_data);
+ imx53_add_vpu();
+ imx53_add_ldb(&ldb_data);
+ imx53_add_v4l2_output(0);
+ imx53_add_v4l2_capture(0);
+ imx53_add_mxc_pwm(1);
+ imx53_add_mxc_pwm_backlight(0, &mxc_pwm_backlight_data);
+ imx53_add_sdhci_esdhc_imx(0, &mx53_smd_sd1_data);
+ imx53_add_sdhci_esdhc_imx(1, &mx53_smd_sd2_data);
+ imx53_add_sdhci_esdhc_imx(2, &mx53_smd_sd3_data);
+ imx53_add_ahci(0, &mx53_smd_sata_data);
+ mxc_register_device(&imx_ahci_device_hwmon, NULL);
+
+ mx53_smd_init_usb();
+ imx53_add_iim(&iim_data);
+ smd_add_device_buttons();
+
+ mx53_smd_init_da9052();
+
+ /* Camera reset */
+ gpio_request(MX53_SMD_CSI0_RST, "cam-reset");
+ gpio_set_value(MX53_SMD_CSI0_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX53_SMD_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX53_SMD_CSI0_PWN, 1);
+ msleep(1);
+ gpio_set_value(MX53_SMD_CSI0_PWN, 0);
+
+ spi_device_init();
+
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+
+ gpio_request(MX53_SMD_DCDC1V8_EN, "dcdc1v8-en");
+ gpio_direction_output(MX53_SMD_DCDC1V8_EN, 1);
+
+ /* ambient light sensor */
+ gpio_request(MX53_SMD_ALS_INT, "als int");
+ gpio_direction_input(MX53_SMD_ALS_INT);
+
+ mxc_register_device(&smd_audio_device, &smd_audio_data);
+ mxc_register_device(&imx_bt_rfkill, &imx_bt_rfkill_data);
+ imx53_add_imx_ssi(1, &smd_ssi_pdata);
+
+ imx53_add_spdif(&mxc_spdif_data);
+ imx53_add_spdif_dai();
+ imx53_add_spdif_audio_device();
+
+ /* this call required to release SCC RAM partition held by ROM
+ * during boot, even if SCC2 driver is not part of the image
+ */
+ imx53_add_mxc_scc2();
+
+ mx5_cpu_regulator_init();
+}
+
+static void __init mx53_smd_timer_init(void)
+{
+ mx53_clocks_init(32768, 24000000, 22579200, 0);
+}
+
+static struct sys_timer mx53_smd_timer = {
+ .init = mx53_smd_timer_init,
+};
+
+MACHINE_START(MX53_SMD, "Freescale MX53 SMD Board")
+ .fixup = fixup_mxc_board,
+ .map_io = mx53_map_io,
+ .init_early = imx53_init_early,
+ .init_irq = mx53_init_irq,
+ .timer = &mx53_smd_timer,
+ .init_machine = mx53_smd_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/bus_freq.c b/arch/arm/mach-mx5/bus_freq.c
new file mode 100755
index 00000000..8e1ccce8
--- /dev/null
+++ b/arch/arm/mach-mx5/bus_freq.c
@@ -0,0 +1,1064 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file bus_freq.c
+ *
+ * @brief A common API for the Freescale Semiconductor i.MXC CPUfreq module
+ * and DVFS CORE module.
+ *
+ * The APIs are for setting bus frequency to low or high.
+ *
+ * @ingroup PM
+ */
+#include <asm/io.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <mach/iram.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/sdram_autogating.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include "crm_regs.h"
+
+#define LP_LOW_VOLTAGE 1050000
+#define LP_NORMAL_VOLTAGE 1250000
+#define LP_APM_CLK 24000000
+#define NAND_LP_APM_CLK 12000000
+#define AXI_A_NORMAL_CLK 166250000
+#define AXI_A_CLK_NORMAL_DIV 4
+#define AXI_B_CLK_NORMAL_DIV 5
+#define AHB_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV
+#define EMI_SLOW_CLK_NORMAL_DIV AXI_B_CLK_NORMAL_DIV
+#define NFC_CLK_NORMAL_DIV 4
+#define SPIN_DELAY 1000000 /* in nanoseconds */
+#define DDR_TYPE_DDR3 0x0
+#define DDR_TYPE_DDR2 0x1
+
+static DEFINE_SPINLOCK(ddr_freq_lock);
+static DEFINE_SPINLOCK(freq_lock);
+
+unsigned long lp_normal_rate;
+unsigned long lp_med_rate;
+unsigned long ddr_normal_rate;
+unsigned long ddr_med_rate;
+unsigned long ddr_low_rate;
+static int cur_ddr_rate;
+static unsigned char mx53_ddr_type;
+
+static struct clk *ddr_clk;
+static struct clk *pll1_sw_clk;
+static struct clk *pll1;
+static struct clk *pll2;
+static struct clk *pll3;
+static struct clk *pll4;
+static struct clk *main_bus_clk;
+static struct clk *axi_a_clk;
+static struct clk *axi_b_clk;
+static struct clk *cpu_clk;
+static struct clk *ddr_hf_clk;
+static struct clk *ahb_clk;
+static struct clk *ddr_clk;
+static struct clk *periph_apm_clk;
+static struct clk *lp_apm;
+static struct clk *gpc_dvfs_clk;
+static struct clk *emi_garb_clk;
+static void __iomem *pll1_base;
+static void __iomem *pll4_base;
+
+struct regulator *pll_regulator;
+
+struct regulator *lp_regulator;
+int low_bus_freq_mode;
+int high_bus_freq_mode;
+int med_bus_freq_mode;
+
+int bus_freq_scaling_initialized;
+
+static struct cpu_op *cpu_op_tbl;
+static struct device *busfreq_dev;
+static int busfreq_suspended;
+static int cpu_podf;
+/* True if bus_frequency is scaled not using DVFS-PER */
+int bus_freq_scaling_is_active;
+
+static int cpu_op_nr;
+int lp_high_freq;
+int lp_med_freq;
+char *lp_reg_id;
+
+static int lp_voltage;
+struct workqueue_struct *voltage_wq;
+static struct work_struct voltage_change_handler;
+struct completion voltage_change_cmpl;
+
+void enter_lpapm_mode_mx50(void);
+void enter_lpapm_mode_mx51(void);
+void enter_lpapm_mode_mx53(void);
+void exit_lpapm_mode_mx50(int high_bus_freq);
+void exit_lpapm_mode_mx51(void);
+void exit_lpapm_mode_mx53(void);
+int low_freq_bus_used(void);
+void set_ddr_freq(int ddr_freq);
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void __iomem *ccm_base;
+extern void __iomem *databahn_base;
+extern int update_ddr_freq(int ddr_rate);
+extern unsigned int mx50_ddr_type;
+
+static DEFINE_SPINLOCK(voltage_lock);
+struct mutex bus_freq_mutex;
+
+struct timeval start_time;
+struct timeval end_time;
+
+static void voltage_work_handler(struct work_struct *work)
+{
+ if (lp_regulator != NULL) {
+ u32 ret = 0;
+ ret = regulator_set_voltage(lp_regulator,
+ lp_voltage, lp_voltage);
+ udelay(400);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT SET LP VOLTAGE!!!!!!\n");
+ return;
+ }
+ }
+ complete_all(&voltage_change_cmpl);
+}
+
+int set_low_bus_freq(void)
+{
+ if (busfreq_suspended)
+ return 0;
+ if (bus_freq_scaling_initialized) {
+ /* can not enter low bus freq, when cpu is in higher freq
+ * or only have one working point */
+ if ((clk_get_rate(cpu_clk) >
+ cpu_op_tbl[cpu_op_nr - 1].cpu_rate)
+ || (cpu_op_nr == 1)) {
+ return 0;
+ }
+
+ mutex_lock(&bus_freq_mutex);
+
+ stop_dvfs_per();
+
+ stop_sdram_autogating();
+
+ if (cpu_is_mx50())
+ enter_lpapm_mode_mx50();
+ else if (cpu_is_mx51())
+ enter_lpapm_mode_mx51();
+ else
+ enter_lpapm_mode_mx53();
+ mutex_unlock(&bus_freq_mutex);
+ }
+ return 0;
+}
+
+void enter_lpapm_mode_mx50()
+{
+ u32 reg;
+ unsigned long flags;
+ spin_lock_irqsave(&freq_lock, flags);
+
+ set_ddr_freq(LP_APM_CLK);
+
+ /* Set the parent of main_bus_clk to be PLL3 */
+ clk_set_parent(main_bus_clk, pll3);
+ /* Set the AHB dividers to be 2.
+ * Set the dividers so that clock rates
+ * are not greater than current clock rate.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ | 0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0x0F)
+ udelay(10);
+
+ low_bus_freq_mode = 1;
+ high_bus_freq_mode = 0;
+ med_bus_freq_mode = 0;
+
+ /* Set the source of main_bus_clk to be lp-apm. */
+ clk_set_parent(main_bus_clk, lp_apm);
+
+ /* Set the AHB dividers to be 1. */
+ /* Set the dividers to be 1, so the clock rates
+ * are at 24Mhz
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ | 0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0x0F)
+ udelay(10);
+
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ spin_lock_irqsave(&voltage_lock, flags);
+ lp_voltage = LP_LOW_VOLTAGE;
+ INIT_COMPLETION(voltage_change_cmpl);
+ queue_work(voltage_wq, &voltage_change_handler);
+ spin_unlock_irqrestore(&voltage_lock, flags);
+
+ if (clk_get_usecount(pll1_sw_clk) == 1) {
+ /* Relock PLL1 to 160MHz. */
+ clk_set_parent(pll1_sw_clk, pll2);
+ /* Set the divider to ARM_PODF to 3. */
+ __raw_writel(0x02, MXC_CCM_CACRR);
+
+ clk_set_rate(pll1, cpu_op_tbl[cpu_op_nr - 1].cpu_rate);
+ clk_set_parent(pll1_sw_clk, pll1);
+ /* Set the divider to ARM_PODF to 1. */
+ __raw_writel(0x0, MXC_CCM_CACRR);
+ }
+
+ udelay(100);
+}
+
+void enter_lpapm_mode_mx51()
+{
+ u32 reg;
+ /* Set PLL3 to 133Mhz if no-one is using it. */
+ if (clk_get_usecount(pll3) == 0) {
+ u32 pll3_rate = clk_get_rate(pll3);
+
+ clk_enable(pll3);
+ clk_set_rate(pll3, clk_round_rate(pll3, 133000000));
+
+ /*Change the DDR freq to 133Mhz. */
+ clk_set_rate(ddr_hf_clk,
+ clk_round_rate(ddr_hf_clk, ddr_low_rate));
+
+ /* Set the parent of Periph_apm_clk to be PLL3 */
+ clk_set_parent(periph_apm_clk, pll3);
+ clk_set_parent(main_bus_clk, periph_apm_clk);
+
+ /* Set the dividers to be 1, so the clock rates
+ * are at 133MHz.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MXC_CCM_CBCDR_EMI_PODF_MASK
+ | MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ | 0 << MXC_CCM_CBCDR_EMI_PODF_OFFSET
+ | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ clk_enable(emi_garb_clk);
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F)
+ udelay(10);
+ clk_disable(emi_garb_clk);
+
+ low_bus_freq_mode = 1;
+ high_bus_freq_mode = 0;
+ med_bus_freq_mode = 0;
+
+ /* Set the source of Periph_APM_Clock to be lp-apm. */
+ clk_set_parent(periph_apm_clk, lp_apm);
+
+ /* Set PLL3 back to original rate. */
+ clk_set_rate(pll3, clk_round_rate(pll3, pll3_rate));
+ clk_disable(pll3);
+ }
+}
+
+void enter_lpapm_mode_mx53()
+{
+ u32 reg;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ /* TBD: Reduce DDR frequency for DDR2 */
+ /* if (mx53_ddr_type == DDR_TYPE_DDR2) {
+ } */
+
+ /* move cpu clk to pll2, 400 / 1 = 400MHZ for cpu */
+ /* Change the source of pll1_sw_clk to be the step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ cpu_podf = __raw_readl(MXC_CCM_CACRR);
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ while (1) {
+ if ((reg & MXC_CCM_CDHIPR_ARM_PODF_BUSY) == 0) {
+ __raw_writel(0x0, MXC_CCM_CACRR);
+ break;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n");
+ }
+ }
+ clk_set_parent(pll1_sw_clk, pll2);
+
+ /* ahb = pll2/8, axi_b = pll2/8, axi_a = pll2/1*/
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 7 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 7 << MXC_CCM_CBCDR_AHB_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ (MXC_CCM_CDHIPR_AXI_A_PODF_BUSY |
+ MXC_CCM_CDHIPR_AXI_B_PODF_BUSY |
+ MXC_CCM_CDHIPR_AHB_PODF_BUSY)) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec
+ > SPIN_DELAY)
+ panic("low bus freq set rate error\n");
+ }
+
+ /* keep this infront of propagating */
+ low_bus_freq_mode = 1;
+ high_bus_freq_mode = 0;
+ med_bus_freq_mode = 0;
+
+ if (clk_get_usecount(pll1) == 0) {
+ reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL);
+ reg &= ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL);
+ }
+ if (clk_get_usecount(pll4) == 0) {
+ reg = __raw_readl(pll4_base + MXC_PLL_DP_CTL);
+ reg &= ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pll4_base + MXC_PLL_DP_CTL);
+ }
+}
+
+int set_high_bus_freq(int high_bus_freq)
+{
+ u32 reg;
+ if (bus_freq_scaling_initialized) {
+ mutex_lock(&bus_freq_mutex);
+ /*
+ * If the CPU freq is 800MHz, set the bus to the high
+ * setpoint (133MHz) and DDR to 200MHz.
+ */
+ if ((clk_get_rate(cpu_clk) >
+ cpu_op_tbl[cpu_op_nr - 1].cpu_rate)
+ || lp_high_freq)
+ high_bus_freq = 1;
+
+ stop_sdram_autogating();
+
+ if (low_bus_freq_mode) {
+ /* Relock PLL3 to 133MHz */
+ if (cpu_is_mx50())
+ exit_lpapm_mode_mx50(high_bus_freq);
+ else if (cpu_is_mx51())
+ exit_lpapm_mode_mx51();
+ else
+ exit_lpapm_mode_mx53();
+ start_dvfs_per();
+ }
+ if (bus_freq_scaling_is_active) {
+ if (!high_bus_freq_mode && high_bus_freq) {
+ if (cpu_is_mx50()) {
+ if (med_bus_freq_mode) {
+ /* Increase SYS_CLK */
+ reg = __raw_readl(MXC_CCM_CLK_SYS);
+ reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK;
+ reg |= 4 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CLK_SYS);
+
+ /* Set the dividers to the default dividers */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
+ udelay(10);
+ }
+ } else {
+ clk_set_rate(ahb_clk,
+ clk_round_rate(ahb_clk,
+ lp_normal_rate));
+ clk_set_rate(ddr_hf_clk,
+ clk_round_rate(ddr_hf_clk,
+ ddr_normal_rate));
+ }
+ /* Set to the high setpoint. */
+ high_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ med_bus_freq_mode = 0;
+ } else if (!med_bus_freq_mode && !high_bus_freq) {
+ if (cpu_is_mx50()) {
+ /* Set the dividers to the medium setpoint dividers */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ |3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ |5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
+ udelay(10);
+ /* Reduce SYS_CLK */
+ reg = __raw_readl(MXC_CCM_CLK_SYS);
+ reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK;
+ reg |= 8 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CLK_SYS);
+ } else {
+ if (cpu_is_mx51())
+ clk_set_rate(ddr_hf_clk,
+ clk_round_rate(
+ ddr_hf_clk,
+ ddr_low_rate));
+ clk_set_rate(ahb_clk,
+ clk_round_rate(
+ ahb_clk, lp_med_rate));
+ }
+ /* Set to the medium setpoint. */
+ high_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ med_bus_freq_mode = 1;
+ }
+ if (cpu_is_mx50()) {
+ if (med_bus_freq_mode &&
+ (cur_ddr_rate != ddr_med_rate))
+ set_ddr_freq(ddr_med_rate);
+ if (high_bus_freq_mode &&
+ (cur_ddr_rate != ddr_normal_rate))
+ set_ddr_freq(ddr_normal_rate);
+ }
+ }
+ start_sdram_autogating();
+ mutex_unlock(&bus_freq_mutex);
+ }
+ return 0;
+}
+
+void exit_lpapm_mode_mx50(int high_bus_freq)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (clk_get_usecount(pll1_sw_clk) == 1) {
+ /* Relock PLL1 to 800MHz. */
+ clk_set_parent(pll1_sw_clk, pll2);
+ /* Set the divider to ARM_PODF to 3, cpu is at 160MHz. */
+ __raw_writel(0x02, MXC_CCM_CACRR);
+
+ clk_set_rate(pll1, cpu_op_tbl[0].pll_rate);
+
+ /* Set the divider to ARM_PODF to 5 before
+ * switching the parent.
+ */
+ __raw_writel(0x4, MXC_CCM_CACRR);
+ clk_set_parent(pll1_sw_clk, pll1);
+ }
+
+ if (!completion_done(&voltage_change_cmpl))
+ wait_for_completion_interruptible(&voltage_change_cmpl);
+ spin_lock_irqsave(&voltage_lock, flags);
+ if (lp_voltage != LP_NORMAL_VOLTAGE) {
+ INIT_COMPLETION(voltage_change_cmpl);
+ lp_voltage = LP_NORMAL_VOLTAGE;
+ if (!queue_work(voltage_wq, &voltage_change_handler))
+ printk(KERN_ERR "WORK_NOT_ADDED\n");
+ spin_unlock_irqrestore(&voltage_lock, flags);
+ wait_for_completion_interruptible(&voltage_change_cmpl);
+ } else {
+ spin_unlock_irqrestore(&voltage_lock, flags);
+ if (!completion_done(&voltage_change_cmpl))
+ wait_for_completion_interruptible(&voltage_change_cmpl);
+ }
+
+ spin_lock_irqsave(&freq_lock, flags);
+ if (!low_bus_freq_mode) {
+ spin_unlock_irqrestore(&freq_lock, flags);
+ return;
+ }
+
+ /* Temporarily set the dividers when the source is PLL3.
+ * No clock rate is above 133MHz.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ |1 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
+ udelay(10);
+
+ clk_set_parent(main_bus_clk, pll3);
+
+ if (bus_freq_scaling_is_active && !high_bus_freq) {
+ /* Set the dividers to the medium setpoint dividers */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ |3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ |5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
+ udelay(10);
+
+ /*Set the main_bus_clk parent to be PLL2. */
+ clk_set_parent(main_bus_clk, pll2);
+
+ /* Set to the medium setpoint. */
+ high_bus_freq_mode = 0;
+ low_bus_freq_mode = 0;
+ med_bus_freq_mode = 1;
+ set_ddr_freq(ddr_med_rate);
+ } else {
+ /* Set the dividers to the default dividers */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MX50_CCM_CBCDR_WEIM_PODF_MASK);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0xF)
+ udelay(10);
+
+ /*Set the main_bus_clk parent to be PLL2. */
+ clk_set_parent(main_bus_clk, pll2);
+
+ /* Set to the high setpoint. */
+ high_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ med_bus_freq_mode = 0;
+ set_ddr_freq(ddr_normal_rate);
+ }
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ udelay(100);
+}
+
+void exit_lpapm_mode_mx51()
+{
+ u32 reg;
+
+ /* Temporarily Set the dividers is PLL3.
+ * No clock rate is above 133MHz.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MXC_CCM_CBCDR_EMI_PODF_MASK
+ | MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_EMI_PODF_OFFSET
+ | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ clk_enable(emi_garb_clk);
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F)
+ udelay(10);
+ clk_disable(emi_garb_clk);
+
+ clk_set_parent(periph_apm_clk, pll3);
+
+ /* Set the dividers to the default dividers */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK
+ | MXC_CCM_CBCDR_EMI_PODF_MASK
+ | MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ reg |= (3 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 4 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 4 << MXC_CCM_CBCDR_AHB_PODF_OFFSET
+ | 4 << MXC_CCM_CBCDR_EMI_PODF_OFFSET
+ | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ clk_enable(emi_garb_clk);
+ while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F)
+ udelay(10);
+
+ low_bus_freq_mode = 0;
+ high_bus_freq_mode = 1;
+ clk_disable(emi_garb_clk);
+
+ /*Set the main_bus_clk parent to be PLL2. */
+ clk_set_parent(main_bus_clk, pll2);
+
+ /*Change the DDR freq to 200MHz*/
+ clk_set_rate(ddr_hf_clk,
+ clk_round_rate(ddr_hf_clk, ddr_normal_rate));
+}
+
+void exit_lpapm_mode_mx53()
+{
+ u32 reg;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+
+ /* move cpu clk to pll1 */
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ while (1) {
+ if ((reg & MXC_CCM_CDHIPR_ARM_PODF_BUSY) == 0) {
+ __raw_writel(cpu_podf & 0x7, MXC_CCM_CACRR);
+ break;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n");
+ }
+ }
+ clk_set_parent(pll1_sw_clk, pll1);
+
+
+ /* ahb = 400/3, axi_b = 400/2, axi_a = 400*/
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK
+ | MXC_CCM_CBCDR_AXI_B_PODF_MASK
+ | MXC_CCM_CBCDR_AHB_PODF_MASK);
+ reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET
+ | 1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET
+ | 2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ (MXC_CCM_CDHIPR_AXI_A_PODF_BUSY |
+ MXC_CCM_CDHIPR_AXI_B_PODF_BUSY |
+ MXC_CCM_CDHIPR_AHB_PODF_BUSY)) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec
+ - nstimeofday.tv_nsec
+ > SPIN_DELAY)
+ panic("bus freq error\n");
+ }
+
+ /* keep this infront of propagating */
+ low_bus_freq_mode = 0;
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+
+ /* TBD: Restore DDR frequency for DDR2 */
+ /* if (mx53_ddr_type == DDR_TYPE_DDR2) {
+ } */
+}
+
+void set_ddr_freq(int ddr_rate)
+{
+ unsigned long flags;
+ unsigned int ret = 0;
+
+ spin_lock_irqsave(&ddr_freq_lock, flags);
+
+ if (cpu_is_mx50())
+ ret = update_ddr_freq(ddr_rate);
+
+ spin_unlock_irqrestore(&ddr_freq_lock, flags);
+ if (!ret)
+ cur_ddr_rate = ddr_rate;
+ udelay(100);
+}
+
+int low_freq_bus_used(void)
+{
+ if ((lp_high_freq == 0)
+ && (lp_med_freq == 0))
+ return 1;
+ else
+ return 0;
+}
+
+void setup_pll(void)
+{
+}
+
+static ssize_t bus_freq_scaling_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (bus_freq_scaling_is_active)
+ return sprintf(buf, "Bus frequency scaling is enabled\n");
+ else
+ return sprintf(buf, "Bus frequency scaling is disabled\n");
+}
+
+static ssize_t bus_freq_scaling_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ u32 reg;
+
+ if (strncmp(buf, "1", 1) == 0) {
+ if (dvfs_per_active()) {
+ printk(KERN_INFO "bus frequency scaling cannot be\
+ enabled when DVFS-PER is active\n");
+ return size;
+ }
+ if (!cpu_is_mx50()) {
+ /* Initialize DVFS-PODF to 0. */
+ reg = __raw_readl(MXC_CCM_CDCR);
+ reg &= ~MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK;
+ __raw_writel(reg, MXC_CCM_CDCR);
+ clk_set_parent(main_bus_clk, pll2);
+ }
+ bus_freq_scaling_is_active = 1;
+ set_high_bus_freq(0);
+ } else if (strncmp(buf, "0", 1) == 0) {
+ if (bus_freq_scaling_is_active)
+ set_high_bus_freq(1);
+ bus_freq_scaling_is_active = 0;
+ }
+
+ return size;
+}
+
+static int busfreq_suspend(struct platform_device *pdev, pm_message_t message)
+{
+ if (low_bus_freq_mode)
+ set_high_bus_freq(1);
+ busfreq_suspended = 1;
+ return 0;
+}
+
+static int busfreq_resume(struct platform_device *pdev)
+{
+ busfreq_suspended = 0;
+ return 0;
+}
+
+static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
+ bus_freq_scaling_enable_store);
+
+/*!
+ * This is the probe routine for the bus frequency driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit busfreq_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ unsigned long pll2_rate, pll1_rate;
+
+ if (cpu_is_mx51()) {
+ pll1_base = MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR);
+ } else if (cpu_is_mx53()) {
+ pll1_base = MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR);
+ pll4_base = MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR);
+ } else if (cpu_is_mx50()) {
+ pll1_base = MX50_IO_ADDRESS(MX50_PLL1_BASE_ADDR);
+ }
+
+ busfreq_dev = &pdev->dev;
+
+ main_bus_clk = clk_get(NULL, "main_bus_clk");
+ if (IS_ERR(main_bus_clk)) {
+ printk(KERN_DEBUG "%s: failed to get main_bus_clk\n",
+ __func__);
+ return PTR_ERR(main_bus_clk);
+ }
+
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (IS_ERR(pll1_sw_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n", __func__);
+ return PTR_ERR(pll1_sw_clk);
+ }
+
+ pll1 = clk_get(NULL, "pll1_main_clk");
+ if (IS_ERR(pll1)) {
+ printk(KERN_DEBUG "%s: failed to get pll1\n", __func__);
+ return PTR_ERR(pll1);
+ }
+
+ pll2 = clk_get(NULL, "pll2");
+ if (IS_ERR(pll2)) {
+ printk(KERN_DEBUG "%s: failed to get pll2\n", __func__);
+ return PTR_ERR(pll2);
+ }
+
+ pll3 = clk_get(NULL, "pll3");
+ if (IS_ERR(pll3)) {
+ printk(KERN_DEBUG "%s: failed to get pll3\n", __func__);
+ return PTR_ERR(pll3);
+ }
+
+ if (cpu_is_mx53()) {
+ pll4 = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4)) {
+ printk(KERN_DEBUG "%s: failed to get pll4\n", __func__);
+ return PTR_ERR(pll4);
+ }
+ }
+
+ axi_a_clk = clk_get(NULL, "axi_a_clk");
+ if (IS_ERR(axi_a_clk)) {
+ printk(KERN_DEBUG "%s: failed to get axi_a_clk\n",
+ __func__);
+ return PTR_ERR(axi_a_clk);
+ }
+
+ axi_b_clk = clk_get(NULL, "axi_b_clk");
+ if (IS_ERR(axi_b_clk)) {
+ printk(KERN_DEBUG "%s: failed to get axi_b_clk\n",
+ __func__);
+ return PTR_ERR(axi_b_clk);
+ }
+
+ ddr_clk = clk_get(NULL, "ddr_clk");
+ if (IS_ERR(ddr_clk)) {
+ printk(KERN_DEBUG "%s: failed to get ddr_clk\n",
+ __func__);
+ return PTR_ERR(ddr_clk);
+ }
+
+ ddr_hf_clk = clk_get_parent(ddr_clk);
+
+ if (IS_ERR(ddr_hf_clk)) {
+ printk(KERN_DEBUG "%s: failed to get ddr_hf_clk\n",
+ __func__);
+ return PTR_ERR(ddr_hf_clk);
+ }
+
+ ahb_clk = clk_get(NULL, "ahb_clk");
+ if (IS_ERR(ahb_clk)) {
+ printk(KERN_DEBUG "%s: failed to get ahb_clk\n",
+ __func__);
+ return PTR_ERR(ahb_clk);
+ }
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
+ __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ if (cpu_is_mx51())
+ emi_garb_clk = clk_get(NULL, "emi_intr_clk.1");
+ else if (cpu_is_mx53())
+ emi_garb_clk = clk_get(NULL, "emi_intr_clk.1");
+ else
+ emi_garb_clk = clk_get(NULL, "ocram_clk");
+ if (IS_ERR(emi_garb_clk)) {
+ printk(KERN_DEBUG "%s: failed to get emi_garb_clk\n",
+ __func__);
+ return PTR_ERR(emi_garb_clk);
+ }
+
+ if (cpu_is_mx51() || cpu_is_mx53()) {
+ periph_apm_clk = clk_get(NULL, "periph_apm_clk");
+ if (IS_ERR(periph_apm_clk)) {
+ printk(KERN_DEBUG "%s: failed to get periph_apm_clk\n",
+ __func__);
+ return PTR_ERR(periph_apm_clk);
+ }
+ }
+
+ lp_apm = clk_get(NULL, "lp_apm");
+ if (IS_ERR(lp_apm)) {
+ printk(KERN_DEBUG "%s: failed to get lp_apm\n",
+ __func__);
+ return PTR_ERR(lp_apm);
+ }
+
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+ if (IS_ERR(gpc_dvfs_clk)) {
+ printk(KERN_DEBUG "%s: failed to get gpc_dvfs_clk\n", __func__);
+ return PTR_ERR(gpc_dvfs_clk);
+ }
+
+ err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+ if (err) {
+ printk(KERN_ERR
+ "Unable to register sysdev entry for BUSFREQ");
+ return err;
+ }
+
+ pll1_rate = clk_get_rate(pll1_sw_clk);
+ pll2_rate = clk_get_rate(pll2);
+
+ if (pll2_rate == 665000000) {
+ /* for mx51 */
+ lp_normal_rate = pll2_rate / 5;
+ lp_med_rate = pll2_rate / 8;
+ ddr_normal_rate = pll1_rate / 4; /* 200M */
+ ddr_low_rate = pll1_rate / 6; /* 133M */
+ } else if (pll2_rate == 600000000) {
+ /* for mx53 evk rev.A */
+ lp_normal_rate = pll2_rate / 5;
+ lp_med_rate = pll2_rate / 8;
+ ddr_normal_rate = pll2_rate / 2;
+ ddr_low_rate = pll2_rate / 2;
+ } else if (pll2_rate == 400000000) {
+ if (cpu_is_mx50()) {
+ lp_normal_rate = pll2_rate / 3;
+ ddr_normal_rate = clk_get_rate(ddr_clk);
+ lp_med_rate = pll2_rate / 6;
+ ddr_low_rate = LP_APM_CLK;
+ if (mx50_ddr_type == MX50_LPDDR2)
+ ddr_med_rate = pll2_rate / 3;
+ else
+ /* mDDR @ 133Mhz currently does not work */
+ ddr_med_rate = ddr_normal_rate;
+ }
+ }
+
+ /* for mx53 */
+ if (cpu_is_mx53()) {
+ /* set DDR type */
+ if (machine_is_mx53_evk() || machine_is_mx53_ard())
+ mx53_ddr_type = DDR_TYPE_DDR2;
+ else
+ mx53_ddr_type = DDR_TYPE_DDR3;
+ if (mx53_ddr_type == DDR_TYPE_DDR2) {
+ /* DDR2 */
+ lp_normal_rate = pll2_rate / 3;
+ lp_med_rate = pll2_rate / 5;
+ ddr_normal_rate = pll2_rate / 1;
+ ddr_low_rate = pll2_rate / 3;
+ } else {
+ /* DDR3: DDR3 frequency can not be lower than 300MHZ */
+ lp_normal_rate = pll2_rate / 3;
+ lp_med_rate = pll2_rate / 5;
+ ddr_normal_rate = pll2_rate / 1;
+ ddr_low_rate = pll2_rate / 1;
+ }
+ }
+
+ if (cpu_is_mx50()) {
+ cur_ddr_rate = ddr_normal_rate;
+
+ if (lp_reg_id != NULL) {
+ lp_regulator = regulator_get(NULL, lp_reg_id);
+ if (IS_ERR(lp_regulator)) {
+ printk(KERN_DEBUG
+ "%s: failed to get lp regulator\n", __func__);
+ return PTR_ERR(lp_regulator);
+ }
+
+ voltage_wq = create_workqueue("voltage_change");
+ INIT_WORK(&voltage_change_handler,
+ voltage_work_handler);
+
+ init_completion(&voltage_change_cmpl);
+ }
+ }
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ low_bus_freq_mode = 0;
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+ bus_freq_scaling_is_active = 0;
+ bus_freq_scaling_initialized = 1;
+
+ mutex_init(&bus_freq_mutex);
+ return 0;
+}
+
+static struct platform_driver busfreq_driver = {
+ .driver = {
+ .name = "imx_busfreq",
+ },
+ .probe = busfreq_probe,
+ .suspend = busfreq_suspend,
+ .resume = busfreq_resume,
+};
+
+/*!
+ * Initialise the busfreq_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init busfreq_init(void)
+{
+ if (platform_driver_register(&busfreq_driver) != 0) {
+ printk(KERN_ERR "busfreq_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "Bus freq driver module loaded\n");
+ return 0;
+}
+
+static void __exit busfreq_cleanup(void)
+{
+ sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&busfreq_driver);
+ bus_freq_scaling_initialized = 0;
+}
+
+module_init(busfreq_init);
+module_exit(busfreq_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("BusFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
new file mode 100755
index 00000000..a6a409b7
--- /dev/null
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -0,0 +1,1588 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "crm_regs.h"
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk osc_clk;
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk mx53_pll4_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk periph_apm_clk;
+static struct clk ahb_clk;
+static struct clk ipg_clk;
+static struct clk usboh3_clk;
+static struct clk emi_fast_clk;
+static struct clk ipu_clk;
+static struct clk mipi_hsc1_clk;
+static struct clk esdhc1_clk;
+static struct clk esdhc2_clk;
+static struct clk esdhc3_mx53_clk;
+
+#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
+
+/* calculate best pre and post dividers to get the required divider */
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
+ u32 max_pre, u32 max_post)
+{
+ if (div >= max_pre * max_post) {
+ *pre = max_pre;
+ *post = max_post;
+ } else if (div >= max_pre) {
+ u32 min_pre, temp_pre, old_err, err;
+ min_pre = DIV_ROUND_UP(div, max_post);
+ old_err = max_pre;
+ for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = DIV_ROUND_UP(div, *pre);
+ } else {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
+{
+ u32 reg = __raw_readl(clk->enable_reg);
+
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= mode << clk->enable_shift;
+
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_ccgr_enable(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
+ return 0;
+}
+
+static void _clk_ccgr_disable(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
+}
+
+static int _clk_ccgr_enable_inrun(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+ return 0;
+}
+
+static void _clk_ccgr_disable_inwait(struct clk *clk)
+{
+ _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return -EINVAL;
+}
+
+static inline void __iomem *_mx51_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return MX51_DPLL1_BASE;
+ else if (pll == &pll2_sw_clk)
+ return MX51_DPLL2_BASE;
+ else if (pll == &pll3_sw_clk)
+ return MX51_DPLL3_BASE;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static inline void __iomem *_mx53_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return MX53_DPLL1_BASE;
+ else if (pll == &pll2_sw_clk)
+ return MX53_DPLL2_BASE;
+ else if (pll == &pll3_sw_clk)
+ return MX53_DPLL3_BASE;
+ else if (pll == &mx53_pll4_sw_clk)
+ return MX53_DPLL4_BASE;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (cpu_is_mx51())
+ return _mx51_get_pll_base(pll);
+ else
+ return _mx53_get_pll_base(pll);
+}
+
+static unsigned long clk_pll_get_rate(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ void __iomem *pllbase;
+ s64 temp;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * parent_rate;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+ unsigned long pll_hfsm, dp_ctl;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ pllbase = _get_pll_base(clk);
+
+ quad_parent_rate = 4 * parent_rate;
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -EINVAL;
+ pdf--;
+
+ temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+ do_div(temp64, quad_parent_rate/1000000);
+ mfn = (long)temp64;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ if (pll_hfsm == 0) {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ } else {
+ reg = mfi << 4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+
+ return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+ int i = 0;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ if (reg & MXC_PLL_DP_CTL_LRF)
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: pll locking failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, step;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ /* When switching from pll_main_clk to a bypass clock, first select a
+ * multiplexed clock in 'step_sel', then shift the glitchless mux
+ * 'pll1_sw_clk_sel'.
+ *
+ * When switching back, do it in reverse order
+ */
+ if (parent == &pll1_main_clk) {
+ /* Switch to pll1_main_clk */
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* step_clk mux switched to lp_apm, to save power. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+ MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ if (parent == &lp_apm_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
+ } else if (parent == &pll2_sw_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
+ } else if (parent == &pll3_sw_clk) {
+ step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED;
+ } else
+ return -EINVAL;
+
+ reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Switch to step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ } else
+ div = 1;
+ return parent_rate / div;
+}
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll2_sw_clk)
+ reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ else
+ reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static unsigned long clk_cpu_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+
+ return parent_rate / div;
+}
+
+static int clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, cpu_podf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+ cpu_podf = parent_rate / rate - 1;
+ /* use post divider to change freq */
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CACRR);
+
+ return 0;
+}
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ int i = 0;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+ reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY))
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: Set parent for periph_apm clock failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+
+ if (parent == &pll2_sw_clk)
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ else if (parent == &periph_apm_clk)
+ reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+};
+
+static unsigned long clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ return parent_rate / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+ int i = 0;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Wait for lock */
+ do {
+ reg = __raw_readl(MXC_CCM_CDHIPR);
+ if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY))
+ break;
+
+ udelay(1);
+ } while (++i < MAX_DPLL_WAIT_TRIES);
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ pr_err("MX5: clk_ahb_set_rate failed\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return parent_rate / div;
+}
+
+
+static int _clk_max_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+
+ /* Handshake with MAX when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ else if (cpu_is_mx53())
+ reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_max_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable_inwait(clk);
+
+ /* No Handshake with MAX when LPM is entered as its disabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ else if (cpu_is_mx53())
+ reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static unsigned long clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+ return parent_rate / div;
+}
+
+static unsigned long clk_ipg_per_get_rate(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+ unsigned long parent_rate;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ return parent_rate / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk)
+ return parent_rate;
+ else
+ BUG();
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+
+ reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+
+ if (parent == &ipg_clk)
+ reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ else if (parent == &lp_apm_clk)
+ reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ else if (parent != &main_bus_clk)
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+#define clk_nfc_set_parent NULL
+
+static unsigned long clk_nfc_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ rate = clk_get_rate(clk->parent) / div;
+ WARN_ON(rate == 0);
+ return rate;
+}
+
+static unsigned long clk_nfc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+
+ if (!rate)
+ return -EINVAL;
+
+ div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ if (div > 8)
+ return -EINVAL;
+
+ return parent_rate / div;
+
+}
+
+static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ div = clk_get_rate(clk->parent) / rate;
+ if (div == 0)
+ div++;
+ if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
+ }
+
+ return 0;
+}
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+static unsigned long clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
+ MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
+ rate = clk_get_rate(clk->parent) / div;
+
+ return rate;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk pll1_main_clk = {
+ .parent = &osc_clk,
+ .get_rate = clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* Clock tree block diagram (WIP):
+ * CCM: Clock Controller Module
+ *
+ * PLL output -> |
+ * | CCM Switcher -> CCM_CLK_ROOT_GEN ->
+ * PLL bypass -> |
+ *
+ */
+
+/* PLL1 SW supplies to ARM core */
+static struct clk pll1_sw_clk = {
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = clk_pll1_sw_get_rate,
+};
+
+/* PLL2 SW supplies to AXI/AHB/IP buses */
+static struct clk pll2_sw_clk = {
+ .parent = &osc_clk,
+ .get_rate = clk_pll_get_rate,
+ .set_rate = _clk_pll_set_rate,
+ .set_parent = _clk_pll2_sw_set_parent,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
+static struct clk pll3_sw_clk = {
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .get_rate = clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
+static struct clk mx53_pll4_sw_clk = {
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* Low-power Audio Playback Mode clock */
+static struct clk lp_apm_clk = {
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+};
+
+static struct clk periph_apm_clk = {
+ .parent = &pll1_sw_clk,
+ .set_parent = _clk_periph_apm_set_parent,
+};
+
+static struct clk cpu_clk = {
+ .parent = &pll1_sw_clk,
+ .get_rate = clk_cpu_get_rate,
+ .set_rate = clk_cpu_set_rate,
+};
+
+static struct clk ahb_clk = {
+ .parent = &main_bus_clk,
+ .get_rate = clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+};
+
+static struct clk iim_clk = {
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+};
+
+/* Main IP interface clock for access to registers */
+static struct clk ipg_clk = {
+ .parent = &ahb_clk,
+ .get_rate = clk_ipg_get_rate,
+};
+
+static struct clk ipg_perclk = {
+ .parent = &lp_apm_clk,
+ .get_rate = clk_ipg_per_get_rate,
+ .set_parent = _clk_ipg_per_set_parent,
+};
+
+static struct clk ahb_max_clk = {
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+};
+
+static struct clk aips_tz1_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk gpc_dvfs_clk = {
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+};
+
+static struct clk gpt_32k_clk = {
+ .id = 0,
+ .parent = &ckil_clk,
+};
+
+static struct clk dummy_clk = {
+ .id = 0,
+};
+
+static struct clk emi_slow_clk = {
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+ .get_rate = clk_emi_slow_get_rate,
+};
+
+static int clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+
+ /* Enable handshake with IPU when certain clock rates are changed */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Enable handshake with IPU when LPM is entered */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable(clk);
+
+ /* Disable handshake with IPU whe dividers are changed */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Disable handshake with IPU when LPM is entered */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk ahbmux1_clk = {
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk ipu_sec_clk = {
+ .parent = &emi_fast_clk,
+ .secondary = &ahbmux1_clk,
+};
+
+static struct clk ddr_hf_clk = {
+ .parent = &pll1_sw_clk,
+ .get_rate = _clk_ddr_hf_get_rate,
+};
+
+static struct clk ddr_clk = {
+ .parent = &ddr_hf_clk,
+};
+
+/* clock definitions for MIPI HSC unit which has been removed
+ * from documentation, but not from hardware
+ */
+static int _clk_hsc_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_hsc_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_ccgr_disable(clk);
+ /* No handshake with HSC as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk mipi_hsp_clk = {
+ .parent = &ipu_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_hsc_enable,
+ .disable = _clk_hsc_disable,
+ .secondary = &mipi_hsc1_clk,
+};
+
+#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = pfx##_get_rate, \
+ .set_rate = pfx##_set_rate, \
+ .round_rate = pfx##_round_rate, \
+ .set_parent = pfx##_set_parent, \
+ .enable = _clk_ccgr_enable, \
+ .disable = _clk_ccgr_disable, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = pfx##_get_rate, \
+ .set_rate = pfx##_set_rate, \
+ .set_parent = pfx##_set_parent, \
+ .enable = _clk_max_enable, \
+ .disable = _clk_max_disable, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define CLK_GET_RATE(name, nr, bitsname) \
+static unsigned long clk_##name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, pred, podf; \
+ \
+ reg = __raw_readl(MXC_CCM_CSCDR##nr); \
+ pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \
+ >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
+ podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \
+ >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
+ \
+ return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \
+ (pred + 1) * (podf + 1)); \
+}
+
+#define CLK_SET_PARENT(name, nr, bitsname) \
+static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ u32 reg, mux; \
+ \
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \
+ &pll3_sw_clk, &lp_apm_clk); \
+ reg = __raw_readl(MXC_CCM_CSCMR##nr) & \
+ ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \
+ reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \
+ __raw_writel(reg, MXC_CCM_CSCMR##nr); \
+ \
+ return 0; \
+}
+
+#define CLK_SET_RATE(name, nr, bitsname) \
+static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div, parent_rate; \
+ u32 pre = 0, post = 0; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div = parent_rate / rate; \
+ \
+ if ((parent_rate / div) != rate) \
+ return -EINVAL; \
+ \
+ __calc_pre_post_dividers(div, &pre, &post, \
+ (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \
+ (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
+ \
+ /* Set sdhc1 clock divider */ \
+ reg = __raw_readl(MXC_CCM_CSCDR##nr) & \
+ ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \
+ | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \
+ reg |= (post - 1) << \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
+ reg |= (pre - 1) << \
+ MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
+ __raw_writel(reg, MXC_CCM_CSCDR##nr); \
+ \
+ return 0; \
+}
+
+/* UART */
+CLK_GET_RATE(uart, 1, UART)
+CLK_SET_PARENT(uart, 1, UART)
+
+static struct clk uart_root_clk = {
+ .parent = &pll2_sw_clk,
+ .get_rate = clk_uart_get_rate,
+ .set_parent = clk_uart_set_parent,
+};
+
+/* USBOH3 */
+CLK_GET_RATE(usboh3, 1, USBOH3)
+CLK_SET_PARENT(usboh3, 1, USBOH3)
+
+static struct clk usboh3_clk = {
+ .parent = &pll2_sw_clk,
+ .get_rate = clk_usboh3_get_rate,
+ .set_parent = clk_usboh3_set_parent,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+};
+
+static struct clk usb_ahb_clk = {
+ .parent = &ipg_clk,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+};
+
+static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+
+ if (parent == &pll3_sw_clk)
+ reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk usb_phy1_clk = {
+ .parent = &pll3_sw_clk,
+ .set_parent = clk_usb_phy1_set_parent,
+ .enable = _clk_ccgr_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_ccgr_disable,
+};
+
+/* eCSPI */
+CLK_GET_RATE(ecspi, 2, CSPI)
+CLK_SET_PARENT(ecspi, 1, CSPI)
+
+static struct clk ecspi_main_clk = {
+ .parent = &pll3_sw_clk,
+ .get_rate = clk_ecspi_get_rate,
+ .set_parent = clk_ecspi_set_parent,
+};
+
+/* eSDHC */
+CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+
+/* mx51 specific */
+CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+
+static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else if (parent == &esdhc2_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc2_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+/* mx53 specific */
+static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
+ else if (parent == &esdhc3_mx53_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
+CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
+CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
+
+static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc3_mx53_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
+ static struct clk name = { \
+ .id = i, \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .get_rate = gr, \
+ .set_rate = sr, \
+ .enable = e, \
+ .disable = d, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \
+ DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s)
+
+/* Shared peripheral bus arbiter */
+DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
+/* UART */
+DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
+ NULL, NULL, &ipg_clk, &spba_clk);
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart1_ipg_clk);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart2_ipg_clk);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &uart_root_clk, &uart3_ipg_clk);
+
+/* GPT */
+DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &gpt_ipg_clk);
+
+DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
+/* I2C */
+DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
+/* FEC */
+DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
+/* NFC */
+DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
+ clk_nfc, &emi_slow_clk, NULL);
+
+/* SSI */
+DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk);
+DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk);
+DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET,
+ NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk);
+
+/* eCSPI */
+DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &spba_clk);
+DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk);
+DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable,
+ &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET,
+ NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk);
+
+/* CSPI */
+DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, &aips_tz2_clk);
+DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
+ NULL, NULL, &ipg_clk, &cspi_ipg_clk);
+
+/* SDMA */
+DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
+ NULL, NULL, &ahb_clk, NULL);
+
+/* eSDHC */
+DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
+ clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
+DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+
+/* mx51 specific */
+DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
+ clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+
+static struct clk esdhc3_clk = {
+ .id = 2,
+ .parent = &esdhc1_clk,
+ .set_parent = clk_esdhc3_set_parent,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+ .secondary = &esdhc3_ipg_clk,
+};
+static struct clk esdhc4_clk = {
+ .id = 3,
+ .parent = &esdhc1_clk,
+ .set_parent = clk_esdhc4_set_parent,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+ .secondary = &esdhc4_ipg_clk,
+};
+
+/* mx53 specific */
+static struct clk esdhc2_mx53_clk = {
+ .id = 2,
+ .parent = &esdhc1_clk,
+ .set_parent = clk_esdhc2_mx53_set_parent,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+ .secondary = &esdhc3_ipg_clk,
+};
+
+DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET,
+ clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk);
+
+static struct clk esdhc4_mx53_clk = {
+ .id = 3,
+ .parent = &esdhc1_clk,
+ .set_parent = clk_esdhc4_mx53_set_parent,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+ .secondary = &esdhc4_ipg_clk,
+};
+
+DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
+DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
+DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
+
+/* IPU */
+DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
+
+DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
+ NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
+ &ddr_clk, NULL);
+
+DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
+ NULL, NULL, &pll3_sw_clk, NULL);
+DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
+ NULL, NULL, &pll3_sw_clk, NULL);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup mx51_lookups[] = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
+ _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
+ _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
+ _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk)
+ _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk)
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk)
+ _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk)
+ _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
+ _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
+ _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk)
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
+ _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
+ _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "ipu", ipu_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+ _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
+};
+
+static struct clk_lookup mx53_lookups[] = {
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_mx53_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_mx53_clk)
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_mx53_clk)
+ _REGISTER_CLOCK("imx53-ecspi.0", NULL, ecspi1_clk)
+ _REGISTER_CLOCK("imx53-ecspi.1", NULL, ecspi2_clk)
+ _REGISTER_CLOCK("imx53-cspi.0", NULL, cspi_clk)
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
+ _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "ipu", ipu_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
+ _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+ _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
+ _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
+};
+
+static void clk_tree_init(void)
+{
+ u32 reg;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ *
+ * FIXME: Verify if true for all boards
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+}
+
+int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2)
+{
+ int i;
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
+ clkdev_add(&mx51_lookups[i]);
+
+ clk_tree_init();
+
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ clk_enable(&iim_clk);
+ mx51_revision();
+ clk_disable(&iim_clk);
+ mx51_display_revision();
+
+ /* move usb_phy_clk to 24MHz */
+ clk_set_parent(&usb_phy1_clk, &osc_clk);
+
+ /* set the usboh3_clk parent to pll2_sw_clk */
+ clk_set_parent(&usboh3_clk, &pll2_sw_clk);
+
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+ clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
+
+ /* set SDHC root clock as 166.25MHZ*/
+ clk_set_rate(&esdhc1_clk, 166250000);
+ clk_set_rate(&esdhc2_clk, 166250000);
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+ MX51_MXC_INT_GPT);
+ return 0;
+}
+
+int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2)
+{
+ int i;
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++)
+ clkdev_add(&mx53_lookups[i]);
+
+ clk_tree_init();
+
+ clk_set_parent(&uart_root_clk, &pll3_sw_clk);
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ clk_enable(&iim_clk);
+ mx53_revision();
+ clk_disable(&iim_clk);
+ mx53_display_revision();
+
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+ clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk);
+
+ /* set SDHC root clock as 200MHZ*/
+ clk_set_rate(&esdhc1_clk, 200000000);
+ clk_set_rate(&esdhc3_mx53_clk, 200000000);
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+ MX53_INT_GPT);
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
new file mode 100755
index 00000000..bf60ffa6
--- /dev/null
+++ b/arch/arm/mach-mx5/clock.c
@@ -0,0 +1,5237 @@
+/*
+ * Copyright (C) 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/sdram_autogating.h>
+
+#include "crm_regs.h"
+#include "cpu_op-mx51.h"
+#include "cpu_op-mx53.h"
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk pll4_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk tve_clk;
+static struct clk emi_fast_clk;
+static struct clk emi_slow_clk;
+static struct clk emi_intr_clk[];
+static struct clk ddr_clk;
+static struct clk ipu_clk[];
+static struct clk ldb_di_clk[];
+static struct clk axi_a_clk;
+static struct clk axi_b_clk;
+static struct clk ddr_hf_clk;
+static struct clk mipi_hsp_clk;
+static struct clk gpu3d_clk;
+static struct clk gpu2d_clk;
+static struct clk vpu_clk[];
+static int cpu_curr_op;
+static struct cpu_op *cpu_op_tbl;
+
+static void __iomem *pll1_base;
+static void __iomem *pll2_base;
+static void __iomem *pll3_base;
+static void __iomem *pll4_base;
+
+static int cpu_op_nr;
+extern int lp_high_freq;
+extern int lp_med_freq;
+static int max_axi_a_clk;
+static int max_axi_b_clk;
+static int max_ahb_clk;
+static int max_emi_slow_clk;
+extern int dvfs_core_is_active;
+
+#define SPIN_DELAY 1000000 /* in nanoseconds */
+#define MAX_AXI_A_CLK_MX51 166250000
+#define MAX_AXI_A_CLK_MX53 400000000
+#define MAX_AXI_B_CLK_MX51 133000000
+#define MAX_AXI_B_CLK_MX53 200000000
+#define MAX_AHB_CLK_MX51 133000000
+#define MAX_EMI_SLOW_CLK_MX51 133000000
+#define MAX_AHB_CLK_MX53 133333333
+#define MAX_EMI_SLOW_CLK_MX53 133333333
+#define MAX_DDR_HF_RATE 200000000
+/* To keep compatible with some NAND flash, limit
+ * max NAND clk to 34MHZ. The user can modify it for
+ * dedicate NAND flash */
+#define MAX_NFC_CLK 34000000
+
+#define UART1_DMA_ENABLE 0
+#define UART2_DMA_ENABLE 0
+#define UART3_DMA_ENABLE 0
+#define UART4_DMA_ENABLE 0
+#define UART5_DMA_ENABLE 0
+
+#ifdef CONFIG_CLK_DEBUG
+#define __INIT_CLK_DEBUG(n) .name = #n,
+#else
+#define __INIT_CLK_DEBUG(n)
+#endif
+
+extern int mxc_jtag_enabled;
+extern int uart_at_24;
+extern int cpufreq_trig_needed;
+extern int low_bus_freq_mode;
+
+static int cpu_clk_set_op(int op);
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void (*set_num_cpu_op)(int num);
+
+static struct clk esdhc3_clk[];
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 8) {
+ min_pre = (div - 1) / 64 + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div < 8) {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGRx_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static int _clk_enable_inrun(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return 0;
+}
+
+/*
+ * For the ddr muxed input clock
+ */
+static inline u32 _get_mux_ddr(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3, struct clk *m4)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else if (parent == m4)
+ return 4;
+ else
+ BUG();
+
+ return 0;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return pll1_base;
+ else if (pll == &pll2_sw_clk)
+ return pll2_base;
+ else if (pll == &pll3_sw_clk)
+ return pll3_base;
+ else if (pll == &pll4_sw_clk)
+ return pll4_base;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ __INIT_CLK_DEBUG(ckih_clk)
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ __INIT_CLK_DEBUG(ckih2_clk)
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ __INIT_CLK_DEBUG(osc_clk)
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ __INIT_CLK_DEBUG(ckil_clk)
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static unsigned long _fpm_get_rate(struct clk *clk)
+{
+ u32 rate = ckil_clk.get_rate(&ckil_clk) * 512;
+ if ((__raw_readl(MXC_CCM_CCR) & MXC_CCM_CCR_FPM_MULT_MASK) != 0)
+ rate *= 2;
+ return rate;
+}
+
+static int _fpm_enable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg |= MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+ return 0;
+}
+
+static void _fpm_disable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg &= ~MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+}
+
+static struct clk fpm_clk = {
+ __INIT_CLK_DEBUG(fpm_clk)
+ .parent = &ckil_clk,
+ .get_rate = _fpm_get_rate,
+ .enable = _fpm_enable,
+ .disable = _fpm_disable,
+};
+
+static unsigned long _fpm_div2_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk fpm_div2_clk = {
+ __INIT_CLK_DEBUG(fpm_div2_clk)
+ .parent = &fpm_clk,
+ .get_rate = _fpm_div2_get_rate,
+};
+
+static unsigned long _clk_pll_get_rate(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ void __iomem *pllbase;
+ s64 temp;
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * clk_get_rate(clk->parent);
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, reg1;
+ void __iomem *pllbase;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+ unsigned long pll_hfsm, dp_ctl;
+
+ pllbase = _get_pll_base(clk);
+
+ quad_parent_rate = 4 * clk_get_rate(clk->parent);
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -1;
+ pdf--;
+
+ temp64 = rate*(pdf+1) - quad_parent_rate*mfi;
+ do_div(temp64, quad_parent_rate/1000000);
+ mfn = (long)temp64;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ if (pll_hfsm == 0) {
+ reg = mfi<<4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ } else {
+ reg = mfi<<4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ /* If auto restart is disabled, restart the PLL and
+ * wait for it to lock.
+ */
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ if (reg & MXC_PLL_DP_CTL_UPEN) {
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CONFIG);
+ if (!(reg & MXC_PLL_DP_CONFIG_AREN)) {
+ reg1 = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ reg1 |= MXC_PLL_DP_CTL_RST;
+ __raw_writel(reg1, pllbase + MXC_PLL_DP_CTL);
+ }
+ /* Wait for lock */
+ getnstimeofday(&nstimeofday);
+ while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL)
+ & MXC_PLL_DP_CTL_LRF)) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("pll_set_rate: pll relock failed\n");
+ }
+ }
+ return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+
+ if (reg & MXC_PLL_DP_CTL_UPEN)
+ return 0;
+
+ reg |= MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ getnstimeofday(&nstimeofday);
+ while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF)) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("pll relock failed\n");
+ }
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static struct clk pll1_main_clk = {
+ __INIT_CLK_DEBUG(pll1_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set the step_clk parent to be lp_apm, to save power. */
+ mux = _get_mux(&lp_apm_clk, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ if (parent == &lp_apm_clk) {
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ reg = __raw_readl(MXC_CCM_CCSR);
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+
+ }
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static unsigned long _clk_pll1_sw_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ div = 1;
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+/* pll1 switch clock */
+static struct clk pll1_sw_clk = {
+ __INIT_CLK_DEBUG(pll1_sw_clk)
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = _clk_pll1_sw_get_rate,
+};
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll2_sw_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ } else {
+ reg = (reg & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL);
+ reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+/* same as pll2_main_clk. These two clocks should always be the same */
+static struct clk pll2_sw_clk = {
+ __INIT_CLK_DEBUG(pll2_sw_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll_set_rate,
+ .set_parent = _clk_pll2_sw_set_parent,
+};
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ __INIT_CLK_DEBUG(pll3_sw_clk)
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+/* same as pll4_main_clk. These two clocks should always be the same */
+static struct clk pll4_sw_clk = {
+ __INIT_CLK_DEBUG(pll4_sw_clk)
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ else if (parent == &fpm_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk lp_apm_clk = {
+ __INIT_CLK_DEBUG(lp_apm_clk)
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+};
+
+static unsigned long _clk_arm_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 i;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+ if (i >= cpu_op_nr)
+ return -EINVAL;
+ cpu_clk_set_op(i);
+
+ return 0;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 i;
+ u32 op;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+
+ if (i > cpu_op_nr)
+ op = 0;
+
+ return cpu_op_tbl[op].cpu_rate;
+}
+
+
+static struct clk cpu_clk = {
+ __INIT_CLK_DEBUG(cpu_clk)
+ .parent = &pll1_sw_clk,
+ .get_rate = _clk_arm_get_rate,
+ .set_rate = _clk_cpu_set_rate,
+ .round_rate = _clk_cpu_round_rate,
+};
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+ reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("pll _clk_periph_apm_set_parent failed\n");
+ }
+ return 0;
+}
+
+static struct clk periph_apm_clk = {
+ __INIT_CLK_DEBUG(periph_apm_clk)
+ .parent = &pll1_sw_clk,
+ .set_parent = _clk_periph_apm_set_parent,
+};
+
+/* TODO: Need to sync with GPC to determine if DVFS is in place so that
+ * the DVFS_PODF divider can be applied in CDCR register.
+ */
+static unsigned long _clk_main_bus_get_rate(struct clk *clk)
+{
+ u32 div = 0;
+
+ if (dvfs_per_divider_active() || low_bus_freq_mode)
+ div = (__raw_readl(MXC_CCM_CDCR) & 0x3);
+ return clk_get_rate(clk->parent) / (div + 1);
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ if (parent == &pll2_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR) &
+ ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ } else if (parent == &periph_apm_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR) | MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ } else {
+ return -EINVAL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ __INIT_CLK_DEBUG(main_bus_clk)
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+ .get_rate = _clk_main_bus_get_rate,
+};
+
+static unsigned long _clk_axi_a_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_A_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_A_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_axi_a_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_A_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AXI_A_PODF_BUSY) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("pll _clk_axi_a_set_rate failed\n");
+ }
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_axi_a_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > max_axi_a_clk)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+
+static struct clk axi_a_clk = {
+ __INIT_CLK_DEBUG(axi_a_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_axi_a_get_rate,
+ .set_rate = _clk_axi_a_set_rate,
+ .round_rate = _clk_axi_a_round_rate,
+};
+
+static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
+ MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long _clk_ddr_hf_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > MAX_DDR_HF_RATE)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_ddr_hf_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_DDR_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_DDR_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_DDR_PODF_BUSY) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("clk_ddr_hf_set_rate failed\n");
+ }
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static struct clk ddr_hf_clk = {
+ __INIT_CLK_DEBUG(ddr_hf_clk)
+ .parent = &pll1_sw_clk,
+ .get_rate = _clk_ddr_hf_get_rate,
+ .round_rate = _clk_ddr_hf_round_rate,
+ .set_rate = _clk_ddr_hf_set_rate,
+};
+
+static unsigned long _clk_axi_b_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_B_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_B_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_axi_b_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_B_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AXI_B_PODF_BUSY) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("_clk_axi_b_set_rate failed\n");
+ }
+
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_axi_b_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > max_axi_b_clk)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+
+static struct clk axi_b_clk = {
+ __INIT_CLK_DEBUG(axi_b_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_axi_b_get_rate,
+ .set_rate = _clk_axi_b_set_rate,
+ .round_rate = _clk_axi_b_round_rate,
+};
+
+static unsigned long _clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY) {
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY)
+ panic("_clk_ahb_set_rate failed\n");
+ }
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > max_ahb_clk)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+
+static struct clk ahb_clk = {
+ __INIT_CLK_DEBUG(ahb_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+};
+
+static int _clk_max_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with MAX when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX51;
+ else
+ reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+
+static void _clk_max_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable_inwait(clk);
+
+ /* No Handshake with MAX when LPM is entered as its disabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX51;
+ else
+ reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk ahb_max_clk = {
+ __INIT_CLK_DEBUG(ahb_max_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+};
+
+static int _clk_emi_slow_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if (parent == &ahb_clk) {
+ reg |= MXC_CCM_CBCDR_EMI_CLK_SEL;
+ } else if (parent == &main_bus_clk) {
+ reg &= ~MXC_CCM_CBCDR_EMI_CLK_SEL;
+ } else {
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_emi_slow_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_EMI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_EMI_PODF_BUSY) {
+ getnstimeofday(&curtime);
+ if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY)
+ panic("_clk_emi_slow_set_rate failed\n");
+ }
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_slow_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > max_emi_slow_clk)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+
+static struct clk emi_slow_clk = {
+ __INIT_CLK_DEBUG(emi_slow_clk)
+ .parent = &main_bus_clk,
+ .set_parent = _clk_emi_slow_set_parent,
+ .get_rate = _clk_emi_slow_get_rate,
+ .set_rate = _clk_emi_slow_set_rate,
+ .round_rate = _clk_emi_slow_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk ahbmux1_clk = {
+ __INIT_CLK_DEBUG(ahbmux1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk ahbmux2_clk = {
+ __INIT_CLK_DEBUG(ahbmux2_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+
+static struct clk emi_fast_clk = {
+ __INIT_CLK_DEBUG(emi_fast_clk)
+ .parent = &ddr_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk emi_intr_clk[] = {
+ {
+ __INIT_CLK_DEBUG(emi_intr_clk_0)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahbmux2_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ },
+ {
+ /* On MX51 - this clock is name emi_garb_clk, and controls the
+ * access of ARM to GARB.
+ */
+ __INIT_CLK_DEBUG(emi_intr_clk_1)
+ .id = 1,
+ .parent = &ahb_clk,
+ .secondary = &ahbmux2_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ }
+};
+
+static unsigned long _clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk ipg_clk = {
+ __INIT_CLK_DEBUG(ipg_clk)
+ .parent = &ahb_clk,
+ .get_rate = _clk_ipg_get_rate,
+};
+
+static unsigned long _clk_ipg_per_get_rate(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk) {
+ return clk_get_rate(&ipg_clk);
+ }
+ BUG();
+ return 0;
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL);
+ if (mux == 2) {
+ reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ if (mux == 0)
+ reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ else
+ reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk ipg_perclk = {
+ __INIT_CLK_DEBUG(ipg_perclk)
+ .parent = &lp_apm_clk,
+ .get_rate = _clk_ipg_per_get_rate,
+ .set_parent = _clk_ipg_per_set_parent,
+};
+
+static int _clk_ipmux_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_ipmux_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(0x1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static struct clk ipumux1_clk = {
+ __INIT_CLK_DEBUG(ipumux1_clk)
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG6_1_OFFSET,
+ .enable = _clk_ipmux_enable,
+ .disable = _clk_ipmux_disable,
+};
+
+static struct clk ipumux2_clk = {
+ __INIT_CLK_DEBUG(ipumux2_clk)
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG6_2_OFFSET,
+ .enable = _clk_ipmux_enable,
+ .disable = _clk_ipmux_disable,
+};
+
+static int _clk_ocram_enable(struct clk *clk)
+{
+ return 0;
+}
+
+static void _clk_ocram_disable(struct clk *clk)
+{
+}
+
+static struct clk ocram_clk = {
+ __INIT_CLK_DEBUG(ocram_clk)
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_ocram_enable,
+ .disable = _clk_ocram_disable,
+};
+
+
+static struct clk aips_tz1_clk = {
+ __INIT_CLK_DEBUG(aips_tz1_clk)
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ __INIT_CLK_DEBUG(aips_tz2_clk)
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk gpc_dvfs_clk = {
+ __INIT_CLK_DEBUG(gpc_dvfs_clk)
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_sdma_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with SDMA when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51;
+ else
+ reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_sdma_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable(clk);
+ /* No handshake with SDMA as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ if (cpu_is_mx51())
+ reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51;
+ else
+ reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk sdma_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sdma_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .enable = _clk_sdma_enable,
+ .disable = _clk_sdma_disable,
+ },
+ {
+ .parent = &ipg_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &emi_intr_clk[0],
+#endif
+ },
+};
+
+static int _clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ if (cpu_is_mx51())
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ else
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MX53_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Handshake with IPU when LPM is entered as its enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ start_sdram_autogating();
+
+ return 0;
+}
+
+static void _clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (sdram_autogating_active())
+ stop_sdram_autogating();
+
+ _clk_disable(clk);
+
+ /* No handshake with IPU whe dividers are changed
+ * as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ if (cpu_is_mx51())
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ else
+ reg |= MXC_CCM_CCDR_IPU_HS_MX53_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* No handshake with IPU when LPM is entered as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static int _clk_ipu_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &ahb_clk,
+ &emi_slow_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+
+static struct clk ipu_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ipu_clk)
+ .parent = &ahb_clk,
+ .secondary = &ipu_clk[1],
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_ipu_enable,
+ .disable = _clk_ipu_disable,
+ .set_parent = _clk_ipu_set_parent,
+ .flags = CPU_FREQ_TRIG_UPDATE | AHB_MED_SET_POINT,
+ },
+ {
+ __INIT_CLK_DEBUG(ipu_clk_1)
+ .parent = &emi_fast_clk,
+ .secondary = &ahbmux1_clk,
+ }
+};
+
+static int _clk_ipu_di_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg &= ~MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(clk->id);
+ if (parent == &pll3_sw_clk)
+ ;
+ else if (parent == &osc_clk)
+ reg |= 1 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ else if (parent == &ckih_clk)
+ reg |= 2 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ else if ((parent == &pll4_sw_clk) && (clk->id == 0)) {
+ if (cpu_is_mx51())
+ return -EINVAL;
+ reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ } else if ((parent == &tve_clk) && (clk->id == 1))
+ reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ else if ((parent == &ldb_di_clk[clk->id]) && cpu_is_mx53())
+ reg |= 5 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ else /* Assume any other clock is external clock pin */
+ reg |= 4 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static int priv_div;
+static unsigned long _clk_ipu_di_get_rate(struct clk *clk)
+{
+ u32 reg, mux;
+ u32 div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = (reg & MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(clk->id)) >>
+ MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(clk->id);
+ if (mux == 0) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_DI1_CLK_PRED_MASK;
+ div = (reg >> MXC_CCM_CDCDR_DI1_CLK_PRED_OFFSET) + 1;
+ } else if ((mux == 3) && (clk->id == 1)) {
+ if (priv_div)
+ div = priv_div;
+ } else if ((mux == 3) && (clk->id == 0)) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_DI_PLL4_PODF_MASK;
+ div = (reg >> MXC_CCM_CDCDR_DI_PLL4_PODF_OFFSET) + 1;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu_di_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if ((clk->parent == &pll4_sw_clk) && (clk->id == 0)) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_DI_PLL4_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CDCDR_DI_PLL4_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+ } else if (clk->parent == &pll3_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_DI1_CLK_PRED_MASK;
+ reg |= (div - 1) << MXC_CCM_CDCDR_DI1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+ } else if (((clk->parent == &tve_clk) && (clk->id == 1)) ||
+ ((clk->parent == &ldb_di_clk[clk->id]) && cpu_is_mx53())) {
+ priv_div = div;
+ return 0;
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
+static unsigned long _clk_ipu_di_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di_clk[clk->id]) && cpu_is_mx53())
+ return parent_rate;
+ else {
+ div = (parent_rate + rate/2) / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return parent_rate / div;
+ }
+}
+
+static struct clk ipu_di_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ipu_di_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .get_rate = _clk_ipu_di_get_rate,
+ .set_parent = _clk_ipu_di_set_parent,
+ .round_rate = _clk_ipu_di_round_rate,
+ .set_rate = _clk_ipu_di_set_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ipu_di_clk_1)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .get_rate = _clk_ipu_di_get_rate,
+ .set_parent = _clk_ipu_di_set_parent,
+ .round_rate = _clk_ipu_di_round_rate,
+ .set_rate = _clk_ipu_di_set_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ldb_di_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+
+ if ((parent == &pll3_sw_clk)) {
+ if (clk->id == 0)
+ reg &= ~(MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL);
+ else
+ reg &= ~(MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL);
+ } else if ((parent == &pll4_sw_clk)) {
+ if (clk->id == 0)
+ reg |= MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL;
+ else
+ reg |= MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL;
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+ return 0;
+}
+
+static unsigned long _clk_ldb_di_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ if (clk->id == 0)
+ div = __raw_readl(MXC_CCM_CSCMR2) &
+ MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+ else
+ div = __raw_readl(MXC_CCM_CSCMR2) &
+ MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+
+ if (div)
+ return clk_get_rate(clk->parent) / 7;
+
+ return (2 * clk_get_rate(clk->parent)) / 7;
+}
+
+static unsigned long _clk_ldb_di_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate * 7 <= parent_rate + parent_rate/20)
+ return parent_rate / 7;
+ else
+ return 2 * parent_rate / 7;
+}
+
+static int _clk_ldb_di_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div = 0;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate * 7 <= parent_rate + parent_rate/20) {
+ div = 7;
+ rate = parent_rate / 7;
+ } else
+ rate = 2 * parent_rate / 7;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ if (div == 7)
+ reg |= (clk->id ? MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV :
+ MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
+ else
+ reg &= ~(clk->id ? MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV :
+ MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static int _clk_ldb_di_enable(struct clk *clk)
+{
+ _clk_enable(clk);
+ ipu_di_clk[clk->id].set_parent(&ipu_di_clk[clk->id], clk);
+ ipu_di_clk[clk->id].parent = clk;
+ ipu_di_clk[clk->id].enable(&ipu_di_clk[clk->id]);
+ ipu_di_clk[clk->id].usecount++;
+ return 0;
+}
+
+static void _clk_ldb_di_disable(struct clk *clk)
+{
+ _clk_disable(clk);
+ ipu_di_clk[clk->id].disable(&ipu_di_clk[clk->id]);
+ ipu_di_clk[clk->id].usecount--;
+}
+
+static struct clk ldb_di_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ldb_di_clk_0)
+ .id = 0,
+ .parent = &pll4_sw_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .get_rate = _clk_ldb_di_get_rate,
+ .set_parent = _clk_ldb_di_set_parent,
+ .round_rate = _clk_ldb_di_round_rate,
+ .set_rate = _clk_ldb_di_set_rate,
+ .enable = _clk_ldb_di_enable,
+ .disable = _clk_ldb_di_disable,
+ .flags = AHB_MED_SET_POINT,
+ },
+ {
+ __INIT_CLK_DEBUG(ldb_di_clk_1)
+ .id = 1,
+ .parent = &pll4_sw_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .get_rate = _clk_ldb_di_get_rate,
+ .set_parent = _clk_ldb_di_set_parent,
+ .round_rate = _clk_ldb_di_round_rate,
+ .set_rate = _clk_ldb_di_set_rate,
+ .enable = _clk_ldb_di_enable,
+ .disable = _clk_ldb_di_disable,
+ .flags = AHB_MED_SET_POINT,
+ },
+};
+
+static int _clk_csi0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_csi0_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR4);
+ pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent)/(pred * podf);
+}
+
+static unsigned long _clk_csi0_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_csi0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR4) &
+ ~(MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK |
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR4);
+
+ return 0;
+}
+
+static struct clk csi0_clk = {
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_csi0_set_parent,
+ .get_rate = _clk_csi0_get_rate,
+ .round_rate = _clk_csi0_round_rate,
+ .set_rate = _clk_csi0_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_csi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_csi1_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR4);
+ pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent)/(pred * podf) ;
+}
+
+static unsigned long _clk_csi1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_csi1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR4) &
+ ~(MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR4);
+
+ return 0;
+}
+
+static struct clk csi1_clk = {
+ __INIT_CLK_DEBUG(csi1_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_csi1_set_parent,
+ .get_rate = _clk_csi1_get_rate,
+ .round_rate = _clk_csi1_round_rate,
+ .set_rate = _clk_csi1_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+};
+
+
+static int _clk_hsc_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_hsc_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable(clk);
+ /* No handshake with HSC as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk mipi_esc_clk = {
+ __INIT_CLK_DEBUG(mipi_esc_clk)
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+};
+
+static struct clk mipi_hsc2_clk = {
+ __INIT_CLK_DEBUG(mipi_hsc2_clk)
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .secondary = &mipi_esc_clk,
+};
+
+static struct clk mipi_hsc1_clk = {
+ __INIT_CLK_DEBUG(mipi_hsc1_clk)
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .secondary = &mipi_hsc2_clk,
+};
+
+static struct clk mipi_hsp_clk = {
+ __INIT_CLK_DEBUG(mipi_hsp_clk)
+ .parent = &ipu_clk[0],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_hsc_enable,
+ .disable = _clk_hsc_disable,
+ .secondary = &mipi_hsc1_clk,
+};
+
+static int _clk_tve_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+
+ if ((parent == &pll3_sw_clk) && cpu_is_mx51()) {
+ reg &= ~(MXC_CCM_CSCMR1_TVE_CLK_SEL);
+ } else if ((parent == &pll4_sw_clk) && cpu_is_mx53()) {
+ reg &= ~(MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL);
+ } else if ((parent == &osc_clk) && cpu_is_mx51()) {
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL;
+ reg &= ~MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ } else if (parent == &ckih_clk) {
+ reg |= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL; /* Reserved on MX53 */
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static unsigned long _clk_tve_get_rate(struct clk *clk)
+{
+ u32 reg, div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & (MXC_CCM_CSCMR1_TVE_CLK_SEL | MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL)) == 0) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ div = (reg >> MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET) + 1;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long _clk_tve_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (cpu_is_mx51() && (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL))
+ return -EINVAL;
+ if (cpu_is_mx53() && (reg & MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL))
+ return -EINVAL;
+
+ div = (parent_rate + rate/2) / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return parent_rate / div;
+}
+
+static int _clk_tve_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (cpu_is_mx51() && (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL))
+ return -EINVAL;
+ if (cpu_is_mx53() && (reg & MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL))
+ return -EINVAL;
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ div--;
+ reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ reg |= div << MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+ return 0;
+}
+
+static struct clk tve_clk = {
+ __INIT_CLK_DEBUG(tve_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_tve_set_parent,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .get_rate = _clk_tve_get_rate,
+ .round_rate = _clk_tve_round_rate,
+ .set_rate = _clk_tve_set_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk spba_clk = {
+ __INIT_CLK_DEBUG(spba_clk)
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_uart_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent)/(prediv * podf) ;
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk uart_main_clk = {
+ __INIT_CLK_DEBUG(uart_main_clk)
+ .parent = &pll2_sw_clk,
+ .get_rate = _clk_uart_get_rate,
+ .set_parent = _clk_uart_set_parent,
+};
+
+static struct clk uart1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart1_clk_0)
+ .id = 0,
+ .parent = &uart_main_clk,
+ .secondary = &uart1_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART1_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+#if UART1_DMA_ENABLE
+ .secondary = &aips_tz1_clk,
+#endif
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart2_clk_0)
+ .id = 1,
+ .parent = &uart_main_clk,
+ .secondary = &uart2_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART2_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+#if UART2_DMA_ENABLE
+ .secondary = &aips_tz1_clk,
+#endif
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart3_clk_0)
+ .id = 2,
+ .parent = &uart_main_clk,
+ .secondary = &uart3_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART3_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart3_clk_1)
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart4_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart4_clk_0)
+ .id = 3,
+ .parent = &uart_main_clk,
+ .secondary = &uart4_clk[1],
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART4_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart4_clk_1)
+ .id = 3,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart5_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart5_clk_0)
+ .id = 4,
+ .parent = &uart_main_clk,
+ .secondary = &uart5_clk[1],
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART5_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart5_clk_1)
+ .id = 4,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpt_clki_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &gpt_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(gpt_clki_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(gpt_clki_2)
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm1_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_2)
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_0)
+ .parent = &ipg_perclk,
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm2_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_2)
+ .id = 1,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk i2c_clk[] = {
+ {
+ __INIT_CLK_DEBUG(i2c_clk_0)
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_1)
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_2)
+ .id = 2,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_hsi2c_serial_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ prediv = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static struct clk hsi2c_serial_clk = {
+ __INIT_CLK_DEBUG(hsi2c_serial_clk)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .get_rate = _clk_hsi2c_serial_get_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk hsi2c_clk = {
+ __INIT_CLK_DEBUG(hsi2c_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_cspi_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk cspi_main_clk = {
+ __INIT_CLK_DEBUG(cspi_main_clk)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_cspi_get_rate,
+ .set_parent = _clk_cspi_set_parent,
+};
+
+static struct clk cspi1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(cspi1_clk_0)
+ .id = 0,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi1_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(cspi1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(cspi2_clk_0)
+ .id = 1,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi2_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(cspi2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi3_clk = {
+ __INIT_CLK_DEBUG(cspi3_clk)
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &aips_tz2_clk,
+};
+
+static unsigned long _clk_ieee_rtc_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_IEEE_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_IEEE_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_IEEE_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_IEEE_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ieee_rtc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~(MXC_CCM_CSCDR2_IEEE_CLK_PRED_MASK |
+ MXC_CCM_CSCDR2_IEEE_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR2_IEEE_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR2_IEEE_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static unsigned long _clk_ieee_rtc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_ieee_rtc_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll3_sw_clk, &pll4_sw_clk,
+ NULL, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR2) & ~MXC_CCM_CSCMR2_IEEE_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR2_IEEE_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static struct clk ieee_rtc_clk = {
+ __INIT_CLK_DEBUG(ieee_rtc_clk)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ieee_rtc_set_parent,
+ .set_rate = _clk_ieee_rtc_set_rate,
+ .round_rate = _clk_ieee_rtc_round_rate,
+ .get_rate = _clk_ieee_rtc_get_rate,
+};
+
+static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &ckih_clk, &lp_apm_clk, &ckih2_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_lp_apm_clk = {
+ __INIT_CLK_DEBUG(ssi_lp_apm_clk)
+ .parent = &ckih_clk,
+ .set_parent = _clk_ssi_lp_apm_set_parent,
+};
+
+static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi1_set_parent,
+ .secondary = &ssi1_clk[1],
+ .get_rate = _clk_ssi1_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &ssi1_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_2)
+ .id = 0,
+ .parent = &aips_tz2_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk[0],
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_0)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi2_set_parent,
+ .secondary = &ssi2_clk[1],
+ .get_rate = _clk_ssi2_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &ssi2_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_2)
+ .id = 1,
+ .parent = &spba_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk[0],
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static int _clk_ssi3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI3_CLK_SEL;
+
+ if (parent == &ssi1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_SSI3_CLK_SEL;
+ else if (parent == &ssi2_clk[0])
+ reg |= MXC_CCM_CSCMR1_SSI3_CLK_SEL;
+ else {
+ printk(KERN_ERR"Set ssi3 clock parent failed!\n");
+ printk(KERN_ERR"ssi3 only support");
+ printk(KERN_ERR"ssi1 and ssi2 as parent clock\n");
+ return -1;
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk ssi3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi3_clk_0)
+ .id = 2,
+ .parent = &ssi1_clk[0],
+ .set_parent = _clk_ssi3_set_parent,
+ .secondary = &ssi3_clk[1],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi3_clk_1)
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &ssi3_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi3_clk_2)
+ .id = 2,
+ .parent = &aips_tz2_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk,
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi_ext1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ u32 div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET) + 1;
+ div = prediv * podf;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ssi_ext1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK |
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi1_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_ssi_ext1_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static struct clk ssi_ext1_clk = {
+ __INIT_CLK_DEBUG(ssi_ext1_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext1_set_parent,
+ .set_rate = _clk_ssi_ext1_set_rate,
+ .round_rate = _clk_ssi_ext1_round_rate,
+ .get_rate = _clk_ssi_ext1_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_ssi_ext2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ u32 div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET) + 1;
+ div = prediv * podf;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi2_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext2_clk = {
+ __INIT_CLK_DEBUG(ssi_ext2_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext2_set_parent,
+ .get_rate = _clk_ssi_ext2_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_esai_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ if (parent == &pll1_sw_clk || parent == &pll2_sw_clk ||
+ parent == &pll3_sw_clk) {
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ NULL);
+ reg &= ~MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET;
+ reg &= ~MXC_CCM_CSCMR2_ESAI_POST_SEL_MASK;
+ reg |= 0 << MXC_CCM_CSCMR2_ESAI_POST_SEL_OFFSET;
+ /* divider setting */
+ } else {
+ mux = _get_mux(parent, &ssi1_clk[0], &ssi2_clk[0], &ckih_clk,
+ &ckih2_clk);
+ reg &= ~MXC_CCM_CSCMR2_ESAI_POST_SEL_MASK;
+ reg |= (mux + 1) << MXC_CCM_CSCMR2_ESAI_POST_SEL_OFFSET;
+ /* divider setting */
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ /* set podf = 0 */
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static unsigned long _clk_esai_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ if (clk->parent == &pll1_sw_clk || clk->parent == &pll2_sw_clk ||
+ clk->parent == &pll3_sw_clk) {
+ pred = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+ } else {
+ podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / podf;
+ }
+}
+
+static struct clk esai_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esai_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esai_set_parent,
+ .get_rate = _clk_esai_get_rate,
+ .secondary = &esai_clk[1],
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esai_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk iim_clk = {
+ __INIT_CLK_DEBUG(iim_clk)
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax1_clk = {
+ __INIT_CLK_DEBUG(tmax1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ };
+
+static struct clk tmax2_clk = {
+ __INIT_CLK_DEBUG(tmax2_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax3_clk = {
+ __INIT_CLK_DEBUG(tmax3_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_usboh3_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk usboh3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(usboh3_clk_0)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_usboh3_set_parent,
+ .get_rate = _clk_usboh3_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usboh3_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(usboh3_clk_1)
+ .parent = &tmax2_clk,
+#if defined(CONFIG_USB_STATIC_IRAM) \
+ || defined(CONFIG_USB_STATIC_IRAM_PPH)
+ .secondary = &emi_intr_clk[0],
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static struct clk usb_ahb_clk = {
+ __INIT_CLK_DEBUG(usb_ahb_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_usb_phy_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ u32 div = 1;
+
+ if (clk->parent == &pll3_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ prediv = ((reg & MXC_CCM_CDCDR_USB_PHY_PRED_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_USB_PHY_PODF_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET) + 1;
+
+ div = (prediv * podf);
+ }
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usb_phy_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &osc_clk)
+ reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ else if (parent == &pll3_sw_clk)
+ reg |= MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ else
+ BUG();
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk usb_phy_clk[] = {
+ {
+ __INIT_CLK_DEBUG(usb_phy_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &tmax3_clk,
+ .set_parent = _clk_usb_phy_set_parent,
+ .get_rate = _clk_usb_phy_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(usb_phy_clk_1)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .secondary = &tmax3_clk,
+ .set_parent = _clk_usb_phy_set_parent,
+ .get_rate = _clk_usb_phy_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk esdhc_dep_clks = {
+ __INIT_CLK_DEBUG(esdhc_dep_clks)
+ .parent = &spba_clk,
+ .secondary = &emi_fast_clk,
+};
+
+static unsigned long _clk_esdhc1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+
+static int _clk_sdhc1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk esdhc1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_0)
+ .id = 0,
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_esdhc1_set_parent,
+ .get_rate = _clk_esdhc1_get_rate,
+ .set_rate = _clk_sdhc1_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc1_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &esdhc1_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_2)
+ .id = 0,
+ .parent = &tmax3_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+
+};
+
+static unsigned long _clk_esdhc2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ if (cpu_is_mx51()) {
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+ }
+ return clk_get_rate(clk->parent);
+}
+
+static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (cpu_is_mx51()) {
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET;
+ } else { /* MX53 */
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ else if (parent == &esdhc3_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ else
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static int _clk_esdhc2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (cpu_is_mx51()) {
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) <<
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) <<
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+ }
+ return 0;
+}
+
+static struct clk esdhc2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_0)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esdhc2_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc2_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &esdhc2_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_2)
+ .id = 0,
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (cpu_is_mx51()) {
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MX51;
+ else if (parent == &esdhc2_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MX51;
+ else
+ BUG();
+ } else { /* MX53 */
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET;
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_esdhc3_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_sdhc3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (cpu_is_mx53()) {
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+ }
+ return 0;
+}
+
+
+static struct clk esdhc3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_0)
+ .id = 2,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc3_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_1)
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &esdhc3_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_2)
+ .id = 0,
+ .parent = &ahb_max_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ if (cpu_is_mx51()) {
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc2_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ BUG();
+ } else {/*MX53 */
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc3_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc4_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_0)
+ .id = 3,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc4_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc4_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_1)
+ .id = 3,
+ .parent = &ipg_clk,
+ .secondary = &esdhc4_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_2)
+ .id = 0,
+ .parent = &tmax3_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static struct clk sata_clk = {
+ __INIT_CLK_DEBUG(sata_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk ieee_1588_clk = {
+ __INIT_CLK_DEBUG(ieee_1588_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk mlb_clk[] = {
+ {
+ __INIT_CLK_DEBUG(mlb_clk_0)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &mlb_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(mlb_clk_1)
+ .parent = &emi_fast_clk,
+ .secondary = &emi_intr_clk[1],
+ },
+};
+
+static int _can_root_clk_set(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &ipg_clk, &ckih_clk, &ckih2_clk, &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR2) & ~MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static struct clk can1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(can1_clk_0)
+ .id = 0,
+ .parent = &lp_apm_clk,
+ .set_parent = _can_root_clk_set,
+ .enable = _clk_enable,
+ .secondary = &can1_clk[1],
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(can1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk can2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(can2_clk_0)
+ .id = 1,
+ .parent = &lp_apm_clk,
+ .set_parent = _can_root_clk_set,
+ .enable = _clk_enable,
+ .secondary = &can2_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(can2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_sim_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR2) & ~MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_sim_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ pred = ((reg & MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static unsigned long _clk_sim_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_sim_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set SIM clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR2) &
+ ~(MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK |
+ MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+
+}
+
+static struct clk sim_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sim_clk_0)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_sim_set_parent,
+ .secondary = &sim_clk[1],
+ .get_rate = _clk_sim_get_rate,
+ .round_rate = _clk_sim_round_rate,
+ .set_rate = _clk_sim_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(sim_clk_1)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_nfc_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long _clk_nfc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ /*
+ * Compute the divider we'd have to use to reach the target rate.
+ */
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (parent_rate / div > MAX_NFC_CLK)
+ div++;
+
+ /*
+ * The divider for this clock is 3 bits wide, so we can't possibly
+ * divide the parent by more than eight.
+ */
+
+ if (div > 8)
+ return -EINVAL;
+
+ return parent_rate / div;
+
+}
+
+static int _clk_nfc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){
+ getnstimeofday(&curtime);
+ if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY)
+ panic("_clk_nfc_set_rate failed\n");
+ }
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+
+ return 0;
+}
+
+static struct clk emi_enfc_clk = {
+ __INIT_CLK_DEBUG(emi_enfc_clk)
+ .parent = &emi_slow_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .disable = _clk_disable_inwait,
+ .get_rate = _clk_nfc_get_rate,
+ .round_rate = _clk_nfc_round_rate,
+ .set_rate = _clk_nfc_set_rate,
+};
+
+static int _clk_spdif_xtal_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &osc_clk, &ckih_clk, &ckih2_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk spdif_xtal_clk = {
+ __INIT_CLK_DEBUG(spdif_xtal_clk)
+ .parent = &osc_clk,
+ .set_parent = _clk_spdif_xtal_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF0_COM;
+ if (parent != &ssi1_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF0_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_spdif0_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+ u32 div = 1;
+
+ if (clk->parent != &ssi1_clk[0]) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1;
+ div = (pred * podf);
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk spdif0_clk[] = {
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_spdif0_set_parent,
+ .get_rate = _clk_spdif0_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_spdif1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF1_COM;
+ if (parent != &ssi2_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF1_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_spdif1_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+ u32 div = 1;
+
+ if (clk->parent != &ssi2_clk[0]) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET) + 1;
+ div = (pred * podf);
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk spdif1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(spdif1_clk_0)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_spdif1_set_parent,
+ .get_rate = _clk_spdif1_get_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(spdif1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, reg2, mux;
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg2 = __raw_readl(MXC_CCM_CBCDR);
+ if (cpu_is_mx51()) {
+ clk->parent = &ddr_hf_clk;
+ mux = _get_mux_ddr(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk, &ddr_hf_clk);
+ } else {
+ clk->parent = &axi_a_clk;
+ mux = _get_mux_ddr(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk, NULL);
+ }
+ if (mux < 4) {
+ reg = (reg & ~MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+ if (cpu_is_mx51())
+ reg2 = (reg2 & ~MXC_CCM_CBCDR_DDR_HF_SEL);
+ } else {
+ reg2 = (reg2 & ~MXC_CCM_CBCDR_DDR_HF_SEL) |
+ (MXC_CCM_CBCDR_DDR_HF_SEL);
+ }
+ if (cpu_is_mx51()) {
+ __raw_writel(reg2, MXC_CCM_CBCDR);
+ getnstimeofday(&nstimeofday);
+ while (__raw_readl(MXC_CCM_CDHIPR) &
+ MXC_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY){
+ getnstimeofday(&curtime);
+ if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY)
+ panic("_clk_ddr_set_parent failed\n");
+ }
+ }
+ return 0;
+}
+
+static struct clk ddr_clk = {
+ __INIT_CLK_DEBUG(ddr_clk)
+ .parent = &axi_b_clk,
+ .set_parent = _clk_ddr_set_parent,
+};
+
+static int _clk_arm_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk arm_axi_clk = {
+ __INIT_CLK_DEBUG(arm_axi_clk)
+ .parent = &axi_a_clk,
+ .set_parent = _clk_arm_axi_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_vpu_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk vpu_clk[] = {
+ {
+ __INIT_CLK_DEBUG(vpu_clk_0)
+ .set_parent = _clk_vpu_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &vpu_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(vpu_clk_1)
+ .set_parent = _clk_vpu_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &vpu_clk[2],
+ },
+ {
+ __INIT_CLK_DEBUG(vpu_clk_2)
+ .parent = &emi_fast_clk,
+ }
+};
+
+static int _clk_lpsr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ mux = _get_mux(parent, &ckil_clk, &osc_clk, NULL, NULL);
+ reg = (reg & ~MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static struct clk lpsr_clk = {
+ __INIT_CLK_DEBUG(lpsr_clk)
+ .parent = &ckil_clk,
+ .set_parent = _clk_lpsr_set_parent,
+};
+
+static unsigned long _clk_pgc_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET;
+ div = 1 >> div;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk pgc_clk = {
+ __INIT_CLK_DEBUG(pgc_clk)
+ .parent = &ipg_clk,
+ .get_rate = _clk_pgc_get_rate,
+};
+
+static unsigned long _clk_usb_get_rate(struct clk *clk)
+{
+ return 60000000;
+}
+
+/*usb OTG clock */
+static struct clk usb_clk = {
+ __INIT_CLK_DEBUG(usb_clk)
+ .get_rate = _clk_usb_get_rate,
+};
+
+static struct clk usb_utmi_clk = {
+ __INIT_CLK_DEBUG(usb_utmi_clk)
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CSCMR1,
+ .enable_shift = MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ __INIT_CLK_DEBUG(rtc_clk)
+ .parent = &ckil_clk,
+ .secondary = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk ata_clk = {
+ __INIT_CLK_DEBUG(ata_clk)
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk owire_clk = {
+ __INIT_CLK_DEBUG(owire_clk)
+ .parent = &ipg_perclk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .disable = _clk_disable,
+};
+
+
+static struct clk fec_clk[] = {
+ {
+ __INIT_CLK_DEBUG(fec_clk_0)
+ .parent = &ipg_clk,
+ .secondary = &fec_clk[1],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(fec_clk_1)
+ .parent = &tmax2_clk,
+ .secondary = &fec_clk[2],
+ },
+ {
+ __INIT_CLK_DEBUG(fec_clk_2)
+ .parent = &aips_tz2_clk,
+ .secondary = &emi_fast_clk,
+ },
+};
+
+static struct clk scc_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sahara_clk_0)
+ .parent = &ahb_clk,
+ .secondary = &scc_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(sahara_clk_1)
+ .parent = &tmax1_clk,
+ .secondary = &scc_clk[2],
+ },
+ {
+ .parent = &emi_fast_clk,
+ .secondary = &emi_intr_clk[0],
+ }
+};
+
+static struct clk sahara_clk[] = {
+ {
+ __INIT_CLK_DEBUG(scc_clk_0)
+ .parent = &ahb_clk,
+ .secondary = &sahara_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(scc_clk_1)
+ .parent = &tmax1_clk,
+ .secondary = &sahara_clk[2],
+ },
+ {
+ .parent = &scc_clk,
+ .secondary = &emi_fast_clk,
+ }
+};
+
+
+static int _clk_gpu3d_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_GPU_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+
+static struct clk garb_clk = {
+ __INIT_CLK_DEBUG(garb_clk)
+ .parent = &axi_a_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpu3d_clk = {
+ __INIT_CLK_DEBUG(gpu3d_clk)
+ .parent = &axi_a_clk,
+ .set_parent = _clk_gpu3d_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ .secondary = &garb_clk,
+};
+
+static int _clk_gpu2d_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu2d_clk = {
+ __INIT_CLK_DEBUG(gpu2d_clk)
+ .parent = &axi_a_clk,
+ .set_parent = _clk_gpu2d_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long cko1_get_rate(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg = reg >> MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ return clk_get_rate(clk->parent) / (reg + 1);
+}
+
+static int cko1_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg |= MXC_CCM_CCOSR_CKOL_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static void cko1_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+}
+
+static int cko1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = (parent_rate/rate - 1) & 0x7;
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg |= div << MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long cko1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ div = div < 1 ? 1 : div;
+ div = div > 8 ? 8 : div;
+ return parent_rate / div;
+}
+
+static int cko1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &cpu_clk)
+ sel = 0;
+ else if (parent == &pll1_sw_clk)
+ sel = 1;
+ else if (parent == &pll2_sw_clk)
+ sel = 2;
+ else if (parent == &pll3_sw_clk)
+ sel = 3;
+ else if (parent == &emi_slow_clk)
+ sel = 4;
+ else if (parent == &pll4_sw_clk)
+ sel = 5;
+ else if (parent == &emi_enfc_clk)
+ sel = 6;
+ else if (parent == &ipu_di_clk[0])
+ sel = 8;
+ else if (parent == &ahb_clk)
+ sel = 11;
+ else if (parent == &ipg_clk)
+ sel = 12;
+ else if (parent == &ipg_perclk)
+ sel = 13;
+ else if (parent == &ckil_clk)
+ sel = 14;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_SEL_MASK;
+ reg |= sel << MXC_CCM_CCOSR_CKOL_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+static struct clk cko1_clk = {
+ __INIT_CLK_DEBUG(cko1_clk)
+ .get_rate = cko1_get_rate,
+ .enable = cko1_enable,
+ .disable = cko1_disable,
+ .set_rate = cko1_set_rate,
+ .round_rate = cko1_round_rate,
+ .set_parent = cko1_set_parent,
+};
+static int _clk_asrc_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ if (parent == &pll4_sw_clk)
+ reg |= MXC_CCM_CSCMR2_ASRC_CLK_SEL;
+ else
+ reg &= ~MXC_CCM_CSCMR2_ASRC_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_asrc_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_ASRC_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_ASRC_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_ASRC_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_ASRC_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_asrc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2) &
+ ~(MXC_CCM_CSCDR2_ASRC_CLK_PRED_MASK |
+ MXC_CCM_CSCDR2_ASRC_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR2_ASRC_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR2_ASRC_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static unsigned long _clk_asrc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static struct clk asrc_clk[] = {
+ {
+ __INIT_CLK_DEBUG(asrc_clk_0)
+ .id = 0,
+ .parent = &pll4_sw_clk,
+ .set_parent = _clk_asrc_set_parent,
+ .get_rate = _clk_asrc_get_rate,
+ .set_rate = _clk_asrc_set_rate,
+ .round_rate = _clk_asrc_round_rate,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(asrc_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ }
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "osc", osc_clk),
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk),
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk),
+ _REGISTER_CLOCK(NULL, "pll1_main_clk", pll1_main_clk),
+ _REGISTER_CLOCK(NULL, "pll1_sw_clk", pll1_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll2", pll2_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll3", pll3_sw_clk),
+ _REGISTER_CLOCK(NULL, "gpc_dvfs_clk", gpc_dvfs_clk),
+ _REGISTER_CLOCK(NULL, "lp_apm", lp_apm_clk),
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk),
+ _REGISTER_CLOCK(NULL, "periph_apm_clk", periph_apm_clk),
+ _REGISTER_CLOCK(NULL, "main_bus_clk", main_bus_clk),
+ _REGISTER_CLOCK(NULL, "axi_a_clk", axi_a_clk),
+ _REGISTER_CLOCK(NULL, "axi_b_clk", axi_b_clk),
+ _REGISTER_CLOCK(NULL, "ahb_clk", ahb_clk),
+ _REGISTER_CLOCK(NULL, "ahb_max_clk", ahb_max_clk),
+ _REGISTER_CLOCK(NULL, "vpu_clk", vpu_clk[0]),
+ _REGISTER_CLOCK(NULL, "vpu_core_clk", vpu_clk[1]),
+ _REGISTER_CLOCK(NULL, "nfc_clk", emi_enfc_clk),
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu1_clk", ipu_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu1_di0_clk", ipu_di_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu1_di1_clk", ipu_di_clk[1]),
+ _REGISTER_CLOCK(NULL, "csi_mclk1", csi0_clk),
+ _REGISTER_CLOCK(NULL, "csi_mclk2", csi1_clk),
+ _REGISTER_CLOCK(NULL, "tve_clk", tve_clk),
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk[0]),
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk[0]),
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk[0]),
+ _REGISTER_CLOCK(NULL, "i2c_clk", i2c_clk[0]),
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]),
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk[0]),
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk[0]),
+ _REGISTER_CLOCK(NULL, "ssi_lp_apm_clk", ssi_lp_apm_clk),
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk[0]),
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk[0]),
+ _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk[0]),
+ _REGISTER_CLOCK(NULL, "ssi_ext1_clk", ssi_ext1_clk),
+ _REGISTER_CLOCK(NULL, "ssi_ext2_clk", ssi_ext2_clk),
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
+ _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk[0]),
+ _REGISTER_CLOCK(NULL, "usb_ahb_clk", usb_ahb_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy_clk[0]),
+ _REGISTER_CLOCK(NULL, "usb_utmi_clk", usb_utmi_clk),
+ _REGISTER_CLOCK(NULL, "usb_clk", usb_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk[0]),
+ _REGISTER_CLOCK(NULL, "emi_slow_clk", emi_slow_clk),
+ _REGISTER_CLOCK(NULL, "ddr_clk", ddr_clk),
+ _REGISTER_CLOCK(NULL, "emi_enfc_clk", emi_enfc_clk),
+ _REGISTER_CLOCK(NULL, "emi_fast_clk", emi_fast_clk),
+ _REGISTER_CLOCK(NULL, "emi_intr_clk.0", emi_intr_clk[0]),
+ _REGISTER_CLOCK(NULL, "emi_intr_clk.1", emi_intr_clk[1]),
+ _REGISTER_CLOCK(NULL, "spdif_xtal_clk", spdif_xtal_clk),
+ _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif0_clk[0]),
+ _REGISTER_CLOCK("mxc_vpu.0", NULL, vpu_clk[0]),
+ _REGISTER_CLOCK(NULL, "lpsr_clk", lpsr_clk),
+ _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk),
+ _REGISTER_CLOCK("pata_fsl", NULL, ata_clk),
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk),
+ _REGISTER_CLOCK(NULL, "sahara_clk", sahara_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpu3d_clk", gpu3d_clk),
+ _REGISTER_CLOCK(NULL, "garb_clk", garb_clk),
+ _REGISTER_CLOCK(NULL, "gpu2d_clk", gpu2d_clk),
+ _REGISTER_CLOCK("mxc_scc.0", NULL, scc_clk[0]),
+ _REGISTER_CLOCK(NULL, "cko1", cko1_clk),
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk[0]),
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk[0]),
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk),
+};
+
+static struct clk_lookup mx51_lookups[] = {
+ _REGISTER_CLOCK("mxc_i2c_hs.3", NULL, hsi2c_serial_clk),
+ _REGISTER_CLOCK("mxc_sim.0", NULL, sim_clk[0]),
+ _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif1_clk[0]),
+ _REGISTER_CLOCK(NULL, "mipi_hsp_clk", mipi_hsp_clk),
+ _REGISTER_CLOCK(NULL, "ddr_hf_clk", ddr_hf_clk),
+ _REGISTER_CLOCK("imx51-ecspi.0", NULL, cspi1_clk[0]),
+ _REGISTER_CLOCK("imx51-ecspi.1", NULL, cspi2_clk[0]),
+ _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi3_clk),
+};
+
+static struct clk_lookup mx53_lookups[] = {
+ _REGISTER_CLOCK(NULL, "pll4", pll4_sw_clk),
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk[0]),
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk[0]),
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]),
+ _REGISTER_CLOCK(NULL, "usb_phy2_clk", usb_phy_clk[1]),
+ _REGISTER_CLOCK(NULL, "ocram_clk", ocram_clk),
+ _REGISTER_CLOCK(NULL, "imx_sata_clk", sata_clk),
+ _REGISTER_CLOCK(NULL, "ieee_1588_clk", ieee_1588_clk),
+ _REGISTER_CLOCK(NULL, "ieee_rtc_clk", ieee_rtc_clk),
+ _REGISTER_CLOCK("mxc_mlb.0", NULL, mlb_clk[0]),
+ _REGISTER_CLOCK("FlexCAN.0", "can_clk", can1_clk[0]),
+ _REGISTER_CLOCK("FlexCAN.1", "can_clk", can2_clk[0]),
+ _REGISTER_CLOCK(NULL, "ldb_di0_clk", ldb_di_clk[0]),
+ _REGISTER_CLOCK(NULL, "ldb_di1_clk", ldb_di_clk[1]),
+ _REGISTER_CLOCK(NULL, "esai_clk", esai_clk[0]),
+ _REGISTER_CLOCK(NULL, "esai_ipg_clk", esai_clk[1]),
+ _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk[1]),
+ _REGISTER_CLOCK(NULL, "asrc_serial_clk", asrc_clk[0]),
+ _REGISTER_CLOCK("imx53-ecspi.0", NULL, cspi1_clk[0]),
+ _REGISTER_CLOCK("imx53-ecspi.1", NULL, cspi2_clk[0]),
+ _REGISTER_CLOCK("imx53-cspi.0", NULL, cspi3_clk),
+};
+
+static void clk_tree_init(void)
+{
+ u32 reg, dp_ctl;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* set pll1_main_clk parent */
+ pll1_main_clk.parent = &osc_clk;
+
+ /* set pll2_sw_clk parent */
+ pll2_sw_clk.parent = &osc_clk;
+
+ /* set pll3_clk parent */
+ pll3_sw_clk.parent = &osc_clk;
+
+ if (cpu_is_mx51()) {
+ dp_ctl = __raw_readl(pll1_base + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll1_main_clk.parent = &fpm_clk;
+
+ dp_ctl = __raw_readl(pll2_base + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll2_sw_clk.parent = &fpm_clk;
+
+ dp_ctl = __raw_readl(pll3_base + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll3_sw_clk.parent = &fpm_clk;
+ } else {
+ /* set pll4_clk parent */
+ pll4_sw_clk.parent = &osc_clk;
+ }
+
+ /* set emi_slow_clk parent */
+ emi_slow_clk.parent = &main_bus_clk;
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if ((reg & MXC_CCM_CBCDR_EMI_CLK_SEL) != 0)
+ emi_slow_clk.parent = &ahb_clk;
+
+ /* set ipg_perclk parent */
+ ipg_perclk.parent = &lp_apm_clk;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
+ ipg_perclk.parent = &ipg_clk;
+ } else {
+ if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
+ ipg_perclk.parent = &main_bus_clk;
+ }
+}
+
+
+int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ __iomem void *base;
+ struct clk *tclk;
+ int i = 0, j = 0, reg;
+ int op_cnt = 0;
+ u32 pll1_rate;
+
+ pll1_base = MX51_DPLL1_BASE;
+ pll2_base = MX51_DPLL2_BASE;
+ pll3_base = MX51_DPLL3_BASE;
+
+ /* Turn off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG4_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ }
+ __raw_writel(0, MXC_CCM_CCGR1);
+ __raw_writel(0, MXC_CCM_CCGR2);
+ __raw_writel(0, MXC_CCM_CCGR3);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR4);
+
+ __raw_writel(1 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG6_1_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG6_2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG7_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR5);
+
+ __raw_writel(1 << MXC_CCM_CCGRx_CG4_OFFSET, MXC_CCM_CCGR6);
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ /* Fix up clocks unique to MX51. */
+ esdhc2_clk[0].get_rate = _clk_esdhc2_get_rate;
+ esdhc2_clk[0].set_rate = _clk_esdhc2_set_rate;
+
+ clk_tree_init();
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ clk_debug_register(lookups[i].clk);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) {
+ clkdev_add(&mx51_lookups[i]);
+ clk_debug_register(mx51_lookups[i].clk);
+ }
+
+ max_axi_a_clk = MAX_AXI_A_CLK_MX51;
+ max_axi_b_clk = MAX_AXI_B_CLK_MX51;
+ max_ahb_clk = MAX_AHB_CLK_MX51;
+ max_emi_slow_clk = MAX_AHB_CLK_MX51;
+
+ /* set DDR clock parent */
+ reg = 0;
+ if (mx51_revision() >= IMX_CHIP_REVISION_2_0) {
+ reg = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_DDR_HF_SEL;
+ reg >>= MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET;
+
+ if (reg)
+ tclk = &ddr_hf_clk;
+ }
+ if (reg == 0) {
+ reg = __raw_readl(MXC_CCM_CBCMR) &
+ MXC_CCM_CBCMR_DDR_CLK_SEL_MASK;
+ reg >>= MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
+
+ if (reg == 0) {
+ tclk = &axi_a_clk;
+ } else if (reg == 1) {
+ tclk = &axi_b_clk;
+ } else if (reg == 2) {
+ tclk = &emi_slow_clk;
+ } else {
+ tclk = &ahb_clk;
+ }
+ }
+ clk_set_parent(&ddr_clk, tclk);
+
+ /*Setup the LPM bypass bits */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS_MX51
+ | MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ /* Disable the handshake with HSC block as its not
+ * initialised right now.
+ */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ clk_enable(&cpu_clk);
+
+ /* Set SDHC parents to be PLL2 */
+ clk_set_parent(&esdhc1_clk[0], &pll2_sw_clk);
+ clk_set_parent(&esdhc2_clk[0], &pll2_sw_clk);
+
+ /* set SDHC root clock as 166.25MHZ*/
+ clk_set_rate(&esdhc1_clk[0], 166250000);
+ clk_set_rate(&esdhc2_clk[0], 166250000);
+
+ /* Initialise the parents to be axi_b, parents are set to
+ * axi_a when the clocks are enabled.
+ */
+ clk_set_parent(&vpu_clk[0], &axi_a_clk);
+ clk_set_parent(&vpu_clk[1], &axi_a_clk);
+ clk_set_parent(&gpu3d_clk, &axi_a_clk);
+ clk_set_parent(&gpu2d_clk, &axi_a_clk);
+
+ /* move cspi to 24MHz */
+ clk_set_parent(&cspi_main_clk, &lp_apm_clk);
+ clk_set_rate(&cspi_main_clk, 12000000);
+ /*move the spdif0 to spdif_xtal_ckl */
+ clk_set_parent(&spdif0_clk[0], &spdif_xtal_clk);
+ /*set the SPDIF dividers to 1 */
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ /* move the spdif1 to 24MHz */
+ clk_set_parent(&spdif1_clk[0], &spdif_xtal_clk);
+ /* set the spdif1 dividers to 1 */
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ /* Move SSI clocks to SSI_LP_APM clock */
+ clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
+
+ clk_set_parent(&ssi1_clk[0], &ssi_lp_apm_clk);
+ /* set the SSI dividers to divide by 2 */
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ clk_set_parent(&ssi2_clk[0], &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ /*
+ * SSI3 has no clock divide register,
+ * we always set SSI3 parent clock to SSI1 and freq same to SSI1
+ */
+ clk_set_parent(&ssi3_clk[0], &ssi1_clk[0]);
+
+ /* Change the SSI_EXT1_CLK to be sourced from SSI1_CLK_ROOT */
+ clk_set_parent(&ssi_ext1_clk, &ssi1_clk[0]);
+ clk_set_parent(&ssi_ext2_clk, &ssi2_clk[0]);
+
+ /* move usb_phy_clk to 24MHz */
+ clk_set_parent(&usb_phy_clk[0], &osc_clk);
+
+ /* set usboh3_clk to pll2 */
+ clk_set_parent(&usboh3_clk[0], &pll2_sw_clk);
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK;
+ reg |= 4 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET;
+ reg |= 1 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ mx51_cpu_op_init();
+ /* Set the current working point. */
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ /* Update the cpu working point table based on the PLL1 freq
+ * at boot time
+ */
+ pll1_rate = clk_get_rate(&pll1_main_clk);
+ if (pll1_rate <= cpu_op_tbl[cpu_op_nr - 1].cpu_rate)
+ op_cnt = 1;
+ else if (pll1_rate <= cpu_op_tbl[1].cpu_rate &&
+ pll1_rate > cpu_op_tbl[2].cpu_rate)
+ op_cnt = cpu_op_nr - 1;
+ else
+ op_cnt = cpu_op_nr;
+
+ cpu_op_tbl[0].cpu_rate = pll1_rate;
+
+ if (op_cnt == 1) {
+ cpu_op_tbl[0] = cpu_op_tbl[cpu_op_nr - 1];
+ memset(&cpu_op_tbl[cpu_op_nr - 1], 0, sizeof(struct cpu_op));
+ memset(&cpu_op_tbl[cpu_op_nr - 2], 0, sizeof(struct cpu_op));
+ } else if (op_cnt < cpu_op_nr) {
+ for (i = 0; i < op_cnt; i++)
+ cpu_op_tbl[i] = cpu_op_tbl[i+1];
+ memset(&cpu_op_tbl[i], 0, sizeof(struct cpu_op));
+ }
+
+ if (op_cnt < cpu_op_nr) {
+ set_num_cpu_op(op_cnt);
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ }
+
+ pll1_rate = clk_get_rate(&pll1_main_clk);
+ for (j = 0; j < cpu_op_nr; j++) {
+ if ((ddr_clk.parent == &ddr_hf_clk)) {
+ /* Change the CPU podf divider based on the boot up
+ * pll1 rate.
+ */
+ cpu_op_tbl[j].cpu_podf =
+ (pll1_rate / cpu_op_tbl[j].cpu_rate)
+ - 1;
+ if (pll1_rate / (cpu_op_tbl[j].cpu_podf + 1) >
+ cpu_op_tbl[j].cpu_rate) {
+ cpu_op_tbl[j].cpu_podf++;
+ cpu_op_tbl[j].cpu_rate =
+ pll1_rate /
+ (1000 * (cpu_op_tbl[j].cpu_podf + 1));
+ cpu_op_tbl[j].cpu_rate *= 1000;
+ }
+ if (pll1_rate / (cpu_op_tbl[j].cpu_podf + 1) <
+ cpu_op_tbl[j].cpu_rate) {
+ cpu_op_tbl[j].cpu_rate = pll1_rate;
+ }
+ }
+ cpu_op_tbl[j].pll_rate = pll1_rate;
+ }
+ /* Set the current working point. */
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (clk_get_rate(&cpu_clk) == cpu_op_tbl[i].cpu_rate) {
+ cpu_curr_op = i;
+ break;
+ }
+ }
+ if (i > cpu_op_nr)
+ BUG();
+
+ clk_set_parent(&arm_axi_clk, &axi_a_clk);
+ clk_set_parent(&ipu_clk[0], &axi_b_clk);
+
+ if (uart_at_24) {
+ /* Move UART to run from lp_apm */
+ clk_set_parent(&uart_main_clk, &lp_apm_clk);
+
+ /* Set the UART dividers to divide, so the UART_CLK is 24MHz. */
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PRED_MASK;
+ reg |= (0 << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) |
+ (0 << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+ } else {
+ clk_set_parent(&uart_main_clk, &pll2_sw_clk);
+
+ /* Set the UART dividers to divide, so the UART_CLK is 66.5MHz. */
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PRED_MASK;
+ reg |= (4 << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) |
+ (1 << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+ }
+
+ clk_set_parent(&emi_slow_clk, &ahb_clk);
+ clk_set_rate(&emi_slow_clk, clk_round_rate(&emi_slow_clk, 130000000));
+
+ /* Change the NFC clock rate to be 1:4 ratio with emi clock. */
+ clk_set_rate(&emi_enfc_clk, clk_round_rate(&emi_enfc_clk,
+ (clk_get_rate(&emi_slow_clk))/4));
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk[0], MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+ MX51_MXC_INT_GPT);
+
+ return 0;
+}
+
+int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ __iomem void *base;
+ struct clk *tclk;
+ int i = 0, j = 0, reg;
+ u32 pll1_rate;
+
+ pll1_base = MX53_DPLL1_BASE;
+ pll2_base = MX53_DPLL2_BASE;
+ pll3_base = MX53_DPLL3_BASE;
+ pll4_base = MX53_DPLL4_BASE;
+
+ /* Turn off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG4_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ }
+
+ __raw_writel(0, MXC_CCM_CCGR1);
+ __raw_writel(0, MXC_CCM_CCGR2);
+ __raw_writel(0, MXC_CCM_CCGR3);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR4);
+
+ __raw_writel(1 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG6_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG7_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR5);
+
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG4_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG13_OFFSET , MXC_CCM_CCGR6);
+
+ __raw_writel(0, MXC_CCM_CCGR7);
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ usb_phy_clk[0].enable_reg = MXC_CCM_CCGR4;
+ usb_phy_clk[0].enable_shift = MXC_CCM_CCGRx_CG5_OFFSET;
+
+ ipumux1_clk.enable_reg = MXC_CCM_CCGR5;
+ ipumux1_clk.enable_shift = MXC_CCM_CCGRx_CG6_OFFSET;
+ ipumux2_clk.enable_reg = MXC_CCM_CCGR6;
+ ipumux2_clk.enable_shift = MXC_CCM_CCGRx_CG0_OFFSET;
+
+ esdhc3_clk[0].get_rate = _clk_esdhc3_get_rate;
+ esdhc3_clk[0].set_rate = _clk_sdhc3_set_rate;
+
+ vpu_clk[2].secondary = &emi_intr_clk[0];
+
+#if defined(CONFIG_USB_STATIC_IRAM) \
+ || defined(CONFIG_USB_STATIC_IRAM_PPH)
+ usboh3_clk[1].secondary = &emi_intr_clk[1];
+#endif
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ ssi2_clk[2].secondary = &emi_intr_clk[1];
+ ssi1_clk[2].secondary = &emi_intr_clk[1];
+#endif
+#ifdef CONFIG_SDMA_IRAM
+ sdma_clk[1].secondary = &emi_intr_clk[1];
+#endif
+
+ clk_tree_init();
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ clk_debug_register(lookups[i].clk);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++) {
+ clkdev_add(&mx53_lookups[i]);
+ clk_debug_register(mx53_lookups[i].clk);
+ }
+
+ clk_set_parent(&esai_clk[0], &ckih_clk);
+
+ ldb_di_clk[0].parent = ldb_di_clk[1].parent =
+ tve_clk.parent = &pll4_sw_clk;
+
+ max_axi_a_clk = MAX_AXI_A_CLK_MX53;
+ max_axi_b_clk = MAX_AXI_B_CLK_MX53;
+ max_ahb_clk = MAX_AHB_CLK_MX53;
+ max_emi_slow_clk = MAX_AHB_CLK_MX53;
+
+
+ /* set DDR clock parent */
+ reg = __raw_readl(MXC_CCM_CBCMR) &
+ MXC_CCM_CBCMR_DDR_CLK_SEL_MASK;
+ reg >>= MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
+ if (reg == 0) {
+ tclk = &axi_a_clk;
+ } else if (reg == 1) {
+ tclk = &axi_b_clk;
+ } else if (reg == 2) {
+ tclk = &emi_slow_clk;
+ } else {
+ tclk = &ahb_clk;
+ }
+ clk_set_parent(&ddr_clk, tclk);
+
+ clk_set_parent(&esdhc1_clk[2], &tmax2_clk);
+ clk_set_parent(&esdhc2_clk[0], &esdhc1_clk[0]);
+ clk_set_parent(&esdhc3_clk[0], &pll2_sw_clk);
+
+#if 0
+ /*Setup the LPM bypass bits */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+#endif
+
+ clk_enable(&cpu_clk);
+
+ clk_enable(&main_bus_clk);
+
+ /* Set AXI_B_CLK to be 200MHz */
+ clk_set_rate(&axi_b_clk, 200000000);
+
+ /* Initialise the parents to be axi_b, parents are set to
+ * axi_a when the clocks are enabled.
+ */
+
+ clk_set_parent(&vpu_clk[0], &axi_b_clk);
+ clk_set_parent(&vpu_clk[1], &axi_b_clk);
+
+ /* move cspi to 24MHz */
+ clk_set_parent(&cspi_main_clk, &lp_apm_clk);
+ clk_set_rate(&cspi_main_clk, 12000000);
+ /*move the spdif0 to spdif_xtal_ckl */
+ clk_set_parent(&spdif0_clk[0], &spdif_xtal_clk);
+ /*set the SPDIF dividers to 1 */
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ /* Move SSI clocks to SSI_LP_APM clock */
+ clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
+
+ clk_set_parent(&ssi1_clk[0], &ssi_lp_apm_clk);
+ /* set the SSI dividers to divide by 2 */
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ clk_set_parent(&ssi2_clk[0], &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ /* Change the SSI_EXT1_CLK to be sourced from PLL2 for camera */
+ clk_set_parent(&ssi_ext1_clk, &pll2_sw_clk);
+ clk_set_rate(&ssi_ext1_clk, 24000000);
+ clk_set_parent(&ssi_ext2_clk, &ssi2_clk[0]);
+
+ /* move usb_phy_clk to 24MHz */
+ clk_set_parent(&usb_phy_clk[0], &osc_clk);
+ clk_set_parent(&usb_phy_clk[1], &osc_clk);
+
+ /* set usboh3_clk to pll2 */
+ clk_set_parent(&usboh3_clk[0], &pll2_sw_clk);
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK;
+ reg |= 4 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET;
+ reg |= 1 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ /* set SDHC root clock as 200MHZ*/
+ clk_set_rate(&esdhc1_clk[0], 200000000);
+ clk_set_rate(&esdhc3_clk[0], 200000000);
+
+ /* Set the 1588 RTC input clocks as 108MHZ */
+ clk_set_parent(&ieee_rtc_clk, &pll3_sw_clk);
+ clk_set_rate(&ieee_rtc_clk, 108000000);
+
+ /* The CPU working point should be set according to part number
+ * information. But part number information is not clear now.
+ * So update the cpu working point table based on the PLL1 freq
+ * at boot time
+ */
+ pll1_rate = clk_get_rate(&pll1_main_clk);
+
+ mx53_cpu_op_init();
+ if (pll1_rate > 1000000000)
+ mx53_set_cpu_part_number(IMX53_CEC_1_2G);
+ else if (pll1_rate > 800000000)
+ mx53_set_cpu_part_number(IMX53_CEC);
+ else
+ mx53_set_cpu_part_number(IMX53_AEC);
+
+ /* Set the current working point. */
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (clk_get_rate(&cpu_clk) == cpu_op_tbl[i].cpu_rate) {
+ cpu_curr_op = i;
+ break;
+ }
+ }
+ if (i > cpu_op_nr)
+ BUG();
+
+ clk_set_parent(&arm_axi_clk, &axi_b_clk);
+ clk_set_parent(&ipu_clk[0], &axi_b_clk);
+ clk_set_parent(&gpu3d_clk, &axi_b_clk);
+ clk_set_parent(&gpu2d_clk, &axi_b_clk);
+
+ clk_set_parent(&emi_slow_clk, &ahb_clk);
+ clk_set_rate(&emi_slow_clk, clk_round_rate(&emi_slow_clk, 133333333));
+
+ clk_set_rate(&emi_enfc_clk, clk_round_rate(&emi_enfc_clk,
+ MAX_NFC_CLK));
+
+ /* set the freq of asrc_serial_clk */
+ clk_set_rate(&asrc_clk[0], clk_round_rate(&asrc_clk[0],
+ 1190000));
+
+ /* System timer */
+ mxc_timer_init(&gpt_clk[0], MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
+ MX53_INT_GPT);
+ return 0;
+}
+
+/*!
+ * Setup cpu clock based on working point.
+ * @param op cpu freq working point
+ * @return 0 on success or error code on failure.
+ */
+static int cpu_clk_set_op(int op)
+{
+ struct cpu_op *p;
+ u32 reg, pll_hfsm;
+ u32 stat;
+
+ if (op == cpu_curr_op)
+ return 0;
+
+ p = &cpu_op_tbl[op];
+
+ /*
+ * If DDR clock is sourced from PLL1, we cannot drop PLL1 freq.
+ * Use the ARM_PODF to change the freq of the core, leave the PLL1
+ * freq unchanged. Meanwhile, if pll_rate is same, use the ARM_PODF
+ * to change the freq of core
+ */
+ if ((ddr_clk.parent == &ddr_hf_clk) ||
+ (p->pll_rate == cpu_op_tbl[cpu_curr_op].pll_rate)) {
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ reg |= cpu_op_tbl[op].cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CACRR);
+ cpu_curr_op = op;
+ } else {
+ struct timespec nstimeofday;
+ struct timespec curtime;
+
+ /* Change the ARM clock to requested frequency */
+ /* First move the ARM clock to step clock which is running
+ * at 24MHz.
+ */
+
+ /* Change the source of pll1_sw_clk to be the step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ /* Stop the PLL */
+ reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL);
+ reg &= ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL);
+
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg = (reg & ~MXC_CCM_CACRR_ARM_PODF_MASK)
+ | p->cpu_podf;
+ __raw_writel(reg, MXC_CCM_CACRR);
+
+ reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL);
+ pll_hfsm = reg & MXC_PLL_DP_CTL_HFSM;
+ /* PDF and MFI */
+ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET;
+ if (pll_hfsm == 0) {
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_OP);
+ __raw_writel(p->mfd, pll1_base + MXC_PLL_DP_MFD);
+ __raw_writel(p->mfn, pll1_base + MXC_PLL_DP_MFN);
+ } else {
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_HFS_OP);
+ __raw_writel(p->mfd, pll1_base + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(p->mfn, pll1_base + MXC_PLL_DP_HFS_MFN);
+ }
+
+ reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL);
+ reg |= MXC_PLL_DP_CTL_UPEN;
+ /* Set the UPEN bits */
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL);
+ /* Forcefully restart the PLL */
+ reg |= MXC_PLL_DP_CTL_RST;
+ __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL);
+
+ /* Wait for the PLL to lock */
+ getnstimeofday(&nstimeofday);
+ do {
+ getnstimeofday(&curtime);
+ if ((curtime.tv_nsec - nstimeofday.tv_nsec) > SPIN_DELAY)
+ panic("pll1 relock failed\n");
+ stat = __raw_readl(pll1_base + MXC_PLL_DP_CTL) &
+ MXC_PLL_DP_CTL_LRF;
+ } while (!stat);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+ /* Move the PLL1 back to the pll1_main_clk */
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ cpu_curr_op = op;
+ }
+
+#if defined(CONFIG_CPU_FREQ)
+ cpufreq_trig_needed = 1;
+#endif
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/clock_mx50.c b/arch/arm/mach-mx5/clock_mx50.c
new file mode 100755
index 00000000..4d2c2b9b
--- /dev/null
+++ b/arch/arm/mach-mx5/clock_mx50.c
@@ -0,0 +1,3608 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/sdram_autogating.h>
+
+#include "crm_regs.h"
+#include "cpu_op-mx50.h"
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk apbh_dma_clk;
+static struct clk apll_clk;
+static struct clk pfd0_clk;
+static struct clk pfd1_clk;
+static struct clk pfd2_clk;
+static struct clk pfd3_clk;
+static struct clk pfd4_clk;
+static struct clk pfd5_clk;
+static struct clk pfd6_clk;
+static struct clk pfd7_clk;
+static struct clk lp_apm_clk;
+static struct clk weim_clk[];
+static struct clk ddr_clk;
+static struct clk axi_a_clk;
+static struct clk axi_b_clk;
+static struct clk gpu2d_clk;
+static int cpu_curr_op;
+static struct cpu_op *cpu_op_tbl;
+
+static void __iomem *pll1_base;
+static void __iomem *pll2_base;
+static void __iomem *pll3_base;
+void __iomem *apll_base;
+
+static int cpu_op_nr;
+extern int lp_high_freq;
+extern int lp_med_freq;
+
+void __iomem *databahn;
+
+#define UART1_DMA_ENABLE 0
+#define UART2_DMA_ENABLE 0
+#define UART3_DMA_ENABLE 0
+#define UART4_DMA_ENABLE 0
+#define UART5_DMA_ENABLE 0
+
+#define DDR_SYNC_MODE 0x30000
+#define SPIN_DELAY 1000000 /* in nanoseconds */
+#define WAIT(exp, timeout) \
+({ \
+ struct timespec nstimeofday; \
+ struct timespec curtime; \
+ int result = 1; \
+ getnstimeofday(&nstimeofday); \
+ while (!(exp)) { \
+ getnstimeofday(&curtime); \
+ if ((curtime.tv_nsec - nstimeofday.tv_nsec) > (timeout)) { \
+ result = 0; \
+ break; \
+ } \
+ } \
+ result; \
+})
+
+#define MAX_AXI_A_CLK_MX50 400000000
+#define MAX_AXI_B_CLK_MX50 200000000
+#define MAX_AHB_CLK 133333333
+#define MAX_EMI_SLOW_CLK 133000000
+
+#ifdef CONFIG_CLK_DEBUG
+#define __INIT_CLK_DEBUG(n) .name = #n,
+#else
+#define __INIT_CLK_DEBUG(n)
+#endif
+
+extern int mxc_jtag_enabled;
+extern int uart_at_24;
+extern int cpufreq_trig_needed;
+extern int low_bus_freq_mode;
+extern int med_bus_freq_mode;
+
+static int cpu_clk_set_op(int wp);
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void (*set_num_cpu_op)(int num);
+
+static struct clk esdhc3_clk[];
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 8) {
+ min_pre = (div - 1) / 64 + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div < 8) {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGRx_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq++;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq++;
+
+ return 0;
+}
+
+static int _clk_enable_inrun(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq--;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq--;
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static unsigned long _clk_round_rate_div(struct clk *clk,
+ unsigned long rate,
+ u32 max_div,
+ u32 *new_div)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div > max_div)
+ div = max_div;
+ else if (div == 0)
+ div++;
+ if (new_div != NULL)
+ *new_div = div;
+
+ return parent_rate / div;
+}
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return 0;
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux8(struct clk *parent, struct clk *m0, struct clk *m1,
+ struct clk *m2, struct clk *m3, struct clk *m4,
+ struct clk *m5, struct clk *m6, struct clk *m7)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else if (parent == m4)
+ return 4;
+ else if (parent == m5)
+ return 5;
+ else if (parent == m6)
+ return 6;
+ else if (parent == m7)
+ return 7;
+ else
+ BUG();
+
+ return 0;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return pll1_base;
+ else if (pll == &pll2_sw_clk)
+ return pll2_base;
+ else if (pll == &pll3_sw_clk)
+ return pll3_base;
+ else
+ BUG();
+
+ return NULL;
+}
+
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ __INIT_CLK_DEBUG(ckih_clk)
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ __INIT_CLK_DEBUG(ckih2_clk)
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ __INIT_CLK_DEBUG(osc_clk)
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ __INIT_CLK_DEBUG(ckil_clk)
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static int apll_enable(struct clk *clk)
+{
+ /* Set bit to flush multiple edges out of PLL vco */
+ __raw_writel(MXC_ANADIG_PLL_HOLD_RING_OFF,
+ apll_base + MXC_ANADIG_MISC_SET);
+
+ __raw_writel(MXC_ANADIG_PLL_POWERUP, apll_base + MXC_ANADIG_MISC_SET);
+
+ if (!WAIT(__raw_readl(apll_base + MXC_ANADIG_PLLCTRL)
+ & MXC_ANADIG_APLL_LOCK, 80000))
+ panic("apll_enable failed!\n");
+
+ /* Clear after relocking, then wait 10 us */
+ __raw_writel(MXC_ANADIG_PLL_HOLD_RING_OFF,
+ apll_base + MXC_ANADIG_MISC_CLR);
+
+ udelay(10);
+
+ return 0;
+}
+
+static void apll_disable(struct clk *clk)
+{
+ __raw_writel(MXC_ANADIG_PLL_POWERUP, apll_base + MXC_ANADIG_MISC_CLR);
+}
+
+static unsigned long apll_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static struct clk apll_clk = {
+ __INIT_CLK_DEBUG(apll_clk)
+ .get_rate = apll_get_rate,
+ .enable = apll_enable,
+ .disable = apll_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 18 ? 18 : frac;
+ frac = frac > 35 ? 35 : frac;
+ do_div(tmp, frac);
+ return tmp;
+}
+
+static int pfd_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 18 ? 18 : frac;
+ frac = frac > 35 ? 35 : frac;
+ /* clear clk frac bits */
+ __raw_writel(MXC_ANADIG_PFD_FRAC_MASK << clk->enable_shift,
+ apll_base + (int)clk->enable_reg + 8);
+ /* set clk frac bits */
+ __raw_writel(frac << clk->enable_shift,
+ apll_base + (int)clk->enable_reg + 4);
+
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ do_div(tmp, frac);
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+ return 0;
+}
+
+static int pfd_enable(struct clk *clk)
+{
+ int index;
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+ index = _get_mux8(clk, &pfd0_clk, &pfd1_clk, &pfd2_clk, &pfd3_clk,
+ &pfd4_clk, &pfd5_clk, &pfd6_clk, &pfd7_clk);
+ /* clear clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ apll_base + (int)clk->enable_reg + 8);
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+ return 0;
+}
+
+static void pfd_disable(struct clk *clk)
+{
+ int index;
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+ index = _get_mux8(clk, &pfd0_clk, &pfd1_clk, &pfd2_clk, &pfd3_clk,
+ &pfd4_clk, &pfd5_clk, &pfd6_clk, &pfd7_clk);
+ /* set clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ apll_base + (int)clk->enable_reg + 4);
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+}
+
+static struct clk pfd0_clk = {
+ __INIT_CLK_DEBUG(pfd0_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC0,
+ .enable_shift = MXC_ANADIG_PFD0_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd1_clk = {
+ __INIT_CLK_DEBUG(pfd1_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC0,
+ .enable_shift = MXC_ANADIG_PFD1_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd2_clk = {
+ __INIT_CLK_DEBUG(pfd2_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC0,
+ .enable_shift = MXC_ANADIG_PFD2_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd3_clk = {
+ __INIT_CLK_DEBUG(pfd3_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC0,
+ .enable_shift = MXC_ANADIG_PFD3_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd4_clk = {
+ __INIT_CLK_DEBUG(pfd4_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC1,
+ .enable_shift = MXC_ANADIG_PFD4_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd5_clk = {
+ __INIT_CLK_DEBUG(pfd5_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC1,
+ .enable_shift = MXC_ANADIG_PFD5_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd6_clk = {
+ __INIT_CLK_DEBUG(pfd6_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC1,
+ .enable_shift = MXC_ANADIG_PFD6_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk pfd7_clk = {
+ __INIT_CLK_DEBUG(pfd7_clk)
+ .parent = &apll_clk,
+ .enable_reg = (void *)MXC_ANADIG_FRAC1,
+ .enable_shift = MXC_ANADIG_PFD7_FRAC_OFFSET,
+ .set_rate = pfd_set_rate,
+ .round_rate = pfd_round_rate,
+ .enable = pfd_enable,
+ .disable = pfd_disable,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_pll_get_rate(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ void __iomem *pllbase;
+ s64 temp;
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * clk_get_rate(clk->parent);
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, reg1;
+ void __iomem *pllbase;
+
+ long mfi, pdf, mfn, mfd = 999999;
+ s64 temp64;
+ unsigned long quad_parent_rate;
+ unsigned long pll_hfsm, dp_ctl;
+
+ pllbase = _get_pll_base(clk);
+
+ quad_parent_rate = 4 * clk_get_rate(clk->parent);
+ pdf = mfi = -1;
+ while (++pdf < 16 && mfi < 5)
+ mfi = rate * (pdf+1) / quad_parent_rate;
+ if (mfi > 15)
+ return -1;
+ pdf--;
+
+ temp64 = rate*(pdf+1) - quad_parent_rate*mfi;
+ do_div(temp64, quad_parent_rate/1000000);
+ mfn = (long)temp64;
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ /* use dpdck0_2 */
+ __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ if (pll_hfsm == 0) {
+ reg = mfi<<4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+ } else {
+ reg = mfi<<4 | pdf;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+ __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+ __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ /* If auto restart is disabled, restart the PLL and
+ * wait for it to lock.
+ */
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ if (reg & MXC_PLL_DP_CTL_UPEN) {
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CONFIG);
+ if (!(reg & MXC_PLL_DP_CONFIG_AREN)) {
+ reg1 = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ reg1 |= MXC_PLL_DP_CTL_RST;
+ __raw_writel(reg1, pllbase + MXC_PLL_DP_CTL);
+ }
+ /* Wait for lock */
+ if (!WAIT(__raw_readl(pllbase + MXC_PLL_DP_CTL)
+ & MXC_PLL_DP_CTL_LRF, SPIN_DELAY))
+ panic("pll_set_rate: pll relock failed\n");
+ }
+ return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+
+ if (reg & MXC_PLL_DP_CTL_UPEN)
+ return 0;
+
+ reg |= MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ if (!WAIT(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF,
+ SPIN_DELAY))
+ panic("pll relock failed\n");
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static struct clk pll1_main_clk = {
+ __INIT_CLK_DEBUG(pll1_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll_get_rate,
+ .set_rate = _clk_pll_set_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set the step_clk parent to be lp_apm, to save power. */
+ mux = _get_mux(&lp_apm_clk, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ if (parent == &lp_apm_clk) {
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ } else {
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+
+ }
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static unsigned long _clk_pll1_sw_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ div = 1;
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+/* pll1 switch clock */
+static struct clk pll1_sw_clk = {
+ __INIT_CLK_DEBUG(pll1_sw_clk)
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = _clk_pll1_sw_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll2_sw_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ } else {
+ reg = (reg & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL);
+ reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+/* same as pll2_main_clk. These two clocks should always be the same */
+static struct clk pll2_sw_clk = {
+ __INIT_CLK_DEBUG(pll2_sw_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll_set_rate,
+ .set_parent = _clk_pll2_sw_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ __INIT_CLK_DEBUG(pll3_sw_clk)
+ .parent = &osc_clk,
+ .set_rate = _clk_pll_set_rate,
+ .get_rate = _clk_pll_get_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ else if (parent == &apll_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk lp_apm_clk = {
+ __INIT_CLK_DEBUG(lp_apm_clk)
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_arm_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 i;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+ if (i >= cpu_op_nr)
+ return -EINVAL;
+ cpu_clk_set_op(i);
+
+ return 0;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 i;
+ u32 wp;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+
+ if (i > cpu_op_nr)
+ wp = 0;
+
+ return cpu_op_tbl[wp].cpu_rate;
+}
+
+
+static struct clk cpu_clk = {
+ __INIT_CLK_DEBUG(cpu_clk)
+ .parent = &pll1_sw_clk,
+ .get_rate = _clk_arm_get_rate,
+ .set_rate = _clk_cpu_set_rate,
+ .round_rate = _clk_cpu_round_rate,
+};
+
+/* TODO: Need to sync with GPC to determine if DVFS is in place so that
+ * the DVFS_PODF divider can be applied in CDCR register.
+ */
+static unsigned long _clk_main_bus_get_rate(struct clk *clk)
+{
+ u32 div = 0;
+
+ if (med_bus_freq_mode)
+ div = (__raw_readl(MXC_CCM_CDCR) & 0x3);
+ return clk_get_rate(clk->parent) / (div + 1);
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CBCDR) & ~MX50_CCM_CBCDR_PERIPH_CLK_SEL_MASK;
+ reg |= (mux << MX50_CCM_CBCDR_PERIPH_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ __INIT_CLK_DEBUG(main_bus_clk)
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+ .get_rate = _clk_main_bus_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_axi_a_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_A_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_A_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_axi_a_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_A_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_AXI_A_PODF_BUSY), SPIN_DELAY))
+ panic("pll _clk_axi_a_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_axi_a_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+
+ return parent_rate / div;
+}
+
+
+static struct clk axi_a_clk = {
+ __INIT_CLK_DEBUG(axi_a_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_axi_a_get_rate,
+ .set_rate = _clk_axi_a_set_rate,
+ .round_rate = _clk_axi_a_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_axi_b_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_B_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_B_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_axi_b_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_B_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_AXI_B_PODF_BUSY), SPIN_DELAY))
+ panic("_clk_axi_b_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_axi_b_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+
+ return parent_rate / div;
+}
+
+
+static struct clk axi_b_clk = {
+ __INIT_CLK_DEBUG(axi_b_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_axi_b_get_rate,
+ .set_rate = _clk_axi_b_set_rate,
+ .round_rate = _clk_axi_b_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY),
+ SPIN_DELAY))
+ panic("_clk_ahb_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (parent_rate / div > MAX_AHB_CLK)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+
+static struct clk ahb_clk = {
+ __INIT_CLK_DEBUG(ahb_clk)
+ .parent = &main_bus_clk,
+ .get_rate = _clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_max_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with MAX when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+
+static void _clk_max_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable_inwait(clk);
+
+ /* No Handshake with MAX when LPM is entered as its disabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk ahb_max_clk = {
+ __INIT_CLK_DEBUG(ahb_max_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+};
+
+static struct clk ahbmux1_clk = {
+ __INIT_CLK_DEBUG(ahbmux1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static unsigned long _clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk ipg_clk = {
+ __INIT_CLK_DEBUG(ipg_clk)
+ .parent = &ahb_clk,
+ .get_rate = _clk_ipg_get_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static unsigned long _clk_ipg_per_get_rate(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk) {
+ return clk_get_rate(&ipg_clk);
+ }
+ BUG();
+ return 0;
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL);
+ if (mux == 2) {
+ reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ if (mux == 0)
+ reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ else
+ reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk ipg_perclk = {
+ __INIT_CLK_DEBUG(ipg_perclk)
+ .parent = &lp_apm_clk,
+ .get_rate = _clk_ipg_per_get_rate,
+ .set_parent = _clk_ipg_per_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ipmux1_clk = {
+ __INIT_CLK_DEBUG(ipmux1_clk)
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk ipmux2_clk = {
+ __INIT_CLK_DEBUG(ipmux2_clk)
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_sys_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CLK_SYS);
+ reg &= ~(MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK |
+ MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK);
+ if (__raw_readl(MXC_CCM_CLKSEQ_BYPASS) & 0x1)
+ reg |= MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK;
+ else
+ reg |= MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_CLK_SYS);
+ return 0;
+}
+
+static void _clk_sys_clk_disable(struct clk *clk)
+{
+ u32 reg, reg1;
+
+ reg1 = (__raw_readl(databahn + DATABAHN_CTL_REG55))
+ & DDR_SYNC_MODE;
+ reg = __raw_readl(MXC_CCM_CLK_SYS);
+ reg &= ~(MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK |
+ MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK);
+ if (__raw_readl(MXC_CCM_CLKSEQ_BYPASS) & 0x1)
+ reg |= 1 << MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_OFFSET;
+ else {
+ /* If DDR is sourced from SYS_CLK (in Sync mode), we cannot
+ * gate its clock when ARM is in wait if the DDR is not in
+ * self refresh.
+ */
+ if (reg1 == DDR_SYNC_MODE)
+ reg |= 3 << MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_OFFSET;
+ else
+ reg |= 1 << MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_OFFSET;
+ }
+ __raw_writel(reg, MXC_CCM_CLK_SYS);
+}
+
+static struct clk sys_clk = {
+ __INIT_CLK_DEBUG(sys_clk)
+ .enable = _clk_sys_clk_enable,
+ .disable = _clk_sys_clk_disable,
+};
+
+
+static int _clk_weim_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if (parent == &ahb_clk)
+ reg |= MX50_CCM_CBCDR_WEIM_CLK_SEL;
+ else if (parent == &main_bus_clk)
+ reg &= ~MX50_CCM_CBCDR_WEIM_CLK_SEL;
+ else
+ BUG();
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ return 0;
+}
+
+static int _clk_weim_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_EMI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_EMI_PODF_BUSY),
+ SPIN_DELAY))
+ panic("_clk_emi_slow_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_weim_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return parent_rate / div;
+}
+
+static struct clk weim_clk[] = {
+ {
+ __INIT_CLK_DEBUG(weim_clk_0)
+ .parent = &main_bus_clk,
+ .set_parent = _clk_weim_set_parent,
+ .set_rate = _clk_weim_set_rate,
+ .round_rate = _clk_weim_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+ .flags = RATE_PROPAGATES,
+ .secondary = &weim_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(weim_clk_1)
+ .parent = &ipg_clk,
+ .secondary = &sys_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .disable = _clk_disable_inwait,
+ }
+};
+
+static int _clk_ocram_enable(struct clk *clk)
+{
+ return 0;
+}
+
+static void _clk_ocram_disable(struct clk *clk)
+{
+}
+
+static struct clk ocram_clk = {
+ __INIT_CLK_DEBUG(ocram_clk)
+ .parent = &sys_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_ocram_enable,
+ .disable = _clk_ocram_disable,
+};
+
+static struct clk aips_tz1_clk = {
+ __INIT_CLK_DEBUG(aips_tz1_clk)
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ __INIT_CLK_DEBUG(aips_tz2_clk)
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk gpc_dvfs_clk = {
+ __INIT_CLK_DEBUG(gpc_dvfs_clk)
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_sdma_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with SDMA when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_sdma_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable(clk);
+ /* No handshake with SDMA as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk sdma_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sdma_clk_0)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .enable = _clk_sdma_enable,
+ .disable = _clk_sdma_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(sdma_clk_1)
+ .parent = &ipg_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &ddr_clk,
+#endif
+ },
+};
+
+static struct clk spba_clk = {
+ __INIT_CLK_DEBUG(spba_clk)
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_uart_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent)/(prediv * podf) ;
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk uart_main_clk = {
+ __INIT_CLK_DEBUG(uart_main_clk)
+ .parent = &pll2_sw_clk,
+ .get_rate = _clk_uart_get_rate,
+ .set_parent = _clk_uart_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk uart1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart1_clk_0)
+ .id = 0,
+ .parent = &uart_main_clk,
+ .secondary = &uart1_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART1_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+#if UART1_DMA_ENABLE
+ .secondary = &aips_tz1_clk,
+#endif
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart2_clk_0)
+ .id = 1,
+ .parent = &uart_main_clk,
+ .secondary = &uart2_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART2_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+#if UART2_DMA_ENABLE
+ .secondary = &aips_tz1_clk,
+#endif
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart3_clk_0)
+ .id = 2,
+ .parent = &uart_main_clk,
+ .secondary = &uart3_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART3_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart3_clk_1)
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart4_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart4_clk_0)
+ .id = 3,
+ .parent = &uart_main_clk,
+ .secondary = &uart4_clk[1],
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART4_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart4_clk_1)
+ .id = 3,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart5_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart5_clk_0)
+ .id = 4,
+ .parent = &uart_main_clk,
+ .secondary = &uart5_clk[1],
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+#if UART5_DMA_ENABLE
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#endif
+ },
+ {
+ __INIT_CLK_DEBUG(uart5_clk_1)
+ .id = 4,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpt_clk_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(gpt_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(gpt_clk_2)
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm1_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm1_clk_2)
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_0)
+ .parent = &ipg_perclk,
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm2_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm2_clk_2)
+ .id = 1,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk i2c_clk[] = {
+ {
+ __INIT_CLK_DEBUG(i2c_clk_0)
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_1)
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_2)
+ .id = 2,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_cspi_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk cspi_main_clk = {
+ __INIT_CLK_DEBUG(cspi_main_clk)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_cspi_get_rate,
+ .set_parent = _clk_cspi_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cspi1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(cspi1_clk_0)
+ .id = 0,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi1_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(cspi1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(cspi2_clk_0)
+ .id = 1,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi2_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(cspi2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable_inrun, /*Active only when ARM is running. */
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi3_clk = {
+ __INIT_CLK_DEBUG(cspi3_clk)
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &aips_tz2_clk,
+};
+
+static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &ckih_clk, &lp_apm_clk, &ckih2_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_lp_apm_clk = {
+ __INIT_CLK_DEBUG(ssi_lp_apm_clk)
+ .parent = &ckih_clk,
+ .set_parent = _clk_ssi_lp_apm_set_parent,
+};
+
+static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi1_set_parent,
+ .secondary = &ssi1_clk[1],
+ .get_rate = _clk_ssi1_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &ssi1_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi1_clk_2)
+ .id = 0,
+ .parent = &aips_tz2_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &ddr_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_0)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi2_set_parent,
+ .secondary = &ssi2_clk[1],
+ .get_rate = _clk_ssi2_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &ssi2_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ssi2_clk_2)
+ .id = 1,
+ .parent = &spba_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &ddr_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi_ext1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ u32 div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET) + 1;
+ div = prediv * podf;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ssi_ext1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK |
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi1_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_ssi_ext1_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static struct clk ssi_ext1_clk = {
+ __INIT_CLK_DEBUG(ssi_ext1_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext1_set_parent,
+ .set_rate = _clk_ssi_ext1_set_rate,
+ .round_rate = _clk_ssi_ext1_round_rate,
+ .get_rate = _clk_ssi_ext1_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_ssi_ext2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+ u32 div = 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET) + 1;
+ div = prediv * podf;
+ }
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi2_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext2_clk = {
+ __INIT_CLK_DEBUG(ssi_ext2_clk)
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext2_set_parent,
+ .get_rate = _clk_ssi_ext2_get_rate,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax2_clk = {
+ __INIT_CLK_DEBUG(tmax2_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk usb_ahb_clk = {
+ __INIT_CLK_DEBUG(usb_ahb_clk)
+ .parent = &ipg_clk,
+ .secondary = &ddr_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk usb_phy_clk[] = {
+ {
+ __INIT_CLK_DEBUG(usb_phy_clk_0)
+ .id = 0,
+ .parent = &osc_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(usb_phy_clk_1)
+ .id = 1,
+ .parent = &osc_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ }
+};
+
+static struct clk esdhc_dep_clks = {
+ __INIT_CLK_DEBUG(esdhc_dep_clks)
+ .parent = &spba_clk,
+ .secondary = &ddr_clk,
+};
+
+static unsigned long _clk_esdhc1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = reg & ~MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_MASK;
+ reg |= mux << MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+
+static int _clk_esdhc1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk esdhc1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_0)
+ .id = 0,
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_esdhc1_set_parent,
+ .get_rate = _clk_esdhc1_get_rate,
+ .set_rate = _clk_esdhc1_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc1_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_1)
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &esdhc1_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc1_clk_2)
+ .id = 0,
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+
+};
+
+static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MX50_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ else if (parent == &esdhc3_clk[0])
+ reg |= MX50_CCM_CSCMR1_ESDHC2_CLK_SEL;
+ else
+ BUG();
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk esdhc2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_0)
+ .id = 1,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc2_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc2_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &esdhc2_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc2_clk_2)
+ .id = 0,
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ mux = _get_mux8(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &lp_apm_clk, &pfd0_clk,
+ &pfd1_clk, &pfd4_clk, &osc_clk);
+ reg = reg & ~MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_MASK;
+ reg |= mux << MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_esdhc3_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_esdhc3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if ((parent_rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set sdhc1 clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR1) &
+ ~(MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+
+static struct clk esdhc3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_0)
+ .id = 2,
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_esdhc3_set_parent,
+ .get_rate = _clk_esdhc3_get_rate,
+ .set_rate = _clk_esdhc3_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_1)
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &esdhc3_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc3_clk_2)
+ .id = 0,
+ .parent = &ahb_max_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MX50_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc3_clk[0])
+ reg |= MX50_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ BUG();
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc4_clk[] = {
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_0)
+ .id = 3,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc4_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc4_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_1)
+ .id = 3,
+ .parent = &ipg_clk,
+ .secondary = &esdhc4_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(esdhc4_clk_2)
+ .id = 0,
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CLK_DDR);
+ if (parent == &pfd0_clk)
+ reg |= MXC_CCM_CLK_DDR_DDR_PFD_SEL;
+ else if (parent == &pll1_sw_clk)
+ reg &= ~MXC_CCM_CLK_DDR_DDR_PFD_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CLK_DDR);
+ return 0;
+}
+
+static unsigned long _clk_ddr_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CLK_DDR);
+ div = (reg & MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK) >>
+ MXC_CCM_CLK_DDR_DDR_DIV_PLL_OFFSET;
+ if (div)
+ return clk_get_rate(clk->parent) / div;
+
+ return 0;
+}
+
+static int _clk_ddr_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ reg = (__raw_readl(databahn + DATABAHN_CTL_REG55)) &
+ DDR_SYNC_MODE;
+ if (reg != DDR_SYNC_MODE) {
+ reg = __raw_readl(MXC_CCM_CLK_DDR);
+ reg |= MXC_CCM_CLK_DDR_DDR_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_CLK_DDR);
+ }
+ return 0;
+}
+
+static void _clk_ddr_disable(struct clk *clk)
+{
+ _clk_disable_inwait(clk);
+}
+
+
+static struct clk ddr_clk = {
+ __INIT_CLK_DEBUG(ddr_clk)
+ .parent = &pll1_sw_clk,
+ .secondary = &sys_clk,
+ .set_parent = _clk_ddr_set_parent,
+ .get_rate = _clk_ddr_get_rate,
+ .enable = _clk_ddr_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_ddr_disable,
+};
+
+static unsigned long _clk_pgc_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET;
+ div = 1 >> div;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static struct clk pgc_clk = {
+ __INIT_CLK_DEBUG(pgc_clk)
+ .parent = &ipg_clk,
+ .get_rate = _clk_pgc_get_rate,
+};
+
+static unsigned long _clk_usb_get_rate(struct clk *clk)
+{
+ return 60000000;
+}
+
+/*usb OTG clock */
+static struct clk usb_clk = {
+ __INIT_CLK_DEBUG(usb_clk)
+ .get_rate = _clk_usb_get_rate,
+};
+
+static struct clk rtc_clk = {
+ __INIT_CLK_DEBUG(rtc_clk)
+ .parent = &ckil_clk,
+ .secondary = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .disable = _clk_disable,
+};
+
+struct clk rng_clk = {
+ __INIT_CLK_DEBUG(rng_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ __INIT_CLK_DEBUG(owire_clk)
+ .parent = &ipg_perclk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk fec_clk[] = {
+ {
+ __INIT_CLK_DEBUG(fec_clk_0)
+ .parent = &ipg_clk,
+ .secondary = &fec_clk[1],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(fec_clk_1)
+ .parent = &aips_tz2_clk,
+ .secondary = &ddr_clk,
+ },
+};
+
+static int gpmi_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_GPMI);
+ reg |= MXC_CCM_GPMI_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_GPMI);
+ _clk_enable(clk);
+ return 0;
+}
+
+static void gpmi_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_GPMI);
+ reg &= ~MXC_CCM_GPMI_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_GPMI);
+ _clk_disable(clk);
+}
+
+static int bch_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_BCH);
+ reg |= MXC_CCM_BCH_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_BCH);
+ _clk_enable(clk);
+ return 0;
+}
+
+static void bch_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_BCH);
+ reg &= ~MXC_CCM_BCH_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_BCH);
+ _clk_disable(clk);
+}
+
+static int gpmi_set_parent(struct clk *clk, struct clk *parent)
+{
+ /* Setting for ONFI nand which need PLL1(800MHZ) */
+ if (parent == &pll1_main_clk) {
+ u32 reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS);
+
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_GPMI_CLK_SEL_MASK) |
+ (0x2 << MXC_CCM_CLKSEQ_BYPASS_BYPASS_GPMI_CLK_SEL_OFFSET);
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_BCH_CLK_SEL_MASK) |
+ (0x2 << MXC_CCM_CLKSEQ_BYPASS_BYPASS_BCH_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS);
+
+ /* change to the new Parent */
+ clk->parent = parent;
+ } else
+ printk(KERN_WARNING "You should not call the %s\n", __func__);
+ return 0;
+}
+
+static int gpmi_set_rate(struct clk *clk, unsigned long rate)
+{
+ /* Setting for ONFI nand which in different mode */
+ if (clk->parent == &pll1_main_clk) {
+ u32 value;
+ u32 reg;
+
+ value = clk_get_rate(clk->parent);
+ value /= rate;
+ value /= 2; /* HW_GPMI_CTRL1's GPMI_CLK_DIV2_EN will be set */
+
+ /* set GPMI clock */
+ reg = __raw_readl(MXC_CCM_GPMI);
+ reg = (reg & ~MXC_CCM_GPMI_CLK_DIV_MASK) | value;
+ __raw_writel(reg, MXC_CCM_GPMI);
+
+ /* set BCH clock */
+ reg = __raw_readl(MXC_CCM_BCH);
+ reg = (reg & ~MXC_CCM_BCH_CLK_DIV_MASK) | value;
+ __raw_writel(reg, MXC_CCM_BCH);
+ } else
+ printk(KERN_WARNING "You should not call the %s\n", __func__);
+ return 0;
+}
+
+static struct clk gpmi_nfc_clk[] = {
+ { /* gpmi_io_clk */
+ __INIT_CLK_DEBUG(gpmi_io_clk)
+ .parent = &osc_clk,
+ .secondary = &gpmi_nfc_clk[1],
+ .set_parent = gpmi_set_parent,
+ .set_rate = gpmi_set_rate,
+ .enable = gpmi_clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .disable = gpmi_clk_disable,
+ },
+ { /* gpmi_apb_clk */
+ __INIT_CLK_DEBUG(gpmi_apb_clk)
+ .parent = &apbh_dma_clk,
+ .secondary = &gpmi_nfc_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .disable = _clk_disable,
+ },
+ { /* bch_clk */
+ __INIT_CLK_DEBUG(gpmi_bch_clk)
+ .parent = &osc_clk,
+ .secondary = &gpmi_nfc_clk[3],
+ .enable = bch_clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = bch_clk_disable,
+ },
+ { /* bch_apb_clk */
+ __INIT_CLK_DEBUG(gpmi_bch_apb_clk)
+ .parent = &apbh_dma_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_ocotp_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk ocotp_clk = {
+ __INIT_CLK_DEBUG(ocotp_clk)
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+ .get_rate = _clk_ocotp_get_rate,
+};
+
+static int _clk_gpu2d_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &weim_clk[0], &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu2d_clk = {
+ __INIT_CLK_DEBUG(gpu2d_clk)
+ .parent = &axi_a_clk,
+ .secondary = &ddr_clk,
+ .set_parent = _clk_gpu2d_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk apbh_dma_clk = {
+ __INIT_CLK_DEBUG(apbh_dma_clk)
+ .parent = &ahb_clk,
+ .secondary = &ddr_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+};
+
+struct clk dcp_clk = {
+ __INIT_CLK_DEBUG(dcp_clk)
+ .parent = &ahb_clk,
+ .secondary = &apbh_dma_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR7,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_display_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS);
+ mux = _get_mux(parent, &osc_clk, &pfd2_clk, &pll1_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS);
+
+ return 0;
+}
+
+static unsigned long _clk_display_axi_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(MXC_CCM_DISPLAY_AXI);
+ div &= MXC_CCM_DISPLAY_AXI_DIV_MASK;
+ if (div == 0) { /* gated off */
+ return clk_get_rate(clk->parent);
+ } else {
+ return clk_get_rate(clk->parent) / div;
+ }
+}
+
+static unsigned long _clk_display_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 max_div = (2 << 6) - 1;
+ return _clk_round_rate_div(clk, rate, max_div, NULL);
+}
+
+static int _clk_display_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div, max_div;
+ u32 reg;
+
+ max_div = (2 << 6) - 1;
+ _clk_round_rate_div(clk, rate, max_div, &new_div);
+
+ reg = __raw_readl(MXC_CCM_DISPLAY_AXI);
+ reg &= ~MXC_CCM_DISPLAY_AXI_DIV_MASK;
+ reg |= new_div << MXC_CCM_DISPLAY_AXI_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_DISPLAY_AXI);
+
+ while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_DISPLAY_AXI_BUSY)
+ ;
+ return 0;
+}
+
+static struct clk display_axi_clk = {
+ __INIT_CLK_DEBUG(display_axi_clk)
+ .parent = &osc_clk,
+ .secondary = &apbh_dma_clk,
+ .set_parent = _clk_display_axi_set_parent,
+ .get_rate = _clk_display_axi_get_rate,
+ .set_rate = _clk_display_axi_set_rate,
+ .round_rate = _clk_display_axi_round_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_DISPLAY_AXI,
+ .enable_shift = MXC_CCM_DISPLAY_AXI_CLKGATE_OFFSET,
+ .flags = RATE_PROPAGATES | AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_pxp_axi_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Set the auto-slow bits */
+ reg = __raw_readl(MXC_CCM_DISPLAY_AXI);
+ reg |= (MXC_CCM_DISPLAY_AXI_PXP_ASM_EN);
+ reg |= (5 << MXC_CCM_DISPLAY_AXI_PXP_ASM_DIV_OFFSET);
+ __raw_writel(reg, MXC_CCM_DISPLAY_AXI);
+
+ return 0;
+}
+
+static void _clk_pxp_axi_disable(struct clk *clk)
+{
+ u32 reg;
+
+ /* clear the auto-slow bits */
+ reg = __raw_readl(MXC_CCM_DISPLAY_AXI);
+ reg &= ~MXC_CCM_DISPLAY_AXI_PXP_ASM_EN;
+ __raw_writel(reg, MXC_CCM_DISPLAY_AXI);
+
+ _clk_disable(clk);
+}
+
+
+/* TODO: check Auto-Slow Mode */
+static struct clk pxp_axi_clk = {
+ __INIT_CLK_DEBUG(pxp_axi_clk)
+ .parent = &display_axi_clk,
+ .enable = _clk_pxp_axi_enable,
+ .disable = _clk_pxp_axi_disable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk elcdif_axi_clk = {
+ __INIT_CLK_DEBUG(elcdif_axi_clk)
+ .parent = &display_axi_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_elcdif_pix_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS);
+ mux = _get_mux(parent, &osc_clk, &pfd6_clk, &pll1_sw_clk, &ckih_clk);
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS);
+
+ return 0;
+}
+
+static unsigned long _clk_elcdif_pix_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_ELCDIFPIX);
+ prediv = ((reg & MXC_CCM_ELCDIFPIX_CLK_PRED_MASK) >>
+ MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_ELCDIFPIX_CLK_PODF_MASK) >>
+ MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static unsigned long _clk_elcdif_pix_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 max_div = (2 << 12) - 1;
+ return _clk_round_rate_div(clk, rate, max_div, NULL);
+}
+
+static int _clk_elcdif_pix_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div, max_div;
+ u32 reg;
+
+ max_div = (2 << 12) - 1;
+ _clk_round_rate_div(clk, rate, max_div, &new_div);
+
+ reg = __raw_readl(MXC_CCM_ELCDIFPIX);
+ /* Pre-divider set to 1 - only use PODF for clk dividing */
+ reg &= ~MXC_CCM_ELCDIFPIX_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET;
+ reg &= ~MXC_CCM_ELCDIFPIX_CLK_PODF_MASK;
+ reg |= new_div << MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_ELCDIFPIX);
+
+ return 0;
+}
+
+static int _clk_elcdif_pix_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ reg = __raw_readl(MXC_CCM_ELCDIFPIX);
+ reg |= 0x3 << MXC_CCM_ELCDIFPIX_CLKGATE_OFFSET;
+ __raw_writel(reg, MXC_CCM_ELCDIFPIX);
+ return 0;
+}
+
+static void _clk_elcdif_pix_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_ELCDIFPIX);
+ reg &= ~MXC_CCM_ELCDIFPIX_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_ELCDIFPIX);
+ _clk_disable(clk);
+}
+
+static struct clk elcdif_pix_clk = {
+ __INIT_CLK_DEBUG(elcdif_pix_clk)
+ .parent = &osc_clk,
+ .secondary = &ddr_clk,
+ .enable = _clk_elcdif_pix_enable,
+ .disable = _clk_elcdif_pix_disable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .set_parent = _clk_elcdif_pix_set_parent,
+ .get_rate = _clk_elcdif_pix_get_rate,
+ .round_rate = _clk_elcdif_pix_round_rate,
+ .set_rate = _clk_elcdif_pix_set_rate,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_epdc_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS);
+ mux = _get_mux(parent, &osc_clk, &pfd3_clk, &pll1_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS);
+
+ return 0;
+}
+
+static unsigned long _clk_epdc_axi_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(MXC_CCM_EPDC_AXI);
+ div &= MXC_CCM_EPDC_AXI_DIV_MASK;
+ if (div == 0) { /* gated off */
+ return clk_get_rate(clk->parent);
+ } else {
+ return clk_get_rate(clk->parent) / div;
+ }
+}
+
+static unsigned long _clk_epdc_axi_round_rate_div(struct clk *clk,
+ unsigned long rate,
+ u32 *new_div)
+{
+ u32 div, max_div;
+
+ max_div = (2 << 6) - 1;
+ div = DIV_ROUND_UP(clk_get_rate(clk->parent), rate);
+ if (div > max_div)
+ div = max_div;
+ else if (div == 0)
+ div++;
+ if (new_div != NULL)
+ *new_div = div;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long _clk_epdc_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ return _clk_epdc_axi_round_rate_div(clk, rate, NULL);
+}
+
+static int _clk_epdc_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div;
+ u32 reg;
+
+ _clk_epdc_axi_round_rate_div(clk, rate, &new_div);
+
+ reg = __raw_readl(MXC_CCM_EPDC_AXI);
+ reg &= ~MXC_CCM_EPDC_AXI_DIV_MASK;
+ reg |= new_div << MXC_CCM_EPDC_AXI_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_EPDC_AXI);
+
+ while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_EPDC_AXI_BUSY)
+ ;
+
+ return 0;
+}
+
+static int _clk_epdc_axi_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ reg = __raw_readl(MXC_CCM_EPDC_AXI);
+ reg |= MXC_CCM_EPDC_AXI_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_EPDC_AXI);
+
+ /* Set the auto-slow bits */
+ reg = __raw_readl(MXC_CCM_EPDC_AXI);
+ reg |= (MXC_CCM_EPDC_AXI_ASM_EN);
+ reg |= (5 << MXC_CCM_EPDC_AXI_ASM_DIV_OFFSET);
+ __raw_writel(reg, MXC_CCM_EPDC_AXI);
+
+ return 0;
+}
+
+static void _clk_epdc_axi_disable(struct clk *clk)
+{
+ u32 reg;
+
+ /* clear the auto-slow bits */
+ reg = __raw_readl(MXC_CCM_EPDC_AXI);
+ reg &= ~MXC_CCM_EPDC_AXI_ASM_EN;
+ __raw_writel(reg, MXC_CCM_EPDC_AXI);
+
+ reg = __raw_readl(MXC_CCM_EPDC_AXI);
+ reg &= ~MXC_CCM_EPDC_AXI_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_EPDC_AXI);
+ _clk_disable(clk);
+}
+
+/* TODO: check Auto-Slow Mode */
+static struct clk epdc_axi_clk = {
+ __INIT_CLK_DEBUG(epdc_axi_clk)
+ .parent = &osc_clk,
+ .secondary = &apbh_dma_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .set_parent = _clk_epdc_axi_set_parent,
+ .get_rate = _clk_epdc_axi_get_rate,
+ .set_rate = _clk_epdc_axi_set_rate,
+ .round_rate = _clk_epdc_axi_round_rate,
+ .enable = _clk_epdc_axi_enable,
+ .disable = _clk_epdc_axi_disable,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+
+static int _clk_epdc_pix_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CLKSEQ_BYPASS);
+ mux = _get_mux(parent, &osc_clk, &pfd5_clk, &pll1_sw_clk, &ckih_clk);
+ reg = (reg & ~MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLKSEQ_BYPASS);
+
+ return 0;
+}
+
+static unsigned long _clk_epdc_pix_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(MXC_CCM_EPDCPIX);
+ div &= MXC_CCM_EPDC_PIX_CLK_PODF_MASK;
+ if (div == 0) { /* gated off */
+ return clk_get_rate(clk->parent);
+ } else {
+ return clk_get_rate(clk->parent) / div;
+ }
+}
+
+static unsigned long _clk_epdc_pix_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 max_div = (2 << 12) - 1;
+ return _clk_round_rate_div(clk, rate, max_div, NULL);
+}
+
+static int _clk_epdc_pix_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div, max_div;
+ u32 reg;
+
+ max_div = (2 << 12) - 1;
+ _clk_round_rate_div(clk, rate, max_div, &new_div);
+
+ reg = __raw_readl(MXC_CCM_EPDCPIX);
+ /* Pre-divider set to 1 - only use PODF for clk dividing */
+ reg &= ~MXC_CCM_EPDC_PIX_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_EPDC_PIX_CLK_PRED_OFFSET;
+ reg &= ~MXC_CCM_EPDC_PIX_CLK_PODF_MASK;
+ reg |= new_div << MXC_CCM_EPDC_PIX_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_EPDCPIX);
+
+ while (__raw_readl(MXC_CCM_CSR2) & MXC_CCM_CSR2_EPDC_PIX_BUSY)
+ ;
+
+ return 0;
+}
+
+static int _clk_epdc_pix_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ reg = __raw_readl(MXC_CCM_EPDCPIX);
+ reg |= MXC_CCM_EPDC_PIX_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_EPDCPIX);
+
+ return 0;
+}
+
+static void _clk_epdc_pix_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_EPDCPIX);
+ reg &= ~MXC_CCM_EPDC_PIX_CLKGATE_MASK;
+ __raw_writel(reg, MXC_CCM_EPDCPIX);
+ _clk_disable(clk);
+}
+
+/* TODO: check Auto-Slow Mode */
+static struct clk epdc_pix_clk = {
+ __INIT_CLK_DEBUG(epdc_pix_clk)
+ .parent = &osc_clk,
+ .secondary = &apbh_dma_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .set_parent = _clk_epdc_pix_set_parent,
+ .get_rate = _clk_epdc_pix_get_rate,
+ .set_rate = _clk_epdc_pix_set_rate,
+ .round_rate = _clk_epdc_pix_round_rate,
+ .enable = _clk_epdc_pix_enable,
+ .disable = _clk_epdc_pix_disable,
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long cko1_get_rate(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= MX50_CCM_CCOSR_CKO1_DIV_MASK;
+ reg = reg >> MX50_CCM_CCOSR_CKO1_DIV_OFFSET;
+ return clk_get_rate(clk->parent) / (reg + 1);
+}
+
+static int cko1_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg |= MX50_CCM_CCOSR_CKO1_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static void cko1_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MX50_CCM_CCOSR_CKO1_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+}
+
+static int cko1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = (parent_rate/rate - 1) & 0x7;
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MX50_CCM_CCOSR_CKO1_DIV_MASK;
+ reg |= div << MX50_CCM_CCOSR_CKO1_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long cko1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ div = div < 1 ? 1 : div;
+ div = div > 8 ? 8 : div;
+ return parent_rate / div;
+}
+
+static int cko1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg, fast;
+
+ if (parent == &cpu_clk) {
+ sel = 0;
+ fast = 1;
+ } else if (parent == &pll1_sw_clk) {
+ sel = 1;
+ fast = 1;
+ } else if (parent == &pll2_sw_clk) {
+ sel = 2;
+ fast = 1;
+ } else if (parent == &pll3_sw_clk) {
+ sel = 3;
+ fast = 1;
+ } else if (parent == &apll_clk) {
+ sel = 0;
+ fast = 0;
+ } else if (parent == &pfd0_clk) {
+ sel = 1;
+ fast = 0;
+ } else if (parent == &pfd1_clk) {
+ sel = 2;
+ fast = 0;
+ } else if (parent == &pfd2_clk) {
+ sel = 3;
+ fast = 0;
+ } else if (parent == &pfd3_clk) {
+ sel = 4;
+ fast = 0;
+ } else if (parent == &pfd4_clk) {
+ sel = 5;
+ fast = 0;
+ } else if (parent == &pfd5_clk) {
+ sel = 6;
+ fast = 0;
+ } else if (parent == &pfd6_clk) {
+ sel = 7;
+ fast = 0;
+ } else if (parent == &weim_clk[0]) {
+ sel = 10;
+ fast = 0;
+ } else if (parent == &ahb_clk) {
+ sel = 11;
+ fast = 0;
+ } else if (parent == &ipg_clk) {
+ sel = 12;
+ fast = 0;
+ } else if (parent == &ipg_perclk) {
+ sel = 13;
+ fast = 0;
+ } else if (parent == &pfd7_clk) {
+ sel = 15;
+ fast = 0;
+ } else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MX50_CCM_CCOSR_CKO1_SEL_MASK;
+ reg |= sel << MX50_CCM_CCOSR_CKO1_SEL_OFFSET;
+ if (fast)
+ reg &= ~MX50_CCM_CCOSR_CKO1_SLOW_SEL;
+ else
+ reg |= MX50_CCM_CCOSR_CKO1_SLOW_SEL;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static struct clk cko1_clk = {
+ __INIT_CLK_DEBUG(cko1_clk)
+ .parent = &pll1_sw_clk,
+ .get_rate = cko1_get_rate,
+ .enable = cko1_enable,
+ .disable = cko1_disable,
+ .set_rate = cko1_set_rate,
+ .round_rate = cko1_round_rate,
+ .set_parent = cko1_set_parent,
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ }
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "osc", osc_clk),
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk),
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk),
+ _REGISTER_CLOCK(NULL, "pll1_main_clk", pll1_main_clk),
+ _REGISTER_CLOCK(NULL, "pll1_sw_clk", pll1_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll2", pll2_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll3", pll3_sw_clk),
+ _REGISTER_CLOCK(NULL, "apll", apll_clk),
+ _REGISTER_CLOCK(NULL, "pfd0", pfd0_clk),
+ _REGISTER_CLOCK(NULL, "pfd1", pfd1_clk),
+ _REGISTER_CLOCK(NULL, "pfd2", pfd2_clk),
+ _REGISTER_CLOCK(NULL, "pfd3", pfd3_clk),
+ _REGISTER_CLOCK(NULL, "pfd4", pfd4_clk),
+ _REGISTER_CLOCK(NULL, "pfd5", pfd5_clk),
+ _REGISTER_CLOCK(NULL, "pfd6", pfd6_clk),
+ _REGISTER_CLOCK(NULL, "pfd7", pfd7_clk),
+ _REGISTER_CLOCK(NULL, "gpc_dvfs_clk", gpc_dvfs_clk),
+ _REGISTER_CLOCK(NULL, "lp_apm", lp_apm_clk),
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk),
+ _REGISTER_CLOCK(NULL, "main_bus_clk", main_bus_clk),
+ _REGISTER_CLOCK(NULL, "axi_a_clk", axi_a_clk),
+ _REGISTER_CLOCK(NULL, "axi_b_clk", axi_b_clk),
+ _REGISTER_CLOCK(NULL, "ahb_clk", ahb_clk),
+ _REGISTER_CLOCK(NULL, "ahb_max_clk", ahb_max_clk),
+ _REGISTER_CLOCK("mxc_sdma", "sdma_ahb_clk", sdma_clk[0]),
+ _REGISTER_CLOCK("mxc_sdma", "sdma_ipg_clk", sdma_clk[1]),
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk[0]),
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk[0]),
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk[0]),
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk[0]),
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk[0]),
+ _REGISTER_CLOCK(NULL, "i2c_clk", i2c_clk[0]),
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]),
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]),
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk[0]),
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk[0]),
+ _REGISTER_CLOCK("imx50-cspi.1", NULL, cspi1_clk[0]),
+ _REGISTER_CLOCK("imx50-cspi.2", NULL, cspi2_clk[0]),
+ _REGISTER_CLOCK("imx50-cspi.3", NULL, cspi3_clk),
+ _REGISTER_CLOCK(NULL, "ssi_lp_apm_clk", ssi_lp_apm_clk),
+ _REGISTER_CLOCK("mxc_ssi.0", NULL, ssi1_clk[0]),
+ _REGISTER_CLOCK("mxc_ssi.1", NULL, ssi2_clk[0]),
+ _REGISTER_CLOCK(NULL, "ssi_ext1_clk", ssi_ext1_clk),
+ _REGISTER_CLOCK(NULL, "ssi_ext2_clk", ssi_ext2_clk),
+ _REGISTER_CLOCK(NULL, "usb_ahb_clk", usb_ahb_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy_clk[0]),
+ _REGISTER_CLOCK(NULL, "usb_phy2_clk", usb_phy_clk[1]),
+ _REGISTER_CLOCK(NULL, "usb_clk", usb_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk[0]),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk[0]),
+ _REGISTER_CLOCK(NULL, "ddr_clk", ddr_clk),
+ _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk),
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk),
+ _REGISTER_CLOCK(NULL, "gpu2d_clk", gpu2d_clk),
+ _REGISTER_CLOCK(NULL, "cko1", cko1_clk),
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk[0]),
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk[0]),
+ _REGISTER_CLOCK(NULL, "fec_sec1_clk", fec_clk[1]),
+ _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk),
+ _REGISTER_CLOCK("imx50-gpmi-nfc.0", NULL, gpmi_nfc_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpmi-apb", gpmi_nfc_clk[1]),
+ _REGISTER_CLOCK(NULL, "bch", gpmi_nfc_clk[2]),
+ _REGISTER_CLOCK(NULL, "bch-apb", gpmi_nfc_clk[3]),
+ _REGISTER_CLOCK(NULL, "rng_clk", rng_clk),
+ _REGISTER_CLOCK(NULL, "dcp_clk", dcp_clk),
+ _REGISTER_CLOCK(NULL, "ocotp_ctrl_ahb_clk", ocotp_clk),
+ _REGISTER_CLOCK(NULL, "ocram_clk", ocram_clk),
+ _REGISTER_CLOCK("mxs-dma-apbh", NULL, apbh_dma_clk),
+ _REGISTER_CLOCK(NULL, "sys_clk", sys_clk),
+ _REGISTER_CLOCK(NULL, "elcdif_pix", elcdif_pix_clk),
+ _REGISTER_CLOCK(NULL, "display_axi", display_axi_clk),
+ _REGISTER_CLOCK(NULL, "elcdif_axi", elcdif_axi_clk),
+ _REGISTER_CLOCK(NULL, "pxp_axi", pxp_axi_clk),
+ _REGISTER_CLOCK(NULL, "epdc_axi", epdc_axi_clk),
+ _REGISTER_CLOCK(NULL, "epdc_pix", epdc_pix_clk),
+};
+
+/*static struct mxc_clk mxc_clks[ARRAY_SIZE(lookups)];*/
+
+static void clk_tree_init(void)
+{
+ u32 reg;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* set pll1_main_clk parent */
+ pll1_main_clk.parent = &osc_clk;
+
+ /* set pll2_sw_clk parent */
+ pll2_sw_clk.parent = &osc_clk;
+
+ /* set pll3_clk parent */
+ pll3_sw_clk.parent = &osc_clk;
+
+ /* set weim_clk parent */
+ weim_clk[0].parent = &main_bus_clk;
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if ((reg & MX50_CCM_CBCDR_WEIM_CLK_SEL) != 0)
+ weim_clk[0].parent = &ahb_clk;
+
+ /* set ipg_perclk parent */
+ ipg_perclk.parent = &lp_apm_clk;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
+ ipg_perclk.parent = &ipg_clk;
+ } else {
+ if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
+ ipg_perclk.parent = &main_bus_clk;
+ }
+}
+
+int __init mx50_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1)
+{
+ __iomem void *base;
+ int i = 0, j = 0, reg;
+ int wp_cnt = 0;
+ u32 pll1_rate;
+
+ pll1_base = MX50_DPLL1_BASE;
+ pll2_base = MX50_DPLL2_BASE;
+ pll3_base = MX50_DPLL3_BASE;
+ apll_base = ioremap(MX50_ANATOP_BASE_ADDR, SZ_4K);
+
+ /* Turn off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG4_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG3_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG14_OFFSET, MXC_CCM_CCGR0);
+ }
+
+ __raw_writel(0, MXC_CCM_CCGR1);
+ __raw_writel(0, MXC_CCM_CCGR2);
+ __raw_writel(0, MXC_CCM_CCGR3);
+ __raw_writel(0, MXC_CCM_CCGR4);
+
+ __raw_writel(3 << MXC_CCM_CCGRx_CG6_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG8_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET, MXC_CCM_CCGR5);
+
+ __raw_writel(3 << MXC_CCM_CCGRx_CG0_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 2 << MXC_CCM_CCGRx_CG14_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG15_OFFSET, MXC_CCM_CCGR6);
+
+ __raw_writel(0, MXC_CCM_CCGR7);
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ oscillator_reference = osc;
+
+ usb_phy_clk[0].enable_reg = MXC_CCM_CCGR4;
+ usb_phy_clk[0].enable_shift = MXC_CCM_CCGRx_CG5_OFFSET;
+ clk_tree_init();
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ clk_debug_register(lookups[i].clk);
+ }
+
+ /* set DDR clock parent */
+ reg = __raw_readl(MXC_CCM_CLK_DDR) &
+ MXC_CCM_CLK_DDR_DDR_PFD_SEL;
+ if (reg)
+ clk_set_parent(&ddr_clk, &pfd0_clk);
+ else
+ clk_set_parent(&ddr_clk, &pll1_sw_clk);
+
+ clk_set_parent(&esdhc1_clk[0], &pll2_sw_clk);
+ clk_set_parent(&esdhc1_clk[2], &tmax2_clk);
+ clk_set_parent(&esdhc2_clk[0], &esdhc1_clk[0]);
+ clk_set_parent(&esdhc3_clk[0], &pll2_sw_clk);
+
+ clk_enable(&cpu_clk);
+
+ clk_enable(&main_bus_clk);
+
+ databahn = ioremap(MX50_DATABAHN_BASE_ADDR, SZ_16K);
+
+ /* Initialise the parents to be axi_b, parents are set to
+ * axi_a when the clocks are enabled.
+ */
+
+ clk_set_parent(&gpu2d_clk, &axi_a_clk);
+
+ /* move cspi to 24MHz */
+ clk_set_parent(&cspi_main_clk, &lp_apm_clk);
+ clk_set_rate(&cspi_main_clk, 12000000);
+
+ /*
+ * Set DISPLAY_AXI to 200Mhz
+ * For Display AXI, source clocks must be
+ * enabled before dividers can be changed
+ */
+ clk_enable(&display_axi_clk);
+ clk_enable(&elcdif_axi_clk);
+ clk_enable(&pxp_axi_clk);
+ clk_set_parent(&display_axi_clk, &pfd2_clk);
+ clk_set_rate(&display_axi_clk, 200000000);
+ clk_disable(&display_axi_clk);
+ clk_disable(&pxp_axi_clk);
+ clk_disable(&elcdif_axi_clk);
+
+ clk_enable(&elcdif_pix_clk);
+ clk_set_parent(&elcdif_pix_clk, &pll1_sw_clk);
+ clk_disable(&elcdif_pix_clk);
+
+ /*
+ * Enable and set EPDC AXI to 200MHz
+ * For EPDC AXI, source clocks must be
+ * enabled before dividers can be changed
+ */
+ clk_enable(&epdc_axi_clk);
+ clk_set_parent(&epdc_axi_clk, &pfd3_clk);
+ clk_set_rate(&epdc_axi_clk, 200000000);
+ clk_disable(&epdc_axi_clk);
+
+ clk_set_parent(&epdc_pix_clk, &pfd5_clk);
+
+ /* Move SSI clocks to SSI_LP_APM clock */
+ clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
+
+ clk_set_parent(&ssi1_clk[0], &ssi_lp_apm_clk);
+ /* set the SSI dividers to divide by 2 */
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ clk_set_parent(&ssi2_clk[0], &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ /* Change the SSI_EXT1_CLK to be sourced from SSI1_CLK_ROOT */
+ clk_set_parent(&ssi_ext1_clk, &ssi1_clk[0]);
+ clk_set_parent(&ssi_ext2_clk, &ssi2_clk[0]);
+
+ /* move usb_phy_clk to 24MHz */
+ clk_set_parent(&usb_phy_clk[0], &osc_clk);
+ clk_set_parent(&usb_phy_clk[1], &osc_clk);
+
+ /* move gpmi-nfc to 24MHz */
+ clk_set_parent(&gpmi_nfc_clk[0], &osc_clk);
+
+ /* set SDHC root clock as 200MHZ*/
+ clk_set_rate(&esdhc1_clk[0], 200000000);
+ clk_set_rate(&esdhc3_clk[0], 200000000);
+
+ clk_set_parent(&uart_main_clk, &lp_apm_clk);
+
+ clk_set_parent(&gpu2d_clk, &axi_b_clk);
+
+ clk_set_parent(&weim_clk[0], &ahb_clk);
+ clk_set_rate(&weim_clk[0], clk_round_rate(&weim_clk[0], 130000000));
+
+ /* Do the following just to disable the PLL since its not used */
+ clk_enable(&pll3_sw_clk);
+ clk_disable(&pll3_sw_clk);
+
+ /* Get the CPU operating points table. */
+ mx50_cpu_op_init();
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ base = MX50_IO_ADDRESS(MX50_GPT1_BASE_ADDR);
+ mxc_timer_init(&gpt_clk[0], base, MX50_INT_GPT);
+
+ return 0;
+}
+
+/*!
+ * Setup cpu clock based on working point.
+ * @param wp cpu freq working point
+ * @return 0 on success or error code on failure.
+ */
+static int cpu_clk_set_op(int wp)
+{
+ struct cpu_op *p;
+ u32 reg;
+
+ if (wp == cpu_curr_op)
+ return 0;
+
+ p = &cpu_op_tbl[wp];
+
+ /*
+ * leave the PLL1 freq unchanged.
+ */
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ reg |= cpu_op_tbl[wp].cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CACRR);
+ cpu_curr_op = wp;
+
+#if defined(CONFIG_CPU_FREQ)
+ cpufreq_trig_needed = 1;
+#endif
+ return 0;
+}
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
new file mode 100755
index 00000000..94a69be9
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * This file contains the CPU initialization code.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/iram_alloc.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#define CORTEXA8_PLAT_AMC 0x18
+#define SRPG_NEON_PUPSCR 0x284
+#define SRPG_NEON_PDNSCR 0x288
+#define SRPG_ARM_PUPSCR 0x2A4
+#define SRPG_ARM_PDNSCR 0x2A8
+#define SRPG_EMPGC0_PUPSCR 0x2E4
+#define SRPG_EMPGC0_PDNSCR 0x2E8
+#define SRPG_EMPGC1_PUPSCR 0x304
+#define SRPG_EMPGC1_PDNSCR 0x308
+
+void __iomem *arm_plat_base;
+void __iomem *gpc_base;
+void __iomem *ccm_base;
+struct cpu_op *(*get_cpu_op)(int *op);
+
+extern void init_ddr_settings(void);
+
+static int cpu_silicon_rev = -1;
+
+#define IIM_SREV 0x24
+#define MX50_HW_ADADIG_DIGPROG 0xB0
+
+static int get_mx51_srev(void)
+{
+ void __iomem *iim_base = MX51_IO_ADDRESS(MX51_IIM_BASE_ADDR);
+ u32 rev = readl(iim_base + IIM_SREV) & 0xff;
+
+ if (rev == 0x0)
+ return IMX_CHIP_REVISION_2_0;
+ else if (rev == 0x10)
+ return IMX_CHIP_REVISION_3_0;
+ return 0;
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+ if (!cpu_is_mx51())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = get_mx51_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
+void mx51_display_revision(void)
+{
+ int rev;
+ char *srev;
+ rev = mx51_revision();
+
+ switch (rev) {
+ case IMX_CHIP_REVISION_2_0:
+ srev = IMX_CHIP_REVISION_2_0_STRING;
+ break;
+ case IMX_CHIP_REVISION_3_0:
+ srev = IMX_CHIP_REVISION_3_0_STRING;
+ break;
+ default:
+ srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+ }
+ printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx51_display_revision);
+
+#ifdef CONFIG_NEON
+
+/*
+ * All versions of the silicon before Rev. 3 have broken NEON implementations.
+ * Dependent on link order - so the assumption is that vfp_init is called
+ * before us.
+ */
+static int __init mx51_neon_fixup(void)
+{
+ if (!cpu_is_mx51())
+ return 0;
+
+ if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) {
+ elf_hwcap &= ~HWCAP_NEON;
+ pr_info("Turning off NEON support, detected broken NEON implementation\n");
+ }
+ return 0;
+}
+
+late_initcall(mx51_neon_fixup);
+#endif
+
+static int get_mx53_srev(void)
+{
+ void __iomem *iim_base = MX51_IO_ADDRESS(MX53_IIM_BASE_ADDR);
+ u32 rev = readl(iim_base + IIM_SREV) & 0xff;
+
+ switch (rev) {
+ case 0x0:
+ return IMX_CHIP_REVISION_1_0;
+ case 0x2:
+ return IMX_CHIP_REVISION_2_0;
+ case 0x3:
+ return IMX_CHIP_REVISION_2_1;
+ default:
+ return IMX_CHIP_REVISION_UNKNOWN;
+ }
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx53
+ */
+int mx53_revision(void)
+{
+ if (!cpu_is_mx53())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = get_mx53_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx53_revision);
+#define MX50_HW_ADADIG_DIGPROG 0xB0
+
+static int get_mx50_srev(void)
+{
+ void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K);
+ u32 rev;
+
+ if (!anatop) {
+ cpu_silicon_rev = -EINVAL;
+ return 0;
+ }
+
+ rev = readl(anatop + MX50_HW_ADADIG_DIGPROG);
+ rev &= 0xff;
+
+ iounmap(anatop);
+ if (rev == 0x0)
+ return IMX_CHIP_REVISION_1_0;
+ else if (rev == 0x1)
+ return IMX_CHIP_REVISION_1_1;
+ return 0;
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx50
+ */
+int mx50_revision(void)
+{
+ if (!cpu_is_mx50())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = get_mx50_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx50_revision);
+
+void mx53_display_revision(void)
+{
+ int rev;
+ char *srev;
+ rev = mx53_revision();
+
+ switch (rev) {
+ case IMX_CHIP_REVISION_1_0:
+ srev = IMX_CHIP_REVISION_1_0_STRING;
+ break;
+ case IMX_CHIP_REVISION_2_0:
+ srev = IMX_CHIP_REVISION_2_0_STRING;
+ break;
+ case IMX_CHIP_REVISION_2_1:
+ srev = IMX_CHIP_REVISION_2_1_STRING;
+ break;
+ default:
+ srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+ }
+ printk(KERN_INFO "CPU identified as i.MX53, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx53_display_revision);
+
+static int __init post_cpu_init(void)
+{
+ unsigned int reg;
+ void __iomem *base;
+ struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk");
+
+ if (cpu_is_mx51()) {
+ ccm_base = MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR);
+ gpc_base = MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR);
+ arm_plat_base = MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR);
+ iram_init(MX51_IRAM_BASE_ADDR, MX51_IRAM_SIZE);
+ } else if (cpu_is_mx53()) {
+ ccm_base = MX53_IO_ADDRESS(MX53_CCM_BASE_ADDR);
+ gpc_base = MX53_IO_ADDRESS(MX53_GPC_BASE_ADDR);
+ arm_plat_base = MX53_IO_ADDRESS(MX53_ARM_BASE_ADDR);
+ iram_init(MX53_IRAM_BASE_ADDR, MX53_IRAM_SIZE);
+ } else {
+ ccm_base = MX50_IO_ADDRESS(MX50_CCM_BASE_ADDR);
+ gpc_base = MX50_IO_ADDRESS(MX50_GPC_BASE_ADDR);
+ arm_plat_base = MX50_IO_ADDRESS(MX50_ARM_BASE_ADDR);
+ iram_init(MX50_IRAM_BASE_ADDR, MX50_IRAM_SIZE);
+ }
+
+ if (cpu_is_mx51() || cpu_is_mx53()) {
+ if (cpu_is_mx51()) {
+ base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
+ } else {
+ base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR);
+ }
+
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+
+ if (cpu_is_mx51())
+ base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
+ else
+ base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR);
+
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+ }
+ clk_enable(gpcclk);
+
+ /* Setup the number of clock cycles to wait for SRPG
+ * power up and power down requests.
+ */
+ __raw_writel(0x010F0201, gpc_base + SRPG_ARM_PUPSCR);
+ __raw_writel(0x010F0201, gpc_base + SRPG_NEON_PUPSCR);
+ __raw_writel(0x00000008, gpc_base + SRPG_EMPGC0_PUPSCR);
+ __raw_writel(0x00000008, gpc_base + SRPG_EMPGC1_PUPSCR);
+
+ __raw_writel(0x01010101, gpc_base + SRPG_ARM_PDNSCR);
+ __raw_writel(0x01010101, gpc_base + SRPG_NEON_PDNSCR);
+ __raw_writel(0x00000018, gpc_base + SRPG_EMPGC0_PDNSCR);
+ __raw_writel(0x00000018, gpc_base + SRPG_EMPGC1_PDNSCR);
+
+ clk_disable(gpcclk);
+ clk_put(gpcclk);
+
+ /* Set ALP bits to 000. Set ALP_EN bit in Arm Memory Controller reg. */
+ reg = 0x8;
+ __raw_writel(reg, arm_plat_base + CORTEXA8_PLAT_AMC);
+
+ if (cpu_is_mx50())
+ init_ddr_settings();
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx5/cpu_op-mx50.c b/arch/arm/mach-mx5/cpu_op-mx50.c
new file mode 100755
index 00000000..f916ae41
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx50.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <mach/hardware.h>
+#include <linux/kernel.h>
+#include <mach/mxc_dvfs.h>
+
+static int num_cpu_op;
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern struct dvfs_op *(*get_dvfs_core_op)(int *wp);
+
+/* working point(wp): 0 - 800MHz; 1 - 400MHz, 2 - 160MHz; */
+static struct cpu_op mx50_cpu_op[] = {
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1050000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 400000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 1050000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 160000000,
+ .cpu_podf = 4,
+ .cpu_voltage = 850000,},
+};
+
+static struct dvfs_op dvfs_core_setpoint[] = {
+ {33, 13, 33, 10, 10, 0x08}, /* 800MHz*/
+ {28, 8, 33, 10, 10, 0x08}, /* 400MHz */
+ {20, 0, 33, 20, 10, 0x08}, /* 160MHz*/
+ {28, 8, 33, 20, 30, 0x08}, /*160MHz, AHB 133MHz, LPAPM mode*/
+ {29, 0, 33, 20, 10, 0x08},}; /* 160MHz, AHB 24MHz */
+
+struct cpu_op *mx50_get_cpu_op(int *op)
+{
+ *op = ARRAY_SIZE(mx50_cpu_op);
+ return mx50_cpu_op;
+}
+
+static struct dvfs_op *mx50_get_dvfs_core_table(int *wp)
+{
+ *wp = ARRAY_SIZE(dvfs_core_setpoint);
+ return dvfs_core_setpoint;
+}
+
+void mx50_cpu_op_init(void)
+{
+ get_cpu_op = mx50_get_cpu_op;
+ num_cpu_op = ARRAY_SIZE(mx50_cpu_op);
+ get_dvfs_core_op = mx50_get_dvfs_core_table;
+}
diff --git a/arch/arm/mach-mx5/cpu_op-mx50.h b/arch/arm/mach-mx5/cpu_op-mx50.h
new file mode 100755
index 00000000..e9844c8e
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx50.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+void mx50_cpu_op_init(void);
+
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.c b/arch/arm/mach-mx5/cpu_op-mx51.c
new file mode 100755
index 00000000..640e4189
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void (*set_num_cpu_op)(int num);
+extern struct dvfs_op *(*get_dvfs_core_op)(int *wp);
+
+static int num_cpu_op;
+
+/* working point(wp): 0 - 800MHz; 1 - 166.25MHz; */
+static struct cpu_op mx51_cpu_op[] = {
+ {
+ .pll_rate = 1000000000,
+ .cpu_rate = 1000000000,
+ .pdf = 0,
+ .mfi = 10,
+ .mfd = 11,
+ .mfn = 5,
+ .cpu_podf = 0,
+ .cpu_voltage = 1175000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1100000,
+ },
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 400000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 1,
+ .cpu_voltage = 950000,
+ },
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 166250000,
+ .cpu_podf = 4,
+ .cpu_voltage = 850000,
+ },
+};
+
+static struct dvfs_op dvfs_core_setpoint[] = {
+ {33, 13, 33, 10, 10, 0x08}, /* 800MHz*/
+ {28, 8, 33, 10, 10, 0x08}, /* 400MHz */
+ {20, 0, 33, 20, 10, 0x08}, /* 160MHz*/
+ {28, 8, 33, 20, 30, 0x08}, /*160MHz, AHB 133MHz, LPAPM mode*/
+ {29, 0, 33, 20, 10, 0x08},}; /* 160MHz, AHB 24MHz */
+
+struct cpu_op *mx51_get_cpu_op(int *op)
+{
+ *op = num_cpu_op;
+ return mx51_cpu_op;
+}
+
+void mx51_set_num_cpu_op(int num)
+{
+ num_cpu_op = num;
+ return;
+}
+
+
+static struct dvfs_op *mx51_get_dvfs_core_table(int *wp)
+{
+ *wp = ARRAY_SIZE(dvfs_core_setpoint);
+ return dvfs_core_setpoint;
+}
+
+void mx51_cpu_op_init(void)
+{
+ get_cpu_op = mx51_get_cpu_op;
+ set_num_cpu_op = mx51_set_num_cpu_op;
+ num_cpu_op = ARRAY_SIZE(mx51_cpu_op);
+ get_dvfs_core_op = mx51_get_dvfs_core_table;
+}
diff --git a/arch/arm/mach-mx5/cpu_op-mx51.h b/arch/arm/mach-mx5/cpu_op-mx51.h
new file mode 100755
index 00000000..54c1345d
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx51.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+void mx51_cpu_op_init(void);
diff --git a/arch/arm/mach-mx5/cpu_op-mx53.c b/arch/arm/mach-mx5/cpu_op-mx53.c
new file mode 100755
index 00000000..debe1bc4
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx53.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include "cpu_op-mx53.h"
+
+/*!
+ * @file mach-mx5/cpu_op-mx53.c
+ *
+ * @brief This file contains the information about MX53 CPU working points.
+ *
+ * @ingroup MSL_MX53
+ */
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void (*set_num_cpu_op)(int num);
+extern struct dvfs_op *(*get_dvfs_core_op)(int *wp);
+
+static int num_cpu_op;
+static struct cpu_op *cpu_op_table;
+
+static struct dvfs_op *dvfs_core_setpoint;
+static int num_dvfs_core_setpoint;
+
+/* Place holder for dvfs_core setpoints for AEC parts */
+static struct dvfs_op dvfs_core_setpoint_aec[] = {
+ {33, 0, 33, 10, 10, 0x08} }; /*800MHz*/
+
+/* Place holder for dvfs_core setpoints for 1.2GHz parts */
+static struct dvfs_op dvfs_core_setpoint_ces_1_2G[] = {
+ {33, 25, 33, 10, 10, 0x08}, /*1_2GHz*/
+ {30, 18, 33, 20, 10, 0x08}, /* 800MHz */
+ {25, 8, 33, 20, 10, 0x08}, /* 400MHz */
+ {28, 8, 33, 20, 30, 0x08}, /* 400MHZ, 133MHz */
+ {29, 0, 33, 20, 10, 0x08},}; /* 400MHZ, 50MHz. */
+
+/* Place holder for dvfs_core setpoints for 1 GHz parts */
+static struct dvfs_op dvfs_core_setpoint_ces[] = {
+ {33, 25, 33, 10, 10, 0x08}, /*1GHz*/
+ {30, 18, 33, 20, 10, 0x08}, /* 800MHz */
+ {25, 8, 33, 20, 10, 0x08}, /* 400MHz */
+ {28, 8, 33, 20, 30, 0x08}, /* 400MHz, 133MHz */
+ {29, 0, 33, 20, 10, 0x08},}; /* 400MHz, 50MHz. */
+
+/* working point for auto*/
+static struct cpu_op cpu_op_aec[] = {
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1050000,},
+};
+
+/* working point for consumer 1G*/
+static struct cpu_op cpu_op_ces[] = {
+ {
+ .pll_rate = 1000000000,
+ .cpu_rate = 1000000000,
+ .pdf = 0,
+ .mfi = 10,
+ .mfd = 11,
+ .mfn = 5,
+ .cpu_podf = 0,
+ .cpu_voltage = 1200000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1050000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 400000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 950000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 160000000,
+ .cpu_podf = 4,
+ .cpu_voltage = 900000,},
+};
+
+/* working point for consumer 1.2G*/
+static struct cpu_op cpu_op_ces_1_2g[] = {
+ {
+ .pll_rate = 1200000000,
+ .cpu_rate = 1200000000,
+ .pdf = 0,
+ .mfi = 12,
+ .mfd = 1,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1300000,},
+ {
+ .pll_rate = 1000000000,
+ .cpu_rate = 1000000000,
+ .pdf = 0,
+ .mfi = 10,
+ .mfd = 11,
+ .mfn = 5,
+ .cpu_podf = 0,
+ .cpu_voltage = 1200000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1050000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 400000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 950000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 160000000,
+ .cpu_podf = 4,
+ .cpu_voltage = 900000,},
+};
+
+static struct dvfs_op *mx53_get_dvfs_core_table(int *wp)
+{
+ /* Add 2 to num_cpu_wp to handle LPAPM mode transitions. */
+ *wp = num_dvfs_core_setpoint;
+ return dvfs_core_setpoint;
+}
+
+struct cpu_op *mx53_get_cpu_op(int *op)
+{
+ *op = num_cpu_op;
+ return cpu_op_table;
+}
+
+void mx53_set_num_cpu_op(int num)
+{
+ num_cpu_op = num;
+ return;
+}
+
+void mx53_cpu_op_init()
+{
+ get_cpu_op = mx53_get_cpu_op;
+ set_num_cpu_op = mx53_set_num_cpu_op;
+ get_dvfs_core_op = mx53_get_dvfs_core_table;
+}
+
+void mx53_set_cpu_part_number(enum mx53_cpu_part_number part_num)
+{
+ switch (part_num) {
+ case IMX53_CEC_1_2G:
+ cpu_op_table = cpu_op_ces_1_2g;
+ num_cpu_op = ARRAY_SIZE(cpu_op_ces_1_2g);
+ dvfs_core_setpoint = dvfs_core_setpoint_ces_1_2G;
+ num_dvfs_core_setpoint =
+ ARRAY_SIZE(dvfs_core_setpoint_ces_1_2G);
+ break;
+ case IMX53_CEC:
+ cpu_op_table = cpu_op_ces;
+ num_cpu_op = ARRAY_SIZE(cpu_op_ces);
+ dvfs_core_setpoint = dvfs_core_setpoint_ces;
+ num_dvfs_core_setpoint =
+ ARRAY_SIZE(dvfs_core_setpoint_ces);
+ break;
+ case IMX53_AEC:
+ default:
+ cpu_op_table = cpu_op_aec;
+ num_cpu_op = ARRAY_SIZE(cpu_op_aec);
+ dvfs_core_setpoint = dvfs_core_setpoint_aec;
+ num_dvfs_core_setpoint =
+ ARRAY_SIZE(dvfs_core_setpoint_aec);
+ break;
+ }
+}
+
+
diff --git a/arch/arm/mach-mx5/cpu_op-mx53.h b/arch/arm/mach-mx5/cpu_op-mx53.h
new file mode 100755
index 00000000..eba0feda
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_op-mx53.h
@@ -0,0 +1,45 @@
+extern void mx51_cpu_op_init(void);
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX53_WP_H__
+#define __ARCH_ARM_MACH_MX53_WP_H__
+#include <linux/types.h>
+
+/*!
+ * @file mach-mx5/cpu_op-mx53.h
+ *
+ * @brief This file contains the information about MX53 CPU working points.
+ *
+ * @ingroup MSL_MX53
+ */
+enum mx53_cpu_part_number {
+ IMX53_AEC, /* automative and infotainment AP */
+ IMX53_CEC, /* Consumer AP, CPU freq is up to 1G */
+ IMX53_CEC_1_2G, /* Consumer AP, CPU freq is up to 1.2GHZ */
+};
+
+void mx53_set_cpu_part_number(enum mx53_cpu_part_number part_num);
+void mx53_cpu_op_init(void);
+
+#endif /*__ARCH_ARM_MACH_MX53_WP_H__ */
+
+
+
diff --git a/arch/arm/mach-mx5/cpu_regulator-mx5.c b/arch/arm/mach-mx5/cpu_regulator-mx5.c
new file mode 100644
index 00000000..b7d01e91
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu_regulator-mx5.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+
+struct regulator *cpu_regulator;
+char *gp_reg_id;
+
+
+void mx5_cpu_regulator_init(void)
+{
+ cpu_regulator = regulator_get(NULL, gp_reg_id);
+ if (IS_ERR(cpu_regulator))
+ printk(KERN_ERR "%s: failed to get cpu regulator\n", __func__);
+}
+
diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
new file mode 100755
index 00000000..c32d19f6
--- /dev/null
+++ b/arch/arm/mach-mx5/crm_regs.h
@@ -0,0 +1,868 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+#define MXC_CCM_BASE MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
+
+#define MX51_DPLL1_BASE MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
+#define MX51_DPLL2_BASE MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)
+#define MX51_DPLL3_BASE MX51_IO_ADDRESS(MX51_PLL3_BASE_ADDR)
+
+#define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR)
+#define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR)
+#define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR)
+#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR)
+
+#define MX50_DPLL1_BASE MX50_IO_ADDRESS(MX50_PLL1_BASE_ADDR)
+#define MX50_DPLL2_BASE MX50_IO_ADDRESS(MX50_PLL2_BASE_ADDR)
+#define MX50_DPLL3_BASE MX50_IO_ADDRESS(MX50_PLL3_BASE_ADDR)
+#define MX50_ANATOP_BASE MX50_IO_ADDRESS(MX50_ANATOP_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+/* Register addresses of apll and pfd*/
+#define MXC_ANADIG_FRAC0 0x10
+#define MXC_ANADIG_FRAC0_SET 0x14
+#define MXC_ANADIG_FRAC0_CLR 0x18
+#define MXC_ANADIG_FRAC1 0x20
+#define MXC_ANADIG_FRAC1_SET 0x24
+#define MXC_ANADIG_FRAC1_CLR 0x28
+#define MXC_ANADIG_MISC 0x60
+#define MXC_ANADIG_MISC_SET 0x64
+#define MXC_ANADIG_MISC_CLR 0x68
+#define MXC_ANADIG_PLLCTRL 0x70
+#define MXC_ANADIG_PLLCTRL_SET 0x74
+#define MXC_ANADIG_PLLCTRL_CLR 0x78
+
+/* apll and pfd Register Bit definitions */
+
+#define MXC_ANADIG_PFD3_CLKGATE (1 << 31)
+#define MXC_ANADIG_PFD3_STABLE (1 << 30)
+#define MXC_ANADIG_PFD3_FRAC_OFFSET 24
+#define MXC_ANADIG_PFD_FRAC_MASK 0x3F
+#define MXC_ANADIG_PFD2_CLKGATE (1 << 23)
+#define MXC_ANADIG_PFD2_STABLE (1 << 22)
+#define MXC_ANADIG_PFD2_FRAC_OFFSET 16
+#define MXC_ANADIG_PFD1_CLKGATE (1 << 15)
+#define MXC_ANADIG_PFD1_STABLE (1 << 14)
+#define MXC_ANADIG_PFD1_FRAC_OFFSET 8
+#define MXC_ANADIG_PFD0_CLKGATE (1 << 7)
+#define MXC_ANADIG_PFD0_STABLE (1 << 6)
+#define MXC_ANADIG_PFD0_FRAC_OFFSET 0
+
+#define MXC_ANADIG_PFD7_CLKGATE (1 << 31)
+#define MXC_ANADIG_PFD7_STABLE (1 << 30)
+#define MXC_ANADIG_PFD7_FRAC_OFFSET 24
+#define MXC_ANADIG_PFD6_CLKGATE (1 << 23)
+#define MXC_ANADIG_PFD6_STABLE (1 << 22)
+#define MXC_ANADIG_PFD6_FRAC_OFFSET 16
+#define MXC_ANADIG_PFD5_CLKGATE (1 << 15)
+#define MXC_ANADIG_PFD5_STABLE (1 << 14)
+#define MXC_ANADIG_PFD5_FRAC_OFFSET 8
+#define MXC_ANADIG_PFD4_CLKGATE (1 << 7)
+#define MXC_ANADIG_PFD4_STABLE (1 << 6)
+#define MXC_ANADIG_PFD4_FRAC_OFFSET 0
+
+#define MXC_ANADIG_REF_SELFBIAS_OFF (1 << 20)
+#define MXC_ANADIG_PLL_HOLD_RING_OFF (1 << 7)
+#define MXC_ANADIG_PLL_POWERUP (1 << 0)
+
+#define MXC_ANADIG_APLL_LOCK (1 << 31)
+#define MXC_ANADIG_APLL_FORCE_LOCK (1 << 30)
+#define MXC_ANADIG_PFD_DIS_OFFSET 16
+#define MXC_ANADIG_PFD_DIS_MASK 0xff
+#define MXC_ANADIG_APLL_LOCK_CNT_OFFSET 0
+#define MXC_ANADIG_APLL_LOCK_CNT_MASK 0xffff
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80)
+#define MXC_CCM_CCGR7 (MXC_CCM_BASE + 0x84)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x88)
+#define MXC_CCM_CSR2 (MXC_CCM_BASE + 0x8C)
+#define MXC_CCM_CLKSEQ_BYPASS (MXC_CCM_BASE + 0x90)
+#define MXC_CCM_CLK_SYS (MXC_CCM_BASE + 0x94)
+#define MXC_CCM_CLK_DDR (MXC_CCM_BASE + 0x98)
+#define MXC_CCM_ELCDIFPIX (MXC_CCM_BASE + 0x9C)
+#define MXC_CCM_EPDCPIX (MXC_CCM_BASE + 0xA0)
+#define MXC_CCM_DISPLAY_AXI (MXC_CCM_BASE + 0xA4)
+#define MXC_CCM_EPDC_AXI (MXC_CCM_BASE + 0xA8)
+#define MXC_CCM_GPMI (MXC_CCM_BASE + 0xAC)
+#define MXC_CCM_BCH (MXC_CCM_BASE + 0xB0)
+#define MXC_CCM_MSHC_XMSCKI (MXC_CCM_BASE + 0xB4)
+
+/* CCM Register Offsets. */
+#define MXC_CCM_CDCR_OFFSET 0x4C
+#define MXC_CCM_CACRR_OFFSET 0x10
+#define MXC_CCM_CDHIPR_OFFSET 0x48
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 11)
+#define MXC_CCM_CCR_CAMP2_EN (1 << 10)
+#define MXC_CCM_CCR_CAMP1_EN (1 << 9)
+#define MXC_CCM_CCR_FPM_EN (1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+
+/* Define the bits in register CCDR */
+/* MX51 */
+#define MXC_CCM_CCDR_HSC_HS_MASK (0x1 << 18)
+#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
+/* MX53 */
+#define MXC_CCM_CCDR_IPU_HS_MX53_MASK (0x1 << 21)
+#define MXC_CCM_CCDR_EMI_HS_INT2_MASK (0x1 << 20)
+#define MXC_CCM_CCDR_EMI_HS_INT1_MASK (0x1 << 19)
+#define MXC_CCM_CCDR_EMI_HS_SLOW_MASK (0x1 << 18)
+#define MXC_CCM_CCDR_EMI_HS_FAST_MASK (0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY (1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE (1 << 4)
+#define MXC_CCM_CSR_CAMP2_READY (1 << 3)
+#define MXC_CCM_CSR_CAMP1_READY (1 << 2)
+#define MXC_CCM_CSR_FPM_READY (1 << 1)
+#define MXC_CCM_CSR_TEMP_MON_ALARM (1 << 1)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_PLL3_PFD_EN (0x1 << 13)
+#define MXC_CCM_CCSR_PLL2_PFD_EN (0x1 << 12)
+#define MXC_CCM_CCSR_PLL1_PFD_EN (0x1 << 11)
+#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 10)
+#define MXC_CCM_CCSR_LP_APM_SE_MX51L (0x1 << 9)
+#define MXC_CCM_CCSR_PLL4_SW_CLK_SEL (1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CCSR_STEP_SEL_LP_APM 0
+#define MXC_CCM_CCSR_STEP_SEL_PLL1_BYPASS 1 /* Only when JTAG connected? */
+#define MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED 2
+#define MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED 3
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) /* 0: pll1_main_clk,
+ 1: step_clk */
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR */
+#define MX50_CCM_CBCDR_WEIM_CLK_SEL (0x1 << 27)
+#define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
+#define MX50_CCM_CBCDR_PERIPH_CLK_SEL_OFFSET (25)
+#define MX50_CCM_CBCDR_PERIPH_CLK_SEL_MASK (0x3 << 25)
+#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET (30)
+#define MXC_CCM_CBCDR_DDR_HF_SEL (0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET (27)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27)
+#define MX50_CCM_CBCDR_WEIM_PODF_OFFSET (22)
+#define MX50_CCM_CBCDR_WEIM_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22)
+#define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_NFC_PODF_OFFSET (13)
+#define MXC_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CBCMR_DBG_APB_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC2_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL_MX51 (0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC2_CLK_SEL (0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18)
+#define MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_OFFSET (21)
+#define MX50_CCM_CSCMR1_ESDHC1_CLK_SEL_MASK (0x3 << 21)
+#define MX50_CCM_CSCMR1_ESDHC2_CLK_SEL (0x1 << 20)
+#define MX50_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 19)
+#define MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_OFFSET (16)
+#define MX50_CCM_CSCMR1_ESDHC3_CLK_SEL_MASK (0x7 << 16)
+#define MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11)
+#define MXC_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n) (26+n*3)
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(n) (0x7 << (26+n*3))
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22)
+/* MX51 */
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14)
+/* MX53 */
+#define MXC_CCM_CSCMR2_ASRC_CLK_SEL (1<<21)
+#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET (19)
+#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK (0x3 << 19)
+#define MXC_CCM_CSCMR2_ESAI_POST_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR2_ESAI_POST_SEL_MASK (0x7 << 16)
+#define MXC_CCM_CSCMR2_IEEE_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR2_IEEE_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12)
+/* MX51 */
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6)
+/* MX53 */
+#define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV (0x1 << 11)
+#define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV (0x1 << 10)
+#define MXC_CCM_CSCMR2_LDB_DI1_CLK_SEL (0x1 << 9)
+#define MXC_CCM_CSCMR2_LDB_DI0_CLK_SEL (0x1 << 8)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC2_CLK_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET (25)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK (0x3F << 25)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET (9)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK (0x7 << 9)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19)
+/* MX51 */
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16)
+/* MX53 */
+#define MXC_CCM_CDCDR_DI_PLL4_PODF_OFFSET (16)
+#define MXC_CCM_CDCDR_DI_PLL4_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CDCDR_DI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CDCDR_DI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (3)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (0)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7)
+
+/* Define the bits in register CHSCCDR */
+/* MX51 */
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7)
+/* MX53 */
+#define MXC_CCM_CHSCCDR_ESAI_HCKT_SEL_OFFSET (6)
+#define MXC_CCM_CHSCCDR_ESAI_HCKT_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CHSCCDR_ESAI_HCKR_SEL_OFFSET (4)
+#define MXC_CCM_CHSCCDR_ESAI_HCKR_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CHSCCDR_SSI2_MLB_SPDIF_SRC_OFFSET (2)
+#define MXC_CCM_CHSCCDR_SSI2_MLB_SPDIF_SRC_MASK (0x3 << 2)
+#define MXC_CCM_CHSCCDR_SSI1_MLB_SPDIF_SRC_OFFSET (0)
+#define MXC_CCM_CHSCCDR_SSI1_MLB_SPDIF_SRC_MASK (0x3)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_ASRC_CLK_PRED_OFFSET (28)
+#define MXC_CCM_CSCDR2_ASRC_CLK_PRED_MASK (0x7 << 28)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
+/* MX51 */
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F)
+/* MX53 */
+#define MXC_CCM_CSCDR2_ASRC_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR2_ASRC_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR2_IEEE_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR2_IEEE_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_IEEE_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR2_IEEE_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY (1 << 8)
+#define MXC_CCM_CDHIPR_DDR_PODF_BUSY (1 << 7)
+#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
+
+/* Define the bits in register CDCR */
+#define MX50_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ_STATUS (0x1 << 7)
+#define MX50_CCM_CDCR_SW_PERIPH_CLK_DIV_REQ (0x1 << 6)
+#define MX50_CCM_CDCR_SW_DVFS_EN (0x1 << 5)
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
+
+/* Define the bits in register CLPCR */
+/* MX51 */
+#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS_MX51 (0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS_MX51 (0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS_MX51 (0x1 << 20)
+/* MX53 */
+#define MXC_CCM_CLPCR_BYPASS_CAN2_LPM_HS (0x1 << 27)
+#define MXC_CCM_CLPCR_BYPASS_CAN1_LPM_HS (0x1 << 27)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS_MX53 (0x1 << 26)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 25)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 24)
+#define MXC_CCM_CLPCR_BYPASS_EMI_INT2_LPM_HS (0x1 << 23)
+#define MX50_CCM_CLPCR_BYPASS_RNGB_LPM_HS (0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_EMI_INT1_LPM_HS (0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_EMI_SLOW_LPM_HS (0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_EMI_FAST_LPM_HS (0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY (0x1 << 2)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED_MX51 (0x1 << 25)
+#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 26)
+#define MXC_CCM_CISR_TEMP_MON_ALARM (0x1 << 25)
+#define MXC_CCM_CISR_EMI_CLK_SEL_LOADED (0x1 << 23)
+#define MXC_CCM_CISR_PER_CLK_SEL_LOADED (0x1 << 22)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY (0x1 << 6)
+#define MXC_CCM_CISR_CKIH2_READY (0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY (0x1 << 4)
+#define MX50_CCM_CISR_CAMP1_READY (0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY (0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1 (0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED_MX51 (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED_MX51 (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED_MX51 (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 26)
+#define MXC_CCM_CIMR_MASK_TEMP_MON_ALARM (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_EMI_CLK_SEL_LOADED (0x1 << 23)
+#define MXC_CCM_CIMR_MASK_PER_CLK_SEL_LOADED (0x1 << 22)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED_MX53 (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_EMI_SLOW_PODF_LOADED_MX53 (0x1 << 19)
+#define MX50_CCM_CIMR_MASK_WEIM_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
+/* MX51 */
+#define MXC_CCM_CIMR_MASK_COSC_READY_MX51 (0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3)
+/* MX53/MX50 */
+#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 6)
+#define MXC_CCM_CIMR_MASK_CAMP2_READY (0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CAMP1_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_LRF_PLL4 (0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_ARM_CLK_INPUT_SEL (0x1 << 24)
+#define MXC_CCM_CGPR_ARM_ASYNC_REF_EN (0x1 << 23)
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7)
+
+#define MX50_CCM_CCOSR_CKO1_SLOW_SEL (0x1 << 8)
+#define MX50_CCM_CCOSR_CKO1_EN (0x1 << 7)
+#define MX50_CCM_CCOSR_CKO1_DIV_OFFSET (4)
+#define MX50_CCM_CCOSR_CKO1_DIV_MASK (0x7 << 4)
+#define MX50_CCM_CCOSR_CKO1_SEL_OFFSET (0)
+#define MX50_CCM_CCOSR_CKO1_SEL_MASK (0xF)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGRx_CG_MASK 0x3
+#define MXC_CCM_CCGRx_MOD_OFF 0x0
+#define MXC_CCM_CCGRx_MOD_ON 0x3
+#define MXC_CCM_CCGRx_MOD_IDLE 0x1
+
+#define MXC_CCM_CCGRx_CG15_MASK (0x3 << 30)
+#define MXC_CCM_CCGRx_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGRx_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGRx_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGRx_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGRx_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGRx_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGRx_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGRx_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGRx_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGRx_CG3_MASK (0x3 << 6)
+#define MXC_CCM_CCGRx_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGRx_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGRx_CG0_MASK (0x3 << 0)
+
+#define MXC_CCM_CCGRx_CG15_OFFSET 30
+#define MXC_CCM_CCGRx_CG14_OFFSET 28
+#define MXC_CCM_CCGRx_CG13_OFFSET 26
+#define MXC_CCM_CCGRx_CG12_OFFSET 24
+#define MXC_CCM_CCGRx_CG11_OFFSET 22
+#define MXC_CCM_CCGRx_CG10_OFFSET 20
+#define MXC_CCM_CCGRx_CG9_OFFSET 18
+#define MXC_CCM_CCGRx_CG8_OFFSET 16
+#define MXC_CCM_CCGRx_CG7_OFFSET 14
+#define MXC_CCM_CCGRx_CG6_OFFSET 12
+#define MXC_CCM_CCGRx_CG5_OFFSET 10
+#define MXC_CCM_CCGRx_CG4_OFFSET 8
+#define MXC_CCM_CCGRx_CG3_OFFSET 6
+#define MXC_CCM_CCGRx_CG2_OFFSET 4
+#define MXC_CCM_CCGRx_CG1_OFFSET 2
+#define MXC_CCM_CCGRx_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR5_CG6_1_OFFSET 12
+#define MXC_CCM_CCGR5_CG6_2_OFFSET 13
+
+/* Define the bits in registers CSR2 */
+#define MXC_CCM_CSR2_ELCDIF_PIX_BUSY (0x1 << 9)
+#define MXC_CCM_CSR2_EPDC_PIX_BUSY (0x1 << 8)
+#define MXC_CCM_CSR2_EPDC_AXI_BUSY (0x1 << 4)
+#define MXC_CCM_CSR2_DISPLAY_AXI_BUSY (0x1 << 3)
+
+/* Define the bits in registers CLKSEQ_BYPASS */
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_OFFSET 14
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_ELCDIF_PIX_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_OFFSET 12
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_PIX_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_GPMI_CLK_SEL_OFFSET 6
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_GPMI_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_BCH_CLK_SEL_OFFSET 8
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_BCH_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_OFFSET 4
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_EPDC_AXI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_OFFSET 2
+#define MXC_CCM_CLKSEQ_BYPASS_BYPASS_DISPLAY_AXI_CLK_SEL_MASK (0x3 << 2)
+
+/* Define the bits in registers CLK_SYS */
+#define MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_OFFSET (30)
+#define MXC_CCM_CLK_SYS_SYS_XTAL_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_OFFSET (28)
+#define MXC_CCM_CLK_SYS_SYS_PLL_CLKGATE_MASK (0x3 << 28)
+#define MXC_CCM_CLK_SYS_DIV_XTAL_OFFSET (6)
+#define MXC_CCM_CLK_SYS_DIV_XTAL_MASK (0xF << 6)
+#define MXC_CCM_CLK_SYS_DIV_PLL_OFFSET (0)
+#define MXC_CCM_CLK_SYS_DIV_PLL_MASK (0x3F)
+
+/* Define the bits in registers CLK_DDR */
+#define MXC_CCM_CLK_DDR_DDR_CLKGATE_OFFSET (30)
+#define MXC_CCM_CLK_DDR_DDR_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_CLK_DDR_DDR_PFD_SEL (1 << 6)
+#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_OFFSET (0)
+#define MXC_CCM_CLK_DDR_DDR_DIV_PLL_MASK (0x3F)
+
+/* Define the bits in register DISPLAY_AXI */
+#define MXC_CCM_DISPLAY_AXI_CLKGATE_OFFSET (30)
+#define MXC_CCM_DISPLAY_AXI_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_DISPLAY_AXI_PXP_ASM_EN (1 << 13)
+#define MXC_CCM_DISPLAY_AXI_PXP_ASM_DIV_MASK (0x7 << 10)
+#define MXC_CCM_DISPLAY_AXI_PXP_ASM_DIV_OFFSET 10
+#define MXC_CCM_DISPLAY_AXI_DIV_OFFSET (0)
+#define MXC_CCM_DISPLAY_AXI_DIV_MASK (0x3F)
+
+/* Define the bits in register EPDC_AXI */
+#define MXC_CCM_EPDC_AXI_CLKGATE_OFFSET (30)
+#define MXC_CCM_EPDC_AXI_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_EPDC_AXI_ASM_EN (1 << 9)
+#define MXC_CCM_EPDC_AXI_ASM_DIV_OFFSET (6)
+#define MXC_CCM_EPDC_AXI_ASM_DIV_MASK (0x7 << 6)
+#define MXC_CCM_EPDC_AXI_DIV_OFFSET (0)
+#define MXC_CCM_EPDC_AXI_DIV_MASK (0x3F)
+
+/* Define the bits in register EPDCPIX */
+#define MXC_CCM_EPDC_PIX_CLKGATE_OFFSET (30)
+#define MXC_CCM_EPDC_PIX_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_EPDC_PIX_CLK_PRED_OFFSET (12)
+#define MXC_CCM_EPDC_PIX_CLK_PRED_MASK (0x3 << 12)
+#define MXC_CCM_EPDC_PIX_CLK_PODF_OFFSET (0)
+#define MXC_CCM_EPDC_PIX_CLK_PODF_MASK (0xFFF)
+
+/* Define the bits in register ELCDIFPIX */
+#define MXC_CCM_ELCDIFPIX_CLKGATE_OFFSET (30)
+#define MXC_CCM_ELCDIFPIX_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_ELCDIFPIX_CLK_PRED_OFFSET (12)
+#define MXC_CCM_ELCDIFPIX_CLK_PRED_MASK (0x3 << 12)
+#define MXC_CCM_ELCDIFPIX_CLK_PODF_OFFSET (0)
+#define MXC_CCM_ELCDIFPIX_CLK_PODF_MASK (0xFFF)
+
+
+/* Define the bits in register GPMI */
+#define MXC_CCM_GPMI_CLKGATE_OFFSET (30)
+#define MXC_CCM_GPMI_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_GPMI_CLK_DIV_OFFSET (0)
+#define MXC_CCM_GPMI_CLK_DIV_MASK (0x3F)
+
+/* Define the bits in register BCH */
+#define MXC_CCM_BCH_CLKGATE_OFFSET (30)
+#define MXC_CCM_BCH_CLKGATE_MASK (0x3 << 30)
+#define MXC_CCM_BCH_CLK_DIV_OFFSET (0)
+#define MXC_CCM_BCH_CLK_DIV_MASK (0x3F)
+
+#define MXC_GPC_BASE (MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR))
+#define MXC_DPTC_LP_BASE (MXC_GPC_BASE + 0x80)
+#define MXC_DPTC_GP_BASE (MXC_GPC_BASE + 0x100)
+#define MXC_DVFS_CORE_BASE (MXC_GPC_BASE + 0x180)
+#define MXC_DVFS_PER_BASE (MXC_GPC_BASE + 0x1C4)
+#define MXC_PGC_IPU_BASE (MXC_GPC_BASE + 0x220)
+#define MXC_PGC_VPU_BASE (MXC_GPC_BASE + 0x240)
+#define MXC_PGC_GPU_BASE (MXC_GPC_BASE + 0x260)
+#define MXC_SRPG_NEON_BASE (MXC_GPC_BASE + 0x280)
+#define MXC_SRPG_ARM_BASE (MXC_GPC_BASE + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE (MXC_GPC_BASE + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE (MXC_GPC_BASE + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE (MXC_GPC_BASE + 0x2E0)
+#define MXC_SRPG_EMI_BASE (MXC_GPC_BASE + 0x300)
+
+/* CORTEXA8 platform */
+extern void __iomem *arm_plat_base;
+#define MXC_CORTEXA8_BASE (arm_plat_base)
+#define MXC_CORTEXA8_PLAT_PVID (arm_plat_base + 0x0)
+#define MXC_CORTEXA8_PLAT_GPC (arm_plat_base + 0x4)
+#define MXC_CORTEXA8_PLAT_PIC (arm_plat_base + 0x8)
+#define MXC_CORTEXA8_PLAT_LPC (arm_plat_base + 0xC)
+#define MXC_CORTEXA8_PLAT_NEON_LPC (arm_plat_base + 0x10)
+#define MXC_CORTEXA8_PLAT_ICGC (arm_plat_base + 0x14)
+#define MXC_CORTEXA8_PLAT_AMC (arm_plat_base + 0x18)
+#define MXC_CORTEXA8_PLAT_NMC (arm_plat_base + 0x20)
+#define MXC_CORTEXA8_PLAT_NMS (arm_plat_base + 0x24)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
+
+/* DVFS PER */
+#define MXC_DVFSPER_LTR0 (MXC_DVFS_PER_BASE)
+#define MXC_DVFSPER_LTR1 (MXC_DVFS_PER_BASE + 0x04)
+#define MXC_DVFSPER_LTR2 (MXC_DVFS_PER_BASE + 0x08)
+#define MXC_DVFSPER_LTR3 (MXC_DVFS_PER_BASE + 0x0C)
+#define MXC_DVFSPER_LTBR0 (MXC_DVFS_PER_BASE + 0x10)
+#define MXC_DVFSPER_LTBR1 (MXC_DVFS_PER_BASE + 0x14)
+#define MXC_DVFSPER_PMCR0 (MXC_DVFS_PER_BASE + 0x18)
+#define MXC_DVFSPER_PMCR1 (MXC_DVFS_PER_BASE + 0x1C)
+
+/* GPC */
+#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
+#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
+#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
+#define MXC_GPC_CNTR_OFFSET 0x0
+#define MXC_GPC_PGR_OFFSET 0x4
+#define MXC_GPC_VCR_OFFSET 0x8
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx5/devices-imx50.h b/arch/arm/mach-mx5/devices-imx50.h
new file mode 100755
index 00000000..8cba79c4
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx50.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mx50.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[];
+#define imx50_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx50_imx_uart_data[id], pdata)
+
+extern const struct imx_srtc_data imx50_imx_srtc_data __initconst;
+#define imx50_add_srtc() \
+ imx_add_srtc(&imx50_imx_srtc_data)
+
+extern const struct imx_dma_res_data imx50_dma_res_data __initconst;
+#define imx50_add_dma() imx_add_dma(&imx50_dma_res_data);
+
+extern const struct imx_fec_data imx50_fec_data;
+#define imx50_add_fec(pdata) \
+ imx_add_fec(&imx50_fec_data, pdata)
+
+extern const struct imx_imx_i2c_data imx50_imx_i2c_data[];
+#define imx50_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx50_imx_i2c_data[id], pdata)
+extern const struct imx_mxc_gpu_data imx50_gpu_data __initconst;
+extern const struct imx_pxp_data imx50_pxp_data __initconst;
+#define imx50_add_imx_pxp() \
+ imx_add_imx_pxp(&imx50_pxp_data)
+
+#define imx50_add_imx_pxp_client() \
+ imx_add_imx_pxp_client()
+
+extern const struct imx_epdc_data imx50_epdc_data __initconst;
+#define imx50_add_imx_epdc(pdata) \
+ imx_add_imx_epdc(&imx50_epdc_data, pdata)
+
+#define imx50_add_mxc_gpu(pdata) \
+ imx_add_mxc_gpu(&imx50_gpu_data, pdata)
+extern const struct imx_sdhci_esdhc_imx_data imx50_sdhci_esdhc_imx_data[] __initconst;
+#define imx50_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx50_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_otp_data imx50_otp_data __initconst;
+#define imx50_add_otp() \
+ imx_add_otp(&imx50_otp_data);
+
+extern const struct imx_viim_data imx50_viim_data __initconst;
+#define imx50_add_viim() \
+ imx_add_viim(&imx50_viim_data)
+
+extern const struct imx_dcp_data imx50_dcp_data __initconst;
+#define imx50_add_dcp() \
+ imx_add_dcp(&imx50_dcp_data);
+
+extern const struct imx_rngb_data imx50_rngb_data __initconst;
+#define imx50_add_rngb() \
+ imx_add_rngb(&imx50_rngb_data);
+extern const struct imx_perfmon_data imx50_perfmon_data __initconst;
+#define imx50_add_perfmon() \
+ imx_add_perfmon(&imx50_perfmon_data);
+#define imx50_add_gpmi(platform_data) imx_add_gpmi(platform_data);
+
+extern const struct imx_perfmon_data imx50_perfmon_data __initconst;
+#define imx50_add_perfmon() \
+ imx_add_perfmon(&imx50_perfmon_data);
+
+extern const struct imx_spi_imx_data imx50_cspi_data[] __initconst;
+#define imx50_add_cspi(id, pdata) \
+ imx_add_spi_imx(&imx50_cspi_data[id], pdata)
+
+extern const struct imx_dvfs_core_data imx50_dvfs_core_data __initconst;
+#define imx50_add_dvfs_core(pdata) \
+ imx_add_dvfs_core(&imx50_dvfs_core_data, pdata)
+
+#define imx50_add_busfreq(pdata) imx_add_busfreq(pdata)
+
+
diff --git a/arch/arm/mach-mx5/devices-imx51.h b/arch/arm/mach-mx5/devices-imx51.h
new file mode 100755
index 00000000..421e9f68
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx51.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx51_fec_data;
+#define imx51_add_fec(pdata) \
+ imx_add_fec(&imx51_fec_data, pdata)
+
+extern const struct imx_imx_i2c_data imx51_imx_i2c_data[];
+#define imx51_add_imx_i2c(id, pdata) \
+extern const struct imx_srtc_data imx51_imx_srtc_data __initconst;
+#define imx51_add_srtc() \
+ imx_add_srtc(&imx51_imx_srtc_data)
+
+ imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
+
+extern const struct imx_imx_ssi_data imx51_imx_ssi_data[];
+#define imx51_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx51_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[];
+#define imx51_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx51_imx_uart_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx51_mxc_nand_data;
+#define imx51_add_mxc_nand(pdata) \
+ imx_add_mxc_nand(&imx51_mxc_nand_data, pdata)
+
+extern const struct imx_sdhci_esdhc_imx_data imx51_sdhci_esdhc_imx_data[];
+#define imx51_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx51_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx51_cspi_data;
+#define imx51_add_cspi(pdata) \
+ imx_add_spi_imx(&imx51_cspi_data, pdata)
+
+extern const struct imx_spi_imx_data imx51_ecspi_data[];
+#define imx51_add_ecspi(id, pdata) \
+ imx_add_spi_imx(&imx51_ecspi_data[id], pdata)
+
+extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[];
+#define imx51_add_imx2_wdt(id, pdata) \
+ imx_add_imx2_wdt(&imx51_imx2_wdt_data[id])
+
+extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[];
+#define imx51_add_mxc_pwm(id) \
+ imx_add_mxc_pwm(&imx51_mxc_pwm_data[id])
+
+extern const struct imx_imx_keypad_data imx51_imx_keypad_data;
+#define imx51_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx51_imx_keypad_data, pdata)
+extern const struct imx_mxc_gpu_data imx51_gpu_data __initconst;
+#define imx51_add_mxc_gpu(pdata) \
+ imx_add_mxc_gpu(&imx51_gpu_data, pdata)
+
+extern const struct imx_mxc_scc2_data imx51_mxc_scc2_data __initconst;
+#define imx51_add_mxc_scc2() \
+ imx_add_mxc_scc2(&imx51_mxc_scc2_data)
+
+extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[] __initconst;
+#define imx51_add_mxc_pwm(id) \
+ imx_add_mxc_pwm(&imx51_mxc_pwm_data[id])
+
+#define imx51_add_mxc_pwm_backlight(id, pdata) \
+ platform_device_register_resndata(NULL, "pwm-backlight",\
+ id, NULL, 0, pdata, sizeof(*pdata));
+
+extern const struct imx_ipuv3_data imx51_ipuv3_data __initconst;
+#define imx51_add_ipuv3(id, pdata) imx_add_ipuv3(id, &imx51_ipuv3_data, pdata)
+#define imx51_add_ipuv3fb(id, pdata) imx_add_ipuv3_fb(id, pdata)
+
+extern const struct imx_vpu_data imx51_vpu_data __initconst;
+#define imx51_add_vpu() imx_add_vpu(&imx51_vpu_data)
+
+extern const struct imx_tve_data imx51_tve_data __initconst;
+#define imx51_add_tve(pdata) \
+ imx_add_tve(&imx51_tve_data, pdata)
+
+#define imx51_add_lcdif(pdata) \
+ platform_device_register_resndata(NULL, "mxc_lcdif",\
+ 0, NULL, 0, pdata, sizeof(*pdata));
+
+#define imx51_add_v4l2_output(id) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_output",\
+ id, NULL, 0, NULL, 0);
+
+#define imx51_add_v4l2_capture(id) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_capture",\
+ id, NULL, 0, NULL, 0);
+
+extern const struct imx_spdif_data imx51_imx_spdif_data __initconst;
+#define imx51_add_spdif(pdata) imx_add_spdif(&imx51_imx_spdif_data, pdata)
+
+extern const struct imx_spdif_dai_data imx51_spdif_dai_data __initconst;
+#define imx51_add_spdif_dai() imx_add_spdif_dai(&imx51_spdif_dai_data)
+
+#define imx51_add_spdif_audio_device(pdata) imx_add_spdif_audio_device()
+
+extern const struct imx_dvfs_core_data imx51_dvfs_core_data __initconst;
+#define imx51_add_dvfs_core(pdata) \
+ imx_add_dvfs_core(&imx51_dvfs_core_data, pdata)
+
+#define imx51_add_busfreq(pdata) imx_add_busfreq(pdata)
+
diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h
new file mode 100755
index 00000000..50b52146
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx53.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 Yong Shen. <Yong.Shen@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx53.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx53_fec_data;
+#define imx53_add_fec(pdata) \
+ imx_add_fec(&imx53_fec_data, pdata)
+
+extern const struct imx_imx_uart_1irq_data imx53_imx_uart_data[];
+#define imx53_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx53_imx_uart_data[id], pdata)
+
+
+extern const struct imx_imx_i2c_data imx53_imx_i2c_data[];
+#define imx53_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx53_imx_i2c_data[id], pdata)
+
+extern const struct imx_sdhci_esdhc_imx_data imx53_sdhci_esdhc_imx_data[];
+#define imx53_add_sdhci_esdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx53_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx53_ecspi_data[];
+#define imx53_add_ecspi(id, pdata) \
+ imx_add_spi_imx(&imx53_ecspi_data[id], pdata)
+
+extern const struct imx_imx2_wdt_data imx53_imx2_wdt_data[];
+#define imx53_add_imx2_wdt(id, pdata) \
+ imx_add_imx2_wdt(&imx53_imx2_wdt_data[id])
+
+extern const struct imx_mxc_pwm_data imx53_mxc_pwm_data[] __initconst;
+#define imx53_add_mxc_pwm(id) \
+ imx_add_mxc_pwm(&imx53_mxc_pwm_data[id])
+
+#define imx53_add_mxc_pwm_backlight(id, pdata) \
+ platform_device_register_resndata(NULL, "pwm-backlight",\
+ id, NULL, 0, pdata, sizeof(*pdata));
+
+extern const struct imx_ipuv3_data imx53_ipuv3_data __initconst;
+#define imx53_add_ipuv3(id, pdata) imx_add_ipuv3(id, &imx53_ipuv3_data, pdata)
+#define imx53_add_ipuv3fb(id, pdata) imx_add_ipuv3_fb(id, pdata)
+
+extern const struct imx_vpu_data imx53_vpu_data __initconst;
+#define imx53_add_vpu() imx_add_vpu(&imx53_vpu_data)
+
+extern const struct imx_tve_data imx53_tve_data __initconst;
+#define imx53_add_tve(pdata) \
+ imx_add_tve(&imx53_tve_data, pdata)
+
+extern const struct imx_dvfs_core_data imx53_dvfs_core_data __initconst;
+#define imx53_add_dvfs_core(pdata) \
+ imx_add_dvfs_core(&imx53_dvfs_core_data, pdata)
+
+#define imx53_add_busfreq(pdata) imx_add_busfreq(pdata)
+
+extern const struct imx_srtc_data imx53_imx_srtc_data __initconst;
+#define imx53_add_srtc() \
+ imx_add_srtc(&imx53_imx_srtc_data)
+
+#define imx53_add_lcdif(pdata) \
+ platform_device_register_resndata(NULL, "mxc_lcdif",\
+ 0, NULL, 0, pdata, sizeof(*pdata));
+
+#define imx53_add_v4l2_output(id) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_output",\
+ id, NULL, 0, NULL, 0);
+
+#define imx53_add_v4l2_capture(id) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_capture",\
+ id, NULL, 0, NULL, 0);
+
+extern const struct imx_ahci_data imx53_ahci_data[] __initconst;
+#define imx53_add_ahci(id, pdata) \
+ imx_add_ahci(&imx53_ahci_data[id], pdata)
+
+extern const struct imx_imx_ssi_data imx53_imx_ssi_data[] __initconst;
+#define imx53_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx53_imx_ssi_data[id], pdata)
+
+extern const struct imx_iim_data imx53_imx_iim_data __initconst;
+#define imx53_add_iim(pdata) \
+ imx_add_iim(&imx53_imx_iim_data, pdata)
+
+extern const struct imx_mxc_gpu_data imx53_gpu_data __initconst;
+#define imx53_add_mxc_gpu(pdata) \
+ imx_add_mxc_gpu(&imx53_gpu_data, pdata)
+
+extern const struct imx_ldb_data imx53_ldb_data __initconst;
+#define imx53_add_ldb(pdata) \
+ imx_add_ldb(&imx53_ldb_data, pdata);
+
+extern const struct imx_mxc_scc2_data imx53_mxc_scc2_data __initconst;
+#define imx53_add_mxc_scc2() \
+ imx_add_mxc_scc2(&imx53_mxc_scc2_data)
+
+extern const struct imx_spdif_data imx53_imx_spdif_data __initconst;
+#define imx53_add_spdif(pdata) imx_add_spdif(&imx53_imx_spdif_data, pdata)
+
+extern const struct imx_spdif_dai_data imx53_spdif_dai_data __initconst;
+#define imx53_add_spdif_dai() imx_add_spdif_dai(&imx53_spdif_dai_data)
+
+#define imx53_add_spdif_audio_device(pdata) imx_add_spdif_audio_device()
+extern const struct imx_imx_esai_data imx53_imx_esai_data[] __initconst;
+#define imx53_add_imx_esai(id, pdata) \
+ imx_add_imx_esai(&imx53_imx_esai_data[id], pdata)
+
+extern struct platform_device imx_ahci_device_hwmon;
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
new file mode 100755
index 00000000..f6f3f68e
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/irqs.h>
+
+static struct resource mxc_hsi2c_resources[] = {
+ {
+ .start = MX51_HSI2C_DMA_BASE_ADDR,
+ .end = MX51_HSI2C_DMA_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_HS_I2C,
+ .end = MX51_MXC_INT_HS_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_hsi2c_device = {
+ .name = "imx-i2c",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(mxc_hsi2c_resources),
+ .resource = mxc_hsi2c_resources
+};
+
+struct platform_device mxc_pm_device = {
+ .name = "mx5_pm",
+ .id = 0,
+};
+
+static u64 usb_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource usbotg_udc_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR,
+ .end = MX51_OTG_BASE_ADDR + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* OTG gadget device */
+struct platform_device mxc_usbdr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(usbotg_udc_resources),
+ .resource = usbotg_udc_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource usbotg_host_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR,
+ .end = MX51_OTG_BASE_ADDR + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbdr_host_device = {
+ .name = "fsl-ehci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(usbotg_host_resources),
+ .resource = usbotg_host_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource usbotg_wakeup_resources[] = {
+ {
+ .start = MX51_MXC_INT_USB_OTG,/* wakeup irq */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MX51_MXC_INT_USB_OTG,/* usb core irq */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbdr_wakeup_device = {
+ .name = "usb_wakeup",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(usbotg_wakeup_resources),
+ .resource = usbotg_wakeup_resources,
+};
+
+static struct resource usbotg_xcvr_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR,
+ .end = MX51_OTG_BASE_ADDR + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbdr_otg_device = {
+ .name = "fsl-usb2-otg",
+ .id = -1,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = usbotg_xcvr_resources,
+ .num_resources = ARRAY_SIZE(usbotg_xcvr_resources),
+};
+
+static struct resource usbh1_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR + 0x200,
+ .end = MX51_OTG_BASE_ADDR + 0x200 + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_H1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbh1_device = {
+ .name = "fsl-ehci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(usbh1_resources),
+ .resource = usbh1_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource usbh1_wakeup_resources[] = {
+ {
+ .start = MX51_MXC_INT_USB_H1, /*wakeup irq*/
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MX51_MXC_INT_USB_H1,
+ .flags = IORESOURCE_IRQ,/* usb core irq */
+ },
+};
+
+struct platform_device mxc_usbh1_wakeup_device = {
+ .name = "usb_wakeup",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(usbh1_wakeup_resources),
+ .resource = usbh1_wakeup_resources,
+};
+
+static struct resource usbh2_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR + 0x400,
+ .end = MX51_OTG_BASE_ADDR + 0x400 + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_H2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbh2_device = {
+ .name = "fsl-ehci",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(usbh2_resources),
+ .resource = usbh2_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource usbh2_wakeup_resources[] = {
+ {
+ .start = MX51_MXC_INT_USB_H2,
+ .flags = IORESOURCE_IRQ,/* wakeup irq */
+ },
+ {
+ .start = MX51_MXC_INT_USB_H2,
+ .flags = IORESOURCE_IRQ,/* usb core irq */
+ },
+};
+
+struct platform_device mxc_usbh2_wakeup_device = {
+ .name = "usb_wakeup",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(usbh2_wakeup_resources),
+ .resource = usbh2_wakeup_resources,
+};
+
+struct platform_device imx_ahci_device_hwmon = {
+ .name = "imx-ahci-hwmon",
+ .id = -1,
+};
+
+static struct mxc_gpio_port mxc_gpio_ports[] = {
+ {
+ .chip.label = "gpio-0",
+ .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
+ .irq = MX51_MXC_INT_GPIO1_LOW,
+ .irq_high = MX51_MXC_INT_GPIO1_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START
+ },
+ {
+ .chip.label = "gpio-1",
+ .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
+ .irq = MX51_MXC_INT_GPIO2_LOW,
+ .irq_high = MX51_MXC_INT_GPIO2_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
+ },
+ {
+ .chip.label = "gpio-2",
+ .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
+ .irq = MX51_MXC_INT_GPIO3_LOW,
+ .irq_high = MX51_MXC_INT_GPIO3_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
+ },
+ {
+ .chip.label = "gpio-3",
+ .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
+ .irq = MX51_MXC_INT_GPIO4_LOW,
+ .irq_high = MX51_MXC_INT_GPIO4_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
+ },
+ {
+ .chip.label = "gpio-4",
+ .base = MX53_IO_ADDRESS(MX53_GPIO5_BASE_ADDR),
+ .irq = MX53_INT_GPIO5_LOW,
+ .irq_high = MX53_INT_GPIO5_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
+ },
+ {
+ .chip.label = "gpio-5",
+ .base = MX53_IO_ADDRESS(MX53_GPIO6_BASE_ADDR),
+ .irq = MX53_INT_GPIO6_LOW,
+ .irq_high = MX53_INT_GPIO6_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
+ },
+ {
+ .chip.label = "gpio-6",
+ .base = MX53_IO_ADDRESS(MX53_GPIO7_BASE_ADDR),
+ .irq = MX53_INT_GPIO7_LOW,
+ .irq_high = MX53_INT_GPIO7_HIGH,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
+ },
+};
+
+int __init imx51_register_gpios(void)
+{
+ return mxc_gpio_init(mxc_gpio_ports, 4);
+}
+
+int __init imx53_register_gpios(void)
+{
+ return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
+}
+
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
new file mode 100755
index 00000000..53ee4748
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.h
@@ -0,0 +1,14 @@
+extern struct platform_device mxc_usbdr_host_device;
+extern struct platform_device mxc_usbh1_device;
+extern struct platform_device mxc_usbh2_device;
+extern struct platform_device mxc_usbdr_udc_device;
+extern struct platform_device mxc_hsi2c_device;
+extern struct platform_device mxc_pwm1_backlight_device;
+extern struct platform_device mxc_pwm2_backlight_device;
+extern struct platform_device mxc_v4l2cap_device;
+extern struct platform_device mxc_v4l2out_device;
+extern struct platform_device mxc_pm_device;
+extern struct platform_device mxc_usbdr_otg_device;
+extern struct platform_device mxc_usbdr_wakeup_device;
+extern struct platform_device mxc_usbh1_wakeup_device;
+extern struct platform_device mxc_usbh2_wakeup_device;
diff --git a/arch/arm/mach-mx5/efika.h b/arch/arm/mach-mx5/efika.h
new file mode 100644
index 00000000..014aa985
--- /dev/null
+++ b/arch/arm/mach-mx5/efika.h
@@ -0,0 +1,10 @@
+#ifndef _EFIKA_H
+#define _EFIKA_H
+
+#define EFIKA_WLAN_EN IMX_GPIO_NR(2, 16)
+#define EFIKA_WLAN_RESET IMX_GPIO_NR(2, 10)
+#define EFIKA_USB_PHY_RESET IMX_GPIO_NR(2, 9)
+
+void __init efika_board_common_init(void);
+
+#endif
diff --git a/arch/arm/mach-mx5/ehci.c b/arch/arm/mach-mx5/ehci.c
new file mode 100644
index 00000000..7ce12c80
--- /dev/null
+++ b/arch/arm/mach-mx5/ehci.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define MXC_OTG_OFFSET 0
+#define MXC_H1_OFFSET 0x200
+#define MXC_H2_OFFSET 0x400
+
+/* USB_CTRL */
+#define MXC_OTG_UCTRL_OWIE_BIT (1 << 27) /* OTG wakeup intr enable */
+#define MXC_OTG_UCTRL_OPM_BIT (1 << 24) /* OTG power mask */
+#define MXC_H1_UCTRL_H1UIE_BIT (1 << 12) /* Host1 ULPI interrupt enable */
+#define MXC_H1_UCTRL_H1WIE_BIT (1 << 11) /* HOST1 wakeup intr enable */
+#define MXC_H1_UCTRL_H1PM_BIT (1 << 8) /* HOST1 power mask */
+
+/* USB_PHY_CTRL_FUNC */
+#define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8) /* OTG Disable Overcurrent Event */
+#define MXC_H1_OC_DIS_BIT (1 << 5) /* UH1 Disable Overcurrent Event */
+
+/* USBH2CTRL */
+#define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
+#define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
+#define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
+
+#define MXC_USBCMD_OFFSET 0x140
+
+/* USBCMD */
+#define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */
+
+int mx51_initialize_usb_hw(int port, unsigned int flags)
+{
+ unsigned int v;
+ void __iomem *usb_base;
+ void __iomem *usbotg_base;
+ void __iomem *usbother_base;
+ int ret = 0;
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base) {
+ printk(KERN_ERR "%s(): ioremap failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ switch (port) {
+ case 0: /* OTG port */
+ usbotg_base = usb_base + MXC_OTG_OFFSET;
+ break;
+ case 1: /* Host 1 port */
+ usbotg_base = usb_base + MXC_H1_OFFSET;
+ break;
+ case 2: /* Host 2 port */
+ usbotg_base = usb_base + MXC_H2_OFFSET;
+ break;
+ default:
+ printk(KERN_ERR"%s no such port %d\n", __func__, port);
+ ret = -ENOENT;
+ goto error;
+ }
+ usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+ switch (port) {
+ case 0: /*OTG port */
+ if (flags & MXC_EHCI_INTERNAL_PHY) {
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED) {
+ /* OC/USBPWR is not used */
+ v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
+ } else {
+ /* OC/USBPWR is used */
+ v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
+ }
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+ v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
+ if (flags & MXC_EHCI_WAKEUP_ENABLED)
+ v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
+ else
+ v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v |= MXC_OTG_UCTRL_OPM_BIT;
+ else
+ v &= ~MXC_OTG_UCTRL_OPM_BIT;
+ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
+ }
+ break;
+ case 1: /* Host 1 */
+ /*Host ULPI */
+ v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
+ if (flags & MXC_EHCI_WAKEUP_ENABLED) {
+ /* HOST1 wakeup/ULPI intr enable */
+ v |= (MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
+ } else {
+ /* HOST1 wakeup/ULPI intr disable */
+ v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);
+ }
+
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
+ else
+ v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
+ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
+
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
+ else
+ v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+ v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
+ if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
+ /* Interrupt Threshold Control:Immediate (no threshold) */
+ v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
+ __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
+ break;
+ case 2: /* Host 2 ULPI */
+ v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
+ if (flags & MXC_EHCI_WAKEUP_ENABLED) {
+ /* HOST1 wakeup/ULPI intr enable */
+ v |= (MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
+ } else {
+ /* HOST1 wakeup/ULPI intr disable */
+ v &= ~(MXC_H2_UCTRL_H2WIE_BIT | MXC_H2_UCTRL_H2UIE_BIT);
+ }
+
+ if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+ v &= ~MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
+ else
+ v |= MXC_H2_UCTRL_H2PM_BIT; /* HOST2 power mask used*/
+ __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
+ break;
+ }
+
+error:
+ iounmap(usb_base);
+ return ret;
+}
+
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
new file mode 100644
index 00000000..97292d20
--- /dev/null
+++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
@@ -0,0 +1,219 @@
+/*
+ *
+ * Copyright (C) 2010 Eric Bénard <eric@eukrea.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/leds.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/mach/arch.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+#define MBIMX51_TSC2007_GPIO IMX_GPIO_NR(3, 30)
+#define MBIMX51_TSC2007_IRQ (MXC_INTERNAL_IRQS + MBIMX51_TSC2007_GPIO)
+#define MBIMX51_LED0 IMX_GPIO_NR(3, 5)
+#define MBIMX51_LED1 IMX_GPIO_NR(3, 6)
+#define MBIMX51_LED2 IMX_GPIO_NR(3, 7)
+#define MBIMX51_LED3 IMX_GPIO_NR(3, 8)
+
+static struct gpio_led mbimx51_leds[] = {
+ {
+ .name = "led0",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = MBIMX51_LED0,
+ },
+ {
+ .name = "led1",
+ .default_trigger = "nand-disk",
+ .active_low = 1,
+ .gpio = MBIMX51_LED1,
+ },
+ {
+ .name = "led2",
+ .default_trigger = "mmc0",
+ .active_low = 1,
+ .gpio = MBIMX51_LED2,
+ },
+ {
+ .name = "led3",
+ .default_trigger = "default-on",
+ .active_low = 1,
+ .gpio = MBIMX51_LED3,
+ },
+};
+
+static struct gpio_led_platform_data mbimx51_leds_info = {
+ .leds = mbimx51_leds,
+ .num_leds = ARRAY_SIZE(mbimx51_leds),
+};
+
+static struct platform_device mbimx51_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mbimx51_leds_info,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mbimx51_leds_gpio,
+};
+
+static iomux_v3_cfg_t mbimx51_pads[] = {
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+
+ /* UART3 */
+ MX51_PAD_UART3_RXD__UART3_RXD,
+ MX51_PAD_UART3_TXD__UART3_TXD,
+ MX51_PAD_KEY_COL4__UART3_RTS,
+ MX51_PAD_KEY_COL5__UART3_CTS,
+
+ /* TSC2007 IRQ */
+ MX51_PAD_NANDF_D10__GPIO3_30,
+
+ /* LEDS */
+ MX51_PAD_DISPB2_SER_DIN__GPIO3_5,
+ MX51_PAD_DISPB2_SER_DIO__GPIO3_6,
+ MX51_PAD_DISPB2_SER_CLK__GPIO3_7,
+ MX51_PAD_DISPB2_SER_RS__GPIO3_8,
+
+ /* KPP */
+ MX51_PAD_KEY_ROW0__KEY_ROW0,
+ MX51_PAD_KEY_ROW1__KEY_ROW1,
+ MX51_PAD_KEY_ROW2__KEY_ROW2,
+ MX51_PAD_KEY_ROW3__KEY_ROW3,
+ MX51_PAD_KEY_COL0__KEY_COL0,
+ MX51_PAD_KEY_COL1__KEY_COL1,
+ MX51_PAD_KEY_COL2__KEY_COL2,
+ MX51_PAD_KEY_COL3__KEY_COL3,
+
+ /* SD 1 */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SD 2 */
+ MX51_PAD_SD2_CMD__SD2_CMD,
+ MX51_PAD_SD2_CLK__SD2_CLK,
+ MX51_PAD_SD2_DATA0__SD2_DATA0,
+ MX51_PAD_SD2_DATA1__SD2_DATA1,
+ MX51_PAD_SD2_DATA2__SD2_DATA2,
+ MX51_PAD_SD2_DATA3__SD2_DATA3,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static int mbimx51_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(0, 1, KEY_2),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_UP),
+
+ KEY(1, 0, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(1, 2, KEY_6),
+ KEY(1, 3, KEY_LEFT),
+
+ KEY(2, 0, KEY_7),
+ KEY(2, 1, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(2, 3, KEY_RIGHT),
+
+ KEY(3, 0, KEY_0),
+ KEY(3, 1, KEY_DOWN),
+ KEY(3, 2, KEY_ESC),
+ KEY(3, 3, KEY_ENTER),
+};
+
+static const struct matrix_keymap_data mbimx51_map_data __initconst = {
+ .keymap = mbimx51_keymap,
+ .keymap_size = ARRAY_SIZE(mbimx51_keymap),
+};
+
+static int tsc2007_get_pendown_state(void)
+{
+ return !gpio_get_value(MBIMX51_TSC2007_GPIO);
+}
+
+struct tsc2007_platform_data tsc2007_data = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = tsc2007_get_pendown_state,
+};
+
+static struct i2c_board_info mbimx51_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tsc2007", 0x49),
+ .irq = MBIMX51_TSC2007_IRQ,
+ .platform_data = &tsc2007_data,
+ }, {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+/*
+ * baseboard initialization.
+ */
+void __init eukrea_mbimx51_baseboard_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mbimx51_pads,
+ ARRAY_SIZE(mbimx51_pads));
+
+ imx51_add_imx_uart(1, NULL);
+ imx51_add_imx_uart(2, &uart_pdata);
+
+ gpio_request(MBIMX51_LED0, "LED0");
+ gpio_direction_output(MBIMX51_LED0, 1);
+ gpio_free(MBIMX51_LED0);
+ gpio_request(MBIMX51_LED1, "LED1");
+ gpio_direction_output(MBIMX51_LED1, 1);
+ gpio_free(MBIMX51_LED1);
+ gpio_request(MBIMX51_LED2, "LED2");
+ gpio_direction_output(MBIMX51_LED2, 1);
+ gpio_free(MBIMX51_LED2);
+ gpio_request(MBIMX51_LED3, "LED3");
+ gpio_direction_output(MBIMX51_LED3, 1);
+ gpio_free(MBIMX51_LED3);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx51_add_imx_keypad(&mbimx51_map_data);
+
+ gpio_request(MBIMX51_TSC2007_GPIO, "tsc2007_irq");
+ gpio_direction_input(MBIMX51_TSC2007_GPIO);
+ irq_set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING);
+ i2c_register_board_info(1, mbimx51_i2c_devices,
+ ARRAY_SIZE(mbimx51_i2c_devices));
+
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+ imx51_add_sdhci_esdhc_imx(1, NULL);
+}
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
new file mode 100644
index 00000000..31c871ec
--- /dev/null
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx51.h>
+#include <mach/audmux.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
+ /* LED */
+ MX51_PAD_NANDF_D10__GPIO3_30,
+ /* SWITCH */
+ _MX51_PAD_NANDF_D9__GPIO3_31 | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
+ /* UART2 */
+ MX51_PAD_UART2_RXD__UART2_RXD,
+ MX51_PAD_UART2_TXD__UART2_TXD,
+ /* UART 3 */
+ MX51_PAD_UART3_RXD__UART3_RXD,
+ MX51_PAD_UART3_TXD__UART3_TXD,
+ MX51_PAD_KEY_COL4__UART3_RTS,
+ MX51_PAD_KEY_COL5__UART3_CTS,
+ /* SD */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+ /* SD1 CD */
+ _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
+};
+
+#define GPIO_LED1 IMX_GPIO_NR(3, 30)
+#define GPIO_SWITCH1 IMX_GPIO_NR(3, 31)
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static const struct gpio_keys_platform_data
+ eukrea_mbimxsd_button_data __initconst = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx51sd init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd51_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+ imx51_add_imx_uart(1, NULL);
+ imx51_add_imx_uart(2, &uart_pdata);
+
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+}
diff --git a/arch/arm/mach-mx5/imx_bt_rfkill.c b/arch/arm/mach-mx5/imx_bt_rfkill.c
new file mode 100755
index 00000000..372ba0fe
--- /dev/null
+++ b/arch/arm/mach-mx5/imx_bt_rfkill.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @file imx_bt_rfkill.c
+ *
+ * @brief This driver is implement a rfkill control interface of bluetooth
+ * chip on i.MX serial boards. Register the power regulator function and
+ * reset function in platform data.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/init.h>
+#include <linux/rfkill.h>
+#include <mach/hardware.h>
+#include <mach/imx_rfkill.h>
+
+static int system_in_suspend;
+
+static int imx_bt_set_block(void *rfkdata, bool blocked)
+{
+ struct imx_bt_rfkill_platform_data *data = rfkdata;
+ int ret;
+
+ /* Bluetooth stack will reset the bluetooth chip during
+ * resume, since we keep bluetooth's power during suspend,
+ * don't let rfkill to actually reset the chip. */
+ if (system_in_suspend)
+ return 0;
+
+ pr_info("rfkill: Bluetooth RF turn %s\n", blocked ? "off" : "on");
+ if (!blocked)
+ ret = data->power_change(1);
+ else
+ ret = data->power_change(0);
+
+ return ret;
+}
+
+static const struct rfkill_ops imx_bt_rfkill_ops = {
+ .set_block = imx_bt_set_block,
+};
+
+static int imx_bt_power_event(struct notifier_block *this,
+ unsigned long event, void *dummy)
+{
+ switch (event) {
+ case PM_SUSPEND_PREPARE:
+ system_in_suspend = 1;
+ /* going to suspend, don't reset chip */
+ break;
+ case PM_POST_SUSPEND:
+ system_in_suspend = 0;
+ /* System is resume, can reset chip */
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block imx_bt_power_notifier = {
+ .notifier_call = imx_bt_power_event,
+};
+
+static int imx_bt_rfkill_probe(struct platform_device *dev)
+{
+ int rc;
+ struct rfkill *rfk;
+
+ struct imx_bt_rfkill_platform_data *data = dev->dev.platform_data;
+
+ if (data->power_change == NULL) {
+ rc = -EINVAL;
+ dev_err(&dev->dev, "no power_change function\n");
+ goto error_check_func;
+ }
+
+ rc = register_pm_notifier(&imx_bt_power_notifier);
+ if (rc)
+ goto error_check_func;
+
+ rfk = rfkill_alloc("imx-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
+ &imx_bt_rfkill_ops, data);
+
+ if (!rfk) {
+ rc = -ENOMEM;
+ goto error_rfk_alloc;
+ }
+
+ rc = rfkill_register(rfk);
+ if (rc)
+ goto error_rfkill;
+
+ platform_set_drvdata(dev, rfk);
+ printk(KERN_INFO "imx_bt_rfkill driver success loaded\n");
+ return 0;
+
+error_rfkill:
+ rfkill_destroy(rfk);
+error_rfk_alloc:
+error_check_func:
+ return rc;
+}
+
+static int __devexit imx_bt_rfkill_remove(struct platform_device *dev)
+{
+ struct imx_bt_rfkill_platform_data *data = dev->dev.platform_data;
+ struct rfkill *rfk = platform_get_drvdata(dev);
+
+ platform_set_drvdata(dev, NULL);
+
+ if (rfk) {
+ rfkill_unregister(rfk);
+ rfkill_destroy(rfk);
+ }
+
+ data->power_change(0);
+
+ return 0;
+}
+
+static struct platform_driver imx_bt_rfkill_drv = {
+ .driver = {
+ .name = "imx_bt_rfkill",
+ },
+
+ .probe = imx_bt_rfkill_probe,
+ .remove = __devexit_p(imx_bt_rfkill_remove),
+};
+
+static int __init imx_bt_rfkill_init(void)
+{
+ return platform_driver_register(&imx_bt_rfkill_drv);
+}
+
+module_init(imx_bt_rfkill_init);
+
+static void __exit imx_bt_rfkill_exit(void)
+{
+ platform_driver_unregister(&imx_bt_rfkill_drv);
+}
+
+module_exit(imx_bt_rfkill_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("RFKill control interface of BT on MX53 SMD");
diff --git a/arch/arm/mach-mx5/mm-mx50.c b/arch/arm/mach-mx5/mm-mx50.c
new file mode 100644
index 00000000..b9c363b5
--- /dev/null
+++ b/arch/arm/mach-mx5/mm-mx50.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+/*
+ * Define the MX50 memory map.
+ */
+static struct map_desc mx50_io_desc[] __initdata = {
+ imx_map_entry(MX50, TZIC, MT_DEVICE),
+ imx_map_entry(MX50, SPBA0, MT_DEVICE),
+ imx_map_entry(MX50, AIPS1, MT_DEVICE),
+ imx_map_entry(MX50, AIPS2, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx50_map_io(void)
+{
+ iotable_init(mx50_io_desc, ARRAY_SIZE(mx50_io_desc));
+}
+
+void __init imx50_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX50);
+ mxc_iomux_v3_init(MX50_IO_ADDRESS(MX50_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX50_IO_ADDRESS(MX50_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx50_gpio_ports[] = {
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 0, 1, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 1, 2, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 2, 3, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 3, 4, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 4, 5, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(MX50, 5, 6, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH),
+};
+
+void __init mx50_init_irq(void)
+{
+ tzic_init_irq(MX50_IO_ADDRESS(MX50_TZIC_BASE_ADDR));
+ mxc_gpio_init(imx50_gpio_ports, ARRAY_SIZE(imx50_gpio_ports));
+}
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
new file mode 100644
index 00000000..ff557301
--- /dev/null
+++ b/arch/arm/mach-mx5/mm.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * Define the MX51 memory map.
+ */
+static struct map_desc mx51_io_desc[] __initdata = {
+ imx_map_entry(MX51, IRAM, MT_DEVICE),
+ imx_map_entry(MX51, DEBUG, MT_DEVICE),
+ imx_map_entry(MX51, AIPS1, MT_DEVICE),
+ imx_map_entry(MX51, SPBA0, MT_DEVICE),
+ imx_map_entry(MX51, AIPS2, MT_DEVICE),
+};
+
+/*
+ * Define the MX53 memory map.
+ */
+static struct map_desc mx53_io_desc[] __initdata = {
+ imx_map_entry(MX53, AIPS1, MT_DEVICE),
+ imx_map_entry(MX53, SPBA0, MT_DEVICE),
+ imx_map_entry(MX53, AIPS2, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx51_map_io(void)
+{
+ iotable_init(mx51_io_desc, ARRAY_SIZE(mx51_io_desc));
+}
+
+void __init imx51_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX51);
+ mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
+}
+
+void __init mx53_map_io(void)
+{
+ iotable_init(mx53_io_desc, ARRAY_SIZE(mx53_io_desc));
+}
+
+void __init imx53_init_early(void)
+{
+ mxc_set_cpu_type(MXC_CPU_MX53);
+ mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
+}
+
+int imx51_register_gpios(void);
+
+void __init mx51_init_irq(void)
+{
+ unsigned long tzic_addr;
+ void __iomem *tzic_virt;
+
+ if (mx51_revision() < IMX_CHIP_REVISION_2_0)
+ tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+ else
+ tzic_addr = MX51_TZIC_BASE_ADDR;
+
+ tzic_virt = ioremap(tzic_addr, SZ_16K);
+ if (!tzic_virt)
+ panic("unable to map TZIC interrupt controller\n");
+
+ tzic_init_irq(tzic_virt);
+ imx51_register_gpios();
+}
+
+int imx53_register_gpios(void);
+
+void __init mx53_init_irq(void)
+{
+ unsigned long tzic_addr;
+ void __iomem *tzic_virt;
+
+ tzic_addr = MX53_TZIC_BASE_ADDR;
+
+ tzic_virt = ioremap(tzic_addr, SZ_16K);
+ if (!tzic_virt)
+ panic("unable to map TZIC interrupt controller\n");
+
+ tzic_init_irq(tzic_virt);
+ imx53_register_gpios();
+}
diff --git a/arch/arm/mach-mx5/mx50_ddr_freq.S b/arch/arm/mach-mx5/mx50_ddr_freq.S
new file mode 100755
index 00000000..06bb4fa5
--- /dev/null
+++ b/arch/arm/mach-mx5/mx50_ddr_freq.S
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * mx50_ddr_freq_change
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(mx50_ddr_freq_change)
+ stmfd sp!, {r4,r5,r6, r7, r8, r9} @ Save registers
+
+ mov r6, r0 @save CCM address
+ mov r5, r1 @save DataBahn address
+ mov r4, r2 @save new freq requested
+ mov r8, r3 @save the DRAM settings array
+
+ /* Make sure no TLB miss will occur when the DDR is in self refresh. */
+ /* Invalidate TLB single entry to ensure that the address is not
+ * already in the TLB.
+ */
+ adr r3, LoopCKE2 @Address in this function.
+ mcr p15, 0, r3, c8, c7, 1 @ Make sure freq code address
+ @ is not already in TLB.
+ mcr p15, 0, r6, c8, c7, 1 @ Make sure CCM address
+ @ is not already in TLB.
+ mcr p15, 0, r5, c8, c7, 1 @ make sure Databahn address
+ @ is not already in TLB.
+ mcr p15, 0, r8, c8, c7, 1 @ make sure Databahn settings
+ @ arrayis not already in TLB.
+
+ mrc p15, 0, r0, c10, c0, 0 @ Read the TLB lockdown register
+ orr r0, r0, #1 @ Set the Preserve bit.
+ mcr p15, 0, r0, c10, c0, 0 @ Write to the lockdown register
+ ldr r2, [r6] @ TLB will miss,
+ @CCM address will be loaded
+ ldr r2, [r5] @ TLB will miss,
+ @Databahn address will be loaded
+ ldr r2, [r8] @ TLB will miss,
+ @Databahn settings will be loaded
+
+ ldr r2, [r3] @ TLB will miss
+ mrc p15, 0, r0, c10, c0, 0 @ Read the lockdown register
+ @ (victim will be incremented)
+ bic r0, r0, #1 @ Clear the preserve bit
+ mcr p15, 0, r0, c10, c0, 0 @ Write to the lockdown register.
+
+ /* If Databahn is in LPM4, exit that mode first. */
+ ldr r9,[r5, #0x50] @Store LPM mode in r9
+ mov r0, r9
+ bic r0, #0x1F
+ str r0,[r5, #0x50]
+
+LoopCKE2:
+ /*Wait for CKE = 1 */
+ ldr r0,[r5, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ bne LoopCKE2
+
+/* Wait for the databahn to idle
+ Meaning, no access to the databahn is
+ being made.
+*/
+NotIdle:
+ ldr r0,[r5, #0x13c]
+ and r0, r0, #0x100
+ ldr r2, =0x100
+ cmp r0, r2
+ beq NotIdle
+
+ /*
+ * Make sure the DDR is self-refresh, before switching its frequency
+ * and clock source
+ */
+
+ /* Step 1: Enter self-refresh mode */
+ ldr r0,[r5, #0x4c]
+ orr r0,r0,#0x1
+ str r0,[r5, #0x4c]
+
+ /* Step 2: Poll the CKE_STATUS bit. */
+LoopCKE0:
+ /* Wait for CKE = 0 */
+ ldr r0,[r5, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ beq LoopCKE0
+
+ /* Step 3: Mask the DLL lock state change, set bit 8 in int_mask. */
+ ldr r0, [r5, #0xac]
+ orr r0, r0, #0x100
+ str r0, [r5, #0xac]
+
+ /* Step 4: Stop the Controller. */
+ ldr r0,[r5]
+ bic r0, r0, #0x1
+ str r0,[r5]
+
+ /* Step 5: Clear the DLL lock state change bit 8 in int_ack */
+ ldr r0, [r5, #0xa8]
+ orr r0, r0, #0x1000000
+ str r0, [r5, #0xa8]
+
+ /* Step 6: Clear the interrupt mask for DLL lock state.
+ * Bit 8 in int_mask */
+ ldr r0, [r5, #0xac]
+ bic r0, r0, #0x100
+ str r0, [r5, #0xac]
+
+ /* Change the freq now */
+ /* If the freq req is below 24MHz, set DDR to synchronous mode.
+ * else set to async mode. */
+ ldr r0, =24000000
+ cmp r4, r0
+ bgt Async_Mode
+
+ /* Set the DDR to be Synchronous
+ mode. */
+ /* Set the Databahn to sync mode. */
+ ldr r0, [r5, #0xdc]
+ orr r0, r0, #0x30000
+ str r0, [r5, #0xdc]
+
+ /* Turn OFF the DDR_CKLGATE_MASK in MXC_CCM_DDR */
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0xC0000000
+ str r0, [r6, #0x98]
+
+ /* Check if XTAL can source the DDR. */
+ ldr r0, =24000000
+ cmp r4, r0
+ ble databahn_ddr_24
+
+ /*Source DDR from PLL1. Setup the dividers accordingly. */
+ ldr r0, =800000000
+ ldr r3, =1
+Loop1:
+ sub r0, r0, r4
+ cmp r0, r4
+ blt Div_Found
+ add r3, r3, #1
+ bgt Loop1
+
+Div_Found:
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x3f
+ orr r0, r0, r3
+ str r0, [r6, #0x94]
+ /* Set the DDR to sourced from PLL1 in sync path */
+ ldr r0, [r6, #0x90]
+ orr r0, r0, #0x3
+ str r0, [r6, #0x90]
+
+ /* Turn OFF the DDR_CKLGATE_MASK in MXC_CCM_DDR */
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0xC0000000
+ str r0, [r6, #0x98]
+
+ ldr r0, =24000000
+ cmp r4, r0
+ beq databahn_ddr_24
+
+ b Ddr_not_24
+
+databahn_ddr_24:
+ /* Restore from the ddr settings array */
+ ldr r1, [r8] @size of array
+ add r8, r8, #8 @skip first eight bytes in array
+update_ddr:
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_ddr
+
+ /* Set SYS_CLK to be sourced from 24MHz. */
+ /* Set the SYS_XTAL_DIV */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x3c0
+ orr r0, r0, #0x40
+ str r0, [r6, #0x94]
+
+ /* Enable SYS_XTAL_CLKGATE. */
+ ldr r0, [r6, #0x94]
+ orr r0, r0, #0xC0000000
+ str r0, [r6, #0x94]
+
+ /* set SYS_CLK to be sourced from XTAL. */
+ ldr r0, [r6, #0x90]
+ bic r0, r0, #0x1
+ str r0, [r6, #0x90]
+
+ /* Disable SYS_PLL_CLKGATE.*/
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x30000000
+ str r0, [r6, #0x94]
+ b Setup_Done
+
+Ddr_not_24:
+Async_Mode:
+ /* If SYS_CLK is running at 24MHz, increase
+ * it to 200MHz.
+ */
+ /* r7 indicates that we are moving from 133Mhz<-> 266MHz */
+ ldr r7, =1
+ ldr r0, [r6, #0x90]
+ and r0, r0, #0x1
+ cmp r0, #0
+ bne Sys_Clk_Not_24
+ ldr r7, =0
+
+ /* Disable SYS_PLL_CLKGATE. */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x30000000
+ str r0, [r6, #0x94]
+
+ /* Set the new divider. */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x3f
+ orr r0, r0, #4
+ str r0, [r6, #0x94]
+
+ /* Enable SYS_PLL_CLKGATE. */
+ ldr r0, [r6, #0x94]
+ orr r0, r0, #0x30000000
+ str r0, [r6, #0x94]
+
+ /* SYS_CLK to be sourced from PLL1. */
+ ldr r0, [r6, #0x90]
+ orr r0, r0, #0x3
+ str r0, [r6, #0x90]
+
+ /* Disable SYS_XTAL_CLKGATE. */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0xC0000000
+ str r0, [r6, #0x94]
+
+Sys_Clk_Not_24:
+ /* Set the Databahn to async mode. */
+ ldr r0, [r5, #0xdc]
+ and r0, r0, #0xfffcffff
+ str r0, [r5, #0xdc]
+
+ /*Source DDR from PLL1. Setup the dividers accordingly. */
+ ldr r0, =800000000
+ ldr r3, =1
+Loop2:
+ sub r0, r0, r4
+ cmp r0, r4
+ blt Div_Found1
+ add r3, r3, #1
+ bgt Loop2
+
+Div_Found1:
+ /* Turn OFF the DDR_CKLGATE_MASK in MXC_CCM_DDR */
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0xC0000000
+ str r0, [r6, #0x98]
+
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0x3f
+ orr r0, r0, r3
+ str r0, [r6, #0x98]
+
+ /* Set the DDR to sourced from PLL1 in async path */
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0x40
+ str r0, [r6, #0x98]
+
+ /* Turn ON the DDR_CKLGATE_MASK in MXC_CCM_DDR */
+ ldr r0, [r6, #0x98]
+ orr r0, r0, #0xC0000000
+ str r0, [r6, #0x98]
+
+ ldr r0, =24000000
+ cmp r4, r0
+ beq databahn_ddr_24
+
+ cmp r7, #1
+ beq just_set_tref
+
+ /* Restore from the ddr settings array */
+ ldr r1, [r8] @size of array
+ add r8, r8, #8 @skip first eight bytes in array
+update_ddr1:
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_ddr1
+
+ b Setup_Done
+
+just_set_tref:
+ /* Check for mDDR v LPDDR2 memory type */
+ ldr r0, [r5]
+ ldr r2, =0x100
+ and r0, r0, #0xF00
+ cmp r0, r2
+ beq mddr_133_200
+
+lpddr2_133_266:
+ ldr r0, =133333333
+ cmp r4, r0
+ bgt ddr_266
+ ldr r0, =0x00050180
+ b tref_done
+ddr_266:
+ ldr r0, =0x00050300
+tref_done:
+ str r0, [r5, #0x40]
+ b Setup_Done
+
+mddr_133_200:
+ ldr r0, =133333333
+ cmp r4, r0
+ bgt mddr_200
+ ldr r0, =0x00050208
+ b tref_done1
+mddr_200:
+ ldr r0, =0x0005030f
+tref_done1:
+ str r0, [r5, #0x40]
+
+Setup_Done:
+ /* Start controller */
+ ldr r0,[r5]
+ orr r0, r0,#0x1
+ str r0,[r5]
+
+ /* Poll the DLL lock state change in int_status reg*/
+ /* DLL is bypassed in the 24MHz mode, so no waiting for DLL to lock. */
+ ldr r0, =24000000
+ cmp r4, r0
+ beq Exit_Self_Refresh
+
+DllLock:
+ ldr r0, [r5, #0xa8]
+ and r0, r0, #0x100
+ ldr r2, =0x100
+ cmp r0, r2
+ bne DllLock
+
+ /*Leave self-refresh mode */
+Exit_Self_Refresh:
+ ldr r0,[r5, #0x4c]
+ and r0,r0,#0xfffffffe
+ str r0,[r5, #0x4c]
+
+LoopCKE1:
+ /*Wait for CKE = 1 */
+ ldr r0,[r5, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ bne LoopCKE1
+
+ /* Put the databahn back to into the LPM mode. */
+ str r9,[r5, #0x50]
+
+ /* Restore registers */
+ ldmfd sp!, {r4,r5,r6, r7, r8, r9}
+ mov pc, lr
+
+ .type mx50_do_ddr_freq_change, #object
+ENTRY(mx50_do_ddr_freq_change)
+ .word mx50_ddr_freq_change
+ .size mx50_ddr_freq_change, . - mx50_ddr_freq_change
diff --git a/arch/arm/mach-mx5/mx50_freq.c b/arch/arm/mach-mx5/mx50_freq.c
new file mode 100755
index 00000000..de9fd7bc
--- /dev/null
+++ b/arch/arm/mach-mx5/mx50_freq.c
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx50_ddr.c
+ *
+ * @brief MX50 DDR specific information file.
+ *
+ *
+ *
+ * @ingroup PM
+ */
+#include <asm/io.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/iram_alloc.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+
+#define LP_APM_CLK 24000000
+#define HW_QOS_DISABLE 0x70
+#define HW_QOS_DISABLE_SET 0x74
+#define HW_QOS_DISABLE_CLR 0x78
+
+static struct clk *epdc_clk;
+
+/* DDR settings */
+unsigned long (*iram_ddr_settings)[2];
+unsigned long (*normal_databahn_settings)[2];
+unsigned int mx50_ddr_type;
+void *ddr_freq_change_iram_base;
+void __iomem *databahn_base;
+
+void (*change_ddr_freq)(void *ccm_addr, void *databahn_addr,
+ u32 freq, void *iram_ddr_settings) = NULL;
+void *wait_in_iram_base;
+void (*wait_in_iram)(void *ccm_addr, void *databahn_addr, u32 sys_clk_count);
+
+extern void mx50_wait(u32 ccm_base, u32 databahn_addr, u32 sys_clk_count);
+extern int ddr_med_rate;
+extern void __iomem *ccm_base;
+extern void __iomem *databahn_base;
+extern void mx50_ddr_freq_change(u32 ccm_base,
+ u32 databahn_addr, u32 freq);
+
+static void __iomem *qosc_base;
+static int ddr_settings_size;
+
+unsigned long lpddr2_databhan_regs_offsets[][2] = {
+ {0x8, 0x0},
+ {0xc, 0x0},
+ {0x10, 0x0},
+ {0x14, 0x0},
+ {0x18, 0x0},
+ {0x1c, 0x0},
+ {0x20, 0x0},
+ {0x24, 0x0},
+ {0x28, 0x0},
+ {0x2c, 0x0},
+ {0x34, 0x0},
+ {0x38, 0x0},
+ {0x3c, 0x0},
+ {0x40, 0x0},
+ {0x48, 0x0},
+ {0x6c, 0x0},
+ {0x78, 0x0},
+ {0x80, 0x0},
+ {0x84, 0x0},
+ {0x88, 0x0},
+ {0x8c, 0x0},
+ {0xcc, 0x0},
+ {0xd4, 0x0},
+ {0xd8, 0x0},
+ {0x104, 0x0},
+ {0x108, 0x0},
+ {0x10c, 0x0},
+ {0x110, 0x0},
+ {0x114, 0x0},
+ {0x200, 0x0},
+ {0x204, 0x0},
+ {0x208, 0x0},
+ {0x20c, 0x0},
+ {0x210, 0x0},
+ {0x214, 0x0},
+ {0x218, 0x0},
+ {0x21c, 0x0},
+ {0x220, 0x0},
+ {0x224, 0x0},
+ {0x228, 0x0},
+ {0x22c, 0x0},
+ {0x234, 0x0},
+ {0x238, 0x0},
+ {0x23c, 0x0},
+ {0x240, 0x0},
+ {0x244, 0x0},
+ {0x248, 0x0},
+ {0x24c, 0x0},
+ {0x250, 0x0},
+ {0x254, 0x0},
+ {0x258, 0x0},
+ {0x25c, 0x0} };
+
+unsigned long lpddr2_24[][2] = {
+ {0x08, 0x00000003},
+ {0x0c, 0x000012c0},
+ {0x10, 0x00000018},
+ {0x14, 0x000000f0},
+ {0x18, 0x02030b0c},
+ {0x1c, 0x02020104},
+ {0x20, 0x05010102},
+ {0x24, 0x00068005},
+ {0x28, 0x01000103},
+ {0x2c, 0x04030101},
+ {0x34, 0x00000202},
+ {0x38, 0x00000001},
+ {0x3c, 0x00000401},
+ {0x40, 0x00030050},
+ {0x48, 0x00040004},
+ {0x6c, 0x00040022},
+ {0x78, 0x00040022},
+ {0x80, 0x00180000},
+ {0x84, 0x00000009},
+ {0x88, 0x02400003},
+ {0x8c, 0x01000200},
+ {0xcc, 0x00000000},
+ {0xd4, 0x01010301},
+ {0xd8, 0x00000101},
+ {0x104, 0x02000602},
+ {0x108, 0x00560000},
+ {0x10c, 0x00560056},
+ {0x110, 0x00560056},
+ {0x114, 0x03060056},
+ {0x200, 0x00000000},
+ {0x204, 0x00000000},
+ {0x208, 0xf3003a27},
+ {0x20c, 0x074002c1},
+ {0x210, 0xf3003a27},
+ {0x214, 0x074002c1},
+ {0x218, 0xf3003a27},
+ {0x21c, 0x074002c1},
+ {0x220, 0xf3003a27},
+ {0x224, 0x074002c1},
+ {0x228, 0xf3003a27},
+ {0x22c, 0x074002c1},
+ {0x234, 0x00810004},
+ {0x238, 0x30219fd3},
+ {0x23c, 0x00219fc1},
+ {0x240, 0x30219fd3},
+ {0x244, 0x00219fc1},
+ {0x248, 0x30219fd3},
+ {0x24c, 0x00219fc1},
+ {0x250, 0x30219fd3},
+ {0x254, 0x00219fc1},
+ {0x258, 0x30219fd3},
+ {0x25c, 0x00219fc1} };
+
+unsigned long mddr_databhan_regs_offsets[][2] = {
+ {0x08, 0x0},
+ {0x14, 0x0},
+ {0x18, 0x0},
+ {0x1c, 0x0},
+ {0x20, 0x0},
+ {0x24, 0x0},
+ {0x28, 0x0},
+ {0x2c, 0x0},
+ {0x34, 0x0},
+ {0x38, 0x0},
+ {0x3c, 0x0},
+ {0x40, 0x0},
+ {0x48, 0x0},
+ {0x6c, 0x0},
+ {0xd4, 0x0},
+ {0x108, 0x0},
+ {0x10c, 0x0},
+ {0x110, 0x0},
+ {0x114, 0x0},
+ {0x200, 0x0},
+ {0x204, 0x0},
+ {0x208, 0x0},
+ {0x20c, 0x0},
+ {0x210, 0x0},
+ {0x214, 0x0},
+ {0x218, 0x0},
+ {0x21c, 0x0},
+ {0x220, 0x0},
+ {0x224, 0x0},
+ {0x228, 0x0},
+ {0x22c, 0x0},
+ {0x234, 0x0},
+ {0x238, 0x0},
+ {0x23c, 0x0},
+ {0x240, 0x0},
+ {0x244, 0x0},
+ {0x248, 0x0},
+ {0x24c, 0x0},
+ {0x250, 0x0},
+ {0x254, 0x0},
+ {0x258, 0x0},
+ {0x25c, 0x0} };
+
+
+unsigned long mddr_24[][2] = {
+ {0x08, 0x000012c0},
+ {0x14, 0x02000000},
+ {0x18, 0x01010506},
+ {0x1c, 0x01020101},
+ {0x20, 0x02000103},
+ {0x24, 0x01069002},
+ {0x28, 0x01000101},
+ {0x2c, 0x02010101},
+ {0x34, 0x00000602},
+ {0x38, 0x00000001},
+ {0x3c, 0x00000301},
+ {0x40, 0x000500b0},
+ {0x48, 0x00030003},
+ {0x6c, 0x00000000},
+ {0xd4, 0x00000200},
+ {0x108, 0x00b30000},
+ {0x10c, 0x00b300b3},
+ {0x110, 0x00b300b3},
+ {0x114, 0x010300b3},
+ {0x200, 0x00000100},
+ {0x204, 0x00000000},
+ {0x208, 0xf4003a27},
+ {0x20c, 0x074002c0},
+ {0x210, 0xf4003a27},
+ {0x214, 0x074002c0},
+ {0x218, 0xf4003a27},
+ {0x21c, 0x074002c0},
+ {0x220, 0xf4003a27},
+ {0x224, 0x074002c0},
+ {0x228, 0xf4003a27},
+ {0x22c, 0x074002c0},
+ {0x234, 0x00800005},
+ {0x238, 0x30319f14},
+ {0x23c, 0x00319f01},
+ {0x240, 0x30319f14},
+ {0x244, 0x00319f01},
+ {0x248, 0x30319f14},
+ {0x24c, 0x00319f01},
+ {0x250, 0x30319f14},
+ {0x254, 0x00319f01},
+ {0x258, 0x30319f14},
+ {0x25c, 0x00319f01} };
+
+int can_change_ddr_freq(void)
+{
+ if (clk_get_usecount(epdc_clk) == 0)
+ return 1;
+ return 0;
+}
+
+int update_ddr_freq(int ddr_rate)
+{
+ int i;
+ unsigned int reg;
+
+ if (!can_change_ddr_freq())
+ return -1;
+
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ iram_ddr_settings[0][0] = ddr_settings_size;
+ if (ddr_rate == LP_APM_CLK) {
+ if (mx50_ddr_type == MX50_LPDDR2) {
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0] =
+ lpddr2_24[i][0];
+ iram_ddr_settings[i + 1][1] =
+ lpddr2_24[i][1];
+ }
+ } else {
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0]
+ = mddr_24[i][0];
+ iram_ddr_settings[i + 1][1]
+ = mddr_24[i][1];
+ }
+ }
+ } else {
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0] =
+ normal_databahn_settings[i][0];
+ iram_ddr_settings[i + 1][1] =
+ normal_databahn_settings[i][1];
+ }
+ if (ddr_rate == ddr_med_rate) {
+ /*Change the tref setting */
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ if (iram_ddr_settings[i + 1][0] == 0x40) {
+ if (mx50_ddr_type == MX50_LPDDR2)
+ /* LPDDR2 133MHz. */
+ iram_ddr_settings[i + 1][1] =
+ 0x00050180;
+ else
+ /* mDDR 133MHz. */
+ iram_ddr_settings[i + 1][1] =
+ 0x00050208;
+ break;
+ }
+ }
+ }
+ }
+ /* Disable all masters from accessing the DDR. */
+ reg = __raw_readl(qosc_base + HW_QOS_DISABLE);
+ reg |= 0xFFE;
+ __raw_writel(reg, qosc_base + HW_QOS_DISABLE_SET);
+ udelay(100);
+
+ /* Set the DDR to default freq. */
+ change_ddr_freq(ccm_base, databahn_base, ddr_rate,
+ iram_ddr_settings);
+
+ /* Enable all masters to access the DDR. */
+ __raw_writel(reg, qosc_base + HW_QOS_DISABLE_CLR);
+
+ return 0;
+}
+
+void init_ddr_settings(void)
+{
+ unsigned long iram_paddr;
+ unsigned int reg;
+ int i;
+ struct clk *ddr_clk = clk_get(NULL, "ddr_clk");
+
+ databahn_base = ioremap(MX50_DATABAHN_BASE_ADDR, SZ_16K);
+
+ /* Find the memory type, LPDDR2 or mddr. */
+ mx50_ddr_type = __raw_readl(databahn_base) & 0xF00;
+ if (mx50_ddr_type == MX50_LPDDR2) {
+ normal_databahn_settings = lpddr2_databhan_regs_offsets;
+ ddr_settings_size = ARRAY_SIZE(lpddr2_databhan_regs_offsets);
+ }
+ else if (mx50_ddr_type == MX50_MDDR) {
+ normal_databahn_settings = mddr_databhan_regs_offsets;
+ ddr_settings_size = ARRAY_SIZE(mddr_databhan_regs_offsets);
+ } else {
+ printk(KERN_DEBUG
+ "%s: Unsupported memory type\n", __func__);
+ return;
+ }
+
+ /* Copy the databhan settings into the iram location. */
+ for (i = 0; i < ddr_settings_size; i++) {
+ normal_databahn_settings[i][1] =
+ __raw_readl(databahn_base
+ + normal_databahn_settings[i][0]);
+ }
+ /* Store the size of the array in iRAM also,
+ * increase the size by 8 bytes.
+ */
+ iram_ddr_settings = iram_alloc(ddr_settings_size + 8, &iram_paddr);
+ if (iram_ddr_settings == NULL) {
+ printk(KERN_DEBUG
+ "%s: failed to allocate iRAM memory for ddr settings\n",
+ __func__);
+ return;
+ }
+
+ /* Allocate IRAM for the DDR freq change code. */
+ iram_alloc(SZ_8K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
+ SZ_8K, MT_MEMORY);
+ memcpy(ddr_freq_change_iram_base, mx50_ddr_freq_change, SZ_8K);
+ change_ddr_freq = (void *)ddr_freq_change_iram_base;
+
+ qosc_base = ioremap(MX50_QOSC_BASE_ADDR, SZ_4K);
+ /* Enable the QoSC */
+ reg = __raw_readl(qosc_base);
+ reg &= ~0xC0000000;
+ __raw_writel(reg, qosc_base);
+
+ /* Allocate IRAM to run the WFI code from iram, since
+ * we can turn off the DDR clocks when ARM is in WFI.
+ */
+ iram_alloc(SZ_4K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ wait_in_iram_base = __arm_ioremap(iram_paddr,
+ SZ_4K, MT_MEMORY);
+ memcpy(wait_in_iram_base, mx50_wait, SZ_4K);
+ wait_in_iram = (void *)wait_in_iram_base;
+
+ clk_enable(ddr_clk);
+
+ /* Set the DDR to enter automatic self-refresh. */
+ /* Set the DDR to automatically enter lower power mode 4. */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG22);
+ reg &= ~LOWPOWER_AUTOENABLE_MASK;
+ reg |= 1 << 1;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG22);
+
+ /* set the counter for entering mode 4. */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG21);
+ reg &= ~LOWPOWER_EXTERNAL_CNT_MASK;
+ reg = 128 << LOWPOWER_EXTERNAL_CNT_OFFSET;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG21);
+
+ /* Enable low power mode 4 */
+ reg = __raw_readl(databahn_base + DATABAHN_CTL_REG20);
+ reg &= ~LOWPOWER_CONTROL_MASK;
+ reg |= 1 << 1;
+ __raw_writel(reg, databahn_base + DATABAHN_CTL_REG20);
+ clk_disable(ddr_clk);
+
+ epdc_clk = clk_get(NULL, "epdc_axi");
+ if (IS_ERR(epdc_clk)) {
+ printk(KERN_DEBUG "%s: failed to get epdc_axi_clk\n",
+ __func__);
+ return;
+ }
+}
diff --git a/arch/arm/mach-mx5/mx50_rdp_pmic_mc13892.c b/arch/arm/mach-mx5/mx50_rdp_pmic_mc13892.c
new file mode 100644
index 00000000..b5946772
--- /dev/null
+++ b/arch/arm/mach-mx5/mx50_rdp_pmic_mc13892.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/pmic_external.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx50.h>
+
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+/* Coin cell charger enable */
+#define COINCHEN_LSH 23
+#define COINCHEN_WID 1
+/* Coin cell charger voltage setting */
+#define VCOIN_LSH 20
+#define VCOIN_WID 3
+
+/* Coin Charger voltage */
+#define VCOIN_2_5V 0x0
+#define VCOIN_2_7V 0x1
+#define VCOIN_2_8V 0x2
+#define VCOIN_2_9V 0x3
+#define VCOIN_3_0V 0x4
+#define VCOIN_3_1V 0x5
+#define VCOIN_3_2V 0x6
+#define VCOIN_3_3V 0x7
+
+/* Keeps VSRTC and CLK32KMCU on for all states */
+#define DRM_LSH 4
+#define DRM_WID 1
+
+/* regulator standby mask */
+#define GEN1_STBY_MASK (1 << 1)
+#define IOHI_STBY_MASK (1 << 4)
+#define DIG_STBY_MASK (1 << 10)
+#define GEN2_STBY_MASK (1 << 13)
+#define PLL_STBY_MASK (1 << 16)
+#define USB2_STBY_MASK (1 << 19)
+
+#define GEN3_STBY_MASK (1 << 1)
+#define CAM_STBY_MASK (1 << 7)
+#define VIDEO_STBY_MASK (1 << 13)
+#define AUDIO_STBY_MASK (1 << 16)
+#define SD_STBY_MASK (1 << 19)
+
+#define REG_MODE_0_ALL_MASK (DIG_STBY_MASK | GEN1_STBY_MASK\
+ | PLL_STBY_MASK | IOHI_STBY_MASK)
+#define REG_MODE_1_ALL_MASK (CAM_STBY_MASK | VIDEO_STBY_MASK |\
+ AUDIO_STBY_MASK | GEN3_STBY_MASK)
+
+/* switch mode setting */
+#define SW1MODE_LSB 0
+#define SW2MODE_LSB 10
+#define SW3MODE_LSB 0
+#define SW4MODE_LSB 8
+
+#define SWMODE_MASK 0xF
+#define SWMODE_AUTO 0x8
+
+/* CPU */
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "cpu_vddgp",
+ }
+};
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "lp_vcc",
+ }
+};
+
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "1-000a",
+ },
+};
+
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDIO",
+ .dev_name = "1-000a",
+ },
+};
+
+static struct regulator_consumer_supply vsd_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+};
+
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+};
+
+static struct regulator_init_data sw1_init = {
+ .constraints = {
+ .name = "SW1",
+ .min_uV = mV_to_uV(600),
+ .max_uV = mV_to_uV(1375),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 850000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+ .min_uV = mV_to_uV(900),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 950000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3_init = {
+ .constraints = {
+ .name = "SW3",
+ .min_uV = mV_to_uV(900),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 950000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ }
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "SW4",
+ .min_uV = mV_to_uV(1100),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data viohi_init = {
+ .constraints = {
+ .name = "VIOHI",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb_init = {
+ .constraints = {
+ .name = "VUSB",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "SWBST",
+ }
+};
+
+static struct regulator_init_data vdig_init = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(1800),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data vpll_init = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = mV_to_uV(1050),
+ .max_uV = mV_to_uV(1800),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb2_init = {
+ .constraints = {
+ .name = "VUSB2",
+ .min_uV = mV_to_uV(2400),
+ .max_uV = mV_to_uV(2775),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vvideo_init = {
+ .constraints = {
+ .name = "VVIDEO",
+ .min_uV = mV_to_uV(2775),
+ .max_uV = mV_to_uV(2775),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data vaudio_init = {
+ .constraints = {
+ .name = "VAUDIO",
+ .min_uV = mV_to_uV(2300),
+ .max_uV = mV_to_uV(3000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data vsd_init = {
+ .constraints = {
+ .name = "VSD",
+ .min_uV = mV_to_uV(1800),
+ .max_uV = mV_to_uV(3150),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vsd_consumers),
+ .consumer_supplies = vsd_consumers,
+};
+
+static struct regulator_init_data vcam_init = {
+ .constraints = {
+ .name = "VCAM",
+ .min_uV = mV_to_uV(2500),
+ .max_uV = mV_to_uV(3000),
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
+ }
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(3150),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(3150),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "VGEN3",
+ .min_uV = mV_to_uV(1800),
+ .max_uV = mV_to_uV(2900),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo1_init = {
+ .constraints = {
+ .name = "GPO1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo2_init = {
+ .constraints = {
+ .name = "GPO2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo3_init = {
+ .constraints = {
+ .name = "GPO3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo4_init = {
+ .constraints = {
+ .name = "GPO4",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct mc13xxx_regulator_init_data mx50_rdp_regulators[] = {
+ { .id = MC13892_SW1, .init_data = &sw1_init },
+ { .id = MC13892_SW2, .init_data = &sw2_init },
+ { .id = MC13892_SW3, .init_data = &sw3_init },
+ { .id = MC13892_SW4, .init_data = &sw4_init },
+ { .id = MC13892_SWBST, .init_data = &swbst_init },
+ { .id = MC13892_VIOHI, .init_data = &viohi_init },
+ { .id = MC13892_VPLL, .init_data = &vpll_init },
+ { .id = MC13892_VDIG, .init_data = &vdig_init },
+ { .id = MC13892_VSD, .init_data = &vsd_init },
+ { .id = MC13892_VUSB2, .init_data = &vusb2_init },
+ { .id = MC13892_VVIDEO, .init_data = &vvideo_init },
+ { .id = MC13892_VAUDIO, .init_data = &vaudio_init },
+ { .id = MC13892_VCAM, .init_data = &vcam_init },
+ { .id = MC13892_VGEN1, .init_data = &vgen1_init },
+ { .id = MC13892_VGEN2, .init_data = &vgen2_init },
+ { .id = MC13892_VGEN3, .init_data = &vgen3_init },
+ { .id = MC13892_VUSB, .init_data = &vusb_init },
+ { .id = MC13892_GPO1, .init_data = &gpo1_init },
+ { .id = MC13892_GPO2, .init_data = &gpo2_init },
+ { .id = MC13892_GPO3, .init_data = &gpo3_init },
+ { .id = MC13892_GPO4, .init_data = &gpo4_init },
+};
+
+static struct mc13xxx_platform_data mx50_rdp_mc13892_data = {
+ .flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx50_rdp_regulators),
+ .regulators = mx50_rdp_regulators,
+};
+
+
+static struct spi_board_info mx50_rdp_spi_device_info[] __initdata = {
+ {
+ .modalias = "mc13892",
+ .irq = gpio_to_irq(114),
+ .max_speed_hz = 6000000, /* max spi SCK clock speed in HZ */
+ .bus_num = 3,
+ .chip_select = 0,
+ .platform_data = &mx50_rdp_mc13892_data,
+ },
+};
+
+
+int __init mx50_rdp_init_mc13892(void)
+{
+ return spi_register_board_info(mx50_rdp_spi_device_info,
+ ARRAY_SIZE(mx50_rdp_spi_device_info));
+}
diff --git a/arch/arm/mach-mx5/mx50_suspend.S b/arch/arm/mach-mx5/mx50_suspend.S
new file mode 100755
index 00000000..1ba15c8a
--- /dev/null
+++ b/arch/arm/mach-mx5/mx50_suspend.S
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+
+#define ARM_CTRL_DCACHE 1 << 2
+#define ARM_CTRL_ICACHE 1 << 12
+#define ARM_AUXCR_L2EN 1 << 1
+
+/*
+ * mx50_suspend
+ *
+ * Suspend the processor (eg, wait for interrupt).
+ * Set the DDR into Self Refresh
+ * IRQs are already disabled.
+ */
+ENTRY(mx50_suspend)
+ stmfd sp!, {r4,r5,r6,r7,r8, r9,r10,r11} @ Save registers
+
+ mov r6, r0 @save databahn address
+
+/* Before putting DDR into self-refresh, make sure
+ any LPM mode that the DDR might be in is exited.
+*/
+ /* If Databahn is in LPM4, exit that mode first. */
+ ldr r8,[r6, #0x50] @Store LPM mode in r8
+ mov r0, r8
+ bic r0, r0, #0x1F
+ str r0,[r6, #0x50]
+
+
+ /* Disable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ bic r0, r0, #ARM_CTRL_ICACHE @ Disable ICache
+ bic r0, r0, #ARM_CTRL_DCACHE @ Disable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedClean
+ mov r10, #0
+Loop1Clean:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type
+ @ for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipClean @ No cache or only instruction cache
+ @ at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset
+ @ (log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the
+ @ way size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way
+ @ size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the index
+ @ size (right aligned)
+Loop2Clean:
+ mov r9, r4 @ R9 working copy of the max way size
+ @ (right aligned)
+Loop3Clean:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache
+ @ number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c14, 2 @ Clean and invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Clean
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Clean
+SkipClean:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Clean
+
+FinishedClean:
+
+ /* Disable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ bic r0, r0, #ARM_AUXCR_L2EN @ Disable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+/* Wait for the databahn to idle
+ Meaning, no access to the databahn is
+ being made.
+*/
+EnterWFI:
+ ldr r0,[r6, #0x13c]
+ and r0, r0, #0x100
+ ldr r2, =0x100
+ cmp r0, r2
+ beq EnterWFI
+
+ /* Enter self-refresh mode */
+ ldr r0,[r6, #0x4c]
+ orr r0,r0,#0x1
+ str r0,[r6, #0x4c]
+
+LoopCKE0:
+ /* Wait for CKE = 0 */
+ ldr r0,[r6, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ beq LoopCKE0
+
+ /* Stop controller */
+ ldr r0,[r6]
+ bic r0, r0, #0x1
+ str r0,[r6]
+
+ .long 0xe320f003 @ Opcode for WFI
+
+ /* Start controller */
+ ldr r0,[r6]
+ orr r0,r0,#0x1
+ str r0,[r6]
+
+LoopPHY:
+ /* Wait for PHY ready */
+ ldr r0,[r6, #0x264]
+ and r0, r0, #0xfffffffe
+ ldr r2, =0x0
+ cmp r0, r2
+ beq LoopPHY
+
+ /*Leave self-refresh mode */
+ ldr r0,[r6, #0x4c]
+ and r0,r0,#0xfffffffe
+ str r0,[r6, #0x4c]
+
+LoopCKE1:
+ /*Wait for CKE = 1 */
+ ldr r0,[r6, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ bne LoopCKE1
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ Invalidate inst cache
+
+/* Invalidate data caches */
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedInvalidate
+ mov r10, #0
+Loop1Invalidate:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache
+ @ Type for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipInvalidate @ No cache or only instruction cache
+ @at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset
+ @(log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the way
+ @size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way
+ @ size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the
+ @ index size (right aligned)
+Loop2Invalidate:
+ mov r9, r4 @ R9 working copy of the max way
+ @ size (right aligned)
+Loop3Invalidate:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache
+ @ number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c6, 2 @ Invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Invalidate
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Invalidate
+SkipInvalidate:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Invalidate
+
+FinishedInvalidate:
+
+ /* Enable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ orr r0, r0, #ARM_AUXCR_L2EN @ Enable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+ /* Enable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ orr r0, r0, #ARM_CTRL_ICACHE @ Enable ICache
+ orr r0, r0, #ARM_CTRL_DCACHE @ Enable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ /* restore LPM mode. */
+ str r8, [r6, #0x50]
+
+ /* Restore registers */
+ ldmfd sp!, {r4,r5,r6,r7,r8,r9,r10,r11}
+ mov pc, lr
+
+ .type mx50_do_suspend, #object
+ENTRY(mx50_do_suspend)
+ .word mx50_suspend
+ .size mx50_suspend, . - mx50_suspend
diff --git a/arch/arm/mach-mx5/mx50_wfi.S b/arch/arm/mach-mx5/mx50_wfi.S
new file mode 100755
index 00000000..a3bf20dd
--- /dev/null
+++ b/arch/arm/mach-mx5/mx50_wfi.S
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * mx50_wait
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(mx50_wait)
+ stmfd sp!, {r3,r4,r5,r6,r7,r8,r9,r10,r11} @ Save registers
+
+ mov r6, r0 @save CCM address
+ mov r5, r1 @save DataBahn address
+ mov r7, r2 @save sys_clk usecount
+
+ /*
+ * Make sure the DDR is self-refresh, before setting the clock bits.
+ */
+
+ /* Step 2: Poll the CKE_STATUS bit. */
+LoopCKE0:
+ /* Wait for CKE = 0 */
+ ldr r0,[r5, #0xfc]
+ and r0, r0, #0x10000
+ ldr r2, =0x10000
+ cmp r0, r2
+ beq LoopCKE0
+
+ /* Check if Databahn is in SYNC or ASYNC mode. */
+ ldr r4, [r5, #0xdc]
+ and r4, r4, #0x30000
+ cmp r4, #0x30000
+ beq Sync_mode
+
+ /* Set the DDR_CLKGATE to 0x1. */
+ ldr r0, [r6, #0x98]
+ bic r0, r0, #0x80000000
+ str r0, [r6, #0x98]
+
+ .long 0xe320f003 @ Opcode for WFI
+
+ /* Set the DDR_CLKGATE to 0x3. */
+ ldr r0, [r6, #0x98]
+ orr r0, r0, #0xC0000000
+ str r0, [r6, #0x98]
+ b Wfi_Done
+
+Sync_mode:
+ /* If usecount of sys_clk is greater than 0, donot gate it. */
+ cmp r7, #0
+ bgt do_wfi
+
+ /* Check if PLL1 is sourcing SYS_CLK. */
+ ldr r5, [r6, #0x90]
+ and r5, r0, #0x1
+ cmp r5, #0x1
+ beq pll1_source
+
+ /* Set the SYS_XTAL_CLKGATE to 0x1. */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x80000000
+ str r0, [r6, #0x94]
+
+ /* Set the SYS_XTAL_DIV to 0xF (1.6MHz) to reduce power.
+ * since this clock is not gated when ARM is in WFI.
+ */
+
+ ldr r0, [r6, #0x94]
+ orr r0, r0, #0x3c0
+ str r0, [r6, #0x94]
+
+ b do_wfi
+pll1_source:
+ /* Set the SYS_PLL_CLKGATE to 0x1. */
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x40000000
+ str r0, [r6, #0x94]
+
+do_wfi:
+ .long 0xe320f003 @ Opcode for WFI
+
+ cmp r7, #0
+ bgt Wfi_Done
+
+ cmp r5, #1
+ beq pll1_source1
+ /* Set the SYS_XTAL_DIV to 24MHz.*/
+ ldr r0, [r6, #0x94]
+ bic r0, r0, #0x3c0
+ orr r0, r0, #0x40
+ str r0, [r6, #0x94]
+
+ /* Set the SYS_XTAL_CLKGATE to 0x3. */
+ ldr r0, [r6, #0x94]
+ orr r0, r0, #0xC0000000
+ str r0, [r6, #0x94]
+ b Wfi_Done
+
+pll1_source1:
+ /* Set the SYS_PLL_CLKGATE to 0x3. */
+ ldr r0, [r6, #0x94]
+ orr r0, r0, #0x30000000
+ str r0, [r6, #0x94]
+
+Wfi_Done:
+ /* Restore registers */
+ ldmfd sp!, {r3,r4,r5,r6,r7,r8,r9,r10,r11}
+ mov pc, lr
+
+ .type mx50_do_wait, #object
+ENTRY(mx50_do_wait)
+ .word mx50_wait
+ .size mx50_wait, . - mx50_wait
diff --git a/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c
new file mode 100644
index 00000000..fcdc03bc
--- /dev/null
+++ b/arch/arm/mach-mx5/mx51_babbage_pmic_mc13892.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * mx51-babbage-pmic-mc13892.c -- i.MX51 Babbage Driver for Atlas MC13892 PMIC
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/err.h>
+#include <linux/pmic_external.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc13892.h>
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <linux/gpio.h>
+#include <mach/iomux-mx51.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+/* CPU */
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_consumer_supply vdig_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDA",
+ .dev_name = "1-000a",
+ },
+};
+
+static struct regulator_consumer_supply vvideo_consumers[] = {
+ {
+ /* sgtl5000 */
+ .supply = "VDDIO",
+ .dev_name = "1-000a",
+ },
+};
+
+struct mc13892;
+
+static struct regulator_init_data sw1_init = {
+ .constraints = {
+ .name = "SW1",
+ .min_uV = mV_to_uV(600),
+ .max_uV = mV_to_uV(1375),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 850000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+ .min_uV = mV_to_uV(900),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 950000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ }
+};
+
+static struct regulator_init_data sw3_init = {
+ .constraints = {
+ .name = "SW3",
+ .min_uV = mV_to_uV(1100),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "SW4",
+ .min_uV = mV_to_uV(1100),
+ .max_uV = mV_to_uV(1850),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data viohi_init = {
+ .constraints = {
+ .name = "VIOHI",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb_init = {
+ .constraints = {
+ .name = "VUSB",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "SWBST",
+ }
+};
+
+static struct regulator_init_data vdig_init = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = mV_to_uV(1650),
+ .max_uV = mV_to_uV(1650),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vdig_consumers),
+ .consumer_supplies = vdig_consumers,
+};
+
+static struct regulator_init_data vpll_init = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = mV_to_uV(1050),
+ .max_uV = mV_to_uV(1800),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb2_init = {
+ .constraints = {
+ .name = "VUSB2",
+ .min_uV = mV_to_uV(2400),
+ .max_uV = mV_to_uV(2775),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vvideo_init = {
+ .constraints = {
+ .name = "VVIDEO",
+ .min_uV = mV_to_uV(2775),
+ .max_uV = mV_to_uV(2775),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vvideo_consumers),
+ .consumer_supplies = vvideo_consumers,
+};
+
+static struct regulator_init_data vaudio_init = {
+ .constraints = {
+ .name = "VAUDIO",
+ .min_uV = mV_to_uV(2300),
+ .max_uV = mV_to_uV(3000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data vsd_init = {
+ .constraints = {
+ .name = "VSD",
+ .min_uV = mV_to_uV(1800),
+ .max_uV = mV_to_uV(3150),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data vcam_init = {
+ .constraints = {
+ .name = "VCAM",
+ .min_uV = mV_to_uV(2500),
+ .max_uV = mV_to_uV(3000),
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
+ }
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(1200),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(3150),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "VGEN3",
+ .min_uV = mV_to_uV(1800),
+ .max_uV = mV_to_uV(2900),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data gpo1_init = {
+ .constraints = {
+ .name = "GPO1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo2_init = {
+ .constraints = {
+ .name = "GPO2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo3_init = {
+ .constraints = {
+ .name = "GPO3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct regulator_init_data gpo4_init = {
+ .constraints = {
+ .name = "GPO4",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ }
+};
+
+static struct mc13xxx_regulator_init_data mx51_bbg_regulators[] = {
+ { .id = MC13892_SW1, .init_data = &sw1_init },
+ { .id = MC13892_SW2, .init_data = &sw2_init },
+ { .id = MC13892_SW3, .init_data = &sw3_init },
+ { .id = MC13892_SW4, .init_data = &sw4_init },
+ { .id = MC13892_SWBST, .init_data = &swbst_init },
+ { .id = MC13892_VIOHI, .init_data = &viohi_init },
+ { .id = MC13892_VPLL, .init_data = &vpll_init },
+ { .id = MC13892_VDIG, .init_data = &vdig_init },
+ { .id = MC13892_VSD, .init_data = &vsd_init },
+ { .id = MC13892_VUSB2, .init_data = &vusb2_init },
+ { .id = MC13892_VVIDEO, .init_data = &vvideo_init },
+ { .id = MC13892_VAUDIO, .init_data = &vaudio_init },
+ { .id = MC13892_VCAM, .init_data = &vcam_init },
+ { .id = MC13892_VGEN1, .init_data = &vgen1_init },
+ { .id = MC13892_VGEN2, .init_data = &vgen2_init },
+ { .id = MC13892_VGEN3, .init_data = &vgen3_init },
+ { .id = MC13892_VUSB, .init_data = &vusb_init },
+ { .id = MC13892_GPO1, .init_data = &gpo1_init },
+ { .id = MC13892_GPO2, .init_data = &gpo2_init },
+ { .id = MC13892_GPO3, .init_data = &gpo3_init },
+ { .id = MC13892_GPO4, .init_data = &gpo4_init },
+};
+
+static struct mc13xxx_platform_data mc13892_plat = {
+ .flags = MC13XXX_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx51_bbg_regulators),
+ .regulators = mx51_bbg_regulators,
+};
+
+#define MC13892_SPI_IRQ gpio_to_irq(8)
+static struct spi_board_info __initdata mc13892_spi_device = {
+ .modalias = "mc13892",
+ .irq = MC13892_SPI_IRQ,
+ .max_speed_hz = 6000000, /* max spi SCK clock speed in HZ */
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &mc13892_plat,
+};
+
+
+int __init mx51_babbage_init_mc13892(void)
+{
+ return spi_register_board_info(&mc13892_spi_device, 1);
+}
+
diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c
new file mode 100644
index 00000000..56739c23
--- /dev/null
+++ b/arch/arm/mach-mx5/mx51_efika.c
@@ -0,0 +1,634 @@
+/*
+ * based on code from the following
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2010 Pegatron Corporation. All Rights Reserved.
+ * Copyright 2009-2010 Genesi USA, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/mc13892.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx51.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <mach/ulpi.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "devices-imx51.h"
+#include "devices.h"
+#include "efika.h"
+#include "cpu_op-mx51.h"
+
+#define MX51_USB_CTRL_1_OFFSET 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+#define MX51_USB_PLL_DIV_19_2_MHZ 0x01
+
+#define EFIKAMX_USB_HUB_RESET IMX_GPIO_NR(1, 5)
+#define EFIKAMX_USBH1_STP IMX_GPIO_NR(1, 27)
+
+#define EFIKAMX_SPI_CS0 IMX_GPIO_NR(4, 24)
+#define EFIKAMX_SPI_CS1 IMX_GPIO_NR(4, 25)
+
+#define EFIKAMX_PMIC IMX_GPIO_NR(1, 6)
+
+static iomux_v3_cfg_t mx51efika_pads[] = {
+ /* UART1 */
+ MX51_PAD_UART1_RXD__UART1_RXD,
+ MX51_PAD_UART1_TXD__UART1_TXD,
+ MX51_PAD_UART1_RTS__UART1_RTS,
+ MX51_PAD_UART1_CTS__UART1_CTS,
+
+ /* SD 1 */
+ MX51_PAD_SD1_CMD__SD1_CMD,
+ MX51_PAD_SD1_CLK__SD1_CLK,
+ MX51_PAD_SD1_DATA0__SD1_DATA0,
+ MX51_PAD_SD1_DATA1__SD1_DATA1,
+ MX51_PAD_SD1_DATA2__SD1_DATA2,
+ MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+ /* SD 2 */
+ MX51_PAD_SD2_CMD__SD2_CMD,
+ MX51_PAD_SD2_CLK__SD2_CLK,
+ MX51_PAD_SD2_DATA0__SD2_DATA0,
+ MX51_PAD_SD2_DATA1__SD2_DATA1,
+ MX51_PAD_SD2_DATA2__SD2_DATA2,
+ MX51_PAD_SD2_DATA3__SD2_DATA3,
+
+ /* SD/MMC WP/CD */
+ MX51_PAD_GPIO1_0__SD1_CD,
+ MX51_PAD_GPIO1_1__SD1_WP,
+ MX51_PAD_GPIO1_7__SD2_WP,
+ MX51_PAD_GPIO1_8__SD2_CD,
+
+ /* spi */
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
+ MX51_PAD_CSPI1_SS0__GPIO4_24,
+ MX51_PAD_CSPI1_SS1__GPIO4_25,
+ MX51_PAD_CSPI1_RDY__ECSPI1_RDY,
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
+ MX51_PAD_GPIO1_6__GPIO1_6,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+
+ /* USB HUB RESET */
+ MX51_PAD_GPIO1_5__GPIO1_5,
+
+ /* WLAN */
+ MX51_PAD_EIM_A22__GPIO2_16,
+ MX51_PAD_EIM_A16__GPIO2_10,
+
+ /* USB PHY RESET */
+ MX51_PAD_EIM_D27__GPIO2_9,
+};
+
+/* Serial ports */
+static const struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* This function is board specific as the bit mask for the plldiv will also
+ * be different for other Freescale SoCs, thus a common bitmask is not
+ * possible and cannot get place in /plat-mxc/ehci.c.
+ */
+static int initialize_otg_port(struct platform_device *pdev)
+{
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *usbother_base;
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ if (!usb_base)
+ return -ENOMEM;
+ usbother_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET);
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+ v |= MX51_USB_PLL_DIV_19_2_MHZ;
+ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+ iounmap(usb_base);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .init = initialize_otg_port,
+ .portsc = MXC_EHCI_UTMI_16BIT,
+};
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+ iomux_v3_cfg_t usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+ iomux_v3_cfg_t usbh1gpio = MX51_PAD_USBH1_STP__GPIO1_27;
+ u32 v;
+ void __iomem *usb_base;
+ void __iomem *socregs_base;
+
+ mxc_iomux_v3_setup_pad(usbh1gpio);
+ gpio_request(EFIKAMX_USBH1_STP, "usbh1_stp");
+ gpio_direction_output(EFIKAMX_USBH1_STP, 0);
+ msleep(1);
+ gpio_set_value(EFIKAMX_USBH1_STP, 1);
+ msleep(1);
+
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+ socregs_base = (void __iomem *)(usb_base + MX5_USBOTHER_REGS_OFFSET);
+
+ /* The clock for the USBH1 ULPI port will come externally */
+ /* from the PHY. */
+ v = __raw_readl(socregs_base + MX51_USB_CTRL_1_OFFSET);
+ __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN,
+ socregs_base + MX51_USB_CTRL_1_OFFSET);
+
+ iounmap(usb_base);
+
+ gpio_free(EFIKAMX_USBH1_STP);
+ mxc_iomux_v3_setup_pad(usbh1stp);
+
+ mdelay(10);
+
+ return mx51_initialize_usb_hw(0, MXC_EHCI_ITC_NO_THRESHOLD);
+}
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .init = initialize_usbh1_port,
+ .portsc = MXC_EHCI_MODE_ULPI,
+};
+
+static void mx51_efika_hubreset(void)
+{
+ gpio_request(EFIKAMX_USB_HUB_RESET, "usb_hub_rst");
+ gpio_direction_output(EFIKAMX_USB_HUB_RESET, 1);
+ msleep(1);
+ gpio_set_value(EFIKAMX_USB_HUB_RESET, 0);
+ msleep(1);
+ gpio_set_value(EFIKAMX_USB_HUB_RESET, 1);
+}
+
+static void __init mx51_efika_usb(void)
+{
+ mx51_efika_hubreset();
+
+ /* pulling it low, means no USB at all... */
+ gpio_request(EFIKA_USB_PHY_RESET, "usb_phy_reset");
+ gpio_direction_output(EFIKA_USB_PHY_RESET, 0);
+ msleep(1);
+ gpio_set_value(EFIKA_USB_PHY_RESET, 1);
+
+ usbh1_config.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+ ULPI_OTG_DRVVBUS_EXT | ULPI_OTG_EXTVBUSIND);
+
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+ if (usbh1_config.otg)
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+}
+
+static struct mtd_partition mx51_efika_spi_nor_partitions[] = {
+ {
+ .name = "u-boot",
+ .offset = 0,
+ .size = SZ_256K,
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_64K,
+ },
+};
+
+static struct flash_platform_data mx51_efika_spi_flash_data = {
+ .name = "spi_flash",
+ .parts = mx51_efika_spi_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mx51_efika_spi_nor_partitions),
+ .type = "sst25vf032b",
+};
+
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "cpu_vcc",
+ }
+};
+
+static struct regulator_consumer_supply vdig_consumers[] = {
+ /* sgtl5000 */
+ REGULATOR_SUPPLY("VDDA", "1-000a"),
+ REGULATOR_SUPPLY("VDDD", "1-000a"),
+};
+
+static struct regulator_consumer_supply vvideo_consumers[] = {
+ /* sgtl5000 */
+ REGULATOR_SUPPLY("VDDIO", "1-000a"),
+};
+
+static struct regulator_consumer_supply vsd_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+};
+
+static struct regulator_consumer_supply pwgt1_consumer[] = {
+ {
+ .supply = "pwgt1",
+ }
+};
+
+static struct regulator_consumer_supply pwgt2_consumer[] = {
+ {
+ .supply = "pwgt2",
+ }
+};
+
+static struct regulator_consumer_supply coincell_consumer[] = {
+ {
+ .supply = "coincell",
+ }
+};
+
+static struct regulator_init_data sw1_init = {
+ .constraints = {
+ .name = "SW1",
+ .min_uV = 600000,
+ .max_uV = 1375000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 850000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+ .min_uV = 900000,
+ .max_uV = 1850000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ .state_mem = {
+ .uV = 950000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ }
+};
+
+static struct regulator_init_data sw3_init = {
+ .constraints = {
+ .name = "SW3",
+ .min_uV = 1100000,
+ .max_uV = 1850000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "SW4",
+ .min_uV = 1100000,
+ .max_uV = 1850000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data viohi_init = {
+ .constraints = {
+ .name = "VIOHI",
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb_init = {
+ .constraints = {
+ .name = "VUSB",
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "SWBST",
+ }
+};
+
+static struct regulator_init_data vdig_init = {
+ .constraints = {
+ .name = "VDIG",
+ .min_uV = 1050000,
+ .max_uV = 1800000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vdig_consumers),
+ .consumer_supplies = vdig_consumers,
+};
+
+static struct regulator_init_data vpll_init = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = 1050000,
+ .max_uV = 1800000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb2_init = {
+ .constraints = {
+ .name = "VUSB2",
+ .min_uV = 2400000,
+ .max_uV = 2775000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vvideo_init = {
+ .constraints = {
+ .name = "VVIDEO",
+ .min_uV = 2775000,
+ .max_uV = 2775000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vvideo_consumers),
+ .consumer_supplies = vvideo_consumers,
+};
+
+static struct regulator_init_data vaudio_init = {
+ .constraints = {
+ .name = "VAUDIO",
+ .min_uV = 2300000,
+ .max_uV = 3000000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vsd_init = {
+ .constraints = {
+ .name = "VSD",
+ .min_uV = 1800000,
+ .max_uV = 3150000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vsd_consumers),
+ .consumer_supplies = vsd_consumers,
+};
+
+static struct regulator_init_data vcam_init = {
+ .constraints = {
+ .name = "VCAM",
+ .min_uV = 2500000,
+ .max_uV = 3000000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+ .min_uV = 1200000,
+ .max_uV = 3150000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+ .min_uV = 1200000,
+ .max_uV = 3150000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 2900000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data gpo1_init = {
+ .constraints = {
+ .name = "GPO1",
+ }
+};
+
+static struct regulator_init_data gpo2_init = {
+ .constraints = {
+ .name = "GPO2",
+ }
+};
+
+static struct regulator_init_data gpo3_init = {
+ .constraints = {
+ .name = "GPO3",
+ }
+};
+
+static struct regulator_init_data gpo4_init = {
+ .constraints = {
+ .name = "GPO4",
+ }
+};
+
+static struct regulator_init_data pwgt1_init = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pwgt1_consumer),
+ .consumer_supplies = pwgt1_consumer,
+};
+
+static struct regulator_init_data pwgt2_init = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pwgt2_consumer),
+ .consumer_supplies = pwgt2_consumer,
+};
+
+static struct regulator_init_data vcoincell_init = {
+ .constraints = {
+ .name = "COINCELL",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(coincell_consumer),
+ .consumer_supplies = coincell_consumer,
+};
+
+static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = {
+ { .id = MC13892_SW1, .init_data = &sw1_init },
+ { .id = MC13892_SW2, .init_data = &sw2_init },
+ { .id = MC13892_SW3, .init_data = &sw3_init },
+ { .id = MC13892_SW4, .init_data = &sw4_init },
+ { .id = MC13892_SWBST, .init_data = &swbst_init },
+ { .id = MC13892_VIOHI, .init_data = &viohi_init },
+ { .id = MC13892_VPLL, .init_data = &vpll_init },
+ { .id = MC13892_VDIG, .init_data = &vdig_init },
+ { .id = MC13892_VSD, .init_data = &vsd_init },
+ { .id = MC13892_VUSB2, .init_data = &vusb2_init },
+ { .id = MC13892_VVIDEO, .init_data = &vvideo_init },
+ { .id = MC13892_VAUDIO, .init_data = &vaudio_init },
+ { .id = MC13892_VCAM, .init_data = &vcam_init },
+ { .id = MC13892_VGEN1, .init_data = &vgen1_init },
+ { .id = MC13892_VGEN2, .init_data = &vgen2_init },
+ { .id = MC13892_VGEN3, .init_data = &vgen3_init },
+ { .id = MC13892_VUSB, .init_data = &vusb_init },
+ { .id = MC13892_GPO1, .init_data = &gpo1_init },
+ { .id = MC13892_GPO2, .init_data = &gpo2_init },
+ { .id = MC13892_GPO3, .init_data = &gpo3_init },
+ { .id = MC13892_GPO4, .init_data = &gpo4_init },
+ { .id = MC13892_PWGT1SPI, .init_data = &pwgt1_init },
+ { .id = MC13892_PWGT2SPI, .init_data = &pwgt2_init },
+ { .id = MC13892_VCOINCELL, .init_data = &vcoincell_init },
+};
+
+static struct mc13xxx_platform_data mx51_efika_mc13892_data = {
+ .flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR,
+ .regulators = {
+ .num_regulators = ARRAY_SIZE(mx51_efika_regulators),
+ .regulators = mx51_efika_regulators,
+ },
+};
+
+static struct spi_board_info mx51_efika_spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 25000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &mx51_efika_spi_flash_data,
+ .irq = -1,
+ },
+ {
+ .modalias = "mc13892",
+ .max_speed_hz = 1000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &mx51_efika_mc13892_data,
+ .irq = gpio_to_irq(EFIKAMX_PMIC),
+ },
+};
+
+static int mx51_efika_spi_cs[] = {
+ EFIKAMX_SPI_CS0,
+ EFIKAMX_SPI_CS1,
+};
+
+static const struct spi_imx_master mx51_efika_spi_pdata __initconst = {
+ .chipselect = mx51_efika_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx51_efika_spi_cs),
+};
+
+void __init efika_board_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51efika_pads,
+ ARRAY_SIZE(mx51efika_pads));
+ imx51_add_imx_uart(0, &uart_pdata);
+ mx51_efika_usb();
+ imx51_add_sdhci_esdhc_imx(0, NULL);
+
+ /* FIXME: comes from original code. check this. */
+ if (mx51_revision() < IMX_CHIP_REVISION_2_0)
+ sw2_init.constraints.state_mem.uV = 1100000;
+ else if (mx51_revision() == IMX_CHIP_REVISION_2_0) {
+ sw2_init.constraints.state_mem.uV = 1250000;
+ sw1_init.constraints.state_mem.uV = 1000000;
+ }
+ if (machine_is_mx51_efikasb())
+ vgen1_init.constraints.max_uV = 1200000;
+
+ gpio_request(EFIKAMX_PMIC, "pmic irq");
+ gpio_direction_input(EFIKAMX_PMIC);
+ spi_register_board_info(mx51_efika_spi_board_info,
+ ARRAY_SIZE(mx51_efika_spi_board_info));
+ imx51_add_ecspi(0, &mx51_efika_spi_pdata);
+
+#if defined(CONFIG_CPU_FREQ_IMX)
+ get_cpu_op = mx51_get_cpu_op;
+#endif
+}
+
diff --git a/arch/arm/mach-mx5/mx53_loco_pmic_da9053.c b/arch/arm/mach-mx5/mx53_loco_pmic_da9053.c
new file mode 100755
index 00000000..9259fd01
--- /dev/null
+++ b/arch/arm/mach-mx5/mx53_loco_pmic_da9053.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/*
+ * mx53_loco_pmic_da9053.c -- i.MX53 LOCO driver for pmic da9053
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/pm.h>
+#include <linux/mfd/da9052/led.h>
+#include <linux/mfd/da9052/tsi.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx53.h>
+#include <mach/gpio.h>
+
+#define DA9052_LDO(max, min, rname, suspend_mv, num_consumers, consumers) \
+{\
+ .constraints = {\
+ .name = (rname), \
+ .max_uV = (max) * 1000,\
+ .min_uV = (min) * 1000,\
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE\
+ |REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE,\
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,\
+ .state_mem = { \
+ .uV = suspend_mv * 1000, \
+ .mode = REGULATOR_MODE_NORMAL, \
+ .enabled = (0 == suspend_mv) ? 0 : 1, \
+ .disabled = 0, \
+ }, \
+ },\
+ .num_consumer_supplies = (num_consumers), \
+ .consumer_supplies = (consumers), \
+}
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+
+static struct regulator_consumer_supply sgtl5000_consumer[] = {
+ REGULATOR_SUPPLY("VDDA", NULL),
+ REGULATOR_SUPPLY("VDDIO", NULL),
+};
+
+static struct regulator_init_data sgtl5000_reg_initdata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sgtl5000_consumer),
+ .consumer_supplies = &sgtl5000_consumer[0],
+};
+
+static struct fixed_voltage_config sgtl5000_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 3200000,
+ .gpio = -1,
+ .init_data = &sgtl5000_reg_initdata,
+};
+
+static struct platform_device sgtl5000_reg_devices = {
+
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &sgtl5000_reg_config,
+ },
+};
+#endif /* CONFIG_SND_SOC_SGTL5000 */
+
+/* CPU */
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "cpu_vddgp",
+ }
+};
+
+/* currently the suspend_mv here takes no effects for DA9053
+preset-voltage have to be done in the latest stage during
+suspend*/
+static struct regulator_init_data da9052_regulators_init[] = {
+ DA9052_LDO(DA9052_LDO1_VOLT_UPPER,
+ DA9052_LDO1_VOLT_LOWER, "DA9052_LDO1", 1300, 0, NULL),
+ DA9052_LDO(DA9052_LDO2_VOLT_UPPER,
+ DA9052_LDO2_VOLT_LOWER, "DA9052_LDO2", 1300, 0, NULL),
+ DA9052_LDO(DA9052_LDO34_VOLT_UPPER,
+ DA9052_LDO34_VOLT_LOWER, "DA9052_LDO3", 3300, 0, NULL),
+ DA9052_LDO(DA9052_LDO34_VOLT_UPPER,
+ DA9052_LDO34_VOLT_LOWER, "DA9052_LDO4", 2775, 0, NULL),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO5", 1300, 0, NULL),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO6", 1200, 0, NULL),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO7", 2750, 0, NULL),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO8", 1800, 0, NULL),
+ DA9052_LDO(DA9052_LDO9_VOLT_UPPER,
+ DA9052_LDO9_VOLT_LOWER, "DA9052_LDO9", 2500, 0, NULL),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO10", 1200, 0, NULL),
+
+ /* BUCKS */
+ DA9052_LDO(DA9052_BUCK_CORE_PRO_VOLT_UPPER,
+ DA9052_BUCK_CORE_PRO_VOLT_LOWER, "DA9052_BUCK_CORE", 850,
+ ARRAY_SIZE(sw1_consumers), sw1_consumers),
+ DA9052_LDO(DA9052_BUCK_CORE_PRO_VOLT_UPPER,
+ DA9052_BUCK_CORE_PRO_VOLT_LOWER, "DA9052_BUCK_PRO", 950,
+ 0, NULL),
+ DA9052_LDO(DA9052_BUCK_MEM_VOLT_UPPER,
+ DA9052_BUCK_MEM_VOLT_LOWER, "DA9052_BUCK_MEM", 1500, 0, NULL),
+ DA9052_LDO(DA9052_BUCK_PERI_VOLT_UPPER,
+ DA9052_BUCK_PERI_VOLT_LOWER, "DA9052_BUCK_PERI", 2500, 0, NULL)
+};
+
+
+static struct da9052_tsi_platform_data da9052_tsi = {
+ .pen_up_interval = 50,
+ .tsi_delay_bit_shift = 6,
+ .tsi_skip_bit_shift = 3,
+ .num_gpio_tsi_register = 3,
+ .tsi_supply_voltage = 2500,
+ /* This is the DA9052 LDO number used for powering the TSI */
+ .tsi_ref_source = 9,
+ .max_tsi_delay = TSI_DELAY_4SLOTS,
+ .max_tsi_skip_slot = TSI_SKIP_330SLOTS,
+};
+
+static struct da9052_led_platform_data da9052_gpio_led[] = {
+ {
+ .id = DA9052_LED_4,
+ .name = "LED_GPIO14",
+ },
+ {
+ .id = DA9052_LED_5,
+ .name = "LED_GPIO15",
+ },
+};
+
+static struct da9052_leds_platform_data da9052_gpio_leds = {
+ .num_leds = ARRAY_SIZE(da9052_gpio_led),
+ .led = da9052_gpio_led,
+};
+
+
+static void da9052_init_ssc_cache(struct da9052 *da9052)
+{
+ unsigned char cnt;
+
+ /* First initialize all registers as Non-volatile */
+ for (cnt = 0; cnt < DA9052_REG_CNT; cnt++) {
+ da9052->ssc_cache[cnt].type = NON_VOLATILE;
+ da9052->ssc_cache[cnt].status = INVALID;
+ da9052->ssc_cache[cnt].val = 0;
+ }
+
+ /* Now selectively set type for all Volatile registers */
+ /* Reg 1 - 9 */
+ da9052->ssc_cache[DA9052_STATUSA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_FAULTLOG_REG].type = VOLATILE;
+
+ /* Reg 15 */
+ da9052->ssc_cache[DA9052_CONTROLB_REG].type = VOLATILE;
+ /* Reg - 17 */
+ da9052->ssc_cache[DA9052_CONTROLD_REG].type = VOLATILE;
+ /* Reg - 60 */
+ da9052->ssc_cache[DA9052_SUPPLY_REG].type = VOLATILE;
+ /* Reg - 62 */
+ da9052->ssc_cache[DA9052_CHGBUCK_REG].type = VOLATILE;
+
+ /* Reg 67 - 68 */
+ da9052->ssc_cache[DA9052_INPUTCONT_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_CHGTIME_REG].type = VOLATILE;
+
+ /* Reg - 70 */
+ da9052->ssc_cache[DA9052_BOOST_REG].type = VOLATILE;
+
+ /* Reg - 81 */
+ da9052->ssc_cache[DA9052_ADCMAN_REG].type = VOLATILE;
+
+ /* Reg - 83 - 85 */
+ da9052->ssc_cache[DA9052_ADCRESL_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_ADCRESH_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_VDDRES_REG].type = VOLATILE;
+
+ /* Reg - 87 */
+ da9052->ssc_cache[DA9052_ICHGAV_REG].type = VOLATILE;
+
+ /* Reg - 90 */
+ da9052->ssc_cache[DA9052_TBATRES_REG].type = VOLATILE;
+
+ /* Reg - 95 */
+ da9052->ssc_cache[DA9052_ADCIN4RES_REG].type = VOLATILE;
+
+ /* Reg - 98 */
+ da9052->ssc_cache[DA9052_ADCIN5RES_REG].type = VOLATILE;
+
+ /* Reg - 101 */
+ da9052->ssc_cache[DA9052_ADCIN6RES_REG].type = VOLATILE;
+
+ /* Reg - 104 */
+ da9052->ssc_cache[DA9052_TJUNCRES_REG].type = VOLATILE;
+
+ /* Reg 106 - 110 */
+ da9052->ssc_cache[DA9052_TSICONTB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIXMSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIYMSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSILSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIZMSB_REG].type = VOLATILE;
+
+ /* Reg 111 - 117 */
+ da9052->ssc_cache[DA9052_COUNTS_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTMI_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTH_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTMO_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTY_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_ALARMMI_REG].type = VOLATILE;
+
+ /* Reg 122 - 125 */
+ da9052->ssc_cache[DA9052_SECONDA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDD_REG].type = VOLATILE;
+
+ /* Following addresses are not assigned to any register */
+ da9052->ssc_cache[126].type = VOLATILE;
+ da9052->ssc_cache[127].type = VOLATILE;
+}
+
+
+#define MX53_LOCO_DA9052_IRQ (6*32 + 11) /* GPIO7_11 */
+
+static int __init loco_da9052_init(struct da9052 *da9052)
+{
+ /* Configuring for DA9052 interrupt servce */
+ /* s3c_gpio_setpull(DA9052_IRQ_PIN, S3C_GPIO_PULL_UP);*/
+
+ /* Set interrupt as LOW LEVEL interrupt source */
+ set_irq_type(gpio_to_irq(MX53_LOCO_DA9052_IRQ), IRQF_TRIGGER_LOW);
+
+ da9052_init_ssc_cache(da9052);
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+ platform_device_register(&sgtl5000_reg_devices);
+#endif
+
+ return 0;
+}
+
+static struct da9052_platform_data __initdata da9052_plat = {
+ .init = loco_da9052_init,
+ .num_regulators = ARRAY_SIZE(da9052_regulators_init),
+ .regulators = da9052_regulators_init,
+ .led_data = &da9052_gpio_leds,
+ .tsi_data = &da9052_tsi,
+ /* .bat_data = &da9052_bat, */
+ /* .gpio_base = GPIO_BOARD_START, */
+};
+
+
+static struct i2c_board_info __initdata da9052_i2c_device = {
+ I2C_BOARD_INFO(DA9052_SSC_I2C_DEVICE_NAME, DA9052_I2C_ADDR >> 1),
+ .irq = gpio_to_irq(MX53_LOCO_DA9052_IRQ),
+ .platform_data = &da9052_plat,
+};
+
+int __init mx53_loco_init_da9052(void)
+{
+ return i2c_register_board_info(0, &da9052_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx5/mx53_loco_pmic_mc34708.c b/arch/arm/mach-mx5/mx53_loco_pmic_mc34708.c
new file mode 100644
index 00000000..f88a184a
--- /dev/null
+++ b/arch/arm/mach-mx5/mx53_loco_pmic_mc34708.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/mc-pmic.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx53.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define MC34708_I2C_DEVICE_NAME "mc34708"
+/* 7-bit I2C bus slave address */
+#define MC34708_I2C_ADDR (0x08)
+
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "SW1",
+ .min_uV = 650000,
+ .max_uV = 1437500,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "SW1B",
+ .min_uV = 650000,
+ .max_uV = 1437500,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+ .min_uV = 650000,
+ .max_uV = 1437500,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ }
+};
+
+static struct regulator_init_data sw3_init = {
+ .constraints = {
+ .name = "SW3",
+ .min_uV = 650000,
+ .max_uV = 1425000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw4a_init = {
+ .constraints = {
+ .name = "SW4A",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(3300),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw4b_init = {
+ .constraints = {
+ .name = "SW4B",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(3300),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data sw5_init = {
+ .constraints = {
+ .name = "SW5",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(1975),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb_init = {
+ .constraints = {
+ .name = "VUSB",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "SWBST",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vpll_init = {
+ .constraints = {
+ .name = "VPLL",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(1800),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vdac_init = {
+ .constraints = {
+ .name = "VDAC",
+ .min_uV = mV_to_uV(2500),
+ .max_uV = mV_to_uV(2775),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vusb2_init = {
+ .constraints = {
+ .name = "VUSB2",
+ .min_uV = mV_to_uV(2500),
+ .max_uV = mV_to_uV(3000),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .boot_on = 1,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+ .min_uV = mV_to_uV(1200),
+ .max_uV = mV_to_uV(1550),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ }
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+ .min_uV = mV_to_uV(2500),
+ .max_uV = mV_to_uV(3300),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .always_on = 1,
+ }
+};
+
+static struct mc_pmic_regulator_init_data mx53_loco_mc34708_regulators[] = {
+ { .id = MC34708_SW1A, .init_data = &sw1a_init},
+ { .id = MC34708_SW1B, .init_data = &sw1b_init},
+ { .id = MC34708_SW2, .init_data = &sw2_init},
+ { .id = MC34708_SW3, .init_data = &sw3_init},
+ { .id = MC34708_SW4A, .init_data = &sw4a_init},
+ { .id = MC34708_SW4B, .init_data = &sw4b_init},
+ { .id = MC34708_SW5, .init_data = &sw5_init},
+ { .id = MC34708_SWBST, .init_data = &swbst_init},
+ { .id = MC34708_VPLL, .init_data = &vpll_init},
+ { .id = MC34708_VREFDDR, .init_data = &vrefddr_init},
+ { .id = MC34708_VUSB, .init_data = &vusb_init},
+ { .id = MC34708_VUSB2, .init_data = &vusb2_init},
+ { .id = MC34708_VDAC, .init_data = &vdac_init},
+ { .id = MC34708_VGEN1, .init_data = &vgen1_init},
+ { .id = MC34708_VGEN2, .init_data = &vgen2_init},
+
+};
+
+
+static struct mc_pmic_platform_data mc34708_plat = {
+ .flags = MC_PMIC_USE_RTC | MC_PMIC_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx53_loco_mc34708_regulators),
+ .regulators = mx53_loco_mc34708_regulators,
+};
+
+static struct i2c_board_info __initdata mc34708_i2c_device = {
+ I2C_BOARD_INFO(MC34708_I2C_DEVICE_NAME, MC34708_I2C_ADDR),
+ .platform_data = &mc34708_plat,
+};
+
+int __init mx53_loco_init_mc34708(u32 int_gpio)
+{
+ mc34708_i2c_device.irq = gpio_to_irq(int_gpio);/*update INT gpio*/
+ return i2c_register_board_info(0, &mc34708_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx5/mx53_smd_pmic_da9053.c b/arch/arm/mach-mx5/mx53_smd_pmic_da9053.c
new file mode 100755
index 00000000..ae39b845
--- /dev/null
+++ b/arch/arm/mach-mx5/mx53_smd_pmic_da9053.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/*
+ * mx53_smd_pmic_da9053.c -- i.MX53 SMD driver for pmic da9053
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/da9052/da9052.h>
+#include <linux/mfd/da9052/pm.h>
+#include <linux/mfd/da9052/led.h>
+#include <linux/mfd/da9052/tsi.h>
+#include <mach/irqs.h>
+#include <mach/iomux-mx53.h>
+#include <mach/gpio.h>
+
+#define DA9052_LDO(max, min, rname, suspend_mv) \
+{\
+ .constraints = {\
+ .name = (rname), \
+ .max_uV = (max) * 1000,\
+ .min_uV = (min) * 1000,\
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE\
+ |REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE,\
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,\
+ .state_mem = { \
+ .uV = suspend_mv * 1000, \
+ .mode = REGULATOR_MODE_NORMAL, \
+ .enabled = (0 == suspend_mv) ? 0 : 1, \
+ .disabled = 0, \
+ }, \
+ },\
+}
+
+/* currently the suspend_mv field here takes no effects for DA9053
+preset-voltage have to be done in the latest stage during
+suspend*/
+static struct regulator_init_data da9052_regulators_init[] = {
+ DA9052_LDO(DA9052_LDO1_VOLT_UPPER,
+ DA9052_LDO1_VOLT_LOWER, "DA9052_LDO1", 1300),
+ DA9052_LDO(DA9052_LDO2_VOLT_UPPER,
+ DA9052_LDO2_VOLT_LOWER, "DA9052_LDO2", 1300),
+ DA9052_LDO(DA9052_LDO34_VOLT_UPPER,
+ DA9052_LDO34_VOLT_LOWER, "DA9052_LDO3", 3300),
+ DA9052_LDO(DA9052_LDO34_VOLT_UPPER,
+ DA9052_LDO34_VOLT_LOWER, "DA9052_LDO4", 2775),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO5", 1300),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO6", 1200),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO7", 2750),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO8", 1800),
+ DA9052_LDO(DA9052_LDO9_VOLT_UPPER,
+ DA9052_LDO9_VOLT_LOWER, "DA9052_LDO9", 2500),
+ DA9052_LDO(DA9052_LDO567810_VOLT_UPPER,
+ DA9052_LDO567810_VOLT_LOWER, "DA9052_LDO10", 1200),
+
+ /* BUCKS */
+ DA9052_LDO(DA9052_BUCK_CORE_PRO_VOLT_UPPER,
+ DA9052_BUCK_CORE_PRO_VOLT_LOWER, "DA9052_BUCK_CORE", 850),
+ DA9052_LDO(DA9052_BUCK_CORE_PRO_VOLT_UPPER,
+ DA9052_BUCK_CORE_PRO_VOLT_LOWER, "DA9052_BUCK_PRO", 950),
+ DA9052_LDO(DA9052_BUCK_MEM_VOLT_UPPER,
+ DA9052_BUCK_MEM_VOLT_LOWER, "DA9052_BUCK_MEM", 1500),
+ DA9052_LDO(DA9052_BUCK_PERI_VOLT_UPPER,
+ DA9052_BUCK_PERI_VOLT_LOWER, "DA9052_BUCK_PERI", 2500)
+};
+
+
+#define MX53_SMD_WiFi_BT_PWR_EN (2*32 + 10) /*GPIO_3_10 */
+struct regulator_init_data wifi_bt_reg_initdata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config wifi_bt_reg_config = {
+ .supply_name = "wifi_bt",
+ .microvolts = 3300000,
+ .gpio = MX53_SMD_WiFi_BT_PWR_EN,
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &wifi_bt_reg_initdata,
+};
+
+static struct platform_device wifi_bt_reg_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wifi_bt_reg_config,
+ },
+};
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+
+static struct regulator_consumer_supply sgtl5000_consumer[] = {
+ REGULATOR_SUPPLY("VDDA", NULL),
+ REGULATOR_SUPPLY("VDDIO", NULL),
+};
+
+static struct regulator_init_data sgtl5000_reg_initdata = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sgtl5000_consumer),
+ .consumer_supplies = &sgtl5000_consumer[0],
+};
+
+static struct fixed_voltage_config sgtl5000_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sgtl5000_reg_initdata,
+};
+
+static struct platform_device sgtl5000_reg_devices = {
+
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &sgtl5000_reg_config,
+ },
+};
+#endif /* CONFIG_SND_SOC_SGTL5000 */
+
+static struct da9052_tsi_platform_data da9052_tsi = {
+ .pen_up_interval = 50,
+ .tsi_delay_bit_shift = 6,
+ .tsi_skip_bit_shift = 3,
+ .num_gpio_tsi_register = 3,
+ .tsi_supply_voltage = 2500,
+ /* This is the DA9052 LDO number used for powering the TSI */
+ .tsi_ref_source = 9,
+ .max_tsi_delay = TSI_DELAY_4SLOTS,
+ .max_tsi_skip_slot = TSI_SKIP_330SLOTS,
+};
+
+static struct da9052_led_platform_data da9052_gpio_led[] = {
+ {
+ .id = DA9052_LED_4,
+ .name = "LED_GPIO14",
+ },
+ {
+ .id = DA9052_LED_5,
+ .name = "LED_GPIO15",
+ },
+};
+
+static struct da9052_leds_platform_data da9052_gpio_leds = {
+ .num_leds = ARRAY_SIZE(da9052_gpio_led),
+ .led = da9052_gpio_led,
+};
+
+
+static void da9052_init_ssc_cache(struct da9052 *da9052)
+{
+ unsigned char cnt;
+
+ /* First initialize all registers as Non-volatile */
+ for (cnt = 0; cnt < DA9052_REG_CNT; cnt++) {
+ da9052->ssc_cache[cnt].type = NON_VOLATILE;
+ da9052->ssc_cache[cnt].status = INVALID;
+ da9052->ssc_cache[cnt].val = 0;
+ }
+
+ /* Now selectively set type for all Volatile registers */
+ /* Reg 1 - 9 */
+ da9052->ssc_cache[DA9052_STATUSA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_STATUSD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_EVENTD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_FAULTLOG_REG].type = VOLATILE;
+
+ /* Reg 15 */
+ da9052->ssc_cache[DA9052_CONTROLB_REG].type = VOLATILE;
+ /* Reg - 17 */
+ da9052->ssc_cache[DA9052_CONTROLD_REG].type = VOLATILE;
+ /* Reg - 60 */
+ da9052->ssc_cache[DA9052_SUPPLY_REG].type = VOLATILE;
+ /* Reg - 62 */
+ da9052->ssc_cache[DA9052_CHGBUCK_REG].type = VOLATILE;
+
+ /* Reg 67 - 68 */
+ da9052->ssc_cache[DA9052_INPUTCONT_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_CHGTIME_REG].type = VOLATILE;
+
+ /* Reg - 70 */
+ da9052->ssc_cache[DA9052_BOOST_REG].type = VOLATILE;
+
+ /* Reg - 81 */
+ da9052->ssc_cache[DA9052_ADCMAN_REG].type = VOLATILE;
+
+ /* Reg - 83 - 85 */
+ da9052->ssc_cache[DA9052_ADCRESL_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_ADCRESH_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_VDDRES_REG].type = VOLATILE;
+
+ /* Reg - 87 */
+ da9052->ssc_cache[DA9052_ICHGAV_REG].type = VOLATILE;
+
+ /* Reg - 90 */
+ da9052->ssc_cache[DA9052_TBATRES_REG].type = VOLATILE;
+
+ /* Reg - 95 */
+ da9052->ssc_cache[DA9052_ADCIN4RES_REG].type = VOLATILE;
+
+ /* Reg - 98 */
+ da9052->ssc_cache[DA9052_ADCIN5RES_REG].type = VOLATILE;
+
+ /* Reg - 101 */
+ da9052->ssc_cache[DA9052_ADCIN6RES_REG].type = VOLATILE;
+
+ /* Reg - 104 */
+ da9052->ssc_cache[DA9052_TJUNCRES_REG].type = VOLATILE;
+
+ /* Reg 106 - 110 */
+ da9052->ssc_cache[DA9052_TSICONTB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIXMSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIYMSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSILSB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_TSIZMSB_REG].type = VOLATILE;
+
+ /* Reg 111 - 117 */
+ da9052->ssc_cache[DA9052_COUNTS_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTMI_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTH_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTD_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTMO_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_COUNTY_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_ALARMMI_REG].type = VOLATILE;
+
+ /* Reg 122 - 125 */
+ da9052->ssc_cache[DA9052_SECONDA_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDB_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDC_REG].type = VOLATILE;
+ da9052->ssc_cache[DA9052_SECONDD_REG].type = VOLATILE;
+
+ /* Following addresses are not assigned to any register */
+ da9052->ssc_cache[126].type = VOLATILE;
+ da9052->ssc_cache[127].type = VOLATILE;
+}
+
+
+#define MX53_SMD_DA9052_IRQ (6*32 + 11) /* GPIO7_11 */
+
+static int __init smd_da9052_init(struct da9052 *da9052)
+{
+ /* Configuring for DA9052 interrupt servce */
+ /* s3c_gpio_setpull(DA9052_IRQ_PIN, S3C_GPIO_PULL_UP);*/
+ int ret;
+ /* Set interrupt as LOW LEVEL interrupt source */
+ set_irq_type(gpio_to_irq(MX53_SMD_DA9052_IRQ), IRQF_TRIGGER_LOW);
+
+ da9052_init_ssc_cache(da9052);
+#ifdef CONFIG_SND_SOC_SGTL5000
+ platform_device_register(&sgtl5000_reg_devices);
+#endif
+ ret = platform_device_register(&wifi_bt_reg_device);
+
+ return 0;
+}
+
+static struct da9052_platform_data __initdata da9052_plat = {
+ .init = smd_da9052_init,
+ .num_regulators = ARRAY_SIZE(da9052_regulators_init),
+ .regulators = da9052_regulators_init,
+ .led_data = &da9052_gpio_leds,
+ .tsi_data = &da9052_tsi,
+ /* .bat_data = &da9052_bat, */
+ /* .gpio_base = GPIO_BOARD_START, */
+};
+
+
+static struct i2c_board_info __initdata da9052_i2c_device = {
+ I2C_BOARD_INFO(DA9052_SSC_I2C_DEVICE_NAME, DA9052_I2C_ADDR >> 1),
+ .irq = gpio_to_irq(MX53_SMD_DA9052_IRQ),
+ .platform_data = &da9052_plat,
+};
+
+int __init mx53_smd_init_da9052(void)
+{
+ return i2c_register_board_info(0, &da9052_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx5/pm.c b/arch/arm/mach-mx5/pm.c
new file mode 100755
index 00000000..9240b7ae
--- /dev/null
+++ b/arch/arm/mach-mx5/pm.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
+#include <linux/regulator/machine.h>
+#include <linux/proc_fs.h>
+#include <linux/cpufreq.h>
+#include <linux/iram_alloc.h>
+#include <linux/fsl_devices.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <asm/delay.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#ifdef CONFIG_ARCH_MX50
+#include <mach/iomux-mx50.h>
+#endif
+#include "crm_regs.h"
+
+#define DATABAHN_CTL_REG0 0
+#define DATABAHN_CTL_REG19 0x4c
+#define DATABAHN_CTL_REG79 0x13c
+#define DATABAHN_PHY_REG25 0x264
+#define MX53_OFFSET 0x20000000
+
+static struct cpu_op *cpu_op_tbl;
+static int cpu_op_nr;
+static struct clk *cpu_clk;
+static struct mxc_pm_platform_data *pm_data;
+
+#if defined(CONFIG_CPU_FREQ)
+static int org_freq;
+extern int set_cpu_freq(int wp);
+#endif
+
+
+static struct device *pm_dev;
+struct clk *gpc_dvfs_clk;
+extern void cpu_do_suspend_workaround(u32 sdclk_iomux_addr);
+extern void mx50_suspend(u32 databahn_addr);
+extern struct cpu_op *(*get_cpu_op)(int *wp);
+extern void __iomem *databahn_base;
+extern void da9053_suspend_cmd(void);
+extern void da9053_resume_dump(void);
+extern void pm_da9053_i2c_init(u32 base_addr);
+
+extern int iram_ready;
+void *suspend_iram_base;
+void (*suspend_in_iram)(void *sdclk_iomux_addr) = NULL;
+void __iomem *suspend_param1;
+
+#define TZIC_WAKEUP0_OFFSET 0x0E00
+#define TZIC_WAKEUP1_OFFSET 0x0E04
+#define TZIC_WAKEUP2_OFFSET 0x0E08
+#define TZIC_WAKEUP3_OFFSET 0x0E0C
+#define GPIO7_0_11_IRQ_BIT (0x1<<11)
+
+static void mx53_smd_loco_irq_wake_fixup(void)
+{
+ void __iomem *tzic_base;
+ tzic_base = ioremap(MX53_TZIC_BASE_ADDR, SZ_4K);
+ if (NULL == tzic_base) {
+ pr_err("fail to map MX53_TZIC_BASE_ADDR\n");
+ return;
+ }
+ __raw_writel(0, tzic_base + TZIC_WAKEUP0_OFFSET);
+ __raw_writel(0, tzic_base + TZIC_WAKEUP1_OFFSET);
+ __raw_writel(0, tzic_base + TZIC_WAKEUP2_OFFSET);
+ /* only enable irq wakeup for da9053 */
+ __raw_writel(GPIO7_0_11_IRQ_BIT, tzic_base + TZIC_WAKEUP3_OFFSET);
+ iounmap(tzic_base);
+ pr_debug("only da9053 irq is wakeup-enabled\n");
+}
+
+static int mx5_suspend_enter(suspend_state_t state)
+{
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+ /* gpc clock is needed for SRPG */
+ clk_enable(gpc_dvfs_clk);
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mxc_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (tzic_enable_wake(0) != 0)
+ return -EAGAIN;
+
+ if (state == PM_SUSPEND_MEM) {
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ if (pm_data && pm_data->suspend_enter)
+ pm_data->suspend_enter();
+
+ suspend_in_iram(suspend_param1);
+
+ if (pm_data && pm_data->suspend_exit)
+ pm_data->suspend_exit();
+ } else {
+ cpu_do_idle();
+ }
+ clk_disable(gpc_dvfs_clk);
+
+ return 0;
+}
+
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx5_suspend_prepare(void)
+{
+#if defined(CONFIG_CPU_FREQ)
+#define MX53_SUSPEND_CPU_WP 1000000000
+ struct cpufreq_freqs freqs;
+ u32 suspend_wp = 0;
+ org_freq = clk_get_rate(cpu_clk);
+ /* workaround for mx53 to suspend on 400MHZ wp */
+ if (cpu_is_mx53())
+ for (suspend_wp = 0; suspend_wp < cpu_op_nr; suspend_wp++)
+ if (cpu_op_tbl[suspend_wp].cpu_rate
+ == MX53_SUSPEND_CPU_WP)
+ break;
+ if (suspend_wp == cpu_op_nr)
+ suspend_wp = 0;
+ pr_info("suspend wp cpu=%d\n", cpu_op_tbl[suspend_wp].cpu_rate);
+ freqs.old = org_freq / 1000;
+ freqs.new = cpu_op_tbl[suspend_wp].cpu_rate / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+
+ if (clk_get_rate(cpu_clk) != cpu_op_tbl[suspend_wp].cpu_rate) {
+ set_cpu_freq(cpu_op_tbl[suspend_wp].cpu_rate);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Called before devices are re-setup.
+ */
+static void mx5_suspend_finish(void)
+{
+#if defined(CONFIG_CPU_FREQ)
+ struct cpufreq_freqs freqs;
+
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+ freqs.new = org_freq / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+
+
+ if (org_freq != clk_get_rate(cpu_clk)) {
+ set_cpu_freq(org_freq);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+#endif
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx5_suspend_end(void)
+{
+}
+
+static int mx5_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx5_suspend_ops = {
+ .valid = mx5_pm_valid,
+ .prepare = mx5_suspend_prepare,
+ .enter = mx5_suspend_enter,
+ .finish = mx5_suspend_finish,
+ .end = mx5_suspend_end,
+};
+
+static int __devinit mx5_pm_probe(struct platform_device *pdev)
+{
+ pm_dev = &pdev->dev;
+ pm_data = pdev->dev.platform_data;
+
+ return 0;
+}
+
+static struct platform_driver mx5_pm_driver = {
+ .driver = {
+ .name = "mx5_pm",
+ },
+ .probe = mx5_pm_probe,
+};
+
+static int __init pm_init(void)
+{
+ unsigned long iram_paddr, cpaddr;
+
+ pr_info("Static Power Management for Freescale i.MX5\n");
+ if (platform_driver_register(&mx5_pm_driver) != 0) {
+ printk(KERN_ERR "mx5_pm_driver register failed\n");
+ return -ENODEV;
+ }
+ suspend_set_ops(&mx5_suspend_ops);
+ /* Move suspend routine into iRAM */
+ cpaddr = iram_alloc(SZ_4K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ suspend_iram_base = __arm_ioremap(iram_paddr, SZ_4K,
+ MT_HIGH_VECTORS);
+ pr_info("cpaddr = %x suspend_iram_base=%x\n", cpaddr, suspend_iram_base);
+
+ if (cpu_is_mx51() || cpu_is_mx53()) {
+ suspend_param1 = MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR + 0x4b8);
+ memcpy(cpaddr, cpu_do_suspend_workaround,
+ SZ_4K);
+ } else if (cpu_is_mx50()) {
+ /*
+ * Need to run the suspend code from IRAM as the DDR needs
+ * to be put into self refresh mode manually.
+ */
+ memcpy(cpaddr, mx50_suspend, SZ_4K);
+
+ suspend_param1 = databahn_base;
+ }
+ suspend_in_iram = (void *)suspend_iram_base;
+
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+ printk(KERN_INFO "PM driver module loaded\n");
+
+ return 0;
+}
+
+
+static void __exit pm_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&mx5_pm_driver);
+}
+
+module_init(pm_init);
+module_exit(pm_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("PM driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx5/sdram_autogating.c b/arch/arm/mach-mx5/sdram_autogating.c
new file mode 100755
index 00000000..ca75739e
--- /dev/null
+++ b/arch/arm/mach-mx5/sdram_autogating.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file sdram_autogating.c
+ *
+ * @brief Enable auto clock gating of the EMI_FAST clock using M4IF.
+ *
+ * The APIs are for enabling and disabling automatic clock gating of EMI_FAST.
+ *
+ * @ingroup PM
+ */
+#include <asm/io.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/sdram_autogating.h>
+#include "crm_regs.h"
+
+static struct device *sdram_autogating_dev;
+#define M4IF_CNTL_REG0 0x8c
+#define M4IF_CNTL_REG1 0x90
+
+/* Flag used to indicate if SDRAM M4IF autoclock gating feature is active. */
+static int sdram_autogating_is_active;
+static int sdram_autogating_paused;
+static void __iomem *m4if_base;
+
+void start_sdram_autogating(void);
+void stop_sdram_autogating(void);
+int sdram_autogating_active(void);
+
+static void enable(void)
+{
+ u32 reg;
+
+ /* Set the Fast arbitration Power saving timer */
+ reg = __raw_readl(m4if_base + M4IF_CNTL_REG1);
+ reg &= ~0xFF;
+ reg |= 0x09;
+ __raw_writel(reg, m4if_base + M4IF_CNTL_REG1);
+ /*Allow for automatic gating of the EMI internal clock.
+ * If this is done, emi_intr CCGR bits should be set to 11.
+ */
+ reg = __raw_readl(m4if_base + M4IF_CNTL_REG0);
+ reg &= ~0x5;
+ __raw_writel(reg, m4if_base + M4IF_CNTL_REG0);
+
+ sdram_autogating_is_active = 1;
+}
+
+static void disable(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(m4if_base + M4IF_CNTL_REG0);
+ reg |= 0x4;
+ __raw_writel(reg, m4if_base + M4IF_CNTL_REG0);
+ sdram_autogating_is_active = 0;
+}
+
+int sdram_autogating_active()
+{
+ return sdram_autogating_is_active;
+}
+
+void start_sdram_autogating()
+{
+ if (cpu_is_mx50())
+ return;
+ if (sdram_autogating_paused) {
+ enable();
+ sdram_autogating_paused = 0;
+ }
+}
+
+void stop_sdram_autogating()
+{
+ if (cpu_is_mx50())
+ return;
+
+ if (sdram_autogating_is_active) {
+ sdram_autogating_paused = 1;
+ disable();
+ }
+}
+
+static ssize_t sdram_autogating_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (sdram_autogating_is_active)
+ return sprintf(buf,
+ "M4IF autoclock gating for EMI_FAST enabled\n");
+ else
+ return sprintf(buf,
+ "M4IF autoclock gating for EMI_FAST disabled\n");
+}
+
+static ssize_t sdram_autogating_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL)
+ enable();
+ else if (strstr(buf, "0") != NULL) {
+ if (sdram_autogating_is_active)
+ disable();
+ }
+ return size;
+}
+
+static DEVICE_ATTR(enable, 0644, sdram_autogating_enable_show,
+ sdram_autogating_enable_store);
+
+/*!
+ * This is the probe routine for the auto clockgating of sdram driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit sdram_autogating_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ int err = 0;
+
+ sdram_autogating_dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ return -ENOMEM;
+ }
+ m4if_base = ioremap(res->start, res->end - res->start + 1);
+
+ err = sysfs_create_file(&sdram_autogating_dev->kobj,
+ &dev_attr_enable.attr);
+ if (err) {
+ printk(KERN_ERR
+ "Unable to register sysdev entry for sdram_autogating");
+ return err;
+ }
+
+ sdram_autogating_is_active = 0;
+
+ return 0;
+}
+
+static struct platform_driver sdram_autogating_driver = {
+ .driver = {
+ .name = "sdram_autogating",
+ },
+ .probe = sdram_autogating_probe,
+};
+
+/*!
+ * Initialise the sdram_autogating_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init sdram_autogating_init(void)
+{
+ if (platform_driver_register(&sdram_autogating_driver) != 0) {
+ printk(KERN_ERR "sdram_autogating_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "sdram autogating driver module loaded\n");
+ return 0;
+}
+
+static void __exit sdram_autogating_cleanup(void)
+{
+ sysfs_remove_file(&sdram_autogating_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&sdram_autogating_driver);
+}
+
+module_init(sdram_autogating_init);
+module_exit(sdram_autogating_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("sdram_autogating driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-mx5/suspend.S b/arch/arm/mach-mx5/suspend.S
new file mode 100755
index 00000000..c7937ec9
--- /dev/null
+++ b/arch/arm/mach-mx5/suspend.S
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+
+#define ARM_CTRL_DCACHE 1 << 2
+#define ARM_CTRL_ICACHE 1 << 12
+#define ARM_AUXCR_L2EN 1 << 1
+
+
+/*
+ * cpu_do_suspend_workaround()
+ *
+ * Suspend the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_do_suspend_workaround)
+ stmfd sp!, {r4,r5,r6,r7,r9,r10,r11} @ Save registers
+
+ mov r6, r0 @save iomux address
+ /* Disable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ bic r0, r0, #ARM_CTRL_ICACHE @ Disable ICache
+ bic r0, r0, #ARM_CTRL_DCACHE @ Disable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedClean
+ mov r10, #0
+Loop1Clean:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipClean @ No cache or only instruction cache at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned)
+Loop2Clean:
+ mov r9, r4 @ R9 working copy of the max way size (right aligned)
+Loop3Clean:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c14, 2 @ Clean and invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Clean
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Clean
+SkipClean:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Clean
+
+FinishedClean:
+
+ /* Disable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ bic r0, r0, #ARM_AUXCR_L2EN @ Disable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+#if 0
+ /*Set the DDR drive strength to low */
+ ldr r10, [r6]
+ and r10, r10, #0xF1 @ clear bits 2-1
+ str r10, [r6]
+#endif
+
+ .long 0xe320f003 @ Opcode for WFI
+
+#if 0
+ /*Set the DDR drive strength to max */
+ orr r10, r10, #0x06 @ set bits 2-1
+ str r10, [r6]
+#endif
+
+ ldr r11, =0x0000fFFF
+TestLoop:
+ subs r11,r11, #1 @ Decrement the index
+ bge TestLoop
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ Invalidate inst cache
+
+ /* Invalidate data caches */
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedInvalidate
+ mov r10, #0
+Loop1Invalidate:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipInvalidate @ No cache or only instruction cache at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned)
+Loop2Invalidate:
+ mov r9, r4 @ R9 working copy of the max way size (right aligned)
+Loop3Invalidate:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c6, 2 @ Invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Invalidate
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Invalidate
+SkipInvalidate:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Invalidate
+
+FinishedInvalidate:
+
+ /* Enable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ orr r0, r0, #ARM_AUXCR_L2EN @ Enable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+ /* Enable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ orr r0, r0, #ARM_CTRL_ICACHE @ Enable ICache
+ orr r0, r0, #ARM_CTRL_DCACHE @ Enable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ /* Restore registers */
+ ldmfd sp!, {r4,r5,r6,r7,r9,r10,r11}
+ mov pc, lr
+
+ .type cpu_do_suspend, #object
+ENTRY(cpu_do_suspend)
+ .word cpu_do_suspend_workaround
+ .size cpu_do_suspend_workaround, . - cpu_do_suspend_workaround
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
new file mode 100755
index 00000000..70667446
--- /dev/null
+++ b/arch/arm/mach-mx5/system.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/* set cpu low power mode before WFI instruction. This function is called
+ * mx5 because it can be used for mx50, mx51, and mx53.*/
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <asm/io.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX51 i.MX51 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx51/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX51
+ */
+
+extern int mxc_jtag_enabled;
+extern int iram_ready;
+extern int dvfs_core_is_active;
+extern void __iomem *ccm_base;
+extern void __iomem *databahn_base;
+extern int low_bus_freq_mode;
+extern void (*wait_in_iram)(void *ccm_addr, void *databahn_addr);
+extern void mx50_wait(u32 ccm_base, u32 databahn_addr);
+extern void stop_dvfs(void);
+extern void *wait_in_iram_base;
+extern void __iomem *apll_base;
+
+static struct clk *gpc_dvfs_clk;
+static struct regulator *vpll;
+static struct clk *pll1_sw_clk;
+static struct clk *osc;
+static struct clk *pll1_main_clk;
+static struct clk *ddr_clk ;
+static int dvfs_core_paused;
+
+/* set cpu low power mode before WFI instruction */
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+ u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+ u32 empgc0, empgc1;
+ int stop_mode = 0;
+
+ /* always allow platform to issue a deep sleep mode request */
+ plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+ ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ case STOP_POWER_OFF:
+ plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+ | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+ if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ stop_mode = 0;
+ } else {
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ stop_mode = 1;
+ }
+ arm_srpgcr |= MXC_SRPGCR_PCR;
+
+ if (tzic_enable_wake(1) != 0)
+ return;
+ break;
+ case STOP_POWER_ON:
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ return;
+ }
+
+ __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+ /* Enable NEON SRPG for all but MX50TO1.0. */
+ if (mx50_revision() != IMX_CHIP_REVISION_1_0)
+ __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+
+ if (stop_mode) {
+ empgc0 |= MXC_SRPGCR_PCR;
+ empgc1 |= MXC_SRPGCR_PCR;
+
+ __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+ }
+}
+
+/* To change the idle power mode, need to set arch_idle_mode to a different
+ * power mode as in enum mxc_cpu_pwr_mode.
+ * May allow dynamically changing the idle mode.
+ */
+static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF;
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ if (likely(!mxc_jtag_enabled)) {
+ if (ddr_clk == NULL)
+ ddr_clk = clk_get(NULL, "ddr_clk");
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+ /* gpc clock is needed for SRPG */
+ clk_enable(gpc_dvfs_clk);
+ mxc_cpu_lp_set(arch_idle_mode);
+
+ if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) {
+ memcpy(wait_in_iram_base, mx50_wait, SZ_4K);
+ wait_in_iram = (void *)wait_in_iram_base;
+ if (low_bus_freq_mode) {
+ u32 reg, cpu_podf;
+
+ reg = __raw_readl(apll_base + 0x50);
+ reg = 0x120490;
+ __raw_writel(reg, apll_base + 0x50);
+ reg = __raw_readl(apll_base + 0x80);
+ reg |= 1;
+ __raw_writel(reg, apll_base + 0x80);
+
+ /* Move ARM to be sourced from 24MHz XTAL.
+ * when ARM is in WFI.
+ */
+ if (pll1_sw_clk == NULL)
+ pll1_sw_clk = clk_get(NULL,
+ "pll1_sw_clk");
+ if (osc == NULL)
+ osc = clk_get(NULL, "lp_apm");
+ if (pll1_main_clk == NULL)
+ pll1_main_clk = clk_get(NULL,
+ "pll1_main_clk");
+
+ clk_set_parent(pll1_sw_clk, osc);
+ /* Set the ARM-PODF divider to 1. */
+ cpu_podf = __raw_readl(MXC_CCM_CACRR);
+ __raw_writel(0x01, MXC_CCM_CACRR);
+
+ wait_in_iram(ccm_base, databahn_base);
+
+ /* Set the ARM-POD divider back
+ * to the original.
+ */
+ __raw_writel(cpu_podf, MXC_CCM_CACRR);
+ clk_set_parent(pll1_sw_clk, pll1_main_clk);
+ } else
+ wait_in_iram(ccm_base, databahn_base);
+ } else
+ cpu_do_idle();
+ clk_disable(gpc_dvfs_clk);
+ clk_put(ddr_clk);
+ }
+}
+
+static int __mxs_reset_block(void __iomem *hwreg, int just_enable)
+{
+ u32 c;
+ int timeout;
+
+ /* the process of software reset of IP block is done
+ in several steps:
+
+ - clear SFTRST and wait for block is enabled;
+ - clear clock gating (CLKGATE bit);
+ - set the SFTRST again and wait for block is in reset;
+ - clear SFTRST and wait for reset completion.
+ */
+ c = __raw_readl(hwreg);
+ c &= ~(1 << 31); /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1 << 31)) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when enabling\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1 << 30); /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+
+ if (!just_enable) {
+ c = __raw_readl(hwreg);
+ c |= (1 << 31); /* now again set SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* poll until CLKGATE set */
+ if (__raw_readl(hwreg) & (1 << 30))
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when resetting\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1 << 31); /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1 << 31)) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when enabling "
+ "after reset\n", __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~(1 << 30); /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+ }
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & (1 << 30)) == 0)
+ break;
+
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when unclockgating\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ return 0;
+}
+
+int mxs_reset_block(void __iomem *hwreg, int just_enable)
+{
+ int try = 10;
+ int r;
+
+ while (try--) {
+ r = __mxs_reset_block(hwreg, just_enable);
+ if (!r)
+ break;
+ pr_debug("%s: try %d failed\n", __func__, 10 - try);
+ }
+ return r;
+}
diff --git a/arch/arm/mach-mx5/usb.h b/arch/arm/mach-mx5/usb.h
new file mode 100755
index 00000000..c059f740
--- /dev/null
+++ b/arch/arm/mach-mx5/usb.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <mach/common.h>
+#include "devices.h"
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_utmi_active(void);
+extern void gpio_usbotg_utmi_inactive(void);
+
+extern void __init mx5_usb_dr_init(void);
+extern void __init mx5_usbh1_init(void);
+extern void __init mx5_usbh2_init(void);
+
+typedef void (*driver_vbus_func)(bool);
+extern void mx5_set_host1_vbus_func(driver_vbus_func);
+extern void mx5_set_otghost_vbus_func(driver_vbus_func);
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+extern void __iomem *imx_otg_base;
diff --git a/arch/arm/mach-mx5/usb_dr.c b/arch/arm/mach-mx5/usb_dr.c
new file mode 100755
index 00000000..7f0d9026
--- /dev/null
+++ b/arch/arm/mach-mx5/usb_dr.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include <linux/delay.h>
+#include <asm/mach-types.h>
+#include "usb.h"
+static int usbotg_init_ext(struct platform_device *pdev);
+static void usbotg_uninit_ext(struct platform_device *pdev);
+static void usbotg_clock_gate(bool on);
+
+static struct clk *usb_phy1_clk;
+static struct clk *usb_oh3_clk;
+static struct clk *usb_ahb_clk;
+static void usbotg_wakeup_event_clear(void);
+extern int clk_get_usecount(struct clk *clk);
+
+/* Beginning of Common operation for DR port */
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data dr_utmi_config = {
+ .name = "DR",
+ .init = usbotg_init_ext,
+ .exit = usbotg_uninit_ext,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .transceiver = "utmi",
+};
+
+/* Platform data for wakeup operation */
+static struct fsl_usb2_wakeup_platform_data dr_wakeup_config = {
+ .name = "DR wakeup",
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .usb_wakeup_exhandle = usbotg_wakeup_event_clear,
+};
+/* Notes: configure USB clock*/
+static int usbotg_init_ext(struct platform_device *pdev)
+{
+ struct clk *usb_clk;
+
+ /* the usb_ahb_clk will be enabled in usb_otg_init */
+ usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_enable(usb_clk);
+ usb_phy1_clk = usb_clk;
+
+ return usbotg_init(pdev);
+}
+
+static void usbotg_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ clk_disable(usb_phy1_clk);
+ clk_put(usb_phy1_clk);
+
+ clk_disable(usb_oh3_clk);
+ clk_put(usb_oh3_clk);
+
+ /* usb_ahb_clk will be disabled at usb_common.c */
+ usbotg_uninit(pdata);
+ clk_put(usb_ahb_clk);
+}
+
+/* Below two macros are used at otg mode to indicate usb mode*/
+#define ENABLED_BY_HOST (0x1 << 0)
+#define ENABLED_BY_DEVICE (0x1 << 1)
+static u32 wakeup_irq_enable_src; /* only useful at otg mode */
+static void __wakeup_irq_enable(bool on, int source)
+ {
+ /* otg host and device share the OWIE bit, only when host and device
+ * all enable the wakeup irq, we can enable the OWIE bit
+ */
+ if (on) {
+#ifdef CONFIG_USB_OTG
+ wakeup_irq_enable_src |= source;
+ if (wakeup_irq_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) {
+ USBCTRL |= UCTRL_OWIE;
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_CONF2;
+ }
+#else
+ USBCTRL |= UCTRL_OWIE;
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_CONF2;
+#endif
+ } else {
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CONF2;
+ USBCTRL &= ~UCTRL_OWIE;
+ wakeup_irq_enable_src &= ~source;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static u32 low_power_enable_src; /* only useful at otg mode */
+static void __phy_lowpower_suspend(bool enable, int source)
+{
+ if (enable) {
+ low_power_enable_src |= source;
+#ifdef CONFIG_USB_OTG
+ if (low_power_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) {
+ pr_debug("phy lowpower enabled\n");
+ UOG_PORTSC1 |= PORTSC_PHCD;
+ }
+#else
+ UOG_PORTSC1 |= PORTSC_PHCD;
+#endif
+ } else {
+ pr_debug("phy lowpower disable\n");
+ UOG_PORTSC1 &= ~PORTSC_PHCD;
+ low_power_enable_src &= ~source;
+ }
+}
+
+static void usbotg_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_ahb_clk);
+ clk_enable(usb_oh3_clk);
+ clk_enable(usb_phy1_clk);
+ } else {
+ clk_disable(usb_phy1_clk);
+ clk_disable(usb_oh3_clk);
+ clk_disable(usb_ahb_clk);
+ }
+ pr_debug("usb_ahb_ref_count:%d, usb_phy_clk1_ref_count:%d\n", clk_get_usecount(usb_ahb_clk), clk_get_usecount(usb_phy1_clk));
+}
+
+void mx5_set_otghost_vbus_func(driver_vbus_func driver_vbus)
+{
+ dr_utmi_config.platform_driver_vbus = driver_vbus;
+}
+
+/* The wakeup operation for DR port, it will clear the wakeup irq status
+ * and re-enable the wakeup
+ */
+static void usbotg_wakeup_event_clear(void)
+{
+ int wakeup_req = USBCTRL & UCTRL_OWIR;
+
+ if (wakeup_req != 0) {
+ printk(KERN_INFO "Unknown wakeup.(OTGSC 0x%x)\n", UOG_OTGSC);
+ /* Disable OWIE to clear OWIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USBCTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USBCTRL |= UCTRL_OWIE;
+ }
+}
+/* End of Common operation for DR port */
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+/* Beginning of host related operation for DR port */
+static void _host_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __wakeup_irq_enable(enable, ENABLED_BY_HOST);
+ /* host only care the ID change wakeup event */
+ if (enable) {
+ pr_debug("host wakeup enable\n");
+ USBCTRL_HOST2 |= UCTRL_H2OIDWK_EN;
+ } else {
+ pr_debug("host wakeup disable\n");
+ USBCTRL_HOST2 &= ~UCTRL_H2OIDWK_EN;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __phy_lowpower_suspend(enable, ENABLED_BY_HOST);
+}
+
+static enum usb_wakeup_event _is_host_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USBCTRL & UCTRL_OWIR;
+ u32 otgsc = UOG_OTGSC;
+
+ /* if ID change sts, it is a host wakeup event */
+ if (wakeup_req && (otgsc & OTGSC_IS_USB_ID)) {
+ printk(KERN_INFO "otg host ID wakeup\n");
+ /* if host ID wakeup, we must clear the b session change sts */
+ UOG_OTGSC = otgsc & (~OTGSC_IS_USB_ID);
+ return WAKEUP_EVENT_ID;
+ }
+ if (wakeup_req && (!(otgsc & OTGSC_STS_USB_ID))) {
+ printk(KERN_INFO "otg host Remote wakeup\n");
+ return WAKEUP_EVENT_DPDM;
+ }
+
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _host_wakeup_enable(pdata, false);
+ _host_phy_lowpower_suspend(pdata, false);
+}
+/* End of host related operation for DR port */
+#endif /* CONFIG_USB_EHCI_ARC_OTG */
+
+
+#ifdef CONFIG_USB_GADGET_ARC
+/* Beginning of device related operation for DR port */
+static void _device_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __wakeup_irq_enable(enable, ENABLED_BY_DEVICE);
+ /* if udc is not used by any gadget, we can not enable the vbus wakeup */
+ if (!pdata->port_enables) {
+ USBCTRL_HOST2 &= ~UCTRL_H2OVBWK_EN;
+ return;
+ }
+ if (enable) {
+ pr_debug("device wakeup enable\n");
+ USBCTRL_HOST2 |= UCTRL_H2OVBWK_EN;
+ } else {
+ pr_debug("device wakeup disable\n");
+ USBCTRL_HOST2 &= ~UCTRL_H2OVBWK_EN;
+ }
+}
+
+static void _device_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __phy_lowpower_suspend(enable, ENABLED_BY_DEVICE);
+}
+
+static enum usb_wakeup_event _is_device_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ int wakeup_req = USBCTRL & UCTRL_OWIR;
+
+ pr_debug("the otgsc is 0x%x, usbsts is 0x%x, portsc is 0x%x, wakeup_irq is 0x%x\n", UOG_OTGSC, UOG_USBSTS, UOG_PORTSC1, wakeup_req);
+
+ /* if ID=1, it is a device wakeup event */
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && (UOG_USBSTS & USBSTS_URI)) {
+ printk(KERN_INFO "otg udc wakeup, host sends reset signal\n");
+ return WAKEUP_EVENT_DPDM;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && \
+ ((UOG_USBSTS & USBSTS_PCI) || (UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME))) {
+ /*
+ * When the line state from J to K, the Port Change Detect bit
+ * in the USBSTS register is also set to '1'.
+ */
+ printk(KERN_INFO "otg udc wakeup, host sends resume signal\n");
+ return WAKEUP_EVENT_DPDM;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && (UOG_OTGSC & OTGSC_STS_A_VBUS_VALID) \
+ && (UOG_OTGSC & OTGSC_IS_B_SESSION_VALID)) {
+ printk(KERN_INFO "otg udc vbus rising wakeup\n");
+ return WAKEUP_EVENT_VBUS;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && !(UOG_OTGSC & OTGSC_STS_A_VBUS_VALID)) {
+ printk(KERN_INFO "otg udc vbus falling wakeup\n");
+ return WAKEUP_EVENT_VBUS;
+ }
+
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void device_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _device_wakeup_enable(pdata, false);
+ _device_phy_lowpower_suspend(pdata, false);
+}
+
+/* end of device related operation for DR port */
+#endif /* CONFIG_USB_GADGET_ARC */
+
+#define MX53_OFFSET 0x20000000
+
+void __init mx5_usb_dr_init(void)
+{
+ int ret = 0;
+#ifdef CONFIG_USB_OTG
+ if (cpu_is_mx53() || cpu_is_mx50()) {
+ mxc_usbdr_otg_device.resource[0].start -= MX53_OFFSET;
+ mxc_usbdr_otg_device.resource[0].end -= MX53_OFFSET;
+ }
+ /* wake_up_enalbe is useless, just for usb_register_remote_wakeup execution*/
+ dr_utmi_config.wake_up_enable = _device_wakeup_enable;
+ dr_utmi_config.operating_mode = FSL_USB2_DR_OTG;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ ret |= platform_device_add_data(&mxc_usbdr_otg_device, &dr_utmi_config, sizeof(dr_utmi_config));
+ if (!machine_is_mx53_loco()) {
+ ret |= platform_device_register(&mxc_usbdr_otg_device);
+ }
+ dr_wakeup_config.usb_pdata[0] = mxc_usbdr_otg_device.dev.platform_data;
+#endif
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ if (cpu_is_mx53() || cpu_is_mx50()) {
+ mxc_usbdr_host_device.resource[0].start -= MX53_OFFSET;
+ mxc_usbdr_host_device.resource[0].end -= MX53_OFFSET;
+ }
+ dr_utmi_config.operating_mode = DR_HOST_MODE;
+ dr_utmi_config.wake_up_enable = _host_wakeup_enable;
+ dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_host_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = host_wakeup_handler;
+ ret |= platform_device_add_data(&mxc_usbdr_host_device, &dr_utmi_config, sizeof(dr_utmi_config));
+ ret |= platform_device_register(&mxc_usbdr_host_device);
+ dr_wakeup_config.usb_pdata[1] = mxc_usbdr_host_device.dev.platform_data;
+#endif
+#ifdef CONFIG_USB_GADGET_ARC
+ if (cpu_is_mx53() || cpu_is_mx50()) {
+ mxc_usbdr_udc_device.resource[0].start -= MX53_OFFSET;
+ mxc_usbdr_udc_device.resource[0].end -= MX53_OFFSET;
+ }
+ dr_utmi_config.operating_mode = DR_UDC_MODE;
+ dr_utmi_config.wake_up_enable = _device_wakeup_enable;
+ dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_device_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = device_wakeup_handler;
+ ret |= platform_device_add_data(&mxc_usbdr_udc_device, &dr_utmi_config, sizeof(dr_utmi_config));
+ ret |= platform_device_register(&mxc_usbdr_udc_device);
+ dr_wakeup_config.usb_pdata[2] = mxc_usbdr_udc_device.dev.platform_data;
+#endif
+ ret |= mxc_register_device(&mxc_usbdr_wakeup_device, &dr_wakeup_config);
+ if (ret)
+ printk(KERN_ERR "%s(%d): error occures while init usb dr \n", __func__, __LINE__);
+}
diff --git a/arch/arm/mach-mx5/usb_h1.c b/arch/arm/mach-mx5/usb_h1.c
new file mode 100755
index 00000000..e291fb7b
--- /dev/null
+++ b/arch/arm/mach-mx5/usb_h1.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+
+#include <asm/delay.h>
+#include <mach/arc_otg.h>
+#include <mach/iomux-mx51.h>
+#include <mach/iomux-mx53.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "usb.h"
+
+static struct clk *usb_phy2_clk;
+static struct clk *usb_oh3_clk;
+static struct clk *usb_ahb_clk;
+extern int clk_get_usecount(struct clk *clk);
+
+#define MX5X_USBH1_STP IMX_GPIO_NR(1, 27)
+#define MX51_3DS_PHY_RESET IMX_GPIO_NR(2, 5)
+
+/*
+ * USB Host1 HS port
+ */
+static int gpio_usbh1_active(void)
+{
+ iomux_v3_cfg_t usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO1_27;
+ iomux_v3_cfg_t phyreset_gpio = MX51_PAD_EIM_D17__GPIO2_1;
+ int ret;
+
+ /* Set USBH1_STP to GPIO and toggle it */
+ mxc_iomux_v3_setup_pad(usbh1stp_gpio);
+ ret = gpio_request(MX5X_USBH1_STP, "usbh1_stp");
+
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_USBH1_STP__GPIO_1_27: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(MX5X_USBH1_STP, 0);
+ gpio_set_value(MX5X_USBH1_STP, 1);
+
+ /* Signal only used on MX51-3DS for reset to PHY.*/
+ if (machine_is_mx51_3ds()) {
+ mxc_iomux_v3_setup_pad(phyreset_gpio);
+ ret = gpio_request(MX51_3DS_PHY_RESET, "eim_d17");
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_EIM_D17__GPIO2_1: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(MX51_3DS_PHY_RESET, 0);
+ gpio_set_value(MX51_3DS_PHY_RESET, 1);
+ }
+
+ msleep(100);
+
+ return 0;
+}
+
+static void gpio_usbh1_inactive(void)
+{
+ /* Signal only used on MX51-3DS for reset to PHY.*/
+ if (machine_is_mx51_3ds()) {
+ gpio_free(MX51_3DS_PHY_RESET);
+ }
+ gpio_free(MX5X_USBH1_STP);
+}
+
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host1, %s, enable is %d\n", __func__, enable);
+ if (enable)
+ USBCTRL |= UCTRL_H1WIE;
+ else {
+ USBCTRL &= ~UCTRL_H1WIE;
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host1, %s, enable is %d\n", __func__, enable);
+ if (enable) {
+ UH1_PORTSC1 |= PORTSC_PHCD;
+ } else {
+ UH1_PORTSC1 &= ~PORTSC_PHCD;
+ }
+}
+
+static void usbh1_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_ahb_clk);
+ clk_enable(usb_oh3_clk);
+ clk_enable(usb_phy2_clk);
+ } else {
+ clk_disable(usb_phy2_clk);
+ clk_disable(usb_oh3_clk);
+ clk_disable(usb_ahb_clk);
+ }
+}
+
+static enum usb_wakeup_event _is_usbh1_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ int wakeup_req = USBCTRL & UCTRL_H1WIR;
+
+ if (wakeup_req)
+ return WAKEUP_EVENT_DPDM;
+
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void h1_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _wake_up_enable(pdata, false);
+ _phy_lowpower_suspend(pdata, false);
+}
+
+static void usbh1_wakeup_event_clear(void)
+{
+ int wakeup_req = USBCTRL & UCTRL_H1WIR;
+
+ if (wakeup_req != 0) {
+ printk(KERN_INFO "Unknown wakeup.(OTGSC 0x%x)\n", UOG_OTGSC);
+ /* Disable H1WIE to clear H1WIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USBCTRL &= ~UCTRL_H1WIE;
+ udelay(100);
+ USBCTRL |= UCTRL_H1WIE;
+ }
+}
+static int fsl_usb_host_init_ext(struct platform_device *pdev)
+{
+ int ret;
+ struct clk *usb_clk;
+
+ /* the usb_ahb_clk will be enabled in usb_otg_init */
+ usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
+
+ if (cpu_is_mx53()) {
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy2_clk");
+ clk_enable(usb_clk);
+ usb_phy2_clk = usb_clk;
+ } else if (cpu_is_mx50()) {
+ usb_clk = clk_get(NULL, "usb_phy2_clk");
+ clk_enable(usb_clk);
+ usb_phy2_clk = usb_clk;
+ } else if (cpu_is_mx51()) {
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+ }
+
+ ret = fsl_usb_host_init(pdev);
+ if (ret)
+ return ret;
+
+ if (cpu_is_mx51()) {
+ /* setback USBH1_STP to be function */
+#if 0 /* Jasper: Need to do... */
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+ gpio_free(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP));
+#endif
+ }
+
+ /* disable remote wakeup irq */
+ USBCTRL &= ~UCTRL_H1WIE;
+ return 0;
+}
+
+static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ if (cpu_is_mx53()) {
+ clk_disable(usb_oh3_clk);
+ clk_put(usb_oh3_clk);
+
+ clk_disable(usb_phy2_clk);
+ clk_put(usb_phy2_clk);
+ } else if (cpu_is_mx50()) {
+ clk_disable(usb_phy2_clk);
+ clk_put(usb_phy2_clk);
+ } else if (cpu_is_mx51()) {
+ clk_disable(usb_oh3_clk);
+ clk_put(usb_oh3_clk);
+ }
+
+ fsl_usb_host_uninit(pdata);
+ /* usb_ahb_clk will be disabled at usb_common.c */
+ clk_put(usb_ahb_clk);
+}
+
+static struct fsl_usb2_platform_data usbh1_config = {
+ .name = "Host 1",
+ .init = fsl_usb_host_init_ext,
+ .exit = fsl_usb_host_uninit_ext,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = usbh1_clock_gate,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
+ .is_wakeup_event = _is_usbh1_wakeup,
+ .wakeup_handler = h1_wakeup_handler,
+ .transceiver = "utmi",
+};
+static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = {
+ .name = "USBH1 wakeup",
+ .usb_clock_for_pm = usbh1_clock_gate,
+ .usb_pdata = {&usbh1_config, NULL, NULL},
+ .usb_wakeup_exhandle = usbh1_wakeup_event_clear,
+};
+
+void mx5_set_host1_vbus_func(driver_vbus_func driver_vbus)
+{
+ usbh1_config.platform_driver_vbus = driver_vbus;
+}
+
+#define MX53_OFFSET 0x20000000
+void __init mx5_usbh1_init(void)
+{
+ if (cpu_is_mx51()) {
+ usbh1_config.phy_mode = FSL_USB2_PHY_ULPI;
+ usbh1_config.transceiver = "isp1504";
+ usbh1_config.gpio_usb_active = gpio_usbh1_active;
+ usbh1_config.gpio_usb_inactive = gpio_usbh1_inactive;
+ }
+ if (cpu_is_mx53() || cpu_is_mx50()) {
+ mxc_usbh1_device.resource[0].start -= MX53_OFFSET;
+ mxc_usbh1_device.resource[0].end -= MX53_OFFSET;
+ }
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+ usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
+ mxc_register_device(&mxc_usbh1_wakeup_device, &usbh1_wakeup_config);
+}
+
diff --git a/arch/arm/mach-mx5/usb_h2.c b/arch/arm/mach-mx5/usb_h2.c
new file mode 100755
index 00000000..1f7d0a70
--- /dev/null
+++ b/arch/arm/mach-mx5/usb_h2.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+
+#include <mach/arc_otg.h>
+#include <mach/iomux-mx51.h>
+#include <mach/iomux-mx53.h>
+#include "usb.h"
+
+#define MX5X_USBH2_STP IMX_GPIO_NR(2, 20)
+
+/*
+ * USB Host2 HS port
+ */
+static int gpio_usbh2_active(void)
+{
+ iomux_v3_cfg_t usbh2stp_gpio = MX51_PAD_EIM_A26__GPIO2_20;
+ int ret = 0;
+
+ /* Set USBH2_STP to GPIO and toggle it */
+ mxc_iomux_v3_setup_pad(usbh2stp_gpio);
+ ret = gpio_request(MX5X_USBH2_STP, "eim_a26");
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_EIM_A26__GPIO2_20: %d\n", ret);
+ return ret;
+ }
+
+ gpio_direction_output(MX5X_USBH2_STP, 0);
+ gpio_set_value(MX5X_USBH2_STP, 1);
+ msleep(100);
+
+ return 0;
+}
+
+static void gpio_usbh2_inactive(void)
+{
+ gpio_free(MX5X_USBH2_STP);
+}
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ printk(KERN_DEBUG "host2, %s, enable is %d\n", __func__, enable);
+ if (enable)
+ USBCTRL_HOST2 |= UCTRL_H2WIE;
+ else {
+ USBCTRL_HOST2 &= ~UCTRL_H2WIE;
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ printk(KERN_DEBUG "host2, %s, enable is %d\n", __func__, enable);
+ if (enable) {
+ UH2_PORTSC1 |= PORTSC_PHCD;
+ } else {
+ UH2_PORTSC1 &= ~PORTSC_PHCD;
+ }
+}
+
+static void fsl_usbh2_clock_gate(bool on)
+{
+ struct clk *usb_clk;
+ if (on) {
+ usb_clk = clk_get(NULL, "usb_ahb_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+ } else {
+ usb_clk = clk_get(NULL, "usb_ahb_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+ }
+}
+
+static enum usb_wakeup_event _is_usbh2_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ int wakeup_req = USBCTRL & UCTRL_H2WIR;
+
+ if (wakeup_req)
+ return WAKEUP_EVENT_DPDM;
+
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void h2_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _wake_up_enable(pdata, false);
+ _phy_lowpower_suspend(pdata, false);
+}
+
+static void usbh2_wakeup_event_clear(void)
+{
+ int wakeup_req = USBCTRL & UCTRL_H2WIR;
+
+ if (wakeup_req != 0) {
+ printk(KERN_INFO "Unknown wakeup.(OTGSC 0x%x)\n", UOG_OTGSC);
+ /* Disable H2WIE to clear H2WIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USBCTRL &= ~UCTRL_H2WIE;
+ udelay(100);
+ USBCTRL |= UCTRL_H2WIE;
+ }
+}
+static int fsl_usb_host_init_ext(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ /* on mx53, there is a hardware limitation that when switch the host2's clk mode
+ * ,usb phy1 clk must be on, after finish switching this clk can be off */
+ if (cpu_is_mx53()) {
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+ }
+
+ ret = fsl_usb_host_init(pdev);
+
+ if (cpu_is_mx53()) {
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+ }
+
+ /* setback USBH2_STP to be function */
+ mxc_iomux_v3_setup_pad(MX51_PAD_EIM_A26__USBH2_STP);
+
+ return ret;
+}
+
+static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ fsl_usb_host_uninit(pdata);
+}
+
+static struct fsl_usb2_platform_data usbh2_config = {
+ .name = "Host 2",
+ .init = fsl_usb_host_init_ext,
+ .exit = fsl_usb_host_uninit_ext,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = fsl_usbh2_clock_gate,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
+ .gpio_usb_active = gpio_usbh2_active,
+ .gpio_usb_inactive = gpio_usbh2_inactive,
+ .is_wakeup_event = _is_usbh2_wakeup,
+ .wakeup_handler = h2_wakeup_handler,
+ .transceiver = "isp1504",
+};
+static struct fsl_usb2_wakeup_platform_data usbh2_wakeup_config = {
+ .name = "USBH2 wakeup",
+ .usb_clock_for_pm = fsl_usbh2_clock_gate,
+ .usb_pdata = {&usbh2_config, NULL, NULL},
+ .usb_wakeup_exhandle = usbh2_wakeup_event_clear,
+};
+
+#define MX53_OFFSET 0x20000000
+void __init mx5_usbh2_init(void)
+{
+ if (cpu_is_mx53() || cpu_is_mx50()) {
+ mxc_usbh2_device.resource[0].start -= MX53_OFFSET;
+ mxc_usbh2_device.resource[0].end -= MX53_OFFSET;
+ }
+ usbh2_config.wakeup_pdata = &usbh2_wakeup_config;
+ mxc_register_device(&mxc_usbh2_device, &usbh2_config);
+ mxc_register_device(&mxc_usbh2_wakeup_device, &usbh2_wakeup_config);
+}
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
new file mode 100644
index 00000000..a8dc8bc1
--- /dev/null
+++ b/arch/arm/mach-mx6/Kconfig
@@ -0,0 +1,382 @@
+if ARCH_MX6
+
+config ARCH_MX6Q
+ bool
+ select USB_ARCH_HAS_EHCI
+ select ARCH_MXC_IOMUX_V3
+ select ARCH_MXC_AUDMUX_V2
+ select ARCH_SUPPORTS_MSI
+ select ARM_GIC
+ select ARCH_HAS_CPUFREQ
+ select OC_ETM
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_IMX_IPUV3
+ select IMX_HAVE_PLATFORM_MXC_PWM
+ select IMX_HAVE_PLATFORM_LDB
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_IMX_VDOA
+
+config FORCE_MAX_ZONEORDER
+ int "MAX_ORDER"
+ default "13"
+
+config SOC_IMX6Q
+ bool
+
+config SOC_IMX6SL
+ bool
+
+config MACH_MX6Q_ARM2
+ bool "Support i.MX 6Quad Armadillo2 platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_ESAI
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_IMX_MIPI_DSI
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_MXC_MLB
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+# select IMX_HAVE_PLATFORM_IMX_ELCDIF
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_PCIE
+ select IMX_HAVE_PLATFORM_IMX_CAAM
+ help
+ Include support for i.MX 6Quad Armadillo2 platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6SL_ARM2
+ bool "Support i.MX 6SoloLite Armadillo2 platform"
+ select ARCH_MX6Q
+ select SOC_IMX6SL
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+ select IMX_HAVE_PLATFORM_IMX_SPDC
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_DCP
+ select IMX_HAVE_PLATFORM_RANDOM_RNGC
+ select ARCH_HAS_RNGC
+ help
+ Include support for i.MX 6Sololite Armadillo2 platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6SL_EVK
+ bool "Support i.MX 6SoloLite EVK platform"
+ select ARCH_MX6Q
+ select SOC_IMX6SL
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+ select IMX_HAVE_PLATFORM_IMX_SPDC
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_FSL_CSI
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_DCP
+ select IMX_HAVE_PLATFORM_RANDOM_RNGC
+ select ARCH_HAS_RNGC
+ help
+ Include support for i.MX 6Sololite EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6SL_NTX
+ bool "Support i.MX 6SoloLite NTX platform"
+ select ARCH_MX6Q
+ select SOC_IMX6SL
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_PERFMON
+ select IMX_HAVE_PLATFORM_IMX_EPDC
+ select IMX_HAVE_PLATFORM_IMX_SPDC
+ select IMX_HAVE_PLATFORM_IMX_PXP
+ select IMX_HAVE_PLATFORM_IMX_FSL_CSI
+ select IMX_HAVE_PLATFORM_IMX_KEYPAD
+ select IMX_HAVE_PLATFORM_IMX_DCP
+ select IMX_HAVE_PLATFORM_RANDOM_RNGC
+ select ARCH_HAS_RNGC
+ help
+ Include support for i.MX 6Sololite NTX platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6Q_SABRELITE
+ bool "Support i.MX 6Quad SABRE Lite platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_IMX_CAAM
+ help
+ Include support for i.MX 6Quad SABRE Lite platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6Q_SABRESD
+ bool "Support i.MX 6Quad SABRESD platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_SSI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_IMX_PCIE
+ select IMX_HAVE_PLATFORM_IMX_CAAM
+ help
+ Include support for i.MX 6Quad SABRE SD platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6Q_SABREAUTO
+ bool "Support i.MX 6Quad SABRE Auto platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_ESAI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_IMX_MIPI_DSI
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ select IMX_HAVE_PLATFORM_IMX_PCIE
+ select IMX_HAVE_PLATFORM_IMX_CAAM
+ help
+ Include support for i.MX 6Quad SABRE Auto platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX6Q_HDMIDONGLE
+ bool "Support i.MX 6Quad HDMIDONGLE platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_PCIE
+ help
+ Include support for i.MX 6Quad HDMI Dongle platform. This includes specific
+ configurations for the board and its peripherals.
+
+comment "MX6 Options:"
+
+config IMX_PCIE
+ bool "PCI Express support"
+ select PCI
+
+config IMX_PCIE_EP_MODE_IN_EP_RC_SYS
+ bool "PCI Express EP mode in the IMX6 RC/EP interconnection system"
+ depends on IMX_PCIE
+
+config IMX_PCIE_RC_MODE_IN_EP_RC_SYS
+ bool "PCI Express RC mode in the IMX6 RC/EP interconnection system"
+ depends on IMX_PCIE
+
+config USB_EHCI_ARC_H1
+ tristate "USB Host 1 support"
+ depends on USB_EHCI_ARC
+
+config USB_FSL_ARC_OTG
+ tristate "FSL USB OTG support"
+
+config USB_ID_WAKEUP_ENABLE
+ bool "Enable USB ID Pin As System Wakeup Source"
+ depends on SOC_IMX6SL
+ default n
+
+config MX6_INTER_LDO_BYPASS
+ bool "Internal LDO in MX6Q/DL bypass"
+ depends on REGULATOR_PFUZE100 && CPU_FREQ_IMX && ARCH_MX6
+ default n
+ help
+ This is choosed for bypass internal LDO in MX6. If choose it, internal
+ LDO will replaced by external pmic regulator(e.g. pfuze100), VDDCORE
+ can be adjust automatically adjust by cpu frequency.
+
+config MX6_CLK_FOR_BOOTUI_TRANS
+ bool "MX6 clk setting for smooth UI transtion from bootloader to kernel"
+ depends on MXC_IPU_V3H
+ default n
+ help
+ This is choosed to keep enable IPU related clocks and PWM clocks and
+ avoid setting IPU related clocks' parents when initializing clock tree
+ so that bootloader splashimage can transition to kernel smoothly.
+
+
+config MX6_ENET_IRQ_TO_GPIO
+ bool "Route ENET interrupts to GPIO"
+ default n
+ help
+ Enabling this will direct all the ENET interrupts to a board specific GPIO.
+ This will allow the system to enter WAIT mode when ENET is active.
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA data structures"
+ depends on IMX_SDMA && SOC_IMX6SL
+ help
+ SDMA buffer or control structures are stored in the IRAM/OCRAM
+
+
+endif
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
new file mode 100644
index 00000000..14fbbde2
--- /dev/null
+++ b/arch/arm/mach-mx6/Makefile
@@ -0,0 +1,25 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_h2.o usb_h3.o\
+pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \
+mx6_mmdc.o mx6_ddr_freq.o mx6sl_ddr.o mx6sl_wfi.o etm.o
+
+obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o
+obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o
+obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o
+obj-$(CONFIG_MACH_MX6SL_EVK) += board-mx6sl_evk.o mx6sl_evk_pmic_pfuze100.o
+obj-$(CONFIG_MACH_MX6SL_NTX) += board-mx6sl_ntx.o mx6sl_ntx_pmic_pfuze100.o mx6sl_ntx_io.o
+obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o
+obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze100.o
+obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o
+obj-$(CONFIG_MACH_MX6Q_HDMIDONGLE) += board-mx6q_hdmidongle.o
+obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_IMX_PCIE) += pcie.o
+obj-$(CONFIG_USB_FSL_ARC_OTG) += usb_dr.o
+obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o
+obj-$(CONFIG_PCI_MSI) += msi.o
+
diff --git a/arch/arm/mach-mx6/Makefile.boot b/arch/arm/mach-mx6/Makefile.boot
new file mode 100644
index 00000000..dc006a84
--- /dev/null
+++ b/arch/arm/mach-mx6/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-$(CONFIG_ARCH_MX6Q) := 0x10008000
+params_phys-$(CONFIG_ARCH_MX6Q) := 0x10000100
+initrd_phys-$(CONFIG_ARCH_MX6Q) := 0x10800000
diff --git a/arch/arm/mach-mx6/board-mx6dl_arm2.h b/arch/arm/mach-mx6/board-mx6dl_arm2.h
new file mode 100644
index 00000000..dd7e6658
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6dl_arm2.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6dl.h>
+
+static iomux_v3_cfg_t mx6dl_arm2_pads[] = {
+
+ /* UART4 for debug */
+ MX6DL_PAD_KEY_COL0__UART4_TXD,
+ MX6DL_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6DL_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6DL_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6DL_PAD_KEY_COL1__ENET_MDIO,
+ MX6DL_PAD_KEY_COL2__ENET_MDC,
+ MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+#ifdef CONFIG_FEC_1588
+ MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#endif
+#endif
+ /* MCLK for csi0 */
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ MX6DL_PAD_GPIO_3__CCM_CLKO2,
+
+ /* SD1 */
+ MX6DL_PAD_SD1_CLK__USDHC1_CLK,
+ MX6DL_PAD_SD1_CMD__USDHC1_CMD,
+ MX6DL_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6DL_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6DL_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6DL_PAD_SD1_DAT3__USDHC1_DAT3,
+ /* SD2 */
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+ /* SD3 */
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6DL_PAD_SD3_RST__USDHC3_RST,
+ /* SD3 VSelect */
+ MX6DL_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6DL_PAD_NANDF_CS0__GPIO_6_11,
+ MX6DL_PAD_NANDF_CS1__GPIO_6_14,
+ /* SD4 */
+ MX6DL_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6DL_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+ MX6DL_PAD_NANDF_ALE__USDHC4_RST,
+ /* eCSPI1 */
+ MX6DL_PAD_EIM_EB2__ECSPI1_SS0,
+ MX6DL_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6DL_PAD_EIM_D17__ECSPI1_MISO,
+ MX6DL_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6DL_PAD_EIM_D19__ECSPI1_SS1,
+ MX6DL_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
+ MX6DL_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ESAI */
+ MX6DL_PAD_ENET_RXD0__ESAI1_HCKT,
+ MX6DL_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6DL_PAD_ENET_RXD1__ESAI1_FST,
+ MX6DL_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6DL_PAD_ENET_TXD1__ESAI1_TX2_RX3,
+ MX6DL_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6DL_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6DL_PAD_NANDF_CS2__ESAI1_TX0,
+ MX6DL_PAD_NANDF_CS3__ESAI1_TX1,
+
+ /* I2C1 */
+ MX6DL_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6DL_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6DL_PAD_KEY_COL3__I2C2_SCL,
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* DISPLAY */
+ MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6DL_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6DL_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6DL_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ MX6DL_PAD_EIM_D24__GPIO_3_24,
+
+ /* UART2 */
+ MX6DL_PAD_EIM_D26__UART2_RXD,
+ MX6DL_PAD_EIM_D27__UART2_TXD,
+ MX6DL_PAD_EIM_D28__UART2_RTS,
+ MX6DL_PAD_EIM_D29__UART2_CTS,
+
+ /* PWM1 */
+ MX6DL_PAD_GPIO_9__PWM1_PWMO,
+
+ /* DISP0 DET */
+ MX6DL_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+ MX6DL_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
+ MX6DL_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
+
+ /* USBOTG ID pin */
+ MX6DL_PAD_GPIO_1__USBOTG_ID,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* MLB150 */
+ MX6DL_PAD_GPIO_3__MLB_MLBCLK,
+ MX6DL_PAD_GPIO_6__MLB_MLBSIG,
+ MX6DL_PAD_GPIO_2__MLB_MLBDAT,
+#endif
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_epdc_pads[] = {
+ MX6DL_PAD_EIM_A17__GPIO_2_21,
+ MX6DL_PAD_EIM_D17__GPIO_3_17,
+ MX6DL_PAD_EIM_A18__GPIO_2_20,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_i2c3_pads[] = {
+ MX6DL_PAD_GPIO_5__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_spdif_pads[] = {
+ /* SPDIF */
+ MX6DL_PAD_GPIO_16__SPDIF_IN1,
+ MX6DL_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_can_pads[] = {
+ /* CAN1 */
+ MX6DL_PAD_GPIO_7__CAN1_TXCAN,
+ MX6DL_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6DL_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
+ MX6DL_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
+
+ /* CAN2 */
+ MX6DL_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6DL_PAD_KEY_ROW4__CAN2_RXCAN,
+ MX6DL_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_esai_record_pads[] = {
+ MX6DL_PAD_ENET_RX_ER__ESAI1_HCKR,
+ MX6DL_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6DL_PAD_ENET_REF_CLK__ESAI1_FSR,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_csi0_sensor_pads[] = {
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ /* ipu1 csi0 */
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6DL_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6DL_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_csi0_tvin_pads[] = {
+ /* ipu1 csi0 */
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6DL_PAD_CSI0_DAT7__GPIO_5_25,
+ /* camera powerdown */
+ MX6DL_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_mipi_sensor_pads[] = {
+ MX6DL_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_audmux_pads[] = {
+
+ /* AUDMUX */
+ MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+};
+
+#define MX6DL_USDHC_PAD_SETTING(id, speed) \
+mx6dl_sd##id##_##speed##mhz[] = { \
+ MX6DL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 200);
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6dl_gpmi_nand[] __initdata = {
+ MX6DL_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6DL_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6DL_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6DL_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6DL_PAD_NANDF_D0__RAWNAND_D0,
+ MX6DL_PAD_NANDF_D1__RAWNAND_D1,
+ MX6DL_PAD_NANDF_D2__RAWNAND_D2,
+ MX6DL_PAD_NANDF_D3__RAWNAND_D3,
+ MX6DL_PAD_NANDF_D4__RAWNAND_D4,
+ MX6DL_PAD_NANDF_D5__RAWNAND_D5,
+ MX6DL_PAD_NANDF_D6__RAWNAND_D6,
+ MX6DL_PAD_NANDF_D7__RAWNAND_D7,
+ MX6DL_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6DL_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_hdmi_ddc_pads[] = {
+ MX6DL_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_i2c2_pads[] = {
+ MX6DL_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
diff --git a/arch/arm/mach-mx6/board-mx6dl_hdmidongle.h b/arch/arm/mach-mx6/board-mx6dl_hdmidongle.h
new file mode 100644
index 00000000..b46b6e16
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6dl_hdmidongle.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _BOARD_MX6DL_HDMIDONGLE_H
+#define _BOARD_MX6DL_HDMIDONGLE_H
+#include <mach/iomux-mx6dl.h>
+
+static iomux_v3_cfg_t mx6dl_hdmidongle_rev_a_pads[] = {
+ /* SPI2 for PMIC communication port */
+ MX6DL_PAD_EIM_OE__ECSPI2_MISO,
+ MX6DL_PAD_EIM_RW__ECSPI2_SS0,
+ MX6DL_PAD_EIM_CS0__ECSPI2_SCLK,
+ MX6DL_PAD_EIM_CS1__ECSPI2_MOSI,
+
+ /*USB_OTG_DET(USB OTG cable plug detect) */
+ MX6DL_PAD_EIM_A16__GPIO_2_22,
+ /*BT_WAKEUP_HOST(Combo module BT wake-up output) */
+ MX6DL_PAD_EIM_A25__GPIO_5_2,
+ /* HOST_WAKEUP_BT(CPU wakeup BT signal)*/
+ MX6DL_PAD_EIM_D16__GPIO_3_16,
+
+ /* I2C3 */
+ MX6DL_PAD_EIM_D17__I2C3_SCL,
+ MX6DL_PAD_EIM_D18__I2C3_SDA,
+
+ /* USB OC pin */
+ MX6DL_PAD_EIM_D21__USBOH3_USBOTG_OC,
+ /* WLAN_WAKEUP_HOST(Combo module WLAN host wake-up output) */
+ MX6DL_PAD_EIM_D22__GPIO_3_22,
+
+ /* BT_UART2 */
+ MX6DL_PAD_EIM_D26__UART2_TXD,
+ MX6DL_PAD_EIM_D27__UART2_RXD,
+ MX6DL_PAD_EIM_D28__UART2_CTS,
+ MX6DL_PAD_EIM_D29__UART2_RTS,
+
+ /*BT_nRST(Combo module BT reset signal)*/
+ MX6DL_PAD_EIM_DA7__GPIO_3_7,
+
+ /*BT_REG_ON(Combo module BT Internal regulators power enable/disable)*/
+ MX6DL_PAD_EIM_DA9__GPIO_3_9,
+
+ /*WL_REG_ON(Combo module WLAN Internal regulators power enable/disable)*/
+ MX6DL_PAD_EIM_DA10__GPIO_3_10,
+
+ /* GPIO2 */
+ MX6DL_PAD_EIM_A22__GPIO_2_16, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A21__GPIO_2_17, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A20__GPIO_2_18, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A19__GPIO_2_19, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A18__GPIO_2_20, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A17__GPIO_2_21, /* Boot Mode Select */
+ MX6DL_PAD_EIM_RW__GPIO_2_26, /* Boot Mode Select */
+ MX6DL_PAD_EIM_LBA__GPIO_2_27, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB0__GPIO_2_28, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB1__GPIO_2_29, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB2__GPIO_2_30, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB3__GPIO_2_31, /* Boot Mode Select */
+
+ /* GPIO3 */
+ MX6DL_PAD_EIM_DA0__GPIO_3_0, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA1__GPIO_3_1, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA2__GPIO_3_2, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA3__GPIO_3_3, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA4__GPIO_3_4, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA5__GPIO_3_5, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA6__GPIO_3_6, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA8__GPIO_3_8, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA11__GPIO_3_11, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA12__GPIO_3_12, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA13__GPIO_3_13, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA14__GPIO_3_14, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA15__GPIO_3_15, /* Boot Mode Select */
+
+ /* GPIO5 */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A24__GPIO_5_4, /* Boot Mode Select */
+
+ /* GPIO6 */
+ MX6DL_PAD_EIM_A23__GPIO_6_6, /* Boot Mode Select */
+
+ /* I2C1 */
+ MX6DL_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6DL_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* UART1 for debug */
+ MX6DL_PAD_CSI0_DAT10__UART1_TXD,
+ MX6DL_PAD_CSI0_DAT11__UART1_RXD,
+
+ /* SD1 (Combo module WLAN SDIO )*/
+ MX6DL_PAD_SD1_CLK__USDHC1_CLK,
+ MX6DL_PAD_SD1_CMD__USDHC1_CMD,
+ MX6DL_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6DL_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6DL_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6DL_PAD_SD1_DAT3__USDHC1_DAT3,
+
+ /* SD2 (MicroSD SDIO CMD)*/
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+ /*SD_DET (SD plug-in detect interrupt)*/
+ MX6DL_PAD_GPIO_4__GPIO_1_4,
+
+ /* SD3 (eMMC SDIO)*/
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6DL_PAD_SD3_RST__USDHC3_RST,
+
+ /* UART4 for debug */
+ MX6DL_PAD_KEY_COL0__UART4_TXD,
+ MX6DL_PAD_KEY_ROW0__UART4_RXD,
+
+ /*HDMI CEC communication PIN*/
+ MX6DL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+
+ /* I2C2 */
+ MX6DL_PAD_KEY_COL3__I2C2_SCL, /* GPIO4[12] */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* GPIO4[13] */
+
+ /*DCDC5V_PWREN(5V DCDC BOOST control signal)*/
+ MX6DL_PAD_KEY_COL4__GPIO_4_14,
+
+ /*USB_OTG_PWREN(USB OTG power change control signal)*/
+ MX6DL_PAD_KEY_ROW4__GPIO_4_15,
+
+ /* USBOTG ID pin */
+ MX6DL_PAD_GPIO_1__USBOTG_ID,
+
+ /* I2C3 */
+ MX6DL_PAD_GPIO_5__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA,
+
+ /*WDOG(Watch dog output)*/
+ MX6DL_PAD_GPIO_9__GPIO_1_9,
+
+ /*PMIC_nINT(PMIC interrupt signal)*/
+ MX6DL_PAD_NANDF_CS0__GPIO_6_11,
+
+ /*GPIO_nRST(GPIO shutdown control)*/
+ MX6DL_PAD_NANDF_CS1__GPIO_6_14,
+
+ /*PWRKEY_DET(Power key press detection)*/
+ MX6DL_PAD_NANDF_CS3__GPIO_6_16,
+
+ /*CHG_SYS_ON(Charger auto power on control signal)*/
+ MX6DL_PAD_NANDF_D6__GPIO_2_6,
+
+ /*IR_RC*/
+ MX6DL_PAD_SD4_DAT6__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6dl_hdmidongle_rev_b_pads[] = {
+ /* SPI2 for PMIC communication port */
+ MX6DL_PAD_EIM_OE__ECSPI2_MISO,
+ MX6DL_PAD_EIM_RW__ECSPI2_SS0,
+ MX6DL_PAD_EIM_CS0__ECSPI2_SCLK,
+ MX6DL_PAD_EIM_CS1__ECSPI2_MOSI,
+
+ /*USB_OTG_DET(USB OTG cable plug detect) */
+ MX6DL_PAD_EIM_A16__GPIO_2_22,
+ /*WLAN_CLKREQn*/
+ MX6DL_PAD_EIM_A25__GPIO_5_2,
+
+ /* WLAN_ACT */
+ MX6DL_PAD_EIM_D17__GPIO_3_17,
+
+ /*BT_PERI*/
+ MX6DL_PAD_EIM_D18__GPIO_3_18,
+
+ /* USB OC pin */
+ MX6DL_PAD_EIM_D21__USBOH3_USBOTG_OC,
+
+ /* WLAN_WAKEn (PM event, OD, used to reactivate the PCIe main PWR and REF CLK) */
+ MX6DL_PAD_EIM_D22__GPIO_3_22,
+
+
+ /*WLAN_PERSTn (PCIe rst signal, avtive LOW)*/
+ MX6DL_PAD_EIM_DA9__GPIO_3_9,
+
+ /*WLAN_PDn (Externally shutdown RTL8192)*/
+ MX6DL_PAD_EIM_DA10__GPIO_3_10,
+
+ /* GPIO2 */
+ MX6DL_PAD_EIM_A22__GPIO_2_16, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A21__GPIO_2_17, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A20__GPIO_2_18, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A19__GPIO_2_19, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A18__GPIO_2_20, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A17__GPIO_2_21, /* Boot Mode Select */
+ MX6DL_PAD_EIM_RW__GPIO_2_26, /* Boot Mode Select */
+ MX6DL_PAD_EIM_LBA__GPIO_2_27, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB0__GPIO_2_28, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB1__GPIO_2_29, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB2__GPIO_2_30, /* Boot Mode Select */
+ MX6DL_PAD_EIM_EB3__GPIO_2_31, /* Boot Mode Select */
+
+ /* GPIO3 */
+ MX6DL_PAD_EIM_DA0__GPIO_3_0, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA1__GPIO_3_1, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA2__GPIO_3_2, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA3__GPIO_3_3, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA4__GPIO_3_4, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA5__GPIO_3_5, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA6__GPIO_3_6, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA8__GPIO_3_8, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA11__GPIO_3_11, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA12__GPIO_3_12, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA13__GPIO_3_13, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA14__GPIO_3_14, /* Boot Mode Select */
+ MX6DL_PAD_EIM_DA15__GPIO_3_15, /* Boot Mode Select */
+
+ /* GPIO5 */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0, /* Boot Mode Select */
+ MX6DL_PAD_EIM_A24__GPIO_5_4, /* Boot Mode Select */
+
+ /* GPIO6 */
+ MX6DL_PAD_EIM_A23__GPIO_6_6, /* Boot Mode Select */
+
+ /* SD2 (MicroSD SDIO CMD)*/
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+ /*SD_DET (SD plug-in detect interrupt)*/
+ MX6DL_PAD_GPIO_4__GPIO_1_4,
+
+ /* SD3 (eMMC SDIO)*/
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6DL_PAD_SD3_RST__USDHC3_RST,
+
+ /* UART4 for debug */
+ MX6DL_PAD_KEY_COL0__UART4_TXD,
+ MX6DL_PAD_KEY_ROW0__UART4_RXD,
+
+ /*SD2_VSELECT (SD2 SDXC power exchange control signal)*/
+ MX6DL_PAD_KEY_ROW1__GPIO_4_9,
+
+ /*HDMI CEC communication PIN*/
+ MX6DL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+
+ /*PWRKEY_DET (Pwr button detection interrupt)*/
+ MX6DL_PAD_ENET_RXD0__GPIO_1_27,
+
+ /*USB_OTG_PWREN(USB OTG power change control signal)*/
+ MX6DL_PAD_KEY_ROW4__GPIO_4_15,
+
+ /* USBOTG ID pin */
+ MX6DL_PAD_GPIO_1__USBOTG_ID,
+
+ /* I2C2 */
+ MX6DL_PAD_KEY_COL3__I2C2_SCL, /* GPIO4[12] */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* GPIO4[13] */
+
+ /* I2C3 */
+ MX6DL_PAD_GPIO_5__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA,
+
+ /*WDOG(Watch dog output)*/
+ MX6DL_PAD_GPIO_9__GPIO_1_9,
+
+ /*PMIC_nINT(PMIC interrupt signal)*/
+ MX6DL_PAD_SD4_DAT3__GPIO_2_11,
+
+ /*GPIO_nRST(GPIO shutdown control)*/
+ MX6DL_PAD_SD4_DAT1__GPIO_2_9,
+
+ /*CHG_SYS_ON(Charger auto power on control signal)*/
+ MX6DL_PAD_SD4_DAT6__GPIO_2_14,
+};
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6dl_gpmi_nand[] __initdata = {
+ MX6DL_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6DL_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6DL_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6DL_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6DL_PAD_NANDF_D0__RAWNAND_D0,
+ MX6DL_PAD_NANDF_D1__RAWNAND_D1,
+ MX6DL_PAD_NANDF_D2__RAWNAND_D2,
+ MX6DL_PAD_NANDF_D3__RAWNAND_D3,
+ MX6DL_PAD_NANDF_D4__RAWNAND_D4,
+ MX6DL_PAD_NANDF_D5__RAWNAND_D5,
+ MX6DL_PAD_NANDF_D6__RAWNAND_D6,
+ MX6DL_PAD_NANDF_D7__RAWNAND_D7,
+ MX6DL_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6DL_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6dl_hdmidongle_hdmi_ddc_pads[] = {
+ MX6DL_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6dl_hdmidongle_i2c2_pads[] = {
+ MX6DL_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
+
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6dl_sabresd.h b/arch/arm/mach-mx6/board-mx6dl_sabresd.h
new file mode 100644
index 00000000..4e2d322f
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6dl_sabresd.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _BOARD_MX6DL_SABRESD_H
+#define _BOARD_MX6DL_SABRESD_H
+#include <mach/iomux-mx6dl.h>
+
+static iomux_v3_cfg_t mx6dl_sabresd_pads[] = {
+ /* AUDMUX */
+ MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+
+ /* CSPI */
+ MX6DL_PAD_KEY_COL0__ECSPI1_SCLK,
+ MX6DL_PAD_KEY_ROW0__ECSPI1_MOSI,
+ MX6DL_PAD_KEY_COL1__ECSPI1_MISO,
+ MX6DL_PAD_KEY_ROW1__GPIO_4_9,
+
+ /* ENET */
+ MX6DL_PAD_ENET_MDIO__ENET_MDIO,
+ MX6DL_PAD_ENET_MDC__ENET_MDC,
+ MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ /* RGMII_nRST */
+ MX6DL_PAD_ENET_CRS_DV__GPIO_1_25,
+ /* IEEE 1588 clock */
+ MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+ /* RGMII Interrupt */
+ MX6DL_PAD_ENET_RXD1__GPIO_1_26,
+
+ /* I2C1 */
+ MX6DL_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6DL_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6DL_PAD_KEY_COL3__I2C2_SCL,
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* I2C3 */
+ MX6DL_PAD_GPIO_3__I2C3_SCL,
+ MX6DL_PAD_GPIO_6__I2C3_SDA,
+#endif
+
+ /* DISPLAY */
+ MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
+ MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
+ MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
+ MX6DL_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
+ MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6DL_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6DL_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6DL_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ /* FlexCAN */
+ MX6DL_PAD_GPIO_7__CAN1_TXCAN,
+ MX6DL_PAD_GPIO_8__CAN1_RXCAN,
+ /* CAN1_STBY */
+ MX6DL_PAD_GPIO_19__GPIO_4_5,
+
+ /* UART1 for debug */
+ MX6DL_PAD_CSI0_DAT10__UART1_TXD,
+ MX6DL_PAD_CSI0_DAT11__UART1_RXD,
+
+ /* UART3 for gps */
+ MX6DL_PAD_EIM_D24__UART3_TXD,
+ MX6DL_PAD_EIM_D25__UART3_RXD,
+
+ /* USB */
+ MX6DL_PAD_ENET_RX_ER__ANATOP_USBOTG_ID,
+ MX6DL_PAD_EIM_D21__USBOH3_USBOTG_OC,
+ /* USB_OTG_PWR_EN */
+ MX6DL_PAD_EIM_D22__GPIO_3_22,
+ MX6DL_PAD_EIM_D30__USBOH3_USBH1_OC,
+ /*USB_H1 PWR EN*/
+ MX6DL_PAD_ENET_TXD1__GPIO_1_29,
+
+ /* USDHC2 */
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+ MX6DL_PAD_NANDF_D4__USDHC2_DAT4,
+ MX6DL_PAD_NANDF_D5__USDHC2_DAT5,
+ MX6DL_PAD_NANDF_D6__USDHC2_DAT6,
+ MX6DL_PAD_NANDF_D7__USDHC2_DAT7,
+ /* SD2_CD */
+ MX6DL_PAD_NANDF_D2__GPIO_2_2,
+ /* SD2_WP */
+ MX6DL_PAD_NANDF_D3__GPIO_2_3,
+
+ /* USDHC3 */
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ /* SD3_CD */
+ MX6DL_PAD_NANDF_D0__GPIO_2_0,
+ /* SD3_WP */
+ MX6DL_PAD_NANDF_D1__GPIO_2_1,
+
+ /* USDHC4 */
+ MX6DL_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6DL_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+
+ /* HDMI_CEC_IN*/
+ MX6DL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+
+ /* CCM - Audio, Camera clock */
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ /* MICROPHONE_DET */
+ MX6DL_PAD_GPIO_9__GPIO_1_9,
+ /* CODEC_PWR_EN */
+ MX6DL_PAD_KEY_COL2__GPIO_4_10,
+ /* HEADPHONE_DET */
+ MX6DL_PAD_SD3_RST__GPIO_7_8,
+
+ /* GPS_RESET_B */
+ MX6DL_PAD_EIM_EB0__GPIO_2_28,
+ /* GPS_PWREN */
+ MX6DL_PAD_EIM_DA0__GPIO_3_0,
+ /* GPS AUX_3V15_EN*/
+ MX6DL_PAD_NANDF_WP_B__GPIO_6_9,
+ /* GPS_PPS */
+ MX6DL_PAD_EIM_D18__GPIO_3_18,
+
+ /* DISP0_RST_B */
+ MX6DL_PAD_EIM_DA8__GPIO_3_8,
+ /* DI0_D0_CS */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0,
+ /* DI1_D0_CS */
+ MX6DL_PAD_EIM_BCLK__GPIO_6_31,
+ /* DISP_PWM */
+ MX6DL_PAD_SD1_DAT3__PWM1_PWMO,
+ /* DISP0 power enable */
+ MX6DL_PAD_ENET_TXD0__GPIO_1_30,
+ /* DISP0_RD */
+ MX6DL_PAD_EIM_D28__GPIO_3_28,
+ /* DISP_RST_B */
+ MX6DL_PAD_NANDF_CS0__GPIO_6_11,
+ /* DISP_PWR_EN */
+ MX6DL_PAD_NANDF_CS1__GPIO_6_14,
+ /* CABC_EN0 */
+ MX6DL_PAD_NANDF_CS2__GPIO_6_15,
+ /* CABC_EN1 */
+ MX6DL_PAD_NANDF_CS3__GPIO_6_16,
+ /* DISP0_WR */
+ MX6DL_PAD_NANDF_WP_B__GPIO_6_9,
+
+ /* ALS INT */
+ MX6DL_PAD_EIM_DA9__GPIO_3_9,
+ /* BARO_INT */
+ MX6DL_PAD_EIM_DA15__GPIO_3_15,
+
+ /* SW4 , SW5 & SW1 */
+ /* Volume Up */
+ MX6DL_PAD_GPIO_4__GPIO_1_4,
+ /* Volume Down */
+ MX6DL_PAD_GPIO_5__GPIO_1_5,
+ /* power off */
+ MX6DL_PAD_EIM_D29__GPIO_3_29,
+
+ /* CAP_TCH_INT1 */
+ MX6DL_PAD_NANDF_CLE__GPIO_6_7,
+
+ /* CAP_TCH_INT0 */
+ MX6DL_PAD_NANDF_ALE__GPIO_6_8,
+
+ /* AUX_5V Enable */
+ MX6DL_PAD_NANDF_RB0__GPIO_6_10,
+
+ /* PCIE_RST_B */
+ MX6DL_PAD_GPIO_17__GPIO_7_12,
+ /* PCIE_PWR_EN */
+ MX6DL_PAD_EIM_D19__GPIO_3_19,
+ /* PCIE_WAKE_B */
+ MX6DL_PAD_CSI0_DATA_EN__GPIO_5_20,
+ /* PCIE_DIS_B */
+ MX6DL_PAD_KEY_COL4__GPIO_4_14,
+
+ /* PMIC_INT_B */
+ MX6DL_PAD_GPIO_18__GPIO_7_13,
+
+ /* Charge */
+ MX6DL_PAD_EIM_A25__GPIO_5_2, /* FLT_1_B */
+ MX6DL_PAD_EIM_D23__GPIO_3_23, /* CHG_1_B */
+ MX6DL_PAD_EIM_DA13__GPIO_3_13, /* CHG_2_B */
+ MX6DL_PAD_EIM_DA14__GPIO_3_14, /* FLT_2_B */
+
+ MX6DL_PAD_ENET_RXD0__GPIO_1_27, /* UOK_B */
+ MX6DL_PAD_EIM_CS1__GPIO_2_24, /* DOK_B */
+
+ /* TS_INT - MAX11801 */
+ MX6DL_PAD_EIM_D26__GPIO_3_26,
+ /* eCompass int */
+ MX6DL_PAD_EIM_D16__GPIO_3_16,
+
+ /* SENSOR_PWR_EN */
+ MX6DL_PAD_EIM_EB3__GPIO_2_31,
+ /* ACCL_INT_INT */
+ MX6DL_PAD_SD1_CMD__GPIO_1_18,
+
+ /*WDOG_B to reset pmic*/
+ MX6DL_PAD_GPIO_1__WDOG2_WDOG_B,
+ /* USR_DEF_RED_LED */
+ MX6DL_PAD_GPIO_2__GPIO_1_2,
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_csi0_sensor_pads[] = {
+ /* IPU1 Camera */
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+
+ MX6DL_PAD_GPIO_0__CCM_CLKO, /* camera clk */
+
+ MX6DL_PAD_SD1_DAT0__GPIO_1_16, /* camera PWDN */
+ MX6DL_PAD_SD1_DAT1__GPIO_1_17, /* camera RESET */
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_mipi_sensor_pads[] = {
+ MX6DL_PAD_GPIO_0__CCM_CLKO, /* camera clk */
+
+ MX6DL_PAD_SD1_DAT2__GPIO_1_19, /* camera PWDN */
+ MX6DL_PAD_SD1_CLK__GPIO_1_20, /* camera RESET */
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_epdc_enable_pads[] = {
+ /* EPDC */
+ MX6DL_PAD_EIM_A16__EPDC_SDDO_0,
+ MX6DL_PAD_EIM_DA10__EPDC_SDDO_1,
+ MX6DL_PAD_EIM_DA12__EPDC_SDDO_2,
+ MX6DL_PAD_EIM_DA11__EPDC_SDDO_3,
+ MX6DL_PAD_EIM_LBA__EPDC_SDDO_4,
+ MX6DL_PAD_EIM_EB2__EPDC_SDDO_5,
+ MX6DL_PAD_EIM_CS0__EPDC_SDDO_6,
+ MX6DL_PAD_EIM_RW__EPDC_SDDO_7,
+ MX6DL_PAD_EIM_A21__EPDC_GDCLK,
+ MX6DL_PAD_EIM_A22__EPDC_GDSP,
+ MX6DL_PAD_EIM_A23__EPDC_GDOE,
+ MX6DL_PAD_EIM_A24__EPDC_GDRL,
+ MX6DL_PAD_EIM_D31__EPDC_SDCLK,
+ MX6DL_PAD_EIM_D27__EPDC_SDOE,
+ MX6DL_PAD_EIM_DA1__EPDC_SDLE,
+ MX6DL_PAD_EIM_EB1__EPDC_SDSHR,
+ MX6DL_PAD_EIM_DA2__EPDC_BDR_0,
+ MX6DL_PAD_EIM_DA4__EPDC_SDCE_0,
+ MX6DL_PAD_EIM_DA5__EPDC_SDCE_1,
+ MX6DL_PAD_EIM_DA6__EPDC_SDCE_2,
+
+ /* EPD PMIC (Maxim 17135) pins */
+ MX6DL_PAD_EIM_A17__GPIO_2_21, /* EPDC_PWRSTAT */
+ MX6DL_PAD_EIM_D17__GPIO_3_17, /* EPDC_VCOM0 */
+ MX6DL_PAD_EIM_A18__GPIO_2_20, /* EPDC_PWRCTRL0 */
+ MX6DL_PAD_EIM_D20__GPIO_3_20, /* EPDC_PMIC_WAKEUP */
+ /*
+ * Depopulate R121, R123, R133, R138, R139,
+ * R167, R168, and R627 when using E-BOOK
+ * Card in 16-bit Data Mode. Meanwhile, comments
+ * the conflict PIN configurations in above tables
+ */
+ /*
+ MX6DL_PAD_EIM_CS1__EPDC_SDDO_8,
+ MX6DL_PAD_EIM_DA15__EPDC_SDDO_9,
+ MX6DL_PAD_EIM_D16__EPDC_SDDO_10,
+ MX6DL_PAD_EIM_D23__EPDC_SDDO_11
+ MX6DL_PAD_EIM_D19__EPDC_SDDO_12,
+ MX6DL_PAD_EIM_DA13__EPDC_SDDO_13,
+ MX6DL_PAD_EIM_DA14__EPDC_SDDO_14,
+ MX6DL_PAD_EIM_A25__EPDC_SDDO_15,
+ */
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_epdc_disable_pads[] = {
+ /* EPDC */
+ MX6DL_PAD_EIM_A16__GPIO_2_22,
+ MX6DL_PAD_EIM_DA10__GPIO_3_10,
+ MX6DL_PAD_EIM_DA12__GPIO_3_12,
+ MX6DL_PAD_EIM_DA11__GPIO_3_11,
+ MX6DL_PAD_EIM_LBA__GPIO_2_27,
+ MX6DL_PAD_EIM_EB2__GPIO_2_30,
+ MX6DL_PAD_EIM_CS0__GPIO_2_23,
+ MX6DL_PAD_EIM_RW__GPIO_2_26,
+ MX6DL_PAD_EIM_A21__GPIO_2_17,
+ MX6DL_PAD_EIM_A22__GPIO_2_16,
+ MX6DL_PAD_EIM_A23__GPIO_6_6,
+ MX6DL_PAD_EIM_A24__GPIO_5_4,
+ MX6DL_PAD_EIM_D31__GPIO_3_31,
+ MX6DL_PAD_EIM_D27__GPIO_3_27,
+ MX6DL_PAD_EIM_DA1__GPIO_3_1,
+ MX6DL_PAD_EIM_EB1__GPIO_2_29,
+ MX6DL_PAD_EIM_DA2__GPIO_3_2,
+ MX6DL_PAD_EIM_DA4__GPIO_3_4,
+ MX6DL_PAD_EIM_DA5__GPIO_3_5,
+ MX6DL_PAD_EIM_DA6__GPIO_3_6,
+
+ /*
+ * Depopulate R121, R123, R133, R138, R139,
+ * R167, R168, and R627 when using E-BOOK
+ * Card in 16-bit Data Mode. Meanwhile, comments
+ * the conflict PIN configurations in above tables
+ */
+ /*
+ MX6DL_PAD_EIM_CS1__EPDC_SDDO_8,
+ MX6DL_PAD_EIM_DA15__EPDC_SDDO_9,
+ MX6DL_PAD_EIM_D16__EPDC_SDDO_10,
+ MX6DL_PAD_EIM_D23__EPDC_SDDO_11
+ MX6DL_PAD_EIM_D19__EPDC_SDDO_12,
+ MX6DL_PAD_EIM_DA13__EPDC_SDDO_13,
+ MX6DL_PAD_EIM_DA14__EPDC_SDDO_14,
+ MX6DL_PAD_EIM_A25__EPDC_SDDO_15,
+ */
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_elan_pads[] = {
+ MX6DL_PAD_EIM_A20__GPIO_2_18,
+ MX6DL_PAD_EIM_DA8__GPIO_3_8,
+ MX6DL_PAD_EIM_D28__GPIO_3_28,
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_hdmi_ddc_pads[] = {
+ MX6DL_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6dl_sabresd_i2c2_pads[] = {
+ MX6DL_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
new file mode 100644
index 00000000..250ef90a
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -0,0 +1,2303 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/ion.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <sound/pcm.h>
+#include <linux/mxc_asrc.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+#include <mach/mxc_asrc.h>
+#include <mach/mipi_dsi.h>
+#include <mach/mipi_csi2.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6q_arm2.h"
+#include "board-mx6dl_arm2.h"
+
+/* GPIO PIN, sort by PORT/BIT */
+#define MX6_ARM2_LDB_BACKLIGHT IMX_GPIO_NR(1, 9)
+#define MX6_ARM2_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define MX6_ARM2_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6_ARM2_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define MX6_ARM2_DISP0_PWR IMX_GPIO_NR(3, 24)
+#define MX6_ARM2_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
+#define MX6_ARM2_CAP_TCH_INT IMX_GPIO_NR(3, 31)
+#define MX6_ARM2_DISP0_DET_INT IMX_GPIO_NR(3, 31)
+#define MX6_ARM2_CSI0_RST IMX_GPIO_NR(4, 5)
+#define MX6_ARM2_DISP0_RESET IMX_GPIO_NR(5, 0)
+#define MX6_ARM2_CSI0_PWN IMX_GPIO_NR(5, 23)
+#define MX6_ARM2_CAN2_EN IMX_GPIO_NR(5, 24)
+#define MX6_ARM2_CSI0_RST_TVIN IMX_GPIO_NR(5, 25)
+#define MX6_ARM2_SD3_CD IMX_GPIO_NR(6, 11)
+#define MX6_ARM2_SD3_WP IMX_GPIO_NR(6, 14)
+#define MX6_ARM2_CAN1_STBY IMX_GPIO_NR(7, 12)
+#define MX6_ARM2_CAN1_EN IMX_GPIO_NR(7, 13)
+#define MX6_ARM2_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0)
+#define MX6_ARM2_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
+#define MX6DL_ARM2_EPDC_SDDO_0 IMX_GPIO_NR(2, 22)
+#define MX6DL_ARM2_EPDC_SDDO_1 IMX_GPIO_NR(3, 10)
+#define MX6DL_ARM2_EPDC_SDDO_2 IMX_GPIO_NR(3, 12)
+#define MX6DL_ARM2_EPDC_SDDO_3 IMX_GPIO_NR(3, 11)
+#define MX6DL_ARM2_EPDC_SDDO_4 IMX_GPIO_NR(2, 27)
+#define MX6DL_ARM2_EPDC_SDDO_5 IMX_GPIO_NR(2, 30)
+#define MX6DL_ARM2_EPDC_SDDO_6 IMX_GPIO_NR(2, 23)
+#define MX6DL_ARM2_EPDC_SDDO_7 IMX_GPIO_NR(2, 26)
+#define MX6DL_ARM2_EPDC_SDDO_8 IMX_GPIO_NR(2, 24)
+#define MX6DL_ARM2_EPDC_SDDO_9 IMX_GPIO_NR(3, 15)
+#define MX6DL_ARM2_EPDC_SDDO_10 IMX_GPIO_NR(3, 16)
+#define MX6DL_ARM2_EPDC_SDDO_11 IMX_GPIO_NR(3, 23)
+#define MX6DL_ARM2_EPDC_SDDO_12 IMX_GPIO_NR(3, 19)
+#define MX6DL_ARM2_EPDC_SDDO_13 IMX_GPIO_NR(3, 13)
+#define MX6DL_ARM2_EPDC_SDDO_14 IMX_GPIO_NR(3, 14)
+#define MX6DL_ARM2_EPDC_SDDO_15 IMX_GPIO_NR(5, 2)
+#define MX6DL_ARM2_EPDC_GDCLK IMX_GPIO_NR(2, 17)
+#define MX6DL_ARM2_EPDC_GDSP IMX_GPIO_NR(2, 16)
+#define MX6DL_ARM2_EPDC_GDOE IMX_GPIO_NR(6, 6)
+#define MX6DL_ARM2_EPDC_GDRL IMX_GPIO_NR(5, 4)
+#define MX6DL_ARM2_EPDC_SDCLK IMX_GPIO_NR(3, 31)
+#define MX6DL_ARM2_EPDC_SDOEZ IMX_GPIO_NR(3, 30)
+#define MX6DL_ARM2_EPDC_SDOED IMX_GPIO_NR(3, 26)
+#define MX6DL_ARM2_EPDC_SDOE IMX_GPIO_NR(3, 27)
+#define MX6DL_ARM2_EPDC_SDLE IMX_GPIO_NR(3, 1)
+#define MX6DL_ARM2_EPDC_SDCLKN IMX_GPIO_NR(3, 0)
+#define MX6DL_ARM2_EPDC_SDSHR IMX_GPIO_NR(2, 29)
+#define MX6DL_ARM2_EPDC_PWRCOM IMX_GPIO_NR(2, 28)
+#define MX6DL_ARM2_EPDC_PWRSTAT IMX_GPIO_NR(2, 21)
+#define MX6DL_ARM2_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 20)
+#define MX6DL_ARM2_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 19)
+#define MX6DL_ARM2_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 18)
+#define MX6DL_ARM2_EPDC_PWRCTRL3 IMX_GPIO_NR(3, 28)
+#define MX6DL_ARM2_EPDC_BDR0 IMX_GPIO_NR(3, 2)
+#define MX6DL_ARM2_EPDC_BDR1 IMX_GPIO_NR(3, 3)
+#define MX6DL_ARM2_EPDC_SDCE0 IMX_GPIO_NR(3, 4)
+#define MX6DL_ARM2_EPDC_SDCE1 IMX_GPIO_NR(3, 5)
+#define MX6DL_ARM2_EPDC_SDCE2 IMX_GPIO_NR(3, 6)
+#define MX6DL_ARM2_EPDC_SDCE3 IMX_GPIO_NR(3, 7)
+#define MX6DL_ARM2_EPDC_SDCE4 IMX_GPIO_NR(3, 8)
+#define MX6DL_ARM2_EPDC_SDCE5 IMX_GPIO_NR(3, 9)
+#define MX6DL_ARM2_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 31)
+#define MX6DL_ARM2_EPDC_PMIC_INT IMX_GPIO_NR(2, 25)
+#define MX6DL_ARM2_EPDC_VCOM IMX_GPIO_NR(3, 17)
+
+#define MX6_ARM2_IO_EXP_GPIO1(x) (MX6_ARM2_MAX7310_1_BASE_ADDR + (x))
+#define MX6_ARM2_IO_EXP_GPIO2(x) (MX6_ARM2_MAX7310_2_BASE_ADDR + (x))
+
+#define MX6_ARM2_PCIE_PWR_EN MX6_ARM2_IO_EXP_GPIO1(2)
+#define MX6_ARM2_PCIE_RESET MX6_ARM2_IO_EXP_GPIO2(2)
+
+#define MX6_ARM2_CAN2_STBY MX6_ARM2_IO_EXP_GPIO2(1)
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
+#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+static struct clk *sata_clk;
+static int esai_record;
+static int sgtl5000_en;
+static int spdif_en;
+static int flexcan_en;
+static int disable_mipi_dsi;
+
+extern struct regulator *(*get_cpu_regulator)(void);
+extern void (*put_cpu_regulator)(void);
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int epdc_enabled;
+extern void mx6_cpu_regulator_init(void);
+static int max17135_regulator_init(struct max17135 *max17135);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 2:
+ if (cpu_is_mx6q()) {
+ sd_pads_200mhz = mx6q_sd3_200mhz;
+ sd_pads_100mhz = mx6q_sd3_100mhz;
+ sd_pads_50mhz = mx6q_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
+ } else if (cpu_is_mx6dl()) {
+ sd_pads_200mhz = mx6dl_sd3_200mhz;
+ sd_pads_100mhz = mx6dl_sd3_100mhz;
+ sd_pads_50mhz = mx6dl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
+ }
+ break;
+ case 3:
+ if (cpu_is_mx6q()) {
+ sd_pads_200mhz = mx6q_sd4_200mhz;
+ sd_pads_100mhz = mx6q_sd4_100mhz;
+ sd_pads_50mhz = mx6q_sd4_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
+ } else if (cpu_is_mx6dl()) {
+ sd_pads_200mhz = mx6dl_sd4_200mhz;
+ sd_pads_100mhz = mx6dl_sd4_100mhz;
+ sd_pads_50mhz = mx6dl_sd4_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd4_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd4_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd4_50mhz);
+ }
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
+ .cd_gpio = MX6_ARM2_SD3_CD,
+ .wp_gpio = MX6_ARM2_SD3_WP,
+ .support_18v = 1,
+ .support_8bit = 1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+/* No card detect signal for SD4 on ARM2 board*/
+static const struct esdhc_platform_data mx6_arm2_sd4_data __initconst = {
+ .always_present = 1,
+ .support_8bit = 1,
+ .keep_power_at_suspend = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static int __init gpmi_nand_platform_init(void)
+{
+ iomux_v3_cfg_t *nand_pads = NULL;
+ u32 nand_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ nand_pads = mx6q_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+ } else if (cpu_is_mx6dl()) {
+ nand_pads = mx6dl_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+
+ }
+ BUG_ON(!nand_pads);
+ return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt);
+}
+
+static struct gpmi_nand_platform_data
+mx6_gpmi_nand_platform_data __initdata = {
+ .platform_init = gpmi_nand_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+ .enable_bbt = 1,
+ .enable_ddr = 0,
+};
+
+static int __init board_support_onfi_nand(char *p)
+{
+ mx6_gpmi_nand_platform_data.enable_ddr = 1;
+ return 0;
+}
+
+early_param("onfi_support", board_support_onfi_nand);
+
+static const struct anatop_thermal_platform_data
+ mx6_arm2_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static const struct imxuart_platform_data mx6_arm2_uart1_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_USE_DCEDTE | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
+};
+
+static inline void mx6_arm2_init_uart(void)
+{
+ imx6q_add_imx_uart(3, NULL);
+ imx6q_add_imx_uart(1, &mx6_arm2_uart1_data);
+}
+
+static int mx6_arm2_fec_phy_init(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+ phy_write(phydev, 0xd, 0x7);
+ phy_write(phydev, 0xe, 0x8016);
+ phy_write(phydev, 0xd, 0x4007);
+ val = phy_read(phydev, 0xe);
+
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, 0xe, val);
+
+ /* introduce tx clock delay */
+ phy_write(phydev, 0x1d, 0x5);
+ val = phy_read(phydev, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, 0x1e, val);
+
+ /*check phy power*/
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+ return 0;
+}
+
+static int mx6_arm2_fec_power_hibernate(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /*set AR8031 debug reg 0xb to hibernate power*/
+ phy_write(phydev, 0x1d, 0xb);
+ val = phy_read(phydev, 0x1e);
+
+ val |= 0x8000;
+ phy_write(phydev, 0x1e, val);
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6_arm2_fec_phy_init,
+ .power_hibernate = mx6_arm2_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
+};
+
+static int mx6_arm2_spi_cs[] = {
+ MX6_ARM2_ECSPI1_CS0,
+ MX6_ARM2_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx6_arm2_spi_data __initconst = {
+ .chipselect = mx6_arm2_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_arm2_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+#endif
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80)
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+}
+
+static int max7310_1_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ int max7310_gpio_value[] = { 0, 1, 0, 1, 0, 0, 0, 0 };
+
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 1 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_platdata = {
+ .gpio_base = MX6_ARM2_MAX7310_1_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_1_setup,
+};
+
+static int max7310_u48_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ int max7310_gpio_value[] = { 1, 1, 1, 1, 0, 1, 0, 0 };
+
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 U48 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_u48_platdata = {
+ .gpio_base = MX6_ARM2_MAX7310_2_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_u48_setup,
+};
+
+static void ddc_dvi_init(void)
+{
+ /* enable DVI I2C */
+ gpio_set_value(MX6_ARM2_DISP0_I2C_EN, 1);
+
+ /* DISP0 Detect */
+ gpio_request(MX6_ARM2_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(MX6_ARM2_DISP0_DET_INT);
+}
+
+static int ddc_dvi_update(void)
+{
+ /* DVI cable state */
+ if (gpio_get_value(MX6_ARM2_DISP0_DET_INT) == 1)
+ return 1;
+ return 0;
+}
+
+static struct fsl_mxc_dvi_platform_data sabr_ddc_dvi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .init = ddc_dvi_init,
+ .update = ddc_dvi_update,
+};
+
+static void mx6_csi0_io_init(void)
+{
+ if (0 == sgtl5000_en) {
+ iomux_v3_cfg_t *sensor_pads = NULL;
+ u32 sensor_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ sensor_pads = mx6q_arm2_csi0_sensor_pads;
+ sensor_pads_cnt = \
+ ARRAY_SIZE(mx6q_arm2_csi0_sensor_pads);
+ } else if (cpu_is_mx6dl()) {
+ sensor_pads = mx6dl_arm2_csi0_sensor_pads;
+ sensor_pads_cnt = \
+ ARRAY_SIZE(mx6dl_arm2_csi0_sensor_pads);
+ }
+
+ BUG_ON(!sensor_pads);
+ mxc_iomux_v3_setup_multiple_pads(sensor_pads, sensor_pads_cnt);
+ }
+ /* Camera reset */
+ gpio_request(MX6_ARM2_CSI0_RST, "cam-reset");
+ gpio_direction_output(MX6_ARM2_CSI0_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6_ARM2_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6_ARM2_CSI0_PWN, 1);
+ msleep(1);
+ gpio_set_value(MX6_ARM2_CSI0_PWN, 0);
+
+ /* For MX6Q:
+ * GPR1 bit19 and bit20 meaning:
+ * Bit19: 0 - Enable mipi to IPU1 CSI0
+ * virtual channel is fixed to 0
+ * 1 - Enable parallel interface to IPU1 CSI0
+ * Bit20: 0 - Enable mipi to IPU2 CSI1
+ * virtual channel is fixed to 3
+ * 1 - Enable parallel interface to IPU2 CSI1
+ * IPU1 CSI1 directly connect to mipi csi2,
+ * virtual channel is fixed to 1
+ * IPU2 CSI0 directly connect to mipi csi2,
+ * virtual channel is fixed to 2
+ *
+ * For MX6DL:
+ * GPR1 bit 21 and GPR13 bit 0-5, RM has detail information
+ */
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .analog_regulator = "DA9052_LDO7",
+ .core_regulator = "DA9052_LDO9",
+ .mclk = 24000000,
+ .mclk_source = 0,
+ .csi = 0,
+ .io_init = mx6_csi0_io_init,
+};
+
+static void mx6_csi0_tvin_io_init(void)
+{
+ if (0 == sgtl5000_en) {
+ iomux_v3_cfg_t *tvin_pads = NULL;
+ u32 tvin_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ tvin_pads = mx6q_arm2_csi0_tvin_pads;
+ tvin_pads_cnt = \
+ ARRAY_SIZE(mx6q_arm2_csi0_tvin_pads);
+ } else if (cpu_is_mx6dl()) {
+ tvin_pads = mx6dl_arm2_csi0_tvin_pads;
+ tvin_pads_cnt = \
+ ARRAY_SIZE(mx6dl_arm2_csi0_tvin_pads);
+ }
+
+ BUG_ON(!tvin_pads);
+ mxc_iomux_v3_setup_multiple_pads(tvin_pads, tvin_pads_cnt);
+ }
+ /* Tvin reset */
+ gpio_request(MX6_ARM2_CSI0_RST_TVIN, "tvin-reset");
+ gpio_direction_output(MX6_ARM2_CSI0_RST_TVIN, 1);
+
+ /* Tvin power down */
+ gpio_request(MX6_ARM2_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6_ARM2_CSI0_PWN, 0);
+ msleep(1);
+ gpio_set_value(MX6_ARM2_CSI0_PWN, 1);
+
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
+}
+
+static struct fsl_mxc_tvin_platform_data tvin_data = {
+ .io_init = mx6_csi0_tvin_io_init,
+ .cvbs = false,
+};
+
+static void mx6_mipi_sensor_io_init(void)
+{
+ iomux_v3_cfg_t *mipi_sensor_pads = NULL;
+ u32 mipi_sensor_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ mipi_sensor_pads = mx6q_arm2_mipi_sensor_pads;
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6q_arm2_mipi_sensor_pads);
+ } else if (cpu_is_mx6dl()) {
+ mipi_sensor_pads = mx6dl_arm2_mipi_sensor_pads;
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6dl_arm2_mipi_sensor_pads);
+
+ }
+ BUG_ON(!mipi_sensor_pads);
+ mxc_iomux_v3_setup_multiple_pads(mipi_sensor_pads,
+ mipi_sensor_pads_cnt);
+
+ /*for mx6dl, mipi virtual channel 1 connect to csi 1*/
+ if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 3, 3, 1);
+}
+
+static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
+ .mclk = 24000000,
+ .csi = 1,
+ .mclk_source = 0,
+ .io_init = mx6_mipi_sensor_io_init,
+};
+
+static struct mxc_audio_codec_platform_data cs42888_data = {
+ .rates = (SNDRV_PCM_RATE_44100 |
+ SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_176400),
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX6DL_ARM2_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6DL_ARM2_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6DL_ARM2_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6DL_ARM2_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6DL_ARM2_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ if (!epdc_enabled) {
+ printk(KERN_DEBUG
+ "max17135_regulator_init abort: EPDC not enabled\n");
+ return 0;
+ }
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ regulator_has_full_constraints();
+
+ return 0;
+}
+
+static int sii902x_get_pins(void)
+{
+ /* Sii902x HDMI controller */
+ gpio_request(MX6_ARM2_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(MX6_ARM2_DISP0_RESET, 0);
+ gpio_request(MX6_ARM2_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(MX6_ARM2_DISP0_DET_INT);
+ return 1;
+}
+
+static void sii902x_put_pins(void)
+{
+ gpio_free(MX6_ARM2_DISP0_RESET);
+ gpio_free(MX6_ARM2_DISP0_DET_INT);
+}
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 0);
+ msleep(10);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .reset = sii902x_hdmi_reset,
+ .get_pins = sii902x_get_pins,
+ .put_pins = sii902x_put_pins,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("cs42888", 0x48),
+ .platform_data = (void *)&cs42888_data,
+ }, {
+ I2C_BOARD_INFO("ov5640", 0x3c),
+ .platform_data = (void *)&camera_data,
+ }, {
+ I2C_BOARD_INFO("adv7180", 0x21),
+ .platform_data = (void *)&tvin_data,
+ },
+};
+
+static struct imxi2c_platform_data mx6_arm2_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_arm2_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_arm2_i2c2_data = {
+ .bitrate = 400000,
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0x48),
+ .platform_data = &max17135_pdata,
+ }, {
+ I2C_BOARD_INFO("max7310", 0x1F),
+ .platform_data = &max7310_platdata,
+ }, {
+ I2C_BOARD_INFO("max7310", 0x1B),
+ .platform_data = &max7310_u48_platdata,
+ }, {
+ I2C_BOARD_INFO("mxc_dvi", 0x50),
+ .platform_data = &sabr_ddc_dvi_data,
+ .irq = gpio_to_irq(MX6_ARM2_DISP0_DET_INT),
+ }, {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(MX6_ARM2_CAP_TCH_INT),
+ }, {
+ I2C_BOARD_INFO("sii902x", 0x39),
+ .platform_data = &sii902x_hdmi_data,
+ .irq = gpio_to_irq(MX6_ARM2_DISP0_DET_INT),
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(MX6_ARM2_CAP_TCH_INT),
+ }, {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ }, {
+ I2C_BOARD_INFO("ov5640_mipi", 0x3c),
+ .platform_data = (void *)&ov5640_mipi_data,
+ }, {
+ I2C_BOARD_INFO("sgtl5000", 0x0a),
+ },
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX6DL_ARM2_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_0);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_1);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_2);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_3);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_4);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_5);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_6);
+ gpio_free(MX6DL_ARM2_EPDC_SDDO_7);
+ gpio_free(MX6DL_ARM2_EPDC_GDCLK);
+ gpio_free(MX6DL_ARM2_EPDC_GDSP);
+ gpio_free(MX6DL_ARM2_EPDC_GDOE);
+ gpio_free(MX6DL_ARM2_EPDC_GDRL);
+ gpio_free(MX6DL_ARM2_EPDC_SDCLK);
+ gpio_free(MX6DL_ARM2_EPDC_SDOE);
+ gpio_free(MX6DL_ARM2_EPDC_SDLE);
+ gpio_free(MX6DL_ARM2_EPDC_SDSHR);
+ gpio_free(MX6DL_ARM2_EPDC_BDR0);
+ gpio_free(MX6DL_ARM2_EPDC_SDCE0);
+ gpio_free(MX6DL_ARM2_EPDC_SDCE1);
+ gpio_free(MX6DL_ARM2_EPDC_SDCE2);
+}
+
+static iomux_v3_cfg_t mx6dl_epdc_pads_enabled[] = {
+ MX6DL_PAD_EIM_A16__EPDC_SDDO_0,
+ MX6DL_PAD_EIM_DA10__EPDC_SDDO_1,
+ MX6DL_PAD_EIM_DA12__EPDC_SDDO_2,
+ MX6DL_PAD_EIM_DA11__EPDC_SDDO_3,
+ MX6DL_PAD_EIM_LBA__EPDC_SDDO_4,
+ MX6DL_PAD_EIM_EB2__EPDC_SDDO_5,
+ MX6DL_PAD_EIM_CS0__EPDC_SDDO_6,
+ MX6DL_PAD_EIM_RW__EPDC_SDDO_7,
+ MX6DL_PAD_EIM_CS1__EPDC_SDDO_8,
+ MX6DL_PAD_EIM_DA15__EPDC_SDDO_9,
+ MX6DL_PAD_EIM_D16__EPDC_SDDO_10,
+ MX6DL_PAD_EIM_D23__EPDC_SDDO_11,
+ MX6DL_PAD_EIM_D19__EPDC_SDDO_12,
+ MX6DL_PAD_EIM_DA13__EPDC_SDDO_13,
+ MX6DL_PAD_EIM_DA14__EPDC_SDDO_14,
+ MX6DL_PAD_EIM_A25__EPDC_SDDO_15,
+ MX6DL_PAD_EIM_A21__EPDC_GDCLK,
+ MX6DL_PAD_EIM_A22__EPDC_GDSP,
+ MX6DL_PAD_EIM_A23__EPDC_GDOE,
+ MX6DL_PAD_EIM_A24__EPDC_GDRL,
+ MX6DL_PAD_EIM_D31__EPDC_SDCLK,
+ MX6DL_PAD_EIM_D27__EPDC_SDOE,
+ MX6DL_PAD_EIM_DA1__EPDC_SDLE,
+ MX6DL_PAD_EIM_EB1__EPDC_SDSHR,
+ MX6DL_PAD_EIM_DA2__EPDC_BDR_0,
+ MX6DL_PAD_EIM_DA4__EPDC_SDCE_0,
+ MX6DL_PAD_EIM_DA5__EPDC_SDCE_1,
+ MX6DL_PAD_EIM_DA6__EPDC_SDCE_2,
+};
+
+static iomux_v3_cfg_t mx6dl_epdc_pads_disabled[] = {
+ MX6DL_PAD_EIM_A16__GPIO_2_22,
+ MX6DL_PAD_EIM_DA10__GPIO_3_10,
+ MX6DL_PAD_EIM_DA12__GPIO_3_12,
+ MX6DL_PAD_EIM_DA11__GPIO_3_11,
+ MX6DL_PAD_EIM_LBA__GPIO_2_27,
+ MX6DL_PAD_EIM_EB2__GPIO_2_30,
+ MX6DL_PAD_EIM_CS0__GPIO_2_23,
+ MX6DL_PAD_EIM_RW__GPIO_2_26,
+ MX6DL_PAD_EIM_CS1__GPIO_2_24,
+ MX6DL_PAD_EIM_DA15__GPIO_3_15,
+ MX6DL_PAD_EIM_D16__GPIO_3_16,
+ MX6DL_PAD_EIM_D23__GPIO_3_23,
+ MX6DL_PAD_EIM_D19__GPIO_3_19,
+ MX6DL_PAD_EIM_DA13__GPIO_3_13,
+ MX6DL_PAD_EIM_DA14__GPIO_3_14,
+ MX6DL_PAD_EIM_A25__GPIO_5_2,
+ MX6DL_PAD_EIM_A21__GPIO_2_17,
+ MX6DL_PAD_EIM_A22__GPIO_2_16,
+ MX6DL_PAD_EIM_A23__GPIO_6_6,
+ MX6DL_PAD_EIM_A24__GPIO_5_4,
+ MX6DL_PAD_EIM_D31__GPIO_3_31,
+ MX6DL_PAD_EIM_D27__GPIO_3_27,
+ MX6DL_PAD_EIM_DA1__GPIO_3_1,
+ MX6DL_PAD_EIM_EB1__GPIO_2_29,
+ MX6DL_PAD_EIM_DA2__GPIO_3_2,
+ MX6DL_PAD_EIM_DA4__GPIO_3_4,
+ MX6DL_PAD_EIM_DA5__GPIO_3_5,
+ MX6DL_PAD_EIM_DA6__GPIO_3_6,
+};
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_epdc_pads_enabled, \
+ ARRAY_SIZE(mx6dl_epdc_pads_enabled));
+
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_0);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_1);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_2);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_3);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_4);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_5);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_6);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDDO_7);
+ gpio_direction_input(MX6DL_ARM2_EPDC_GDCLK);
+ gpio_direction_input(MX6DL_ARM2_EPDC_GDSP);
+ gpio_direction_input(MX6DL_ARM2_EPDC_GDOE);
+ gpio_direction_input(MX6DL_ARM2_EPDC_GDRL);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDCLK);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDOE);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDLE);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDSHR);
+ gpio_direction_input(MX6DL_ARM2_EPDC_BDR0);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDCE0);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDCE1);
+ gpio_direction_input(MX6DL_ARM2_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_epdc_pads_disabled, \
+ ARRAY_SIZE(mx6dl_epdc_pads_disabled));
+
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_GDSP, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_GDOE, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_GDRL, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDOE, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDLE, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_BDR0, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6DL_ARM2_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static void imx6_arm2_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6_ARM2_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(MX6_ARM2_USB_OTG_PWR, 0);
+}
+
+static void __init mx6_arm2_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6_ARM2_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_ARM2_USB_OTG_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_ARM2_USB_OTG_PWR, 0);
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+
+ mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+ mx6_usb_h3_init();
+#endif
+}
+
+static struct viv_gpu_platform_data imx6_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M,
+};
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6_arm2_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ /* Enable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 1);
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+
+release_sata_clk:
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+ /* Disable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 0);
+
+ return ret;
+}
+
+static void mx6_arm2_sata_exit(struct device *dev)
+{
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+
+ /* Disable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 0);
+
+}
+
+static struct ahci_platform_data mx6_arm2_sata_data = {
+ .init = mx6_arm2_sata_init,
+ .exit = mx6_arm2_sata_exit,
+};
+
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+static void mx6_arm2_reset_mipi_dsi(void)
+{
+ gpio_set_value(MX6_ARM2_DISP0_PWR, 1);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 1);
+ udelay(10);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 0);
+ udelay(50);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 1);
+
+ /*
+ * it needs to delay 120ms minimum for reset complete
+ */
+ msleep(120);
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+ .ipu_id = 1,
+ .disp_id = 1,
+ .lcd_panel = "TRULY-WVGA",
+ .reset = mx6_arm2_reset_mipi_dsi,
+};
+
+static struct ipuv3_fb_platform_data sabr_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ }, {
+ .disp_dev = "mipi_dsi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "TRULY-WVGA",
+ .default_bpp = 24,
+ .int_clk = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+ int max_ipu_id = cpu_is_mx6q() ? 1 : 0;
+
+ if ((ipu_id > max_ipu_id) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2 * ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+
+ /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+ if (hdmi_SDMA_check())
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+/* On mx6x arm2 board i2c2 iomux with hdmi ddc,
+ * the pins default work at i2c2 function,
+ when hdcp enable, the pins should work at ddc function */
+
+static void hdmi_enable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6dl_arm2_hdmi_ddc_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6q_arm2_hdmi_ddc_pads));
+}
+
+static void hdmi_disable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_i2c2_pads,
+ ARRAY_SIZE(mx6dl_arm2_i2c2_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_i2c2_pads,
+ ARRAY_SIZE(mx6q_arm2_i2c2_pads));
+}
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+ .enable_pins = hdmi_enable_ddc_pin,
+ .disable_pins = hdmi_disable_ddc_pin,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 1,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SEP0,
+ .sec_ipu_id = 0,
+ .sec_disp_id = 1,
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ },
+};
+
+static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct ion_platform_data imx_ion_data = {
+ .nr = 1,
+ .heaps = {
+ {
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = "vpu_ion",
+ .size = SZ_64M,
+ },
+ },
+};
+
+static struct gpio mx6_flexcan_gpios[] = {
+ { MX6_ARM2_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
+ { MX6_ARM2_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
+ { MX6_ARM2_CAN2_EN, GPIOF_OUT_INIT_LOW, "flexcan2-en" },
+};
+
+static void mx6_flexcan0_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6_ARM2_CAN1_EN, 1);
+ gpio_set_value(MX6_ARM2_CAN1_STBY, 1);
+ } else {
+ gpio_set_value(MX6_ARM2_CAN1_EN, 0);
+ gpio_set_value(MX6_ARM2_CAN1_STBY, 0);
+ }
+}
+
+static void mx6_flexcan1_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6_ARM2_CAN2_EN, 1);
+ gpio_set_value_cansleep(MX6_ARM2_CAN2_STBY, 1);
+ } else {
+ gpio_set_value(MX6_ARM2_CAN2_EN, 0);
+ gpio_set_value_cansleep(MX6_ARM2_CAN2_STBY, 0);
+ }
+}
+
+static const struct flexcan_platform_data
+ mx6_arm2_flexcan_pdata[] __initconst = {
+ {
+ .transceiver_switch = mx6_flexcan0_switch,
+ }, {
+ .transceiver_switch = mx6_flexcan1_switch,
+ }
+};
+
+static struct mipi_csi2_platform_data mipi_csi2_pdata = {
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+static struct fsl_mxc_capture_platform_data capture_data[] = {
+ {
+ .csi = 0,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 0,
+ }, {
+ .csi = 1,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 1,
+ },
+};
+
+
+static void arm2_suspend_enter(void)
+{
+ /* suspend preparation */
+}
+
+static void arm2_suspend_exit(void)
+{
+ /* resmue resore */
+}
+static const struct pm_platform_data mx6_arm2_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = arm2_suspend_enter,
+ .suspend_exit = arm2_suspend_exit,
+};
+
+static const struct asrc_p2p_params esai_p2p = {
+ .p2p_rate = 44100,
+ .p2p_width = ASRC_WIDTH_24_BIT,
+};
+
+static struct mxc_audio_platform_data sab_audio_data = {
+ .sysclk = 16934400,
+ .priv = (void *)&esai_p2p,
+};
+
+static struct platform_device sab_audio_device = {
+ .name = "imx-cs42888",
+};
+
+static struct imx_esai_platform_data sab_esai_pdata = {
+ .flags = IMX_ESAI_NET,
+};
+
+static struct regulator_consumer_supply arm2_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data arm2_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(arm2_vmmc_consumers),
+ .consumer_supplies = arm2_vmmc_consumers,
+};
+
+static struct fixed_voltage_config arm2_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &arm2_vmmc_init,
+};
+
+static struct platform_device arm2_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &arm2_vmmc_reg_config,
+ },
+};
+
+#ifdef CONFIG_SND_SOC_CS42888
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_va = {
+ .supply = "VA",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vd = {
+ .supply = "VD",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vls = {
+ .supply = "VLS",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vlc = {
+ .supply = "VLC",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_init_data cs42888_arm2_va_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_va,
+};
+
+static struct regulator_init_data cs42888_arm2_vd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vd,
+};
+
+static struct regulator_init_data cs42888_arm2_vls_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vls,
+};
+
+static struct regulator_init_data cs42888_arm2_vlc_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vlc,
+};
+
+static struct fixed_voltage_config cs42888_arm2_va_reg_config = {
+ .supply_name = "VA",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_va_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vd_reg_config = {
+ .supply_name = "VD",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vd_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vls_reg_config = {
+ .supply_name = "VLS",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vls_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vlc_reg_config = {
+ .supply_name = "VLC",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vlc_reg_initdata,
+};
+
+static struct platform_device cs42888_arm2_va_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &cs42888_arm2_va_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &cs42888_arm2_vd_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vls_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 5,
+ .dev = {
+ .platform_data = &cs42888_arm2_vls_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vlc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 6,
+ .dev = {
+ .platform_data = &cs42888_arm2_vlc_reg_config,
+ },
+};
+
+#endif /* CONFIG_SND_SOC_CS42888 */
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vdda = {
+ .supply = "VDDA",
+ .dev_name = "1-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddio = {
+ .supply = "VDDIO",
+ .dev_name = "1-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddd = {
+ .supply = "VDDD",
+ .dev_name = "1-000a",
+};
+
+static struct regulator_init_data sgtl5000_arm2_vdda_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vdda,
+};
+
+static struct regulator_init_data sgtl5000_arm2_vddio_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddio,
+};
+
+static struct regulator_init_data sgtl5000_arm2_vddd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddd,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vdda_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 1800000,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vdda_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vddio_reg_config = {
+ .supply_name = "VDDIO",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vddio_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vddd_reg_config = {
+ .supply_name = "VDDD",
+ .microvolts = 0,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vddd_reg_initdata,
+};
+
+static struct platform_device sgtl5000_arm2_vdda_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 7,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vdda_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_arm2_vddio_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 8,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vddio_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_arm2_vddd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 9,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vddd_reg_config,
+ },
+};
+
+#endif /* CONFIG_SND_SOC_SGTL5000 */
+
+static struct mxc_audio_platform_data mx6_arm2_audio_data;
+
+static int mx6_arm2_sgtl5000_init(void)
+{
+
+ mx6_arm2_audio_data.sysclk = 12000000;
+
+ return 0;
+}
+
+static struct imx_ssi_platform_data mx6_arm2_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data mx6_arm2_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .init = mx6_arm2_sgtl5000_init,
+ .hp_gpio = -1,
+};
+
+static struct platform_device mx6_arm2_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+static int __init mx6_arm2_init_audio(void)
+{
+ struct clk *pll3_pfd, *esai_clk;
+ mxc_register_device(&sab_audio_device, &sab_audio_data);
+ imx6q_add_imx_esai(0, &sab_esai_pdata);
+
+ esai_clk = clk_get(NULL, "esai_clk");
+ if (IS_ERR(esai_clk))
+ return PTR_ERR(esai_clk);
+
+ pll3_pfd = clk_get(NULL, "pll3_pfd_508M");
+ if (IS_ERR(pll3_pfd))
+ return PTR_ERR(pll3_pfd);
+
+ clk_set_parent(esai_clk, pll3_pfd);
+ clk_set_rate(esai_clk, 101647058);
+
+#ifdef CONFIG_SND_SOC_CS42888
+ platform_device_register(&cs42888_arm2_va_reg_devices);
+ platform_device_register(&cs42888_arm2_vd_reg_devices);
+ platform_device_register(&cs42888_arm2_vls_reg_devices);
+ platform_device_register(&cs42888_arm2_vlc_reg_devices);
+#endif
+
+ if (sgtl5000_en) {
+ /* SSI audio init part */
+ mxc_register_device(&mx6_arm2_audio_device,
+ &mx6_arm2_audio_data);
+ imx6q_add_imx_ssi(1, &mx6_arm2_ssi_pdata);
+
+ /*
+ * AUDMUX3 and CSI0_Camera use the same pin
+ * MX6x_PAD_CSI0_DAT5
+ */
+ if (cpu_is_mx6q()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_audmux_pads,
+ ARRAY_SIZE(mx6q_arm2_audmux_pads));
+ } else if (cpu_is_mx6dl()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_audmux_pads,
+ ARRAY_SIZE(mx6dl_arm2_audmux_pads));
+ }
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+ platform_device_register(&sgtl5000_arm2_vdda_reg_devices);
+ platform_device_register(&sgtl5000_arm2_vddio_reg_devices);
+ platform_device_register(&sgtl5000_arm2_vddd_reg_devices);
+#endif
+ }
+
+ return 0;
+}
+
+static int __init early_use_esai_record(char *p)
+{
+ esai_record = 1;
+ return 0;
+}
+
+early_param("esai_record", early_use_esai_record);
+
+static struct mxc_mlb_platform_data mx6_arm2_mlb150_data = {
+ .reg_nvcc = NULL,
+ .mlb_clk = "mlb150_clk",
+ .mlb_pll_clk = "pll6",
+};
+
+static struct mxc_dvfs_platform_data arm2_dvfscore_data = {
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init mx6_arm2_fixup(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static int __init early_enable_sgtl5000(char *p)
+{
+ sgtl5000_en = 1;
+ return 0;
+}
+
+early_param("sgtl5000", early_enable_sgtl5000);
+
+static int __init early_enable_spdif(char *p)
+{
+ spdif_en = 1;
+ return 0;
+}
+
+early_param("spdif", early_enable_spdif);
+
+static int __init early_enable_can(char *p)
+{
+ flexcan_en = 1;
+ return 0;
+}
+
+early_param("flexcan", early_enable_can);
+
+static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1, /* enable tx */
+ .spdif_rx = 1, /* enable rx */
+ /*
+ * spdif0_clk will be 454.7MHz divided by ccm dividers.
+ *
+ * 44.1KHz: 454.7MHz / 7 (ccm) / 23 (spdif) = 44,128 Hz ~ 0.06% error
+ * 48KHz: 454.7MHz / 4 (ccm) / 37 (spdif) = 48,004 Hz ~ 0.01% error
+ * 32KHz: 454.7MHz / 6 (ccm) / 37 (spdif) = 32,003 Hz ~ 0.01% error
+ */
+ .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_div_44100 = 23,
+ .spdif_div_48000 = 37,
+ .spdif_div_32000 = 37,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static const struct imx_pcie_platform_data mx6_arm2_pcie_data __initconst = {
+ .pcie_pwr_en = MX6_ARM2_PCIE_PWR_EN,
+ .pcie_rst = MX6_ARM2_PCIE_RESET,
+ .pcie_wake_up = -EINVAL,
+ .pcie_dis = -EINVAL,
+};
+
+static int __init early_disable_mipi_dsi(char *p)
+{
+ /*enable on board HDMI*/
+ /*mulplex pin with mipi disp0_reset we should disable mipi reset*/
+ disable_mipi_dsi = 1;
+ return 0;
+}
+
+early_param("disable_mipi_dsi", early_disable_mipi_dsi);
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_arm2_init(void)
+{
+ int i;
+ int ret;
+
+ iomux_v3_cfg_t *common_pads = NULL;
+ iomux_v3_cfg_t *esai_rec_pads = NULL;
+ iomux_v3_cfg_t *spdif_pads = NULL;
+ iomux_v3_cfg_t *flexcan_pads = NULL;
+ iomux_v3_cfg_t *i2c3_pads = NULL;
+ iomux_v3_cfg_t *epdc_pads = NULL;
+
+ int common_pads_cnt;
+ int esai_rec_pads_cnt;
+ int spdif_pads_cnt;
+ int flexcan_pads_cnt;
+ int i2c3_pads_cnt;
+ int epdc_pads_cnt;
+
+
+ /*
+ * common pads: pads are non-shared with others on this board
+ * feature_pds: pads are shared with others on this board
+ */
+
+ if (cpu_is_mx6q()) {
+ common_pads = mx6q_arm2_pads;
+ esai_rec_pads = mx6q_arm2_esai_record_pads;
+ spdif_pads = mx6q_arm2_spdif_pads;
+ flexcan_pads = mx6q_arm2_can_pads;
+ i2c3_pads = mx6q_arm2_i2c3_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6q_arm2_pads);
+ esai_rec_pads_cnt = ARRAY_SIZE(mx6q_arm2_esai_record_pads);
+ spdif_pads_cnt = ARRAY_SIZE(mx6q_arm2_spdif_pads);
+ flexcan_pads_cnt = ARRAY_SIZE(mx6q_arm2_can_pads);
+ i2c3_pads_cnt = ARRAY_SIZE(mx6q_arm2_i2c3_pads);
+ } else if (cpu_is_mx6dl()) {
+ common_pads = mx6dl_arm2_pads;
+ esai_rec_pads = mx6dl_arm2_esai_record_pads;
+ spdif_pads = mx6dl_arm2_spdif_pads;
+ flexcan_pads = mx6dl_arm2_can_pads;
+ i2c3_pads = mx6dl_arm2_i2c3_pads;
+ epdc_pads = mx6dl_arm2_epdc_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6dl_arm2_pads);
+ esai_rec_pads_cnt = ARRAY_SIZE(mx6dl_arm2_esai_record_pads);
+ spdif_pads_cnt = ARRAY_SIZE(mx6dl_arm2_spdif_pads);
+ flexcan_pads_cnt = ARRAY_SIZE(mx6dl_arm2_can_pads);
+ i2c3_pads_cnt = ARRAY_SIZE(mx6dl_arm2_i2c3_pads);
+ epdc_pads_cnt = ARRAY_SIZE(mx6dl_arm2_epdc_pads);
+ }
+
+ BUG_ON(!common_pads);
+ mxc_iomux_v3_setup_multiple_pads(common_pads, common_pads_cnt);
+
+ if (esai_record) {
+ BUG_ON(!esai_rec_pads);
+ mxc_iomux_v3_setup_multiple_pads(esai_rec_pads,
+ esai_rec_pads_cnt);
+ }
+
+ /*
+ * IEEE-1588 ts_clk, S/PDIF in and i2c3 are mutually exclusive
+ * because all of them use GPIO_16.
+ * S/PDIF out and can1 stby are mutually exclusive because both
+ * use GPIO_17.
+ */
+#ifndef CONFIG_FEC_1588
+ if (spdif_en) {
+ BUG_ON(!spdif_pads);
+ mxc_iomux_v3_setup_multiple_pads(spdif_pads, spdif_pads_cnt);
+ } else {
+ BUG_ON(!i2c3_pads);
+ mxc_iomux_v3_setup_multiple_pads(i2c3_pads, i2c3_pads_cnt);
+ }
+#else
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
+ if (!spdif_en && flexcan_en) {
+ BUG_ON(!flexcan_pads);
+ mxc_iomux_v3_setup_multiple_pads(flexcan_pads,
+ flexcan_pads_cnt);
+ }
+
+ /*
+ * the following is the common devices support on the shared ARM2 boards
+ * Since i.MX6DQ/DL share the same memory/Register layout, we don't
+ * need to diff the i.MX6DQ or i.MX6DL here. We can simply use the
+ * mx6q_add_features() for the shared devices. For which only exist
+ * on each indivual SOC, we can use cpu_is_mx6q/6dl() to diff it.
+ */
+
+ gp_reg_id = arm2_dvfscore_data.reg_id;
+ soc_reg_id = arm2_dvfscore_data.soc_id;
+ pu_reg_id = arm2_dvfscore_data.pu_id;
+ mx6_arm2_init_uart();
+
+
+ imx6q_add_mipi_csi2(&mipi_csi2_pdata);
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ if (cpu_is_mx6q())
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+
+ if (cpu_is_mx6dl()) {
+ mipi_dsi_pdata.ipu_id = 0;
+ mipi_dsi_pdata.disp_id = 1;
+ ldb_data.ipu_id = 0;
+ ldb_data.disp_id = 0;
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data) / 2; i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+ }
+
+ if (!disable_mipi_dsi)
+ imx6q_add_mipi_dsi(&mipi_dsi_pdata);
+ imx6q_add_vdoa();
+ imx6q_add_lcdif(&lcdif_data);
+ imx6q_add_ldb(&ldb_data);
+ imx6q_add_v4l2_output(0);
+ imx6q_add_v4l2_capture(0, &capture_data[0]);
+ imx6q_add_v4l2_capture(1, &capture_data[1]);
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_caam();
+
+ imx6q_add_imx_i2c(0, &mx6_arm2_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_arm2_i2c1_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ if (!spdif_en) {
+ if (disable_mipi_dsi)
+ mx6_arm2_i2c2_data.bitrate = 100000;
+ imx6q_add_imx_i2c(2, &mx6_arm2_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+ }
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6_arm2_spi_data);
+ spi_device_init();
+
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6_arm2_anatop_thermal_data);
+
+ if (!esai_record) {
+ imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+ }
+
+ imx6q_add_pm_imx(0, &mx6_arm2_pm_data);
+ imx6q_add_sdhci_usdhc_imx(3, &mx6_arm2_sd4_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_arm2_sd3_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6_gpu_pdata);
+ if (cpu_is_mx6q())
+ imx6q_add_ahci(0, &mx6_arm2_sata_data);
+ imx6q_add_vpu();
+ mx6_arm2_init_usb();
+ mx6_arm2_init_audio();
+ platform_device_register(&arm2_vmmc_reg_devices);
+ mx6_cpu_regulator_init();
+
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
+ /* DISP0 Reset - Assert for i2c disabled mode */
+ gpio_request(MX6_ARM2_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(MX6_ARM2_DISP0_RESET, 0);
+
+ /* DISP0 I2C enable */
+ if (!disable_mipi_dsi) {
+ gpio_request(MX6_ARM2_DISP0_I2C_EN, "disp0-i2c");
+ gpio_direction_output(MX6_ARM2_DISP0_I2C_EN, 0);
+ }
+ gpio_request(MX6_ARM2_DISP0_PWR, "disp0-pwr");
+ gpio_direction_output(MX6_ARM2_DISP0_PWR, 1);
+
+ gpio_request(MX6_ARM2_LDB_BACKLIGHT, "ldb-backlight");
+ gpio_direction_output(MX6_ARM2_LDB_BACKLIGHT, 1);
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+ imx6q_add_gpmi(&mx6_gpmi_nand_platform_data);
+
+ imx6q_add_dvfs_core(&arm2_dvfscore_data);
+
+ imx6q_add_ion(0, &imx_ion_data,
+ sizeof(imx_ion_data) + sizeof(struct ion_platform_heap));
+
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_arm2_pwm_backlight_data);
+
+ if (spdif_en) {
+ mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0", NULL);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ imx6q_add_spdif(&mxc_spdif_data);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+ } else if (flexcan_en) {
+ ret = gpio_request_array(mx6_flexcan_gpios,
+ ARRAY_SIZE(mx6_flexcan_gpios));
+ if (ret) {
+ pr_err("failed to request flexcan-gpios: %d\n", ret);
+ } else {
+ imx6q_add_flexcan0(&mx6_arm2_flexcan_pdata[0]);
+ imx6q_add_flexcan1(&mx6_arm2_flexcan_pdata[1]);
+ }
+ }
+
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+ imx6q_add_mlb150(&mx6_arm2_mlb150_data);
+
+ if (cpu_is_mx6dl() && epdc_enabled) {
+ BUG_ON(!epdc_pads);
+ mxc_iomux_v3_setup_multiple_pads(epdc_pads, epdc_pads_cnt);
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+ mxc_register_device(&max17135_sensor_device, NULL);
+ imx6dl_add_imx_epdc(&epdc_data);
+ }
+ /* Add PCIe RC interface support */
+ imx6q_add_pcie(&mx6_arm2_pcie_data);
+ imx6q_add_busfreq();
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART4_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6_arm2_reserve(void)
+{
+ phys_addr_t phys;
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ if (imx6_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(
+ imx6_gpu_pdata.reserved_mem_size, SZ_4K, SZ_2G);
+ memblock_remove(phys, imx6_gpu_pdata.reserved_mem_size);
+ imx6_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+
+#if defined(CONFIG_ION)
+ if (imx_ion_data.heaps[0].size) {
+ phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K);
+ memblock_free(phys, imx_ion_data.heaps[0].size);
+ memblock_remove(phys, imx_ion_data.heaps[0].size);
+ imx_ion_data.heaps[0].base = phys;
+ }
+#endif
+}
+
+MACHINE_START(MX6Q_ARM2, "Freescale i.MX 6Quad/Solo/DualLite Armadillo2 Board")
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = mx6_arm2_fixup,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_arm2_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_arm2_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.h b/arch/arm/mach-mx6/board-mx6q_arm2.h
new file mode 100644
index 00000000..2a6a2052
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2012, 2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6q.h>
+
+static iomux_v3_cfg_t mx6q_arm2_pads[] = {
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6Q_PAD_KEY_COL1__ENET_MDIO,
+ MX6Q_PAD_KEY_COL2__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+#ifdef CONFIG_FEC_1588
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#endif
+#endif
+ /* MCLK for csi0 */
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ MX6Q_PAD_GPIO_3__CCM_CLKO2,
+
+ /* SD1 */
+ MX6Q_PAD_SD1_CLK__USDHC1_CLK,
+ MX6Q_PAD_SD1_CMD__USDHC1_CMD,
+ MX6Q_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6Q_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6Q_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6Q_PAD_SD1_DAT3__USDHC1_DAT3,
+ /* SD2 */
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ /* SD3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6Q_PAD_SD3_RST__USDHC3_RST,
+ /* SD3 VSelect */
+ MX6Q_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6Q_PAD_NANDF_CS0__GPIO_6_11,
+ MX6Q_PAD_NANDF_CS1__GPIO_6_14,
+ /* SD4 */
+ MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+ MX6Q_PAD_NANDF_ALE__USDHC4_RST,
+ /* eCSPI1 */
+ MX6Q_PAD_EIM_EB2__ECSPI1_SS0,
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO,
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6Q_PAD_EIM_D19__ECSPI1_SS1,
+ MX6Q_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
+ MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ESAI */
+ MX6Q_PAD_ENET_RXD0__ESAI1_HCKT,
+ MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6Q_PAD_ENET_RXD1__ESAI1_FST,
+ MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3,
+ MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6Q_PAD_NANDF_CS2__ESAI1_TX0,
+ MX6Q_PAD_NANDF_CS3__ESAI1_TX1,
+
+ /* I2C1 */
+ MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL,
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ MX6Q_PAD_EIM_D24__GPIO_3_24,
+
+ /* UART2 */
+ MX6Q_PAD_EIM_D26__UART2_RXD,
+ MX6Q_PAD_EIM_D27__UART2_TXD,
+ MX6Q_PAD_EIM_D28__UART2_RTS,
+ MX6Q_PAD_EIM_D29__UART2_CTS,
+
+ /* PWM1 */
+ MX6Q_PAD_GPIO_9__PWM1_PWMO,
+
+ /* DISP0 DET */
+ MX6Q_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+ MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
+ MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* MLB150 */
+ MX6Q_PAD_GPIO_3__MLB_MLBCLK,
+ MX6Q_PAD_GPIO_6__MLB_MLBSIG,
+ MX6Q_PAD_GPIO_2__MLB_MLBDAT,
+#endif
+};
+
+static iomux_v3_cfg_t mx6q_arm2_i2c3_pads[] = {
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_spdif_pads[] = {
+ /* SPDIF */
+ MX6Q_PAD_GPIO_16__SPDIF_IN1,
+ MX6Q_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_can_pads[] = {
+ /* CAN1 */
+ MX6Q_PAD_GPIO_7__CAN1_TXCAN,
+ MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6Q_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
+ MX6Q_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
+
+ /* CAN2 */
+ MX6Q_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6Q_PAD_KEY_ROW4__CAN2_RXCAN,
+ MX6Q_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
+};
+
+static iomux_v3_cfg_t mx6q_arm2_esai_record_pads[] = {
+ MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR,
+ MX6Q_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_csi0_sensor_pads[] = {
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_csi0_tvin_pads[] = {
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_CSI0_DAT7__GPIO_5_25,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_mipi_sensor_pads[] = {
+ MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_audmux_pads[] = {
+
+ /* AUDMUX */
+ MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+};
+
+#define MX6Q_USDHC_PAD_SETTING(id, speed) \
+mx6q_sd##id##_##speed##mhz[] = { \
+ MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 200);
+
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
+ MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6Q_PAD_NANDF_D0__RAWNAND_D0,
+ MX6Q_PAD_NANDF_D1__RAWNAND_D1,
+ MX6Q_PAD_NANDF_D2__RAWNAND_D2,
+ MX6Q_PAD_NANDF_D3__RAWNAND_D3,
+ MX6Q_PAD_NANDF_D4__RAWNAND_D4,
+ MX6Q_PAD_NANDF_D5__RAWNAND_D5,
+ MX6Q_PAD_NANDF_D6__RAWNAND_D6,
+ MX6Q_PAD_NANDF_D7__RAWNAND_D7,
+ MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_hdmi_ddc_pads[] = {
+ MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6q_arm2_i2c2_pads[] = {
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
diff --git a/arch/arm/mach-mx6/board-mx6q_hdmidongle.c b/arch/arm/mach-mx6/board-mx6q_hdmidongle.c
new file mode 100644
index 00000000..ffd8d9af
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_hdmidongle.c
@@ -0,0 +1,800 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#ifdef CONFIG_MFD_WM831X
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#include <linux/mfd/wm831x/regulator.h>
+#include <linux/mfd/wm831x/gpio.h>
+#endif
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6q_hdmidongle.h"
+#include "board-mx6dl_hdmidongle.h"
+
+#define HDMIDONGLE_USB_OTG_PWR IMX_GPIO_NR(4, 15)
+#define HDMIDONGLE_USB_H1_PWR IMX_GPIO_NR(4, 14)
+#define HDMIDONGLE_ECSPI2_CS0 IMX_GPIO_NR(2, 26)
+#define HDMIDONGLE_HDMI_CEC_IN IMX_GPIO_NR(4, 11)
+
+
+#define HDMIDONGLE_BT_RST IMX_GPIO_NR(3, 7)
+#define HDMIDONGLE_BT_EN IMX_GPIO_NR(3, 9)
+#define HDMIDONGLE_WL_EN IMX_GPIO_NR(3, 10)
+
+#define HDMIDONGLE_SD2_CD IMX_GPIO_NR(1, 4)
+#define HDMIDONGLE_REVA_POWER_KEY IMX_GPIO_NR(6, 16)
+#define HDMIDONGLE_REVB_POWER_KEY IMX_GPIO_NR(1, 27)
+
+#ifdef CONFIG_IMX_PCIE
+#define HDMIDONGLE_PCIE_PWR_EN IMX_GPIO_NR(3, 7) /*fake pcie power enable */
+#define HDMIDONGLE_PCIE_RST IMX_GPIO_NR(3, 9)
+#define HDMIDONGLE_PCIE_WAKE IMX_GPIO_NR(3, 22)
+#define HDMIDONGLE_PCIE_DIS IMX_GPIO_NR(3, 10)
+#endif
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+
+static const struct esdhc_platform_data mx6q_hdmidongle_sd1_data __initconst = {
+ .always_present = 1,
+};
+
+static const struct esdhc_platform_data mx6q_hdmidongle_sd2_data __initconst = {
+ .cd_gpio = HDMIDONGLE_SD2_CD,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_CONTROLLER,
+};
+
+static const struct esdhc_platform_data mx6q_hdmidongle_sd3_data __initconst = {
+ .always_present = 1,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+static const struct esdhc_platform_data mx6q_hdmidongle_revc_sd3_data __initconst = {
+ .always_present = 1,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 0,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+
+static int __init gpmi_nand_platform_init(void)
+{
+ iomux_v3_cfg_t *nand_pads = NULL;
+ u32 nand_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ nand_pads = mx6q_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6q_gpmi_nand);
+ } else if (cpu_is_mx6dl()) {
+ nand_pads = mx6dl_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+
+ }
+ BUG_ON(!nand_pads);
+ return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt);
+}
+
+static struct gpmi_nand_platform_data
+mx6_gpmi_nand_platform_data __initdata = {
+ .platform_init = gpmi_nand_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+ .enable_bbt = 1,
+ .enable_ddr = 0,
+};
+
+static int __init board_support_onfi_nand(char *p)
+{
+ mx6_gpmi_nand_platform_data.enable_ddr = 1;
+ return 0;
+}
+
+early_param("onfi_support", board_support_onfi_nand);
+
+
+static const struct anatop_thermal_platform_data
+ mx6q_hdmidongle_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static inline void mx6q_hdmidongle_init_uart(void)
+{
+ if (board_is_mx6_reva())
+ imx6q_add_imx_uart(1, NULL);
+ imx6q_add_imx_uart(0, NULL);
+ imx6q_add_imx_uart(3, NULL);
+}
+
+static int mx6q_hdmidongle_spi_cs[] = {
+ HDMIDONGLE_ECSPI2_CS0,
+};
+
+static const struct spi_imx_master mx6q_hdmidongle_spi_data __initconst = {
+ .chipselect = mx6q_hdmidongle_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6q_hdmidongle_spi_cs),
+};
+
+
+
+#ifdef CONFIG_MFD_WM831X
+#if 0
+/* 1.4125, 1.4125. 1.5 */
+#define WM831X_DC1_ON_CONFIG_VAL (0x48<<WM831X_DC1_ON_VSEL_SHIFT)
+#define WM831X_DC2_ON_CONFIG_VAL (0x48<<WM831X_DC2_ON_VSEL_SHIFT)
+#define WM831X_DC3_ON_CONFIG_VAL (0x1A<<WM831X_DC3_ON_VSEL_SHIFT)
+#else
+/* 1.375, 1.375. 1.5 */
+
+#define WM831X_DC1_ON_CONFIG_VAL (0x44<<WM831X_DC1_ON_VSEL_SHIFT)
+#define WM831X_DC2_ON_CONFIG_VAL (0x44<<WM831X_DC2_ON_VSEL_SHIFT)
+#define WM831X_DC3_ON_CONFIG_VAL (0x1A<<WM831X_DC3_ON_VSEL_SHIFT)
+
+#endif
+
+#define WM831X_DC1_DVS_MODE_VAL (0x02<<WM831X_DC1_DVS_SRC_SHIFT)
+#define WM831X_DC2_DVS_MODE_VAL (0x02<<WM831X_DC2_DVS_SRC_SHIFT)
+
+#define WM831X_DC1_DVS_CONTROL_VAL (0x20<<WM831X_DC1_DVS_VSEL_SHIFT)
+#define WM831X_DC2_DVS_CONTROL_VAL (0x20<<WM831X_DC2_DVS_VSEL_SHIFT)
+
+#define WM831X_DC1_DVS_MASK (WM831X_DC1_DVS_SRC_MASK|WM831X_DC1_DVS_VSEL_MASK)
+#define WM831X_DC2_DVS_MASK (WM831X_DC2_DVS_SRC_MASK|WM831X_DC1_DVS_VSEL_MASK)
+
+#define WM831X_DC1_DVS_VAL (WM831X_DC1_DVS_MODE_VAL|WM831X_DC1_DVS_CONTROL_VAL)
+#define WM831X_DC2_DVS_VAL (WM831X_DC2_DVS_MODE_VAL|WM831X_DC2_DVS_CONTROL_VAL)
+
+#define WM831X_GPN_FN_VAL_HW_EN (0x0A<<WM831X_GPN_FN_SHIFT)
+#define WM831X_GPN_FN_VAL_HW_CTL (0x0C<<WM831X_GPN_FN_SHIFT)
+#define WM831X_GPN_FN_VAL_DVS1 (0x08<<WM831X_GPN_FN_SHIFT)
+
+#define WM831X_GPN_DIR_VAL (0x1<<WM831X_GPN_DIR_SHIFT)
+#define WM831X_GPN_PULL_VAL (0x3<<WM831X_GPN_PULL_SHIFT)
+#define WM831X_GPN_INT_MODE_VAL (0x1<<WM831X_GPN_INT_MODE_SHIFT)
+#define WM831X_GPN_POL_VAL (0x1<<WM831X_GPN_POL_SHIFT)
+#define WM831X_GPN_ENA_VAL (0x1<<WM831X_GPN_ENA_SHIFT)
+
+#define WM831X_GPIO7_8_9_MASK (WM831X_GPN_DIR_MASK|WM831X_GPN_INT_MODE_MASK|WM831X_GPN_PULL_MASK|WM831X_GPN_POL_MASK|WM831X_GPN_FN_MASK)
+
+
+#define WM831X_GPIO7_VAL (WM831X_GPN_DIR_VAL|WM831X_GPN_PULL_VAL|WM831X_GPN_INT_MODE_VAL|WM831X_GPN_POL_VAL|WM831X_GPN_ENA_VAL|WM831X_GPN_FN_VAL_HW_EN)
+#define WM831X_GPIO8_VAL (WM831X_GPN_DIR_VAL|WM831X_GPN_PULL_VAL|WM831X_GPN_INT_MODE_VAL|WM831X_GPN_POL_VAL|WM831X_GPN_ENA_VAL|WM831X_GPN_FN_VAL_HW_CTL)
+#define WM831X_GPIO9_VAL (WM831X_GPN_DIR_VAL|WM831X_GPN_PULL_VAL|WM831X_GPN_INT_MODE_VAL|WM831X_GPN_POL_VAL|WM831X_GPN_ENA_VAL|WM831X_GPN_FN_VAL_DVS1)
+
+#define WM831X_STATUS_LED_MASK 0xC000
+#define WM831X_STATUS_LED_ON (0x1 << 14)
+#define WM831X_STATUS_LED_OFF (0x0 << 14)
+
+static int wm8326_post_init(struct wm831x *wm831x)
+{
+ wm831x_set_bits(wm831x, WM831X_DC1_ON_CONFIG, WM831X_DC1_ON_VSEL_MASK, WM831X_DC1_ON_CONFIG_VAL);
+ wm831x_set_bits(wm831x, WM831X_DC2_ON_CONFIG, WM831X_DC2_ON_VSEL_MASK, WM831X_DC2_ON_CONFIG_VAL);
+ wm831x_set_bits(wm831x, WM831X_DC3_ON_CONFIG, WM831X_DC3_ON_VSEL_MASK, WM831X_DC3_ON_CONFIG_VAL);
+
+ wm831x_set_bits(wm831x, WM831X_DC1_DVS_CONTROL, WM831X_DC1_DVS_MASK, WM831X_DC1_DVS_VAL);
+ wm831x_set_bits(wm831x, WM831X_DC2_DVS_CONTROL, WM831X_DC2_DVS_MASK, WM831X_DC2_DVS_VAL);
+
+ wm831x_set_bits(wm831x, WM831X_GPIO7_CONTROL, WM831X_GPIO7_8_9_MASK, WM831X_GPIO7_VAL);
+ wm831x_set_bits(wm831x, WM831X_GPIO8_CONTROL, WM831X_GPIO7_8_9_MASK, WM831X_GPIO8_VAL);
+ wm831x_set_bits(wm831x, WM831X_GPIO9_CONTROL, WM831X_GPIO7_8_9_MASK, WM831X_GPIO9_VAL);
+
+ wm831x_set_bits(wm831x, WM831X_STATUS_LED_1 , WM831X_STATUS_LED_MASK, WM831X_STATUS_LED_OFF);
+ wm831x_set_bits(wm831x, WM831X_STATUS_LED_2 , WM831X_STATUS_LED_MASK, WM831X_STATUS_LED_ON);
+ return 0;
+}
+
+static struct wm831x_pdata hdmidongle_wm8326_pdata = {
+ .post_init = wm8326_post_init,
+};
+#endif
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+#ifdef CONFIG_MFD_WM831X
+ I2C_BOARD_INFO("wm8326", 0x34),
+ .platform_data = &hdmidongle_wm8326_pdata,
+#endif
+ },
+};
+
+static struct spi_board_info wm8326_spi1_board_info[] __initdata = {
+#if defined(CONFIG_MFD_WM831X_SPI)
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "wm8326",
+ .max_speed_hz = 20000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(wm8326_spi1_board_info,
+ ARRAY_SIZE(wm8326_spi1_board_info));
+}
+
+static struct imxi2c_platform_data mx6q_hdmidongle_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ },
+};
+
+
+static void imx6q_hdmidongle_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(HDMIDONGLE_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(HDMIDONGLE_USB_OTG_PWR, 0);
+}
+
+static void __init imx6q_hdmidongle_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+ /* disable external charger detect,
+ * or it will affect signal quality at dp .
+ */
+ ret = gpio_request(HDMIDONGLE_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO HDMIDONGLE_USB_OTG_PWR: %d\n",
+ ret);
+ return;
+ }
+ gpio_direction_output(HDMIDONGLE_USB_OTG_PWR, 0);
+ /* keep USB host1 VBUS always on */
+ if (board_is_mx6_reva()) {
+ ret = gpio_request(HDMIDONGLE_USB_H1_PWR, "usb-h1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO HDMIDONGLE_USB_H1_PWR: %d\n",
+ ret);
+ return;
+ }
+ gpio_direction_output(HDMIDONGLE_USB_H1_PWR, 1);
+ }
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+
+ mx6_set_otghost_vbus_func(imx6q_hdmidongle_usbotg_vbus);
+}
+
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M,
+};
+
+
+static struct ipuv3_fb_platform_data hdmidongle_fb_data[] = {
+ {/*fb0*/
+ .disp_dev = "hdmi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "1920x1080M@60",
+ .default_bpp = 32,
+ .int_clk = false,
+ },
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+ /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+ if (hdmi_SDMA_check())
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+/* On mx6x sabresd board i2c2 iomux with hdmi ddc,
+ * the pins default work at i2c2 function,
+ when hdcp enable, the pins should work at ddc function */
+
+static void hdmi_enable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6dl_hdmidongle_hdmi_ddc_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6q_hdmidongle_hdmi_ddc_pads));
+}
+
+static void hdmi_disable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_i2c2_pads,
+ ARRAY_SIZE(mx6dl_hdmidongle_i2c2_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_i2c2_pads,
+ ARRAY_SIZE(mx6q_hdmidongle_i2c2_pads));
+}
+
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+ .enable_pins = hdmi_enable_ddc_pin,
+ .disable_pins = hdmi_disable_ddc_pin,
+ .phy_reg_vlev = 0x0294,
+ .phy_reg_cksymtx = 0x800d,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ },
+};
+
+static void hdmidongle_suspend_enter(void)
+{
+ /* suspend preparation */
+}
+
+static void hdmidongle_suspend_exit(void)
+{
+ /* resume restore */
+}
+static const struct pm_platform_data mx6q_hdmidongle_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = hdmidongle_suspend_enter,
+ .suspend_exit = hdmidongle_suspend_exit,
+};
+
+static struct regulator_consumer_supply hdmidongle_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data hdmidongle_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(hdmidongle_vmmc_consumers),
+ .consumer_supplies = hdmidongle_vmmc_consumers,
+};
+
+static struct fixed_voltage_config hdmidongle_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &hdmidongle_vmmc_init,
+};
+
+static struct platform_device hdmidongle_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &hdmidongle_vmmc_reg_config,
+ },
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+ .debounce_interval = debounce, \
+}
+
+static struct gpio_keys_button hdmidongle_reva_buttons[] = {
+ GPIO_BUTTON(HDMIDONGLE_REVA_POWER_KEY, KEY_POWER, 1, "power", 1, 1),
+};
+
+static struct gpio_keys_platform_data hdmidongle_reva_button_data = {
+ .buttons = hdmidongle_reva_buttons,
+ .nbuttons = ARRAY_SIZE(hdmidongle_reva_buttons),
+};
+
+static struct platform_device hdmidongle_reva_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &hdmidongle_reva_button_data,
+ }
+};
+
+static struct gpio_keys_button hdmidongle_revb_buttons[] = {
+ GPIO_BUTTON(HDMIDONGLE_REVB_POWER_KEY, KEY_POWER, 1, "power", 1, 1),
+};
+
+static struct gpio_keys_platform_data hdmidongle_revb_button_data = {
+ .buttons = hdmidongle_revb_buttons,
+ .nbuttons = ARRAY_SIZE(hdmidongle_revb_buttons),
+};
+
+static struct platform_device hdmidongle_revb_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &hdmidongle_revb_button_data,
+ }
+};
+
+
+static void __init imx6q_add_device_buttons(void)
+{
+ if (board_is_mx6_reva())
+ platform_device_register(&hdmidongle_reva_button_device);
+ else
+ platform_device_register(&hdmidongle_revb_button_device);
+}
+#else
+static void __init imx6q_add_device_buttons(void) {}
+#endif
+
+static struct mxc_dvfs_platform_data hdmidongle_dvfscore_data = {
+ #ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ #else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+ #endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ char *str;
+ struct tag *t;
+ int i = 0;
+ struct ipuv3_fb_platform_data *pdata_fb = hdmidongle_fb_data;
+
+ for_each_tag(t, tags) {
+ if (t->hdr.tag == ATAG_CMDLINE) {
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "fbmem=");
+ if (str != NULL) {
+ str += 6;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ while (*str == ',' &&
+ i < ARRAY_SIZE(hdmidongle_fb_data)) {
+ str++;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ }
+ }
+ break;
+ }
+ }
+}
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+ u32 value;
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /*set TOP and DP_EN bit*/
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+#ifdef CONFIG_IMX_PCIE
+static const struct imx_pcie_platform_data mx6_hdmidongle_pcie_data __initconst = {
+ .pcie_pwr_en = HDMIDONGLE_PCIE_PWR_EN,
+ .pcie_rst = HDMIDONGLE_PCIE_RST,
+ .pcie_wake_up = HDMIDONGLE_PCIE_WAKE,
+ .pcie_dis = HDMIDONGLE_PCIE_DIS,
+};
+#endif
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_hdmidongle_board_init(void)
+{
+ int i;
+
+ if (cpu_is_mx6q()) {
+ if (board_is_mx6_revb() || board_is_mx6_revc())
+ mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_rev_b_pads,
+ ARRAY_SIZE(mx6q_hdmidongle_rev_b_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_rev_a_pads,
+ ARRAY_SIZE(mx6q_hdmidongle_rev_a_pads));
+ } else if (cpu_is_mx6dl()) {
+ if (board_is_mx6_revb() || board_is_mx6_revc())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_rev_b_pads,
+ ARRAY_SIZE(mx6dl_hdmidongle_rev_b_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_rev_a_pads,
+ ARRAY_SIZE(mx6dl_hdmidongle_rev_a_pads));
+ }
+
+ gp_reg_id = hdmidongle_dvfscore_data.reg_id;
+ soc_reg_id = hdmidongle_dvfscore_data.soc_id;
+ pu_reg_id = hdmidongle_dvfscore_data.pu_id;
+ mx6q_hdmidongle_init_uart();
+
+ /*
+ * MX6DL/Solo only supports single IPU
+ * The following codes are used to change ipu id
+ * and display id information for MX6DL/Solo. Then
+ * register 1 IPU device and up to 2 displays for
+ * MX6DL/Solo
+ */
+ if (cpu_is_mx6dl())
+ hdmi_core_data.disp_id = 0;
+
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ if (cpu_is_mx6q())
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+ for (i = 0; i < ARRAY_SIZE(hdmidongle_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &hdmidongle_fb_data[i]);
+
+ imx6q_add_vdoa();
+
+ imx6q_add_v4l2_output(0);
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_i2c(1, &mx6q_hdmidongle_i2c_data);
+ imx6q_add_imx_i2c(2, &mx6q_hdmidongle_i2c_data);
+
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+
+
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+
+ /* SPI */
+ imx6q_add_ecspi(1, &mx6q_hdmidongle_spi_data);
+ spi_device_init();
+
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6q_hdmidongle_anatop_thermal_data);
+ imx6q_add_pm_imx(0, &mx6q_hdmidongle_pm_data);
+ /* Move sd3 to first because sd3 connect to emmc.
+ Mfgtools want emmc is mmcblk0 and other sd card is mmcblk1.
+ */
+ if (board_is_mx6_revc())
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_hdmidongle_revc_sd3_data);
+ else
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_hdmidongle_sd3_data);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6q_hdmidongle_sd2_data);
+ if (board_is_mx6_reva())
+ imx6q_add_sdhci_usdhc_imx(0, &mx6q_hdmidongle_sd1_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6q_hdmidongle_init_usb();
+
+ imx6q_add_vpu();
+
+ platform_device_register(&hdmidongle_vmmc_reg_devices);
+
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+ if (board_is_mx6_revb() || board_is_mx6_revc())
+ imx6q_add_gpmi(&mx6_gpmi_nand_platform_data);
+
+ imx6q_add_dvfs_core(&hdmidongle_dvfscore_data);
+ #ifndef CONFIG_MX6_INTER_LDO_BYPASS
+ mx6_cpu_regulator_init();
+ #endif
+
+ imx6q_add_device_buttons();
+
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+
+ if (board_is_mx6_reva()) {
+ gpio_request(HDMIDONGLE_BT_RST, "bt_reset");
+ gpio_direction_output(HDMIDONGLE_BT_RST, 1);
+ gpio_set_value(HDMIDONGLE_BT_RST, 1);
+ msleep(1000);
+ gpio_request(HDMIDONGLE_BT_EN, "bt_en");
+ gpio_direction_output(HDMIDONGLE_BT_EN, 1);
+ gpio_set_value(HDMIDONGLE_BT_EN, 1);
+
+ msleep(1000);
+ gpio_request(HDMIDONGLE_WL_EN, "wl_en");
+ gpio_direction_output(HDMIDONGLE_WL_EN, 1);
+ gpio_set_value(HDMIDONGLE_WL_EN, 1);
+ msleep(1000);
+ } else if (board_is_mx6_revb() || board_is_mx6_revc()) {
+ /* Add PCIe RC interface support */
+#ifdef CONFIG_IMX_PCIE
+ imx6q_add_pcie(&mx6_hdmidongle_pcie_data);
+#endif
+ }
+ pm_power_off = mx6_snvs_poweroff;
+ imx6q_add_busfreq();
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_hdmidongle_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART4_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mx6_hdmidongle_timer = {
+ .init = mx6_hdmidongle_timer_init,
+};
+
+static void __init mx6q_hdmidongle_reserve(void)
+{
+ phys_addr_t phys;
+ int i;
+
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+#if defined(CONFIG_ION)
+ if (imx_ion_data.heaps[0].size) {
+ phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K);
+ memblock_remove(phys, imx_ion_data.heaps[0].size);
+ imx_ion_data.heaps[0].base = phys;
+ }
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(hdmidongle_fb_data); i++)
+ if (hdmidongle_fb_data[i].res_size[0]) {
+ /* reserve for background buffer */
+ phys = memblock_alloc(hdmidongle_fb_data[i].res_size[0],
+ SZ_4K);
+ memblock_remove(phys, hdmidongle_fb_data[i].res_size[0]);
+ hdmidongle_fb_data[i].res_base[0] = phys;
+ }
+}
+
+/*
+ * initialize __mach_desc_MX6Q_HDMIDONGLE data structure.
+ */
+MACHINE_START(MX6Q_HDMIDONGLE, "Freescale i.MX 6Quad/DualLite HDMI Dongle Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_hdmidongle_board_init,
+ .timer = &mx6_hdmidongle_timer,
+ .reserve = mx6q_hdmidongle_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_hdmidongle.h b/arch/arm/mach-mx6/board-mx6q_hdmidongle.h
new file mode 100644
index 00000000..9338c3e6
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_hdmidongle.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _BOARD_MX6Q_HDMIDONGLE_H
+#define _BOARD_MX6Q_HDMIDONGLE_H
+#include <mach/iomux-mx6q.h>
+
+static iomux_v3_cfg_t mx6q_hdmidongle_rev_a_pads[] = {
+ /* SPI2 for PMIC communication port */
+ MX6Q_PAD_EIM_OE__ECSPI2_MISO,
+ MX6Q_PAD_EIM_RW__ECSPI2_SS0,
+ MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
+ MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,
+
+ /*USB_OTG_DET(USB OTG cable plug detect) */
+ MX6Q_PAD_EIM_A16__GPIO_2_22,
+ /*BT_WAKEUP_HOST(Combo module BT wake-up output) */
+ MX6Q_PAD_EIM_A25__GPIO_5_2,
+ /* HOST_WAKEUP_BT(CPU wakeup BT signal)*/
+ MX6Q_PAD_EIM_D16__GPIO_3_16,
+
+ /* I2C3 */
+ MX6Q_PAD_EIM_D17__I2C3_SCL,
+ MX6Q_PAD_EIM_D18__I2C3_SDA,
+
+ /* USB OC pin */
+ MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC,
+ /* WLAN_WAKEUP_HOST(Combo module WLAN host wake-up output) */
+ MX6Q_PAD_EIM_D22__GPIO_3_22,
+
+ /* BT_UART2 */
+ MX6Q_PAD_EIM_D26__UART2_TXD,
+ MX6Q_PAD_EIM_D27__UART2_RXD,
+ MX6Q_PAD_EIM_D28__UART2_CTS,
+ MX6Q_PAD_EIM_D29__UART2_RTS,
+
+ /*BT_nRST(Combo module BT reset signal)*/
+ MX6Q_PAD_EIM_DA7__GPIO_3_7,
+
+ /*BT_REG_ON(Combo module BT Internal regulators power enable/disable)*/
+ MX6Q_PAD_EIM_DA9__GPIO_3_9,
+
+ /*WL_REG_ON(Combo module WLAN Internal regulators power enable/disable)*/
+ MX6Q_PAD_EIM_DA10__GPIO_3_10,
+
+ /* GPIO2 */
+ MX6Q_PAD_EIM_A22__GPIO_2_16, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A21__GPIO_2_17, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A20__GPIO_2_18, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A19__GPIO_2_19, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A18__GPIO_2_20, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A17__GPIO_2_21, /* Boot Mode Select */
+ MX6Q_PAD_EIM_RW__GPIO_2_26, /* Boot Mode Select */
+ MX6Q_PAD_EIM_LBA__GPIO_2_27, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB0__GPIO_2_28, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB1__GPIO_2_29, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB2__GPIO_2_30, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB3__GPIO_2_31, /* Boot Mode Select */
+
+ /* GPIO3 */
+ MX6Q_PAD_EIM_DA0__GPIO_3_0, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA1__GPIO_3_1, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA2__GPIO_3_2, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA3__GPIO_3_3, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA4__GPIO_3_4, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA5__GPIO_3_5, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA6__GPIO_3_6, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA8__GPIO_3_8, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA11__GPIO_3_11, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA12__GPIO_3_12, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA13__GPIO_3_13, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA14__GPIO_3_14, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA15__GPIO_3_15, /* Boot Mode Select */
+
+ /* GPIO5 */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A24__GPIO_5_4, /* Boot Mode Select */
+
+ /* GPIO6 */
+ MX6Q_PAD_EIM_A23__GPIO_6_6, /* Boot Mode Select */
+
+ /* I2C1 */
+ MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* UART1 for debug */
+ MX6Q_PAD_CSI0_DAT10__UART1_TXD,
+ MX6Q_PAD_CSI0_DAT11__UART1_RXD,
+
+ /* SD1 (Combo module WLAN SDIO )*/
+ MX6Q_PAD_SD1_CLK__USDHC1_CLK,
+ MX6Q_PAD_SD1_CMD__USDHC1_CMD,
+ MX6Q_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6Q_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6Q_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6Q_PAD_SD1_DAT3__USDHC1_DAT3,
+
+ /* SD2 (MicroSD SDIO CMD)*/
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ /*SD_DET (SD plug-in detect interrupt)*/
+ MX6Q_PAD_GPIO_4__GPIO_1_4,
+
+ /* SD3 (eMMC SDIO)*/
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6Q_PAD_SD3_RST__USDHC3_RST,
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+
+ /*HDMI CEC communication PIN*/
+ MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+
+ /* I2C2 */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* GPIO4[12] */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* GPIO4[13] */
+
+ /*DCDC5V_PWREN(5V DCDC BOOST control signal)*/
+ MX6Q_PAD_KEY_COL4__GPIO_4_14,
+
+ /*USB_OTG_PWREN(USB OTG power change control signal)*/
+ MX6Q_PAD_KEY_ROW4__GPIO_4_15,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+
+ /* I2C3 */
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+
+ /*WDOG(Watch dog output)*/
+ MX6Q_PAD_GPIO_9__GPIO_1_9,
+
+ /*PMIC_nINT(PMIC interrupt signal)*/
+ MX6Q_PAD_NANDF_CS0__GPIO_6_11,
+
+ /*GPIO_nRST(GPIO shutdown control)*/
+ MX6Q_PAD_NANDF_CS1__GPIO_6_14,
+
+ /*PWRKEY_DET(Power key press detection)*/
+ MX6Q_PAD_NANDF_CS3__GPIO_6_16,
+
+ /*CHG_SYS_ON(Charger auto power on control signal)*/
+ MX6Q_PAD_NANDF_D6__GPIO_2_6,
+
+ /*IR_RC*/
+ MX6Q_PAD_SD4_DAT6__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6q_hdmidongle_rev_b_pads[] = {
+ /* SPI2 for PMIC communication port */
+ MX6Q_PAD_EIM_OE__ECSPI2_MISO,
+ MX6Q_PAD_EIM_RW__ECSPI2_SS0,
+ MX6Q_PAD_EIM_CS0__ECSPI2_SCLK,
+ MX6Q_PAD_EIM_CS1__ECSPI2_MOSI,
+
+ /*USB_OTG_DET(USB OTG cable plug detect) */
+ MX6Q_PAD_EIM_A16__GPIO_2_22,
+ /*WLAN_CLKREQn*/
+ MX6Q_PAD_EIM_A25__GPIO_5_2,
+
+ /* WLAN_ACT */
+ MX6Q_PAD_EIM_D17__GPIO_3_17,
+
+ /*BT_PERI*/
+ MX6Q_PAD_EIM_D18__GPIO_3_18,
+
+ /* USB OC pin */
+ MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC,
+
+ /* WLAN_WAKEn (PM event, OD, used to reactivate the PCIe main PWR and REF CLK) */
+ MX6Q_PAD_EIM_D22__GPIO_3_22,
+
+
+ /*WLAN_PERSTn (PCIe rst signal, avtive LOW)*/
+ MX6Q_PAD_EIM_DA9__GPIO_3_9,
+
+ /*WLAN_PDn (Externally shutdown RTL8192)*/
+ MX6Q_PAD_EIM_DA10__GPIO_3_10,
+
+ /* GPIO2 */
+ MX6Q_PAD_EIM_A22__GPIO_2_16, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A21__GPIO_2_17, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A20__GPIO_2_18, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A19__GPIO_2_19, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A18__GPIO_2_20, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A17__GPIO_2_21, /* Boot Mode Select */
+ MX6Q_PAD_EIM_RW__GPIO_2_26, /* Boot Mode Select */
+ MX6Q_PAD_EIM_LBA__GPIO_2_27, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB0__GPIO_2_28, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB1__GPIO_2_29, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB2__GPIO_2_30, /* Boot Mode Select */
+ MX6Q_PAD_EIM_EB3__GPIO_2_31, /* Boot Mode Select */
+
+ /* GPIO3 */
+ MX6Q_PAD_EIM_DA0__GPIO_3_0, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA1__GPIO_3_1, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA2__GPIO_3_2, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA3__GPIO_3_3, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA4__GPIO_3_4, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA5__GPIO_3_5, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA6__GPIO_3_6, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA8__GPIO_3_8, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA11__GPIO_3_11, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA12__GPIO_3_12, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA13__GPIO_3_13, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA14__GPIO_3_14, /* Boot Mode Select */
+ MX6Q_PAD_EIM_DA15__GPIO_3_15, /* Boot Mode Select */
+
+ /* GPIO5 */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0, /* Boot Mode Select */
+ MX6Q_PAD_EIM_A24__GPIO_5_4, /* Boot Mode Select */
+
+ /* GPIO6 */
+ MX6Q_PAD_EIM_A23__GPIO_6_6, /* Boot Mode Select */
+
+
+ /* SD2 (MicroSD SDIO CMD)*/
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ /*SD_DET (SD plug-in detect interrupt)*/
+ MX6Q_PAD_GPIO_4__GPIO_1_4,
+
+ /* SD3 (eMMC SDIO)*/
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6Q_PAD_SD3_RST__USDHC3_RST,
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+
+ /*SD2_VSELECT (SD2 SDXC power exchange control signal)*/
+ MX6Q_PAD_KEY_ROW1__GPIO_4_9,
+
+ /*HDMI CEC communication PIN*/
+ MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+
+ /*PWRKEY_DET (Pwr button detection interrupt)*/
+ MX6Q_PAD_ENET_RXD0__GPIO_1_27,
+
+ /*USB_OTG_PWREN(USB OTG power change control signal)*/
+ MX6Q_PAD_KEY_ROW4__GPIO_4_15,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+
+ /* I2C2 */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* GPIO4[12] */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* GPIO4[13] */
+
+ /* I2C3 */
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+
+ /*WDOG(Watch dog output)*/
+ MX6Q_PAD_GPIO_9__GPIO_1_9,
+
+ /*PMIC_nINT(PMIC interrupt signal)*/
+ MX6Q_PAD_SD4_DAT3__GPIO_2_11,
+
+ /*GPIO_nRST(GPIO shutdown control)*/
+ MX6Q_PAD_SD4_DAT1__GPIO_2_9,
+
+ /*CHG_SYS_ON(Charger auto power on control signal)*/
+ MX6Q_PAD_SD4_DAT6__GPIO_2_14,
+};
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
+ MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6Q_PAD_NANDF_D0__RAWNAND_D0,
+ MX6Q_PAD_NANDF_D1__RAWNAND_D1,
+ MX6Q_PAD_NANDF_D2__RAWNAND_D2,
+ MX6Q_PAD_NANDF_D3__RAWNAND_D3,
+ MX6Q_PAD_NANDF_D4__RAWNAND_D4,
+ MX6Q_PAD_NANDF_D5__RAWNAND_D5,
+ MX6Q_PAD_NANDF_D6__RAWNAND_D6,
+ MX6Q_PAD_NANDF_D7__RAWNAND_D7,
+ MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6q_hdmidongle_hdmi_ddc_pads[] = {
+ MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6q_hdmidongle_i2c2_pads[] = {
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
+
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
new file mode 100644
index 00000000..01b07faf
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -0,0 +1,1764 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+#include <linux/spi/flash.h>
+#else
+#include <linux/mtd/physmap.h>
+#endif
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/ion.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mxc_asrc.h>
+#include <sound/pcm.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+#include <mach/mxc_asrc.h>
+#include <mach/mipi_dsi.h>
+#include <mach/mipi_csi2.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6q_sabreauto.h"
+#include "board-mx6solo_sabreauto.h"
+
+/* sorted by GPIO_NR */
+#define SABREAUTO_SD1_CD IMX_GPIO_NR(1, 1)
+#define SABREAUTO_ESAI_INT IMX_GPIO_NR(1, 10)
+#define SABREAUTO_ANDROID_HOME IMX_GPIO_NR(1, 11)
+#define SABREAUTO_ANDROID_BACK IMX_GPIO_NR(1, 12)
+#define SABREAUTO_SD3_WP IMX_GPIO_NR(1, 13)
+#define SABREAUTO_I2C_EXP_RST IMX_GPIO_NR(1, 15)
+#define SABREAUTO_USB_OTG_OC IMX_GPIO_NR(2, 8)
+#define SABREAUTO_LDB_BACKLIGHT3 IMX_GPIO_NR(2, 9)
+#define SABREAUTO_LDB_BACKLIGHT4 IMX_GPIO_NR(2, 10)
+#define SABREAUTO_ANDROID_MENU IMX_GPIO_NR(2, 12)
+#define SABREAUTO_ANDROID_VOLUP IMX_GPIO_NR(2, 15)
+#define SABREAUTO_CAP_TCH_INT IMX_GPIO_NR(2, 28)
+#define SABREAUTO_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define SABREAUTO_DISP0_PWR IMX_GPIO_NR(3, 24)
+#define SABREAUTO_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
+#define SABREAUTO_DISP0_DET_INT IMX_GPIO_NR(3, 31)
+#define SABREAUTO_DISP0_RESET IMX_GPIO_NR(5, 0)
+#define SABREAUTO_I2C3_STEER IMX_GPIO_NR(5, 4)
+#define SABREAUTO_WEIM_NOR_WDOG1 IMX_GPIO_NR(4, 29)
+#define SABREAUTO_ANDROID_VOLDOWN IMX_GPIO_NR(5, 14)
+#define SABREAUTO_PMIC_INT IMX_GPIO_NR(5, 16)
+#define SABREAUTO_ALS_INT IMX_GPIO_NR(5, 17)
+#define SABREAUTO_SD1_WP IMX_GPIO_NR(5, 20)
+#define SABREAUTO_USB_HOST1_OC IMX_GPIO_NR(5, 0)
+#define SABREAUTO_SD3_CD IMX_GPIO_NR(6, 15)
+
+#define SABREAUTO_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0)
+#define SABREAUTO_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
+#define SABREAUTO_MAX7310_3_BASE_ADDR IMX_GPIO_NR(8, 16)
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
+#define SABREAUTO_IO_EXP_GPIO1(x) (SABREAUTO_MAX7310_1_BASE_ADDR + (x))
+#define SABREAUTO_IO_EXP_GPIO2(x) (SABREAUTO_MAX7310_2_BASE_ADDR + (x))
+#define SABREAUTO_IO_EXP_GPIO3(x) (SABREAUTO_MAX7310_3_BASE_ADDR + (x))
+
+#define SABREAUTO_PCIE_RST_B_REVB (SABREAUTO_MAX7310_1_BASE_ADDR + 2)
+/*
+ * CAN2 STBY and EN lines are the same as the CAN1. These lines are not
+ * independent.
+ */
+#define SABREAUTO_PER_RST SABREAUTO_IO_EXP_GPIO1(3)
+#define SABREAUTO_VIDEOIN_PWR SABREAUTO_IO_EXP_GPIO2(2)
+#define SABREAUTO_CAN1_STEER SABREAUTO_IO_EXP_GPIO2(3)
+#define SABREAUTO_CAN_STBY SABREAUTO_IO_EXP_GPIO2(5)
+#define SABREAUTO_CAN_EN SABREAUTO_IO_EXP_GPIO2(6)
+#define SABREAUTO_USB_HOST1_PWR SABREAUTO_IO_EXP_GPIO2(7)
+#define SABREAUTO_USB_OTG_PWR SABREAUTO_IO_EXP_GPIO3(1)
+#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+
+static int mma8451_position = 3;
+static struct clk *sata_clk;
+static int mipi_sensor;
+static int can0_enable;
+static int uart3_en;
+static int tuner_en;
+static int spinor_en;
+static int weimnor_en;
+
+static int __init spinor_enable(char *p)
+{
+ spinor_en = 1;
+ return 0;
+}
+early_param("spi-nor", spinor_enable);
+
+static int __init weimnor_enable(char *p)
+{
+ weimnor_en = 1;
+ return 0;
+}
+early_param("weim-nor", weimnor_enable);
+
+static int __init uart3_enable(char *p)
+{
+ uart3_en = 1;
+ return 0;
+}
+early_param("uart3", uart3_enable);
+
+static int __init tuner_enable(char *p)
+{
+ tuner_en = 1;
+ return 0;
+}
+early_param("tuner", tuner_enable);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+}
+
+static struct gpio_keys_button ard_buttons[] = {
+ GPIO_BUTTON(SABREAUTO_ANDROID_HOME, KEY_HOME, 1, "home", 0),
+ GPIO_BUTTON(SABREAUTO_ANDROID_BACK, KEY_BACK, 1, "back", 0),
+ GPIO_BUTTON(SABREAUTO_ANDROID_MENU, KEY_MENU, 1, "menu", 0),
+ GPIO_BUTTON(SABREAUTO_ANDROID_VOLUP, KEY_VOLUMEUP, 1, "volume-up", 0),
+ GPIO_BUTTON(SABREAUTO_ANDROID_VOLDOWN, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static struct gpio_keys_platform_data ard_android_button_data = {
+ .buttons = ard_buttons,
+ .nbuttons = ARRAY_SIZE(ard_buttons),
+};
+
+static struct platform_device ard_android_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ard_android_button_data,
+ }
+};
+
+static void __init imx6q_add_android_device_buttons(void)
+{
+ platform_device_register(&ard_android_button_device);
+}
+#else
+static void __init imx6q_add_android_device_buttons(void) {}
+#endif
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ if (index != 2) {
+ printk(KERN_ERR"no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (cpu_is_mx6q()) {
+ sd_pads_200mhz = mx6q_sd3_200mhz;
+ sd_pads_100mhz = mx6q_sd3_100mhz;
+ sd_pads_50mhz = mx6q_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
+ } else if (cpu_is_mx6dl()) {
+ sd_pads_200mhz = mx6dl_sd3_200mhz;
+ sd_pads_100mhz = mx6dl_sd3_100mhz;
+ sd_pads_50mhz = mx6dl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6q_sabreauto_sd3_data __initconst = {
+ .cd_gpio = SABREAUTO_SD3_CD,
+ .wp_gpio = SABREAUTO_SD3_WP,
+ .keep_power_at_suspend = 1,
+ .support_18v = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6q_sabreauto_sd1_data __initconst = {
+ .cd_gpio = SABREAUTO_SD1_CD,
+ .wp_gpio = SABREAUTO_SD1_WP,
+ .keep_power_at_suspend = 1,
+};
+
+
+static int __init gpmi_nand_platform_init(void)
+{
+ iomux_v3_cfg_t *nand_pads = NULL;
+ u32 nand_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ nand_pads = mx6q_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6q_gpmi_nand);
+ } else if (cpu_is_mx6dl()) {
+ nand_pads = mx6dl_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+
+ }
+ BUG_ON(!nand_pads);
+ return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt);
+}
+
+static const struct gpmi_nand_platform_data
+mx6q_gpmi_nand_platform_data __initconst = {
+ .platform_init = gpmi_nand_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+};
+
+static const struct anatop_thermal_platform_data
+mx6q_sabreauto_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static const struct imxuart_platform_data mx6_bt_uart_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART3_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART3_TX,
+};
+
+static inline void mx6q_sabreauto_init_uart(void)
+{
+ imx6q_add_imx_uart(1, NULL);
+ imx6q_add_imx_uart(2, &mx6_bt_uart_data);
+ imx6q_add_imx_uart(3, NULL);
+}
+
+static int mx6q_sabreauto_fec_phy_init(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ if (!board_is_mx6_reva()) {
+ /* Ar8031 phy SmartEEE feature cause link status generates
+ * glitch, which cause ethernet link down/up issue, so
+ * disable SmartEEE
+ */
+ phy_write(phydev, 0xd, 0x3);
+ phy_write(phydev, 0xe, 0x805d);
+ phy_write(phydev, 0xd, 0x4003);
+ val = phy_read(phydev, 0xe);
+ val &= ~(0x1 << 8);
+ phy_write(phydev, 0xe, val);
+
+ /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+ phy_write(phydev, 0xd, 0x7);
+ phy_write(phydev, 0xe, 0x8016);
+ phy_write(phydev, 0xd, 0x4007);
+ val = phy_read(phydev, 0xe);
+
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, 0xe, val);
+
+ /* Introduce tx clock delay */
+ phy_write(phydev, 0x1d, 0x5);
+ val = phy_read(phydev, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, 0x1e, val);
+
+ /*check phy power*/
+ val = phy_read(phydev, 0x0);
+
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+ } else {
+ /* prefer master mode, 1000 Base-T capable */
+ phy_write(phydev, 0x9, 0x0f00);
+
+ /* min rx data delay */
+ phy_write(phydev, 0x0b, 0x8105);
+ phy_write(phydev, 0x0c, 0x0000);
+
+ /* max rx/tx clock delay, min rx/tx control delay */
+ phy_write(phydev, 0x0b, 0x8104);
+ phy_write(phydev, 0x0c, 0xf0f0);
+ phy_write(phydev, 0x0b, 0x104);
+ }
+
+ return 0;
+}
+
+static int mx6q_sabreauto_fec_power_hibernate(struct phy_device *phydev)
+{
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6q_sabreauto_fec_phy_init,
+ .power_hibernate = mx6q_sabreauto_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
+};
+
+static int mx6q_sabreauto_spi_cs[] = {
+ SABREAUTO_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx6q_sabreauto_spi_data __initconst = {
+ .chipselect = mx6q_sabreauto_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabreauto_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80)
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+#endif
+};
+static void spi_device_init(void)
+{
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+}
+#else
+static struct mtd_partition mxc_nor_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = 0x00080000,
+ }, {
+ .name = "nor.Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+static struct resource nor_flash_resource = {
+ .start = CS0_BASE_ADDR,
+ .end = CS0_BASE_ADDR + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .probe_type = "cfi_probe",
+ .width = 2,
+ .parts = mxc_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nor_partitions),
+};
+
+static struct platform_device physmap_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .resource = &nor_flash_resource,
+ .num_resources = 1,
+};
+
+static void mx6q_setup_weimcs(void)
+{
+ unsigned int reg;
+ void __iomem *nor_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR);
+ void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR);
+
+ /*CCM_BASE_ADDR + CLKCTL_CCGR6*/
+ reg = readl(ccm_reg + 0x80);
+ reg |= 0x00000C00;
+ writel(reg, ccm_reg + 0x80);
+
+ __raw_writel(0x00620081, nor_reg);
+ __raw_writel(0x1C022000, nor_reg + 0x00000008);
+ __raw_writel(0x0804a240, nor_reg + 0x00000010);
+}
+#endif
+
+static int max7310_1_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ /* 0 BACKLITE_ON */
+ /* 1 SAT_SHUTDN_B */
+ /* 2 CPU_PER_RST_B */
+ /* 3 MAIN_PER_RST_B */
+ /* 4 IPOD_RST_B */
+ /* 5 MLB_RST_B */
+ /* 6 SSI_STEERING */
+ /* 7 GPS_RST_B */
+
+ int max7310_gpio_value[] = {
+ 0, 1, 1, 1, 0, 0, 1, 0,
+ };
+
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 1 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_platdata = {
+ .gpio_base = SABREAUTO_MAX7310_1_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_1_setup,
+};
+
+static int max7310_u39_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ /* 0 not use */
+ /* 1 GPS_PWREN */
+ /* 2 VIDEO_ADC_PWRDN_B */
+ /* 3 ENET_CAN1_STEER */
+ /* 4 EIMD30_BTUART3_STEER */
+ /* 5 CAN_STBY */
+ /* 6 CAN_EN */
+ /* 7 USB_H1_PWR */
+
+ int max7310_gpio_value[] = {
+ 0, 1, 0, 0, 0, 1, 1, 1,
+ };
+
+ int n;
+
+ if (uart3_en)
+ max7310_gpio_value[4] = 1;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 U39 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static int max7310_u43_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ /*0 PORT_EXP_C0*/
+ /*1 USB_OTG_PWR_ON */
+ /*2 SAT_RST_B*/
+ /*3 NAND_BT_WIFI_STEER*/
+
+ int max7310_gpio_value[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ };
+ int n;
+
+ if (uart3_en)
+ max7310_gpio_value[3] = 1;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 U43 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_u39_platdata = {
+ .gpio_base = SABREAUTO_MAX7310_2_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_u39_setup,
+};
+
+static struct pca953x_platform_data max7310_u43_platdata = {
+ .gpio_base = SABREAUTO_MAX7310_3_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_u43_setup,
+};
+
+static void adv7180_pwdn(int pwdn)
+{
+ int status = -1;
+
+ status = gpio_request(SABREAUTO_VIDEOIN_PWR, "tvin-pwr");
+
+ if (pwdn)
+ gpio_direction_output(SABREAUTO_VIDEOIN_PWR, 0);
+ else
+ gpio_direction_output(SABREAUTO_VIDEOIN_PWR, 1);
+
+ gpio_free(SABREAUTO_VIDEOIN_PWR);
+}
+
+static struct fsl_mxc_tvin_platform_data adv7180_data = {
+ .dvddio_reg = NULL,
+ .dvdd_reg = NULL,
+ .avdd_reg = NULL,
+ .pvdd_reg = NULL,
+ .pwdn = adv7180_pwdn,
+ .reset = NULL,
+ .cvbs = true,
+};
+
+static struct imxi2c_platform_data mx6q_sabreauto_i2c2_data = {
+ .bitrate = 400000,
+};
+
+static struct imxi2c_platform_data mx6q_sabreauto_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct mxc_audio_codec_platform_data cs42888_data = {
+ .rates = (
+ SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000),
+};
+
+static struct fsl_mxc_lightsensor_platform_data ls_data = {
+ .rext = 499,
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max7310", 0x30),
+ .platform_data = &max7310_platdata,
+ }, {
+ I2C_BOARD_INFO("max7310", 0x32),
+ .platform_data = &max7310_u39_platdata,
+ }, {
+ I2C_BOARD_INFO("max7310", 0x34),
+ .platform_data = &max7310_u43_platdata,
+ }, {
+ I2C_BOARD_INFO("adv7180", 0x21),
+ .platform_data = (void *)&adv7180_data,
+ }, {
+ I2C_BOARD_INFO("isl29023", 0x44),
+ .irq = gpio_to_irq(SABREAUTO_ALS_INT),
+ .platform_data = &ls_data,
+ },
+ {
+ I2C_BOARD_INFO("mma8451", 0x1c),
+ .platform_data = (void *)&mma8451_position,
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x04),
+ .irq = gpio_to_irq(SABREAUTO_CAP_TCH_INT),
+ }, {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ }, {
+ I2C_BOARD_INFO("cs42888", 0x48),
+ .platform_data = (void *)&cs42888_data,
+ }, {
+ I2C_BOARD_INFO("si4763_i2c", 0x63),
+ },
+};
+
+struct platform_device mxc_si4763_audio_device = {
+ .name = "imx-tuner-si4763",
+ .id = 0,
+};
+
+struct platform_device si4763_codec_device = {
+ .name = "si4763",
+ .id = 0,
+};
+
+static struct imx_ssi_platform_data mx6_sabreauto_ssi1_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+static struct mxc_audio_platform_data si4763_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 5,
+};
+static void imx6q_sabreauto_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value_cansleep(SABREAUTO_USB_OTG_PWR, 1);
+ else
+ gpio_set_value_cansleep(SABREAUTO_USB_OTG_PWR, 0);
+}
+
+static void imx6q_sabreauto_usbhost1_vbus(bool on)
+{
+ if (on)
+ gpio_set_value_cansleep(SABREAUTO_USB_HOST1_PWR, 1);
+ else
+ gpio_set_value_cansleep(SABREAUTO_USB_HOST1_PWR, 0);
+}
+
+static void __init imx6q_sabreauto_init_usb(void)
+{
+ int ret = 0;
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+ ret = gpio_request(SABREAUTO_USB_OTG_OC, "otg-oc");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO SABREAUTO_USB_OTG_OC:"
+ " %d\n", ret);
+ return;
+ }
+ gpio_direction_input(SABREAUTO_USB_OTG_OC);
+
+ ret = gpio_request(SABREAUTO_USB_HOST1_OC, "usbh1-oc");
+ if (ret) {
+ printk(KERN_ERR"failed to get SABREAUTO_USB_HOST1_OC:"
+ " %d\n", ret);
+ return;
+ }
+ gpio_direction_input(SABREAUTO_USB_HOST1_OC);
+
+ mxc_iomux_set_gpr_register(1, 13, 1, 0);
+ mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus);
+ mx6_usb_dr_init();
+ mx6_set_host1_vbus_func(imx6q_sabreauto_usbhost1_vbus);
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+ mx6_usb_h3_init();
+#endif
+}
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M,
+};
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6q_sabreauto_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+#else
+ usleep_range(1000, 2000);
+ /* AHCI PHY enter into PDDQ mode if the AHCI module is not enabled */
+ tmpdata = readl(addr + PORT_PHY_CTL);
+ writel(tmpdata | PORT_PHY_CTL_PDDQ_LOC, addr + PORT_PHY_CTL);
+ pr_info("No AHCI save PWR: PDDQ %s\n", ((readl(addr + PORT_PHY_CTL)
+ >> 20) & 1) ? "enabled" : "disabled");
+#endif
+
+release_sata_clk:
+ /* disable SATA_PHY PLL */
+ writel((readl(IOMUXC_GPR13) & ~0x2), IOMUXC_GPR13);
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+static void mx6q_sabreauto_sata_exit(struct device *dev)
+{
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+
+}
+
+static struct ahci_platform_data mx6q_sabreauto_sata_data = {
+ .init = mx6q_sabreauto_sata_init,
+ .exit = mx6q_sabreauto_sata_exit,
+};
+#endif
+
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+static void mx6q_sabreauto_reset_mipi_dsi(void)
+{
+ gpio_set_value(SABREAUTO_DISP0_PWR, 1);
+ gpio_set_value(SABREAUTO_DISP0_RESET, 1);
+ udelay(10);
+ gpio_set_value(SABREAUTO_DISP0_RESET, 0);
+ udelay(50);
+ gpio_set_value(SABREAUTO_DISP0_RESET, 1);
+
+ /*
+ * it needs to delay 120ms minimum for reset complete
+ */
+ msleep(120);
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .lcd_panel = "TRULY-WVGA",
+ .reset = mx6q_sabreauto_reset_mipi_dsi,
+};
+
+static struct ipuv3_fb_platform_data sabr_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ printk(KERN_ERR"Invalid IPU select for HDMI: %d. Set to 0\n",
+ ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ printk(KERN_ERR"Invalid DI select for HDMI: %d. Set to 0\n",
+ disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+
+ /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+ if (hdmi_SDMA_check())
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+/* On mx6x sabreauto board i2c2 iomux with hdmi ddc,
+ * the pins default work at i2c2 function,
+ when hdcp enable, the pins should work at ddc function */
+
+static void hdmi_enable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabreauto_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6dl_sabreauto_hdmi_ddc_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6q_sabreauto_hdmi_ddc_pads));
+}
+
+static void hdmi_disable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabreauto_i2c2_pads,
+ ARRAY_SIZE(mx6dl_sabreauto_i2c2_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_i2c2_pads,
+ ARRAY_SIZE(mx6q_sabreauto_i2c2_pads));
+}
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+ .enable_pins = hdmi_enable_ddc_pin,
+ .disable_pins = hdmi_disable_ddc_pin,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 1,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SEP0,
+ .sec_ipu_id = 1,
+ .sec_disp_id = 1,
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ },
+};
+
+/* Backlight PWM for CPU board lvds*/
+static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data3 = {
+ .pwm_id = 2,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct ion_platform_data imx_ion_data = {
+ .nr = 1,
+ .heaps = {
+ {
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = "vpu_ion",
+ .size = SZ_64M,
+ },
+ },
+};
+
+/* Backlight PWM for Main board lvds*/
+static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data4 = {
+ .pwm_id = 3,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+static int flexcan0_en;
+static int flexcan1_en;
+
+static void mx6q_flexcan_switch(void)
+{
+ if (flexcan0_en || flexcan1_en) {
+ /*
+ * The transceiver TJA1041A on sabreauto RevE baseboard will
+ * fail to transit to Normal state if EN/STBY is high by default
+ * after board power up. So we set the EN/STBY initial state to low
+ * first then to high to guarantee the state transition successfully.
+ */
+ gpio_set_value_cansleep(SABREAUTO_CAN_EN, 0);
+ gpio_set_value_cansleep(SABREAUTO_CAN_STBY, 0);
+
+ gpio_set_value_cansleep(SABREAUTO_CAN_EN, 1);
+ gpio_set_value_cansleep(SABREAUTO_CAN_STBY, 1);
+ /* Enable STEER pin if CAN1 interface is required.
+ * STEER pin is used to switch between ENET_MDC
+ * and CAN1_TX functionality. By default ENET_MDC
+ * is active after reset.
+ */
+ if (flexcan0_en)
+ gpio_set_value_cansleep(SABREAUTO_CAN1_STEER, 1);
+
+ } else {
+ /* avoid to disable CAN xcvr if any of the CAN interfaces
+ * are down. XCRV will be disabled only if both CAN2
+ * interfaces are DOWN.
+ */
+ if (!flexcan0_en && !flexcan1_en) {
+ gpio_set_value_cansleep(SABREAUTO_CAN_EN, 0);
+ gpio_set_value_cansleep(SABREAUTO_CAN_STBY, 0);
+ }
+ /* turn down STEER pin only if CAN1 is DOWN */
+ if (!flexcan0_en)
+ gpio_set_value_cansleep(SABREAUTO_CAN1_STEER, 0);
+
+ }
+}
+static void mx6q_flexcan0_switch(int enable)
+{
+ flexcan0_en = enable;
+ mx6q_flexcan_switch();
+}
+
+static void mx6q_flexcan1_switch(int enable)
+{
+ flexcan1_en = enable;
+ mx6q_flexcan_switch();
+}
+
+static const struct flexcan_platform_data
+ mx6q_sabreauto_flexcan_pdata[] __initconst = {
+ {
+ .transceiver_switch = mx6q_flexcan0_switch,
+ }, {
+ .transceiver_switch = mx6q_flexcan1_switch,
+ }
+};
+
+static struct mipi_csi2_platform_data mipi_csi2_pdata = {
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+static void sabreauto_suspend_enter(void)
+{
+ /* suspend preparation */
+}
+
+static void sabreauto_suspend_exit(void)
+{
+ /* resmue resore */
+}
+static const struct pm_platform_data mx6q_sabreauto_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = sabreauto_suspend_enter,
+ .suspend_exit = sabreauto_suspend_exit,
+};
+
+static const struct asrc_p2p_params esai_p2p = {
+ .p2p_rate = 48000,
+ .p2p_width = ASRC_WIDTH_24_BIT,
+};
+
+static struct mxc_audio_platform_data sab_audio_data = {
+ .sysclk = 24576000,
+ .codec_name = "cs42888.1-0048",
+ .priv = (void *)&esai_p2p,
+};
+
+static struct platform_device sab_audio_device = {
+ .name = "imx-cs42888",
+};
+
+static struct imx_esai_platform_data sab_esai_pdata = {
+ .flags = IMX_ESAI_NET,
+};
+
+static struct regulator_consumer_supply sabreauto_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data sabreauto_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(sabreauto_vmmc_consumers),
+ .consumer_supplies = sabreauto_vmmc_consumers,
+};
+
+static struct fixed_voltage_config sabreauto_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sabreauto_vmmc_init,
+};
+
+static struct platform_device sabreauto_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &sabreauto_vmmc_reg_config,
+ },
+};
+
+static struct regulator_consumer_supply cs42888_sabreauto_consumer_va = {
+ .supply = "VA",
+ .dev_name = "1-0048",
+};
+
+static struct regulator_consumer_supply cs42888_sabreauto_consumer_vd = {
+ .supply = "VD",
+ .dev_name = "1-0048",
+};
+
+static struct regulator_consumer_supply cs42888_sabreauto_consumer_vls = {
+ .supply = "VLS",
+ .dev_name = "1-0048",
+};
+
+static struct regulator_consumer_supply cs42888_sabreauto_consumer_vlc = {
+ .supply = "VLC",
+ .dev_name = "1-0048",
+};
+
+static struct regulator_init_data cs42888_sabreauto_va_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_sabreauto_consumer_va,
+};
+
+static struct regulator_init_data cs42888_sabreauto_vd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_sabreauto_consumer_vd,
+};
+
+static struct regulator_init_data cs42888_sabreauto_vls_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_sabreauto_consumer_vls,
+};
+
+static struct regulator_init_data cs42888_sabreauto_vlc_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_sabreauto_consumer_vlc,
+};
+
+static struct fixed_voltage_config cs42888_sabreauto_va_reg_config = {
+ .supply_name = "VA",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_sabreauto_va_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_sabreauto_vd_reg_config = {
+ .supply_name = "VD",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_sabreauto_vd_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_sabreauto_vls_reg_config = {
+ .supply_name = "VLS",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_sabreauto_vls_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_sabreauto_vlc_reg_config = {
+ .supply_name = "VLC",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_sabreauto_vlc_reg_initdata,
+};
+
+static struct platform_device cs42888_sabreauto_va_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &cs42888_sabreauto_va_reg_config,
+ },
+};
+
+static struct platform_device cs42888_sabreauto_vd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &cs42888_sabreauto_vd_reg_config,
+ },
+};
+
+static struct platform_device cs42888_sabreauto_vls_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 5,
+ .dev = {
+ .platform_data = &cs42888_sabreauto_vls_reg_config,
+ },
+};
+
+static struct platform_device cs42888_sabreauto_vlc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 6,
+ .dev = {
+ .platform_data = &cs42888_sabreauto_vlc_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ struct clk *pll4_clk, *esai_clk, *anaclk_2;
+
+ mxc_register_device(&sab_audio_device, &sab_audio_data);
+ imx6q_add_imx_esai(0, &sab_esai_pdata);
+
+ gpio_request(SABREAUTO_ESAI_INT, "esai-int");
+ gpio_direction_input(SABREAUTO_ESAI_INT);
+
+ anaclk_2 = clk_get(NULL, "anaclk_2");
+ if (IS_ERR(anaclk_2))
+ return PTR_ERR(anaclk_2);
+ clk_set_rate(anaclk_2, 24576000);
+
+ esai_clk = clk_get(NULL, "esai_clk");
+ if (IS_ERR(esai_clk))
+ return PTR_ERR(esai_clk);
+
+ pll4_clk = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4_clk))
+ return PTR_ERR(pll4_clk);
+
+ clk_set_parent(pll4_clk, anaclk_2);
+ clk_set_parent(esai_clk, pll4_clk);
+ clk_set_rate(pll4_clk, 786432000);
+ clk_set_rate(esai_clk, 24576000);
+
+ platform_device_register(&cs42888_sabreauto_va_reg_devices);
+ platform_device_register(&cs42888_sabreauto_vd_reg_devices);
+ platform_device_register(&cs42888_sabreauto_vls_reg_devices);
+ platform_device_register(&cs42888_sabreauto_vlc_reg_devices);
+ return 0;
+}
+
+static struct mxc_mlb_platform_data mx6_sabreauto_mlb150_data = {
+ .reg_nvcc = NULL,
+ .mlb_clk = "mlb150_clk",
+ .mlb_pll_clk = "pll6",
+};
+
+static struct mxc_dvfs_platform_data sabreauto_dvfscore_data = {
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+}
+
+static int __init early_enable_mipi_sensor(char *p)
+{
+ mipi_sensor = 1;
+ return 0;
+}
+early_param("mipi_sensor", early_enable_mipi_sensor);
+
+static int __init early_enable_can0(char *p)
+{
+ can0_enable = 1;
+ return 0;
+}
+early_param("can0", early_enable_can0);
+
+static inline void __init mx6q_csi0_io_init(void)
+{
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 0, /* disable tx */
+ .spdif_rx = 1, /* enable rx */
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct fsl_mxc_capture_platform_data capture_data[] = {
+ {
+ .csi = 0,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 0,
+ }, {
+ .csi = 1,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 1,
+ },
+};
+
+static const struct imx_pcie_platform_data mx6_sabreauto_pcie_data __initconst = {
+ .pcie_pwr_en = -EINVAL,
+ .pcie_rst = SABREAUTO_PCIE_RST_B_REVB,
+ .pcie_wake_up = -EINVAL,
+ .pcie_dis = -EINVAL,
+};
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_board_init(void)
+{
+ int i;
+ int ret;
+ iomux_v3_cfg_t *common_pads = NULL;
+ iomux_v3_cfg_t *can0_pads = NULL;
+ iomux_v3_cfg_t *can1_pads = NULL;
+ iomux_v3_cfg_t *mipi_sensor_pads = NULL;
+ iomux_v3_cfg_t *i2c3_pads = NULL;
+ iomux_v3_cfg_t *tuner_pads = NULL;
+ iomux_v3_cfg_t *spinor_pads = NULL;
+ iomux_v3_cfg_t *weimnor_pads = NULL;
+ iomux_v3_cfg_t *bluetooth_pads = NULL;
+ iomux_v3_cfg_t *extra_pads = NULL;
+
+ int common_pads_cnt;
+ int can0_pads_cnt;
+ int can1_pads_cnt;
+ int mipi_sensor_pads_cnt;
+ int i2c3_pads_cnt;
+ int tuner_pads_cnt;
+ int spinor_pads_cnt;
+ int weimnor_pads_cnt;
+ int bluetooth_pads_cnt;
+ int extra_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ common_pads = mx6q_sabreauto_pads;
+ can0_pads = mx6q_sabreauto_can0_pads;
+ can1_pads = mx6q_sabreauto_can1_pads;
+ mipi_sensor_pads = mx6q_sabreauto_mipi_sensor_pads;
+ tuner_pads = mx6q_tuner_pads;
+ spinor_pads = mx6q_spinor_pads;
+ weimnor_pads = mx6q_weimnor_pads;
+ bluetooth_pads = mx6q_bluetooth_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6q_sabreauto_pads);
+ can0_pads_cnt = ARRAY_SIZE(mx6q_sabreauto_can0_pads);
+ can1_pads_cnt = ARRAY_SIZE(mx6q_sabreauto_can1_pads);
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6q_sabreauto_mipi_sensor_pads);
+ tuner_pads_cnt = ARRAY_SIZE(mx6q_tuner_pads);
+ spinor_pads_cnt = ARRAY_SIZE(mx6q_spinor_pads);
+ weimnor_pads_cnt = ARRAY_SIZE(mx6q_weimnor_pads);
+ bluetooth_pads_cnt = ARRAY_SIZE(mx6q_bluetooth_pads);
+ if (board_is_mx6_reva()) {
+ i2c3_pads = mx6q_i2c3_pads_rev_a;
+ i2c3_pads_cnt = ARRAY_SIZE(mx6q_i2c3_pads_rev_a);
+ mxc_iomux_v3_setup_multiple_pads(i2c3_pads,
+ i2c3_pads_cnt);
+ } else {
+ i2c3_pads = mx6q_i2c3_pads_rev_b;
+ i2c3_pads_cnt = ARRAY_SIZE(mx6q_i2c3_pads_rev_b);
+ extra_pads = mx6q_extra_pads_rev_b;
+ extra_pads_cnt = ARRAY_SIZE(mx6q_extra_pads_rev_b);
+ mxc_iomux_v3_setup_multiple_pads(extra_pads,
+ extra_pads_cnt);
+ }
+ } else if (cpu_is_mx6dl()) {
+ common_pads = mx6dl_sabreauto_pads;
+ can0_pads = mx6dl_sabreauto_can0_pads;
+ can1_pads = mx6dl_sabreauto_can1_pads;
+ mipi_sensor_pads = mx6dl_sabreauto_mipi_sensor_pads;
+ tuner_pads = mx6dl_tuner_pads;
+ spinor_pads = mx6dl_spinor_pads;
+ weimnor_pads = mx6dl_weimnor_pads;
+ bluetooth_pads = mx6dl_bluetooth_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6dl_sabreauto_pads);
+ can0_pads_cnt = ARRAY_SIZE(mx6dl_sabreauto_can0_pads);
+ can1_pads_cnt = ARRAY_SIZE(mx6dl_sabreauto_can1_pads);
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6dl_sabreauto_mipi_sensor_pads);
+ tuner_pads_cnt = ARRAY_SIZE(mx6dl_tuner_pads);
+ spinor_pads_cnt = ARRAY_SIZE(mx6dl_spinor_pads);
+ weimnor_pads_cnt = ARRAY_SIZE(mx6dl_weimnor_pads);
+ bluetooth_pads_cnt = ARRAY_SIZE(mx6dl_bluetooth_pads);
+
+ if (board_is_mx6_reva()) {
+ i2c3_pads = mx6dl_i2c3_pads_rev_a;
+ i2c3_pads_cnt = ARRAY_SIZE(mx6dl_i2c3_pads_rev_a);
+ mxc_iomux_v3_setup_multiple_pads(i2c3_pads,
+ i2c3_pads_cnt);
+ } else {
+ i2c3_pads = mx6dl_i2c3_pads_rev_b;
+ i2c3_pads_cnt = ARRAY_SIZE(mx6dl_i2c3_pads_rev_b);
+ extra_pads = mx6dl_extra_pads_rev_b;
+ extra_pads_cnt = ARRAY_SIZE(mx6dl_extra_pads_rev_b);
+ mxc_iomux_v3_setup_multiple_pads(extra_pads,
+ extra_pads_cnt);
+ }
+ }
+
+ BUG_ON(!common_pads);
+ mxc_iomux_v3_setup_multiple_pads(common_pads, common_pads_cnt);
+
+ /*If at least one NOR memory is selected we don't
+ * configure IC23 PADS for rev B */
+ if (spinor_en) {
+ BUG_ON(!spinor_pads);
+ mxc_iomux_v3_setup_multiple_pads(spinor_pads, spinor_pads_cnt);
+ } else if (weimnor_en) {
+ BUG_ON(!weimnor_pads);
+ mxc_iomux_v3_setup_multiple_pads(weimnor_pads,
+ weimnor_pads_cnt);
+ } else {
+ if (!board_is_mx6_reva()) {
+ BUG_ON(!i2c3_pads);
+ mxc_iomux_v3_setup_multiple_pads(i2c3_pads,
+ i2c3_pads_cnt);
+ }
+ if (uart3_en) {
+ BUG_ON(!bluetooth_pads);
+ mxc_iomux_v3_setup_multiple_pads(bluetooth_pads,
+ bluetooth_pads_cnt);
+ }
+ }
+
+ if (can0_enable) {
+ BUG_ON(!can0_pads);
+ mxc_iomux_v3_setup_multiple_pads(can0_pads,
+ can0_pads_cnt);
+ }
+
+ BUG_ON(!can1_pads);
+ mxc_iomux_v3_setup_multiple_pads(can1_pads, can1_pads_cnt);
+
+ if (tuner_en) {
+ BUG_ON(!tuner_pads);
+ mxc_iomux_v3_setup_multiple_pads(tuner_pads,
+ tuner_pads_cnt);
+ }
+
+ /* assert i2c-rst */
+ gpio_request(SABREAUTO_I2C_EXP_RST, "i2c-rst");
+ gpio_direction_output(SABREAUTO_I2C_EXP_RST, 1);
+
+ if (!board_is_mx6_reva()) {
+ /* enable either EIM_D18 or i2c3_sda route path */
+ gpio_request(SABREAUTO_I2C3_STEER, "i2c3-steer");
+ if (spinor_en)
+ gpio_direction_output(SABREAUTO_I2C3_STEER, 0);
+ else if (weimnor_en) {
+ /*Put DISP0_DAT8 in ALT5 mode to prevent WDOG1 of
+ resetting WEIM NOR*/
+ gpio_direction_output(SABREAUTO_I2C3_STEER, 0);
+
+ gpio_request(SABREAUTO_WEIM_NOR_WDOG1, "nor-reset");
+ gpio_direction_output(SABREAUTO_WEIM_NOR_WDOG1, 1);
+ } else
+ gpio_direction_output(SABREAUTO_I2C3_STEER, 1);
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and
+ * RMII reference clk
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+ }
+
+ if (mipi_sensor) {
+ BUG_ON(!mipi_sensor_pads);
+ mxc_iomux_v3_setup_multiple_pads(mipi_sensor_pads,
+ mipi_sensor_pads_cnt);
+ }
+
+ gp_reg_id = sabreauto_dvfscore_data.reg_id;
+ soc_reg_id = sabreauto_dvfscore_data.soc_id;
+ mx6q_sabreauto_init_uart();
+ imx6q_add_mipi_csi2(&mipi_csi2_pdata);
+ if (cpu_is_mx6dl()) {
+ mipi_dsi_pdata.ipu_id = 0;
+ mipi_dsi_pdata.disp_id = 1;
+ ldb_data.ipu_id = 0;
+ ldb_data.disp_id = 0;
+ ldb_data.sec_ipu_id = 0;
+ ldb_data.sec_disp_id = 1;
+ hdmi_core_data.disp_id = 1;
+ }
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ if (cpu_is_mx6q()) {
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+ } else if (cpu_is_mx6dl())
+ for (i = 0; i < (ARRAY_SIZE(sabr_fb_data) + 1) / 2; i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+
+ imx6q_add_vdoa();
+ imx6q_add_mipi_dsi(&mipi_dsi_pdata);
+ imx6q_add_lcdif(&lcdif_data);
+ imx6q_add_ldb(&ldb_data);
+ imx6q_add_v4l2_output(0);
+ imx6q_add_v4l2_capture(0, &capture_data[0]);
+ imx6q_add_v4l2_capture(1, &capture_data[1]);
+ imx6q_add_android_device_buttons();
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_caam();
+
+ imx6q_add_imx_i2c(1, &mx6q_sabreauto_i2c1_data);
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ imx6q_add_imx_i2c(2, &mx6q_sabreauto_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+ ret = gpio_request(SABREAUTO_PMIC_INT, "pFUZE-int");
+ if (ret) {
+ printk(KERN_ERR"request pFUZE-int error!!\n");
+ return;
+ } else {
+ gpio_direction_input(SABREAUTO_PMIC_INT);
+ mx6q_sabreauto_init_pfuze100(SABREAUTO_PMIC_INT);
+ }
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6q_sabreauto_spi_data);
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ spi_device_init();
+#else
+ mx6q_setup_weimcs();
+ platform_device_register(&physmap_flash_device);
+#endif
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6q_sabreauto_anatop_thermal_data);
+
+ if (!can0_enable) {
+ imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+
+ }
+ imx6q_add_pm_imx(0, &mx6q_sabreauto_pm_data);
+
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabreauto_sd3_data);
+ imx6q_add_sdhci_usdhc_imx(0, &mx6q_sabreauto_sd1_data);
+
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6q_sabreauto_init_usb();
+ if (cpu_is_mx6q()) {
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+ imx6q_add_ahci(0, &mx6q_sabreauto_sata_data);
+#else
+ mx6q_sabreauto_sata_init(NULL,
+ (void __iomem *)ioremap(MX6Q_SATA_BASE_ADDR, SZ_4K));
+#endif
+ }
+ imx6q_add_vpu();
+ imx6q_init_audio();
+ platform_device_register(&sabreauto_vmmc_reg_devices);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
+ if (!mipi_sensor)
+ mx6q_csi0_io_init();
+
+ /* DISP0 Detect */
+ gpio_request(SABREAUTO_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(SABREAUTO_DISP0_DET_INT);
+
+ /* DISP0 Reset - Assert for i2c disabled mode */
+ gpio_request(SABREAUTO_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(SABREAUTO_DISP0_RESET, 0);
+
+ /* DISP0 I2C enable */
+ gpio_request(SABREAUTO_DISP0_I2C_EN, "disp0-i2c");
+ gpio_direction_output(SABREAUTO_DISP0_I2C_EN, 0);
+
+ gpio_request(SABREAUTO_DISP0_PWR, "disp0-pwr");
+ gpio_direction_output(SABREAUTO_DISP0_PWR, 1);
+
+ gpio_request(SABREAUTO_LDB_BACKLIGHT3, "ldb-backlight3");
+ gpio_direction_output(SABREAUTO_LDB_BACKLIGHT3, 1);
+ gpio_request(SABREAUTO_LDB_BACKLIGHT4, "ldb-backlight4");
+ gpio_direction_output(SABREAUTO_LDB_BACKLIGHT4, 1);
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+ if (!uart3_en)
+ imx6q_add_gpmi(&mx6q_gpmi_nand_platform_data);
+
+ imx6q_add_dvfs_core(&sabreauto_dvfscore_data);
+
+ imx6q_add_ion(0, &imx_ion_data,
+ sizeof(imx_ion_data) + sizeof(struct ion_platform_heap));
+ imx6q_add_mxc_pwm(2);
+ imx6q_add_mxc_pwm(3);
+ imx6q_add_mxc_pwm_backlight(2, &mx6_arm2_pwm_backlight_data3);
+ imx6q_add_mxc_pwm_backlight(3, &mx6_arm2_pwm_backlight_data4);
+
+ mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0", NULL);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ imx6q_add_spdif(&mxc_spdif_data);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+
+ if (can0_enable)
+ imx6q_add_flexcan0(&mx6q_sabreauto_flexcan_pdata[0]);
+ imx6q_add_flexcan1(&mx6q_sabreauto_flexcan_pdata[1]);
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+ imx6q_add_mlb150(&mx6_sabreauto_mlb150_data);
+
+ /* Tuner audio interface */
+ imx6q_add_imx_ssi(1, &mx6_sabreauto_ssi1_pdata);
+ mxc_register_device(&si4763_codec_device, NULL);
+ mxc_register_device(&mxc_si4763_audio_device, &si4763_audio_data);
+
+ imx6q_add_busfreq();
+
+ /* Add PCIe RC interface support */
+ imx6q_add_pcie(&mx6_sabreauto_pcie_data);
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART4_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6q_reserve(void)
+{
+ phys_addr_t phys;
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, SZ_2G);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+
+#if defined(CONFIG_ION)
+ if (imx_ion_data.heaps[0].size) {
+ phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K);
+ memblock_free(phys, imx_ion_data.heaps[0].size);
+ memblock_remove(phys, imx_ion_data.heaps[0].size);
+ imx_ion_data.heaps[0].base = phys;
+ }
+#endif
+}
+
+MACHINE_START(MX6Q_SABREAUTO, "Freescale i.MX 6Quad/DualLite/Solo Sabre Auto Board")
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_board_init,
+ .timer = &mxc_timer,
+ .reserve = mx6q_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.h b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
new file mode 100644
index 00000000..cec36d57
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.h
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6q.h>
+
+static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6Q_PAD_KEY_COL1__ENET_MDIO,
+ MX6Q_PAD_KEY_COL2__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ /*RGMII Phy Interrupt */
+ MX6Q_PAD_GPIO_19__GPIO_4_5,
+#endif
+ /* MCLK for csi0 */
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ /*MX6Q_PAD_GPIO_3__CCM_CLKO2,i*/
+
+ /* Android GPIO keys */
+ MX6Q_PAD_SD2_CMD__GPIO_1_11, /* home */
+ MX6Q_PAD_SD2_DAT3__GPIO_1_12, /* back */
+ MX6Q_PAD_SD4_DAT4__GPIO_2_12, /* prog */
+ MX6Q_PAD_SD4_DAT7__GPIO_2_15, /* vol up */
+ MX6Q_PAD_DISP0_DAT20__GPIO_5_14, /* vol down */
+
+ /* SD1 */
+ MX6Q_PAD_SD1_CLK__USDHC1_CLK_50MHZ_40OHM,
+ MX6Q_PAD_SD1_CMD__USDHC1_CMD_50MHZ_40OHM,
+ MX6Q_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM,
+ MX6Q_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM,
+ MX6Q_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM,
+ MX6Q_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM,
+
+ /* SD1_CD and SD1_WP */
+ MX6Q_PAD_GPIO_1__GPIO_1_1,
+ MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20,
+
+ /* SD3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+
+ /* SD3 VSelect */
+ MX6Q_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6Q_PAD_NANDF_CS2__GPIO_6_15,
+ MX6Q_PAD_SD2_DAT2__GPIO_1_13,
+
+ /* ESAI */
+ MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6Q_PAD_ENET_RXD1__ESAI1_FST,
+ MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3,
+ MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6Q_PAD_GPIO_17__ESAI1_TX0,
+ MX6Q_PAD_NANDF_CS3__ESAI1_TX1,
+ MX6Q_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6Q_PAD_GPIO_9__ESAI1_FSR,
+ /* esai interrupt */
+ MX6Q_PAD_SD2_CLK__GPIO_1_10,
+
+ /* I2C2 */
+ MX6Q_PAD_EIM_EB2__I2C2_SCL,
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+ MX6Q_PAD_SD2_DAT0__GPIO_1_15,
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+
+ /* LITE_SENS_INT_B */
+ MX6Q_PAD_DISP0_DAT23__GPIO_5_17,
+ /*PMIC INT*/
+ MX6Q_PAD_DISP0_DAT22__GPIO_5_16,
+
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4,
+ MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5,
+ MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6,
+ MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7,
+ MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8,
+ MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9,
+ MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10,
+ MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11,
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+
+ /* PWM3 and PMW4 */
+ MX6Q_PAD_SD4_DAT1__PWM3_PWMO,
+ MX6Q_PAD_SD4_DAT2__PWM4_PWMO,
+
+ /* DISP0 RESET */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* SPDIF */
+ MX6Q_PAD_KEY_COL3__SPDIF_IN1,
+
+ /* Touchscreen interrupt */
+ MX6Q_PAD_EIM_EB0__GPIO_2_28,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID,
+
+ /* VIDEO adv7180 INTRQ */
+ MX6Q_PAD_ENET_RXD0__GPIO_1_27,
+ /* UART 2 */
+ MX6Q_PAD_GPIO_7__UART2_TXD,
+ MX6Q_PAD_GPIO_8__UART2_RXD,
+ MX6Q_PAD_SD4_DAT6__UART2_CTS,
+ MX6Q_PAD_SD4_DAT5__UART2_RTS,
+
+ /*USBs OC pin */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0, /*HOST1_OC*/
+ MX6Q_PAD_SD4_DAT0__GPIO_2_8, /*OTG_OC*/
+
+ /* DISP0 I2C ENABLE*/
+ MX6Q_PAD_EIM_D28__GPIO_3_28,
+
+ /* DISP0 DET */
+ MX6Q_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* MLB150 */
+ MX6Q_PAD_ENET_TXD1__MLB_MLBCLK,
+ MX6Q_PAD_GPIO_6__MLB_MLBSIG,
+ MX6Q_PAD_GPIO_2__MLB_MLBDAT,
+#endif
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_can0_pads[] = {
+ /* CAN1 */
+ MX6Q_PAD_KEY_COL2__CAN1_TXCAN,
+ MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
+};
+
+
+static iomux_v3_cfg_t mx6q_sabreauto_can1_pads[] = {
+ /* CAN2 */
+ MX6Q_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6Q_PAD_KEY_ROW4__CAN2_RXCAN,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_mipi_sensor_pads[] = {
+ MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+#define MX6Q_USDHC_PAD_SETTING(id, speed) \
+mx6q_sd##id##_##speed##mhz[] = { \
+ MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
+ MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6Q_PAD_NANDF_D0__RAWNAND_D0,
+ MX6Q_PAD_NANDF_D1__RAWNAND_D1,
+ MX6Q_PAD_NANDF_D2__RAWNAND_D2,
+ MX6Q_PAD_NANDF_D3__RAWNAND_D3,
+ MX6Q_PAD_NANDF_D4__RAWNAND_D4,
+ MX6Q_PAD_NANDF_D5__RAWNAND_D5,
+ MX6Q_PAD_NANDF_D6__RAWNAND_D6,
+ MX6Q_PAD_NANDF_D7__RAWNAND_D7,
+ MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6q_i2c3_pads_rev_a[] __initdata = {
+ MX6Q_PAD_GPIO_3__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+};
+static iomux_v3_cfg_t mx6q_i2c3_pads_rev_b[] __initdata = {
+ MX6Q_PAD_GPIO_3__I2C3_SCL,
+ MX6Q_PAD_EIM_D18__I2C3_SDA,
+};
+static iomux_v3_cfg_t mx6q_tuner_pads[] __initdata = {
+ MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC,
+ MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS,
+ MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD,
+};
+static iomux_v3_cfg_t mx6q_extra_pads_rev_b[] __initdata = {
+ MX6Q_PAD_EIM_A24__GPIO_5_4,
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+};
+static iomux_v3_cfg_t mx6q_spinor_pads[] __initdata = {
+ /* eCSPI1 */
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO,
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6Q_PAD_EIM_D19__ECSPI1_SS1,
+
+ MX6Q_PAD_EIM_D19__GPIO_3_19,
+};
+
+/*Bluetooth is conflicted with GMPI and NOR chips*/
+static iomux_v3_cfg_t mx6q_bluetooth_pads[] __initdata = {
+ /* UART 3 */
+ MX6Q_PAD_SD4_CLK__UART3_RXD,
+ MX6Q_PAD_SD4_CMD__UART3_TXD,
+ MX6Q_PAD_EIM_D30__UART3_CTS,
+ MX6Q_PAD_EIM_EB3__UART3_RTS,
+};
+
+static iomux_v3_cfg_t mx6q_weimnor_pads[] __initdata = {
+ /* Parallel NOR */
+ MX6Q_PAD_EIM_OE__WEIM_WEIM_OE,
+ MX6Q_PAD_EIM_RW__WEIM_WEIM_RW,
+ MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT,
+ MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0,
+ /*Control NOR reset using gpio mode*/
+ MX6Q_PAD_DISP0_DAT8__GPIO_4_29,
+
+ MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA,
+ MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK,
+ /* Parallel Nor Data Bus */
+ MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16,
+ MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17,
+ MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18,
+ MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19,
+ MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20,
+ MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21,
+ MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22,
+ MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23,
+ MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24,
+ MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25,
+ MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26,
+ MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27,
+ MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28,
+ MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29,
+ MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30,
+ MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31,
+
+ /* Parallel Nor 25 bit Address Bus */
+ MX6Q_PAD_EIM_A24__GPIO_5_4,
+ MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23,
+ MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22,
+ MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21,
+ MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20,
+ MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19,
+ MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18,
+ MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17,
+ MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16,
+
+ MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15,
+ MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14,
+ MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13,
+ MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12,
+ MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11,
+ MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10,
+ MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9,
+ MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8,
+ MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7,
+ MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6,
+ MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5,
+ MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4,
+ MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3,
+ MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2,
+ MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1,
+ MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_hdmi_ddc_pads[] = {
+ MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_i2c2_pads[] = {
+ MX6Q_PAD_EIM_EB2__I2C2_SCL, /* I2C2 SCL */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
new file mode 100644
index 00000000..f13a5d47
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -0,0 +1,1414 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/ion.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+#include <mach/mxc_asrc.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+
+#define MX6Q_SABRELITE_SD3_CD IMX_GPIO_NR(7, 0)
+#define MX6Q_SABRELITE_SD3_WP IMX_GPIO_NR(7, 1)
+#define MX6Q_SABRELITE_SD4_CD IMX_GPIO_NR(2, 6)
+#define MX6Q_SABRELITE_SD4_WP IMX_GPIO_NR(2, 7)
+#define MX6Q_SABRELITE_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6Q_SABRELITE_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define MX6Q_SABRELITE_CAP_TCH_INT1 IMX_GPIO_NR(1, 9)
+#define MX6Q_SABRELITE_USB_HUB_RESET IMX_GPIO_NR(7, 12)
+#define MX6Q_SABRELITE_CAN1_STBY IMX_GPIO_NR(1, 2)
+#define MX6Q_SABRELITE_CAN1_EN IMX_GPIO_NR(1, 4)
+#define MX6Q_SABRELITE_MENU_KEY IMX_GPIO_NR(2, 1)
+#define MX6Q_SABRELITE_BACK_KEY IMX_GPIO_NR(2, 2)
+#define MX6Q_SABRELITE_ONOFF_KEY IMX_GPIO_NR(2, 3)
+#define MX6Q_SABRELITE_HOME_KEY IMX_GPIO_NR(2, 4)
+#define MX6Q_SABRELITE_VOL_UP_KEY IMX_GPIO_NR(7, 13)
+#define MX6Q_SABRELITE_VOL_DOWN_KEY IMX_GPIO_NR(4, 5)
+#define MX6Q_SABRELITE_CSI0_RST IMX_GPIO_NR(1, 8)
+#define MX6Q_SABRELITE_CSI0_PWN IMX_GPIO_NR(1, 6)
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
+#define MX6Q_SABRELITE_SD3_WP_PADCFG (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+static struct clk *sata_clk;
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+static int caam_enabled;
+
+extern struct regulator *(*get_cpu_regulator)(void);
+extern void (*put_cpu_regulator)(void);
+
+static iomux_v3_cfg_t mx6q_sabrelite_pads[] = {
+ /* AUDMUX */
+ MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD,
+ MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC,
+ MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD,
+ MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS,
+
+ /* CAN1 */
+ MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6Q_PAD_KEY_COL2__CAN1_TXCAN,
+ MX6Q_PAD_GPIO_2__GPIO_1_2, /* STNDBY */
+ MX6Q_PAD_GPIO_7__GPIO_1_7, /* NERR */
+ MX6Q_PAD_GPIO_4__GPIO_1_4, /* Enable */
+
+ /* CCM */
+ MX6Q_PAD_GPIO_0__CCM_CLKO, /* SGTL500 sys_mclk */
+ MX6Q_PAD_GPIO_3__CCM_CLKO2, /* J5 - Camera MCLK */
+
+ /* ECSPI1 */
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO,
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ENET */
+ MX6Q_PAD_ENET_MDIO__ENET_MDIO,
+ MX6Q_PAD_ENET_MDC__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ MX6Q_PAD_ENET_TX_EN__GPIO_1_28, /* Micrel RGMII Phy Interrupt */
+ MX6Q_PAD_EIM_D23__GPIO_3_23, /* RGMII reset */
+
+ /* GPIO1 */
+ MX6Q_PAD_ENET_RX_ER__GPIO_1_24, /* J9 - Microphone Detect */
+
+ /* GPIO2 */
+ MX6Q_PAD_NANDF_D1__GPIO_2_1, /* J14 - Menu Button */
+ MX6Q_PAD_NANDF_D2__GPIO_2_2, /* J14 - Back Button */
+ MX6Q_PAD_NANDF_D3__GPIO_2_3, /* J14 - Search Button */
+ MX6Q_PAD_NANDF_D4__GPIO_2_4, /* J14 - Home Button */
+ MX6Q_PAD_EIM_A22__GPIO_2_16, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A21__GPIO_2_17, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A20__GPIO_2_18, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A19__GPIO_2_19, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A18__GPIO_2_20, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A17__GPIO_2_21, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A16__GPIO_2_22, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_RW__GPIO_2_26, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_LBA__GPIO_2_27, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB0__GPIO_2_28, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB1__GPIO_2_29, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB3__GPIO_2_31, /* J12 - Boot Mode Select */
+
+ /* GPIO3 */
+ MX6Q_PAD_EIM_DA0__GPIO_3_0, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA1__GPIO_3_1, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA2__GPIO_3_2, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA3__GPIO_3_3, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA4__GPIO_3_4, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA5__GPIO_3_5, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA6__GPIO_3_6, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA7__GPIO_3_7, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA8__GPIO_3_8, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA9__GPIO_3_9, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA10__GPIO_3_10, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA11__GPIO_3_11, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA12__GPIO_3_12, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA13__GPIO_3_13, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA14__GPIO_3_14, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA15__GPIO_3_15, /* J12 - Boot Mode Select */
+
+ /* GPIO4 */
+ MX6Q_PAD_GPIO_19__GPIO_4_5, /* J14 - Volume Down */
+
+ /* GPIO5 */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A24__GPIO_5_4, /* J12 - Boot Mode Select */
+
+ /* GPIO6 */
+ MX6Q_PAD_EIM_A23__GPIO_6_6, /* J12 - Boot Mode Select */
+
+ /* GPIO7 */
+ MX6Q_PAD_GPIO_17__GPIO_7_12, /* USB Hub Reset */
+ MX6Q_PAD_GPIO_18__GPIO_7_13, /* J14 - Volume Up */
+
+ /* I2C1, SGTL5000 */
+ MX6Q_PAD_EIM_D21__I2C1_SCL, /* GPIO3[21] */
+ MX6Q_PAD_EIM_D28__I2C1_SDA, /* GPIO3[28] */
+
+ /* I2C2 Camera, MIPI */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* GPIO4[12] */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* GPIO4[13] */
+
+ /* I2C3 */
+ MX6Q_PAD_GPIO_5__I2C3_SCL, /* GPIO1[5] - J7 - Display card */
+#ifdef CONFIG_FEC_1588
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#else
+ MX6Q_PAD_GPIO_16__I2C3_SDA, /* GPIO7[11] - J15 - RGB connector */
+#endif
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
+ MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+ MX6Q_PAD_GPIO_7__GPIO_1_7, /* J7 - Display Connector GP */
+ MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
+ MX6Q_PAD_NANDF_D0__GPIO_2_0, /* J6 - LVDS Display contrast */
+
+
+ /* PWM1 */
+ MX6Q_PAD_SD1_DAT3__PWM1_PWMO, /* GPIO1[21] */
+
+ /* PWM2 */
+ MX6Q_PAD_SD1_DAT2__PWM2_PWMO, /* GPIO1[19] */
+
+ /* PWM3 */
+ MX6Q_PAD_SD1_DAT1__PWM3_PWMO, /* GPIO1[17] */
+
+ /* PWM4 */
+ MX6Q_PAD_SD1_CMD__PWM4_PWMO, /* GPIO1[18] */
+
+ /* UART1 */
+ MX6Q_PAD_SD3_DAT7__UART1_TXD,
+ MX6Q_PAD_SD3_DAT6__UART1_RXD,
+
+ /* UART2 for debug */
+ MX6Q_PAD_EIM_D26__UART2_TXD,
+ MX6Q_PAD_EIM_D27__UART2_RXD,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+
+ /* USB OC pin */
+ MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC,
+ MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC,
+
+ /* USDHC3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT5__GPIO_7_0, /* J18 - SD3_CD */
+ NEW_PAD_CTRL(MX6Q_PAD_SD3_DAT4__GPIO_7_1, MX6Q_SABRELITE_SD3_WP_PADCFG),
+
+ /* USDHC4 */
+ MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6Q_PAD_NANDF_D6__GPIO_2_6, /* J20 - SD4_CD */
+ MX6Q_PAD_NANDF_D7__GPIO_2_7, /* SD4_WP */
+};
+
+static iomux_v3_cfg_t mx6q_sabrelite_csi0_sensor_pads[] = {
+ /* IPU1 Camera */
+ MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8,
+ MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9,
+ MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10,
+ MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11,
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__GPIO_1_6, /* J5 - Camera GP */
+#endif
+ MX6Q_PAD_GPIO_8__GPIO_1_8, /* J5 - Camera Reset */
+ MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* J5 - Camera GP */
+ MX6Q_PAD_NANDF_D5__GPIO_2_5, /* J16 - MIPI GP */
+ MX6Q_PAD_NANDF_WP_B__GPIO_6_9, /* J16 - MIPI GP */
+};
+
+static iomux_v3_cfg_t mx6q_sabrelite_hdmi_ddc_pads[] = {
+ MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6q_sabrelite_i2c2_pads[] = {
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
+
+#define MX6Q_USDHC_PAD_SETTING(id, speed) \
+mx6q_sd##id##_##speed##mhz[] = { \
+ MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 200);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 2:
+ sd_pads_200mhz = mx6q_sd3_200mhz;
+ sd_pads_100mhz = mx6q_sd3_100mhz;
+ sd_pads_50mhz = mx6q_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
+ break;
+ case 3:
+ sd_pads_200mhz = mx6q_sd4_200mhz;
+ sd_pads_100mhz = mx6q_sd4_100mhz;
+ sd_pads_50mhz = mx6q_sd4_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6q_sabrelite_sd3_data __initconst = {
+ .cd_gpio = MX6Q_SABRELITE_SD3_CD,
+ .wp_gpio = MX6Q_SABRELITE_SD3_WP,
+ .keep_power_at_suspend = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6q_sabrelite_sd4_data __initconst = {
+ .cd_gpio = MX6Q_SABRELITE_SD4_CD,
+ .wp_gpio = MX6Q_SABRELITE_SD4_WP,
+ .keep_power_at_suspend = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct anatop_thermal_platform_data
+ mx6q_sabrelite_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static inline void mx6q_sabrelite_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL);
+ imx6q_add_imx_uart(1, NULL);
+}
+
+static int mx6q_sabrelite_fec_phy_init(struct phy_device *phydev)
+{
+ /* prefer master mode, disable 1000 Base-T capable */
+ phy_write(phydev, 0x9, 0x1c00);
+
+ /* min rx data delay */
+ phy_write(phydev, 0x0b, 0x8105);
+ phy_write(phydev, 0x0c, 0x0000);
+
+ /* max rx/tx clock delay, min rx/tx control delay */
+ phy_write(phydev, 0x0b, 0x8104);
+ phy_write(phydev, 0x0c, 0xf0f0);
+ phy_write(phydev, 0x0b, 0x104);
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6q_sabrelite_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
+};
+
+static int mx6q_sabrelite_spi_cs[] = {
+ MX6Q_SABRELITE_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx6q_sabrelite_spi_data __initconst = {
+ .chipselect = mx6q_sabrelite_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabrelite_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition imx6_sabrelite_spi_nor_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data imx6_sabrelite__spi_flash_data = {
+ .name = "m25p80",
+ .parts = imx6_sabrelite_spi_nor_partitions,
+ .nr_parts = ARRAY_SIZE(imx6_sabrelite_spi_nor_partitions),
+ .type = "sst25vf016b",
+};
+#endif
+
+static struct spi_board_info imx6_sabrelite_spi_nor_device[] __initdata = {
+#if defined(CONFIG_MTD_M25P80)
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &imx6_sabrelite__spi_flash_data,
+ },
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(imx6_sabrelite_spi_nor_device,
+ ARRAY_SIZE(imx6_sabrelite_spi_nor_device));
+}
+
+static struct mxc_audio_platform_data mx6_sabrelite_audio_data;
+
+static int mx6_sabrelite_sgtl5000_init(void)
+{
+ struct clk *clko;
+ struct clk *new_parent;
+ int rate;
+
+ clko = clk_get(NULL, "clko_clk");
+ if (IS_ERR(clko)) {
+ pr_err("can't get CLKO clock.\n");
+ return PTR_ERR(clko);
+ }
+ new_parent = clk_get(NULL, "ahb");
+ if (!IS_ERR(new_parent)) {
+ clk_set_parent(clko, new_parent);
+ clk_put(new_parent);
+ }
+ rate = clk_round_rate(clko, 16000000);
+ if (rate < 8000000 || rate > 27000000) {
+ pr_err("Error:SGTL5000 mclk freq %d out of range!\n", rate);
+ clk_put(clko);
+ return -1;
+ }
+
+ mx6_sabrelite_audio_data.sysclk = rate;
+ clk_set_rate(clko, rate);
+ clk_enable(clko);
+ return 0;
+}
+
+static struct imx_ssi_platform_data mx6_sabrelite_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data mx6_sabrelite_audio_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 4,
+ .init = mx6_sabrelite_sgtl5000_init,
+ .hp_gpio = -1,
+};
+
+static struct platform_device mx6_sabrelite_audio_device = {
+ .name = "imx-sgtl5000",
+};
+
+static struct imxi2c_platform_data mx6q_sabrelite_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("sgtl5000", 0x0a),
+ },
+};
+
+static void mx6q_csi0_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 1);
+ else
+ gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 0);
+
+ msleep(2);
+}
+
+static void mx6q_csi0_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_csi0_sensor_pads,
+ ARRAY_SIZE(mx6q_sabrelite_csi0_sensor_pads));
+
+ /* Camera power down */
+ gpio_request(MX6Q_SABRELITE_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6Q_SABRELITE_CSI0_PWN, 1);
+ msleep(1);
+ gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 0);
+
+ /* Camera reset */
+ gpio_request(MX6Q_SABRELITE_CSI0_RST, "cam-reset");
+ gpio_direction_output(MX6Q_SABRELITE_CSI0_RST, 1);
+
+ gpio_set_value(MX6Q_SABRELITE_CSI0_RST, 0);
+ msleep(1);
+ gpio_set_value(MX6Q_SABRELITE_CSI0_RST, 1);
+
+ /* For MX6Q GPR1 bit19 and bit20 meaning:
+ * Bit19: 0 - Enable mipi to IPU1 CSI0
+ * virtual channel is fixed to 0
+ * 1 - Enable parallel interface to IPU1 CSI0
+ * Bit20: 0 - Enable mipi to IPU2 CSI1
+ * virtual channel is fixed to 3
+ * 1 - Enable parallel interface to IPU2 CSI1
+ * IPU1 CSI1 directly connect to mipi csi2,
+ * virtual channel is fixed to 1
+ * IPU2 CSI0 directly connect to mipi csi2,
+ * virtual channel is fixed to 2
+ */
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .mclk = 24000000,
+ .mclk_source = 0,
+ .csi = 0,
+ .io_init = mx6q_csi0_io_init,
+ .pwdn = mx6q_csi0_cam_powerdown,
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ },
+ {
+ I2C_BOARD_INFO("ov564x", 0x3c),
+ .platform_data = (void *)&camera_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(MX6Q_SABRELITE_CAP_TCH_INT1),
+ },
+};
+
+static void imx6q_sabrelite_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6Q_SABRELITE_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(MX6Q_SABRELITE_USB_OTG_PWR, 0);
+}
+
+static void __init imx6q_sabrelite_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+ /* disable external charger detect,
+ * or it will affect signal quality at dp .
+ */
+ ret = gpio_request(MX6Q_SABRELITE_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6Q_SABRELITE_USB_OTG_PWR: %d\n",
+ ret);
+ return;
+ }
+ gpio_direction_output(MX6Q_SABRELITE_USB_OTG_PWR, 0);
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+
+ mx6_set_otghost_vbus_func(imx6q_sabrelite_usbotg_vbus);
+ mx6_usb_dr_init();
+}
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6q_sabrelite_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+#else
+ usleep_range(1000, 2000);
+ /* AHCI PHY enter into PDDQ mode if the AHCI module is not enabled */
+ tmpdata = readl(addr + PORT_PHY_CTL);
+ writel(tmpdata | PORT_PHY_CTL_PDDQ_LOC, addr + PORT_PHY_CTL);
+ pr_info("No AHCI save PWR: PDDQ %s\n", ((readl(addr + PORT_PHY_CTL)
+ >> 20) & 1) ? "enabled" : "disabled");
+#endif
+
+release_sata_clk:
+ /* disable SATA_PHY PLL */
+ writel((readl(IOMUXC_GPR13) & ~0x2), IOMUXC_GPR13);
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+static void mx6q_sabrelite_sata_exit(struct device *dev)
+{
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+}
+
+static struct ahci_platform_data mx6q_sabrelite_sata_data = {
+ .init = mx6q_sabrelite_sata_init,
+ .exit = mx6q_sabrelite_sata_exit,
+};
+#endif
+
+static struct gpio mx6q_sabrelite_flexcan_gpios[] = {
+ { MX6Q_SABRELITE_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
+ { MX6Q_SABRELITE_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
+};
+
+static void mx6q_sabrelite_flexcan0_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6Q_SABRELITE_CAN1_EN, 1);
+ gpio_set_value(MX6Q_SABRELITE_CAN1_STBY, 1);
+ } else {
+ gpio_set_value(MX6Q_SABRELITE_CAN1_EN, 0);
+ gpio_set_value(MX6Q_SABRELITE_CAN1_STBY, 0);
+ }
+}
+
+static const struct flexcan_platform_data
+ mx6q_sabrelite_flexcan0_pdata __initconst = {
+ .transceiver_switch = mx6q_sabrelite_flexcan0_switch,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M,
+};
+
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+static struct ipuv3_fb_platform_data sabrelite_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-SVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-VGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+
+ /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+ if ((mx6q_revision() > IMX_CHIP_REVISION_1_1))
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+/* On mx6x sbarelite board i2c2 iomux with hdmi ddc,
+ * the pins default work at i2c2 function,
+ when hdcp enable, the pins should work at ddc function */
+
+static void hdmi_enable_ddc_pin(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6q_sabrelite_hdmi_ddc_pads));
+}
+
+static void hdmi_disable_ddc_pin(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_i2c2_pads,
+ ARRAY_SIZE(mx6q_sabrelite_i2c2_pads));
+}
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+ .enable_pins = hdmi_enable_ddc_pin,
+ .disable_pins = hdmi_disable_ddc_pin,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 1,
+ .disp_id = 0,
+ .ext_ref = 1,
+ .mode = LDB_SEP0,
+ .sec_ipu_id = 1,
+ .sec_disp_id = 1,
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "clko2_clk",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "clko2_clk",
+ },
+};
+
+static struct ion_platform_data imx_ion_data = {
+ .nr = 1,
+ .heaps = {
+ {
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = "vpu_ion",
+ .size = SZ_64M,
+ },
+ },
+};
+
+static struct fsl_mxc_capture_platform_data capture_data[] = {
+ {
+ .csi = 0,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 0,
+ }, {
+ .csi = 1,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 1,
+ },
+};
+
+
+struct imx_vout_mem {
+ resource_size_t res_mbase;
+ resource_size_t res_msize;
+};
+
+static struct imx_vout_mem vout_mem __initdata = {
+ .res_msize = SZ_128M,
+};
+
+
+static void sabrelite_suspend_enter(void)
+{
+ /* suspend preparation */
+}
+
+static void sabrelite_suspend_exit(void)
+{
+ /* resume restore */
+}
+static const struct pm_platform_data mx6q_sabrelite_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = sabrelite_suspend_enter,
+ .suspend_exit = sabrelite_suspend_exit,
+};
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+}
+
+static struct gpio_keys_button sabrelite_buttons[] = {
+ GPIO_BUTTON(MX6Q_SABRELITE_ONOFF_KEY, KEY_POWER, 1, "key-power", 1),
+ GPIO_BUTTON(MX6Q_SABRELITE_MENU_KEY, KEY_MENU, 1, "key-memu", 0),
+ GPIO_BUTTON(MX6Q_SABRELITE_HOME_KEY, KEY_HOME, 1, "key-home", 0),
+ GPIO_BUTTON(MX6Q_SABRELITE_BACK_KEY, KEY_BACK, 1, "key-back", 0),
+ GPIO_BUTTON(MX6Q_SABRELITE_VOL_UP_KEY, KEY_VOLUMEUP, 1, "volume-up", 0),
+ GPIO_BUTTON(MX6Q_SABRELITE_VOL_DOWN_KEY, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static struct gpio_keys_platform_data sabrelite_button_data = {
+ .buttons = sabrelite_buttons,
+ .nbuttons = ARRAY_SIZE(sabrelite_buttons),
+};
+
+static struct platform_device sabrelite_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &sabrelite_button_data,
+ }
+};
+
+static void __init sabrelite_add_device_buttons(void)
+{
+ platform_device_register(&sabrelite_button_device);
+}
+#else
+static void __init sabrelite_add_device_buttons(void) {}
+#endif
+
+static struct regulator_consumer_supply sabrelite_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data sabrelite_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(sabrelite_vmmc_consumers),
+ .consumer_supplies = sabrelite_vmmc_consumers,
+};
+
+static struct fixed_voltage_config sabrelite_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sabrelite_vmmc_init,
+};
+
+static struct platform_device sabrelite_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &sabrelite_vmmc_reg_config,
+ },
+};
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+
+static struct regulator_consumer_supply sgtl5000_sabrelite_consumer_vdda = {
+ .supply = "VDDA",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_sabrelite_consumer_vddio = {
+ .supply = "VDDIO",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_sabrelite_consumer_vddd = {
+ .supply = "VDDD",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_init_data sgtl5000_sabrelite_vdda_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_sabrelite_consumer_vdda,
+};
+
+static struct regulator_init_data sgtl5000_sabrelite_vddio_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_sabrelite_consumer_vddio,
+};
+
+static struct regulator_init_data sgtl5000_sabrelite_vddd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_sabrelite_consumer_vddd,
+};
+
+static struct fixed_voltage_config sgtl5000_sabrelite_vdda_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 2500000,
+ .gpio = -1,
+ .init_data = &sgtl5000_sabrelite_vdda_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_sabrelite_vddio_reg_config = {
+ .supply_name = "VDDIO",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sgtl5000_sabrelite_vddio_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_sabrelite_vddd_reg_config = {
+ .supply_name = "VDDD",
+ .microvolts = 0,
+ .gpio = -1,
+ .init_data = &sgtl5000_sabrelite_vddd_reg_initdata,
+};
+
+static struct platform_device sgtl5000_sabrelite_vdda_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &sgtl5000_sabrelite_vdda_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_sabrelite_vddio_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &sgtl5000_sabrelite_vddio_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_sabrelite_vddd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &sgtl5000_sabrelite_vddd_reg_config,
+ },
+};
+
+#endif /* CONFIG_SND_SOC_SGTL5000 */
+
+static int imx6q_init_audio(void)
+{
+ mxc_register_device(&mx6_sabrelite_audio_device,
+ &mx6_sabrelite_audio_data);
+ imx6q_add_imx_ssi(1, &mx6_sabrelite_ssi_pdata);
+#ifdef CONFIG_SND_SOC_SGTL5000
+ platform_device_register(&sgtl5000_sabrelite_vdda_reg_devices);
+ platform_device_register(&sgtl5000_sabrelite_vddio_reg_devices);
+ platform_device_register(&sgtl5000_sabrelite_vddd_reg_devices);
+#endif
+ return 0;
+}
+
+static struct platform_pwm_backlight_data mx6_sabrelite_pwm_backlight_data = {
+ .pwm_id = 3,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct mxc_dvfs_platform_data sabrelite_dvfscore_data = {
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ char *str;
+ struct tag *t;
+ int i = 0;
+ struct ipuv3_fb_platform_data *pdata_fb = sabrelite_fb_data;
+
+ for_each_tag(t, tags) {
+ if (t->hdr.tag == ATAG_CMDLINE) {
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "fbmem=");
+ if (str != NULL) {
+ str += 6;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ while (*str == ',' &&
+ i < ARRAY_SIZE(sabrelite_fb_data)) {
+ str++;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ }
+ }
+ break;
+ }
+ }
+}
+
+static struct mipi_csi2_platform_data mipi_csi2_pdata = {
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+static int __init caam_setup(char *__unused)
+{
+ caam_enabled = 1;
+ return 1;
+}
+early_param("caam", caam_setup);
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_sabrelite_board_init(void)
+{
+ int i;
+ int ret;
+ struct clk *clko2;
+ struct clk *new_parent;
+ int rate;
+ struct platform_device *voutdev;
+
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_pads,
+ ARRAY_SIZE(mx6q_sabrelite_pads));
+
+#ifdef CONFIG_FEC_1588
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
+ gp_reg_id = sabrelite_dvfscore_data.reg_id;
+ soc_reg_id = sabrelite_dvfscore_data.soc_id;
+ pu_reg_id = sabrelite_dvfscore_data.pu_id;
+ mx6q_sabrelite_init_uart();
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+
+ for (i = 0; i < ARRAY_SIZE(sabrelite_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabrelite_fb_data[i]);
+
+ imx6q_add_vdoa();
+ imx6q_add_lcdif(&lcdif_data);
+ imx6q_add_ldb(&ldb_data);
+ voutdev = imx6q_add_v4l2_output(0);
+ if (vout_mem.res_msize && voutdev) {
+ dma_declare_coherent_memory(&voutdev->dev,
+ vout_mem.res_mbase,
+ vout_mem.res_mbase,
+ vout_mem.res_msize,
+ (DMA_MEMORY_MAP |
+ DMA_MEMORY_EXCLUSIVE));
+ }
+
+
+ imx6q_add_v4l2_capture(0, &capture_data[0]);
+ imx6q_add_v4l2_capture(1, &capture_data[1]);
+ imx6q_add_mipi_csi2(&mipi_csi2_pdata);
+ imx6q_add_imx_snvs_rtc();
+
+ if (1 == caam_enabled)
+ imx6q_add_imx_caam();
+
+ imx6q_add_imx_i2c(0, &mx6q_sabrelite_i2c_data);
+ imx6q_add_imx_i2c(1, &mx6q_sabrelite_i2c_data);
+ imx6q_add_imx_i2c(2, &mx6q_sabrelite_i2c_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6q_sabrelite_spi_data);
+ spi_device_init();
+
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6q_sabrelite_anatop_thermal_data);
+ imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+ imx6q_add_pm_imx(0, &mx6q_sabrelite_pm_data);
+ imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabrelite_sd4_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabrelite_sd3_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6q_sabrelite_init_usb();
+
+ if (cpu_is_mx6q()) {
+#ifdef CONFIG_SATA_AHCI_PLATFORM
+ imx6q_add_ahci(0, &mx6q_sabrelite_sata_data);
+#else
+ mx6q_sabrelite_sata_init(NULL,
+ (void __iomem *)ioremap(MX6Q_SATA_BASE_ADDR, SZ_4K));
+#endif
+ }
+ imx6q_add_vpu();
+ imx6q_init_audio();
+ platform_device_register(&sabrelite_vmmc_reg_devices);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
+ /* release USB Hub reset */
+ gpio_set_value(MX6Q_SABRELITE_USB_HUB_RESET, 1);
+
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm(1);
+ imx6q_add_mxc_pwm(2);
+ imx6q_add_mxc_pwm(3);
+ imx6q_add_mxc_pwm_backlight(3, &mx6_sabrelite_pwm_backlight_data);
+
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+
+ imx6q_add_dvfs_core(&sabrelite_dvfscore_data);
+
+ imx6q_add_ion(0, &imx_ion_data,
+ sizeof(imx_ion_data) + sizeof(struct ion_platform_heap));
+
+ sabrelite_add_device_buttons();
+
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+
+ ret = gpio_request_array(mx6q_sabrelite_flexcan_gpios,
+ ARRAY_SIZE(mx6q_sabrelite_flexcan_gpios));
+ if (ret)
+ pr_err("failed to request flexcan1-gpios: %d\n", ret);
+ else
+ imx6q_add_flexcan0(&mx6q_sabrelite_flexcan0_pdata);
+
+ clko2 = clk_get(NULL, "clko2_clk");
+ if (IS_ERR(clko2))
+ pr_err("can't get CLKO2 clock.\n");
+
+ new_parent = clk_get(NULL, "osc_clk");
+ if (!IS_ERR(new_parent)) {
+ clk_set_parent(clko2, new_parent);
+ clk_put(new_parent);
+ }
+ rate = clk_round_rate(clko2, 24000000);
+ clk_set_rate(clko2, rate);
+ clk_enable(clko2);
+ imx6q_add_busfreq();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_sabrelite_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART2_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mx6_sabrelite_timer = {
+ .init = mx6_sabrelite_timer_init,
+};
+
+static void __init mx6q_sabrelite_reserve(void)
+{
+ phys_addr_t phys;
+ int i;
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+
+#if defined(CONFIG_ION)
+ if (imx_ion_data.heaps[0].size) {
+ phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K);
+ memblock_remove(phys, imx_ion_data.heaps[0].size);
+ imx_ion_data.heaps[0].base = phys;
+ }
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(sabrelite_fb_data); i++)
+ if (sabrelite_fb_data[i].res_size[0]) {
+ /* reserve for background buffer */
+ phys = memblock_alloc(sabrelite_fb_data[i].res_size[0],
+ SZ_4K);
+ memblock_remove(phys, sabrelite_fb_data[i].res_size[0]);
+ sabrelite_fb_data[i].res_base[0] = phys;
+ }
+ if (vout_mem.res_msize) {
+ phys = memblock_alloc_base(vout_mem.res_msize,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, vout_mem.res_msize);
+ vout_mem.res_mbase = phys;
+ }
+
+}
+
+/*
+ * initialize __mach_desc_MX6Q_SABRELITE data structure.
+ */
+MACHINE_START(MX6Q_SABRELITE, "Freescale i.MX 6Quad Sabre-Lite Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_sabrelite_board_init,
+ .timer = &mx6_sabrelite_timer,
+ .reserve = mx6q_sabrelite_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
new file mode 100644
index 00000000..f3209116
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -0,0 +1,2046 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/ion.h>
+#include <linux/etherdevice.h>
+#include <linux/power/sabresd_battery.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/mfd/wm8994/gpio.h>
+#include <sound/wm8962.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+#include <mach/mxc_asrc.h>
+#include <mach/mipi_dsi.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6q_sabresd.h"
+#include "board-mx6dl_sabresd.h"
+
+#define SABRESD_USR_DEF_GRN_LED IMX_GPIO_NR(1, 1)
+#define SABRESD_USR_DEF_RED_LED IMX_GPIO_NR(1, 2)
+#define SABRESD_VOLUME_UP IMX_GPIO_NR(1, 4)
+#define SABRESD_VOLUME_DN IMX_GPIO_NR(1, 5)
+#define SABRESD_MICROPHONE_DET IMX_GPIO_NR(1, 9)
+#define SABRESD_CSI0_PWN IMX_GPIO_NR(1, 16)
+#define SABRESD_CSI0_RST IMX_GPIO_NR(1, 17)
+#define SABRESD_ACCL_INT IMX_GPIO_NR(1, 18)
+#define SABRESD_MIPICSI_PWN IMX_GPIO_NR(1, 19)
+#define SABRESD_MIPICSI_RST IMX_GPIO_NR(1, 20)
+#define SABRESD_RGMII_RST IMX_GPIO_NR(1, 25)
+#define SABRESD_RGMII_INT IMX_GPIO_NR(1, 26)
+#define SABRESD_CHARGE_UOK_B IMX_GPIO_NR(1, 27)
+#define SABRESD_USBH1_PWR_EN IMX_GPIO_NR(1, 29)
+#define SABRESD_DISP0_PWR_EN IMX_GPIO_NR(1, 30)
+
+#define SABRESD_SD3_CD IMX_GPIO_NR(2, 0)
+#define SABRESD_SD3_WP IMX_GPIO_NR(2, 1)
+#define SABRESD_SD2_CD IMX_GPIO_NR(2, 2)
+#define SABRESD_SD2_WP IMX_GPIO_NR(2, 3)
+#define SABRESD_CHARGE_DOK_B IMX_GPIO_NR(2, 24)
+#define SABRESD_GPS_RESET IMX_GPIO_NR(2, 28)
+#define SABRESD_SENSOR_EN IMX_GPIO_NR(2, 31)
+
+#define SABRESD_GPS_EN IMX_GPIO_NR(3, 0)
+#define SABRESD_DISP0_RST_B IMX_GPIO_NR(3, 8)
+#define SABRESD_ALS_INT IMX_GPIO_NR(3, 9)
+#define SABRESD_CHARGE_CHG_2_B IMX_GPIO_NR(3, 13)
+#define SABRESD_CHARGE_FLT_2_B IMX_GPIO_NR(3, 14)
+#define SABRESD_BAR0_INT IMX_GPIO_NR(3, 15)
+#define SABRESD_eCOMPASS_INT IMX_GPIO_NR(3, 16)
+#define SABRESD_GPS_PPS IMX_GPIO_NR(3, 18)
+#define SABRESD_PCIE_PWR_EN IMX_GPIO_NR(3, 19)
+#define SABRESD_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define SABRESD_USB_H1_PWR IMX_GPIO_NR(1, 29)
+#define SABRESD_CHARGE_CHG_1_B IMX_GPIO_NR(3, 23)
+#define SABRESD_TS_INT IMX_GPIO_NR(3, 26)
+#define SABRESD_DISP0_RD IMX_GPIO_NR(3, 28)
+#define SABRESD_POWER_OFF IMX_GPIO_NR(3, 29)
+
+#define SABRESD_CAN1_STBY IMX_GPIO_NR(4, 5)
+#define SABRESD_ECSPI1_CS0 IMX_GPIO_NR(4, 9)
+#define SABRESD_CODEC_PWR_EN IMX_GPIO_NR(4, 10)
+#define SABRESD_HDMI_CEC_IN IMX_GPIO_NR(4, 11)
+#define SABRESD_PCIE_DIS_B IMX_GPIO_NR(4, 14)
+
+#define SABRESD_DI0_D0_CS IMX_GPIO_NR(5, 0)
+#define SABRESD_CHARGE_FLT_1_B IMX_GPIO_NR(5, 2)
+#define SABRESD_PCIE_WAKE_B IMX_GPIO_NR(5, 20)
+
+#define SABRESD_CAP_TCH_INT1 IMX_GPIO_NR(6, 7)
+#define SABRESD_CAP_TCH_INT0 IMX_GPIO_NR(6, 8)
+#define SABRESD_DISP_RST_B IMX_GPIO_NR(6, 11)
+#define SABRESD_DISP_PWR_EN IMX_GPIO_NR(6, 14)
+#define SABRESD_CABC_EN0 IMX_GPIO_NR(6, 15)
+#define SABRESD_CABC_EN1 IMX_GPIO_NR(6, 16)
+#define SABRESD_AUX_3V15_EN IMX_GPIO_NR(6, 9)
+#define SABRESD_DISP0_WR_REVB IMX_GPIO_NR(6, 9)
+#define SABRESD_AUX_5V_EN IMX_GPIO_NR(6, 10)
+#define SABRESD_DI1_D0_CS IMX_GPIO_NR(6, 31)
+
+#define SABRESD_HEADPHONE_DET IMX_GPIO_NR(7, 8)
+#define SABRESD_PCIE_RST_B_REVB IMX_GPIO_NR(7, 12)
+#define SABRESD_PMIC_INT_B IMX_GPIO_NR(7, 13)
+#define SABRESD_PFUZE_INT IMX_GPIO_NR(7, 13)
+
+#define SABRESD_EPDC_SDDO_0 IMX_GPIO_NR(2, 22)
+#define SABRESD_EPDC_SDDO_1 IMX_GPIO_NR(3, 10)
+#define SABRESD_EPDC_SDDO_2 IMX_GPIO_NR(3, 12)
+#define SABRESD_EPDC_SDDO_3 IMX_GPIO_NR(3, 11)
+#define SABRESD_EPDC_SDDO_4 IMX_GPIO_NR(2, 27)
+#define SABRESD_EPDC_SDDO_5 IMX_GPIO_NR(2, 30)
+#define SABRESD_EPDC_SDDO_6 IMX_GPIO_NR(2, 23)
+#define SABRESD_EPDC_SDDO_7 IMX_GPIO_NR(2, 26)
+#define SABRESD_EPDC_SDDO_8 IMX_GPIO_NR(2, 24)
+#define SABRESD_EPDC_SDDO_9 IMX_GPIO_NR(3, 15)
+#define SABRESD_EPDC_SDDO_10 IMX_GPIO_NR(3, 16)
+#define SABRESD_EPDC_SDDO_11 IMX_GPIO_NR(3, 23)
+#define SABRESD_EPDC_SDDO_12 IMX_GPIO_NR(3, 19)
+#define SABRESD_EPDC_SDDO_13 IMX_GPIO_NR(3, 13)
+#define SABRESD_EPDC_SDDO_14 IMX_GPIO_NR(3, 14)
+#define SABRESD_EPDC_SDDO_15 IMX_GPIO_NR(5, 2)
+#define SABRESD_EPDC_GDCLK IMX_GPIO_NR(2, 17)
+#define SABRESD_EPDC_GDSP IMX_GPIO_NR(2, 16)
+#define SABRESD_EPDC_GDOE IMX_GPIO_NR(6, 6)
+#define SABRESD_EPDC_GDRL IMX_GPIO_NR(5, 4)
+#define SABRESD_EPDC_SDCLK IMX_GPIO_NR(3, 31)
+#define SABRESD_EPDC_SDOEZ IMX_GPIO_NR(3, 30)
+#define SABRESD_EPDC_SDOED IMX_GPIO_NR(3, 26)
+#define SABRESD_EPDC_SDOE IMX_GPIO_NR(3, 27)
+#define SABRESD_EPDC_SDLE IMX_GPIO_NR(3, 1)
+#define SABRESD_EPDC_SDCLKN IMX_GPIO_NR(3, 0)
+#define SABRESD_EPDC_SDSHR IMX_GPIO_NR(2, 29)
+#define SABRESD_EPDC_PWRCOM IMX_GPIO_NR(2, 28)
+#define SABRESD_EPDC_PWRSTAT IMX_GPIO_NR(2, 21)
+#define SABRESD_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 20)
+#define SABRESD_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 19)
+#define SABRESD_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 18)
+#define SABRESD_EPDC_PWRCTRL3 IMX_GPIO_NR(3, 28)
+#define SABRESD_EPDC_BDR0 IMX_GPIO_NR(3, 2)
+#define SABRESD_EPDC_BDR1 IMX_GPIO_NR(3, 3)
+#define SABRESD_EPDC_SDCE0 IMX_GPIO_NR(3, 4)
+#define SABRESD_EPDC_SDCE1 IMX_GPIO_NR(3, 5)
+#define SABRESD_EPDC_SDCE2 IMX_GPIO_NR(3, 6)
+#define SABRESD_EPDC_SDCE3 IMX_GPIO_NR(3, 7)
+#define SABRESD_EPDC_SDCE4 IMX_GPIO_NR(3, 8)
+#define SABRESD_EPDC_PMIC_WAKE IMX_GPIO_NR(3, 20)
+#define SABRESD_EPDC_PMIC_INT IMX_GPIO_NR(2, 25)
+#define SABRESD_EPDC_VCOM IMX_GPIO_NR(3, 17)
+#define SABRESD_CHARGE_NOW IMX_GPIO_NR(1, 2)
+#define SABRESD_CHARGE_DONE IMX_GPIO_NR(1, 1)
+#define SABRESD_ELAN_CE IMX_GPIO_NR(2, 18)
+#define SABRESD_ELAN_RST IMX_GPIO_NR(3, 8)
+#define SABRESD_ELAN_INT IMX_GPIO_NR(3, 28)
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6_ENET_IRQ IMX_GPIO_NR(1, 6)
+#define IOMUX_OBSRV_MUX1_OFFSET 0x3c
+#define OBSRV_MUX1_MASK 0x3f
+#define OBSRV_MUX1_ENET_IRQ 0x9
+#endif
+
+static struct clk *sata_clk;
+static struct clk *clko;
+static int mma8451_position = 1;
+static int mag3110_position = 2;
+static int max11801_mode = 1;
+static int enable_lcd_ldb;
+
+static int caam_enabled;
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int epdc_enabled;
+
+static int max17135_regulator_init(struct max17135 *max17135);
+
+static const struct esdhc_platform_data mx6q_sabresd_sd2_data __initconst = {
+ .cd_gpio = SABRESD_SD2_CD,
+ .wp_gpio = SABRESD_SD2_WP,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_CONTROLLER,
+ .runtime_pm = 1,
+};
+
+static const struct esdhc_platform_data mx6q_sabresd_sd3_data __initconst = {
+ .cd_gpio = SABRESD_SD3_CD,
+ .wp_gpio = SABRESD_SD3_WP,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_CONTROLLER,
+};
+
+static const struct esdhc_platform_data mx6q_sabresd_sd4_data __initconst = {
+ .always_present = 1,
+ .keep_power_at_suspend = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+static const struct anatop_thermal_platform_data
+ mx6q_sabresd_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static inline void mx6q_sabresd_init_uart(void)
+{
+ imx6q_add_imx_uart(2, NULL);
+ imx6q_add_imx_uart(0, NULL);
+}
+
+static int mx6q_sabresd_fec_phy_init(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+ phy_write(phydev, 0xd, 0x7);
+ phy_write(phydev, 0xe, 0x8016);
+ phy_write(phydev, 0xd, 0x4007);
+ val = phy_read(phydev, 0xe);
+
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, 0xe, val);
+
+ /* Introduce tx clock delay */
+ phy_write(phydev, 0x1d, 0x5);
+ val = phy_read(phydev, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, 0x1e, val);
+
+ /*check phy power*/
+ val = phy_read(phydev, 0x0);
+
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6q_sabresd_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ .gpio_irq = MX6_ENET_IRQ,
+#endif
+};
+
+static int mx6q_sabresd_spi_cs[] = {
+ SABRESD_ECSPI1_CS0,
+};
+
+static const struct spi_imx_master mx6q_sabresd_spi_data __initconst = {
+ .chipselect = mx6q_sabresd_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabresd_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition imx6_sabresd_spi_nor_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data imx6_sabresd__spi_flash_data = {
+ .name = "m25p80",
+ .parts = imx6_sabresd_spi_nor_partitions,
+ .nr_parts = ARRAY_SIZE(imx6_sabresd_spi_nor_partitions),
+ .type = "sst25vf016b",
+};
+#endif
+
+static struct spi_board_info imx6_sabresd_spi_nor_device[] __initdata = {
+#if defined(CONFIG_MTD_M25P80)
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &imx6_sabresd__spi_flash_data,
+ },
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(imx6_sabresd_spi_nor_device,
+ ARRAY_SIZE(imx6_sabresd_spi_nor_device));
+}
+
+static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct platform_device mx6_sabresd_audio_wm8958_device = {
+ .name = "imx-wm8958",
+};
+
+static struct mxc_audio_platform_data wm8958_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = SABRESD_HEADPHONE_DET,
+ .hp_active_low = 1,
+};
+
+static struct wm8994_pdata wm8958_config_data = {
+ .gpio_defaults = {
+ [0] = WM8994_GP_FN_GPIO | WM8994_GPN_DB,
+ [1] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [2] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [3] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [4] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [5] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [7] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [8] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [9] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ [10] = WM8994_GP_FN_GPIO | WM8994_GPN_DB | WM8994_GPN_PD,
+ },
+};
+
+static int mxc_wm8958_init(void)
+{
+ struct clk *clko;
+ int rate;
+
+ clko = clk_get(NULL, "clko_clk");
+ if (IS_ERR(clko)) {
+ pr_err("can't get CLKO clock.\n");
+ return PTR_ERR(clko);
+ }
+ /* both audio codec and comera use CLKO clk*/
+ rate = clk_round_rate(clko, 24000000);
+
+ wm8958_data.sysclk = rate;
+ clk_set_rate(clko, rate);
+
+ /* enable wm8958 4.2v power supply */
+ gpio_request(SABRESD_CODEC_PWR_EN, "aud_4v2");
+ gpio_direction_output(SABRESD_CODEC_PWR_EN, 1);
+ msleep(1);
+ gpio_set_value(SABRESD_CODEC_PWR_EN, 1);
+
+ return 0;
+}
+
+static struct platform_device mx6_sabresd_audio_wm8962_device = {
+ .name = "imx-wm8962",
+};
+
+static struct mxc_audio_platform_data wm8962_data;
+
+static int wm8962_clk_enable(int enable)
+{
+ if (enable)
+ clk_enable(clko);
+ else
+ clk_disable(clko);
+
+ return 0;
+}
+
+static int mxc_wm8962_init(void)
+{
+ int rate;
+
+ clko = clk_get(NULL, "clko_clk");
+ if (IS_ERR(clko)) {
+ pr_err("can't get CLKO clock.\n");
+ return PTR_ERR(clko);
+ }
+ /* both audio codec and comera use CLKO clk*/
+ rate = clk_round_rate(clko, 24000000);
+ clk_set_rate(clko, rate);
+
+ wm8962_data.sysclk = rate;
+
+ return 0;
+}
+
+static struct wm8962_pdata wm8962_config_data = {
+ .gpio_init = {
+ [2] = WM8962_GPIO_FN_DMICCLK,
+ [4] = 0x8000 | WM8962_GPIO_FN_DMICDAT,
+ },
+};
+
+static struct mxc_audio_platform_data wm8962_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = SABRESD_HEADPHONE_DET,
+ .hp_active_low = 1,
+ .mic_gpio = SABRESD_MICROPHONE_DET,
+ .mic_active_low = 1,
+ .init = mxc_wm8962_init,
+ .clock_enable = wm8962_clk_enable,
+};
+
+static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "0-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "0-001a"),
+};
+
+static struct regulator_init_data sabresd_vwm8962_init = {
+ .constraints = {
+ .name = "SPKVDD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers),
+ .consumer_supplies = sabresd_vwm8962_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vwm8962_reg_config = {
+ .supply_name = "SPKVDD",
+ .microvolts = 4200000,
+ .gpio = SABRESD_CODEC_PWR_EN,
+ .enable_high = 1,
+ .enabled_at_boot = 1,
+ .init_data = &sabresd_vwm8962_init,
+};
+
+static struct platform_device sabresd_vwm8962_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &sabresd_vwm8962_reg_config,
+ },
+};
+
+static void mx6q_csi0_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(SABRESD_CSI0_PWN, 1);
+ else
+ gpio_set_value(SABRESD_CSI0_PWN, 0);
+
+ msleep(2);
+}
+
+static void mx6q_csi0_io_init(void)
+{
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_csi0_sensor_pads,
+ ARRAY_SIZE(mx6q_sabresd_csi0_sensor_pads));
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_csi0_sensor_pads,
+ ARRAY_SIZE(mx6dl_sabresd_csi0_sensor_pads));
+
+ /* Camera reset */
+ gpio_request(SABRESD_CSI0_RST, "cam-reset");
+ gpio_direction_output(SABRESD_CSI0_RST, 1);
+
+ /* Camera power down */
+ gpio_request(SABRESD_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(SABRESD_CSI0_PWN, 1);
+ msleep(5);
+ gpio_set_value(SABRESD_CSI0_PWN, 0);
+ msleep(5);
+ gpio_set_value(SABRESD_CSI0_RST, 0);
+ msleep(1);
+ gpio_set_value(SABRESD_CSI0_RST, 1);
+ msleep(5);
+ gpio_set_value(SABRESD_CSI0_PWN, 1);
+
+ /* For MX6Q:
+ * GPR1 bit19 and bit20 meaning:
+ * Bit19: 0 - Enable mipi to IPU1 CSI0
+ * virtual channel is fixed to 0
+ * 1 - Enable parallel interface to IPU1 CSI0
+ * Bit20: 0 - Enable mipi to IPU2 CSI1
+ * virtual channel is fixed to 3
+ * 1 - Enable parallel interface to IPU2 CSI1
+ * IPU1 CSI1 directly connect to mipi csi2,
+ * virtual channel is fixed to 1
+ * IPU2 CSI0 directly connect to mipi csi2,
+ * virtual channel is fixed to 2
+ *
+ * For MX6DL:
+ * GPR13 bit 0-2 IPU_CSI0_MUX
+ * 000 MIPI_CSI0
+ * 100 IPU CSI0
+ */
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .mclk = 24000000,
+ .mclk_source = 0,
+ .csi = 0,
+ .io_init = mx6q_csi0_io_init,
+ .pwdn = mx6q_csi0_cam_powerdown,
+};
+
+static void mx6q_mipi_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(SABRESD_MIPICSI_PWN, 1);
+ else
+ gpio_set_value(SABRESD_MIPICSI_PWN, 0);
+
+ msleep(2);
+}
+
+static void mx6q_mipi_sensor_io_init(void)
+{
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_mipi_sensor_pads,
+ ARRAY_SIZE(mx6q_sabresd_mipi_sensor_pads));
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_mipi_sensor_pads,
+ ARRAY_SIZE(mx6dl_sabresd_mipi_sensor_pads));
+
+ /* Camera reset */
+ gpio_request(SABRESD_MIPICSI_RST, "cam-reset");
+ gpio_direction_output(SABRESD_MIPICSI_RST, 1);
+
+ /* Camera power down */
+ gpio_request(SABRESD_MIPICSI_PWN, "cam-pwdn");
+ gpio_direction_output(SABRESD_MIPICSI_PWN, 1);
+ msleep(5);
+ gpio_set_value(SABRESD_MIPICSI_PWN, 0);
+ msleep(5);
+ gpio_set_value(SABRESD_MIPICSI_RST, 0);
+ msleep(1);
+ gpio_set_value(SABRESD_MIPICSI_RST, 1);
+ msleep(5);
+ gpio_set_value(SABRESD_MIPICSI_PWN, 1);
+
+ /*for mx6dl, mipi virtual channel 1 connect to csi 1*/
+ if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 3, 3, 1);
+}
+
+static struct fsl_mxc_camera_platform_data mipi_csi2_data = {
+ .mclk = 24000000,
+ .mclk_source = 0,
+ .csi = 1,
+ .io_init = mx6q_mipi_sensor_io_init,
+ .pwdn = mx6q_mipi_powerdown,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = SABRESD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = SABRESD_EPDC_VCOM,
+ .gpio_pmic_wakeup = SABRESD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = SABRESD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = SABRESD_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ if (!epdc_enabled) {
+ printk(KERN_DEBUG
+ "max17135_regulator_init abort: EPDC not enabled\n");
+ return 0;
+ }
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * TODO: We cannot enable full constraints for now, since
+ * it results in the PFUZE regulators being disabled
+ * at the end of boot, which disables critical regulators.
+ */
+ /*regulator_has_full_constraints();*/
+
+ return 0;
+}
+
+static struct imxi2c_platform_data mx6q_sabresd_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct fsl_mxc_lightsensor_platform_data ls_data = {
+ .rext = 499, /* calibration: 499K->700K */
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm89**", 0x1a),
+ },
+ {
+ I2C_BOARD_INFO("ov5642", 0x3c),
+ .platform_data = (void *)&camera_data,
+ },
+ {
+ I2C_BOARD_INFO("mma8451", 0x1c),
+ .platform_data = (void *)&mma8451_position,
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ },
+ {
+ I2C_BOARD_INFO("ov5640_mipi", 0x3c),
+ .platform_data = (void *)&mipi_csi2_data,
+ },
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(SABRESD_CAP_TCH_INT0),
+ },
+ {
+ I2C_BOARD_INFO("max11801", 0x48),
+ .platform_data = (void *)&max11801_mode,
+ .irq = gpio_to_irq(SABRESD_TS_INT),
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0x48),
+ .platform_data = &max17135_pdata,
+ },
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(SABRESD_CAP_TCH_INT1),
+ },
+ {
+ I2C_BOARD_INFO("mag3110", 0x0e),
+ .irq = gpio_to_irq(SABRESD_eCOMPASS_INT),
+ .platform_data = (void *)&mag3110_position,
+ },
+ {
+ I2C_BOARD_INFO("isl29023", 0x44),
+ .irq = gpio_to_irq(SABRESD_ALS_INT),
+ .platform_data = &ls_data,
+ }, {
+ I2C_BOARD_INFO("elan-touch", 0x10),
+ .irq = gpio_to_irq(SABRESD_ELAN_INT),
+ },
+ {
+ I2C_BOARD_INFO("mxc_ldb_i2c", 0x50),
+ .platform_data = (void *)0,
+ },
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(SABRESD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(SABRESD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(SABRESD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(SABRESD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(SABRESD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(SABRESD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(SABRESD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(SABRESD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(SABRESD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(SABRESD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(SABRESD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(SABRESD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(SABRESD_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(SABRESD_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(SABRESD_EPDC_SDDO_0);
+ gpio_free(SABRESD_EPDC_SDDO_1);
+ gpio_free(SABRESD_EPDC_SDDO_2);
+ gpio_free(SABRESD_EPDC_SDDO_3);
+ gpio_free(SABRESD_EPDC_SDDO_4);
+ gpio_free(SABRESD_EPDC_SDDO_5);
+ gpio_free(SABRESD_EPDC_SDDO_6);
+ gpio_free(SABRESD_EPDC_SDDO_7);
+ gpio_free(SABRESD_EPDC_GDCLK);
+ gpio_free(SABRESD_EPDC_GDSP);
+ gpio_free(SABRESD_EPDC_GDOE);
+ gpio_free(SABRESD_EPDC_GDRL);
+ gpio_free(SABRESD_EPDC_SDCLK);
+ gpio_free(SABRESD_EPDC_SDOE);
+ gpio_free(SABRESD_EPDC_SDLE);
+ gpio_free(SABRESD_EPDC_SDSHR);
+ gpio_free(SABRESD_EPDC_BDR0);
+ gpio_free(SABRESD_EPDC_SDCE0);
+ gpio_free(SABRESD_EPDC_SDCE1);
+ gpio_free(SABRESD_EPDC_SDCE2);
+}
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6dl_sabresd_epdc_enable_pads));
+
+ gpio_direction_input(SABRESD_EPDC_SDDO_0);
+ gpio_direction_input(SABRESD_EPDC_SDDO_1);
+ gpio_direction_input(SABRESD_EPDC_SDDO_2);
+ gpio_direction_input(SABRESD_EPDC_SDDO_3);
+ gpio_direction_input(SABRESD_EPDC_SDDO_4);
+ gpio_direction_input(SABRESD_EPDC_SDDO_5);
+ gpio_direction_input(SABRESD_EPDC_SDDO_6);
+ gpio_direction_input(SABRESD_EPDC_SDDO_7);
+ gpio_direction_input(SABRESD_EPDC_GDCLK);
+ gpio_direction_input(SABRESD_EPDC_GDSP);
+ gpio_direction_input(SABRESD_EPDC_GDOE);
+ gpio_direction_input(SABRESD_EPDC_GDRL);
+ gpio_direction_input(SABRESD_EPDC_SDCLK);
+ gpio_direction_input(SABRESD_EPDC_SDOE);
+ gpio_direction_input(SABRESD_EPDC_SDLE);
+ gpio_direction_input(SABRESD_EPDC_SDSHR);
+ gpio_direction_input(SABRESD_EPDC_BDR0);
+ gpio_direction_input(SABRESD_EPDC_SDCE0);
+ gpio_direction_input(SABRESD_EPDC_SDCE1);
+ gpio_direction_input(SABRESD_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6dl_sabresd_epdc_disable_pads));
+
+ gpio_direction_output(SABRESD_EPDC_SDDO_0, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_1, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_2, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_3, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_4, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_5, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_6, 0);
+ gpio_direction_output(SABRESD_EPDC_SDDO_7, 0);
+ gpio_direction_output(SABRESD_EPDC_GDCLK, 0);
+ gpio_direction_output(SABRESD_EPDC_GDSP, 0);
+ gpio_direction_output(SABRESD_EPDC_GDOE, 0);
+ gpio_direction_output(SABRESD_EPDC_GDRL, 0);
+ gpio_direction_output(SABRESD_EPDC_SDCLK, 0);
+ gpio_direction_output(SABRESD_EPDC_SDOE, 0);
+ gpio_direction_output(SABRESD_EPDC_SDLE, 0);
+ gpio_direction_output(SABRESD_EPDC_SDSHR, 0);
+ gpio_direction_output(SABRESD_EPDC_BDR0, 0);
+ gpio_direction_output(SABRESD_EPDC_SDCE0, 0);
+ gpio_direction_output(SABRESD_EPDC_SDCE1, 0);
+ gpio_direction_output(SABRESD_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static void imx6q_sabresd_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(SABRESD_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(SABRESD_USB_OTG_PWR, 0);
+}
+
+static void __init imx6q_sabresd_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+ /* disable external charger detect,
+ * or it will affect signal quality at dp .
+ */
+ ret = gpio_request(SABRESD_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO SABRESD_USB_OTG_PWR: %d\n",
+ ret);
+ return;
+ }
+ gpio_direction_output(SABRESD_USB_OTG_PWR, 0);
+ /* keep USB host1 VBUS always on */
+ ret = gpio_request(SABRESD_USB_H1_PWR, "usb-h1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO SABRESD_USB_H1_PWR: %d\n",
+ ret);
+ return;
+ }
+ gpio_direction_output(SABRESD_USB_H1_PWR, 1);
+ if (board_is_mx6_reva())
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+ else
+ mxc_iomux_set_gpr_register(1, 13, 1, 0);
+
+ mx6_set_otghost_vbus_func(imx6q_sabresd_usbotg_vbus);
+}
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6q_sabresd_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ ret = sata_init(addr, tmpdata);
+ if (ret == 0)
+ return ret;
+
+release_sata_clk:
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+static void mx6q_sabresd_sata_exit(struct device *dev)
+{
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+}
+
+static struct ahci_platform_data mx6q_sabresd_sata_data = {
+ .init = mx6q_sabresd_sata_init,
+ .exit = mx6q_sabresd_sata_exit,
+};
+
+static void mx6q_sabresd_flexcan0_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(SABRESD_CAN1_STBY, 1);
+ } else {
+ gpio_set_value(SABRESD_CAN1_STBY, 0);
+ }
+}
+
+static const struct flexcan_platform_data
+ mx6q_sabresd_flexcan0_pdata __initconst = {
+ .transceiver_switch = mx6q_sabresd_flexcan0_switch,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M + SZ_64M,
+};
+
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+static void mx6_reset_mipi_dsi(void)
+{
+ gpio_set_value(SABRESD_DISP_PWR_EN, 1);
+ gpio_set_value(SABRESD_DISP_RST_B, 1);
+ udelay(10);
+ gpio_set_value(SABRESD_DISP_RST_B, 0);
+ udelay(50);
+ gpio_set_value(SABRESD_DISP_RST_B, 1);
+
+ /*
+ * it needs to delay 120ms minimum for reset complete
+ */
+ msleep(120);
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+ .ipu_id = 0,
+ .disp_id = 1,
+ .lcd_panel = "TRULY-WVGA",
+ .reset = mx6_reset_mipi_dsi,
+};
+
+static struct ipuv3_fb_platform_data sabresd_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ .late_init = false,
+ }, {
+ .disp_dev = "hdmi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "1920x1080M@60",
+ .default_bpp = 32,
+ .int_clk = false,
+ .late_init = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
+ .late_init = false,
+ },
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+
+ /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+ if (hdmi_SDMA_check())
+ mxc_iomux_set_gpr_register(0, 0, 1, 1);
+}
+
+/* On mx6x sabresd board i2c2 iomux with hdmi ddc,
+ * the pins default work at i2c2 function,
+ when hdcp enable, the pins should work at ddc function */
+
+static void hdmi_enable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6dl_sabresd_hdmi_ddc_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_hdmi_ddc_pads,
+ ARRAY_SIZE(mx6q_sabresd_hdmi_ddc_pads));
+}
+
+static void hdmi_disable_ddc_pin(void)
+{
+ if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_i2c2_pads,
+ ARRAY_SIZE(mx6dl_sabresd_i2c2_pads));
+ else
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_i2c2_pads,
+ ARRAY_SIZE(mx6q_sabresd_i2c2_pads));
+}
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+ .enable_pins = hdmi_enable_ddc_pin,
+ .disable_pins = hdmi_disable_ddc_pin,
+ .phy_reg_vlev = 0x0294,
+ .phy_reg_cksymtx = 0x800d,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 1,
+ .disp_id = 1,
+ .ext_ref = 1,
+ .mode = LDB_SEP1,
+ .sec_ipu_id = 1,
+ .sec_disp_id = 0,
+};
+
+static struct max8903_pdata charger1_data = {
+ .dok = SABRESD_CHARGE_DOK_B,
+ .uok = SABRESD_CHARGE_UOK_B,
+ .chg = SABRESD_CHARGE_CHG_1_B,
+ .flt = SABRESD_CHARGE_FLT_1_B,
+ .dcm_always_high = true,
+ .dc_valid = true,
+ .usb_valid = true,
+};
+
+static struct platform_device sabresd_max8903_charger_1 = {
+ .name = "max8903-charger",
+ .id = 1,
+ .dev = {
+ .platform_data = &charger1_data,
+ },
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ .bypass_reset = false,
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "clko_clk",
+ .bypass_reset = false,
+ },
+};
+
+static struct ion_platform_data imx_ion_data = {
+ .nr = 1,
+ .heaps = {
+ {
+ .id = 0,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = "vpu_ion",
+ .size = SZ_64M,
+ },
+ },
+};
+
+static struct fsl_mxc_capture_platform_data capture_data[] = {
+ {
+ .csi = 0,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 0,
+ }, {
+ .csi = 1,
+ .ipu = 0,
+ .mclk_source = 0,
+ .is_mipi = 1,
+ },
+};
+
+
+struct imx_vout_mem {
+ resource_size_t res_mbase;
+ resource_size_t res_msize;
+};
+
+static struct imx_vout_mem vout_mem __initdata = {
+ .res_msize = SZ_128M,
+};
+
+static void sabresd_suspend_enter(void)
+{
+ /* suspend preparation */
+ /* Disable AUX 5V */
+ gpio_set_value(SABRESD_AUX_5V_EN, 0);
+}
+
+static void sabresd_suspend_exit(void)
+{
+ /* resume restore */
+ /* Enable AUX 5V */
+ gpio_set_value(SABRESD_AUX_5V_EN, 1);
+}
+static const struct pm_platform_data mx6q_sabresd_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = sabresd_suspend_enter,
+ .suspend_exit = sabresd_suspend_exit,
+};
+
+static struct regulator_consumer_supply sabresd_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data sabresd_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vmmc_consumers),
+ .consumer_supplies = sabresd_vmmc_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sabresd_vmmc_init,
+};
+
+static struct platform_device sabresd_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &sabresd_vmmc_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ if (board_is_mx6_reva()) {
+ mxc_register_device(&mx6_sabresd_audio_wm8958_device,
+ &wm8958_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ mxc_wm8958_init();
+ } else {
+ platform_device_register(&sabresd_vwm8962_reg_devices);
+ mxc_register_device(&mx6_sabresd_audio_wm8962_device,
+ &wm8962_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ mxc_wm8962_init();
+ }
+
+ return 0;
+}
+
+#ifndef CONFIG_IMX_PCIE
+static void pcie_3v3_power(void)
+{
+ /* disable PCIE_3V3 first */
+ gpio_request(SABRESD_PCIE_PWR_EN, "pcie_3v3_en");
+ gpio_direction_output(SABRESD_PCIE_PWR_EN, 0);
+ mdelay(10);
+ /* enable PCIE_3V3 again */
+ gpio_set_value(SABRESD_PCIE_PWR_EN, 1);
+ gpio_free(SABRESD_PCIE_PWR_EN);
+}
+
+static void pcie_3v3_reset(void)
+{
+ /* reset miniPCIe */
+ gpio_request(SABRESD_PCIE_RST_B_REVB, "pcie_reset_rebB");
+ gpio_direction_output(SABRESD_PCIE_RST_B_REVB, 0);
+ /* The PCI Express Mini CEM specification states that PREST# is
+ deasserted minimum 1ms after 3.3vVaux has been applied and stable*/
+ mdelay(1);
+ gpio_set_value(SABRESD_PCIE_RST_B_REVB, 1);
+ gpio_free(SABRESD_PCIE_RST_B_REVB);
+}
+#endif
+
+static void gps_power_on(bool on)
+{
+ /* Enable/disable aux_3v15 */
+ gpio_request(SABRESD_AUX_3V15_EN, "aux_3v15_en");
+ gpio_direction_output(SABRESD_AUX_3V15_EN, 1);
+ gpio_set_value(SABRESD_AUX_3V15_EN, on);
+ gpio_free(SABRESD_AUX_3V15_EN);
+ /*Enable/disable gps_en*/
+ gpio_request(SABRESD_GPS_EN, "gps_en");
+ gpio_direction_output(SABRESD_GPS_EN, 1);
+ gpio_set_value(SABRESD_GPS_EN, on);
+ gpio_free(SABRESD_GPS_EN);
+
+}
+
+#if defined(CONFIG_LEDS_TRIGGER) || defined(CONFIG_LEDS_GPIO)
+
+#define GPIO_LED(gpio_led, name_led, act_low, state_suspend, trigger) \
+{ \
+ .gpio = gpio_led, \
+ .name = name_led, \
+ .active_low = act_low, \
+ .retain_state_suspended = state_suspend, \
+ .default_state = 0, \
+ .default_trigger = "max8903-"trigger, \
+}
+
+/* use to show a external power source is connected
+ * GPIO_LED(SABRESD_CHARGE_DONE, "chg_detect", 0, 1, "ac-online"),
+ */
+static struct gpio_led imx6q_gpio_leds[] = {
+ GPIO_LED(SABRESD_CHARGE_NOW, "chg_now_led", 0, 1,
+ "charger-charging"),
+/* For the latest B4 board, this GPIO_1 is connected to POR_B,
+which will reset the whole board if this pin's level is changed,
+so, for the latest board, we have to avoid using this pin as
+GPIO.
+ GPIO_LED(SABRESD_CHARGE_DONE, "chg_done_led", 0, 1,
+ "charger-full"),
+*/
+};
+
+static struct gpio_led_platform_data imx6q_gpio_leds_data = {
+ .leds = imx6q_gpio_leds,
+ .num_leds = ARRAY_SIZE(imx6q_gpio_leds),
+};
+
+static struct platform_device imx6q_gpio_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &imx6q_gpio_leds_data,
+ }
+};
+
+static void __init imx6q_add_device_gpio_leds(void)
+{
+ platform_device_register(&imx6q_gpio_led_device);
+}
+#else
+static void __init imx6q_add_device_gpio_leds(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+ .debounce_interval = debounce, \
+}
+
+static struct gpio_keys_button imx6q_buttons[] = {
+ GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1),
+ GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_POWER, 1, "volume-down", 1, 1),
+};
+
+static struct gpio_keys_platform_data imx6q_button_data = {
+ .buttons = imx6q_buttons,
+ .nbuttons = ARRAY_SIZE(imx6q_buttons),
+};
+
+static struct platform_device imx6q_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &imx6q_button_data,
+ }
+};
+
+static void __init imx6q_add_device_buttons(void)
+{
+ platform_device_register(&imx6q_button_device);
+}
+#else
+static void __init imx6q_add_device_buttons(void) {}
+#endif
+
+static struct platform_pwm_backlight_data mx6_sabresd_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 248,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct mxc_dvfs_platform_data sabresd_dvfscore_data = {
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+#else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+#endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ char *str;
+ struct tag *t;
+ int i = 0;
+ struct ipuv3_fb_platform_data *pdata_fb = sabresd_fb_data;
+
+ for_each_tag(t, tags) {
+ if (t->hdr.tag == ATAG_CMDLINE) {
+ str = t->u.cmdline.cmdline;
+ str = strstr(str, "fbmem=");
+ if (str != NULL) {
+ str += 6;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ while (*str == ',' &&
+ i < ARRAY_SIZE(sabresd_fb_data)) {
+ str++;
+ pdata_fb[i++].res_size[0] = memparse(str, &str);
+ }
+ }
+ break;
+ }
+ }
+}
+
+static struct mipi_csi2_platform_data mipi_csi2_pdata = {
+ .ipu_id = 0,
+ .csi_id = 1,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+ u32 value;
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /*set TOP and DP_EN bit*/
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+static const struct imx_pcie_platform_data mx6_sabresd_pcie_data __initconst = {
+ .pcie_pwr_en = SABRESD_PCIE_PWR_EN,
+ .pcie_rst = SABRESD_PCIE_RST_B_REVB,
+ .pcie_wake_up = SABRESD_PCIE_WAKE_B,
+ .pcie_dis = SABRESD_PCIE_DIS_B,
+#ifdef CONFIG_IMX_PCIE_EP_MODE_IN_EP_RC_SYS
+ .type_ep = 1,
+#else
+ .type_ep = 0,
+#endif
+};
+
+static int __init early_enable_lcd_ldb(char *p)
+{
+ enable_lcd_ldb = 1;
+ return 0;
+}
+early_param("enable_lcd_ldb", early_enable_lcd_ldb);
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_sabresd_board_init(void)
+{
+ int i;
+ int ret;
+ struct clk *clko, *clko2;
+ struct clk *new_parent;
+ int rate;
+ struct platform_device *voutdev;
+
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabresd_pads,
+ ARRAY_SIZE(mx6q_sabresd_pads));
+ else if (cpu_is_mx6dl()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_sabresd_pads,
+ ARRAY_SIZE(mx6dl_sabresd_pads));
+ }
+
+#ifdef CONFIG_FEC_1588
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
+ gp_reg_id = sabresd_dvfscore_data.reg_id;
+ soc_reg_id = sabresd_dvfscore_data.soc_id;
+ pu_reg_id = sabresd_dvfscore_data.pu_id;
+ mx6q_sabresd_init_uart();
+
+ /*
+ * MX6DL/Solo only supports single IPU
+ * The following codes are used to change ipu id
+ * and display id information for MX6DL/Solo. Then
+ * register 1 IPU device and up to 2 displays for
+ * MX6DL/Solo
+ */
+ if (cpu_is_mx6dl()) {
+ ldb_data.ipu_id = 0;
+ ldb_data.disp_id = 1;
+ hdmi_core_data.disp_id = 0;
+ mipi_dsi_pdata.ipu_id = 0;
+ mipi_dsi_pdata.disp_id = 1;
+ }
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ if (cpu_is_mx6q()) {
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+ for (i = 0; i < 4 && i < ARRAY_SIZE(sabresd_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);
+ } else
+ for (i = 0; i < 2 && i < ARRAY_SIZE(sabresd_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabresd_fb_data[i]);
+
+ imx6q_add_vdoa();
+ imx6q_add_mipi_dsi(&mipi_dsi_pdata);
+ imx6q_add_lcdif(&lcdif_data);
+ imx6q_add_ldb(&ldb_data);
+ voutdev = imx6q_add_v4l2_output(0);
+ if (vout_mem.res_msize && voutdev) {
+ dma_declare_coherent_memory(&voutdev->dev,
+ vout_mem.res_mbase,
+ vout_mem.res_mbase,
+ vout_mem.res_msize,
+ (DMA_MEMORY_MAP |
+ DMA_MEMORY_EXCLUSIVE));
+ }
+
+ imx6q_add_v4l2_capture(0, &capture_data[0]);
+ imx6q_add_v4l2_capture(1, &capture_data[1]);
+ imx6q_add_mipi_csi2(&mipi_csi2_pdata);
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_caam();
+
+ if (board_is_mx6_reva()) {
+ strcpy(mxc_i2c0_board_info[0].type, "wm8958");
+ mxc_i2c0_board_info[0].platform_data = &wm8958_config_data;
+ } else {
+ strcpy(mxc_i2c0_board_info[0].type, "wm8962");
+ mxc_i2c0_board_info[0].platform_data = &wm8962_config_data;
+ }
+ imx6q_add_device_gpio_leds();
+
+ imx6q_add_imx_i2c(0, &mx6q_sabresd_i2c_data);
+ imx6q_add_imx_i2c(1, &mx6q_sabresd_i2c_data);
+ imx6q_add_imx_i2c(2, &mx6q_sabresd_i2c_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+ ret = gpio_request(SABRESD_PFUZE_INT, "pFUZE-int");
+ if (ret) {
+ printk(KERN_ERR"request pFUZE-int error!!\n");
+ return;
+ } else {
+ gpio_direction_input(SABRESD_PFUZE_INT);
+ mx6q_sabresd_init_pfuze100(SABRESD_PFUZE_INT);
+ }
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6q_sabresd_spi_data);
+ spi_device_init();
+
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6q_sabresd_anatop_thermal_data);
+ imx6_init_fec(fec_data);
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ /* Make sure the IOMUX_OBSRV_MUX1 is set to ENET_IRQ. */
+ mxc_iomux_set_specialbits_register(IOMUX_OBSRV_MUX1_OFFSET,
+ OBSRV_MUX1_ENET_IRQ, OBSRV_MUX1_MASK);
+#endif
+
+ imx6q_add_pm_imx(0, &mx6q_sabresd_pm_data);
+
+ /* Move sd4 to first because sd4 connect to emmc.
+ Mfgtools want emmc is mmcblk0 and other sd card is mmcblk1.
+ */
+ imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabresd_sd4_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabresd_sd3_data);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6q_sabresd_sd2_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6q_sabresd_init_usb();
+ /* SATA is not supported by MX6DL/Solo */
+ if (cpu_is_mx6q())
+ imx6q_add_ahci(0, &mx6q_sabresd_sata_data);
+ imx6q_add_vpu();
+ imx6q_init_audio();
+ platform_device_register(&sabresd_vmmc_reg_devices);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
+ /*
+ * Disable HannStar touch panel CABC function,
+ * this function turns the panel's backlight automatically
+ * according to the content shown on the panel which
+ * may cause annoying unstable backlight issue.
+ */
+ gpio_request(SABRESD_CABC_EN0, "cabc-en0");
+ gpio_direction_output(SABRESD_CABC_EN0, 0);
+ gpio_request(SABRESD_CABC_EN1, "cabc-en1");
+ gpio_direction_output(SABRESD_CABC_EN1, 0);
+
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm(1);
+ imx6q_add_mxc_pwm(2);
+ imx6q_add_mxc_pwm(3);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_sabresd_pwm_backlight_data);
+
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+
+ imx6q_add_dvfs_core(&sabresd_dvfscore_data);
+#ifndef CONFIG_MX6_INTER_LDO_BYPASS
+ mx6_cpu_regulator_init();
+#endif
+ imx6q_add_device_buttons();
+
+ /* enable sensor 3v3 and 1v8 */
+ gpio_request(SABRESD_SENSOR_EN, "sensor-en");
+ gpio_direction_output(SABRESD_SENSOR_EN, 1);
+
+ /* enable ecompass intr */
+ gpio_request(SABRESD_eCOMPASS_INT, "ecompass-int");
+ gpio_direction_input(SABRESD_eCOMPASS_INT);
+ /* enable light sensor intr */
+ gpio_request(SABRESD_ALS_INT, "als-int");
+ gpio_direction_input(SABRESD_ALS_INT);
+
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+
+ if (cpu_is_mx6dl()) {
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+ if (epdc_enabled) {
+ mxc_register_device(&max17135_sensor_device, NULL);
+ imx6dl_add_imx_epdc(&epdc_data);
+ }
+ }
+ /*
+ ret = gpio_request_array(mx6q_sabresd_flexcan_gpios,
+ ARRAY_SIZE(mx6q_sabresd_flexcan_gpios));
+ if (ret)
+ pr_err("failed to request flexcan1-gpios: %d\n", ret);
+ else
+ imx6q_add_flexcan0(&mx6q_sabresd_flexcan0_pdata);
+ */
+
+ clko2 = clk_get(NULL, "clko2_clk");
+ if (IS_ERR(clko2))
+ pr_err("can't get CLKO2 clock.\n");
+
+ new_parent = clk_get(NULL, "osc_clk");
+ if (!IS_ERR(new_parent)) {
+ clk_set_parent(clko2, new_parent);
+ clk_put(new_parent);
+ }
+ rate = clk_round_rate(clko2, 24000000);
+ clk_set_rate(clko2, rate);
+ clk_enable(clko2);
+
+ /* Camera and audio use osc clock */
+ clko = clk_get(NULL, "clko_clk");
+ if (!IS_ERR(clko))
+ clk_set_parent(clko, clko2);
+
+ /* Enable Aux_5V */
+ gpio_request(SABRESD_AUX_5V_EN, "aux_5v_en");
+ gpio_direction_output(SABRESD_AUX_5V_EN, 1);
+ gpio_set_value(SABRESD_AUX_5V_EN, 1);
+
+#ifndef CONFIG_IMX_PCIE
+ /* enable pcie 3v3 power without pcie driver */
+ pcie_3v3_power();
+ mdelay(10);
+ pcie_3v3_reset();
+#endif
+
+ gps_power_on(true);
+ /* Register charger chips */
+ platform_device_register(&sabresd_max8903_charger_1);
+ pm_power_off = mx6_snvs_poweroff;
+ imx6q_add_busfreq();
+
+ /* Add PCIe RC interface support */
+ imx6q_add_pcie(&mx6_sabresd_pcie_data);
+ if (cpu_is_mx6dl()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_elan_pads,
+ ARRAY_SIZE(mx6dl_arm2_elan_pads));
+
+ /* ELAN Touchscreen */
+ gpio_request(SABRESD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(SABRESD_ELAN_INT);
+
+ gpio_request(SABRESD_ELAN_CE, "elan-cs");
+ gpio_direction_output(SABRESD_ELAN_CE, 1);
+ gpio_direction_output(SABRESD_ELAN_CE, 0);
+
+ gpio_request(SABRESD_ELAN_RST, "elan-rst");
+ gpio_direction_output(SABRESD_ELAN_RST, 1);
+ gpio_direction_output(SABRESD_ELAN_RST, 0);
+ mdelay(1);
+ gpio_direction_output(SABRESD_ELAN_RST, 1);
+ gpio_direction_output(SABRESD_ELAN_CE, 1);
+ }
+
+ imx6_add_armpmu();
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_sabresd_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mx6_sabresd_timer = {
+ .init = mx6_sabresd_timer_init,
+};
+
+static void __init mx6q_sabresd_reserve(void)
+{
+ phys_addr_t phys;
+ int i;
+
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+
+#if defined(CONFIG_ION)
+ if (imx_ion_data.heaps[0].size) {
+ phys = memblock_alloc(imx_ion_data.heaps[0].size, SZ_4K);
+ memblock_remove(phys, imx_ion_data.heaps[0].size);
+ imx_ion_data.heaps[0].base = phys;
+ }
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(sabresd_fb_data); i++)
+ if (sabresd_fb_data[i].res_size[0]) {
+ /* reserve for background buffer */
+ phys = memblock_alloc(sabresd_fb_data[i].res_size[0],
+ SZ_4K);
+ memblock_remove(phys, sabresd_fb_data[i].res_size[0]);
+ sabresd_fb_data[i].res_base[0] = phys;
+ }
+ if (vout_mem.res_msize) {
+ phys = memblock_alloc_base(vout_mem.res_msize,
+ SZ_4K, SZ_1G);
+ memblock_remove(phys, vout_mem.res_msize);
+ vout_mem.res_mbase = phys;
+ }
+}
+
+/*
+ * initialize __mach_desc_MX6Q_SABRESD data structure.
+ */
+MACHINE_START(MX6Q_SABRESD, "Freescale i.MX 6Quad/DualLite/Solo Sabre-SD Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_sabresd_board_init,
+ .timer = &mx6_sabresd_timer,
+ .reserve = mx6q_sabresd_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.h b/arch/arm/mach-mx6/board-mx6q_sabresd.h
new file mode 100644
index 00000000..b2bb8c92
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _BOARD_MX6Q_SABRESD_H
+#define _BOARD_MX6Q_SABRESD_H
+#include <mach/iomux-mx6q.h>
+
+static iomux_v3_cfg_t mx6q_sabresd_pads[] = {
+ /* AUDMUX */
+ MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+
+ /* CAN1 */
+ MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE,
+ /* MX6Q_PAD_KEY_COL2__CAN1_TXCAN, */
+ MX6Q_PAD_GPIO_1__WDOG2_WDOG_B, /*WDOG_B to reset pmic*/
+ MX6Q_PAD_GPIO_2__GPIO_1_2, /* user defined red led */
+ MX6Q_PAD_GPIO_7__GPIO_1_7, /* NERR */
+
+ /* CCM */
+ MX6Q_PAD_GPIO_0__CCM_CLKO, /* SGTL500 sys_mclk */
+ MX6Q_PAD_GPIO_3__CCM_CLKO2, /* J5 - Camera MCLK */
+
+ /* ECSPI1 */
+ MX6Q_PAD_KEY_COL0__ECSPI1_SCLK,
+ MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI,
+ MX6Q_PAD_KEY_COL1__ECSPI1_MISO,
+ MX6Q_PAD_KEY_ROW1__GPIO_4_9,
+ /* ENET */
+ MX6Q_PAD_ENET_MDIO__ENET_MDIO,
+ MX6Q_PAD_ENET_MDC__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ MX6Q_PAD_ENET_TX_EN__GPIO_1_28, /* Micrel RGMII Phy Interrupt */
+ MX6Q_PAD_EIM_D23__GPIO_3_23, /* RGMII reset */
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT, /* Internal connect for 1588 TS Clock */
+
+ /* GPIO1 */
+ MX6Q_PAD_ENET_RX_ER__GPIO_1_24, /* J9 - Microphone Detect */
+
+ /* GPIO2 */
+ /* MX6Q_PAD_NANDF_D1__GPIO_2_1,*/ /* J14 - Menu Button */
+ /* MX6Q_PAD_NANDF_D2__GPIO_2_2,*/ /* J14 - Back Button */
+ /* MX6Q_PAD_NANDF_D3__GPIO_2_3,*/ /* J14 - Search Button */
+ /* MX6Q_PAD_NANDF_D4__GPIO_2_4,*/ /* J14 - Home Button */
+ MX6Q_PAD_EIM_A22__GPIO_2_16, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A21__GPIO_2_17, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A20__GPIO_2_18, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A19__GPIO_2_19, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A18__GPIO_2_20, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A17__GPIO_2_21, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A16__GPIO_2_22, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_RW__GPIO_2_26, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_LBA__GPIO_2_27, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB0__GPIO_2_28, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB1__GPIO_2_29, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_EB3__GPIO_2_31, /* J12 - Boot Mode Select */
+
+ /* GPIO3 */
+ MX6Q_PAD_EIM_DA0__GPIO_3_0, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA1__GPIO_3_1, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA2__GPIO_3_2, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA3__GPIO_3_3, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA4__GPIO_3_4, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA5__GPIO_3_5, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA6__GPIO_3_6, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA7__GPIO_3_7, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA8__GPIO_3_8, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA9__GPIO_3_9, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA10__GPIO_3_10, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA11__GPIO_3_11, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA12__GPIO_3_12, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA13__GPIO_3_13, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA14__GPIO_3_14, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_DA15__GPIO_3_15, /* J12 - Boot Mode Select */
+
+ /* SW4 , SW5 & SW1 */
+ MX6Q_PAD_GPIO_4__GPIO_1_4, /* Volume Up */
+ MX6Q_PAD_GPIO_5__GPIO_1_5, /* Volume Down */
+ MX6Q_PAD_EIM_D29__GPIO_3_29, /* power off */
+
+ /* CAP_TCH_INT1 */
+ MX6Q_PAD_NANDF_CLE__GPIO_6_7,
+
+ /* CAP_TCH_INT0 */
+ MX6Q_PAD_NANDF_ALE__GPIO_6_8,
+
+ /* eCompass int */
+ MX6Q_PAD_EIM_D16__GPIO_3_16,
+
+ /* GPIO5 */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0, /* J12 - Boot Mode Select */
+ MX6Q_PAD_EIM_A24__GPIO_5_4, /* J12 - Boot Mode Select */
+
+ /* GPIO6 */
+ MX6Q_PAD_EIM_A23__GPIO_6_6, /* J12 - Boot Mode Select */
+ MX6Q_PAD_NANDF_RB0__GPIO_6_10, /* AUX_5V Enable */
+
+ /* I2C1, WM8958 */
+ MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2, Camera, MIPI */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL,
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* I2C3 */
+ MX6Q_PAD_GPIO_3__I2C3_SCL, /* GPIO1[3] */
+ MX6Q_PAD_GPIO_6__I2C3_SDA,
+#endif
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2, /* HSync */
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3, /* VSync */
+ MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4, /* Contrast */
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+ MX6Q_PAD_GPIO_7__GPIO_1_7, /* J7 - Display Connector GP */
+ MX6Q_PAD_GPIO_9__GPIO_1_9, /* J7 - Display Connector GP */
+ /* MX6Q_PAD_NANDF_D0__GPIO_2_0,*/ /* J6 - LVDS Display contrast */
+
+ /* DISP_PWM */
+ MX6Q_PAD_SD1_DAT3__PWM1_PWMO, /* GPIO1[21] */
+
+ /* UART1 for debug */
+ MX6Q_PAD_CSI0_DAT10__UART1_TXD,
+ MX6Q_PAD_CSI0_DAT11__UART1_RXD,
+
+ /* UART3 for gps */
+ MX6Q_PAD_EIM_D24__UART3_TXD,
+ MX6Q_PAD_EIM_D25__UART3_RXD,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID,
+
+ /* USB power pin */
+ MX6Q_PAD_EIM_D22__GPIO_3_22,
+ MX6Q_PAD_ENET_TXD1__GPIO_1_29,
+
+ /* USB OC pin */
+ MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC,
+ MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC,
+
+ /* USDHC2 */
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ MX6Q_PAD_NANDF_D4__USDHC2_DAT4,
+ MX6Q_PAD_NANDF_D5__USDHC2_DAT5,
+ MX6Q_PAD_NANDF_D6__USDHC2_DAT6,
+ MX6Q_PAD_NANDF_D7__USDHC2_DAT7,
+ MX6Q_PAD_NANDF_D2__GPIO_2_2, /* SD2_CD */
+ MX6Q_PAD_NANDF_D3__GPIO_2_3, /* SD2_WP */
+
+ /* USDHC3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6Q_PAD_NANDF_D0__GPIO_2_0, /* SD3_CD */
+ MX6Q_PAD_NANDF_D1__GPIO_2_1, /* SD3_WP */
+
+ /* USDHC4 */
+ MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+
+ /* Charge */
+ MX6Q_PAD_EIM_A25__GPIO_5_2, /* FLT_1_B */
+ MX6Q_PAD_EIM_D23__GPIO_3_23, /* CHG_1_B */
+ MX6Q_PAD_EIM_DA13__GPIO_3_13, /* CHG_2_B */
+ MX6Q_PAD_EIM_DA14__GPIO_3_14, /* FLT_2_B */
+
+ MX6Q_PAD_ENET_RXD0__GPIO_1_27, /* UOK_B */
+ MX6Q_PAD_EIM_CS1__GPIO_2_24, /* DOK_B */
+
+ /* Audio Codec */
+ MX6Q_PAD_KEY_COL2__GPIO_4_10, /* CODEC_PWR_EN */
+ MX6Q_PAD_SD3_RST__GPIO_7_8, /* HEADPHONE_DET */
+ MX6Q_PAD_GPIO_9__GPIO_1_9, /* MICROPHONE_DET */
+
+ /*GPS AUX_3V15_EN*/
+ MX6Q_PAD_NANDF_WP_B__GPIO_6_9,
+
+ /* PCIE */
+ MX6Q_PAD_EIM_D19__GPIO_3_19, /* PCIE_PWR_EN */
+
+ MX6Q_PAD_GPIO_17__GPIO_7_12, /* PCIE_RST */
+ MX6Q_PAD_KEY_COL4__GPIO_4_14, /* PCIE_DIS */
+
+ /* DISP_RST_B */
+ MX6Q_PAD_NANDF_CS0__GPIO_6_11,
+ /* DISP_PWR_EN */
+ MX6Q_PAD_NANDF_CS1__GPIO_6_14,
+ /* CABC_EN0 */
+ MX6Q_PAD_NANDF_CS2__GPIO_6_15,
+ /* CABC_EN1 */
+ MX6Q_PAD_NANDF_CS3__GPIO_6_16,
+};
+
+static iomux_v3_cfg_t mx6q_sabresd_csi0_sensor_pads[] = {
+ /* IPU1 Camera */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+
+ MX6Q_PAD_GPIO_0__CCM_CLKO, /* camera clk */
+
+ MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* camera PWDN */
+ MX6Q_PAD_SD1_DAT1__GPIO_1_17, /* camera RESET */
+};
+
+static iomux_v3_cfg_t mx6q_sabresd_mipi_sensor_pads[] = {
+ MX6Q_PAD_GPIO_0__CCM_CLKO, /* camera clk */
+
+ MX6Q_PAD_SD1_DAT2__GPIO_1_19, /* camera PWDN */
+ MX6Q_PAD_SD1_CLK__GPIO_1_20, /* camera RESET */
+};
+
+static iomux_v3_cfg_t mx6q_sabresd_hdmi_ddc_pads[] = {
+ MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6q_sabresd_i2c2_pads[] = {
+ MX6Q_PAD_KEY_COL3__I2C2_SCL, /* I2C2 SCL */
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c
new file mode 100755
index 00000000..fbc5d4dd
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c
@@ -0,0 +1,1313 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <sound/wm8962.h>
+#include <sound/pcm.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6sl.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6sl_common.h"
+
+static int spdc_sel;
+static int max17135_regulator_init(struct max17135 *max17135);
+static struct clk *extern_audio_root;
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int __init mx6sl_arm2_init_pfuze100(u32 int_gpio);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 0:
+ sd_pads_200mhz = mx6sl_sd1_200mhz;
+ sd_pads_100mhz = mx6sl_sd1_100mhz;
+ sd_pads_50mhz = mx6sl_sd1_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz);
+ break;
+ case 1:
+ sd_pads_200mhz = mx6sl_sd2_200mhz;
+ sd_pads_100mhz = mx6sl_sd2_100mhz;
+ sd_pads_50mhz = mx6sl_sd2_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz);
+ break;
+ case 2:
+ sd_pads_200mhz = mx6sl_sd3_200mhz;
+ sd_pads_100mhz = mx6sl_sd3_100mhz;
+ sd_pads_50mhz = mx6sl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz);
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6_arm2_sd1_data __initconst = {
+ .cd_gpio = MX6_BRD_SD1_CD,
+ .wp_gpio = MX6_BRD_SD1_WP,
+ .support_8bit = 1,
+ .support_18v = 1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_arm2_sd2_data __initconst = {
+ .cd_gpio = MX6_BRD_SD2_CD,
+ .wp_gpio = MX6_BRD_SD2_WP,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
+ .cd_gpio = MX6_BRD_SD3_CD,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply arm2_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+};
+
+static struct regulator_init_data arm2_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(arm2_vmmc_consumers),
+ .consumer_supplies = arm2_vmmc_consumers,
+};
+
+static struct fixed_voltage_config arm2_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &arm2_vmmc_init,
+};
+
+static struct platform_device arm2_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &arm2_vmmc_reg_config,
+ },
+};
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static const struct anatop_thermal_platform_data
+ mx6sl_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+ };
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * TODO: We cannot enable full constraints for now, since
+ * it results in the PFUZE regulators being disabled
+ * at the end of boot, which disables critical regulators.
+ */
+ /*regulator_has_full_constraints();*/
+
+ return 0;
+}
+
+static int mx6_arm2_spi_cs[] = {
+ MX6_BRD_ECSPI1_CS0,
+};
+
+static const struct spi_imx_master mx6_arm2_spi_data __initconst = {
+ .chipselect = mx6_arm2_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_arm2_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+};
+#endif
+
+static void spi_device_init(void)
+{
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+#endif
+}
+
+static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data wm8962_data;
+
+static struct platform_device mx6_sabresd_audio_wm8962_device = {
+ .name = "imx-wm8962",
+};
+
+static struct wm8962_pdata wm8962_config_data = {
+
+};
+
+static int wm8962_clk_enable(int enable)
+{
+ if (enable)
+ clk_enable(extern_audio_root);
+ else
+ clk_disable(extern_audio_root);
+
+ return 0;
+}
+
+static int mxc_wm8962_init(void)
+{
+ struct clk *pll4;
+ int rate;
+
+ extern_audio_root = clk_get(NULL, "extern_audio_clk");
+ if (IS_ERR(extern_audio_root)) {
+ pr_err("can't get extern_audio_root clock.\n");
+ return PTR_ERR(extern_audio_root);
+ }
+
+ pll4 = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4)) {
+ pr_err("can't get pll4 clock.\n");
+ return PTR_ERR(pll4);
+ }
+
+ clk_set_parent(extern_audio_root, pll4);
+
+ rate = 24000000;
+ clk_set_rate(extern_audio_root, 24000000);
+
+ wm8962_data.sysclk = rate;
+
+ return 0;
+}
+
+static struct mxc_audio_platform_data wm8962_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = MX6_BRD_HEADPHONE_DET,
+ .hp_active_low = 1,
+ .mic_gpio = -1,
+ .mic_active_low = 1,
+ .init = mxc_wm8962_init,
+ .clock_enable = wm8962_clk_enable,
+};
+
+static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_init_data sabresd_vwm8962_init = {
+ .constraints = {
+ .name = "SPKVDD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers),
+ .consumer_supplies = sabresd_vwm8962_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vwm8962_reg_config = {
+ .supply_name = "SPKVDD",
+ .microvolts = 4325000,
+ .gpio = -1,
+ .enabled_at_boot = 1,
+ .init_data = &sabresd_vwm8962_init,
+};
+
+static struct platform_device sabresd_vwm8962_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &sabresd_vwm8962_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ platform_device_register(&sabresd_vwm8962_reg_devices);
+ mxc_register_device(&mx6_sabresd_audio_wm8962_device,
+ &wm8962_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ return 0;
+}
+
+static struct imxi2c_platform_data mx6_arm2_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_arm2_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_arm2_i2c2_data = {
+ .bitrate = 400000,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0x48),
+ .platform_data = &max17135_pdata,
+ }, {
+ I2C_BOARD_INFO("elan-touch", 0x10),
+ .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT),
+ }, {
+ I2C_BOARD_INFO("mma8450", 0x1c),
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8962", 0x1a),
+ .platform_data = &wm8962_config_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ },
+};
+
+static struct mxc_dvfs_platform_data mx6sl_arm2_dvfscore_data = {
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+#else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+#endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_32M,
+};
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+
+static inline void mx6_arm2_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */
+}
+
+static int mx6sl_arm2_fec_phy_init(struct phy_device *phydev)
+{
+ int val;
+
+ /* power on FEC phy and reset phy */
+ gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr");
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0);
+ /* wait RC ms for hw reset */
+ msleep(1);
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1);
+
+ /* check phy power */
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN) {
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+ }
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6sl_arm2_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_GDRL);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_BDR0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDRL);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_BDR0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static int spdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for SPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE");
+
+ return ret;
+}
+
+static void spdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable SPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_disable_pins(void)
+{
+ /* Configure MUX settings for SPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+}
+
+static struct imx_spdc_panel_init_set spdc_init_set = {
+ .yoe_pol = false,
+ .dual_gate = false,
+ .resolution = 0,
+ .ud = false,
+ .rl = false,
+ .data_filter_n = true,
+ .power_ready = true,
+ .rgbw_mode_enable = false,
+ .hburst_len_en = true,
+};
+
+static struct fb_videomode erk_1_4_a01 = {
+ .name = "ERK_1_4_A01",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 40000000,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct imx_spdc_fb_mode spdc_panel_modes[] = {
+ {
+ &erk_1_4_a01,
+ &spdc_init_set,
+ .wave_timing = "pvi"
+ },
+};
+
+static struct imx_spdc_fb_platform_data spdc_data = {
+ .spdc_mode = spdc_panel_modes,
+ .num_modes = ARRAY_SIZE(spdc_panel_modes),
+ .get_pins = spdc_get_pins,
+ .put_pins = spdc_put_pins,
+ .enable_pins = spdc_enable_pins,
+ .disable_pins = spdc_disable_pins,
+};
+
+static int __init early_use_spdc_sel(char *p)
+{
+ spdc_sel = 1;
+ return 0;
+}
+early_param("spdc", early_use_spdc_sel);
+
+static void setup_spdc(void)
+{
+ /* GPR0[8]: 0:EPDC, 1:SPDC */
+ if (spdc_sel)
+ mxc_iomux_set_gpr_register(0, 8, 1, 1);
+}
+
+static void imx6_arm2_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 1);
+ else
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 0);
+}
+
+static void __init mx6_arm2_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0);
+
+ ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1);
+
+ mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_DAT,
+ PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_STROBE,
+ PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK);
+
+ mx6_usb_h2_init();
+#endif
+}
+
+static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+static struct fb_videomode video_modes[] = {
+ {
+ /* 800x480 @ 57 Hz , pixel clk @ 32MHz */
+ "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "SEIKO-WVGA",
+ .mode = video_modes,
+ .num_modes = ARRAY_SIZE(video_modes),
+ },
+};
+
+static struct platform_device lcd_wvga_device = {
+ .name = "lcd_seiko",
+};
+
+static int mx6sl_arm2_keymap[] = {
+ KEY(0, 0, KEY_SELECT),
+ KEY(0, 1, KEY_BACK),
+ KEY(0, 2, KEY_F1),
+ KEY(0, 3, KEY_F2),
+
+ KEY(1, 0, KEY_F3),
+ KEY(1, 1, KEY_F4),
+ KEY(1, 2, KEY_POWER),
+ KEY(1, 3, KEY_MENU),
+
+ KEY(2, 0, KEY_PREVIOUS),
+ KEY(2, 1, KEY_NEXT),
+ KEY(2, 2, KEY_HOME),
+ KEY(2, 3, KEY_NEXT),
+
+ KEY(3, 0, KEY_UP),
+ KEY(3, 1, KEY_LEFT),
+ KEY(3, 2, KEY_RIGHT),
+ KEY(3, 3, KEY_DOWN),
+};
+
+static const struct matrix_keymap_data mx6sl_arm2_map_data __initconst = {
+ .keymap = mx6sl_arm2_keymap,
+ .keymap_size = ARRAY_SIZE(mx6sl_arm2_keymap),
+};
+static void __init elan_ts_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads,
+ ARRAY_SIZE(mx6sl_brd_elan_pads));
+
+ /* ELAN Touchscreen */
+ gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(MX6SL_BRD_ELAN_INT);
+
+ gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs");
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 0);
+
+ gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst");
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 0);
+ mdelay(1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+}
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+ u32 value;
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /* set TOP and DP_EN bit */
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_arm2_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
+ ARRAY_SIZE(mx6sl_brd_pads));
+
+ elan_ts_init();
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id;
+#else
+ gp_reg_id = mx6sl_arm2_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_arm2_dvfscore_data.soc_id;
+ pu_reg_id = mx6sl_arm2_dvfscore_data.pu_id;
+ mx6_cpu_regulator_init();
+#endif
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_i2c(0, &mx6_arm2_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_arm2_i2c1_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ imx6q_add_imx_i2c(2, &mx6_arm2_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6_arm2_spi_data);
+ spi_device_init();
+
+ mx6sl_arm2_init_pfuze100(0);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data);
+
+ mx6_arm2_init_uart();
+ /* get enet tx reference clk from FEC_REF_CLK pad.
+ * GPR1[14] = 0, GPR1[18:17] = 00
+ */
+ mxc_iomux_set_gpr_register(1, 14, 1, 0);
+ mxc_iomux_set_gpr_register(1, 17, 2, 0);
+
+ imx6_init_fec(fec_data);
+
+ platform_device_register(&arm2_vmmc_reg_devices);
+ imx6q_add_sdhci_usdhc_imx(0, &mx6_arm2_sd1_data);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6_arm2_sd2_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_arm2_sd3_data);
+
+ mx6_arm2_init_usb();
+ imx6q_add_otp();
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_arm2_pwm_backlight_data);
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF//[
+ imx6dl_add_imx_elcdif(&fb_data[0]);
+#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ mxc_register_device(&lcd_wvga_device, NULL);
+
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+ mxc_register_device(&max17135_sensor_device, NULL);
+ setup_spdc();
+ if (!spdc_sel)
+ imx6dl_add_imx_epdc(&epdc_data);
+ else
+ imx6sl_add_imx_spdc(&spdc_data);
+ imx6q_add_dvfs_core(&mx6sl_arm2_dvfscore_data);
+
+ imx6q_init_audio();
+
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6sl_add_imx_keypad(&mx6sl_arm2_map_data);
+ imx6q_add_busfreq();
+ imx6sl_add_dcp();
+ imx6sl_add_rngb();
+ imx6sl_add_imx_pxp_v4l2();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+
+ pm_power_off = mx6_snvs_poweroff;
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6sl_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6_arm2_reserve(void)
+{
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ phys_addr_t phys;
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+}
+
+MACHINE_START(MX6SL_ARM2, "Freescale i.MX 6SoloLite Armadillo2 Board")
+ .boot_params = MX6SL_PHYS_OFFSET + 0x100,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_arm2_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_arm2_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6sl_common.h b/arch/arm/mach-mx6/board-mx6sl_common.h
new file mode 100644
index 00000000..4eab0b35
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_common.h
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _BOARD_MX6SL_COMMON_H
+#define _BOARD_MX6SL_COMMON_H
+#include <mach/iomux-mx6sl.h>
+
+#define MX6_BRD_LCD_RESET IMX_GPIO_NR(2, 19) /* LCD_REST */
+
+#define MX6_BRD_USBOTG1_PWR IMX_GPIO_NR(4, 0) /* KEY_COL4 */
+#define MX6_BRD_USBOTG2_PWR IMX_GPIO_NR(4, 2) /* KEY_COL5 */
+#define MX6_BRD_LCD_PWR_EN IMX_GPIO_NR(4, 3) /* KEY_ROW5 */
+#define MX6_BRD_SD1_WP IMX_GPIO_NR(4, 6) /* KEY_COL7 */
+#define MX6_BRD_SD1_CD IMX_GPIO_NR(4, 7) /* KEY_ROW7 */
+#define MX6_BRD_ECSPI1_CS0 IMX_GPIO_NR(4, 11) /* ECSPI1_SS0 */
+#define MX6_BRD_HEADPHONE_DET IMX_GPIO_NR(4, 19) /* FEC_RX_ER */
+#define MX6_BRD_SD2_WP IMX_GPIO_NR(4, 29) /* SD2_DAT6 */
+#define MX6_BRD_SD2_CD IMX_GPIO_NR(5, 0) /* SD2_DAT7 */
+#define MX6_BRD_SD3_CD IMX_GPIO_NR(3, 22) /* REF_CLK_32K */
+#define MX6_BRD_FEC_PWR_EN IMX_GPIO_NR(4, 21) /* FEC_TX_CLK */
+#define MX6_BRD_CHG_FLT IMX_GPIO_NR(4, 14) /* ECSPI2_MISO */
+#define MX6_BRD_CHG_UOK IMX_GPIO_NR(4, 13) /* ECSPI2_MOSI */
+#define MX6_BRD_CHG_DOK IMX_GPIO_NR(4, 13) /* ECSPI2_MOSI */
+#define MX6_BRD_CHG_STATUS IMX_GPIO_NR(4, 15) /* ECSPI2_SS0 */
+
+/* EPDC GPIO pins */
+#define MX6SL_BRD_EPDC_SDDO_0 IMX_GPIO_NR(1, 7)
+#define MX6SL_BRD_EPDC_SDDO_1 IMX_GPIO_NR(1, 8)
+#define MX6SL_BRD_EPDC_SDDO_2 IMX_GPIO_NR(1, 9)
+#define MX6SL_BRD_EPDC_SDDO_3 IMX_GPIO_NR(1, 10)
+#define MX6SL_BRD_EPDC_SDDO_4 IMX_GPIO_NR(1, 11)
+#define MX6SL_BRD_EPDC_SDDO_5 IMX_GPIO_NR(1, 12)
+#define MX6SL_BRD_EPDC_SDDO_6 IMX_GPIO_NR(1, 13)
+#define MX6SL_BRD_EPDC_SDDO_7 IMX_GPIO_NR(1, 14)
+#define MX6SL_BRD_EPDC_SDDO_8 IMX_GPIO_NR(1, 15)
+#define MX6SL_BRD_EPDC_SDDO_9 IMX_GPIO_NR(1, 16)
+#define MX6SL_BRD_EPDC_SDDO_10 IMX_GPIO_NR(1, 17)
+#define MX6SL_BRD_EPDC_SDDO_11 IMX_GPIO_NR(1, 18)
+#define MX6SL_BRD_EPDC_SDDO_12 IMX_GPIO_NR(1, 19)
+#define MX6SL_BRD_EPDC_SDDO_13 IMX_GPIO_NR(1, 20)
+#define MX6SL_BRD_EPDC_SDDO_14 IMX_GPIO_NR(1, 21)
+#define MX6SL_BRD_EPDC_SDDO_15 IMX_GPIO_NR(1, 22)
+#define MX6SL_BRD_EPDC_GDCLK IMX_GPIO_NR(1, 31)
+#define MX6SL_BRD_EPDC_GDSP IMX_GPIO_NR(2, 2)
+#define MX6SL_BRD_EPDC_GDOE IMX_GPIO_NR(2, 0)
+#define MX6SL_BRD_EPDC_GDRL IMX_GPIO_NR(2, 1)
+#define MX6SL_BRD_EPDC_SDCLK IMX_GPIO_NR(1, 23)
+#define MX6SL_BRD_EPDC_SDOE IMX_GPIO_NR(1, 25)
+#define MX6SL_BRD_EPDC_SDLE IMX_GPIO_NR(1, 24)
+#define MX6SL_BRD_EPDC_SDSHR IMX_GPIO_NR(1, 26)
+#define MX6SL_BRD_EPDC_PWRCOM IMX_GPIO_NR(2, 11)
+#define MX6SL_BRD_EPDC_PWRSTAT IMX_GPIO_NR(2, 13)
+#define MX6SL_BRD_EPDC_PWRCTRL0 IMX_GPIO_NR(2, 7)
+#define MX6SL_BRD_EPDC_PWRCTRL1 IMX_GPIO_NR(2, 8)
+#define MX6SL_BRD_EPDC_PWRCTRL2 IMX_GPIO_NR(2, 9)
+#define MX6SL_BRD_EPDC_PWRCTRL3 IMX_GPIO_NR(2, 10)
+#define MX6SL_BRD_EPDC_BDR0 IMX_GPIO_NR(2, 5)
+#define MX6SL_BRD_EPDC_BDR1 IMX_GPIO_NR(2, 6)
+#define MX6SL_BRD_EPDC_SDCE0 IMX_GPIO_NR(1, 27)
+#define MX6SL_BRD_EPDC_SDCE1 IMX_GPIO_NR(1, 28)
+#define MX6SL_BRD_EPDC_SDCE2 IMX_GPIO_NR(1, 29)
+#define MX6SL_BRD_EPDC_SDCE3 IMX_GPIO_NR(1, 30)
+#define MX6SL_BRD_EPDC_PMIC_WAKE IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */
+#define MX6SL_BRD_EPDC_PMIC_INT IMX_GPIO_NR(2, 12) /* EPDC_PWRINT */
+#define MX6SL_BRD_EPDC_VCOM IMX_GPIO_NR(2, 3)
+/* ELAN TS */
+#define MX6SL_BRD_ELAN_CE IMX_GPIO_NR(2, 9)
+#define MX6SL_BRD_ELAN_INT IMX_GPIO_NR(2, 10)
+#define MX6SL_BRD_ELAN_RST IMX_GPIO_NR(4, 4)
+/* CSI */
+#define MX6SL_BRD_CSI_PWDN IMX_GPIO_NR(1, 25)
+#define MX6SL_BRD_CSI_RST IMX_GPIO_NR(1, 26)
+
+static iomux_v3_cfg_t mx6sl_brd_pads[] = {
+
+ /* AUDMUX */
+ MX6SL_PAD_AUD_TXC__AUDMUX_AUD3_TXC,
+ MX6SL_PAD_AUD_TXD__AUDMUX_AUD3_TXD,
+ MX6SL_PAD_AUD_TXFS__AUDMUX_AUD3_TXFS,
+ MX6SL_PAD_AUD_RXD__AUDMUX_AUD3_RXD,
+ MX6SL_PAD_AUD_MCLK__AUDMUX_AUDIO_CLK_OUT,
+
+ /* Audio Codec */
+ MX6SL_PAD_FEC_RX_ER__GPIO_4_19, /* HEADPHONE_DET */
+
+ /* SPDIF TX */
+ MX6SL_PAD_SD2_DAT4__SPDIF_OUT1,
+
+ /* UART1 */
+ MX6SL_PAD_UART1_RXD__UART1_RXD,
+ MX6SL_PAD_UART1_TXD__UART1_TXD,
+
+ /* USBOTG ID pin */
+#ifndef CONFIG_USB_ID_WAKEUP_ENABLE
+ MX6SL_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID,
+#endif
+
+ /* USBOTG POWER GPIO */
+ MX6SL_PAD_KEY_COL4__GPIO_4_0,
+ MX6SL_PAD_KEY_COL5__GPIO_4_2,
+ /* USB OC pin */
+ MX6SL_PAD_KEY_ROW4__USB_USBOTG1_OC,
+ MX6SL_PAD_ECSPI2_SCLK__USB_USBOTG2_OC,
+ /* USB HSIC pin */
+ MX6SL_PAD_HSIC_STROBE__USB_H_STROBE,
+ MX6SL_PAD_HSIC_DAT__USB_H_DATA,
+
+ /* SD1 */
+ MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ,
+ MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ,
+ MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ,
+ MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ,
+ MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ,
+ MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ,
+ MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ,
+ MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ,
+ MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ,
+ MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ,
+ /* SD1 CD & WP */
+ MX6SL_PAD_KEY_ROW7__GPIO_4_7,
+ MX6SL_PAD_KEY_COL7__GPIO_4_6,
+ /* SD2 */
+ MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ,
+ MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ,
+ MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ,
+ MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ,
+ MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ,
+ MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ,
+ /* SD2 CD & WP */
+ MX6SL_PAD_SD2_DAT7__GPIO_5_0,
+ //MX6SL_PAD_SD2_DAT6__GPIO_4_29,
+ /* SD3 */
+ MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ /* SD3 CD */
+ MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
+
+ /* FEC */
+ MX6SL_PAD_FEC_MDC__FEC_MDC,
+ MX6SL_PAD_FEC_MDIO__FEC_MDIO,
+ MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT, /* clock from anatop */
+ MX6SL_PAD_FEC_RX_ER__GPIO_4_19,
+ MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV,
+ MX6SL_PAD_FEC_RXD0__FEC_RDATA_0,
+ MX6SL_PAD_FEC_RXD1__FEC_RDATA_1,
+ MX6SL_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX6SL_PAD_FEC_TXD0__FEC_TDATA_0,
+ MX6SL_PAD_FEC_TXD1__FEC_TDATA_1,
+ MX6SL_PAD_FEC_TX_CLK__GPIO_4_21, /* Phy power enable */
+
+ /* I2C */
+ MX6SL_PAD_I2C1_SCL__I2C1_SCL,
+ MX6SL_PAD_I2C1_SDA__I2C1_SDA,
+ MX6SL_PAD_I2C2_SCL__I2C2_SCL,
+ MX6SL_PAD_I2C2_SDA__I2C2_SDA,
+
+ /* ECSPI1 */
+ MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO,
+ MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI,
+ MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK,
+ MX6SL_PAD_ECSPI1_SS0__ECSPI1_SS0,
+ MX6SL_PAD_ECSPI1_SS0__GPIO_4_11, /* SS0 */
+
+ /* LCD */
+#if 0//[
+
+ MX6SL_PAD_LCD_CLK__LCDIF_CLK,
+ MX6SL_PAD_LCD_ENABLE__LCDIF_ENABLE,
+ MX6SL_PAD_LCD_HSYNC__LCDIF_HSYNC,
+ MX6SL_PAD_LCD_VSYNC__LCDIF_VSYNC,
+ MX6SL_PAD_LCD_RESET__LCDIF_RESET,
+ MX6SL_PAD_LCD_DAT0__LCDIF_DAT_0,
+ MX6SL_PAD_LCD_DAT1__LCDIF_DAT_1,
+ MX6SL_PAD_LCD_DAT2__LCDIF_DAT_2,
+ MX6SL_PAD_LCD_DAT3__LCDIF_DAT_3,
+ MX6SL_PAD_LCD_DAT4__LCDIF_DAT_4,
+ MX6SL_PAD_LCD_DAT5__LCDIF_DAT_5,
+ MX6SL_PAD_LCD_DAT6__LCDIF_DAT_6,
+ MX6SL_PAD_LCD_DAT7__LCDIF_DAT_7,
+ MX6SL_PAD_LCD_DAT8__LCDIF_DAT_8,
+ MX6SL_PAD_LCD_DAT9__LCDIF_DAT_9,
+ MX6SL_PAD_LCD_DAT10__LCDIF_DAT_10,
+ MX6SL_PAD_LCD_DAT11__LCDIF_DAT_11,
+ MX6SL_PAD_LCD_DAT12__LCDIF_DAT_12,
+ MX6SL_PAD_LCD_DAT13__LCDIF_DAT_13,
+ MX6SL_PAD_LCD_DAT14__LCDIF_DAT_14,
+ MX6SL_PAD_LCD_DAT15__LCDIF_DAT_15,
+ MX6SL_PAD_LCD_DAT16__LCDIF_DAT_16,
+ MX6SL_PAD_LCD_DAT17__LCDIF_DAT_17,
+ MX6SL_PAD_LCD_DAT18__LCDIF_DAT_18,
+ MX6SL_PAD_LCD_DAT19__LCDIF_DAT_19,
+ MX6SL_PAD_LCD_DAT20__LCDIF_DAT_20,
+ MX6SL_PAD_LCD_DAT21__LCDIF_DAT_21,
+ MX6SL_PAD_LCD_DAT22__LCDIF_DAT_22,
+ MX6SL_PAD_LCD_DAT23__LCDIF_DAT_23,
+#else//][!
+
+ MX6SL_PAD_LCD_CLK__GPIO_2_15,
+ MX6SL_PAD_LCD_ENABLE__GPIO_2_16,
+ MX6SL_PAD_LCD_HSYNC__GPIO_2_17,
+ MX6SL_PAD_LCD_VSYNC__GPIO_2_18,
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+
+ MX6SL_PAD_LCD_DAT0__GPIO_2_20,
+ MX6SL_PAD_LCD_DAT1__GPIO_2_21,
+ MX6SL_PAD_LCD_DAT2__GPIO_2_22,
+ MX6SL_PAD_LCD_DAT3__GPIO_2_23,
+ MX6SL_PAD_LCD_DAT4__GPIO_2_24,
+ MX6SL_PAD_LCD_DAT5__GPIO_2_25,
+ MX6SL_PAD_LCD_DAT6__GPIO_2_26,
+ MX6SL_PAD_LCD_DAT8__GPIO_2_28,
+ MX6SL_PAD_LCD_DAT9__GPIO_2_29,
+ MX6SL_PAD_LCD_DAT10__GPIO_2_30,
+ MX6SL_PAD_LCD_DAT11__GPIO_2_31,
+ MX6SL_PAD_LCD_DAT12__GPIO_3_0,
+ MX6SL_PAD_LCD_DAT13__GPIO_3_1,
+ MX6SL_PAD_LCD_DAT14__GPIO_3_2,
+ MX6SL_PAD_LCD_DAT15__GPIO_3_3,
+ MX6SL_PAD_LCD_DAT16__GPIO_3_4,
+ MX6SL_PAD_LCD_DAT17__GPIO_3_5,
+ MX6SL_PAD_LCD_DAT18__GPIO_3_6,
+ MX6SL_PAD_LCD_DAT19__GPIO_3_7,
+ MX6SL_PAD_LCD_DAT20__GPIO_3_8,
+ MX6SL_PAD_LCD_DAT21__GPIO_3_9,
+ MX6SL_PAD_LCD_DAT22__GPIO_3_10,
+ MX6SL_PAD_LCD_DAT23__GPIO_3_11,
+
+#endif //]
+
+ /* LCD brightness */
+ MX6SL_PAD_PWM1__PWM1_PWMO,
+ /* LCD power on */
+ //MX6SL_PAD_KEY_ROW5__GPIO_4_3,
+
+ /* keypad on E-Ink add-on board */
+ MX6SL_PAD_KEY_COL0__KPP_COL_0,
+ MX6SL_PAD_KEY_COL1__KPP_COL_1,
+ MX6SL_PAD_KEY_COL2__KPP_COL_2,
+ MX6SL_PAD_KEY_COL3__KPP_COL_3,
+ MX6SL_PAD_KEY_ROW0__KPP_ROW_0,
+ MX6SL_PAD_KEY_ROW1__KPP_ROW_1,
+ MX6SL_PAD_KEY_ROW2__KPP_ROW_2,
+ MX6SL_PAD_KEY_ROW3__KPP_ROW_3,
+
+ /* WDOG */
+ MX6SL_PAD_WDOG_B__WDOG1_WDOG_B,
+
+ /* Charge */
+ MX6SL_PAD_ECSPI2_MISO__GPIO_4_14, /* CHG_FLT */
+ MX6SL_PAD_ECSPI2_SS0__GPIO_4_15, /* CHG_STATUS */
+ MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13, /* CHG_UOK ,CHG_DOK*/
+};
+
+static iomux_v3_cfg_t mx6sl_brd_epdc_enable_pads[] = {
+ /* EPDC */
+ MX6SL_PAD_EPDC_D0__EPDC_SDDO_0,
+ MX6SL_PAD_EPDC_D1__EPDC_SDDO_1,
+ MX6SL_PAD_EPDC_D2__EPDC_SDDO_2,
+ MX6SL_PAD_EPDC_D3__EPDC_SDDO_3,
+ MX6SL_PAD_EPDC_D4__EPDC_SDDO_4,
+ MX6SL_PAD_EPDC_D5__EPDC_SDDO_5,
+ MX6SL_PAD_EPDC_D6__EPDC_SDDO_6,
+ MX6SL_PAD_EPDC_D7__EPDC_SDDO_7,
+ MX6SL_PAD_EPDC_D8__EPDC_SDDO_8,
+ MX6SL_PAD_EPDC_D9__EPDC_SDDO_9,
+ MX6SL_PAD_EPDC_D10__EPDC_SDDO_10,
+ MX6SL_PAD_EPDC_D11__EPDC_SDDO_11,
+ MX6SL_PAD_EPDC_D12__EPDC_SDDO_12,
+ MX6SL_PAD_EPDC_D13__EPDC_SDDO_13,
+ MX6SL_PAD_EPDC_D14__EPDC_SDDO_14,
+ MX6SL_PAD_EPDC_D15__EPDC_SDDO_15,
+
+ MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK,
+ MX6SL_PAD_EPDC_GDSP__EPDC_GDSP,
+ MX6SL_PAD_EPDC_GDOE__EPDC_GDOE,
+ MX6SL_PAD_EPDC_GDRL__EPDC_GDRL,
+ MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK,
+ MX6SL_PAD_EPDC_SDOE__EPDC_SDOE,
+ MX6SL_PAD_EPDC_SDLE__EPDC_SDLE,
+ MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR,
+ MX6SL_PAD_EPDC_BDR0__EPDC_BDR_0,
+ MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE_0,
+ MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE_1,
+// MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE_2,
+
+ /* EPD PMIC (Maxim 17135) pins */
+// MX6SL_PAD_EPDC_VCOM0__GPIO_2_3,
+// MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13,
+// MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7,
+// MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_epdc_disable_pads[] = {
+ /* EPDC */
+ MX6SL_PAD_EPDC_D0__GPIO_1_7,
+ MX6SL_PAD_EPDC_D1__GPIO_1_8,
+ MX6SL_PAD_EPDC_D2__GPIO_1_9,
+ MX6SL_PAD_EPDC_D3__GPIO_1_10,
+ MX6SL_PAD_EPDC_D4__GPIO_1_11,
+ MX6SL_PAD_EPDC_D5__GPIO_1_12,
+ MX6SL_PAD_EPDC_D6__GPIO_1_13,
+ MX6SL_PAD_EPDC_D7__GPIO_1_14,
+ MX6SL_PAD_EPDC_D8__GPIO_1_15,
+ MX6SL_PAD_EPDC_D9__GPIO_1_16,
+ MX6SL_PAD_EPDC_D10__GPIO_1_17,
+ MX6SL_PAD_EPDC_D11__GPIO_1_18,
+ MX6SL_PAD_EPDC_D12__GPIO_1_19,
+ MX6SL_PAD_EPDC_D13__GPIO_1_20,
+ MX6SL_PAD_EPDC_D14__GPIO_1_21,
+ MX6SL_PAD_EPDC_D15__GPIO_1_22,
+
+ MX6SL_PAD_EPDC_GDCLK__GPIO_1_31,
+ MX6SL_PAD_EPDC_GDSP__GPIO_2_2,
+ MX6SL_PAD_EPDC_GDOE__GPIO_2_0,
+ MX6SL_PAD_EPDC_GDRL__GPIO_2_1,
+ MX6SL_PAD_EPDC_SDCLK__GPIO_1_23,
+ MX6SL_PAD_EPDC_SDOE__GPIO_1_25,
+ MX6SL_PAD_EPDC_SDLE__GPIO_1_24,
+ MX6SL_PAD_EPDC_SDSHR__GPIO_1_26,
+ MX6SL_PAD_EPDC_BDR0__GPIO_2_5,
+ MX6SL_PAD_EPDC_SDCE0__GPIO_1_27,
+ MX6SL_PAD_EPDC_SDCE1__GPIO_1_28,
+// MX6SL_PAD_EPDC_SDCE2__GPIO_1_29,
+
+ /* EPD PMIC (Maxim 17135) pins */
+// MX6SL_PAD_EPDC_VCOM0__GPIO_2_3,
+// MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13,
+// MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7,
+// MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_spdc_enable_pads[] = {
+ /* SPDC data*/
+ MX6SL_PAD_EPDC_D0__TCON_E_DATA_0,
+ MX6SL_PAD_EPDC_D1__TCON_E_DATA_1,
+ MX6SL_PAD_EPDC_D2__TCON_E_DATA_2,
+ MX6SL_PAD_EPDC_D3__TCON_E_DATA_3,
+ MX6SL_PAD_EPDC_D4__TCON_E_DATA_4,
+ MX6SL_PAD_EPDC_D5__TCON_E_DATA_5,
+ MX6SL_PAD_EPDC_D6__TCON_E_DATA_6,
+ MX6SL_PAD_EPDC_D7__TCON_E_DATA_7,
+
+ MX6SL_PAD_EPDC_GDOE__TCON_YOEL, /* AUO panel SIPIX_YOE */
+
+ MX6SL_PAD_EPDC_D9__TCON_E_DATA_9, /* AUO panel SIPIX_PWR_RDY*/
+
+// MX6SL_PAD_EPDC_SDCE2__TCON_YDIOUR, /* AUO panel SIPIX_YDIO */
+// MX6SL_PAD_EPDC_SDCE3__TCON_YDIODR, /* AUO panel SIPIX_YDIO */
+ MX6SL_PAD_EPDC_GDRL__TCON_YDIOUL, /* AUO panel SIPIX_YDIO */
+ MX6SL_PAD_EPDC_GDSP__TCON_YDIODL, /* SIPIX_YDIO/SIPIX2_SPV */
+
+ MX6SL_PAD_EPDC_GDCLK__TCON_YCKL, /* SIPIX_YCLK/SIPIX2_CKV */
+
+ MX6SL_PAD_EPDC_SDSHR__TCON_XDIOR, /* AUO panel SIPIX_XDIO */
+ MX6SL_PAD_EPDC_SDOE__TCON_XDIOL, /* SIPIX_XDIO/SIPIX2_OE */
+
+ MX6SL_PAD_EPDC_SDLE__TCON_LD, /* SIPIX_LD/SIPIX2_LE */
+
+ MX6SL_PAD_EPDC_SDCE1__TCON_YOER, /* AUO panel SIPIX_SOE */
+ MX6SL_PAD_EPDC_BDR0__TCON_RL, /* AUO panel SIPIX_SOE */
+ MX6SL_PAD_EPDC_BDR1__TCON_UD, /* AUO panel SIPIX_SOE */
+
+ MX6SL_PAD_EPDC_SDCLK__TCON_CL, /* SIPIX_XCLK/SIPIX2_CL */
+
+ MX6SL_PAD_EPDC_D10__TCON_E_DATA_10, /* AUO panel SIPIX_SHD_N */
+
+ MX6SL_PAD_EPDC_SDCE0__TCON_YCKR, /* LG panel SIPIX2_CE */
+
+ /* EPD PMIC (Maxim 17135) pins */
+ MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, /* PMICA_CEN */
+ MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13,
+ MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7,
+ MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_spdc_disable_pads[] = {
+ MX6SL_PAD_EPDC_D0__GPIO_1_7,
+ MX6SL_PAD_EPDC_D1__GPIO_1_8,
+ MX6SL_PAD_EPDC_D2__GPIO_1_9,
+ MX6SL_PAD_EPDC_D3__GPIO_1_10,
+ MX6SL_PAD_EPDC_D4__GPIO_1_11,
+ MX6SL_PAD_EPDC_D5__GPIO_1_12,
+ MX6SL_PAD_EPDC_D6__GPIO_1_13,
+ MX6SL_PAD_EPDC_D7__GPIO_1_14,
+
+ MX6SL_PAD_EPDC_SDCE1__GPIO_1_28,
+ MX6SL_PAD_EPDC_GDOE__GPIO_2_0,
+ MX6SL_PAD_EPDC_D9__GPIO_1_16,
+// MX6SL_PAD_EPDC_SDCE2__GPIO_1_29,
+// MX6SL_PAD_EPDC_SDCE3__GPIO_1_30,
+ MX6SL_PAD_EPDC_GDRL__GPIO_2_1,
+ MX6SL_PAD_EPDC_GDSP__GPIO_2_2,
+ MX6SL_PAD_EPDC_GDCLK__GPIO_1_31,
+ MX6SL_PAD_EPDC_SDSHR__GPIO_1_26,
+ MX6SL_PAD_EPDC_SDOE__GPIO_1_25,
+ MX6SL_PAD_EPDC_SDLE__GPIO_1_24,
+ MX6SL_PAD_EPDC_SDCE1__GPIO_1_28,
+ MX6SL_PAD_EPDC_BDR0__GPIO_2_5,
+ MX6SL_PAD_EPDC_BDR1__GPIO_2_6,
+ MX6SL_PAD_EPDC_SDCLK__GPIO_1_23,
+ MX6SL_PAD_EPDC_D10__GPIO_1_17,
+ MX6SL_PAD_EPDC_SDCE0__GPIO_1_27,
+
+ /* EPD PMIC (Maxim 17135) pins */
+ MX6SL_PAD_EPDC_VCOM0__GPIO_2_3,
+ MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13,
+ MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7,
+ MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_elan_pads[] = {
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, /* INT */
+ MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, /* CE */
+ MX6SL_PAD_KEY_COL6__GPIO_4_4, /* RST */
+};
+
+static iomux_v3_cfg_t suspend_enter_pads[] = {
+ /* Audio pads. */
+ MX6SL_PAD_AUD_MCLK__GPIO_1_6,
+ MX6SL_PAD_AUD_RXC__GPIO_1_1,
+ MX6SL_PAD_AUD_RXD__GPIO_1_2,
+ MX6SL_PAD_AUD_RXFS__GPIO_1_0,
+ MX6SL_PAD_AUD_TXC__GPIO_1_3,
+ MX6SL_PAD_AUD_TXD__GPIO_1_5,
+ MX6SL_PAD_AUD_TXFS__GPIO_1_4,
+ /* ECSPI pads. */
+ MX6SL_PAD_ECSPI1_MISO__GPIO_4_10,
+ MX6SL_PAD_ECSPI1_MOSI__GPIO_4_9,
+ MX6SL_PAD_ECSPI1_SCLK__GPIO_4_8,
+ MX6SL_PAD_ECSPI1_SS0__GPIO_4_11,
+ MX6SL_PAD_ECSPI2_SCLK__GPIO_4_12,
+ /* FEC pad*/
+ MX6SL_PAD_FEC_CRS_DV__GPIO_4_25,
+ MX6SL_PAD_FEC_MDC__GPIO_4_23,
+ MX6SL_PAD_FEC_MDIO__GPIO_4_20,
+ MX6SL_PAD_FEC_REF_CLK__GPIO_4_26,
+ MX6SL_PAD_FEC_RXD0__GPIO_4_17,
+ MX6SL_PAD_FEC_RXD1__GPIO_4_18,
+ MX6SL_PAD_FEC_TXD0__GPIO_4_24,
+ MX6SL_PAD_FEC_TXD1__GPIO_4_16,
+ MX6SL_PAD_FEC_TX_CLK__GPIO_4_21,
+ MX6SL_PAD_FEC_TX_EN__GPIO_4_22,
+ /* I2C pads */
+ MX6SL_PAD_I2C1_SCL__GPIO_3_12,
+ MX6SL_PAD_I2C1_SDA__GPIO_3_13,
+ MX6SL_PAD_I2C2_SCL__GPIO_3_14,
+ MX6SL_PAD_I2C2_SDA__GPIO_3_15,
+ /* LCD pads*/
+ MX6SL_PAD_LCD_CLK__GPIO_2_15,
+ MX6SL_PAD_LCD_DAT0__GPIO_2_20,
+ MX6SL_PAD_LCD_DAT1__GPIO_2_21,
+ MX6SL_PAD_LCD_DAT2__GPIO_2_22,
+ MX6SL_PAD_LCD_DAT3__GPIO_2_23,
+ MX6SL_PAD_LCD_DAT4__GPIO_2_24,
+ MX6SL_PAD_LCD_DAT5__GPIO_2_25,
+ MX6SL_PAD_LCD_DAT10__GPIO_2_30,
+ MX6SL_PAD_LCD_DAT11__GPIO_2_31,
+ MX6SL_PAD_LCD_DAT12__GPIO_3_0,
+ MX6SL_PAD_LCD_DAT13__GPIO_3_1,
+ MX6SL_PAD_LCD_DAT14__GPIO_3_2,
+ MX6SL_PAD_LCD_DAT15__GPIO_3_3,
+ MX6SL_PAD_LCD_DAT16__GPIO_3_4,
+ MX6SL_PAD_LCD_DAT17__GPIO_3_5,
+ MX6SL_PAD_LCD_DAT18__GPIO_3_6,
+ MX6SL_PAD_LCD_DAT19__GPIO_3_7,
+ MX6SL_PAD_LCD_DAT20__GPIO_3_8,
+ MX6SL_PAD_LCD_DAT21__GPIO_3_9,
+ MX6SL_PAD_LCD_DAT22__GPIO_3_10,
+ MX6SL_PAD_LCD_DAT23__GPIO_3_11,
+ /* PWM pads */
+ MX6SL_PAD_PWM1__GPIO_3_23,
+ /* SD pads. */
+ MX6SL_PAD_SD1_CLK__GPIO_5_15,
+ MX6SL_PAD_SD1_CMD__GPIO_5_14,
+ MX6SL_PAD_SD1_DAT0__GPIO_5_11,
+ MX6SL_PAD_SD1_DAT1__GPIO_5_8,
+ MX6SL_PAD_SD1_DAT2__GPIO_5_13,
+ MX6SL_PAD_SD1_DAT3__GPIO_5_6,
+ MX6SL_PAD_SD1_DAT4__GPIO_5_12,
+ MX6SL_PAD_SD1_DAT5__GPIO_5_9,
+ MX6SL_PAD_SD1_DAT6__GPIO_5_7,
+ MX6SL_PAD_SD1_DAT7__GPIO_5_10,
+
+ MX6SL_PAD_SD2_CLK__GPIO_5_5,
+ MX6SL_PAD_SD2_CMD__GPIO_5_4,
+ MX6SL_PAD_SD2_DAT0__GPIO_5_1,
+ MX6SL_PAD_SD2_DAT1__GPIO_4_30,
+ MX6SL_PAD_SD2_DAT2__GPIO_5_3,
+ MX6SL_PAD_SD2_DAT3__GPIO_4_28,
+ MX6SL_PAD_SD2_DAT4__GPIO_5_2,
+ MX6SL_PAD_SD2_DAT5__GPIO_4_31,
+
+ MX6SL_PAD_SD3_CLK__GPIO_5_18,
+ MX6SL_PAD_SD3_CMD__GPIO_5_21,
+ MX6SL_PAD_SD3_DAT0__GPIO_5_19,
+ MX6SL_PAD_SD3_DAT1__GPIO_5_20,
+ MX6SL_PAD_SD3_DAT2__GPIO_5_16,
+ MX6SL_PAD_SD3_DAT3__GPIO_5_17,
+
+ /* USBOTG ID pin */
+#ifndef CONFIG_USB_ID_WAKEUP_ENABLE
+ MX6SL_PAD_EPDC_PWRCOM__GPIO_2_11,
+#endif
+ MX6SL_PAD_HSIC_STROBE__GPIO_3_20,
+ MX6SL_PAD_HSIC_DAT__GPIO_3_19,
+
+ /* Key row/column */
+ MX6SL_PAD_KEY_COL0__GPIO_3_24,
+ MX6SL_PAD_KEY_COL1__GPIO_3_26,
+ MX6SL_PAD_KEY_COL2__GPIO_3_28,
+ MX6SL_PAD_KEY_COL3__GPIO_3_30,
+ MX6SL_PAD_KEY_COL6__GPIO_4_4,
+ MX6SL_PAD_KEY_COL7__GPIO_4_6,
+ MX6SL_PAD_KEY_ROW0__GPIO_3_25,
+ MX6SL_PAD_KEY_ROW1__GPIO_3_27,
+ MX6SL_PAD_KEY_ROW2__GPIO_3_29,
+ MX6SL_PAD_KEY_ROW3__GPIO_3_31,
+ MX6SL_PAD_KEY_ROW4__GPIO_4_1,
+ MX6SL_PAD_KEY_ROW5__GPIO_4_3,
+ MX6SL_PAD_KEY_ROW6__GPIO_4_5,
+};
+
+static iomux_v3_cfg_t suspend_exit_pads[ARRAY_SIZE(suspend_enter_pads)];
+
+#define MX6SL_USDHC_8BIT_PAD_SETTING(id, speed) \
+mx6sl_sd##id##_##speed##mhz[] = { \
+ MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+#define MX6SL_USDHC_4BIT_PAD_SETTING(id, speed) \
+mx6sl_sd##id##_##speed##mhz[] = { \
+ MX6SL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6SL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+}
+
+
+static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 50);
+static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 100);
+static iomux_v3_cfg_t MX6SL_USDHC_8BIT_PAD_SETTING(1, 200);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 50);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 100);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(2, 200);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6SL_USDHC_4BIT_PAD_SETTING(3, 200);
+
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c
new file mode 100644
index 00000000..4d09153d
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_evk.c
@@ -0,0 +1,1672 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <sound/wm8962.h>
+#include <sound/pcm.h>
+#include <linux/power/sabresd_battery.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6sl.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6sl_common.h"
+
+
+static int spdc_sel;
+static int max17135_regulator_init(struct max17135 *max17135);
+struct clk *extern_audio_root;
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int __init mx6sl_evk_init_pfuze100(u32 int_gpio);
+
+static int csi_enabled;
+
+static iomux_v3_cfg_t mx6sl_brd_csi_enable_pads[] = {
+ MX6SL_PAD_EPDC_GDRL__CSI_MCLK,
+ MX6SL_PAD_EPDC_SDCE3__I2C3_SDA,
+ MX6SL_PAD_EPDC_SDCE2__I2C3_SCL,
+ MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK,
+ MX6SL_PAD_EPDC_GDSP__CSI_VSYNC,
+ MX6SL_PAD_EPDC_GDOE__CSI_HSYNC,
+ MX6SL_PAD_EPDC_SDLE__CSI_D_9,
+ MX6SL_PAD_EPDC_SDCLK__CSI_D_8,
+ MX6SL_PAD_EPDC_D7__CSI_D_7,
+ MX6SL_PAD_EPDC_D6__CSI_D_6,
+ MX6SL_PAD_EPDC_D5__CSI_D_5,
+ MX6SL_PAD_EPDC_D4__CSI_D_4,
+ MX6SL_PAD_EPDC_D3__CSI_D_3,
+ MX6SL_PAD_EPDC_D2__CSI_D_2,
+ MX6SL_PAD_EPDC_D1__CSI_D_1,
+ MX6SL_PAD_EPDC_D0__CSI_D_0,
+
+ MX6SL_PAD_EPDC_SDSHR__GPIO_1_26, /* CMOS_RESET_B GPIO */
+ MX6SL_PAD_EPDC_SDOE__GPIO_1_25, /* CMOS_PWDN GPIO */
+};
+
+/* uart2 pins */
+static iomux_v3_cfg_t mx6sl_uart2_pads[] = {
+ MX6SL_PAD_SD2_DAT5__UART2_TXD,
+ MX6SL_PAD_SD2_DAT4__UART2_RXD,
+ MX6SL_PAD_SD2_DAT6__UART2_RTS,
+ MX6SL_PAD_SD2_DAT7__UART2_CTS,
+};
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int __init csi_setup(char *__unused)
+{
+ csi_enabled = 1;
+ return 1;
+}
+__setup("csi", csi_setup);
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 0:
+ sd_pads_200mhz = mx6sl_sd1_200mhz;
+ sd_pads_100mhz = mx6sl_sd1_100mhz;
+ sd_pads_50mhz = mx6sl_sd1_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz);
+ break;
+ case 1:
+ sd_pads_200mhz = mx6sl_sd2_200mhz;
+ sd_pads_100mhz = mx6sl_sd2_100mhz;
+ sd_pads_50mhz = mx6sl_sd2_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz);
+ break;
+ case 2:
+ sd_pads_200mhz = mx6sl_sd3_200mhz;
+ sd_pads_100mhz = mx6sl_sd3_100mhz;
+ sd_pads_50mhz = mx6sl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz);
+ break;
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+static const struct esdhc_platform_data mx6_evk_sd1_data __initconst = {
+ .cd_gpio = MX6_BRD_SD1_CD,
+ .wp_gpio = MX6_BRD_SD1_WP,
+ .support_8bit = 1,
+ .support_18v = 1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_evk_sd2_data __initconst = {
+ .cd_gpio = MX6_BRD_SD2_CD,
+ .wp_gpio = MX6_BRD_SD2_WP,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+static const struct esdhc_platform_data mx6_evk_sd3_data __initconst = {
+ .cd_gpio = MX6_BRD_SD3_CD,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .support_18v = 1,
+ .platform_pad_change = plt_sd_pad_change,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+static struct regulator_consumer_supply evk_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+};
+
+static struct regulator_init_data evk_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(evk_vmmc_consumers),
+ .consumer_supplies = evk_vmmc_consumers,
+};
+
+static struct fixed_voltage_config evk_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &evk_vmmc_init,
+};
+
+static struct platform_device evk_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &evk_vmmc_reg_config,
+ },
+};
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+};
+
+static const struct anatop_thermal_platform_data
+ mx6sl_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+ };
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * TODO: We cannot enable full constraints for now, since
+ * it results in the PFUZE regulators being disabled
+ * at the end of boot, which disables critical regulators.
+ */
+ /*regulator_has_full_constraints();*/
+
+ return 0;
+}
+
+static int mx6_evk_spi_cs[] = {
+ MX6_BRD_ECSPI1_CS0,
+};
+
+static const struct spi_imx_master mx6_evk_spi_data __initconst = {
+ .chipselect = mx6_evk_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_evk_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+};
+#endif
+
+static void spi_device_init(void)
+{
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+#endif
+}
+
+static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+static struct mxc_audio_platform_data wm8962_data;
+
+static struct platform_device mx6_sabresd_audio_wm8962_device = {
+ .name = "imx-wm8962",
+};
+
+static struct wm8962_pdata wm8962_config_data = {
+
+};
+
+static int wm8962_clk_enable(int enable)
+{
+ if (enable)
+ clk_enable(extern_audio_root);
+ else
+ clk_disable(extern_audio_root);
+
+ return 0;
+}
+
+static int mxc_wm8962_init(void)
+{
+ struct clk *pll4;
+ int rate;
+
+ extern_audio_root = clk_get(NULL, "extern_audio_clk");
+ if (IS_ERR(extern_audio_root)) {
+ pr_err("can't get extern_audio_root clock.\n");
+ return PTR_ERR(extern_audio_root);
+ }
+
+ pll4 = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4)) {
+ pr_err("can't get pll4 clock.\n");
+ return PTR_ERR(pll4);
+ }
+
+ clk_set_parent(extern_audio_root, pll4);
+
+ rate = 24000000;
+ clk_set_rate(extern_audio_root, 24000000);
+
+ wm8962_data.sysclk = rate;
+ /* set AUDMUX pads to 1.8v */
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_MCLK,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_RXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXC,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXFS,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+
+ return 0;
+}
+
+static struct mxc_audio_platform_data wm8962_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = MX6_BRD_HEADPHONE_DET,
+ .hp_active_low = 1,
+ .mic_gpio = -1,
+ .mic_active_low = 1,
+ .init = mxc_wm8962_init,
+ .clock_enable = wm8962_clk_enable,
+};
+
+static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_init_data sabresd_vwm8962_init = {
+ .constraints = {
+ .name = "SPKVDD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers),
+ .consumer_supplies = sabresd_vwm8962_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vwm8962_reg_config = {
+ .supply_name = "SPKVDD",
+ .microvolts = 4325000,
+ .gpio = -1,
+ .enabled_at_boot = 1,
+ .init_data = &sabresd_vwm8962_init,
+};
+
+static struct platform_device sabresd_vwm8962_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &sabresd_vwm8962_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ platform_device_register(&sabresd_vwm8962_reg_devices);
+ mxc_register_device(&mx6_sabresd_audio_wm8962_device,
+ &wm8962_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ return 0;
+}
+
+static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 1,
+ .spdif_clk_48000 = -1,
+ .spdif_div_44100 = 23,
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL,
+};
+
+
+enum DISPLAY_PANEL_MODE {
+ PANEL_MODE_LCD,
+ PANEL_MODE_HDMI,
+ PANEL_MODE_EINK,
+};
+
+static int display_panel_mode = PANEL_MODE_EINK;
+
+static iomux_v3_cfg_t mx6sl_sii902x_hdmi_pads_enabled[] = {
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10,
+};
+
+static int sii902x_get_pins(void)
+{
+ /* Sii902x HDMI controller */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_sii902x_hdmi_pads_enabled, \
+ ARRAY_SIZE(mx6sl_sii902x_hdmi_pads_enabled));
+
+ /* Reset Pin */
+ gpio_request(MX6_BRD_LCD_RESET, "disp0-reset");
+ gpio_direction_output(MX6_BRD_LCD_RESET, 1);
+
+ /* Interrupter pin GPIO */
+ gpio_request(MX6SL_BRD_EPDC_PWRCTRL3, "disp0-detect");
+ gpio_direction_input(MX6SL_BRD_EPDC_PWRCTRL3);
+ return 1;
+}
+
+static void sii902x_put_pins(void)
+{
+ gpio_free(MX6_BRD_LCD_RESET);
+ gpio_free(MX6SL_BRD_EPDC_PWRCTRL3);
+}
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(MX6_BRD_LCD_RESET, 0);
+ msleep(10);
+ gpio_set_value(MX6_BRD_LCD_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .reset = sii902x_hdmi_reset,
+ .get_pins = sii902x_get_pins,
+ .put_pins = sii902x_put_pins,
+};
+
+static void mx6sl_csi_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_csi_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_csi_enable_pads));
+
+ /* Camera reset */
+ gpio_request(MX6SL_BRD_CSI_RST, "cam-reset");
+ gpio_direction_output(MX6SL_BRD_CSI_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6SL_BRD_CSI_PWDN, "cam-pwdn");
+ gpio_direction_output(MX6SL_BRD_CSI_PWDN, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 0);
+ msleep(1);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+}
+
+static void mx6sl_csi_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+ else
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+
+ msleep(2);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .mclk = 24000000,
+ .io_init = mx6sl_csi_io_init,
+ .pwdn = mx6sl_csi_cam_powerdown,
+ .core_regulator = "VGEN2_1V5",
+ .analog_regulator = "VGEN6_2V8",
+};
+
+static struct imxi2c_platform_data mx6_evk_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_evk_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_evk_i2c2_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max17135", 0), /*0x48*/
+ .platform_data = &max17135_pdata,
+ }, {
+ I2C_BOARD_INFO("elan-touch", 0), /*0x10*/
+ .irq = gpio_to_irq(MX6SL_BRD_ELAN_INT),
+ }, {
+ I2C_BOARD_INFO("mma8450", 0x1c),
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("wm8962", 0x1a),
+ .platform_data = &wm8962_config_data,
+ },
+ {
+ I2C_BOARD_INFO("sii902x", 0), /*0x39*/
+ .platform_data = &sii902x_hdmi_data,
+ .irq = gpio_to_irq(MX6SL_BRD_EPDC_PWRCTRL3)
+ },
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ov5640", 0x3c),
+ .platform_data = (void *)&camera_data,
+ },
+};
+
+static struct mxc_dvfs_platform_data mx6sl_evk_dvfscore_data = {
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+#else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+#endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_32M,
+};
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+
+static const struct imxuart_platform_data mx6sl_evk_uart1_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
+};
+
+static inline void mx6_evk_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */
+}
+
+static int mx6sl_evk_fec_phy_init(struct phy_device *phydev)
+{
+ int val;
+
+ /* power on FEC phy and reset phy */
+ gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr");
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0);
+ /* wait RC ms for hw reset */
+ msleep(1);
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1);
+
+ /* check phy power */
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6sl_evk_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_GDRL);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_BDR0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDRL);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_BDR0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0);
+}
+
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+static int spdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for SPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE");
+
+ return ret;
+}
+
+static void spdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable SPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_disable_pins(void)
+{
+ /* Configure MUX settings for SPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+}
+
+static struct imx_spdc_panel_init_set spdc_init_set = {
+ .yoe_pol = false,
+ .dual_gate = false,
+ .resolution = 0,
+ .ud = false,
+ .rl = false,
+ .data_filter_n = true,
+ .power_ready = true,
+ .rgbw_mode_enable = false,
+ .hburst_len_en = true,
+};
+
+static struct fb_videomode erk_1_4_a01 = {
+ .name = "ERK_1_4_A01",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 40000000,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct imx_spdc_fb_mode spdc_panel_modes[] = {
+ {
+ &erk_1_4_a01,
+ &spdc_init_set,
+ .wave_timing = "pvi"
+ },
+};
+
+static struct imx_spdc_fb_platform_data spdc_data = {
+ .spdc_mode = spdc_panel_modes,
+ .num_modes = ARRAY_SIZE(spdc_panel_modes),
+ .get_pins = spdc_get_pins,
+ .put_pins = spdc_put_pins,
+ .enable_pins = spdc_enable_pins,
+ .disable_pins = spdc_disable_pins,
+};
+
+static int __init early_use_spdc_sel(char *p)
+{
+ spdc_sel = 1;
+ return 0;
+}
+early_param("spdc", early_use_spdc_sel);
+
+static void setup_spdc(void)
+{
+ /* GPR0[8]: 0:EPDC, 1:SPDC */
+ if (spdc_sel)
+ mxc_iomux_set_gpr_register(0, 8, 1, 1);
+}
+
+static void imx6_evk_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 1);
+ else
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 0);
+}
+
+static void __init mx6_evk_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0);
+
+ ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1);
+
+ mx6_set_otghost_vbus_func(imx6_evk_usbotg_vbus);
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+#endif
+}
+
+static struct platform_pwm_backlight_data mx6_evk_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+static struct fb_videomode wvga_video_modes[] = {
+ {
+ /* 800x480 @ 57 Hz , pixel clk @ 32MHz */
+ "SEIKO-WVGA", 60, 800, 480, 29850, 89, 164, 23, 10, 10, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data wvga_fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "SEIKO-WVGA",
+ .mode = wvga_video_modes,
+ .num_modes = ARRAY_SIZE(wvga_video_modes),
+ .panel_type = "lcd",
+ },
+};
+
+static struct platform_device lcd_wvga_device = {
+ .name = "lcd_seiko",
+};
+
+static struct fb_videomode hdmi_video_modes[] = {
+ {
+ /* 1920x1080 @ 60 Hz , pixel clk @ 148MHz */
+ "sii9022x_1080p60", 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data hdmi_fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "1920x1080M@60",
+ .mode = hdmi_video_modes,
+ .num_modes = ARRAY_SIZE(hdmi_video_modes),
+ .panel_type = "hdmi",
+ },
+};
+
+static int mx6sl_evk_keymap[] = {
+ KEY(0, 0, KEY_SELECT), /* EVK:SW6 DC2:SELECT */
+ KEY(0, 1, KEY_BACK), /* EVK:SW7 DC2:BACK */
+ KEY(0, 2, KEY_F1), /* EVK:SW8 DC2:F1 */
+ KEY(0, 3, KEY_F2), /* EVK DC2:F2 */
+
+ KEY(1, 0, KEY_F3), /* EVK:SW9 DC2:F3 */
+ KEY(1, 1, KEY_VOLUMEDOWN), /* EVK:SW10 DC2:F4 */
+ KEY(1, 2, KEY_VOLUMEUP), /* EVK:SW11 DC2:F5 */
+ KEY(1, 3, KEY_MENU), /* EVK DC2:MENU */
+
+ KEY(2, 0, KEY_PREVIOUS), /* EVK:SW12 DC2:PREV */
+ KEY(2, 1, KEY_NEXT), /* EVK:SW13 DC2:NEX1 */
+ KEY(2, 2, KEY_HOME), /* EVK DC2:HOME */
+ KEY(2, 3, KEY_NEXT), /* EVK DC2:NEX2 */
+
+ KEY(3, 0, KEY_UP), /* EVK DC2:UP */
+ KEY(3, 1, KEY_LEFT), /* EVK DC2:LEFT */
+ KEY(3, 2, KEY_RIGHT), /* EVK DC2:RIGHT */
+ KEY(3, 3, KEY_DOWN), /* EVK DC2:DOWN */
+};
+
+static const struct matrix_keymap_data mx6sl_evk_map_data __initconst = {
+ .keymap = mx6sl_evk_keymap,
+ .keymap_size = ARRAY_SIZE(mx6sl_evk_keymap),
+};
+static void __init elan_ts_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads,
+ ARRAY_SIZE(mx6sl_brd_elan_pads));
+
+ /* ELAN Touchscreen */
+ gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(MX6SL_BRD_ELAN_INT);
+
+ gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs");
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 0);
+
+ gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst");
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 0);
+ mdelay(1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+}
+
+/*
+ *Usually UOK and DOK should have separate
+ *line to differentiate its behaviour (with different
+ * GPIO irq),because connect max8903 pin UOK to
+ *pin DOK from hardware design,cause software cannot
+ *process and distinguish two interrupt, so default
+ *enable dc_valid for ac charger
+ */
+static struct max8903_pdata charger1_data = {
+ .dok = MX6_BRD_CHG_DOK,
+ .uok = MX6_BRD_CHG_UOK,
+ .chg = MX6_BRD_CHG_STATUS,
+ .flt = MX6_BRD_CHG_FLT,
+ .dcm_always_high = true,
+ .dc_valid = true,
+ .usb_valid = false,
+ .feature_flag = 1,
+};
+
+static struct platform_device evk_max8903_charger_1 = {
+ .name = "max8903-charger",
+ .dev = {
+ .platform_data = &charger1_data,
+ },
+};
+
+/*! Device Definition for csi v4l2 device */
+static struct platform_device csi_v4l2_devices = {
+ .name = "csi_v4l2",
+ .id = 0,
+};
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+ u32 value;
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /* set TOP and DP_EN bit */
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+static int uart2_enabled;
+static int __init uart2_setup(char * __unused)
+{
+ uart2_enabled = 1;
+ return 1;
+}
+__setup("bluetooth", uart2_setup);
+
+static void __init uart2_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_uart2_pads,
+ ARRAY_SIZE(mx6sl_uart2_pads));
+ imx6sl_add_imx_uart(1, &mx6sl_evk_uart1_data);
+}
+
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+
+#define MX6SL_EVK_POWER_OFF IMX_GPIO_NR(3, 18)
+
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+ .debounce_interval = debounce, \
+}
+
+static struct gpio_keys_button imx6sl_buttons[] = {
+ GPIO_BUTTON(MX6SL_EVK_POWER_OFF, KEY_POWER, 1, "power", 1, 1),
+};
+
+static struct gpio_keys_platform_data imx6sl_button_data = {
+ .buttons = imx6sl_buttons,
+ .nbuttons = ARRAY_SIZE(imx6sl_buttons),
+ .rep = 0,
+};
+
+static struct platform_device imx6sl_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &imx6sl_button_data,
+ }
+};
+
+static void __init imx6sl_add_device_buttons(void)
+{
+ platform_device_register(&imx6sl_button_device);
+}
+#else
+static void __init imx6sl_add_device_buttons(void) {}
+#endif
+
+
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_evk_init(void)
+{
+ u32 i;
+
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
+ ARRAY_SIZE(mx6sl_brd_pads));
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ gp_reg_id = mx6sl_evk_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_evk_dvfscore_data.soc_id;
+#else
+ gp_reg_id = mx6sl_evk_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_evk_dvfscore_data.soc_id;
+ pu_reg_id = mx6sl_evk_dvfscore_data.pu_id;
+ mx6_cpu_regulator_init();
+#endif
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_i2c(0, &mx6_evk_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_evk_i2c1_data);
+
+ /* setting sii902x address when hdmi enabled */
+ switch (display_panel_mode) {
+ case PANEL_MODE_EINK:
+ for (i = 0; i < ARRAY_SIZE(mxc_i2c0_board_info); i++)
+ if (!strcmp(mxc_i2c0_board_info[i].type, "max17135"))
+ mxc_i2c0_board_info[i].addr = 0x48;
+ for (i = 0; i < ARRAY_SIZE(mxc_i2c0_board_info); i++)
+ if (!strcmp(mxc_i2c0_board_info[i].type, "elan-touch"))
+ mxc_i2c0_board_info[i].addr = 0x10;
+ elan_ts_init();
+ mxc_register_device(&max17135_sensor_device, NULL);
+ setup_spdc();
+ if (!spdc_sel)
+ imx6dl_add_imx_epdc(&epdc_data);
+ else
+ imx6sl_add_imx_spdc(&spdc_data);
+ break;
+ case PANEL_MODE_HDMI:
+ for (i = 0; i < ARRAY_SIZE(mxc_i2c1_board_info); i++)
+ if (!strcmp(mxc_i2c1_board_info[i].type, "sii902x"))
+ mxc_i2c1_board_info[i].addr = 0x39;
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF//[
+ imx6dl_add_imx_elcdif(&hdmi_fb_data[0]);
+#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+ mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0",
+ NULL);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ imx6q_add_spdif(&mxc_spdif_data);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+ break;
+ case PANEL_MODE_LCD:
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF//[
+ imx6dl_add_imx_elcdif(&wvga_fb_data[0]);
+#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ mxc_register_device(&lcd_wvga_device, NULL);
+ break;
+ default:
+ pr_err("Error display_panel_mode\n");
+ }
+
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+
+ /* only camera on I2C2, that's why we can do so */
+ if (csi_enabled == 1) {
+ mxc_register_device(&csi_v4l2_devices, NULL);
+ imx6q_add_imx_i2c(2, &mx6_evk_i2c2_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+ }
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6_evk_spi_data);
+ spi_device_init();
+
+ mx6sl_evk_init_pfuze100(0);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data);
+
+ mx6_evk_init_uart();
+ /* get enet tx reference clk from FEC_REF_CLK pad.
+ * GPR1[14] = 0, GPR1[18:17] = 00
+ */
+ mxc_iomux_set_gpr_register(1, 14, 1, 0);
+ mxc_iomux_set_gpr_register(1, 17, 2, 0);
+
+ imx6_init_fec(fec_data);
+
+ platform_device_register(&evk_vmmc_reg_devices);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6_evk_sd2_data);
+ imx6q_add_sdhci_usdhc_imx(0, &mx6_evk_sd1_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_evk_sd3_data);
+
+ mx6_evk_init_usb();
+ imx6q_add_otp();
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_evk_pwm_backlight_data);
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF//[
+ imx6dl_add_imx_elcdif(&wvga_fb_data[0]);
+#endif //] CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+
+ gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+ gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ mxc_register_device(&lcd_wvga_device, NULL);
+
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+
+ if (csi_enabled) {
+ imx6sl_add_fsl_csi();
+ }
+ imx6q_add_dvfs_core(&mx6sl_evk_dvfscore_data);
+
+ imx6q_init_audio();
+
+ /* uart2 for bluetooth */
+ if (uart2_enabled)
+ uart2_init();
+
+ //mxc_register_device(&mxc_bt_rfkill, &mxc_bt_rfkill_data);
+
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6sl_add_device_buttons();
+ imx6sl_add_imx_keypad(&mx6sl_evk_map_data);
+ imx6q_add_busfreq();
+ imx6sl_add_dcp();
+ imx6sl_add_rngb();
+ imx6sl_add_imx_pxp_v4l2();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+ /* Register charger chips */
+ platform_device_register(&evk_max8903_charger_1);
+ pm_power_off = mx6_snvs_poweroff;
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6sl_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6_evk_reserve(void)
+{
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ phys_addr_t phys;
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+}
+
+static int __init display_panel_setup(char *options)
+{
+ if (!options || !*options) {
+ pr_err("Error panel options\n");
+ return 0;
+ }
+
+ if (!strcmp(options, "lcd"))
+ display_panel_mode = PANEL_MODE_LCD;
+ else if (!strcmp(options, "hdmi"))
+ display_panel_mode = PANEL_MODE_HDMI;
+ else if (!strcmp(options, "eink"))
+ display_panel_mode = PANEL_MODE_EINK;
+ else
+ pr_warn("WARN: invalid display panel mode setting");
+
+ return 1;
+}
+
+__setup("panel=", display_panel_setup);
+
+MACHINE_START(MX6SL_EVK, "Freescale i.MX 6SoloLite EVK Board")
+ .boot_params = MX6SL_PHYS_OFFSET + 0x100,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_evk_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_evk_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6sl_ntx.c b/arch/arm/mach-mx6/board-mx6sl_ntx.c
new file mode 100755
index 00000000..26c3c900
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_ntx.c
@@ -0,0 +1,3886 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/max17135.h>
+#include <sound/wm8962.h>
+#include <sound/pcm.h>
+#include <linux/power/sabresd_battery.h>
+#include <../drivers/misc/ntx-misc.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6sl.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <linux/usbplugevent.h>
+#include <linux/mmc/sdhci.h>
+
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "board-mx6sl_common.h"
+#include "board-mx6sl_ntx.h"
+
+#include "ntx_hwconfig.h"
+
+#include <linux/mfd/ricoh619.h>
+#include <linux/rtc/rtc-ricoh619.h>
+#include <linux/power/ricoh619_battery.h>
+#include <linux/regulator/ricoh619-regulator.h>
+
+#include "../../../drivers/input/keyboard/gpiofn.h"
+#define TOUCH_HOME_LED 1
+#include "../../../drivers/misc/ntx-misc.h"
+
+
+#define GDEBUG 0
+#include <linux/gallen_dbg.h>
+
+
+#define EPD_TIMING_ED068OG1_NUMCE3 1
+#define EPD_TIMING_ED068TG1 1
+
+
+
+extern int gSleep_Mode_Suspend;
+
+
+volatile unsigned gMX6SL_NTX_ACIN_PG = IMX_GPIO_NR(4, 20); /* FEC_MDIO */
+volatile unsigned gMX6SL_NTX_CHG = IMX_GPIO_NR(4, 21); /* FEC_TX_CLK */
+volatile unsigned gMX6SL_MSP_INT = IMX_GPIO_NR(4, 19); /* FEC_RX_ER */
+volatile unsigned gMX6SL_PWR_SW = IMX_GPIO_NR(4, 25); /* FEC_CRS_DV */
+volatile unsigned gMX6SL_IR_TOUCH_INT = IMX_GPIO_NR(4, 24); /* FEC_TXD0 */
+volatile unsigned gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(4, 17); /* FEC_RXD0 */
+volatile unsigned gMX6SL_HALL_EN = IMX_GPIO_NR(4, 23); /* FEC_MDC */
+volatile unsigned gMX6SL_ON_LED = IMX_GPIO_NR(4, 22); /* FEC_TX_EN */
+volatile unsigned gMX6SL_CHG_LED = IMX_GPIO_NR(4, 16); /* FEC_TXD1 */
+volatile unsigned gMX6SL_ACT_LED = IMX_GPIO_NR(4, 26); /* FEC_REF_CLK */
+volatile unsigned gMX6SL_WIFI_3V3 = IMX_GPIO_NR(5, 0); /* SD2_DAT7 */
+volatile unsigned gMX6SL_WIFI_RST = IMX_GPIO_NR(4, 27); /* SD2_RST */
+volatile unsigned gMX6SL_WIFI_INT = IMX_GPIO_NR(4, 29); /* SD2_DAT6 */
+volatile unsigned gMX6SL_HOME_LED = IMX_GPIO_NR(5, 10); /* SD2_DAT6 */
+
+volatile int giISD_3V3_ON_Ctrl = -1;
+
+static int spdc_sel;
+static int max17135_regulator_init(struct max17135 *max17135);
+
+extern char *gp_reg_id;
+extern char *soc_reg_id;
+extern char *pu_reg_id;
+extern int __init mx6sl_ntx_init_pfuze100(u32 int_gpio);
+extern void tle4913_init(void);
+
+static int csi_enabled;
+
+#define _MYINIT_DATA
+#define _MYINIT_TEXT
+volatile static unsigned char _MYINIT_DATA *gpbHWCFG_paddr;
+//volatile unsigned char *gpbHWCFG_vaddr;
+volatile unsigned long _MYINIT_DATA gdwHWCFG_size;
+volatile int _MYINIT_DATA giBootPort;
+
+volatile NTX_HWCONFIG *gptHWCFG;
+
+static void * _MemoryRequest(void *addr, u32 len, const char * name)
+{
+ void * mem = NULL;
+ do {
+ printk(KERN_DEBUG "***%s:%d: request memory region! addr=%p, len=%hd***\n",
+ __FUNCTION__, __LINE__, addr, len);
+ if (!request_mem_region((u32)addr, len, name)) {
+ printk(KERN_CRIT "%s(): request memory region failed! addr=%p, len %hd\n",__FUNCTION__, addr, len);
+ break;
+ }
+ mem = (void *) ioremap_nocache((u32)addr, len);
+ if (!mem) {
+ printk(KERN_CRIT "***%s:%d: could not ioremap %s***\n", __FUNCTION__, __LINE__, name);
+ release_mem_region((u32)addr, len);
+ break;
+ }
+ } while (0);
+ return mem;
+}
+
+int gIsCustomerUi;
+static int _MYINIT_TEXT hwcfg_p_setup(char *str)
+{
+ gpbHWCFG_paddr = (unsigned char *)simple_strtoul(str,NULL,0);
+ if(NULL==gptHWCFG) {
+ gptHWCFG = (NTX_HWCONFIG *)_MemoryRequest((void *)gpbHWCFG_paddr, gdwHWCFG_size, "hwcfg_p");
+ if(!gptHWCFG) {
+ return 0;
+ }
+ }
+ printk("%s() hwcfg_p=%p,vaddr=%p,size=%d,pcb=0x%x\n",__FUNCTION__,
+ gpbHWCFG_paddr,gptHWCFG,(int)gdwHWCFG_size,gptHWCFG->m_val.bPCB);
+ gIsCustomerUi = (int)gptHWCFG->m_val.bUIStyle;
+
+ return 1;
+}
+
+static int _MYINIT_TEXT hwcfg_size_setup(char *str)
+{
+ gdwHWCFG_size = (unsigned long)simple_strtoul(str,NULL,0);
+ printk("%s() hwcfg_szie=%d\n",__FUNCTION__,(int)gdwHWCFG_size);
+ return 1;
+}
+
+static int _MYINIT_TEXT boot_port_setup(char *str)
+{
+ giBootPort = (int)simple_strtoul(str,NULL,0);
+ printk("%s() boot_port=%d\n",__FUNCTION__,giBootPort);
+ return 1;
+}
+
+static void _parse_cmdline(void)
+{
+ static int iParseCnt = 0;
+ char *pcPatternStart,*pcPatternVal,*pcPatternValEnd,cTempStore;
+ unsigned long ulPatternLen;
+
+ char *szParsePatternA[]={"hwcfg_sz=","hwcfg_p=","boot_port="};
+ int ((*pfnDispatchA[])(char *str))={hwcfg_size_setup,hwcfg_p_setup,boot_port_setup };
+
+ int i;
+ char *pszCmdLineBuf;
+
+
+ if(iParseCnt++>0) {
+ printk("%s : cmdline parse already done .\n",__FUNCTION__);
+ return ;
+ }
+ //printk("%s():cmdline(%d)=%s\n",__FUNCTION__,strlen(saved_command_line),saved_command_line);
+
+ pszCmdLineBuf = kmalloc(strlen(saved_command_line)+1,GFP_KERNEL);
+ //ASSERT(pszCmdLineBuf);
+ strcpy(pszCmdLineBuf,saved_command_line);
+ printk("%s():cp cmdline=%s\n",__FUNCTION__,pszCmdLineBuf);
+
+ for(i=0;i<sizeof(szParsePatternA)/sizeof(szParsePatternA[0]);i++) {
+ ulPatternLen = strlen(szParsePatternA[i]);
+ pcPatternStart = strstr(pszCmdLineBuf,szParsePatternA[i]);
+ if(pcPatternStart) {
+ pcPatternVal=pcPatternStart + ulPatternLen ;
+ pcPatternValEnd = strchr(pcPatternVal,' ');
+ cTempStore='\0';
+ if(pcPatternValEnd) {
+ cTempStore = *pcPatternValEnd;
+ *pcPatternValEnd = '\0';
+ }
+ //printk("%s():pattern \"%s\" ,val=\"%s\"\n",__FUNCTION__,szParsePatternA[i],pcPatternVal);
+ pfnDispatchA[i](pcPatternVal);
+ if(pcPatternValEnd) {
+ *pcPatternValEnd = cTempStore;
+ }
+ }
+ else
+ printk ("[%s-%d] %s not found !!!\n",__func__,__LINE__,szParsePatternA[i]);
+ }
+ if (NULL == gptHWCFG) {
+ printk ("[%s-%d] personal initial hw config.\n",__func__,__LINE__);
+ gptHWCFG = (NTX_HWCONFIG *)kmalloc(sizeof(NTX_HWCONFIG), GFP_KERNEL);
+ gptHWCFG->m_val.bTouchCtrl = 8;
+ }
+}
+
+
+
+/* uart2 pins */
+#if 0 // gallen disabled .
+static iomux_v3_cfg_t mx6sl_uart2_pads[] = {
+ MX6SL_PAD_SD2_DAT5__UART2_TXD,
+ MX6SL_PAD_SD2_DAT4__UART2_RXD,
+ MX6SL_PAD_SD2_DAT6__UART2_RTS,
+ MX6SL_PAD_SD2_DAT7__UART2_CTS,
+};
+#endif
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd_pad_change(unsigned int index, int clock)
+{
+ /* LOW speed is the default state of SD pads */
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ iomux_v3_cfg_t *sd_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd_pads_50mhz = NULL;
+
+ u32 sd_pads_200mhz_cnt;
+ u32 sd_pads_100mhz_cnt;
+ u32 sd_pads_50mhz_cnt;
+
+ switch (index) {
+ case 0:
+ sd_pads_200mhz = mx6sl_sd1_200mhz;
+ sd_pads_100mhz = mx6sl_sd1_100mhz;
+ sd_pads_50mhz = mx6sl_sd1_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd1_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd1_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd1_50mhz);
+ break;
+ case 1:
+ sd_pads_200mhz = mx6sl_sd2_200mhz;
+ sd_pads_100mhz = mx6sl_sd2_100mhz;
+ sd_pads_50mhz = mx6sl_sd2_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd2_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd2_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd2_50mhz);
+ break;
+ case 2:
+ sd_pads_200mhz = mx6sl_sd3_200mhz;
+ sd_pads_100mhz = mx6sl_sd3_100mhz;
+ sd_pads_50mhz = mx6sl_sd3_50mhz;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_sd3_200mhz);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_sd3_100mhz);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_sd3_50mhz);
+ break;
+ case 3:
+ sd_pads_200mhz = mx6sl_brd_ntx_sd4_pads;
+ sd_pads_100mhz = mx6sl_brd_ntx_sd4_pads;
+ sd_pads_50mhz = mx6sl_brd_ntx_sd4_pads;
+
+ sd_pads_200mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads);
+ sd_pads_100mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads);
+ sd_pads_50mhz_cnt = ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads);
+ break;
+
+ default:
+ printk(KERN_ERR "no such SD host controller index %d\n", index);
+ return -EINVAL;
+ }
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_200mhz);
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz,
+ sd_pads_200mhz_cnt);
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_100mhz);
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz,
+ sd_pads_100mhz_cnt);
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+ BUG_ON(!sd_pads_50mhz);
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz,
+ sd_pads_50mhz_cnt);
+ }
+}
+
+
+static const struct esdhc_platform_data mx6_ntx_isd_data __initconst = {
+ .always_present = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+static const struct esdhc_platform_data mx6_ntx_isd8bits_data __initconst = {
+ .always_present = 1,
+ .delay_line = 0,
+ .support_8bit = 1,
+ .platform_pad_change = plt_sd_pad_change,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+static const struct esdhc_platform_data mx6_ntx_sd_wifi_data __initconst = {
+ .cd_gpio = MX6SL_WIFI_3V3,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+// .platform_pad_change = plt_sd_pad_change,
+ .cd_type = ESDHC_CD_WIFI_PWR,
+};
+
+static const struct esdhc_platform_data mx6_ntx_q22_sd_wifi_data __initconst = {
+ .cd_gpio = IMX_GPIO_NR(4, 29),
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+// .platform_pad_change = plt_sd_pad_change,
+ .cd_type = ESDHC_CD_WIFI_PWR,
+};
+
+static const struct esdhc_platform_data mx6_ntx_esd_data __initconst = {
+ .cd_gpio = MX6SL_EXT_SD_CD,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd_pad_change,
+ .cd_type = ESDHC_CD_GPIO,
+};
+static const struct esdhc_platform_data mx6_ntx_esd_nocd_data __initconst = {
+ .always_present = 1,
+ .cd_gpio = 0,
+ .wp_gpio = -1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = 0,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#if 0
+static struct regulator_consumer_supply ntx_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.0"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data ntx_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(ntx_vmmc_consumers),
+ .consumer_supplies = ntx_vmmc_consumers,
+};
+
+static struct fixed_voltage_config ntx_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &ntx_vmmc_init,
+};
+
+static struct platform_device ntx_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &ntx_vmmc_reg_config,
+ },
+};
+#endif
+
+static struct regulator_consumer_supply display_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "DISPLAY",
+ },
+};
+
+static struct regulator_consumer_supply vcom_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "VCOM",
+ },
+};
+
+static struct regulator_consumer_supply v3p3_consumers[] = {
+ {
+ /* MAX17135 */
+ .supply = "V3P3",
+ },
+};
+
+static struct regulator_init_data max17135_init_data[] = {
+#if 0
+ {
+ .constraints = {
+ .name = "DISPLAY",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(display_consumers),
+ .consumer_supplies = display_consumers,
+ }, {
+ .constraints = {
+ .name = "GVDD",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "GVEE",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINN",
+ .min_uV = V_to_uV(-22),
+ .max_uV = V_to_uV(-22),
+ },
+ }, {
+ .constraints = {
+ .name = "HVINP",
+ .min_uV = V_to_uV(20),
+ .max_uV = V_to_uV(20),
+ },
+ }, {
+ .constraints = {
+ .name = "VCOM",
+ .min_uV = mV_to_uV(-4325),
+ .max_uV = mV_to_uV(-500),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vcom_consumers),
+ .consumer_supplies = vcom_consumers,
+ }, {
+ .constraints = {
+ .name = "VNEG",
+ .min_uV = V_to_uV(-15),
+ .max_uV = V_to_uV(-15),
+ },
+ }, {
+ .constraints = {
+ .name = "VPOS",
+ .min_uV = V_to_uV(15),
+ .max_uV = V_to_uV(15),
+ },
+ }, {
+ .constraints = {
+ .name = "V3P3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(v3p3_consumers),
+ .consumer_supplies = v3p3_consumers,
+ },
+#endif
+};
+
+static const struct anatop_thermal_platform_data
+ mx6sl_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+ };
+
+static struct platform_device max17135_sensor_device = {
+ .name = "max17135_sensor",
+ .id = 0,
+};
+
+static struct max17135_platform_data max17135_pdata __initdata = {
+ .vneg_pwrup = 1,
+ .gvee_pwrup = 1,
+ .vpos_pwrup = 2,
+ .gvdd_pwrup = 1,
+ .gvdd_pwrdn = 1,
+ .vpos_pwrdn = 2,
+ .gvee_pwrdn = 1,
+ .vneg_pwrdn = 1,
+ .gpio_pmic_pwrgood = MX6SL_BRD_EPDC_PWRSTAT,
+ .gpio_pmic_vcom_ctrl = MX6SL_BRD_EPDC_VCOM,
+ .gpio_pmic_wakeup = MX6SL_BRD_EPDC_PMIC_WAKE,
+ .gpio_pmic_v3p3 = MX6SL_BRD_EPDC_PWRCTRL0,
+ .gpio_pmic_intr = MX6SL_BRD_EPDC_PMIC_INT,
+ .regulator_init = max17135_init_data,
+ .init = max17135_regulator_init,
+};
+
+static int __init max17135_regulator_init(struct max17135 *max17135)
+{
+#if 0
+ struct max17135_platform_data *pdata = &max17135_pdata;
+ int i, ret;
+
+ max17135->gvee_pwrup = pdata->gvee_pwrup;
+ max17135->vneg_pwrup = pdata->vneg_pwrup;
+ max17135->vpos_pwrup = pdata->vpos_pwrup;
+ max17135->gvdd_pwrup = pdata->gvdd_pwrup;
+ max17135->gvdd_pwrdn = pdata->gvdd_pwrdn;
+ max17135->vpos_pwrdn = pdata->vpos_pwrdn;
+ max17135->vneg_pwrdn = pdata->vneg_pwrdn;
+ max17135->gvee_pwrdn = pdata->gvee_pwrdn;
+
+ max17135->max_wait = pdata->vpos_pwrup + pdata->vneg_pwrup +
+ pdata->gvdd_pwrup + pdata->gvee_pwrup;
+
+ max17135->gpio_pmic_pwrgood = pdata->gpio_pmic_pwrgood;
+ max17135->gpio_pmic_vcom_ctrl = pdata->gpio_pmic_vcom_ctrl;
+ max17135->gpio_pmic_wakeup = pdata->gpio_pmic_wakeup;
+ max17135->gpio_pmic_v3p3 = pdata->gpio_pmic_v3p3;
+ max17135->gpio_pmic_intr = pdata->gpio_pmic_intr;
+
+ gpio_request(max17135->gpio_pmic_wakeup, "epdc-pmic-wake");
+ gpio_direction_output(max17135->gpio_pmic_wakeup, 0);
+
+ gpio_request(max17135->gpio_pmic_vcom_ctrl, "epdc-vcom");
+ gpio_direction_output(max17135->gpio_pmic_vcom_ctrl, 0);
+
+ gpio_request(max17135->gpio_pmic_v3p3, "epdc-v3p3");
+ gpio_direction_output(max17135->gpio_pmic_v3p3, 0);
+
+ gpio_request(max17135->gpio_pmic_intr, "epdc-pmic-int");
+ gpio_direction_input(max17135->gpio_pmic_intr);
+
+ gpio_request(max17135->gpio_pmic_pwrgood, "epdc-pwrstat");
+ gpio_direction_input(max17135->gpio_pmic_pwrgood);
+
+ max17135->vcom_setup = false;
+ max17135->init_done = false;
+
+ for (i = 0; i < MAX17135_NUM_REGULATORS; i++) {
+ ret = max17135_register_regulator(max17135, i,
+ &pdata->regulator_init[i]);
+ if (ret != 0) {
+ printk(KERN_ERR"max17135 regulator init failed: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
+ * TODO: We cannot enable full constraints for now, since
+ * it results in the PFUZE regulators being disabled
+ * at the end of boot, which disables critical regulators.
+ */
+ /*regulator_has_full_constraints();*/
+#endif
+ return 0;
+}
+
+static int mx6_ntx_spi_cs[] = {
+ MX6_BRD_ECSPI1_CS0,
+};
+
+static const struct spi_imx_master mx6_ntx_spi_data __initconst = {
+ .chipselect = mx6_ntx_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_ntx_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00100000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+};
+#endif
+
+static void spi_device_init(void)
+{
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+#endif
+}
+
+static struct imx_ssi_platform_data mx6_sabresd_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_SYN,
+};
+
+#if 0
+static struct mxc_audio_platform_data wm8962_data;
+
+static struct platform_device mx6_sabresd_audio_wm8962_device = {
+ .name = "imx-wm8962",
+};
+
+static struct wm8962_pdata wm8962_config_data = {
+
+};
+
+static int wm8962_clk_enable(int enable)
+{
+ if (enable)
+ clk_enable(ntx_extern_audio_root);
+ else
+ clk_disable(ntx_extern_audio_root);
+
+ return 0;
+}
+
+static int mxc_wm8962_init(void)
+{
+ struct clk *pll4;
+ int rate;
+
+ ntx_extern_audio_root = clk_get(NULL, "extern_audio_clk");
+ if (IS_ERR(ntx_extern_audio_root)) {
+ pr_err("can't get ntx_extern_audio_root clock.\n");
+ return PTR_ERR(ntx_extern_audio_root);
+ }
+
+ pll4 = clk_get(NULL, "pll4");
+ if (IS_ERR(pll4)) {
+ pr_err("can't get pll4 clock.\n");
+ return PTR_ERR(pll4);
+ }
+
+ clk_set_parent(ntx_extern_audio_root, pll4);
+
+ rate = clk_round_rate(ntx_extern_audio_root, 26000000);
+ clk_set_rate(ntx_extern_audio_root, rate);
+
+ wm8962_data.sysclk = rate;
+ /* set AUDMUX pads to 1.8v */
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_MCLK,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_RXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXC,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXD,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+ mxc_iomux_set_specialbits_register(MX6SL_PAD_AUD_TXFS,
+ PAD_CTL_LVE, PAD_CTL_LVE_MASK);
+
+ return 0;
+}
+
+static struct mxc_audio_platform_data wm8962_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_gpio = MX6_BRD_HEADPHONE_DET,
+ .hp_active_low = 1,
+ .mic_gpio = -1,
+ .mic_active_low = 1,
+ .init = mxc_wm8962_init,
+ .clock_enable = wm8962_clk_enable,
+};
+
+static struct regulator_consumer_supply sabresd_vwm8962_consumers[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "1-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "1-001a"),
+};
+
+static struct regulator_init_data sabresd_vwm8962_init = {
+ .constraints = {
+ .name = "SPKVDD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sabresd_vwm8962_consumers),
+ .consumer_supplies = sabresd_vwm8962_consumers,
+};
+
+static struct fixed_voltage_config sabresd_vwm8962_reg_config = {
+ .supply_name = "SPKVDD",
+ .microvolts = 4325000,
+ .gpio = -1,
+ .enabled_at_boot = 1,
+ .init_data = &sabresd_vwm8962_init,
+};
+
+static struct platform_device sabresd_vwm8962_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &sabresd_vwm8962_reg_config,
+ },
+};
+
+static int __init imx6q_init_audio(void)
+{
+ platform_device_register(&sabresd_vwm8962_reg_devices);
+ mxc_register_device(&mx6_sabresd_audio_wm8962_device,
+ &wm8962_data);
+ imx6q_add_imx_ssi(1, &mx6_sabresd_ssi_pdata);
+
+ return 0;
+}
+
+static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 1,
+ .spdif_clk_48000 = -1,
+ .spdif_div_44100 = 23,
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL,
+};
+#endif
+
+
+enum DISPLAY_PANEL_MODE {
+ PANEL_MODE_LCD,
+ PANEL_MODE_HDMI,
+ PANEL_MODE_EINK,
+};
+
+static int display_panel_mode = PANEL_MODE_EINK;
+
+#if 0
+static iomux_v3_cfg_t mx6sl_sii902x_hdmi_pads_enabled[] = {
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10,
+};
+
+static int sii902x_get_pins(void)
+{
+ /* Sii902x HDMI controller */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_sii902x_hdmi_pads_enabled, \
+ ARRAY_SIZE(mx6sl_sii902x_hdmi_pads_enabled));
+
+ /* Reset Pin */
+ gpio_request(MX6_BRD_LCD_RESET, "disp0-reset");
+ gpio_direction_output(MX6_BRD_LCD_RESET, 1);
+
+ /* Interrupter pin GPIO */
+ gpio_request(MX6SL_BRD_EPDC_PWRCTRL3, "disp0-detect");
+ gpio_direction_input(MX6SL_BRD_EPDC_PWRCTRL3);
+ return 1;
+}
+
+static void sii902x_put_pins(void)
+{
+ gpio_free(MX6_BRD_LCD_RESET);
+ gpio_free(MX6SL_BRD_EPDC_PWRCTRL3);
+}
+
+static void sii902x_hdmi_reset(void)
+{
+ gpio_set_value(MX6_BRD_LCD_RESET, 0);
+ msleep(10);
+ gpio_set_value(MX6_BRD_LCD_RESET, 1);
+ msleep(10);
+}
+
+static struct fsl_mxc_lcd_platform_data sii902x_hdmi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .reset = sii902x_hdmi_reset,
+ .get_pins = sii902x_get_pins,
+ .put_pins = sii902x_put_pins,
+};
+
+static void mx6sl_csi_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_csi_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_csi_enable_pads));
+
+ /* Camera reset */
+ gpio_request(MX6SL_BRD_CSI_RST, "cam-reset");
+ gpio_direction_output(MX6SL_BRD_CSI_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6SL_BRD_CSI_PWDN, "cam-pwdn");
+ gpio_direction_output(MX6SL_BRD_CSI_PWDN, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 0);
+ msleep(1);
+ gpio_set_value(MX6SL_BRD_CSI_RST, 1);
+ msleep(5);
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+}
+
+static void mx6sl_csi_cam_powerdown(int powerdown)
+{
+ if (powerdown)
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 1);
+ else
+ gpio_set_value(MX6SL_BRD_CSI_PWDN, 0);
+
+ msleep(2);
+}
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .mclk = 24000000,
+ .io_init = mx6sl_csi_io_init,
+ .pwdn = mx6sl_csi_cam_powerdown,
+ .core_regulator = "VGEN2_1V5",
+ .analog_regulator = "VGEN6_2V8",
+};
+#endif
+
+static struct imxi2c_platform_data mx6_ntx_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_ntx_i2c1_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data mx6_ntx_i2c2_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info i2c_zforce_ir_touch_binfo = {
+ .type = "zforce-ir-touch",
+ .addr = 0x50,
+ //.platform_data = MX6SL_IR_TOUCH_INT,
+ //.irq = gpio_to_irq(MX6SL_IR_TOUCH_INT),
+};
+
+static struct i2c_board_info i2c_elan_touch_binfo = {
+ .type = "elan-touch",
+ .addr = 0x15,
+};
+
+int ricoh619_init_port(int irq_num)
+{
+ printk("[%s-%d] ...\n",__func__,__LINE__);
+ return 0;
+}
+
+static struct ricoh619_rtc_platform_data ricoh_rtc_data = {
+ .time = {
+ .tm_year = 1970,
+ .tm_mon = 0,
+ .tm_mday = 1,
+ .tm_hour = 0,
+ .tm_min = 0,
+ .tm_sec = 0,
+ },
+};
+
+static struct ricoh619_battery_platform_data ricoh_battery_data = {
+// .irq = RICOH619_IRQ_BASE,
+ .alarm_vol_mv = 3400,
+ // .adc_channel = RICOH619_ADC_CHANNEL_VBAT,
+ .multiple = 100, //100%
+ .monitor_time = 60,
+ /* some parameter is depend of battery type */
+ .type[0] = {
+ .ch_vfchg = 0xFF, /* VFCHG = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+ .ch_vrchg = 0xFF, /* VRCHG = 0 - 4 (3.85v, 3.90v, 3.95v, 4.00v, 4.10v) */
+ .ch_vbatovset = 0xFF, /* VBATOVSET = 0 or 1 (0 : 4.38v(up)/3.95v(down) 1: 4.53v(up)/4.10v(down)) */
+ .ch_ichg = 0xFF, /* ICHG = 0 - 0x1D (100mA - 3000mA) */
+ .ch_ilim_adp = 0xFF, /* ILIM_ADP = 0 - 0x1D (100mA - 3000mA) */
+ .ch_ilim_usb = 0xFF, /* ILIM_USB = 0 - 0x1D (100mA - 3000mA) */
+ .ch_icchg = 0, /* ICCHG = 0 - 3 (50mA 100mA 150mA 200mA) */
+ .fg_target_vsys = 0, /* This value is the target one to DSOC=0% */
+ .fg_target_ibat = 0, /* This value is the target one to DSOC=0% */
+ .fg_poff_vbat = 3520, /* setting value of 0 per Vbat */
+ .jt_en = 0, /* JEITA Enable = 0 or 1 (1:enable, 0:disable) */
+ .jt_hw_sw = 1, /* JEITA HW or SW = 0 or 1 (1:HardWare, 0:SoftWare) */
+ .jt_temp_h = 50, /* degree C */
+ .jt_temp_l = 12, /* degree C */
+ .jt_vfchg_h = 0x03, /* VFCHG High = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+ .jt_vfchg_l = 0, /* VFCHG High = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+ .jt_ichg_h = 0x0D, /* VFCHG Low = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+ .jt_ichg_l = 0x09, /* ICHG Low = 0 - 0x1D (100mA - 3000mA) */
+ },
+ /*
+ .type[1] = {
+ .ch_vfchg = 0x0,
+ .ch_vrchg = 0x0,
+ .ch_vbatovset = 0x0,
+ .ch_ichg = 0x0,
+ .ch_ilim_adp = 0x0,
+ .ch_ilim_usb = 0x0,
+ .ch_icchg = 0x00,
+ .fg_target_vsys = 3300,//3000,
+ .fg_target_ibat = 1000,//1000,
+ .jt_en = 0,
+ .jt_hw_sw = 1,
+ .jt_temp_h = 40,
+ .jt_temp_l = 10,
+ .jt_vfchg_h = 0x0,
+ .jt_vfchg_l = 0,
+ .jt_ichg_h = 0x01,
+ .jt_ichg_l = 0x01,
+ },
+ */
+
+/* JEITA Parameter
+*
+* VCHG
+* |
+* jt_vfchg_h~+~~~~~~~~~~~~~~~~~~~+
+* | |
+* jt_vfchg_l-| - - - - - - - - - +~~~~~~~~~~+
+* | Charge area + |
+* -------0--+-------------------+----------+--- Temp
+* ! +
+* ICHG
+* | +
+* jt_ichg_h-+ - -+~~~~~~~~~~~~~~+~~~~~~~~~~+
+* + | + |
+* jt_ichg_l-+~~~~+ Charge area |
+* | + + |
+* 0--+----+--------------+----------+--- Temp
+* 0 jt_temp_l jt_temp_h 55
+*/
+};
+
+#define RICOH_REG(_id, _name, _sname) \
+{ \
+ .id = RICOH619_ID_##_id, \
+ .name = "ricoh61x-regulator", \
+ .platform_data = &pdata_##_name##_##_sname, \
+}
+
+static struct regulator_consumer_supply ricoh619_dc1_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core2_1v3_soc", NULL),
+};
+static struct regulator_consumer_supply ricoh619_dc2_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core1_3v3", NULL),
+};
+static struct regulator_consumer_supply ricoh619_dc3_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core2_1v3_arm", NULL),
+};
+static struct regulator_consumer_supply ricoh619_dc4_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core4_1v2", NULL),
+};
+static struct regulator_consumer_supply ricoh619_dc5_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core4_1v8", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldo1_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_ir_3v3", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldo2_supply_0[] = {
+};
+static struct regulator_consumer_supply ricoh619_ldo3_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_core5_1v2", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldo4_supply_0[] = {
+};
+static struct regulator_consumer_supply ricoh619_ldo5_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_spd_3v3", NULL),
+// REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+static struct regulator_consumer_supply ricoh619_ldo6_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_ddr_0v6", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldo7_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_pwm", "0-0007"),
+ REGULATOR_SUPPLY("vdd_fl_0_pwm", "0-0043"),
+ REGULATOR_SUPPLY("vdd_fl_pwm", "2-0043"),
+};
+static struct regulator_consumer_supply ricoh619_ldo8_supply_0[] = {
+ REGULATOR_SUPPLY("ldo_1v8", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldo9_supply_0[] = {
+};
+static struct regulator_consumer_supply ricoh619_ldo10_supply_0[] = {
+};
+static struct regulator_consumer_supply ricoh619_ldortc1_supply_0[] = {
+ REGULATOR_SUPPLY("vdd_rtc_3v3", NULL),
+};
+static struct regulator_consumer_supply ricoh619_ldortc2_supply_0[] = {
+};
+
+#define RICOH_PDATA_INIT(_name, _sname, _minmv, _maxmv, _supply_reg, _always_on, \
+ _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply, _flags, \
+ _ext_contol, _sleep_mV) \
+ static struct ricoh619_regulator_platform_data pdata_##_name##_##_sname = \
+ { \
+ .regulator = { \
+ .constraints = { \
+ .min_uV = (_minmv)*1000, \
+ .max_uV = (_maxmv)*1000, \
+ .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
+ REGULATOR_MODE_STANDBY), \
+ .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
+ REGULATOR_CHANGE_STATUS | \
+ REGULATOR_CHANGE_VOLTAGE), \
+ .always_on = _always_on, \
+ .boot_on = _boot_on, \
+ .apply_uV = _apply_uv, \
+ }, \
+ .num_consumer_supplies = \
+ ARRAY_SIZE(ricoh619_##_name##_supply_##_sname), \
+ .consumer_supplies = ricoh619_##_name##_supply_##_sname, \
+ .supply_regulator = _supply_reg, \
+ }, \
+ .init_uV = _init_uV * 1000, \
+ .init_enable = _init_enable, \
+ .init_apply = _init_apply, \
+ .sleep_uV = (_sleep_mV)*1000, \
+ .flags = _flags, \
+ .ext_pwr_req = _ext_contol, \
+ }
+
+RICOH_PDATA_INIT(dc1, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 950); // Core2_1V3
+RICOH_PDATA_INIT(dc2, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core3_3V3
+RICOH_PDATA_INIT(dc3, 0, 950, 1425, 0, 1, 1, 0, 1425, 1, 1, 0, 0, 950); // Core2_1V3_ARM
+RICOH_PDATA_INIT(dc4, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core4_1V2
+RICOH_PDATA_INIT(dc5, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core4_1V8
+
+RICOH_PDATA_INIT(ldo1, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // IR_3V3
+RICOH_PDATA_INIT(ldo2, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core1_3V3*
+RICOH_PDATA_INIT(ldo3, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // Core5_1V2
+RICOH_PDATA_INIT(ldo4, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved
+RICOH_PDATA_INIT(ldo5, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // SPD_3V3
+RICOH_PDATA_INIT(ldo6, 0, 0, 0, 0, 1, 1, 0, -1, 1, 1, 0, 0, 0); // DDR_0V6
+RICOH_PDATA_INIT(ldo7, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // VDD_PWM
+RICOH_PDATA_INIT(ldo8, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // ldo_1v8
+//RICOH_PDATA_INIT(ldo8, 0, 3300, 3300, 0, 1, 1, 0, 3300, 1, 1, 0, 0, 3300); // ldo_1v8 output 3V3
+RICOH_PDATA_INIT(ldo9, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved
+RICOH_PDATA_INIT(ldo10, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0); // Reserved
+RICOH_PDATA_INIT(ldortc1, 0,0, 0, 0, 1, 1, 0, -1, 1, 1, -1, -1, -1);
+RICOH_PDATA_INIT(ldortc2, 0,0, 0, 0, 0, 0, 0, -1, 0, 1, -1, -1, -1);
+
+#define RICOH619_DEV_REG \
+ RICOH_REG(DC1, dc1, 0), \
+ RICOH_REG(DC2, dc2, 0), \
+ RICOH_REG(DC3, dc3, 0), \
+ RICOH_REG(DC4, dc4, 0), \
+ RICOH_REG(DC5, dc5, 0), \
+ RICOH_REG(LDO1, ldo1, 0), \
+ RICOH_REG(LDO2, ldo2, 0), \
+ RICOH_REG(LDO3, ldo3, 0), \
+ RICOH_REG(LDO4, ldo4, 0), \
+ RICOH_REG(LDO5, ldo5, 0), \
+ RICOH_REG(LDO6, ldo6, 0), \
+ RICOH_REG(LDO7, ldo7, 0), \
+ RICOH_REG(LDO8, ldo8, 0), \
+ RICOH_REG(LDO9, ldo9, 0), \
+ RICOH_REG(LDO10, ldo10, 0), \
+ RICOH_REG(LDORTC1, ldortc1, 0), \
+ RICOH_REG(LDORTC2, ldortc2, 0)
+
+struct ricoh619_subdev_info ricoh619_sub_data[] = {
+ RICOH619_DEV_REG,
+ {
+ .name = "ricoh619-battery",
+ .id = -1,
+ .platform_data = &ricoh_battery_data,
+ },
+ {
+ .name = "rtc_ricoh619",
+ .id = 0,
+ .platform_data = &ricoh_rtc_data,
+ },
+};
+
+
+#define RICOH_GPIO_INIT(_init_apply, _output_mode, _output_val, _led_mode, _led_func) \
+ { \
+ .output_mode_en = _output_mode, \
+ .output_val = _output_val, \
+ .init_apply = _init_apply, \
+ .led_mode = _led_mode, \
+ .led_func = _led_func, \
+ }
+struct ricoh619_gpio_init_data ricoh_gpio_data[] = {
+ RICOH_GPIO_INIT(false, false, 0, 0, 0),
+ RICOH_GPIO_INIT(false, false, 0, 0, 0),
+ RICOH_GPIO_INIT(false, false, 0, 0, 0),
+ RICOH_GPIO_INIT(false, false, 0, 0, 0),
+};
+
+static struct ricoh619_platform_data ntx_ricoh_data = {
+ .num_subdevs = ARRAY_SIZE(ricoh619_sub_data),
+ .subdevs = ricoh619_sub_data,
+ .gpio_base = 7*32,
+ .gpio_init_data = ricoh_gpio_data,
+ .num_gpioinit_data = ARRAY_SIZE(ricoh_gpio_data),
+ .enable_shutdown_pin = true,
+};
+
+static struct i2c_board_info i2c_sysmp_ricoh619_binfo = {
+ .type = "ricoh619",
+ .addr = 0x32,
+ .platform_data = &ntx_ricoh_data,
+};
+
+static struct i2c_board_info i2c_sysmp_msp430_binfo = {
+ .type = "msp430",
+ .addr = 0x43,
+ //.irq = gpio_to_irq(MX6SL_MSP_INT),
+};
+
+static struct i2c_board_info i2c_ht68f20_binfo = {
+ .type = "ht68f20",
+ .addr = 0x07,
+};
+
+static struct i2c_board_info i2c_kl25_binfo = {
+ .type = "kl25",
+ .addr = 0x5A,
+ .irq = gpio_to_irq(MX6SL_KL25_INT2),
+};
+
+static struct i2c_board_info i2c_mma8652_binfo = {
+ .type = "mma8652",
+ .addr = 0x1D,
+ .irq = gpio_to_irq(MX6SL_KL25_INT2),
+};
+
+static struct i2c_board_info i2c_wacom_binfo = {
+ .type = "wacom_i2c",
+ .addr = 0x09,
+ .irq = gpio_to_irq(MX6SL_WACOM_INT),
+};
+
+static struct i2c_board_info __initdata i2c_waltop_binfo = {
+ .type = "waltop_i2c",
+ .addr = 0x37,
+ .platform_data = MX6SL_WALTOP_RST,
+ .irq = gpio_to_irq(MX6SL_WALTOP_INT),
+};
+#if 0
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+};
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+#if 0
+ {
+ I2C_BOARD_INFO("ov5640", 0x3c),
+ .platform_data = (void *)&camera_data,
+ },
+#endif
+ {
+ .type = "msp430",
+ .addr = 0x43,
+ .irq = gpio_to_irq(MX6SL_MSP_INT),
+ },
+};
+#endif
+
+static struct ntx_misc_platform_data ntx_misc_info;
+
+static struct platform_device ntx_charger = {
+ .name = "pmic_battery",
+ .id = 1,
+ .dev = {
+ .platform_data = &ntx_misc_info,
+ }
+};
+
+static struct platform_device ntx_light_ldm = {
+ .name = "pmic_light",
+ .id = 1,
+};
+
+static struct mxc_dvfs_platform_data mx6sl_ntx_dvfscore_data = {
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ .reg_id = "VDDCORE",
+ .soc_id = "VDDSOC",
+#else
+ .reg_id = "cpu_vddgp",
+ .soc_id = "cpu_vddsoc",
+ .pu_id = "cpu_vddvpu",
+#endif
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_32M,
+};
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+
+static const struct imxuart_platform_data mx6sl_ntx_uart1_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
+};
+
+static inline void mx6_ntx_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL); /* DEBUG UART1 */
+}
+
+#if 0
+static int mx6sl_ntx_fec_phy_init(struct phy_device *phydev)
+{
+ int val;
+
+ /* power on FEC phy and reset phy */
+ gpio_request(MX6_BRD_FEC_PWR_EN, "fec-pwr");
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 0);
+ /* wait RC ms for hw reset */
+ msleep(1);
+ gpio_direction_output(MX6_BRD_FEC_PWR_EN, 1);
+
+ /* check phy power */
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6sl_ntx_fec_phy_init,
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+#endif
+
+static int epdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for EPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "epdc_d0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "epdc_d1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "epdc_d2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "epdc_d3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "epdc_d4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "epdc_d5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "epdc_d6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "epdc_d7");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_8 , "epdc_d8");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9 , "epdc_d9");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "epdc_d10");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_11, "epdc_d11");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_12, "epdc_d12");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_13, "epdc_d13");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_14, "epdc_d14");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_15, "epdc_d15");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "epdc_gdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "epdc_gdsp");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "epdc_gdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDRL, "epdc_gdrl");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "epdc_sdclk");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDOE, "epdc_sdoe");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "epdc_sdle");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "epdc_sdshr");
+ ret |= gpio_request(MX6SL_BRD_EPDC_BDR0, "epdc_bdr0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "epdc_sdce0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "epdc_sdce1");
+// ret |= gpio_request(MX6SL_BRD_EPDC_SDCE2, "epdc_sdce2");
+
+ return ret;
+}
+
+static void epdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_8);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_11);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_12);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_13);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_14);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_15);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_GDRL);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_BDR0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+// gpio_free(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void mxc_pads_lve_setup(iomux_v3_cfg_t *pad_list, unsigned count,int iIsLVE)
+{
+ iomux_v3_cfg_t tPadctrlOld;
+ iomux_v3_cfg_t tPadctrl;
+ iomux_v3_cfg_t *p = pad_list;
+
+ int i;
+
+ for(i=0;i<count;i++) {
+ tPadctrlOld = tPadctrl = *p ;
+
+#if 0
+ if(tPadctrl&NO_PAD_CTRL) {
+ mxc_iomux_v3_get_pad(&tPadctrlOld);
+ tPadctrl = tPadctrlOld;
+ //tPadctrl &= ~((iomux_v3_cfg_t)NO_PAD_CTRL<<MUX_PAD_CTRL_SHIFT);
+ }
+#endif
+
+ if(iIsLVE) {
+ tPadctrl |= ((iomux_v3_cfg_t)PAD_CTL_LVE<<MUX_PAD_CTRL_SHIFT);
+ }
+ else {
+ tPadctrl &= ~((iomux_v3_cfg_t)PAD_CTL_LVE<<MUX_PAD_CTRL_SHIFT);
+ }
+
+ #if 0
+ printk("PAD LVE 0x%llx:0x%llx->0x%llx \n",
+ pad_list[i],tPadctrlOld,tPadctrl);
+ #endif
+
+ mxc_iomux_v3_setup_pad(tPadctrl);
+ p++;
+ }
+}
+
+
+
+
+
+static void epdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable EPDC use */
+
+ if(NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,4)) {
+ // Panel is designed for low voltage .
+ mxc_pads_lve_setup(mx6sl_brd_epdc_enable_pads,\
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads),1);
+ }
+ else {
+#if 0
+ mxc_pads_lve_setup(mx6sl_brd_epdc_enable_pads,\
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads),0);
+#else
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_enable_pads));
+#endif
+
+ }
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ //if( 1==gptHWCFG->m_val.bDisplayBusWidth ||
+ // 3==gptHWCFG->m_val.bDisplayBusWidth)
+ {
+ // 16 bits .
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_8);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_11);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_12);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_13);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_14);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_15);
+ }
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDRL);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_BDR0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+// gpio_direction_input(MX6SL_BRD_EPDC_SDCE2);
+}
+
+static void epdc_disable_pins(void)
+{
+ /* Configure MUX settings for EPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_epdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_epdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ //if( 1==gptHWCFG->m_val.bDisplayBusWidth ||
+ // 3==gptHWCFG->m_val.bDisplayBusWidth)
+ {
+ // 16 bits .
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_8, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_11, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_12, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_13, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_14, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_15, 0);
+ }
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDRL, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_BDR0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+// gpio_direction_output(MX6SL_BRD_EPDC_SDCE2, 0);
+}
+
+#if 1 //[
+static struct fb_videomode ed060scq_mode = {
+.name = "E60SCQ",
+.refresh = 85,
+.xres = 800,
+.yres = 600,
+.pixclock = 25000000,
+.left_margin = 8,
+.right_margin = 60,
+.upper_margin = 4,
+.lower_margin = 10,
+.hsync_len = 8,
+.vsync_len = 4,
+.sync = 0,
+.vmode = FB_VMODE_NONINTERLACED,
+.flag = 0,
+};
+
+static struct fb_videomode ed060sc8_mode = {
+.name = "E60SC8",
+.refresh = 85,
+.xres = 800,
+.yres = 600,
+.pixclock = 30000000,
+.left_margin = 8,
+.right_margin = 164,
+.upper_margin = 4,
+.lower_margin = 18,
+.hsync_len = 4,
+.vsync_len = 1,
+.sync = 0,
+.vmode = FB_VMODE_NONINTERLACED,
+.flag = 0,
+};
+
+// for ED060XC5 release by Freescale Grace 20120726 .
+
+static struct fb_videomode ed060xc1_mode = {
+.name = "E60XC1",
+.refresh = 85,
+.xres = 1024,
+.yres = 768,
+.pixclock = 40000000,
+.left_margin = 12,
+.right_margin = 72,
+.upper_margin = 4,
+.lower_margin = 5,
+.hsync_len = 8,
+.vsync_len = 2,
+.sync = 0,
+.vmode = FB_VMODE_NONINTERLACED,
+.flag = 0,
+};
+
+static struct fb_videomode ed060xc5_mode = {
+.name = "E60XC5",
+.refresh = 85,
+.xres = 1024,
+.yres = 758,
+.pixclock = 40000000,
+.left_margin = 12,
+.right_margin = 76,
+.upper_margin = 4,
+.lower_margin = 5,
+.hsync_len = 12,
+.vsync_len = 2,
+.sync = 0,
+.vmode = FB_VMODE_NONINTERLACED,
+.flag = 0,
+};
+
+static struct fb_videomode e60_v110_mode = {
+.name = "E60_V110",
+.refresh = 50,
+.xres = 800,
+.yres = 600,
+.pixclock = 18604700,
+.left_margin = 8,
+.right_margin = 176,
+.upper_margin = 4,
+.lower_margin = 2,
+.hsync_len = 4,
+.vsync_len = 1,
+.sync = 0,
+.vmode = FB_VMODE_NONINTERLACED,
+.flag = 0,
+};
+
+static struct fb_videomode ed050xxx_mode = {
+ .name="ED050XXXX",
+ .refresh=85,
+ .xres=800,
+ .yres=600,
+ .pixclock=26666667,
+ .left_margin=4,
+ .right_margin=98,
+ .upper_margin=4,
+ .lower_margin=9,
+ .hsync_len=8,
+ .vsync_len=2,
+ .sync=0,
+ .vmode=FB_VMODE_NONINTERLACED,
+ .flag=0,
+};
+
+
+#ifdef EPD_TIMING_ED068TG1 //[
+static struct fb_videomode ed068tg1_mode = {
+.name = "ED068TG1",
+.refresh=85,
+.xres=1440,
+.yres=1080,
+.pixclock=96000000,
+.left_margin=24,
+.right_margin=267,
+.upper_margin=4,
+.lower_margin=5,
+.hsync_len=24,
+.vsync_len=2,
+.sync=0,
+.vmode=FB_VMODE_NONINTERLACED,
+.flag=0,
+};
+#elif defined(EPD_TIMING_ED068OG1_NUMCE3) //][
+/* i.MX508 waveform data timing data structures for ed068og1_numce3 */
+/* Created on - Monday, October 15, 2012 10:36:24
+ Warning: this pixel clock is derived from 480 MHz parent! */
+
+static struct fb_videomode ed068og1_numce3_mode = {
+.name="ED068OG1_NUMCE3",
+.refresh=85,
+.xres=1440,
+.yres=1080,
+.pixclock=96000000,
+.left_margin=24,
+.right_margin=267,
+.upper_margin=4,
+.lower_margin=5,
+.hsync_len=24,
+.vsync_len=2,
+.sync=0,
+.vmode=FB_VMODE_NONINTERLACED,
+.flag=0,
+};
+#else
+static struct fb_videomode ed068og1_mode = {
+.name = "E68OG1",
+.refresh=85,
+.xres=1440,
+.yres=1080,
+.pixclock=120000000,
+.left_margin=32,
+.right_margin=508,
+.upper_margin=4,
+.lower_margin=5,
+.hsync_len=32,
+.vsync_len=2,
+.sync=0,
+.vmode=FB_VMODE_NONINTERLACED,
+.flag=0,
+};
+#endif//]EPD_TIMING_ED068OG1_NUMCE3
+
+static struct fb_videomode peng060d_mode = {
+.name = "PENG060D",
+.refresh=85,
+.xres=1448,
+.yres=1072,
+.pixclock=80000000,
+.left_margin=16,
+.right_margin=102,
+.upper_margin=4,
+.lower_margin=4,
+.hsync_len=28,
+.vsync_len=2,
+.sync=0,
+.vmode=FB_VMODE_NONINTERLACED,
+.flag=0,
+};
+
+static struct fb_videomode ef133ut1sce_mode = {
+.name="EF133UT1SCE",
+.refresh=65,
+.xres=1600,
+.yres=1200,
+.pixclock=72222223,
+.left_margin=8,
+.right_margin=97,
+.upper_margin=4,
+.lower_margin=7,
+.hsync_len=12,
+.vsync_len=1,
+.sync=0,
+.vmode=FB_VMODE_NONINTERLACED,
+.flag=0,
+};
+
+
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+////////////////////
+{
+& ed060sc8_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+465, /* gdclk_hp_offs */
+250, /* gdsp_offs changed delay to 8.3 uS */
+0, /* gdoe_offs */
+8, /* gdclk_offs changed delay to 4.5 SDCLK */
+1, /* num_ce */
+},
+
+////////////////////
+{
+& e60_v110_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+465, /* gdclk_hp_offs */
+250, /* gdsp_offs changed delay to 8.3 uS */
+0, /* gdoe_offs */
+8, /* gdclk_offs changed delay to 4.5 SDCLK */
+1, /* num_ce */
+},
+
+////////////////////
+{
+& ed060xc5_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+524, /* gdclk_hp_offs */
+25, /* gdsp_offs changed delay to 8.3 uS */
+0, /* gdoe_offs */
+19, /* gdclk_offs changed delay to 4.5 SDCLK */
+1, /* num_ce */
+},
+
+////////////////////
+{
+& ed060xc1_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+492, /* gdclk_hp_offs */
+29, /* gdsp_offs changed delay to 8.3 uS */
+0, /* gdoe_offs */
+23, /* gdclk_offs changed delay to 4.5 SDCLK */
+1, /* num_ce */
+},
+
+////////////////////
+{
+ &ed050xxx_mode, /* struct fb_videomode *mode */
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 420, /* GDCLK_HP */
+ 20, /* GDSP_OFF */
+ 0, /* GDOE_OFF */
+ 11, /* gdclk_offs */
+ 3, /* num_ce */
+},
+
+#ifdef EPD_TIMING_ED068TG1 //[
+{
+& ed068tg1_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+665, /* GDCLK_HP */
+718, /* GDSP_OFF */
+0, /* GDOE_OFF */
+199, /* gdclk_offs */
+1, /* num_ce */
+},
+#elif defined(EPD_TIMING_ED068OG1_NUMCE3)//][
+{
+& ed068og1_numce3_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+665, /* GDCLK_HP */
+210, /* GDSP_OFF */
+0, /* GDOE_OFF */
+199, /* gdclk_offs */
+3, /* num_ce */
+},
+#else//][ !EPD_TIMING_ED068OG1_NUMCE3
+{
+& ed068og1_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+831, /* GDCLK_HP */
+285, /* GDSP_OFF */
+0, /* GDOE_OFF */
+271, /* gdclk_offs */
+1, /* num_ce */
+},
+#endif//] EPD_TIMING_ED068OG1_NUMCE3
+
+{
+&peng060d_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+562, /* GDCLK_HP */
+664, /* GDSP_OFF */
+0, /* GDOE_OFF */
+227, /* gdclk_offs */
+3, /* num_ce */
+},
+{
+&ef133ut1sce_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+743, /* GDCLK_HP */
+475, /* GDSP_OFF */
+0, /* GDOE_OFF */
+15, /* gdclk_offs */
+1, /* num_ce */
+},
+{
+&ed060scq_mode,
+4, /* vscan_holdoff */
+10, /* sdoed_width */
+20, /* sdoed_delay */
+10, /* sdoez_width */
+20, /* sdoez_delay */
+438, /* GDCLK_HP */
+263, /* GDSP_OFF */
+0, /* GDOE_OFF */
+23, /* gdclk_offs */
+3, /* num_ce */
+},
+};
+
+
+#else //][!
+static struct fb_videomode e60_v110_mode = {
+ .name = "E60_V110",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 18604700,
+ .left_margin = 8,
+ .right_margin = 178,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e60_v220_mode = {
+ .name = "E60_V220",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 30000000,
+ .left_margin = 8,
+ .right_margin = 164,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+};
+static struct fb_videomode e060scm_mode = {
+ .name = "E060SCM",
+ .refresh = 85,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 26666667,
+ .left_margin = 8,
+ .right_margin = 100,
+ .upper_margin = 4,
+ .lower_margin = 8,
+ .hsync_len = 4,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+static struct fb_videomode e97_v110_mode = {
+ .name = "E97_V110",
+ .refresh = 50,
+ .xres = 1200,
+ .yres = 825,
+ .pixclock = 32000000,
+ .left_margin = 12,
+ .right_margin = 128,
+ .upper_margin = 4,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_epdc_fb_mode panel_modes[] = {
+ {
+ &e60_v110_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 428, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e60_v220_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 465, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 9, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e060scm_mode,
+ 4, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 419, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 5, /* gdclk_offs */
+ 1, /* num_ce */
+ },
+ {
+ &e97_v110_mode,
+ 8, /* vscan_holdoff */
+ 10, /* sdoed_width */
+ 20, /* sdoed_delay */
+ 10, /* sdoez_width */
+ 20, /* sdoez_delay */
+ 632, /* gdclk_hp_offs */
+ 20, /* gdsp_offs */
+ 0, /* gdoe_offs */
+ 1, /* gdclk_offs */
+ 3, /* num_ce */
+ }
+};
+#endif //]
+
+static struct imx_epdc_fb_platform_data epdc_data = {
+ .epdc_mode = panel_modes,
+ .num_modes = ARRAY_SIZE(panel_modes),
+ .get_pins = epdc_get_pins,
+ .put_pins = epdc_put_pins,
+ .enable_pins = epdc_enable_pins,
+ .disable_pins = epdc_disable_pins,
+};
+
+typedef void (*usb_insert_handler) (char inserted);
+usb_insert_handler mxc_misc_report_usb;
+
+static void mxc_register_usb_plug(void* pk_cb)
+{
+ pmic_event_callback_t usb_plug_event;
+
+// usb_plug_event.param = (void *)1;
+// usb_plug_event.func = (void *)pk_cb;
+// pmic_event_subscribe(EVENT_VBUSVI, usb_plug_event);
+ if (gIsCustomerUi)
+ mxc_misc_report_usb = pk_cb;
+ DBG_MSG("%s(),pk_cb=%p\n",__FUNCTION__,pk_cb);
+
+}
+
+
+extern int mxc_usb_plug_getstatus (void);
+
+
+#define SW_USBPLUG 0x0C
+static struct usbplug_event_platform_data usbplug_data = {
+ .usbevent.type = EV_SW,
+ .usbevent.code = SW_USBPLUG,
+ .register_usbplugevent = mxc_register_usb_plug,
+ .get_key_status = mxc_usb_plug_getstatus,
+};
+
+struct platform_device mxc_usb_plug_device = {
+ .name = "usb_plug",
+ .id = 0,
+ };
+
+
+
+static int spdc_get_pins(void)
+{
+ int ret = 0;
+
+ /* Claim GPIOs for SPDC pins - used during power up/down */
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_0, "SPDC_D0");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_1, "SPDC_D1");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_2, "SPDC_D2");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_3, "SPDC_D3");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_4, "SPDC_D4");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_5, "SPDC_D5");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_6, "SPDC_D6");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_7, "SPDC_D7");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDOE, "SIPIX_YOE");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_9, "SIPIX_PWR_RDY");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDSP, "SIPIX_YDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_GDCLK, "SIPIX_YCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDSHR, "SIPIX_XDIO");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDLE, "SIPIX_LD");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE1, "SIPIX_SOE");
+
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCLK, "SIPIX_XCLK");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDDO_10, "SIPIX_SHD_N");
+ ret |= gpio_request(MX6SL_BRD_EPDC_SDCE0, "SIPIX2_CE");
+
+ return ret;
+}
+
+static void spdc_put_pins(void)
+{
+ gpio_free(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_7);
+
+ gpio_free(MX6SL_BRD_EPDC_GDOE);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_free(MX6SL_BRD_EPDC_GDSP);
+ gpio_free(MX6SL_BRD_EPDC_GDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDSHR);
+ gpio_free(MX6SL_BRD_EPDC_SDLE);
+ gpio_free(MX6SL_BRD_EPDC_SDCE1);
+ gpio_free(MX6SL_BRD_EPDC_SDCLK);
+ gpio_free(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_free(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_enable_pins(void)
+{
+ /* Configure MUX settings to enable SPDC use */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_enable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_enable_pads));
+
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_0);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_2);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_3);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_4);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_5);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_6);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_7);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_8);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_11);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_12);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_13);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_14);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_15);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDOE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_9);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDSP);
+ gpio_direction_input(MX6SL_BRD_EPDC_GDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDSHR);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDLE);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE1);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCLK);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDDO_10);
+ gpio_direction_input(MX6SL_BRD_EPDC_SDCE0);
+}
+
+static void spdc_disable_pins(void)
+{
+ /* Configure MUX settings for SPDC pins to
+ * GPIO and drive to 0. */
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_spdc_disable_pads, \
+ ARRAY_SIZE(mx6sl_brd_spdc_disable_pads));
+
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_0, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_2, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_3, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_4, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_5, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_6, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_7, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_8 , 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9 , 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_11, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_12, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_13, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_14, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_15, 0);
+
+ gpio_direction_output(MX6SL_BRD_EPDC_GDOE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_9, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDSP, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_GDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDSHR, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDLE, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE1, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCLK, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDDO_10, 0);
+ gpio_direction_output(MX6SL_BRD_EPDC_SDCE0, 0);
+}
+
+static struct imx_spdc_panel_init_set spdc_init_set = {
+ .yoe_pol = false,
+ .dual_gate = false,
+ .resolution = 0,
+ .ud = false,
+ .rl = false,
+ .data_filter_n = true,
+ .power_ready = true,
+ .rgbw_mode_enable = false,
+ .hburst_len_en = true,
+};
+
+static struct fb_videomode erk_1_4_a01 = {
+ .name = "ERK_1_4_A01",
+ .refresh = 50,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 40000000,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static struct imx_spdc_fb_mode spdc_panel_modes[] = {
+ {
+ &erk_1_4_a01,
+ &spdc_init_set,
+ .wave_timing = "pvi"
+ },
+};
+
+static struct imx_spdc_fb_platform_data spdc_data = {
+ .spdc_mode = spdc_panel_modes,
+ .num_modes = ARRAY_SIZE(spdc_panel_modes),
+ .get_pins = spdc_get_pins,
+ .put_pins = spdc_put_pins,
+ .enable_pins = spdc_enable_pins,
+ .disable_pins = spdc_disable_pins,
+};
+
+static int __init early_use_spdc_sel(char *p)
+{
+ spdc_sel = 1;
+ return 0;
+}
+early_param("spdc", early_use_spdc_sel);
+
+static void setup_spdc(void)
+{
+ /* GPR0[8]: 0:EPDC, 1:SPDC */
+ if (spdc_sel)
+ mxc_iomux_set_gpr_register(0, 8, 1, 1);
+}
+
+static void imx6_ntx_usbotg_vbus(bool on)
+{
+#if 0
+ if (on)
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 1);
+ else
+ gpio_set_value(MX6_BRD_USBOTG1_PWR, 0);
+#endif
+}
+
+static void __init mx6_ntx_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
+#if 0
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0);
+
+ ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr");
+ if (ret) {
+ pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1);
+#endif
+
+ mx6_set_otghost_vbus_func(imx6_ntx_usbotg_vbus);
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+#endif
+}
+
+static struct platform_device mxcbl_device = {
+ .name = "mxc_msp430_fl",
+};
+
+static struct platform_pwm_backlight_data mx6_ntx_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+static struct fb_videomode wvga_video_modes[] = {
+ {
+ /* 800x480 @ 57 Hz , pixel clk @ 32MHz */
+ "SEIKO-WVGA", 60, 800, 480, 29850, 99, 164, 33, 10, 10, 10,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data wvga_fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "SEIKO-WVGA",
+ .mode = wvga_video_modes,
+ .num_modes = ARRAY_SIZE(wvga_video_modes),
+ .panel_type = "lcd",
+ },
+};
+
+static struct platform_device lcd_wvga_device = {
+ .name = "lcd_seiko",
+};
+
+#if 0
+static struct fb_videomode hdmi_video_modes[] = {
+ {
+ /* 1920x1080 @ 60 Hz , pixel clk @ 148MHz */
+ "sii9022x_1080p60", 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+ FB_SYNC_CLK_LAT_FALL,
+ FB_VMODE_NONINTERLACED,
+ 0,},
+};
+
+static struct mxc_fb_platform_data hdmi_fb_data[] = {
+ {
+ .interface_pix_fmt = V4L2_PIX_FMT_RGB24,
+ .mode_str = "1920x1080M@60",
+ .mode = hdmi_video_modes,
+ .num_modes = ARRAY_SIZE(hdmi_video_modes),
+ .panel_type = "hdmi",
+ },
+};
+#endif
+
+static int mx6sl_ntx_keymap[] = {
+ KEY(0, 0, 90),
+};
+
+static struct platform_device ntx_device_rtc = {
+ .name = "ntx_misc_rtc",
+ .id = 0,
+ .dev = {
+ .platform_data = -1,
+ }
+};
+
+static const struct matrix_keymap_data mx6sl_ntx_map_data __initconst = {
+ .keymap = mx6sl_ntx_keymap,
+ .keymap_size = ARRAY_SIZE(mx6sl_ntx_keymap),
+};
+#if 0
+static void __init elan_ts_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_elan_pads,
+ ARRAY_SIZE(mx6sl_brd_elan_pads));
+
+ /* ELAN Touchscreen */
+ gpio_request(MX6SL_BRD_ELAN_INT, "elan-interrupt");
+ gpio_direction_input(MX6SL_BRD_ELAN_INT);
+
+ gpio_request(MX6SL_BRD_ELAN_CE, "elan-cs");
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 0);
+
+ gpio_request(MX6SL_BRD_ELAN_RST, "elan-rst");
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 0);
+ mdelay(1);
+ gpio_direction_output(MX6SL_BRD_ELAN_RST, 1);
+ gpio_direction_output(MX6SL_BRD_ELAN_CE, 1);
+}
+#endif
+
+/*
+ *Usually UOK and DOK should have separate
+ *line to differentiate its behaviour (with different
+ * GPIO irq),because connect max8903 pin UOK to
+ *pin DOK from hardware design,cause software cannot
+ *process and distinguish two interrupt, so default
+ *enable dc_valid for ac charger
+ */
+static struct max8903_pdata charger1_data = {
+ .dok = MX6_BRD_CHG_DOK,
+ .uok = MX6_BRD_CHG_UOK,
+ .chg = MX6_BRD_CHG_STATUS,
+ .flt = MX6_BRD_CHG_FLT,
+ .dcm_always_high = true,
+ .dc_valid = true,
+ .usb_valid = false,
+ .feature_flag = 1,
+};
+
+static struct platform_device ntx_max8903_charger_1 = {
+ .name = "max8903-charger",
+ .dev = {
+ .platform_data = &charger1_data,
+ },
+};
+
+/*! Device Definition for csi v4l2 device */
+static struct platform_device csi_v4l2_devices = {
+ .name = "csi_v4l2",
+ .id = 0,
+};
+
+#define SNVS_LPCR 0x38
+static void mx6_snvs_poweroff(void)
+{
+ u32 value;
+ void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR);
+
+ value = readl(mx6_snvs_base + SNVS_LPCR);
+ /* set TOP and DP_EN bit */
+ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR);
+}
+
+#if 0
+static int uart2_enabled;
+static int __init uart2_setup(char * __unused)
+{
+ uart2_enabled = 1;
+ return 1;
+}
+__setup("bluetooth", uart2_setup);
+
+static void __init uart2_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_uart2_pads,
+ ARRAY_SIZE(mx6sl_uart2_pads));
+ imx6sl_add_imx_uart(1, &mx6sl_ntx_uart1_data);
+}
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake, debounce) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+ .debounce_interval = debounce, \
+}
+
+static struct gpio_keys_button gpio_key_matrix_FL[] = {
+ GPIO_BUTTON(GPIO_KB_ROW0, 90, 1, "front_light", 1,1), // Front light
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(4, 25), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+
+static struct gpio_keys_button gpio_key_HOME_FL[] = {
+ GPIO_BUTTON(GPIO_KB_COL1, 90, 1, "front_light", 1,1), // Front light
+ GPIO_BUTTON(GPIO_KB_COL0, KEY_HOME, 1, "home", 1,1), // home
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+static struct gpio_keys_button gpio_key_RETURN_HOME_MENU[] = {
+ GPIO_BUTTON(GPIO_KB_ROW0, KEY_HOME, 1, "home", 1,1), // home
+ GPIO_BUTTON(GPIO_KB_ROW1, KEY_MENU, 1, "menu", 1,1), // menu
+ GPIO_BUTTON(GPIO_KB_ROW2, KEY_ESC, 1, "return", 1,1), // return
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+
+static struct gpio_keys_button gpio_key_HOME[] = {
+ GPIO_BUTTON(GPIO_KB_COL0, 61, 1, "home", 1, 50), // home
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+
+static struct gpio_keys_button gpio_key_FL[] = {
+ GPIO_BUTTON(GPIO_KB_COL1, 90, 1, "front_light", 1, 10), // Front light
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+
+static struct gpio_keys_button gpio_key_None[] = {
+//#ifdef CONFIG_ANDROID //[
+ GPIO_BUTTON(IMX_GPIO_NR(5, 8), KEY_POWER, 1, "power", 1, 1),
+//#endif //]CONFIG_ANDROID
+};
+
+static struct gpio_keys_button *gptGPIO_HOME_KEY;
+
+static struct gpio_keys_platform_data ntx_gpio_key_data = {
+ .buttons = gpio_key_matrix_FL,
+ .nbuttons = ARRAY_SIZE(gpio_key_matrix_FL),
+};
+
+static struct platform_device ntx_gpio_key_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ntx_gpio_key_data,
+ }
+};
+
+#ifdef TOUCH_HOME_LED//[
+
+extern int ntx_get_homepad_enabled_status(void);
+
+static int giHomeLED_Delay_Ticks=100;
+static volatile int giCurHomeLED_state;
+static struct delayed_work homeled_pwrdwn_work,homepad_check_work;
+/*
+ * giHomePad_enable :
+ * 0 = disabled .
+ * 1 = enabled home pad/led action .
+ * 2 = enabled home pad/led action and send event to application layer .
+ */
+static int giHomePad_enable=2;
+
+
+static void _homeled_onoff_force(int iIsON)
+{
+ //int iOldHomeLED_state=giCurHomeLED_state;
+ int iIsHOMELED_gpio=1;
+
+ if( 0==gptHWCFG->m_val.bHOME_LED_PWM && \
+ ( 36!=gptHWCFG->m_val.bPCB && 40!=gptHWCFG->m_val.bPCB) )
+ {
+ // HOME_LED_PWM==NO && !=E60Q3X&&E60Q5X
+ return ;
+ }
+
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ printk("MSP430 ");
+ iIsHOMELED_gpio=0;
+ }
+ else {
+ printk("GPIO ");
+ }
+
+ if(iIsON) {
+ giCurHomeLED_state=1;
+ printk("HOME LED [ON]\n");
+ if(iIsHOMELED_gpio) {
+ gpio_direction_output (gMX6SL_HOME_LED, 0);
+ }
+ else {
+ }
+ }
+ else {
+ giCurHomeLED_state=0;
+ printk("HOME LED [OFF]\n");
+ if(iIsHOMELED_gpio) {
+ gpio_direction_output (gMX6SL_HOME_LED, 1);
+ }
+ else {
+ }
+ }
+}
+
+
+static ssize_t homepad_enable_write(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ int iParam;
+ extern void gpiokeys_enable_button(struct gpio_keys_button *button,int iIsEnable);
+
+ iParam = simple_strtol(buf,NULL,0);
+
+ if(iParam!=giHomePad_enable) {
+ switch (iParam) {
+ case 0:
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ //msp430_homeled_enable(0);
+ }
+ //gpiokeys_enable_button(gptGPIO_HOME_KEY,0);
+ _homeled_onoff_force(0);
+ msp430_homepad_enable(0);
+ giHomePad_enable = iParam;
+ break;
+ case 1:
+ case 2:
+ //gpiokeys_enable_button(gptGPIO_HOME_KEY,1);
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ //msp430_homeled_enable(1);
+ }
+ msp430_homepad_enable(2);
+ giHomePad_enable = iParam;
+ break;
+ default :
+ printk(KERN_ERR"invalid parameter !\n");
+ return -1;
+ }
+ }
+ else {
+
+ }
+
+ return strlen(buf);
+}
+static ssize_t homepad_enable_read(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ ssize_t szChk=0;
+ sprintf(buf,"%d\n",giHomePad_enable);
+ szChk = strlen(buf);
+ return szChk;
+}
+static DEVICE_ATTR(homepad_enable,0666,
+ homepad_enable_read,
+ homepad_enable_write);
+
+static ssize_t homeled_delayms_show(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ ssize_t szChk=0;
+ sprintf(buf,"%d\n",giHomeLED_Delay_Ticks*(1000/HZ));
+ szChk = strlen(buf);
+ return szChk;
+}
+static ssize_t homeled_delayms_store(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ int iDelayms;
+ ssize_t szChk;
+ iDelayms = simple_strtol(buf,NULL,0);
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ int iChk = msp430_set_homeled_delayms(iDelayms);
+ if(iChk>=0) {
+ giHomeLED_Delay_Ticks = msecs_to_jiffies(iChk);
+ szChk = strlen(buf);
+ }
+ else {
+ szChk = -1;
+ }
+ }
+ else if (36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM)
+ {
+ // HOME LED is controlled by SOC .
+ giHomeLED_Delay_Ticks = msecs_to_jiffies(iDelayms);
+ szChk = strlen(buf);
+ }
+ return szChk;
+}
+static DEVICE_ATTR(homeled_delayms,0666,
+ homeled_delayms_show,
+ homeled_delayms_store);
+
+static ssize_t homeled_delaylevel_show(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ ssize_t szChk=0;
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) {
+ sprintf(buf,"%d\n",msp430_get_homeled_pwm_delaylevel());
+ }
+ else {
+ sprintf(buf,"%d\n",msp430_get_homeled_gpio_delaylevel());
+ }
+ szChk = strlen(buf);
+ }
+ else {
+ }
+ return szChk;
+}
+static ssize_t homeled_delaylevel_store(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ int iDelayLevel;
+
+ iDelayLevel = simple_strtol(buf,NULL,0);
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) {
+ msp430_set_homeled_pwm_delaylevel(iDelayLevel);
+ }
+ else {
+ msp430_set_homeled_gpio_delaylevel(iDelayLevel);
+ }
+ return strlen(buf);
+ }
+ else {
+ return (ssize_t)(-1);
+ }
+}
+static DEVICE_ATTR(homeled_delaylevel,0666,
+ homeled_delaylevel_show,
+ homeled_delaylevel_store);
+
+
+static ssize_t homeled_type_show(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ char *pszHomeLedType;
+
+ msp430_homeled_type_get(&pszHomeLedType);
+ sprintf(buf,"%s\n",pszHomeLedType);
+
+ return strlen(buf);
+ }
+ else {
+ return 0;
+ }
+}
+
+static ssize_t homeled_type_store(struct device *dev,
+ struct device_attribute *attr,const char *buf,size_t count)
+{
+ ssize_t szChk = -1;
+
+ if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED is controlled by MSP430 .
+ if( msp430_homeled_type_set_by_name(buf) >=0 ) {
+ szChk = strlen(buf);
+ }
+ }
+ else {
+ printk(KERN_WARNING"Home led control type cannot changed on this hardware \n");
+ }
+
+ return szChk;
+}
+
+static DEVICE_ATTR(homeled_type,0666,
+ homeled_type_show,
+ homeled_type_store);
+
+
+static const struct attribute *sysfs_homepad_attrs[] = {
+ &dev_attr_homepad_enable.attr,
+ NULL
+};
+static const struct attribute *sysfs_homeled_msp430_attrs[] = {
+ &dev_attr_homeled_type.attr,
+ &dev_attr_homeled_delayms.attr,
+ &dev_attr_homeled_delaylevel.attr,
+ NULL
+};
+static const struct attribute *sysfs_homeled_socgpio_attrs[] = {
+ &dev_attr_homeled_delayms.attr,
+ NULL
+};
+
+
+
+static void _homeled_onoff(int iIsON)
+{
+ if(2==gptHWCFG->m_val.bUIStyle) {
+ if(gSleep_Mode_Suspend) {
+ // skip home led control when system want to enter fake hibernation .
+ _homeled_onoff_force(0);
+ return ;
+ }
+ }
+ _homeled_onoff_force(iIsON);
+}
+
+static void _homepad_work_func(struct work_struct *work)
+{
+ int iIsHomePressing,iHomeGPIOVal;
+
+ iHomeGPIOVal=gpio_get_value(gptGPIO_HOME_KEY->gpio);
+ iIsHomePressing = (iHomeGPIOVal?1:0)^gptGPIO_HOME_KEY->active_low;
+ //printk("%s(),\"%s\" gpio=%d,down=%d\n",__FUNCTION__,
+ // gptGPIO_HOME_KEY->desc,iHomeGPIOVal,iIsHomePressing);
+ if(iIsHomePressing) {
+ msp430_homepad_enable(2);
+ }
+}
+static void _homeled_work_func(struct work_struct *work)
+{
+
+ _homeled_onoff(0);
+
+}
+
+static int ntx_touch_home_key_hook(struct gpio_keys_button *I_gpio_btn_data,int state)
+{
+ int iRet = 0;
+ //printk("%s(%p,%d)\n",__FUNCTION__,I_gpio_btn_data,state);
+ /*if(0x03==gptHWCFG->m_val.bUIConfig) {
+ // RD/MP mode .
+ if(!state) {
+ printk("%s():current home led=%d\n",__FUNCTION__,giCurHomeLED_state);
+ _homeled_onoff(!giCurHomeLED_state);
+ }
+ }
+ else*/
+ {
+ if(state) {
+
+ if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM ) {
+ // E60Q3X or HOME LED is GPIO controlled by SOC .
+ cancel_delayed_work_sync(&homeled_pwrdwn_work);
+ cancel_delayed_work_sync(&homepad_check_work);
+ schedule_delayed_work(&homepad_check_work, giHomeLED_Delay_Ticks+400);
+ _homeled_onoff(1);
+ }
+ }
+ else {
+
+ if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM ) {
+ // E60Q3X or HOME LED is GPIO controlled by SOC .
+ cancel_delayed_work_sync(&homeled_pwrdwn_work);
+ schedule_delayed_work(&homeled_pwrdwn_work, giHomeLED_Delay_Ticks);
+ }
+ }
+
+ if(giHomePad_enable<=1) {
+ iRet = -1;
+ }
+ }
+ return iRet;
+}
+
+void homeled_onoff(int iIsON) {
+ _homeled_onoff_force(iIsON);
+}
+
+int ntx_get_homepad_enabled_status(void)
+{
+ return giHomePad_enable;
+}
+
+int ntx_get_homeled_delay_ms(void)
+{
+ return jiffies_to_msecs(giHomeLED_Delay_Ticks);
+}
+
+void ntx_create_homepad_sys_attrs(struct kobject *kobj)
+{
+ int iChk;
+ if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB || 0!=gptHWCFG->m_val.bHOME_LED_PWM) {
+ iChk = sysfs_create_files(kobj,sysfs_homepad_attrs);
+ if(iChk) {
+ pr_err("Can't create homepad attr sysfs !\n");
+ }
+ if(36==gptHWCFG->m_val.bPCB||2==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // E60Q3X or HOME LED PWM controlled by SOC .
+ iChk = sysfs_create_files(kobj,sysfs_homeled_socgpio_attrs);
+ if(iChk) {
+ pr_err("Can't create homepad soc gpio attr sysfs !\n");
+ }
+ }
+ else if(1==gptHWCFG->m_val.bHOME_LED_PWM) {
+ // HOME LED PWM is controlled by MSP430 .
+ iChk = sysfs_create_files(kobj,sysfs_homeled_msp430_attrs);
+ if(iChk) {
+ pr_err("Can't create homepad msp430 pwm attr sysfs !\n");
+ }
+ }
+ }
+}
+#else //][!TOUCH_HOME_LED
+static void _homeled_onoff(int iIsON) {}
+void homeled_onoff(int iIsON) {}
+#endif //]TOUCH_HOME_LED
+
+#endif
+
+
+
+void *g_wifi_sd_host;
+irq_handler_t g_cd_irq;
+
+void ntx_register_wifi_cd (irq_handler_t handler, void *data)
+{
+ printk ("[%s-%d] register g_cd_irq \n",__func__,__LINE__);
+ g_wifi_sd_host = data;
+ g_cd_irq = handler;
+}
+
+
+static DEFINE_MUTEX(ntx_wifi_power_mutex);
+static int gi_wifi_power_status = -1;
+
+int _ntx_get_wifi_power_status(void)
+{
+ int iWifiPowerStatus;
+
+ mutex_lock(&ntx_wifi_power_mutex);
+ iWifiPowerStatus = gi_wifi_power_status;
+ mutex_unlock(&ntx_wifi_power_mutex);
+
+ return iWifiPowerStatus;
+}
+
+int _ntx_wifi_power_ctrl (int isWifiEnable)
+{
+ int iHWID;
+ int iOldStatus;
+
+ mutex_lock(&ntx_wifi_power_mutex);
+ iOldStatus = gi_wifi_power_status;
+ printk("Wifi / BT power control %d\n", isWifiEnable);
+ if(isWifiEnable == 0){
+ gpio_direction_output (gMX6SL_WIFI_RST, 0);
+ gpio_direction_input (gMX6SL_WIFI_3V3); // turn off Wifi_3V3_on
+
+ msleep(10);
+// DO NOT switch pin functions to GPIO
+/*
+ // sdio port disable ...
+ if(33==gptHWCFG->m_val.bPCB) {
+ //E60Q2X .
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd3_gpio_pads));
+ gpio_request (MX6SL_SD3_CLK , "MX6SL_SD3_CLK" );
+ gpio_request (MX6SL_SD3_CMD , "MX6SL_SD3_CMD" );
+ gpio_request (MX6SL_SD3_DAT0, "MX6SL_SD3_DAT0");
+ gpio_request (MX6SL_SD3_DAT1, "MX6SL_SD3_DAT1");
+ gpio_request (MX6SL_SD3_DAT2, "MX6SL_SD3_DAT2");
+ gpio_request (MX6SL_SD3_DAT3, "MX6SL_SD3_DAT3");
+ gpio_direction_output (MX6SL_SD3_CLK , 0);
+ gpio_direction_output (MX6SL_SD3_CMD , 0);
+ gpio_direction_output (MX6SL_SD3_DAT0, 0);
+ gpio_direction_output (MX6SL_SD3_DAT1, 0);
+ gpio_direction_output (MX6SL_SD3_DAT2, 0);
+ gpio_direction_output (MX6SL_SD3_DAT3, 0);
+ }
+ else {
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd2_gpio_pads));
+ gpio_request (MX6SL_SD2_CLK , "MX6SL_SD2_CLK" );
+ gpio_request (MX6SL_SD2_CMD , "MX6SL_SD2_CMD" );
+ gpio_request (MX6SL_SD2_DAT0, "MX6SL_SD2_DAT0");
+ gpio_request (MX6SL_SD2_DAT1, "MX6SL_SD2_DAT1");
+ gpio_request (MX6SL_SD2_DAT2, "MX6SL_SD2_DAT2");
+ gpio_request (MX6SL_SD2_DAT3, "MX6SL_SD2_DAT3");
+ gpio_direction_input (MX6SL_SD2_CLK );
+ gpio_direction_input (MX6SL_SD2_CMD );
+ gpio_direction_input (MX6SL_SD2_DAT0);
+ gpio_direction_input (MX6SL_SD2_DAT1);
+ gpio_direction_input (MX6SL_SD2_DAT2);
+ gpio_direction_input (MX6SL_SD2_DAT3);
+ }
+*/
+
+#ifdef _WIFI_ALWAYS_ON_
+ disable_irq_wake(gpio_to_irq(gMX6SL_WIFI_INT));
+#endif
+ gi_wifi_power_status=0;
+ }
+ else {
+
+
+ // sdio port process ...
+ if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) {
+ // E60Q0X/E60Q1X
+ gpio_free (MX6SL_SD2_CLK );
+ gpio_free (MX6SL_SD2_CMD );
+ gpio_free (MX6SL_SD2_DAT0);
+ gpio_free (MX6SL_SD2_DAT1);
+ gpio_free (MX6SL_SD2_DAT2);
+ gpio_free (MX6SL_SD2_DAT3);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_wifi_pads, ARRAY_SIZE(mx6sl_ntx_sd2_wifi_pads));
+ }
+ else {
+ gpio_free (MX6SL_SD3_CLK );
+ gpio_free (MX6SL_SD3_CMD );
+ gpio_free (MX6SL_SD3_DAT0);
+ gpio_free (MX6SL_SD3_DAT1);
+ gpio_free (MX6SL_SD3_DAT2);
+ gpio_free (MX6SL_SD3_DAT3);
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_wifi_pads, ARRAY_SIZE(mx6sl_ntx_sd3_wifi_pads));
+ }
+ //msleep(10);
+
+ gpio_direction_output (gMX6SL_WIFI_3V3, 0); // turn on Wifi_3V3_on
+ //schedule_timeout(HZ/50);
+ msleep(10);
+
+ gpio_direction_input (gMX6SL_WIFI_INT);
+ //msleep(10);
+ gpio_direction_output (gMX6SL_WIFI_RST, 1); // turn on wifi_RST
+ //schedule_timeout(HZ/10);
+ msleep(30);
+#ifdef _WIFI_ALWAYS_ON_
+ enable_irq_wake(gpio_to_irq(gMX6SL_WIFI_INT));
+#endif
+ gi_wifi_power_status=1;
+ }
+
+ if (g_cd_irq) {
+ struct sdhci_host *host;
+
+ host = (struct sdhci_host *) g_wifi_sd_host;
+ //g_cd_irq (0, g_wifi_sd_host);
+ //schedule_timeout (100);
+ //msleep(1000);
+ mmc_detect_change(host->mmc, msecs_to_jiffies(500));
+ //msleep(600);
+ schedule_timeout(500);
+ }
+ else {
+ printk ("[%s-%d] not registered.\n",__func__,__LINE__);
+ }
+
+ if(isWifiEnable == 0){ // switch PIN function to GPIO
+ // sdio port disable ...
+ if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) {
+ // E60Q0X/E60Q1X.
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd2_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd2_gpio_pads));
+ gpio_request (MX6SL_SD2_CLK , "MX6SL_SD2_CLK" );
+ gpio_request (MX6SL_SD2_CMD , "MX6SL_SD2_CMD" );
+ gpio_request (MX6SL_SD2_DAT0, "MX6SL_SD2_DAT0");
+ gpio_request (MX6SL_SD2_DAT1, "MX6SL_SD2_DAT1");
+ gpio_request (MX6SL_SD2_DAT2, "MX6SL_SD2_DAT2");
+ gpio_request (MX6SL_SD2_DAT3, "MX6SL_SD2_DAT3");
+ gpio_direction_input (MX6SL_SD2_CLK );
+ gpio_direction_input (MX6SL_SD2_CMD );
+ gpio_direction_input (MX6SL_SD2_DAT0);
+ gpio_direction_input (MX6SL_SD2_DAT1);
+ gpio_direction_input (MX6SL_SD2_DAT2);
+ gpio_direction_input (MX6SL_SD2_DAT3);
+ }
+ else {
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_sd3_gpio_pads, ARRAY_SIZE(mx6sl_ntx_sd3_gpio_pads));
+ gpio_request (MX6SL_SD3_CLK , "MX6SL_SD3_CLK" );
+ gpio_request (MX6SL_SD3_CMD , "MX6SL_SD3_CMD" );
+ gpio_request (MX6SL_SD3_DAT0, "MX6SL_SD3_DAT0");
+ gpio_request (MX6SL_SD3_DAT1, "MX6SL_SD3_DAT1");
+ gpio_request (MX6SL_SD3_DAT2, "MX6SL_SD3_DAT2");
+ gpio_request (MX6SL_SD3_DAT3, "MX6SL_SD3_DAT3");
+ gpio_direction_output (MX6SL_SD3_CLK , 0);
+ gpio_direction_output (MX6SL_SD3_CMD , 0);
+ gpio_direction_output (MX6SL_SD3_DAT0, 0);
+ gpio_direction_output (MX6SL_SD3_DAT1, 0);
+ gpio_direction_output (MX6SL_SD3_DAT2, 0);
+ gpio_direction_output (MX6SL_SD3_DAT3, 0);
+ }
+ }
+ printk("%s() end.\n",__FUNCTION__);
+ mutex_unlock(&ntx_wifi_power_mutex);
+ return iOldStatus;
+}
+
+void ntx_wifi_power_ctrl(int iIsWifiEnable)
+{
+ _ntx_wifi_power_ctrl(iIsWifiEnable);
+}
+
+EXPORT_SYMBOL(ntx_wifi_power_ctrl);
+
+static iomux_v3_cfg_t mx6sl_ntx_suspend_pads[] = {
+ MX6SL_PAD_I2C2_SCL__GPIO_3_14,
+ MX6SL_PAD_I2C2_SDA__GPIO_3_15,
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_resume_pads[] = {
+ MX6SL_PAD_I2C2_SCL__I2C2_SCL,
+ MX6SL_PAD_I2C2_SDA__I2C2_SDA,
+};
+
+extern void ntx_gpio_suspend (void);
+extern void ntx_gpio_resume (void);
+
+static void ntx_suspend_enter(void)
+{
+// mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_suspend_pads, ARRAY_SIZE(mx6sl_ntx_suspend_pads));
+// gpio_request(MX6SL_I2C2_SCL, "MX6SL_I2C2_SCL");
+// gpio_request(MX6SL_I2C2_SDA, "MX6SL_I2C2_SDA");
+// gpio_direction_output (MX6SL_I2C2_SCL, 0);
+// gpio_direction_output (MX6SL_I2C2_SDA, 0);
+
+#if 0
+ gpio_direction_output (MX6SL_EP_PWRALL, 1);
+ gpio_direction_output (MX6SL_EP_WAKEUP, 0);
+ gpio_direction_output (MX6SL_EP_PWRUP, 0);
+ gpio_direction_output (MX6SL_EP_VCOM, 0);
+ gpio_direction_input (MX6SL_EP_INT);
+ gpio_direction_input (MX6SL_EP_PWRSTAT);
+#endif
+
+ _homeled_onoff_force(0);
+
+ ntx_gpio_suspend ();
+
+#if 0
+ {
+ unsigned int *pIomux = IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR)+0x4C;
+ unsigned int value;
+
+ printk ("Addr , value\n");
+ while (IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR)+0x5A8 >= pIomux) {
+ value = *pIomux;
+ printk ("0x%08X, 0x%08X, %s%s%s\n",pIomux, value,((value&0x2000)?"PUE - ":""),\
+ ((value&0x2000)?((value&0xC000)?"Pull Up - ":"Pull Down - "):""),((value&0x1000)?"PKE":""));
+ ++pIomux;
+ }
+ }
+#endif
+#if 0
+{
+ void __iomem *base = IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR);
+ unsigned int offset = 0x4C;
+ unsigned int addr = 0x20E0000;
+ unsigned int value;
+
+ for(offset=0x4C; offset <=0x884; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+
+ base = IO_ADDRESS(GPIO1_BASE_ADDR);
+ addr = 0x209C000;
+ for(offset=0; offset<=0x1C; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+
+ base = IO_ADDRESS(GPIO2_BASE_ADDR);
+ addr = 0x20A0000;
+ for(offset=0; offset<=0x1C; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+
+ base = IO_ADDRESS(GPIO3_BASE_ADDR);
+ addr = 0x20A4000;
+ for(offset=0; offset<=0x1C; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+
+ base = IO_ADDRESS(GPIO4_BASE_ADDR);
+ addr = 0x20A8000;
+ for(offset=0; offset<=0x1C; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+
+ base = IO_ADDRESS(GPIO5_BASE_ADDR);
+ addr = 0x20AC000;
+ for(offset=0; offset<=0x1C; offset+=4) {
+ value = __raw_readl( base + offset);
+ printk(KERN_DEBUG "addr %08x = %08x\n", addr+offset, value);
+ }
+}
+#endif
+}
+
+static void ntx_suspend_exit(void)
+{
+#if 0
+ gpio_direction_output (MX6SL_EP_WAKEUP, 1);
+#endif
+
+// gpio_free(MX6SL_I2C2_SCL);
+// gpio_free(MX6SL_I2C2_SDA);
+// mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_resume_pads, ARRAY_SIZE(mx6sl_ntx_resume_pads));
+ ntx_gpio_resume ();
+
+}
+
+static const struct pm_platform_data mx6sl_ntx_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = ntx_suspend_enter,
+ .suspend_exit = ntx_suspend_exit,
+};
+
+void ntx_wacom_reset(bool on) {
+ gpio_direction_output (MX6SL_WACOM_RST, on);
+}
+static void ntx_gpio_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_pads));
+
+
+
+ if(31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB) {
+ // E60Q0X|E60Q1X.
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd4_gpio_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_sd4_gpio_pads));
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd1_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_sd1_pads));
+#if 1
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_q12_wifictrl_pads,
+ ARRAY_SIZE(mx6sl_ntx_q12_wifictrl_pads));
+#endif
+ giISD_3V3_ON_Ctrl=-1;
+ }
+ else {
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd4_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads));
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_sd1_gpio_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_sd1_gpio_pads));
+
+#if 1
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_ntx_q22_wifictrl_pads,
+ ARRAY_SIZE(mx6sl_ntx_q22_wifictrl_pads));
+#endif
+ if(1==gptHWCFG->m_val.bLed) {
+ // RGB/G type LED .
+ // ON_LED#
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH);
+ }
+
+ gMX6SL_NTX_ACIN_PG = IMX_GPIO_NR(5, 14);
+ gMX6SL_NTX_CHG = IMX_GPIO_NR(5, 15);
+ gMX6SL_MSP_INT = IMX_GPIO_NR(5, 11);
+ gMX6SL_PWR_SW = IMX_GPIO_NR(5, 8);
+ gMX6SL_IR_TOUCH_INT = IMX_GPIO_NR(5, 6);
+ gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 9);
+ if(49==gptHWCFG->m_val.bPCB) {
+ // E60QDX
+ gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 13);
+ }
+
+ gMX6SL_HALL_EN = IMX_GPIO_NR(5, 12);
+
+ // LED assign ...
+ gMX6SL_CHG_LED = IMX_GPIO_NR(5, 10);
+ if(37==gptHWCFG->m_val.bPCB) {
+ // E60QB0 .
+ gMX6SL_ACT_LED = IMX_GPIO_NR(5, 13);
+ gMX6SL_ON_LED = IMX_GPIO_NR(5, 7);
+ }
+ else if(46==gptHWCFG->m_val.bPCB||48==gptHWCFG->m_val.bPCB) {
+ // E60Q9X/E60QAX .
+
+ // ON_LED# pull high .
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH);
+
+ gMX6SL_ACT_LED = IMX_GPIO_NR(5, 7);
+ gMX6SL_ON_LED = IMX_GPIO_NR(5, 13);
+ }
+ else if(42==gptHWCFG->m_val.bPCB){
+ // E60Q6X
+ gMX6SL_ACT_LED = IMX_GPIO_NR(5, 13);
+ gMX6SL_ON_LED = IMX_GPIO_NR(5, 13);
+ }
+ else {
+ gMX6SL_ACT_LED = IMX_GPIO_NR(5, 7);
+ gMX6SL_ON_LED = IMX_GPIO_NR(5, 7);
+ }
+
+ gMX6SL_WIFI_3V3 = IMX_GPIO_NR(4, 29);
+ gMX6SL_WIFI_RST = IMX_GPIO_NR(5, 0);
+ gMX6SL_WIFI_INT = IMX_GPIO_NR(4, 31);
+
+ if(37==gptHWCFG->m_val.bPCB) {
+ // E60QBX.
+ gpio_request (GPIO_ESD_3V3_ON, "ESD_3V3_ON");
+ gpio_direction_input (GPIO_ESD_3V3_ON);
+ gpio_free (GPIO_ESD_3V3_ON);
+ giISD_3V3_ON_Ctrl = -1;
+ }
+ else {
+ if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB) {
+ // E60Q3X/E60Q5X
+ gMX6SL_CHG_LED = IMX_GPIO_NR(5, 7);
+ gMX6SL_IR_TOUCH_RST = IMX_GPIO_NR(5, 13);
+ gpio_request (MX6SL_KL25_INT2, "MX6SL_KL25_INT2");
+ gpio_direction_input (MX6SL_KL25_INT2);
+ }
+ else {
+ if(0==gptHWCFG->m_val.bPMIC) {
+ //若有RICOH PMIC則ESD_3V3_ON都會交由PMIC控制.
+ gpio_request (GPIO_ESD_3V3_ON, "ESD_3V3_ON");
+ gpio_direction_output (GPIO_ESD_3V3_ON, 1);
+ }
+ }
+
+ if(0==gptHWCFG->m_val.bPMIC) {
+ gpio_request (GPIO_ISD_3V3_ON, "ISD_3V3_ON");
+ if(33==gptHWCFG->m_val.bPCB) {
+ // E60Q2X .
+ giISD_3V3_ON_Ctrl = 0;
+ }
+ else {
+ giISD_3V3_ON_Ctrl = 1;
+ }
+ }
+ }
+
+
+ gpio_request (GPIO_IR_3V3_ON, "IR_3V3_ON");
+ gpio_direction_output (GPIO_IR_3V3_ON, 1);
+ //gpio_request (GPIO_EP_3V3_ON, "EP_3V3_ON");
+ //gpio_direction_output (GPIO_EP_3V3_ON, 1);
+
+ if(2==gptHWCFG->m_val.bTouch2Ctrl) {
+ // Wacom Digitizer
+ gpio_request (MX6SL_WACOM_PDCT, "MX6SL_WACOM_PDCT");
+ gpio_direction_input (MX6SL_WACOM_PDCT);
+ gpio_request (MX6SL_WACOM_FWE, "MX6SL_WACOM_FWE");
+ gpio_direction_output (MX6SL_WACOM_FWE, 0);
+ gpio_request (MX6SL_WACOM_RST, "MX6SL_WACOM_RST");
+ ntx_wacom_reset(0);
+
+ if(42==gptHWCFG->m_val.bPCB) {
+ // Wacom GPIOs
+ gpio_request (MX6SL_WACOM_INT, "MX6SL_WACOM_INT");
+ gpio_direction_input (MX6SL_WACOM_INT);
+ i2c_register_board_info(1,&i2c_wacom_binfo,1);
+ }
+ else {
+ gpio_request (MX6SL_WACOM_INT_4_1, "MX6SL_WACOM_INT");
+ gpio_direction_input (MX6SL_WACOM_INT_4_1);
+ i2c_register_board_info(0,&i2c_wacom_binfo,1);
+ }
+ }
+ else if(3==gptHWCFG->m_val.bTouch2Ctrl) {
+ if(42==gptHWCFG->m_val.bPCB) {
+ gpio_request (MX6SL_WALTOP_INT_4_0, "MX6SL_WALTOP_INT_4_0");
+ gpio_direction_input (MX6SL_WALTOP_INT_4_0);
+ gpio_request (MX6SL_WALTOP_RST_3_30, "MX6SL_WALTOP_RST_3_30");
+ gpio_direction_output (MX6SL_WALTOP_RST_3_30, 1);
+
+ i2c_waltop_binfo.platform_data = MX6SL_WALTOP_RST_3_30;
+ i2c_waltop_binfo.irq = gpio_to_irq(MX6SL_WALTOP_INT_4_0);
+ i2c_register_board_info(1,&i2c_waltop_binfo,1);
+ } else {
+ gpio_request (MX6SL_WALTOP_INT, "MX6SL_WALTOP_INT");
+ gpio_direction_input (MX6SL_WALTOP_INT);
+ gpio_request (MX6SL_WALTOP_RST, "MX6SL_WALTOP_RST");
+ gpio_direction_output (MX6SL_WALTOP_RST, 1);
+ i2c_register_board_info(0,&i2c_waltop_binfo,1);
+ }
+ }
+ }
+
+ if(-1!=giISD_3V3_ON_Ctrl) {
+ gpio_direction_output (GPIO_ISD_3V3_ON, giISD_3V3_ON_Ctrl?1:0);
+ }
+
+ i2c_zforce_ir_touch_binfo.platform_data = gMX6SL_IR_TOUCH_INT;
+ i2c_zforce_ir_touch_binfo.irq = gpio_to_irq(gMX6SL_IR_TOUCH_INT);
+
+ i2c_elan_touch_binfo.platform_data = gMX6SL_IR_TOUCH_INT;
+ i2c_elan_touch_binfo.irq = gpio_to_irq(gMX6SL_IR_TOUCH_INT);
+ if(47==gptHWCFG->m_val.bPCB) { //ED0Q02
+ i2c_elan_touch_binfo.addr = 0x10;
+ }
+
+ i2c_sysmp_msp430_binfo.irq = gpio_to_irq(gMX6SL_MSP_INT);
+ i2c_sysmp_ricoh619_binfo.irq = gpio_to_irq(gMX6SL_MSP_INT);
+
+ ntx_misc_info.acin_gpio = gMX6SL_NTX_ACIN_PG;
+ ntx_misc_info.chg_gpio = gMX6SL_NTX_CHG;
+
+ if(37!=gptHWCFG->m_val.bPCB) {
+ gpio_request (MX6SL_HW_ID0, "MX6SL_HW_ID0");
+ gpio_request (MX6SL_HW_ID1, "MX6SL_HW_ID1");
+ gpio_request (MX6SL_HW_ID2, "MX6SL_HW_ID2");
+ gpio_request (MX6SL_HW_ID3, "MX6SL_HW_ID3");
+ gpio_request (MX6SL_HW_ID4, "MX6SL_HW_ID4");
+ gpio_direction_input (MX6SL_HW_ID0);
+ gpio_direction_input (MX6SL_HW_ID1);
+ gpio_direction_input (MX6SL_HW_ID2);
+ gpio_direction_input (MX6SL_HW_ID3);
+ gpio_direction_input (MX6SL_HW_ID4);
+ }
+
+ gpio_request (gMX6SL_ON_LED, "MX6SL_ON_LED");
+ gpio_request (gMX6SL_ACT_LED, "MX6SL_ACT_LED");
+ gpio_direction_input (gMX6SL_ACT_LED);
+ gpio_direction_output (gMX6SL_ON_LED, 0);
+
+ if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB) {
+ // E60Q3X/E60Q5X
+ gpio_request (gMX6SL_HOME_LED, "MX6SL_HOME_LED");
+ }
+ else {
+ gpio_request (gMX6SL_CHG_LED, "MX6SL_CHG_LED");
+ gpio_direction_input (gMX6SL_CHG_LED);
+ }
+
+ gpio_request (gMX6SL_NTX_ACIN_PG, "MX6SL_NTX_ACIN_PG");
+ gpio_direction_input (gMX6SL_NTX_ACIN_PG);
+
+ gpio_request (gMX6SL_NTX_CHG, "MX6SL_NTX_CHG");
+ gpio_direction_input (gMX6SL_NTX_CHG);
+
+ gpio_request (gMX6SL_MSP_INT, "MX6SL_MSP_INT");
+ gpio_direction_input (gMX6SL_MSP_INT);
+ //#ifndef CONFIG_ANDROID //[
+ if(0==gptHWCFG->m_val.bUIStyle) {
+ gpio_request (gMX6SL_PWR_SW, "MX6SL_PWR_SW");
+ gpio_direction_input (gMX6SL_PWR_SW);
+ }
+ //#endif //]CONFIG_ANDROID
+
+ gpio_request (gMX6SL_IR_TOUCH_INT, "MX6SL_IR_TOUCH_INT");
+ gpio_direction_input (gMX6SL_IR_TOUCH_INT);
+
+ gpio_request (gMX6SL_IR_TOUCH_RST, "MX6SL_IR_TOUCH_RST");
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 0);
+ mdelay (10);
+ gpio_direction_input (gMX6SL_IR_TOUCH_RST);
+ if(0==gptHWCFG->m_val.bHallSensor) {
+ gpio_request (gMX6SL_HALL_EN, "MX6SL_HALL_EN");
+ gpio_direction_input (gMX6SL_HALL_EN);
+ }
+
+ gpio_request (gMX6SL_WIFI_RST, "MX6SL_WIFI_RST");
+ gpio_request (gMX6SL_WIFI_3V3, "MX6SL_WIFI_3V3");
+ gpio_request (gMX6SL_WIFI_INT, "MX6SL_WIFI_INT");
+ gpio_direction_input (gMX6SL_WIFI_INT);
+ ntx_wifi_power_ctrl (0);
+
+ gpio_request (MX6SL_FL_EN, "MX6SL_FL_EN");
+ gpio_direction_input (MX6SL_FL_EN);
+ gpio_request (MX6SL_FL_R_EN, "MX6SL_FL_R_EN");
+ gpio_direction_input (MX6SL_FL_R_EN);
+
+#if 0 //[
+ gpio_request (MX6SL_EP_PWRALL, "MX6SL_EP_PWRALL" );
+ gpio_request (MX6SL_EP_WAKEUP , "MX6SL_EP_WAKEUP" );
+ gpio_request (MX6SL_EP_PWRUP , "MX6SL_EP_PWRUP" );
+ gpio_request (MX6SL_EP_INT , "MX6SL_EP_INT" );
+ gpio_request (MX6SL_EP_PWRSTAT , "MX6SL_EP_PWRSTAT" );
+ gpio_request (MX6SL_EP_VCOM , "MX6SL_EP_VCOM" );
+ gpio_direction_output (MX6SL_EP_PWRALL, 1);
+ gpio_direction_output (MX6SL_EP_WAKEUP, 0);
+ gpio_direction_output (MX6SL_EP_PWRUP, 0);
+ gpio_direction_output (MX6SL_EP_VCOM, 0);
+ gpio_direction_input (MX6SL_EP_INT);
+ gpio_direction_input (MX6SL_EP_PWRSTAT);
+#endif //]
+
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_ntx_init(void)
+{
+ u32 i;
+ int iMSP430_I2C_Chn;
+ struct esdhc_platform_data *pt_esdhc_ntx_isd_data;
+
+ _parse_cmdline();
+
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_pads,
+ ARRAY_SIZE(mx6sl_brd_pads));
+
+ ntx_gpio_init ();
+
+ gpiofn_init();
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+ gp_reg_id = mx6sl_ntx_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_ntx_dvfscore_data.soc_id;
+#else
+ gp_reg_id = mx6sl_ntx_dvfscore_data.reg_id;
+ soc_reg_id = mx6sl_ntx_dvfscore_data.soc_id;
+ pu_reg_id = mx6sl_ntx_dvfscore_data.pu_id;
+ mx6_cpu_regulator_init();
+#endif
+
+ if( (46==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_REV>=0x10) ||
+ 48==gptHWCFG->m_val.bPCB)
+ {
+ // E60Q9X rev >=A10 ...
+ // E60QAX ...
+ // MSP430 @ I2C1
+ iMSP430_I2C_Chn = 0;//I2C1
+ }
+ else {
+ iMSP430_I2C_Chn = 2;//I2C3 in curcuit .
+ if(0==gptHWCFG->m_val.bPMIC) {
+ // 當MSP430å–代為PMIC工作時,它éžå¸¸å¿™éŒ„,高速的頻率有å¯èƒ½æœƒä½¿å®ƒå‡ºéŒ¯ã€‚
+ mx6_ntx_i2c2_data.bitrate = 100000;
+ }
+ }
+// imx6q_add_imx_snvs_rtc();
+
+
+ imx6q_add_imx_i2c(0, &mx6_ntx_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_ntx_i2c1_data);
+ imx6q_add_imx_i2c(2, &mx6_ntx_i2c2_data);
+
+ if (4==gptHWCFG->m_val.bTouchType) {
+ // IR touch type
+ if ( 31==gptHWCFG->m_val.bPCB||32==gptHWCFG->m_val.bPCB||
+ 33==gptHWCFG->m_val.bPCB||36==gptHWCFG->m_val.bPCB||
+ 40==gptHWCFG->m_val.bPCB||
+ (46==gptHWCFG->m_val.bPCB&&gptHWCFG->m_val.bPCB_REV<0x10) )
+ {
+ // E60Q2X/E60Q3X/E60Q1X/E60Q2X/E60Q5X/<E60Q9XA10
+ i2c_register_board_info(0,&i2c_zforce_ir_touch_binfo,1);
+ }
+ else {
+ //
+ i2c_register_board_info(1,&i2c_zforce_ir_touch_binfo,1);
+ }
+ }
+ else if (3==gptHWCFG->m_val.bTouchType) {
+ // C touch type .
+ i2c_register_board_info(0,&i2c_elan_touch_binfo,1);
+ }
+ else {
+ printk("TouchType %d do not support yet ! no touch driver will be loaded \n",(int) gptHWCFG->m_val.bTouchType);
+ }
+
+ if(1==gptHWCFG->m_val.bPMIC){
+ // RC5T619 .
+ if(!NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,4)) {
+ // Panel is designed for low voltage .
+ printk("ldo8_1v8 ouput 3v3\n");
+ pdata_ldo8_0.regulator.constraints.min_uV = 3300*1000;
+ pdata_ldo8_0.regulator.constraints.max_uV = 3300*1000;
+ //pdata_ldo8_0.regulator.constraints.always_on = 1;
+ //pdata_ldo8_0.regulator.constraints.boot_on = 1;
+ pdata_ldo8_0.init_uV = 3300*1000;
+ //pdata_ldo8_0.init_enable = 1;
+ pdata_ldo8_0.sleep_uV = 3300*1000;
+ }
+
+ // PCB is designed for low voltage .
+ ntx_ricoh_data.irq_base = irq_alloc_descs (-1, 0, RICOH61x_NR_IRQS, "RICOH61x");
+ if (0 < ntx_ricoh_data.irq_base) {
+ ricoh_battery_data.irq = ntx_ricoh_data.irq_base;
+ ricoh_rtc_data.irq = ntx_ricoh_data.irq_base;
+ printk ("[%s-%d] irq_alloc_descs return %d for %d RICOH61x\n",__func__, __LINE__, ntx_ricoh_data.irq_base, RICOH61x_NR_IRQS);
+ }
+ else {
+ printk ("[%s-%d] RICOH61x irq_alloc_descs failed with %d\n",__func__, __LINE__, ntx_ricoh_data.irq_base, RICOH61x_NR_IRQS);
+ }
+ i2c_register_board_info(2,&i2c_sysmp_ricoh619_binfo,1);
+ // platform_device_register(&ricoh_device_rtc);
+ pm_power_off = ricoh619_power_off;
+ }
+
+
+ if(38!=gptHWCFG->m_val.bPCB&&37!=gptHWCFG->m_val.bPCB)
+ {
+ i2c_register_board_info(iMSP430_I2C_Chn,&i2c_sysmp_msp430_binfo,1);
+ }
+
+ if(0==gptHWCFG->m_val.bRTC) {
+ // RTC use MSP430
+ platform_device_register(&ntx_device_rtc);
+ }
+
+ if(1==gptHWCFG->m_val.bFL_PWM){
+ // Front light PWM source is ht68f20
+ i2c_register_board_info(0,&i2c_ht68f20_binfo,1);
+ }
+
+ if(3==gptHWCFG->m_val.bRSensor) {
+ // g-sensor with microP KL25
+ i2c_register_board_info(0,&i2c_kl25_binfo,1);
+ }
+
+
+ if(4==gptHWCFG->m_val.bRSensor) {
+ // g-sensor : MMA8652
+ //if(36!=gptHWCFG->m_val.bPCB)
+ {
+ /* 20140220 temporarily remove MMA8652 from E60Q32 to save power
+ since not currently used but installed (MMA8652 default mode: Standby) */
+ i2c_register_board_info(0,&i2c_mma8652_binfo,1);
+ }
+ }
+
+ //i2c_register_board_info(0, mxc_i2c0_board_info,
+ // ARRAY_SIZE(mxc_i2c0_board_info));
+ //i2c_register_board_info(1, mxc_i2c1_board_info,
+ // ARRAY_SIZE(mxc_i2c1_board_info));
+ //i2c_register_board_info(2, mxc_i2c2_board_info,
+ // ARRAY_SIZE(mxc_i2c2_board_info));
+
+ /* only camera on I2C2, that's why we can do so */
+// if (csi_enabled == 1) {
+// mxc_register_device(&csi_v4l2_devices, NULL);
+// imx6q_add_imx_i2c(2, &mx6_ntx_i2c2_data);
+// }
+// imx6q_add_imx_snvs_rtc();
+
+ /* SPI */
+// imx6q_add_ecspi(0, &mx6_ntx_spi_data);
+// spi_device_init();
+
+// mx6sl_ntx_init_pfuze100(0);
+ imx6q_add_anatop_thermal_imx(1, &mx6sl_anatop_thermal_data);
+ imx6q_add_pm_imx(0, &mx6sl_ntx_pm_data);
+
+ mx6_ntx_init_uart();
+ /* get enet tx reference clk from FEC_REF_CLK pad.
+ * GPR1[14] = 0, GPR1[18:17] = 00
+ */
+// mxc_iomux_set_gpr_register(1, 14, 1, 0);
+// mxc_iomux_set_gpr_register(1, 17, 2, 0);
+
+// imx6_init_fec(fec_data);
+
+ //platform_device_register(&ntx_vmmc_reg_devices);
+
+ if(2==gptHWCFG->m_val.bIFlash) {
+ // eMMC .
+ pt_esdhc_ntx_isd_data = &mx6_ntx_isd8bits_data;
+ }
+ else {
+ pt_esdhc_ntx_isd_data = &mx6_ntx_isd_data;
+ }
+
+ switch(gptHWCFG->m_val.bPCB) {
+ case 31: //E60Q0X .
+ case 32: //E60Q1X .
+ // SD1 = ISD
+ // SD2 = ESD
+ // SD3 = SDIO WIFI
+ // SD4 = GPIO
+ imx6q_add_sdhci_usdhc_imx(giBootPort, pt_esdhc_ntx_isd_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_esd_data); // mmcblk1
+ imx6q_add_sdhci_usdhc_imx(1, &mx6_ntx_sd_wifi_data);
+ break;
+
+ default:
+ // \C5\FD\B7s\AA\BA\B3]\ADp\BA\FB\AB\F9\A6b\B3o\ADӰ϶\F4\A1A\A5H\BAɥi\AF\E0\B9F\A8줣\ADק\EFCODE\B4N\AF\E0\A5Ψ\EC\B7s\BE\F7\BAؤW\A1C
+ // SD1 = GPIO
+ // SD2 = ESD
+ // SD3 = SDIO WIFI
+ // SD4 = EMMC
+ if(1==giBootPort) {
+ // ESD is boot device .
+ printk("add usdhc %d as mmcblk0\n",giBootPort+1);
+ if(46==gptHWCFG->m_val.bPCB||
+ 48==gptHWCFG->m_val.bPCB)
+ {
+ //
+ imx6q_add_sdhci_usdhc_imx(giBootPort, &mx6_ntx_esd_nocd_data);
+ }
+ else {
+ imx6q_add_sdhci_usdhc_imx(giBootPort, &mx6_ntx_esd_data);
+ }
+ printk("add usdhc 4 as mmcblk1\n");
+ imx6q_add_sdhci_usdhc_imx(3, pt_esdhc_ntx_isd_data); // mmcblk1
+ printk("add usdhc 3 as sdio for wifi\n");
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_q22_sd_wifi_data);
+ }
+ else {
+ // EMMC is boot device .
+ imx6q_add_sdhci_usdhc_imx(giBootPort, pt_esdhc_ntx_isd_data);
+ imx6q_add_sdhci_usdhc_imx(1, &mx6_ntx_esd_data); // mmcblk1
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_ntx_q22_sd_wifi_data);
+ }
+ break;
+ }
+
+ mx6_ntx_init_usb();
+ imx6q_add_otp();
+// imx6q_add_mxc_pwm(0);
+// imx6q_add_mxc_pwm_backlight(0, &mx6_ntx_pwm_backlight_data);
+
+
+// gpio_request(MX6_BRD_LCD_PWR_EN, "elcdif-power-on");
+// gpio_direction_output(MX6_BRD_LCD_PWR_EN, 1);
+ //mxc_register_device(&lcd_wvga_device, NULL);
+
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+
+ imx6dl_add_imx_epdc(&epdc_data);
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF //[
+ imx6dl_add_imx_elcdif(&wvga_fb_data[0]);
+#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+ //imx6q_add_dvfs_core(&mx6sl_ntx_dvfscore_data);
+
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+
+
+#ifdef CONFIG_MXC_GPU_VIV//[
+ if(2==gptHWCFG->m_val.bUIStyle)
+ {
+ // only android models needs GPU .
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ }
+#endif//] CONFIG_MXC_GPU_VIV
+
+ //imx6sl_add_device_buttons();
+ if(!NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,0)) {
+ // key matrix : ON
+
+ //mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_kb_pads,ARRAY_SIZE(mx6sl_brd_ntx_kb_pads));
+ //mdelay(1);
+
+ imx6sl_add_imx_keypad(&mx6sl_ntx_map_data);
+ }
+ //else
+ {
+ // gpio keys
+ mxc_iomux_v3_setup_multiple_pads(mx6sl_brd_ntx_kb_gpio_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_kb_gpio_pads));
+ udelay(1);
+
+ switch(gptHWCFG->m_val.bPCB) {
+ case 32://E60Q1X
+ case 31://E60Q0X
+ // use gpio instead of keymatrix ...
+ gpio_request (GPIO_KB_COL0, "KB_COL0");
+ gpio_direction_output (GPIO_KB_COL0, 0);
+ gpio_request (GPIO_KB_COL1, "KB_COL1");
+ gpio_direction_output (GPIO_KB_COL1, 0);
+
+ ntx_gpio_key_data.buttons = gpio_key_matrix_FL;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_matrix_FL);
+ break;
+ case 33://E60Q2X
+ ntx_gpio_key_data.buttons = gpio_key_HOME;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME);
+ break;
+ /*case 36://E60Q3X
+ ntx_gpio_key_data.buttons = gpio_key_HOME_FL;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL);
+ break;*/
+ default:
+ switch(gptHWCFG->m_val.bKeyPad) { //key pad define through bKeyPad in hwconfig
+ case 12: // NO_Key
+ ntx_gpio_key_data.buttons = gpio_key_None;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_None);
+ break;
+ case 11: // FL_Key
+ ntx_gpio_key_data.buttons = gpio_key_FL;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_FL);
+ break;
+ case 16: // FL+HOME PAD
+ case 13: // FL+HOME KEY
+ ntx_gpio_key_data.buttons = gpio_key_HOME_FL;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL);
+ break;
+ case 14: // HOME
+ case 18: // HOMEPAD
+ ntx_gpio_key_data.buttons = gpio_key_HOME;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME);
+ break;
+ case 17: // RETURN+HOME+MENU
+ ntx_gpio_key_data.buttons = gpio_key_RETURN_HOME_MENU;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_RETURN_HOME_MENU);
+ break;
+ default: // FL+HOME
+ ntx_gpio_key_data.buttons = gpio_key_HOME_FL;
+ ntx_gpio_key_data.nbuttons = ARRAY_SIZE(gpio_key_HOME_FL);
+ break;
+ }
+ break;
+ }
+
+ for(i=0;i<ntx_gpio_key_data.nbuttons;i++) {
+ if(0==strcmp(ntx_gpio_key_data.buttons[i].desc,"btn home")) {
+
+#ifdef TOUCH_HOME_LED//[
+ if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB ||
+ 0!=gptHWCFG->m_val.bHOME_LED_PWM)
+ {
+ // E60Q32/E60Q5X/
+ /*
+ * prepare hook functions of keys .
+ */
+ gptGPIO_HOME_KEY = &ntx_gpio_key_data.buttons[i];
+
+ if( 36==gptHWCFG->m_val.bPCB || 2==gptHWCFG->m_val.bHOME_LED_PWM )
+ {
+ // E60Q3X or HOME LED is GPIO controlled by SOC .
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT7__GPIO_5_10_OUPUT);
+ INIT_DELAYED_WORK(&homeled_pwrdwn_work,_homeled_work_func);
+ INIT_DELAYED_WORK(&homepad_check_work,_homepad_work_func);
+ }
+
+ ntx_gpio_key_data.buttons[i].hook = ntx_touch_home_key_hook;
+ ntx_gpio_key_data.buttons[i].debounce_interval = 50;
+
+ }
+
+
+#endif //]TOUCH_HOME_LED
+
+ if(2==gptHWCFG->m_val.bUIStyle) {
+ ntx_gpio_key_data.buttons[i].code = KEY_HOME;
+ }
+ }
+ else {
+ if(0==gptHWCFG->m_val.bUIStyle) {
+ if(0==strcmp(ntx_gpio_key_data.buttons[i].desc,"btn power")) {
+ printk("%s(),Ebrmain remote power key in gpio keys \n",__FUNCTION__);
+ ntx_gpio_key_data.nbuttons-=1;
+ }
+ }
+ }
+ }
+
+ if( 1==gptHWCFG->m_val.bHOME_LED_PWM ) {
+ // HOME LED is controled by MSP430 .
+ if(MSP430_HOMELED_TYPE_PWM==msp430_homeled_type_get(0)) {
+ giHomeLED_Delay_Ticks = 200;
+ }
+ else {
+ giHomeLED_Delay_Ticks = 100;
+ }
+ }
+
+
+ platform_device_register(&ntx_gpio_key_device);
+ }
+
+ imx6q_add_busfreq();
+ imx6sl_add_dcp();
+ imx6sl_add_rngb();
+ imx6sl_add_imx_pxp_v4l2();
+
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
+ mxc_register_device(&mxcbl_device, NULL);
+
+
+ platform_device_register(&ntx_light_ldm);
+#ifndef CONFIG_ANDROID //[
+ mxc_register_device(&mxc_usb_plug_device, &usbplug_data);
+#endif//]CONFIG_ANDROID
+ if (1==gptHWCFG->m_val.bPMIC) {
+ // RC5T619 .
+ }
+ else {
+ /* Register charger chips */
+ platform_device_register(&ntx_charger);
+
+ }
+
+ if(gptHWCFG) {
+
+ if(1==gptHWCFG->m_val.bHallSensor) {
+ // hall sensor enabled .
+ tle4913_init();
+ }
+
+
+ }
+ else {
+ printk(KERN_ERR "missing ntx hwconfig !!\n");
+ }
+
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6sl_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART1_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6_ntx_reserve(void)
+{
+#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
+ phys_addr_t phys;
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, MEMBLOCK_ALLOC_ACCESSIBLE);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+#endif
+}
+
+static int __init display_panel_setup(char *options)
+{
+ if (!options || !*options) {
+ pr_err("Error panel options\n");
+ return 0;
+ }
+
+ if (!strcmp(options, "lcd"))
+ display_panel_mode = PANEL_MODE_LCD;
+ else if (!strcmp(options, "hdmi"))
+ display_panel_mode = PANEL_MODE_HDMI;
+ else if (!strcmp(options, "eink"))
+ display_panel_mode = PANEL_MODE_EINK;
+ else
+ pr_warn("WARN: invalid display panel mode setting");
+
+ return 1;
+}
+
+__setup("panel=", display_panel_setup);
+
+MACHINE_START(MX6SL_NTX, "Freescale i.MX 6SoloLite NTX Board")
+ .boot_params = MX6SL_PHYS_OFFSET + 0x100,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_ntx_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_ntx_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6sl_ntx.h b/arch/arm/mach-mx6/board-mx6sl_ntx.h
new file mode 100755
index 00000000..15e6534d
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6sl_ntx.h
@@ -0,0 +1,306 @@
+#ifndef _BOARD_MX6SL_NTX_H
+#define _BOARD_MX6SL_NTX_H
+#include <mach/iomux-mx6sl.h>
+
+
+#define MX6SL_NTX_ACIN_PG gMX6SL_NTX_ACIN_PG
+#define MX6SL_NTX_CHG gMX6SL_NTX_CHG
+#define MX6SL_MSP_INT gMX6SL_MSP_INT
+#define MX6SL_PWR_SW gMX6SL_PWR_SW
+#define MX6SL_IR_TOUCH_INT gMX6SL_IR_TOUCH_INT
+#define MX6SL_IR_TOUCH_RST gMX6SL_IR_TOUCH_RST
+#define MX6SL_HALL_EN gMX6SL_HALL_EN
+#define MX6SL_ON_LED gMX6SL_ON_LED
+#define MX6SL_CHG_LED gMX6SL_CHG_LED
+#define MX6SL_ACT_LED gMX6SL_ACT_LED
+
+#define MX6SL_EXT_SD_CD IMX_GPIO_NR(5, 2) /* SD2_DAT4 */
+#define MX6SL_WIFI_3V3 IMX_GPIO_NR(5, 0) /* SD2_DAT7 */
+#define MX6SL_WIFI_RST IMX_GPIO_NR(4, 27) /* SD2_RST */
+#define MX6SL_WIFI_INT IMX_GPIO_NR(4, 29) /* SD2_DAT6 */
+#define MX6SL_HW_ID0 IMX_GPIO_NR(4, 2) /* KEY_COL5 */
+#define MX6SL_HW_ID1 IMX_GPIO_NR(4, 4) /* KEY_COL6 */
+#define MX6SL_HW_ID2 IMX_GPIO_NR(4, 6) /* KEY_COL7 */
+#define MX6SL_HW_ID3 IMX_GPIO_NR(4, 5) /* KEY_ROW6 */
+#define MX6SL_HW_ID4 IMX_GPIO_NR(4, 7) /* KEY_ROW7 */
+#define MX6SL_FL_EN IMX_GPIO_NR(2, 10) /* EPDC_PWRCTRL3 */
+#define MX6SL_FL_R_EN IMX_GPIO_NR(1, 29) /* EPDC_SDCE2 */
+#define MX6SL_EP_PWRALL IMX_GPIO_NR(2, 14) /* EPDC_PWRWAKEUP */
+#define MX6SL_EP_WAKEUP IMX_GPIO_NR(2, 7) /* EPDC_PWRCTRL0 */
+#define MX6SL_EP_PWRUP IMX_GPIO_NR(2, 8) /* EPDC_PWRCTRL1 */
+#define MX6SL_EP_INT IMX_GPIO_NR(2, 9) /* EPDC_PWRCTRL2 */
+#define MX6SL_EP_PWRSTAT IMX_GPIO_NR(2, 13) /* EPDC_PWRSTAT */
+#define MX6SL_EP_VCOM IMX_GPIO_NR(2, 3) /* EPDC_VCOM0 */
+
+#define MX6SL_SD2_CLK IMX_GPIO_NR(5, 5) /* SD2_CLK */
+#define MX6SL_SD2_CMD IMX_GPIO_NR(5, 4) /* SD2_CMD */
+#define MX6SL_SD2_DAT0 IMX_GPIO_NR(5, 1) /* SD2_DAT0 */
+#define MX6SL_SD2_DAT1 IMX_GPIO_NR(4, 30) /* SD2_DAT1 */
+#define MX6SL_SD2_DAT2 IMX_GPIO_NR(5, 3) /* SD2_DAT2 */
+#define MX6SL_SD2_DAT3 IMX_GPIO_NR(4, 28) /* SD2_DAT3 */
+
+#define MX6SL_SD3_CLK IMX_GPIO_NR(5, 18) /* SD3_CLK */
+#define MX6SL_SD3_CMD IMX_GPIO_NR(5, 21) /* SD3_CMD */
+#define MX6SL_SD3_DAT0 IMX_GPIO_NR(5, 19) /* SD3_DAT0 */
+#define MX6SL_SD3_DAT1 IMX_GPIO_NR(5, 20) /* SD3_DAT1 */
+#define MX6SL_SD3_DAT2 IMX_GPIO_NR(5, 16) /* SD3_DAT2 */
+#define MX6SL_SD3_DAT3 IMX_GPIO_NR(5, 17) /* SD3_DAT3 */
+
+#define MX6SL_I2C2_SCL IMX_GPIO_NR(3, 14) /* I2C2_SCL */
+#define MX6SL_I2C2_SDA IMX_GPIO_NR(3, 15) /* I2C2_SDA */
+#define MX6SL_I2C3_SCL IMX_GPIO_NR(3, 21) /* I2C3_SCL */
+#define MX6SL_I2C3_SDA IMX_GPIO_NR(3, 22) /* I2C3_SDA */
+
+#define GPIO_ESD_3V3_ON IMX_GPIO_NR(3, 29) /* ROW2 */
+#define GPIO_ISD_3V3_ON IMX_GPIO_NR(3, 31) /* ROW3 */
+#define GPIO_IR_3V3_ON IMX_GPIO_NR(4, 1) /* ROW4 */
+//#define GPIO_EP_3V3_ON IMX_GPIO_NR(4, 3) /* ROW5 */
+
+#define GPIO_KB_COL0 IMX_GPIO_NR(3, 24) /* COL0 */
+#define GPIO_KB_COL1 IMX_GPIO_NR(3, 26) /* COL1 */
+
+#define GPIO_KB_ROW0 IMX_GPIO_NR(3, 25) /* ROW0 */
+#define GPIO_KB_ROW1 IMX_GPIO_NR(3, 27) /* ROW1 */
+#define GPIO_KB_ROW2 IMX_GPIO_NR(3, 29) /* ROW2 */
+
+#define MX6SL_KL25_INT2 IMX_GPIO_NR(3, 29) /* ROW2 */
+#if 1
+#define MX6SL_WACOM_INT IMX_GPIO_NR(4, 0) /* COL4 */
+#define MX6SL_WACOM_PDCT IMX_GPIO_NR(4, 2) /* COL5 */
+#else
+#define MX6SL_WACOM_INT IMX_GPIO_NR(4, 2) /* COL5 */
+#define MX6SL_WACOM_PDCT IMX_GPIO_NR(4, 0) /* COL4 */
+#endif
+#define MX6SL_WACOM_INT_4_1 IMX_GPIO_NR(4, 1) /* ROW4 */
+#define MX6SL_WACOM_FWE IMX_GPIO_NR(3, 24) /* COL0 */
+#define MX6SL_WACOM_RST IMX_GPIO_NR(3, 30) /* COL3 */
+
+#define MX6SL_WALTOP_RST IMX_GPIO_NR(3, 31) /* ROW3 */
+#define MX6SL_WALTOP_RST_3_30 IMX_GPIO_NR(3, 30) /* ROW3 */
+#define MX6SL_WALTOP_INT IMX_GPIO_NR(4, 1) /* ROW4 */
+#define MX6SL_WALTOP_INT_4_0 IMX_GPIO_NR(4, 0) /* ROW4 */
+
+
+extern volatile unsigned gMX6SL_NTX_ACIN_PG;
+extern volatile unsigned gMX6SL_NTX_CHG;
+extern volatile unsigned gMX6SL_MSP_INT;
+extern volatile unsigned gMX6SL_PWR_SW;
+extern volatile unsigned gMX6SL_IR_TOUCH_INT;
+extern volatile unsigned gMX6SL_IR_TOUCH_RST;
+extern volatile unsigned gMX6SL_HALL_EN;
+extern volatile unsigned gMX6SL_ON_LED;
+extern volatile unsigned gMX6SL_CHG_LED;
+extern volatile unsigned gMX6SL_ACT_LED;
+extern volatile unsigned gMX6SL_WIFI_3V3;
+extern volatile unsigned gMX6SL_WIFI_RST;
+extern volatile unsigned gMX6SL_WIFI_INT;
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_kb_pads[] = {
+ MX6SL_PAD_KEY_COL0__KPP_COL_0,
+ MX6SL_PAD_KEY_COL1__KPP_COL_1,
+ MX6SL_PAD_KEY_ROW0__KPP_ROW_0,
+ MX6SL_PAD_KEY_ROW1__KPP_ROW_1,
+};
+static iomux_v3_cfg_t mx6sl_brd_ntx_kb_gpio_pads[] = {
+ MX6SL_PAD_KEY_COL0__GPIO_3_24,
+ MX6SL_PAD_KEY_COL1__GPIO_3_26,
+ MX6SL_PAD_KEY_ROW0__GPIO_3_25,
+ MX6SL_PAD_KEY_ROW1__GPIO_3_27,
+ MX6SL_PAD_KEY_ROW2__GPIO_3_29,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_sd4_pads[] = {
+ MX6SL_PAD_FEC_MDIO__USDHC4_CLK,
+ MX6SL_PAD_FEC_TX_CLK__USDHC4_CMD,
+ MX6SL_PAD_FEC_RX_ER__USDHC4_DAT0,
+ MX6SL_PAD_FEC_CRS_DV__USDHC4_DAT1,
+ MX6SL_PAD_FEC_RXD1__USDHC4_DAT2,
+ MX6SL_PAD_FEC_TXD0__USDHC4_DAT3,
+ MX6SL_PAD_FEC_MDC__USDHC4_DAT4,
+ MX6SL_PAD_FEC_RXD0__USDHC4_DAT5,
+ MX6SL_PAD_FEC_TX_EN__USDHC4_DAT6,
+ MX6SL_PAD_FEC_TXD1__USDHC4_DAT7,
+ MX6SL_PAD_FEC_REF_CLK__GPIO_4_26_PULLHIGH,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_sd4_gpio_pads[] = {
+ MX6SL_PAD_FEC_MDIO__GPIO_4_20, // PWR_GOOD
+ MX6SL_PAD_FEC_TX_CLK__GPIO_4_21, // CHG#
+ MX6SL_PAD_FEC_RX_ER__GPIO_4_19, // MSP_INT#
+ MX6SL_PAD_FEC_CRS_DV__GPIO_4_25, // PWR_SW
+ MX6SL_PAD_FEC_RXD1__GPIO_4_18, // GS_INT
+ MX6SL_PAD_FEC_TXD0__GPIO_4_24, // IR_TOUCH_INT#
+ MX6SL_PAD_FEC_MDC__GPIO_4_23, // HALL_EN
+ MX6SL_PAD_FEC_RXD0__GPIO_4_17, // IR_RST
+ MX6SL_PAD_FEC_TX_EN__GPIO_4_22, // ACT_LED
+ MX6SL_PAD_FEC_TXD1__GPIO_4_16, // CHG_LED
+ MX6SL_PAD_FEC_REF_CLK__GPIO_4_26, // ON_LED
+};
+
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_sd1_pads[] = {
+ MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ,
+ MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ,
+ MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ,
+ MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ,
+ MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ,
+ MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ,
+ MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ,
+ MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ,
+ MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ,
+ MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ,
+};
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_sd1_gpio_pads[] = {
+ MX6SL_PAD_SD1_CLK__GPIO_5_15, // CHG#
+ MX6SL_PAD_SD1_CMD__GPIO_5_14, // ACIN_PG#
+ MX6SL_PAD_SD1_DAT0__GPIO_5_11, // MSP_INT#
+ MX6SL_PAD_SD1_DAT1__GPIO_5_8, // PWR_SW#
+ MX6SL_PAD_SD1_DAT2__GPIO_5_13, // TP85
+ MX6SL_PAD_SD1_DAT3__GPIO_5_6, // IR_DataReady
+ MX6SL_PAD_SD1_DAT4__GPIO_5_12, // TP86/Hall_EN#
+ MX6SL_PAD_SD1_DAT5__GPIO_5_9, // V325_RST#
+ MX6SL_PAD_SD1_DAT6__GPIO_5_7, // ACTION_LED_RH#
+ MX6SL_PAD_SD1_DAT7__GPIO_5_10, // TP82/Charge_LED_RH#
+};
+
+
+
+static iomux_v3_cfg_t mx6sl_brd_ntx_pads[] = {
+ MX6SL_PAD_REF_CLK_24M__I2C3_SCL,
+ MX6SL_PAD_REF_CLK_32K__I2C3_SDA,
+
+ /* USBOTG ID pin */
+ MX6SL_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID,
+
+ MX6SL_PAD_SD2_DAT4__GPIO_5_2, // EXT_SD_CD
+ MX6SL_PAD_SD2_DAT7__GPIO_5_0, // WIFI_3V3_ON
+ MX6SL_PAD_SD2_RST__GPIO_4_27, // WIFI_RST
+ //MX6SL_PAD_SD2_DAT6__GPIO_4_29_OUTPUT, // WIFI_INT
+
+ MX6SL_PAD_KEY_COL5__GPIO_4_2, // HW_ID0
+ MX6SL_PAD_KEY_COL6__GPIO_4_4, // HW_ID1
+ MX6SL_PAD_KEY_COL7__GPIO_4_6, // HW_ID2
+ MX6SL_PAD_KEY_ROW6__GPIO_4_5, // HW_ID3
+ MX6SL_PAD_KEY_ROW7__GPIO_4_7, // HW_ID4
+
+ MX6SL_PAD_KEY_ROW2__GPIO_3_29, // ESD_3V3_ON(Q22)/BS_INT(Q12)/NA
+ MX6SL_PAD_KEY_ROW3__GPIO_3_31, // ISD_3V3_ON(Q22)/BS_3V3(Q12/NA
+ MX6SL_PAD_KEY_ROW4__GPIO_4_1, // IR_3V3_ON(Q22)/BS_UP(Q12)/NA
+ //MX6SL_PAD_KEY_ROW5__GPIO_4_3, // EP_3V3_ON(Q22)/BS_DN(Q12)/NA
+
+ MX6SL_PAD_KEY_COL2__GPIO_3_28, // BS_Left (Q12)/NA
+ MX6SL_PAD_KEY_COL3__GPIO_3_30, // BS_Right (Q12)/NA
+ MX6SL_PAD_KEY_COL4__GPIO_4_0, // BS_Click (Q12)/NA
+
+#if 0
+ MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7, // EP_PWRCTRL0 (WAKEUP#)
+ MX6SL_PAD_EPDC_PWRCTRL1__GPIO_2_8, // EP_PWRCTRL1 (PWRUP)
+ MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9, // EP_INT
+ MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,// PWRALL
+ MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13, // EP_PWRSTAT (PWR_GOOD)
+ MX6SL_PAD_EPDC_VCOM0__GPIO_2_3, // VCOM_CTRL
+#endif
+
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10, // FL_EN
+ MX6SL_PAD_EPDC_SDCE2__GPIO_1_29, // FL_R_EN
+
+ MX6SL_PAD_LCD_DAT0__GPIO_2_20,
+ MX6SL_PAD_LCD_DAT1__GPIO_2_21,
+ MX6SL_PAD_LCD_DAT2__GPIO_2_22,
+ MX6SL_PAD_LCD_DAT3__GPIO_2_23,
+ MX6SL_PAD_LCD_DAT4__GPIO_2_24,
+ MX6SL_PAD_LCD_DAT5__GPIO_2_25,
+ MX6SL_PAD_LCD_DAT6__GPIO_2_26,
+ MX6SL_PAD_LCD_DAT7__GPIO_2_27,
+ MX6SL_PAD_LCD_DAT8__GPIO_2_28,
+ MX6SL_PAD_LCD_DAT9__GPIO_2_29,
+ MX6SL_PAD_LCD_DAT10__GPIO_2_30,
+ MX6SL_PAD_LCD_DAT11__GPIO_2_31,
+ MX6SL_PAD_LCD_DAT12__GPIO_3_0,
+ MX6SL_PAD_LCD_DAT13__GPIO_3_1,
+ MX6SL_PAD_LCD_DAT14__GPIO_3_2,
+ MX6SL_PAD_LCD_DAT15__GPIO_3_3,
+ MX6SL_PAD_LCD_DAT16__GPIO_3_4,
+ MX6SL_PAD_LCD_DAT17__GPIO_3_5,
+ MX6SL_PAD_LCD_DAT18__GPIO_3_6,
+ MX6SL_PAD_LCD_DAT19__GPIO_3_7,
+ MX6SL_PAD_LCD_DAT20__GPIO_3_8,
+ MX6SL_PAD_LCD_DAT21__GPIO_3_9,
+ MX6SL_PAD_LCD_DAT22__GPIO_3_10,
+ MX6SL_PAD_LCD_DAT23__GPIO_3_11,
+
+ MX6SL_PAD_LCD_CLK__GPIO_2_15,
+ MX6SL_PAD_LCD_ENABLE__GPIO_2_16,
+ MX6SL_PAD_LCD_HSYNC__GPIO_2_17,
+ MX6SL_PAD_LCD_VSYNC__GPIO_2_18,
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+
+ MX6SL_PAD_ECSPI1_SCLK__GPIO_4_8,
+ MX6SL_PAD_ECSPI1_MOSI__GPIO_4_9,
+ MX6SL_PAD_ECSPI1_MISO__GPIO_4_10,
+ MX6SL_PAD_ECSPI1_SS0__GPIO_4_11,
+ MX6SL_PAD_ECSPI2_SCLK__GPIO_4_12,
+ MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13,
+ MX6SL_PAD_ECSPI2_MISO__GPIO_4_14,
+ MX6SL_PAD_ECSPI2_SS0__GPIO_4_15,
+ MX6SL_PAD_AUD_RXFS__GPIO_1_0,
+ MX6SL_PAD_AUD_RXC__GPIO_1_1,
+ MX6SL_PAD_AUD_RXD__GPIO_1_2,
+ MX6SL_PAD_AUD_TXC__GPIO_1_3,
+ MX6SL_PAD_AUD_TXFS__GPIO_1_4,
+ MX6SL_PAD_AUD_TXD__GPIO_1_5,
+ MX6SL_PAD_AUD_MCLK__GPIO_1_6,
+ MX6SL_PAD_HSIC_DAT__GPIO_3_19,
+ MX6SL_PAD_HSIC_STROBE__GPIO_3_20,
+ MX6SL_PAD_WDOG_B__GPIO_3_18,
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_sd2_gpio_pads[] = {
+ MX6SL_PAD_SD2_CLK__GPIO_5_5,
+ MX6SL_PAD_SD2_CMD__GPIO_5_4,
+ MX6SL_PAD_SD2_DAT0__GPIO_5_1,
+ MX6SL_PAD_SD2_DAT1__GPIO_4_30,
+ MX6SL_PAD_SD2_DAT2__GPIO_5_3,
+ MX6SL_PAD_SD2_DAT3__GPIO_4_28,
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_sd2_wifi_pads[] = {
+ MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ,
+ MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ,
+ MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ,
+ MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ,
+ MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ,
+ MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ,
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_sd3_gpio_pads[] = {
+ MX6SL_PAD_SD3_CLK__GPIO_5_18,
+ MX6SL_PAD_SD3_CMD__GPIO_5_21,
+ MX6SL_PAD_SD3_DAT0__GPIO_5_19,
+ MX6SL_PAD_SD3_DAT1__GPIO_5_20,
+ MX6SL_PAD_SD3_DAT2__GPIO_5_16,
+ MX6SL_PAD_SD3_DAT3__GPIO_5_17,
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_sd3_wifi_pads[] = {
+ MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+};
+
+
+static iomux_v3_cfg_t mx6sl_ntx_q22_wifictrl_pads[] = {
+ MX6SL_PAD_SD2_DAT6__GPIO_4_29_OUTPUT, // WiFi_3V3_ON#
+ MX6SL_PAD_SD2_DAT5__GPIO_4_31_INPUT, // WiFi_INT#
+};
+
+static iomux_v3_cfg_t mx6sl_ntx_q12_wifictrl_pads[] = {
+ MX6SL_PAD_SD2_DAT6__GPIO_4_29, // WiFi_INT#
+ MX6SL_PAD_SD2_DAT5__GPIO_4_31, //NC
+};
+
+#endif
diff --git a/arch/arm/mach-mx6/board-mx6solo_sabreauto.h b/arch/arm/mach-mx6/board-mx6solo_sabreauto.h
new file mode 100644
index 00000000..b0edb5e5
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6solo_sabreauto.h
@@ -0,0 +1,377 @@
+
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6dl.h>
+
+static iomux_v3_cfg_t mx6dl_sabreauto_pads[] = {
+
+ /* UART4 for debug */
+ MX6DL_PAD_KEY_COL0__UART4_TXD,
+ MX6DL_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6DL_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6DL_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6DL_PAD_KEY_COL1__ENET_MDIO,
+ MX6DL_PAD_KEY_COL2__ENET_MDC,
+ MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+ /*RGMII Phy Interrupt */
+ MX6DL_PAD_GPIO_19__GPIO_4_5,
+#endif
+ /* MCLK for csi0 */
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ /*MX6DL_PAD_GPIO_3__CCM_CLKO2,i*/
+
+ /* Android GPIO keys */
+ MX6DL_PAD_SD2_CMD__GPIO_1_11, /* home */
+ MX6DL_PAD_SD2_DAT3__GPIO_1_12, /* back */
+ MX6DL_PAD_SD4_DAT4__GPIO_2_12, /* prog */
+ MX6DL_PAD_SD4_DAT7__GPIO_2_15, /* vol up */
+ MX6DL_PAD_DISP0_DAT20__GPIO_5_14, /* vol down */
+
+ /* SD1 */
+ MX6DL_PAD_SD1_CLK__USDHC1_CLK_50MHZ_40OHM,
+ MX6DL_PAD_SD1_CMD__USDHC1_CMD_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM,
+ MX6DL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM,
+
+ /* SD1_CD and SD1_WP */
+ MX6DL_PAD_GPIO_1__GPIO_1_1,
+ MX6DL_PAD_CSI0_DATA_EN__GPIO_5_20,
+
+ /* SD3 */
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+
+ /* SD3 VSelect */
+ MX6DL_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6DL_PAD_NANDF_CS2__GPIO_6_15,
+ MX6DL_PAD_SD2_DAT2__GPIO_1_13,
+
+ /* ESAI */
+ MX6DL_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6DL_PAD_ENET_RXD1__ESAI1_FST,
+ MX6DL_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6DL_PAD_GPIO_5__ESAI1_TX2_RX3,
+ MX6DL_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6DL_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6DL_PAD_GPIO_17__ESAI1_TX0,
+ MX6DL_PAD_NANDF_CS3__ESAI1_TX1,
+ MX6DL_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6DL_PAD_GPIO_9__ESAI1_FSR,
+ /* esai interrupt */
+ MX6DL_PAD_SD2_CLK__GPIO_1_10,
+
+ /* I2C2 */
+ MX6DL_PAD_EIM_EB2__I2C2_SCL,
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA,
+ MX6DL_PAD_SD2_DAT0__GPIO_1_15,
+
+ /* DISPLAY */
+ MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ /* LITE_SENS_INT_B */
+ MX6DL_PAD_DISP0_DAT23__GPIO_5_17,
+ /*PMIC INT*/
+ MX6DL_PAD_DISP0_DAT22__GPIO_5_16,
+
+ /* ipu1 csi0 */
+ MX6DL_PAD_CSI0_DAT4__IPU1_CSI0_D_4,
+ MX6DL_PAD_CSI0_DAT5__IPU1_CSI0_D_5,
+ MX6DL_PAD_CSI0_DAT6__IPU1_CSI0_D_6,
+ MX6DL_PAD_CSI0_DAT7__IPU1_CSI0_D_7,
+ MX6DL_PAD_CSI0_DAT8__IPU1_CSI0_D_8,
+ MX6DL_PAD_CSI0_DAT9__IPU1_CSI0_D_9,
+ MX6DL_PAD_CSI0_DAT10__IPU1_CSI0_D_10,
+ MX6DL_PAD_CSI0_DAT11__IPU1_CSI0_D_11,
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+
+ /* PWM3 and PMW4 */
+ MX6DL_PAD_SD4_DAT1__PWM3_PWMO,
+ MX6DL_PAD_SD4_DAT2__PWM4_PWMO,
+
+ /* DISP0 RESET */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* SPDIF */
+ MX6DL_PAD_KEY_COL3__SPDIF_IN1,
+
+ /* Touchscreen interrupt */
+ MX6DL_PAD_EIM_EB0__GPIO_2_28,
+
+ /* USBOTG ID pin */
+ MX6DL_PAD_ENET_RX_ER__ANATOP_USBOTG_ID,
+
+ /* VIDEO adv7180 INTRQ */
+ MX6DL_PAD_ENET_RXD0__GPIO_1_27,
+ /* UART 2 */
+ MX6DL_PAD_GPIO_7__UART2_TXD,
+ MX6DL_PAD_GPIO_8__UART2_RXD,
+ MX6DL_PAD_SD4_DAT6__UART2_CTS,
+ MX6DL_PAD_SD4_DAT5__UART2_RTS,
+
+ /*USBs OC pin */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0, /*HOST1_OC*/
+ MX6DL_PAD_SD4_DAT0__GPIO_2_8, /*OTG_OC*/
+
+ /* DISP0 I2C ENABLE*/
+ MX6DL_PAD_EIM_D28__GPIO_3_28,
+
+ /* DISP0 DET */
+ MX6DL_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1,
+#else
+ /* MLB150 */
+ MX6DL_PAD_ENET_TXD1__MLB_MLBCLK,
+ MX6DL_PAD_GPIO_6__MLB_MLBSIG,
+ MX6DL_PAD_GPIO_2__MLB_MLBDAT,
+#endif
+};
+
+static iomux_v3_cfg_t mx6dl_sabreauto_can0_pads[] = {
+ /* CAN1 */
+ MX6DL_PAD_KEY_COL2__CAN1_TXCAN,
+ MX6DL_PAD_KEY_ROW2__CAN1_RXCAN,
+};
+
+
+static iomux_v3_cfg_t mx6dl_sabreauto_can1_pads[] = {
+ /* CAN2 */
+ MX6DL_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6DL_PAD_KEY_ROW4__CAN2_RXCAN,
+};
+
+static iomux_v3_cfg_t mx6dl_sabreauto_mipi_sensor_pads[] = {
+ MX6DL_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+#define MX6DL_USDHC_PAD_SETTING(id, speed) \
+mx6dl_sd##id##_##speed##mhz[] = { \
+ MX6DL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 200);
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6dl_gpmi_nand[] __initdata = {
+ MX6DL_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6DL_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6DL_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6DL_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6DL_PAD_NANDF_D0__RAWNAND_D0,
+ MX6DL_PAD_NANDF_D1__RAWNAND_D1,
+ MX6DL_PAD_NANDF_D2__RAWNAND_D2,
+ MX6DL_PAD_NANDF_D3__RAWNAND_D3,
+ MX6DL_PAD_NANDF_D4__RAWNAND_D4,
+ MX6DL_PAD_NANDF_D5__RAWNAND_D5,
+ MX6DL_PAD_NANDF_D6__RAWNAND_D6,
+ MX6DL_PAD_NANDF_D7__RAWNAND_D7,
+ MX6DL_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6DL_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static iomux_v3_cfg_t mx6dl_i2c3_pads_rev_a[] __initdata = {
+ MX6DL_PAD_GPIO_3__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6dl_i2c3_pads_rev_b[] __initdata = {
+ MX6DL_PAD_GPIO_3__I2C3_SCL,
+ MX6DL_PAD_EIM_D18__I2C3_SDA,
+};
+static iomux_v3_cfg_t mx6dl_tuner_pads[] __initdata = {
+ MX6DL_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC,
+ MX6DL_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS,
+ MX6DL_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD,
+};
+static iomux_v3_cfg_t mx6dl_extra_pads_rev_b[] __initdata = {
+ MX6DL_PAD_EIM_A24__GPIO_5_4,
+ MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+};
+static iomux_v3_cfg_t mx6dl_spinor_pads[] __initdata = {
+ /* eCSPI1 */
+ MX6DL_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6DL_PAD_EIM_D17__ECSPI1_MISO,
+ MX6DL_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6DL_PAD_EIM_D19__ECSPI1_SS1,
+
+ MX6DL_PAD_EIM_D19__GPIO_3_19,
+};
+
+/*Bluetooth is conflicted with GMPI and NOR chips*/
+static iomux_v3_cfg_t mx6dl_bluetooth_pads[] __initdata = {
+ /* UART 3 */
+ MX6DL_PAD_SD4_CLK__UART3_RXD,
+ MX6DL_PAD_SD4_CMD__UART3_TXD,
+ MX6DL_PAD_EIM_D30__UART3_CTS,
+ MX6DL_PAD_EIM_EB3__UART3_RTS,
+};
+
+static iomux_v3_cfg_t mx6dl_weimnor_pads[] __initdata = {
+ /* Parallel NOR */
+ MX6DL_PAD_EIM_OE__WEIM_WEIM_OE,
+ MX6DL_PAD_EIM_RW__WEIM_WEIM_RW,
+ MX6DL_PAD_EIM_WAIT__WEIM_WEIM_WAIT,
+ MX6DL_PAD_EIM_CS0__WEIM_WEIM_CS_0,
+ /*Control NOR reset using gpio mode*/
+ MX6DL_PAD_DISP0_DAT8__GPIO_4_29,
+
+ MX6DL_PAD_EIM_LBA__WEIM_WEIM_LBA,
+ MX6DL_PAD_EIM_BCLK__WEIM_WEIM_BCLK,
+ /* Parallel Nor Data Bus */
+ MX6DL_PAD_EIM_D16__WEIM_WEIM_D_16,
+ MX6DL_PAD_EIM_D17__WEIM_WEIM_D_17,
+ MX6DL_PAD_EIM_D18__WEIM_WEIM_D_18,
+ MX6DL_PAD_EIM_D19__WEIM_WEIM_D_19,
+ MX6DL_PAD_EIM_D20__WEIM_WEIM_D_20,
+ MX6DL_PAD_EIM_D21__WEIM_WEIM_D_21,
+ MX6DL_PAD_EIM_D22__WEIM_WEIM_D_22,
+ MX6DL_PAD_EIM_D23__WEIM_WEIM_D_23,
+ MX6DL_PAD_EIM_D24__WEIM_WEIM_D_24,
+ MX6DL_PAD_EIM_D25__WEIM_WEIM_D_25,
+ MX6DL_PAD_EIM_D26__WEIM_WEIM_D_26,
+ MX6DL_PAD_EIM_D27__WEIM_WEIM_D_27,
+ MX6DL_PAD_EIM_D28__WEIM_WEIM_D_28,
+ MX6DL_PAD_EIM_D29__WEIM_WEIM_D_29,
+ MX6DL_PAD_EIM_D30__WEIM_WEIM_D_30,
+ MX6DL_PAD_EIM_D31__WEIM_WEIM_D_31,
+
+ /* Parallel Nor 25 bit Address Bus */
+ MX6DL_PAD_EIM_A24__GPIO_5_4,
+ MX6DL_PAD_EIM_A23__WEIM_WEIM_A_23,
+ MX6DL_PAD_EIM_A22__WEIM_WEIM_A_22,
+ MX6DL_PAD_EIM_A21__WEIM_WEIM_A_21,
+ MX6DL_PAD_EIM_A20__WEIM_WEIM_A_20,
+ MX6DL_PAD_EIM_A19__WEIM_WEIM_A_19,
+ MX6DL_PAD_EIM_A18__WEIM_WEIM_A_18,
+ MX6DL_PAD_EIM_A17__WEIM_WEIM_A_17,
+ MX6DL_PAD_EIM_A16__WEIM_WEIM_A_16,
+
+ MX6DL_PAD_EIM_DA15__WEIM_WEIM_DA_A_15,
+ MX6DL_PAD_EIM_DA14__WEIM_WEIM_DA_A_14,
+ MX6DL_PAD_EIM_DA13__WEIM_WEIM_DA_A_13,
+ MX6DL_PAD_EIM_DA12__WEIM_WEIM_DA_A_12,
+ MX6DL_PAD_EIM_DA11__WEIM_WEIM_DA_A_11,
+ MX6DL_PAD_EIM_DA10__WEIM_WEIM_DA_A_10,
+ MX6DL_PAD_EIM_DA9__WEIM_WEIM_DA_A_9,
+ MX6DL_PAD_EIM_DA8__WEIM_WEIM_DA_A_8,
+ MX6DL_PAD_EIM_DA7__WEIM_WEIM_DA_A_7,
+ MX6DL_PAD_EIM_DA6__WEIM_WEIM_DA_A_6,
+ MX6DL_PAD_EIM_DA5__WEIM_WEIM_DA_A_5,
+ MX6DL_PAD_EIM_DA4__WEIM_WEIM_DA_A_4,
+ MX6DL_PAD_EIM_DA3__WEIM_WEIM_DA_A_3,
+ MX6DL_PAD_EIM_DA2__WEIM_WEIM_DA_A_2,
+ MX6DL_PAD_EIM_DA1__WEIM_WEIM_DA_A_1,
+ MX6DL_PAD_EIM_DA0__WEIM_WEIM_DA_A_0,
+};
+
+static iomux_v3_cfg_t mx6dl_sabreauto_hdmi_ddc_pads[] = {
+ MX6DL_PAD_EIM_EB2__HDMI_TX_DDC_SCL, /* HDMI DDC SCL */
+ MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA, /* HDMI DDC SDA */
+};
+
+static iomux_v3_cfg_t mx6dl_sabreauto_i2c2_pads[] = {
+ MX6DL_PAD_EIM_EB2__I2C2_SCL, /* I2C2 SCL */
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA, /* I2C2 SDA */
+};
diff --git a/arch/arm/mach-mx6/bus_freq.c b/arch/arm/mach-mx6/bus_freq.c
new file mode 100644
index 00000000..2d408b8b
--- /dev/null
+++ b/arch/arm/mach-mx6/bus_freq.c
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ * @file bus_freq.c
+ *
+ * @brief A common API for the Freescale Semiconductor i.MXC CPUfreq module
+ * and DVFS CORE module.
+ *
+ * The APIs are for setting bus frequency to low or high.
+ *
+ * @ingroup PM
+ */
+#include <asm/io.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <mach/iram.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/sdram_autogating.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include "crm_regs.h"
+#include <linux/suspend.h>
+
+#define LPAPM_CLK 24000000
+#define DDR_AUDIO_CLK 100000000
+#define DDR_MED_CLK 400000000
+#define DDR3_NORMAL_CLK 528000000
+#define GPC_PGC_GPU_PGCR_OFFSET 0x260
+#define GPC_CNTR_OFFSET 0x0
+
+static DEFINE_SPINLOCK(freq_lock);
+
+int low_bus_freq_mode;
+int audio_bus_freq_mode;
+int high_bus_freq_mode;
+int med_bus_freq_mode;
+
+int bus_freq_scaling_initialized;
+static struct device *busfreq_dev;
+static int busfreq_suspended;
+
+/* True if bus_frequency is scaled not using DVFS-PER */
+int bus_freq_scaling_is_active;
+
+int lp_high_freq;
+int lp_med_freq;
+int lp_audio_freq;
+int high_cpu_freq;
+unsigned int ddr_low_rate;
+unsigned int ddr_med_rate;
+unsigned int ddr_normal_rate;
+
+int low_freq_bus_used(void);
+void set_ddr_freq(int ddr_freq);
+void *mx6sl_wfi_iram_base;
+unsigned long mx6sl_wfi_iram_phys_addr;
+
+void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr,\
+ int audio_mode) = NULL;
+extern void mx6sl_wait (int arm_podf, unsigned long wfi_iram_addr);
+
+void *mx6sl_ddr_freq_base;
+unsigned long mx6sl_ddr_freq_phys_addr;
+void (*mx6sl_ddr_freq_change_iram)(int ddr_freq, int low_bus_freq_mode) = NULL;
+extern void mx6sl_ddr_iram(int ddr_freq);
+
+extern int init_mmdc_settings(void);
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern int update_ddr_freq(int ddr_rate);
+extern unsigned long save_ttbr1(void);
+extern void restore_ttbr1(u32 ttbr1);
+extern int chip_rev;
+
+DEFINE_MUTEX(bus_freq_mutex);
+
+struct timeval start_time;
+struct timeval end_time;
+
+static int cpu_op_nr;
+static u32 org_arm_podf;
+static struct cpu_op *cpu_op_tbl;
+static struct clk *pll2_400;
+static struct clk *axi_clk;
+static struct clk *ahb_clk;
+static struct clk *periph_clk;
+static struct clk *osc_clk;
+static struct clk *cpu_clk;
+static struct clk *pll3;
+static struct clk *pll2;
+static struct clk *pll1;
+static struct clk *pll1_sw_clk;
+static struct clk *pll3_sw_clk;
+static struct clk *pll2_200;
+struct clk *mmdc_ch0_axi;
+static struct clk *pll3_540;
+
+static struct delayed_work low_bus_freq_handler;
+
+void reduce_bus_freq(void)
+{
+ if (!cpu_is_mx6sl()) {
+ if (cpu_is_mx6dl() &&
+ (clk_get_parent(axi_clk) != periph_clk))
+ /* Set the axi_clk to be sourced from the periph_clk.
+ * So that its frequency can be lowered down to 50MHz
+ * or 24MHz as the case may be.
+ */
+ clk_set_parent(axi_clk, periph_clk);
+
+ clk_enable(pll3);
+ if (lp_audio_freq) {
+ /* Need to ensure that PLL2_PFD_400M is kept ON. */
+ clk_enable(pll2_400);
+ update_ddr_freq(DDR_AUDIO_CLK);
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk, pll2_200);
+ audio_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ } else {
+ update_ddr_freq(LPAPM_CLK);
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk, osc_clk);
+ if (audio_bus_freq_mode)
+ clk_disable(pll2_400);
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ }
+
+ if (med_bus_freq_mode)
+ clk_disable(pll2_400);
+
+ clk_disable(pll3);
+ med_bus_freq_mode = 0;
+ } else {
+ u32 reg;
+ u32 div;
+ unsigned long flags;
+
+ if (high_bus_freq_mode) {
+ /* Set periph_clk to be sourced from OSC_CLK */
+ /* Set AXI to 24MHz. */
+ clk_set_parent(periph_clk, osc_clk);
+ clk_set_rate(axi_clk,
+ clk_round_rate(axi_clk, LPAPM_CLK));
+ /* Set AHB to 24MHz. */
+ clk_set_rate(ahb_clk,
+ clk_round_rate(ahb_clk, LPAPM_CLK));
+ }
+ if (lp_audio_freq) {
+ u32 ttbr1;
+ /* PLL2 is on in this mode, as DDR is at 100MHz. */
+ /* Now change DDR freq while running from IRAM. */
+
+ /* Set AHB to 24MHz. */
+ clk_set_rate(ahb_clk,
+ clk_round_rate(ahb_clk, LPAPM_CLK / 3));
+
+ spin_lock_irqsave(&freq_lock, flags);
+ /* sync the outer cache. */
+ outer_sync();
+
+ /* Save TTBR1 */
+ ttbr1 = save_ttbr1();
+
+ mx6sl_ddr_freq_change_iram(DDR_AUDIO_CLK,
+ low_bus_freq_mode);
+ restore_ttbr1(ttbr1);
+
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ if (low_bus_freq_mode) {
+ /* Swtich ARM to run off PLL2_PFD2_400MHz
+ * since DDR is anyway at 100MHz.
+ */
+ clk_set_parent(pll1_sw_clk, pll2_400);
+
+ /* Ensure that the clock will be
+ * at original speed.
+ */
+ reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ /* We have enabled PLL1 in the code below when
+ * ARM is from PLL1, so disable it here.
+ */
+ clk_disable(pll1);
+ }
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 1;
+ } else {
+ u32 ttbr1;
+ /* Set MMDC clk to 24MHz. */
+ /* Since we are going to set PLL2 in bypass mode,
+ * move the CPU clock off PLL2.
+ */
+ /* Ensure that the clock will be at
+ * lowest possible freq.
+ */
+ org_arm_podf = __raw_readl(MXC_CCM_CACRR);
+ /* Need to enable PLL1 before setting its rate. */
+ clk_enable(pll1);
+ clk_set_rate(pll1,
+ cpu_op_tbl[cpu_op_nr - 1].pll_lpm_rate);
+ div = clk_get_rate(pll1) /
+ cpu_op_tbl[cpu_op_nr - 1].cpu_rate;
+
+ reg = __raw_writel(div - 1, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ clk_set_parent(pll1_sw_clk, pll1);
+
+ spin_lock_irqsave(&freq_lock, flags);
+ /* sync the outer cache. */
+ outer_sync();
+
+ ttbr1 = save_ttbr1();
+ /* Now change DDR freq while running from IRAM. */
+ mx6sl_ddr_freq_change_iram(LPAPM_CLK,
+ low_bus_freq_mode);
+ restore_ttbr1(ttbr1);
+
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ low_bus_freq_mode = 1;
+ audio_bus_freq_mode = 0;
+ }
+ }
+ high_bus_freq_mode = 0;
+
+}
+
+static void reduce_bus_freq_handler(struct work_struct *work)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (!low_freq_bus_used()) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ /* If we are already in audio bus freq mode,
+ * just return if lp_audio_freq is true.
+ */
+ if (audio_bus_freq_mode && lp_audio_freq) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+
+ /* If we dont want to transition from low bus to
+ * audio bus mode and are already in
+ *low bus mode, then return.
+ */
+ if (!lp_audio_freq && low_bus_freq_mode) {
+ mutex_unlock(&bus_freq_mutex);
+ return;
+ }
+ reduce_bus_freq();
+
+ mutex_unlock(&bus_freq_mutex);
+}
+
+/* Set the DDR, AHB to 24MHz.
+ * This mode will be activated only when none of the modules that
+ * need a higher DDR or AHB frequency are active.
+ */
+int set_low_bus_freq(void)
+{
+ if (busfreq_suspended)
+ return 0;
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ /* Check to see if we need to get from
+ * low bus freq mode to audio bus freq mode.
+ * If so, the change needs to be done immediately.
+ */
+ if (lp_audio_freq && low_bus_freq_mode)
+ reduce_bus_freq();
+ else
+ /* Don't lower the frequency immediately. Instead
+ * scheduled a delayed work and drop the freq if
+ * the conditions still remain the same.
+ */
+ schedule_delayed_work(&low_bus_freq_handler,
+ usecs_to_jiffies(500000));
+ return 0;
+}
+
+/* Set the DDR to either 528MHz or 400MHz for MX6q
+ * or 400MHz for MX6DL.
+ */
+int set_high_bus_freq(int high_bus_freq)
+{
+ if (bus_freq_scaling_initialized && bus_freq_scaling_is_active)
+ cancel_delayed_work_sync(&low_bus_freq_handler);
+
+ if (busfreq_suspended)
+ return 0;
+
+
+ if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active)
+ return 0;
+
+ if (cpu_is_mx6sl())
+ high_bus_freq = 1;
+
+ if (high_bus_freq_mode && high_bus_freq)
+ return 0;
+
+
+ /* medium bus freq is only supported for MX6DQ */
+ if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq)
+ return 0;
+
+ if (cpu_is_mx6dl() && high_bus_freq)
+ high_bus_freq = 0;
+
+ if (cpu_is_mx6dl() && med_bus_freq_mode)
+ return 0;
+
+ if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) ||
+ (med_bus_freq_mode && !high_bus_freq && lp_med_freq &&
+ !lp_high_freq))
+ return 0;
+
+ if (cpu_is_mx6sl()) {
+ u32 reg;
+ unsigned long flags;
+ u32 ttbr1;
+
+ spin_lock_irqsave(&freq_lock, flags);
+ /* sync the outer cache. */
+ outer_sync();
+
+ ttbr1 = save_ttbr1();
+
+ /* Change DDR freq in IRAM. */
+ mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode);
+
+ restore_ttbr1(ttbr1);
+
+ spin_unlock_irqrestore(&freq_lock, flags);
+
+ /* Set periph_clk to be sourced from pll2_pfd2_400M */
+ /* First need to set the divider before changing the */
+ /* parent if parent clock is larger than previous one */
+ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk,
+ LPAPM_CLK / 3));
+ clk_set_rate(axi_clk,
+ clk_round_rate(axi_clk, LPAPM_CLK / 2));
+ clk_set_parent(periph_clk, pll2_400);
+
+ if (low_bus_freq_mode) {
+ /* Now move ARM to be sourced from PLL2_400 too. */
+ clk_set_parent(pll1_sw_clk, pll2_400);
+
+ /* Ensure that the clock will be at original speed. */
+ reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ clk_disable(pll1);
+ }
+ high_bus_freq_mode = 1;
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+ } else {
+ clk_enable(pll3);
+ if (high_bus_freq) {
+ update_ddr_freq(ddr_normal_rate);
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk, pll2);
+ if (med_bus_freq_mode)
+ clk_disable(pll2_400);
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+ } else {
+ clk_enable(pll2_400);
+ update_ddr_freq(ddr_med_rate);
+ /* Make sure periph clk's parent also got updated */
+ clk_set_parent(periph_clk, pll2_400);
+ high_bus_freq_mode = 0;
+ med_bus_freq_mode = 1;
+ }
+ if (audio_bus_freq_mode)
+ clk_disable(pll2_400);
+
+ /* AXI_CLK is sourced from PLL3_PFD_540 on MX6DL */
+ if (cpu_is_mx6dl() &&
+ clk_get_parent(axi_clk) != pll3_540)
+ clk_set_parent(axi_clk, pll3_540);
+
+ low_bus_freq_mode = 0;
+ audio_bus_freq_mode = 0;
+
+ clk_disable(pll3);
+ }
+ return 0;
+}
+
+int low_freq_bus_used(void)
+{
+ if (!bus_freq_scaling_initialized)
+ return 0;
+
+ /* We only go the lowest setpoint if ARM is also
+ * at the lowest setpoint.
+ */
+ if (high_cpu_freq)
+ return 0;
+
+ if ((lp_high_freq == 0)
+ && (lp_med_freq == 0))
+ return 1;
+ else
+ return 0;
+}
+
+void bus_freq_update(struct clk *clk, bool flag)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (flag) {
+ if (clk == cpu_clk) {
+ /* The CPU freq is being increased.
+ * check if we need to increase the bus freq
+ */
+ high_cpu_freq = 1;
+ if (low_bus_freq_mode || audio_bus_freq_mode)
+ set_high_bus_freq(0);
+ } else {
+ /* Update count */
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq++;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq++;
+ else if (clk->flags & AHB_AUDIO_SET_POINT)
+ lp_audio_freq++;
+ /* Update bus freq */
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 0)) {
+ if (!(clk->flags &
+ (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) {
+ if (low_freq_bus_used())
+ set_low_bus_freq();
+ } else {
+ if ((clk->flags & AHB_MED_SET_POINT)
+ && !med_bus_freq_mode) {
+ /* Set to Medium setpoint */
+ set_high_bus_freq(0);
+ } else if ((clk->flags & AHB_HIGH_SET_POINT)
+ && !high_bus_freq_mode) {
+ /* Currently at low or medium
+ * set point, need to set to
+ * high setpoint
+ */
+ set_high_bus_freq(1);
+ }
+ }
+ }
+ }
+ } else {
+ if (clk == cpu_clk) {
+ /* CPU freq is dropped, check if we can
+ * lower the bus freq.
+ */
+ high_cpu_freq = 0;
+
+ if (low_freq_bus_used() &&
+ !(low_bus_freq_mode || audio_bus_freq_mode))
+ set_low_bus_freq();
+ } else {
+ /* Update count */
+ if (clk->flags & AHB_HIGH_SET_POINT)
+ lp_high_freq--;
+ else if (clk->flags & AHB_MED_SET_POINT)
+ lp_med_freq--;
+ else if (clk->flags & AHB_AUDIO_SET_POINT)
+ lp_audio_freq--;
+ /* Update bus freq */
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 0)) {
+ if (low_freq_bus_used())
+ set_low_bus_freq();
+ else {
+ /* Set to either high or
+ * medium setpoint.
+ */
+ set_high_bus_freq(0);
+ }
+ }
+ }
+ }
+ mutex_unlock(&bus_freq_mutex);
+ return;
+}
+void setup_pll(void)
+{
+}
+
+static ssize_t bus_freq_scaling_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (bus_freq_scaling_is_active)
+ return sprintf(buf, "Bus frequency scaling is enabled\n");
+ else
+ return sprintf(buf, "Bus frequency scaling is disabled\n");
+}
+
+static ssize_t bus_freq_scaling_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strncmp(buf, "1", 1) == 0) {
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q())
+ /*do not enable bus freq*/
+ bus_freq_scaling_is_active = 0;
+ printk(KERN_WARNING "Bus frequency can't be enabled if using VPU 352M!\n");
+ return size;
+#else
+ bus_freq_scaling_is_active = 1;
+#endif
+ set_high_bus_freq(0);
+ /* Make sure system can enter low bus mode if it should be in
+ low bus mode */
+ if (low_freq_bus_used() && !low_bus_freq_mode)
+ set_low_bus_freq();
+ } else if (strncmp(buf, "0", 1) == 0) {
+ if (bus_freq_scaling_is_active)
+ set_high_bus_freq(1);
+ bus_freq_scaling_is_active = 0;
+ }
+ return size;
+}
+
+static int busfreq_suspend(struct platform_device *pdev, pm_message_t message)
+{
+ return 0;
+}
+
+static int bus_freq_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ mutex_lock(&bus_freq_mutex);
+
+ if (event == PM_SUSPEND_PREPARE) {
+ set_high_bus_freq(1);
+ busfreq_suspended = 1;
+ } else if (event == PM_POST_SUSPEND) {
+ busfreq_suspended = 0;
+ }
+
+ mutex_unlock(&bus_freq_mutex);
+
+ return NOTIFY_OK;
+}
+static int busfreq_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+static struct notifier_block imx_bus_freq_pm_notifier = {
+ .notifier_call = bus_freq_pm_notify,
+};
+
+static DEVICE_ATTR(enable, 0644, bus_freq_scaling_enable_show,
+ bus_freq_scaling_enable_store);
+
+/*!
+ * This is the probe routine for the bus frequency driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+
+static int __devinit busfreq_probe(struct platform_device *pdev)
+{
+ u32 err;
+
+ busfreq_dev = &pdev->dev;
+
+ pll2_400 = clk_get(NULL, "pll2_pfd_400M");
+ if (IS_ERR(pll2_400)) {
+ printk(KERN_DEBUG "%s: failed to get pll2_pfd_400M\n",
+ __func__);
+ return PTR_ERR(pll2_400);
+ }
+
+ pll2_200 = clk_get(NULL, "pll2_200M");
+ if (IS_ERR(pll2_200)) {
+ printk(KERN_DEBUG "%s: failed to get pll2_200M\n",
+ __func__);
+ return PTR_ERR(pll2_200);
+ }
+
+ pll2 = clk_get(NULL, "pll2");
+ if (IS_ERR(pll2)) {
+ printk(KERN_DEBUG "%s: failed to get pll2\n",
+ __func__);
+ return PTR_ERR(pll2);
+ }
+
+ pll1 = clk_get(NULL, "pll1_main_clk");
+ if (IS_ERR(pll1)) {
+ printk(KERN_DEBUG "%s: failed to get pll1\n",
+ __func__);
+ return PTR_ERR(pll1);
+ }
+
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (IS_ERR(pll1_sw_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n",
+ __func__);
+ return PTR_ERR(pll1_sw_clk);
+ }
+
+
+ if (IS_ERR(pll2)) {
+ printk(KERN_DEBUG "%s: failed to get pll2\n",
+ __func__);
+ return PTR_ERR(pll2);
+ }
+
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_DEBUG "%s: failed to get cpu_clk\n",
+ __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ pll3 = clk_get(NULL, "pll3_main_clk");
+ if (IS_ERR(pll3)) {
+ printk(KERN_DEBUG "%s: failed to get pll3\n",
+ __func__);
+ return PTR_ERR(pll3);
+ }
+
+ pll3_540 = clk_get(NULL, "pll3_pfd_540M");
+ if (IS_ERR(pll3_540)) {
+ printk(KERN_DEBUG "%s: failed to get periph_clk\n",
+ __func__);
+ return PTR_ERR(pll3_540);
+ }
+
+ pll3_sw_clk = clk_get(NULL, "pll3_sw_clk");
+ if (IS_ERR(pll3_sw_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll3_sw_clk\n",
+ __func__);
+ return PTR_ERR(pll3_sw_clk);
+ }
+
+ axi_clk = clk_get(NULL, "axi_clk");
+ if (IS_ERR(axi_clk)) {
+ printk(KERN_DEBUG "%s: failed to get axi_clk\n",
+ __func__);
+ return PTR_ERR(axi_clk);
+ }
+
+ ahb_clk = clk_get(NULL, "ahb");
+ if (IS_ERR(ahb_clk)) {
+ printk(KERN_DEBUG "%s: failed to get ahb_clk\n",
+ __func__);
+ return PTR_ERR(ahb_clk);
+ }
+
+ periph_clk = clk_get(NULL, "periph_clk");
+ if (IS_ERR(periph_clk)) {
+ printk(KERN_DEBUG "%s: failed to get periph_clk\n",
+ __func__);
+ return PTR_ERR(periph_clk);
+ }
+
+ osc_clk = clk_get(NULL, "osc");
+ if (IS_ERR(osc_clk)) {
+ printk(KERN_DEBUG "%s: failed to get osc_clk\n",
+ __func__);
+ return PTR_ERR(osc_clk);
+ }
+
+ mmdc_ch0_axi = clk_get(NULL, "mmdc_ch0_axi");
+ if (IS_ERR(mmdc_ch0_axi)) {
+ printk(KERN_DEBUG "%s: failed to get mmdc_ch0_axi\n",
+ __func__);
+ return PTR_ERR(mmdc_ch0_axi);
+ }
+
+ err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+ if (err) {
+ printk(KERN_ERR
+ "Unable to register sysdev entry for BUSFREQ");
+ return err;
+ }
+
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ low_bus_freq_mode = 0;
+ if (cpu_is_mx6dl()) {
+ high_bus_freq_mode = 0;
+ med_bus_freq_mode = 1;
+ /* To make pll2_400 use count right, as when
+ system enter 24M, it will disable pll2_400 */
+ clk_enable(pll2_400);
+ } else if (cpu_is_mx6sl()) {
+ /* Set med_bus_freq_mode to 1 since med_bus_freq_mode
+ is not supported as yet for MX6SL */
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 1;
+ } else {
+ high_bus_freq_mode = 1;
+ med_bus_freq_mode = 0;
+ }
+ bus_freq_scaling_is_active = 0;
+ bus_freq_scaling_initialized = 1;
+
+ if (cpu_is_mx6q()) {
+ ddr_low_rate = LPAPM_CLK;
+ ddr_med_rate = DDR_MED_CLK;
+ ddr_normal_rate = DDR3_NORMAL_CLK;
+ }
+ if (cpu_is_mx6dl() || cpu_is_mx6sl()) {
+ ddr_low_rate = LPAPM_CLK;
+ ddr_normal_rate = ddr_med_rate = DDR_MED_CLK;
+ }
+
+ INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler);
+ register_pm_notifier(&imx_bus_freq_pm_notifier);
+
+ if (!cpu_is_mx6sl())
+ init_mmdc_settings();
+ else {
+ /* Use preallocated memory */
+ mx6sl_wfi_iram_phys_addr = MX6SL_WFI_IRAM_CODE;
+
+ /*
+ * Don't ioremap the address, we have fixed the IRAM address
+ * at IRAM_BASE_ADDR_VIRT
+ */
+ mx6sl_wfi_iram_base = (void *)IRAM_BASE_ADDR_VIRT +
+ (mx6sl_wfi_iram_phys_addr - IRAM_BASE_ADDR);
+
+ memcpy(mx6sl_wfi_iram_base, mx6sl_wait, MX6SL_WFI_IRAM_CODE_SIZE);
+ mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base;
+
+ /* Use preallocated memory */
+ mx6sl_ddr_freq_phys_addr = MX6_DDR_FREQ_IRAM_CODE;
+
+ /*
+ * Don't ioremap the address, we have fixed the IRAM address
+ * at IRAM_BASE_ADDR_VIRT
+ */
+ mx6sl_ddr_freq_base = (void *)IRAM_BASE_ADDR_VIRT +
+ (mx6sl_ddr_freq_phys_addr - IRAM_BASE_ADDR);
+
+ memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, MX6SL_DDR_FREQ_CODE_SIZE);
+ mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base;
+ }
+
+ return 0;
+}
+
+static struct platform_driver busfreq_driver = {
+ .driver = {
+ .name = "imx_busfreq",
+ },
+ .probe = busfreq_probe,
+ .suspend = busfreq_suspend,
+ .resume = busfreq_resume,
+};
+
+/*!
+ * Initialise the busfreq_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init busfreq_init(void)
+{
+ if (platform_driver_register(&busfreq_driver) != 0) {
+ printk(KERN_ERR "busfreq_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "Bus freq driver module loaded\n");
+
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q())
+ bus_freq_scaling_is_active = 0;/*disable bus_freq*/
+
+#else
+ /* Enable busfreq by default. */
+ bus_freq_scaling_is_active = 1;
+#endif
+ if (cpu_is_mx6q())
+ set_high_bus_freq(1);
+ else if (cpu_is_mx6dl())
+ set_high_bus_freq(0);
+
+ printk(KERN_INFO "Bus freq driver Enabled\n");
+ return 0;
+}
+
+static void __exit busfreq_cleanup(void)
+{
+ sysfs_remove_file(&busfreq_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&busfreq_driver);
+ bus_freq_scaling_initialized = 0;
+}
+
+late_initcall(busfreq_init);
+module_exit(busfreq_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("BusFreq driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
new file mode 100644
index 00000000..9d3dbfa2
--- /dev/null
+++ b/arch/arm/mach-mx6/clock.c
@@ -0,0 +1,5736 @@
+
+/*
+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/regulator/consumer.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/ahci_sata.h>
+#include <mach/mxc_hdmi.h>
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "regs-anadig.h"
+
+#ifdef CONFIG_CLK_DEBUG
+#define __INIT_CLK_DEBUG(n) .name = #n,
+#else
+#define __INIT_CLK_DEBUG(n)
+#endif
+
+extern u32 arm_max_freq;
+extern int mxc_jtag_enabled;
+extern struct regulator *cpu_regulator;
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern int lp_high_freq;
+extern int lp_med_freq;
+extern int wait_mode_arm_podf;
+extern int lp_audio_freq;
+extern int cur_arm_podf;
+extern bool enet_is_active;
+
+void __iomem *apll_base;
+
+static void __iomem *timer_base;
+static struct clk ipu1_clk;
+static struct clk ipu2_clk;
+static struct clk axi_clk;
+static struct clk pll1_sys_main_clk;
+static struct clk pll2_528_bus_main_clk;
+static struct clk pll2_pfd_400M;
+static struct clk pll2_pfd_352M;
+static struct clk pll3_pfd_540M;
+static struct clk pll2_pfd_594M;
+static struct clk pll3_usb_otg_main_clk;
+static struct clk pll4_audio_main_clk;
+static struct clk pll5_video_main_clk;
+static struct clk pll6_mlb150_main_clk;
+static struct clk pll7_usb_host_main_clk;
+static struct clk pll8_enet_main_clk;
+static struct clk apbh_dma_clk;
+static struct clk openvg_axi_clk;
+static struct clk enfc_clk;
+static struct clk usdhc3_clk;
+static struct clk ipg_clk;
+static struct clk gpt_clk[];
+static struct clk clko2_clk;
+
+static struct cpu_op *cpu_op_tbl;
+static int cpu_op_nr;
+static bool pll1_enabled;
+static bool arm_needs_pll2_400;
+
+#define SPIN_DELAY 1200000 /* in nanoseconds */
+
+#define AUDIO_VIDEO_MIN_CLK_FREQ 650000000
+#define AUDIO_VIDEO_MAX_CLK_FREQ 1300000000
+DEFINE_SPINLOCK(clk_lock);
+#define V2_TCN 0x24
+#define V2_TSTAT 0x08
+#define V2_TSTAT_ROV (1 << 5)
+#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
+#define MXC_TCTL 0x00
+#define MXC_TPRER 0x04
+#define V2_TPRER_PRE24M_OFFSET 12
+#define V2_TPRER_PRE24M_MASK 0xF
+
+/* We need to check the exp status again after timer expiration,
+ * as there might be interrupt coming between the first time exp
+ * and the time reading, then the time reading may be several ms
+ * after the exp checking due to the irq handle, so we need to
+ * check it to make sure the exp return the right value after
+ * timer expiration. */
+#define WAIT(exp, timeout) \
+({ \
+ u32 gpt_rate; \
+ u32 gpt_ticks; \
+ u32 gpt_cnt; \
+ u32 reg; \
+ int result = 1; \
+ gpt_rate = clk_get_rate(&gpt_clk[0]); \
+ gpt_ticks = timeout / (1000000000 / gpt_rate); \
+ reg = __raw_readl(timer_base + V2_TSTAT);\
+ /* Clear the GPT roll over interrupt. */ \
+ if (reg & V2_TSTAT_ROV) { \
+ __raw_writel(V2_TSTAT_ROV, timer_base + V2_TSTAT);\
+ } \
+ gpt_cnt = __raw_readl(timer_base + V2_TCN); \
+ while (!(exp)) { \
+ if ((__raw_readl(timer_base + V2_TCN) - gpt_cnt) > gpt_ticks) { \
+ if (!exp) \
+ result = 0; \
+ break; \
+ } else { \
+ reg = __raw_readl(timer_base + V2_TSTAT);\
+ if (reg & V2_TSTAT_ROV) { \
+ u32 old_cnt = gpt_cnt; \
+ /* Timer has rolled over. \
+ * Calculate the new tick count. \
+ */ \
+ gpt_cnt = __raw_readl(timer_base + V2_TCN); \
+ gpt_ticks -= (0xFFFFFFFF - old_cnt + gpt_cnt); \
+ /* Clear the roll over interrupt. */ \
+ __raw_writel(V2_TSTAT_ROV, \
+ timer_base + V2_TSTAT); \
+ } \
+ } \
+ } \
+ result; \
+})
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+static unsigned long anaclk_1_reference, anaclk_2_reference;
+
+/* For MX 6DL/S, Video PLL may be used by synchronous display devices,
+ * such as HDMI or LVDS, and also by the EPDC. If EPDC is in use,
+ * it must use the Video PLL to achieve the clock frequencies it needs.
+ * So if EPDC is in use, the "epdc" string should be added to kernel
+ * parameters, in order to set the EPDC parent clock to the Video PLL.
+ * This will have an impact on the behavior of HDMI and LVDS.
+ */
+int epdc_enabled;
+static int __init epdc_setup(char *__unused)
+{
+ epdc_enabled = 1;
+ return 1;
+}
+__setup("epdc", epdc_setup);
+
+static void __calc_pre_post_dividers(u32 max_podf, u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ /* Some of the podfs are 3 bits while others are 6 bits.
+ * Handle both cases here.
+ */
+ if (div >= 512 && (max_podf == 64)) {
+ /* For pre = 3bits and podf = 6 bits, max divider is 512. */
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64 && (max_podf == 8)) {
+ /* For pre = 3bits and podf = 3 bits, max divider is 64. */
+ *pre = 8;
+ *post = 8;
+ } else if (div >= 8) {
+ /* Find the minimum pre-divider for a max podf */
+ if (max_podf == 64)
+ min_pre = (div - 1) / (1 << 6) + 1;
+ else
+ min_pre = (div - 1) / (1 << 3) + 1;
+ old_err = 8;
+ /* Now loop through to find the max pre-divider. */
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div < 8) {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGRx_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return 0;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_sys_main_clk)
+ return PLL1_SYS_BASE_ADDR;
+ else if (pll == &pll2_528_bus_main_clk)
+ return PLL2_528_BASE_ADDR;
+ else if (pll == &pll3_usb_otg_main_clk)
+ return PLL3_480_USB1_BASE_ADDR;
+ else if (pll == &pll4_audio_main_clk)
+ return PLL4_AUDIO_BASE_ADDR;
+ else if (pll == &pll5_video_main_clk)
+ return PLL5_VIDEO_BASE_ADDR;
+ else if (pll == &pll6_mlb150_main_clk)
+ return PLL6_MLB_BASE_ADDR;
+ else if (pll == &pll7_usb_host_main_clk)
+ return PLL7_480_USB2_BASE_ADDR;
+ else if (pll == &pll8_enet_main_clk)
+ return PLL8_ENET_BASE_ADDR;
+ else
+ BUG();
+ return NULL;
+}
+
+
+/*
+ * For the 6-to-1 muxed input clock
+ */
+static inline u32 _get_mux6(struct clk *parent, struct clk *m0, struct clk *m1,
+ struct clk *m2, struct clk *m3, struct clk *m4,
+ struct clk *m5)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else if (parent == m4)
+ return 4;
+ else if (parent == m5)
+ return 5;
+ else
+ BUG();
+
+ return 0;
+}
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+static unsigned long _clk_anaclk_1_get_rate(struct clk *clk)
+{
+ return anaclk_1_reference;
+}
+
+static int _clk_anaclk_1_set_rate(struct clk *clk, unsigned long rate)
+{
+ anaclk_1_reference = rate;
+ return 0;
+}
+
+static unsigned long _clk_anaclk_2_get_rate(struct clk *clk)
+{
+ return anaclk_2_reference;
+}
+
+static int _clk_anaclk_2_set_rate(struct clk *clk, unsigned long rate)
+{
+ anaclk_2_reference = rate;
+ return 0;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ __INIT_CLK_DEBUG(ckih_clk)
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ __INIT_CLK_DEBUG(ckih2_clk)
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ __INIT_CLK_DEBUG(osc_clk)
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ __INIT_CLK_DEBUG(ckil_clk)
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk anaclk_1 = {
+ __INIT_CLK_DEBUG(anaclk_1)
+ .get_rate = _clk_anaclk_1_get_rate,
+ .set_rate = _clk_anaclk_1_set_rate,
+};
+
+static struct clk anaclk_2 = {
+ __INIT_CLK_DEBUG(anaclk_2)
+ .get_rate = _clk_anaclk_2_get_rate,
+ .set_rate = _clk_anaclk_2_set_rate,
+};
+
+static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ tmp += rate/2;
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 12 ? 12 : frac;
+ frac = frac > 35 ? 35 : frac;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ do_div(tmp, frac);
+ return tmp;
+}
+
+static unsigned long pfd_get_rate(struct clk *clk)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+
+ frac = (__raw_readl(clk->enable_reg) >> clk->enable_shift) &
+ ANADIG_PFD_FRAC_MASK;
+
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int pfd_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+
+ /* Round up the divider so that we don't set a rate
+ * higher than what is requested. */
+ tmp += rate/2;
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 12 ? 12 : frac;
+ frac = frac > 35 ? 35 : frac;
+ /* clear clk frac bits */
+ __raw_writel(ANADIG_PFD_FRAC_MASK << clk->enable_shift,
+ (int)clk->enable_reg + 8);
+ /* set clk frac bits */
+ __raw_writel(frac << clk->enable_shift,
+ (int)clk->enable_reg + 4);
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+ return 0;
+}
+
+static int _clk_pfd_enable(struct clk *clk)
+{
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+
+ /* clear clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ (int)clk->enable_reg + 8);
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+
+ return 0;
+}
+
+static void _clk_pfd_disable(struct clk *clk)
+{
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.enable(&apbh_dma_clk);
+
+ /* set clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ (int)clk->enable_reg + 4);
+
+ if (apbh_dma_clk.usecount == 0)
+ apbh_dma_clk.disable(&apbh_dma_clk);
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ reg &= ~ANADIG_PLL_POWER_DOWN;
+
+ /* The 480MHz PLLs have the opposite definition for power bit. */
+ if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk)
+ reg |= ANADIG_PLL_POWER_DOWN;
+
+ __raw_writel(reg, pllbase);
+
+ /* It will power on pll3 */
+ if (clk == &pll3_usb_otg_main_clk)
+ __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_CLR);
+
+ /* Wait for PLL to lock */
+ if (!WAIT((__raw_readl(pllbase) & ANADIG_PLL_LOCK),
+ SPIN_DELAY))
+ panic("pll enable failed\n");
+
+ /* Enable the PLL output now*/
+ reg = __raw_readl(pllbase);
+ reg &= ~ANADIG_PLL_BYPASS;
+ reg |= ANADIG_PLL_ENABLE;
+ __raw_writel(reg, pllbase);
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ if ((arm_needs_pll2_400) && (clk == &pll2_528_bus_main_clk))
+ return;
+ /*
+ * To support USB remote wake up, need always keep power and enable bit
+ * BM_ANADIG_ANA_MISC2_CONTROL0 will power off PLL3's power
+ * Please see TKT064178 for detail.
+ */
+ if (clk == &pll3_usb_otg_main_clk) {
+ __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET);
+ return;
+ }
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ reg |= ANADIG_PLL_BYPASS;
+ reg &= ~ANADIG_PLL_ENABLE;
+
+ __raw_writel(reg, pllbase);
+
+}
+
+static unsigned long _clk_pll1_main_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ /* If PLL1 is bypassed, its rate will be from OSC directly */
+ if (__raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_SYS_BYPASS_MASK)
+ return clk_get_rate(clk->parent);
+
+ div = __raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ val = (clk_get_rate(clk->parent) * div) / 2;
+ return val;
+}
+
+static int _clk_pll1_main_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate < AUDIO_VIDEO_MIN_CLK_FREQ || rate > AUDIO_VIDEO_MAX_CLK_FREQ)
+ return -EINVAL;
+
+ div = (rate * 2) / clk_get_rate(clk->parent);
+
+ /* Update div */
+ reg = __raw_readl(PLL1_SYS_BASE_ADDR) & ~ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL1_SYS_BASE_ADDR);
+
+ /* Wait for PLL1 to lock */
+ if (!WAIT((__raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_LOCK),
+ SPIN_DELAY))
+ panic("pll1 enable failed\n");
+
+ return 0;
+}
+
+static void _clk_pll1_disable(struct clk *clk)
+{
+ void __iomem *pllbase;
+ u32 reg;
+
+ pll1_enabled = false;
+
+ /* Set PLL1 in bypass mode only. */
+ /* We need to be able to set the ARM-PODF bit
+ * when the system enters WAIT mode. And setting
+ * this bit requires PLL1_main to be enabled.
+ */
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ reg |= ANADIG_PLL_BYPASS;
+ __raw_writel(reg, pllbase);
+}
+
+static int _clk_pll1_enable(struct clk *clk)
+{
+ _clk_pll_enable(clk);
+ pll1_enabled = true;
+ return 0;
+}
+
+static struct clk pll1_sys_main_clk = {
+ __INIT_CLK_DEBUG(pll1_sys_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll1_main_get_rate,
+ .set_rate = _clk_pll1_main_set_rate,
+ .enable = _clk_pll1_enable,
+ .disable = _clk_pll1_disable,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_sys_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set the step_clk parent to be lp_apm, to save power. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL);
+ } else {
+ /* Set STEP_CLK to be the parent*/
+ if (parent == &osc_clk) {
+ /* Set STEP_CLK to be sourced from LPAPM. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ } else {
+ /* Set STEP_CLK to be sourced from PLL2-PDF (400MHz). */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_STEP_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static unsigned long _clk_pll1_sw_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk pll1_sw_clk = {
+ __INIT_CLK_DEBUG(pll1_sw_clk)
+ .parent = &pll1_sys_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = _clk_pll1_sw_get_rate,
+};
+
+static unsigned long _clk_pll2_main_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL2_528_BASE_ADDR) & ANADIG_PLL_528_DIV_SELECT;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+
+ else
+ val = clk_get_rate(clk->parent) * 20;
+
+ return val;
+}
+
+static int _clk_pll2_main_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL2_528_BASE_ADDR);
+ reg &= ~ANADIG_PLL_528_DIV_SELECT;
+ reg |= div;
+ __raw_writel(reg, PLL2_528_BASE_ADDR);
+
+ return 0;
+}
+
+static struct clk pll2_528_bus_main_clk = {
+ __INIT_CLK_DEBUG(pll2_528_bus_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll2_main_get_rate,
+ .set_rate = _clk_pll2_main_set_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static void _clk_pll2_pfd_400M_disable(struct clk *clk)
+{
+ if (!arm_needs_pll2_400)
+ _clk_pfd_disable(clk);
+}
+
+static struct clk pll2_pfd_400M = {
+ __INIT_CLK_DEBUG(pll2_pfd_400M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD2_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pll2_pfd_400M_disable,
+ .get_rate = pfd_get_rate,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll2_pfd_352M = {
+ __INIT_CLK_DEBUG(pll2_pfd_352M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD0_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll2_pfd_594M = {
+ __INIT_CLK_DEBUG(pll2_pfd_594M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD1_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static unsigned long _clk_pll2_200M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk pll2_200M = {
+ __INIT_CLK_DEBUG(pll2_200M)
+ .parent = &pll2_pfd_400M,
+ .get_rate = _clk_pll2_200M_get_rate,
+};
+
+static unsigned long _clk_pll3_usb_otg_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL3_480_USB1_BASE_ADDR)
+ & ANADIG_PLL_480_DIV_SELECT_MASK;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+ else
+ val = clk_get_rate(clk->parent) * 20;
+ return val;
+}
+
+static int _clk_pll3_usb_otg_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL3_480_USB1_BASE_ADDR);
+ reg &= ~ANADIG_PLL_480_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL3_480_USB1_BASE_ADDR);
+
+ return 0;
+}
+
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_usb_otg_main_clk = {
+ __INIT_CLK_DEBUG(pll3_usb_otg_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* for USB OTG */
+static struct clk usb_phy1_clk = {
+ __INIT_CLK_DEBUG(usb_phy1_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* For HSIC port 1 */
+static struct clk usb_phy3_clk = {
+ __INIT_CLK_DEBUG(usb_phy3_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* For HSIC port 2 */
+static struct clk usb_phy4_clk = {
+ __INIT_CLK_DEBUG(usb_phy4_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+static struct clk pll3_pfd_508M = {
+ __INIT_CLK_DEBUG(pll3_pfd_508M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD2_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll3_pfd_454M = {
+ __INIT_CLK_DEBUG(pll3_pfd_454M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD3_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll3_pfd_720M = {
+ __INIT_CLK_DEBUG(pll3_pfd_720M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD0_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static int pfd_540M_set_rate(struct clk *clk, unsigned long rate)
+{
+ if ((clk_get_parent(&ipu1_clk) == clk) ||
+ (clk_get_parent(&ipu2_clk) == clk) ||
+ (clk_get_parent(&axi_clk) == clk))
+ WARN(1, "CHANGING rate of 540M PFD when IPU and \
+ AXI is sourced from it \n");
+
+ return pfd_set_rate(clk, rate);
+}
+
+static struct clk pll3_pfd_540M = {
+ __INIT_CLK_DEBUG(pll3_pfd_540M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD1_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_540M_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+ .get_rate = pfd_get_rate,
+};
+
+static unsigned long _clk_pll3_sw_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ __INIT_CLK_DEBUG(pll3_sw_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .get_rate = _clk_pll3_sw_get_rate,
+};
+
+static unsigned long _clk_pll3_120M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+static struct clk pll3_120M = {
+ __INIT_CLK_DEBUG(pll3_120M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_120M_get_rate,
+};
+
+static unsigned long _clk_pll3_80M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 6;
+}
+
+static struct clk pll3_80M = {
+ __INIT_CLK_DEBUG(pll3_80M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_80M_get_rate,
+};
+
+static unsigned long _clk_pll3_60M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 8;
+}
+
+static struct clk pll3_60M = {
+ __INIT_CLK_DEBUG(pll3_60M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_60M_get_rate,
+};
+
+static unsigned long _clk_audio_video_get_rate(struct clk *clk)
+{
+ unsigned int div, mfn, mfd;
+ unsigned long rate;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ void __iomem *pllbase;
+ int rev = mx6q_revision();
+ unsigned int test_div_sel, control3, post_div = 1;
+
+ if (clk == &pll4_audio_main_clk)
+ pllbase = PLL4_AUDIO_BASE_ADDR;
+ else
+ pllbase = PLL5_VIDEO_BASE_ADDR;
+
+ if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
+ test_div_sel = (__raw_readl(pllbase)
+ & ANADIG_PLL_AV_TEST_DIV_SEL_MASK)
+ >> ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET;
+ if (test_div_sel == 0)
+ post_div = 4;
+ else if (test_div_sel == 1)
+ post_div = 2;
+
+ if (clk == &pll5_video_main_clk) {
+ control3 = (__raw_readl(ANA_MISC2_BASE_ADDR)
+ & ANADIG_ANA_MISC2_CONTROL3_MASK)
+ >> ANADIG_ANA_MISC2_CONTROL3_OFFSET;
+ if (control3 == 1)
+ post_div *= 2;
+ else if (control3 == 3)
+ post_div *= 4;
+ }
+ }
+
+ div = __raw_readl(pllbase) & ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ mfn = __raw_readl(pllbase + PLL_NUM_DIV_OFFSET);
+ mfd = __raw_readl(pllbase + PLL_DENOM_DIV_OFFSET);
+
+ rate = (parent_rate * div) + ((parent_rate / mfd) * mfn);
+ rate = rate / post_div;
+
+ return rate;
+}
+
+static int _clk_audio_video_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+ unsigned int mfn, mfd = 1000000;
+ s64 temp64;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ void __iomem *pllbase;
+ unsigned long min_clk_rate, pre_div_rate;
+ int rev = mx6q_revision();
+ u32 test_div_sel = 2;
+ u32 control3 = 0;
+
+ if ((rev < IMX_CHIP_REVISION_1_1) && !cpu_is_mx6dl())
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ;
+ else if (clk == &pll4_audio_main_clk)
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
+ else
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 16;
+
+ if ((rate < min_clk_rate) || (rate > AUDIO_VIDEO_MAX_CLK_FREQ))
+ return -EINVAL;
+
+ if (clk == &pll4_audio_main_clk)
+ pllbase = PLL4_AUDIO_BASE_ADDR;
+ else
+ pllbase = PLL5_VIDEO_BASE_ADDR;
+
+ pre_div_rate = rate;
+ if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
+ while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
+ pre_div_rate *= 2;
+ /*
+ * test_div_sel field values:
+ * 2 -> Divide by 1
+ * 1 -> Divide by 2
+ * 0 -> Divide by 4
+ *
+ * control3 field values:
+ * 0 -> Divide by 1
+ * 1 -> Divide by 2
+ * 3 -> Divide by 4
+ */
+ if (test_div_sel != 0)
+ test_div_sel--;
+ else {
+ control3++;
+ if (control3 == 2)
+ control3++;
+ }
+ }
+ }
+
+ div = pre_div_rate / parent_rate;
+ temp64 = (u64) (pre_div_rate - (div * parent_rate));
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ reg = __raw_readl(pllbase)
+ & ~ANADIG_PLL_SYS_DIV_SELECT_MASK
+ & ~ANADIG_PLL_AV_TEST_DIV_SEL_MASK;
+ reg |= div |
+ (test_div_sel << ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET);
+ __raw_writel(reg, pllbase);
+ __raw_writel(mfn, pllbase + PLL_NUM_DIV_OFFSET);
+ __raw_writel(mfd, pllbase + PLL_DENOM_DIV_OFFSET);
+
+ if ((rev >= IMX_CHIP_REVISION_1_1) &&
+ (pllbase == PLL5_VIDEO_BASE_ADDR)) {
+ reg = __raw_readl(ANA_MISC2_BASE_ADDR)
+ & ~ANADIG_ANA_MISC2_CONTROL3_MASK;
+ reg |= control3 << ANADIG_ANA_MISC2_CONTROL3_OFFSET;
+ __raw_writel(reg, ANA_MISC2_BASE_ADDR);
+ }
+
+ return 0;
+}
+
+static unsigned long _clk_audio_video_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long min_clk_rate;
+ unsigned int div, post_div = 1;
+ unsigned int mfn, mfd = 1000000;
+ s64 temp64;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ unsigned long pre_div_rate;
+ u32 test_div_sel = 2;
+ u32 control3 = 0;
+ unsigned long final_rate;
+ int rev = mx6q_revision();
+
+ if ((rev < IMX_CHIP_REVISION_1_1) && !cpu_is_mx6dl())
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ;
+ else if (clk == &pll4_audio_main_clk)
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
+ else
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 16;
+
+ if (rate < min_clk_rate)
+ return min_clk_rate;
+
+ if (rate > AUDIO_VIDEO_MAX_CLK_FREQ)
+ return AUDIO_VIDEO_MAX_CLK_FREQ;
+
+ pre_div_rate = rate;
+ if ((rev >= IMX_CHIP_REVISION_1_1) || cpu_is_mx6dl()) {
+ while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
+ pre_div_rate *= 2;
+ post_div *= 2;
+ if (test_div_sel != 0)
+ test_div_sel--;
+ else {
+ control3++;
+ if (control3 == 2)
+ control3++;
+ }
+ }
+ }
+
+ div = pre_div_rate / parent_rate;
+ temp64 = (u64) (pre_div_rate - (div * parent_rate));
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ final_rate = (parent_rate * div) + ((parent_rate / mfd) * mfn);
+ final_rate = final_rate / post_div;
+
+ return final_rate;
+}
+
+static int _clk_audio_video_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+ void __iomem *pllbase;
+
+ if (clk == &pll4_audio_main_clk)
+ pllbase = PLL4_AUDIO_BASE_ADDR;
+ else
+ pllbase = PLL5_VIDEO_BASE_ADDR;
+
+ reg = __raw_readl(pllbase) & ~ANADIG_PLL_BYPASS_CLK_SRC_MASK;
+ mux = _get_mux6(parent, &osc_clk, &anaclk_1, &anaclk_2,
+ NULL, NULL, NULL);
+ reg |= mux << ANADIG_PLL_BYPASS_CLK_SRC_OFFSET;
+ __raw_writel(reg, pllbase);
+
+ /* Set anaclk_x as input */
+ if (parent == &anaclk_1) {
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= (ANATOP_LVDS_CLK1_IBEN_MASK &
+ ~ANATOP_LVDS_CLK1_OBEN_MASK);
+ __raw_writel(reg, ANADIG_MISC1_REG);
+ } else if (parent == &anaclk_2) {
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= (ANATOP_LVDS_CLK2_IBEN_MASK &
+ ~ANATOP_LVDS_CLK2_OBEN_MASK);
+ __raw_writel(reg, ANADIG_MISC1_REG);
+ }
+
+ return 0;
+}
+
+static struct clk pll4_audio_main_clk = {
+ __INIT_CLK_DEBUG(pll4_audio_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_audio_video_set_rate,
+ .get_rate = _clk_audio_video_get_rate,
+ .round_rate = _clk_audio_video_round_rate,
+ .set_parent = _clk_audio_video_set_parent,
+};
+
+static struct clk pll5_video_main_clk = {
+ __INIT_CLK_DEBUG(pll5_video_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_audio_video_set_rate,
+ .get_rate = _clk_audio_video_get_rate,
+ .round_rate = _clk_audio_video_round_rate,
+ .set_parent = _clk_audio_video_set_parent,
+};
+
+static int _clk_pll_mlb_main_enable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ reg &= ~ANADIG_PLL_BYPASS;
+
+ reg = (0x3 << ANADIG_PLL_MLB_FLT_RES_CFG_OFFSET) |
+ (0x3 << ANADIG_PLL_MLB_RX_CLK_DELAY_CFG_OFFSET) |
+ (0x2 << ANADIG_PLL_MLB_VDDD_DELAY_CFG_OFFSET) |
+ (0x1 << ANADIG_PLL_MLB_VDDA_DELAY_CFG_OFFSET) |
+ (ANADIG_PLL_HOLD_RING_OFF);
+ __raw_writel(reg, pllbase);
+
+ return 0;
+}
+
+static void _clk_pll_mlb_main_disable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+
+ reg |= ANADIG_PLL_BYPASS;
+
+ __raw_writel(reg, pllbase);
+}
+
+static struct clk pll6_mlb150_main_clk = {
+ __INIT_CLK_DEBUG(pll6_mlb150_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_mlb_main_enable,
+ .disable = _clk_pll_mlb_main_disable,
+};
+
+static unsigned long _clk_pll7_usb_otg_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL7_480_USB2_BASE_ADDR)
+ & ANADIG_PLL_480_DIV_SELECT_MASK;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+ else
+ val = clk_get_rate(clk->parent) * 20;
+ return val;
+}
+
+static int _clk_pll7_usb_otg_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL7_480_USB2_BASE_ADDR);
+ reg &= ~ANADIG_PLL_480_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL7_480_USB2_BASE_ADDR);
+
+ return 0;
+}
+
+static struct clk pll7_usb_host_main_clk = {
+ __INIT_CLK_DEBUG(pll7_usb_host_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll7_usb_otg_set_rate,
+ .get_rate = _clk_pll7_usb_otg_get_rate,
+
+};
+
+static struct clk pll8_enet_main_clk = {
+ __INIT_CLK_DEBUG(pll8_enet_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static unsigned long _clk_arm_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
+{
+ int i;
+ u32 div;
+ unsigned long parent_rate;
+ unsigned long flags;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+ if (i >= cpu_op_nr)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clk_lock, flags);
+
+ if (rate <= clk_get_rate(&pll2_pfd_400M)) {
+ /* Source pll1_sw_clk from step_clk which is sourced from
+ * PLL2_PFD_400M.
+ */
+ if (pll1_sw_clk.parent != &pll2_pfd_400M) {
+ if (pll2_pfd_400M.usecount == 0) {
+ /* Check if PLL2 needs to be enabled also. */
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk);
+ /* Ensure parent usecount is
+ * also incremented.
+ */
+ pll2_528_bus_main_clk.usecount++;
+ pll2_pfd_400M.enable(&pll2_pfd_400M);
+ }
+ pll2_pfd_400M.usecount++;
+ arm_needs_pll2_400 = true;
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
+ pll1_sw_clk.parent = &pll2_pfd_400M;
+ }
+ } else {
+ /* Make sure PLL1 is enabled */
+ if (!pll1_enabled) {
+ pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 1;
+ }
+ /* Make sure PLL1 rate is what we want */
+ if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
+ /* If pll1_sw_clk is from pll1_sys_main_clk, switch it */
+ if (pll1_sw_clk.parent == &pll1_sys_main_clk) {
+ /* Change the PLL1 rate. */
+ if (pll2_pfd_400M.usecount != 0)
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
+ else
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
+ }
+ pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate);
+ }
+ /* Make sure pll1_sw_clk is from pll1_sys_main_clk */
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
+ pll1_sw_clk.parent = &pll1_sys_main_clk;
+ if (arm_needs_pll2_400) {
+ pll2_pfd_400M.usecount--;
+ if (pll2_pfd_400M.usecount == 0) {
+ pll2_pfd_400M.disable(&pll2_pfd_400M);
+ /* Ensure parent usecount is
+ * also decremented.
+ */
+ pll2_528_bus_main_clk.usecount--;
+ if (pll2_528_bus_main_clk.usecount == 0)
+ pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk);
+ }
+ }
+ arm_needs_pll2_400 = false;
+ }
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state. The max ARM clk is decided by the
+ * ipg_clk and has to follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ * For ex, when IPG is at 66MHz, ARM_CLK cannot be greater
+ * than 158MHz.
+ * Pre-calculate the optimal divider now.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
+ if (div == 0)
+ div = 1;
+
+ if ((parent_rate / div) > rate)
+ div++;
+
+ if (div > 8) {
+ spin_unlock_irqrestore(&clk_lock, flags);
+ return -1;
+ }
+
+ cur_arm_podf = div;
+
+ __raw_writel(div - 1, MXC_CCM_CACRR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+
+ if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) {
+ pll1_sys_main_clk.disable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 0;
+ }
+
+ spin_unlock_irqrestore(&clk_lock, flags);
+
+ return 0;
+}
+
+static struct clk cpu_clk = {
+ __INIT_CLK_DEBUG(cpu_clk)
+ .parent = &pll1_sw_clk,
+ .set_rate = _clk_arm_set_rate,
+ .get_rate = _clk_arm_get_rate,
+};
+
+static unsigned long _clk_twd_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk twd_clk = {
+ __INIT_CLK_DEBUG(twd_clk)
+ .parent = &cpu_clk,
+ .get_rate = _clk_twd_get_rate,
+};
+
+static int _clk_periph_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk, &pll2_pfd_400M,
+ &pll2_pfd_352M, &pll2_200M, &pll3_sw_clk, &osc_clk);
+
+ if (mux <= 3) {
+ /* Set the pre_periph_clk multiplexer */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ /* Set the periph_clk_sel multiplexer. */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ } else {
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ /* Set the periph_clk2_podf divider to divide by 1. */
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Set the periph_clk2_sel mux. */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
+ reg |= ((mux - 4) << MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ /* Set periph_clk_sel to select periph_clk2. */
+ reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ }
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY), SPIN_DELAY))
+ panic("_clk_periph_set_parent failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_periph_get_rate(struct clk *clk)
+{
+ u32 div = 1;
+ u32 reg;
+ unsigned long val;
+
+ if ((clk->parent == &pll3_sw_clk) || (clk->parent == &osc_clk)) {
+ reg = __raw_readl(MXC_CCM_CBCDR)
+ & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK;
+ div = (reg >> MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET) + 1;
+ }
+ val = clk_get_rate(clk->parent) / div;
+ return val;
+}
+
+static struct clk periph_clk = {
+ __INIT_CLK_DEBUG(periph_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .set_parent = _clk_periph_set_parent,
+ .get_rate = _clk_periph_get_rate,
+};
+
+static unsigned long _clk_axi_get_rate(struct clk *clk)
+{
+ u32 div, reg;
+ unsigned long val;
+
+ reg = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_AXI_PODF_MASK;
+ div = (reg >> MXC_CCM_CBCDR_AXI_PODF_OFFSET);
+
+ val = clk_get_rate(clk->parent) / (div + 1);
+ return val;
+}
+
+static int _clk_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_AXI_PODF_BUSY), SPIN_DELAY))
+ panic("pll _clk_axi_a_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum
+ * value for the clock.
+ * Also prevent a div of 0.
+ */
+
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+
+ return parent_rate / div;
+}
+
+static int _clk_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+
+ mux = _get_mux6(parent, &periph_clk, &pll2_pfd_400M,
+ &pll3_pfd_540M, NULL, NULL, NULL);
+
+ if (mux == 0) {
+ /* Set the AXI_SEL mux */
+ reg = __raw_readl(MXC_CCM_CBCDR) & ~MXC_CCM_CBCDR_AXI_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ } else {
+ /* Set the AXI_ALT_SEL mux. */
+ reg = __raw_readl(MXC_CCM_CBCDR)
+ & ~MXC_CCM_CBCDR_AXI_ALT_SEL_MASK;
+ reg |= ((mux - 1) << MXC_CCM_CBCDR_AXI_ALT_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Set the AXI_SEL mux */
+ reg = __raw_readl(MXC_CCM_CBCDR) & ~MXC_CCM_CBCDR_AXI_SEL;
+ reg |= MXC_CCM_CBCDR_AXI_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ }
+ return 0;
+}
+
+static struct clk axi_clk = {
+ __INIT_CLK_DEBUG(axi_clk)
+ .parent = &periph_clk,
+ .set_parent = _clk_axi_set_parent,
+ .set_rate = _clk_axi_set_rate,
+ .get_rate = _clk_axi_get_rate,
+ .round_rate = _clk_axi_round_rate,
+};
+
+static unsigned long _clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY),
+ SPIN_DELAY))
+ panic("_clk_ahb_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk ahb_clk = {
+ __INIT_CLK_DEBUG(ahb_clk)
+ .parent = &periph_clk,
+ .get_rate = _clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+};
+
+static unsigned long _clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+
+static struct clk ipg_clk = {
+ __INIT_CLK_DEBUG(ipg_clk)
+ .parent = &ahb_clk,
+ .get_rate = _clk_ipg_get_rate,
+};
+
+static struct clk tzasc1_clk = {
+ __INIT_CLK_DEBUG(tzasc1_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk tzasc2_clk = {
+ __INIT_CLK_DEBUG(tzasc2_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk mx6fast1_clk = {
+ __INIT_CLK_DEBUG(mx6fast1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk mx6per1_clk = {
+ __INIT_CLK_DEBUG(mx6per1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &mx6fast1_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk mx6per2_clk = {
+ __INIT_CLK_DEBUG(mx6per2_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static unsigned long _clk_mmdc_ch0_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
+ MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_mmdc_ch0_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_MMDC_CH0_PODF_BUSY),
+ SPIN_DELAY))
+ panic("_clk_mmdc_ch0_axi_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_mmdc_ch0_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk mmdc_ch0_axi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(mmdc_ch0_axi_clk)
+ .id = 0,
+ .parent = &periph_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .secondary = &mmdc_ch0_axi_clk[1],
+ .get_rate = _clk_mmdc_ch0_axi_get_rate,
+ .set_rate = _clk_mmdc_ch0_axi_set_rate,
+ .round_rate = _clk_mmdc_ch0_axi_round_rate,
+ },
+ {
+ __INIT_CLK_DEBUG(mmdc_ch0_ipg_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .secondary = &tzasc1_clk,
+ },
+};
+
+static unsigned long _clk_mmdc_ch1_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) >>
+ MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_mmdc_ch1_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY), SPIN_DELAY))
+ panic("_clk_mmdc_ch1_axi_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_mmdc_ch1_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk mmdc_ch1_axi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(mmdc_ch1_axi_clk)
+ .id = 0,
+ .parent = &pll2_pfd_400M,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .secondary = &mmdc_ch1_axi_clk[1],
+ .get_rate = _clk_mmdc_ch1_axi_get_rate,
+ .set_rate = _clk_mmdc_ch1_axi_set_rate,
+ .round_rate = _clk_mmdc_ch1_axi_round_rate,
+ },
+ {
+ .id = 1,
+ __INIT_CLK_DEBUG(mmdc_ch1_ipg_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .secondary = &tzasc2_clk,
+ },
+};
+
+static struct clk ocram_clk = {
+ __INIT_CLK_DEBUG(ocram_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static unsigned long _clk_ipg_perclk_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ div = ((reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK) >>
+ MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipg_perclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET;
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+
+static unsigned long _clk_ipg_perclk_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static struct clk ipg_perclk = {
+ __INIT_CLK_DEBUG(ipg_perclk)
+ .parent = &ipg_clk,
+ .get_rate = _clk_ipg_perclk_get_rate,
+ .set_rate = _clk_ipg_perclk_set_rate,
+ .round_rate = _clk_ipg_perclk_round_rate,
+};
+
+static struct clk spba_clk = {
+ __INIT_CLK_DEBUG(spba_clk)
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk sdma_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sdma_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &sdma_clk[1],
+ },
+ {
+ .parent = &mx6per1_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &mmdc_ch0_axi_clk[0],
+#endif
+ },
+};
+
+static int _clk_gpu2d_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_GPU2D_AXI_CLK_SEL;
+
+ if (parent == &ahb_clk)
+ reg |= MXC_CCM_CBCMR_GPU2D_AXI_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu2d_axi_clk = {
+ __INIT_CLK_DEBUG(gpu2d_axi_clk)
+ .parent = &axi_clk,
+ .set_parent = _clk_gpu2d_axi_set_parent,
+};
+
+static int _clk_gpu3d_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL;
+
+ if (parent == &ahb_clk)
+ reg |= MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu3d_axi_clk = {
+ __INIT_CLK_DEBUG(gpu3d_axi_clk)
+ .parent = &axi_clk,
+ .secondary = &mmdc_ch0_axi_clk[0],
+ .set_parent = _clk_gpu3d_axi_set_parent,
+};
+
+static int _clk_pcie_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL;
+
+ if (parent == &ahb_clk)
+ reg |= MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk pcie_axi_clk = {
+ __INIT_CLK_DEBUG(pcie_axi_clk)
+ .parent = &axi_clk,
+ .set_parent = _clk_pcie_axi_set_parent,
+};
+
+static int _clk_vdo_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_VDOAXI_CLK_SEL;
+
+ if (parent == &ahb_clk)
+ reg |= MXC_CCM_CBCMR_VDOAXI_CLK_SEL;
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk vdo_axi_clk = {
+ __INIT_CLK_DEBUG(vdo_axi_clk)
+ .parent = &axi_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_vdo_axi_set_parent,
+};
+
+static struct clk vdoa_clk[] = {
+ {
+ __INIT_CLK_DEBUG(vdoa_clk)
+ .id = 0,
+ .parent = &vdo_axi_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &vdoa_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &vdoa_clk[2],
+ },
+ {
+ .parent = &mx6fast1_clk,
+ .secondary = &ocram_clk,
+ },
+};
+
+static unsigned long mx6_timer_rate(void)
+{
+ u32 parent_rate = clk_get_rate(&osc_clk);
+
+ u32 reg = __raw_readl(timer_base + MXC_TCTL);
+ u32 div;
+
+ if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) {
+ if (cpu_is_mx6q())
+ /* For MX6Q, only options are 24MHz or 24MHz/8*/
+ return parent_rate / 8;
+ else {
+ /* For MX6DLS and MX6Solo, the rate is based on the
+ * divider value set in prescalar register. */
+ div = __raw_readl(timer_base + MXC_TPRER);
+ div = (div >> V2_TPRER_PRE24M_OFFSET) &
+ V2_TPRER_PRE24M_MASK;
+ return parent_rate / (div + 1);
+ }
+ }
+ return 0;
+}
+
+static unsigned long _clk_gpt_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0)
+ return clk_get_rate(clk->parent);
+
+ rate = mx6_timer_rate();
+ if (!rate)
+ return clk_get_rate(clk->parent);
+
+ return rate;
+}
+
+static struct clk gpt_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpt_clk)
+ .parent = &osc_clk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .get_rate = _clk_gpt_get_rate,
+ .secondary = &gpt_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(gpt_serial_clk)
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_iim_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk iim_clk = {
+ __INIT_CLK_DEBUG(iim_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ .get_rate = _clk_iim_get_rate,
+};
+
+static struct clk i2c_clk[] = {
+ {
+ __INIT_CLK_DEBUG(i2c_clk_0)
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_1)
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_2)
+ .id = 2,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_vpu_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR)
+ & ~MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &axi_clk, &pll2_pfd_400M,
+ &pll2_pfd_352M, NULL, NULL, NULL);
+
+ reg |= (mux << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long _clk_vpu_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK) >>
+ MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_vpu_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static unsigned long _clk_vpu_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk vpu_clk[] = {
+ {
+ __INIT_CLK_DEBUG(vpu_clk)
+ .parent = &axi_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_vpu_axi_set_parent,
+ .round_rate = _clk_vpu_axi_round_rate,
+ .set_rate = _clk_vpu_axi_set_rate,
+ .get_rate = _clk_vpu_axi_get_rate,
+ .secondary = &vpu_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &vpu_clk[2],
+ },
+ {
+ .parent = &mx6fast1_clk,
+ .secondary = &ocram_clk,
+ },
+};
+
+static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCDR3)
+ & ~MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll2_pfd_400M, &pll3_120M, &pll3_pfd_540M, NULL, NULL);
+
+ reg |= (mux << MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ div = ((reg & MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK) >>
+ MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ reg &= ~MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk ipu1_clk = {
+ __INIT_CLK_DEBUG(ipu1_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mmdc_ch0_axi_clk[0],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu1_set_parent,
+ .round_rate = _clk_ipu_round_rate,
+ .set_rate = _clk_ipu1_set_rate,
+ .get_rate = _clk_ipu1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_ipu2_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCDR3)
+ & ~MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll2_pfd_400M, &pll3_120M, &pll3_pfd_540M, NULL, NULL);
+
+ reg |= (mux << MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu2_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ div = ((reg & MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK) >>
+ MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ reg &= ~MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static struct clk ipu2_clk = {
+ __INIT_CLK_DEBUG(ipu2_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mmdc_ch0_axi_clk[0],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu2_set_parent,
+ .round_rate = _clk_ipu_round_rate,
+ .set_rate = _clk_ipu2_set_rate,
+ .get_rate = _clk_ipu2_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk usdhc_dep_clk = {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ };
+
+static unsigned long _clk_usdhc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_usdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
+
+ if (parent == &pll2_pfd_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC1_CLK_SEL);
+
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk usdhc1_clk = {
+ __INIT_CLK_DEBUG(usdhc1_clk)
+ .id = 0,
+ .parent = &pll2_pfd_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc1_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc1_set_rate,
+ .get_rate = _clk_usdhc1_get_rate,
+};
+
+static int _clk_usdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
+
+ if (parent == &pll2_pfd_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC2_CLK_SEL);
+
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc2_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC2_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk usdhc2_clk = {
+ __INIT_CLK_DEBUG(usdhc2_clk)
+ .id = 1,
+ .parent = &pll2_pfd_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc2_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc2_set_rate,
+ .get_rate = _clk_usdhc2_get_rate,
+};
+
+static int _clk_usdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
+
+ if (parent == &pll2_pfd_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC3_CLK_SEL);
+
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc3_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC3_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+
+static struct clk usdhc3_clk = {
+ __INIT_CLK_DEBUG(usdhc3_clk)
+ .id = 2,
+ .parent = &pll2_pfd_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc3_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc3_set_rate,
+ .get_rate = _clk_usdhc3_get_rate,
+};
+
+static int _clk_usdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
+
+ if (parent == &pll2_pfd_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC4_CLK_SEL);
+
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc4_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc4_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC4_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+
+static struct clk usdhc4_clk = {
+ __INIT_CLK_DEBUG(usdhc4_clk)
+ .id = 3,
+ .parent = &pll2_pfd_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc4_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc4_set_rate,
+ .get_rate = _clk_usdhc4_get_rate,
+};
+
+static unsigned long _clk_ssi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK |
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd_508M, &pll3_pfd_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET);
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk = {
+ __INIT_CLK_DEBUG(ssi1_clk)
+ .parent = &pll3_pfd_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi1_set_parent,
+ .set_rate = _clk_ssi1_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi1_get_rate,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &mmdc_ch0_axi_clk[0],
+#endif
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK)
+ >> MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK)
+ >> MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~(MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK |
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd_508M, &pll3_pfd_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET);
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk = {
+ __INIT_CLK_DEBUG(ssi2_clk)
+ .parent = &pll3_pfd_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi2_set_parent,
+ .set_rate = _clk_ssi2_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi2_get_rate,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &mmdc_ch0_axi_clk[0],
+#endif
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_ssi3_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK|
+ MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+
+static int _clk_ssi3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd_508M, &pll3_pfd_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET);
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi3_clk = {
+ __INIT_CLK_DEBUG(ssi3_clk)
+ .parent = &pll3_pfd_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi3_set_parent,
+ .set_rate = _clk_ssi3_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi3_get_rate,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &mmdc_ch0_axi_clk[0],
+#endif
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_ldb_di_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate * 7 <= parent_rate + parent_rate/20)
+ return parent_rate / 7;
+ else
+ return 2 * parent_rate / 7;
+}
+
+static unsigned long _clk_ldb_di0_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(MXC_CCM_CSCMR2) &
+ MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+
+ if (div)
+ return clk_get_rate(clk->parent) / 7;
+
+ return (2 * clk_get_rate(clk->parent)) / 7;
+}
+
+static int _clk_ldb_di0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div = 0;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate * 7 <= parent_rate + parent_rate/20) {
+ div = 7;
+ rate = parent_rate / 7;
+ } else
+ rate = 2 * parent_rate / 7;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ if (div == 7)
+ reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+ else
+ reg &= ~MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static int _clk_ldb_di0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ int rev = mx6q_revision();
+
+ reg = __raw_readl(MXC_CCM_CS2CDR)
+ & ~MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M,
+ (rev == IMX_CHIP_REVISION_1_0) ?
+ &pll3_pfd_540M : /* MX6Q TO1.0 */
+ &mmdc_ch1_axi_clk[0], /* MX6Q TO1.1 and MX6DL */
+ &pll3_usb_otg_main_clk, NULL);
+ reg |= (mux << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+static struct clk ldb_di0_clk = {
+ __INIT_CLK_DEBUG(ldb_di0_clk)
+ .id = 0,
+ .parent = &pll2_pfd_352M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ldb_di0_set_parent,
+ .set_rate = _clk_ldb_di0_set_rate,
+ .round_rate = _clk_ldb_di_round_rate,
+ .get_rate = _clk_ldb_di0_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_ldb_di1_get_rate(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(MXC_CCM_CSCMR2) &
+ MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+
+ if (div)
+ return clk_get_rate(clk->parent) / 7;
+
+ return (2 * clk_get_rate(clk->parent)) / 7;
+}
+
+static int _clk_ldb_di1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div = 0;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate * 7 <= parent_rate + parent_rate/20) {
+ div = 7;
+ rate = parent_rate / 7;
+ } else
+ rate = 2 * parent_rate / 7;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ if (div == 7)
+ reg |= MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+ else
+ reg &= ~MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static int _clk_ldb_di1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ int rev = mx6q_revision();
+
+ reg = __raw_readl(MXC_CCM_CS2CDR)
+ & ~MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M,
+ (rev == IMX_CHIP_REVISION_1_0) ?
+ &pll3_pfd_540M : /* MX6Q TO1.0 */
+ &mmdc_ch1_axi_clk[0], /* MX6Q TO1.1 and MX6DL */
+ &pll3_usb_otg_main_clk, NULL);
+ reg |= (mux << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+static struct clk ldb_di1_clk = {
+ __INIT_CLK_DEBUG(ldb_di1_clk)
+ .id = 0,
+ .parent = &pll2_pfd_352M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ldb_di1_set_parent,
+ .set_rate = _clk_ldb_di1_set_rate,
+ .round_rate = _clk_ldb_di_round_rate,
+ .get_rate = _clk_ldb_di1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+
+static unsigned long _clk_ipu_di_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk))
+ return parent_rate;
+
+ div = parent_rate / rate;
+ /* Round to closest divisor */
+ if ((parent_rate % rate) > (rate / 2))
+ div++;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static unsigned long _clk_ipu1_di0_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk))
+ return clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+
+ div = ((reg & MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK) >>
+ MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu1_di0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk)) {
+ if (parent_rate == rate)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+ reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+
+static int _clk_ipu1_di0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (parent == &ldb_di0_clk)
+ mux = 0x3;
+ else if (parent == &ldb_di1_clk)
+ mux = 0x4;
+ else {
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, &pll3_pfd_540M);
+ reg |= (mux << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ /* Derive clock from divided pre-muxed ipu1_di0 clock.*/
+ mux = 0;
+ }
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET),
+ MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu1_di1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk))
+ return clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+
+ div = ((reg & MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK)
+ >> MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu1_di1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk)) {
+ if (parent_rate == rate)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+ reg &= ~MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+
+static int _clk_ipu1_di1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (parent == &ldb_di0_clk)
+ mux = 0x3;
+ else if (parent == &ldb_di1_clk)
+ mux = 0x4;
+ else {
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, &pll3_pfd_540M);
+ reg |= (mux << MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ /* Derive clock from divided pre-muxed ipu1_di0 clock.*/
+ mux = 0;
+ }
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET),
+ MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static struct clk ipu1_di_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ipu1_di_clk_0)
+ .id = 0,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu1_di0_set_parent,
+ .set_rate = _clk_ipu1_di0_set_rate,
+ .round_rate = _clk_ipu_di_round_rate,
+ .get_rate = _clk_ipu1_di0_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(ipu1_di_clk_1)
+ .id = 1,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu1_di1_set_parent,
+ .set_rate = _clk_ipu1_di1_set_rate,
+ .round_rate = _clk_ipu_di_round_rate,
+ .get_rate = _clk_ipu1_di1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+};
+
+static unsigned long _clk_ipu2_di0_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk))
+ return clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+
+ div = ((reg & MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK) >>
+ MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu2_di0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk)) {
+ if (parent_rate == rate)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static int _clk_ipu2_di0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (parent == &ldb_di0_clk)
+ mux = 0x3;
+ else if (parent == &ldb_di1_clk)
+ mux = 0x4;
+ else {
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, &pll3_pfd_540M);
+ reg |= (mux << MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ /* Derive clock from divided pre-muxed ipu2_di0 clock.*/
+ mux = 0;
+ }
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET),
+ MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu2_di1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk))
+ return clk_get_rate(clk->parent);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+
+ div = ((reg & MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK)
+ >> MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu2_di1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if ((clk->parent == &ldb_di0_clk) ||
+ (clk->parent == &ldb_di1_clk)) {
+ if (parent_rate == rate)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static int _clk_ipu2_di1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ if (parent == &ldb_di0_clk)
+ mux = 0x3;
+ else if (parent == &ldb_di1_clk)
+ mux = 0x4;
+ else {
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, &pll3_pfd_540M);
+ reg |= (mux << MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ /* Derive clock from divided pre-muxed ipu1_di0 clock.*/
+ mux = 0;
+ }
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET),
+ MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static struct clk ipu2_di_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ipu2_di_clk_0)
+ .id = 0,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu2_di0_set_parent,
+ .set_rate = _clk_ipu2_di0_set_rate,
+ .round_rate = _clk_ipu_di_round_rate,
+ .get_rate = _clk_ipu2_di0_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(ipu2_di_clk_1)
+ .id = 1,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu2_di1_set_parent,
+ .set_rate = _clk_ipu2_di1_set_rate,
+ .round_rate = _clk_ipu_di_round_rate,
+ .get_rate = _clk_ipu2_di1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+};
+
+static unsigned long _clk_can_root_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int _clk_can_root_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2) & MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK;
+ reg |= ((div - 1) << MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_can_root_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long val;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2) & MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK;
+ div = (reg >> MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET) + 1;
+ val = clk_get_rate(clk->parent) / div;
+
+ return val;
+}
+
+static struct clk can_clk_root = {
+ __INIT_CLK_DEBUG(can_clk_root)
+ .parent = &pll3_60M,
+ .set_rate = _clk_can_root_set_rate,
+ .get_rate = _clk_can_root_get_rate,
+ .round_rate = _clk_can_root_round_rate,
+};
+
+static struct clk can2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(can2_module_clk)
+ .id = 0,
+ .parent = &can_clk_root,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &can2_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(can2_serial_clk)
+ .id = 1,
+ .parent = &can_clk_root,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+
+static struct clk can1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(can1_module_clk)
+ .id = 0,
+ .parent = &can_clk_root,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &can1_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(can1_serial_clk)
+ .id = 1,
+ .parent = &can_clk_root,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_spdif_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CDCDR)
+ & ~MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll4_audio_main_clk,
+ &pll3_pfd_508M, &pll3_pfd_454M,
+ &pll3_sw_clk, NULL, NULL);
+ reg |= mux << MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_spdif0_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK)
+ >> MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK)
+ >> MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_spdif0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 64)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~(MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK|
+ MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static struct clk spdif0_clk[] = {
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &spdif0_clk[1],
+ .set_rate = _clk_spdif0_set_rate,
+ .get_rate = _clk_spdif0_get_rate,
+ .set_parent = _clk_spdif0_set_parent,
+ .round_rate = _clk_spdif_round_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ },
+};
+
+static unsigned long _clk_esai_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_esai_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2) & ~MXC_CCM_CSCMR2_ESAI_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll4_audio_main_clk, &pll3_pfd_508M,
+ &pll3_pfd_454M, &pll3_sw_clk, NULL, NULL);
+ reg |= mux << MXC_CCM_CSCMR2_ESAI_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_esai_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ pred = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_esai_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 64)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK|
+ MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static struct clk esai_clk = {
+ __INIT_CLK_DEBUG(esai_clk)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_rate = _clk_esai_set_rate,
+ .get_rate = _clk_esai_get_rate,
+ .set_parent = _clk_esai_set_parent,
+ .round_rate = _clk_esai_round_rate,
+};
+
+static int _clk_enet_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div = 1;
+
+ switch (rate) {
+ case 25000000:
+ div = 0;
+ break;
+ case 50000000:
+ div = 1;
+ break;
+ case 100000000:
+ div = 2;
+ break;
+ case 125000000:
+ div = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_DIV_SELECT_MASK;
+ reg |= (div << ANADIG_PLL_ENET_DIV_SELECT_OFFSET);
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ return 0;
+}
+
+static unsigned long _clk_enet_get_rate(struct clk *clk)
+{
+ unsigned int div;
+
+ div = (__raw_readl(PLL8_ENET_BASE_ADDR))
+ & ANADIG_PLL_ENET_DIV_SELECT_MASK;
+
+ switch (div) {
+ case 0:
+ div = 20;
+ break;
+ case 1:
+ div = 10;
+ break;
+ case 3:
+ div = 5;
+ break;
+ case 4:
+ div = 4;
+ break;
+ }
+
+ return 500000000 / div;
+}
+
+static int _clk_enet_enable(struct clk *clk)
+{
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ enet_is_active = true;
+#endif
+ _clk_enable(clk);
+ return 0;
+}
+
+static void _clk_enet_disable(struct clk *clk)
+{
+ _clk_disable(clk);
+#ifndef CONFIG_MX6_ENET_IRQ_TO_GPIO
+ enet_is_active = false;
+#endif
+}
+
+static struct clk enet_clk[] = {
+ {
+ __INIT_CLK_DEBUG(enet_clk)
+ .id = 0,
+ .parent = &pll8_enet_main_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enet_enable,
+ .disable = _clk_enet_disable,
+ .set_rate = _clk_enet_set_rate,
+ .get_rate = _clk_enet_get_rate,
+ .secondary = &enet_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static unsigned long _clk_enet_mdc_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk enet_mdc_clk = {
+ __INIT_CLK_DEBUG(enet_mdc_clk)
+ .parent = &ipg_clk,
+ .get_rate = _clk_enet_mdc_get_rate,
+};
+
+static struct clk ecspi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ecspi0_clk)
+ .id = 0,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi1_clk)
+ .id = 1,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi2_clk)
+ .id = 2,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi3_clk)
+ .id = 3,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi4_clk)
+ .id = 4,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_emi_slow_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_emi_slow_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
+
+ mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd_400M, &pll2_pfd_352M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET);
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ div = ((reg & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_emi_slow_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk emi_slow_clk = {
+ __INIT_CLK_DEBUG(emi_slow_clk)
+ .id = 0,
+ .parent = &axi_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_rate = _clk_emi_slow_set_rate,
+ .get_rate = _clk_emi_slow_get_rate,
+ .round_rate = _clk_emi_slow_round_rate,
+ .set_parent = _clk_emi_slow_set_parent,
+};
+
+static unsigned long _clk_emi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_emi_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_ACLK_EMI_MASK;
+
+ /*mux = _get_mux6(parent, &pll2_pfd_400M, &pll3_usb_otg_main_clk,
+ &axi_clk, &pll2_pfd_352M, NULL, NULL);*/
+ mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd_400M, &pll2_pfd_352M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_ACLK_EMI_OFFSET);
+ /* aclk_podf fixup */
+ reg ^= 0x00600000;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ /* ACLK_EMI_PODF read value matches with real divider value */
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ div = ((reg & MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_emi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ /*
+ * This is a software workaround for ACLK_EMI_PODF SoC
+ * implementation bug. The write/read/divider values
+ * have the relationship described by the following table:
+ *
+ * write value read value description
+ * 3b'000 3b'110 divided by 7
+ * 3b'001 3b'111 divided by 8
+ * 3b'010 3b'100 divided by 5
+ * 3b'011 3b'101 divided by 6
+ * 3b'100 3b'010 divided by 3
+ * 3b'101 3b'011 divided by 4
+ * 3b'110 3b'000 divided by 1
+ * 3b'111 3b'001 divided by 2(default)
+ *
+ * That's why we do the xor operation below.
+ */
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK;
+ reg |= ((div - 1)^0x6) << MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk emi_clk = {
+ __INIT_CLK_DEBUG(emi_clk)
+ .id = 0,
+ .parent = &axi_clk,
+ .set_rate = _clk_emi_set_rate,
+ .get_rate = _clk_emi_get_rate,
+ .round_rate = _clk_emi_round_rate,
+ .set_parent = _clk_emi_set_parent,
+};
+
+static unsigned long _clk_enfc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_enfc_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR)
+ & ~MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_pfd_352M,
+ &pll2_528_bus_main_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd_400M, NULL, NULL);
+ reg |= mux << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+static unsigned long _clk_enfc_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+
+ pred = ((reg & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK)
+ >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK)
+ >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_enfc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~(MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK|
+ MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+static struct clk enfc_clk = {
+ __INIT_CLK_DEBUG(enfc_clk)
+ .id = 0,
+ .parent = &pll2_pfd_352M,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_rate = _clk_enfc_set_rate,
+ .get_rate = _clk_enfc_get_rate,
+ .round_rate = _clk_enfc_round_rate,
+ .set_parent = _clk_enfc_set_parent,
+};
+
+static unsigned long _clk_uart_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int _clk_uart_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1) & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg |= ((div - 1) << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static unsigned long _clk_uart_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long val;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1) & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ div = (reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+ val = clk_get_rate(clk->parent) / div;
+
+ return val;
+}
+
+static struct clk uart_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart_clk)
+ .id = 0,
+ .parent = &pll3_80M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &uart_clk[1],
+ .set_rate = _clk_uart_set_rate,
+ .get_rate = _clk_uart_get_rate,
+ .round_rate = _clk_uart_round_rate,
+ },
+ {
+ __INIT_CLK_DEBUG(uart_serial_clk)
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static unsigned long _clk_hsi_tx_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_hsi_tx_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_HSI_TX_CLK_SEL;
+
+ if (parent == &pll2_pfd_400M)
+ reg |= (MXC_CCM_CDCDR_HSI_TX_CLK_SEL);
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_hsi_tx_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ div = ((reg & MXC_CCM_CDCDR_HSI_TX_PODF_MASK) >>
+ MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_hsi_tx_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_HSI_TX_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static struct clk hsi_tx_clk[] = {
+ {
+ __INIT_CLK_DEBUG(hsi_tx_clk)
+ .id = 0,
+ .parent = &pll2_pfd_400M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_hsi_tx_set_parent,
+ .round_rate = _clk_hsi_tx_round_rate,
+ .set_rate = _clk_hsi_tx_set_rate,
+ .get_rate = _clk_hsi_tx_get_rate,
+ .secondary = &hsi_tx_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mx6per1_clk,
+ .secondary = &mx6per2_clk,
+ },
+};
+
+static struct clk mipi_pllref_clk = {
+ __INIT_CLK_DEBUG(mipi_pllref_clk)
+ .id = 0,
+ .parent = &pll3_pfd_540M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk hdmi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(hdmi_isfr_clk)
+ .id = 0,
+ .parent = &pll3_pfd_540M,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(hdmi_iahb_clk)
+ .id = 1,
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk caam_clk[] = {
+ {
+ __INIT_CLK_DEBUG(caam_mem_clk)
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &caam_clk[1],
+ },
+ {
+ __INIT_CLK_DEBUG(caam_aclk_clk)
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &caam_clk[2],
+ },
+ {
+ __INIT_CLK_DEBUG(caam_ipg_clk)
+ .id = 2,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static int _clk_asrc_serial_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll4_audio_main_clk, &pll3_pfd_508M,
+ &pll3_pfd_454M, &pll3_sw_clk, NULL, NULL);
+ reg |= mux << MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_asrc_serial_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK)
+ >> MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK)
+ >> MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_asrc_serial_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 64)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~(MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK|
+ MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_asrc_serial_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static struct clk asrc_clk[] = {
+ {
+ __INIT_CLK_DEBUG(asrc_clk)
+ .id = 0,
+ .parent = &pll4_audio_main_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &spba_clk,
+ },
+ {
+ /*In the MX6 spec, asrc_serial_clk is listed as SPDIF1 clk
+ * This clock can never be gated and does not have any
+ * CCGR bits associated with it.
+ */
+ __INIT_CLK_DEBUG(asrc_serial_clk)
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_rate = _clk_asrc_serial_set_rate,
+ .get_rate = _clk_asrc_serial_get_rate,
+ .set_parent = _clk_asrc_serial_set_parent,
+ .round_rate = _clk_asrc_serial_round_rate,
+ },
+};
+
+static struct clk apbh_dma_clk = {
+ __INIT_CLK_DEBUG(apbh_dma_clk)
+ .parent = &usdhc3_clk,
+ .secondary = &mx6per1_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+};
+
+static struct clk aips_tz2_clk = {
+ __INIT_CLK_DEBUG(aips_tz2_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz1_clk = {
+ __INIT_CLK_DEBUG(aips_tz1_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+
+static struct clk openvg_axi_clk = {
+ __INIT_CLK_DEBUG(openvg_axi_clk)
+ .parent = &gpu2d_axi_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_gpu3d_core_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_gpu3d_core_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR)
+ & ~MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk,
+ &pll2_pfd_594M, &pll2_pfd_400M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long _clk_gpu3d_core_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ div = ((reg & MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_gpu3d_core_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (div > 8)
+ div = 8;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu3d_core_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpu3d_core_clk)
+ .parent = &pll2_pfd_594M,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .set_parent = _clk_gpu3d_core_set_parent,
+ .set_rate = _clk_gpu3d_core_set_rate,
+ .get_rate = _clk_gpu3d_core_get_rate,
+ .round_rate = _clk_gpu3d_core_round_rate,
+ .secondary = &gpu3d_core_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &gpu3d_axi_clk,
+ .secondary = &mx6fast1_clk,
+ },
+};
+
+static unsigned long _clk_gpu2d_core_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_gpu2d_core_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) &
+ ~MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK;
+
+ /*on mx6dl, 2d core clock sources from 3d shader core clock*/
+ if (!cpu_is_mx6dl()) {
+ mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+ }
+
+ return 0;
+}
+
+static unsigned long _clk_gpu2d_core_get_rate(struct clk *clk)
+{
+ u32 reg, div = 1;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ if (cpu_is_mx6q())
+ div = ((reg & MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET) + 1;
+ else if (cpu_is_mx6dl())
+ /* on i.mx6dl, gpu2d_core_clk source from gpu3d_shader_clk */
+ return clk_get_rate(clk->parent);
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_gpu2d_core_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+static struct clk gpu2d_core_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpu2d_core_clk)
+ .parent = &pll2_pfd_352M,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .disable = _clk_disable,
+ .set_parent = _clk_gpu2d_core_set_parent,
+ .set_rate = _clk_gpu2d_core_set_rate,
+ .get_rate = _clk_gpu2d_core_get_rate,
+ .round_rate = _clk_gpu2d_core_round_rate,
+ .secondary = &mx6fast1_clk,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+};
+
+static unsigned long _clk_gpu3d_shader_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_gpu3d_shader_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR)
+ & ~MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &mmdc_ch0_axi_clk[0],
+ &pll3_usb_otg_main_clk,
+ &pll2_pfd_594M, &pll3_pfd_720M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long _clk_gpu3d_shader_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ div = ((reg & MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_gpu3d_shader_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (div > 8)
+ div = 8;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+
+static struct clk gpu3d_shader_clk = {
+ __INIT_CLK_DEBUG(gpu3d_shader_clk)
+ .parent = &pll3_pfd_720M,
+ .secondary = &mmdc_ch0_axi_clk[0],
+ .set_parent = _clk_gpu3d_shader_set_parent,
+ .set_rate = _clk_gpu3d_shader_set_rate,
+ .get_rate = _clk_gpu3d_shader_get_rate,
+ .round_rate = _clk_gpu3d_shader_round_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+/* set the parent by the ipcg table */
+static struct clk gpmi_nand_clk[] = {
+ { /* gpmi_io_clk */
+ __INIT_CLK_DEBUG(gpmi_io_clk)
+ .parent = &enfc_clk,
+ .secondary = &gpmi_nand_clk[1],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .disable = _clk_disable,
+ },
+ { /* gpmi_apb_clk */
+ __INIT_CLK_DEBUG(gpmi_apb_clk)
+ .parent = &usdhc3_clk,
+ .secondary = &gpmi_nand_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
+ .disable = _clk_disable,
+ },
+ { /* bch_clk */
+ __INIT_CLK_DEBUG(gpmi_bch_clk)
+ .parent = &usdhc4_clk,
+ .secondary = &gpmi_nand_clk[3],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+ },
+ { /* bch_apb_clk */
+ __INIT_CLK_DEBUG(gpmi_bch_apb_clk)
+ .parent = &usdhc3_clk,
+ .secondary = &gpmi_nand_clk[4],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .disable = _clk_disable,
+ },
+ { /* bch relative clk */
+ __INIT_CLK_DEBUG(pl301_mx6qperl_bch)
+ .parent = &mx6per1_clk,
+ .secondary = &mmdc_ch0_axi_clk[0],
+ },
+};
+
+static struct clk pwm_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm_clk_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_1)
+ .parent = &ipg_perclk,
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_2)
+ .parent = &ipg_perclk,
+ .id = 2,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_3)
+ .parent = &ipg_perclk,
+ .id = 3,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_sata_enable(struct clk *clk)
+{
+ unsigned int reg;
+
+ /* Enable SATA ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_ENET_EN_SATA;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ _clk_enable(clk);
+
+ return 0;
+}
+
+static void _clk_sata_disable(struct clk *clk)
+{
+ unsigned int reg;
+
+ _clk_disable(clk);
+
+ /* Disable SATA ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_EN_SATA;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+}
+
+static struct clk sata_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sata_clk)
+ .parent = &pll8_enet_main_clk,
+ .enable = _clk_sata_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_sata_disable,
+ .secondary = &sata_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &ipg_clk,
+ .secondary = &sata_clk[2],
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static int _clk_pcie_enable(struct clk *clk)
+{
+ unsigned int reg;
+
+#ifndef CONFIG_IMX_PCIE_RC_MODE_IN_EP_RC_SYS
+ /* Activate LVDS CLK1 (the MiniPCIe slot clock input) */
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg &= ~ANATOP_LVDS_CLK1_IBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= ANATOP_LVDS_CLK1_SRC_SATA;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= ANATOP_LVDS_CLK1_OBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+#endif
+
+ /* Enable PCIE ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_ENET_EN_PCIE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ _clk_enable(clk);
+
+ return 0;
+}
+
+static void _clk_pcie_disable(struct clk *clk)
+{
+ unsigned int reg;
+
+ _clk_disable(clk);
+
+#ifndef CONFIG_IMX_PCIE_RC_MODE_IN_EP_RC_SYS
+ /* De-activate LVDS CLK1 (the MiniPCIe slot clock input) */
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= ANATOP_LVDS_CLK1_IBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg &= ~ANATOP_LVDS_CLK1_SRC_SATA;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg &= ~ANATOP_LVDS_CLK1_OBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+#endif
+
+ /* Disable PCIE ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_EN_PCIE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+}
+
+static struct clk pcie_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pcie_clk)
+ .parent = &pcie_axi_clk,
+ .enable = _clk_pcie_enable,
+ .disable = _clk_pcie_disable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .secondary = &pcie_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ /*
+ * Enable SATA ref clock.
+ * PCIe needs both sides to have the same source of refernce clock,
+ * The SATA reference clock is taken out to link partner.
+ */
+ .parent = &sata_clk[0],
+ .secondary = &pcie_clk[2],
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6fast1_clk,
+ },
+};
+
+static int _clk_pcie_ep_enable(struct clk *clk)
+{
+ unsigned int reg;
+
+ /* Enable PCIE ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_ENET_EN_PCIE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ _clk_enable(clk);
+
+ return 0;
+}
+
+static void _clk_pcie_ep_disable(struct clk *clk)
+{
+ unsigned int reg;
+
+ _clk_disable(clk);
+
+ /* Disable PCIE ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_EN_PCIE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+}
+
+static struct clk pcie_ep_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pcie_ep_clk)
+ .parent = &pcie_axi_clk,
+ .enable = _clk_pcie_ep_enable,
+ .disable = _clk_pcie_ep_disable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .secondary = &pcie_ep_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &pll8_enet_main_clk,
+ .secondary = &pcie_ep_clk[2],
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6fast1_clk,
+ },
+};
+
+static struct clk usboh3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(usboh3_clk)
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usboh3_clk[1],
+ .flags = AHB_MED_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch0_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static int _clk_mlb_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, cbcmr = __raw_readl(MXC_CCM_CBCMR);
+
+ /*
+ * In Rigel validatioin, the MLB sys_clock isn't using the
+ * right frequency after boot.
+ * In arik, the register CBCMR controls gpu2d clock, not mlb clock,
+ * mlb is sourced from axi clock.
+ * But In rigel, the axi clock is lower than in mx6q, so mlb need to
+ * find a new clock root.
+ * The gpu2d clock is the root of mlb clock in rigel.
+ * Thus we need to add below code in mx6dl.
+ * */
+ sel = _get_mux(parent, &axi_clk, &pll3_sw_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M);
+
+ cbcmr &= ~MXC_CCM_CBCMR_MLB_CLK_SEL_MASK;
+ cbcmr |= sel << MXC_CCM_CBCMR_MLB_CLK_SEL_OFFSET;
+ __raw_writel(cbcmr, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk mlb150_clk = {
+ __INIT_CLK_DEBUG(mlb150_clk)
+ .id = 0,
+ .secondary = &ocram_clk,
+ .set_parent = _clk_mlb_set_parent,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_enable1(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable1(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &pll3_usb_otg_main_clk)
+ sel = 0;
+ else if (parent == &pll2_528_bus_main_clk)
+ sel = 1;
+ else if (parent == &pll1_sys_main_clk)
+ sel = 2;
+ else if (parent == &pll5_video_main_clk)
+ sel = 3;
+ else if (parent == &axi_clk)
+ sel = 5;
+ else if (parent == &enfc_clk)
+ sel = 6;
+ else if (parent == &ipu1_di_clk[0])
+ sel = 7;
+ else if (parent == &ipu1_di_clk[1])
+ sel = 8;
+ else if (parent == &ipu2_di_clk[0])
+ sel = 9;
+ else if (parent == &ipu2_di_clk[1])
+ sel = 10;
+ else if (parent == &ahb_clk)
+ sel = 11;
+ else if (parent == &ipg_clk)
+ sel = 12;
+ else if (parent == &ipg_perclk)
+ sel = 13;
+ else if (parent == &ckil_clk)
+ sel = 14;
+ else if (parent == &pll4_audio_main_clk)
+ sel = 15;
+ else if (parent == &clko2_clk) {
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg |= MXC_CCM_CCOSR_CKOL_MIRROR_CKO2_MASK;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+ } else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~(MXC_CCM_CCOSR_CKOL_MIRROR_CKO2_MASK |
+ MXC_CCM_CCOSR_CKOL_SEL_MASK);
+ reg |= sel << MXC_CCM_CCOSR_CKOL_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko_get_rate(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCOSR);
+ u32 div = ((reg & MXC_CCM_CCOSR_CKOL_DIV_MASK) >>
+ MXC_CCM_CCOSR_CKOL_DIV_OFFSET) + 1;
+
+ if (clk->parent == &clko2_clk)
+ /* clko may output clko2 without divider */
+ return clk_get_rate(clk->parent);
+ else
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ /* clko may output clko2 without divider */
+ if (clk->parent == &clko2_clk)
+ return 0;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ /* clko may output clko2 without divider */
+ if (clk->parent == &clko2_clk)
+ return parent_rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ else if (parent_rate % rate)
+ div++;
+
+ if (div > 8)
+ div = 8;
+ return parent_rate / div;
+}
+
+static int _clk_clko2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &mmdc_ch0_axi_clk[0])
+ sel = 0;
+ else if (parent == &mmdc_ch1_axi_clk[0])
+ sel = 1;
+ else if (parent == &usdhc4_clk)
+ sel = 2;
+ else if (parent == &usdhc1_clk)
+ sel = 3;
+ else if (parent == &gpu2d_axi_clk)
+ sel = 4;
+ else if (parent == &ecspi_clk[0])
+ sel = 6;
+ else if (parent == &gpu3d_axi_clk)
+ sel = 7;
+ else if (parent == &usdhc3_clk)
+ sel = 8;
+ else if (parent == &pcie_clk[0])
+ sel = 9;
+ else if (parent == &ipu1_clk)
+ sel = 11;
+ else if (parent == &ipu2_clk)
+ sel = 12;
+ else if (parent == &vdo_axi_clk)
+ sel = 13;
+ else if (parent == &osc_clk)
+ sel = 14;
+ else if (parent == &gpu2d_core_clk[0])
+ sel = 15;
+ else if (parent == &gpu3d_core_clk[0])
+ sel = 16;
+ else if (parent == &usdhc2_clk)
+ sel = 17;
+ else if (parent == &ssi1_clk)
+ sel = 18;
+ else if (parent == &ssi2_clk)
+ sel = 19;
+ else if (parent == &ssi3_clk)
+ sel = 20;
+ else if (parent == &gpu3d_shader_clk)
+ sel = 21;
+ else if (parent == &can_clk_root)
+ sel = 23;
+ else if (parent == &ldb_di0_clk)
+ sel = 24;
+ else if (parent == &ldb_di1_clk)
+ sel = 25;
+ else if (parent == &esai_clk)
+ sel = 26;
+ else if (parent == &uart_clk[0])
+ sel = 28;
+ else if (parent == &spdif0_clk[0])
+ sel = 29;
+ else if (parent == &hsi_tx_clk[0])
+ sel = 31;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKO2_SEL_MASK;
+ reg |= sel << MXC_CCM_CCOSR_CKO2_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko2_get_rate(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCOSR);
+ u32 div = ((reg & MXC_CCM_CCOSR_CKO2_DIV_MASK) >>
+ MXC_CCM_CCOSR_CKO2_DIV_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_clko2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKO2_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_CCOSR_CKO2_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static struct clk clko_clk = {
+ __INIT_CLK_DEBUG(clko_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCOSR,
+ .enable_shift = MXC_CCM_CCOSR_CKOL_EN_OFFSET,
+ .disable = _clk_disable1,
+ .set_parent = _clk_clko_set_parent,
+ .set_rate = _clk_clko_set_rate,
+ .get_rate = _clk_clko_get_rate,
+ .round_rate = _clk_clko_round_rate,
+};
+
+static struct clk clko2_clk = {
+ __INIT_CLK_DEBUG(clko2_clk)
+ .parent = &usdhc4_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCOSR,
+ .enable_shift = MXC_CCM_CCOSR_CKO2_EN_OFFSET,
+ .disable = _clk_disable1,
+ .set_parent = _clk_clko2_set_parent,
+ .set_rate = _clk_clko2_set_rate,
+ .get_rate = _clk_clko2_get_rate,
+ .round_rate = _clk_clko_round_rate,
+};
+
+static struct clk perfmon0_clk = {
+ __INIT_CLK_DEBUG(perfmon0_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon1_clk = {
+ __INIT_CLK_DEBUG(perfmon1_clk)
+ .parent = &ipu1_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon2_clk = {
+ __INIT_CLK_DEBUG(perfmon2_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk dummy_clk = {
+ .id = 0,
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ }
+
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "osc", osc_clk),
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk),
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk),
+ _REGISTER_CLOCK(NULL, "pll1_main_clk", pll1_sys_main_clk),
+ _REGISTER_CLOCK(NULL, "pll1_sw_clk", pll1_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll2", pll2_528_bus_main_clk),
+ _REGISTER_CLOCK(NULL, "pll2_pfd_400M", pll2_pfd_400M),
+ _REGISTER_CLOCK(NULL, "pll2_pfd_352M", pll2_pfd_352M),
+ _REGISTER_CLOCK(NULL, "pll2_pfd_594M", pll2_pfd_594M),
+ _REGISTER_CLOCK(NULL, "pll2_200M", pll2_200M),
+ _REGISTER_CLOCK(NULL, "pll3_main_clk", pll3_usb_otg_main_clk),
+ _REGISTER_CLOCK(NULL, "pll3_pfd_508M", pll3_pfd_508M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd_454M", pll3_pfd_454M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd_720M", pll3_pfd_720M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd_540M", pll3_pfd_540M),
+ _REGISTER_CLOCK(NULL, "pll3_sw_clk", pll3_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll3_120M", pll3_120M),
+ _REGISTER_CLOCK(NULL, "pll3_120M", pll3_80M),
+ _REGISTER_CLOCK(NULL, "pll3_120M", pll3_60M),
+ _REGISTER_CLOCK(NULL, "pll4", pll4_audio_main_clk),
+ _REGISTER_CLOCK(NULL, "pll5", pll5_video_main_clk),
+ _REGISTER_CLOCK(NULL, "pll6", pll6_mlb150_main_clk),
+ _REGISTER_CLOCK(NULL, "pll3", pll7_usb_host_main_clk),
+ _REGISTER_CLOCK(NULL, "pll4", pll8_enet_main_clk),
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk),
+ _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
+ _REGISTER_CLOCK(NULL, "periph_clk", periph_clk),
+ _REGISTER_CLOCK(NULL, "axi_clk", axi_clk),
+ _REGISTER_CLOCK(NULL, "mmdc_ch0_axi", mmdc_ch0_axi_clk[0]),
+ _REGISTER_CLOCK(NULL, "mmdc_ch1_axi", mmdc_ch1_axi_clk[0]),
+ _REGISTER_CLOCK(NULL, "ahb", ahb_clk),
+ _REGISTER_CLOCK(NULL, "ipg_clk", ipg_clk),
+ _REGISTER_CLOCK(NULL, "ipg_perclk", ipg_perclk),
+ _REGISTER_CLOCK(NULL, "spba", spba_clk),
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpu2d_axi_clk", gpu2d_axi_clk),
+ _REGISTER_CLOCK(NULL, "gpu3d_axi_clk", gpu3d_axi_clk),
+ _REGISTER_CLOCK(NULL, "pcie_axi_clk", pcie_axi_clk),
+ _REGISTER_CLOCK(NULL, "vdo_axi_clk", vdo_axi_clk),
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
+ _REGISTER_CLOCK(NULL, "i2c_clk", i2c_clk[0]),
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]),
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]),
+ _REGISTER_CLOCK(NULL, "vpu_clk", vpu_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu1_clk", ipu1_clk),
+ _REGISTER_CLOCK(NULL, "ipu2_clk", ipu2_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, usdhc1_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, usdhc2_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, usdhc3_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, usdhc4_clk),
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk),
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk),
+ _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk),
+ _REGISTER_CLOCK(NULL, "ipu1_di0_clk", ipu1_di_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu1_di1_clk", ipu1_di_clk[1]),
+ _REGISTER_CLOCK(NULL, "ipu2_di0_clk", ipu2_di_clk[0]),
+ _REGISTER_CLOCK(NULL, "ipu2_di1_clk", ipu2_di_clk[1]),
+ _REGISTER_CLOCK(NULL, "can_root_clk", can_clk_root),
+ _REGISTER_CLOCK("imx6q-flexcan.0", NULL, can1_clk[0]),
+ _REGISTER_CLOCK("imx6q-flexcan.1", NULL, can2_clk[0]),
+ _REGISTER_CLOCK(NULL, "ldb_di0_clk", ldb_di0_clk),
+ _REGISTER_CLOCK(NULL, "ldb_di1_clk", ldb_di1_clk),
+ _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif0_clk[0]),
+ _REGISTER_CLOCK(NULL, "esai_clk", esai_clk),
+ _REGISTER_CLOCK("imx6q-ecspi.0", NULL, ecspi_clk[0]),
+ _REGISTER_CLOCK("imx6q-ecspi.1", NULL, ecspi_clk[1]),
+ _REGISTER_CLOCK("imx6q-ecspi.2", NULL, ecspi_clk[2]),
+ _REGISTER_CLOCK("imx6q-ecspi.3", NULL, ecspi_clk[3]),
+ _REGISTER_CLOCK("imx6q-ecspi.4", NULL, ecspi_clk[4]),
+ _REGISTER_CLOCK(NULL, "emi_slow_clk", emi_slow_clk),
+ _REGISTER_CLOCK(NULL, "emi_clk", emi_clk),
+ _REGISTER_CLOCK(NULL, "enfc_clk", enfc_clk),
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.4", NULL, uart_clk[0]),
+ _REGISTER_CLOCK(NULL, "hsi_tx", hsi_tx_clk[0]),
+ _REGISTER_CLOCK(NULL, "caam_clk", caam_clk[0]),
+ _REGISTER_CLOCK(NULL, "asrc_clk", asrc_clk[0]),
+ _REGISTER_CLOCK(NULL, "asrc_serial_clk", asrc_clk[1]),
+ _REGISTER_CLOCK(NULL, "mxs-dma-apbh", apbh_dma_clk),
+ _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
+ _REGISTER_CLOCK(NULL, "gpu3d_clk", gpu3d_core_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpu2d_clk", gpu2d_core_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpu3d_shader_clk", gpu3d_shader_clk),
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk[0]),
+ _REGISTER_CLOCK("imx6q-gpmi-nand.0", NULL, gpmi_nand_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpmi-apb", gpmi_nand_clk[1]),
+ _REGISTER_CLOCK(NULL, "bch", gpmi_nand_clk[2]),
+ _REGISTER_CLOCK(NULL, "bch-apb", gpmi_nand_clk[3]),
+ _REGISTER_CLOCK(NULL, "pl301_mx6qperl-bch", gpmi_nand_clk[4]),
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk[0]),
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm_clk[1]),
+ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm_clk[2]),
+ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm_clk[3]),
+ _REGISTER_CLOCK(NULL, "pcie_clk", pcie_clk[0]),
+ _REGISTER_CLOCK(NULL, "pcie_ep_clk", pcie_ep_clk[0]),
+ _REGISTER_CLOCK(NULL, "fec_clk", enet_clk[0]),
+ _REGISTER_CLOCK(NULL, "fec_mdc_clk", enet_mdc_clk),
+ _REGISTER_CLOCK(NULL, "imx_sata_clk", sata_clk[0]),
+ _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk[0]),
+ _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy1_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy3_clk", usb_phy3_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy4_clk", usb_phy4_clk),
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk),
+ _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk),
+ _REGISTER_CLOCK(NULL, "hdmi_isfr_clk", hdmi_clk[0]),
+ _REGISTER_CLOCK(NULL, "hdmi_iahb_clk", hdmi_clk[1]),
+ _REGISTER_CLOCK(NULL, "mipi_pllref_clk", mipi_pllref_clk),
+ _REGISTER_CLOCK(NULL, "vdoa", vdoa_clk[0]),
+ _REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
+ _REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
+ _REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
+ _REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk),
+ _REGISTER_CLOCK(NULL, "pxp_axi", ipu2_clk),
+ _REGISTER_CLOCK(NULL, "epdc_axi", ipu2_clk),
+ _REGISTER_CLOCK(NULL, "epdc_pix", ipu2_di_clk[1]),
+ _REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
+ _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
+ _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
+ _REGISTER_CLOCK(NULL, "mlb150_clk", mlb150_clk),
+ _REGISTER_CLOCK(NULL, "anaclk_1", anaclk_1),
+ _REGISTER_CLOCK(NULL, "anaclk_2", anaclk_2),
+ _REGISTER_CLOCK(NULL, "apb_pclk", dummy_clk),
+};
+
+static void clk_tree_init(void)
+
+{
+ unsigned int reg;
+
+ reg = __raw_readl(MMDC_MDMISC_OFFSET);
+ if ((reg & MMDC_MDMISC_DDR_TYPE_MASK) ==
+ (0x1 << MMDC_MDMISC_DDR_TYPE_OFFSET) ||
+ cpu_is_mx6dl()) {
+ clk_set_parent(&periph_clk, &pll2_pfd_400M);
+ printk(KERN_INFO "Set periph_clk's parent to pll2_pfd_400M!\n");
+ }
+}
+
+
+int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2)
+{
+ __iomem void *base;
+ int i, reg;
+ u32 parent_rate, rate;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ timer_base = ioremap(GPT_BASE_ADDR, SZ_4K);
+
+ apll_base = ioremap(ANATOP_BASE_ADDR, SZ_4K);
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ clk_debug_register(lookups[i].clk);
+ }
+
+ /* Lower the ipg_perclk frequency to 22MHz.
+ * I2C needs a minimum of 12.8MHz as its source
+ * to acheive 400KHz speed. IPG_PERCLK sources
+ * I2C. 22MHz when divided by the I2C divider gives the
+ * freq closest to 400KHz.
+ */
+ clk_set_rate(&ipg_perclk, 22000000);
+
+ /* Timer needs to be initialized first as the
+ * the WAIT routines use GPT counter as
+ * a delay.
+ */
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0) {
+ gpt_clk[0].parent = &ipg_perclk;
+ gpt_clk[0].get_rate = NULL;
+ } else {
+ /* Here we use OSC 24M as GPT's clock source, no need to
+ enable gpt serial clock*/
+ gpt_clk[0].secondary = NULL;
+ }
+
+ mxc_timer_init(&gpt_clk[0], timer_base, MXC_INT_GPT);
+
+ clk_tree_init();
+
+ /*
+ * Lower the ipg_perclk frequency to 22MHz.
+ * I2C needs a minimum of 12.8MHz as its source
+ * to acheive 400KHz speed. IPG_PERCLK sources
+ * I2C. 22MHz when divided by the I2C divider gives the
+ * freq closest to 400KHz.
+ */
+ //clk_set_rate(&ipg_perclk, 22000000);
+
+#ifdef CONFIG_MX6_VPU_352M
+ if (cpu_is_mx6q()) {
+ clk_set_rate(&pll2_pfd_400M, 352000000);
+ clk_set_parent(&vpu_clk[0], &pll2_pfd_400M);
+ }
+#endif
+ /* keep correct count. */
+ clk_enable(&cpu_clk);
+ clk_enable(&periph_clk);
+ /* Disable un-necessary PFDs & PLLs */
+ if (pll2_pfd_400M.usecount == 0 && cpu_is_mx6q())
+ pll2_pfd_400M.disable(&pll2_pfd_400M);
+ pll2_pfd_352M.disable(&pll2_pfd_352M);
+ pll2_pfd_594M.disable(&pll2_pfd_594M);
+
+#if !defined(CONFIG_FEC_1588)
+ pll3_pfd_454M.disable(&pll3_pfd_454M);
+ pll3_pfd_508M.disable(&pll3_pfd_508M);
+ pll3_pfd_540M.disable(&pll3_pfd_540M);
+ pll3_pfd_720M.disable(&pll3_pfd_720M);
+
+ pll3_usb_otg_main_clk.disable(&pll3_usb_otg_main_clk);
+#endif
+ pll4_audio_main_clk.disable(&pll4_audio_main_clk);
+ pll5_video_main_clk.disable(&pll5_video_main_clk);
+ pll6_mlb150_main_clk.disable(&pll6_mlb150_main_clk);
+ pll7_usb_host_main_clk.disable(&pll7_usb_host_main_clk);
+ pll8_enet_main_clk.disable(&pll8_enet_main_clk);
+
+ sata_clk[0].disable(&sata_clk[0]);
+ pcie_clk[0].disable(&pcie_clk[0]);
+
+ /* Initialize Audio and Video PLLs to valid frequency. */
+ clk_set_rate(&pll4_audio_main_clk, 176000000);
+ clk_set_rate(&pll5_video_main_clk, 650000000);
+
+ clk_set_parent(&ipu1_di_clk[0], &pll5_video_main_clk);
+ clk_set_parent(&ipu1_di_clk[1], &pll5_video_main_clk);
+ clk_set_parent(&ipu2_di_clk[0], &pll5_video_main_clk);
+ clk_set_parent(&ipu2_di_clk[1], &pll5_video_main_clk);
+
+ clk_set_parent(&emi_clk, &pll2_pfd_400M);
+#ifdef CONFIG_MX6_VPU_352M
+ clk_set_rate(&emi_clk, 176000000);
+#else
+ clk_set_rate(&emi_clk, 198000000);
+#endif
+ /*
+ * on mx6dl, 2d core clock sources from 3d shader core clock,
+ * but 3d shader clock multiplexer of mx6dl is different from
+ * mx6q. For instance the equivalent of pll2_pfd_594M on mc6q
+ * is pll2_pfd_528M on mx6dl. Make a note here.
+ */
+ clk_set_parent(&gpu3d_shader_clk, &pll2_pfd_594M);
+ clk_set_rate(&gpu3d_shader_clk, 594000000);
+ if (cpu_is_mx6dl()) {
+ /*for mx6dl, change gpu3d core clk parant to 594_PFD */
+ clk_set_parent(&gpu3d_core_clk[0], &pll2_pfd_594M);
+ clk_set_rate(&gpu3d_core_clk[0], 594000000);
+
+ /*on mx6dl, 2d core clock sources from 3d shader core clock*/
+ clk_set_parent(&gpu2d_core_clk[0], &gpu3d_shader_clk);
+ /* on mx6dl gpu3d_axi_clk source from mmdc0 directly */
+ clk_set_parent(&gpu3d_axi_clk, &mmdc_ch0_axi_clk[0]);
+ /* on mx6dl gpu2d_axi_clk source from mmdc0 directly */
+ clk_set_parent(&gpu2d_axi_clk, &mmdc_ch0_axi_clk[0]);
+
+ clk_set_rate(&pll3_pfd_540M, 540000000);
+
+ clk_set_parent(&ipu1_clk, &pll3_pfd_540M);
+ /* pxp & epdc */
+ clk_set_parent(&ipu2_clk, &pll2_pfd_400M);
+ clk_set_rate(&ipu2_clk, 200000000);
+ clk_set_parent(&axi_clk, &pll3_pfd_540M);
+ } else if (cpu_is_mx6q()) {
+ clk_set_parent(&gpu3d_core_clk[0], &mmdc_ch0_axi_clk[0]);
+ clk_set_rate(&gpu3d_core_clk[0], 528000000);
+ clk_set_parent(&ipu2_clk, &mmdc_ch0_axi_clk[0]);
+ clk_set_parent(&ipu1_clk, &mmdc_ch0_axi_clk[0]);
+ clk_set_parent(&axi_clk, &periph_clk);
+ }
+
+ /* Need to keep PLL3_PFD_540M enabled until AXI is sourced from it. */
+ clk_enable(&axi_clk);
+
+ if (cpu_is_mx6q())
+ clk_set_parent(&gpu2d_core_clk[0], &pll3_usb_otg_main_clk);
+
+ clk_set_parent(&ldb_di0_clk, &pll2_pfd_352M);
+ clk_set_parent(&ldb_di1_clk, &pll2_pfd_352M);
+
+ /* PCLK camera - J5 */
+ clk_set_parent(&clko2_clk, &osc_clk);
+ clk_set_rate(&clko2_clk, 2400000);
+
+ clk_set_parent(&clko_clk, &pll4_audio_main_clk);
+ /*
+ * FIXME: asrc needs to use asrc_serial(spdif1) clock to do sample
+ * rate convertion and this clock frequency can not be too high, set
+ * it to the minimum value 7.5Mhz to make asrc work properly.
+ */
+ clk_set_parent(&asrc_clk[1], &pll3_sw_clk);
+ clk_set_rate(&asrc_clk[1], 7500000);
+
+ /* set the GPMI clock to default frequency : 20MHz */
+ clk_set_parent(&enfc_clk, &pll2_pfd_400M);
+ clk_set_rate(&enfc_clk, enfc_clk.round_rate(&enfc_clk, 20000000));
+
+ mx6_cpu_op_init();
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ /* Gate off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(3 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
+ }
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0)
+ /* If GPT use ipg_perclk, we need to enable gpt serial clock */
+ __raw_writel(3 << MXC_CCM_CCGRx_CG10_OFFSET | 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1);
+ else
+ __raw_writel(3 << MXC_CCM_CCGRx_CG10_OFFSET, MXC_CCM_CCGR1);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG10_OFFSET, MXC_CCM_CCGR3);
+ __raw_writel(3 << MXC_CCM_CCGRx_CG7_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG6_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG4_OFFSET, MXC_CCM_CCGR4);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR5);
+
+ __raw_writel(0, MXC_CCM_CCGR6);
+
+ /* S/PDIF */
+ clk_set_parent(&spdif0_clk[0], &pll3_pfd_454M);
+
+ /* MLB150 SYS Clock */
+ /*
+ * In Rigel validatioin, the MLB sys_clock isn't using the
+ * right frequency after boot.
+ * In arik, the register CBCMR controls gpu2d clock, not mlb clock,
+ * mlb is sourced from axi clock.
+ * But In rigel, the axi clock is lower than in mx6q, so mlb need to
+ * find a new clock root.
+ * The gpu2d clock is the root of mlb clock in rigel.
+ * Thus we need to add below code in mx6dl.
+ * */
+ if (cpu_is_mx6dl())
+ clk_set_parent(&mlb150_clk, &pll3_sw_clk);
+
+
+ if (cpu_is_mx6dl()) {
+ /* pxp & epdc */
+ clk_set_parent(&ipu2_clk, &pll2_pfd_400M);
+ clk_set_rate(&ipu2_clk, 200000000);
+ if (epdc_enabled)
+ clk_set_parent(&ipu2_di_clk[1], &pll5_video_main_clk);
+ else
+ clk_set_parent(&ipu2_di_clk[1], &pll3_pfd_540M);
+ }
+
+ lp_high_freq = 0;
+ lp_med_freq = 0;
+ lp_audio_freq = 0;
+
+ /* Get current ARM_PODF value */
+ rate = clk_get_rate(&cpu_clk);
+ parent_rate = clk_get_rate(&pll1_sw_clk);
+ cur_arm_podf = parent_rate / rate;
+
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state.
+ * The max ARM clk is decided by the ipg_clk and has to
+ * follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
+ /* Turn OFF all unnecessary PHYs. */
+ if (cpu_is_mx6q()) {
+ /* Turn off SATA PHY. */
+ base = ioremap(MX6Q_SATA_BASE_ADDR, SZ_8K);
+ reg = __raw_readl(base + PORT_PHY_CTL);
+ __raw_writel(reg | PORT_PHY_CTL_PDDQ_LOC, base + PORT_PHY_CTL);
+ }
+
+ /* Turn off HDMI PHY. */
+ base = ioremap(MX6Q_HDMI_ARB_BASE_ADDR, SZ_128K);
+ reg = __raw_readb(base + HDMI_PHY_CONF0);
+ __raw_writeb(reg | HDMI_PHY_CONF0_GEN2_PDDQ_MASK, base + HDMI_PHY_CONF0);
+
+ reg = __raw_readb(base + HDMI_MC_PHYRSTZ);
+ __raw_writeb(reg | HDMI_MC_PHYRSTZ_DEASSERT, base + HDMI_MC_PHYRSTZ);
+
+ iounmap(base);
+
+ base = ioremap(MX6Q_IOMUXC_BASE_ADDR, SZ_4K);
+ /* Close PLL inside SATA PHY. */
+ reg = __raw_readl(base + 0x34);
+ __raw_writel(reg | (1 << 1), base + 0x34);
+
+ /* Close PCIE PHY. */
+ reg = __raw_readl(base + 0x04);
+ reg |= (1 << 18);
+ __raw_writel(reg, base + 0x04);
+ iounmap(base);
+
+ return 0;
+
+}
diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c
new file mode 100755
index 00000000..f70563d3
--- /dev/null
+++ b/arch/arm/mach-mx6/clock_mx6sl.c
@@ -0,0 +1,4182 @@
+/*
+ * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/hrtimer.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/regulator/consumer.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+#include <mach/mxc_dvfs.h>
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+#include "regs-anadig.h"
+
+#ifdef CONFIG_CLK_DEBUG
+#define __INIT_CLK_DEBUG(n) .name = #n,
+#else
+#define __INIT_CLK_DEBUG(n)
+#endif
+
+extern u32 arm_max_freq;
+extern int mxc_jtag_enabled;
+extern struct regulator *cpu_regulator;
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern int lp_high_freq;
+extern int lp_med_freq;
+extern int wait_mode_arm_podf;
+extern int mx6q_revision(void);
+extern int cur_arm_podf;
+
+static void __iomem *apll_base;
+static void __iomem *timer_base;
+static struct clk pll1_sys_main_clk;
+static struct clk pll2_528_bus_main_clk;
+static struct clk pll2_pfd2_400M;
+static struct clk pll3_usb_otg_main_clk;
+static struct clk pll4_audio_main_clk;
+static struct clk pll5_video_main_clk;
+static struct clk pll6_enet_main_clk; /* Essentially same as PLL8 on MX6Q/DL */
+static struct clk pll7_usb_host_main_clk;
+static struct clk usdhc3_clk;
+static struct clk ipg_clk;
+static struct clk gpt_clk[];
+static struct clk ahb_clk;
+
+static struct cpu_op *cpu_op_tbl;
+static int cpu_op_nr;
+static bool pll1_enabled;
+static bool arm_needs_pll2_400;
+static bool audio_pll_bypass;
+
+DEFINE_SPINLOCK(mx6sl_clk_lock);
+#define SPIN_DELAY 1200000 /* in nanoseconds */
+
+#define AUDIO_VIDEO_MIN_CLK_FREQ 650000000
+#define AUDIO_VIDEO_MAX_CLK_FREQ 1300000000
+#define MAX_ARM_CLK_IN_WAIT 158000000
+#define V2_TCN 0x24
+#define V2_TSTAT 0x08
+#define V2_TSTAT_ROV (1 << 5)
+#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
+#define MXC_TCTL 0x00
+#define MXC_TPRER 0x04
+#define V2_TPRER_PRE24M_OFFSET 12
+#define V2_TPRER_PRE24M_MASK 0xF
+
+/* We need to check the exp status again after timer expiration,
+ * as there might be interrupt coming between the first time exp
+ * and the time reading, then the time reading may be several ms
+ * after the exp checking due to the irq handle, so we need to
+ * check it to make sure the exp return the right value after
+ * timer expiration. */
+#define WAIT(exp, timeout) \
+({ \
+ u32 gpt_rate; \
+ u32 gpt_ticks; \
+ u32 gpt_cnt; \
+ u32 reg; \
+ int result = 1; \
+ gpt_rate = clk_get_rate(&gpt_clk[0]); \
+ gpt_ticks = timeout / (1000000000 / gpt_rate); \
+ reg = __raw_readl(timer_base + V2_TSTAT);\
+ /* Clear the GPT roll over interrupt. */ \
+ if (reg & V2_TSTAT_ROV) { \
+ __raw_writel(V2_TSTAT_ROV, timer_base + V2_TSTAT); \
+ } \
+ gpt_cnt = __raw_readl(timer_base + V2_TCN); \
+ while (!(exp)) { \
+ if ((__raw_readl(timer_base + V2_TCN) - gpt_cnt) > gpt_ticks) { \
+ if (!exp) \
+ result = 0; \
+ break; \
+ } else { \
+ reg = __raw_readl(timer_base + V2_TSTAT);\
+ if (reg & V2_TSTAT_ROV) { \
+ u32 old_cnt = gpt_cnt; \
+ /* Timer has rolled over. \
+ * Calculate the new tick count. \
+ */ \
+ gpt_cnt = __raw_readl(timer_base + V2_TCN); \
+ gpt_ticks -= (0xFFFFFFFF - old_cnt + gpt_cnt); \
+ /* Clear the roll over interrupt. */ \
+ __raw_writel(V2_TSTAT_ROV, \
+ timer_base + V2_TSTAT); \
+ } \
+ } \
+ } \
+ result; \
+})
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+static unsigned long anaclk_1_reference, anaclk_2_reference;
+
+static void __calc_pre_post_dividers(u32 max_podf, u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ /* Some of the podfs are 3 bits while others are 6 bits.
+ * Handle both cases here.
+ */
+ if (div >= 512 && (max_podf == 64)) {
+ /* For pre = 3bits and podf = 6 bits, max divider is 512. */
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64 && (max_podf == 8)) {
+ /* For pre = 3bits and podf = 3 bits, max divider is 64. */
+ *pre = 8;
+ *post = 8;
+ } else if (div >= 8) {
+ /* Find the minimum pre-divider for a max podf */
+ if (max_podf == 64)
+ min_pre = (div - 1) / (1 << 6) + 1;
+ else
+ min_pre = (div - 1) / (1 << 3) + 1;
+ old_err = 8;
+ /* Now loop through to find the max pre-divider. */
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div < 8) {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGRx_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return 0;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_sys_main_clk)
+ return PLL1_SYS_BASE_ADDR;
+ else if (pll == &pll2_528_bus_main_clk)
+ return PLL2_528_BASE_ADDR;
+ else if (pll == &pll3_usb_otg_main_clk)
+ return PLL3_480_USB1_BASE_ADDR;
+ else if (pll == &pll4_audio_main_clk)
+ return PLL4_AUDIO_BASE_ADDR;
+ else if (pll == &pll5_video_main_clk)
+ return PLL5_VIDEO_BASE_ADDR;
+ else if (pll == &pll6_enet_main_clk)
+ /* Essentially same as PLL8 on MX6Q/DL */
+ return PLL8_ENET_BASE_ADDR;
+ else if (pll == &pll7_usb_host_main_clk)
+ return PLL7_480_USB2_BASE_ADDR;
+ else
+ BUG();
+ return NULL;
+}
+
+
+/*
+ * For the 6-to-1 muxed input clock
+ */
+static inline u32 _get_mux6(struct clk *parent, struct clk *m0, struct clk *m1,
+ struct clk *m2, struct clk *m3, struct clk *m4,
+ struct clk *m5)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else if (parent == m4)
+ return 4;
+ else if (parent == m5)
+ return 5;
+ else
+ BUG();
+
+ return 0;
+}
+static unsigned long get_high_reference_clock_rate(struct clk *clk)
+{
+ return external_high_reference;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+ return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+ return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+ return ckih2_reference;
+}
+
+static unsigned long _clk_anaclk_1_get_rate(struct clk *clk)
+{
+ return anaclk_1_reference;
+}
+
+static int _clk_anaclk_1_set_rate(struct clk *clk, unsigned long rate)
+{
+ anaclk_1_reference = rate;
+ return 0;
+}
+
+static unsigned long _clk_anaclk_2_get_rate(struct clk *clk)
+{
+ return anaclk_2_reference;
+}
+
+static int _clk_anaclk_2_set_rate(struct clk *clk, unsigned long rate)
+{
+ anaclk_2_reference = rate;
+ return 0;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+ __INIT_CLK_DEBUG(ckih_clk)
+ .get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+ __INIT_CLK_DEBUG(ckih2_clk)
+ .get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+ __INIT_CLK_DEBUG(osc_clk)
+ .get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+ __INIT_CLK_DEBUG(ckil_clk)
+ .get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk anaclk_1 = {
+ __INIT_CLK_DEBUG(anaclk_1)
+ .get_rate = _clk_anaclk_1_get_rate,
+ .set_rate = _clk_anaclk_1_set_rate,
+};
+
+static struct clk anaclk_2 = {
+ __INIT_CLK_DEBUG(anaclk_2)
+ .get_rate = _clk_anaclk_2_get_rate,
+ .set_rate = _clk_anaclk_2_set_rate,
+};
+
+static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ tmp += rate/2;
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 12 ? 12 : frac;
+ frac = frac > 35 ? 35 : frac;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+ do_div(tmp, frac);
+ return tmp;
+}
+
+static unsigned long pfd_get_rate(struct clk *clk)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+
+ frac = (__raw_readl(clk->enable_reg) >> clk->enable_shift) &
+ ANADIG_PFD_FRAC_MASK;
+
+ do_div(tmp, frac);
+
+ return tmp;
+}
+
+static int pfd_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 frac;
+ u64 tmp;
+ tmp = (u64)clk_get_rate(clk->parent) * 18;
+
+ /* Round up the divider so that we don't set a rate
+ * higher than what is requested. */
+ tmp += rate/2;
+ do_div(tmp, rate);
+ frac = tmp;
+ frac = frac < 12 ? 12 : frac;
+ frac = frac > 35 ? 35 : frac;
+ /* clear clk frac bits */
+ __raw_writel(ANADIG_PFD_FRAC_MASK << clk->enable_shift,
+ (int)clk->enable_reg + 8);
+ /* set clk frac bits */
+ __raw_writel(frac << clk->enable_shift,
+ (int)clk->enable_reg + 4);
+
+ return 0;
+}
+
+static int _clk_pfd_enable(struct clk *clk)
+{
+ /* clear clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ (int)clk->enable_reg + 8);
+
+ udelay(3);
+ return 0;
+}
+
+static void _clk_pfd_disable(struct clk *clk)
+{
+ /* set clk gate bit */
+ __raw_writel((1 << (clk->enable_shift + 7)),
+ (int)clk->enable_reg + 4);
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ if (clk != &pll4_audio_main_clk || !audio_pll_bypass)
+ reg &= ~ANADIG_PLL_POWER_DOWN;
+
+ /* The 480MHz PLLs have the opposite definition for power bit. */
+ if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk)
+ reg |= ANADIG_PLL_POWER_DOWN;
+
+ __raw_writel(reg, pllbase);
+
+ /* It will power on pll3 */
+ if (clk == &pll3_usb_otg_main_clk)
+ __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_CLR);
+
+ /* Wait for PLL to lock */
+ if (clk != &pll4_audio_main_clk || !audio_pll_bypass) {
+ if (!WAIT((__raw_readl(pllbase) & ANADIG_PLL_LOCK),
+ SPIN_DELAY))
+ panic("pll enable failed\n");
+ }
+ /* Enable the PLL output now*/
+ reg = __raw_readl(pllbase);
+
+ /* If audio PLL is set to 24MHz, leave it in bypass mode. */
+ if (clk != &pll4_audio_main_clk || !audio_pll_bypass)
+ reg &= ~ANADIG_PLL_BYPASS;
+
+ reg |= ANADIG_PLL_ENABLE;
+
+ __raw_writel(reg, pllbase);
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ if ((arm_needs_pll2_400) && (clk == &pll2_528_bus_main_clk))
+ return;
+
+
+ pllbase = _get_pll_base(clk);
+
+ reg = __raw_readl(pllbase);
+ reg |= ANADIG_PLL_BYPASS;
+ reg |= ANADIG_PLL_POWER_DOWN;
+
+ /* The 480MHz PLLs have the opposite definition for power bit. */
+ if (clk == &pll3_usb_otg_main_clk || clk == &pll7_usb_host_main_clk)
+ reg &= ~ANADIG_PLL_POWER_DOWN;
+
+ /* PLL1, PLL2, PLL3, PLL7 should not disable the ENABLE bit.
+ * The output of these PLLs maybe used even if they are bypassed.
+ */
+ if (clk == &pll4_audio_main_clk || clk == &pll5_video_main_clk ||
+ clk == &pll6_enet_main_clk)
+ reg &= ~ANADIG_PLL_ENABLE;
+
+ __raw_writel(reg, pllbase);
+
+ /*
+ * It will power off PLL3's power, it is the TO1.1 fix
+ * Please see TKT064178 for detail.
+ */
+ if (clk == &pll3_usb_otg_main_clk)
+ __raw_writel(BM_ANADIG_ANA_MISC2_CONTROL0, apll_base + HW_ANADIG_ANA_MISC2_SET);
+}
+
+static unsigned long _clk_pll1_main_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ val = (clk_get_rate(clk->parent) * div) / 2;
+ return val;
+}
+
+static int _clk_pll1_main_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate < AUDIO_VIDEO_MIN_CLK_FREQ || rate > AUDIO_VIDEO_MAX_CLK_FREQ)
+ return -EINVAL;
+
+ div = (rate * 2) / clk_get_rate(clk->parent);
+
+ /* Update div */
+ reg = __raw_readl(PLL1_SYS_BASE_ADDR) & ~ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL1_SYS_BASE_ADDR);
+
+ /* Wait for PLL1 to lock */
+ if (!WAIT((__raw_readl(PLL1_SYS_BASE_ADDR) & ANADIG_PLL_LOCK),
+ SPIN_DELAY))
+ panic("pll1 set rate failed\n");
+
+ return 0;
+}
+
+static int _clk_pll1_main_enable(struct clk *clk)
+{
+ pll1_enabled = true;
+ _clk_pll_enable(clk);
+ return 0;
+}
+
+static void _clk_pll1_main_disable(struct clk *clk)
+{
+ unsigned int reg;
+ void __iomem *pllbase;
+
+ pll1_enabled = false;
+ pllbase = _get_pll_base(clk);
+
+ /* Set the PLL is bypass mode only.
+ * We need to be able to set the ARM_PODF bit
+ * in WAIT mode. Setting the ARM_PODF bit
+ * requires PLL1 to be enabled.
+ */
+ reg = __raw_readl(pllbase);
+ reg |= (ANADIG_PLL_BYPASS | ANADIG_PLL_POWER_DOWN);
+ __raw_writel(reg, pllbase);
+}
+
+static struct clk pll1_sys_main_clk = {
+ __INIT_CLK_DEBUG(pll1_sys_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll1_main_get_rate,
+ .set_rate = _clk_pll1_main_set_rate,
+ .enable = _clk_pll1_main_enable,
+ .disable = _clk_pll1_main_disable,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_sys_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set the step_clk parent to be lp_apm, to save power. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL);
+ } else {
+ /* Set STEP_CLK to be the parent*/
+ if (parent == &osc_clk) {
+ /* Set STEP_CLK to be sourced from LPAPM. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ } else {
+ /* Set STEP_CLK to be sourced from PLL2-PDF (400MHz). */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_STEP_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ }
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static unsigned long _clk_pll1_sw_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk pll1_sw_clk = {
+ __INIT_CLK_DEBUG(pll1_sw_clk)
+ .parent = &pll1_sys_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .get_rate = _clk_pll1_sw_get_rate,
+};
+
+static unsigned long _clk_pll2_main_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL2_528_BASE_ADDR) & ANADIG_PLL_528_DIV_SELECT;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+
+ else
+ val = clk_get_rate(clk->parent) * 20;
+
+ return val;
+}
+
+static int _clk_pll2_main_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL2_528_BASE_ADDR);
+ reg &= ~ANADIG_PLL_528_DIV_SELECT;
+ reg |= div;
+ __raw_writel(reg, PLL2_528_BASE_ADDR);
+
+ return 0;
+}
+
+static struct clk pll2_528_bus_main_clk = {
+ __INIT_CLK_DEBUG(pll2_528_bus_main_clk)
+ .parent = &osc_clk,
+ .get_rate = _clk_pll2_main_get_rate,
+ .set_rate = _clk_pll2_main_set_rate,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static void _clk_pll2_pfd2_400M_disable(struct clk *clk)
+{
+ if (!arm_needs_pll2_400)
+ _clk_pfd_disable(clk);
+}
+
+static struct clk pll2_pfd2_400M = {
+ __INIT_CLK_DEBUG(pll2_pfd2_400M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD2_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pll2_pfd2_400M_disable,
+ .get_rate = pfd_get_rate,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll2_pfd0_352M = {
+ __INIT_CLK_DEBUG(pll2_pfd0_352M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD0_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll2_pfd1_594M = {
+ __INIT_CLK_DEBUG(pll2_pfd1_594M)
+ .parent = &pll2_528_bus_main_clk,
+ .enable_reg = (void *)PFD_528_BASE_ADDR,
+ .enable_shift = ANADIG_PFD1_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static unsigned long _clk_pll2_200M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk pll2_200M = {
+ __INIT_CLK_DEBUG(pll2_200M)
+ .parent = &pll2_pfd2_400M,
+ .get_rate = _clk_pll2_200M_get_rate,
+};
+
+static unsigned long _clk_pll3_usb_otg_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL3_480_USB1_BASE_ADDR)
+ & ANADIG_PLL_480_DIV_SELECT_MASK;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+ else
+ val = clk_get_rate(clk->parent) * 20;
+ return val;
+}
+
+static int _clk_pll3_usb_otg_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL3_480_USB1_BASE_ADDR);
+ reg &= ~ANADIG_PLL_480_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL3_480_USB1_BASE_ADDR);
+
+ return 0;
+}
+
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_usb_otg_main_clk = {
+ __INIT_CLK_DEBUG(pll3_usb_otg_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* for USB OTG */
+static struct clk usb_phy1_clk = {
+ __INIT_CLK_DEBUG(usb_phy1_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* For HSIC port 1 */
+static struct clk usb_phy3_clk = {
+ __INIT_CLK_DEBUG(usb_phy3_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+/* For HSIC port 2 */
+static struct clk usb_phy4_clk = {
+ __INIT_CLK_DEBUG(usb_phy4_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .set_rate = _clk_pll3_usb_otg_set_rate,
+ .get_rate = _clk_pll3_usb_otg_get_rate,
+};
+
+static struct clk pll3_pfd2_508M = {
+ __INIT_CLK_DEBUG(pll3_pfd2_508M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD2_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll3_pfd3_454M = {
+ __INIT_CLK_DEBUG(pll3_pfd3_454M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD3_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll3_pfd0_720M = {
+ __INIT_CLK_DEBUG(pll3_pfd0_720M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD0_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+};
+
+static struct clk pll3_pfd1_540M = {
+ __INIT_CLK_DEBUG(pll3_pfd1_540M)
+ .parent = &pll3_usb_otg_main_clk,
+ .enable_reg = (void *)PFD_480_BASE_ADDR,
+ .enable_shift = ANADIG_PFD1_FRAC_OFFSET,
+ .enable = _clk_pfd_enable,
+ .disable = _clk_pfd_disable,
+ .set_rate = pfd_set_rate,
+ .get_rate = pfd_get_rate,
+ .round_rate = pfd_round_rate,
+ .get_rate = pfd_get_rate,
+};
+
+static unsigned long _clk_pll3_sw_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ __INIT_CLK_DEBUG(pll3_sw_clk)
+ .parent = &pll3_usb_otg_main_clk,
+ .get_rate = _clk_pll3_sw_get_rate,
+};
+
+static unsigned long _clk_pll3_120M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+static struct clk pll3_120M = {
+ __INIT_CLK_DEBUG(pll3_120M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_120M_get_rate,
+};
+
+static unsigned long _clk_pll3_80M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 6;
+}
+
+static struct clk pll3_80M = {
+ __INIT_CLK_DEBUG(pll3_80M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_80M_get_rate,
+};
+
+static unsigned long _clk_pll3_60M_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 8;
+}
+
+static struct clk pll3_60M = {
+ __INIT_CLK_DEBUG(pll3_60M)
+ .parent = &pll3_sw_clk,
+ .get_rate = _clk_pll3_60M_get_rate,
+};
+
+static unsigned long _clk_audio_video_get_rate(struct clk *clk)
+{
+ unsigned int div, mfn, mfd;
+ unsigned long rate;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ void __iomem *pllbase;
+ unsigned int test_div_sel, control3, post_div;
+
+ pllbase = _get_pll_base(clk);
+
+ if (__raw_readl(pllbase) & ANADIG_PLL_BYPASS)
+ return 24000000;
+
+ test_div_sel = (__raw_readl(pllbase)
+ & ANADIG_PLL_AV_TEST_DIV_SEL_MASK)
+ >> ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET;
+ /* post_div = 4 - test_div_sel; */
+ if (test_div_sel == 0)
+ post_div = 4;
+ else if (test_div_sel == 1)
+ post_div = 2;
+ else
+ post_div = 1;
+
+ /* PMU_REG_MISC2 in RM */
+ if (clk == &pll5_video_main_clk) {
+ control3 = (__raw_readl(ANA_MISC2_BASE_ADDR)
+ & ANADIG_ANA_MISC2_CONTROL3_MASK)
+ >> ANADIG_ANA_MISC2_CONTROL3_OFFSET;
+ if (control3 == 1)
+ post_div *= 2;
+ else if (control3 == 3)
+ post_div *= 4;
+ }
+
+ div = __raw_readl(pllbase) & ANADIG_PLL_SYS_DIV_SELECT_MASK;
+ mfn = __raw_readl(pllbase + PLL_NUM_DIV_OFFSET);
+ mfd = __raw_readl(pllbase + PLL_DENOM_DIV_OFFSET);
+
+ rate = (parent_rate * div) + ((parent_rate / mfd) * mfn);
+ rate = rate / post_div;
+
+ return rate;
+}
+
+static int _clk_audio_video_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+ unsigned int mfn, mfd = 1000000;
+ s64 temp64;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ void __iomem *pllbase;
+ unsigned long min_clk_rate, pre_div_rate;
+ u32 test_div_sel = 2;
+ u32 control3 = 0;
+
+ pllbase = _get_pll_base(clk);
+
+ if (clk == &pll4_audio_main_clk && audio_pll_bypass) {
+ reg = __raw_readl(pllbase)
+ & ~ANADIG_PLL_SYS_DIV_SELECT_MASK
+ & ~ANADIG_PLL_AV_TEST_DIV_SEL_MASK;
+ __raw_writel(reg, pllbase);
+ return 0;
+ }
+
+ if (clk == &pll4_audio_main_clk)
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
+ else
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 16;
+
+ if ((rate < min_clk_rate) || (rate > AUDIO_VIDEO_MAX_CLK_FREQ))
+ return -EINVAL;
+
+ pre_div_rate = rate;
+ while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
+ pre_div_rate *= 2;
+ /*
+ * test_div_sel field values:
+ * 2 -> Divide by 1
+ * 1 -> Divide by 2
+ * 0 -> Divide by 4
+ *
+ * control3 field values:
+ * 0 -> Divide by 1
+ * 1 -> Divide by 2
+ * 3 -> Divide by 4
+ */
+ if (test_div_sel != 0)
+ test_div_sel--;
+ else {
+ control3++;
+ if (control3 == 2)
+ control3++;
+ }
+ }
+
+ div = pre_div_rate / parent_rate;
+ temp64 = (u64) (pre_div_rate - (div * parent_rate));
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ reg = __raw_readl(pllbase)
+ & ~ANADIG_PLL_SYS_DIV_SELECT_MASK
+ & ~ANADIG_PLL_AV_TEST_DIV_SEL_MASK;
+ reg |= div |
+ (test_div_sel << ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET);
+ __raw_writel(reg, pllbase);
+ __raw_writel(mfn, pllbase + PLL_NUM_DIV_OFFSET);
+ __raw_writel(mfd, pllbase + PLL_DENOM_DIV_OFFSET);
+
+ reg = __raw_readl(ANA_MISC2_BASE_ADDR)
+ & ~ANADIG_ANA_MISC2_CONTROL3_MASK;
+ reg |= control3 << ANADIG_ANA_MISC2_CONTROL3_OFFSET;
+ __raw_writel(reg, ANA_MISC2_BASE_ADDR);
+
+ return 0;
+}
+
+static unsigned long _clk_audio_video_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long min_clk_rate;
+ unsigned int div, post_div = 1;
+ unsigned int mfn, mfd = 1000000;
+ s64 temp64;
+ unsigned int parent_rate = clk_get_rate(clk->parent);
+ unsigned long pre_div_rate;
+ u32 test_div_sel = 2;
+ u32 control3 = 0;
+ unsigned long final_rate;
+
+ if (clk == &pll4_audio_main_clk && audio_pll_bypass)
+ return 24000000;
+
+ if (clk == &pll4_audio_main_clk)
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 4;
+ else
+ min_clk_rate = AUDIO_VIDEO_MIN_CLK_FREQ / 16;
+
+ if (rate < min_clk_rate)
+ return min_clk_rate;
+
+ if (rate > AUDIO_VIDEO_MAX_CLK_FREQ)
+ return AUDIO_VIDEO_MAX_CLK_FREQ;
+
+ pre_div_rate = rate;
+ while (pre_div_rate < AUDIO_VIDEO_MIN_CLK_FREQ) {
+ pre_div_rate *= 2;
+ post_div *= 2;
+ if (test_div_sel != 0)
+ test_div_sel--;
+ else {
+ control3++;
+ if (control3 == 2)
+ control3++;
+ }
+ }
+
+ div = pre_div_rate / parent_rate;
+ temp64 = (u64) (pre_div_rate - (div * parent_rate));
+ temp64 *= mfd;
+ do_div(temp64, parent_rate);
+ mfn = temp64;
+
+ final_rate = (parent_rate * div) + ((parent_rate / mfd) * mfn);
+ final_rate = final_rate / post_div;
+
+ return final_rate;
+}
+
+static int _clk_audio_video_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+ void __iomem *pllbase;
+
+ if (clk == &pll4_audio_main_clk)
+ pllbase = PLL4_AUDIO_BASE_ADDR;
+ else
+ pllbase = PLL5_VIDEO_BASE_ADDR;
+
+ reg = __raw_readl(pllbase) & ~ANADIG_PLL_BYPASS_CLK_SRC_MASK;
+ mux = _get_mux6(parent, &osc_clk, &anaclk_1, &anaclk_2,
+ NULL, NULL, NULL);
+ reg |= mux << ANADIG_PLL_BYPASS_CLK_SRC_OFFSET;
+ __raw_writel(reg, pllbase);
+
+ /* Set anaclk_x as input */
+ if (parent == &anaclk_1) {
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= (ANATOP_LVDS_CLK1_IBEN_MASK &
+ ~ANATOP_LVDS_CLK1_OBEN_MASK);
+ __raw_writel(reg, ANADIG_MISC1_REG);
+ } else if (parent == &anaclk_2) {
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= (ANATOP_LVDS_CLK2_IBEN_MASK &
+ ~ANATOP_LVDS_CLK2_OBEN_MASK);
+ __raw_writel(reg, ANADIG_MISC1_REG);
+ }
+
+ return 0;
+}
+
+static struct clk pll4_audio_main_clk = {
+ __INIT_CLK_DEBUG(pll4_audio_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_audio_video_set_rate,
+ .get_rate = _clk_audio_video_get_rate,
+ .round_rate = _clk_audio_video_round_rate,
+ .set_parent = _clk_audio_video_set_parent,
+};
+
+static struct clk pll5_video_main_clk = {
+ __INIT_CLK_DEBUG(pll5_video_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_audio_video_set_rate,
+ .get_rate = _clk_audio_video_get_rate,
+ .round_rate = _clk_audio_video_round_rate,
+ .set_parent = _clk_audio_video_set_parent,
+};
+
+static struct clk pll6_enet_main_clk = {
+ __INIT_CLK_DEBUG(pll6_enet_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+};
+
+static unsigned long _clk_pll7_usb_otg_get_rate(struct clk *clk)
+{
+ unsigned int div;
+ unsigned long val;
+
+ div = __raw_readl(PLL7_480_USB2_BASE_ADDR)
+ & ANADIG_PLL_480_DIV_SELECT_MASK;
+
+ if (div == 1)
+ val = clk_get_rate(clk->parent) * 22;
+ else
+ val = clk_get_rate(clk->parent) * 20;
+ return val;
+}
+
+static int _clk_pll7_usb_otg_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div;
+
+ if (rate == 528000000)
+ div = 1;
+ else if (rate == 480000000)
+ div = 0;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(PLL7_480_USB2_BASE_ADDR);
+ reg &= ~ANADIG_PLL_480_DIV_SELECT_MASK;
+ reg |= div;
+ __raw_writel(reg, PLL7_480_USB2_BASE_ADDR);
+
+ return 0;
+}
+
+static struct clk pll7_usb_host_main_clk = {
+ __INIT_CLK_DEBUG(pll7_usb_host_main_clk)
+ .parent = &osc_clk,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .set_rate = _clk_pll7_usb_otg_set_rate,
+ .get_rate = _clk_pll7_usb_otg_get_rate,
+
+};
+
+static unsigned long _clk_arm_get_rate(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+extern int high_cpu_freq;
+
+static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
+{
+ int i;
+ u32 div;
+ u32 parent_rate;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
+ unsigned long flags;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (rate == cpu_op_tbl[i].cpu_rate)
+ break;
+ }
+ if (i >= cpu_op_nr)
+ return -EINVAL;
+
+ if (clk_get_rate(&ahb_clk) == 24000000) {
+ printk(KERN_INFO "we should not be here!!!!! AHB is at 24MHz....cpu_rate requested = %ld\n", rate);
+ dump_stack();
+ BUG();
+ }
+ spin_lock_irqsave(&mx6sl_clk_lock, flags);
+
+ if (rate <= clk_get_rate(&pll2_pfd2_400M)) {
+ /* Source pll1_sw_clk from step_clk which is sourced from
+ * PLL2_PFD2_400M.
+ */
+ if (pll1_sw_clk.parent != &pll2_pfd2_400M) {
+ if (pll2_pfd2_400M.usecount == 0) {
+ /* Check if PLL2 needs to be enabled also. */
+ if (pll2_528_bus_main_clk.usecount == 0) {
+ pll2_528_bus_main_clk.enable(&pll2_528_bus_main_clk);
+ osc_clk.usecount++;
+ }
+ /* Ensure parent usecount is
+ * also incremented.
+ */
+ pll2_528_bus_main_clk.usecount++;
+ pll2_pfd2_400M.enable(&pll2_pfd2_400M);
+ }
+ arm_needs_pll2_400 = true;
+ pll2_pfd2_400M.usecount++;
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M);
+ pll1_sw_clk.parent = &pll2_pfd2_400M;
+ }
+ } else {
+ /* Make sure PLL1 is enabled */
+ if (!pll1_enabled) {
+ pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 1;
+ osc_clk.usecount++;
+ }
+ if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
+ if (pll1_sw_clk.parent == &pll1_sys_main_clk) {
+ /* Change the PLL1 rate. */
+ if (pll2_pfd2_400M.usecount != 0)
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M);
+ else
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
+ }
+ pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate);
+ }
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
+ pll1_sw_clk.parent = &pll1_sys_main_clk;
+
+ if (arm_needs_pll2_400) {
+ pll2_pfd2_400M.usecount--;
+ if (pll2_pfd2_400M.usecount == 0) {
+ pll2_pfd2_400M.disable(&pll2_pfd2_400M);
+ /* Ensure parent usecount is
+ * also decremented.
+ */
+ pll2_528_bus_main_clk.usecount--;
+ if (pll2_528_bus_main_clk.usecount == 0) {
+ pll2_528_bus_main_clk.disable(&pll2_528_bus_main_clk);
+ osc_clk.usecount--;
+ }
+ }
+ }
+ arm_needs_pll2_400 = false;
+ }
+ parent_rate = clk_get_rate(clk->parent);
+ div = parent_rate / rate;
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state.
+ * The max ARM clk is decided by the ipg_clk and has to
+ * follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ * For ex, when IPG is at 66MHz, ARM_CLK cannot be greater
+ * than 158MHz. Pre-calculate the optimal divider now.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
+ if (div == 0)
+ div = 1;
+
+ if ((parent_rate / div) > rate)
+ div++;
+
+ if (div > 8) {
+ spin_unlock_irqrestore(&mx6sl_clk_lock, flags);
+ return -1;
+ }
+
+ cur_arm_podf = div;
+
+ __raw_writel(div - 1, MXC_CCM_CACRR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+
+ if (pll1_sys_main_clk.usecount == 1 && arm_needs_pll2_400) {
+ pll1_sys_main_clk.disable(&pll1_sys_main_clk);
+ pll1_sys_main_clk.usecount = 0;
+ osc_clk.usecount--;
+ }
+
+ spin_unlock_irqrestore(&mx6sl_clk_lock, flags);
+
+ return 0;
+}
+
+static struct clk cpu_clk = {
+ __INIT_CLK_DEBUG(cpu_clk)
+ .parent = &pll1_sw_clk,
+ .set_rate = _clk_arm_set_rate,
+ .get_rate = _clk_arm_get_rate,
+};
+
+static unsigned long _clk_twd_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static int _clk_ipg_perclk_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+
+ if (parent == &osc_clk)
+ reg |= 0x1 << MXC_CCM_CSCMR1_PERCLK_CLK_SEL_OFFSET;
+ else
+ reg &= ~(0x1 << MXC_CCM_CSCMR1_PERCLK_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+static struct clk twd_clk = {
+ __INIT_CLK_DEBUG(twd_clk)
+ .parent = &cpu_clk,
+ .get_rate = _clk_twd_get_rate,
+};
+
+static int _clk_periph_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk, &pll2_pfd2_400M,
+ &pll2_pfd0_352M, &pll2_200M, &pll3_sw_clk, &osc_clk);
+
+ if (mux <= 3) {
+ /* Set the pre_periph_clk multiplexer */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+ udelay(5);
+ /* Set the periph_clk_sel multiplexer. */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ } else {
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ /* Set the periph_clk2_podf divider to divide by 1. */
+ reg &= ~MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Set the periph_clk2_sel mux. */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
+ reg |= ((mux - 4) << MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ /* Set periph_clk_sel to select periph_clk. */
+ reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ }
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY), SPIN_DELAY))
+ panic("_clk_periph_set_parent failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_periph_get_rate(struct clk *clk)
+{
+ u32 div = 1;
+ u32 reg;
+ unsigned long val;
+
+ if ((clk->parent == &pll3_sw_clk) || (clk->parent == &osc_clk)) {
+ reg = __raw_readl(MXC_CCM_CBCDR)
+ & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK;
+ div = (reg >> MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET) + 1;
+ }
+ val = clk_get_rate(clk->parent) / div;
+ return val;
+}
+
+static struct clk periph_clk = {
+ __INIT_CLK_DEBUG(periph_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .set_parent = _clk_periph_set_parent,
+ .get_rate = _clk_periph_get_rate,
+};
+
+static unsigned long _clk_axi_get_rate(struct clk *clk)
+{
+ u32 div, reg;
+ unsigned long val;
+
+ reg = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_AXI_PODF_MASK;
+ div = (reg >> MXC_CCM_CBCDR_AXI_PODF_OFFSET);
+
+ val = clk_get_rate(clk->parent) / (div + 1);
+ return val;
+}
+
+static int _clk_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AXI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AXI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_AXI_PODF_BUSY), SPIN_DELAY))
+ panic("pll _clk_axi_a_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum
+ * value for the clock.
+ * Also prevent a div of 0.
+ */
+
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+
+ return parent_rate / div;
+}
+
+static int _clk_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ int mux;
+
+ mux = _get_mux6(parent, &periph_clk, &pll2_pfd2_400M,
+ &pll3_pfd1_540M, NULL, NULL, NULL);
+
+ if (mux == 0) {
+ /* Set the AXI_SEL mux */
+ reg = __raw_readl(MXC_CCM_CBCDR) & ~MXC_CCM_CBCDR_AXI_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ } else {
+ /* Set the AXI_ALT_SEL mux. */
+ reg = __raw_readl(MXC_CCM_CBCDR)
+ & ~MXC_CCM_CBCDR_AXI_ALT_SEL_MASK;
+ reg |= ((mux - 1) << MXC_CCM_CBCDR_AXI_ALT_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* Set the AXI_SEL mux */
+ reg = __raw_readl(MXC_CCM_CBCDR) & ~MXC_CCM_CBCDR_AXI_SEL;
+ reg |= MXC_CCM_CBCDR_AXI_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ }
+ return 0;
+}
+
+static struct clk axi_clk = {
+ __INIT_CLK_DEBUG(axi_clk)
+ .parent = &periph_clk,
+ .set_parent = _clk_axi_set_parent,
+ .set_rate = _clk_axi_set_rate,
+ .get_rate = _clk_axi_get_rate,
+ .round_rate = _clk_axi_round_rate,
+};
+
+static unsigned long _clk_ahb_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY),
+ SPIN_DELAY))
+ panic("_clk_ahb_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk ahb_clk = {
+ __INIT_CLK_DEBUG(ahb_clk)
+ .parent = &periph_clk,
+ .get_rate = _clk_ahb_get_rate,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+};
+
+static unsigned long _clk_ipg_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+
+static struct clk ipg_clk = {
+ __INIT_CLK_DEBUG(ipg_clk)
+ .parent = &ahb_clk,
+ .get_rate = _clk_ipg_get_rate,
+};
+
+static struct clk tzasc2_clk = {
+ __INIT_CLK_DEBUG(tzasc2_clk)
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk mx6fast1_clk = {
+ __INIT_CLK_DEBUG(mx6fast1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk mx6per1_clk = {
+ __INIT_CLK_DEBUG(mx6per1_clk)
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &mx6fast1_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static int _clk_mmdc_ch1_axi_set_parent(struct clk *clk,
+ struct clk *parent)
+{
+ u32 reg;
+ int mux;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk, &pll2_pfd2_400M,
+ &pll2_pfd0_352M, &pll2_200M, &pll3_sw_clk, NULL);
+
+ if (mux <= 3) {
+ /* Set the pre_periph2_clk_sel multiplexer */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ /* Set the periph2_clk_sel multiplexer. */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ } else {
+ /* Select PLL3_SW_CLK from the periph2_clk2
+ multiplexer */
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_PERIPH2_CLK2_SEL;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ /* Set the periph2_clk_sel multiplexer. */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+ reg |= MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+ }
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY), SPIN_DELAY))
+ panic("_clk_mmdc_ch1_axi_set_parent failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_mmdc_ch1_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) >>
+ MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_mmdc_ch1_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (!WAIT(!(__raw_readl(MXC_CCM_CDHIPR)
+ & MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY), SPIN_DELAY))
+ panic("_clk_mmdc_ch1_axi_set_rate failed\n");
+
+ return 0;
+}
+
+static unsigned long _clk_mmdc_ch1_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk mmdc_ch1_axi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(mmdc_ch1_axi_clk)
+ .id = 0,
+ .parent = &pll2_pfd2_400M,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .secondary = &mmdc_ch1_axi_clk[1],
+ .set_parent = _clk_mmdc_ch1_axi_set_parent,
+ .get_rate = _clk_mmdc_ch1_axi_get_rate,
+ .set_rate = _clk_mmdc_ch1_axi_set_rate,
+ .round_rate = _clk_mmdc_ch1_axi_round_rate,
+ },
+ {
+ .id = 1,
+ __INIT_CLK_DEBUG(mmdc_ch1_ipg_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .secondary = &tzasc2_clk,
+ },
+};
+
+#if defined(CONFIG_SDMA_IRAM) || defined(CONFIG_SND_MXC_SOC_IRAM)
+static struct clk ocram_clk = {
+ __INIT_CLK_DEBUG(ocram_clk)
+ .id = 0,
+ .parent = &axi_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+#endif
+
+static unsigned long _clk_ipg_perclk_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ div = ((reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK) >>
+ MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipg_perclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+
+static unsigned long _clk_ipg_perclk_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static struct clk ipg_perclk = {
+ __INIT_CLK_DEBUG(ipg_perclk)
+ .parent = &osc_clk,
+ .set_parent = _clk_ipg_perclk_set_parent,
+ .get_rate = _clk_ipg_perclk_get_rate,
+ .set_rate = _clk_ipg_perclk_set_rate,
+ .round_rate = _clk_ipg_perclk_round_rate,
+};
+
+static struct clk spba_clk = {
+ __INIT_CLK_DEBUG(spba_clk)
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk sdma_clk[] = {
+ {
+ __INIT_CLK_DEBUG(sdma_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &sdma_clk[1],
+ },
+ {
+ .parent = &mx6per1_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &ocram_clk,
+#else
+ .secondary = &mmdc_ch1_axi_clk[0],
+#endif
+ },
+};
+
+static unsigned long mx6_timer_rate(void)
+{
+ u32 parent_rate = clk_get_rate(&osc_clk);
+
+ u32 reg = __raw_readl(timer_base + MXC_TCTL);
+ u32 div;
+
+ if ((reg & V2_TCTL_CLK_OSC_DIV8) == V2_TCTL_CLK_OSC_DIV8) {
+ if (cpu_is_mx6q())
+ /* For MX6Q, only options are 24MHz or 24MHz/8*/
+ return parent_rate / 8;
+ else {
+ /* For MX6DLS and MX6Solo, the rate is based on the
+ * divider value set in prescalar register. */
+ div = __raw_readl(timer_base + MXC_TPRER);
+ div = (div >> V2_TPRER_PRE24M_OFFSET) &
+ V2_TPRER_PRE24M_MASK;
+ return parent_rate / (div + 1);
+ }
+ }
+ return 0;
+}
+
+static unsigned long _clk_gpt_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0)
+ return clk_get_rate(clk->parent);
+
+ rate = mx6_timer_rate();
+ if (!rate)
+ return clk_get_rate(clk->parent);
+
+ return rate;
+}
+
+static struct clk gpt_clk[] = {
+ {
+ __INIT_CLK_DEBUG(gpt_clk)
+ .parent = &osc_clk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .get_rate = _clk_gpt_get_rate,
+ },
+};
+
+static unsigned long _clk_iim_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk iim_clk = {
+ __INIT_CLK_DEBUG(iim_clk)
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
+ .disable = _clk_disable,
+ .get_rate = _clk_iim_get_rate,
+};
+
+static struct clk i2c_clk[] = {
+ {
+ __INIT_CLK_DEBUG(i2c_clk_0)
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_1)
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(i2c_clk_2)
+ .id = 2,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCDR3)
+ & ~MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &osc_clk,
+ &pll2_pfd2_400M, &pll3_120M, &pll3_pfd1_540M, NULL, NULL);
+
+ reg |= (mux << MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ div = ((reg & MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK) >>
+ MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ reg &= ~MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static struct clk ipu1_clk = {
+ __INIT_CLK_DEBUG(csi_clk)
+ .parent = &osc_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu1_set_parent,
+ .round_rate = _clk_ipu_round_rate,
+ .set_rate = _clk_ipu1_set_rate,
+ .get_rate = _clk_ipu1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_ipu2_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCDR3)
+ & ~MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk,
+ &pll2_pfd2_400M, &pll3_sw_clk, &pll3_pfd1_540M, NULL, NULL);
+
+ reg |= (mux << MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static unsigned long _clk_ipu2_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ div = ((reg & MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK) >>
+ MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_ipu2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ reg &= ~MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR3);
+
+ return 0;
+}
+
+static struct clk ipu2_clk = {
+ __INIT_CLK_DEBUG(elcdif_axi_clk)
+ .parent = &pll2_pfd2_400M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ipu2_set_parent,
+ .round_rate = _clk_ipu_round_rate,
+ .set_rate = _clk_ipu2_set_rate,
+ .get_rate = _clk_ipu2_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk usdhc_dep_clk = {
+ .parent = &mmdc_ch1_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ };
+
+static unsigned long _clk_usdhc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_usdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
+
+ if (parent == &pll2_pfd0_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC1_CLK_SEL);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc1_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk usdhc1_clk = {
+ __INIT_CLK_DEBUG(usdhc1_clk)
+ .id = 0,
+ .parent = &pll2_pfd2_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc1_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc1_set_rate,
+ .get_rate = _clk_usdhc1_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_usdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
+
+ if (parent == &pll2_pfd0_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC2_CLK_SEL);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc2_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC2_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk usdhc2_clk = {
+ __INIT_CLK_DEBUG(usdhc2_clk)
+ .id = 1,
+ .parent = &pll2_pfd2_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc2_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc2_set_rate,
+ .get_rate = _clk_usdhc2_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_usdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
+
+ if (parent == &pll2_pfd0_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC3_CLK_SEL);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc3_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC3_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+
+static struct clk usdhc3_clk = {
+ __INIT_CLK_DEBUG(usdhc3_clk)
+ .id = 2,
+ .parent = &pll2_pfd2_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc3_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc3_set_rate,
+ .get_rate = _clk_usdhc3_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static int _clk_usdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
+
+ if (parent == &pll2_pfd0_352M)
+ reg |= (MXC_CCM_CSCMR1_USDHC4_CLK_SEL);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_usdhc4_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = ((reg & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_usdhc4_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_USDHC4_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+
+static struct clk usdhc4_clk = {
+ __INIT_CLK_DEBUG(usdhc4_clk)
+ .id = 3,
+ .parent = &pll2_pfd2_400M,
+ .secondary = &usdhc_dep_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_usdhc4_set_parent,
+ .round_rate = _clk_usdhc_round_rate,
+ .set_rate = _clk_usdhc4_set_rate,
+ .get_rate = _clk_usdhc4_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_ssi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK |
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static unsigned long _clk_extern_audio_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_extern_audio_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2) & ~MXC_CCM_CSCMR2_ESAI_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll4_audio_main_clk, &pll3_pfd2_508M,
+ &pll3_pfd3_454M, &pll3_sw_clk, NULL, NULL);
+ reg |= mux << MXC_CCM_CSCMR2_ESAI_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static unsigned long _clk_extern_audio_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ pred = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_extern_audio_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ if (rate == 24000000 && clk->parent == &pll4_audio_main_clk) {
+ /* If the requested rate is 24MHz,
+ * set the PLL4 to bypass mode.
+ */
+ audio_pll_bypass = 1;
+ pre = post = 1;
+ } else {
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 64)
+ return -EINVAL;
+
+ audio_pll_bypass = 0;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+ }
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK|
+ MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+static struct clk extern_audio_clk = {
+ __INIT_CLK_DEBUG(extern_audio_clk)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_rate = _clk_extern_audio_set_rate,
+ .get_rate = _clk_extern_audio_get_rate,
+ .set_parent = _clk_extern_audio_set_parent,
+ .round_rate = _clk_extern_audio_round_rate,
+};
+
+
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd2_508M, &pll3_pfd3_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi1_clk)
+ .parent = &pll3_pfd2_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi1_set_parent,
+ .set_rate = _clk_ssi1_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi1_get_rate,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#ifndef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &mmdc_ch1_axi_clk[0],
+#else
+ .secondary = &ocram_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK)
+ >> MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK)
+ >> MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~(MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK |
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ return 0;
+}
+
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd2_508M, &pll3_pfd3_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi2_clk)
+ .parent = &pll3_pfd2_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi2_set_parent,
+ .set_rate = _clk_ssi2_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi2_get_rate,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#ifndef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &mmdc_ch1_axi_clk[0],
+#else
+ .secondary = &ocram_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_ssi3_get_rate(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK)
+ >> MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (prediv * podf);
+}
+
+static int _clk_ssi3_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 512)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 6, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~(MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK|
+ MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK);
+ reg |= (post - 1) << MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ return 0;
+}
+
+
+static int _clk_ssi3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd2_508M, &pll3_pfd3_454M,
+ &pll4_audio_main_clk, NULL, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ssi3_clk)
+ .parent = &pll3_pfd2_508M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ssi3_set_parent,
+ .set_rate = _clk_ssi3_set_rate,
+ .round_rate = _clk_ssi_round_rate,
+ .get_rate = _clk_ssi3_get_rate,
+ .flags = AHB_AUDIO_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+#ifndef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &mmdc_ch1_axi_clk[0],
+#else
+ .secondary = &ocram_clk,
+#endif
+ },
+};
+
+static unsigned long _clk_epdc_lcdif_pix_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ /* Round to closest divisor */
+ if ((parent_rate % rate) > (rate / 2))
+ div++;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static unsigned long _clk_pxp_epdc_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ /* Round to closest divisor */
+ if ((parent_rate % rate) > (rate / 2))
+ div++;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static unsigned long _clk_pxp_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+
+ div = ((reg & MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK) >>
+ MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_pxp_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+ reg &= ~MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static int _clk_pxp_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk,
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd0_352M, &pll2_pfd2_400M, &pll3_pfd1_540M);
+ reg |= (mux << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ /* Derive clock from divided pre-muxed pxp_axi clock.*/
+ mux = 0;
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET),
+ MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_epdc_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+
+ div = ((reg & MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK)
+ >> MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_epdc_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR);
+ reg &= ~MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static int _clk_epdc_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk,
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd0_352M, &pll2_pfd2_400M, &pll3_pfd1_540M);
+ reg |= (mux << MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CHSCCDR);
+
+ /* Derive clock from divided pre-muxed ipu1_di0 clock.*/
+ mux = 0;
+ reg = __raw_readl(MXC_CCM_CHSCCDR)
+ & ~MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET),
+ MXC_CCM_CHSCCDR);
+
+ return 0;
+}
+
+static struct clk pxp_axi_clk = {
+ __INIT_CLK_DEBUG(pxp_axi_clk)
+ .id = 0,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_pxp_axi_set_parent,
+ .set_rate = _clk_pxp_axi_set_rate,
+ .round_rate = _clk_pxp_epdc_axi_round_rate,
+ .get_rate = _clk_pxp_axi_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk epdc_axi_clk = {
+ __INIT_CLK_DEBUG(epdc_axi_clk)
+ .id = 0,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_epdc_axi_set_parent,
+ .set_rate = _clk_epdc_axi_set_rate,
+ .round_rate = _clk_pxp_epdc_axi_round_rate,
+ .get_rate = _clk_epdc_axi_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_lcdif_pix_get_rate(struct clk *clk)
+{
+ u32 reg, pre, post;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+
+ pre = ((reg & MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK) >>
+ MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET) + 1;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ post = ((reg & MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pre * post);
+}
+
+static int _clk_lcdif_pix_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK;
+ reg |= (pre - 1) << MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ /*
+ * fixup:
+ * Bits 22 and 21 of the divide value are inverted before
+ * going into the divider port.
+ */
+ post = (post - 1) ^ 0x6;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK;
+ reg |= post << MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static int _clk_lcdif_pix_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk,
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd0_352M, &pll3_pfd0_720M, &pll3_pfd1_540M);
+ reg |= (mux << MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ /* Derive clock from divided pre-muxed lcdif_pix clock.*/
+ mux = 0;
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK;
+ __raw_writel(reg | (mux << MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET),
+ MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static unsigned long _clk_epdc_pix_get_rate(struct clk *clk)
+{
+ u32 reg, pre, post;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+
+ pre = ((reg & MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK) >>
+ MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET) + 1;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ post = ((reg & MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET) + 1;
+
+
+ return clk_get_rate(clk->parent) / (pre * post);
+}
+
+static int _clk_epdc_pix_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK;
+ reg |= (pre - 1) << MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK;
+ reg |= (post - 1) << MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static int _clk_epdc_pix_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2)
+ & ~MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_528_bus_main_clk,
+ &pll3_usb_otg_main_clk, &pll5_video_main_clk,
+ &pll2_pfd0_352M, &pll2_pfd1_594M, &pll3_pfd1_540M);
+ reg |= (mux << MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static struct clk lcdif_pix_clk = {
+ __INIT_CLK_DEBUG(lcdif_pix_clk)
+ .id = 0,
+ .parent = &pll5_video_main_clk,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_lcdif_pix_set_parent,
+ .set_rate = _clk_lcdif_pix_set_rate,
+ .round_rate = _clk_epdc_lcdif_pix_round_rate,
+ .get_rate = _clk_lcdif_pix_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static struct clk epdc_pix_clk = {
+ __INIT_CLK_DEBUG(epdc_pix_clk)
+ .id = 0,
+ .parent = &pll3_pfd1_540M,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_epdc_pix_set_parent,
+ .set_rate = _clk_epdc_pix_set_rate,
+ .round_rate = _clk_epdc_lcdif_pix_round_rate,
+ .get_rate = _clk_epdc_pix_get_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+static unsigned long _clk_spdif_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (parent_rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ return parent_rate / (pre * post);
+}
+
+static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CDCDR)
+ & ~MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll4_audio_main_clk,
+ &pll3_pfd2_508M, &pll3_pfd3_454M,
+ &pll3_sw_clk, NULL, NULL);
+ reg |= mux << MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static unsigned long _clk_spdif0_get_rate(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK)
+ >> MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK)
+ >> MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / (pred * podf);
+}
+
+static int _clk_spdif0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, pre, post;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || div > 64)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(1 << 3, div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~(MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK|
+ MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ return 0;
+}
+
+static struct clk spdif0_clk[] = {
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_0)
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &spdif0_clk[1],
+ .set_rate = _clk_spdif0_set_rate,
+ .get_rate = _clk_spdif0_get_rate,
+ .set_parent = _clk_spdif0_set_parent,
+ .round_rate = _clk_spdif_round_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ __INIT_CLK_DEBUG(spdif0_clk_1)
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ },
+};
+
+static int _clk_ecspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2) & ~MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK;
+
+ if (parent == &pll3_60M)
+ mux = 0;
+ else
+ mux = 1; /* osc */
+
+ reg |= mux << MXC_CCM_CSCDR2_ECSPI_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+
+ return 0;
+}
+
+static int _clk_fec_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int reg, div = 1;
+
+ switch (rate) {
+ case 25000000:
+ div = 0;
+ break;
+ case 50000000:
+ div = 1;
+ break;
+ case 100000000:
+ div = 2;
+ break;
+ case 125000000:
+ div = 3;
+ break;
+ default:
+ return -EINVAL;
+ }
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_DIV_SELECT_MASK;
+ reg |= (div << ANADIG_PLL_ENET_DIV_SELECT_OFFSET);
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ return 0;
+}
+
+static unsigned long _clk_fec_get_rate(struct clk *clk)
+{
+ unsigned int div;
+
+ div = (__raw_readl(PLL8_ENET_BASE_ADDR))
+ & ANADIG_PLL_ENET_DIV_SELECT_MASK;
+
+ switch (div) {
+ case 0:
+ div = 20;
+ break;
+ case 1:
+ div = 10;
+ break;
+ case 3:
+ div = 5;
+ break;
+ case 4:
+ div = 4;
+ break;
+ }
+
+ return 500000000 / div;
+}
+
+static int _clk_fec_enable(struct clk *clk)
+{
+ unsigned int reg;
+
+ /* Enable ENET ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_BYPASS;
+ reg |= ANADIG_PLL_ENABLE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ _clk_enable(clk);
+ return 0;
+}
+
+static void _clk_fec_disable(struct clk *clk)
+{
+ unsigned int reg;
+
+ _clk_disable(clk);
+
+ /* Enable ENET ref clock */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_BYPASS;
+ reg &= ~ANADIG_PLL_ENABLE;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+}
+
+static struct clk fec_clk[] = {
+ {
+ __INIT_CLK_DEBUG(fec_clk)
+ .id = 0,
+ .parent = &pll6_enet_main_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_fec_enable,
+ .disable = _clk_fec_disable,
+ .set_rate = _clk_fec_set_rate,
+ .get_rate = _clk_fec_get_rate,
+ .secondary = &fec_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch1_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static unsigned long _clk_fec_mdc_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent);
+}
+
+static struct clk fec_mdc_clk = {
+ __INIT_CLK_DEBUG(fec_mdc_clk)
+ .parent = &ipg_clk,
+ .get_rate = _clk_fec_mdc_get_rate,
+};
+
+static struct clk ecspi_clk[] = {
+ {
+ __INIT_CLK_DEBUG(ecspi0_clk)
+ .id = 0,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ecspi_set_parent,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi1_clk)
+ .id = 1,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ecspi_set_parent,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi2_clk)
+ .id = 2,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ecspi_set_parent,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi3_clk)
+ .id = 3,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ecspi_set_parent,
+ },
+ {
+ __INIT_CLK_DEBUG(ecspi4_clk)
+ .id = 4,
+ .parent = &pll3_60M,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_parent = _clk_ecspi_set_parent,
+ },
+};
+
+static unsigned long _clk_emi_slow_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_emi_slow_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CSCMR1)
+ & ~MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
+
+ mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd2_400M, &pll3_pfd0_720M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_slow_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ div = ((reg & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK) >>
+ MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_emi_slow_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk emi_slow_clk = {
+ __INIT_CLK_DEBUG(emi_slow_clk)
+ .id = 0,
+ .parent = &axi_clk,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .set_rate = _clk_emi_slow_set_rate,
+ .get_rate = _clk_emi_slow_get_rate,
+ .round_rate = _clk_emi_slow_round_rate,
+ .set_parent = _clk_emi_slow_set_parent,
+};
+
+static unsigned long _clk_uart_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 64)
+ div = 64;
+
+ return parent_rate / div;
+}
+
+static int _clk_uart_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 64))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1) & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg |= ((div - 1) << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET);
+
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static unsigned long _clk_uart_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+ unsigned long val;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1) & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ div = (reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+ val = clk_get_rate(clk->parent) / div;
+
+ /* If the parent is OSC, there is an in-built divide by 6. */
+ if (clk->parent == &osc_clk)
+ val = val / 6;
+
+ return val;
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1) & ~MXC_CCM_CSCDR1_UART_CLK_SEL_MASK;
+
+ if (parent == &osc_clk)
+ mux = 1;
+ else
+ mux = 0; /* osc */
+
+ reg |= mux << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET;
+
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ return 0;
+}
+
+static struct clk uart_clk[] = {
+ {
+ __INIT_CLK_DEBUG(uart_clk)
+ .id = 0,
+ .parent = &pll3_80M,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &uart_clk[1],
+ .set_rate = _clk_uart_set_rate,
+ .get_rate = _clk_uart_get_rate,
+ .round_rate = _clk_uart_round_rate,
+ .set_parent = _clk_uart_set_parent,
+ },
+ {
+ __INIT_CLK_DEBUG(uart_serial_clk)
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk aips_tz2_clk = {
+ __INIT_CLK_DEBUG(aips_tz2_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz1_clk = {
+ __INIT_CLK_DEBUG(aips_tz1_clk)
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+/* Raster 2D and OpenVG GPU core share the same clock gate bits,
+ * so we abstract gpu2d_core_clk to handle clock gate enabling
+ * and disabling for both 2D core. These two 2D core have
+ * different multiplexer, so gpu2d_axi_clk and openvg_axi_clk
+ * are provided for them to control the multiplexer individually.
+*/
+static struct clk gpu2d_core_clk = {
+ __INIT_CLK_DEBUG(gpu2d_core_clk)
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+ .disable = _clk_disable,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_openvg_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_openvg_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR)
+ & ~MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll3_pfd1_540M,
+ &pll3_usb_otg_main_clk,
+ &pll2_528_bus_main_clk, &pll2_pfd2_400M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long _clk_openvg_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ div = ((reg & MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_openvg_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (div > 8)
+ div = 8;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk openvg_axi_clk = {
+ __INIT_CLK_DEBUG(openvg_axi_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .set_parent = _clk_openvg_axi_set_parent,
+ .set_rate = _clk_openvg_axi_set_rate,
+ .get_rate = _clk_openvg_axi_get_rate,
+ .round_rate = _clk_openvg_axi_round_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+static unsigned long _clk_gpu2d_axi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+
+ if (div > 8)
+ div = 8;
+
+ return parent_rate / div;
+}
+
+static int _clk_gpu2d_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ int mux;
+ u32 reg = __raw_readl(MXC_CCM_CBCMR) &
+ ~MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK;
+
+ mux = _get_mux6(parent, &pll2_pfd2_400M, &pll3_usb_otg_main_clk,
+ &pll3_pfd1_540M, &pll2_528_bus_main_clk, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static unsigned long _clk_gpu2d_axi_get_rate(struct clk *clk)
+{
+ u32 reg, div = 1;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ div = ((reg & MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK) >>
+ MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET) + 1;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_gpu2d_axi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+ u32 parent_rate = clk_get_rate(clk->parent);
+
+ div = parent_rate / rate;
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg &= ~MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu2d_axi_clk = {
+ __INIT_CLK_DEBUG(gpu2d_axi_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .set_parent = _clk_gpu2d_axi_set_parent,
+ .set_rate = _clk_gpu2d_axi_set_rate,
+ .get_rate = _clk_gpu2d_axi_get_rate,
+ .round_rate = _clk_gpu2d_axi_round_rate,
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+};
+
+/* set the parent by the ipcg table */
+
+static struct clk pwm_clk[] = {
+ {
+ __INIT_CLK_DEBUG(pwm_clk_0)
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_1)
+ .parent = &ipg_perclk,
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_2)
+ .parent = &ipg_perclk,
+ .id = 2,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ __INIT_CLK_DEBUG(pwm_clk_3)
+ .parent = &ipg_perclk,
+ .id = 3,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk usboh3_clk[] = {
+ {
+ __INIT_CLK_DEBUG(usboh3_clk)
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usboh3_clk[1],
+ .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .parent = &mmdc_ch1_axi_clk[0],
+ .secondary = &mx6per1_clk,
+ },
+};
+
+static int _clk_enable1(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable1(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &pll3_usb_otg_main_clk)
+ sel = 0;
+ else if (parent == &pll2_528_bus_main_clk)
+ sel = 1;
+ else if (parent == &pll1_sys_main_clk)
+ sel = 2;
+ else if (parent == &pll5_video_main_clk)
+ sel = 3;
+ else if (parent == &axi_clk)
+ sel = 5;
+ else if (parent == &pxp_axi_clk)
+ sel = 7;
+ else if (parent == &epdc_axi_clk)
+ sel = 8;
+ else if (parent == &lcdif_pix_clk)
+ sel = 9;
+ else if (parent == &epdc_pix_clk)
+ sel = 10;
+ else if (parent == &ahb_clk)
+ sel = 11;
+ else if (parent == &ipg_clk)
+ sel = 12;
+ else if (parent == &ipg_perclk)
+ sel = 13;
+ else if (parent == &ckil_clk)
+ sel = 14;
+ else if (parent == &pll4_audio_main_clk)
+ sel = 15;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_SEL_MASK;
+ reg |= sel << MXC_CCM_CCOSR_CKOL_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko_get_rate(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCOSR);
+ u32 div = ((reg & MXC_CCM_CCOSR_CKOL_DIV_MASK) >>
+ MXC_CCM_CCOSR_CKOL_DIV_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ /* Make sure rate is not greater than the maximum value for the clock.
+ * Also prevent a div of 0.
+ */
+ if (div == 0)
+ div++;
+ if (div > 8)
+ div = 8;
+ return parent_rate / div;
+}
+
+static int _clk_clko2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &mmdc_ch1_axi_clk[0])
+ sel = 0;
+ else if (parent == &usdhc4_clk)
+ sel = 2;
+ else if (parent == &usdhc1_clk)
+ sel = 3;
+ else if (parent == &ecspi_clk[0])
+ sel = 6;
+ else if (parent == &usdhc3_clk)
+ sel = 8;
+ else if (parent == &ipu1_clk)
+ sel = 11;
+ else if (parent == &ipu2_clk)
+ sel = 12;
+
+ else if (parent == &osc_clk)
+ sel = 14;
+ else if (parent == &usdhc2_clk)
+ sel = 17;
+ else if (parent == &ssi1_clk[0])
+ sel = 18;
+ else if (parent == &ssi2_clk[0])
+ sel = 19;
+ else if (parent == &ssi3_clk[0])
+ sel = 20;
+ else if (parent == &uart_clk[0])
+ sel = 28;
+ else if (parent == &spdif0_clk[0])
+ sel = 29;
+ else if (parent == &spdif0_clk[1])
+ sel = 30;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKO2_SEL_MASK;
+ reg |= sel << MXC_CCM_CCOSR_CKO2_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long _clk_clko2_get_rate(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCOSR);
+ u32 div = ((reg & MXC_CCM_CCOSR_CKO2_DIV_MASK) >>
+ MXC_CCM_CCOSR_CKO2_DIV_OFFSET) + 1;
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int _clk_clko2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 parent_rate = clk_get_rate(clk->parent);
+ u32 div = parent_rate / rate;
+
+ if (div == 0)
+ div++;
+ if (((parent_rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKO2_DIV_MASK;
+ reg |= (div - 1) << MXC_CCM_CCOSR_CKO2_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static struct clk clko_clk = {
+ __INIT_CLK_DEBUG(clko_clk)
+ .parent = &pll2_528_bus_main_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCOSR,
+ .enable_shift = MXC_CCM_CCOSR_CKOL_EN_OFFSET,
+ .disable = _clk_disable1,
+ .set_parent = _clk_clko_set_parent,
+ .set_rate = _clk_clko_set_rate,
+ .get_rate = _clk_clko_get_rate,
+ .round_rate = _clk_clko_round_rate,
+};
+
+static struct clk clko2_clk = {
+ __INIT_CLK_DEBUG(clko2_clk)
+ .parent = &usdhc4_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCOSR,
+ .enable_shift = MXC_CCM_CCOSR_CKO2_EN_OFFSET,
+ .disable = _clk_disable1,
+ .set_parent = _clk_clko2_set_parent,
+ .set_rate = _clk_clko2_set_rate,
+ .get_rate = _clk_clko2_get_rate,
+ .round_rate = _clk_clko_round_rate,
+};
+
+static struct clk perfmon0_clk = {
+ __INIT_CLK_DEBUG(perfmon0_clk)
+ .parent = &mmdc_ch1_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon1_clk = {
+ __INIT_CLK_DEBUG(perfmon1_clk)
+ .parent = &ipu1_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon2_clk = {
+ __INIT_CLK_DEBUG(perfmon2_clk)
+ .parent = &mmdc_ch1_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk dummy_clk = {
+ .id = 0,
+};
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ }
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "osc", osc_clk),
+ _REGISTER_CLOCK(NULL, "ckih", ckih_clk),
+ _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk),
+ _REGISTER_CLOCK(NULL, "ckil", ckil_clk),
+ _REGISTER_CLOCK(NULL, "pll1_main_clk", pll1_sys_main_clk),
+ _REGISTER_CLOCK(NULL, "pll1_sw_clk", pll1_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll2", pll2_528_bus_main_clk),
+ _REGISTER_CLOCK(NULL, "pll2_pfd_400M", pll2_pfd2_400M),
+ _REGISTER_CLOCK(NULL, "pll2_pfd0_352M", pll2_pfd0_352M),
+ _REGISTER_CLOCK(NULL, "pll2_pfd1_594M", pll2_pfd1_594M),
+ _REGISTER_CLOCK(NULL, "pll2_200M", pll2_200M),
+ _REGISTER_CLOCK(NULL, "pll3_main_clk", pll3_usb_otg_main_clk),
+ _REGISTER_CLOCK(NULL, "pll3_pfd2_508M", pll3_pfd2_508M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd3_454M", pll3_pfd3_454M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd0_720M", pll3_pfd0_720M),
+ _REGISTER_CLOCK(NULL, "pll3_pfd_540M", pll3_pfd1_540M),
+ _REGISTER_CLOCK(NULL, "pll3_sw_clk", pll3_sw_clk),
+ _REGISTER_CLOCK(NULL, "pll3_120M", pll3_120M),
+ _REGISTER_CLOCK(NULL, "pll3_80M", pll3_80M),
+ _REGISTER_CLOCK(NULL, "pll3_60M", pll3_60M),
+ _REGISTER_CLOCK(NULL, "pll4", pll4_audio_main_clk),
+ _REGISTER_CLOCK(NULL, "pll5", pll5_video_main_clk),
+ _REGISTER_CLOCK(NULL, "pll6", pll6_enet_main_clk),
+ _REGISTER_CLOCK(NULL, "extern_audio_clk", extern_audio_clk),
+ _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk),
+ _REGISTER_CLOCK("smp_twd", NULL, twd_clk),
+ _REGISTER_CLOCK(NULL, "periph_clk", periph_clk),
+ _REGISTER_CLOCK(NULL, "axi_clk", axi_clk),
+ _REGISTER_CLOCK(NULL, "mmdc_ch0_axi", mmdc_ch1_axi_clk[0]),
+ _REGISTER_CLOCK(NULL, "ahb", ahb_clk),
+ _REGISTER_CLOCK(NULL, "ipg_clk", ipg_clk),
+ _REGISTER_CLOCK(NULL, "ipg_perclk", ipg_perclk),
+ _REGISTER_CLOCK(NULL, "spba", spba_clk),
+ _REGISTER_CLOCK("imx-sdma", NULL, sdma_clk[0]),
+ _REGISTER_CLOCK(NULL, "iim_clk", iim_clk),
+ _REGISTER_CLOCK(NULL, "i2c_clk", i2c_clk[0]),
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk[1]),
+ _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk[2]),
+ _REGISTER_CLOCK(NULL, "csi_clk", ipu1_clk),
+ _REGISTER_CLOCK(NULL, "elcdif_axi", ipu2_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, usdhc1_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, usdhc2_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, usdhc3_clk),
+ _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, usdhc4_clk),
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk[0]),
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk[0]),
+ _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk[0]),
+ _REGISTER_CLOCK(NULL, "pxp_axi", pxp_axi_clk),
+ _REGISTER_CLOCK(NULL, "epdc_axi", epdc_axi_clk),
+ _REGISTER_CLOCK(NULL, "epdc_pix", epdc_pix_clk),
+ _REGISTER_CLOCK(NULL, "elcdif_pix", lcdif_pix_clk),
+ _REGISTER_CLOCK("mxc_spdif.0", NULL, spdif0_clk[0]),
+ _REGISTER_CLOCK("imx6q-ecspi.0", NULL, ecspi_clk[0]),
+ _REGISTER_CLOCK("imx6q-ecspi.1", NULL, ecspi_clk[1]),
+ _REGISTER_CLOCK("imx6q-ecspi.2", NULL, ecspi_clk[2]),
+ _REGISTER_CLOCK("imx6q-ecspi.3", NULL, ecspi_clk[3]),
+ _REGISTER_CLOCK("imx6q-ecspi.4", NULL, ecspi_clk[4]),
+ _REGISTER_CLOCK(NULL, "emi_slow_clk", emi_slow_clk),
+ _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[0]),
+ _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpt", gpt_clk[0]),
+ _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk[0]),
+ _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm_clk[1]),
+ _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm_clk[2]),
+ _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm_clk[3]),
+ _REGISTER_CLOCK(NULL, "fec_clk", fec_clk[0]),
+ _REGISTER_CLOCK(NULL, "fec_mdc_clk", fec_mdc_clk),
+ _REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk[0]),
+ _REGISTER_CLOCK(NULL, "usb_phy1_clk", usb_phy1_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy3_clk", usb_phy3_clk),
+ _REGISTER_CLOCK(NULL, "usb_phy4_clk", usb_phy4_clk),
+ _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk),
+ _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk),
+ _REGISTER_CLOCK(NULL, "kpp", dummy_clk),
+ _REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
+ _REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
+ _REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
+ _REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk),
+ _REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
+ _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
+ _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
+ _REGISTER_CLOCK(NULL, "anaclk_1", anaclk_1),
+ _REGISTER_CLOCK(NULL, "anaclk_2", anaclk_2),
+ _REGISTER_CLOCK(NULL, "gpu2d_clk", gpu2d_core_clk),
+ _REGISTER_CLOCK(NULL, "gpu2d_axi_clk", gpu2d_axi_clk),
+ _REGISTER_CLOCK(NULL, "openvg_axi_clk", openvg_axi_clk),
+ _REGISTER_CLOCK(NULL, "rng_clk", dummy_clk),
+ _REGISTER_CLOCK(NULL, "dcp_clk", dummy_clk),
+};
+
+static void clk_tree_init(void)
+
+{
+ unsigned int reg;
+
+ reg = __raw_readl(MMDC_MDMISC_OFFSET);
+ /*
+ * For lpddr2 board, current freq only support up to 400MHz,
+ * in this case, periph clk will set to 400MHz in uboot,
+ * so in clock init, we need to check whether the ddr clock
+ * is set to 400MHz, if yes, then we should set periph clk
+ * parent to pll2_pfd2_400M.
+ */
+ if ((reg & MMDC_MDMISC_DDR_TYPE_MASK) ==
+ (0x1 << MMDC_MDMISC_DDR_TYPE_OFFSET)) {
+ clk_set_parent(&periph_clk, &pll2_pfd2_400M);
+ }
+}
+
+
+int __init mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2)
+{
+ int i;
+ u32 parent_rate, rate;
+ unsigned long ipg_clk_rate, max_arm_wait_clk;
+
+ external_low_reference = ckil;
+ external_high_reference = ckih1;
+ ckih2_reference = ckih2;
+ oscillator_reference = osc;
+
+ timer_base = ioremap(GPT_BASE_ADDR, SZ_4K);
+ apll_base = ioremap(ANATOP_BASE_ADDR, SZ_4K);
+
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ clkdev_add(&lookups[i]);
+ clk_debug_register(lookups[i].clk);
+ }
+
+ /* GPT will source from perclk, hence ipg_perclk
+ * should be from OSC24M */
+ clk_set_parent(&ipg_perclk, &osc_clk);
+
+
+ /*IPG_PERCLK sources I2C.
+ * I2C needs a minimum of 12.8MHz as its source
+ * to acheive 400KHz speed.
+ * Hence set ipg_perclk to 24MHz.
+ */
+
+ clk_set_rate(&ipg_perclk, 24000000);
+
+ gpt_clk[0].parent = &ipg_perclk;
+ gpt_clk[0].get_rate = NULL;
+
+ mxc_timer_init(&gpt_clk[0], timer_base, MXC_INT_GPT);
+
+ /* keep correct count. */
+ clk_enable(&cpu_clk);
+ clk_enable(&periph_clk);
+ clk_enable(&mmdc_ch1_axi_clk[0]);
+
+ clk_tree_init();
+
+ /* Set AHB to 132MHz. */
+ clk_set_rate(&ahb_clk, clk_round_rate(&ahb_clk, 132000000));
+
+ /* Disable un-necessary PFDs & PLLs */
+ pll2_pfd0_352M.disable(&pll2_pfd0_352M);
+ pll2_pfd1_594M.disable(&pll2_pfd1_594M);
+
+ pll3_pfd3_454M.disable(&pll3_pfd3_454M);
+ pll3_pfd2_508M.disable(&pll3_pfd2_508M);
+ pll3_pfd1_540M.disable(&pll3_pfd1_540M);
+ pll3_pfd0_720M.disable(&pll3_pfd0_720M);
+
+ pll3_usb_otg_main_clk.disable(&pll3_usb_otg_main_clk);
+ pll4_audio_main_clk.disable(&pll4_audio_main_clk);
+ pll5_video_main_clk.disable(&pll5_video_main_clk);
+ pll6_enet_main_clk.disable(&pll6_enet_main_clk);
+
+ /* Initialize Audio and Video PLLs to valid frequency (650MHz). */
+ clk_set_rate(&pll4_audio_main_clk, 650000000);
+ clk_set_rate(&pll5_video_main_clk, 650000000);
+
+ clk_set_parent(&clko_clk, &ipg_clk);
+
+ mx6_cpu_op_init();
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ /* Gate off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(3 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG2_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG1_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR0);
+ }
+ __raw_writel(3 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG11_OFFSET, MXC_CCM_CCGR1);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG10_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG9_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG8_OFFSET, MXC_CCM_CCGR2);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG14_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG13_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG12_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG11_OFFSET |
+ 3 << MXC_CCM_CCGRx_CG10_OFFSET, MXC_CCM_CCGR3);
+ __raw_writel(3 << MXC_CCM_CCGRx_CG7_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG6_OFFSET |
+ 1 << MXC_CCM_CCGRx_CG4_OFFSET, MXC_CCM_CCGR4);
+ __raw_writel(1 << MXC_CCM_CCGRx_CG0_OFFSET, MXC_CCM_CCGR5);
+
+ __raw_writel(0, MXC_CCM_CCGR6);
+
+ /* Bypass MMDC_CH0 handshake */
+ __raw_writel(0x20000, MXC_CCM_CCDR);
+
+ /* S/PDIF */
+ clk_set_parent(&spdif0_clk[0], &pll3_pfd3_454M);
+
+ /* pxp & epdc axi */
+ clk_set_parent(&pxp_axi_clk, &pll2_pfd2_400M);
+ clk_set_rate(&pxp_axi_clk, 198000000);
+ clk_set_parent(&epdc_axi_clk, &pll2_pfd2_400M);
+ clk_set_rate(&epdc_axi_clk, 198000000);
+
+ /* epdc pix - PLL5 as parent */
+ clk_set_parent(&epdc_pix_clk, &pll5_video_main_clk);
+ /* lcdif pix - PLL5 as parent */
+ clk_set_parent(&lcdif_pix_clk, &pll5_video_main_clk);
+
+ clk_set_parent(&ssi2_clk[0], &pll4_audio_main_clk);
+
+ lp_high_freq = 0;
+ lp_med_freq = 0;
+
+ /* Get current ARM_PODF value */
+ rate = clk_get_rate(&cpu_clk);
+ parent_rate = clk_get_rate(&pll1_sw_clk);
+ cur_arm_podf = parent_rate / rate;
+
+ /* Calculate the ARM_PODF to be applied when the system
+ * enters WAIT state.
+ * The max ARM clk is decided by the ipg_clk and has to
+ * follow the ratio of ARM_CLK:IPG_CLK of 12:5.
+ */
+ ipg_clk_rate = clk_get_rate(&ipg_clk);
+ max_arm_wait_clk = (12 * ipg_clk_rate) / 5;
+ wait_mode_arm_podf = parent_rate / max_arm_wait_clk;
+
+#if 1
+ _clk_disable(&gpu2d_core_clk);
+#endif
+ return 0;
+
+}
diff --git a/arch/arm/mach-mx6/cpu.c b/arch/arm/mach-mx6/cpu.c
new file mode 100644
index 00000000..86df0826
--- /dev/null
+++ b/arch/arm/mach-mx6/cpu.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/iram_alloc.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+
+struct cpu_op *(*get_cpu_op)(int *op);
+bool enable_wait_mode = true;
+u32 enable_ldo_mode = LDO_MODE_DEFAULT;
+u32 arm_max_freq = CPU_AT_1_2GHz;
+bool mem_clk_on_in_wait;
+int chip_rev;
+unsigned long iram_tlb_base_addr;
+unsigned long iram_tlb_phys_addr;
+
+void __iomem *gpc_base;
+void __iomem *ccm_base;
+
+extern unsigned int num_cpu_idle_lock;
+
+static int cpu_silicon_rev = -1;
+#define MX6_USB_ANALOG_DIGPROG 0x260
+#define MX6SL_USB_ANALOG_DIGPROG 0x280
+
+unsigned long save_ttbr1(void)
+{
+ unsigned long lttbr1;
+ asm volatile(
+ ".align 4\n"
+ "mrc p15, 0, %0, c2, c0, 1\n"
+ : "=r" (lttbr1)
+ );
+ return lttbr1;
+}
+
+void restore_ttbr1(u32 ttbr1)
+{
+ asm volatile(
+ ".align 4\n"
+ "mcr p15, 0, %0, c2, c0, 1\n"
+ : : "r" (ttbr1)
+ );
+}
+
+static int mx6_get_srev(void)
+{
+ void __iomem *anatop = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ u32 rev;
+ if (cpu_is_mx6sl())
+ rev = __raw_readl(anatop + MX6SL_USB_ANALOG_DIGPROG);
+ else
+ rev = __raw_readl(anatop + MX6_USB_ANALOG_DIGPROG);
+
+ rev &= 0xff;
+
+ if (rev == 0)
+ return IMX_CHIP_REVISION_1_0;
+ else if (rev == 1)
+ return IMX_CHIP_REVISION_1_1;
+ else if (rev == 2)
+ return IMX_CHIP_REVISION_1_2;
+
+ return IMX_CHIP_REVISION_UNKNOWN;
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ */
+int mx6q_revision(void)
+{
+ if (!cpu_is_mx6q())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = mx6_get_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx6q_revision);
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ */
+int mx6dl_revision(void)
+{
+ if (!cpu_is_mx6dl())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = mx6_get_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx6dl_revision);
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ */
+int mx6sl_revision(void)
+{
+ if (!cpu_is_mx6sl())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = mx6_get_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx6sl_revision);
+
+static int __init post_cpu_init(void)
+{
+ unsigned int reg;
+ void __iomem *base;
+ u32 iram_size;
+
+ if (cpu_is_mx6q())
+ iram_size = MX6Q_IRAM_SIZE;
+ else
+ iram_size = MX6DL_MX6SL_IRAM_SIZE;
+
+ iram_init(MX6Q_IRAM_BASE_ADDR, iram_size);
+
+ base = ioremap(AIPS1_ON_BASE_ADDR, PAGE_SIZE);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+ iounmap(base);
+
+ base = ioremap(AIPS2_ON_BASE_ADDR, PAGE_SIZE);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+ iounmap(base);
+
+ /* Force IOMUXC irq to be pending for CCM LPM */
+ base = IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR);
+ reg = __raw_readl(base + 0x4);
+ reg |= 0x1000;
+ __raw_writel(reg, base + 0x4);
+
+ /* Allow SCU_CLK to be disabled when all cores are in WFI*/
+ base = IO_ADDRESS(SCU_BASE_ADDR);
+ reg = __raw_readl(base);
+ reg |= 0x20;
+ __raw_writel(reg, base);
+
+ /* Disable SRC warm reset to work aound system reboot issue */
+ base = IO_ADDRESS(SRC_BASE_ADDR);
+ reg = __raw_readl(base);
+ reg &= ~0x1;
+ __raw_writel(reg, base);
+
+ gpc_base = MX6_IO_ADDRESS(GPC_BASE_ADDR);
+ ccm_base = MX6_IO_ADDRESS(CCM_BASE_ADDR);
+
+ /* enable AXI cache for VDOA/VPU/IPU
+ * set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7
+ * clear OCRAM_CTL bits to disable pipeline control
+ */
+ reg = __raw_readl(IOMUXC_GPR3);
+ reg &= ~IOMUXC_GPR3_OCRAM_CTL_EN;
+ __raw_writel(reg, IOMUXC_GPR3);
+ reg = __raw_readl(IOMUXC_GPR4);
+ reg |= IOMUXC_GPR4_VDOA_CACHE_EN | IOMUXC_GPR4_VPU_CACHE_EN |
+ IOMUXC_GPR4_IPU_CACHE_EN;
+ __raw_writel(reg, IOMUXC_GPR4);
+ __raw_writel(IOMUXC_GPR6_IPU1_QOS, IOMUXC_GPR6);
+ __raw_writel(IOMUXC_GPR7_IPU2_QOS, IOMUXC_GPR7);
+
+ num_cpu_idle_lock = 0x0;
+ if (cpu_is_mx6dl())
+ num_cpu_idle_lock = 0xffff0000;
+
+#ifdef CONFIG_SMP
+ switch (setup_max_cpus) {
+ case 3:
+ num_cpu_idle_lock = 0xff000000;
+ break;
+ case 2:
+ num_cpu_idle_lock = 0xffff0000;
+ break;
+ case 1:
+ case 0:
+ num_cpu_idle_lock = 0xffffff00;
+ break;
+ }
+#endif
+ /*
+ * The option to keep ARM memory clocks enabled during WAIT
+ * is only available on MX6SL, MX6DQ TO1.2 (or later) and
+ * MX6DL TO1.1 (or later)
+ * So if the user specifies "mem_clk_on" on any other chip,
+ * ensure that it is disabled.
+ */
+ if (!cpu_is_mx6sl() && (mx6q_revision() < IMX_CHIP_REVISION_1_2) &&
+ (mx6dl_revision() < IMX_CHIP_REVISION_1_1))
+ mem_clk_on_in_wait = false;
+
+ if (cpu_is_mx6q())
+ chip_rev = mx6q_revision();
+ else if (cpu_is_mx6dl())
+ chip_rev = mx6dl_revision();
+ else
+ chip_rev = mx6sl_revision();
+
+ /* mx6sl doesn't have pcie. save power, disable PCIe PHY */
+ if (!cpu_is_mx6sl()) {
+ reg = __raw_readl(IOMUXC_GPR1);
+ reg = reg & (~IOMUXC_GPR1_PCIE_REF_CLK_EN);
+ reg |= IOMUXC_GPR1_TEST_POWERDOWN;
+ __raw_writel(reg, IOMUXC_GPR1);
+ }
+ if (cpu_is_mx6sl()) {
+ int i;
+ /*
+ * Allocate the bottom 16K of IRAM page tables that
+ * will be used when DDR is in self-refresh.
+ */
+ iram_tlb_phys_addr = MX6_IRAM_TLB_BASE_ADDR;
+ iram_tlb_base_addr = (unsigned long)__arm_ioremap(iram_tlb_phys_addr,
+ MX6_IRAM_TLB_SIZE, MT_MEMORY_NONCACHED);
+
+ /* Set all entries to 0. */
+ memset((void *)iram_tlb_base_addr, 0, MX6_IRAM_TLB_SIZE);
+
+ /* Make sure the IRAM virtual address has a mapping in the IRAM page table. */
+ i = ((IRAM_BASE_ADDR_VIRT >> 20) << 2 ) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (IRAM_BASE_ADDR & 0xFFF0000) | TT_ATTRIB_NON_CACHEABLE_1M;
+ /* Make sure the AIPS1 virtual address has a mapping in the IRAM page table. */
+ i = ((AIPS1_BASE_ADDR_VIRT >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (AIPS1_ARB_BASE_ADDR & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
+ /* Make sure the AIPS2 virtual address has a mapping in the IRAM page table. */
+ i = ((AIPS2_BASE_ADDR_VIRT >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (AIPS2_ARB_BASE_ADDR & 0xFFF00000) | TT_ATTRIB_NON_CACHEABLE_1M;
+ /* Make sure the AIPS2 virtual address has a mapping in the IRAM page table. */
+ i = ((L2_BASE_ADDR_VIRT >> 20) << 2) / 4;
+ *((unsigned long *)iram_tlb_base_addr + i) =
+ (L2_BASE_ADDR & 0xFFF0000) | TT_ATTRIB_NON_CACHEABLE_1M;
+
+ }
+ return 0;
+}
+postcore_initcall(post_cpu_init);
+
+static int __init enable_wait(char *p)
+{
+ if (memcmp(p, "on", 2) == 0) {
+ enable_wait_mode = true;
+ p += 2;
+ } else if (memcmp(p, "off", 3) == 0) {
+ enable_wait_mode = false;
+ p += 3;
+ }
+ return 0;
+}
+early_param("enable_wait_mode", enable_wait);
+
+static int __init arm_core_max(char *p)
+{
+ if (memcmp(p, "1200", 4) == 0) {
+ arm_max_freq = CPU_AT_1_2GHz;
+ p += 4;
+ } else if (memcmp(p, "1000", 4) == 0) {
+ arm_max_freq = CPU_AT_1GHz;
+ p += 4;
+ } else if (memcmp(p, "800", 3) == 0) {
+ arm_max_freq = CPU_AT_800MHz;
+ p += 3;
+ }
+ return 0;
+}
+
+early_param("arm_freq", arm_core_max);
+
+static int __init enable_ldo(char *p)
+{
+ if (memcmp(p, "on", 2) == 0) {
+ enable_ldo_mode = LDO_MODE_ENABLED;
+ p += 2;
+ } else if (memcmp(p, "off", 3) == 0) {
+ enable_ldo_mode = LDO_MODE_BYPASSED;
+ p += 3;
+ }
+ return 0;
+}
+early_param("ldo_active", enable_ldo);
+
+static int __init enable_mem_clk_in_wait(char *p)
+{
+ mem_clk_on_in_wait = true;
+
+ return 0;
+}
+
+early_param("mem_clk_on", enable_mem_clk_in_wait);
+
+
+
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
new file mode 100644
index 00000000..24dcc712
--- /dev/null
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include "cpu_op-mx6.h"
+
+#define OCOTP_SPEED_BIT_OFFSET (16)
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern struct dvfs_op *(*get_dvfs_core_op)(int *wp);
+extern void (*set_num_cpu_op)(int num);
+extern u32 arm_max_freq;
+static int num_cpu_op;
+
+/* working point(wp): 0 - 1.2GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */
+static struct cpu_op mx6q_cpu_op_1_2G[] = {
+ {
+ .pll_rate = 1200000000,
+ .cpu_rate = 1200000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1275000,
+ .soc_voltage = 1275000,
+ .cpu_voltage = 1275000,},
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 1250000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
+};
+
+/* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */
+static struct cpu_op mx6q_cpu_op_1G[] = {
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 1250000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
+};
+
+static struct cpu_op mx6q_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+#ifdef CONFIG_MX6_VPU_352M
+ /*VPU 352Mhz need voltage 1.25V*/
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+#else
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+#endif
+ .cpu_voltage = 1150000,},
+#ifdef CONFIG_MX6_VPU_352M
+ /*pll2_pfd_400M will be fix on 352M,to avoid modify other code
+ which assume ARM clock sourcing from pll2_pfd_400M, change cpu
+ freq from 396M to 352M.*/
+ {
+ .pll_rate = 352000000,
+ .cpu_rate = 352000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1250000,
+ .soc_voltage = 1250000,
+ .cpu_voltage = 950000,},
+#else
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 950000,},
+#endif
+};
+
+/* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */
+static struct cpu_op mx6dl_cpu_op_1_2G[] = {
+ {
+ .pll_rate = 1200000000,
+ .cpu_rate = 1200000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1275000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1175000,},
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
+};
+/* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */
+static struct cpu_op mx6dl_cpu_op_1G[] = {
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1250000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1175000,},
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
+};
+static struct cpu_op mx6dl_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1175000,},
+ {
+ .pll_rate = 396000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1175000,
+ .soc_voltage = 1175000,
+ .cpu_voltage = 1075000,},
+};
+
+static struct cpu_op mx6sl_cpu_op_1G[] = {
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1200000,
+ .soc_voltage = 1200000,
+ .cpu_voltage = 1250000,},
+/* {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1150000,
+ .soc_voltage = 1150000,
+ .cpu_voltage = 1150000,},*/
+ {
+ .pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1150000,
+ .soc_voltage = 1150000,
+ .cpu_voltage = 950000,},
+};
+
+static struct cpu_op mx6sl_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1150000,
+ .soc_voltage = 1150000,
+ .cpu_voltage = 1150000,},
+ {
+ .pll_rate = 396000000,
+ .pll_lpm_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 0,
+ .pu_voltage = 1150000,
+ .soc_voltage = 1150000,
+ .cpu_voltage = 950000,},
+};
+
+static struct dvfs_op dvfs_core_setpoint_1_2G[] = {
+ {33, 14, 33, 10, 128, 0x10}, /* 1.2GHz*/
+ {30, 12, 33, 100, 200, 0x10}, /* 800MHz */
+ {28, 12, 33, 100, 200, 0x10}, /* 672MHz */
+ {26, 8, 33, 100, 200, 0x10}, /* 400MHz */
+ {20, 0, 33, 20, 10, 0x10} }; /* 200MHz*/
+
+static struct dvfs_op dvfs_core_setpoint_1G[] = {
+ {33, 14, 33, 10, 128, 0x10}, /* 1GHz*/
+ {30, 12, 33, 100, 200, 0x10}, /* 800MHz */
+ {28, 12, 33, 100, 200, 0x10}, /* 672MHz */
+ {26, 8, 33, 100, 200, 0x10}, /* 400MHz */
+ {20, 0, 33, 20, 10, 0x10} }; /* 200MHz*/
+
+static struct dvfs_op dvfs_core_setpoint[] = {
+ {33, 14, 33, 10, 128, 0x08}, /* 800MHz */
+ {26, 8, 33, 100, 200, 0x08}, /* 400MHz */
+ {20, 0, 33, 100, 10, 0x08} }; /* 200MHz*/
+
+static struct dvfs_op *mx6_get_dvfs_core_table(int *wp)
+{
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ *wp = ARRAY_SIZE(dvfs_core_setpoint_1_2G);
+ return dvfs_core_setpoint_1_2G;
+ } else if (arm_max_freq == CPU_AT_1GHz) {
+ *wp = ARRAY_SIZE(dvfs_core_setpoint_1G);
+ return dvfs_core_setpoint_1G;
+ } else {
+ *wp = ARRAY_SIZE(dvfs_core_setpoint);
+ return dvfs_core_setpoint;
+ }
+}
+
+struct cpu_op *mx6_get_cpu_op(int *op)
+{
+ if (cpu_is_mx6dl()) {
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G);
+ return mx6dl_cpu_op_1_2G;
+ } else if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G);
+ return mx6dl_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op);
+ return mx6dl_cpu_op;
+ }
+ } else if (cpu_is_mx6q()) {
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G);
+ return mx6q_cpu_op_1_2G;
+ } else if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G);
+ return mx6q_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op);
+ return mx6q_cpu_op;
+ }
+ } else {
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G);
+ return mx6sl_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op);
+ return mx6sl_cpu_op;
+ }
+ }
+}
+
+void mx6_set_num_cpu_op(int num)
+{
+ num_cpu_op = num;
+ return;
+}
+
+void mx6_cpu_op_init(void)
+{
+ unsigned int reg;
+ void __iomem *base;
+ if (!cpu_is_mx6sl()) {
+ /*read fuse bit to know the max cpu freq : offset 0x440
+ * bit[17:16]:SPEED_GRADING[1:0],for mx6dq/dl*/
+ base = IO_ADDRESS(OCOTP_BASE_ADDR);
+ reg = __raw_readl(base + 0x440);
+ reg &= (0x3 << OCOTP_SPEED_BIT_OFFSET);
+ reg >>= OCOTP_SPEED_BIT_OFFSET;
+ /*choose the little value to run lower max cpufreq*/
+ arm_max_freq = (reg > arm_max_freq) ? arm_max_freq : reg;
+ } else {
+ /*
+ * There is no SPEED_GRADING fuse bit on mx6sl,then do:
+ * If arm_max_freq set by default on CPU_AT_1_2GHz which mean
+ * there is no 'arm_freq' setting in cmdline from bootloader,
+ * force arm_max_freq to 1G. Else use 'arm_freq' setting.
+ */
+ if (arm_max_freq == CPU_AT_1_2GHz)
+ arm_max_freq = CPU_AT_1GHz;/*mx6sl max freq is 1Ghz*/
+ }
+ printk(KERN_INFO "arm_max_freq=%s\n", (arm_max_freq == CPU_AT_1_2GHz) ?
+ "1.2GHz" : ((arm_max_freq == CPU_AT_1GHz) ? "1GHz" : "800MHz"));
+ get_cpu_op = mx6_get_cpu_op;
+ set_num_cpu_op = mx6_set_num_cpu_op;
+
+ get_dvfs_core_op = mx6_get_dvfs_core_table;
+}
+
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.h b/arch/arm/mach-mx6/cpu_op-mx6.h
new file mode 100644
index 00000000..310cbb37
--- /dev/null
+++ b/arch/arm/mach-mx6/cpu_op-mx6.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*The below value aligned with SPEED_GRADING bits in 0x440 fuse offset */
+#define CPU_AT_800MHz 0
+#define CPU_AT_1GHz 2
+#define CPU_AT_1_2GHz 3
+
+void mx6_cpu_op_init(void);
diff --git a/arch/arm/mach-mx6/cpu_regulator-mx6.c b/arch/arm/mach-mx6/cpu_regulator-mx6.c
new file mode 100644
index 00000000..1a67e9d5
--- /dev/null
+++ b/arch/arm/mach-mx6/cpu_regulator-mx6.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#if defined(CONFIG_CPU_FREQ)
+#include <linux/cpufreq.h>
+#endif
+#include <linux/io.h>
+#include <asm/cpu.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include "regs-anadig.h"
+#include "crm_regs.h"
+struct regulator *cpu_regulator;
+struct regulator *soc_regulator;
+struct regulator *pu_regulator;
+char *gp_reg_id;
+char *soc_reg_id;
+char *pu_reg_id;
+static struct clk *cpu_clk;
+static int cpu_op_nr;
+static struct cpu_op *cpu_op_tbl;
+extern struct cpu_op *(*get_cpu_op)(int *op);
+
+extern unsigned long loops_per_jiffy;
+extern u32 enable_ldo_mode;
+int external_pureg;
+
+static inline unsigned long mx6_cpu_jiffies(unsigned long old, u_int div,
+ u_int mult)
+{
+#if BITS_PER_LONG == 32
+
+ u64 result = ((u64) old) * ((u64) mult);
+ do_div(result, div);
+ return (unsigned long) result;
+
+#elif BITS_PER_LONG == 64
+
+ unsigned long result = old * ((u64) mult);
+ result /= div;
+ return result;
+
+#endif
+}
+
+void mx6_cpu_regulator_init(void)
+{
+ int cpu;
+ u32 curr_cpu = 0;
+ unsigned int reg;
+#ifndef CONFIG_SMP
+ unsigned long old_loops_per_jiffy;
+#endif
+ void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
+ external_pureg = 0;
+ /*If internal ldo actived, use internal cpu_* regulator to replace the
+ *regulator ids from board file. If internal ldo bypassed, use the
+ *regulator ids which defined in board file and source from extern pmic
+ *power rails.
+ *If you want to use ldo bypass,you should do:
+ *1.set enable_ldo_mode=LDO_MODE_BYPASSED in your board file by default
+ * or set in commandline from u-boot
+ *2.set your extern pmic regulator name in your board file.
+ */
+ if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ gp_reg_id = "cpu_vddgp";
+ soc_reg_id = "cpu_vddsoc";
+ pu_reg_id = "cpu_vddgpu";
+ }
+ printk(KERN_INFO "cpu regulator mode:%s\n", (enable_ldo_mode ==
+ LDO_MODE_BYPASSED) ? "ldo_bypass" : "ldo_enable");
+ cpu_regulator = regulator_get(NULL, gp_reg_id);
+#if 0
+ if (IS_ERR(cpu_regulator))
+ printk(KERN_ERR "%s: failed to get cpu regulator\n", __func__);
+ else
+#endif
+ {
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n",
+ __func__);
+ } else {
+ curr_cpu = clk_get_rate(cpu_clk);
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ soc_regulator = regulator_get(NULL, soc_reg_id);
+ if (IS_ERR(soc_regulator))
+ printk(KERN_ERR "%s: failed to get soc regulator\n",
+ __func__);
+ else
+ /* set soc to highest setpoint voltage. */
+ regulator_set_voltage(soc_regulator,
+ cpu_op_tbl[0].soc_voltage,
+ cpu_op_tbl[0].soc_voltage);
+
+ pu_regulator = regulator_get(NULL, pu_reg_id);
+ if (IS_ERR(pu_regulator))
+ printk(KERN_ERR "%s: failed to get pu regulator\n",
+ __func__);
+ else
+ /* set pu to higheset setpoint voltage. */
+ regulator_set_voltage(pu_regulator,
+ cpu_op_tbl[0].pu_voltage,
+ cpu_op_tbl[0].pu_voltage);
+ if (!IS_ERR(cpu_regulator)) {
+ /* set the core to higheset setpoint voltage. */
+ regulator_set_voltage(cpu_regulator,
+ cpu_op_tbl[0].cpu_voltage,
+ cpu_op_tbl[0].cpu_voltage);
+ }
+ if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /* digital bypass VDDPU/VDDSOC/VDDARM */
+ reg = __raw_readl(ANADIG_REG_CORE);
+ reg &= ~BM_ANADIG_REG_CORE_REG0_TRG;
+ reg |= BF_ANADIG_REG_CORE_REG0_TRG(0x1f);
+ reg &= ~BM_ANADIG_REG_CORE_REG1_TRG;
+ reg |= BF_ANADIG_REG_CORE_REG1_TRG(0x1f);
+ reg &= ~BM_ANADIG_REG_CORE_REG2_TRG;
+ reg |= BF_ANADIG_REG_CORE_REG2_TRG(0x1f);
+ __raw_writel(reg, ANADIG_REG_CORE);
+ /* mask the ANATOP brown out irq in the GPC. */
+ reg = __raw_readl(gpc_base + 0x14);
+ reg |= 0x80000000;
+ __raw_writel(reg, gpc_base + 0x14);
+ }
+
+ clk_set_rate(cpu_clk, cpu_op_tbl[0].cpu_rate);
+
+ /* fix loops-per-jiffy */
+#ifdef CONFIG_SMP
+ for_each_online_cpu(cpu)
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ mx6_cpu_jiffies(
+ per_cpu(cpu_data, cpu).loops_per_jiffy,
+ curr_cpu / 1000,
+ clk_get_rate(cpu_clk) / 1000);
+#else
+ old_loops_per_jiffy = loops_per_jiffy;
+
+ loops_per_jiffy =
+ mx6_cpu_jiffies(old_loops_per_jiffy,
+ curr_cpu/1000,
+ clk_get_rate(cpu_clk) / 1000);
+#endif
+#if defined(CONFIG_CPU_FREQ)
+ /* Fix CPU frequency for CPUFREQ. */
+ for (cpu = 0; cpu < num_online_cpus(); cpu++)
+ cpufreq_get(cpu);
+#endif
+ }
+ }
+ /*
+ * if use ldo bypass and VDDPU_IN is single supplied
+ * by external pmic, it means VDDPU_IN can be turned off
+ * if GPU/VPU driver not running.In this case we should set
+ * external_pureg which can be used in pu_enable/pu_disable of
+ * arch/arm/mach-mx6/mx6_anatop_regulator.c to
+ * enable or disable external VDDPU regulator from pmic. But for FSL
+ * reference boards, VDDSOC_IN connect with VDDPU_IN, so we didn't set
+ * pu_reg_id to the external pmic regulator supply name in the board
+ * file. In this case external_pureg should be 0 and can't turn off
+ * extern pmic regulator, but can turn off VDDPU by internal anatop
+ * power gate.
+ *
+ * if enable internal ldo , external_pureg will be 0, and
+ * VDDPU can be turned off by internal anatop anatop power gate.
+ *
+ */
+ if (!IS_ERR(pu_regulator) && strcmp(pu_reg_id, "cpu_vddgpu"))
+ external_pureg = 1;
+}
+
diff --git a/arch/arm/mach-mx6/crm_regs.h b/arch/arm/mach-mx6/crm_regs.h
new file mode 100644
index 00000000..0ae8e41e
--- /dev/null
+++ b/arch/arm/mach-mx6/crm_regs.h
@@ -0,0 +1,569 @@
+/*
+ * Copyright 2008-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX6_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX6_CRM_REGS_H__
+
+/* IOMUXC */
+#define MXC_IOMUXC_BASE MX6_IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR)
+#define IOMUXC_GPR0 (MXC_IOMUXC_BASE + 0x00)
+#define IOMUXC_GPR1 (MXC_IOMUXC_BASE + 0x04)
+#define IOMUXC_GPR2 (MXC_IOMUXC_BASE + 0x08)
+#define IOMUXC_GPR3 (MXC_IOMUXC_BASE + 0x0C)
+#define IOMUXC_GPR4 (MXC_IOMUXC_BASE + 0x10)
+#define IOMUXC_GPR5 (MXC_IOMUXC_BASE + 0x14)
+#define IOMUXC_GPR6 (MXC_IOMUXC_BASE + 0x18)
+#define IOMUXC_GPR7 (MXC_IOMUXC_BASE + 0x1C)
+#define IOMUXC_GPR8 (MXC_IOMUXC_BASE + 0x20)
+#define IOMUXC_GPR9 (MXC_IOMUXC_BASE + 0x24)
+#define IOMUXC_GPR10 (MXC_IOMUXC_BASE + 0x28)
+#define IOMUXC_GPR11 (MXC_IOMUXC_BASE + 0x2C)
+#define IOMUXC_GPR12 (MXC_IOMUXC_BASE + 0x30)
+#define IOMUXC_GPR13 (MXC_IOMUXC_BASE + 0x34)
+
+/* GPR1: IOMUXC_GPR1_PCIE_REF_CLK_EN(IOMUXC_GPR1[16]) */
+#define IOMUXC_GPR1_PCIE_REF_CLK_EN (1 << 16)
+/* GPR1: IOMUXC_GPR1_TEST_POWERDOWN(IOMUXC_GPR1[18]) */
+#define IOMUXC_GPR1_TEST_POWERDOWN (1 << 18)
+
+/* GPR8: IOMUXC_GPR8_TX_DEEMPH_GEN1(IOMUXC_GPR8[5:0]) */
+#define IOMUXC_GPR8_TX_DEEMPH_GEN1 (0x3F << 0)
+/* GPR8: IOMUXC_GPR8_TX_DEEMPH_GEN2_3P5DB(IOMUXC_GPR8[11:6]) */
+#define IOMUXC_GPR8_TX_DEEMPH_GEN2_3P5DB (0x3F << 6)
+/* GPR8: IOMUXC_GPR8_TX_DEEMPH_GEN2_6DB(IOMUXC_GPR8[17:12]) */
+#define IOMUXC_GPR8_TX_DEEMPH_GEN2_6DB (0x3F << 12)
+/* GPR8: IOMUXC_GPR8_TX_SWING_FULL(IOMUXC_GPR8[24:18]) */
+#define IOMUXC_GPR8_TX_SWING_FULL (0x7F << 18)
+/* GPR8: IOMUXC_GPR8_TX_SWING_LOW(IOMUXC_GPR8[31:25]) */
+#define IOMUXC_GPR8_TX_SWING_LOW (0x7F << 25)
+
+/* GPR12: IOMUXC_GPR12_LOS_LEVEL(IOMUXC_GPR12[8:4]) */
+#define IOMUXC_GPR12_LOS_LEVEL (0x1F << 4)
+/* GPR12: IOMUXC_GPR12_APP_LTSSM_ENABLE(IOMUXC_GPR12[10]) */
+#define IOMUXC_GPR12_APP_LTSSM_ENABLE (1 << 10)
+/* GPR12: IOMUXC_GPR12_DEVICE_TYPE(IOMUXC_GPR12[15:12]) */
+#define IOMUXC_GPR12_DEVICE_TYPE (0xF << 12)
+
+#define IOMUXC_GPR3_OCRAM_CTL_EN (0xf << 21)
+#define IOMUXC_GPR4_VDOA_CACHE_EN (0xf << 28)
+#define IOMUXC_GPR4_VPU_CACHE_EN (0xcc)
+#define IOMUXC_GPR4_IPU_CACHE_EN (0x3)
+#define IOMUXC_GPR6_IPU1_QOS (0x007f007f)
+#define IOMUXC_GPR7_IPU2_QOS (0x007f007f)
+
+/* MMDC */
+#define MXC_MMDC_P0_BASE MX6_IO_ADDRESS(MMDC_P0_BASE_ADDR)
+#define MMDC_MDMISC_OFFSET (MXC_MMDC_P0_BASE + 0x18)
+#define MMDC_MDMISC_DDR_TYPE_MASK (0x3 << 3)
+#define MMDC_MDMISC_DDR_TYPE_OFFSET (3)
+
+/* PLLs */
+#define MXC_PLL_BASE MX6_IO_ADDRESS(ANATOP_BASE_ADDR)
+#define PLL1_SYS_BASE_ADDR (MXC_PLL_BASE + 0x0)
+#define PLL2_528_BASE_ADDR (MXC_PLL_BASE + 0x30)
+#define PLL3_480_USB1_BASE_ADDR (MXC_PLL_BASE + 0x10)
+#define PLL4_AUDIO_BASE_ADDR (MXC_PLL_BASE + 0x70)
+#define PLL5_VIDEO_BASE_ADDR (MXC_PLL_BASE + 0xA0)
+#define PLL6_MLB_BASE_ADDR (MXC_PLL_BASE + 0xD0)
+#define PLL7_480_USB2_BASE_ADDR (MXC_PLL_BASE + 0x20)
+#define PLL8_ENET_BASE_ADDR (MXC_PLL_BASE + 0xE0)
+#define PFD_480_BASE_ADDR (MXC_PLL_BASE + 0xF0)
+#define PFD_528_BASE_ADDR (MXC_PLL_BASE + 0x100)
+#define ANADIG_REG_CORE (MXC_PLL_BASE + 0x140)
+#define ANADIG_MISC1_REG (MXC_PLL_BASE + 0x160)
+#define ANADIG_MISC2_REG (MXC_PLL_BASE + 0x170)
+#define ANATOP_LVDS_CLK1_SRC_SATA 0xB
+#define ANATOP_LVDS_CLK1_OBEN_MASK 0x400
+#define ANATOP_LVDS_CLK1_IBEN_MASK 0x1000
+#define ANATOP_LVDS_CLK2_OBEN_MASK 0x800
+#define ANATOP_LVDS_CLK2_IBEN_MASK 0x2000
+#define ANA_MISC2_BASE_ADDR (MXC_PLL_BASE + 0x170)
+
+#define PLL_SETREG_OFFSET 0x4
+#define PLL_CLRREG_OFFSET 0x8
+#define PLL_TOGGLE_OFFSET 0x0C
+#define PLL_NUM_DIV_OFFSET 0x10
+#define PLL_DENOM_DIV_OFFSET 0x20
+#define PLL_528_SS_OFFSET 0x10
+#define PLL_528_NUM_DIV_OFFSET 0x20
+#define PLL_528_DENOM_DIV_OFFSET 0x30
+
+/* Common PLL register bit defines. */
+#define ANADIG_PLL_LOCK (1 << 31)
+#define ANADIG_PLL_BYPASS (1 << 16)
+#define ANADIG_PLL_BYPASS_CLK_SRC_MASK (0x3 << 14)
+#define ANADIG_PLL_BYPASS_CLK_SRC_OFFSET (14)
+#define ANADIG_PLL_ENABLE (1 << 13)
+#define ANADIG_PLL_POWER_DOWN (1 << 12)
+#define ANADIG_PLL_HOLD_RING_OFF (1 << 11)
+
+/* PLL1_SYS defines */
+#define ANADIG_PLL_SYS_DIV_SELECT_MASK (0x7F)
+#define ANADIG_PLL_SYS_DIV_SELECT_OFFSET (0)
+#define ANADIG_PLL_SYS_BYPASS_MASK (0x10000)
+#define ANADIG_PLL_SYS_BYPASS_OFFSET (16)
+
+/* PLL2_528 defines */
+#define ANADIG_PLL_528_DIV_SELECT (1)
+
+/* PLL3_480 defines. */
+#define ANADIG_PLL_480_EN_USB_CLKS (1 << 6)
+#define ANADIG_PLL_480_DIV_SELECT_MASK (0x3)
+#define ANADIG_PLL_480_DIV_SELECT_OFFSET (0)
+
+/* PLL4_AUDIO PLL5_VIDEO defines. */
+#define ANADIG_PLL_AV_DIV_SELECT_MASK (0x7F)
+#define ANADIG_PLL_AV_DIV_SELECT_OFFSET (0)
+#define ANADIG_PLL_AV_TEST_DIV_SEL_MASK (0x180000)
+#define ANADIG_PLL_AV_TEST_DIV_SEL_OFFSET (19)
+
+/* PLL6_MLB defines. */
+#define ANADIG_PLL_MLB_LOCK (1 << 31)
+#define ANADIG_PLL_MLB_FLT_RES_CFG_MASK (0x7 << 26)
+#define ANADIG_PLL_MLB_FLT_RES_CFG_OFFSET (26)
+#define ANADIG_PLL_MLB_RX_CLK_DELAY_CFG_MASK (0x7 << 23)
+#define ANADIG_PLL_MLB_RX_CLK_DELAY_CFG_OFFSET (23)
+#define ANADIG_PLL_MLB_VDDD_DELAY_CFG_MASK (0x7 << 20)
+#define ANADIG_PLL_MLB_VDDD_DELAY_CFG_OFFSET (20)
+#define ANADIG_PLL_MLB_VDDA_DELAY_CFG_MASK (0x7 << 17)
+#define ANADIG_PLL_MLB_VDDA_DELAY_CFG_OFFSET (17)
+#define ANADIG_PLL_MLB_BYPASS (1 << 16)
+
+/* PLL8_ENET defines. */
+#define ANADIG_PLL_ENET_LOCK (1 << 31)
+#define ANADIG_PLL_ENET_EN_SATA (1 << 20)
+#define ANADIG_PLL_ENET_EN_PCIE (1 << 19)
+#define ANADIG_PLL_ENET_BYPASS (1 << 16)
+#define ANADIG_PLL_ENET_EN (1 << 13)
+#define ANADIG_PLL_ENET_POWER_DOWN (1 << 12)
+#define ANADIG_PLL_ENET_DIV_SELECT_MASK (0x3)
+#define ANADIG_PLL_ENET_DIV_SELECT_OFFSET (0)
+#define ANATOP_BYPASS_SRC_LVDS1 0x00004000
+
+/* PFD register defines. */
+#define ANADIG_PFD_FRAC_MASK 0x3F
+#define ANADIG_PFD3_CLKGATE (1 << 31)
+#define ANADIG_PFD3_STABLE (1 << 30)
+#define ANADIG_PFD3_FRAC_OFFSET 24
+#define ANADIG_PFD2_CLKGATE (1 << 23)
+#define ANADIG_PFD2_STABLE (1 << 22)
+#define ANADIG_PFD2_FRAC_OFFSET 16
+#define ANADIG_PFD1_CLKGATE (1 << 15)
+#define ANADIG_PFD1_STABLE (1 << 14)
+#define ANADIG_PFD1_FRAC_OFFSET 8
+#define ANADIG_PFD0_CLKGATE (1 << 7)
+#define ANADIG_PFD0_STABLE (1 << 6)
+#define ANADIG_PFD0_FRAC_OFFSET 0
+
+/* ANATOP Regulator/LDO defines */
+#define ANADIG_REG_RAMP_RATE_MASK 0x03
+#define ANADIG_REG_RAMP_RATE_OFFSET (0x3 << 27)
+#define ANADIG_REG_ADJUST_MASK 0xF
+#define ANADIG_REG_TARGET_MASK 0x1F
+#define ANADIG_REG2_SOC_ADJUST_OFFSET 23
+#define ANADIG_REG2_SOC_TARGET_OFFSET 18
+#define ANADIG_REG1_PU_ADJUST_OFFSET 14
+#define ANADIG_REG1_PU_TARGET_OFFSET 9
+#define ANADIG_REG0_CORE_ADJUST_OFFSET 5
+#define ANADIG_REG0_CORE_TARGET_OFFSET 0
+
+/* ANA MISC2 register defines */
+#define ANADIG_ANA_MISC2_REG1_BO_EN (1 << 13)
+#define ANADIG_ANA_MISC2_CONTROL3_MASK 0xC0000000
+#define ANADIG_ANA_MISC2_CONTROL3_OFFSET 30
+#define ANADIG_ANA_MISC2_REG0_STEP_TIME_MASK 0x03000000
+#define ANADIG_ANA_MISC2_REG1_STEP_TIME_MASK 0x0C000000
+#define ANADIG_ANA_MISC2_REG2_STEP_TIME_MASK 0x30000000
+
+#define MXC_CCM_BASE MX6_IO_ADDRESS(CCM_BASE_ADDR)
+/* CCM Register Offsets. */
+#define MXC_CCM_CDCR_OFFSET 0x4C
+#define MXC_CCM_CACRR_OFFSET 0x10
+#define MXC_CCM_CDHIPR_OFFSET 0x48
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0c)
+#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1c)
+#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2c)
+#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCCDR (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3c)
+#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4c)
+#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5c)
+#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80)
+#define MXC_CCM_CCGR7 (MXC_CCM_BASE + 0x84)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x88)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_RBC_EN (1 << 27)
+#define MXC_CCM_CCR_REG_BYPASS_CNT_MASK (0x3F << 21)
+#define MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET (21)
+#define MXC_CCM_CCR_WB_COUNT_MASK (0x7 << 16)
+#define MXC_CCM_CCR_WB_COUNT_OFFSET (16)
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_MMDC_CH1_HS_MASK (1 << 16)
+#define MXC_CCM_CCDR_MMDC_CH0_HS_MASK (1 << 17)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSC_READY (1 << 5)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_PDF_540M_AUTO_DIS (1 << 15)
+#define MXC_CCM_CCSR_PDF_720M_AUTO_DIS (1 << 14)
+#define MXC_CCM_CCSR_PDF_454M_AUTO_DIS (1 << 13)
+#define MXC_CCM_CCSR_PDF_508M_AUTO_DIS (1 << 12)
+#define MXC_CCM_CCSR_PDF_594M_AUTO_DIS (1 << 11)
+#define MXC_CCM_CCSR_PDF_352M_AUTO_DIS (1 << 10)
+#define MXC_CCM_CCSR_PDF_400M_AUTO_DIS (1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL (1 << 8)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK (0x7 << 27)
+#define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET (27)
+#define MXC_CCM_CBCDR_PERIPH2_CLK_SEL (1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (1 << 25)
+#define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_AXI_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_AXI_ALT_SEL_MASK (1 << 7)
+#define MXC_CCM_CBCDR_AXI_ALT_SEL_OFFSET (7)
+#define MXC_CCM_CBCDR_AXI_SEL (1 << 6)
+#define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET (3)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK (0x7 << 0)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET (0)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK (0x7 << 29)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET (29)
+#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK (0x7 << 26)
+#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET (26)
+#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK (0x7 << 23)
+#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET (23)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK (0x3 << 21)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET (21)
+#define MXC_CCM_CBCMR_PERIPH2_CLK2_SEL (1 << 20)
+#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK (0x3 << 18)
+#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CBCMR_MLB_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CBCMR_MLB_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET (12)
+#define MXC_CCM_CBCMR_VDOAXI_CLK_SEL (1 << 11)
+#define MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL (1 << 10)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL (1 << 1)
+#define MXC_CCM_CBCMR_GPU2D_AXI_CLK_SEL (1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK (0x3 << 29)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET (29)
+#define MXC_CCM_CSCMR1_ACLK_EMI_MASK (0x3 << 27)
+#define MXC_CCM_CSCMR1_ACLK_EMI_OFFSET (27)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK (0x7 << 23)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET (23)
+#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK (0x7 << 20)
+#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET (20)
+#define MXC_CCM_CSCMR1_USDHC4_CLK_SEL (1 << 19)
+#define MXC_CCM_CSCMR1_USDHC3_CLK_SEL (1 << 18)
+#define MXC_CCM_CSCMR1_USDHC2_CLK_SEL (1 << 17)
+#define MXC_CCM_CSCMR1_USDHC1_CLK_SEL (1 << 16)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CSCMR1_PERCLK_CLK_SEL_MASK (0x1 << 6)
+#define MXC_CCM_CSCMR1_PERCLK_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCMR1_PERCLK_PODF_MASK (0x3F)
+#define MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET (0)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_ESAI_CLK_SEL_MASK (0x3 << 19)
+#define MXC_CCM_CSCMR2_ESAI_CLK_SEL_OFFSET (19)
+#define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV (1 << 11)
+#define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV (1 << 10)
+#define MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK (0x3F << 2)
+#define MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET (2)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET (25)
+#define MXC_CCM_CSCDR1_USDHC4_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET (22)
+#define MXC_CCM_CSCDR1_USDHC3_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_USDHC2_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET (16)
+#define MXC_CCM_CSCDR1_USDHC1_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_UART_CLK_SEL_MASK (0x1 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CS1CDR */
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK (0x7 << 25)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET (25)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK (0x7 << 9)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET (9)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CS2CDR */
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK (0x3F << 21)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET (21)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK (0x7 << 18)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET (18)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK (0x7 << 12)
+#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_HSI_TX_PODF_MASK (0x7 << 29)
+#define MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET (29)
+#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL (1 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (22)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 12)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (12)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x7 << 9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET (7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK (0x7 << 15)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET (15)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET (12)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK (0x7)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET (0)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK (0x1 << 18)
+#define MXC_CCM_CSCDR2_ECSPI_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK (0x7 << 15)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET (15)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK (0x7 << 12)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET (12)
+#define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK (0x7 << 9)
+#define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET (9)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET (3)
+#define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK (0x7)
+#define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET (0)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET (16)
+#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK (0x3 << 9)
+#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET (9)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_MMDC_CH0_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_PODF_BUSY (1)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_MASK_L2CC_IDLE (1 << 27)
+#define MXC_CCM_CLPCR_MASK_SCU_IDLE (1 << 26)
+#define MXC_CCM_CLPCR_MASK_CORE3_WFI (1 << 25)
+#define MXC_CCM_CLPCR_MASK_CORE2_WFI (1 << 24)
+#define MXC_CCM_CLPCR_MASK_CORE1_WFI (1 << 23)
+#define MXC_CCM_CLPCR_MASK_CORE0_WFI (1 << 22)
+#define MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS (1 << 21)
+#define MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS (1 << 19)
+#define MXC_CCM_CLPCR_WB_CORE_AT_LPM (1 << 17)
+#define MXC_CCM_CLPCR_WB_PER_AT_LPM (1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_VSTBY (1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY (1 << 2)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (1 << 26)
+#define MXC_CCM_CISR_MMDC_CH0_PODF_LOADED (1 << 23)
+#define MXC_CCM_CISR_PERIPH_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CISR_MMDC_CH1_PODF_LOADED (1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (1 << 20)
+#define MXC_CCM_CISR_PERIPH2_CLK_SEL_LOADED (1 << 19)
+#define MXC_CCM_CISR_AXI_PODF_LOADED (1 << 17)
+#define MXC_CCM_CISR_COSC_READY (1 << 6)
+#define MXC_CCM_CISR_LRF_PLL (1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (1 << 26)
+#define MXC_CCM_CIMR_MASK_MMDC_CH0_PODF_LOADED (1 << 23)
+#define MXC_CCM_CIMR_MASK_PERIPH_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CIMR_MASK_MMDC_CH1_PODF_LOADED (1 << 21)
+#define MXC_CCM_CIMR_MASK_AHB_PODF_LOADED (1 << 20)
+#define MXC_CCM_CIMR_MASK_PERIPH2_CLK_SEL_LOADED (1 << 22)
+#define MXC_CCM_CIMR_MASK_AXI_PODF_LOADED (1 << 17)
+#define MXC_CCM_CIMR_MASK_COSC_READY (1 << 6)
+#define MXC_CCM_CIMR_MASK_LRF_PLL (1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (24)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_MIRROR_CKO2_MASK (1 << 8)
+#define MXC_CCM_CCOSR_CKOL_EN_OFFSET 7
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (1 << 4)
+#define MXC_CCM_CGPR_MMDC_EXT_CLK_DIS (1 << 2)
+#define MXC_CCM_CGPR_PMIC_DELAY_SCALER (1)
+#define MXC_CCM_CGPR_MEM_IPG_STOP_MASK (1 << 1)
+#define MXC_CCM_CGPR_WAIT_MODE_FIX (1 << 17)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGRx_CG_MASK 0x3
+#define MXC_CCM_CCGRx_MOD_OFF 0x0
+#define MXC_CCM_CCGRx_MOD_ON 0x3
+#define MXC_CCM_CCGRx_MOD_IDLE 0x1
+
+#define MXC_CCM_CCGRx_CG15_MASK (0x3 << 30)
+#define MXC_CCM_CCGRx_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGRx_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGRx_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGRx_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGRx_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGRx_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGRx_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGRx_CG7_MASK (0x3 << 14)
+#define MXC_CCM_CCGRx_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGRx_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGRx_CG3_MASK (0x3 << 6)
+#define MXC_CCM_CCGRx_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGRx_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGRx_CG0_MASK (0x3 << 0)
+
+#define MXC_CCM_CCGRx_CG15_OFFSET 30
+#define MXC_CCM_CCGRx_CG14_OFFSET 28
+#define MXC_CCM_CCGRx_CG13_OFFSET 26
+#define MXC_CCM_CCGRx_CG12_OFFSET 24
+#define MXC_CCM_CCGRx_CG11_OFFSET 22
+#define MXC_CCM_CCGRx_CG10_OFFSET 20
+#define MXC_CCM_CCGRx_CG9_OFFSET 18
+#define MXC_CCM_CCGRx_CG8_OFFSET 16
+#define MXC_CCM_CCGRx_CG7_OFFSET 14
+#define MXC_CCM_CCGRx_CG6_OFFSET 12
+#define MXC_CCM_CCGRx_CG5_OFFSET 10
+#define MXC_CCM_CCGRx_CG4_OFFSET 8
+#define MXC_CCM_CCGRx_CG3_OFFSET 6
+#define MXC_CCM_CCGRx_CG2_OFFSET 4
+#define MXC_CCM_CCGRx_CG1_OFFSET 2
+#define MXC_CCM_CCGRx_CG0_OFFSET 0
+
+#endif /* __ARCH_ARM_MACH_MX6_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
new file mode 100644
index 00000000..4525e29a
--- /dev/null
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mx6.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_imx_uart_1irq_data imx6q_imx_uart_data[] __initconst;
+#define imx6q_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx6q_imx_uart_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx6sl_imx_uart_data[] __initconst;
+#define imx6sl_add_imx_uart(id, pdata) \
+ imx_add_imx_uart_1irq(&imx6sl_imx_uart_data[id], pdata)
+
+extern const struct imx_snvs_rtc_data imx6q_imx_snvs_rtc_data __initconst;
+#define imx6q_add_imx_snvs_rtc() \
+ imx_add_snvs_rtc(&imx6q_imx_snvs_rtc_data)
+
+extern const struct imx_caam_data imx6q_imx_caam_data __initconst;
+#define imx6q_add_imx_caam() \
+ imx_add_caam(&imx6q_imx_caam_data)
+
+extern const struct imx_anatop_thermal_imx_data
+imx6q_anatop_thermal_imx_data __initconst;
+#define imx6q_add_anatop_thermal_imx(id, pdata) \
+ imx_add_anatop_thermal_imx(&imx6q_anatop_thermal_imx_data, pdata)
+
+extern const struct imx_dma_res_data imx6q_dma_res_data __initconst;
+#define imx6q_add_dma() imx_add_dma(&imx6q_dma_res_data);
+
+#define imx6q_add_gpmi(platform_data) imx_add_gpmi(platform_data);
+
+extern const struct imx_fec_data imx6q_fec_data __initconst;
+#define imx6q_add_fec(pdata) \
+ imx_add_fec(&imx6q_fec_data, pdata)
+extern const struct imx_fec_data imx6sl_fec_data __initconst;
+#define imx6sl_add_fec(pdata) \
+ imx_add_fec(&imx6sl_fec_data, pdata)
+
+extern const struct imx_sdhci_esdhc_imx_data
+imx6q_sdhci_usdhc_imx_data[] __initconst;
+#define imx6q_add_sdhci_usdhc_imx(id, pdata) \
+ imx_add_sdhci_esdhc_imx(&imx6q_sdhci_usdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx6q_ecspi_data[] __initconst;
+#define imx6q_add_ecspi(id, pdata) \
+ imx_add_spi_imx(&imx6q_ecspi_data[id], pdata)
+
+extern const struct imx_imx_i2c_data imx6q_imx_i2c_data[] __initconst;
+#define imx6q_add_imx_i2c(id, pdata) \
+ imx_add_imx_i2c(&imx6q_imx_i2c_data[id], pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx6q_fsl_usb2_udc_data __initconst;
+#define imx6q_add_fsl_usb2_udc(pdata) \
+ imx_add_fsl_usb2_udc(&imx6q_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx6q_mxc_ehci_otg_data __initconst;
+#define imx6q_add_fsl_ehci_otg(pdata) \
+ imx_add_fsl_ehci(&imx6q_mxc_ehci_otg_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] __initconst;
+#define imx6q_add_fsl_ehci_hs(id, pdata) \
+ imx_add_fsl_ehci(&imx6q_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] __initconst;
+#define imx6sl_add_fsl_ehci_hs(id, pdata) \
+ imx_add_fsl_ehci(&imx6sl_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data __initconst;
+#define imx6q_add_fsl_usb2_otg(pdata) \
+ imx_add_fsl_usb2_otg(&imx6q_fsl_usb2_otg_data, pdata)
+
+extern const struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data __initconst;
+#define imx6q_add_fsl_usb2_otg_wakeup(pdata) \
+ imx_add_fsl_usb2_wakeup(&imx6q_fsl_otg_wakeup_data, pdata)
+
+extern const struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] __initconst;
+#define imx6q_add_fsl_usb2_hs_wakeup(id, pdata) \
+ imx_add_fsl_usb2_wakeup(&imx6q_fsl_hs_wakeup_data[id - 1], pdata)
+
+extern const struct imx_fsl_usb2_wakeup_data imx6sl_fsl_hs_wakeup_data[] __initconst;
+#define imx6sl_add_fsl_usb2_hs_wakeup(id, pdata) \
+ imx_add_fsl_usb2_wakeup(&imx6sl_fsl_hs_wakeup_data[id - 1], pdata)
+
+extern const struct imx_imx_esai_data imx6q_imx_esai_data[] __initconst;
+#define imx6q_add_imx_esai(id, pdata) \
+ imx_add_imx_esai(&imx6q_imx_esai_data[id], pdata)
+
+extern const struct imx_viv_gpu_data imx6_gpu_data __initconst;
+
+extern const struct imx_ahci_data imx6q_ahci_data __initconst;
+#define imx6q_add_ahci(id, pdata) \
+ imx_add_ahci(&imx6q_ahci_data, pdata)
+
+extern const struct imx_imx_ssi_data imx6_imx_ssi_data[] __initconst;
+#define imx6q_add_imx_ssi(id, pdata) \
+ imx_add_imx_ssi(&imx6_imx_ssi_data[id], pdata)
+
+extern const struct imx_ipuv3_data imx6q_ipuv3_data[] __initconst;
+#define imx6q_add_ipuv3(id, pdata) imx_add_ipuv3(id, &imx6q_ipuv3_data[id], pdata)
+#define imx6q_add_ipuv3fb(id, pdata) imx_add_ipuv3_fb(id, pdata)
+
+#define imx6q_add_lcdif(pdata) \
+ platform_device_register_resndata(NULL, "mxc_lcdif",\
+ 0, NULL, 0, pdata, sizeof(*pdata));
+
+extern const struct imx_ldb_data imx6q_ldb_data __initconst;
+#define imx6q_add_ldb(pdata) \
+ imx_add_ldb(&imx6q_ldb_data, pdata);
+
+#define imx6q_add_v4l2_output(id) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_output",\
+ id, NULL, 0, NULL, 0);
+
+#define imx6q_add_v4l2_capture(id, pdata) \
+ platform_device_register_resndata(NULL, "mxc_v4l2_capture",\
+ id, NULL, 0, pdata, sizeof(*pdata));
+
+extern const struct imx_mxc_hdmi_data imx6q_mxc_hdmi_data __initconst;
+#define imx6q_add_mxc_hdmi(pdata) \
+ imx_add_mxc_hdmi(&imx6q_mxc_hdmi_data, pdata)
+
+extern const struct imx_mxc_hdmi_core_data imx6q_mxc_hdmi_core_data __initconst;
+#define imx6q_add_mxc_hdmi_core(pdata) \
+ imx_add_mxc_hdmi_core(&imx6q_mxc_hdmi_core_data, pdata)
+
+extern const struct imx_vpu_data imx6q_vpu_data __initconst;
+#define imx6q_add_vpu() imx_add_vpu(&imx6q_vpu_data)
+
+extern const struct imx_otp_data imx6q_otp_data __initconst;
+#define imx6q_add_otp() \
+ imx_add_otp(&imx6q_otp_data)
+
+extern const struct imx_viim_data imx6q_viim_data __initconst;
+#define imx6q_add_viim() \
+ imx_add_viim(&imx6q_viim_data)
+
+extern const struct imx_imx2_wdt_data imx6q_imx2_wdt_data[] __initconst;
+#define imx6q_add_imx2_wdt(id, pdata) \
+ imx_add_imx2_wdt(&imx6q_imx2_wdt_data[id])
+
+extern const struct imx_pm_imx_data imx6q_pm_imx_data __initconst;
+#define imx6q_add_pm_imx(id, pdata) \
+ imx_add_pm_imx(&imx6q_pm_imx_data, pdata)
+
+extern const struct imx_imx_asrc_data imx6q_imx_asrc_data[] __initconst;
+#define imx6q_add_asrc(pdata) \
+ imx_add_imx_asrc(imx6q_imx_asrc_data, pdata)
+
+extern const struct imx_dvfs_core_data imx6q_dvfs_core_data __initconst;
+#define imx6q_add_dvfs_core(pdata) \
+ imx_add_dvfs_core(&imx6q_dvfs_core_data, pdata)
+
+extern const struct imx_viv_gpu_data imx6_gc2000_data __initconst;
+extern const struct imx_viv_gpu_data imx6_gc320_data __initconst;
+extern const struct imx_viv_gpu_data imx6_gc355_data __initconst;
+
+extern const struct imx_mxc_pwm_data imx6q_mxc_pwm_data[] __initconst;
+#define imx6q_add_mxc_pwm(id) \
+ imx_add_mxc_pwm(&imx6q_mxc_pwm_data[id])
+
+#define imx6q_add_mxc_pwm_backlight(id, pdata) \
+ platform_device_register_resndata(NULL, "pwm-backlight",\
+ id, NULL, 0, pdata, sizeof(*pdata));
+
+extern const struct imx_spdif_data imx6q_imx_spdif_data __initconst;
+#define imx6q_add_spdif(pdata) imx_add_spdif(&imx6q_imx_spdif_data, pdata)
+
+extern const struct imx_spdif_dai_data imx6q_spdif_dai_data __initconst;
+#define imx6q_add_spdif_dai() imx_add_spdif_dai(&imx6q_spdif_dai_data)
+
+#define imx6q_add_spdif_audio_device(pdata) imx_add_spdif_audio_device()
+
+#define imx6q_add_hdmi_soc() imx_add_hdmi_soc()
+extern const struct imx_hdmi_soc_data imx6q_imx_hdmi_soc_dai_data __initconst;
+#define imx6q_add_hdmi_soc_dai() \
+ imx_add_hdmi_soc_dai(&imx6q_imx_hdmi_soc_dai_data)
+
+extern const struct imx_mipi_dsi_data imx6q_mipi_dsi_data __initconst;
+#define imx6q_add_mipi_dsi(pdata) \
+ imx_add_mipi_dsi(&imx6q_mipi_dsi_data, pdata)
+
+extern const struct imx_flexcan_data imx6q_flexcan_data[] __initconst;
+#define imx6q_add_flexcan(id, pdata) \
+ imx_add_flexcan(&imx6q_flexcan_data[id], pdata)
+#define imx6q_add_flexcan0(pdata) imx6q_add_flexcan(0, pdata)
+#define imx6q_add_flexcan1(pdata) imx6q_add_flexcan(1, pdata)
+
+extern const struct imx_mipi_csi2_data imx6q_mipi_csi2_data __initconst;
+#define imx6q_add_mipi_csi2(pdata) \
+ imx_add_mipi_csi2(&imx6q_mipi_csi2_data, pdata)
+
+extern const struct imx_perfmon_data imx6q_perfmon_data[] __initconst;
+#define imx6q_add_perfmon(id) \
+ imx_add_perfmon(&imx6q_perfmon_data[id])
+
+extern const struct imx_mxc_mlb_data imx6q_mxc_mlb150_data __initconst;
+#define imx6q_add_mlb150(pdata) \
+ imx_add_mlb(pdata)
+
+extern const struct imx_pxp_data imx6dl_pxp_data __initconst;
+#define imx6dl_add_imx_pxp() \
+ imx_add_imx_pxp(&imx6dl_pxp_data)
+
+#define imx6dl_add_imx_pxp_client() \
+ imx_add_imx_pxp_client()
+
+#define imx6sl_add_imx_pxp_v4l2() \
+ imx_add_imx_pxp_v4l2()
+
+extern const struct imx_fsl_csi_data imx6sl_csi_data __initconst;
+#define imx6sl_add_fsl_csi() \
+ imx_add_fsl_csi(&imx6sl_csi_data)
+
+extern const struct imx_epdc_data imx6dl_epdc_data __initconst;
+#define imx6dl_add_imx_epdc(pdata) \
+ imx_add_imx_epdc(&imx6dl_epdc_data, pdata)
+
+extern const struct imx_epdc_data imx6sl_spdc_data __initconst;
+#define imx6sl_add_imx_spdc(pdata) \
+ imx_add_imx_spdc(&imx6sl_spdc_data, pdata)
+
+extern const struct imx_elcdif_data imx6dl_elcdif_data __initconst;
+#define imx6dl_add_imx_elcdif(pdata) \
+ imx_add_imx_elcdif(&imx6dl_elcdif_data, pdata)
+extern const struct imx_vdoa_data imx6q_vdoa_data __initconst;
+#define imx6q_add_vdoa() imx_add_vdoa(&imx6q_vdoa_data)
+
+extern const struct imx_pcie_data imx6q_pcie_data __initconst;
+#define imx6q_add_pcie(pdata) imx_add_pcie(&imx6q_pcie_data, pdata)
+
+#define imx6q_add_busfreq(pdata) imx_add_busfreq(pdata)
+
+#define imx6q_add_ion(id, pdata, size) \
+ platform_device_register_resndata(NULL, "ion-mxc",\
+ id, NULL, 0, pdata, size);
+
+extern const struct imx_imx_keypad_data imx6sl_imx_keypad_data;
+#define imx6sl_add_imx_keypad(pdata) \
+ imx_add_imx_keypad(&imx6sl_imx_keypad_data, pdata)
+
+extern const struct imx_dcp_data imx6sl_dcp_data __initconst;
+#define imx6sl_add_dcp() \
+ imx_add_dcp(&imx6sl_dcp_data);
+
+extern const struct imx_rngb_data imx6sl_rngb_data __initconst;
+#define imx6sl_add_rngb() \
+ imx_add_rngb(&imx6sl_rngb_data);
+
+#define imx6_add_armpmu() imx_add_imx_armpmu()
diff --git a/arch/arm/mach-mx6/devices.c b/arch/arm/mach-mx6/devices.c
new file mode 100644
index 00000000..29becab0
--- /dev/null
+++ b/arch/arm/mach-mx6/devices.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/ipu.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/uio_driver.h>
+#include <linux/iram_alloc.h>
+#include <linux/fsl_devices.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+static struct mxc_gpio_port mxc_gpio_ports[] = {
+ {
+ .chip.label = "gpio-0",
+ .base = IO_ADDRESS(GPIO1_BASE_ADDR),
+ .irq = MXC_INT_GPIO1_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO1_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START
+ },
+ {
+ .chip.label = "gpio-1",
+ .base = IO_ADDRESS(GPIO2_BASE_ADDR),
+ .irq = MXC_INT_GPIO2_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO2_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
+ },
+ {
+ .chip.label = "gpio-2",
+ .base = IO_ADDRESS(GPIO3_BASE_ADDR),
+ .irq = MXC_INT_GPIO3_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO3_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
+ },
+ {
+ .chip.label = "gpio-3",
+ .base = IO_ADDRESS(GPIO4_BASE_ADDR),
+ .irq = MXC_INT_GPIO4_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO4_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
+ },
+ {
+ .chip.label = "gpio-4",
+ .base = IO_ADDRESS(GPIO5_BASE_ADDR),
+ .irq = MXC_INT_GPIO5_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO5_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 4
+ },
+ {
+ .chip.label = "gpio-5",
+ .base = IO_ADDRESS(GPIO6_BASE_ADDR),
+ .irq = MXC_INT_GPIO6_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO6_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 5
+ },
+ {
+ .chip.label = "gpio-6",
+ .base = IO_ADDRESS(GPIO7_BASE_ADDR),
+ .irq = MXC_INT_GPIO7_INT15_0_NUM,
+ .irq_high = MXC_INT_GPIO7_INT31_16_NUM,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 6
+ },
+};
+
+int mx6q_register_gpios(void)
+{
+ /* 7 ports for Mx6 */
+ return mxc_gpio_init(mxc_gpio_ports, 7);
+}
diff --git a/arch/arm/mach-mx6/dummy_gpio.c b/arch/arm/mach-mx6/dummy_gpio.c
new file mode 100644
index 00000000..006397bc
--- /dev/null
+++ b/arch/arm/mach-mx6/dummy_gpio.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+
+void gpio_uart_active(int port, int no_irda) {}
+EXPORT_SYMBOL(gpio_uart_active);
+
+void gpio_uart_inactive(int port, int no_irda) {}
+EXPORT_SYMBOL(gpio_uart_inactive);
+
+void gpio_gps_active(void) {}
+EXPORT_SYMBOL(gpio_gps_active);
+
+void gpio_gps_inactive(void) {}
+EXPORT_SYMBOL(gpio_gps_inactive);
+
+void config_uartdma_event(int port) {}
+EXPORT_SYMBOL(config_uartdma_event);
+
+void gpio_spi_active(int cspi_mod) {}
+EXPORT_SYMBOL(gpio_spi_active);
+
+void gpio_spi_inactive(int cspi_mod) {}
+EXPORT_SYMBOL(gpio_spi_inactive);
+
+void gpio_owire_active(void) {}
+EXPORT_SYMBOL(gpio_owire_active);
+
+void gpio_owire_inactive(void) {}
+EXPORT_SYMBOL(gpio_owire_inactive);
+
+void gpio_i2c_active(int i2c_num) {}
+EXPORT_SYMBOL(gpio_i2c_active);
+
+void gpio_i2c_inactive(int i2c_num) {}
+EXPORT_SYMBOL(gpio_i2c_inactive);
+
+void gpio_i2c_hs_active(void) {}
+EXPORT_SYMBOL(gpio_i2c_hs_active);
+
+void gpio_i2c_hs_inactive(void) {}
+EXPORT_SYMBOL(gpio_i2c_hs_inactive);
+
+void gpio_pmic_active(void) {}
+EXPORT_SYMBOL(gpio_pmic_active);
+
+void gpio_activate_audio_ports(void) {}
+EXPORT_SYMBOL(gpio_activate_audio_ports);
+
+void gpio_sdhc_active(int module) {}
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+void gpio_sdhc_inactive(int module) {}
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+void gpio_sensor_select(int sensor) {}
+
+void gpio_sensor_active(unsigned int csi) {}
+EXPORT_SYMBOL(gpio_sensor_active);
+
+void gpio_sensor_inactive(unsigned int csi) {}
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+void gpio_ata_active(void) {}
+EXPORT_SYMBOL(gpio_ata_active);
+
+void gpio_ata_inactive(void) {}
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+void gpio_nand_active(void) {}
+EXPORT_SYMBOL(gpio_nand_active);
+
+void gpio_nand_inactive(void) {}
+EXPORT_SYMBOL(gpio_nand_inactive);
+
+void gpio_keypad_active(void) {}
+EXPORT_SYMBOL(gpio_keypad_active);
+
+void gpio_keypad_inactive(void) {}
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+int gpio_usbotg_hs_active(void)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+
+void gpio_usbotg_hs_inactive(void) {}
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+
+void gpio_fec_active(void) {}
+EXPORT_SYMBOL(gpio_fec_active);
+
+void gpio_fec_inactive(void) {}
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+void gpio_spdif_active(void) {}
+EXPORT_SYMBOL(gpio_spdif_active);
+
+void gpio_spdif_inactive(void) {}
+EXPORT_SYMBOL(gpio_spdif_inactive);
+
+void gpio_mlb_active(void) {}
+EXPORT_SYMBOL(gpio_mlb_active);
+
+void gpio_mlb_inactive(void) {}
+EXPORT_SYMBOL(gpio_mlb_inactive);
diff --git a/arch/arm/mach-mx6/etm.c b/arch/arm/mach-mx6/etm.c
new file mode 100644
index 00000000..8f328608
--- /dev/null
+++ b/arch/arm/mach-mx6/etm.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/iram_alloc.h>
+#include <linux/delay.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/coresight.h>
+
+static struct __init amba_device mx6_etb_device = {
+ .dev = {
+ .init_name = "etb",
+ },
+ .res = {
+ .start = MX6Q_ETB_BASE_ADDR,
+ .end = MX6Q_ETB_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x3bb907,
+};
+
+static struct __init amba_device mx6_etm_device[] = {
+ {
+ .dev = {
+ .init_name = "etm.0",
+ },
+ .res = {
+ .start = MX6Q_PTM0_BASE_ADDR,
+ .end = MX6Q_PTM0_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.1",
+ },
+ .res = {
+ .start = MX6Q_PTM1_BASE_ADDR,
+ .end = MX6Q_PTM1_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.2",
+ },
+ .res = {
+ .start = MX6Q_PTM2_BASE_ADDR,
+ .end = MX6Q_PTM2_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+ {
+ .dev = {
+ .init_name = "etm.3",
+ },
+ .res = {
+ .start = MX6Q_PTM3_BASE_ADDR,
+ .end = MX6Q_PTM3_BASE_ADDR + SZ_4K - 1,
+ },
+ .periphid = 0x1bb950,
+ },
+};
+
+#define FUNNEL_CTL 0
+static int __init etm_init(void)
+{
+ int i;
+ __iomem void *base;
+ base = ioremap(0x02144000, SZ_4K);
+ /*Unlock Funnel*/
+ __raw_writel(UNLOCK_MAGIC, base + CSMR_LOCKACCESS);
+ /*Enable all funnel port*/
+ __raw_writel(__raw_readl(base + FUNNEL_CTL) | 0xFF,
+ base + FUNNEL_CTL);
+ /*Lock Funnel*/
+ __raw_writel(0, base + CSMR_LOCKACCESS);
+ iounmap(base);
+
+ amba_device_register(&mx6_etb_device, &iomem_resource);
+ for (i = 0; i < num_possible_cpus(); i++)
+ amba_device_register(mx6_etm_device + i, &iomem_resource);
+
+ return 0;
+}
+
+subsys_initcall(etm_init);
diff --git a/arch/arm/mach-mx6/headsmp.S b/arch/arm/mach-mx6/headsmp.S
new file mode 100644
index 00000000..9492d8dc
--- /dev/null
+++ b/arch/arm/mach-mx6/headsmp.S
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ENTRY(v7_invalidate_l1)
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1: sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2: subs r3, r3, #1 @ Temp--
+ mov r5, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+ mcr p15, 0, r5, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+ mov pc, lr
+ENDPROC(v7_invalidate_l1)
+
+ __CPUINIT
+ENTRY(mx6_secondary_startup)
+
+ /* Invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0 @ Invalidate I-Cache
+ /* Invalidate L1 D-cache */
+ bl v7_invalidate_l1
+ /* Set ARM working mode */
+ msr cpsr_fsxc, #0xd3
+
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ ldr r1, = 0x020d8020
+ add r1, r0, LSL#3
+
+ /*Clear SRC_GPR register */
+ mov r0, #0
+ str r0, [r1]
+ str r0, [r1, #0x4]
+
+ /* Jump to secondary_startup */
+ b secondary_startup
+
+ENDPROC(mx6_secondary_startup)
diff --git a/arch/arm/mach-mx6/irq.c b/arch/arm/mach-mx6/irq.c
new file mode 100644
index 00000000..d298d50b
--- /dev/null
+++ b/arch/arm/mach-mx6/irq.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <asm/hardware/gic.h>
+#include <mach/hardware.h>
+#ifdef CONFIG_CPU_FREQ_GOV_INTERACTIVE
+#include <linux/cpufreq.h>
+#endif
+#ifdef CONFIG_PCI_MSI
+#include "msi.h"
+#endif
+
+int mx6q_register_gpios(void);
+unsigned int gpc_wake_irq[4];
+extern bool enable_wait_mode;
+#ifdef CONFIG_CPU_FREQ_GOV_INTERACTIVE
+extern int cpufreq_gov_irq_tuner_register(struct irq_tuner dbs_irq_tuner);
+#endif
+
+static int mx6_gic_irq_set_wake(struct irq_data *d, unsigned int enable)
+{
+ if ((d->irq < MXC_INT_START) || (d->irq > MXC_INT_END)) {
+ printk(KERN_ERR "Invalid irq number!\n");
+ return -EINVAL;
+ }
+
+ if (enable) {
+ gpc_wake_irq[d->irq / 32 - 1] |= 1 << (d->irq % 32);
+ printk(KERN_INFO "add wake up source irq %d\n", d->irq);
+ } else {
+ printk(KERN_INFO "remove wake up source irq %d\n", d->irq);
+ gpc_wake_irq[d->irq / 32 - 1] &= ~(1 << (d->irq % 32));
+ }
+ return 0;
+}
+#ifdef CONFIG_CPU_FREQ_GOV_INTERACTIVE
+static struct irq_tuner mxc_irq_tuner[] = {
+ {
+ .irq_number = 41, /* GPU 3D */
+ .up_threshold = 0,
+ .enable = 0,},
+ {
+ .irq_number = 42, /* GPU 2D */
+ .up_threshold = 40,
+ .enable = 0,},
+ {
+ .irq_number = 43, /* GPU VG */
+ .up_threshold = 0,
+ .enable = 0,},
+ {
+ .irq_number = 42, /* GPU 2D */
+ .up_threshold = 40,
+ .enable = 1,},
+ {
+ .irq_number = 43, /* GPU VG */
+ .up_threshold = 0,
+ .enable = 1,},
+ {
+ .irq_number = 54, /* uSDHC1 */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 55, /* uSDHC2 */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 56, /* uSDHC3 */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 57, /* uSDHC4 */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 71, /* SATA */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 75, /* OTG */
+ .up_threshold = 10,
+ .enable = 1,},
+ {
+ .irq_number = 150, /* ENET */
+ .up_threshold = 4,
+ .enable = 1,},
+ {
+ .irq_number = 0, /* END */
+ .up_threshold = 0,
+ .enable = 0,},
+};
+#endif
+void mx6_init_irq(void)
+{
+ void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
+ struct irq_desc *desc;
+ unsigned int i;
+
+ /* start offset if private timer irq id, which is 29.
+ * ID table:
+ * Global timer, PPI -> ID27
+ * A legacy nFIQ, PPI -> ID28
+ * Private timer, PPI -> ID29
+ * Watchdog timers, PPI -> ID30
+ * A legacy nIRQ, PPI -> ID31
+ */
+ gic_init(0, 29, IO_ADDRESS(IC_DISTRIBUTOR_BASE_ADDR),
+ IO_ADDRESS(IC_INTERFACES_BASE_ADDR));
+
+ if (enable_wait_mode) {
+ /* Mask the always pending interrupts - HW bug. */
+ __raw_writel(0x00400000, gpc_base + 0x0c);
+ __raw_writel(0x20000000, gpc_base + 0x10);
+ }
+
+
+ for (i = MXC_INT_START; i <= MXC_INT_END; i++) {
+ desc = irq_to_desc(i);
+ desc->irq_data.chip->irq_set_wake = mx6_gic_irq_set_wake;
+ }
+ mx6q_register_gpios();
+#ifdef CONFIG_CPU_FREQ_GOV_INTERACTIVE
+ for (i = 0; i < ARRAY_SIZE(mxc_irq_tuner); i++)
+ cpufreq_gov_irq_tuner_register(mxc_irq_tuner[i]);
+#endif
+#ifdef CONFIG_PCI_MSI
+ imx_msi_init();
+#endif
+}
diff --git a/arch/arm/mach-mx6/localtimer.c b/arch/arm/mach-mx6/localtimer.c
new file mode 100644
index 00000000..2fac9fb2
--- /dev/null
+++ b/arch/arm/mach-mx6/localtimer.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+#include <mach/irqs.h>
+#include <mach/hardware.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-mx6/mm.c b/arch/arm/mach-mx6/mm.c
new file mode 100644
index 00000000..78e5712b
--- /dev/null
+++ b/arch/arm/mach-mx6/mm.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+#include <mach/iomux-v3.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "crm_regs.h"
+
+/*!
+ * This structure defines the MX6 memory map.
+ */
+static struct map_desc mx6_io_desc[] __initdata = {
+ {
+ .virtual = BOOT_ROM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(BOOT_ROM_BASE_ADDR),
+ .length = ROMCP_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_ARB_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_ARB_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = ARM_PERIPHBASE_VIRT,
+ .pfn = __phys_to_pfn(ARM_PERIPHBASE),
+ .length = ARM_PERIPHBASE_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = IRAM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(IRAM_BASE_ADDR),
+ .length = IRAM_VIRT_SIZE,
+ .type = MT_MEMORY_NONCACHED},
+};
+
+static void mx6_set_cpu_type(void)
+{
+ u32 cpu_type = readl(IO_ADDRESS(ANATOP_BASE_ADDR + 0x280));
+
+ cpu_type >>= 16;
+ if (cpu_type == 0x60) {
+ mxc_set_cpu_type(MXC_CPU_MX6SL);
+ imx_print_silicon_rev("i.MX6SoloLite", mx6sl_revision());
+ return;
+ }
+
+ cpu_type = readl(IO_ADDRESS(ANATOP_BASE_ADDR + 0x260));
+ cpu_type >>= 16;
+ if (cpu_type == 0x63) {
+ mxc_set_cpu_type(MXC_CPU_MX6Q);
+ imx_print_silicon_rev("i.MX6Q", mx6q_revision());
+ } else if (cpu_type == 0x61) {
+ mxc_set_cpu_type(MXC_CPU_MX6DL);
+ imx_print_silicon_rev("i.MX6DL/SOLO", mx6dl_revision());
+ } else
+ pr_err("Unknown CPU type: %x\n", cpu_type);
+}
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mx6_map_io(void)
+{
+ iotable_init(mx6_io_desc, ARRAY_SIZE(mx6_io_desc));
+ mxc_iomux_v3_init(IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR));
+ mxc_arch_reset_init(IO_ADDRESS(MX6Q_WDOG1_BASE_ADDR));
+ mx6_set_cpu_type();
+ mxc_cpu_lp_set(WAIT_CLOCKED);
+}
+#ifdef CONFIG_CACHE_L2X0
+int mxc_init_l2x0(void)
+{
+ unsigned int val;
+
+ #define IOMUXC_GPR11_L2CACHE_AS_OCRAM 0x00000002
+
+ val = readl(IOMUXC_GPR11);
+ if (cpu_is_mx6sl() && (val & IOMUXC_GPR11_L2CACHE_AS_OCRAM)) {
+ /* L2 cache configured as OCRAM, reset it */
+ val &= ~IOMUXC_GPR11_L2CACHE_AS_OCRAM;
+ writel(val, IOMUXC_GPR11);
+ }
+
+ writel(0x132, IO_ADDRESS(L2_BASE_ADDR + L2X0_TAG_LATENCY_CTRL));
+ writel(0x132, IO_ADDRESS(L2_BASE_ADDR + L2X0_DATA_LATENCY_CTRL));
+
+ /*
+ * The L2 cache controller(PL310) version on the i.MX6D/Q is r3p1-50rel0
+ * The L2 cache controller(PL310) version on the i.MX6DL/SOLO/SL is r3p2
+ * But according to ARM PL310 errata: 752271
+ * ID: 752271: Double linefill feature can cause data corruption
+ * Fault Status: Present in: r3p0, r3p1, r3p1-50rel0. Fixed in r3p2
+ * Workaround: The only workaround to this erratum is to disable the
+ * double linefill feature. This is the default behavior.
+ */
+ if (!cpu_is_mx6q()) {
+ val = readl(IO_ADDRESS(L2_BASE_ADDR + L2X0_PREFETCH_CTRL));
+ val |= 0x40800000;
+ writel(val, IO_ADDRESS(L2_BASE_ADDR + L2X0_PREFETCH_CTRL));
+ }
+
+ val = readl(IO_ADDRESS(L2_BASE_ADDR + L2X0_POWER_CTRL));
+ val |= L2X0_DYNAMIC_CLK_GATING_EN;
+ val |= L2X0_STNDBY_MODE_EN;
+ writel(val, IO_ADDRESS(L2_BASE_ADDR + L2X0_POWER_CTRL));
+
+ l2x0_init(IO_ADDRESS(L2_BASE_ADDR), 0x0, ~0x00000000);
+ return 0;
+}
+
+
+arch_initcall(mxc_init_l2x0);
+#endif
diff --git a/arch/arm/mach-mx6/msi.c b/arch/arm/mach-mx6/msi.c
new file mode 100644
index 00000000..096d1c24
--- /dev/null
+++ b/arch/arm/mach-mx6/msi.c
@@ -0,0 +1,151 @@
+/*
+ * arch/arm/mach-mx6/msi.c
+ *
+ * PCI MSI support for the imx processor
+ *
+ * Copyright (c) 2013 Boundary Devices.
+ * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/pci.h>
+#include <linux/msi.h>
+#include <asm/bitops.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include "msi.h"
+
+
+#define IMX_NUM_MSI_IRQS 128
+static DECLARE_BITMAP(msi_irq_in_use, IMX_NUM_MSI_IRQS);
+
+static void imx_msi_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int i, j;
+ unsigned int status;
+ struct irq_chip *chip = irq_get_chip(irq);
+ unsigned int base_irq = IRQ_IMX_MSI_0;
+
+ chained_irq_enter(chip, desc);
+ for (i = 0; i < 8; i++) {
+ status = imx_pcie_msi_pending(i);
+ while (status) {
+ j = __fls(status);
+ generic_handle_irq(base_irq + j);
+ status &= ~(1 << j);
+ }
+ base_irq += 32;
+ }
+ chained_irq_exit(chip, desc);
+}
+
+/*
+* Dynamic irq allocate and deallocation
+*/
+int create_irq(void)
+{
+ int irq, pos;
+
+ do {
+ pos = find_first_zero_bit(msi_irq_in_use, IMX_NUM_MSI_IRQS);
+ if ((unsigned int)pos >= IMX_NUM_MSI_IRQS)
+ return -ENOSPC;
+ /* test_and_set_bit operates on 32-bits at a time */
+ } while (test_and_set_bit(pos, msi_irq_in_use));
+
+ irq = IRQ_IMX_MSI_0 + pos;
+ dynamic_irq_init(irq);
+ return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+ int pos = irq - IRQ_IMX_MSI_0;
+
+ dynamic_irq_cleanup(irq);
+ clear_bit(pos, msi_irq_in_use);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ destroy_irq(irq);
+}
+
+static void imx_msi_irq_ack(struct irq_data *d)
+{
+ return;
+}
+
+static void imx_msi_irq_enable(struct irq_data *d)
+{
+ imx_pcie_enable_irq(d->irq - IRQ_IMX_MSI_0, 1);
+ return unmask_msi_irq(d);
+}
+
+static void imx_msi_irq_disable(struct irq_data *d)
+{
+ imx_pcie_enable_irq(d->irq - IRQ_IMX_MSI_0, 0);
+ return mask_msi_irq(d);
+}
+
+static void imx_msi_irq_mask(struct irq_data *d)
+{
+ imx_pcie_mask_irq(d->irq - IRQ_IMX_MSI_0, 1);
+ return mask_msi_irq(d);
+}
+
+static void imx_msi_irq_unmask(struct irq_data *d)
+{
+ imx_pcie_mask_irq(d->irq - IRQ_IMX_MSI_0, 0);
+ return unmask_msi_irq(d);
+}
+
+static struct irq_chip imx_msi_chip = {
+ .name = "PCIe-MSI",
+ .irq_ack = imx_msi_irq_ack,
+ .irq_enable = imx_msi_irq_enable,
+ .irq_disable = imx_msi_irq_disable,
+ .irq_mask = imx_msi_irq_mask,
+ .irq_unmask = imx_msi_irq_unmask,
+};
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+ int irq = create_irq();
+ struct msi_msg msg;
+
+ if (irq < 0)
+ return irq;
+
+ irq_set_msi_desc(irq, desc);
+
+ msg.address_hi = 0x0;
+ msg.address_lo = MSI_MATCH_ADDR;
+ /* 16bits msg.data: set cpu type to the upper 8bits*/
+ msg.data = (mxc_cpu_type << 8) | ((irq - IRQ_IMX_MSI_0) & 0xFF);
+
+ write_msi_msg(irq, &msg);
+ irq_set_chip_and_handler(irq, &imx_msi_chip, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ pr_info("IMX-PCIe: MSI 0x%04x @%#x:%#x, irq = %d\n",
+ msg.data, msg.address_hi,
+ msg.address_lo, irq);
+ return 0;
+}
+
+void imx_msi_init(void)
+{
+ irq_set_chained_handler(MXC_INT_PCIE_0, imx_msi_handler);
+}
diff --git a/arch/arm/mach-mx6/msi.h b/arch/arm/mach-mx6/msi.h
new file mode 100644
index 00000000..ce0e4673
--- /dev/null
+++ b/arch/arm/mach-mx6/msi.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Boundary Devices, Inc. All Rights Reserved.
+ * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+extern void imx_pcie_enable_irq(unsigned pos, int set);
+void imx_pcie_mask_irq(unsigned pos, int set);
+unsigned imx_pcie_msi_pending(unsigned index);
+
+#define MSI_MATCH_ADDR 0x01FF8000
+
+void imx_msi_init(void);
diff --git a/arch/arm/mach-mx6/mx6_anatop_regulator.c b/arch/arm/mach-mx6/mx6_anatop_regulator.c
new file mode 100644
index 00000000..b26f86bf
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_anatop_regulator.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * mx6_anatop_regulator.c -- i.MX6 Driver for Anatop regulators
+ */
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+
+#include <mach/clock.h>
+#include <mach/system.h>
+
+#include "crm_regs.h"
+#include "regs-anadig.h"
+
+#define GPC_PGC_GPU_PGCR_OFFSET 0x260
+#define GPC_CNTR_OFFSET 0x0
+
+#define LDO_RAMP_UP_UNIT_IN_CYCLES 64 /* 64 cycles per step */
+#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* time base on 24M OSC */
+
+extern struct platform_device sgtl5000_vdda_reg_devices;
+extern struct platform_device sgtl5000_vddio_reg_devices;
+extern struct platform_device sgtl5000_vddd_reg_devices;
+extern void __iomem *gpc_base;
+/* we use the below flag to keep PU regulator state, because enable/disable
+of PU regulator share with the same register as voltage set of PU regulator.
+PU voltage set by cpufreq driver if the flag is set, and enable/disable by
+GPU/VPU driver*/
+static unsigned int pu_is_enabled;
+static unsigned int get_clk;
+static struct clk *gpu3d_clk, *gpu3d_shade_clk, *gpu2d_clk, *gpu2d_axi_clk;
+static struct clk *openvg_axi_clk, *vpu_clk;
+extern int external_pureg;
+extern struct regulator *pu_regulator;
+extern u32 enable_ldo_mode;
+
+
+static int get_voltage(struct anatop_regulator *sreg)
+{
+ int uv;
+ struct anatop_regulator_data *rdata = sreg->rdata;
+
+ if (sreg->rdata->control_reg) {
+ u32 val = (__raw_readl(rdata->control_reg) >>
+ rdata->vol_bit_shift) & rdata->vol_bit_mask;
+ uv = rdata->min_voltage + (val - rdata->min_bit_val) * 25000;
+ pr_debug("vddio = %d, val=%u\n", uv, val);
+ return uv;
+ } else {
+ pr_debug("Regulator not supported.\n");
+ return -ENOTSUPP;
+ }
+}
+
+static int set_voltage(struct anatop_regulator *sreg, int uv)
+{
+ u32 val, reg;
+ u32 delay, steps, old_val;
+
+ pr_debug("%s: uv %d, min %d, max %d\n", __func__,
+ uv, sreg->rdata->min_voltage, sreg->rdata->max_voltage);
+
+ if (uv < sreg->rdata->min_voltage || uv > sreg->rdata->max_voltage)
+ return -EINVAL;
+
+ if (sreg->rdata->control_reg) {
+ val = sreg->rdata->min_bit_val +
+ (uv - sreg->rdata->min_voltage) / 25000;
+
+ reg = (__raw_readl(sreg->rdata->control_reg) &
+ ~(sreg->rdata->vol_bit_mask <<
+ sreg->rdata->vol_bit_shift));
+ pr_debug("%s: calculated val %d\n", __func__, val);
+
+ old_val = (__raw_readl(sreg->rdata->control_reg) >>
+ sreg->rdata->vol_bit_shift) & sreg->rdata->vol_bit_mask;
+
+ __raw_writel((val << sreg->rdata->vol_bit_shift) | reg,
+ sreg->rdata->control_reg);
+
+ if (sreg->rdata->control_reg == (unsigned int)(MXC_PLL_BASE +
+ HW_ANADIG_REG_CORE)) {
+ /* calculate how many steps to ramp up */
+ steps = (val > old_val) ? val - old_val : 0;
+ if (steps) {
+ switch (sreg->rdata->vol_bit_shift) {
+ case BP_ANADIG_REG_CORE_REG0_TRG:
+ reg = (__raw_readl(MXC_PLL_BASE +
+ HW_ANADIG_ANA_MISC2) &
+ BM_ANADIG_ANA_MISC2_REG0_STEP_TIME) >>
+ BP_ANADIG_ANA_MISC2_REG0_STEP_TIME;
+ break;
+ case BP_ANADIG_REG_CORE_REG1_TRG:
+ reg = (__raw_readl(MXC_PLL_BASE +
+ HW_ANADIG_ANA_MISC2) &
+ BM_ANADIG_ANA_MISC2_REG1_STEP_TIME) >>
+ BP_ANADIG_ANA_MISC2_REG1_STEP_TIME;
+ break;
+ case BP_ANADIG_REG_CORE_REG2_TRG:
+ reg = (__raw_readl(MXC_PLL_BASE +
+ HW_ANADIG_ANA_MISC2) &
+ BM_ANADIG_ANA_MISC2_REG2_STEP_TIME) >>
+ BP_ANADIG_ANA_MISC2_REG2_STEP_TIME;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * the delay time for LDO ramp up time is
+ * based on the register setting, we need
+ * to calculate how many steps LDO need to
+ * ramp up, and how much delay needs. (us)
+ */
+ delay = steps * ((LDO_RAMP_UP_UNIT_IN_CYCLES <<
+ reg) / LDO_RAMP_UP_FREQ_IN_MHZ + 1);
+ udelay(delay);
+ pr_debug("%s: %s: delay %d, steps %d, uv %d\n",
+ __func__, sreg->rdata->name, delay,
+ steps, uv);
+ }
+ }
+
+ return 0;
+ } else {
+ pr_debug("Regulator not supported.\n");
+ return -ENOTSUPP;
+ }
+}
+
+static int pu_enable(struct anatop_regulator *sreg)
+{
+ unsigned int reg, vddsoc;
+ int ret = 0;
+ /*get PU related clk to finish PU regulator power up*/
+ if (!get_clk) {
+ if (!cpu_is_mx6sl()) {
+ gpu3d_clk = clk_get(NULL, "gpu3d_clk");
+ if (IS_ERR(gpu3d_clk))
+ printk(KERN_ERR "%s: failed to get gpu3d_clk!\n"
+ , __func__);
+ gpu3d_shade_clk = clk_get(NULL, "gpu3d_shader_clk");
+ if (IS_ERR(gpu3d_shade_clk))
+ printk(KERN_ERR "%s: failed to get shade_clk!\n"
+ , __func__);
+ if (IS_ERR(vpu_clk))
+ printk(KERN_ERR "%s: failed to get vpu_clk!\n",
+ __func__);
+ }
+ gpu2d_clk = clk_get(NULL, "gpu2d_clk");
+ if (IS_ERR(gpu2d_clk))
+ printk(KERN_ERR "%s: failed to get gpu2d_clk!\n",
+ __func__);
+ gpu2d_axi_clk = clk_get(NULL, "gpu2d_axi_clk");
+ if (IS_ERR(gpu2d_axi_clk))
+ printk(KERN_ERR "%s: failed to get gpu2d_axi_clk!\n",
+ __func__);
+ openvg_axi_clk = clk_get(NULL, "openvg_axi_clk");
+ if (IS_ERR(openvg_axi_clk))
+ printk(KERN_ERR "%s: failed to get openvg_axi_clk!\n",
+ __func__);
+ get_clk = 1;
+
+ }
+ if (external_pureg) {
+ /*enable extern PU regulator*/
+ ret = regulator_enable(pu_regulator);
+ if (ret < 0)
+ printk(KERN_ERR "%s: enable pu error!\n", __func__);
+ } else {
+ /*Track the voltage of VDDPU with VDDSOC if use internal PU
+ *regulator.
+ */
+ reg = __raw_readl(ANADIG_REG_CORE);
+ vddsoc = reg & (ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG2_SOC_TARGET_OFFSET);
+ reg &= ~(ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG1_PU_TARGET_OFFSET);
+ reg |= vddsoc >> (ANADIG_REG2_SOC_TARGET_OFFSET
+ -ANADIG_REG1_PU_TARGET_OFFSET);
+ __raw_writel(reg, ANADIG_REG_CORE);
+ }
+
+ /* Need to wait for the regulator to come back up */
+ /*
+ * Delay time is based on the number of 24MHz clock cycles
+ * programmed in the ANA_MISC2_BASE_ADDR for each
+ * 25mV step.
+ */
+ udelay(150);
+ /*enable gpu clock to powerup GPU right.*/
+ if (get_clk) {
+ if (!cpu_is_mx6sl()) {
+ clk_enable(gpu3d_clk);
+ clk_enable(gpu3d_shade_clk);
+ clk_enable(vpu_clk);
+ }
+ clk_enable(gpu2d_clk);
+ clk_enable(gpu2d_axi_clk);
+ clk_enable(openvg_axi_clk);
+ }
+ /* enable power up request */
+ reg = __raw_readl(gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
+ __raw_writel(reg | 0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
+ /* power up request */
+ reg = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
+ __raw_writel(reg | 0x2, gpc_base + GPC_CNTR_OFFSET);
+ /* Wait for the power up bit to clear */
+ while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x2)
+ ;
+ /* Enable the Brown Out detection. */
+ reg = __raw_readl(ANA_MISC2_BASE_ADDR);
+ reg |= ANADIG_ANA_MISC2_REG1_BO_EN;
+ __raw_writel(reg, ANA_MISC2_BASE_ADDR);
+ if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /* Unmask the ANATOP brown out interrupt in the GPC. */
+ reg = __raw_readl(gpc_base + 0x14);
+ reg &= ~0x80000000;
+ __raw_writel(reg, gpc_base + 0x14);
+ }
+ pu_is_enabled = 1;
+ if (get_clk) {
+ if (!cpu_is_mx6sl()) {
+ clk_disable(gpu3d_clk);
+ clk_disable(gpu3d_shade_clk);
+ clk_disable(vpu_clk);
+ }
+ clk_disable(gpu2d_clk);
+ clk_disable(gpu2d_axi_clk);
+ clk_disable(openvg_axi_clk);
+ }
+ return 0;
+}
+
+int pu_disable(struct anatop_regulator *sreg)
+{
+ unsigned int reg;
+ int ret = 0;
+
+ /* Disable the brown out detection since we are going to be
+ * disabling the LDO.
+ */
+ reg = __raw_readl(ANA_MISC2_BASE_ADDR);
+ reg &= ~ANADIG_ANA_MISC2_REG1_BO_EN;
+ __raw_writel(reg, ANA_MISC2_BASE_ADDR);
+
+ /* Power gate the PU LDO. */
+ /* Power gate the PU domain first. */
+ /* enable power down request */
+ reg = __raw_readl(gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
+ __raw_writel(reg | 0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
+ /* power down request */
+ reg = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
+ __raw_writel(reg | 0x1, gpc_base + GPC_CNTR_OFFSET);
+ /* Wait for power down to complete. */
+ while (__raw_readl(gpc_base + GPC_CNTR_OFFSET) & 0x1)
+ ;
+ if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /* Mask the ANATOP brown out interrupt in the GPC. */
+ reg = __raw_readl(gpc_base + 0x14);
+ reg |= 0x80000000;
+ __raw_writel(reg, gpc_base + 0x14);
+ }
+
+ if (external_pureg) {
+ /*disable extern PU regulator*/
+ ret = regulator_disable(pu_regulator);
+ if (ret < 0)
+ printk(KERN_ERR "%s: disable pu error!\n", __func__);
+ } else {
+ /* PU power gating. */
+ reg = __raw_readl(ANADIG_REG_CORE);
+ reg &= ~(ANADIG_REG_TARGET_MASK <<
+ ANADIG_REG1_PU_TARGET_OFFSET);
+ __raw_writel(reg, ANADIG_REG_CORE);
+ }
+ pu_is_enabled = 0;
+ /* Clear the BO interrupt in the ANATOP. */
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= 0x80000000;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+ return 0;
+}
+EXPORT_SYMBOL(pu_disable);
+static int is_pu_enabled(struct anatop_regulator *sreg)
+{
+ return pu_is_enabled;
+}
+static int enable(struct anatop_regulator *sreg)
+{
+ return 0;
+}
+
+static int disable(struct anatop_regulator *sreg)
+{
+ return 0;
+}
+
+static int is_enabled(struct anatop_regulator *sreg)
+{
+ return 1;
+}
+static int vdd3p0_enable(struct anatop_regulator *sreg)
+{
+ __raw_writel(BM_ANADIG_REG_3P0_ENABLE_LINREG,
+ sreg->rdata->control_reg+4);
+ return 0;
+}
+
+static int vdd3p0_disable(struct anatop_regulator *sreg)
+{
+ __raw_writel(BM_ANADIG_REG_3P0_ENABLE_LINREG,
+ sreg->rdata->control_reg+8);
+ return 0;
+}
+
+static int vdd3p0_is_enabled(struct anatop_regulator *sreg)
+{
+ return !!(__raw_readl(sreg->rdata->control_reg) & BM_ANADIG_REG_3P0_ENABLE_LINREG);
+}
+
+static struct anatop_regulator_data vddpu_data = {
+ .name = "vddpu",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = pu_enable,
+ .disable = pu_disable,
+ .is_enabled = is_pu_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_CORE),
+ .vol_bit_shift = 9,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 1,
+ .min_voltage = 725000,
+ .max_voltage = 1300000,
+};
+
+static struct anatop_regulator_data vddcore_data = {
+ .name = "vddcore",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = enable,
+ .disable = disable,
+ .is_enabled = is_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_CORE),
+ .vol_bit_shift = 0,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 1,
+ .min_voltage = 725000,
+ .max_voltage = 1300000,
+};
+
+static struct anatop_regulator_data vddsoc_data = {
+ .name = "vddsoc",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = enable,
+ .disable = disable,
+ .is_enabled = is_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_CORE),
+ .vol_bit_shift = 18,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 1,
+ .min_voltage = 725000,
+ .max_voltage = 1300000,
+};
+
+static struct anatop_regulator_data vdd2p5_data = {
+ .name = "vdd2p5",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = enable,
+ .disable = disable,
+ .is_enabled = is_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_2P5),
+ .vol_bit_shift = 8,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 0,
+ .min_voltage = 2000000,
+ .max_voltage = 2775000,
+};
+
+static struct anatop_regulator_data vdd1p1_data = {
+ .name = "vdd1p1",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = enable,
+ .disable = disable,
+ .is_enabled = is_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_1P1),
+ .vol_bit_shift = 8,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 4,
+ .min_voltage = 800000,
+ .max_voltage = 1400000,
+};
+
+static struct anatop_regulator_data vdd3p0_data = {
+ .name = "vdd3p0",
+ .set_voltage = set_voltage,
+ .get_voltage = get_voltage,
+ .enable = vdd3p0_enable,
+ .disable = vdd3p0_disable,
+ .is_enabled = vdd3p0_is_enabled,
+ .control_reg = (u32)(MXC_PLL_BASE + HW_ANADIG_REG_3P0),
+ .vol_bit_shift = 8,
+ .vol_bit_mask = 0x1F,
+ .min_bit_val = 0,
+ .min_voltage = 2625000,
+ .max_voltage = 3400000,
+};
+
+/* CPU */
+static struct regulator_consumer_supply vddcore_consumers[] = {
+ {
+ .supply = "cpu_vddgp",
+ }
+};
+/* PU */
+static struct regulator_consumer_supply vddpu_consumers[] = {
+ {
+ .supply = "cpu_vddvpu",
+ },
+ {
+ .supply = "cpu_vddgpu",
+ }
+};
+/* SOC */
+static struct regulator_consumer_supply vddsoc_consumers[] = {
+ {
+ .supply = "cpu_vddsoc",
+ },
+};
+
+/* USB phy 3P0 */
+static struct regulator_consumer_supply vdd3p0_consumers[] = {
+ {
+ .supply = "cpu_vdd3p0",
+ },
+};
+
+static struct regulator_init_data vddpu_init = {
+ .constraints = {
+ .name = "vddpu",
+ .min_uV = 725000,
+ .max_uV = 1300000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_MODE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddpu_consumers),
+ .consumer_supplies = vddpu_consumers,
+};
+
+static struct regulator_init_data vddcore_init = {
+ .constraints = {
+ .name = "vddcore",
+ .min_uV = 725000,
+ .max_uV = 1300000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddcore_consumers),
+ .consumer_supplies = &vddcore_consumers[0],
+};
+
+static struct regulator_init_data vddsoc_init = {
+ .constraints = {
+ .name = "vddsoc",
+ .min_uV = 725000,
+ .max_uV = 1300000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vddsoc_consumers),
+ .consumer_supplies = &vddsoc_consumers[0],
+};
+
+static struct regulator_init_data vdd2p5_init = {
+ .constraints = {
+ .name = "vdd2p5",
+ .min_uV = 2000000,
+ .max_uV = 2775000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 0,
+ .consumer_supplies = NULL,
+};
+
+
+static struct regulator_init_data vdd1p1_init = {
+ .constraints = {
+ .name = "vdd1p1",
+ .min_uV = 800000,
+ .max_uV = 1400000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ .input_uV = 5000000,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 0,
+ .consumer_supplies = NULL,
+};
+
+
+static struct regulator_init_data vdd3p0_init = {
+ .constraints = {
+ .name = "vdd3p0",
+ .min_uV = 2625000,
+ .max_uV = 3400000,
+ .valid_modes_mask = REGULATOR_MODE_FAST |
+ REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vdd3p0_consumers),
+ .consumer_supplies = &vdd3p0_consumers[0],
+};
+
+static struct anatop_regulator vddpu_reg = {
+ .rdata = &vddpu_data,
+};
+
+static struct anatop_regulator vddcore_reg = {
+ .rdata = &vddcore_data,
+};
+
+static struct anatop_regulator vddsoc_reg = {
+ .rdata = &vddsoc_data,
+};
+
+static struct anatop_regulator vdd2p5_reg = {
+ .rdata = &vdd2p5_data,
+};
+
+static struct anatop_regulator vdd1p1_reg = {
+ .rdata = &vdd1p1_data,
+};
+
+static struct anatop_regulator vdd3p0_reg = {
+ .rdata = &vdd3p0_data,
+};
+
+static int __init regulators_init(void)
+{
+ unsigned int reg;
+
+ anatop_register_regulator(&vddpu_reg, ANATOP_VDDPU, &vddpu_init);
+ anatop_register_regulator(&vddcore_reg, ANATOP_VDDCORE, &vddcore_init);
+ anatop_register_regulator(&vddsoc_reg, ANATOP_VDDSOC, &vddsoc_init);
+ anatop_register_regulator(&vdd2p5_reg, ANATOP_VDD2P5, &vdd2p5_init);
+ anatop_register_regulator(&vdd1p1_reg, ANATOP_VDD1P1, &vdd1p1_init);
+ anatop_register_regulator(&vdd3p0_reg, ANATOP_VDD3P0, &vdd3p0_init);
+
+ /* Set the REGx step time back to reset value,
+ * as ROM may modify it according to fuse setting,
+ * so we need to set it back, otherwise, the delay
+ * time in cpu freq change will be impacted, the reset
+ * value is 0'b00, 64 cycles of 24M clock.
+ */
+ reg = __raw_readl(ANADIG_MISC2_REG);
+ reg &= ~ANADIG_ANA_MISC2_REG0_STEP_TIME_MASK;
+ reg &= ~ANADIG_ANA_MISC2_REG1_STEP_TIME_MASK;
+ reg &= ~ANADIG_ANA_MISC2_REG2_STEP_TIME_MASK;
+ __raw_writel(reg, ANADIG_MISC2_REG);
+
+ /* clear flag in boot */
+ pu_is_enabled = 0;
+ get_clk = 0;
+ pu_disable(NULL);
+ return 0;
+}
+postcore_initcall(regulators_init);
diff --git a/arch/arm/mach-mx6/mx6_ddr_freq.S b/arch/arm/mach-mx6/mx6_ddr_freq.S
new file mode 100644
index 00000000..de20f0c3
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_ddr_freq.S
@@ -0,0 +1,1010 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+
+ .macro switch_to_528MHz
+
+ /* DDR freq change to 528MHz */
+
+ /* check if periph_clk_sel is already set */
+ ldr r0, [r6, #0x14]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ beq set_ahb_podf_before_switch
+
+ /* Step 1: Change periph_clk to be sourced from pll3_clk. */
+ /* Ensure PLL3 is the source and set the divider to 1. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0x3000
+ str r0, [r6, #0x18]
+
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x38000000
+ str r0, [r6, #0x14]
+
+ /* Set the AHB dividers before the switch. */
+ /* Don't change AXI clock divider. */
+ /* Set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4 (need to maintain GPT divider). */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0xd00
+ orr r0, r0, #0x10000
+ str r0, [r6, #0x14]
+
+wait_div_update528:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update528
+
+ /* Now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch3:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch3
+
+ b switch_pre_periph_clk_528
+
+set_ahb_podf_before_switch:
+ /* Set the AHB dividers before the switch. */
+ /* Especially if the AHB is at 24MHz, divider
+ * would be at divide by 1 and clock
+ * would be too fast when switching to PLL3.
+ */
+ /* Don't change AXI clock divider. */
+ /* Set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4 (need to maintain GPT divider). */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0xd00
+ orr r0, r0, #0x10000
+ str r0, [r6, #0x14]
+
+wait_div_update528_1:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update528_1
+
+switch_pre_periph_clk_528:
+
+ /* Now switch pre_periph_clk to PLL2_528MHz. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0xC0000
+ str r0, [r6, #0x18]
+
+ /* Now switch periph_clk back. */
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch4:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch4
+
+ ldr r0, =ANATOP_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r1, [r0, #0x260]
+ mov r2, r1
+ /*Is mx6q?*/
+ and r1, r1, #0xff0000
+ cmp r1, #0x630000
+ bne skip_gpt_workaround1
+ /*Is mx6q TO1.0?*/
+ and r2, r2, #0xff
+ cmp r2, #0x0
+ bne skip_gpt_workaround1
+ /* Change the GPT divider so that its at 6MHz. */
+ ldr r0, [r6, #0x1C]
+ bic r0, r0, #0x3F
+ orr r0, r0, #0xA
+ str r0, [r6, #0x1C]
+skip_gpt_workaround1:
+ .endm
+
+ .macro switch_to_400MHz
+
+ /* check if periph_clk_sel is already set */
+ ldr r0, [r6, #0x14]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ beq set_ahb_podf_before_switch1
+
+ /* Step 1: Change periph_clk to be sourced from pll3_clk. */
+ /* Ensure PLL3 is the source and set the divider to 1. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0x3000
+ str r0, [r6, #0x18]
+
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x38000000
+ str r0, [r6, #0x14]
+
+ /* Now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch5:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch5
+
+ b switch_pre_periph_clk_400
+
+set_ahb_podf_before_switch1:
+ /* Set the AHB dividers before the switch. */
+ /* Especially if the AHB is at 24MHz, divider
+ * would be at divide by 1 and clock
+ * would be too fast when switching to PLL3.
+ */
+ /* Don't change AXI clock divider. */
+ /* Set the MMDC_DIV=1, AXI_DIV = 2, AHB_DIV=4 (need to maintain GPT divider). */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0x900
+ orr r0, r0, #0x10000
+ str r0, [r6, #0x14]
+
+wait_div_update400_1:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update400_1
+
+switch_pre_periph_clk_400:
+
+ /* Now switch pre_periph_clk to PFD_400MHz. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0xC0000
+ orr r0, r0, #0x40000
+ str r0, [r6, #0x18]
+
+ /* Now switch periph_clk back. */
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch6:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch6
+
+ /* Change AHB divider so that we are at 400/3=133MHz. */
+ /* Don't change AXI clock divider. */
+ /* Set the MMDC_DIV=1, AXI_DIV=2, AHB_DIV=3 (need to maintain GPT divider). */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0x900
+ orr r0, r0, #0x10000
+ str r0, [r6, #0x14]
+
+wait_div_update400_2:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update400_2
+
+ ldr r0, =ANATOP_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r1, [r0, #0x260]
+ mov r2, r1
+ /*Is mx6q?*/
+ and r1, r1, #0xff0000
+ cmp r1, #0x630000
+ bne skip_gpt_workaround2
+ /*Is mx6q TO1.0?*/
+ and r2, r2, #0xff
+ cmp r2, #0x0
+ bne skip_gpt_workaround2
+ /* Change the GPT divider so that its at 6MHz. */
+ ldr r0, [r6, #0x1C]
+ bic r0, r0, #0x3F
+ orr r0, r0, #0xA
+ str r0, [r6, #0x1C]
+skip_gpt_workaround2:
+ .endm
+
+ .macro switch_to_50MHz
+
+ /* Set DDR to 50MHz. */
+ /* check if periph_clk_sel is already set */
+ ldr r0, [r6, #0x14]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ beq switch_pre_periph_clk_50
+
+ /* Set the periph_clk to be sourced from PLL2_PFD_200M */
+ /* Step 1: Change periph_clk to be sourced from pll3_clk. */
+ /* Ensure PLL3 is the source and set the divider to 1. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0x3000
+ str r0, [r6, #0x18]
+
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x38000000
+ str r0, [r6, #0x14]
+
+ /* Now switch periph_clk to pll3_main_clk. */
+ ldr r0, [r6, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch_50:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch_50
+
+switch_pre_periph_clk_50:
+
+ /* Now switch pre_periph_clk to PFD_200MHz. */
+ ldr r0, [r6, #0x18]
+ orr r0, r0, #0xC0000
+ str r0, [r6, #0x18]
+
+ /* Set the MMDC_DIV=4, AXI_DIV = 4, AHB_DIV=8 (need to maintain GPT divider). */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+
+ orr r0, r0, #0x180000
+ orr r0, r0, #0x30000
+
+ /* If changing AHB divider remember to change the IPGPER divider too below. */
+ orr r0, r0, #0x1d00
+ str r0, [r6, #0x14]
+
+wait_div_update_50:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update_50
+
+ /* Now switch periph_clk back. */
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch2:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch2
+
+ ldr r0, =ANATOP_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r1, [r0, #0x260]
+ mov r2, r1
+ /*Is mx6q?*/
+ and r1, r1, #0xff0000
+ cmp r1, #0x630000
+ bne skip_gpt_workaround3
+ /*Is mx6q TO1.0?*/
+ and r2, r2, #0xff
+ cmp r2, #0x0
+ bne skip_gpt_workaround3
+ /* Change the GPT divider so that its at 6MHz. */
+ ldr r0, [r6, #0x1C]
+ bic r0, r0, #0x3F
+ orr r0, r0, #0x1
+ str r0, [r6, #0x1C]
+skip_gpt_workaround3:
+
+ .endm
+
+ .macro switch_to_24MHz
+ /* Change the freq now */
+ /* Try setting DDR to 24MHz. */
+ /* Source it from the periph_clk2 */
+ /* Ensure the periph_clk2 is sourced from 24MHz
+ and the divider is 1. */
+ ldr r0, [r6, #0x18]
+ bic r0, r0, #0x3000
+ orr r0, r0, #0x1000
+ str r0, [r6, #0x18]
+
+ ldr r0, [r6, #0x14]
+ bic r0, r0, #0x38000000
+ str r0, [r6, #0x14]
+
+ /* Now switch periph_clk to 24MHz. */
+ ldr r0, [r6, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r6, #0x14]
+
+periph_clk_switch1:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch1
+
+ /* Change all the dividers to 1. */
+ ldr r0, [r6, #0x14]
+ ldr r2, =0x3f1f00
+ bic r0, r0, r2
+ orr r0, r0, #0x100
+ str r0, [r6, #0x14]
+
+ /* Wait for the divider to change. */
+wait_div_update:
+ ldr r0, [r6, #0x48]
+ cmp r0, #0
+ bne wait_div_update
+
+ ldr r0, =ANATOP_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r1, [r0, #0x260]
+ mov r2, r1
+ /*Is mx6q?*/
+ and r1, r1, #0xff0000
+ cmp r1, #0x630000
+ bne skip_gpt_workaround4
+ /*Is mx6q TO1.0?*/
+ and r2, r2, #0xff
+ cmp r2, #0x0
+ bne skip_gpt_workaround4
+ /* Change the GPT divider so that its at 6MHz. */
+ ldr r0, [r6, #0x1C]
+ bic r0, r0, #0x3F
+ orr r0, r0, #0x1
+ str r0, [r6, #0x1C]
+skip_gpt_workaround4:
+
+ .endm
+
+/*
+ * mx6_ddr_freq_change
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(mx6_ddr_freq_change)
+
+ stmfd sp!, {r4,r5,r6, r7, r8, r9, r10, r11} @ Save registers
+
+ ldr r6, =CCM_BASE_ADDR
+ add r6, r6, #PERIPBASE_VIRT
+ ldr r5, =MMDC_P0_BASE_ADDR
+ add r5, r5, #PERIPBASE_VIRT
+ ldr r7, =MX6Q_IOMUXC_BASE_ADDR
+ add r7, r7, #PERIPBASE_VIRT
+
+ mov r4, r0 @save new freq requested
+ mov r8, r1 @save the ddr settings for the new rate
+ mov r9, r2 @save the mode DDR is currently in (DLL ON/OFF)
+ mov r11, r3 @save iomux offsets
+
+ddr_freq_change:
+ /* Make sure no TLB miss will occur when the DDR is in self refresh. */
+ /* Invalidate TLB single entry to ensure that the address is not
+ * already in the TLB.
+ */
+
+ adr r10, ddr_freq_change @Address in this function.
+
+ ldr r2, [r6] @ TLB will miss,
+ @CCM address will be loaded
+ ldr r2, [r5] @ TLB will miss,
+ @MMDC address will be loaded
+ ldr r2, [r7] @ TLB will miss,
+ @IOMUX will be loaded
+
+ ldr r2, [r8] @ Get the DDR settings.
+ ldr r2, [r10] @ TLB will miss
+ ldr r2, [r11] @Get the IOMUX settings
+
+ /* Make sure all the L1 & L2 buffers are drained, as
+ * we don't want any writes to the DDR when it is
+ * in self-refresh.
+ */
+ /* Make sure the L1 buffers are drained. */
+ dsb
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Make sure the L2 buffers are drained.
+ * Sync operation on L2 drains the buffers.
+ */
+ ldr r0, =L2_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ mov r1, #0x0
+ str r1, [r0, #0x730]
+#endif
+
+ /* The second dsb might be needed to keep cache sync (device write)
+ * ordering with the memory accesses before it.
+ */
+ dsb
+ isb
+
+ /* Disable automatic power saving. */
+ ldr r0, [r5, #0x404]
+ orr r0, r0, #0x01
+ str r0, [r5, #0x404]
+
+ /* Disable MMDC power down timer. */
+ /*MMDC0_MDPDC disable power down timer */
+ ldr r0, [r5, #0x4]
+ bic r0, r0, #0xff00
+ str r0, [r5, #0x4]
+
+/* Delay for a while */
+ ldr r1, =4
+delay1:
+ ldr r2, =0
+cont1:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont1
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay1
+
+ /* set CON_REG */
+ ldr r0, =0x8000
+ str r0, [r5, #0x1C]
+poll_conreq_set_1:
+ ldr r0, [r5, #0x1C]
+ and r0, r0, #0x4000
+ cmp r0, #0x4000
+ bne poll_conreq_set_1
+
+ /*setmem /32 0x021b001c = 0x00008010 //Precharge all on cs0 */
+ /*setmem /32 0x021b001c = 0x00008018 //Precharge all on cs1 */
+ ldr r0, =0x00008010
+ str r0, [r5, #0x1C]
+ ldr r0, =0x00008018
+ str r0, [r5, #0x1C]
+
+ /* if requested frequency is greater than 300MHz go to DLL on mode */
+ ldr r1, =300000000
+ cmp r4, r1
+ bge dll_on_mode
+
+dll_off_mode:
+
+ /* if DLL is currently on, turn it off
+ cmp r9, #1
+ beq continue_dll_off_1
+
+ /* setmem /32 0x021b001c = 0x00018031 //Rtt_NOM off + set dll off, cs 0 */
+ /* setmem /32 0x021b001c = 0x00018039 //Rtt_NOM off + set dll off, cs 1 */
+ ldr r0, =0x00018031
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x00018039
+ str r0, [r5, #0x1C]
+
+ ldr r1, =10
+delay1a:
+ ldr r2, =0
+cont1a:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont1a
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay1a
+
+continue_dll_off_1:
+
+ /* set DVFS - enter self refresh mode */
+ ldr r0, [r5, #0x404]
+ orr r0, r0, #0x200000
+ str r0, [r5, #0x404]
+
+ /* de-assert con_req */
+ mov r0, #0x0
+ str r0, [r5, #0x1C]
+
+poll_dvfs_set_1:
+ ldr r0, [r5, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ bne poll_dvfs_set_1
+
+ ldr r1, =24000000
+ cmp r4, r1
+ beq switch_freq_24
+
+ switch_to_50MHz
+ b continue_dll_off_2
+
+switch_freq_24:
+ switch_to_24MHz
+
+continue_dll_off_2:
+
+ /* set SBS - block ddr accesses */
+ ldr r0, [r5, #0x410]
+ orr r0, r0, #0x100
+ str r0, [r5, #0x410]
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r0, [r5, #0x404]
+ bic r0, r0, #0x200000
+ str r0, [r5, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r0, [r5, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* if DLL was previously on, continue DLL off routine
+ cmp r9, #1
+ beq continue_dll_off_3
+
+ /* setmem /32 0x021b001c = 0x00018031 //Rtt_NOM off + set dll off, cs 0 */
+ /* setmem /32 0x021b001c = 0x00018039 //Rtt_NOM off + set dll off, cs 1 */
+ ldr r0, =0x00018031
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x00018039
+ str r0, [r5, #0x1C]
+
+ /* setmem /32 0x021b001c = 0x04208030 //write mode reg MR0: CL=6, wr=6 ,cs 0 */
+ /* setmem /32 0x021b001c = 0x04208038 //write mode reg MR0: CL=6, wr=6 ,cs 1 */
+ ldr r0, =0x08208030
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x08208038
+ str r0, [r5, #0x1C]
+
+ /* setmem /32 0x021b001c = 0x02088032 //write mode reg MR2 , CWL=6 ,cs0 */
+ /* setmem /32 0x021b001c = 0x0208803A //write mode reg MR2 , CWL=6 ,cs1 */
+ ldr r0, =0x00088032
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x0008803A
+ str r0, [r5, #0x1C]
+
+ /* double refresh ????
+ ldr r0, =0x00001800
+ str r0, [r5, #0x20]*/
+
+ /* delay for a while. */
+ ldr r1, =4
+delay_1:
+ ldr r2, =0
+cont_1:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont_1
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay_1
+
+ /* MMDC0_MDCFG0 see spread sheet for timings, CAS=6 */
+ ldr r0, [r5, #0x0C]
+ bic r0, r0, #0xf
+ orr r0, r0, #0x3
+ str r0, [r5, #0x0C]
+
+ /* MMDC0_MDCFG1 see spread sheet for timings, tCWL=6 */
+ ldr r0, [r5, #0x10]
+ bic r0, r0, #0x7
+ orr r0, r0, #0x4
+ str r0, [r5, #0x10]
+
+ /* Enable bank interleaving, Address mirror on, WALAT = 0x1, RALAT = 0x2, DDR2_EN = 0 */
+ /*setmem /32 0x021b0018 = 0x00091680 */
+ ldr r0, =0x00091680
+ str r0, [r5, #0x18]
+
+ /* enable dqs pull down in the IOMUX. */
+ /*
+ setmem /32 0x020e05a8 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - DSE=110
+ setmem /32 0x020e05b0 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 - DSE=110
+ setmem /32 0x020e0524 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 - DSE=110
+ setmem /32 0x020e051c = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 - DSE=110
+ setmem /32 0x020e0518 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 - DSE=110
+ setmem /32 0x020e050c = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 - DSE=110
+ setmem /32 0x020e05b8 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 - DSE=110
+ setmem /32 0x020e05c0 = 0x00003030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 - DSE=110
+ */
+ ldr r1, [r11] @size of array
+ add r11, r11, #8 @skip first eight bytes in array
+ ldr r2, =0x3028
+update_iomux:
+ ldr r0, [r11, #0x0] @ offset
+ ldr r3, [r7, r0]
+ bic r3, r3, r2 @ Clear the DSE, PUE and PKE bits
+ orr r3, r3, #0x3000 @ Enable the Pull downs and lower the drive strength.
+ orr r3, r3, #0x28
+ str r3, [r7, r0]
+ add r11, r11, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_iomux
+
+ /* ODT disabled */
+ /* setmem /32 0x021b0818 = 0x0 // DDR_PHY_P0_MPODTCTRL */
+ /* setmem /32 0x021b4818 = 0x0 // DDR_PHY_P1_MPODTCTRL */
+ ldr r0, =0x0
+ ldr r2, =0x818
+ str r0, [r5, r2]
+ ldr r2, =0x4818
+ str r0, [r5, r2]
+
+ /* DQS gating disabled */
+ /* setmem /32 0x021b083c = 0x233f033f */
+ ldr r2, =0x83c
+ ldr r0, [r5, r2]
+ orr r0, r0, #0x20000000
+ str r0, [r5, r2]
+
+ ldr r2, =0x483c
+ ldr r0, [r5, r2]
+ orr r0, r0, #0x20000000
+ str r0, [r5, r2]
+
+ /* MMDC0_MAPSR adopt power down enable */
+ /* setmem /32 0x021b0404 = 0x00011006 */
+ ldr r0, [r5, #0x404]
+ bic r0, r0, #0x01
+ str r0, [r5, #0x404]
+
+ /* frc_msr + mu bypass*/
+ ldr r0, =0x00000060
+ str r0, [r5, #0x8b8]
+ ldr r2, =0x48b8
+ str r0, [r5, r2]
+ ldr r0, =0x00000460
+ str r0, [r5, #0x8b8]
+ ldr r2, =0x48b8
+ str r0, [r5, r2]
+ ldr r0, =0x00000c60
+ str r0, [r5, #0x8b8]
+ ldr r2, =0x48b8
+ str r0, [r5, r2]
+
+continue_dll_off_3:
+
+ /* clear SBS - unblock accesses to DDR */
+ ldr r0, [r5, #0x410]
+ bic r0, r0, #0x100
+ str r0, [r5, #0x410]
+
+ mov r0, #0x0
+ str r0, [r5, #0x1C]
+poll_conreq_clear_1:
+ ldr r0, [r5, #0x1C]
+ and r0, r0, #0x4000
+ cmp r0, #0x4000
+ beq poll_conreq_clear_1
+
+ b done
+
+dll_on_mode:
+ /* assert DVFS - enter self refresh mode */
+ ldr r0, [r5, #0x404]
+ orr r0, r0, #0x200000
+ str r0, [r5, #0x404]
+
+ /* de-assert CON_REQ */
+ mov r0, #0x0
+ str r0, [r5, #0x1C]
+
+ /* poll DVFS ack */
+poll_dvfs_set_2:
+ ldr r0, [r5, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ bne poll_dvfs_set_2
+
+ ldr r1, =528000000
+ cmp r4, r1
+ beq switch_freq_528
+
+ switch_to_400MHz
+
+ b continue_dll_on
+
+switch_freq_528:
+ switch_to_528MHz
+
+continue_dll_on:
+
+ /* set SBS step-by-step mode */
+ ldr r0, [r5, #0x410]
+ orr r0, r0, #0x100
+ str r0, [r5, #0x410]
+
+ /* clear DVFS - exit self refresh mode */
+ ldr r0, [r5, #0x404]
+ bic r0, r0, #0x200000
+ str r0, [r5, #0x404]
+
+poll_dvfs_clear_2:
+ ldr r0, [r5, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ beq poll_dvfs_clear_2
+
+ /* if DLL is currently off, turn it back on */
+ cmp r9, #0
+ beq update_calibration_only
+
+ ldr r0, =0xa5390003
+ str r0, [r5, #0x800]
+ ldr r2, =0x4800
+ str r0, [r5, r2]
+
+ /* enable DQS gating */
+ ldr r2, =0x83c
+ ldr r0, [r5, r2]
+ bic r0, r0, #0x20000000
+ str r0, [r5, r2]
+
+ ldr r2, =0x483c
+ ldr r0, [r5, r2]
+ bic r0, r0, #0x20000000
+ str r0, [r5, r2]
+
+ /* force measure */
+ ldr r0, =0x00000800
+ str r0, [r5, #0x8b8]
+ ldr r2, =0x48b8
+ str r0, [r5, r2]
+
+ /* delay for while */
+ ldr r1, =4
+delay5:
+ ldr r2, =0
+cont5:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont5
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay5
+ /* Disable dqs pull down in the IOMUX. */
+ /*
+ setmem /32 0x020e05a8 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 - DSE=110
+ setmem /32 0x020e05b0 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 - DSE=110
+ setmem /32 0x020e0524 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 - DSE=110
+ setmem /32 0x020e051c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 - DSE=110
+ setmem /32 0x020e0518 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 - DSE=110
+ setmem /32 0x020e050c = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 - DSE=110
+ setmem /32 0x020e05b8 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 - DSE=110
+ setmem /32 0x020e05c0 = 0x00000030 // IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 - DSE=110
+ */
+ ldr r1, [r11] @size of array
+ add r11, r11, #8 @skip first eight bytes in array
+update_iomux1:
+ ldr r0, [r11, #0x0] @ offset
+ ldr r3, [r11, #0x4]
+ str r3, [r7, r0] @Store the original IOMUX value read during boot
+ add r11, r11, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_iomux1
+
+ /* config ESDCTL timings to 528MHz:
+ @// setmem /32 0x021b000c = 0x555A7975 @// MMDC0_MDCFG0 see spread sheet for timings
+ @//setmem /32 0x021b0010 = 0xFF538E64 @// MMDC0_MDCFG1 see spread sheet for timings
+ @//setmem /32 0x021b0014 = 0x01ff00db @// MMDC0_MDCFG2 - tRRD - 4ck; tWTR - 4ck; tRTP - 4ck; tDLLK - 512ck
+ @//setmem /32 0x021b0018 = 0x00081740 @// MMDC0_MDMISC, RALAT=0x5 (original value)
+ */
+ ldr r9, [r8] @size of array
+ add r8, r8, #8 @skip first eight bytes in array
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /* update MISC register: WALAT, RALAT */
+ ldr r0, =0x00081740
+ str r0, [r5, #0x18]
+
+ /*configure ddr devices to dll on, odt
+ @//setmem /32 0x021b001c = 0x00428031
+ @//setmem /32 0x021b001c = 0x00428039
+ */
+ ldr r0, =0x00028031
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x00028039
+ str r0, [r5, #0x1C]
+
+ /* delay for while */
+ ldr r1, =4
+delay7:
+ ldr r2, =0
+cont7:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont7
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay7
+
+ /* reset dll
+ @// setmem /32 0x021b001c = 0x09208030
+ @// setmem /32 0x021b001c = 0x09208038
+ */
+ ldr r0, =0x09208030
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x09208038
+ str r0, [r5, #0x1C]
+
+ /* delay for while */
+ ldr r1, =100
+delay8:
+ ldr r2, =0
+cont8:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay8
+
+ /* tcwl=6:
+ @//setmem /32 0x021b001c = 0x04088032
+ @//setmem /32 0x021b001c = 0x0408803a
+ */
+ /* MR2 - CS0 */
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /*MR2 - CS1 */
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r0, =0x00428031
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x00428039
+ str r0, [r5, #0x1C]
+
+ /* tcl=8
+ @// setmem /32 0x021b001c = 0x08408030
+ @// setmem /32 0x021b001c = 0x08408038
+ */
+ /* MR1 - CS0 */
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /*MR1 - CS1 */
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ /* issue a zq command
+ @// setmem /32 0x021b001c = 0x04000040
+ @// setmem /32 0x021b001c = 0x04000048
+ */
+ ldr r0, =0x04008040
+ str r0, [r5, #0x1C]
+
+ ldr r0, =0x04008048
+ str r0, [r5, #0x1C]
+
+ /* ESDCTL ODT enable
+ @//setmem /32 0x021b0818 = 0x00022225 @// DDR_PHY_P0_MPODTCTRL
+ @//setmem /32 0x021b4818 = 0x00022225 @// DDR_PHY_P1_MPODTCTRL
+ */
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+
+ ldr r2, =0x4818
+ str r0, [r5, r2]
+
+ /* delay for while */
+ ldr r1, =40
+delay15:
+ ldr r2, =0
+cont15:
+ ldr r0, [r5, r2]
+ add r2, r2, #4
+ cmp r2, #16
+ bne cont15
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt delay15
+
+ /* MMDC0_MAPSR adopt power down enable */
+ /* setmem /32 0x021b0404 = 0x00011006 */
+ ldr r0, [r5, #0x404]
+ bic r0, r0, #0x01
+ str r0, [r5, #0x404]
+
+ /* Enable MMDC power down timer. */
+ ldr r0, [r5, #0x4]
+ orr r0, r0, #0x5500
+ str r0, [r5, #0x4]
+
+ b update_calibration
+
+update_calibration_only:
+ ldr r1, [r8] @ size of array
+ sub r1, r1, #7 @ first 7 entries are not related to calibration
+ add r8, r8, #64 @ Skip the first 7 entries that are needed only when DLL was OFF + count entry.
+ b update_calib
+
+update_calibration:
+ /* Write the new calibration values. */
+ mov r1, r9 @ size of array
+ sub r1, r1, #7 @ first 7 entries are not related to calibration
+
+update_calib:
+ ldr r0, [r8, #0x0] @ offset
+ ldr r3, [r8, #0x4] @ value
+ str r3, [r5, r0]
+ add r8, r8, #8
+ sub r1, r1, #1
+ cmp r1, #0
+ bgt update_calib
+
+ /* Perform a force measurement. */
+ ldr r0, =0x800
+ str r0, [r5, #0x8B8]
+ ldr r2, =0x48B8
+ str r0, [r5, r2]
+
+ /* clear SBS - unblock DDR accesses */
+ ldr r0, [r5, #0x410]
+ bic r0, r0, #0x100
+ str r0, [r5, #0x410]
+
+ mov r0, #0x0
+ str r0, [r5, #0x1C]
+poll_conreq_clear_2:
+ ldr r0, [r5, #0x1C]
+ and r0, r0, #0x4000
+ cmp r0, #0x4000
+ beq poll_conreq_clear_2
+
+done:
+
+ /* Restore registers */
+
+ ldmfd sp!, {r4,r5,r6, r7, r8, r9, r10, r11}
+
+ mov pc, lr
+
+ .type mx6_do_ddr_freq_change, #object
+ENTRY(mx6_do_ddr_freq_change)
+ .word mx6_ddr_freq_change
+ .size mx6_ddr_freq_change, . - mx6_ddr_freq_change
diff --git a/arch/arm/mach-mx6/mx6_fec.c b/arch/arm/mach-mx6/mx6_fec.c
new file mode 100644
index 00000000..935ba264
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_fec.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/fec.h>
+#include <linux/etherdevice.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include "devices-imx6q.h"
+
+#define HW_OCOTP_MACn(n) (0x00000620 + (n) * 0x10)
+
+static int fec_get_mac_addr(unsigned char *mac)
+{
+ unsigned int value;
+
+ value = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_MACn(0));
+ mac[5] = value & 0xff;
+ mac[4] = (value >> 8) & 0xff;
+ mac[3] = (value >> 16) & 0xff;
+ mac[2] = (value >> 24) & 0xff;
+ value = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + HW_OCOTP_MACn(1));
+ mac[1] = value & 0xff;
+ mac[0] = (value >> 8) & 0xff;
+
+ return 0;
+}
+
+void __init imx6_init_fec(struct fec_platform_data fec_data)
+{
+ fec_get_mac_addr(fec_data.mac);
+ if (!is_valid_ether_addr(fec_data.mac))
+ random_ether_addr(fec_data.mac);
+
+ if (cpu_is_mx6sl())
+ imx6sl_add_fec(&fec_data);
+ else
+ imx6q_add_fec(&fec_data);
+}
diff --git a/arch/arm/mach-mx6/mx6_mmdc.c b/arch/arm/mach-mx6/mx6_mmdc.c
new file mode 100644
index 00000000..eca8d83c
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_mmdc.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx6_mmdc.c
+ *
+ * @brief MX6 MMDC specific file.
+ *
+ * @ingroup PM
+ */
+#include <asm/io.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/iram_alloc.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <asm/hardware/gic.h>
+#include "crm_regs.h"
+
+
+/* DDR settings */
+unsigned long (*iram_ddr_settings)[2];
+unsigned long (*normal_mmdc_settings)[2];
+unsigned long (*iram_iomux_settings)[2];
+void __iomem *mmdc_base;
+void __iomem *iomux_base;
+void __iomem *gic_dist_base;
+void __iomem *gic_cpu_base;
+
+void (*mx6_change_ddr_freq)(u32 freq, void *ddr_settings, bool dll_mode, void* iomux_offsets) = NULL;
+
+extern unsigned int ddr_low_rate;
+extern unsigned int ddr_med_rate;
+extern unsigned int ddr_normal_rate;
+extern int low_bus_freq_mode;
+extern int audio_bus_freq_mode;
+extern int mmdc_med_rate;
+extern void __iomem *ccm_base;
+extern void mx6_ddr_freq_change(u32 freq, void *ddr_settings, bool dll_mode, void *iomux_offsets);
+
+static void *ddr_freq_change_iram_base;
+static int ddr_settings_size;
+static int iomux_settings_size;
+static volatile unsigned int cpus_in_wfe;
+static volatile bool wait_for_ddr_freq_update;
+static int curr_ddr_rate;
+
+#define MIN_DLL_ON_FREQ 333000000
+#define MAX_DLL_OFF_FREQ 125000000
+
+unsigned long ddr3_dll_mx6q[][2] = {
+ {0x0c, 0x0},
+ {0x10, 0x0},
+ {0x1C, 0x04088032},
+ {0x1C, 0x0408803a},
+ {0x1C, 0x08408030},
+ {0x1C, 0x08408038},
+ {0x818, 0x0},
+};
+
+unsigned long ddr3_calibration[][2] = {
+ {0x83c, 0x0},
+ {0x840, 0x0},
+ {0x483c, 0x0},
+ {0x4840, 0x0},
+ {0x848, 0x0},
+ {0x4848, 0x0},
+ {0x850, 0x0},
+ {0x4850, 0x0},
+};
+
+unsigned long ddr3_dll_mx6dl[][2] = {
+ {0x0c, 0x0},
+ {0x10, 0x0},
+ {0x1C, 0x04008032},
+ {0x1C, 0x0400803a},
+ {0x1C, 0x07208030},
+ {0x1C, 0x07208038},
+ {0x818, 0x0},
+};
+
+unsigned long iomux_offsets_mx6q[][2] = {
+ {0x5A8, 0x0},
+ {0x5B0, 0x0},
+ {0x524, 0x0},
+ {0x51C, 0x0},
+ {0x518, 0x0},
+ {0x50C, 0x0},
+ {0x5B8, 0x0},
+ {0x5C0, 0x0},
+};
+
+unsigned long iomux_offsets_mx6dl[][2] = {
+ {0x4BC, 0x0},
+ {0x4C0, 0x0},
+ {0x4C4, 0x0},
+ {0x4C8, 0x0},
+ {0x4CC, 0x0},
+ {0x4D0, 0x0},
+ {0x4D4, 0x0},
+ {0x4D8, 0x0},
+};
+
+unsigned long ddr3_400[][2] = {
+ {0x83c, 0x42490249},
+ {0x840, 0x02470247},
+ {0x483c, 0x42570257},
+ {0x4840, 0x02400240},
+ {0x848, 0x4039363C},
+ {0x4848, 0x3A39333F},
+ {0x850, 0x38414441},
+ {0x4850, 0x472D4833}
+};
+
+unsigned long *irq_used;
+
+unsigned long irqs_used_mx6q[] = {
+ MXC_INT_INTERRUPT_139_NUM,
+ MX6Q_INT_PERFMON1,
+ MX6Q_INT_PERFMON2,
+ MX6Q_INT_PERFMON3,
+};
+
+unsigned long irqs_used_mx6dl[] = {
+ MXC_INT_INTERRUPT_139_NUM,
+ MX6Q_INT_PERFMON1,
+};
+
+int can_change_ddr_freq(void)
+{
+ return 1;
+}
+
+
+/* Each active core apart from the one changing the DDR frequency will execute
+ * this function. The rest of the cores have to remain in WFE state until the frequency
+ * is changed.
+ */
+irqreturn_t wait_in_wfe_irq(int irq, void *dev_id)
+{
+ u32 me = smp_processor_id();
+
+ *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
+
+ while (wait_for_ddr_freq_update)
+ wfe();
+
+ *((char *)(&cpus_in_wfe) + (u8)me) = 0;
+
+ return IRQ_HANDLED;
+}
+
+/* Change the DDR frequency. */
+int update_ddr_freq(int ddr_rate)
+{
+ int i, j;
+ unsigned int reg;
+ bool dll_off = false;
+ unsigned int online_cpus = 0;
+ int cpu = 0;
+ int me;
+
+ if (!can_change_ddr_freq())
+ return -1;
+
+ if (ddr_rate == curr_ddr_rate)
+ return 0;
+
+ printk(KERN_DEBUG"%s(%d) %s(%d)\n",__FILE__,__LINE__,__FUNCTION__,ddr_rate);
+
+ if (low_bus_freq_mode || audio_bus_freq_mode)
+ dll_off = true;
+
+ iram_ddr_settings[0][0] = ddr_settings_size;
+ iram_iomux_settings[0][0] = iomux_settings_size;
+ if (ddr_rate == ddr_med_rate && cpu_is_mx6q()) {
+ for (i = 0; i < ARRAY_SIZE(ddr3_dll_mx6q); i++) {
+ iram_ddr_settings[i + 1][0] =
+ normal_mmdc_settings[i][0];
+ iram_ddr_settings[i + 1][1] =
+ normal_mmdc_settings[i][1];
+ }
+ for (j = 0, i = ARRAY_SIZE(ddr3_dll_mx6q); i < iram_ddr_settings[0][0]; j++, i++) {
+ iram_ddr_settings[i + 1][0] =
+ ddr3_400[j][0];
+ iram_ddr_settings[i + 1][1] =
+ ddr3_400[j][1];
+ }
+ } else if (ddr_rate == ddr_normal_rate) {
+ for (i = 0; i < iram_ddr_settings[0][0]; i++) {
+ iram_ddr_settings[i + 1][0] =
+ normal_mmdc_settings[i][0];
+ iram_ddr_settings[i + 1][1] =
+ normal_mmdc_settings[i][1];
+ }
+ }
+
+ /* Ensure that all Cores are in WFE. */
+ local_irq_disable();
+
+ me = smp_processor_id();
+
+ *((char *)(&cpus_in_wfe) + (u8)me) = 0xff;
+ wait_for_ddr_freq_update = true;
+ for_each_online_cpu(cpu) {
+ *((char *)(&online_cpus) + (u8)cpu) = 0xff;
+ if (cpu != me) {
+ /* Set the interrupt to be pending in the GIC. */
+ reg = 1 << (irq_used[cpu] % 32);
+ writel_relaxed(reg, gic_dist_base + GIC_DIST_PENDING_SET + (irq_used[cpu] / 32) * 4);
+ }
+ }
+ while (cpus_in_wfe != online_cpus)
+ udelay(5);
+
+ /* Now we can change the DDR frequency. */
+ mx6_change_ddr_freq(ddr_rate, iram_ddr_settings, dll_off, iram_iomux_settings);
+
+ curr_ddr_rate = ddr_rate;
+
+ /* DDR frequency change is done . */
+ wait_for_ddr_freq_update = false;
+
+ /* Wake up all the cores. */
+ sev();
+
+ *((char *)(&cpus_in_wfe) + (u8)me) = 0;
+
+ local_irq_enable();
+
+ return 0;
+}
+
+int init_mmdc_settings(void)
+{
+ unsigned long iram_paddr;
+ int i, err, cpu;
+
+ mmdc_base = ioremap(MMDC_P0_BASE_ADDR, SZ_32K);
+ iomux_base = ioremap(MX6Q_IOMUXC_BASE_ADDR, SZ_16K);
+ gic_dist_base = ioremap(IC_DISTRIBUTOR_BASE_ADDR, SZ_16K);
+ gic_cpu_base = ioremap(IC_INTERFACES_BASE_ADDR, SZ_16K);
+
+ if (cpu_is_mx6q())
+ ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6q) + ARRAY_SIZE(ddr3_calibration);
+ if (cpu_is_mx6dl())
+ ddr_settings_size = ARRAY_SIZE(ddr3_dll_mx6dl) + ARRAY_SIZE(ddr3_calibration);
+
+ normal_mmdc_settings = kmalloc((ddr_settings_size * 8), GFP_KERNEL);
+ if (cpu_is_mx6q()) {
+ memcpy(normal_mmdc_settings, ddr3_dll_mx6q, sizeof(ddr3_dll_mx6q));
+ memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6q)), ddr3_calibration, sizeof(ddr3_calibration));
+ }
+ if (cpu_is_mx6dl()) {
+ memcpy(normal_mmdc_settings, ddr3_dll_mx6dl, sizeof(ddr3_dll_mx6dl));
+ memcpy(((char *)normal_mmdc_settings + sizeof(ddr3_dll_mx6dl)), ddr3_calibration, sizeof(ddr3_calibration));
+ }
+
+ /* Store the original DDR settings at boot. */
+ for (i = 0; i < ddr_settings_size; i++) {
+ /*Writes via command mode register cannot be read back.
+ * Hence hardcode them in the initial static array.
+ * This may require modification on a per customer basis.
+ */
+ if (normal_mmdc_settings[i][0] != 0x1C)
+ normal_mmdc_settings[i][1] =
+ __raw_readl(mmdc_base
+ + normal_mmdc_settings[i][0]);
+ }
+
+ /* Store the size of the array in iRAM also,
+ * increase the size by 8 bytes.
+ */
+ iram_ddr_settings = iram_alloc((ddr_settings_size * 8) + 8, &iram_paddr);
+ if (iram_ddr_settings == NULL) {
+ printk(KERN_DEBUG
+ "%s: failed to allocate iRAM memory for ddr settings\n",
+ __func__);
+ return ENOMEM;
+ }
+
+ iomux_settings_size = ARRAY_SIZE(iomux_offsets_mx6q);
+ /* Store the size of the iomux settings in iRAM also,
+ * increase the size by 8 bytes.
+ */
+ iram_iomux_settings = iram_alloc((iomux_settings_size * 8) + 8, &iram_paddr);
+ if (iram_iomux_settings == NULL) {
+ printk(KERN_DEBUG
+ "%s: failed to allocate iRAM memory for iomuxr settings\n",
+ __func__);
+ return ENOMEM;
+ }
+
+ /* Store the IOMUX settings at boot. */
+ if (cpu_is_mx6q()) {
+ for (i = 0; i < iomux_settings_size; i++) {
+ iomux_offsets_mx6q[i][1] =
+ __raw_readl(iomux_base
+ + iomux_offsets_mx6q[i][0]);
+ iram_iomux_settings[i+1][0] = iomux_offsets_mx6q[i][0];
+ iram_iomux_settings[i+1][1] = iomux_offsets_mx6q[i][1];
+ }
+ irq_used = irqs_used_mx6q;
+ }
+
+ if (cpu_is_mx6dl()) {
+ for (i = 0; i < iomux_settings_size; i++) {
+ iomux_offsets_mx6dl[i][1] =
+ __raw_readl(iomux_base
+ + iomux_offsets_mx6dl[i][0]);
+ iram_iomux_settings[i+1][0] = iomux_offsets_mx6dl[i][0];
+ iram_iomux_settings[i+1][1] = iomux_offsets_mx6dl[i][1];
+ }
+ irq_used = irqs_used_mx6dl;
+ }
+
+ /* Allocate IRAM for the DDR freq change code. */
+ iram_alloc(SZ_8K, &iram_paddr);
+ /* Need to remap the area here since we want the memory region
+ to be executable. */
+ ddr_freq_change_iram_base = __arm_ioremap(iram_paddr,
+ SZ_8K, MT_MEMORY_NONCACHED);
+ memcpy(ddr_freq_change_iram_base, mx6_ddr_freq_change, SZ_8K);
+ mx6_change_ddr_freq = (void *)ddr_freq_change_iram_base;
+
+ curr_ddr_rate = ddr_normal_rate;
+
+ for_each_online_cpu(cpu) {
+ /* Set up a reserved interrupt to get all the active cores into a WFE state
+ * before changing the DDR frequency.
+ */
+ err = request_irq(irq_used[cpu], wait_in_wfe_irq, IRQF_PERCPU, "mmdc_1",
+ NULL);
+ if (err) {
+ printk(KERN_ERR "MMDC: Unable to attach to %ld,err = %d\n", irq_used[cpu], err);
+ return err;
+ }
+ err = irq_set_affinity(irq_used[cpu], cpumask_of(cpu));
+ if (err) {
+ printk(KERN_ERR "MMDC: unable to set irq affinity irq=%ld,\n", irq_used[cpu]);
+ return err;
+ }
+ }
+ return 0;
+}
diff --git a/arch/arm/mach-mx6/mx6_suspend.S b/arch/arm/mach-mx6/mx6_suspend.S
new file mode 100644
index 00000000..30388ead
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_suspend.S
@@ -0,0 +1,1713 @@
+/*
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+#include <asm/memory.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "src-reg.h"
+
+#define ARM_CTRL_DCACHE (1 << 2)
+#define ARM_CTRL_ICACHE (1 << 12)
+#define ARM_AUXCR_L2EN (1 << 1)
+#define TTRBIT_MASK 0xffffc000
+#define TABLE_INDEX_MASK 0xfff00000
+#define TABLE_ENTRY 0x00000c02
+#define CACHE_DISABLE_MASK 0xfffffffb
+#define MMDC_MAPSR_OFFSET 0x404
+#define MMDC_MAPSR_PSS (1 << 4)
+#define MMDC_MAPSR_PSD (1 << 0)
+/*
+ * The code size is limited to 5K, as we may need to store
+ * this code * along with the low power WFI and DDR freq
+ * change code within 8K of IRAM.
+ */
+#define IRAM_SUSPEND_SIZE MX6_SUSPEND_CODE_SIZE
+
+.extern iram_tlb_phys_addr
+.extern suspend_iram_base
+.extern suspend_iram_phys_addr
+
+/*************************************************************
+mx6_suspend:
+
+Suspend the processor (eg, wait for interrupt).
+Set the DDR into Self Refresh
+IRQs are already disabled.
+
+The following code contain both standby and
+dormant mode for MX6, decided by the parameter
+passed in r0:
+see define in include/linux/suspend.h
+1 -> cpu enter stop mode;
+3 -> cpu enter dormant mode.
+r1: iram_paddr
+r2: suspend_iram_base
+*************************************************************/
+ .macro mx6sl_standy_saving_set
+
+ /* Move periph_clk to OSC_CLK. */
+ ldr r1, =CCM_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Ensure the periph_clk2_sel to OSC clk. */
+ ldr r0, [r1, #0x18]
+ bic r0, r0, #0x3000
+ orr r0, r0, #0x1000
+ str r0, [r1, #0x18]
+
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x2000000
+ str r0, [r1, #0x14]
+
+periph_clk_switch:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne periph_clk_switch
+
+ /* Set the divider to divider by 8 */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x70000
+ orr r0, r0, #0x1c00
+ str r0, [r1, #0x14]
+
+ahb_podf:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne ahb_podf
+
+ /* Move DDR clk to PLL3 clock.
+ */
+ /* First set the divider to 2. */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x1
+ str r0, [r1, #0x14]
+
+ ldr r0, [r1, #0x18]
+ bic r0, r0, #0x100000
+ str r0, [r1, #0x18]
+
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x4000000
+ str r0, [r1, #0x14]
+
+ddr_switch:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne ddr_switch
+
+ /* Set DDR clock to divide by 8. */
+ ldr r0, [r1, #0x14]
+ orr r0, r0, #0x38
+ str r0, [r1, #0x14]
+
+mmdc_div:
+ ldr r0, [r1, #0x48]
+ cmp r0, #0
+ bne mmdc_div
+
+ /* Now Switch ARM to run from
+ * step_clk sourced from OSC.
+ */
+ ldr r0, [r1, #0xc]
+ bic r0, r1, #0x100
+ str r0, [r1, #0x0c]
+
+ /* Now switch PLL1_SW_CLK to step_clk. */
+ ldr r0, [r1, #0x0c]
+ orr r0, r0, #0x4
+ str r0, [r1, #0x0c]
+
+ ldr r1, =ANATOP_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Need to clock gate the 528 PFDs before
+ * powering down PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC/AHB
+ */
+ ldr r0, [r1, #0x100]
+ orr r0, r0, #0x800000
+ str r0, [r1, #0x100]
+
+ /* Now bypass PLL1 and PLL2. */
+ ldr r0, =0x10000
+ str r0, [r1, #0x4]
+ str r0, [r1, #0x34]
+
+ /* Now do all the analog savings. */
+
+ /* Disable 1p1 brown out. */
+ ldr r0, [r1, #0x110]
+ bic r0, r0, #0x2
+ str r0, [r1, #0x110]
+
+ /* Enable the weak 2P5 */
+ ldr r0, [r1, #0x130]
+ orr r0, r0, #0x40000
+ str r0, [r1, #0x130]
+
+ /*Disable main 2p5. */
+ ldr r0, [r1, #0x130]
+ bic r0, r0, #0x1
+ str r0, [r1, #0x130]
+
+
+ /* Set the OSC bias current to -37.5%
+ * to drop the power on VDDHIGH.
+ */
+ ldr r0, [r1, #0x150]
+ orr r0, r0, #0xC000
+ str r0, [r1, #0x150]
+ .endm
+
+ .macro mx6sl_standby_savings_restore
+
+ /* Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r1, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r1, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r1, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r1, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5:
+ ldr r6, [r1, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r1, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r1, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r1, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r1, #0x110]
+
+ /* Unbypass PLLs and
+ * wait for relock.
+ */
+ ldr r6, =(1 << 16)
+ str r6, [r1, #0x08]
+ str r6, [r1, #0x38]
+
+wait_for_pll_lock:
+ ldr r6, [r1, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+wait_for_pll2_lock:
+ ldr r6, [r1, #0x30]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll2_lock
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r3, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r3, #0xc]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r1, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r1, #0x100]
+
+ /* Move periph_clk back
+ * to PLL2_PFD2_400.
+ */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x2000000
+ str r6, [r3, #0x14]
+
+periph_clk_switch1:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne periph_clk_switch1
+
+ /* Set the dividers to default value. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x70000
+ bic r6, r6, #0x1c00
+ orr r6, r6, #0x10800
+ str r6, [r3, #0x14]
+
+ahb_podf1:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne ahb_podf1
+
+ /* Move MMDC back to PLL2_PFD2_400 */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r3, #0x14]
+
+mmdc_loop2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_loop2
+
+ /* Set DDR clock to divide by 1. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r3, #0x14]
+
+mmdc_div1:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_div1
+
+ .endm
+
+ .macro mx6sl_standby_pg_savings_restore
+
+ /* Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r1, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r1, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r1, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r1, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5_1:
+ ldr r6, [r1, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5_1
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r1, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r1, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r1, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r1, #0x110]
+
+ /* Unbypass PLLs and
+ * wait for relock.
+ */
+ ldr r6, =(1 << 16)
+ str r6, [r1, #0x08]
+ str r6, [r1, #0x38]
+
+wait_for_pll_lock1:
+ ldr r6, [r1, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock1
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r3, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r3, #0xc]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r1, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r1, #0x100]
+
+ /* Move DDR clock back to PLL2_PFD2_400 */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r3, #0x14]
+
+mmdc_loop3:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_loop3
+
+ /* Set DDR clock to divide by 1. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r3, #0x14]
+
+mmdc_div2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne mmdc_div2
+
+ /* Move periph_clk back
+ * to PLL2_PFD2_400.
+ */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x2000000
+ str r6, [r3, #0x14]
+
+periph_clk_switch2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne periph_clk_switch2
+
+ /* Set the dividers to default value. */
+ ldr r6, [r3, #0x14]
+ bic r6, r6, #0x70000
+ bic r6, r6, #0x1c00
+ orr r6, r6, #0x10800
+ str r6, [r3, #0x14]
+
+ahb_podf2:
+ ldr r6, [r3, #0x48]
+ cmp r6, #0
+ bne ahb_podf2
+
+ .endm
+
+ .macro sl_ddr_io_save
+
+ ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
+ ldr r5, [r1, #0x310] /* DRAM_DQM1 */
+ ldr r6, [r1, #0x314] /* DRAM_DQM2 */
+ ldr r7, [r1, #0x318] /* DRAM_DQM3 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x5c4] /* GPR_B0DS */
+ ldr r5, [r1, #0x5cc] /* GPR_B1DS */
+ ldr r6, [r1, #0x5d4] /* GPR_B2DS */
+ ldr r7, [r1, #0x5d8] /* GPR_B3DS */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x300] /* DRAM_CAS */
+ ldr r5, [r1, #0x31c] /* DRAM_RAS */
+ ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ ldr r5, [r1, #0x5c0] /* DDRMODE */
+ ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
+ ldr r7, [r1, #0x340] /* DRAM_SODT1*/
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ ldr r6, [r1, #0x320] /* DRAM_RESET */
+ stmfd r0!, {r4-r6}
+
+ .endm
+
+ .macro sl_ddr_io_restore
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x30c] /* DRAM_DQM0 */
+ str r5, [r1, #0x310] /* DRAM_DQM1 */
+ str r6, [r1, #0x314] /* DRAM_DQM2 */
+ str r7, [r1, #0x318] /* DRAM_DQM3 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x5c4] /* GPR_B0DS */
+ str r5, [r1, #0x5cc] /* GPR_B1DS */
+ str r6, [r1, #0x5d4] /* GPR_B2DS */
+ str r7, [r1, #0x5d8] /* GPR_B3DS */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x300] /* DRAM_CAS */
+ str r5, [r1, #0x31c] /* DRAM_RAS */
+ str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r7, [r1, #0x5ac] /* GPR_ADDS*/
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r5, [r1, #0x5c0] /* DDRMODE */
+ str r6, [r1, #0x33c] /* DRAM_SODT0*/
+ str r7, [r1, #0x340] /* DRAM_SODT1*/
+
+ ldmea r0!, {r4-r6}
+ str r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ str r6, [r1, #0x320] /* DRAM_RESET */
+
+ .endm
+
+ .macro sl_ddr_io_set_lpm
+
+ mov r0, #0
+ str r0, [r1, #0x30c] /* DRAM_DQM0 */
+ str r0, [r1, #0x310] /* DRAM_DQM1 */
+ str r0, [r1, #0x314] /* DRAM_DQM2 */
+ str r0, [r1, #0x318] /* DRAM_DQM3 */
+
+ str r0, [r1, #0x5c4] /* GPR_B0DS */
+ str r0, [r1, #0x5cc] /* GPR_B1DS */
+ str r0, [r1, #0x5d4] /* GPR_B2DS */
+ str r0, [r1, #0x5d8] /* GPR_B3DS */
+
+ str r0, [r1, #0x300] /* DRAM_CAS */
+ str r0, [r1, #0x31c] /* DRAM_RAS */
+ str r0, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r0, [r1, #0x5ac] /* GPR_ADDS*/
+
+ str r0, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r0, [r1, #0x5c0] /* DDRMODE */
+ str r0, [r1, #0x33c] /* DRAM_SODT0*/
+ str r0, [r1, #0x340] /* DRAM_SODT1*/
+
+ mov r0, #0x80000
+ str r0, [r1, #0x320] /* DRAM_RESET */
+ mov r0, #0x1000
+ str r0, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r0, [r1, #0x334] /* DRAM_SDCKE1 */
+
+ .endm
+
+ .macro dl_ddr_io_save
+
+ ldr r4, [r1, #0x470] /* DRAM_DQM0 */
+ ldr r5, [r1, #0x474] /* DRAM_DQM1 */
+ ldr r6, [r1, #0x478] /* DRAM_DQM2 */
+ ldr r7, [r1, #0x47c] /* DRAM_DQM3 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x480] /* DRAM_DQM4 */
+ ldr r5, [r1, #0x484] /* DRAM_DQM5 */
+ ldr r6, [r1, #0x488] /* DRAM_DQM6 */
+ ldr r7, [r1, #0x48c] /* DRAM_DQM7 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x464] /* DRAM_CAS */
+ ldr r5, [r1, #0x490] /* DRAM_RAS */
+ ldr r6, [r1, #0x4ac] /* DRAM_SDCLK_0 */
+ ldr r7, [r1, #0x4b0] /* DRAM_SDCLK_1 */
+ stmfd r0!, {r4-r7}
+
+ ldr r5, [r1, #0x750] /* DDRMODE_CTL */
+ ldr r6, [r1, #0x760] /* DDRMODE */
+ stmfd r0!, {r5-r6}
+
+ ldr r4, [r1, #0x4bc] /* DRAM_SDQS0 */
+ ldr r5, [r1, #0x4c0] /* DRAM_SDQS1 */
+ ldr r6, [r1, #0x4c4] /* DRAM_SDQS2 */
+ ldr r7, [r1, #0x4c8] /* DRAM_SDQS3 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x4cc] /* DRAM_SDQS4 */
+ ldr r5, [r1, #0x4d0] /* DRAM_SDQS5 */
+ ldr r6, [r1, #0x4d4] /* DRAM_SDQS6 */
+ ldr r7, [r1, #0x4d8] /* DRAM_SDQS7 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x764] /* GPR_B0DS */
+ ldr r5, [r1, #0x770] /* GPR_B1DS */
+ ldr r6, [r1, #0x778] /* GPR_B2DS */
+ ldr r7, [r1, #0x77c] /* GPR_B3DS */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x780] /* GPR_B4DS */
+ ldr r5, [r1, #0x784] /* GPR_B5DS */
+ ldr r6, [r1, #0x78c] /* GPR_B6DS */
+ ldr r7, [r1, #0x748] /* GPR_B7DS */
+ stmfd r0!, {r4-r7}
+
+ ldr r5, [r1, #0x74c] /* GPR_ADDS*/
+ ldr r6, [r1, #0x4b4] /* DRAM_SODT0*/
+ ldr r7, [r1, #0x4b8] /* DRAM_SODT1*/
+ stmfd r0!, {r5-r7}
+
+ .endm
+
+ .macro dl_ddr_io_restore
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x470] /* DRAM_DQM0 */
+ str r5, [r1, #0x474] /* DRAM_DQM1 */
+ str r6, [r1, #0x478] /* DRAM_DQM2 */
+ str r7, [r1, #0x47c] /* DRAM_DQM3 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x480] /* DRAM_DQM4 */
+ str r5, [r1, #0x484] /* DRAM_DQM5 */
+ str r6, [r1, #0x488] /* DRAM_DQM6 */
+ str r7, [r1, #0x48c] /* DRAM_DQM7 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x464] /* DRAM_CAS */
+ str r5, [r1, #0x490] /* DRAM_RAS */
+ str r6, [r1, #0x4ac] /* DRAM_SDCLK_0 */
+ str r7, [r1, #0x4b0] /* DRAM_SDCLK_1 */
+
+ ldmea r0!, {r5-r6}
+ str r5, [r1, #0x750] /* DDRMODE_CTL */
+ str r6, [r1, #0x760] /* DDRMODE */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x4bc] /* DRAM_SDQS0 */
+ str r5, [r1, #0x4c0] /* DRAM_SDQS1 */
+ str r6, [r1, #0x4c4] /* DRAM_SDQS2 */
+ str r7, [r1, #0x4c8] /* DRAM_SDQS3 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x4cc] /* DRAM_SDQS4 */
+ str r5, [r1, #0x4d0] /* DRAM_SDQS5 */
+ str r6, [r1, #0x4d4] /* DRAM_SDQS6 */
+ str r7, [r1, #0x4d8] /* DRAM_SDQS7 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x764] /* GPR_B0DS */
+ str r5, [r1, #0x770] /* GPR_B1DS */
+ str r6, [r1, #0x778] /* GPR_B2DS */
+ str r7, [r1, #0x77c] /* GPR_B3DS */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x780] /* GPR_B4DS */
+ str r5, [r1, #0x784] /* GPR_B5DS */
+ str r6, [r1, #0x78c] /* GPR_B6DS */
+ str r7, [r1, #0x748] /* GPR_B7DS */
+
+ ldmea r0!, {r5-r7}
+ str r5, [r1, #0x74c] /* GPR_ADDS*/
+ str r6, [r1, #0x4b4] /* DRAM_SODT0*/
+ str r7, [r1, #0x4b8] /* DRAM_SODT1*/
+
+ .endm
+
+ .macro dl_ddr_io_set_lpm
+
+ mov r0, #0
+ str r0, [r1, #0x470] /* DRAM_DQM0 */
+ str r0, [r1, #0x474] /* DRAM_DQM1 */
+ str r0, [r1, #0x478] /* DRAM_DQM2 */
+ str r0, [r1, #0x47c] /* DRAM_DQM3 */
+
+ str r0, [r1, #0x480] /* DRAM_DQM4 */
+ str r0, [r1, #0x484] /* DRAM_DQM5 */
+ str r0, [r1, #0x488] /* DRAM_DQM6 */
+ str r0, [r1, #0x48c] /* DRAM_DQM7 */
+
+ str r0, [r1, #0x464] /* DRAM_CAS */
+ str r0, [r1, #0x490] /* DRAM_RAS */
+ str r0, [r1, #0x4ac] /* DRAM_SDCLK_0 */
+ str r0, [r1, #0x4b0] /* DRAM_SDCLK_1 */
+
+ str r0, [r1, #0x750] /* DDRMODE_CTL */
+ str r0, [r1, #0x760] /* DDRMODE */
+
+ str r0, [r1, #0x4bc] /* DRAM_SDQS0 */
+ str r0, [r1, #0x4c0] /* DRAM_SDQS1 */
+ str r0, [r1, #0x4c4] /* DRAM_SDQS2 */
+ str r0, [r1, #0x4c8] /* DRAM_SDQS3 */
+
+ str r0, [r1, #0x4cc] /* DRAM_SDQS4 */
+ str r0, [r1, #0x4d0] /* DRAM_SDQS5 */
+ str r0, [r1, #0x4d4] /* DRAM_SDQS6 */
+ str r0, [r1, #0x4d8] /* DRAM_SDQS7 */
+
+ str r0, [r1, #0x764] /* GPR_B0DS */
+ str r0, [r1, #0x770] /* GPR_B1DS */
+ str r0, [r1, #0x778] /* GPR_B2DS */
+ str r0, [r1, #0x77c] /* GPR_B3DS */
+
+ str r0, [r1, #0x780] /* GPR_B4DS */
+ str r0, [r1, #0x784] /* GPR_B5DS */
+ str r0, [r1, #0x78c] /* GPR_B6DS */
+ str r0, [r1, #0x748] /* GPR_B7DS */
+
+ str r0, [r1, #0x74c] /* GPR_ADDS*/
+ str r0, [r1, #0x4b4] /* DRAM_SODT0*/
+ str r0, [r1, #0x4b8] /* DRAM_SODT1*/
+
+ .endm
+
+ .macro dq_ddr_io_save
+
+ ldr r4, [r1, #0x5ac] /* DRAM_DQM0 */
+ ldr r5, [r1, #0x5b4] /* DRAM_DQM1 */
+ ldr r6, [r1, #0x528] /* DRAM_DQM2 */
+ ldr r7, [r1, #0x520] /* DRAM_DQM3 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x514] /* DRAM_DQM4 */
+ ldr r5, [r1, #0x510] /* DRAM_DQM5 */
+ ldr r6, [r1, #0x5bc] /* DRAM_DQM6 */
+ ldr r7, [r1, #0x5c4] /* DRAM_DQM7 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x56c] /* DRAM_CAS */
+ ldr r5, [r1, #0x578] /* DRAM_RAS */
+ ldr r6, [r1, #0x588] /* DRAM_SDCLK_0 */
+ ldr r7, [r1, #0x594] /* DRAM_SDCLK_1 */
+ stmfd r0!, {r4-r7}
+
+ ldr r5, [r1, #0x750] /* DDRMODE_CTL */
+ ldr r6, [r1, #0x774] /* DDRMODE */
+ stmfd r0!, {r5-r6}
+
+ ldr r4, [r1, #0x5a8] /* DRAM_SDQS0 */
+ ldr r5, [r1, #0x5b0] /* DRAM_SDQS1 */
+ ldr r6, [r1, #0x524] /* DRAM_SDQS2 */
+ ldr r7, [r1, #0x51c] /* DRAM_SDQS3 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x518] /* DRAM_SDQS4 */
+ ldr r5, [r1, #0x50c] /* DRAM_SDQS5 */
+ ldr r6, [r1, #0x5b8] /* DRAM_SDQS6 */
+ ldr r7, [r1, #0x5c0] /* DRAM_SDQS7 */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x784] /* GPR_B0DS */
+ ldr r5, [r1, #0x788] /* GPR_B1DS */
+ ldr r6, [r1, #0x794] /* GPR_B2DS */
+ ldr r7, [r1, #0x79c] /* GPR_B3DS */
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #0x7a0] /* GPR_B4DS */
+ ldr r5, [r1, #0x7a4] /* GPR_B5DS */
+ ldr r6, [r1, #0x7a8] /* GPR_B6DS */
+ ldr r7, [r1, #0x748] /* GPR_B7DS */
+ stmfd r0!, {r4-r7}
+
+ ldr r5, [r1, #0x74c] /* GPR_ADDS*/
+ ldr r6, [r1, #0x59c] /* DRAM_SODT0*/
+ ldr r7, [r1, #0x5a0] /* DRAM_SODT1*/
+ stmfd r0!, {r5-r7}
+
+ .endm
+
+ .macro dq_ddr_io_restore
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x5ac] /* DRAM_DQM0 */
+ str r5, [r1, #0x5b4] /* DRAM_DQM1 */
+ str r6, [r1, #0x528] /* DRAM_DQM2 */
+ str r7, [r1, #0x520] /* DRAM_DQM3 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x514] /* DRAM_DQM4 */
+ str r5, [r1, #0x510] /* DRAM_DQM5 */
+ str r6, [r1, #0x5bc] /* DRAM_DQM6 */
+ str r7, [r1, #0x5c4] /* DRAM_DQM7 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x56c] /* DRAM_CAS */
+ str r5, [r1, #0x578] /* DRAM_RAS */
+ str r6, [r1, #0x588] /* DRAM_SDCLK_0 */
+ str r7, [r1, #0x594] /* DRAM_SDCLK_1 */
+
+ ldmea r0!, {r5-r6}
+ str r5, [r1, #0x750] /* DDRMODE_CTL */
+ str r6, [r1, #0x774] /* DDRMODE */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x5a8] /* DRAM_SDQS0 */
+ str r5, [r1, #0x5b0] /* DRAM_SDQS1 */
+ str r6, [r1, #0x524] /* DRAM_SDQS2 */
+ str r7, [r1, #0x51c] /* DRAM_SDQS3 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x518] /* DRAM_SDQS4 */
+ str r5, [r1, #0x50c] /* DRAM_SDQS5 */
+ str r6, [r1, #0x5b8] /* DRAM_SDQS6 */
+ str r7, [r1, #0x5c0] /* DRAM_SDQS7 */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x784] /* GPR_B0DS */
+ str r5, [r1, #0x788] /* GPR_B1DS */
+ str r6, [r1, #0x794] /* GPR_B2DS */
+ str r7, [r1, #0x79c] /* GPR_B3DS */
+
+ ldmea r0!, {r4-r7}
+ str r4, [r1, #0x7a0] /* GPR_B4DS */
+ str r5, [r1, #0x7a4] /* GPR_B5DS */
+ str r6, [r1, #0x7a8] /* GPR_B6DS */
+ str r7, [r1, #0x748] /* GPR_B7DS */
+
+ ldmea r0!, {r5-r7}
+ str r5, [r1, #0x74c] /* GPR_ADDS*/
+ str r6, [r1, #0x59c] /* DRAM_SODT0*/
+ str r7, [r1, #0x5a0] /* DRAM_SODT1*/
+
+ .endm
+
+ .macro dq_ddr_io_set_lpm
+
+ mov r0, #0
+ str r0, [r1, #0x5ac] /* DRAM_DQM0 */
+ str r0, [r1, #0x5b4] /* DRAM_DQM1 */
+ str r0, [r1, #0x528] /* DRAM_DQM2 */
+ str r0, [r1, #0x520] /* DRAM_DQM3 */
+
+ str r0, [r1, #0x514] /* DRAM_DQM4 */
+ str r0, [r1, #0x510] /* DRAM_DQM5 */
+ str r0, [r1, #0x5bc] /* DRAM_DQM6 */
+ str r0, [r1, #0x5c4] /* DRAM_DQM7 */
+
+ str r0, [r1, #0x56c] /* DRAM_CAS */
+ str r0, [r1, #0x578] /* DRAM_RAS */
+ str r0, [r1, #0x588] /* DRAM_SDCLK_0 */
+ str r0, [r1, #0x594] /* DRAM_SDCLK_1 */
+
+ str r0, [r1, #0x750] /* DDRMODE_CTL */
+ str r0, [r1, #0x774] /* DDRMODE */
+
+ str r0, [r1, #0x5a8] /* DRAM_SDQS0 */
+ str r0, [r1, #0x5b0] /* DRAM_SDQS1 */
+ str r0, [r1, #0x524] /* DRAM_SDQS2 */
+ str r0, [r1, #0x51c] /* DRAM_SDQS3 */
+
+ str r0, [r1, #0x518] /* DRAM_SDQS4 */
+ str r0, [r1, #0x50c] /* DRAM_SDQS5 */
+ str r0, [r1, #0x5b8] /* DRAM_SDQS6 */
+ str r0, [r1, #0x5c0] /* DRAM_SDQS7 */
+
+ str r0, [r1, #0x784] /* GPR_B0DS */
+ str r0, [r1, #0x788] /* GPR_B1DS */
+ str r0, [r1, #0x794] /* GPR_B2DS */
+ str r0, [r1, #0x79c] /* GPR_B3DS */
+
+ str r0, [r1, #0x7a0] /* GPR_B4DS */
+ str r0, [r1, #0x7a4] /* GPR_B5DS */
+ str r0, [r1, #0x7a8] /* GPR_B6DS */
+ str r0, [r1, #0x748] /* GPR_B7DS */
+
+ str r0, [r1, #0x74c] /* GPR_ADDS*/
+ str r0, [r1, #0x59c] /* DRAM_SODT0*/
+ str r0, [r1, #0x5a0] /* DRAM_SODT1*/
+
+ .endm
+
+/******************************************************************
+Invalidate l1 dcache, r0-r4, r6, r7 used
+******************************************************************/
+ .macro invalidate_l1_dcache
+
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1:
+ sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2:
+ subs r3, r3, #1 @ Temp--
+ mov r7, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r7, r7, r6
+ mcr p15, 0, r7, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+
+ .endm
+
+/******************************************************************
+Flush and disable L1 dcache
+******************************************************************/
+ .macro flush_disable_l1_dcache
+
+ /*
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ push {r0-r12, lr}
+ ldr r0, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r0
+ pop {r0-r12, lr}
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
+ */
+ push {r0-r12, lr}
+ ldr r0, =v7_flush_dcache_all
+ mov lr, pc
+ mov pc, r0
+ pop {r0-r12, lr}
+
+ /*
+ * Execute an ISB instruction to ensure that all of the
+ * CP15 register changes have been committed.
+ */
+ isb
+
+ /*
+ * Execute a barrier instruction to ensure that all cache,
+ * TLB and branch predictor maintenance operations issued
+ * by any CPU in the cluster have completed.
+ */
+ dsb
+ dmb
+
+ .endm
+
+/******************************************************************
+Clean L2 cache
+******************************************************************/
+ .macro clean_l2_cache
+ /* Clean L2 cache to write the dirty data into DRAM to make
+ sure the data alignment between DRAM and L2 cache.
+ */
+#ifdef CONFIG_CACHE_L2X0
+ /* Clean L2 cache here */
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ /* Make way to 0xFFFF 16 ways */
+ mov r0, #0x10000
+ sub r0, r0, #0x1
+ /* 0x7BC is L2X0_CLEAN_WAY */
+ mov r4, #0x700
+ orr r4, #0xBC
+ str r0, [r1, r4]
+3:
+ ldr r5, [r1, r4]
+ ands r5, r5, r0
+ bne 3b
+4:
+ mov r5, #0x0
+ /* 0x730 is L2X0_CACHE_SYNC */
+ mov r4, #0x700
+ orr r4, #0x30
+ str r5, [r1, r4]
+5:
+ ldr r5, [r1, r4]
+ ands r5, r5, #0x1
+ bne 5b
+#endif
+ .endm
+
+ .align 3
+ENTRY(mx6_suspend)
+ stmfd sp!, {r0-r12} @ Save registers
+/*************************************************************
+suspend mode entry
+*************************************************************/
+ mov r12, r3 /* Save CPU type to r12*/
+ mov r11, r0 /* Save the state in r11 */
+
+ cmp r12, #MXC_CPU_MX6SL
+ beq dormant
+
+ cmp r0, #0x1
+ bne dormant /* dormant mode */
+
+ /* Need to flush and disable L1 dcache*/
+ flush_disable_l1_dcache
+
+ /* Need to clean L2 dcache*/
+ clean_l2_cache
+
+ /* Disable L2 cache */
+#ifdef CONFIG_CACHE_L2X0
+ ldr r2, =L2_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+ mov r4, #0x0
+ str r4, [r2, #L2X0_CTRL]
+#endif
+
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+
+ /* Invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0 @ Invalidate I-Cache
+
+ /* Need to invalidate L1 dcache, as the power is dropped */
+ invalidate_l1_dcache
+
+ /* Enable L1 dcache first */
+ mrc p15, 0, r0, c1, c0, 0
+ orr r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+
+ /* Enable L2 cache here */
+#ifdef CONFIG_CACHE_L2X0
+ ldr r2, =L2_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+ mov r4, #0x1
+ str r4, [r2, #L2X0_CTRL]
+#endif
+
+/***********************************************************
+never run to here
+************************************************************/
+ b out /* exit standby */
+ /* Place the literal pool here so that
+ * literals are within 4KB range
+ */
+ .ltorg
+/************************************************************
+dormant entry, data save in stack, save sp in the src_gpr2
+************************************************************/
+dormant:
+ mov r3, r1
+ mov r0, r1
+ add r0, r0, #IRAM_SUSPEND_SIZE /* 8K */
+ ldr r4, =SRC_BASE_ADDR
+ add r4, r4, #PERIPBASE_VIRT
+ str r0, [r4, #SRC_GPR2_OFFSET] /* set src_gpr2 */
+/************************************************************
+saved register and context as below:
+ ddr_iomux set
+ sp
+ spsr
+ lr
+ CPACR
+ TTBR0
+ TTBR1
+ TTBCR
+ DACR
+ PRRR
+ NMRR
+ ACTLR
+ Context ID
+ User r/w thread ID
+ Secure or NS VBAR
+ CPSR
+ SCTLR
+************************************************************/
+ /* save mmdc iomux setting, stack is from the tail of
+ iram_suspend base */
+
+ mov r0, r2 /* get suspend_iram_base */
+ add r0, r0, #IRAM_SUSPEND_SIZE /* 5K */
+
+ mov r4, r12 @ Store cpu type
+ stmfd r0!, {r4}
+ mov r4, r11 @ Store state entered
+ stmfd r0!, {r4}
+
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ cmp r12, #MXC_CPU_MX6Q
+ bne dl_io_save
+ dq_ddr_io_save
+ b ddr_io_save_done
+dl_io_save:
+ cmp r12, #MXC_CPU_MX6DL
+ bne sl_io_save
+ dl_ddr_io_save
+ b ddr_io_save_done
+sl_io_save:
+ sl_ddr_io_save
+
+ddr_io_save_done:
+#ifdef CONFIG_CACHE_L2X0
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ ldr r4, [r1, #L2X0_CTRL]
+ ldr r5, [r1, #L2X0_AUX_CTRL]
+ ldr r6, [r1, #L2X0_TAG_LATENCY_CTRL]
+ ldr r7, [r1, #L2X0_DATA_LATENCY_CTRL]
+ stmfd r0!, {r4-r7}
+
+ ldr r4, [r1, #L2X0_PREFETCH_CTRL]
+ ldr r5, [r1, #L2X0_POWER_CTRL]
+ stmfd r0!, {r4-r5}
+#endif
+
+ mov r4, sp @ Store sp
+ mrs r5, spsr @ Store spsr
+ mov r6, lr @ Store lr
+ stmfd r0!, {r4-r6}
+
+ /* c1 and c2 registers */
+ mrc p15, 0, r4, c1, c0, 2 @ CPACR
+ mrc p15, 0, r5, c2, c0, 0 @ TTBR0
+ mrc p15, 0, r6, c2, c0, 1 @ TTBR1
+ mrc p15, 0, r7, c2, c0, 2 @ TTBCR
+ stmfd r0!, {r4-r7}
+
+ /* c3 and c10 registers */
+ mrc p15, 0, r4, c3, c0, 0 @ DACR
+ mrc p15, 0, r5, c10, c2, 0 @ PRRR
+ mrc p15, 0, r6, c10, c2, 1 @ NMRR
+ mrc p15, 0, r7, c1, c0, 1 @ ACTLR
+ stmfd r0!,{r4-r7}
+
+ /* c12, c13 and CPSR registers */
+ mrc p15, 0, r4, c13, c0, 1 @ Context ID
+ mrc p15, 0, r5, c13, c0, 2 @ User r/w thread ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS VBAR
+ mrs r7, cpsr @ Store CPSR
+ stmfd r0!, {r4-r7}
+
+ /* c1 control register */
+ mrc p15, 0, r4, c1, c0, 0 @ SCTLR
+ stmfd r0!, {r4}
+
+ /* Need to flush and disable L1 dcache*/
+ flush_disable_l1_dcache
+
+ /* Need to clean L2 dcache*/
+ clean_l2_cache
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r6, [r6]
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r6, c2, c0, 1
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+/****************************************************************
+set ddr iomux to low power mode
+****************************************************************/
+ ldr r1, =MMDC_P0_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Put DDR explicitly into self-refresh. */
+ /* Disable Automatic power savings. */
+ ldr r0, [r1, #0x404]
+ orr r0, r0, #0x01
+ str r0, [r1, #0x404]
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r0, [r1, #0x404]
+ orr r0, r0, #0x200000
+ str r0, [r1, #0x404]
+
+poll_dvfs_set_1:
+ ldr r0, [r1, #0x404]
+ and r0, r0, #0x2000000
+ cmp r0, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set mmdc iomux to low power mode */
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ cmp r12, #MXC_CPU_MX6Q
+ bne dl_io_set_lpm
+ dq_ddr_io_set_lpm
+ b ddr_io_set_lpm_done
+dl_io_set_lpm:
+ cmp r12, #MXC_CPU_MX6DL
+ bne sl_io_set_lpm
+ dl_ddr_io_set_lpm
+ b ddr_io_set_lpm_done
+sl_io_set_lpm:
+ sl_ddr_io_set_lpm
+
+ddr_io_set_lpm_done:
+ /* Do Analog Power Optimizations
+ * for MX6SL in standby mode.
+ */
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_savings
+ cmp r11, #1
+ bne no_analog_savings
+
+ /* We are here because on
+ * MX6SL, we want to lower
+ * the power in Standby mode.
+ */
+ mx6sl_standy_saving_set
+
+no_analog_savings:
+
+/****************************************************************
+save resume pointer into SRC_GPR1
+****************************************************************/
+ ldr r0, =mx6_suspend
+ ldr r1, =resume
+ sub r1, r1, r0
+ add r3, r3, r1
+ ldr r1, =SRC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ str r3, [r1, #SRC_GPR1_OFFSET]
+
+ /* Mask all GPC interrupts before
+ * enabling the RBC counters to
+ * avoid the counter starting too
+ * early if an interupt is already
+ * pending.
+ */
+ ldr r3, =GPC_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+ ldr r4, [r3, #0x08]
+ ldr r5, [r3, #0x0c]
+ ldr r6, [r3, #0x10]
+ ldr r7, [r3, #0x14]
+
+ ldr r8, =0xffffffff
+ str r8, [r3, #0x08]
+ str r8, [r3, #0x0c]
+ str r8, [r3, #0x10]
+ str r8, [r3, #0x14]
+
+ /* Enable the RBC bypass counter here
+ * to hold off the interrupts.
+ * RBC counter = 32 (1ms)
+ * Minimum RBC delay should be
+ * 400us for the analog LDOs to
+ * power down.
+ */
+ ldr r1, =CCM_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r8, [r1, #0x0]
+ ldr r0, =0x7E00000
+ bic r8, r8, r0
+ ldr r0, =0x4000000
+ orr r8, r8, r0
+ str r8, [r1, #0x0]
+
+ /* Enable the counter. */
+ ldr r8, [r1, #0x0]
+ orr r8, r8, #0x8000000
+ str r8, [r1, #0x0]
+
+ /* Unmask all the GPC interrupts. */
+ str r4, [r3, #0x08]
+ str r5, [r3, #0x0c]
+ str r6, [r3, #0x10]
+ str r7, [r3, #0x14]
+
+
+ /* Now delay for a short while (3usec)
+ * ARM is at 1GHz at this point
+ * so a short loop should be enough.
+ * This delay is required to ensure that
+ * the RBC counter can start counting in case an
+ * interrupt is already pending or in case an interrupt
+ * arrives just as ARM is about to assert DSM_request.
+ */
+ ldr r4, =2000
+rbc_loop:
+ sub r4, r4, #0x1
+ cmp r4, #0x0
+ bne rbc_loop
+
+ /*if internal ldo(VDDARM) bypassed,analog bypass it for DSM(0x1e) and
+ *restore it when resume(0x1f).
+ */
+ ldr r1, =ANATOP_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r4, [r1, #0x140]
+ and r4, r4, #0x1f
+ cmp r4, #0x1f
+ bne ldo_check_done1
+ldo_analog_bypass:
+ ldr r4, [r1, #0x140]
+ bic r4, r4, #0x1f
+ orr r4, r4, #0x1e
+ str r4, [r1, #0x140]
+ldo_check_done1:
+/****************************************************************
+execute a wfi instruction to let SOC go into stop mode.
+****************************************************************/
+ wfi
+
+ nop
+ nop
+ nop
+ nop
+
+/****************************************************************
+if go here, means there is a wakeup irq pending, we should resume
+system immediately.
+****************************************************************/
+ /*restore it with 0x1f if use ldo bypass mode.*/
+ ldr r1, =ANATOP_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r3, [r1, #0x140]
+ and r3, r3, #0x1f
+ cmp r3, #0x1e
+ bne ldo_check_done2
+ldo_bypass_restore:
+ ldr r3, [r1, #0x140]
+ orr r3, r3, #0x1f
+ str r3, [r1, #0x140]
+ldo_check_done2:
+ /*
+ * Get the address of IRAM stack
+ */
+ ldr r0, =SRC_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r0, [r0, #SRC_GPR2_OFFSET]
+
+ add r0, r0, #PERIPBASE_VIRT
+ ldmea r0!, {r12} @ get cpu type to make ddr io
+ @ offset right
+
+ ldmea r0!, {r11} @ standby or mem
+
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_restore
+
+ cmp r11, #0x1
+ bne no_analog_restore
+
+ ldr r3, =CCM_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+
+ /* Restore the analog settings. */
+ mx6sl_standby_savings_restore
+
+no_analog_restore:
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ cmp r12, #MXC_CPU_MX6Q
+ bne dl_io_restore
+ dq_ddr_io_restore
+ b ddr_io_restore_done
+dl_io_restore:
+ cmp r12, #MXC_CPU_MX6DL
+ bne sl_io_restore
+ dl_ddr_io_restore
+ b ddr_io_restore_done
+sl_io_restore:
+ sl_ddr_io_restore
+ ldr r1, =MMDC_P0_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =0x83c
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+fifo_reset1_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset1_wait
+
+ /* reset FIFO a second time */
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+fifo_reset2_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset2_wait
+
+ddr_io_restore_done:
+ ldr r1, =MMDC_P0_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Ensure DDR exits self-refresh. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r1, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r1, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r1, #0x404]
+
+ /* Add enough nops so that the
+ * prefetcher will not get instructions
+ * from DDR before its IO pads
+ * are restored.
+ */
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ mrc p15, 0, r1, c1, c0, 0
+ orr r1, r1, #(1 << 2) @ Enable the C bit
+ mcr p15, 0, r1, c1, c0, 0
+
+ /* Restore TTBCR */
+ dsb
+ isb
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ b out /* exit standby */
+ .ltorg
+
+/****************************************************************
+when SOC exit stop mode, arm core restart from here, currently
+are running with MMU off.
+****************************************************************/
+resume:
+ /*restore it with 0x1f if use ldo bypass mode.*/
+ ldr r1, =ANATOP_BASE_ADDR
+ ldr r3, [r1, #0x140]
+ and r3, r3, #0x1f
+ cmp r3, #0x1e
+ bne ldo_check_done3
+ ldr r3, [r1, #0x140]
+ orr r3, r3, #0x1f
+ str r3, [r1, #0x140]
+ldo_check_done3:
+ /* Invalidate L1 I-cache first */
+ mov r1, #0x0
+ mcr p15, 0, r1, c7, c5, 0 @ Invalidate I-Cache
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate Icache to PoU
+ mcr p15, 0, r1, c7, c5, 6 @ invalidate branch predictor
+ mov r1, #0x1800
+ mcr p15, 0, r1, c1, c0, 0 @ enable the Icache and branch prediction
+ isb @ as soon as possible
+
+ /* Need to invalidate L1 dcache */
+ invalidate_l1_dcache
+
+ ldr r0, =SRC_BASE_ADDR
+ str r1, [r0, #SRC_GPR1_OFFSET] /* clear SRC_GPR1 */
+ ldr r0, [r0, #SRC_GPR2_OFFSET]
+
+ ldmea r0!, {r12} @ get cpu type
+
+ ldmea r0!, {r11} @ standby or mem
+
+ cmp r12, #MXC_CPU_MX6SL
+ bne no_analog_restore1
+
+ cmp r11, #0x1
+ bne no_analog_restore1
+
+ ldr r1, =ANATOP_BASE_ADDR
+ ldr r3, =CCM_BASE_ADDR
+
+ /* Restore the analog settings. */
+ mx6sl_standby_pg_savings_restore
+
+no_analog_restore1:
+ /* Restore DDR IO */
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+
+ cmp r12, #MXC_CPU_MX6Q
+ bne dl_io_dsm_restore
+ dq_ddr_io_restore
+ b ddr_io_restore_dsm_done
+dl_io_dsm_restore:
+ cmp r12, #MXC_CPU_MX6DL
+ bne sl_io_dsm_restore
+ dl_ddr_io_restore
+ b ddr_io_restore_dsm_done
+sl_io_dsm_restore:
+ sl_ddr_io_restore
+ ldr r1, =MMDC_P0_BASE_ADDR
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =0x83c
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+dsm_fifo_reset1_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne dsm_fifo_reset1_wait
+
+ /* reset FIFO a second time */
+ ldr r6, [r1, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r1, r7]
+dsm_fifo_reset2_wait:
+ ldr r6, [r1, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne dsm_fifo_reset2_wait
+
+ddr_io_restore_dsm_done:
+ ldr r1, =MMDC_P0_BASE_ADDR
+
+ /* Ensure DDR exits self-refresh. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r1, #0x404]
+
+poll_dvfs_clear_2:
+ ldr r6, [r1, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_2
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r1, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r1, #0x404]
+
+#ifdef CONFIG_CACHE_L2X0
+ ldr r2, =L2_BASE_ADDR
+ ldmea r0!, {r4-r7}
+ /* L2 will be enabled after L1 is enabled */
+ mov r4, #0x0
+ str r4, [r2, #L2X0_CTRL]
+ str r5, [r2, #L2X0_AUX_CTRL]
+ str r6, [r2, #L2X0_TAG_LATENCY_CTRL]
+ str r7, [r2, #L2X0_DATA_LATENCY_CTRL]
+
+ ldmea r0!, {r4-r5}
+ str r4, [r2, #L2X0_PREFETCH_CTRL]
+ str r5, [r2, #L2X0_POWER_CTRL]
+#endif
+
+ /* Restore cp15 registers and cpu type */
+ ldmea r0!, {r4-r6}
+ mov sp, r4 @ Restore sp
+ msr spsr_cxsf, r5 @ Restore spsr
+ mov lr, r6 @ Restore lr
+
+ /* c1 and c2 registers */
+ ldmea r0!, {r4-r7}
+ mcr p15, 0, r4, c1, c0, 2 @ CPACR
+ mcr p15, 0, r5, c2, c0, 0 @ TTBR0
+ mcr p15, 0, r6, c2, c0, 1 @ TTBR1
+ mcr p15, 0, r7, c2, c0, 2 @ TTBCR
+
+ /* c3 and c10 registers */
+ ldmea r0!,{r4-r7}
+ mcr p15, 0, r4, c3, c0, 0 @ DACR
+ mcr p15, 0, r5, c10, c2, 0 @ PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ NMRR
+ mcr p15, 0, r7, c1, c0, 1 @ ACTLR
+
+ /* c12, c13 and CPSR registers */
+ ldmea r0!,{r4-r7}
+ mcr p15, 0, r4, c13, c0, 1 @ Context ID
+ mcr p15, 0, r5, c13, c0, 2 @ User r/w thread ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS VBAR
+ msr cpsr, r7 @ store cpsr
+
+ /*
+ * Enabling MMU here. Page entry needs to be altered
+ * to create temporary 1:1 map and then resore the entry
+ * ones MMU is enabled
+ */
+ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
+ and r7, #0x7 @ Extract N (0:2) to decide
+ cmp r7, #0x0 @ TTBR0/TTBR1
+ beq use_ttbr0
+ttbr_error:
+ b ttbr_error @ Only N = 0 supported
+use_ttbr0:
+ mrc p15, 0, r2, c2, c0, 0 @ Read TTBR0
+ ldr r5, =TTRBIT_MASK
+ and r2, r5
+ mov r4, pc
+ ldr r5, =TABLE_INDEX_MASK
+ and r4, r5 @ r4 = 31 to 20 bits of pc
+ ldr r1, =TABLE_ENTRY
+ add r1, r1, r4 @ r1 has value of table entry
+ lsr r4, #18 @ Address of table entry
+ add r2, r4 @ r2 - location to be modified
+
+ /* Storing previous entry of location being modified */
+ ldr r4, [r2]
+ mov r9, r4
+ str r1, [r2]
+
+ /*
+ * Storing address of entry being modified
+ * It will be restored after enabling MMU
+ */
+ mov r10, r2
+
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r1, c8, c5, 0 @ Invalidate ITLB
+ mcr p15, 0, r1, c8, c6, 0 @ Invalidate DTLB
+
+ /*
+ * Restore control register but don't enable Data caches here.
+ * Caches will be enabled after restoring MMU table entry.
+ */
+ ldmea r0!, {r4}
+ mov r11, r4
+ ldr r2, =CACHE_DISABLE_MASK
+ and r4, r4, r2
+ mcr p15, 0, r4, c1, c0, 0
+ isb
+ dsb
+ ldr r1, =mmu_on_label
+ bx r1
+mmu_on_label:
+
+/************************************************************
+restore control register to enable cache
+************************************************************/
+ mov r0, r11
+ mcr p15, 0, r0, c1, c0, 0 @ with caches enabled.
+ dsb
+ isb
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Enable L2 cache here */
+ ldr r2, =L2_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+ mov r4, #0x1
+ str r4, [r2, #L2X0_CTRL]
+#endif
+
+ mov r8, lr
+ push {r0-r3, r12}
+
+ /* Set up the per-CPU stacks */
+ bl cpu_init
+ pop {r0-r3, r12}
+
+ /*
+ * Restore the MMU table entry that was modified for
+ * enabling MMU.
+ */
+ ldr r4, =PAGE_OFFSET
+
+ cmp r12, #MXC_CPU_MX6SL
+ bne dq_dl_phy_offset
+ ldr r5, =MX6SL_PHYS_OFFSET
+ b get_phy_offset_done
+dq_dl_phy_offset:
+ ldr r5, =MX6_PHYS_OFFSET
+get_phy_offset_done:
+
+ sub r4, r4, r5
+ add r4, r4, r10
+ str r9, [r4]
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c1, 6 @ flush TLB and issue barriers
+ mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
+ mcr p15, 0, r0, c8, c5, 0 @ Invalidate ITLB
+ mcr p15, 0, r0, c8, c6, 0 @ Invalidate DTLB
+ dsb
+ isb
+
+/***********************************************************
+return back to mx6_suspend_enter for dormant
+***********************************************************/
+ mov lr, r8
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+/************************************************
+return back to mx6_suspend_enter for suspend
+*************************************************/
+out:
+ ldmfd sp!, {r0-r12}
+ mov pc, lr
+
+ .type mx6_do_suspend, #object
+ENTRY(mx6_do_suspend)
+ .word mx6_suspend
+ .size mx6_suspend, . - mx6_suspend
diff --git a/arch/arm/mach-mx6/mx6_wfi.S b/arch/arm/mach-mx6/mx6_wfi.S
new file mode 100644
index 00000000..afe7b9a3
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6_wfi.S
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+
+/*
+ * mx6_wait
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ */
+ENTRY(mx6_wait)
+
+ push {r4, r5, r6, r7, r8, r9}
+
+ mov r7, r2 /* Store the arm_podf to be used. */
+ mov r6, r3
+
+ ldr r2, =ANATOP_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+
+ ldr r8, =CCM_BASE_ADDR
+ add r8, r8, #PERIPBASE_VIRT
+
+
+ /* get the flags variables into the cache */
+ ldr r3, [r0]
+
+ /* get CPU ID */
+ mrc p15,0,r5,c0,c0,5
+ and r5, r5, #0x3
+
+ mov r4,#0xff
+ strb r4,[r0,r5]
+
+ dsb
+
+ mvn r4, #0x0
+ ldr r3, [r0]
+ cmp r3, r4
+ bne DO_WFI
+
+ mov r4, #0x1
+ ldrex r3, [r1]
+ cmp r3, #0x0
+ strexeq r3, r4, [r1]
+ cmpeq r3, #0x0
+ bne DO_WFI
+
+ mov r3, #0xff
+
+ /* Check to see if we need to switch to 24MHz */
+ cmp r7, #0
+ bne use_podf
+ /* Switch ARM to PLL1 output. */
+ /* PLL1 should already be in bypass state. */
+ ldr r6, [r8, #0x0C]
+ bic r6, r6, #0x04
+ str r6, [r8, #0x0C]
+ b cont
+
+use_podf:
+ /* Change ARM_PODF to the max possible podf
+ * so that ARM_CLK to IPG_CLK is in 12:5 ratio.
+ */
+ str r7, [r8, #0x10]
+ /* Loop till podf is accepted. */
+podf_loop:
+ ldr r4, [r8, #0x48]
+ cmp r4, #0x0
+ bne podf_loop
+
+ /* dmb */
+
+cont:
+ str r3, [r1]
+
+ dsb
+
+ mvn r4, #0x0
+ ldr r3, [r0]
+ cmp r3, r4
+ beq DO_WFI
+
+ mov r3, #0x0
+ /* Switch to 24MHz or use ARM_PODF. */
+ cmp r7, #0x0
+ bne use_podf1
+ /* Set pll1_sw_clk to run from STEP_CLK. */
+ orr r6, r6, #0x04
+ str r6, [r8, #0x0C]
+ b DO_WFI
+use_podf1:
+ str r6, [r8, #0x10]
+
+ str r3, [r1]
+
+DO_WFI:
+ dsb
+
+ wfi
+
+ mov r4, #0x0
+ strb r4, [r0, r5]
+
+ dsb
+
+ ldr r3, [r1]
+ cmp r3, #0xff
+ bne DONE
+
+ mov r4, #0x0
+ cmp r7, #0x0
+ bne use_podf2
+ /* Set pll1_sw_clk to run from STEP_CLK. */
+ ldr r6, [r8, #0x0C]
+ orr r6, r6, #0x04
+ str r6, [r8, #0x0C]
+
+ b cont1
+
+use_podf2:
+ str r6, [r8, #0x10]
+
+cont1:
+ mov r3, #0x0
+ str r3, [r1]
+
+DONE:
+
+ pop {r4,r5, r6, r7, r8, r9}
+
+ /* Restore registers */
+ mov pc, lr
+
+ .type mx6_do_wait, #object
+ENTRY(mx6_do_wait)
+ .word mx6_wait
+ .size mx6_wait, . - mx6_wait
diff --git a/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c
new file mode 100644
index 00000000..671233f3
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6q_sabreauto_pmic_pfuze100.c
@@ -0,0 +1,545 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <linux/io.h>
+#include <mach/irqs.h>
+#include <mach/system.h>
+#include "crm_regs.h"
+#include "regs-anadig.h"
+#include "cpu_op-mx6.h"
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+#define PFUZE100_DEVICEID (0x0)
+#define PFUZE100_REVID (0x3)
+#define PFUZE100_SW1AMODE (0x23)
+#define PFUZE100_SW1AVOL 32
+#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1CVOL 46
+#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+
+extern u32 arm_max_freq;
+extern u32 enable_ldo_mode;
+
+static struct regulator_consumer_supply sw1a_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ }
+};
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "P3V0_VDDHIGH_SW2",
+ }
+};
+
+static struct regulator_consumer_supply sw3_consumers[] = {
+ {
+ .supply = "P1V5_DDR_SW3",
+ }
+};
+
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "P1V8_SW4",
+ }
+};
+
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "P5V0_SWBST",
+ }
+};
+
+static struct regulator_consumer_supply vsnvs_consumers[] = {
+ {
+ .supply = "P3V0_STBY",
+ }
+};
+
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "P1V2_VGEN1",
+ }
+};
+
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "P1V5_VGEN2",
+ }
+};
+
+static struct regulator_consumer_supply vgen3_consumers[] = {
+ {
+ .supply = "P1V8_VGEN3",
+ }
+};
+
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "P1V8_VGEN4",
+ }
+};
+
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "P2V5_VGEN5",
+ }
+};
+
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "P2V8_VGEN6",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers),
+ .consumer_supplies = sw1a_consumers,
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw3_consumers),
+ .consumer_supplies = sw3_consumers,
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vsnvs_consumers),
+ .consumer_supplies = vsnvs_consumers,
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen3_consumers),
+ .consumer_supplies = vgen3_consumers,
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret, i;
+ unsigned char value;
+
+ /*use default mode(ldo bypass) if no param from cmdline*/
+ if (enable_ldo_mode == LDO_MODE_DEFAULT)
+ enable_ldo_mode = LDO_MODE_ENABLED;
+
+ /*read Device ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_DEVICEID, &value);
+ if (ret)
+ goto err;
+ if (value != 0x10) {
+ printk(KERN_ERR "wrong device id:%x!\n", value);
+ goto err;
+ }
+
+ /*read Revision ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_REVID, &value);
+ if (ret)
+ goto err;
+ if (value == 0x10) {
+ printk(KERN_WARNING "PF100 1.0 chip found!\n");
+ /* workaround ER1 of pfuze1.0: set all buck regulators in PWM mode
+ * except SW1C(APS) in normal and PFM mode in standby.
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)/*SW1C*/
+ value = 0xc;/*normal:APS mode;standby:PFM mode*/
+ else
+ value = 0xd;/*normal:PWM mode;standby:PFM mode*/
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ } else {
+ /*set all switches APS in normal and PFM mode in standby*/
+ for (i = 0; i < 7; i++) {
+ value = 0xc;
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ }
+ /*use ldo active mode if use 1.2GHz,otherwise use ldo bypass mode*/
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ /*VDDARM_IN 1.425*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2d);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.425V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2d);
+ if (ret)
+ goto err;
+ enable_ldo_mode = LDO_MODE_ENABLED;
+ } else if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /*decrease VDDARM_IN/VDDSOC_IN,since we will use ldo bypass mode*/
+ /*VDDARM_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*set SW1AB/1C DVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ } else if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /*Increase VDDARM_IN/VDDSOC_IN to 1.375V in ldo active mode*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ }
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+ {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6q_sabreauto_init_pfuze100(u32 int_gpio)
+{
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(1, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c
new file mode 100644
index 00000000..c18a0143
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6q_sabresd_pmic_pfuze100.c
@@ -0,0 +1,529 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <linux/io.h>
+#include <mach/irqs.h>
+#include <mach/system.h>
+#include "crm_regs.h"
+#include "regs-anadig.h"
+#include "cpu_op-mx6.h"
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+#define PFUZE100_DEVICEID (0x0)
+#define PFUZE100_REVID (0x3)
+#define PFUZE100_SW1AMODE (0x23)
+#define PFUZE100_SW1AVOL 32
+#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1CVOL 46
+#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+
+extern u32 arm_max_freq;
+extern u32 enable_ldo_mode;
+
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "MICVDD",
+ .dev_name = "0-001a",
+ }
+};
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "AUD_1V8",
+ }
+};
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "SWBST_5V",
+ }
+};
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "VGEN1_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "VGEN2_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "DBVDD",
+ .dev_name = "0-001a",
+ },
+ {
+ .supply = "AVDD",
+ .dev_name = "0-001a",
+ },
+ {
+ .supply = "DCVDD",
+ .dev_name = "0-001a",
+ },
+ {
+ .supply = "CPVDD",
+ .dev_name = "0-001a",
+ },
+ {
+ .supply = "PLLVDD",
+ .dev_name = "0-001a",
+ }
+};
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "VGEN5_2V8",
+ }
+};
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "VGEN6_3V3",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "PFUZE100_SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "PFUZE100_SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "PFUZE100_SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "PFUZE100_VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "PFUZE100_VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret, i;
+ unsigned char value;
+ /*use default mode(ldo bypass) if no param from cmdline*/
+ if (enable_ldo_mode == LDO_MODE_DEFAULT)
+ enable_ldo_mode = LDO_MODE_BYPASSED;
+ /*read Device ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_DEVICEID, &value);
+ if (ret)
+ goto err;
+ if (value != 0x10) {
+ printk(KERN_ERR "wrong device id:%x!\n", value);
+ goto err;
+ }
+
+ /*read Revision ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_REVID, &value);
+ if (ret)
+ goto err;
+ if (value == 0x10) {
+ printk(KERN_WARNING "PF100 1.0 chip found!\n");
+ /* workaround ER1 of pfuze1.0: set all buck regulators in PWM mode
+ * except SW1C(APS) in normal and PFM mode in standby.
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)/*SW1C*/
+ value = 0xc;/*normal:APS mode;standby:PFM mode*/
+ else
+ value = 0xd;/*normal:PWM mode;standby:PFM mode*/
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ } else {
+ /*set all switches APS in normal and PFM mode in standby*/
+ for (i = 0; i < 7; i++) {
+ value = 0xc;
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ }
+ /*use ldo active mode if use 1.2GHz,otherwise use ldo bypass mode*/
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ /*VDDARM_IN 1.425*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2d);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.425V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2d);
+ if (ret)
+ goto err;
+ enable_ldo_mode = LDO_MODE_ENABLED;
+ } else if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /*decrease VDDARM_IN/VDDSOC_IN,since we will use ldo bypass mode*/
+ /*VDDARM_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*set SW1AB/1C DVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ } else if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /*Increase VDDARM_IN/VDDSOC_IN to 1.375V in ldo active mode*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ }
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+ {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6q_sabresd_init_pfuze100(u32 int_gpio)
+{
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(1, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
new file mode 100644
index 00000000..7cebb8f2
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_arm2_pmic_pfuze100.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <mach/irqs.h>
+#include <mach/system.h>
+#include "cpu_op-mx6.h"
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+#define PFUZE100_DEVICEID (0x0)
+#define PFUZE100_REVID (0x3)
+#define PFUZE100_SW1AMODE (0x23)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1AVOL 32
+#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1CVOL 46
+#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
+extern u32 enable_ldo_mode;
+extern u32 arm_max_freq;
+
+
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "MICVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DBVDD",
+ .dev_name = "1-001a",
+ }
+
+};
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "AUD_1V8",
+ }
+};
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "SWBST_5V",
+ }
+};
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "VGEN1_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "VGEN2_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "AVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DCVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "CPVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "PLLVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "VGEN5_2V8",
+ }
+};
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "VGEN6_3V3",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "PFUZE100_SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "PFUZE100_SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "PFUZE100_SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "PFUZE100_VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "PFUZE100_VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret, i;
+ unsigned char value;
+
+ /*use default mode(ldo bypass) if no param from cmdline*/
+ if (enable_ldo_mode == LDO_MODE_DEFAULT)
+ enable_ldo_mode = LDO_MODE_BYPASSED;
+ /*read Device ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_DEVICEID, &value);
+ if (ret)
+ goto err;
+ if (value != 0x10) {
+ printk(KERN_ERR "wrong device id:%x!\n", value);
+ goto err;
+ }
+
+ /*read Revision ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_REVID, &value);
+ if (ret)
+ goto err;
+ if (value == 0x10) {
+ printk(KERN_WARNING "PF100 1.0 chip found!\n");
+ /* workaround ER1 of pfuze1.0: set all buck regulators in PWM mode
+ * except SW1C(APS) in normal and PFM mode in standby.
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)/*SW1C*/
+ value = 0xc;/*normal:APS mode;standby:PFM mode*/
+ else
+ value = 0xd;/*normal:PWM mode;standby:PFM mode*/
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ } else {
+ /*set all switches APS in normal and PFM mode in standby*/
+ for (i = 0; i < 7; i++) {
+ value = 0xc;
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ }
+ /*use ldo active mode if use 1.2GHz,otherwise use ldo bypass mode*/
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ /*VDDARM_IN 1.47*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2f);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.475V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2f);
+ if (ret)
+ goto err;
+ enable_ldo_mode = LDO_MODE_ENABLED;
+ } else if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /*decrease VDDARM_IN/VDDSOC_IN,since we will use dynamic ldo bypass
+ *mode or ldo bypass mode here.*/
+ /*VDDARM_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*set SW1AB/SW1C DVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ } else if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /*Increase VDDARM_IN/VDDSOC_IN to 1.375V in ldo active mode*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ }
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+ {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6sl_arm2_init_pfuze100(u32 int_gpio)
+{
+ if (int_gpio)
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(0, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6sl_ddr.S b/arch/arm/mach-mx6/mx6sl_ddr.S
new file mode 100644
index 00000000..bac1e7c2
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_ddr.S
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+.extern iram_tlb_phys_addr
+.extern mx6sl_ddr_freq_base
+.extern mx6sl_ddr_freq_phys_addr
+
+ .macro mx6sl_switch_to_24MHz
+
+ /* Set MMDC clock to be sourced from PLL3. */
+ /* Ensure first periph2_clk2 is sourced from PLL3. */
+ /* Set the PERIPH2_CLK2_PODF to divide by 2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ orr r6, r6, #0x1
+ str r6, [r2, #0x14]
+
+ /* Select PLL3 to source MMDC. */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Swtich periph2_clk_sel to run from PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch1
+
+ /* Need to clock gate the 528 PFDs before
+ * powering down PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC
+ */
+ ldr r6, [r3, #0x100]
+ orr r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+ /* Set PLL2 to bypass state. We should be here
+ *only if MMDC is not sourced from PLL2.*/
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ ldr r6, [r3, #0x30]
+ orr r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Ensure pre_periph2_clk_mux is set to pll2 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ str r6, [r2, #0x18]
+
+ /* Set MMDC clock to be sourced from the bypassed PLL2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch2:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch2
+
+ /* Now move MMDC back to periph2_clk2 source.
+ * after selecting PLL2 as the option.
+ */
+ /* Select PLL2 as the source. */
+ ldr r6, [r2, #0x18]
+ orr r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* set periph2_clk2_podf to divide by 1. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x7
+ str r6, [r2, #0x14]
+
+ /* Now move periph2_clk to periph2_clk2 source */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch3:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch3
+
+ /* Now set the MMDC PODF back to 1.*/
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ str r6, [r2, #0x14]
+
+mmdc_podf0:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf0
+
+ .endm
+
+ .macro ddr_switch_400MHz
+
+ /* Set MMDC divider first, in case PLL3 is at 480MHz. */
+ ldr r6, [r3, #0x10]
+ and r6, r6, #0x10000
+ cmp r6, #0x10000
+ beq pll3_in_bypass
+ /* Set MMDC divder to divide by 2. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x8
+ str r6, [r2, #0x14]
+
+mmdc_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf
+
+pll3_in_bypass:
+
+ /* Check if we are switching between
+ * 400Mhz <-> 100MHz.If so, we should
+ * try to source MMDC from PLL2_200M.
+ */
+ cmp r1, #0
+ beq not_low_bus_freq
+
+ /* Ensure that MMDC is sourced from PLL2 mux first. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch4:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch4
+
+not_low_bus_freq:
+ /* Now ensure periph2_clk2_sel mux is set to PLL3 */
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x100000
+ str r6, [r2, #0x18]
+
+ /* Now switch MMDC to PLL3. */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x4000000
+ str r6, [r2, #0x14]
+
+periph2_clk_switch5:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne periph2_clk_switch5
+
+ /* Check if PLL2 is already unlocked.
+ * If so do nothing with PLL2.
+ */
+ cmp r1, #0
+ beq pll2_already_on
+
+ /* Now power up PLL2 and unbypass it. */
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x1000
+ str r6, [r3, #0x30]
+
+ /* Make sure PLL2 has locked.*/
+wait_for_pll_lock:
+ ldr r6, [r3, #0x30]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ ldr r6, [r3, #0x30]
+ bic r6, r6, #0x10000
+ str r6, [r3, #0x30]
+
+ /* Need to enable the 528 PFDs after
+ * powering up PLL2.
+ * Only the PLL2_PFD2_400M should be ON
+ * as it feeds the MMDC. Rest should have
+ * been managed by clock code.
+ */
+ ldr r6, [r3, #0x100]
+ bic r6, r6, #0x800000
+ str r6, [r3, #0x100]
+
+pll2_already_on:
+ /* Now switch MMDC clk back to pll2_mux option. */
+ /* Ensure pre_periph2_clk2 is set to pll2_pfd_400M */
+ /* If switching to audio DDR freq, set the
+ * pre_periph2_clk2 to PLL2_PFD_200M
+ */
+ ldr r6, =400000000
+ cmp r6, r0
+ bne use_pll2_pfd_200M
+
+ ldr r6, [r2, #0x18]
+ bic r6, r6, #0x600000
+ orr r6, r6, #0x200000
+ str r6, [r2, #0x18]
+ ldr r6, =400000000
+ b cont2
+
+use_pll2_pfd_200M:
+ ldr r6, [r2, #0x18]
+ orr r6, r6, #0x600000
+ str r6, [r2, #0x18]
+ ldr r6, =200000000
+
+cont2:
+ ldr r4, [r2, #0x14]
+ bic r4, r4, #0x4000000
+ str r4, [r2, #0x14]
+
+periph2_clk_switch6:
+ ldr r4, [r2, #0x48]
+ cmp r4, #0
+ bne periph2_clk_switch6
+
+change_divider_only:
+ /* Calculate the MMDC divider
+ * based on the requested freq.
+ */
+ ldr r4, =0
+Loop2:
+ sub r6, r6, r0
+ cmp r6, r0
+ blt Div_Found
+ add r4, r4, #1
+ bgt Loop2
+
+ /* Shift divider into correct offset. */
+ lsl r4, r4, #3
+Div_Found:
+ /* Set the MMDC PODF. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, r4
+ str r6, [r2, #0x14]
+
+mmdc_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0
+ bne mmdc_podf1
+
+ .endm
+
+ .macro mmdc_clk_lower_100MHz
+
+ /* Prior to reducing the DDR frequency (at 528/400 MHz),
+ read the Measure unit count bits (MU_UNIT_DEL_NUM) */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ /* Original MU unit count */
+ mov r6, r6, LSR #16
+ ldr r4, =0x3FF
+ and r6, r6, r4
+ /* Original MU unit count * 2 */
+ mov r7, r6, LSL #1
+ /* Bypass the automatic measure unit when below 100 MHz
+ by setting the Measure unit bypass enable bit (MU_BYP_EN) */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Double the measure count value read in step 1 and program it in the
+ * measurement bypass bits (MU_BYP_VAL) of the MMDC PHY Measure Unit
+ * Register for the reduced frequency operation below 100 MHz
+ */
+ ldr r6, [r8, r5]
+ ldr r4, =0x3FF
+ bic r6, r6, r4
+ orr r6, r6, r7
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure
+
+ .endm
+
+ .macro mmdc_clk_above_100MHz
+
+ /* Make sure that the PHY measurement unit is NOT in bypass mode */
+ ldr r5, =0x8B8
+ ldr r6, [r8, r5]
+ bic r6, r6, #0x400
+ str r6, [r8, r5]
+ /* Now perform a Force Measurement. */
+ ldr r6, [r8, r5]
+ orr r6, r6, #0x800
+ str r6, [r8, r5]
+ /* Wait for FRC_MSR to clear. */
+force_measure1:
+ ldr r6, [r8, r5]
+ and r6, r6, #0x800
+ cmp r6, #0x0
+ bne force_measure1
+ .endm
+
+ .align 3
+/*
+ * mx6sl_ddr_iram
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : DDR freq.
+ * r1: low_bus_freq_mode flag
+ */
+ENTRY(mx6sl_ddr_iram)
+
+ push {r4-r10}
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+mx6sl_ddr_freq_change:
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /*
+ * Sync L2 and then disable it.
+ */
+ dsb
+ ldr r4, =L2_BASE_ADDR
+ add r4, r4, #PERIPBASE_VIRT
+ ldr r6, =0x0
+ str r6, [r4, #0x730]
+ /* Disable L2. */
+ str r6, [r4, #0x100]
+
+ dsb
+ isb
+
+ ldr r3, =ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+ ldr r2, =CCM_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+ ldr r8, =MMDC_P0_BASE_ADDR
+ add r8, r8, #PERIPBASE_VIRT
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* Disable MMDC power down timer. */
+ /*MMDC0_MDPDC disable power down timer */
+ ldr r6, [r8, #0x4]
+ bic r6, r6, #0xff00
+ str r6, [r8, #0x4]
+
+ /* Delay for a while */
+ ldr r10, =10
+delay1:
+ ldr r7, =0
+cont1:
+ ldr r6, [r8, r7]
+ add r7, r7, #4
+ cmp r7, #16
+ bne cont1
+ sub r10, r10, #1
+ cmp r10, #0
+ bgt delay1
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ ldr r10, =100000000
+ cmp r0, r10
+ bgt set_ddr_mu_above_100
+ mmdc_clk_lower_100MHz
+
+set_ddr_mu_above_100:
+ ldr r10, =24000000
+ cmp r0, r10
+ beq set_to_24MHz
+
+ ddr_switch_400MHz
+ ldr r10, =100000000
+ cmp r0, r10
+ blt done
+ mmdc_clk_above_100MHz
+ b done
+
+set_to_24MHz:
+ mx6sl_switch_to_24MHz
+
+done:
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ ldr r10, =24000000
+ cmp r0, r10
+ beq skip_power_down
+
+ /* Enable MMDC power down timer. */
+ ldr r6, [r8, #0x4]
+ orr r6, r6, #0x5500
+ str r6, [r8, #0x4]
+
+skip_power_down:
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ /* Enable L2. */
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r6, =0x1
+ str r6, [r1, #0x100]
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+ dsb
+ isb
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ pop {r4-r10}
+
+ /* Restore registers */
+ mov pc, lr
diff --git a/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
new file mode 100644
index 00000000..14bd33ff
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_evk_pmic_pfuze100.c
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <mach/irqs.h>
+#include <mach/system.h>
+#include "cpu_op-mx6.h"
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+#define PFUZE100_DEVICEID (0x0)
+#define PFUZE100_REVID (0x3)
+#define PFUZE100_SW1AMODE (0x23)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1AVOL 32
+#define PFUZE100_SW1AVOL_VSEL_M (0x3f<<0)
+#define PFUZE100_SW1CVOL 46
+#define PFUZE100_SW1CVOL_VSEL_M (0x3f<<0)
+
+extern u32 enable_ldo_mode;
+extern u32 arm_max_freq;
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "MICVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "AUD_1V8",
+ }
+};
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "SWBST_5V",
+ }
+};
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "VGEN1_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "VGEN2_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen3_consumers[] = {
+ {
+ .supply = "AVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DCVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "CPVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "PLLVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DBVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "VGEN4_1V8",
+ }
+};
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "VGEN5_2V8",
+ }
+};
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "VGEN6_2V8",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ .initial_state = PM_SUSPEND_MEM,
+ .state_mem = {
+ .uV = 975000,/*0.9V+6%*/
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "PFUZE100_SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "PFUZE100_SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "PFUZE100_SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "PFUZE100_VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "PFUZE100_VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen3_consumers),
+ .consumer_supplies = vgen3_consumers,
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret, i;
+ unsigned char value;
+ /*use default mode(ldo bypass) if no param from cmdline*/
+ if (enable_ldo_mode == LDO_MODE_DEFAULT)
+ enable_ldo_mode = LDO_MODE_BYPASSED;
+ /*read Device ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_DEVICEID, &value);
+ if (ret)
+ goto err;
+ if (value != 0x10) {
+ printk(KERN_ERR "wrong device id:%x!\n", value);
+ goto err;
+ }
+
+ /*read Revision ID*/
+ ret = pfuze_reg_read(pfuze, PFUZE100_REVID, &value);
+ if (ret)
+ goto err;
+ if (value == 0x10) {
+ printk(KERN_WARNING "PF100 1.0 chip found!\n");
+ /* workaround ER1 of pfuze1.0: set all buck regulators in PWM mode
+ * except SW1C(APS) in normal and PFM mode in standby.
+ */
+ for (i = 0; i < 7; i++) {
+ if (i == 2)/*SW1C*/
+ value = 0xc;/*normal:APS mode;standby:PFM mode*/
+ else
+ value = 0xd;/*normal:PWM mode;standby:PFM mode*/
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ } else {
+ /*set all switches APS in normal and PFM mode in standby*/
+ for (i = 0; i < 7; i++) {
+ value = 0xc;
+ ret = pfuze_reg_write(pfuze,
+ PFUZE100_SW1AMODE + (i * 7),
+ value);
+ if (ret)
+ goto err;
+ }
+
+ }
+ /*use ldo active mode if use 1.2GHz,otherwise use ldo bypass mode*/
+ if (arm_max_freq == CPU_AT_1_2GHz) {
+ /*VDDARM_IN 1.47*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2f);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.475V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2f);
+ if (ret)
+ goto err;
+ enable_ldo_mode = LDO_MODE_ENABLED;
+ } else if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /*decrease VDDARM_IN/VDDSOC_IN,since we will use dynamic ldo bypass
+ *mode or ldo bypass mode here.*/
+ /*VDDARM_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+ /*VDDSOC_IN 1.3V*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x28);
+ if (ret)
+ goto err;
+
+ /*set SW1AB/SW1CDVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ } else if (enable_ldo_mode != LDO_MODE_BYPASSED) {
+ /*Increase VDDARM_IN/VDDSOC_IN to 1.375V in ldo active mode*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1AVOL,
+ PFUZE100_SW1AVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CVOL,
+ PFUZE100_SW1CVOL_VSEL_M,
+ 0x2b);
+ if (ret)
+ goto err;
+ }
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+ {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6sl_evk_init_pfuze100(u32 int_gpio)
+{
+ if (int_gpio)
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(0, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6sl_ntx_io.c b/arch/arm/mach-mx6/mx6sl_ntx_io.c
new file mode 100755
index 00000000..403509d1
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_ntx_io.c
@@ -0,0 +1,2605 @@
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/iomux-mx6sl.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+
+
+#include <generated/autoconf.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/miscdevice.h>
+#include <linux/irq.h>
+#include <linux/freezer.h>
+
+#include <mach/common.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <mach/iomux-v3.h>
+
+
+#include <linux/mfd/ricoh619.h>
+#include <linux/rtc/rtc-ricoh619.h>
+#include <linux/power/ricoh619_battery.h>
+#include <linux/regulator/ricoh619-regulator.h>
+
+#define GDEBUG 0
+#include <linux/gallen_dbg.h>
+
+//#define GPIOFN_PWRKEY 1
+
+//#ifdef GPIOFN_PWRKEY//[
+ #include "../../../drivers/input/keyboard/gpiofn.h"
+//#endif //]GPIOFN_PWRKEY
+
+#include "../../../drivers/video/mxc/lk_tps65185.h"
+#include "../../../drivers/video/mxc/lk_fp9928.h"
+
+
+//#define _WIFI_ALWAYS_ON_ // wifi always on for startic
+
+#include "board-mx6sl_ntx.h"
+#include "ntx_hwconfig.h"
+
+#define DEVICE_NAME "ntx_io" // "pvi_io"
+#define DEVICE_MINJOR 190
+
+#define CM_PLATFORM 164
+#define CM_HWCONFIG 165
+#define CM_SET_HWCONFIG 166
+
+#define CM_SD_IN 117
+#define AC_IN 118
+#define CM_PWR_ON2 112
+#define CM_AUDIO_PWR 113
+#define CM_POWER_BTN 110
+#define CM_USB_Plug_IN 108
+#define CM_AC_CK 109
+#define CM_CHARGE_STATUS 204
+#define CM_nLED 101
+#define CM_nLED_CPU 102
+#define POWER_OFF_COMMAND 0xC0 // 192
+#define SYS_RESET_COMMAND 193 // Joseph 091223
+#define GET_LnBATT_CPU 0XC2 // 194
+#define GET_VBATT_TH 0XC3 // 195
+#define CM_SIGUSR1 104
+//kay 20081110 for detecting SD write protect
+#define CM_SD_PROTECT 120
+#define SYS_AUTO_POWER_ON 0xC4 // 196 Joseph 120620
+
+//20090216 for detecting controller
+#define CM_CONTROLLER 121
+
+//20090416 for detecting controller
+#define CM_USB_AC_STATUS 122
+#define CM_RTC_WAKEUP_FLAG 123
+#define CM_SYSTEM_RESET 124
+#define CM_USB_HOST_PWR 125
+#define CM_BLUETOOTH_PWR 126
+#define CM_TELLPID 99
+#define CM_LED_BLINK 127
+#define CM_TOUCH_LOCK 128
+#define CM_DEVICE_MODULE 129
+#define CM_BLUETOOTH_RESET 130
+#define CM_DEVICE_INFO 131
+
+//Joseph 091211 for 3G
+#define CM_3G_POWER 150
+#define CM_3G_RF_OFF 151
+#define CM_3G_RESET 152
+#define CM_3G_GET_WAKE_STATUS 153
+
+//Joseph 091209
+#define CM_ROTARY_STATUS 200
+#define CM_GET_KEY_STATUS 201
+#define CM_GET_WHEEL_KEY_STATUS 202
+#define CM_GET_KL25_STATUS 203
+#define CM_GET_KL25_ACTION 199
+#define POWER_KEEP_COMMAND 205
+#define CM_GET_BATTERY_STATUS 206
+#define CM_SET_ALARM_WAKEUP 207
+#define CM_WIFI_CTRL 208
+#define CM_ROTARY_ENABLE 209
+
+#define CM_GET_UP_VERSION 215
+
+// gallen 100621
+// Audio functions ...
+#define CM_AUDIO_GET_VOLUME 230
+#define CM_AUDIO_SET_VOLUME 240
+#define CM_FRONT_LIGHT_SET 241
+#define CM_FRONT_LIGHT_AVAILABLE 242
+#define CM_FRONT_LIGHT_DUTY 243
+#define CM_FRONT_LIGHT_FREQUENCY 244
+#define CM_FRONT_LIGHT_R_EN 245
+#define CM_FRONT_LIGHT_HT68F20_SETDUTY 246
+#define CM_FRONT_LIGHT_GETDUTY 247
+
+#define CM_GET_KEYS 107
+
+
+#ifdef GPIOFN_PWRKEY//[
+static void power_key_chk(unsigned long v);
+
+static int PWR_SW_func(int iGPIOVal)
+{
+ printk("[%s]\n",__FUNCTION__);
+ power_key_chk(0);
+}
+
+static GPIODATA gtNTX_PWR_GPIO_data = {
+ .pfnGPIO = PWR_SW_func,
+ .uGPIO = gMX6SL_PWR_SW,
+ .szName = "PWR_SW",
+ .tPADCtrl = MX50_PAD_CSPI_MISO__GPIO_4_10,
+ .uiIRQType = IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,
+ .iWakeup = 1,
+};
+
+#endif //]GPIOFN_PWRKEY
+
+
+unsigned short __EBRMAIN_PID__ = 0;
+
+unsigned char __USB_ADAPTOR__=0;
+EXPORT_SYMBOL(__USB_ADAPTOR__);
+
+static int Driver_Count = -1;
+unsigned char __TOUCH_LOCK__= 0;
+int gSleep_Mode_Suspend;
+
+extern volatile NTX_HWCONFIG *gptHWCFG;
+
+extern volatile int giISD_3V3_ON_Ctrl ;
+
+typedef enum __DEV_MODULE_NAME{
+ EB500=0,
+ EB600=1,
+ EB600E=2,
+ EB600EM=3,
+ COOKIE=4,
+}__dev_module_name;
+
+typedef enum __DEV_MODULE_CPU{
+ CPU_S3C2410=0,
+ CPU_S3C2440=1,
+ CPU_S3C2416=2,
+ CPU_CORETEX_A8=3,
+ CPU_COOKIE=4,
+}__dev_module_cpu;
+
+typedef enum __DEV_MODULE_CONTROLLER{
+ CONTROLLER_PVI=0,
+ CONTROLLER_EPSON=1,
+ CONTROLLER_SW=2,
+}__dev_module_controller;
+
+typedef enum __DEV_MODULE_WIFI{
+ WIFI_NONE=0,
+ WIFI_MARVELL=1,
+ WIFI_OTHER=2,
+}__dev_module_wifi;
+
+typedef enum __DEV_MODULE_BLUETOOTH{
+ BLUETOOTH_NONE=0,
+ BLUETOOTH_TI=1,
+ BLUETOOTH_CSR=2,
+}__devi_module_bluetooth;
+
+struct ebook_device_info {
+ char device_name;
+ char cpu;
+ char controller;
+ char wifi;
+ char bluetooth;
+};
+
+
+static volatile int giFL_ON=0;
+
+static unsigned short FL_table0[100]={
+0x0001,0x0006,0x0007,0x0009,0x000C,0x000D,0x000E,0x000F,0x0011,0x0012,
+0x0014,0x0015,0x0017,0x0018,0x001A,0x001B,0x001C,0x001D,0x001F,0x0020,
+0x0022,0x0023,0x0025,0x0027,0x0028,0x002A,0x002B,0x002D,0x002E,0x0030,
+0x0031,0x0033,0x0035,0x0036,0x0038,0x0039,0x003B,0x003C,0x003E,0x0040,
+0x0041,0x0043,0x0044,0x0046,0x0047,0x0049,0x004A,0x0051,0x0057,0x005D,
+0x0063,0x006A,0x0070,0x0076,0x007C,0x0083,0x0089,0x008F,0x0095,0x009C,
+0x00A2,0x00A8,0x00AE,0x00B5,0x00B9,0x00BB,0x00C1,0x00C7,0x00CE,0x00D4,
+0x00DA,0x00E0,0x00E7,0x00ED,0x00F3,0x00F9,0x0100,0x0106,0x010C,0x0112,
+0x0118,0x011F,0x0125,0x012B,0x0131,0x0138,0x013E,0x0144,0x014A,0x0151,
+0x0157,0x015D,0x0163,0x016A,0x0170,0x0176,0x017C,0x0183,0x0189,0x018F
+};
+
+struct front_light_setting {
+ unsigned short fl_r_en;
+ unsigned short freq;
+ unsigned short duty;
+};
+
+static struct front_light_setting FL_table[][100]={
+{// TABLE1
+{0,20000,3}, {0,20000,5}, {0,20000,7}, {0,20000,9}, {0,20000,11},
+{0,20000,13}, {0,20000,15}, {0,20000,17}, {0,20000,19}, {0,20000,21},
+{0,20000,23}, {0,20000,25}, {0,20000,27}, {0,20000,30}, {0,20000,33},
+{0,20000,36}, {0,20000,39}, {0,20000,42}, {0,20000,46}, {0,20000,51},
+{0,20000,54}, {0,20000,59}, {0,20000,63}, {0,20000,68}, {0,20000,71},
+{0,20000,74}, {0,20000,87}, {0,20000,99}, {0,20000,112}, {0,20000,124},
+{0,20000,137}, {0,20000,149}, {0,20000,162}, {0,20000,174}, {0,20000,185},
+{0,20000,193}, {0,20000,206}, {0,20000,218}, {0,20000,231}, {0,20000,243},
+{0,20000,256}, {1,20000,45}, {1,20000,46}, {1,20000,47}, {1,20000,48},
+{1,20000,49}, {1,20000,50}, {1,20000,51}, {1,20000,53}, {1,20000,55},
+{1,20000,56}, {1,20000,58}, {1,20000,60}, {1,20000,63}, {1,20000,65},
+{1,20000,68}, {1,20000,70}, {1,20000,75}, {1,20000,78}, {1,20000,80},
+{1,20000,85}, {1,20000,88}, {1,20000,90}, {1,20000,95}, {1,20000,100},
+{1,20000,105}, {1,20000,110}, {1,20000,115}, {1,20000,120}, {1,20000,125},
+{1,20000,130}, {1,20000,135}, {1,20000,140}, {1,20000,145}, {1,20000,150},
+{1,20000,155}, {1,20000,160}, {1,20000,170}, {1,20000,180}, {1,20000,190},
+{1,20000,200}, {1,20000,210}, {1,20000,220}, {1,20000,230}, {1,20000,240},
+{1,20000,250}, {1,20000,260}, {1,20000,270}, {1,20000,280}, {1,20000,290},
+{1,20000,300}, {1,20000,310}, {1,20000,320}, {1,20000,330}, {1,20000,340},
+{1,20000,350}, {1,20000,360}, {1,20000,370}, {1,20000,380}, {1,20000,400}
+},
+{// TABLE2
+{0,20000, 3 }, {0,20000, 4 }, {0,20000, 5 }, {0,20000, 6 }, {0,20000, 7 }, // 1%
+{0,20000, 8 }, {0,20000, 8 }, {0,20000, 9 }, {0,20000, 9 }, {0,20000, 10 }, //
+{0,20000, 12 }, {0,20000, 16 }, {0,20000, 19 }, {0,20000, 22 }, {0,20000, 25 }, // 11%
+{0,20000, 30 }, {0,20000, 38 }, {0,20000, 45 }, {0,20000, 52 }, {0,20000, 60 }, //
+{0,20000, 75 }, {0,20000,100 }, {0,20000,125 }, {0,20000,145 }, {0,20000,160 }, // 21%
+{0,20000,160 }, {0,20000,160 }, {0,20000,160 }, {0,20000,160 }, {1,20000, 20 }, //
+{1,20000, 22 }, {1,20000, 24 }, {1,20000, 26 }, {1,20000, 28 }, {1,20000, 30 }, // 31%
+{1,20000, 32 }, {1,20000, 34 }, {1,20000, 36 }, {1,20000, 38 }, {1,20000, 40 }, //
+{1,20000, 42 }, {1,20000, 44 }, {1,20000, 46 }, {1,20000, 48 }, {1,20000, 50 }, // 41%
+{1,20000, 52 }, {1,20000, 54 }, {1,20000, 56 }, {1,20000, 58 }, {1,20000, 60 }, //
+{1,20000, 62 }, {1,20000, 65 }, {1,20000, 69 }, {1,20000, 74 }, {1,20000, 80 }, // 51%
+{1,20000, 84 }, {1,20000, 88 }, {1,20000, 92 }, {1,20000, 96 }, {1,20000,100 }, //
+{1,20000,106 }, {1,20000,112 }, {1,20000,118 }, {1,20000,124 }, {1,20000,130 }, // 61%
+{1,20000,136 }, {1,20000,142 }, {1,20000,148 }, {1,20000,154 }, {1,20000,160 }, //
+{1,20000,168 }, {1,20000,176 }, {1,20000,184 }, {1,20000,192 }, {1,20000,200 }, // 71%
+{1,20000,206 }, {1,20000,212 }, {1,20000,218 }, {1,20000,224 }, {1,20000,230 }, //
+{1,20000,238 }, {1,20000,246 }, {1,20000,254 }, {1,20000,262 }, {1,20000,270 }, // 81%
+{1,20000,278 }, {1,20000,286 }, {1,20000,294 }, {1,20000,302 }, {1,20000,310 }, //
+{1,20000,318 }, {1,20000,326 }, {1,20000,334 }, {1,20000,342 }, {1,20000,350 }, // 91%
+{1,20000,360 }, {1,20000,370 }, {1,20000,380 }, {1,20000,330 }, {1,20000,400 }
+},
+{// TABLE3
+{0,10000,6},{0,10000,28},{0,10000,44},{0,10000,62},{0,10000,87},
+{0,10000,100},{0,10000,112},{0,10000,128},{0,10000,147},{0,10000,153},
+{0,10000,165},{0,10000,172},{0,10000,181},{0,10000,194},{0,10000,215},
+{0,10000,225},{0,10000,247},{0,10000,265},{0,10000,287},{0,10000,490},
+{0,10000,500},{0,10000,515},{0,10000,537},{0,10000,553},{0,10000,587},
+{0,10000,618},{0,10000,681},{0,10000,737},{0,10000,799},{1,10000,6},
+{1,10000,12},{1,10000,19},{1,10000,25},{1,10000,28},{1,10000,37},
+{1,10000,44},{1,10000,53},{1,10000,56},{1,10000,62},{1,10000,69},
+{1,10000,75},{1,10000,81},{1,10000,87},{1,10000,94},{1,10000,100},
+{1,10000,103},{1,10000,109},{1,10000,116},{1,10000,122},{1,10000,128},
+{1,10000,134},{1,10000,137},{1,10000,144},{1,10000,150},{1,10000,165},
+{1,10000,178},{1,10000,187},{1,10000,197},{1,10000,206},{1,10000,215},
+{1,10000,225},{1,10000,237},{1,10000,250},{1,10000,262},{1,10000,275},
+{1,10000,287},{1,10000,300},{1,10000,312},{1,10000,325},{1,10000,337},
+{1,10000,350},{1,10000,365},{1,10000,381},{1,10000,393},{1,10000,409},
+{1,10000,425},{1,10000,440},{1,10000,456},{1,10000,471},{1,10000,484},
+{1,10000,496},{1,10000,509},{1,10000,524},{1,10000,540},{1,10000,553},
+{1,10000,568},{1,10000,584},{1,10000,599},{1,10000,615},{1,10000,631},
+{1,10000,646},{1,10000,659},{1,10000,677},{1,10000,696},{1,10000,712},
+{1,10000,731},{1,10000,746},{1,10000,765},{1,10000,784},{1,10000,799}
+},
+{// TABLE4
+{0,20000,2}, {0,20000,5}, {0,20000,8}, {0,20000,12}, {0,20000,16},
+{0,20000,22}, {0,20000,28}, {0,20000,36}, {0,20000,39}, {0,20000,45},
+{0,20000,52}, {0,20000,56}, {0,20000,61}, {0,20000,67}, {0,20000,75},
+{0,20000,81}, {0,20000,87}, {0,20000,94}, {0,20000,100}, {0,20000,106},
+{0,20000,112}, {0,20000,119}, {0,20000,131}, {0,20000,137}, {0,20000,144},
+{0,20000,156}, {0,20000,175}, {0,20000,188}, {0,20000,212}, {0,20000,231},
+{0,20000,237}, {0,20000,250}, {0,20000,256}, {0,20000,262}, {0,20000,268},
+{0,20000,275}, {0,20000,287}, {0,20000,293}, {0,20000,306}, {0,20000,331},
+{0,20000,337}, {0,20000,350}, {0,20000,368}, {1,20000,67}, {1,20000,69},
+{1,20000,72}, {1,20000,75}, {1,20000,81}, {1,20000,87}, {1,20000,94},
+{1,20000,100}, {1,20000,106}, {1,20000,112}, {1,20000,119}, {1,20000,125},
+{1,20000,131}, {1,20000,137}, {1,20000,144}, {1,20000,150}, {1,20000,156},
+{1,20000,162}, {1,20000,169}, {1,20000,175}, {1,20000,181}, {1,20000,185},
+{1,20000,188}, {1,20000,194}, {1,20000,200}, {1,20000,206}, {1,20000,212},
+{1,20000,219}, {1,20000,225}, {1,20000,231}, {1,20000,237}, {1,20000,244},
+{1,20000,250}, {1,20000,256}, {1,20000,262}, {1,20000,268}, {1,20000,275},
+{1,20000,281}, {1,20000,287}, {1,20000,293}, {1,20000,300}, {1,20000,306},
+{1,20000,312}, {1,20000,318}, {1,20000,325}, {1,20000,331}, {1,20000,337},
+{1,20000,343}, {1,20000,350}, {1,20000,356}, {1,20000,362}, {1,20000,368},
+{1,20000,375}, {1,20000,381}, {1,20000,387}, {1,20000,393}, {1,20000,400}
+},
+{// TABLE5
+{0,20000,39},{0,20000,41},{0,20000,42},{0,20000,45},{0,20000,47},
+{0,20000,48},{0,20000,50},{0,20000,53},{0,20000,56},{0,20000,59},
+{0,20000,62},{0,20000,64},{0,20000,67},{0,20000,70},{0,20000,73},
+{0,20000,75},{0,20000,81},{0,20000,87},{0,20000,94},{0,20000,100},
+{0,20000,106},{0,20000,112},{0,20000,119},{0,20000,125},{0,20000,131},
+{0,20000,137},{0,20000,144},{0,20000,150},{0,20000,156},{0,20000,162},
+{0,20000,168},{0,20000,175},{0,20000,181},{0,20000,185},{0,20000,194},
+{0,20000,200},{0,20000,206},{0,20000,212},{0,20000,219},{0,20000,225},
+{0,20000,231},{0,20000,237},{0,20000,244},{0,20000,250},{1,20000,67},
+{1,20000,70},{1,20000,73},{1,20000,75},{1,20000,81},{1,20000,87},
+{1,20000,94},{1,20000,100},{1,20000,106},{1,20000,112},{1,20000,119},
+{1,20000,125},{1,20000,131},{1,20000,137},{1,20000,144},{1,20000,150},
+{1,20000,156},{1,20000,162},{1,20000,169},{1,20000,175},{1,20000,181},
+{1,20000,188},{1,20000,194},{1,20000,200},{1,20000,206},{1,20000,212},
+{1,20000,219},{1,20000,225},{1,20000,231},{1,20000,237},{1,20000,244},
+{1,20000,250},{1,20000,256},{1,20000,262},{1,20000,268},{1,20000,275},
+{1,20000,281},{1,20000,287},{1,20000,293},{1,20000,300},{1,20000,306},
+{1,20000,312},{1,20000,318},{1,20000,325},{1,20000,331},{1,20000,337},
+{1,20000,343},{1,20000,350},{1,20000,356},{1,20000,362},{1,20000,368},
+{1,20000,375},{1,20000,381},{1,20000,387},{1,20000,393},{1,20000,400}
+},
+{// TABLE6
+{0,20000,39},{0,20000,42},{0,20000,45},{0,20000,47},{0,20000,50},
+{0,20000,53},{0,20000,59},{0,20000,62},{0,20000,64},{0,20000,67},
+{0,20000,70},{0,20000,73},{0,20000,75},{0,20000,81},{0,20000,87},
+{0,20000,94},{0,20000,100},{0,20000,106},{0,20000,112},{0,20000,119},
+{0,20000,125},{0,20000,131},{0,20000,137},{0,20000,144},{0,20000,150},
+{0,20000,156},{0,20000,162},{0,20000,168},{0,20000,175},{0,20000,181},
+{0,20000,185},{0,20000,194},{0,20000,200},{0,20000,206},{0,20000,212},
+{0,20000,219},{0,20000,225},{0,20000,231},{0,20000,237},{0,20000,244},
+{0,20000,250},{0,20000,260},{0,20000,270},{0,20000,280},{1,20000,55},
+{1,20000,58},{1,20000,63},{1,20000,68},{1,20000,75},{1,20000,81},
+{1,20000,87},{1,20000,94},{1,20000,100},{1,20000,106},{1,20000,112},
+{1,20000,119},{1,20000,125},{1,20000,131},{1,20000,137},{1,20000,144},
+{1,20000,150},{1,20000,156},{1,20000,162},{1,20000,169},{1,20000,175},
+{1,20000,181},{1,20000,188},{1,20000,194},{1,20000,200},{1,20000,206},
+{1,20000,212},{1,20000,219},{1,20000,225},{1,20000,231},{1,20000,237},
+{1,20000,244},{1,20000,250},{1,20000,256},{1,20000,262},{1,20000,268},
+{1,20000,275},{1,20000,281},{1,20000,287},{1,20000,293},{1,20000,300},
+{1,20000,306},{1,20000,312},{1,20000,318},{1,20000,325},{1,20000,331},
+{1,20000,337},{1,20000,343},{1,20000,350},{1,20000,356},{1,20000,362},
+{1,20000,368},{1,20000,375},{1,20000,381},{1,20000,387},{1,20000,400}
+},
+{ // TABLE7
+{0,20000,39}, {0,20000,41}, {0,20000,42}, {0,20000,45}, {0,20000,47},
+{0,20000,48}, {0,20000,50}, {0,20000,53}, {0,20000,56}, {0,20000,59},
+{0,20000,62}, {0,20000,64}, {0,20000,67}, {0,20000,70}, {0,20000,73},
+{0,20000,75}, {0,20000,81}, {0,20000,87}, {0,20000,94}, {0,20000,106},
+{0,20000,119}, {0,20000,131}, {0,20000,144}, {0,20000,156}, {0,20000,168},
+{0,20000,181}, {0,20000,194}, {0,20000,206}, {0,20000,219}, {0,20000,231},
+{0,20000,244}, {0,20000,255}, {0,20000,265}, {0,20000,275}, {0,20000,285},
+{0,20000,295}, {0,20000,305}, {0,20000,315}, {0,20000,325}, {0,20000,335},
+{0,20000,345}, {0,20000,355}, {0,20000,365}, {0,20000,375}, {1,20000,67},
+{1,20000,70}, {1,20000,73}, {1,20000,75}, {1,20000,81}, {1,20000,87},
+{1,20000,94}, {1,20000,100}, {1,20000,106}, {1,20000,112}, {1,20000,119},
+{1,20000,125}, {1,20000,131}, {1,20000,137}, {1,20000,144}, {1,20000,150},
+{1,20000,156}, {1,20000,162}, {1,20000,169}, {1,20000,175}, {1,20000,181},
+{1,20000,188}, {1,20000,194}, {1,20000,200}, {1,20000,206}, {1,20000,212},
+{1,20000,219}, {1,20000,225}, {1,20000,231}, {1,20000,237}, {1,20000,244},
+{1,20000,250}, {1,20000,256}, {1,20000,262}, {1,20000,268}, {1,20000,275},
+{1,20000,281}, {1,20000,287}, {1,20000,293}, {1,20000,300}, {1,20000,306},
+{1,20000,312}, {1,20000,318}, {1,20000,325}, {1,20000,331}, {1,20000,337},
+{1,20000,343}, {1,20000,350}, {1,20000,356}, {1,20000,362}, {1,20000,368},
+{1,20000,375}, {1,20000,381}, {1,20000,387}, {1,20000,393}, {1,20000,400}
+},
+{// TABLE8
+{0,20000,18},{0,20000,24},{0,20000,30},{0,20000,41},{0,20000,49},
+{0,20000,62},{0,20000,71},{0,20000,82},{0,20000,93},{0,20000,110},
+{0,20000,132},{0,20000,150},{0,20000,170},{0,20000,195},{0,20000,216},
+{0,20000,238},{0,20000,252},{0,20000,266},{0,20000,280},{1,20000,30},
+{1,20000,32},{1,20000,33},{1,20000,35},{1,20000,37},{1,20000,39},
+{1,20000,41},{1,20000,43},{1,20000,45},{1,20000,47},{1,20000,49},
+{1,20000,51},{1,20000,53},{1,20000,55},{1,20000,57},{1,20000,59},
+{1,20000,61},{1,20000,63},{1,20000,65},{1,20000,67},{1,20000,69},
+{1,20000,71},{1,20000,73},{1,20000,75},{1,20000,77},{1,20000,80},
+{1,20000,84},{1,20000,87},{1,20000,89},{1,20000,91},{1,20000,93},
+{1,20000,96},{1,20000,99},{1,20000,102},{1,20000,104},{1,20000,106},
+{1,20000,109},{1,20000,112},{1,20000,114},{1,20000,116},{1,20000,118},
+{1,20000,120},{1,20000,123},{1,20000,126},{1,20000,128},{1,20000,131},
+{1,20000,133},{1,20000,136},{1,20000,138},{1,20000,140},{1,20000,143},
+{1,20000,146},{1,20000,149},{1,20000,152},{1,20000,155},{1,20000,158},
+{1,20000,160},{1,20000,162},{1,20000,165},{1,20000,167},{1,20000,172},
+{1,20000,175},{1,20000,178},{1,20000,185},{1,20000,192},{1,20000,196},
+{1,20000,200},{1,20000,204},{1,20000,208},{1,20000,216},{1,20000,223},
+{1,20000,230},{1,20000,237},{1,20000,245},{1,20000,248},{1,20000,252},
+{1,20000,257},{1,20000,262},{1,20000,268},{1,20000,274},{1,20000,280},
+},
+{//TABLE9
+{0,20000,18}, {0,20000,21}, {0,20000,26}, {0,20000,38}, {0,20000,46},
+{0,20000,58}, {0,20000,67}, {0,20000,77}, {0,20000,90}, {0,20000,101},
+{0,20000,123}, {0,20000,140}, {0,20000,160}, {0,20000,190}, {0,20000,210},
+{0,20000,230}, {0,20000,245}, {0,20000,258}, {0,20000,270},{1,20000,24},
+{1,20000,26}, {1,20000,28}, {1,20000,30}, {1,20000,32}, {1,20000,34},
+{1,20000,36}, {1,20000,38}, {1,20000,40}, {1,20000,42}, {1,20000,44},
+{1,20000,46}, {1,20000,48}, {1,20000,50}, {1,20000,52}, {1,20000,54},
+{1,20000,56}, {1,20000,58}, {1,20000,60}, {1,20000,62}, {1,20000,64},
+{1,20000,66}, {1,20000,68}, {1,20000,70}, {1,20000,72}, {1,20000,74},
+{1,20000,76}, {1,20000,78}, {1,20000,80}, {1,20000,82}, {1,20000,84},
+{1,20000,86}, {1,20000,88}, {1,20000,90}, {1,20000,92}, {1,20000,94},
+{1,20000,96}, {1,20000,98}, {1,20000,100}, {1,20000,102}, {1,20000,104},
+{1,20000,106}, {1,20000,108}, {1,20000,110}, {1,20000,112}, {1,20000,114},
+{1,20000,116}, {1,20000,118}, {1,20000,120}, {1,20000,122}, {1,20000,124},
+{1,20000,126}, {1,20000,128}, {1,20000,130}, {1,20000,132}, {1,20000,134},
+{1,20000,136}, {1,20000,138}, {1,20000,142}, {1,20000,144}, {1,20000,148},
+{1,20000,152}, {1,20000,158}, {1,20000,161}, {1,20000,163}, {1,20000,166},
+{1,20000,169}, {1,20000,175}, {1,20000,180}, {1,20000,184}, {1,20000,187},
+{1,20000,192}, {1,20000,196}, {1,20000,199}, {1,20000,203}, {1,20000,207},
+{1,20000,211}, {1,20000,215}, {1,20000,219}, {1,20000,226}, {1,20000,230}
+}
+};
+
+struct delayed_work FL_off;
+
+static void FL_module_off(void);
+
+void FL_off_func(struct work_struct *work);
+int FL_suspend(void);
+
+//kay for LED thread
+//static unsigned char LED_conitnuous=0;
+static unsigned char LED_conitnuous=1;
+static int LED_Flash_Count;
+static int gKeepPowerAlive;
+int gMxcPowerKeyIrqTriggered, g_power_key_pressed;
+volatile int g_mxc_touch_triggered = 1; //gallen 100420
+int g_wakeup_by_alarm;
+int gWifiEnabled=0;
+static unsigned long g_usb_in_tick; // Joseph 101001
+static int g_ioctl_SD_status, g_ioctl_USB_status, g_ioctl_rotary_status,g_Cus_Ctrl_Led;
+int g_mmc_card_detect_changed; // Joseph 20110125
+static DEFINE_SPINLOCK(led_flash_lock);
+static DECLARE_WAIT_QUEUE_HEAD(LED_blink_WaitQueue);
+static DECLARE_WAIT_QUEUE_HEAD(LED_freeze_WaitQueue);
+static DECLARE_WAIT_QUEUE_HEAD(WheelKey_WaitQueue);
+////////////////////
+
+static unsigned int last_FL_duty = 0;
+static unsigned int current_FL_freq = 0xFFFF;
+
+
+static DECLARE_WAIT_QUEUE_HEAD(Reset_WaitQueue);
+
+extern int gIsCustomerUi;
+
+int ntx_charge_status (void);
+int mxc_usb_plug_getstatus (void);
+
+void led_green (int isOn)
+{
+
+ if(0x03!=gptHWCFG->m_val.bUIConfig) {
+ // do not check charging status in MP/RD mode
+ if(gMX6SL_ON_LED==gMX6SL_CHG_LED&&mxc_usb_plug_getstatus()) {
+ // skip control charge led while charging .
+ return ;
+ }
+ }
+
+
+ if (isOn)
+ gpio_direction_output (gMX6SL_ON_LED,0);
+ else {
+ switch(gptHWCFG->m_val.bPCB) {
+ case 33:
+ // E60Q2X .
+ gpio_direction_output (gMX6SL_ON_LED,1);
+ default :
+ gpio_direction_input (gMX6SL_ON_LED);
+ }
+ }
+}
+
+void led_blue (int isOn)
+{
+
+ switch(gptHWCFG->m_val.bLed) {
+ case 1:
+ if (isOn)
+ gpio_direction_output (gMX6SL_ACT_LED,0);
+ else
+ gpio_direction_input (gMX6SL_ACT_LED);
+ break;
+ }
+}
+
+void led_red (int isOn) {
+ switch(gptHWCFG->m_val.bLed) {
+ //case 0:// Type1 .
+ case 1:// RGB
+ case 2:// RG
+ case 3:// RGH
+ case 7:// WH
+ if (isOn) {
+ gpio_direction_output (gMX6SL_CHG_LED,0);
+ }
+ else {
+ gpio_direction_input (gMX6SL_CHG_LED);
+ }
+ break;
+ }
+}
+
+
+//kay 20090925
+//check WiFi ID
+static int check_hardware_wifi(void)
+{
+ return WIFI_NONE;
+}
+
+//check Bluetooth ID
+static int check_hardware_bt(void)
+{
+ return BLUETOOTH_NONE;
+}
+
+static int check_hardware_cpu(void)
+{
+ return CPU_S3C2440;
+}
+
+//static int check_hardeare_name(void)
+int check_hardware_name(void)
+{
+ static int pcb_id = -1;
+
+ if (0 >= pcb_id) {
+ switch(gptHWCFG->m_val.bPCB)
+ {
+ default:
+ pcb_id = gptHWCFG->m_val.bPCB;
+ break;
+ }
+ printk ("[%s-%d] PCBA ID is %d\n",__func__,__LINE__,pcb_id);
+ }
+
+ return pcb_id;
+}
+EXPORT_SYMBOL(check_hardware_name);
+
+static int check_hardware_controller(void)
+{
+ return CONTROLLER_EPSON;
+}
+
+static void collect_hardware_info(struct ebook_device_info *info)
+{
+ info->cpu = check_hardware_cpu();
+ info->device_name = check_hardware_name();
+ info->controller = check_hardware_controller();
+ info->wifi = check_hardware_wifi();
+ info->bluetooth = check_hardware_bt();
+}
+
+static int openDriver(struct inode *inode,struct file *filp)
+{
+ if(!Driver_Count)
+ Driver_Count++;
+ return 0;
+}
+static int releaseDriver(struct inode *inode,struct file *filp)
+{
+ if(Driver_Count)
+ Driver_Count--;
+ return 0;
+}
+static void bluetooth_reset(int i)
+{
+}
+
+static void bluetooth_pwr(int i)
+{
+}
+
+extern unsigned long g_kl25_result;
+extern unsigned long g_kl25_action;
+extern void ntx_wifi_power_ctrl (int isWifiEnable);
+
+extern u16 msp430_deviceid(void);
+extern void msp430_auto_power(int minutes);
+extern void msp430_power_off(void);
+extern void msp430_pm_restart(void);
+extern void msp430_powerkeep(int n);
+extern int msp430_battery(void);
+extern void msp430_fl_enable (int isEnable);
+
+int ricoh619_restart(void);
+int ricoh619_battery_2_msp430_adc(void);
+int ricoh619_charger_detect(void);
+int ricoh619_dcin_status(void);
+
+extern int ht68f20_write_reg(unsigned int reg, unsigned int value);
+extern unsigned int ht68f20_read_reg(unsigned int reg);
+extern void ht68f20_enable(int isEnable);
+
+extern int up_write_reg(unsigned int reg, unsigned int value);
+extern unsigned int up_read_reg(unsigned int reg);
+
+int g_power_key_debounce; // Joseph 20100921 for ESD
+
+static void fl_pwm_enable (int isEnable)
+{
+ static int s_pwm_enabled=1;
+ if(1==gptHWCFG->m_val.bFL_PWM)
+ {
+ if (s_pwm_enabled != isEnable) {
+ s_pwm_enabled = isEnable;
+ ht68f20_enable (isEnable);
+ if (isEnable) {
+ mxc_iomux_v3_setup_pad (MX6SL_PAD_I2C1_SCL__I2C1_SCL);
+ mxc_iomux_v3_setup_pad (MX6SL_PAD_I2C1_SDA__I2C1_SDA);
+ }
+ else {
+ mxc_iomux_v3_setup_pad (MX6SL_PAD_I2C1_SCL__GPIO_3_12);
+ mxc_iomux_v3_setup_pad (MX6SL_PAD_I2C1_SDA__GPIO_3_13);
+ }
+ }
+ }
+}
+
+unsigned long long hwconfig = 0x0000000011000001LL;
+EXPORT_SYMBOL(hwconfig);
+unsigned char platform_type[32];
+EXPORT_SYMBOL(platform_type);
+
+static int __init early_hw(char *p)
+{
+ hwconfig = simple_strtoull(p, NULL, 16);
+ printk("hwconfig: %16llX\n", hwconfig);
+ return 0;
+}
+early_param("hwconfig", early_hw);
+
+//to parse hardware configuration bits
+static int __init early_board(char *p)
+{
+ strncpy(platform_type, p, sizeof(platform_type));
+ printk("board: %s\n", platform_type);
+ return 0;
+}
+early_param("board", early_board);
+
+int power_key_status (void)
+{
+ return gpio_get_value (gMX6SL_PWR_SW)?0:1;
+}
+
+int fl_set_percentage(int iFL_Percentage)
+{
+ int iRet = 0;
+ int p=iFL_Percentage;
+
+
+ if(0==gptHWCFG->m_val.bFrontLight)
+ return -1;
+
+ if(1==gptHWCFG->m_val.bFL_PWM)
+ {
+ // HT68F20
+
+ if (p) {
+ fl_pwm_enable (1);
+ if(delayed_work_pending(&FL_off)){
+ cancel_delayed_work_sync(&FL_off);
+ printk("FL_off delayed work canceled");
+ }
+ printk ("\nset front light level : %d\n",p);
+ if(p>0 && p<=100)
+ {
+ // temporary table
+ // for first 70 levels, fl_r_en = 0
+ // duty = 27,34,41 .... 510
+ // for 71~100 levels, fl_r_en =1
+ // duty = 162, 174, 186, 198 ... 510
+ int fl_r_en;
+ int duty;
+ if(p<=70){
+ fl_r_en = 0;
+ duty = 20 + p*7;
+ }
+ else {
+ fl_r_en = 1;
+ duty = 150 + (p-70)*12;
+ }
+ if (last_FL_duty >= p)
+ gpio_direction_output (MX6SL_FL_R_EN, fl_r_en);
+
+ ht68f20_write_reg (0xA6, duty&0xFF); // Set PWM duty
+ ht68f20_write_reg (0xA7, duty>>8);
+ printk ("Set front light duty : %d\n",duty);
+
+ if (last_FL_duty < p)
+ gpio_direction_output (MX6SL_FL_R_EN, fl_r_en);
+ }
+ else{
+ printk("Wrong number! level range from 0 to 100\n");
+ }
+ if (0 == last_FL_duty){
+ ht68f20_write_reg (0xA3, 0x01); // enable front light pwm
+
+ msleep(100);
+ gpio_direction_output(MX6SL_FL_EN,giFL_ON);
+ }
+ }
+ else if(last_FL_duty != 0){
+ printk ("FL PWM off command\n");
+ ht68f20_write_reg(0xA3, 0);
+ schedule_delayed_work(&FL_off, 120);
+ }
+ last_FL_duty = p;
+
+ }
+ else
+ {
+ if (p) {
+ if(delayed_work_pending(&FL_off)){
+ cancel_delayed_work_sync(&FL_off);
+ printk("FL_off delayed work canceled");
+ }
+ printk ("\nset front light level : %d\n",p);
+ if(p>0 && p<=100)
+ {
+ if( gptHWCFG->m_val.bFrontLight == 3){ //TABLE0a
+ up_write_reg (0xA5, 0x0100);
+ up_write_reg (0xA4, 0x9000);
+ up_write_reg (0xA7, FL_table0[p-1]&0xFF00);
+ up_write_reg (0xA6, FL_table0[p-1]<<8);
+ printk("PWMCNT : 0x%04x\n", FL_table0[p-1]);
+ }
+ else if( gptHWCFG->m_val.bFrontLight == 1 || gptHWCFG->m_val.bFrontLight == 2 ){ //TABLE0, TABLE0+
+ if (0 == last_FL_duty){
+ up_write_reg (0xA5, 0x0100);
+ up_write_reg (0xA4, 0x9000);
+ }
+ if(p<=50){
+ gpio_direction_output(MX6SL_FL_R_EN,0);
+ up_write_reg (0xA7, FL_table0[2*(p-1)]&0xFF00);
+ up_write_reg (0xA6, FL_table0[2*(p-1)]<<8);
+ printk("PWMCNT : 0x%04x\n", FL_table0[2*(p-1)]);
+ }else{
+ gpio_direction_output(MX6SL_FL_R_EN,1);
+ up_write_reg (0xA7, FL_table0[p-1]&0xFF00);
+ up_write_reg (0xA6, FL_table0[p-1]<<8);
+ printk("PWMCNT : 0x%04x\n", FL_table0[p-1]);
+ }
+ }
+ else{
+ int t_no = gptHWCFG->m_val.bFrontLight-4; // mapping hwconfig to FL_table
+ int freq = 8000000/FL_table[t_no][p-1].freq;
+
+ if (30 == gptHWCFG->m_val.bPCB && p==5) { //E606E2
+ p=1;
+ }
+
+ if (last_FL_duty >= p)
+ gpio_direction_output (MX6SL_FL_R_EN, FL_table[t_no][p-1].fl_r_en);
+
+ if( freq != current_FL_freq){
+ printk ("Set front light Frequency : %d\n",FL_table[t_no][p-1].freq);
+ up_write_reg (0xA5, freq&0xFF00); // Set Frequency 8M/freq
+ up_write_reg (0xA4, freq<<8);
+ current_FL_freq = freq;
+ }
+ up_write_reg (0xA7, FL_table[t_no][p-1].duty&0xFF00); // Set PWM duty
+ up_write_reg (0xA6, FL_table[t_no][p-1].duty<<8);
+ printk ("Set front light duty : %d\n",FL_table[t_no][p-1].duty);
+
+ if (last_FL_duty < p)
+ gpio_direction_output (MX6SL_FL_R_EN, FL_table[t_no][p-1].fl_r_en);
+ }
+ }
+ else{
+ printk("Wrong number! level range from 0 to 100\n");
+ }
+ if (0 == last_FL_duty){
+ up_write_reg (0xA1, 0xFF00); // Disable front light auto off timer
+ up_write_reg (0xA2, 0xFF00);
+
+ up_write_reg (0xA3, 0x0100); // enable front light pwm
+
+ msleep(100);
+ gpio_direction_output(MX6SL_FL_EN,giFL_ON);
+ msp430_fl_enable (1);
+ }
+ }
+ else if(last_FL_duty != 0){
+ printk ("FL PWM off command\n");
+ up_write_reg(0xA3, 0);
+ schedule_delayed_work(&FL_off, 120);
+ }
+ last_FL_duty = p;
+ }
+ return iRet;
+}
+
+
+
+
+static void ntx_system_reset(const char *pszDomain)
+{
+ if(pszDomain) {
+ printk("%s() ---%s reset ---\n",__FUNCTION__,pszDomain);
+ }
+
+ if(0!=gptHWCFG->m_val.bFrontLight){
+ up_write_reg (0xA3, 0);
+ msleep (1200);
+
+ FL_module_off();
+ }
+
+ while (1) {
+ gKeepPowerAlive = 0;
+ if (1==gptHWCFG->m_val.bPMIC) {
+ // RC5T19 .
+ printk("%s() --- RC5T19 restarting system ---\n",__FUNCTION__);
+ ricoh619_restart ();
+ }
+ else {
+ printk("%s() --- MSP430 restarting system ---\n",__FUNCTION__);
+ msp430_pm_restart();
+ }
+ sleep_on_timeout(&Reset_WaitQueue, 14*HZ/10);
+ }
+}
+
+static void ntx_system_poweroff(const char *pszDomain)
+{
+ if(pszDomain) {
+ printk("%s() ---%s poweroff ---\n",__FUNCTION__,pszDomain);
+ }
+ if (!gKeepPowerAlive) {
+
+ if(0!=gptHWCFG->m_val.bFrontLight){
+
+ if(0==gptHWCFG->m_val.bFL_PWM) {
+ // FL is controlled by MSP430 .
+ up_write_reg (0xA3, 0);
+ }
+
+ msleep (1200);
+
+ FL_module_off();
+ }
+
+ LED_conitnuous = 0;
+ led_green(0);
+ while (1) {
+ printk("Kernel---Power Down ---\n");
+ if(1==gptHWCFG->m_val.bPMIC)
+ ricoh619_power_off();
+ else
+ msp430_power_off();
+ sleep_on_timeout(&Reset_WaitQueue, 14*HZ/10);
+ }
+ }
+ else {
+ printk("Kernel---in keep alive mode ---\n");
+ }
+}
+
+static int ioctlDriver(struct file *filp, unsigned int command, unsigned long arg)
+{
+ unsigned long i = 0, temp;
+ unsigned int p = arg;//*(unsigned int *)arg;
+ struct ebook_device_info info;
+
+ if(!Driver_Count){
+ printk("pvi_io : do not open\n");
+ return -1;
+ }
+
+ switch(command)
+ {
+ case POWER_OFF_COMMAND:
+ ntx_system_poweroff("POWER_OFF_COMMAND");
+ break;
+
+ case SYS_RESET_COMMAND:
+ ntx_system_reset("SYS_RESET_COMMAND");
+ break;
+
+ case SYS_AUTO_POWER_ON:
+ msp430_auto_power(p);
+ ntx_system_reset("SYS_AUTO_POWER_ON");
+ break;
+
+ case POWER_KEEP_COMMAND:
+ printk("Kernel---System Keep Alive --- %d\n",p);
+ gKeepPowerAlive=p;
+ if(1==gptHWCFG->m_val.bPMIC)
+ break;
+ if (gKeepPowerAlive) {
+ msp430_powerkeep(1);
+ wake_up_interruptible(&LED_freeze_WaitQueue);
+ }
+ else
+ msp430_powerkeep(0);
+ break;
+
+ case CM_GET_BATTERY_STATUS:
+ if(1==gptHWCFG->m_val.bPMIC) {
+ i = ricoh619_battery_2_msp430_adc();
+ }
+ else {
+ i = msp430_battery ();
+ }
+ if (0 == i)
+ i = 0x8000;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+
+ break;
+
+ case AC_IN:
+ if(1==gptHWCFG->m_val.bPMIC) {
+ i = ricoh619_charger_detect()?1:0;
+ }
+ else
+ i = gpio_get_value (gMX6SL_NTX_ACIN_PG)?0:1;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_SD_IN:
+ g_ioctl_SD_status = gpio_get_value (MX6SL_EXT_SD_CD);
+ i = (g_ioctl_SD_status)?0:1;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_USB_Plug_IN:
+ if(1==gptHWCFG->m_val.bPMIC) {
+ g_ioctl_USB_status = ricoh619_charger_detect()?0:1;
+ }
+ else {
+ if (!g_ioctl_USB_status && gpio_get_value (gMX6SL_NTX_ACIN_PG)) {
+ msleep(200); // sleep 200ms to avoid system halt when USB plug out.
+ }
+ g_ioctl_USB_status = gpio_get_value (gMX6SL_NTX_ACIN_PG);
+ }
+ i = (g_ioctl_USB_status)?0:1;
+ if (!g_Cus_Ctrl_Led) {
+ led_red(g_ioctl_USB_status?0:1);
+ }
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case GET_LnBATT_CPU:
+ break;
+ case GET_VBATT_TH:
+ break;
+ case CM_AC_CK:
+ break;
+ case CM_CHARGE_STATUS:
+ i = ntx_charge_status();
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+ case CM_PWR_ON2:
+ break;
+ case CM_AUDIO_PWR:
+ break;
+ case CM_nLED:
+ //printk("CM_nLED %d\n",p);
+ led_green(p?1:0);
+ break;
+
+ case CM_nLED_CPU:
+ break;
+
+ case CM_SD_PROTECT:
+ i = 0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_CONTROLLER:
+ i = 2; // 2: Epson controller. for micro window
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_USB_AC_STATUS:
+ i = 0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_RTC_WAKEUP_FLAG:
+ if (!g_wakeup_by_alarm) {
+ if(1!=gptHWCFG->m_val.bPMIC) {
+ int tmp = up_read_reg (0x60);
+ if (0x8000 & tmp) {
+ printk ("[%s-%d] =================> Micro P MSP430 alarm triggered <===================\n", __func__, __LINE__);
+ g_wakeup_by_alarm = 1;
+ }
+ }
+ }
+ i = g_wakeup_by_alarm; // Joseph 091221 for slide show test.
+ g_wakeup_by_alarm = 0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_SYSTEM_RESET:
+ ntx_system_reset("CM_SYSTEM_RESET");
+ break;
+
+ case CM_USB_HOST_PWR:
+ break;
+
+ case CM_BLUETOOTH_PWR:
+ ntx_wifi_power_ctrl (p);
+ break;
+
+ case CM_TELLPID:
+ if(p!=0){
+ printk("PID %d\n",p);
+ __EBRMAIN_PID__= p;
+ }
+ break;
+
+ case CM_LED_BLINK:
+ if (2==p) {
+ spin_lock(&led_flash_lock);
+ LED_Flash_Count++;
+ spin_unlock(&led_flash_lock);
+ }
+ if (!LED_conitnuous)
+ wake_up_interruptible(&LED_freeze_WaitQueue);
+ LED_conitnuous = p;
+ break;
+
+ case CM_TOUCH_LOCK:
+ if(p==0)
+ {
+ __TOUCH_LOCK__ = 0;
+ }else{
+ __TOUCH_LOCK__ = 1;
+ }
+ break;
+
+ case CM_DEVICE_MODULE:
+ i = check_hardware_name();
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_BLUETOOTH_RESET:
+ break;
+
+ case CM_DEVICE_INFO:
+ collect_hardware_info(&info);
+ copy_to_user((void __user *)arg, &info, sizeof(info));
+ break;
+
+ case CM_ROTARY_STATUS:
+ break;
+
+ case CM_ROTARY_ENABLE:
+ break;
+
+ case CM_GET_KEYS:
+ i = 0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+ case CM_POWER_BTN:
+ case CM_GET_KEY_STATUS:
+ if (g_power_key_pressed) {
+ g_power_key_pressed = 0;
+ i = 1;
+ }
+ else {
+ i = power_key_status ();
+
+ if (i) {
+ if (2 >= g_power_key_debounce) { // Joseph 20100921 for ESD
+ printk ("[%s-%d] power key bounce detected %d\n",__func__,__LINE__, g_power_key_debounce);
+ i=0;
+ }
+ else {
+ gMxcPowerKeyIrqTriggered = 0;
+ }
+ }
+ else if (gMxcPowerKeyIrqTriggered) { // POWER key interrupt triggered.
+ if (2 < g_power_key_debounce) {
+ i = 1;
+ }
+ else
+ printk ("[%s-%d] power key bounce detected %d\n",__func__,__LINE__,g_power_key_debounce);
+ gMxcPowerKeyIrqTriggered = 0;
+ }
+ }
+
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ g_mxc_touch_triggered = 0;
+ break;
+
+ case CM_GET_WHEEL_KEY_STATUS:
+ i=0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_GET_KL25_STATUS:
+ i=g_kl25_result;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ g_kl25_result &= 0xFF;
+ break;
+
+ case CM_GET_KL25_ACTION:
+ i=g_kl25_action ;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ g_kl25_action = 0;
+ break;
+
+ case CM_3G_POWER:
+ break;
+
+ case CM_3G_RF_OFF:
+ break;
+
+ case CM_3G_RESET:
+ break;
+
+ case CM_WIFI_CTRL:
+ ntx_wifi_power_ctrl (p);
+ break;
+
+ case CM_3G_GET_WAKE_STATUS:
+ i = 0;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_SET_ALARM_WAKEUP:
+ break;
+
+ case CM_GET_UP_VERSION:
+ if(1==gptHWCFG->m_val.bMicroP) {
+ i = 0;
+ }
+ else
+ i = msp430_deviceid();
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ break;
+
+ case CM_AUDIO_GET_VOLUME:
+ break;
+
+ case CM_AUDIO_SET_VOLUME:
+ break;
+
+ case CM_FRONT_LIGHT_SET:
+ fl_set_percentage(p);
+ break;
+
+ case CM_FRONT_LIGHT_GETDUTY:
+ if(1==gptHWCFG->m_val.bFL_PWM)
+ {
+ int duty;
+ duty = ht68f20_read_reg(0xB0);
+ printk ("[%s-%d] Front light Duty : %d\%\n",__func__,__LINE__,duty);
+ }
+ break;
+
+ case CM_FRONT_LIGHT_HT68F20_SETDUTY:
+ if(0!=gptHWCFG->m_val.bFrontLight && 1==gptHWCFG->m_val.bFL_PWM)
+ {
+ fl_pwm_enable (1);
+ if (p) {
+ printk ("\nSet front light duty : %3d\n",p);
+ ht68f20_write_reg (0xA6, p&0xFF);
+ ht68f20_write_reg (0xA7, p>>8);
+ if (0 == last_FL_duty){
+ ht68f20_write_reg (0xA3, 0x01);
+
+ msleep(100);
+ gpio_direction_output(MX6SL_FL_EN,giFL_ON);
+ }
+ }
+ else {
+ printk ("turn off front light\n");
+ ht68f20_write_reg (0xA3, 0);
+
+ FL_module_off();
+ }
+ last_FL_duty = p;
+ }
+ break;
+
+ case CM_FRONT_LIGHT_AVAILABLE:
+ {
+ i = (unsigned long) (gptHWCFG->m_val.bFrontLight?1:0) ;
+ copy_to_user((void __user *)arg, &i, sizeof(unsigned long));
+ }
+ break;
+
+ case CM_FRONT_LIGHT_DUTY:
+ if(0!=gptHWCFG->m_val.bFrontLight)
+ {
+ if (p) {
+ printk ("\nSet front light PWMCNT : 0x%4X\n",p);
+ printk ("Current front light Frequency : (8MHz/0x%4X)\n",current_FL_freq);
+ up_write_reg (0xA7, p&0xFF00);
+ up_write_reg (0xA6, p<<8);
+ if (0 == last_FL_duty){
+ up_write_reg (0xA1, 0xFF00);
+ up_write_reg (0xA2, 0xFF00);
+// up_write_reg (0xA5, 0xFF00);
+// up_write_reg (0xA4, 0xFF00);
+ up_write_reg (0xA3, 0x0100);
+
+ msleep(100);
+ gpio_direction_output(MX6SL_FL_EN,giFL_ON);
+ }
+ }
+ else {
+ printk ("turn off front light\n");
+ up_write_reg (0xA3, 0);
+ FL_module_off();
+ }
+ last_FL_duty = p;
+ }
+ break;
+
+ case CM_FRONT_LIGHT_FREQUENCY:
+ if(0!=gptHWCFG->m_val.bFrontLight)
+ {
+ if (p) {
+ printk ("set front light Frequency : (8MHz/0x%4X)\n",p);
+// up_write_reg (0xA4, (p<<8));
+ up_write_reg (0xA5, p&0xFF00);
+ up_write_reg (0xA4, (p<<8));
+ current_FL_freq = p;
+ }
+ }
+ break;
+
+ case CM_FRONT_LIGHT_R_EN:
+ if(0!=gptHWCFG->m_val.bFrontLight)
+ {
+ printk ("set FL_R_EN : %d\n",p);
+ gpio_direction_output(MX6SL_FL_R_EN, p);
+ }
+ break;
+
+ case CM_PLATFORM:
+ copy_to_user((void __user *)arg, &platform_type, 32);
+ break;
+ case CM_HWCONFIG:
+ copy_to_user((void __user *)arg, &hwconfig, sizeof(unsigned long
+ long));
+ break;
+ case CM_SET_HWCONFIG:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ copy_from_user(&hwconfig, (void __user *)arg, sizeof(unsigned long
+ long));
+ break;
+
+#ifdef TOUCH_HOME_LED
+ case CM_HOME_LED_ONOFF:
+ if(0x03==gptHWCFG->m_val.bUIConfig){
+ extern void homeled_onoff(int iIsON);
+ switch(p){
+ case 0:
+ homeled_onoff(0);
+ break;
+
+ case 1:
+ homeled_onoff(1);
+ break;
+
+ default:
+ homeled_onoff(1);
+ break;
+ }
+ }
+ break;
+#endif //#ifdef TOUCH_HOME_LED
+
+ default:
+ printk("pvi_io : do not get the command [%d]\n", command);
+ return -1;
+ }
+ return 0;
+}
+
+static struct file_operations driverFops= {
+ .owner = THIS_MODULE,
+ .open = openDriver,
+ .unlocked_ioctl = ioctlDriver,
+ .release = releaseDriver,
+};
+static struct miscdevice driverDevice = {
+ .minor = DEVICE_MINJOR,
+ .name = DEVICE_NAME,
+ .fops = &driverFops,
+};
+
+/*
+void mxc_set_fl_duty (int duty)
+{
+ static unsigned int last_FL_duty = 0;
+ static unsigned int current_FL_freq = 0xFFFF;
+ int t_no = gptHWCFG->m_val.bFrontLight-4; // mapping hwconfig to FL_table
+
+ if(0==gptHWCFG->m_val.bFrontLight)
+ return;
+
+ if (duty) {
+ if(delayed_work_pending(&FL_off)){
+ cancel_delayed_work_sync(&FL_off);
+ printk("FL_off delayed work canceled");
+ }
+ printk ("\nset front light level : %d\n",duty);
+
+ int freq = 8000000/FL_table[t_no][duty-1].freq;
+
+ if (last_FL_duty >= duty)
+ gpio_direction_output (MX6SL_FL_R_EN, FL_table[t_no][duty-1].fl_r_en);
+ if (freq != current_FL_freq) {
+ up_write_reg (0xA5, freq&0xFF00); // Set Frequency 8M/freq
+ up_write_reg (0xA4, freq<<8);
+ current_FL_freq = freq;
+ }
+ up_write_reg (0xA7, FL_table[t_no][duty-1].duty&0xFF00); // Set PWM duty
+ up_write_reg (0xA6, FL_table[t_no][duty-1].duty<<8);
+ gpio_direction_output (MX6SL_FL_R_EN, FL_table[t_no][duty-1].fl_r_en);
+
+ if (0 == last_FL_duty){
+ up_write_reg (0xA1, 0xFF00);
+ up_write_reg (0xA2, 0xFF00);
+
+ up_write_reg (0xA3, 0x0100);
+
+ msleep(100);
+ gpio_direction_output(MX6SL_FL_EN,0);
+ }
+ }
+ else if (last_FL_duty) {
+ printk ("turn off front light\n");
+ printk ("FL PWM off command\n");
+ up_write_reg(0xA3, 0);
+ schedule_delayed_work(&FL_off, 120);
+ current_FL_freq = 0xFFFF;
+ }
+ last_FL_duty = duty;
+}
+*/
+
+// ================================= Simulate MC13892 Signaling LED Driver ================================
+static struct timer_list green_led_timer, blue_led_timer, red_led_timer;
+static unsigned char green_led_dc, blue_led_dc, red_led_dc, \
+ green_led_flag, blue_led_flag, red_led_flag;
+static int green_led_period,blue_led_period,red_led_period ;
+
+static void ntx_led_set_timer (struct timer_list *pTimer, unsigned char dc, int blink)
+{
+ int period;
+
+ if (0 == dc || 0==blink) {
+ del_timer_sync(pTimer);
+ return;
+ }
+
+
+ switch (blink) {
+ case 1:
+ period = 100 / 8; // 1/8 s
+ break;
+ case 2:
+ period = 100; // 1 s
+ break;
+ case 3:
+ period = 200; // 2 s
+ break;
+ default:
+ if(blink>10) {
+ period = blink/10;
+ break;
+ }
+ return ;
+ }
+
+ mod_timer(pTimer, jiffies + period);
+}
+
+static void green_led_blink_func (unsigned long v)
+{
+ green_led_flag ^= 1;
+ led_green(green_led_flag?0:1);
+ ntx_led_set_timer (&green_led_timer, green_led_dc, green_led_period);
+}
+
+static void blue_led_blink_func (unsigned long v)
+{
+ blue_led_flag ^= 1;
+ led_blue(blue_led_flag?0:1);
+ ntx_led_set_timer (&blue_led_timer, blue_led_dc, blue_led_period);
+}
+
+static void red_led_blink_func (unsigned long v)
+{
+ red_led_flag ^= 1;
+ led_red(red_led_flag?0:1);
+ ntx_led_set_timer (&red_led_timer, red_led_dc, red_led_period);
+}
+
+void ntx_led_blink (unsigned int channel, int period)
+{
+ //printk("%s,period=%d\n",__FUNCTION__,period);
+ g_Cus_Ctrl_Led = 1;
+ switch (channel) {
+ case 3:
+ red_led_period = period&3;
+ ntx_led_set_timer (&red_led_timer, red_led_dc, red_led_period);
+ if(0==period) {
+ led_red(0);
+ }
+ break;
+ case 4:
+ //green_led_period = period&3;
+ green_led_period = period;
+ ntx_led_set_timer (&green_led_timer, green_led_dc, green_led_period);
+ if(0==period) {
+ led_green(0);
+ }
+ break;
+ case 5:
+ blue_led_period = period&3;
+ ntx_led_set_timer (&blue_led_timer, blue_led_dc, blue_led_period);
+ if(0==period) {
+ led_blue(0);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ntx_led_dc (unsigned int channel, unsigned char dc)
+{
+ LED_conitnuous = 0;
+ g_Cus_Ctrl_Led = 1;
+ switch (channel) {
+ case 3:
+ red_led_dc = dc;
+ red_led_flag = (dc)?0:1;
+ led_red(red_led_flag?0:1);
+ ntx_led_set_timer (&red_led_timer, red_led_dc, red_led_period);
+ break;
+ case 4:
+ green_led_dc = dc;
+ green_led_flag = (dc)?0:1;
+ led_green(green_led_flag?0:1);
+ ntx_led_set_timer (&green_led_timer, green_led_dc, green_led_period);
+ break;
+ case 5:
+ blue_led_dc = dc;
+ blue_led_flag = (dc)?0:1;
+ led_blue(blue_led_flag?0:1);
+ ntx_led_set_timer (&blue_led_timer, blue_led_dc, blue_led_period);
+ break;
+ default:
+ break;
+ }
+}
+
+void ntx_led_current (unsigned int channel, unsigned char value)
+{
+ g_Cus_Ctrl_Led = 1;
+ if (!value)
+ ntx_led_dc (channel, 0);
+}
+
+static void FL_module_off(void)
+{
+ if(giFL_ON) {
+ gpio_direction_output(MX6SL_FL_EN,0);
+ }
+ else {
+ gpio_direction_input(MX6SL_FL_EN);
+ }
+ gpio_direction_input(MX6SL_FL_R_EN);
+ fl_pwm_enable (0);
+ msp430_fl_enable (0);
+}
+
+void FL_off_func(struct work_struct *work)
+{
+ printk("[%s-%d]FL PWR off\n",__FUNCTION__,__LINE__);
+ FL_module_off();
+}
+
+int FL_suspend(void){
+ if(delayed_work_pending(&FL_off)){
+ return -1;
+ }
+ return 0;
+}
+
+static int sleep_thread(void)
+{
+int rc = 0;
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if(signal_pending(current))
+ rc = -EINTR;
+ __set_current_state(TASK_RUNNING);
+ return rc;
+}
+
+static int LED_Thread(void *param)
+{
+ sigset_t thread_signal_mask;
+ siginitsetinv(&thread_signal_mask, sigmask(SIGKILL));
+ sigprocmask(SIG_SETMASK, &thread_signal_mask, NULL);
+
+ while(1){
+ if(freezing(current)){
+ printk("freeze 0 !!!!!!!!!!!!!!!!!!!!\n");
+ try_to_freeze();
+ }
+
+ if(LED_conitnuous == 0){
+ interruptible_sleep_on(&LED_freeze_WaitQueue);
+ if(freezing(current)){
+ printk("freeze 1!!!!!!!!!!!!!!!!!!!!\n");
+ try_to_freeze();
+ }
+ }
+ if (g_Cus_Ctrl_Led) {
+ LED_conitnuous = 0;
+ continue;
+ }
+ led_green(1);
+ while (gKeepPowerAlive) {
+ sleep_on_timeout(&Reset_WaitQueue,HZ*2);
+ msp430_powerkeep(1);
+ }
+ //start to blink LED;
+ if (2 == LED_conitnuous) {
+ spin_lock(&led_flash_lock);
+ LED_Flash_Count = 0;
+ LED_conitnuous = 0;
+ spin_unlock(&led_flash_lock);
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/10);
+ led_green(0);
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/10);
+ led_green(1);
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/10);
+ if (!green_led_dc)
+ led_green(0);
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/10);
+ }
+ else {
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/2);
+ if (!green_led_dc)
+ led_green(0);
+ sleep_on_timeout(&LED_blink_WaitQueue,HZ/2);
+ }
+ }
+ return 0;
+}
+
+static struct timer_list power_key_timer;
+
+extern void mxc_kpp_report_key(int isDown,__u16 wKeyCode);
+extern void gpiokeys_report_key(int isDown,__u16 wKeyCode);
+extern void mxc_kpp_report_power(int isDown);
+extern void gpiokeys_report_power(int isDown);
+extern void gpiokeys_report_event(unsigned int type, unsigned int code, int value);
+extern void mxc_kpp_report_event(unsigned int type, unsigned int code, int value);
+
+void ntx_report_key(int isDown,__u16 wKeyCode)
+{
+ if(NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,0)) {
+ // no keymatrix .
+ gpiokeys_report_key(isDown, wKeyCode);
+ }else{
+ mxc_kpp_report_key(isDown, wKeyCode);
+ }
+}
+
+void ntx_report_event(unsigned int type, unsigned int code, int value)
+{
+ if(NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bPCB_Flags,0)) {
+ // no keymatrix .
+ gpiokeys_report_event(type,code,value);
+ }else{
+ mxc_kpp_report_event(type,code,value);
+ }
+}
+
+void ntx_report_power(int isDown)
+{
+ ntx_report_key(isDown, KEY_POWER);
+}
+
+static void power_key_chk(unsigned long v)
+{
+ int iPwrKeyState=power_key_status();
+ if (iPwrKeyState) {
+ ++g_power_key_debounce;
+ if (2 == g_power_key_debounce) {
+ ntx_report_power(1);
+ }
+ mod_timer(&power_key_timer, jiffies + 1);
+ }
+ else {
+ ntx_report_power(0);
+ }
+
+#if 0 //[ debug code .
+ printk("%s():PwrKeyState=%d,debounce=%d,IsCustomUI=%d\n",__FUNCTION__,
+ iPwrKeyState,g_power_key_debounce,gIsCustomerUi);
+#endif //]
+}
+
+void power_key_int_function(void)
+{
+ gMxcPowerKeyIrqTriggered = 1;
+ g_power_key_debounce = 0;
+ mod_timer(&power_key_timer, jiffies + 1);
+}
+
+static irqreturn_t power_key_int(int irq, void *dev_id)
+{
+ //printk("%s !!\n",__FUNCTION__);
+ power_key_int_function();
+ return 0;
+}
+
+int ntx_charge_status (void)
+{
+ int iIsUSBPlugged = 0;
+
+ if (1==gptHWCFG->m_val.bPMIC) {
+ iIsUSBPlugged = ricoh619_dcin_status();
+ }
+ else {
+ iIsUSBPlugged = gpio_get_value (gMX6SL_NTX_ACIN_PG)?0:1;
+ }
+ if (!iIsUSBPlugged) {
+ return 0;
+ }
+ else {
+ return (1 | (gpio_get_value (gMX6SL_NTX_CHG)?0:2));
+ }
+}
+
+int mxc_usb_plug_getstatus (void)
+{
+ //if (gIsCustomerUi)
+ {
+ int usb_status = 0;
+#if 1
+ if (1==gptHWCFG->m_val.bPMIC) {
+ usb_status = ricoh619_dcin_status();
+ g_ioctl_USB_status = usb_status?0:1;
+ return usb_status;
+ }
+ else
+#endif
+ usb_status = gpio_get_value (gMX6SL_NTX_ACIN_PG);
+
+ DBG_MSG("%s(),USB status=%d\n",__FUNCTION__,g_ioctl_USB_status);
+ g_ioctl_USB_status = usb_status?0:1;
+ return g_ioctl_USB_status;
+ }
+ //else {
+ //return 0;
+ //}
+}
+
+/*!
+ * Key raw pins interrupt handler.
+ */
+static irqreturn_t gpio_key_row_int(int irq, void *dev_id)
+{
+// pr_info(KERN_INFO "key matrix pressed ...\n");
+ return 0;
+}
+
+// NTX_GPIO_KEYS
+#define NTX_GPIO_KEYS_MAX 5
+static int gi_ntx_gpio_buttons_total = 0;
+static struct gpio_keys_button ntx_gpio_buttons[NTX_GPIO_KEYS_MAX] = {
+ {0,},
+};
+static struct gpio_keys_platform_data ntx_gpio_key_data = {
+ .buttons=ntx_gpio_buttons,
+ .nbuttons=0,
+ .rep=0,
+};
+static struct platform_device ntx_gpio_key_device = {
+ .name = "mxckpd",
+ .id = -1,
+ .dev = {
+ .platform_data = &ntx_gpio_key_data,
+ },
+};
+
+static void mxc_pads_dse_setup(iomux_v3_cfg_t *pad_list, unsigned count,iomux_v3_cfg_t tDSE_PAD_VAL)
+{
+ iomux_v3_cfg_t *p = pad_list;
+ int i;
+ iomux_v3_cfg_t tDSE_PAD_MASK=(iomux_v3_cfg_t)0x38<<MUX_PAD_CTRL_SHIFT;
+ iomux_v3_cfg_t tDSE_PAD_Current;
+
+ tDSE_PAD_VAL <<= MUX_PAD_CTRL_SHIFT;
+ tDSE_PAD_VAL &= tDSE_PAD_MASK;
+
+ for(i=0;i<count;i++) {
+ mxc_iomux_v3_get_pad(p);
+
+ tDSE_PAD_Current = *p;
+
+ *p &= ~tDSE_PAD_MASK;
+ *p |= tDSE_PAD_VAL;
+
+ //printk("PAD set 0x%llx->0x%llx \n",tDSE_PAD_Current,*p);
+ mxc_iomux_v3_setup_pad(*p);
+ p++;
+ }
+}
+
+#define GPIO_BAT_LOW_INT IMX_GPIO_NR(3, 28) /* COL2 */
+static irqreturn_t bat_low_int(int irq, void *dev_id)
+{
+ printk ("[%s-%d] triggered!!\n", __func__, __LINE__);
+ return 0;
+}
+
+
+static int gpio_initials(void)
+{
+ int irq, ret;
+ int error;
+
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_KEY_COL2__GPIO_3_28);
+ gpio_request (GPIO_BAT_LOW_INT, "MX6SL_BAT_LOW");
+ gpio_direction_input(GPIO_BAT_LOW_INT);
+#if 0
+ irq = gpio_to_irq(GPIO_BAT_LOW_INT);
+ ret = request_irq(irq, bat_low_int, IRQF_TRIGGER_FALLING, "bat_low", 0);
+ if (ret)
+ pr_info("register on-off key interrupt failed\n");
+ else
+ enable_irq_wake(irq);
+#endif
+#ifndef CONFIG_ANDROID//[
+ if(0==gptHWCFG->m_val.bUIStyle) {
+ // Ebrmain .
+
+ power_key_timer.function = power_key_chk;
+ init_timer(&power_key_timer);
+ /* OFF_CHK */
+ #ifdef GPIOFN_PWRKEY//[
+ gpiofn_register(&gtNTX_PWR_GPIO_data);
+ #else //][!GPIOFN_PWRKEY
+
+ gpio_direction_input(gMX6SL_PWR_SW);
+ {
+ /* Set power key as wakeup resource */
+ irq = gpio_to_irq(gMX6SL_PWR_SW);
+ ret = request_irq(irq, power_key_int, IRQF_TRIGGER_FALLING, "power_key", 0);
+ if (ret)
+ pr_info("register on-off key interrupt failed\n");
+ else
+ enable_irq_wake(irq);
+ }
+ }
+ #endif //]GPIOFN_PWRKEY
+#endif//]CONFIG_ANDROID
+
+
+ gpio_direction_output(gMX6SL_IR_TOUCH_RST, 0);
+ msleep(20);
+ gpio_direction_input(gMX6SL_IR_TOUCH_RST);
+
+ // MX6SL_FL_EN
+ if( 0 != gptHWCFG->m_val.bFrontLight ){
+ if(NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bFrontLight_Flags,2)){
+ // FL_EN invert .
+ //printk("FL_EN inverted !\n",__FUNCTION__);
+ giFL_ON=1;
+ }
+ if( 0 == NTXHWCFG_TST_FLAG(gptHWCFG->m_val.bFrontLight_Flags,0)){
+ FL_module_off();
+ }
+ INIT_DELAYED_WORK(&FL_off, FL_off_func);
+ }
+
+#ifdef _WIFI_ALWAYS_ON_
+ set_irq_type(gpio_to_irq(gMX6SL_WIFI_INT), IRQF_TRIGGER_FALLING);
+#endif
+
+ if(40==gptHWCFG->m_val.bPCB||49==gptHWCFG->m_val.bPCB) {
+ // E60Q5X / E60QDX for EMI .
+ printk("EMMC DSE set to 48 ohm \n");
+ mxc_pads_dse_setup(mx6sl_brd_ntx_sd4_pads,
+ ARRAY_SIZE(mx6sl_brd_ntx_sd4_pads),(iomux_v3_cfg_t)PAD_CTL_DSE_48ohm);
+ }
+
+ // initial test point for ESD , Joseph 20100504
+ return 0;
+}
+
+#include <mach/hardware.h>
+#define SSI1_IO_BASE_ADDR IO_ADDRESS(SSI1_BASE_ADDR)
+#define SSI2_IO_BASE_ADDR IO_ADDRESS(SSI2_BASE_ADDR)
+#define SSI1_SCR ((SSI1_IO_BASE_ADDR) + 0x10)
+#define SSI2_SCR ((SSI2_IO_BASE_ADDR) + 0x10)
+
+#include <mach/arc_otg.h>
+#include "crm_regs.h"
+extern void __iomem *apll_base;
+unsigned long gUart_ucr1;
+
+static iomux_v3_cfg_t ntx_suspend_enter_pads[] = {
+ // I2C1,I2C2
+ MX6SL_PAD_I2C2_SCL__GPIO_3_14,
+ MX6SL_PAD_I2C2_SDA__GPIO_3_15,
+ MX6SL_PAD_I2C1_SCL__GPIO_3_12,
+ MX6SL_PAD_I2C1_SDA__GPIO_3_13,
+ // SD2
+ MX6SL_PAD_SD2_CLK__GPIO_5_5,
+ MX6SL_PAD_SD2_CMD__GPIO_5_4,
+ MX6SL_PAD_SD2_DAT0__GPIO_5_1,
+ MX6SL_PAD_SD2_DAT1__GPIO_4_30,
+ MX6SL_PAD_SD2_DAT2__GPIO_5_3,
+ MX6SL_PAD_SD2_DAT3__GPIO_4_28,
+ // SD3
+ MX6SL_PAD_SD3_CLK__GPIO_5_18,
+ MX6SL_PAD_SD3_CMD__GPIO_5_21,
+ MX6SL_PAD_SD3_DAT0__GPIO_5_19,
+ MX6SL_PAD_SD3_DAT1__GPIO_5_20,
+ MX6SL_PAD_SD3_DAT2__GPIO_5_16,
+ MX6SL_PAD_SD3_DAT3__GPIO_5_17,
+ // SD4
+ MX6SL_PAD_FEC_TX_CLK__GPIO_4_21,
+ MX6SL_PAD_FEC_MDIO__GPIO_4_20,
+ MX6SL_PAD_FEC_RX_ER__GPIO_4_19,
+ MX6SL_PAD_FEC_CRS_DV__GPIO_4_25,
+ MX6SL_PAD_FEC_RXD1__GPIO_4_18,
+ MX6SL_PAD_FEC_TXD0__GPIO_4_24,
+ MX6SL_PAD_FEC_MDC__GPIO_4_23,
+ MX6SL_PAD_FEC_RXD0__GPIO_4_17,
+ MX6SL_PAD_FEC_TX_EN__GPIO_4_22,
+ MX6SL_PAD_FEC_TXD1__GPIO_4_16,
+ MX6SL_PAD_FEC_REF_CLK__GPIO_4_26,
+
+ // TEST ONLY
+ MX6SL_PAD_ECSPI1_MISO__GPIO_4_10,
+ MX6SL_PAD_ECSPI1_MOSI__GPIO_4_9,
+ MX6SL_PAD_ECSPI1_SCLK__GPIO_4_8,
+ MX6SL_PAD_ECSPI1_SS0__GPIO_4_11,
+
+ MX6SL_PAD_ECSPI2_MISO__GPIO_4_14,
+ MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13,
+ MX6SL_PAD_ECSPI2_SCLK__GPIO_4_12,
+ MX6SL_PAD_ECSPI2_SS0__GPIO_4_15,
+
+ MX6SL_PAD_EPDC_BDR0__GPIO_2_5,
+ MX6SL_PAD_EPDC_BDR1__GPIO_2_6,
+ MX6SL_PAD_EPDC_D0__GPIO_1_7,
+ MX6SL_PAD_EPDC_D1__GPIO_1_8,
+ MX6SL_PAD_EPDC_D10__GPIO_1_17,
+ MX6SL_PAD_EPDC_D11__GPIO_1_18,
+ MX6SL_PAD_EPDC_D12__GPIO_1_19,
+ MX6SL_PAD_EPDC_D13__GPIO_1_20,
+ MX6SL_PAD_EPDC_D14__GPIO_1_21,
+ MX6SL_PAD_EPDC_D15__GPIO_1_22,
+ MX6SL_PAD_EPDC_D2__GPIO_1_9,
+ MX6SL_PAD_EPDC_D3__GPIO_1_10,
+ MX6SL_PAD_EPDC_D4__GPIO_1_11,
+ MX6SL_PAD_EPDC_D5__GPIO_1_12,
+ MX6SL_PAD_EPDC_D6__GPIO_1_13,
+ MX6SL_PAD_EPDC_D7__GPIO_1_14,
+ MX6SL_PAD_EPDC_D8__GPIO_1_15,
+ MX6SL_PAD_EPDC_D9__GPIO_1_16,
+ MX6SL_PAD_EPDC_GDCLK__GPIO_1_31,
+ MX6SL_PAD_EPDC_GDOE__GPIO_2_0,
+ MX6SL_PAD_EPDC_GDRL__GPIO_2_1,
+ MX6SL_PAD_EPDC_GDSP__GPIO_2_2,
+// MX6SL_PAD_EPDC_PWRCOM__GPIO_2_11,
+ MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7,
+ MX6SL_PAD_EPDC_PWRCTRL1__GPIO_2_8,
+ MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9,
+ MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10,
+ MX6SL_PAD_EPDC_PWRINT__GPIO_2_12,
+ MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13,
+ MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14,
+ MX6SL_PAD_EPDC_SDCE0__GPIO_1_27,
+ MX6SL_PAD_EPDC_SDCE1__GPIO_1_28,
+ MX6SL_PAD_EPDC_SDCE2__GPIO_1_29,
+ MX6SL_PAD_EPDC_SDCE3__GPIO_1_30,
+ MX6SL_PAD_EPDC_SDCLK__GPIO_1_23,
+ MX6SL_PAD_EPDC_SDLE__GPIO_1_24,
+ MX6SL_PAD_EPDC_SDOE__GPIO_1_25,
+ MX6SL_PAD_EPDC_SDSHR__GPIO_1_26,
+ MX6SL_PAD_EPDC_VCOM0__GPIO_2_3,
+ MX6SL_PAD_EPDC_VCOM1__GPIO_2_4,
+
+/*
+ffffff80
+000077ff
+0000f000
+53ffff00
+003f003a
+*/
+ MX6SL_PAD_HSIC_DAT__GPIO_3_19,
+ MX6SL_PAD_HSIC_STROBE__GPIO_3_20,
+ MX6SL_PAD_KEY_COL0__GPIO_3_24,
+ MX6SL_PAD_KEY_COL1__GPIO_3_26,
+ MX6SL_PAD_KEY_COL2__GPIO_3_28,
+ MX6SL_PAD_KEY_COL3__GPIO_3_30,
+ MX6SL_PAD_KEY_COL4__GPIO_4_0,
+ MX6SL_PAD_KEY_COL5__GPIO_4_2,
+ MX6SL_PAD_KEY_COL6__GPIO_4_4,
+ MX6SL_PAD_KEY_COL7__GPIO_4_6,
+ MX6SL_PAD_KEY_ROW0__GPIO_3_25,
+ MX6SL_PAD_KEY_ROW1__GPIO_3_27,
+ MX6SL_PAD_KEY_ROW2__GPIO_3_29,
+ MX6SL_PAD_KEY_ROW3__GPIO_3_31,
+ MX6SL_PAD_KEY_ROW4__GPIO_4_1,
+ MX6SL_PAD_KEY_ROW5__GPIO_4_3,
+ MX6SL_PAD_KEY_ROW6__GPIO_4_5,
+ MX6SL_PAD_KEY_ROW7__GPIO_4_7,
+/*
+ffffff80
+000077ff
+ff18f000
+57ffffff
+003f003a
+*/
+ MX6SL_PAD_LCD_CLK__GPIO_2_15,
+ MX6SL_PAD_LCD_DAT0__GPIO_2_20,
+ MX6SL_PAD_LCD_DAT1__GPIO_2_21,
+ MX6SL_PAD_LCD_DAT10__GPIO_2_30,
+ MX6SL_PAD_LCD_DAT11__GPIO_2_31,
+ MX6SL_PAD_LCD_DAT12__GPIO_3_0,
+ MX6SL_PAD_LCD_DAT13__GPIO_3_1,
+ MX6SL_PAD_LCD_DAT14__GPIO_3_2,
+ MX6SL_PAD_LCD_DAT15__GPIO_3_3,
+ MX6SL_PAD_LCD_DAT16__GPIO_3_4,
+ MX6SL_PAD_LCD_DAT17__GPIO_3_5,
+ MX6SL_PAD_LCD_DAT18__GPIO_3_6,
+ MX6SL_PAD_LCD_DAT19__GPIO_3_7,
+ MX6SL_PAD_LCD_DAT2__GPIO_2_22,
+ MX6SL_PAD_LCD_DAT20__GPIO_3_8,
+ MX6SL_PAD_LCD_DAT21__GPIO_3_9,
+ MX6SL_PAD_LCD_DAT22__GPIO_3_10,
+ MX6SL_PAD_LCD_DAT23__GPIO_3_11,
+ MX6SL_PAD_LCD_DAT3__GPIO_2_23,
+ MX6SL_PAD_LCD_DAT4__GPIO_2_24,
+ MX6SL_PAD_LCD_DAT5__GPIO_2_25,
+ MX6SL_PAD_LCD_DAT6__GPIO_2_26,
+ MX6SL_PAD_LCD_DAT7__GPIO_2_27,
+ MX6SL_PAD_LCD_DAT8__GPIO_2_28,
+ MX6SL_PAD_LCD_DAT9__GPIO_2_29,
+ MX6SL_PAD_LCD_ENABLE__GPIO_2_16,
+ MX6SL_PAD_LCD_HSYNC__GPIO_2_17,
+ MX6SL_PAD_LCD_RESET__GPIO_2_19,
+ MX6SL_PAD_LCD_VSYNC__GPIO_2_18,
+ MX6SL_PAD_PWM1__GPIO_3_23,
+ MX6SL_PAD_REF_CLK_24M__GPIO_3_21,
+ MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
+ MX6SL_PAD_SD1_CLK__GPIO_5_15,
+ MX6SL_PAD_SD1_CMD__GPIO_5_14,
+ MX6SL_PAD_SD1_DAT0__GPIO_5_11,
+ MX6SL_PAD_SD1_DAT1__GPIO_5_8,
+ MX6SL_PAD_SD1_DAT2__GPIO_5_13,
+ MX6SL_PAD_SD1_DAT3__GPIO_5_6,
+ MX6SL_PAD_SD1_DAT4__GPIO_5_12,
+ MX6SL_PAD_SD1_DAT5__GPIO_5_9,
+ MX6SL_PAD_SD1_DAT6__GPIO_5_7,
+ MX6SL_PAD_SD1_DAT7__GPIO_5_10,
+ MX6SL_PAD_SD2_DAT4__GPIO_5_2,
+ MX6SL_PAD_SD2_DAT5__GPIO_4_31,
+// MX6SL_PAD_SD2_DAT6__GPIO_4_29,
+ MX6SL_PAD_SD2_DAT7__GPIO_5_0,
+ MX6SL_PAD_SD2_RST__GPIO_4_27,
+// MX6SL_PAD_UART1_RXD__GPIO_3_16,
+// MX6SL_PAD_UART1_TXD__GPIO_3_17,
+ MX6SL_PAD_WDOG_B__GPIO_3_18,
+/*
+0xffffff80
+0xfffff7ff
+0xfffcffff
+0xdfffffff
+0x003fffff
+
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
+1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
+2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1
+3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+4 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+5 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+
+*/
+
+};
+
+#define dump_pad_iomux_val(_pad_name,_iomux_v3cfg,pin_func_str,desc_str) \
+ {\
+ iomux_v3_cfg_t tDSE_PAD_Current;\
+ tDSE_PAD_Current=_iomux_v3cfg;\
+ mxc_iomux_v3_get_pad(&tDSE_PAD_Current);\
+ printk("%s(%d):%s %s(%s)= 0x%llx \n",__func__,__LINE__,\
+ desc_str,#_pad_name,pin_func_str,tDSE_PAD_Current);\
+ printk("\tpadctrl=0x%x\n",(tDSE_PAD_Current>>MUX_PAD_CTRL_SHIFT)&0x43ffff);\
+ printk("\tmode=0x%x\n",(tDSE_PAD_Current>>MUX_MODE_SHIFT)&0x1f);\
+ printk("\tinput=0x%x\n",(tDSE_PAD_Current>>MUX_SEL_INPUT_SHIFT)&0xf);\
+ }
+
+static unsigned int ntx_gpio_dir[5],ntx_gpio_insuspend_dir[5];
+static iomux_v3_cfg_t local_suspend_enter_pads[ARRAY_SIZE(ntx_suspend_enter_pads)];
+static iomux_v3_cfg_t ntx_suspend_exit_pads[ARRAY_SIZE(ntx_suspend_enter_pads)];
+
+extern int fl_level; // If FL is on, value is 0-100. If FL is off, value is 0;
+extern int fl_current; // Unit is 1uA. If FL is off, value is 0;
+extern int slp_state; // 0:Suspend, 1:Hibernate
+extern int idle_current; // Unit is 1uA.
+extern int sus_current; // Unit is 1uA.
+extern int hiber_current; // Unit is 1uA.
+extern bool bat_alert_req_flg; // 0:Normal, 1:Re-synchronize request from system
+void ricoh_suspend_state_sync(void)
+{
+ const int fl_currentA[] = {
+ 620 , 720 , 830 , 990 , 1120 , 1300 , 1460 , 1590 , 1750 , 2020 , // 01 ~ 10
+ 2330 , 2610 , 2900 , 3260 , 3570 , 3900 , 4100 , 4300 , 4510 , 6230 , // 11 ~ 20
+ 6640 , 6840 , 7270 , 7690 , 8100 , 8520 , 8930 , 9350 , 9810 , 10180, // 21 ~ 30
+ 10610, 11010, 11430, 11860, 12310, 12700, 13160, 13560, 13960, 14370, // 31 ~ 40
+ 14730, 15130, 15530, 15930, 16530, 17330, 17920, 18300, 18720, 19120, // 41 ~ 50
+ 19720, 20320, 20930, 21320, 21720, 22330, 22940, 23340, 23760, 24170, // 51 ~ 60
+ 24570, 25180, 25780, 26180, 26790, 27190, 27820, 28220, 28630, 29260, // 61 ~ 70
+ 29860, 30500, 31090, 31700, 32310, 32740, 33140, 33760, 34200, 35230, // 71 ~ 80
+ 35850, 36460, 37910, 39370, 40200, 41050, 41890, 42700, 44400, 45880, // 81 ~ 90
+ 47360, 48860, 50560, 51160, 52000, 53070, 54150, 55440, 56710, 58000, // 91 ~ 100
+ };
+ fl_level = last_FL_duty; // If FL is on, value is 0-100. If FL is off, value is 0;
+ if (last_FL_duty)
+ fl_current = fl_currentA[last_FL_duty-1]; // Unit is 1uA. If FL is off, value is 0;
+ else
+ fl_current = 0;
+ slp_state = gSleep_Mode_Suspend?1:0; // 0:Suspend, 1:Hibernate
+ idle_current = 1000; // Unit is 1uA.
+ sus_current = 1900; // Unit is 1uA.
+ hiber_current = 889; // Unit is 1uA.
+ bat_alert_req_flg = 0; // 0:Normal, 1:Re-synchronize request from system
+}
+
+//#define DUMP_PADS 1
+extern int mxc_epdc_fb_ep1v8_output(int iIsOutput);
+
+void ntx_gpio_suspend (void)
+{
+ g_wakeup_by_alarm = 0;
+
+
+ led_blue(0);
+ led_green(0);
+
+ gpiofn_suspend();
+ if (gSleep_Mode_Suspend) {
+
+ ntx_gpio_insuspend_dir[0]=0xffffff80;
+ ntx_gpio_insuspend_dir[1]=0xfffff7ff;
+ ntx_gpio_insuspend_dir[2]=0xfffcffff;
+ ntx_gpio_insuspend_dir[3]=0xdfffffff;
+ ntx_gpio_insuspend_dir[4]=0x003fffff;
+
+
+ if(7==gptHWCFG->m_val.bDisplayCtrl) {
+ tps65185_ONOFF(0);
+ }
+ else if(8==gptHWCFG->m_val.bDisplayCtrl) {
+ fp9928_ONOFF(0);
+ }
+ //mxc_epdc_fb_ep1v8_output(0);
+ //gpio_direction_output (GPIO_EP_3V3_ON, 0);
+ //gpio_direction_output (MX6SL_EP_PWRALL, 0);
+
+
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SCL__GPIO_3_12);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SDA__GPIO_3_13);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C2_SCL__GPIO_3_14);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C2_SDA__GPIO_3_15);
+
+ if(3==gptHWCFG->m_val.bTouchType || 4==gptHWCFG->m_val.bTouchType) {
+ if(0x03!=gptHWCFG->m_val.bUIConfig) {
+ // turn off ir touch power.
+ gpio_direction_output (gMX6SL_IR_TOUCH_INT, 0);
+
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 0);
+ gpio_direction_output (GPIO_IR_3V3_ON, 0);
+ }
+ }
+
+ }
+
+ gUart_ucr1 = __raw_readl(ioremap(MX6SL_UART1_BASE_ADDR, SZ_4K)+0x80);
+ __raw_writel(0, ioremap(MX6SL_UART1_BASE_ADDR, SZ_4K)+0x80);
+
+ if (gSleep_Mode_Suspend) {
+ iomux_v3_cfg_t *p = local_suspend_enter_pads;
+ int i;
+ void __iomem *base;
+ unsigned long dwDisableBit ;
+
+ /* Set PADCTRL to 0 for all IOMUX. */
+ for (i = 0; i < ARRAY_SIZE(ntx_suspend_enter_pads); i++) {
+ *p = ntx_suspend_exit_pads[i] = ntx_suspend_enter_pads[i];
+
+ if(1==gptHWCFG->m_val.bPMIC) {
+ // pads for Ricoh PMIC .
+ // I2C3_SCL,I2C3_SDA,CHG,BAT_LOW_INT,PMU_INT
+ if( ((*p)==(MX6SL_PAD_REF_CLK_24M__GPIO_3_21)) ||
+ ((*p)==(MX6SL_PAD_REF_CLK_32K__GPIO_3_22)) ||
+ ((*p)==(MX6SL_PAD_SD1_CLK__GPIO_5_15)) ||
+ ((*p)==(MX6SL_PAD_KEY_COL2__GPIO_3_28)) ||
+ ((*p)==(MX6SL_PAD_SD1_DAT0__GPIO_5_11)) )
+ {
+ continue ;
+ }
+ }
+
+ if( (*p) == (MX6SL_PAD_SD3_CLK__GPIO_5_18) ||
+ (*p) == (MX6SL_PAD_SD3_CMD__GPIO_5_21) ||
+ (*p) == (MX6SL_PAD_SD3_DAT0__GPIO_5_19) ||
+ (*p) == (MX6SL_PAD_SD3_DAT1__GPIO_5_20) ||
+ (*p) == (MX6SL_PAD_SD3_DAT2__GPIO_5_16) ||
+ (*p) == (MX6SL_PAD_SD3_DAT3__GPIO_5_17) )
+ {
+ *p &= ~MUX_PAD_CTRL_MASK;
+ /* Enable the Pull down and the keeper
+ * Set the drive strength to 0.
+ */
+ *p |= ((u64)0x3000 << MUX_PAD_CTRL_SHIFT);
+ }
+ else if((*p) == (MX6SL_PAD_FEC_MDIO__GPIO_4_20 )||
+ (*p) == (MX6SL_PAD_FEC_TX_CLK__GPIO_4_21)||
+ (*p) == (MX6SL_PAD_FEC_RX_ER__GPIO_4_19 )||
+ (*p) == (MX6SL_PAD_FEC_CRS_DV__GPIO_4_25)||
+ (*p) == (MX6SL_PAD_FEC_RXD1__GPIO_4_18 )||
+ (*p) == (MX6SL_PAD_FEC_TXD0__GPIO_4_24 )||
+ (*p) == (MX6SL_PAD_FEC_MDC__GPIO_4_23 )||
+ (*p) == (MX6SL_PAD_FEC_RXD0__GPIO_4_17 )||
+ (*p) == (MX6SL_PAD_FEC_TX_EN__GPIO_4_22 )||
+ (*p) == (MX6SL_PAD_FEC_TXD1__GPIO_4_16 )||
+ (*p) == (MX6SL_PAD_FEC_REF_CLK__GPIO_4_26))
+ {
+ // EMMC PADS
+#if 1
+ if( 2==gptHWCFG->m_val.bIFlash )
+#else
+ if (37==gptHWCFG->m_val.bPCB /* E60QBX */||
+/* >=E60Q30A10 */((36==gptHWCFG->m_val.bPCB) && gptHWCFG->m_val.bPCB_REV>=0x10) ||
+ 40==gptHWCFG->m_val.bPCB /* E60Q5X */ )
+#endif
+ {
+ *p &= ~MUX_PAD_CTRL_MASK;
+ /* Enable the Pull down and the keeper
+ * Set the drive strength to 0.
+ */
+ *p |= ((u64)0x3000 << MUX_PAD_CTRL_SHIFT);
+ }
+ }
+ else if((*p) == (MX6SL_PAD_KEY_ROW5__GPIO_4_3) &&
+ (((36==gptHWCFG->m_val.bPCB) && gptHWCFG->m_val.bPCB_REV>=0x10) ||
+ (40==gptHWCFG->m_val.bPCB)||(47==gptHWCFG->m_val.bPCB)||(49==gptHWCFG->m_val.bPCB)))
+ {
+ // E60Q3X revA10 , E60Q5X , ED0Q0X , E60QDX
+ // GPIO 4_3 for EP_3V3_ON .
+ }
+ else if((*p) == (MX6SL_PAD_KEY_ROW3__GPIO_3_31) && (giISD_3V3_ON_Ctrl!=-1) )
+ {
+ //only >=E60Q30A10 can turn off ISD_3V3
+
+ gpio_direction_output (GPIO_ISD_3V3_ON, giISD_3V3_ON_Ctrl?0:1);
+ }
+ else if( (*p) == (MX6SL_PAD_KEY_ROW4__GPIO_4_1) ||
+ (*p) == (MX6SL_PAD_KEY_ROW5__GPIO_4_3) ||
+ (*p) == (MX6SL_PAD_EPDC_SDCE2__GPIO_1_29) ) {
+ // pull down
+ *p &= ~MUX_PAD_CTRL_MASK;
+ *p |= ((u64)0x30b0 << MUX_PAD_CTRL_SHIFT);
+ }
+/* else if(
+ (*p) == MX6SL_PAD_EPDC_BDR0__GPIO_2_5 ||
+ (*p) == MX6SL_PAD_EPDC_BDR1__GPIO_2_6 ||
+ (*p) == MX6SL_PAD_EPDC_D0__GPIO_1_7 ||
+ (*p) == MX6SL_PAD_EPDC_D1__GPIO_1_8 ||
+ (*p) == MX6SL_PAD_EPDC_D10__GPIO_1_17 ||
+ (*p) == MX6SL_PAD_EPDC_D11__GPIO_1_18 ||
+ (*p) == MX6SL_PAD_EPDC_D12__GPIO_1_19 ||
+ (*p) == MX6SL_PAD_EPDC_D13__GPIO_1_20 ||
+ (*p) == MX6SL_PAD_EPDC_D14__GPIO_1_21 ||
+ (*p) == MX6SL_PAD_EPDC_D15__GPIO_1_22 ||
+ (*p) == MX6SL_PAD_EPDC_D2__GPIO_1_9 ||
+ (*p) == MX6SL_PAD_EPDC_D3__GPIO_1_10 ||
+ (*p) == MX6SL_PAD_EPDC_D4__GPIO_1_11 ||
+ (*p) == MX6SL_PAD_EPDC_D5__GPIO_1_12 ||
+ (*p) == MX6SL_PAD_EPDC_D6__GPIO_1_13 ||
+ (*p) == MX6SL_PAD_EPDC_D7__GPIO_1_14 ||
+ (*p) == MX6SL_PAD_EPDC_D8__GPIO_1_15 ||
+ (*p) == MX6SL_PAD_EPDC_D9__GPIO_1_16 ||
+ (*p) == MX6SL_PAD_EPDC_GDCLK__GPIO_1_31 ||
+ (*p) == MX6SL_PAD_EPDC_GDOE__GPIO_2_0 ||
+ (*p) == MX6SL_PAD_EPDC_GDRL__GPIO_2_1 ||
+ (*p) == MX6SL_PAD_EPDC_GDSP__GPIO_2_2 ||
+ (*p) == MX6SL_PAD_EPDC_PWRCOM__GPIO_2_11 ||
+ (*p) == MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7 ||
+ (*p) == MX6SL_PAD_EPDC_PWRCTRL1__GPIO_2_8 ||
+ (*p) == MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9 ||
+ (*p) == MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10 ||
+ (*p) == MX6SL_PAD_EPDC_PWRINT__GPIO_2_12 ||
+ (*p) == MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13 ||
+ (*p) == MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14 ||
+ (*p) == MX6SL_PAD_EPDC_SDCE0__GPIO_1_27 ||
+ (*p) == MX6SL_PAD_EPDC_SDCE1__GPIO_1_28 ||
+ (*p) == MX6SL_PAD_EPDC_SDCE2__GPIO_1_29 ||
+ (*p) == MX6SL_PAD_EPDC_SDCE3__GPIO_1_30 ||
+ (*p) == MX6SL_PAD_EPDC_SDCLK__GPIO_1_23 ||
+ (*p) == MX6SL_PAD_EPDC_SDLE__GPIO_1_24 ||
+ (*p) == MX6SL_PAD_EPDC_SDOE__GPIO_1_25 ||
+ (*p) == MX6SL_PAD_EPDC_SDSHR__GPIO_1_26 ||
+ (*p) == MX6SL_PAD_EPDC_VCOM0__GPIO_2_3 ||
+ (*p) == MX6SL_PAD_EPDC_VCOM1__GPIO_2_4
+ ) {
+ *p &= ~MUX_PAD_CTRL_MASK;
+ *p |= ((u64)0x3000 << MUX_PAD_CTRL_SHIFT);
+ }
+*/
+ else if ( (*p) == MX6SL_PAD_SD2_DAT6__GPIO_4_29 ||
+ (*p) == MX6SL_PAD_SD1_DAT6__GPIO_5_7 ||
+ ((1==gptHWCFG->m_val.bLed)&&((*p)==MX6SL_PAD_SD1_DAT2__GPIO_5_13)) )
+ {
+ // pull up
+ if((*p) == MX6SL_PAD_SD1_DAT6__GPIO_5_7&&(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB
+ || 49==gptHWCFG->m_val.bPCB))
+ {
+ // E60Q3X/E60Q5X/E60QDX
+ // skip set pad of GP5_7 for Green LED .
+ }
+ else {
+ *p &= ~MUX_PAD_CTRL_MASK;
+ *p |= ((u64)0x0001b0b1 << MUX_PAD_CTRL_SHIFT);
+ }
+ }
+ else if( (*p) == MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10) {
+
+ if(0==giFL_ON) {
+ // open drain
+ *p &= ~MUX_PAD_CTRL_MASK;
+ *p |= ((u64)0x000108b0 << MUX_PAD_CTRL_SHIFT);
+ }
+ }
+ else {
+ if((36==gptHWCFG->m_val.bPCB||40==gptHWCFG->m_val.bPCB||49==gptHWCFG->m_val.bPCB) &&
+ ((*p) == (MX6SL_PAD_SD1_DAT7__GPIO_5_10 )) )
+ {
+ // E60Q3X ,E60Q5X, E60QDX
+ // skip setting home led to floating state .
+ }
+ else {
+ // floating
+ *p &= ~MUX_PAD_CTRL_MASK;
+ *p |= ((u64)0x000110b0 << MUX_PAD_CTRL_SHIFT);
+ }
+ }
+ p++;
+ }
+
+ // Direction control .
+ mxc_iomux_v3_get_multiple_pads(ntx_suspend_exit_pads,
+ ARRAY_SIZE(ntx_suspend_exit_pads));
+
+#ifdef DUMP_PADS//[
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_24M,MX6SL_PAD_REF_CLK_24M__GPIO_3_21,
+ "I2C3_SCL","before hibernation");
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_32K,MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
+ "I2C3_SDA","before hibernation");
+#endif//] DUMP_PADS
+ mxc_iomux_v3_setup_multiple_pads(local_suspend_enter_pads,
+ ARRAY_SIZE(local_suspend_enter_pads));
+
+#ifdef DUMP_PADS//[
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_24M,MX6SL_PAD_REF_CLK_24M__GPIO_3_21,
+ "I2C3_SCL","in hibernation");
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_32K,MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
+ "I2C3_SDA","in hibernation");
+#endif//]DUMP_PADS
+
+ if(giFL_ON) {
+ // set as output .
+ dwDisableBit = (unsigned long)(1<<10);
+ ntx_gpio_insuspend_dir[1] &= ~dwDisableBit; //GP2_10
+ }
+
+ if( (36==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_REV>=0x10) ||
+ 40==gptHWCFG->m_val.bPCB || 49==gptHWCFG->m_val.bPCB)
+ {
+ // >=E60Q30A1 , E60Q5X , E60QDX
+ dwDisableBit = (unsigned long)(1<<3);
+ ntx_gpio_insuspend_dir[3] &= ~dwDisableBit; //GP4_3 for EP_3V3_ON output
+ dwDisableBit = (unsigned long)(1<<7);
+ ntx_gpio_insuspend_dir[4] &= ~dwDisableBit; //GP5_7 for POWER_LED output
+ dwDisableBit = (unsigned long)(1<<10);
+ ntx_gpio_insuspend_dir[4] &= ~dwDisableBit; //GP5_10 for HOME_LED output
+ }
+ else if(47==gptHWCFG->m_val.bPCB)
+ {
+ // ED0Q0X .
+ dwDisableBit = (unsigned long)(1<<3);
+ ntx_gpio_insuspend_dir[3] &= ~dwDisableBit; //GP4_3 for EP_3V3/1V8_ON output
+ dwDisableBit = (unsigned long)(1<<7);
+ ntx_gpio_insuspend_dir[4] &= ~dwDisableBit; //GP5_7 for (green)ACTION_LED output
+ }
+
+ if(-1!=giISD_3V3_ON_Ctrl) {
+ dwDisableBit = (unsigned long)(1<<31);
+ ntx_gpio_insuspend_dir[2] &= ~dwDisableBit; //GP3_31 for ISD_3V3_ON output
+ }
+
+
+ base = IO_ADDRESS(GPIO1_BASE_ADDR);
+ ntx_gpio_dir[0] = __raw_readl(base+4);
+ __raw_writel( ntx_gpio_dir[0]&(~ntx_gpio_insuspend_dir[0]), base+4);
+
+ base = IO_ADDRESS(GPIO2_BASE_ADDR);
+ ntx_gpio_dir[1] = __raw_readl(base+4);
+ __raw_writel( ntx_gpio_dir[1]&(~ntx_gpio_insuspend_dir[1]), base+4);
+
+ base = IO_ADDRESS(GPIO3_BASE_ADDR);
+ ntx_gpio_dir[2] = __raw_readl(base+4);
+ __raw_writel( ntx_gpio_dir[2]&(~ntx_gpio_insuspend_dir[2]), base+4);
+
+ base = IO_ADDRESS(GPIO4_BASE_ADDR);
+ ntx_gpio_dir[3] = __raw_readl(base+4);
+ __raw_writel( ntx_gpio_dir[3]&(~ntx_gpio_insuspend_dir[3]), base+4);
+
+ base = IO_ADDRESS(GPIO5_BASE_ADDR);
+ ntx_gpio_dir[4] = __raw_readl(base+4);
+ __raw_writel( ntx_gpio_dir[4]&(~ntx_gpio_insuspend_dir[4]), base+4);
+ }
+}
+
+void ntx_gpio_resume (void)
+{
+ if (gSleep_Mode_Suspend) {
+ void __iomem *base;
+
+ base = IO_ADDRESS(GPIO1_BASE_ADDR);
+ __raw_writel( ntx_gpio_dir[0], base+4);
+
+ base = IO_ADDRESS(GPIO2_BASE_ADDR);
+ __raw_writel( ntx_gpio_dir[1], base+4);
+
+ base = IO_ADDRESS(GPIO3_BASE_ADDR);
+ __raw_writel( ntx_gpio_dir[2], base+4);
+
+ base = IO_ADDRESS(GPIO4_BASE_ADDR);
+ __raw_writel( ntx_gpio_dir[3], base+4);
+
+ base = IO_ADDRESS(GPIO5_BASE_ADDR);
+ __raw_writel( ntx_gpio_dir[4], base+4);
+
+ mxc_iomux_v3_setup_multiple_pads(ntx_suspend_exit_pads,
+ ARRAY_SIZE(ntx_suspend_exit_pads));
+
+#ifdef DUMP_PADS//[
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_24M,MX6SL_PAD_REF_CLK_24M__GPIO_3_21,
+ "I2C3_SCL","exit hibernation");
+ dump_pad_iomux_val(MX6SL_PAD_REF_CLK_32K,MX6SL_PAD_REF_CLK_32K__GPIO_3_22,
+ "I2C3_SDA","exit hibernation");
+#endif//] DUMP_PADS
+
+ }
+ __raw_writel(gUart_ucr1, ioremap(MX6SL_UART1_BASE_ADDR, SZ_4K)+0x80);
+ if (gSleep_Mode_Suspend) {
+
+ if(-1!=giISD_3V3_ON_Ctrl) {
+ gpio_direction_output (GPIO_ISD_3V3_ON,giISD_3V3_ON_Ctrl?1:0);
+ }
+
+ if(1==gptHWCFG->m_val.bLed) {
+ // Blue Led .
+ // ON_LED#
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH);
+ }
+
+
+ if((3==gptHWCFG->m_val.bTouchType || 4==gptHWCFG->m_val.bTouchType) && 0x03==gptHWCFG->m_val.bUIConfig) {
+ // IR Touch Type & MP/RD Mode for IR tool .
+ // reset ir touch
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 0);
+ mdelay (20);
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 1);
+ }
+ else {
+ // turn on ir touch power.
+ gpio_direction_output (GPIO_IR_3V3_ON, 1);
+ if (37 != gptHWCFG->m_val.bPCB) {
+ // E60QB0 .
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SCL__I2C1_SCL);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SDA__I2C1_SDA);
+ }
+ gpio_direction_input (gMX6SL_IR_TOUCH_INT);
+ mdelay (20);
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 1);
+ }
+
+ gpio_free(IMX_GPIO_NR(3, 14));
+ gpio_free(IMX_GPIO_NR(3, 15));
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C2_SCL__I2C2_SCL);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C2_SDA__I2C2_SDA);
+
+ //mxc_epdc_fb_ep1v8_output(1);
+ //gpio_direction_output (GPIO_EP_3V3_ON, 1);
+ //mdelay (5);
+ if(7==gptHWCFG->m_val.bDisplayCtrl) {
+ tps65185_ONOFF(1);
+ }
+ else if(8==gptHWCFG->m_val.bDisplayCtrl) {
+ fp9928_ONOFF(1);
+ }
+ //gpio_direction_output (MX6SL_EP_PWRALL, 1);
+ }
+
+ gpiofn_resume();
+
+ if(36==gptHWCFG->m_val.bPCB || 40==gptHWCFG->m_val.bPCB || 49==gptHWCFG->m_val.bPCB) {
+ // E60Q3X/E60Q5X
+ if(mxc_usb_plug_getstatus()) {
+ led_red(1);
+ }
+ else {
+ led_red(0);
+ }
+ }
+
+#ifdef CONFIG_ANDROID //[
+#else //][!CONFIG_ANDROID
+ g_power_key_pressed = power_key_status(); // POWER key
+ if(0==gptHWCFG->m_val.bUIStyle) {
+ // Ebrmain .
+ if (g_power_key_pressed)
+ mod_timer(&power_key_timer, jiffies + 1);
+ }
+
+ if (LED_conitnuous)
+ wake_up_interruptible(&LED_freeze_WaitQueue);
+ else {
+ ntx_led_blink (3, red_led_period);
+ ntx_led_blink (4, green_led_period);
+ ntx_led_blink (5, blue_led_period);
+ }
+#endif //]CONFIG_ANDROID
+}
+
+
+#include <linux/regulator/consumer.h>
+void ntx_gpio_touch_reset (void)
+{
+ struct regulator *reg_TP3V3 = NULL;
+
+ printk ("[%s-%d] reset touch.\n",__func__,__LINE__);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SCL__GPIO_3_12);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SDA__GPIO_3_13);
+
+ gpio_request(IMX_GPIO_NR(3, 12),"i2c1_scl");
+ gpio_request(IMX_GPIO_NR(3, 13),"i2c1_sda");
+ gpio_direction_output (IMX_GPIO_NR(3, 12), 0);
+ gpio_direction_output (IMX_GPIO_NR(3, 13), 0);
+ // turn off ir touch power.
+ gpio_direction_output (gMX6SL_IR_TOUCH_INT, 0);
+ gpio_direction_output(gMX6SL_IR_TOUCH_RST, 0);
+ if (1==gptHWCFG->m_val.bPMIC) {
+ reg_TP3V3 = regulator_get(NULL,"vdd_ir_3v3");
+ if (IS_ERR(reg_TP3V3))
+ printk ("[%s-%d] regulator_get vdd_ir_3v3 returned NULL!!\n",__func__,__LINE__);
+ else {
+ regulator_force_disable (reg_TP3V3);
+ }
+ }
+ else
+ gpio_direction_output (GPIO_IR_3V3_ON, 0);
+ msleep (200);
+ // turn on ir touch power.
+ if (1==gptHWCFG->m_val.bPMIC) {
+ if (IS_ERR(reg_TP3V3))
+ printk ("[%s-%d] regulator_get vdd_ir_3v3 returned NULL!!\n",__func__,__LINE__);
+ else {
+ regulator_enable (reg_TP3V3);
+ regulator_put (reg_TP3V3);
+ }
+ }
+ else
+ gpio_direction_output (GPIO_IR_3V3_ON, 1);
+ gpio_free(IMX_GPIO_NR(3, 12));
+ gpio_free(IMX_GPIO_NR(3, 13));
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SCL__I2C1_SCL);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_I2C1_SDA__I2C1_SDA);
+ gpio_direction_input (gMX6SL_IR_TOUCH_INT);
+ mdelay (20);
+ gpio_direction_output (gMX6SL_IR_TOUCH_RST, 1);
+}
+
+void ntx_msp430_i2c_force_release (void)
+{
+ int retryCnt=20;
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_REF_CLK_24M__GPIO_3_21);
+ gpio_request(MX6SL_I2C3_SDA, "i2c3_sda");
+ gpio_direction_input (MX6SL_I2C3_SDA);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_REF_CLK_32K__GPIO_3_22);
+ gpio_request(MX6SL_I2C3_SCL, "i2c3_scl");
+ gpio_direction_output (MX6SL_I2C3_SCL, 1);
+ // send clock out until i2c SDA released.
+ while (retryCnt-- && !gpio_get_value (MX6SL_I2C3_SDA)) {
+ gpio_set_value (MX6SL_I2C3_SCL,1);
+ udelay (5);
+ gpio_set_value (MX6SL_I2C3_SCL,0);
+ schedule_timeout (1);
+// udelay (5);
+ }
+ // simulate i2c stop signal
+ gpio_direction_output (MX6SL_I2C3_SDA,0);
+ gpio_free(MX6SL_I2C3_SCL);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_REF_CLK_24M__I2C3_SCL);
+ udelay (2);
+ gpio_free(MX6SL_I2C3_SDA);
+ mxc_iomux_v3_setup_pad(MX6SL_PAD_REF_CLK_32K__I2C3_SDA);
+}
+
+
+void ntx_machine_restart(char mode, const char *cmd)
+{
+ if (cmd && ('\0' != *cmd)) {
+ printk("%s mode=%c,cmd=%s\n",__FUNCTION__,mode,cmd);
+ arm_machine_restart (mode, cmd);
+ }
+ else {
+ printk ("[%s-%d] do hardware reset...\n",__func__,__LINE__);
+ ntx_system_reset(0);
+ }
+}
+
+void ntx_machine_poweroff(void)
+{
+ ntx_system_poweroff(__FUNCTION__);
+}
+
+static int __init initDriver(void)
+{
+ int ret;
+
+ ret = misc_register(&driverDevice);
+ if (ret < 0) {
+ printk("pvi_io: can't get major number\n");
+ return ret;
+ }
+
+ gpio_initials();
+
+ //start a kernel thread;
+ ret = kernel_thread(LED_Thread,NULL,CLONE_KERNEL);
+ if(ret < 0){
+ printk("LED thread creat error\n");
+ }
+
+ ////////////////////////
+ green_led_timer.function = green_led_blink_func;
+ init_timer(&green_led_timer);
+ blue_led_timer.function = blue_led_blink_func;
+ init_timer(&blue_led_timer);
+ red_led_timer.function = red_led_blink_func;
+ init_timer(&red_led_timer);
+
+ pm_power_off = ntx_machine_poweroff;
+ arm_pm_restart = ntx_machine_restart;
+
+ return 0;
+}
+static void __exit exitDriver(void) {
+ misc_deregister(&driverDevice);
+}
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Joe");
+MODULE_VERSION("2007-9-20");
+MODULE_DESCRIPTION ("PVI_IO driver");
+module_init(initDriver);
+module_exit(exitDriver);
diff --git a/arch/arm/mach-mx6/mx6sl_ntx_pmic_pfuze100.c b/arch/arm/mach-mx6/mx6sl_ntx_pmic_pfuze100.c
new file mode 100755
index 00000000..88f2c9c7
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_ntx_pmic_pfuze100.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/machine.h>
+#include <linux/mfd/pfuze.h>
+#include <mach/irqs.h>
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV) (mV * 1000)
+#define uV_to_mV(uV) (uV / 1000)
+#define V_to_uV(V) (mV_to_uV(V * 1000))
+#define uV_to_V(uV) (uV_to_mV(uV) / 1000)
+
+#define PFUZE100_I2C_DEVICE_NAME "pfuze100"
+/* 7-bit I2C bus slave address */
+#define PFUZE100_I2C_ADDR (0x08)
+ /*SWBST*/
+#define PFUZE100_SW1ASTANDBY 33
+#define PFUZE100_SW1ASTANDBY_STBY_VAL (0x19) /* 925mv */
+#define PFUZE100_SW1ASTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW1BSTANDBY 40
+#define PFUZE100_SW1BSTANDBY_STBY_VAL (0x19) /* 925mv */
+#define PFUZE100_SW1BSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW1CSTANDBY 47
+#define PFUZE100_SW1CSTANDBY_STBY_VAL (0x19) /* 925mv */
+#define PFUZE100_SW1CSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW2STANDBY 54
+#define PFUZE100_SW2STANDBY_STBY_VAL 0x0
+#define PFUZE100_SW2STANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW3ASTANDBY 61
+#define PFUZE100_SW3ASTANDBY_STBY_VAL 0x0
+#define PFUZE100_SW3ASTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW3BSTANDBY 68
+#define PFUZE100_SW3BSTANDBY_STBY_VAL 0x0
+#define PFUZE100_SW3BSTANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SW4STANDBY 75
+#define PFUZE100_SW4STANDBY_STBY_VAL 0
+#define PFUZE100_SW4STANDBY_STBY_M (0x3f<<0)
+#define PFUZE100_SWBSTCON1 102
+#define PFUZE100_SWBSTCON1_SWBSTMOD_VAL (0x1<<2)
+#define PFUZE100_SWBSTCON1_SWBSTMOD_M (0x3<<2)
+#define PFUZE100_SW1ACON 36
+#define PFUZE100_SW1ACON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1ACON_SPEED_M (0x3<<6)
+#define PFUZE100_SW1CCON 49
+#define PFUZE100_SW1CCON_SPEED_VAL (0x1<<6) /*default */
+#define PFUZE100_SW1CCON_SPEED_M (0x3<<6)
+
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+static struct regulator_consumer_supply sw1_consumers[] = {
+ {
+ .supply = "VDDCORE",
+ }
+};
+static struct regulator_consumer_supply sw1c_consumers[] = {
+ {
+ .supply = "VDDSOC",
+ },
+};
+#endif
+
+static struct regulator_consumer_supply sw2_consumers[] = {
+ {
+ .supply = "MICVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply sw4_consumers[] = {
+ {
+ .supply = "AUD_1V8",
+ }
+};
+static struct regulator_consumer_supply swbst_consumers[] = {
+ {
+ .supply = "SWBST_5V",
+ }
+};
+static struct regulator_consumer_supply vgen1_consumers[] = {
+ {
+ .supply = "VGEN1_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen2_consumers[] = {
+ {
+ .supply = "VGEN2_1V5",
+ }
+};
+static struct regulator_consumer_supply vgen3_consumers[] = {
+ {
+ .supply = "AVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DCVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "CPVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "PLLVDD",
+ .dev_name = "1-001a",
+ },
+ {
+ .supply = "DBVDD",
+ .dev_name = "1-001a",
+ }
+};
+static struct regulator_consumer_supply vgen4_consumers[] = {
+ {
+ .supply = "VGEN4_1V8",
+ }
+};
+static struct regulator_consumer_supply vgen5_consumers[] = {
+ {
+ .supply = "VGEN5_2V8",
+ }
+};
+static struct regulator_consumer_supply vgen6_consumers[] = {
+ {
+ .supply = "VGEN6_2V8",
+ }
+};
+
+static struct regulator_init_data sw1a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1A",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 650000,
+ .max_uV = 1437500,
+#else
+ .min_uV = 300000,
+ .max_uV = 1875000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifndef CONFIG_MACH_MX6SL_NTX
+ .num_consumer_supplies = ARRAY_SIZE(sw1_consumers),
+ .consumer_supplies = sw1_consumers,
+#endif
+#endif
+};
+
+static struct regulator_init_data sw1b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1B",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw1c_init = {
+ .constraints = {
+ .name = "PFUZE100_SW1C",
+ .min_uV = 300000,
+ .max_uV = 1875000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+#ifdef CONFIG_MX6_INTER_LDO_BYPASS
+#ifndef CONFIG_MACH_MX6SL_NTX
+ .num_consumer_supplies = ARRAY_SIZE(sw1c_consumers),
+ .consumer_supplies = sw1c_consumers,
+#endif
+#endif
+};
+
+static struct regulator_init_data sw2_init = {
+ .constraints = {
+ .name = "PFUZE100_SW2",
+#if PFUZE100_SW2_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw2_consumers),
+ .consumer_supplies = sw2_consumers,
+};
+
+static struct regulator_init_data sw3a_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3A",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw3b_init = {
+ .constraints = {
+ .name = "PFUZE100_SW3B",
+#if PFUZE100_SW3_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data sw4_init = {
+ .constraints = {
+ .name = "PFUZE100_SW4",
+#if PFUZE100_SW4_VOL6
+ .min_uV = 800000,
+ .max_uV = 3950000,
+#else
+ .min_uV = 400000,
+ .max_uV = 1975000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sw4_consumers),
+ .consumer_supplies = sw4_consumers,
+};
+
+static struct regulator_init_data swbst_init = {
+ .constraints = {
+ .name = "PFUZE100_SWBST",
+ .min_uV = 5000000,
+ .max_uV = 5150000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(swbst_consumers),
+ .consumer_supplies = swbst_consumers,
+};
+
+static struct regulator_init_data vsnvs_init = {
+ .constraints = {
+ .name = "PFUZE100_VSNVS",
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vrefddr_init = {
+ .constraints = {
+ .name = "PFUZE100_VREFDDR",
+ .always_on = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data vgen1_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN1",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen1_consumers),
+ .consumer_supplies = vgen1_consumers,
+};
+
+static struct regulator_init_data vgen2_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN2",
+#ifdef PFUZE100_FIRST_VERSION
+ .min_uV = 1200000,
+ .max_uV = 1550000,
+#else
+ .min_uV = 800000,
+ .max_uV = 1550000,
+#endif
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen2_consumers),
+ .consumer_supplies = vgen2_consumers,
+
+};
+
+static struct regulator_init_data vgen3_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN3",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 0,
+ .boot_on = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen3_consumers),
+ .consumer_supplies = vgen3_consumers,
+};
+
+static struct regulator_init_data vgen4_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN4",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen4_consumers),
+ .consumer_supplies = vgen4_consumers,
+};
+
+static struct regulator_init_data vgen5_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN5",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen5_consumers),
+ .consumer_supplies = vgen5_consumers,
+};
+
+static struct regulator_init_data vgen6_init = {
+ .constraints = {
+ .name = "PFUZE100_VGEN6",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .valid_modes_mask = 0,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vgen6_consumers),
+ .consumer_supplies = vgen6_consumers,
+};
+
+static int pfuze100_init(struct mc_pfuze *pfuze)
+{
+ int ret;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ASTANDBY,
+ PFUZE100_SW1ASTANDBY_STBY_M,
+ PFUZE100_SW1ASTANDBY_STBY_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CSTANDBY,
+ PFUZE100_SW1CSTANDBY_STBY_M,
+ PFUZE100_SW1CSTANDBY_STBY_VAL);
+ if (ret)
+ goto err;
+ /*set SW1AB/SW1CDVSPEED as 25mV step each 4us,quick than 16us before.*/
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1ACON,
+ PFUZE100_SW1ACON_SPEED_M,
+ PFUZE100_SW1ACON_SPEED_VAL);
+ if (ret)
+ goto err;
+ ret = pfuze_reg_rmw(pfuze, PFUZE100_SW1CCON,
+ PFUZE100_SW1CCON_SPEED_M,
+ PFUZE100_SW1CCON_SPEED_VAL);
+ if (ret)
+ goto err;
+ return 0;
+err:
+ printk(KERN_ERR "pfuze100 init error!\n");
+ return -1;
+}
+
+static struct pfuze_regulator_init_data mx6q_sabreauto_pfuze100_regulators[] = {
+ {.id = PFUZE100_SW1A, .init_data = &sw1a_init},
+// {.id = PFUZE100_SW1B, .init_data = &sw1b_init},
+ {.id = PFUZE100_SW1C, .init_data = &sw1c_init},
+#if 0
+ {.id = PFUZE100_SW2, .init_data = &sw2_init},
+ {.id = PFUZE100_SW3A, .init_data = &sw3a_init},
+ {.id = PFUZE100_SW3B, .init_data = &sw3b_init},
+ {.id = PFUZE100_SW4, .init_data = &sw4_init},
+ {.id = PFUZE100_SWBST, .init_data = &swbst_init},
+ {.id = PFUZE100_VSNVS, .init_data = &vsnvs_init},
+ {.id = PFUZE100_VREFDDR, .init_data = &vrefddr_init},
+ {.id = PFUZE100_VGEN1, .init_data = &vgen1_init},
+ {.id = PFUZE100_VGEN2, .init_data = &vgen2_init},
+ {.id = PFUZE100_VGEN3, .init_data = &vgen3_init},
+ {.id = PFUZE100_VGEN4, .init_data = &vgen4_init},
+ {.id = PFUZE100_VGEN5, .init_data = &vgen5_init},
+ {.id = PFUZE100_VGEN6, .init_data = &vgen6_init},
+#endif
+};
+
+static struct pfuze_platform_data pfuze100_plat = {
+ .flags = PFUZE_USE_REGULATOR,
+ .num_regulators = ARRAY_SIZE(mx6q_sabreauto_pfuze100_regulators),
+ .regulators = mx6q_sabreauto_pfuze100_regulators,
+ .pfuze_init = pfuze100_init,
+};
+
+static struct i2c_board_info __initdata pfuze100_i2c_device = {
+ I2C_BOARD_INFO(PFUZE100_I2C_DEVICE_NAME, PFUZE100_I2C_ADDR),
+ .irq=0,
+ .platform_data = &pfuze100_plat,
+};
+
+int __init mx6sl_ntx_init_pfuze100(u32 int_gpio)
+{
+ if (int_gpio)
+ pfuze100_i2c_device.irq = gpio_to_irq(int_gpio); /*update INT gpio */
+ return i2c_register_board_info(0, &pfuze100_i2c_device, 1);
+}
diff --git a/arch/arm/mach-mx6/mx6sl_wfi.S b/arch/arm/mach-mx6/mx6sl_wfi.S
new file mode 100644
index 00000000..c51fcc77
--- /dev/null
+++ b/arch/arm/mach-mx6/mx6sl_wfi.S
@@ -0,0 +1,727 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/linkage.h>
+#include <mach/hardware.h>
+/*
+ * The code size is limited to 1.5K
+ * as we may need to store this code
+ * along with the suspend and DDR freq change
+ * code within 8K of IRAM.
+ */
+
+#define IRAM_WAIT_SIZE MX6SL_WFI_IRAM_CODE_SIZE
+
+.extern iram_tlb_phys_addr
+.extern mx6sl_wfi_iram_base
+.extern mx6sl_wfi_iram_phys_addr
+
+ .macro sl_ddr_io_save
+
+ ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
+ ldr r5, [r1, #0x310] /* DRAM_DQM1 */
+ ldr r6, [r1, #0x314] /* DRAM_DQM2 */
+ ldr r7, [r1, #0x318] /* DRAM_DQM3 */
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x5c4] /* GPR_B0DS */
+ ldr r5, [r1, #0x5cc] /* GPR_B1DS */
+ ldr r6, [r1, #0x5d4] /* GPR_B2DS */
+ ldr r7, [r1, #0x5d8] /* GPR_B3DS */
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x300] /* DRAM_CAS */
+ ldr r5, [r1, #0x31c] /* DRAM_RAS */
+ ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ ldr r5, [r1, #0x5c0] /* DDRMODE */
+ ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
+ ldr r7, [r1, #0x340] /* DRAM_SODT1*/
+ stmfd r9!, {r4-r7}
+
+ ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ ldr r6, [r1, #0x320] /* DRAM_RESET */
+ stmfd r9!, {r4-r6}
+
+ .endm
+
+ .macro sl_ddr_io_restore
+
+ /* r9 points to IRAM stack.
+ * r1 points to IOMUX base address.
+ * r8 points to MMDC base address.
+ */
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x30c] /* DRAM_DQM0 */
+ str r5, [r1, #0x310] /* DRAM_DQM1 */
+ str r6, [r1, #0x314] /* DRAM_DQM2 */
+ str r7, [r1, #0x318] /* DRAM_DQM3 */
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x5c4] /* GPR_B0DS */
+ str r5, [r1, #0x5cc] /* GPR_B1DS */
+ str r6, [r1, #0x5d4] /* GPR_B2DS */
+ str r7, [r1, #0x5d8] /* GPR_B3DS */
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x300] /* DRAM_CAS */
+ str r5, [r1, #0x31c] /* DRAM_RAS */
+ str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r7, [r1, #0x5ac] /* GPR_ADDS*/
+
+ ldmea r9!, {r4-r7}
+ str r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r5, [r1, #0x5c0] /* DDRMODE */
+ str r6, [r1, #0x33c] /* DRAM_SODT0*/
+ str r7, [r1, #0x340] /* DRAM_SODT1*/
+
+ ldmea r9!, {r4-r6}
+ str r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r5, [r1, #0x334] /* DRAM_SDCKE1 */
+ str r6, [r1, #0x320] /* DRAM_RESET */
+
+ /* Need to reset the FIFO to avoid MMDC lockup
+ * caused because of floating/changing the
+ * configuration of many DDR IO pads.
+ */
+ /* reset read FIFO, RST_RD_FIFO */
+ ldr r7, =0x83c
+ ldr r6, [r8, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r8, r7]
+fifo_reset1_wait:
+ ldr r6, [r8, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset1_wait
+
+ /* reset FIFO a second time */
+ ldr r6, [r8, r7]
+ orr r6, r6, #0x80000000
+ str r6, [r8, r7]
+fifo_reset2_wait:
+ ldr r6, [r8, r7]
+ and r6, r6, #0x80000000
+ cmp r6, #0
+ bne fifo_reset2_wait
+
+ .endm
+
+ .macro sl_ddr_io_set_lpm
+
+ mov r4, #0
+ str r4, [r1, #0x30c] /* DRAM_DQM0 */
+ str r4, [r1, #0x310] /* DRAM_DQM1 */
+ str r4, [r1, #0x314] /* DRAM_DQM2 */
+ str r4, [r1, #0x318] /* DRAM_DQM3 */
+
+ str r4, [r1, #0x5c4] /* GPR_B0DS */
+ str r4, [r1, #0x5cc] /* GPR_B1DS */
+ str r4, [r1, #0x5d4] /* GPR_B2DS */
+ str r4, [r1, #0x5d8] /* GPR_B3DS */
+
+ str r4, [r1, #0x300] /* DRAM_CAS */
+ str r4, [r1, #0x31c] /* DRAM_RAS */
+ str r4, [r1, #0x338] /* DRAM_SDCLK_0 */
+ str r4, [r1, #0x5ac] /* GPR_ADDS*/
+
+ str r4, [r1, #0x5b0] /* DDRMODE_CTL */
+ str r4, [r1, #0x5c0] /* DDRMODE */
+ str r4, [r1, #0x33c] /* DRAM_SODT0*/
+ str r4, [r1, #0x340] /* DRAM_SODT1*/
+
+ mov r4, #0x80000
+ str r4, [r1, #0x320] /* DRAM_RESET */
+ mov r4, #0x1000
+ str r4, [r1, #0x330] /* DRAM_SDCKE0 */
+ str r4, [r1, #0x334] /* DRAM_SDCKE1 */
+
+ .endm
+
+ .align 3
+/*
+ * mx6sl_wait
+ *
+ * Idle the processor (eg, wait for interrupt).
+ * Make sure DDR is in self-refresh.
+ * IRQs are already disabled.
+ * r0 : arm_podf before WFI is entered
+ * r1: WFI IRAMcode base address.
+ */
+ENTRY(mx6sl_wait)
+
+ push {r4-r12}
+
+mx6sl_lpm_wfi:
+ mov r11, r2
+
+ /* Get the IRAM data storage address. */
+ mov r10, r1
+ mov r9, r1 /* get suspend_iram_base */
+ add r9, r9, #IRAM_WAIT_SIZE /* 1.5K */
+
+ /*
+ * To ensure no page table walks occur in DDR, we
+ * have a another page table stored in IRAM that only
+ * contains entries pointing to IRAM, AIPS1 and AIPS2.
+ * We need to set the TTBR1 to the new IRAM TLB.
+ * Do the following steps:
+ * 1. Flush the Branch Target Address Cache (BTAC)
+ * 2. Set TTBR1 to point to IRAM page table.
+ * 3. Disable page table walks in TTBR0 (PD0 = 1)
+ * 4. Set TTBR0.N=1, implying 0-2G is translated by TTBR0
+ * and 2-4G is translated by TTBR1.
+ */
+
+ ldr r6, =iram_tlb_phys_addr
+ ldr r7, [r6]
+
+ /* Flush the BTAC. */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+ /* Disable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+ isb
+
+ /* Store the IRAM table in TTBR1 */
+ mcr p15, 0, r7, c2, c0, 1
+
+ /* Read TTBCR and set PD0=1, N = 1 */
+ mrc p15, 0, r6, c2, c0, 2
+ orr r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+
+ /* Disable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ bic r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ dsb
+
+ /*
+ * Sync L2 and then disable it.
+ */
+ dsb
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r6, =0x0
+ str r6, [r1, #0x730]
+ /* Disable L2. */
+ str r6, [r1, #0x100]
+ dsb
+ isb
+
+ ldr r1, =MX6Q_IOMUXC_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+
+ /* Save the DDR IO state. */
+ sl_ddr_io_save
+
+ ldr r3, =ANATOP_BASE_ADDR
+ add r3, r3, #PERIPBASE_VIRT
+ ldr r2, =CCM_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
+ ldr r8, =MMDC_P0_BASE_ADDR
+ add r8, r8, #PERIPBASE_VIRT
+
+ /* Disable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* Make the DDR explicitly enter self-refresh. */
+ ldr r6, [r8, #0x404]
+ orr r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_set_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ bne poll_dvfs_set_1
+
+ /* set SBS step-by-step mode */
+ ldr r6, [r8, #0x410]
+ orr r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ cmp r11, #1
+ beq audio_mode
+
+ /* Now set DDR rate to 1MHz. */
+ /* DDR is from bypassed PLL2 on periph2_clk2 path.
+ * Set the periph2_clk2_podf to divide by 8.
+ */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x07
+ str r6, [r2, #0x14]
+
+ /* Now set MMDC PODF to divide by 3. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x10
+ str r6, [r2, #0x14]
+ b mmdc_podf
+
+audio_mode:
+ /* MMDC is from PLL2_200M.
+ * Set the mmdc_podf to div by 8.
+ */
+ ldr r6, [r2, #0x14]
+ orr r6, r6, #0x38
+ str r6, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+mmdc_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne mmdc_podf
+
+ /* Set the DDR IO in LPM state. */
+ sl_ddr_io_set_lpm
+
+ cmp r11, #1
+ beq do_audio_arm_clk
+
+ /* Check if none of the PLLs are
+ * locked, except PLL1 which will get
+ * bypassed below.
+ * We should not be here if PLL2 is not
+ * bypassed.
+ */
+ ldr r7, =1
+ /* USB1 PLL3 */
+ ldr r6, [r3, #0x10]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* USB2 PLL7 */
+ ldr r6, [r3, #0x20]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* Audio PLL4 */
+ ldr r6, [r3, #0x70]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* Video PLL5 */
+ ldr r6, [r3, #0xA0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ /* ENET PLL8 */
+ ldr r6, [r3, #0xE0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ beq no_analog_saving
+
+ b cont
+
+no_analog_saving:
+ ldr r7, =0
+
+cont:
+ /*Set the AHB to 3MHz. AXI to 3MHz. */
+ ldr r9, [r2, #0x14]
+ mov r6, r9
+ orr r6, r6, #0x1c00
+ orr r6, r6, #0x70000
+ str r6, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+ahb_podf:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop
+
+ /* Now set ARM to 24MHz. */
+ /* Move ARM to be sourced from STEP_CLK
+ * after setting STEP_CLK to 24MHz.
+ */
+ ldr r6, [r2, #0xc]
+ bic r6, r6, #0x100
+ str r6, [r2, #0x0c]
+ /* Now PLL1_SW_CLK to step_clk. */
+ ldr r6, [r2, #0x0c]
+ orr r6, r6, #0x4
+ str r6, [r2, #0x0c]
+
+ /* Bypass PLL1 and power it down. */
+ ldr r6, =(1 << 16)
+ orr r6, r6, #0x1000
+ str r6, [r3, #0x04]
+
+ /* Set the ARM PODF to divide by 8. */
+ /* IPG is at 1.5MHz here, we need ARM to
+ * run at the 12:5 ratio (WAIT mode issue).
+ */
+ ldr r6, =0x7
+ str r6, [r2, #0x10]
+
+ /* Loop till podf is accepted. */
+podf_loop:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop
+
+ /* Check if we can save some
+ * in the Analog section.
+ */
+ cmp r7, #0x1
+ bne do_wfi
+
+ /* Disable 1p1 brown out. */
+ ldr r6, [r3, #0x110]
+ bic r6, r6, #0x2
+ str r6, [r3, #0x110]
+
+ /* Enable the weak 2P5 */
+ ldr r6, [r3, #0x130]
+ orr r6, r6, #0x40000
+ str r6, [r3, #0x130]
+
+ /*Disable main 2p5. */
+ ldr r6, [r3, #0x130]
+ bic r6, r6, #0x1
+ str r6, [r3, #0x130]
+
+ /* Set the OSC bias current to -37.5%
+ * to drop the power on VDDHIGH.
+ */
+ ldr r6, [r3, #0x150]
+ orr r6, r6, #0xC000
+ str r6, [r3, #0x150]
+
+ /* Enable low power bandgap */
+ ldr r6, [r3, #0x260]
+ orr r6, r6, #0x20
+ str r6, [r3, #0x260]
+
+ /* turn off the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r3, #0x260]
+ orr r6, r6, #0x80
+ str r6, [r3, #0x260]
+
+ /* Clear the REFTOP_SELFBIASOFF,
+ * self-bias circuit of the band gap.
+ * Per RM, should be cleared when
+ * band gap is powered down.
+ */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0x8
+ str r6, [r3, #0x150]
+
+ /*Power down the regular bandgap. */
+ ldr r6, [r3, #0x150]
+ orr r6, r6, #0x1
+ str r6, [r3, #0x150]
+
+ b do_wfi
+
+do_audio_arm_clk:
+ /*
+ * ARM is from PLL2_PFD2_400M here.
+ * Switch ARM to bypassed PLL1.
+ */
+ ldr r6, [r2, #0xC]
+ bic r6, r6, #0x4
+ str r6, [r2, #0xC]
+
+ /*
+ * Set the ARM_PODF to divide by 2
+ * as IPG is at 4MHz, we cannot run
+ * ARM_CLK above 9.6MHz when
+ * system enters WAIT mode.
+ */
+ ldr r6, =0x2
+ str r6, [r2, #0x10]
+
+ /* Loop till podf is accepted. */
+podf_loop_audio:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop_audio
+
+do_wfi:
+ /* Now do WFI. */
+ wfi
+
+ /* Set original ARM PODF back. */
+ str r0, [r2, #0x10]
+
+ /* Loop till podf is accepted. */
+podf_loop1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop1
+
+ cmp r11, #1
+ beq audio_arm_clk_restore
+
+ /*
+ * Check if powered down
+ * analog components.
+ */
+ cmp r7, #0x1
+ bne skip_analog_restore
+
+ /* Power up the regular bandgap. */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0x1
+ str r6, [r3, #0x150]
+
+ /* turn on the bias current
+ * from the regular bandgap.
+ */
+ ldr r6, [r3, #0x260]
+ bic r6, r6, #0x80
+ str r6, [r3, #0x260]
+
+ /* Disable the low power bandgap */
+ ldr r6, [r3, #0x260]
+ bic r6, r6, #0x20
+ str r6, [r3, #0x260]
+
+ /*
+ * Set the OSC bias current to max
+ * value for normal operation.
+ */
+ ldr r6, [r3, #0x150]
+ bic r6, r6, #0xC000
+ str r6, [r3, #0x150]
+
+ /*Enable main 2p5. */
+ ldr r6, [r3, #0x130]
+ orr r6, r6, #0x1
+ str r6, [r3, #0x130]
+
+ /* Ensure the 2P5 is up. */
+loop_2p5:
+ ldr r6, [r3, #0x130]
+ and r6, r6, #0x20000
+ cmp r6, #0x20000
+ bne loop_2p5
+
+ /* Disable the weak 2P5 */
+ ldr r6, [r3, #0x130]
+ bic r6, r6, #0x40000
+ str r6, [r3, #0x130]
+
+ /* Enable 1p1 brown out. */
+ ldr r6, [r3, #0x110]
+ orr r6, r6, #0x2
+ str r6, [r3, #0x110]
+
+skip_analog_restore:
+
+ /* Power up PLL1 and un-bypass it. */
+ ldr r6, =(1 << 12)
+ str r6, [r3, #0x08]
+
+ /* Wait for PLL1 to relock. */
+wait_for_pll_lock:
+ ldr r6, [r3, #0x0]
+ and r6, r6, #0x80000000
+ cmp r6, #0x80000000
+ bne wait_for_pll_lock
+
+ ldr r6, =(1 << 16)
+ str r6, [r3, #0x08]
+
+ /* Set PLL1_sw_clk back to PLL1. */
+ ldr r6, [r2, #0x0c]
+ bic r6, r6, #0x4
+ str r6, [r2, #0xc]
+
+ /* Restore AHB/AXI back. */
+ str r9, [r2, #0x14]
+
+ /* Loop till podf is accepted. */
+ahb_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne podf_loop1
+
+ b wfi_restore
+
+audio_arm_clk_restore:
+ /* Move ARM back to PLL2_PFD2_400M */
+ ldr r6, [r2, #0xC]
+ orr r6, r6, #0x4
+ str r6, [r2, #0xC]
+
+wfi_restore:
+ mov r9, r10 /* get suspend_iram_base */
+ add r9, r9, #IRAM_WAIT_SIZE /* 4K */
+
+ /* Restore the DDR IO before exiting self-refresh. */
+ sl_ddr_io_restore
+
+ cmp r11, #1
+ beq mmdc_audio_restore
+
+ /* Set MMDC back to 24MHz. */
+ /* Set periph2_clk2_podf to divide by 1. */
+ /* Now set MMDC PODF to divide by 1. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x3f
+ str r6, [r2, #0x14]
+
+ b mmdc_podf1
+
+mmdc_audio_restore:
+ /* Set MMDC back to 100MHz. */
+ ldr r6, [r2, #0x14]
+ bic r6, r6, #0x38
+ orr r6, r6, #0x8
+ str r6, [r2, $0x14]
+
+mmdc_podf1:
+ ldr r6, [r2, #0x48]
+ cmp r6, #0x0
+ bne mmdc_podf1
+
+ /* clear DVFS - exit from self refresh mode */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x200000
+ str r6, [r8, #0x404]
+
+poll_dvfs_clear_1:
+ ldr r6, [r8, #0x404]
+ and r6, r6, #0x2000000
+ cmp r6, #0x2000000
+ beq poll_dvfs_clear_1
+
+ /* Enable Automatic power savings. */
+ ldr r6, [r8, #0x404]
+ bic r6, r6, #0x01
+ str r6, [r8, #0x404]
+
+ /* clear SBS - unblock DDR accesses */
+ ldr r6, [r8, #0x410]
+ bic r6, r6, #0x100
+ str r6, [r8, #0x410]
+
+ /* Enable L2. */
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ ldr r6, =0x1
+ str r6, [r1, #0x100]
+
+ /* Enable L1 data cache. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x4
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Restore the TTBCR */
+
+ dsb
+ isb
+ /* Read TTBCR and set PD0=0, N = 0 */
+ mrc p15, 0, r6, c2, c0, 2
+ bic r6, r6, #0x11
+ mcr p15, 0, r6, c2, c0, 2
+
+ dsb
+ isb
+
+ /* flush the TLB */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c8, c3, 0
+ dsb
+ isb
+
+ /* Enable Branch Prediction, Z bit in SCTLR. */
+ mrc p15, 0, r6, c1, c0, 0
+ orr r6, r6, #0x800
+ mcr p15, 0, r6, c1, c0, 0
+
+ /* Flush the Branch Target Address Cache (BTAC) */
+ ldr r6, =0x0
+ mcr p15, 0, r6, c7, c1, 6
+
+
+ /* Add these nops so that the
+ * prefetcher will not try to get
+ * any instructions from DDR.
+ * The prefetch depth is about 23
+ * on A9, so adding 25 nops.
+ */
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ pop {r4-r12}
+
+ /* Restore registers */
+ mov pc, lr
+
+ .type mx6sl_do_wait, #object
+ENTRY(mx6sl_do_wait)
+ .word mx6sl_wait
+ .size mx6sl_wait, . - mx6sl_wait
+
diff --git a/arch/arm/mach-mx6/ntx_hwconfig.h b/arch/arm/mach-mx6/ntx_hwconfig.h
new file mode 100755
index 00000000..cba4f94e
--- /dev/null
+++ b/arch/arm/mach-mx6/ntx_hwconfig.h
@@ -0,0 +1,267 @@
+#ifndef __ntx_hwconfig_h//[
+#define __ntx_hwconfig_h
+
+
+#ifdef __cplusplus //[
+extern "C" {
+#endif //] __cplusplus
+
+
+#define SYSHWCONFIG_SEEKSIZE (1024*512)
+
+
+typedef struct tagNTXHWCFG_HDR {
+ char cMagicNameA[10];// should be "HW CONFIG "
+ char cVersionNameA[5];// should be "vx.x"
+ unsigned char bHWConfigSize;// v0.1=19 .
+} NTXHWCFG_HDR ;
+
+typedef struct tagNTXHWCFG_VAL {
+ unsigned char bPCB;//
+ unsigned char bKeyPad;// key pad type .
+ unsigned char bAudioCodec;//
+ unsigned char bAudioAmp;//
+ unsigned char bWifi;//
+ unsigned char bBT;//
+ unsigned char bMobile;//
+ unsigned char bTouchCtrl;//touch controller .
+ unsigned char bTouchType;//touch type .
+ unsigned char bDisplayCtrl;//
+ unsigned char bDisplayPanel;//
+ unsigned char bRSensor;//
+ unsigned char bMicroP;//
+ unsigned char bCustomer;//
+ unsigned char bBattery;//
+ unsigned char bLed;//
+ unsigned char bRamSize;// ram size
+ unsigned char bIFlash; // internal flash type .
+ unsigned char bExternalMem;// external sd type .
+ unsigned char bRootFsType;// root fs type .
+ unsigned char bSysPartType;// system partition type .
+ unsigned char bProgressXHiByte; // Progress bar position while boot ,X
+ unsigned char bProgressXLoByte; // ,X
+ unsigned char bProgressYHiByte; // ,Y
+ unsigned char bProgressYLoByte; // ,Y
+ unsigned char bProgressCnts; // Cnt .
+ unsigned char bContentType; // Book content type .
+ unsigned char bCPU; //main cpu type .
+ unsigned char bUIStyle; // UI style .
+ unsigned char bRamType; // Ram Type .
+ unsigned char bUIConfig; // UI config .
+ unsigned char bDisplayResolution;// Display resolution .
+ unsigned char bFrontLight;// Front Light .
+ unsigned char bCPUFreq;// CPU frequency .
+ unsigned char bHallSensor;// Hall Sensor Controller .
+ unsigned char bDisplayBusWidth;// Display BUS width/bits .
+ unsigned char bFrontLight_Flags;// Front Light Flags .
+ unsigned char bPCB_Flags;// PCB Flags .
+ unsigned char bFrontLight_LED_Driver;// Front Light LED driver .
+ unsigned char bVCOM_10mV_HiByte;// VCOM mV High byte .
+ unsigned char bVCOM_10mV_LoByte;// VCOM mV Low byte .
+ unsigned char bPCB_REV;// PCB revision .
+ unsigned char bPCB_LVL;// PCB develop level .
+ unsigned char bHOME_LED_PWM;// HOME LED PWM source .
+ unsigned char bPMIC;// System PMIC .
+ unsigned char bFL_PWM;// FrontLight PWM source
+ unsigned char bRTC;// System RTC source
+ unsigned char bBootOpt;// Boot option
+ unsigned char bTouch2Ctrl;//touch controller .
+ unsigned char bTouch2Type;//touch type .
+ unsigned char bGPS;//GPS module .
+ unsigned char bFM;//FM module .
+} NTXHWCFG_VAL ;
+
+typedef struct tagNTX_HWCONFG{
+ NTXHWCFG_HDR m_hdr;
+ NTXHWCFG_VAL m_val;
+ unsigned char m_bReserveA[110-sizeof(NTXHWCFG_HDR)-sizeof(NTXHWCFG_VAL)];
+} NTX_HWCONFIG;
+
+// Filed types ...
+#define FIELD_TYPE_IDXSTR 0
+#define FIELD_TYPE_BYTE 1
+#define FIELD_TYPE_FLAGS 2
+
+// Filed Flags ...
+#define FIELD_FLAGS_HW 0x0000
+#define FIELD_FLAGS_SW 0x0001
+
+
+typedef struct tagHwConfigField{
+ char *szVersion;
+ char *szFieldName ;
+ int iFieldValueCnt;
+ char **szFieldValueA ;
+ unsigned short wFieldType;
+ unsigned short wFieldFlags;
+} HwConfigField ;
+
+
+extern const char * gszPCBA[];
+extern const char * gszKeyPadA[];
+extern const char * gszAudioCodecA[];//
+extern const char * gszAudioAmpA[];//
+extern const char * gszWifiA[];//
+extern const char * gszBTA[];//
+extern const char * gszMobileA[];//
+extern const char * gszTouchCtrlA[];//touch controller .
+extern const char * gszTouchTypeA[];//
+extern const char * gszDisplayCtrlA[];
+extern const char * gszDisplayPanelA[];
+extern const char * gszRSensorA[];//
+extern const char * gszMicroPA[];//
+extern const char * gszCustomerA[];//
+extern const char * gszBatteryA[];//
+extern const char * gszLedA[];//
+extern const char * gszRamSizeA[];// ram size
+extern const char * gszIFlashA[]; // internal flash type .
+extern const char * gszExternalMemA[];// external sd type .
+extern const char * gszRootFsTypeA[];// root fs type .
+extern const char * gszSysPartTypeA[];// system partition type .
+extern const char * gszCPUA[];// cpu type .
+extern const char * gszUIStyleA[];// UI Style (netronix UI/customer UI) .
+extern const char * gszRAMTypeA[];// Ram Type .
+extern const char * gszUIConfigA[];// UI Config .
+extern const char * gszDisplayResolutionA[];// Display Resolution .
+extern const char * gszFrontLightA[];// Front Light .
+extern const char * gszCPUFreqA[];// CPU frequency .
+extern const char * gszHallSensorA[];// Hall Sensor .
+extern const char * gszDisplayBusWidthA[];// Display BUS width .
+extern const char * gszFrontLightLEDrvA[];//Front Light LED driver IC .
+extern const char * gszPCB_LVLA[];//PCB develop level .
+extern const char * gszHOME_LED_PWMA[];// HOME LED PWM source .
+extern const char * gszPMICA[];// System PMIC .
+extern const char * gszFL_PWMA[];// FrontLight PWM source
+extern const char * gszRTCA[];// System RTC source .
+extern const char * gszFMA[];// System RTC source .
+extern const char * gszGPSA[];// System RTC source .
+
+
+// the return value of hw config apis . >=0 is success ,others is fail .
+#define HWCFG_RET_SUCCESS (0)
+#define HWCFG_RET_PTRERR (-1) // parameter include error pointer
+#define HWCFG_RET_HDRNOTMATCH (-2) // hwconfig header magic not match .
+#define HWCFG_RET_CFGVERTOOOLD (-3) // hwconfig tool version newer than config struct value (you should update the config file)...
+#define HWCFG_RET_CFGVERTOONEW (-4) // hwconfig tool version older than config struct value (you should update the config tool)...
+#define HWCFG_RET_CFGVERNOTMATCH (-5) // hwconfig tool version and config struct version not match ...
+#define HWCFG_RET_CFGVERFMTERR (-6) // config version format error (must be vX.X) ...
+#define HWCFG_RET_NOTHISFIELDIDX (-7) // field index error .
+#define HWCFG_RET_NOTHISFIELDNAME (-8) // field name error .
+#define HWCFG_RET_FILEOPENFAIL (-9) // file open fail .
+#define HWCFG_RET_FILEWRITEFAIL (-10) // file open fail .
+#define HWCFG_RET_FIELDTYPEERROR (-11) // field type error .
+#define HWCFG_RET_FIELDTRDONLY (-12) // field read only .
+#define HWCFG_RET_CFGVALFLAGIDXERROR (-13) // index of config's flags not avalible .
+#define HWCFG_RET_CFGVALFLAGNAMEERROR (-14) // flag name of config not avalible .
+#define HWCFG_RET_FIELDIDXOUTRANGE (-15) // field index out of range .
+
+
+// ntx hardward config field index list ...
+#define HWCFG_FLDIDX_PCB 0
+#define HWCFG_FLDIDX_KeyPad 1
+#define HWCFG_FLDIDX_AudioCodec 2
+#define HWCFG_FLDIDX_AudioAmp 3
+#define HWCFG_FLDIDX_Wifi 4
+#define HWCFG_FLDIDX_BT 5
+#define HWCFG_FLDIDX_Mobile 6
+#define HWCFG_FLDIDX_TouchCtrl 7
+#define HWCFG_FLDIDX_TouchType 8
+#define HWCFG_FLDIDX_DisplayCtrl 9
+#define HWCFG_FLDIDX_DisplayPanel 10
+#define HWCFG_FLDIDX_RSensor 11
+#define HWCFG_FLDIDX_MicroP 12
+#define HWCFG_FLDIDX_Customer 13
+#define HWCFG_FLDIDX_Battery 14
+#define HWCFG_FLDIDX_Led 15
+#define HWCFG_FLDIDX_RamSize 16
+#define HWCFG_FLDIDX_IFlash 17
+#define HWCFG_FLDIDX_ExternalMem 18
+#define HWCFG_FLDIDX_RootFsType 19 // v0.2
+#define HWCFG_FLDIDX_SysPartType 20 // v0.3
+
+#define HWCFG_FLDIDX_ProgressXHiByte 21 // v0.4
+#define HWCFG_FLDIDX_ProgressXLoByte 22 // v0.4
+#define HWCFG_FLDIDX_ProgressYHiByte 23 // v0.4
+#define HWCFG_FLDIDX_ProgressYLoByte 24 // v0.4
+#define HWCFG_FLDIDX_ProgressCnts 25 // v0.4
+
+#define HWCFG_FLDIDX_ContentType 26 // v0.5
+#define HWCFG_FLDIDX_CPU 27 // v0.6
+#define HWCFG_FLDIDX_UISTYLE 28 // v0.7
+
+#define HWCFG_FLDIDX_RAMTYPE 29 // v0.8
+#define HWCFG_FLDIDX_UICONFIG 30 // v0.9
+#define HWCFG_FLDIDX_DISPLAYRESOLUTION 31 // v1.0
+#define HWCFG_FLDIDX_FRONTLIGHT 32 // v1.1
+#define HWCFG_FLDIDX_CPUFREQ 33 // v1.2
+#define HWCFG_FLDIDX_HALLSENSOR 34 // v1.3
+#define HWCFG_FLDIDX_DisplayBusWidth 35 // v1.4
+#define HWCFG_FLDIDX_FrontLight_Flags 36 // v1.5
+#define HWCFG_FLDIDX_PCB_Flags 37 // v1.6
+#define HWCFG_FLDIDX_FrontLight_LEDrv 38 // v1.7
+#define HWCFG_FLDIDX_VCOM_10mV_HiByte 39 // v1.8
+#define HWCFG_FLDIDX_VCOM_10mV_LoByte 40 // v1.8
+#define HWCFG_FLDIDX_PCB_REV 41 // v1.9
+#define HWCFG_FLDIDX_PCB_LVL 42 // v2.0
+#define HWCFG_FLDIDX_HOME_PWM 43 // v2.1
+#define HWCFG_FLDIDX_PMIC 44 // v2.1
+#define HWCFG_FLDIDX_FL_PWM 45// v2.1
+#define HWCFG_FLDIDX_RTC 46// v2.1
+#define HWCFG_FLDIDX_BOOTOPT 47// v2.2
+#define HWCFG_FLDIDX_Touch2Ctrl 48 // v2.3
+#define HWCFG_FLDIDX_Touch2Type 49 // v2.3
+#define HWCFG_FLDIDX_GPS 50 // v2.4
+#define HWCFG_FLDIDX_FM 51 // v2.4
+
+
+
+
+NTX_HWCONFIG *NtxHwCfg_Load(const char *szFileName,int iIsSeek);
+NTX_HWCONFIG *NtxHwCfg_LoadEx(const char *szFileName,unsigned long dwIsSeek);
+int NtxHwCfg_Save(const char *szFileName,int iIsSeek);
+NTX_HWCONFIG *NtxHwCfg_Get(void);
+
+
+int NtxHwCfg_GetTotalFlds(void);//¨ú±o¦@¦³´X­ÓÄæ¦ì.
+int NtxHwCfg_GetFldVal(int iFldIdx,HwConfigField *O_ptHwCfgFld);//¨ú±o¤v©w¸qªºÄæ¦ì­È.
+unsigned char NtxHwCfg_FldStrVal2Val(int iFldIdx,char *szFldStrVal);//Äæ¦ìªº¦r¦ê­ÈÂà´«¬°Äæ¦ì.
+const char *NtxHwCfg_FldVal2StrVal(int iFldIdx,unsigned char bFldVal);//Äæ¦ìªº­ÈÂà´«¬°¦r¦ê­È.
+int NtxHwCfg_FldName2Idx(const char *szFldName);
+int NtxHwCfg_is_HW_Fld(int iFldIdx);
+int NtxHwCfg_is_SW_Fld(int iFldIdx);
+
+int NtxHwCfg_ChkCfgHeaderEx2(NTX_HWCONFIG *pHdr,int iIsIgnoreVersion,const char *pcCompareHdrVersionA);
+int NtxHwCfg_ChkCfgHeaderEx(NTX_HWCONFIG *pHdr,int iIsIgnoreVersion);
+int NtxHwCfg_ChkCfgHeader(NTX_HWCONFIG *pHdr);//Àˬd²ÕºAªíÀY,ª©¥».
+int NtxHwCfg_CfgUpgrade(NTX_HWCONFIG *pHdr);//®æ¦¡¤É¯Å¦Ü¤u¨ã¤@­Pªºª©¥».
+
+int NtxHwCfg_GetCfgTotalFlds(NTX_HWCONFIG *pHdr);//¨ú±o²ÕºAÁ`¦@¦³´X­ÓÄæ¦ì.
+
+int NtxHwCfg_GetCfgFldVal(NTX_HWCONFIG *pHdr,int iFieldIdx);
+const char *NtxHwCfg_GetCfgFldStrVal(NTX_HWCONFIG *pHdr,int iFieldIdx);
+int NtxHwCfg_GetCfgFldFlagVal(NTX_HWCONFIG *pHdr,int iFieldIdx,int iFlagsIdx);
+int NtxHwCfg_GetCfgFldFlagValByName(NTX_HWCONFIG *pHdr,int iFieldIdx,const char *pszFlagName);
+
+int NtxHwCfg_SetCfgFldVal(NTX_HWCONFIG *pHdr,int iFieldIdx,int iFieldVal);
+int NtxHwCfg_SetCfgFldStrVal(NTX_HWCONFIG *pHdr,int iFieldIdx,const char *pszFieldStrVal);
+int NtxHwCfg_SetCfgFldStrValEx(NTX_HWCONFIG *pHdr,int iFieldIdx,const char *pszFieldStrVal,int iHW_WR_Protect);
+int NtxHwCfg_SetCfgFldFlagValByName(NTX_HWCONFIG *pHdr,int iFieldIdx,const char *pszFlagName,int iIsTurnON,int iHW_WR_Protect);
+
+int NtxHwCfg_SetCfgFldValDefs(NTX_HWCONFIG *I_pHdr,int I_iFieldIdx,
+ const char **I_pszFieldValDefs,int I_iTotalVals);
+
+int NtxHwCfg_CompareHdrFldVersion(NTX_HWCONFIG *pHdr,int iFieldIdx);
+
+// get field value name in hardware config struct ...
+#define NTXHWCFG_GET_FLDCFGNAME(pHdr,_fld) gsz##_fld##A[pHdr->m_val.b##_fld]
+// get print format by field in hardware config struct ...
+#define NTXHWCFG_GET_FLDCFGPRTFMT(pHdr,_fld) "%s : %s",#_fld,NTXHWCFG_GET_FLDCFGNAME(pHdr,_fld)
+
+#define NTXHWCFG_TST_FLAG(_flags,_bit_n) ((_flags)&(0x01<<(_bit_n)))?1:0
+
+#ifdef __cplusplus //[
+}
+#endif //] __cplusplus
+
+#endif //] __ntx_hwconfig_h
+
diff --git a/arch/arm/mach-mx6/pcie.c b/arch/arm/mach-mx6/pcie.c
new file mode 100644
index 00000000..fa37e07c
--- /dev/null
+++ b/arch/arm/mach-mx6/pcie.c
@@ -0,0 +1,1161 @@
+/*
+ * arch/arm/mach-mx6/pcie.c
+ *
+ * PCIe host controller driver for IMX6 SOCs
+ *
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Bits taken from arch/arm/mach-dove/pcie.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/time.h>
+
+#include <mach/pcie.h>
+
+#include <asm/sizes.h>
+#include <asm/signal.h>
+
+#include "crm_regs.h"
+#ifdef CONFIG_PCI_MSI
+#include "msi.h"
+#endif
+
+/* Register Definitions */
+#define PRT_LOG_R_BaseAddress 0x700
+
+/* Register DB_R0 */
+/* Debug Register 0 */
+#define DB_R0 (PRT_LOG_R_BaseAddress + 0x28)
+#define DB_R0_RegisterSize 32
+#define DB_R0_RegisterResetValue 0x0
+#define DB_R0_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R0 */
+
+/* Register DB_R1 */
+/* Debug Register 1 */
+#define DB_R1 (PRT_LOG_R_BaseAddress + 0x2c)
+#define DB_R1_RegisterSize 32
+#define DB_R1_RegisterResetValue 0x0
+#define DB_R1_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R1 */
+
+#define ATU_R_BaseAddress 0x900
+#define ATU_VIEWPORT_R (ATU_R_BaseAddress + 0x0)
+#define ATU_REGION_CTRL1_R (ATU_R_BaseAddress + 0x4)
+#define ATU_REGION_CTRL2_R (ATU_R_BaseAddress + 0x8)
+#define ATU_REGION_LOWBASE_R (ATU_R_BaseAddress + 0xC)
+#define ATU_REGION_UPBASE_R (ATU_R_BaseAddress + 0x10)
+#define ATU_REGION_LIMIT_ADDR_R (ATU_R_BaseAddress + 0x14)
+#define ATU_REGION_LOW_TRGT_ADDR_R (ATU_R_BaseAddress + 0x18)
+#define ATU_REGION_UP_TRGT_ADDR_R (ATU_R_BaseAddress + 0x1C)
+
+/* Registers of PHY */
+/* Register PHY_STS_R */
+/* PHY Status Register */
+#define PHY_STS_R (PRT_LOG_R_BaseAddress + 0x110)
+
+/* Register PHY_CTRL_R */
+/* PHY Control Register */
+#define PHY_CTRL_R (PRT_LOG_R_BaseAddress + 0x114)
+
+#define SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO 0x0011
+/* FIELD: RES_ACK_IN_OVRD [15:15]
+// FIELD: RES_ACK_IN [14:14]
+// FIELD: RES_REQ_IN_OVRD [13:13]
+// FIELD: RES_REQ_IN [12:12]
+// FIELD: RTUNE_REQ_OVRD [11:11]
+// FIELD: RTUNE_REQ [10:10]
+// FIELD: MPLL_MULTIPLIER_OVRD [9:9]
+// FIELD: MPLL_MULTIPLIER [8:2]
+// FIELD: MPLL_EN_OVRD [1:1]
+// FIELD: MPLL_EN [0:0]
+*/
+
+#define SSP_CR_SUP_DIG_ATEOVRD 0x0010
+/* FIELD: ateovrd_en [2:2]
+// FIELD: ref_usb2_en [1:1]
+// FIELD: ref_clkdiv2 [0:0]
+*/
+
+#define SSP_CR_LANE0_DIG_RX_OVRD_IN_LO 0x1005
+/* FIELD: RX_LOS_EN_OVRD [13:13]
+// FIELD: RX_LOS_EN [12:12]
+// FIELD: RX_TERM_EN_OVRD [11:11]
+// FIELD: RX_TERM_EN [10:10]
+// FIELD: RX_BIT_SHIFT_OVRD [9:9]
+// FIELD: RX_BIT_SHIFT [8:8]
+// FIELD: RX_ALIGN_EN_OVRD [7:7]
+// FIELD: RX_ALIGN_EN [6:6]
+// FIELD: RX_DATA_EN_OVRD [5:5]
+// FIELD: RX_DATA_EN [4:4]
+// FIELD: RX_PLL_EN_OVRD [3:3]
+// FIELD: RX_PLL_EN [2:2]
+// FIELD: RX_INVERT_OVRD [1:1]
+// FIELD: RX_INVERT [0:0]
+*/
+
+#define SSP_CR_LANE0_DIG_RX_ASIC_OUT 0x100D
+/* FIELD: LOS [2:2]
+// FIELD: PLL_STATE [1:1]
+// FIELD: VALID [0:0]
+*/
+
+/* control bus bit definition */
+#define PCIE_CR_CTL_DATA_LOC 0
+#define PCIE_CR_CTL_CAP_ADR_LOC 16
+#define PCIE_CR_CTL_CAP_DAT_LOC 17
+#define PCIE_CR_CTL_WR_LOC 18
+#define PCIE_CR_CTL_RD_LOC 19
+#define PCIE_CR_STAT_DATA_LOC 0
+#define PCIE_CR_STAT_ACK_LOC 16
+
+#define PCIE_CAP_STRUC_BaseAddress 0x70
+
+/* Register LNK_CAP */
+/* PCIE Link cap */
+#define LNK_CAP (PCIE_CAP_STRUC_BaseAddress + 0xc)
+#define LNK_CAP_RegisterSize 32
+#define LNK_CAP_RegisterResetValue 0x011cc12
+#define LNK_CAP_RegisterResetMask 0xffffffff
+
+#ifdef CONFIG_PCI_MSI
+#define PCIE_RC_MSI_CAP 0x50
+
+#define PCIE_PL_MSICA 0x820
+#define PCIE_PL_MSICUA 0x824
+#define PCIE_PL_MSIC_INT 0x828
+
+#define MSIC_INT_EN 0x0
+#define MSIC_INT_MASK 0x4
+#define MSIC_INT_STATUS 0x8
+#endif
+
+/* End of Register Definitions */
+
+#define PCIE_DBI_BASE_ADDR (PCIE_ARB_END_ADDR - SZ_16K + 1)
+
+#define PCIE_CONF_BUS(b) (((b) & 0xFF) << 16)
+#define PCIE_CONF_DEV(d) (((d) & 0x1F) << 11)
+#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8)
+#define PCIE_CONF_REG(r) ((r) & ~0x3)
+
+/*
+ * The default values of the RC's reserved ddr memory
+ * used to verify EP mode.
+ * BTW, here is the layout of the 1G ddr on SD boards
+ * 0x1000_0000 ~ 0x4FFF_FFFF
+ */
+static u32 rc_ddr_test_region = 0x40000000;
+static u32 rc_ddr_test_region_size = (SZ_16M - SZ_16K);
+
+#ifdef EP_SELF_IO_TEST
+static void *rc_ddr_test_reg1, *rc_ddr_test_reg2;
+static void __iomem *pcie_arb_base_addr;
+static struct timeval tv1, tv2, tv3;
+static u32 tv_count1, tv_count2;
+#endif
+static void __iomem *base;
+static void __iomem *dbi_base;
+
+enum {
+ MemRdWr = 0,
+ MemRdLk = 1,
+ IORdWr = 2,
+ CfgRdWr0 = 4,
+ CfgRdWr1 = 5
+};
+
+struct imx_pcie_port {
+ u8 index;
+ u8 root_bus_nr;
+ void __iomem *base;
+ void __iomem *dbi_base;
+ spinlock_t conf_lock;
+
+ char io_space_name[16];
+ char mem_space_name[16];
+
+ struct resource res[2];
+};
+
+static struct imx_pcie_port imx_pcie_port[1];
+static int num_pcie_ports;
+
+static int pcie_phy_cr_read(int addr, int *data);
+static int pcie_phy_cr_write(int addr, int data);
+static void change_field(int *in, int start, int end, int val);
+
+/* IMX PCIE GPR configure routines */
+static inline void imx_pcie_clrset(u32 mask, u32 val, void __iomem *addr)
+{
+ writel(((readl(addr) & ~mask) | (val & mask)), addr);
+}
+
+static struct imx_pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = num_pcie_ports - 1; i >= 0; i--) {
+ int rbus = imx_pcie_port[i].root_bus_nr;
+ if (rbus != -1 && rbus == bus)
+ break;
+ }
+
+ return i >= 0 ? imx_pcie_port + i : NULL;
+}
+
+static int __init imx_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct imx_pcie_port *pp;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ pp = &imx_pcie_port[nr];
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * IORESOURCE_IO
+ */
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = PCIE_ARB_BASE_ADDR + SZ_16M - SZ_2M;
+ pp->res[0].end = pp->res[0].start + SZ_1M - 1;
+ }
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = PCIE_ARB_BASE_ADDR;
+ pp->res[1].end = pp->res[1].start + SZ_16M - SZ_2M - 1;
+ }
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+static int imx_pcie_link_up(void __iomem *dbi_base)
+{
+ /* Check the pcie link up or link down */
+ int iterations = 200;
+ u32 rc, ltssm, rx_valid, temp;
+
+ do {
+ /* link is debug bit 36 debug 1 start in bit 32 */
+ rc = readl(dbi_base + DB_R1) & (0x1 << (36 - 32)) ;
+ iterations--;
+ usleep_range(2000, 3000);
+
+ /* From L0, initiate MAC entry to gen2 if EP/RC supports gen2.
+ * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2).
+ * If (MAC/LTSSM.state == Recovery.RcvrLock)
+ * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition
+ * to gen2 is stuck
+ */
+ pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_ASIC_OUT, &rx_valid);
+ ltssm = readl(dbi_base + DB_R0) & 0x3F;
+ if ((ltssm == 0x0D) && ((rx_valid & 0x01) == 0)) {
+ pr_info("Transition to gen2 is stuck, reset PHY!\n");
+ pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO, &temp);
+ change_field(&temp, 3, 3, 0x1);
+ change_field(&temp, 5, 5, 0x1);
+ pcie_phy_cr_write(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO,
+ 0x0028);
+ usleep_range(2000, 3000);
+ pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO, &temp);
+ change_field(&temp, 3, 3, 0x0);
+ change_field(&temp, 5, 5, 0x0);
+ pcie_phy_cr_write(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO,
+ 0x0000);
+ }
+
+ if (iterations == 0)
+ pr_info("link up failed, DB_R0:0x%08x, DB_R1:0x%08x!\n"
+ , readl(dbi_base + DB_R0)
+ , readl(dbi_base + DB_R1));
+ } while (!rc && iterations);
+
+ if (!rc)
+ return 0;
+ return 1;
+}
+
+static void imx_pcie_regions_setup(struct device *dev, void __iomem *dbi_base)
+{
+ struct imx_pcie_platform_data *pdata = dev->platform_data;
+#ifdef CONFIG_PCI_MSI
+ unsigned int i;
+ void __iomem *p = dbi_base + PCIE_PL_MSIC_INT;
+#endif
+
+ /*
+ * i.MX6 defines 16MB in the AXI address map for PCIe.
+ *
+ * That address space excepted the pcie registers is
+ * split and defined into different regions by iATU,
+ * with sizes and offsets as follows:
+ *
+ * RC:
+ * 0x0100_0000 --- 0x01DF_FFFF 14MB IORESOURCE_MEM
+ * 0x01E0_0000 --- 0x01EF_FFFF 1MB IORESOURCE_IO
+ * 0x01F0_0000 --- 0x01FF_FFFF 1MB Cfg + MSI + Registers
+ *
+ * EP (default value):
+ * 0x0100_0000 --- 0x01FF_C000 16MB - 16KB IORESOURCE_MEM
+ */
+
+ /* CMD reg:I/O space, MEM space, and Bus Master Enable */
+ writel(readl(dbi_base + PCI_COMMAND)
+ | PCI_COMMAND_IO
+ | PCI_COMMAND_MEMORY
+ | PCI_COMMAND_MASTER,
+ dbi_base + PCI_COMMAND);
+
+ if (pdata->type_ep) {
+ /*
+ * configure the class_rev(emaluate one memory ram ep device),
+ * bar0 and bar1 of ep
+ */
+ writel(0xdeadbeaf, dbi_base + PCI_VENDOR_ID);
+ writel(readl(dbi_base + PCI_CLASS_REVISION)
+ | (PCI_CLASS_MEMORY_RAM << 16),
+ dbi_base + PCI_CLASS_REVISION);
+ writel(0xdeadbeaf, dbi_base + PCI_SUBSYSTEM_VENDOR_ID);
+
+ /* 32bit none-prefetchable 8M bytes memory on bar0 */
+ writel(0x0, dbi_base + PCI_BASE_ADDRESS_0);
+ writel(SZ_8M - 1, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_0);
+
+ /* None used bar1 */
+ writel(0x0, dbi_base + PCI_BASE_ADDRESS_1);
+ writel(0, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_1);
+
+ /* 4K bytes IO on bar2 */
+ writel(0x1, dbi_base + PCI_BASE_ADDRESS_2);
+ writel(SZ_4K - 1, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_2);
+
+ /*
+ * 32bit prefetchable 1M bytes memory on bar3
+ * FIXME BAR MASK3 is not changable, the size
+ * is fixed to 256 bytes.
+ */
+ writel(0x8, dbi_base + PCI_BASE_ADDRESS_3);
+ writel(SZ_1M - 1, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_3);
+
+ /*
+ * 64bit prefetchable 1M bytes memory on bar4-5.
+ * FIXME BAR4,5 are not enabled yet
+ */
+ writel(0xc, dbi_base + PCI_BASE_ADDRESS_4);
+ writel(SZ_1M - 1, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_4);
+ writel(0, dbi_base + (1 << 12) + PCI_BASE_ADDRESS_5);
+
+ /*
+ * region0 outbound used to access RC's reserved ddr memory
+ */
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(PCIE_ARB_BASE_ADDR, dbi_base + ATU_REGION_LOWBASE_R);
+ writel(0, dbi_base + ATU_REGION_UPBASE_R);
+ writel(PCIE_ARB_BASE_ADDR + rc_ddr_test_region_size,
+ dbi_base + ATU_REGION_LIMIT_ADDR_R);
+
+ writel(rc_ddr_test_region,
+ dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+ writel(MemRdWr, dbi_base + ATU_REGION_CTRL1_R);
+ writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+ } else {
+ /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
+ writel(readl(dbi_base + PCI_CLASS_REVISION)
+ | (PCI_CLASS_BRIDGE_PCI << 16),
+ dbi_base + PCI_CLASS_REVISION);
+
+ /*
+ * region0 outbound used to access target cfg
+ */
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(PCIE_ARB_END_ADDR - SZ_1M + 1,
+ dbi_base + ATU_REGION_LOWBASE_R);
+ writel(PCIE_ARB_END_ADDR - SZ_64K,
+ dbi_base + ATU_REGION_LIMIT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UPBASE_R);
+
+ writel(0, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+ writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
+ writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+ }
+
+#ifdef CONFIG_PCI_MSI
+ writel(MSI_MATCH_ADDR, dbi_base + PCIE_PL_MSICA);
+ writel(0, dbi_base + PCIE_PL_MSICUA);
+ for (i = 0; i < 8 ; i++) {
+ writel(0, p + MSIC_INT_EN);
+ writel(0xFFFFFFFF, p + MSIC_INT_MASK);
+ writel(0xFFFFFFFF, p + MSIC_INT_STATUS);
+ p += 12;
+ }
+#endif
+}
+
+#ifdef CONFIG_PCI_MSI
+void imx_pcie_mask_irq(unsigned int pos, int set)
+{
+ unsigned int mask = 1 << (pos & 0x1F);
+ unsigned int val, newval;
+ void __iomem *p;
+
+ p = dbi_base + PCIE_PL_MSIC_INT + MSIC_INT_MASK + ((pos >> 5) * 12);
+
+ if (pos >= (8 * 32))
+ return;
+ val = readl(p);
+ if (set)
+ newval = val | mask;
+ else
+ newval = val & ~mask;
+ if (val != newval)
+ writel(newval, p);
+}
+
+void imx_pcie_enable_irq(unsigned int pos, int set)
+{
+ unsigned int mask = 1 << (pos & 0x1F);
+ unsigned int val, newval;
+ void __iomem *p;
+
+ p = dbi_base + PCIE_PL_MSIC_INT + MSIC_INT_EN + ((pos >> 5) * 12);
+
+ /* RC: MSI CAP enable */
+ if (set) {
+ val = readl(dbi_base + PCIE_RC_MSI_CAP);
+ val |= (PCI_MSI_FLAGS_ENABLE << 16);
+ writel(val, dbi_base + PCIE_RC_MSI_CAP);
+ }
+
+ if (pos >= (8 * 32))
+ return;
+ val = readl(p);
+ if (set)
+ newval = val | mask;
+ else
+ newval = val & ~mask;
+ if (val != newval)
+ writel(newval, p);
+ if (set && (val != newval))
+ imx_pcie_mask_irq(pos, 0); /* unmask when enabled */
+ }
+
+unsigned int imx_pcie_msi_pending(unsigned int index)
+{
+ unsigned int val, mask;
+ void __iomem *p = dbi_base + PCIE_PL_MSIC_INT + (index * 12);
+
+ if (index >= 8)
+ return 0;
+ val = readl(p + MSIC_INT_STATUS);
+ mask = readl(p + MSIC_INT_MASK);
+ val &= ~mask;
+ writel(val, p + MSIC_INT_STATUS);
+ return val;
+}
+#endif
+
+static int imx_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct imx_pcie_port *pp = bus_to_port(bus->number);
+ u32 va_address;
+
+ /* Added to change transaction TYPE */
+ if (bus->number < 2) {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
+ } else {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(CfgRdWr1, dbi_base + ATU_REGION_CTRL1_R);
+ }
+
+ if (pp) {
+ if (devfn != 0) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ va_address = (u32)dbi_base + (where & ~0x3);
+ } else {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+
+ writel((((PCIE_CONF_BUS(bus->number)
+ + PCIE_CONF_DEV(PCI_SLOT(devfn))
+ + PCIE_CONF_FUNC(PCI_FUNC(devfn)))) << 8),
+ dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ va_address = (u32)base + PCIE_CONF_REG(where);
+ }
+
+ *val = readl(va_address);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xFF;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xFFFF;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int imx_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct imx_pcie_port *pp = bus_to_port(bus->number);
+ u32 va_address = 0, mask = 0, tmp = 0;
+ int ret = PCIBIOS_SUCCESSFUL;
+
+ /* Added to change transaction TYPE */
+ if (bus->number < 2) {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
+ } else {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(CfgRdWr1, dbi_base + ATU_REGION_CTRL1_R);
+ }
+
+ if (pp) {
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ va_address = (u32)dbi_base + (where & ~0x3);
+ } else {
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+
+ writel((((PCIE_CONF_BUS(bus->number)
+ + PCIE_CONF_DEV(PCI_SLOT(devfn))
+ + PCIE_CONF_FUNC(PCI_FUNC(devfn)))) << 8),
+ dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ va_address = (u32)base + PCIE_CONF_REG(where);
+ }
+
+ if (size == 4) {
+ writel(val, va_address);
+ goto exit;
+ }
+
+ if (size == 2)
+ mask = ~(0xFFFF << ((where & 0x3) * 8));
+ else if (size == 1)
+ mask = ~(0xFF << ((where & 0x3) * 8));
+ else
+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
+
+ tmp = readl(va_address) & mask;
+ tmp |= val << ((where & 0x3) * 8);
+ writel(tmp, va_address);
+exit:
+ return ret;
+}
+
+static struct pci_ops imx_pcie_ops = {
+ .read = imx_pcie_rd_conf,
+ .write = imx_pcie_wr_conf,
+};
+
+static struct pci_bus __init *
+imx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr < num_pcie_ports) {
+ bus = pci_scan_bus(sys->busnr, &imx_pcie_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+static int __init imx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ switch (pin) {
+ case 1: return MXC_INT_PCIE_3;
+ case 2: return MXC_INT_PCIE_2;
+ case 3: return MXC_INT_PCIE_1;
+ case 4: return MXC_INT_PCIE_0;
+ default: return -1;
+ }
+}
+
+static struct hw_pci imx_pci __initdata = {
+ .nr_controllers = 1,
+ .swizzle = pci_std_swizzle,
+ .setup = imx_pcie_setup,
+ .scan = imx_pcie_scan_bus,
+ .map_irq = imx_pcie_map_irq,
+};
+
+/* PHY CR bus acess routines */
+static int pcie_phy_cr_ack_polling(int max_iterations, int exp_val)
+{
+ u32 temp_rd_data, wait_counter = 0;
+
+ do {
+ temp_rd_data = readl(dbi_base + PHY_STS_R);
+ temp_rd_data = (temp_rd_data >> PCIE_CR_STAT_ACK_LOC) & 0x1;
+ wait_counter++;
+ } while ((wait_counter < max_iterations) && (temp_rd_data != exp_val));
+
+ if (temp_rd_data != exp_val)
+ return 0 ;
+ return 1 ;
+}
+
+static int pcie_phy_cr_cap_addr(int addr)
+{
+ u32 temp_wr_data;
+
+ /* write addr */
+ temp_wr_data = addr << PCIE_CR_CTL_DATA_LOC ;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* capture addr */
+ temp_wr_data |= (0x1 << PCIE_CR_CTL_CAP_ADR_LOC);
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack */
+ if (!pcie_phy_cr_ack_polling(100, 1))
+ return 0;
+
+ /* deassert cap addr */
+ temp_wr_data = addr << PCIE_CR_CTL_DATA_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack de-assetion */
+ if (!pcie_phy_cr_ack_polling(100, 0))
+ return 0 ;
+
+ return 1 ;
+}
+
+static int pcie_phy_cr_read(int addr , int *data)
+{
+ u32 temp_rd_data, temp_wr_data;
+
+ /* write addr */
+ /* cap addr */
+ if (!pcie_phy_cr_cap_addr(addr))
+ return 0;
+
+ /* assert rd signal */
+ temp_wr_data = 0x1 << PCIE_CR_CTL_RD_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack */
+ if (!pcie_phy_cr_ack_polling(100, 1))
+ return 0;
+
+ /* after got ack return data */
+ temp_rd_data = readl(dbi_base + PHY_STS_R);
+ *data = (temp_rd_data & (0xFFFF << PCIE_CR_STAT_DATA_LOC)) ;
+
+ /* deassert rd signal */
+ temp_wr_data = 0x0;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack de-assetion */
+ if (!pcie_phy_cr_ack_polling(100, 0))
+ return 0 ;
+
+ return 1 ;
+
+}
+
+static int pcie_phy_cr_write(int addr, int data)
+{
+ u32 temp_wr_data;
+
+ /* write addr */
+ /* cap addr */
+ if (!pcie_phy_cr_cap_addr(addr))
+ return 0 ;
+
+ temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* capture data */
+ temp_wr_data |= (0x1 << PCIE_CR_CTL_CAP_DAT_LOC);
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack */
+ if (!pcie_phy_cr_ack_polling(100, 1))
+ return 0 ;
+
+ /* deassert cap data */
+ temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack de-assetion */
+ if (!pcie_phy_cr_ack_polling(100, 0))
+ return 0;
+
+ /* assert wr signal */
+ temp_wr_data = 0x1 << PCIE_CR_CTL_WR_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack */
+ if (!pcie_phy_cr_ack_polling(100, 1))
+ return 0;
+
+ /* deassert wr signal */
+ temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ /* wait for ack de-assetion */
+ if (!pcie_phy_cr_ack_polling(100, 0))
+ return 0;
+
+ temp_wr_data = 0x0 ;
+ writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+ return 1 ;
+}
+
+static void change_field(int *in, int start, int end, int val)
+{
+ int mask;
+
+ mask = ((0xFFFFFFFF << start) ^ (0xFFFFFFFF << (end + 1))) & 0xFFFFFFFF;
+ *in = (*in & ~mask) | (val << start);
+}
+
+static void imx_pcie_enable_controller(struct device *dev)
+{
+ struct clk *pcie_clk;
+ struct imx_pcie_platform_data *pdata = dev->platform_data;
+
+ /* Enable PCIE power */
+ gpio_request(pdata->pcie_pwr_en, "PCIE POWER_EN");
+
+ /* activate PCIE_PWR_EN */
+ gpio_direction_output(pdata->pcie_pwr_en, 1);
+
+ imx_pcie_clrset(IOMUXC_GPR1_TEST_POWERDOWN, 0 << 18, IOMUXC_GPR1);
+
+
+ /* enable the clks */
+ if (pdata->type_ep) {
+ pcie_clk = clk_get(NULL, "pcie_ep_clk");
+ if (IS_ERR(pcie_clk))
+ pr_err("no pcie_ep clock.\n");
+
+ if (clk_enable(pcie_clk)) {
+ pr_err("can't enable pcie_ep clock.\n");
+ clk_put(pcie_clk);
+ }
+ } else {
+ pcie_clk = clk_get(NULL, "pcie_clk");
+ if (IS_ERR(pcie_clk))
+ pr_err("no pcie clock.\n");
+
+ if (clk_enable(pcie_clk)) {
+ pr_err("can't enable pcie clock.\n");
+ clk_put(pcie_clk);
+ }
+ }
+ imx_pcie_clrset(IOMUXC_GPR1_PCIE_REF_CLK_EN, 1 << 16, IOMUXC_GPR1);
+}
+
+static void card_reset(struct device *dev)
+{
+ struct imx_pcie_platform_data *pdata = dev->platform_data;
+
+ /* PCIE RESET */
+ gpio_request(pdata->pcie_rst, "PCIE RESET");
+
+ /* activate PERST_B */
+ gpio_direction_output(pdata->pcie_rst, 0);
+
+ /* Add one reset to the pcie external device */
+ msleep(100);
+
+ /* deactive PERST_B */
+ gpio_direction_output(pdata->pcie_rst, 1);
+}
+
+static void __init add_pcie_port(void __iomem *base, void __iomem *dbi_base,
+ struct imx_pcie_platform_data *pdata)
+{
+ struct clk *pcie_clk;
+
+ if (imx_pcie_link_up(dbi_base)) {
+ struct imx_pcie_port *pp = &imx_pcie_port[num_pcie_ports++];
+
+ pr_info("IMX PCIe port: link up.\n");
+
+ pp->index = 0;
+ pp->root_bus_nr = -1;
+ pp->base = base;
+ pp->dbi_base = dbi_base;
+ spin_lock_init(&pp->conf_lock);
+ memset(pp->res, 0, sizeof(pp->res));
+ } else {
+ pr_info("IMX PCIe port: link down!\n");
+
+ /* Release the clocks, and disable the power */
+ pcie_clk = clk_get(NULL, "pcie_clk");
+ if (IS_ERR(pcie_clk))
+ pr_err("no pcie clock.\n");
+
+ clk_disable(pcie_clk);
+ clk_put(pcie_clk);
+
+ imx_pcie_clrset(IOMUXC_GPR1_PCIE_REF_CLK_EN, 0 << 16,
+ IOMUXC_GPR1);
+
+ /* Disable PCIE power */
+ gpio_request(pdata->pcie_pwr_en, "PCIE POWER_EN");
+
+ /* activate PCIE_PWR_EN */
+ gpio_direction_output(pdata->pcie_pwr_en, 0);
+
+ imx_pcie_clrset(IOMUXC_GPR1_TEST_POWERDOWN, 1 << 18,
+ IOMUXC_GPR1);
+ }
+}
+
+/* Added for PCI abort handling */
+static int imx6q_pcie_abort_handler(unsigned long addr,
+ unsigned int fsr, struct pt_regs *regs)
+{
+ /*
+ * If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+ return 0;
+}
+
+#ifdef CONFIG_IMX_PCIE_EP_MODE_IN_EP_RC_SYS
+static ssize_t imx_pcie_rc_memw_info(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ return sprintf(buf, "imx-pcie-rc-memw-info start 0x%08x, size 0x%08x\n",
+ rc_ddr_test_region, rc_ddr_test_region_size);
+}
+
+static ssize_t
+imx_pcie_rc_memw_start(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 memw_start;
+
+ sscanf(buf, "%x\n", &memw_start);
+
+ if (memw_start < 0x10000000) {
+ dev_err(dev, "Invalid memory start address.\n");
+ dev_info(dev, "For example: echo 0x41000000 > /sys/...");
+ return -1;
+ }
+
+ if (rc_ddr_test_region != memw_start) {
+ rc_ddr_test_region = memw_start;
+ /* Re-setup the iATU */
+ imx_pcie_regions_setup(dev, dbi_base);
+ }
+
+ return count;
+}
+
+static ssize_t
+imx_pcie_rc_memw_size(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ u32 memw_size;
+
+ sscanf(buf, "%x\n", &memw_size);
+
+ if ((memw_size > (SZ_16M - SZ_16K)) || (memw_size < SZ_64K)) {
+ dev_err(dev, "Invalid, should be [SZ_64K,SZ_16M - SZ_16KB].\n");
+ dev_info(dev, "For example: echo 0x800000 > /sys/...");
+ return -1;
+ }
+
+ if (rc_ddr_test_region_size != memw_size) {
+ rc_ddr_test_region_size = memw_size;
+ /* Re-setup the iATU */
+ imx_pcie_regions_setup(dev, dbi_base);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(rc_memw_info, S_IRUGO, imx_pcie_rc_memw_info, NULL);
+static DEVICE_ATTR(rc_memw_start_set, S_IWUGO, NULL, imx_pcie_rc_memw_start);
+static DEVICE_ATTR(rc_memw_size_set, S_IWUGO, NULL, imx_pcie_rc_memw_size);
+
+static struct attribute *imx_pcie_attrs[] = {
+ /*
+ * The start address, and the limitation (64KB ~ (16MB - 16KB))
+ * of the ddr mem window reserved by RC, and used for EP to access.
+ * BTW, these attrs are only configured at EP side.
+ */
+ &dev_attr_rc_memw_info.attr,
+ &dev_attr_rc_memw_start_set.attr,
+ &dev_attr_rc_memw_size_set.attr,
+ NULL
+};
+
+static struct attribute_group imx_pcie_attrgroup = {
+ .attrs = imx_pcie_attrs,
+};
+#endif
+
+static int __devinit imx_pcie_pltfm_probe(struct platform_device *pdev)
+{
+#ifdef EP_SELF_IO_TEST
+ int i;
+#endif
+ int ret = 0;
+ struct resource *mem;
+ struct device *dev = &pdev->dev;
+ struct imx_pcie_platform_data *pdata = dev->platform_data;
+
+ pr_info("iMX6 PCIe %s mode %s entering.\n",
+ pdata->type_ep ? "PCIe EP" : "PCIe RC", __func__);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(dev, "no mmio space\n");
+ return -EINVAL;
+ }
+
+#ifdef CONFIG_IMX_PCIE_EP_MODE_IN_EP_RC_SYS
+ /* add attributes for device */
+ ret = sysfs_create_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
+ if (ret)
+ return -EINVAL;
+#endif
+
+ /* Added for PCI abort handling */
+ hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
+ "imprecise external abort");
+
+ base = ioremap_nocache(PCIE_ARB_END_ADDR - SZ_1M + 1, SZ_1M - SZ_16K);
+ if (!base) {
+ pr_err("error with ioremap in function %s\n", __func__);
+ ret = PTR_ERR(base);
+#ifdef CONFIG_IMX_PCIE_EP_MODE_IN_EP_RC_SYS
+ sysfs_remove_group(&pdev->dev.kobj, &imx_pcie_attrgroup);
+#endif
+ return ret;
+ }
+
+ dbi_base = devm_ioremap(dev, mem->start, resource_size(mem));
+ if (!dbi_base) {
+ dev_err(dev, "can't map %pR\n", mem);
+ ret = PTR_ERR(dbi_base);
+ goto err_base;
+ }
+
+ /* FIXME the field name should be aligned to RM */
+ imx_pcie_clrset(IOMUXC_GPR12_APP_LTSSM_ENABLE, 0 << 10, IOMUXC_GPR12);
+
+ /* configure constant input signal to the pcie ctrl and phy */
+ if (pdata->type_ep & 1)
+ /* EP */
+ imx_pcie_clrset(IOMUXC_GPR12_DEVICE_TYPE,
+ PCI_EXP_TYPE_ENDPOINT << 12, IOMUXC_GPR12);
+ else
+ /* RC */
+ imx_pcie_clrset(IOMUXC_GPR12_DEVICE_TYPE,
+ PCI_EXP_TYPE_ROOT_PORT << 12, IOMUXC_GPR12);
+ imx_pcie_clrset(IOMUXC_GPR12_LOS_LEVEL, 9 << 4, IOMUXC_GPR12);
+
+ imx_pcie_clrset(IOMUXC_GPR8_TX_DEEMPH_GEN1, 0 << 0, IOMUXC_GPR8);
+ imx_pcie_clrset(IOMUXC_GPR8_TX_DEEMPH_GEN2_3P5DB, 0 << 6, IOMUXC_GPR8);
+ imx_pcie_clrset(IOMUXC_GPR8_TX_DEEMPH_GEN2_6DB, 20 << 12, IOMUXC_GPR8);
+ imx_pcie_clrset(IOMUXC_GPR8_TX_SWING_FULL, 127 << 18, IOMUXC_GPR8);
+ imx_pcie_clrset(IOMUXC_GPR8_TX_SWING_LOW, 127 << 25, IOMUXC_GPR8);
+
+ /* Enable the pwr, clks and so on */
+ imx_pcie_enable_controller(dev);
+ if (!(pdata->type_ep)) {
+ /*Only RC: togle the external card's reset */
+ card_reset(dev) ;
+
+ imx_pcie_regions_setup(dev, dbi_base);
+ }
+
+ pr_info("PCIE: %s start link up.\n", __func__);
+ /* start link up */
+ imx_pcie_clrset(IOMUXC_GPR12_APP_LTSSM_ENABLE, 1 << 10, IOMUXC_GPR12);
+
+ if (pdata->type_ep) {
+#ifdef EP_SELF_IO_TEST
+ /* Prepare the test regions and data */
+ rc_ddr_test_reg1 = kzalloc(rc_ddr_test_region_size, GFP_KERNEL);
+ if (!rc_ddr_test_reg1)
+ pr_err("PCIe EP: can't alloc the test region1.\n");
+
+ rc_ddr_test_reg2 = kzalloc(rc_ddr_test_region_size, GFP_KERNEL);
+ if (!rc_ddr_test_reg2) {
+ kfree(rc_ddr_test_reg1);
+ pr_err("PCIe EP: can't alloc the test region2.\n");
+ }
+
+ pcie_arb_base_addr = ioremap_cached(PCIE_ARB_BASE_ADDR,
+ rc_ddr_test_region_size);
+
+ if (!pcie_arb_base_addr) {
+ pr_err("error with ioremap in function %s\n", __func__);
+ ret = PTR_ERR(pcie_arb_base_addr);
+ kfree(rc_ddr_test_reg2);
+ kfree(rc_ddr_test_reg1);
+ goto err_base;
+ }
+
+ for (i = 0; i < rc_ddr_test_region_size; i = i + 4) {
+ writel(0xE6600D00 + i, rc_ddr_test_reg1 + i);
+ writel(0xDEADBEAF, rc_ddr_test_reg2 + i);
+ }
+#endif
+
+ pr_info("PCIe EP: waiting for link up...\n");
+ /* link is debug bit 36 debug 1 start in bit 32 */
+ do {
+ usleep_range(10, 20);
+ } while ((readl(dbi_base + DB_R1) & 0x10) == 0);
+ /* Make sure that the PCIe link is up */
+ if (imx_pcie_link_up(dbi_base)) {
+ pr_info("PCIe EP: link up.\n");
+ } else {
+ pr_info("PCIe EP: ERROR link is down, exit!\n");
+#ifdef EP_SELF_IO_TEST
+ kfree(rc_ddr_test_reg2);
+ kfree(rc_ddr_test_reg1);
+ iounmap(pcie_arb_base_addr);
+#endif
+ goto err_link_down;
+ }
+
+ imx_pcie_regions_setup(dev, dbi_base);
+#ifdef EP_SELF_IO_TEST
+ /* PCIe EP start the data transfer after link up */
+ pr_info("PCIe EP: Starting data transfer...\n");
+ do_gettimeofday(&tv1);
+
+ memcpy((unsigned long *)pcie_arb_base_addr,
+ (unsigned long *)rc_ddr_test_reg1, 0xFFC000);
+
+ do_gettimeofday(&tv2);
+
+ memcpy((unsigned long *)rc_ddr_test_reg2,
+ (unsigned long *)pcie_arb_base_addr, 0xFFC000);
+
+ do_gettimeofday(&tv3);
+
+ if (memcmp(rc_ddr_test_reg2, rc_ddr_test_reg1, 0xFFC000) != 0) {
+ pr_info("PCIe EP: Data transfer is failed.\n");
+ } else {
+ tv_count1 = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC
+ + tv2.tv_usec - tv1.tv_usec;
+ tv_count2 = (tv3.tv_sec - tv2.tv_sec) * USEC_PER_SEC
+ + tv3.tv_usec - tv2.tv_usec;
+
+ pr_info("PCIe EP: Data transfer is successful."
+ "tv_count1 %dus, tv_count2 %dus.\n",
+ tv_count1, tv_count2);
+ pr_info("PCIe EP: Data write speed is %ldMB/s.\n",
+ ((((0xFFC000/1024) * MSEC_PER_SEC)))
+ /(tv_count1));
+ pr_info("PCIe EP: Data read speed is %ldMB/s.\n",
+ ((((0xFFC000/1024) * MSEC_PER_SEC)))
+ /(tv_count2));
+ }
+#endif
+
+ } else {
+ /* add the pcie port */
+ add_pcie_port(base, dbi_base, pdata);
+
+ pci_common_init(&imx_pci);
+ }
+ return 0;
+
+err_link_down:
+ iounmap(dbi_base);
+
+err_base:
+ iounmap(base);
+
+ return ret;
+}
+
+static struct platform_driver imx_pcie_pltfm_driver = {
+ .driver = {
+ .name = "imx-pcie",
+ .owner = THIS_MODULE,
+ },
+ .probe = imx_pcie_pltfm_probe,
+};
+
+/*****************************************************************************\
+ * *
+ * Driver init/exit *
+ * *
+\*****************************************************************************/
+
+static int __init imx_pcie_drv_init(void)
+{
+ return platform_driver_register(&imx_pcie_pltfm_driver);
+}
+
+static void __exit imx_pcie_drv_exit(void)
+{
+ platform_driver_unregister(&imx_pcie_pltfm_driver);
+}
+
+module_init(imx_pcie_drv_init);
+module_exit(imx_pcie_drv_exit);
+
+MODULE_DESCRIPTION("i.MX PCIE platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-mx6/plat_hotplug.c b/arch/arm/mach-mx6/plat_hotplug.c
new file mode 100644
index 00000000..20a33329
--- /dev/null
+++ b/arch/arm/mach-mx6/plat_hotplug.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <linux/io.h>
+#include "src-reg.h"
+#include <linux/sched.h>
+#include <asm/cacheflush.h>
+
+extern unsigned int num_cpu_idle_lock;
+void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ unsigned int val;
+
+ val = jiffies;
+ /* wait secondary cpu to die, timeout is 50ms */
+ while (__raw_readl(src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4) == 0) {
+ if (time_after(jiffies, (unsigned long)(val + HZ / 20))) {
+ printk(KERN_WARNING "cpu %d: cpu could not die\n", cpu);
+ break;
+ }
+ }
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ val = __raw_readl(src_base + SRC_SCR_OFFSET);
+ val &= ~(1 << (BP_SRC_SCR_CORES_DBG_RST + cpu));
+ val |= (1 << (BP_SRC_SCR_CORE0_RST + cpu));
+ __raw_writel(val, src_base + SRC_SCR_OFFSET);
+
+ val = jiffies;
+ /* wait secondary cpu reset done, timeout is 10ms */
+ while ((__raw_readl(src_base + SRC_SCR_OFFSET) &
+ (1 << (BP_SRC_SCR_CORE0_RST + cpu))) != 0) {
+ if (time_after(jiffies, (unsigned long)(val + HZ / 100))) {
+ printk(KERN_WARNING "cpu %d: cpu reset fail\n", cpu);
+ break;
+ }
+ }
+
+ __raw_writel(0x0, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ unsigned int v;
+ if (cpu == 0) {
+ printk(KERN_ERR "CPU0 can't be disabled!\n");
+ return;
+ }
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n" /* Invalidate I cache */
+ " mcr p15, 0, %1, c7, c10, 4\n" /* DSB */
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n" /* Disable SMP in ACTLR */
+ " bic %0, %0, %3\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n" /* Disable D cache in SCTLR */
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+ /* Tell cpu0 to kill this core, as this core's cache is
+ already disabled, and we want to set a flag to tell cpu0
+ to kill this core, so I write the flag to this core's SRC
+ parameter register, after cpu0 kill this core, it will
+ clear this register. */
+
+ __raw_writel(0x1, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
+
+ for (;;) {
+ /*
+ * Execute WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+ printk(KERN_ERR "cpu %d wake up from wfi !!!\n", cpu);
+ }
+ asm volatile(
+ " mrc p15, 0, %0, c1, c0, 0\n" /* Enable D cache in SCTLR */
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n" /* Enable SMP in ACTLR */
+ " orr %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+ __raw_writel(0x0, src_base + SRC_GPR1_OFFSET + (8 * cpu) + 4);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ *((char *)(&num_cpu_idle_lock) + (u8)cpu) = 0xff;
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-mx6/platsmp.c b/arch/arm/mach-mx6/platsmp.c
new file mode 100644
index 00000000..a21f0231
--- /dev/null
+++ b/arch/arm/mach-mx6/platsmp.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/mach-types.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/mx6.h>
+#include <mach/smp.h>
+#include "src-reg.h"
+
+static DEFINE_SPINLOCK(boot_lock);
+
+static void __iomem *scu_base_addr(void)
+{
+ return IO_ADDRESS(SCU_BASE_ADDR);
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ trace_hardirqs_off();
+
+ spin_lock(&boot_lock);
+ /*
+ * 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);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+
+ spin_unlock(&boot_lock);
+
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long boot_entry;
+ void __iomem *src_base = IO_ADDRESS(SRC_BASE_ADDR);
+ unsigned int val;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /* set entry point for cpu1-cpu3*/
+ boot_entry = virt_to_phys(mx6_secondary_startup);
+
+ writel(boot_entry, src_base + SRC_GPR1_OFFSET + 4 * 2 * cpu);
+ writel(0, src_base + SRC_GPR1_OFFSET + 4 * 2 * cpu + 4);
+
+ smp_wmb();
+ dsb();
+ flush_cache_all();
+
+ /* reset cpu<n> */
+ val = readl(src_base + SRC_SCR_OFFSET);
+ val |= 1 << (BP_SRC_SCR_CORE0_RST + cpu);
+ val |= 1 << (BP_SRC_SCR_CORES_DBG_RST + cpu);
+ writel(val, src_base + SRC_SCR_OFFSET);
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+
+}
+
+/*
+ * 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;
+
+ /* sanity check */
+ if (ncores == 0) {
+ pr_err("mx6: strange CM count of 0? Default to 1\n");
+ ncores = 1;
+ }
+ if (ncores > NR_CPUS) {
+ pr_warning("mx6: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+static void __init wakeup_secondary(void)
+{
+
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+ void __iomem *scu_base = scu_base_addr();
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ /*
+ * Initialise the SCU and wake up the secondary core using
+ * wakeup_secondary().
+ */
+ scu_enable(scu_base);
+ wakeup_secondary();
+}
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c
new file mode 100644
index 00000000..a6b4c748
--- /dev/null
+++ b/arch/arm/mach-mx6/pm.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/suspend.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/proc_fs.h>
+#include <linux/iram_alloc.h>
+#include <linux/fsl_devices.h>
+#include <asm/mach-types.h>
+#include <asm/cacheflush.h>
+#include <asm/tlb.h>
+#include <asm/delay.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/imx-pm.h>
+#include <mach/arc_otg.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#ifdef CONFIG_ARCH_MX6Q
+#include <mach/iomux-mx6q.h>
+#endif
+#include "crm_regs.h"
+#include "src-reg.h"
+#include "regs-anadig.h"
+
+#define SCU_CTRL_OFFSET 0x00
+#define GPC_IMR1_OFFSET 0x08
+#define GPC_IMR2_OFFSET 0x0c
+#define GPC_IMR3_OFFSET 0x10
+#define GPC_IMR4_OFFSET 0x14
+#define GPC_ISR1_OFFSET 0x18
+#define GPC_ISR2_OFFSET 0x1c
+#define GPC_ISR3_OFFSET 0x20
+#define GPC_ISR4_OFFSET 0x24
+#define GPC_CNTR_OFFSET 0x0
+#define GPC_PGC_DISP_PGCR_OFFSET 0x240
+#define GPC_PGC_DISP_PUPSCR_OFFSET 0x244
+#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248
+#define GPC_PGC_DISP_SR_OFFSET 0x24c
+#define GPC_PGC_GPU_PGCR_OFFSET 0x260
+#define GPC_PGC_CPU_PDN_OFFSET 0x2a0
+#define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4
+#define GPC_PGC_CPU_PDNSCR_OFFSET 0x2a8
+#define UART_UCR3_OFFSET 0x88
+#define UART_USR1_OFFSET 0x94
+#define UART_UCR3_AWAKEN (1 << 4)
+#define UART_USR1_AWAKE (1 << 4)
+#define LOCAL_TWD_LOAD_OFFSET 0x0
+#define LOCAL_TWD_COUNT_OFFSET 0x4
+#define LOCAL_TWD_CONTROL_OFFSET 0x8
+#define LOCAL_TWD_INT_OFFSET 0xc
+#define ANATOP_REG_1P1_OFFSET 0x110
+#define ANATOP_REG_2P5_OFFSET 0x130
+#define ANATOP_REG_CORE_OFFSET 0x140
+#define VDD3P0_VOLTAGE 3200000
+
+static struct clk *cpu_clk;
+static struct clk *axi_clk;
+static struct clk *periph_clk;
+static struct clk *pll3_usb_otg_main_clk;
+static struct regulator *vdd3p0_regulator;
+
+static struct pm_platform_data *pm_data;
+
+
+#if defined(CONFIG_CPU_FREQ)
+extern int set_cpu_freq(int wp);
+#endif
+extern void mx6_suspend(suspend_state_t state);
+extern void mx6_init_irq(void);
+extern unsigned int gpc_wake_irq[4];
+extern bool enable_wait_mode;
+extern unsigned long save_ttbr1(void);
+extern void restore_ttbr1(u32 ttbr1);
+extern int pu_disable(struct anatop_regulator *sreg);
+
+static struct device *pm_dev;
+struct clk *gpc_dvfs_clk;
+static void __iomem *scu_base;
+static void __iomem *gpc_base;
+static void __iomem *src_base;
+static void __iomem *local_twd_base;
+static void __iomem *gic_dist_base;
+static void __iomem *gic_cpu_base;
+static void __iomem *anatop_base;
+
+static void (*suspend_in_iram)(suspend_state_t state,
+ unsigned long iram_paddr, unsigned long suspend_iram_base, unsigned int cpu_type) = NULL;
+static unsigned long cpaddr;
+
+static u32 ccm_ccr, ccm_clpcr, scu_ctrl;
+static u32 gpc_imr[4], gpc_cpu_pup, gpc_cpu_pdn, gpc_cpu, gpc_ctr, gpc_disp;
+static u32 anatop[3], ccgr1, ccgr2, ccgr3, ccgr6;
+static u32 ccm_analog_pfd528;
+static u32 ccm_analog_pll3_480;
+static u32 ccm_anadig_ana_misc2;
+static bool usb_vbus_wakeup_enabled;
+
+void *suspend_iram_base;
+unsigned long suspend_iram_phys_addr;
+
+/*
+ * The USB VBUS wakeup should be disabled to avoid vbus wake system
+ * up due to vbus comparator is closed at weak 2p5 mode.
+ */
+static void usb_power_down_handler(void)
+{
+ u32 temp;
+ bool usb_oh3_clk_already_on;
+ if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0)
+ & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) != 0) {
+ usb_vbus_wakeup_enabled = false;
+ return;
+ }
+ /* enable usb oh3 clock if needed*/
+ temp = __raw_readl(MXC_CCM_CCGR6);
+ usb_oh3_clk_already_on = \
+ ((temp & (MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET)) \
+ == (MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET));
+ if (!usb_oh3_clk_already_on) {
+ temp |= MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET;
+ __raw_writel(temp, MXC_CCM_CCGR6);
+ }
+ /* disable vbus wakeup */
+ usb_vbus_wakeup_enabled = !!(USB_OTG_CTRL & UCTRL_WKUP_VBUS_EN);
+ if (usb_vbus_wakeup_enabled) {
+ USB_OTG_CTRL &= ~UCTRL_WKUP_VBUS_EN;
+ }
+ /* disable usb oh3 clock */
+ if (!usb_oh3_clk_already_on) {
+ temp = __raw_readl(MXC_CCM_CCGR6);
+ temp &= ~(MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET);
+ __raw_writel(temp, MXC_CCM_CCGR6);
+ }
+}
+
+static void usb_power_up_handler(void)
+{
+ /* enable vbus wakeup at runtime if needed */
+ if (usb_vbus_wakeup_enabled) {
+ u32 temp;
+ bool usb_oh3_clk_already_on;
+ /* enable usb oh3 clock if needed*/
+ temp = __raw_readl(MXC_CCM_CCGR6);
+ usb_oh3_clk_already_on = \
+ ((temp & (MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET)) \
+ == (MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET));
+ if (!usb_oh3_clk_already_on) {
+ temp |= MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET;
+ __raw_writel(temp, MXC_CCM_CCGR6);
+ }
+
+ /* restore usb wakeup enable setting */
+ USB_OTG_CTRL |= UCTRL_WKUP_VBUS_EN;
+
+ /* disable usb oh3 clock */
+ if (!usb_oh3_clk_already_on) {
+ temp = __raw_readl(MXC_CCM_CCGR6);
+ temp &= ~(MXC_CCM_CCGRx_CG_MASK << MXC_CCM_CCGRx_CG0_OFFSET);
+ __raw_writel(temp, MXC_CCM_CCGR6);
+ }
+ }
+}
+
+
+static void disp_power_down(void)
+{
+ if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) {
+
+ __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET);
+ __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET);
+
+ __raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ __raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET);
+
+ /* Disable EPDC/LCDIF pix clock, and EPDC/LCDIF/PXP axi clock */
+ __raw_writel(ccgr3 &
+ ~MXC_CCM_CCGRx_CG5_MASK &
+ ~MXC_CCM_CCGRx_CG4_MASK &
+ ~MXC_CCM_CCGRx_CG3_MASK &
+ ~MXC_CCM_CCGRx_CG2_MASK &
+ ~MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3);
+
+ }
+}
+
+static void disp_power_up(void)
+{
+ if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) {
+ /*
+ * Need to enable EPDC/LCDIF pix clock, and
+ * EPDC/LCDIF/PXP axi clock before power up.
+ */
+ __raw_writel(ccgr3 |
+ MXC_CCM_CCGRx_CG5_MASK |
+ MXC_CCM_CCGRx_CG4_MASK |
+ MXC_CCM_CCGRx_CG3_MASK |
+ MXC_CCM_CCGRx_CG2_MASK |
+ MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3);
+
+ __raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET);
+ __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET);
+ }
+}
+
+static void mx6_suspend_store(void)
+{
+ /* save some settings before suspend */
+ ccm_ccr = __raw_readl(MXC_CCM_CCR);
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR);
+ ccm_analog_pfd528 = __raw_readl(PFD_528_BASE_ADDR);
+ ccm_analog_pll3_480 = __raw_readl(PLL3_480_USB1_BASE_ADDR);
+ ccm_anadig_ana_misc2 = __raw_readl(MXC_PLL_BASE + HW_ANADIG_ANA_MISC2);
+ ccgr1 = __raw_readl(MXC_CCM_CCGR1);
+ ccgr2 = __raw_readl(MXC_CCM_CCGR2);
+ ccgr3 = __raw_readl(MXC_CCM_CCGR3);
+ ccgr6 = __raw_readl(MXC_CCM_CCGR6);
+ scu_ctrl = __raw_readl(scu_base + SCU_CTRL_OFFSET);
+ gpc_imr[0] = __raw_readl(gpc_base + GPC_IMR1_OFFSET);
+ gpc_imr[1] = __raw_readl(gpc_base + GPC_IMR2_OFFSET);
+ gpc_imr[2] = __raw_readl(gpc_base + GPC_IMR3_OFFSET);
+ gpc_imr[3] = __raw_readl(gpc_base + GPC_IMR4_OFFSET);
+ gpc_cpu_pup = __raw_readl(gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
+ gpc_cpu_pdn = __raw_readl(gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
+ gpc_cpu = __raw_readl(gpc_base + GPC_PGC_CPU_PDN_OFFSET);
+ gpc_ctr = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
+ if (cpu_is_mx6sl())
+ gpc_disp = __raw_readl(gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ anatop[0] = __raw_readl(anatop_base + ANATOP_REG_2P5_OFFSET);
+ anatop[1] = __raw_readl(anatop_base + ANATOP_REG_CORE_OFFSET);
+ anatop[2] = __raw_readl(anatop_base + ANATOP_REG_1P1_OFFSET);
+}
+
+static void mx6_suspend_restore(void)
+{
+ /* restore settings after suspend */
+ __raw_writel(anatop[0], anatop_base + ANATOP_REG_2P5_OFFSET);
+ __raw_writel(anatop[1], anatop_base + ANATOP_REG_CORE_OFFSET);
+ __raw_writel(anatop[2], anatop_base + ANATOP_REG_1P1_OFFSET);
+ /* Per spec, the count needs to be zeroed and reconfigured on exit from
+ * low power mode
+ */
+ __raw_writel(ccm_ccr & ~MXC_CCM_CCR_REG_BYPASS_CNT_MASK &
+ ~MXC_CCM_CCR_WB_COUNT_MASK, MXC_CCM_CCR);
+ udelay(50);
+ __raw_writel(ccm_ccr, MXC_CCM_CCR);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(scu_ctrl, scu_base + SCU_CTRL_OFFSET);
+ __raw_writel(gpc_imr[0], gpc_base + GPC_IMR1_OFFSET);
+ __raw_writel(gpc_imr[1], gpc_base + GPC_IMR2_OFFSET);
+ __raw_writel(gpc_imr[2], gpc_base + GPC_IMR3_OFFSET);
+ __raw_writel(gpc_imr[3], gpc_base + GPC_IMR4_OFFSET);
+ __raw_writel(gpc_cpu_pup, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
+ __raw_writel(gpc_cpu_pdn, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
+ __raw_writel(gpc_cpu, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
+ if (cpu_is_mx6sl())
+ __raw_writel(gpc_disp, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
+ __raw_writel(ccgr1, MXC_CCM_CCGR1);
+ __raw_writel(ccgr2, MXC_CCM_CCGR2);
+ __raw_writel(ccgr3, MXC_CCM_CCGR3);
+ __raw_writel(ccgr6, MXC_CCM_CCGR6);
+ __raw_writel(ccm_analog_pfd528, PFD_528_BASE_ADDR);
+ __raw_writel(ccm_analog_pll3_480, PLL3_480_USB1_BASE_ADDR);
+ __raw_writel(ccm_anadig_ana_misc2, MXC_PLL_BASE + HW_ANADIG_ANA_MISC2);
+}
+
+static int mx6_suspend_enter(suspend_state_t state)
+{
+ unsigned int wake_irq_isr[4];
+ unsigned int cpu_type;
+ struct gic_dist_state gds;
+ struct gic_cpu_state gcs;
+ bool arm_pg = false;
+
+ if (cpu_is_mx6q())
+ cpu_type = MXC_CPU_MX6Q;
+ else if (cpu_is_mx6dl())
+ cpu_type = MXC_CPU_MX6DL;
+ else
+ cpu_type = MXC_CPU_MX6SL;
+
+ wake_irq_isr[0] = __raw_readl(gpc_base +
+ GPC_ISR1_OFFSET) & gpc_wake_irq[0];
+ wake_irq_isr[1] = __raw_readl(gpc_base +
+ GPC_ISR2_OFFSET) & gpc_wake_irq[1];
+ wake_irq_isr[2] = __raw_readl(gpc_base +
+ GPC_ISR3_OFFSET) & gpc_wake_irq[2];
+ wake_irq_isr[3] = __raw_readl(gpc_base +
+ GPC_ISR4_OFFSET) & gpc_wake_irq[3];
+ if (wake_irq_isr[0] | wake_irq_isr[1] |
+ wake_irq_isr[2] | wake_irq_isr[3]) {
+ printk(KERN_INFO "There are wakeup irq pending,system resume!\n");
+ printk(KERN_INFO "wake_irq_isr[0-3]: 0x%x, 0x%x, 0x%x, 0x%x\n",
+ wake_irq_isr[0], wake_irq_isr[1],
+ wake_irq_isr[2], wake_irq_isr[3]);
+ return 0;
+ }
+ mx6_suspend_store();
+
+ /*
+ * i.MX6dl TO1.0/i.MX6dq TO1.1/1.0 TKT094231: can't support
+ * ARM_POWER_OFF mode.
+ */
+ if (state == PM_SUSPEND_MEM &&
+ ((mx6dl_revision() == IMX_CHIP_REVISION_1_0) ||
+ (cpu_is_mx6q() && mx6q_revision() <= IMX_CHIP_REVISION_1_1))) {
+ state = PM_SUSPEND_STANDBY;
+ }
+
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ disp_power_down();
+ usb_power_down_handler();
+#ifndef CONFIG_MXC_GPU_VIV
+ pu_disable(NULL);
+#endif
+ mxc_cpu_lp_set(ARM_POWER_OFF);
+ arm_pg = true;
+ break;
+ case PM_SUSPEND_STANDBY:
+ if (cpu_is_mx6sl()) {
+ disp_power_down();
+ usb_power_down_handler();
+#ifndef CONFIG_MXC_GPU_VIV
+ pu_disable(NULL);
+#endif
+ mxc_cpu_lp_set(STOP_XTAL_ON);
+ arm_pg = true;
+ } else
+ mxc_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * L2 can exit by 'reset' or Inband beacon (from remote EP)
+ * toggling phy_powerdown has same effect as 'inband beacon'
+ * So, toggle bit18 of GPR1, to fix errata
+ * "PCIe PCIe does not support L2 Power Down"
+ */
+ __raw_writel(__raw_readl(IOMUXC_GPR1) | (1 << 18), IOMUXC_GPR1);
+
+ if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) {
+ u32 ttbr1;
+
+ flush_cache_all();
+
+ if (arm_pg) {
+ /* preserve gic state */
+ save_gic_dist_state(0, &gds);
+ save_gic_cpu_state(0, &gcs);
+ }
+
+ if (pm_data && pm_data->suspend_enter)
+ pm_data->suspend_enter();
+
+ ttbr1 = save_ttbr1();
+ suspend_in_iram(state, (unsigned long)suspend_iram_phys_addr,
+ (unsigned long)suspend_iram_base, cpu_type);
+ restore_ttbr1(ttbr1);
+
+ if (pm_data && pm_data->suspend_exit)
+ pm_data->suspend_exit();
+
+ /* Reset the RBC counter. */
+ /* All interrupts should be masked before the
+ * RBC counter is reset.
+ */
+ /* Mask all interrupts. These will be unmasked by
+ * the mx6_suspend_restore routine below.
+ */
+ __raw_writel(0xffffffff, gpc_base + 0x08);
+ __raw_writel(0xffffffff, gpc_base + 0x0c);
+ __raw_writel(0xffffffff, gpc_base + 0x10);
+ __raw_writel(0xffffffff, gpc_base + 0x14);
+
+ /* Clear the RBC counter and RBC_EN bit. */
+ /* Disable the REG_BYPASS_COUNTER. */
+ __raw_writel(__raw_readl(MXC_CCM_CCR) &
+ ~MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR);
+ /* Make sure we clear REG_BYPASS_COUNT*/
+ __raw_writel(__raw_readl(MXC_CCM_CCR) &
+ (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR);
+ /* Need to wait for a minimum of 2 CLKILS (32KHz) for the
+ * counter to clear and reset.
+ */
+ udelay(80);
+
+ if (arm_pg) {
+ /* restore gic registers */
+ restore_gic_dist_state(0, &gds);
+ restore_gic_cpu_state(0, &gcs);
+ }
+ if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) {
+ usb_power_up_handler();
+ disp_power_up();
+ }
+
+ mx6_suspend_restore();
+
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base + HW_ANADIG_ANA_MISC0_CLR);
+
+ } else {
+ cpu_do_idle();
+ }
+
+ /*
+ * L2 can exit by 'reset' or Inband beacon (from remote EP)
+ * toggling phy_powerdown has same effect as 'inband beacon'
+ * So, toggle bit18 of GPR1, to fix errata
+ * "PCIe PCIe does not support L2 Power Down"
+ */
+ __raw_writel(__raw_readl(IOMUXC_GPR1) & (~(1 << 18)), IOMUXC_GPR1);
+
+ return 0;
+}
+
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx6_suspend_prepare(void)
+{
+ int ret;
+ ret = regulator_disable(vdd3p0_regulator);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to disable 3p0 regulator Err: %d\n",
+ __func__, ret);
+ }
+ return 0;
+}
+
+/*
+ * Called before devices are re-setup.
+ */
+static void mx6_suspend_finish(void)
+{
+ int ret;
+ ret = regulator_enable(vdd3p0_regulator);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to enable 3p0 regulator Err: %d\n",
+ __func__, ret);
+ }
+}
+
+static int mx6_suspend_begin(suspend_state_t state)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+
+static int mx6_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx6_suspend_ops = {
+ .valid = mx6_pm_valid,
+ .begin = mx6_suspend_begin,
+ .prepare = mx6_suspend_prepare,
+ .enter = mx6_suspend_enter,
+ .finish = mx6_suspend_finish,
+};
+
+static int __devinit mx6_pm_probe(struct platform_device *pdev)
+{
+ pm_dev = &pdev->dev;
+ pm_data = pdev->dev.platform_data;
+
+ return 0;
+}
+
+static struct platform_driver mx6_pm_driver = {
+ .driver = {
+ .name = "imx_pm",
+ },
+ .probe = mx6_pm_probe,
+};
+
+static int __init pm_init(void)
+{
+ int ret = 0;
+ scu_base = IO_ADDRESS(SCU_BASE_ADDR);
+ gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
+ src_base = IO_ADDRESS(SRC_BASE_ADDR);
+ gic_dist_base = IO_ADDRESS(IC_DISTRIBUTOR_BASE_ADDR);
+ gic_cpu_base = IO_ADDRESS(IC_INTERFACES_BASE_ADDR);
+ local_twd_base = IO_ADDRESS(LOCAL_TWD_ADDR);
+ anatop_base = IO_ADDRESS(ANATOP_BASE_ADDR);
+
+ pr_info("Static Power Management for Freescale i.MX6\n");
+
+ pr_info("wait mode is %s for i.MX6\n", enable_wait_mode ?
+ "enabled" : "disabled");
+
+ if (platform_driver_register(&mx6_pm_driver) != 0) {
+ printk(KERN_ERR "mx6_pm_driver register failed\n");
+ return -ENODEV;
+ }
+
+ suspend_set_ops(&mx6_suspend_ops);
+ /* Use preallocated IRAM memory. */
+ suspend_iram_phys_addr = MX6_SUSPEND_IRAM_CODE;
+
+ /* Dont ioremap the address, we have fixed the IRAM address at IRAM_BASE_ADDR_VIRT */
+ suspend_iram_base = IRAM_BASE_ADDR_VIRT + (suspend_iram_phys_addr - IRAM_BASE_ADDR);
+
+ pr_info("cpaddr = %x suspend_iram_base=%x\n",
+ (unsigned int)cpaddr, (unsigned int)suspend_iram_base);
+
+ /*
+ * Need to run the suspend code from IRAM as the DDR needs
+ * to be put into low power mode manually.
+ */
+ memcpy((void *)suspend_iram_base, mx6_suspend, MX6_SUSPEND_CODE_SIZE);
+
+ suspend_in_iram = (void *)suspend_iram_base;
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+ axi_clk = clk_get(NULL, "axi_clk");
+ if (IS_ERR(axi_clk)) {
+ printk(KERN_DEBUG "%s: failed to get axi_clk\n", __func__);
+ return PTR_ERR(axi_clk);
+ }
+ periph_clk = clk_get(NULL, "periph_clk");
+ if (IS_ERR(periph_clk)) {
+ printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__);
+ return PTR_ERR(periph_clk);
+ }
+ pll3_usb_otg_main_clk = clk_get(NULL, "pll3_main_clk");
+ if (IS_ERR(pll3_usb_otg_main_clk)) {
+ printk(KERN_DEBUG "%s: failed to get pll3_main_clk\n", __func__);
+ return PTR_ERR(pll3_usb_otg_main_clk);
+ }
+
+ vdd3p0_regulator = regulator_get(NULL, "cpu_vdd3p0");
+ if (IS_ERR(vdd3p0_regulator)) {
+ printk(KERN_ERR "%s: failed to get 3p0 regulator Err: %d\n",
+ __func__, ret);
+ return PTR_ERR(vdd3p0_regulator);
+ }
+ ret = regulator_set_voltage(vdd3p0_regulator, VDD3P0_VOLTAGE,
+ VDD3P0_VOLTAGE);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to set 3p0 regulator voltage Err: %d\n",
+ __func__, ret);
+ }
+ ret = regulator_enable(vdd3p0_regulator);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to enable 3p0 regulator Err: %d\n",
+ __func__, ret);
+ }
+
+ printk(KERN_INFO "PM driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit pm_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&mx6_pm_driver);
+ regulator_put(vdd3p0_regulator);
+}
+
+module_init(pm_init);
+module_exit(pm_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("PM driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-mx6/regs-anadig.h b/arch/arm/mach-mx6/regs-anadig.h
new file mode 100644
index 00000000..b1d16456
--- /dev/null
+++ b/arch/arm/mach-mx6/regs-anadig.h
@@ -0,0 +1,1011 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * Freescale ANADIG Register Definitions
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.30
+ * Template revision: 1.3
+ */
+
+#ifndef __ARCH_ARM___ANADIG_H
+#define __ARCH_ARM___ANADIG_H
+
+
+#define HW_ANADIG_PLL_SYS (0x00000000)
+#define HW_ANADIG_PLL_SYS_SET (0x00000004)
+#define HW_ANADIG_PLL_SYS_CLR (0x00000008)
+#define HW_ANADIG_PLL_SYS_TOG (0x0000000c)
+
+#define BM_ANADIG_PLL_SYS_LOCK 0x80000000
+#define BP_ANADIG_PLL_SYS_RSVD0 20
+#define BM_ANADIG_PLL_SYS_RSVD0 0x7FF00000
+#define BF_ANADIG_PLL_SYS_RSVD0(v) \
+ (((v) << 20) & BM_ANADIG_PLL_SYS_RSVD0)
+#define BM_ANADIG_PLL_SYS_PLL_SEL 0x00080000
+#define BM_ANADIG_PLL_SYS_LVDS_24MHZ_SEL 0x00040000
+#define BM_ANADIG_PLL_SYS_LVDS_SEL 0x00020000
+#define BM_ANADIG_PLL_SYS_BYPASS 0x00010000
+#define BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC 14
+#define BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_PLL_SYS_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_SYS_ENABLE 0x00002000
+#define BM_ANADIG_PLL_SYS_POWERDOWN 0x00001000
+#define BM_ANADIG_PLL_SYS_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_SYS_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_SYS_HALF_CP 0x00000200
+#define BM_ANADIG_PLL_SYS_DOUBLE_LF 0x00000100
+#define BM_ANADIG_PLL_SYS_HALF_LF 0x00000080
+#define BP_ANADIG_PLL_SYS_DIV_SELECT 0
+#define BM_ANADIG_PLL_SYS_DIV_SELECT 0x0000007F
+#define BF_ANADIG_PLL_SYS_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_PLL_SYS_DIV_SELECT)
+
+#define HW_ANADIG_USB1_PLL_480_CTRL (0x00000010)
+#define HW_ANADIG_USB1_PLL_480_CTRL_SET (0x00000014)
+#define HW_ANADIG_USB1_PLL_480_CTRL_CLR (0x00000018)
+#define HW_ANADIG_USB1_PLL_480_CTRL_TOG (0x0000001c)
+
+#define BM_ANADIG_USB1_PLL_480_CTRL_LOCK 0x80000000
+#define BP_ANADIG_USB1_PLL_480_CTRL_RSVD1 17
+#define BM_ANADIG_USB1_PLL_480_CTRL_RSVD1 0x7FFE0000
+#define BF_ANADIG_USB1_PLL_480_CTRL_RSVD1(v) \
+ (((v) << 17) & BM_ANADIG_USB1_PLL_480_CTRL_RSVD1)
+#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS 0x00010000
+#define BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC 14
+#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC)
+#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_USB1_PLL_480_CTRL_ENABLE 0x00002000
+#define BM_ANADIG_USB1_PLL_480_CTRL_POWER 0x00001000
+#define BM_ANADIG_USB1_PLL_480_CTRL_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_CP 0x00000400
+#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_CP 0x00000200
+#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_LF 0x00000100
+#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_LF 0x00000080
+#define BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS 0x00000040
+#define BM_ANADIG_USB1_PLL_480_CTRL_RSVD0 0x00000020
+#define BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0 2
+#define BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0 0x0000001C
+#define BF_ANADIG_USB1_PLL_480_CTRL_CONTROL0(v) \
+ (((v) << 2) & BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0)
+#define BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT 0
+#define BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT 0x00000003
+#define BF_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT)
+
+#define HW_ANADIG_USB2_PLL_480_CTRL (0x00000020)
+#define HW_ANADIG_USB2_PLL_480_CTRL_SET (0x00000024)
+#define HW_ANADIG_USB2_PLL_480_CTRL_CLR (0x00000028)
+#define HW_ANADIG_USB2_PLL_480_CTRL_TOG (0x0000002c)
+
+#define BM_ANADIG_USB2_PLL_480_CTRL_LOCK 0x80000000
+#define BP_ANADIG_USB2_PLL_480_CTRL_RSVD1 17
+#define BM_ANADIG_USB2_PLL_480_CTRL_RSVD1 0x7FFE0000
+#define BF_ANADIG_USB2_PLL_480_CTRL_RSVD1(v) \
+ (((v) << 17) & BM_ANADIG_USB2_PLL_480_CTRL_RSVD1)
+#define BM_ANADIG_USB2_PLL_480_CTRL_BYPASS 0x00010000
+#define BP_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC 14
+#define BM_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC)
+#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_USB2_PLL_480_CTRL_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_USB2_PLL_480_CTRL_ENABLE 0x00002000
+#define BM_ANADIG_USB2_PLL_480_CTRL_POWER 0x00001000
+#define BM_ANADIG_USB2_PLL_480_CTRL_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_USB2_PLL_480_CTRL_DOUBLE_CP 0x00000400
+#define BM_ANADIG_USB2_PLL_480_CTRL_HALF_CP 0x00000200
+#define BM_ANADIG_USB2_PLL_480_CTRL_DOUBLE_LF 0x00000100
+#define BM_ANADIG_USB2_PLL_480_CTRL_HALF_LF 0x00000080
+#define BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040
+#define BM_ANADIG_USB2_PLL_480_CTRL_RSVD0 0x00000020
+#define BP_ANADIG_USB2_PLL_480_CTRL_CONTROL0 2
+#define BM_ANADIG_USB2_PLL_480_CTRL_CONTROL0 0x0000001C
+#define BF_ANADIG_USB2_PLL_480_CTRL_CONTROL0(v) \
+ (((v) << 2) & BM_ANADIG_USB2_PLL_480_CTRL_CONTROL0)
+#define BP_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT 0
+#define BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT 0x00000003
+#define BF_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT)
+
+#define HW_ANADIG_PLL_528 (0x00000030)
+#define HW_ANADIG_PLL_528_SET (0x00000034)
+#define HW_ANADIG_PLL_528_CLR (0x00000038)
+#define HW_ANADIG_PLL_528_TOG (0x0000003c)
+
+#define BM_ANADIG_PLL_528_LOCK 0x80000000
+#define BP_ANADIG_PLL_528_RSVD1 19
+#define BM_ANADIG_PLL_528_RSVD1 0x7FF80000
+#define BF_ANADIG_PLL_528_RSVD1(v) \
+ (((v) << 19) & BM_ANADIG_PLL_528_RSVD1)
+#define BM_ANADIG_PLL_528_PFD_OFFSET_EN 0x00040000
+#define BM_ANADIG_PLL_528_DITHER_ENABLE 0x00020000
+#define BM_ANADIG_PLL_528_BYPASS 0x00010000
+#define BP_ANADIG_PLL_528_BYPASS_CLK_SRC 14
+#define BM_ANADIG_PLL_528_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_PLL_528_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_PLL_528_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_528_ENABLE 0x00002000
+#define BM_ANADIG_PLL_528_POWERDOWN 0x00001000
+#define BM_ANADIG_PLL_528_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_528_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_528_HALF_CP 0x00000200
+#define BM_ANADIG_PLL_528_DOUBLE_LF 0x00000100
+#define BM_ANADIG_PLL_528_HALF_LF 0x00000080
+#define BP_ANADIG_PLL_528_RSVD0 1
+#define BM_ANADIG_PLL_528_RSVD0 0x0000007E
+#define BF_ANADIG_PLL_528_RSVD0(v) \
+ (((v) << 1) & BM_ANADIG_PLL_528_RSVD0)
+#define BM_ANADIG_PLL_528_DIV_SELECT 0x00000001
+
+#define HW_ANADIG_PLL_528_SS (0x00000040)
+
+#define BP_ANADIG_PLL_528_SS_STOP 16
+#define BM_ANADIG_PLL_528_SS_STOP 0xFFFF0000
+#define BF_ANADIG_PLL_528_SS_STOP(v) \
+ (((v) << 16) & BM_ANADIG_PLL_528_SS_STOP)
+#define BM_ANADIG_PLL_528_SS_ENABLE 0x00008000
+#define BP_ANADIG_PLL_528_SS_STEP 0
+#define BM_ANADIG_PLL_528_SS_STEP 0x00007FFF
+#define BF_ANADIG_PLL_528_SS_STEP(v) \
+ (((v) << 0) & BM_ANADIG_PLL_528_SS_STEP)
+
+#define HW_ANADIG_PLL_528_NUM (0x00000050)
+
+#define BP_ANADIG_PLL_528_NUM_RSVD0 30
+#define BM_ANADIG_PLL_528_NUM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_528_NUM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_528_NUM_RSVD0)
+#define BP_ANADIG_PLL_528_NUM_A 0
+#define BM_ANADIG_PLL_528_NUM_A 0x3FFFFFFF
+#define BF_ANADIG_PLL_528_NUM_A(v) \
+ (((v) << 0) & BM_ANADIG_PLL_528_NUM_A)
+
+#define HW_ANADIG_PLL_528_DENOM (0x00000060)
+
+#define BP_ANADIG_PLL_528_DENOM_RSVD0 30
+#define BM_ANADIG_PLL_528_DENOM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_528_DENOM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_528_DENOM_RSVD0)
+#define BP_ANADIG_PLL_528_DENOM_B 0
+#define BM_ANADIG_PLL_528_DENOM_B 0x3FFFFFFF
+#define BF_ANADIG_PLL_528_DENOM_B(v) \
+ (((v) << 0) & BM_ANADIG_PLL_528_DENOM_B)
+
+#define HW_ANADIG_PLL_AUDIO (0x00000070)
+#define HW_ANADIG_PLL_AUDIO_SET (0x00000074)
+#define HW_ANADIG_PLL_AUDIO_CLR (0x00000078)
+#define HW_ANADIG_PLL_AUDIO_TOG (0x0000007c)
+
+#define BM_ANADIG_PLL_AUDIO_LOCK 0x80000000
+#define BP_ANADIG_PLL_AUDIO_RSVD0 22
+#define BM_ANADIG_PLL_AUDIO_RSVD0 0x7FC00000
+#define BF_ANADIG_PLL_AUDIO_RSVD0(v) \
+ (((v) << 22) & BM_ANADIG_PLL_AUDIO_RSVD0)
+#define BM_ANADIG_PLL_AUDIO_SSC_EN 0x00200000
+#define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT 19
+#define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT 0x00180000
+#define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v) \
+ (((v) << 19) & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+#define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN 0x00040000
+#define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE 0x00020000
+#define BM_ANADIG_PLL_AUDIO_BYPASS 0x00010000
+#define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC 14
+#define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_AUDIO_ENABLE 0x00002000
+#define BM_ANADIG_PLL_AUDIO_POWERDOWN 0x00001000
+#define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_AUDIO_HALF_CP 0x00000200
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_LF 0x00000100
+#define BM_ANADIG_PLL_AUDIO_HALF_LF 0x00000080
+#define BP_ANADIG_PLL_AUDIO_DIV_SELECT 0
+#define BM_ANADIG_PLL_AUDIO_DIV_SELECT 0x0000007F
+#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_PLL_AUDIO_DIV_SELECT)
+
+#define HW_ANADIG_PLL_AUDIO_NUM (0x00000080)
+
+#define BP_ANADIG_PLL_AUDIO_NUM_RSVD0 30
+#define BM_ANADIG_PLL_AUDIO_NUM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_AUDIO_NUM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_AUDIO_NUM_RSVD0)
+#define BP_ANADIG_PLL_AUDIO_NUM_A 0
+#define BM_ANADIG_PLL_AUDIO_NUM_A 0x3FFFFFFF
+#define BF_ANADIG_PLL_AUDIO_NUM_A(v) \
+ (((v) << 0) & BM_ANADIG_PLL_AUDIO_NUM_A)
+
+#define HW_ANADIG_PLL_AUDIO_DENOM (0x00000090)
+
+#define BP_ANADIG_PLL_AUDIO_DENOM_RSVD0 30
+#define BM_ANADIG_PLL_AUDIO_DENOM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_AUDIO_DENOM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_AUDIO_DENOM_RSVD0)
+#define BP_ANADIG_PLL_AUDIO_DENOM_B 0
+#define BM_ANADIG_PLL_AUDIO_DENOM_B 0x3FFFFFFF
+#define BF_ANADIG_PLL_AUDIO_DENOM_B(v) \
+ (((v) << 0) & BM_ANADIG_PLL_AUDIO_DENOM_B)
+
+#define HW_ANADIG_PLL_VIDEO (0x000000a0)
+#define HW_ANADIG_PLL_VIDEO_SET (0x000000a4)
+#define HW_ANADIG_PLL_VIDEO_CLR (0x000000a8)
+#define HW_ANADIG_PLL_VIDEO_TOG (0x000000ac)
+
+#define BM_ANADIG_PLL_VIDEO_LOCK 0x80000000
+#define BP_ANADIG_PLL_VIDEO_RSVD0 22
+#define BM_ANADIG_PLL_VIDEO_RSVD0 0x7FC00000
+#define BF_ANADIG_PLL_VIDEO_RSVD0(v) \
+ (((v) << 22) & BM_ANADIG_PLL_VIDEO_RSVD0)
+#define BM_ANADIG_PLL_VIDEO_SSC_EN 0x00200000
+#define BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT 19
+#define BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT 0x00180000
+#define BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(v) \
+ (((v) << 19) & BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
+#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN 0x00040000
+#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE 0x00020000
+#define BM_ANADIG_PLL_VIDEO_BYPASS 0x00010000
+#define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC 14
+#define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_VIDEO_ENABLE 0x00002000
+#define BM_ANADIG_PLL_VIDEO_POWERDOWN 0x00001000
+#define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_VIDEO_HALF_CP 0x00000200
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_LF 0x00000100
+#define BM_ANADIG_PLL_VIDEO_HALF_LF 0x00000080
+#define BP_ANADIG_PLL_VIDEO_DIV_SELECT 0
+#define BM_ANADIG_PLL_VIDEO_DIV_SELECT 0x0000007F
+#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_PLL_VIDEO_DIV_SELECT)
+
+#define HW_ANADIG_PLL_VIDEO_NUM (0x000000b0)
+
+#define BP_ANADIG_PLL_VIDEO_NUM_RSVD0 30
+#define BM_ANADIG_PLL_VIDEO_NUM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_VIDEO_NUM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_VIDEO_NUM_RSVD0)
+#define BP_ANADIG_PLL_VIDEO_NUM_A 0
+#define BM_ANADIG_PLL_VIDEO_NUM_A 0x3FFFFFFF
+#define BF_ANADIG_PLL_VIDEO_NUM_A(v) \
+ (((v) << 0) & BM_ANADIG_PLL_VIDEO_NUM_A)
+
+#define HW_ANADIG_PLL_VIDEO_DENOM (0x000000c0)
+
+#define BP_ANADIG_PLL_VIDEO_DENOM_RSVD0 30
+#define BM_ANADIG_PLL_VIDEO_DENOM_RSVD0 0xC0000000
+#define BF_ANADIG_PLL_VIDEO_DENOM_RSVD0(v) \
+ (((v) << 30) & BM_ANADIG_PLL_VIDEO_DENOM_RSVD0)
+#define BP_ANADIG_PLL_VIDEO_DENOM_B 0
+#define BM_ANADIG_PLL_VIDEO_DENOM_B 0x3FFFFFFF
+#define BF_ANADIG_PLL_VIDEO_DENOM_B(v) \
+ (((v) << 0) & BM_ANADIG_PLL_VIDEO_DENOM_B)
+
+#define HW_ANADIG_PLL_MLB (0x000000d0)
+#define HW_ANADIG_PLL_MLB_SET (0x000000d4)
+#define HW_ANADIG_PLL_MLB_CLR (0x000000d8)
+#define HW_ANADIG_PLL_MLB_TOG (0x000000dc)
+
+#define BM_ANADIG_PLL_MLB_LOCK 0x80000000
+#define BP_ANADIG_PLL_MLB_RSVD2 29
+#define BM_ANADIG_PLL_MLB_RSVD2 0x60000000
+#define BF_ANADIG_PLL_MLB_RSVD2(v) \
+ (((v) << 29) & BM_ANADIG_PLL_MLB_RSVD2)
+#define BP_ANADIG_PLL_MLB_MLB_FLT_RES_SEL 26
+#define BM_ANADIG_PLL_MLB_MLB_FLT_RES_SEL 0x1C000000
+#define BF_ANADIG_PLL_MLB_MLB_FLT_RES_SEL(v) \
+ (((v) << 26) & BM_ANADIG_PLL_MLB_MLB_FLT_RES_SEL)
+#define BP_ANADIG_PLL_MLB_RX_CLK_DELAY_CFG 23
+#define BM_ANADIG_PLL_MLB_RX_CLK_DELAY_CFG 0x03800000
+#define BF_ANADIG_PLL_MLB_RX_CLK_DELAY_CFG(v) \
+ (((v) << 23) & BM_ANADIG_PLL_MLB_RX_CLK_DELAY_CFG)
+#define BP_ANADIG_PLL_MLB_VDDD_DELAY_CFG 20
+#define BM_ANADIG_PLL_MLB_VDDD_DELAY_CFG 0x00700000
+#define BF_ANADIG_PLL_MLB_VDDD_DELAY_CFG(v) \
+ (((v) << 20) & BM_ANADIG_PLL_MLB_VDDD_DELAY_CFG)
+#define BP_ANADIG_PLL_MLB_VDDA_DELAY_CFG 17
+#define BM_ANADIG_PLL_MLB_VDDA_DELAY_CFG 0x000E0000
+#define BF_ANADIG_PLL_MLB_VDDA_DELAY_CFG(v) \
+ (((v) << 17) & BM_ANADIG_PLL_MLB_VDDA_DELAY_CFG)
+#define BM_ANADIG_PLL_MLB_BYPASS 0x00010000
+#define BP_ANADIG_PLL_MLB_RSVD1 14
+#define BM_ANADIG_PLL_MLB_RSVD1 0x0000C000
+#define BF_ANADIG_PLL_MLB_RSVD1(v) \
+ (((v) << 14) & BM_ANADIG_PLL_MLB_RSVD1)
+#define BP_ANADIG_PLL_MLB_PHASE_SEL 12
+#define BM_ANADIG_PLL_MLB_PHASE_SEL 0x00003000
+#define BF_ANADIG_PLL_MLB_PHASE_SEL(v) \
+ (((v) << 12) & BM_ANADIG_PLL_MLB_PHASE_SEL)
+#define BM_ANADIG_PLL_MLB_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_MLB_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_MLB_HALF_CP 0x00000200
+#define BP_ANADIG_PLL_MLB_RSVD0 0
+#define BM_ANADIG_PLL_MLB_RSVD0 0x000001FF
+#define BF_ANADIG_PLL_MLB_RSVD0(v) \
+ (((v) << 0) & BM_ANADIG_PLL_MLB_RSVD0)
+
+#define HW_ANADIG_PLL_ENET (0x000000e0)
+#define HW_ANADIG_PLL_ENET_SET (0x000000e4)
+#define HW_ANADIG_PLL_ENET_CLR (0x000000e8)
+#define HW_ANADIG_PLL_ENET_TOG (0x000000ec)
+
+#define BM_ANADIG_PLL_ENET_LOCK 0x80000000
+#define BP_ANADIG_PLL_ENET_RSVD1 21
+#define BM_ANADIG_PLL_ENET_RSVD1 0x7FE00000
+#define BF_ANADIG_PLL_ENET_RSVD1(v) \
+ (((v) << 21) & BM_ANADIG_PLL_ENET_RSVD1)
+#define BM_ANADIG_PLL_ENET_ENABLE_SATA 0x00100000
+#define BM_ANADIG_PLL_ENET_ENABLE_PCIE 0x00080000
+#define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN 0x00040000
+#define BM_ANADIG_PLL_ENET_DITHER_ENABLE 0x00020000
+#define BM_ANADIG_PLL_ENET_BYPASS 0x00010000
+#define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC 14
+#define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC 0x0000C000
+#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v) \
+ (((v) << 14) & BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1 0x1
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2 0x2
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR 0x3
+#define BM_ANADIG_PLL_ENET_ENABLE 0x00002000
+#define BM_ANADIG_PLL_ENET_POWERDOWN 0x00001000
+#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF 0x00000800
+#define BM_ANADIG_PLL_ENET_DOUBLE_CP 0x00000400
+#define BM_ANADIG_PLL_ENET_HALF_CP 0x00000200
+#define BM_ANADIG_PLL_ENET_DOUBLE_LF 0x00000100
+#define BM_ANADIG_PLL_ENET_HALF_LF 0x00000080
+#define BP_ANADIG_PLL_ENET_RSVD0 2
+#define BM_ANADIG_PLL_ENET_RSVD0 0x0000007C
+#define BF_ANADIG_PLL_ENET_RSVD0(v) \
+ (((v) << 2) & BM_ANADIG_PLL_ENET_RSVD0)
+#define BP_ANADIG_PLL_ENET_DIV_SELECT 0
+#define BM_ANADIG_PLL_ENET_DIV_SELECT 0x00000003
+#define BF_ANADIG_PLL_ENET_DIV_SELECT(v) \
+ (((v) << 0) & BM_ANADIG_PLL_ENET_DIV_SELECT)
+
+#define HW_ANADIG_PFD_480 (0x000000f0)
+#define HW_ANADIG_PFD_480_SET (0x000000f4)
+#define HW_ANADIG_PFD_480_CLR (0x000000f8)
+#define HW_ANADIG_PFD_480_TOG (0x000000fc)
+
+#define BM_ANADIG_PFD_480_PFD3_CLKGATE 0x80000000
+#define BM_ANADIG_PFD_480_PFD3_STABLE 0x40000000
+#define BP_ANADIG_PFD_480_PFD3_FRAC 24
+#define BM_ANADIG_PFD_480_PFD3_FRAC 0x3F000000
+#define BF_ANADIG_PFD_480_PFD3_FRAC(v) \
+ (((v) << 24) & BM_ANADIG_PFD_480_PFD3_FRAC)
+#define BM_ANADIG_PFD_480_PFD2_CLKGATE 0x00800000
+#define BM_ANADIG_PFD_480_PFD2_STABLE 0x00400000
+#define BP_ANADIG_PFD_480_PFD2_FRAC 16
+#define BM_ANADIG_PFD_480_PFD2_FRAC 0x003F0000
+#define BF_ANADIG_PFD_480_PFD2_FRAC(v) \
+ (((v) << 16) & BM_ANADIG_PFD_480_PFD2_FRAC)
+#define BM_ANADIG_PFD_480_PFD1_CLKGATE 0x00008000
+#define BM_ANADIG_PFD_480_PFD1_STABLE 0x00004000
+#define BP_ANADIG_PFD_480_PFD1_FRAC 8
+#define BM_ANADIG_PFD_480_PFD1_FRAC 0x00003F00
+#define BF_ANADIG_PFD_480_PFD1_FRAC(v) \
+ (((v) << 8) & BM_ANADIG_PFD_480_PFD1_FRAC)
+#define BM_ANADIG_PFD_480_PFD0_CLKGATE 0x00000080
+#define BM_ANADIG_PFD_480_PFD0_STABLE 0x00000040
+#define BP_ANADIG_PFD_480_PFD0_FRAC 0
+#define BM_ANADIG_PFD_480_PFD0_FRAC 0x0000003F
+#define BF_ANADIG_PFD_480_PFD0_FRAC(v) \
+ (((v) << 0) & BM_ANADIG_PFD_480_PFD0_FRAC)
+
+#define HW_ANADIG_PFD_528 (0x00000100)
+#define HW_ANADIG_PFD_528_SET (0x00000104)
+#define HW_ANADIG_PFD_528_CLR (0x00000108)
+#define HW_ANADIG_PFD_528_TOG (0x0000010c)
+
+#define BM_ANADIG_PFD_528_PFD3_CLKGATE 0x80000000
+#define BM_ANADIG_PFD_528_PFD3_STABLE 0x40000000
+#define BP_ANADIG_PFD_528_PFD3_FRAC 24
+#define BM_ANADIG_PFD_528_PFD3_FRAC 0x3F000000
+#define BF_ANADIG_PFD_528_PFD3_FRAC(v) \
+ (((v) << 24) & BM_ANADIG_PFD_528_PFD3_FRAC)
+#define BM_ANADIG_PFD_528_PFD2_CLKGATE 0x00800000
+#define BM_ANADIG_PFD_528_PFD2_STABLE 0x00400000
+#define BP_ANADIG_PFD_528_PFD2_FRAC 16
+#define BM_ANADIG_PFD_528_PFD2_FRAC 0x003F0000
+#define BF_ANADIG_PFD_528_PFD2_FRAC(v) \
+ (((v) << 16) & BM_ANADIG_PFD_528_PFD2_FRAC)
+#define BM_ANADIG_PFD_528_PFD1_CLKGATE 0x00008000
+#define BM_ANADIG_PFD_528_PFD1_STABLE 0x00004000
+#define BP_ANADIG_PFD_528_PFD1_FRAC 8
+#define BM_ANADIG_PFD_528_PFD1_FRAC 0x00003F00
+#define BF_ANADIG_PFD_528_PFD1_FRAC(v) \
+ (((v) << 8) & BM_ANADIG_PFD_528_PFD1_FRAC)
+#define BM_ANADIG_PFD_528_PFD0_CLKGATE 0x00000080
+#define BM_ANADIG_PFD_528_PFD0_STABLE 0x00000040
+#define BP_ANADIG_PFD_528_PFD0_FRAC 0
+#define BM_ANADIG_PFD_528_PFD0_FRAC 0x0000003F
+#define BF_ANADIG_PFD_528_PFD0_FRAC(v) \
+ (((v) << 0) & BM_ANADIG_PFD_528_PFD0_FRAC)
+
+#define HW_ANADIG_REG_1P1 (0x00000110)
+#define HW_ANADIG_REG_1P1_SET (0x00000114)
+#define HW_ANADIG_REG_1P1_CLR (0x00000118)
+#define HW_ANADIG_REG_1P1_TOG (0x0000011c)
+
+#define BP_ANADIG_REG_1P1_RSVD2 18
+#define BM_ANADIG_REG_1P1_RSVD2 0xFFFC0000
+#define BF_ANADIG_REG_1P1_RSVD2(v) \
+ (((v) << 18) & BM_ANADIG_REG_1P1_RSVD2)
+#define BM_ANADIG_REG_1P1_OK_VDD1P1 0x00020000
+#define BM_ANADIG_REG_1P1_BO_VDD1P1 0x00010000
+#define BP_ANADIG_REG_1P1_RSVD1 13
+#define BM_ANADIG_REG_1P1_RSVD1 0x0000E000
+#define BF_ANADIG_REG_1P1_RSVD1(v) \
+ (((v) << 13) & BM_ANADIG_REG_1P1_RSVD1)
+#define BP_ANADIG_REG_1P1_OUTPUT_TRG 8
+#define BM_ANADIG_REG_1P1_OUTPUT_TRG 0x00001F00
+#define BF_ANADIG_REG_1P1_OUTPUT_TRG(v) \
+ (((v) << 8) & BM_ANADIG_REG_1P1_OUTPUT_TRG)
+#define BM_ANADIG_REG_1P1_RSVD0 0x00000080
+#define BP_ANADIG_REG_1P1_BO_OFFSET 4
+#define BM_ANADIG_REG_1P1_BO_OFFSET 0x00000070
+#define BF_ANADIG_REG_1P1_BO_OFFSET(v) \
+ (((v) << 4) & BM_ANADIG_REG_1P1_BO_OFFSET)
+#define BM_ANADIG_REG_1P1_ENABLE_PULLDOWN 0x00000008
+#define BM_ANADIG_REG_1P1_ENABLE_ILIMIT 0x00000004
+#define BM_ANADIG_REG_1P1_ENABLE_BO 0x00000002
+#define BM_ANADIG_REG_1P1_ENABLE_LINREG 0x00000001
+
+#define HW_ANADIG_REG_3P0 (0x00000120)
+#define HW_ANADIG_REG_3P0_SET (0x00000124)
+#define HW_ANADIG_REG_3P0_CLR (0x00000128)
+#define HW_ANADIG_REG_3P0_TOG (0x0000012c)
+
+#define BP_ANADIG_REG_3P0_RSVD2 18
+#define BM_ANADIG_REG_3P0_RSVD2 0xFFFC0000
+#define BF_ANADIG_REG_3P0_RSVD2(v) \
+ (((v) << 18) & BM_ANADIG_REG_3P0_RSVD2)
+#define BM_ANADIG_REG_3P0_OK_VDD3P0 0x00020000
+#define BM_ANADIG_REG_3P0_BO_VDD3P0 0x00010000
+#define BP_ANADIG_REG_3P0_RSVD1 13
+#define BM_ANADIG_REG_3P0_RSVD1 0x0000E000
+#define BF_ANADIG_REG_3P0_RSVD1(v) \
+ (((v) << 13) & BM_ANADIG_REG_3P0_RSVD1)
+#define BP_ANADIG_REG_3P0_OUTPUT_TRG 8
+#define BM_ANADIG_REG_3P0_OUTPUT_TRG 0x00001F00
+#define BF_ANADIG_REG_3P0_OUTPUT_TRG(v) \
+ (((v) << 8) & BM_ANADIG_REG_3P0_OUTPUT_TRG)
+#define BM_ANADIG_REG_3P0_VBUS_SEL 0x00000080
+#define BP_ANADIG_REG_3P0_BO_OFFSET 4
+#define BM_ANADIG_REG_3P0_BO_OFFSET 0x00000070
+#define BF_ANADIG_REG_3P0_BO_OFFSET(v) \
+ (((v) << 4) & BM_ANADIG_REG_3P0_BO_OFFSET)
+#define BM_ANADIG_REG_3P0_RSVD0 0x00000008
+#define BM_ANADIG_REG_3P0_ENABLE_ILIMIT 0x00000004
+#define BM_ANADIG_REG_3P0_ENABLE_BO 0x00000002
+#define BM_ANADIG_REG_3P0_ENABLE_LINREG 0x00000001
+
+#define HW_ANADIG_REG_2P5 (0x00000130)
+#define HW_ANADIG_REG_2P5_SET (0x00000134)
+#define HW_ANADIG_REG_2P5_CLR (0x00000138)
+#define HW_ANADIG_REG_2P5_TOG (0x0000013c)
+
+#define BP_ANADIG_REG_2P5_RSVD2 19
+#define BM_ANADIG_REG_2P5_RSVD2 0xFFF80000
+#define BF_ANADIG_REG_2P5_RSVD2(v) \
+ (((v) << 19) & BM_ANADIG_REG_2P5_RSVD2)
+#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x00040000
+#define BM_ANADIG_REG_2P5_OK_VDD2P5 0x00020000
+#define BM_ANADIG_REG_2P5_BO_VDD2P5 0x00010000
+#define BP_ANADIG_REG_2P5_RSVD1 13
+#define BM_ANADIG_REG_2P5_RSVD1 0x0000E000
+#define BF_ANADIG_REG_2P5_RSVD1(v) \
+ (((v) << 13) & BM_ANADIG_REG_2P5_RSVD1)
+#define BP_ANADIG_REG_2P5_OUTPUT_TRG 8
+#define BM_ANADIG_REG_2P5_OUTPUT_TRG 0x00001F00
+#define BF_ANADIG_REG_2P5_OUTPUT_TRG(v) \
+ (((v) << 8) & BM_ANADIG_REG_2P5_OUTPUT_TRG)
+#define BM_ANADIG_REG_2P5_RSVD0 0x00000080
+#define BP_ANADIG_REG_2P5_BO_OFFSET 4
+#define BM_ANADIG_REG_2P5_BO_OFFSET 0x00000070
+#define BF_ANADIG_REG_2P5_BO_OFFSET(v) \
+ (((v) << 4) & BM_ANADIG_REG_2P5_BO_OFFSET)
+#define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x00000008
+#define BM_ANADIG_REG_2P5_ENABLE_ILIMIT 0x00000004
+#define BM_ANADIG_REG_2P5_ENABLE_BO 0x00000002
+#define BM_ANADIG_REG_2P5_ENABLE_LINREG 0x00000001
+
+#define HW_ANADIG_REG_CORE (0x00000140)
+#define HW_ANADIG_REG_CORE_SET (0x00000144)
+#define HW_ANADIG_REG_CORE_CLR (0x00000148)
+#define HW_ANADIG_REG_CORE_TOG (0x0000014c)
+
+#define BM_ANADIG_REG_CORE_REF_SHIFT 0x80000000
+#define BM_ANADIG_REG_CORE_RSVD0 0x40000000
+#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000
+#define BP_ANADIG_REG_CORE_RAMP_RATE 27
+#define BM_ANADIG_REG_CORE_RAMP_RATE 0x18000000
+#define BF_ANADIG_REG_CORE_RAMP_RATE(v) \
+ (((v) << 27) & BM_ANADIG_REG_CORE_RAMP_RATE)
+#define BP_ANADIG_REG_CORE_REG2_ADJ 23
+#define BM_ANADIG_REG_CORE_REG2_ADJ 0x07800000
+#define BF_ANADIG_REG_CORE_REG2_ADJ(v) \
+ (((v) << 23) & BM_ANADIG_REG_CORE_REG2_ADJ)
+#define BP_ANADIG_REG_CORE_REG2_TRG 18
+#define BM_ANADIG_REG_CORE_REG2_TRG 0x007C0000
+#define BF_ANADIG_REG_CORE_REG2_TRG(v) \
+ (((v) << 18) & BM_ANADIG_REG_CORE_REG2_TRG)
+#define BP_ANADIG_REG_CORE_REG1_ADJ 14
+#define BM_ANADIG_REG_CORE_REG1_ADJ 0x0003C000
+#define BF_ANADIG_REG_CORE_REG1_ADJ(v) \
+ (((v) << 14) & BM_ANADIG_REG_CORE_REG1_ADJ)
+#define BP_ANADIG_REG_CORE_REG1_TRG 9
+#define BM_ANADIG_REG_CORE_REG1_TRG 0x00003E00
+#define BF_ANADIG_REG_CORE_REG1_TRG(v) \
+ (((v) << 9) & BM_ANADIG_REG_CORE_REG1_TRG)
+#define BP_ANADIG_REG_CORE_REG0_ADJ 5
+#define BM_ANADIG_REG_CORE_REG0_ADJ 0x000001E0
+#define BF_ANADIG_REG_CORE_REG0_ADJ(v) \
+ (((v) << 5) & BM_ANADIG_REG_CORE_REG0_ADJ)
+#define BP_ANADIG_REG_CORE_REG0_TRG 0
+#define BM_ANADIG_REG_CORE_REG0_TRG 0x0000001F
+#define BF_ANADIG_REG_CORE_REG0_TRG(v) \
+ (((v) << 0) & BM_ANADIG_REG_CORE_REG0_TRG)
+
+#define HW_ANADIG_ANA_MISC0 (0x00000150)
+#define HW_ANADIG_ANA_MISC0_SET (0x00000154)
+#define HW_ANADIG_ANA_MISC0_CLR (0x00000158)
+#define HW_ANADIG_ANA_MISC0_TOG (0x0000015c)
+
+#define BP_ANADIG_ANA_MISC0_RSVD2 29
+#define BM_ANADIG_ANA_MISC0_RSVD2 0xE0000000
+#define BF_ANADIG_ANA_MISC0_RSVD2(v) \
+ (((v) << 29) & BM_ANADIG_ANA_MISC0_RSVD2)
+#define BP_ANADIG_ANA_MISC0_CLKGATE_DELAY 26
+#define BM_ANADIG_ANA_MISC0_CLKGATE_DELAY 0x1C000000
+#define BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(v) \
+ (((v) << 26) & BM_ANADIG_ANA_MISC0_CLKGATE_DELAY)
+#define BM_ANADIG_ANA_MISC0_CLKGATE_CTRL 0x02000000
+#define BP_ANADIG_ANA_MISC0_ANAMUX 21
+#define BM_ANADIG_ANA_MISC0_ANAMUX 0x01E00000
+#define BF_ANADIG_ANA_MISC0_ANAMUX(v) \
+ (((v) << 21) & BM_ANADIG_ANA_MISC0_ANAMUX)
+#define BM_ANADIG_ANA_MISC0_ANAMUX_EN 0x00100000
+#define BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH 18
+#define BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH 0x000C0000
+#define BF_ANADIG_ANA_MISC0_WBCP_VPW_THRESH(v) \
+ (((v) << 18) & BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
+#define BM_ANADIG_ANA_MISC0_OSC_XTALOK_EN 0x00020000
+#define BM_ANADIG_ANA_MISC0_OSC_XTALOK 0x00010000
+#define BP_ANADIG_ANA_MISC0_OSC_I 14
+#define BM_ANADIG_ANA_MISC0_OSC_I 0x0000C000
+#define BF_ANADIG_ANA_MISC0_OSC_I(v) \
+ (((v) << 14) & BM_ANADIG_ANA_MISC0_OSC_I)
+#define BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN 0x00002000
+#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG \
+ (cpu_is_mx6sl() ? 0x00000800 : 0x00001000)
+#define BP_ANADIG_ANA_MISC0_RSVD0 10
+#define BM_ANADIG_ANA_MISC0_RSVD0 0x00000C00
+#define BF_ANADIG_ANA_MISC0_RSVD0(v) \
+ (((v) << 10) & BM_ANADIG_ANA_MISC0_RSVD0)
+#define BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST 8
+#define BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST 0x00000300
+#define BF_ANADIG_ANA_MISC0_REFTOP_BIAS_TST(v) \
+ (((v) << 8) & BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
+#define BM_ANADIG_ANA_MISC0_REFTOP_VBGUP 0x00000080
+#define BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ 4
+#define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ 0x00000070
+#define BF_ANADIG_ANA_MISC0_REFTOP_VBGADJ(v) \
+ (((v) << 4) & BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
+#define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF 0x00000008
+#define BM_ANADIG_ANA_MISC0_REFTOP_LOWPOWER 0x00000004
+#define BM_ANADIG_ANA_MISC0_REFTOP_PWDVBGUP 0x00000002
+#define BM_ANADIG_ANA_MISC0_REFTOP_PWD 0x00000001
+
+#define HW_ANADIG_ANA_MISC1 (0x00000160)
+#define HW_ANADIG_ANA_MISC1_SET (0x00000164)
+#define HW_ANADIG_ANA_MISC1_CLR (0x00000168)
+#define HW_ANADIG_ANA_MISC1_TOG (0x0000016c)
+
+#define BM_ANADIG_ANA_MISC1_IRQ_DIG_BO 0x80000000
+#define BM_ANADIG_ANA_MISC1_IRQ_ANA_BO 0x40000000
+#define BM_ANADIG_ANA_MISC1_IRQ_TEMPSENSE_BO 0x20000000
+#define BP_ANADIG_ANA_MISC1_RSVD0 14
+#define BM_ANADIG_ANA_MISC1_RSVD0 0x1FFFC000
+#define BF_ANADIG_ANA_MISC1_RSVD0(v) \
+ (((v) << 14) & BM_ANADIG_ANA_MISC1_RSVD0)
+#define BM_ANADIG_ANA_MISC1_LVDSCLK2_IBEN 0x00002000
+#define BM_ANADIG_ANA_MISC1_LVDSCLK1_IBEN 0x00001000
+#define BM_ANADIG_ANA_MISC1_LVDSCLK2_OBEN 0x00000800
+#define BM_ANADIG_ANA_MISC1_LVDSCLK1_OBEN 0x00000400
+#define BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL 5
+#define BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL 0x000003E0
+#define BF_ANADIG_ANA_MISC1_LVDS2_CLK_SEL(v) \
+ (((v) << 5) & BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
+#define BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL 0
+#define BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL 0x0000001F
+#define BF_ANADIG_ANA_MISC1_LVDS1_CLK_SEL(v) \
+ (((v) << 0) & BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
+
+#define HW_ANADIG_ANA_MISC2 (0x00000170)
+#define HW_ANADIG_ANA_MISC2_SET (0x00000174)
+#define HW_ANADIG_ANA_MISC2_CLR (0x00000178)
+#define HW_ANADIG_ANA_MISC2_TOG (0x0000017c)
+
+#define BP_ANADIG_ANA_MISC2_CONTROL3 30
+#define BM_ANADIG_ANA_MISC2_CONTROL3 0xC0000000
+#define BF_ANADIG_ANA_MISC2_CONTROL3(v) \
+ (((v) << 30) & BM_ANADIG_ANA_MISC2_CONTROL3)
+#define BP_ANADIG_ANA_MISC2_REG2_STEP_TIME 28
+#define BM_ANADIG_ANA_MISC2_REG2_STEP_TIME 0x30000000
+#define BF_ANADIG_ANA_MISC2_REG2_STEP_TIME(v) \
+ (((v) << 28) & BM_ANADIG_ANA_MISC2_REG2_STEP_TIME)
+#define BP_ANADIG_ANA_MISC2_REG1_STEP_TIME 26
+#define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME 0x0C000000
+#define BF_ANADIG_ANA_MISC2_REG1_STEP_TIME(v) \
+ (((v) << 26) & BM_ANADIG_ANA_MISC2_REG1_STEP_TIME)
+#define BP_ANADIG_ANA_MISC2_REG0_STEP_TIME 24
+#define BM_ANADIG_ANA_MISC2_REG0_STEP_TIME 0x03000000
+#define BF_ANADIG_ANA_MISC2_REG0_STEP_TIME(v) \
+ (((v) << 24) & BM_ANADIG_ANA_MISC2_REG0_STEP_TIME)
+#define BM_ANADIG_ANA_MISC2_CONTROL2 0x00800000
+#define BM_ANADIG_ANA_MISC2_REG2_OK 0x00400000
+#define BM_ANADIG_ANA_MISC2_REG2_ENABLE_BO 0x00200000
+#define BM_ANADIG_ANA_MISC2_RSVD2 0x00100000
+#define BM_ANADIG_ANA_MISC2_REG2_BO_STATUS 0x00080000
+#define BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET 16
+#define BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET 0x00070000
+#define BF_ANADIG_ANA_MISC2_REG2_BO_OFFSET(v) \
+ (((v) << 16) & BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
+#define BM_ANADIG_ANA_MISC2_CONTROL1 0x00008000
+#define BM_ANADIG_ANA_MISC2_REG1_OK 0x00004000
+#define BM_ANADIG_ANA_MISC2_REG1_ENABLE_BO 0x00002000
+#define BM_ANADIG_ANA_MISC2_RSVD1 0x00001000
+#define BM_ANADIG_ANA_MISC2_REG1_BO_STATUS 0x00000800
+#define BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET 8
+#define BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET 0x00000700
+#define BF_ANADIG_ANA_MISC2_REG1_BO_OFFSET(v) \
+ (((v) << 8) & BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET)
+#define BM_ANADIG_ANA_MISC2_CONTROL0 0x00000080
+#define BM_ANADIG_ANA_MISC2_REG0_OK 0x00000040
+#define BM_ANADIG_ANA_MISC2_REG0_ENABLE_BO 0x00000020
+#define BM_ANADIG_ANA_MISC2_RSVD0 0x00000010
+#define BM_ANADIG_ANA_MISC2_REG0_BO_STATUS 0x00000008
+#define BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET 0
+#define BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET 0x00000007
+#define BF_ANADIG_ANA_MISC2_REG0_BO_OFFSET(v) \
+ (((v) << 0) & BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
+
+#define HW_ANADIG_TEMPSENSE0 (0x00000180)
+#define HW_ANADIG_TEMPSENSE0_SET (0x00000184)
+#define HW_ANADIG_TEMPSENSE0_CLR (0x00000188)
+#define HW_ANADIG_TEMPSENSE0_TOG (0x0000018c)
+
+#define BP_ANADIG_TEMPSENSE0_ALARM_VALUE 20
+#define BM_ANADIG_TEMPSENSE0_ALARM_VALUE 0xFFF00000
+#define BF_ANADIG_TEMPSENSE0_ALARM_VALUE(v) \
+ (((v) << 20) & BM_ANADIG_TEMPSENSE0_ALARM_VALUE)
+#define BP_ANADIG_TEMPSENSE0_TEMP_VALUE 8
+#define BM_ANADIG_TEMPSENSE0_TEMP_VALUE 0x000FFF00
+#define BF_ANADIG_TEMPSENSE0_TEMP_VALUE(v) \
+ (((v) << 8) & BM_ANADIG_TEMPSENSE0_TEMP_VALUE)
+#define BM_ANADIG_TEMPSENSE0_RSVD0 0x00000080
+#define BM_ANADIG_TEMPSENSE0_TEST 0x00000040
+#define BP_ANADIG_TEMPSENSE0_VBGADJ 3
+#define BM_ANADIG_TEMPSENSE0_VBGADJ 0x00000038
+#define BF_ANADIG_TEMPSENSE0_VBGADJ(v) \
+ (((v) << 3) & BM_ANADIG_TEMPSENSE0_VBGADJ)
+#define BM_ANADIG_TEMPSENSE0_FINISHED 0x00000004
+#define BM_ANADIG_TEMPSENSE0_MEASURE_TEMP 0x00000002
+#define BM_ANADIG_TEMPSENSE0_POWER_DOWN 0x00000001
+
+#define HW_ANADIG_TEMPSENSE1 (0x00000190)
+#define HW_ANADIG_TEMPSENSE1_SET (0x00000194)
+#define HW_ANADIG_TEMPSENSE1_CLR (0x00000198)
+#define HW_ANADIG_TEMPSENSE1_TOG (0x0000019c)
+
+#define BP_ANADIG_TEMPSENSE1_RSVD0 16
+#define BM_ANADIG_TEMPSENSE1_RSVD0 0xFFFF0000
+#define BF_ANADIG_TEMPSENSE1_RSVD0(v) \
+ (((v) << 16) & BM_ANADIG_TEMPSENSE1_RSVD0)
+#define BP_ANADIG_TEMPSENSE1_MEASURE_FREQ 0
+#define BM_ANADIG_TEMPSENSE1_MEASURE_FREQ 0x0000FFFF
+#define BF_ANADIG_TEMPSENSE1_MEASURE_FREQ(v) \
+ (((v) << 0) & BM_ANADIG_TEMPSENSE1_MEASURE_FREQ)
+
+#define HW_ANADIG_USB1_VBUS_DETECT (0x000001a0)
+#define HW_ANADIG_USB1_VBUS_DETECT_SET (0x000001a4)
+#define HW_ANADIG_USB1_VBUS_DETECT_CLR (0x000001a8)
+#define HW_ANADIG_USB1_VBUS_DETECT_TOG (0x000001ac)
+
+#define BM_ANADIG_USB1_VBUS_DETECT_EN_CHARGER_RESISTOR 0x80000000
+#define BP_ANADIG_USB1_VBUS_DETECT_RSVD2 28
+#define BM_ANADIG_USB1_VBUS_DETECT_RSVD2 0x70000000
+#define BF_ANADIG_USB1_VBUS_DETECT_RSVD2(v) \
+ (((v) << 28) & BM_ANADIG_USB1_VBUS_DETECT_RSVD2)
+#define BM_ANADIG_USB1_VBUS_DETECT_CHARGE_VBUS 0x08000000
+#define BM_ANADIG_USB1_VBUS_DETECT_DISCHARGE_VBUS 0x04000000
+#define BP_ANADIG_USB1_VBUS_DETECT_RSVD1 21
+#define BM_ANADIG_USB1_VBUS_DETECT_RSVD1 0x03E00000
+#define BF_ANADIG_USB1_VBUS_DETECT_RSVD1(v) \
+ (((v) << 21) & BM_ANADIG_USB1_VBUS_DETECT_RSVD1)
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_PWRUP_CMPS 0x00100000
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_5VDETECT 0x00080000
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_TO_B 0x00040000
+#define BP_ANADIG_USB1_VBUS_DETECT_RSVD0 8
+#define BM_ANADIG_USB1_VBUS_DETECT_RSVD0 0x0003FF00
+#define BF_ANADIG_USB1_VBUS_DETECT_RSVD0(v) \
+ (((v) << 8) & BM_ANADIG_USB1_VBUS_DETECT_RSVD0)
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_OVERRIDE 0x00000080
+#define BM_ANADIG_USB1_VBUS_DETECT_AVALID_OVERRIDE 0x00000040
+#define BM_ANADIG_USB1_VBUS_DETECT_BVALID_OVERRIDE 0x00000020
+#define BM_ANADIG_USB1_VBUS_DETECT_SESSEND_OVERRIDE 0x00000010
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUS_OVERRIDE_EN 0x00000008
+#define BP_ANADIG_USB1_VBUS_DETECT_VBUSVALID_THRESH 0
+#define BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_THRESH 0x00000007
+#define BF_ANADIG_USB1_VBUS_DETECT_VBUSVALID_THRESH(v) \
+ (((v) << 0) & BM_ANADIG_USB1_VBUS_DETECT_VBUSVALID_THRESH)
+
+#define HW_ANADIG_USB1_CHRG_DETECT (0x000001b0)
+#define HW_ANADIG_USB1_CHRG_DETECT_SET (0x000001b4)
+#define HW_ANADIG_USB1_CHRG_DETECT_CLR (0x000001b8)
+#define HW_ANADIG_USB1_CHRG_DETECT_TOG (0x000001bc)
+
+#define BP_ANADIG_USB1_CHRG_DETECT_RSVD2 24
+#define BM_ANADIG_USB1_CHRG_DETECT_RSVD2 0xFF000000
+#define BF_ANADIG_USB1_CHRG_DETECT_RSVD2(v) \
+ (((v) << 24) & BM_ANADIG_USB1_CHRG_DETECT_RSVD2)
+#define BM_ANADIG_USB1_CHRG_DETECT_BGR_BIAS 0x00800000
+#define BP_ANADIG_USB1_CHRG_DETECT_RSVD1 21
+#define BM_ANADIG_USB1_CHRG_DETECT_RSVD1 0x00600000
+#define BF_ANADIG_USB1_CHRG_DETECT_RSVD1(v) \
+ (((v) << 21) & BM_ANADIG_USB1_CHRG_DETECT_RSVD1)
+#define BM_ANADIG_USB1_CHRG_DETECT_EN_B 0x00100000
+#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B 0x00080000
+#define BM_ANADIG_USB1_CHRG_DETECT_CHK_CONTACT 0x00040000
+#define BP_ANADIG_USB1_CHRG_DETECT_RSVD0 1
+#define BM_ANADIG_USB1_CHRG_DETECT_RSVD0 0x0003FFFE
+#define BF_ANADIG_USB1_CHRG_DETECT_RSVD0(v) \
+ (((v) << 1) & BM_ANADIG_USB1_CHRG_DETECT_RSVD0)
+#define BM_ANADIG_USB1_CHRG_DETECT_FORCE_DETECT 0x00000001
+
+#define HW_ANADIG_USB1_VBUS_DET_STAT (0x000001c0)
+#define HW_ANADIG_USB1_VBUS_DET_STAT_SET (0x000001c4)
+#define HW_ANADIG_USB1_VBUS_DET_STAT_CLR (0x000001c8)
+#define HW_ANADIG_USB1_VBUS_DET_STAT_TOG (0x000001cc)
+
+#define BP_ANADIG_USB1_VBUS_DET_STAT_RSVD0 4
+#define BM_ANADIG_USB1_VBUS_DET_STAT_RSVD0 0xFFFFFFF0
+#define BF_ANADIG_USB1_VBUS_DET_STAT_RSVD0(v) \
+ (((v) << 4) & BM_ANADIG_USB1_VBUS_DET_STAT_RSVD0)
+#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID 0x00000008
+#define BM_ANADIG_USB1_VBUS_DET_STAT_AVALID 0x00000004
+#define BM_ANADIG_USB1_VBUS_DET_STAT_BVALID 0x00000002
+#define BM_ANADIG_USB1_VBUS_DET_STAT_SESSEND 0x00000001
+
+#define HW_ANADIG_USB1_CHRG_DET_STAT (0x000001d0)
+#define HW_ANADIG_USB1_CHRG_DET_STAT_SET (0x000001d4)
+#define HW_ANADIG_USB1_CHRG_DET_STAT_CLR (0x000001d8)
+#define HW_ANADIG_USB1_CHRG_DET_STAT_TOG (0x000001dc)
+
+#define BP_ANADIG_USB1_CHRG_DET_STAT_RSVD0 4
+#define BM_ANADIG_USB1_CHRG_DET_STAT_RSVD0 0xFFFFFFF0
+#define BF_ANADIG_USB1_CHRG_DET_STAT_RSVD0(v) \
+ (((v) << 4) & BM_ANADIG_USB1_CHRG_DET_STAT_RSVD0)
+#define BM_ANADIG_USB1_CHRG_DET_STAT_DP_STATE 0x00000008
+#define BM_ANADIG_USB1_CHRG_DET_STAT_DM_STATE 0x00000004
+#define BM_ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED 0x00000002
+#define BM_ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT 0x00000001
+
+#define HW_ANADIG_USB1_LOOPBACK (0x000001e0)
+#define HW_ANADIG_USB1_LOOPBACK_SET (0x000001e4)
+#define HW_ANADIG_USB1_LOOPBACK_CLR (0x000001e8)
+#define HW_ANADIG_USB1_LOOPBACK_TOG (0x000001ec)
+
+#define BP_ANADIG_USB1_LOOPBACK_RSVD0 9
+#define BM_ANADIG_USB1_LOOPBACK_RSVD0 0xFFFFFE00
+#define BF_ANADIG_USB1_LOOPBACK_RSVD0(v) \
+ (((v) << 9) & BM_ANADIG_USB1_LOOPBACK_RSVD0)
+#define BM_ANADIG_USB1_LOOPBACK_UTMO_DIG_TST1 0x00000100
+#define BM_ANADIG_USB1_LOOPBACK_UTMO_DIG_TST0 0x00000080
+#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_HIZ 0x00000040
+#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN 0x00000020
+#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_LS_MODE 0x00000010
+#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_HS_MODE 0x00000008
+#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 0x00000004
+#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST0 0x00000002
+#define BM_ANADIG_USB1_LOOPBACK_UTMI_TESTSTART 0x00000001
+
+#define HW_ANADIG_USB1_MISC (0x000001f0)
+#define HW_ANADIG_USB1_MISC_SET (0x000001f4)
+#define HW_ANADIG_USB1_MISC_CLR (0x000001f8)
+#define HW_ANADIG_USB1_MISC_TOG (0x000001fc)
+
+#define BM_ANADIG_USB1_MISC_RSVD1 0x80000000
+#define BM_ANADIG_USB1_MISC_EN_CLK_UTMI 0x40000000
+#define BM_ANADIG_USB1_MISC_RX_VPIN_FS 0x20000000
+#define BM_ANADIG_USB1_MISC_RX_VMIN_FS 0x10000000
+#define BM_ANADIG_USB1_MISC_RX_RXD_FS 0x08000000
+#define BM_ANADIG_USB1_MISC_RX_SQUELCH 0x04000000
+#define BM_ANADIG_USB1_MISC_RX_DISCON_DET 0x02000000
+#define BM_ANADIG_USB1_MISC_RX_HS_DATA 0x01000000
+#define BP_ANADIG_USB1_MISC_RSVD0 2
+#define BM_ANADIG_USB1_MISC_RSVD0 0x00FFFFFC
+#define BF_ANADIG_USB1_MISC_RSVD0(v) \
+ (((v) << 2) & BM_ANADIG_USB1_MISC_RSVD0)
+#define BM_ANADIG_USB1_MISC_EN_DEGLITCH 0x00000002
+#define BM_ANADIG_USB1_MISC_HS_USE_EXTERNAL_R 0x00000001
+
+#define HW_ANADIG_USB2_VBUS_DETECT (0x00000200)
+#define HW_ANADIG_USB2_VBUS_DETECT_SET (0x00000204)
+#define HW_ANADIG_USB2_VBUS_DETECT_CLR (0x00000208)
+#define HW_ANADIG_USB2_VBUS_DETECT_TOG (0x0000020c)
+
+#define BM_ANADIG_USB2_VBUS_DETECT_EN_CHARGER_RESISTOR 0x80000000
+#define BP_ANADIG_USB2_VBUS_DETECT_RSVD2 28
+#define BM_ANADIG_USB2_VBUS_DETECT_RSVD2 0x70000000
+#define BF_ANADIG_USB2_VBUS_DETECT_RSVD2(v) \
+ (((v) << 28) & BM_ANADIG_USB2_VBUS_DETECT_RSVD2)
+#define BM_ANADIG_USB2_VBUS_DETECT_CHARGE_VBUS 0x08000000
+#define BM_ANADIG_USB2_VBUS_DETECT_DISCHARGE_VBUS 0x04000000
+#define BP_ANADIG_USB2_VBUS_DETECT_RSVD1 21
+#define BM_ANADIG_USB2_VBUS_DETECT_RSVD1 0x03E00000
+#define BF_ANADIG_USB2_VBUS_DETECT_RSVD1(v) \
+ (((v) << 21) & BM_ANADIG_USB2_VBUS_DETECT_RSVD1)
+#define BM_ANADIG_USB2_VBUS_DETECT_VBUSVALID_PWRUP_CMPS 0x00100000
+#define BM_ANADIG_USB2_VBUS_DETECT_VBUSVALID_5VDETECT 0x00080000
+#define BM_ANADIG_USB2_VBUS_DETECT_VBUSVALID_TO_B 0x00040000
+#define BP_ANADIG_USB2_VBUS_DETECT_RSVD0 3
+#define BM_ANADIG_USB2_VBUS_DETECT_RSVD0 0x0003FFF8
+#define BF_ANADIG_USB2_VBUS_DETECT_RSVD0(v) \
+ (((v) << 3) & BM_ANADIG_USB2_VBUS_DETECT_RSVD0)
+#define BP_ANADIG_USB2_VBUS_DETECT_VBUSVALID_THRESH 0
+#define BM_ANADIG_USB2_VBUS_DETECT_VBUSVALID_THRESH 0x00000007
+#define BF_ANADIG_USB2_VBUS_DETECT_VBUSVALID_THRESH(v) \
+ (((v) << 0) & BM_ANADIG_USB2_VBUS_DETECT_VBUSVALID_THRESH)
+
+#define HW_ANADIG_USB2_CHRG_DETECT (0x00000210)
+#define HW_ANADIG_USB2_CHRG_DETECT_SET (0x00000214)
+#define HW_ANADIG_USB2_CHRG_DETECT_CLR (0x00000218)
+#define HW_ANADIG_USB2_CHRG_DETECT_TOG (0x0000021c)
+
+#define BP_ANADIG_USB2_CHRG_DETECT_RSVD2 24
+#define BM_ANADIG_USB2_CHRG_DETECT_RSVD2 0xFF000000
+#define BF_ANADIG_USB2_CHRG_DETECT_RSVD2(v) \
+ (((v) << 24) & BM_ANADIG_USB2_CHRG_DETECT_RSVD2)
+#define BM_ANADIG_USB2_CHRG_DETECT_BGR_BIAS 0x00800000
+#define BP_ANADIG_USB2_CHRG_DETECT_RSVD1 21
+#define BM_ANADIG_USB2_CHRG_DETECT_RSVD1 0x00600000
+#define BF_ANADIG_USB2_CHRG_DETECT_RSVD1(v) \
+ (((v) << 21) & BM_ANADIG_USB2_CHRG_DETECT_RSVD1)
+#define BM_ANADIG_USB2_CHRG_DETECT_EN_B 0x00100000
+#define BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B 0x00080000
+#define BM_ANADIG_USB2_CHRG_DETECT_CHK_CONTACT 0x00040000
+#define BP_ANADIG_USB2_CHRG_DETECT_RSVD0 1
+#define BM_ANADIG_USB2_CHRG_DETECT_RSVD0 0x0003FFFE
+#define BF_ANADIG_USB2_CHRG_DETECT_RSVD0(v) \
+ (((v) << 1) & BM_ANADIG_USB2_CHRG_DETECT_RSVD0)
+#define BM_ANADIG_USB2_CHRG_DETECT_FORCE_DETECT 0x00000001
+
+#define HW_ANADIG_USB2_VBUS_DET_STAT (0x00000220)
+#define HW_ANADIG_USB2_VBUS_DET_STAT_SET (0x00000224)
+#define HW_ANADIG_USB2_VBUS_DET_STAT_CLR (0x00000228)
+#define HW_ANADIG_USB2_VBUS_DET_STAT_TOG (0x0000022c)
+
+#define BP_ANADIG_USB2_VBUS_DET_STAT_RSVD0 4
+#define BM_ANADIG_USB2_VBUS_DET_STAT_RSVD0 0xFFFFFFF0
+#define BF_ANADIG_USB2_VBUS_DET_STAT_RSVD0(v) \
+ (((v) << 4) & BM_ANADIG_USB2_VBUS_DET_STAT_RSVD0)
+#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID 0x00000008
+#define BM_ANADIG_USB2_VBUS_DET_STAT_AVALID 0x00000004
+#define BM_ANADIG_USB2_VBUS_DET_STAT_BVALID 0x00000002
+#define BM_ANADIG_USB2_VBUS_DET_STAT_SESSEND 0x00000001
+
+#define HW_ANADIG_USB2_CHRG_DET_STAT (0x00000230)
+#define HW_ANADIG_USB2_CHRG_DET_STAT_SET (0x00000234)
+#define HW_ANADIG_USB2_CHRG_DET_STAT_CLR (0x00000238)
+#define HW_ANADIG_USB2_CHRG_DET_STAT_TOG (0x0000023c)
+
+#define BP_ANADIG_USB2_CHRG_DET_STAT_RSVD0 4
+#define BM_ANADIG_USB2_CHRG_DET_STAT_RSVD0 0xFFFFFFF0
+#define BF_ANADIG_USB2_CHRG_DET_STAT_RSVD0(v) \
+ (((v) << 4) & BM_ANADIG_USB2_CHRG_DET_STAT_RSVD0)
+#define BM_ANADIG_USB2_CHRG_DET_STAT_DP_STATE 0x00000008
+#define BM_ANADIG_USB2_CHRG_DET_STAT_DM_STATE 0x00000004
+#define BM_ANADIG_USB2_CHRG_DET_STAT_CHRG_DETECTED 0x00000002
+#define BM_ANADIG_USB2_CHRG_DET_STAT_PLUG_CONTACT 0x00000001
+
+#define HW_ANADIG_USB2_LOOPBACK (0x00000240)
+#define HW_ANADIG_USB2_LOOPBACK_SET (0x00000244)
+#define HW_ANADIG_USB2_LOOPBACK_CLR (0x00000248)
+#define HW_ANADIG_USB2_LOOPBACK_TOG (0x0000024c)
+
+#define BP_ANADIG_USB2_LOOPBACK_RSVD0 9
+#define BM_ANADIG_USB2_LOOPBACK_RSVD0 0xFFFFFE00
+#define BF_ANADIG_USB2_LOOPBACK_RSVD0(v) \
+ (((v) << 9) & BM_ANADIG_USB2_LOOPBACK_RSVD0)
+#define BM_ANADIG_USB2_LOOPBACK_UTMO_DIG_TST1 0x00000100
+#define BM_ANADIG_USB2_LOOPBACK_UTMO_DIG_TST0 0x00000080
+#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_HIZ 0x00000040
+#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN 0x00000020
+#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_LS_MODE 0x00000010
+#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_HS_MODE 0x00000008
+#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 0x00000004
+#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST0 0x00000002
+#define BM_ANADIG_USB2_LOOPBACK_UTMI_TESTSTART 0x00000001
+
+#define HW_ANADIG_USB2_MISC (0x00000250)
+#define HW_ANADIG_USB2_MISC_SET (0x00000254)
+#define HW_ANADIG_USB2_MISC_CLR (0x00000258)
+#define HW_ANADIG_USB2_MISC_TOG (0x0000025c)
+
+#define BM_ANADIG_USB2_MISC_RSVD1 0x80000000
+#define BM_ANADIG_USB2_MISC_EN_CLK_UTMI 0x40000000
+#define BM_ANADIG_USB2_MISC_RX_VPIN_FS 0x20000000
+#define BM_ANADIG_USB2_MISC_RX_VMIN_FS 0x10000000
+#define BM_ANADIG_USB2_MISC_RX_RXD_FS 0x08000000
+#define BM_ANADIG_USB2_MISC_RX_SQUELCH 0x04000000
+#define BM_ANADIG_USB2_MISC_RX_DISCON_DET 0x02000000
+#define BM_ANADIG_USB2_MISC_RX_HS_DATA 0x01000000
+#define BP_ANADIG_USB2_MISC_RSVD0 2
+#define BM_ANADIG_USB2_MISC_RSVD0 0x00FFFFFC
+#define BF_ANADIG_USB2_MISC_RSVD0(v) \
+ (((v) << 2) & BM_ANADIG_USB2_MISC_RSVD0)
+#define BM_ANADIG_USB2_MISC_EN_DEGLITCH 0x00000002
+#define BM_ANADIG_USB2_MISC_HS_USE_EXTERNAL_R 0x00000001
+
+#define HW_ANADIG_DIGPROG (0x00000260)
+
+#define BP_ANADIG_DIGPROG_RSVD 24
+#define BM_ANADIG_DIGPROG_RSVD 0xFF000000
+#define BF_ANADIG_DIGPROG_RSVD(v) \
+ (((v) << 24) & BM_ANADIG_DIGPROG_RSVD)
+#define BP_ANADIG_DIGPROG_MAJOR 8
+#define BM_ANADIG_DIGPROG_MAJOR 0x00FFFF00
+#define BF_ANADIG_DIGPROG_MAJOR(v) \
+ (((v) << 8) & BM_ANADIG_DIGPROG_MAJOR)
+#define BP_ANADIG_DIGPROG_MINOR 0
+#define BM_ANADIG_DIGPROG_MINOR 0x000000FF
+#define BF_ANADIG_DIGPROG_MINOR(v) \
+ (((v) << 0) & BM_ANADIG_DIGPROG_MINOR)
+#endif /* __ARCH_ARM___ANADIG_H */
diff --git a/arch/arm/mach-mx6/serial.h b/arch/arm/mach-mx6/serial.h
new file mode 100644
index 00000000..c510b59b
--- /dev/null
+++ b/arch/arm/mach-mx6/serial.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX51_SERIAL_H__
+#define __ARCH_ARM_MACH_MX51_SERIAL_H__
+
+/* UART 1 configuration */
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * Specify the size of the DMA receive buffer. The minimum buffer size is 512
+ * bytes. The buffer size should be a multiple of 256.
+ */
+#define UART1_DMA_RXBUFSIZE 1024
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+#define UART1_DMA_ENABLE 0
+/* UART 2 configuration */
+#define UART2_UCR4_CTSTL -1
+#define UART2_DMA_ENABLE 1
+#define UART2_DMA_RXBUFSIZE 512
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_UCR4_CTSTL 16
+#define UART3_DMA_ENABLE 0
+#define UART3_DMA_RXBUFSIZE 1024
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+/* UART 4 configuration */
+#define UART4_UCR4_CTSTL -1
+#define UART4_DMA_ENABLE 0
+#define UART4_DMA_RXBUFSIZE 512
+#define UART4_UFCR_RXTL 16
+#define UART4_UFCR_TXTL 16
+/* UART 5 configuration */
+#define UART5_UCR4_CTSTL -1
+#define UART5_DMA_ENABLE 0
+#define UART5_DMA_RXBUFSIZE 512
+#define UART5_UFCR_RXTL 16
+#define UART5_UFCR_TXTL 16
+
+#endif /* __ARCH_ARM_MACH_MX51_SERIAL_H__ */
diff --git a/arch/arm/mach-mx6/src-reg.h b/arch/arm/mach-mx6/src-reg.h
new file mode 100644
index 00000000..dc13e431
--- /dev/null
+++ b/arch/arm/mach-mx6/src-reg.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.30
+ * Template revision: 1.3
+ */
+#ifndef _SRC_REGISTER_HEADER_
+#define _SRC_REGISTER_HEADER_
+
+#define SRC_SCR_OFFSET 0x000
+#define SRC_SBMR_OFFSET 0x004
+#define SRC_SRSR_OFFSET 0x008
+#define SRC_SAIAR_OFFSET 0x00c
+#define SRC_SAIRAR_OFFSET 0x010
+#define SRC_SISR_OFFSET 0x014
+#define SRC_SIMR_OFFSET 0x018
+#define SRC_SBMR2_OFFSET 0x01c
+#define SRC_GPR1_OFFSET 0x020
+#define SRC_GPR2_OFFSET 0x024
+#define SRC_GPR3_OFFSET 0x028
+#define SRC_GPR4_OFFSET 0x02c
+#define SRC_GPR5_OFFSET 0x030
+#define SRC_GPR6_OFFSET 0x034
+#define SRC_GPR7_OFFSET 0x038
+#define SRC_GPR8_OFFSET 0x03c
+#define SRC_GPR9_OFFSET 0x040
+#define SRC_GPR10_OFFSET 0x044
+
+#define BP_SRC_SCR_CORE0_RST 13
+#define BP_SRC_SCR_CORES_DBG_RST 21
+#define BP_SRC_SCR_CORE1_ENABLE 22
+
+#endif
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
new file mode 100644
index 00000000..a195094b
--- /dev/null
+++ b/arch/arm/mach-mx6/system.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pmic_external.h>
+#include <linux/clockchips.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include <asm/hardware/gic.h>
+#include "crm_regs.h"
+#include "regs-anadig.h"
+
+#include "ntx_hwconfig.h"
+
+
+#define SCU_CTRL 0x00
+#define SCU_CONFIG 0x04
+#define SCU_CPU_STATUS 0x08
+#define SCU_INVALIDATE 0x0c
+#define SCU_FPGA_REVISION 0x10
+#define GPC_CNTR_OFFSET 0x0
+#define GPC_PGC_GPU_PGCR_OFFSET 0x260
+#define GPC_PGC_CPU_PDN_OFFSET 0x2a0
+#define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4
+#define GPC_PGC_CPU_PDNSCR_OFFSET 0x2a8
+
+#define MODULE_CLKGATE (1 << 30)
+#define MODULE_SFTRST (1 << 31)
+
+extern unsigned int gpc_wake_irq[4];
+
+static void __iomem *gpc_base = IO_ADDRESS(GPC_BASE_ADDR);
+extern struct clk *mmdc_ch0_axi;
+
+volatile unsigned int num_cpu_idle;
+volatile unsigned int num_cpu_idle_lock = 0x0;
+int wait_mode_arm_podf;
+int cur_arm_podf;
+bool enet_is_active;
+void arch_idle_with_workaround(int cpu);
+
+extern void *mx6sl_wfi_iram_base;
+extern void (*mx6sl_wfi_iram)(int arm_podf, unsigned long wfi_iram_addr, \
+ int audio_mode);
+extern void mx6_wait(void *num_cpu_idle_lock, void *num_cpu_idle, \
+ int wait_arm_podf, int cur_arm_podf);
+extern unsigned long save_ttbr1(void);
+extern void restore_ttbr1(u32 ttbr1);
+
+extern bool enable_wait_mode;
+extern int low_bus_freq_mode;
+extern int audio_bus_freq_mode;
+extern bool mem_clk_on_in_wait;
+extern int chip_rev;
+
+extern volatile NTX_HWCONFIG *gptHWCFG;
+
+void gpc_set_wakeup(unsigned int irq[4])
+{
+ /* Mask all wake up source */
+ __raw_writel(~irq[0], gpc_base + 0x8);
+ __raw_writel(~irq[1], gpc_base + 0xc);
+ __raw_writel(~irq[2], gpc_base + 0x10);
+ __raw_writel(~irq[3], gpc_base + 0x14);
+
+ return;
+}
+
+void gpc_mask_single_irq(int irq, bool enable)
+{
+ void __iomem *reg;
+ u32 val;
+
+ reg = gpc_base + 0x8 + (irq / 32 - 1) * 4;
+ val = __raw_readl(reg);
+ if (enable)
+ val |= 1 << (irq % 32);
+ else
+ val &= ~(1 << (irq % 32));
+ __raw_writel(val, reg);
+
+ return;
+}
+
+/* set cpu low power mode before WFI instruction */
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+
+ int stop_mode = 0;
+ void __iomem *anatop_base = IO_ADDRESS(ANATOP_BASE_ADDR);
+ u32 ccm_clpcr, anatop_val;
+
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ /*
+ * CCM state machine has restriction that, everytime enable
+ * LPM mode, we need to make sure last wakeup from LPM mode
+ * is a dsm_wakeup_signal, which means the wakeup source
+ * must be seen by GPC, then CCM will clean its state machine
+ * and re-sample necessary signal to decide whether it can
+ * enter LPM mode. Here we force irq #32 to be always pending,
+ * unmask it before we enable LPM mode and mask it after LPM
+ * is enabled, this flow will make sure CCM state machine in
+ * reliable state before we enter LPM mode.
+ */
+ gpc_mask_single_irq(MXC_INT_GPR, false);
+
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ case STOP_POWER_OFF:
+ case ARM_POWER_OFF:
+ if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+ ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ if (cpu_is_mx6sl()) {
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
+ } else
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ stop_mode = 0;
+ } else if (mode == STOP_POWER_OFF) {
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ if (cpu_is_mx6sl()) {
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
+ } else
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ stop_mode = 1;
+ } else {
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ if (cpu_is_mx6sl()) {
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
+ } else
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ stop_mode = 2;
+ }
+ break;
+ case STOP_XTAL_ON:
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ if (cpu_is_mx6sl()) {
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
+ ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
+ } else
+ ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
+ stop_mode = 3;
+
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ gpc_mask_single_irq(MXC_INT_GPR, true);
+ return;
+ }
+
+ if (stop_mode > 0) {
+ gpc_set_wakeup(gpc_wake_irq);
+ /* Power down and power up sequence */
+ /* The PUPSCR counter counts in terms of CLKIL (32KHz) cycles.
+ * The PUPSCR should include the time it takes for the ARM LDO to
+ * ramp up.
+ */
+ __raw_writel(0xf0f, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
+ /* The PDNSCR is a counter that counts in IPG_CLK cycles. This counter
+ * can be set to minimum values to power down faster.
+ */
+ __raw_writel(0x101, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
+ if (stop_mode >= 2) {
+ /* dormant mode, need to power off the arm core */
+ __raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
+#if 0
+ if (cpu_is_mx6q() || cpu_is_mx6dl() && (4!=gptHWCFG->m_val.bRamType) )
+#else
+ if( cpu_is_mx6q() || cpu_is_mx6dl() )
+#endif
+ {
+ /* If stop_mode_config is clear, then 2P5 will be off,
+ need to enable weak 2P5, as DDR IO need 2P5 as
+ pre-driver */
+ if ((__raw_readl(anatop_base + HW_ANADIG_ANA_MISC0)
+ & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) {
+ /* Enable weak 2P5 linear regulator */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_REG_2P5);
+ anatop_val |= BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG;
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_REG_2P5);
+ }
+ if (mx6q_revision() != IMX_CHIP_REVISION_1_0) {
+ /* Enable fet_odrive */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_REG_CORE);
+ anatop_val |= BM_ANADIG_REG_CORE_FET_ODRIVE;
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_REG_CORE);
+ }
+ } else {
+ if (stop_mode == 2) {
+#if 1
+ /* Disable VDDHIGH_IN to VDDSNVS_IN
+ * power path, only used when VDDSNVS_IN
+ * is powered by dedicated
+ * power rail */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_ANA_MISC0);
+ anatop_val |= BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN;
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_ANA_MISC0);
+#endif
+ /* Need to enable pull down if 2P5 is disabled */
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_REG_2P5);
+
+#if 1 //[
+ if ( /* <= E60Q2XA14 */
+ (33==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_REV<=0x14 ) ||
+ /* <= E60Q30BXX */
+ (36==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_LVL==1 ) ||
+ /* <= E60QBXA00 */
+ (37==gptHWCFG->m_val.bPCB && gptHWCFG->m_val.bPCB_REV<=0 ) )
+ {
+ //printk("%s<=E60Q2XA14|<=E60Q3XA00\n",__FUNCTION__);
+ /* Enable weak 2P5 linear regulator */
+ anatop_val |= BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG|
+ BM_ANADIG_REG_2P5_ENABLE_ILIMIT;
+ }
+ else
+ {
+ anatop_val |= (BM_ANADIG_REG_2P5_ENABLE_ILIMIT|
+ BM_ANADIG_REG_2P5_ENABLE_PULLDOWN);
+ }
+#endif //]
+
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_REG_2P5);
+
+ anatop_val = __raw_readl(anatop_base +
+ HW_ANADIG_REG_1P1);
+ anatop_val |= BM_ANADIG_REG_1P1_ENABLE_ILIMIT;
+ __raw_writel(anatop_val, anatop_base +
+ HW_ANADIG_REG_1P1);
+ }
+ }
+ if (stop_mode != 3) {
+ /* Make sure we clear WB_COUNT
+ * and re-config it.
+ */
+ __raw_writel(__raw_readl(MXC_CCM_CCR) &
+ (~MXC_CCM_CCR_WB_COUNT_MASK),
+ MXC_CCM_CCR);
+ /* Reconfigure WB, need to set WB counter
+ * to 0x7 to make sure it work normally */
+ __raw_writel(__raw_readl(MXC_CCM_CCR) |
+ (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET),
+ MXC_CCM_CCR);
+
+ /* Set WB_PER enable */
+ ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM;
+ }
+ }
+ if (cpu_is_mx6sl() ||
+ (mx6q_revision() > IMX_CHIP_REVISION_1_1) ||
+ (mx6dl_revision() > IMX_CHIP_REVISION_1_0)) {
+ u32 reg;
+ /* We need to allow the memories to be clock gated
+ * in STOP mode, else the power consumption will
+ * be very high.
+ */
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
+ if (!cpu_is_mx6sl() && stop_mode >= 2) {
+ /*
+ * For MX6QTO1.2 or later and MX6DLTO1.1 or later,
+ * ensure that the CCM_CGPR bit 17 is cleared before
+ * dormant mode is entered.
+ */
+ reg &= ~MXC_CCM_CGPR_WAIT_MODE_FIX;
+ }
+ __raw_writel(reg, MXC_CCM_CGPR);
+ }
+ }
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ gpc_mask_single_irq(MXC_INT_GPR, true);
+}
+
+extern int tick_broadcast_oneshot_active(void);
+
+void ca9_do_idle(void)
+{
+ do {
+ cpu_do_idle();
+ } while (__raw_readl(gic_cpu_base_addr + GIC_CPU_HIGHPRI) == 1023);
+}
+
+void arch_idle_single_core(void)
+{
+ u32 reg;
+
+ if (cpu_is_mx6dl() && chip_rev > IMX_CHIP_REVISION_1_0) {
+ /*
+ * MX6DLS TO1.1 has the HW fix for the WAIT mode issue.
+ * Ensure that the CGPR bit 17 is set to enable the fix.
+ */
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ ca9_do_idle();
+ } else {
+ if (low_bus_freq_mode || audio_bus_freq_mode) {
+ int ddr_usecount = 0;
+ if ((mmdc_ch0_axi != NULL))
+ ddr_usecount = clk_get_usecount(mmdc_ch0_axi);
+
+ if (cpu_is_mx6sl() && (ddr_usecount == 1) &&
+ (low_bus_freq_mode || audio_bus_freq_mode)) {
+ /* In this mode PLL2 i already in bypass,
+ * ARM is sourced from PLL1. The code in IRAM
+ * will set ARM to be sourced from STEP_CLK
+ * at 24MHz. It will also set DDR to 1MHz to
+ * reduce power.
+ */
+ u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR);
+ u32 ttbr1;
+
+ outer_sync();
+ /* Need to run WFI code from IRAM so that
+ * we can lower DDR freq.
+ */
+ ttbr1 = save_ttbr1();
+ mx6sl_wfi_iram(org_arm_podf,
+ (unsigned long)mx6sl_wfi_iram_base,
+ audio_bus_freq_mode);
+ restore_ttbr1(ttbr1);
+ } else {
+ /* Need to set ARM to run at 24MHz since IPG
+ * is at 12MHz. This is valid for audio mode on
+ * MX6SL, and all low power modes on MX6DLS.
+ */
+ if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ /* ARM is from PLL1, need to switch to
+ * STEP_CLK sourced from 24MHz.
+ */
+ /* Swtich STEP_CLK to 24MHz. */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_STEP_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ /* Set PLL1_SW_CLK to be from
+ *STEP_CLK.
+ */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ } else {
+ /* PLL1_SW_CLK is sourced from
+ * PLL2_PFD2_400MHz at this point.
+ * Move it to bypassed PLL1.
+ */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
+ ca9_do_idle();
+
+ if (cpu_is_mx6sl() && low_bus_freq_mode) {
+ /* Set PLL1_SW_CLK to be from PLL1 */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ } else {
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+ }
+ }
+ } else {
+ /*
+ * Implement the 12:5 ARM:IPG_CLK ratio
+ * workaround for the WAIT mode issue.
+ * We can directly use the divider to drop the ARM
+ * core freq in a single core environment.
+ * Set the ARM_PODF to get the max freq possible
+ * to avoid the WAIT mode issue when IPG is at 66MHz.
+ */
+ __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR);
+ while (__raw_readl(MXC_CCM_CDHIPR))
+ ;
+ ca9_do_idle();
+
+ __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR);
+ }
+ }
+}
+
+void arch_idle_with_workaround(int cpu)
+{
+ u32 podf = wait_mode_arm_podf;
+
+ *((char *)(&num_cpu_idle_lock) + (char)cpu) = 0x0;
+
+ if (low_bus_freq_mode || audio_bus_freq_mode)
+ /* In case when IPG is at 12MHz, we need to ensure that
+ * ARM is at 24MHz, as the max freq ARM can run at is
+ *~28.8MHz.
+ */
+ podf = 0;
+
+ mx6_wait((void *)&num_cpu_idle_lock,
+ (void *)&num_cpu_idle,
+ podf, cur_arm_podf - 1);
+
+}
+
+void arch_idle_multi_core(int cpu)
+{
+ u32 reg;
+
+ /* iMX6Q and iMX6DL */
+ if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) ||
+ (cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) {
+ /*
+ * This code should only be executed on MX6QTO1.2 or later
+ * and MX6DL TO1.1 or later.
+ * These chips have the HW fix for the WAIT mode issue.
+ * Ensure that the CGPR bit 17 is set to enable the fix.
+ */
+
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg |= MXC_CCM_CGPR_WAIT_MODE_FIX;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ ca9_do_idle();
+ } else
+ arch_idle_with_workaround(cpu);
+}
+
+void arch_idle(void)
+{
+ int cpu = smp_processor_id();
+
+ if (enable_wait_mode) {
+#ifdef CONFIG_LOCAL_TIMERS
+ if (!tick_broadcast_oneshot_active()
+ || !tick_oneshot_mode_active())
+ return;
+
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
+#endif
+ if (enet_is_active)
+ /* Don't allow the chip to enter WAIT mode if enet is active
+ * and the GPIO workaround for ENET interrupts is not used,
+ * since all ENET interrupts donot wake up the SOC.
+ */
+ mxc_cpu_lp_set(WAIT_CLOCKED);
+ else
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ if (mem_clk_on_in_wait) {
+ u32 reg;
+ /*
+ * MX6SL, MX6Q (TO1.2 or later) and
+ * MX6DL (TO1.1 or later) have a bit in
+ * CCM_CGPR that when cleared keeps the
+ * clocks to memories ON when ARM is in WFI.
+ * This mode can be used when IPG clock is
+ * very low (12MHz) and the ARM:IPG ratio
+ * perhaps cannot be maintained.
+ */
+ reg = __raw_readl(MXC_CCM_CGPR);
+ reg &= ~MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
+ __raw_writel(reg, MXC_CCM_CGPR);
+
+ ca9_do_idle();
+ } else if (num_possible_cpus() == 1)
+ /* iMX6SL or iMX6DLS */
+ arch_idle_single_core();
+ else
+ arch_idle_multi_core(cpu);
+#ifdef CONFIG_LOCAL_TIMERS
+ clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
+#endif
+ } else {
+ mxc_cpu_lp_set(WAIT_CLOCKED);
+ ca9_do_idle();
+ }
+}
+
+static int __mxs_reset_block(void __iomem *hwreg, int just_enable)
+{
+ u32 c;
+ int timeout;
+
+ /* the process of software reset of IP block is done
+ in several steps:
+
+ - clear SFTRST and wait for block is enabled;
+ - clear clock gating (CLKGATE bit);
+ - set the SFTRST again and wait for block is in reset;
+ - clear SFTRST and wait for reset completion.
+ */
+ c = __raw_readl(hwreg);
+ c &= ~MODULE_SFTRST; /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & MODULE_SFTRST) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when enabling\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~MODULE_CLKGATE; /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+
+ if (!just_enable) {
+ c = __raw_readl(hwreg);
+ c |= MODULE_SFTRST; /* now again set SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* poll until CLKGATE set */
+ if (__raw_readl(hwreg) & MODULE_CLKGATE)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when resetting\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~MODULE_SFTRST; /* clear SFTRST */
+ __raw_writel(c, hwreg);
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & MODULE_SFTRST) == 0)
+ break;
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when enabling "
+ "after reset\n", __func__, hwreg);
+ return -ETIME;
+ }
+
+ c = __raw_readl(hwreg);
+ c &= ~MODULE_CLKGATE; /* clear CLKGATE */
+ __raw_writel(c, hwreg);
+ }
+ for (timeout = 1000000; timeout > 0; timeout--)
+ /* still in SFTRST state ? */
+ if ((__raw_readl(hwreg) & MODULE_CLKGATE) == 0)
+ break;
+
+ if (timeout <= 0) {
+ printk(KERN_ERR "%s(%p): timeout when unclockgating\n",
+ __func__, hwreg);
+ return -ETIME;
+ }
+
+ return 0;
+}
+
+static int _mxs_reset_block(void __iomem *hwreg, int just_enable)
+{
+ int try = 10;
+ int r;
+
+ while (try--) {
+ r = __mxs_reset_block(hwreg, just_enable);
+ if (!r)
+ break;
+ pr_debug("%s: try %d failed\n", __func__, 10 - try);
+ }
+ return r;
+}
+
+
+#define BOOT_MODE_SERIAL_ROM (0x00000030)
+#define PERSIST_WATCHDOG_RESET_BOOT (0x10000000)
+/*BOOT_CFG1[7..4] = 0x3 Boot from Serial ROM (I2C/SPI)*/
+
+#ifdef CONFIG_MXC_REBOOT_MFGMODE
+void do_switch_mfgmode(void)
+{
+ u32 reg;
+
+ /*
+ * During reset, if GPR10[28] is 1, ROM will copy GPR9[25:0]
+ * to SBMR1, which will determine what is the boot device.
+ * Here SERIAL_ROM mode is selected
+ */
+ reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR9);
+ reg |= BOOT_MODE_SERIAL_ROM;
+ __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR9);
+
+ reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR10);
+ reg |= PERSIST_WATCHDOG_RESET_BOOT;
+ __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR10);
+
+}
+
+void mxc_clear_mfgmode(void)
+{
+ u32 reg;
+ reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR9);
+
+ reg &= ~BOOT_MODE_SERIAL_ROM;
+ __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR9);
+
+ reg = __raw_readl(SRC_BASE_ADDR + SRC_GPR10);
+ reg &= ~PERSIST_WATCHDOG_RESET_BOOT;
+ __raw_writel(reg, SRC_BASE_ADDR + SRC_GPR10);
+}
+#endif
+
+#ifdef CONFIG_MXC_REBOOT_ANDROID_CMD
+/* This function will set a bit on SNVS_LPGPR[7-8] bits to enter
+ * special boot mode. These bits will not clear by watchdog reset, so
+ * it can be checked by bootloader to choose enter different mode.*/
+
+#define ANDROID_RECOVERY_BOOT (1 << 7)
+#define ANDROID_FASTBOOT_BOOT (1 << 8)
+
+void do_switch_recovery(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);
+ reg |= ANDROID_RECOVERY_BOOT;
+ __raw_writel(reg, MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);
+}
+
+void do_switch_fastboot(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);
+ reg |= ANDROID_FASTBOOT_BOOT;
+ __raw_writel(reg, MX6Q_SNVS_BASE_ADDR + SNVS_LPGPR);
+}
+#endif
+
+int mxs_reset_block(void __iomem *hwreg)
+{
+ return _mxs_reset_block(hwreg, false);
+}
+EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/mach-mx6/usb.h b/arch/arm/mach-mx6/usb.h
new file mode 100644
index 00000000..819e45e5
--- /dev/null
+++ b/arch/arm/mach-mx6/usb.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/common.h>
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_utmi_active(void);
+extern void gpio_usbotg_utmi_inactive(void);
+extern bool usb_icbug_swfix_need(void);
+extern void __init mx6_usb_h2_init(void);
+extern void __init mx6_usb_h3_init(void);
+
+typedef void (*driver_vbus_func)(bool);
+extern void mx6_set_host3_vbus_func(driver_vbus_func);
+extern void mx6_set_host2_vbus_func(driver_vbus_func);
+extern void mx6_set_host1_vbus_func(driver_vbus_func);
+extern void mx6_set_otghost_vbus_func(driver_vbus_func);
+extern void mx6_get_otghost_vbus_func(driver_vbus_func *driver_vbus);
+extern void mx6_get_host1_vbus_func(driver_vbus_func *driver_vbus);
+extern struct platform_device anatop_thermal_device;
+extern struct platform_device mxc_usbdr_otg_device;
+extern struct platform_device mxc_usbdr_udc_device;
+extern struct platform_device mxc_usbdr_host_device;
+extern struct platform_device mxc_usbdr_wakeup_device;
+extern struct platform_device mxc_usbh1_device;
+extern struct platform_device mxc_usbh1_wakeup_device;
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+extern void __iomem *imx_otg_base;
+#define imx_fsl_usb2_wakeup_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .irq_phy = soc ## _INT_USB_PHY ## _id, \
+ .irq_core = soc ## _INT_USB_ ## hs, \
+ }
+#define imx_mxc_ehci_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _USB_ ## hs ## _BASE_ADDR, \
+ .irq = soc ## _INT_USB_ ## hs, \
+ }
+#define imx_fsl_usb2_otg_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+#define imx_fsl_usb2_udc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
new file mode 100644
index 00000000..cba9c541
--- /dev/null
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -0,0 +1,795 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include "devices-imx6q.h"
+#include "regs-anadig.h"
+#include "usb.h"
+
+DEFINE_MUTEX(otg_wakeup_enable_mutex);
+static int usbotg_init_ext(struct platform_device *pdev);
+static void usbotg_uninit_ext(struct platform_device *pdev);
+static void usbotg_clock_gate(bool on);
+static void _dr_discharge_line(bool enable);
+extern bool usb_icbug_swfix_need(void);
+static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, \
+ bool enable);
+static u32 wakeup_irq_enable_src; /* only useful at otg mode */
+static u32 low_power_enable_src; /* only useful at otg mode */
+
+/* The usb_phy1_clk do not have enable/disable function at clock.c
+ * and PLL output for usb1's phy should be always enabled.
+ * usb_phy1_clk only stands for usb uses pll3 as its parent.
+ */
+static struct clk *usb_phy1_clk;
+static struct clk *usb_oh3_clk;
+static u8 otg_used;
+
+static void usbotg_wakeup_event_clear(void);
+extern int clk_get_usecount(struct clk *clk);
+/* Beginning of Common operation for DR port */
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data dr_utmi_config = {
+ .name = "DR",
+ .init = usbotg_init_ext,
+ .exit = usbotg_uninit_ext,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .transceiver = "utmi",
+ .phy_regs = USB_PHY0_BASE_ADDR,
+ .dr_discharge_line = _dr_discharge_line,
+ .lowpower = true, /* Default driver low power is true */
+};
+
+/* Platform data for wakeup operation */
+static struct fsl_usb2_wakeup_platform_data dr_wakeup_config = {
+ .name = "DR wakeup",
+ .usb_clock_for_pm = usbotg_clock_gate,
+ .usb_wakeup_exhandle = usbotg_wakeup_event_clear,
+};
+
+static void usbotg_internal_phy_clock_gate(bool on)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ if (on) {
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_CLR);
+ } else {
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_SET);
+ }
+}
+
+static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
+{
+ u32 tmp;
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ void __iomem *phy_ctrl;
+
+ /* Stop then Reset */
+ UOG_USBCMD &= ~UCMD_RUN_STOP;
+ while (UOG_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UOG_USBCMD |= UCMD_RESET;
+ while ((UOG_USBCMD) & (UCMD_RESET))
+ ;
+
+ /*
+ * If the controller reset does not put the PHY be out of
+ * low power mode, do it manually.
+ */
+ if (UOG_PORTSC1 & PORTSC_PHCD) {
+ UOG_PORTSC1 &= ~PORTSC_PHCD;
+ mdelay(1);
+ }
+
+ /* Reset USBPHY module */
+ phy_ctrl = phy_reg + HW_USBPHY_CTRL;
+ tmp = __raw_readl(phy_ctrl);
+ tmp |= BM_USBPHY_CTRL_SFTRST;
+ __raw_writel(tmp, phy_ctrl);
+ udelay(10);
+
+ /* Remove CLKGATE and SFTRST */
+ tmp = __raw_readl(phy_ctrl);
+ tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
+ __raw_writel(tmp, phy_ctrl);
+ udelay(10);
+
+ /* Power up the PHY */
+ __raw_writel(0, phy_reg + HW_USBPHY_PWD);
+ if ((pdata->operating_mode == FSL_USB2_DR_HOST) ||
+ (pdata->operating_mode == FSL_USB2_DR_OTG)) {
+ /* enable FS/LS device */
+ __raw_writel(BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3
+ , phy_reg + HW_USBPHY_CTRL_SET);
+ }
+
+ if (!usb_icbug_swfix_need())
+ __raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
+ if (cpu_is_mx6sl())
+ __raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
+ return 0;
+}
+/* Notes: configure USB clock*/
+static int usbotg_init_ext(struct platform_device *pdev)
+{
+ struct clk *usb_clk;
+ u32 ret;
+
+ /* at mx6q: this clock is AHB clock for usb core */
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy1_clk");
+ clk_enable(usb_clk);
+ usb_phy1_clk = usb_clk;
+
+ ret = usbotg_init(pdev);
+ if (ret) {
+ clk_disable(usb_oh3_clk);
+ clk_put(usb_oh3_clk);
+ clk_disable(usb_phy1_clk);
+ clk_put(usb_phy1_clk);
+ printk(KERN_ERR "otg init fails......\n");
+ return ret;
+ }
+ if (!otg_used) {
+ wakeup_irq_enable_src = 0;
+ low_power_enable_src = 0;
+ usb_phy_enable(pdev->dev.platform_data);
+ enter_phy_lowpower_suspend(pdev->dev.platform_data, false);
+ /*after the phy reset,can not read the readingvalue for id/vbus at
+ * the register of otgsc ,cannot read at once ,need delay 3 ms
+ */
+ mdelay(3);
+ }
+ otg_used++;
+
+#if 0
+ printk("%s(%d):usb_oh3_clk:%d, usb_phy_clk1_ref_count:%d\n",
+ __FUNCTION__,__LINE__,clk_get_usecount(usb_oh3_clk),
+ clk_get_usecount(usb_phy1_clk));
+#endif
+
+ return ret;
+}
+
+static void usbotg_uninit_ext(struct platform_device *pdev)
+{
+ otg_used--;
+ if (!otg_used) {
+ //clk_disable(usb_phy1_clk);
+ clk_put(usb_phy1_clk);
+ clk_put(usb_oh3_clk);
+ }
+#if 0
+ printk("%s(%d):otg_used=%d,usb_oh3_clk:%d, usb_phy_clk1_ref_count:%d\n",
+ __FUNCTION__,__LINE__,otg_used,clk_get_usecount(usb_oh3_clk),
+ clk_get_usecount(usb_phy1_clk));
+#endif
+}
+
+static void usbotg_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_oh3_clk);
+ clk_enable(usb_phy1_clk);
+ } else {
+ clk_disable(usb_phy1_clk);
+ clk_disable(usb_oh3_clk);
+ }
+ //printk("usb_oh3_clk:%d, usb_phy_clk1_ref_count:%d\n", clk_get_usecount(usb_oh3_clk), clk_get_usecount(usb_phy1_clk));
+}
+
+static void dr_platform_phy_power_on(void)
+{
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+}
+
+static void _dr_discharge_line(bool enable)
+{
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+
+ pr_debug("DR: %s enable is %d\n", __func__, enable);
+ if (enable) {
+ __raw_writel(BM_USBPHY_DEBUG_CLKGATE, phy_reg + HW_USBPHY_DEBUG_CLR);
+ __raw_writel(BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1
+ |BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN,
+ anatop_base_addr + HW_ANADIG_USB1_LOOPBACK);
+ } else {
+ __raw_writel(0x0,
+ anatop_base_addr + HW_ANADIG_USB1_LOOPBACK);
+ __raw_writel(BM_USBPHY_DEBUG_CLKGATE, phy_reg + HW_USBPHY_DEBUG_SET);
+ }
+}
+
+/* Below two macros are used at otg mode to indicate usb mode*/
+#define ENABLED_BY_HOST (0x1 << 0)
+#define ENABLED_BY_DEVICE (0x1 << 1)
+static void enter_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ u32 tmp;
+ pr_debug("DR: %s begins, enable is %d\n", __func__, enable);
+
+ if (enable) {
+ UOG_PORTSC1 |= PORTSC_PHCD;
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+ usbotg_internal_phy_clock_gate(false);
+
+ } else {
+ if (UOG_PORTSC1 & PORTSC_PHCD)
+ UOG_PORTSC1 &= ~PORTSC_PHCD;
+
+ /* Wait PHY clock stable */
+ mdelay(1);
+
+ usbotg_internal_phy_clock_gate(true);
+
+ udelay(2);
+
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+ /*
+ * The PHY works at 32Khz clock when it is at low power mode,
+ * it needs 10 clocks from 32Khz to normal work state, so
+ * 500us is the safe value for PHY enters stable status
+ * according to IC engineer.
+ *
+ * Besides, the digital value needs 1ms debounce time to
+ * wait the value to be stable. We have expected the
+ * value from OTGSC is correct after calling this API.
+ *
+ * So delay 2ms is a save value.
+ */
+ mdelay(2);
+
+ }
+ pr_debug("DR: %s ends, enable is %d\n", __func__, enable);
+}
+
+static void __phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable, int source)
+{
+ if (enable) {
+ low_power_enable_src |= source;
+#ifdef CONFIG_USB_OTG
+ if (low_power_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) {
+ pr_debug("phy lowpower enabled\n");
+ enter_phy_lowpower_suspend(pdata, enable);
+ }
+#else
+ enter_phy_lowpower_suspend(pdata, enable);
+#endif
+ } else {
+ pr_debug("phy lowpower disable\n");
+ enter_phy_lowpower_suspend(pdata, enable);
+ low_power_enable_src &= ~source;
+ }
+}
+
+static void otg_wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+
+ pr_debug("%s, enable is %d\n", __func__, enable);
+ if (enable) {
+ __raw_writel(BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_SET);
+ USB_OTG_CTRL |= UCTRL_OWIE;
+ } else {
+ __raw_writel(BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_CLR);
+ USB_OTG_CTRL &= ~UCTRL_OWIE;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void __wakeup_irq_enable(struct fsl_usb2_platform_data *pdata, bool on, int source)
+ {
+ /* otg host and device share the OWIE bit, only when host and device
+ * all enable the wakeup irq, we can enable the OWIE bit
+ */
+ if (on) {
+#ifdef CONFIG_USB_OTG
+ wakeup_irq_enable_src |= source;
+ if (wakeup_irq_enable_src == (ENABLED_BY_HOST | ENABLED_BY_DEVICE)) {
+ otg_wake_up_enable(pdata, on);
+ }
+#else
+ otg_wake_up_enable(pdata, on);
+#endif
+ } else {
+ otg_wake_up_enable(pdata, on);
+ wakeup_irq_enable_src &= ~source;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+/* The wakeup operation for DR port, it will clear the wakeup irq status
+ * and re-enable the wakeup
+ */
+static void usbotg_wakeup_event_clear(void)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ int wakeup_req = USB_OTG_CTRL & UCTRL_OWIR;
+
+ printk(KERN_INFO "\n %s: wakeup_req=%d, USB_OTG_CTRL=%08x, UOG_OTGSC=%08x, UOG_USBSTS=%08x, UOG_PORTSC1=%08x, USBPHY_CTRL=%08x\n",
+ __func__, wakeup_req?1:0, USB_OTG_CTRL, UOG_OTGSC, UOG_USBSTS, UOG_PORTSC1, __raw_readl(phy_reg + HW_USBPHY_CTRL));
+
+ if (wakeup_req != 0) {
+ printk(KERN_INFO "Unknown wakeup.(OTGSC 0x%x)\n", UOG_OTGSC);
+ /* Disable OWIE to clear OWIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ __raw_writel(BM_USBPHY_CTRL_ENDPDMCHG_WKUP, phy_reg + HW_USBPHY_CTRL_CLR);
+ UOG_OTGSC |= 0x007f0000;
+
+ USB_OTG_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ __raw_writel(BM_USBPHY_CTRL_ENDPDMCHG_WKUP, phy_reg + HW_USBPHY_CTRL_SET);
+ USB_OTG_CTRL |= UCTRL_OWIE;
+ }
+ else {
+ /* spurious USB wakeup but WIR does not set, let's software use the
+ * bit UCTRL_WKUP_SW as an indication of software OWIR
+ */
+ USB_OTG_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USB_OTG_CTRL |= UCTRL_OWIE;
+ USB_OTG_CTRL |= UCTRL_WKUP_SW;
+ }
+}
+
+/* End of Common operation for DR port */
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+/* Beginning of host related operation for DR port */
+static void fsl_platform_otg_set_usb_phy_dis(
+ struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ u32 usb_phy_ctrl_dcdt = 0;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0) {
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET);
+
+ udelay(300);
+
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+
+ UOG_USBSTS |= (1 << 7);
+
+ while ((UOG_USBSTS & (1 << 7)) == 0)
+ ;
+
+ udelay(2);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR);
+
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+
+ }
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
+}
+
+static void _host_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ u32 tmp;
+ u32 index = 0;
+
+ /* before we set and then clear PWD bit,
+ * we must wait LS to be suspend */
+ if ((UOG_PORTSC1 & (3 << 26)) != (1 << 26)) {
+ while (((UOG_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_J_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ } else {
+ while (((UOG_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_K_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
+
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ fsl_platform_otg_set_usb_phy_dis(pdata, 0);
+}
+
+static void _host_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
+{
+ u32 index = 0;
+
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
+ fsl_platform_otg_set_usb_phy_dis(pdata, 1);
+}
+static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+}
+
+static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+{
+ u32 index = 0;
+
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ if ((UOG_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+}
+
+static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __phy_lowpower_suspend(pdata, enable, ENABLED_BY_HOST);
+}
+
+static void _host_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ void __iomem *phy_reg __maybe_unused = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ mutex_lock(&otg_wakeup_enable_mutex);
+ __wakeup_irq_enable(pdata, enable, ENABLED_BY_HOST);
+#ifdef CONFIG_USB_OTG
+ if (enable) {
+ pr_debug("host wakeup enable\n");
+ USB_OTG_CTRL |= UCTRL_WKUP_ID_EN;
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP, phy_reg + HW_USBPHY_CTRL_SET);
+ } else {
+ pr_debug("host wakeup disable\n");
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP, phy_reg + HW_USBPHY_CTRL_CLR);
+ USB_OTG_CTRL &= ~UCTRL_WKUP_ID_EN;
+ /* The interrupt must be disabled for at least 3 clock
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+ pr_debug("the otgsc is 0x%x, usbsts is 0x%x, portsc is 0x%x, otgctrl: 0x%x\n", UOG_OTGSC, UOG_USBSTS, UOG_PORTSC1, USB_OTG_CTRL);
+#endif
+ mutex_unlock(&otg_wakeup_enable_mutex);
+}
+
+static enum usb_wakeup_event _is_host_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USB_OTG_CTRL & UCTRL_OWIR;
+ u32 otgsc = UOG_OTGSC;
+
+ if (wakeup_req) {
+ pr_debug("the otgsc is 0x%x, usbsts is 0x%x, portsc is 0x%x, wakeup_irq is 0x%x\n", UOG_OTGSC, UOG_USBSTS, UOG_PORTSC1, wakeup_req);
+ }
+ else {
+ // no hardware OWIR, let check if there is software OWIR
+ if (USB_OTG_CTRL & UCTRL_WKUP_SW) {
+ wakeup_req = UCTRL_WKUP_SW;
+ }
+ }
+ /* if ID change sts, it is a host wakeup event */
+ if (otgsc & OTGSC_IS_USB_ID) {
+ pr_debug("otg host ID wakeup\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_ID;
+ }
+ if (wakeup_req && (!(otgsc & OTGSC_STS_USB_ID))) {
+ pr_debug("otg host Remote wakeup\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_DPDM;
+ }
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _host_phy_lowpower_suspend(pdata, false);
+ _host_wakeup_enable(pdata, false);
+}
+/* End of host related operation for DR port */
+#endif /* CONFIG_USB_EHCI_ARC_OTG */
+
+
+#ifdef CONFIG_USB_GADGET_ARC
+/* Beginning of device related operation for DR port */
+static void _device_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ __phy_lowpower_suspend(pdata, enable, ENABLED_BY_DEVICE);
+}
+
+static void _device_wakeup_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ mutex_lock(&otg_wakeup_enable_mutex);
+ __wakeup_irq_enable(pdata, enable, ENABLED_BY_DEVICE);
+ /* if udc is not used by any gadget, we can not enable the vbus wakeup */
+ if (!pdata->port_enables) {
+ USB_OTG_CTRL &= ~UCTRL_WKUP_VBUS_EN;
+ mutex_unlock(&otg_wakeup_enable_mutex);
+ return;
+ }
+ if (enable) {
+ pr_debug("device wakeup enable\n");
+ USB_OTG_CTRL |= UCTRL_WKUP_VBUS_EN;
+ __raw_writel(BM_USBPHY_CTRL_ENVBUSCHG_WKUP, phy_reg + HW_USBPHY_CTRL_SET);
+ } else {
+ pr_debug("device wakeup disable\n");
+ __raw_writel(BM_USBPHY_CTRL_ENVBUSCHG_WKUP, phy_reg + HW_USBPHY_CTRL_CLR);
+ USB_OTG_CTRL &= ~UCTRL_WKUP_VBUS_EN;
+ }
+ mutex_unlock(&otg_wakeup_enable_mutex);
+}
+
+static enum usb_wakeup_event _is_device_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ int wakeup_req = (USB_OTG_CTRL & UCTRL_OWIR);
+ pr_debug("%s\n", __func__);
+
+ if (!wakeup_req) {
+ // no hardware OWIR, let check if there is software OWIR
+ if (USB_OTG_CTRL & UCTRL_WKUP_SW) {
+ wakeup_req = UCTRL_WKUP_SW;
+ }
+ }
+
+ /* if ID=1, it is a device wakeup event */
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && (UOG_USBSTS & USBSTS_URI)) {
+ printk(KERN_INFO "otg udc wakeup, host sends reset signal\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_DPDM;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && \
+ ((UOG_USBSTS & USBSTS_PCI) || (UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME))) {
+ /*
+ * When the line state from J to K, the Port Change Detect bit
+ * in the USBSTS register is also set to '1'.
+ */
+ printk(KERN_INFO "otg udc wakeup, host sends resume signal\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_DPDM;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && (UOG_OTGSC & OTGSC_STS_A_VBUS_VALID) /*\
+ && (UOG_OTGSC & OTGSC_IS_B_SESSION_VALID)*/) {
+ printk(KERN_INFO "otg udc vbus rising wakeup\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_VBUS;
+ }
+ if (wakeup_req && (UOG_OTGSC & OTGSC_STS_USB_ID) && !(UOG_OTGSC & OTGSC_STS_A_VBUS_VALID)) {
+ printk(KERN_INFO "otg udc vbus falling wakeup\n");
+ USB_OTG_CTRL &= (~UCTRL_WKUP_SW);
+ return WAKEUP_EVENT_VBUS;
+ }
+
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void device_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _device_phy_lowpower_suspend(pdata, false);
+ _device_wakeup_enable(pdata, false);
+}
+
+/* end of device related operation for DR port */
+#endif /* CONFIG_USB_GADGET_ARC */
+
+static struct platform_device *pdev[3], *pdev_wakeup;
+static driver_vbus_func mx6_set_usb_otg_vbus;
+static int devnum;
+static int __init mx6_usb_dr_init(void)
+{
+ int i = 0;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ struct imx_fsl_usb2_wakeup_data __maybe_unused imx6q_fsl_otg_wakeup_data =
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 0, OTG);
+ struct imx_mxc_ehci_data __maybe_unused imx6q_mxc_ehci_otg_data =
+ imx_mxc_ehci_data_entry_single(MX6Q, 0, OTG);
+ struct imx_fsl_usb2_udc_data __maybe_unused imx6q_fsl_usb2_udc_data =
+ imx_fsl_usb2_udc_data_entry_single(MX6Q);
+ struct imx_fsl_usb2_otg_data __maybe_unused imx6q_fsl_usb2_otg_data =
+ imx_fsl_usb2_otg_data_entry_single(MX6Q);
+
+ /* Some phy and power's special controls for otg
+ * 1. The external charger detector needs to be disabled
+ * or the signal at DP will be poor
+ * 2. The EN_USB_CLKS is always enabled.
+ * The PLL's power is controlled by usb and others who
+ * use pll3 too.
+ */
+ __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B \
+ | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, \
+ anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT);
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+ mx6_get_otghost_vbus_func(&mx6_set_usb_otg_vbus);
+ dr_utmi_config.platform_driver_vbus = mx6_set_usb_otg_vbus;
+#ifdef CONFIG_USB_OTG
+ /* wake_up_enable is useless, just for usb_register_remote_wakeup execution*/
+ dr_utmi_config.wake_up_enable = _device_wakeup_enable;
+ dr_utmi_config.operating_mode = FSL_USB2_DR_OTG;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ pdev[i] = imx6q_add_fsl_usb2_otg(&dr_utmi_config);
+ dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data;
+ i++;
+#endif
+#ifdef CONFIG_USB_GADGET_ARC
+ dr_utmi_config.operating_mode = DR_UDC_MODE;
+ dr_utmi_config.wake_up_enable = _device_wakeup_enable;
+ dr_utmi_config.platform_rh_suspend = NULL;
+ dr_utmi_config.platform_rh_resume = NULL;
+ dr_utmi_config.platform_set_disconnect_det = NULL;
+ dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_device_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = device_wakeup_handler;
+ dr_utmi_config.charger_base_addr = anatop_base_addr;
+ dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on;
+ pdev[i] = imx6q_add_fsl_usb2_udc(&dr_utmi_config);
+ dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data;
+ i++;
+#endif
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+ dr_utmi_config.operating_mode = DR_HOST_MODE;
+ dr_utmi_config.wake_up_enable = _host_wakeup_enable;
+ if (usb_icbug_swfix_need()) {
+ dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend_swfix;
+ dr_utmi_config.platform_rh_resume = _host_platform_rh_resume_swfix;
+ } else {
+ dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend;
+ dr_utmi_config.platform_rh_resume = _host_platform_rh_resume;
+ }
+ dr_utmi_config.platform_set_disconnect_det = fsl_platform_otg_set_usb_phy_dis;
+ dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
+ dr_utmi_config.is_wakeup_event = _is_host_wakeup;
+ dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
+ dr_utmi_config.wakeup_handler = host_wakeup_handler;
+ dr_utmi_config.platform_phy_power_on = dr_platform_phy_power_on;
+ pdev[i] = imx6q_add_fsl_ehci_otg(&dr_utmi_config);
+ dr_wakeup_config.usb_pdata[i] = pdev[i]->dev.platform_data;
+ i++;
+#endif
+ devnum = i;
+ /* register wakeup device */
+ pdev_wakeup = imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config);
+ for (i = 0; i < devnum; i++) {
+ platform_device_add(pdev[i]);
+ ((struct fsl_usb2_platform_data *)(pdev[i]->dev.platform_data))->wakeup_pdata =
+ (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
+ }
+ return 0;
+}
+module_init(mx6_usb_dr_init);
+
+static void __exit mx6_usb_dr_exit(void)
+{
+ int i;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+
+ for (i = 0; i < devnum; i++)
+ platform_device_del(pdev[devnum-i-1]);
+ platform_device_unregister(pdev_wakeup);
+ otg_used = 0;
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR);
+ return ;
+}
+module_exit(mx6_usb_dr_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-mx6/usb_h1.c b/arch/arm/mach-mx6/usb_h1.c
new file mode 100644
index 00000000..cfbced8f
--- /dev/null
+++ b/arch/arm/mach-mx6/usb_h1.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include "devices-imx6q.h"
+#include "regs-anadig.h"
+#include "usb.h"
+
+static struct clk *usb_oh3_clk;
+extern int clk_get_usecount(struct clk *clk);
+static struct fsl_usb2_platform_data usbh1_config;
+
+static void fsl_platform_h1_set_usb_phy_dis(
+ struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ u32 usb_phy_ctrl_dcdt = 0;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0) {
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET);
+
+ udelay(300);
+
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+
+ UH1_USBSTS |= (1 << 7);
+
+ while ((UH1_USBSTS & (1 << 7)) == 0)
+ ;
+
+ udelay(2);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR);
+
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
+
+ }
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
+}
+
+static void usbh1_internal_phy_clock_gate(bool on)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
+ if (on) {
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_CLR);
+ } else {
+ __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_SET);
+ }
+}
+
+static void usbh1_platform_phy_power_on(void)
+{
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG,
+ anatop_base_addr + HW_ANADIG_ANA_MISC0_SET);
+}
+
+static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
+{
+ u32 tmp;
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
+ void __iomem *phy_ctrl;
+
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while ((UH1_USBCMD) & (UCMD_RESET))
+ ;
+ /*
+ * If the controller reset does not put the PHY be out of
+ * low power mode, do it manually.
+ */
+ if (UH1_PORTSC1 & PORTSC_PHCD) {
+ UH1_PORTSC1 &= ~PORTSC_PHCD;
+ mdelay(1);
+ }
+
+ /* Reset USBPHY module */
+ phy_ctrl = phy_reg + HW_USBPHY_CTRL;
+ tmp = __raw_readl(phy_ctrl);
+ tmp |= BM_USBPHY_CTRL_SFTRST;
+ __raw_writel(tmp, phy_ctrl);
+ udelay(10);
+
+ /* Remove CLKGATE and SFTRST */
+ tmp = __raw_readl(phy_ctrl);
+ tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
+ __raw_writel(tmp, phy_ctrl);
+ udelay(10);
+
+ /* Power up the PHY */
+ __raw_writel(0, phy_reg + HW_USBPHY_PWD);
+ /* enable FS/LS device */
+ tmp = __raw_readl(phy_reg + HW_USBPHY_CTRL);
+ tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_CTRL);
+
+ if (!usb_icbug_swfix_need())
+ __raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
+ if (cpu_is_mx6sl())
+ __raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
+ return 0;
+}
+static int fsl_usb_host_init_ext(struct platform_device *pdev)
+{
+ int ret;
+ struct clk *usb_clk;
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ ret = fsl_usb_host_init(pdev);
+ if (ret) {
+ printk(KERN_ERR "host1 init fails......\n");
+ clk_disable(usb_oh3_clk);
+ clk_put(usb_oh3_clk);
+ return ret;
+ }
+ usbh1_internal_phy_clock_gate(true);
+ usb_phy_enable(pdev->dev.platform_data);
+
+ return 0;
+}
+
+static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ fsl_usb_host_uninit(pdata);
+
+ clk_put(usb_oh3_clk);
+
+}
+
+static void usbh1_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_oh3_clk);
+ } else {
+ clk_disable(usb_oh3_clk);
+ }
+}
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
+
+ pr_debug("host1, %s, enable is %d\n", __func__, enable);
+ if (enable) {
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
+ | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_SET);
+ USB_H1_CTRL |= (UCTRL_OWIE);
+ } else {
+ __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP
+ | BM_USBPHY_CTRL_ENDPDMCHG_WKUP
+ | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS
+ | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD
+ | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE
+ | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE
+ | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_CLR);
+ USB_H1_CTRL &= ~(UCTRL_OWIE);
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void usbh1_platform_rh_suspend_swfix(struct fsl_usb2_platform_data *pdata)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
+ u32 tmp;
+ u32 index = 0;
+
+ /* before we set and then clear PWD bit,
+ * we must wait LS to be J */
+ if ((UH1_PORTSC1 & (3 << 26)) != (1 << 26)) {
+ while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_J_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ } else {
+ while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_K_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
+
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ fsl_platform_h1_set_usb_phy_dis(pdata, 0);
+}
+
+static void usbh1_platform_rh_resume_swfix(struct fsl_usb2_platform_data *pdata)
+{
+ u32 index = 0;
+
+ if ((UH1_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
+ fsl_platform_h1_set_usb_phy_dis(pdata, 1);
+}
+
+static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
+{
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+}
+
+static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
+{
+ u32 index = 0;
+
+ /*for mx6sl ,we do not need any sw fix*/
+ if (cpu_is_mx6sl())
+ return ;
+ if ((UH1_PORTSC1 & (PORTSC_PORT_SPEED_MASK)) != PORTSC_PORT_SPEED_HIGH)
+ return ;
+ while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ udelay(500);
+ index++;
+ }
+ if (index >= 1000)
+ printk(KERN_ERR "failed to wait for the resume finished in %s() line:%d\n",
+ __func__, __LINE__);
+ /* We should add some delay to wait for the device switch to
+ * High-Speed 45ohm termination resistors mode. */
+ udelay(500);
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+}
+
+static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ u32 tmp;
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
+ pr_debug("host1, %s, enable is %d\n", __func__, enable);
+ if (enable) {
+ UH1_PORTSC1 |= PORTSC_PHCD;
+
+ pr_debug("%s, Poweroff UTMI \n", __func__);
+
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+
+ usbh1_internal_phy_clock_gate(false);
+ } else {
+ if (UH1_PORTSC1 & PORTSC_PHCD)
+ UH1_PORTSC1 &= ~PORTSC_PHCD;
+
+ /* Wait PHY clock stable */
+ mdelay(1);
+
+ usbh1_internal_phy_clock_gate(true);
+
+ udelay(2);
+
+ tmp = (BM_USBPHY_PWD_TXPWDFS
+ | BM_USBPHY_PWD_TXPWDIBIAS
+ | BM_USBPHY_PWD_TXPWDV2I
+ | BM_USBPHY_PWD_RXPWDENV
+ | BM_USBPHY_PWD_RXPWD1PT1
+ | BM_USBPHY_PWD_RXPWDDIFF
+ | BM_USBPHY_PWD_RXPWDRX);
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+ /*
+ * The PHY works at 32Khz clock when it is at low power mode,
+ * it needs 10 clocks from 32Khz to normal work state, so
+ * 500us is the safe value for PHY enters stable status
+ * according to IC engineer.
+ */
+ udelay(500);
+ }
+}
+
+static enum usb_wakeup_event _is_usbh1_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USB_H1_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req)
+ return WAKEUP_EVENT_DPDM;
+ pr_err("host1, %s, invalid wake up\n", __func__);
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void h1_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _wake_up_enable(pdata, false);
+ _phy_lowpower_suspend(pdata, false);
+}
+
+static void usbh1_wakeup_event_clear(void)
+{
+ int wakeup_req = USB_H1_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req != 0) {
+ printk(KERN_INFO "Unknown wakeup.(H1 OTGSC 0x%x)\n", UH1_OTGSC);
+ /* Disable OWIE to clear OWIR, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USB_H1_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USB_H1_CTRL |= UCTRL_OWIE;
+ }
+}
+
+static struct fsl_usb2_platform_data usbh1_config = {
+ .name = "Host 1",
+ .init = fsl_usb_host_init_ext,
+ .exit = fsl_usb_host_uninit_ext,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = usbh1_clock_gate,
+ .platform_set_disconnect_det = fsl_platform_h1_set_usb_phy_dis,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
+ .is_wakeup_event = _is_usbh1_wakeup,
+ .wakeup_handler = h1_wakeup_handler,
+ .platform_phy_power_on = usbh1_platform_phy_power_on,
+ .transceiver = "utmi",
+ .phy_regs = USB_PHY1_BASE_ADDR,
+};
+static struct fsl_usb2_wakeup_platform_data usbh1_wakeup_config = {
+ .name = "USBH1 wakeup",
+ .usb_clock_for_pm = usbh1_clock_gate,
+ .usb_pdata = {&usbh1_config, NULL, NULL},
+ .usb_wakeup_exhandle = usbh1_wakeup_event_clear,
+};
+
+static struct platform_device *pdev, *pdev_wakeup;
+static driver_vbus_func mx6_set_usb_host1_vbus;
+
+static int __init mx6_usb_h1_init(void)
+{
+ static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)};
+ struct imx_fsl_usb2_wakeup_data imx6sl_fsl_hs_wakeup_data[] = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)};
+ struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = {
+ imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)};
+ struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = {
+ imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)};
+
+ mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus);
+ if (mx6_set_usb_host1_vbus)
+ mx6_set_usb_host1_vbus(true);
+
+ /* Some phy and power's special controls for host1
+ * 1. The external charger detector needs to be disabled
+ * or the signal at DP will be poor
+ * 2. The PLL's power and output to usb for host 1
+ * is totally controlled by IC, so the Software only needs
+ * to enable them at initializtion.
+ */
+ __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B \
+ | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
+ anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \
+ | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
+ | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
+
+ usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
+ if (usb_icbug_swfix_need()) {
+ usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend_swfix;
+ usbh1_config.platform_rh_resume = usbh1_platform_rh_resume_swfix;
+ } else {
+ usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend;
+ usbh1_config.platform_rh_resume = usbh1_platform_rh_resume;
+ }
+ if (cpu_is_mx6sl())
+ pdev = imx6sl_add_fsl_ehci_hs(1, &usbh1_config);
+ else
+ pdev = imx6q_add_fsl_ehci_hs(1, &usbh1_config);
+ usbh1_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
+ if (cpu_is_mx6sl())
+ pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
+ else
+ pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
+ platform_device_add(pdev);
+ ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
+ (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
+ return 0;
+}
+module_init(mx6_usb_h1_init);
+
+static void __exit mx6_usb_h1_exit(void)
+{
+ static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+
+ platform_device_unregister(pdev);
+ platform_device_unregister(pdev_wakeup);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE \
+ | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
+ | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+ if (mx6_set_usb_host1_vbus)
+ mx6_set_usb_host1_vbus(false);
+
+ return ;
+}
+module_exit(mx6_usb_h1_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx6/usb_h2.c b/arch/arm/mach-mx6/usb_h2.c
new file mode 100644
index 00000000..2577abd4
--- /dev/null
+++ b/arch/arm/mach-mx6/usb_h2.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * High Speed Inter Chip code for i.MX6, this file is for HSIC port 1
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/iomux-mx6dl.h>
+#include <mach/iomux-mx6sl.h>
+#include "devices-imx6q.h"
+#include "regs-anadig.h"
+#include "usb.h"
+
+static struct clk *usb_oh3_clk;
+static struct clk *usb_phy3_clk;
+
+extern int clk_get_usecount(struct clk *clk);
+static struct fsl_usb2_platform_data usbh2_config;
+
+static void usbh2_internal_phy_clock_gate(bool on)
+{
+ if (on) {
+ /* must turn on the 480M clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ USB_H2_CTRL |= UCTRL_UTMI_ON_CLOCK;
+ USB_UH2_HSIC_CTRL |= HSIC_CLK_ON;
+ } else {
+ USB_UH2_HSIC_CTRL &= ~HSIC_CLK_ON;
+ /* can't turn off this clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ /*USB_H2_CTRL &= ~UCTRL_UTMI_ON_CLOCK*/;
+ }
+}
+
+static int fsl_usb_host_init_ext(struct platform_device *pdev)
+{
+ int ret;
+ struct clk *usb_clk;
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy3_clk");
+ clk_enable(usb_clk);
+ usb_phy3_clk = usb_clk;
+
+ ret = fsl_usb_host_init(pdev);
+ if (ret) {
+ printk(KERN_ERR "host1 init fails......\n");
+ return ret;
+ }
+ usbh2_internal_phy_clock_gate(true);
+ /* Host2 HSIC enable */
+ USB_UH2_HSIC_CTRL |= HSIC_EN;
+
+ return 0;
+}
+
+static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ fsl_usb_host_uninit(pdata);
+
+ clk_put(usb_phy3_clk);
+
+ clk_put(usb_oh3_clk);
+
+}
+
+static void usbh2_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_oh3_clk);
+ clk_enable(usb_phy3_clk);
+ usbh2_internal_phy_clock_gate(true);
+ } else {
+ usbh2_internal_phy_clock_gate(false);
+ clk_disable(usb_phy3_clk);
+ clk_disable(usb_oh3_clk);
+ }
+}
+
+void mx6_set_host2_vbus_func(driver_vbus_func driver_vbus)
+{
+ usbh2_config.platform_driver_vbus = driver_vbus;
+}
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host2, %s, enable is %d\n", __func__, enable);
+ /* for HSIC, no disconnect nor connect
+ * we need to disable the WKDS, WKCN */
+ UH2_PORTSC1 &= ~(PORTSC_WKDC | PORTSC_WKCN);
+
+ if (enable) {
+ USB_H2_CTRL |= (UCTRL_OWIE);
+ } else {
+ USB_H2_CTRL &= ~(UCTRL_OWIE);
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host2, %s, enable is %d\n", __func__, enable);
+ if (enable)
+ UH2_PORTSC1 |= PORTSC_PHCD;
+ else
+ UH2_PORTSC1 &= ~PORTSC_PHCD;
+
+}
+
+static enum usb_wakeup_event _is_usbh2_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USB_H2_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req)
+ return WAKEUP_EVENT_DPDM;
+ pr_err("host2, %s, invalid wake up\n", __func__);
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void h2_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _wake_up_enable(pdata, false);
+ _phy_lowpower_suspend(pdata, false);
+}
+
+static void usbh2_wakeup_event_clear(void)
+{
+ u32 wakeup_req = USB_H2_CTRL & UCTRL_OWIR;
+ pr_debug("%s\n", __func__);
+
+ if (wakeup_req != 0) {
+ /* Disable H2 wakeup enable to clear H2 wakeup request, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USB_H2_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USB_H2_CTRL |= UCTRL_OWIE;
+ }
+}
+
+static void hsic_start(void)
+{
+ pr_debug("%s\n", __func__);
+ /* strobe 47K pull up */
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_pad(
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_pad(
+ MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START);
+ else if (cpu_is_mx6sl())
+ mxc_iomux_v3_setup_pad(
+ MX6SL_PAD_HSIC_STROBE__USB_H_STROBE_START);
+}
+
+static void hsic_device_connected(void)
+{
+ pr_debug("%s\n", __func__);
+ if (!(USB_UH2_HSIC_CTRL & HSIC_DEV_CONN))
+ USB_UH2_HSIC_CTRL |= HSIC_DEV_CONN;
+}
+
+static struct fsl_usb2_platform_data usbh2_config = {
+ .name = "Host 2",
+ .init = fsl_usb_host_init_ext,
+ .exit = fsl_usb_host_uninit_ext,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_HSIC,
+ .power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = usbh2_clock_gate,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
+ .is_wakeup_event = _is_usbh2_wakeup,
+ .wakeup_handler = h2_wakeup_handler,
+ .transceiver = "hsic_xcvr",
+ .hsic_post_ops = hsic_start,
+ .hsic_device_connected = hsic_device_connected,
+};
+
+static struct fsl_usb2_wakeup_platform_data usbh2_wakeup_config = {
+ .name = "usbh2 wakeup",
+ .usb_clock_for_pm = usbh2_clock_gate,
+ .usb_pdata = {&usbh2_config, NULL, NULL},
+ .usb_wakeup_exhandle = usbh2_wakeup_event_clear,
+};
+
+void __init mx6_usb_h2_init(void)
+{
+ struct platform_device *pdev, *pdev_wakeup;
+ static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usbh2_config.wakeup_pdata = &usbh2_wakeup_config;
+ if (cpu_is_mx6sl())
+ pdev = imx6sl_add_fsl_ehci_hs(2, &usbh2_config);
+ else
+ pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config);
+
+ usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
+ if (cpu_is_mx6sl())
+ pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
+ else
+ pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config);
+ platform_device_add(pdev);
+ ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
+ pdev_wakeup->dev.platform_data;
+ /* Some phy and power's special controls for host2
+ * 1. Its 480M is from OTG's 480M
+ * 2. EN_USB_CLKS should always be opened
+ */
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+ /* must change the clkgate delay to 2 or 3 to avoid
+ * 24M OSCI clock not stable issue */
+ __raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3),
+ anatop_base_addr + HW_ANADIG_ANA_MISC0);
+}
diff --git a/arch/arm/mach-mx6/usb_h3.c b/arch/arm/mach-mx6/usb_h3.c
new file mode 100644
index 00000000..a057269c
--- /dev/null
+++ b/arch/arm/mach-mx6/usb_h3.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * High Speed Inter Chip code for i.MX6, this file is for HSIC port 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/iomux-mx6dl.h>
+#include "devices-imx6q.h"
+#include "regs-anadig.h"
+#include "usb.h"
+
+static struct clk *usb_oh3_clk;
+static struct clk *usb_phy4_clk;
+
+extern int clk_get_usecount(struct clk *clk);
+static struct fsl_usb2_platform_data usbh3_config;
+
+static void usbh3_internal_phy_clock_gate(bool on)
+{
+ if (on) {
+ /* must turn on the 480M clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ USB_H3_CTRL |= UCTRL_UTMI_ON_CLOCK;
+ USB_UH3_HSIC_CTRL |= HSIC_CLK_ON;
+ } else {
+ USB_UH3_HSIC_CTRL &= ~HSIC_CLK_ON;
+ /* can't turn off this clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ /*USB_H3_CTRL &= ~UCTRL_UTMI_ON_CLOCK;*/
+ }
+}
+
+static int fsl_usb_host_init_ext(struct platform_device *pdev)
+{
+ int ret;
+ struct clk *usb_clk;
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ usb_oh3_clk = usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy4_clk");
+ clk_enable(usb_clk);
+ usb_phy4_clk = usb_clk;
+
+ ret = fsl_usb_host_init(pdev);
+ if (ret) {
+ printk(KERN_ERR "host1 init fails......\n");
+ return ret;
+ }
+ usbh3_internal_phy_clock_gate(true);
+
+ /* Host3 HSIC enable */
+ USB_UH3_HSIC_CTRL |= HSIC_EN;
+
+ return 0;
+}
+
+static void fsl_usb_host_uninit_ext(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+
+ fsl_usb_host_uninit(pdata);
+
+ clk_put(usb_phy4_clk);
+
+ clk_put(usb_oh3_clk);
+
+}
+
+static void usbh3_clock_gate(bool on)
+{
+ pr_debug("%s: on is %d\n", __func__, on);
+ if (on) {
+ clk_enable(usb_oh3_clk);
+ clk_enable(usb_phy4_clk);
+ usbh3_internal_phy_clock_gate(true);
+ } else {
+ usbh3_internal_phy_clock_gate(false);
+ clk_disable(usb_phy4_clk);
+ clk_disable(usb_oh3_clk);
+ }
+}
+
+void mx6_set_host3_vbus_func(driver_vbus_func driver_vbus)
+{
+ usbh3_config.platform_driver_vbus = driver_vbus;
+}
+
+static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host3, %s, enable is %d\n", __func__, enable);
+ /* for HSIC, no disconnect nor connect
+ * we need to disable the WKDS, WKCN */
+ UH3_PORTSC1 &= ~(PORTSC_WKDC | PORTSC_WKCN);
+
+ if (enable) {
+ USB_H3_CTRL |= (UCTRL_OWIE);
+ } else {
+ USB_H3_CTRL &= ~(UCTRL_OWIE);
+ /* The interrupt must be disabled for at least 3
+ * cycles of the standby clock(32k Hz) , that is 0.094 ms*/
+ udelay(100);
+ }
+}
+
+static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ pr_debug("host3, %s, enable is %d\n", __func__, enable);
+ if (enable)
+ UH3_PORTSC1 |= PORTSC_PHCD;
+ else
+ UH3_PORTSC1 &= ~PORTSC_PHCD;
+
+}
+
+static enum usb_wakeup_event _is_usbh3_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ u32 wakeup_req = USB_H3_CTRL & UCTRL_OWIR;
+
+ if (wakeup_req)
+ return WAKEUP_EVENT_DPDM;
+ pr_err("host3, %s, invalid wake up\n", __func__);
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void usbh3_wakeup_handler(struct fsl_usb2_platform_data *pdata)
+{
+ _wake_up_enable(pdata, false);
+ _phy_lowpower_suspend(pdata, false);
+}
+
+static void usbh3_wakeup_event_clear(void)
+{
+ u32 wakeup_req = USB_H3_CTRL & UCTRL_OWIR;
+ pr_debug("%s\n", __func__);
+
+ if (wakeup_req != 0) {
+ /* Disable H3 wakeup enable to clear H3 wakeup request, wait 3 clock
+ * cycles of standly clock(32KHz)
+ */
+ USB_H3_CTRL &= ~UCTRL_OWIE;
+ udelay(100);
+ USB_H3_CTRL |= UCTRL_OWIE;
+ }
+}
+
+static void hsic_start(void)
+{
+ pr_debug("%s", __func__);
+ /* strobe 47K pull up */
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_pad(
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_pad(
+ MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
+}
+
+static void hsic_device_connected(void)
+{
+ pr_debug("%s\n", __func__);
+ if (!(USB_UH3_HSIC_CTRL & HSIC_DEV_CONN))
+ USB_UH3_HSIC_CTRL |= HSIC_DEV_CONN;
+}
+
+static struct fsl_usb2_platform_data usbh3_config = {
+ .name = "Host 3",
+ .init = fsl_usb_host_init_ext,
+ .exit = fsl_usb_host_uninit_ext,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_HSIC,
+ .power_budget = 500, /* 500 mA max power */
+ .wake_up_enable = _wake_up_enable,
+ .usb_clock_for_pm = usbh3_clock_gate,
+ .phy_lowpower_suspend = _phy_lowpower_suspend,
+ .is_wakeup_event = _is_usbh3_wakeup,
+ .wakeup_handler = usbh3_wakeup_handler,
+ .transceiver = "hsic_xcvr",
+ .hsic_post_ops = hsic_start,
+ .hsic_device_connected = hsic_device_connected,
+};
+
+static struct fsl_usb2_wakeup_platform_data usbh3_wakeup_config = {
+ .name = "usbh3 wakeup",
+ .usb_clock_for_pm = usbh3_clock_gate,
+ .usb_pdata = {&usbh3_config, NULL, NULL},
+ .usb_wakeup_exhandle = usbh3_wakeup_event_clear,
+};
+
+void __init mx6_usb_h3_init(void)
+{
+ struct platform_device *pdev, *pdev_wakeup;
+ static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usbh3_config.wakeup_pdata = &usbh3_wakeup_config;
+ pdev = imx6q_add_fsl_ehci_hs(3, &usbh3_config);
+ usbh3_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
+ pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(3, &usbh3_wakeup_config);
+ platform_device_add(pdev);
+ ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
+ pdev_wakeup->dev.platform_data;
+
+ /* Some phy and power's special controls for host3
+ * 1. Its 480M is from OTG's 480M
+ * 2. EN_USB_CLKS should always be opened
+ */
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+ /* must change the clkgate delay to 2 or 3 to avoid
+ * 24M OSCI clock not stable issue */
+ __raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3),
+ anatop_base_addr + HW_ANADIG_ANA_MISC0);
+}
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 00000000..e6990ec5
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,70 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config MXS_OCOTP
+ bool
+
+config SOC_IMX23
+ bool
+ select CPU_ARM926T
+ select HAVE_PWM
+
+config SOC_IMX28
+ bool
+ select CPU_ARM926T
+ select HAVE_PWM
+
+comment "MXS platforms:"
+
+config MACH_STMP378X_DEVB
+ bool "Support STMP378x_devb Platform"
+ select SOC_IMX23
+ select MXS_HAVE_AMBA_DUART
+ select MXS_HAVE_PLATFORM_AUART
+ select MXS_HAVE_PLATFORM_MXS_MMC
+ help
+ Include support for STMP378x-devb platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX23EVK
+ bool "Support MX23EVK Platform"
+ select SOC_IMX23
+ select MXS_HAVE_AMBA_DUART
+ select MXS_HAVE_PLATFORM_AUART
+ select MXS_HAVE_PLATFORM_MXS_MMC
+ select MXS_HAVE_PLATFORM_GPMI_NFC
+ select MXS_HAVE_PLATFORM_MXSFB
+ help
+ Include support for MX23EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+ bool "Support MX28EVK Platform"
+ select SOC_IMX28
+ select MXS_HAVE_AMBA_DUART
+ select MXS_HAVE_PLATFORM_AUART
+ select MXS_HAVE_PLATFORM_FEC
+ select MXS_HAVE_PLATFORM_FLEXCAN
+ select MXS_HAVE_PLATFORM_MXS_MMC
+ select MXS_HAVE_PLATFORM_GPMI_NFC
+ select MXS_HAVE_PLATFORM_MXSFB
+ select MXS_OCOTP
+ help
+ Include support for MX28EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MODULE_TX28
+ bool
+ select SOC_IMX28
+ select MXS_HAVE_AMBA_DUART
+ select MXS_HAVE_PLATFORM_AUART
+ select MXS_HAVE_PLATFORM_FEC
+ select MXS_HAVE_PLATFORM_MXS_I2C
+ select MXS_HAVE_PLATFORM_MXS_PWM
+
+config MACH_TX28
+ bool "Ka-Ro TX28 module"
+ select MODULE_TX28
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 00000000..58e89237
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,16 @@
+# Common support
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_MXS_OCOTP) += ocotp.o
+obj-$(CONFIG_PM) += pm.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+obj-$(CONFIG_MODULE_TX28) += module-tx28.o
+obj-$(CONFIG_MACH_TX28) += mach-tx28.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 00000000..eb541e02
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x40008000
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 00000000..e0e06cda
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/clkdev.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT 8
+
+static int _raw_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ }
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+ return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+ .get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+ /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+ * and is incorrect (excessive). Per definition of the PLLCTRL0
+ * POWER field, waiting at least 10us.
+ */
+ udelay(10);
+
+ return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+ .get_rate = pll_clk_get_rate,
+ .enable = pll_clk_enable,
+ .disable = pll_clk_disable,
+ .parent = &ref_xtal_clk,
+};
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ unsigned long parent_rate; \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
+ div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
+ parent_rate = clk_get_rate(clk->parent); \
+ \
+ return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#define _DEFINE_CLOCK_REF(name, er, es) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
+ .get_rate = name##_get_rate, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = &pll_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+ /* ref_xtal_clk is implemented as the only parent */
+ return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+ return clk->parent->get_rate(clk->parent) / 750;
+}
+
+#define _CLK_GET_RATE(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ if (clk->parent == &ref_xtal_clk) \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
+ BP_CLKCTRL_##rs##_DIV_XTAL; \
+ else \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
+ BP_CLKCTRL_##rs##_DIV_##rs; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#define _CLK_GET_RATE_STUB(name) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ return clk_get_rate(clk->parent); \
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, bm_busy, div_max, d, f, div, frac;
+ unsigned long diff, parent_rate, calc_rate;
+ int i;
+
+ parent_rate = clk_get_rate(clk->parent);
+
+ if (clk->parent == &ref_xtal_clk) {
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div == 0 || div > div_max)
+ return -EINVAL;
+ } else {
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+ rate >>= PARENT_RATE_SHIFT;
+ parent_rate >>= PARENT_RATE_SHIFT;
+ diff = parent_rate;
+ div = frac = 1;
+ for (d = 1; d <= div_max; d++) {
+ f = parent_rate * 18 / d / rate;
+ if ((parent_rate * 18 / d) % rate)
+ f++;
+ if (f < 18 || f > 35)
+ continue;
+
+ calc_rate = parent_rate * 18 / f / d;
+ if (calc_rate > rate)
+ continue;
+
+ if (rate - calc_rate < diff) {
+ frac = f;
+ div = d;
+ diff = rate - calc_rate;
+ }
+
+ if (diff == 0)
+ break;
+ }
+
+ if (diff == parent_rate)
+ return -EINVAL;
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+ reg |= frac;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ }
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_CPU) & bm_busy))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define _CLK_SET_RATE(name, dr) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div_max, div; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg & (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#define _CLK_SET_RATE_STUB(name) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ return -EINVAL; \
+}
+
+_CLK_SET_RATE_STUB(emi_clk)
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) { \
+ __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
+ clk->parent = parent; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#define _CLK_SET_PARENT_STUB(name) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) \
+ return -EINVAL; \
+ else \
+ return 0; \
+}
+
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+ .get_rate = cpu_clk_get_rate,
+ .set_rate = cpu_clk_set_rate,
+ .set_parent = cpu_clk_set_parent,
+ .parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+ .get_rate = hbus_clk_get_rate,
+ .parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+ .get_rate = xbus_clk_get_rate,
+ .set_rate = xbus_clk_set_rate,
+ .parent = &ref_xtal_clk,
+};
+
+static struct clk rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_##es, \
+ .get_rate = name##_get_rate, \
+ .set_rate = name##_set_rate, \
+ .set_parent = name##_set_parent, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = p, \
+ }
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ /* for amba bus driver */
+ _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
+ /* for amba-pl011 driver */
+ _REGISTER_CLOCK("duart", NULL, uart_clk)
+ _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
+ _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+ _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
+ _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "audio", audio_clk)
+ _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
+ _REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
+ _REGISTER_CLOCK("imx23-gpmi-nfc", NULL, gpmi_clk)
+};
+
+static int clk_misc_init(void)
+{
+ u32 reg;
+ int i;
+
+ /* Fix up parent per register setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+ cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+ &ref_xtal_clk : &ref_cpu_clk;
+ emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+ &ref_xtal_clk : &ref_emi_clk;
+ ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+ &ref_xtal_clk : &ref_io_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_io_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+ &ref_xtal_clk : &ref_pix_clk;
+
+ /* Use int div over frac when both are available */
+ __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+ reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+ reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+ reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+ reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+ /*
+ * Set safe hbus clock divider. A divider of 3 ensure that
+ * the Vddd voltage required for the cpu clock is sufficiently
+ * high for the hbus clock.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+ reg &= BM_CLKCTRL_HBUS_DIV;
+ reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Gate off cpu clock in WFI for power saving */
+ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+ /*
+ * 480 MHz seems too high to be ssp clock source directly,
+ * so set frac to get a 288 MHz ref_io.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+ reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
+ return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+ clk_misc_init();
+
+ /*
+ * source ssp clock from ref_io than ref_xtal,
+ * as ref_xtal only provides 24 MHz as maximum.
+ */
+ clk_set_parent(&ssp_clk, &ref_io_clk);
+
+ clk_enable(&cpu_clk);
+ clk_enable(&hbus_clk);
+ clk_enable(&xbus_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&uart_clk);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 00000000..5c52dbfc
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,784 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/clkdev.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx28.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT 8
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->enable_reg) {
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+ }
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+ return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+ .get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+ return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g) \
+static int name##_enable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ udelay(10); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ \
+ return 0; \
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g) \
+static void name##_disable(struct clk *clk) \
+{ \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_POWER, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+ if (clk == &pll2_clk) \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET); \
+ else \
+ __raw_writel(BM_CLKCTRL_##r##CTRL0_##g, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR); \
+ \
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name) \
+ static struct clk name = { \
+ .get_rate = name##_get_rate, \
+ .enable = name##_enable, \
+ .disable = name##_disable, \
+ .parent = &ref_xtal_clk, \
+ }
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ unsigned long parent_rate; \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); \
+ div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; \
+ parent_rate = clk_get_rate(clk->parent); \
+ \
+ return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_CLKGATE##es, \
+ .get_rate = name##_get_rate, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = &pll0_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+ /* ref_xtal_clk is implemented as the only parent */
+ return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+ return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ if (clk->parent == &ref_xtal_clk) \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >> \
+ BP_CLKCTRL_##rs##_DIV_XTAL; \
+ else \
+ div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >> \
+ BP_CLKCTRL_##rs##_DIV_##rs; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ u32 reg, div; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ if (clk == &saif0_clk || clk == &saif1_clk) \
+ return clk_get_rate(clk->parent) >> 16 * div; \
+ else \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+
+#define _CLK_GET_RATE_STUB(name) \
+static unsigned long name##_get_rate(struct clk *clk) \
+{ \
+ return clk_get_rate(clk->parent); \
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+_CLK_GET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV 0
+#define BP_CLKCTRL_CPU_DIV 0
+#define BM_CLKCTRL_CPU_BUSY 0
+
+#define _CLK_SET_RATE(name, dr, fr, fs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, bm_busy, div_max, d, f, div, frac; \
+ unsigned long diff, parent_rate, calc_rate; \
+ int i; \
+ \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ bm_busy = BM_CLKCTRL_##dr##_BUSY; \
+ \
+ if (clk->parent == &ref_xtal_clk) { \
+ parent_rate = clk_get_rate(clk->parent); \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \
+ BP_CLKCTRL_CPU_DIV_XTAL; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL; \
+ } \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ } else { \
+ /* \
+ * hack alert: this block modifies clk->parent, too, \
+ * so the base to use it the grand parent. \
+ */ \
+ parent_rate = clk_get_rate(clk->parent->parent); \
+ rate >>= PARENT_RATE_SHIFT; \
+ parent_rate >>= PARENT_RATE_SHIFT; \
+ diff = parent_rate; \
+ div = frac = 1; \
+ if (clk == &cpu_clk) { \
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> \
+ BP_CLKCTRL_CPU_DIV_CPU; \
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU; \
+ } \
+ for (d = 1; d <= div_max; d++) { \
+ f = parent_rate * 18 / d / rate; \
+ if ((parent_rate * 18 / d) % rate) \
+ f++; \
+ if (f < 18 || f > 35) \
+ continue; \
+ \
+ calc_rate = parent_rate * 18 / f / d; \
+ if (calc_rate > rate) \
+ continue; \
+ \
+ if (rate - calc_rate < diff) { \
+ frac = f; \
+ div = d; \
+ diff = rate - calc_rate; \
+ } \
+ \
+ if (diff == 0) \
+ break; \
+ } \
+ \
+ if (diff == parent_rate) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
+ reg |= frac; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
+ } \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ if (clk == &cpu_clk) { \
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU; \
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU; \
+ } else { \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg & (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & bm_busy)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u32 reg, div_max, div; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \
+ \
+ div = DIV_ROUND_UP(parent_rate, rate); \
+ if (div == 0 || div > div_max) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ reg &= ~BM_CLKCTRL_##dr##_DIV; \
+ reg |= div << BP_CLKCTRL_##dr##_DIV; \
+ if (reg & (1 << clk->enable_shift)) { \
+ pr_err("%s: clock is gated\n", __func__); \
+ return -EINVAL; \
+ } \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ u16 div; \
+ u32 reg; \
+ u64 lrate; \
+ unsigned long parent_rate; \
+ int i; \
+ \
+ parent_rate = clk_get_rate(clk->parent); \
+ if (rate > parent_rate) \
+ return -EINVAL; \
+ \
+ lrate = (u64)rate << 16; \
+ do_div(lrate, parent_rate); \
+ div = (u16)lrate; \
+ \
+ if (!div) \
+ return -EINVAL; \
+ \
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ reg &= ~BM_CLKCTRL_##rs##_DIV; \
+ reg |= div << BP_CLKCTRL_##rs##_DIV; \
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs); \
+ \
+ for (i = 10000; i; i--) \
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR + \
+ HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY)) \
+ break; \
+ if (!i) { \
+ pr_err("%s: divider writing timeout\n", __func__); \
+ return -ETIMEDOUT; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name) \
+static int name##_set_rate(struct clk *clk, unsigned long rate) \
+{ \
+ return -EINVAL; \
+}
+
+_CLK_SET_RATE_STUB(emi_clk)
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+_CLK_SET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) { \
+ __raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit, \
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG); \
+ clk->parent = parent; \
+ } \
+ \
+ return 0; \
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name) \
+static int name##_set_parent(struct clk *clk, struct clk *parent) \
+{ \
+ if (parent != clk->parent) \
+ return -EINVAL; \
+ else \
+ return 0; \
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+ .get_rate = cpu_clk_get_rate,
+ .set_rate = cpu_clk_set_rate,
+ .set_parent = cpu_clk_set_parent,
+ .parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+ .get_rate = hbus_clk_get_rate,
+ .parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+ .get_rate = xbus_clk_get_rate,
+ .set_rate = xbus_clk_set_rate,
+ .parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+ .get_rate = lradc_clk_get_rate,
+ .parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 16,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p) \
+ static struct clk name = { \
+ .enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, \
+ .enable_shift = BP_CLKCTRL_##er##_##es, \
+ .get_rate = name##_get_rate, \
+ .set_rate = name##_set_rate, \
+ .set_parent = name##_set_parent, \
+ .enable = _raw_clk_enable, \
+ .disable = _raw_clk_disable, \
+ .parent = p, \
+ }
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ /* for amba bus driver */
+ _REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
+ /* for amba-pl011 driver */
+ _REGISTER_CLOCK("duart", NULL, uart_clk)
+ _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
+ _REGISTER_CLOCK("imx28-gpmi-nfc", NULL, gpmi_clk)
+ _REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
+ _REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
+ _REGISTER_CLOCK("mxs-auart.3", NULL, uart_clk)
+ _REGISTER_CLOCK("mxs-auart.4", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("pll2", NULL, pll2_clk)
+ _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
+ _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+ _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+ _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
+ _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
+ _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
+ _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+ _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+ _REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.5", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.6", NULL, pwm_clk)
+ _REGISTER_CLOCK("mxs-pwm.7", NULL, pwm_clk)
+ _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+ _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+ _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+ u32 reg;
+ int i;
+
+ /* Fix up parent per register setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+ cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+ &ref_xtal_clk : &ref_cpu_clk;
+ emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+ &ref_xtal_clk : &ref_emi_clk;
+ ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+ &ref_xtal_clk : &ref_io0_clk;
+ ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+ &ref_xtal_clk : &ref_io1_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+ &ref_xtal_clk : &ref_pix_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_gpmi_clk;
+ saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+ &ref_xtal_clk : &pll0_clk;
+ saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+ &ref_xtal_clk : &pll0_clk;
+
+ /* Use int div over frac when both are available */
+ __raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+ __raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+ reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+ reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+ reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+ reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+ reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+ reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+ reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+ /* SAIF has to use frac div for functional operation */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+ reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+ reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+ /*
+ * Set safe hbus clock divider. A divider of 3 ensure that
+ * the Vddd voltage required for the cpu clock is sufficiently
+ * high for the hbus clock.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+ reg &= BM_CLKCTRL_HBUS_DIV;
+ reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ /* Gate off cpu clock in WFI for power saving */
+ __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+ /* Extra fec clock setting */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+ reg &= ~BM_CLKCTRL_ENET_SLEEP;
+ reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+ /*
+ * 480 MHz seems too high to be ssp clock source directly,
+ * so set frac0 to get a 288 MHz ref_io0.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+ reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+ reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
+ return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+ clk_misc_init();
+
+ /*
+ * source ssp clock from ref_io0 than ref_xtal,
+ * as ref_xtal only provides 24 MHz as maximum.
+ */
+ clk_set_parent(&ssp0_clk, &ref_io0_clk);
+ clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
+ clk_enable(&cpu_clk);
+ clk_enable(&hbus_clk);
+ clk_enable(&xbus_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&uart_clk);
+
+ clk_set_parent(&lcdif_clk, &ref_pix_clk);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 00000000..a7093c88
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,198 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+ WARN_ON(!clk->usecount);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ if (clk->usecount)
+ clk_enable(parent);
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ mutex_unlock(&clocks_mutex);
+
+ if (clk->usecount)
+ clk_disable(old);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 00000000..d5b9e452
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/devices-common.h>
+#include <mach/mxsfb.h>
+
+extern const struct amba_device mx23_duart_device __initconst;
+#define mx23_add_duart() \
+ mxs_add_duart(&mx23_duart_device)
+
+extern const struct mxs_auart_data mx23_auart_data[] __initconst;
+#define mx23_add_auart(id) mxs_add_auart(&mx23_auart_data[id])
+#define mx23_add_auart0() mx23_add_auart(0)
+#define mx23_add_auart1() mx23_add_auart(1)
+
+extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst;
+#define mx23_add_mxs_mmc(id, pdata) \
+ mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata)
+
+extern const struct mxs_gpmi_nfc_data mx23_gpmi_nfc_data __initconst;
+#define mx23_add_gpmi_nfc(pdata) \
+ mxs_add_gpmi_nfc(pdata, &mx23_gpmi_nfc_data)
+
+#define mx23_add_mxs_pwm(id) mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)
+
+struct platform_device *__init mx23_add_mxsfb(
+ const struct mxsfb_platform_data *pdata);
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 00000000..bec937ce
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+#include <mach/mxsfb.h>
+
+extern const struct amba_device mx28_duart_device __initconst;
+#define mx28_add_duart() \
+ mxs_add_duart(&mx28_duart_device)
+
+extern const struct mxs_auart_data mx28_auart_data[] __initconst;
+#define mx28_add_auart(id) mxs_add_auart(&mx28_auart_data[id])
+#define mx28_add_auart0() mx28_add_auart(0)
+#define mx28_add_auart1() mx28_add_auart(1)
+#define mx28_add_auart2() mx28_add_auart(2)
+#define mx28_add_auart3() mx28_add_auart(3)
+#define mx28_add_auart4() mx28_add_auart(4)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+ mxs_add_fec(&mx28_fec_data[id], pdata)
+
+extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
+#define mx28_add_flexcan(id, pdata) \
+ mxs_add_flexcan(&mx28_flexcan_data[id], pdata)
+#define mx28_add_flexcan0(pdata) mx28_add_flexcan(0, pdata)
+#define mx28_add_flexcan1(pdata) mx28_add_flexcan(1, pdata)
+
+extern const struct mxs_gpmi_nfc_data mx28_gpmi_nfc_data __initconst;
+#define mx28_add_gpmi_nfc(pdata) \
+ mxs_add_gpmi_nfc(pdata, &mx28_gpmi_nfc_data)
+
+extern const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
+#define mx28_add_mxs_i2c(id) mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
+
+extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst;
+#define mx28_add_mxs_mmc(id, pdata) \
+ mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata)
+
+#define mx28_add_mxs_pwm(id) mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)
+
+struct platform_device *__init mx28_add_mxsfb(
+ const struct mxsfb_platform_data *pdata);
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 00000000..cfdb6b28
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ if (dmamask)
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
+
+int __init mxs_add_amba_device(const struct amba_device *dev)
+{
+ struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL);
+
+ if (!adev) {
+ pr_err("%s: failed to allocate memory", __func__);
+ return -ENOMEM;
+ }
+
+ *adev = *dev;
+
+ return amba_device_register(adev, &iomem_resource);
+}
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 00000000..b42a14b7
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,28 @@
+config MXS_HAVE_AMBA_DUART
+ bool
+ select ARM_AMBA
+
+config MXS_HAVE_PLATFORM_AUART
+ bool
+
+config MXS_HAVE_PLATFORM_FEC
+ bool
+
+config MXS_HAVE_PLATFORM_FLEXCAN
+ select HAVE_CAN_FLEXCAN if CAN
+ bool
+
+config MXS_HAVE_PLATFORM_GPMI_NFC
+ bool
+
+config MXS_HAVE_PLATFORM_MXS_I2C
+ bool
+
+config MXS_HAVE_PLATFORM_MXS_MMC
+ bool
+
+config MXS_HAVE_PLATFORM_MXS_PWM
+ bool
+
+config MXS_HAVE_PLATFORM_MXSFB
+ bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 00000000..ac923ced
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,10 @@
+obj-$(CONFIG_MXS_HAVE_AMBA_DUART) += amba-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
+obj-y += platform-dma.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_GPMI_NFC) += platform-gpmi-nfc.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c
new file mode 100644
index 00000000..a559db09
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/amba-duart.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/irq.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define MXS_AMBA_DUART_DEVICE(name, soc) \
+const struct amba_device name##_device __initconst = { \
+ .dev = { \
+ .init_name = "duart", \
+ }, \
+ .res = { \
+ .start = soc ## _DUART_BASE_ADDR, \
+ .end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .irq = {soc ## _INT_DUART, NO_IRQ}, \
+}
+
+#ifdef CONFIG_SOC_IMX23
+MXS_AMBA_DUART_DEVICE(mx23_duart, MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+MXS_AMBA_DUART_DEVICE(mx28_duart, MX28);
+#endif
+
+int __init mxs_add_duart(const struct amba_device *dev)
+{
+ return mxs_add_amba_device(dev);
+}
diff --git a/arch/arm/mach-mxs/devices/platform-auart.c b/arch/arm/mach-mxs/devices/platform-auart.c
new file mode 100644
index 00000000..27608f5d
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-auart.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <asm/sizes.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_auart_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _AUART ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_AUART ## hwid, \
+ }
+
+#define mxs_auart_data_entry(soc, _id, hwid) \
+ [_id] = mxs_auart_data_entry_single(soc, _id, hwid)
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_auart_data mx23_auart_data[] __initconst = {
+#define mx23_auart_data_entry(_id, hwid) \
+ mxs_auart_data_entry(MX23, _id, hwid)
+ mx23_auart_data_entry(0, 1),
+ mx23_auart_data_entry(1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_auart_data mx28_auart_data[] __initconst = {
+#define mx28_auart_data_entry(_id) \
+ mxs_auart_data_entry(MX28, _id, _id)
+ mx28_auart_data_entry(0),
+ mx28_auart_data_entry(1),
+ mx28_auart_data_entry(2),
+ mx28_auart_data_entry(3),
+ mx28_auart_data_entry(4),
+};
+#endif
+
+struct platform_device *__init mxs_add_auart(
+ const struct mxs_auart_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device_dmamask("mxs-auart", data->id,
+ res, ARRAY_SIZE(res), NULL, 0,
+ DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/mach-mxs/devices/platform-dma.c b/arch/arm/mach-mxs/devices/platform-dma.c
new file mode 100644
index 00000000..6a0202b1
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-dma.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+static struct platform_device *__init mxs_add_dma(const char *devid,
+ resource_size_t base)
+{
+ struct resource res[] = {
+ {
+ .start = base,
+ .end = base + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+
+ return mxs_add_platform_device_dmamask(devid, -1,
+ res, ARRAY_SIZE(res), NULL, 0,
+ DMA_BIT_MASK(32));
+}
+
+static int __init mxs_add_mxs_dma(void)
+{
+ char *apbh = "mxs-dma-apbh";
+ char *apbx = "mxs-dma-apbx";
+
+ if (cpu_is_mx23()) {
+ mxs_add_dma(apbh, MX23_APBH_DMA_BASE_ADDR);
+ mxs_add_dma(apbx, MX23_APBX_DMA_BASE_ADDR);
+ }
+
+ if (cpu_is_mx28()) {
+ mxs_add_dma(apbh, MX28_APBH_DMA_BASE_ADDR);
+ mxs_add_dma(apbx, MX28_APBX_DMA_BASE_ADDR);
+ }
+
+ return 0;
+}
+arch_initcall(mxs_add_mxs_dma);
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 00000000..ae96a4fd
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
+ .irq = soc ## _INT_ENET_MAC ## _id, \
+ }
+
+#define mxs_fec_data_entry(soc, _id) \
+ [_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id) \
+ mxs_fec_data_entry(MX28, _id)
+ mx28_fec_data_entry(0),
+ mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device_dmamask("imx28-fec", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata),
+ DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-mxs/devices/platform-flexcan.c b/arch/arm/mach-mxs/devices/platform-flexcan.c
new file mode 100644
index 00000000..43a6b4ba
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-flexcan.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010, 2011 Pengutronix,
+ * Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_flexcan_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _CAN ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CAN ## _hwid, \
+ }
+
+#define mxs_flexcan_data_entry(soc, _id, _hwid, _size) \
+ [_id] = mxs_flexcan_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_flexcan_data mx28_flexcan_data[] __initconst = {
+#define mx28_flexcan_data_entry(_id, _hwid) \
+ mxs_flexcan_data_entry_single(MX28, _id, _hwid, SZ_8K)
+ mx28_flexcan_data_entry(0, 0),
+ mx28_flexcan_data_entry(1, 1),
+};
+#endif /* ifdef CONFIG_SOC_IMX28 */
+
+struct platform_device *__init mxs_add_flexcan(
+ const struct mxs_flexcan_data *data,
+ const struct flexcan_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("flexcan", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/devices/platform-gpmi-nfc.c b/arch/arm/mach-mxs/devices/platform-gpmi-nfc.c
new file mode 100644
index 00000000..ae88672c
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-gpmi-nfc.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <asm/sizes.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define RES_MEM(soc, _id, _s, _n) \
+ { \
+ .start = soc ##_## _id ## _BASE_ADDR, \
+ .end = soc ##_## _id ## _BASE_ADDR + (_s) - 1,\
+ .name = (_n), \
+ .flags = IORESOURCE_MEM, \
+ }
+
+#define RES_IRQ(soc, _id, _n) \
+ { \
+ .start = soc ##_INT_## _id, \
+ .end = soc ##_INT_## _id, \
+ .name = (_n), \
+ .flags = IORESOURCE_IRQ, \
+ }
+
+#define RES_DMA(soc, _i_s, _i_e, _n) \
+ { \
+ .start = soc ##_## _i_s, \
+ .end = soc ##_## _i_e, \
+ .name = (_n), \
+ .flags = IORESOURCE_DMA, \
+ }
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_gpmi_nfc_data mx23_gpmi_nfc_data __initconst = {
+ .devid = "imx23-gpmi-nfc",
+ .res = {
+ /* GPMI */
+ RES_MEM(MX23, GPMI, SZ_8K, GPMI_NFC_GPMI_REGS_ADDR_RES_NAME),
+ RES_IRQ(MX23, GPMI_ATTENTION, GPMI_NFC_GPMI_INTERRUPT_RES_NAME),
+ /* BCH */
+ RES_MEM(MX23, BCH, SZ_8K, GPMI_NFC_BCH_REGS_ADDR_RES_NAME),
+ RES_IRQ(MX23, BCH, GPMI_NFC_BCH_INTERRUPT_RES_NAME),
+ /* DMA */
+ RES_DMA(MX23, DMA_GPMI0, DMA_GPMI3,
+ GPMI_NFC_DMA_CHANNELS_RES_NAME),
+ RES_IRQ(MX23, GPMI_DMA, GPMI_NFC_DMA_INTERRUPT_RES_NAME),
+ },
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_gpmi_nfc_data mx28_gpmi_nfc_data __initconst = {
+ .devid = "imx28-gpmi-nfc",
+ .res = {
+ /* GPMI */
+ RES_MEM(MX28, GPMI, SZ_8K, GPMI_NFC_GPMI_REGS_ADDR_RES_NAME),
+ RES_IRQ(MX28, GPMI, GPMI_NFC_GPMI_INTERRUPT_RES_NAME),
+ /* BCH */
+ RES_MEM(MX28, BCH, SZ_8K, GPMI_NFC_BCH_REGS_ADDR_RES_NAME),
+ RES_IRQ(MX28, BCH, GPMI_NFC_BCH_INTERRUPT_RES_NAME),
+ /* DMA */
+ RES_DMA(MX28, DMA_GPMI0, DMA_GPMI7,
+ GPMI_NFC_DMA_CHANNELS_RES_NAME),
+ RES_IRQ(MX28, GPMI_DMA, GPMI_NFC_DMA_INTERRUPT_RES_NAME),
+ },
+};
+#endif
+
+struct platform_device *__init
+mxs_add_gpmi_nfc(const struct gpmi_nfc_platform_data *pdata,
+ const struct mxs_gpmi_nfc_data *data)
+{
+ return mxs_add_platform_device_dmamask(data->devid, -1,
+ data->res, RES_SIZE,
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-i2c.c b/arch/arm/mach-mxs/devices/platform-mxs-i2c.c
new file mode 100644
index 00000000..79222ec8
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mxs-i2c.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Pengutronix
+ * Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_i2c_data_entry_single(soc, _id) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _I2C ## _id ## _BASE_ADDR, \
+ .errirq = soc ## _INT_I2C ## _id ## _ERROR, \
+ .dmairq = soc ## _INT_I2C ## _id ## _DMA, \
+ }
+
+#define mxs_i2c_data_entry(soc, _id) \
+ [_id] = mxs_i2c_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst = {
+ mxs_i2c_data_entry(MX28, 0),
+ mxs_i2c_data_entry(MX28, 1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mxs_i2c(
+ const struct mxs_mxs_i2c_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->errirq,
+ .end = data->errirq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->dmairq,
+ .end = data->dmairq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("mxs-i2c", data->id, res,
+ ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
new file mode 100644
index 00000000..382dacbe
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
+ .dma = soc ## _DMA_SSP ## hwid, \
+ .irq_err = soc ## _INT_SSP ## hwid ## _ERROR, \
+ .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
+ }
+
+#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \
+ [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
+
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
+ mxs_mxs_mmc_data_entry(MX23, 0, 1),
+ mxs_mxs_mmc_data_entry(MX23, 1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
+ mxs_mxs_mmc_data_entry(MX28, 0, 0),
+ mxs_mxs_mmc_data_entry(MX28, 1, 1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mxs_mmc(
+ const struct mxs_mxs_mmc_data *data,
+ const struct mxs_mmc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->dma,
+ .end = data->dma,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = data->irq_err,
+ .end = data->irq_err,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq_dma,
+ .end = data->irq_dma,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("mxs-mmc", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-pwm.c b/arch/arm/mach-mxs/devices/platform-mxs-pwm.c
new file mode 100644
index 00000000..680f5a90
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mxs-pwm.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init mxs_add_mxs_pwm(resource_size_t iobase, int id)
+{
+ struct resource res = {
+ .flags = IORESOURCE_MEM,
+ };
+
+ res.start = iobase + 0x10 + 0x20 * id;
+ res.end = res.start + 0x1f;
+
+ return mxs_add_platform_device("mxs-pwm", id, &res, 1, NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/devices/platform-mxsfb.c b/arch/arm/mach-mxs/devices/platform-mxsfb.c
new file mode 100644
index 00000000..bf72c9b8
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mxsfb.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+#include <mach/mxsfb.h>
+
+#ifdef CONFIG_SOC_IMX23
+struct platform_device *__init mx23_add_mxsfb(
+ const struct mxsfb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = MX23_LCDIF_BASE_ADDR,
+ .end = MX23_LCDIF_BASE_ADDR + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return mxs_add_platform_device_dmamask("imx23-fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+#endif /* ifdef CONFIG_SOC_IMX23 */
+
+#ifdef CONFIG_SOC_IMX28
+struct platform_device *__init mx28_add_mxsfb(
+ const struct mxsfb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = MX28_LCDIF_BASE_ADDR,
+ .end = MX28_LCDIF_BASE_ADDR + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return mxs_add_platform_device_dmamask("imx28-fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+#endif /* ifdef CONFIG_SOC_IMX28 */
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 00000000..2c950fef
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,331 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE 0x0
+#define GPIO_INT_LOW_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_HIGH_LEV 0x3
+#define GPIO_INT_LEV_MASK (1 << 0)
+#define GPIO_INT_POL_MASK (1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id));
+}
+
+static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable) {
+ __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id));
+ } else {
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ }
+}
+
+static void mxs_gpio_ack_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void mxs_gpio_mask_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void mxs_gpio_unmask_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ u32 pin_mask = 1 << (gpio & 31);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ void __iomem *pin_addr;
+ int edge;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set level or edge */
+ pin_addr = port->base + PINCTRL_IRQLEV(port->id);
+ if (edge & GPIO_INT_LEV_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_addr);
+
+ /* set polarity */
+ pin_addr = port->base + PINCTRL_IRQPOL(port->id);
+ if (edge & GPIO_INT_POL_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_addr);
+
+ clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+ __raw_readl(port->base + PINCTRL_IRQEN(port->id));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ u32 gpio_idx = gpio & 0x1f;
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .name = "mxs gpio",
+ .irq_ack = mxs_gpio_ack_irq,
+ .irq_mask = mxs_gpio_mask_irq,
+ .irq_unmask = mxs_gpio_unmask_irq,
+ .irq_set_type = mxs_gpio_set_irq_type,
+ .irq_set_wake = mxs_gpio_set_wake_irq,
+};
+
+static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
+
+ if (dir)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_addr);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
+
+ if (value)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_addr);
+}
+
+static int mxs_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ return port->virtual_irq_start + offset;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ mxs_set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxs_gpio_set(chip, offset, value);
+ mxs_set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+ int i, j;
+
+ /* save for local usage */
+ mxs_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ pr_info("MXS GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base + PINCTRL_PIN2IRQ(i));
+ __raw_writel(0, port[i].base + PINCTRL_IRQEN(i));
+
+ /* clear address has to be used to clear IRQSTAT bits */
+ __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));
+
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* setup one handler for each entry */
+ irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq, &port[i]);
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxs_gpio_direction_input;
+ port[i].chip.direction_output = mxs_gpio_direction_output;
+ port[i].chip.get = mxs_gpio_get;
+ port[i].chip.set = mxs_gpio_set;
+ port[i].chip.to_irq = mxs_gpio_to_irq;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+
+ /* its a serious configuration bug when it fails */
+ BUG_ON(gpiochip_add(&port[i].chip) < 0);
+ }
+
+ return 0;
+}
+
+#define MX23_GPIO_BASE MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR)
+#define MX28_GPIO_BASE MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR)
+
+#define DEFINE_MXS_GPIO_PORT(_base, _irq, _id) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .id = _id, \
+ .irq = _irq, \
+ .base = _base, \
+ .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO0, 0),
+ DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO1, 1),
+ DEFINE_MXS_GPIO_PORT(MX23_GPIO_BASE, MX23_INT_GPIO2, 2),
+};
+
+int __init mx23_register_gpios(void)
+{
+ return mxs_gpio_init(mx23_gpio_ports, ARRAY_SIZE(mx23_gpio_ports));
+}
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO0, 0),
+ DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO1, 1),
+ DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO2, 2),
+ DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO3, 3),
+ DEFINE_MXS_GPIO_PORT(MX28_GPIO_BASE, MX28_INT_GPIO4, 4),
+};
+
+int __init mx28_register_gpios(void)
+{
+ return mxs_gpio_init(mx28_gpio_ports, ARRAY_SIZE(mx28_gpio_ports));
+}
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 00000000..005bb066
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+struct mxs_gpio_port {
+ void __iomem *base;
+ int id;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 00000000..23ca9d08
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR 0x0000
+#define HW_ICOLL_LEVELACK 0x0010
+#define HW_ICOLL_CTRL 0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n) (0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n) (0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE 0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 0x1
+
+static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
+
+static void icoll_ack_irq(struct irq_data *d)
+{
+ /*
+ * The Interrupt Collector is able to prioritize irqs.
+ * Currently only level 0 is used. So acking can use
+ * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+ */
+ __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+ icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(struct irq_data *d)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->irq));
+}
+
+static void icoll_unmask_irq(struct irq_data *d)
+{
+ __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+ icoll_base + HW_ICOLL_INTERRUPTn_SET(d->irq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+ .irq_ack = icoll_ack_irq,
+ .irq_mask = icoll_mask_irq,
+ .irq_unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void)
+{
+ int i;
+
+ /*
+ * Interrupt Collector reset, which initializes the priority
+ * for each irq to level 0.
+ */
+ mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+ irq_set_chip_and_handler(i, &mxs_icoll_chip, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 00000000..3a8f2e3a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 00000000..592c9ab5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 00000000..635bb5d9
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern const u32 *mxs_get_ocotp(void);
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_timer_init(struct clk *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 00000000..79650a1a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 00000000..9359992a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/amba/bus.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return mxs_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
+
+int __init mxs_add_amba_device(const struct amba_device *dev);
+
+/* duart */
+int __init mxs_add_duart(const struct amba_device *dev);
+
+/* auart */
+struct mxs_auart_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_auart(
+ const struct mxs_auart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata);
+
+/* flexcan */
+#include <linux/can/platform/flexcan.h>
+struct mxs_flexcan_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_flexcan(
+ const struct mxs_flexcan_data *data,
+ const struct flexcan_platform_data *pdata);
+
+/* gpmi-nfc */
+#include <mach/gpmi-nfc.h>
+struct mxs_gpmi_nfc_data {
+ const char *devid;
+ const struct resource res[RES_SIZE];
+};
+struct platform_device *__init
+mxs_add_gpmi_nfc(const struct gpmi_nfc_platform_data *pdata,
+ const struct mxs_gpmi_nfc_data *data);
+
+/* i2c */
+struct mxs_mxs_i2c_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t errirq;
+ resource_size_t dmairq;
+};
+struct platform_device * __init mxs_add_mxs_i2c(
+ const struct mxs_mxs_i2c_data *data);
+
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mxs_mmc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t dma;
+ resource_size_t irq_err;
+ resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mxs_mmc(
+ const struct mxs_mxs_mmc_data *data,
+ const struct mxs_mmc_platform_data *pdata);
+
+/* pwm */
+struct platform_device *__init mxs_add_mxs_pwm(
+ resource_size_t iobase, int id);
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 00000000..9f0da12e
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mxs.h>
+
+#define MXS_ICOLL_VBASE MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR)
+#define HW_ICOLL_STAT_OFFSET 0x70
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #HW_ICOLL_STAT_OFFSET]
+ cmp \irqnr, #0x7F
+ strne \irqnr, [\base]
+ moveqs \irqnr, #0
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =MXS_ICOLL_VBASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 00000000..828ccccb
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#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
+
+#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/gpmi-nfc.h b/arch/arm/mach-mxs/include/mach/gpmi-nfc.h
new file mode 100644
index 00000000..25fc6053
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpmi-nfc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_GPMI_NFC_H
+#define __INCLUDE_GPMI_NFC_H
+
+/* The size of the resource is fixed. */
+#define RES_SIZE 6
+
+/* Resource names for the GPMI NFC driver. */
+#define GPMI_NFC_GPMI_REGS_ADDR_RES_NAME "GPMI NFC GPMI Registers"
+#define GPMI_NFC_GPMI_INTERRUPT_RES_NAME "GPMI NFC GPMI Interrupt"
+#define GPMI_NFC_BCH_REGS_ADDR_RES_NAME "GPMI NFC BCH Registers"
+#define GPMI_NFC_BCH_INTERRUPT_RES_NAME "GPMI NFC BCH Interrupt"
+#define GPMI_NFC_DMA_CHANNELS_RES_NAME "GPMI NFC DMA Channels"
+#define GPMI_NFC_DMA_INTERRUPT_RES_NAME "GPMI NFC DMA Interrupt"
+
+/**
+ * struct gpmi_nfc_platform_data - GPMI NFC driver platform data.
+ *
+ * This structure communicates platform-specific information to the GPMI NFC
+ * driver that can't be expressed as resources.
+ *
+ * @platform_init: A pointer to a function the driver will call to
+ * initialize the platform (e.g., set up the pin mux).
+ * @platform_exit: A pointer to a function the driver will call to
+ * exit the platform (e.g., free pins).
+ * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and
+ * from the NAND Flash device, in nanoseconds.
+ * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and
+ * from the NAND Flash device, in nanoseconds.
+ * @max_chip_count: The maximum number of chips for which the driver
+ * should configure the hardware. This value most
+ * likely reflects the number of pins that are
+ * connected to a NAND Flash device. If this is
+ * greater than the SoC hardware can support, the
+ * driver will print a message and fail to initialize.
+ * @partitions: An optional pointer to an array of partition
+ * descriptions.
+ * @partition_count: The number of elements in the partitions array.
+ */
+struct gpmi_nfc_platform_data {
+ /* SoC hardware information. */
+ int (*platform_init)(void);
+ void (*platform_exit)(void);
+
+ /* NAND Flash information. */
+ unsigned int min_prop_delay_in_ns;
+ unsigned int max_prop_delay_in_ns;
+ unsigned int max_chip_count;
+
+ /* Medium information. */
+ struct mtd_partition *partitions;
+ unsigned partition_count;
+};
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 00000000..53e89a09
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 00000000..289b7227
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 00000000..b0190a48
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX
+ */
+/* MUXSEL_0 */
+#define MX23_PAD_GPMI_D00__GPMI_D00 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D01__GPMI_D01 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D02__GPMI_D02 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D03__GPMI_D03 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D04__GPMI_D04 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D05__GPMI_D05 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D06__GPMI_D06 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D07__GPMI_D07 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D08__GPMI_D08 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D09__GPMI_D09 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D10__GPMI_D10 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D11__GPMI_D11 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D12__GPMI_D12 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D13__GPMI_D13 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D14__GPMI_D14 MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_D15__GPMI_D15 MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CLE__GPMI_CLE MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_ALE__GPMI_ALE MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE2N__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY0__GPMI_RDY0 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY1__GPMI_RDY1 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY2__GPMI_RDY2 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDY3__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_WPN__GPMI_WPN MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_WRN__GPMI_WRN MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_RDN__GPMI_RDN MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_CTS__AUART1_CTS MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_RTS__AUART1_RTS MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_RX__AUART1_RX MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_0)
+#define MX23_PAD_AUART1_TX__AUART1_TX MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_0)
+#define MX23_PAD_I2C_SCL__I2C_SCL MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_0)
+#define MX23_PAD_I2C_SDA__I2C_SDA MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_0)
+
+#define MX23_PAD_LCD_D00__LCD_D00 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D01__LCD_D01 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D02__LCD_D02 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D03__LCD_D03 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D04__LCD_D04 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D05__LCD_D05 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D06__LCD_D06 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D07__LCD_D07 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D08__LCD_D08 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D09__LCD_D09 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D10__LCD_D10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D11__LCD_D11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D12__LCD_D12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D13__LCD_D13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D14__LCD_D14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D15__LCD_D15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D16__LCD_D16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_D17__LCD_D17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_RESET__LCD_RESET MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_RS__LCD_RS MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_WR__LCD_WR MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_CS__LCD_CS MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_DOTCK__LCD_DOTCK MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_ENABLE__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_HSYNC__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_0)
+#define MX23_PAD_LCD_VSYNC__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_0)
+#define MX23_PAD_PWM0__PWM0 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_0)
+#define MX23_PAD_PWM1__PWM1 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_0)
+#define MX23_PAD_PWM2__PWM2 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_0)
+#define MX23_PAD_PWM3__PWM3 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_0)
+#define MX23_PAD_PWM4__PWM4 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_0)
+
+#define MX23_PAD_SSP1_CMD__SSP1_CMD MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DETECT__SSP1_DETECT MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA0__SSP1_DATA0 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA1__SSP1_DATA1 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA2__SSP1_DATA2 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_DATA3__SSP1_DATA3 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_0)
+#define MX23_PAD_SSP1_SCK__SSP1_SCK MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_0)
+#define MX23_PAD_ROTARYA__ROTARYA MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_0)
+#define MX23_PAD_ROTARYB__ROTARYB MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A00__EMI_A00 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A01__EMI_A01 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A02__EMI_A02 MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A03__EMI_A03 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A04__EMI_A04 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A05__EMI_A05 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A06__EMI_A06 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A07__EMI_A07 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A08__EMI_A08 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A09__EMI_A09 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A10__EMI_A10 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A11__EMI_A11 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_A12__EMI_A12 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_BA0__EMI_BA0 MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_BA1__EMI_BA1 MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CASN__EMI_CASN MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CE0N__EMI_CE0N MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CE1N__EMI_CE1N MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE1N__GPMI_CE1N MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_0)
+#define MX23_PAD_GPMI_CE0N__GPMI_CE0N MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CKE__EMI_CKE MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_RASN__EMI_RASN MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_WEN__EMI_WEN MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_0)
+
+#define MX23_PAD_EMI_D00__EMI_D00 MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D01__EMI_D01 MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D02__EMI_D02 MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D03__EMI_D03 MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D04__EMI_D04 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D05__EMI_D05 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D06__EMI_D06 MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D07__EMI_D07 MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D08__EMI_D08 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D09__EMI_D09 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D10__EMI_D10 MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D11__EMI_D11 MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D12__EMI_D12 MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D13__EMI_D13 MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D14__EMI_D14 MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_D15__EMI_D15 MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQM0__EMI_DQM0 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQM1__EMI_DQM1 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQS0__EMI_DQS0 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_DQS1__EMI_DQS1 MXS_IOMUX_PAD_NAKED(3, 19, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CLK__EMI_CLK MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_0)
+#define MX23_PAD_EMI_CLKN__EMI_CLKN MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_0)
+
+/* MUXSEL_1 */
+#define MX23_PAD_GPMI_D00__LCD_D8 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D01__LCD_D9 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D02__LCD_D10 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D03__LCD_D11 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D04__LCD_D12 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D05__LCD_D13 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D06__LCD_D14 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D07__LCD_D15 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D08__LCD_D18 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D09__LCD_D19 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D10__LCD_D20 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D11__LCD_D21 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D12__LCD_D22 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D13__LCD_D23 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D14__AUART2_RX MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_D15__AUART2_TX MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_CLE__LCD_D16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_ALE__LCD_D17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_1)
+#define MX23_PAD_GPMI_CE2N__ATA_A2 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_RTS__IR_CLK MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_RX__IR_RX MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_1)
+#define MX23_PAD_AUART1_TX__IR_TX MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_1)
+#define MX23_PAD_I2C_SCL__GPMI_RDY2 MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_1)
+#define MX23_PAD_I2C_SDA__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_1)
+
+#define MX23_PAD_LCD_D00__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D01__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D02__ETM_DA10 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D03__ETM_DA11 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D04__ETM_DA12 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D05__ETM_DA13 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D06__ETM_DA14 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D07__ETM_DA15 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D08__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D09__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D10__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D11__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D12__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D13__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D14__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_D15__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_RESET__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_RS__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_DOTCK__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_ENABLE__I2C_SCL MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_HSYNC__I2C_SDA MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_1)
+#define MX23_PAD_LCD_VSYNC__LCD_BUSY MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_1)
+#define MX23_PAD_PWM0__ROTARYA MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_1)
+#define MX23_PAD_PWM1__ROTARYB MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_1)
+#define MX23_PAD_PWM2__GPMI_RDY3 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_1)
+#define MX23_PAD_PWM3__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_1)
+#define MX23_PAD_PWM4__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_1)
+
+#define MX23_PAD_SSP1_DETECT__GPMI_CE3N MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_1)
+#define MX23_PAD_SSP1_DATA1__I2C_SCL MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_1)
+#define MX23_PAD_SSP1_DATA2__I2C_SDA MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_1)
+#define MX23_PAD_ROTARYA__AUART2_RTS MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_1)
+#define MX23_PAD_ROTARYB__AUART2_CTS MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_1)
+
+/* MUXSEL_2 */
+#define MX23_PAD_GPMI_D00__SSP2_DATA0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D01__SSP2_DATA1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D02__SSP2_DATA2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D03__SSP2_DATA3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D04__SSP2_DATA4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D05__SSP2_DATA5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D06__SSP2_DATA6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D07__SSP2_DATA7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D08__SSP1_DATA4 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D09__SSP1_DATA5 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D10__SSP1_DATA6 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D11__SSP1_DATA7 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_D15__GPMI_CE3N MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_RDY0__SSP2_DETECT MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_RDY1__SSP2_CMD MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_2)
+#define MX23_PAD_GPMI_WRN__SSP2_SCK MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_CTS__SSP1_DATA4 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_RTS__SSP1_DATA5 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_RX__SSP1_DATA6 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_2)
+#define MX23_PAD_AUART1_TX__SSP1_DATA7 MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_2)
+#define MX23_PAD_I2C_SCL__AUART1_TX MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_2)
+#define MX23_PAD_I2C_SDA__AUART1_RX MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_2)
+
+#define MX23_PAD_LCD_D08__SAIF2_SDATA0 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D09__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D10__SAIF_MCLK_BITCLK MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D11__SAIF_LRCLK MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D12__SAIF2_SDATA1 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D13__SAIF2_SDATA2 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D14__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D15__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_D16__SAIF_ALT_BITCLK MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_2)
+#define MX23_PAD_LCD_RESET__GPMI_CE3N MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_2)
+#define MX23_PAD_PWM0__DUART_RX MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_2)
+#define MX23_PAD_PWM1__DUART_TX MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_2)
+#define MX23_PAD_PWM3__AUART1_CTS MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_2)
+#define MX23_PAD_PWM4__AUART1_RTS MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_2)
+
+#define MX23_PAD_SSP1_CMD__JTAG_TDO MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DETECT__USB_OTG_ID MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA0__JTAG_TDI MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA1__JTAG_TCLK MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA2__JTAG_RTCK MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_DATA3__JTAG_TMS MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_2)
+#define MX23_PAD_SSP1_SCK__JTAG_TRST MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_2)
+#define MX23_PAD_ROTARYA__SPDIF MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_2)
+#define MX23_PAD_ROTARYB__GPMI_CE3N MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_2)
+
+/* MUXSEL_GPIO */
+#define MX23_PAD_GPMI_D00__GPIO_0_0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D01__GPIO_0_1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D02__GPIO_0_2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D03__GPIO_0_3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D04__GPIO_0_4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D05__GPIO_0_5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D06__GPIO_0_6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D07__GPIO_0_7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D08__GPIO_0_8 MXS_IOMUX_PAD_NAKED(0, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D09__GPIO_0_9 MXS_IOMUX_PAD_NAKED(0, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D10__GPIO_0_10 MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D11__GPIO_0_11 MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D12__GPIO_0_12 MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D13__GPIO_0_13 MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D14__GPIO_0_14 MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D15__GPIO_0_15 MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CLE__GPIO_0_16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_ALE__GPIO_0_17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE2N__GPIO_0_18 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY0__GPIO_0_19 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY1__GPIO_0_20 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY2__GPIO_0_21 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY3__GPIO_0_22 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WPN__GPIO_0_23 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WRN__GPIO_0_24 MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDN__GPIO_0_25 MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_CTS__GPIO_0_26 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RTS__GPIO_0_27 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RX__GPIO_0_28 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_TX__GPIO_0_29 MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SCL__GPIO_0_30 MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SDA__GPIO_0_31 MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
+
+#define MX23_PAD_LCD_D00__GPIO_1_0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D01__GPIO_1_1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D02__GPIO_1_2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D03__GPIO_1_3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D04__GPIO_1_4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D05__GPIO_1_5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D06__GPIO_1_6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D07__GPIO_1_7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D08__GPIO_1_8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D09__GPIO_1_9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D10__GPIO_1_10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D11__GPIO_1_11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D12__GPIO_1_12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D13__GPIO_1_13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D14__GPIO_1_14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D15__GPIO_1_15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D16__GPIO_1_16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D17__GPIO_1_17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RESET__GPIO_1_18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RS__GPIO_1_19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_WR__GPIO_1_20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_CS__GPIO_1_21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_DOTCK__GPIO_1_22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_ENABLE__GPIO_1_23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_HSYNC__GPIO_1_24 MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_VSYNC__GPIO_1_25 MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM0__GPIO_1_26 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM1__GPIO_1_27 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM2__GPIO_1_28 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM3__GPIO_1_29 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM4__GPIO_1_30 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+
+#define MX23_PAD_SSP1_CMD__GPIO_2_0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DETECT__GPIO_2_1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA0__GPIO_2_2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA1__GPIO_2_3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA2__GPIO_2_4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA3__GPIO_2_5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_SCK__GPIO_2_6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYA__GPIO_2_7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYB__GPIO_2_8 MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A00__GPIO_2_9 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A01__GPIO_2_10 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A02__GPIO_2_11 MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A03__GPIO_2_12 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A04__GPIO_2_13 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A05__GPIO_2_14 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A06__GPIO_2_15 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A07__GPIO_2_16 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A08__GPIO_2_17 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A09__GPIO_2_18 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A10__GPIO_2_19 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A11__GPIO_2_20 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A12__GPIO_2_21 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA0__GPIO_2_22 MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA1__GPIO_2_23 MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CASN__GPIO_2_24 MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE0N__GPIO_2_25 MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE1N__GPIO_2_26 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE1N__GPIO_2_27 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE0N__GPIO_2_28 MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CKE__GPIO_2_29 MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_RASN__GPIO_2_30 MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_WEN__GPIO_2_31 MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 00000000..f50fefd1
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX
+ */
+/* MUXSEL_0 */
+#define MX28_PAD_GPMI_D00__GPMI_D0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D01__GPMI_D1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D02__GPMI_D2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D03__GPMI_D3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D04__GPMI_D4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D05__GPMI_D5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D06__GPMI_D6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_D07__GPMI_D7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE0N__GPMI_CE0N MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE1N__GPMI_CE1N MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE2N__GPMI_CE2N MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CE3N__GPMI_CE3N MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY0__GPMI_READY0 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY1__GPMI_READY1 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY2__GPMI_READY2 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDY3__GPMI_READY3 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RDN__GPMI_RDN MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_WRN__GPMI_WRN MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_ALE__GPMI_ALE MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_CLE__GPMI_CLE MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_0)
+#define MX28_PAD_GPMI_RESETN__GPMI_RESETN MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_0)
+
+#define MX28_PAD_LCD_D00__LCD_D0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D01__LCD_D1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D02__LCD_D2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D03__LCD_D3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D04__LCD_D4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D05__LCD_D5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D06__LCD_D6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D07__LCD_D7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D08__LCD_D8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D09__LCD_D9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D10__LCD_D10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D11__LCD_D11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D12__LCD_D12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D13__LCD_D13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D14__LCD_D14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D15__LCD_D15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D16__LCD_D16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D17__LCD_D17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D18__LCD_D18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D19__LCD_D19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D20__LCD_D20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D21__LCD_D21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D22__LCD_D22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_D23__LCD_D23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RD_E__LCD_RD_E MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_WR_RWN__LCD_WR_RWN MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RS__LCD_RS MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_CS__LCD_CS MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_VSYNC__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_HSYNC__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_DOTCLK__LCD_DOTCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_ENABLE__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 31, PAD_MUXSEL_0)
+
+#define MX28_PAD_SSP0_DATA0__SSP0_D0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA1__SSP0_D1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA2__SSP0_D2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA3__SSP0_D3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA4__SSP0_D4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA5__SSP0_D5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA6__SSP0_D6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DATA7__SSP0_D7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_CMD__SSP0_CMD MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_0)
+#define MX28_PAD_SSP0_SCK__SSP0_SCK MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_SCK__SSP1_SCK MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_CMD__SSP1_CMD MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_DATA0__SSP1_D0 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_0)
+#define MX28_PAD_SSP1_DATA3__SSP1_D3 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SCK__SSP2_SCK MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_MOSI__SSP2_CMD MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_MISO__SSP2_D0 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS0__SSP2_D3 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS1__SSP2_D4 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_0)
+#define MX28_PAD_SSP2_SS2__SSP2_D5 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_SCK__SSP3_SCK MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_MOSI__SSP3_CMD MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_MISO__SSP3_D0 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_0)
+#define MX28_PAD_SSP3_SS0__SSP3_D3 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_0)
+
+#define MX28_PAD_AUART0_RX__AUART0_RX MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_TX__AUART0_TX MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_CTS__AUART0_CTS MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_0)
+#define MX28_PAD_AUART0_RTS__AUART0_RTS MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_RX__AUART1_RX MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_TX__AUART1_TX MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_CTS__AUART1_CTS MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_0)
+#define MX28_PAD_AUART1_RTS__AUART1_RTS MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_RX__AUART2_RX MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_TX__AUART2_TX MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_CTS__AUART2_CTS MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_0)
+#define MX28_PAD_AUART2_RTS__AUART2_RTS MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_RX__AUART3_RX MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_TX__AUART3_TX MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_CTS__AUART3_CTS MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_0)
+#define MX28_PAD_AUART3_RTS__AUART3_RTS MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_0)
+#define MX28_PAD_PWM0__PWM_0 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_0)
+#define MX28_PAD_PWM1__PWM_1 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_0)
+#define MX28_PAD_PWM2__PWM_2 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_MCLK__SAIF0_MCLK MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_0)
+#define MX28_PAD_I2C0_SCL__I2C0_SCL MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_0)
+#define MX28_PAD_I2C0_SDA__I2C0_SDA MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_0)
+#define MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_0)
+#define MX28_PAD_SPDIF__SPDIF_TX MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_0)
+#define MX28_PAD_PWM3__PWM_3 MXS_IOMUX_PAD_NAKED(3, 28, PAD_MUXSEL_0)
+#define MX28_PAD_PWM4__PWM_4 MXS_IOMUX_PAD_NAKED(3, 29, PAD_MUXSEL_0)
+#define MX28_PAD_LCD_RESET__LCD_RESET MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_0)
+
+#define MX28_PAD_ENET0_MDC__ENET0_MDC MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TX_CLK__ENET0_TX_CLK MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD2__ENET0_RXD2 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RXD3__ENET0_RXD3 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD2__ENET0_TXD2 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_TXD3__ENET0_TXD3 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_CLK MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_COL__ENET0_COL MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_0)
+#define MX28_PAD_ENET0_CRS__ENET0_CRS MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_0)
+#define MX28_PAD_ENET_CLK__CLKCTRL_ENET MXS_IOMUX_PAD_NAKED(4, 16, PAD_MUXSEL_0)
+#define MX28_PAD_JTAG_RTCK__JTAG_RTCK MXS_IOMUX_PAD_NAKED(4, 20, PAD_MUXSEL_0)
+
+#define MX28_PAD_EMI_D00__EMI_DATA0 MXS_IOMUX_PAD_NAKED(5, 0, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D01__EMI_DATA1 MXS_IOMUX_PAD_NAKED(5, 1, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D02__EMI_DATA2 MXS_IOMUX_PAD_NAKED(5, 2, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D03__EMI_DATA3 MXS_IOMUX_PAD_NAKED(5, 3, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D04__EMI_DATA4 MXS_IOMUX_PAD_NAKED(5, 4, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D05__EMI_DATA5 MXS_IOMUX_PAD_NAKED(5, 5, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D06__EMI_DATA6 MXS_IOMUX_PAD_NAKED(5, 6, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D07__EMI_DATA7 MXS_IOMUX_PAD_NAKED(5, 7, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D08__EMI_DATA8 MXS_IOMUX_PAD_NAKED(5, 8, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D09__EMI_DATA9 MXS_IOMUX_PAD_NAKED(5, 9, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D10__EMI_DATA10 MXS_IOMUX_PAD_NAKED(5, 10, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D11__EMI_DATA11 MXS_IOMUX_PAD_NAKED(5, 11, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D12__EMI_DATA12 MXS_IOMUX_PAD_NAKED(5, 12, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D13__EMI_DATA13 MXS_IOMUX_PAD_NAKED(5, 13, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D14__EMI_DATA14 MXS_IOMUX_PAD_NAKED(5, 14, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_D15__EMI_DATA15 MXS_IOMUX_PAD_NAKED(5, 15, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_ODT0__EMI_ODT0 MXS_IOMUX_PAD_NAKED(5, 16, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQM0__EMI_DQM0 MXS_IOMUX_PAD_NAKED(5, 17, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_ODT1__EMI_ODT1 MXS_IOMUX_PAD_NAKED(5, 18, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQM1__EMI_DQM1 MXS_IOMUX_PAD_NAKED(5, 19, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK MXS_IOMUX_PAD_NAKED(5, 20, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CLK__EMI_CLK MXS_IOMUX_PAD_NAKED(5, 21, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQS0__EMI_DQS0 MXS_IOMUX_PAD_NAKED(5, 22, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DQS1__EMI_DQS1 MXS_IOMUX_PAD_NAKED(5, 23, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN MXS_IOMUX_PAD_NAKED(5, 26, PAD_MUXSEL_0)
+
+#define MX28_PAD_EMI_A00__EMI_ADDR0 MXS_IOMUX_PAD_NAKED(6, 0, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A01__EMI_ADDR1 MXS_IOMUX_PAD_NAKED(6, 1, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A02__EMI_ADDR2 MXS_IOMUX_PAD_NAKED(6, 2, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A03__EMI_ADDR3 MXS_IOMUX_PAD_NAKED(6, 3, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A04__EMI_ADDR4 MXS_IOMUX_PAD_NAKED(6, 4, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A05__EMI_ADDR5 MXS_IOMUX_PAD_NAKED(6, 5, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A06__EMI_ADDR6 MXS_IOMUX_PAD_NAKED(6, 6, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A07__EMI_ADDR7 MXS_IOMUX_PAD_NAKED(6, 7, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A08__EMI_ADDR8 MXS_IOMUX_PAD_NAKED(6, 8, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A09__EMI_ADDR9 MXS_IOMUX_PAD_NAKED(6, 9, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A10__EMI_ADDR10 MXS_IOMUX_PAD_NAKED(6, 10, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A11__EMI_ADDR11 MXS_IOMUX_PAD_NAKED(6, 11, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A12__EMI_ADDR12 MXS_IOMUX_PAD_NAKED(6, 12, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A13__EMI_ADDR13 MXS_IOMUX_PAD_NAKED(6, 13, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_A14__EMI_ADDR14 MXS_IOMUX_PAD_NAKED(6, 14, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA0__EMI_BA0 MXS_IOMUX_PAD_NAKED(6, 16, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA1__EMI_BA1 MXS_IOMUX_PAD_NAKED(6, 17, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_BA2__EMI_BA2 MXS_IOMUX_PAD_NAKED(6, 18, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CASN__EMI_CASN MXS_IOMUX_PAD_NAKED(6, 19, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_RASN__EMI_RASN MXS_IOMUX_PAD_NAKED(6, 20, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_WEN__EMI_WEN MXS_IOMUX_PAD_NAKED(6, 21, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CE0N__EMI_CE0N MXS_IOMUX_PAD_NAKED(6, 22, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CE1N__EMI_CE1N MXS_IOMUX_PAD_NAKED(6, 23, PAD_MUXSEL_0)
+#define MX28_PAD_EMI_CKE__EMI_CKE MXS_IOMUX_PAD_NAKED(6, 24, PAD_MUXSEL_0)
+
+/* MUXSEL_1 */
+#define MX28_PAD_GPMI_D00__SSP1_D0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D01__SSP1_D1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D02__SSP1_D2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D03__SSP1_D3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D04__SSP1_D4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D05__SSP1_D5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D06__SSP1_D6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_D07__SSP1_D7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE0N__SSP3_D0 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE1N__SSP3_D3 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE2N__CAN1_TX MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CE3N__CAN1_RX MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY1__SSP1_CMD MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY2__CAN0_TX MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDY3__CAN0_RX MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RDN__SSP3_SCK MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_WRN__SSP1_SCK MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_ALE__SSP3_D1 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_CLE__SSP3_D2 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_1)
+#define MX28_PAD_GPMI_RESETN__SSP3_CMD MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_1)
+
+#define MX28_PAD_LCD_D03__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D04__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D08__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D09__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D20__ENET1_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D21__ENET1_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D22__ENET1_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_D23__ENET1_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RD_E__LCD_VSYNC MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_WR_RWN__LCD_HSYNC MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RS__LCD_DOTCLK MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_CS__LCD_ENABLE MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_VSYNC__SAIF1_SDATA0 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_HSYNC__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_DOTCLK__SAIF1_MCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_1)
+
+#define MX28_PAD_SSP0_DATA4__SSP2_D0 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA5__SSP2_D3 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA6__SSP2_CMD MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_1)
+#define MX28_PAD_SSP0_DATA7__SSP2_SCK MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_SCK__SSP2_D1 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_CMD__SSP2_D2 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_DATA0__SSP2_D6 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_1)
+#define MX28_PAD_SSP1_DATA3__SSP2_D7 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SCK__AUART2_RX MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_MOSI__AUART2_TX MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_MISO__AUART3_RX MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS0__AUART3_TX MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS1__SSP2_D1 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_1)
+#define MX28_PAD_SSP2_SS2__SSP2_D2 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_SCK__AUART4_TX MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_MOSI__AUART4_RX MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_MISO__AUART4_RTS MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_1)
+#define MX28_PAD_SSP3_SS0__AUART4_CTS MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_1)
+
+#define MX28_PAD_AUART0_RX__I2C0_SCL MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_TX__I2C0_SDA MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_CTS__AUART4_RX MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_1)
+#define MX28_PAD_AUART0_RTS__AUART4_TX MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_RX__SSP2_CARD_DETECT MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_TX__SSP3_CARD_DETECT MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_CTS__USB0_OVERCURRENT MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_1)
+#define MX28_PAD_AUART1_RTS__USB0_ID MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_RX__SSP3_D1 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_TX__SSP3_D2 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_CTS__I2C1_SCL MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_1)
+#define MX28_PAD_AUART2_RTS__I2C1_SDA MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_RX__CAN0_TX MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_TX__CAN0_RX MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_CTS__CAN1_TX MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_1)
+#define MX28_PAD_AUART3_RTS__CAN1_RX MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_1)
+#define MX28_PAD_PWM0__I2C1_SCL MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_1)
+#define MX28_PAD_PWM1__I2C1_SDA MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_1)
+#define MX28_PAD_PWM2__USB0_ID MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_MCLK__PWM_3 MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_LRCLK__PWM_4 MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_BITCLK__PWM_5 MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF0_SDATA0__PWM_6 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_1)
+#define MX28_PAD_I2C0_SCL__TIMROT_ROTARYA MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_1)
+#define MX28_PAD_I2C0_SDA__TIMROT_ROTARYB MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_1)
+#define MX28_PAD_SAIF1_SDATA0__PWM_7 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_1)
+#define MX28_PAD_LCD_RESET__LCD_VSYNC MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_1)
+
+#define MX28_PAD_ENET0_MDC__GPMI_CE4N MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_MDIO__GPMI_CE5N MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RX_EN__GPMI_CE6N MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD0__GPMI_CE7N MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD1__GPMI_READY4 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TX_CLK__HSADC_TRIGGER MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TX_EN__GPMI_READY5 MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD0__GPMI_READY6 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD1__GPMI_READY7 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD2__ENET1_RXD0 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RXD3__ENET1_RXD1 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD2__ENET1_TXD0 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_TXD3__ENET1_TXD1 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_RX_ER MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_COL__ENET1_TX_EN MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_1)
+#define MX28_PAD_ENET0_CRS__ENET1_RX_EN MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_1)
+
+/* MUXSEL_2 */
+#define MX28_PAD_GPMI_CE2N__ENET0_RX_ER MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_CE3N__SAIF1_MCLK MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY0__USB0_ID MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY2__ENET0_TX_ER MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_RDY3__HSADC_TRIGGER MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_ALE__SSP3_D4 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_2)
+#define MX28_PAD_GPMI_CLE__SSP3_D5 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_LCD_D00__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D01__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D02__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D03__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D04__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D05__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D06__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D07__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D08__ETM_DA8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D09__ETM_DA9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D10__ETM_DA10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D11__ETM_DA11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D12__ETM_DA12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D13__ETM_DA13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D14__ETM_DA14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D15__ETM_DA15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D16__ETM_DA7 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D17__ETM_DA6 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D18__ETM_DA5 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D19__ETM_DA4 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D20__ETM_DA3 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D21__ETM_DA2 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D22__ETM_DA1 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_D23__ETM_DA0 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_RD_E__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_WR_RWN__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_HSYNC__ETM_TCTL MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_2)
+#define MX28_PAD_LCD_DOTCLK__ETM_TCLK MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_2)
+
+#define MX28_PAD_SSP1_SCK__ENET0_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_CMD__ENET0_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_DATA0__ENET0_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_2)
+#define MX28_PAD_SSP1_DATA3__ENET0_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SCK__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_MOSI__SAIF0_SDATA2 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_MISO__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS0__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS1__USB1_OVERCURRENT MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_2)
+#define MX28_PAD_SSP2_SS2__USB0_OVERCURRENT MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_SCK__ENET1_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_MOSI__ENET1_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_MISO__ENET1_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_2)
+#define MX28_PAD_SSP3_SS0__ENET1_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_AUART0_RX__DUART_CTS MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_TX__DUART_RTS MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_CTS__DUART_RX MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_2)
+#define MX28_PAD_AUART0_RTS__DUART_TX MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_RX__PWM_0 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_TX__PWM_1 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_CTS__TIMROT_ROTARYA MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_2)
+#define MX28_PAD_AUART1_RTS__TIMROT_ROTARYB MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_RX__SSP3_D4 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_TX__SSP3_D5 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_CTS__SAIF1_BITCLK MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_2)
+#define MX28_PAD_AUART2_RTS__SAIF1_LRCLK MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_RX__ENET0_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_TX__ENET0_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_CTS__ENET0_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_2)
+#define MX28_PAD_AUART3_RTS__ENET0_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_2)
+#define MX28_PAD_PWM0__DUART_RX MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_2)
+#define MX28_PAD_PWM1__DUART_TX MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_2)
+#define MX28_PAD_PWM2__USB1_OVERCURRENT MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_MCLK__AUART4_CTS MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_LRCLK__AUART4_RTS MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_BITCLK__AUART4_RX MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF0_SDATA0__AUART4_TX MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_2)
+#define MX28_PAD_I2C0_SCL__DUART_RX MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_2)
+#define MX28_PAD_I2C0_SDA__DUART_TX MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_2)
+#define MX28_PAD_SAIF1_SDATA0__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_2)
+#define MX28_PAD_SPDIF__ENET1_RX_ER MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_2)
+
+#define MX28_PAD_ENET0_MDC__SAIF0_SDATA1 MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_MDIO__SAIF0_SDATA2 MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RX_EN__SAIF1_SDATA1 MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD0__SAIF1_SDATA2 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TX_CLK__ENET0_1588_EVENT2_OUT MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD2__ENET0_1588_EVENT0_OUT MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RXD3__ENET0_1588_EVENT0_IN MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TXD2__ENET0_1588_EVENT1_OUT MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_TXD3__ENET0_1588_EVENT1_IN MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_RX_CLK__ENET0_1588_EVENT2_IN MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_COL__ENET0_1588_EVENT3_OUT MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_2)
+#define MX28_PAD_ENET0_CRS__ENET0_1588_EVENT3_IN MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_2)
+
+/* MUXSEL_GPIO */
+#define MX28_PAD_GPMI_D00__GPIO_0_0 MXS_IOMUX_PAD_NAKED(0, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D01__GPIO_0_1 MXS_IOMUX_PAD_NAKED(0, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D02__GPIO_0_2 MXS_IOMUX_PAD_NAKED(0, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D03__GPIO_0_3 MXS_IOMUX_PAD_NAKED(0, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D04__GPIO_0_4 MXS_IOMUX_PAD_NAKED(0, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D05__GPIO_0_5 MXS_IOMUX_PAD_NAKED(0, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D06__GPIO_0_6 MXS_IOMUX_PAD_NAKED(0, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_D07__GPIO_0_7 MXS_IOMUX_PAD_NAKED(0, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE0N__GPIO_0_16 MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE1N__GPIO_0_17 MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE2N__GPIO_0_18 MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CE3N__GPIO_0_19 MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY0__GPIO_0_20 MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY1__GPIO_0_21 MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY2__GPIO_0_22 MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDY3__GPIO_0_23 MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RDN__GPIO_0_24 MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_WRN__GPIO_0_25 MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_ALE__GPIO_0_26 MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_CLE__GPIO_0_27 MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_GPMI_RESETN__GPIO_0_28 MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_LCD_D00__GPIO_1_0 MXS_IOMUX_PAD_NAKED(1, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D01__GPIO_1_1 MXS_IOMUX_PAD_NAKED(1, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D02__GPIO_1_2 MXS_IOMUX_PAD_NAKED(1, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D03__GPIO_1_3 MXS_IOMUX_PAD_NAKED(1, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D04__GPIO_1_4 MXS_IOMUX_PAD_NAKED(1, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D05__GPIO_1_5 MXS_IOMUX_PAD_NAKED(1, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D06__GPIO_1_6 MXS_IOMUX_PAD_NAKED(1, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D07__GPIO_1_7 MXS_IOMUX_PAD_NAKED(1, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D08__GPIO_1_8 MXS_IOMUX_PAD_NAKED(1, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D09__GPIO_1_9 MXS_IOMUX_PAD_NAKED(1, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D10__GPIO_1_10 MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D11__GPIO_1_11 MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D12__GPIO_1_12 MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D13__GPIO_1_13 MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D14__GPIO_1_14 MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D15__GPIO_1_15 MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D16__GPIO_1_16 MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D17__GPIO_1_17 MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D18__GPIO_1_18 MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D19__GPIO_1_19 MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D20__GPIO_1_20 MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D21__GPIO_1_21 MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D22__GPIO_1_22 MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_D23__GPIO_1_23 MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RD_E__GPIO_1_24 MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_WR_RWN__GPIO_1_25 MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RS__GPIO_1_26 MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_CS__GPIO_1_27 MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_VSYNC__GPIO_1_28 MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_HSYNC__GPIO_1_29 MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_DOTCLK__GPIO_1_30 MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_ENABLE__GPIO_1_31 MXS_IOMUX_PAD_NAKED(1, 31, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_SSP0_DATA0__GPIO_2_0 MXS_IOMUX_PAD_NAKED(2, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA1__GPIO_2_1 MXS_IOMUX_PAD_NAKED(2, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA2__GPIO_2_2 MXS_IOMUX_PAD_NAKED(2, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA3__GPIO_2_3 MXS_IOMUX_PAD_NAKED(2, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA4__GPIO_2_4 MXS_IOMUX_PAD_NAKED(2, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA5__GPIO_2_5 MXS_IOMUX_PAD_NAKED(2, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA6__GPIO_2_6 MXS_IOMUX_PAD_NAKED(2, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DATA7__GPIO_2_7 MXS_IOMUX_PAD_NAKED(2, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_CMD__GPIO_2_8 MXS_IOMUX_PAD_NAKED(2, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_DETECT__GPIO_2_9 MXS_IOMUX_PAD_NAKED(2, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP0_SCK__GPIO_2_10 MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_SCK__GPIO_2_12 MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_CMD__GPIO_2_13 MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_DATA0__GPIO_2_14 MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15 MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SCK__GPIO_2_16 MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_MOSI__GPIO_2_17 MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_MISO__GPIO_2_18 MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS0__GPIO_2_19 MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS1__GPIO_2_20 MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP2_SS2__GPIO_2_21 MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_SCK__GPIO_2_24 MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_MOSI__GPIO_2_25 MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_MISO__GPIO_2_26 MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SSP3_SS0__GPIO_2_27 MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_AUART0_RX__GPIO_3_0 MXS_IOMUX_PAD_NAKED(3, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_TX__GPIO_3_1 MXS_IOMUX_PAD_NAKED(3, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_CTS__GPIO_3_2 MXS_IOMUX_PAD_NAKED(3, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART0_RTS__GPIO_3_3 MXS_IOMUX_PAD_NAKED(3, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_RX__GPIO_3_4 MXS_IOMUX_PAD_NAKED(3, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_TX__GPIO_3_5 MXS_IOMUX_PAD_NAKED(3, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_CTS__GPIO_3_6 MXS_IOMUX_PAD_NAKED(3, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART1_RTS__GPIO_3_7 MXS_IOMUX_PAD_NAKED(3, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_RX__GPIO_3_8 MXS_IOMUX_PAD_NAKED(3, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_TX__GPIO_3_9 MXS_IOMUX_PAD_NAKED(3, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_CTS__GPIO_3_10 MXS_IOMUX_PAD_NAKED(3, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART2_RTS__GPIO_3_11 MXS_IOMUX_PAD_NAKED(3, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_RX__GPIO_3_12 MXS_IOMUX_PAD_NAKED(3, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_TX__GPIO_3_13 MXS_IOMUX_PAD_NAKED(3, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_CTS__GPIO_3_14 MXS_IOMUX_PAD_NAKED(3, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_AUART3_RTS__GPIO_3_15 MXS_IOMUX_PAD_NAKED(3, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM0__GPIO_3_16 MXS_IOMUX_PAD_NAKED(3, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM1__GPIO_3_17 MXS_IOMUX_PAD_NAKED(3, 17, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM2__GPIO_3_18 MXS_IOMUX_PAD_NAKED(3, 18, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_MCLK__GPIO_3_20 MXS_IOMUX_PAD_NAKED(3, 20, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_LRCLK__GPIO_3_21 MXS_IOMUX_PAD_NAKED(3, 21, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_BITCLK__GPIO_3_22 MXS_IOMUX_PAD_NAKED(3, 22, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF0_SDATA0__GPIO_3_23 MXS_IOMUX_PAD_NAKED(3, 23, PAD_MUXSEL_GPIO)
+#define MX28_PAD_I2C0_SCL__GPIO_3_24 MXS_IOMUX_PAD_NAKED(3, 24, PAD_MUXSEL_GPIO)
+#define MX28_PAD_I2C0_SDA__GPIO_3_25 MXS_IOMUX_PAD_NAKED(3, 25, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SAIF1_SDATA0__GPIO_3_26 MXS_IOMUX_PAD_NAKED(3, 26, PAD_MUXSEL_GPIO)
+#define MX28_PAD_SPDIF__GPIO_3_27 MXS_IOMUX_PAD_NAKED(3, 27, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM3__GPIO_3_28 MXS_IOMUX_PAD_NAKED(3, 28, PAD_MUXSEL_GPIO)
+#define MX28_PAD_PWM4__GPIO_3_29 MXS_IOMUX_PAD_NAKED(3, 29, PAD_MUXSEL_GPIO)
+#define MX28_PAD_LCD_RESET__GPIO_3_30 MXS_IOMUX_PAD_NAKED(3, 30, PAD_MUXSEL_GPIO)
+
+#define MX28_PAD_ENET0_MDC__GPIO_4_0 MXS_IOMUX_PAD_NAKED(4, 0, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_MDIO__GPIO_4_1 MXS_IOMUX_PAD_NAKED(4, 1, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RX_EN__GPIO_4_2 MXS_IOMUX_PAD_NAKED(4, 2, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD0__GPIO_4_3 MXS_IOMUX_PAD_NAKED(4, 3, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD1__GPIO_4_4 MXS_IOMUX_PAD_NAKED(4, 4, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TX_CLK__GPIO_4_5 MXS_IOMUX_PAD_NAKED(4, 5, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TX_EN__GPIO_4_6 MXS_IOMUX_PAD_NAKED(4, 6, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD0__GPIO_4_7 MXS_IOMUX_PAD_NAKED(4, 7, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD1__GPIO_4_8 MXS_IOMUX_PAD_NAKED(4, 8, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD2__GPIO_4_9 MXS_IOMUX_PAD_NAKED(4, 9, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RXD3__GPIO_4_10 MXS_IOMUX_PAD_NAKED(4, 10, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD2__GPIO_4_11 MXS_IOMUX_PAD_NAKED(4, 11, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_TXD3__GPIO_4_12 MXS_IOMUX_PAD_NAKED(4, 12, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 MXS_IOMUX_PAD_NAKED(4, 13, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_COL__GPIO_4_14 MXS_IOMUX_PAD_NAKED(4, 14, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET0_CRS__GPIO_4_15 MXS_IOMUX_PAD_NAKED(4, 15, PAD_MUXSEL_GPIO)
+#define MX28_PAD_ENET_CLK__GPIO_4_16 MXS_IOMUX_PAD_NAKED(4, 16, PAD_MUXSEL_GPIO)
+#define MX28_PAD_JTAG_RTCK__GPIO_4_20 MXS_IOMUX_PAD_NAKED(4, 20, PAD_MUXSEL_GPIO)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 00000000..7abdf58b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+/*
+ * IOMUX/PAD Bit field definitions
+ *
+ * PAD_BANK: 0..2 (3)
+ * PAD_PIN: 3..7 (5)
+ * PAD_MUXSEL: 8..9 (2)
+ * PAD_MA: 10..11 (2)
+ * PAD_MA_VALID: 12 (1)
+ * PAD_VOL: 13 (1)
+ * PAD_VOL_VALID: 14 (1)
+ * PAD_PULL: 15 (1)
+ * PAD_PULL_VALID: 16 (1)
+ * RESERVED: 17..31 (15)
+ */
+typedef u32 iomux_cfg_t;
+
+#define MXS_PAD_BANK_SHIFT 0
+#define MXS_PAD_BANK_MASK ((iomux_cfg_t)0x7 << MXS_PAD_BANK_SHIFT)
+#define MXS_PAD_PIN_SHIFT 3
+#define MXS_PAD_PIN_MASK ((iomux_cfg_t)0x1f << MXS_PAD_PIN_SHIFT)
+#define MXS_PAD_MUXSEL_SHIFT 8
+#define MXS_PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MUXSEL_SHIFT)
+#define MXS_PAD_MA_SHIFT 10
+#define MXS_PAD_MA_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MA_SHIFT)
+#define MXS_PAD_MA_VALID_SHIFT 12
+#define MXS_PAD_MA_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_MA_VALID_SHIFT)
+#define MXS_PAD_VOL_SHIFT 13
+#define MXS_PAD_VOL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_SHIFT)
+#define MXS_PAD_VOL_VALID_SHIFT 14
+#define MXS_PAD_VOL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_VOL_VALID_SHIFT)
+#define MXS_PAD_PULL_SHIFT 15
+#define MXS_PAD_PULL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_SHIFT)
+#define MXS_PAD_PULL_VALID_SHIFT 16
+#define MXS_PAD_PULL_VALID_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_VALID_SHIFT)
+
+#define PAD_MUXSEL_0 0
+#define PAD_MUXSEL_1 1
+#define PAD_MUXSEL_2 2
+#define PAD_MUXSEL_GPIO 3
+
+#define PAD_4MA 0
+#define PAD_8MA 1
+#define PAD_12MA 2
+#define PAD_16MA 3
+
+#define PAD_1V8 0
+#define PAD_3V3 1
+
+#define PAD_NOPULL 0
+#define PAD_PULLUP 1
+
+#define MXS_PAD_4MA ((PAD_4MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_8MA ((PAD_8MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_12MA ((PAD_12MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+#define MXS_PAD_16MA ((PAD_16MA << MXS_PAD_MA_SHIFT) | \
+ MXS_PAD_MA_VALID_MASK)
+
+#define MXS_PAD_1V8 ((PAD_1V8 << MXS_PAD_VOL_SHIFT) | \
+ MXS_PAD_VOL_VALID_MASK)
+#define MXS_PAD_3V3 ((PAD_3V3 << MXS_PAD_VOL_SHIFT) | \
+ MXS_PAD_VOL_VALID_MASK)
+
+#define MXS_PAD_NOPULL ((PAD_NOPULL << MXS_PAD_PULL_SHIFT) | \
+ MXS_PAD_PULL_VALID_MASK)
+#define MXS_PAD_PULLUP ((PAD_PULLUP << MXS_PAD_PULL_SHIFT) | \
+ MXS_PAD_PULL_VALID_MASK)
+
+/* generic pad control used in most cases */
+#define MXS_PAD_CTRL (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL)
+
+#define MXS_IOMUX_PAD(_bank, _pin, _muxsel, _ma, _vol, _pull) \
+ (((iomux_cfg_t)(_bank) << MXS_PAD_BANK_SHIFT) | \
+ ((iomux_cfg_t)(_pin) << MXS_PAD_PIN_SHIFT) | \
+ ((iomux_cfg_t)(_muxsel) << MXS_PAD_MUXSEL_SHIFT) | \
+ ((iomux_cfg_t)(_ma) << MXS_PAD_MA_SHIFT) | \
+ ((iomux_cfg_t)(_vol) << MXS_PAD_VOL_SHIFT) | \
+ ((iomux_cfg_t)(_pull) << MXS_PAD_PULL_SHIFT))
+
+/*
+ * A pad becomes naked, when none of mA, vol or pull
+ * validity bits is set.
+ */
+#define MXS_IOMUX_PAD_NAKED(_bank, _pin, _muxsel) \
+ MXS_IOMUX_PAD(_bank, _pin, _muxsel, 0, 0, 0)
+
+static inline unsigned int PAD_BANK(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_BANK_MASK) >> MXS_PAD_BANK_SHIFT;
+}
+
+static inline unsigned int PAD_PIN(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PIN_MASK) >> MXS_PAD_PIN_SHIFT;
+}
+
+static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MUXSEL_MASK) >> MXS_PAD_MUXSEL_SHIFT;
+}
+
+static inline unsigned int PAD_MA(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MA_MASK) >> MXS_PAD_MA_SHIFT;
+}
+
+static inline unsigned int PAD_MA_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MA_VALID_MASK) >> MXS_PAD_MA_VALID_SHIFT;
+}
+
+static inline unsigned int PAD_VOL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_VOL_MASK) >> MXS_PAD_VOL_SHIFT;
+}
+
+static inline unsigned int PAD_VOL_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_VOL_VALID_MASK) >> MXS_PAD_VOL_VALID_SHIFT;
+}
+
+static inline unsigned int PAD_PULL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PULL_MASK) >> MXS_PAD_PULL_SHIFT;
+}
+
+static inline unsigned int PAD_PULL_VALID(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PULL_VALID_MASK) >> MXS_PAD_PULL_VALID_SHIFT;
+}
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad);
+
+/*
+ * configures multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 00000000..f771039b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 00000000..b5420a5c
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mmc.h b/arch/arm/mach-mxs/include/mach/mmc.h
new file mode 100644
index 00000000..211547a0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mmc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_MMC_H__
+#define __MACH_MXS_MMC_H__
+
+struct mxs_mmc_platform_data {
+ int wp_gpio; /* write protect pin */
+ unsigned int flags;
+#define SLOTF_4_BIT_CAPABLE (1 << 0)
+#define SLOTF_8_BIT_CAPABLE (1 << 1)
+};
+#endif /* __MACH_MXS_MMC_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 00000000..599094bc
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP1_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_AUART1_TX_DMA 23
+#define MX23_INT_AUART1 24
+#define MX23_INT_AUART1_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_AUART2_TX_DMA 58
+#define MX23_INT_AUART2 59
+#define MX23_INT_AUART2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+/*
+ * APBH DMA
+ */
+#define MX23_DMA_SSP1 1
+#define MX23_DMA_SSP2 2
+#define MX23_DMA_GPMI0 4
+#define MX23_DMA_GPMI1 5
+#define MX23_DMA_GPMI2 6
+#define MX23_DMA_GPMI3 7
+
+/*
+ * APBX DMA
+ */
+#define MX23_DMA_ADC 0
+#define MX23_DMA_DAC 1
+#define MX23_DMA_SPDIF 2
+#define MX23_DMA_I2C 3
+#define MX23_DMA_SAIF0 4
+#define MX23_DMA_UART0_RX 6
+#define MX23_DMA_UART0_TX 7
+#define MX23_DMA_UART1_RX 8
+#define MX23_DMA_UART1_TX 9
+#define MX23_DMA_SAIF1 10
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 00000000..75d86118
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR 0x00000000
+#define MX28_OCRAM_SIZE SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR 0x80000000
+#define MX28_IO_SIZE SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR (MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR (MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR (MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR (MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR (MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR (MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR (MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR (MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR (MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR (MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR (MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT 0
+#define MX28_INT_VDDD_BRNOUT 1
+#define MX28_INT_VDDIO_BRNOUT 2
+#define MX28_INT_VDDA_BRNOUT 3
+#define MX28_INT_VDD5V_DROOP 4
+#define MX28_INT_DCDC4P2_BRNOUT 5
+#define MX28_INT_VDD5V 6
+#define MX28_INT_CAN0 8
+#define MX28_INT_CAN1 9
+#define MX28_INT_LRADC_TOUCH 10
+#define MX28_INT_HSADC 13
+#define MX28_INT_IRADC_THRESH0 14
+#define MX28_INT_IRADC_THRESH1 15
+#define MX28_INT_LRADC_CH0 16
+#define MX28_INT_LRADC_CH1 17
+#define MX28_INT_LRADC_CH2 18
+#define MX28_INT_LRADC_CH3 19
+#define MX28_INT_LRADC_CH4 20
+#define MX28_INT_LRADC_CH5 21
+#define MX28_INT_LRADC_CH6 22
+#define MX28_INT_LRADC_CH7 23
+#define MX28_INT_LRADC_BUTTON0 24
+#define MX28_INT_LRADC_BUTTON1 25
+#define MX28_INT_PERFMON 27
+#define MX28_INT_RTC_1MSEC 28
+#define MX28_INT_RTC_ALARM 29
+#define MX28_INT_COMMS 31
+#define MX28_INT_EMI_ERR 32
+#define MX28_INT_LCDIF 38
+#define MX28_INT_PXP 39
+#define MX28_INT_BCH 41
+#define MX28_INT_GPMI 42
+#define MX28_INT_SPDIF_ERROR 45
+#define MX28_INT_DUART 47
+#define MX28_INT_TIMER0 48
+#define MX28_INT_TIMER1 49
+#define MX28_INT_TIMER2 50
+#define MX28_INT_TIMER3 51
+#define MX28_INT_DCP_VMI 52
+#define MX28_INT_DCP 53
+#define MX28_INT_DCP_SECURE 54
+#define MX28_INT_SAIF1 58
+#define MX28_INT_SAIF0 59
+#define MX28_INT_SPDIF_DMA 66
+#define MX28_INT_I2C0_DMA 68
+#define MX28_INT_I2C1_DMA 69
+#define MX28_INT_AUART0_RX_DMA 70
+#define MX28_INT_AUART0_TX_DMA 71
+#define MX28_INT_AUART1_RX_DMA 72
+#define MX28_INT_AUART1_TX_DMA 73
+#define MX28_INT_AUART2_RX_DMA 74
+#define MX28_INT_AUART2_TX_DMA 75
+#define MX28_INT_AUART3_RX_DMA 76
+#define MX28_INT_AUART3_TX_DMA 77
+#define MX28_INT_AUART4_RX_DMA 78
+#define MX28_INT_AUART4_TX_DMA 79
+#define MX28_INT_SAIF0_DMA 80
+#define MX28_INT_SAIF1_DMA 81
+#define MX28_INT_SSP0_DMA 82
+#define MX28_INT_SSP1_DMA 83
+#define MX28_INT_SSP2_DMA 84
+#define MX28_INT_SSP3_DMA 85
+#define MX28_INT_LCDIF_DMA 86
+#define MX28_INT_HSADC_DMA 87
+#define MX28_INT_GPMI_DMA 88
+#define MX28_INT_DIGCTL_DEBUG_TRAP 89
+#define MX28_INT_USB1 92
+#define MX28_INT_USB0 93
+#define MX28_INT_USB1_WAKEUP 94
+#define MX28_INT_USB0_WAKEUP 95
+#define MX28_INT_SSP0_ERROR 96
+#define MX28_INT_SSP1_ERROR 97
+#define MX28_INT_SSP2_ERROR 98
+#define MX28_INT_SSP3_ERROR 99
+#define MX28_INT_ENET_SWI 100
+#define MX28_INT_ENET_MAC0 101
+#define MX28_INT_ENET_MAC1 102
+#define MX28_INT_ENET_MAC0_1588 103
+#define MX28_INT_ENET_MAC1_1588 104
+#define MX28_INT_I2C1_ERROR 110
+#define MX28_INT_I2C0_ERROR 111
+#define MX28_INT_AUART0 112
+#define MX28_INT_AUART1 113
+#define MX28_INT_AUART2 114
+#define MX28_INT_AUART3 115
+#define MX28_INT_AUART4 116
+#define MX28_INT_GPIO4 123
+#define MX28_INT_GPIO3 124
+#define MX28_INT_GPIO2 125
+#define MX28_INT_GPIO1 126
+#define MX28_INT_GPIO0 127
+
+/*
+ * APBH DMA
+ */
+#define MX28_DMA_SSP0 0
+#define MX28_DMA_SSP1 1
+#define MX28_DMA_SSP2 2
+#define MX28_DMA_SSP3 3
+#define MX28_DMA_GPMI0 4
+#define MX28_DMA_GPMI1 5
+#define MX28_DMA_GPMI2 6
+#define MX28_DMA_GPMI3 7
+#define MX28_DMA_GPMI4 8
+#define MX28_DMA_GPMI5 9
+#define MX28_DMA_GPMI6 10
+#define MX28_DMA_GPMI7 11
+#define MX28_DMA_HSADC 12
+#define MX28_DMA_LCDIF 13
+
+/*
+ * APBX DMA
+ */
+#define MX28_DMA_AUART4_RX 0
+#define MX28_DMA_AUART4_TX 1
+#define MX28_DMA_SPDIF_TX 2
+#define MX28_DMA_SAIF0 4
+#define MX28_DMA_SAIF1 5
+#define MX28_DMA_I2C0 6
+#define MX28_DMA_I2C1 7
+#define MX28_DMA_AUART0_RX 8
+#define MX28_DMA_AUART0_TX 9
+#define MX28_DMA_AUART1_RX 10
+#define MX28_DMA_AUART1_TX 11
+#define MX28_DMA_AUART2_RX 12
+#define MX28_DMA_AUART2_TX 13
+#define MX28_DMA_AUART3_RX 14
+#define MX28_DMA_AUART3_TX 15
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 00000000..1332f73c
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+/*
+ * MXS CPU types
+ */
+#define cpu_is_mx23() ( \
+ machine_is_mx23evk() || \
+ machine_is_stmp378x() || \
+ 0)
+#define cpu_is_mx28() ( \
+ machine_is_mx28evk() || \
+ machine_is_tx28() || \
+ 0)
+
+/*
+ * IO addresses common to MXS-based
+ */
+#define MXS_IO_BASE_ADDR 0x80000000
+#define MXS_IO_SIZE SZ_1M
+
+#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
+#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
+#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
+#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
+#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
+#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
+#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
+#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
+#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
+#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
+#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
+#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
+#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
+#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
+#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
+#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
+#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
+#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
+#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
+#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
+#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
+#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
+#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
+#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf50fffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 7) + \
+ (((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+#ifndef __ASSEMBLER__
+static inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_SET_ADDR);
+}
+
+static inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
+
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
+#endif
+
+#endif /* __MACH_MXS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxsfb.h b/arch/arm/mach-mxs/include/mach/mxsfb.h
new file mode 100644
index 00000000..e4d79791
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxsfb.h
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_FB_H
+#define __MACH_FB_H
+
+#include <linux/fb.h>
+
+#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+#define FB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
+#define FB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */
+
+struct mxsfb_platform_data {
+ struct fb_videomode *mode_list;
+ unsigned mode_count;
+
+ unsigned default_bpp;
+
+ unsigned dotclk_delay; /* refer manual HW_LCDIF_VDCTRL4 register */
+ unsigned ld_intf_width; /* refer STMLCDIF_* macros */
+
+ unsigned fb_size; /* Size of the video memory. If zero a
+ * default will be used
+ */
+ unsigned long fb_phys; /* physical address for the video memory. If
+ * zero the framebuffer memory will be dynamically
+ * allocated. If specified,fb_size must also be specified.
+ * fb_phys must be unused by Linux.
+ */
+};
+
+#endif /* __MACH_FB_H */
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 00000000..0e428239
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 00000000..734ce898
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE 32000 /* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 00000000..7f8bf653
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@minirl.com)
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#include <asm/mach-types.h>
+
+unsigned long mxs_duart_base;
+
+#define MXS_DUART(x) (*(volatile unsigned long *)(mxs_duart_base + (x)))
+
+#define MXS_DUART_DR 0x00
+#define MXS_DUART_FR 0x18
+#define MXS_DUART_FR_TXFE (1 << 7)
+#define MXS_DUART_CR 0x30
+#define MXS_DUART_CR_UARTEN (1 << 0)
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If it's not, the output is
+ * simply discarded.
+ */
+
+static void putc(int ch)
+{
+ if (!mxs_duart_base)
+ return;
+ if (!(MXS_DUART(MXS_DUART_CR) & MXS_DUART_CR_UARTEN))
+ return;
+
+ while (!(MXS_DUART(MXS_DUART_FR) & MXS_DUART_FR_TXFE))
+ barrier();
+
+ MXS_DUART(MXS_DUART_DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR 0x80070000
+#define MX28_DUART_BASE_ADDR 0x80074000
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX23EVK:
+ mxs_duart_base = MX23_DUART_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX28EVK:
+ case MACH_TYPE_TX28:
+ mxs_duart_base = MX28_DUART_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 00000000..103b0165
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 00000000..0e804e2f
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mxs.h>
+#include <mach/iomux.h>
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+ u32 reg, ofs, bp, bm;
+ void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
+
+ /* muxsel */
+ ofs = 0x100;
+ ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+ bp = PAD_PIN(pad) % 16 * 2;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MUXSEL(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+
+ /* drive */
+ ofs = cpu_is_mx23() ? 0x200 : 0x300;
+ ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+ /* mA */
+ if (PAD_MA_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MA(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+ }
+ /* vol */
+ if (PAD_VOL_VALID(pad)) {
+ bp = PAD_PIN(pad) % 8 * 4 + 2;
+ if (PAD_VOL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, iomux_base + ofs);
+ }
+
+ /* pull */
+ if (PAD_PULL_VALID(pad)) {
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ if (PAD_PULL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, iomux_base + ofs);
+ }
+
+ return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+ const iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 00000000..5cdeb12e
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+#define MX23EVK_LCD_ENABLE MXS_GPIO_NR(1, 18)
+#define MX23EVK_BL_ENABLE MXS_GPIO_NR(1, 28)
+#define MX23EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER MXS_GPIO_NR(1, 29)
+
+static const iomux_cfg_t mx23evk_pads[] __initconst = {
+ /* duart */
+ MX23_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
+ MX23_PAD_PWM1__DUART_TX | MXS_PAD_CTRL,
+
+ /* auart */
+ MX23_PAD_AUART1_RX__AUART1_RX | MXS_PAD_CTRL,
+ MX23_PAD_AUART1_TX__AUART1_TX | MXS_PAD_CTRL,
+ MX23_PAD_AUART1_CTS__AUART1_CTS | MXS_PAD_CTRL,
+ MX23_PAD_AUART1_RTS__AUART1_RTS | MXS_PAD_CTRL,
+
+ /* mxsfb (lcdif) */
+ MX23_PAD_LCD_D00__LCD_D00 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D01__LCD_D01 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D02__LCD_D02 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D03__LCD_D03 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D04__LCD_D04 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D05__LCD_D05 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D06__LCD_D06 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D07__LCD_D07 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D08__LCD_D08 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D09__LCD_D09 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D10__LCD_D10 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D11__LCD_D11 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D12__LCD_D12 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D13__LCD_D13 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D14__LCD_D14 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D15__LCD_D15 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D16__LCD_D16 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_D17__LCD_D17 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D08__LCD_D18 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D09__LCD_D19 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D10__LCD_D20 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D11__LCD_D21 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D12__LCD_D22 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D13__LCD_D23 | MXS_PAD_CTRL,
+ MX23_PAD_LCD_VSYNC__LCD_VSYNC | MXS_PAD_CTRL,
+ MX23_PAD_LCD_HSYNC__LCD_HSYNC | MXS_PAD_CTRL,
+ MX23_PAD_LCD_DOTCK__LCD_DOTCK | MXS_PAD_CTRL,
+ MX23_PAD_LCD_ENABLE__LCD_ENABLE | MXS_PAD_CTRL,
+ /* LCD panel enable */
+ MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,
+ /* backlight control */
+ MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL,
+
+ /* mmc */
+ MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D08__SSP1_DATA4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D09__SSP1_DATA5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D10__SSP1_DATA6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D11__SSP1_DATA7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_CMD__SSP1_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX23_PAD_SSP1_SCK__SSP1_SCK |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX23_PAD_PWM4__GPIO_1_30 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX23_PAD_PWM3__GPIO_1_29 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* gpmi-nfc */
+#define MXS_PAD_GPMI_NFC (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL)
+static iomux_cfg_t mx23evk_gpmi_nfc_pads[] = {
+ MX23_PAD_GPMI_D00__GPMI_D00 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D01__GPMI_D01 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D02__GPMI_D02 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D03__GPMI_D03 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D04__GPMI_D04 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D05__GPMI_D05 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D06__GPMI_D06 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_D07__GPMI_D07 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_CLE__GPMI_CLE | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_ALE__GPMI_ALE | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_WPN__GPMI_WPN | MXS_PAD_GPMI_NFC,
+ MX23_PAD_GPMI_WRN__GPMI_WRN | MXS_PAD_GPMI_NFC,
+ MX23_PAD_GPMI_RDN__GPMI_RDN | MXS_PAD_GPMI_NFC,
+ MX23_PAD_GPMI_RDY0__GPMI_RDY0 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_RDY1__GPMI_RDY1 | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_CE0N__GPMI_CE0N | MXS_PAD_CTRL,
+ MX23_PAD_GPMI_CE1N__GPMI_CE1N | MXS_PAD_CTRL,
+};
+
+static int mx23evk_gpmi_nfc_platform_init(void)
+{
+ return mxs_iomux_setup_multiple_pads(mx23evk_gpmi_nfc_pads,
+ ARRAY_SIZE(mx23evk_gpmi_nfc_pads));
+}
+
+static const
+struct gpmi_nfc_platform_data mx23evk_gpmi_nfc_data __initconst = {
+ .platform_init = mx23evk_gpmi_nfc_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+};
+
+/* mxsfb (lcdif) */
+static struct fb_videomode mx23evk_video_modes[] = {
+ {
+ .name = "Samsung-LMS430HF02",
+ .refresh = 60,
+ .xres = 480,
+ .yres = 272,
+ .pixclock = 108096, /* picosecond (9.2 MHz) */
+ .left_margin = 15,
+ .right_margin = 8,
+ .upper_margin = 12,
+ .lower_margin = 4,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT |
+ FB_SYNC_DOTCLK_FAILING_ACT,
+ },
+};
+
+static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = {
+ .mode_list = mx23evk_video_modes,
+ .mode_count = ARRAY_SIZE(mx23evk_video_modes),
+ .default_bpp = 32,
+ .ld_intf_width = STMLCDIF_24BIT,
+};
+
+static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = {
+ .wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+};
+
+static void __init mx23evk_init(void)
+{
+ int ret;
+
+ mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+ mx23_add_duart();
+ mx23_add_auart0();
+
+ /* power on mmc slot by writing 0 to the gpio */
+ ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
+ "mmc0-slot-power");
+ if (ret)
+ pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+ mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata);
+
+ ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
+ if (ret)
+ pr_warn("failed to request gpio lcd-enable: %d\n", ret);
+ else
+ gpio_set_value(MX23EVK_LCD_ENABLE, 1);
+
+ ret = gpio_request_one(MX23EVK_BL_ENABLE, GPIOF_DIR_OUT, "bl-enable");
+ if (ret)
+ pr_warn("failed to request gpio bl-enable: %d\n", ret);
+ else
+ gpio_set_value(MX23EVK_BL_ENABLE, 1);
+
+ mx23_add_gpmi_nfc(&mx23evk_gpmi_nfc_data);
+ mx23_add_mxsfb(&mx23evk_mxsfb_pdata);
+}
+
+static void __init mx23evk_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+ .init = mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = mx23evk_init,
+ .timer = &mx23evk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 00000000..78fe1a97
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FLEXCAN_SWITCH MXS_GPIO_NR(2, 13)
+#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
+#define MX28EVK_BL_ENABLE MXS_GPIO_NR(3, 18)
+#define MX28EVK_LCD_ENABLE MXS_GPIO_NR(3, 30)
+#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+#define MX28EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER MXS_GPIO_NR(3, 29)
+
+static const iomux_cfg_t mx28evk_pads[] __initconst = {
+ /* duart */
+ MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
+ MX28_PAD_PWM1__DUART_TX | MXS_PAD_CTRL,
+
+ /* auart0 */
+ MX28_PAD_AUART0_RX__AUART0_RX | MXS_PAD_CTRL,
+ MX28_PAD_AUART0_TX__AUART0_TX | MXS_PAD_CTRL,
+ MX28_PAD_AUART0_CTS__AUART0_CTS | MXS_PAD_CTRL,
+ MX28_PAD_AUART0_RTS__AUART0_RTS | MXS_PAD_CTRL,
+ /* auart3 */
+ MX28_PAD_AUART3_RX__AUART3_RX | MXS_PAD_CTRL,
+ MX28_PAD_AUART3_TX__AUART3_TX | MXS_PAD_CTRL,
+ MX28_PAD_AUART3_CTS__AUART3_CTS | MXS_PAD_CTRL,
+ MX28_PAD_AUART3_RTS__AUART3_RTS | MXS_PAD_CTRL,
+
+#define MXS_PAD_FEC (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP)
+ /* fec0 */
+ MX28_PAD_ENET0_MDC__ENET0_MDC | MXS_PAD_FEC,
+ MX28_PAD_ENET0_MDIO__ENET0_MDIO | MXS_PAD_FEC,
+ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MXS_PAD_FEC,
+ MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MXS_PAD_FEC,
+ MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MXS_PAD_FEC,
+ MX28_PAD_ENET_CLK__CLKCTRL_ENET | MXS_PAD_FEC,
+ /* fec1 */
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN | MXS_PAD_FEC,
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_COL__ENET1_TX_EN | MXS_PAD_FEC,
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0 | MXS_PAD_FEC,
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1 | MXS_PAD_FEC,
+ /* phy power line */
+ MX28_PAD_SSP1_DATA3__GPIO_2_15 | MXS_PAD_CTRL,
+ /* phy reset line */
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13 | MXS_PAD_CTRL,
+
+ /* flexcan0 */
+ MX28_PAD_GPMI_RDY2__CAN0_TX,
+ MX28_PAD_GPMI_RDY3__CAN0_RX,
+ /* flexcan1 */
+ MX28_PAD_GPMI_CE2N__CAN1_TX,
+ MX28_PAD_GPMI_CE3N__CAN1_RX,
+ /* transceiver power control */
+ MX28_PAD_SSP1_CMD__GPIO_2_13,
+
+ /* mxsfb (lcdif) */
+ MX28_PAD_LCD_D00__LCD_D0 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D01__LCD_D1 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D02__LCD_D2 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D03__LCD_D3 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D04__LCD_D4 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D05__LCD_D5 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D06__LCD_D6 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D07__LCD_D7 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D08__LCD_D8 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D09__LCD_D9 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D10__LCD_D10 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D11__LCD_D11 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D12__LCD_D12 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D13__LCD_D13 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D14__LCD_D14 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D15__LCD_D15 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D16__LCD_D16 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D17__LCD_D17 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D18__LCD_D18 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D19__LCD_D19 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D20__LCD_D20 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D21__LCD_D21 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D22__LCD_D22 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_D23__LCD_D23 | MXS_PAD_CTRL,
+ MX28_PAD_LCD_RD_E__LCD_VSYNC | MXS_PAD_CTRL,
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MXS_PAD_CTRL,
+ MX28_PAD_LCD_RS__LCD_DOTCLK | MXS_PAD_CTRL,
+ MX28_PAD_LCD_CS__LCD_ENABLE | MXS_PAD_CTRL,
+ /* LCD panel enable */
+ MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
+ /* backlight control */
+ MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL,
+ /* mmc0 */
+ MX28_PAD_SSP0_DATA0__SSP0_D0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA1__SSP0_D1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA2__SSP0_D2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA3__SSP0_D3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA4__SSP0_D4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA5__SSP0_D5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA6__SSP0_D6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA7__SSP0_D7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_CMD__SSP0_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_SSP0_SCK__SSP0_SCK |
+ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX28_PAD_SSP1_SCK__GPIO_2_12 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX28_PAD_PWM3__GPIO_3_28 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+ /* mmc1 */
+ MX28_PAD_GPMI_D00__SSP1_D0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D01__SSP1_D1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D02__SSP1_D2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D03__SSP1_D3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D04__SSP1_D4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D05__SSP1_D5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D06__SSP1_D6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D07__SSP1_D7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_RDY1__SSP1_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_GPMI_WRN__SSP1_SCK |
+ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX28_PAD_PWM4__GPIO_3_29 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* fec */
+static void __init mx28evk_fec_reset(void)
+{
+ int ret;
+ struct clk *clk;
+
+ /* Enable fec phy clock */
+ clk = clk_get_sys("pll2", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ /* Power up fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ /* Reset fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ mdelay(1);
+ gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static struct fec_platform_data mx28_fec_pdata[] __initdata = {
+ {
+ /* fec0 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ }, {
+ /* fec1 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ },
+};
+
+static int __init mx28evk_fec_get_mac(void)
+{
+ int i;
+ u32 val;
+ const u32 *ocotp = mxs_get_ocotp();
+
+ if (!ocotp)
+ goto error;
+
+ /*
+ * OCOTP only stores the last 4 octets for each mac address,
+ * so hard-code Freescale OUI (00:04:9f) here.
+ */
+ for (i = 0; i < 2; i++) {
+ val = ocotp[i * 4];
+ mx28_fec_pdata[i].mac[0] = 0x00;
+ mx28_fec_pdata[i].mac[1] = 0x04;
+ mx28_fec_pdata[i].mac[2] = 0x9f;
+ mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+ mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+ mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+ }
+
+ return 0;
+
+error:
+ pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+ return -ETIMEDOUT;
+}
+
+/*
+ * MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
+ */
+static int flexcan0_en, flexcan1_en;
+
+static void mx28evk_flexcan_switch(void)
+{
+ if (flexcan0_en || flexcan1_en)
+ gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 1);
+ else
+ gpio_set_value(MX28EVK_FLEXCAN_SWITCH, 0);
+}
+
+static void mx28evk_flexcan0_switch(int enable)
+{
+ flexcan0_en = enable;
+ mx28evk_flexcan_switch();
+}
+
+static void mx28evk_flexcan1_switch(int enable)
+{
+ flexcan1_en = enable;
+ mx28evk_flexcan_switch();
+}
+
+static const struct flexcan_platform_data
+ mx28evk_flexcan_pdata[] __initconst = {
+ {
+ .transceiver_switch = mx28evk_flexcan0_switch,
+ }, {
+ .transceiver_switch = mx28evk_flexcan1_switch,
+ }
+};
+
+/* gpmi-nfc */
+#define MXS_PAD_GPMI_NFC (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL)
+static iomux_cfg_t mx28evk_gpmi_nfc_pads[] = {
+ MX28_PAD_GPMI_D00__GPMI_D0 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D01__GPMI_D1 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D02__GPMI_D2 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D03__GPMI_D3 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D04__GPMI_D4 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D05__GPMI_D5 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D06__GPMI_D6 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_D07__GPMI_D7 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_ALE__GPMI_ALE | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_CLE__GPMI_CLE | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_CE0N__GPMI_CE0N | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_CE1N__GPMI_CE1N | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_RDY0__GPMI_READY0 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_RDY1__GPMI_READY1 | MXS_PAD_CTRL,
+ MX28_PAD_GPMI_RDN__GPMI_RDN | MXS_PAD_GPMI_NFC,
+ MX28_PAD_GPMI_WRN__GPMI_WRN | MXS_PAD_GPMI_NFC,
+ MX28_PAD_GPMI_RESETN__GPMI_RESETN | MXS_PAD_GPMI_NFC,
+};
+
+static int mx28evk_gpmi_nfc_platform_init(void)
+{
+ return mxs_iomux_setup_multiple_pads(mx28evk_gpmi_nfc_pads,
+ ARRAY_SIZE(mx28evk_gpmi_nfc_pads));
+}
+
+static const struct gpmi_nfc_platform_data
+mx28evk_gpmi_nfc_data __initconst = {
+ .platform_init = mx28evk_gpmi_nfc_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+};
+
+/* mxsfb (lcdif) */
+static struct fb_videomode mx28evk_video_modes[] = {
+ {
+ .name = "Seiko-43WVF1G",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 29851, /* picosecond (33.5 MHz) */
+ .left_margin = 89,
+ .right_margin = 164,
+ .upper_margin = 23,
+ .lower_margin = 10,
+ .hsync_len = 10,
+ .vsync_len = 10,
+ .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT |
+ FB_SYNC_DOTCLK_FAILING_ACT,
+ },
+};
+
+static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = {
+ .mode_list = mx28evk_video_modes,
+ .mode_count = ARRAY_SIZE(mx28evk_video_modes),
+ .default_bpp = 32,
+ .ld_intf_width = STMLCDIF_24BIT,
+};
+
+static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = {
+ {
+ /* mmc0 */
+ .wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+ }, {
+ /* mmc1 */
+ .wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+ },
+};
+
+static void __init mx28evk_init(void)
+{
+ int ret;
+
+ mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+ mx28_add_duart();
+ mx28_add_auart0();
+ mx28_add_auart3();
+
+ if (mx28evk_fec_get_mac())
+ pr_warn("%s: failed on fec mac setup\n", __func__);
+
+ mx28evk_fec_reset();
+ mx28_add_fec(0, &mx28_fec_pdata[0]);
+ mx28_add_fec(1, &mx28_fec_pdata[1]);
+
+ ret = gpio_request_one(MX28EVK_FLEXCAN_SWITCH, GPIOF_DIR_OUT,
+ "flexcan-switch");
+ if (ret) {
+ pr_err("failed to request gpio flexcan-switch: %d\n", ret);
+ } else {
+ mx28_add_flexcan(0, &mx28evk_flexcan_pdata[0]);
+ mx28_add_flexcan(1, &mx28evk_flexcan_pdata[1]);
+ }
+
+ ret = gpio_request_one(MX28EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
+ if (ret)
+ pr_warn("failed to request gpio lcd-enable: %d\n", ret);
+ else
+ gpio_set_value(MX28EVK_LCD_ENABLE, 1);
+
+ ret = gpio_request_one(MX28EVK_BL_ENABLE, GPIOF_DIR_OUT, "bl-enable");
+ if (ret)
+ pr_warn("failed to request gpio bl-enable: %d\n", ret);
+ else
+ gpio_set_value(MX28EVK_BL_ENABLE, 1);
+
+ mx28_add_gpmi_nfc(&mx28evk_gpmi_nfc_data);
+ mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+
+ /* power on mmc slot by writing 0 to the gpio */
+ ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
+ "mmc0-slot-power");
+ if (ret)
+ pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+ mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
+
+ ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
+ "mmc1-slot-power");
+ if (ret)
+ pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
+ mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+ mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+ .init = mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-stmp378x_devb.c b/arch/arm/mach-mxs/mach-stmp378x_devb.c
new file mode 100644
index 00000000..7f38d82b
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-stmp378x_devb.c
@@ -0,0 +1,120 @@
+/*
+ * board setup for STMP378x-Development-Board
+ *
+ * based on mx23evk board setup and information gained form the original
+ * plat-stmp based board setup, now converted to mach-mxs.
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+#define STMP378X_DEVB_MMC0_WRITE_PROTECT MXS_GPIO_NR(1, 30)
+#define STMP378X_DEVB_MMC0_SLOT_POWER MXS_GPIO_NR(1, 29)
+
+#define STMP378X_DEVB_PAD_AUART (MXS_PAD_4MA | MXS_PAD_1V8 | MXS_PAD_NOPULL)
+
+static const iomux_cfg_t stmp378x_dvb_pads[] __initconst = {
+ /* duart (extended setup missing in old boardcode, too */
+ MX23_PAD_PWM0__DUART_RX,
+ MX23_PAD_PWM1__DUART_TX,
+
+ /* auart */
+ MX23_PAD_AUART1_RX__AUART1_RX | STMP378X_DEVB_PAD_AUART,
+ MX23_PAD_AUART1_TX__AUART1_TX | STMP378X_DEVB_PAD_AUART,
+ MX23_PAD_AUART1_CTS__AUART1_CTS | STMP378X_DEVB_PAD_AUART,
+ MX23_PAD_AUART1_RTS__AUART1_RTS | STMP378X_DEVB_PAD_AUART,
+
+ /* mmc */
+ MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_CMD__SSP1_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX23_PAD_SSP1_SCK__SSP1_SCK |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX23_PAD_PWM4__GPIO_1_30 | MXS_PAD_CTRL, /* write protect */
+ MX23_PAD_PWM3__GPIO_1_29 | MXS_PAD_CTRL, /* power enable */
+};
+
+static struct mxs_mmc_platform_data stmp378x_dvb_mmc_pdata __initdata = {
+ .wp_gpio = STMP378X_DEVB_MMC0_WRITE_PROTECT,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
+ {
+ .modalias = "enc28j60",
+ .max_speed_hz = 6 * 1000 * 1000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = NULL,
+ },
+#endif
+};
+
+static void __init stmp378x_dvb_init(void)
+{
+ int ret;
+
+ mxs_iomux_setup_multiple_pads(stmp378x_dvb_pads,
+ ARRAY_SIZE(stmp378x_dvb_pads));
+
+ mx23_add_duart();
+ mx23_add_auart0();
+
+ /* power on mmc slot */
+ ret = gpio_request_one(STMP378X_DEVB_MMC0_SLOT_POWER,
+ GPIOF_OUT_INIT_LOW, "mmc0-slot-power");
+ if (ret)
+ pr_warn("could not power mmc (%d)\n", ret);
+
+ mx23_add_mxs_mmc(0, &stmp378x_dvb_mmc_pdata);
+
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
+static void __init stmp378x_dvb_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer stmp378x_dvb_timer = {
+ .init = stmp378x_dvb_timer_init,
+};
+
+MACHINE_START(STMP378X, "STMP378X")
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = stmp378x_dvb_init,
+ .timer = &stmp378x_dvb_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mach-tx28.c b/arch/arm/mach-mxs/mach-tx28.c
new file mode 100644
index 00000000..b65e3719
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-tx28.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010 <LW@KARO-electronics.de>
+ *
+ * based on: mach-mx28_evk.c
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation
+ */
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/i2c.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "module-tx28.h"
+
+#define TX28_STK5_GPIO_LED MXS_GPIO_NR(4, 10)
+
+static const iomux_cfg_t tx28_stk5v3_pads[] __initconst = {
+ /* LED */
+ MX28_PAD_ENET0_RXD3__GPIO_4_10 |
+ MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL,
+
+ /* framebuffer */
+#define LCD_MODE (MXS_PAD_3V3 | MXS_PAD_4MA)
+ MX28_PAD_LCD_D00__LCD_D0 | LCD_MODE,
+ MX28_PAD_LCD_D01__LCD_D1 | LCD_MODE,
+ MX28_PAD_LCD_D02__LCD_D2 | LCD_MODE,
+ MX28_PAD_LCD_D03__LCD_D3 | LCD_MODE,
+ MX28_PAD_LCD_D04__LCD_D4 | LCD_MODE,
+ MX28_PAD_LCD_D05__LCD_D5 | LCD_MODE,
+ MX28_PAD_LCD_D06__LCD_D6 | LCD_MODE,
+ MX28_PAD_LCD_D07__LCD_D7 | LCD_MODE,
+ MX28_PAD_LCD_D08__LCD_D8 | LCD_MODE,
+ MX28_PAD_LCD_D09__LCD_D9 | LCD_MODE,
+ MX28_PAD_LCD_D10__LCD_D10 | LCD_MODE,
+ MX28_PAD_LCD_D11__LCD_D11 | LCD_MODE,
+ MX28_PAD_LCD_D12__LCD_D12 | LCD_MODE,
+ MX28_PAD_LCD_D13__LCD_D13 | LCD_MODE,
+ MX28_PAD_LCD_D14__LCD_D14 | LCD_MODE,
+ MX28_PAD_LCD_D15__LCD_D15 | LCD_MODE,
+ MX28_PAD_LCD_D16__LCD_D16 | LCD_MODE,
+ MX28_PAD_LCD_D17__LCD_D17 | LCD_MODE,
+ MX28_PAD_LCD_D18__LCD_D18 | LCD_MODE,
+ MX28_PAD_LCD_D19__LCD_D19 | LCD_MODE,
+ MX28_PAD_LCD_D20__LCD_D20 | LCD_MODE,
+ MX28_PAD_LCD_D21__LCD_D21 | LCD_MODE,
+ MX28_PAD_LCD_D22__LCD_D22 | LCD_MODE,
+ MX28_PAD_LCD_D23__LCD_D23 | LCD_MODE,
+ MX28_PAD_LCD_RD_E__LCD_VSYNC | LCD_MODE,
+ MX28_PAD_LCD_WR_RWN__LCD_HSYNC | LCD_MODE,
+ MX28_PAD_LCD_RS__LCD_DOTCLK | LCD_MODE,
+ MX28_PAD_LCD_CS__LCD_CS | LCD_MODE,
+ MX28_PAD_LCD_VSYNC__LCD_VSYNC | LCD_MODE,
+ MX28_PAD_LCD_HSYNC__LCD_HSYNC | LCD_MODE,
+ MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | LCD_MODE,
+ MX28_PAD_LCD_ENABLE__GPIO_1_31 | LCD_MODE,
+ MX28_PAD_LCD_RESET__GPIO_3_30 | LCD_MODE,
+ MX28_PAD_PWM0__PWM_0 | LCD_MODE,
+
+ /* UART1 */
+ MX28_PAD_AUART0_CTS__DUART_RX,
+ MX28_PAD_AUART0_RTS__DUART_TX,
+ MX28_PAD_AUART0_TX__DUART_RTS,
+ MX28_PAD_AUART0_RX__DUART_CTS,
+
+ /* UART2 */
+ MX28_PAD_AUART1_RX__AUART1_RX,
+ MX28_PAD_AUART1_TX__AUART1_TX,
+ MX28_PAD_AUART1_RTS__AUART1_RTS,
+ MX28_PAD_AUART1_CTS__AUART1_CTS,
+
+ /* CAN */
+ MX28_PAD_GPMI_RDY2__CAN0_TX,
+ MX28_PAD_GPMI_RDY3__CAN0_RX,
+
+ /* I2C */
+ MX28_PAD_I2C0_SCL__I2C0_SCL,
+ MX28_PAD_I2C0_SDA__I2C0_SDA,
+
+ /* TSC2007 */
+ MX28_PAD_SAIF0_MCLK__GPIO_3_20 | MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP,
+
+ /* MMC0 */
+ MX28_PAD_SSP0_DATA0__SSP0_D0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA1__SSP0_D1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA2__SSP0_D2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA3__SSP0_D3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA4__SSP0_D4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA5__SSP0_D5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA6__SSP0_D6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA7__SSP0_D7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_CMD__SSP0_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_SSP0_SCK__SSP0_SCK |
+ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+static struct gpio_led tx28_stk5v3_leds[] = {
+ {
+ .name = "GPIO-LED",
+ .default_trigger = "heartbeat",
+ .gpio = TX28_STK5_GPIO_LED,
+ },
+};
+
+static const struct gpio_led_platform_data tx28_stk5v3_led_data __initconst = {
+ .leds = tx28_stk5v3_leds,
+ .num_leds = ARRAY_SIZE(tx28_stk5v3_leds),
+};
+
+static struct spi_board_info tx28_spi_board_info[] = {
+ {
+ .modalias = "spidev",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = (void *)SPI_GPIO_NO_CHIPSELECT,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static struct i2c_board_info tx28_stk5v3_i2c_boardinfo[] __initdata = {
+ {
+ I2C_BOARD_INFO("ds1339", 0x68),
+ },
+};
+
+static void __init tx28_stk5v3_init(void)
+{
+ mxs_iomux_setup_multiple_pads(tx28_stk5v3_pads,
+ ARRAY_SIZE(tx28_stk5v3_pads));
+
+ mx28_add_duart(); /* UART1 */
+ mx28_add_auart(1); /* UART2 */
+
+ tx28_add_fec0();
+ /* spi via ssp will be added when available */
+ spi_register_board_info(tx28_spi_board_info,
+ ARRAY_SIZE(tx28_spi_board_info));
+ mxs_add_platform_device("leds-gpio", 0, NULL, 0,
+ &tx28_stk5v3_led_data, sizeof(tx28_stk5v3_led_data));
+ mx28_add_mxs_i2c(0);
+ i2c_register_board_info(0, tx28_stk5v3_i2c_boardinfo,
+ ARRAY_SIZE(tx28_stk5v3_i2c_boardinfo));
+}
+
+static void __init tx28_timer_init(void)
+{
+ mx28_clocks_init();
+}
+
+static struct sys_timer tx28_timer = {
+ .init = tx28_timer_init,
+};
+
+MACHINE_START(TX28, "Ka-Ro electronics TX28 module")
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = tx28_stk5v3_init,
+ .timer = &tx28_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 00000000..5148cd64
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+ mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX23, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx23_map_io(void)
+{
+ iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+ icoll_init_irq();
+ mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 00000000..7e4cea32
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mx28.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX28, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx28_map_io(void)
+{
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq();
+ mx28_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c
new file mode 100644
index 00000000..0fcff470
--- /dev/null
+++ b/arch/arm/mach-mxs/module-tx28.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 <LW@KARO-electronics.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/fec.h>
+#include <linux/gpio.h>
+
+#include <mach/iomux-mx28.h>
+#include "../devices-mx28.h"
+
+#include "module-tx28.h"
+
+#define TX28_FEC_PHY_POWER MXS_GPIO_NR(3, 29)
+#define TX28_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {
+ /* PHY POWER */
+ MX28_PAD_PWM4__GPIO_3_29 |
+ MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
+ /* PHY RESET */
+ MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
+ MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
+ /* Mode strap pins 0-2 */
+ MX28_PAD_ENET0_RXD0__GPIO_4_3 |
+ MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
+ MX28_PAD_ENET0_RXD1__GPIO_4_4 |
+ MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
+ MX28_PAD_ENET0_RX_EN__GPIO_4_2 |
+ MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3,
+ /* nINT */
+ MX28_PAD_ENET0_TX_CLK__GPIO_4_5 |
+ MXS_PAD_4MA | MXS_PAD_NOPULL | MXS_PAD_3V3,
+
+ MX28_PAD_ENET0_MDC__GPIO_4_0,
+ MX28_PAD_ENET0_MDIO__GPIO_4_1,
+ MX28_PAD_ENET0_TX_EN__GPIO_4_6,
+ MX28_PAD_ENET0_TXD0__GPIO_4_7,
+ MX28_PAD_ENET0_TXD1__GPIO_4_8,
+ MX28_PAD_ENET_CLK__GPIO_4_16,
+};
+
+#define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
+static const iomux_cfg_t tx28_fec0_pads[] __initconst = {
+ MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
+ MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
+ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
+ MX28_PAD_ENET0_RXD0__ENET0_RXD0 | FEC_MODE,
+ MX28_PAD_ENET0_RXD1__ENET0_RXD1 | FEC_MODE,
+ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | FEC_MODE,
+ MX28_PAD_ENET0_TXD0__ENET0_TXD0 | FEC_MODE,
+ MX28_PAD_ENET0_TXD1__ENET0_TXD1 | FEC_MODE,
+ MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
+};
+
+static const iomux_cfg_t tx28_fec1_pads[] __initconst = {
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0,
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1,
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0,
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1,
+ MX28_PAD_ENET0_COL__ENET1_TX_EN,
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN,
+};
+
+static struct fec_platform_data tx28_fec0_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct fec_platform_data tx28_fec1_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+int __init tx28_add_fec0(void)
+{
+ int i, ret;
+
+ pr_debug("%s: Switching FEC PHY power off\n", __func__);
+ ret = mxs_iomux_setup_multiple_pads(tx28_fec_gpio_pads,
+ ARRAY_SIZE(tx28_fec_gpio_pads));
+ for (i = 0; i < ARRAY_SIZE(tx28_fec_gpio_pads); i++) {
+ unsigned int gpio = MXS_GPIO_NR(PAD_BANK(tx28_fec_gpio_pads[i]),
+ PAD_PIN(tx28_fec_gpio_pads[i]));
+
+ ret = gpio_request(gpio, "FEC");
+ if (ret) {
+ pr_err("Failed to request GPIO_%d_%d: %d\n",
+ PAD_BANK(tx28_fec_gpio_pads[i]),
+ PAD_PIN(tx28_fec_gpio_pads[i]), ret);
+ goto free_gpios;
+ }
+ ret = gpio_direction_output(gpio, 0);
+ if (ret) {
+ pr_err("Failed to set direction of GPIO_%d_%d to output: %d\n",
+ gpio / 32 + 1, gpio % 32, ret);
+ goto free_gpios;
+ }
+ }
+
+ /* Power up fec phy */
+ pr_debug("%s: Switching FEC PHY power on\n", __func__);
+ ret = gpio_direction_output(TX28_FEC_PHY_POWER, 1);
+ if (ret) {
+ pr_err("Failed to power on PHY: %d\n", ret);
+ goto free_gpios;
+ }
+ mdelay(26); /* 25ms according to data sheet */
+
+ /* nINT */
+ gpio_direction_input(MXS_GPIO_NR(4, 5));
+ /* Mode strap pins */
+ gpio_direction_output(MXS_GPIO_NR(4, 2), 1);
+ gpio_direction_output(MXS_GPIO_NR(4, 3), 1);
+ gpio_direction_output(MXS_GPIO_NR(4, 4), 1);
+
+ udelay(100); /* minimum assertion time for nRST */
+
+ pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
+ gpio_set_value(TX28_FEC_PHY_RESET, 1);
+
+ ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads,
+ ARRAY_SIZE(tx28_fec0_pads));
+ if (ret) {
+ pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
+ __func__, ret);
+ goto free_gpios;
+ }
+ pr_debug("%s: Registering FEC0 device\n", __func__);
+ mx28_add_fec(0, &tx28_fec0_data);
+ return 0;
+
+free_gpios:
+ while (--i >= 0) {
+ unsigned int gpio = MXS_GPIO_NR(PAD_BANK(tx28_fec_gpio_pads[i]),
+ PAD_PIN(tx28_fec_gpio_pads[i]));
+
+ gpio_free(gpio);
+ }
+
+ return ret;
+}
+
+int __init tx28_add_fec1(void)
+{
+ int ret;
+
+ ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads,
+ ARRAY_SIZE(tx28_fec1_pads));
+ if (ret) {
+ pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ pr_debug("%s: Registering FEC1 device\n", __func__);
+ mx28_add_fec(1, &tx28_fec1_data);
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/module-tx28.h b/arch/arm/mach-mxs/module-tx28.h
new file mode 100644
index 00000000..8ed42545
--- /dev/null
+++ b/arch/arm/mach-mxs/module-tx28.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+int __init tx28_add_fec0(void);
+int __init tx28_add_fec1(void);
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 00000000..54add60f
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <asm/processor.h> /* for cpu_relax() */
+
+#include <mach/mxs.h>
+
+#define OCOTP_WORD_OFFSET 0x20
+#define OCOTP_WORD_COUNT 0x20
+
+#define BM_OCOTP_CTRL_BUSY (1 << 8)
+#define BM_OCOTP_CTRL_ERROR (1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
+
+const u32 *mxs_get_ocotp(void)
+{
+ void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+ int timeout = 0x400;
+ size_t i;
+ static int once = 0;
+
+ if (once)
+ return ocotp_words;
+
+ mutex_lock(&ocotp_mutex);
+
+ /*
+ * clk_enable(hbus_clk) for ocotp can be skipped
+ * as it must be on when system is running.
+ */
+
+ /* try to clear ERROR bit */
+ __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+ /* check both BUSY and ERROR cleared */
+ while ((__raw_readl(ocotp_base) &
+ (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ /* open OCOTP banks for read */
+ __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ /* approximately wait 32 hclk cycles */
+ udelay(1);
+
+ /* poll BUSY bit becoming cleared */
+ timeout = 0x400;
+ while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ for (i = 0; i < OCOTP_WORD_COUNT; i++)
+ ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+ i * 0x10);
+
+ /* close banks for power saving */
+ __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ once = 1;
+
+ mutex_unlock(&ocotp_mutex);
+
+ return ocotp_words;
+
+error_unlock:
+ mutex_unlock(&ocotp_mutex);
+ pr_err("%s: timeout in reading OCOTP\n", __func__);
+ return NULL;
+}
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 00000000..fb042da2
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ arch_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+ .enter = mxs_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+ suspend_set_ops(&mxs_suspend_ops);
+ return 0;
+}
+device_initcall(mxs_pm_init);
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 00000000..0ea5c9d0
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,331 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+
+#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU (0x00000020)
+#define HW_CLKCTRL_CPU_SET (0x00000024)
+#define HW_CLKCTRL_CPU_CLR (0x00000028)
+#define HW_CLKCTRL_CPU_TOG (0x0000002c)
+
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS (0x00000030)
+#define HW_CLKCTRL_HBUS_SET (0x00000034)
+#define HW_CLKCTRL_HBUS_CLR (0x00000038)
+#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
+
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE 0x00100000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS (0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL (0x00000050)
+#define HW_CLKCTRL_XTAL_SET (0x00000054)
+#define HW_CLKCTRL_XTAL_CLR (0x00000058)
+#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_PIX (0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE 31
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP (0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE 31
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI (0x00000080)
+
+#define BP_CLKCTRL_GPMI_CLKGATE 31
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF (0x00000090)
+
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+
+#define HW_CLKCTRL_EMI (0x000000a0)
+
+#define BP_CLKCTRL_EMI_CLKGATE 31
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_IR (0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF (0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV (0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+
+#define HW_CLKCTRL_ETM (0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC (0x000000f0)
+#define HW_CLKCTRL_FRAC_SET (0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO 31
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x00000100)
+#define HW_CLKCTRL_FRAC1_SET (0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+
+#define HW_CLKCTRL_CLKSEQ (0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
+
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+
+#define HW_CLKCTRL_RESET (0x00000120)
+
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x00000130)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+
+#define HW_CLKCTRL_VERSION (0x00000140)
+
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 00000000..7d1b061d
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,486 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_H__
+
+#define HW_CLKCTRL_PLL0CTRL0 (0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER 0x00020000
+
+#define HW_CLKCTRL_PLL0CTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0 (0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET (0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR (0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG (0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI 0x80000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER 0x00020000
+
+#define HW_CLKCTRL_PLL1CTRL1 (0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0 (0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET (0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR (0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG (0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE 0x80000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B 0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER 0x00800000
+
+#define HW_CLKCTRL_CPU (0x00000050)
+#define HW_CLKCTRL_CPU_SET (0x00000054)
+#define HW_CLKCTRL_CPU_CLR (0x00000058)
+#define HW_CLKCTRL_CPU_TOG (0x0000005c)
+
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU 0x10000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN 0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL 16
+#define BM_CLKCTRL_CPU_DIV_XTAL 0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v) \
+ (((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT 0x00001000
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN 0x00000400
+#define BP_CLKCTRL_CPU_DIV_CPU 0
+#define BM_CLKCTRL_CPU_DIV_CPU 0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v) \
+ (((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS (0x00000060)
+#define HW_CLKCTRL_HBUS_SET (0x00000064)
+#define HW_CLKCTRL_HBUS_CLR (0x00000068)
+#define HW_CLKCTRL_HBUS_TOG (0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY 0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE 0x20000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE 0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE 0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE 0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE 0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE 0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE 0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE 0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE 0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE 0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV 16
+#define BM_CLKCTRL_HBUS_SLOW_DIV 0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1 0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2 0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4 0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8 0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN 0x00000020
+#define BP_CLKCTRL_HBUS_DIV 0
+#define BM_CLKCTRL_HBUS_DIV 0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS (0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE 0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_XBUS_DIV 0
+#define BM_CLKCTRL_XBUS_DIV 0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL (0x00000080)
+#define HW_CLKCTRL_XTAL_SET (0x00000084)
+#define HW_CLKCTRL_XTAL_CLR (0x00000088)
+#define HW_CLKCTRL_XTAL_TOG (0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE 0x04000000
+#define BP_CLKCTRL_XTAL_DIV_UART 0
+#define BM_CLKCTRL_XTAL_DIV_UART 0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v) \
+ (((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0 (0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE 31
+#define BM_CLKCTRL_SSP0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP0_BUSY 0x20000000
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP0_DIV 0
+#define BM_CLKCTRL_SSP0_DIV 0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1 (0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE 31
+#define BM_CLKCTRL_SSP1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP1_BUSY 0x20000000
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP1_DIV 0
+#define BM_CLKCTRL_SSP1_DIV 0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2 (0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE 31
+#define BM_CLKCTRL_SSP2_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP2_BUSY 0x20000000
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP2_DIV 0
+#define BM_CLKCTRL_SSP2_DIV 0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3 (0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE 31
+#define BM_CLKCTRL_SSP3_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP3_BUSY 0x20000000
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP3_DIV 0
+#define BM_CLKCTRL_SSP3_DIV 0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI (0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE 31
+#define BM_CLKCTRL_GPMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_GPMI_BUSY 0x20000000
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN 0x00000400
+#define BP_CLKCTRL_GPMI_DIV 0
+#define BM_CLKCTRL_GPMI_DIV 0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF (0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE 31
+#define BM_CLKCTRL_SPDIF_CLKGATE 0x80000000
+
+#define HW_CLKCTRL_EMI (0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE 31
+#define BM_CLKCTRL_EMI_CLKGATE 0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN 0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL 0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI 0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU 0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE 0x04000000
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC 0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE 0x00010000
+#define BP_CLKCTRL_EMI_DIV_XTAL 8
+#define BM_CLKCTRL_EMI_DIV_XTAL 0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v) \
+ (((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_DIV_EMI 0
+#define BM_CLKCTRL_EMI_DIV_EMI 0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v) \
+ (((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0 (0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE 31
+#define BM_CLKCTRL_SAIF0_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF0_BUSY 0x20000000
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF0_DIV 0
+#define BM_CLKCTRL_SAIF0_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1 (0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE 31
+#define BM_CLKCTRL_SAIF1_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF1_BUSY 0x20000000
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF1_DIV 0
+#define BM_CLKCTRL_SAIF1_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF (0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE 31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY 0x20000000
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN 0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV 0
+#define BM_CLKCTRL_DIS_LCDIF_DIV 0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM (0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000080
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET (0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP 0x80000000
+#define BP_CLKCTRL_ENET_DISABLE 30
+#define BM_CLKCTRL_ENET_DISABLE 0x40000000
+#define BM_CLKCTRL_ENET_STATUS 0x20000000
+#define BM_CLKCTRL_ENET_BUSY_TIME 0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME 21
+#define BM_CLKCTRL_ENET_DIV_TIME 0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY 0x08000000
+#define BP_CLKCTRL_ENET_DIV 21
+#define BM_CLKCTRL_ENET_DIV 0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v) \
+ (((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL 19
+#define BM_CLKCTRL_ENET_TIME_SEL 0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v) \
+ (((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL 0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL 0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK 0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN 0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP 0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW 0x00010000
+
+#define HW_CLKCTRL_HSADC (0x00000150)
+
+#define BM_CLKCTRL_HSADC_RESETB 0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV 28
+#define BM_CLKCTRL_HSADC_FREQDIV 0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v) \
+ (((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+
+#define HW_CLKCTRL_FLEXCAN (0x00000160)
+
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0 30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0 0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS 0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1 28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1 0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS 0x08000000
+
+#define HW_CLKCTRL_FRAC0 (0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET (0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR (0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG (0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0 31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0 0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC 24
+#define BM_CLKCTRL_FRAC0_IO0FRAC 0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1 23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1 0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC 16
+#define BM_CLKCTRL_FRAC0_IO1FRAC 0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC 8
+#define BM_CLKCTRL_FRAC0_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC 0
+#define BM_CLKCTRL_FRAC0_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET (0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR (0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG (0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI 23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI 0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC 16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC 15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC 0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC 8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX 7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX 0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC 0
+#define BM_CLKCTRL_FRAC1_PIXFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ (0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET (0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x000001dc)
+
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00040000
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF 0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD 0x0
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0 0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0 0x00000001
+
+#define HW_CLKCTRL_RESET (0x000001e0)
+
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE 0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE 0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE 0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT 0x00000004
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT 30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT 0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+ (((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+
+#define HW_CLKCTRL_VERSION (0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR 24
+#define BM_CLKCTRL_VERSION_MAJOR 0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR 16
+#define BM_CLKCTRL_VERSION_MINOR 0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v) \
+ (((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP 0
+#define BM_CLKCTRL_VERSION_STEP 0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v) \
+ (((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX28_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 00000000..20ec3bdd
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#define MX23_CLKCTRL_RESET_OFFSET 0x120
+#define MX28_CLKCTRL_RESET_OFFSET 0x1e0
+#define MXS_CLKCTRL_RESET_CHIP (1 << 1)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *mxs_clkctrl_reset_addr;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ /* reset the chip */
+ __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);
+
+ pr_err("Failed to assert the chip reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+static int __init mxs_arch_reset_init(void)
+{
+ struct clk *clk;
+
+ mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +
+ (cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :
+ MX28_CLKCTRL_RESET_OFFSET);
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ return 0;
+}
+core_initcall(mxs_arch_reset_init);
+
+/*
+ * Clear the bit and poll it cleared. This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+ int timeout = 0x400;
+
+ /* clear the bit */
+ __mxs_clrl(mask, addr);
+
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+
+ /* poll the bit becoming clear */
+ while ((__raw_readl(addr) & mask) && --timeout)
+ /* nothing */;
+
+ return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ int ret;
+ int timeout = 0x400;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear CLKGATE */
+ __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
+
+ /* set SFTRST to reset the block */
+ __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
+ udelay(1);
+
+ /* poll CLKGATE becoming set */
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (unlikely(!timeout))
+ goto error;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear and poll CLKGATE */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+ if (unlikely(ret))
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
+EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 00000000..cace0d2e
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timrot 0 and 1, while MX23
+ * uses 0 and 2.
+ */
+
+#define MX23_TIMROT_VERSION_OFFSET 0x0a0
+#define MX28_TIMROT_VERSION_OFFSET 0x120
+#define BP_TIMROT_MAJOR_VERSION 24
+#define BV_TIMROT_VERSION_1 0x01
+#define BV_TIMROT_VERSION_2 0x02
+#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
+
+/*
+ * There are 4 registers for each timrotv2 instance, and 2 registers
+ * for each timrotv1. So address step 0x40 in macros below strides
+ * one instance of timrotv2 while two instances of timrotv1.
+ *
+ * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
+ * on MX28 while timrot2 on MX23.
+ */
+/* common between v1 and v2 */
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+/* v1 only */
+#define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40)
+/* v2 only */
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
+
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+
+static struct clock_event_device mxs_clockevent_device;
+static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *mxs_timrot_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
+static u32 timrot_major_version;
+
+static inline void timrot_irq_disable(void)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+ return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
+ & 0xffff0000) >> 16);
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
+
+ return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
+
+ return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .dev_id = &mxs_clockevent_device,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] const = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != mxs_clockevent_mode) {
+ /* Set event time into the furthest future */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ pr_info("%s: changing mode from %s to %s\n", __func__,
+ clock_event_mode_label[mxs_clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ mxs_clockevent_mode = mode;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_err("%s: Periodic mode is not implemented\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ timrot_irq_enable();
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device mxs_clockevent_device = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrotv2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ mxs_clockevent_device.mult =
+ div_sc(c, NSEC_PER_SEC, mxs_clockevent_device.shift);
+ mxs_clockevent_device.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
+ mxs_clockevent_device.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &mxs_clockevent_device);
+ mxs_clockevent_device.min_delta_ns =
+ clockevent_delta2ns(0xf, &mxs_clockevent_device);
+ } else {
+ mxs_clockevent_device.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &mxs_clockevent_device);
+ mxs_clockevent_device.min_delta_ns =
+ clockevent_delta2ns(0xf, &mxs_clockevent_device);
+ }
+
+ clockevents_register_device(&mxs_clockevent_device);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrotv1_get_cycles,
+ .mask = CLOCKSOURCE_MASK(16),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1())
+ clocksource_register_hz(&clocksource_mxs, c);
+ else
+ clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
+ "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk, int irq)
+{
+ clk_enable(timer_clk);
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
+
+ /* get timrot version */
+ timrot_major_version = __raw_readl(mxs_timrot_base +
+ (cpu_is_mx23() ? MX23_TIMROT_VERSION_OFFSET :
+ MX28_TIMROT_VERSION_OFFSET));
+ timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
+
+ /* one for clock_event */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+
+ /* another for clocksource */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
+
+ /* set clocksource timer fixed count to the maximum */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig
new file mode 100644
index 00000000..3d90ef19
--- /dev/null
+++ b/arch/arm/mach-netx/Kconfig
@@ -0,0 +1,24 @@
+menu "NetX Implementations"
+ depends on ARCH_NETX
+
+config MACH_NXDKN
+ bool "Enable Hilscher nxdkn Eval Board support"
+ depends on ARCH_NETX
+ help
+ Board support for the Hilscher NetX Eval Board
+
+config MACH_NXDB500
+ bool "Enable Hilscher nxdb500 Eval Board support"
+ depends on ARCH_NETX
+ select ARM_AMBA
+ help
+ Board support for the Hilscher nxdb500 Eval Board
+
+config MACH_NXEB500HMI
+ bool "Enable Hilscher nxeb500hmi Eval Board support"
+ depends on ARCH_NETX
+ select ARM_AMBA
+ help
+ Board support for the Hilscher nxeb500hmi Eval Board
+
+endmenu
diff --git a/arch/arm/mach-netx/Makefile b/arch/arm/mach-netx/Makefile
new file mode 100644
index 00000000..7ce4ba9e
--- /dev/null
+++ b/arch/arm/mach-netx/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y += time.o generic.o pfifo.o xc.o
+
+# Specific board support
+obj-$(CONFIG_MACH_NXDKN) += nxdkn.o
+obj-$(CONFIG_MACH_NXDB500) += nxdb500.o fb.o
+obj-$(CONFIG_MACH_NXEB500HMI) += nxeb500hmi.o fb.o
diff --git a/arch/arm/mach-netx/Makefile.boot b/arch/arm/mach-netx/Makefile.boot
new file mode 100644
index 00000000..b81cf6af
--- /dev/null
+++ b/arch/arm/mach-netx/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x80008000
+
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
new file mode 100644
index 00000000..b9913234
--- /dev/null
+++ b/arch/arm/mach-netx/fb.c
@@ -0,0 +1,113 @@
+/*
+ * arch/arm/mach-netx/fb.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+
+#include <asm/irq.h>
+
+#include <mach/netx-regs.h>
+#include <mach/hardware.h>
+
+static struct clcd_panel *netx_panel;
+
+void netx_clcd_enable(struct clcd_fb *fb)
+{
+}
+
+int netx_clcd_setup(struct clcd_fb *fb)
+{
+ dma_addr_t dma;
+
+ fb->panel = netx_panel;
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, 1024*1024,
+ &dma, GFP_KERNEL);
+ if (!fb->fb.screen_base) {
+ printk(KERN_ERR "CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = 1024*1024;
+
+ return 0;
+}
+
+int netx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+void netx_clcd_remove(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+void clk_disable(struct clk *clk)
+{
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ return 0;
+}
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ return dev && strcmp(dev_name(dev), "fb") == 0 ? NULL : ERR_PTR(-ENOENT);
+}
+
+void clk_put(struct clk *clk)
+{
+}
+
+static struct amba_device fb_device = {
+ .dev = {
+ .init_name = "fb",
+ .coherent_dma_mask = ~0,
+ },
+ .res = {
+ .start = 0x00104000,
+ .end = 0x00104fff,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { NETX_IRQ_LCD, NO_IRQ },
+};
+
+int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
+{
+ netx_panel = panel;
+ fb_device.dev.platform_data = board;
+ return amba_device_register(&fb_device, &iomem_resource);
+}
diff --git a/arch/arm/mach-netx/fb.h b/arch/arm/mach-netx/fb.h
new file mode 100644
index 00000000..4919cf33
--- /dev/null
+++ b/arch/arm/mach-netx/fb.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-netx/fb.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+void netx_clcd_enable(struct clcd_fb *fb);
+int netx_clcd_setup(struct clcd_fb *fb);
+int netx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma);
+void netx_clcd_remove(struct clcd_fb *fb);
+int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel);
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
new file mode 100644
index 00000000..00023b5c
--- /dev/null
+++ b/arch/arm/mach-netx/generic.c
@@ -0,0 +1,189 @@
+/*
+ * arch/arm/mach-netx/generic.c
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/vic.h>
+#include <mach/netx-regs.h>
+#include <asm/mach/irq.h>
+
+static struct map_desc netx_io_desc[] __initdata = {
+ {
+ .virtual = NETX_IO_VIRT,
+ .pfn = __phys_to_pfn(NETX_IO_PHYS),
+ .length = NETX_IO_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+void __init netx_map_io(void)
+{
+ iotable_init(netx_io_desc, ARRAY_SIZE(netx_io_desc));
+}
+
+static struct resource netx_rtc_resources[] = {
+ [0] = {
+ .start = 0x00101200,
+ .end = 0x00101220,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device netx_rtc_device = {
+ .name = "netx-rtc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(netx_rtc_resources),
+ .resource = netx_rtc_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &netx_rtc_device,
+};
+
+#if 0
+#define DEBUG_IRQ(fmt...) printk(fmt)
+#else
+#define DEBUG_IRQ(fmt...) while (0) {}
+#endif
+
+static void
+netx_hif_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
+{
+ unsigned int irq = NETX_IRQ_HIF_CHAINED(0);
+ unsigned int stat;
+
+ stat = ((readl(NETX_DPMAS_INT_EN) &
+ readl(NETX_DPMAS_INT_STAT)) >> 24) & 0x1f;
+
+ while (stat) {
+ if (stat & 1) {
+ DEBUG_IRQ("handling irq %d\n", irq);
+ generic_handle_irq(irq);
+ }
+ irq++;
+ stat >>= 1;
+ }
+}
+
+static int
+netx_hif_irq_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int val, irq;
+
+ val = readl(NETX_DPMAS_IF_CONF1);
+
+ irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
+
+ if (type & IRQ_TYPE_EDGE_RISING) {
+ DEBUG_IRQ("rising edges\n");
+ val |= (1 << 26) << irq;
+ }
+ if (type & IRQ_TYPE_EDGE_FALLING) {
+ DEBUG_IRQ("falling edges\n");
+ val &= ~((1 << 26) << irq);
+ }
+ if (type & IRQ_TYPE_LEVEL_LOW) {
+ DEBUG_IRQ("low level\n");
+ val &= ~((1 << 26) << irq);
+ }
+ if (type & IRQ_TYPE_LEVEL_HIGH) {
+ DEBUG_IRQ("high level\n");
+ val |= (1 << 26) << irq;
+ }
+
+ writel(val, NETX_DPMAS_IF_CONF1);
+
+ return 0;
+}
+
+static void
+netx_hif_ack_irq(struct irq_data *d)
+{
+ unsigned int val, irq;
+
+ irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
+ writel((1 << 24) << irq, NETX_DPMAS_INT_STAT);
+
+ val = readl(NETX_DPMAS_INT_EN);
+ val &= ~((1 << 24) << irq);
+ writel(val, NETX_DPMAS_INT_EN);
+
+ DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
+}
+
+static void
+netx_hif_mask_irq(struct irq_data *d)
+{
+ unsigned int val, irq;
+
+ irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
+ val = readl(NETX_DPMAS_INT_EN);
+ val &= ~((1 << 24) << irq);
+ writel(val, NETX_DPMAS_INT_EN);
+ DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
+}
+
+static void
+netx_hif_unmask_irq(struct irq_data *d)
+{
+ unsigned int val, irq;
+
+ irq = d->irq - NETX_IRQ_HIF_CHAINED(0);
+ val = readl(NETX_DPMAS_INT_EN);
+ val |= (1 << 24) << irq;
+ writel(val, NETX_DPMAS_INT_EN);
+ DEBUG_IRQ("%s: irq %d\n", __func__, d->irq);
+}
+
+static struct irq_chip netx_hif_chip = {
+ .irq_ack = netx_hif_ack_irq,
+ .irq_mask = netx_hif_mask_irq,
+ .irq_unmask = netx_hif_unmask_irq,
+ .irq_set_type = netx_hif_irq_type,
+};
+
+void __init netx_init_irq(void)
+{
+ int irq;
+
+ vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0, 0);
+
+ for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
+ irq_set_chip_and_handler(irq, &netx_hif_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN);
+ irq_set_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
+}
+
+static int __init netx_init(void)
+{
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(netx_init);
+
diff --git a/arch/arm/mach-netx/generic.h b/arch/arm/mach-netx/generic.h
new file mode 100644
index 00000000..ede2d353
--- /dev/null
+++ b/arch/arm/mach-netx/generic.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-netx/generic.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+extern void __init netx_map_io(void);
+extern void __init netx_init_irq(void);
+
+struct sys_timer;
+extern struct sys_timer netx_timer;
diff --git a/arch/arm/mach-netx/include/mach/debug-macro.S b/arch/arm/mach-netx/include/mach/debug-macro.S
new file mode 100644
index 00000000..56a91522
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/debug-macro.S
@@ -0,0 +1,36 @@
+/* arch/arm/mach-netx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include "hardware.h"
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00000a00
+ orr \rv, \rp, #io_p2v(0x00100000) @ virtual
+ orr \rp, \rp, #0x00100000 @ physical
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0]
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #0x18]
+ tst \rd, #(1 << 3)
+ bne 1002b
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18]
+ tst \rd, #(1 << 3)
+ bne 1001b
+ .endm
diff --git a/arch/arm/mach-netx/include/mach/entry-macro.S b/arch/arm/mach-netx/include/mach/entry-macro.S
new file mode 100644
index 00000000..844f1f9a
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/entry-macro.S
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-netx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Hilscher netX based platforms
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =io_p2v(0x001ff000)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #0]
+ clz \irqnr, \irqstat
+ rsb \irqnr, \irqnr, #31
+ cmp \irqstat, #0
+ .endm
+
diff --git a/arch/arm/mach-netx/include/mach/eth.h b/arch/arm/mach-netx/include/mach/eth.h
new file mode 100644
index 00000000..88af1ac2
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/eth.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-netx/include/mach/eth.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef ASMARM_ARCH_ETH_H
+#define ASMARM_ARCH_ETH_H
+
+struct netxeth_platform_data {
+ unsigned int xcno; /* number of xmac/xpec engine this eth uses */
+};
+
+#endif
diff --git a/arch/arm/mach-netx/include/mach/hardware.h b/arch/arm/mach-netx/include/mach/hardware.h
new file mode 100644
index 00000000..517a2bd3
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/hardware.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-netx/include/mach/hardware.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#define NETX_IO_PHYS 0x00100000
+#define NETX_IO_VIRT 0xe0000000
+#define NETX_IO_SIZE 0x00100000
+
+#define SRAM_INTERNAL_PHYS_0 0x00000
+#define SRAM_INTERNAL_PHYS_1 0x08000
+#define SRAM_INTERNAL_PHYS_2 0x10000
+#define SRAM_INTERNAL_PHYS_3 0x18000
+#define SRAM_INTERNAL_PHYS(no) ((no) * 0x8000)
+
+#define XPEC_MEM_SIZE 0x4000
+#define XMAC_MEM_SIZE 0x1000
+#define SRAM_MEM_SIZE 0x8000
+
+#define io_p2v(x) ((x) - NETX_IO_PHYS + NETX_IO_VIRT)
+#define io_v2p(x) ((x) - NETX_IO_VIRT + NETX_IO_PHYS)
+
+#endif
diff --git a/arch/arm/mach-netx/include/mach/io.h b/arch/arm/mach-netx/include/mach/io.h
new file mode 100644
index 00000000..c3921cb3
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-netx/include/mach/io.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-netx/include/mach/irqs.h b/arch/arm/mach-netx/include/mach/irqs.h
new file mode 100644
index 00000000..6ce914d5
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/irqs.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-netx/include/mach/irqs.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define NETX_IRQ_VIC_START 0
+#define NETX_IRQ_SOFTINT 0
+#define NETX_IRQ_TIMER0 1
+#define NETX_IRQ_TIMER1 2
+#define NETX_IRQ_TIMER2 3
+#define NETX_IRQ_SYSTIME_NS 4
+#define NETX_IRQ_SYSTIME_S 5
+#define NETX_IRQ_GPIO_15 6
+#define NETX_IRQ_WATCHDOG 7
+#define NETX_IRQ_UART0 8
+#define NETX_IRQ_UART1 9
+#define NETX_IRQ_UART2 10
+#define NETX_IRQ_USB 11
+#define NETX_IRQ_SPI 12
+#define NETX_IRQ_I2C 13
+#define NETX_IRQ_LCD 14
+#define NETX_IRQ_HIF 15
+#define NETX_IRQ_GPIO_0_14 16
+#define NETX_IRQ_XPEC0 17
+#define NETX_IRQ_XPEC1 18
+#define NETX_IRQ_XPEC2 19
+#define NETX_IRQ_XPEC3 20
+#define NETX_IRQ_XPEC(no) (17 + (no))
+#define NETX_IRQ_MSYNC0 21
+#define NETX_IRQ_MSYNC1 22
+#define NETX_IRQ_MSYNC2 23
+#define NETX_IRQ_MSYNC3 24
+#define NETX_IRQ_IRQ_PHY 25
+#define NETX_IRQ_ISO_AREA 26
+/* int 27 is reserved */
+/* int 28 is reserved */
+#define NETX_IRQ_TIMER3 29
+#define NETX_IRQ_TIMER4 30
+/* int 31 is reserved */
+
+#define NETX_IRQS 32
+
+/* for multiplexed irqs on gpio 0..14 */
+#define NETX_IRQ_GPIO(x) (NETX_IRQS + (x))
+#define NETX_IRQ_GPIO_LAST NETX_IRQ_GPIO(14)
+
+/* Host interface interrupts */
+#define NETX_IRQ_HIF_CHAINED(x) (NETX_IRQ_GPIO_LAST + 1 + (x))
+#define NETX_IRQ_HIF_PIO35 NETX_IRQ_HIF_CHAINED(0)
+#define NETX_IRQ_HIF_PIO36 NETX_IRQ_HIF_CHAINED(1)
+#define NETX_IRQ_HIF_PIO40 NETX_IRQ_HIF_CHAINED(2)
+#define NETX_IRQ_HIF_PIO47 NETX_IRQ_HIF_CHAINED(3)
+#define NETX_IRQ_HIF_PIO72 NETX_IRQ_HIF_CHAINED(4)
+#define NETX_IRQ_HIF_LAST NETX_IRQ_HIF_CHAINED(4)
+
+#define NR_IRQS (NETX_IRQ_HIF_LAST + 1)
diff --git a/arch/arm/mach-netx/include/mach/memory.h b/arch/arm/mach-netx/include/mach/memory.h
new file mode 100644
index 00000000..59561496
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/memory.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-netx/include/mach/memory.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x80000000)
+
+#endif
+
diff --git a/arch/arm/mach-netx/include/mach/netx-regs.h b/arch/arm/mach-netx/include/mach/netx-regs.h
new file mode 100644
index 00000000..5a03e7cc
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/netx-regs.h
@@ -0,0 +1,432 @@
+/*
+ * arch/arm/mach-netx/include/mach/netx-regs.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_NETX_REGS_H
+#define __ASM_ARCH_NETX_REGS_H
+
+/* offsets relative to the beginning of the io space */
+#define NETX_OFS_SYSTEM 0x00000
+#define NETX_OFS_MEMCR 0x00100
+#define NETX_OFS_DPMAS 0x03000
+#define NETX_OFS_GPIO 0x00800
+#define NETX_OFS_PIO 0x00900
+#define NETX_OFS_UART0 0x00a00
+#define NETX_OFS_UART1 0x00a40
+#define NETX_OFS_UART2 0x00a80
+#define NETX_OF_MIIMU 0x00b00
+#define NETX_OFS_SPI 0x00c00
+#define NETX_OFS_I2C 0x00d00
+#define NETX_OFS_SYSTIME 0x01100
+#define NETX_OFS_RTC 0x01200
+#define NETX_OFS_EXTBUS 0x03600
+#define NETX_OFS_LCD 0x04000
+#define NETX_OFS_USB 0x20000
+#define NETX_OFS_XMAC0 0x60000
+#define NETX_OFS_XMAC1 0x61000
+#define NETX_OFS_XMAC2 0x62000
+#define NETX_OFS_XMAC3 0x63000
+#define NETX_OFS_XMAC(no) (0x60000 + (no) * 0x1000)
+#define NETX_OFS_PFIFO 0x64000
+#define NETX_OFS_XPEC0 0x70000
+#define NETX_OFS_XPEC1 0x74000
+#define NETX_OFS_XPEC2 0x78000
+#define NETX_OFS_XPEC3 0x7c000
+#define NETX_OFS_XPEC(no) (0x70000 + (no) * 0x4000)
+#define NETX_OFS_VIC 0xff000
+
+/* physical addresses */
+#define NETX_PA_SYSTEM (NETX_IO_PHYS + NETX_OFS_SYSTEM)
+#define NETX_PA_MEMCR (NETX_IO_PHYS + NETX_OFS_MEMCR)
+#define NETX_PA_DPMAS (NETX_IO_PHYS + NETX_OFS_DPMAS)
+#define NETX_PA_GPIO (NETX_IO_PHYS + NETX_OFS_GPIO)
+#define NETX_PA_PIO (NETX_IO_PHYS + NETX_OFS_PIO)
+#define NETX_PA_UART0 (NETX_IO_PHYS + NETX_OFS_UART0)
+#define NETX_PA_UART1 (NETX_IO_PHYS + NETX_OFS_UART1)
+#define NETX_PA_UART2 (NETX_IO_PHYS + NETX_OFS_UART2)
+#define NETX_PA_MIIMU (NETX_IO_PHYS + NETX_OF_MIIMU)
+#define NETX_PA_SPI (NETX_IO_PHYS + NETX_OFS_SPI)
+#define NETX_PA_I2C (NETX_IO_PHYS + NETX_OFS_I2C)
+#define NETX_PA_SYSTIME (NETX_IO_PHYS + NETX_OFS_SYSTIME)
+#define NETX_PA_RTC (NETX_IO_PHYS + NETX_OFS_RTC)
+#define NETX_PA_EXTBUS (NETX_IO_PHYS + NETX_OFS_EXTBUS)
+#define NETX_PA_LCD (NETX_IO_PHYS + NETX_OFS_LCD)
+#define NETX_PA_USB (NETX_IO_PHYS + NETX_OFS_USB)
+#define NETX_PA_XMAC0 (NETX_IO_PHYS + NETX_OFS_XMAC0)
+#define NETX_PA_XMAC1 (NETX_IO_PHYS + NETX_OFS_XMAC1)
+#define NETX_PA_XMAC2 (NETX_IO_PHYS + NETX_OFS_XMAC2)
+#define NETX_PA_XMAC3 (NETX_IO_PHYS + NETX_OFS_XMAC3)
+#define NETX_PA_XMAC(no) (NETX_IO_PHYS + NETX_OFS_XMAC(no))
+#define NETX_PA_PFIFO (NETX_IO_PHYS + NETX_OFS_PFIFO)
+#define NETX_PA_XPEC0 (NETX_IO_PHYS + NETX_OFS_XPEC0)
+#define NETX_PA_XPEC1 (NETX_IO_PHYS + NETX_OFS_XPEC1)
+#define NETX_PA_XPEC2 (NETX_IO_PHYS + NETX_OFS_XPEC2)
+#define NETX_PA_XPEC3 (NETX_IO_PHYS + NETX_OFS_XPEC3)
+#define NETX_PA_XPEC(no) (NETX_IO_PHYS + NETX_OFS_XPEC(no))
+#define NETX_PA_VIC (NETX_IO_PHYS + NETX_OFS_VIC)
+
+/* virtual addresses */
+#define NETX_VA_SYSTEM (NETX_IO_VIRT + NETX_OFS_SYSTEM)
+#define NETX_VA_MEMCR (NETX_IO_VIRT + NETX_OFS_MEMCR)
+#define NETX_VA_DPMAS (NETX_IO_VIRT + NETX_OFS_DPMAS)
+#define NETX_VA_GPIO (NETX_IO_VIRT + NETX_OFS_GPIO)
+#define NETX_VA_PIO (NETX_IO_VIRT + NETX_OFS_PIO)
+#define NETX_VA_UART0 (NETX_IO_VIRT + NETX_OFS_UART0)
+#define NETX_VA_UART1 (NETX_IO_VIRT + NETX_OFS_UART1)
+#define NETX_VA_UART2 (NETX_IO_VIRT + NETX_OFS_UART2)
+#define NETX_VA_MIIMU (NETX_IO_VIRT + NETX_OF_MIIMU)
+#define NETX_VA_SPI (NETX_IO_VIRT + NETX_OFS_SPI)
+#define NETX_VA_I2C (NETX_IO_VIRT + NETX_OFS_I2C)
+#define NETX_VA_SYSTIME (NETX_IO_VIRT + NETX_OFS_SYSTIME)
+#define NETX_VA_RTC (NETX_IO_VIRT + NETX_OFS_RTC)
+#define NETX_VA_EXTBUS (NETX_IO_VIRT + NETX_OFS_EXTBUS)
+#define NETX_VA_LCD (NETX_IO_VIRT + NETX_OFS_LCD)
+#define NETX_VA_USB (NETX_IO_VIRT + NETX_OFS_USB)
+#define NETX_VA_XMAC0 (NETX_IO_VIRT + NETX_OFS_XMAC0)
+#define NETX_VA_XMAC1 (NETX_IO_VIRT + NETX_OFS_XMAC1)
+#define NETX_VA_XMAC2 (NETX_IO_VIRT + NETX_OFS_XMAC2)
+#define NETX_VA_XMAC3 (NETX_IO_VIRT + NETX_OFS_XMAC3)
+#define NETX_VA_XMAC(no) (NETX_IO_VIRT + NETX_OFS_XMAC(no))
+#define NETX_VA_PFIFO (NETX_IO_VIRT + NETX_OFS_PFIFO)
+#define NETX_VA_XPEC0 (NETX_IO_VIRT + NETX_OFS_XPEC0)
+#define NETX_VA_XPEC1 (NETX_IO_VIRT + NETX_OFS_XPEC1)
+#define NETX_VA_XPEC2 (NETX_IO_VIRT + NETX_OFS_XPEC2)
+#define NETX_VA_XPEC3 (NETX_IO_VIRT + NETX_OFS_XPEC3)
+#define NETX_VA_XPEC(no) (NETX_IO_VIRT + NETX_OFS_XPEC(no))
+#define NETX_VA_VIC (NETX_IO_VIRT + NETX_OFS_VIC)
+
+/*********************************
+ * System functions *
+ *********************************/
+
+/* Registers */
+#define NETX_SYSTEM_REG(ofs) __io(NETX_VA_SYSTEM + (ofs))
+#define NETX_SYSTEM_BOO_SR NETX_SYSTEM_REG(0x00)
+#define NETX_SYSTEM_IOC_CR NETX_SYSTEM_REG(0x04)
+#define NETX_SYSTEM_IOC_MR NETX_SYSTEM_REG(0x08)
+
+/* FIXME: Docs are not consistent */
+/* #define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x08) */
+#define NETX_SYSTEM_RES_CR NETX_SYSTEM_REG(0x0c)
+
+#define NETX_SYSTEM_PHY_CONTROL NETX_SYSTEM_REG(0x10)
+#define NETX_SYSTEM_REV NETX_SYSTEM_REG(0x34)
+#define NETX_SYSTEM_IOC_ACCESS_KEY NETX_SYSTEM_REG(0x70)
+#define NETX_SYSTEM_WDG_TR NETX_SYSTEM_REG(0x200)
+#define NETX_SYSTEM_WDG_CTR NETX_SYSTEM_REG(0x204)
+#define NETX_SYSTEM_WDG_IRQ_TIMEOUT NETX_SYSTEM_REG(0x208)
+#define NETX_SYSTEM_WDG_RES_TIMEOUT NETX_SYSTEM_REG(0x20c)
+
+/* Bits */
+#define NETX_SYSTEM_RES_CR_RSTIN (1<<0)
+#define NETX_SYSTEM_RES_CR_WDG_RES (1<<1)
+#define NETX_SYSTEM_RES_CR_HOST_RES (1<<2)
+#define NETX_SYSTEM_RES_CR_FIRMW_RES (1<<3)
+#define NETX_SYSTEM_RES_CR_XPEC0_RES (1<<4)
+#define NETX_SYSTEM_RES_CR_XPEC1_RES (1<<5)
+#define NETX_SYSTEM_RES_CR_XPEC2_RES (1<<6)
+#define NETX_SYSTEM_RES_CR_XPEC3_RES (1<<7)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC0_RES (1<<16)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC1_RES (1<<17)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC2_RES (1<<18)
+#define NETX_SYSTEM_RES_CR_DIS_XPEC3_RES (1<<19)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG0 (1<<20)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG1 (1<<21)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG2 (1<<22)
+#define NETX_SYSTEM_RES_CR_FIRMW_FLG3 (1<<23)
+#define NETX_SYSTEM_RES_CR_FIRMW_RES_EN (1<<24)
+#define NETX_SYSTEM_RES_CR_RSTOUT (1<<25)
+#define NETX_SYSTEM_RES_CR_EN_RSTOUT (1<<26)
+
+#define PHY_CONTROL_RESET (1<<31)
+#define PHY_CONTROL_SIM_BYP (1<<30)
+#define PHY_CONTROL_CLK_XLATIN (1<<29)
+#define PHY_CONTROL_PHY1_EN (1<<21)
+#define PHY_CONTROL_PHY1_NP_MSG_CODE
+#define PHY_CONTROL_PHY1_AUTOMDIX (1<<17)
+#define PHY_CONTROL_PHY1_FIXMODE (1<<16)
+#define PHY_CONTROL_PHY1_MODE(mode) (((mode) & 0x7) << 13)
+#define PHY_CONTROL_PHY0_EN (1<<12)
+#define PHY_CONTROL_PHY0_NP_MSG_CODE
+#define PHY_CONTROL_PHY0_AUTOMDIX (1<<8)
+#define PHY_CONTROL_PHY0_FIXMODE (1<<7)
+#define PHY_CONTROL_PHY0_MODE(mode) (((mode) & 0x7) << 4)
+#define PHY_CONTROL_PHY_ADDRESS(adr) ((adr) & 0xf)
+
+#define PHY_MODE_10BASE_T_HALF 0
+#define PHY_MODE_10BASE_T_FULL 1
+#define PHY_MODE_100BASE_TX_FX_FULL 2
+#define PHY_MODE_100BASE_TX_FX_HALF 3
+#define PHY_MODE_100BASE_TX_HALF 4
+#define PHY_MODE_REPEATER 5
+#define PHY_MODE_POWER_DOWN 6
+#define PHY_MODE_ALL 7
+
+/* Bits */
+#define VECT_CNTL_ENABLE (1 << 5)
+
+/*******************************
+ * GPIO and timer module *
+ *******************************/
+
+/* Registers */
+#define NETX_GPIO_REG(ofs) __io(NETX_VA_GPIO + (ofs))
+#define NETX_GPIO_CFG(gpio) NETX_GPIO_REG(0x0 + ((gpio)<<2))
+#define NETX_GPIO_THRESHOLD_CAPTURE(gpio) NETX_GPIO_REG(0x40 + ((gpio)<<2))
+#define NETX_GPIO_COUNTER_CTRL(counter) NETX_GPIO_REG(0x80 + ((counter)<<2))
+#define NETX_GPIO_COUNTER_MAX(counter) NETX_GPIO_REG(0x94 + ((counter)<<2))
+#define NETX_GPIO_COUNTER_CURRENT(counter) NETX_GPIO_REG(0xa8 + ((counter)<<2))
+#define NETX_GPIO_IRQ_ENABLE NETX_GPIO_REG(0xbc)
+#define NETX_GPIO_IRQ_DISABLE NETX_GPIO_REG(0xc0)
+#define NETX_GPIO_SYSTIME_NS_CMP NETX_GPIO_REG(0xc4)
+#define NETX_GPIO_LINE NETX_GPIO_REG(0xc8)
+#define NETX_GPIO_IRQ NETX_GPIO_REG(0xd0)
+
+/* Bits */
+#define NETX_GPIO_CFG_IOCFG_GP_INPUT (0x0)
+#define NETX_GPIO_CFG_IOCFG_GP_OUTPUT (0x1)
+#define NETX_GPIO_CFG_IOCFG_GP_UART (0x2)
+#define NETX_GPIO_CFG_INV (1<<2)
+#define NETX_GPIO_CFG_MODE_INPUT_READ (0<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_CONT_RISING (1<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_ONCE_RISING (2<<3)
+#define NETX_GPIO_CFG_MODE_INPUT_CAPTURE_HIGH_LEVEL (3<<3)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER0 (0<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER1 (1<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER2 (2<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER3 (3<<5)
+#define NETX_GPIO_CFG_COUNT_REF_COUNTER4 (4<<5)
+#define NETX_GPIO_CFG_COUNT_REF_SYSTIME (7<<5)
+
+#define NETX_GPIO_COUNTER_CTRL_RUN (1<<0)
+#define NETX_GPIO_COUNTER_CTRL_SYM (1<<1)
+#define NETX_GPIO_COUNTER_CTRL_ONCE (1<<2)
+#define NETX_GPIO_COUNTER_CTRL_IRQ_EN (1<<3)
+#define NETX_GPIO_COUNTER_CTRL_CNT_EVENT (1<<4)
+#define NETX_GPIO_COUNTER_CTRL_RST_EN (1<<5)
+#define NETX_GPIO_COUNTER_CTRL_SEL_EVENT (1<<6)
+#define NETX_GPIO_COUNTER_CTRL_GPIO_REF /* FIXME */
+
+#define GPIO_BIT(gpio) (1<<(gpio))
+#define COUNTER_BIT(counter) ((1<<16)<<(counter))
+
+/*******************************
+ * PIO *
+ *******************************/
+
+/* Registers */
+#define NETX_PIO_REG(ofs) __io(NETX_VA_PIO + (ofs))
+#define NETX_PIO_INPIO NETX_PIO_REG(0x0)
+#define NETX_PIO_OUTPIO NETX_PIO_REG(0x4)
+#define NETX_PIO_OEPIO NETX_PIO_REG(0x8)
+
+/*******************************
+ * MII Unit *
+ *******************************/
+
+/* Registers */
+#define NETX_MIIMU __io(NETX_VA_MIIMU)
+
+/* Bits */
+#define MIIMU_SNRDY (1<<0)
+#define MIIMU_PREAMBLE (1<<1)
+#define MIIMU_OPMODE_WRITE (1<<2)
+#define MIIMU_MDC_PERIOD (1<<3)
+#define MIIMU_PHY_NRES (1<<4)
+#define MIIMU_RTA (1<<5)
+#define MIIMU_REGADDR(adr) (((adr) & 0x1f) << 6)
+#define MIIMU_PHYADDR(adr) (((adr) & 0x1f) << 11)
+#define MIIMU_DATA(data) (((data) & 0xffff) << 16)
+
+/*******************************
+ * xmac / xpec *
+ *******************************/
+
+/* XPEC register offsets relative to NETX_VA_XPEC(no) */
+#define NETX_XPEC_R0_OFS 0x00
+#define NETX_XPEC_R1_OFS 0x04
+#define NETX_XPEC_R2_OFS 0x08
+#define NETX_XPEC_R3_OFS 0x0c
+#define NETX_XPEC_R4_OFS 0x10
+#define NETX_XPEC_R5_OFS 0x14
+#define NETX_XPEC_R6_OFS 0x18
+#define NETX_XPEC_R7_OFS 0x1c
+#define NETX_XPEC_RANGE01_OFS 0x20
+#define NETX_XPEC_RANGE23_OFS 0x24
+#define NETX_XPEC_RANGE45_OFS 0x28
+#define NETX_XPEC_RANGE67_OFS 0x2c
+#define NETX_XPEC_PC_OFS 0x48
+#define NETX_XPEC_TIMER_OFS(timer) (0x30 + ((timer)<<2))
+#define NETX_XPEC_IRQ_OFS 0x8c
+#define NETX_XPEC_SYSTIME_NS_OFS 0x90
+#define NETX_XPEC_FIFO_DATA_OFS 0x94
+#define NETX_XPEC_SYSTIME_S_OFS 0x98
+#define NETX_XPEC_ADC_OFS 0x9c
+#define NETX_XPEC_URX_COUNT_OFS 0x40
+#define NETX_XPEC_UTX_COUNT_OFS 0x44
+#define NETX_XPEC_PC_OFS 0x48
+#define NETX_XPEC_ZERO_OFS 0x4c
+#define NETX_XPEC_STATCFG_OFS 0x50
+#define NETX_XPEC_EC_MASKA_OFS 0x54
+#define NETX_XPEC_EC_MASKB_OFS 0x58
+#define NETX_XPEC_EC_MASK0_OFS 0x5c
+#define NETX_XPEC_EC_MASK8_OFS 0x7c
+#define NETX_XPEC_EC_MASK9_OFS 0x80
+#define NETX_XPEC_XPU_HOLD_PC_OFS 0x100
+#define NETX_XPEC_RAM_START_OFS 0x2000
+
+/* Bits */
+#define XPU_HOLD_PC (1<<0)
+
+/* XMAC register offsets relative to NETX_VA_XMAC(no) */
+#define NETX_XMAC_RPU_PROGRAM_START_OFS 0x000
+#define NETX_XMAC_RPU_PROGRAM_END_OFS 0x3ff
+#define NETX_XMAC_TPU_PROGRAM_START_OFS 0x400
+#define NETX_XMAC_TPU_PROGRAM_END_OFS 0x7ff
+#define NETX_XMAC_RPU_HOLD_PC_OFS 0xa00
+#define NETX_XMAC_TPU_HOLD_PC_OFS 0xa04
+#define NETX_XMAC_STATUS_SHARED0_OFS 0x840
+#define NETX_XMAC_CONFIG_SHARED0_OFS 0x844
+#define NETX_XMAC_STATUS_SHARED1_OFS 0x848
+#define NETX_XMAC_CONFIG_SHARED1_OFS 0x84c
+#define NETX_XMAC_STATUS_SHARED2_OFS 0x850
+#define NETX_XMAC_CONFIG_SHARED2_OFS 0x854
+#define NETX_XMAC_STATUS_SHARED3_OFS 0x858
+#define NETX_XMAC_CONFIG_SHARED3_OFS 0x85c
+
+#define RPU_HOLD_PC (1<<15)
+#define TPU_HOLD_PC (1<<15)
+
+/*******************************
+ * Pointer FIFO *
+ *******************************/
+
+/* Registers */
+#define NETX_PFIFO_REG(ofs) __io(NETX_VA_PFIFO + (ofs))
+#define NETX_PFIFO_BASE(pfifo) NETX_PFIFO_REG(0x00 + ((pfifo)<<2))
+#define NETX_PFIFO_BORDER_BASE(pfifo) NETX_PFIFO_REG(0x80 + ((pfifo)<<2))
+#define NETX_PFIFO_RESET NETX_PFIFO_REG(0x100)
+#define NETX_PFIFO_FULL NETX_PFIFO_REG(0x104)
+#define NETX_PFIFO_EMPTY NETX_PFIFO_REG(0x108)
+#define NETX_PFIFO_OVEFLOW NETX_PFIFO_REG(0x10c)
+#define NETX_PFIFO_UNDERRUN NETX_PFIFO_REG(0x110)
+#define NETX_PFIFO_FILL_LEVEL(pfifo) NETX_PFIFO_REG(0x180 + ((pfifo)<<2))
+#define NETX_PFIFO_XPEC_ISR(xpec) NETX_PFIFO_REG(0x400 + ((xpec) << 2))
+
+
+/*******************************
+ * Memory Controller *
+ *******************************/
+
+/* Registers */
+#define NETX_MEMCR_REG(ofs) __io(NETX_VA_MEMCR + (ofs))
+#define NETX_MEMCR_SRAM_CTRL(cs) NETX_MEMCR_REG(0x0 + 4 * (cs)) /* SRAM for CS 0..2 */
+#define NETX_MEMCR_SDRAM_CFG_CTRL NETX_MEMCR_REG(0x40)
+#define NETX_MEMCR_SDRAM_TIMING_CTRL NETX_MEMCR_REG(0x44)
+#define NETX_MEMCR_SDRAM_MODE NETX_MEMCR_REG(0x48)
+#define NETX_MEMCR_SDRAM_EXT_MODE NETX_MEMCR_REG(0x4c)
+#define NETX_MEMCR_PRIO_TIMESLOT_CTRL NETX_MEMCR_REG(0x80)
+#define NETX_MEMCR_PRIO_ACCESS_CTRL NETX_MEMCR_REG(0x84)
+
+/* Bits */
+#define NETX_MEMCR_SRAM_CTRL_WIDTHEXTMEM(x) (((x) & 0x3) << 24)
+#define NETX_MEMCR_SRAM_CTRL_WSPOSTPAUSEEXTMEM(x) (((x) & 0x3) << 16)
+#define NETX_MEMCR_SRAM_CTRL_WSPREPASEEXTMEM(x) (((x) & 0x3) << 8)
+#define NETX_MEMCR_SRAM_CTRL_WSEXTMEM(x) (((x) & 0x1f) << 0)
+
+
+/*******************************
+ * Dual Port Memory *
+ *******************************/
+
+/* Registers */
+#define NETX_DPMAS_REG(ofs) __io(NETX_VA_DPMAS + (ofs))
+#define NETX_DPMAS_SYS_STAT NETX_DPMAS_REG(0x4d8)
+#define NETX_DPMAS_INT_STAT NETX_DPMAS_REG(0x4e0)
+#define NETX_DPMAS_INT_EN NETX_DPMAS_REG(0x4f0)
+#define NETX_DPMAS_IF_CONF0 NETX_DPMAS_REG(0x608)
+#define NETX_DPMAS_IF_CONF1 NETX_DPMAS_REG(0x60c)
+#define NETX_DPMAS_EXT_CONFIG(cs) NETX_DPMAS_REG(0x610 + 4 * (cs))
+#define NETX_DPMAS_IO_MODE0 NETX_DPMAS_REG(0x620) /* I/O 32..63 */
+#define NETX_DPMAS_DRV_EN0 NETX_DPMAS_REG(0x624)
+#define NETX_DPMAS_DATA0 NETX_DPMAS_REG(0x628)
+#define NETX_DPMAS_IO_MODE1 NETX_DPMAS_REG(0x630) /* I/O 64..84 */
+#define NETX_DPMAS_DRV_EN1 NETX_DPMAS_REG(0x634)
+#define NETX_DPMAS_DATA1 NETX_DPMAS_REG(0x638)
+
+/* Bits */
+#define NETX_DPMAS_INT_EN_GLB_EN (1<<31)
+#define NETX_DPMAS_INT_EN_MEM_LCK (1<<30)
+#define NETX_DPMAS_INT_EN_WDG (1<<29)
+#define NETX_DPMAS_INT_EN_PIO72 (1<<28)
+#define NETX_DPMAS_INT_EN_PIO47 (1<<27)
+#define NETX_DPMAS_INT_EN_PIO40 (1<<26)
+#define NETX_DPMAS_INT_EN_PIO36 (1<<25)
+#define NETX_DPMAS_INT_EN_PIO35 (1<<24)
+
+#define NETX_DPMAS_IF_CONF0_HIF_DISABLED (0<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_EXT_BUS (1<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_UP_8BIT (2<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_UP_16BIT (3<<28)
+#define NETX_DPMAS_IF_CONF0_HIF_IO (4<<28)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_PP (1<<14)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_OD (2<<14)
+#define NETX_DPMAS_IF_CONF0_WAIT_DRV_TRI (3<<14)
+
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO35 (1<<26)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO36 (1<<27)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO40 (1<<28)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO47 (1<<29)
+#define NETX_DPMAS_IF_CONF1_IRQ_POL_PIO72 (1<<30)
+
+#define NETX_EXT_CONFIG_TALEWIDTH(x) (((x) & 0x7) << 29)
+#define NETX_EXT_CONFIG_TADRHOLD(x) (((x) & 0x7) << 26)
+#define NETX_EXT_CONFIG_TCSON(x) (((x) & 0x7) << 23)
+#define NETX_EXT_CONFIG_TRDON(x) (((x) & 0x7) << 20)
+#define NETX_EXT_CONFIG_TWRON(x) (((x) & 0x7) << 17)
+#define NETX_EXT_CONFIG_TWROFF(x) (((x) & 0x1f) << 12)
+#define NETX_EXT_CONFIG_TRDWRCYC(x) (((x) & 0x1f) << 7)
+#define NETX_EXT_CONFIG_WAIT_POL (1<<6)
+#define NETX_EXT_CONFIG_WAIT_EN (1<<5)
+#define NETX_EXT_CONFIG_NRD_MODE (1<<4)
+#define NETX_EXT_CONFIG_DS_MODE (1<<3)
+#define NETX_EXT_CONFIG_NWR_MODE (1<<2)
+#define NETX_EXT_CONFIG_16BIT (1<<1)
+#define NETX_EXT_CONFIG_CS_ENABLE (1<<0)
+
+#define NETX_DPMAS_IO_MODE0_WRL (1<<13)
+#define NETX_DPMAS_IO_MODE0_WAIT (1<<14)
+#define NETX_DPMAS_IO_MODE0_READY (1<<15)
+#define NETX_DPMAS_IO_MODE0_CS0 (1<<19)
+#define NETX_DPMAS_IO_MODE0_EXTRD (1<<20)
+
+#define NETX_DPMAS_IO_MODE1_CS2 (1<<15)
+#define NETX_DPMAS_IO_MODE1_CS1 (1<<16)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_NPOR (0<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_100MHZ (1<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_NPIO36 (2<<30)
+#define NETX_DPMAS_IO_MODE1_SAMPLE_PIO36 (3<<30)
+
+/*******************************
+ * I2C *
+ *******************************/
+#define NETX_I2C_REG(ofs) __io(NETX_VA_I2C, (ofs))
+#define NETX_I2C_CTRL NETX_I2C_REG(0x0)
+#define NETX_I2C_DATA NETX_I2C_REG(0x4)
+
+#endif /* __ASM_ARCH_NETX_REGS_H */
diff --git a/arch/arm/mach-netx/include/mach/param.h b/arch/arm/mach-netx/include/mach/param.h
new file mode 100644
index 00000000..a7714592
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/param.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-netx/include/mach/param.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
diff --git a/arch/arm/mach-netx/include/mach/pfifo.h b/arch/arm/mach-netx/include/mach/pfifo.h
new file mode 100644
index 00000000..42c59068
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/pfifo.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-netx/include/mach/pfifo.h
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#ifndef ASM_ARCH_PFIFO_H
+#define ASM_ARCH_PFIFO_H
+
+static inline int pfifo_push(int no, unsigned int pointer)
+{
+ writel(pointer, NETX_PFIFO_BASE(no));
+ return 0;
+}
+
+static inline unsigned int pfifo_pop(int no)
+{
+ return readl(NETX_PFIFO_BASE(no));
+}
+
+static inline int pfifo_fill_level(int no)
+{
+
+ return readl(NETX_PFIFO_FILL_LEVEL(no));
+}
+
+static inline int pfifo_full(int no)
+{
+ return readl(NETX_PFIFO_FULL) & (1<<no) ? 1 : 0;
+}
+
+static inline int pfifo_empty(int no)
+{
+ return readl(NETX_PFIFO_EMPTY) & (1<<no) ? 1 : 0;
+}
+
+int pfifo_request(unsigned int pfifo_mask);
+void pfifo_free(unsigned int pfifo_mask);
+
+#endif /* ASM_ARCH_PFIFO_H */
diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h
new file mode 100644
index 00000000..dc7b4bc0
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/system.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-netx/include/mach/system.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "netx-regs.h"
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES,
+ NETX_SYSTEM_RES_CR);
+}
+
+#endif
+
diff --git a/arch/arm/mach-netx/include/mach/timex.h b/arch/arm/mach-netx/include/mach/timex.h
new file mode 100644
index 00000000..1120dd0b
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/timex.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-netx/include/mach/timex.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define CLOCK_TICK_RATE 100000000
diff --git a/arch/arm/mach-netx/include/mach/uncompress.h b/arch/arm/mach-netx/include/mach/uncompress.h
new file mode 100644
index 00000000..84f91284
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-netx/include/mach/uncompress.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+#define REG(x) (*(volatile unsigned long *)(x))
+
+#define UART1_BASE 0x100a00
+#define UART2_BASE 0x100a80
+
+#define UART_DR 0x0
+
+#define UART_CR 0x14
+#define CR_UART_EN (1<<0)
+
+#define UART_FR 0x18
+#define FR_BUSY (1<<3)
+#define FR_TXFF (1<<5)
+
+static void putc(char c)
+{
+ unsigned long base;
+
+ if (REG(UART1_BASE + UART_CR) & CR_UART_EN)
+ base = UART1_BASE;
+ else if (REG(UART2_BASE + UART_CR) & CR_UART_EN)
+ base = UART2_BASE;
+ else
+ return;
+
+ while (REG(base + UART_FR) & FR_TXFF);
+ REG(base + UART_DR) = c;
+}
+
+static inline void flush(void)
+{
+ unsigned long base;
+
+ if (REG(UART1_BASE + UART_CR) & CR_UART_EN)
+ base = UART1_BASE;
+ else if (REG(UART2_BASE + UART_CR) & CR_UART_EN)
+ base = UART2_BASE;
+ else
+ return;
+
+ while (REG(base + UART_FR) & FR_BUSY);
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-netx/include/mach/vmalloc.h b/arch/arm/mach-netx/include/mach/vmalloc.h
new file mode 100644
index 00000000..871f1ef7
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-netx/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-netx/include/mach/xc.h b/arch/arm/mach-netx/include/mach/xc.h
new file mode 100644
index 00000000..0c0011d4
--- /dev/null
+++ b/arch/arm/mach-netx/include/mach/xc.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-netx/include/mach/xc.h
+ *
+ * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_XC_H
+#define __ASM_ARCH_XC_H
+
+struct xc {
+ int no;
+ unsigned int type;
+ unsigned int version;
+ void __iomem *xpec_base;
+ void __iomem *xmac_base;
+ void __iomem *sram_base;
+ int irq;
+ struct device *dev;
+};
+
+int xc_reset(struct xc *x);
+int xc_stop(struct xc* x);
+int xc_start(struct xc *x);
+int xc_running(struct xc *x);
+int xc_request_firmware(struct xc* x);
+struct xc* request_xc(int xcno, struct device *dev);
+void free_xc(struct xc *x);
+
+#endif /* __ASM_ARCH_XC_H */
diff --git a/arch/arm/mach-netx/nxdb500.c b/arch/arm/mach-netx/nxdb500.c
new file mode 100644
index 00000000..ca8b203a
--- /dev/null
+++ b/arch/arm/mach-netx/nxdb500.c
@@ -0,0 +1,208 @@
+/*
+ * arch/arm/mach-netx/nxdb500.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/netx-regs.h>
+#include <mach/eth.h>
+
+#include "generic.h"
+#include "fb.h"
+
+static struct clcd_panel qvga = {
+ .mode = {
+ .name = "QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 187617,
+ .left_margin = 6,
+ .right_margin = 26,
+ .upper_margin = 0,
+ .lower_margin = 6,
+ .hsync_len = 6,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = 16,
+ .cntl = CNTL_LCDTFT | CNTL_BGR,
+ .bpp = 16,
+ .grayscale = 0,
+};
+
+static inline int nxdb500_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
+{
+ var->green.length = 5;
+ var->green.msb_right = 0;
+
+ return clcdfb_check(fb, var);
+}
+
+static int nxdb500_clcd_setup(struct clcd_fb *fb)
+{
+ unsigned int val;
+
+ fb->fb.var.green.length = 5;
+ fb->fb.var.green.msb_right = 0;
+
+ /* enable asic control */
+ val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+ writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+ writel(3, NETX_SYSTEM_IOC_CR);
+
+ val = readl(NETX_PIO_OUTPIO);
+ writel(val | 1, NETX_PIO_OUTPIO);
+
+ val = readl(NETX_PIO_OEPIO);
+ writel(val | 1, NETX_PIO_OEPIO);
+ return netx_clcd_setup(fb);
+}
+
+static struct clcd_board clcd_data = {
+ .name = "netX",
+ .check = nxdb500_check,
+ .decode = clcdfb_decode,
+ .enable = netx_clcd_enable,
+ .setup = nxdb500_clcd_setup,
+ .mmap = netx_clcd_mmap,
+ .remove = netx_clcd_remove,
+};
+
+static struct netxeth_platform_data eth0_platform_data = {
+ .xcno = 0,
+};
+
+static struct platform_device netx_eth0_device = {
+ .name = "netx-eth",
+ .id = 0,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth0_platform_data,
+ }
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+ .xcno = 1,
+};
+
+static struct platform_device netx_eth1_device = {
+ .name = "netx-eth",
+ .id = 1,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth1_platform_data,
+ }
+};
+
+static struct resource netx_uart0_resources[] = {
+ [0] = {
+ .start = 0x00100A00,
+ .end = 0x00100A3F,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (NETX_IRQ_UART0),
+ .end = (NETX_IRQ_UART0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device netx_uart0_device = {
+ .name = "netx-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(netx_uart0_resources),
+ .resource = netx_uart0_resources,
+};
+
+static struct resource netx_uart1_resources[] = {
+ [0] = {
+ .start = 0x00100A40,
+ .end = 0x00100A7F,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (NETX_IRQ_UART1),
+ .end = (NETX_IRQ_UART1),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device netx_uart1_device = {
+ .name = "netx-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(netx_uart1_resources),
+ .resource = netx_uart1_resources,
+};
+
+static struct resource netx_uart2_resources[] = {
+ [0] = {
+ .start = 0x00100A80,
+ .end = 0x00100ABF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (NETX_IRQ_UART2),
+ .end = (NETX_IRQ_UART2),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device netx_uart2_device = {
+ .name = "netx-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(netx_uart2_resources),
+ .resource = netx_uart2_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &netx_eth0_device,
+ &netx_eth1_device,
+ &netx_uart0_device,
+ &netx_uart1_device,
+ &netx_uart2_device,
+};
+
+static void __init nxdb500_init(void)
+{
+ netx_fb_init(&clcd_data, &qvga);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXDB500, "Hilscher nxdb500")
+ .boot_params = 0x80000100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .timer = &netx_timer,
+ .init_machine = nxdb500_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxdkn.c b/arch/arm/mach-netx/nxdkn.c
new file mode 100644
index 00000000..d775cbe0
--- /dev/null
+++ b/arch/arm/mach-netx/nxdkn.c
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/mach-netx/nxdkn.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/netx-regs.h>
+#include <mach/eth.h>
+
+#include "generic.h"
+
+static struct netxeth_platform_data eth0_platform_data = {
+ .xcno = 0,
+};
+
+static struct platform_device nxdkn_eth0_device = {
+ .name = "netx-eth",
+ .id = 0,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth0_platform_data,
+ }
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+ .xcno = 1,
+};
+
+static struct platform_device nxdkn_eth1_device = {
+ .name = "netx-eth",
+ .id = 1,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth1_platform_data,
+ }
+};
+
+static struct resource netx_uart0_resources[] = {
+ [0] = {
+ .start = 0x00100A00,
+ .end = 0x00100A3F,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (NETX_IRQ_UART0),
+ .end = (NETX_IRQ_UART0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device netx_uart0_device = {
+ .name = "netx-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(netx_uart0_resources),
+ .resource = netx_uart0_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &nxdkn_eth0_device,
+ &nxdkn_eth1_device,
+ &netx_uart0_device,
+};
+
+static void __init nxdkn_init(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXDKN, "Hilscher nxdkn")
+ .boot_params = 0x80000100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .timer = &netx_timer,
+ .init_machine = nxdkn_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/nxeb500hmi.c b/arch/arm/mach-netx/nxeb500hmi.c
new file mode 100644
index 00000000..de369cd1
--- /dev/null
+++ b/arch/arm/mach-netx/nxeb500hmi.c
@@ -0,0 +1,185 @@
+/*
+ * arch/arm/mach-netx/nxeb500hmi.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/netx-regs.h>
+#include <mach/eth.h>
+
+#include "generic.h"
+#include "fb.h"
+
+static struct clcd_panel qvga = {
+ .mode = {
+ .name = "QVGA",
+ .refresh = 60,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 187617,
+ .left_margin = 6,
+ .right_margin = 26,
+ .upper_margin = 0,
+ .lower_margin = 6,
+ .hsync_len = 6,
+ .vsync_len = 1,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = 16,
+ .cntl = CNTL_LCDTFT | CNTL_BGR,
+ .bpp = 16,
+ .grayscale = 0,
+};
+
+static inline int nxeb500hmi_check(struct clcd_fb *fb, struct fb_var_screeninfo *var)
+{
+ var->green.length = 5;
+ var->green.msb_right = 0;
+
+ return clcdfb_check(fb, var);
+}
+
+static int nxeb500hmi_clcd_setup(struct clcd_fb *fb)
+{
+ unsigned int val;
+
+ fb->fb.var.green.length = 5;
+ fb->fb.var.green.msb_right = 0;
+
+ /* enable asic control */
+ val = readl(NETX_SYSTEM_IOC_ACCESS_KEY);
+ writel(val, NETX_SYSTEM_IOC_ACCESS_KEY);
+
+ writel(3, NETX_SYSTEM_IOC_CR);
+
+ /* GPIO 14 is used for display enable on newer boards */
+ writel(9, NETX_GPIO_CFG(14));
+
+ val = readl(NETX_PIO_OUTPIO);
+ writel(val | 1, NETX_PIO_OUTPIO);
+
+ val = readl(NETX_PIO_OEPIO);
+ writel(val | 1, NETX_PIO_OEPIO);
+ return netx_clcd_setup(fb);
+}
+
+static struct clcd_board clcd_data = {
+ .name = "netX",
+ .check = nxeb500hmi_check,
+ .decode = clcdfb_decode,
+ .enable = netx_clcd_enable,
+ .setup = nxeb500hmi_clcd_setup,
+ .mmap = netx_clcd_mmap,
+ .remove = netx_clcd_remove,
+};
+
+static struct netxeth_platform_data eth0_platform_data = {
+ .xcno = 0,
+};
+
+static struct platform_device netx_eth0_device = {
+ .name = "netx-eth",
+ .id = 0,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth0_platform_data,
+ }
+};
+
+static struct netxeth_platform_data eth1_platform_data = {
+ .xcno = 1,
+};
+
+static struct platform_device netx_eth1_device = {
+ .name = "netx-eth",
+ .id = 1,
+ .num_resources = 0,
+ .resource = NULL,
+ .dev = {
+ .platform_data = &eth1_platform_data,
+ }
+};
+
+static struct resource netx_cf_resources[] = {
+ [0] = {
+ .start = 0x20000000,
+ .end = 0x25ffffff,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
+ },
+};
+
+static struct platform_device netx_cf_device = {
+ .name = "netx-cf",
+ .id = 0,
+ .resource = netx_cf_resources,
+ .num_resources = ARRAY_SIZE(netx_cf_resources),
+};
+
+static struct resource netx_uart0_resources[] = {
+ [0] = {
+ .start = 0x00100A00,
+ .end = 0x00100A3F,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (NETX_IRQ_UART0),
+ .end = (NETX_IRQ_UART0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device netx_uart0_device = {
+ .name = "netx-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(netx_uart0_resources),
+ .resource = netx_uart0_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &netx_eth0_device,
+ &netx_eth1_device,
+ &netx_cf_device,
+ &netx_uart0_device,
+};
+
+static void __init nxeb500hmi_init(void)
+{
+ netx_fb_init(&clcd_data, &qvga);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(NXEB500HMI, "Hilscher nxeb500hmi")
+ .boot_params = 0x80000100,
+ .map_io = netx_map_io,
+ .init_irq = netx_init_irq,
+ .timer = &netx_timer,
+ .init_machine = nxeb500hmi_init,
+MACHINE_END
diff --git a/arch/arm/mach-netx/pfifo.c b/arch/arm/mach-netx/pfifo.c
new file mode 100644
index 00000000..03984943
--- /dev/null
+++ b/arch/arm/mach-netx/pfifo.c
@@ -0,0 +1,68 @@
+/*
+ * arch/arm/mach-netx/pfifo.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/netx-regs.h>
+#include <mach/pfifo.h>
+
+static DEFINE_MUTEX(pfifo_lock);
+
+static unsigned int pfifo_used = 0;
+
+int pfifo_request(unsigned int pfifo_mask)
+{
+ int err = 0;
+ unsigned int val;
+
+ mutex_lock(&pfifo_lock);
+
+ if (pfifo_mask & pfifo_used) {
+ err = -EBUSY;
+ goto out;
+ }
+
+ pfifo_used |= pfifo_mask;
+
+ val = readl(NETX_PFIFO_RESET);
+ writel(val | pfifo_mask, NETX_PFIFO_RESET);
+ writel(val, NETX_PFIFO_RESET);
+
+out:
+ mutex_unlock(&pfifo_lock);
+ return err;
+}
+
+void pfifo_free(unsigned int pfifo_mask)
+{
+ mutex_lock(&pfifo_lock);
+ pfifo_used &= ~pfifo_mask;
+ mutex_unlock(&pfifo_lock);
+}
+
+EXPORT_SYMBOL(pfifo_push);
+EXPORT_SYMBOL(pfifo_pop);
+EXPORT_SYMBOL(pfifo_fill_level);
+EXPORT_SYMBOL(pfifo_empty);
+EXPORT_SYMBOL(pfifo_request);
+EXPORT_SYMBOL(pfifo_free);
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
new file mode 100644
index 00000000..e24c141b
--- /dev/null
+++ b/arch/arm/mach-netx/time.c
@@ -0,0 +1,157 @@
+/*
+ * arch/arm/mach-netx/time.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/netx-regs.h>
+
+#define TIMER_CLOCKEVENT 0
+#define TIMER_CLOCKSOURCE 1
+
+static void netx_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ u32 tmode;
+
+ /* disable timer */
+ writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ writel(LATCH, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
+ tmode = NETX_GPIO_COUNTER_CTRL_RST_EN |
+ NETX_GPIO_COUNTER_CTRL_IRQ_EN |
+ NETX_GPIO_COUNTER_CTRL_RUN;
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ writel(0, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKEVENT));
+ tmode = NETX_GPIO_COUNTER_CTRL_IRQ_EN |
+ NETX_GPIO_COUNTER_CTRL_RUN;
+ break;
+
+ default:
+ WARN(1, "%s: unhandled mode %d\n", __func__, mode);
+ /* fall through */
+
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ tmode = 0;
+ break;
+ }
+
+ writel(tmode, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKEVENT));
+}
+
+static int netx_set_next_event(unsigned long evt,
+ struct clock_event_device *clk)
+{
+ writel(0 - evt, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKEVENT));
+ return 0;
+}
+
+static struct clock_event_device netx_clockevent = {
+ .name = "netx-timer" __stringify(TIMER_CLOCKEVENT),
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = netx_set_next_event,
+ .set_mode = netx_set_mode,
+};
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+netx_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &netx_clockevent;
+
+ /* acknowledge interrupt */
+ writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction netx_timer_irq = {
+ .name = "NetX Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = netx_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt
+ */
+static void __init netx_timer_init(void)
+{
+ /* disable timer initially */
+ writel(0, NETX_GPIO_COUNTER_CTRL(0));
+
+ /* Reset the timer value to zero */
+ writel(0, NETX_GPIO_COUNTER_CURRENT(0));
+
+ writel(LATCH, NETX_GPIO_COUNTER_MAX(0));
+
+ /* acknowledge interrupt */
+ writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
+
+ /* Enable the interrupt in the specific timer
+ * register and start timer
+ */
+ writel(COUNTER_BIT(0), NETX_GPIO_IRQ_ENABLE);
+ writel(NETX_GPIO_COUNTER_CTRL_IRQ_EN | NETX_GPIO_COUNTER_CTRL_RUN,
+ NETX_GPIO_COUNTER_CTRL(0));
+
+ setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
+
+ /* Setup timer one for clocksource */
+ writel(0, NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
+ writel(0, NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE));
+ writel(0xffffffff, NETX_GPIO_COUNTER_MAX(TIMER_CLOCKSOURCE));
+
+ writel(NETX_GPIO_COUNTER_CTRL_RUN,
+ NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
+
+ clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE),
+ "netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up);
+
+ netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
+ netx_clockevent.shift);
+ netx_clockevent.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &netx_clockevent);
+ /* with max_delta_ns >= delta2ns(0x800) the system currently runs fine.
+ * Adding some safety ... */
+ netx_clockevent.min_delta_ns =
+ clockevent_delta2ns(0xa00, &netx_clockevent);
+ netx_clockevent.cpumask = cpumask_of(0);
+ clockevents_register_device(&netx_clockevent);
+}
+
+struct sys_timer netx_timer = {
+ .init = netx_timer_init,
+};
diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c
new file mode 100644
index 00000000..f009b54e
--- /dev/null
+++ b/arch/arm/mach-netx/xc.c
@@ -0,0 +1,257 @@
+/*
+ * arch/arm/mach-netx/xc.c
+ *
+ * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/netx-regs.h>
+
+#include <mach/xc.h>
+
+static DEFINE_MUTEX(xc_lock);
+
+static int xc_in_use = 0;
+
+struct fw_desc {
+ unsigned int ofs;
+ unsigned int size;
+ unsigned int patch_ofs;
+ unsigned int patch_entries;
+};
+
+struct fw_header {
+ unsigned int magic;
+ unsigned int type;
+ unsigned int version;
+ unsigned int reserved[5];
+ struct fw_desc fw_desc[3];
+} __attribute__ ((packed));
+
+int xc_stop(struct xc *x)
+{
+ writel(RPU_HOLD_PC, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
+ writel(TPU_HOLD_PC, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
+ writel(XPU_HOLD_PC, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
+ return 0;
+}
+
+int xc_start(struct xc *x)
+{
+ writel(0, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
+ writel(0, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
+ writel(0, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
+ return 0;
+}
+
+int xc_running(struct xc *x)
+{
+ return (readl(x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS) & RPU_HOLD_PC)
+ || (readl(x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS) & TPU_HOLD_PC)
+ || (readl(x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS) & XPU_HOLD_PC) ?
+ 0 : 1;
+}
+
+int xc_reset(struct xc *x)
+{
+ writel(0, x->xpec_base + NETX_XPEC_PC_OFS);
+ return 0;
+}
+
+static int xc_check_ptr(struct xc *x, unsigned long adr, unsigned int size)
+{
+ if (adr >= NETX_PA_XMAC(x->no) &&
+ adr + size < NETX_PA_XMAC(x->no) + XMAC_MEM_SIZE)
+ return 0;
+
+ if (adr >= NETX_PA_XPEC(x->no) &&
+ adr + size < NETX_PA_XPEC(x->no) + XPEC_MEM_SIZE)
+ return 0;
+
+ dev_err(x->dev, "Illegal pointer in firmware found. aborting\n");
+
+ return -1;
+}
+
+static int xc_patch(struct xc *x, const void *patch, int count)
+{
+ unsigned int val, adr;
+ const unsigned int *data = patch;
+
+ int i;
+ for (i = 0; i < count; i++) {
+ adr = *data++;
+ val = *data++;
+ if (xc_check_ptr(x, adr, 4) < 0)
+ return -EINVAL;
+
+ writel(val, (void __iomem *)io_p2v(adr));
+ }
+ return 0;
+}
+
+int xc_request_firmware(struct xc *x)
+{
+ int ret;
+ char name[16];
+ const struct firmware *fw;
+ struct fw_header *head;
+ unsigned int size;
+ int i;
+ const void *src;
+ unsigned long dst;
+
+ sprintf(name, "xc%d.bin", x->no);
+
+ ret = request_firmware(&fw, name, x->dev);
+
+ if (ret < 0) {
+ dev_err(x->dev, "request_firmware failed\n");
+ return ret;
+ }
+
+ head = (struct fw_header *)fw->data;
+ if (head->magic != 0x4e657458) {
+ if (head->magic == 0x5874654e) {
+ dev_err(x->dev,
+ "firmware magic is 'XteN'. Endianess problems?\n");
+ ret = -ENODEV;
+ goto exit_release_firmware;
+ }
+ dev_err(x->dev, "unrecognized firmware magic 0x%08x\n",
+ head->magic);
+ ret = -ENODEV;
+ goto exit_release_firmware;
+ }
+
+ x->type = head->type;
+ x->version = head->version;
+
+ ret = -EINVAL;
+
+ for (i = 0; i < 3; i++) {
+ src = fw->data + head->fw_desc[i].ofs;
+ dst = *(unsigned int *)src;
+ src += sizeof (unsigned int);
+ size = head->fw_desc[i].size - sizeof (unsigned int);
+
+ if (xc_check_ptr(x, dst, size))
+ goto exit_release_firmware;
+
+ memcpy((void *)io_p2v(dst), src, size);
+
+ src = fw->data + head->fw_desc[i].patch_ofs;
+ size = head->fw_desc[i].patch_entries;
+ ret = xc_patch(x, src, size);
+ if (ret < 0)
+ goto exit_release_firmware;
+ }
+
+ ret = 0;
+
+ exit_release_firmware:
+ release_firmware(fw);
+
+ return ret;
+}
+
+struct xc *request_xc(int xcno, struct device *dev)
+{
+ struct xc *x = NULL;
+
+ mutex_lock(&xc_lock);
+
+ if (xcno > 3)
+ goto exit;
+ if (xc_in_use & (1 << xcno))
+ goto exit;
+
+ x = kmalloc(sizeof (struct xc), GFP_KERNEL);
+ if (!x)
+ goto exit;
+
+ if (!request_mem_region
+ (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(&dev->kobj)))
+ goto exit_free;
+
+ if (!request_mem_region
+ (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(&dev->kobj)))
+ goto exit_release_1;
+
+ if (!request_mem_region
+ (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(&dev->kobj)))
+ goto exit_release_2;
+
+ x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
+ x->xmac_base = (void * __iomem)io_p2v(NETX_PA_XMAC(xcno));
+ x->sram_base = ioremap(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+ if (!x->sram_base)
+ goto exit_release_3;
+
+ x->irq = NETX_IRQ_XPEC(xcno);
+
+ x->no = xcno;
+ x->dev = dev;
+
+ xc_in_use |= (1 << xcno);
+
+ goto exit;
+
+ exit_release_3:
+ release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+ exit_release_2:
+ release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
+ exit_release_1:
+ release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
+ exit_free:
+ kfree(x);
+ x = NULL;
+ exit:
+ mutex_unlock(&xc_lock);
+ return x;
+}
+
+void free_xc(struct xc *x)
+{
+ int xcno = x->no;
+
+ mutex_lock(&xc_lock);
+
+ iounmap(x->sram_base);
+ release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
+ release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
+ release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
+ xc_in_use &= ~(1 << x->no);
+ kfree(x);
+
+ mutex_unlock(&xc_lock);
+}
+
+EXPORT_SYMBOL(free_xc);
+EXPORT_SYMBOL(request_xc);
+EXPORT_SYMBOL(xc_request_firmware);
+EXPORT_SYMBOL(xc_reset);
+EXPORT_SYMBOL(xc_running);
+EXPORT_SYMBOL(xc_start);
+EXPORT_SYMBOL(xc_stop);
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig
new file mode 100644
index 00000000..3c5e0f52
--- /dev/null
+++ b/arch/arm/mach-nomadik/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_NOMADIK
+
+menu "Nomadik boards"
+
+config MACH_NOMADIK_8815NHK
+ bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
+ select NOMADIK_8815
+ select HAS_MTU
+
+endmenu
+
+config NOMADIK_8815
+ bool
+
+config I2C_BITBANG_8815NHK
+ tristate "Driver for bit-bang busses found on the 8815 NHK"
+ depends on I2C && MACH_NOMADIK_8815NHK
+ select I2C_ALGOBIT
+ default y
+
+endif
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile
new file mode 100644
index 00000000..a6bbd1a7
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+# Object file lists.
+
+obj-y += clock.o
+
+# Cpu revision
+obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
+
+# Specific board support
+obj-$(CONFIG_MACH_NOMADIK_8815NHK) += board-nhk8815.o
+
+# Nomadik extra devices
+obj-$(CONFIG_I2C_BITBANG_8815NHK) += i2c-8815nhk.o
diff --git a/arch/arm/mach-nomadik/Makefile.boot b/arch/arm/mach-nomadik/Makefile.boot
new file mode 100644
index 00000000..c7e75acf
--- /dev/null
+++ b/arch/arm/mach-nomadik/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
new file mode 100644
index 00000000..13993035
--- /dev/null
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/mach-nomadik/board-8815nhk.c
+ *
+ * Copyright (C) STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * NHK15 board specifc driver definition
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <asm/sizes.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <plat/mtu.h>
+
+#include <mach/setup.h>
+#include <mach/nand.h>
+#include <mach/fsmc.h>
+
+/* Initial value for SRC control register: all timers use MXTAL/8 source */
+#define SRC_CR_INIT_MASK 0x00007fff
+#define SRC_CR_INIT_VAL 0x2aaa8000
+
+/* These addresses span 16MB, so use three individual pages */
+static struct resource nhk8815_nand_resources[] = {
+ {
+ .name = "nand_addr",
+ .start = NAND_IO_ADDR,
+ .end = NAND_IO_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "nand_cmd",
+ .start = NAND_IO_CMD,
+ .end = NAND_IO_CMD + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "nand_data",
+ .start = NAND_IO_DATA,
+ .end = NAND_IO_DATA + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static int nhk8815_nand_init(void)
+{
+ /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */
+ writel(0x0000000E, FSMC_PCR(0));
+ writel(0x000D0A00, FSMC_PMEM(0));
+ writel(0x00100A00, FSMC_PATT(0));
+
+ /* enable access to the chip select area */
+ writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0));
+
+ return 0;
+}
+
+/*
+ * These partitions are the same as those used in the 2.6.20 release
+ * shipped by the vendor; the first two partitions are mandated
+ * by the boot ROM, and the bootloader area is somehow oversized...
+ */
+static struct mtd_partition nhk8815_partitions[] = {
+ {
+ .name = "X-Loader(NAND)",
+ .offset = 0,
+ .size = SZ_256K,
+ }, {
+ .name = "MemInit(NAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ }, {
+ .name = "BootLoader(NAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ }, {
+ .name = "Kernel zImage(NAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 3 * SZ_1M,
+ }, {
+ .name = "Root Filesystem(NAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 22 * SZ_1M,
+ }, {
+ .name = "User Filesystem(NAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct nomadik_nand_platform_data nhk8815_nand_data = {
+ .parts = nhk8815_partitions,
+ .nparts = ARRAY_SIZE(nhk8815_partitions),
+ .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING \
+ | NAND_NO_READRDY | NAND_NO_AUTOINCR,
+ .init = nhk8815_nand_init,
+};
+
+static struct platform_device nhk8815_nand_device = {
+ .name = "nomadik_nand",
+ .dev = {
+ .platform_data = &nhk8815_nand_data,
+ },
+ .resource = nhk8815_nand_resources,
+ .num_resources = ARRAY_SIZE(nhk8815_nand_resources),
+};
+
+/* These are the partitions for the OneNand device, different from above */
+static struct mtd_partition nhk8815_onenand_partitions[] = {
+ {
+ .name = "X-Loader(OneNAND)",
+ .offset = 0,
+ .size = SZ_256K,
+ }, {
+ .name = "MemInit(OneNAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ }, {
+ .name = "BootLoader(OneNAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M-SZ_256K,
+ }, {
+ .name = "SysImage(OneNAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * SZ_1M,
+ }, {
+ .name = "Root Filesystem(OneNAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 22 * SZ_1M,
+ }, {
+ .name = "User Filesystem(OneNAND)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct onenand_platform_data nhk8815_onenand_data = {
+ .parts = nhk8815_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions),
+};
+
+static struct resource nhk8815_onenand_resource[] = {
+ {
+ .start = 0x30000000,
+ .end = 0x30000000 + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device nhk8815_onenand_device = {
+ .name = "onenand-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &nhk8815_onenand_data,
+ },
+ .resource = nhk8815_onenand_resource,
+ .num_resources = ARRAY_SIZE(nhk8815_onenand_resource),
+};
+
+static void __init nhk8815_onenand_init(void)
+{
+#ifdef CONFIG_MTD_ONENAND
+ /* Set up SMCS0 for OneNand */
+ writel(0x000030db, FSMC_BCR(0));
+ writel(0x02100551, FSMC_BTR(0));
+#endif
+}
+
+#define __MEM_4K_RESOURCE(x) \
+ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+static struct amba_device uart0_device = {
+ .dev = { .init_name = "uart0" },
+ __MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
+ .irq = {IRQ_UART0, NO_IRQ},
+};
+
+static struct amba_device uart1_device = {
+ .dev = { .init_name = "uart1" },
+ __MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
+ .irq = {IRQ_UART1, NO_IRQ},
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &uart0_device,
+ &uart1_device,
+};
+
+static struct resource nhk8815_eth_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x34000000 + 0x300,
+ .end = 0x34000000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = NOMADIK_GPIO_TO_IRQ(115),
+ .end = NOMADIK_GPIO_TO_IRQ(115),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
+ }
+};
+
+static struct platform_device nhk8815_eth_device = {
+ .name = "smc91x",
+ .resource = nhk8815_eth_resources,
+ .num_resources = ARRAY_SIZE(nhk8815_eth_resources),
+};
+
+static int __init nhk8815_eth_init(void)
+{
+ int gpio_nr = 115; /* hardwired in the board */
+ int err;
+
+ err = gpio_request(gpio_nr, "eth_irq");
+ if (!err) err = nmk_gpio_set_mode(gpio_nr, NMK_GPIO_ALT_GPIO);
+ if (!err) err = gpio_direction_input(gpio_nr);
+ if (err)
+ pr_err("Error %i in %s\n", err, __func__);
+ return err;
+}
+device_initcall(nhk8815_eth_init);
+
+static struct platform_device *nhk8815_platform_devices[] __initdata = {
+ &nhk8815_nand_device,
+ &nhk8815_onenand_device,
+ &nhk8815_eth_device,
+ /* will add more devices */
+};
+
+static void __init nomadik_timer_init(void)
+{
+ u32 src_cr;
+
+ /* Configure timer sources in "system reset controller" ctrl reg */
+ src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
+ src_cr &= SRC_CR_INIT_MASK;
+ src_cr |= SRC_CR_INIT_VAL;
+ writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
+
+ /* Save global pointer to mtu, used by platform timer code */
+ mtu_base = io_p2v(NOMADIK_MTU0_BASE);
+
+ nmdk_timer_init();
+}
+
+static struct sys_timer nomadik_timer = {
+ .init = nomadik_timer_init,
+};
+
+static void __init nhk8815_platform_init(void)
+{
+ int i;
+
+ cpu8815_platform_init();
+ nhk8815_onenand_init();
+ platform_add_devices(nhk8815_platform_devices,
+ ARRAY_SIZE(nhk8815_platform_devices));
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(NOMADIK, "NHK8815")
+ /* Maintainer: ST MicroElectronics */
+ .boot_params = 0x100,
+ .map_io = cpu8815_map_io,
+ .init_irq = cpu8815_init_irq,
+ .timer = &nomadik_timer,
+ .init_machine = nhk8815_platform_init,
+MACHINE_END
diff --git a/arch/arm/mach-nomadik/clock.c b/arch/arm/mach-nomadik/clock.c
new file mode 100644
index 00000000..48a59f24
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.c
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/arm/mach-nomadik/clock.c
+ *
+ * Copyright (C) 2009 Alessandro Rubini
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include "clock.h"
+
+/*
+ * The nomadik board uses generic clocks, but the serial pl011 file
+ * calls clk_enable(), clk_disable(), clk_get_rate(), so we provide them
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+static struct clk clk_24 = {
+ .rate = 2400000,
+};
+
+static struct clk clk_48 = {
+ .rate = 48 * 1000 * 1000,
+};
+
+/*
+ * Catch-all default clock to satisfy drivers using the clk API. We don't
+ * model the actual hardware clocks yet.
+ */
+static struct clk clk_default;
+
+#define CLK(_clk, dev) \
+ { \
+ .clk = _clk, \
+ .dev_id = dev, \
+ }
+
+static struct clk_lookup lookups[] = {
+ {
+ .con_id = "apb_pclk",
+ .clk = &clk_default,
+ },
+ CLK(&clk_24, "mtu0"),
+ CLK(&clk_24, "mtu1"),
+ CLK(&clk_48, "uart0"),
+ CLK(&clk_48, "uart1"),
+ CLK(&clk_default, "gpio.0"),
+ CLK(&clk_default, "gpio.1"),
+ CLK(&clk_default, "gpio.2"),
+ CLK(&clk_default, "gpio.3"),
+ CLK(&clk_default, "rng"),
+};
+
+int __init clk_init(void)
+{
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+ return 0;
+}
diff --git a/arch/arm/mach-nomadik/clock.h b/arch/arm/mach-nomadik/clock.h
new file mode 100644
index 00000000..78da2e7c
--- /dev/null
+++ b/arch/arm/mach-nomadik/clock.h
@@ -0,0 +1,15 @@
+
+/*
+ * linux/arch/arm/mach-nomadik/clock.h
+ *
+ * Copyright (C) 2009 Alessandro Rubini
+ *
+ * This program is free software; you can 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 clk {
+ unsigned long rate;
+};
+
+int __init clk_init(void);
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
new file mode 100644
index 00000000..ac58e3b0
--- /dev/null
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright STMicroelectronics, 2007.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/vic.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "clock.h"
+
+#define __MEM_4K_RESOURCE(x) \
+ .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+/* The 8815 has 4 GPIO blocks, let's register them immediately */
+
+#define GPIO_RESOURCE(block) \
+ { \
+ .start = NOMADIK_GPIO##block##_BASE, \
+ .end = NOMADIK_GPIO##block##_BASE + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = IRQ_GPIO##block, \
+ .end = IRQ_GPIO##block, \
+ .flags = IORESOURCE_IRQ, \
+ }
+
+#define GPIO_DEVICE(block) \
+ { \
+ .name = "gpio", \
+ .id = block, \
+ .num_resources = 2, \
+ .resource = &cpu8815_gpio_resources[block * 2], \
+ .dev = { \
+ .platform_data = &cpu8815_gpio[block], \
+ }, \
+ }
+
+static struct nmk_gpio_platform_data cpu8815_gpio[] = {
+ {
+ .name = "GPIO-0-31",
+ .first_gpio = 0,
+ .first_irq = NOMADIK_GPIO_TO_IRQ(0),
+ }, {
+ .name = "GPIO-32-63",
+ .first_gpio = 32,
+ .first_irq = NOMADIK_GPIO_TO_IRQ(32),
+ }, {
+ .name = "GPIO-64-95",
+ .first_gpio = 64,
+ .first_irq = NOMADIK_GPIO_TO_IRQ(64),
+ }, {
+ .name = "GPIO-96-127", /* 124..127 not routed to pin */
+ .first_gpio = 96,
+ .first_irq = NOMADIK_GPIO_TO_IRQ(96),
+ }
+};
+
+static struct resource cpu8815_gpio_resources[] = {
+ GPIO_RESOURCE(0),
+ GPIO_RESOURCE(1),
+ GPIO_RESOURCE(2),
+ GPIO_RESOURCE(3),
+};
+
+static struct platform_device cpu8815_platform_gpio[] = {
+ GPIO_DEVICE(0),
+ GPIO_DEVICE(1),
+ GPIO_DEVICE(2),
+ GPIO_DEVICE(3),
+};
+
+static struct amba_device cpu8815_amba_rng = {
+ .dev = {
+ .init_name = "rng",
+ },
+ __MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
+};
+
+static struct platform_device *platform_devs[] __initdata = {
+ cpu8815_platform_gpio + 0,
+ cpu8815_platform_gpio + 1,
+ cpu8815_platform_gpio + 2,
+ cpu8815_platform_gpio + 3,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ &cpu8815_amba_rng
+};
+
+static int __init cpu8815_init(void)
+{
+ int i;
+
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+ return 0;
+}
+arch_initcall(cpu8815_init);
+
+/* All SoC devices live in the same area (see hardware.h) */
+static struct map_desc nomadik_io_desc[] __initdata = {
+ {
+ .virtual = NOMADIK_IO_VIRTUAL,
+ .pfn = __phys_to_pfn(NOMADIK_IO_PHYSICAL),
+ .length = NOMADIK_IO_SIZE,
+ .type = MT_DEVICE,
+ }
+ /* static ram and secured ram may be added later */
+};
+
+void __init cpu8815_map_io(void)
+{
+ iotable_init(nomadik_io_desc, ARRAY_SIZE(nomadik_io_desc));
+}
+
+void __init cpu8815_init_irq(void)
+{
+ /* This modified VIC cell has two register blocks, at 0 and 0x20 */
+ vic_init(io_p2v(NOMADIK_IC_BASE + 0x00), IRQ_VIC_START + 0, ~0, 0);
+ vic_init(io_p2v(NOMADIK_IC_BASE + 0x20), IRQ_VIC_START + 32, ~0, 0);
+
+ /*
+ * Init clocks here so that they are available for system timer
+ * initialization.
+ */
+ clk_init();
+}
+
+/*
+ * This function is called from the board init ("init_machine").
+ */
+ void __init cpu8815_platform_init(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ /* At full speed latency must be >=2, so 0x249 in low bits */
+ l2x0_init(io_p2v(NOMADIK_L2CC_BASE), 0x00730249, 0xfe000fff);
+#endif
+ return;
+}
diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c
new file mode 100644
index 00000000..abfe25a0
--- /dev/null
+++ b/arch/arm/mach-nomadik/i2c-8815nhk.c
@@ -0,0 +1,65 @@
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/i2c-gpio.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+/*
+ * There are two busses in the 8815NHK.
+ * They could, in theory, be driven by the hardware component, but we
+ * use bit-bang through GPIO by now, to keep things simple
+ */
+
+static struct i2c_gpio_platform_data nhk8815_i2c_data0 = {
+ /* keep defaults for timeouts; pins are push-pull bidirectional */
+ .scl_pin = 62,
+ .sda_pin = 63,
+};
+
+static struct i2c_gpio_platform_data nhk8815_i2c_data1 = {
+ /* keep defaults for timeouts; pins are push-pull bidirectional */
+ .scl_pin = 53,
+ .sda_pin = 54,
+};
+
+/* first bus: GPIO XX and YY */
+static struct platform_device nhk8815_i2c_dev0 = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &nhk8815_i2c_data0,
+ },
+};
+/* second bus: GPIO XX and YY */
+static struct platform_device nhk8815_i2c_dev1 = {
+ .name = "i2c-gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &nhk8815_i2c_data1,
+ },
+};
+
+static int __init nhk8815_i2c_init(void)
+{
+ nmk_gpio_set_mode(nhk8815_i2c_data0.scl_pin, NMK_GPIO_ALT_GPIO);
+ nmk_gpio_set_mode(nhk8815_i2c_data0.sda_pin, NMK_GPIO_ALT_GPIO);
+ platform_device_register(&nhk8815_i2c_dev0);
+
+ nmk_gpio_set_mode(nhk8815_i2c_data1.scl_pin, NMK_GPIO_ALT_GPIO);
+ nmk_gpio_set_mode(nhk8815_i2c_data1.sda_pin, NMK_GPIO_ALT_GPIO);
+ platform_device_register(&nhk8815_i2c_dev1);
+
+ return 0;
+}
+
+static void __exit nhk8815_i2c_exit(void)
+{
+ platform_device_unregister(&nhk8815_i2c_dev0);
+ platform_device_unregister(&nhk8815_i2c_dev1);
+ return;
+}
+
+module_init(nhk8815_i2c_init);
+module_exit(nhk8815_i2c_exit);
diff --git a/arch/arm/mach-nomadik/include/mach/clkdev.h b/arch/arm/mach-nomadik/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/debug-macro.S b/arch/arm/mach-nomadik/include/mach/debug-macro.S
new file mode 100644
index 00000000..e7151b4b
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/debug-macro.S
@@ -0,0 +1,20 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00100000
+ add \rp, \rp, #0x000fb000
+ add \rv, \rp, #0xf0000000 @ virtual base
+ add \rp, \rp, #0x10000000 @ physical base address
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-nomadik/include/mach/entry-macro.S b/arch/arm/mach-nomadik/include/mach/entry-macro.S
new file mode 100644
index 00000000..49f1aa3b
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/entry-macro.S
@@ -0,0 +1,43 @@
+/*
+ * Low-level IRQ helper macros for Nomadik platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IO_ADDRESS(NOMADIK_IC_BASE)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ /* This stanza gets the irq mask from one of two status registers */
+ mov \irqnr, #0
+ ldr \irqstat, [\base, #VIC_REG_IRQSR0] @ get masked status
+ cmp \irqstat, #0
+ bne 1001f
+ add \irqnr, \irqnr, #32
+ ldr \irqstat, [\base, #VIC_REG_IRQSR1] @ get masked status
+
+1001: tst \irqstat, #15
+ bne 1002f
+ add \irqnr, \irqnr, #4
+ movs \irqstat, \irqstat, lsr #4
+ bne 1001b
+1002: tst \irqstat, #1
+ bne 1003f
+ add \irqnr, \irqnr, #1
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
+ .endm
diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h
new file mode 100644
index 00000000..8c2c0518
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/fsmc.h
@@ -0,0 +1,29 @@
+
+/* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */
+
+#ifndef __ASM_ARCH_FSMC_H
+#define __ASM_ARCH_FSMC_H
+
+#include <mach/hardware.h>
+/*
+ * Register list
+ */
+
+/* bus control reg. and bus timing reg. for CS0..CS3 */
+#define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3))
+#define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04)
+
+/* PC-card and NAND:
+ * PCR = control register
+ * PMEM = memory timing
+ * PATT = attribute timing
+ * PIO = I/O timing
+ * PECCR = ECC result
+ */
+#define FSMC_PCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00)
+#define FSMC_PMEM(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08)
+#define FSMC_PATT(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c)
+#define FSMC_PIO(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10)
+#define FSMC_PECCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14)
+
+#endif /* __ASM_ARCH_FSMC_H */
diff --git a/arch/arm/mach-nomadik/include/mach/gpio.h b/arch/arm/mach-nomadik/include/mach/gpio.h
new file mode 100644
index 00000000..7a81a042
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-nomadik/include/mach/hardware.h b/arch/arm/mach-nomadik/include/mach/hardware.h
new file mode 100644
index 00000000..6316dba3
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/hardware.h
@@ -0,0 +1,90 @@
+/*
+ * This file contains the hardware definitions of the Nomadik.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Nomadik registers live from 0x1000.0000 to 0x1023.0000 -- currently */
+#define NOMADIK_IO_VIRTUAL 0xF0000000 /* VA of IO */
+#define NOMADIK_IO_PHYSICAL 0x10000000 /* PA of IO */
+#define NOMADIK_IO_SIZE 0x00300000 /* 3MB for all regs */
+
+/* used in C code, so cast to proper type */
+#define io_p2v(x) ((void __iomem *)(x) \
+ - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
+#define io_v2p(x) ((unsigned long)(x) \
+ - NOMADIK_IO_VIRTUAL + NOMADIK_IO_PHYSICAL)
+
+/* used in asm code, so no casts */
+#define IO_ADDRESS(x) ((x) - NOMADIK_IO_PHYSICAL + NOMADIK_IO_VIRTUAL)
+
+/*
+ * Base address defination for Nomadik Onchip Logic Block
+ */
+#define NOMADIK_FSMC_BASE 0x10100000 /* FSMC registers */
+#define NOMADIK_SDRAMC_BASE 0x10110000 /* SDRAM Controller */
+#define NOMADIK_CLCDC_BASE 0x10120000 /* CLCD Controller */
+#define NOMADIK_MDIF_BASE 0x10120000 /* MDIF */
+#define NOMADIK_DMA0_BASE 0x10130000 /* DMA0 Controller */
+#define NOMADIK_IC_BASE 0x10140000 /* Vectored Irq Controller */
+#define NOMADIK_DMA1_BASE 0x10150000 /* DMA1 Controller */
+#define NOMADIK_USB_BASE 0x10170000 /* USB-OTG conf reg base */
+#define NOMADIK_CRYP_BASE 0x10180000 /* Crypto processor */
+#define NOMADIK_SHA1_BASE 0x10190000 /* SHA-1 Processor */
+#define NOMADIK_XTI_BASE 0x101A0000 /* XTI */
+#define NOMADIK_RNG_BASE 0x101B0000 /* Random number generator */
+#define NOMADIK_SRC_BASE 0x101E0000 /* SRC base */
+#define NOMADIK_WDOG_BASE 0x101E1000 /* Watchdog */
+#define NOMADIK_MTU0_BASE 0x101E2000 /* Multiple Timer 0 */
+#define NOMADIK_MTU1_BASE 0x101E3000 /* Multiple Timer 1 */
+#define NOMADIK_GPIO0_BASE 0x101E4000 /* GPIO0 */
+#define NOMADIK_GPIO1_BASE 0x101E5000 /* GPIO1 */
+#define NOMADIK_GPIO2_BASE 0x101E6000 /* GPIO2 */
+#define NOMADIK_GPIO3_BASE 0x101E7000 /* GPIO3 */
+#define NOMADIK_RTC_BASE 0x101E8000 /* Real Time Clock base */
+#define NOMADIK_PMU_BASE 0x101E9000 /* Power Management Unit */
+#define NOMADIK_OWM_BASE 0x101EA000 /* One wire master */
+#define NOMADIK_SCR_BASE 0x101EF000 /* Secure Control registers */
+#define NOMADIK_MSP2_BASE 0x101F0000 /* MSP 2 interface */
+#define NOMADIK_MSP1_BASE 0x101F1000 /* MSP 1 interface */
+#define NOMADIK_UART2_BASE 0x101F2000 /* UART 2 interface */
+#define NOMADIK_SSIRx_BASE 0x101F3000 /* SSI 8-ch rx interface */
+#define NOMADIK_SSITx_BASE 0x101F4000 /* SSI 8-ch tx interface */
+#define NOMADIK_MSHC_BASE 0x101F5000 /* Memory Stick(Pro) Host */
+#define NOMADIK_SDI_BASE 0x101F6000 /* SD-card/MM-Card */
+#define NOMADIK_I2C1_BASE 0x101F7000 /* I2C1 interface */
+#define NOMADIK_I2C0_BASE 0x101F8000 /* I2C0 interface */
+#define NOMADIK_MSP0_BASE 0x101F9000 /* MSP 0 interface */
+#define NOMADIK_FIRDA_BASE 0x101FA000 /* FIrDA interface */
+#define NOMADIK_UART1_BASE 0x101FB000 /* UART 1 interface */
+#define NOMADIK_SSP_BASE 0x101FC000 /* SSP interface */
+#define NOMADIK_UART0_BASE 0x101FD000 /* UART 0 interface */
+#define NOMADIK_SGA_BASE 0x101FE000 /* SGA interface */
+#define NOMADIK_L2CC_BASE 0x10210000 /* L2 Cache controller */
+
+/* Other ranges, not for p2v/v2p */
+#define NOMADIK_BACKUP_RAM 0x80010000
+#define NOMADIK_EBROM 0x80000000 /* Embedded boot ROM */
+#define NOMADIK_HAMACV_DMEM_BASE 0xA0100000 /* HAMACV Data Memory Start */
+#define NOMADIK_HAMACV_DMEM_END 0xA01FFFFF /* HAMACV Data Memory End */
+#define NOMADIK_HAMACA_DMEM 0xA0200000 /* HAMACA Data Memory Space */
+
+#define NOMADIK_FSMC_VA IO_ADDRESS(NOMADIK_FSMC_BASE)
+#define NOMADIK_MTU0_VA IO_ADDRESS(NOMADIK_MTU0_BASE)
+#define NOMADIK_MTU1_VA IO_ADDRESS(NOMADIK_MTU1_BASE)
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-nomadik/include/mach/io.h b/arch/arm/mach-nomadik/include/mach/io.h
new file mode 100644
index 00000000..2e1eca1b
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-nomadik/include/mach/io.h (copied from mach-sa1100)
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/irqs.h b/arch/arm/mach-nomadik/include/mach/irqs.h
new file mode 100644
index 00000000..8faabc56
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/irqs.h
@@ -0,0 +1,82 @@
+/*
+ * mach-nomadik/include/mach/irqs.h
+ *
+ * Copyright (C) ST Microelectronics
+ *
+ * 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include <mach/hardware.h>
+
+#define IRQ_VIC_START 0 /* first VIC interrupt is 0 */
+
+/*
+ * Interrupt numbers generic for all Nomadik Chip cuts
+ */
+#define IRQ_WATCHDOG 0
+#define IRQ_SOFTINT 1
+#define IRQ_CRYPTO 2
+#define IRQ_OWM 3
+#define IRQ_MTU0 4
+#define IRQ_MTU1 5
+#define IRQ_GPIO0 6
+#define IRQ_GPIO1 7
+#define IRQ_GPIO2 8
+#define IRQ_GPIO3 9
+#define IRQ_RTC_RTT 10
+#define IRQ_SSP 11
+#define IRQ_UART0 12
+#define IRQ_DMA1 13
+#define IRQ_CLCD_MDIF 14
+#define IRQ_DMA0 15
+#define IRQ_PWRFAIL 16
+#define IRQ_UART1 17
+#define IRQ_FIRDA 18
+#define IRQ_MSP0 19
+#define IRQ_I2C0 20
+#define IRQ_I2C1 21
+#define IRQ_SDMMC 22
+#define IRQ_USBOTG 23
+#define IRQ_SVA_IT0 24
+#define IRQ_SVA_IT1 25
+#define IRQ_SAA_IT0 26
+#define IRQ_SAA_IT1 27
+#define IRQ_UART2 28
+#define IRQ_MSP2 31
+#define IRQ_L2CC 48
+#define IRQ_HPI 49
+#define IRQ_SKE 50
+#define IRQ_KP 51
+#define IRQ_MEMST 54
+#define IRQ_SGA_IT 58
+#define IRQ_USBM 60
+#define IRQ_MSP1 62
+
+#define NOMADIK_SOC_NR_IRQS 64
+
+/* After chip-specific IRQ numbers we have the GPIO ones */
+#define NOMADIK_NR_GPIO 128 /* last 4 not wired to pins */
+#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + NOMADIK_SOC_NR_IRQS)
+#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - NOMADIK_SOC_NR_IRQS)
+#define NR_IRQS NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+
+/* Following two are used by entry_macro.S, to access our dual-vic */
+#define VIC_REG_IRQSR0 0
+#define VIC_REG_IRQSR1 0x20
+
+#endif /* __ASM_ARCH_IRQS_H */
+
diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h
new file mode 100644
index 00000000..d3325211
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * mach-nomadik/include/mach/memory.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/nand.h b/arch/arm/mach-nomadik/include/mach/nand.h
new file mode 100644
index 00000000..c3c8254c
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/nand.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_ARCH_NAND_H
+#define __ASM_ARCH_NAND_H
+
+struct nomadik_nand_platform_data {
+ struct mtd_partition *parts;
+ int nparts;
+ int options;
+ int (*init) (void);
+ int (*exit) (void);
+};
+
+#define NAND_IO_DATA 0x40000000
+#define NAND_IO_CMD 0x40800000
+#define NAND_IO_ADDR 0x41000000
+
+#endif /* __ASM_ARCH_NAND_H */
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
new file mode 100644
index 00000000..b7897edf
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/setup.h
@@ -0,0 +1,22 @@
+
+/*
+ * These symbols are needed for board-specific files to call their
+ * own cpu-specific files
+ */
+
+#ifndef __ASM_ARCH_SETUP_H
+#define __ASM_ARCH_SETUP_H
+
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+#ifdef CONFIG_NOMADIK_8815
+
+extern void cpu8815_map_io(void);
+extern void cpu8815_platform_init(void);
+extern void cpu8815_init_irq(void);
+extern void nmdk_timer_init(void);
+
+#endif /* NOMADIK_8815 */
+
+#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h
new file mode 100644
index 00000000..7119f688
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/system.h
@@ -0,0 +1,45 @@
+/*
+ * mach-nomadik/include/mach/system.h
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ void __iomem *src_rstsr = io_p2v(NOMADIK_SRC_BASE + 0x18);
+
+ /* FIXME: use egpio when implemented */
+
+ /* Write anything to Reset status register */
+ writel(1, src_rstsr);
+}
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/timex.h b/arch/arm/mach-nomadik/include/mach/timex.h
new file mode 100644
index 00000000..318b8896
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/timex.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE 2400000
+
+#endif
diff --git a/arch/arm/mach-nomadik/include/mach/uncompress.h b/arch/arm/mach-nomadik/include/mach/uncompress.h
new file mode 100644
index 00000000..071003bc
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/uncompress.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 STMicroelectronics
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+
+/* we need the constants in amba/serial.h, but it refers to amba_device */
+struct amba_device;
+#include <linux/amba/serial.h>
+
+#define NOMADIK_UART_DR 0x101FB000
+#define NOMADIK_UART_LCRH 0x101FB02c
+#define NOMADIK_UART_CR 0x101FB030
+#define NOMADIK_UART_FR 0x101FB018
+
+static void putc(const char c)
+{
+ /* Do nothing if the UART is not enabled. */
+ if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
+ return;
+
+ if (c == '\n')
+ putc('\r');
+
+ while (readb(NOMADIK_UART_FR) & UART01x_FR_TXFF)
+ barrier();
+ writeb(c, NOMADIK_UART_DR);
+}
+
+static void flush(void)
+{
+ if (!(readb(NOMADIK_UART_CR) & UART01x_CR_UARTEN))
+ return;
+ while (readb(NOMADIK_UART_FR) & UART01x_FR_BUSY)
+ barrier();
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog() /* nothing to do here */
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-nomadik/include/mach/vmalloc.h b/arch/arm/mach-nomadik/include/mach/vmalloc.h
new file mode 100644
index 00000000..f83d574d
--- /dev/null
+++ b/arch/arm/mach-nomadik/include/mach/vmalloc.h
@@ -0,0 +1,2 @@
+
+#define VMALLOC_END 0xe8000000UL
diff --git a/arch/arm/mach-nuc93x/Kconfig b/arch/arm/mach-nuc93x/Kconfig
new file mode 100644
index 00000000..2bc40a28
--- /dev/null
+++ b/arch/arm/mach-nuc93x/Kconfig
@@ -0,0 +1,19 @@
+if ARCH_NUC93X
+
+config CPU_NUC932
+ bool
+ help
+ Support for NUC932 of Nuvoton NUC93X CPUs.
+
+menu "NUC932 Machines"
+
+config MACH_NUC932EVB
+ bool "Nuvoton NUC932 Evaluation Board"
+ default y
+ select CPU_NUC932
+ help
+ Say Y here if you are using the Nuvoton NUC932EVB
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-nuc93x/Makefile b/arch/arm/mach-nuc93x/Makefile
new file mode 100644
index 00000000..440e2dec
--- /dev/null
+++ b/arch/arm/mach-nuc93x/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := irq.o time.o dev.o cpu.o clock.o
+# NUC932 CPU support files
+
+obj-$(CONFIG_CPU_NUC932) += nuc932.o
+
+# machine support
+
+obj-$(CONFIG_MACH_NUC932EVB) += mach-nuc932evb.o
diff --git a/arch/arm/mach-nuc93x/Makefile.boot b/arch/arm/mach-nuc93x/Makefile.boot
new file mode 100644
index 00000000..a057b546
--- /dev/null
+++ b/arch/arm/mach-nuc93x/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+
diff --git a/arch/arm/mach-nuc93x/clock.c b/arch/arm/mach-nuc93x/clock.c
new file mode 100644
index 00000000..0521efbc
--- /dev/null
+++ b/arch/arm/mach-nuc93x/clock.c
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include "clock.h"
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ (clk->enable)(clk, 1);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ (clk->enable)(clk, 0);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return 27000000;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void nuc93x_clk_enable(struct clk *clk, int enable)
+{
+ unsigned int clocks = clk->cken;
+ unsigned long clken;
+
+ clken = __raw_readl(NUC93X_VA_CLKPWR);
+
+ if (enable)
+ clken |= clocks;
+ else
+ clken &= ~clocks;
+
+ __raw_writel(clken, NUC93X_VA_CLKPWR);
+}
+
+void clks_register(struct clk_lookup *clks, size_t num)
+{
+ int i;
+
+ for (i = 0; i < num; i++)
+ clkdev_add(&clks[i]);
+}
diff --git a/arch/arm/mach-nuc93x/clock.h b/arch/arm/mach-nuc93x/clock.h
new file mode 100644
index 00000000..4de1f1da
--- /dev/null
+++ b/arch/arm/mach-nuc93x/clock.h
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-nuc93x/clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ */
+
+#include <linux/clkdev.h>
+
+void nuc93x_clk_enable(struct clk *clk, int enable);
+void clks_register(struct clk_lookup *clks, size_t num);
+
+struct clk {
+ unsigned long cken;
+ unsigned int enabled;
+ void (*enable)(struct clk *, int enable);
+};
+
+#define DEFINE_CLK(_name, _ctrlbit) \
+struct clk clk_##_name = { \
+ .enable = nuc93x_clk_enable, \
+ .cken = (1 << _ctrlbit), \
+ }
+
+#define DEF_CLKLOOK(_clk, _devname, _conname) \
+ { \
+ .clk = _clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
diff --git a/arch/arm/mach-nuc93x/cpu.c b/arch/arm/mach-nuc93x/cpu.c
new file mode 100644
index 00000000..f6ff5d87
--- /dev/null
+++ b/arch/arm/mach-nuc93x/cpu.c
@@ -0,0 +1,135 @@
+/*
+ * linux/arch/arm/mach-nuc93x/cpu.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC93x series cpu common support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* Initial IO mappings */
+
+static struct map_desc nuc93x_iodesc[] __initdata = {
+ IODESC_ENT(IRQ),
+ IODESC_ENT(GCR),
+ IODESC_ENT(UART),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(EBI),
+};
+
+/* Initial nuc932 clock declarations. */
+static DEFINE_CLK(audio, 2);
+static DEFINE_CLK(sd, 3);
+static DEFINE_CLK(jpg, 4);
+static DEFINE_CLK(video, 5);
+static DEFINE_CLK(vpost, 6);
+static DEFINE_CLK(2d, 7);
+static DEFINE_CLK(gpu, 8);
+static DEFINE_CLK(gdma, 9);
+static DEFINE_CLK(adc, 10);
+static DEFINE_CLK(uart, 11);
+static DEFINE_CLK(spi, 12);
+static DEFINE_CLK(pwm, 13);
+static DEFINE_CLK(timer, 14);
+static DEFINE_CLK(wdt, 15);
+static DEFINE_CLK(ac97, 16);
+static DEFINE_CLK(i2s, 16);
+static DEFINE_CLK(usbck, 17);
+static DEFINE_CLK(usb48, 18);
+static DEFINE_CLK(usbh, 19);
+static DEFINE_CLK(i2c, 20);
+static DEFINE_CLK(ext, 0);
+
+static struct clk_lookup nuc932_clkregs[] = {
+ DEF_CLKLOOK(&clk_audio, "nuc932-audio", NULL),
+ DEF_CLKLOOK(&clk_sd, "nuc932-sd", NULL),
+ DEF_CLKLOOK(&clk_jpg, "nuc932-jpg", "NULL"),
+ DEF_CLKLOOK(&clk_video, "nuc932-video", "NULL"),
+ DEF_CLKLOOK(&clk_vpost, "nuc932-vpost", NULL),
+ DEF_CLKLOOK(&clk_2d, "nuc932-2d", NULL),
+ DEF_CLKLOOK(&clk_gpu, "nuc932-gpu", NULL),
+ DEF_CLKLOOK(&clk_gdma, "nuc932-gdma", "NULL"),
+ DEF_CLKLOOK(&clk_adc, "nuc932-adc", NULL),
+ DEF_CLKLOOK(&clk_uart, NULL, "uart"),
+ DEF_CLKLOOK(&clk_spi, "nuc932-spi", NULL),
+ DEF_CLKLOOK(&clk_pwm, "nuc932-pwm", NULL),
+ DEF_CLKLOOK(&clk_timer, NULL, "timer"),
+ DEF_CLKLOOK(&clk_wdt, "nuc932-wdt", NULL),
+ DEF_CLKLOOK(&clk_ac97, "nuc932-ac97", NULL),
+ DEF_CLKLOOK(&clk_i2s, "nuc932-i2s", NULL),
+ DEF_CLKLOOK(&clk_usbck, "nuc932-usbck", NULL),
+ DEF_CLKLOOK(&clk_usb48, "nuc932-usb48", NULL),
+ DEF_CLKLOOK(&clk_usbh, "nuc932-usbh", NULL),
+ DEF_CLKLOOK(&clk_i2c, "nuc932-i2c", NULL),
+ DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+};
+
+/* Initial serial platform data */
+
+struct plat_serial8250_port nuc93x_uart_data[] = {
+ NUC93X_8250PORT(UART0),
+ {},
+};
+
+struct platform_device nuc93x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = nuc93x_uart_data,
+ },
+};
+
+/*Init NUC93x evb io*/
+
+void __init nuc93x_map_io(struct map_desc *mach_desc, int mach_size)
+{
+ unsigned long idcode = 0x0;
+
+ iotable_init(mach_desc, mach_size);
+ iotable_init(nuc93x_iodesc, ARRAY_SIZE(nuc93x_iodesc));
+
+ idcode = __raw_readl(NUC93XPDID);
+ if (idcode == NUC932_CPUID)
+ printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
+ else
+ printk(KERN_ERR "CPU type detect error!\n");
+
+}
+
+/*Init NUC93x clock*/
+
+void __init nuc93x_init_clocks(void)
+{
+ clks_register(nuc932_clkregs, ARRAY_SIZE(nuc932_clkregs));
+}
+
diff --git a/arch/arm/mach-nuc93x/cpu.h b/arch/arm/mach-nuc93x/cpu.h
new file mode 100644
index 00000000..9def2819
--- /dev/null
+++ b/arch/arm/mach-nuc93x/cpu.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/mach-nuc93x/cpu.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Header file for NUC93X CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ *
+ */
+
+#define IODESC_ENT(y) \
+{ \
+ .virtual = (unsigned long)NUC93X_VA_##y, \
+ .pfn = __phys_to_pfn(NUC93X_PA_##y), \
+ .length = NUC93X_SZ_##y, \
+ .type = MT_DEVICE, \
+}
+
+#define NUC93X_8250PORT(name) \
+{ \
+ .membase = name##_BA, \
+ .mapbase = name##_PA, \
+ .irq = IRQ_##name, \
+ .uartclk = 57139200, \
+ .regshift = 2, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+}
+
+/*Cpu identifier register*/
+
+#define NUC93XPDID NUC93X_VA_GCR
+#define NUC932_CPUID 0x29550091
+
+/* extern file from cpu.c */
+
+extern void nuc93x_clock_source(struct device *dev, unsigned char *src);
+extern void nuc93x_init_clocks(void);
+extern void nuc93x_map_io(struct map_desc *mach_desc, int mach_size);
+extern void nuc93x_board_init(struct platform_device **device, int size);
+extern struct platform_device nuc93x_serial_device;
+
diff --git a/arch/arm/mach-nuc93x/dev.c b/arch/arm/mach-nuc93x/dev.c
new file mode 100644
index 00000000..a962ae95
--- /dev/null
+++ b/arch/arm/mach-nuc93x/dev.c
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-nuc93x/dev.c
+ *
+ * Copyright (C) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include "cpu.h"
+
+/*Here should be your evb resourse,such as LCD*/
+
+static struct platform_device *nuc93x_public_dev[] __initdata = {
+ &nuc93x_serial_device,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc93x_board_init(struct platform_device **device, int size)
+{
+ platform_add_devices(device, size);
+ platform_add_devices(nuc93x_public_dev, ARRAY_SIZE(nuc93x_public_dev));
+}
+
diff --git a/arch/arm/mach-nuc93x/include/mach/clkdev.h b/arch/arm/mach-nuc93x/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/entry-macro.S b/arch/arm/mach-nuc93x/include/mach/entry-macro.S
new file mode 100644
index 00000000..1352cbda
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/entry-macro.S
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/entry-macro.S
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ */
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \base, #AIC_BA
+
+ ldr \irqnr, [ \base, #AIC_IPER]
+ ldr \irqnr, [ \base, #AIC_ISNR]
+ cmp \irqnr, #0
+
+ .endm
+
+ /* currently don't need an disable_fiq macro */
+
+ .macro disable_fiq
+ .endm
diff --git a/arch/arm/mach-nuc93x/include/mach/hardware.h b/arch/arm/mach-nuc93x/include/mach/hardware.h
new file mode 100644
index 00000000..fb5c6fcb
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/hardware.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/hardware.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/io.h b/arch/arm/mach-nuc93x/include/mach/io.h
new file mode 100644
index 00000000..72e5051c
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/io.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+
+#define __mem_pci(a) (a)
+#define __io(a) __typesafe_io(a)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/irqs.h b/arch/arm/mach-nuc93x/include/mach/irqs.h
new file mode 100644
index 00000000..7c4aa71e
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/irqs.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/irqs.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#define NUC93X_IRQ(x) (x)
+
+/* Main cpu interrupts */
+
+#define IRQ_WDT NUC93X_IRQ(1)
+#define IRQ_IRQ0 NUC93X_IRQ(2)
+#define IRQ_IRQ1 NUC93X_IRQ(3)
+#define IRQ_IRQ2 NUC93X_IRQ(4)
+#define IRQ_IRQ3 NUC93X_IRQ(5)
+#define IRQ_USBH NUC93X_IRQ(6)
+#define IRQ_APU NUC93X_IRQ(7)
+#define IRQ_VPOST NUC93X_IRQ(8)
+#define IRQ_ADC NUC93X_IRQ(9)
+#define IRQ_UART0 NUC93X_IRQ(10)
+#define IRQ_TIMER0 NUC93X_IRQ(11)
+#define IRQ_GPU0 NUC93X_IRQ(12)
+#define IRQ_GPU1 NUC93X_IRQ(13)
+#define IRQ_GPU2 NUC93X_IRQ(14)
+#define IRQ_GPU3 NUC93X_IRQ(15)
+#define IRQ_GPU4 NUC93X_IRQ(16)
+#define IRQ_VIN NUC93X_IRQ(17)
+#define IRQ_USBD NUC93X_IRQ(18)
+#define IRQ_VRAMLD NUC93X_IRQ(19)
+#define IRQ_GDMA0 NUC93X_IRQ(20)
+#define IRQ_GDMA1 NUC93X_IRQ(21)
+#define IRQ_SDIO NUC93X_IRQ(22)
+#define IRQ_FMI NUC93X_IRQ(22)
+#define IRQ_JPEG NUC93X_IRQ(23)
+#define IRQ_SPI0 NUC93X_IRQ(24)
+#define IRQ_SPI1 NUC93X_IRQ(25)
+#define IRQ_RTC NUC93X_IRQ(26)
+#define IRQ_PWM0 NUC93X_IRQ(27)
+#define IRQ_PWM1 NUC93X_IRQ(28)
+#define IRQ_PWM2 NUC93X_IRQ(29)
+#define IRQ_PWM3 NUC93X_IRQ(30)
+#define IRQ_I2SAC97 NUC93X_IRQ(31)
+#define IRQ_CAP0 IRQ_PWM0
+#define IRQ_CAP1 IRQ_PWM1
+#define IRQ_CAP2 IRQ_PWM2
+#define IRQ_CAP3 IRQ_PWM3
+#define NR_IRQS (IRQ_I2SAC97 + 1)
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/map.h b/arch/arm/mach-nuc93x/include/mach/map.h
new file mode 100644
index 00000000..fd0b5e89
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/map.h
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/map.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#define MAP_OFFSET (0xfff00000)
+#define CLK_OFFSET (0x10)
+
+#ifndef __ASSEMBLY__
+#define NUC93X_ADDR(x) ((void __iomem *)(0xF0000000 + ((x)&(~MAP_OFFSET))))
+#else
+#define NUC93X_ADDR(x) (0xF0000000 + ((x)&(~MAP_OFFSET)))
+#endif
+
+ /*
+ * nuc932 hardware register definition
+ */
+
+#define NUC93X_PA_IRQ (0xFFF83000)
+#define NUC93X_PA_GCR (0xFFF00000)
+#define NUC93X_PA_EBI (0xFFF01000)
+#define NUC93X_PA_UART (0xFFF80000)
+#define NUC93X_PA_TIMER (0xFFF81000)
+#define NUC93X_PA_GPIO (0xFFF84000)
+#define NUC93X_PA_GDMA (0xFFF03000)
+#define NUC93X_PA_USBHOST (0xFFF0d000)
+#define NUC93X_PA_I2C (0xFFF89000)
+#define NUC93X_PA_LCD (0xFFF06000)
+#define NUC93X_PA_GE (0xFFF05000)
+#define NUC93X_PA_ADC (0xFFF85000)
+#define NUC93X_PA_RTC (0xFFF87000)
+#define NUC93X_PA_PWM (0xFFF82000)
+#define NUC93X_PA_ACTL (0xFFF0a000)
+#define NUC93X_PA_USBDEV (0xFFF0C000)
+#define NUC93X_PA_JEPEG (0xFFF0e000)
+#define NUC93X_PA_CACHE_T (0xFFF60000)
+#define NUC93X_PA_VRAM (0xFFF0b000)
+#define NUC93X_PA_DMAC (0xFFF09000)
+#define NUC93X_PA_I2SM (0xFFF08000)
+#define NUC93X_PA_CACHE (0xFFF02000)
+#define NUC93X_PA_GPU (0xFFF04000)
+#define NUC93X_PA_VIDEOIN (0xFFF07000)
+#define NUC93X_PA_SPI0 (0xFFF86000)
+#define NUC93X_PA_SPI1 (0xFFF88000)
+
+ /*
+ * nuc932 virtual address mapping.
+ * interrupt controller is the first thing we put in, to make
+ * the assembly code for the irq detection easier
+ */
+
+#define NUC93X_VA_IRQ NUC93X_ADDR(0x00000000)
+#define NUC93X_SZ_IRQ SZ_4K
+
+#define NUC93X_VA_GCR NUC93X_ADDR(NUC93X_PA_IRQ)
+#define NUC93X_VA_CLKPWR (NUC93X_VA_GCR+CLK_OFFSET)
+#define NUC93X_SZ_GCR SZ_4K
+
+/* EBI management */
+
+#define NUC93X_VA_EBI NUC93X_ADDR(NUC93X_PA_EBI)
+#define NUC93X_SZ_EBI SZ_4K
+
+/* UARTs */
+
+#define NUC93X_VA_UART NUC93X_ADDR(NUC93X_PA_UART)
+#define NUC93X_SZ_UART SZ_4K
+
+/* Timers */
+
+#define NUC93X_VA_TIMER NUC93X_ADDR(NUC93X_PA_TIMER)
+#define NUC93X_SZ_TIMER SZ_4K
+
+/* GPIO ports */
+
+#define NUC93X_VA_GPIO NUC93X_ADDR(NUC93X_PA_GPIO)
+#define NUC93X_SZ_GPIO SZ_4K
+
+/* GDMA control */
+
+#define NUC93X_VA_GDMA NUC93X_ADDR(NUC93X_PA_GDMA)
+#define NUC93X_SZ_GDMA SZ_4K
+
+/* I2C hardware controller */
+
+#define NUC93X_VA_I2C NUC93X_ADDR(NUC93X_PA_I2C)
+#define NUC93X_SZ_I2C SZ_4K
+
+/* LCD controller*/
+
+#define NUC93X_VA_LCD NUC93X_ADDR(NUC93X_PA_LCD)
+#define NUC93X_SZ_LCD SZ_4K
+
+/* 2D controller*/
+
+#define NUC93X_VA_GE NUC93X_ADDR(NUC93X_PA_GE)
+#define NUC93X_SZ_GE SZ_4K
+
+/* ADC */
+
+#define NUC93X_VA_ADC NUC93X_ADDR(NUC93X_PA_ADC)
+#define NUC93X_SZ_ADC SZ_4K
+
+/* RTC */
+
+#define NUC93X_VA_RTC NUC93X_ADDR(NUC93X_PA_RTC)
+#define NUC93X_SZ_RTC SZ_4K
+
+/* Pulse Width Modulation(PWM) Registers */
+
+#define NUC93X_VA_PWM NUC93X_ADDR(NUC93X_PA_PWM)
+#define NUC93X_SZ_PWM SZ_4K
+
+/* Audio Controller controller */
+
+#define NUC93X_VA_ACTL NUC93X_ADDR(NUC93X_PA_ACTL)
+#define NUC93X_SZ_ACTL SZ_4K
+
+/* USB Device port */
+
+#define NUC93X_VA_USBDEV NUC93X_ADDR(NUC93X_PA_USBDEV)
+#define NUC93X_SZ_USBDEV SZ_4K
+
+/* USB host controller*/
+#define NUC93X_VA_USBHOST NUC93X_ADDR(NUC93X_PA_USBHOST)
+#define NUC93X_SZ_USBHOST SZ_4K
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/memory.h b/arch/arm/mach-nuc93x/include/mach/memory.h
new file mode 100644
index 00000000..ef9864b0
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/memory.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/memory.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-clock.h b/arch/arm/mach-nuc93x/include/mach/regs-clock.h
new file mode 100644
index 00000000..5cb2954f
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/regs-clock.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H
+
+/* Clock Control Registers */
+#define CLK_BA NUC93X_VA_CLKPWR
+#define REG_CLKEN (CLK_BA + 0x00)
+#define REG_CLKSEL (CLK_BA + 0x04)
+#define REG_CLKDIV (CLK_BA + 0x08)
+#define REG_PLLCON0 (CLK_BA + 0x0C)
+#define REG_PLLCON1 (CLK_BA + 0x10)
+#define REG_PMCON (CLK_BA + 0x14)
+#define REG_IRQWAKECON (CLK_BA + 0x18)
+#define REG_IRQWAKEFLAG (CLK_BA + 0x1C)
+#define REG_IPSRST (CLK_BA + 0x20)
+#define REG_CLKEN1 (CLK_BA + 0x24)
+#define REG_CLKDIV1 (CLK_BA + 0x28)
+
+/* Define PLL freq setting */
+#define PLL_DISABLE 0x12B63
+#define PLL_66MHZ 0x2B63
+#define PLL_100MHZ 0x4F64
+#define PLL_120MHZ 0x4F63
+#define PLL_166MHZ 0x4124
+#define PLL_200MHZ 0x4F24
+
+/* Define AHB:CPUFREQ ratio */
+#define AHB_CPUCLK_1_1 0x00
+#define AHB_CPUCLK_1_2 0x01
+#define AHB_CPUCLK_1_4 0x02
+#define AHB_CPUCLK_1_8 0x03
+
+/* Define APB:AHB ratio */
+#define APB_AHB_1_2 0x01
+#define APB_AHB_1_4 0x02
+#define APB_AHB_1_8 0x03
+
+/* Define clock skew */
+#define DEFAULTSKEW 0x48
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-ebi.h b/arch/arm/mach-nuc93x/include/mach/regs-ebi.h
new file mode 100644
index 00000000..3c72550e
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/regs-ebi.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA NUC93X_VA_EBI
+#define REG_EBICON (EBI_BA + 0x00)
+#define REG_ROMCON (EBI_BA + 0x04)
+#define REG_SDCONF0 (EBI_BA + 0x08)
+#define REG_SDCONF1 (EBI_BA + 0x0C)
+#define REG_SDTIME0 (EBI_BA + 0x10)
+#define REG_SDTIME1 (EBI_BA + 0x14)
+#define REG_EXT0CON (EBI_BA + 0x18)
+#define REG_EXT1CON (EBI_BA + 0x1C)
+#define REG_EXT2CON (EBI_BA + 0x20)
+#define REG_EXT3CON (EBI_BA + 0x24)
+#define REG_EXT4CON (EBI_BA + 0x28)
+#define REG_CKSKEW (EBI_BA + 0x2C)
+
+#endif /* __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-irq.h b/arch/arm/mach-nuc93x/include/mach/regs-irq.h
new file mode 100644
index 00000000..23021592
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/regs-irq.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* Advance Interrupt Controller (AIC) Registers */
+
+#define AIC_BA NUC93X_VA_IRQ
+
+#define REG_AIC_IRQSC (AIC_BA+0x80)
+#define REG_AIC_GEN (AIC_BA+0x84)
+#define REG_AIC_GASR (AIC_BA+0x88)
+#define REG_AIC_GSCR (AIC_BA+0x8C)
+#define REG_AIC_IRSR (AIC_BA+0x100)
+#define REG_AIC_IASR (AIC_BA+0x104)
+#define REG_AIC_ISR (AIC_BA+0x108)
+#define REG_AIC_IPER (AIC_BA+0x10C)
+#define REG_AIC_ISNR (AIC_BA+0x110)
+#define REG_AIC_IMR (AIC_BA+0x114)
+#define REG_AIC_OISR (AIC_BA+0x118)
+#define REG_AIC_MECR (AIC_BA+0x120)
+#define REG_AIC_MDCR (AIC_BA+0x124)
+#define REG_AIC_SSCR (AIC_BA+0x128)
+#define REG_AIC_SCCR (AIC_BA+0x12C)
+#define REG_AIC_EOSCR (AIC_BA+0x130)
+#define AIC_IPER (0x10C)
+#define AIC_ISNR (0x110)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-serial.h b/arch/arm/mach-nuc93x/include/mach/regs-serial.h
new file mode 100644
index 00000000..767a047a
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/regs-serial.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define UART0_BA NUC93X_VA_UART
+#define UART1_BA (NUC93X_VA_UART+0x100)
+
+#define UART0_PA NUC93X_PA_UART
+#define UART1_PA (NUC93X_PA_UART+0x100)
+
+
+#ifndef __ASSEMBLY__
+
+struct nuc93x_uart_clksrc {
+ const char *name;
+ unsigned int divisor;
+ unsigned int min_baud;
+ unsigned int max_baud;
+};
+
+struct nuc93x_uartcfg {
+ unsigned char hwport;
+ unsigned char unused;
+ unsigned short flags;
+ unsigned long uart_flags;
+
+ unsigned long ucon;
+ unsigned long ulcon;
+ unsigned long ufcon;
+
+ struct nuc93x_uart_clksrc *clocks;
+ unsigned int clocks_size;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff --git a/arch/arm/mach-nuc93x/include/mach/regs-timer.h b/arch/arm/mach-nuc93x/include/mach/regs-timer.h
new file mode 100644
index 00000000..394be961
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/regs-timer.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+/* Timer Registers */
+
+#define TMR_BA NUC93X_VA_TIMER
+#define REG_TCSR0 (TMR_BA+0x00)
+#define REG_TICR0 (TMR_BA+0x08)
+#define REG_TDR0 (TMR_BA+0x10)
+#define REG_TISR (TMR_BA+0x18)
+#define REG_WTCR (TMR_BA+0x1C)
+
+#endif /* __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/system.h b/arch/arm/mach-nuc93x/include/mach/system.h
new file mode 100644
index 00000000..d26bd9a5
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/system.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/machnuc93x/include/mach/system.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system.h
+ *
+ * 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 <asm/proc-fns.h>
+
+static void arch_idle(void)
+{
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+
diff --git a/arch/arm/mach-nuc93x/include/mach/timex.h b/arch/arm/mach-nuc93x/include/mach/timex.h
new file mode 100644
index 00000000..0c719cc9
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/timex.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/timex.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE Now, I don't use it. */
+
+#define CLOCK_TICK_RATE 27000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/uncompress.h b/arch/arm/mach-nuc93x/include/mach/uncompress.h
new file mode 100644
index 00000000..381cb9ba
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/uncompress.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/uncompress.h
+ *
+ * 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_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+/* Defines for UART registers */
+
+#include <mach/regs-serial.h>
+#include <mach/map.h>
+#include <linux/serial_reg.h>
+
+#define arch_decomp_wdog()
+
+#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
+static u32 * const uart_base = (u32 *)UART0_PA;
+
+static void putc(int ch)
+{
+ /* Check THRE and TEMT bits before we transmit the character.
+ */
+ while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+
+ *uart_base = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#endif/* __ASM_NUC93X_UNCOMPRESS_H */
diff --git a/arch/arm/mach-nuc93x/include/mach/vmalloc.h b/arch/arm/mach-nuc93x/include/mach/vmalloc.h
new file mode 100644
index 00000000..98a21b81
--- /dev/null
+++ b/arch/arm/mach-nuc93x/include/mach/vmalloc.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-nuc93x/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * 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_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xE0000000)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-nuc93x/irq.c b/arch/arm/mach-nuc93x/irq.c
new file mode 100644
index 00000000..aa279f23
--- /dev/null
+++ b/arch/arm/mach-nuc93x/irq.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-nuc93x/irq.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+static void nuc93x_irq_mask(struct irq_data *d)
+{
+ __raw_writel(1 << d->irq, REG_AIC_MDCR);
+}
+
+/*
+ * By the w90p910 spec,any irq,only write 1
+ * to REG_AIC_EOSCR for ACK
+ */
+
+static void nuc93x_irq_ack(struct irq_data *d)
+{
+ __raw_writel(0x01, REG_AIC_EOSCR);
+}
+
+static void nuc93x_irq_unmask(struct irq_data *d)
+{
+ __raw_writel(1 << d->irq, REG_AIC_MECR);
+
+}
+
+static struct irq_chip nuc93x_irq_chip = {
+ .irq_ack = nuc93x_irq_ack,
+ .irq_mask = nuc93x_irq_mask,
+ .irq_unmask = nuc93x_irq_unmask,
+};
+
+void __init nuc93x_init_irq(void)
+{
+ int irqno;
+
+ __raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
+
+ for (irqno = IRQ_WDT; irqno <= NR_IRQS; irqno++) {
+ irq_set_chip_and_handler(irqno, &nuc93x_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-nuc93x/mach-nuc932evb.c b/arch/arm/mach-nuc93x/mach-nuc932evb.c
new file mode 100644
index 00000000..d7025704
--- /dev/null
+++ b/arch/arm/mach-nuc93x/mach-nuc932evb.c
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc932.h"
+
+static void __init nuc932evb_map_io(void)
+{
+ nuc932_map_io();
+ nuc932_init_clocks();
+ nuc932_init_uartclk();
+}
+
+static void __init nuc932evb_init(void)
+{
+ nuc932_board_init();
+}
+
+MACHINE_START(NUC932EVB, "NUC932EVB")
+ /* Maintainer: Wan ZongShun */
+ .boot_params = 0,
+ .map_io = nuc932evb_map_io,
+ .init_irq = nuc93x_init_irq,
+ .init_machine = nuc932evb_init,
+ .timer = &nuc93x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-nuc93x/nuc932.c b/arch/arm/mach-nuc93x/nuc932.c
new file mode 100644
index 00000000..3966ead6
--- /dev/null
+++ b/arch/arm/mach-nuc93x/nuc932.c
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-nuc93x/nuc932.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC932 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc932_dev[] __initdata = {
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc932evb_iodesc[] __initdata = {
+};
+
+/*Init NUC932 evb io*/
+
+void __init nuc932_map_io(void)
+{
+ nuc93x_map_io(nuc932evb_iodesc, ARRAY_SIZE(nuc932evb_iodesc));
+}
+
+/*Init NUC932 clock*/
+
+void __init nuc932_init_clocks(void)
+{
+ nuc93x_init_clocks();
+}
+
+/*enable NUC932 uart clock*/
+
+void __init nuc932_init_uartclk(void)
+{
+ struct clk *ck_uart = clk_get(NULL, "uart");
+ BUG_ON(IS_ERR(ck_uart));
+
+ clk_enable(ck_uart);
+}
+
+/*Init NUC932 board info*/
+
+void __init nuc932_board_init(void)
+{
+ nuc93x_board_init(nuc932_dev, ARRAY_SIZE(nuc932_dev));
+}
diff --git a/arch/arm/mach-nuc93x/nuc932.h b/arch/arm/mach-nuc93x/nuc932.h
new file mode 100644
index 00000000..9a66edd5
--- /dev/null
+++ b/arch/arm/mach-nuc93x/nuc932.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-nuc93x/nuc932.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC93x CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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 map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc93x_init_irq(void);
+extern struct sys_timer nuc93x_timer;
+
+/* extern file from nuc932.c */
+
+extern void nuc932_board_init(void);
+extern void nuc932_init_clocks(void);
+extern void nuc932_map_io(void);
+extern void nuc932_init_uartclk(void);
diff --git a/arch/arm/mach-nuc93x/time.c b/arch/arm/mach-nuc93x/time.c
new file mode 100644
index 00000000..2f90f9dc
--- /dev/null
+++ b/arch/arm/mach-nuc93x/time.c
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/mach-nuc93x/time.c
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <mach/system.h>
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define RESETINT 0x01
+#define PERIOD (0x01 << 27)
+#define ONESHOT (0x00 << 27)
+#define COUNTEN (0x01 << 30)
+#define INTEN (0x01 << 29)
+
+#define TICKS_PER_SEC 100
+#define PRESCALE 0x63 /* Divider = prescale + 1 */
+
+unsigned int timer0_load;
+
+static unsigned long nuc93x_gettimeoffset(void)
+{
+ return 0;
+}
+
+/*IRQ handler for the timer*/
+
+static irqreturn_t nuc93x_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ __raw_writel(0x01, REG_TISR); /* clear TIF0 */
+ return IRQ_HANDLED;
+}
+
+static struct irqaction nuc93x_timer_irq = {
+ .name = "nuc93x Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = nuc93x_timer_interrupt,
+};
+
+/*Set up timer reg.*/
+
+static void nuc93x_timer_setup(void)
+{
+ struct clk *ck_ext = clk_get(NULL, "ext");
+ struct clk *ck_timer = clk_get(NULL, "timer");
+ unsigned int rate, val = 0;
+
+ BUG_ON(IS_ERR(ck_ext) || IS_ERR(ck_timer));
+
+ clk_enable(ck_timer);
+ rate = clk_get_rate(ck_ext);
+ clk_put(ck_ext);
+ rate = rate / (PRESCALE + 0x01);
+
+ /* set a known state */
+ __raw_writel(0x00, REG_TCSR0);
+ __raw_writel(RESETINT, REG_TISR);
+
+ timer0_load = (rate / TICKS_PER_SEC);
+ __raw_writel(timer0_load, REG_TICR0);
+
+ val |= (PERIOD | COUNTEN | INTEN | PRESCALE);;
+ __raw_writel(val, REG_TCSR0);
+
+}
+
+static void __init nuc93x_timer_init(void)
+{
+ nuc93x_timer_setup();
+ setup_irq(IRQ_TIMER0, &nuc93x_timer_irq);
+}
+
+struct sys_timer nuc93x_timer = {
+ .init = nuc93x_timer_init,
+ .offset = nuc93x_gettimeoffset,
+ .resume = nuc93x_timer_setup
+};
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
new file mode 100644
index 00000000..e0a02816
--- /dev/null
+++ b/arch/arm/mach-omap1/Kconfig
@@ -0,0 +1,245 @@
+if ARCH_OMAP1
+
+menu "TI OMAP1 specific features"
+
+comment "OMAP Core Type"
+ depends on ARCH_OMAP1
+
+config ARCH_OMAP730
+ depends on ARCH_OMAP1
+ bool "OMAP730 Based System"
+ select CPU_ARM926T
+ select OMAP_MPU_TIMER
+ select ARCH_OMAP_OTG
+
+config ARCH_OMAP850
+ depends on ARCH_OMAP1
+ bool "OMAP850 Based System"
+ select CPU_ARM926T
+ select ARCH_OMAP_OTG
+
+config ARCH_OMAP15XX
+ depends on ARCH_OMAP1
+ default y
+ bool "OMAP15xx Based System"
+ select CPU_ARM925T
+ select OMAP_MPU_TIMER
+
+config ARCH_OMAP16XX
+ depends on ARCH_OMAP1
+ bool "OMAP16xx Based System"
+ select CPU_ARM926T
+ select ARCH_OMAP_OTG
+
+comment "OMAP Board Type"
+ depends on ARCH_OMAP1
+
+config MACH_OMAP_INNOVATOR
+ bool "TI Innovator"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
+ select OMAP_MCBSP
+ help
+ TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
+ have such a board.
+
+config MACH_OMAP_H2
+ bool "TI H2 Support"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ select OMAP_MCBSP
+ help
+ TI OMAP 1610/1611B H2 board support. Say Y here if you have such
+ a board.
+
+config MACH_OMAP_H3
+ bool "TI H3 Support"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ help
+ TI OMAP 1710 H3 board support. Say Y here if you have such
+ a board.
+
+config MACH_OMAP_HTCWIZARD
+ bool "HTC Wizard"
+ depends on ARCH_OMAP850
+ help
+ HTC Wizard smartphone support (AKA QTEK 9100, ...)
+
+config MACH_HERALD
+ bool "HTC Herald"
+ depends on ARCH_OMAP850
+ help
+ HTC Herald smartphone support (AKA T-Mobile Wing, ...)
+
+config MACH_OMAP_OSK
+ bool "TI OSK Support"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ select OMAP_MCBSP
+ help
+ TI OMAP 5912 OSK (OMAP Starter Kit) board support. Say Y here
+ if you have such a board.
+
+config OMAP_OSK_MISTRAL
+ bool "Mistral QVGA board Support"
+ depends on MACH_OMAP_OSK
+ help
+ The OSK supports an optional add-on board with a Quarter-VGA
+ touchscreen, PDA-ish buttons, a resume button, bicolor LED,
+ and camera connector. Say Y here if you have this board.
+
+config MACH_OMAP_PERSEUS2
+ bool "TI Perseus2"
+ depends on ARCH_OMAP1 && ARCH_OMAP730
+ help
+ Support for TI OMAP 730 Perseus2 board. Say Y here if you have such
+ a board.
+
+config MACH_OMAP_FSAMPLE
+ bool "TI F-Sample"
+ depends on ARCH_OMAP1 && ARCH_OMAP730
+ help
+ Support for TI OMAP 850 F-Sample board. Say Y here if you have such
+ a board.
+
+config MACH_VOICEBLUE
+ bool "Voiceblue"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for Voiceblue GSM/VoIP gateway. Say Y here if you have
+ such a board.
+
+config MACH_OMAP_PALMTE
+ bool "Palm Tungsten E"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Tungsten E PDA. To boot the kernel, you'll
+ need a PalmOS compatible bootloader; check out
+ http://palmtelinux.sourceforge.net/ for more information.
+ Say Y here if you have this PDA model, say N otherwise.
+
+config MACH_OMAP_PALMZ71
+ bool "Palm Zire71"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Zire71 PDA. To boot the kernel,
+ you'll need a PalmOS compatible bootloader; check out
+ http://hackndev.com/palm/z71 for more information.
+ Say Y here if you have such a PDA, say N otherwise.
+
+config MACH_OMAP_PALMTT
+ bool "Palm Tungsten|T"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Palm Tungsten|T PDA. To boot the kernel, you'll
+ need a PalmOS compatible bootloader (Garux); check out
+ http://garux.sourceforge.net/ for more information.
+ Say Y here if you have this PDA model, say N otherwise.
+
+config MACH_SX1
+ bool "Siemens SX1"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Support for the Siemens SX1 phone. To boot the kernel,
+ you'll need a SX1 compatible bootloader; check out
+ http://forum.oslik.ru and
+ http://www.handhelds.org/moin/moin.cgi/SiemensSX1
+ for more information.
+ Say Y here if you have such a phone, say NO otherwise.
+
+config MACH_NOKIA770
+ bool "Nokia 770"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ help
+ Support for the Nokia 770 Internet Tablet. Say Y here if you
+ have such a device.
+
+config MACH_AMS_DELTA
+ bool "Amstrad E3 (Delta)"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ select FIQ
+ help
+ Support for the Amstrad E3 (codename Delta) videophone. Say Y here
+ if you have such a device.
+
+config MACH_OMAP_GENERIC
+ bool "Generic OMAP board"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX)
+ help
+ Support for generic OMAP-1510, 1610 or 1710 board with
+ no FPGA. Can be used as template for porting Linux to
+ custom OMAP boards. Say Y here if you have a custom
+ board.
+
+comment "OMAP CPU Speed"
+ depends on ARCH_OMAP1
+
+config OMAP_CLOCKS_SET_BY_BOOTLOADER
+ bool "OMAP clocks set by bootloader"
+ depends on ARCH_OMAP1
+ help
+ Enable this option to prevent the kernel from overriding the clock
+ frequencies programmed by bootloader for MPU, DSP, MMUs, TC,
+ internal LCD controller and MPU peripherals.
+
+config OMAP_ARM_216MHZ
+ bool "OMAP ARM 216 MHz CPU (1710 only)"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ help
+ Enable 216 MHz clock for OMAP1710 CPU. If unsure, say N.
+
+config OMAP_ARM_195MHZ
+ bool "OMAP ARM 195 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 195MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_192MHZ
+ bool "OMAP ARM 192 MHz CPU"
+ depends on ARCH_OMAP1 && ARCH_OMAP16XX
+ help
+ Enable 192MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_182MHZ
+ bool "OMAP ARM 182 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 182MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_168MHZ
+ bool "OMAP ARM 168 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 168MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_150MHZ
+ bool "OMAP ARM 150 MHz CPU"
+ depends on ARCH_OMAP1 && ARCH_OMAP15XX
+ help
+ Enable 150MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_120MHZ
+ bool "OMAP ARM 120 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 120MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_96MHZ
+ bool "OMAP ARM 96 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 96MHz clock for OMAP CPU. If unsure, say N.
+
+config OMAP_ARM_60MHZ
+ bool "OMAP ARM 60 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ default y
+ help
+ Enable 60MHz clock for OMAP CPU. If unsure, say Y.
+
+config OMAP_ARM_30MHZ
+ bool "OMAP ARM 30 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 30MHz clock for OMAP CPU. If unsure, say N.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
new file mode 100644
index 00000000..5b114d15
--- /dev/null
+++ b/arch/arm/mach-omap1/Makefile
@@ -0,0 +1,67 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
+obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o
+
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+
+obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
+# DSP
+obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
+mailbox_mach-objs := mailbox.o
+
+i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+obj-y += $(i2c-omap-m) $(i2c-omap-y)
+
+led-y := leds.o
+
+usb-fs-$(CONFIG_USB) := usb.o
+obj-y += $(usb-fs-m) $(usb-fs-y)
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o board-h2-mmc.o
+obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
+obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
+obj-$(CONFIG_MACH_OMAP_PERSEUS2) += board-perseus2.o
+obj-$(CONFIG_MACH_OMAP_FSAMPLE) += board-fsample.o
+obj-$(CONFIG_MACH_OMAP_OSK) += board-osk.o
+obj-$(CONFIG_MACH_OMAP_H3) += board-h3.o board-h3-mmc.o
+obj-$(CONFIG_MACH_VOICEBLUE) += board-voiceblue.o
+obj-$(CONFIG_MACH_OMAP_PALMTE) += board-palmte.o
+obj-$(CONFIG_MACH_OMAP_PALMZ71) += board-palmz71.o
+obj-$(CONFIG_MACH_OMAP_PALMTT) += board-palmtt.o
+obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
+obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o ams-delta-fiq.o \
+ ams-delta-fiq-handler.o
+obj-$(CONFIG_MACH_SX1) += board-sx1.o board-sx1-mmc.o
+obj-$(CONFIG_MACH_HERALD) += board-htcherald.o
+
+ifeq ($(CONFIG_ARCH_OMAP15XX),y)
+# Innovator-1510 FPGA
+obj-$(CONFIG_MACH_OMAP_INNOVATOR) += fpga.o
+endif
+
+# GPIO
+obj-$(CONFIG_ARCH_OMAP730) += gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP850) += gpio7xx.o
+obj-$(CONFIG_ARCH_OMAP15XX) += gpio15xx.o
+obj-$(CONFIG_ARCH_OMAP16XX) += gpio16xx.o
+
+# LEDs support
+led-$(CONFIG_MACH_OMAP_H2) += leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_H3) += leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_INNOVATOR) += leds-innovator.o
+led-$(CONFIG_MACH_OMAP_PERSEUS2) += leds-h2p2-debug.o
+led-$(CONFIG_MACH_OMAP_OSK) += leds-osk.o
+obj-$(CONFIG_LEDS) += $(led-y)
+
+ifneq ($(CONFIG_FB_OMAP),)
+obj-y += lcd_dma.o
+endif
diff --git a/arch/arm/mach-omap1/Makefile.boot b/arch/arm/mach-omap1/Makefile.boot
new file mode 100644
index 00000000..292d56c5
--- /dev/null
+++ b/arch/arm/mach-omap1/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x10008000
+params_phys-y := 0x10000100
+initrd_phys-y := 0x10800000
diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S
new file mode 100644
index 00000000..c1c5fb6a
--- /dev/null
+++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S
@@ -0,0 +1,278 @@
+/*
+ * linux/arch/arm/mach-omap1/ams-delta-fiq-handler.S
+ *
+ * Based on linux/arch/arm/lib/floppydma.S
+ * Renamed and modified to work with 2.6 kernel by Matt Callow
+ * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 2004 Pete Trapps
+ * Copyright (C) 2006 Matt Callow
+ * Copyright (C) 2010 Janusz Krzysztofik
+ *
+ * This program is free software; you can 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/linkage.h>
+
+#include <plat/io.h>
+#include <plat/board-ams-delta.h>
+
+#include <mach/ams-delta-fiq.h>
+
+/*
+ * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c.
+ * Unfortunately, those were not placed in a separate header file.
+ */
+#define OMAP1510_GPIO_BASE 0xFFFCE000
+#define OMAP1510_GPIO_DATA_INPUT 0x00
+#define OMAP1510_GPIO_DATA_OUTPUT 0x04
+#define OMAP1510_GPIO_DIR_CONTROL 0x08
+#define OMAP1510_GPIO_INT_CONTROL 0x0c
+#define OMAP1510_GPIO_INT_MASK 0x10
+#define OMAP1510_GPIO_INT_STATUS 0x14
+#define OMAP1510_GPIO_PIN_CONTROL 0x18
+
+/* GPIO register bitmasks */
+#define KEYBRD_DATA_MASK (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_DATA)
+#define KEYBRD_CLK_MASK (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_CLK)
+#define MODEM_IRQ_MASK (0x1 << AMS_DELTA_GPIO_PIN_MODEM_IRQ)
+#define HOOK_SWITCH_MASK (0x1 << AMS_DELTA_GPIO_PIN_HOOK_SWITCH)
+#define OTHERS_MASK (MODEM_IRQ_MASK | HOOK_SWITCH_MASK)
+
+/* IRQ handler register bitmasks */
+#define DEFERRED_FIQ_MASK (0x1 << (INT_DEFERRED_FIQ % IH2_BASE))
+#define GPIO_BANK1_MASK (0x1 << INT_GPIO_BANK1)
+
+/* Driver buffer byte offsets */
+#define BUF_MASK (FIQ_MASK * 4)
+#define BUF_STATE (FIQ_STATE * 4)
+#define BUF_KEYS_CNT (FIQ_KEYS_CNT * 4)
+#define BUF_TAIL_OFFSET (FIQ_TAIL_OFFSET * 4)
+#define BUF_HEAD_OFFSET (FIQ_HEAD_OFFSET * 4)
+#define BUF_BUF_LEN (FIQ_BUF_LEN * 4)
+#define BUF_KEY (FIQ_KEY * 4)
+#define BUF_MISSED_KEYS (FIQ_MISSED_KEYS * 4)
+#define BUF_BUFFER_START (FIQ_BUFFER_START * 4)
+#define BUF_GPIO_INT_MASK (FIQ_GPIO_INT_MASK * 4)
+#define BUF_KEYS_HICNT (FIQ_KEYS_HICNT * 4)
+#define BUF_IRQ_PEND (FIQ_IRQ_PEND * 4)
+#define BUF_SIR_CODE_L1 (FIQ_SIR_CODE_L1 * 4)
+#define BUF_SIR_CODE_L2 (IRQ_SIR_CODE_L2 * 4)
+#define BUF_CNT_INT_00 (FIQ_CNT_INT_00 * 4)
+#define BUF_CNT_INT_KEY (FIQ_CNT_INT_KEY * 4)
+#define BUF_CNT_INT_MDM (FIQ_CNT_INT_MDM * 4)
+#define BUF_CNT_INT_03 (FIQ_CNT_INT_03 * 4)
+#define BUF_CNT_INT_HSW (FIQ_CNT_INT_HSW * 4)
+#define BUF_CNT_INT_05 (FIQ_CNT_INT_05 * 4)
+#define BUF_CNT_INT_06 (FIQ_CNT_INT_06 * 4)
+#define BUF_CNT_INT_07 (FIQ_CNT_INT_07 * 4)
+#define BUF_CNT_INT_08 (FIQ_CNT_INT_08 * 4)
+#define BUF_CNT_INT_09 (FIQ_CNT_INT_09 * 4)
+#define BUF_CNT_INT_10 (FIQ_CNT_INT_10 * 4)
+#define BUF_CNT_INT_11 (FIQ_CNT_INT_11 * 4)
+#define BUF_CNT_INT_12 (FIQ_CNT_INT_12 * 4)
+#define BUF_CNT_INT_13 (FIQ_CNT_INT_13 * 4)
+#define BUF_CNT_INT_14 (FIQ_CNT_INT_14 * 4)
+#define BUF_CNT_INT_15 (FIQ_CNT_INT_15 * 4)
+#define BUF_CIRC_BUFF (FIQ_CIRC_BUFF * 4)
+
+
+/*
+ * Register usage
+ * r8 - temporary
+ * r9 - the driver buffer
+ * r10 - temporary
+ * r11 - interrupts mask
+ * r12 - base pointers
+ * r13 - interrupts status
+ */
+
+ .text
+
+ .global qwerty_fiqin_end
+
+ENTRY(qwerty_fiqin_start)
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+ @ FIQ intrrupt handler
+ ldr r12, omap_ih1_base @ set pointer to level1 handler
+
+ ldr r11, [r12, #IRQ_MIR_REG_OFFSET] @ fetch interrupts mask
+
+ ldr r13, [r12, #IRQ_ITR_REG_OFFSET] @ fetch interrupts status
+ bics r13, r13, r11 @ clear masked - any left?
+ beq exit @ none - spurious FIQ? exit
+
+ ldr r10, [r12, #IRQ_SIR_FIQ_REG_OFFSET] @ get requested interrupt number
+
+ mov r8, #2 @ reset FIQ agreement
+ str r8, [r12, #IRQ_CONTROL_REG_OFFSET]
+
+ cmp r10, #INT_GPIO_BANK1 @ is it GPIO bank interrupt?
+ beq gpio @ yes - process it
+
+ mov r8, #1
+ orr r8, r11, r8, lsl r10 @ mask spurious interrupt
+ str r8, [r12, #IRQ_MIR_REG_OFFSET]
+exit:
+ subs pc, lr, #4 @ return from FIQ
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@
+gpio: @ GPIO bank interrupt handler
+ ldr r12, omap1510_gpio_base @ set base pointer to GPIO bank
+
+ ldr r11, [r12, #OMAP1510_GPIO_INT_MASK] @ fetch GPIO interrupts mask
+restart:
+ ldr r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ fetch status bits
+ bics r13, r13, r11 @ clear masked - any left?
+ beq exit @ no - spurious interrupt? exit
+
+ orr r11, r11, r13 @ mask all requested interrupts
+ str r11, [r12, #OMAP1510_GPIO_INT_MASK]
+
+ ands r10, r13, #KEYBRD_CLK_MASK @ extract keyboard status - set?
+ beq hksw @ no - try next source
+
+
+ @@@@@@@@@@@@@@@@@@@@@@
+ @ Keyboard clock FIQ mode interrupt handler
+ @ r10 now contains KEYBRD_CLK_MASK, use it
+ str r10, [r12, #OMAP1510_GPIO_INT_STATUS] @ ack the interrupt
+ bic r11, r11, r10 @ unmask it
+ str r11, [r12, #OMAP1510_GPIO_INT_MASK]
+
+ @ Process keyboard data
+ ldr r8, [r12, #OMAP1510_GPIO_DATA_INPUT] @ fetch GPIO input
+
+ ldr r10, [r9, #BUF_STATE] @ fetch kbd interface state
+ cmp r10, #0 @ are we expecting start bit?
+ bne data @ no - go to data processing
+
+ ands r8, r8, #KEYBRD_DATA_MASK @ check start bit - detected?
+ beq hksw @ no - try next source
+
+ @ r8 contains KEYBRD_DATA_MASK, use it
+ str r8, [r9, #BUF_STATE] @ enter data processing state
+ @ r10 already contains 0, reuse it
+ str r10, [r9, #BUF_KEY] @ clear keycode
+ mov r10, #2 @ reset input bit mask
+ str r10, [r9, #BUF_MASK]
+
+ @ Mask other GPIO line interrupts till key done
+ str r11, [r9, #BUF_GPIO_INT_MASK] @ save mask for later restore
+ mvn r11, #KEYBRD_CLK_MASK @ prepare all except kbd mask
+ str r11, [r12, #OMAP1510_GPIO_INT_MASK] @ store into the mask register
+
+ b restart @ restart
+
+data: ldr r10, [r9, #BUF_MASK] @ fetch current input bit mask
+
+ @ r8 still contains GPIO input bits
+ ands r8, r8, #KEYBRD_DATA_MASK @ is keyboard data line low?
+ ldreq r8, [r9, #BUF_KEY] @ yes - fetch collected so far,
+ orreq r8, r8, r10 @ set 1 at current mask position
+ streq r8, [r9, #BUF_KEY] @ and save back
+
+ mov r10, r10, lsl #1 @ shift mask left
+ bics r10, r10, #0x800 @ have we got all the bits?
+ strne r10, [r9, #BUF_MASK] @ not yet - store the mask
+ bne restart @ and restart
+
+ @ r10 already contains 0, reuse it
+ str r10, [r9, #BUF_STATE] @ reset state to start
+
+ @ Key done - restore interrupt mask
+ ldr r10, [r9, #BUF_GPIO_INT_MASK] @ fetch saved mask
+ and r11, r11, r10 @ unmask all saved as unmasked
+ str r11, [r12, #OMAP1510_GPIO_INT_MASK] @ restore into the mask register
+
+ @ Try appending the keycode to the circular buffer
+ ldr r10, [r9, #BUF_KEYS_CNT] @ get saved keystrokes count
+ ldr r8, [r9, #BUF_BUF_LEN] @ get buffer size
+ cmp r10, r8 @ is buffer full?
+ beq hksw @ yes - key lost, next source
+
+ add r10, r10, #1 @ incremet keystrokes counter
+ str r10, [r9, #BUF_KEYS_CNT]
+
+ ldr r10, [r9, #BUF_TAIL_OFFSET] @ get buffer tail offset
+ @ r8 already contains buffer size
+ cmp r10, r8 @ end of buffer?
+ moveq r10, #0 @ yes - rewind to buffer start
+
+ ldr r12, [r9, #BUF_BUFFER_START] @ get buffer start address
+ add r12, r12, r10, LSL #2 @ calculate buffer tail address
+ ldr r8, [r9, #BUF_KEY] @ get last keycode
+ str r8, [r12] @ append it to the buffer tail
+
+ add r10, r10, #1 @ increment buffer tail offset
+ str r10, [r9, #BUF_TAIL_OFFSET]
+
+ ldr r10, [r9, #BUF_CNT_INT_KEY] @ increment interrupts counter
+ add r10, r10, #1
+ str r10, [r9, #BUF_CNT_INT_KEY]
+ @@@@@@@@@@@@@@@@@@@@@@@@
+
+
+hksw: @Is hook switch interrupt requested?
+ tst r13, #HOOK_SWITCH_MASK @ is hook switch status bit set?
+ beq mdm @ no - try next source
+
+
+ @@@@@@@@@@@@@@@@@@@@@@@@
+ @ Hook switch interrupt FIQ mode simple handler
+
+ @ Don't toggle active edge, the switch always bounces
+
+ @ Increment hook switch interrupt counter
+ ldr r10, [r9, #BUF_CNT_INT_HSW]
+ add r10, r10, #1
+ str r10, [r9, #BUF_CNT_INT_HSW]
+ @@@@@@@@@@@@@@@@@@@@@@@@
+
+
+mdm: @Is it a modem interrupt?
+ tst r13, #MODEM_IRQ_MASK @ is modem status bit set?
+ beq irq @ no - check for next interrupt
+
+
+ @@@@@@@@@@@@@@@@@@@@@@@@
+ @ Modem FIQ mode interrupt handler stub
+
+ @ Increment modem interrupt counter
+ ldr r10, [r9, #BUF_CNT_INT_MDM]
+ add r10, r10, #1
+ str r10, [r9, #BUF_CNT_INT_MDM]
+ @@@@@@@@@@@@@@@@@@@@@@@@
+
+
+irq: @ Place deferred_fiq interrupt request
+ ldr r12, deferred_fiq_ih_base @ set pointer to IRQ handler
+ mov r10, #DEFERRED_FIQ_MASK @ set deferred_fiq bit
+ str r10, [r12, #IRQ_ISR_REG_OFFSET] @ place it in the ISR register
+
+ ldr r12, omap1510_gpio_base @ set pointer back to GPIO bank
+ b restart @ check for next GPIO interrupt
+ @@@@@@@@@@@@@@@@@@@@@@@@@@@
+
+
+/*
+ * Virtual addresses for IO
+ */
+omap_ih1_base:
+ .word OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
+deferred_fiq_ih_base:
+ .word OMAP1_IO_ADDRESS(DEFERRED_FIQ_IH_BASE)
+omap1510_gpio_base:
+ .word OMAP1_IO_ADDRESS(OMAP1510_GPIO_BASE)
+qwerty_fiqin_end:
+
+/*
+ * Check the size of the FIQ,
+ * it cannot go beyond 0xffff0200, and is copied to 0xffff001c
+ */
+.if (qwerty_fiqin_end - qwerty_fiqin_start) > (0x200 - 0x1c)
+ .err
+.endif
diff --git a/arch/arm/mach-omap1/ams-delta-fiq.c b/arch/arm/mach-omap1/ams-delta-fiq.c
new file mode 100644
index 00000000..152b32c1
--- /dev/null
+++ b/arch/arm/mach-omap1/ams-delta-fiq.c
@@ -0,0 +1,157 @@
+/*
+ * Amstrad E3 FIQ handling
+ *
+ * Copyright (C) 2009 Janusz Krzysztofik
+ * Copyright (c) 2006 Matt Callow
+ * Copyright (c) 2004 Amstrad Plc
+ * Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Parts of this code are taken from linux/arch/arm/mach-omap/irq.c
+ * in the MontaVista 2.4 kernel (and the Amstrad changes therein)
+ *
+ * This program is free software; you can 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <plat/board-ams-delta.h>
+
+#include <asm/fiq.h>
+#include <mach/ams-delta-fiq.h>
+
+static struct fiq_handler fh = {
+ .name = "ams-delta-fiq"
+};
+
+/*
+ * This buffer is shared between FIQ and IRQ contexts.
+ * The FIQ and IRQ isrs can both read and write it.
+ * It is structured as a header section several 32bit slots,
+ * followed by the circular buffer where the FIQ isr stores
+ * keystrokes received from the qwerty keyboard.
+ * See ams-delta-fiq.h for details of offsets.
+ */
+unsigned int fiq_buffer[1024];
+EXPORT_SYMBOL(fiq_buffer);
+
+static unsigned int irq_counter[16];
+
+static irqreturn_t deferred_fiq(int irq, void *dev_id)
+{
+ struct irq_desc *irq_desc;
+ struct irq_chip *irq_chip = NULL;
+ int gpio, irq_num, fiq_count;
+
+ irq_desc = irq_to_desc(IH_GPIO_BASE);
+ if (irq_desc)
+ irq_chip = irq_desc->irq_data.chip;
+
+ /*
+ * For each handled GPIO interrupt, keep calling its interrupt handler
+ * until the IRQ counter catches the FIQ incremented interrupt counter.
+ */
+ for (gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK;
+ gpio <= AMS_DELTA_GPIO_PIN_HOOK_SWITCH; gpio++) {
+ irq_num = gpio_to_irq(gpio);
+ fiq_count = fiq_buffer[FIQ_CNT_INT_00 + gpio];
+
+ while (irq_counter[gpio] < fiq_count) {
+ if (gpio != AMS_DELTA_GPIO_PIN_KEYBRD_CLK) {
+ struct irq_data *d = irq_get_irq_data(irq_num);
+
+ /*
+ * It looks like handle_edge_irq() that
+ * OMAP GPIO edge interrupts default to,
+ * expects interrupt already unmasked.
+ */
+ if (irq_chip && irq_chip->irq_unmask)
+ irq_chip->irq_unmask(d);
+ }
+ generic_handle_irq(irq_num);
+
+ irq_counter[gpio]++;
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+void __init ams_delta_init_fiq(void)
+{
+ void *fiqhandler_start;
+ unsigned int fiqhandler_length;
+ struct pt_regs FIQ_regs;
+ unsigned long val, offset;
+ int i, retval;
+
+ fiqhandler_start = &qwerty_fiqin_start;
+ fiqhandler_length = &qwerty_fiqin_end - &qwerty_fiqin_start;
+ pr_info("Installing fiq handler from %p, length 0x%x\n",
+ fiqhandler_start, fiqhandler_length);
+
+ retval = claim_fiq(&fh);
+ if (retval) {
+ pr_err("ams_delta_init_fiq(): couldn't claim FIQ, ret=%d\n",
+ retval);
+ return;
+ }
+
+ retval = request_irq(INT_DEFERRED_FIQ, deferred_fiq,
+ IRQ_TYPE_EDGE_RISING, "deferred_fiq", 0);
+ if (retval < 0) {
+ pr_err("Failed to get deferred_fiq IRQ, ret=%d\n", retval);
+ release_fiq(&fh);
+ return;
+ }
+ /*
+ * Since no set_type() method is provided by OMAP irq chip,
+ * switch to edge triggered interrupt type manually.
+ */
+ offset = IRQ_ILR0_REG_OFFSET + INT_DEFERRED_FIQ * 0x4;
+ val = omap_readl(DEFERRED_FIQ_IH_BASE + offset) & ~(1 << 1);
+ omap_writel(val, DEFERRED_FIQ_IH_BASE + offset);
+
+ set_fiq_handler(fiqhandler_start, fiqhandler_length);
+
+ /*
+ * Initialise the buffer which is shared
+ * between FIQ mode and IRQ mode
+ */
+ fiq_buffer[FIQ_GPIO_INT_MASK] = 0;
+ fiq_buffer[FIQ_MASK] = 0;
+ fiq_buffer[FIQ_STATE] = 0;
+ fiq_buffer[FIQ_KEY] = 0;
+ fiq_buffer[FIQ_KEYS_CNT] = 0;
+ fiq_buffer[FIQ_KEYS_HICNT] = 0;
+ fiq_buffer[FIQ_TAIL_OFFSET] = 0;
+ fiq_buffer[FIQ_HEAD_OFFSET] = 0;
+ fiq_buffer[FIQ_BUF_LEN] = 256;
+ fiq_buffer[FIQ_MISSED_KEYS] = 0;
+ fiq_buffer[FIQ_BUFFER_START] =
+ (unsigned int) &fiq_buffer[FIQ_CIRC_BUFF];
+
+ for (i = FIQ_CNT_INT_00; i <= FIQ_CNT_INT_15; i++)
+ fiq_buffer[i] = 0;
+
+ /*
+ * FIQ mode r9 always points to the fiq_buffer, becauses the FIQ isr
+ * will run in an unpredictable context. The fiq_buffer is the FIQ isr's
+ * only means of communication with the IRQ level and other kernel
+ * context code.
+ */
+ FIQ_regs.ARM_r9 = (unsigned int)fiq_buffer;
+ set_fiq_regs(&FIQ_regs);
+
+ pr_info("request_fiq(): fiq_buffer = %p\n", fiq_buffer);
+
+ /*
+ * Redirect GPIO interrupts to FIQ
+ */
+ offset = IRQ_ILR0_REG_OFFSET + INT_GPIO_BANK1 * 0x4;
+ val = omap_readl(OMAP_IH1_BASE + offset) | 1;
+ omap_writel(val, OMAP_IH1_BASE + offset);
+}
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
new file mode 100644
index 00000000..f49ce85d
--- /dev/null
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -0,0 +1,398 @@
+/*
+ * linux/arch/arm/mach-omap1/board-ams-delta.c
+ *
+ * Modified from board-generic.c
+ *
+ * Board specific inits for the Amstrad E3 (codename Delta) videophone
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * This program is free software; you can 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/input.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/serial.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/io.h>
+#include <plat/board-ams-delta.h>
+#include <mach/gpio.h>
+#include <plat/keypad.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <mach/camera.h>
+
+#include <mach/ams-delta-fiq.h>
+
+static u8 ams_delta_latch1_reg;
+static u16 ams_delta_latch2_reg;
+
+static const unsigned int ams_delta_keymap[] = {
+ KEY(0, 0, KEY_F1), /* Advert */
+
+ KEY(0, 3, KEY_COFFEE), /* Games */
+ KEY(0, 2, KEY_QUESTION), /* Directory */
+ KEY(2, 3, KEY_CONNECT), /* Internet */
+ KEY(1, 2, KEY_SHOP), /* Services */
+ KEY(1, 1, KEY_PHONE), /* VoiceMail */
+
+ KEY(0, 1, KEY_DELETE), /* Delete */
+ KEY(2, 2, KEY_PLAY), /* Play */
+ KEY(1, 0, KEY_PAGEUP), /* Up */
+ KEY(1, 3, KEY_PAGEDOWN), /* Down */
+ KEY(2, 0, KEY_EMAIL), /* ReadEmail */
+ KEY(2, 1, KEY_STOP), /* Stop */
+
+ /* Numeric keypad portion */
+ KEY(0, 7, KEY_KP1),
+ KEY(0, 6, KEY_KP2),
+ KEY(0, 5, KEY_KP3),
+ KEY(1, 7, KEY_KP4),
+ KEY(1, 6, KEY_KP5),
+ KEY(1, 5, KEY_KP6),
+ KEY(2, 7, KEY_KP7),
+ KEY(2, 6, KEY_KP8),
+ KEY(2, 5, KEY_KP9),
+ KEY(3, 6, KEY_KP0),
+ KEY(3, 7, KEY_KPASTERISK),
+ KEY(3, 5, KEY_KPDOT), /* # key */
+ KEY(7, 2, KEY_NUMLOCK), /* Mute */
+ KEY(7, 1, KEY_KPMINUS), /* Recall */
+ KEY(6, 1, KEY_KPPLUS), /* Redial */
+ KEY(7, 6, KEY_KPSLASH), /* Handsfree */
+ KEY(6, 0, KEY_ENTER), /* Video */
+
+ KEY(7, 4, KEY_CAMERA), /* Photo */
+
+ KEY(0, 4, KEY_F2), /* Home */
+ KEY(1, 4, KEY_F3), /* Office */
+ KEY(2, 4, KEY_F4), /* Mobile */
+ KEY(7, 7, KEY_F5), /* SMS */
+ KEY(7, 5, KEY_F6), /* Email */
+
+ /* QWERTY portion of keypad */
+ KEY(3, 4, KEY_Q),
+ KEY(3, 3, KEY_W),
+ KEY(3, 2, KEY_E),
+ KEY(3, 1, KEY_R),
+ KEY(3, 0, KEY_T),
+ KEY(4, 7, KEY_Y),
+ KEY(4, 6, KEY_U),
+ KEY(4, 5, KEY_I),
+ KEY(4, 4, KEY_O),
+ KEY(4, 3, KEY_P),
+
+ KEY(4, 2, KEY_A),
+ KEY(4, 1, KEY_S),
+ KEY(4, 0, KEY_D),
+ KEY(5, 7, KEY_F),
+ KEY(5, 6, KEY_G),
+ KEY(5, 5, KEY_H),
+ KEY(5, 4, KEY_J),
+ KEY(5, 3, KEY_K),
+ KEY(5, 2, KEY_L),
+
+ KEY(5, 1, KEY_Z),
+ KEY(5, 0, KEY_X),
+ KEY(6, 7, KEY_C),
+ KEY(6, 6, KEY_V),
+ KEY(6, 5, KEY_B),
+ KEY(6, 4, KEY_N),
+ KEY(6, 3, KEY_M),
+ KEY(6, 2, KEY_SPACE),
+
+ KEY(7, 0, KEY_LEFTSHIFT), /* Vol up */
+ KEY(7, 3, KEY_LEFTCTRL), /* Vol down */
+};
+
+void ams_delta_latch1_write(u8 mask, u8 value)
+{
+ ams_delta_latch1_reg &= ~mask;
+ ams_delta_latch1_reg |= value;
+ *(volatile __u8 *) AMS_DELTA_LATCH1_VIRT = ams_delta_latch1_reg;
+}
+
+void ams_delta_latch2_write(u16 mask, u16 value)
+{
+ ams_delta_latch2_reg &= ~mask;
+ ams_delta_latch2_reg |= value;
+ *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg;
+}
+
+static void __init ams_delta_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static struct map_desc ams_delta_io_desc[] __initdata = {
+ /* AMS_DELTA_LATCH1 */
+ {
+ .virtual = AMS_DELTA_LATCH1_VIRT,
+ .pfn = __phys_to_pfn(AMS_DELTA_LATCH1_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
+ /* AMS_DELTA_LATCH2 */
+ {
+ .virtual = AMS_DELTA_LATCH2_VIRT,
+ .pfn = __phys_to_pfn(AMS_DELTA_LATCH2_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
+ /* AMS_DELTA_MODEM */
+ {
+ .virtual = AMS_DELTA_MODEM_VIRT,
+ .pfn = __phys_to_pfn(AMS_DELTA_MODEM_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
+};
+
+static struct omap_lcd_config ams_delta_lcd_config = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_usb_config ams_delta_usb_config __initdata = {
+ .register_host = 1,
+ .hmc_mode = 16,
+ .pins[0] = 2,
+};
+
+static struct omap_board_config_kernel ams_delta_config[] __initdata = {
+ { OMAP_TAG_LCD, &ams_delta_lcd_config },
+};
+
+static struct resource ams_delta_nand_resources[] = {
+ [0] = {
+ .start = OMAP1_MPUIO_BASE,
+ .end = OMAP1_MPUIO_BASE +
+ OMAP_MPUIO_IO_CNTL + sizeof(u32) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ams_delta_nand_device = {
+ .name = "ams-delta-nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ams_delta_nand_resources),
+ .resource = ams_delta_nand_resources,
+};
+
+static struct resource ams_delta_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data ams_delta_keymap_data = {
+ .keymap = ams_delta_keymap,
+ .keymap_size = ARRAY_SIZE(ams_delta_keymap),
+};
+
+static struct omap_kp_platform_data ams_delta_kp_data __initdata = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &ams_delta_keymap_data,
+ .delay = 9,
+};
+
+static struct platform_device ams_delta_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &ams_delta_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(ams_delta_kp_resources),
+ .resource = ams_delta_kp_resources,
+};
+
+static struct platform_device ams_delta_lcd_device = {
+ .name = "lcd_ams_delta",
+ .id = -1,
+};
+
+static struct platform_device ams_delta_led_device = {
+ .name = "ams-delta-led",
+ .id = -1
+};
+
+static struct i2c_board_info ams_delta_camera_board_info[] = {
+ {
+ I2C_BOARD_INFO("ov6650", 0x60),
+ },
+};
+
+#ifdef CONFIG_LEDS_TRIGGERS
+DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger);
+
+static int ams_delta_camera_power(struct device *dev, int power)
+{
+ /*
+ * turn on camera LED
+ */
+ if (power)
+ led_trigger_event(ams_delta_camera_led_trigger, LED_FULL);
+ else
+ led_trigger_event(ams_delta_camera_led_trigger, LED_OFF);
+ return 0;
+}
+#else
+#define ams_delta_camera_power NULL
+#endif
+
+static struct soc_camera_link ams_delta_iclink = {
+ .bus_id = 0, /* OMAP1 SoC camera bus */
+ .i2c_adapter_id = 1,
+ .board_info = &ams_delta_camera_board_info[0],
+ .module_name = "ov6650",
+ .power = ams_delta_camera_power,
+};
+
+static struct platform_device ams_delta_camera_device = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &ams_delta_iclink,
+ },
+};
+
+static struct omap1_cam_platform_data ams_delta_camera_platform_data = {
+ .camexclk_khz = 12000, /* default 12MHz clock, no extra DPLL */
+ .lclk_khz_max = 1334, /* results in 5fps CIF, 10fps QCIF */
+};
+
+static struct platform_device *ams_delta_devices[] __initdata = {
+ &ams_delta_nand_device,
+ &ams_delta_kp_device,
+ &ams_delta_lcd_device,
+ &ams_delta_led_device,
+ &ams_delta_camera_device,
+};
+
+static void __init ams_delta_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+
+ /* parallel camera interface */
+ omap_cfg_reg(H19_1610_CAM_EXCLK);
+ omap_cfg_reg(J15_1610_CAM_LCLK);
+ omap_cfg_reg(L18_1610_CAM_VS);
+ omap_cfg_reg(L15_1610_CAM_HS);
+ omap_cfg_reg(L19_1610_CAM_D0);
+ omap_cfg_reg(K14_1610_CAM_D1);
+ omap_cfg_reg(K15_1610_CAM_D2);
+ omap_cfg_reg(K19_1610_CAM_D3);
+ omap_cfg_reg(K18_1610_CAM_D4);
+ omap_cfg_reg(J14_1610_CAM_D5);
+ omap_cfg_reg(J19_1610_CAM_D6);
+ omap_cfg_reg(J18_1610_CAM_D7);
+
+ iotable_init(ams_delta_io_desc, ARRAY_SIZE(ams_delta_io_desc));
+
+ omap_board_config = ams_delta_config;
+ omap_board_config_size = ARRAY_SIZE(ams_delta_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+ /* Clear latch2 (NAND, LCD, modem enable) */
+ ams_delta_latch2_write(~0, 0);
+
+ omap1_usb_init(&ams_delta_usb_config);
+ omap1_set_camera_info(&ams_delta_camera_platform_data);
+#ifdef CONFIG_LEDS_TRIGGERS
+ led_trigger_register_simple("ams_delta_camera",
+ &ams_delta_camera_led_trigger);
+#endif
+ platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
+
+ ams_delta_init_fiq();
+
+ omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
+}
+
+static struct plat_serial8250_port ams_delta_modem_ports[] = {
+ {
+ .membase = IOMEM(AMS_DELTA_MODEM_VIRT),
+ .mapbase = AMS_DELTA_MODEM_PHYS,
+ .irq = -EINVAL, /* changed later */
+ .flags = UPF_BOOT_AUTOCONF,
+ .irqflags = IRQF_TRIGGER_RISING,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = BASE_BAUD * 16,
+ },
+ { },
+};
+
+static struct platform_device ams_delta_modem_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = ams_delta_modem_ports,
+ },
+};
+
+static int __init ams_delta_modem_init(void)
+{
+ int err;
+
+ if (!machine_is_ams_delta())
+ return -ENODEV;
+
+ omap_cfg_reg(M14_1510_GPIO2);
+ ams_delta_modem_ports[0].irq =
+ gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+
+ err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem");
+ if (err) {
+ pr_err("Couldn't request gpio pin for modem\n");
+ return err;
+ }
+ gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ);
+
+ ams_delta_latch2_write(
+ AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC,
+ AMS_DELTA_LATCH2_MODEM_NRESET | AMS_DELTA_LATCH2_MODEM_CODEC);
+
+ return platform_device_register(&ams_delta_modem_device);
+}
+arch_initcall(ams_delta_modem_init);
+
+static void __init ams_delta_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
+ /* Maintainer: Jonathan McDowell <noodles@earth.li> */
+ .boot_params = 0x10000100,
+ .map_io = ams_delta_map_io,
+ .reserve = omap_reserve,
+ .init_irq = ams_delta_init_irq,
+ .init_machine = ams_delta_init,
+ .timer = &omap_timer,
+MACHINE_END
+
+EXPORT_SYMBOL(ams_delta_latch1_write);
+EXPORT_SYMBOL(ams_delta_latch2_write);
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
new file mode 100644
index 00000000..87f173d9
--- /dev/null
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -0,0 +1,398 @@
+/*
+ * linux/arch/arm/mach-omap1/board-fsample.c
+ *
+ * Modified from board-perseus2.c
+ *
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/tc.h>
+#include <mach/gpio.h>
+#include <plat/mux.h>
+#include <plat/flash.h>
+#include <plat/fpga.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/board.h>
+
+/* fsample is pretty close to p2-sample */
+
+#define fsample_cpld_read(reg) __raw_readb(reg)
+#define fsample_cpld_write(val, reg) __raw_writeb(val, reg)
+
+#define FSAMPLE_CPLD_BASE 0xE8100000
+#define FSAMPLE_CPLD_SIZE SZ_4K
+#define FSAMPLE_CPLD_START 0x05080000
+
+#define FSAMPLE_CPLD_REG_A (FSAMPLE_CPLD_BASE + 0x00)
+#define FSAMPLE_CPLD_SWITCH (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_UART (FSAMPLE_CPLD_BASE + 0x02)
+#define FSAMPLE_CPLD_REG_B (FSAMPLE_CPLD_BASE + 0x04)
+#define FSAMPLE_CPLD_VERSION (FSAMPLE_CPLD_BASE + 0x06)
+#define FSAMPLE_CPLD_SET_CLR (FSAMPLE_CPLD_BASE + 0x06)
+
+#define FSAMPLE_CPLD_BIT_BT_RESET 0
+#define FSAMPLE_CPLD_BIT_LCD_RESET 1
+#define FSAMPLE_CPLD_BIT_CAM_PWDN 2
+#define FSAMPLE_CPLD_BIT_CHARGER_ENABLE 3
+#define FSAMPLE_CPLD_BIT_SD_MMC_EN 4
+#define FSAMPLE_CPLD_BIT_aGPS_PWREN 5
+#define FSAMPLE_CPLD_BIT_BACKLIGHT 6
+#define FSAMPLE_CPLD_BIT_aGPS_EN_RESET 7
+#define FSAMPLE_CPLD_BIT_aGPS_SLEEPx_N 8
+#define FSAMPLE_CPLD_BIT_OTG_RESET 9
+
+#define fsample_cpld_set(bit) \
+ fsample_cpld_write((((bit) & 15) << 4) | 0x0f, FSAMPLE_CPLD_SET_CLR)
+
+#define fsample_cpld_clear(bit) \
+ fsample_cpld_write(0xf0 | ((bit) & 15), FSAMPLE_CPLD_SET_CLR)
+
+static const unsigned int fsample_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_LEFT),
+ KEY(3, 0, KEY_DOWN),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_F10),
+ KEY(1, 1, KEY_SEND),
+ KEY(2, 1, KEY_END),
+ KEY(3, 1, KEY_VOLUMEDOWN),
+ KEY(4, 1, KEY_VOLUMEUP),
+ KEY(5, 1, KEY_RECORD),
+ KEY(0, 2, KEY_F9),
+ KEY(1, 2, KEY_3),
+ KEY(2, 2, KEY_6),
+ KEY(3, 2, KEY_9),
+ KEY(4, 2, KEY_KPDOT),
+ KEY(0, 3, KEY_BACK),
+ KEY(1, 3, KEY_2),
+ KEY(2, 3, KEY_5),
+ KEY(3, 3, KEY_8),
+ KEY(4, 3, KEY_0),
+ KEY(5, 3, KEY_KPSLASH),
+ KEY(0, 4, KEY_HOME),
+ KEY(1, 4, KEY_1),
+ KEY(2, 4, KEY_4),
+ KEY(3, 4, KEY_7),
+ KEY(4, 4, KEY_KPASTERISK),
+ KEY(5, 4, KEY_POWER),
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
+ .end = H2P2_DBG_FPGA_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_7XX_MPU_EXT_NIRQ,
+ .end = 0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static void __init fsample_init_smc91x(void)
+{
+ fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+ H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+}
+
+static struct mtd_partition nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* rest of flash is a file system */
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ },
+};
+
+static struct physmap_flash_data nor_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = nor_partitions,
+ .nr_parts = ARRAY_SIZE(nor_partitions),
+};
+
+static struct resource nor_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_data,
+ },
+ .num_resources = 1,
+ .resource = &nor_resource,
+};
+
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long mask;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+ if (ctrl & NAND_ALE)
+ mask |= 0x04;
+ writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define FSAMPLE_NAND_RB_GPIO_PIN 62
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = nand_cmd_ctl,
+ .dev_ready = nand_dev_ready,
+ },
+};
+
+static struct resource nand_resource = {
+ .start = OMAP_CS3_PHYS,
+ .end = OMAP_CS3_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+ .name = "gen_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .num_resources = 1,
+ .resource = &nand_resource,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource kp_resources[] = {
+ [0] = {
+ .start = INT_7XX_MPUIO_KEYPAD,
+ .end = INT_7XX_MPUIO_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data fsample_keymap_data = {
+ .keymap = fsample_keymap,
+ .keymap_size = ARRAY_SIZE(fsample_keymap),
+};
+
+static struct omap_kp_platform_data kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &fsample_keymap_data,
+ .delay = 4,
+};
+
+static struct platform_device kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_data,
+ },
+ .num_resources = ARRAY_SIZE(kp_resources),
+ .resource = kp_resources,
+};
+
+static struct platform_device lcd_device = {
+ .name = "lcd_p2",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &kp_device,
+ &lcd_device,
+};
+
+static struct omap_lcd_config fsample_lcd_config = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel fsample_config[] __initdata = {
+ { OMAP_TAG_LCD, &fsample_lcd_config },
+};
+
+static void __init omap_fsample_init(void)
+{
+ fsample_init_smc91x();
+
+ if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0)
+ BUG();
+ gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN);
+
+ omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+ omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+
+ /* Mux pins for keypad */
+ omap_cfg_reg(E2_7XX_KBR0);
+ omap_cfg_reg(J7_7XX_KBR1);
+ omap_cfg_reg(E1_7XX_KBR2);
+ omap_cfg_reg(F3_7XX_KBR3);
+ omap_cfg_reg(D2_7XX_KBR4);
+ omap_cfg_reg(C2_7XX_KBC0);
+ omap_cfg_reg(D3_7XX_KBC1);
+ omap_cfg_reg(E4_7XX_KBC2);
+ omap_cfg_reg(F4_7XX_KBC3);
+ omap_cfg_reg(E3_7XX_KBC4);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ omap_board_config = fsample_config;
+ omap_board_config_size = ARRAY_SIZE(fsample_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+static void __init omap_fsample_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc omap_fsample_io_desc[] __initdata = {
+ {
+ .virtual = H2P2_DBG_FPGA_BASE,
+ .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START),
+ .length = H2P2_DBG_FPGA_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = FSAMPLE_CPLD_BASE,
+ .pfn = __phys_to_pfn(FSAMPLE_CPLD_START),
+ .length = FSAMPLE_CPLD_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init omap_fsample_map_io(void)
+{
+ omap1_map_common_io();
+ iotable_init(omap_fsample_io_desc,
+ ARRAY_SIZE(omap_fsample_io_desc));
+
+ /* Early, board-dependent init */
+
+ /*
+ * Hold GSM Reset until needed
+ */
+ omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL);
+
+ /*
+ * UARTs -> done automagically by 8250 driver
+ */
+
+ /*
+ * CSx timings, GPIO Mux ... setup
+ */
+
+ /* Flash: CS0 timings setup */
+ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0);
+ omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0);
+
+ /*
+ * Ethernet support through the debug board
+ * CS1 timings setup
+ */
+ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1);
+ omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1);
+
+ /*
+ * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
+ * It is used as the Ethernet controller interrupt
+ */
+ omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9);
+}
+
+MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
+/* Maintainer: Brian Swetland <swetland@google.com> */
+ .boot_params = 0x10000100,
+ .map_io = omap_fsample_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_fsample_init_irq,
+ .init_machine = omap_fsample_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
new file mode 100644
index 00000000..23f4ab9e
--- /dev/null
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-omap1/board-generic.c
+ *
+ * Modified from board-innovator1510.c
+ *
+ * Code for generic OMAP board. Should work on many OMAP systems where
+ * the device drivers take care of all the necessary hardware initialization.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+
+static void __init omap_generic_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+/* assume no Mini-AB port */
+
+#ifdef CONFIG_ARCH_OMAP15XX
+static struct omap_usb_config generic1510_usb_config __initdata = {
+ .register_host = 1,
+ .register_dev = 1,
+ .hmc_mode = 16,
+ .pins[0] = 3,
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct omap_usb_config generic1610_usb_config __initdata = {
+#ifdef CONFIG_USB_OTG
+ .otg = 1,
+#endif
+ .register_host = 1,
+ .register_dev = 1,
+ .hmc_mode = 16,
+ .pins[0] = 6,
+};
+#endif
+
+static struct omap_board_config_kernel generic_config[] __initdata = {
+};
+
+static void __init omap_generic_init(void)
+{
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap15xx()) {
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ omap1_usb_init(&generic1510_usb_config);
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+ if (!cpu_is_omap1510()) {
+ omap1_usb_init(&generic1610_usb_config);
+ }
+#endif
+
+ omap_board_config = generic_config;
+ omap_board_config_size = ARRAY_SIZE(generic_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+static void __init omap_generic_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
+ /* Maintainer: Tony Lindgren <tony@atomide.com> */
+ .boot_params = 0x10000100,
+ .map_io = omap_generic_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_generic_init_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
new file mode 100644
index 00000000..f2fc43d8
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h2-mmc.c
+ *
+ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
+ * Author: Felipe Balbi <felipe.lima@indt.org.br>
+ *
+ * This code is based on linux/arch/arm/mach-omap2/board-n800-mmc.c, which is:
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <plat/mmc.h>
+#include <mach/gpio.h>
+
+#include "board-h2.h"
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ gpio_set_value(H2_TPS_GPIO_MMC_PWR_EN, power_on);
+ return 0;
+}
+
+static int mmc_late_init(struct device *dev)
+{
+ int ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return ret;
+
+ gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
+
+ return ret;
+}
+
+static void mmc_cleanup(struct device *dev)
+{
+ gpio_free(H2_TPS_GPIO_MMC_PWR_EN);
+}
+
+/*
+ * H2 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .init = mmc_late_init,
+ .cleanup = mmc_cleanup,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "mmcblk",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+void __init h2_mmc_init(void)
+{
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+
+void __init h2_mmc_init(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
new file mode 100644
index 00000000..ba3bd09c
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -0,0 +1,470 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h2.c
+ *
+ * Board specific inits for OMAP-1610 H2
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * H2 specific changes and cleanup
+ * Copyright (C) 2004 Nokia Corporation by Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/i2c/tps65010.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+#include <asm/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/irda.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/flash.h>
+
+#include "board-h2.h"
+
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define OMAP1610_ETHR_START 0x04000300
+
+static const unsigned int h2_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_3),
+ KEY(3, 0, KEY_F10),
+ KEY(4, 0, KEY_F5),
+ KEY(5, 0, KEY_9),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(2, 1, KEY_2),
+ KEY(3, 1, KEY_F9),
+ KEY(4, 1, KEY_F7),
+ KEY(5, 1, KEY_0),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_6),
+ KEY(2, 2, KEY_1),
+ KEY(3, 2, KEY_F2),
+ KEY(4, 2, KEY_F6),
+ KEY(5, 2, KEY_HOME),
+ KEY(0, 3, KEY_8),
+ KEY(1, 3, KEY_5),
+ KEY(2, 3, KEY_F12),
+ KEY(3, 3, KEY_F3),
+ KEY(4, 3, KEY_F8),
+ KEY(5, 3, KEY_END),
+ KEY(0, 4, KEY_7),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_F11),
+ KEY(3, 4, KEY_F1),
+ KEY(4, 4, KEY_F4),
+ KEY(5, 4, KEY_ESC),
+ KEY(0, 5, KEY_F13),
+ KEY(1, 5, KEY_F14),
+ KEY(2, 5, KEY_F15),
+ KEY(3, 5, KEY_F16),
+ KEY(4, 5, KEY_SLEEP),
+};
+
+static struct mtd_partition h2_nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data h2_nor_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = h2_nor_partitions,
+ .nr_parts = ARRAY_SIZE(h2_nor_partitions),
+};
+
+static struct resource h2_nor_resource = {
+ /* This is on CS3, wherever it's mapped */
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h2_nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &h2_nor_data,
+ },
+ .num_resources = 1,
+ .resource = &h2_nor_resource,
+};
+
+static struct mtd_partition h2_nand_partitions[] = {
+#if 0
+ /* REVISIT: enable these partitions if you make NAND BOOT
+ * work on your H2 (rev C or newer); published versions of
+ * x-load only support P2 and H3.
+ */
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 64 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 192 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * SZ_1M,
+ },
+#endif
+ {
+ .name = "filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static void h2_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long mask;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+ if (ctrl & NAND_ALE)
+ mask |= 0x04;
+ writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define H2_NAND_RB_GPIO_PIN 62
+
+static int h2_nand_dev_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(H2_NAND_RB_GPIO_PIN);
+}
+
+static const char *h2_part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data h2_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(h2_nand_partitions),
+ .partitions = h2_nand_partitions,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ .part_probe_types = h2_part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = h2_nand_cmd_ctl,
+ .dev_ready = h2_nand_dev_ready,
+
+ },
+};
+
+static struct resource h2_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h2_nand_device = {
+ .name = "gen_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &h2_nand_platdata,
+ },
+ .num_resources = 1,
+ .resource = &h2_nand_resource,
+};
+
+static struct smc91x_platdata h2_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource h2_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP1610_ETHR_START, /* Physical */
+ .end = OMAP1610_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(0),
+ .end = OMAP_GPIO_IRQ(0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device h2_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &h2_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(h2_smc91x_resources),
+ .resource = h2_smc91x_resources,
+};
+
+static struct resource h2_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data h2_keymap_data = {
+ .keymap = h2_keymap,
+ .keymap_size = ARRAY_SIZE(h2_keymap),
+};
+
+static struct omap_kp_platform_data h2_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &h2_keymap_data,
+ .rep = true,
+ .delay = 9,
+ .dbounce = true,
+};
+
+static struct platform_device h2_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h2_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(h2_kp_resources),
+ .resource = h2_kp_resources,
+};
+
+#define H2_IRDA_FIRSEL_GPIO_PIN 17
+
+static struct omap_irda_config h2_irda_data = {
+ .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource h2_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 irda_dmamask = 0xffffffff;
+
+static struct platform_device h2_irda_device = {
+ .name = "omapirda",
+ .id = 0,
+ .dev = {
+ .platform_data = &h2_irda_data,
+ .dma_mask = &irda_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(h2_irda_resources),
+ .resource = h2_irda_resources,
+};
+
+static struct platform_device h2_lcd_device = {
+ .name = "lcd_h2",
+ .id = -1,
+};
+
+static struct platform_device *h2_devices[] __initdata = {
+ &h2_nor_device,
+ &h2_nand_device,
+ &h2_smc91x_device,
+ &h2_irda_device,
+ &h2_kp_device,
+ &h2_lcd_device,
+};
+
+static void __init h2_init_smc91x(void)
+{
+ if (gpio_request(0, "SMC91x irq") < 0) {
+ printk("Error requesting gpio 0 for smc91x irq\n");
+ return;
+ }
+}
+
+static int tps_setup(struct i2c_client *client, void *context)
+{
+ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
+ TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
+
+ return 0;
+}
+
+static struct tps65010_board tps_board = {
+ .base = H2_TPS_GPIO_BASE,
+ .outmask = 0x0f,
+ .setup = tps_setup,
+};
+
+static struct i2c_board_info __initdata h2_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65010", 0x48),
+ .irq = OMAP_GPIO_IRQ(58),
+ .platform_data = &tps_board,
+ }, {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(2),
+ },
+};
+
+static void __init h2_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static struct omap_usb_config h2_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 19, /* 0:host(off) 1:dev|otg 2:disabled */
+ /* .hmc_mode = 21,*/ /* 0:host(off) 1:dev(loopback) 2:host(loopback) */
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* needs OTG cable, or NONSTANDARD (B-to-MiniB) */
+ .hmc_mode = 20, /* 1:dev|otg(off) 1:host 2:disabled */
+#endif
+
+ .pins[1] = 3,
+};
+
+static struct omap_lcd_config h2_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel h2_config[] __initdata = {
+ { OMAP_TAG_LCD, &h2_lcd_config },
+};
+
+static void __init h2_init(void)
+{
+ h2_init_smc91x();
+
+ /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
+ * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
+ * notice whether a NAND chip is enabled at probe time.
+ *
+ * FIXME revC boards (and H3) support NAND-boot, with a dip switch to
+ * put NOR on CS2B and NAND (which on H2 may be 16bit) on CS3. Try
+ * detecting that in code here, to avoid probing every possible flash
+ * configuration...
+ */
+ h2_nor_resource.end = h2_nor_resource.start = omap_cs3_phys();
+ h2_nor_resource.end += SZ_32M - 1;
+
+ h2_nand_resource.end = h2_nand_resource.start = OMAP_CS2B_PHYS;
+ h2_nand_resource.end += SZ_4K - 1;
+ if (gpio_request(H2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
+ BUG();
+ gpio_direction_input(H2_NAND_RB_GPIO_PIN);
+
+ omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+ omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+
+ /* MMC: card detect and WP */
+ /* omap_cfg_reg(U19_ARMIO1); */ /* CD */
+ omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
+
+ /* Mux pins for keypad */
+ omap_cfg_reg(F18_1610_KBC0);
+ omap_cfg_reg(D20_1610_KBC1);
+ omap_cfg_reg(D19_1610_KBC2);
+ omap_cfg_reg(E18_1610_KBC3);
+ omap_cfg_reg(C21_1610_KBC4);
+ omap_cfg_reg(G18_1610_KBR0);
+ omap_cfg_reg(F19_1610_KBR1);
+ omap_cfg_reg(H14_1610_KBR2);
+ omap_cfg_reg(E20_1610_KBR3);
+ omap_cfg_reg(E19_1610_KBR4);
+ omap_cfg_reg(N19_1610_KBR5);
+
+ platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
+ omap_board_config = h2_config;
+ omap_board_config_size = ARRAY_SIZE(h2_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, h2_i2c_board_info,
+ ARRAY_SIZE(h2_i2c_board_info));
+ omap1_usb_init(&h2_usb_config);
+ h2_mmc_init();
+}
+
+static void __init h2_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_H2, "TI-H2")
+ /* Maintainer: Imre Deak <imre.deak@nokia.com> */
+ .boot_params = 0x10000100,
+ .map_io = h2_map_io,
+ .reserve = omap_reserve,
+ .init_irq = h2_init_irq,
+ .init_machine = h2_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h2.h b/arch/arm/mach-omap1/board-h2.h
new file mode 100644
index 00000000..315e2662
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h2.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-omap1/board-h2.h
+ *
+ * Hardware definitions for TI OMAP1610 H2 board.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_H2_H
+#define __ASM_ARCH_OMAP_H2_H
+
+#define H2_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H2_TPS_GPIO_MMC_PWR_EN (H2_TPS_GPIO_BASE + 3)
+
+extern void h2_mmc_init(void);
+
+#endif /* __ASM_ARCH_OMAP_H2_H */
+
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
new file mode 100644
index 00000000..2098525e
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h3-mmc.c
+ *
+ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
+ * Author: Felipe Balbi <felipe.lima@indt.org.br>
+ *
+ * This code is based on linux/arch/arm/mach-omap2/board-n800-mmc.c, which is:
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <plat/mmc.h>
+#include <mach/gpio.h>
+
+#include "board-h3.h"
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ gpio_set_value(H3_TPS_GPIO_MMC_PWR_EN, power_on);
+ return 0;
+}
+
+/*
+ * H3 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that maybe uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "mmcblk",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+void __init h3_mmc_init(void)
+{
+ int ret;
+
+ ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
+
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+
+void __init h3_mmc_init(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
new file mode 100644
index 00000000..ac486776
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -0,0 +1,458 @@
+/*
+ * linux/arch/arm/mach-omap1/board-h3.c
+ *
+ * This file contains OMAP1710 H3 specific code.
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * Greg Lonnon (glonnon@ridgerun.com) or info@ridgerun.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/types.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/tps65010.h>
+#include <linux/smc91x.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <mach/hardware.h>
+#include <asm/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/irqs.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/dma.h>
+#include <plat/common.h>
+#include <plat/flash.h>
+
+#include "board-h3.h"
+
+/* In OMAP1710 H3 the Ethernet is directly connected to CS1 */
+#define OMAP1710_ETHR_START 0x04000300
+
+#define H3_TS_GPIO 48
+
+static const unsigned int h3_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_3),
+ KEY(3, 0, KEY_F10),
+ KEY(4, 0, KEY_F5),
+ KEY(5, 0, KEY_9),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(2, 1, KEY_2),
+ KEY(3, 1, KEY_F9),
+ KEY(4, 1, KEY_F7),
+ KEY(5, 1, KEY_0),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_6),
+ KEY(2, 2, KEY_1),
+ KEY(3, 2, KEY_F2),
+ KEY(4, 2, KEY_F6),
+ KEY(5, 2, KEY_HOME),
+ KEY(0, 3, KEY_8),
+ KEY(1, 3, KEY_5),
+ KEY(2, 3, KEY_F12),
+ KEY(3, 3, KEY_F3),
+ KEY(4, 3, KEY_F8),
+ KEY(5, 3, KEY_END),
+ KEY(0, 4, KEY_7),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_F11),
+ KEY(3, 4, KEY_F1),
+ KEY(4, 4, KEY_F4),
+ KEY(5, 4, KEY_ESC),
+ KEY(0, 5, KEY_F13),
+ KEY(1, 5, KEY_F14),
+ KEY(2, 5, KEY_F15),
+ KEY(3, 5, KEY_F16),
+ KEY(4, 5, KEY_SLEEP),
+};
+
+
+static struct mtd_partition nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data nor_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = nor_partitions,
+ .nr_parts = ARRAY_SIZE(nor_partitions),
+};
+
+static struct resource nor_resource = {
+ /* This is on CS3, wherever it's mapped */
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_data,
+ },
+ .num_resources = 1,
+ .resource = &nor_resource,
+};
+
+static struct mtd_partition nand_partitions[] = {
+#if 0
+ /* REVISIT: enable these partitions if you make NAND BOOT work */
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 64 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * 1024,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 192 * 1024,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * SZ_1M,
+ },
+#endif
+ {
+ .name = "filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long mask;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+ if (ctrl & NAND_ALE)
+ mask |= 0x04;
+ writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define H3_NAND_RB_GPIO_PIN 10
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(H3_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(nand_partitions),
+ .partitions = nand_partitions,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = nand_cmd_ctl,
+ .dev_ready = nand_dev_ready,
+
+ },
+};
+
+static struct resource nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+ .name = "gen_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &nand_platdata,
+ },
+ .num_resources = 1,
+ .resource = &nand_resource,
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = OMAP1710_ETHR_START, /* Physical */
+ .end = OMAP1710_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(40),
+ .end = OMAP_GPIO_IRQ(40),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void __init h3_init_smc91x(void)
+{
+ omap_cfg_reg(W15_1710_GPIO40);
+ if (gpio_request(40, "SMC91x irq") < 0) {
+ printk("Error requesting gpio 40 for smc91x irq\n");
+ return;
+ }
+}
+
+#define GPTIMER_BASE 0xFFFB1400
+#define GPTIMER_REGS(x) (0xFFFB1400 + (x * 0x800))
+#define GPTIMER_REGS_SIZE 0x46
+
+static struct resource intlat_resources[] = {
+ [0] = {
+ .start = GPTIMER_REGS(0), /* Physical */
+ .end = GPTIMER_REGS(0) + GPTIMER_REGS_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_1610_GPTIMER1,
+ .end = INT_1610_GPTIMER1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device intlat_device = {
+ .name = "omap_intlat",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(intlat_resources),
+ .resource = intlat_resources,
+};
+
+static struct resource h3_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data h3_keymap_data = {
+ .keymap = h3_keymap,
+ .keymap_size = ARRAY_SIZE(h3_keymap),
+};
+
+static struct omap_kp_platform_data h3_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &h3_keymap_data,
+ .rep = true,
+ .delay = 9,
+ .dbounce = true,
+};
+
+static struct platform_device h3_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h3_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(h3_kp_resources),
+ .resource = h3_kp_resources,
+};
+
+static struct platform_device h3_lcd_device = {
+ .name = "lcd_h3",
+ .id = -1,
+};
+
+static struct spi_board_info h3_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "tsc2101",
+ .bus_num = 2,
+ .chip_select = 0,
+ .irq = OMAP_GPIO_IRQ(H3_TS_GPIO),
+ .max_speed_hz = 16000000,
+ /* .platform_data = &tsc_platform_data, */
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &intlat_device,
+ &h3_kp_device,
+ &h3_lcd_device,
+};
+
+static struct omap_usb_config h3_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 19, /* 0:host(off) 1:dev|otg 2:disabled */
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+ .hmc_mode = 20, /* 1:dev|otg(off) 1:host 2:disabled */
+#endif
+
+ .pins[1] = 3,
+};
+
+static struct omap_lcd_config h3_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel h3_config[] __initdata = {
+ { OMAP_TAG_LCD, &h3_lcd_config },
+};
+
+static struct i2c_board_info __initdata h3_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65013", 0x48),
+ /* .irq = OMAP_GPIO_IRQ(??), */
+ },
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(14),
+ },
+};
+
+static void __init h3_init(void)
+{
+ h3_init_smc91x();
+
+ /* Here we assume the NOR boot config: NOR on CS3 (possibly swapped
+ * to address 0 by a dip switch), NAND on CS2B. The NAND driver will
+ * notice whether a NAND chip is enabled at probe time.
+ *
+ * H3 support NAND-boot, with a dip switch to put NOR on CS2B and NAND
+ * (which on H2 may be 16bit) on CS3. Try detecting that in code here,
+ * to avoid probing every possible flash configuration...
+ */
+ nor_resource.end = nor_resource.start = omap_cs3_phys();
+ nor_resource.end += SZ_32M - 1;
+
+ nand_resource.end = nand_resource.start = OMAP_CS2B_PHYS;
+ nand_resource.end += SZ_4K - 1;
+ if (gpio_request(H3_NAND_RB_GPIO_PIN, "NAND ready") < 0)
+ BUG();
+ gpio_direction_input(H3_NAND_RB_GPIO_PIN);
+
+ /* GPIO10 Func_MUX_CTRL reg bit 29:27, Configure V2 to mode1 as GPIO */
+ /* GPIO10 pullup/down register, Enable pullup on GPIO10 */
+ omap_cfg_reg(V2_1710_GPIO10);
+
+ /* Mux pins for keypad */
+ omap_cfg_reg(F18_1610_KBC0);
+ omap_cfg_reg(D20_1610_KBC1);
+ omap_cfg_reg(D19_1610_KBC2);
+ omap_cfg_reg(E18_1610_KBC3);
+ omap_cfg_reg(C21_1610_KBC4);
+ omap_cfg_reg(G18_1610_KBR0);
+ omap_cfg_reg(F19_1610_KBR1);
+ omap_cfg_reg(H14_1610_KBR2);
+ omap_cfg_reg(E20_1610_KBR3);
+ omap_cfg_reg(E19_1610_KBR4);
+ omap_cfg_reg(N19_1610_KBR5);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ spi_register_board_info(h3_spi_board_info,
+ ARRAY_SIZE(h3_spi_board_info));
+ omap_board_config = h3_config;
+ omap_board_config_size = ARRAY_SIZE(h3_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, h3_i2c_board_info,
+ ARRAY_SIZE(h3_i2c_board_info));
+ omap1_usb_init(&h3_usb_config);
+ h3_mmc_init();
+}
+
+static void __init h3_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static void __init h3_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
+ /* Maintainer: Texas Instruments, Inc. */
+ .boot_params = 0x10000100,
+ .map_io = h3_map_io,
+ .reserve = omap_reserve,
+ .init_irq = h3_init_irq,
+ .init_machine = h3_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-h3.h b/arch/arm/mach-omap1/board-h3.h
new file mode 100644
index 00000000..78de535b
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h3.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-omap1/board-h3.h
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2004 Texas Instruments, 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_ARCH_OMAP_H3_H
+#define __ASM_ARCH_OMAP_H3_H
+
+#define H3_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define H3_TPS_GPIO_MMC_PWR_EN (H3_TPS_GPIO_BASE + 4)
+
+extern void h3_mmc_init(void);
+
+#endif /* __ASM_ARCH_OMAP_H3_H */
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
new file mode 100644
index 00000000..ba05a51f
--- /dev/null
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -0,0 +1,620 @@
+/*
+ * HTC Herald board configuration
+ * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
+ * Copyright (C) 2009 Wing Linux
+ *
+ * Based on the board-htcwizard.c file from the linwizard project:
+ * Copyright (C) 2006 Unai Uribarri
+ * Copyright (C) 2008 linwizard.sourceforge.net
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/htcpld.h>
+#include <linux/leds.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/omap7xx.h>
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/keypad.h>
+#include <plat/usb.h>
+#include <plat/mmc.h>
+
+#include <mach/irqs.h>
+
+#include <linux/delay.h>
+
+/* LCD register definition */
+#define OMAP_LCDC_CONTROL (0xfffec000 + 0x00)
+#define OMAP_LCDC_STATUS (0xfffec000 + 0x10)
+#define OMAP_DMA_LCD_CCR (0xfffee300 + 0xc2)
+#define OMAP_DMA_LCD_CTRL (0xfffee300 + 0xc4)
+#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)
+#define OMAP_LCDC_STAT_DONE (1 << 0)
+
+/* GPIO definitions for the power button and keyboard slide switch */
+#define HTCHERALD_GPIO_POWER 139
+#define HTCHERALD_GPIO_SLIDE 174
+#define HTCHERALD_GIRQ_BTNS 141
+
+/* GPIO definitions for the touchscreen */
+#define HTCHERALD_GPIO_TS 76
+
+/* HTCPLD definitions */
+
+/*
+ * CPLD Logic
+ *
+ * Chip 3 - 0x03
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * DPAD light x x x x x x x 1
+ * SoundDev x x x x 1 x x x
+ * Screen white 1 x x x x x x x
+ * MMC power on x x x x x 1 x x
+ * Happy times (n) 0 x x x x 1 x x
+ *
+ * Chip 4 - 0x04
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Keyboard light x x x x x x x 1
+ * LCD Bright (4) x x x x x 1 1 x
+ * LCD Bright (3) x x x x x 0 1 x
+ * LCD Bright (2) x x x x x 1 0 x
+ * LCD Bright (1) x x x x x 0 0 x
+ * LCD Off x x x x 0 x x x
+ * LCD image (fb) 1 x x x x x x x
+ * LCD image (white) 0 x x x x x x x
+ * Caps lock LED x x 1 x x x x x
+ *
+ * Chip 5 - 0x05
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Red (solid) x x x x x 1 x x
+ * Red (flash) x x x x x x 1 x
+ * Green (GSM flash) x x x x 1 x x x
+ * Green (GSM solid) x x x 1 x x x x
+ * Green (wifi flash) x x 1 x x x x x
+ * Blue (bt flash) x 1 x x x x x x
+ * DPAD Int Enable 1 x x x x x x 0
+ *
+ * (Combinations of the above can be made for different colors.)
+ * The direction pad interrupt enable must be set each time the
+ * interrupt is handled.
+ *
+ * Chip 6 - 0x06
+ *
+ * Function 7 6 5 4 3 2 1 0
+ * ------------------------------------
+ * Vibrator x x x x 1 x x x
+ * Alt LED x x x 1 x x x x
+ * Screen white 1 x x x x x x x
+ * Screen white x x 1 x x x x x
+ * Screen white x 0 x x x x x x
+ * Enable kbd dpad x x x x x x 0 x
+ * Happy Times 0 1 0 x x x 0 x
+ */
+
+/*
+ * HTCPLD GPIO lines start 16 after OMAP_MAX_GPIO_LINES to account
+ * for the 16 MPUIO lines.
+ */
+#define HTCPLD_GPIO_START_OFFSET (OMAP_MAX_GPIO_LINES + 16)
+#define HTCPLD_IRQ(chip, offset) (OMAP_IRQ_END + 8 * (chip) + (offset))
+#define HTCPLD_BASE(chip, offset) \
+ (HTCPLD_GPIO_START_OFFSET + 8 * (chip) + (offset))
+
+#define HTCPLD_GPIO_LED_DPAD HTCPLD_BASE(0, 0)
+#define HTCPLD_GPIO_LED_KBD HTCPLD_BASE(1, 0)
+#define HTCPLD_GPIO_LED_CAPS HTCPLD_BASE(1, 5)
+#define HTCPLD_GPIO_LED_RED_FLASH HTCPLD_BASE(2, 1)
+#define HTCPLD_GPIO_LED_RED_SOLID HTCPLD_BASE(2, 2)
+#define HTCPLD_GPIO_LED_GREEN_FLASH HTCPLD_BASE(2, 3)
+#define HTCPLD_GPIO_LED_GREEN_SOLID HTCPLD_BASE(2, 4)
+#define HTCPLD_GPIO_LED_WIFI HTCPLD_BASE(2, 5)
+#define HTCPLD_GPIO_LED_BT HTCPLD_BASE(2, 6)
+#define HTCPLD_GPIO_LED_VIBRATE HTCPLD_BASE(3, 3)
+#define HTCPLD_GPIO_LED_ALT HTCPLD_BASE(3, 4)
+
+#define HTCPLD_GPIO_RIGHT_KBD HTCPLD_BASE(6, 7)
+#define HTCPLD_GPIO_UP_KBD HTCPLD_BASE(6, 6)
+#define HTCPLD_GPIO_LEFT_KBD HTCPLD_BASE(6, 5)
+#define HTCPLD_GPIO_DOWN_KBD HTCPLD_BASE(6, 4)
+
+#define HTCPLD_GPIO_RIGHT_DPAD HTCPLD_BASE(7, 7)
+#define HTCPLD_GPIO_UP_DPAD HTCPLD_BASE(7, 6)
+#define HTCPLD_GPIO_LEFT_DPAD HTCPLD_BASE(7, 5)
+#define HTCPLD_GPIO_DOWN_DPAD HTCPLD_BASE(7, 4)
+#define HTCPLD_GPIO_ENTER_DPAD HTCPLD_BASE(7, 3)
+
+/*
+ * The htcpld chip requires a gpio write to a specific line
+ * to re-enable interrupts after one has occurred.
+ */
+#define HTCPLD_GPIO_INT_RESET_HI HTCPLD_BASE(2, 7)
+#define HTCPLD_GPIO_INT_RESET_LO HTCPLD_BASE(2, 0)
+
+/* Chip 5 */
+#define HTCPLD_IRQ_RIGHT_KBD HTCPLD_IRQ(0, 7)
+#define HTCPLD_IRQ_UP_KBD HTCPLD_IRQ(0, 6)
+#define HTCPLD_IRQ_LEFT_KBD HTCPLD_IRQ(0, 5)
+#define HTCPLD_IRQ_DOWN_KBD HTCPLD_IRQ(0, 4)
+
+/* Chip 6 */
+#define HTCPLD_IRQ_RIGHT_DPAD HTCPLD_IRQ(1, 7)
+#define HTCPLD_IRQ_UP_DPAD HTCPLD_IRQ(1, 6)
+#define HTCPLD_IRQ_LEFT_DPAD HTCPLD_IRQ(1, 5)
+#define HTCPLD_IRQ_DOWN_DPAD HTCPLD_IRQ(1, 4)
+#define HTCPLD_IRQ_ENTER_DPAD HTCPLD_IRQ(1, 3)
+
+/* Keyboard definition */
+
+static const unsigned int htc_herald_keymap[] = {
+ KEY(0, 0, KEY_RECORD), /* Mail button */
+ KEY(1, 0, KEY_CAMERA), /* Camera */
+ KEY(2, 0, KEY_PHONE), /* Send key */
+ KEY(3, 0, KEY_VOLUMEUP), /* Volume up */
+ KEY(4, 0, KEY_F2), /* Right bar (landscape) */
+ KEY(5, 0, KEY_MAIL), /* Win key (portrait) */
+ KEY(6, 0, KEY_DIRECTORY), /* Right bar (protrait) */
+ KEY(0, 1, KEY_LEFTCTRL), /* Windows key */
+ KEY(1, 1, KEY_COMMA),
+ KEY(2, 1, KEY_M),
+ KEY(3, 1, KEY_K),
+ KEY(4, 1, KEY_SLASH), /* OK key */
+ KEY(5, 1, KEY_I),
+ KEY(6, 1, KEY_U),
+ KEY(0, 2, KEY_LEFTALT),
+ KEY(1, 2, KEY_TAB),
+ KEY(2, 2, KEY_N),
+ KEY(3, 2, KEY_J),
+ KEY(4, 2, KEY_ENTER),
+ KEY(5, 2, KEY_H),
+ KEY(6, 2, KEY_Y),
+ KEY(0, 3, KEY_SPACE),
+ KEY(1, 3, KEY_L),
+ KEY(2, 3, KEY_B),
+ KEY(3, 3, KEY_V),
+ KEY(4, 3, KEY_BACKSPACE),
+ KEY(5, 3, KEY_G),
+ KEY(6, 3, KEY_T),
+ KEY(0, 4, KEY_CAPSLOCK), /* Shift */
+ KEY(1, 4, KEY_C),
+ KEY(2, 4, KEY_F),
+ KEY(3, 4, KEY_R),
+ KEY(4, 4, KEY_O),
+ KEY(5, 4, KEY_E),
+ KEY(6, 4, KEY_D),
+ KEY(0, 5, KEY_X),
+ KEY(1, 5, KEY_Z),
+ KEY(2, 5, KEY_S),
+ KEY(3, 5, KEY_W),
+ KEY(4, 5, KEY_P),
+ KEY(5, 5, KEY_Q),
+ KEY(6, 5, KEY_A),
+ KEY(0, 6, KEY_CONNECT), /* Voice button */
+ KEY(2, 6, KEY_CANCEL), /* End key */
+ KEY(3, 6, KEY_VOLUMEDOWN), /* Volume down */
+ KEY(4, 6, KEY_F1), /* Left bar (landscape) */
+ KEY(5, 6, KEY_WWW), /* OK button (portrait) */
+ KEY(6, 6, KEY_CALENDAR), /* Left bar (portrait) */
+};
+
+static const struct matrix_keymap_data htc_herald_keymap_data = {
+ .keymap = htc_herald_keymap,
+ .keymap_size = ARRAY_SIZE(htc_herald_keymap),
+};
+
+static struct omap_kp_platform_data htcherald_kp_data = {
+ .rows = 7,
+ .cols = 7,
+ .delay = 20,
+ .rep = true,
+ .keymap_data = &htc_herald_keymap_data,
+};
+
+static struct resource kp_resources[] = {
+ [0] = {
+ .start = INT_7XX_MPUIO_KEYPAD,
+ .end = INT_7XX_MPUIO_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &htcherald_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(kp_resources),
+ .resource = kp_resources,
+};
+
+/* GPIO buttons for keyboard slide and power button */
+static struct gpio_keys_button herald_gpio_keys_table[] = {
+ {BTN_0, HTCHERALD_GPIO_POWER, 1, "POWER", EV_KEY, 1, 20},
+ {SW_LID, HTCHERALD_GPIO_SLIDE, 0, "SLIDE", EV_SW, 1, 20},
+
+ {KEY_LEFT, HTCPLD_GPIO_LEFT_KBD, 1, "LEFT", EV_KEY, 1, 20},
+ {KEY_RIGHT, HTCPLD_GPIO_RIGHT_KBD, 1, "RIGHT", EV_KEY, 1, 20},
+ {KEY_UP, HTCPLD_GPIO_UP_KBD, 1, "UP", EV_KEY, 1, 20},
+ {KEY_DOWN, HTCPLD_GPIO_DOWN_KBD, 1, "DOWN", EV_KEY, 1, 20},
+
+ {KEY_LEFT, HTCPLD_GPIO_LEFT_DPAD, 1, "DLEFT", EV_KEY, 1, 20},
+ {KEY_RIGHT, HTCPLD_GPIO_RIGHT_DPAD, 1, "DRIGHT", EV_KEY, 1, 20},
+ {KEY_UP, HTCPLD_GPIO_UP_DPAD, 1, "DUP", EV_KEY, 1, 20},
+ {KEY_DOWN, HTCPLD_GPIO_DOWN_DPAD, 1, "DDOWN", EV_KEY, 1, 20},
+ {KEY_ENTER, HTCPLD_GPIO_ENTER_DPAD, 1, "DENTER", EV_KEY, 1, 20},
+};
+
+static struct gpio_keys_platform_data herald_gpio_keys_data = {
+ .buttons = herald_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(herald_gpio_keys_table),
+ .rep = true,
+};
+
+static struct platform_device herald_gpiokeys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &herald_gpio_keys_data,
+ },
+};
+
+/* LEDs for the Herald. These connect to the HTCPLD GPIO device. */
+static struct gpio_led gpio_leds[] = {
+ {"dpad", NULL, HTCPLD_GPIO_LED_DPAD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"kbd", NULL, HTCPLD_GPIO_LED_KBD, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"vibrate", NULL, HTCPLD_GPIO_LED_VIBRATE, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"green_solid", NULL, HTCPLD_GPIO_LED_GREEN_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"green_flash", NULL, HTCPLD_GPIO_LED_GREEN_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"red_solid", "mmc0", HTCPLD_GPIO_LED_RED_SOLID, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"red_flash", NULL, HTCPLD_GPIO_LED_RED_FLASH, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"wifi", NULL, HTCPLD_GPIO_LED_WIFI, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"bt", NULL, HTCPLD_GPIO_LED_BT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"caps", NULL, HTCPLD_GPIO_LED_CAPS, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+ {"alt", NULL, HTCPLD_GPIO_LED_ALT, 0, 0, LEDS_GPIO_DEFSTATE_OFF},
+};
+
+static struct gpio_led_platform_data gpio_leds_data = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &gpio_leds_data,
+ },
+};
+
+/* HTC PLD chips */
+
+static struct resource htcpld_resources[] = {
+ [0] = {
+ .start = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),
+ .end = OMAP_GPIO_IRQ(HTCHERALD_GIRQ_BTNS),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct htcpld_chip_platform_data htcpld_chips[] = {
+ [0] = {
+ .addr = 0x03,
+ .reset = 0x04,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(0, 0),
+ .gpio_in_base = HTCPLD_BASE(4, 0),
+ },
+ [1] = {
+ .addr = 0x04,
+ .reset = 0x8e,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(1, 0),
+ .gpio_in_base = HTCPLD_BASE(5, 0),
+ },
+ [2] = {
+ .addr = 0x05,
+ .reset = 0x80,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(2, 0),
+ .gpio_in_base = HTCPLD_BASE(6, 0),
+ .irq_base = HTCPLD_IRQ(0, 0),
+ .num_irqs = 8,
+ },
+ [3] = {
+ .addr = 0x06,
+ .reset = 0x40,
+ .num_gpios = 8,
+ .gpio_out_base = HTCPLD_BASE(3, 0),
+ .gpio_in_base = HTCPLD_BASE(7, 0),
+ .irq_base = HTCPLD_IRQ(1, 0),
+ .num_irqs = 8,
+ },
+};
+
+static struct htcpld_core_platform_data htcpld_pfdata = {
+ .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI,
+ .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO,
+ .i2c_adapter_id = 1,
+
+ .chip = htcpld_chips,
+ .num_chip = ARRAY_SIZE(htcpld_chips),
+};
+
+static struct platform_device htcpld_device = {
+ .name = "i2c-htcpld",
+ .id = -1,
+ .resource = htcpld_resources,
+ .num_resources = ARRAY_SIZE(htcpld_resources),
+ .dev = {
+ .platform_data = &htcpld_pfdata,
+ },
+};
+
+/* USB Device */
+static struct omap_usb_config htcherald_usb_config __initdata = {
+ .otg = 0,
+ .register_host = 0,
+ .register_dev = 1,
+ .hmc_mode = 4,
+ .pins[0] = 2,
+};
+
+/* LCD Device resources */
+static struct omap_lcd_config htcherald_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel htcherald_config[] __initdata = {
+ { OMAP_TAG_LCD, &htcherald_lcd_config },
+};
+
+static struct platform_device lcd_device = {
+ .name = "lcd_htcherald",
+ .id = -1,
+};
+
+/* MMC Card */
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+static struct omap_mmc_platform_data htc_mmc1_data = {
+ .nr_slots = 1,
+ .switch_slot = NULL,
+ .slots[0] = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "mmcblk",
+ .nomux = 1,
+ .wires = 4,
+ .switch_pin = -1,
+ },
+};
+
+static struct omap_mmc_platform_data *htc_mmc_data[1];
+#endif
+
+
+/* Platform devices for the Herald */
+static struct platform_device *devices[] __initdata = {
+ &kp_device,
+ &lcd_device,
+ &htcpld_device,
+ &gpio_leds_device,
+ &herald_gpiokeys_device,
+};
+
+/*
+ * Touchscreen
+ */
+static const struct ads7846_platform_data htcherald_ts_platform_data = {
+ .model = 7846,
+ .keep_vref_on = 1,
+ .x_plate_ohms = 496,
+ .gpio_pendown = HTCHERALD_GPIO_TS,
+ .pressure_max = 10000,
+ .pressure_min = 5000,
+ .x_min = 528,
+ .x_max = 3760,
+ .y_min = 624,
+ .y_max = 3760,
+};
+
+static struct spi_board_info __initdata htcherald_spi_board_info[] = {
+ {
+ .modalias = "ads7846",
+ .platform_data = &htcherald_ts_platform_data,
+ .irq = OMAP_GPIO_IRQ(HTCHERALD_GPIO_TS),
+ .max_speed_hz = 2500000,
+ .bus_num = 2,
+ .chip_select = 1,
+ }
+};
+
+/*
+ * Init functions from here on
+ */
+
+static void __init htcherald_lcd_init(void)
+{
+ u32 reg;
+ unsigned int tries = 200;
+
+ /* disable controller if active */
+ reg = omap_readl(OMAP_LCDC_CONTROL);
+ if (reg & OMAP_LCDC_CTRL_LCD_EN) {
+ reg &= ~OMAP_LCDC_CTRL_LCD_EN;
+ omap_writel(reg, OMAP_LCDC_CONTROL);
+
+ /* wait for end of frame */
+ while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
+ tries--;
+ if (!tries)
+ break;
+ }
+ if (!tries)
+ printk(KERN_WARNING "Timeout waiting for end of frame "
+ "-- LCD may not be available\n");
+
+ /* turn off DMA */
+ reg = omap_readw(OMAP_DMA_LCD_CCR);
+ reg &= ~(1 << 7);
+ omap_writew(reg, OMAP_DMA_LCD_CCR);
+
+ reg = omap_readw(OMAP_DMA_LCD_CTRL);
+ reg &= ~(1 << 8);
+ omap_writew(reg, OMAP_DMA_LCD_CTRL);
+ }
+}
+
+static void __init htcherald_map_io(void)
+{
+ omap1_map_common_io();
+
+ /*
+ * The LCD panel must be disabled and DMA turned off here, as doing
+ * it later causes the LCD never to reinitialize.
+ */
+ htcherald_lcd_init();
+
+ printk(KERN_INFO "htcherald_map_io done.\n");
+}
+
+static void __init htcherald_disable_watchdog(void)
+{
+ /* Disable watchdog if running */
+ if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
+ /*
+ * disable a potentially running watchdog timer before
+ * it kills us.
+ */
+ printk(KERN_WARNING "OMAP850 Watchdog seems to be activated, disabling it for now.\n");
+ omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
+ omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+#define HTCHERALD_GPIO_USB_EN1 33
+#define HTCHERALD_GPIO_USB_EN2 73
+#define HTCHERALD_GPIO_USB_DM 35
+#define HTCHERALD_GPIO_USB_DP 36
+
+static void __init htcherald_usb_enable(void)
+{
+ unsigned int tries = 20;
+ unsigned int value = 0;
+
+ /* Request the GPIOs we need to control here */
+ if (gpio_request(HTCHERALD_GPIO_USB_EN1, "herald_usb") < 0)
+ goto err1;
+
+ if (gpio_request(HTCHERALD_GPIO_USB_EN2, "herald_usb") < 0)
+ goto err2;
+
+ if (gpio_request(HTCHERALD_GPIO_USB_DM, "herald_usb") < 0)
+ goto err3;
+
+ if (gpio_request(HTCHERALD_GPIO_USB_DP, "herald_usb") < 0)
+ goto err4;
+
+ /* force USB_EN GPIO to 0 */
+ do {
+ /* output low */
+ gpio_direction_output(HTCHERALD_GPIO_USB_EN1, 0);
+ } while ((value = gpio_get_value(HTCHERALD_GPIO_USB_EN1)) == 1 &&
+ --tries);
+
+ if (value == 1)
+ printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
+
+ gpio_direction_output(HTCHERALD_GPIO_USB_EN2, 0); /* output low */
+ gpio_direction_input(HTCHERALD_GPIO_USB_DM); /* input */
+ gpio_direction_input(HTCHERALD_GPIO_USB_DP); /* input */
+
+ goto done;
+
+err4:
+ gpio_free(HTCHERALD_GPIO_USB_DM);
+err3:
+ gpio_free(HTCHERALD_GPIO_USB_EN2);
+err2:
+ gpio_free(HTCHERALD_GPIO_USB_EN1);
+err1:
+ printk(KERN_ERR "Unabled to request GPIO for USB\n");
+done:
+ printk(KERN_INFO "USB setup complete.\n");
+}
+
+static void __init htcherald_init(void)
+{
+ printk(KERN_INFO "HTC Herald init.\n");
+
+ /* Do board initialization before we register all the devices */
+ omap_board_config = htcherald_config;
+ omap_board_config_size = ARRAY_SIZE(htcherald_config);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ htcherald_disable_watchdog();
+
+ htcherald_usb_enable();
+ omap1_usb_init(&htcherald_usb_config);
+
+ spi_register_board_info(htcherald_spi_board_info,
+ ARRAY_SIZE(htcherald_spi_board_info));
+
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+ htc_mmc_data[0] = &htc_mmc1_data;
+ omap1_init_mmc(htc_mmc_data, 1);
+#endif
+}
+
+static void __init htcherald_init_irq(void)
+{
+ printk(KERN_INFO "htcherald_init_irq.\n");
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+MACHINE_START(HERALD, "HTC Herald")
+ /* Maintainer: Cory Maccarrone <darkstar6262@gmail.com> */
+ /* Maintainer: wing-linux.sourceforge.net */
+ .boot_params = 0x10000100,
+ .map_io = htcherald_map_io,
+ .reserve = omap_reserve,
+ .init_irq = htcherald_init_irq,
+ .init_machine = htcherald_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
new file mode 100644
index 00000000..2d9b8cbd
--- /dev/null
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -0,0 +1,468 @@
+/*
+ * linux/arch/arm/mach-omap1/board-innovator.c
+ *
+ * Board specific inits for OMAP-1510 and OMAP-1610 Innovator
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.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/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mux.h>
+#include <plat/flash.h>
+#include <plat/fpga.h>
+#include <mach/gpio.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/mmc.h>
+
+/* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
+#define INNOVATOR1610_ETHR_START 0x04000300
+
+static const unsigned int innovator_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(3, 0, KEY_DOWN),
+ KEY(1, 1, KEY_F2),
+ KEY(2, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_F3),
+ KEY(1, 2, KEY_F4),
+ KEY(2, 2, KEY_UP),
+ KEY(2, 3, KEY_ENTER),
+ KEY(3, 3, KEY_LEFT),
+};
+
+static struct mtd_partition innovator_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* rest of flash1 is a file system */
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16M - SZ_2M - 2 * SZ_128K,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data innovator_flash_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = innovator_partitions,
+ .nr_parts = ARRAY_SIZE(innovator_partitions),
+};
+
+static struct resource innovator_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device innovator_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &innovator_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &innovator_flash_resource,
+};
+
+static struct resource innovator_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data innovator_keymap_data = {
+ .keymap = innovator_keymap,
+ .keymap_size = ARRAY_SIZE(innovator_keymap),
+};
+
+static struct omap_kp_platform_data innovator_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &innovator_keymap_data,
+ .delay = 4,
+};
+
+static struct platform_device innovator_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &innovator_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(innovator_kp_resources),
+ .resource = innovator_kp_resources,
+};
+
+static struct smc91x_platdata innovator_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+#ifdef CONFIG_ARCH_OMAP15XX
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc innovator1510_io_desc[] __initdata = {
+ {
+ .virtual = OMAP1510_FPGA_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_FPGA_START),
+ .length = OMAP1510_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static struct resource innovator1510_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP1510_FPGA_ETHR_START, /* Physical */
+ .end = OMAP1510_FPGA_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP1510_INT_ETHER,
+ .end = OMAP1510_INT_ETHER,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device innovator1510_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &innovator_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(innovator1510_smc91x_resources),
+ .resource = innovator1510_smc91x_resources,
+};
+
+static struct platform_device innovator1510_lcd_device = {
+ .name = "lcd_inn1510",
+ .id = -1,
+};
+
+static struct platform_device innovator1510_spi_device = {
+ .name = "spi_inn1510",
+ .id = -1,
+};
+
+static struct platform_device *innovator1510_devices[] __initdata = {
+ &innovator_flash_device,
+ &innovator1510_smc91x_device,
+ &innovator_kp_device,
+ &innovator1510_lcd_device,
+ &innovator1510_spi_device,
+};
+
+static int innovator_get_pendown_state(void)
+{
+ return !(fpga_read(OMAP1510_FPGA_TOUCHSCREEN) & (1 << 5));
+}
+
+static const struct ads7846_platform_data innovator1510_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = innovator_get_pendown_state,
+};
+
+static struct spi_board_info __initdata innovator1510_boardinfo[] = { {
+ /* FPGA (bus "10") CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &innovator1510_ts_info,
+ .irq = OMAP1510_INT_FPGA_TS,
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 10,
+ .chip_select = 0,
+} };
+
+#endif /* CONFIG_ARCH_OMAP15XX */
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+static struct resource innovator1610_smc91x_resources[] = {
+ [0] = {
+ .start = INNOVATOR1610_ETHR_START, /* Physical */
+ .end = INNOVATOR1610_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(0),
+ .end = OMAP_GPIO_IRQ(0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device innovator1610_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &innovator_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(innovator1610_smc91x_resources),
+ .resource = innovator1610_smc91x_resources,
+};
+
+static struct platform_device innovator1610_lcd_device = {
+ .name = "inn1610_lcd",
+ .id = -1,
+};
+
+static struct platform_device *innovator1610_devices[] __initdata = {
+ &innovator_flash_device,
+ &innovator1610_smc91x_device,
+ &innovator_kp_device,
+ &innovator1610_lcd_device,
+};
+
+#endif /* CONFIG_ARCH_OMAP16XX */
+
+static void __init innovator_init_smc91x(void)
+{
+ if (cpu_is_omap1510()) {
+ fpga_write(fpga_read(OMAP1510_FPGA_RST) & ~1,
+ OMAP1510_FPGA_RST);
+ udelay(750);
+ } else {
+ if (gpio_request(0, "SMC91x irq") < 0) {
+ printk("Error requesting gpio 0 for smc91x irq\n");
+ return;
+ }
+ }
+}
+
+static void __init innovator_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+#ifdef CONFIG_ARCH_OMAP15XX
+static struct omap_usb_config innovator1510_usb_config __initdata = {
+ /* for bundled non-standard host and peripheral cables */
+ .hmc_mode = 4,
+
+ .register_host = 1,
+ .pins[1] = 6,
+ .pins[2] = 6, /* Conflicts with UART2 */
+
+ .register_dev = 1,
+ .pins[0] = 2,
+};
+
+static struct omap_lcd_config innovator1510_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+static struct omap_usb_config h2_usb_config __initdata = {
+ /* usb1 has a Mini-AB port and external isp1301 transceiver */
+ .otg = 2,
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 19, /* 0:host(off) 1:dev|otg 2:disabled */
+ /* .hmc_mode = 21,*/ /* 0:host(off) 1:dev(loopback) 2:host(loopback) */
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* NONSTANDARD CABLE NEEDED (B-to-Mini-B) */
+ .hmc_mode = 20, /* 1:dev|otg(off) 1:host 2:disabled */
+#endif
+
+ .pins[1] = 3,
+};
+
+static struct omap_lcd_config innovator1610_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+#endif
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (power_on)
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
+ OMAP1510_FPGA_POWER);
+ else
+ fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
+ OMAP1510_FPGA_POWER);
+
+ return 0;
+}
+
+/*
+ * Innovator could use the following functions tested:
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ * - mmc_get_cover_state that uses FPGA F4 UIO43
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .wires = 4,
+ .name = "mmcblk",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+static void __init innovator_mmc_init(void)
+{
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
+}
+
+#else
+static inline void innovator_mmc_init(void)
+{
+}
+#endif
+
+static struct omap_board_config_kernel innovator_config[] = {
+ { OMAP_TAG_LCD, NULL },
+};
+
+static void __init innovator_init(void)
+{
+ if (cpu_is_omap1510())
+ omap1510_fpga_init_irq();
+ innovator_init_smc91x();
+
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
+ unsigned char reg;
+
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ reg = fpga_read(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM1_EN;
+ fpga_write(reg, OMAP1510_FPGA_POWER);
+ udelay(10);
+
+ reg = fpga_read(OMAP1510_FPGA_POWER);
+ reg |= OMAP1510_FPGA_PCR_COM2_EN;
+ fpga_write(reg, OMAP1510_FPGA_POWER);
+ udelay(10);
+
+ platform_add_devices(innovator1510_devices, ARRAY_SIZE(innovator1510_devices));
+ spi_register_board_info(innovator1510_boardinfo,
+ ARRAY_SIZE(innovator1510_boardinfo));
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ if (!cpu_is_omap1510()) {
+ platform_add_devices(innovator1610_devices, ARRAY_SIZE(innovator1610_devices));
+ }
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
+ omap1_usb_init(&innovator1510_usb_config);
+ innovator_config[1].data = &innovator1510_lcd_config;
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+ if (cpu_is_omap1610()) {
+ omap1_usb_init(&h2_usb_config);
+ innovator_config[1].data = &innovator1610_lcd_config;
+ }
+#endif
+ omap_board_config = innovator_config;
+ omap_board_config_size = ARRAY_SIZE(innovator_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ innovator_mmc_init();
+}
+
+static void __init innovator_map_io(void)
+{
+ omap1_map_common_io();
+
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
+ iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc));
+ udelay(10); /* Delay needed for FPGA */
+
+ /* Dump the Innovator FPGA rev early - useful info for support. */
+ printk("Innovator FPGA Rev %d.%d Board Rev %d\n",
+ fpga_read(OMAP1510_FPGA_REV_HIGH),
+ fpga_read(OMAP1510_FPGA_REV_LOW),
+ fpga_read(OMAP1510_FPGA_BOARD_REV));
+ }
+#endif
+}
+
+MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
+ /* Maintainer: MontaVista Software, Inc. */
+ .boot_params = 0x10000100,
+ .map_io = innovator_map_io,
+ .reserve = omap_reserve,
+ .init_irq = innovator_init_irq,
+ .init_machine = innovator_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
new file mode 100644
index 00000000..cfd08492
--- /dev/null
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -0,0 +1,273 @@
+/*
+ * linux/arch/arm/mach-omap1/board-nokia770.c
+ *
+ * Modified from board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/clk.h>
+#include <linux/omapfb.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/hwa742.h>
+#include <plat/lcd_mipid.h>
+#include <plat/mmc.h>
+#include <plat/clock.h>
+
+#define ADS7846_PENDOWN_GPIO 15
+
+static void __init omap_nokia770_init_irq(void)
+{
+ /* On Nokia 770, the SleepX signal is masked with an
+ * MPUIO line by default. It has to be unmasked for it
+ * to become functional */
+
+ /* SleepX mask direction */
+ omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008);
+ /* Unmask SleepX signal */
+ omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004);
+
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static const unsigned int nokia770_keymap[] = {
+ KEY(1, 0, GROUP_0 | KEY_UP),
+ KEY(2, 0, GROUP_1 | KEY_F5),
+ KEY(0, 1, GROUP_0 | KEY_LEFT),
+ KEY(1, 1, GROUP_0 | KEY_ENTER),
+ KEY(2, 1, GROUP_0 | KEY_RIGHT),
+ KEY(0, 2, GROUP_1 | KEY_ESC),
+ KEY(1, 2, GROUP_0 | KEY_DOWN),
+ KEY(2, 2, GROUP_1 | KEY_F4),
+ KEY(0, 3, GROUP_2 | KEY_F7),
+ KEY(1, 3, GROUP_2 | KEY_F8),
+ KEY(2, 3, GROUP_2 | KEY_F6),
+};
+
+static struct resource nokia770_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data nokia770_keymap_data = {
+ .keymap = nokia770_keymap,
+ .keymap_size = ARRAY_SIZE(nokia770_keymap),
+};
+
+static struct omap_kp_platform_data nokia770_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &nokia770_keymap_data,
+ .delay = 4,
+};
+
+static struct platform_device nokia770_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &nokia770_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(nokia770_kp_resources),
+ .resource = nokia770_kp_resources,
+};
+
+static struct platform_device *nokia770_devices[] __initdata = {
+ &nokia770_kp_device,
+};
+
+static void mipid_shutdown(struct mipid_platform_data *pdata)
+{
+ if (pdata->nreset_gpio != -1) {
+ printk(KERN_INFO "shutdown LCD\n");
+ gpio_set_value(pdata->nreset_gpio, 0);
+ msleep(120);
+ }
+}
+
+static struct mipid_platform_data nokia770_mipid_platform_data = {
+ .shutdown = mipid_shutdown,
+};
+
+static void __init mipid_dev_init(void)
+{
+ const struct omap_lcd_config *conf;
+
+ conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+ if (conf != NULL) {
+ nokia770_mipid_platform_data.nreset_gpio = conf->nreset_gpio;
+ nokia770_mipid_platform_data.data_lines = conf->data_lines;
+ }
+}
+
+static void __init ads7846_dev_init(void)
+{
+ if (gpio_request(ADS7846_PENDOWN_GPIO, "ADS7846 pendown") < 0)
+ printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
+}
+
+static int ads7846_get_pendown_state(void)
+{
+ return !gpio_get_value(ADS7846_PENDOWN_GPIO);
+}
+
+static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = {
+ .x_max = 0x0fff,
+ .y_max = 0x0fff,
+ .x_plate_ohms = 180,
+ .pressure_max = 255,
+ .debounce_max = 10,
+ .debounce_tol = 3,
+ .debounce_rep = 1,
+ .get_pendown_state = ads7846_get_pendown_state,
+};
+
+static struct spi_board_info nokia770_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "lcd_mipid",
+ .bus_num = 2,
+ .chip_select = 3,
+ .max_speed_hz = 12000000,
+ .platform_data = &nokia770_mipid_platform_data,
+ },
+ [1] = {
+ .modalias = "ads7846",
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 2500000,
+ .irq = OMAP_GPIO_IRQ(15),
+ .platform_data = &nokia770_ads7846_platform_data,
+ },
+};
+
+static struct hwa742_platform_data nokia770_hwa742_platform_data = {
+ .te_connected = 1,
+};
+
+static void __init hwa742_dev_init(void)
+{
+ clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL);
+ omapfb_set_ctrl_platform_data(&nokia770_hwa742_platform_data);
+}
+
+/* assume no Mini-AB port */
+
+static struct omap_usb_config nokia770_usb_config __initdata = {
+ .otg = 1,
+ .register_host = 1,
+ .register_dev = 1,
+ .hmc_mode = 16,
+ .pins[0] = 6,
+};
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define NOKIA770_GPIO_MMC_POWER 41
+#define NOKIA770_GPIO_MMC_SWITCH 23
+
+static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on);
+ return 0;
+}
+
+static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
+{
+ return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
+}
+
+static struct omap_mmc_platform_data nokia770_mmc2_data = {
+ .nr_slots = 1,
+ .dma_mask = 0xffffffff,
+ .max_freq = 12000000,
+ .slots[0] = {
+ .set_power = nokia770_mmc_set_power,
+ .get_cover_state = nokia770_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .name = "mmcblk",
+ },
+};
+
+static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
+
+static void __init nokia770_mmc_init(void)
+{
+ int ret;
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
+ if (ret < 0)
+ return;
+ gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
+
+ ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
+ if (ret < 0) {
+ gpio_free(NOKIA770_GPIO_MMC_POWER);
+ return;
+ }
+ gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
+
+ /* Only the second MMC controller is used */
+ nokia770_mmc_data[1] = &nokia770_mmc2_data;
+ omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+static inline void nokia770_mmc_init(void)
+{
+}
+#endif
+
+static void __init omap_nokia770_init(void)
+{
+ platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
+ spi_register_board_info(nokia770_spi_board_info,
+ ARRAY_SIZE(nokia770_spi_board_info));
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ hwa742_dev_init();
+ ads7846_dev_init();
+ mipid_dev_init();
+ omap1_usb_init(&nokia770_usb_config);
+ nokia770_mmc_init();
+}
+
+static void __init omap_nokia770_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(NOKIA770, "Nokia 770")
+ .boot_params = 0x10000100,
+ .map_io = omap_nokia770_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_nokia770_init_irq,
+ .init_machine = omap_nokia770_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
new file mode 100644
index 00000000..e68dfde1
--- /dev/null
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -0,0 +1,592 @@
+/*
+ * linux/arch/arm/mach-omap1/board-osk.c
+ *
+ * Board specific init for OMAP5912 OSK
+ *
+ * Written by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/smc91x.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <mach/hardware.h>
+#include <asm/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/flash.h>
+#include <plat/usb.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/common.h>
+
+/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */
+#define OMAP_OSK_ETHR_START 0x04800300
+
+/* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with
+ * alternate pin configurations for hardware-controlled blinking.
+ */
+#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0)
+# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1)
+# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2)
+# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3)
+# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4)
+# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5)
+
+static struct mtd_partition osk_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data osk_flash_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = osk_partitions,
+ .nr_parts = ARRAY_SIZE(osk_partitions),
+};
+
+static struct resource osk_flash_resource = {
+ /* this is on CS3, wherever it's mapped */
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device osk5912_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &osk_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &osk_flash_resource,
+};
+
+static struct smc91x_platdata osk5912_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource osk5912_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP_OSK_ETHR_START, /* Physical */
+ .end = OMAP_OSK_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(0),
+ .end = OMAP_GPIO_IRQ(0),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device osk5912_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .platform_data = &osk5912_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(osk5912_smc91x_resources),
+ .resource = osk5912_smc91x_resources,
+};
+
+static struct resource osk5912_cf_resources[] = {
+ [0] = {
+ .start = OMAP_GPIO_IRQ(62),
+ .end = OMAP_GPIO_IRQ(62),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device osk5912_cf_device = {
+ .name = "omap_cf",
+ .id = -1,
+ .dev = {
+ .platform_data = (void *) 2 /* CS2 */,
+ },
+ .num_resources = ARRAY_SIZE(osk5912_cf_resources),
+ .resource = osk5912_cf_resources,
+};
+
+static struct platform_device *osk5912_devices[] __initdata = {
+ &osk5912_flash_device,
+ &osk5912_smc91x_device,
+ &osk5912_cf_device,
+};
+
+static struct gpio_led tps_leds[] = {
+ /* NOTE: D9 and D2 have hardware blink support.
+ * Also, D9 requires non-battery power.
+ */
+ { .gpio = OSK_TPS_GPIO_LED_D9, .name = "d9",
+ .default_trigger = "ide-disk", },
+ { .gpio = OSK_TPS_GPIO_LED_D2, .name = "d2", },
+ { .gpio = OSK_TPS_GPIO_LED_D3, .name = "d3", .active_low = 1,
+ .default_trigger = "heartbeat", },
+};
+
+static struct gpio_led_platform_data tps_leds_data = {
+ .num_leds = 3,
+ .leds = tps_leds,
+};
+
+static struct platform_device osk5912_tps_leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev.platform_data = &tps_leds_data,
+};
+
+static int osk_tps_setup(struct i2c_client *client, void *context)
+{
+ /* Set GPIO 1 HIGH to disable VBUS power supply;
+ * OHCI driver powers it up/down as needed.
+ */
+ gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en");
+ gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1);
+
+ /* Set GPIO 2 high so LED D3 is off by default */
+ tps65010_set_gpio_out_value(GPIO2, HIGH);
+
+ /* Set GPIO 3 low to take ethernet out of reset */
+ gpio_request(OSK_TPS_GPIO_LAN_RESET, "smc_reset");
+ gpio_direction_output(OSK_TPS_GPIO_LAN_RESET, 0);
+
+ /* GPIO4 is VDD_DSP */
+ gpio_request(OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power");
+ gpio_direction_output(OSK_TPS_GPIO_DSP_PWR_EN, 1);
+ /* REVISIT if DSP support isn't configured, power it off ... */
+
+ /* Let LED1 (D9) blink; leds-gpio may override it */
+ tps65010_set_led(LED1, BLINK);
+
+ /* Set LED2 off by default */
+ tps65010_set_led(LED2, OFF);
+
+ /* Enable LOW_PWR handshake */
+ tps65010_set_low_pwr(ON);
+
+ /* Switch VLDO2 to 3.0V for AIC23 */
+ tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V
+ | TPS_LDO1_ENABLE);
+
+ /* register these three LEDs */
+ osk5912_tps_leds.dev.parent = &client->dev;
+ platform_device_register(&osk5912_tps_leds);
+
+ return 0;
+}
+
+static struct tps65010_board tps_board = {
+ .base = OSK_TPS_GPIO_BASE,
+ .outmask = 0x0f,
+ .setup = osk_tps_setup,
+};
+
+static struct i2c_board_info __initdata osk_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65010", 0x48),
+ .irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)),
+ .platform_data = &tps_board,
+
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1B),
+ },
+ /* TODO when driver support is ready:
+ * - optionally on Mistral, ov9640 camera sensor at 0x30
+ */
+};
+
+static void __init osk_init_smc91x(void)
+{
+ u32 l;
+
+ if ((gpio_request(0, "smc_irq")) < 0) {
+ printk("Error requesting gpio 0 for smc91x irq\n");
+ return;
+ }
+
+ /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */
+ l = omap_readl(EMIFS_CCS(1));
+ l |= 0x3;
+ omap_writel(l, EMIFS_CCS(1));
+}
+
+static void __init osk_init_cf(void)
+{
+ omap_cfg_reg(M7_1610_GPIO62);
+ if ((gpio_request(62, "cf_irq")) < 0) {
+ printk("Error requesting gpio 62 for CF irq\n");
+ return;
+ }
+ /* the CF I/O IRQ is really active-low */
+ irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING);
+}
+
+static void __init osk_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static struct omap_usb_config osk_usb_config __initdata = {
+ /* has usb host connector (A) ... for development it can also
+ * be used, with a NONSTANDARD gender-bending cable/dongle, as
+ * a peripheral.
+ */
+#ifdef CONFIG_USB_GADGET_OMAP
+ .register_dev = 1,
+ .hmc_mode = 0,
+#else
+ .register_host = 1,
+ .hmc_mode = 16,
+ .rwc = 1,
+#endif
+ .pins[0] = 2,
+};
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+static struct omap_lcd_config osk_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+#endif
+
+static struct omap_board_config_kernel osk_config[] __initdata = {
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+ { OMAP_TAG_LCD, &osk_lcd_config },
+#endif
+};
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+#include <linux/input.h>
+#include <linux/i2c/at24.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <plat/keypad.h>
+
+static struct at24_platform_data at24c04 = {
+ .byte_len = SZ_4K / 8,
+ .page_size = 16,
+};
+
+static struct i2c_board_info __initdata mistral_i2c_board_info[] = {
+ {
+ /* NOTE: powered from LCD supply */
+ I2C_BOARD_INFO("24c04", 0x50),
+ .platform_data = &at24c04,
+ },
+ /* TODO when driver support is ready:
+ * - optionally ov9640 camera sensor at 0x30
+ */
+};
+
+static const unsigned int osk_keymap[] = {
+ /* KEY(col, row, code) */
+ KEY(0, 0, KEY_F1), /* SW4 */
+ KEY(3, 0, KEY_UP), /* (sw2/up) */
+ KEY(1, 1, KEY_LEFTCTRL), /* SW5 */
+ KEY(2, 1, KEY_LEFT), /* (sw2/left) */
+ KEY(0, 2, KEY_SPACE), /* SW3 */
+ KEY(1, 2, KEY_ESC), /* SW6 */
+ KEY(2, 2, KEY_DOWN), /* (sw2/down) */
+ KEY(2, 3, KEY_ENTER), /* (sw2/select) */
+ KEY(3, 3, KEY_RIGHT), /* (sw2/right) */
+};
+
+static const struct matrix_keymap_data osk_keymap_data = {
+ .keymap = osk_keymap,
+ .keymap_size = ARRAY_SIZE(osk_keymap),
+};
+
+static struct omap_kp_platform_data osk_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &osk_keymap_data,
+ .delay = 9,
+};
+
+static struct resource osk5912_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device osk5912_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &osk_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(osk5912_kp_resources),
+ .resource = osk5912_kp_resources,
+};
+
+static struct omap_backlight_config mistral_bl_data = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device mistral_bl_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &mistral_bl_data,
+ },
+};
+
+static struct platform_device osk5912_lcd_device = {
+ .name = "lcd_osk",
+ .id = -1,
+};
+
+static struct platform_device *mistral_devices[] __initdata = {
+ &osk5912_kp_device,
+ &mistral_bl_device,
+ &osk5912_lcd_device,
+};
+
+static int mistral_get_pendown_state(void)
+{
+ return !gpio_get_value(4);
+}
+
+static const struct ads7846_platform_data mistral_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = mistral_get_pendown_state,
+};
+
+static struct spi_board_info __initdata mistral_boardinfo[] = { {
+ /* MicroWire (bus 2) CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &mistral_ts_info,
+ .irq = OMAP_GPIO_IRQ(4),
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+} };
+
+#ifdef CONFIG_PM
+static irqreturn_t
+osk_mistral_wake_interrupt(int irq, void *ignored)
+{
+ return IRQ_HANDLED;
+}
+#endif
+
+static void __init osk_mistral_init(void)
+{
+ /* NOTE: we could actually tell if there's a Mistral board
+ * attached, e.g. by trying to read something from the ads7846.
+ * But this arch_init() code is too early for that, since we
+ * can't talk to the ads or even the i2c eeprom.
+ */
+
+ /* parallel camera interface */
+ omap_cfg_reg(J15_1610_CAM_LCLK);
+ omap_cfg_reg(J18_1610_CAM_D7);
+ omap_cfg_reg(J19_1610_CAM_D6);
+ omap_cfg_reg(J14_1610_CAM_D5);
+ omap_cfg_reg(K18_1610_CAM_D4);
+ omap_cfg_reg(K19_1610_CAM_D3);
+ omap_cfg_reg(K15_1610_CAM_D2);
+ omap_cfg_reg(K14_1610_CAM_D1);
+ omap_cfg_reg(L19_1610_CAM_D0);
+ omap_cfg_reg(L18_1610_CAM_VS);
+ omap_cfg_reg(L15_1610_CAM_HS);
+ omap_cfg_reg(M19_1610_CAM_RSTZ);
+ omap_cfg_reg(Y15_1610_CAM_OUTCLK);
+
+ /* serial camera interface */
+ omap_cfg_reg(H19_1610_CAM_EXCLK);
+ omap_cfg_reg(W13_1610_CCP_CLKM);
+ omap_cfg_reg(Y12_1610_CCP_CLKP);
+ /* CCP_DATAM CONFLICTS WITH UART1.TX (and serial console) */
+ /* omap_cfg_reg(Y14_1610_CCP_DATAM); */
+ omap_cfg_reg(W14_1610_CCP_DATAP);
+
+ /* CAM_PWDN */
+ if (gpio_request(11, "cam_pwdn") == 0) {
+ omap_cfg_reg(N20_1610_GPIO11);
+ gpio_direction_output(11, 0);
+ } else
+ pr_debug("OSK+Mistral: CAM_PWDN is awol\n");
+
+
+ /* omap_cfg_reg(P19_1610_GPIO6); */ /* BUSY */
+ gpio_request(6, "ts_busy");
+ gpio_direction_input(6);
+
+ omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */
+ gpio_request(4, "ts_int");
+ gpio_direction_input(4);
+ irq_set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING);
+
+ spi_register_board_info(mistral_boardinfo,
+ ARRAY_SIZE(mistral_boardinfo));
+
+ /* the sideways button (SW1) is for use as a "wakeup" button
+ *
+ * NOTE: The Mistral board has the wakeup button (SW1) wired
+ * to the LCD 3.3V rail, which is powered down during suspend.
+ * To allow this button to wake up the omap, work around this
+ * HW bug by rewiring SW1 to use the main 3.3V rail.
+ */
+ omap_cfg_reg(N15_1610_MPUIO2);
+ if (gpio_request(OMAP_MPUIO(2), "wakeup") == 0) {
+ int ret = 0;
+ int irq = gpio_to_irq(OMAP_MPUIO(2));
+
+ gpio_direction_input(OMAP_MPUIO(2));
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+#ifdef CONFIG_PM
+ /* share the IRQ in case someone wants to use the
+ * button for more than wakeup from system sleep.
+ */
+ ret = request_irq(irq,
+ &osk_mistral_wake_interrupt,
+ IRQF_SHARED, "mistral_wakeup",
+ &osk_mistral_wake_interrupt);
+ if (ret != 0) {
+ gpio_free(OMAP_MPUIO(2));
+ printk(KERN_ERR "OSK+Mistral: no wakeup irq, %d?\n",
+ ret);
+ } else
+ enable_irq_wake(irq);
+#endif
+ } else
+ printk(KERN_ERR "OSK+Mistral: wakeup button is awol\n");
+
+ /* LCD: backlight, and power; power controls other devices on the
+ * board, like the touchscreen, EEPROM, and wakeup (!) switch.
+ */
+ omap_cfg_reg(PWL);
+ if (gpio_request(2, "lcd_pwr") == 0)
+ gpio_direction_output(2, 1);
+
+ i2c_register_board_info(1, mistral_i2c_board_info,
+ ARRAY_SIZE(mistral_i2c_board_info));
+
+ platform_add_devices(mistral_devices, ARRAY_SIZE(mistral_devices));
+}
+#else
+static void __init osk_mistral_init(void) { }
+#endif
+
+#define EMIFS_CS3_VAL (0x88013141)
+
+static void __init osk_init(void)
+{
+ u32 l;
+
+ osk_init_smc91x();
+ osk_init_cf();
+
+ /* Workaround for wrong CS3 (NOR flash) timing
+ * There are some U-Boot versions out there which configure
+ * wrong CS3 memory timings. This mainly leads to CRC
+ * or similar errors if you use NOR flash (e.g. with JFFS2)
+ */
+ l = omap_readl(EMIFS_CCS(3));
+ if (l != EMIFS_CS3_VAL)
+ omap_writel(EMIFS_CS3_VAL, EMIFS_CCS(3));
+
+ osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys();
+ osk_flash_resource.end += SZ_32M - 1;
+ platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices));
+ omap_board_config = osk_config;
+ omap_board_config_size = ARRAY_SIZE(osk_config);
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= (3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+
+ omap1_usb_init(&osk_usb_config);
+
+ /* irq for tps65010 chip */
+ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
+ if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0)
+ gpio_direction_input(OMAP_MPUIO(1));
+
+ omap_serial_init();
+ omap_register_i2c_bus(1, 400, osk_i2c_board_info,
+ ARRAY_SIZE(osk_i2c_board_info));
+ osk_mistral_init();
+}
+
+static void __init osk_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_OSK, "TI-OSK")
+ /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */
+ .boot_params = 0x10000100,
+ .map_io = osk_map_io,
+ .reserve = omap_reserve,
+ .init_irq = osk_init_irq,
+ .init_machine = osk_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
new file mode 100644
index 00000000..c9d38f47
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmte.c
+ *
+ * Modified from board-generic.c
+ *
+ * Support for the Palm Tungsten E PDA.
+ *
+ * Original version : Laurent Gonzalez
+ *
+ * Maintainers : http://palmtelinux.sf.net
+ * palmtelinux-developpers@lists.sf.net
+ *
+ * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
+ *
+ * This program is free software; you can 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/input.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/apm-emulation.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/flash.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/tc.h>
+#include <plat/dma.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+
+#define PALMTE_USBDETECT_GPIO 0
+#define PALMTE_USB_OR_DC_GPIO 1
+#define PALMTE_TSC_GPIO 4
+#define PALMTE_PINTDAV_GPIO 6
+#define PALMTE_MMC_WP_GPIO 8
+#define PALMTE_MMC_POWER_GPIO 9
+#define PALMTE_HDQ_GPIO 11
+#define PALMTE_HEADPHONES_GPIO 14
+#define PALMTE_SPEAKER_GPIO 15
+#define PALMTE_DC_GPIO OMAP_MPUIO(2)
+#define PALMTE_MMC_SWITCH_GPIO OMAP_MPUIO(4)
+#define PALMTE_MMC1_GPIO OMAP_MPUIO(6)
+#define PALMTE_MMC2_GPIO OMAP_MPUIO(7)
+#define PALMTE_MMC3_GPIO OMAP_MPUIO(11)
+
+static void __init omap_palmte_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static const unsigned int palmte_keymap[] = {
+ KEY(0, 0, KEY_F1), /* Calendar */
+ KEY(1, 0, KEY_F2), /* Contacts */
+ KEY(2, 0, KEY_F3), /* Tasks List */
+ KEY(3, 0, KEY_F4), /* Note Pad */
+ KEY(4, 0, KEY_POWER),
+ KEY(0, 1, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(4, 1, KEY_ENTER),
+};
+
+static const struct matrix_keymap_data palmte_keymap_data = {
+ .keymap = palmte_keymap,
+ .keymap_size = ARRAY_SIZE(palmte_keymap),
+};
+
+static struct omap_kp_platform_data palmte_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &palmte_keymap_data,
+ .rep = true,
+ .delay = 12,
+};
+
+static struct resource palmte_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmte_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmte_kp_resources),
+ .resource = palmte_kp_resources,
+};
+
+static struct mtd_partition palmte_rom_partitions[] = {
+ /* PalmOS "Small ROM", contains the bootloader and the debugger */
+ {
+ .name = "smallrom",
+ .offset = 0,
+ .size = 0xa000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ /* PalmOS "Big ROM", a filesystem with all the OS code and data */
+ {
+ .name = "bigrom",
+ .offset = SZ_128K,
+ /*
+ * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
+ * 0x7b0000 bytes in the English-only ("enUS") version.
+ */
+ .size = 0x7b0000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data palmte_rom_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = palmte_rom_partitions,
+ .nr_parts = ARRAY_SIZE(palmte_rom_partitions),
+};
+
+static struct resource palmte_rom_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmte_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_rom_data,
+ },
+ .num_resources = 1,
+ .resource = &palmte_rom_resource,
+};
+
+static struct platform_device palmte_lcd_device = {
+ .name = "lcd_palmte",
+ .id = -1,
+};
+
+static struct omap_backlight_config palmte_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmte_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_backlight_config,
+ },
+};
+
+static struct omap_irda_config palmte_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmte_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmte_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmte_irda_resources),
+ .resource = palmte_irda_resources,
+};
+
+static struct platform_device *palmte_devices[] __initdata = {
+ &palmte_rom_device,
+ &palmte_kp_device,
+ &palmte_lcd_device,
+ &palmte_backlight_device,
+ &palmte_irda_device,
+};
+
+static struct omap_usb_config palmte_usb_config __initdata = {
+ .register_dev = 1, /* Mini-B only receptacle */
+ .hmc_mode = 0,
+ .pins[0] = 2,
+};
+
+static struct omap_lcd_config palmte_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel palmte_config[] __initdata = {
+ { OMAP_TAG_LCD, &palmte_lcd_config },
+};
+
+static struct spi_board_info palmte_spi_info[] __initdata = {
+ {
+ .modalias = "tsc2102",
+ .bus_num = 2, /* uWire (officially) */
+ .chip_select = 0, /* As opposed to 3 */
+ .irq = OMAP_GPIO_IRQ(PALMTE_PINTDAV_GPIO),
+ .max_speed_hz = 8000000,
+ },
+};
+
+static void __init palmte_misc_gpio_setup(void)
+{
+ /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */
+ if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) {
+ printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n");
+ return;
+ }
+ gpio_direction_input(PALMTE_PINTDAV_GPIO);
+
+ /* Set USB-or-DC-IN pin as input (unused) */
+ if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) {
+ printk(KERN_ERR "Could not reserve cable signal GPIO!\n");
+ return;
+ }
+ gpio_direction_input(PALMTE_USB_OR_DC_GPIO);
+}
+
+static void __init omap_palmte_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ omap_board_config = palmte_config;
+ omap_board_config_size = ARRAY_SIZE(palmte_config);
+
+ platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices));
+
+ spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
+ palmte_misc_gpio_setup();
+ omap_serial_init();
+ omap1_usb_init(&palmte_usb_config);
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+static void __init omap_palmte_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
+ .boot_params = 0x10000100,
+ .map_io = omap_palmte_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_palmte_init_irq,
+ .init_machine = omap_palmte_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
new file mode 100644
index 00000000..f04f2d36
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -0,0 +1,330 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmtt.c
+ *
+ * Modified from board-palmtt2.c
+ *
+ * Modified and amended for Palm Tungsten|T
+ * by Marek Vasut <marek.vasut@gmail.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/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/leds.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/led.h>
+#include <mach/gpio.h>
+#include <plat/flash.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#define PALMTT_USBDETECT_GPIO 0
+#define PALMTT_CABLE_GPIO 1
+#define PALMTT_LED_GPIO 3
+#define PALMTT_PENIRQ_GPIO 6
+#define PALMTT_MMC_WP_GPIO 8
+#define PALMTT_HDQ_GPIO 11
+
+static const unsigned int palmtt_keymap[] = {
+ KEY(0, 0, KEY_ESC),
+ KEY(1, 0, KEY_SPACE),
+ KEY(2, 0, KEY_LEFTCTRL),
+ KEY(3, 0, KEY_TAB),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_SLEEP),
+ KEY(4, 2, KEY_Y),
+};
+
+static struct mtd_partition palmtt_partitions[] = {
+ {
+ .name = "write8k",
+ .offset = 0,
+ .size = SZ_8K,
+ .mask_flags = 0,
+ },
+ {
+ .name = "PalmOS-BootLoader(ro)",
+ .offset = SZ_8K,
+ .size = 7 * SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * SZ_8K,
+ .mask_flags = 0,
+ },
+ {
+ .name = "PalmOS-FS(ro)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 7 * SZ_1M + 4 * SZ_64K - 16 * SZ_8K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "u-boot(rez)",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0
+ },
+ {
+ .name = "empty",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data palmtt_flash_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = palmtt_partitions,
+ .nr_parts = ARRAY_SIZE(palmtt_partitions),
+};
+
+static struct resource palmtt_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmtt_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &palmtt_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &palmtt_flash_resource,
+};
+
+static struct resource palmtt_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data palmtt_keymap_data = {
+ .keymap = palmtt_keymap,
+ .keymap_size = ARRAY_SIZE(palmtt_keymap),
+};
+
+static struct omap_kp_platform_data palmtt_kp_data = {
+ .rows = 6,
+ .cols = 3,
+ .keymap_data = &palmtt_keymap_data,
+};
+
+static struct platform_device palmtt_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmtt_kp_resources),
+ .resource = palmtt_kp_resources,
+};
+
+static struct platform_device palmtt_lcd_device = {
+ .name = "lcd_palmtt",
+ .id = -1,
+};
+static struct omap_irda_config palmtt_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmtt_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmtt_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmtt_irda_resources),
+ .resource = palmtt_irda_resources,
+};
+
+static struct platform_device palmtt_spi_device = {
+ .name = "spi_palmtt",
+ .id = -1,
+};
+
+static struct omap_backlight_config palmtt_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmtt_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data= &palmtt_backlight_config,
+ },
+};
+
+static struct omap_led_config palmtt_led_config[] = {
+ {
+ .cdev = {
+ .name = "palmtt:led0",
+ },
+ .gpio = PALMTT_LED_GPIO,
+ },
+};
+
+static struct omap_led_platform_data palmtt_led_data = {
+ .nr_leds = ARRAY_SIZE(palmtt_led_config),
+ .leds = palmtt_led_config,
+};
+
+static struct platform_device palmtt_led_device = {
+ .name = "omap-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtt_led_data,
+ },
+};
+
+static struct platform_device *palmtt_devices[] __initdata = {
+ &palmtt_flash_device,
+ &palmtt_kp_device,
+ &palmtt_lcd_device,
+ &palmtt_irda_device,
+ &palmtt_spi_device,
+ &palmtt_backlight_device,
+ &palmtt_led_device,
+};
+
+static int palmtt_get_pendown_state(void)
+{
+ return !gpio_get_value(6);
+}
+
+static const struct ads7846_platform_data palmtt_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = palmtt_get_pendown_state,
+};
+
+static struct spi_board_info __initdata palmtt_boardinfo[] = {
+ {
+ /* MicroWire (bus 2) CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &palmtt_ts_info,
+ .irq = OMAP_GPIO_IRQ(6),
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+ }
+};
+
+static void __init omap_palmtt_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static struct omap_usb_config palmtt_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0,
+ .pins[0] = 2,
+};
+
+static struct omap_lcd_config palmtt_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel palmtt_config[] __initdata = {
+ { OMAP_TAG_LCD, &palmtt_lcd_config },
+};
+
+static void __init omap_mpu_wdt_mode(int mode) {
+ if (mode)
+ omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
+ else {
+ omap_writew(0x00f5, OMAP_WDT_TIMER_MODE);
+ omap_writew(0x00a0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+static void __init omap_palmtt_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ omap_mpu_wdt_mode(0);
+
+ omap_board_config = palmtt_config;
+ omap_board_config_size = ARRAY_SIZE(palmtt_config);
+
+ platform_add_devices(palmtt_devices, ARRAY_SIZE(palmtt_devices));
+
+ spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
+ omap_serial_init();
+ omap1_usb_init(&palmtt_usb_config);
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+static void __init omap_palmtt_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
+ .boot_params = 0x10000100,
+ .map_io = omap_palmtt_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_palmtt_init_irq,
+ .init_machine = omap_palmtt_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
new file mode 100644
index 00000000..45f01d2c
--- /dev/null
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -0,0 +1,350 @@
+/*
+ * linux/arch/arm/mach-omap1/board-palmz71.c
+ *
+ * Modified from board-generic.c
+ *
+ * Support for the Palm Zire71 PDA.
+ *
+ * Original version : Laurent Gonzalez
+ *
+ * Modified for zire71 : Marek Vasut
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/flash.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/irda.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/omap-alsa.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#define PALMZ71_USBDETECT_GPIO 0
+#define PALMZ71_PENIRQ_GPIO 6
+#define PALMZ71_MMC_WP_GPIO 8
+#define PALMZ71_HDQ_GPIO 11
+
+#define PALMZ71_HOTSYNC_GPIO OMAP_MPUIO(1)
+#define PALMZ71_CABLE_GPIO OMAP_MPUIO(2)
+#define PALMZ71_SLIDER_GPIO OMAP_MPUIO(3)
+#define PALMZ71_MMC_IN_GPIO OMAP_MPUIO(4)
+
+static void __init
+omap_palmz71_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static const unsigned int palmz71_keymap[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(1, 0, KEY_F2),
+ KEY(2, 0, KEY_F3),
+ KEY(3, 0, KEY_F4),
+ KEY(4, 0, KEY_POWER),
+ KEY(0, 1, KEY_LEFT),
+ KEY(1, 1, KEY_DOWN),
+ KEY(2, 1, KEY_UP),
+ KEY(3, 1, KEY_RIGHT),
+ KEY(4, 1, KEY_ENTER),
+ KEY(0, 2, KEY_CAMERA),
+};
+
+static const struct matrix_keymap_data palmz71_keymap_data = {
+ .keymap = palmz71_keymap,
+ .keymap_size = ARRAY_SIZE(palmz71_keymap),
+};
+
+static struct omap_kp_platform_data palmz71_kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &palmz71_keymap_data,
+ .rep = true,
+ .delay = 80,
+};
+
+static struct resource palmz71_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmz71_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(palmz71_kp_resources),
+ .resource = palmz71_kp_resources,
+};
+
+static struct mtd_partition palmz71_rom_partitions[] = {
+ /* PalmOS "Small ROM", contains the bootloader and the debugger */
+ {
+ .name = "smallrom",
+ .offset = 0,
+ .size = 0xa000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ /* PalmOS "Big ROM", a filesystem with all the OS code and data */
+ {
+ .name = "bigrom",
+ .offset = SZ_128K,
+ /*
+ * 0x5f0000 bytes big in the multi-language ("EFIGS") version,
+ * 0x7b0000 bytes in the English-only ("enUS") version.
+ */
+ .size = 0x7b0000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data palmz71_rom_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = palmz71_rom_partitions,
+ .nr_parts = ARRAY_SIZE(palmz71_rom_partitions),
+};
+
+static struct resource palmz71_rom_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmz71_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_rom_data,
+ },
+ .num_resources = 1,
+ .resource = &palmz71_rom_resource,
+};
+
+static struct platform_device palmz71_lcd_device = {
+ .name = "lcd_palmz71",
+ .id = -1,
+};
+
+static struct omap_irda_config palmz71_irda_config = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource palmz71_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device palmz71_irda_device = {
+ .name = "omapirda",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_irda_config,
+ },
+ .num_resources = ARRAY_SIZE(palmz71_irda_resources),
+ .resource = palmz71_irda_resources,
+};
+
+static struct platform_device palmz71_spi_device = {
+ .name = "spi_palmz71",
+ .id = -1,
+};
+
+static struct omap_backlight_config palmz71_backlight_config = {
+ .default_intensity = 0xa0,
+};
+
+static struct platform_device palmz71_backlight_device = {
+ .name = "omap-bl",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz71_backlight_config,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &palmz71_rom_device,
+ &palmz71_kp_device,
+ &palmz71_lcd_device,
+ &palmz71_irda_device,
+ &palmz71_spi_device,
+ &palmz71_backlight_device,
+};
+
+static int
+palmz71_get_pendown_state(void)
+{
+ return !gpio_get_value(PALMZ71_PENIRQ_GPIO);
+}
+
+static const struct ads7846_platform_data palmz71_ts_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .get_pendown_state = palmz71_get_pendown_state,
+};
+
+static struct spi_board_info __initdata palmz71_boardinfo[] = { {
+ /* MicroWire (bus 2) CS0 has an ads7846e */
+ .modalias = "ads7846",
+ .platform_data = &palmz71_ts_info,
+ .irq = OMAP_GPIO_IRQ(PALMZ71_PENIRQ_GPIO),
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 2,
+ .chip_select = 0,
+} };
+
+static struct omap_usb_config palmz71_usb_config __initdata = {
+ .register_dev = 1, /* Mini-B only receptacle */
+ .hmc_mode = 0,
+ .pins[0] = 2,
+};
+
+static struct omap_lcd_config palmz71_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel palmz71_config[] __initdata = {
+ {OMAP_TAG_LCD, &palmz71_lcd_config},
+};
+
+static irqreturn_t
+palmz71_powercable(int irq, void *dev_id)
+{
+ if (gpio_get_value(PALMZ71_USBDETECT_GPIO)) {
+ printk(KERN_INFO "PM: Power cable connected\n");
+ irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
+ IRQ_TYPE_EDGE_FALLING);
+ } else {
+ printk(KERN_INFO "PM: Power cable disconnected\n");
+ irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
+ IRQ_TYPE_EDGE_RISING);
+ }
+ return IRQ_HANDLED;
+}
+
+static void __init
+omap_mpu_wdt_mode(int mode)
+{
+ if (mode)
+ omap_writew(0x8000, OMAP_WDT_TIMER_MODE);
+ else {
+ omap_writew(0x00f5, OMAP_WDT_TIMER_MODE);
+ omap_writew(0x00a0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+static void __init
+palmz71_gpio_setup(int early)
+{
+ if (early) {
+ /* Only set GPIO1 so we have a working serial */
+ gpio_direction_output(1, 1);
+ } else {
+ /* Set MMC/SD host WP pin as input */
+ if (gpio_request(PALMZ71_MMC_WP_GPIO, "MMC WP") < 0) {
+ printk(KERN_ERR "Could not reserve WP GPIO!\n");
+ return;
+ }
+ gpio_direction_input(PALMZ71_MMC_WP_GPIO);
+
+ /* Monitor the Power-cable-connected signal */
+ if (gpio_request(PALMZ71_USBDETECT_GPIO, "USB detect") < 0) {
+ printk(KERN_ERR
+ "Could not reserve cable signal GPIO!\n");
+ return;
+ }
+ gpio_direction_input(PALMZ71_USBDETECT_GPIO);
+ if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
+ palmz71_powercable, IRQF_SAMPLE_RANDOM,
+ "palmz71-cable", 0))
+ printk(KERN_ERR
+ "IRQ request for power cable failed!\n");
+ palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), 0);
+ }
+}
+
+static void __init
+omap_palmz71_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ palmz71_gpio_setup(1);
+ omap_mpu_wdt_mode(0);
+
+ omap_board_config = palmz71_config;
+ omap_board_config_size = ARRAY_SIZE(palmz71_config);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ spi_register_board_info(palmz71_boardinfo,
+ ARRAY_SIZE(palmz71_boardinfo));
+ omap1_usb_init(&palmz71_usb_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ palmz71_gpio_setup(0);
+}
+
+static void __init
+omap_palmz71_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
+ .boot_params = 0x10000100,
+ .map_io = omap_palmz71_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_palmz71_init_irq,
+ .init_machine = omap_palmz71_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
new file mode 100644
index 00000000..3c8ee848
--- /dev/null
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -0,0 +1,359 @@
+/*
+ * linux/arch/arm/mach-omap1/board-perseus2.c
+ *
+ * Modified from board-generic.c
+ *
+ * Original OMAP730 support by Jean Pihet <j-pihet@ti.com>
+ * Updated for 2.6 by Kevin Hilman <kjh@hilman.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/tc.h>
+#include <mach/gpio.h>
+#include <plat/mux.h>
+#include <plat/fpga.h>
+#include <plat/flash.h>
+#include <plat/keypad.h>
+#include <plat/common.h>
+#include <plat/board.h>
+
+static const unsigned int p2_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_LEFT),
+ KEY(3, 0, KEY_DOWN),
+ KEY(4, 0, KEY_ENTER),
+ KEY(0, 1, KEY_F10),
+ KEY(1, 1, KEY_SEND),
+ KEY(2, 1, KEY_END),
+ KEY(3, 1, KEY_VOLUMEDOWN),
+ KEY(4, 1, KEY_VOLUMEUP),
+ KEY(5, 1, KEY_RECORD),
+ KEY(0, 2, KEY_F9),
+ KEY(1, 2, KEY_3),
+ KEY(2, 2, KEY_6),
+ KEY(3, 2, KEY_9),
+ KEY(4, 2, KEY_KPDOT),
+ KEY(0, 3, KEY_BACK),
+ KEY(1, 3, KEY_2),
+ KEY(2, 3, KEY_5),
+ KEY(3, 3, KEY_8),
+ KEY(4, 3, KEY_0),
+ KEY(5, 3, KEY_KPSLASH),
+ KEY(0, 4, KEY_HOME),
+ KEY(1, 4, KEY_1),
+ KEY(2, 4, KEY_4),
+ KEY(3, 4, KEY_7),
+ KEY(4, 4, KEY_KPASTERISK),
+ KEY(5, 4, KEY_POWER),
+};
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = H2P2_DBG_FPGA_ETHR_START, /* Physical */
+ .end = H2P2_DBG_FPGA_ETHR_START + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_7XX_MPU_EXT_NIRQ,
+ .end = 0,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct mtd_partition nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* rest of flash is a file system */
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ },
+};
+
+static struct physmap_flash_data nor_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = nor_partitions,
+ .nr_parts = ARRAY_SIZE(nor_partitions),
+};
+
+static struct resource nor_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nor_data,
+ },
+ .num_resources = 1,
+ .resource = &nor_resource,
+};
+
+static void nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long mask;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ mask = (ctrl & NAND_CLE) ? 0x02 : 0;
+ if (ctrl & NAND_ALE)
+ mask |= 0x04;
+ writeb(cmd, (unsigned long)this->IO_ADDR_W | mask);
+}
+
+#define P2_NAND_RB_GPIO_PIN 62
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+ return gpio_get_value(P2_NAND_RB_GPIO_PIN);
+}
+
+static const char *part_probes[] = { "cmdlinepart", NULL };
+
+static struct platform_nand_data nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .options = NAND_SAMSUNG_LP_OPTIONS,
+ .part_probe_types = part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = nand_cmd_ctl,
+ .dev_ready = nand_dev_ready,
+ },
+};
+
+static struct resource nand_resource = {
+ .start = OMAP_CS3_PHYS,
+ .end = OMAP_CS3_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device nand_device = {
+ .name = "gen_nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &nand_data,
+ },
+ .num_resources = 1,
+ .resource = &nand_resource,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource kp_resources[] = {
+ [0] = {
+ .start = INT_7XX_MPUIO_KEYPAD,
+ .end = INT_7XX_MPUIO_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data p2_keymap_data = {
+ .keymap = p2_keymap,
+ .keymap_size = ARRAY_SIZE(p2_keymap),
+};
+
+static struct omap_kp_platform_data kp_data = {
+ .rows = 8,
+ .cols = 8,
+ .keymap_data = &p2_keymap_data,
+ .delay = 4,
+ .dbounce = true,
+};
+
+static struct platform_device kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_data,
+ },
+ .num_resources = ARRAY_SIZE(kp_resources),
+ .resource = kp_resources,
+};
+
+static struct platform_device lcd_device = {
+ .name = "lcd_p2",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &nor_device,
+ &nand_device,
+ &smc91x_device,
+ &kp_device,
+ &lcd_device,
+};
+
+static struct omap_lcd_config perseus2_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel perseus2_config[] __initdata = {
+ { OMAP_TAG_LCD, &perseus2_lcd_config },
+};
+
+static void __init perseus2_init_smc91x(void)
+{
+ fpga_write(1, H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+ fpga_write(fpga_read(H2P2_DBG_FPGA_LAN_RESET) & ~1,
+ H2P2_DBG_FPGA_LAN_RESET);
+ mdelay(50);
+}
+
+static void __init omap_perseus2_init(void)
+{
+ perseus2_init_smc91x();
+
+ if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0)
+ BUG();
+ gpio_direction_input(P2_NAND_RB_GPIO_PIN);
+
+ omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
+ omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+
+ /* Mux pins for keypad */
+ omap_cfg_reg(E2_7XX_KBR0);
+ omap_cfg_reg(J7_7XX_KBR1);
+ omap_cfg_reg(E1_7XX_KBR2);
+ omap_cfg_reg(F3_7XX_KBR3);
+ omap_cfg_reg(D2_7XX_KBR4);
+ omap_cfg_reg(C2_7XX_KBC0);
+ omap_cfg_reg(D3_7XX_KBC1);
+ omap_cfg_reg(E4_7XX_KBC2);
+ omap_cfg_reg(F4_7XX_KBC3);
+ omap_cfg_reg(E3_7XX_KBC4);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ omap_board_config = perseus2_config;
+ omap_board_config_size = ARRAY_SIZE(perseus2_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+}
+
+static void __init omap_perseus2_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+/* Only FPGA needs to be mapped here. All others are done with ioremap */
+static struct map_desc omap_perseus2_io_desc[] __initdata = {
+ {
+ .virtual = H2P2_DBG_FPGA_BASE,
+ .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START),
+ .length = H2P2_DBG_FPGA_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init omap_perseus2_map_io(void)
+{
+ omap1_map_common_io();
+ iotable_init(omap_perseus2_io_desc,
+ ARRAY_SIZE(omap_perseus2_io_desc));
+
+ /* Early, board-dependent init */
+
+ /*
+ * Hold GSM Reset until needed
+ */
+ omap_writew(omap_readw(OMAP7XX_DSP_M_CTL) & ~1, OMAP7XX_DSP_M_CTL);
+
+ /*
+ * UARTs -> done automagically by 8250 driver
+ */
+
+ /*
+ * CSx timings, GPIO Mux ... setup
+ */
+
+ /* Flash: CS0 timings setup */
+ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_0);
+ omap_writel(0x00000088, OMAP7XX_FLASH_ACFG_0);
+
+ /*
+ * Ethernet support through the debug board
+ * CS1 timings setup
+ */
+ omap_writel(0x0000fff3, OMAP7XX_FLASH_CFG_1);
+ omap_writel(0x00000000, OMAP7XX_FLASH_ACFG_1);
+
+ /*
+ * Configure MPU_EXT_NIRQ IO in IO_CONF9 register,
+ * It is used as the Ethernet controller interrupt
+ */
+ omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9);
+}
+
+MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
+ /* Maintainer: Kevin Hilman <kjh@hilman.org> */
+ .boot_params = 0x10000100,
+ .map_io = omap_perseus2_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_perseus2_init_irq,
+ .init_machine = omap_perseus2_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c
new file mode 100644
index 00000000..e8ddd86e
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1-mmc.c
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-omap1/board-sx1-mmc.c
+ *
+ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
+ * Author: Carlos Eduardo Aguiar <carlos.aguiar@indt.org.br>
+ *
+ * This code is based on linux/arch/arm/mach-omap1/board-h2-mmc.c, which is:
+ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT
+ *
+ * This program is free software; you can 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/hardware.h>
+#include <plat/mmc.h>
+#include <mach/gpio.h>
+#include <plat/board-sx1.h>
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ int err;
+ u8 dat = 0;
+
+ err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+
+ if (power_on)
+ dat |= SOFIA_MMC_POWER;
+ else
+ dat &= ~SOFIA_MMC_POWER;
+
+ return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+
+/* Cover switch is at OMAP_MPUIO(3) */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 1,
+ .slots[0] = {
+ .set_power = mmc_set_power,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "mmcblk",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC];
+
+void __init sx1_mmc_init(void)
+{
+ mmc_data[0] = &mmc1_data;
+ omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
+}
+
+#else
+
+void __init sx1_mmc_init(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
new file mode 100644
index 00000000..0ad781db
--- /dev/null
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -0,0 +1,430 @@
+/*
+* linux/arch/arm/mach-omap1/board-sx1.c
+*
+* Modified from board-generic.c
+*
+* Support for the Siemens SX1 mobile phone.
+*
+* Original version : Vladimir Ananiev (Vovan888-at-gmail com)
+*
+* Maintainters : Vladimir Ananiev (aka Vovan888), Sergge
+* oslik.ru
+*
+* This program is free software; you can 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/input.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/errno.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/flash.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/irda.h>
+#include <plat/usb.h>
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/keypad.h>
+#include <plat/board-sx1.h>
+
+/* Write to I2C device */
+int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value)
+{
+ struct i2c_adapter *adap;
+ int err;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+
+ adap = i2c_get_adapter(0);
+ if (!adap)
+ return -ENODEV;
+ msg->addr = devaddr; /* I2C address of chip */
+ msg->flags = 0;
+ msg->len = 2;
+ msg->buf = data;
+ data[0] = regoffset; /* register num */
+ data[1] = value; /* register data */
+ err = i2c_transfer(adap, msg, 1);
+ i2c_put_adapter(adap);
+ if (err >= 0)
+ return 0;
+ return err;
+}
+
+/* Read from I2C device */
+int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value)
+{
+ struct i2c_adapter *adap;
+ int err;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+
+ adap = i2c_get_adapter(0);
+ if (!adap)
+ return -ENODEV;
+
+ msg->addr = devaddr; /* I2C address of chip */
+ msg->flags = 0;
+ msg->len = 1;
+ msg->buf = data;
+ data[0] = regoffset; /* register num */
+ err = i2c_transfer(adap, msg, 1);
+
+ msg->addr = devaddr; /* I2C address */
+ msg->flags = I2C_M_RD;
+ msg->len = 1;
+ msg->buf = data;
+ err = i2c_transfer(adap, msg, 1);
+ *value = data[0];
+ i2c_put_adapter(adap);
+
+ if (err >= 0)
+ return 0;
+ return err;
+}
+/* set keyboard backlight intensity */
+int sx1_setkeylight(u8 keylight)
+{
+ if (keylight > SOFIA_MAX_LIGHT_VAL)
+ keylight = SOFIA_MAX_LIGHT_VAL;
+ return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
+}
+/* get current keylight intensity */
+int sx1_getkeylight(u8 * keylight)
+{
+ return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_KEYLIGHT_REG, keylight);
+}
+/* set LCD backlight intensity */
+int sx1_setbacklight(u8 backlight)
+{
+ if (backlight > SOFIA_MAX_LIGHT_VAL)
+ backlight = SOFIA_MAX_LIGHT_VAL;
+ return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
+ backlight);
+}
+/* get current LCD backlight intensity */
+int sx1_getbacklight (u8 * backlight)
+{
+ return sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_BACKLIGHT_REG,
+ backlight);
+}
+/* set LCD backlight power on/off */
+int sx1_setmmipower(u8 onoff)
+{
+ int err;
+ u8 dat = 0;
+ err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+ if (onoff)
+ dat |= SOFIA_MMILIGHT_POWER;
+ else
+ dat &= ~SOFIA_MMILIGHT_POWER;
+ return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+
+/* set USB power on/off */
+int sx1_setusbpower(u8 onoff)
+{
+ int err;
+ u8 dat = 0;
+ err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
+ if (err < 0)
+ return err;
+ if (onoff)
+ dat |= SOFIA_USB_POWER;
+ else
+ dat &= ~SOFIA_USB_POWER;
+ return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
+}
+
+EXPORT_SYMBOL(sx1_setkeylight);
+EXPORT_SYMBOL(sx1_getkeylight);
+EXPORT_SYMBOL(sx1_setbacklight);
+EXPORT_SYMBOL(sx1_getbacklight);
+EXPORT_SYMBOL(sx1_setmmipower);
+EXPORT_SYMBOL(sx1_setusbpower);
+
+/*----------- Keypad -------------------------*/
+
+static const unsigned int sx1_keymap[] = {
+ KEY(3, 5, GROUP_0 | 117), /* camera Qt::Key_F17 */
+ KEY(4, 0, GROUP_0 | 114), /* voice memo Qt::Key_F14 */
+ KEY(4, 1, GROUP_2 | 114), /* voice memo */
+ KEY(4, 2, GROUP_3 | 114), /* voice memo */
+ KEY(0, 0, GROUP_1 | KEY_F12), /* red button Qt::Key_Hangup */
+ KEY(3, 4, GROUP_1 | KEY_LEFT),
+ KEY(3, 2, GROUP_1 | KEY_DOWN),
+ KEY(3, 1, GROUP_1 | KEY_RIGHT),
+ KEY(3, 0, GROUP_1 | KEY_UP),
+ KEY(3, 3, GROUP_1 | KEY_POWER), /* joystick press or Qt::Key_Select */
+ KEY(0, 5, GROUP_1 | KEY_1),
+ KEY(0, 4, GROUP_1 | KEY_2),
+ KEY(0, 3, GROUP_1 | KEY_3),
+ KEY(4, 3, GROUP_1 | KEY_4),
+ KEY(4, 4, GROUP_1 | KEY_5),
+ KEY(4, 5, GROUP_1 | KEY_KPASTERISK),/* "*" */
+ KEY(1, 4, GROUP_1 | KEY_6),
+ KEY(1, 5, GROUP_1 | KEY_7),
+ KEY(1, 3, GROUP_1 | KEY_8),
+ KEY(2, 3, GROUP_1 | KEY_9),
+ KEY(2, 5, GROUP_1 | KEY_0),
+ KEY(2, 4, GROUP_1 | 113), /* # F13 Toggle input method Qt::Key_F13 */
+ KEY(1, 0, GROUP_1 | KEY_F11), /* green button Qt::Key_Call */
+ KEY(2, 1, GROUP_1 | KEY_YEN), /* left soft Qt::Key_Context1 */
+ KEY(2, 2, GROUP_1 | KEY_F8), /* right soft Qt::Key_Back */
+ KEY(1, 2, GROUP_1 | KEY_LEFTSHIFT), /* shift */
+ KEY(1, 1, GROUP_1 | KEY_BACKSPACE), /* C (clear) */
+ KEY(2, 0, GROUP_1 | KEY_F7), /* menu Qt::Key_Menu */
+};
+
+static struct resource sx1_kp_resources[] = {
+ [0] = {
+ .start = INT_KEYBOARD,
+ .end = INT_KEYBOARD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct matrix_keymap_data sx1_keymap_data = {
+ .keymap = sx1_keymap,
+ .keymap_size = ARRAY_SIZE(sx1_keymap),
+};
+
+static struct omap_kp_platform_data sx1_kp_data = {
+ .rows = 6,
+ .cols = 6,
+ .keymap_data = &sx1_keymap_data,
+ .delay = 80,
+};
+
+static struct platform_device sx1_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &sx1_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(sx1_kp_resources),
+ .resource = sx1_kp_resources,
+};
+
+/*----------- IRDA -------------------------*/
+
+static struct omap_irda_config sx1_irda_data = {
+ .transceiver_cap = IR_SIRMODE,
+ .rx_channel = OMAP_DMA_UART3_RX,
+ .tx_channel = OMAP_DMA_UART3_TX,
+ .dest_start = UART3_THR,
+ .src_start = UART3_RHR,
+ .tx_trigger = 0,
+ .rx_trigger = 0,
+};
+
+static struct resource sx1_irda_resources[] = {
+ [0] = {
+ .start = INT_UART3,
+ .end = INT_UART3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 irda_dmamask = 0xffffffff;
+
+static struct platform_device sx1_irda_device = {
+ .name = "omapirda",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_irda_data,
+ .dma_mask = &irda_dmamask,
+ },
+ .num_resources = ARRAY_SIZE(sx1_irda_resources),
+ .resource = sx1_irda_resources,
+};
+
+/*----------- MTD -------------------------*/
+
+static struct mtd_partition sx1_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0x01800000,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M - 2 * SZ_128K,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data sx1_flash_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+ .parts = sx1_partitions,
+ .nr_parts = ARRAY_SIZE(sx1_partitions),
+};
+
+#ifdef CONFIG_SX1_OLD_FLASH
+/* MTD Intel StrataFlash - old flashes */
+static struct resource sx1_old_flash_resource[] = {
+ [0] = {
+ .start = OMAP_CS0_PHYS, /* Physical */
+ .end = OMAP_CS0_PHYS + SZ_16M - 1,,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_CS1_PHYS,
+ .end = OMAP_CS1_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sx1_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_flash_data,
+ },
+ .num_resources = 2,
+ .resource = &sx1_old_flash_resource,
+};
+#else
+/* MTD Intel 4000 flash - new flashes */
+static struct resource sx1_new_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device sx1_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sx1_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sx1_new_flash_resource,
+};
+#endif
+
+/*----------- USB -------------------------*/
+
+static struct omap_usb_config sx1_usb_config __initdata = {
+ .otg = 0,
+ .register_dev = 1,
+ .register_host = 0,
+ .hmc_mode = 0,
+ .pins[0] = 2,
+ .pins[1] = 0,
+ .pins[2] = 0,
+};
+
+/*----------- LCD -------------------------*/
+
+static struct platform_device sx1_lcd_device = {
+ .name = "lcd_sx1",
+ .id = -1,
+};
+
+static struct omap_lcd_config sx1_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+/*-----------------------------------------*/
+static struct platform_device *sx1_devices[] __initdata = {
+ &sx1_flash_device,
+ &sx1_kp_device,
+ &sx1_lcd_device,
+ &sx1_irda_device,
+};
+/*-----------------------------------------*/
+
+static struct omap_board_config_kernel sx1_config[] __initdata = {
+ { OMAP_TAG_LCD, &sx1_lcd_config },
+};
+
+/*-----------------------------------------*/
+
+static void __init omap_sx1_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ platform_add_devices(sx1_devices, ARRAY_SIZE(sx1_devices));
+
+ omap_board_config = sx1_config;
+ omap_board_config_size = ARRAY_SIZE(sx1_config);
+ omap_serial_init();
+ omap_register_i2c_bus(1, 100, NULL, 0);
+ omap1_usb_init(&sx1_usb_config);
+ sx1_mmc_init();
+
+ /* turn on USB power */
+ /* sx1_setusbpower(1); can't do it here because i2c is not ready */
+ gpio_request(1, "A_IRDA_OFF");
+ gpio_request(11, "A_SWITCH");
+ gpio_request(15, "A_USB_ON");
+ gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */
+ gpio_direction_output(11, 0); /*A_SWITCH = 0 */
+ gpio_direction_output(15, 0); /*A_USB_ON = 0 */
+}
+/*----------------------------------------*/
+static void __init omap_sx1_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+/*----------------------------------------*/
+
+static void __init omap_sx1_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+MACHINE_START(SX1, "OMAP310 based Siemens SX1")
+ .boot_params = 0x10000100,
+ .map_io = omap_sx1_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_sx1_init_irq,
+ .init_machine = omap_sx1_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
new file mode 100644
index 00000000..65d24204
--- /dev/null
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -0,0 +1,310 @@
+/*
+ * linux/arch/arm/mach-omap1/board-voiceblue.c
+ *
+ * Modified from board-generic.c
+ *
+ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
+ *
+ * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway).
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mtd/physmap.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board-voiceblue.h>
+#include <plat/common.h>
+#include <mach/gpio.h>
+#include <plat/flash.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+#include <plat/usb.h>
+
+static struct plat_serial8250_port voiceblue_ports[] = {
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000),
+ .irq = OMAP_GPIO_IRQ(12),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000),
+ .irq = OMAP_GPIO_IRQ(13),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000),
+ .irq = OMAP_GPIO_IRQ(14),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ {
+ .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000),
+ .irq = OMAP_GPIO_IRQ(15),
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = 3686400,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = voiceblue_ports,
+ },
+};
+
+static int __init ext_uart_init(void)
+{
+ if (!machine_is_voiceblue())
+ return -ENODEV;
+
+ return platform_device_register(&serial_device);
+}
+arch_initcall(ext_uart_init);
+
+static struct physmap_flash_data voiceblue_flash_data = {
+ .width = 2,
+ .set_vpp = omap1_set_vpp,
+};
+
+static struct resource voiceblue_flash_resource = {
+ .start = OMAP_CS0_PHYS,
+ .end = OMAP_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device voiceblue_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &voiceblue_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &voiceblue_flash_resource,
+};
+
+static struct smc91x_platdata voiceblue_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource voiceblue_smc91x_resources[] = {
+ [0] = {
+ .start = OMAP_CS2_PHYS + 0x300,
+ .end = OMAP_CS2_PHYS + 0x300 + 16,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(8),
+ .end = OMAP_GPIO_IRQ(8),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device voiceblue_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .dev = {
+ .platform_data = &voiceblue_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources),
+ .resource = voiceblue_smc91x_resources,
+};
+
+static struct platform_device *voiceblue_devices[] __initdata = {
+ &voiceblue_flash_device,
+ &voiceblue_smc91x_device,
+};
+
+static struct omap_usb_config voiceblue_usb_config __initdata = {
+ .hmc_mode = 3,
+ .register_host = 1,
+ .register_dev = 1,
+ .pins[0] = 2,
+ .pins[1] = 6,
+ .pins[2] = 6,
+};
+
+static struct omap_board_config_kernel voiceblue_config[] = {
+};
+
+static void __init voiceblue_init_irq(void)
+{
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+static void __init voiceblue_map_io(void)
+{
+ omap1_map_common_io();
+}
+
+#define MACHINE_PANICED 1
+#define MACHINE_REBOOTING 2
+#define MACHINE_REBOOT 4
+static unsigned long machine_state;
+
+static int panic_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+{
+ if (test_and_set_bit(MACHINE_PANICED, &machine_state))
+ return NOTIFY_DONE;
+
+ /* Flash power LED */
+ omap_writeb(0x78, OMAP_LPG1_LCR);
+ omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block panic_block = {
+ .notifier_call = panic_event,
+};
+
+static int __init voiceblue_setup(void)
+{
+ if (!machine_is_voiceblue())
+ return -ENODEV;
+
+ /* Setup panic notifier */
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
+
+ return 0;
+}
+postcore_initcall(voiceblue_setup);
+
+static int wdt_gpio_state;
+
+void voiceblue_wdt_enable(void)
+{
+ gpio_direction_output(0, 0);
+ gpio_set_value(0, 1);
+ gpio_set_value(0, 0);
+ wdt_gpio_state = 0;
+}
+
+void voiceblue_wdt_disable(void)
+{
+ gpio_set_value(0, 0);
+ gpio_set_value(0, 1);
+ gpio_set_value(0, 0);
+ gpio_direction_input(0);
+}
+
+void voiceblue_wdt_ping(void)
+{
+ if (test_bit(MACHINE_REBOOT, &machine_state))
+ return;
+
+ wdt_gpio_state = !wdt_gpio_state;
+ gpio_set_value(0, wdt_gpio_state);
+}
+
+static void voiceblue_reset(char mode, const char *cmd)
+{
+ /*
+ * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
+ * "Global Software Reset Affects Traffic Controller Frequency".
+ */
+ if (cpu_is_omap5912()) {
+ omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL);
+ omap_writew(0x8, ARM_RSTCT1);
+ }
+
+ set_bit(MACHINE_REBOOT, &machine_state);
+ voiceblue_wdt_enable();
+ while (1) ;
+}
+
+EXPORT_SYMBOL(voiceblue_wdt_enable);
+EXPORT_SYMBOL(voiceblue_wdt_disable);
+EXPORT_SYMBOL(voiceblue_wdt_ping);
+
+static void __init voiceblue_init(void)
+{
+ /* mux pins for uarts */
+ omap_cfg_reg(UART1_TX);
+ omap_cfg_reg(UART1_RTS);
+ omap_cfg_reg(UART2_TX);
+ omap_cfg_reg(UART2_RTS);
+ omap_cfg_reg(UART3_TX);
+ omap_cfg_reg(UART3_RX);
+
+ /* Watchdog */
+ gpio_request(0, "Watchdog");
+ /* smc91x reset */
+ gpio_request(7, "SMC91x reset");
+ gpio_direction_output(7, 1);
+ udelay(2); /* wait at least 100ns */
+ gpio_set_value(7, 0);
+ mdelay(50); /* 50ms until PHY ready */
+ /* smc91x interrupt pin */
+ gpio_request(8, "SMC91x irq");
+ /* 16C554 reset*/
+ gpio_request(6, "16C554 reset");
+ gpio_direction_output(6, 0);
+ /* 16C554 interrupt pins */
+ gpio_request(12, "16C554 irq");
+ gpio_request(13, "16C554 irq");
+ gpio_request(14, "16C554 irq");
+ gpio_request(15, "16C554 irq");
+ irq_set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING);
+
+ platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
+ omap_board_config = voiceblue_config;
+ omap_board_config_size = ARRAY_SIZE(voiceblue_config);
+ omap_serial_init();
+ omap1_usb_init(&voiceblue_usb_config);
+ omap_register_i2c_bus(1, 100, NULL, 0);
+
+ /* There is a good chance board is going up, so enable power LED
+ * (it is connected through invertor) */
+ omap_writeb(0x00, OMAP_LPG1_LCR);
+ omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */
+
+ arch_reset = voiceblue_reset;
+}
+
+MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
+ /* Maintainer: Ladislav Michl <michl@2n.cz> */
+ .boot_params = 0x10000100,
+ .map_io = voiceblue_map_io,
+ .reserve = omap_reserve,
+ .init_irq = voiceblue_init_irq,
+ .init_machine = voiceblue_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
new file mode 100644
index 00000000..84ef7047
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.c
@@ -0,0 +1,609 @@
+/*
+ * linux/arch/arm/mach-omap1/clock.c
+ *
+ * Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * Modified to use omap shared clock framework by
+ * Tony Lindgren <tony@atomide.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/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <asm/mach-types.h>
+
+#include <plat/cpu.h>
+#include <plat/usb.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "opp.h"
+
+__u32 arm_idlect1_mask;
+struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
+
+/*
+ * Omap1 specific clock functions
+ */
+
+unsigned long omap1_uart_recalc(struct clk *clk)
+{
+ unsigned int val = __raw_readl(clk->enable_reg);
+ return val & clk->enable_bit ? 48000000 : 12000000;
+}
+
+unsigned long omap1_sossi_recalc(struct clk *clk)
+{
+ u32 div = omap_readl(MOD_CONF_CTRL_1);
+
+ div = (div >> 17) & 0x7;
+ div++;
+
+ return clk->parent->rate / div;
+}
+
+static void omap1_clk_allow_idle(struct clk *clk)
+{
+ struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+ if (!(clk->flags & CLOCK_IDLE_CONTROL))
+ return;
+
+ if (iclk->no_idle_count > 0 && !(--iclk->no_idle_count))
+ arm_idlect1_mask |= 1 << iclk->idlect_shift;
+}
+
+static void omap1_clk_deny_idle(struct clk *clk)
+{
+ struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
+
+ if (!(clk->flags & CLOCK_IDLE_CONTROL))
+ return;
+
+ if (iclk->no_idle_count++ == 0)
+ arm_idlect1_mask &= ~(1 << iclk->idlect_shift);
+}
+
+static __u16 verify_ckctl_value(__u16 newval)
+{
+ /* This function checks for following limitations set
+ * by the hardware (all conditions must be true):
+ * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
+ * ARM_CK >= TC_CK
+ * DSP_CK >= TC_CK
+ * DSPMMU_CK >= TC_CK
+ *
+ * In addition following rules are enforced:
+ * LCD_CK <= TC_CK
+ * ARMPER_CK <= TC_CK
+ *
+ * However, maximum frequencies are not checked for!
+ */
+ __u8 per_exp;
+ __u8 lcd_exp;
+ __u8 arm_exp;
+ __u8 dsp_exp;
+ __u8 tc_exp;
+ __u8 dspmmu_exp;
+
+ per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
+ lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
+ arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
+ dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
+ tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
+ dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
+
+ if (dspmmu_exp < dsp_exp)
+ dspmmu_exp = dsp_exp;
+ if (dspmmu_exp > dsp_exp+1)
+ dspmmu_exp = dsp_exp+1;
+ if (tc_exp < arm_exp)
+ tc_exp = arm_exp;
+ if (tc_exp < dspmmu_exp)
+ tc_exp = dspmmu_exp;
+ if (tc_exp > lcd_exp)
+ lcd_exp = tc_exp;
+ if (tc_exp > per_exp)
+ per_exp = tc_exp;
+
+ newval &= 0xf000;
+ newval |= per_exp << CKCTL_PERDIV_OFFSET;
+ newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
+ newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
+ newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
+ newval |= tc_exp << CKCTL_TCDIV_OFFSET;
+ newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
+
+ return newval;
+}
+
+static int calc_dsor_exp(struct clk *clk, unsigned long rate)
+{
+ /* Note: If target frequency is too low, this function will return 4,
+ * which is invalid value. Caller must check for this value and act
+ * accordingly.
+ *
+ * Note: This function does not check for following limitations set
+ * by the hardware (all conditions must be true):
+ * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
+ * ARM_CK >= TC_CK
+ * DSP_CK >= TC_CK
+ * DSPMMU_CK >= TC_CK
+ */
+ unsigned long realrate;
+ struct clk * parent;
+ unsigned dsor_exp;
+
+ parent = clk->parent;
+ if (unlikely(parent == NULL))
+ return -EIO;
+
+ realrate = parent->rate;
+ for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
+ if (realrate <= rate)
+ break;
+
+ realrate /= 2;
+ }
+
+ return dsor_exp;
+}
+
+unsigned long omap1_ckctl_recalc(struct clk *clk)
+{
+ /* Calculate divisor encoded as 2-bit exponent */
+ int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
+
+ return clk->parent->rate / dsor;
+}
+
+unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
+{
+ int dsor;
+
+ /* Calculate divisor encoded as 2-bit exponent
+ *
+ * The clock control bits are in DSP domain,
+ * so api_ck is needed for access.
+ * Note that DSP_CKCTL virt addr = phys addr, so
+ * we must use __raw_readw() instead of omap_readw().
+ */
+ omap1_clk_enable(api_ck_p);
+ dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
+ omap1_clk_disable(api_ck_p);
+
+ return clk->parent->rate / dsor;
+}
+
+/* MPU virtual clock functions */
+int omap1_select_table_rate(struct clk *clk, unsigned long rate)
+{
+ /* Find the highest supported frequency <= rate and switch to it */
+ struct mpu_rate * ptr;
+ unsigned long dpll1_rate, ref_rate;
+
+ dpll1_rate = ck_dpll1_p->rate;
+ ref_rate = ck_ref_p->rate;
+
+ for (ptr = omap1_rate_table; ptr->rate; ptr++) {
+ if (ptr->xtal != ref_rate)
+ continue;
+
+ /* DPLL1 cannot be reprogrammed without risking system crash */
+ if (likely(dpll1_rate != 0) && ptr->pll_rate != dpll1_rate)
+ continue;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->rate <= rate)
+ break;
+ }
+
+ if (!ptr->rate)
+ return -EINVAL;
+
+ /*
+ * In most cases we should not need to reprogram DPLL.
+ * Reprogramming the DPLL is tricky, it must be done from SRAM.
+ * (on 730, bit 13 must always be 1)
+ */
+ if (cpu_is_omap7xx())
+ omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val | 0x2000);
+ else
+ omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
+
+ /* XXX Do we need to recalculate the tree below DPLL1 at this point? */
+ ck_dpll1_p->rate = ptr->pll_rate;
+
+ return 0;
+}
+
+int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp;
+ u16 regval;
+
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
+
+ regval = __raw_readw(DSP_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ __raw_writew(regval, DSP_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+
+ return 0;
+}
+
+long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp < 0)
+ return dsor_exp;
+ if (dsor_exp > 3)
+ dsor_exp = 3;
+ return clk->parent->rate / (1 << dsor_exp);
+}
+
+int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
+{
+ int dsor_exp;
+ u16 regval;
+
+ dsor_exp = calc_dsor_exp(clk, rate);
+ if (dsor_exp > 3)
+ dsor_exp = -EINVAL;
+ if (dsor_exp < 0)
+ return dsor_exp;
+
+ regval = omap_readw(ARM_CKCTL);
+ regval &= ~(3 << clk->rate_offset);
+ regval |= dsor_exp << clk->rate_offset;
+ regval = verify_ckctl_value(regval);
+ omap_writew(regval, ARM_CKCTL);
+ clk->rate = clk->parent->rate / (1 << dsor_exp);
+ return 0;
+}
+
+long omap1_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+ /* Find the highest supported frequency <= rate */
+ struct mpu_rate * ptr;
+ long highest_rate;
+ unsigned long ref_rate;
+
+ ref_rate = ck_ref_p->rate;
+
+ highest_rate = -EINVAL;
+
+ for (ptr = omap1_rate_table; ptr->rate; ptr++) {
+ if (ptr->xtal != ref_rate)
+ continue;
+
+ highest_rate = ptr->rate;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->rate <= rate)
+ break;
+ }
+
+ return highest_rate;
+}
+
+static unsigned calc_ext_dsor(unsigned long rate)
+{
+ unsigned dsor;
+
+ /* MCLK and BCLK divisor selection is not linear:
+ * freq = 96MHz / dsor
+ *
+ * RATIO_SEL range: dsor <-> RATIO_SEL
+ * 0..6: (RATIO_SEL+2) <-> (dsor-2)
+ * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
+ * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
+ * can not be used.
+ */
+ for (dsor = 2; dsor < 96; ++dsor) {
+ if ((dsor & 1) && dsor > 8)
+ continue;
+ if (rate >= 96000000 / dsor)
+ break;
+ }
+ return dsor;
+}
+
+/* XXX Only needed on 1510 */
+int omap1_set_uart_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int val;
+
+ val = __raw_readl(clk->enable_reg);
+ if (rate == 12000000)
+ val &= ~(1 << clk->enable_bit);
+ else if (rate == 48000000)
+ val |= (1 << clk->enable_bit);
+ else
+ return -EINVAL;
+ __raw_writel(val, clk->enable_reg);
+ clk->rate = rate;
+
+ return 0;
+}
+
+/* External clock (MCLK & BCLK) functions */
+int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned dsor;
+ __u16 ratio_bits;
+
+ dsor = calc_ext_dsor(rate);
+ clk->rate = 96000000 / dsor;
+ if (dsor > 8)
+ ratio_bits = ((dsor - 8) / 2 + 6) << 2;
+ else
+ ratio_bits = (dsor - 2) << 2;
+
+ ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
+ __raw_writew(ratio_bits, clk->enable_reg);
+
+ return 0;
+}
+
+int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
+{
+ u32 l;
+ int div;
+ unsigned long p_rate;
+
+ p_rate = clk->parent->rate;
+ /* Round towards slower frequency */
+ div = (p_rate + rate - 1) / rate;
+ div--;
+ if (div < 0 || div > 7)
+ return -EINVAL;
+
+ l = omap_readl(MOD_CONF_CTRL_1);
+ l &= ~(7 << 17);
+ l |= div << 17;
+ omap_writel(l, MOD_CONF_CTRL_1);
+
+ clk->rate = p_rate / (div + 1);
+
+ return 0;
+}
+
+long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate)
+{
+ return 96000000 / calc_ext_dsor(rate);
+}
+
+void omap1_init_ext_clk(struct clk *clk)
+{
+ unsigned dsor;
+ __u16 ratio_bits;
+
+ /* Determine current rate and ensure clock is based on 96MHz APLL */
+ ratio_bits = __raw_readw(clk->enable_reg) & ~1;
+ __raw_writew(ratio_bits, clk->enable_reg);
+
+ ratio_bits = (ratio_bits & 0xfc) >> 2;
+ if (ratio_bits > 6)
+ dsor = (ratio_bits - 6) * 2 + 8;
+ else
+ dsor = ratio_bits + 2;
+
+ clk-> rate = 96000000 / dsor;
+}
+
+int omap1_clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->usecount++ == 0) {
+ if (clk->parent) {
+ ret = omap1_clk_enable(clk->parent);
+ if (ret)
+ goto err;
+
+ if (clk->flags & CLOCK_NO_IDLE_PARENT)
+ omap1_clk_deny_idle(clk->parent);
+ }
+
+ ret = clk->ops->enable(clk);
+ if (ret) {
+ if (clk->parent)
+ omap1_clk_disable(clk->parent);
+ goto err;
+ }
+ }
+ return ret;
+
+err:
+ clk->usecount--;
+ return ret;
+}
+
+void omap1_clk_disable(struct clk *clk)
+{
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ clk->ops->disable(clk);
+ if (likely(clk->parent)) {
+ omap1_clk_disable(clk->parent);
+ if (clk->flags & CLOCK_NO_IDLE_PARENT)
+ omap1_clk_allow_idle(clk->parent);
+ }
+ }
+}
+
+static int omap1_clk_enable_generic(struct clk *clk)
+{
+ __u16 regval16;
+ __u32 regval32;
+
+ if (unlikely(clk->enable_reg == NULL)) {
+ printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return -EINVAL;
+ }
+
+ if (clk->flags & ENABLE_REG_32BIT) {
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 |= (1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+ } else {
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 |= (1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
+ }
+
+ return 0;
+}
+
+static void omap1_clk_disable_generic(struct clk *clk)
+{
+ __u16 regval16;
+ __u32 regval32;
+
+ if (clk->enable_reg == NULL)
+ return;
+
+ if (clk->flags & ENABLE_REG_32BIT) {
+ regval32 = __raw_readl(clk->enable_reg);
+ regval32 &= ~(1 << clk->enable_bit);
+ __raw_writel(regval32, clk->enable_reg);
+ } else {
+ regval16 = __raw_readw(clk->enable_reg);
+ regval16 &= ~(1 << clk->enable_bit);
+ __raw_writew(regval16, clk->enable_reg);
+ }
+}
+
+const struct clkops clkops_generic = {
+ .enable = omap1_clk_enable_generic,
+ .disable = omap1_clk_disable_generic,
+};
+
+static int omap1_clk_enable_dsp_domain(struct clk *clk)
+{
+ int retval;
+
+ retval = omap1_clk_enable(api_ck_p);
+ if (!retval) {
+ retval = omap1_clk_enable_generic(clk);
+ omap1_clk_disable(api_ck_p);
+ }
+
+ return retval;
+}
+
+static void omap1_clk_disable_dsp_domain(struct clk *clk)
+{
+ if (omap1_clk_enable(api_ck_p) == 0) {
+ omap1_clk_disable_generic(clk);
+ omap1_clk_disable(api_ck_p);
+ }
+}
+
+const struct clkops clkops_dspck = {
+ .enable = omap1_clk_enable_dsp_domain,
+ .disable = omap1_clk_disable_dsp_domain,
+};
+
+/* XXX SYSC register handling does not belong in the clock framework */
+static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
+{
+ int ret;
+ struct uart_clk *uclk;
+
+ ret = omap1_clk_enable_generic(clk);
+ if (ret == 0) {
+ /* Set smart idle acknowledgement mode */
+ uclk = (struct uart_clk *)clk;
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
+ uclk->sysc_addr);
+ }
+
+ return ret;
+}
+
+/* XXX SYSC register handling does not belong in the clock framework */
+static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
+{
+ struct uart_clk *uclk;
+
+ /* Set force idle acknowledgement mode */
+ uclk = (struct uart_clk *)clk;
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
+
+ omap1_clk_disable_generic(clk);
+}
+
+/* XXX SYSC register handling does not belong in the clock framework */
+const struct clkops clkops_uart_16xx = {
+ .enable = omap1_clk_enable_uart_functional_16xx,
+ .disable = omap1_clk_disable_uart_functional_16xx,
+};
+
+long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->round_rate != NULL)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+
+int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk->set_rate)
+ ret = clk->set_rate(clk, rate);
+ return ret;
+}
+
+/*
+ * Omap1 clock reset and init functions
+ */
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+
+void omap1_clk_disable_unused(struct clk *clk)
+{
+ __u32 regval32;
+
+ /* Clocks in the DSP domain need api_ck. Just assume bootloader
+ * has not enabled any DSP clocks */
+ if (clk->enable_reg == DSP_IDLECT2) {
+ printk(KERN_INFO "Skipping reset check for DSP domain "
+ "clock \"%s\"\n", clk->name);
+ return;
+ }
+
+ /* Is the clock already disabled? */
+ if (clk->flags & ENABLE_REG_32BIT)
+ regval32 = __raw_readl(clk->enable_reg);
+ else
+ regval32 = __raw_readw(clk->enable_reg);
+
+ if ((regval32 & (1 << clk->enable_bit)) == 0)
+ return;
+
+ printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
+ clk->ops->disable(clk);
+ printk(" done\n");
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
new file mode 100644
index 00000000..eaf09efb
--- /dev/null
+++ b/arch/arm/mach-omap1/clock.h
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-omap1/clock.h
+ *
+ * Copyright (C) 2004 - 2005, 2009 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP1_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
+
+#include <linux/clk.h>
+
+#include <plat/clock.h>
+
+extern int __init omap1_clk_init(void);
+extern int omap1_clk_enable(struct clk *clk);
+extern void omap1_clk_disable(struct clk *clk);
+extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
+extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_ckctl_recalc(struct clk *clk);
+extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_sossi_recalc(struct clk *clk);
+extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
+extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate);
+extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_uart_recalc(struct clk *clk);
+extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate);
+extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate);
+extern void omap1_init_ext_clk(struct clk *clk);
+extern int omap1_select_table_rate(struct clk *clk, unsigned long rate);
+extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate);
+extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
+extern unsigned long omap1_watchdog_recalc(struct clk *clk);
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+extern void omap1_clk_disable_unused(struct clk *clk);
+#else
+#define omap1_clk_disable_unused NULL
+#endif
+
+struct uart_clk {
+ struct clk clk;
+ unsigned long sysc_addr;
+};
+
+/* Provide a method for preventing idling some ARM IDLECT clocks */
+struct arm_idlect1_clk {
+ struct clk clk;
+ unsigned long no_idle_count;
+ __u8 idlect_shift;
+};
+
+/* ARM_CKCTL bit shifts */
+#define CKCTL_PERDIV_OFFSET 0
+#define CKCTL_LCDDIV_OFFSET 2
+#define CKCTL_ARMDIV_OFFSET 4
+#define CKCTL_DSPDIV_OFFSET 6
+#define CKCTL_TCDIV_OFFSET 8
+#define CKCTL_DSPMMUDIV_OFFSET 10
+/*#define ARM_TIMXO 12*/
+#define EN_DSPCK 13
+/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
+/* DSP_CKCTL bit shifts */
+#define CKCTL_DSPPERDIV_OFFSET 0
+
+/* ARM_IDLECT2 bit shifts */
+#define EN_WDTCK 0
+#define EN_XORPCK 1
+#define EN_PERCK 2
+#define EN_LCDCK 3
+#define EN_LBCK 4 /* Not on 1610/1710 */
+/*#define EN_HSABCK 5*/
+#define EN_APICK 6
+#define EN_TIMCK 7
+#define DMACK_REQ 8
+#define EN_GPIOCK 9 /* Not on 1610/1710 */
+/*#define EN_LBFREECK 10*/
+#define EN_CKOUT_ARM 11
+
+/* ARM_IDLECT3 bit shifts */
+#define EN_OCPI_CK 0
+#define EN_TC1_CK 2
+#define EN_TC2_CK 4
+
+/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
+#define EN_DSPTIMCK 5
+
+/* Various register defines for clock controls scattered around OMAP chip */
+#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */
+#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
+#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
+#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
+#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
+#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
+#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
+#define SOFT_REQ_REG 0xfffe0834
+#define SOFT_REQ_REG2 0xfffe0880
+
+extern __u32 arm_idlect1_mask;
+extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
+
+extern const struct clkops clkops_dspck;
+extern const struct clkops clkops_dummy;
+extern const struct clkops clkops_uart_16xx;
+extern const struct clkops clkops_generic;
+
+#endif
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
new file mode 100644
index 00000000..92400b9e
--- /dev/null
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -0,0 +1,927 @@
+/*
+ * linux/arch/arm/mach-omap1/clock_data.c
+ *
+ * Copyright (C) 2004 - 2005, 2009-2010 Nokia Corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * To do:
+ * - Clocks that are only available on some chips should be marked with the
+ * chips that they are present on.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h> /* for machine_is_* */
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/clkdev_omap.h>
+#include <plat/usb.h> /* for OTG_BASE */
+
+#include "clock.h"
+
+/* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
+#define IDL_CLKOUT_ARM_SHIFT 12
+#define IDLTIM_ARM_SHIFT 9
+#define IDLAPI_ARM_SHIFT 8
+#define IDLIF_ARM_SHIFT 6
+#define IDLLB_ARM_SHIFT 4 /* undocumented? */
+#define OMAP1510_IDLLCD_ARM_SHIFT 3 /* undocumented? */
+#define IDLPER_ARM_SHIFT 2
+#define IDLXORP_ARM_SHIFT 1
+#define IDLWDT_ARM_SHIFT 0
+
+/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_UART3_CLK_MODE_R 31
+#define CONF_MOD_UART2_CLK_MODE_R 30
+#define CONF_MOD_UART1_CLK_MODE_R 29
+#define CONF_MOD_MMC_SD_CLK_REQ_R 23
+#define CONF_MOD_MCBSP3_AUXON 20
+
+/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_SOSSI_CLK_EN_R 16
+
+/* Some OTG_SYSCON_2-specific bit fields */
+#define OTG_SYSCON_2_UHOST_EN_SHIFT 8
+
+/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
+#define SOFT_MMC2_DPLL_REQ_SHIFT 13
+#define SOFT_MMC_DPLL_REQ_SHIFT 12
+#define SOFT_UART3_DPLL_REQ_SHIFT 11
+#define SOFT_UART2_DPLL_REQ_SHIFT 10
+#define SOFT_UART1_DPLL_REQ_SHIFT 9
+#define SOFT_USB_OTG_DPLL_REQ_SHIFT 8
+#define SOFT_CAM_DPLL_REQ_SHIFT 7
+#define SOFT_COM_MCKO_REQ_SHIFT 6
+#define SOFT_PERIPH_REQ_SHIFT 5 /* sys_ck gate for UART2 ? */
+#define USB_REQ_EN_SHIFT 4
+#define SOFT_USB_REQ_SHIFT 3 /* sys_ck gate for USB host? */
+#define SOFT_SDW_REQ_SHIFT 2 /* sys_ck gate for Bluetooth? */
+#define SOFT_COM_REQ_SHIFT 1 /* sys_ck gate for com proc? */
+#define SOFT_DPLL_REQ_SHIFT 0
+
+/*
+ * Omap1 clocks
+ */
+
+static struct clk ck_ref = {
+ .name = "ck_ref",
+ .ops = &clkops_null,
+ .rate = 12000000,
+};
+
+static struct clk ck_dpll1 = {
+ .name = "ck_dpll1",
+ .ops = &clkops_null,
+ .parent = &ck_ref,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation. [ FIX: SoSSI, SSR ]
+ */
+static struct arm_idlect1_clk ck_dpll1out = {
+ .clk = {
+ .name = "ck_dpll1out",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT |
+ ENABLE_ON_INIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_CKOUT_ARM,
+ .recalc = &followparent_recalc,
+ },
+ .idlect_shift = IDL_CLKOUT_ARM_SHIFT,
+};
+
+static struct clk sossi_ck = {
+ .name = "ck_sossi",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1out.clk,
+ .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
+ .enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
+ .recalc = &omap1_sossi_recalc,
+ .set_rate = &omap1_set_sossi_rate,
+};
+
+static struct clk arm_ck = {
+ .name = "arm_ck",
+ .ops = &clkops_null,
+ .parent = &ck_dpll1,
+ .rate_offset = CKCTL_ARMDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct arm_idlect1_clk armper_ck = {
+ .clk = {
+ .name = "armper_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_PERCK,
+ .rate_offset = CKCTL_PERDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+ },
+ .idlect_shift = IDLPER_ARM_SHIFT,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation. [ GPIO code for 1510 ]
+ */
+static struct clk arm_gpio_ck = {
+ .name = "ick",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .flags = ENABLE_ON_INIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_GPIOCK,
+ .recalc = &followparent_recalc,
+};
+
+static struct arm_idlect1_clk armxor_ck = {
+ .clk = {
+ .name = "armxor_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_ref,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_XORPCK,
+ .recalc = &followparent_recalc,
+ },
+ .idlect_shift = IDLXORP_ARM_SHIFT,
+};
+
+static struct arm_idlect1_clk armtim_ck = {
+ .clk = {
+ .name = "armtim_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_ref,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_TIMCK,
+ .recalc = &followparent_recalc,
+ },
+ .idlect_shift = IDLTIM_ARM_SHIFT,
+};
+
+static struct arm_idlect1_clk armwdt_ck = {
+ .clk = {
+ .name = "armwdt_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_ref,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_WDTCK,
+ .fixed_div = 14,
+ .recalc = &omap_fixed_divisor_recalc,
+ },
+ .idlect_shift = IDLWDT_ARM_SHIFT,
+};
+
+static struct clk arminth_ck16xx = {
+ .name = "arminth_ck",
+ .ops = &clkops_null,
+ .parent = &arm_ck,
+ .recalc = &followparent_recalc,
+ /* Note: On 16xx the frequency can be divided by 2 by programming
+ * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
+ *
+ * 1510 version is in TC clocks.
+ */
+};
+
+static struct clk dsp_ck = {
+ .name = "dsp_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
+ .enable_bit = EN_DSPCK,
+ .rate_offset = CKCTL_DSPDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct clk dspmmu_ck = {
+ .name = "dspmmu_ck",
+ .ops = &clkops_null,
+ .parent = &ck_dpll1,
+ .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct clk dspper_ck = {
+ .name = "dspper_ck",
+ .ops = &clkops_dspck,
+ .parent = &ck_dpll1,
+ .enable_reg = DSP_IDLECT2,
+ .enable_bit = EN_PERCK,
+ .rate_offset = CKCTL_PERDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc_dsp_domain,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = &omap1_clk_set_rate_dsp_domain,
+};
+
+static struct clk dspxor_ck = {
+ .name = "dspxor_ck",
+ .ops = &clkops_dspck,
+ .parent = &ck_ref,
+ .enable_reg = DSP_IDLECT2,
+ .enable_bit = EN_XORPCK,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dsptim_ck = {
+ .name = "dsptim_ck",
+ .ops = &clkops_dspck,
+ .parent = &ck_ref,
+ .enable_reg = DSP_IDLECT2,
+ .enable_bit = EN_DSPTIMCK,
+ .recalc = &followparent_recalc,
+};
+
+static struct arm_idlect1_clk tc_ck = {
+ .clk = {
+ .name = "tc_ck",
+ .ops = &clkops_null,
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IDLE_CONTROL,
+ .rate_offset = CKCTL_TCDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+ },
+ .idlect_shift = IDLIF_ARM_SHIFT,
+};
+
+static struct clk arminth_ck1510 = {
+ .name = "arminth_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+ /* Note: On 1510 the frequency follows TC_CK
+ *
+ * 16xx version is in MPU clocks.
+ */
+};
+
+static struct clk tipb_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "tipb_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk l3_ocpi_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "l3_ocpi_ck",
+ .ops = &clkops_generic,
+ .parent = &tc_ck.clk,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
+ .enable_bit = EN_OCPI_CK,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk tc1_ck = {
+ .name = "tc1_ck",
+ .ops = &clkops_generic,
+ .parent = &tc_ck.clk,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
+ .enable_bit = EN_TC1_CK,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * FIXME: This clock seems to be necessary but no-one has asked for its
+ * activation. [ pm.c (SRAM), CCP, Camera ]
+ */
+static struct clk tc2_ck = {
+ .name = "tc2_ck",
+ .ops = &clkops_generic,
+ .parent = &tc_ck.clk,
+ .flags = ENABLE_ON_INIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
+ .enable_bit = EN_TC2_CK,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dma_ck = {
+ /* No-idle controlled by "tc_ck" */
+ .name = "dma_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dma_lcdfree_ck = {
+ .name = "dma_lcdfree_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct arm_idlect1_clk api_ck = {
+ .clk = {
+ .name = "api_ck",
+ .ops = &clkops_generic,
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_APICK,
+ .recalc = &followparent_recalc,
+ },
+ .idlect_shift = IDLAPI_ARM_SHIFT,
+};
+
+static struct arm_idlect1_clk lb_ck = {
+ .clk = {
+ .name = "lb_ck",
+ .ops = &clkops_generic,
+ .parent = &tc_ck.clk,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_LBCK,
+ .recalc = &followparent_recalc,
+ },
+ .idlect_shift = IDLLB_ARM_SHIFT,
+};
+
+static struct clk rhea1_ck = {
+ .name = "rhea1_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rhea2_ck = {
+ .name = "rhea2_ck",
+ .ops = &clkops_null,
+ .parent = &tc_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk lcd_ck_16xx = {
+ .name = "lcd_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_LCDCK,
+ .rate_offset = CKCTL_LCDDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+};
+
+static struct arm_idlect1_clk lcd_ck_1510 = {
+ .clk = {
+ .name = "lcd_ck",
+ .ops = &clkops_generic,
+ .parent = &ck_dpll1,
+ .flags = CLOCK_IDLE_CONTROL,
+ .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
+ .enable_bit = EN_LCDCK,
+ .rate_offset = CKCTL_LCDDIV_OFFSET,
+ .recalc = &omap1_ckctl_recalc,
+ .round_rate = omap1_clk_round_rate_ckctl_arm,
+ .set_rate = omap1_clk_set_rate_ckctl_arm,
+ },
+ .idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
+};
+
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
+static struct clk uart1_1510 = {
+ .name = "uart1_ck",
+ .ops = &clkops_null,
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+};
+
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
+static struct uart_clk uart1_16xx = {
+ .clk = {
+ .name = "uart1_ck",
+ .ops = &clkops_uart_16xx,
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
+ },
+ .sysc_addr = 0xfffb0054,
+};
+
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
+static struct clk uart2_ck = {
+ .name = "uart2_ck",
+ .ops = &clkops_null,
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_UART2_CLK_MODE_R,
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+};
+
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
+static struct clk uart3_1510 = {
+ .name = "uart3_ck",
+ .ops = &clkops_null,
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 12000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
+ .set_rate = &omap1_set_uart_rate,
+ .recalc = &omap1_uart_recalc,
+};
+
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
+static struct uart_clk uart3_16xx = {
+ .clk = {
+ .name = "uart3_ck",
+ .ops = &clkops_uart_16xx,
+ /* Direct from ULPD, no real parent */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
+ },
+ .sysc_addr = 0xfffb9854,
+};
+
+static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
+ .name = "usb_clko",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 6000000,
+ .flags = ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
+ .enable_bit = USB_MCLK_EN_BIT,
+};
+
+static struct clk usb_hhc_ck1510 = {
+ .name = "usb_hhc_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
+ .flags = ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = USB_HOST_HHC_UHOST_EN,
+};
+
+static struct clk usb_hhc_ck16xx = {
+ .name = "usb_hhc_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 48000000,
+ /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
+ .flags = ENABLE_REG_32BIT,
+ .enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
+ .enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
+};
+
+static struct clk usb_dc_ck = {
+ .name = "usb_dc_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 48000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = USB_REQ_EN_SHIFT,
+};
+
+static struct clk usb_dc_ck7xx = {
+ .name = "usb_dc_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 48000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
+};
+
+static struct clk uart1_7xx = {
+ .name = "uart1_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 12000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = 9,
+};
+
+static struct clk uart2_7xx = {
+ .name = "uart2_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 12000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = 11,
+};
+
+static struct clk mclk_1510 = {
+ .name = "mclk",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .rate = 12000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
+};
+
+static struct clk mclk_16xx = {
+ .name = "mclk",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
+ .enable_bit = COM_ULPD_PLL_CLK_REQ,
+ .set_rate = &omap1_set_ext_clk_rate,
+ .round_rate = &omap1_round_ext_clk_rate,
+ .init = &omap1_init_ext_clk,
+};
+
+static struct clk bclk_1510 = {
+ .name = "bclk",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .rate = 12000000,
+};
+
+static struct clk bclk_16xx = {
+ .name = "bclk",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent. May be enabled by ext hardware. */
+ .enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
+ .enable_bit = SWD_ULPD_PLL_CLK_REQ,
+ .set_rate = &omap1_set_ext_clk_rate,
+ .round_rate = &omap1_round_ext_clk_rate,
+ .init = &omap1_init_ext_clk,
+};
+
+static struct clk mmc1_ck = {
+ .name = "mmc1_ck",
+ .ops = &clkops_generic,
+ /* Functional clock is direct from ULPD, interface clock is ARMPER */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = CONF_MOD_MMC_SD_CLK_REQ_R,
+};
+
+/*
+ * XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
+ * CONF_MOD_MCBSP3_AUXON ??
+ */
+static struct clk mmc2_ck = {
+ .name = "mmc2_ck",
+ .ops = &clkops_generic,
+ /* Functional clock is direct from ULPD, interface clock is ARMPER */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
+ .enable_bit = 20,
+};
+
+static struct clk mmc3_ck = {
+ .name = "mmc3_ck",
+ .ops = &clkops_generic,
+ /* Functional clock is direct from ULPD, interface clock is ARMPER */
+ .parent = &armper_ck.clk,
+ .rate = 48000000,
+ .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
+};
+
+static struct clk virtual_ck_mpu = {
+ .name = "mpu",
+ .ops = &clkops_null,
+ .parent = &arm_ck, /* Is smarter alias for */
+ .recalc = &followparent_recalc,
+ .set_rate = &omap1_select_table_rate,
+ .round_rate = &omap1_round_to_table_rate,
+};
+
+/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
+remains active during MPU idle whenever this is enabled */
+static struct clk i2c_fck = {
+ .name = "i2c_fck",
+ .ops = &clkops_null,
+ .flags = CLOCK_NO_IDLE_PARENT,
+ .parent = &armxor_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c_ick = {
+ .name = "i2c_ick",
+ .ops = &clkops_null,
+ .flags = CLOCK_NO_IDLE_PARENT,
+ .parent = &armper_ck.clk,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap_clks[] = {
+ /* non-ULPD clocks */
+ CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ /* CK_GEN1 clocks */
+ CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX),
+ CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX),
+ CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_gpio.0", "ick", &arm_gpio_ck, CK_1510 | CK_310),
+ CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX),
+ CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310),
+ CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX),
+ /* CK_GEN2 clocks */
+ CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310),
+ /* CK_GEN3 clocks */
+ CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310),
+ CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX | CK_7XX),
+ CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX),
+ CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX),
+ CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
+ CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310),
+ CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX),
+ CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX),
+ CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_7XX),
+ CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310),
+ /* ULPD clocks */
+ CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310),
+ CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX),
+ CLK(NULL, "uart1_ck", &uart1_7xx, CK_7XX),
+ CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "uart2_ck", &uart2_7xx, CK_7XX),
+ CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310),
+ CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX),
+ CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310),
+ CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX),
+ CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX),
+ CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX),
+ CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310),
+ CLK(NULL, "mclk", &mclk_16xx, CK_16XX),
+ CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310),
+ CLK(NULL, "bclk", &bclk_16xx, CK_16XX),
+ CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310),
+ CLK("mmci-omap.0", "fck", &mmc3_ck, CK_7XX),
+ CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX),
+ CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX),
+ /* Virtual clocks */
+ CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
+ CLK("omap_i2c.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX),
+ CLK("omap_i2c.1", "ick", &i2c_ick, CK_16XX),
+ CLK("omap_i2c.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX),
+ CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX),
+ CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX),
+ CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX),
+ CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX),
+ CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX),
+ CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX),
+ CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX),
+ CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310),
+ CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
+ CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
+};
+
+/*
+ * init
+ */
+
+static struct clk_functions omap1_clk_functions = {
+ .clk_enable = omap1_clk_enable,
+ .clk_disable = omap1_clk_disable,
+ .clk_round_rate = omap1_clk_round_rate,
+ .clk_set_rate = omap1_clk_set_rate,
+ .clk_disable_unused = omap1_clk_disable_unused,
+};
+
+int __init omap1_clk_init(void)
+{
+ struct omap_clk *c;
+ const struct omap_clock_config *info;
+ int crystal_type = 0; /* Default 12 MHz */
+ u32 reg, cpu_mask;
+
+#ifdef CONFIG_DEBUG_LL
+ /*
+ * Resets some clocks that may be left on from bootloader,
+ * but leaves serial clocks on.
+ */
+ omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
+#endif
+
+ /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */
+ reg = omap_readw(SOFT_REQ_REG) & (1 << 4);
+ omap_writew(reg, SOFT_REQ_REG);
+ if (!cpu_is_omap15xx())
+ omap_writew(0, SOFT_REQ_REG2);
+
+ clk_init(&omap1_clk_functions);
+
+ /* By default all idlect1 clocks are allowed to idle */
+ arm_idlect1_mask = ~0;
+
+ for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+ clk_preinit(c->lk.clk);
+
+ cpu_mask = 0;
+ if (cpu_is_omap16xx())
+ cpu_mask |= CK_16XX;
+ if (cpu_is_omap1510())
+ cpu_mask |= CK_1510;
+ if (cpu_is_omap7xx())
+ cpu_mask |= CK_7XX;
+ if (cpu_is_omap310())
+ cpu_mask |= CK_310;
+
+ for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
+ if (c->cpu & cpu_mask) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ }
+
+ /* Pointers to these clocks are needed by code in clock.c */
+ api_ck_p = clk_get(NULL, "api_ck");
+ ck_dpll1_p = clk_get(NULL, "ck_dpll1");
+ ck_ref_p = clk_get(NULL, "ck_ref");
+
+ info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
+ if (info != NULL) {
+ if (!cpu_is_omap15xx())
+ crystal_type = info->system_clock_type;
+ }
+
+ if (cpu_is_omap7xx())
+ ck_ref.rate = 13000000;
+ if (cpu_is_omap16xx() && crystal_type == 2)
+ ck_ref.rate = 19200000;
+
+ pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: "
+ "0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
+ omap_readw(ARM_CKCTL));
+
+ /* We want to be in syncronous scalable mode */
+ omap_writew(0x1000, ARM_SYSST);
+
+#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
+ /* Use values set by bootloader. Determine PLL rate and recalculate
+ * dependent clocks as if kernel had changed PLL or divisors.
+ */
+ {
+ unsigned pll_ctl_val = omap_readw(DPLL_CTL);
+
+ ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
+ if (pll_ctl_val & 0x10) {
+ /* PLL enabled, apply multiplier and divisor */
+ if (pll_ctl_val & 0xf80)
+ ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
+ ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
+ } else {
+ /* PLL disabled, apply bypass divisor */
+ switch (pll_ctl_val & 0xc) {
+ case 0:
+ break;
+ case 0x4:
+ ck_dpll1.rate /= 2;
+ break;
+ default:
+ ck_dpll1.rate /= 4;
+ break;
+ }
+ }
+ }
+#else
+ /* Find the highest supported frequency and enable it */
+ if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
+ printk(KERN_ERR "System frequencies not set. Check your config.\n");
+ /* Guess sane values (60MHz) */
+ omap_writew(0x2290, DPLL_CTL);
+ omap_writew(cpu_is_omap7xx() ? 0x3005 : 0x1005, ARM_CKCTL);
+ ck_dpll1.rate = 60000000;
+ }
+#endif
+ propagate_rate(&ck_dpll1);
+ /* Cache rates for clocks connected to ck_ref (not dpll1) */
+ propagate_rate(&ck_ref);
+ printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
+ "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
+ ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
+ ck_dpll1.rate / 1000000, (ck_dpll1.rate / 100000) % 10,
+ arm_ck.rate / 1000000, (arm_ck.rate / 100000) % 10);
+
+ if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
+ /* Select slicer output as OMAP input clock */
+ omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
+ OMAP7XX_PCC_UPLD_CTRL);
+ }
+
+ /* Amstrad Delta wants BCLK high when inactive */
+ if (machine_is_ams_delta())
+ omap_writel(omap_readl(ULPD_CLOCK_CTRL) |
+ (1 << SDW_MCLK_INV_BIT),
+ ULPD_CLOCK_CTRL);
+
+ /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
+ /* (on 730, bit 13 must not be cleared) */
+ if (cpu_is_omap7xx())
+ omap_writew(omap_readw(ARM_CKCTL) & 0x2fff, ARM_CKCTL);
+ else
+ omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
+
+ /* Put DSP/MPUI into reset until needed */
+ omap_writew(0, ARM_RSTCT1);
+ omap_writew(1, ARM_RSTCT2);
+ omap_writew(0x400, ARM_IDLECT1);
+
+ /*
+ * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
+ * of the ARM_IDLECT2 register must be set to zero. The power-on
+ * default value of this bit is one.
+ */
+ omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_enable(&armper_ck.clk);
+ clk_enable(&armxor_ck.clk);
+ clk_enable(&armtim_ck.clk); /* This should be done by timer code */
+
+ if (cpu_is_omap15xx())
+ clk_enable(&arm_gpio_ck);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
new file mode 100644
index 00000000..36f26c3f
--- /dev/null
+++ b/arch/arm/mach-omap1/devices.c
@@ -0,0 +1,333 @@
+/*
+ * linux/arch/arm/mach-omap1/devices.c
+ *
+ * OMAP1 platform device setup/initialization
+ *
+ * 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/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+
+#include <mach/camera.h>
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/mux.h>
+#include <mach/gpio.h>
+#include <plat/mmc.h>
+#include <plat/omap7xx.h>
+#include <plat/mcbsp.h>
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
+
+#define OMAP_RTC_BASE 0xfffb4800
+
+static struct resource rtc_resources[] = {
+ {
+ .start = OMAP_RTC_BASE,
+ .end = OMAP_RTC_BASE + 0x5f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_RTC_TIMER,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap_rtc_device = {
+ .name = "omap_rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+static void omap_init_rtc(void)
+{
+ (void) platform_device_register(&omap_rtc_device);
+}
+#else
+static inline void omap_init_rtc(void) {}
+#endif
+
+static inline void omap_init_mbox(void) { }
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if (controller_nr == 0) {
+ if (cpu_is_omap7xx()) {
+ omap_cfg_reg(MMC_7XX_CMD);
+ omap_cfg_reg(MMC_7XX_CLK);
+ omap_cfg_reg(MMC_7XX_DAT0);
+ } else {
+ omap_cfg_reg(MMC_CMD);
+ omap_cfg_reg(MMC_CLK);
+ omap_cfg_reg(MMC_DAT0);
+ }
+
+ if (cpu_is_omap1710()) {
+ omap_cfg_reg(M15_1710_MMC_CLKI);
+ omap_cfg_reg(P19_1710_MMC_CMDDIR);
+ omap_cfg_reg(P20_1710_MMC_DATDIR0);
+ }
+ if (mmc_controller->slots[0].wires == 4 && !cpu_is_omap7xx()) {
+ omap_cfg_reg(MMC_DAT1);
+ /* NOTE: DAT2 can be on W10 (here) or M15 */
+ if (!mmc_controller->slots[0].nomux)
+ omap_cfg_reg(MMC_DAT2);
+ omap_cfg_reg(MMC_DAT3);
+ }
+ }
+
+ /* Block 2 is on newer chips, and has many pinout options */
+ if (cpu_is_omap16xx() && controller_nr == 1) {
+ if (!mmc_controller->slots[1].nomux) {
+ omap_cfg_reg(Y8_1610_MMC2_CMD);
+ omap_cfg_reg(Y10_1610_MMC2_CLK);
+ omap_cfg_reg(R18_1610_MMC2_CLKIN);
+ omap_cfg_reg(W8_1610_MMC2_DAT0);
+ if (mmc_controller->slots[1].wires == 4) {
+ omap_cfg_reg(V8_1610_MMC2_DAT1);
+ omap_cfg_reg(W15_1610_MMC2_DAT2);
+ omap_cfg_reg(R10_1610_MMC2_DAT3);
+ }
+
+ /* These are needed for the level shifter */
+ omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+ omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+ omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+ }
+
+ /* Feedback clock must be set on OMAP-1710 MMC2 */
+ if (cpu_is_omap1710())
+ omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+ MOD_CONF_CTRL_1);
+ }
+}
+
+void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+ int i;
+
+ for (i = 0; i < nr_controllers; i++) {
+ unsigned long base, size;
+ unsigned int irq = 0;
+
+ if (!mmc_data[i])
+ continue;
+
+ omap1_mmc_mux(mmc_data[i], i);
+
+ switch (i) {
+ case 0:
+ base = OMAP1_MMC1_BASE;
+ irq = INT_MMC;
+ break;
+ case 1:
+ if (!cpu_is_omap16xx())
+ return;
+ base = OMAP1_MMC2_BASE;
+ irq = INT_1610_MMC2;
+ break;
+ default:
+ continue;
+ }
+ size = OMAP1_MMC_SIZE;
+
+ omap_mmc_add("mmci-omap", i, base, size, irq, mmc_data[i]);
+ };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* OMAP7xx SPI support */
+#if defined(CONFIG_SPI_OMAP_100K) || defined(CONFIG_SPI_OMAP_100K_MODULE)
+
+struct platform_device omap_spi1 = {
+ .name = "omap1_spi100k",
+ .id = 1,
+};
+
+struct platform_device omap_spi2 = {
+ .name = "omap1_spi100k",
+ .id = 2,
+};
+
+static void omap_init_spi100k(void)
+{
+ omap_spi1.dev.platform_data = ioremap(OMAP7XX_SPI1_BASE, 0x7ff);
+ if (omap_spi1.dev.platform_data)
+ platform_device_register(&omap_spi1);
+
+ omap_spi2.dev.platform_data = ioremap(OMAP7XX_SPI2_BASE, 0x7ff);
+ if (omap_spi2.dev.platform_data)
+ platform_device_register(&omap_spi2);
+}
+
+#else
+static inline void omap_init_spi100k(void)
+{
+}
+#endif
+
+
+#define OMAP1_CAMERA_BASE 0xfffb6800
+#define OMAP1_CAMERA_IOSIZE 0x1c
+
+static struct resource omap1_camera_resources[] = {
+ [0] = {
+ .start = OMAP1_CAMERA_BASE,
+ .end = OMAP1_CAMERA_BASE + OMAP1_CAMERA_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_CAMERA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 omap1_camera_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device omap1_camera_device = {
+ .name = "omap1-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &omap1_camera_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(omap1_camera_resources),
+ .resource = omap1_camera_resources,
+};
+
+void __init omap1_camera_init(void *info)
+{
+ struct platform_device *dev = &omap1_camera_device;
+ int ret;
+
+ dev->dev.platform_data = info;
+
+ ret = platform_device_register(dev);
+ if (ret)
+ dev_err(&dev->dev, "unable to register device: %d\n", ret);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static inline void omap_init_sti(void) {}
+
+#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
+
+static struct platform_device omap_pcm = {
+ .name = "omap-pcm-audio",
+ .id = -1,
+};
+
+OMAP_MCBSP_PLATFORM_DEVICE(1);
+OMAP_MCBSP_PLATFORM_DEVICE(2);
+OMAP_MCBSP_PLATFORM_DEVICE(3);
+
+static void omap_init_audio(void)
+{
+ platform_device_register(&omap_mcbsp1);
+ platform_device_register(&omap_mcbsp2);
+ if (!cpu_is_omap7xx())
+ platform_device_register(&omap_mcbsp3);
+ platform_device_register(&omap_pcm);
+}
+
+#else
+static inline void omap_init_audio(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ * (a) Does any "standard config" pin muxing needed. Board-specific
+ * code will have muxed GPIO pins and done "nonstandard" setup;
+ * that code could live in the boot loader.
+ * (b) Populating board-specific platform_data with the data drivers
+ * rely on to handle wiring variations.
+ * (c) Creating platform devices as meaningful on this board and
+ * with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers. So is responding to probe().
+ *
+ * Board-specific knowledge like creating devices or pin setup is to be
+ * kept out of drivers as much as possible. In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap1_init_devices(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+
+ omap_init_mbox();
+ omap_init_rtc();
+ omap_init_spi100k();
+ omap_init_sti();
+ omap_init_audio();
+
+ return 0;
+}
+arch_initcall(omap1_init_devices);
+
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+
+static struct resource wdt_resources[] = {
+ {
+ .start = 0xfffeb000,
+ .end = 0xfffeb07F,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_wdt_device = {
+ .name = "omap_wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init omap_init_wdt(void)
+{
+ if (!cpu_is_omap16xx())
+ return -ENODEV;
+
+ return platform_device_register(&omap_wdt_device);
+}
+subsys_initcall(omap_init_wdt);
+#endif
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
new file mode 100644
index 00000000..f5a52204
--- /dev/null
+++ b/arch/arm/mach-omap1/dma.c
@@ -0,0 +1,391 @@
+/*
+ * OMAP1/OMAP7xx - specific DMA driver
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into platform driver
+ * - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <plat/dma.h>
+#include <plat/tc.h>
+#include <plat/irqs.h>
+
+#define OMAP1_DMA_BASE (0xfffed800)
+#define OMAP1_LOGICAL_DMA_CH_COUNT 17
+#define OMAP1_DMA_STRIDE 0x40
+
+static u32 errata;
+static u32 enable_1510_mode;
+static u8 dma_stride;
+static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
+
+static u16 reg_map[] = {
+ [GCR] = 0x400,
+ [GSCR] = 0x404,
+ [GRST1] = 0x408,
+ [HW_ID] = 0x442,
+ [PCH2_ID] = 0x444,
+ [PCH0_ID] = 0x446,
+ [PCH1_ID] = 0x448,
+ [PCHG_ID] = 0x44a,
+ [PCHD_ID] = 0x44c,
+ [CAPS_0] = 0x44e,
+ [CAPS_1] = 0x452,
+ [CAPS_2] = 0x456,
+ [CAPS_3] = 0x458,
+ [CAPS_4] = 0x45a,
+ [PCH2_SR] = 0x460,
+ [PCH0_SR] = 0x480,
+ [PCH1_SR] = 0x482,
+ [PCHD_SR] = 0x4c0,
+
+ /* Common Registers */
+ [CSDP] = 0x00,
+ [CCR] = 0x02,
+ [CICR] = 0x04,
+ [CSR] = 0x06,
+ [CEN] = 0x10,
+ [CFN] = 0x12,
+ [CSFI] = 0x14,
+ [CSEI] = 0x16,
+ [CPC] = 0x18, /* 15xx only */
+ [CSAC] = 0x18,
+ [CDAC] = 0x1a,
+ [CDEI] = 0x1c,
+ [CDFI] = 0x1e,
+ [CLNK_CTRL] = 0x28,
+
+ /* Channel specific register offsets */
+ [CSSA] = 0x08,
+ [CDSA] = 0x0c,
+ [COLOR] = 0x20,
+ [CCR2] = 0x24,
+ [LCH_CTRL] = 0x2a,
+};
+
+static struct resource res[] __initdata = {
+ [0] = {
+ .start = OMAP1_DMA_BASE,
+ .end = OMAP1_DMA_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "0",
+ .start = INT_DMA_CH0_6,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "1",
+ .start = INT_DMA_CH1_7,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = "2",
+ .start = INT_DMA_CH2_8,
+ .flags = IORESOURCE_IRQ,
+ },
+ [4] = {
+ .name = "3",
+ .start = INT_DMA_CH3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [5] = {
+ .name = "4",
+ .start = INT_DMA_CH4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [6] = {
+ .name = "5",
+ .start = INT_DMA_CH5,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* Handled in lcd_dma.c */
+ [7] = {
+ .name = "6",
+ .start = INT_1610_DMA_CH6,
+ .flags = IORESOURCE_IRQ,
+ },
+ /* irq's for omap16xx and omap7xx */
+ [8] = {
+ .name = "7",
+ .start = INT_1610_DMA_CH7,
+ .flags = IORESOURCE_IRQ,
+ },
+ [9] = {
+ .name = "8",
+ .start = INT_1610_DMA_CH8,
+ .flags = IORESOURCE_IRQ,
+ },
+ [10] = {
+ .name = "9",
+ .start = INT_1610_DMA_CH9,
+ .flags = IORESOURCE_IRQ,
+ },
+ [11] = {
+ .name = "10",
+ .start = INT_1610_DMA_CH10,
+ .flags = IORESOURCE_IRQ,
+ },
+ [12] = {
+ .name = "11",
+ .start = INT_1610_DMA_CH11,
+ .flags = IORESOURCE_IRQ,
+ },
+ [13] = {
+ .name = "12",
+ .start = INT_1610_DMA_CH12,
+ .flags = IORESOURCE_IRQ,
+ },
+ [14] = {
+ .name = "13",
+ .start = INT_1610_DMA_CH13,
+ .flags = IORESOURCE_IRQ,
+ },
+ [15] = {
+ .name = "14",
+ .start = INT_1610_DMA_CH14,
+ .flags = IORESOURCE_IRQ,
+ },
+ [16] = {
+ .name = "15",
+ .start = INT_1610_DMA_CH15,
+ .flags = IORESOURCE_IRQ,
+ },
+ [17] = {
+ .name = "16",
+ .start = INT_DMA_LCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ u8 stride;
+ u32 offset;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+
+ __raw_writew(val, dma_base + offset);
+ if ((reg > CLNK_CTRL && reg < CCEN) ||
+ (reg > PCHD_ID && reg < CAPS_2)) {
+ u32 offset2 = reg_map[reg] + 2 + (stride * lch);
+ __raw_writew(val >> 16, dma_base + offset2);
+ }
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ u8 stride;
+ u32 offset, val;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+
+ val = __raw_readw(dma_base + offset);
+ if ((reg > CLNK_CTRL && reg < CCEN) ||
+ (reg > PCHD_ID && reg < CAPS_2)) {
+ u16 upper;
+ u32 offset2 = reg_map[reg] + 2 + (stride * lch);
+ upper = __raw_readw(dma_base + offset2);
+ val |= (upper << 16);
+ }
+ return val;
+}
+
+static void omap1_clear_lch_regs(int lch)
+{
+ int i = dma_common_ch_start;
+
+ for (; i <= dma_common_ch_end; i += 1)
+ dma_write(0, i, lch);
+}
+
+static void omap1_clear_dma(int lch)
+{
+ u32 l;
+
+ l = dma_read(CCR, lch);
+ l &= ~OMAP_DMA_CCR_EN;
+ dma_write(l, CCR, lch);
+
+ /* Clear pending interrupts */
+ l = dma_read(CSR, lch);
+}
+
+static void omap1_show_dma_caps(void)
+{
+ if (enable_1510_mode) {
+ printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
+ } else {
+ u16 w;
+ printk(KERN_INFO "OMAP DMA hardware version %d\n",
+ dma_read(HW_ID, 0));
+ printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
+ dma_read(CAPS_0, 0), dma_read(CAPS_1, 0),
+ dma_read(CAPS_2, 0), dma_read(CAPS_3, 0),
+ dma_read(CAPS_4, 0));
+
+ /* Disable OMAP 3.0/3.1 compatibility mode. */
+ w = dma_read(GSCR, 0);
+ w |= 1 << 3;
+ dma_write(w, GSCR, 0);
+ }
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx())
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ return errata;
+}
+
+static int __init omap1_system_dma_init(void)
+{
+ struct omap_system_dma_plat_info *p;
+ struct omap_dma_dev_attr *d;
+ struct platform_device *pdev;
+ int ret;
+
+ pdev = platform_device_alloc("omap_dma_system", 0);
+ if (!pdev) {
+ pr_err("%s: Unable to device alloc for dma\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ dma_base = ioremap(res[0].start, resource_size(&res[0]));
+ if (!dma_base) {
+ pr_err("%s: Unable to ioremap\n", __func__);
+ ret = -ENODEV;
+ goto exit_device_put;
+ }
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_device_put;
+ }
+
+ p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+ if (!p) {
+ dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
+ __func__, pdev->name);
+ ret = -ENOMEM;
+ goto exit_device_del;
+ }
+
+ d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
+ if (!d) {
+ dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
+ __func__, pdev->name);
+ ret = -ENOMEM;
+ goto exit_release_p;
+ }
+
+ d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
+
+ /* Valid attributes for omap1 plus processors */
+ if (cpu_is_omap15xx())
+ d->dev_caps = ENABLE_1510_MODE;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+ d->dev_caps |= SRC_PORT;
+ d->dev_caps |= DST_PORT;
+ d->dev_caps |= SRC_INDEX;
+ d->dev_caps |= DST_INDEX;
+ d->dev_caps |= IS_BURST_ONLY4;
+ d->dev_caps |= CLEAR_CSR_ON_READ;
+ d->dev_caps |= IS_WORD_16;
+
+
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+ if (!d->chan) {
+ dev_err(&pdev->dev, "%s: Memory allocation failed"
+ "for d->chan!!!\n", __func__);
+ goto exit_release_d;
+ }
+
+ if (cpu_is_omap15xx())
+ d->chan_count = 9;
+ else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+ if (!(d->dev_caps & ENABLE_1510_MODE))
+ d->chan_count = 16;
+ else
+ d->chan_count = 9;
+ }
+
+ p->dma_attr = d;
+
+ p->show_dma_caps = omap1_show_dma_caps;
+ p->clear_lch_regs = omap1_clear_lch_regs;
+ p->clear_dma = omap1_clear_dma;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+ p->disable_irq_lch = NULL;
+
+ p->errata = configure_dma_errata();
+
+ ret = platform_device_add_data(pdev, p, sizeof(*p));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_release_chan;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
+ __func__, pdev->name, pdev->id);
+ goto exit_release_chan;
+ }
+
+ dma_stride = OMAP1_DMA_STRIDE;
+ dma_common_ch_start = CPC;
+ dma_common_ch_end = COLOR;
+
+ return ret;
+
+exit_release_chan:
+ kfree(d->chan);
+exit_release_d:
+ kfree(d);
+exit_release_p:
+ kfree(p);
+exit_device_del:
+ platform_device_del(pdev);
+exit_device_put:
+ platform_device_put(pdev);
+
+ return ret;
+}
+arch_initcall(omap1_system_dma_init);
diff --git a/arch/arm/mach-omap1/flash.c b/arch/arm/mach-omap1/flash.c
new file mode 100644
index 00000000..1749cb37
--- /dev/null
+++ b/arch/arm/mach-omap1/flash.c
@@ -0,0 +1,34 @@
+/*
+ * Flash support for OMAP1
+ *
+ * This program is free software; you can 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/mtd/mtd.h>
+#include <linux/mtd/map.h>
+
+#include <plat/io.h>
+#include <plat/tc.h>
+#include <plat/flash.h>
+
+void omap1_set_vpp(struct platform_device *pdev, int enable)
+{
+ static int count;
+ u32 l;
+
+ if (enable) {
+ if (count++ == 0) {
+ l = omap_readl(EMIFS_CONFIG);
+ l |= OMAP_EMIFS_CONFIG_WP;
+ omap_writel(l, EMIFS_CONFIG);
+ }
+ } else {
+ if (count && (--count == 0)) {
+ l = omap_readl(EMIFS_CONFIG);
+ l &= ~OMAP_EMIFS_CONFIG_WP;
+ omap_writel(l, EMIFS_CONFIG);
+ }
+ }
+}
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
new file mode 100644
index 00000000..cddbf8b0
--- /dev/null
+++ b/arch/arm/mach-omap1/fpga.c
@@ -0,0 +1,188 @@
+/*
+ * linux/arch/arm/mach-omap1/fpga.c
+ *
+ * Interrupt handler for OMAP-1510 Innovator FPGA
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <plat/fpga.h>
+#include <mach/gpio.h>
+
+static void fpga_mask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq - OMAP_FPGA_IRQ_BASE;
+
+ if (irq < 8)
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO)
+ & ~(1 << irq)), OMAP1510_FPGA_IMR_LO);
+ else if (irq < 16)
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+ & ~(1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
+ else
+ __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
+ & ~(1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
+}
+
+
+static inline u32 get_fpga_unmasked_irqs(void)
+{
+ return
+ ((__raw_readb(OMAP1510_FPGA_ISR_LO) &
+ __raw_readb(OMAP1510_FPGA_IMR_LO))) |
+ ((__raw_readb(OMAP1510_FPGA_ISR_HI) &
+ __raw_readb(OMAP1510_FPGA_IMR_HI)) << 8) |
+ ((__raw_readb(INNOVATOR_FPGA_ISR2) &
+ __raw_readb(INNOVATOR_FPGA_IMR2)) << 16);
+}
+
+
+static void fpga_ack_irq(struct irq_data *d)
+{
+ /* Don't need to explicitly ACK FPGA interrupts */
+}
+
+static void fpga_unmask_irq(struct irq_data *d)
+{
+ unsigned int irq = d->irq - OMAP_FPGA_IRQ_BASE;
+
+ if (irq < 8)
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_LO) | (1 << irq)),
+ OMAP1510_FPGA_IMR_LO);
+ else if (irq < 16)
+ __raw_writeb((__raw_readb(OMAP1510_FPGA_IMR_HI)
+ | (1 << (irq - 8))), OMAP1510_FPGA_IMR_HI);
+ else
+ __raw_writeb((__raw_readb(INNOVATOR_FPGA_IMR2)
+ | (1 << (irq - 16))), INNOVATOR_FPGA_IMR2);
+}
+
+static void fpga_mask_ack_irq(struct irq_data *d)
+{
+ fpga_mask_irq(d);
+ fpga_ack_irq(d);
+}
+
+void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc)
+{
+ u32 stat;
+ int fpga_irq;
+
+ stat = get_fpga_unmasked_irqs();
+
+ if (!stat)
+ return;
+
+ for (fpga_irq = OMAP_FPGA_IRQ_BASE;
+ (fpga_irq < OMAP_FPGA_IRQ_END) && stat;
+ fpga_irq++, stat >>= 1) {
+ if (stat & 1) {
+ generic_handle_irq(fpga_irq);
+ }
+ }
+}
+
+static struct irq_chip omap_fpga_irq_ack = {
+ .name = "FPGA-ack",
+ .irq_ack = fpga_mask_ack_irq,
+ .irq_mask = fpga_mask_irq,
+ .irq_unmask = fpga_unmask_irq,
+};
+
+
+static struct irq_chip omap_fpga_irq = {
+ .name = "FPGA",
+ .irq_ack = fpga_ack_irq,
+ .irq_mask = fpga_mask_irq,
+ .irq_unmask = fpga_unmask_irq,
+};
+
+/*
+ * All of the FPGA interrupt request inputs except for the touchscreen are
+ * edge-sensitive; the touchscreen is level-sensitive. The edge-sensitive
+ * interrupts are acknowledged as a side-effect of reading the interrupt
+ * status register from the FPGA. The edge-sensitive interrupt inputs
+ * cause a problem with level interrupt requests, such as Ethernet. The
+ * problem occurs when a level interrupt request is asserted while its
+ * interrupt input is masked in the FPGA, which results in a missed
+ * interrupt.
+ *
+ * In an attempt to workaround the problem with missed interrupts, the
+ * mask_ack routine for all of the FPGA interrupts has been changed from
+ * fpga_mask_ack_irq() to fpga_ack_irq() so that the specific FPGA interrupt
+ * being serviced is left unmasked. We can do this because the FPGA cascade
+ * interrupt is installed with the IRQF_DISABLED flag, which leaves all
+ * interrupts masked at the CPU while an FPGA interrupt handler executes.
+ *
+ * Limited testing indicates that this workaround appears to be effective
+ * for the smc9194 Ethernet driver used on the Innovator. It should work
+ * on other FPGA interrupts as well, but any drivers that explicitly mask
+ * interrupts at the interrupt controller via disable_irq/enable_irq
+ * could pose a problem.
+ */
+void omap1510_fpga_init_irq(void)
+{
+ int i, res;
+
+ __raw_writeb(0, OMAP1510_FPGA_IMR_LO);
+ __raw_writeb(0, OMAP1510_FPGA_IMR_HI);
+ __raw_writeb(0, INNOVATOR_FPGA_IMR2);
+
+ for (i = OMAP_FPGA_IRQ_BASE; i < OMAP_FPGA_IRQ_END; i++) {
+
+ if (i == OMAP1510_INT_FPGA_TS) {
+ /*
+ * The touchscreen interrupt is level-sensitive, so
+ * we'll use the regular mask_ack routine for it.
+ */
+ irq_set_chip(i, &omap_fpga_irq_ack);
+ }
+ else {
+ /*
+ * All FPGA interrupts except the touchscreen are
+ * edge-sensitive, so we won't mask them.
+ */
+ irq_set_chip(i, &omap_fpga_irq);
+ }
+
+ irq_set_handler(i, handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ /*
+ * The FPGA interrupt line is connected to GPIO13. Claim this pin for
+ * the ARM.
+ *
+ * NOTE: For general GPIO/MPUIO access and interrupts, please see
+ * gpio.[ch]
+ */
+ res = gpio_request(13, "FPGA irq");
+ if (res) {
+ pr_err("%s failed to get gpio\n", __func__);
+ return;
+ }
+ gpio_direction_input(13);
+ irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
+}
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c
new file mode 100644
index 00000000..364137c2
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio15xx.c
@@ -0,0 +1,99 @@
+/*
+ * OMAP15xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation 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.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+#define OMAP1510_GPIO_BASE 0xFFFCE000
+
+/* gpio1 */
+static struct __initdata resource omap15xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 16,
+ .bank_stride = 1,
+};
+
+static struct platform_device omap15xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap15xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap15xx_mpu_gpio_resources),
+ .resource = omap15xx_mpu_gpio_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap15xx_gpio_resources[] = {
+ {
+ .start = OMAP1510_GPIO_BASE,
+ .end = OMAP1510_GPIO_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_1510,
+ .bank_width = 16,
+};
+
+static struct platform_device omap15xx_gpio = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap15xx_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap15xx_gpio_resources),
+ .resource = omap15xx_gpio_resources,
+};
+
+/*
+ * omap15xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap15xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap15xx_gpio_init(void)
+{
+ if (!cpu_is_omap15xx())
+ return -EINVAL;
+
+ platform_device_register(&omap15xx_mpu_gpio);
+ platform_device_register(&omap15xx_gpio);
+
+ gpio_bank_count = 2;
+ return 0;
+}
+postcore_initcall(omap15xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c
new file mode 100644
index 00000000..293a246e
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio16xx.c
@@ -0,0 +1,200 @@
+/*
+ * OMAP16xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation 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.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP1610_GPIO1_BASE 0xfffbe400
+#define OMAP1610_GPIO2_BASE 0xfffbec00
+#define OMAP1610_GPIO3_BASE 0xfffbb400
+#define OMAP1610_GPIO4_BASE 0xfffbbc00
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+
+/* mpu gpio */
+static struct __initdata resource omap16xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 16,
+ .bank_stride = 1,
+};
+
+static struct platform_device omap16xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap16xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_mpu_gpio_resources),
+ .resource = omap16xx_mpu_gpio_resources,
+};
+
+/* gpio1 */
+static struct __initdata resource omap16xx_gpio1_resources[] = {
+ {
+ .start = OMAP1610_GPIO1_BASE,
+ .end = OMAP1610_GPIO1_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct platform_device omap16xx_gpio1 = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap16xx_gpio1_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio1_resources),
+ .resource = omap16xx_gpio1_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap16xx_gpio2_resources[] = {
+ {
+ .start = OMAP1610_GPIO2_BASE,
+ .end = OMAP1610_GPIO2_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 16,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct platform_device omap16xx_gpio2 = {
+ .name = "omap_gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &omap16xx_gpio2_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio2_resources),
+ .resource = omap16xx_gpio2_resources,
+};
+
+/* gpio3 */
+static struct __initdata resource omap16xx_gpio3_resources[] = {
+ {
+ .start = OMAP1610_GPIO3_BASE,
+ .end = OMAP1610_GPIO3_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 32,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct platform_device omap16xx_gpio3 = {
+ .name = "omap_gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &omap16xx_gpio3_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio3_resources),
+ .resource = omap16xx_gpio3_resources,
+};
+
+/* gpio4 */
+static struct __initdata resource omap16xx_gpio4_resources[] = {
+ {
+ .start = OMAP1610_GPIO4_BASE,
+ .end = OMAP1610_GPIO4_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_1610_GPIO_BANK4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 48,
+ .bank_type = METHOD_GPIO_1610,
+ .bank_width = 16,
+};
+
+static struct platform_device omap16xx_gpio4 = {
+ .name = "omap_gpio",
+ .id = 4,
+ .dev = {
+ .platform_data = &omap16xx_gpio4_config,
+ },
+ .num_resources = ARRAY_SIZE(omap16xx_gpio4_resources),
+ .resource = omap16xx_gpio4_resources,
+};
+
+static struct __initdata platform_device * omap16xx_gpio_dev[] = {
+ &omap16xx_mpu_gpio,
+ &omap16xx_gpio1,
+ &omap16xx_gpio2,
+ &omap16xx_gpio3,
+ &omap16xx_gpio4,
+};
+
+/*
+ * omap16xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap16xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap16xx_gpio_init(void)
+{
+ int i;
+
+ if (!cpu_is_omap16xx())
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(omap16xx_gpio_dev); i++)
+ platform_device_register(omap16xx_gpio_dev[i]);
+
+ gpio_bank_count = ARRAY_SIZE(omap16xx_gpio_dev);
+
+ return 0;
+}
+postcore_initcall(omap16xx_gpio_init);
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c
new file mode 100644
index 00000000..c6ad248d
--- /dev/null
+++ b/arch/arm/mach-omap1/gpio7xx.c
@@ -0,0 +1,262 @@
+/*
+ * OMAP7xx specific gpio init
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation 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.
+ */
+
+#include <linux/gpio.h>
+
+#define OMAP7XX_GPIO1_BASE 0xfffbc000
+#define OMAP7XX_GPIO2_BASE 0xfffbc800
+#define OMAP7XX_GPIO3_BASE 0xfffbd000
+#define OMAP7XX_GPIO4_BASE 0xfffbd800
+#define OMAP7XX_GPIO5_BASE 0xfffbe000
+#define OMAP7XX_GPIO6_BASE 0xfffbe800
+#define OMAP1_MPUIO_VBASE OMAP1_MPUIO_BASE
+
+/* mpu gpio */
+static struct __initdata resource omap7xx_mpu_gpio_resources[] = {
+ {
+ .start = OMAP1_MPUIO_VBASE,
+ .end = OMAP1_MPUIO_VBASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_MPUIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = {
+ .virtual_irq_start = IH_MPUIO_BASE,
+ .bank_type = METHOD_MPUIO,
+ .bank_width = 32,
+ .bank_stride = 2,
+};
+
+static struct platform_device omap7xx_mpu_gpio = {
+ .name = "omap_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap7xx_mpu_gpio_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_mpu_gpio_resources),
+ .resource = omap7xx_mpu_gpio_resources,
+};
+
+/* gpio1 */
+static struct __initdata resource omap7xx_gpio1_resources[] = {
+ {
+ .start = OMAP7XX_GPIO1_BASE,
+ .end = OMAP7XX_GPIO1_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = {
+ .virtual_irq_start = IH_GPIO_BASE,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio1 = {
+ .name = "omap_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap7xx_gpio1_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio1_resources),
+ .resource = omap7xx_gpio1_resources,
+};
+
+/* gpio2 */
+static struct __initdata resource omap7xx_gpio2_resources[] = {
+ {
+ .start = OMAP7XX_GPIO2_BASE,
+ .end = OMAP7XX_GPIO2_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 32,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio2 = {
+ .name = "omap_gpio",
+ .id = 2,
+ .dev = {
+ .platform_data = &omap7xx_gpio2_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio2_resources),
+ .resource = omap7xx_gpio2_resources,
+};
+
+/* gpio3 */
+static struct __initdata resource omap7xx_gpio3_resources[] = {
+ {
+ .start = OMAP7XX_GPIO3_BASE,
+ .end = OMAP7XX_GPIO3_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 64,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio3 = {
+ .name = "omap_gpio",
+ .id = 3,
+ .dev = {
+ .platform_data = &omap7xx_gpio3_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio3_resources),
+ .resource = omap7xx_gpio3_resources,
+};
+
+/* gpio4 */
+static struct __initdata resource omap7xx_gpio4_resources[] = {
+ {
+ .start = OMAP7XX_GPIO4_BASE,
+ .end = OMAP7XX_GPIO4_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 96,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio4 = {
+ .name = "omap_gpio",
+ .id = 4,
+ .dev = {
+ .platform_data = &omap7xx_gpio4_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio4_resources),
+ .resource = omap7xx_gpio4_resources,
+};
+
+/* gpio5 */
+static struct __initdata resource omap7xx_gpio5_resources[] = {
+ {
+ .start = OMAP7XX_GPIO5_BASE,
+ .end = OMAP7XX_GPIO5_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 128,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio5 = {
+ .name = "omap_gpio",
+ .id = 5,
+ .dev = {
+ .platform_data = &omap7xx_gpio5_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio5_resources),
+ .resource = omap7xx_gpio5_resources,
+};
+
+/* gpio6 */
+static struct __initdata resource omap7xx_gpio6_resources[] = {
+ {
+ .start = OMAP7XX_GPIO6_BASE,
+ .end = OMAP7XX_GPIO6_BASE + SZ_2K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_7XX_GPIO_BANK6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = {
+ .virtual_irq_start = IH_GPIO_BASE + 160,
+ .bank_type = METHOD_GPIO_7XX,
+ .bank_width = 32,
+};
+
+static struct platform_device omap7xx_gpio6 = {
+ .name = "omap_gpio",
+ .id = 6,
+ .dev = {
+ .platform_data = &omap7xx_gpio6_config,
+ },
+ .num_resources = ARRAY_SIZE(omap7xx_gpio6_resources),
+ .resource = omap7xx_gpio6_resources,
+};
+
+static struct __initdata platform_device * omap7xx_gpio_dev[] = {
+ &omap7xx_mpu_gpio,
+ &omap7xx_gpio1,
+ &omap7xx_gpio2,
+ &omap7xx_gpio3,
+ &omap7xx_gpio4,
+ &omap7xx_gpio5,
+ &omap7xx_gpio6,
+};
+
+/*
+ * omap7xx_gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap7xx_gpio_init is a postcore_initcall.
+ */
+static int __init omap7xx_gpio_init(void)
+{
+ int i;
+
+ if (!cpu_is_omap7xx())
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(omap7xx_gpio_dev); i++)
+ platform_device_register(omap7xx_gpio_dev[i]);
+
+ gpio_bank_count = ARRAY_SIZE(omap7xx_gpio_dev);
+
+ return 0;
+}
+postcore_initcall(omap7xx_gpio_init);
diff --git a/arch/arm/mach-omap1/i2c.c b/arch/arm/mach-omap1/i2c.c
new file mode 100644
index 00000000..5446c991
--- /dev/null
+++ b/arch/arm/mach-omap1/i2c.c
@@ -0,0 +1,35 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <plat/i2c.h>
+#include <plat/mux.h>
+#include <plat/cpu.h>
+
+void __init omap1_i2c_mux_pins(int bus_id)
+{
+ if (cpu_is_omap7xx()) {
+ omap_cfg_reg(I2C_7XX_SDA);
+ omap_cfg_reg(I2C_7XX_SCL);
+ } else {
+ omap_cfg_reg(I2C_SDA);
+ omap_cfg_reg(I2C_SCL);
+ }
+}
diff --git a/arch/arm/mach-omap1/id.c b/arch/arm/mach-omap1/id.c
new file mode 100644
index 00000000..a0e3560b
--- /dev/null
+++ b/arch/arm/mach-omap1/id.c
@@ -0,0 +1,204 @@
+/*
+ * linux/arch/arm/mach-omap1/id.c
+ *
+ * OMAP1 CPU identification code
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <plat/cpu.h>
+
+#define OMAP_DIE_ID_0 0xfffe1800
+#define OMAP_DIE_ID_1 0xfffe1804
+#define OMAP_PRODUCTION_ID_0 0xfffe2000
+#define OMAP_PRODUCTION_ID_1 0xfffe2004
+#define OMAP32_ID_0 0xfffed400
+#define OMAP32_ID_1 0xfffed404
+
+struct omap_id {
+ u16 jtag_id; /* Used to determine OMAP type */
+ u8 die_rev; /* Processor revision */
+ u32 omap_id; /* OMAP revision */
+ u32 type; /* Cpu id bits [31:08], cpu class bits [07:00] */
+};
+
+static unsigned int omap_revision;
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+ { .jtag_id = 0xb574, .die_rev = 0x2, .omap_id = 0x03310315, .type = 0x03100000},
+ { .jtag_id = 0x355f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300100},
+ { .jtag_id = 0xb55f, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x07300300},
+ { .jtag_id = 0xb62c, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x08500000},
+ { .jtag_id = 0xb470, .die_rev = 0x0, .omap_id = 0x03310100, .type = 0x15100000},
+ { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320000, .type = 0x16100000},
+ { .jtag_id = 0xb576, .die_rev = 0x2, .omap_id = 0x03320100, .type = 0x16110000},
+ { .jtag_id = 0xb576, .die_rev = 0x3, .omap_id = 0x03320100, .type = 0x16100c00},
+ { .jtag_id = 0xb576, .die_rev = 0x0, .omap_id = 0x03320200, .type = 0x16100d00},
+ { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+ { .jtag_id = 0xb613, .die_rev = 0x0, .omap_id = 0x03320300, .type = 0x1610ef00},
+ { .jtag_id = 0xb576, .die_rev = 0x1, .omap_id = 0x03320100, .type = 0x16110000},
+ { .jtag_id = 0xb58c, .die_rev = 0x2, .omap_id = 0x03320200, .type = 0x16110b00},
+ { .jtag_id = 0xb58c, .die_rev = 0x3, .omap_id = 0x03320200, .type = 0x16110c00},
+ { .jtag_id = 0xb65f, .die_rev = 0x0, .omap_id = 0x03320400, .type = 0x16212300},
+ { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320400, .type = 0x16212300},
+ { .jtag_id = 0xb65f, .die_rev = 0x1, .omap_id = 0x03320500, .type = 0x16212300},
+ { .jtag_id = 0xb5f7, .die_rev = 0x0, .omap_id = 0x03330000, .type = 0x17100000},
+ { .jtag_id = 0xb5f7, .die_rev = 0x1, .omap_id = 0x03330100, .type = 0x17100000},
+ { .jtag_id = 0xb5f7, .die_rev = 0x2, .omap_id = 0x03330100, .type = 0x17100000},
+};
+
+unsigned int omap_rev(void)
+{
+ return omap_revision;
+}
+EXPORT_SYMBOL(omap_rev);
+
+/*
+ * Get OMAP type from PROD_ID.
+ * 1710 has the PROD_ID in bits 15:00, not in 16:01 as documented in TRM.
+ * 1510 PROD_ID is empty, and 1610 PROD_ID does not make sense.
+ * Undocumented register in TEST BLOCK is used as fallback; This seems to
+ * work on 1510, 1610 & 1710. The official way hopefully will work in future
+ * processors.
+ */
+static u16 __init omap_get_jtag_id(void)
+{
+ u32 prod_id, omap_id;
+
+ prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
+ omap_id = omap_readl(OMAP32_ID_1);
+
+ /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730/850 */
+ if (((prod_id >> 20) == 0) || (prod_id == omap_id))
+ prod_id = 0;
+ else
+ prod_id &= 0xffff;
+
+ if (prod_id)
+ return prod_id;
+
+ /* Use OMAP32_ID_1 as fallback */
+ prod_id = ((omap_id >> 12) & 0xffff);
+
+ return prod_id;
+}
+
+/*
+ * Get OMAP revision from DIE_REV.
+ * Early 1710 processors may have broken OMAP_DIE_ID, it contains PROD_ID.
+ * Undocumented register in the TEST BLOCK is used as fallback.
+ * REVISIT: This does not seem to work on 1510
+ */
+static u8 __init omap_get_die_rev(void)
+{
+ u32 die_rev;
+
+ die_rev = omap_readl(OMAP_DIE_ID_1);
+
+ /* Check for broken OMAP_DIE_ID on early 1710 */
+ if (((die_rev >> 12) & 0xffff) == omap_get_jtag_id())
+ die_rev = 0;
+
+ die_rev = (die_rev >> 17) & 0xf;
+ if (die_rev)
+ return die_rev;
+
+ die_rev = (omap_readl(OMAP32_ID_1) >> 28) & 0xf;
+
+ return die_rev;
+}
+
+void __init omap_check_revision(void)
+{
+ int i;
+ u16 jtag_id;
+ u8 die_rev;
+ u32 omap_id;
+ u8 cpu_type;
+
+ jtag_id = omap_get_jtag_id();
+ die_rev = omap_get_die_rev();
+ omap_id = omap_readl(OMAP32_ID_0);
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "OMAP_DIE_ID_0: 0x%08x\n", omap_readl(OMAP_DIE_ID_0));
+ printk(KERN_DEBUG "OMAP_DIE_ID_1: 0x%08x DIE_REV: %i\n",
+ omap_readl(OMAP_DIE_ID_1),
+ (omap_readl(OMAP_DIE_ID_1) >> 17) & 0xf);
+ printk(KERN_DEBUG "OMAP_PRODUCTION_ID_0: 0x%08x\n",
+ omap_readl(OMAP_PRODUCTION_ID_0));
+ printk(KERN_DEBUG "OMAP_PRODUCTION_ID_1: 0x%08x JTAG_ID: 0x%04x\n",
+ omap_readl(OMAP_PRODUCTION_ID_1),
+ omap_readl(OMAP_PRODUCTION_ID_1) & 0xffff);
+ printk(KERN_DEBUG "OMAP32_ID_0: 0x%08x\n", omap_readl(OMAP32_ID_0));
+ printk(KERN_DEBUG "OMAP32_ID_1: 0x%08x\n", omap_readl(OMAP32_ID_1));
+ printk(KERN_DEBUG "JTAG_ID: 0x%04x DIE_REV: %i\n", jtag_id, die_rev);
+#endif
+
+ system_serial_high = omap_readl(OMAP_DIE_ID_0);
+ system_serial_low = omap_readl(OMAP_DIE_ID_1);
+
+ /* First check only the major version in a safe way */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == (omap_ids[i].jtag_id)) {
+ omap_revision = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Check if we can find the die revision */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == omap_ids[i].jtag_id && die_rev == omap_ids[i].die_rev) {
+ omap_revision = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Finally check also the omap_id */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (jtag_id == omap_ids[i].jtag_id
+ && die_rev == omap_ids[i].die_rev
+ && omap_id == omap_ids[i].omap_id) {
+ omap_revision = omap_ids[i].type;
+ break;
+ }
+ }
+
+ /* Add the cpu class info (7xx, 15xx, 16xx, 24xx) */
+ cpu_type = omap_revision >> 24;
+
+ switch (cpu_type) {
+ case 0x07:
+ case 0x08:
+ omap_revision |= 0x07;
+ break;
+ case 0x03:
+ case 0x15:
+ omap_revision |= 0x15;
+ break;
+ case 0x16:
+ case 0x17:
+ omap_revision |= 0x16;
+ break;
+ default:
+ printk(KERN_INFO "Unknown OMAP cpu type: 0x%02x\n", cpu_type);
+ }
+
+ printk(KERN_INFO "OMAP%04x", omap_revision >> 16);
+ if ((omap_revision >> 8) & 0xff)
+ printk(KERN_INFO "%x", (omap_revision >> 8) & 0xff);
+ printk(KERN_INFO " revision %i handled as %02xxx id: %08x%08x\n",
+ die_rev, omap_revision & 0xff, system_serial_low,
+ system_serial_high);
+}
+
diff --git a/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h
new file mode 100644
index 00000000..23eed003
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/ams-delta-fiq.h
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/mach-omap1/include/ams-delta-fiq.h
+ *
+ * Taken from the original Amstrad modifications to fiq.h
+ *
+ * Copyright (c) 2004 Amstrad Plc
+ * Copyright (c) 2006 Matt Callow
+ * Copyright (c) 2010 Janusz Krzysztofik
+ *
+ * This program is free software; you can 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 __AMS_DELTA_FIQ_H
+#define __AMS_DELTA_FIQ_H
+
+#include <plat/irqs.h>
+
+/*
+ * Interrupt number used for passing control from FIQ to IRQ.
+ * IRQ12, described as reserved, has been selected.
+ */
+#define INT_DEFERRED_FIQ INT_1510_RES12
+/*
+ * Base address of an interrupt handler that the INT_DEFERRED_FIQ belongs to.
+ */
+#if (INT_DEFERRED_FIQ < IH2_BASE)
+#define DEFERRED_FIQ_IH_BASE OMAP_IH1_BASE
+#else
+#define DEFERRED_FIQ_IH_BASE OMAP_IH2_BASE
+#endif
+
+/*
+ * These are the offsets from the beginning of the fiq_buffer. They are put here
+ * since the buffer and header need to be accessed by drivers servicing devices
+ * which generate GPIO interrupts - e.g. keyboard, modem, hook switch.
+ */
+#define FIQ_MASK 0
+#define FIQ_STATE 1
+#define FIQ_KEYS_CNT 2
+#define FIQ_TAIL_OFFSET 3
+#define FIQ_HEAD_OFFSET 4
+#define FIQ_BUF_LEN 5
+#define FIQ_KEY 6
+#define FIQ_MISSED_KEYS 7
+#define FIQ_BUFFER_START 8
+#define FIQ_GPIO_INT_MASK 9
+#define FIQ_KEYS_HICNT 10
+#define FIQ_IRQ_PEND 11
+#define FIQ_SIR_CODE_L1 12
+#define IRQ_SIR_CODE_L2 13
+
+#define FIQ_CNT_INT_00 14
+#define FIQ_CNT_INT_KEY 15
+#define FIQ_CNT_INT_MDM 16
+#define FIQ_CNT_INT_03 17
+#define FIQ_CNT_INT_HSW 18
+#define FIQ_CNT_INT_05 19
+#define FIQ_CNT_INT_06 20
+#define FIQ_CNT_INT_07 21
+#define FIQ_CNT_INT_08 22
+#define FIQ_CNT_INT_09 23
+#define FIQ_CNT_INT_10 24
+#define FIQ_CNT_INT_11 25
+#define FIQ_CNT_INT_12 26
+#define FIQ_CNT_INT_13 27
+#define FIQ_CNT_INT_14 28
+#define FIQ_CNT_INT_15 29
+
+#define FIQ_CIRC_BUFF 30 /*Start of circular buffer */
+
+#ifndef __ASSEMBLER__
+extern unsigned int fiq_buffer[];
+extern unsigned char qwerty_fiqin_start, qwerty_fiqin_end;
+
+extern void __init ams_delta_init_fiq(void);
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap1/include/mach/camera.h b/arch/arm/mach-omap1/include/mach/camera.h
new file mode 100644
index 00000000..847d00f0
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/camera.h
@@ -0,0 +1,13 @@
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#include <media/omap1_camera.h>
+
+void omap1_camera_init(void *);
+
+static inline void omap1_set_camera_info(struct omap1_cam_platform_data *info)
+{
+ omap1_camera_init(info);
+}
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
diff --git a/arch/arm/mach-omap1/include/mach/clkdev.h b/arch/arm/mach-omap1/include/mach/clkdev.h
new file mode 100644
index 00000000..ea8640e4
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/clkdev.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/clkdev.h
+ */
+
+#include <plat/clkdev.h>
diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S
new file mode 100644
index 00000000..62856044
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/debug-macro.S
@@ -0,0 +1,107 @@
+/* arch/arm/mach-omap1/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+
+#include <plat/serial.h>
+
+#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
+ .pushsection .data
+omap_uart_phys: .word 0x0
+omap_uart_virt: .word 0x0
+ .popsection
+
+ /*
+ * Note that this code won't work if the bootloader passes
+ * a wrong machine ID number in r1. To debug, just hardcode
+ * the desired UART phys and virt addresses temporarily into
+ * the omap_uart_phys and omap_uart_virt above.
+ */
+ .macro addruart, rp, rv
+
+ /* Use omap_uart_phys/virt if already configured */
+9: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
+ ldrne \rp, =omap_uart_phys @ MMU enabled
+ add \rv, \rp, #4 @ omap_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
+ bne 99f @ already configured
+
+ /* Check the debug UART configuration set in uncompress.h */
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
+ ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled
+ ldr \rp, [\rp, #0]
+
+ /* Select the UART to use based on the UART1 scratchpad value */
+10: cmp \rp, #0 @ no port configured?
+ beq 11f @ if none, try to use UART1
+ cmp \rp, #OMAP1UART1
+ beq 11f @ configure OMAP1UART1
+ cmp \rp, #OMAP1UART2
+ beq 12f @ configure OMAP1UART2
+ cmp \rp, #OMAP1UART3
+ beq 13f @ configure OMAP2UART3
+
+ /* Configure the UART offset from the phys/virt base */
+11: mov \rp, #0x00fb0000 @ OMAP1UART1
+ b 98f
+12: mov \rp, #0x00fb0000 @ OMAP1UART1
+ orr \rp, \rp, #0x00000800 @ OMAP1UART2
+ b 98f
+13: mov \rp, #0x00fb0000 @ OMAP1UART1
+ orr \rp, \rp, #0x00000800 @ OMAP1UART2
+ orr \rp, \rp, #0x00009000 @ OMAP1UART3
+
+ /* Store both phys and virt address for the uart */
+98: add \rp, \rp, #0xff000000 @ phys base
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ sub \rp, \rp, #0xff000000 @ phys base
+ add \rp, \rp, #0xfe000000 @ virt base
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
+ b 9b
+99:
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldrb \rd, [\rx, #(UART_LSR << OMAP_PORT_SHIFT)]
+ and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ beq 1002f
+ ldrb \rd, [\rx, #(UART_LSR << OMAP7XX_PORT_SHIFT)]
+ and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ bne 1001b
+1002:
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
diff --git a/arch/arm/mach-omap1/include/mach/entry-macro.S b/arch/arm/mach-omap1/include/mach/entry-macro.S
new file mode 100644
index 00000000..bfb4fb1d
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/entry-macro.S
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-omap1/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for OMAP-based platforms
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/io.h>
+#include <mach/irqs.h>
+#include <asm/hardware/gic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =OMAP1_IO_ADDRESS(OMAP_IH1_BASE)
+ ldr \irqnr, [\base, #IRQ_ITR_REG_OFFSET]
+ ldr \tmp, [\base, #IRQ_MIR_REG_OFFSET]
+ mov \irqstat, #0xffffffff
+ bic \tmp, \irqstat, \tmp
+ tst \irqnr, \tmp
+ beq 1510f
+
+ ldr \irqnr, [\base, #IRQ_SIR_FIQ_REG_OFFSET]
+ ldr \tmp, =omap_irq_flags @ irq flags address
+ ldr \tmp, [\tmp, #0] @ irq flags value
+ cmp \irqnr, #0
+ ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+ cmpeq \irqnr, \tmp
+ ldreq \base, =OMAP1_IO_ADDRESS(OMAP_IH2_BASE)
+ ldreq \irqnr, [\base, #IRQ_SIR_IRQ_REG_OFFSET]
+ addeqs \irqnr, \irqnr, #32
+1510:
+ .endm
+
diff --git a/arch/arm/mach-omap1/include/mach/gpio.h b/arch/arm/mach-omap1/include/mach/gpio.h
new file mode 100644
index 00000000..e737706a
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/gpio.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/gpio.h
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-omap1/include/mach/hardware.h b/arch/arm/mach-omap1/include/mach/hardware.h
new file mode 100644
index 00000000..a3f6287b
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/hardware.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/hardware.h
+ */
+
+#include <plat/hardware.h>
diff --git a/arch/arm/mach-omap1/include/mach/io.h b/arch/arm/mach-omap1/include/mach/io.h
new file mode 100644
index 00000000..57bdf74a
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/io.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/io.h
+ */
+
+#include <plat/io.h>
diff --git a/arch/arm/mach-omap1/include/mach/irqs.h b/arch/arm/mach-omap1/include/mach/irqs.h
new file mode 100644
index 00000000..9292fdc1
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/irqs.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/irqs.h
+ */
+
+#include <plat/irqs.h>
diff --git a/arch/arm/mach-omap1/include/mach/lcd_dma.h b/arch/arm/mach-omap1/include/mach/lcd_dma.h
new file mode 100644
index 00000000..d7a457bb
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/lcd_dma.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-omap1/include/mach/lcd_dma.h
+ *
+ * Extracted from arch/arm/plat-omap/include/plat/dma.h
+ * Copyright (C) 2003 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.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 __MACH_OMAP1_LCD_DMA_H__
+#define __MACH_OMAP1_LCD_DMA_H__
+
+/* Hardware registers for LCD DMA */
+#define OMAP1510_DMA_LCD_BASE (0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U (OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L (OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE (0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U (OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L (OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U (OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L (OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U (OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L (OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U (OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1 (OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L (OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1 (OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1 (OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
+
+/* LCD DMA block numbers */
+enum {
+ OMAP_LCD_DMA_B1_TOP,
+ OMAP_LCD_DMA_B1_BOTTOM,
+ OMAP_LCD_DMA_B2_TOP,
+ OMAP_LCD_DMA_B2_BOTTOM
+};
+
+/* LCD DMA functions */
+extern int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+ void *data);
+extern void omap_free_lcd_dma(void);
+extern void omap_setup_lcd_dma(void);
+extern void omap_enable_lcd_dma(void);
+extern void omap_stop_lcd_dma(void);
+extern void omap_set_lcd_dma_ext_controller(int external);
+extern void omap_set_lcd_dma_single_transfer(int single);
+extern void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+ int data_type);
+extern void omap_set_lcd_dma_b1_rotation(int rotate);
+extern void omap_set_lcd_dma_b1_vxres(unsigned long vxres);
+extern void omap_set_lcd_dma_b1_mirror(int mirror);
+extern void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale);
+
+extern int omap_lcd_dma_running(void);
+
+#endif /* __MACH_OMAP1_LCD_DMA_H__ */
diff --git a/arch/arm/mach-omap1/include/mach/lcdc.h b/arch/arm/mach-omap1/include/mach/lcdc.h
new file mode 100644
index 00000000..89bd703a
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/lcdc.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-omap1/include/mach/lcdc.h
+ *
+ * Extracted from drivers/video/omap/lcdc.c
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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 __MACH_LCDC_H__
+#define __MACH_LCDC_H__
+
+#define OMAP_LCDC_BASE 0xfffec000
+#define OMAP_LCDC_SIZE 256
+#define OMAP_LCDC_IRQ INT_LCD_CTRL
+
+#define OMAP_LCDC_CONTROL (OMAP_LCDC_BASE + 0x00)
+#define OMAP_LCDC_TIMING0 (OMAP_LCDC_BASE + 0x04)
+#define OMAP_LCDC_TIMING1 (OMAP_LCDC_BASE + 0x08)
+#define OMAP_LCDC_TIMING2 (OMAP_LCDC_BASE + 0x0c)
+#define OMAP_LCDC_STATUS (OMAP_LCDC_BASE + 0x10)
+#define OMAP_LCDC_SUBPANEL (OMAP_LCDC_BASE + 0x14)
+#define OMAP_LCDC_LINE_INT (OMAP_LCDC_BASE + 0x18)
+#define OMAP_LCDC_DISPLAY_STATUS (OMAP_LCDC_BASE + 0x1c)
+
+#define OMAP_LCDC_STAT_DONE (1 << 0)
+#define OMAP_LCDC_STAT_VSYNC (1 << 1)
+#define OMAP_LCDC_STAT_SYNC_LOST (1 << 2)
+#define OMAP_LCDC_STAT_ABC (1 << 3)
+#define OMAP_LCDC_STAT_LINE_INT (1 << 4)
+#define OMAP_LCDC_STAT_FUF (1 << 5)
+#define OMAP_LCDC_STAT_LOADED_PALETTE (1 << 6)
+
+#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)
+#define OMAP_LCDC_CTRL_LCD_TFT (1 << 7)
+#define OMAP_LCDC_CTRL_LINE_IRQ_CLR_SEL (1 << 10)
+
+#define OMAP_LCDC_IRQ_VSYNC (1 << 2)
+#define OMAP_LCDC_IRQ_DONE (1 << 3)
+#define OMAP_LCDC_IRQ_LOADED_PALETTE (1 << 4)
+#define OMAP_LCDC_IRQ_LINE_NIRQ (1 << 5)
+#define OMAP_LCDC_IRQ_LINE (1 << 6)
+#define OMAP_LCDC_IRQ_MASK (((1 << 5) - 1) << 2)
+
+#endif /* __MACH_LCDC_H__ */
diff --git a/arch/arm/mach-omap1/include/mach/memory.h b/arch/arm/mach-omap1/include/mach/memory.h
new file mode 100644
index 00000000..e9b600c1
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/memory.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/memory.h
+ */
+
+#include <plat/memory.h>
diff --git a/arch/arm/mach-omap1/include/mach/mtd-xip.h b/arch/arm/mach-omap1/include/mach/mtd-xip.h
new file mode 100644
index 00000000..f82a8dca
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/mtd-xip.h
@@ -0,0 +1,61 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions.
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
+ *
+ * (c) 2005 MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express or
+ * implied.
+ */
+
+#ifndef __ARCH_OMAP_MTD_XIP_H__
+#define __ARCH_OMAP_MTD_XIP_H__
+
+#include <mach/hardware.h>
+#define OMAP_MPU_TIMER_BASE (0xfffec500)
+#define OMAP_MPU_TIMER_OFFSET 0x100
+
+typedef struct {
+ u32 cntl; /* CNTL_TIMER, R/W */
+ u32 load_tim; /* LOAD_TIM, W */
+ u32 read_tim; /* READ_TIM, R */
+} xip_omap_mpu_timer_regs_t;
+
+#define xip_omap_mpu_timer_base(n) \
+((volatile xip_omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE + \
+ (n)*OMAP_MPU_TIMER_OFFSET))
+
+static inline unsigned long xip_omap_mpu_timer_read(int nr)
+{
+ volatile xip_omap_mpu_timer_regs_t* timer = xip_omap_mpu_timer_base(nr);
+ return timer->read_tim;
+}
+
+#define xip_irqpending() \
+ (omap_readl(OMAP_IH1_ITR) & ~omap_readl(OMAP_IH1_MIR))
+#define xip_currtime() (~xip_omap_mpu_timer_read(0))
+
+/*
+ * It's permitted to do approxmation for xip_elapsed_since macro
+ * (see linux/mtd/xip.h)
+ */
+
+#ifdef CONFIG_MACH_OMAP_PERSEUS2
+#define xip_elapsed_since(x) (signed)((~xip_omap_mpu_timer_read(0) - (x)) / 7)
+#else
+#define xip_elapsed_since(x) (signed)((~xip_omap_mpu_timer_read(0) - (x)) / 6)
+#endif
+
+/*
+ * xip_cpu_idle() is used when waiting for a delay equal or larger than
+ * the system timer tick period. This should put the CPU into idle mode
+ * to save power and to be woken up only when some interrupts are pending.
+ * As above, this should not rely upon standard kernel code.
+ */
+
+#define xip_cpu_idle() asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (1))
+
+#endif /* __ARCH_OMAP_MTD_XIP_H__ */
diff --git a/arch/arm/mach-omap1/include/mach/smp.h b/arch/arm/mach-omap1/include/mach/smp.h
new file mode 100644
index 00000000..80a371c0
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/smp.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/smp.h
+ */
+
+#include <plat/smp.h>
diff --git a/arch/arm/mach-omap1/include/mach/system.h b/arch/arm/mach-omap1/include/mach/system.h
new file mode 100644
index 00000000..a6c1b3a1
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/system.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/system.h
+ */
+
+#include <plat/system.h>
diff --git a/arch/arm/mach-omap1/include/mach/timex.h b/arch/arm/mach-omap1/include/mach/timex.h
new file mode 100644
index 00000000..4793790d
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/timex.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/timex.h
+ */
+
+#include <plat/timex.h>
diff --git a/arch/arm/mach-omap1/include/mach/uncompress.h b/arch/arm/mach-omap1/include/mach/uncompress.h
new file mode 100644
index 00000000..0ff22dc0
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/uncompress.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap1/include/mach/uncompress.h
+ */
+
+#include <plat/uncompress.h>
diff --git a/arch/arm/mach-omap1/include/mach/vmalloc.h b/arch/arm/mach-omap1/include/mach/vmalloc.h
new file mode 100644
index 00000000..22ec4a47
--- /dev/null
+++ b/arch/arm/mach-omap1/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-omap1/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xd8000000UL
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
new file mode 100644
index 00000000..870886a2
--- /dev/null
+++ b/arch/arm/mach-omap1/io.c
@@ -0,0 +1,183 @@
+/*
+ * linux/arch/arm/mach-omap1/io.c
+ *
+ * OMAP1 I/O mapping code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/tlb.h>
+#include <asm/mach/map.h>
+#include <plat/mux.h>
+#include <plat/tc.h>
+
+#include "clock.h"
+
+extern void omap_check_revision(void);
+extern void omap_sram_init(void);
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc omap_io_desc[] __initdata = {
+ {
+ .virtual = OMAP1_IO_VIRT,
+ .pfn = __phys_to_pfn(OMAP1_IO_PHYS),
+ .length = OMAP1_IO_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+static struct map_desc omap7xx_io_desc[] __initdata = {
+ {
+ .virtual = OMAP7XX_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP7XX_DSP_START),
+ .length = OMAP7XX_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP7XX_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP7XX_DSPREG_START),
+ .length = OMAP7XX_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+static struct map_desc omap1510_io_desc[] __initdata = {
+ {
+ .virtual = OMAP1510_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSP_START),
+ .length = OMAP1510_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP1510_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP1510_DSPREG_START),
+ .length = OMAP1510_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+static struct map_desc omap16xx_io_desc[] __initdata = {
+ {
+ .virtual = OMAP16XX_DSP_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSP_START),
+ .length = OMAP16XX_DSP_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = OMAP16XX_DSPREG_BASE,
+ .pfn = __phys_to_pfn(OMAP16XX_DSPREG_START),
+ .length = OMAP16XX_DSPREG_SIZE,
+ .type = MT_DEVICE
+ }
+};
+#endif
+
+/*
+ * Maps common IO regions for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_map_common_io(void)
+{
+ iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc));
+
+ /* Normally devicemaps_init() would flush caches and tlb after
+ * mdesc->map_io(), but we must also do it here because of the CPU
+ * revision check below.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ /* We want to check CPU revision early for cpu_is_omapxxxx() macros.
+ * IO space mapping must be initialized before we can do that.
+ */
+ omap_check_revision();
+
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+ if (cpu_is_omap7xx()) {
+ iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc));
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap15xx()) {
+ iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc));
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+ if (cpu_is_omap16xx()) {
+ iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc));
+ }
+#endif
+
+ omap_sram_init();
+}
+
+/*
+ * Common low-level hardware init for omap1. This should only get called from
+ * board specific init.
+ */
+void __init omap1_init_common_hw(void)
+{
+ /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort
+ * on a Posted Write in the TIPB Bridge".
+ */
+ omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
+ omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
+
+ /* Must init clocks early to assure that timer interrupt works
+ */
+ omap1_clk_init();
+
+ omap1_mux_init();
+}
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+u8 omap_readb(u32 pa)
+{
+ return __raw_readb(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readb);
+
+u16 omap_readw(u32 pa)
+{
+ return __raw_readw(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readw);
+
+u32 omap_readl(u32 pa)
+{
+ return __raw_readl(OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readl);
+
+void omap_writeb(u8 v, u32 pa)
+{
+ __raw_writeb(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writeb);
+
+void omap_writew(u16 v, u32 pa)
+{
+ __raw_writew(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writew);
+
+void omap_writel(u32 v, u32 pa)
+{
+ __raw_writel(v, OMAP1_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
new file mode 100644
index 00000000..5d3da7a6
--- /dev/null
+++ b/arch/arm/mach-omap1/irq.c
@@ -0,0 +1,247 @@
+/*
+ * linux/arch/arm/mach-omap1/irq.c
+ *
+ * Interrupt handler for all OMAP boards
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * Completely re-written to support various OMAP chips with bank specific
+ * interrupt handlers.
+ *
+ * Some snippets of the code taken from the older OMAP interrupt handler
+ * Copyright (C) 2001 RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * GPIO interrupt handler moved to gpio.c by Juha Yrjola
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/gpio.h>
+#include <plat/cpu.h>
+
+#define IRQ_BANK(irq) ((irq) >> 5)
+#define IRQ_BIT(irq) ((irq) & 0x1f)
+
+struct omap_irq_bank {
+ unsigned long base_reg;
+ unsigned long trigger_map;
+ unsigned long wake_enable;
+};
+
+u32 omap_irq_flags;
+static unsigned int irq_bank_count;
+static struct omap_irq_bank *irq_banks;
+
+static inline unsigned int irq_bank_readl(int bank, int offset)
+{
+ return omap_readl(irq_banks[bank].base_reg + offset);
+}
+
+static inline void irq_bank_writel(unsigned long value, int bank, int offset)
+{
+ omap_writel(value, irq_banks[bank].base_reg + offset);
+}
+
+static void omap_ack_irq(struct irq_data *d)
+{
+ if (d->irq > 31)
+ omap_writel(0x1, OMAP_IH2_BASE + IRQ_CONTROL_REG_OFFSET);
+
+ omap_writel(0x1, OMAP_IH1_BASE + IRQ_CONTROL_REG_OFFSET);
+}
+
+static void omap_mask_irq(struct irq_data *d)
+{
+ int bank = IRQ_BANK(d->irq);
+ u32 l;
+
+ l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+ l |= 1 << IRQ_BIT(d->irq);
+ omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+}
+
+static void omap_unmask_irq(struct irq_data *d)
+{
+ int bank = IRQ_BANK(d->irq);
+ u32 l;
+
+ l = omap_readl(irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+ l &= ~(1 << IRQ_BIT(d->irq));
+ omap_writel(l, irq_banks[bank].base_reg + IRQ_MIR_REG_OFFSET);
+}
+
+static void omap_mask_ack_irq(struct irq_data *d)
+{
+ omap_mask_irq(d);
+ omap_ack_irq(d);
+}
+
+static int omap_wake_irq(struct irq_data *d, unsigned int enable)
+{
+ int bank = IRQ_BANK(d->irq);
+
+ if (enable)
+ irq_banks[bank].wake_enable |= IRQ_BIT(d->irq);
+ else
+ irq_banks[bank].wake_enable &= ~IRQ_BIT(d->irq);
+
+ return 0;
+}
+
+
+/*
+ * Allows tuning the IRQ type and priority
+ *
+ * NOTE: There is currently no OMAP fiq handler for Linux. Read the
+ * mailing list threads on FIQ handlers if you are planning to
+ * add a FIQ handler for OMAP.
+ */
+static void omap_irq_set_cfg(int irq, int fiq, int priority, int trigger)
+{
+ signed int bank;
+ unsigned long val, offset;
+
+ bank = IRQ_BANK(irq);
+ /* FIQ is only available on bank 0 interrupts */
+ fiq = bank ? 0 : (fiq & 0x1);
+ val = fiq | ((priority & 0x1f) << 2) | ((trigger & 0x1) << 1);
+ offset = IRQ_ILR0_REG_OFFSET + IRQ_BIT(irq) * 0x4;
+ irq_bank_writel(val, bank, offset);
+}
+
+#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850)
+static struct omap_irq_bank omap7xx_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3f8e22f },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb9c1f2 },
+ { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0x800040f3 },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+static struct omap_irq_bank omap1510_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3febfff },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xffbfffed },
+};
+static struct omap_irq_bank omap310_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3faefc3 },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0x65b3c061 },
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+
+static struct omap_irq_bank omap1610_irq_banks[] = {
+ { .base_reg = OMAP_IH1_BASE, .trigger_map = 0xb3fefe8f },
+ { .base_reg = OMAP_IH2_BASE, .trigger_map = 0xfdb7c1fd },
+ { .base_reg = OMAP_IH2_BASE + 0x100, .trigger_map = 0xffffb7ff },
+ { .base_reg = OMAP_IH2_BASE + 0x200, .trigger_map = 0xffffffff },
+};
+#endif
+
+static struct irq_chip omap_irq_chip = {
+ .name = "MPU",
+ .irq_ack = omap_mask_ack_irq,
+ .irq_mask = omap_mask_irq,
+ .irq_unmask = omap_unmask_irq,
+ .irq_set_wake = omap_wake_irq,
+};
+
+void __init omap_init_irq(void)
+{
+ int i, j;
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ if (cpu_is_omap7xx()) {
+ omap_irq_flags = INT_7XX_IH2_IRQ;
+ irq_banks = omap7xx_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap7xx_irq_banks);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+ if (cpu_is_omap1510()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
+ irq_banks = omap1510_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap1510_irq_banks);
+ }
+ if (cpu_is_omap310()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
+ irq_banks = omap310_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap310_irq_banks);
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+ if (cpu_is_omap16xx()) {
+ omap_irq_flags = INT_1510_IH2_IRQ;
+ irq_banks = omap1610_irq_banks;
+ irq_bank_count = ARRAY_SIZE(omap1610_irq_banks);
+ }
+#endif
+ printk("Total of %i interrupts in %i interrupt banks\n",
+ irq_bank_count * 32, irq_bank_count);
+
+ /* Mask and clear all interrupts */
+ for (i = 0; i < irq_bank_count; i++) {
+ irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET);
+ irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET);
+ }
+
+ /* Clear any pending interrupts */
+ irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET);
+ irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET);
+
+ /* Enable interrupts in global mask */
+ if (cpu_is_omap7xx())
+ irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET);
+
+ /* Install the interrupt handlers for each bank */
+ for (i = 0; i < irq_bank_count; i++) {
+ for (j = i * 32; j < (i + 1) * 32; j++) {
+ int irq_trigger;
+
+ irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
+ omap_irq_set_cfg(j, 0, 0, irq_trigger);
+
+ irq_set_chip_and_handler(j, &omap_irq_chip,
+ handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+ }
+
+ /* Unmask level 2 handler */
+
+ if (cpu_is_omap7xx())
+ omap_unmask_irq(irq_get_irq_data(INT_7XX_IH2_IRQ));
+ else if (cpu_is_omap15xx())
+ omap_unmask_irq(irq_get_irq_data(INT_1510_IH2_IRQ));
+ else if (cpu_is_omap16xx())
+ omap_unmask_irq(irq_get_irq_data(INT_1610_IH2_IRQ));
+}
diff --git a/arch/arm/mach-omap1/lcd_dma.c b/arch/arm/mach-omap1/lcd_dma.c
new file mode 100644
index 00000000..45380935
--- /dev/null
+++ b/arch/arm/mach-omap1/lcd_dma.c
@@ -0,0 +1,451 @@
+/*
+ * linux/arch/arm/mach-omap1/lcd_dma.c
+ *
+ * Extracted from arch/arm/plat-omap/dma.c
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Support functions for the OMAP internal DMA channels.
+ *
+ * This program is free software; you can 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/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/lcdc.h>
+#include <plat/dma.h>
+
+int omap_lcd_dma_running(void)
+{
+ /*
+ * On OMAP1510, internal LCD controller will start the transfer
+ * when it gets enabled, so assume DMA running if LCD enabled.
+ */
+ if (cpu_is_omap15xx())
+ if (omap_readw(OMAP_LCDC_CONTROL) & OMAP_LCDC_CTRL_LCD_EN)
+ return 1;
+
+ /* Check if LCD DMA is running */
+ if (cpu_is_omap16xx())
+ if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
+ return 1;
+
+ return 0;
+}
+
+static struct lcd_dma_info {
+ spinlock_t lock;
+ int reserved;
+ void (*callback)(u16 status, void *data);
+ void *cb_data;
+
+ int active;
+ unsigned long addr, size;
+ int rotate, data_type, xres, yres;
+ int vxres;
+ int mirror;
+ int xscale, yscale;
+ int ext_ctrl;
+ int src_port;
+ int single_transfer;
+} lcd_dma;
+
+void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
+ int data_type)
+{
+ lcd_dma.addr = addr;
+ lcd_dma.data_type = data_type;
+ lcd_dma.xres = fb_xres;
+ lcd_dma.yres = fb_yres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1);
+
+void omap_set_lcd_dma_src_port(int port)
+{
+ lcd_dma.src_port = port;
+}
+
+void omap_set_lcd_dma_ext_controller(int external)
+{
+ lcd_dma.ext_ctrl = external;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
+
+void omap_set_lcd_dma_single_transfer(int single)
+{
+ lcd_dma.single_transfer = single;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
+
+void omap_set_lcd_dma_b1_rotation(int rotate)
+{
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
+ BUG();
+ return;
+ }
+ lcd_dma.rotate = rotate;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
+
+void omap_set_lcd_dma_b1_mirror(int mirror)
+{
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
+ BUG();
+ }
+ lcd_dma.mirror = mirror;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
+
+void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
+{
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "DMA virtual resulotion is not supported "
+ "in 1510 mode\n");
+ BUG();
+ }
+ lcd_dma.vxres = vxres;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
+
+void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
+{
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
+ BUG();
+ }
+ lcd_dma.xscale = xscale;
+ lcd_dma.yscale = yscale;
+}
+EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
+
+static void set_b1_regs(void)
+{
+ unsigned long top, bottom;
+ int es;
+ u16 w;
+ unsigned long en, fn;
+ long ei, fi;
+ unsigned long vxres;
+ unsigned int xscale, yscale;
+
+ switch (lcd_dma.data_type) {
+ case OMAP_DMA_DATA_TYPE_S8:
+ es = 1;
+ break;
+ case OMAP_DMA_DATA_TYPE_S16:
+ es = 2;
+ break;
+ case OMAP_DMA_DATA_TYPE_S32:
+ es = 4;
+ break;
+ default:
+ BUG();
+ return;
+ }
+
+ vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
+ xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
+ yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
+ BUG_ON(vxres < lcd_dma.xres);
+
+#define PIXADDR(x, y) (lcd_dma.addr + \
+ ((y) * vxres * yscale + (x) * xscale) * es)
+#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
+
+ switch (lcd_dma.rotate) {
+ case 0:
+ if (!lcd_dma.mirror) {
+ top = PIXADDR(0, 0);
+ bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+ /* 1510 DMA requires the bottom address to be 2 more
+ * than the actual last memory access location. */
+ if (cpu_is_omap15xx() &&
+ lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
+ bottom += 2;
+ ei = PIXSTEP(0, 0, 1, 0);
+ fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
+ } else {
+ top = PIXADDR(lcd_dma.xres - 1, 0);
+ bottom = PIXADDR(0, lcd_dma.yres - 1);
+ ei = PIXSTEP(1, 0, 0, 0);
+ fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
+ }
+ en = lcd_dma.xres;
+ fn = lcd_dma.yres;
+ break;
+ case 90:
+ if (!lcd_dma.mirror) {
+ top = PIXADDR(0, lcd_dma.yres - 1);
+ bottom = PIXADDR(lcd_dma.xres - 1, 0);
+ ei = PIXSTEP(0, 1, 0, 0);
+ fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
+ } else {
+ top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+ bottom = PIXADDR(0, 0);
+ ei = PIXSTEP(0, 1, 0, 0);
+ fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
+ }
+ en = lcd_dma.yres;
+ fn = lcd_dma.xres;
+ break;
+ case 180:
+ if (!lcd_dma.mirror) {
+ top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+ bottom = PIXADDR(0, 0);
+ ei = PIXSTEP(1, 0, 0, 0);
+ fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
+ } else {
+ top = PIXADDR(0, lcd_dma.yres - 1);
+ bottom = PIXADDR(lcd_dma.xres - 1, 0);
+ ei = PIXSTEP(0, 0, 1, 0);
+ fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
+ }
+ en = lcd_dma.xres;
+ fn = lcd_dma.yres;
+ break;
+ case 270:
+ if (!lcd_dma.mirror) {
+ top = PIXADDR(lcd_dma.xres - 1, 0);
+ bottom = PIXADDR(0, lcd_dma.yres - 1);
+ ei = PIXSTEP(0, 0, 0, 1);
+ fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
+ } else {
+ top = PIXADDR(0, 0);
+ bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
+ ei = PIXSTEP(0, 0, 0, 1);
+ fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
+ }
+ en = lcd_dma.yres;
+ fn = lcd_dma.xres;
+ break;
+ default:
+ BUG();
+ return; /* Suppress warning about uninitialized vars */
+ }
+
+ if (cpu_is_omap15xx()) {
+ omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
+ omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
+ omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
+ omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
+
+ return;
+ }
+
+ /* 1610 regs */
+ omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
+ omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
+ omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
+ omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
+
+ omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
+ omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
+
+ w = omap_readw(OMAP1610_DMA_LCD_CSDP);
+ w &= ~0x03;
+ w |= lcd_dma.data_type;
+ omap_writew(w, OMAP1610_DMA_LCD_CSDP);
+
+ w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+ /* Always set the source port as SDRAM for now*/
+ w &= ~(0x03 << 6);
+ if (lcd_dma.callback != NULL)
+ w |= 1 << 1; /* Block interrupt enable */
+ else
+ w &= ~(1 << 1);
+ omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+ if (!(lcd_dma.rotate || lcd_dma.mirror ||
+ lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
+ return;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CCR);
+ /* Set the double-indexed addressing mode */
+ w |= (0x03 << 12);
+ omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+ omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
+ omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
+ omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
+}
+
+static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
+{
+ u16 w;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+ if (unlikely(!(w & (1 << 3)))) {
+ printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
+ return IRQ_NONE;
+ }
+ /* Ack the IRQ */
+ w |= (1 << 3);
+ omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+ lcd_dma.active = 0;
+ if (lcd_dma.callback != NULL)
+ lcd_dma.callback(w, lcd_dma.cb_data);
+
+ return IRQ_HANDLED;
+}
+
+int omap_request_lcd_dma(void (*callback)(u16 status, void *data),
+ void *data)
+{
+ spin_lock_irq(&lcd_dma.lock);
+ if (lcd_dma.reserved) {
+ spin_unlock_irq(&lcd_dma.lock);
+ printk(KERN_ERR "LCD DMA channel already reserved\n");
+ BUG();
+ return -EBUSY;
+ }
+ lcd_dma.reserved = 1;
+ spin_unlock_irq(&lcd_dma.lock);
+ lcd_dma.callback = callback;
+ lcd_dma.cb_data = data;
+ lcd_dma.active = 0;
+ lcd_dma.single_transfer = 0;
+ lcd_dma.rotate = 0;
+ lcd_dma.vxres = 0;
+ lcd_dma.mirror = 0;
+ lcd_dma.xscale = 0;
+ lcd_dma.yscale = 0;
+ lcd_dma.ext_ctrl = 0;
+ lcd_dma.src_port = 0;
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_request_lcd_dma);
+
+void omap_free_lcd_dma(void)
+{
+ spin_lock(&lcd_dma.lock);
+ if (!lcd_dma.reserved) {
+ spin_unlock(&lcd_dma.lock);
+ printk(KERN_ERR "LCD DMA is not reserved\n");
+ BUG();
+ return;
+ }
+ if (!cpu_is_omap15xx())
+ omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
+ OMAP1610_DMA_LCD_CCR);
+ lcd_dma.reserved = 0;
+ spin_unlock(&lcd_dma.lock);
+}
+EXPORT_SYMBOL(omap_free_lcd_dma);
+
+void omap_enable_lcd_dma(void)
+{
+ u16 w;
+
+ /*
+ * Set the Enable bit only if an external controller is
+ * connected. Otherwise the OMAP internal controller will
+ * start the transfer when it gets enabled.
+ */
+ if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl)
+ return;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+ w |= 1 << 8;
+ omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+
+ lcd_dma.active = 1;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CCR);
+ w |= 1 << 7;
+ omap_writew(w, OMAP1610_DMA_LCD_CCR);
+}
+EXPORT_SYMBOL(omap_enable_lcd_dma);
+
+void omap_setup_lcd_dma(void)
+{
+ BUG_ON(lcd_dma.active);
+ if (!cpu_is_omap15xx()) {
+ /* Set some reasonable defaults */
+ omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
+ omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
+ omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
+ }
+ set_b1_regs();
+ if (!cpu_is_omap15xx()) {
+ u16 w;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CCR);
+ /*
+ * If DMA was already active set the end_prog bit to have
+ * the programmed register set loaded into the active
+ * register set.
+ */
+ w |= 1 << 11; /* End_prog */
+ if (!lcd_dma.single_transfer)
+ w |= (3 << 8); /* Auto_init, repeat */
+ omap_writew(w, OMAP1610_DMA_LCD_CCR);
+ }
+}
+EXPORT_SYMBOL(omap_setup_lcd_dma);
+
+void omap_stop_lcd_dma(void)
+{
+ u16 w;
+
+ lcd_dma.active = 0;
+ if (cpu_is_omap15xx() || !lcd_dma.ext_ctrl)
+ return;
+
+ w = omap_readw(OMAP1610_DMA_LCD_CCR);
+ w &= ~(1 << 7);
+ omap_writew(w, OMAP1610_DMA_LCD_CCR);
+
+ w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+ w &= ~(1 << 8);
+ omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+}
+EXPORT_SYMBOL(omap_stop_lcd_dma);
+
+static int __init omap_init_lcd_dma(void)
+{
+ int r;
+
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ if (cpu_is_omap16xx()) {
+ u16 w;
+
+ /* this would prevent OMAP sleep */
+ w = omap_readw(OMAP1610_DMA_LCD_CTRL);
+ w &= ~(1 << 8);
+ omap_writew(w, OMAP1610_DMA_LCD_CTRL);
+ }
+
+ spin_lock_init(&lcd_dma.lock);
+
+ r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
+ "LCD DMA", NULL);
+ if (r != 0)
+ printk(KERN_ERR "unable to request IRQ for LCD DMA "
+ "(error %d)\n", r);
+
+ return r;
+}
+
+arch_initcall(omap_init_lcd_dma);
+
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c
new file mode 100644
index 00000000..b4f9be52
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-h2p2-debug.c
@@ -0,0 +1,167 @@
+/*
+ * linux/arch/arm/mach-omap1/leds-h2p2-debug.c
+ *
+ * Copyright 2003 by Texas Instruments Incorporated
+ *
+ * There are 16 LEDs on the debug board (all green); four may be used
+ * for logical 'green', 'amber', 'red', and 'blue' (after "claiming").
+ *
+ * The "surfer" expansion board and H2 sample board also have two-color
+ * green+red LEDs (in parallel), used here for timer and idle indicators.
+ */
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <plat/fpga.h>
+#include <mach/gpio.h>
+
+#include "leds.h"
+
+
+#define GPIO_LED_RED 3
+#define GPIO_LED_GREEN OMAP_MPUIO(4)
+
+
+#define LED_STATE_ENABLED 0x01
+#define LED_STATE_CLAIMED 0x02
+#define LED_TIMER_ON 0x04
+
+#define GPIO_IDLE GPIO_LED_GREEN
+#define GPIO_TIMER GPIO_LED_RED
+
+
+void h2p2_dbg_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ static struct h2p2_dbg_fpga __iomem *fpga;
+ static u16 led_state, hw_led_state;
+
+ local_irq_save(flags);
+
+ if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
+ goto done;
+
+ switch (evt) {
+ case led_start:
+ if (!fpga)
+ fpga = ioremap(H2P2_DBG_FPGA_START,
+ H2P2_DBG_FPGA_SIZE);
+ if (fpga) {
+ led_state |= LED_STATE_ENABLED;
+ __raw_writew(~0, &fpga->leds);
+ }
+ break;
+
+ case led_stop:
+ case led_halted:
+ /* all leds off during suspend or shutdown */
+
+ if (! machine_is_omap_perseus2()) {
+ gpio_set_value(GPIO_TIMER, 0);
+ gpio_set_value(GPIO_IDLE, 0);
+ }
+
+ __raw_writew(~0, &fpga->leds);
+ led_state &= ~LED_STATE_ENABLED;
+ if (evt == led_halted) {
+ iounmap(fpga);
+ fpga = NULL;
+ }
+
+ goto done;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ led_state ^= LED_TIMER_ON;
+
+ if (machine_is_omap_perseus2())
+ hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
+ else {
+ gpio_set_value(GPIO_TIMER, led_state & LED_TIMER_ON);
+ goto done;
+ }
+
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (machine_is_omap_perseus2())
+ hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ gpio_set_value(GPIO_IDLE, 1);
+ goto done;
+ }
+
+ break;
+
+ case led_idle_end:
+ if (machine_is_omap_perseus2())
+ hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ gpio_set_value(GPIO_IDLE, 0);
+ goto done;
+ }
+
+ break;
+#endif
+
+ case led_green_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
+ break;
+ case led_green_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
+ break;
+ case led_amber_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
+ break;
+
+ case led_red_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_RED;
+ break;
+ case led_red_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
+ break;
+
+ case led_blue_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
+ break;
+ case led_blue_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
+ break;
+
+ default:
+ break;
+ }
+
+
+ /*
+ * Actually burn the LEDs
+ */
+ if (led_state & LED_STATE_ENABLED)
+ __raw_writew(~hw_led_state, &fpga->leds);
+
+done:
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c
new file mode 100644
index 00000000..9b99c289
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-innovator.c
@@ -0,0 +1,99 @@
+/*
+ * linux/arch/arm/mach-omap1/leds-innovator.c
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void innovator_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = 0;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ hw_led_state = 0;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= 0;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= 0;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~0;
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~0;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= 0;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~0;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= 0;
+ break;
+
+ default:
+ break;
+ }
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c
new file mode 100644
index 00000000..499d7ad8
--- /dev/null
+++ b/arch/arm/mach-omap1/leds-osk.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/mach-omap1/leds-osk.c
+ *
+ * LED driver for OSK with optional Mistral QVGA board
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <mach/gpio.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED (1 << 0)
+#define LED_STATE_CLAIMED (1 << 1)
+static u8 led_state;
+
+#define TIMER_LED (1 << 3) /* Mistral board */
+#define IDLE_LED (1 << 4) /* Mistral board */
+static u8 hw_led_state;
+
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+/* For now, all system indicators require the Mistral board, since that
+ * LED can be manipulated without a task context. This LED is either red,
+ * or green, but not both; it can't give the full "disco led" effect.
+ */
+
+#define GPIO_LED_RED 3
+#define GPIO_LED_GREEN OMAP_MPUIO(4)
+
+static void mistral_setled(void)
+{
+ int red = 0;
+ int green = 0;
+
+ if (hw_led_state & TIMER_LED)
+ red = 1;
+ else if (hw_led_state & IDLE_LED)
+ green = 1;
+ /* else both sides are disabled */
+
+ gpio_set_value(GPIO_LED_GREEN, green);
+ gpio_set_value(GPIO_LED_RED, red);
+}
+
+#endif
+
+void osk_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+ u16 leds;
+
+ local_irq_save(flags);
+
+ if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
+ goto done;
+
+ leds = hw_led_state;
+ switch (evt) {
+ case led_start:
+ led_state |= LED_STATE_ENABLED;
+ hw_led_state = 0;
+ leds = ~0;
+ break;
+
+ case led_halted:
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ hw_led_state = 0;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ leds = ~0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+
+ case led_timer:
+ hw_led_state ^= TIMER_LED;
+ mistral_setled();
+ break;
+
+ case led_idle_start: /* idle == off */
+ hw_led_state &= ~IDLE_LED;
+ mistral_setled();
+ break;
+
+ case led_idle_end:
+ hw_led_state |= IDLE_LED;
+ mistral_setled();
+ break;
+
+#endif /* CONFIG_OMAP_OSK_MISTRAL */
+
+ default:
+ break;
+ }
+
+ leds ^= hw_led_state;
+
+done:
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c
new file mode 100644
index 00000000..22eb11dd
--- /dev/null
+++ b/arch/arm/mach-omap1/leds.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-omap1/leds.c
+ *
+ * OMAP LEDs dispatcher
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <mach/gpio.h>
+#include <plat/mux.h>
+
+#include "leds.h"
+
+static int __init
+omap_leds_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ if (machine_is_omap_innovator())
+ leds_event = innovator_leds_event;
+
+ else if (machine_is_omap_h2()
+ || machine_is_omap_h3()
+ || machine_is_omap_perseus2())
+ leds_event = h2p2_dbg_leds_event;
+
+ else if (machine_is_omap_osk())
+ leds_event = osk_leds_event;
+
+ else
+ return -1;
+
+ if (machine_is_omap_h2()
+ || machine_is_omap_h3()
+#ifdef CONFIG_OMAP_OSK_MISTRAL
+ || machine_is_omap_osk()
+#endif
+ ) {
+
+ /* LED1/LED2 pins can be used as GPIO (as done here), or by
+ * the LPG (works even in deep sleep!), to drive a bicolor
+ * LED on the H2 sample board, and another on the H2/P2
+ * "surfer" expansion board.
+ *
+ * The same pins drive a LED on the OSK Mistral board, but
+ * that's a different kind of LED (just one color at a time).
+ */
+ omap_cfg_reg(P18_1610_GPIO3);
+ if (gpio_request(3, "LED red") == 0)
+ gpio_direction_output(3, 1);
+ else
+ printk(KERN_WARNING "LED: can't get GPIO3/red?\n");
+
+ omap_cfg_reg(MPUIO4);
+ if (gpio_request(OMAP_MPUIO(4), "LED green") == 0)
+ gpio_direction_output(OMAP_MPUIO(4), 1);
+ else
+ printk(KERN_WARNING "LED: can't get MPUIO4/green?\n");
+ }
+
+ leds_event(led_start);
+ return 0;
+}
+
+__initcall(omap_leds_init);
diff --git a/arch/arm/mach-omap1/leds.h b/arch/arm/mach-omap1/leds.h
new file mode 100644
index 00000000..a1e9fedc
--- /dev/null
+++ b/arch/arm/mach-omap1/leds.h
@@ -0,0 +1,3 @@
+extern void innovator_leds_event(led_event_t evt);
+extern void h2p2_dbg_leds_event(led_event_t evt);
+extern void osk_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-omap1/mailbox.c b/arch/arm/mach-omap1/mailbox.c
new file mode 100644
index 00000000..c0e1f48a
--- /dev/null
+++ b/arch/arm/mach-omap1/mailbox.c
@@ -0,0 +1,198 @@
+/*
+ * Mailbox reservation modules for OMAP1
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation
+ * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <plat/mailbox.h>
+
+#define MAILBOX_ARM2DSP1 0x00
+#define MAILBOX_ARM2DSP1b 0x04
+#define MAILBOX_DSP2ARM1 0x08
+#define MAILBOX_DSP2ARM1b 0x0c
+#define MAILBOX_DSP2ARM2 0x10
+#define MAILBOX_DSP2ARM2b 0x14
+#define MAILBOX_ARM2DSP1_Flag 0x18
+#define MAILBOX_DSP2ARM1_Flag 0x1c
+#define MAILBOX_DSP2ARM2_Flag 0x20
+
+static void __iomem *mbox_base;
+
+struct omap_mbox1_fifo {
+ unsigned long cmd;
+ unsigned long data;
+ unsigned long flag;
+};
+
+struct omap_mbox1_priv {
+ struct omap_mbox1_fifo tx_fifo;
+ struct omap_mbox1_fifo rx_fifo;
+};
+
+static inline int mbox_read_reg(size_t ofs)
+{
+ return __raw_readw(mbox_base + ofs);
+}
+
+static inline void mbox_write_reg(u32 val, size_t ofs)
+{
+ __raw_writew(val, mbox_base + ofs);
+}
+
+/* msg */
+static mbox_msg_t omap1_mbox_fifo_read(struct omap_mbox *mbox)
+{
+ struct omap_mbox1_fifo *fifo =
+ &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
+ mbox_msg_t msg;
+
+ msg = mbox_read_reg(fifo->data);
+ msg |= ((mbox_msg_t) mbox_read_reg(fifo->cmd)) << 16;
+
+ return msg;
+}
+
+static void
+omap1_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ struct omap_mbox1_fifo *fifo =
+ &((struct omap_mbox1_priv *)mbox->priv)->tx_fifo;
+
+ mbox_write_reg(msg & 0xffff, fifo->data);
+ mbox_write_reg(msg >> 16, fifo->cmd);
+}
+
+static int omap1_mbox_fifo_empty(struct omap_mbox *mbox)
+{
+ return 0;
+}
+
+static int omap1_mbox_fifo_full(struct omap_mbox *mbox)
+{
+ struct omap_mbox1_fifo *fifo =
+ &((struct omap_mbox1_priv *)mbox->priv)->rx_fifo;
+
+ return mbox_read_reg(fifo->flag);
+}
+
+/* irq */
+static void
+omap1_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+ if (irq == IRQ_RX)
+ enable_irq(mbox->irq);
+}
+
+static void
+omap1_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+ if (irq == IRQ_RX)
+ disable_irq(mbox->irq);
+}
+
+static int
+omap1_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+ if (irq == IRQ_TX)
+ return 0;
+ return 1;
+}
+
+static struct omap_mbox_ops omap1_mbox_ops = {
+ .type = OMAP_MBOX_TYPE1,
+ .fifo_read = omap1_mbox_fifo_read,
+ .fifo_write = omap1_mbox_fifo_write,
+ .fifo_empty = omap1_mbox_fifo_empty,
+ .fifo_full = omap1_mbox_fifo_full,
+ .enable_irq = omap1_mbox_enable_irq,
+ .disable_irq = omap1_mbox_disable_irq,
+ .is_irq = omap1_mbox_is_irq,
+};
+
+/* FIXME: the following struct should be created automatically by the user id */
+
+/* DSP */
+static struct omap_mbox1_priv omap1_mbox_dsp_priv = {
+ .tx_fifo = {
+ .cmd = MAILBOX_ARM2DSP1b,
+ .data = MAILBOX_ARM2DSP1,
+ .flag = MAILBOX_ARM2DSP1_Flag,
+ },
+ .rx_fifo = {
+ .cmd = MAILBOX_DSP2ARM1b,
+ .data = MAILBOX_DSP2ARM1,
+ .flag = MAILBOX_DSP2ARM1_Flag,
+ },
+};
+
+static struct omap_mbox mbox_dsp_info = {
+ .name = "dsp",
+ .ops = &omap1_mbox_ops,
+ .priv = &omap1_mbox_dsp_priv,
+};
+
+static struct omap_mbox *omap1_mboxes[] = { &mbox_dsp_info, NULL };
+
+static int __devinit omap1_mbox_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ int ret;
+ struct omap_mbox **list;
+
+ list = omap1_mboxes;
+ list[0]->irq = platform_get_irq_byname(pdev, "dsp");
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mbox_base = ioremap(mem->start, resource_size(mem));
+ if (!mbox_base)
+ return -ENOMEM;
+
+ ret = omap_mbox_register(&pdev->dev, list);
+ if (ret) {
+ iounmap(mbox_base);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit omap1_mbox_remove(struct platform_device *pdev)
+{
+ omap_mbox_unregister();
+ iounmap(mbox_base);
+ return 0;
+}
+
+static struct platform_driver omap1_mbox_driver = {
+ .probe = omap1_mbox_probe,
+ .remove = __devexit_p(omap1_mbox_remove),
+ .driver = {
+ .name = "omap-mailbox",
+ },
+};
+
+static int __init omap1_mbox_init(void)
+{
+ return platform_driver_register(&omap1_mbox_driver);
+}
+
+static void __exit omap1_mbox_exit(void)
+{
+ platform_driver_unregister(&omap1_mbox_driver);
+}
+
+module_init(omap1_mbox_init);
+module_exit(omap1_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap1 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_ALIAS("platform:omap1-mailbox");
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
new file mode 100644
index 00000000..d9af9811
--- /dev/null
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -0,0 +1,410 @@
+/*
+ * linux/arch/arm/mach-omap1/mcbsp.c
+ *
+ * Copyright (C) 2008 Instituto Nokia de Tecnologia
+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Multichannel mode not supported.
+ */
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <mach/irqs.h>
+#include <plat/dma.h>
+#include <plat/mux.h>
+#include <plat/cpu.h>
+#include <plat/mcbsp.h>
+
+#define DPS_RSTCT2_PER_EN (1 << 0)
+#define DSP_RSTCT2_WD_PER_EN (1 << 1)
+
+static int dsp_use;
+static struct clk *api_clk;
+static struct clk *dsp_clk;
+
+static void omap1_mcbsp_request(unsigned int id)
+{
+ /*
+ * On 1510, 1610 and 1710, McBSP1 and McBSP3
+ * are DSP public peripherals.
+ */
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
+ if (dsp_use++ == 0) {
+ api_clk = clk_get(NULL, "api_ck");
+ dsp_clk = clk_get(NULL, "dsp_ck");
+ if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
+ clk_enable(api_clk);
+ clk_enable(dsp_clk);
+
+ /*
+ * DSP external peripheral reset
+ * FIXME: This should be moved to dsp code
+ */
+ __raw_writew(__raw_readw(DSP_RSTCT2) | DPS_RSTCT2_PER_EN |
+ DSP_RSTCT2_WD_PER_EN, DSP_RSTCT2);
+ }
+ }
+ }
+}
+
+static void omap1_mcbsp_free(unsigned int id)
+{
+ if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
+ if (--dsp_use == 0) {
+ if (!IS_ERR(api_clk)) {
+ clk_disable(api_clk);
+ clk_put(api_clk);
+ }
+ if (!IS_ERR(dsp_clk)) {
+ clk_disable(dsp_clk);
+ clk_put(dsp_clk);
+ }
+ }
+ }
+}
+
+static struct omap_mcbsp_ops omap1_mcbsp_ops = {
+ .request = omap1_mcbsp_request,
+ .free = omap1_mcbsp_free,
+};
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+struct resource omap7xx_mcbsp_res[][6] = {
+ {
+ {
+ .start = OMAP7XX_MCBSP1_BASE,
+ .end = OMAP7XX_MCBSP1_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_7XX_McBSP1RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_7XX_McBSP1TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+ {
+ {
+ .start = OMAP7XX_MCBSP2_BASE,
+ .end = OMAP7XX_MCBSP2_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_7XX_McBSP2RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_7XX_McBSP2TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+};
+
+#define omap7xx_mcbsp_res_0 omap7xx_mcbsp_res[0]
+
+static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = {
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+};
+#define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1])
+#define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res)
+#else
+#define omap7xx_mcbsp_res_0 NULL
+#define omap7xx_mcbsp_pdata NULL
+#define OMAP7XX_MCBSP_RES_SZ 0
+#define OMAP7XX_MCBSP_COUNT 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP15XX
+struct resource omap15xx_mcbsp_res[][6] = {
+ {
+ {
+ .start = OMAP1510_MCBSP1_BASE,
+ .end = OMAP1510_MCBSP1_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_McBSP1RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_McBSP1TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+ {
+ {
+ .start = OMAP1510_MCBSP2_BASE,
+ .end = OMAP1510_MCBSP2_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_1510_SPI_RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_1510_SPI_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+ {
+ {
+ .start = OMAP1510_MCBSP3_BASE,
+ .end = OMAP1510_MCBSP3_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_McBSP3RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_McBSP3TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+};
+
+#define omap15xx_mcbsp_res_0 omap15xx_mcbsp_res[0]
+
+static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+};
+#define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1])
+#define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res)
+#else
+#define omap15xx_mcbsp_res_0 NULL
+#define omap15xx_mcbsp_pdata NULL
+#define OMAP15XX_MCBSP_RES_SZ 0
+#define OMAP15XX_MCBSP_COUNT 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP16XX
+struct resource omap16xx_mcbsp_res[][6] = {
+ {
+ {
+ .start = OMAP1610_MCBSP1_BASE,
+ .end = OMAP1610_MCBSP1_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_McBSP1RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_McBSP1TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+ {
+ {
+ .start = OMAP1610_MCBSP2_BASE,
+ .end = OMAP1610_MCBSP2_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_1610_McBSP2_RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_1610_McBSP2_TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+ {
+ {
+ .start = OMAP1610_MCBSP3_BASE,
+ .end = OMAP1610_MCBSP3_BASE + SZ_256,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "rx",
+ .start = INT_McBSP3RX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "tx",
+ .start = INT_McBSP3TX,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "rx",
+ .start = OMAP_DMA_MCBSP3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .name = "tx",
+ .start = OMAP_DMA_MCBSP3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ },
+};
+
+#define omap16xx_mcbsp_res_0 omap16xx_mcbsp_res[0]
+
+static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+ {
+ .ops = &omap1_mcbsp_ops,
+ },
+};
+#define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1])
+#define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res)
+#else
+#define omap16xx_mcbsp_res_0 NULL
+#define omap16xx_mcbsp_pdata NULL
+#define OMAP16XX_MCBSP_RES_SZ 0
+#define OMAP16XX_MCBSP_COUNT 0
+#endif
+
+static int __init omap1_mcbsp_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ if (cpu_is_omap7xx())
+ omap_mcbsp_count = OMAP7XX_MCBSP_COUNT;
+ else if (cpu_is_omap15xx())
+ omap_mcbsp_count = OMAP15XX_MCBSP_COUNT;
+ else if (cpu_is_omap16xx())
+ omap_mcbsp_count = OMAP16XX_MCBSP_COUNT;
+
+ mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+ GFP_KERNEL);
+ if (!mcbsp_ptr)
+ return -ENOMEM;
+
+ if (cpu_is_omap7xx())
+ omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res_0,
+ OMAP7XX_MCBSP_RES_SZ,
+ omap7xx_mcbsp_pdata,
+ OMAP7XX_MCBSP_COUNT);
+
+ if (cpu_is_omap15xx())
+ omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res_0,
+ OMAP15XX_MCBSP_RES_SZ,
+ omap15xx_mcbsp_pdata,
+ OMAP15XX_MCBSP_COUNT);
+
+ if (cpu_is_omap16xx())
+ omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res_0,
+ OMAP16XX_MCBSP_RES_SZ,
+ omap16xx_mcbsp_pdata,
+ OMAP16XX_MCBSP_COUNT);
+
+ return omap_mcbsp_init();
+}
+
+arch_initcall(omap1_mcbsp_init);
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
new file mode 100644
index 00000000..5fdef7a3
--- /dev/null
+++ b/arch/arm/mach-omap1/mux.c
@@ -0,0 +1,471 @@
+/*
+ * linux/arch/arm/mach-omap1/mux.c
+ *
+ * OMAP1 pin multiplexing configurations
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <asm/system.h>
+
+#include <plat/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+static struct omap_mux_cfg arch_mux_cfg;
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+static struct pin_config __initdata_or_module omap7xx_pins[] = {
+MUX_CFG_7XX("E2_7XX_KBR0", 12, 21, 0, 20, 1, 0)
+MUX_CFG_7XX("J7_7XX_KBR1", 12, 25, 0, 24, 1, 0)
+MUX_CFG_7XX("E1_7XX_KBR2", 12, 29, 0, 28, 1, 0)
+MUX_CFG_7XX("F3_7XX_KBR3", 13, 1, 0, 0, 1, 0)
+MUX_CFG_7XX("D2_7XX_KBR4", 13, 5, 0, 4, 1, 0)
+MUX_CFG_7XX("C2_7XX_KBC0", 13, 9, 0, 8, 1, 0)
+MUX_CFG_7XX("D3_7XX_KBC1", 13, 13, 0, 12, 1, 0)
+MUX_CFG_7XX("E4_7XX_KBC2", 13, 17, 0, 16, 1, 0)
+MUX_CFG_7XX("F4_7XX_KBC3", 13, 21, 0, 20, 1, 0)
+MUX_CFG_7XX("E3_7XX_KBC4", 13, 25, 0, 24, 1, 0)
+
+MUX_CFG_7XX("AA17_7XX_USB_DM", 2, 21, 0, 20, 0, 0)
+MUX_CFG_7XX("W16_7XX_USB_PU_EN", 2, 25, 0, 24, 0, 0)
+MUX_CFG_7XX("W17_7XX_USB_VBUSI", 2, 29, 6, 28, 1, 0)
+MUX_CFG_7XX("W18_7XX_USB_DMCK_OUT",3, 3, 1, 2, 0, 0)
+MUX_CFG_7XX("W19_7XX_USB_DCRST", 3, 7, 1, 6, 0, 0)
+
+/* MMC Pins */
+MUX_CFG_7XX("MMC_7XX_CMD", 2, 9, 0, 8, 1, 0)
+MUX_CFG_7XX("MMC_7XX_CLK", 2, 13, 0, 12, 1, 0)
+MUX_CFG_7XX("MMC_7XX_DAT0", 2, 17, 0, 16, 1, 0)
+
+/* I2C interface */
+MUX_CFG_7XX("I2C_7XX_SCL", 5, 1, 0, 0, 1, 0)
+MUX_CFG_7XX("I2C_7XX_SDA", 5, 5, 0, 0, 1, 0)
+
+/* SPI pins */
+MUX_CFG_7XX("SPI_7XX_1", 6, 5, 4, 4, 1, 0)
+MUX_CFG_7XX("SPI_7XX_2", 6, 9, 4, 8, 1, 0)
+MUX_CFG_7XX("SPI_7XX_3", 6, 13, 4, 12, 1, 0)
+MUX_CFG_7XX("SPI_7XX_4", 6, 17, 4, 16, 1, 0)
+MUX_CFG_7XX("SPI_7XX_5", 8, 25, 0, 24, 0, 0)
+MUX_CFG_7XX("SPI_7XX_6", 9, 5, 0, 4, 0, 0)
+
+/* UART pins */
+MUX_CFG_7XX("UART_7XX_1", 3, 21, 0, 20, 0, 0)
+MUX_CFG_7XX("UART_7XX_2", 8, 1, 6, 0, 0, 0)
+};
+#define OMAP7XX_PINS_SZ ARRAY_SIZE(omap7xx_pins)
+#else
+#define omap7xx_pins NULL
+#define OMAP7XX_PINS_SZ 0
+#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
+
+#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
+static struct pin_config __initdata_or_module omap1xxx_pins[] = {
+/*
+ * description mux mode mux pull pull pull pu_pd pu dbg
+ * reg offset mode reg bit ena reg
+ */
+MUX_CFG("UART1_TX", 9, 21, 1, 2, 3, 0, NA, 0, 0)
+MUX_CFG("UART1_RTS", 9, 12, 1, 2, 0, 0, NA, 0, 0)
+
+/* UART2 (COM_UART_GATING), conflicts with USB2 */
+MUX_CFG("UART2_TX", C, 27, 1, 3, 3, 0, NA, 0, 0)
+MUX_CFG("UART2_RX", C, 18, 0, 3, 1, 1, NA, 0, 0)
+MUX_CFG("UART2_CTS", C, 21, 0, 3, 1, 1, NA, 0, 0)
+MUX_CFG("UART2_RTS", C, 24, 1, 3, 2, 0, NA, 0, 0)
+
+/* UART3 (GIGA_UART_GATING) */
+MUX_CFG("UART3_TX", 6, 0, 1, 0, 30, 0, NA, 0, 0)
+MUX_CFG("UART3_RX", 6, 3, 0, 0, 31, 1, NA, 0, 0)
+MUX_CFG("UART3_CTS", 5, 12, 2, 0, 24, 0, NA, 0, 0)
+MUX_CFG("UART3_RTS", 5, 15, 2, 0, 25, 0, NA, 0, 0)
+MUX_CFG("UART3_CLKREQ", 9, 27, 0, 2, 5, 0, NA, 0, 0)
+MUX_CFG("UART3_BCLK", A, 0, 0, 2, 6, 0, NA, 0, 0)
+MUX_CFG("Y15_1610_UART3_RTS", A, 0, 1, 2, 6, 0, NA, 0, 0)
+
+/* PWT & PWL, conflicts with UART3 */
+MUX_CFG("PWT", 6, 0, 2, 0, 30, 0, NA, 0, 0)
+MUX_CFG("PWL", 6, 3, 1, 0, 31, 1, NA, 0, 0)
+
+/* USB internal master generic */
+MUX_CFG("R18_USB_VBUS", 7, 9, 2, 1, 11, 0, NA, 0, 1)
+MUX_CFG("R18_1510_USB_GPIO0", 7, 9, 0, 1, 11, 1, NA, 0, 1)
+/* works around erratum: W4_USB_PUEN and W4_USB_PUDIS are switched! */
+MUX_CFG("W4_USB_PUEN", D, 3, 3, 3, 5, 1, NA, 0, 1)
+MUX_CFG("W4_USB_CLKO", D, 3, 1, 3, 5, 0, NA, 0, 1)
+MUX_CFG("W4_USB_HIGHZ", D, 3, 4, 3, 5, 0, 3, 0, 1)
+MUX_CFG("W4_GPIO58", D, 3, 7, 3, 5, 0, 3, 0, 1)
+
+/* USB1 master */
+MUX_CFG("USB1_SUSP", 8, 27, 2, 1, 27, 0, NA, 0, 1)
+MUX_CFG("USB1_SE0", 9, 0, 2, 1, 28, 0, NA, 0, 1)
+MUX_CFG("W13_1610_USB1_SE0", 9, 0, 4, 1, 28, 0, NA, 0, 1)
+MUX_CFG("USB1_TXEN", 9, 3, 2, 1, 29, 0, NA, 0, 1)
+MUX_CFG("USB1_TXD", 9, 24, 1, 2, 4, 0, NA, 0, 1)
+MUX_CFG("USB1_VP", A, 3, 1, 2, 7, 0, NA, 0, 1)
+MUX_CFG("USB1_VM", A, 6, 1, 2, 8, 0, NA, 0, 1)
+MUX_CFG("USB1_RCV", A, 9, 1, 2, 9, 0, NA, 0, 1)
+MUX_CFG("USB1_SPEED", A, 12, 2, 2, 10, 0, NA, 0, 1)
+MUX_CFG("R13_1610_USB1_SPEED", A, 12, 5, 2, 10, 0, NA, 0, 1)
+MUX_CFG("R13_1710_USB1_SEO", A, 12, 5, 2, 10, 0, NA, 0, 1)
+
+/* USB2 master */
+MUX_CFG("USB2_SUSP", B, 3, 1, 2, 17, 0, NA, 0, 1)
+MUX_CFG("USB2_VP", B, 6, 1, 2, 18, 0, NA, 0, 1)
+MUX_CFG("USB2_TXEN", B, 9, 1, 2, 19, 0, NA, 0, 1)
+MUX_CFG("USB2_VM", C, 18, 1, 3, 0, 0, NA, 0, 1)
+MUX_CFG("USB2_RCV", C, 21, 1, 3, 1, 0, NA, 0, 1)
+MUX_CFG("USB2_SE0", C, 24, 2, 3, 2, 0, NA, 0, 1)
+MUX_CFG("USB2_TXD", C, 27, 2, 3, 3, 0, NA, 0, 1)
+
+/* OMAP-1510 GPIO */
+MUX_CFG("R18_1510_GPIO0", 7, 9, 0, 1, 11, 1, 0, 0, 1)
+MUX_CFG("R19_1510_GPIO1", 7, 6, 0, 1, 10, 1, 0, 0, 1)
+MUX_CFG("M14_1510_GPIO2", 7, 3, 0, 1, 9, 1, 0, 0, 1)
+
+/* OMAP1610 GPIO */
+MUX_CFG("P18_1610_GPIO3", 7, 0, 0, 1, 8, 0, NA, 0, 1)
+MUX_CFG("Y15_1610_GPIO17", A, 0, 7, 2, 6, 0, NA, 0, 1)
+
+/* OMAP-1710 GPIO */
+MUX_CFG("R18_1710_GPIO0", 7, 9, 0, 1, 11, 1, 1, 1, 1)
+MUX_CFG("V2_1710_GPIO10", F, 27, 1, 4, 3, 1, 4, 1, 1)
+MUX_CFG("N21_1710_GPIO14", 6, 9, 0, 1, 1, 1, 1, 1, 1)
+MUX_CFG("W15_1710_GPIO40", 9, 27, 7, 2, 5, 1, 2, 1, 1)
+
+/* MPUIO */
+MUX_CFG("MPUIO2", 7, 18, 0, 1, 14, 1, NA, 0, 1)
+MUX_CFG("N15_1610_MPUIO2", 7, 18, 0, 1, 14, 1, 1, 0, 1)
+MUX_CFG("MPUIO4", 7, 15, 0, 1, 13, 1, NA, 0, 1)
+MUX_CFG("MPUIO5", 7, 12, 0, 1, 12, 1, NA, 0, 1)
+
+MUX_CFG("T20_1610_MPUIO5", 7, 12, 0, 1, 12, 0, 3, 0, 1)
+MUX_CFG("W11_1610_MPUIO6", 10, 15, 2, 3, 8, 0, 3, 0, 1)
+MUX_CFG("V10_1610_MPUIO7", A, 24, 2, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W11_1610_MPUIO9", 10, 15, 1, 3, 8, 0, 3, 0, 1)
+MUX_CFG("V10_1610_MPUIO10", A, 24, 1, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W10_1610_MPUIO11", A, 18, 2, 2, 11, 0, 2, 0, 1)
+MUX_CFG("E20_1610_MPUIO13", 3, 21, 1, 0, 7, 0, 0, 0, 1)
+MUX_CFG("U20_1610_MPUIO14", 9, 6, 6, 0, 30, 0, 0, 0, 1)
+MUX_CFG("E19_1610_MPUIO15", 3, 18, 1, 0, 6, 0, 0, 0, 1)
+
+/* MCBSP2 */
+MUX_CFG("MCBSP2_CLKR", C, 6, 0, 2, 27, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_CLKX", C, 9, 0, 2, 29, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_DR", C, 0, 0, 2, 26, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_DX", C, 15, 0, 2, 31, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_FSR", C, 12, 0, 2, 30, 1, NA, 0, 1)
+MUX_CFG("MCBSP2_FSX", C, 3, 0, 2, 27, 1, NA, 0, 1)
+
+/* MCBSP3 NOTE: Mode must 1 for clock */
+MUX_CFG("MCBSP3_CLKX", 9, 3, 1, 1, 29, 0, NA, 0, 1)
+
+/* Misc ballouts */
+MUX_CFG("BALLOUT_V8_ARMIO3", B, 18, 0, 2, 25, 1, NA, 0, 1)
+MUX_CFG("N20_HDQ", 6, 18, 1, 1, 4, 0, 1, 4, 0)
+
+/* OMAP-1610 MMC2 */
+MUX_CFG("W8_1610_MMC2_DAT0", B, 21, 6, 2, 23, 1, 2, 1, 1)
+MUX_CFG("V8_1610_MMC2_DAT1", B, 27, 6, 2, 25, 1, 2, 1, 1)
+MUX_CFG("W15_1610_MMC2_DAT2", 9, 12, 6, 2, 5, 1, 2, 1, 1)
+MUX_CFG("R10_1610_MMC2_DAT3", B, 18, 6, 2, 22, 1, 2, 1, 1)
+MUX_CFG("Y10_1610_MMC2_CLK", B, 3, 6, 2, 17, 0, 2, 0, 1)
+MUX_CFG("Y8_1610_MMC2_CMD", B, 24, 6, 2, 24, 1, 2, 1, 1)
+MUX_CFG("V9_1610_MMC2_CMDDIR", B, 12, 6, 2, 20, 0, 2, 1, 1)
+MUX_CFG("V5_1610_MMC2_DATDIR0", B, 15, 6, 2, 21, 0, 2, 1, 1)
+MUX_CFG("W19_1610_MMC2_DATDIR1", 8, 15, 6, 1, 23, 0, 1, 1, 1)
+MUX_CFG("R18_1610_MMC2_CLKIN", 7, 9, 6, 1, 11, 0, 1, 11, 1)
+
+/* OMAP-1610 External Trace Interface */
+MUX_CFG("M19_1610_ETM_PSTAT0", 5, 27, 1, 0, 29, 0, 0, 0, 1)
+MUX_CFG("L15_1610_ETM_PSTAT1", 5, 24, 1, 0, 28, 0, 0, 0, 1)
+MUX_CFG("L18_1610_ETM_PSTAT2", 5, 21, 1, 0, 27, 0, 0, 0, 1)
+MUX_CFG("L19_1610_ETM_D0", 5, 18, 1, 0, 26, 0, 0, 0, 1)
+MUX_CFG("J19_1610_ETM_D6", 5, 0, 1, 0, 20, 0, 0, 0, 1)
+MUX_CFG("J18_1610_ETM_D7", 5, 27, 1, 0, 19, 0, 0, 0, 1)
+
+/* OMAP16XX GPIO */
+MUX_CFG("P20_1610_GPIO4", 6, 27, 0, 1, 7, 0, 1, 1, 1)
+MUX_CFG("V9_1610_GPIO7", B, 12, 1, 2, 20, 0, 2, 1, 1)
+MUX_CFG("W8_1610_GPIO9", B, 21, 0, 2, 23, 0, 2, 1, 1)
+MUX_CFG("N20_1610_GPIO11", 6, 18, 0, 1, 4, 0, 1, 1, 1)
+MUX_CFG("N19_1610_GPIO13", 6, 12, 0, 1, 2, 0, 1, 1, 1)
+MUX_CFG("P10_1610_GPIO22", C, 0, 7, 2, 26, 0, 2, 1, 1)
+MUX_CFG("V5_1610_GPIO24", B, 15, 7, 2, 21, 0, 2, 1, 1)
+MUX_CFG("AA20_1610_GPIO_41", 9, 9, 7, 1, 31, 0, 1, 1, 1)
+MUX_CFG("W19_1610_GPIO48", 8, 15, 7, 1, 23, 1, 1, 0, 1)
+MUX_CFG("M7_1610_GPIO62", 10, 0, 0, 4, 24, 0, 4, 0, 1)
+MUX_CFG("V14_16XX_GPIO37", 9, 18, 7, 2, 2, 0, 2, 2, 0)
+MUX_CFG("R9_16XX_GPIO18", C, 18, 7, 3, 0, 0, 3, 0, 0)
+MUX_CFG("L14_16XX_GPIO49", 6, 3, 7, 0, 31, 0, 0, 31, 0)
+
+/* OMAP-1610 uWire */
+MUX_CFG("V19_1610_UWIRE_SCLK", 8, 6, 0, 1, 20, 0, 1, 1, 1)
+MUX_CFG("U18_1610_UWIRE_SDI", 8, 0, 0, 1, 18, 0, 1, 1, 1)
+MUX_CFG("W21_1610_UWIRE_SDO", 8, 3, 0, 1, 19, 0, 1, 1, 1)
+MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1)
+MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1)
+MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1)
+
+/* OMAP-1610 SPI */
+MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1)
+MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1)
+MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1)
+MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1)
+MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1)
+MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1)
+MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1)
+MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1)
+MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1)
+
+/* OMAP-1610 Flash */
+MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1)
+
+/* First MMC interface, same on 1510, 1610 and 1710 */
+MUX_CFG("MMC_CMD", A, 27, 0, 2, 15, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT1", A, 24, 0, 2, 14, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT2", A, 18, 0, 2, 12, 1, 2, 1, 1)
+MUX_CFG("MMC_DAT0", B, 0, 0, 2, 16, 1, 2, 1, 1)
+MUX_CFG("MMC_CLK", A, 21, 0, NA, 0, 0, NA, 0, 1)
+MUX_CFG("MMC_DAT3", 10, 15, 0, 3, 8, 1, 3, 1, 1)
+MUX_CFG("M15_1710_MMC_CLKI", 6, 21, 2, 0, 0, 0, NA, 0, 1)
+MUX_CFG("P19_1710_MMC_CMDDIR", 6, 24, 6, 0, 0, 0, NA, 0, 1)
+MUX_CFG("P20_1710_MMC_DATDIR0", 6, 27, 5, 0, 0, 0, NA, 0, 1)
+
+/* OMAP-1610 USB0 alternate configuration */
+MUX_CFG("W9_USB0_TXEN", B, 9, 5, 2, 19, 0, 2, 0, 1)
+MUX_CFG("AA9_USB0_VP", B, 6, 5, 2, 18, 0, 2, 0, 1)
+MUX_CFG("Y5_USB0_RCV", C, 21, 5, 3, 1, 0, 1, 0, 1)
+MUX_CFG("R9_USB0_VM", C, 18, 5, 3, 0, 0, 3, 0, 1)
+MUX_CFG("V6_USB0_TXD", C, 27, 5, 3, 3, 0, 3, 0, 1)
+MUX_CFG("W5_USB0_SE0", C, 24, 5, 3, 2, 0, 3, 0, 1)
+MUX_CFG("V9_USB0_SPEED", B, 12, 5, 2, 20, 0, 2, 0, 1)
+MUX_CFG("Y10_USB0_SUSP", B, 3, 5, 2, 17, 0, 2, 0, 1)
+
+/* USB2 interface */
+MUX_CFG("W9_USB2_TXEN", B, 9, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("AA9_USB2_VP", B, 6, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("Y5_USB2_RCV", C, 21, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("R9_USB2_VM", C, 18, 1, NA, 0, 0, NA, 0, 1)
+MUX_CFG("V6_USB2_TXD", C, 27, 2, NA, 0, 0, NA, 0, 1)
+MUX_CFG("W5_USB2_SE0", C, 24, 2, NA, 0, 0, NA, 0, 1)
+
+/* 16XX UART */
+MUX_CFG("R13_1610_UART1_TX", A, 12, 6, 2, 10, 0, 2, 10, 1)
+MUX_CFG("V14_16XX_UART1_RX", 9, 18, 0, 2, 2, 0, 2, 2, 1)
+MUX_CFG("R14_1610_UART1_CTS", 9, 15, 0, 2, 1, 0, 2, 1, 1)
+MUX_CFG("AA15_1610_UART1_RTS", 9, 12, 1, 2, 0, 0, 2, 0, 1)
+MUX_CFG("R9_16XX_UART2_RX", C, 18, 0, 3, 0, 0, 3, 0, 1)
+MUX_CFG("L14_16XX_UART3_RX", 6, 3, 0, 0, 31, 0, 0, 31, 1)
+
+/* I2C interface */
+MUX_CFG("I2C_SCL", 7, 24, 0, NA, 0, 0, NA, 0, 0)
+MUX_CFG("I2C_SDA", 7, 27, 0, NA, 0, 0, NA, 0, 0)
+
+/* Keypad */
+MUX_CFG("F18_1610_KBC0", 3, 15, 0, 0, 5, 1, 0, 0, 0)
+MUX_CFG("D20_1610_KBC1", 3, 12, 0, 0, 4, 1, 0, 0, 0)
+MUX_CFG("D19_1610_KBC2", 3, 9, 0, 0, 3, 1, 0, 0, 0)
+MUX_CFG("E18_1610_KBC3", 3, 6, 0, 0, 2, 1, 0, 0, 0)
+MUX_CFG("C21_1610_KBC4", 3, 3, 0, 0, 1, 1, 0, 0, 0)
+MUX_CFG("G18_1610_KBR0", 4, 0, 0, 0, 10, 1, 0, 1, 0)
+MUX_CFG("F19_1610_KBR1", 3, 27, 0, 0, 9, 1, 0, 1, 0)
+MUX_CFG("H14_1610_KBR2", 3, 24, 0, 0, 8, 1, 0, 1, 0)
+MUX_CFG("E20_1610_KBR3", 3, 21, 0, 0, 7, 1, 0, 1, 0)
+MUX_CFG("E19_1610_KBR4", 3, 18, 0, 0, 6, 1, 0, 1, 0)
+MUX_CFG("N19_1610_KBR5", 6, 12, 1, 1, 2, 1, 1, 1, 0)
+
+/* Power management */
+MUX_CFG("T20_1610_LOW_PWR", 7, 12, 1, NA, 0, 0, NA, 0, 0)
+
+/* MCLK Settings */
+MUX_CFG("V5_1710_MCLK_ON", B, 15, 0, NA, 0, 0, NA, 0, 0)
+MUX_CFG("V5_1710_MCLK_OFF", B, 15, 6, NA, 0, 0, NA, 0, 0)
+MUX_CFG("R10_1610_MCLK_ON", B, 18, 0, NA, 22, 0, NA, 1, 0)
+MUX_CFG("R10_1610_MCLK_OFF", B, 18, 6, 2, 22, 1, 2, 1, 1)
+
+/* CompactFlash controller, conflicts with MMC1 */
+MUX_CFG("P11_1610_CF_CD2", A, 27, 3, 2, 15, 1, 2, 1, 1)
+MUX_CFG("R11_1610_CF_IOIS16", B, 0, 3, 2, 16, 1, 2, 1, 1)
+MUX_CFG("V10_1610_CF_IREQ", A, 24, 3, 2, 14, 0, 2, 0, 1)
+MUX_CFG("W10_1610_CF_RESET", A, 18, 3, 2, 12, 1, 2, 1, 1)
+MUX_CFG("W11_1610_CF_CD1", 10, 15, 3, 3, 8, 1, 3, 1, 1)
+
+/* parallel camera */
+MUX_CFG("J15_1610_CAM_LCLK", 4, 24, 0, 0, 18, 1, 0, 0, 0)
+MUX_CFG("J18_1610_CAM_D7", 4, 27, 0, 0, 19, 1, 0, 0, 0)
+MUX_CFG("J19_1610_CAM_D6", 5, 0, 0, 0, 20, 1, 0, 0, 0)
+MUX_CFG("J14_1610_CAM_D5", 5, 3, 0, 0, 21, 1, 0, 0, 0)
+MUX_CFG("K18_1610_CAM_D4", 5, 6, 0, 0, 22, 1, 0, 0, 0)
+MUX_CFG("K19_1610_CAM_D3", 5, 9, 0, 0, 23, 1, 0, 0, 0)
+MUX_CFG("K15_1610_CAM_D2", 5, 12, 0, 0, 24, 1, 0, 0, 0)
+MUX_CFG("K14_1610_CAM_D1", 5, 15, 0, 0, 25, 1, 0, 0, 0)
+MUX_CFG("L19_1610_CAM_D0", 5, 18, 0, 0, 26, 1, 0, 0, 0)
+MUX_CFG("L18_1610_CAM_VS", 5, 21, 0, 0, 27, 1, 0, 0, 0)
+MUX_CFG("L15_1610_CAM_HS", 5, 24, 0, 0, 28, 1, 0, 0, 0)
+MUX_CFG("M19_1610_CAM_RSTZ", 5, 27, 0, 0, 29, 0, 0, 0, 0)
+MUX_CFG("Y15_1610_CAM_OUTCLK", A, 0, 6, 2, 6, 0, 2, 0, 0)
+
+/* serial camera */
+MUX_CFG("H19_1610_CAM_EXCLK", 4, 21, 0, 0, 17, 0, 0, 0, 0)
+ /* REVISIT 5912 spec sez CCP_* can't pullup or pulldown ... ? */
+MUX_CFG("Y12_1610_CCP_CLKP", 8, 18, 6, 1, 24, 1, 1, 0, 0)
+MUX_CFG("W13_1610_CCP_CLKM", 9, 0, 6, 1, 28, 1, 1, 0, 0)
+MUX_CFG("W14_1610_CCP_DATAP", 9, 24, 6, 2, 4, 1, 2, 0, 0)
+MUX_CFG("Y14_1610_CCP_DATAM", 9, 21, 6, 2, 3, 1, 2, 0, 0)
+};
+#define OMAP1XXX_PINS_SZ ARRAY_SIZE(omap1xxx_pins)
+#else
+#define omap1xxx_pins NULL
+#define OMAP1XXX_PINS_SZ 0
+#endif /* CONFIG_ARCH_OMAP15XX || CONFIG_ARCH_OMAP16XX */
+
+static int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
+{
+ static DEFINE_SPINLOCK(mux_spin_lock);
+ unsigned long flags;
+ unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
+ pull_orig = 0, pull = 0;
+ unsigned int mask, warn = 0;
+
+ /* Check the mux register in question */
+ if (cfg->mux_reg) {
+ unsigned tmp1, tmp2;
+
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ reg_orig = omap_readl(cfg->mux_reg);
+
+ /* The mux registers always seem to be 3 bits long */
+ mask = (0x7 << cfg->mask_offset);
+ tmp1 = reg_orig & mask;
+ reg = reg_orig & ~mask;
+
+ tmp2 = (cfg->mask << cfg->mask_offset);
+ reg |= tmp2;
+
+ if (tmp1 != tmp2)
+ warn = 1;
+
+ omap_writel(reg, cfg->mux_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+ }
+
+ /* Check for pull up or pull down selection on 1610 */
+ if (!cpu_is_omap15xx()) {
+ if (cfg->pu_pd_reg && cfg->pull_val) {
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ pu_pd_orig = omap_readl(cfg->pu_pd_reg);
+ mask = 1 << cfg->pull_bit;
+
+ if (cfg->pu_pd_val) {
+ if (!(pu_pd_orig & mask))
+ warn = 1;
+ /* Use pull up */
+ pu_pd = pu_pd_orig | mask;
+ } else {
+ if (pu_pd_orig & mask)
+ warn = 1;
+ /* Use pull down */
+ pu_pd = pu_pd_orig & ~mask;
+ }
+ omap_writel(pu_pd, cfg->pu_pd_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+ }
+ }
+
+ /* Check for an associated pull down register */
+ if (cfg->pull_reg) {
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ pull_orig = omap_readl(cfg->pull_reg);
+ mask = 1 << cfg->pull_bit;
+
+ if (cfg->pull_val) {
+ if (pull_orig & mask)
+ warn = 1;
+ /* Low bit = pull enabled */
+ pull = pull_orig & ~mask;
+ } else {
+ if (!(pull_orig & mask))
+ warn = 1;
+ /* High bit = pull disabled */
+ pull = pull_orig | mask;
+ }
+
+ omap_writel(pull, cfg->pull_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+ }
+
+ if (warn) {
+#ifdef CONFIG_OMAP_MUX_WARNINGS
+ printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
+#endif
+ }
+
+#ifdef CONFIG_OMAP_MUX_DEBUG
+ if (cfg->debug || warn) {
+ printk("MUX: Setting register %s\n", cfg->name);
+ printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
+ cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
+
+ if (!cpu_is_omap15xx()) {
+ if (cfg->pu_pd_reg && cfg->pull_val) {
+ printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
+ cfg->pu_pd_name, cfg->pu_pd_reg,
+ pu_pd_orig, pu_pd);
+ }
+ }
+
+ if (cfg->pull_reg)
+ printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
+ cfg->pull_name, cfg->pull_reg, pull_orig, pull);
+ }
+#endif
+
+#ifdef CONFIG_OMAP_MUX_WARNINGS
+ return warn ? -ETXTBSY : 0;
+#else
+ return 0;
+#endif
+}
+
+int __init omap1_mux_init(void)
+{
+ if (cpu_is_omap7xx()) {
+ arch_mux_cfg.pins = omap7xx_pins;
+ arch_mux_cfg.size = OMAP7XX_PINS_SZ;
+ arch_mux_cfg.cfg_reg = omap1_cfg_reg;
+ }
+
+ if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
+ arch_mux_cfg.pins = omap1xxx_pins;
+ arch_mux_cfg.size = OMAP1XXX_PINS_SZ;
+ arch_mux_cfg.cfg_reg = omap1_cfg_reg;
+ }
+
+ return omap_mux_register(&arch_mux_cfg);
+}
+
+#endif
diff --git a/arch/arm/mach-omap1/opp.h b/arch/arm/mach-omap1/opp.h
new file mode 100644
index 00000000..07074d79
--- /dev/null
+++ b/arch/arm/mach-omap1/opp.h
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/arm/mach-omap1/opp.h
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP1_OPP_H
+#define __ARCH_ARM_MACH_OMAP1_OPP_H
+
+#include <linux/types.h>
+
+struct mpu_rate {
+ unsigned long rate;
+ unsigned long xtal;
+ unsigned long pll_rate;
+ __u16 ckctl_val;
+ __u16 dpllctl_val;
+};
+
+extern struct mpu_rate omap1_rate_table[];
+
+#endif
diff --git a/arch/arm/mach-omap1/opp_data.c b/arch/arm/mach-omap1/opp_data.c
new file mode 100644
index 00000000..75a54651
--- /dev/null
+++ b/arch/arm/mach-omap1/opp_data.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/arm/mach-omap1/opp_data.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "opp.h"
+
+/*-------------------------------------------------------------------------
+ * Omap1 MPU rate table
+ *-------------------------------------------------------------------------*/
+struct mpu_rate omap1_rate_table[] = {
+ /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
+ * NOTE: Comment order here is different from bits in CKCTL value:
+ * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
+ */
+#if defined(CONFIG_OMAP_ARM_216MHZ)
+ { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_195MHZ)
+ { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_192MHZ)
+ { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
+ { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
+ { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
+ { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/4/4/8/8/8 */
+ { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_182MHZ)
+ { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_168MHZ)
+ { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
+#endif
+#if defined(CONFIG_OMAP_ARM_150MHZ)
+ { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_120MHZ)
+ { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
+#endif
+#if defined(CONFIG_OMAP_ARM_96MHZ)
+ { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_60MHZ)
+ { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
+#endif
+#if defined(CONFIG_OMAP_ARM_30MHZ)
+ { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
+#endif
+ { 0, 0, 0, 0, 0 },
+};
+
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
new file mode 100644
index 00000000..98ba9784
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.c
@@ -0,0 +1,730 @@
+/*
+ * linux/arch/arm/mach-omap1/pm.c
+ *
+ * OMAP Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Modified for the OMAP1510 by David Singleton:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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/suspend.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/atomic.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+#include <plat/cpu.h>
+#include <mach/irqs.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/tc.h>
+#include <plat/mux.h>
+#include <plat/dma.h>
+#include <plat/dmtimer.h>
+
+#include "pm.h"
+
+static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
+static unsigned short dsp_sleep_save[DSP_SLEEP_SAVE_SIZE];
+static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
+static unsigned int mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_SIZE];
+static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
+static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
+
+#ifdef CONFIG_OMAP_32K_TIMER
+
+static unsigned short enable_dyn_sleep = 1;
+
+static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%hu\n", enable_dyn_sleep);
+}
+
+static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char * buf, size_t n)
+{
+ unsigned short value;
+ if (sscanf(buf, "%hu", &value) != 1 ||
+ (value != 0 && value != 1)) {
+ printk(KERN_ERR "idle_sleep_store: Invalid value\n");
+ return -EINVAL;
+ }
+ enable_dyn_sleep = value;
+ return n;
+}
+
+static struct kobj_attribute sleep_while_idle_attr =
+ __ATTR(sleep_while_idle, 0644, idle_show, idle_store);
+
+#endif
+
+static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL;
+
+/*
+ * Let's power down on idle, but only if we are really
+ * idle, because once we start down the path of
+ * going idle we continue to do idle even if we get
+ * a clock tick interrupt . .
+ */
+void omap1_pm_idle(void)
+{
+ extern __u32 arm_idlect1_mask;
+ __u32 use_idlect1 = arm_idlect1_mask;
+ int do_sleep = 0;
+
+ local_irq_disable();
+ local_fiq_disable();
+ if (need_resched()) {
+ local_fiq_enable();
+ local_irq_enable();
+ return;
+ }
+
+#ifdef CONFIG_OMAP_MPU_TIMER
+#warning Enable 32kHz OS timer in order to allow sleep states in idle
+ use_idlect1 = use_idlect1 & ~(1 << 9);
+#else
+
+ while (enable_dyn_sleep) {
+
+#ifdef CONFIG_CBUS_TAHVO_USB
+ extern int vbus_active;
+ /* Clock requirements? */
+ if (vbus_active)
+ break;
+#endif
+ do_sleep = 1;
+ break;
+ }
+
+#endif
+
+#ifdef CONFIG_OMAP_DM_TIMER
+ use_idlect1 = omap_dm_timer_modify_idlect_mask(use_idlect1);
+#endif
+
+ if (omap_dma_running())
+ use_idlect1 &= ~(1 << 6);
+
+ /* We should be able to remove the do_sleep variable and multiple
+ * tests above as soon as drivers, timer and DMA code have been fixed.
+ * Even the sleep block count should become obsolete. */
+ if ((use_idlect1 != ~0) || !do_sleep) {
+
+ __u32 saved_idlect1 = omap_readl(ARM_IDLECT1);
+ if (cpu_is_omap15xx())
+ use_idlect1 &= OMAP1510_BIG_SLEEP_REQUEST;
+ else
+ use_idlect1 &= OMAP1610_IDLECT1_SLEEP_VAL;
+ omap_writel(use_idlect1, ARM_IDLECT1);
+ __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
+ omap_writel(saved_idlect1, ARM_IDLECT1);
+
+ local_fiq_enable();
+ local_irq_enable();
+ return;
+ }
+ omap_sram_suspend(omap_readl(ARM_IDLECT1),
+ omap_readl(ARM_IDLECT2));
+
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+/*
+ * Configuration of the wakeup event is board specific. For the
+ * moment we put it into this helper function. Later it may move
+ * to board specific files.
+ */
+static void omap_pm_wakeup_setup(void)
+{
+ u32 level1_wake = 0;
+ u32 level2_wake = OMAP_IRQ_BIT(INT_UART2);
+
+ /*
+ * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade,
+ * and the L2 wakeup interrupts: keypad and UART2. Note that the
+ * drivers must still separately call omap_set_gpio_wakeup() to
+ * wake up to a GPIO interrupt.
+ */
+ if (cpu_is_omap7xx())
+ level1_wake = OMAP_IRQ_BIT(INT_7XX_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_7XX_IH2_IRQ);
+ else if (cpu_is_omap15xx())
+ level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_1510_IH2_IRQ);
+ else if (cpu_is_omap16xx())
+ level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) |
+ OMAP_IRQ_BIT(INT_1610_IH2_IRQ);
+
+ omap_writel(~level1_wake, OMAP_IH1_MIR);
+
+ if (cpu_is_omap7xx()) {
+ omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+ omap_writel(~(OMAP_IRQ_BIT(INT_7XX_WAKE_UP_REQ) |
+ OMAP_IRQ_BIT(INT_7XX_MPUIO_KEYPAD)),
+ OMAP_IH2_1_MIR);
+ } else if (cpu_is_omap15xx()) {
+ level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
+ omap_writel(~level2_wake, OMAP_IH2_MIR);
+ } else if (cpu_is_omap16xx()) {
+ level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD);
+ omap_writel(~level2_wake, OMAP_IH2_0_MIR);
+
+ /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */
+ omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ),
+ OMAP_IH2_1_MIR);
+ omap_writel(~0x0, OMAP_IH2_2_MIR);
+ omap_writel(~0x0, OMAP_IH2_3_MIR);
+ }
+
+ /* New IRQ agreement, recalculate in cascade order */
+ omap_writel(1, OMAP_IH2_CONTROL);
+ omap_writel(1, OMAP_IH1_CONTROL);
+}
+
+#define EN_DSPCK 13 /* ARM_CKCTL */
+#define EN_APICK 6 /* ARM_IDLECT2 */
+#define DSP_EN 1 /* ARM_RSTCT1 */
+
+void omap1_pm_suspend(void)
+{
+ unsigned long arg0 = 0, arg1 = 0;
+
+ printk(KERN_INFO "PM: OMAP%x is trying to enter deep sleep...\n",
+ omap_rev());
+
+ omap_serial_wake_trigger(1);
+
+ if (!cpu_is_omap15xx())
+ omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG);
+
+ /*
+ * Step 1: turn off interrupts (FIXME: NOTE: already disabled)
+ */
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ /*
+ * Step 2: save registers
+ *
+ * The omap is a strange/beautiful device. The caches, memory
+ * and register state are preserved across power saves.
+ * We have to save and restore very little register state to
+ * idle the omap.
+ *
+ * Save interrupt, MPUI, ARM and UPLD control registers.
+ */
+
+ if (cpu_is_omap7xx()) {
+ MPUI7XX_SAVE(OMAP_IH1_MIR);
+ MPUI7XX_SAVE(OMAP_IH2_0_MIR);
+ MPUI7XX_SAVE(OMAP_IH2_1_MIR);
+ MPUI7XX_SAVE(MPUI_CTRL);
+ MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI7XX_SAVE(EMIFS_CONFIG);
+ MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
+
+ } else if (cpu_is_omap15xx()) {
+ MPUI1510_SAVE(OMAP_IH1_MIR);
+ MPUI1510_SAVE(OMAP_IH2_MIR);
+ MPUI1510_SAVE(MPUI_CTRL);
+ MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI1510_SAVE(EMIFS_CONFIG);
+ MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+ } else if (cpu_is_omap16xx()) {
+ MPUI1610_SAVE(OMAP_IH1_MIR);
+ MPUI1610_SAVE(OMAP_IH2_0_MIR);
+ MPUI1610_SAVE(OMAP_IH2_1_MIR);
+ MPUI1610_SAVE(OMAP_IH2_2_MIR);
+ MPUI1610_SAVE(OMAP_IH2_3_MIR);
+ MPUI1610_SAVE(MPUI_CTRL);
+ MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI1610_SAVE(EMIFS_CONFIG);
+ MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+ }
+
+ ARM_SAVE(ARM_CKCTL);
+ ARM_SAVE(ARM_IDLECT1);
+ ARM_SAVE(ARM_IDLECT2);
+ if (!(cpu_is_omap15xx()))
+ ARM_SAVE(ARM_IDLECT3);
+ ARM_SAVE(ARM_EWUPCT);
+ ARM_SAVE(ARM_RSTCT1);
+ ARM_SAVE(ARM_RSTCT2);
+ ARM_SAVE(ARM_SYSST);
+ ULPD_SAVE(ULPD_CLOCK_CTRL);
+ ULPD_SAVE(ULPD_STATUS_REQ);
+
+ /* (Step 3 removed - we now allow deep sleep by default) */
+
+ /*
+ * Step 4: OMAP DSP Shutdown
+ */
+
+ /* stop DSP */
+ omap_writew(omap_readw(ARM_RSTCT1) & ~(1 << DSP_EN), ARM_RSTCT1);
+
+ /* shut down dsp_ck */
+ if (!cpu_is_omap7xx())
+ omap_writew(omap_readw(ARM_CKCTL) & ~(1 << EN_DSPCK), ARM_CKCTL);
+
+ /* temporarily enabling api_ck to access DSP registers */
+ omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
+
+ /* save DSP registers */
+ DSP_SAVE(DSP_IDLECT2);
+
+ /* Stop all DSP domain clocks */
+ __raw_writew(0, DSP_IDLECT2);
+
+ /*
+ * Step 5: Wakeup Event Setup
+ */
+
+ omap_pm_wakeup_setup();
+
+ /*
+ * Step 6: ARM and Traffic controller shutdown
+ */
+
+ /* disable ARM watchdog */
+ omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
+ omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
+
+ /*
+ * Step 6b: ARM and Traffic controller shutdown
+ *
+ * Step 6 continues here. Prepare jump to power management
+ * assembly code in internal SRAM.
+ *
+ * Since the omap_cpu_suspend routine has been copied to
+ * SRAM, we'll do an indirect procedure call to it and pass the
+ * contents of arm_idlect1 and arm_idlect2 so it can restore
+ * them when it wakes up and it will return.
+ */
+
+ arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
+ arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
+
+ /*
+ * Step 6c: ARM and Traffic controller shutdown
+ *
+ * Jump to assembly code. The processor will stay there
+ * until wake up.
+ */
+ omap_sram_suspend(arg0, arg1);
+
+ /*
+ * If we are here, processor is woken up!
+ */
+
+ /*
+ * Restore DSP clocks
+ */
+
+ /* again temporarily enabling api_ck to access DSP registers */
+ omap_writew(omap_readw(ARM_IDLECT2) | 1 << EN_APICK, ARM_IDLECT2);
+
+ /* Restore DSP domain clocks */
+ DSP_RESTORE(DSP_IDLECT2);
+
+ /*
+ * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
+ */
+
+ if (!(cpu_is_omap15xx()))
+ ARM_RESTORE(ARM_IDLECT3);
+ ARM_RESTORE(ARM_CKCTL);
+ ARM_RESTORE(ARM_EWUPCT);
+ ARM_RESTORE(ARM_RSTCT1);
+ ARM_RESTORE(ARM_RSTCT2);
+ ARM_RESTORE(ARM_SYSST);
+ ULPD_RESTORE(ULPD_CLOCK_CTRL);
+ ULPD_RESTORE(ULPD_STATUS_REQ);
+
+ if (cpu_is_omap7xx()) {
+ MPUI7XX_RESTORE(EMIFS_CONFIG);
+ MPUI7XX_RESTORE(EMIFF_SDRAM_CONFIG);
+ MPUI7XX_RESTORE(OMAP_IH1_MIR);
+ MPUI7XX_RESTORE(OMAP_IH2_0_MIR);
+ MPUI7XX_RESTORE(OMAP_IH2_1_MIR);
+ } else if (cpu_is_omap15xx()) {
+ MPUI1510_RESTORE(MPUI_CTRL);
+ MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
+ MPUI1510_RESTORE(EMIFS_CONFIG);
+ MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
+ MPUI1510_RESTORE(OMAP_IH1_MIR);
+ MPUI1510_RESTORE(OMAP_IH2_MIR);
+ } else if (cpu_is_omap16xx()) {
+ MPUI1610_RESTORE(MPUI_CTRL);
+ MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
+ MPUI1610_RESTORE(EMIFS_CONFIG);
+ MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
+
+ MPUI1610_RESTORE(OMAP_IH1_MIR);
+ MPUI1610_RESTORE(OMAP_IH2_0_MIR);
+ MPUI1610_RESTORE(OMAP_IH2_1_MIR);
+ MPUI1610_RESTORE(OMAP_IH2_2_MIR);
+ MPUI1610_RESTORE(OMAP_IH2_3_MIR);
+ }
+
+ if (!cpu_is_omap15xx())
+ omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG);
+
+ /*
+ * Re-enable interrupts
+ */
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ omap_serial_wake_trigger(0);
+
+ printk(KERN_INFO "PM: OMAP%x is re-starting from deep sleep...\n",
+ omap_rev());
+}
+
+#if defined(DEBUG) && defined(CONFIG_PROC_FS)
+static int g_read_completed;
+
+/*
+ * Read system PM registers for debugging
+ */
+static int omap_pm_read_proc(
+ char *page_buffer,
+ char **my_first_byte,
+ off_t virtual_start,
+ int length,
+ int *eof,
+ void *data)
+{
+ int my_buffer_offset = 0;
+ char * const my_base = page_buffer;
+
+ ARM_SAVE(ARM_CKCTL);
+ ARM_SAVE(ARM_IDLECT1);
+ ARM_SAVE(ARM_IDLECT2);
+ if (!(cpu_is_omap15xx()))
+ ARM_SAVE(ARM_IDLECT3);
+ ARM_SAVE(ARM_EWUPCT);
+ ARM_SAVE(ARM_RSTCT1);
+ ARM_SAVE(ARM_RSTCT2);
+ ARM_SAVE(ARM_SYSST);
+
+ ULPD_SAVE(ULPD_IT_STATUS);
+ ULPD_SAVE(ULPD_CLOCK_CTRL);
+ ULPD_SAVE(ULPD_SOFT_REQ);
+ ULPD_SAVE(ULPD_STATUS_REQ);
+ ULPD_SAVE(ULPD_DPLL_CTRL);
+ ULPD_SAVE(ULPD_POWER_CTRL);
+
+ if (cpu_is_omap7xx()) {
+ MPUI7XX_SAVE(MPUI_CTRL);
+ MPUI7XX_SAVE(MPUI_DSP_STATUS);
+ MPUI7XX_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI7XX_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI7XX_SAVE(EMIFF_SDRAM_CONFIG);
+ MPUI7XX_SAVE(EMIFS_CONFIG);
+ } else if (cpu_is_omap15xx()) {
+ MPUI1510_SAVE(MPUI_CTRL);
+ MPUI1510_SAVE(MPUI_DSP_STATUS);
+ MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
+ MPUI1510_SAVE(EMIFS_CONFIG);
+ } else if (cpu_is_omap16xx()) {
+ MPUI1610_SAVE(MPUI_CTRL);
+ MPUI1610_SAVE(MPUI_DSP_STATUS);
+ MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
+ MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
+ MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
+ MPUI1610_SAVE(EMIFS_CONFIG);
+ }
+
+ if (virtual_start == 0) {
+ g_read_completed = 0;
+
+ my_buffer_offset += sprintf(my_base + my_buffer_offset,
+ "ARM_CKCTL_REG: 0x%-8x \n"
+ "ARM_IDLECT1_REG: 0x%-8x \n"
+ "ARM_IDLECT2_REG: 0x%-8x \n"
+ "ARM_IDLECT3_REG: 0x%-8x \n"
+ "ARM_EWUPCT_REG: 0x%-8x \n"
+ "ARM_RSTCT1_REG: 0x%-8x \n"
+ "ARM_RSTCT2_REG: 0x%-8x \n"
+ "ARM_SYSST_REG: 0x%-8x \n"
+ "ULPD_IT_STATUS_REG: 0x%-4x \n"
+ "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
+ "ULPD_SOFT_REQ_REG: 0x%-4x \n"
+ "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
+ "ULPD_STATUS_REQ_REG: 0x%-4x \n"
+ "ULPD_POWER_CTRL_REG: 0x%-4x \n",
+ ARM_SHOW(ARM_CKCTL),
+ ARM_SHOW(ARM_IDLECT1),
+ ARM_SHOW(ARM_IDLECT2),
+ ARM_SHOW(ARM_IDLECT3),
+ ARM_SHOW(ARM_EWUPCT),
+ ARM_SHOW(ARM_RSTCT1),
+ ARM_SHOW(ARM_RSTCT2),
+ ARM_SHOW(ARM_SYSST),
+ ULPD_SHOW(ULPD_IT_STATUS),
+ ULPD_SHOW(ULPD_CLOCK_CTRL),
+ ULPD_SHOW(ULPD_SOFT_REQ),
+ ULPD_SHOW(ULPD_DPLL_CTRL),
+ ULPD_SHOW(ULPD_STATUS_REQ),
+ ULPD_SHOW(ULPD_POWER_CTRL));
+
+ if (cpu_is_omap7xx()) {
+ my_buffer_offset += sprintf(my_base + my_buffer_offset,
+ "MPUI7XX_CTRL_REG 0x%-8x \n"
+ "MPUI7XX_DSP_STATUS_REG: 0x%-8x \n"
+ "MPUI7XX_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+ "MPUI7XX_DSP_API_CONFIG_REG: 0x%-8x \n"
+ "MPUI7XX_SDRAM_CONFIG_REG: 0x%-8x \n"
+ "MPUI7XX_EMIFS_CONFIG_REG: 0x%-8x \n",
+ MPUI7XX_SHOW(MPUI_CTRL),
+ MPUI7XX_SHOW(MPUI_DSP_STATUS),
+ MPUI7XX_SHOW(MPUI_DSP_BOOT_CONFIG),
+ MPUI7XX_SHOW(MPUI_DSP_API_CONFIG),
+ MPUI7XX_SHOW(EMIFF_SDRAM_CONFIG),
+ MPUI7XX_SHOW(EMIFS_CONFIG));
+ } else if (cpu_is_omap15xx()) {
+ my_buffer_offset += sprintf(my_base + my_buffer_offset,
+ "MPUI1510_CTRL_REG 0x%-8x \n"
+ "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
+ "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+ "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
+ "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
+ "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
+ MPUI1510_SHOW(MPUI_CTRL),
+ MPUI1510_SHOW(MPUI_DSP_STATUS),
+ MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
+ MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
+ MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
+ MPUI1510_SHOW(EMIFS_CONFIG));
+ } else if (cpu_is_omap16xx()) {
+ my_buffer_offset += sprintf(my_base + my_buffer_offset,
+ "MPUI1610_CTRL_REG 0x%-8x \n"
+ "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
+ "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
+ "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
+ "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
+ "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
+ MPUI1610_SHOW(MPUI_CTRL),
+ MPUI1610_SHOW(MPUI_DSP_STATUS),
+ MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
+ MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
+ MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
+ MPUI1610_SHOW(EMIFS_CONFIG));
+ }
+
+ g_read_completed++;
+ } else if (g_read_completed >= 1) {
+ *eof = 1;
+ return 0;
+ }
+ g_read_completed++;
+
+ *my_first_byte = page_buffer;
+ return my_buffer_offset;
+}
+
+static void omap_pm_init_proc(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_read_entry("driver/omap_pm",
+ S_IWUSR | S_IRUGO, NULL,
+ omap_pm_read_proc, NULL);
+}
+
+#endif /* DEBUG && CONFIG_PROC_FS */
+
+static void (*saved_idle)(void) = NULL;
+
+/*
+ * omap_pm_prepare - Do preliminary suspend work.
+ *
+ */
+static int omap_pm_prepare(void)
+{
+ /* We cannot sleep in idle until we have resumed */
+ saved_idle = pm_idle;
+ pm_idle = NULL;
+
+ return 0;
+}
+
+
+/*
+ * omap_pm_enter - Actually enter a sleep state.
+ * @state: State we're entering.
+ *
+ */
+
+static int omap_pm_enter(suspend_state_t state)
+{
+ switch (state)
+ {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ omap1_pm_suspend();
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/**
+ * omap_pm_finish - Finish up suspend sequence.
+ *
+ * This is called after we wake back up (or if entering the sleep state
+ * failed).
+ */
+
+static void omap_pm_finish(void)
+{
+ pm_idle = saved_idle;
+}
+
+
+static irqreturn_t omap_wakeup_interrupt(int irq, void *dev)
+{
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap_wakeup_irq = {
+ .name = "peripheral wakeup",
+ .flags = IRQF_DISABLED,
+ .handler = omap_wakeup_interrupt
+};
+
+
+
+static const struct platform_suspend_ops omap_pm_ops = {
+ .prepare = omap_pm_prepare,
+ .enter = omap_pm_enter,
+ .finish = omap_pm_finish,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init omap_pm_init(void)
+{
+
+#ifdef CONFIG_OMAP_32K_TIMER
+ int error;
+#endif
+
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ printk("Power Management for TI OMAP.\n");
+
+ /*
+ * We copy the assembler sleep/wakeup routines to SRAM.
+ * These routines need to be in SRAM as that's the only
+ * memory the MPU can see when it wakes up.
+ */
+ if (cpu_is_omap7xx()) {
+ omap_sram_suspend = omap_sram_push(omap7xx_cpu_suspend,
+ omap7xx_cpu_suspend_sz);
+ } else if (cpu_is_omap15xx()) {
+ omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend,
+ omap1510_cpu_suspend_sz);
+ } else if (cpu_is_omap16xx()) {
+ omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend,
+ omap1610_cpu_suspend_sz);
+ }
+
+ if (omap_sram_suspend == NULL) {
+ printk(KERN_ERR "PM not initialized: Missing SRAM support\n");
+ return -ENODEV;
+ }
+
+ pm_idle = omap1_pm_idle;
+
+ if (cpu_is_omap7xx())
+ setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
+ else if (cpu_is_omap16xx())
+ setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq);
+
+ /* Program new power ramp-up time
+ * (0 for most boards since we don't lower voltage when in deep sleep)
+ */
+ omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3);
+
+ /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */
+ omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL);
+
+ /* Configure IDLECT3 */
+ if (cpu_is_omap7xx())
+ omap_writel(OMAP7XX_IDLECT3_VAL, OMAP7XX_IDLECT3);
+ else if (cpu_is_omap16xx())
+ omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3);
+
+ suspend_set_ops(&omap_pm_ops);
+
+#if defined(DEBUG) && defined(CONFIG_PROC_FS)
+ omap_pm_init_proc();
+#endif
+
+#ifdef CONFIG_OMAP_32K_TIMER
+ error = sysfs_create_file(power_kobj, &sleep_while_idle_attr.attr);
+ if (error)
+ printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
+#endif
+
+ if (cpu_is_omap16xx()) {
+ /* configure LOW_PWR pin */
+ omap_cfg_reg(T20_1610_LOW_PWR);
+ }
+
+ return 0;
+}
+__initcall(omap_pm_init);
diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h
new file mode 100644
index 00000000..cd926dcb
--- /dev/null
+++ b/arch/arm/mach-omap1/pm.h
@@ -0,0 +1,281 @@
+/*
+ * arch/arm/mach-omap1/pm.h
+ *
+ * Header file for OMAP1 Power Management Routines
+ *
+ * Author: MontaVista Software, Inc.
+ * support@mvista.com
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * Cleanup 2004 for Linux 2.6 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP1_PM_H
+#define __ARCH_ARM_MACH_OMAP1_PM_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Register and offset definitions to be used in PM assembler code
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_ASM_BASE OMAP1_IO_ADDRESS(0xfffece00)
+#define ARM_IDLECT1_ASM_OFFSET 0x04
+#define ARM_IDLECT2_ASM_OFFSET 0x08
+
+#define TCMIF_ASM_BASE OMAP1_IO_ADDRESS(0xfffecc00)
+#define EMIFS_CONFIG_ASM_OFFSET 0x0c
+#define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20
+
+/*
+ * ----------------------------------------------------------------------------
+ * Power management bitmasks
+ * ----------------------------------------------------------------------------
+ */
+#define IDLE_WAIT_CYCLES 0x00000fff
+#define PERIPHERAL_ENABLE 0x2
+
+#define SELF_REFRESH_MODE 0x0c000001
+#define IDLE_EMIFS_REQUEST 0xc
+#define MODEM_32K_EN 0x1
+#define PER_EN 0x1
+
+#define CPU_SUSPEND_SIZE 200
+#define ULPD_LOW_PWR_EN 0x0001
+#define ULPD_DEEP_SLEEP_TRANSITION_EN 0x0010
+#define ULPD_SETUP_ANALOG_CELL_3_VAL 0
+#define ULPD_POWER_CTRL_REG_VAL 0x0219
+
+#define DSP_IDLE_DELAY 10
+#define DSP_IDLE 0x0040
+#define DSP_RST 0x0004
+#define DSP_ENABLE 0x0002
+#define SUFFICIENT_DSP_RESET_TIME 1000
+#define DEFAULT_MPUI_CONFIG 0x05cf
+#define ENABLE_XORCLK 0x2
+#define DSP_CLOCK_ENABLE 0x2000
+#define DSP_IDLE_MODE 0x2
+#define TC_IDLE_REQUEST (0x0000000c)
+
+#define IRQ_LEVEL2 (1<<0)
+#define IRQ_KEYBOARD (1<<1)
+#define IRQ_UART2 (1<<15)
+
+#define PDE_BIT 0x08
+#define PWD_EN_BIT 0x04
+#define EN_PERCK_BIT 0x04
+
+#define OMAP1510_DEEP_SLEEP_REQUEST 0x0ec7
+#define OMAP1510_BIG_SLEEP_REQUEST 0x0cc5
+#define OMAP1510_IDLE_LOOP_REQUEST 0x0c00
+#define OMAP1510_IDLE_CLOCK_DOMAINS 0x2
+
+/* Both big sleep and deep sleep use same values. Difference is in ULPD. */
+#define OMAP1610_IDLECT1_SLEEP_VAL 0x13c7
+#define OMAP1610_IDLECT2_SLEEP_VAL 0x09c7
+#define OMAP1610_IDLECT3_VAL 0x3f
+#define OMAP1610_IDLECT3_SLEEP_ORMASK 0x2c
+#define OMAP1610_IDLECT3 0xfffece24
+#define OMAP1610_IDLE_LOOP_REQUEST 0x0400
+
+#define OMAP7XX_IDLECT1_SLEEP_VAL 0x16c7
+#define OMAP7XX_IDLECT2_SLEEP_VAL 0x09c7
+#define OMAP7XX_IDLECT3_VAL 0x3f
+#define OMAP7XX_IDLECT3 0xfffece24
+#define OMAP7XX_IDLE_LOOP_REQUEST 0x0C00
+
+#if !defined(CONFIG_ARCH_OMAP730) && \
+ !defined(CONFIG_ARCH_OMAP850) && \
+ !defined(CONFIG_ARCH_OMAP15XX) && \
+ !defined(CONFIG_ARCH_OMAP16XX)
+#warning "Power management for this processor not implemented yet"
+#endif
+
+#ifndef __ASSEMBLER__
+
+#include <linux/clk.h>
+
+extern struct kset power_subsys;
+
+extern void prevent_idle_sleep(void);
+extern void allow_idle_sleep(void);
+
+extern void omap1_pm_idle(void);
+extern void omap1_pm_suspend(void);
+
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
+extern void omap7xx_idle_loop_suspend(void);
+extern void omap1510_idle_loop_suspend(void);
+extern void omap1610_idle_loop_suspend(void);
+
+extern unsigned int omap7xx_cpu_suspend_sz;
+extern unsigned int omap1510_cpu_suspend_sz;
+extern unsigned int omap1610_cpu_suspend_sz;
+extern unsigned int omap7xx_idle_loop_suspend_sz;
+extern unsigned int omap1510_idle_loop_suspend_sz;
+extern unsigned int omap1610_idle_loop_suspend_sz;
+
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+extern void omap_serial_wake_trigger(int enable);
+#else
+#define omap_serial_wakeup_init() {}
+#define omap_serial_wake_trigger(x) {}
+#endif /* CONFIG_OMAP_SERIAL_WAKE */
+
+#define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x)
+#define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x))
+#define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x]
+
+#define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x)
+#define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x))
+#define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x]
+
+#define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x)
+#define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x))
+#define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]
+
+#define MPUI7XX_SAVE(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] = omap_readl(x)
+#define MPUI7XX_RESTORE(x) omap_writel((mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]), (x))
+#define MPUI7XX_SHOW(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]
+
+#define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x)
+#define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x))
+#define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]
+
+#define MPUI1610_SAVE(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] = omap_readl(x)
+#define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x))
+#define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]
+
+/*
+ * List of global OMAP registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+
+enum arm_save_state {
+ ARM_SLEEP_SAVE_START = 0,
+ /*
+ * MPU control registers 32 bits
+ */
+ ARM_SLEEP_SAVE_ARM_CKCTL,
+ ARM_SLEEP_SAVE_ARM_IDLECT1,
+ ARM_SLEEP_SAVE_ARM_IDLECT2,
+ ARM_SLEEP_SAVE_ARM_IDLECT3,
+ ARM_SLEEP_SAVE_ARM_EWUPCT,
+ ARM_SLEEP_SAVE_ARM_RSTCT1,
+ ARM_SLEEP_SAVE_ARM_RSTCT2,
+ ARM_SLEEP_SAVE_ARM_SYSST,
+ ARM_SLEEP_SAVE_SIZE
+};
+
+enum dsp_save_state {
+ DSP_SLEEP_SAVE_START = 0,
+ /*
+ * DSP registers 16 bits
+ */
+ DSP_SLEEP_SAVE_DSP_IDLECT2,
+ DSP_SLEEP_SAVE_SIZE
+};
+
+enum ulpd_save_state {
+ ULPD_SLEEP_SAVE_START = 0,
+ /*
+ * ULPD registers 16 bits
+ */
+ ULPD_SLEEP_SAVE_ULPD_IT_STATUS,
+ ULPD_SLEEP_SAVE_ULPD_CLOCK_CTRL,
+ ULPD_SLEEP_SAVE_ULPD_SOFT_REQ,
+ ULPD_SLEEP_SAVE_ULPD_STATUS_REQ,
+ ULPD_SLEEP_SAVE_ULPD_DPLL_CTRL,
+ ULPD_SLEEP_SAVE_ULPD_POWER_CTRL,
+ ULPD_SLEEP_SAVE_SIZE
+};
+
+enum mpui1510_save_state {
+ MPUI1510_SLEEP_SAVE_START = 0,
+ /*
+ * MPUI registers 32 bits
+ */
+ MPUI1510_SLEEP_SAVE_MPUI_CTRL,
+ MPUI1510_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
+ MPUI1510_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
+ MPUI1510_SLEEP_SAVE_MPUI_DSP_STATUS,
+ MPUI1510_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
+ MPUI1510_SLEEP_SAVE_EMIFS_CONFIG,
+ MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR,
+ MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR,
+#if defined(CONFIG_ARCH_OMAP15XX)
+ MPUI1510_SLEEP_SAVE_SIZE
+#else
+ MPUI1510_SLEEP_SAVE_SIZE = 0
+#endif
+};
+
+enum mpui7xx_save_state {
+ MPUI7XX_SLEEP_SAVE_START = 0,
+ /*
+ * MPUI registers 32 bits
+ */
+ MPUI7XX_SLEEP_SAVE_MPUI_CTRL,
+ MPUI7XX_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
+ MPUI7XX_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
+ MPUI7XX_SLEEP_SAVE_MPUI_DSP_STATUS,
+ MPUI7XX_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
+ MPUI7XX_SLEEP_SAVE_EMIFS_CONFIG,
+ MPUI7XX_SLEEP_SAVE_OMAP_IH1_MIR,
+ MPUI7XX_SLEEP_SAVE_OMAP_IH2_0_MIR,
+ MPUI7XX_SLEEP_SAVE_OMAP_IH2_1_MIR,
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ MPUI7XX_SLEEP_SAVE_SIZE
+#else
+ MPUI7XX_SLEEP_SAVE_SIZE = 0
+#endif
+};
+
+enum mpui1610_save_state {
+ MPUI1610_SLEEP_SAVE_START = 0,
+ /*
+ * MPUI registers 32 bits
+ */
+ MPUI1610_SLEEP_SAVE_MPUI_CTRL,
+ MPUI1610_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG,
+ MPUI1610_SLEEP_SAVE_MPUI_DSP_API_CONFIG,
+ MPUI1610_SLEEP_SAVE_MPUI_DSP_STATUS,
+ MPUI1610_SLEEP_SAVE_EMIFF_SDRAM_CONFIG,
+ MPUI1610_SLEEP_SAVE_EMIFS_CONFIG,
+ MPUI1610_SLEEP_SAVE_OMAP_IH1_MIR,
+ MPUI1610_SLEEP_SAVE_OMAP_IH2_0_MIR,
+ MPUI1610_SLEEP_SAVE_OMAP_IH2_1_MIR,
+ MPUI1610_SLEEP_SAVE_OMAP_IH2_2_MIR,
+ MPUI1610_SLEEP_SAVE_OMAP_IH2_3_MIR,
+#if defined(CONFIG_ARCH_OMAP16XX)
+ MPUI1610_SLEEP_SAVE_SIZE
+#else
+ MPUI1610_SLEEP_SAVE_SIZE = 0
+#endif
+};
+
+#endif /* ASSEMBLER */
+#endif /* __ASM_ARCH_OMAP_PM_H */
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
new file mode 100644
index 00000000..334fb887
--- /dev/null
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -0,0 +1,79 @@
+/*
+ * Runtime PM support code for OMAP1
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+static int omap1_pm_runtime_suspend(struct device *dev)
+{
+ int ret;
+
+ dev_dbg(dev, "%s\n", __func__);
+
+ ret = pm_generic_runtime_suspend(dev);
+ if (ret)
+ return ret;
+
+ ret = pm_runtime_clk_suspend(dev);
+ if (ret) {
+ pm_generic_runtime_resume(dev);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int omap1_pm_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "%s\n", __func__);
+
+ pm_runtime_clk_resume(dev);
+ return pm_generic_runtime_resume(dev);
+}
+
+static struct dev_power_domain default_power_domain = {
+ .ops = {
+ .runtime_suspend = omap1_pm_runtime_suspend,
+ .runtime_resume = omap1_pm_runtime_resume,
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+#define OMAP1_PWR_DOMAIN (&default_power_domain)
+#else
+#define OMAP1_PWR_DOMAIN NULL
+#endif /* CONFIG_PM_RUNTIME */
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+ .pwr_domain = OMAP1_PWR_DOMAIN,
+ .con_ids = { "ick", "fck", NULL, },
+};
+
+static int __init omap1_pm_runtime_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+
+ return 0;
+}
+core_initcall(omap1_pm_runtime_init);
+
diff --git a/arch/arm/mach-omap1/reset.c b/arch/arm/mach-omap1/reset.c
new file mode 100644
index 00000000..ad951ee6
--- /dev/null
+++ b/arch/arm/mach-omap1/reset.c
@@ -0,0 +1,25 @@
+/*
+ * OMAP1 reset support
+ */
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include <plat/prcm.h>
+
+void omap1_arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28
+ * "Global Software Reset Affects Traffic Controller Frequency".
+ */
+ if (cpu_is_omap5912()) {
+ omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL);
+ omap_writew(0x8, ARM_RSTCT1);
+ }
+
+ omap_writew(1, ARM_RSTCT1);
+}
+
+void (*arch_reset)(char, const char *) = omap1_arch_reset;
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
new file mode 100644
index 00000000..550ca9d9
--- /dev/null
+++ b/arch/arm/mach-omap1/serial.c
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/arm/mach-omap1/serial.c
+ *
+ * OMAP1 serial 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/irq.h>
+#include <linux/delay.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <plat/board.h>
+#include <plat/mux.h>
+#include <mach/gpio.h>
+#include <plat/fpga.h>
+
+#include "pm.h"
+
+static struct clk * uart1_ck;
+static struct clk * uart2_ck;
+static struct clk * uart3_ck;
+
+static inline unsigned int omap_serial_in(struct plat_serial8250_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+ return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset,
+ int value)
+{
+ offset <<= p->regshift;
+ __raw_writeb(value, p->membase + offset);
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+static void __init omap_serial_reset(struct plat_serial8250_port *p)
+{
+ omap_serial_outp(p, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_DISABLE); /* disable UART */
+ omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */
+ omap_serial_outp(p, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_16X_MODE); /* enable UART */
+
+ if (!cpu_is_omap15xx()) {
+ omap_serial_outp(p, UART_OMAP_SYSC, 0x01);
+ while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01));
+ }
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = OMAP1_UART1_BASE,
+ .irq = INT_UART1,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ },
+ {
+ .mapbase = OMAP1_UART2_BASE,
+ .irq = INT_UART2,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ },
+ {
+ .mapbase = OMAP1_UART3_BASE,
+ .irq = INT_UART3,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = OMAP16XX_BASE_BAUD * 16,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+/*
+ * Note that on Innovator-1510 UART2 pins conflict with USB2.
+ * By default UART2 does not work on Innovator-1510 if you have
+ * USB OHCI enabled. To use UART2, you must disable USB2 first.
+ */
+void __init omap_serial_init(void)
+{
+ int i;
+
+ if (cpu_is_omap7xx()) {
+ serial_platform_data[0].regshift = 0;
+ serial_platform_data[1].regshift = 0;
+ serial_platform_data[0].irq = INT_7XX_UART_MODEM_1;
+ serial_platform_data[1].irq = INT_7XX_UART_MODEM_IRDA_2;
+ }
+
+ if (cpu_is_omap15xx()) {
+ serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16;
+ serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16;
+ serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(serial_platform_data) - 1; i++) {
+
+ /* Don't look at UARTs higher than 2 for omap7xx */
+ if (cpu_is_omap7xx() && i > 1) {
+ serial_platform_data[i].membase = NULL;
+ serial_platform_data[i].mapbase = 0;
+ continue;
+ }
+
+ /* Static mapping, never released */
+ serial_platform_data[i].membase =
+ ioremap(serial_platform_data[i].mapbase, SZ_2K);
+ if (!serial_platform_data[i].membase) {
+ printk(KERN_ERR "Could not ioremap uart%i\n", i);
+ continue;
+ }
+ switch (i) {
+ case 0:
+ uart1_ck = clk_get(NULL, "uart1_ck");
+ if (IS_ERR(uart1_ck))
+ printk("Could not get uart1_ck\n");
+ else {
+ clk_enable(uart1_ck);
+ if (cpu_is_omap15xx())
+ clk_set_rate(uart1_ck, 12000000);
+ }
+ break;
+ case 1:
+ uart2_ck = clk_get(NULL, "uart2_ck");
+ if (IS_ERR(uart2_ck))
+ printk("Could not get uart2_ck\n");
+ else {
+ clk_enable(uart2_ck);
+ if (cpu_is_omap15xx())
+ clk_set_rate(uart2_ck, 12000000);
+ else
+ clk_set_rate(uart2_ck, 48000000);
+ }
+ break;
+ case 2:
+ uart3_ck = clk_get(NULL, "uart3_ck");
+ if (IS_ERR(uart3_ck))
+ printk("Could not get uart3_ck\n");
+ else {
+ clk_enable(uart3_ck);
+ if (cpu_is_omap15xx())
+ clk_set_rate(uart3_ck, 12000000);
+ }
+ break;
+ }
+ omap_serial_reset(&serial_platform_data[i]);
+ }
+}
+
+#ifdef CONFIG_OMAP_SERIAL_WAKE
+
+static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id)
+{
+ /* Need to do something with serial port right after wake-up? */
+ return IRQ_HANDLED;
+}
+
+/*
+ * Reroutes serial RX lines to GPIO lines for the duration of
+ * sleep to allow waking up the device from serial port even
+ * in deep sleep.
+ */
+void omap_serial_wake_trigger(int enable)
+{
+ if (!cpu_is_omap16xx())
+ return;
+
+ if (uart1_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(V14_16XX_GPIO37);
+ else
+ omap_cfg_reg(V14_16XX_UART1_RX);
+ }
+ if (uart2_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(R9_16XX_GPIO18);
+ else
+ omap_cfg_reg(R9_16XX_UART2_RX);
+ }
+ if (uart3_ck != NULL) {
+ if (enable)
+ omap_cfg_reg(L14_16XX_GPIO49);
+ else
+ omap_cfg_reg(L14_16XX_UART3_RX);
+ }
+}
+
+static void __init omap_serial_set_port_wakeup(int gpio_nr)
+{
+ int ret;
+
+ ret = gpio_request(gpio_nr, "UART wake");
+ if (ret < 0) {
+ printk(KERN_ERR "Could not request UART wake GPIO: %i\n",
+ gpio_nr);
+ return;
+ }
+ gpio_direction_input(gpio_nr);
+ ret = request_irq(gpio_to_irq(gpio_nr), &omap_serial_wake_interrupt,
+ IRQF_TRIGGER_RISING, "serial wakeup", NULL);
+ if (ret) {
+ gpio_free(gpio_nr);
+ printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
+ gpio_nr);
+ return;
+ }
+ enable_irq_wake(gpio_to_irq(gpio_nr));
+}
+
+static int __init omap_serial_wakeup_init(void)
+{
+ if (!cpu_is_omap16xx())
+ return 0;
+
+ if (uart1_ck != NULL)
+ omap_serial_set_port_wakeup(37);
+ if (uart2_ck != NULL)
+ omap_serial_set_port_wakeup(18);
+ if (uart3_ck != NULL)
+ omap_serial_set_port_wakeup(49);
+
+ return 0;
+}
+late_initcall(omap_serial_wakeup_init);
+
+#endif /* CONFIG_OMAP_SERIAL_WAKE */
+
+static int __init omap_init(void)
+{
+ if (!cpu_class_is_omap1())
+ return -ENODEV;
+
+ return platform_device_register(&serial_device);
+}
+arch_initcall(omap_init);
diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S
new file mode 100644
index 00000000..c875bdc9
--- /dev/null
+++ b/arch/arm/mach-omap1/sleep.S
@@ -0,0 +1,366 @@
+/*
+ * linux/arch/arm/mach-omap1/sleep.S
+ *
+ * Low-level OMAP7XX/1510/1610 sleep/wakeUp support
+ *
+ * Initial SA1110 code:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Adapted for PXA by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/io.h>
+#include "pm.h"
+
+ .text
+
+
+/*
+ * Forces OMAP into deep sleep state
+ *
+ * omapXXXX_cpu_suspend()
+ *
+ * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
+ * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
+ * in register r1.
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ * wakes up it continues execution at the point it went to sleep.
+ *
+ * Note: Because of errata work arounds we have processor specific functions
+ * here. They are mostly the same, but slightly different.
+ *
+ */
+
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ .align 3
+ENTRY(omap7xx_cpu_suspend)
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r12, lr}
+
+ @ Drain write cache
+ mov r4, #0
+ mcr p15, 0, r0, c7, c10, 4
+ nop
+
+ @ load base address of Traffic Controller
+ mov r6, #TCMIF_ASM_BASE & 0xff000000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
+
+ @ prepare to put SDRAM into self-refresh manually
+ ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
+ orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
+ str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+ @ prepare to put EMIFS to Sleep
+ ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
+ str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ load base address of ARM_IDLECT1 and ARM_IDLECT2
+ mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+ @ turn off clock domains
+ @ do not disable PERCK (0x04)
+ mov r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff
+ orr r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00
+ strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+ @ request ARM idle
+ mov r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff
+ orr r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00
+ strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ disable instruction cache
+ mrc p15, 0, r9, c1, c0, 0
+ bic r2, r9, #0x1000
+ mcr p15, 0, r2, c1, c0, 0
+ nop
+
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+ mov r2, #0
+ mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
+/*
+ * omap7xx_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack.
+ */
+ @ re-enable Icache
+ mcr p15, 0, r9, c1, c0, 0
+
+ @ reset the ARM_IDLECT1 and ARM_IDLECT2.
+ strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ Restore EMIFF controls
+ str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r12, pc}
+
+ENTRY(omap7xx_cpu_suspend_sz)
+ .word . - omap7xx_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
+
+#ifdef CONFIG_ARCH_OMAP15XX
+ .align 3
+ENTRY(omap1510_cpu_suspend)
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r12, lr}
+
+ @ load base address of Traffic Controller
+ mov r4, #TCMIF_ASM_BASE & 0xff000000
+ orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
+ orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
+
+ @ work around errata of OMAP1510 PDE bit for TC shut down
+ @ clear PDE bit
+ ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+ bic r5, r5, #PDE_BIT & 0xff
+ str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ set PWD_EN bit
+ and r5, r5, #PWD_EN_BIT & 0xff
+ str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ prepare to put SDRAM into self-refresh manually
+ ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
+ orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
+ str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+ @ prepare to put EMIFS to Sleep
+ ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+ orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
+ str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ load base address of ARM_IDLECT1 and ARM_IDLECT2
+ mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+ @ turn off clock domains
+ mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
+ orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
+ strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+ @ request ARM idle
+ mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
+ orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
+ strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ mov r5, #IDLE_WAIT_CYCLES & 0xff
+ orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
+l_1510_2:
+ subs r5, r5, #1
+ bne l_1510_2
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+ mov r2, #0
+ mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
+/*
+ * omap1510_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
+ */
+ strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r12, pc}
+
+ENTRY(omap1510_cpu_suspend_sz)
+ .word . - omap1510_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP15XX */
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+ .align 3
+ENTRY(omap1610_cpu_suspend)
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r12, lr}
+
+ @ Drain write cache
+ mov r4, #0
+ mcr p15, 0, r0, c7, c10, 4
+ nop
+
+ @ Load base address of Traffic Controller
+ mov r6, #TCMIF_ASM_BASE & 0xff000000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
+ orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
+
+ @ Prepare to put SDRAM into self-refresh manually
+ ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r7, #SELF_REFRESH_MODE & 0xff000000
+ orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff
+ str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+
+ @ Prepare to put EMIFS to Sleep
+ ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+ orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff
+ str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ Load base address of ARM_IDLECT1 and ARM_IDLECT2
+ mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
+ orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
+
+ @ Turn off clock domains
+ @ Do not disable PERCK (0x04)
+ mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
+ orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
+ strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+
+ @ Request ARM idle
+ mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
+ orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
+ strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+/*
+ * Let's wait for the next wake up event to wake us up. r0 can't be
+ * used here because r0 holds ARM_IDLECT1
+ */
+ mov r2, #0
+ mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
+
+ @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions
+ @ according to this formula:
+ @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV
+ @ Max DPLL_MULT = 18
+ @ DPLL_DIV = 1
+ @ ARMDIV = 1
+ @ => 74 nop-instructions
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @10
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @20
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @30
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @40
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @50
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @60
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop @70
+ nop
+ nop
+ nop
+ nop @74
+/*
+ * omap1610_cpu_suspend()'s resume point.
+ *
+ * It will just start executing here, so we'll restore stuff from the
+ * stack.
+ */
+ @ Restore the ARM_IDLECT1 and ARM_IDLECT2.
+ strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
+ strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
+
+ @ Restore EMIFF controls
+ str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
+ str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
+
+ @ Restore regs and return
+ ldmfd sp!, {r0 - r12, pc}
+
+ENTRY(omap1610_cpu_suspend_sz)
+ .word . - omap1610_cpu_suspend
+#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S
new file mode 100644
index 00000000..692587d0
--- /dev/null
+++ b/arch/arm/mach-omap1/sram.S
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/arm/plat-omap/sram-fn.S
+ *
+ * Functions that need to be run in internal SRAM
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/io.h>
+#include <mach/hardware.h>
+
+ .text
+
+/*
+ * Reprograms ULPD and CKCTL.
+ */
+ .align 3
+ENTRY(omap1_sram_reprogram_clock)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ mov r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0xff000000
+ orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x00ff0000
+ orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x0000ff00
+
+ mov r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0xff000000
+ orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x00ff0000
+ orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x0000ff00
+
+ tst r0, #1 << 4 @ want lock mode?
+ beq newck @ nope
+ bic r0, r0, #1 << 4 @ else clear lock bit
+ strh r0, [r2] @ set dpll into bypass mode
+ orr r0, r0, #1 << 4 @ set lock bit again
+
+newck:
+ strh r1, [r3] @ write new ckctl value
+ strh r0, [r2] @ write new dpll value
+
+ mov r4, #0x0700 @ let the clocks settle
+ orr r4, r4, #0x00ff
+delay: sub r4, r4, #1
+ cmp r4, #0
+ bne delay
+
+lock: ldrh r4, [r2], #0 @ read back dpll value
+ tst r0, #1 << 4 @ want lock mode?
+ beq out @ nope
+ tst r4, #1 << 0 @ dpll rate locked?
+ beq lock @ try again
+
+out:
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+ENTRY(omap1_sram_reprogram_clock_sz)
+ .word . - omap1_sram_reprogram_clock
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
new file mode 100644
index 00000000..03e1e106
--- /dev/null
+++ b/arch/arm/mach-omap1/time.c
@@ -0,0 +1,312 @@
+/*
+ * linux/arch/arm/mach-omap1/time.c
+ *
+ * OMAP Timers
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Partial timer rewrite and additional dynamic tick timer support by
+ * Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * MPU timer code based on the older MPU timer code for OMAP
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/sched_clock.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <plat/common.h>
+
+#ifdef CONFIG_OMAP_MPU_TIMER
+
+#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE
+#define OMAP_MPU_TIMER_OFFSET 0x100
+
+typedef struct {
+ u32 cntl; /* CNTL_TIMER, R/W */
+ u32 load_tim; /* LOAD_TIM, W */
+ u32 read_tim; /* READ_TIM, R */
+} omap_mpu_timer_regs_t;
+
+#define omap_mpu_timer_base(n) \
+((omap_mpu_timer_regs_t __iomem *)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE + \
+ (n)*OMAP_MPU_TIMER_OFFSET))
+
+static inline unsigned long notrace omap_mpu_timer_read(int nr)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+ return readl(&timer->read_tim);
+}
+
+static inline void omap_mpu_set_autoreset(int nr)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+
+ writel(readl(&timer->cntl) | MPU_TIMER_AR, &timer->cntl);
+}
+
+static inline void omap_mpu_remove_autoreset(int nr)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+
+ writel(readl(&timer->cntl) & ~MPU_TIMER_AR, &timer->cntl);
+}
+
+static inline void omap_mpu_timer_start(int nr, unsigned long load_val,
+ int autoreset)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+ unsigned int timerflags = MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST;
+
+ if (autoreset)
+ timerflags |= MPU_TIMER_AR;
+
+ writel(MPU_TIMER_CLOCK_ENABLE, &timer->cntl);
+ udelay(1);
+ writel(load_val, &timer->load_tim);
+ udelay(1);
+ writel(timerflags, &timer->cntl);
+}
+
+static inline void omap_mpu_timer_stop(int nr)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+
+ writel(readl(&timer->cntl) & ~MPU_TIMER_ST, &timer->cntl);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer 1 ... count down to zero, interrupt, reload
+ * ---------------------------------------------------------------------------
+ */
+static int omap_mpu_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ omap_mpu_timer_start(0, cycles, 0);
+ return 0;
+}
+
+static void omap_mpu_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ omap_mpu_set_autoreset(0);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ omap_mpu_timer_stop(0);
+ omap_mpu_remove_autoreset(0);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_mpu_timer1 = {
+ .name = "mpu_timer1",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap_mpu_set_next_event,
+ .set_mode = omap_mpu_set_mode,
+};
+
+static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mpu_timer1;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap_mpu_timer1_irq = {
+ .name = "mpu_timer1",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = omap_mpu_timer1_interrupt,
+};
+
+static __init void omap_init_mpu_timer(unsigned long rate)
+{
+ setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
+ omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
+
+ clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC,
+ clockevent_mpu_timer1.shift);
+ clockevent_mpu_timer1.max_delta_ns =
+ clockevent_delta2ns(-1, &clockevent_mpu_timer1);
+ clockevent_mpu_timer1.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_mpu_timer1);
+
+ clockevent_mpu_timer1.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_mpu_timer1);
+}
+
+
+/*
+ * ---------------------------------------------------------------------------
+ * MPU timer 2 ... free running 32-bit clock source and scheduler clock
+ * ---------------------------------------------------------------------------
+ */
+
+static DEFINE_CLOCK_DATA(cd);
+
+static inline unsigned long long notrace _omap_mpu_sched_clock(void)
+{
+ u32 cyc = ~omap_mpu_timer_read(1);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+#ifndef CONFIG_OMAP_32K_TIMER
+unsigned long long notrace sched_clock(void)
+{
+ return _omap_mpu_sched_clock();
+}
+#else
+static unsigned long long notrace omap_mpu_sched_clock(void)
+{
+ return _omap_mpu_sched_clock();
+}
+#endif
+
+static void notrace mpu_update_sched_clock(void)
+{
+ u32 cyc = ~omap_mpu_timer_read(1);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void __init omap_init_clocksource(unsigned long rate)
+{
+ omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(1);
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ omap_mpu_timer_start(1, ~0, 1);
+ init_sched_clock(&cd, mpu_update_sched_clock, 32, rate);
+
+ if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate,
+ 300, 32, clocksource_mmio_readl_down))
+ printk(err, "mpu_timer2");
+}
+
+static void __init omap_mpu_timer_init(void)
+{
+ struct clk *ck_ref = clk_get(NULL, "ck_ref");
+ unsigned long rate;
+
+ BUG_ON(IS_ERR(ck_ref));
+
+ rate = clk_get_rate(ck_ref);
+ clk_put(ck_ref);
+
+ /* PTV = 0 */
+ rate /= 2;
+
+ omap_init_mpu_timer(rate);
+ omap_init_clocksource(rate);
+}
+
+#else
+static inline void omap_mpu_timer_init(void)
+{
+ pr_err("Bogus timer, should not happen\n");
+}
+#endif /* CONFIG_OMAP_MPU_TIMER */
+
+#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER)
+static unsigned long long (*preferred_sched_clock)(void);
+
+unsigned long long notrace sched_clock(void)
+{
+ if (!preferred_sched_clock)
+ return 0;
+
+ return preferred_sched_clock();
+}
+
+static inline void preferred_sched_clock_init(bool use_32k_sched_clock)
+{
+ if (use_32k_sched_clock)
+ preferred_sched_clock = omap_32k_sched_clock;
+ else
+ preferred_sched_clock = omap_mpu_sched_clock;
+}
+#else
+static inline void preferred_sched_clock_init(bool use_32k_sched_clcok)
+{
+}
+#endif
+
+static inline int omap_32k_timer_usable(void)
+{
+ int res = false;
+
+ if (cpu_is_omap730() || cpu_is_omap15xx())
+ return res;
+
+#ifdef CONFIG_OMAP_32K_TIMER
+ res = omap_32k_timer_init();
+#endif
+
+ return res;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init omap_timer_init(void)
+{
+ if (omap_32k_timer_usable()) {
+ preferred_sched_clock_init(1);
+ } else {
+ omap_mpu_timer_init();
+ preferred_sched_clock_init(0);
+ }
+}
+
+struct sys_timer omap_timer = {
+ .init = omap_timer_init,
+};
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
new file mode 100644
index 00000000..13d7b8f1
--- /dev/null
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -0,0 +1,193 @@
+/*
+ * linux/arch/arm/mach-omap1/timer32k.c
+ *
+ * OMAP 32K Timer
+ *
+ * Copyright (C) 2004 - 2005 Nokia Corporation
+ * Partial timer rewrite and additional dynamic tick timer support by
+ * Tony Lindgen <tony@atomide.com> and
+ * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * OMAP Dual-mode timer framework support by Timo Teras
+ *
+ * MPU timer code based on the older MPU timer code for OMAP
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <plat/common.h>
+#include <plat/dmtimer.h>
+
+/*
+ * ---------------------------------------------------------------------------
+ * 32KHz OS timer
+ *
+ * This currently works only on 16xx, as 1510 does not have the continuous
+ * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track
+ * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer
+ * on 1510 would be possible, but the timer would not be as accurate as
+ * with the 32KHz synchronized timer.
+ * ---------------------------------------------------------------------------
+ */
+
+/* 16xx specific defines */
+#define OMAP1_32K_TIMER_BASE 0xfffb9000
+#define OMAP1_32K_TIMER_CR 0x08
+#define OMAP1_32K_TIMER_TVR 0x00
+#define OMAP1_32K_TIMER_TCR 0x04
+
+#define OMAP_32K_TICKS_PER_SEC (32768)
+
+/*
+ * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1
+ * so with HZ = 128, TVR = 255.
+ */
+#define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1)
+
+#define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \
+ (((nr_jiffies) * (clock_rate)) / HZ)
+
+static inline void omap_32k_timer_write(int val, int reg)
+{
+ omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
+}
+
+static inline unsigned long omap_32k_timer_read(int reg)
+{
+ return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
+}
+
+static inline void omap_32k_timer_start(unsigned long load_val)
+{
+ if (!load_val)
+ load_val = 1;
+ omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR);
+ omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR);
+}
+
+static inline void omap_32k_timer_stop(void)
+{
+ omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR);
+}
+
+#define omap_32k_timer_ack_irq()
+
+static int omap_32k_timer_set_next_event(unsigned long delta,
+ struct clock_event_device *dev)
+{
+ omap_32k_timer_start(delta);
+
+ return 0;
+}
+
+static void omap_32k_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ omap_32k_timer_stop();
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_32k_timer = {
+ .name = "32k-timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap_32k_timer_set_next_event,
+ .set_mode = omap_32k_timer_set_mode,
+};
+
+static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_32k_timer;
+ omap_32k_timer_ack_irq();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap_32k_timer_irq = {
+ .name = "32KHz timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = omap_32k_timer_interrupt,
+};
+
+static __init void omap_init_32k_timer(void)
+{
+ setup_irq(INT_OS_TIMER, &omap_32k_timer_irq);
+
+ clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC,
+ NSEC_PER_SEC,
+ clockevent_32k_timer.shift);
+ clockevent_32k_timer.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer);
+ clockevent_32k_timer.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_32k_timer);
+
+ clockevent_32k_timer.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_32k_timer);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+bool __init omap_32k_timer_init(void)
+{
+ omap_init_clocksource_32k();
+
+#ifdef CONFIG_OMAP_DM_TIMER
+ omap_dm_timer_init();
+#endif
+ omap_init_32k_timer();
+
+ return true;
+}
diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c
new file mode 100644
index 00000000..19de03b0
--- /dev/null
+++ b/arch/arm/mach-omap1/usb.c
@@ -0,0 +1,530 @@
+/*
+ * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
+ *
+ * Copyright (C) 2004 Texas Instruments, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+
+#include <plat/mux.h>
+#include <plat/usb.h>
+
+/* These routines should handle the standard chip-specific modes
+ * for usb0/1/2 ports, covering basic mux and transceiver setup.
+ *
+ * Some board-*.c files will need to set up additional mux options,
+ * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
+ */
+
+/* TESTED ON:
+ * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
+ * - 5912 OSK UDC, with *nonstandard* A-to-A cable
+ * - 1510 Innovator UDC with bundled usb0 cable
+ * - 1510 Innovator OHCI with bundled usb1/usb2 cable
+ * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
+ * - 1710 custom development board using alternate pin group
+ * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ */
+
+#define INT_USB_IRQ_GEN IH2_BASE + 20
+#define INT_USB_IRQ_NISO IH2_BASE + 30
+#define INT_USB_IRQ_ISO IH2_BASE + 29
+#define INT_USB_IRQ_HGEN INT_USB_HHC_1
+#define INT_USB_IRQ_OTG IH2_BASE + 8
+
+#ifdef CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+ /* order is significant! */
+ { /* registers */
+ .start = UDC_BASE,
+ .end = UDC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, { /* general IRQ */
+ .start = INT_USB_IRQ_GEN,
+ .flags = IORESOURCE_IRQ,
+ }, { /* PIO IRQ */
+ .start = INT_USB_IRQ_NISO,
+ .flags = IORESOURCE_IRQ,
+ }, { /* SOF IRQ */
+ .start = INT_USB_IRQ_ISO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+ .name = "omap_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+};
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+ /* IRQ numbers for omap7xx */
+ if(cpu_is_omap7xx()) {
+ udc_resources[1].start = INT_7XX_USB_GENI;
+ udc_resources[2].start = INT_7XX_USB_NON_ISO;
+ udc_resources[3].start = INT_7XX_USB_ISO;
+ }
+ pdata->udc_device = &udc_device;
+}
+
+#else
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = OMAP_OHCI_BASE,
+ .end = OMAP_OHCI_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_IRQ_HGEN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+ if (cpu_is_omap7xx())
+ ohci_resources[1].start = INT_7XX_USB_HHC_1;
+ pdata->ohci_device = &ohci_device;
+}
+
+#else
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+ /* order is significant! */
+ {
+ .start = OTG_BASE,
+ .end = OTG_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_USB_IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device otg_device = {
+ .name = "omap_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(otg_resources),
+ .resource = otg_resources,
+};
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+ if (cpu_is_omap7xx())
+ otg_resources[1].start = INT_7XX_USB_OTG;
+ pdata->otg_device = &otg_device;
+}
+
+#else
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+u32 __init omap1_usb0_init(unsigned nwires, unsigned is_device)
+{
+ u32 syscon1 = 0;
+
+ if (nwires == 0) {
+ if (!cpu_is_omap15xx()) {
+ u32 l;
+
+ /* pulldown D+/D- */
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ return 0;
+ }
+
+ if (is_device) {
+ if (cpu_is_omap7xx()) {
+ omap_cfg_reg(AA17_7XX_USB_DM);
+ omap_cfg_reg(W16_7XX_USB_PU_EN);
+ omap_cfg_reg(W17_7XX_USB_VBUSI);
+ omap_cfg_reg(W18_7XX_USB_DMCK_OUT);
+ omap_cfg_reg(W19_7XX_USB_DCRST);
+ } else
+ omap_cfg_reg(W4_USB_PUEN);
+ }
+
+ if (nwires == 2) {
+ u32 l;
+
+ // omap_cfg_reg(P9_USB_DP);
+ // omap_cfg_reg(R8_USB_DM);
+
+ if (cpu_is_omap15xx()) {
+ /* This works on 1510-Innovator */
+ return 0;
+ }
+
+ /* NOTES:
+ * - peripheral should configure VBUS detection!
+ * - only peripherals may use the internal D+/D- pulldowns
+ * - OTG support on this port not yet written
+ */
+
+ /* Don't do this for omap7xx -- it causes USB to not work correctly */
+ if (!cpu_is_omap7xx()) {
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(7 << 4);
+ if (!is_device)
+ l |= (3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ return 3 << 16;
+ }
+
+ /* alternate pin config, external transceiver */
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
+ return 0;
+ }
+
+ omap_cfg_reg(V6_USB0_TXD);
+ omap_cfg_reg(W9_USB0_TXEN);
+ omap_cfg_reg(W5_USB0_SE0);
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB0_RCV);
+
+ /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
+ * may be able to use I2C requests to set those bits along
+ * with VBUS switching and overcurrent detection.
+ */
+
+ if (nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ {
+ u32 l;
+
+ omap_cfg_reg(AA9_USB0_VP);
+ omap_cfg_reg(R9_USB0_VM);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 0, nwires);
+ }
+
+ return syscon1 << 16;
+}
+
+u32 __init omap1_usb1_init(unsigned nwires)
+{
+ u32 syscon1 = 0;
+
+ if (!cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ if (nwires == 0)
+ return 0;
+
+ /* external transceiver */
+ omap_cfg_reg(USB1_TXD);
+ omap_cfg_reg(USB1_TXEN);
+ if (nwires != 3)
+ omap_cfg_reg(USB1_RCV);
+
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB1_SEO);
+ omap_cfg_reg(USB1_SPEED);
+ // SUSP
+ } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
+ omap_cfg_reg(W13_1610_USB1_SE0);
+ omap_cfg_reg(R13_1610_USB1_SPEED);
+ // SUSP
+ } else if (cpu_is_omap1710()) {
+ omap_cfg_reg(R13_1710_USB1_SE0);
+ // SUSP
+ } else {
+ pr_debug("usb%d cpu unrecognized\n", 1);
+ return 0;
+ }
+
+ switch (nwires) {
+ case 2:
+ goto bad;
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ omap_cfg_reg(USB1_VP);
+ omap_cfg_reg(USB1_VM);
+ if (!cpu_is_omap15xx()) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+bad:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 1, nwires);
+ }
+
+ return syscon1 << 20;
+}
+
+u32 __init omap1_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ u32 syscon1 = 0;
+
+ /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
+ if (alt_pingroup || nwires == 0)
+ return 0;
+
+ if (!cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ /* external transceiver */
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB2_TXD);
+ omap_cfg_reg(USB2_TXEN);
+ omap_cfg_reg(USB2_SEO);
+ if (nwires != 3)
+ omap_cfg_reg(USB2_RCV);
+ /* there is no USB2_SPEED */
+ } else if (cpu_is_omap16xx()) {
+ omap_cfg_reg(V6_USB2_TXD);
+ omap_cfg_reg(W9_USB2_TXEN);
+ omap_cfg_reg(W5_USB2_SE0);
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB2_RCV);
+ // FIXME omap_cfg_reg(USB2_SPEED);
+ } else {
+ pr_debug("usb%d cpu unrecognized\n", 1);
+ return 0;
+ }
+
+ // omap_cfg_reg(USB2_SUSP);
+
+ switch (nwires) {
+ case 2:
+ goto bad;
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 5:
+ goto bad;
+ case 6:
+ syscon1 = 3;
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB2_VP);
+ omap_cfg_reg(USB2_VM);
+ } else {
+ u32 l;
+
+ omap_cfg_reg(AA9_USB2_VP);
+ omap_cfg_reg(R9_USB2_VM);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+bad:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 2, nwires);
+ }
+
+ return syscon1 << 24;
+}
+
+#ifdef CONFIG_ARCH_OMAP15XX
+
+/* ULPD_DPLL_CTRL */
+#define DPLL_IOB (1 << 13)
+#define DPLL_PLL_ENABLE (1 << 4)
+#define DPLL_LOCK (1 << 0)
+
+/* ULPD_APLL_CTRL */
+#define APLL_NDPLL_SWITCH (1 << 0)
+
+static void __init omap_1510_usb_init(struct omap_usb_config *config)
+{
+ unsigned int val;
+ u16 w;
+
+ config->usb0_init(config->pins[0], is_usb0_device(config));
+ config->usb1_init(config->pins[1]);
+ config->usb2_init(config->pins[2], 0);
+
+ val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
+ val |= (config->hmc_mode << 1);
+ omap_writel(val, MOD_CONF_CTRL_0);
+
+ printk("USB: hmc %d", config->hmc_mode);
+ if (config->pins[0])
+ printk(", usb0 %d wires%s", config->pins[0],
+ is_usb0_device(config) ? " (dev)" : "");
+ if (config->pins[1])
+ printk(", usb1 %d wires", config->pins[1]);
+ if (config->pins[2])
+ printk(", usb2 %d wires", config->pins[2]);
+ printk("\n");
+
+ /* use DPLL for 48 MHz function clock */
+ pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL),
+ omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ));
+
+ w = omap_readw(ULPD_APLL_CTRL);
+ w &= ~APLL_NDPLL_SWITCH;
+ omap_writew(w, ULPD_APLL_CTRL);
+
+ w = omap_readw(ULPD_DPLL_CTRL);
+ w |= DPLL_IOB | DPLL_PLL_ENABLE;
+ omap_writew(w, ULPD_DPLL_CTRL);
+
+ w = omap_readw(ULPD_SOFT_REQ);
+ w |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
+ omap_writew(w, ULPD_SOFT_REQ);
+
+ while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK))
+ cpu_relax();
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ if (config->register_dev) {
+ int status;
+
+ udc_device.dev.platform_data = config;
+ status = platform_device_register(&udc_device);
+ if (status)
+ pr_debug("can't register UDC device, %d\n", status);
+ /* udc driver gates 48MHz by D+ pullup */
+ }
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ if (config->register_host) {
+ int status;
+
+ ohci_device.dev.platform_data = config;
+ status = platform_device_register(&ohci_device);
+ if (status)
+ pr_debug("can't register OHCI device, %d\n", status);
+ /* hcd explicitly gates 48MHz */
+ }
+#endif
+}
+
+#else
+static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
+#endif
+
+void __init omap1_usb_init(struct omap_usb_config *pdata)
+{
+ pdata->usb0_init = omap1_usb0_init;
+ pdata->usb1_init = omap1_usb1_init;
+ pdata->usb2_init = omap1_usb2_init;
+ udc_device_init(pdata);
+ ohci_device_init(pdata);
+ otg_device_init(pdata);
+
+ if (cpu_is_omap7xx() || cpu_is_omap16xx())
+ omap_otg_init(pdata);
+ else if (cpu_is_omap15xx())
+ omap_1510_usb_init(pdata);
+ else
+ printk(KERN_ERR "USB: No init for your chip yet\n");
+}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
new file mode 100644
index 00000000..841ae21f
--- /dev/null
+++ b/arch/arm/mach-omap2/Kconfig
@@ -0,0 +1,348 @@
+if ARCH_OMAP2PLUS
+
+menu "TI OMAP2/3/4 Specific Features"
+
+config ARCH_OMAP2PLUS_TYPICAL
+ bool "Typical OMAP configuration"
+ default y
+ select AEABI
+ select REGULATOR
+ select PM
+ select PM_RUNTIME
+ select VFP
+ select NEON if ARCH_OMAP3 || ARCH_OMAP4
+ select SERIAL_OMAP
+ select SERIAL_OMAP_CONSOLE
+ select I2C
+ select I2C_OMAP
+ select MFD_SUPPORT
+ select MENELAUS if ARCH_OMAP2
+ select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
+ select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+ help
+ Compile a kernel suitable for booting most boards
+
+config ARCH_OMAP2
+ bool "TI OMAP2"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V6
+
+config ARCH_OMAP3
+ bool "TI OMAP3"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V7
+ select USB_ARCH_HAS_EHCI
+ select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
+
+config ARCH_OMAP4
+ bool "TI OMAP4"
+ default y
+ depends on ARCH_OMAP2PLUS
+ select CPU_V7
+ select ARM_GIC
+ select LOCAL_TIMERS if SMP
+ select PL310_ERRATA_588369
+ select PL310_ERRATA_727915
+ select ARM_ERRATA_720789
+ select ARCH_HAS_OPP
+ select PM_OPP if PM
+ select USB_ARCH_HAS_EHCI
+
+comment "OMAP Core Type"
+ depends on ARCH_OMAP2
+
+config SOC_OMAP2420
+ bool "OMAP2420 support"
+ depends on ARCH_OMAP2
+ default y
+ select OMAP_DM_TIMER
+ select ARCH_OMAP_OTG
+
+config SOC_OMAP2430
+ bool "OMAP2430 support"
+ depends on ARCH_OMAP2
+ default y
+ select ARCH_OMAP_OTG
+
+config SOC_OMAP3430
+ bool "OMAP3430 support"
+ depends on ARCH_OMAP3
+ default y
+ select ARCH_OMAP_OTG
+
+config SOC_OMAPTI816X
+ bool "TI816X support"
+ depends on ARCH_OMAP3
+ default y
+
+config OMAP_PACKAGE_ZAF
+ bool
+
+config OMAP_PACKAGE_ZAC
+ bool
+
+config OMAP_PACKAGE_CBC
+ bool
+
+config OMAP_PACKAGE_CBB
+ bool
+
+config OMAP_PACKAGE_CUS
+ bool
+
+config OMAP_PACKAGE_CBP
+ bool
+
+config OMAP_PACKAGE_CBL
+ bool
+
+config OMAP_PACKAGE_CBS
+ bool
+
+comment "OMAP Board Type"
+ depends on ARCH_OMAP2PLUS
+
+config MACH_OMAP_GENERIC
+ bool "Generic OMAP board"
+ depends on ARCH_OMAP2
+ default y
+
+config MACH_OMAP2_TUSB6010
+ bool
+ depends on ARCH_OMAP2 && SOC_OMAP2420
+ default y if MACH_NOKIA_N8X0
+
+config MACH_OMAP_H4
+ bool "OMAP 2420 H4 board"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAF
+ select OMAP_DEBUG_DEVICES
+
+config MACH_OMAP_APOLLON
+ bool "OMAP 2420 Apollon board"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAC
+
+config MACH_OMAP_2430SDP
+ bool "OMAP 2430 SDP board"
+ depends on SOC_OMAP2430
+ default y
+ select OMAP_PACKAGE_ZAC
+
+config MACH_OMAP3_BEAGLE
+ bool "OMAP3 BEAGLE board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_DEVKIT8000
+ bool "DEVKIT8000 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CUS
+
+config MACH_OMAP_LDP
+ bool "OMAP3 LDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3530_LV_SOM
+ bool "OMAP3 Logic 3530 LV SOM board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP3530 SOM Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/texas-instruments-zoom%E2%84%A2-omap35x-development-kit
+
+config MACH_OMAP3_TORPEDO
+ bool "OMAP3 Logic 35x Torpedo board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+ default y
+ help
+ Support for the LogicPD OMAP35x Torpedo Development kit
+ for full description please see the products webpage at
+ http://www.logicpd.com/products/development-kits/zoom-omap35x-torpedo-development-kit
+
+config MACH_OVERO
+ bool "Gumstix Overo board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3EVM
+ bool "OMAP 3530 EVM board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3517EVM
+ bool "OMAP3517/ AM3517 EVM board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_CRANEBOARD
+ bool "AM3517/05 CRANE board"
+ depends on ARCH_OMAP3
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP3_PANDORA
+ bool "OMAP3 Pandora"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select REGULATOR_FIXED_VOLTAGE
+
+config MACH_OMAP3_TOUCHBOOK
+ bool "OMAP3 Touch Book"
+ depends on ARCH_OMAP3
+ default y
+ select BACKLIGHT_CLASS_DEVICE
+
+config MACH_OMAP_3430SDP
+ bool "OMAP 3430 SDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_NOKIA_N800
+ bool
+
+config MACH_NOKIA_N810
+ bool
+
+config MACH_NOKIA_N810_WIMAX
+ bool
+
+config MACH_NOKIA_N8X0
+ bool "Nokia N800/N810"
+ depends on SOC_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAC
+ select MACH_NOKIA_N800
+ select MACH_NOKIA_N810
+ select MACH_NOKIA_N810_WIMAX
+
+config MACH_NOKIA_RM680
+ bool "Nokia RM-680 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_NOKIA_RX51
+ bool "Nokia RX-51 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_OMAP_ZOOM2
+ bool "OMAP3 Zoom2 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE
+
+config MACH_OMAP_ZOOM3
+ bool "OMAP3630 Zoom3 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBP
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
+ select REGULATOR_FIXED_VOLTAGE
+
+config MACH_CM_T35
+ bool "CompuLab CM-T35 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CUS
+
+config MACH_CM_T3517
+ bool "CompuLab CM-T3517 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_IGEP0020
+ bool "IGEP v2 board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+
+config MACH_IGEP0030
+ bool "IGEP OMAP3 module"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBB
+ select MACH_IGEP0020
+
+config MACH_SBC3530
+ bool "OMAP3 SBC STALKER board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CUS
+
+config MACH_OMAP_3630SDP
+ bool "OMAP3630 SDP board"
+ depends on ARCH_OMAP3
+ default y
+ select OMAP_PACKAGE_CBP
+
+config MACH_TI8168EVM
+ bool "TI8168 Evaluation Module"
+ depends on SOC_OMAPTI816X
+ default y
+
+config MACH_OMAP_4430SDP
+ bool "OMAP 4430 SDP board"
+ default y
+ depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
+ select REGULATOR_FIXED_VOLTAGE
+
+config MACH_OMAP4_PANDA
+ bool "OMAP4 Panda Board"
+ default y
+ depends on ARCH_OMAP4
+ select OMAP_PACKAGE_CBL
+ select OMAP_PACKAGE_CBS
+ select REGULATOR_FIXED_VOLTAGE
+
+config OMAP3_EMU
+ bool "OMAP3 debugging peripherals"
+ depends on ARCH_OMAP3
+ select ARM_AMBA
+ select OC_ETM
+ help
+ Say Y here to enable debugging hardware of omap3
+
+config OMAP3_SDRC_AC_TIMING
+ bool "Enable SDRC AC timing register changes"
+ depends on ARCH_OMAP3
+ default n
+ help
+ If you know that none of your system initiators will attempt to
+ access SDRAM during CORE DVFS, select Y here. This should boost
+ SDRAM performance at lower CORE OPPs. There are relatively few
+ users who will wish to say yes at this point - almost everyone will
+ wish to say no. Selecting yes without understanding what is
+ going on could result in system crashes;
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
new file mode 100644
index 00000000..b1480779
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile
@@ -0,0 +1,272 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o \
+ common.o gpio.o dma.o wd_timer.o
+
+omap-2-3-common = irq.o sdrc.o
+hwmod-common = omap_hwmod.o \
+ omap_hwmod_common_data.o
+clock-common = clock.o clock_common_data.o \
+ clkt_dpll.o clkt_clksel.o
+
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
+
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+
+obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
+
+# SMP support ONLY available for OMAP4
+obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
+obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
+obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
+obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o
+
+plus_sec := $(call as-instr,.arch_extension sec,+sec)
+AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec)
+
+# Functions loaded to SRAM
+obj-$(CONFIG_SOC_OMAP2420) += sram242x.o
+obj-$(CONFIG_SOC_OMAP2430) += sram243x.o
+obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o
+
+AFLAGS_sram242x.o :=-Wa,-march=armv6
+AFLAGS_sram243x.o :=-Wa,-march=armv6
+AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
+
+# Pin multiplexing
+obj-$(CONFIG_SOC_OMAP2420) += mux2420.o
+obj-$(CONFIG_SOC_OMAP2430) += mux2430.o
+obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
+
+# SMS/SDRC
+obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
+# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
+
+# OPP table initialization
+ifeq ($(CONFIG_PM_OPP),y)
+obj-y += opp.o
+obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
+endif
+
+# Power Management
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
+obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \
+ cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o
+obj-$(CONFIG_PM_DEBUG) += pm-debug.o
+obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
+obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
+
+AFLAGS_sleep24xx.o :=-Wa,-march=armv6
+AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec)
+
+ifeq ($(CONFIG_PM_VERBOSE),y)
+CFLAGS_pm_bus.o += -DDEBUG
+endif
+
+endif
+
+# PRCM
+obj-$(CONFIG_ARCH_OMAP2) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o
+obj-$(CONFIG_ARCH_OMAP3) += prcm.o cm2xxx_3xxx.o prm2xxx_3xxx.o \
+ vc3xxx_data.o vp3xxx_data.o
+# XXX The presence of cm2xxx_3xxx.o on the line below is temporary and
+# will be removed once the OMAP4 part of the codebase is converted to
+# use OMAP4-specific PRCM functions.
+obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
+ cm44xx.o prcm_mpu44xx.o \
+ prminst44xx.o vc44xx_data.o \
+ vp44xx_data.o
+
+# OMAP voltage domains
+ifeq ($(CONFIG_PM),y)
+voltagedomain-common := voltage.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
+ voltagedomains3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
+ voltagedomains44xx_data.o
+endif
+
+# OMAP powerdomain framework
+powerdomain-common += powerdomain.o powerdomain-common.o
+obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains2xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(powerdomain-common) \
+ powerdomain2xxx_3xxx.o \
+ powerdomains3xxx_data.o \
+ powerdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
+ powerdomain44xx.o \
+ powerdomains44xx_data.o
+
+# PRCM clockdomain control
+obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
+ clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
+ clockdomain2xxx_3xxx.o \
+ clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
+ clockdomain44xx.o \
+ clockdomains44xx_data.o
+
+# Clock framework
+obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o \
+ clkt2xxx_sys.o \
+ clkt2xxx_dpllcore.o \
+ clkt2xxx_virt_prcm_set.o \
+ clkt2xxx_apll.o clkt2xxx_osc.o \
+ clkt2xxx_dpll.o clkt_iclk.o
+obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \
+ clock34xx.o clkt34xx_dpll3m2.o \
+ clock3517.o clock36xx.o \
+ dpll3xxx.o clock3xxx_data.o \
+ clkt_iclk.o
+obj-$(CONFIG_ARCH_OMAP4) += $(clock-common) clock44xx_data.o \
+ dpll3xxx.o dpll44xx.o
+
+# OMAP2 clock rate set data (old "OPP" data)
+obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o
+
+# hwmod data
+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
+
+# EMU peripherals
+obj-$(CONFIG_OMAP3_EMU) += emu.o
+
+# L3 interconnect
+obj-$(CONFIG_ARCH_OMAP3) += omap_l3_smx.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_l3_noc.o
+
+obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
+mailbox_mach-objs := mailbox.o
+
+obj-$(CONFIG_OMAP_IOMMU) += iommu2.o
+
+iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
+obj-y += $(iommu-m) $(iommu-y)
+
+i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+obj-y += $(i2c-omap-m) $(i2c-omap-y)
+
+ifneq ($(CONFIG_TIDSPBRIDGE),)
+obj-y += dsp.o
+endif
+
+# Specific board support
+obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
+obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
+obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
+ board-flash.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OVERO) += board-overo.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
+ hsmmc.o \
+ board-flash.o
+obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
+obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
+ sdram-nokia.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
+ sdram-nokia.o \
+ board-rx51-peripherals.o \
+ board-rx51-video.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o \
+ board-flash.o \
+ hsmmc.o \
+ board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o \
+ board-flash.o \
+ hsmmc.o \
+ board-zoom-debugboard.o
+obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
+ board-zoom-peripherals.o \
+ board-zoom-display.o \
+ board-flash.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
+obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \
+ hsmmc.o \
+ omap_phy_internal.o
+obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \
+ hsmmc.o \
+ omap_phy_internal.o
+
+obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \
+ omap_phy_internal.o \
+
+obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
+
+obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \
+ hsmmc.o
+obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o
+# Platform specific device init code
+usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o
+obj-y += $(usbfs-m) $(usbfs-y)
+obj-y += usb-musb.o
+obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o
+obj-y += usb-host.o
+
+onenand-$(CONFIG_MTD_ONENAND_OMAP2) := gpmc-onenand.o
+obj-y += $(onenand-m) $(onenand-y)
+
+nand-$(CONFIG_MTD_NAND_OMAP2) := gpmc-nand.o
+obj-y += $(nand-m) $(nand-y)
+
+smc91x-$(CONFIG_SMC91X) := gpmc-smc91x.o
+obj-y += $(smc91x-m) $(smc91x-y)
+
+smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
+obj-y += $(smsc911x-m) $(smsc911x-y)
+obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o
+
+disp-$(CONFIG_OMAP2_DSS) := display.o
+obj-y += $(disp-m) $(disp-y)
+
+obj-y += common-board-devices.o
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
new file mode 100644
index 00000000..565aff7f
--- /dev/null
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
new file mode 100644
index 00000000..5de6eac0
--- /dev/null
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/arm/mach-omap2/board-2430sdp.c
+ *
+ * Copyright (C) 2006 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial Code : Based on a patch from Komal Shah and Richard Woodruff
+ * Updated the Code for 2430 SDP : Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mmc/host.h>
+#include <linux/delay.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc-smc91x.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define SDP2430_CS0_BASE 0x04000000
+#define SECONDARY_LCD_GPIO 147
+
+static struct mtd_partition sdp2430_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data sdp2430_flash_data = {
+ .width = 2,
+ .parts = sdp2430_partitions,
+ .nr_parts = ARRAY_SIZE(sdp2430_partitions),
+};
+
+static struct resource sdp2430_flash_resource = {
+ .start = SDP2430_CS0_BASE,
+ .end = SDP2430_CS0_BASE + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device sdp2430_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &sdp2430_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &sdp2430_flash_resource,
+};
+
+static struct platform_device sdp2430_lcd_device = {
+ .name = "sdp2430_lcd",
+ .id = -1,
+};
+
+static struct platform_device *sdp2430_devices[] __initdata = {
+ &sdp2430_flash_device,
+ &sdp2430_lcd_device,
+};
+
+static struct omap_lcd_config sdp2430_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 5,
+ .gpio_irq = 149,
+ .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
+ IORESOURCE_IRQ_LOWLEVEL,
+
+};
+
+static void __init board_smc91x_init(void)
+{
+ omap_mux_init_gpio(149, OMAP_PIN_INPUT);
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static struct omap_board_config_kernel sdp2430_config[] __initdata = {
+ {OMAP_TAG_LCD, &sdp2430_lcd_config},
+};
+
+static void __init omap_2430sdp_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static struct regulator_consumer_supply sdp2430_vmmc1_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp2430_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp2430_vmmc1_supplies),
+ .consumer_supplies = &sdp2430_vmmc1_supplies[0],
+};
+
+static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_platform_data sdp2430_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &sdp2430_gpio_data,
+ .vmmc1 = &sdp2430_vmmc1,
+};
+
+static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2D),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = OMAP_GPIO_IRQ(78),
+ },
+};
+
+static int __init omap2430_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo,
+ ARRAY_SIZE(sdp2430_i2c1_boardinfo));
+ omap2_pmic_init("twl4030", &sdp2430_twldata);
+ return 0;
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ext_clock = 1,
+ },
+ {} /* Terminator */
+};
+
+static struct omap_usb_config sdp2430_usb_config __initdata = {
+ .otg = 1,
+#ifdef CONFIG_USB_GADGET_OMAP
+ .hmc_mode = 0x0,
+#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ .hmc_mode = 0x1,
+#endif
+ .pins[0] = 3,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_2430sdp_init(void)
+{
+ omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+
+ omap_board_config = sdp2430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp2430_config);
+
+ omap2430_i2c_init();
+
+ platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
+ omap_serial_init();
+ omap2_hsmmc_init(mmc);
+ omap2_usbfs_init(&sdp2430_usb_config);
+
+ omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
+ usb_musb_init(NULL);
+
+ board_smc91x_init();
+
+ /* Turn off secondary LCD backlight */
+ gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
+ "Secondary LCD backlight");
+}
+
+static void __init omap_2430sdp_map_io(void)
+{
+ omap2_set_globals_243x();
+ omap243x_map_common_io();
+}
+
+MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap_2430sdp_map_io,
+ .init_early = omap_2430sdp_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_2430sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
new file mode 100644
index 00000000..5dac974b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -0,0 +1,810 @@
+/*
+ * linux/arch/arm/mach-omap2/board-3430sdp.c
+ *
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/usb.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include <plat/gpmc-smc91x.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-qimonda-hyb18m512160af-6.h"
+#include "hsmmc.h"
+#include "pm.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define CONFIG_DISABLE_HFCLK 1
+
+#define SDP3430_TS_GPIO_IRQ_SDPV1 3
+#define SDP3430_TS_GPIO_IRQ_SDPV2 2
+
+#define ENABLE_VAUX3_DEDICATED 0x03
+#define ENABLE_VAUX3_DEV_GRP 0x20
+
+#define TWL4030_MSECURE_GPIO 22
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(0, 4, KEY_C),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(1, 4, KEY_G),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_3),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(3, 4, KEY_Q),
+ KEY(4, 0, KEY_R),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_T),
+ KEY(4, 3, KEY_U),
+ KEY(4, 4, KEY_D),
+ KEY(5, 0, KEY_V),
+ KEY(5, 1, KEY_W),
+ KEY(5, 2, KEY_L),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_H),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data sdp3430_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 5,
+ .cols = 6,
+ .rep = 1,
+};
+
+#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8
+#define SDP3430_LCD_PANEL_ENABLE_GPIO 5
+
+static struct gpio sdp3430_dss_gpios[] __initdata = {
+ {SDP3430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "LCD reset" },
+ {SDP3430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD Backlight"},
+};
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init sdp3430_display_init(void)
+{
+ int r;
+
+ r = gpio_request_array(sdp3430_dss_gpios,
+ ARRAY_SIZE(sdp3430_dss_gpios));
+ if (r)
+ printk(KERN_ERR "failed to get LCD control GPIOs\n");
+
+}
+
+static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 1);
+ gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ lcd_enabled = 0;
+
+ gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 0);
+ gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void sdp3430_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static int sdp3430_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void sdp3430_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+
+static struct omap_dss_device sdp3430_lcd_device = {
+ .name = "lcd",
+ .driver_name = "sharp_ls_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 16,
+ .platform_enable = sdp3430_panel_enable_lcd,
+ .platform_disable = sdp3430_panel_disable_lcd,
+};
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = sdp3430_panel_enable_dvi,
+ .platform_disable = sdp3430_panel_disable_dvi,
+};
+
+static struct omap_dss_device sdp3430_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device sdp3430_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = sdp3430_panel_enable_tv,
+ .platform_disable = sdp3430_panel_disable_tv,
+};
+
+
+static struct omap_dss_device *sdp3430_dss_devices[] = {
+ &sdp3430_lcd_device,
+ &sdp3430_dvi_device,
+ &sdp3430_tv_device,
+};
+
+static struct omap_dss_board_info sdp3430_dss_data = {
+ .num_devices = ARRAY_SIZE(sdp3430_dss_devices),
+ .devices = sdp3430_dss_devices,
+ .default_device = &sdp3430_lcd_device,
+};
+
+static struct omap_board_config_kernel sdp3430_config[] __initdata = {
+};
+
+static void __init omap_3430sdp_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL);
+}
+
+static int sdp3430_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
+8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
+5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
+4040, 3910, 3790, 3670, 3550
+};
+
+static struct twl4030_bci_platform_data sdp3430_bci_data = {
+ .battery_tmp_tbl = sdp3430_batt_table,
+ .tblsize = ARRAY_SIZE(sdp3430_batt_table),
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ /* 8 bits (default) requires S6.3 == ON,
+ * so the SIM card isn't used; else 4 bits.
+ */
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 4,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 7,
+ },
+ {} /* Terminator */
+};
+
+static int sdp3430_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ),
+ * gpio + 1 is "mmc1_cd" (input/IRQ)
+ */
+ mmc[0].gpio_cd = gpio + 0;
+ mmc[1].gpio_cd = gpio + 1;
+ omap2_hsmmc_init(mmc);
+
+ /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
+
+ /* gpio + 15 is "sub_lcd_nRST" (output) */
+ gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST");
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data sdp3430_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(16) | BIT(17),
+ .setup = sdp3430_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data sdp3430_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_madc_platform_data sdp3430_madc_data = {
+ .irq_line = 1,
+};
+
+/* regulator consumer mappings */
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = {
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vsim_supplies[] = {
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"),
+};
+
+static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+/*
+ * Apply all the fixed voltages since most versions of U-Boot
+ * don't bother with that initialization.
+ */
+
+/* VAUX1 for mainboard (irda and sub-lcd) */
+static struct regulator_init_data sdp3430_vaux1 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX2 for camera module */
+static struct regulator_init_data sdp3430_vaux2 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX3 for LCD board */
+static struct regulator_init_data sdp3430_vaux3 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies),
+ .consumer_supplies = sdp3430_vaux3_supplies,
+};
+
+/* VAUX4 for OMAP VDD_CSI2 (camera) */
+static struct regulator_init_data sdp3430_vaux4 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data sdp3430_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc1_supplies),
+ .consumer_supplies = sdp3430_vmmc1_supplies,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data sdp3430_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 1850000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies),
+ .consumer_supplies = sdp3430_vmmc2_supplies,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data sdp3430_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vsim_supplies),
+ .consumer_supplies = sdp3430_vsim_supplies,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data sdp3430_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vdda_dac_supplies),
+ .consumer_supplies = sdp3430_vdda_dac_supplies,
+};
+
+static struct regulator_init_data sdp3430_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vpll2_supplies),
+ .consumer_supplies = sdp3430_vpll2_supplies,
+};
+
+static struct twl4030_codec_audio_data sdp3430_audio;
+
+static struct twl4030_codec_data sdp3430_codec = {
+ .audio_mclk = 26000000,
+ .audio = &sdp3430_audio,
+};
+
+static struct twl4030_platform_data sdp3430_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .bci = &sdp3430_bci_data,
+ .gpio = &sdp3430_gpio_data,
+ .madc = &sdp3430_madc_data,
+ .keypad = &sdp3430_kp_data,
+ .usb = &sdp3430_usb_data,
+ .codec = &sdp3430_codec,
+
+ .vaux1 = &sdp3430_vaux1,
+ .vaux2 = &sdp3430_vaux2,
+ .vaux3 = &sdp3430_vaux3,
+ .vaux4 = &sdp3430_vaux4,
+ .vmmc1 = &sdp3430_vmmc1,
+ .vmmc2 = &sdp3430_vmmc2,
+ .vsim = &sdp3430_vsim,
+ .vdac = &sdp3430_vdac,
+ .vpll2 = &sdp3430_vpll2,
+};
+
+static int __init omap3430_i2c_init(void)
+{
+ /* i2c1 for PMIC only */
+ omap3_pmic_init("twl4030", &sdp3430_twldata);
+ /* i2c2 on camera connector (for sensor control) and optional isp1301 */
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ /* i2c3 on display connector (for DVI, tfp410) */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 3,
+ .flags = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
+ IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ board_smc91x_data.gpio_irq = 6;
+ else
+ board_smc91x_data.gpio_irq = 29;
+
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 57,
+ .reset_gpio_port[1] = 61,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_device_pad serial1_pads[] __initdata = {
+ /*
+ * Note that off output enable is an active low
+ * signal. So setting this means pin is a
+ * input enabled in off mode
+ */
+ OMAP_MUX_STATIC("uart1_cts.uart1_cts",
+ OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart1_rts.uart1_rts",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart1_rx.uart1_rx",
+ OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart1_tx.uart1_tx",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart2_cts.uart2_cts",
+ OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rts.uart2_rts",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rx.uart2_rx",
+ OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_tx.uart2_tx",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial3_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
+ OMAP_PIN_INPUT_PULLDOWN |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
+ OMAP_PIN_INPUT |
+ OMAP_PIN_OFF_INPUT_PULLDOWN |
+ OMAP_OFFOUT_EN |
+ OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
+ OMAP_PIN_OUTPUT |
+ OMAP_OFF_EN |
+ OMAP_MUX_MODE0),
+};
+
+static struct omap_board_data serial1_data __initdata = {
+ .id = 0,
+ .pads = serial1_pads,
+ .pads_cnt = ARRAY_SIZE(serial1_pads),
+};
+
+static struct omap_board_data serial2_data __initdata = {
+ .id = 1,
+ .pads = serial2_pads,
+ .pads_cnt = ARRAY_SIZE(serial2_pads),
+};
+
+static struct omap_board_data serial3_data __initdata = {
+ .id = 2,
+ .pads = serial3_pads,
+ .pads_cnt = ARRAY_SIZE(serial3_pads),
+};
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init_port(&serial1_data);
+ omap_serial_init_port(&serial2_data);
+ omap_serial_init_port(&serial3_data);
+}
+#else
+#define board_mux NULL
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+#endif
+
+/*
+ * SDP3430 V2 Board CS organization
+ * Different from SDP3430 V1. Now 4 switches used to specify CS
+ *
+ * See also the Switch S8 settings in the comments.
+ */
+static char chip_sel_3430[][GPMC_CS_NUM] = {
+ {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
+ {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
+ {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
+};
+
+static struct mtd_partition sdp_nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "Bootloader-NOR",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "Params-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "Kernel-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "Filesystem-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+ {
+ .name = "X-Loader-OneNAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot Environment-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * (64 * 2048),
+ },
+ {
+ .name = "File System-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition sdp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 6 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 40 * (64 * 2048),
+ },
+ {
+ .name = "File System - NAND",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */
+ },
+};
+
+static struct flash_partitions sdp_flash_partitions[] = {
+ {
+ .parts = sdp_nor_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nor_partitions),
+ },
+ {
+ .parts = sdp_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
+ },
+ {
+ .parts = sdp_nand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nand_partitions),
+ },
+};
+
+static void __init omap_3430sdp_init(void)
+{
+ int gpio_pendown;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = sdp3430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp3430_config);
+ omap3430_i2c_init();
+ omap_display_init(&sdp3430_dss_data);
+ if (omap_rev() > OMAP3430_REV_ES1_0)
+ gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2;
+ else
+ gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
+ omap_ads7846_init(1, gpio_pendown, 310, NULL);
+ board_serial_init();
+ usb_musb_init(NULL);
+ board_smc91x_init();
+ board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
+ sdp3430_display_init();
+ enable_board_wakeup_source();
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
+ /* Maintainer: Syed Khasim - Texas Instruments Inc */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap_3430sdp_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_3430sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
new file mode 100644
index 00000000..a5933cc1
--- /dev/null
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/gpmc-smc91x.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 3,
+ .flags = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ board_smc91x_data.gpio_irq = 158;
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif /* defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) */
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 126,
+ .reset_gpio_port[1] = 61,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static struct omap_board_config_kernel sdp_config[] __initdata = {
+};
+
+static void __init omap_sdp_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+/*
+ * SDP3630 CS organization
+ * See also the Switch S8 settings in the comments.
+ */
+static char chip_sel_sdp[][GPMC_CS_NUM] = {
+ {PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0}, /* S8:1111 */
+ {PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1110 */
+ {PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0}, /* S8:1101 */
+};
+
+static struct mtd_partition sdp_nor_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "Bootloader-NOR",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "Params-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "Kernel-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "Filesystem-NOR",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct mtd_partition sdp_onenand_partitions[] = {
+ {
+ .name = "X-Loader-OneNAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "U-Boot Environment-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 16 * (64 * 2048),
+ },
+ {
+ .name = "File System-OneNAND",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition sdp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 6 * (64 * 2048),
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 40 * (64 * 2048),
+ },
+ {
+ .name = "File System - NAND",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x780000 */
+ },
+};
+
+static struct flash_partitions sdp_flash_partitions[] = {
+ {
+ .parts = sdp_nor_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nor_partitions),
+ },
+ {
+ .parts = sdp_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_onenand_partitions),
+ },
+ {
+ .parts = sdp_nand_partitions,
+ .nr_parts = ARRAY_SIZE(sdp_nand_partitions),
+ },
+};
+
+static void __init omap_sdp_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_board_config = sdp_config;
+ omap_board_config_size = ARRAY_SIZE(sdp_config);
+ zoom_peripherals_init();
+ zoom_display_init();
+ board_smc91x_init();
+ board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
+ enable_board_wakeup_source();
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap_sdp_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
new file mode 100644
index 00000000..14a5971d
--- /dev/null
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -0,0 +1,774 @@
+/*
+ * Board support file for OMAP4430 SDP.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/twl.h>
+#include <linux/gpio_keys.h>
+#include <linux/regulator/machine.h>
+#include <linux/leds.h>
+#include <linux/leds_pwm.h>
+
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+#include <plat/mmc.h>
+#include <plat/omap4-keypad.h>
+#include <video/omapdss.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define ETH_KS8851_IRQ 34
+#define ETH_KS8851_POWER_ON 48
+#define ETH_KS8851_QUART 138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
+#define OMAP4_SFH7741_ENABLE_GPIO 188
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+
+static const int sdp4430_keymap[] = {
+ KEY(0, 0, KEY_E),
+ KEY(0, 1, KEY_R),
+ KEY(0, 2, KEY_T),
+ KEY(0, 3, KEY_HOME),
+ KEY(0, 4, KEY_F5),
+ KEY(0, 5, KEY_UNKNOWN),
+ KEY(0, 6, KEY_I),
+ KEY(0, 7, KEY_LEFTSHIFT),
+
+ KEY(1, 0, KEY_D),
+ KEY(1, 1, KEY_F),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_SEND),
+ KEY(1, 4, KEY_F6),
+ KEY(1, 5, KEY_UNKNOWN),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_ENTER),
+
+ KEY(2, 0, KEY_X),
+ KEY(2, 1, KEY_C),
+ KEY(2, 2, KEY_V),
+ KEY(2, 3, KEY_END),
+ KEY(2, 4, KEY_F7),
+ KEY(2, 5, KEY_UNKNOWN),
+ KEY(2, 6, KEY_DOT),
+ KEY(2, 7, KEY_CAPSLOCK),
+
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_KPPLUS),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_F1),
+ KEY(3, 4, KEY_F8),
+ KEY(3, 5, KEY_UNKNOWN),
+ KEY(3, 6, KEY_O),
+ KEY(3, 7, KEY_SPACE),
+
+ KEY(4, 0, KEY_W),
+ KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_U),
+ KEY(4, 3, KEY_F2),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(4, 5, KEY_UNKNOWN),
+ KEY(4, 6, KEY_L),
+ KEY(4, 7, KEY_LEFT),
+
+ KEY(5, 0, KEY_S),
+ KEY(5, 1, KEY_H),
+ KEY(5, 2, KEY_J),
+ KEY(5, 3, KEY_F3),
+ KEY(5, 4, KEY_F9),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ KEY(5, 6, KEY_M),
+ KEY(5, 7, KEY_RIGHT),
+
+ KEY(6, 0, KEY_Q),
+ KEY(6, 1, KEY_A),
+ KEY(6, 2, KEY_N),
+ KEY(6, 3, KEY_BACK),
+ KEY(6, 4, KEY_BACKSPACE),
+ KEY(6, 5, KEY_UNKNOWN),
+ KEY(6, 6, KEY_P),
+ KEY(6, 7, KEY_UP),
+
+ KEY(7, 0, KEY_PROG1),
+ KEY(7, 1, KEY_PROG2),
+ KEY(7, 2, KEY_PROG3),
+ KEY(7, 3, KEY_PROG4),
+ KEY(7, 4, KEY_F4),
+ KEY(7, 5, KEY_UNKNOWN),
+ KEY(7, 6, KEY_OK),
+ KEY(7, 7, KEY_DOWN),
+};
+
+static struct matrix_keymap_data sdp4430_keymap_data = {
+ .keymap = sdp4430_keymap,
+ .keymap_size = ARRAY_SIZE(sdp4430_keymap),
+};
+
+static struct omap4_keypad_platform_data sdp4430_keypad_data = {
+ .keymap_data = &sdp4430_keymap_data,
+ .rows = 8,
+ .cols = 8,
+};
+static struct gpio_led sdp4430_gpio_leds[] = {
+ {
+ .name = "omap4:green:debug0",
+ .gpio = 61,
+ },
+ {
+ .name = "omap4:green:debug1",
+ .gpio = 30,
+ },
+ {
+ .name = "omap4:green:debug2",
+ .gpio = 7,
+ },
+ {
+ .name = "omap4:green:debug3",
+ .gpio = 8,
+ },
+ {
+ .name = "omap4:green:debug4",
+ .gpio = 50,
+ },
+ {
+ .name = "omap4:blue:user",
+ .gpio = 169,
+ },
+ {
+ .name = "omap4:red:user",
+ .gpio = 170,
+ },
+ {
+ .name = "omap4:green:user",
+ .gpio = 139,
+ },
+
+};
+
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+ {
+ .desc = "Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+ .active_low = 0,
+ }
+};
+
+static struct gpio_led_platform_data sdp4430_led_data = {
+ .leds = sdp4430_gpio_leds,
+ .num_leds = ARRAY_SIZE(sdp4430_gpio_leds),
+};
+
+static struct led_pwm sdp4430_pwm_leds[] = {
+ {
+ .name = "omap4:green:chrg",
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .pwm_period_ns = 7812500,
+ },
+};
+
+static struct led_pwm_platform_data sdp4430_pwm_data = {
+ .num_leds = ARRAY_SIZE(sdp4430_pwm_leds),
+ .leds = sdp4430_pwm_leds,
+};
+
+static struct platform_device sdp4430_leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_pwm_data,
+ },
+};
+
+static int omap_prox_activate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+ return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+ gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+ .buttons = sdp4430_gpio_keys,
+ .nbuttons = ARRAY_SIZE(sdp4430_gpio_keys),
+ .enable = omap_prox_activate,
+ .disable = omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_gpio_keys_data,
+ },
+};
+
+static struct platform_device sdp4430_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_led_data,
+ },
+};
+static struct spi_board_info sdp4430_spi_board_info[] __initdata = {
+ {
+ .modalias = "ks8851",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 24000000,
+ .irq = ETH_KS8851_IRQ,
+ },
+};
+
+static struct gpio sdp4430_eth_gpios[] __initdata = {
+ { ETH_KS8851_POWER_ON, GPIOF_OUT_INIT_HIGH, "eth_power" },
+ { ETH_KS8851_QUART, GPIOF_OUT_INIT_HIGH, "quart" },
+ { ETH_KS8851_IRQ, GPIOF_IN, "eth_irq" },
+};
+
+static int __init omap_ethernet_init(void)
+{
+ int status;
+
+ /* Request of GPIO lines */
+ status = gpio_request_array(sdp4430_eth_gpios,
+ ARRAY_SIZE(sdp4430_eth_gpios));
+ if (status)
+ pr_err("Cannot request ETH GPIOs\n");
+
+ return status;
+}
+
+static struct platform_device sdp4430_lcd_device = {
+ .name = "sdp4430_lcd",
+ .id = -1,
+};
+
+static struct platform_device *sdp4430_devices[] __initdata = {
+ &sdp4430_lcd_device,
+ &sdp4430_gpio_keys_device,
+ &sdp4430_leds_gpio,
+ &sdp4430_leds_pwm,
+};
+
+static struct omap_lcd_config sdp4430_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel sdp4430_config[] __initdata = {
+ { OMAP_TAG_LCD, &sdp4430_lcd_config },
+};
+
+static void __init omap_4430sdp_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+#ifdef CONFIG_OMAP_32K_TIMER
+ omap2_gp_clockevent_set_gptimer(1);
+#endif
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_UTMI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct twl4030_usb_data omap4_usbphy_data = {
+ .phy_init = omap4430_phy_init,
+ .phy_exit = omap4430_phy_exit,
+ .phy_power = omap4430_phy_power,
+ .phy_set_clock = omap4430_phy_set_clk,
+ .phy_suspend = omap4430_phy_suspend,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .ocr_mask = MMC_VDD_29_30,
+ .no_off_init = true,
+ },
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply sdp4430_vaux_supply[] = {
+ {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.1",
+ },
+};
+static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
+ {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.0",
+ },
+};
+
+static int omap4_twl6030_hsmmc_late_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ /* Setting MMC1 Card detect Irq */
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ pr_err("Failed configuring MMC1 card detect\n");
+ pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
+ MMCDETECT_INTR_OFFSET;
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
+ return ret;
+}
+
+static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
+{
+ struct omap_mmc_platform_data *pdata;
+
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed %s\n", __func__);
+ return;
+ }
+ pdata = dev->platform_data;
+ pdata->init = omap4_twl6030_hsmmc_late_init;
+}
+
+static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ struct omap2_hsmmc_info *c;
+
+ omap2_hsmmc_init(controllers);
+ for (c = controllers; c->mmc; c++)
+ omap4_twl6030_hsmmc_set_late_init(c->dev);
+
+ return 0;
+}
+
+static struct regulator_init_data sdp4430_vaux1 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = sdp4430_vaux_supply,
+};
+
+static struct regulator_init_data sdp4430_vaux2 = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vaux3 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for MMC1 card */
+static struct regulator_init_data sdp4430_vmmc = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = sdp4430_vmmc_supply,
+};
+
+static struct regulator_init_data sdp4430_vpp = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 2500000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vusim = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2900000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vana = {
+ .constraints = {
+ .min_uV = 2100000,
+ .max_uV = 2100000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vcxio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_vusb = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data sdp4430_clk32kg = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct twl4030_platform_data sdp4430_twldata = {
+ .irq_base = TWL6030_IRQ_BASE,
+ .irq_end = TWL6030_IRQ_END,
+
+ /* Regulators */
+ .vmmc = &sdp4430_vmmc,
+ .vpp = &sdp4430_vpp,
+ .vusim = &sdp4430_vusim,
+ .vana = &sdp4430_vana,
+ .vcxio = &sdp4430_vcxio,
+ .vdac = &sdp4430_vdac,
+ .vusb = &sdp4430_vusb,
+ .vaux1 = &sdp4430_vaux1,
+ .vaux2 = &sdp4430_vaux2,
+ .vaux3 = &sdp4430_vaux3,
+ .clk32kg = &sdp4430_clk32kg,
+ .usb = &omap4_usbphy_data
+};
+
+static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tmp105", 0x48),
+ },
+ {
+ I2C_BOARD_INFO("bh1780", 0x29),
+ },
+};
+static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("hmc5843", 0x1e),
+ },
+};
+static int __init omap4_i2c_init(void)
+{
+ omap4_pmic_init("twl6030", &sdp4430_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
+ omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_4_boardinfo));
+ return 0;
+}
+
+static void __init omap_sfh7741prox_init(void)
+{
+ int error;
+
+ error = gpio_request_one(OMAP4_SFH7741_ENABLE_GPIO,
+ GPIOF_OUT_INIT_LOW, "sfh7741");
+ if (error < 0)
+ pr_err("%s:failed to request GPIO %d, error %d\n",
+ __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+}
+
+static void sdp4430_hdmi_mux_init(void)
+{
+ omap_mux_init_signal("hdmi_cec",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_ddc_scl",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_ddc_sda",
+ OMAP_PIN_INPUT_PULLUP);
+}
+
+static struct gpio sdp4430_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+};
+
+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+ int status;
+
+ status = gpio_request_array(sdp4430_hdmi_gpios,
+ ARRAY_SIZE(sdp4430_hdmi_gpios));
+ if (status)
+ pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
+
+ return status;
+}
+
+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+ gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
+}
+
+static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
+static struct omap_dss_device sdp4430_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+ .type = OMAP_DISPLAY_TYPE_HDMI,
+ .platform_enable = sdp4430_panel_enable_hdmi,
+ .platform_disable = sdp4430_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &sdp4430_hdmi_data,
+};
+
+static struct omap_dss_device *sdp4430_dss_devices[] = {
+ &sdp4430_hdmi_device,
+};
+
+static struct omap_dss_board_info sdp4430_dss_data = {
+ .num_devices = ARRAY_SIZE(sdp4430_dss_devices),
+ .devices = sdp4430_dss_devices,
+ .default_device = &sdp4430_hdmi_device,
+};
+
+void omap_4430sdp_display_init(void)
+{
+ sdp4430_hdmi_mux_init();
+ omap_display_init(&sdp4430_dss_data);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart2_cts.uart2_cts",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rts.uart2_rts",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rx.uart2_rx",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_tx.uart2_tx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial3_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
+ OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial4_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart4_rx.uart4_rx",
+ OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart4_tx.uart4_tx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_board_data serial2_data __initdata = {
+ .id = 1,
+ .pads = serial2_pads,
+ .pads_cnt = ARRAY_SIZE(serial2_pads),
+};
+
+static struct omap_board_data serial3_data __initdata = {
+ .id = 2,
+ .pads = serial3_pads,
+ .pads_cnt = ARRAY_SIZE(serial3_pads),
+};
+
+static struct omap_board_data serial4_data __initdata = {
+ .id = 3,
+ .pads = serial4_pads,
+ .pads_cnt = ARRAY_SIZE(serial4_pads),
+};
+
+static inline void board_serial_init(void)
+{
+ struct omap_board_data bdata;
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+ bdata.id = 0;
+ /* pass dummy data for UART1 */
+ omap_serial_init_port(&bdata);
+
+ omap_serial_init_port(&serial2_data);
+ omap_serial_init_port(&serial3_data);
+ omap_serial_init_port(&serial4_data);
+}
+#else
+#define board_mux NULL
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+ #endif
+
+static void __init omap_4430sdp_init(void)
+{
+ int status;
+ int package = OMAP_PACKAGE_CBS;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, NULL, package);
+
+ omap_board_config = sdp4430_config;
+ omap_board_config_size = ARRAY_SIZE(sdp4430_config);
+
+ omap4_i2c_init();
+ omap_sfh7741prox_init();
+ platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
+ board_serial_init();
+ omap4_twl6030_hsmmc_init(mmc);
+
+ usb_musb_init(&musb_board_data);
+
+ status = omap_ethernet_init();
+ if (status) {
+ pr_err("Ethernet initialization failed: %d\n", status);
+ } else {
+ sdp4430_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ);
+ spi_register_board_info(sdp4430_spi_board_info,
+ ARRAY_SIZE(sdp4430_spi_board_info));
+ }
+
+ status = omap4_keyboard_init(&sdp4430_keypad_data);
+ if (status)
+ pr_err("Keypad initialization failed: %d\n", status);
+
+ omap_4430sdp_display_init();
+}
+
+static void __init omap_4430sdp_map_io(void)
+{
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+}
+
+MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
+ /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap_4430sdp_map_io,
+ .init_early = omap_4430sdp_init_early,
+ .init_irq = gic_init_irq,
+ .init_machine = omap_4430sdp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
new file mode 100644
index 00000000..5e438a77
--- /dev/null
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -0,0 +1,110 @@
+/*
+ * Support for AM3517/05 Craneboard
+ * http://www.mistralsolutions.com/products/craneboard.php
+ *
+ * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com>
+ * Author: R.Srinath <srinath@mistralsolutions.com>
+ *
+ * Based on mach-omap2/board-am3517evm.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define GPIO_USB_POWER 35
+#define GPIO_USB_NRESET 38
+
+
+/* Board initialization */
+static struct omap_board_config_kernel am3517_crane_config[] __initdata = {
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
+static void __init am3517_crane_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = GPIO_USB_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void __init am3517_crane_init(void)
+{
+ int ret;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+
+ omap_board_config = am3517_crane_config;
+ omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
+
+ /* Configure GPIO for EHCI port */
+ if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
+ GPIO_USB_NRESET);
+ return;
+ }
+
+ if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) {
+ pr_err("Can not configure mux for GPIO_USB_POWER %d\n",
+ GPIO_USB_POWER);
+ return;
+ }
+
+ ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
+ "usb_ehci_enable");
+ if (ret < 0) {
+ pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
+ return;
+ }
+
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am3517_crane_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = am3517_crane_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
new file mode 100644
index 00000000..63af4171
--- /dev/null
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -0,0 +1,500 @@
+/*
+ * linux/arch/arm/mach-omap2/board-am3517evm.c
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated
+ * Author: Ranjith Lohithakshan <ranjithl@ti.com>
+ *
+ * Based on mach-omap2/board-omap3evm.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/can/platform/ti_hecc.h>
+#include <linux/davinci_emac.h>
+
+#include <mach/hardware.h>
+#include <mach/am35xx.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define AM35XX_EVM_MDIO_FREQUENCY (1000000)
+
+static struct mdio_platform_data am3517_evm_mdio_pdata = {
+ .bus_freq = AM35XX_EVM_MDIO_FREQUENCY,
+};
+
+static struct resource am3517_mdio_resources[] = {
+ {
+ .start = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET,
+ .end = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET +
+ SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device am3517_mdio_device = {
+ .name = "davinci_mdio",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(am3517_mdio_resources),
+ .resource = am3517_mdio_resources,
+ .dev.platform_data = &am3517_evm_mdio_pdata,
+};
+
+static struct emac_platform_data am3517_evm_emac_pdata = {
+ .rmii_en = 1,
+};
+
+static struct resource am3517_emac_resources[] = {
+ {
+ .start = AM35XX_IPSS_EMAC_BASE,
+ .end = AM35XX_IPSS_EMAC_BASE + 0x2FFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
+ .end = INT_35XX_EMAC_C0_RXTHRESH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_RX_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_TX_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
+ .end = INT_35XX_EMAC_C0_MISC_PULSE_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am3517_emac_device = {
+ .name = "davinci_emac",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am3517_emac_resources),
+ .resource = am3517_emac_resources,
+};
+
+static void am3517_enable_ethernet_int(void)
+{
+ u32 regval;
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_TX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_MISC_PULSE_CLR |
+ AM35XX_CPGMAC_C0_RX_THRESH_CLR);
+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am3517_disable_ethernet_int(void)
+{
+ u32 regval;
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = (regval | AM35XX_CPGMAC_C0_RX_PULSE_CLR |
+ AM35XX_CPGMAC_C0_TX_PULSE_CLR);
+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am3517_evm_ethernet_init(struct emac_platform_data *pdata)
+{
+ unsigned int regval;
+
+ pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET;
+ pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET;
+ pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET;
+ pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE;
+ pdata->version = EMAC_VERSION_2;
+ pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR;
+ pdata->interrupt_enable = am3517_enable_ethernet_int;
+ pdata->interrupt_disable = am3517_disable_ethernet_int;
+ am3517_emac_device.dev.platform_data = pdata;
+ platform_device_register(&am3517_emac_device);
+ platform_device_register(&am3517_mdio_device);
+ clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev),
+ NULL, &am3517_emac_device.dev);
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+ regval = regval & (~(AM35XX_CPGMACSS_SW_RST));
+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+
+ return ;
+}
+
+
+
+#define LCD_PANEL_PWR 176
+#define LCD_PANEL_BKLIGHT_PWR 182
+#define LCD_PANEL_PWM 181
+
+static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("s35390a", 0x30),
+ },
+};
+
+/*
+ * RTC - S35390A
+ */
+#define GPIO_RTCS35390A_IRQ 55
+
+static void __init am3517_evm_rtc_init(void)
+{
+ int r;
+
+ omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
+
+ r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq");
+ if (r < 0) {
+ printk(KERN_WARNING "failed to request GPIO#%d\n",
+ GPIO_RTCS35390A_IRQ);
+ return;
+ }
+
+ am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
+}
+
+/*
+ * I2C GPIO Expander - TCA6416
+ */
+
+/* Mounted on Base-Board */
+static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+};
+static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1A),
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &am3517evm_gpio_expander_info_0,
+ },
+};
+
+/* Mounted on UI Card */
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + 16,
+};
+static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + 32,
+};
+static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tca6416", 0x20),
+ .platform_data = &am3517evm_ui_gpio_expander_info_1,
+ },
+ {
+ I2C_BOARD_INFO("tca6416", 0x21),
+ .platform_data = &am3517evm_ui_gpio_expander_info_2,
+ },
+};
+
+static int __init am3517_evm_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 400, NULL, 0);
+ omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c2_boardinfo));
+ omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c3_boardinfo));
+
+ return 0;
+}
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
+ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
+static struct gpio am3517_evm_dss_gpios[] __initdata = {
+ /* GPIO 182 = LCD Backlight Power */
+ { LCD_PANEL_BKLIGHT_PWR, GPIOF_OUT_INIT_HIGH, "lcd_backlight_pwr" },
+ /* GPIO 181 = LCD Panel PWM */
+ { LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
+ /* GPIO 176 = LCD Panel Power enable pin */
+ { LCD_PANEL_PWR, GPIOF_OUT_INIT_HIGH, "dvi enable" },
+};
+
+static void __init am3517_evm_display_init(void)
+{
+ int r;
+
+ omap_mux_init_gpio(LCD_PANEL_PWR, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(LCD_PANEL_BKLIGHT_PWR, OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_gpio(LCD_PANEL_PWM, OMAP_PIN_INPUT_PULLDOWN);
+
+ r = gpio_request_array(am3517_evm_dss_gpios,
+ ARRAY_SIZE(am3517_evm_dss_gpios));
+ if (r) {
+ printk(KERN_ERR "failed to get DSS panel control GPIOs\n");
+ return;
+ }
+
+ printk(KERN_INFO "Display initialized successfully\n");
+}
+#else
+static void __init am3517_evm_display_init(void) {}
+#endif
+
+static int am3517_evm_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(LCD_PANEL_PWR, 1);
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void am3517_evm_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(LCD_PANEL_PWR, 0);
+ lcd_enabled = 0;
+}
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "sharp_lq",
+ .platform_enable = am3517_evm_panel_enable_lcd,
+ .platform_disable = am3517_evm_panel_disable_lcd,
+};
+
+static struct omap_dss_device am3517_evm_lcd_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 16,
+};
+
+static int am3517_evm_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void am3517_evm_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device am3517_evm_tv_device = {
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .name = "tv",
+ .driver_name = "venc",
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = am3517_evm_panel_enable_tv,
+ .platform_disable = am3517_evm_panel_disable_tv,
+};
+
+static int am3517_evm_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void am3517_evm_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = am3517_evm_panel_enable_dvi,
+ .platform_disable = am3517_evm_panel_disable_dvi,
+};
+
+static struct omap_dss_device am3517_evm_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *am3517_evm_dss_devices[] = {
+ &am3517_evm_lcd_device,
+ &am3517_evm_tv_device,
+ &am3517_evm_dvi_device,
+};
+
+static struct omap_dss_board_info am3517_evm_dss_data = {
+ .num_devices = ARRAY_SIZE(am3517_evm_dss_devices),
+ .devices = am3517_evm_dss_devices,
+ .default_device = &am3517_evm_lcd_device,
+};
+
+/*
+ * Board initialization
+ */
+static void __init am3517_evm_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 500,
+ .set_phy_power = am35x_musb_phy_power,
+ .clear_irq = am35x_musb_clear_irq,
+ .set_mode = am35x_set_mode,
+ .reset = am35x_musb_reset,
+};
+
+static __init void am3517_evm_musb_init(void)
+{
+ u32 devconf2;
+
+ /*
+ * Set up USB clock/mode in the DEVCONF2 register.
+ */
+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ /* USB2.0 PHY reference clock is 13 MHz */
+ devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
+ devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
+ | CONF2_DATPOL;
+
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+ usb_musb_init(&musb_board_data);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+#if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
+ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+#else
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+#endif
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 57,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* USB OTG DRVVBUS offset = 0x212 */
+ OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+
+static struct resource am3517_hecc_resources[] = {
+ {
+ .start = AM35XX_IPSS_HECC_BASE,
+ .end = AM35XX_IPSS_HECC_BASE + 0x3FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_HECC0_IRQ,
+ .end = INT_35XX_HECC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device am3517_hecc_device = {
+ .name = "ti_hecc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(am3517_hecc_resources),
+ .resource = am3517_hecc_resources,
+};
+
+static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
+ .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
+ .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
+ .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
+ .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
+ .int_line = AM35XX_HECC_INT_LINE,
+ .version = AM35XX_HECC_VERSION,
+};
+
+static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
+{
+ am3517_hecc_device.dev.platform_data = pdata;
+ platform_device_register(&am3517_hecc_device);
+}
+
+static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
+};
+
+static void __init am3517_evm_init(void)
+{
+ omap_board_config = am3517_evm_config;
+ omap_board_config_size = ARRAY_SIZE(am3517_evm_config);
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ am3517_evm_i2c_init();
+ omap_display_init(&am3517_evm_dss_data);
+ omap_serial_init();
+
+ /* Configure GPIO for EHCI port */
+ omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
+ usbhs_init(&usbhs_bdata);
+ am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
+ /* DSS */
+ am3517_evm_display_init();
+
+ /* RTC - S35390A */
+ am3517_evm_rtc_init();
+
+ i2c_register_board_info(1, am3517evm_i2c1_boardinfo,
+ ARRAY_SIZE(am3517evm_i2c1_boardinfo));
+ /*Ethernet*/
+ am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
+
+ /* MUSB */
+ am3517_evm_musb_init();
+}
+
+MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = am3517_evm_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = am3517_evm_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
new file mode 100644
index 00000000..b124bdfb
--- /dev/null
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -0,0 +1,360 @@
+/*
+ * linux/arch/arm/mach-omap2/board-apollon.c
+ *
+ * Copyright (C) 2005,2006 Samsung Electronics
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Modified from mach-omap/omap2/board-h4.c
+ *
+ * Code for apollon OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/smc91x.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <plat/led.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+
+#include "mux.h"
+#include "control.h"
+
+/* LED & Switch macros */
+#define LED0_GPIO13 13
+#define LED1_GPIO14 14
+#define LED2_GPIO15 15
+#define SW_ENTER_GPIO16 16
+#define SW_UP_GPIO17 17
+#define SW_DOWN_GPIO58 58
+
+#define APOLLON_FLASH_CS 0
+#define APOLLON_ETH_CS 1
+#define APOLLON_ETHR_GPIO_IRQ 74
+
+static struct mtd_partition apollon_partitions[] = {
+ {
+ .name = "X-Loader + U-Boot",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_16M,
+ },
+ {
+ .name = "filesystem00",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_32M,
+ },
+ {
+ .name = "filesystem01",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct onenand_platform_data apollon_flash_data = {
+ .parts = apollon_partitions,
+ .nr_parts = ARRAY_SIZE(apollon_partitions),
+};
+
+static struct resource apollon_flash_resource[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device apollon_onenand_device = {
+ .name = "onenand-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &apollon_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(apollon_flash_resource),
+ .resource = apollon_flash_resource,
+};
+
+static void __init apollon_flash_init(void)
+{
+ unsigned long base;
+
+ if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
+ printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
+ return;
+ }
+ apollon_flash_resource[0].start = base;
+ apollon_flash_resource[0].end = base + SZ_128K - 1;
+}
+
+static struct smc91x_platdata appolon_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource apollon_smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+ .end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct platform_device apollon_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .platform_data = &appolon_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(apollon_smc91x_resources),
+ .resource = apollon_smc91x_resources,
+};
+
+static struct platform_device apollon_lcd_device = {
+ .name = "apollon_lcd",
+ .id = -1,
+};
+
+static struct omap_led_config apollon_led_config[] = {
+ {
+ .cdev = {
+ .name = "apollon:led0",
+ },
+ .gpio = LED0_GPIO13,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led1",
+ },
+ .gpio = LED1_GPIO14,
+ },
+ {
+ .cdev = {
+ .name = "apollon:led2",
+ },
+ .gpio = LED2_GPIO15,
+ },
+};
+
+static struct omap_led_platform_data apollon_led_data = {
+ .nr_leds = ARRAY_SIZE(apollon_led_config),
+ .leds = apollon_led_config,
+};
+
+static struct platform_device apollon_led_device = {
+ .name = "omap-led",
+ .id = -1,
+ .dev = {
+ .platform_data = &apollon_led_data,
+ },
+};
+
+static struct platform_device *apollon_devices[] __initdata = {
+ &apollon_onenand_device,
+ &apollon_smc91x_device,
+ &apollon_lcd_device,
+ &apollon_led_device,
+};
+
+static inline void __init apollon_init_smc91x(void)
+{
+ unsigned long base;
+
+ unsigned int rate;
+ struct clk *gpmc_fck;
+ int eth_cs;
+ int err;
+
+ gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
+ if (IS_ERR(gpmc_fck)) {
+ WARN_ON(1);
+ return;
+ }
+
+ clk_enable(gpmc_fck);
+ rate = clk_get_rate(gpmc_fck);
+
+ eth_cs = APOLLON_ETH_CS;
+
+ /* Make sure CS1 timings are correct */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
+
+ if (rate >= 160000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else if (rate >= 130000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else {/* rate = 100000000 */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
+ }
+
+ if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
+ goto out;
+ }
+ apollon_smc91x_resources[0].start = base + 0x300;
+ apollon_smc91x_resources[0].end = base + 0x30f;
+ udelay(100);
+
+ omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
+ err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
+ if (err) {
+ printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
+ APOLLON_ETHR_GPIO_IRQ);
+ gpmc_cs_free(APOLLON_ETH_CS);
+ }
+out:
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+}
+
+static struct omap_usb_config apollon_usb_config __initdata = {
+ .register_dev = 1,
+ .hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
+
+ .pins[0] = 6,
+};
+
+static struct omap_lcd_config apollon_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel apollon_config[] __initdata = {
+ { OMAP_TAG_LCD, &apollon_lcd_config },
+};
+
+static void __init omap_apollon_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static struct gpio apollon_gpio_leds[] __initdata = {
+ { LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
+ { LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */
+ { LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4 */
+};
+
+static void __init apollon_led_init(void)
+{
+ omap_mux_init_signal("vlynq_clk.gpio_13", 0);
+ omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+
+ gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
+}
+
+static void __init apollon_usb_init(void)
+{
+ /* USB device */
+ /* DEVICE_SUSPEND */
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+ gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
+ omap2_usbfs_init(&apollon_usb_config);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_apollon_init(void)
+{
+ u32 v;
+
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+ omap_board_config = apollon_config;
+ omap_board_config_size = ARRAY_SIZE(apollon_config);
+
+ apollon_init_smc91x();
+ apollon_led_init();
+ apollon_flash_init();
+ apollon_usb_init();
+
+ /* REVISIT: where's the correct place */
+ omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
+
+ /* LCD PWR_EN */
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
+
+ /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+ platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
+ omap_serial_init();
+}
+
+static void __init omap_apollon_map_io(void)
+{
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+}
+
+MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
+ /* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap_apollon_map_io,
+ .init_early = omap_apollon_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_apollon_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
new file mode 100644
index 00000000..77456dec
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -0,0 +1,652 @@
+/*
+ * board-cm-t35.c (CompuLab CM-T35 module)
+ *
+ * Copyright (C) 2009 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/at24.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <plat/mcspi.h>
+
+#include <mach/hardware.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define CM_T35_GPIO_PENDOWN 57
+
+#define CM_T35_SMSC911X_CS 5
+#define CM_T35_SMSC911X_GPIO 163
+#define SB_T35_SMSC911X_CS 4
+#define SB_T35_SMSC911X_GPIO 65
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = {
+ .id = 0,
+ .cs = CM_T35_SMSC911X_CS,
+ .gpio_irq = CM_T35_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = {
+ .id = 1,
+ .cs = SB_T35_SMSC911X_CS,
+ .gpio_irq = SB_T35_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static void __init cm_t35_init_ethernet(void)
+{
+ gpmc_smsc911x_init(&cm_t35_smsc911x_cfg);
+ gpmc_smsc911x_init(&sb_t35_smsc911x_cfg);
+}
+#else
+static inline void __init cm_t35_init_ethernet(void) { return; }
+#endif
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led cm_t35_leds[] = {
+ [0] = {
+ .gpio = 186,
+ .name = "cm-t35:green",
+ .default_trigger = "heartbeat",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data cm_t35_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_t35_leds),
+ .leds = cm_t35_leds,
+};
+
+static struct platform_device cm_t35_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t35_led_pdata,
+ },
+};
+
+static void __init cm_t35_init_led(void)
+{
+ platform_device_register(&cm_t35_led_device);
+}
+#else
+static inline void cm_t35_init_led(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+static struct mtd_partition cm_t35_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data cm_t35_nand_data = {
+ .parts = cm_t35_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t35_nand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .cs = 0,
+
+};
+
+static void __init cm_t35_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t35_nand_data) < 0)
+ pr_err("CM-T35: Unable to register NAND device\n");
+}
+#else
+static inline void cm_t35_init_nand(void) {}
+#endif
+
+#define CM_T35_LCD_EN_GPIO 157
+#define CM_T35_LCD_BL_GPIO 58
+#define CM_T35_DVI_EN_GPIO 54
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static int cm_t35_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
+ gpio_set_value(CM_T35_LCD_BL_GPIO, 1);
+
+ lcd_enabled = 1;
+
+ return 0;
+}
+
+static void cm_t35_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ lcd_enabled = 0;
+
+ gpio_set_value(CM_T35_LCD_BL_GPIO, 0);
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 0);
+}
+
+static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(CM_T35_DVI_EN_GPIO, 0);
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void cm_t35_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(CM_T35_DVI_EN_GPIO, 1);
+ dvi_enabled = 0;
+}
+
+static int cm_t35_panel_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void cm_t35_panel_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "toppoly_tdo35s",
+ .platform_enable = cm_t35_panel_enable_lcd,
+ .platform_disable = cm_t35_panel_disable_lcd,
+};
+
+static struct omap_dss_device cm_t35_lcd_device = {
+ .name = "lcd",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 18,
+};
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = cm_t35_panel_enable_dvi,
+ .platform_disable = cm_t35_panel_disable_dvi,
+};
+
+static struct omap_dss_device cm_t35_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device cm_t35_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = cm_t35_panel_enable_tv,
+ .platform_disable = cm_t35_panel_disable_tv,
+};
+
+static struct omap_dss_device *cm_t35_dss_devices[] = {
+ &cm_t35_lcd_device,
+ &cm_t35_dvi_device,
+ &cm_t35_tv_device,
+};
+
+static struct omap_dss_board_info cm_t35_dss_data = {
+ .num_devices = ARRAY_SIZE(cm_t35_dss_devices),
+ .devices = cm_t35_dss_devices,
+ .default_device = &cm_t35_dvi_device,
+};
+
+static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct tdo24m_platform_data tdo24m_config = {
+ .model = TDO35S,
+};
+
+static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 1000000,
+ .controller_data = &tdo24m_mcspi_config,
+ .platform_data = &tdo24m_config,
+ },
+};
+
+static struct gpio cm_t35_dss_gpios[] __initdata = {
+ { CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW, "lcd enable" },
+ { CM_T35_LCD_BL_GPIO, GPIOF_OUT_INIT_LOW, "lcd bl enable" },
+ { CM_T35_DVI_EN_GPIO, GPIOF_OUT_INIT_HIGH, "dvi enable" },
+};
+
+static void __init cm_t35_init_display(void)
+{
+ int err;
+
+ spi_register_board_info(cm_t35_lcd_spi_board_info,
+ ARRAY_SIZE(cm_t35_lcd_spi_board_info));
+
+ err = gpio_request_array(cm_t35_dss_gpios,
+ ARRAY_SIZE(cm_t35_dss_gpios));
+ if (err) {
+ pr_err("CM-T35: failed to request DSS control GPIOs\n");
+ return;
+ }
+
+ gpio_export(CM_T35_LCD_EN_GPIO, 0);
+ gpio_export(CM_T35_LCD_BL_GPIO, 0);
+ gpio_export(CM_T35_DVI_EN_GPIO, 0);
+
+ msleep(50);
+ gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
+
+ err = omap_display_init(&cm_t35_dss_data);
+ if (err) {
+ pr_err("CM-T35: failed to register DSS device\n");
+ gpio_free_array(cm_t35_dss_gpios, ARRAY_SIZE(cm_t35_dss_gpios));
+ }
+}
+
+static struct regulator_consumer_supply cm_t35_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply cm_t35_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct regulator_consumer_supply cm_t35_vdac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static struct regulator_consumer_supply cm_t35_vdvi_supply =
+ REGULATOR_SUPPLY("vdvi", "omapdss");
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data cm_t35_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cm_t35_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data cm_t35_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cm_t35_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data cm_t35_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cm_t35_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data cm_t35_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cm_t35_vdvi_supply,
+};
+
+static struct twl4030_usb_data cm_t35_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static uint32_t cm_t35_keymap[] = {
+ KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_LEFT),
+ KEY(1, 0, KEY_UP), KEY(1, 1, KEY_ENTER), KEY(1, 2, KEY_DOWN),
+ KEY(2, 0, KEY_RIGHT), KEY(2, 1, KEY_C), KEY(2, 2, KEY_D),
+};
+
+static struct matrix_keymap_data cm_t35_keymap_data = {
+ .keymap = cm_t35_keymap,
+ .keymap_size = ARRAY_SIZE(cm_t35_keymap),
+};
+
+static struct twl4030_keypad_data cm_t35_kp_data = {
+ .keymap_data = &cm_t35_keymap_data,
+ .rows = 3,
+ .cols = 3,
+ .rep = 1,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .transceiver = 1,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
+ {} /* Terminator */
+};
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = OMAP_MAX_GPIO_LINES + 6,
+ .reset_gpio_port[1] = OMAP_MAX_GPIO_LINES + 7,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio,
+ unsigned ngpio)
+{
+ int wlan_rst = gpio + 2;
+
+ if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) {
+ gpio_export(wlan_rst, 0);
+ udelay(10);
+ gpio_set_value(wlan_rst, 0);
+ udelay(10);
+ gpio_set_value(wlan_rst, 1);
+ } else {
+ pr_err("CM-T35: could not obtain gpio for WiFi reset\n");
+ }
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters */
+ cm_t35_vmmc1_supply.dev = mmc[0].dev;
+ cm_t35_vsim_supply.dev = mmc[0].dev;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data cm_t35_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = cm_t35_twl_gpio_setup,
+};
+
+static struct twl4030_platform_data cm_t35_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .keypad = &cm_t35_kp_data,
+ .usb = &cm_t35_usb_data,
+ .gpio = &cm_t35_gpio_data,
+ .vmmc1 = &cm_t35_vmmc1,
+ .vsim = &cm_t35_vsim,
+ .vdac = &cm_t35_vdac,
+ .vpll2 = &cm_t35_vpll2,
+};
+
+static void __init cm_t35_init_i2c(void)
+{
+ omap3_pmic_init("tps65930", &cm_t35_twldata);
+}
+
+static void __init cm_t35_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* nCS and IRQ for CM-T35 ethernet */
+ OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
+ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* nCS and IRQ for SB-T35 ethernet */
+ OMAP3_MUX(GPMC_NCS4, OMAP_MUX_MODE0),
+ OMAP3_MUX(GPMC_WAIT3, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* PENDOWN GPIO */
+ OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* mUSB */
+ OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* MMC 2 */
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+
+ /* McSPI 1 */
+ OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+
+ /* McSPI 4 */
+ OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
+
+ /* McBSP 2 */
+ OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* serial ports */
+ OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* DSS */
+ OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* display controls */
+ OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* TPS IRQ */
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
+ OMAP_PIN_INPUT_PULLUP),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct omap_board_config_kernel cm_t35_config[] __initdata = {
+};
+
+static void __init cm_t35_init(void)
+{
+ omap_board_config = cm_t35_config;
+ omap_board_config_size = ARRAY_SIZE(cm_t35_config);
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_serial_init();
+ cm_t35_init_i2c();
+ cm_t35_init_nand();
+ omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
+ cm_t35_init_ethernet();
+ cm_t35_init_led();
+ cm_t35_init_display();
+
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+}
+
+MACHINE_START(CM_T35, "Compulab CM-T35")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = cm_t35_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = cm_t35_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
new file mode 100644
index 00000000..c3a9fd35
--- /dev/null
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -0,0 +1,310 @@
+/*
+ * linux/arch/arm/mach-omap2/board-cm-t3517.c
+ *
+ * Support for the CompuLab CM-T3517 modules
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Author: Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/rtc-v3020.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/can/platform/ti_hecc.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+#include <plat/nand.h>
+#include <plat/gpmc.h>
+
+#include <mach/am35xx.h>
+
+#include "mux.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cm_t3517_leds[] = {
+ [0] = {
+ .gpio = 186,
+ .name = "cm-t3517:green",
+ .default_trigger = "heartbeat",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_led_platform_data cm_t3517_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_t3517_leds),
+ .leds = cm_t3517_leds,
+};
+
+static struct platform_device cm_t3517_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_led_pdata,
+ },
+};
+
+static void __init cm_t3517_init_leds(void)
+{
+ platform_device_register(&cm_t3517_led_device);
+}
+#else
+static inline void cm_t3517_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE)
+static struct resource cm_t3517_hecc_resources[] = {
+ {
+ .start = AM35XX_IPSS_HECC_BASE,
+ .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_35XX_HECC0_IRQ,
+ .end = INT_35XX_HECC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ti_hecc_platform_data cm_t3517_hecc_pdata = {
+ .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
+ .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
+ .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
+ .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
+ .int_line = AM35XX_HECC_INT_LINE,
+ .version = AM35XX_HECC_VERSION,
+};
+
+static struct platform_device cm_t3517_hecc_device = {
+ .name = "ti_hecc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources),
+ .resource = cm_t3517_hecc_resources,
+ .dev = {
+ .platform_data = &cm_t3517_hecc_pdata,
+ },
+};
+
+static void cm_t3517_init_hecc(void)
+{
+ platform_device_register(&cm_t3517_hecc_device);
+}
+#else
+static inline void cm_t3517_init_hecc(void) {}
+#endif
+
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+#define RTC_IO_GPIO (153)
+#define RTC_WR_GPIO (154)
+#define RTC_RD_GPIO (53)
+#define RTC_CS_GPIO (163)
+#define RTC_CS_EN_GPIO (160)
+
+struct v3020_platform_data cm_t3517_v3020_pdata = {
+ .use_gpio = 1,
+ .gpio_cs = RTC_CS_GPIO,
+ .gpio_wr = RTC_WR_GPIO,
+ .gpio_rd = RTC_RD_GPIO,
+ .gpio_io = RTC_IO_GPIO,
+};
+
+static struct platform_device cm_t3517_rtc_device = {
+ .name = "v3020",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_t3517_v3020_pdata,
+ }
+};
+
+static void __init cm_t3517_init_rtc(void)
+{
+ int err;
+
+ err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH,
+ "rtc cs en");
+ if (err) {
+ pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
+ return;
+ }
+
+ platform_device_register(&cm_t3517_rtc_device);
+}
+#else
+static inline void cm_t3517_init_rtc(void) {}
+#endif
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+#define HSUSB1_RESET_GPIO (146)
+#define HSUSB2_RESET_GPIO (147)
+#define USB_HUB_RESET_GPIO (152)
+
+static struct usbhs_omap_board_data cm_t3517_ehci_pdata __initdata = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = HSUSB1_RESET_GPIO,
+ .reset_gpio_port[1] = HSUSB2_RESET_GPIO,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static int __init cm_t3517_init_usbh(void)
+{
+ int err;
+
+ err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW,
+ "usb hub rst");
+ if (err) {
+ pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
+ } else {
+ udelay(10);
+ gpio_set_value(USB_HUB_RESET_GPIO, 1);
+ msleep(1);
+ }
+
+ usbhs_init(&cm_t3517_ehci_pdata);
+
+ return 0;
+}
+#else
+static inline int cm_t3517_init_usbh(void)
+{
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+static struct mtd_partition cm_t3517_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data cm_t3517_nand_data = {
+ .parts = cm_t3517_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .cs = 0,
+};
+
+static void __init cm_t3517_init_nand(void)
+{
+ if (gpmc_nand_init(&cm_t3517_nand_data) < 0)
+ pr_err("CM-T3517: NAND initialization failed\n");
+}
+#else
+static inline void cm_t3517_init_nand(void) {}
+#endif
+
+static struct omap_board_config_kernel cm_t3517_config[] __initdata = {
+};
+
+static void __init cm_t3517_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* GPIO186 - Green LED */
+ OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* RTC GPIOs: */
+ /* IO - GPIO153 */
+ OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* WR# - GPIO154 */
+ OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* RD# - GPIO53 */
+ OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* CS# - GPIO163 */
+ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* CS EN - GPIO160 */
+ OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* HSUSB1 RESET */
+ OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* HSUSB2 RESET */
+ OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* CM-T3517 USB HUB nRESET */
+ OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init cm_t3517_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ omap_board_config = cm_t3517_config;
+ omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
+ cm_t3517_init_leds();
+ cm_t3517_init_nand();
+ cm_t3517_init_rtc();
+ cm_t3517_init_usbh();
+ cm_t3517_init_hecc();
+}
+
+MACHINE_START(CM_T3517, "Compulab CM-T3517")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = cm_t3517_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = cm_t3517_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
new file mode 100644
index 00000000..34956ec8
--- /dev/null
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -0,0 +1,711 @@
+/*
+ * board-devkit8000.c - TimLL Devkit8000
+ *
+ * Copyright (C) 2009 Kim Botherway
+ * Copyright (C) 2010 Thomas Weber
+ *
+ * Modified from mach-omap2/board-omap3beagle.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <mach/id.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include <plat/mcspi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/dm9000.h>
+#include <linux/interrupt.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "common-board-devices.h"
+
+#define OMAP_DM9000_GPIO_IRQ 25
+#define OMAP3_DEVKIT_TS_GPIO 27
+
+static struct mtd_partition devkit8000_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {} /* Terminator */
+};
+
+static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
+}
+
+static int devkit8000_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void devkit8000_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value_cansleep(dssdev->reset_gpio, 0);
+}
+
+static struct regulator_consumer_supply devkit8000_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
+
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply devkit8000_vio_supply =
+ REGULATOR_SUPPLY("vcc", "spi2.0");
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "generic",
+ .platform_enable = devkit8000_panel_enable_lcd,
+ .platform_disable = devkit8000_panel_disable_lcd,
+};
+
+static struct omap_dss_device devkit8000_lcd_device = {
+ .name = "lcd",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = devkit8000_panel_enable_dvi,
+ .platform_disable = devkit8000_panel_disable_dvi,
+};
+
+static struct omap_dss_device devkit8000_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device devkit8000_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+
+static struct omap_dss_device *devkit8000_dss_devices[] = {
+ &devkit8000_lcd_device,
+ &devkit8000_dvi_device,
+ &devkit8000_tv_device,
+};
+
+static struct omap_dss_board_info devkit8000_dss_data = {
+ .num_devices = ARRAY_SIZE(devkit8000_dss_devices),
+ .devices = devkit8000_dss_devices,
+ .default_device = &devkit8000_lcd_device,
+};
+
+static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(1, 0, KEY_2),
+ KEY(2, 0, KEY_3),
+ KEY(0, 1, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(2, 1, KEY_6),
+ KEY(3, 1, KEY_F5),
+ KEY(0, 2, KEY_7),
+ KEY(1, 2, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(3, 2, KEY_F6),
+ KEY(0, 3, KEY_F7),
+ KEY(1, 3, KEY_0),
+ KEY(2, 3, KEY_F8),
+ PERSISTENT_KEY(4, 5),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data devkit8000_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 6,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct gpio_led gpio_leds[];
+
+static int devkit8000_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
+ devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
+ ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "LCD_PWREN");
+ if (ret < 0) {
+ devkit8000_lcd_device.reset_gpio = -EINVAL;
+ printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
+ }
+
+ /* gpio + 7 is "DVI_PD" (out, active low) */
+ devkit8000_dvi_device.reset_gpio = gpio + 7;
+ ret = gpio_request_one(devkit8000_dvi_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "DVI PowerDown");
+ if (ret < 0) {
+ devkit8000_dvi_device.reset_gpio = -EINVAL;
+ printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n");
+ }
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pulldowns = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = devkit8000_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data devkit8000_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &devkit8000_vmmc1_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data devkit8000_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &devkit8000_vdda_dac_supply,
+};
+
+/* VPLL1 for digital video outputs */
+static struct regulator_init_data devkit8000_vpll1 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
+ .consumer_supplies = devkit8000_vpll1_supplies,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data devkit8000_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &devkit8000_vio_supply,
+};
+
+static struct twl4030_usb_data devkit8000_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data devkit8000_audio_data;
+
+static struct twl4030_codec_data devkit8000_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &devkit8000_audio_data,
+};
+
+static struct twl4030_platform_data devkit8000_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .usb = &devkit8000_usb_data,
+ .gpio = &devkit8000_gpio_data,
+ .codec = &devkit8000_codec_data,
+ .vmmc1 = &devkit8000_vmmc1,
+ .vdac = &devkit8000_vdac,
+ .vpll1 = &devkit8000_vpll1,
+ .vio = &devkit8000_vio,
+ .keypad = &devkit8000_kp_data,
+};
+
+static int __init devkit8000_i2c_init(void)
+{
+ omap3_pmic_init("tps65930", &devkit8000_twldata);
+ /* Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .gpio = 186,
+ .active_low = true,
+ },
+ {
+ .name = "led2",
+ .default_trigger = "mmc0",
+ .gpio = 163,
+ .active_low = true,
+ },
+ {
+ .name = "ledB",
+ .default_trigger = "none",
+ .gpio = 153,
+ .active_low = true,
+ },
+ {
+ .name = "led3",
+ .default_trigger = "none",
+ .gpio = 164,
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 26,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+
+static void __init devkit8000_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+static void __init devkit8000_init_irq(void)
+{
+ omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+ omap2_gp_clockevent_set_gptimer(12);
+#endif
+}
+
+#define OMAP_DM9000_BASE 0x2c000000
+
+static struct resource omap_dm9000_resources[] = {
+ [0] = {
+ .start = OMAP_DM9000_BASE,
+ .end = (OMAP_DM9000_BASE + 0x4 - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (OMAP_DM9000_BASE + 0x400),
+ .end = (OMAP_DM9000_BASE + 0x400 + 0x4 - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = OMAP_GPIO_IRQ(OMAP_DM9000_GPIO_IRQ),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
+ },
+};
+
+static struct dm9000_plat_data omap_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device omap_dm9000_dev = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap_dm9000_resources),
+ .resource = omap_dm9000_resources,
+ .dev = {
+ .platform_data = &omap_dm9000_platdata,
+ },
+};
+
+static void __init omap_dm9000_init(void)
+{
+ unsigned char *eth_addr = omap_dm9000_platdata.dev_addr;
+ struct omap_die_id odi;
+ int ret;
+
+ ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq");
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
+ OMAP_DM9000_GPIO_IRQ);
+ return;
+ }
+
+ /* init the mac address using DIE id */
+ omap_get_die_id(&odi);
+
+ eth_addr[0] = 0x02; /* locally administered */
+ eth_addr[1] = odi.id_1 & 0xff;
+ eth_addr[2] = (odi.id_0 & 0xff000000) >> 24;
+ eth_addr[3] = (odi.id_0 & 0x00ff0000) >> 16;
+ eth_addr[4] = (odi.id_0 & 0x0000ff00) >> 8;
+ eth_addr[5] = (odi.id_0 & 0x000000ff);
+}
+
+static struct platform_device *devkit8000_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+ &omap_dm9000_dev,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* nCS and IRQ for Devkit8000 ethernet */
+ OMAP3_MUX(GPMC_NCS6, OMAP_MUX_MODE0),
+ OMAP3_MUX(ETK_D11, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+
+ /* McSPI 2*/
+ OMAP3_MUX(MCSPI2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI2_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCSPI2_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI2_CS0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCSPI2_CS1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* PENDOWN GPIO */
+ OMAP3_MUX(ETK_D13, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* mUSB */
+ OMAP3_MUX(HSUSB0_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_STP, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(HSUSB0_DIR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_NXT, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(HSUSB0_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* USB 1 */
+ OMAP3_MUX(ETK_CTL, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(ETK_D8, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D9, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D0, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D2, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ OMAP3_MUX(ETK_D7, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+
+ /* MMC 1 */
+ OMAP3_MUX(SDMMC1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT4, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT5, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT6, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(SDMMC1_DAT7, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* McBSP 2 */
+ OMAP3_MUX(MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* I2C 1 */
+ OMAP3_MUX(I2C1_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C1_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 2 */
+ OMAP3_MUX(I2C2_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 3 */
+ OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* I2C 4 */
+ OMAP3_MUX(I2C4_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C4_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* serial ports */
+ OMAP3_MUX(MCBSP3_CLKX, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(UART1_TX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(UART1_RX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* DSS */
+ OMAP3_MUX(DSS_PCLK, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_HSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_VSYNC, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_ACBIAS, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA0, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA2, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA3, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA4, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA5, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA6, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA7, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA8, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA9, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA10, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA11, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA12, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA13, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA14, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA15, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA16, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA17, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA20, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+
+ /* expansion port */
+ /* McSPI 1 */
+ OMAP3_MUX(MCSPI1_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SIMO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_SOMI, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCSPI1_CS0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+ OMAP3_MUX(MCSPI1_CS3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+
+ /* HDQ */
+ OMAP3_MUX(HDQ_SIO, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ /* McSPI4 */
+ OMAP3_MUX(MCBSP1_CLKR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_DR, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP3_MUX(MCBSP1_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP),
+
+ /* MMC 2 */
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+
+ /* I2C3 */
+ OMAP3_MUX(I2C3_SCL, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+ OMAP3_MUX(I2C3_SDA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(MCBSP1_FSR, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ OMAP3_MUX(GPMC_NCS7, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ OMAP3_MUX(GPMC_NCS3, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* TPS IRQ */
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_WAKEUP_EN | \
+ OMAP_PIN_INPUT_PULLUP),
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init devkit8000_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_serial_init();
+
+ omap_dm9000_init();
+
+ devkit8000_i2c_init();
+ platform_add_devices(devkit8000_devices,
+ ARRAY_SIZE(devkit8000_devices));
+
+ omap_display_init(&devkit8000_dss_data);
+
+ omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL);
+
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
+ ARRAY_SIZE(devkit8000_nand_partitions));
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = devkit8000_init_early,
+ .init_irq = devkit8000_init_irq,
+ .init_machine = devkit8000_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
new file mode 100644
index 00000000..729892fd
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -0,0 +1,256 @@
+/*
+ * board-flash.c
+ * Modified from mach-omap2/board-3430sdp-flash.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Vimal Singh <vimalsingh@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+#include <plat/irqs.h>
+
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/onenand.h>
+#include <plat/tc.h>
+
+#include "board-flash.h"
+
+#define REG_FPGA_REV 0x10
+#define REG_FPGA_DIP_SWITCH_INPUT2 0x60
+#define MAX_SUPPORTED_GPMC_CONFIG 3
+
+#define DEBUG_BASE 0x08000000 /* debug board */
+
+/* various memory sizes */
+#define FLASH_SIZE_SDPV1 SZ_64M /* NOR flash (64 Meg aligned) */
+#define FLASH_SIZE_SDPV2 SZ_128M /* NOR flash (256 Meg aligned) */
+
+static struct physmap_flash_data board_nor_data = {
+ .width = 2,
+};
+
+static struct resource board_nor_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device board_nor_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &board_nor_data,
+ },
+ .num_resources = 1,
+ .resource = &board_nor_resource,
+};
+
+static void
+__init board_nor_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+{
+ int err;
+
+ board_nor_data.parts = nor_parts;
+ board_nor_data.nr_parts = nr_parts;
+
+ /* Configure start address and size of NOR device */
+ if (omap_rev() >= OMAP3430_REV_ES1_0) {
+ err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
+ (unsigned long *)&board_nor_resource.start);
+ board_nor_resource.end = board_nor_resource.start
+ + FLASH_SIZE_SDPV2 - 1;
+ } else {
+ err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
+ (unsigned long *)&board_nor_resource.start);
+ board_nor_resource.end = board_nor_resource.start
+ + FLASH_SIZE_SDPV1 - 1;
+ }
+ if (err < 0) {
+ pr_err("NOR: Can't request GPMC CS\n");
+ return;
+ }
+ if (platform_device_register(&board_nor_device) < 0)
+ pr_err("Unable to register NOR device\n");
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data = {
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static void
+__init board_onenand_init(struct mtd_partition *onenand_parts,
+ u8 nr_parts, u8 cs)
+{
+ board_onenand_data.cs = cs;
+ board_onenand_data.parts = onenand_parts;
+ board_onenand_data.nr_parts = nr_parts;
+
+ gpmc_onenand_init(&board_onenand_data);
+}
+#else
+static void
+__init board_onenand_init(struct mtd_partition *nor_parts, u8 nr_parts, u8 cs)
+{
+}
+#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+
+/* Note that all values in this struct are in nanoseconds */
+static struct gpmc_timings nand_timings = {
+
+ .sync_clk = 0,
+
+ .cs_on = 0,
+ .cs_rd_off = 36,
+ .cs_wr_off = 36,
+
+ .adv_on = 6,
+ .adv_rd_off = 24,
+ .adv_wr_off = 36,
+
+ .we_off = 30,
+ .oe_off = 48,
+
+ .access = 54,
+ .rd_cycle = 72,
+ .wr_cycle = 72,
+
+ .wr_access = 30,
+ .wr_data_mux_bus = 0,
+};
+
+static struct omap_nand_platform_data board_nand_data = {
+ .nand_setup = NULL,
+ .gpmc_t = &nand_timings,
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .dev_ready = NULL,
+ .devsize = 0, /* '0' for 8-bit, '1' for 16-bit device */
+};
+
+void
+__init board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type)
+{
+ board_nand_data.cs = cs;
+ board_nand_data.parts = nand_parts;
+ board_nand_data.nr_parts = nr_parts;
+ board_nand_data.devsize = nand_type;
+
+ board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+ board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
+ gpmc_nand_init(&board_nand_data);
+}
+#else
+void
+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, int nand_type)
+{
+}
+#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
+
+/**
+ * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get
+ * the various cs values.
+ */
+static u8 get_gpmc0_type(void)
+{
+ u8 cs = 0;
+ void __iomem *fpga_map_addr;
+
+ fpga_map_addr = ioremap(DEBUG_BASE, 4096);
+ if (!fpga_map_addr)
+ return -ENOMEM;
+
+ if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV)))
+ /* we dont have an DEBUG FPGA??? */
+ /* Depend on #defines!! default to strata boot return param */
+ goto unmap;
+
+ /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */
+ cs = __raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf;
+
+ /* ES2.0 SDP's onwards 4 dip switches are provided for CS */
+ if (omap_rev() >= OMAP3430_REV_ES1_0)
+ /* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */
+ cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) |
+ ((cs & 2) << 1) | ((cs & 1) << 3);
+ else
+ /* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */
+ cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2);
+unmap:
+ iounmap(fpga_map_addr);
+ return cs;
+}
+
+/**
+ * board_flash_init - Identify devices connected to GPMC and register.
+ *
+ * @return - void.
+ */
+void board_flash_init(struct flash_partitions partition_info[],
+ char chip_sel_board[][GPMC_CS_NUM], int nand_type)
+{
+ u8 cs = 0;
+ u8 norcs = GPMC_CS_NUM + 1;
+ u8 nandcs = GPMC_CS_NUM + 1;
+ u8 onenandcs = GPMC_CS_NUM + 1;
+ u8 idx;
+ unsigned char *config_sel = NULL;
+
+ /* REVISIT: Is this return correct idx for 2430 SDP?
+ * for which cs configuration matches for 2430 SDP?
+ */
+ idx = get_gpmc0_type();
+ if (idx >= MAX_SUPPORTED_GPMC_CONFIG) {
+ pr_err("%s: Invalid chip select: %d\n", __func__, cs);
+ return;
+ }
+ config_sel = (unsigned char *)(chip_sel_board[idx]);
+
+ while (cs < GPMC_CS_NUM) {
+ switch (config_sel[cs]) {
+ case PDC_NOR:
+ if (norcs > GPMC_CS_NUM)
+ norcs = cs;
+ break;
+ case PDC_NAND:
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ break;
+ case PDC_ONENAND:
+ if (onenandcs > GPMC_CS_NUM)
+ onenandcs = cs;
+ break;
+ };
+ cs++;
+ }
+
+ if (norcs > GPMC_CS_NUM)
+ pr_err("NOR: Unable to find configuration in GPMC\n");
+ else
+ board_nor_init(partition_info[0].parts,
+ partition_info[0].nr_parts, norcs);
+
+ if (onenandcs > GPMC_CS_NUM)
+ pr_err("OneNAND: Unable to find configuration in GPMC\n");
+ else
+ board_onenand_init(partition_info[1].parts,
+ partition_info[1].nr_parts, onenandcs);
+
+ if (nandcs > GPMC_CS_NUM)
+ pr_err("NAND: Unable to find configuration in GPMC\n");
+ else
+ board_nand_init(partition_info[2].parts,
+ partition_info[2].nr_parts, nandcs, nand_type);
+}
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
new file mode 100644
index 00000000..c240a3f8
--- /dev/null
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -0,0 +1,30 @@
+/*
+ * board-sdp.h
+ *
+ * Information structures for SDP-specific board config data
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can 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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <plat/gpmc.h>
+
+#define PDC_NOR 1
+#define PDC_NAND 2
+#define PDC_ONENAND 3
+#define DBG_MPDB 4
+
+struct flash_partitions {
+ struct mtd_partition *parts;
+ int nr_parts;
+};
+
+extern void board_flash_init(struct flash_partitions [],
+ char chip_sel[][GPMC_CS_NUM], int nand_type);
+extern void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type);
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
new file mode 100644
index 00000000..73e3c31e
--- /dev/null
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -0,0 +1,76 @@
+/*
+ * linux/arch/arm/mach-omap2/board-generic.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * Code for generic OMAP2 board. Should work on many OMAP2 systems where
+ * the bootloader passes the board-specific data to the kernel.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can 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/device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+
+static struct omap_board_config_kernel generic_config[] = {
+};
+
+static void __init omap_generic_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static void __init omap_generic_init(void)
+{
+ omap_serial_init();
+ omap_board_config = generic_config;
+ omap_board_config_size = ARRAY_SIZE(generic_config);
+}
+
+static void __init omap_generic_map_io(void)
+{
+ if (cpu_is_omap242x()) {
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+ } else if (cpu_is_omap243x()) {
+ omap2_set_globals_243x();
+ omap243x_map_common_io();
+ } else if (cpu_is_omap34xx()) {
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+ } else if (cpu_is_omap44xx()) {
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+ }
+}
+
+/* XXX This machine entry name should be updated */
+MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
+ /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap_generic_map_io,
+ .init_early = omap_generic_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
new file mode 100644
index 00000000..bac7933b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -0,0 +1,392 @@
+/*
+ * linux/arch/arm/mach-omap2/board-h4.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Modified from mach-omap/omap1/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/input.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/keypad.h>
+#include <plat/menelaus.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+
+#include "mux.h"
+#include "control.h"
+
+#define H4_FLASH_CS 0
+#define H4_SMC91X_CS 1
+
+#define H4_ETHR_GPIO_IRQ 92
+
+static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 };
+static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 };
+
+static const unsigned int h4_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(2, 0, KEY_A),
+ KEY(3, 0, KEY_B),
+ KEY(4, 0, KEY_C),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(2, 1, KEY_E),
+ KEY(3, 1, KEY_F),
+ KEY(4, 1, KEY_G),
+ KEY(0, 2, KEY_ENTER),
+ KEY(1, 2, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(3, 2, KEY_K),
+ KEY(4, 2, KEY_3),
+ KEY(0, 3, KEY_M),
+ KEY(1, 3, KEY_N),
+ KEY(2, 3, KEY_O),
+ KEY(3, 3, KEY_P),
+ KEY(4, 3, KEY_Q),
+ KEY(0, 4, KEY_R),
+ KEY(1, 4, KEY_4),
+ KEY(2, 4, KEY_T),
+ KEY(3, 4, KEY_U),
+ KEY(4, 4, KEY_ENTER),
+ KEY(0, 5, KEY_V),
+ KEY(1, 5, KEY_W),
+ KEY(2, 5, KEY_L),
+ KEY(3, 5, KEY_S),
+ KEY(4, 5, KEY_ENTER),
+};
+
+static struct mtd_partition h4_partitions[] = {
+ /* bootloader (U-Boot, etc) in first sector */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = 0,
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ .mask_flags = 0
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data h4_flash_data = {
+ .width = 2,
+ .parts = h4_partitions,
+ .nr_parts = ARRAY_SIZE(h4_partitions),
+};
+
+static struct resource h4_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device h4_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &h4_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &h4_flash_resource,
+};
+
+static const struct matrix_keymap_data h4_keymap_data = {
+ .keymap = h4_keymap,
+ .keymap_size = ARRAY_SIZE(h4_keymap),
+};
+
+static struct omap_kp_platform_data h4_kp_data = {
+ .rows = 6,
+ .cols = 7,
+ .keymap_data = &h4_keymap_data,
+ .rep = true,
+ .row_gpios = row_gpios,
+ .col_gpios = col_gpios,
+};
+
+static struct platform_device h4_kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &h4_kp_data,
+ },
+};
+
+static struct platform_device h4_lcd_device = {
+ .name = "lcd_h4",
+ .id = -1,
+};
+
+static struct platform_device *h4_devices[] __initdata = {
+ &h4_flash_device,
+ &h4_kp_device,
+ &h4_lcd_device,
+};
+
+/* 2420 Sysboot setup (2430 is different) */
+static u32 get_sysboot_value(void)
+{
+ return (omap_ctrl_readl(OMAP24XX_CONTROL_STATUS) &
+ (OMAP2_SYSBOOT_5_MASK | OMAP2_SYSBOOT_4_MASK |
+ OMAP2_SYSBOOT_3_MASK | OMAP2_SYSBOOT_2_MASK |
+ OMAP2_SYSBOOT_1_MASK | OMAP2_SYSBOOT_0_MASK));
+}
+
+/* H4-2420's always used muxed mode, H4-2422's always use non-muxed
+ *
+ * Note: OMAP-GIT doesn't correctly do is_cpu_omap2422 and is_cpu_omap2423
+ * correctly. The macro needs to look at production_id not just hawkeye.
+ */
+static u32 is_gpmc_muxed(void)
+{
+ u32 mux;
+ mux = get_sysboot_value();
+ if ((mux & 0xF) == 0xd)
+ return 1; /* NAND config (could be either) */
+ if (mux & 0x2) /* if mux'ed */
+ return 1;
+ else
+ return 0;
+}
+
+static inline void __init h4_init_debug(void)
+{
+ int eth_cs;
+ unsigned long cs_mem_base;
+ unsigned int muxed, rate;
+ struct clk *gpmc_fck;
+
+ eth_cs = H4_SMC91X_CS;
+
+ gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
+ if (IS_ERR(gpmc_fck)) {
+ WARN_ON(1);
+ return;
+ }
+
+ clk_enable(gpmc_fck);
+ rate = clk_get_rate(gpmc_fck);
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+
+ if (is_gpmc_muxed())
+ muxed = 0x200;
+ else
+ muxed = 0;
+
+ /* Make sure CS1 timings are correct */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1,
+ 0x00011000 | muxed);
+
+ if (rate >= 160000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else if (rate >= 130000000) {
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
+ } else {/* rate = 100000000 */
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
+ gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
+ }
+
+ if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ goto out;
+ }
+
+ udelay(100);
+
+ omap_mux_init_gpio(92, 0);
+ if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
+ gpmc_cs_free(eth_cs);
+
+out:
+ clk_disable(gpmc_fck);
+ clk_put(gpmc_fck);
+}
+
+static void __init h4_init_flash(void)
+{
+ unsigned long base;
+
+ if (gpmc_cs_request(H4_FLASH_CS, SZ_64M, &base) < 0) {
+ printk("Can't request GPMC CS for flash\n");
+ return;
+ }
+ h4_flash_resource.start = base;
+ h4_flash_resource.end = base + SZ_64M - 1;
+}
+
+static struct omap_lcd_config h4_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_usb_config h4_usb_config __initdata = {
+ /* S1.10 OFF -- usb "download port"
+ * usb0 switched to Mini-B port and isp1105 transceiver;
+ * S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging
+ */
+ .register_dev = 1,
+ .pins[0] = 3,
+/* .hmc_mode = 0x14,*/ /* 0:dev 1:host 2:disable */
+ .hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
+};
+
+static struct omap_board_config_kernel h4_config[] __initdata = {
+ { OMAP_TAG_LCD, &h4_lcd_config },
+};
+
+static void __init omap_h4_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static void __init omap_h4_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static struct at24_platform_data m24c01 = {
+ .byte_len = SZ_1K / 8,
+ .page_size = 16,
+};
+
+static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("isp1301_omap", 0x2d),
+ .irq = OMAP_GPIO_IRQ(125),
+ },
+ { /* EEPROM on mainboard */
+ I2C_BOARD_INFO("24c01", 0x52),
+ .platform_data = &m24c01,
+ },
+ { /* EEPROM on cpu card */
+ I2C_BOARD_INFO("24c01", 0x57),
+ .platform_data = &m24c01,
+ },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap_h4_init(void)
+{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
+
+ omap_board_config = h4_config;
+ omap_board_config_size = ARRAY_SIZE(h4_config);
+
+ /*
+ * Make sure the serial ports are muxed on at this point.
+ * You have to mux them off in device drivers later on
+ * if not needed.
+ */
+
+#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
+ omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
+ if (omap_has_menelaus()) {
+ omap_mux_init_signal("sdrc_a14.gpio0",
+ OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+ omap_mux_init_signal("gpio_98", 0);
+ row_gpios[5] = 0;
+ col_gpios[2] = 15;
+ col_gpios[6] = 18;
+ } else {
+ omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("gpio_100", 0);
+ omap_mux_init_signal("gpio_98", 0);
+ }
+ omap_mux_init_signal("gpio_90", 0);
+ omap_mux_init_signal("gpio_91", 0);
+ omap_mux_init_signal("gpio_36", 0);
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+ omap_mux_init_signal("gpio_97", 0);
+#endif
+
+ i2c_register_board_info(1, h4_i2c_board_info,
+ ARRAY_SIZE(h4_i2c_board_info));
+
+ platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
+ omap2_usbfs_init(&h4_usb_config);
+ omap_serial_init();
+ h4_init_flash();
+}
+
+static void __init omap_h4_map_io(void)
+{
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+}
+
+MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
+ /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap_h4_map_io,
+ .init_early = omap_h4_init_early,
+ .init_irq = omap_h4_init_irq,
+ .init_machine = omap_h4_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
new file mode 100644
index 00000000..0c1bfca3
--- /dev/null
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2009 Integration Software and Electronic Engineering.
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-numonyx-m65kxxxxam.h"
+#include "common-board-devices.h"
+
+#define IGEP2_SMSC911X_CS 5
+#define IGEP2_SMSC911X_GPIO 176
+#define IGEP2_GPIO_USBH_NRESET 24
+#define IGEP2_GPIO_LED0_GREEN 26
+#define IGEP2_GPIO_LED0_RED 27
+#define IGEP2_GPIO_LED1_RED 28
+#define IGEP2_GPIO_DVI_PUP 170
+
+#define IGEP2_RB_GPIO_WIFI_NPD 94
+#define IGEP2_RB_GPIO_WIFI_NRESET 95
+#define IGEP2_RB_GPIO_BT_NRESET 137
+#define IGEP2_RC_GPIO_WIFI_NPD 138
+#define IGEP2_RC_GPIO_WIFI_NRESET 139
+#define IGEP2_RC_GPIO_BT_NRESET 137
+
+#define IGEP3_GPIO_LED0_GREEN 54
+#define IGEP3_GPIO_LED0_RED 53
+#define IGEP3_GPIO_LED1_RED 16
+#define IGEP3_GPIO_USBH_NRESET 183
+
+/*
+ * IGEP2 Hardware Revision Table
+ *
+ * --------------------------------------------------------------------------
+ * | Id. | Hw Rev. | HW0 (28) | WIFI_NPD | WIFI_NRESET | BT_NRESET |
+ * --------------------------------------------------------------------------
+ * | 0 | B | high | gpio94 | gpio95 | - |
+ * | 0 | B/C (B-compatible) | high | gpio94 | gpio95 | gpio137 |
+ * | 1 | C | low | gpio138 | gpio139 | gpio137 |
+ * --------------------------------------------------------------------------
+ */
+
+#define IGEP2_BOARD_HWREV_B 0
+#define IGEP2_BOARD_HWREV_C 1
+#define IGEP3_BOARD_HWREV 2
+
+static u8 hwrev;
+
+static void __init igep2_get_revision(void)
+{
+ u8 ret;
+
+ if (machine_is_igep0030()) {
+ hwrev = IGEP3_BOARD_HWREV;
+ return;
+ }
+
+ omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
+
+ if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) {
+ pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ return;
+ }
+
+ ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
+ if (ret == 0) {
+ pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_C;
+ } else if (ret == 1) {
+ pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
+ hwrev = IGEP2_BOARD_HWREV_B;
+ } else {
+ pr_err("IGEP2: Unknown Hardware Revision\n");
+ hwrev = -1;
+ }
+
+ gpio_free(IGEP2_GPIO_LED1_RED);
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+#define ONENAND_MAP 0x20000000
+
+/* NAND04GR4E1A ( x2 Flash built-in COMBO POP MEMORY )
+ * Since the device is equipped with two DataRAMs, and two-plane NAND
+ * Flash memory array, these two component enables simultaneous program
+ * of 4KiB. Plane1 has only even blocks such as block0, block2, block4
+ * while Plane2 has only odd blocks such as block1, block3, block5.
+ * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
+ */
+
+static struct mtd_partition igep_onenand_partitions[] = {
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 2 * (64*(2*2048))
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 6 * (64*(2*2048)),
+ },
+ {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2 * (64*(2*2048)),
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 12 * (64*(2*2048)),
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data igep_onenand_data = {
+ .parts = igep_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(igep_onenand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device igep_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep_onenand_data,
+ },
+};
+
+static void __init igep_flash_init(void)
+{
+ u8 cs = 0;
+ u8 onenandcs = GPMC_CS_NUM + 1;
+
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ u32 ret;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* Check if NAND/oneNAND is configured */
+ if ((ret & 0xC00) == 0x800)
+ /* NAND found */
+ pr_err("IGEP: Unsupported NAND found\n");
+ else {
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+ /* ONENAND found */
+ onenandcs = cs;
+ }
+ }
+
+ if (onenandcs > GPMC_CS_NUM) {
+ pr_err("IGEP: Unable to find configuration in GPMC\n");
+ return;
+ }
+
+ igep_onenand_data.cs = onenandcs;
+
+ if (platform_device_register(&igep_onenand_device) < 0)
+ pr_err("IGEP: Unable to register OneNAND device\n");
+}
+
+#else
+static void __init igep_flash_init(void) {}
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = IGEP2_SMSC911X_CS,
+ .gpio_irq = IGEP2_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static inline void __init igep2_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init igep2_init_smsc911x(void) { }
+#endif
+
+static struct regulator_consumer_supply igep_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data igep_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep_vmmc1_supply,
+};
+
+static struct regulator_consumer_supply igep_vio_supply =
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1");
+
+static struct regulator_init_data igep_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep_vio_supply,
+};
+
+static struct regulator_consumer_supply igep_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
+
+static struct regulator_init_data igep_vmmc2 = {
+ .constraints = {
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &igep_vmmc2_supply,
+};
+
+static struct fixed_voltage_config igep_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 1,
+ .init_data = &igep_vmmc2,
+};
+
+static struct platform_device igep_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &igep_vwlan,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+#endif
+ {} /* Terminator */
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led igep_gpio_leds[] = {
+ [0] = {
+ .name = "gpio-led:red:d0",
+ .default_trigger = "default-off"
+ },
+ [1] = {
+ .name = "gpio-led:green:d0",
+ .default_trigger = "default-off",
+ },
+ [2] = {
+ .name = "gpio-led:red:d1",
+ .default_trigger = "default-off",
+ },
+ [3] = {
+ .name = "gpio-led:green:d1",
+ .default_trigger = "heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data igep_led_pdata = {
+ .leds = igep_gpio_leds,
+ .num_leds = ARRAY_SIZE(igep_gpio_leds),
+};
+
+static struct platform_device igep_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &igep_led_pdata,
+ },
+};
+
+static void __init igep_leds_init(void)
+{
+ if (machine_is_igep0020()) {
+ igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+ } else {
+ igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+ }
+
+ platform_device_register(&igep_led_device);
+}
+
+#else
+static struct gpio igep_gpio_leds[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d0" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d1" },
+};
+
+static inline void igep_leds_init(void)
+{
+ int i;
+
+ if (machine_is_igep0020()) {
+ igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+ } else {
+ igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+ igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+ igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+ }
+
+ if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) {
+ pr_warning("IGEP v2: Could not obtain leds gpios\n");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++)
+ gpio_export(igep_gpio_leds[i].gpio, 0);
+}
+#endif
+
+static struct gpio igep2_twl_gpios[] = {
+ { -EINVAL, GPIOF_IN, "GPIO_EHCI_NOC" },
+ { -EINVAL, GPIOF_OUT_INIT_LOW, "GPIO_USBH_CPEN" },
+};
+
+static int igep_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
+ ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH,
+ "gpio-led:green:d1");
+ if (ret == 0)
+ gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
+ else
+ pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n");
+#else
+ igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
+ if (machine_is_igep0030())
+ return 0;
+
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ igep2_twl_gpios[0].gpio = gpio + 1;
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */
+ igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX;
+
+ ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios));
+ if (ret < 0)
+ pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
+
+ return 0;
+};
+
+static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = igep_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data igep_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static int igep2_enable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1);
+
+ return 0;
+}
+
+static void igep2_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_direction_output(IGEP2_GPIO_DVI_PUP, 0);
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = igep2_enable_dvi,
+ .platform_disable = igep2_disable_dvi,
+};
+
+static struct omap_dss_device igep2_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *igep2_dss_devices[] = {
+ &igep2_dvi_device
+};
+
+static struct omap_dss_board_info igep2_dss_data = {
+ .num_devices = ARRAY_SIZE(igep2_dss_devices),
+ .devices = igep2_dss_devices,
+ .default_device = &igep2_dvi_device,
+};
+
+static struct regulator_consumer_supply igep2_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data igep2_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies),
+ .consumer_supplies = igep2_vpll2_supplies,
+};
+
+static void __init igep2_display_init(void)
+{
+ int err = gpio_request_one(IGEP2_GPIO_DVI_PUP, GPIOF_OUT_INIT_HIGH,
+ "GPIO_DVI_PUP");
+ if (err)
+ pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
+}
+
+static struct platform_device *igep_devices[] __initdata = {
+ &igep_vwlan_device,
+};
+
+static void __init igep_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(m65kxxxxam_sdrc_params,
+ m65kxxxxam_sdrc_params);
+}
+
+static struct twl4030_codec_audio_data igep2_audio_data;
+
+static struct twl4030_codec_data igep2_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &igep2_audio_data,
+};
+
+static int igep2_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_A),
+ KEY(0, 3, KEY_B),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_F),
+ KEY(2, 0, KEY_ENTER),
+ KEY(2, 1, KEY_I),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_K),
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data igep2_keymap_data = {
+ .keymap = igep2_keymap,
+ .keymap_size = ARRAY_SIZE(igep2_keymap),
+};
+
+static struct twl4030_keypad_data igep2_keypad_pdata = {
+ .keymap_data = &igep2_keymap_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+static struct twl4030_platform_data igep_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .usb = &igep_usb_data,
+ .gpio = &igep_twl4030_gpio_pdata,
+ .vmmc1 = &igep_vmmc1,
+ .vio = &igep_vio,
+};
+
+static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static void __init igep_i2c_init(void)
+{
+ int ret;
+
+ if (machine_is_igep0020()) {
+ /*
+ * Bus 3 is attached to the DVI port where devices like the
+ * pico DLP projector don't work reliably with 400kHz
+ */
+ ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
+ ARRAY_SIZE(igep2_i2c3_boardinfo));
+ if (ret)
+ pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
+
+ igep_twldata.codec = &igep2_codec_data;
+ igep_twldata.keypad = &igep2_keypad_pdata;
+ igep_twldata.vpll2 = &igep2_vpll2;
+ }
+
+ omap3_pmic_init("twl4030", &igep_twldata);
+}
+
+static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+static struct gpio igep_wlan_bt_gpios[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD" },
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" },
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET" },
+};
+
+static void __init igep_wlan_bt_init(void)
+{
+ int err;
+
+ /* GPIO's for WLAN-BT combo depends on hardware revision */
+ if (hwrev == IGEP2_BOARD_HWREV_B) {
+ igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD;
+ igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET;
+ igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET;
+ } else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) {
+ igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD;
+ igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET;
+ igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET;
+ } else
+ return;
+
+ err = gpio_request_array(igep_wlan_bt_gpios,
+ ARRAY_SIZE(igep_wlan_bt_gpios));
+ if (err) {
+ pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n");
+ return;
+ }
+
+ gpio_export(igep_wlan_bt_gpios[0].gpio, 0);
+ gpio_export(igep_wlan_bt_gpios[1].gpio, 0);
+ gpio_export(igep_wlan_bt_gpios[2].gpio, 0);
+
+ gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0);
+ udelay(10);
+ gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1);
+
+}
+#else
+static inline void __init igep_wlan_bt_init(void) { }
+#endif
+
+static void __init igep_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
+ /* Get IGEP2 hardware revision */
+ igep2_get_revision();
+ /* Register I2C busses and drivers */
+ igep_i2c_init();
+ platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
+ omap_serial_init();
+ usb_musb_init(NULL);
+
+ igep_flash_init();
+ igep_leds_init();
+
+ /*
+ * WLAN-BT combo module from MuRata which has a Marvell WLAN
+ * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
+ */
+ igep_wlan_bt_init();
+
+ if (machine_is_igep0020()) {
+ omap_display_init(&igep2_dss_data);
+ igep2_display_init();
+ igep2_init_smsc911x();
+ usbhs_init(&igep2_usbhs_bdata);
+ } else {
+ usbhs_init(&igep3_usbhs_bdata);
+ }
+}
+
+MACHINE_START(IGEP0020, "IGEP v2 board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = igep_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = igep_init,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(IGEP0030, "IGEP OMAP3 module")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = igep_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = igep_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
new file mode 100644
index 00000000..f7d60380
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -0,0 +1,356 @@
+/*
+ * linux/arch/arm/mach-omap2/board-ldp.c
+ *
+ * Copyright (C) 2008 Texas Instruments Inc.
+ * Nishant Kamat <nskamat@ti.com>
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio_keys.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <mach/gpio.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <mach/board-zoom.h>
+
+#include <asm/delay.h>
+#include <plat/usb.h>
+#include <plat/gpmc-smsc911x.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#define LDP_SMSC911X_CS 1
+#define LDP_SMSC911X_GPIO 152
+#define DEBUG_BASE 0x08000000
+#define LDP_ETHR_START DEBUG_BASE
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_1),
+ KEY(1, 0, KEY_2),
+ KEY(2, 0, KEY_3),
+ KEY(0, 1, KEY_4),
+ KEY(1, 1, KEY_5),
+ KEY(2, 1, KEY_6),
+ KEY(3, 1, KEY_F5),
+ KEY(0, 2, KEY_7),
+ KEY(1, 2, KEY_8),
+ KEY(2, 2, KEY_9),
+ KEY(3, 2, KEY_F6),
+ KEY(0, 3, KEY_F7),
+ KEY(1, 3, KEY_0),
+ KEY(2, 3, KEY_F8),
+ PERSISTENT_KEY(4, 5),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ 0
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data ldp_kp_twl4030_data = {
+ .keymap_data = &board_map_data,
+ .rows = 6,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct gpio_keys_button ldp_gpio_keys_buttons[] = {
+ [0] = {
+ .code = KEY_ENTER,
+ .gpio = 101,
+ .desc = "enter sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [1] = {
+ .code = KEY_F1,
+ .gpio = 102,
+ .desc = "func 1",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [2] = {
+ .code = KEY_F2,
+ .gpio = 103,
+ .desc = "func 2",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [3] = {
+ .code = KEY_F3,
+ .gpio = 104,
+ .desc = "func 3",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [4] = {
+ .code = KEY_F4,
+ .gpio = 105,
+ .desc = "func 4",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [5] = {
+ .code = KEY_LEFT,
+ .gpio = 106,
+ .desc = "left sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [6] = {
+ .code = KEY_RIGHT,
+ .gpio = 107,
+ .desc = "right sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [7] = {
+ .code = KEY_UP,
+ .gpio = 108,
+ .desc = "up sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+ [8] = {
+ .code = KEY_DOWN,
+ .gpio = 109,
+ .desc = "down sw",
+ .active_low = 1,
+ .debounce_interval = 30,
+ },
+};
+
+static struct gpio_keys_platform_data ldp_gpio_keys = {
+ .buttons = ldp_gpio_keys_buttons,
+ .nbuttons = ARRAY_SIZE(ldp_gpio_keys_buttons),
+ .rep = 1,
+};
+
+static struct platform_device ldp_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &ldp_gpio_keys,
+ },
+};
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = LDP_SMSC911X_CS,
+ .gpio_irq = LDP_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static inline void __init ldp_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+static struct platform_device ldp_lcd_device = {
+ .name = "ldp_lcd",
+ .id = -1,
+};
+
+static struct omap_lcd_config ldp_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel ldp_config[] __initdata = {
+ { OMAP_TAG_LCD, &ldp_lcd_config },
+};
+
+static void __init omap_ldp_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static struct twl4030_usb_data ldp_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_gpio_platform_data ldp_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_madc_platform_data ldp_madc_data = {
+ .irq_line = 1,
+};
+
+static struct regulator_consumer_supply ldp_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data ldp_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldp_vmmc1_supply,
+};
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply ldp_vaux1_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+};
+
+/* VAUX1 */
+static struct regulator_init_data ldp_vaux1 = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldp_vaux1_supplies),
+ .consumer_supplies = ldp_vaux1_supplies,
+};
+
+static struct twl4030_platform_data ldp_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .madc = &ldp_madc_data,
+ .usb = &ldp_usb_data,
+ .vmmc1 = &ldp_vmmc1,
+ .vaux1 = &ldp_vaux1,
+ .gpio = &ldp_gpio_data,
+ .keypad = &ldp_kp_twl4030_data,
+};
+
+static int __init omap_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &ldp_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct platform_device *ldp_devices[] __initdata = {
+ &ldp_lcd_device,
+ &ldp_gpio_keys_device,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct mtd_partition ldp_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048), /* 512KB, 0x80000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 2 * (64 * 2048), /* 256KB, 0x40000 */
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/
+ .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */
+ },
+ {
+ .name = "File System - NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */
+ .size = MTDPART_SIZ_FULL, /* 96MB, 0x6000000 */
+ },
+
+};
+
+static void __init omap_ldp_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = ldp_config;
+ omap_board_config_size = ARRAY_SIZE(ldp_config);
+ ldp_init_smsc911x();
+ omap_i2c_init();
+ platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
+ omap_ads7846_init(1, 54, 310, NULL);
+ omap_serial_init();
+ usb_musb_init(NULL);
+ board_nand_init(ldp_nand_partitions,
+ ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
+
+ omap2_hsmmc_init(mmc);
+ /* link regulators to MMC adapters */
+ ldp_vmmc1_supply.dev = mmc[0].dev;
+}
+
+MACHINE_START(OMAP_LDP, "OMAP LDP board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap_ldp_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_ldp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
new file mode 100644
index 00000000..8d74318e
--- /dev/null
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -0,0 +1,725 @@
+/*
+ * linux/arch/arm/mach-omap2/board-n8x0.c
+ *
+ * Copyright (C) 2005-2009 Nokia Corporation
+ * Author: Juha Yrjola <juha.yrjola@nokia.com>
+ *
+ * Modified from mach-omap2/board-generic.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/usb/musb.h>
+#include <sound/tlv320aic3x.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/menelaus.h>
+#include <mach/irqs.h>
+#include <plat/mcspi.h>
+#include <plat/onenand.h>
+#include <plat/mmc.h>
+#include <plat/serial.h>
+
+#include "mux.h"
+
+static int slot1_cover_open;
+static int slot2_cover_open;
+static struct device *mmc_device;
+
+#define TUSB6010_ASYNC_CS 1
+#define TUSB6010_SYNC_CS 4
+#define TUSB6010_GPIO_INT 58
+#define TUSB6010_GPIO_ENABLE 0
+#define TUSB6010_DMACHAN 0x3f
+
+#ifdef CONFIG_USB_MUSB_TUSB6010
+/*
+ * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
+ * 1.5 V voltage regulators of PM companion chip. Companion chip will then
+ * provide then PGOOD signal to TUSB6010 which will release it from reset.
+ */
+static int tusb_set_power(int state)
+{
+ int i, retval = 0;
+
+ if (state) {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
+ msleep(1);
+
+ /* Wait until TUSB6010 pulls INT pin down */
+ i = 100;
+ while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
+ msleep(1);
+ i--;
+ }
+
+ if (!i) {
+ printk(KERN_ERR "tusb: powerup failed\n");
+ retval = -ENODEV;
+ }
+ } else {
+ gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
+ msleep(10);
+ }
+
+ return retval;
+}
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+static struct musb_hdrc_platform_data tusb_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+ .mode = MUSB_HOST,
+#endif
+ .set_power = tusb_set_power,
+ .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */
+ .power = 100, /* Max 100 mA VBUS for host mode */
+ .config = &musb_config,
+};
+
+static void __init n8x0_usb_init(void)
+{
+ int ret = 0;
+ static char announce[] __initdata = KERN_INFO "TUSB 6010\n";
+
+ /* PM companion chip power control pin */
+ ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW,
+ "TUSB6010 enable");
+ if (ret != 0) {
+ printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
+ TUSB6010_GPIO_ENABLE);
+ return;
+ }
+ tusb_set_power(0);
+
+ ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
+ TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
+ TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
+ if (ret != 0)
+ goto err;
+
+ printk(announce);
+
+ return;
+
+err:
+ gpio_free(TUSB6010_GPIO_ENABLE);
+}
+#else
+
+static void __init n8x0_usb_init(void) {}
+
+#endif /*CONFIG_USB_MUSB_TUSB6010 */
+
+
+static struct omap2_mcspi_device_config p54spi_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct spi_board_info n800_spi_board_info[] __initdata = {
+ {
+ .modalias = "p54spi",
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 48000000,
+ .controller_data = &p54spi_mcspi_config,
+ },
+};
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+static struct mtd_partition onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x20000,
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x60000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "initfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x400000,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 26,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READ,
+ }
+};
+#endif
+
+#if defined(CONFIG_MENELAUS) && \
+ (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE))
+
+/*
+ * On both N800 and N810, only the first of the two MMC controllers is in use.
+ * The two MMC slots are multiplexed via Menelaus companion chip over I2C.
+ * On N800, both slots are powered via Menelaus. On N810, only one of the
+ * slots is powered via Menelaus. The N810 EMMC is powered via GPIO.
+ *
+ * VMMC slot 1 on both N800 and N810
+ * VDCDC3_APE and VMCS2_APE slot 2 on N800
+ * GPIO23 and GPIO9 slot 2 EMMC on N810
+ *
+ */
+#define N8X0_SLOT_SWITCH_GPIO 96
+#define N810_EMMC_VSD_GPIO 23
+#define N810_EMMC_VIO_GPIO 9
+
+static int n8x0_mmc_switch_slot(struct device *dev, int slot)
+{
+#ifdef CONFIG_MMC_DEBUG
+ dev_dbg(dev, "Choose slot %d\n", slot + 1);
+#endif
+ gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot);
+ return 0;
+}
+
+static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ int mV;
+
+#ifdef CONFIG_MMC_DEBUG
+ dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
+ power_on ? "on" : "off", vdd);
+#endif
+ if (slot == 0) {
+ if (!power_on)
+ return menelaus_set_vmmc(0);
+ switch (1 << vdd) {
+ case MMC_VDD_33_34:
+ case MMC_VDD_32_33:
+ case MMC_VDD_31_32:
+ mV = 3100;
+ break;
+ case MMC_VDD_30_31:
+ mV = 3000;
+ break;
+ case MMC_VDD_28_29:
+ mV = 2800;
+ break;
+ case MMC_VDD_165_195:
+ mV = 1850;
+ break;
+ default:
+ BUG();
+ }
+ return menelaus_set_vmmc(mV);
+ } else {
+ if (!power_on)
+ return menelaus_set_vdcdc(3, 0);
+ switch (1 << vdd) {
+ case MMC_VDD_33_34:
+ case MMC_VDD_32_33:
+ mV = 3300;
+ break;
+ case MMC_VDD_30_31:
+ case MMC_VDD_29_30:
+ mV = 3000;
+ break;
+ case MMC_VDD_28_29:
+ case MMC_VDD_27_28:
+ mV = 2800;
+ break;
+ case MMC_VDD_24_25:
+ case MMC_VDD_23_24:
+ mV = 2400;
+ break;
+ case MMC_VDD_22_23:
+ case MMC_VDD_21_22:
+ mV = 2200;
+ break;
+ case MMC_VDD_20_21:
+ mV = 2000;
+ break;
+ case MMC_VDD_165_195:
+ mV = 1800;
+ break;
+ default:
+ BUG();
+ }
+ return menelaus_set_vdcdc(3, mV);
+ }
+ return 0;
+}
+
+static void n810_set_power_emmc(struct device *dev,
+ int power_on)
+{
+ dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off");
+
+ if (power_on) {
+ gpio_set_value(N810_EMMC_VSD_GPIO, 1);
+ msleep(1);
+ gpio_set_value(N810_EMMC_VIO_GPIO, 1);
+ msleep(1);
+ } else {
+ gpio_set_value(N810_EMMC_VIO_GPIO, 0);
+ msleep(50);
+ gpio_set_value(N810_EMMC_VSD_GPIO, 0);
+ msleep(50);
+ }
+}
+
+static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ if (machine_is_nokia_n800() || slot == 0)
+ return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd);
+
+ n810_set_power_emmc(dev, power_on);
+
+ return 0;
+}
+
+static int n8x0_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+{
+ int r;
+
+ dev_dbg(dev, "Set slot %d bus mode %s\n", slot + 1,
+ bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
+ BUG_ON(slot != 0 && slot != 1);
+ slot++;
+ switch (bus_mode) {
+ case MMC_BUSMODE_OPENDRAIN:
+ r = menelaus_set_mmc_opendrain(slot, 1);
+ break;
+ case MMC_BUSMODE_PUSHPULL:
+ r = menelaus_set_mmc_opendrain(slot, 0);
+ break;
+ default:
+ BUG();
+ }
+ if (r != 0 && printk_ratelimit())
+ dev_err(dev, "MMC: unable to set bus mode for slot %d\n",
+ slot);
+ return r;
+}
+
+static int n8x0_mmc_get_cover_state(struct device *dev, int slot)
+{
+ slot++;
+ BUG_ON(slot != 1 && slot != 2);
+ if (slot == 1)
+ return slot1_cover_open;
+ else
+ return slot2_cover_open;
+}
+
+static void n8x0_mmc_callback(void *data, u8 card_mask)
+{
+ int bit, *openp, index;
+
+ if (machine_is_nokia_n800()) {
+ bit = 1 << 1;
+ openp = &slot2_cover_open;
+ index = 1;
+ } else {
+ bit = 1;
+ openp = &slot1_cover_open;
+ index = 0;
+ }
+
+ if (card_mask & bit)
+ *openp = 1;
+ else
+ *openp = 0;
+
+ omap_mmc_notify_cover_event(mmc_device, index, *openp);
+}
+
+static int n8x0_mmc_late_init(struct device *dev)
+{
+ int r, bit, *openp;
+ int vs2sel;
+
+ mmc_device = dev;
+
+ r = menelaus_set_slot_sel(1);
+ if (r < 0)
+ return r;
+
+ if (machine_is_nokia_n800())
+ vs2sel = 0;
+ else
+ vs2sel = 2;
+
+ r = menelaus_set_mmc_slot(2, 0, vs2sel, 1);
+ if (r < 0)
+ return r;
+
+ n8x0_mmc_set_power(dev, 0, MMC_POWER_ON, 16); /* MMC_VDD_28_29 */
+ n8x0_mmc_set_power(dev, 1, MMC_POWER_ON, 16);
+
+ r = menelaus_set_mmc_slot(1, 1, 0, 1);
+ if (r < 0)
+ return r;
+ r = menelaus_set_mmc_slot(2, 1, vs2sel, 1);
+ if (r < 0)
+ return r;
+
+ r = menelaus_get_slot_pin_states();
+ if (r < 0)
+ return r;
+
+ if (machine_is_nokia_n800()) {
+ bit = 1 << 1;
+ openp = &slot2_cover_open;
+ } else {
+ bit = 1;
+ openp = &slot1_cover_open;
+ slot2_cover_open = 0;
+ }
+
+ /* All slot pin bits seem to be inversed until first switch change */
+ if (r == 0xf || r == (0xf & ~bit))
+ r = ~r;
+
+ if (r & bit)
+ *openp = 1;
+ else
+ *openp = 0;
+
+ r = menelaus_register_mmc_callback(n8x0_mmc_callback, NULL);
+
+ return r;
+}
+
+static void n8x0_mmc_shutdown(struct device *dev)
+{
+ int vs2sel;
+
+ if (machine_is_nokia_n800())
+ vs2sel = 0;
+ else
+ vs2sel = 2;
+
+ menelaus_set_mmc_slot(1, 0, 0, 0);
+ menelaus_set_mmc_slot(2, 0, vs2sel, 0);
+}
+
+static void n8x0_mmc_cleanup(struct device *dev)
+{
+ menelaus_unregister_mmc_callback();
+
+ gpio_free(N8X0_SLOT_SWITCH_GPIO);
+
+ if (machine_is_nokia_n810()) {
+ gpio_free(N810_EMMC_VSD_GPIO);
+ gpio_free(N810_EMMC_VIO_GPIO);
+ }
+}
+
+/*
+ * MMC controller1 has two slots that are multiplexed via I2C.
+ * MMC controller2 is not in use.
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+ .nr_slots = 2,
+ .switch_slot = n8x0_mmc_switch_slot,
+ .init = n8x0_mmc_late_init,
+ .cleanup = n8x0_mmc_cleanup,
+ .shutdown = n8x0_mmc_shutdown,
+ .max_freq = 24000000,
+ .dma_mask = 0xffffffff,
+ .slots[0] = {
+ .wires = 4,
+ .set_power = n8x0_mmc_set_power,
+ .set_bus_mode = n8x0_mmc_set_bus_mode,
+ .get_cover_state = n8x0_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_30_31 |
+ MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "internal",
+ },
+ .slots[1] = {
+ .set_power = n8x0_mmc_set_power,
+ .set_bus_mode = n8x0_mmc_set_bus_mode,
+ .get_cover_state = n8x0_mmc_get_cover_state,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_20_21 |
+ MMC_VDD_21_22 | MMC_VDD_22_23 |
+ MMC_VDD_23_24 | MMC_VDD_24_25 |
+ MMC_VDD_27_28 | MMC_VDD_28_29 |
+ MMC_VDD_29_30 | MMC_VDD_30_31 |
+ MMC_VDD_32_33 | MMC_VDD_33_34,
+ .name = "external",
+ },
+};
+
+static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
+
+static struct gpio n810_emmc_gpios[] __initdata = {
+ { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" },
+ { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" },
+};
+
+static void __init n8x0_mmc_init(void)
+{
+ int err;
+
+ if (machine_is_nokia_n810()) {
+ mmc1_data.slots[0].name = "external";
+
+ /*
+ * Some Samsung Movinand chips do not like open-ended
+ * multi-block reads and fall to braind-dead state
+ * while doing so. Reducing the number of blocks in
+ * the transfer or delays in clock disable do not help
+ */
+ mmc1_data.slots[1].name = "internal";
+ mmc1_data.slots[1].ban_openended = 1;
+ }
+
+ err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW,
+ "MMC slot switch");
+ if (err)
+ return;
+
+ if (machine_is_nokia_n810()) {
+ err = gpio_request_array(n810_emmc_gpios,
+ ARRAY_SIZE(n810_emmc_gpios));
+ if (err) {
+ gpio_free(N8X0_SLOT_SWITCH_GPIO);
+ return;
+ }
+ }
+
+ mmc_data[0] = &mmc1_data;
+ omap242x_init_mmc(mmc_data);
+}
+#else
+
+void __init n8x0_mmc_init(void)
+{
+}
+#endif /* CONFIG_MMC_OMAP */
+
+#ifdef CONFIG_MENELAUS
+
+static int n8x0_auto_sleep_regulators(void)
+{
+ u32 val;
+ int ret;
+
+ val = EN_VPLL_SLEEP | EN_VMMC_SLEEP \
+ | EN_VAUX_SLEEP | EN_VIO_SLEEP \
+ | EN_VMEM_SLEEP | EN_DC3_SLEEP \
+ | EN_VC_SLEEP | EN_DC2_SLEEP;
+
+ ret = menelaus_set_regulator_sleep(1, val);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set regulators to sleep on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n8x0_auto_voltage_scale(void)
+{
+ int ret;
+
+ ret = menelaus_set_vcore_hw(1400, 1050);
+ if (ret < 0) {
+ printk(KERN_ERR "Could not set VCORE voltage on "
+ "menelaus: %u\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+ int ret;
+
+ ret = n8x0_auto_voltage_scale();
+ if (ret < 0)
+ return ret;
+ ret = n8x0_auto_sleep_regulators();
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+#else
+static int n8x0_menelaus_late_init(struct device *dev)
+{
+ return 0;
+}
+#endif
+
+static struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = {
+ .late_init = n8x0_menelaus_late_init,
+};
+
+static struct i2c_board_info __initdata n8x0_i2c_board_info_1[] __initdata = {
+ {
+ I2C_BOARD_INFO("menelaus", 0x72),
+ .irq = INT_24XX_SYS_NIRQ,
+ .platform_data = &n8x0_menelaus_platform_data,
+ },
+};
+
+static struct aic3x_pdata n810_aic33_data __initdata = {
+ .gpio_reset = 118,
+};
+
+static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &n810_aic33_data,
+ },
+};
+
+static void __init n8x0_map_io(void)
+{
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+}
+
+static void __init n8x0_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* I2S codec port pins for McBSP block */
+ OMAP2420_MUX(EAC_AC_SCLK, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_FS, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DIN, OMAP_MUX_MODE1 | OMAP_PIN_INPUT),
+ OMAP2420_MUX(EAC_AC_DOUT, OMAP_MUX_MODE1 | OMAP_PIN_OUTPUT),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ {
+ .name = "uart3_rx_irrx.uart3_rx_irrx",
+ .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
+ .enable = OMAP_MUX_MODE0,
+ .idle = OMAP_MUX_MODE3 /* Mux as GPIO for idle */
+ },
+};
+
+static inline void board_serial_init(void)
+{
+ struct omap_board_data bdata;
+
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+
+ bdata.id = 0;
+ omap_serial_init_port(&bdata);
+
+ bdata.id = 1;
+ omap_serial_init_port(&bdata);
+
+ bdata.id = 2;
+ bdata.pads = serial2_pads;
+ bdata.pads_cnt = ARRAY_SIZE(serial2_pads);
+ omap_serial_init_port(&bdata);
+}
+
+#else
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+
+#endif
+
+static void __init n8x0_init_machine(void)
+{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+ /* FIXME: add n810 spi devices */
+ spi_register_board_info(n800_spi_board_info,
+ ARRAY_SIZE(n800_spi_board_info));
+ omap_register_i2c_bus(1, 400, n8x0_i2c_board_info_1,
+ ARRAY_SIZE(n8x0_i2c_board_info_1));
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ if (machine_is_nokia_n810())
+ i2c_register_board_info(2, n810_i2c_board_info_2,
+ ARRAY_SIZE(n810_i2c_board_info_2));
+ board_serial_init();
+ gpmc_onenand_init(board_onenand_data);
+ n8x0_mmc_init();
+ n8x0_usb_init();
+}
+
+MACHINE_START(NOKIA_N800, "Nokia N800")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = n8x0_map_io,
+ .init_early = n8x0_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810, "Nokia N810")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = n8x0_map_io,
+ .init_early = n8x0_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = n8x0_map_io,
+ .init_early = n8x0_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = n8x0_init_machine,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
new file mode 100644
index 00000000..7f21d24b
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -0,0 +1,603 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3beagle.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/opp.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <plat/omap_device.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "pm.h"
+#include "common-board-devices.h"
+
+/*
+ * OMAP3 Beagle revision
+ * Run time detection of Beagle revision is done by reading GPIO.
+ * GPIO ID -
+ * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1
+ * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0
+ * C4 = GPIO173, GPIO172, GPIO171: 1 0 1
+ * XM = GPIO173, GPIO172, GPIO171: 0 0 0
+ */
+enum {
+ OMAP3BEAGLE_BOARD_UNKN = 0,
+ OMAP3BEAGLE_BOARD_AXBX,
+ OMAP3BEAGLE_BOARD_C1_3,
+ OMAP3BEAGLE_BOARD_C4,
+ OMAP3BEAGLE_BOARD_XM,
+};
+
+static u8 omap3_beagle_version;
+
+static u8 omap3_beagle_get_rev(void)
+{
+ return omap3_beagle_version;
+}
+
+static struct gpio omap3_beagle_rev_gpios[] __initdata = {
+ { 171, GPIOF_IN, "rev_id_0" },
+ { 172, GPIOF_IN, "rev_id_1" },
+ { 173, GPIOF_IN, "rev_id_2" },
+};
+
+static void __init omap3_beagle_init_rev(void)
+{
+ int ret;
+ u16 beagle_rev = 0;
+
+ omap_mux_init_gpio(171, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
+
+ ret = gpio_request_array(omap3_beagle_rev_gpios,
+ ARRAY_SIZE(omap3_beagle_rev_gpios));
+ if (ret < 0) {
+ printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ return;
+ }
+
+ beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
+ | (gpio_get_value(173) << 2);
+
+ gpio_free_array(omap3_beagle_rev_gpios,
+ ARRAY_SIZE(omap3_beagle_rev_gpios));
+
+ switch (beagle_rev) {
+ case 7:
+ printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_AXBX;
+ break;
+ case 6:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C1/C2/C3\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C1_3;
+ break;
+ case 5:
+ printk(KERN_INFO "OMAP3 Beagle Rev: C4\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_C4;
+ break;
+ case 0:
+ printk(KERN_INFO "OMAP3 Beagle Rev: xM\n");
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM;
+ break;
+ default:
+ printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
+ omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+ }
+}
+
+static struct mtd_partition omap3beagle_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+/* DSS */
+
+static int beagle_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 1);
+
+ return 0;
+}
+
+static void beagle_disable_dvi(struct omap_dss_device *dssdev)
+{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = beagle_enable_dvi,
+ .platform_disable = beagle_disable_dvi,
+};
+
+static struct omap_dss_device beagle_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = -EINVAL,
+};
+
+static struct omap_dss_device beagle_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static struct omap_dss_device *beagle_dss_devices[] = {
+ &beagle_dvi_device,
+ &beagle_tv_device,
+};
+
+static struct omap_dss_board_info beagle_dss_data = {
+ .num_devices = ARRAY_SIZE(beagle_dss_devices),
+ .devices = beagle_dss_devices,
+ .default_device = &beagle_dvi_device,
+};
+
+static struct regulator_consumer_supply beagle_vdac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static struct regulator_consumer_supply beagle_vdvi_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static void __init beagle_display_init(void)
+{
+ int r;
+
+ r = gpio_request_one(beagle_dvi_device.reset_gpio, GPIOF_OUT_INIT_LOW,
+ "DVI reset");
+ if (r < 0)
+ printk(KERN_ERR "Unable to get DVI reset GPIO\n");
+}
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply beagle_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply beagle_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct gpio_led gpio_leds[];
+
+static int beagle_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int r, usb_pwr_level;
+
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ mmc[0].gpio_wp = -EINVAL;
+ } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) ||
+ (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) {
+ omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+ mmc[0].gpio_wp = 23;
+ } else {
+ omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+ }
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters */
+ beagle_vmmc1_supply.dev = mmc[0].dev;
+ beagle_vsim_supply.dev = mmc[0].dev;
+
+ /*
+ * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
+ * high / others active low)
+ * DVI reset GPIO is different between beagle revisions
+ */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+ beagle_dvi_device.reset_gpio = 129;
+ /*
+ * gpio + 1 on Xm controls the TFP410's enable line (active low)
+ * gpio + 2 control varies depending on the board rev as below:
+ * P7/P8 revisions(prototype): Camera EN
+ * A2+ revisions (production): LDO (DVI, serial, led blocks)
+ */
+ r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW,
+ "nDVI_PWR_EN");
+ if (r)
+ pr_err("%s: unable to configure nDVI_PWR_EN\n",
+ __func__);
+ r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
+ "DVI_LDO_EN");
+ if (r)
+ pr_err("%s: unable to configure DVI_LDO_EN\n",
+ __func__);
+ } else {
+ usb_pwr_level = GPIOF_OUT_INIT_LOW;
+ beagle_dvi_device.reset_gpio = 170;
+ /*
+ * REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
+ pr_err("%s: unable to configure EHCI_nOC\n", __func__);
+ }
+
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data beagle_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = beagle_twl_gpio_setup,
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data beagle_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &beagle_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data beagle_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &beagle_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data beagle_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &beagle_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data beagle_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies),
+ .consumer_supplies = beagle_vdvi_supplies,
+};
+
+static struct twl4030_usb_data beagle_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data beagle_audio_data;
+
+static struct twl4030_codec_data beagle_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &beagle_audio_data,
+};
+
+static struct twl4030_platform_data beagle_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .usb = &beagle_usb_data,
+ .gpio = &beagle_gpio_data,
+ .codec = &beagle_codec_data,
+ .vmmc1 = &beagle_vmmc1,
+ .vsim = &beagle_vsim,
+ .vdac = &beagle_vdac,
+ .vpll2 = &beagle_vpll2,
+};
+
+static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static int __init omap3_beagle_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &beagle_twldata);
+ /* Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz */
+ omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
+ return 0;
+}
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "beagleboard::usr0",
+ .default_trigger = "heartbeat",
+ .gpio = 150,
+ },
+ {
+ .name = "beagleboard::usr1",
+ .default_trigger = "mmc0",
+ .gpio = 149,
+ },
+ {
+ .name = "beagleboard::pmu_stat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 7,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static void __init omap3_beagle_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+static void __init omap3_beagle_init_irq(void)
+{
+ omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+ omap2_gp_clockevent_set_gptimer(12);
+#endif
+}
+
+static struct platform_device *omap3_beagle_devices[] __initdata = {
+ &leds_gpio,
+ &keys_gpio,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 147,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init beagle_opp_init(void)
+{
+ int r = 0;
+
+ /* Initialize the omap3 opp table */
+ if (omap3_opp_init()) {
+ pr_err("%s: opp default init failed\n", __func__);
+ return;
+ }
+
+ /* Custom OPP enabled for XM */
+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
+ struct omap_hwmod *mh = omap_hwmod_lookup("mpu");
+ struct omap_hwmod *dh = omap_hwmod_lookup("iva");
+ struct device *dev;
+
+ if (!mh || !dh) {
+ pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
+ __func__, mh, dh);
+ return;
+ }
+ /* Enable MPU 1GHz and lower opps */
+ dev = &mh->od->pdev.dev;
+ r = opp_enable(dev, 800000000);
+ /* TODO: MPU 1GHz needs SR and ABB */
+
+ /* Enable IVA 800MHz and lower opps */
+ dev = &dh->od->pdev.dev;
+ r |= opp_enable(dev, 660000000);
+ /* TODO: DSP 800MHz needs SR and ABB */
+ if (r) {
+ pr_err("%s: failed to enable higher opp %d\n",
+ __func__, r);
+ /*
+ * Cleanup - disable the higher freqs - we dont care
+ * about the results
+ */
+ dev = &mh->od->pdev.dev;
+ opp_disable(dev, 800000000);
+ dev = &dh->od->pdev.dev;
+ opp_disable(dev, 660000000);
+ }
+ }
+ return;
+}
+
+static void __init omap3_beagle_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3_beagle_init_rev();
+ omap3_beagle_i2c_init();
+ platform_add_devices(omap3_beagle_devices,
+ ARRAY_SIZE(omap3_beagle_devices));
+ omap_display_init(&beagle_dss_data);
+ omap_serial_init();
+
+ omap_mux_init_gpio(170, OMAP_PIN_INPUT);
+ /* REVISIT leave DVI powered down until it's needed ... */
+ gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
+
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
+ ARRAY_SIZE(omap3beagle_nand_partitions));
+
+ /* Ensure msecure is mux'd to be able to set the RTC. */
+ omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ beagle_display_init();
+ beagle_opp_init();
+}
+
+MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
+ /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3_beagle_init_early,
+ .init_irq = omap3_beagle_init_irq,
+ .init_machine = omap3_beagle_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
new file mode 100644
index 00000000..b4d43464
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -0,0 +1,746 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3evm.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/leds.h>
+#include <linux/interrupt.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/i2c/twl.h>
+#include <linux/usb/otg.h>
+#include <linux/smsc911x.h>
+
+#include <linux/wl12xx.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/usb.h>
+#include <plat/common.h>
+#include <plat/mcspi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OMAP3_EVM_TS_GPIO 175
+#define OMAP3_EVM_EHCI_VBUS 22
+#define OMAP3_EVM_EHCI_SELECT 61
+
+#define OMAP3EVM_ETHR_START 0x2c000000
+#define OMAP3EVM_ETHR_SIZE 1024
+#define OMAP3EVM_ETHR_ID_REV 0x50
+#define OMAP3EVM_ETHR_GPIO_IRQ 176
+#define OMAP3EVM_SMSC911X_CS 5
+/*
+ * Eth Reset signal
+ * 64 = Generation 1 (<=RevD)
+ * 7 = Generation 2 (>=RevE)
+ */
+#define OMAP3EVM_GEN1_ETHR_GPIO_RST 64
+#define OMAP3EVM_GEN2_ETHR_GPIO_RST 7
+
+static u8 omap3_evm_version;
+
+u8 get_omap3_evm_rev(void)
+{
+ return omap3_evm_version;
+}
+EXPORT_SYMBOL(get_omap3_evm_rev);
+
+static void __init omap3_evm_get_revision(void)
+{
+ void __iomem *ioaddr;
+ unsigned int smsc_id;
+
+ /* Ethernet PHY ID is stored at ID_REV register */
+ ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K);
+ if (!ioaddr)
+ return;
+ smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000;
+ iounmap(ioaddr);
+
+ switch (smsc_id) {
+ /*SMSC9115 chipset*/
+ case 0x01150000:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
+ break;
+ /*SMSC 9220 chipset*/
+ case 0x92200000:
+ default:
+ omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
+ }
+}
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = OMAP3EVM_SMSC911X_CS,
+ .gpio_irq = OMAP3EVM_ETHR_GPIO_IRQ,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static inline void __init omap3evm_init_smsc911x(void)
+{
+ struct clk *l3ck;
+ unsigned int rate;
+
+ l3ck = clk_get(NULL, "l3_ck");
+ if (IS_ERR(l3ck))
+ rate = 100000000;
+ else
+ rate = clk_get_rate(l3ck);
+
+ /* Configure ethernet controller reset gpio */
+ if (cpu_is_omap3430()) {
+ if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
+ smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST;
+ else
+ smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
+ }
+
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init omap3evm_init_smsc911x(void) { return; }
+#endif
+
+/*
+ * OMAP3EVM LCD Panel control signals
+ */
+#define OMAP3EVM_LCD_PANEL_LR 2
+#define OMAP3EVM_LCD_PANEL_UD 3
+#define OMAP3EVM_LCD_PANEL_INI 152
+#define OMAP3EVM_LCD_PANEL_ENVDD 153
+#define OMAP3EVM_LCD_PANEL_QVGA 154
+#define OMAP3EVM_LCD_PANEL_RESB 155
+#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210
+#define OMAP3EVM_DVI_PANEL_EN_GPIO 199
+
+static struct gpio omap3_evm_dss_gpios[] __initdata = {
+ { OMAP3EVM_LCD_PANEL_RESB, GPIOF_OUT_INIT_HIGH, "lcd_panel_resb" },
+ { OMAP3EVM_LCD_PANEL_INI, GPIOF_OUT_INIT_HIGH, "lcd_panel_ini" },
+ { OMAP3EVM_LCD_PANEL_QVGA, GPIOF_OUT_INIT_LOW, "lcd_panel_qvga" },
+ { OMAP3EVM_LCD_PANEL_LR, GPIOF_OUT_INIT_HIGH, "lcd_panel_lr" },
+ { OMAP3EVM_LCD_PANEL_UD, GPIOF_OUT_INIT_HIGH, "lcd_panel_ud" },
+ { OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW, "lcd_panel_envdd" },
+};
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_evm_display_init(void)
+{
+ int r;
+
+ r = gpio_request_array(omap3_evm_dss_gpios,
+ ARRAY_SIZE(omap3_evm_dss_gpios));
+ if (r)
+ printk(KERN_ERR "failed to get lcd_panel_* gpios\n");
+}
+
+static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+ else
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+ else
+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+
+ lcd_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_lcd_device = {
+ .name = "lcd",
+ .driver_name = "sharp_ls_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 18,
+ .platform_enable = omap3_evm_enable_lcd,
+ .platform_disable = omap3_evm_disable_lcd,
+};
+
+static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_evm_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+ .platform_enable = omap3_evm_enable_tv,
+ .platform_disable = omap3_evm_disable_tv,
+};
+
+static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 1);
+
+ dvi_enabled = 1;
+ return 0;
+}
+
+static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 0);
+
+ dvi_enabled = 0;
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = omap3_evm_enable_dvi,
+ .platform_disable = omap3_evm_disable_dvi,
+};
+
+static struct omap_dss_device omap3_evm_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *omap3_evm_dss_devices[] = {
+ &omap3_evm_lcd_device,
+ &omap3_evm_tv_device,
+ &omap3_evm_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_evm_dss_data = {
+ .num_devices = ARRAY_SIZE(omap3_evm_dss_devices),
+ .devices = omap3_evm_dss_devices,
+ .default_device = &omap3_evm_lcd_device,
+};
+
+static struct regulator_consumer_supply omap3evm_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply omap3evm_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3evm_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3evm_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3evm_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3evm_vsim_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 63,
+ },
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ {
+ .name = "wl1271",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+#endif
+ {} /* Terminator */
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "omap3evm::ledb",
+ /* normally not visible (board underside) */
+ .default_trigger = "default-on",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+
+static int omap3evm_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int r, lcd_bl_en;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ omap_mux_init_gpio(63, OMAP_PIN_INPUT);
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters */
+ omap3evm_vmmc1_supply.dev = mmc[0].dev;
+ omap3evm_vsim_supply.dev = mmc[0].dev;
+
+ /*
+ * Most GPIOs are for USB OTG. Some are mostly sent to
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+ lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ?
+ GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL");
+ if (r)
+ printk(KERN_ERR "failed to get/set lcd_bkl gpio\n");
+
+ /* gpio + 7 == DVI Enable */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ platform_device_register(&leds_gpio);
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = omap3evm_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data omap3evm_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_ENTER),
+ KEY(0, 3, KEY_M),
+
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_I),
+ KEY(1, 3, KEY_N),
+
+ KEY(2, 0, KEY_A),
+ KEY(2, 1, KEY_E),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_O),
+
+ KEY(3, 0, KEY_B),
+ KEY(3, 1, KEY_F),
+ KEY(3, 2, KEY_K),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data omap3evm_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+static struct twl4030_madc_platform_data omap3evm_madc_data = {
+ .irq_line = 1,
+};
+
+static struct twl4030_codec_audio_data omap3evm_audio_data;
+
+static struct twl4030_codec_data omap3evm_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &omap3evm_audio_data,
+};
+
+static struct regulator_consumer_supply omap3_evm_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data omap3_evm_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3_evm_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data omap3_evm_vpll2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies),
+ .consumer_supplies = omap3_evm_vpll2_supplies,
+};
+
+/* ads7846 on SPI */
+static struct regulator_consumer_supply omap3evm_vio_supply =
+ REGULATOR_SUPPLY("vcc", "spi1.0");
+
+/* VIO for ads7846 */
+static struct regulator_init_data omap3evm_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3evm_vio_supply,
+};
+
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+
+#define OMAP3EVM_WLAN_PMENA_GPIO (150)
+#define OMAP3EVM_WLAN_IRQ_GPIO (149)
+
+static struct regulator_consumer_supply omap3evm_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
+
+/* VMMC2 for driving the WL12xx module */
+static struct regulator_init_data omap3evm_vmmc2 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3evm_vmmc2_supply,
+};
+
+static struct fixed_voltage_config omap3evm_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.80V */
+ .gpio = OMAP3EVM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &omap3evm_vmmc2,
+};
+
+static struct platform_device omap3evm_wlan_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &omap3evm_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO),
+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
+};
+#endif
+
+static struct twl4030_platform_data omap3evm_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .keypad = &omap3evm_kp_data,
+ .madc = &omap3evm_madc_data,
+ .usb = &omap3evm_usb_data,
+ .gpio = &omap3evm_gpio_data,
+ .codec = &omap3evm_codec_data,
+ .vdac = &omap3_evm_vdac,
+ .vpll2 = &omap3_evm_vpll2,
+ .vio = &omap3evm_vio,
+ .vmmc1 = &omap3evm_vmmc1,
+ .vsim = &omap3evm_vsim,
+};
+
+static int __init omap3_evm_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &omap3evm_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
+};
+
+static void __init omap3_evm_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
+}
+
+static struct usbhs_omap_board_data usbhs_bdata __initdata = {
+
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ /* PHY reset GPIO will be runtime programmed based on EVM version */
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux omap35x_board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_board_mux omap36x_board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+ OMAP_PIN_OFF_WAKEUPENABLE),
+ /* AM/DM37x EVM: DSS data bus muxed with sys_boot */
+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+ OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE),
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WLAN IRQ - GPIO 149 */
+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
+ /* WLAN POWER ENABLE - GPIO 150 */
+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+
+ /* MMC2 SDIO pin muxes for WL12xx */
+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+#endif
+
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap35x_board_mux NULL
+#define omap36x_board_mux NULL
+#endif
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct gpio omap3_evm_ehci_gpios[] __initdata = {
+ { OMAP3_EVM_EHCI_VBUS, GPIOF_OUT_INIT_HIGH, "enable EHCI VBUS" },
+ { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW, "select EHCI port" },
+};
+
+static void __init omap3_evm_init(void)
+{
+ omap3_evm_get_revision();
+
+ if (cpu_is_omap3630())
+ omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB);
+ else
+ omap3_mux_init(omap35x_board_mux, OMAP_PACKAGE_CBB);
+
+ omap_board_config = omap3_evm_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
+
+ omap3_evm_i2c_init();
+
+ omap_display_init(&omap3_evm_dss_data);
+
+ omap_serial_init();
+
+ /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
+ usb_nop_xceiv_register();
+
+ if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
+ /* enable EHCI VBUS using GPIO22 */
+ omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP);
+ /* Select EHCI port on main board */
+ omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT,
+ OMAP_PIN_INPUT_PULLUP);
+ gpio_request_array(omap3_evm_ehci_gpios,
+ ARRAY_SIZE(omap3_evm_ehci_gpios));
+
+ /* setup EHCI phy reset config */
+ omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
+ usbhs_bdata.reset_gpio_port[1] = 21;
+
+ /* EVM REV >= E can supply 500mA with EXTVBUS programming */
+ musb_board_data.power = 500;
+ musb_board_data.extvbus = 1;
+ } else {
+ /* setup EHCI phy reset on MDC */
+ omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
+ usbhs_bdata.reset_gpio_port[1] = 135;
+ }
+ usb_musb_init(&musb_board_data);
+ usbhs_init(&usbhs_bdata);
+ omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
+ omap3evm_init_smsc911x();
+ omap3_evm_display_init();
+
+#ifdef CONFIG_WL12XX_PLATFORM_DATA
+ /* WL12xx WLAN Init */
+ if (wl12xx_set_platform_data(&omap3evm_wlan_data))
+ pr_err("error setting wl12xx data\n");
+ platform_device_register(&omap3evm_wlan_regulator);
+#endif
+}
+
+MACHINE_START(OMAP3EVM, "OMAP3 EVM")
+ /* Maintainer: Syed Mohammed Khasim - Texas Instruments */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3_evm_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap3_evm_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
new file mode 100644
index 00000000..60d9be49
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -0,0 +1,230 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3logic.c
+ *
+ * Copyright (C) 2010 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Copyright (C) 2010 Logic Product Development, Inc.
+ * Peter Barada <peter.barada@logicpd.com>
+ *
+ * Modified from Beagle, EVM, and RX51
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "control.h"
+#include "common-board-devices.h"
+
+#include <plat/mux.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc-smsc911x.h>
+#include <plat/gpmc.h>
+#include <plat/sdrc.h>
+
+#define OMAP3LOGIC_SMSC911X_CS 1
+
+#define OMAP3530_LV_SOM_MMC_GPIO_CD 110
+#define OMAP3530_LV_SOM_MMC_GPIO_WP 126
+#define OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ 152
+
+#define OMAP3_TORPEDO_MMC_GPIO_CD 127
+#define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ 129
+
+static struct regulator_consumer_supply omap3logic_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3logic_vmmc1 = {
+ .constraints = {
+ .name = "VMMC1",
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3logic_vmmc1_supply,
+};
+
+static struct twl4030_gpio_platform_data omap3logic_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8)
+ | BIT(13) | BIT(15) | BIT(16) | BIT(17),
+};
+
+static struct twl4030_platform_data omap3logic_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &omap3logic_gpio_data,
+ .vmmc1 = &omap3logic_vmmc1,
+};
+
+static int __init omap3logic_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &omap3logic_twldata);
+ return 0;
+}
+
+static struct omap2_hsmmc_info __initdata board_mmc_info[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static void __init board_mmc_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_mmc_info[0].gpio_cd = OMAP3530_LV_SOM_MMC_GPIO_CD;
+ board_mmc_info[0].gpio_wp = OMAP3530_LV_SOM_MMC_GPIO_WP;
+ omap_mux_init_signal("gpio_110", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("gpio_126", OMAP_PIN_OUTPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_mmc_info[0].gpio_cd = OMAP3_TORPEDO_MMC_GPIO_CD;
+ omap_mux_init_signal("gpio_127", OMAP_PIN_OUTPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ omap2_hsmmc_init(board_mmc_info);
+ /* link regulators to MMC adapters */
+ omap3logic_vmmc1_supply.dev = board_mmc_info[0].dev;
+}
+
+static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
+ .cs = OMAP3LOGIC_SMSC911X_CS,
+ .gpio_irq = -EINVAL,
+ .gpio_reset = -EINVAL,
+};
+
+/* TODO/FIXME (comment by Peter Barada, LogicPD):
+ * Fix the PBIAS voltage for Torpedo MMC1 pins that
+ * are used for other needs (IRQs, etc). */
+static void omap3torpedo_fix_pbias_voltage(void)
+{
+ u16 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+ u32 reg;
+
+ if (machine_is_omap3_torpedo())
+ {
+ /* Set the bias for the pin */
+ reg = omap_ctrl_readl(control_pbias_offset);
+
+ reg &= ~OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg, control_pbias_offset);
+
+ /* 100ms delay required for PBIAS configuration */
+ msleep(100);
+
+ reg |= OMAP343X_PBIASLITEVMODE1;
+ reg |= OMAP343X_PBIASLITEPWRDNZ1;
+ omap_ctrl_writel(reg | 0x300, control_pbias_offset);
+ }
+}
+
+static inline void __init board_smsc911x_init(void)
+{
+ if (machine_is_omap3530_lv_som()) {
+ /* OMAP3530 LV SOM board */
+ board_smsc911x_data.gpio_irq =
+ OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_152", OMAP_PIN_INPUT);
+ } else if (machine_is_omap3_torpedo()) {
+ /* OMAP3 Torpedo board */
+ board_smsc911x_data.gpio_irq = OMAP3_TORPEDO_SMSC911X_GPIO_IRQ;
+ omap_mux_init_signal("gpio_129", OMAP_PIN_INPUT);
+ } else {
+ /* unsupported board */
+ printk(KERN_ERR "%s(): unknown machine type\n", __func__);
+ return;
+ }
+
+ gpmc_smsc911x_init(&board_smsc911x_data);
+}
+
+static void __init omap3logic_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap3logic_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3torpedo_fix_pbias_voltage();
+ omap3logic_i2c_init();
+ omap_serial_init();
+ board_mmc_init();
+ board_smsc911x_init();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_early = omap3logic_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_early = omap3logic_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap3logic_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
new file mode 100644
index 00000000..23f71d40
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -0,0 +1,649 @@
+/*
+ * board-omap3pandora.c (Pandora Handheld Console)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/wl12xx.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/leds.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/regulator/fixed.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <mach/hardware.h>
+#include <plat/mcspi.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <plat/nand.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define PANDORA_WIFI_IRQ_GPIO 21
+#define PANDORA_WIFI_NRESET_GPIO 23
+#define OMAP3_PANDORA_TS_GPIO 94
+
+static struct mtd_partition omap3pandora_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 15 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "uboot-env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 80 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data pandora_nand_data = {
+ .cs = 0,
+ .devsize = NAND_BUSWIDTH_16,
+ .xfer_type = NAND_OMAP_PREFETCH_DMA,
+ .parts = omap3pandora_nand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
+};
+
+static struct gpio_led pandora_gpio_leds[] = {
+ {
+ .name = "pandora::sd1",
+ .default_trigger = "mmc0",
+ .gpio = 128,
+ }, {
+ .name = "pandora::sd2",
+ .default_trigger = "mmc1",
+ .gpio = 129,
+ }, {
+ .name = "pandora::bluetooth",
+ .gpio = 158,
+ }, {
+ .name = "pandora::wifi",
+ .gpio = 159,
+ },
+};
+
+static struct gpio_led_platform_data pandora_gpio_led_data = {
+ .leds = pandora_gpio_leds,
+ .num_leds = ARRAY_SIZE(pandora_gpio_leds),
+};
+
+static struct platform_device pandora_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &pandora_gpio_led_data,
+ },
+};
+
+#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \
+{ \
+ .gpio = gpio_num, \
+ .type = ev_type, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .debounce_interval = 4, \
+ .desc = "btn " descr, \
+}
+
+#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \
+ GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description)
+
+static struct gpio_keys_button pandora_gpio_keys[] = {
+ GPIO_BUTTON_LOW(110, KEY_UP, "up"),
+ GPIO_BUTTON_LOW(103, KEY_DOWN, "down"),
+ GPIO_BUTTON_LOW(96, KEY_LEFT, "left"),
+ GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"),
+ GPIO_BUTTON_LOW(109, KEY_PAGEUP, "game 1"),
+ GPIO_BUTTON_LOW(111, KEY_END, "game 2"),
+ GPIO_BUTTON_LOW(106, KEY_PAGEDOWN, "game 3"),
+ GPIO_BUTTON_LOW(101, KEY_HOME, "game 4"),
+ GPIO_BUTTON_LOW(102, KEY_RIGHTSHIFT, "l"),
+ GPIO_BUTTON_LOW(97, KEY_KPPLUS, "l2"),
+ GPIO_BUTTON_LOW(105, KEY_RIGHTCTRL, "r"),
+ GPIO_BUTTON_LOW(107, KEY_KPMINUS, "r2"),
+ GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"),
+ GPIO_BUTTON_LOW(99, KEY_MENU, "menu"),
+ GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"),
+ GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"),
+ GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"),
+};
+
+static struct gpio_keys_platform_data pandora_gpio_key_info = {
+ .buttons = pandora_gpio_keys,
+ .nbuttons = ARRAY_SIZE(pandora_gpio_keys),
+};
+
+static struct platform_device pandora_keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &pandora_gpio_key_info,
+ },
+};
+
+static const uint32_t board_keymap[] = {
+ /* row, col, code */
+ KEY(0, 0, KEY_9),
+ KEY(0, 1, KEY_8),
+ KEY(0, 2, KEY_I),
+ KEY(0, 3, KEY_J),
+ KEY(0, 4, KEY_N),
+ KEY(0, 5, KEY_M),
+ KEY(1, 0, KEY_0),
+ KEY(1, 1, KEY_7),
+ KEY(1, 2, KEY_U),
+ KEY(1, 3, KEY_H),
+ KEY(1, 4, KEY_B),
+ KEY(1, 5, KEY_SPACE),
+ KEY(2, 0, KEY_BACKSPACE),
+ KEY(2, 1, KEY_6),
+ KEY(2, 2, KEY_Y),
+ KEY(2, 3, KEY_G),
+ KEY(2, 4, KEY_V),
+ KEY(2, 5, KEY_FN),
+ KEY(3, 0, KEY_O),
+ KEY(3, 1, KEY_5),
+ KEY(3, 2, KEY_T),
+ KEY(3, 3, KEY_F),
+ KEY(3, 4, KEY_C),
+ KEY(4, 0, KEY_P),
+ KEY(4, 1, KEY_4),
+ KEY(4, 2, KEY_R),
+ KEY(4, 3, KEY_D),
+ KEY(4, 4, KEY_X),
+ KEY(5, 0, KEY_K),
+ KEY(5, 1, KEY_3),
+ KEY(5, 2, KEY_E),
+ KEY(5, 3, KEY_S),
+ KEY(5, 4, KEY_Z),
+ KEY(6, 0, KEY_L),
+ KEY(6, 1, KEY_2),
+ KEY(6, 2, KEY_W),
+ KEY(6, 3, KEY_A),
+ KEY(6, 4, KEY_DOT),
+ KEY(7, 0, KEY_ENTER),
+ KEY(7, 1, KEY_1),
+ KEY(7, 2, KEY_Q),
+ KEY(7, 3, KEY_LEFTSHIFT),
+ KEY(7, 4, KEY_COMMA),
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data pandora_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 6,
+ .rep = 1,
+};
+
+static struct omap_dss_device pandora_lcd_device = {
+ .name = "lcd",
+ .driver_name = "tpo_td043mtea1_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = 157,
+};
+
+static struct omap_dss_device pandora_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static struct omap_dss_device *pandora_dss_devices[] = {
+ &pandora_lcd_device,
+ &pandora_tv_device,
+};
+
+static struct omap_dss_board_info pandora_dss_data = {
+ .num_devices = ARRAY_SIZE(pandora_dss_devices),
+ .devices = pandora_dss_devices,
+ .default_device = &pandora_lcd_device,
+};
+
+static void pandora_wl1251_init_card(struct mmc_card *card)
+{
+ /*
+ * We have TI wl1251 attached to MMC3. Pass this information to
+ * SDIO core because it can't be probed by normal methods.
+ */
+ card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+ card->cccr.wide_bus = 1;
+ card->cis.vendor = 0x104c;
+ card->cis.device = 0x9066;
+ card->cis.blksize = 512;
+ card->cis.max_dtr = 20000000;
+}
+
+static struct omap2_hsmmc_info omap3pandora_mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 126,
+ .ext_clock = 0,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 127,
+ .ext_clock = 1,
+ .transceiver = true,
+ },
+ {
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .init_card = pandora_wl1251_init_card,
+ },
+ {} /* Terminator */
+};
+
+static int omap3pandora_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret, gpio_32khz;
+
+ /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
+ omap3pandora_mmc[0].gpio_cd = gpio + 0;
+ omap3pandora_mmc[1].gpio_cd = gpio + 1;
+ omap2_hsmmc_init(omap3pandora_mmc);
+
+ /* gpio + 13 drives 32kHz buffer for wifi module */
+ gpio_32khz = gpio + 13;
+ ret = gpio_request_one(gpio_32khz, GPIOF_OUT_INIT_HIGH, "wifi 32kHz");
+ if (ret < 0) {
+ pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = omap3pandora_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply pandora_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
+
+static struct regulator_consumer_supply pandora_vmmc2_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
+
+static struct regulator_consumer_supply pandora_vmmc3_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2");
+
+static struct regulator_consumer_supply pandora_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static struct regulator_consumer_supply pandora_vdds_supplies[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_consumer_supply pandora_vcc_lcd_supply =
+ REGULATOR_SUPPLY("vcc", "display0");
+
+static struct regulator_consumer_supply pandora_usb_phy_supply =
+ REGULATOR_SUPPLY("hsusb0", "ehci-omap.0");
+
+/* ads7846 on SPI and 2 nub controllers on I2C */
+static struct regulator_consumer_supply pandora_vaux4_supplies[] = {
+ REGULATOR_SUPPLY("vcc", "spi1.0"),
+ REGULATOR_SUPPLY("vcc", "3-0066"),
+ REGULATOR_SUPPLY("vcc", "3-0067"),
+};
+
+static struct regulator_consumer_supply pandora_adac_supply =
+ REGULATOR_SUPPLY("vcc", "soc-audio");
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data pandora_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */
+static struct regulator_init_data pandora_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vmmc2_supply,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data pandora_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data pandora_vpll2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vdds_supplies),
+ .consumer_supplies = pandora_vdds_supplies,
+};
+
+/* VAUX1 for LCD */
+static struct regulator_init_data pandora_vaux1 = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vcc_lcd_supply,
+};
+
+/* VAUX2 for USB host PHY */
+static struct regulator_init_data pandora_vaux2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_usb_phy_supply,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data pandora_vaux4 = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(pandora_vaux4_supplies),
+ .consumer_supplies = pandora_vaux4_supplies,
+};
+
+/* VSIM for audio DAC */
+static struct regulator_init_data pandora_vsim = {
+ .constraints = {
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_adac_supply,
+};
+
+/* Fixed regulator internal to Wifi module */
+static struct regulator_init_data pandora_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &pandora_vmmc3_supply,
+};
+
+static struct fixed_voltage_config pandora_vwlan = {
+ .supply_name = "vwlan",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = PANDORA_WIFI_NRESET_GPIO,
+ .startup_delay = 50000, /* 50ms */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &pandora_vmmc3,
+};
+
+static struct platform_device pandora_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &pandora_vwlan,
+ },
+};
+
+static struct twl4030_usb_data omap3pandora_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data omap3pandora_audio_data;
+
+static struct twl4030_codec_data omap3pandora_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &omap3pandora_audio_data,
+};
+
+static struct twl4030_bci_platform_data pandora_bci_data;
+
+static struct twl4030_platform_data omap3pandora_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+ .gpio = &omap3pandora_gpio_data,
+ .usb = &omap3pandora_usb_data,
+ .codec = &omap3pandora_codec_data,
+ .vmmc1 = &pandora_vmmc1,
+ .vmmc2 = &pandora_vmmc2,
+ .vdac = &pandora_vdac,
+ .vpll2 = &pandora_vpll2,
+ .vaux1 = &pandora_vaux1,
+ .vaux2 = &pandora_vaux2,
+ .vaux4 = &pandora_vaux4,
+ .vsim = &pandora_vsim,
+ .keypad = &pandora_kp_data,
+ .bci = &pandora_bci_data,
+};
+
+static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("bq27500", 0x55),
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+static int __init omap3pandora_i2c_init(void)
+{
+ omap3_pmic_init("tps65950", &omap3pandora_twldata);
+ /* i2c2 pins are not connected */
+ omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
+ ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
+ return 0;
+}
+
+static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
+ {
+ .modalias = "tpo_td043mtea1_panel_spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 375000,
+ .platform_data = &pandora_lcd_device,
+ }
+};
+
+static void __init omap3pandora_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+static void __init pandora_wl1251_init(void)
+{
+ struct wl12xx_platform_data pandora_wl1251_pdata;
+ int ret;
+
+ memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+
+ ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
+ if (ret < 0)
+ goto fail;
+
+ pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
+ if (pandora_wl1251_pdata.irq < 0)
+ goto fail_irq;
+
+ pandora_wl1251_pdata.use_eeprom = true;
+ ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+ if (ret < 0)
+ goto fail_irq;
+
+ return;
+
+fail_irq:
+ gpio_free(PANDORA_WIFI_IRQ_GPIO);
+fail:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+}
+
+static struct platform_device *omap3pandora_devices[] __initdata = {
+ &pandora_leds_gpio,
+ &pandora_keys_gpio,
+ &pandora_vwlan_device,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = 16,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap3pandora_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap3pandora_i2c_init();
+ pandora_wl1251_init();
+ platform_add_devices(omap3pandora_devices,
+ ARRAY_SIZE(omap3pandora_devices));
+ omap_display_init(&pandora_dss_data);
+ omap_serial_init();
+ spi_register_board_info(omap3pandora_spi_board_info,
+ ARRAY_SIZE(omap3pandora_spi_board_info));
+ omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
+ usbhs_init(&usbhs_bdata);
+ usb_musb_init(NULL);
+ gpmc_nand_init(&pandora_nand_data);
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3pandora_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap3pandora_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
new file mode 100644
index 00000000..0c108a21
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -0,0 +1,564 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3evm.c
+ *
+ * Copyright (C) 2008 Guangzhou EMA-Tech
+ *
+ * Modified from mach-omap2/board-omap3evm.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+
+#include <plat/mcspi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c/at24.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "common-board-devices.h"
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <plat/gpmc-smsc911x.h>
+
+#define OMAP3STALKER_ETHR_START 0x2c000000
+#define OMAP3STALKER_ETHR_SIZE 1024
+#define OMAP3STALKER_ETHR_GPIO_IRQ 19
+#define OMAP3STALKER_SMC911X_CS 5
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .cs = OMAP3STALKER_SMC911X_CS,
+ .gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ,
+ .gpio_reset = -EINVAL,
+ .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
+};
+
+static inline void __init omap3stalker_init_eth(void)
+{
+ struct clk *l3ck;
+ unsigned int rate;
+
+ l3ck = clk_get(NULL, "l3_ck");
+ if (IS_ERR(l3ck))
+ rate = 100000000;
+ else
+ rate = clk_get_rate(l3ck);
+
+ omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
+ gpmc_smsc911x_init(&smsc911x_cfg);
+}
+
+#else
+static inline void __init omap3stalker_init_eth(void)
+{
+ return;
+}
+#endif
+
+/*
+ * OMAP3 DSS control signals
+ */
+
+#define DSS_ENABLE_GPIO 199
+#define LCD_PANEL_BKLIGHT_GPIO 210
+#define ENABLE_VPLL2_DEV_GRP 0xE0
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_stalker_display_init(void)
+{
+ return;
+}
+
+static int omap3_stalker_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(DSS_ENABLE_GPIO, 1);
+ gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 1);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(DSS_ENABLE_GPIO, 0);
+ gpio_set_value(LCD_PANEL_BKLIGHT_GPIO, 0);
+ lcd_enabled = 0;
+}
+
+static struct panel_generic_dpi_data lcd_panel = {
+ .name = "generic",
+ .platform_enable = omap3_stalker_enable_lcd,
+ .platform_disable = omap3_stalker_disable_lcd,
+};
+
+static struct omap_dss_device omap3_stalker_lcd_device = {
+ .name = "lcd",
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd_panel,
+ .phy.dpi.data_lines = 24,
+ .type = OMAP_DISPLAY_TYPE_DPI,
+};
+
+static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void omap3_stalker_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_stalker_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+#if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO)
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+#elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE)
+ .u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+#endif
+ .platform_enable = omap3_stalker_enable_tv,
+ .platform_disable = omap3_stalker_disable_tv,
+};
+
+static int omap3_stalker_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ gpio_set_value(DSS_ENABLE_GPIO, 1);
+ dvi_enabled = 1;
+ return 0;
+}
+
+static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(DSS_ENABLE_GPIO, 0);
+ dvi_enabled = 0;
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = omap3_stalker_enable_dvi,
+ .platform_disable = omap3_stalker_disable_dvi,
+};
+
+static struct omap_dss_device omap3_stalker_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device *omap3_stalker_dss_devices[] = {
+ &omap3_stalker_lcd_device,
+ &omap3_stalker_tv_device,
+ &omap3_stalker_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_stalker_dss_data = {
+ .num_devices = ARRAY_SIZE(omap3_stalker_dss_devices),
+ .devices = omap3_stalker_dss_devices,
+ .default_device = &omap3_stalker_dvi_device,
+};
+
+static struct regulator_consumer_supply omap3stalker_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply omap3stalker_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3stalker_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3stalker_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3stalker_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3stalker_vsim_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 23,
+ },
+ {} /* Terminator */
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 18,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "stalker:D8:usr0",
+ .default_trigger = "default-on",
+ .gpio = 126,
+ },
+ {
+ .name = "stalker:D9:usr1",
+ .default_trigger = "default-on",
+ .gpio = 127,
+ },
+ {
+ .name = "stalker:D3:mmc0",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ .default_trigger = "mmc0",
+ },
+ {
+ .name = "stalker:D4:heartbeat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ .default_trigger = "heartbeat",
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static int
+omap3stalker_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters */
+ omap3stalker_vmmc1_supply.dev = mmc[0].dev;
+ omap3stalker_vsim_supply.dev = mmc[0].dev;
+
+ /*
+ * Most GPIOs are for USB OTG. Some are mostly sent to
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+ "EN_LCD_BKL");
+
+ /* gpio + 7 == DVI Enable */
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+ /* GPIO + 13 == ledsync (out, heartbeat) */
+ gpio_leds[3].gpio = gpio + 13;
+
+ platform_device_register(&leds_gpio);
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data omap3stalker_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = omap3stalker_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data omap3stalker_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_LEFT),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_ENTER),
+ KEY(0, 3, KEY_M),
+
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_UP),
+ KEY(1, 2, KEY_I),
+ KEY(1, 3, KEY_N),
+
+ KEY(2, 0, KEY_A),
+ KEY(2, 1, KEY_E),
+ KEY(2, 2, KEY_J),
+ KEY(2, 3, KEY_O),
+
+ KEY(3, 0, KEY_B),
+ KEY(3, 1, KEY_F),
+ KEY(3, 2, KEY_K),
+ KEY(3, 3, KEY_P)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data omap3stalker_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 4,
+ .cols = 4,
+ .rep = 1,
+};
+
+static struct twl4030_madc_platform_data omap3stalker_madc_data = {
+ .irq_line = 1,
+};
+
+static struct twl4030_codec_audio_data omap3stalker_audio_data;
+
+static struct twl4030_codec_data omap3stalker_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &omap3stalker_audio_data,
+};
+
+static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data omap3_stalker_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap3_stalker_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_init_data omap3_stalker_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies),
+ .consumer_supplies = omap3_stalker_vpll2_supplies,
+};
+
+static struct twl4030_platform_data omap3stalker_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .keypad = &omap3stalker_kp_data,
+ .madc = &omap3stalker_madc_data,
+ .usb = &omap3stalker_usb_data,
+ .gpio = &omap3stalker_gpio_data,
+ .codec = &omap3stalker_codec_data,
+ .vdac = &omap3_stalker_vdac,
+ .vpll2 = &omap3_stalker_vpll2,
+ .vmmc1 = &omap3stalker_vmmc1,
+ .vsim = &omap3stalker_vsim,
+};
+
+static struct at24_platform_data fram_info = {
+ .byte_len = (64 * 1024) / 8,
+ .page_size = 8192,
+ .flags = AT24_FLAG_ADDR16 | AT24_FLAG_IRUGO,
+};
+
+static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = {
+ {
+ I2C_BOARD_INFO("24c64", 0x50),
+ .flags = I2C_CLIENT_WAKE,
+ .platform_data = &fram_info,
+ },
+};
+
+static int __init omap3_stalker_i2c_init(void)
+{
+ omap3_pmic_init("twl4030", &omap3stalker_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3,
+ ARRAY_SIZE(omap3stalker_i2c_boardinfo3));
+ return 0;
+}
+
+#define OMAP3_STALKER_TS_GPIO 175
+
+static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
+};
+
+static void __init omap3_stalker_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
+}
+
+static void __init omap3_stalker_init_irq(void)
+{
+ omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+ omap2_gp_clockevent_set_gptimer(12);
+#endif
+}
+
+static struct platform_device *omap3_stalker_devices[] __initdata = {
+ &keys_gpio,
+};
+
+static struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 21,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+ {.reg_offset = OMAP_MUX_TERMINATOR},
+};
+#endif
+
+static void __init omap3_stalker_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
+ omap_board_config = omap3_stalker_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
+
+ omap3_stalker_i2c_init();
+
+ platform_add_devices(omap3_stalker_devices,
+ ARRAY_SIZE(omap3_stalker_devices));
+
+ omap_display_init(&omap3_stalker_dss_data);
+
+ omap_serial_init();
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
+
+ omap_mux_init_gpio(21, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
+
+ omap3stalker_init_eth();
+ omap3_stalker_display_init();
+/* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(SBC3530, "OMAP3 STALKER")
+ /* Maintainer: Jason Lam -lzg@ema-tech.com */
+ .boot_params = 0x80000100,
+ .map_io = omap3_map_io,
+ .init_early = omap3_stalker_init_early,
+ .init_irq = omap3_stalker_init_irq,
+ .init_machine = omap3_stalker_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
new file mode 100644
index 00000000..5f649faf
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -0,0 +1,453 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3touchbook.c
+ *
+ * Copyright (C) 2009 Always Innovating
+ *
+ * Modified from mach-omap2/board-omap3beagleboard.c
+ *
+ * Initial code: Grégoire Gentil, Tim Yamin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mmc/host.h>
+
+#include <plat/mcspi.h>
+#include <linux/spi/spi.h>
+
+#include <linux/spi/ads7846.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/gpmc.h>
+#include <plat/nand.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "timer-gp.h"
+#include "common-board-devices.h"
+
+#include <asm/setup.h>
+
+#define OMAP3_AC_GPIO 136
+#define OMAP3_TS_GPIO 162
+#define TB_BL_PWM_TIMER 9
+#define TB_KILL_POWER_GPIO 168
+
+static unsigned long touchbook_revision;
+
+static struct mtd_partition omap3touchbook_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = 29,
+ },
+ {} /* Terminator */
+};
+
+static struct platform_device omap3_touchbook_lcd_device = {
+ .name = "omap3touchbook_lcd",
+ .id = -1,
+};
+
+static struct omap_lcd_config omap3_touchbook_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct regulator_consumer_supply touchbook_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply touchbook_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct gpio_led gpio_leds[];
+
+static int touchbook_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ if (system_rev >= 0x20 && system_rev <= 0x34301000) {
+ omap_mux_init_gpio(23, OMAP_PIN_INPUT);
+ mmc[0].gpio_wp = 23;
+ } else {
+ omap_mux_init_gpio(29, OMAP_PIN_INPUT);
+ }
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters */
+ touchbook_vmmc1_supply.dev = mmc[0].dev;
+ touchbook_vsim_supply.dev = mmc[0].dev;
+
+ /* REVISIT: need ehci-omap hooks for external VBUS
+ * power switch and overcurrent detect
+ */
+ gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC");
+
+ /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+ gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+ "nEN_USB_PWR");
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data touchbook_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .pullups = BIT(1),
+ .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+ | BIT(15) | BIT(16) | BIT(17),
+ .setup = touchbook_twl_gpio_setup,
+};
+
+static struct regulator_consumer_supply touchbook_vdac_supply = {
+ .supply = "vdac",
+ .dev = &omap3_touchbook_lcd_device.dev,
+};
+
+static struct regulator_consumer_supply touchbook_vdvi_supply = {
+ .supply = "vdvi",
+ .dev = &omap3_touchbook_lcd_device.dev,
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data touchbook_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &touchbook_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data touchbook_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &touchbook_vsim_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data touchbook_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &touchbook_vdac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data touchbook_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &touchbook_vdvi_supply,
+};
+
+static struct twl4030_usb_data touchbook_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_codec_audio_data touchbook_audio_data;
+
+static struct twl4030_codec_data touchbook_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &touchbook_audio_data,
+};
+
+static struct twl4030_platform_data touchbook_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .usb = &touchbook_usb_data,
+ .gpio = &touchbook_gpio_data,
+ .codec = &touchbook_codec_data,
+ .vmmc1 = &touchbook_vmmc1,
+ .vsim = &touchbook_vsim,
+ .vdac = &touchbook_vdac,
+ .vpll2 = &touchbook_vpll2,
+};
+
+static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("bq27200", 0x55),
+ },
+};
+
+static int __init omap3_touchbook_i2c_init(void)
+{
+ /* Standard TouchBook bus */
+ omap3_pmic_init("twl4030", &touchbook_twldata);
+
+ /* Additional TouchBook bus */
+ omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
+ ARRAY_SIZE(touchBook_i2c_boardinfo));
+
+ return 0;
+}
+
+static struct ads7846_platform_data ads7846_pdata = {
+ .x_min = 100,
+ .y_min = 265,
+ .x_max = 3950,
+ .y_max = 3750,
+ .x_plate_ohms = 40,
+ .pressure_max = 255,
+ .debounce_max = 10,
+ .debounce_tol = 5,
+ .debounce_rep = 1,
+ .gpio_pendown = OMAP3_TS_GPIO,
+ .keep_vref_on = 1,
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "touchbook::usr0",
+ .default_trigger = "heartbeat",
+ .gpio = 150,
+ },
+ {
+ .name = "touchbook::usr1",
+ .default_trigger = "mmc0",
+ .gpio = 149,
+ },
+ {
+ .name = "touchbook::pmu_stat",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 7,
+ .desc = "user",
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_POWER,
+ .gpio = 183,
+ .desc = "power",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
+ { OMAP_TAG_LCD, &omap3_touchbook_lcd_config },
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init omap3_touchbook_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+static void __init omap3_touchbook_init_irq(void)
+{
+ omap_init_irq();
+#ifdef CONFIG_OMAP_32K_TIMER
+ omap2_gp_clockevent_set_gptimer(12);
+#endif
+}
+
+static struct platform_device *omap3_touchbook_devices[] __initdata = {
+ &omap3_touchbook_lcd_device,
+ &leds_gpio,
+ &keys_gpio,
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 147,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static void omap3_touchbook_poweroff(void)
+{
+ int pwr_off = TB_KILL_POWER_GPIO;
+
+ if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0)
+ printk(KERN_ERR "Unable to get kill power GPIO\n");
+}
+
+static int __init early_touchbook_revision(char *p)
+{
+ if (!p)
+ return 0;
+
+ return strict_strtoul(p, 10, &touchbook_revision);
+}
+early_param("tbr", early_touchbook_revision);
+
+static void __init omap3_touchbook_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = omap3_touchbook_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
+
+ pm_power_off = omap3_touchbook_poweroff;
+
+ omap3_touchbook_i2c_init();
+ platform_add_devices(omap3_touchbook_devices,
+ ARRAY_SIZE(omap3_touchbook_devices));
+ omap_serial_init();
+
+ omap_mux_init_gpio(170, OMAP_PIN_INPUT);
+ /* REVISIT leave DVI powered down until it's needed ... */
+ gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
+
+ /* Touchscreen and accelerometer */
+ omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions,
+ ARRAY_SIZE(omap3touchbook_nand_partitions));
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+}
+
+MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
+ /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3_touchbook_init_early,
+ .init_irq = omap3_touchbook_init_irq,
+ .init_machine = omap3_touchbook_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
new file mode 100644
index 00000000..107dfc37
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -0,0 +1,726 @@
+/*
+ * Board support file for OMAP4430 based PandaBoard.
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * Author: David Anders <x0132446@ti.com>
+ *
+ * Based on mach-omap2/board-4430sdp.c
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <video/omapdss.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/usb.h>
+#include <plat/mmc.h>
+#include <video/omap-panel-generic-dpi.h>
+#include "timer-gp.h"
+
+#include "hsmmc.h"
+#include "control.h"
+#include "mux.h"
+#include "common-board-devices.h"
+
+#define GPIO_HUB_POWER 1
+#define GPIO_HUB_NRESET 62
+#define GPIO_WIFI_PMENA 43
+#define GPIO_WIFI_IRQ 53
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
+
+/* wl127x BT, FM, GPS connectivity chip */
+static int wl1271_gpios[] = {46, -1, -1};
+static struct platform_device wl1271_device = {
+ .name = "kim",
+ .id = -1,
+ .dev = {
+ .platform_data = &wl1271_gpios,
+ },
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "pandaboard::status1",
+ .default_trigger = "heartbeat",
+ .gpio = 7,
+ },
+ {
+ .name = "pandaboard::status2",
+ .default_trigger = "mmc0",
+ .gpio = 8,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct platform_device *panda_devices[] __initdata = {
+ &leds_gpio,
+ &wl1271_device,
+};
+
+static void __init omap4_panda_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = false,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = -EINVAL,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+static struct gpio panda_ehci_gpios[] __initdata = {
+ { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" },
+ { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" },
+};
+
+static void __init omap4_ehci_init(void)
+{
+ int ret;
+ struct clk *phy_ref_clk;
+
+ /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
+ phy_ref_clk = clk_get(NULL, "auxclk3_ck");
+ if (IS_ERR(phy_ref_clk)) {
+ pr_err("Cannot request auxclk3\n");
+ return;
+ }
+ clk_set_rate(phy_ref_clk, 19200000);
+ clk_enable(phy_ref_clk);
+
+ /* disable the power to the usb hub prior to init and reset phy+hub */
+ ret = gpio_request_array(panda_ehci_gpios,
+ ARRAY_SIZE(panda_ehci_gpios));
+ if (ret) {
+ pr_err("Unable to initialize EHCI power/reset\n");
+ return;
+ }
+
+ gpio_export(GPIO_HUB_POWER, 0);
+ gpio_export(GPIO_HUB_NRESET, 0);
+ gpio_set_value(GPIO_HUB_NRESET, 1);
+
+ usbhs_init(&usbhs_bdata);
+
+ /* enable power to hub */
+ gpio_set_value(GPIO_HUB_POWER, 1);
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_UTMI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+static struct twl4030_usb_data omap4_usbphy_data = {
+ .phy_init = omap4430_phy_init,
+ .phy_exit = omap4430_phy_exit,
+ .phy_power = omap4430_phy_power,
+ .phy_set_clock = omap4430_phy_set_clk,
+ .phy_suspend = omap4430_phy_suspend,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 5,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .ocr_mask = MMC_VDD_165_195,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
+ {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.0",
+ },
+};
+
+static struct regulator_consumer_supply omap4_panda_vmmc5_supply = {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.4",
+};
+
+static struct regulator_init_data panda_vmmc5 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &omap4_panda_vmmc5_supply,
+};
+
+static struct fixed_voltage_config panda_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = GPIO_WIFI_PMENA,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &panda_vmmc5,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &panda_vwlan,
+ },
+};
+
+struct wl12xx_platform_data omap_panda_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ),
+ /* PANDA ref clock is 38.4 MHz */
+ .board_ref_clock = 2,
+};
+
+static int omap4_twl6030_hsmmc_late_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ if (!pdata) {
+ dev_err(dev, "%s: NULL platform data\n", __func__);
+ return -EINVAL;
+ }
+ /* Setting MMC1 Card detect Irq */
+ if (pdev->id == 0) {
+ ret = twl6030_mmc_card_detect_config();
+ if (ret)
+ dev_err(dev, "%s: Error card detect config(%d)\n",
+ __func__, ret);
+ else
+ pdata->slots[0].card_detect = twl6030_mmc_card_detect;
+ }
+ return ret;
+}
+
+static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
+{
+ struct omap_mmc_platform_data *pdata;
+
+ /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+ if (!dev) {
+ pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
+ return;
+ }
+ pdata = dev->platform_data;
+
+ pdata->init = omap4_twl6030_hsmmc_late_init;
+}
+
+static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ struct omap2_hsmmc_info *c;
+
+ omap2_hsmmc_init(controllers);
+ for (c = controllers; c->mmc; c++)
+ omap4_twl6030_hsmmc_set_late_init(c->dev);
+
+ return 0;
+}
+
+static struct regulator_init_data omap4_panda_vaux2 = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vaux3 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for MMC1 card */
+static struct regulator_init_data omap4_panda_vmmc = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = omap4_panda_vmmc_supply,
+};
+
+static struct regulator_init_data omap4_panda_vpp = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 2500000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vana = {
+ .constraints = {
+ .min_uV = 2100000,
+ .max_uV = 2100000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vcxio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vusb = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_clk32kg = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct twl4030_platform_data omap4_panda_twldata = {
+ .irq_base = TWL6030_IRQ_BASE,
+ .irq_end = TWL6030_IRQ_END,
+
+ /* Regulators */
+ .vmmc = &omap4_panda_vmmc,
+ .vpp = &omap4_panda_vpp,
+ .vana = &omap4_panda_vana,
+ .vcxio = &omap4_panda_vcxio,
+ .vdac = &omap4_panda_vdac,
+ .vusb = &omap4_panda_vusb,
+ .vaux2 = &omap4_panda_vaux2,
+ .vaux3 = &omap4_panda_vaux3,
+ .clk32kg = &omap4_panda_clk32kg,
+ .usb = &omap4_usbphy_data,
+};
+
+/*
+ * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
+ * is connected as I2C slave device, and can be accessed at address 0x50
+ */
+static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
+static int __init omap4_panda_i2c_init(void)
+{
+ omap4_pmic_init("twl6030", &omap4_panda_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ /*
+ * Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz
+ */
+ omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
+ ARRAY_SIZE(panda_i2c_eeprom));
+ omap_register_i2c_bus(4, 400, NULL, 0);
+ return 0;
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 53 */
+ OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
+ /* WLAN POWER ENABLE - GPIO 43 */
+ OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC5 CMD */
+ OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC5 CLK */
+ OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC5 DAT[0-3] */
+ OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+ /* gpio 0 - TFP410 PD */
+ OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
+ /* dispc2_data23 */
+ OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data22 */
+ OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data21 */
+ OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data20 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data19 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data18 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data15 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data14 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data13 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data12 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data11 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data10 */
+ OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data9 */
+ OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data16 */
+ OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data17 */
+ OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_hsync */
+ OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_pclk */
+ OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_vsync */
+ OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_de */
+ OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data8 */
+ OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data7 */
+ OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data6 */
+ OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data5 */
+ OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data4 */
+ OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data3 */
+ OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data2 */
+ OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data1 */
+ OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data0 */
+ OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_device_pad serial2_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart2_cts.uart2_cts",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rts.uart2_rts",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_rx.uart2_rx",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart2_tx.uart2_tx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial3_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
+ OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
+ OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_device_pad serial4_pads[] __initdata = {
+ OMAP_MUX_STATIC("uart4_rx.uart4_rx",
+ OMAP_PIN_INPUT | OMAP_MUX_MODE0),
+ OMAP_MUX_STATIC("uart4_tx.uart4_tx",
+ OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
+};
+
+static struct omap_board_data serial2_data __initdata = {
+ .id = 1,
+ .pads = serial2_pads,
+ .pads_cnt = ARRAY_SIZE(serial2_pads),
+};
+
+static struct omap_board_data serial3_data __initdata = {
+ .id = 2,
+ .pads = serial3_pads,
+ .pads_cnt = ARRAY_SIZE(serial3_pads),
+};
+
+static struct omap_board_data serial4_data __initdata = {
+ .id = 3,
+ .pads = serial4_pads,
+ .pads_cnt = ARRAY_SIZE(serial4_pads),
+};
+
+static inline void board_serial_init(void)
+{
+ struct omap_board_data bdata;
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+ bdata.id = 0;
+ /* pass dummy data for UART1 */
+ omap_serial_init_port(&bdata);
+
+ omap_serial_init_port(&serial2_data);
+ omap_serial_init_port(&serial3_data);
+ omap_serial_init_port(&serial4_data);
+}
+#else
+#define board_mux NULL
+
+static inline void board_serial_init(void)
+{
+ omap_serial_init();
+}
+#endif
+
+/* Display DVI */
+#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
+
+static int omap4_panda_enable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void omap4_panda_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+/* Using generic display panel */
+static struct panel_generic_dpi_data omap4_dvi_panel = {
+ .name = "generic",
+ .platform_enable = omap4_panda_enable_dvi,
+ .platform_disable = omap4_panda_disable_dvi,
+};
+
+struct omap_dss_device omap4_panda_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &omap4_dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+};
+
+int __init omap4_panda_dvi_init(void)
+{
+ int r;
+
+ /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
+ r = gpio_request_one(omap4_panda_dvi_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "DVI PD");
+ if (r)
+ pr_err("Failed to get DVI powerdown GPIO\n");
+
+ return r;
+}
+
+
+static void omap4_panda_hdmi_mux_init(void)
+{
+ omap_mux_init_signal("hdmi_cec",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_ddc_scl",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_ddc_sda",
+ OMAP_PIN_INPUT_PULLUP);
+}
+
+static struct gpio panda_hdmi_gpios[] = {
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
+ { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
+};
+
+static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+ int status;
+
+ status = gpio_request_array(panda_hdmi_gpios,
+ ARRAY_SIZE(panda_hdmi_gpios));
+ if (status)
+ pr_err("Cannot request HDMI GPIOs\n");
+
+ return status;
+}
+
+static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+ gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
+}
+
+static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
+static struct omap_dss_device omap4_panda_hdmi_device = {
+ .name = "hdmi",
+ .driver_name = "hdmi_panel",
+ .type = OMAP_DISPLAY_TYPE_HDMI,
+ .platform_enable = omap4_panda_panel_enable_hdmi,
+ .platform_disable = omap4_panda_panel_disable_hdmi,
+ .channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &omap4_panda_hdmi_data,
+};
+
+static struct omap_dss_device *omap4_panda_dss_devices[] = {
+ &omap4_panda_dvi_device,
+ &omap4_panda_hdmi_device,
+};
+
+static struct omap_dss_board_info omap4_panda_dss_data = {
+ .num_devices = ARRAY_SIZE(omap4_panda_dss_devices),
+ .devices = omap4_panda_dss_devices,
+ .default_device = &omap4_panda_dvi_device,
+};
+
+void omap4_panda_display_init(void)
+{
+ int r;
+
+ r = omap4_panda_dvi_init();
+ if (r)
+ pr_err("error initializing panda DVI\n");
+
+ omap4_panda_hdmi_mux_init();
+ omap_display_init(&omap4_panda_dss_data);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
+}
+
+static void __init omap4_panda_init(void)
+{
+ int package = OMAP_PACKAGE_CBS;
+
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ package = OMAP_PACKAGE_CBL;
+ omap4_mux_init(board_mux, NULL, package);
+
+ if (wl12xx_set_platform_data(&omap_panda_wlan_data))
+ pr_err("error setting wl12xx data\n");
+
+ omap4_panda_i2c_init();
+ platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
+ platform_device_register(&omap_vwlan_device);
+ board_serial_init();
+ omap4_twl6030_hsmmc_init(mmc);
+ omap4_ehci_init();
+ usb_musb_init(&musb_board_data);
+ omap4_panda_display_init();
+}
+
+static void __init omap4_panda_map_io(void)
+{
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+}
+
+MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
+ /* Maintainer: David Anders - Texas Instruments Inc */
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap4_panda_map_io,
+ .init_early = omap4_panda_init_early,
+ .init_irq = gic_init_irq,
+ .init_machine = omap4_panda_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
new file mode 100644
index 00000000..175e1ab2
--- /dev/null
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -0,0 +1,621 @@
+/*
+ * board-overo.c (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
+#include <plat/gpmc.h>
+#include <mach/hardware.h>
+#include <plat/nand.h>
+#include <plat/mcspi.h>
+#include <plat/mux.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OVERO_GPIO_BT_XGATE 15
+#define OVERO_GPIO_W2W_NRESET 16
+#define OVERO_GPIO_PENDOWN 114
+#define OVERO_GPIO_BT_NRESET 164
+#define OVERO_GPIO_USBH_CPEN 168
+#define OVERO_GPIO_USBH_NRESET 183
+
+#define OVERO_SMSC911X_CS 5
+#define OVERO_SMSC911X_GPIO 176
+#define OVERO_SMSC911X2_CS 4
+#define OVERO_SMSC911X2_GPIO 65
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+
+/* fixed regulator for ads7846 */
+static struct regulator_consumer_supply ads7846_supply =
+ REGULATOR_SUPPLY("vcc", "spi1.0");
+
+static struct regulator_init_data vads7846_regulator = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ads7846_supply,
+};
+
+static struct fixed_voltage_config vads7846 = {
+ .supply_name = "vads7846",
+ .microvolts = 3300000, /* 3.3V */
+ .gpio = -EINVAL,
+ .startup_delay = 0,
+ .init_data = &vads7846_regulator,
+};
+
+static struct platform_device vads7846_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &vads7846,
+ },
+};
+
+static void __init overo_ads7846_init(void)
+{
+ omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL);
+ platform_device_register(&vads7846_device);
+}
+
+#else
+static inline void __init overo_ads7846_init(void) { return; }
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+#include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+ .id = 0,
+ .cs = OVERO_SMSC911X_CS,
+ .gpio_irq = OVERO_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct omap_smsc911x_platform_data smsc911x2_cfg = {
+ .id = 1,
+ .cs = OVERO_SMSC911X2_CS,
+ .gpio_irq = OVERO_SMSC911X2_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static void __init overo_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&smsc911x_cfg);
+ gpmc_smsc911x_init(&smsc911x2_cfg);
+}
+
+#else
+static inline void __init overo_init_smsc911x(void) { return; }
+#endif
+
+/* DSS */
+static int lcd_enabled;
+static int dvi_enabled;
+
+#define OVERO_GPIO_LCD_EN 144
+#define OVERO_GPIO_LCD_BL 145
+
+static struct gpio overo_dss_gpios[] __initdata = {
+ { OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" },
+ { OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" },
+};
+
+static void __init overo_display_init(void)
+{
+ if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) {
+ printk(KERN_ERR "could not obtain DSS control GPIOs\n");
+ return;
+ }
+
+ gpio_export(OVERO_GPIO_LCD_EN, 0);
+ gpio_export(OVERO_GPIO_LCD_BL, 0);
+}
+
+static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = overo_panel_enable_dvi,
+ .platform_disable = overo_panel_disable_dvi,
+};
+
+static struct omap_dss_device overo_dvi_device = {
+ .name = "dvi",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+static struct omap_dss_device overo_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(OVERO_GPIO_LCD_EN, 1);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 1);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OVERO_GPIO_LCD_EN, 0);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 0);
+ lcd_enabled = 0;
+}
+
+static struct panel_generic_dpi_data lcd43_panel = {
+ .name = "samsung_lte430wq_f0c",
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+
+static struct omap_dss_device overo_lcd43_device = {
+ .name = "lcd43",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .driver_name = "generic_dpi_panel",
+ .data = &lcd43_panel,
+ .phy.dpi.data_lines = 24,
+};
+
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+static struct omap_dss_device overo_lcd35_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd35",
+ .driver_name = "lgphilips_lb035q02_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+static struct omap_dss_device *overo_dss_devices[] = {
+ &overo_dvi_device,
+ &overo_tv_device,
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ &overo_lcd35_device,
+#endif
+ &overo_lcd43_device,
+};
+
+static struct omap_dss_board_info overo_dss_data = {
+ .num_devices = ARRAY_SIZE(overo_dss_devices),
+ .devices = overo_dss_devices,
+ .default_device = &overo_dvi_device,
+};
+
+static struct regulator_consumer_supply overo_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static struct regulator_consumer_supply overo_vdds_dsi_supply[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct mtd_partition overo_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 14 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x240000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ {
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .transceiver = true,
+ .ocr_mask = 0x00100000, /* 3.3V */
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply overo_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#include <linux/leds.h>
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "overo:red:gpio21",
+ .default_trigger = "heartbeat",
+ .gpio = 21,
+ .active_low = true,
+ },
+ {
+ .name = "overo:blue:gpio22",
+ .default_trigger = "none",
+ .gpio = 22,
+ .active_low = true,
+ },
+ {
+ .name = "overo:blue:COM",
+ .default_trigger = "mmc0",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_leds_pdata = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device gpio_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_leds_pdata,
+ },
+};
+
+static void __init overo_init_led(void)
+{
+ platform_device_register(&gpio_leds_device);
+}
+
+#else
+static inline void __init overo_init_led(void) { return; }
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_0,
+ .gpio = 23,
+ .desc = "button0",
+ .wakeup = 1,
+ },
+ {
+ .code = BTN_1,
+ .gpio = 14,
+ .desc = "button1",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_keys_pdata = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_keys_pdata,
+ },
+};
+
+static void __init overo_init_keys(void)
+{
+ platform_device_register(&gpio_keys_device);
+}
+
+#else
+static inline void __init overo_init_keys(void) { return; }
+#endif
+
+static int overo_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ omap2_hsmmc_init(mmc);
+
+ overo_vmmc1_supply.dev = mmc[0].dev;
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+#endif
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data overo_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .use_leds = true,
+ .setup = overo_twl_gpio_setup,
+};
+
+static struct twl4030_usb_data overo_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct regulator_init_data overo_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &overo_vmmc1_supply,
+};
+
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data overo_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &overo_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data overo_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(overo_vdds_dsi_supply),
+ .consumer_supplies = overo_vdds_dsi_supply,
+};
+
+static struct twl4030_codec_audio_data overo_audio_data;
+
+static struct twl4030_codec_data overo_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &overo_audio_data,
+};
+
+static struct twl4030_platform_data overo_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+ .gpio = &overo_gpio_data,
+ .usb = &overo_usb_data,
+ .codec = &overo_codec_data,
+ .vmmc1 = &overo_vmmc1,
+ .vdac = &overo_vdac,
+ .vpll2 = &overo_vpll2,
+};
+
+static int __init overo_i2c_init(void)
+{
+ omap3_pmic_init("tps65950", &overo_twldata);
+ /* i2c2 pins are used for gpio */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ {
+ .modalias = "lgphilips_lb035q02_panel-spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 500000,
+ .mode = SPI_MODE_3,
+ },
+#endif
+};
+
+static int __init overo_spi_init(void)
+{
+ overo_ads7846_init();
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ return 0;
+}
+
+static void __init overo_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+}
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct gpio overo_bt_gpios[] __initdata = {
+ { OVERO_GPIO_BT_XGATE, GPIOF_OUT_INIT_LOW, "lcd enable" },
+ { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
+};
+
+static void __init overo_init(void)
+{
+ int ret;
+
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ overo_i2c_init();
+ omap_display_init(&overo_dss_data);
+ omap_serial_init();
+ omap_nand_flash_init(0, overo_nand_partitions,
+ ARRAY_SIZE(overo_nand_partitions));
+ usb_musb_init(NULL);
+ usbhs_init(&usbhs_bdata);
+ overo_spi_init();
+ overo_ads7846_init();
+ overo_init_smsc911x();
+ overo_display_init();
+ overo_init_led();
+ overo_init_keys();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH,
+ "OVERO_GPIO_W2W_NRESET");
+ if (ret == 0) {
+ gpio_export(OVERO_GPIO_W2W_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
+ udelay(10);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_W2W_NRESET\n");
+ }
+
+ ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios));
+ if (ret) {
+ pr_err("%s: could not obtain BT gpios\n", __func__);
+ } else {
+ gpio_export(OVERO_GPIO_BT_XGATE, 0);
+ gpio_export(OVERO_GPIO_BT_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
+ mdelay(6);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
+ }
+
+ ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH,
+ "OVERO_GPIO_USBH_CPEN");
+ if (ret == 0)
+ gpio_export(OVERO_GPIO_USBH_CPEN, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_USBH_CPEN\n");
+}
+
+MACHINE_START(OVERO, "Gumstix Overo")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = overo_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = overo_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
new file mode 100644
index 00000000..42d10b12
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -0,0 +1,169 @@
+/*
+ * Board support file for Nokia RM-680.
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can 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/i2c.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/i2c/twl.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <plat/i2c.h>
+#include <plat/mmc.h>
+#include <plat/usb.h>
+#include <plat/gpmc.h>
+#include <plat/common.h>
+#include <plat/onenand.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "sdram-nokia.h"
+#include "common-board-devices.h"
+
+static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+/* Fixed regulator for internal eMMC */
+static struct regulator_init_data rm680_vemmc = {
+ .constraints = {
+ .name = "rm680_vemmc",
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS
+ | REGULATOR_CHANGE_MODE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers),
+ .consumer_supplies = rm680_vemmc_consumers,
+};
+
+static struct fixed_voltage_config rm680_vemmc_config = {
+ .supply_name = "VEMMC",
+ .microvolts = 2900000,
+ .gpio = 157,
+ .startup_delay = 150,
+ .enable_high = 1,
+ .init_data = &rm680_vemmc,
+};
+
+static struct platform_device rm680_vemmc_device = {
+ .name = "reg-fixed-voltage",
+ .dev = {
+ .platform_data = &rm680_vemmc_config,
+ },
+};
+
+static struct platform_device *rm680_peripherals_devices[] __initdata = {
+ &rm680_vemmc_device,
+};
+
+/* TWL */
+static struct twl4030_gpio_platform_data rm680_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pullups = BIT(0),
+ .pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15),
+};
+
+static struct twl4030_usb_data rm680_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_platform_data rm680_twl_data = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+ .gpio = &rm680_gpio_data,
+ .usb = &rm680_usb_data,
+ /* add rest of the children here */
+};
+
+static void __init rm680_i2c_init(void)
+{
+ omap_pmic_init(1, 2900, "twl5031", INT_34XX_SYS_NIRQ, &rm680_twl_data);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .gpio_irq = 65,
+ .flags = ONENAND_SYNC_READWRITE,
+ }
+};
+#endif
+
+/* eMMC */
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ },
+ { /* Terminator */ }
+};
+
+static void __init rm680_peripherals_init(void)
+{
+ platform_add_devices(rm680_peripherals_devices,
+ ARRAY_SIZE(rm680_peripherals_devices));
+ rm680_i2c_init();
+ gpmc_onenand_init(board_onenand_data);
+ omap2_hsmmc_init(mmc);
+}
+
+static void __init rm680_init_early(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap2_init_common_infrastructure();
+ sdrc_params = nokia_get_sdram_timings();
+ omap2_init_common_devices(sdrc_params, sdrc_params);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static void __init rm680_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_serial_init();
+ usb_musb_init(NULL);
+ rm680_peripherals_init();
+}
+
+static void __init rm680_map_io(void)
+{
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+}
+
+MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = rm680_map_io,
+ .init_early = rm680_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = rm680_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
new file mode 100644
index 00000000..c5659717
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -0,0 +1,990 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-peripherals.c
+ *
+ * Copyright (C) 2008-2009 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/spi/spi.h>
+#include <linux/wl12xx.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/mmc/host.h>
+#include <linux/power/isp1704_charger.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/onenand.h>
+#include <plat/gpmc-smc91x.h>
+
+#include <mach/board-rx51.h>
+
+#include <sound/tlv320aic3x.h>
+#include <sound/tpa6130a2-plat.h>
+#include <media/radio-si4713.h>
+#include <media/si4713.h>
+
+#include <../drivers/staging/iio/light/tsl2563.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define SYSTEM_REV_B_USES_VAUX3 0x1699
+#define SYSTEM_REV_S_USES_VAUX3 0x8
+
+#define RX51_WL1251_POWER_GPIO 87
+#define RX51_WL1251_IRQ_GPIO 42
+#define RX51_FMTX_RESET_GPIO 163
+#define RX51_FMTX_IRQ 53
+
+#define RX51_USB_TRANSCEIVER_RST_GPIO 67
+
+/* list all spi devices here */
+enum {
+ RX51_SPI_WL1251,
+ RX51_SPI_MIPID, /* LCD panel */
+ RX51_SPI_TSC2005, /* Touch Controller */
+};
+
+static struct wl12xx_platform_data wl1251_pdata;
+
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
+ .cover_comp_gain = 16,
+};
+#endif
+
+static struct omap2_mcspi_device_config wl1251_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config mipid_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1,
+};
+
+static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = {
+ [RX51_SPI_WL1251] = {
+ .modalias = "wl1251",
+ .bus_num = 4,
+ .chip_select = 0,
+ .max_speed_hz = 48000000,
+ .mode = SPI_MODE_3,
+ .controller_data = &wl1251_mcspi_config,
+ .platform_data = &wl1251_pdata,
+ },
+ [RX51_SPI_MIPID] = {
+ .modalias = "acx565akm",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 6000000,
+ .controller_data = &mipid_mcspi_config,
+ },
+ [RX51_SPI_TSC2005] = {
+ .modalias = "tsc2005",
+ .bus_num = 1,
+ .chip_select = 0,
+ /* .irq = OMAP_GPIO_IRQ(RX51_TSC2005_IRQ_GPIO),*/
+ .max_speed_hz = 6000000,
+ .controller_data = &tsc2005_mcspi_config,
+ /* .platform_data = &tsc2005_config,*/
+ },
+};
+
+static void rx51_charger_set_power(bool on)
+{
+ gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on);
+}
+
+static struct isp1704_charger_data rx51_charger_data = {
+ .set_power = rx51_charger_set_power,
+};
+
+static struct platform_device rx51_charger_device = {
+ .name = "isp1704_charger",
+ .dev = {
+ .platform_data = &rx51_charger_data,
+ },
+};
+
+static void __init rx51_charger_init(void)
+{
+ WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO,
+ GPIOF_OUT_INIT_HIGH, "isp1704_reset"));
+
+ platform_device_register(&rx51_charger_device);
+}
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+
+#define RX51_GPIO_CAMERA_LENS_COVER 110
+#define RX51_GPIO_CAMERA_FOCUS 68
+#define RX51_GPIO_CAMERA_CAPTURE 69
+#define RX51_GPIO_KEYPAD_SLIDE 71
+#define RX51_GPIO_LOCK_BUTTON 113
+#define RX51_GPIO_PROXIMITY 89
+
+#define RX51_GPIO_DEBOUNCE_TIMEOUT 10
+
+static struct gpio_keys_button rx51_gpio_keys[] = {
+ {
+ .desc = "Camera Lens Cover",
+ .type = EV_SW,
+ .code = SW_CAMERA_LENS_COVER,
+ .gpio = RX51_GPIO_CAMERA_LENS_COVER,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Camera Focus",
+ .type = EV_KEY,
+ .code = KEY_CAMERA_FOCUS,
+ .gpio = RX51_GPIO_CAMERA_FOCUS,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Camera Capture",
+ .type = EV_KEY,
+ .code = KEY_CAMERA,
+ .gpio = RX51_GPIO_CAMERA_CAPTURE,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Lock Button",
+ .type = EV_KEY,
+ .code = KEY_SCREENLOCK,
+ .gpio = RX51_GPIO_LOCK_BUTTON,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Keypad Slide",
+ .type = EV_SW,
+ .code = SW_KEYPAD_SLIDE,
+ .gpio = RX51_GPIO_KEYPAD_SLIDE,
+ .active_low = 1,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }, {
+ .desc = "Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .gpio = RX51_GPIO_PROXIMITY,
+ .active_low = 0,
+ .debounce_interval = RX51_GPIO_DEBOUNCE_TIMEOUT,
+ }
+};
+
+static struct gpio_keys_platform_data rx51_gpio_keys_data = {
+ .buttons = rx51_gpio_keys,
+ .nbuttons = ARRAY_SIZE(rx51_gpio_keys),
+};
+
+static struct platform_device rx51_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_gpio_keys_data,
+ },
+};
+
+static void __init rx51_add_gpio_keys(void)
+{
+ platform_device_register(&rx51_gpio_keys_device);
+}
+#else
+static void __init rx51_add_gpio_keys(void)
+{
+}
+#endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */
+
+static uint32_t board_keymap[] = {
+ /*
+ * Note that KEY(x, 8, KEY_XXX) entries represent "entrire row
+ * connected to the ground" matrix state.
+ */
+ KEY(0, 0, KEY_Q),
+ KEY(0, 1, KEY_O),
+ KEY(0, 2, KEY_P),
+ KEY(0, 3, KEY_COMMA),
+ KEY(0, 4, KEY_BACKSPACE),
+ KEY(0, 6, KEY_A),
+ KEY(0, 7, KEY_S),
+
+ KEY(1, 0, KEY_W),
+ KEY(1, 1, KEY_D),
+ KEY(1, 2, KEY_F),
+ KEY(1, 3, KEY_G),
+ KEY(1, 4, KEY_H),
+ KEY(1, 5, KEY_J),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_L),
+
+ KEY(2, 0, KEY_E),
+ KEY(2, 1, KEY_DOT),
+ KEY(2, 2, KEY_UP),
+ KEY(2, 3, KEY_ENTER),
+ KEY(2, 5, KEY_Z),
+ KEY(2, 6, KEY_X),
+ KEY(2, 7, KEY_C),
+ KEY(2, 8, KEY_F9),
+
+ KEY(3, 0, KEY_R),
+ KEY(3, 1, KEY_V),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_N),
+ KEY(3, 4, KEY_M),
+ KEY(3, 5, KEY_SPACE),
+ KEY(3, 6, KEY_SPACE),
+ KEY(3, 7, KEY_LEFT),
+
+ KEY(4, 0, KEY_T),
+ KEY(4, 1, KEY_DOWN),
+ KEY(4, 2, KEY_RIGHT),
+ KEY(4, 4, KEY_LEFTCTRL),
+ KEY(4, 5, KEY_RIGHTALT),
+ KEY(4, 6, KEY_LEFTSHIFT),
+ KEY(4, 8, KEY_F10),
+
+ KEY(5, 0, KEY_Y),
+ KEY(5, 8, KEY_F11),
+
+ KEY(6, 0, KEY_U),
+
+ KEY(7, 0, KEY_I),
+ KEY(7, 1, KEY_F7),
+ KEY(7, 2, KEY_F8),
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data rx51_kp_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 8,
+ .rep = 1,
+};
+
+static struct twl4030_madc_platform_data rx51_madc_data = {
+ .irq_line = 1,
+};
+
+/* Enable input logic and pull all lines up when eMMC is on. */
+static struct omap_board_mux rx51_mmc2_on_mux[] = {
+ OMAP3_MUX(SDMMC2_CMD, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/* Disable input logic and pull all lines down when eMMC is off. */
+static struct omap_board_mux rx51_mmc2_off_mux[] = {
+ OMAP3_MUX(SDMMC2_CMD, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT0, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT1, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT2, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT3, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT4, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT5, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT6, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ OMAP3_MUX(SDMMC2_DAT7, OMAP_PULL_ENA | OMAP_MUX_MODE0),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+static struct omap_mux_partition *partition;
+
+/*
+ * Current flows to eMMC when eMMC is off and the data lines are pulled up,
+ * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
+ */
+static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
+{
+ if (power_on)
+ omap_mux_write_array(partition, rx51_mmc2_on_mux);
+ else
+ omap_mux_write_array(partition, rx51_mmc2_off_mux);
+}
+
+static struct omap2_hsmmc_info mmc[] __initdata = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .cover_only = true,
+ .gpio_cd = 160,
+ .gpio_wp = -EINVAL,
+ .power_saving = true,
+ },
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ /* See also rx51_mmc2_remux */
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .power_saving = true,
+ .remux = rx51_mmc2_remux,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply rx51_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
+
+static struct regulator_consumer_supply rx51_vaux3_supply =
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
+
+static struct regulator_consumer_supply rx51_vsim_supply =
+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1");
+
+static struct regulator_consumer_supply rx51_vmmc2_supplies[] = {
+ /* tlv320aic3x analog supplies */
+ REGULATOR_SUPPLY("AVDD", "2-0018"),
+ REGULATOR_SUPPLY("DRVDD", "2-0018"),
+ REGULATOR_SUPPLY("AVDD", "2-0019"),
+ REGULATOR_SUPPLY("DRVDD", "2-0019"),
+ /* tpa6130a2 */
+ REGULATOR_SUPPLY("Vdd", "2-0060"),
+ /* Keep vmmc as last item. It is not iterated for newer boards */
+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
+};
+
+static struct regulator_consumer_supply rx51_vio_supplies[] = {
+ /* tlv320aic3x digital supplies */
+ REGULATOR_SUPPLY("IOVDD", "2-0018"),
+ REGULATOR_SUPPLY("DVDD", "2-0018"),
+ REGULATOR_SUPPLY("IOVDD", "2-0019"),
+ REGULATOR_SUPPLY("DVDD", "2-0019"),
+ /* Si4713 IO supply */
+ REGULATOR_SUPPLY("vio", "2-0063"),
+};
+
+static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ /* Si4713 supply */
+ REGULATOR_SUPPLY("vdd", "2-0063"),
+};
+
+static struct regulator_consumer_supply rx51_vdac_supply[] = {
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"),
+};
+
+static struct regulator_init_data rx51_vaux1 = {
+ .constraints = {
+ .name = "V28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .always_on = true, /* due battery cover sensor */
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vaux1_consumers),
+ .consumer_supplies = rx51_vaux1_consumers,
+};
+
+static struct regulator_init_data rx51_vaux2 = {
+ .constraints = {
+ .name = "VCSI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VAUX3 - adds more power to VIO_18 rail */
+static struct regulator_init_data rx51_vaux3_cam = {
+ .constraints = {
+ .name = "VCAM_DIG_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vaux3_mmc = {
+ .constraints = {
+ .name = "VMMC2_30",
+ .min_uV = 2800000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vaux3_supply,
+};
+
+static struct regulator_init_data rx51_vaux4 = {
+ .constraints = {
+ .name = "VCAM_ANA_28",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data rx51_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vmmc1_supply,
+};
+
+static struct regulator_init_data rx51_vmmc2 = {
+ .constraints = {
+ .name = "V28_A",
+ .min_uV = 2800000,
+ .max_uV = 3000000,
+ .always_on = true, /* due VIO leak to AIC34 VDDs */
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vmmc2_supplies),
+ .consumer_supplies = rx51_vmmc2_supplies,
+};
+
+static struct regulator_init_data rx51_vsim = {
+ .constraints = {
+ .name = "VMMC2_IO_18",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &rx51_vsim_supply,
+};
+
+static struct regulator_init_data rx51_vdac = {
+ .constraints = {
+ .name = "VDAC",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = rx51_vdac_supply,
+};
+
+static struct regulator_init_data rx51_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(rx51_vio_supplies),
+ .consumer_supplies = rx51_vio_supplies,
+};
+
+static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
+ .gpio_reset = RX51_FMTX_RESET_GPIO,
+};
+
+static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
+ I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
+ .platform_data = &rx51_si4713_i2c_data,
+};
+
+static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
+ .i2c_bus = 2,
+ .subdev_board_info = &rx51_si4713_board_info,
+};
+
+static struct platform_device rx51_si4713_dev = {
+ .name = "radio-si4713",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx51_si4713_data,
+ },
+};
+
+static __init void rx51_init_si4713(void)
+{
+ int err;
+
+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+ if (err) {
+ printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
+ return;
+ }
+ rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
+ platform_device_register(&rx51_si4713_dev);
+}
+
+static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
+{
+ /* FIXME this gpio setup is just a placeholder for now */
+ gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm");
+ gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "speaker_en");
+
+ return 0;
+}
+
+static struct twl4030_gpio_platform_data rx51_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(0) | BIT(1) | BIT(2) | BIT(3)
+ | BIT(4) | BIT(5)
+ | BIT(8) | BIT(9) | BIT(10) | BIT(11)
+ | BIT(12) | BIT(13) | BIT(14) | BIT(15)
+ | BIT(16) | BIT(17) ,
+ .setup = rx51_twlgpio_setup,
+};
+
+static struct twl4030_usb_data rx51_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_ins sleep_on_seq[] __initdata = {
+/*
+ * Turn off everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_SLEEP), 2},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+ .script = sleep_on_seq,
+ .size = ARRAY_SIZE(sleep_on_seq),
+ .flags = TWL4030_SLEEP_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+/*
+ * Reenable everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+ .script = wakeup_seq,
+ .size = ARRAY_SIZE(wakeup_seq),
+ .flags = TWL4030_WAKEUP12_SCRIPT,
+};
+
+static struct twl4030_ins wakeup_p3_seq[] __initdata = {
+/*
+ * Reenable everything
+ */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 1, 0, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wakeup_p3_script __initdata = {
+ .script = wakeup_p3_seq,
+ .size = ARRAY_SIZE(wakeup_p3_seq),
+ .flags = TWL4030_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_ins wrst_seq[] __initdata = {
+/*
+ * Reset twl4030.
+ * Reset VDD1 regulator.
+ * Reset VDD2 regulator.
+ * Reset VPLL1 regulator.
+ * Enable sysclk output.
+ * Reenable twl4030.
+ */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, 0, 1, RES_STATE_ACTIVE),
+ 0x13},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 0, 3, RES_STATE_OFF), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD1, RES_STATE_WRST), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VDD2, RES_STATE_WRST), 0x13},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VPLL1, RES_STATE_WRST), 0x35},
+ {MSG_SINGULAR(DEV_GRP_P3, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2},
+};
+
+static struct twl4030_script wrst_script __initdata = {
+ .script = wrst_seq,
+ .size = ARRAY_SIZE(wrst_seq),
+ .flags = TWL4030_WRST_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+ /* wakeup12 script should be loaded before sleep script, otherwise a
+ board might hit retention before loading of wakeup script is
+ completed. This can cause boot failures depending on timing issues.
+ */
+ &wakeup_script,
+ &sleep_on_script,
+ &wakeup_p3_script,
+ &wrst_script,
+};
+
+static struct twl4030_resconfig twl4030_rconfig[] __initdata = {
+ { .resource = RES_VDD1, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VDD2, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VPLL1, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = RES_STATE_OFF,
+ .remap_sleep = RES_STATE_OFF
+ },
+ { .resource = RES_VPLL2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX1, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX3, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VAUX4, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VMMC1, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VMMC2, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VDAC, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VSIM, .devgroup = -1,
+ .type = -1, .type2 = 3, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = -1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_VIO, .devgroup = DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1 , .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_REGEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_P1 | DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_32KCLKOUT, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_RESET, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { .resource = RES_MAIN_REF, .devgroup = -1,
+ .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
+ },
+ { 0, 0},
+};
+
+static struct twl4030_power_data rx51_t2scripts_data __initdata = {
+ .scripts = twl4030_scripts,
+ .num = ARRAY_SIZE(twl4030_scripts),
+ .resource_config = twl4030_rconfig,
+};
+
+struct twl4030_codec_vibra_data rx51_vibra_data __initdata = {
+ .coexist = 0,
+};
+
+struct twl4030_codec_data rx51_codec_data __initdata = {
+ .audio_mclk = 26000000,
+ .vibra = &rx51_vibra_data,
+};
+
+static struct twl4030_platform_data rx51_twldata __initdata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .gpio = &rx51_gpio_data,
+ .keypad = &rx51_kp_data,
+ .madc = &rx51_madc_data,
+ .usb = &rx51_usb_data,
+ .power = &rx51_t2scripts_data,
+ .codec = &rx51_codec_data,
+
+ .vaux1 = &rx51_vaux1,
+ .vaux2 = &rx51_vaux2,
+ .vaux4 = &rx51_vaux4,
+ .vmmc1 = &rx51_vmmc1,
+ .vsim = &rx51_vsim,
+ .vdac = &rx51_vdac,
+ .vio = &rx51_vio,
+};
+
+static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = {
+ .id = TPA6130A2,
+ .power_gpio = 98,
+};
+
+/* Audio setup data */
+static struct aic3x_setup_data rx51_aic34_setup = {
+ .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
+ .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
+};
+
+static struct aic3x_pdata rx51_aic3x_data = {
+ .setup = &rx51_aic34_setup,
+ .gpio_reset = 60,
+};
+
+static struct aic3x_pdata rx51_aic3x_data2 = {
+ .gpio_reset = 60,
+};
+
+static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &rx51_aic3x_data,
+ },
+ {
+ I2C_BOARD_INFO("tlv320aic3x", 0x19),
+ .platform_data = &rx51_aic3x_data2,
+ },
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+ {
+ I2C_BOARD_INFO("tsl2563", 0x29),
+ .platform_data = &rx51_tsl2563_platform_data,
+ },
+#endif
+ {
+ I2C_BOARD_INFO("tpa6130a2", 0x60),
+ .platform_data = &rx51_tpa6130a2_data,
+ }
+};
+
+static int __init rx51_i2c_init(void)
+{
+ if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
+ system_rev >= SYSTEM_REV_B_USES_VAUX3) {
+ rx51_twldata.vaux3 = &rx51_vaux3_mmc;
+ /* Only older boards use VMMC2 for internal MMC */
+ rx51_vmmc2.num_consumer_supplies--;
+ } else {
+ rx51_twldata.vaux3 = &rx51_vaux3_cam;
+ }
+ rx51_twldata.vmmc2 = &rx51_vmmc2;
+ omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata);
+ omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
+ ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+static struct mtd_partition onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x20000,
+ .mask_flags = MTD_WRITEABLE, /* Force read-only */
+ },
+ {
+ .name = "config",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x60000,
+ },
+ {
+ .name = "log",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x40000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "initfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x200000,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data board_onenand_data[] = {
+ {
+ .cs = 0,
+ .gpio_irq = 65,
+ .parts = onenand_partitions,
+ .nr_parts = ARRAY_SIZE(onenand_partitions),
+ .flags = ONENAND_SYNC_READWRITE,
+ }
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+
+static struct omap_smc91x_platform_data board_smc91x_data = {
+ .cs = 1,
+ .gpio_irq = 54,
+ .gpio_pwrdwn = 86,
+ .gpio_reset = 164,
+ .flags = GPMC_TIMINGS_SMC91C96 | IORESOURCE_IRQ_HIGHLEVEL,
+};
+
+static void __init board_smc91x_init(void)
+{
+ omap_mux_init_gpio(54, OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_gpio(86, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(164, OMAP_PIN_OUTPUT);
+
+ gpmc_smc91x_init(&board_smc91x_data);
+}
+
+#else
+
+static inline void board_smc91x_init(void)
+{
+}
+
+#endif
+
+static void rx51_wl1251_set_power(bool enable)
+{
+ gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
+}
+
+static struct gpio rx51_wl1251_gpios[] __initdata = {
+ { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" },
+ { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" },
+};
+
+static void __init rx51_init_wl1251(void)
+{
+ int irq, ret;
+
+ ret = gpio_request_array(rx51_wl1251_gpios,
+ ARRAY_SIZE(rx51_wl1251_gpios));
+ if (ret < 0)
+ goto error;
+
+ irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO);
+ if (irq < 0)
+ goto err_irq;
+
+ wl1251_pdata.set_power = rx51_wl1251_set_power;
+ rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
+
+ return;
+
+err_irq:
+ gpio_free(RX51_WL1251_IRQ_GPIO);
+ gpio_free(RX51_WL1251_POWER_GPIO);
+error:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+ wl1251_pdata.set_power = NULL;
+
+ /*
+ * Now rx51_peripherals_spi_board_info[1].irq is zero and
+ * set_power is null, and wl1251_probe() will fail.
+ */
+}
+
+void __init rx51_peripherals_init(void)
+{
+ rx51_i2c_init();
+ gpmc_onenand_init(board_onenand_data);
+ board_smc91x_init();
+ rx51_add_gpio_keys();
+ rx51_init_wl1251();
+ rx51_init_si4713();
+ spi_register_board_info(rx51_peripherals_spi_board_info,
+ ARRAY_SIZE(rx51_peripherals_spi_board_info));
+
+ partition = omap_mux_get("core");
+ if (partition)
+ omap2_hsmmc_init(mmc);
+
+ rx51_charger_init();
+}
+
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
new file mode 100644
index 00000000..2c1289bd
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51-video.c
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/mm.h>
+#include <asm/mach-types.h>
+#include <video/omapdss.h>
+#include <plat/vram.h>
+#include <plat/mcspi.h>
+
+#include <mach/board-rx51.h>
+
+#include "mux.h"
+
+#define RX51_LCD_RESET_GPIO 90
+
+#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static int rx51_lcd_enable(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void rx51_lcd_disable(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+static struct omap_dss_device rx51_lcd_device = {
+ .name = "lcd",
+ .driver_name = "panel-acx565akm",
+ .type = OMAP_DISPLAY_TYPE_SDI,
+ .phy.sdi.datapairs = 2,
+ .reset_gpio = RX51_LCD_RESET_GPIO,
+ .platform_enable = rx51_lcd_enable,
+ .platform_disable = rx51_lcd_disable,
+};
+
+static struct omap_dss_device rx51_tv_device = {
+ .name = "tv",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .driver_name = "venc",
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+};
+
+static struct omap_dss_device *rx51_dss_devices[] = {
+ &rx51_lcd_device,
+ &rx51_tv_device,
+};
+
+static struct omap_dss_board_info rx51_dss_board_info = {
+ .num_devices = ARRAY_SIZE(rx51_dss_devices),
+ .devices = rx51_dss_devices,
+ .default_device = &rx51_lcd_device,
+};
+
+static int __init rx51_video_init(void)
+{
+ if (!machine_is_nokia_rx51())
+ return 0;
+
+ if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) {
+ pr_err("%s cannot configure MUX for LCD RESET\n", __func__);
+ return 0;
+ }
+
+ if (gpio_request_one(RX51_LCD_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
+ "LCD ACX565AKM reset")) {
+ pr_err("%s failed to get LCD Reset GPIO\n", __func__);
+ return 0;
+ }
+
+ omap_display_init(&rx51_dss_board_info);
+ return 0;
+}
+
+subsys_initcall(rx51_video_init);
+
+void __init rx51_video_mem_init(void)
+{
+ /*
+ * GFX 864x480x32bpp
+ * VID1/2 1280x720x32bpp double buffered
+ */
+ omap_vram_set_sdram_vram(PAGE_ALIGN(864 * 480 * 4) +
+ 2 * PAGE_ALIGN(1280 * 720 * 4 * 2), 0);
+}
+
+#else
+void __init rx51_video_mem_init(void) { }
+#endif /* defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE) */
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
new file mode 100644
index 00000000..fec4cac8
--- /dev/null
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -0,0 +1,166 @@
+/*
+ * linux/arch/arm/mach-omap2/board-rx51.c
+ *
+ * Copyright (C) 2007, 2008 Nokia
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/mcspi.h>
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/dma.h>
+#include <plat/gpmc.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+#include "pm.h"
+#include "sdram-nokia.h"
+
+#define RX51_GPIO_SLEEP_IND 162
+
+extern void rx51_video_mem_init(void);
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "sleep_ind",
+ .gpio = RX51_GPIO_SLEEP_IND,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+/*
+ * cpuidle C-states definition override from the default values.
+ * The 'exit_latency' field is the sum of sleep and wake-up latencies.
+ */
+static struct cpuidle_params rx51_cpuidle_params[] = {
+ /* C1 */
+ {110 + 162, 5 , 1},
+ /* C2 */
+ {106 + 180, 309, 1},
+ /* C3 */
+ {107 + 410, 46057, 0},
+ /* C4 */
+ {121 + 3374, 46057, 0},
+ /* C5 */
+ {855 + 1146, 46057, 1},
+ /* C6 */
+ {7580 + 4134, 484329, 0},
+ /* C7 */
+ {7505 + 15274, 484329, 1},
+};
+
+static struct omap_lcd_config rx51_lcd_config = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_fbmem_config rx51_fbmem0_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem1_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_fbmem_config rx51_fbmem2_config = {
+ .size = 752 * 1024,
+};
+
+static struct omap_board_config_kernel rx51_config[] = {
+ { OMAP_TAG_FBMEM, &rx51_fbmem0_config },
+ { OMAP_TAG_FBMEM, &rx51_fbmem1_config },
+ { OMAP_TAG_FBMEM, &rx51_fbmem2_config },
+ { OMAP_TAG_LCD, &rx51_lcd_config },
+};
+
+static void __init rx51_init_early(void)
+{
+ struct omap_sdrc_params *sdrc_params;
+
+ omap2_init_common_infrastructure();
+ sdrc_params = nokia_get_sdram_timings();
+ omap2_init_common_devices(sdrc_params, sdrc_params);
+}
+
+extern void __init rx51_peripherals_init(void);
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_PERIPHERAL,
+ .power = 0,
+};
+
+static void __init rx51_init(void)
+{
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ omap_board_config = rx51_config;
+ omap_board_config_size = ARRAY_SIZE(rx51_config);
+ omap3_pm_init_cpuidle(rx51_cpuidle_params);
+ omap_serial_init();
+ usb_musb_init(&musb_board_data);
+ rx51_peripherals_init();
+
+ /* Ensure SDRC pins are mux'd for self-refresh */
+ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
+
+ platform_device_register(&leds_gpio);
+}
+
+static void __init rx51_map_io(void)
+{
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+}
+
+static void __init rx51_reserve(void)
+{
+ rx51_video_mem_init();
+ omap_reserve();
+}
+
+MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
+ /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
+ .boot_params = 0x80000100,
+ .reserve = rx51_reserve,
+ .map_io = rx51_map_io,
+ .init_early = rx51_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = rx51_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
new file mode 100644
index 00000000..09fa7bff
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -0,0 +1,62 @@
+/*
+ * Code for TI8168 EVM.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/irqs.h>
+#include <plat/board.h>
+#include <plat/common.h>
+
+static struct omap_board_config_kernel ti8168_evm_config[] __initdata = {
+};
+
+static void __init ti8168_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ omap2_init_common_devices(NULL, NULL);
+}
+
+static void __init ti8168_evm_init_irq(void)
+{
+ omap_init_irq();
+}
+
+static void __init ti8168_evm_init(void)
+{
+ omap_serial_init();
+ omap_board_config = ti8168_evm_config;
+ omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
+}
+
+static void __init ti8168_evm_map_io(void)
+{
+ omap2_set_globals_ti816x();
+ omapti816x_map_common_io();
+}
+
+MACHINE_START(TI8168EVM, "ti8168evm")
+ /* Maintainer: Texas Instruments */
+ .boot_params = 0x80000100,
+ .map_io = ti8168_evm_map_io,
+ .init_early = ti8168_init_early,
+ .init_irq = ti8168_evm_init_irq,
+ .timer = &omap_timer,
+ .init_machine = ti8168_evm_init,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-zoom-debugboard.c b/arch/arm/mach-omap2/board-zoom-debugboard.c
new file mode 100644
index 00000000..6402e781
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-debugboard.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ * Mikkel Christensen <mlc@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_8250.h>
+#include <linux/smsc911x.h>
+#include <linux/interrupt.h>
+
+#include <plat/gpmc.h>
+#include <plat/gpmc-smsc911x.h>
+
+#include <mach/board-zoom.h>
+
+#define ZOOM_SMSC911X_CS 7
+#define ZOOM_SMSC911X_GPIO 158
+#define ZOOM_QUADUART_CS 3
+#define ZOOM_QUADUART_GPIO 102
+#define QUART_CLK 1843200
+#define DEBUG_BASE 0x08000000
+#define ZOOM_ETHR_START DEBUG_BASE
+
+static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = {
+ .cs = ZOOM_SMSC911X_CS,
+ .gpio_irq = ZOOM_SMSC911X_GPIO,
+ .gpio_reset = -EINVAL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static inline void __init zoom_init_smsc911x(void)
+{
+ gpmc_smsc911x_init(&zoom_smsc911x_cfg);
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = ZOOM_UART_BASE,
+ .irq = OMAP_GPIO_IRQ(102),
+ .flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
+ .irqflags = IRQF_SHARED | IRQF_TRIGGER_RISING,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = QUART_CLK,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device zoom_debugboard_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static inline void __init zoom_init_quaduart(void)
+{
+ int quart_cs;
+ unsigned long cs_mem_base;
+ int quart_gpio = 0;
+
+ quart_cs = ZOOM_QUADUART_CS;
+
+ if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem"
+ "for Quad UART(TL16CP754C)\n");
+ return;
+ }
+
+ quart_gpio = ZOOM_QUADUART_GPIO;
+
+ if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0)
+ printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
+ quart_gpio);
+}
+
+static inline int omap_zoom_debugboard_detect(void)
+{
+ int debug_board_detect = 0;
+ int ret = 1;
+
+ debug_board_detect = ZOOM_SMSC911X_GPIO;
+
+ if (gpio_request_one(debug_board_detect, GPIOF_IN,
+ "Zoom debug board detect") < 0) {
+ printk(KERN_ERR "Failed to request GPIO%d for Zoom debug"
+ "board detect\n", debug_board_detect);
+ return 0;
+ }
+
+ if (!gpio_get_value(debug_board_detect)) {
+ ret = 0;
+ }
+ gpio_free(debug_board_detect);
+ return ret;
+}
+
+static struct platform_device *zoom_devices[] __initdata = {
+ &zoom_debugboard_serial_device,
+};
+
+int __init zoom_debugboard_init(void)
+{
+ if (!omap_zoom_debugboard_detect())
+ return 0;
+
+ zoom_init_smsc911x();
+ zoom_init_quaduart();
+ return platform_add_devices(zoom_devices, ARRAY_SIZE(zoom_devices));
+}
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
new file mode 100644
index 00000000..d4683ba5
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-display.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 Texas Instruments Inc.
+ *
+ * Modified from mach-omap2/board-zoom-peripherals.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/spi/spi.h>
+#include <plat/mcspi.h>
+#include <video/omapdss.h>
+
+#define LCD_PANEL_RESET_GPIO_PROD 96
+#define LCD_PANEL_RESET_GPIO_PILOT 55
+#define LCD_PANEL_QVGA_GPIO 56
+
+static struct gpio zoom_lcd_gpios[] __initdata = {
+ { -EINVAL, GPIOF_OUT_INIT_HIGH, "lcd reset" },
+ { LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "lcd qvga" },
+};
+
+static void __init zoom_lcd_panel_init(void)
+{
+ zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
+ LCD_PANEL_RESET_GPIO_PROD :
+ LCD_PANEL_RESET_GPIO_PILOT;
+
+ if (gpio_request_array(zoom_lcd_gpios, ARRAY_SIZE(zoom_lcd_gpios)))
+ pr_err("%s: Failed to get LCD GPIOs.\n", __func__);
+}
+
+static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ return 0;
+}
+
+static void zoom_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+}
+
+/*
+ * PWMA/B register offsets (TWL4030_MODULE_PWMA)
+ */
+#define TWL_INTBR_PMBR1 0xD
+#define TWL_INTBR_GPBR1 0xC
+#define TWL_LED_PWMON 0x0
+#define TWL_LED_PWMOFF 0x1
+
+static int zoom_set_bl_intensity(struct omap_dss_device *dssdev, int level)
+{
+ unsigned char c;
+ u8 mux_pwm, enb_pwm;
+
+ if (level > 100)
+ return -1;
+
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &mux_pwm, TWL_INTBR_PMBR1);
+ twl_i2c_read_u8(TWL4030_MODULE_INTBR, &enb_pwm, TWL_INTBR_GPBR1);
+
+ if (level == 0) {
+ /* disable pwm1 output and clock */
+ enb_pwm = enb_pwm & 0xF5;
+ /* change pwm1 pin to gpio pin */
+ mux_pwm = mux_pwm & 0xCF;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ enb_pwm, TWL_INTBR_GPBR1);
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ mux_pwm, TWL_INTBR_PMBR1);
+ return 0;
+ }
+
+ if (!((enb_pwm & 0xA) && (mux_pwm & 0x30))) {
+ /* change gpio pin to pwm1 pin */
+ mux_pwm = mux_pwm | 0x30;
+ /* enable pwm1 output and clock*/
+ enb_pwm = enb_pwm | 0x0A;
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ mux_pwm, TWL_INTBR_PMBR1);
+ twl_i2c_write_u8(TWL4030_MODULE_INTBR,
+ enb_pwm, TWL_INTBR_GPBR1);
+ }
+
+ c = ((50 * (100 - level)) / 100) + 1;
+ twl_i2c_write_u8(TWL4030_MODULE_PWM1, 0x7F, TWL_LED_PWMOFF);
+ twl_i2c_write_u8(TWL4030_MODULE_PWM1, c, TWL_LED_PWMON);
+
+ return 0;
+}
+
+static struct omap_dss_device zoom_lcd_device = {
+ .name = "lcd",
+ .driver_name = "NEC_8048_panel",
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .phy.dpi.data_lines = 24,
+ .platform_enable = zoom_panel_enable_lcd,
+ .platform_disable = zoom_panel_disable_lcd,
+ .max_backlight_level = 100,
+ .set_backlight = zoom_set_bl_intensity,
+};
+
+static struct omap_dss_device *zoom_dss_devices[] = {
+ &zoom_lcd_device,
+};
+
+static struct omap_dss_board_info zoom_dss_data = {
+ .num_devices = ARRAY_SIZE(zoom_dss_devices),
+ .devices = zoom_dss_devices,
+ .default_device = &zoom_lcd_device,
+};
+
+static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
+ .turbo_mode = 1,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct spi_board_info nec_8048_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "nec_8048_spi",
+ .bus_num = 1,
+ .chip_select = 2,
+ .max_speed_hz = 375000,
+ .controller_data = &dss_lcd_mcspi_config,
+ },
+};
+
+void __init zoom_display_init(void)
+{
+ omap_display_init(&zoom_dss_data);
+ spi_register_board_info(nec_8048_spi_board_info,
+ ARRAY_SIZE(nec_8048_spi_board_info));
+ zoom_lcd_panel_init();
+}
+
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
new file mode 100644
index 00000000..118c6f53
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2009 Texas Instruments Inc.
+ *
+ * Modified from mach-omap2/board-zoom2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/wl12xx.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/common.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "common-board-devices.h"
+
+#define OMAP_ZOOM_WLAN_PMENA_GPIO (101)
+#define OMAP_ZOOM_WLAN_IRQ_GPIO (162)
+
+#define LCD_PANEL_ENABLE_GPIO (7 + OMAP_MAX_GPIO_LINES)
+
+/* Zoom2 has Qwerty keyboard*/
+static uint32_t board_keymap[] = {
+ KEY(0, 0, KEY_E),
+ KEY(0, 1, KEY_R),
+ KEY(0, 2, KEY_T),
+ KEY(0, 3, KEY_HOME),
+ KEY(0, 6, KEY_I),
+ KEY(0, 7, KEY_LEFTSHIFT),
+ KEY(1, 0, KEY_D),
+ KEY(1, 1, KEY_F),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_SEND),
+ KEY(1, 6, KEY_K),
+ KEY(1, 7, KEY_ENTER),
+ KEY(2, 0, KEY_X),
+ KEY(2, 1, KEY_C),
+ KEY(2, 2, KEY_V),
+ KEY(2, 3, KEY_END),
+ KEY(2, 6, KEY_DOT),
+ KEY(2, 7, KEY_CAPSLOCK),
+ KEY(3, 0, KEY_Z),
+ KEY(3, 1, KEY_KPPLUS),
+ KEY(3, 2, KEY_B),
+ KEY(3, 3, KEY_F1),
+ KEY(3, 6, KEY_O),
+ KEY(3, 7, KEY_SPACE),
+ KEY(4, 0, KEY_W),
+ KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_U),
+ KEY(4, 3, KEY_F2),
+ KEY(4, 4, KEY_VOLUMEUP),
+ KEY(4, 6, KEY_L),
+ KEY(4, 7, KEY_LEFT),
+ KEY(5, 0, KEY_S),
+ KEY(5, 1, KEY_H),
+ KEY(5, 2, KEY_J),
+ KEY(5, 3, KEY_F3),
+ KEY(5, 4, KEY_UNKNOWN),
+ KEY(5, 5, KEY_VOLUMEDOWN),
+ KEY(5, 6, KEY_M),
+ KEY(5, 7, KEY_RIGHT),
+ KEY(6, 0, KEY_Q),
+ KEY(6, 1, KEY_A),
+ KEY(6, 2, KEY_N),
+ KEY(6, 3, KEY_BACKSPACE),
+ KEY(6, 6, KEY_P),
+ KEY(6, 7, KEY_UP),
+ KEY(7, 0, KEY_PROG1), /*MACRO 1 <User defined> */
+ KEY(7, 1, KEY_PROG2), /*MACRO 2 <User defined> */
+ KEY(7, 2, KEY_PROG3), /*MACRO 3 <User defined> */
+ KEY(7, 3, KEY_PROG4), /*MACRO 4 <User defined> */
+ KEY(7, 6, KEY_SELECT),
+ KEY(7, 7, KEY_DOWN)
+};
+
+static struct matrix_keymap_data board_map_data = {
+ .keymap = board_keymap,
+ .keymap_size = ARRAY_SIZE(board_keymap),
+};
+
+static struct twl4030_keypad_data zoom_kp_twl4030_data = {
+ .keymap_data = &board_map_data,
+ .rows = 8,
+ .cols = 8,
+ .rep = 1,
+};
+
+static struct regulator_consumer_supply zoom_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply zoom_vsim_supply = {
+ .supply = "vmmc_aux",
+};
+
+static struct regulator_consumer_supply zoom_vmmc2_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply zoom_vmmc3_supply = {
+ .supply = "vmmc",
+ .dev_name = "omap_hsmmc.2",
+};
+
+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
+static struct regulator_init_data zoom_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vmmc1_supply,
+};
+
+/* VMMC2 for MMC2 card */
+static struct regulator_init_data zoom_vmmc2 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 1850000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vmmc2_supply,
+};
+
+/* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */
+static struct regulator_init_data zoom_vsim = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vsim_supply,
+};
+
+static struct regulator_init_data zoom_vmmc3 = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vmmc3_supply,
+};
+
+static struct fixed_voltage_config zoom_vwlan = {
+ .supply_name = "vwl1271",
+ .microvolts = 1800000, /* 1.8V */
+ .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO,
+ .startup_delay = 70000, /* 70msec */
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &zoom_vmmc3,
+};
+
+static struct platform_device omap_vwlan_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &zoom_vwlan,
+ },
+};
+
+static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
+ .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO),
+ /* ZOOM ref clock is 26 MHz */
+ .board_ref_clock = 1,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .name = "external",
+ .mmc = 1,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -EINVAL,
+ .power_saving = true,
+ },
+ {
+ .name = "internal",
+ .mmc = 2,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .nonremovable = true,
+ .power_saving = true,
+ },
+ {
+ .name = "wl1271",
+ .mmc = 3,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD,
+ .gpio_wp = -EINVAL,
+ .gpio_cd = -EINVAL,
+ .nonremovable = true,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply zoom_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
+};
+
+static struct regulator_consumer_supply zoom_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
+
+static struct regulator_init_data zoom_vpll2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies),
+ .consumer_supplies = zoom_vpll2_supplies,
+};
+
+static struct regulator_init_data zoom_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &zoom_vdda_dac_supply,
+};
+
+static int zoom_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ int ret;
+
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ omap2_hsmmc_init(mmc);
+
+ /* link regulators to MMC adapters ... we "know" the
+ * regulators will be set up only *after* we return.
+ */
+ zoom_vmmc1_supply.dev = mmc[0].dev;
+ zoom_vsim_supply.dev = mmc[0].dev;
+ zoom_vmmc2_supply.dev = mmc[1].dev;
+
+ ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
+ "lcd enable");
+ if (ret)
+ pr_err("Failed to get LCD_PANEL_ENABLE_GPIO (gpio%d).\n",
+ LCD_PANEL_ENABLE_GPIO);
+
+ return ret;
+}
+
+/* EXTMUTE callback function */
+static void zoom2_set_hs_extmute(int mute)
+{
+ gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
+}
+
+static int zoom_batt_table[] = {
+/* 0 C*/
+30800, 29500, 28300, 27100,
+26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
+17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
+11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
+8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
+5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
+4040, 3910, 3790, 3670, 3550
+};
+
+static struct twl4030_bci_platform_data zoom_bci_data = {
+ .battery_tmp_tbl = zoom_batt_table,
+ .tblsize = ARRAY_SIZE(zoom_batt_table),
+};
+
+static struct twl4030_usb_data zoom_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+static struct twl4030_gpio_platform_data zoom_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .setup = zoom_twl_gpio_setup,
+};
+
+static struct twl4030_madc_platform_data zoom_madc_data = {
+ .irq_line = 1,
+};
+
+static struct twl4030_codec_audio_data zoom_audio_data;
+
+static struct twl4030_codec_data zoom_codec_data = {
+ .audio_mclk = 26000000,
+ .audio = &zoom_audio_data,
+};
+
+static struct twl4030_platform_data zoom_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ .bci = &zoom_bci_data,
+ .madc = &zoom_madc_data,
+ .usb = &zoom_usb_data,
+ .gpio = &zoom_gpio_data,
+ .keypad = &zoom_kp_twl4030_data,
+ .codec = &zoom_codec_data,
+ .vmmc1 = &zoom_vmmc1,
+ .vmmc2 = &zoom_vmmc2,
+ .vsim = &zoom_vsim,
+ .vpll2 = &zoom_vpll2,
+ .vdac = &zoom_vdac,
+};
+
+static int __init omap_i2c_init(void)
+{
+ if (machine_is_omap_zoom2()) {
+ zoom_audio_data.ramp_delay_value = 3; /* 161 ms */
+ zoom_audio_data.hs_extmute = 1;
+ zoom_audio_data.set_hs_extmute = zoom2_set_hs_extmute;
+ }
+ omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static void enable_board_wakeup_source(void)
+{
+ /* T2 interrupt line (keypad) */
+ omap_mux_init_signal("sys_nirq",
+ OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
+}
+
+void __init zoom_peripherals_init(void)
+{
+ if (wl12xx_set_platform_data(&omap_zoom_wlan_data))
+ pr_err("error setting wl12xx data\n");
+
+ omap_i2c_init();
+ platform_device_register(&omap_vwlan_device);
+ usb_musb_init(NULL);
+ enable_board_wakeup_source();
+ omap_serial_init();
+}
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
new file mode 100644
index 00000000..4b133d75
--- /dev/null
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2009-2010 Texas Instruments Inc.
+ * Mikkel Christensen <mlc@ti.com>
+ * Felipe Balbi <balbi@ti.com>
+ *
+ * Modified from mach-omap2/board-ldp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/usb.h>
+
+#include <mach/board-zoom.h>
+
+#include "board-flash.h"
+#include "mux.h"
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "sdram-hynix-h8mbx00u0mer-0em.h"
+
+#define ZOOM3_EHCI_RESET_GPIO 64
+
+static void __init omap_zoom_init_early(void)
+{
+ omap2_init_common_infrastructure();
+ if (machine_is_omap_zoom2())
+ omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ else if (machine_is_omap_zoom3())
+ omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+}
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 162 */
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+ /* WLAN POWER ENABLE - GPIO 101 */
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC3 CMD */
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 CLK */
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 DAT[0-3] */
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#endif
+
+static struct mtd_partition zoom_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader-NAND",
+ .offset = 0,
+ .size = 4 * (64 * 2048), /* 512KB, 0x80000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 10 * (64 * 2048), /* 1.25MB, 0x140000 */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "Boot Env-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1c0000 */
+ .size = 2 * (64 * 2048), /* 256KB, 0x40000 */
+ },
+ {
+ .name = "Kernel-NAND",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x0200000*/
+ .size = 240 * (64 * 2048), /* 30M, 0x1E00000 */
+ },
+ {
+ .name = "system",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x2000000 */
+ .size = 3328 * (64 * 2048), /* 416M, 0x1A000000 */
+ },
+ {
+ .name = "userdata",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1C000000*/
+ .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
+ },
+ {
+ .name = "cache",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x1E000000*/
+ .size = 256 * (64 * 2048), /* 32M, 0x2000000 */
+ },
+};
+
+static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+ .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+ .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = ZOOM3_EHCI_RESET_GPIO,
+ .reset_gpio_port[2] = -EINVAL,
+};
+
+static void __init omap_zoom_init(void)
+{
+ if (machine_is_omap_zoom2()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+ } else if (machine_is_omap_zoom3()) {
+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
+ omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
+ usbhs_init(&usbhs_bdata);
+ }
+
+ board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions),
+ ZOOM_NAND_CS, NAND_BUSWIDTH_16);
+ zoom_debugboard_init();
+ zoom_peripherals_init();
+ zoom_display_init();
+}
+
+MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap_zoom_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_zoom_init,
+ .timer = &omap_timer,
+MACHINE_END
+
+MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
+ .boot_params = 0x80000100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap_zoom_init_early,
+ .init_irq = omap_init_irq,
+ .init_machine = omap_zoom_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
new file mode 100644
index 00000000..b19a1f72
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_apll.c
@@ -0,0 +1,146 @@
+/*
+ * OMAP2xxx APLL clock control functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
+#define EN_APLL_STOPPED 0
+#define EN_APLL_LOCKED 3
+
+/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
+#define APLLS_CLKIN_19_2MHZ 0
+#define APLLS_CLKIN_13MHZ 2
+#define APLLS_CLKIN_12MHZ 3
+
+void __iomem *cm_idlest_pll;
+
+/* Private functions */
+
+/* Enable an APLL if off */
+static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
+{
+ u32 cval, apll_mask;
+
+ apll_mask = EN_APLL_LOCKED << clk->enable_bit;
+
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+
+ if ((cval & apll_mask) == apll_mask)
+ return 0; /* apll already enabled */
+
+ cval &= ~apll_mask;
+ cval |= apll_mask;
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+
+ omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
+ OMAP24XX_CM_IDLEST_VAL, clk->name);
+
+ /*
+ * REVISIT: Should we return an error code if omap2_wait_clock_ready()
+ * fails?
+ */
+ return 0;
+}
+
+static int omap2_clk_apll96_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
+}
+
+static int omap2_clk_apll54_enable(struct clk *clk)
+{
+ return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
+}
+
+static void _apll96_allow_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll96_auto_low_power_stop();
+}
+
+static void _apll96_deny_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll96_disable_autoidle();
+}
+
+static void _apll54_allow_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll54_auto_low_power_stop();
+}
+
+static void _apll54_deny_idle(struct clk *clk)
+{
+ omap2xxx_cm_set_apll54_disable_autoidle();
+}
+
+/* Stop APLL */
+static void omap2_clk_apll_disable(struct clk *clk)
+{
+ u32 cval;
+
+ cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
+ omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
+}
+
+/* Public data */
+
+const struct clkops clkops_apll96 = {
+ .enable = omap2_clk_apll96_enable,
+ .disable = omap2_clk_apll_disable,
+ .allow_idle = _apll96_allow_idle,
+ .deny_idle = _apll96_deny_idle,
+};
+
+const struct clkops clkops_apll54 = {
+ .enable = omap2_clk_apll54_enable,
+ .disable = omap2_clk_apll_disable,
+ .allow_idle = _apll54_allow_idle,
+ .deny_idle = _apll54_deny_idle,
+};
+
+/* Public functions */
+
+u32 omap2xxx_get_apll_clkin(void)
+{
+ u32 aplls, srate = 0;
+
+ aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
+ aplls &= OMAP24XX_APLLS_CLKIN_MASK;
+ aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
+
+ if (aplls == APLLS_CLKIN_19_2MHZ)
+ srate = 19200000;
+ else if (aplls == APLLS_CLKIN_13MHZ)
+ srate = 13000000;
+ else if (aplls == APLLS_CLKIN_12MHZ)
+ srate = 12000000;
+
+ return srate;
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpll.c b/arch/arm/mach-omap2/clkt2xxx_dpll.c
new file mode 100644
index 00000000..1502a7bc
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpll.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP2-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/**
+ * _allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control. The DPLL will enter low-power
+ * stop when its downstream clocks are gated. No return value.
+ * REVISIT: DPLL can optionally enter low-power bypass by writing 0x1
+ * instead. Add some mechanism to optionally enter this mode.
+ */
+static void _allow_idle(struct clk *clk)
+{
+ if (!clk || !clk->dpll_data)
+ return;
+
+ omap2xxx_cm_set_dpll_auto_low_power_stop();
+}
+
+/**
+ * _deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control. No return value.
+ */
+static void _deny_idle(struct clk *clk)
+{
+ if (!clk || !clk->dpll_data)
+ return;
+
+ omap2xxx_cm_set_dpll_disable_autoidle();
+}
+
+
+/* Public data */
+
+const struct clkops clkops_omap2xxx_dpll_ops = {
+ .allow_idle = _allow_idle,
+ .deny_idle = _deny_idle,
+};
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
new file mode 100644
index 00000000..4ae43922
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c
@@ -0,0 +1,173 @@
+/*
+ * DPLL + CORE_CLK composite clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX The DPLL and CORE clocks should be split into two separate clock
+ * types.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
+
+/**
+ * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
+ * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
+ *
+ * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
+ * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
+ * (the latter is unusual). This currently should be called with
+ * struct clk *dpll_ck, which is a composite clock of dpll_ck and
+ * core_ck.
+ */
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
+{
+ long long core_clk;
+ u32 v;
+
+ core_clk = omap2_get_dpll_rate(clk);
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ v &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (v == CORE_CLK_SRC_32K)
+ core_clk = 32768;
+ else
+ core_clk *= v;
+
+ return core_clk;
+}
+
+/*
+ * Uses the current prcm set to tell if a rate is valid.
+ * You can go slower, but not faster within a given rate set.
+ */
+static long omap2_dpllcore_round_rate(unsigned long target_rate)
+{
+ u32 high, low, core_clk_src;
+
+ core_clk_src = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
+ high = curr_prcm_set->dpll_speed * 2;
+ low = curr_prcm_set->dpll_speed;
+ } else { /* DPLL clockout x 2 */
+ high = curr_prcm_set->dpll_speed;
+ low = curr_prcm_set->dpll_speed / 2;
+ }
+
+#ifdef DOWN_VARIABLE_DPLL
+ if (target_rate > high)
+ return high;
+ else
+ return target_rate;
+#else
+ if (target_rate > low)
+ return high;
+ else
+ return low;
+#endif
+
+}
+
+unsigned long omap2_dpllcore_recalc(struct clk *clk)
+{
+ return omap2xxx_clk_get_core_rate(clk);
+}
+
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, low, mult, div, valid_rate, done_rate;
+ u32 bypass = 0;
+ struct prcm_config tmpset;
+ const struct dpll_data *dd;
+
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+ mult = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ mult &= OMAP24XX_CORE_CLK_SRC_MASK;
+
+ if ((rate == (cur_rate / 2)) && (mult == 2)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (rate != cur_rate) {
+ valid_rate = omap2_dpllcore_round_rate(rate);
+ if (valid_rate != rate)
+ return -EINVAL;
+
+ if (mult == 1)
+ low = curr_prcm_set->dpll_speed;
+ else
+ low = curr_prcm_set->dpll_speed / 2;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
+ tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
+ dd->div1_mask);
+ div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
+ tmpset.cm_clksel2_pll = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
+ tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
+ if (rate > low) {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
+ mult = ((rate / 2) / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ } else {
+ tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
+ mult = (rate / 1000000);
+ done_rate = CORE_CLK_SRC_DPLL;
+ }
+ tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
+ tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
+
+ /* Worst case */
+ tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
+
+ if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
+ bypass = 1;
+
+ /* For omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ /* Force dll lock mode */
+ omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
+ bypass);
+
+ /* Errata: ret dll entry state */
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+ }
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c
new file mode 100644
index 00000000..c3460928
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_osc.c
@@ -0,0 +1,76 @@
+/*
+ * OMAP2xxx osc_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * XXX This does not actually enable the osc_ck, since the osc_ck must
+ * be running for this function to be called. Instead, this function
+ * is used to disable an autoidle mode on the osc_ck. The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
+static int omap2_enable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+
+ return 0;
+}
+
+/*
+ * XXX This does not actually disable the osc_ck, since doing so would
+ * immediately halt the system. Instead, this function is used to
+ * enable an autoidle mode on the osc_ck. The existing
+ * clk_enable/clk_disable()-based usecounting for osc_ck should be
+ * replaced with autoidle-based usecounting.
+ */
+static void omap2_disable_osc_ck(struct clk *clk)
+{
+ u32 pcc;
+
+ pcc = __raw_readl(prcm_clksrc_ctrl);
+
+ __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl);
+}
+
+const struct clkops clkops_oscck = {
+ .enable = omap2_enable_osc_ck,
+ .disable = omap2_disable_osc_ck,
+};
+
+unsigned long omap2_osc_clk_recalc(struct clk *clk)
+{
+ return omap2xxx_get_apll_clkin() * omap2xxx_get_sysclkdiv();
+}
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c
new file mode 100644
index 00000000..8693cfda
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_sys.c
@@ -0,0 +1,50 @@
+/*
+ * OMAP2xxx sys_clk-specific clock code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+void __iomem *prcm_clksrc_ctrl;
+
+u32 omap2xxx_get_sysclkdiv(void)
+{
+ u32 div;
+
+ div = __raw_readl(prcm_clksrc_ctrl);
+ div &= OMAP_SYSCLKDIV_MASK;
+ div >>= OMAP_SYSCLKDIV_SHIFT;
+
+ return div;
+}
+
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk)
+{
+ return clk->parent->rate / omap2xxx_get_sysclkdiv();
+}
+
+
diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
new file mode 100644
index 00000000..39f9d5a5
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
@@ -0,0 +1,246 @@
+/*
+ * OMAP2xxx DVFS virtual clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX Some of this code should be replaceable by the upcoming OPP layer
+ * code. However, some notion of "rate set" is probably still necessary
+ * for OMAP2xxx at least. Rate sets should be generalized so they can be
+ * used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff
+ * has in the past expressed a preference to use rate sets for OPP changes,
+ * rather than dynamically recalculating the clock tree, so if someone wants
+ * this badly enough to write the code to handle it, we should support it
+ * as an option.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+const struct prcm_config *curr_prcm_set;
+const struct prcm_config *rate_table;
+
+/**
+ * omap2_table_mpu_recalc - just return the MPU speed
+ * @clk: virt_prcm_set struct clk
+ *
+ * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
+ */
+unsigned long omap2_table_mpu_recalc(struct clk *clk)
+{
+ return curr_prcm_set->mpu_speed;
+}
+
+/*
+ * Look for a rate equal or less than the target rate given a configuration set.
+ *
+ * What's not entirely clear is "which" field represents the key field.
+ * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
+ * just uses the ARM rates.
+ */
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate)
+{
+ const struct prcm_config *ptr;
+ long highest_rate;
+
+ highest_rate = -EINVAL;
+
+ for (ptr = rate_table; ptr->mpu_speed; ptr++) {
+ if (!(ptr->flags & cpu_mask))
+ continue;
+ if (ptr->xtal_speed != sclk->rate)
+ continue;
+
+ highest_rate = ptr->mpu_speed;
+
+ /* Can check only after xtal frequency check */
+ if (ptr->mpu_speed <= rate)
+ break;
+ }
+ return highest_rate;
+}
+
+/* Sets basic clocks based on the specified rate */
+int omap2_select_table_rate(struct clk *clk, unsigned long rate)
+{
+ u32 cur_rate, done_rate, bypass = 0, tmp;
+ const struct prcm_config *prcm;
+ unsigned long found_speed = 0;
+ unsigned long flags;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ if (prcm->mpu_speed <= rate) {
+ found_speed = prcm->mpu_speed;
+ break;
+ }
+ }
+
+ if (!found_speed) {
+ printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
+ rate / 1000000);
+ return -EINVAL;
+ }
+
+ curr_prcm_set = prcm;
+ cur_rate = omap2xxx_clk_get_core_rate(dclk);
+
+ if (prcm->dpll_speed == cur_rate / 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
+ } else if (prcm->dpll_speed == cur_rate * 2) {
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+ } else if (prcm->dpll_speed != cur_rate) {
+ local_irq_save(flags);
+
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ bypass = 1;
+
+ if ((prcm->cm_clksel2_pll & OMAP24XX_CORE_CLK_SRC_MASK) ==
+ CORE_CLK_SRC_DPLL_X2)
+ done_rate = CORE_CLK_SRC_DPLL_X2;
+ else
+ done_rate = CORE_CLK_SRC_DPLL;
+
+ /* MPU divider */
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mpu, MPU_MOD, CM_CLKSEL);
+
+ /* dsp + iva1 div(2420), iva2.1(2430) */
+ omap2_cm_write_mod_reg(prcm->cm_clksel_dsp,
+ OMAP24XX_DSP_MOD, CM_CLKSEL);
+
+ omap2_cm_write_mod_reg(prcm->cm_clksel_gfx, GFX_MOD, CM_CLKSEL);
+
+ /* Major subsystem dividers */
+ tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK;
+ omap2_cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD,
+ CM_CLKSEL1);
+
+ if (cpu_is_omap2430())
+ omap2_cm_write_mod_reg(prcm->cm_clksel_mdm,
+ OMAP2430_MDM_MOD, CM_CLKSEL);
+
+ /* x2 to enter omap2xxx_sdrc_init_params() */
+ omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
+
+ omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
+ bypass);
+
+ omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
+ omap2xxx_sdrc_reprogram(done_rate, 0);
+
+ local_irq_restore(flags);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Walk PRCM rate table and fillout cpufreq freq_table
+ * XXX This should be replaced by an OPP layer in the near future
+ */
+static struct cpufreq_frequency_table *freq_table;
+
+void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ const struct prcm_config *prcm;
+ int i = 0;
+ int tbl_sz = 0;
+
+ if (!cpu_is_omap24xx())
+ return;
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ tbl_sz++;
+ }
+
+ /*
+ * XXX Ensure that we're doing what CPUFreq expects for this error
+ * case and the following one
+ */
+ if (tbl_sz == 0) {
+ pr_warning("%s: no matching entries in rate_table\n",
+ __func__);
+ return;
+ }
+
+ /* Include the CPUFREQ_TABLE_END terminator entry */
+ tbl_sz++;
+
+ freq_table = kzalloc(sizeof(struct cpufreq_frequency_table) * tbl_sz,
+ GFP_ATOMIC);
+ if (!freq_table) {
+ pr_err("%s: could not kzalloc frequency table\n", __func__);
+ return;
+ }
+
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sclk->rate)
+ continue;
+
+ /* don't put bypass rates in table */
+ if (prcm->dpll_speed == prcm->xtal_speed)
+ continue;
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = prcm->mpu_speed / 1000;
+ i++;
+ }
+
+ freq_table[i].index = i;
+ freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ *table = &freq_table[0];
+}
+
+void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ if (!cpu_is_omap24xx())
+ return;
+
+ kfree(freq_table);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/clkt34xx_dpll3m2.c b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
new file mode 100644
index 00000000..d6e34dd9
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt34xx_dpll3m2.c
@@ -0,0 +1,122 @@
+/*
+ * OMAP34xx M2 divider clock code
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni Högander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "sdrc.h"
+
+#define CYCLES_PER_MHZ 1000000
+
+/*
+ * CORE DPLL (DPLL3) M2 divider rate programming functions
+ *
+ * These call into SRAM code to do the actual CM writes, since the SDRAM
+ * is clocked from DPLL3.
+ */
+
+/**
+ * omap3_core_dpll_m2_set_rate - set CORE DPLL M2 divider
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Program the DPLL M2 divider with the rounded target rate. Returns
+ * -EINVAL upon error, or 0 upon success.
+ */
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 new_div = 0;
+ u32 unlock_dll = 0;
+ u32 c;
+ unsigned long validrate, sdrcrate, _mpurate;
+ struct omap_sdrc_params *sdrc_cs0;
+ struct omap_sdrc_params *sdrc_cs1;
+ int ret;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ sdrcrate = sdrc_ick_p->rate;
+ if (rate > clk->rate)
+ sdrcrate <<= ((rate / clk->rate) >> 1);
+ else
+ sdrcrate >>= ((clk->rate / rate) >> 1);
+
+ ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
+ if (ret)
+ return -EINVAL;
+
+ if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
+ pr_debug("clock: will unlock SDRC DLL\n");
+ unlock_dll = 1;
+ }
+
+ /*
+ * XXX This only needs to be done when the CPU frequency changes
+ */
+ _mpurate = arm_fck_p->rate / CYCLES_PER_MHZ;
+ c = (_mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT;
+ c += 1; /* for safety */
+ c *= SDRC_MPURATE_LOOPS;
+ c >>= SDRC_MPURATE_SCALE;
+ if (c == 0)
+ c = 1;
+
+ pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
+ validrate);
+ pr_debug("clock: SDRC CS0 timing params used:"
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
+ if (sdrc_cs1)
+ pr_debug("clock: SDRC CS1 timing params used: "
+ " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+
+ if (sdrc_cs1)
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+ sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+ else
+ omap3_configure_core_dpll(
+ new_div, unlock_dll, c, rate > clk->rate,
+ sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+ sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+ 0, 0, 0, 0);
+ clk->rate = rate;
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
new file mode 100644
index 00000000..e25364de
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -0,0 +1,509 @@
+/*
+ * clkt_clksel.c - OMAP2/3/4 clksel clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * clksel clocks are clocks that do not have a fixed parent, or that
+ * can divide their parent's rate, or possibly both at the same time, based
+ * on the contents of a hardware register bitfield.
+ *
+ * All of the various mux and divider settings can be encoded into
+ * struct clksel* data structures, and then these can be autogenerated
+ * from some hardware database for each new chip generation. This
+ * should avoid the need to write, review, and validate a lot of new
+ * clock code for each new chip, since it can be exported from the SoC
+ * design flow. This is now done on OMAP4.
+ *
+ * The fusion of mux and divider clocks is a software creation. In
+ * hardware reality, the multiplexer (parent selection) and the
+ * divider exist separately. XXX At some point these clksel clocks
+ * should be split into "divider" clocks and "mux" clocks to better
+ * match the hardware.
+ *
+ * (The name "clksel" comes from the name of the corresponding
+ * register field in the OMAP2/3 family of SoCs.)
+ *
+ * XXX Currently these clocks are only used in the OMAP2/3/4 code, but
+ * many of the OMAP1 clocks should be convertible to use this
+ * mechanism.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+
+/* Private functions */
+
+/**
+ * _get_clksel_by_parent() - return clksel struct for a given clk & parent
+ * @clk: OMAP struct clk ptr to inspect
+ * @src_clk: OMAP struct clk ptr of the parent clk to search for
+ *
+ * Scan the struct clksel array associated with the clock to find
+ * the element associated with the supplied parent clock address.
+ * Returns a pointer to the struct clksel on success or NULL on error.
+ */
+static const struct clksel *_get_clksel_by_parent(struct clk *clk,
+ struct clk *src_clk)
+{
+ const struct clksel *clks;
+
+ for (clks = clk->clksel; clks->parent; clks++)
+ if (clks->parent == src_clk)
+ break; /* Found the requested parent */
+
+ if (!clks->parent) {
+ /* This indicates a data problem */
+ WARN(1, "clock: Could not find parent clock %s in clksel array "
+ "of clock %s\n", src_clk->name, clk->name);
+ return NULL;
+ }
+
+ return clks;
+}
+
+/**
+ * _get_div_and_fieldval() - find the new clksel divisor and field value to use
+ * @src_clk: planned new parent struct clk *
+ * @clk: struct clk * that is being reparented
+ * @field_val: pointer to a u32 to contain the register data for the divisor
+ *
+ * Given an intended new parent struct clk * @src_clk, and the struct
+ * clk * @clk to the clock that is being reparented, find the
+ * appropriate rate divisor for the new clock (returned as the return
+ * value), and the corresponding register bitfield data to program to
+ * reach that divisor (returned in the u32 pointed to by @field_val).
+ * Returns 0 on error, or returns the newly-selected divisor upon
+ * success (in this latter case, the corresponding register bitfield
+ * value is passed back in the variable pointed to by @field_val)
+ */
+static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
+ u32 *field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr, *max_clkr = NULL;
+ u8 max_div = 0;
+
+ clks = _get_clksel_by_parent(clk, src_clk);
+ if (!clks)
+ return 0;
+
+ /*
+ * Find the highest divisor (e.g., the one resulting in the
+ * lowest rate) to use as the default. This should avoid
+ * clock rates that are too high for the device. XXX A better
+ * solution here would be to try to determine if there is a
+ * divisor matching the original clock rate before the parent
+ * switch, and if it cannot be found, to fall back to the
+ * highest divisor.
+ */
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->div > max_div) {
+ max_div = clkr->div;
+ max_clkr = clkr;
+ }
+ }
+
+ if (max_div == 0) {
+ /* This indicates an error in the clksel data */
+ WARN(1, "clock: Could not find divisor for clock %s parent %s"
+ "\n", clk->name, src_clk->parent->name);
+ return 0;
+ }
+
+ *field_val = max_clkr->val;
+
+ return max_div;
+}
+
+/**
+ * _write_clksel_reg() - program a clock's clksel register in hardware
+ * @clk: struct clk * to program
+ * @v: clksel bitfield value to program (with LSB at bit 0)
+ *
+ * Shift the clksel register bitfield value @v to its appropriate
+ * location in the clksel register and write it in. This function
+ * will ensure that the write to the clksel_reg reaches its
+ * destination before returning -- important since PRM and CM register
+ * accesses can be quite slow compared to ARM cycles -- but does not
+ * take into account any time the hardware might take to switch the
+ * clock source.
+ */
+static void _write_clksel_reg(struct clk *clk, u32 field_val)
+{
+ u32 v;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= ~clk->clksel_mask;
+ v |= field_val << __ffs(clk->clksel_mask);
+ __raw_writel(v, clk->clksel_reg);
+
+ v = __raw_readl(clk->clksel_reg); /* OCP barrier */
+}
+
+/**
+ * _clksel_to_divisor() - turn clksel field value into integer divider
+ * @clk: OMAP struct clk to use
+ * @field_val: register field value to find
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a register field
+ * value to search for, find the corresponding clock divisor. The register
+ * field value should be pre-masked and shifted down so the LSB is at bit 0
+ * before calling. Returns 0 on error or returns the actual integer divisor
+ * upon success.
+ */
+static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return 0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->val == field_val)
+ break;
+ }
+
+ if (!clkr->div) {
+ /* This indicates a data error */
+ WARN(1, "clock: Could not find fieldval %d for clock %s parent "
+ "%s\n", field_val, clk->name, clk->parent->name);
+ return 0;
+ }
+
+ return clkr->div;
+}
+
+/**
+ * _divisor_to_clksel() - turn clksel integer divisor into a field value
+ * @clk: OMAP struct clk to use
+ * @div: integer divisor to search for
+ *
+ * Given a struct clk of a rate-selectable clksel clock, and a clock
+ * divisor, find the corresponding register field value. Returns the
+ * register field value _before_ left-shifting (i.e., LSB is at bit
+ * 0); or returns 0xFFFFFFFF (~0) upon error.
+ */
+static u32 _divisor_to_clksel(struct clk *clk, u32 div)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+
+ /* should never happen */
+ WARN_ON(div == 0);
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->div == div)
+ break;
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: Could not find divisor %d for clock %s parent "
+ "%s\n", div, clk->name, clk->parent->name);
+ return ~0;
+ }
+
+ return clkr->val;
+}
+
+/**
+ * _read_divisor() - get current divisor applied to parent clock (from hdwr)
+ * @clk: OMAP struct clk to use.
+ *
+ * Read the current divisor register value for @clk that is programmed
+ * into the hardware, convert it into the actual divisor value, and
+ * return it; or return 0 on error.
+ */
+static u32 _read_divisor(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return 0;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= clk->clksel_mask;
+ v >>= __ffs(clk->clksel_mask);
+
+ return _clksel_to_divisor(clk, v);
+}
+
+/* Public functions */
+
+/**
+ * omap2_clksel_round_rate_div() - find divisor for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ * @new_div: ptr to where we should store the divisor
+ *
+ * Finds 'best' divider value in an array based on the source and target
+ * rates. The divider array must be sorted with smallest divider first.
+ * This function is also used by the DPLL3 M2 divider code.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+ u32 *new_div)
+{
+ unsigned long test_rate;
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 last_div = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return ~0;
+
+ pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
+ clk->name, target_rate);
+
+ *new_div = 1;
+
+ clks = _get_clksel_by_parent(clk, clk->parent);
+ if (!clks)
+ return ~0;
+
+ for (clkr = clks->rates; clkr->div; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ /* Sanity check */
+ if (clkr->div <= last_div)
+ pr_err("clock: clksel_rate table not sorted "
+ "for clock %s", clk->name);
+
+ last_div = clkr->div;
+
+ test_rate = clk->parent->rate / clkr->div;
+
+ if (test_rate <= target_rate)
+ break; /* found it */
+ }
+
+ if (!clkr->div) {
+ pr_err("clock: Could not find divisor for target "
+ "rate %ld for clock %s parent %s\n", target_rate,
+ clk->name, clk->parent->name);
+ return ~0;
+ }
+
+ *new_div = clkr->div;
+
+ pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
+ (clk->parent->rate / clkr->div));
+
+ return clk->parent->rate / clkr->div;
+}
+
+/*
+ * Clocktype interface functions to the OMAP clock code
+ * (i.e., those used in struct clk field function pointers, etc.)
+ */
+
+/**
+ * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Given a pointer @clk to a source-selectable struct clk, read the
+ * hardware register and determine what its parent is currently set
+ * to. Update @clk's .parent field with the appropriate clk ptr. No
+ * return value.
+ */
+void omap2_init_clksel_parent(struct clk *clk)
+{
+ const struct clksel *clks;
+ const struct clksel_rate *clkr;
+ u32 r, found = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return;
+
+ r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
+ r >>= __ffs(clk->clksel_mask);
+
+ for (clks = clk->clksel; clks->parent && !found; clks++) {
+ for (clkr = clks->rates; clkr->div && !found; clkr++) {
+ if (!(clkr->flags & cpu_mask))
+ continue;
+
+ if (clkr->val == r) {
+ if (clk->parent != clks->parent) {
+ pr_debug("clock: inited %s parent "
+ "to %s (was %s)\n",
+ clk->name, clks->parent->name,
+ ((clk->parent) ?
+ clk->parent->name : "NULL"));
+ clk_reparent(clk, clks->parent);
+ };
+ found = 1;
+ }
+ }
+ }
+
+ /* This indicates a data error */
+ WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
+ clk->name, r);
+
+ return;
+}
+
+/**
+ * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
+ * @clk: struct clk *
+ *
+ * This function is intended to be called only by the clock framework.
+ * Each clksel clock should have its struct clk .recalc field set to this
+ * function. Returns the clock's current rate, based on its parent's rate
+ * and its current divisor setting in the hardware.
+ */
+unsigned long omap2_clksel_recalc(struct clk *clk)
+{
+ unsigned long rate;
+ u32 div = 0;
+
+ div = _read_divisor(clk);
+ if (div == 0)
+ return clk->rate;
+
+ rate = clk->parent->rate / div;
+
+ pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name,
+ rate, div);
+
+ return rate;
+}
+
+/**
+ * omap2_clksel_round_rate() - find rounded rate for the given clock and rate
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ *
+ * This function is intended to be called only by the clock framework.
+ * Finds best target rate based on the source clock and possible dividers.
+ * rates. The divider array must be sorted with smallest divider first.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
+ */
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ u32 new_div;
+
+ return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
+}
+
+/**
+ * omap2_clksel_set_rate() - program clock rate in hardware
+ * @clk: struct clk * to program rate
+ * @rate: target rate to program
+ *
+ * This function is intended to be called only by the clock framework.
+ * Program @clk's rate to @rate in the hardware. The clock can be
+ * either enabled or disabled when this happens, although if the clock
+ * is enabled, some downstream devices may glitch or behave
+ * unpredictably when the clock rate is changed - this depends on the
+ * hardware. This function does not currently check the usecount of
+ * the clock, so if multiple drivers are using the clock, and the rate
+ * is changed, they will all be affected without any notification.
+ * Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 field_val, validrate, new_div = 0;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return -EINVAL;
+
+ validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
+ if (validrate != rate)
+ return -EINVAL;
+
+ field_val = _divisor_to_clksel(clk, new_div);
+ if (field_val == ~0)
+ return -EINVAL;
+
+ _write_clksel_reg(clk, field_val);
+
+ clk->rate = clk->parent->rate / new_div;
+
+ pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate);
+
+ return 0;
+}
+
+/*
+ * Clksel parent setting function - not passed in struct clk function
+ * pointer - instead, the OMAP clock code currently assumes that any
+ * parent-setting clock is a clksel clock, and calls
+ * omap2_clksel_set_parent() by default
+ */
+
+/**
+ * omap2_clksel_set_parent() - change a clock's parent clock
+ * @clk: struct clk * of the child clock
+ * @new_parent: struct clk * of the new parent clock
+ *
+ * This function is intended to be called only by the clock framework.
+ * Change the parent clock of clock @clk to @new_parent. This is
+ * intended to be used while @clk is disabled. This function does not
+ * currently check the usecount of the clock, so if multiple drivers
+ * are using the clock, and the parent is changed, they will all be
+ * affected without any notification. Returns -EINVAL upon error, or
+ * 0 upon success.
+ */
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ u32 field_val = 0;
+ u32 parent_div;
+
+ if (!clk->clksel || !clk->clksel_mask)
+ return -EINVAL;
+
+ parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
+ if (!parent_div)
+ return -EINVAL;
+
+ _write_clksel_reg(clk, field_val);
+
+ clk_reparent(clk, new_parent);
+
+ /* CLKSEL clocks follow their parents' rates, divided by a divisor */
+ clk->rate = new_parent->rate;
+
+ if (parent_div > 0)
+ clk->rate /= parent_div;
+
+ pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
+ clk->name, clk->parent->name, clk->rate);
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
new file mode 100644
index 00000000..bcffee00
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -0,0 +1,340 @@
+/*
+ * OMAP2/3/4 DPLL clock functions
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/div64.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* DPLL rate rounding: minimum DPLL multiplier, divider values */
+#define DPLL_MIN_MULTIPLIER 2
+#define DPLL_MIN_DIVIDER 1
+
+/* Possible error results from _dpll_test_mult */
+#define DPLL_MULT_UNDERFLOW -1
+
+/*
+ * Scale factor to mitigate roundoff errors in DPLL rate rounding.
+ * The higher the scale factor, the greater the risk of arithmetic overflow,
+ * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
+ * must be a power of DPLL_SCALE_BASE.
+ */
+#define DPLL_SCALE_FACTOR 64
+#define DPLL_SCALE_BASE 2
+#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
+ (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
+
+/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
+#define DPLL_FINT_BAND1_MIN 750000
+#define DPLL_FINT_BAND1_MAX 2100000
+#define DPLL_FINT_BAND2_MIN 7500000
+#define DPLL_FINT_BAND2_MAX 21000000
+
+/* _dpll_test_fint() return codes */
+#define DPLL_FINT_UNDERFLOW -1
+#define DPLL_FINT_INVALID -2
+
+/* Private functions */
+
+/*
+ * _dpll_test_fint - test whether an Fint value is valid for the DPLL
+ * @clk: DPLL struct clk to test
+ * @n: divider value (N) to test
+ *
+ * Tests whether a particular divider @n will result in a valid DPLL
+ * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
+ * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
+ * (assuming that it is counting N upwards), or -2 if the enclosing loop
+ * should skip to the next iteration (again assuming N is increasing).
+ */
+static int _dpll_test_fint(struct clk *clk, u8 n)
+{
+ struct dpll_data *dd;
+ long fint;
+ int ret = 0;
+
+ dd = clk->dpll_data;
+
+ /* DPLL divider must result in a valid jitter correction val */
+ fint = clk->parent->rate / n;
+ if (fint < DPLL_FINT_BAND1_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "lowering max_divider\n", n);
+ dd->max_divider = n;
+ ret = DPLL_FINT_UNDERFLOW;
+
+ } else if (fint > DPLL_FINT_BAND1_MAX &&
+ fint < DPLL_FINT_BAND2_MIN) {
+
+ pr_debug("rejecting n=%d due to Fint failure\n", n);
+ ret = DPLL_FINT_INVALID;
+
+ } else if (fint > DPLL_FINT_BAND2_MAX) {
+
+ pr_debug("rejecting n=%d due to Fint failure, "
+ "boosting min_divider\n", n);
+ dd->min_divider = n;
+ ret = DPLL_FINT_INVALID;
+
+ }
+
+ return ret;
+}
+
+static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
+ unsigned int m, unsigned int n)
+{
+ unsigned long long num;
+
+ num = (unsigned long long)parent_rate * m;
+ do_div(num, n);
+ return num;
+}
+
+/*
+ * _dpll_test_mult - test a DPLL multiplier value
+ * @m: pointer to the DPLL m (multiplier) value under test
+ * @n: current DPLL n (divider) value under test
+ * @new_rate: pointer to storage for the resulting rounded rate
+ * @target_rate: the desired DPLL rate
+ * @parent_rate: the DPLL's parent clock rate
+ *
+ * This code tests a DPLL multiplier value, ensuring that the
+ * resulting rate will not be higher than the target_rate, and that
+ * the multiplier value itself is valid for the DPLL. Initially, the
+ * integer pointed to by the m argument should be prescaled by
+ * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
+ * a non-scaled m upon return. This non-scaled m will result in a
+ * new_rate as close as possible to target_rate (but not greater than
+ * target_rate) given the current (parent_rate, n, prescaled m)
+ * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
+ * non-scaled m attempted to underflow, which can allow the calling
+ * function to bail out early; or 0 upon success.
+ */
+static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
+ unsigned long target_rate,
+ unsigned long parent_rate)
+{
+ int r = 0, carry = 0;
+
+ /* Unscale m and round if necessary */
+ if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
+ carry = 1;
+ *m = (*m / DPLL_SCALE_FACTOR) + carry;
+
+ /*
+ * The new rate must be <= the target rate to avoid programming
+ * a rate that is impossible for the hardware to handle
+ */
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+ if (*new_rate > target_rate) {
+ (*m)--;
+ *new_rate = 0;
+ }
+
+ /* Guard against m underflow */
+ if (*m < DPLL_MIN_MULTIPLIER) {
+ *m = DPLL_MIN_MULTIPLIER;
+ *new_rate = 0;
+ r = DPLL_MULT_UNDERFLOW;
+ }
+
+ if (*new_rate == 0)
+ *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
+
+ return r;
+}
+
+/* Public functions */
+
+void omap2_init_dpll_parent(struct clk *clk)
+{
+ u32 v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return;
+
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ /* Reparent the struct clk in case the dpll is in bypass */
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ clk_reparent(clk, dd->clk_bypass);
+ }
+ return;
+}
+
+/**
+ * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
+ * @clk: struct clk * of a DPLL
+ *
+ * DPLLs can be locked or bypassed - basically, enabled or disabled.
+ * When locked, the DPLL output depends on the M and N values. When
+ * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
+ * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
+ * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
+ * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
+ * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
+ * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
+ * if the clock @clk is not a DPLL.
+ */
+u32 omap2_get_dpll_rate(struct clk *clk)
+{
+ long long dpll_clk;
+ u32 dpll_mult, dpll_div, v;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return 0;
+
+ /* Return bypass rate if DPLL is bypassed */
+ v = __raw_readl(dd->control_reg);
+ v &= dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+
+ if (cpu_is_omap24xx()) {
+ if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP2XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap34xx()) {
+ if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP3XXX_EN_DPLL_FRBYPASS)
+ return dd->clk_bypass->rate;
+ } else if (cpu_is_omap44xx()) {
+ if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
+ v == OMAP4XXX_EN_DPLL_FRBYPASS ||
+ v == OMAP4XXX_EN_DPLL_MNBYPASS)
+ return dd->clk_bypass->rate;
+ }
+
+ v = __raw_readl(dd->mult_div1_reg);
+ dpll_mult = v & dd->mult_mask;
+ dpll_mult >>= __ffs(dd->mult_mask);
+ dpll_div = v & dd->div1_mask;
+ dpll_div >>= __ffs(dd->div1_mask);
+
+ dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
+ do_div(dpll_clk, dpll_div + 1);
+
+ return dpll_clk;
+}
+
+/* DPLL rate rounding code */
+
+/**
+ * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
+ * @clk: struct clk * for a DPLL
+ * @target_rate: desired DPLL clock rate
+ *
+ * Given a DPLL and a desired target rate, round the target rate to a
+ * possible, programmable rate for this DPLL. Attempts to select the
+ * minimum possible n. Stores the computed (m, n) in the DPLL's
+ * dpll_data structure so set_rate() will not need to call this
+ * (expensive) function again. Returns ~0 if the target rate cannot
+ * be rounded, or the rounded rate upon success.
+ */
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
+{
+ int m, n, r, scaled_max_m;
+ unsigned long scaled_rt_rp;
+ unsigned long new_rate = 0;
+ struct dpll_data *dd;
+
+ if (!clk || !clk->dpll_data)
+ return ~0;
+
+ dd = clk->dpll_data;
+
+ pr_debug("clock: %s: starting DPLL round_rate, target rate %ld\n",
+ clk->name, target_rate);
+
+ scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
+ scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
+
+ dd->last_rounded_rate = 0;
+
+ for (n = dd->min_divider; n <= dd->max_divider; n++) {
+
+ /* Is the (input clk, divider) pair valid for the DPLL? */
+ r = _dpll_test_fint(clk, n);
+ if (r == DPLL_FINT_UNDERFLOW)
+ break;
+ else if (r == DPLL_FINT_INVALID)
+ continue;
+
+ /* Compute the scaled DPLL multiplier, based on the divider */
+ m = scaled_rt_rp * n;
+
+ /*
+ * Since we're counting n up, a m overflow means we
+ * can bail out completely (since as n increases in
+ * the next iteration, there's no way that m can
+ * increase beyond the current m)
+ */
+ if (m > scaled_max_m)
+ break;
+
+ r = _dpll_test_mult(&m, n, &new_rate, target_rate,
+ dd->clk_ref->rate);
+
+ /* m can't be set low enough for this n - try with a larger n */
+ if (r == DPLL_MULT_UNDERFLOW)
+ continue;
+
+ pr_debug("clock: %s: m = %d: n = %d: new_rate = %ld\n",
+ clk->name, m, n, new_rate);
+
+ if (target_rate == new_rate) {
+ dd->last_rounded_m = m;
+ dd->last_rounded_n = n;
+ dd->last_rounded_rate = target_rate;
+ break;
+ }
+ }
+
+ if (target_rate != new_rate) {
+ pr_debug("clock: %s: cannot round to rate %ld\n", clk->name,
+ target_rate);
+ return ~0;
+ }
+
+ return target_rate;
+}
+
diff --git a/arch/arm/mach-omap2/clkt_iclk.c b/arch/arm/mach-omap2/clkt_iclk.c
new file mode 100644
index 00000000..3d43fba2
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_iclk.c
@@ -0,0 +1,82 @@
+/*
+ * OMAP2/3 interface clock control
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/* Private functions */
+
+/* XXX */
+void omap2_clkt_iclk_allow_idle(struct clk *clk)
+{
+ u32 v, r;
+
+ r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = __raw_readl((__force void __iomem *)r);
+ v |= (1 << clk->enable_bit);
+ __raw_writel(v, (__force void __iomem *)r);
+}
+
+/* XXX */
+void omap2_clkt_iclk_deny_idle(struct clk *clk)
+{
+ u32 v, r;
+
+ r = ((__force u32)clk->enable_reg ^ (CM_AUTOIDLE ^ CM_ICLKEN));
+
+ v = __raw_readl((__force void __iomem *)r);
+ v &= ~(1 << clk->enable_bit);
+ __raw_writel(v, (__force void __iomem *)r);
+}
+
+/* Public data */
+
+const struct clkops clkops_omap2_iclk_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_dflt = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_iclk_idle_only = {
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+const struct clkops clkops_omap2_mdmclk_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
new file mode 100644
index 00000000..180299e4
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.c
@@ -0,0 +1,523 @@
+/*
+ * linux/arch/arm/mach-omap2/clock.c
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <trace/events/power.h>
+
+#include <asm/cpu.h>
+#include <plat/clock.h>
+#include "clockdomain.h"
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+u8 cpu_mask;
+
+/*
+ * OMAP2+ specific clock functions
+ */
+
+/* Private functions */
+
+/**
+ * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE
+ * @clk: struct clk * belonging to the module
+ *
+ * If the necessary clocks for the OMAP hardware IP block that
+ * corresponds to clock @clk are enabled, then wait for the module to
+ * indicate readiness (i.e., to leave IDLE). This code does not
+ * belong in the clock code and will be moved in the medium term to
+ * module-dependent code. No return value.
+ */
+static void _omap2_module_wait_ready(struct clk *clk)
+{
+ void __iomem *companion_reg, *idlest_reg;
+ u8 other_bit, idlest_bit, idlest_val;
+
+ /* Not all modules have multiple clocks that their IDLEST depends on */
+ if (clk->ops->find_companion) {
+ clk->ops->find_companion(clk, &companion_reg, &other_bit);
+ if (!(__raw_readl(companion_reg) & (1 << other_bit)))
+ return;
+ }
+
+ clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);
+
+ omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,
+ clk->name);
+}
+
+/* Public functions */
+
+/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk. Intended to be
+ * called during clk_register(). No return value.
+ */
+void omap2_init_clk_clkdm(struct clk *clk)
+{
+ struct clockdomain *clkdm;
+
+ if (!clk->clkdm_name)
+ return;
+
+ clkdm = clkdm_lookup(clk->clkdm_name);
+ if (clkdm) {
+ pr_debug("clock: associated clk %s to clkdm %s\n",
+ clk->name, clk->clkdm_name);
+ clk->clkdm = clkdm;
+ } else {
+ pr_debug("clock: could not associate clk %s to "
+ "clkdm %s\n", clk->name, clk->clkdm_name);
+ }
+}
+
+/**
+ * omap2_clk_dflt_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Note: We don't need special code here for INVERT_ENABLE for the
+ * time being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL
+ *
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's
+ * just a matter of XORing the bits.
+ *
+ * Some clocks don't have companion clocks. For example, modules with
+ * only an interface clock (such as MAILBOXES) don't have a companion
+ * clock. Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active. Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts. No return value.
+ */
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+ u8 *other_bit)
+{
+ u32 r;
+
+ /*
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
+ * it's just a matter of XORing the bits.
+ */
+ r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));
+
+ *other_reg = (__force void __iomem *)r;
+ *other_bit = clk->enable_bit;
+}
+
+/**
+ * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
+ * @clk: struct clk * to find IDLEST info for
+ * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
+ * @idlest_bit: u8 * to return the CM_IDLEST bit shift in
+ * @idlest_val: u8 * to return the idle status indicator
+ *
+ * Return the CM_IDLEST register address and bit shift corresponding
+ * to the module that "owns" this clock. This default code assumes
+ * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that
+ * the IDLEST register address ID corresponds to the CM_*CLKEN
+ * register address ID (e.g., that CM_FCLKEN2 corresponds to
+ * CM_IDLEST2). This is not true for all modules. No return value.
+ */
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ *idlest_bit = clk->enable_bit;
+
+ /*
+ * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
+ * 34xx reverses this, just to keep us on our toes
+ * AM35xx uses both, depending on the module.
+ */
+ if (cpu_is_omap24xx())
+ *idlest_val = OMAP24XX_CM_IDLEST_VAL;
+ else if (cpu_is_omap34xx())
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+ else
+ BUG();
+
+}
+
+int omap2_dflt_clk_enable(struct clk *clk)
+{
+ u32 v;
+
+ if (unlikely(clk->enable_reg == NULL)) {
+ pr_err("clock.c: Enable for %s without enable code\n",
+ clk->name);
+ return 0; /* REVISIT: -EINVAL */
+ }
+
+ v = __raw_readl(clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v &= ~(1 << clk->enable_bit);
+ else
+ v |= (1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ v = __raw_readl(clk->enable_reg); /* OCP barrier */
+
+ if (clk->ops->find_idlest)
+ _omap2_module_wait_ready(clk);
+
+ return 0;
+}
+
+void omap2_dflt_clk_disable(struct clk *clk)
+{
+ u32 v;
+
+ if (!clk->enable_reg) {
+ /*
+ * 'Independent' here refers to a clock which is not
+ * controlled by its parent.
+ */
+ printk(KERN_ERR "clock: clk_disable called on independent "
+ "clock %s which has no enable_reg\n", clk->name);
+ return;
+ }
+
+ v = __raw_readl(clk->enable_reg);
+ if (clk->flags & INVERT_ENABLE)
+ v |= (1 << clk->enable_bit);
+ else
+ v &= ~(1 << clk->enable_bit);
+ __raw_writel(v, clk->enable_reg);
+ /* No OCP barrier needed here since it is a disable operation */
+}
+
+const struct clkops clkops_omap2_dflt_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+};
+
+const struct clkops clkops_omap2_dflt = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+};
+
+/**
+ * omap2_clk_disable - disable a clock, if the system is not using it
+ * @clk: struct clk * to disable
+ *
+ * Decrements the usecount on struct clk @clk. If there are no users
+ * left, call the clkops-specific clock disable function to disable it
+ * in hardware. If the clock is part of a clockdomain (which they all
+ * should be), request that the clockdomain be disabled. (It too has
+ * a usecount, and so will not be disabled in the hardware until it no
+ * longer has any users.) If the clock has a parent clock (most of
+ * them do), then call ourselves, recursing on the parent clock. This
+ * can cause an entire branch of the clock tree to be powered off by
+ * simply disabling one clock. Intended to be called with the clockfw_lock
+ * spinlock held. No return value.
+ */
+void omap2_clk_disable(struct clk *clk)
+{
+ if (clk->usecount == 0) {
+ WARN(1, "clock: %s: omap2_clk_disable() called, but usecount "
+ "already 0?", clk->name);
+ return;
+ }
+
+ pr_debug("clock: %s: decrementing usecount\n", clk->name);
+
+ clk->usecount--;
+
+ if (clk->usecount > 0)
+ return;
+
+ pr_debug("clock: %s: disabling in hardware\n", clk->name);
+
+ if (clk->ops && clk->ops->disable) {
+ trace_clock_disable(clk->name, 0, smp_processor_id());
+ clk->ops->disable(clk);
+ }
+
+ if (clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, clk);
+
+ if (clk->parent)
+ omap2_clk_disable(clk->parent);
+}
+
+/**
+ * omap2_clk_enable - request that the system enable a clock
+ * @clk: struct clk * to enable
+ *
+ * Increments the usecount on struct clk @clk. If there were no users
+ * previously, then recurse up the clock tree, enabling all of the
+ * clock's parents and all of the parent clockdomains, and finally,
+ * enabling @clk's clockdomain, and @clk itself. Intended to be
+ * called with the clockfw_lock spinlock held. Returns 0 upon success
+ * or a negative error code upon failure.
+ */
+int omap2_clk_enable(struct clk *clk)
+{
+ int ret;
+
+ pr_debug("clock: %s: incrementing usecount\n", clk->name);
+
+ clk->usecount++;
+
+ if (clk->usecount > 1)
+ return 0;
+
+ pr_debug("clock: %s: enabling in hardware\n", clk->name);
+
+ if (clk->parent) {
+ ret = omap2_clk_enable(clk->parent);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable parent %s: %d\n",
+ clk->name, clk->parent->name, ret);
+ goto oce_err1;
+ }
+ }
+
+ if (clk->clkdm) {
+ ret = clkdm_clk_enable(clk->clkdm, clk);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable clockdomain %s: "
+ "%d\n", clk->name, clk->clkdm->name, ret);
+ goto oce_err2;
+ }
+ }
+
+ if (clk->ops && clk->ops->enable) {
+ trace_clock_enable(clk->name, 1, smp_processor_id());
+ ret = clk->ops->enable(clk);
+ if (ret) {
+ WARN(1, "clock: %s: could not enable: %d\n",
+ clk->name, ret);
+ goto oce_err3;
+ }
+ }
+
+ return 0;
+
+oce_err3:
+ if (clk->clkdm)
+ clkdm_clk_disable(clk->clkdm, clk);
+oce_err2:
+ if (clk->parent)
+ omap2_clk_disable(clk->parent);
+oce_err1:
+ clk->usecount--;
+
+ return ret;
+}
+
+/* Given a clock and a rate apply a clock specific rounding function */
+long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+
+/* Set the clock rate for a clock source */
+int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);
+
+ /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
+ if (clk->set_rate) {
+ trace_clock_set_rate(clk->name, rate, smp_processor_id());
+ ret = clk->set_rate(clk, rate);
+ }
+
+ return ret;
+}
+
+int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
+{
+ if (!clk->clksel)
+ return -EINVAL;
+
+ if (clk->parent == new_parent)
+ return 0;
+
+ return omap2_clksel_set_parent(clk, new_parent);
+}
+
+/* OMAP3/4 non-CORE DPLL clkops */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+
+const struct clkops clkops_omap3_noncore_dpll_ops = {
+ .enable = omap3_noncore_dpll_enable,
+ .disable = omap3_noncore_dpll_disable,
+ .allow_idle = omap3_dpll_allow_idle,
+ .deny_idle = omap3_dpll_deny_idle,
+};
+
+const struct clkops clkops_omap3_core_dpll_ops = {
+ .allow_idle = omap3_dpll_allow_idle,
+ .deny_idle = omap3_dpll_deny_idle,
+};
+
+#endif
+
+/*
+ * OMAP2+ clock reset and init functions
+ */
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+void omap2_clk_disable_unused(struct clk *clk)
+{
+ u32 regval32, v;
+
+ v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;
+
+ regval32 = __raw_readl(clk->enable_reg);
+ if ((regval32 & (1 << clk->enable_bit)) == v)
+ return;
+
+ pr_debug("Disabling unused clock \"%s\"\n", clk->name);
+ if (cpu_is_omap34xx()) {
+ omap2_clk_enable(clk);
+ omap2_clk_disable(clk);
+ } else {
+ clk->ops->disable(clk);
+ }
+ if (clk->clkdm != NULL)
+ pwrdm_clkdm_state_switch(clk->clkdm);
+}
+#endif
+
+/**
+ * omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument
+ * @mpurate_ck_name: clk name of the clock to change rate
+ *
+ * Change the ARM MPU clock rate to the rate specified on the command
+ * line, if one was specified. @mpurate_ck_name should be
+ * "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx.
+ * XXX Does not handle voltage scaling - on OMAP2xxx this is currently
+ * handled by the virt_prcm_set clock, but this should be handled by
+ * the OPP layer. XXX This is intended to be handled by the OPP layer
+ * code in the near future and should be removed from the clock code.
+ * Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects
+ * the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name
+ * cannot be found, or 0 upon success.
+ */
+int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)
+{
+ struct clk *mpurate_ck;
+ int r;
+
+ if (!mpurate)
+ return -EINVAL;
+
+ mpurate_ck = clk_get(NULL, mpurate_ck_name);
+ if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name))
+ return -ENOENT;
+
+ r = clk_set_rate(mpurate_ck, mpurate);
+ if (IS_ERR_VALUE(r)) {
+ WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",
+ mpurate_ck->name, mpurate, r);
+ return -EINVAL;
+ }
+
+ calibrate_delay();
+ recalculate_root_clocks();
+
+ clk_put(mpurate_ck);
+
+ return 0;
+}
+
+/**
+ * omap2_clk_print_new_rates - print summary of current clock tree rates
+ * @hfclkin_ck_name: clk name for the off-chip HF oscillator
+ * @core_ck_name: clk name for the on-chip CORE_CLK
+ * @mpu_ck_name: clk name for the ARM MPU clock
+ *
+ * Prints a short message to the console with the HFCLKIN oscillator
+ * rate, the rate of the CORE clock, and the rate of the ARM MPU clock.
+ * Called by the boot-time MPU rate switching code. XXX This is intended
+ * to be handled by the OPP layer code in the near future and should be
+ * removed from the clock code. No return value.
+ */
+void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+ const char *core_ck_name,
+ const char *mpu_ck_name)
+{
+ struct clk *hfclkin_ck, *core_ck, *mpu_ck;
+ unsigned long hfclkin_rate;
+
+ mpu_ck = clk_get(NULL, mpu_ck_name);
+ if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name))
+ return;
+
+ core_ck = clk_get(NULL, core_ck_name);
+ if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name))
+ return;
+
+ hfclkin_ck = clk_get(NULL, hfclkin_ck_name);
+ if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name))
+ return;
+
+ hfclkin_rate = clk_get_rate(hfclkin_ck);
+
+ pr_info("Switched to new clocking rate (Crystal/Core/MPU): "
+ "%ld.%01ld/%ld/%ld MHz\n",
+ (hfclkin_rate / 1000000),
+ ((hfclkin_rate / 100000) % 10),
+ (clk_get_rate(core_ck) / 1000000),
+ (clk_get_rate(mpu_ck) / 1000000));
+}
+
+/* Common data */
+
+struct clk_functions omap2_clk_functions = {
+ .clk_enable = omap2_clk_enable,
+ .clk_disable = omap2_clk_disable,
+ .clk_round_rate = omap2_clk_round_rate,
+ .clk_set_rate = omap2_clk_set_rate,
+ .clk_set_parent = omap2_clk_set_parent,
+ .clk_disable_unused = omap2_clk_disable_unused,
+#ifdef CONFIG_CPU_FREQ
+ /* These will be removed when the OPP code is integrated */
+ .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,
+ .clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,
+#endif
+};
+
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
new file mode 100644
index 00000000..e10ff2b5
--- /dev/null
+++ b/arch/arm/mach-omap2/clock.h
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/arm/mach-omap2/clock.h
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK_H
+
+#include <plat/clock.h>
+
+/* CM_CLKSEL2_PLL.CORE_CLK_SRC bits (2XXX) */
+#define CORE_CLK_SRC_32K 0x0
+#define CORE_CLK_SRC_DPLL 0x1
+#define CORE_CLK_SRC_DPLL_X2 0x2
+
+/* OMAP2xxx CM_CLKEN_PLL.EN_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP2XXX_EN_DPLL_LPBYPASS 0x1
+#define OMAP2XXX_EN_DPLL_FRBYPASS 0x2
+#define OMAP2XXX_EN_DPLL_LOCKED 0x3
+
+/* OMAP3xxx CM_CLKEN_PLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP3XXX_EN_DPLL_LPBYPASS 0x5
+#define OMAP3XXX_EN_DPLL_FRBYPASS 0x6
+#define OMAP3XXX_EN_DPLL_LOCKED 0x7
+
+/* OMAP4xxx CM_CLKMODE_DPLL*.EN_*_DPLL bits - for omap2_get_dpll_rate() */
+#define OMAP4XXX_EN_DPLL_MNBYPASS 0x4
+#define OMAP4XXX_EN_DPLL_LPBYPASS 0x5
+#define OMAP4XXX_EN_DPLL_FRBYPASS 0x6
+#define OMAP4XXX_EN_DPLL_LOCKED 0x7
+
+/* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */
+#define DPLL_LOW_POWER_STOP 0x1
+#define DPLL_LOW_POWER_BYPASS 0x5
+#define DPLL_LOCKED 0x7
+
+/* DPLL Type and DCO Selection Flags */
+#define DPLL_J_TYPE 0x1
+
+int omap2_clk_enable(struct clk *clk);
+void omap2_clk_disable(struct clk *clk);
+long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
+int omap2_clk_set_rate(struct clk *clk, unsigned long rate);
+int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent);
+long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate);
+unsigned long omap3_dpll_recalc(struct clk *clk);
+unsigned long omap3_clkoutx2_recalc(struct clk *clk);
+void omap3_dpll_allow_idle(struct clk *clk);
+void omap3_dpll_deny_idle(struct clk *clk);
+u32 omap3_dpll_autoidle_read(struct clk *clk);
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
+int omap3_noncore_dpll_enable(struct clk *clk);
+void omap3_noncore_dpll_disable(struct clk *clk);
+int omap4_dpllmx_gatectrl_read(struct clk *clk);
+void omap4_dpllmx_allow_gatectrl(struct clk *clk);
+void omap4_dpllmx_deny_gatectrl(struct clk *clk);
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+void omap2_clk_disable_unused(struct clk *clk);
+#else
+#define omap2_clk_disable_unused NULL
+#endif
+
+void omap2_init_clk_clkdm(struct clk *clk);
+
+/* clkt_clksel.c public functions */
+u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
+ u32 *new_div);
+void omap2_init_clksel_parent(struct clk *clk);
+unsigned long omap2_clksel_recalc(struct clk *clk);
+long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
+int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
+int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
+
+/* clkt_iclk.c public functions */
+extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
+extern void omap2_clkt_iclk_deny_idle(struct clk *clk);
+
+u32 omap2_get_dpll_rate(struct clk *clk);
+void omap2_init_dpll_parent(struct clk *clk);
+
+int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
+
+
+#ifdef CONFIG_ARCH_OMAP2
+void omap2xxx_clk_prepare_for_reboot(void);
+#else
+static inline void omap2xxx_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void omap3_clk_prepare_for_reboot(void);
+#else
+static inline void omap3_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void omap4_clk_prepare_for_reboot(void);
+#else
+static inline void omap4_clk_prepare_for_reboot(void)
+{
+}
+#endif
+
+int omap2_dflt_clk_enable(struct clk *clk);
+void omap2_dflt_clk_disable(struct clk *clk);
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+ u8 *other_bit);
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+ u8 *idlest_bit, u8 *idlest_val);
+int omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name);
+void omap2_clk_print_new_rates(const char *hfclkin_ck_name,
+ const char *core_ck_name,
+ const char *mpu_ck_name);
+
+extern u8 cpu_mask;
+
+extern const struct clkops clkops_omap2_dflt_wait;
+extern const struct clkops clkops_dummy;
+extern const struct clkops clkops_omap2_dflt;
+
+extern struct clk_functions omap2_clk_functions;
+extern struct clk *vclk, *sclk;
+
+extern const struct clksel_rate gpt_32k_rates[];
+extern const struct clksel_rate gpt_sys_rates[];
+extern const struct clksel_rate gfx_l3_rates[];
+extern const struct clksel_rate dsp_ick_rates[];
+
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ)
+extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#else
+#define omap2_clk_init_cpufreq_table 0
+#define omap2_clk_exit_cpufreq_table 0
+#endif
+
+extern const struct clkops clkops_omap2_iclk_dflt_wait;
+extern const struct clkops clkops_omap2_iclk_dflt;
+extern const struct clkops clkops_omap2_iclk_idle_only;
+extern const struct clkops clkops_omap2_mdmclk_dflt_wait;
+extern const struct clkops clkops_omap2xxx_dpll_ops;
+extern const struct clkops clkops_omap3_noncore_dpll_ops;
+extern const struct clkops clkops_omap3_core_dpll_ops;
+extern const struct clkops clkops_omap4_dpllmx_ops;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
new file mode 100644
index 00000000..2926d028
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -0,0 +1,1970 @@
+/*
+ * OMAP2420 clock data
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define OMAP_CM_REGADDR OMAP2420_CM_REGADDR
+
+/*
+ * 2420 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ * many cases the parent is selectable. The set parent calls will
+ * also switch sources.
+ *
+ * Several sources are given initial rates which may be wrong, this will
+ * be fixed up in the init func.
+ *
+ * Things are broadly separated below by clock domains. It is
+ * noteworthy that most peripherals have dependencies on multiple clock
+ * domains. Many get their interface clocks from the L4 domain, but get
+ * functional clocks from fixed sources or other core domain derived
+ * clocks.
+ */
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+ .name = "func_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+ .name = "secure_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
+ .name = "osc_ck",
+ .ops = &clkops_oscck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
+ .name = "sys_ck", /* ~ ref_clk also */
+ .ops = &clkops_null,
+ .parent = &osc_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2xxx_sys_clk_recalc,
+};
+
+static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
+ .name = "alt_ck",
+ .ops = &clkops_null,
+ .rate = 54000000,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change. ...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .mult_mask = OMAP24XX_DPLL_MULT_MASK,
+ .div1_mask = OMAP24XX_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP24XX_EN_DPLL_MASK,
+ .max_multiplier = 1023,
+ .min_divider = 1,
+ .max_divider = 16,
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+ .name = "dpll_ck",
+ .ops = &clkops_omap2xxx_dpll_ops,
+ .parent = &sys_ck, /* Can be func_32k also */
+ .dpll_data = &dpll_dd,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_dpllcore_recalc,
+ .set_rate = &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+ .name = "apll96_ck",
+ .ops = &clkops_apll96,
+ .parent = &sys_ck,
+ .rate = 96000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+ .name = "apll54_ck",
+ .ops = &clkops_apll54,
+ .parent = &sys_ck,
+ .rate = 54000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+ { .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+ { .parent = &alt_ck, .rates = func_54m_alt_rates, },
+ { .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+ .name = "func_54m_ck",
+ .ops = &clkops_null,
+ .parent = &apll54_ck, /* can also be alt_clk */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_54M_SOURCE_MASK,
+ .clksel = func_54m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+ .name = "core_ck",
+ .ops = &clkops_null,
+ .parent = &dpll_ck, /* can also be 32k */
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk func_96m_ck = {
+ .name = "func_96m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+ { .div = 2, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+ { .parent = &apll96_ck, .rates = func_48m_apll96_rates },
+ { .parent = &alt_ck, .rates = func_48m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+ .name = "func_48m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck, /* 96M or Alt */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_48M_SOURCE_MASK,
+ .clksel = func_48m_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+ .name = "func_12m_ck",
+ .ops = &clkops_null,
+ .parent = &func_48m_ck,
+ .fixed_div = 4,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+ .name = "ck_wdt1_osc",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &osc_ck,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+ { .parent = &core_ck, .rates = common_clkout_src_core_rates },
+ { .parent = &sys_ck, .rates = common_clkout_src_sys_rates },
+ { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+ { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+ .name = "sys_clkout_src",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .enable_bit = OMAP24XX_CLKOUT_EN_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_SOURCE_MASK,
+ .clksel = common_clkout_src_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 16, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+ { .parent = &sys_clkout_src, .rates = common_clkout_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+ .name = "sys_clkout",
+ .ops = &clkops_null,
+ .parent = &sys_clkout_src,
+ .clkdm_name = "wkup_clkdm",
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_DIV_MASK,
+ .clksel = sys_clkout_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2_src = {
+ .name = "sys_clkout2_src",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .enable_bit = OMAP2420_CLKOUT2_EN_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP2420_CLKOUT2_SOURCE_MASK,
+ .clksel = common_clkout_src_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+ { .parent = &sys_clkout2_src, .rates = common_clkout_rates },
+ { .parent = NULL }
+};
+
+/* In 2430, new in 2420 ES2 */
+static struct clk sys_clkout2 = {
+ .name = "sys_clkout2",
+ .ops = &clkops_null,
+ .parent = &sys_clkout2_src,
+ .clkdm_name = "wkup_clkdm",
+ .clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP2420_CLKOUT2_DIV_MASK,
+ .clksel = sys_clkout2_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+ .name = "emul_ck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2420_PRCM_CLKEMUL_CTRL,
+ .enable_bit = OMAP24XX_EMULATION_EN_SHIFT,
+ .recalc = &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ * Clocks:
+ * MPU_FCLK, MPU_ICLK
+ * INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_242X },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+ { .parent = &core_ck, .rates = mpu_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk mpu_ck = { /* Control cpu */
+ .name = "mpu_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "mpu_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_MPU_MASK,
+ .clksel = mpu_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2420-UMA+IVA1) clock domain
+ * Clocks:
+ * 2420: UMA_FCLK, UMA_ICLK, IVA_MPU, IVA_COP
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 12, .val = 12, .flags = RATE_IN_242X },
+ { .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+ { .parent = &core_ck, .rates = dsp_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_MASK,
+ .clksel = dsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel dsp_ick_clksel[] = {
+ { .parent = &dsp_fck, .rates = dsp_ick_rates },
+ { .parent = NULL }
+};
+
+static struct clk dsp_ick = {
+ .name = "dsp_ick", /* apparently ipi and isp */
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &dsp_fck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP2420_EN_DSP_IPI_SHIFT, /* for ipi */
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
+ .clksel = dsp_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain. Does not
+ * exist on later OMAPs.
+ */
+static struct clk iva1_ifck = {
+ .name = "iva1_ifck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "iva1_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP2420_EN_IVA_COP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP2420_CLKSEL_IVA_MASK,
+ .clksel = dsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* IVA1 mpu/int/i/f clocks are /2 of parent */
+static struct clk iva1_mpu_int_ifck = {
+ .name = "iva1_mpu_int_ifck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &iva1_ifck,
+ .clkdm_name = "iva1_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP2420_EN_IVA_MPU_SHIFT,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ * CAM, HS-USB.
+ * F-CLOCK
+ * SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_242X },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 12, .val = 12, .flags = RATE_IN_242X },
+ { .div = 16, .val = 16, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+ { .parent = &core_ck, .rates = core_l3_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
+ .name = "core_l3_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L3_MASK,
+ .clksel = core_l3_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+ { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+ { .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = { /* FS-USB interface clock */
+ .name = "usb_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_USB_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_USB_MASK,
+ .clksel = usb_l4_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks. Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+ { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+ { .parent = NULL }
+};
+
+static struct clk l4_ck = { /* used both as an ick and fck */
+ .name = "l4_ck",
+ .ops = &clkops_null,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
+ .clksel = l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+ { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+ .name = "ssi_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_SSI_MASK,
+ .clksel = ssi_ssr_sst_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ * Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+ { .parent = &core_l3_ck, .rates = gfx_l3_rates },
+ { .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+ .name = "gfx_3d_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_3D_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP_CLKSEL_GFX_MASK,
+ .clksel = gfx_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk gfx_2d_fck = {
+ .name = "gfx_2d_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_2D_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP_CLKSEL_GFX_MASK,
+ .clksel = gfx_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* This interface clock does not have a CM_AUTOIDLE bit */
+static struct clk gfx_ick = {
+ .name = "gfx_ick", /* From l3 */
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+ .enable_bit = OMAP_EN_GFX_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+/* XXX Add RATE_NOT_VALIDATED */
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_24XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_24XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_24XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+ { .parent = &sys_ck, .rates = dss1_fck_sys_rates },
+ { .parent = &core_ck, .rates = dss1_fck_core_rates },
+ { .parent = NULL },
+};
+
+static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
+ .name = "dss_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ck, /* really both l3 and l4 */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+ .name = "dss1_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &core_ck, /* Core or sys */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_DSS1_MASK,
+ .clksel = dss1_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel dss2_fck_clksel[] = {
+ { .parent = &sys_ck, .rates = dss2_fck_sys_rates },
+ { .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+ { .parent = NULL }
+};
+
+static struct clk dss2_fck = { /* Alt clk used in power management */
+ .name = "dss2_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &sys_ck, /* fixed at sys_ck or 48MHz */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS2_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_DSS2_MASK,
+ .clksel = dss2_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk dss_54m_fck = { /* Alt clk used in power management */
+ .name = "dss_54m_fck", /* 54m tv clk */
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_54m_ck,
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_TV_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wu_l4_ick = {
+ .name = "wu_l4_ick",
+ .ops = &clkops_null,
+ .parent = &sys_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static const struct clksel_rate gpt_alt_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+ { .parent = &func_32k_ck, .rates = gpt_32k_rates },
+ { .parent = &sys_ck, .rates = gpt_sys_rates },
+ { .parent = &alt_ck, .rates = gpt_alt_rates },
+ { .parent = NULL },
+};
+
+static struct clk gpt1_ick = {
+ .name = "gpt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+ .name = "gpt1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT1_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk gpt2_ick = {
+ .name = "gpt2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+ .name = "gpt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT2_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_ick = {
+ .name = "gpt3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+ .name = "gpt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT3_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_ick = {
+ .name = "gpt4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+ .name = "gpt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT4_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_ick = {
+ .name = "gpt5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+ .name = "gpt5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT5_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_ick = {
+ .name = "gpt6_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+ .name = "gpt6_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT6_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_ick = {
+ .name = "gpt7_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+ .name = "gpt7_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT7_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_ick = {
+ .name = "gpt8_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+ .name = "gpt8_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT8_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_ick = {
+ .name = "gpt9_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+ .name = "gpt9_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT9_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt10_ick = {
+ .name = "gpt10_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+ .name = "gpt10_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT10_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_ick = {
+ .name = "gpt11_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+ .name = "gpt11_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT11_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt12_ick = {
+ .name = "gpt12_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+ .name = "gpt12_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &secure_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT12_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+ .name = "mcbsp1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+ { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
+static struct clk mcbsp1_fck = {
+ .name = "mcbsp1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .clksel_reg = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+ .name = "mcbsp2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+ .name = "mcbsp2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .clksel_reg = OMAP242X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcspi1_ick = {
+ .name = "mcspi1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+ .name = "mcspi1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+ .name = "mcspi2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+ .name = "mcspi2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+ .name = "uart1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_UART1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+ .name = "uart1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_UART1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+ .name = "uart2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_UART2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+ .name = "uart2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_UART2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+ .name = "uart3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_UART3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+ .name = "uart3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_UART3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+ .name = "gpios_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+ .name = "gpios_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+ .name = "mpu_wdt_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+ .name = "mpu_wdt_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+ .name = "sync_32k_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .flags = ENABLE_ON_INIT,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+ .name = "wdt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_WDT1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+ .name = "omapctrl_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .flags = ENABLE_ON_INIT,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+ .name = "cam_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_CAM_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK. It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
+static struct clk cam_fck = {
+ .name = "cam_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_CAM_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+ .name = "mailboxes_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+ .name = "wdt4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_WDT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+ .name = "wdt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_WDT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+ .name = "wdt3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_WDT3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+ .name = "wdt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_WDT3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+ .name = "mspro_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+ .name = "mspro_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmc_ick = {
+ .name = "mmc_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_MMC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmc_fck = {
+ .name = "mmc_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_MMC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+ .name = "fac_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_FAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fac_fck = {
+ .name = "fac_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_FAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk eac_ick = {
+ .name = "eac_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_EAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk eac_fck = {
+ .name = "eac_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_EAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+ .name = "hdq_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+ .name = "hdq_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+ .name = "i2c2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_I2C2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+ .name = "i2c2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_I2C2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+ .name = "i2c1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_I2C1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+ .name = "i2c1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_I2C1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk gpmc_fck = {
+ .name = "gpmc_fck",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sdma_fck = {
+ .name = "sdma_fck",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk sdma_ick = {
+ .name = "sdma_ick",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk sdrc_ick = {
+ .name = "sdrc_ick",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP24XX_AUTO_SDRC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk vlynq_ick = {
+ .name = "vlynq_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate vlynq_fck_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel_rate vlynq_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_242X },
+ { .div = 2, .val = 2, .flags = RATE_IN_242X },
+ { .div = 3, .val = 3, .flags = RATE_IN_242X },
+ { .div = 4, .val = 4, .flags = RATE_IN_242X },
+ { .div = 6, .val = 6, .flags = RATE_IN_242X },
+ { .div = 8, .val = 8, .flags = RATE_IN_242X },
+ { .div = 9, .val = 9, .flags = RATE_IN_242X },
+ { .div = 12, .val = 12, .flags = RATE_IN_242X },
+ { .div = 16, .val = 16, .flags = RATE_IN_242X },
+ { .div = 18, .val = 18, .flags = RATE_IN_242X },
+ { .div = 0 }
+};
+
+static const struct clksel vlynq_fck_clksel[] = {
+ { .parent = &func_96m_ck, .rates = vlynq_fck_96m_rates },
+ { .parent = &core_ck, .rates = vlynq_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk vlynq_fck = {
+ .name = "vlynq_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP2420_CLKSEL_VLYNQ_MASK,
+ .clksel = vlynq_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk des_ick = {
+ .name = "des_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_DES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sha_ick = {
+ .name = "sha_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_SHA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+ .name = "rng_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_RNG_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aes_ick = {
+ .name = "aes_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_AES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+ .name = "pka_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_PKA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_fck = {
+ .name = "usb_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_USB_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+ .name = "virt_prcm_set",
+ .ops = &clkops_null,
+ .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
+ .recalc = &omap2_table_mpu_recalc, /* sets are keyed on mpu rate */
+ .set_rate = &omap2_select_table_rate,
+ .round_rate = &omap2_round_to_table_rate,
+};
+
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2420_clks[] = {
+ /* external root sources */
+ CLK(NULL, "func_32k_ck", &func_32k_ck, CK_242X),
+ CLK(NULL, "secure_32k_ck", &secure_32k_ck, CK_242X),
+ CLK(NULL, "osc_ck", &osc_ck, CK_242X),
+ CLK(NULL, "sys_ck", &sys_ck, CK_242X),
+ CLK(NULL, "alt_ck", &alt_ck, CK_242X),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_242X),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_242X),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_242X),
+ /* internal analog sources */
+ CLK(NULL, "dpll_ck", &dpll_ck, CK_242X),
+ CLK(NULL, "apll96_ck", &apll96_ck, CK_242X),
+ CLK(NULL, "apll54_ck", &apll54_ck, CK_242X),
+ /* internal prcm root sources */
+ CLK(NULL, "func_54m_ck", &func_54m_ck, CK_242X),
+ CLK(NULL, "core_ck", &core_ck, CK_242X),
+ CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_242X),
+ CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_242X),
+ CLK(NULL, "func_96m_ck", &func_96m_ck, CK_242X),
+ CLK(NULL, "func_48m_ck", &func_48m_ck, CK_242X),
+ CLK(NULL, "func_12m_ck", &func_12m_ck, CK_242X),
+ CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_242X),
+ CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_242X),
+ CLK(NULL, "sys_clkout", &sys_clkout, CK_242X),
+ CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X),
+ CLK(NULL, "sys_clkout2", &sys_clkout2, CK_242X),
+ CLK(NULL, "emul_ck", &emul_ck, CK_242X),
+ /* mpu domain clocks */
+ CLK(NULL, "mpu_ck", &mpu_ck, CK_242X),
+ /* dsp domain clocks */
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_242X),
+ CLK(NULL, "dsp_ick", &dsp_ick, CK_242X),
+ CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X),
+ CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X),
+ /* GFX domain clocks */
+ CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_242X),
+ CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X),
+ CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
+ /* DSS domain clocks */
+ CLK("omapdss_dss", "ick", &dss_ick, CK_242X),
+ CLK("omapdss_dss", "fck", &dss1_fck, CK_242X),
+ CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X),
+ CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X),
+ /* L3 domain clocks */
+ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
+ CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
+ CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_242X),
+ /* L4 domain clocks */
+ CLK(NULL, "l4_ck", &l4_ck, CK_242X),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X),
+ CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_242X),
+ /* virtual meta-group clock */
+ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X),
+ /* general l4 interface ck, multi-parent functional clk */
+ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_242X),
+ CLK(NULL, "gpt1_fck", &gpt1_fck, CK_242X),
+ CLK(NULL, "gpt2_ick", &gpt2_ick, CK_242X),
+ CLK(NULL, "gpt2_fck", &gpt2_fck, CK_242X),
+ CLK(NULL, "gpt3_ick", &gpt3_ick, CK_242X),
+ CLK(NULL, "gpt3_fck", &gpt3_fck, CK_242X),
+ CLK(NULL, "gpt4_ick", &gpt4_ick, CK_242X),
+ CLK(NULL, "gpt4_fck", &gpt4_fck, CK_242X),
+ CLK(NULL, "gpt5_ick", &gpt5_ick, CK_242X),
+ CLK(NULL, "gpt5_fck", &gpt5_fck, CK_242X),
+ CLK(NULL, "gpt6_ick", &gpt6_ick, CK_242X),
+ CLK(NULL, "gpt6_fck", &gpt6_fck, CK_242X),
+ CLK(NULL, "gpt7_ick", &gpt7_ick, CK_242X),
+ CLK(NULL, "gpt7_fck", &gpt7_fck, CK_242X),
+ CLK(NULL, "gpt8_ick", &gpt8_ick, CK_242X),
+ CLK(NULL, "gpt8_fck", &gpt8_fck, CK_242X),
+ CLK(NULL, "gpt9_ick", &gpt9_ick, CK_242X),
+ CLK(NULL, "gpt9_fck", &gpt9_fck, CK_242X),
+ CLK(NULL, "gpt10_ick", &gpt10_ick, CK_242X),
+ CLK(NULL, "gpt10_fck", &gpt10_fck, CK_242X),
+ CLK(NULL, "gpt11_ick", &gpt11_ick, CK_242X),
+ CLK(NULL, "gpt11_fck", &gpt11_fck, CK_242X),
+ CLK(NULL, "gpt12_ick", &gpt12_ick, CK_242X),
+ CLK(NULL, "gpt12_fck", &gpt12_fck, CK_242X),
+ CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_242X),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_242X),
+ CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_242X),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_242X),
+ CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_242X),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_242X),
+ CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_242X),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_242X),
+ CLK(NULL, "uart1_ick", &uart1_ick, CK_242X),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_242X),
+ CLK(NULL, "uart2_ick", &uart2_ick, CK_242X),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_242X),
+ CLK(NULL, "uart3_ick", &uart3_ick, CK_242X),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_242X),
+ CLK(NULL, "gpios_ick", &gpios_ick, CK_242X),
+ CLK(NULL, "gpios_fck", &gpios_fck, CK_242X),
+ CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_242X),
+ CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_242X),
+ CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_242X),
+ CLK(NULL, "wdt1_ick", &wdt1_ick, CK_242X),
+ CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_242X),
+ CLK("omap24xxcam", "fck", &cam_fck, CK_242X),
+ CLK("omap24xxcam", "ick", &cam_ick, CK_242X),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_242X),
+ CLK(NULL, "wdt4_ick", &wdt4_ick, CK_242X),
+ CLK(NULL, "wdt4_fck", &wdt4_fck, CK_242X),
+ CLK(NULL, "wdt3_ick", &wdt3_ick, CK_242X),
+ CLK(NULL, "wdt3_fck", &wdt3_fck, CK_242X),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_242X),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_242X),
+ CLK("mmci-omap.0", "ick", &mmc_ick, CK_242X),
+ CLK("mmci-omap.0", "fck", &mmc_fck, CK_242X),
+ CLK(NULL, "fac_ick", &fac_ick, CK_242X),
+ CLK(NULL, "fac_fck", &fac_fck, CK_242X),
+ CLK(NULL, "eac_ick", &eac_ick, CK_242X),
+ CLK(NULL, "eac_fck", &eac_fck, CK_242X),
+ CLK("omap_hdq.0", "ick", &hdq_ick, CK_242X),
+ CLK("omap_hdq.1", "fck", &hdq_fck, CK_242X),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_242X),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_242X),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_242X),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_242X),
+ CLK(NULL, "gpmc_fck", &gpmc_fck, CK_242X),
+ CLK(NULL, "sdma_fck", &sdma_fck, CK_242X),
+ CLK(NULL, "sdma_ick", &sdma_ick, CK_242X),
+ CLK(NULL, "sdrc_ick", &sdrc_ick, CK_242X),
+ CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X),
+ CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X),
+ CLK(NULL, "des_ick", &des_ick, CK_242X),
+ CLK("omap-sham", "ick", &sha_ick, CK_242X),
+ CLK("omap_rng", "ick", &rng_ick, CK_242X),
+ CLK("omap-aes", "ick", &aes_ick, CK_242X),
+ CLK(NULL, "pka_ick", &pka_ick, CK_242X),
+ CLK(NULL, "usb_fck", &usb_fck, CK_242X),
+ CLK("musb-hdrc", "fck", &osc_ck, CK_242X),
+};
+
+/*
+ * init code
+ */
+
+int __init omap2420_clk_init(void)
+{
+ const struct prcm_config *prcm;
+ struct omap_clk *c;
+ u32 clkrate;
+
+ prcm_clksrc_ctrl = OMAP2420_PRCM_CLKSRC_CTRL;
+ cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
+ cpu_mask = RATE_IN_242X;
+ rate_table = omap2420_rate_table;
+
+ clk_init(&omap2_clk_functions);
+
+ for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
+ c++)
+ clk_preinit(c->lk.clk);
+
+ osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+ propagate_rate(&osc_ck);
+ sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
+ propagate_rate(&sys_ck);
+
+ for (c = omap2420_clks; c < omap2420_clks + ARRAY_SIZE(omap2420_clks);
+ c++) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
+ }
+
+ /* Disable autoidle on all clocks; let the PM code enable it later */
+ omap_clk_disable_autoidle_all();
+
+ /* Check the MPU rate set by bootloader */
+ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck.rate)
+ continue;
+ if (prcm->dpll_speed <= clkrate)
+ break;
+ }
+ curr_prcm_set = prcm;
+
+ recalculate_root_clocks();
+
+ pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+ (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+ (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_enable_init_clocks();
+
+ /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+ vclk = clk_get(NULL, "virt_prcm_set");
+ sclk = clk_get(NULL, "sys_ck");
+ dclk = clk_get(NULL, "dpll_ck");
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clock2430.c b/arch/arm/mach-omap2/clock2430.c
new file mode 100644
index 00000000..d87bc9cb
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2430.c
@@ -0,0 +1,59 @@
+/*
+ * clock2430.c - OMAP2430-specific clock integration code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+
+/**
+ * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
+ * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE. This custom function
+ * passes back the correct CM_IDLEST register address for I2CHS
+ * modules. No return value.
+ */
+static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ *idlest_reg = OMAP2430_CM_REGADDR(CORE_MOD, CM_IDLEST);
+ *idlest_bit = clk->enable_bit;
+ *idlest_val = OMAP24XX_CM_IDLEST_VAL;
+}
+
+/* 2430 I2CHS has non-standard IDLEST register */
+const struct clkops clkops_omap2430_i2chs_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap2430_clk_i2chs_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
new file mode 100644
index 00000000..0c79d39e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -0,0 +1,2070 @@
+/*
+ * OMAP2430 clock data
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2011 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "opp2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "control.h"
+
+#define OMAP_CM_REGADDR OMAP2430_CM_REGADDR
+
+/*
+ * 2430 clock tree.
+ *
+ * NOTE:In many cases here we are assigning a 'default' parent. In
+ * many cases the parent is selectable. The set parent calls will
+ * also switch sources.
+ *
+ * Several sources are given initial rates which may be wrong, this will
+ * be fixed up in the init func.
+ *
+ * Things are broadly separated below by clock domains. It is
+ * noteworthy that most peripherals have dependencies on multiple clock
+ * domains. Many get their interface clocks from the L4 domain, but get
+ * functional clocks from fixed sources or other core domain derived
+ * clocks.
+ */
+
+/* Base external input clocks */
+static struct clk func_32k_ck = {
+ .name = "func_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+static struct clk secure_32k_ck = {
+ .name = "secure_32k_ck",
+ .ops = &clkops_null,
+ .rate = 32768,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
+static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
+ .name = "osc_ck",
+ .ops = &clkops_oscck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_osc_clk_recalc,
+};
+
+/* Without modem likely 12MHz, with modem likely 13MHz */
+static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
+ .name = "sys_ck", /* ~ ref_clk also */
+ .ops = &clkops_null,
+ .parent = &osc_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2xxx_sys_clk_recalc,
+};
+
+static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
+ .name = "alt_ck",
+ .ops = &clkops_null,
+ .rate = 54000000,
+ .clkdm_name = "wkup_clkdm",
+};
+
+/* Optional external clock input for McBSP CLKS */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
+/*
+ * Analog domain root source clocks
+ */
+
+/* dpll_ck, is broken out in to special cases through clksel */
+/* REVISIT: Rate changes on dpll_ck trigger a full set change. ...
+ * deal with this
+ */
+
+static struct dpll_data dpll_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .mult_mask = OMAP24XX_DPLL_MULT_MASK,
+ .div1_mask = OMAP24XX_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP24XX_EN_DPLL_MASK,
+ .max_multiplier = 1023,
+ .min_divider = 1,
+ .max_divider = 16,
+};
+
+/*
+ * XXX Cannot add round_rate here yet, as this is still a composite clock,
+ * not just a DPLL
+ */
+static struct clk dpll_ck = {
+ .name = "dpll_ck",
+ .ops = &clkops_omap2xxx_dpll_ops,
+ .parent = &sys_ck, /* Can be func_32k also */
+ .dpll_data = &dpll_dd,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_dpllcore_recalc,
+ .set_rate = &omap2_reprogram_dpllcore,
+};
+
+static struct clk apll96_ck = {
+ .name = "apll96_ck",
+ .ops = &clkops_apll96,
+ .parent = &sys_ck,
+ .rate = 96000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_96M_PLL_SHIFT,
+};
+
+static struct clk apll54_ck = {
+ .name = "apll54_ck",
+ .ops = &clkops_apll54,
+ .parent = &sys_ck,
+ .rate = 54000000,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP24XX_EN_54M_PLL_SHIFT,
+};
+
+/*
+ * PRCM digital base sources
+ */
+
+/* func_54m_ck */
+
+static const struct clksel_rate func_54m_apll54_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_54m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_54m_clksel[] = {
+ { .parent = &apll54_ck, .rates = func_54m_apll54_rates, },
+ { .parent = &alt_ck, .rates = func_54m_alt_rates, },
+ { .parent = NULL },
+};
+
+static struct clk func_54m_ck = {
+ .name = "func_54m_ck",
+ .ops = &clkops_null,
+ .parent = &apll54_ck, /* can also be alt_clk */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_54M_SOURCE_MASK,
+ .clksel = func_54m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+ .name = "core_ck",
+ .ops = &clkops_null,
+ .parent = &dpll_ck, /* can also be 32k */
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* func_96m_ck */
+static const struct clksel_rate func_96m_apll96_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_96m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_243X },
+ { .div = 0 },
+};
+
+static const struct clksel func_96m_clksel[] = {
+ { .parent = &apll96_ck, .rates = func_96m_apll96_rates },
+ { .parent = &alt_ck, .rates = func_96m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk func_96m_ck = {
+ .name = "func_96m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck,
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP2430_96M_SOURCE_MASK,
+ .clksel = func_96m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* func_48m_ck */
+
+static const struct clksel_rate func_48m_apll96_rates[] = {
+ { .div = 2, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate func_48m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel func_48m_clksel[] = {
+ { .parent = &apll96_ck, .rates = func_48m_apll96_rates },
+ { .parent = &alt_ck, .rates = func_48m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk func_48m_ck = {
+ .name = "func_48m_ck",
+ .ops = &clkops_null,
+ .parent = &apll96_ck, /* 96M or Alt */
+ .clkdm_name = "wkup_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_48M_SOURCE_MASK,
+ .clksel = func_48m_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk func_12m_ck = {
+ .name = "func_12m_ck",
+ .ops = &clkops_null,
+ .parent = &func_48m_ck,
+ .fixed_div = 4,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/* Secure timer, only available in secure mode */
+static struct clk wdt1_osc_ck = {
+ .name = "ck_wdt1_osc",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &osc_ck,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The common_clkout* clksel_rate structs are common to
+ * sys_clkout, sys_clkout_src, sys_clkout2, and sys_clkout2_src.
+ * sys_clkout2_* are 2420-only, so the
+ * clksel_rate flags fields are inaccurate for those clocks. This is
+ * harmless since access to those clocks are gated by the struct clk
+ * flags fields, which mark them as 2420-only.
+ */
+static const struct clksel_rate common_clkout_src_core_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_96m_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_clkout_src_54m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel common_clkout_src_clksel[] = {
+ { .parent = &core_ck, .rates = common_clkout_src_core_rates },
+ { .parent = &sys_ck, .rates = common_clkout_src_sys_rates },
+ { .parent = &func_96m_ck, .rates = common_clkout_src_96m_rates },
+ { .parent = &func_54m_ck, .rates = common_clkout_src_54m_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout_src = {
+ .name = "sys_clkout_src",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2430_PRCM_CLKOUT_CTRL,
+ .enable_bit = OMAP24XX_CLKOUT_EN_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP2430_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_SOURCE_MASK,
+ .clksel = common_clkout_src_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static const struct clksel_rate common_clkout_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 16, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel sys_clkout_clksel[] = {
+ { .parent = &sys_clkout_src, .rates = common_clkout_rates },
+ { .parent = NULL }
+};
+
+static struct clk sys_clkout = {
+ .name = "sys_clkout",
+ .ops = &clkops_null,
+ .parent = &sys_clkout_src,
+ .clkdm_name = "wkup_clkdm",
+ .clksel_reg = OMAP2430_PRCM_CLKOUT_CTRL,
+ .clksel_mask = OMAP24XX_CLKOUT_DIV_MASK,
+ .clksel = sys_clkout_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk emul_ck = {
+ .name = "emul_ck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_54m_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP2430_PRCM_CLKEMUL_CTRL,
+ .enable_bit = OMAP24XX_EMULATION_EN_SHIFT,
+ .recalc = &followparent_recalc,
+
+};
+
+/*
+ * MPU clock domain
+ * Clocks:
+ * MPU_FCLK, MPU_ICLK
+ * INT_M_FCLK, INT_M_I_CLK
+ *
+ * - Individual clocks are hardware managed.
+ * - Base divider comes from: CM_CLKSEL_MPU
+ *
+ */
+static const struct clksel_rate mpu_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel mpu_clksel[] = {
+ { .parent = &core_ck, .rates = mpu_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk mpu_ck = { /* Control cpu */
+ .name = "mpu_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "mpu_clkdm",
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_MPU_MASK,
+ .clksel = mpu_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * DSP (2430-IVA2.1) clock domain
+ * Clocks:
+ * 2430: IVA2.1_FCLK (really just DSP_FCLK), IVA2.1_ICLK
+ *
+ * Won't be too specific here. The core clock comes into this block
+ * it is divided then tee'ed. One branch goes directly to xyz enable
+ * controls. The other branch gets further divided by 2 then possibly
+ * routed into a synchronizer and out of clocks abc.
+ */
+static const struct clksel_rate dsp_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 },
+};
+
+static const struct clksel dsp_fck_clksel[] = {
+ { .parent = &core_ck, .rates = dsp_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_MASK,
+ .clksel = dsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel dsp_ick_clksel[] = {
+ { .parent = &dsp_fck, .rates = dsp_ick_rates },
+ { .parent = NULL }
+};
+
+/* 2430 only - EN_DSP controls both dsp fclk and iclk on 2430 */
+static struct clk iva2_1_ick = {
+ .name = "iva2_1_ick",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dsp_fck,
+ .clkdm_name = "dsp_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP24XX_CLKSEL_DSP_IF_MASK,
+ .clksel = dsp_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * L3 clock domain
+ * L3 clocks are used for both interface and functional clocks to
+ * multiple entities. Some of these clocks are completely managed
+ * by hardware, and some others allow software control. Hardware
+ * managed ones general are based on directly CLK_REQ signals and
+ * various auto idle settings. The functional spec sets many of these
+ * as 'tie-high' for their enables.
+ *
+ * I-CLOCKS:
+ * L3-Interconnect, SMS, GPMC, SDRC, OCM_RAM, OCM_ROM, SDMA
+ * CAM, HS-USB.
+ * F-CLOCK
+ * SSI.
+ *
+ * GPMC memories and SDRC have timing and clock sensitive registers which
+ * may very well need notification when the clock changes. Currently for low
+ * operating points, these are taken care of in sleep.S.
+ */
+static const struct clksel_rate core_l3_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel core_l3_clksel[] = {
+ { .parent = &core_ck, .rates = core_l3_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
+ .name = "core_l3_ck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L3_MASK,
+ .clksel = core_l3_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* usb_l4_ick */
+static const struct clksel_rate usb_l4_ick_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel usb_l4_ick_clksel[] = {
+ { .parent = &core_l3_ck, .rates = usb_l4_ick_core_l3_rates },
+ { .parent = NULL },
+};
+
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
+static struct clk usb_l4_ick = { /* FS-USB interface clock */
+ .name = "usb_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_USB_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_USB_MASK,
+ .clksel = usb_l4_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks. Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+ { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+ { .parent = NULL }
+};
+
+static struct clk l4_ck = { /* used both as an ick and fck */
+ .name = "l4_ck",
+ .ops = &clkops_null,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
+ .clksel = l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * SSI is in L3 management domain, its direct parent is core not l3,
+ * many core power domain entities are grouped into the L3 clock
+ * domain.
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
+ *
+ * ssr = core/1/2/3/4/5, sst = 1/2 ssr.
+ */
+static const struct clksel_rate ssi_ssr_sst_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_243X },
+ { .div = 0 }
+};
+
+static const struct clksel ssi_ssr_sst_fck_clksel[] = {
+ { .parent = &core_ck, .rates = ssi_ssr_sst_fck_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk ssi_ssr_sst_fck = {
+ .name = "ssi_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_SSI_MASK,
+ .clksel = ssi_ssr_sst_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * Presumably this is the same as SSI_ICLK.
+ * TRM contradicts itself on what clockdomain SSI_ICLK is in
+ */
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_SSI_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+
+/*
+ * GFX clock domain
+ * Clocks:
+ * GFX_FCLK, GFX_ICLK
+ * GFX_CG1(2d), GFX_CG2(3d)
+ *
+ * GFX_FCLK runs from L3, and is divided by (1,2,3,4)
+ * The 2d and 3d clocks run at a hardware determined
+ * divided value of fclk.
+ *
+ */
+
+/* This clksel struct is shared between gfx_3d_fck and gfx_2d_fck */
+static const struct clksel gfx_fck_clksel[] = {
+ { .parent = &core_l3_ck, .rates = gfx_l3_rates },
+ { .parent = NULL },
+};
+
+static struct clk gfx_3d_fck = {
+ .name = "gfx_3d_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_3D_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP_CLKSEL_GFX_MASK,
+ .clksel = gfx_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk gfx_2d_fck = {
+ .name = "gfx_2d_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_2D_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP_CLKSEL_GFX_MASK,
+ .clksel = gfx_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* This interface clock does not have a CM_AUTOIDLE bit */
+static struct clk gfx_ick = {
+ .name = "gfx_ick", /* From l3 */
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "gfx_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+ .enable_bit = OMAP_EN_GFX_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * Modem clock domain (2430)
+ * CLOCKS:
+ * MDM_OSC_CLK
+ * MDM_ICLK
+ * These clocks are usable in chassis mode only.
+ */
+static const struct clksel_rate mdm_ick_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_243X },
+ { .div = 4, .val = 4, .flags = RATE_IN_243X },
+ { .div = 6, .val = 6, .flags = RATE_IN_243X },
+ { .div = 9, .val = 9, .flags = RATE_IN_243X },
+ { .div = 0 }
+};
+
+static const struct clksel mdm_ick_clksel[] = {
+ { .parent = &core_ck, .rates = mdm_ick_core_rates },
+ { .parent = NULL }
+};
+
+static struct clk mdm_ick = { /* used both as a ick and fck */
+ .name = "mdm_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_ck,
+ .clkdm_name = "mdm_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
+ .enable_bit = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP2430_CLKSEL_MDM_MASK,
+ .clksel = mdm_ick_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mdm_osc_ck = {
+ .name = "mdm_osc_ck",
+ .ops = &clkops_omap2_mdmclk_dflt_wait,
+ .parent = &osc_ck,
+ .clkdm_name = "mdm_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
+ .enable_bit = OMAP2430_EN_OSC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * DSS clock domain
+ * CLOCKs:
+ * DSS_L4_ICLK, DSS_L3_ICLK,
+ * DSS_CLK1, DSS_CLK2, DSS_54MHz_CLK
+ *
+ * DSS is both initiator and target.
+ */
+/* XXX Add RATE_NOT_VALIDATED */
+
+static const struct clksel_rate dss1_fck_sys_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate dss1_fck_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_24XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_24XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_24XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_24XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_24XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_24XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_24XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel dss1_fck_clksel[] = {
+ { .parent = &sys_ck, .rates = dss1_fck_sys_rates },
+ { .parent = &core_ck, .rates = dss1_fck_core_rates },
+ { .parent = NULL },
+};
+
+static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
+ .name = "dss_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ck, /* really both l3 and l4 */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss1_fck = {
+ .name = "dss1_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &core_ck, /* Core or sys */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_DSS1_MASK,
+ .clksel = dss1_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate dss2_fck_sys_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate dss2_fck_48m_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel dss2_fck_clksel[] = {
+ { .parent = &sys_ck, .rates = dss2_fck_sys_rates },
+ { .parent = &func_48m_ck, .rates = dss2_fck_48m_rates },
+ { .parent = NULL }
+};
+
+static struct clk dss2_fck = { /* Alt clk used in power management */
+ .name = "dss2_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &sys_ck, /* fixed at sys_ck or 48MHz */
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_DSS2_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_DSS2_MASK,
+ .clksel = dss2_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk dss_54m_fck = { /* Alt clk used in power management */
+ .name = "dss_54m_fck", /* 54m tv clk */
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_54m_ck,
+ .clkdm_name = "dss_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_TV_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wu_l4_ick = {
+ .name = "wu_l4_ick",
+ .ops = &clkops_null,
+ .parent = &sys_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * CORE power domain ICLK & FCLK defines.
+ * Many of the these can have more than one possible parent. Entries
+ * here will likely have an L4 interface parent, and may have multiple
+ * functional clock parents.
+ */
+static const struct clksel_rate gpt_alt_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel omap24xx_gpt_clksel[] = {
+ { .parent = &func_32k_ck, .rates = gpt_32k_rates },
+ { .parent = &sys_ck, .rates = gpt_sys_rates },
+ { .parent = &alt_ck, .rates = gpt_alt_rates },
+ { .parent = NULL },
+};
+
+static struct clk gpt1_ick = {
+ .name = "gpt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt1_fck = {
+ .name = "gpt1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT1_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+static struct clk gpt2_ick = {
+ .name = "gpt2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+ .name = "gpt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT2_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_ick = {
+ .name = "gpt3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt3_fck = {
+ .name = "gpt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT3_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_ick = {
+ .name = "gpt4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt4_fck = {
+ .name = "gpt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT4_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_ick = {
+ .name = "gpt5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt5_fck = {
+ .name = "gpt5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT5_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_ick = {
+ .name = "gpt6_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt6_fck = {
+ .name = "gpt6_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT6_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_ick = {
+ .name = "gpt7_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt7_fck = {
+ .name = "gpt7_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT7_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_ick = {
+ .name = "gpt8_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt8_fck = {
+ .name = "gpt8_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT8_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_ick = {
+ .name = "gpt9_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt9_fck = {
+ .name = "gpt9_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT9_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt10_ick = {
+ .name = "gpt10_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt10_fck = {
+ .name = "gpt10_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT10_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_ick = {
+ .name = "gpt11_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt11_fck = {
+ .name = "gpt11_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT11_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt12_ick = {
+ .name = "gpt12_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt12_fck = {
+ .name = "gpt12_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &secure_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL2),
+ .clksel_mask = OMAP24XX_CLKSEL_GPT12_MASK,
+ .clksel = omap24xx_gpt_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+ .name = "mcbsp1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel mcbsp_fck_clksel[] = {
+ { .parent = &func_96m_ck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
+static struct clk mcbsp1_fck = {
+ .name = "mcbsp1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+ .name = "mcbsp2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp2_fck = {
+ .name = "mcbsp2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+ .name = "mcbsp3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+ .name = "mcbsp3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP3_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+ .name = "mcbsp4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+ .name = "mcbsp4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP4_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+ .name = "mcbsp5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp5_fck = {
+ .name = "mcbsp5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .init = &omap2_init_clksel_parent,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
+ .clksel_reg = OMAP243X_CTRL_REGADDR(OMAP243X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP5_CLKS_MASK,
+ .clksel = mcbsp_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcspi1_ick = {
+ .name = "mcspi1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+ .name = "mcspi1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+ .name = "mcspi2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+ .name = "mcspi2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+ .name = "mcspi3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+ .name = "mcspi3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+ .name = "uart1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_UART1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+ .name = "uart1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_UART1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+ .name = "uart2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_UART2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+ .name = "uart2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_UART2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+ .name = "uart3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP24XX_EN_UART3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+ .name = "uart3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_UART3_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpios_ick = {
+ .name = "gpios_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpios_fck = {
+ .name = "gpios_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mpu_wdt_ick = {
+ .name = "mpu_wdt_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mpu_wdt_fck = {
+ .name = "mpu_wdt_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sync_32k_ick = {
+ .name = "sync_32k_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .flags = ENABLE_ON_INIT,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_32KSYNC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+ .name = "wdt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_WDT1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+ .name = "omapctrl_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .flags = ENABLE_ON_INIT,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk icr_ick = {
+ .name = "icr_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wu_l4_ick,
+ .clkdm_name = "wkup_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP2430_EN_ICR_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+ .name = "cam_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_CAM_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK. It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
+static struct clk cam_fck = {
+ .name = "cam_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_CAM_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+ .name = "mailboxes_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt4_ick = {
+ .name = "wdt4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_WDT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt4_fck = {
+ .name = "wdt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_WDT4_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+ .name = "mspro_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+ .name = "mspro_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+ .name = "fac_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_FAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fac_fck = {
+ .name = "fac_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_FAC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+ .name = "hdq_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+ .name = "hdq_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_12m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP24XX_EN_HDQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * XXX This is marked as a 2420-only define, but it claims to be present
+ * on 2430 also. Double-check.
+ */
+static struct clk i2c2_ick = {
+ .name = "i2c2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_I2C2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2chs2_fck = {
+ .name = "i2chs2_fck",
+ .ops = &clkops_omap2430_i2chs_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_I2CHS2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * XXX This is marked as a 2420-only define, but it claims to be present
+ * on 2430 also. Double-check.
+ */
+static struct clk i2c1_ick = {
+ .name = "i2c1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP2420_EN_I2C1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2chs1_fck = {
+ .name = "i2chs1_fck",
+ .ops = &clkops_omap2430_i2chs_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_I2CHS1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk gpmc_fck = {
+ .name = "gpmc_fck",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP24XX_AUTO_GPMC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sdma_fck = {
+ .name = "sdma_fck",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The enable_reg/enable_bit in this clock is only used for CM_AUTOIDLE
+ * accesses derived from this data.
+ */
+static struct clk sdma_ick = {
+ .name = "sdma_ick",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP24XX_AUTO_SDMA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sdrc_ick = {
+ .name = "sdrc_ick",
+ .ops = &clkops_omap2_iclk_idle_only,
+ .parent = &core_l3_ck,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP2430_EN_SDRC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk des_ick = {
+ .name = "des_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_DES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sha_ick = {
+ .name = "sha_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_SHA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+ .name = "rng_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_RNG_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aes_ick = {
+ .name = "aes_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_AES_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+ .name = "pka_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
+ .enable_bit = OMAP24XX_EN_PKA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_fck = {
+ .name = "usb_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_48m_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP24XX_EN_USB_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usbhs_ick = {
+ .name = "usbhs_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l3_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_USBHS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+ .name = "mmchs1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+ .name = "mmchs1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+ .name = "mmchs2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+ .name = "mmchs2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_96m_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+ .name = "gpio5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_GPIO5_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_fck = {
+ .name = "gpio5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_GPIO5_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mdm_intc_ick = {
+ .name = "mdm_intc_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP2430_EN_MDM_INTC_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchsdb1_fck = {
+ .name = "mmchsdb1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchsdb2_fck = {
+ .name = "mmchsdb2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &func_32k_ck,
+ .clkdm_name = "core_l4_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
+ .enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * This clock is a composite clock which does entire set changes then
+ * forces a rebalance. It keys on the MPU speed, but it really could
+ * be any key speed part of a set in the rate table.
+ *
+ * to really change a set, you need memory table sets which get changed
+ * in sram, pre-notifiers & post notifiers, changing the top set, without
+ * having low level display recalc's won't work... this is why dpm notifiers
+ * work, isr's off, walk a list of clocks already _off_ and not messing with
+ * the bus.
+ *
+ * This clock should have no parent. It embodies the entire upper level
+ * active set. A parent will mess up some of the init also.
+ */
+static struct clk virt_prcm_set = {
+ .name = "virt_prcm_set",
+ .ops = &clkops_null,
+ .parent = &mpu_ck, /* Indexed by mpu speed, no parent */
+ .recalc = &omap2_table_mpu_recalc, /* sets are keyed on mpu rate */
+ .set_rate = &omap2_select_table_rate,
+ .round_rate = &omap2_round_to_table_rate,
+};
+
+
+/*
+ * clkdev integration
+ */
+
+static struct omap_clk omap2430_clks[] = {
+ /* external root sources */
+ CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X),
+ CLK(NULL, "secure_32k_ck", &secure_32k_ck, CK_243X),
+ CLK(NULL, "osc_ck", &osc_ck, CK_243X),
+ CLK(NULL, "sys_ck", &sys_ck, CK_243X),
+ CLK(NULL, "alt_ck", &alt_ck, CK_243X),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_243X),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_243X),
+ /* internal analog sources */
+ CLK(NULL, "dpll_ck", &dpll_ck, CK_243X),
+ CLK(NULL, "apll96_ck", &apll96_ck, CK_243X),
+ CLK(NULL, "apll54_ck", &apll54_ck, CK_243X),
+ /* internal prcm root sources */
+ CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X),
+ CLK(NULL, "core_ck", &core_ck, CK_243X),
+ CLK("omap-mcbsp.1", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.2", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.3", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.4", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK("omap-mcbsp.5", "prcm_fck", &func_96m_ck, CK_243X),
+ CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X),
+ CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X),
+ CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X),
+ CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X),
+ CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X),
+ CLK(NULL, "sys_clkout", &sys_clkout, CK_243X),
+ CLK(NULL, "emul_ck", &emul_ck, CK_243X),
+ /* mpu domain clocks */
+ CLK(NULL, "mpu_ck", &mpu_ck, CK_243X),
+ /* dsp domain clocks */
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_243X),
+ CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X),
+ /* GFX domain clocks */
+ CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X),
+ CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_243X),
+ CLK(NULL, "gfx_ick", &gfx_ick, CK_243X),
+ /* Modem domain clocks */
+ CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
+ CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
+ /* DSS domain clocks */
+ CLK("omapdss_dss", "ick", &dss_ick, CK_243X),
+ CLK("omapdss_dss", "fck", &dss1_fck, CK_243X),
+ CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X),
+ CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X),
+ /* L3 domain clocks */
+ CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
+ CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
+ CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_243X),
+ /* L4 domain clocks */
+ CLK(NULL, "l4_ck", &l4_ck, CK_243X),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X),
+ CLK(NULL, "wu_l4_ick", &wu_l4_ick, CK_243X),
+ /* virtual meta-group clock */
+ CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X),
+ /* general l4 interface ck, multi-parent functional clk */
+ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X),
+ CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X),
+ CLK(NULL, "gpt2_ick", &gpt2_ick, CK_243X),
+ CLK(NULL, "gpt2_fck", &gpt2_fck, CK_243X),
+ CLK(NULL, "gpt3_ick", &gpt3_ick, CK_243X),
+ CLK(NULL, "gpt3_fck", &gpt3_fck, CK_243X),
+ CLK(NULL, "gpt4_ick", &gpt4_ick, CK_243X),
+ CLK(NULL, "gpt4_fck", &gpt4_fck, CK_243X),
+ CLK(NULL, "gpt5_ick", &gpt5_ick, CK_243X),
+ CLK(NULL, "gpt5_fck", &gpt5_fck, CK_243X),
+ CLK(NULL, "gpt6_ick", &gpt6_ick, CK_243X),
+ CLK(NULL, "gpt6_fck", &gpt6_fck, CK_243X),
+ CLK(NULL, "gpt7_ick", &gpt7_ick, CK_243X),
+ CLK(NULL, "gpt7_fck", &gpt7_fck, CK_243X),
+ CLK(NULL, "gpt8_ick", &gpt8_ick, CK_243X),
+ CLK(NULL, "gpt8_fck", &gpt8_fck, CK_243X),
+ CLK(NULL, "gpt9_ick", &gpt9_ick, CK_243X),
+ CLK(NULL, "gpt9_fck", &gpt9_fck, CK_243X),
+ CLK(NULL, "gpt10_ick", &gpt10_ick, CK_243X),
+ CLK(NULL, "gpt10_fck", &gpt10_fck, CK_243X),
+ CLK(NULL, "gpt11_ick", &gpt11_ick, CK_243X),
+ CLK(NULL, "gpt11_fck", &gpt11_fck, CK_243X),
+ CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X),
+ CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X),
+ CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X),
+ CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X),
+ CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X),
+ CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X),
+ CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X),
+ CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X),
+ CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X),
+ CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X),
+ CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X),
+ CLK(NULL, "uart1_ick", &uart1_ick, CK_243X),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_243X),
+ CLK(NULL, "uart2_ick", &uart2_ick, CK_243X),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_243X),
+ CLK(NULL, "uart3_ick", &uart3_ick, CK_243X),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_243X),
+ CLK(NULL, "gpios_ick", &gpios_ick, CK_243X),
+ CLK(NULL, "gpios_fck", &gpios_fck, CK_243X),
+ CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X),
+ CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X),
+ CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X),
+ CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X),
+ CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X),
+ CLK(NULL, "icr_ick", &icr_ick, CK_243X),
+ CLK("omap24xxcam", "fck", &cam_fck, CK_243X),
+ CLK("omap24xxcam", "ick", &cam_ick, CK_243X),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_243X),
+ CLK(NULL, "wdt4_ick", &wdt4_ick, CK_243X),
+ CLK(NULL, "wdt4_fck", &wdt4_fck, CK_243X),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_243X),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_243X),
+ CLK(NULL, "fac_ick", &fac_ick, CK_243X),
+ CLK(NULL, "fac_fck", &fac_fck, CK_243X),
+ CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X),
+ CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_243X),
+ CLK("omap_i2c.1", "fck", &i2chs1_fck, CK_243X),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_243X),
+ CLK("omap_i2c.2", "fck", &i2chs2_fck, CK_243X),
+ CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X),
+ CLK(NULL, "sdma_fck", &sdma_fck, CK_243X),
+ CLK(NULL, "sdma_ick", &sdma_ick, CK_243X),
+ CLK(NULL, "sdrc_ick", &sdrc_ick, CK_243X),
+ CLK(NULL, "des_ick", &des_ick, CK_243X),
+ CLK("omap-sham", "ick", &sha_ick, CK_243X),
+ CLK("omap_rng", "ick", &rng_ick, CK_243X),
+ CLK("omap-aes", "ick", &aes_ick, CK_243X),
+ CLK(NULL, "pka_ick", &pka_ick, CK_243X),
+ CLK(NULL, "usb_fck", &usb_fck, CK_243X),
+ CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X),
+ CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X),
+ CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_243X),
+ CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X),
+ CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_243X),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X),
+ CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X),
+ CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
+ CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
+ CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
+};
+
+/*
+ * init code
+ */
+
+int __init omap2430_clk_init(void)
+{
+ const struct prcm_config *prcm;
+ struct omap_clk *c;
+ u32 clkrate;
+
+ prcm_clksrc_ctrl = OMAP2430_PRCM_CLKSRC_CTRL;
+ cm_idlest_pll = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST);
+ cpu_mask = RATE_IN_243X;
+ rate_table = omap2430_rate_table;
+
+ clk_init(&omap2_clk_functions);
+
+ for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
+ c++)
+ clk_preinit(c->lk.clk);
+
+ osc_ck.rate = omap2_osc_clk_recalc(&osc_ck);
+ propagate_rate(&osc_ck);
+ sys_ck.rate = omap2xxx_sys_clk_recalc(&sys_ck);
+ propagate_rate(&sys_ck);
+
+ for (c = omap2430_clks; c < omap2430_clks + ARRAY_SIZE(omap2430_clks);
+ c++) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
+ }
+
+ /* Disable autoidle on all clocks; let the PM code enable it later */
+ omap_clk_disable_autoidle_all();
+
+ /* Check the MPU rate set by bootloader */
+ clkrate = omap2xxx_clk_get_core_rate(&dpll_ck);
+ for (prcm = rate_table; prcm->mpu_speed; prcm++) {
+ if (!(prcm->flags & cpu_mask))
+ continue;
+ if (prcm->xtal_speed != sys_ck.rate)
+ continue;
+ if (prcm->dpll_speed <= clkrate)
+ break;
+ }
+ curr_prcm_set = prcm;
+
+ recalculate_root_clocks();
+
+ pr_info("Clocking rate (Crystal/DPLL/MPU): %ld.%01ld/%ld/%ld MHz\n",
+ (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
+ (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_enable_init_clocks();
+
+ /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */
+ vclk = clk_get(NULL, "virt_prcm_set");
+ sclk = clk_get(NULL, "sys_ck");
+ dclk = clk_get(NULL, "dpll_ck");
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clock2xxx.c b/arch/arm/mach-omap2/clock2xxx.c
new file mode 100644
index 00000000..80bb0f0e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2xxx.c
@@ -0,0 +1,73 @@
+/*
+ * clock2xxx.c - OMAP2xxx-specific clock integration code
+ *
+ * Copyright (C) 2005-2008 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
+ * Gordon McNutt and RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+struct clk *vclk, *sclk, *dclk;
+
+/*
+ * Omap24xx specific clock functions
+ */
+
+/*
+ * Set clocks for bypass mode for reboot to work.
+ */
+void omap2xxx_clk_prepare_for_reboot(void)
+{
+ u32 rate;
+
+ if (vclk == NULL || sclk == NULL)
+ return;
+
+ rate = clk_get_rate(sclk);
+ clk_set_rate(vclk, rate);
+}
+
+/*
+ * Switch the MPU rate if specified on cmdline. We cannot do this
+ * early until cmdline is parsed. XXX This should be removed from the
+ * clock code and handled by the OPP layer code in the near future.
+ */
+static int __init omap2xxx_clk_arch_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap24xx())
+ return 0;
+
+ ret = omap2_clk_switch_mpurate_at_boot("virt_prcm_set");
+ if (!ret)
+ omap2_clk_print_new_rates("sys_ck", "dpll_ck", "mpu_ck");
+
+ return ret;
+}
+
+arch_initcall(omap2xxx_clk_arch_init);
+
+
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
new file mode 100644
index 00000000..cb6df8ca
--- /dev/null
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -0,0 +1,44 @@
+/*
+ * OMAP2 clock function prototypes and macros
+ *
+ * Copyright (C) 2005-2010 Texas Instruments, Inc.
+ * Copyright (C) 2004-2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK2XXX_H
+
+unsigned long omap2_table_mpu_recalc(struct clk *clk);
+int omap2_select_table_rate(struct clk *clk, unsigned long rate);
+long omap2_round_to_table_rate(struct clk *clk, unsigned long rate);
+unsigned long omap2xxx_sys_clk_recalc(struct clk *clk);
+unsigned long omap2_osc_clk_recalc(struct clk *clk);
+unsigned long omap2_dpllcore_recalc(struct clk *clk);
+int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate);
+unsigned long omap2xxx_clk_get_core_rate(struct clk *clk);
+u32 omap2xxx_get_apll_clkin(void);
+u32 omap2xxx_get_sysclkdiv(void);
+void omap2xxx_clk_prepare_for_reboot(void);
+
+#ifdef CONFIG_SOC_OMAP2420
+int omap2420_clk_init(void);
+#else
+#define omap2420_clk_init() do { } while(0)
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+int omap2430_clk_init(void);
+#else
+#define omap2430_clk_init() do { } while(0)
+#endif
+
+extern void __iomem *prcm_clksrc_ctrl, *cm_idlest_pll;
+
+extern struct clk *dclk;
+
+extern const struct clkops clkops_omap2430_i2chs_wait;
+extern const struct clkops clkops_oscck;
+extern const struct clkops clkops_apll96;
+extern const struct clkops clkops_apll54;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
new file mode 100644
index 00000000..1fc96b9e
--- /dev/null
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -0,0 +1,153 @@
+/*
+ * OMAP3-specific clock framework functions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni Högander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock34xx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+
+/**
+ * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
+ * from the CM_{I,F}CLKEN bit. Pass back the correct info via
+ * @idlest_reg and @idlest_bit. No return value.
+ */
+static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_omap3430es2_ssi_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_ssi_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clkops clkops_omap3430es2_iclk_ssi_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_ssi_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+/**
+ * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * Some OMAP modules on OMAP3 ES2+ chips have both initiator and
+ * target IDLEST bits. For our purposes, we are concerned with the
+ * target IDLEST bits, which exist at a different bit position than
+ * the *CLKEN bit position for these modules (DSS and USBHOST) (The
+ * default find_idlest code assumes that they are at the same
+ * position.) No return value.
+ */
+static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ /* USBHOST_IDLE has same shift */
+ *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+/**
+ * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
+ * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via
+ * @idlest_reg and @idlest_bit. No return value.
+ */
+static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_omap3430es2_hsotgusb_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+};
+
+const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = omap3430es2_clk_hsotgusb_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
new file mode 100644
index 00000000..084ba71b
--- /dev/null
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -0,0 +1,18 @@
+/*
+ * OMAP34xx clock function prototypes and macros
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H
+
+extern const struct clkops clkops_omap3430es2_ssi_wait;
+extern const struct clkops clkops_omap3430es2_iclk_ssi_wait;
+extern const struct clkops clkops_omap3430es2_hsotgusb_wait;
+extern const struct clkops clkops_omap3430es2_iclk_hsotgusb_wait;
+extern const struct clkops clkops_omap3430es2_dss_usbhost_wait;
+extern const struct clkops clkops_omap3430es2_iclk_dss_usbhost_wait;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock3517.c b/arch/arm/mach-omap2/clock3517.c
new file mode 100644
index 00000000..2e97d08f
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3517.c
@@ -0,0 +1,126 @@
+/*
+ * OMAP3517/3505-specific clock framework functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2011 Nokia Corporation
+ *
+ * Ranjith Lohithakshan
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3517.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * In AM35xx IPSS, the {ICK,FCK} enable bits for modules are exported
+ * in the same register at a bit offset of 0x8. The EN_ACK for ICK is
+ * at an offset of 4 from ICK enable bit.
+ */
+#define AM35XX_IPSS_ICK_MASK 0xF
+#define AM35XX_IPSS_ICK_EN_ACK_OFFSET 0x4
+#define AM35XX_IPSS_ICK_FCK_OFFSET 0x8
+#define AM35XX_IPSS_CLK_IDLEST_VAL 0
+
+/**
+ * am35xx_clk_find_idlest - return clock ACK info for AM35XX IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The interface clocks on AM35xx IPSS reflects the clock idle status
+ * in the enable register itsel at a bit offset of 4 from the enable
+ * bit. A value of 1 indicates that clock is enabled.
+ */
+static void am35xx_clk_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ *idlest_reg = (__force void __iomem *)(clk->enable_reg);
+ *idlest_bit = clk->enable_bit + AM35XX_IPSS_ICK_EN_ACK_OFFSET;
+ *idlest_val = AM35XX_IPSS_CLK_IDLEST_VAL;
+}
+
+/**
+ * am35xx_clk_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Some clocks don't have companion clocks. For example, modules with
+ * only an interface clock (such as HECC) don't have a companion
+ * clock. Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active. Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts. No return value.
+ */
+static void am35xx_clk_find_companion(struct clk *clk, void __iomem **other_reg,
+ u8 *other_bit)
+{
+ *other_reg = (__force void __iomem *)(clk->enable_reg);
+ if (clk->enable_bit & AM35XX_IPSS_ICK_MASK)
+ *other_bit = clk->enable_bit + AM35XX_IPSS_ICK_FCK_OFFSET;
+ else
+ *other_bit = clk->enable_bit - AM35XX_IPSS_ICK_FCK_OFFSET;
+}
+
+const struct clkops clkops_am35xx_ipss_module_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = am35xx_clk_find_idlest,
+ .find_companion = am35xx_clk_find_companion,
+};
+
+/**
+ * am35xx_clk_ipss_find_idlest - return CM_IDLEST info for IPSS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ * @idlest_val: pointer to a u8 to store the CM_IDLEST indicator
+ *
+ * The IPSS target CM_IDLEST bit is at a different shift from the
+ * CM_{I,F}CLKEN bit. Pass back the correct info via @idlest_reg
+ * and @idlest_bit. No return value.
+ */
+static void am35xx_clk_ipss_find_idlest(struct clk *clk,
+ void __iomem **idlest_reg,
+ u8 *idlest_bit,
+ u8 *idlest_val)
+{
+ u32 r;
+
+ r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+ *idlest_reg = (__force void __iomem *)r;
+ *idlest_bit = AM35XX_ST_IPSS_SHIFT;
+ *idlest_val = OMAP34XX_CM_IDLEST_VAL;
+}
+
+const struct clkops clkops_am35xx_ipss_wait = {
+ .enable = omap2_dflt_clk_enable,
+ .disable = omap2_dflt_clk_disable,
+ .find_idlest = am35xx_clk_ipss_find_idlest,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .allow_idle = omap2_clkt_iclk_allow_idle,
+ .deny_idle = omap2_clkt_iclk_deny_idle,
+};
+
+
diff --git a/arch/arm/mach-omap2/clock3517.h b/arch/arm/mach-omap2/clock3517.h
new file mode 100644
index 00000000..ca5e5a64
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3517.h
@@ -0,0 +1,14 @@
+/*
+ * OMAP3517/3505 clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3517_H
+
+extern const struct clkops clkops_am35xx_ipss_module_wait;
+extern const struct clkops clkops_am35xx_ipss_wait;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock36xx.c b/arch/arm/mach-omap2/clock36xx.c
new file mode 100644
index 00000000..0c5e25ed
--- /dev/null
+++ b/arch/arm/mach-omap2/clock36xx.c
@@ -0,0 +1,72 @@
+/*
+ * OMAP36xx-specific clkops
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Mike Turquette
+ * Vijaykumar GN
+ * Paul Walmsley
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu,
+ * Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock36xx.h"
+
+
+/**
+ * omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
+ * from HSDivider PWRDN problem Implements Errata ID: i556.
+ * @clk: DPLL output struct clk
+ *
+ * 3630 only: dpll3_m3_ck, dpll4_m2_ck, dpll4_m3_ck, dpll4_m4_ck,
+ * dpll4_m5_ck & dpll4_m6_ck dividers gets loaded with reset
+ * valueafter their respective PWRDN bits are set. Any dummy write
+ * (Any other value different from the Read value) to the
+ * corresponding CM_CLKSEL register will refresh the dividers.
+ */
+static int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk *clk)
+{
+ u32 dummy_v, orig_v, clksel_shift;
+ int ret;
+
+ /* Clear PWRDN bit of HSDIVIDER */
+ ret = omap2_dflt_clk_enable(clk);
+
+ /* Restore the dividers */
+ if (!ret) {
+ clksel_shift = __ffs(clk->parent->clksel_mask);
+ orig_v = __raw_readl(clk->parent->clksel_reg);
+ dummy_v = orig_v;
+
+ /* Write any other value different from the Read value */
+ dummy_v ^= (1 << clksel_shift);
+ __raw_writel(dummy_v, clk->parent->clksel_reg);
+
+ /* Write the original divider */
+ __raw_writel(orig_v, clk->parent->clksel_reg);
+ }
+
+ return ret;
+}
+
+const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore = {
+ .enable = omap36xx_pwrdn_clk_enable_with_hsdiv_restore,
+ .disable = omap2_dflt_clk_disable,
+ .find_companion = omap2_clk_dflt_find_companion,
+ .find_idlest = omap2_clk_dflt_find_idlest,
+};
diff --git a/arch/arm/mach-omap2/clock36xx.h b/arch/arm/mach-omap2/clock36xx.h
new file mode 100644
index 00000000..a7dee5bc
--- /dev/null
+++ b/arch/arm/mach-omap2/clock36xx.h
@@ -0,0 +1,13 @@
+/*
+ * OMAP36xx clock function prototypes and macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK36XX_H
+
+extern const struct clkops clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
new file mode 100644
index 00000000..952c3e01
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3xxx.c
@@ -0,0 +1,101 @@
+/*
+ * OMAP3-specific clock framework functions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Jouni Högander
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+ * that are sourced by DPLL5, and both of these require this clock
+ * to be at 120 MHz for proper operation.
+ */
+#define DPLL5_FREQ_FOR_USBHOST 120000000
+
+/* needed by omap3_core_dpll_m2_set_rate() */
+struct clk *sdrc_ick_p, *arm_fck_p;
+
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
+{
+ /*
+ * According to the 12-5 CDP code from TI, "Limitation 2.5"
+ * on 3430ES1 prevents us from changing DPLL multipliers or dividers
+ * on DPLL4.
+ */
+ if (omap_rev() == OMAP3430_REV_ES1_0) {
+ pr_err("clock: DPLL4 cannot change rate due to "
+ "silicon 'Limitation 2.5' on 3430ES1.\n");
+ return -EINVAL;
+ }
+
+ return omap3_noncore_dpll_set_rate(clk, rate);
+}
+
+void __init omap3_clk_lock_dpll5(void)
+{
+ struct clk *dpll5_clk;
+ struct clk *dpll5_m2_clk;
+
+ dpll5_clk = clk_get(NULL, "dpll5_ck");
+ clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
+ clk_enable(dpll5_clk);
+
+ /* Program dpll5_m2_clk divider for no division */
+ dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+ clk_enable(dpll5_m2_clk);
+ clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
+
+ clk_disable(dpll5_m2_clk);
+ clk_disable(dpll5_clk);
+ return;
+}
+
+/* Common clock code */
+
+/*
+ * Switch the MPU rate if specified on cmdline. We cannot do this
+ * early until cmdline is parsed. XXX This should be removed from the
+ * clock code and handled by the OPP layer code in the near future.
+ */
+static int __init omap3xxx_clk_arch_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ ret = omap2_clk_switch_mpurate_at_boot("dpll1_ck");
+ if (!ret)
+ omap2_clk_print_new_rates("osc_sys_ck", "core_ck", "arm_fck");
+
+ return ret;
+}
+
+arch_initcall(omap3xxx_clk_arch_init);
+
+
diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h
new file mode 100644
index 00000000..8bbeeaf3
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3xxx.h
@@ -0,0 +1,21 @@
+/*
+ * OMAP3-common clock function prototypes and macros
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK3XXX_H
+
+int omap3xxx_clk_init(void);
+int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
+int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
+void omap3_clk_lock_dpll5(void);
+
+extern struct clk *sdrc_ick_p;
+extern struct clk *arm_fck_p;
+
+extern const struct clkops clkops_noncore_dpll_ops;
+
+#endif
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
new file mode 100644
index 00000000..75b119bd
--- /dev/null
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -0,0 +1,3576 @@
+/*
+ * OMAP3 clock data
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * With many device clock fixes by Kevin Hilman and Jouni Högander
+ * DPLL bypass clock support added by Roman Tereshonkov
+ *
+ */
+
+/*
+ * Virtual clocks are introduced as convenient tools.
+ * They are sources for other clocks and not supposed
+ * to be requested from drivers directly.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock3xxx.h"
+#include "clock34xx.h"
+#include "clock36xx.h"
+#include "clock3517.h"
+
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "control.h"
+
+/*
+ * clocks
+ */
+
+#define OMAP_CM_REGADDR OMAP34XX_CM_REGADDR
+
+/* Maximum DPLL multiplier, divider values for OMAP3 */
+#define OMAP3_MAX_DPLL_MULT 2047
+#define OMAP3630_MAX_JTYPE_DPLL_MULT 4095
+#define OMAP3_MAX_DPLL_DIV 128
+
+/*
+ * DPLL1 supplies clock to the MPU.
+ * DPLL2 supplies clock to the IVA2.
+ * DPLL3 supplies CORE domain clocks.
+ * DPLL4 supplies peripheral clocks.
+ * DPLL5 supplies other peripheral clocks (USBHOST, USIM).
+ */
+
+/* Forward declarations for DPLL bypass clocks */
+static struct clk dpll1_fck;
+static struct clk dpll2_fck;
+
+/* PRM CLOCKS */
+
+/* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */
+static struct clk omap_32k_fck = {
+ .name = "omap_32k_fck",
+ .ops = &clkops_null,
+ .rate = 32768,
+};
+
+static struct clk secure_32k_fck = {
+ .name = "secure_32k_fck",
+ .ops = &clkops_null,
+ .rate = 32768,
+};
+
+/* Virtual source clocks for osc_sys_ck */
+static struct clk virt_12m_ck = {
+ .name = "virt_12m_ck",
+ .ops = &clkops_null,
+ .rate = 12000000,
+};
+
+static struct clk virt_13m_ck = {
+ .name = "virt_13m_ck",
+ .ops = &clkops_null,
+ .rate = 13000000,
+};
+
+static struct clk virt_16_8m_ck = {
+ .name = "virt_16_8m_ck",
+ .ops = &clkops_null,
+ .rate = 16800000,
+};
+
+static struct clk virt_19_2m_ck = {
+ .name = "virt_19_2m_ck",
+ .ops = &clkops_null,
+ .rate = 19200000,
+};
+
+static struct clk virt_26m_ck = {
+ .name = "virt_26m_ck",
+ .ops = &clkops_null,
+ .rate = 26000000,
+};
+
+static struct clk virt_38_4m_ck = {
+ .name = "virt_38_4m_ck",
+ .ops = &clkops_null,
+ .rate = 38400000,
+};
+
+static const struct clksel_rate osc_sys_12m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_13m_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_16_8m_rates[] = {
+ { .div = 1, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_19_2m_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_26m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate osc_sys_38_4m_rates[] = {
+ { .div = 1, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel osc_sys_clksel[] = {
+ { .parent = &virt_12m_ck, .rates = osc_sys_12m_rates },
+ { .parent = &virt_13m_ck, .rates = osc_sys_13m_rates },
+ { .parent = &virt_16_8m_ck, .rates = osc_sys_16_8m_rates },
+ { .parent = &virt_19_2m_ck, .rates = osc_sys_19_2m_rates },
+ { .parent = &virt_26m_ck, .rates = osc_sys_26m_rates },
+ { .parent = &virt_38_4m_ck, .rates = osc_sys_38_4m_rates },
+ { .parent = NULL },
+};
+
+/* Oscillator clock */
+/* 12, 13, 16.8, 19.2, 26, or 38.4 MHz */
+static struct clk osc_sys_ck = {
+ .name = "osc_sys_ck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP3430_PRM_CLKSEL,
+ .clksel_mask = OMAP3430_SYS_CLKIN_SEL_MASK,
+ .clksel = osc_sys_clksel,
+ /* REVISIT: deal with autoextclkmode? */
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate div2_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel sys_clksel[] = {
+ { .parent = &osc_sys_ck, .rates = div2_rates },
+ { .parent = NULL }
+};
+
+/* Latency: this clock is only enabled after PRM_CLKSETUP.SETUP_TIME */
+/* Feeds DPLLs - divided first by PRM_CLKSRC_CTRL.SYSCLKDIV? */
+static struct clk sys_ck = {
+ .name = "sys_ck",
+ .ops = &clkops_null,
+ .parent = &osc_sys_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP3430_PRM_CLKSRC_CTRL,
+ .clksel_mask = OMAP_SYSCLKDIV_MASK,
+ .clksel = sys_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk sys_altclk = {
+ .name = "sys_altclk",
+ .ops = &clkops_null,
+};
+
+/* Optional external clock input for some McBSPs */
+static struct clk mcbsp_clks = {
+ .name = "mcbsp_clks",
+ .ops = &clkops_null,
+};
+
+/* PRM EXTERNAL CLOCK OUTPUT */
+
+static struct clk sys_clkout1 = {
+ .name = "sys_clkout1",
+ .ops = &clkops_omap2_dflt,
+ .parent = &osc_sys_ck,
+ .enable_reg = OMAP3430_PRM_CLKOUT_CTRL,
+ .enable_bit = OMAP3430_CLKOUT_EN_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* DPLLS */
+
+/* CM CLOCKS */
+
+static const struct clksel_rate div16_dpll_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 5, .val = 5, .flags = RATE_IN_3XXX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3XXX },
+ { .div = 7, .val = 7, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+ { .div = 9, .val = 9, .flags = RATE_IN_3XXX },
+ { .div = 10, .val = 10, .flags = RATE_IN_3XXX },
+ { .div = 11, .val = 11, .flags = RATE_IN_3XXX },
+ { .div = 12, .val = 12, .flags = RATE_IN_3XXX },
+ { .div = 13, .val = 13, .flags = RATE_IN_3XXX },
+ { .div = 14, .val = 14, .flags = RATE_IN_3XXX },
+ { .div = 15, .val = 15, .flags = RATE_IN_3XXX },
+ { .div = 16, .val = 16, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate dpll4_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 5, .val = 5, .flags = RATE_IN_3XXX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3XXX },
+ { .div = 7, .val = 7, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+ { .div = 9, .val = 9, .flags = RATE_IN_3XXX },
+ { .div = 10, .val = 10, .flags = RATE_IN_3XXX },
+ { .div = 11, .val = 11, .flags = RATE_IN_3XXX },
+ { .div = 12, .val = 12, .flags = RATE_IN_3XXX },
+ { .div = 13, .val = 13, .flags = RATE_IN_3XXX },
+ { .div = 14, .val = 14, .flags = RATE_IN_3XXX },
+ { .div = 15, .val = 15, .flags = RATE_IN_3XXX },
+ { .div = 16, .val = 16, .flags = RATE_IN_3XXX },
+ { .div = 17, .val = 17, .flags = RATE_IN_36XX },
+ { .div = 18, .val = 18, .flags = RATE_IN_36XX },
+ { .div = 19, .val = 19, .flags = RATE_IN_36XX },
+ { .div = 20, .val = 20, .flags = RATE_IN_36XX },
+ { .div = 21, .val = 21, .flags = RATE_IN_36XX },
+ { .div = 22, .val = 22, .flags = RATE_IN_36XX },
+ { .div = 23, .val = 23, .flags = RATE_IN_36XX },
+ { .div = 24, .val = 24, .flags = RATE_IN_36XX },
+ { .div = 25, .val = 25, .flags = RATE_IN_36XX },
+ { .div = 26, .val = 26, .flags = RATE_IN_36XX },
+ { .div = 27, .val = 27, .flags = RATE_IN_36XX },
+ { .div = 28, .val = 28, .flags = RATE_IN_36XX },
+ { .div = 29, .val = 29, .flags = RATE_IN_36XX },
+ { .div = 30, .val = 30, .flags = RATE_IN_36XX },
+ { .div = 31, .val = 31, .flags = RATE_IN_36XX },
+ { .div = 32, .val = 32, .flags = RATE_IN_36XX },
+ { .div = 0 }
+};
+
+/* DPLL1 */
+/* MPU clock source */
+/* Type: DPLL */
+static struct dpll_data dpll1_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+ .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK,
+ .clk_bypass = &dpll1_fck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_MPU_DPLL_FREQSEL_MASK,
+ .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL),
+ .enable_mask = OMAP3430_EN_MPU_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+ .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+ .idlest_mask = OMAP3430_ST_MPU_CLK_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll1_ck = {
+ .name = "dpll1_ck",
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .parent = &sys_ck,
+ .dpll_data = &dpll1_dd,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll1_clkdm",
+ .recalc = &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed.
+ */
+static struct clk dpll1_x2_ck = {
+ .name = "dpll1_x2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll1_ck,
+ .clkdm_name = "dpll1_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+/* On DPLL1, unlike other DPLLs, the divider is downstream from CLKOUTX2 */
+static const struct clksel div16_dpll1_x2m2_clksel[] = {
+ { .parent = &dpll1_x2_ck, .rates = div16_dpll_rates },
+ { .parent = NULL }
+};
+
+/*
+ * Does not exist in the TRM - needed to separate the M2 divider from
+ * bypass selection in mpu_ck
+ */
+static struct clk dpll1_x2m2_ck = {
+ .name = "dpll1_x2m2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll1_x2_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL),
+ .clksel_mask = OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK,
+ .clksel = div16_dpll1_x2m2_clksel,
+ .clkdm_name = "dpll1_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* DPLL2 */
+/* IVA2 clock source */
+/* Type: DPLL */
+
+static struct dpll_data dpll2_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+ .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK,
+ .clk_bypass = &dpll2_fck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_IVA2_DPLL_FREQSEL_MASK,
+ .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL),
+ .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) |
+ (1 << DPLL_LOW_POWER_BYPASS),
+ .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
+ .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
+ .idlest_mask = OMAP3430_ST_IVA2_CLK_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll2_ck = {
+ .name = "dpll2_ck",
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .parent = &sys_ck,
+ .dpll_data = &dpll2_dd,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll2_clkdm",
+ .recalc = &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll2_m2x2_clksel[] = {
+ { .parent = &dpll2_ck, .rates = div16_dpll_rates },
+ { .parent = NULL }
+};
+
+/*
+ * The TRM is conflicted on whether IVA2 clock comes from DPLL2 CLKOUT
+ * or CLKOUTX2. CLKOUT seems most plausible.
+ */
+static struct clk dpll2_m2_ck = {
+ .name = "dpll2_m2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll2_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD,
+ OMAP3430_CM_CLKSEL2_PLL),
+ .clksel_mask = OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK,
+ .clksel = div16_dpll2_m2x2_clksel,
+ .clkdm_name = "dpll2_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * DPLL3
+ * Source clock for all interfaces and for some device fclks
+ * REVISIT: Also supports fast relock bypass - not included below
+ */
+static struct dpll_data dpll3_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_CORE_DPLL_FREQSEL_MASK,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP3430_EN_CORE_DPLL_MASK,
+ .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+ .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+ .idlest_mask = OMAP3430_ST_CORE_CLK_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll3_ck = {
+ .name = "dpll3_ck",
+ .ops = &clkops_omap3_core_dpll_ops,
+ .parent = &sys_ck,
+ .dpll_data = &dpll3_dd,
+ .round_rate = &omap2_dpll_round_rate,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed
+ */
+static struct clk dpll3_x2_ck = {
+ .name = "dpll3_x2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_ck,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate div31_dpll3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 5, .val = 5, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 7, .val = 7, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 9, .val = 9, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 10, .val = 10, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 11, .val = 11, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 12, .val = 12, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 13, .val = 13, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 14, .val = 14, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 15, .val = 15, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 16, .val = 16, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 17, .val = 17, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 18, .val = 18, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 19, .val = 19, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 20, .val = 20, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 21, .val = 21, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 22, .val = 22, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 23, .val = 23, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 24, .val = 24, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 25, .val = 25, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 26, .val = 26, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 27, .val = 27, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 28, .val = 28, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 29, .val = 29, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 30, .val = 30, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 31, .val = 31, .flags = RATE_IN_3430ES2PLUS_36XX },
+ { .div = 0 },
+};
+
+static const struct clksel div31_dpll3m2_clksel[] = {
+ { .parent = &dpll3_ck, .rates = div31_dpll3_rates },
+ { .parent = NULL }
+};
+
+/* DPLL3 output M2 - primary control point for CORE speed */
+static struct clk dpll3_m2_ck = {
+ .name = "dpll3_m2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK,
+ .clksel = div31_dpll3m2_clksel,
+ .clkdm_name = "dpll3_clkdm",
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap3_core_dpll_m2_set_rate,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk core_ck = {
+ .name = "core_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_m2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dpll3_m2x2_ck = {
+ .name = "dpll3_m2x2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_m2_ck,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static const struct clksel div16_dpll3_clksel[] = {
+ { .parent = &dpll3_ck, .rates = div16_dpll_rates },
+ { .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll3_m3x2_ck */
+static struct clk dpll3_m3_ck = {
+ .name = "dpll3_m3_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_DIV_DPLL3_MASK,
+ .clksel = div16_dpll3_clksel,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll3_m3x2_ck = {
+ .name = "dpll3_m3x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll3_m3_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_EMU_CORE_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_core_alwon_ck = {
+ .name = "emu_core_alwon_ck",
+ .ops = &clkops_null,
+ .parent = &dpll3_m3x2_ck,
+ .clkdm_name = "dpll3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* DPLL4 */
+/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
+/* Type: DPLL */
+static struct dpll_data dpll4_dd;
+
+static struct dpll_data dpll4_dd_34xx __initdata = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+ .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430_PERIPH_DPLL_FREQSEL_MASK,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+ .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+ .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+ .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+};
+
+static struct dpll_data dpll4_dd_3630 __initdata = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
+ .mult_mask = OMAP3630_PERIPH_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+ .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
+ .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
+ .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
+ .dco_mask = OMAP3630_PERIPH_DPLL_DCO_SEL_MASK,
+ .sddiv_mask = OMAP3630_PERIPH_DPLL_SD_DIV_MASK,
+ .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+ .flags = DPLL_J_TYPE
+};
+
+static struct clk dpll4_ck = {
+ .name = "dpll4_ck",
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .parent = &sys_ck,
+ .dpll_data = &dpll4_dd,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_dpll4_set_rate,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_dpll_recalc,
+};
+
+/*
+ * This virtual clock provides the CLKOUTX2 output from the DPLL if the
+ * DPLL isn't bypassed --
+ * XXX does this serve any downstream clocks?
+ */
+static struct clk dpll4_x2_ck = {
+ .name = "dpll4_x2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll4_clksel[] = {
+ { .parent = &dpll4_ck, .rates = dpll4_rates },
+ { .parent = NULL }
+};
+
+/* This virtual clock is the source for dpll4_m2x2_ck */
+static struct clk dpll4_m2_ck = {
+ .name = "dpll4_m2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430_CM_CLKSEL3),
+ .clksel_mask = OMAP3630_DIV_96M_MASK,
+ .clksel = dpll4_clksel,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m2x2_ck = {
+ .name = "dpll4_m2x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll4_m2_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_96M_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+/*
+ * DPLL4 generates DPLL4_M2X2_CLK which is then routed into the PRM as
+ * PRM_96M_ALWON_(F)CLK. Two clocks then emerge from the PRM:
+ * 96M_ALWON_FCLK (called "omap_96m_alwon_fck" below) and
+ * CM_96K_(F)CLK.
+ */
+
+/* Adding 192MHz Clock node needed by SGX */
+static struct clk omap_192m_alwon_fck = {
+ .name = "omap_192m_alwon_fck",
+ .ops = &clkops_null,
+ .parent = &dpll4_m2x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate omap_96m_alwon_fck_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_36XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_36XX },
+ { .div = 0 }
+};
+
+static const struct clksel omap_96m_alwon_fck_clksel[] = {
+ { .parent = &omap_192m_alwon_fck, .rates = omap_96m_alwon_fck_rates },
+ { .parent = NULL }
+};
+
+static const struct clksel_rate omap_96m_dpll_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate omap_96m_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static struct clk omap_96m_alwon_fck = {
+ .name = "omap_96m_alwon_fck",
+ .ops = &clkops_null,
+ .parent = &dpll4_m2x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk omap_96m_alwon_fck_3630 = {
+ .name = "omap_96m_alwon_fck",
+ .parent = &omap_192m_alwon_fck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3630_CLKSEL_96M_MASK,
+ .clksel = omap_96m_alwon_fck_clksel
+};
+
+static struct clk cm_96m_fck = {
+ .name = "cm_96m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_96m_alwon_fck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel omap_96m_fck_clksel[] = {
+ { .parent = &cm_96m_fck, .rates = omap_96m_dpll_rates },
+ { .parent = &sys_ck, .rates = omap_96m_sys_rates },
+ { .parent = NULL }
+};
+
+static struct clk omap_96m_fck = {
+ .name = "omap_96m_fck",
+ .ops = &clkops_null,
+ .parent = &sys_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_SOURCE_96M_MASK,
+ .clksel = omap_96m_fck_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m3x2_ck */
+static struct clk dpll4_m3_ck = {
+ .name = "dpll4_m3_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_TV_MASK,
+ .clksel = dpll4_clksel,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m3x2_ck = {
+ .name = "dpll4_m3x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll4_m3_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_TV_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel_rate omap_54m_d4m3x2_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate omap_54m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel omap_54m_clksel[] = {
+ { .parent = &dpll4_m3x2_ck, .rates = omap_54m_d4m3x2_rates },
+ { .parent = &sys_altclk, .rates = omap_54m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk omap_54m_fck = {
+ .name = "omap_54m_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_SOURCE_54M_MASK,
+ .clksel = omap_54m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate omap_48m_cm96m_rates[] = {
+ { .div = 2, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate omap_48m_alt_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel omap_48m_clksel[] = {
+ { .parent = &cm_96m_fck, .rates = omap_48m_cm96m_rates },
+ { .parent = &sys_altclk, .rates = omap_48m_alt_rates },
+ { .parent = NULL }
+};
+
+static struct clk omap_48m_fck = {
+ .name = "omap_48m_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_SOURCE_48M_MASK,
+ .clksel = omap_48m_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk omap_12m_fck = {
+ .name = "omap_12m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_48m_fck,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m4x2_ck */
+static struct clk dpll4_m4_ck = {
+ .name = "dpll4_m4_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_DSS1_MASK,
+ .clksel = dpll4_clksel,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+ .set_rate = &omap2_clksel_set_rate,
+ .round_rate = &omap2_clksel_round_rate,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m4x2_ck = {
+ .name = "dpll4_m4x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll4_m4_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_DSS1_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m5x2_ck */
+static struct clk dpll4_m5_ck = {
+ .name = "dpll4_m5_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_CAM_MASK,
+ .clksel = dpll4_clksel,
+ .clkdm_name = "dpll4_clkdm",
+ .set_rate = &omap2_clksel_set_rate,
+ .round_rate = &omap2_clksel_round_rate,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m5x2_ck = {
+ .name = "dpll4_m5x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll4_m5_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_CAM_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+/* This virtual clock is the source for dpll4_m6x2_ck */
+static struct clk dpll4_m6_ck = {
+ .name = "dpll4_m6_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_DIV_DPLL4_MASK,
+ .clksel = dpll4_clksel,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* The PWRDN bit is apparently only available on 3430ES2 and above */
+static struct clk dpll4_m6x2_ck = {
+ .name = "dpll4_m6x2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll4_m6_ck,
+ .enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
+ .enable_bit = OMAP3430_PWRDN_EMU_PERIPH_SHIFT,
+ .flags = INVERT_ENABLE,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static struct clk emu_per_alwon_ck = {
+ .name = "emu_per_alwon_ck",
+ .ops = &clkops_null,
+ .parent = &dpll4_m6x2_ck,
+ .clkdm_name = "dpll4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* DPLL5 */
+/* Supplies 120MHz clock, USIM source clock */
+/* Type: DPLL */
+/* 3430ES2 only */
+static struct dpll_data dpll5_dd = {
+ .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
+ .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
+ .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
+ .clk_bypass = &sys_ck,
+ .clk_ref = &sys_ck,
+ .freqsel_mask = OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK,
+ .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2),
+ .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK,
+ .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED),
+ .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT,
+ .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT,
+ .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT,
+ .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL),
+ .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
+ .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+ .idlest_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+ .max_multiplier = OMAP3_MAX_DPLL_MULT,
+ .min_divider = 1,
+ .max_divider = OMAP3_MAX_DPLL_DIV,
+};
+
+static struct clk dpll5_ck = {
+ .name = "dpll5_ck",
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .parent = &sys_ck,
+ .dpll_data = &dpll5_dd,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+ .clkdm_name = "dpll5_clkdm",
+ .recalc = &omap3_dpll_recalc,
+};
+
+static const struct clksel div16_dpll5_clksel[] = {
+ { .parent = &dpll5_ck, .rates = div16_dpll_rates },
+ { .parent = NULL }
+};
+
+static struct clk dpll5_m2_ck = {
+ .name = "dpll5_m2_ck",
+ .ops = &clkops_null,
+ .parent = &dpll5_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL5),
+ .clksel_mask = OMAP3430ES2_DIV_120M_MASK,
+ .clksel = div16_dpll5_clksel,
+ .clkdm_name = "dpll5_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* CM EXTERNAL CLOCK OUTPUTS */
+
+static const struct clksel_rate clkout2_src_core_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_96m_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate clkout2_src_54m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel clkout2_src_clksel[] = {
+ { .parent = &core_ck, .rates = clkout2_src_core_rates },
+ { .parent = &sys_ck, .rates = clkout2_src_sys_rates },
+ { .parent = &cm_96m_fck, .rates = clkout2_src_96m_rates },
+ { .parent = &omap_54m_fck, .rates = clkout2_src_54m_rates },
+ { .parent = NULL }
+};
+
+static struct clk clkout2_src_ck = {
+ .name = "clkout2_src_ck",
+ .ops = &clkops_omap2_dflt,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP3430_CM_CLKOUT_CTRL,
+ .enable_bit = OMAP3430_CLKOUT2_EN_SHIFT,
+ .clksel_reg = OMAP3430_CM_CLKOUT_CTRL,
+ .clksel_mask = OMAP3430_CLKOUT2SOURCE_MASK,
+ .clksel = clkout2_src_clksel,
+ .clkdm_name = "core_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate sys_clkout2_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 16, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel sys_clkout2_clksel[] = {
+ { .parent = &clkout2_src_ck, .rates = sys_clkout2_rates },
+ { .parent = NULL },
+};
+
+static struct clk sys_clkout2 = {
+ .name = "sys_clkout2",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP3430_CM_CLKOUT_CTRL,
+ .clksel_mask = OMAP3430_CLKOUT2_DIV_MASK,
+ .clksel = sys_clkout2_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+/* CM OUTPUT CLOCKS */
+
+static struct clk corex2_fck = {
+ .name = "corex2_fck",
+ .ops = &clkops_null,
+ .parent = &dpll3_m2x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+/* DPLL power domain clock controls */
+
+static const struct clksel_rate div4_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel div4_core_clksel[] = {
+ { .parent = &core_ck, .rates = div4_rates },
+ { .parent = NULL }
+};
+
+/*
+ * REVISIT: Are these in DPLL power domain or CM power domain? docs
+ * may be inconsistent here?
+ */
+static struct clk dpll1_fck = {
+ .name = "dpll1_fck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
+ .clksel_mask = OMAP3430_MPU_CLK_SRC_MASK,
+ .clksel = div4_core_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mpu_ck = {
+ .name = "mpu_ck",
+ .ops = &clkops_null,
+ .parent = &dpll1_x2m2_ck,
+ .clkdm_name = "mpu_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* arm_fck is divided by two when DPLL1 locked; otherwise, passthrough mpu_ck */
+static const struct clksel_rate arm_fck_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel arm_fck_clksel[] = {
+ { .parent = &mpu_ck, .rates = arm_fck_rates },
+ { .parent = NULL }
+};
+
+static struct clk arm_fck = {
+ .name = "arm_fck",
+ .ops = &clkops_null,
+ .parent = &mpu_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
+ .clksel_mask = OMAP3430_ST_MPU_CLK_MASK,
+ .clksel = arm_fck_clksel,
+ .clkdm_name = "mpu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* XXX What about neon_clkdm ? */
+
+/*
+ * REVISIT: This clock is never specifically defined in the 3430 TRM,
+ * although it is referenced - so this is a guess
+ */
+static struct clk emu_mpu_alwon_ck = {
+ .name = "emu_mpu_alwon_ck",
+ .ops = &clkops_null,
+ .parent = &mpu_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dpll2_fck = {
+ .name = "dpll2_fck",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
+ .clksel_mask = OMAP3430_IVA2_CLK_SRC_MASK,
+ .clksel = div4_core_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk iva2_ck = {
+ .name = "iva2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll2_m2_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT,
+ .clkdm_name = "iva2_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* Common interface clocks */
+
+static const struct clksel div2_core_clksel[] = {
+ { .parent = &core_ck, .rates = div2_rates },
+ { .parent = NULL }
+};
+
+static struct clk l3_ick = {
+ .name = "l3_ick",
+ .ops = &clkops_null,
+ .parent = &core_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_L3_MASK,
+ .clksel = div2_core_clksel,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel div2_l3_clksel[] = {
+ { .parent = &l3_ick, .rates = div2_rates },
+ { .parent = NULL }
+};
+
+static struct clk l4_ick = {
+ .name = "l4_ick",
+ .ops = &clkops_null,
+ .parent = &l3_ick,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_L4_MASK,
+ .clksel = div2_l3_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+
+};
+
+static const struct clksel div2_l4_clksel[] = {
+ { .parent = &l4_ick, .rates = div2_rates },
+ { .parent = NULL }
+};
+
+static struct clk rm_ick = {
+ .name = "rm_ick",
+ .ops = &clkops_null,
+ .parent = &l4_ick,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_RM_MASK,
+ .clksel = div2_l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* GFX power domain */
+
+/* GFX clocks are in 3430ES1 only. 3430ES2 and later uses the SGX instead */
+
+static const struct clksel gfx_l3_clksel[] = {
+ { .parent = &l3_ick, .rates = gfx_l3_rates },
+ { .parent = NULL }
+};
+
+/*
+ * Virtual parent clock for gfx_l3_ick and gfx_l3_fck
+ * This interface clock does not have a CM_AUTOIDLE bit
+ */
+static struct clk gfx_l3_ck = {
+ .name = "gfx_l3_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
+ .enable_bit = OMAP_EN_GFX_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gfx_l3_fck = {
+ .name = "gfx_l3_fck",
+ .ops = &clkops_null,
+ .parent = &gfx_l3_ck,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP_CLKSEL_GFX_MASK,
+ .clksel = gfx_l3_clksel,
+ .clkdm_name = "gfx_3430es1_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gfx_l3_ick = {
+ .name = "gfx_l3_ick",
+ .ops = &clkops_null,
+ .parent = &gfx_l3_ck,
+ .clkdm_name = "gfx_3430es1_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gfx_cg1_ck = {
+ .name = "gfx_cg1_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &gfx_l3_fck, /* REVISIT: correct? */
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES1_EN_2D_SHIFT,
+ .clkdm_name = "gfx_3430es1_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gfx_cg2_ck = {
+ .name = "gfx_cg2_ck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &gfx_l3_fck, /* REVISIT: correct? */
+ .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES1_EN_3D_SHIFT,
+ .clkdm_name = "gfx_3430es1_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* SGX power domain - 3430ES2 only */
+
+static const struct clksel_rate sgx_core_rates[] = {
+ { .div = 2, .val = 5, .flags = RATE_IN_36XX },
+ { .div = 3, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 6, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate sgx_192m_rates[] = {
+ { .div = 1, .val = 4, .flags = RATE_IN_36XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate sgx_corex2_rates[] = {
+ { .div = 3, .val = 6, .flags = RATE_IN_36XX },
+ { .div = 5, .val = 7, .flags = RATE_IN_36XX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate sgx_96m_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel sgx_clksel[] = {
+ { .parent = &core_ck, .rates = sgx_core_rates },
+ { .parent = &cm_96m_fck, .rates = sgx_96m_rates },
+ { .parent = &omap_192m_alwon_fck, .rates = sgx_192m_rates },
+ { .parent = &corex2_fck, .rates = sgx_corex2_rates },
+ { .parent = NULL }
+};
+
+static struct clk sgx_fck = {
+ .name = "sgx_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430ES2_CLKSEL_SGX_MASK,
+ .clksel = sgx_clksel,
+ .clkdm_name = "sgx_clkdm",
+ .recalc = &omap2_clksel_recalc,
+ .set_rate = &omap2_clksel_set_rate,
+ .round_rate = &omap2_clksel_round_rate
+};
+
+/* This interface clock does not have a CM_AUTOIDLE bit */
+static struct clk sgx_ick = {
+ .name = "sgx_ick",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT,
+ .clkdm_name = "sgx_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* CORE power domain */
+
+static struct clk d2d_26m_fck = {
+ .name = "d2d_26m_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430ES1_EN_D2D_SHIFT,
+ .clkdm_name = "d2d_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk modem_fck = {
+ .name = "modem_fck",
+ .ops = &clkops_omap2_mdmclk_dflt_wait,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MODEM_SHIFT,
+ .clkdm_name = "d2d_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sad2d_ick = {
+ .name = "sad2d_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_SAD2D_SHIFT,
+ .clkdm_name = "d2d_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mad2d_ick = {
+ .name = "mad2d_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP3430_EN_MAD2D_SHIFT,
+ .clkdm_name = "d2d_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel omap343x_gpt_clksel[] = {
+ { .parent = &omap_32k_fck, .rates = gpt_32k_rates },
+ { .parent = &sys_ck, .rates = gpt_sys_rates },
+ { .parent = NULL}
+};
+
+static struct clk gpt10_fck = {
+ .name = "gpt10_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &sys_ck,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_GPT10_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT10_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt11_fck = {
+ .name = "gpt11_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &sys_ck,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_GPT11_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT11_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk cpefuse_fck = {
+ .name = "cpefuse_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+ .enable_bit = OMAP3430ES2_EN_CPEFUSE_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ts_fck = {
+ .name = "ts_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &omap_32k_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+ .enable_bit = OMAP3430ES2_EN_TS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usbtll_fck = {
+ .name = "usbtll_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &dpll5_m2_ck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
+ .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* CORE 96M FCLK-derived clocks */
+
+static struct clk core_96m_fck = {
+ .name = "core_96m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_96m_fck,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs3_fck = {
+ .name = "mmchs3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs2_fck = {
+ .name = "mmchs2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MMC2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_fck = {
+ .name = "mspro_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MSPRO_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs1_fck = {
+ .name = "mmchs1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MMC1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c3_fck = {
+ .name = "i2c3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_I2C3_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+ .name = "i2c2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_I2C2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c1_fck = {
+ .name = "i2c1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_I2C1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * MCBSP 1 & 5 get their 96MHz clock from core_96m_fck;
+ * MCBSP 2, 3, 4 get their 96MHz clock from per_96m_fck.
+ */
+static const struct clksel_rate common_mcbsp_96m_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel_rate common_mcbsp_mcbsp_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel mcbsp_15_clksel[] = {
+ { .parent = &core_96m_fck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
+static struct clk mcbsp5_fck = {
+ .name = "mcbsp5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
+ .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP5_CLKS_MASK,
+ .clksel = mcbsp_15_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp1_fck = {
+ .name = "mcbsp1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
+ .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
+ .clksel = mcbsp_15_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* CORE_48M_FCK-derived clocks */
+
+static struct clk core_48m_fck = {
+ .name = "core_48m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_48m_fck,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi4_fck = {
+ .name = "mcspi4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
+ .recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
+};
+
+static struct clk mcspi3_fck = {
+ .name = "mcspi3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
+ .recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
+};
+
+static struct clk mcspi2_fck = {
+ .name = "mcspi2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
+ .recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
+};
+
+static struct clk mcspi1_fck = {
+ .name = "mcspi1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
+ .recalc = &followparent_recalc,
+ .clkdm_name = "core_l4_clkdm",
+};
+
+static struct clk uart2_fck = {
+ .name = "uart2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_UART2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_fck = {
+ .name = "uart1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_UART1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fshostusb_fck = {
+ .name = "fshostusb_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* CORE_12M_FCK based clocks */
+
+static struct clk core_12m_fck = {
+ .name = "core_12m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_12m_fck,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_fck = {
+ .name = "hdq_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_12m_fck,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_HDQ_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* DPLL3-derived clock */
+
+static const struct clksel_rate ssi_ssr_corex2_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+static const struct clksel ssi_ssr_clksel[] = {
+ { .parent = &corex2_fck, .rates = ssi_ssr_corex2_rates },
+ { .parent = NULL }
+};
+
+static struct clk ssi_ssr_fck_3430es1 = {
+ .name = "ssi_ssr_fck",
+ .ops = &clkops_omap2_dflt,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_SSI_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_SSI_MASK,
+ .clksel = ssi_ssr_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk ssi_ssr_fck_3430es2 = {
+ .name = "ssi_ssr_fck",
+ .ops = &clkops_omap3430es2_ssi_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+ .enable_bit = OMAP3430_EN_SSI_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_SSI_MASK,
+ .clksel = ssi_ssr_clksel,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es1 = {
+ .name = "ssi_sst_fck",
+ .ops = &clkops_null,
+ .parent = &ssi_ssr_fck_3430es1,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es2 = {
+ .name = "ssi_sst_fck",
+ .ops = &clkops_null,
+ .parent = &ssi_ssr_fck_3430es2,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+
+
+/* CORE_L3_ICK based clocks */
+
+/*
+ * XXX must add clk_enable/clk_disable for these if standard code won't
+ * handle it
+ */
+static struct clk core_l3_ick = {
+ .name = "core_l3_ick",
+ .ops = &clkops_null,
+ .parent = &l3_ick,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es1 = {
+ .name = "hsotgusb_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &core_l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es2 = {
+ .name = "hsotgusb_ick",
+ .ops = &clkops_omap3430es2_iclk_hsotgusb_wait,
+ .parent = &core_l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* This interface clock does not have a CM_AUTOIDLE bit */
+static struct clk sdrc_ick = {
+ .name = "sdrc_ick",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &core_l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_SDRC_SHIFT,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpmc_fck = {
+ .name = "gpmc_fck",
+ .ops = &clkops_null,
+ .parent = &core_l3_ick,
+ .flags = ENABLE_ON_INIT, /* huh? */
+ .clkdm_name = "core_l3_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* SECURITY_L3_ICK based clocks */
+
+static struct clk security_l3_ick = {
+ .name = "security_l3_ick",
+ .ops = &clkops_null,
+ .parent = &l3_ick,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk pka_ick = {
+ .name = "pka_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &security_l3_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP3430_EN_PKA_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* CORE_L4_ICK based clocks */
+
+static struct clk core_l4_ick = {
+ .name = "core_l4_ick",
+ .ops = &clkops_null,
+ .parent = &l4_ick,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usbtll_ick = {
+ .name = "usbtll_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
+ .enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs3_ick = {
+ .name = "mmchs3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* Intersystem Communication Registers - chassis mode only */
+static struct clk icr_ick = {
+ .name = "icr_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_ICR_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aes2_ick = {
+ .name = "aes2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_AES2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sha12_ick = {
+ .name = "sha12_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_SHA12_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk des2_ick = {
+ .name = "des2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_DES2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs2_ick = {
+ .name = "mmchs2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MMC2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmchs1_ick = {
+ .name = "mmchs1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MMC1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mspro_ick = {
+ .name = "mspro_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MSPRO_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hdq_ick = {
+ .name = "hdq_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_HDQ_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi4_ick = {
+ .name = "mcspi4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi3_ick = {
+ .name = "mcspi3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_ick = {
+ .name = "mcspi2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi1_ick = {
+ .name = "mcspi1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c3_ick = {
+ .name = "i2c3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_I2C3_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c2_ick = {
+ .name = "i2c2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_I2C2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c1_ick = {
+ .name = "i2c1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_I2C1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_ick = {
+ .name = "uart2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_UART2_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart1_ick = {
+ .name = "uart1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_UART1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt11_ick = {
+ .name = "gpt11_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_GPT11_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt10_ick = {
+ .name = "gpt10_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_GPT10_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp5_ick = {
+ .name = "mcbsp5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp1_ick = {
+ .name = "mcbsp1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk fac_ick = {
+ .name = "fac_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430ES1_EN_FAC_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mailboxes_ick = {
+ .name = "mailboxes_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_MAILBOXES_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk omapctrl_ick = {
+ .name = "omapctrl_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_OMAPCTRL_SHIFT,
+ .flags = ENABLE_ON_INIT,
+ .recalc = &followparent_recalc,
+};
+
+/* SSI_L4_ICK based clocks */
+
+static struct clk ssi_l4_ick = {
+ .name = "ssi_l4_ick",
+ .ops = &clkops_null,
+ .parent = &l4_ick,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es1 = {
+ .name = "ssi_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &ssi_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_SSI_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ssi_ick_3430es2 = {
+ .name = "ssi_ick",
+ .ops = &clkops_omap3430es2_iclk_ssi_wait,
+ .parent = &ssi_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430_EN_SSI_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* REVISIT: Technically the TRM claims that this is CORE_CLK based,
+ * but l4_ick makes more sense to me */
+
+static const struct clksel usb_l4_clksel[] = {
+ { .parent = &l4_ick, .rates = div2_rates },
+ { .parent = NULL },
+};
+
+static struct clk usb_l4_ick = {
+ .name = "usb_l4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &l4_ick,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = OMAP3430ES1_EN_FSHOSTUSB_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK,
+ .clksel = usb_l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* SECURITY_L4_ICK2 based clocks */
+
+static struct clk security_l4_ick2 = {
+ .name = "security_l4_ick2",
+ .ops = &clkops_null,
+ .parent = &l4_ick,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aes1_ick = {
+ .name = "aes1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &security_l4_ick2,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP3430_EN_AES1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+ .name = "rng_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &security_l4_ick2,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP3430_EN_RNG_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sha11_ick = {
+ .name = "sha11_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &security_l4_ick2,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP3430_EN_SHA11_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk des1_ick = {
+ .name = "des1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &security_l4_ick2,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
+ .enable_bit = OMAP3430_EN_DES1_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/* DSS */
+static struct clk dss1_alwon_fck_3430es1 = {
+ .name = "dss1_alwon_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &dpll4_m4x2_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_DSS1_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss1_alwon_fck_3430es2 = {
+ .name = "dss1_alwon_fck",
+ .ops = &clkops_omap3430es2_dss_usbhost_wait,
+ .parent = &dpll4_m4x2_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_DSS1_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_tv_fck = {
+ .name = "dss_tv_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &omap_54m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_TV_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_96m_fck = {
+ .name = "dss_96m_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &omap_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_TV_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss2_alwon_fck = {
+ .name = "dss2_alwon_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_DSS2_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es1 = {
+ /* Handles both L3 and L4 clocks */
+ .name = "dss_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_ick_3430es2 = {
+ /* Handles both L3 and L4 clocks */
+ .name = "dss_ick",
+ .ops = &clkops_omap3430es2_iclk_dss_usbhost_wait,
+ .parent = &l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+ .clkdm_name = "dss_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* CAM */
+
+static struct clk cam_mclk = {
+ .name = "cam_mclk",
+ .ops = &clkops_omap2_dflt,
+ .parent = &dpll4_m5x2_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_CAM_SHIFT,
+ .clkdm_name = "cam_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk cam_ick = {
+ /* Handles both L3 and L4 clocks */
+ .name = "cam_ick",
+ .ops = &clkops_omap2_iclk_dflt,
+ .parent = &l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_CAM_SHIFT,
+ .clkdm_name = "cam_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk csi2_96m_fck = {
+ .name = "csi2_96m_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &core_96m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_CSI2_SHIFT,
+ .clkdm_name = "cam_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* USBHOST - 3430ES2 only */
+
+static struct clk usbhost_120m_fck = {
+ .name = "usbhost_120m_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &dpll5_m2_ck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT,
+ .clkdm_name = "usbhost_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usbhost_48m_fck = {
+ .name = "usbhost_48m_fck",
+ .ops = &clkops_omap3430es2_dss_usbhost_wait,
+ .parent = &omap_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
+ .clkdm_name = "usbhost_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usbhost_ick = {
+ /* Handles both L3 and L4 clocks */
+ .name = "usbhost_ick",
+ .ops = &clkops_omap3430es2_iclk_dss_usbhost_wait,
+ .parent = &l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT,
+ .clkdm_name = "usbhost_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* WKUP */
+
+static const struct clksel_rate usim_96m_rates[] = {
+ { .div = 2, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 5, .flags = RATE_IN_3XXX },
+ { .div = 10, .val = 6, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate usim_120m_rates[] = {
+ { .div = 4, .val = 7, .flags = RATE_IN_3XXX },
+ { .div = 8, .val = 8, .flags = RATE_IN_3XXX },
+ { .div = 16, .val = 9, .flags = RATE_IN_3XXX },
+ { .div = 20, .val = 10, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel usim_clksel[] = {
+ { .parent = &omap_96m_fck, .rates = usim_96m_rates },
+ { .parent = &dpll5_m2_ck, .rates = usim_120m_rates },
+ { .parent = &sys_ck, .rates = div2_rates },
+ { .parent = NULL },
+};
+
+/* 3430ES2 only */
+static struct clk usim_fck = {
+ .name = "usim_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430ES2_CLKSEL_USIMOCP_MASK,
+ .clksel = usim_clksel,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
+static struct clk gpt1_fck = {
+ .name = "gpt1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT1_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT1_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk wkup_32k_fck = {
+ .name = "wkup_32k_fck",
+ .ops = &clkops_null,
+ .parent = &omap_32k_fck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio1_dbck = {
+ .name = "gpio1_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &wkup_32k_fck,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt2_fck = {
+ .name = "wdt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &wkup_32k_fck,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_WDT2_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wkup_l4_ick = {
+ .name = "wkup_l4_ick",
+ .ops = &clkops_null,
+ .parent = &sys_ck,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* 3430ES2 only */
+/* Never specifically named in the TRM, so we have to infer a likely name */
+static struct clk usim_ick = {
+ .name = "usim_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt2_ick = {
+ .name = "wdt2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_WDT2_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt1_ick = {
+ .name = "wdt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_WDT1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio1_ick = {
+ .name = "gpio1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk omap_32ksync_ick = {
+ .name = "omap_32ksync_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_32KSYNC_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* XXX This clock no longer exists in 3430 TRM rev F */
+static struct clk gpt12_ick = {
+ .name = "gpt12_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT12_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt1_ick = {
+ .name = "gpt1_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &wkup_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+
+
+/* PER clock domain */
+
+static struct clk per_96m_fck = {
+ .name = "per_96m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_96m_alwon_fck,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk per_48m_fck = {
+ .name = "per_48m_fck",
+ .ops = &clkops_null,
+ .parent = &omap_48m_fck,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+ .name = "uart3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &per_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_UART3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart4_fck = {
+ .name = "uart4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &per_48m_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3630_EN_UART4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt2_fck = {
+ .name = "gpt2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT2_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT2_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt3_fck = {
+ .name = "gpt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT3_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT3_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt4_fck = {
+ .name = "gpt4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT4_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT4_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt5_fck = {
+ .name = "gpt5_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT5_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT5_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt6_fck = {
+ .name = "gpt6_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT6_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT6_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt7_fck = {
+ .name = "gpt7_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT7_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT7_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt8_fck = {
+ .name = "gpt8_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT8_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT8_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk gpt9_fck = {
+ .name = "gpt9_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPT9_SHIFT,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_CLKSEL),
+ .clksel_mask = OMAP3430_CLKSEL_GPT9_MASK,
+ .clksel = omap343x_gpt_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk per_32k_alwon_fck = {
+ .name = "per_32k_alwon_fck",
+ .ops = &clkops_null,
+ .parent = &omap_32k_fck,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio6_dbck = {
+ .name = "gpio6_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO6_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_dbck = {
+ .name = "gpio5_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO5_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio4_dbck = {
+ .name = "gpio4_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio3_dbck = {
+ .name = "gpio3_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio2_dbck = {
+ .name = "gpio2_dbck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_GPIO2_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt3_fck = {
+ .name = "wdt3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &per_32k_alwon_fck,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_WDT3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk per_l4_ick = {
+ .name = "per_l4_ick",
+ .ops = &clkops_null,
+ .parent = &l4_ick,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio6_ick = {
+ .name = "gpio6_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO6_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+ .name = "gpio5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO5_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio4_ick = {
+ .name = "gpio4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio3_ick = {
+ .name = "gpio3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio2_ick = {
+ .name = "gpio2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPIO2_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt3_ick = {
+ .name = "wdt3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_WDT3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_ick = {
+ .name = "uart3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_UART3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart4_ick = {
+ .name = "uart4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3630_EN_UART4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt9_ick = {
+ .name = "gpt9_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT9_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt8_ick = {
+ .name = "gpt8_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT8_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt7_ick = {
+ .name = "gpt7_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT7_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt6_ick = {
+ .name = "gpt6_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT6_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt5_ick = {
+ .name = "gpt5_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT5_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt4_ick = {
+ .name = "gpt4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt3_ick = {
+ .name = "gpt3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpt2_ick = {
+ .name = "gpt2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_GPT2_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp2_ick = {
+ .name = "mcbsp2_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp3_ick = {
+ .name = "mcbsp3_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcbsp4_ick = {
+ .name = "mcbsp4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &per_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
+ .clkdm_name = "per_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel mcbsp_234_clksel[] = {
+ { .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = NULL }
+};
+
+static struct clk mcbsp2_fck = {
+ .name = "mcbsp2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
+ .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP2_CONTROL_DEVCONF0),
+ .clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
+ .clksel = mcbsp_234_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp3_fck = {
+ .name = "mcbsp3_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
+ .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP3_CLKS_MASK,
+ .clksel = mcbsp_234_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk mcbsp4_fck = {
+ .name = "mcbsp4_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .init = &omap2_init_clksel_parent,
+ .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
+ .clksel_reg = OMAP343X_CTRL_REGADDR(OMAP343X_CONTROL_DEVCONF1),
+ .clksel_mask = OMAP2_MCBSP4_CLKS_MASK,
+ .clksel = mcbsp_234_clksel,
+ .clkdm_name = "per_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* EMU clocks */
+
+/* More information: ARM Cortex-A8 Technical Reference Manual, sect 10.1 */
+
+static const struct clksel_rate emu_src_sys_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate emu_src_core_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate emu_src_per_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel_rate emu_src_mpu_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel emu_src_clksel[] = {
+ { .parent = &sys_ck, .rates = emu_src_sys_rates },
+ { .parent = &emu_core_alwon_ck, .rates = emu_src_core_rates },
+ { .parent = &emu_per_alwon_ck, .rates = emu_src_per_rates },
+ { .parent = &emu_mpu_alwon_ck, .rates = emu_src_mpu_rates },
+ { .parent = NULL },
+};
+
+/*
+ * Like the clkout_src clocks, emu_src_clk is a virtual clock, existing only
+ * to switch the source of some of the EMU clocks.
+ * XXX Are there CLKEN bits for these EMU clks?
+ */
+static struct clk emu_src_ck = {
+ .name = "emu_src_ck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_MUX_CTRL_MASK,
+ .clksel = emu_src_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclk_emu_rates[] = {
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 6, .val = 6, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel pclk_emu_clksel[] = {
+ { .parent = &emu_src_ck, .rates = pclk_emu_rates },
+ { .parent = NULL },
+};
+
+static struct clk pclk_fck = {
+ .name = "pclk_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_CLKSEL_PCLK_MASK,
+ .clksel = pclk_emu_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate pclkx2_emu_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel pclkx2_emu_clksel[] = {
+ { .parent = &emu_src_ck, .rates = pclkx2_emu_rates },
+ { .parent = NULL },
+};
+
+static struct clk pclkx2_fck = {
+ .name = "pclkx2_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_CLKSEL_PCLKX2_MASK,
+ .clksel = pclkx2_emu_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel atclk_emu_clksel[] = {
+ { .parent = &emu_src_ck, .rates = div2_rates },
+ { .parent = NULL },
+};
+
+static struct clk atclk_fck = {
+ .name = "atclk_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_CLKSEL_ATCLK_MASK,
+ .clksel = atclk_emu_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk traceclk_src_fck = {
+ .name = "traceclk_src_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_TRACE_MUX_CTRL_MASK,
+ .clksel = emu_src_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel_rate traceclk_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_3XXX },
+ { .div = 0 },
+};
+
+static const struct clksel traceclk_clksel[] = {
+ { .parent = &traceclk_src_fck, .rates = traceclk_rates },
+ { .parent = NULL },
+};
+
+static struct clk traceclk_fck = {
+ .name = "traceclk_fck",
+ .ops = &clkops_null,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(OMAP3430_EMU_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP3430_CLKSEL_TRACECLK_MASK,
+ .clksel = traceclk_clksel,
+ .clkdm_name = "emu_clkdm",
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* SR clocks */
+
+/* SmartReflex fclk (VDD1) */
+static struct clk sr1_fck = {
+ .name = "sr1_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_SR1_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* SmartReflex fclk (VDD2) */
+static struct clk sr2_fck = {
+ .name = "sr2_fck",
+ .ops = &clkops_omap2_dflt_wait,
+ .parent = &sys_ck,
+ .enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
+ .enable_bit = OMAP3430_EN_SR2_SHIFT,
+ .clkdm_name = "wkup_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sr_l4_ick = {
+ .name = "sr_l4_ick",
+ .ops = &clkops_null, /* RMK: missing? */
+ .parent = &l4_ick,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+/* SECURE_32K_FCK clocks */
+
+static struct clk gpt12_fck = {
+ .name = "gpt12_fck",
+ .ops = &clkops_null,
+ .parent = &secure_32k_fck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wdt1_fck = {
+ .name = "wdt1_fck",
+ .ops = &clkops_null,
+ .parent = &secure_32k_fck,
+ .recalc = &followparent_recalc,
+};
+
+/* Clocks for AM35XX */
+static struct clk ipss_ick = {
+ .name = "ipss_ick",
+ .ops = &clkops_am35xx_ipss_wait,
+ .parent = &core_l3_ick,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = AM35XX_EN_IPSS_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk emac_ick = {
+ .name = "emac_ick",
+ .ops = &clkops_am35xx_ipss_module_wait,
+ .parent = &ipss_ick,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_CPGMAC_VBUSP_CLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rmii_ck = {
+ .name = "rmii_ck",
+ .ops = &clkops_null,
+ .rate = 50000000,
+};
+
+static struct clk emac_fck = {
+ .name = "emac_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &rmii_ck,
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_CPGMAC_FCLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_am35xx = {
+ .name = "hsotgusb_ick",
+ .ops = &clkops_am35xx_ipss_module_wait,
+ .parent = &ipss_ick,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_USBOTG_VBUSP_CLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hsotgusb_fck_am35xx = {
+ .name = "hsotgusb_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &sys_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_USBOTG_FCLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk hecc_ck = {
+ .name = "hecc_ck",
+ .ops = &clkops_am35xx_ipss_module_wait,
+ .parent = &sys_ck,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_HECC_VBUSP_CLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk vpfe_ick = {
+ .name = "vpfe_ick",
+ .ops = &clkops_am35xx_ipss_module_wait,
+ .parent = &ipss_ick,
+ .clkdm_name = "core_l3_clkdm",
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_VPFE_VBUSP_CLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk pclk_ck = {
+ .name = "pclk_ck",
+ .ops = &clkops_null,
+ .rate = 27000000,
+};
+
+static struct clk vpfe_fck = {
+ .name = "vpfe_fck",
+ .ops = &clkops_omap2_dflt,
+ .parent = &pclk_ck,
+ .enable_reg = OMAP343X_CTRL_REGADDR(AM35XX_CONTROL_IPSS_CLK_CTRL),
+ .enable_bit = AM35XX_VPFE_FCLK_SHIFT,
+ .recalc = &followparent_recalc,
+};
+
+/*
+ * The UART1/2 functional clock acts as the functional
+ * clock for UART4. No separate fclk control available.
+ */
+static struct clk uart4_ick_am35xx = {
+ .name = "uart4_ick",
+ .ops = &clkops_omap2_iclk_dflt_wait,
+ .parent = &core_l4_ick,
+ .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+ .enable_bit = AM35XX_EN_UART4_SHIFT,
+ .clkdm_name = "core_l4_clkdm",
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dummy_apb_pclk = {
+ .name = "apb_pclk",
+ .ops = &clkops_null,
+};
+
+/*
+ * clkdev
+ */
+
+/* XXX At some point we should rename this file to clock3xxx_data.c */
+static struct omap_clk omap3xxx_clks[] = {
+ CLK(NULL, "apb_pclk", &dummy_apb_pclk, CK_3XXX),
+ CLK(NULL, "omap_32k_fck", &omap_32k_fck, CK_3XXX),
+ CLK(NULL, "virt_12m_ck", &virt_12m_ck, CK_3XXX),
+ CLK(NULL, "virt_13m_ck", &virt_13m_ck, CK_3XXX),
+ CLK(NULL, "virt_16_8m_ck", &virt_16_8m_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "virt_19_2m_ck", &virt_19_2m_ck, CK_3XXX),
+ CLK(NULL, "virt_26m_ck", &virt_26m_ck, CK_3XXX),
+ CLK(NULL, "virt_38_4m_ck", &virt_38_4m_ck, CK_3XXX),
+ CLK(NULL, "osc_sys_ck", &osc_sys_ck, CK_3XXX),
+ CLK(NULL, "sys_ck", &sys_ck, CK_3XXX),
+ CLK(NULL, "sys_altclk", &sys_altclk, CK_3XXX),
+ CLK("omap-mcbsp.1", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.2", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.3", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.4", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK("omap-mcbsp.5", "pad_fck", &mcbsp_clks, CK_3XXX),
+ CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX),
+ CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX),
+ CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX),
+ CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_3XXX),
+ CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
+ CLK(NULL, "dpll2_ck", &dpll2_ck, CK_34XX | CK_36XX),
+ CLK(NULL, "dpll2_m2_ck", &dpll2_m2_ck, CK_34XX | CK_36XX),
+ CLK(NULL, "dpll3_ck", &dpll3_ck, CK_3XXX),
+ CLK(NULL, "core_ck", &core_ck, CK_3XXX),
+ CLK(NULL, "dpll3_x2_ck", &dpll3_x2_ck, CK_3XXX),
+ CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck, CK_3XXX),
+ CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_3XXX),
+ CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_3XXX),
+ CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_3XXX),
+ CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_3XXX),
+ CLK(NULL, "dpll4_ck", &dpll4_ck, CK_3XXX),
+ CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_3XXX),
+ CLK(NULL, "omap_192m_alwon_fck", &omap_192m_alwon_fck, CK_36XX),
+ CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_3XXX),
+ CLK(NULL, "omap_96m_fck", &omap_96m_fck, CK_3XXX),
+ CLK(NULL, "cm_96m_fck", &cm_96m_fck, CK_3XXX),
+ CLK(NULL, "omap_54m_fck", &omap_54m_fck, CK_3XXX),
+ CLK(NULL, "omap_48m_fck", &omap_48m_fck, CK_3XXX),
+ CLK(NULL, "omap_12m_fck", &omap_12m_fck, CK_3XXX),
+ CLK(NULL, "dpll4_m2_ck", &dpll4_m2_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m2x2_ck", &dpll4_m2x2_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m3_ck", &dpll4_m3_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m3x2_ck", &dpll4_m3x2_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m4_ck", &dpll4_m4_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m4x2_ck", &dpll4_m4x2_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m5_ck", &dpll4_m5_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_3XXX),
+ CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_3XXX),
+ CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_3XXX),
+ CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_3XXX),
+ CLK(NULL, "sys_clkout2", &sys_clkout2, CK_3XXX),
+ CLK(NULL, "corex2_fck", &corex2_fck, CK_3XXX),
+ CLK(NULL, "dpll1_fck", &dpll1_fck, CK_3XXX),
+ CLK(NULL, "mpu_ck", &mpu_ck, CK_3XXX),
+ CLK(NULL, "arm_fck", &arm_fck, CK_3XXX),
+ CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_3XXX),
+ CLK(NULL, "dpll2_fck", &dpll2_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "iva2_ck", &iva2_ck, CK_34XX | CK_36XX),
+ CLK(NULL, "l3_ick", &l3_ick, CK_3XXX),
+ CLK(NULL, "l4_ick", &l4_ick, CK_3XXX),
+ CLK(NULL, "rm_ick", &rm_ick, CK_3XXX),
+ CLK(NULL, "gfx_l3_ck", &gfx_l3_ck, CK_3430ES1),
+ CLK(NULL, "gfx_l3_fck", &gfx_l3_fck, CK_3430ES1),
+ CLK(NULL, "gfx_l3_ick", &gfx_l3_ick, CK_3430ES1),
+ CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck, CK_3430ES1),
+ CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck, CK_3430ES1),
+ CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2PLUS | CK_3517 | CK_36XX),
+ CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2PLUS | CK_3517 | CK_36XX),
+ CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1),
+ CLK(NULL, "modem_fck", &modem_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sad2d_ick", &sad2d_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "mad2d_ick", &mad2d_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "gpt10_fck", &gpt10_fck, CK_3XXX),
+ CLK(NULL, "gpt11_fck", &gpt11_fck, CK_3XXX),
+ CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
+ CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
+ CLK("omap_hsmmc.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_3XXX),
+ CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX),
+ CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_3XXX),
+ CLK("omap_i2c.3", "fck", &i2c3_fck, CK_3XXX),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_3XXX),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_3XXX),
+ CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_3XXX),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_3XXX),
+ CLK(NULL, "core_48m_fck", &core_48m_fck, CK_3XXX),
+ CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_3XXX),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_3XXX),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_3XXX),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_3XXX),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_3XXX),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_3XXX),
+ CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
+ CLK(NULL, "core_12m_fck", &core_12m_fck, CK_3XXX),
+ CLK("omap_hdq.0", "fck", &hdq_fck, CK_3XXX),
+ CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1),
+ CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1),
+ CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "core_l3_ick", &core_l3_ick, CK_3XXX),
+ CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es1, CK_3430ES1),
+ CLK("musb-omap2430", "ick", &hsotgusb_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "sdrc_ick", &sdrc_ick, CK_3XXX),
+ CLK(NULL, "gpmc_fck", &gpmc_fck, CK_3XXX),
+ CLK(NULL, "security_l3_ick", &security_l3_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX),
+ CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX),
+ CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX),
+ CLK("omap-sham", "ick", &sha12_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "des2_ick", &des2_ick, CK_34XX | CK_36XX),
+ CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_3XXX),
+ CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_3XXX),
+ CLK(NULL, "mspro_ick", &mspro_ick, CK_34XX | CK_36XX),
+ CLK("omap_hdq.0", "ick", &hdq_ick, CK_3XXX),
+ CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_3XXX),
+ CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_3XXX),
+ CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_3XXX),
+ CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_3XXX),
+ CLK("omap_i2c.3", "ick", &i2c3_ick, CK_3XXX),
+ CLK("omap_i2c.2", "ick", &i2c2_ick, CK_3XXX),
+ CLK("omap_i2c.1", "ick", &i2c1_ick, CK_3XXX),
+ CLK(NULL, "uart2_ick", &uart2_ick, CK_3XXX),
+ CLK(NULL, "uart1_ick", &uart1_ick, CK_3XXX),
+ CLK(NULL, "gpt11_ick", &gpt11_ick, CK_3XXX),
+ CLK(NULL, "gpt10_ick", &gpt10_ick, CK_3XXX),
+ CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_3XXX),
+ CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_3XXX),
+ CLK(NULL, "fac_ick", &fac_ick, CK_3430ES1),
+ CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_3XXX),
+ CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "ssi_ick", &ssi_ick_3430es1, CK_3430ES1),
+ CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1),
+ CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_34XX | CK_36XX),
+ CLK(NULL, "aes1_ick", &aes1_ick, CK_34XX | CK_36XX),
+ CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
+ CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
+ CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX),
+ CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX),
+ CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX),
+ CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
+ CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
+ CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX),
+ CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX),
+ CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX),
+ CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX),
+ CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX),
+ CLK(NULL, "gpio1_dbck", &gpio1_dbck, CK_3XXX),
+ CLK("omap_wdt", "fck", &wdt2_fck, CK_3XXX),
+ CLK(NULL, "wkup_l4_ick", &wkup_l4_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "usim_ick", &usim_ick, CK_3430ES2PLUS | CK_36XX),
+ CLK("omap_wdt", "ick", &wdt2_ick, CK_3XXX),
+ CLK(NULL, "wdt1_ick", &wdt1_ick, CK_3XXX),
+ CLK(NULL, "gpio1_ick", &gpio1_ick, CK_3XXX),
+ CLK(NULL, "omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
+ CLK(NULL, "gpt12_ick", &gpt12_ick, CK_3XXX),
+ CLK(NULL, "gpt1_ick", &gpt1_ick, CK_3XXX),
+ CLK("omap-mcbsp.2", "prcm_fck", &per_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.3", "prcm_fck", &per_96m_fck, CK_3XXX),
+ CLK("omap-mcbsp.4", "prcm_fck", &per_96m_fck, CK_3XXX),
+ CLK(NULL, "per_96m_fck", &per_96m_fck, CK_3XXX),
+ CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX),
+ CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX),
+ CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX),
+ CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX),
+ CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX),
+ CLK(NULL, "gpt5_fck", &gpt5_fck, CK_3XXX),
+ CLK(NULL, "gpt6_fck", &gpt6_fck, CK_3XXX),
+ CLK(NULL, "gpt7_fck", &gpt7_fck, CK_3XXX),
+ CLK(NULL, "gpt8_fck", &gpt8_fck, CK_3XXX),
+ CLK(NULL, "gpt9_fck", &gpt9_fck, CK_3XXX),
+ CLK(NULL, "per_32k_alwon_fck", &per_32k_alwon_fck, CK_3XXX),
+ CLK(NULL, "gpio6_dbck", &gpio6_dbck, CK_3XXX),
+ CLK(NULL, "gpio5_dbck", &gpio5_dbck, CK_3XXX),
+ CLK(NULL, "gpio4_dbck", &gpio4_dbck, CK_3XXX),
+ CLK(NULL, "gpio3_dbck", &gpio3_dbck, CK_3XXX),
+ CLK(NULL, "gpio2_dbck", &gpio2_dbck, CK_3XXX),
+ CLK(NULL, "wdt3_fck", &wdt3_fck, CK_3XXX),
+ CLK(NULL, "per_l4_ick", &per_l4_ick, CK_3XXX),
+ CLK(NULL, "gpio6_ick", &gpio6_ick, CK_3XXX),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_3XXX),
+ CLK(NULL, "gpio4_ick", &gpio4_ick, CK_3XXX),
+ CLK(NULL, "gpio3_ick", &gpio3_ick, CK_3XXX),
+ CLK(NULL, "gpio2_ick", &gpio2_ick, CK_3XXX),
+ CLK(NULL, "wdt3_ick", &wdt3_ick, CK_3XXX),
+ CLK(NULL, "uart3_ick", &uart3_ick, CK_3XXX),
+ CLK(NULL, "uart4_ick", &uart4_ick, CK_36XX),
+ CLK(NULL, "gpt9_ick", &gpt9_ick, CK_3XXX),
+ CLK(NULL, "gpt8_ick", &gpt8_ick, CK_3XXX),
+ CLK(NULL, "gpt7_ick", &gpt7_ick, CK_3XXX),
+ CLK(NULL, "gpt6_ick", &gpt6_ick, CK_3XXX),
+ CLK(NULL, "gpt5_ick", &gpt5_ick, CK_3XXX),
+ CLK(NULL, "gpt4_ick", &gpt4_ick, CK_3XXX),
+ CLK(NULL, "gpt3_ick", &gpt3_ick, CK_3XXX),
+ CLK(NULL, "gpt2_ick", &gpt2_ick, CK_3XXX),
+ CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_3XXX),
+ CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_3XXX),
+ CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_3XXX),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_3XXX),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_3XXX),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_3XXX),
+ CLK("etb", "emu_src_ck", &emu_src_ck, CK_3XXX),
+ CLK(NULL, "pclk_fck", &pclk_fck, CK_3XXX),
+ CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_3XXX),
+ CLK(NULL, "atclk_fck", &atclk_fck, CK_3XXX),
+ CLK(NULL, "traceclk_src_fck", &traceclk_src_fck, CK_3XXX),
+ CLK(NULL, "traceclk_fck", &traceclk_fck, CK_3XXX),
+ CLK(NULL, "sr1_fck", &sr1_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sr2_fck", &sr2_fck, CK_34XX | CK_36XX),
+ CLK(NULL, "sr_l4_ick", &sr_l4_ick, CK_34XX | CK_36XX),
+ CLK(NULL, "secure_32k_fck", &secure_32k_fck, CK_3XXX),
+ CLK(NULL, "gpt12_fck", &gpt12_fck, CK_3XXX),
+ CLK(NULL, "wdt1_fck", &wdt1_fck, CK_3XXX),
+ CLK(NULL, "ipss_ick", &ipss_ick, CK_AM35XX),
+ CLK(NULL, "rmii_ck", &rmii_ck, CK_AM35XX),
+ CLK(NULL, "pclk_ck", &pclk_ck, CK_AM35XX),
+ CLK("davinci_emac", "emac_clk", &emac_ick, CK_AM35XX),
+ CLK("davinci_emac", "phy_clk", &emac_fck, CK_AM35XX),
+ CLK("vpfe-capture", "master", &vpfe_ick, CK_AM35XX),
+ CLK("vpfe-capture", "slave", &vpfe_fck, CK_AM35XX),
+ CLK("musb-am35x", "ick", &hsotgusb_ick_am35xx, CK_AM35XX),
+ CLK("musb-am35x", "fck", &hsotgusb_fck_am35xx, CK_AM35XX),
+ CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX),
+ CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
+};
+
+
+int __init omap3xxx_clk_init(void)
+{
+ struct omap_clk *c;
+ u32 cpu_clkflg = 0;
+
+ if (cpu_is_omap3517()) {
+ cpu_mask = RATE_IN_34XX;
+ cpu_clkflg = CK_3517;
+ } else if (cpu_is_omap3505()) {
+ cpu_mask = RATE_IN_34XX;
+ cpu_clkflg = CK_3505;
+ } else if (cpu_is_omap3630()) {
+ cpu_mask = (RATE_IN_34XX | RATE_IN_36XX);
+ cpu_clkflg = CK_36XX;
+ } else if (cpu_is_ti816x()) {
+ cpu_mask = RATE_IN_TI816X;
+ cpu_clkflg = CK_TI816X;
+ } else if (cpu_is_omap34xx()) {
+ if (omap_rev() == OMAP3430_REV_ES1_0) {
+ cpu_mask = RATE_IN_3430ES1;
+ cpu_clkflg = CK_3430ES1;
+ } else {
+ /*
+ * Assume that anything that we haven't matched yet
+ * has 3430ES2-type clocks.
+ */
+ cpu_mask = RATE_IN_3430ES2PLUS;
+ cpu_clkflg = CK_3430ES2PLUS;
+ }
+ } else {
+ WARN(1, "clock: could not identify OMAP3 variant\n");
+ }
+
+ if (omap3_has_192mhz_clk())
+ omap_96m_alwon_fck = omap_96m_alwon_fck_3630;
+
+ if (cpu_is_omap3630()) {
+ /*
+ * XXX This type of dynamic rewriting of the clock tree is
+ * deprecated and should be revised soon.
+ *
+ * For 3630: override clkops_omap2_dflt_wait for the
+ * clocks affected from PWRDN reset Limitation
+ */
+ dpll3_m3x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ dpll4_m2x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ dpll4_m3x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ dpll4_m4x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ dpll4_m5x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ dpll4_m6x2_ck.ops =
+ &clkops_omap36xx_pwrdn_with_hsdiv_wait_restore;
+ }
+
+ /*
+ * XXX This type of dynamic rewriting of the clock tree is
+ * deprecated and should be revised soon.
+ */
+ if (cpu_is_omap3630())
+ dpll4_dd = dpll4_dd_3630;
+ else
+ dpll4_dd = dpll4_dd_34xx;
+
+ clk_init(&omap2_clk_functions);
+
+ for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+ c++)
+ clk_preinit(c->lk.clk);
+
+ for (c = omap3xxx_clks; c < omap3xxx_clks + ARRAY_SIZE(omap3xxx_clks);
+ c++)
+ if (c->cpu & cpu_clkflg) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
+ }
+
+ /* Disable autoidle on all clocks; let the PM code enable it later */
+ omap_clk_disable_autoidle_all();
+
+ recalculate_root_clocks();
+
+ pr_info("Clocking rate (Crystal/Core/MPU): %ld.%01ld/%ld/%ld MHz\n",
+ (osc_sys_ck.rate / 1000000), (osc_sys_ck.rate / 100000) % 10,
+ (core_ck.rate / 1000000), (arm_fck.rate / 1000000));
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_enable_init_clocks();
+
+ /*
+ * Lock DPLL5 -- here only until other device init code can
+ * handle this
+ */
+ if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0))
+ omap3_clk_lock_dpll5();
+
+ /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
+ sdrc_ick_p = clk_get(NULL, "sdrc_ick");
+ arm_fck_p = clk_get(NULL, "arm_fck");
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clock44xx.h b/arch/arm/mach-omap2/clock44xx.h
new file mode 100644
index 00000000..6be10959
--- /dev/null
+++ b/arch/arm/mach-omap2/clock44xx.h
@@ -0,0 +1,20 @@
+/*
+ * OMAP4 clock function prototypes and macros
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCK44XX_H
+
+/*
+ * XXX Missing values for the OMAP4 DPLL_USB
+ * XXX Missing min_multiplier values for all OMAP4 DPLLs
+ */
+#define OMAP4430_MAX_DPLL_MULT 2047
+#define OMAP4430_MAX_DPLL_DIV 128
+
+int omap4xxx_clk_init(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
new file mode 100644
index 00000000..8c965671
--- /dev/null
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -0,0 +1,3324 @@
+/*
+ * OMAP4 Clock data
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX Some of the ES1 clocks have been removed/changed; once support
+ * is added for discriminating clocks by ES level, these should be added back
+ * in.
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <plat/clkdev_omap.h>
+
+#include "clock.h"
+#include "clock44xx.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "control.h"
+#include "scrm44xx.h"
+
+/* OMAP4 modulemode control */
+#define OMAP4430_MODULEMODE_HWCTRL 0
+#define OMAP4430_MODULEMODE_SWCTRL 1
+
+/* Root clocks */
+
+static struct clk extalt_clkin_ck = {
+ .name = "extalt_clkin_ck",
+ .rate = 59000000,
+ .ops = &clkops_null,
+};
+
+static struct clk pad_clks_ck = {
+ .name = "pad_clks_ck",
+ .rate = 12000000,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CLKSEL_ABE,
+ .enable_bit = OMAP4430_PAD_CLKS_GATE_SHIFT,
+};
+
+static struct clk pad_slimbus_core_clks_ck = {
+ .name = "pad_slimbus_core_clks_ck",
+ .rate = 12000000,
+ .ops = &clkops_null,
+};
+
+static struct clk secure_32k_clk_src_ck = {
+ .name = "secure_32k_clk_src_ck",
+ .rate = 32768,
+ .ops = &clkops_null,
+};
+
+static struct clk slimbus_clk = {
+ .name = "slimbus_clk",
+ .rate = 12000000,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CLKSEL_ABE,
+ .enable_bit = OMAP4430_SLIMBUS_CLK_GATE_SHIFT,
+};
+
+static struct clk sys_32k_ck = {
+ .name = "sys_32k_ck",
+ .rate = 32768,
+ .ops = &clkops_null,
+};
+
+static struct clk virt_12000000_ck = {
+ .name = "virt_12000000_ck",
+ .ops = &clkops_null,
+ .rate = 12000000,
+};
+
+static struct clk virt_13000000_ck = {
+ .name = "virt_13000000_ck",
+ .ops = &clkops_null,
+ .rate = 13000000,
+};
+
+static struct clk virt_16800000_ck = {
+ .name = "virt_16800000_ck",
+ .ops = &clkops_null,
+ .rate = 16800000,
+};
+
+static struct clk virt_19200000_ck = {
+ .name = "virt_19200000_ck",
+ .ops = &clkops_null,
+ .rate = 19200000,
+};
+
+static struct clk virt_26000000_ck = {
+ .name = "virt_26000000_ck",
+ .ops = &clkops_null,
+ .rate = 26000000,
+};
+
+static struct clk virt_27000000_ck = {
+ .name = "virt_27000000_ck",
+ .ops = &clkops_null,
+ .rate = 27000000,
+};
+
+static struct clk virt_38400000_ck = {
+ .name = "virt_38400000_ck",
+ .ops = &clkops_null,
+ .rate = 38400000,
+};
+
+static const struct clksel_rate div_1_0_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_1_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_2_rates[] = {
+ { .div = 1, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_3_rates[] = {
+ { .div = 1, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_4_rates[] = {
+ { .div = 1, .val = 4, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_5_rates[] = {
+ { .div = 1, .val = 5, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_6_rates[] = {
+ { .div = 1, .val = 6, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel_rate div_1_7_rates[] = {
+ { .div = 1, .val = 7, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel sys_clkin_sel[] = {
+ { .parent = &virt_12000000_ck, .rates = div_1_1_rates },
+ { .parent = &virt_13000000_ck, .rates = div_1_2_rates },
+ { .parent = &virt_16800000_ck, .rates = div_1_3_rates },
+ { .parent = &virt_19200000_ck, .rates = div_1_4_rates },
+ { .parent = &virt_26000000_ck, .rates = div_1_5_rates },
+ { .parent = &virt_27000000_ck, .rates = div_1_6_rates },
+ { .parent = &virt_38400000_ck, .rates = div_1_7_rates },
+ { .parent = NULL },
+};
+
+static struct clk sys_clkin_ck = {
+ .name = "sys_clkin_ck",
+ .rate = 38400000,
+ .clksel = sys_clkin_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_SYS_CLKSEL,
+ .clksel_mask = OMAP4430_SYS_CLKSEL_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk tie_low_clock_ck = {
+ .name = "tie_low_clock_ck",
+ .rate = 0,
+ .ops = &clkops_null,
+};
+
+static struct clk utmi_phy_clkout_ck = {
+ .name = "utmi_phy_clkout_ck",
+ .rate = 60000000,
+ .ops = &clkops_null,
+};
+
+static struct clk xclk60mhsp1_ck = {
+ .name = "xclk60mhsp1_ck",
+ .rate = 60000000,
+ .ops = &clkops_null,
+};
+
+static struct clk xclk60mhsp2_ck = {
+ .name = "xclk60mhsp2_ck",
+ .rate = 60000000,
+ .ops = &clkops_null,
+};
+
+static struct clk xclk60motg_ck = {
+ .name = "xclk60motg_ck",
+ .rate = 60000000,
+ .ops = &clkops_null,
+};
+
+/* Module clocks and DPLL outputs */
+
+static const struct clksel abe_dpll_bypass_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &sys_32k_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk abe_dpll_bypass_clk_mux_ck = {
+ .name = "abe_dpll_bypass_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk abe_dpll_refclk_mux_ck = {
+ .name = "abe_dpll_refclk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_ABE_PLL_REF_CLKSEL,
+ .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* DPLL_ABE */
+static struct dpll_data dpll_abe_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_ABE,
+ .clk_bypass = &abe_dpll_bypass_clk_mux_ck,
+ .clk_ref = &abe_dpll_refclk_mux_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_ABE,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_ABE,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_ABE,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_abe_ck = {
+ .name = "dpll_abe_ck",
+ .parent = &abe_dpll_refclk_mux_ck,
+ .dpll_data = &dpll_abe_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static struct clk dpll_abe_x2_ck = {
+ .name = "dpll_abe_x2_ck",
+ .parent = &dpll_abe_ck,
+ .flags = CLOCK_CLKOUTX2,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap3_clkoutx2_recalc,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
+};
+
+static const struct clksel_rate div31_1to31_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 3, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 4, .flags = RATE_IN_4430 },
+ { .div = 5, .val = 5, .flags = RATE_IN_4430 },
+ { .div = 6, .val = 6, .flags = RATE_IN_4430 },
+ { .div = 7, .val = 7, .flags = RATE_IN_4430 },
+ { .div = 8, .val = 8, .flags = RATE_IN_4430 },
+ { .div = 9, .val = 9, .flags = RATE_IN_4430 },
+ { .div = 10, .val = 10, .flags = RATE_IN_4430 },
+ { .div = 11, .val = 11, .flags = RATE_IN_4430 },
+ { .div = 12, .val = 12, .flags = RATE_IN_4430 },
+ { .div = 13, .val = 13, .flags = RATE_IN_4430 },
+ { .div = 14, .val = 14, .flags = RATE_IN_4430 },
+ { .div = 15, .val = 15, .flags = RATE_IN_4430 },
+ { .div = 16, .val = 16, .flags = RATE_IN_4430 },
+ { .div = 17, .val = 17, .flags = RATE_IN_4430 },
+ { .div = 18, .val = 18, .flags = RATE_IN_4430 },
+ { .div = 19, .val = 19, .flags = RATE_IN_4430 },
+ { .div = 20, .val = 20, .flags = RATE_IN_4430 },
+ { .div = 21, .val = 21, .flags = RATE_IN_4430 },
+ { .div = 22, .val = 22, .flags = RATE_IN_4430 },
+ { .div = 23, .val = 23, .flags = RATE_IN_4430 },
+ { .div = 24, .val = 24, .flags = RATE_IN_4430 },
+ { .div = 25, .val = 25, .flags = RATE_IN_4430 },
+ { .div = 26, .val = 26, .flags = RATE_IN_4430 },
+ { .div = 27, .val = 27, .flags = RATE_IN_4430 },
+ { .div = 28, .val = 28, .flags = RATE_IN_4430 },
+ { .div = 29, .val = 29, .flags = RATE_IN_4430 },
+ { .div = 30, .val = 30, .flags = RATE_IN_4430 },
+ { .div = 31, .val = 31, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel dpll_abe_m2x2_div[] = {
+ { .parent = &dpll_abe_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_abe_m2x2_ck = {
+ .name = "dpll_abe_m2x2_ck",
+ .parent = &dpll_abe_x2_ck,
+ .clksel = dpll_abe_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk abe_24m_fclk = {
+ .name = "abe_24m_fclk",
+ .parent = &dpll_abe_m2x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 8,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel_rate div3_1to4_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel abe_clk_div[] = {
+ { .parent = &dpll_abe_m2x2_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
+static struct clk abe_clk = {
+ .name = "abe_clk",
+ .parent = &dpll_abe_m2x2_ck,
+ .clksel = abe_clk_div,
+ .clksel_reg = OMAP4430_CM_CLKSEL_ABE,
+ .clksel_mask = OMAP4430_CLKSEL_OPP_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel_rate div2_1to2_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel aess_fclk_div[] = {
+ { .parent = &abe_clk, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk aess_fclk = {
+ .name = "aess_fclk",
+ .parent = &abe_clk,
+ .clksel = aess_fclk_div,
+ .clksel_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_AESS_FCLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_abe_m3x2_ck = {
+ .name = "dpll_abe_m3x2_ck",
+ .parent = &dpll_abe_x2_ck,
+ .clksel = dpll_abe_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_ABE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel core_hsd_byp_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_abe_m3x2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk core_hsd_byp_clk_mux_ck = {
+ .name = "core_hsd_byp_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = core_hsd_byp_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_CORE,
+ .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* DPLL_CORE */
+static struct dpll_data dpll_core_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_CORE,
+ .clk_bypass = &core_hsd_byp_clk_mux_ck,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_CORE,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_CORE,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_CORE,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_core_ck = {
+ .name = "dpll_core_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_core_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_core_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+};
+
+static struct clk dpll_core_x2_ck = {
+ .name = "dpll_core_x2_ck",
+ .parent = &dpll_core_ck,
+ .flags = CLOCK_CLKOUTX2,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_core_m6x2_div[] = {
+ { .parent = &dpll_core_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_core_m6x2_ck = {
+ .name = "dpll_core_m6x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_CORE,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel dbgclk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk dbgclk_mux_ck = {
+ .name = "dbgclk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel dpll_core_m2_div[] = {
+ { .parent = &dpll_core_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_core_m2_ck = {
+ .name = "dpll_core_m2_ck",
+ .parent = &dpll_core_ck,
+ .clksel = dpll_core_m2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_CORE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk ddrphy_ck = {
+ .name = "ddrphy_ck",
+ .parent = &dpll_core_m2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static struct clk dpll_core_m5x2_ck = {
+ .name = "dpll_core_m5x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_CORE,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel div_core_div[] = {
+ { .parent = &dpll_core_m5x2_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk div_core_ck = {
+ .name = "div_core_ck",
+ .parent = &dpll_core_m5x2_ck,
+ .clksel = div_core_div,
+ .clksel_reg = OMAP4430_CM_CLKSEL_CORE,
+ .clksel_mask = OMAP4430_CLKSEL_CORE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel_rate div4_1to8_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 2, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 2, .flags = RATE_IN_4430 },
+ { .div = 8, .val = 3, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel div_iva_hs_clk_div[] = {
+ { .parent = &dpll_core_m5x2_ck, .rates = div4_1to8_rates },
+ { .parent = NULL },
+};
+
+static struct clk div_iva_hs_clk = {
+ .name = "div_iva_hs_clk",
+ .parent = &dpll_core_m5x2_ck,
+ .clksel = div_iva_hs_clk_div,
+ .clksel_reg = OMAP4430_CM_BYPCLK_DPLL_IVA,
+ .clksel_mask = OMAP4430_CLKSEL_0_1_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk div_mpu_hs_clk = {
+ .name = "div_mpu_hs_clk",
+ .parent = &dpll_core_m5x2_ck,
+ .clksel = div_iva_hs_clk_div,
+ .clksel_reg = OMAP4430_CM_BYPCLK_DPLL_MPU,
+ .clksel_mask = OMAP4430_CLKSEL_0_1_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_core_m4x2_ck = {
+ .name = "dpll_core_m4x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_CORE,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dll_clk_div_ck = {
+ .name = "dll_clk_div_ck",
+ .parent = &dpll_core_m4x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel dpll_abe_m2_div[] = {
+ { .parent = &dpll_abe_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_abe_m2_ck = {
+ .name = "dpll_abe_m2_ck",
+ .parent = &dpll_abe_ck,
+ .clksel = dpll_abe_m2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_ABE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_core_m3x2_ck = {
+ .name = "dpll_core_m3x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
+ .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DIV_M3_DPLL_CORE,
+ .enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_core_m7x2_ck = {
+ .name = "dpll_core_m7x2_ck",
+ .parent = &dpll_core_x2_ck,
+ .clksel = dpll_core_m6x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_CORE,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel iva_hsd_byp_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &div_iva_hs_clk, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk iva_hsd_byp_clk_mux_ck = {
+ .name = "iva_hsd_byp_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = iva_hsd_byp_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_IVA,
+ .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* DPLL_IVA */
+static struct dpll_data dpll_iva_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_IVA,
+ .clk_bypass = &iva_hsd_byp_clk_mux_ck,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_IVA,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_IVA,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_IVA,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_iva_ck = {
+ .name = "dpll_iva_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_iva_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static struct clk dpll_iva_x2_ck = {
+ .name = "dpll_iva_x2_ck",
+ .parent = &dpll_iva_ck,
+ .flags = CLOCK_CLKOUTX2,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_iva_m4x2_div[] = {
+ { .parent = &dpll_iva_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_iva_m4x2_ck = {
+ .name = "dpll_iva_m4x2_ck",
+ .parent = &dpll_iva_x2_ck,
+ .clksel = dpll_iva_m4x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_IVA,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_iva_m5x2_ck = {
+ .name = "dpll_iva_m5x2_ck",
+ .parent = &dpll_iva_x2_ck,
+ .clksel = dpll_iva_m4x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_IVA,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+/* DPLL_MPU */
+static struct dpll_data dpll_mpu_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_MPU,
+ .clk_bypass = &div_mpu_hs_clk,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_MPU,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_MPU,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_MPU,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_mpu_ck = {
+ .name = "dpll_mpu_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_mpu_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static const struct clksel dpll_mpu_m2_div[] = {
+ { .parent = &dpll_mpu_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_mpu_m2_ck = {
+ .name = "dpll_mpu_m2_ck",
+ .parent = &dpll_mpu_ck,
+ .clksel = dpll_mpu_m2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk per_hs_clk_div_ck = {
+ .name = "per_hs_clk_div_ck",
+ .parent = &dpll_abe_m3x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 2,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel per_hsd_byp_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &per_hs_clk_div_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk per_hsd_byp_clk_mux_ck = {
+ .name = "per_hsd_byp_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = per_hsd_byp_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_CLKSEL_DPLL_PER,
+ .clksel_mask = OMAP4430_DPLL_BYP_CLKSEL_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/* DPLL_PER */
+static struct dpll_data dpll_per_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_PER,
+ .clk_bypass = &per_hsd_byp_clk_mux_ck,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_PER,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_PER,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_PER,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_per_ck = {
+ .name = "dpll_per_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_per_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static const struct clksel dpll_per_m2_div[] = {
+ { .parent = &dpll_per_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_per_m2_ck = {
+ .name = "dpll_per_m2_ck",
+ .parent = &dpll_per_ck,
+ .clksel = dpll_per_m2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_x2_ck = {
+ .name = "dpll_per_x2_ck",
+ .parent = &dpll_per_ck,
+ .flags = CLOCK_CLKOUTX2,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap3_clkoutx2_recalc,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
+};
+
+static const struct clksel dpll_per_m2x2_div[] = {
+ { .parent = &dpll_per_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_per_m2x2_ck = {
+ .name = "dpll_per_m2x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_PER,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_m3x2_ck = {
+ .name = "dpll_per_m3x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
+ .clksel_mask = OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DIV_M3_DPLL_PER,
+ .enable_bit = OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_m4x2_ck = {
+ .name = "dpll_per_m4x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M4_DPLL_PER,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_m5x2_ck = {
+ .name = "dpll_per_m5x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M5_DPLL_PER,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_m6x2_ck = {
+ .name = "dpll_per_m6x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M6_DPLL_PER,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk dpll_per_m7x2_ck = {
+ .name = "dpll_per_m7x2_ck",
+ .parent = &dpll_per_x2_ck,
+ .clksel = dpll_per_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M7_DPLL_PER,
+ .clksel_mask = OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+/* DPLL_UNIPRO */
+static struct dpll_data dpll_unipro_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_UNIPRO,
+ .clk_bypass = &sys_clkin_ck,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_UNIPRO,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_UNIPRO,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .sddiv_mask = OMAP4430_DPLL_SD_DIV_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_unipro_ck = {
+ .name = "dpll_unipro_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_unipro_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static struct clk dpll_unipro_x2_ck = {
+ .name = "dpll_unipro_x2_ck",
+ .parent = &dpll_unipro_ck,
+ .flags = CLOCK_CLKOUTX2,
+ .ops = &clkops_null,
+ .recalc = &omap3_clkoutx2_recalc,
+};
+
+static const struct clksel dpll_unipro_m2x2_div[] = {
+ { .parent = &dpll_unipro_x2_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_unipro_m2x2_ck = {
+ .name = "dpll_unipro_m2x2_ck",
+ .parent = &dpll_unipro_x2_ck,
+ .clksel = dpll_unipro_m2x2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_UNIPRO,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk usb_hs_clk_div_ck = {
+ .name = "usb_hs_clk_div_ck",
+ .parent = &dpll_abe_m3x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 3,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+/* DPLL_USB */
+static struct dpll_data dpll_usb_dd = {
+ .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB,
+ .clk_bypass = &usb_hs_clk_div_ck,
+ .flags = DPLL_J_TYPE,
+ .clk_ref = &sys_clkin_ck,
+ .control_reg = OMAP4430_CM_CLKMODE_DPLL_USB,
+ .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ .autoidle_reg = OMAP4430_CM_AUTOIDLE_DPLL_USB,
+ .idlest_reg = OMAP4430_CM_IDLEST_DPLL_USB,
+ .mult_mask = OMAP4430_DPLL_MULT_MASK,
+ .div1_mask = OMAP4430_DPLL_DIV_MASK,
+ .enable_mask = OMAP4430_DPLL_EN_MASK,
+ .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK,
+ .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK,
+ .max_multiplier = OMAP4430_MAX_DPLL_MULT,
+ .max_divider = OMAP4430_MAX_DPLL_DIV,
+ .min_divider = 1,
+};
+
+
+static struct clk dpll_usb_ck = {
+ .name = "dpll_usb_ck",
+ .parent = &sys_clkin_ck,
+ .dpll_data = &dpll_usb_dd,
+ .init = &omap2_init_dpll_parent,
+ .ops = &clkops_omap3_noncore_dpll_ops,
+ .recalc = &omap3_dpll_recalc,
+ .round_rate = &omap2_dpll_round_rate,
+ .set_rate = &omap3_noncore_dpll_set_rate,
+};
+
+static struct clk dpll_usb_clkdcoldo_ck = {
+ .name = "dpll_usb_clkdcoldo_ck",
+ .parent = &dpll_usb_ck,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .clksel_reg = OMAP4430_CM_CLKDCOLDO_DPLL_USB,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel dpll_usb_m2_div[] = {
+ { .parent = &dpll_usb_ck, .rates = div31_1to31_rates },
+ { .parent = NULL },
+};
+
+static struct clk dpll_usb_m2_ck = {
+ .name = "dpll_usb_m2_ck",
+ .parent = &dpll_usb_ck,
+ .clksel = dpll_usb_m2_div,
+ .clksel_reg = OMAP4430_CM_DIV_M2_DPLL_USB,
+ .clksel_mask = OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK,
+ .ops = &clkops_omap4_dpllmx_ops,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel ducati_clk_mux_sel[] = {
+ { .parent = &div_core_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_per_m6x2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk ducati_clk_mux_ck = {
+ .name = "ducati_clk_mux_ck",
+ .parent = &div_core_ck,
+ .clksel = ducati_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT,
+ .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk func_12m_fclk = {
+ .name = "func_12m_fclk",
+ .parent = &dpll_per_m2x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 16,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static struct clk func_24m_clk = {
+ .name = "func_24m_clk",
+ .parent = &dpll_per_m2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static struct clk func_24mc_fclk = {
+ .name = "func_24mc_fclk",
+ .parent = &dpll_per_m2x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 8,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel_rate div2_4to8_rates[] = {
+ { .div = 4, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 8, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel func_48m_fclk_div[] = {
+ { .parent = &dpll_per_m2x2_ck, .rates = div2_4to8_rates },
+ { .parent = NULL },
+};
+
+static struct clk func_48m_fclk = {
+ .name = "func_48m_fclk",
+ .parent = &dpll_per_m2x2_ck,
+ .clksel = func_48m_fclk_div,
+ .clksel_reg = OMAP4430_CM_SCALE_FCLK,
+ .clksel_mask = OMAP4430_SCALE_FCLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk func_48mc_fclk = {
+ .name = "func_48mc_fclk",
+ .parent = &dpll_per_m2x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel_rate div2_2to4_rates[] = {
+ { .div = 2, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 4, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel func_64m_fclk_div[] = {
+ { .parent = &dpll_per_m4x2_ck, .rates = div2_2to4_rates },
+ { .parent = NULL },
+};
+
+static struct clk func_64m_fclk = {
+ .name = "func_64m_fclk",
+ .parent = &dpll_per_m4x2_ck,
+ .clksel = func_64m_fclk_div,
+ .clksel_reg = OMAP4430_CM_SCALE_FCLK,
+ .clksel_mask = OMAP4430_SCALE_FCLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel func_96m_fclk_div[] = {
+ { .parent = &dpll_per_m2x2_ck, .rates = div2_2to4_rates },
+ { .parent = NULL },
+};
+
+static struct clk func_96m_fclk = {
+ .name = "func_96m_fclk",
+ .parent = &dpll_per_m2x2_ck,
+ .clksel = func_96m_fclk_div,
+ .clksel_reg = OMAP4430_CM_SCALE_FCLK,
+ .clksel_mask = OMAP4430_SCALE_FCLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel hsmmc6_fclk_sel[] = {
+ { .parent = &func_64m_fclk, .rates = div_1_0_rates },
+ { .parent = &func_96m_fclk, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk hsmmc6_fclk = {
+ .name = "hsmmc6_fclk",
+ .parent = &func_64m_fclk,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate div2_1to8_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 8, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel init_60m_fclk_div[] = {
+ { .parent = &dpll_usb_m2_ck, .rates = div2_1to8_rates },
+ { .parent = NULL },
+};
+
+static struct clk init_60m_fclk = {
+ .name = "init_60m_fclk",
+ .parent = &dpll_usb_m2_ck,
+ .clksel = init_60m_fclk_div,
+ .clksel_reg = OMAP4430_CM_CLKSEL_USB_60MHZ,
+ .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel l3_div_div[] = {
+ { .parent = &div_core_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk l3_div_ck = {
+ .name = "l3_div_ck",
+ .parent = &div_core_ck,
+ .clksel = l3_div_div,
+ .clksel_reg = OMAP4430_CM_CLKSEL_CORE,
+ .clksel_mask = OMAP4430_CLKSEL_L3_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel l4_div_div[] = {
+ { .parent = &l3_div_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk l4_div_ck = {
+ .name = "l4_div_ck",
+ .parent = &l3_div_ck,
+ .clksel = l4_div_div,
+ .clksel_reg = OMAP4430_CM_CLKSEL_CORE,
+ .clksel_mask = OMAP4430_CLKSEL_L4_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk lp_clk_div_ck = {
+ .name = "lp_clk_div_ck",
+ .parent = &dpll_abe_m2x2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 16,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel l4_wkup_clk_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &lp_clk_div_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk l4_wkup_clk_mux_ck = {
+ .name = "l4_wkup_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = l4_wkup_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4_WKUP_CLKSEL,
+ .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel per_abe_nc_fclk_div[] = {
+ { .parent = &dpll_abe_m2_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk per_abe_nc_fclk = {
+ .name = "per_abe_nc_fclk",
+ .parent = &dpll_abe_m2_ck,
+ .clksel = per_abe_nc_fclk_div,
+ .clksel_reg = OMAP4430_CM_SCALE_FCLK,
+ .clksel_mask = OMAP4430_SCALE_FCLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel mcasp2_fclk_sel[] = {
+ { .parent = &func_96m_fclk, .rates = div_1_0_rates },
+ { .parent = &per_abe_nc_fclk, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk mcasp2_fclk = {
+ .name = "mcasp2_fclk",
+ .parent = &func_96m_fclk,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcasp3_fclk = {
+ .name = "mcasp3_fclk",
+ .parent = &func_96m_fclk,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ocp_abe_iclk = {
+ .name = "ocp_abe_iclk",
+ .parent = &aess_fclk,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk per_abe_24m_fclk = {
+ .name = "per_abe_24m_fclk",
+ .parent = &dpll_abe_m2_ck,
+ .ops = &clkops_null,
+ .fixed_div = 4,
+ .recalc = &omap_fixed_divisor_recalc,
+};
+
+static const struct clksel pmd_stm_clock_mux_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_core_m6x2_ck, .rates = div_1_1_rates },
+ { .parent = &tie_low_clock_ck, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+static struct clk pmd_stm_clock_mux_ck = {
+ .name = "pmd_stm_clock_mux_ck",
+ .parent = &sys_clkin_ck,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk pmd_trace_clk_mux_ck = {
+ .name = "pmd_trace_clk_mux_ck",
+ .parent = &sys_clkin_ck,
+ .ops = &clkops_null,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel syc_clk_div_div[] = {
+ { .parent = &sys_clkin_ck, .rates = div2_1to2_rates },
+ { .parent = NULL },
+};
+
+static struct clk syc_clk_div_ck = {
+ .name = "syc_clk_div_ck",
+ .parent = &sys_clkin_ck,
+ .clksel = syc_clk_div_div,
+ .clksel_reg = OMAP4430_CM_ABE_DSS_SYS_CLKSEL,
+ .clksel_mask = OMAP4430_CLKSEL_0_0_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+/* Leaf clocks controlled by modules */
+
+static struct clk aes1_fck = {
+ .name = "aes1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_AES1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aes2_fck = {
+ .name = "aes2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_AES2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk aess_fck = {
+ .name = "aess_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &aess_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk bandgap_fclk = {
+ .name = "bandgap_fclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk des3des_fck = {
+ .name = "des3des_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_DES3DES_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel dmic_sync_mux_sel[] = {
+ { .parent = &abe_24m_fclk, .rates = div_1_0_rates },
+ { .parent = &syc_clk_div_ck, .rates = div_1_1_rates },
+ { .parent = &func_24m_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+static struct clk dmic_sync_mux_ck = {
+ .name = "dmic_sync_mux_ck",
+ .parent = &abe_24m_fclk,
+ .clksel = dmic_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel func_dmic_abe_gfclk_sel[] = {
+ { .parent = &dmic_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = &slimbus_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+/* Merged func_dmic_abe_gfclk into dmic */
+static struct clk dmic_fck = {
+ .name = "dmic_fck",
+ .parent = &dmic_sync_mux_ck,
+ .clksel = func_dmic_abe_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+static struct clk dsp_fck = {
+ .name = "dsp_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "tesla_clkdm",
+ .parent = &dpll_iva_m4x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_sys_clk = {
+ .name = "dss_sys_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &syc_clk_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_tv_clk = {
+ .name = "dss_tv_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_TV_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &extalt_clkin_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_dss_clk = {
+ .name = "dss_dss_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DSSCLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &dpll_per_m5x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_48mhz_clk = {
+ .name = "dss_48mhz_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &func_48mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk dss_fck = {
+ .name = "dss_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_dss_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk efuse_ctrl_cust_fck = {
+ .name = "efuse_ctrl_cust_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_cefuse_clkdm",
+ .parent = &sys_clkin_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk emif1_fck = {
+ .name = "emif1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "l3_emif_clkdm",
+ .parent = &ddrphy_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk emif2_fck = {
+ .name = "emif2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .flags = ENABLE_ON_INIT,
+ .clkdm_name = "l3_emif_clkdm",
+ .parent = &ddrphy_ck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel fdif_fclk_div[] = {
+ { .parent = &dpll_per_m4x2_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
+/* Merged fdif_fclk into fdif */
+static struct clk fdif_fck = {
+ .name = "fdif_fck",
+ .parent = &dpll_per_m4x2_ck,
+ .clksel = fdif_fclk_div,
+ .clksel_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_FCLK_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+ .enable_reg = OMAP4430_CM_CAM_FDIF_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "iss_clkdm",
+};
+
+static struct clk fpka_fck = {
+ .name = "fpka_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio1_dbclk = {
+ .name = "gpio1_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio1_ick = {
+ .name = "gpio1_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &l4_wkup_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio2_dbclk = {
+ .name = "gpio2_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio2_ick = {
+ .name = "gpio2_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio3_dbclk = {
+ .name = "gpio3_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio3_ick = {
+ .name = "gpio3_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio4_dbclk = {
+ .name = "gpio4_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio4_ick = {
+ .name = "gpio4_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_dbclk = {
+ .name = "gpio5_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio5_ick = {
+ .name = "gpio5_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio6_dbclk = {
+ .name = "gpio6_dbclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_DBCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpio6_ick = {
+ .name = "gpio6_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gpmc_ick = {
+ .name = "gpmc_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3_2_GPMC_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_2_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel sgx_clk_mux_sel[] = {
+ { .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+/* Merged sgx_clk_mux into gpu */
+static struct clk gpu_fck = {
+ .name = "gpu_fck",
+ .parent = &dpll_core_m7x2_ck,
+ .clksel = sgx_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SGX_FCLK_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_GFX_GFX_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_gfx_clkdm",
+};
+
+static struct clk hdq1w_fck = {
+ .name = "hdq1w_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_HDQ1W_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_12m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel hsi_fclk_div[] = {
+ { .parent = &dpll_per_m2x2_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
+/* Merged hsi_fclk into hsi */
+static struct clk hsi_fck = {
+ .name = "hsi_fck",
+ .parent = &dpll_per_m2x2_ck,
+ .clksel = hsi_fclk_div,
+ .clksel_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_24_25_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+ .enable_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+};
+
+static struct clk i2c1_fck = {
+ .name = "i2c1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c2_fck = {
+ .name = "i2c2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c3_fck = {
+ .name = "i2c3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk i2c4_fck = {
+ .name = "i2c4_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ipu_fck = {
+ .name = "ipu_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "ducati_clkdm",
+ .parent = &ducati_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk iss_ctrlclk = {
+ .name = "iss_ctrlclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,
+ .clkdm_name = "iss_clkdm",
+ .parent = &func_96m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk iss_fck = {
+ .name = "iss_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "iss_clkdm",
+ .parent = &ducati_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk iva_fck = {
+ .name = "iva_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "ivahd_clkdm",
+ .parent = &dpll_iva_m5x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk kbd_fck = {
+ .name = "kbd_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk l3_instr_ick = {
+ .name = "l3_instr_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk l3_main_3_ick = {
+ .name = "l3_main_3_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INSTR_L3_3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcasp_sync_mux_ck = {
+ .name = "mcasp_sync_mux_ck",
+ .parent = &abe_24m_fclk,
+ .clksel = dmic_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel func_mcasp_abe_gfclk_sel[] = {
+ { .parent = &mcasp_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = &slimbus_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+/* Merged func_mcasp_abe_gfclk into mcasp */
+static struct clk mcasp_fck = {
+ .name = "mcasp_fck",
+ .parent = &mcasp_sync_mux_ck,
+ .clksel = func_mcasp_abe_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_MCASP_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+static struct clk mcbsp1_sync_mux_ck = {
+ .name = "mcbsp1_sync_mux_ck",
+ .parent = &abe_24m_fclk,
+ .clksel = dmic_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel func_mcbsp1_gfclk_sel[] = {
+ { .parent = &mcbsp1_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = &slimbus_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+/* Merged func_mcbsp1_gfclk into mcbsp1 */
+static struct clk mcbsp1_fck = {
+ .name = "mcbsp1_fck",
+ .parent = &mcbsp1_sync_mux_ck,
+ .clksel = func_mcbsp1_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+static struct clk mcbsp2_sync_mux_ck = {
+ .name = "mcbsp2_sync_mux_ck",
+ .parent = &abe_24m_fclk,
+ .clksel = dmic_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel func_mcbsp2_gfclk_sel[] = {
+ { .parent = &mcbsp2_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = &slimbus_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+/* Merged func_mcbsp2_gfclk into mcbsp2 */
+static struct clk mcbsp2_fck = {
+ .name = "mcbsp2_fck",
+ .parent = &mcbsp2_sync_mux_ck,
+ .clksel = func_mcbsp2_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+static struct clk mcbsp3_sync_mux_ck = {
+ .name = "mcbsp3_sync_mux_ck",
+ .parent = &abe_24m_fclk,
+ .clksel = dmic_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel func_mcbsp3_gfclk_sel[] = {
+ { .parent = &mcbsp3_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = &slimbus_clk, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+/* Merged func_mcbsp3_gfclk into mcbsp3 */
+static struct clk mcbsp3_fck = {
+ .name = "mcbsp3_fck",
+ .parent = &mcbsp3_sync_mux_ck,
+ .clksel = func_mcbsp3_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+static struct clk mcbsp4_sync_mux_ck = {
+ .name = "mcbsp4_sync_mux_ck",
+ .parent = &func_96m_fclk,
+ .clksel = mcasp2_fclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static const struct clksel per_mcbsp4_gfclk_sel[] = {
+ { .parent = &mcbsp4_sync_mux_ck, .rates = div_1_0_rates },
+ { .parent = &pad_clks_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+/* Merged per_mcbsp4_gfclk into mcbsp4 */
+static struct clk mcbsp4_fck = {
+ .name = "mcbsp4_fck",
+ .parent = &mcbsp4_sync_mux_ck,
+ .clksel = per_mcbsp4_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_SOURCE_24_24_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+static struct clk mcpdm_fck = {
+ .name = "mcpdm_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &pad_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi1_fck = {
+ .name = "mcspi1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi2_fck = {
+ .name = "mcspi2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi3_fck = {
+ .name = "mcspi3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mcspi4_fck = {
+ .name = "mcspi4_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+/* Merged hsmmc1_fclk into mmc1 */
+static struct clk mmc1_fck = {
+ .name = "mmc1_fck",
+ .parent = &func_64m_fclk,
+ .clksel = hsmmc6_fclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+};
+
+/* Merged hsmmc2_fclk into mmc2 */
+static struct clk mmc2_fck = {
+ .name = "mmc2_fck",
+ .parent = &func_64m_fclk,
+ .clksel = hsmmc6_fclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+};
+
+static struct clk mmc3_fck = {
+ .name = "mmc3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmc4_fck = {
+ .name = "mmc4_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk mmc5_fck = {
+ .name = "mmc5_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ocp2scp_usb_phy_phy_48m = {
+ .name = "ocp2scp_usb_phy_phy_48m",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PHY_48M_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ocp2scp_usb_phy_ick = {
+ .name = "ocp2scp_usb_phy_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk ocp_wp_noc_ick = {
+ .name = "ocp_wp_noc_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_instr_clkdm",
+ .flags = ENABLE_ON_INIT,
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk rng_ick = {
+ .name = "rng_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_RNG_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sha2md5_fck = {
+ .name = "sha2md5_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_secure_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk sl2if_ick = {
+ .name = "sl2if_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_IVAHD_SL2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "ivahd_clkdm",
+ .parent = &dpll_iva_m5x2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fclk_1 = {
+ .name = "slimbus1_fclk_1",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK1_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &func_24m_clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fclk_0 = {
+ .name = "slimbus1_fclk_0",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK0_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &abe_24m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fclk_2 = {
+ .name = "slimbus1_fclk_2",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK2_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &pad_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_slimbus_clk = {
+ .name = "slimbus1_slimbus_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT,
+ .clkdm_name = "abe_clkdm",
+ .parent = &slimbus_clk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus1_fck = {
+ .name = "slimbus1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &ocp_abe_iclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_fclk_1 = {
+ .name = "slimbus2_fclk_1",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &per_abe_24m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_fclk_0 = {
+ .name = "slimbus2_fclk_0",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_24mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_slimbus_clk = {
+ .name = "slimbus2_slimbus_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &pad_slimbus_core_clks_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk slimbus2_fck = {
+ .name = "slimbus2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk smartreflex_core_fck = {
+ .name = "smartreflex_core_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_ao_clkdm",
+ .parent = &l4_wkup_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk smartreflex_iva_fck = {
+ .name = "smartreflex_iva_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_ao_clkdm",
+ .parent = &l4_wkup_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk smartreflex_mpu_fck = {
+ .name = "smartreflex_mpu_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_ao_clkdm",
+ .parent = &l4_wkup_clk_mux_ck,
+ .recalc = &followparent_recalc,
+};
+
+/* Merged dmt1_clk_mux into timer1 */
+static struct clk timer1_fck = {
+ .name = "timer1_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+};
+
+/* Merged cm2_dm10_mux into timer10 */
+static struct clk timer10_fck = {
+ .name = "timer10_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm11_mux into timer11 */
+static struct clk timer11_fck = {
+ .name = "timer11_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm2_mux into timer2 */
+static struct clk timer2_fck = {
+ .name = "timer2_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm3_mux into timer3 */
+static struct clk timer3_fck = {
+ .name = "timer3_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+/* Merged cm2_dm4_mux into timer4 */
+static struct clk timer4_fck = {
+ .name = "timer4_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+static const struct clksel timer5_sync_mux_sel[] = {
+ { .parent = &syc_clk_div_ck, .rates = div_1_0_rates },
+ { .parent = &sys_32k_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+/* Merged timer5_sync_mux into timer5 */
+static struct clk timer5_fck = {
+ .name = "timer5_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer6_sync_mux into timer6 */
+static struct clk timer6_fck = {
+ .name = "timer6_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer7_sync_mux into timer7 */
+static struct clk timer7_fck = {
+ .name = "timer7_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged timer8_sync_mux into timer8 */
+static struct clk timer8_fck = {
+ .name = "timer8_fck",
+ .parent = &syc_clk_div_ck,
+ .clksel = timer5_sync_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+};
+
+/* Merged cm2_dm9_mux into timer9 */
+static struct clk timer9_fck = {
+ .name = "timer9_fck",
+ .parent = &sys_clkin_ck,
+ .clksel = abe_dpll_bypass_clk_mux_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_MASK,
+ .ops = &clkops_omap2_dflt,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+};
+
+static struct clk uart1_fck = {
+ .name = "uart1_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart2_fck = {
+ .name = "uart2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart3_fck = {
+ .name = "uart3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk uart4_fck = {
+ .name = "uart4_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_per_clkdm",
+ .parent = &func_48m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_fs_fck = {
+ .name = "usb_host_fs_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &func_48mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel utmi_p1_gfclk_sel[] = {
+ { .parent = &init_60m_fclk, .rates = div_1_0_rates },
+ { .parent = &xclk60mhsp1_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk utmi_p1_gfclk = {
+ .name = "utmi_p1_gfclk",
+ .parent = &init_60m_fclk,
+ .clksel = utmi_p1_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_UTMI_P1_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_host_hs_utmi_p1_clk = {
+ .name = "usb_host_hs_utmi_p1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &utmi_p1_gfclk,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel utmi_p2_gfclk_sel[] = {
+ { .parent = &init_60m_fclk, .rates = div_1_0_rates },
+ { .parent = &xclk60mhsp2_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk utmi_p2_gfclk = {
+ .name = "utmi_p2_gfclk",
+ .parent = &init_60m_fclk,
+ .clksel = utmi_p2_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_UTMI_P2_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_host_hs_utmi_p2_clk = {
+ .name = "usb_host_hs_utmi_p2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &utmi_p2_gfclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_utmi_p3_clk = {
+ .name = "usb_host_hs_utmi_p3_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_hsic480m_p1_clk = {
+ .name = "usb_host_hs_hsic480m_p1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &dpll_usb_m2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_hsic60m_p1_clk = {
+ .name = "usb_host_hs_hsic60m_p1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_hsic60m_p2_clk = {
+ .name = "usb_host_hs_hsic60m_p2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_hsic480m_p2_clk = {
+ .name = "usb_host_hs_hsic480m_p2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &dpll_usb_m2_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_func48mclk = {
+ .name = "usb_host_hs_func48mclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &func_48mc_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_host_hs_fck = {
+ .name = "usb_host_hs_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel otg_60m_gfclk_sel[] = {
+ { .parent = &utmi_phy_clkout_ck, .rates = div_1_0_rates },
+ { .parent = &xclk60motg_ck, .rates = div_1_1_rates },
+ { .parent = NULL },
+};
+
+static struct clk otg_60m_gfclk = {
+ .name = "otg_60m_gfclk",
+ .parent = &utmi_phy_clkout_ck,
+ .clksel = otg_60m_gfclk_sel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_60M_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk usb_otg_hs_xclk = {
+ .name = "usb_otg_hs_xclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_XCLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &otg_60m_gfclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_otg_hs_ick = {
+ .name = "usb_otg_hs_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l3_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_phy_cm_clk32k = {
+ .name = "usb_phy_cm_clk32k",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_ALWON_USBPHY_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_CLK32K_SHIFT,
+ .clkdm_name = "l4_ao_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_usb_ch2_clk = {
+ .name = "usb_tll_hs_usb_ch2_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_usb_ch0_clk = {
+ .name = "usb_tll_hs_usb_ch0_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_usb_ch1_clk = {
+ .name = "usb_tll_hs_usb_ch1_clk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &init_60m_fclk,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usb_tll_hs_ick = {
+ .name = "usb_tll_hs_ick",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l3_init_clkdm",
+ .parent = &l4_div_ck,
+ .recalc = &followparent_recalc,
+};
+
+static const struct clksel_rate div2_14to18_rates[] = {
+ { .div = 14, .val = 0, .flags = RATE_IN_4430 },
+ { .div = 18, .val = 1, .flags = RATE_IN_4430 },
+ { .div = 0 },
+};
+
+static const struct clksel usim_fclk_div[] = {
+ { .parent = &dpll_per_m4x2_ck, .rates = div2_14to18_rates },
+ { .parent = NULL },
+};
+
+static struct clk usim_ck = {
+ .name = "usim_ck",
+ .parent = &dpll_per_m4x2_ck,
+ .clksel = usim_fclk_div,
+ .clksel_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_DIV_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static struct clk usim_fclk = {
+ .name = "usim_fclk",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
+ .enable_bit = OMAP4430_OPTFCLKEN_FCLK_SHIFT,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &usim_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk usim_fck = {
+ .name = "usim_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_USIM_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_HWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wd_timer2_fck = {
+ .name = "wd_timer2_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "l4_wkup_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk wd_timer3_fck = {
+ .name = "wd_timer3_fck",
+ .ops = &clkops_omap2_dflt,
+ .enable_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ .enable_bit = OMAP4430_MODULEMODE_SWCTRL,
+ .clkdm_name = "abe_clkdm",
+ .parent = &sys_32k_ck,
+ .recalc = &followparent_recalc,
+};
+
+/* Remaining optional clocks */
+static const struct clksel stm_clk_div_div[] = {
+ { .parent = &pmd_stm_clock_mux_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
+static struct clk stm_clk_div_ck = {
+ .name = "stm_clk_div_ck",
+ .parent = &pmd_stm_clock_mux_ck,
+ .clksel = stm_clk_div_div,
+ .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_PMD_STM_CLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+static const struct clksel trace_clk_div_div[] = {
+ { .parent = &pmd_trace_clk_mux_ck, .rates = div3_1to4_rates },
+ { .parent = NULL },
+};
+
+static struct clk trace_clk_div_ck = {
+ .name = "trace_clk_div_ck",
+ .parent = &pmd_trace_clk_mux_ck,
+ .clksel = trace_clk_div_div,
+ .clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
+ .clksel_mask = OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,
+ .ops = &clkops_null,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate,
+};
+
+/* SCRM aux clk nodes */
+
+static const struct clksel auxclk_sel[] = {
+ { .parent = &sys_clkin_ck, .rates = div_1_0_rates },
+ { .parent = &dpll_core_m3x2_ck, .rates = div_1_1_rates },
+ { .parent = &dpll_per_m3x2_ck, .rates = div_1_2_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclk0_ck = {
+ .name = "auxclk0_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK0,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK0,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk1_ck = {
+ .name = "auxclk1_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK1,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK1,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk2_ck = {
+ .name = "auxclk2_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK2,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK2,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+static struct clk auxclk3_ck = {
+ .name = "auxclk3_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK3,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK3,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk4_ck = {
+ .name = "auxclk4_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK4,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK4,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static struct clk auxclk5_ck = {
+ .name = "auxclk5_ck",
+ .parent = &sys_clkin_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_omap2_dflt,
+ .clksel = auxclk_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLK5,
+ .clksel_mask = OMAP4_SRCSELECT_MASK,
+ .recalc = &omap2_clksel_recalc,
+ .enable_reg = OMAP4_SCRM_AUXCLK5,
+ .enable_bit = OMAP4_ENABLE_SHIFT,
+};
+
+static const struct clksel auxclkreq_sel[] = {
+ { .parent = &auxclk0_ck, .rates = div_1_0_rates },
+ { .parent = &auxclk1_ck, .rates = div_1_1_rates },
+ { .parent = &auxclk2_ck, .rates = div_1_2_rates },
+ { .parent = &auxclk3_ck, .rates = div_1_3_rates },
+ { .parent = &auxclk4_ck, .rates = div_1_4_rates },
+ { .parent = &auxclk5_ck, .rates = div_1_5_rates },
+ { .parent = NULL },
+};
+
+static struct clk auxclkreq0_ck = {
+ .name = "auxclkreq0_ck",
+ .parent = &auxclk0_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ0,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq1_ck = {
+ .name = "auxclkreq1_ck",
+ .parent = &auxclk1_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ1,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq2_ck = {
+ .name = "auxclkreq2_ck",
+ .parent = &auxclk2_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ2,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq3_ck = {
+ .name = "auxclkreq3_ck",
+ .parent = &auxclk3_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ3,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq4_ck = {
+ .name = "auxclkreq4_ck",
+ .parent = &auxclk4_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ4,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+static struct clk auxclkreq5_ck = {
+ .name = "auxclkreq5_ck",
+ .parent = &auxclk5_ck,
+ .init = &omap2_init_clksel_parent,
+ .ops = &clkops_null,
+ .clksel = auxclkreq_sel,
+ .clksel_reg = OMAP4_SCRM_AUXCLKREQ5,
+ .clksel_mask = OMAP4_MAPPING_MASK,
+ .recalc = &omap2_clksel_recalc,
+};
+
+/*
+ * clkdev
+ */
+
+static struct omap_clk omap44xx_clks[] = {
+ CLK(NULL, "extalt_clkin_ck", &extalt_clkin_ck, CK_443X),
+ CLK(NULL, "pad_clks_ck", &pad_clks_ck, CK_443X),
+ CLK(NULL, "pad_slimbus_core_clks_ck", &pad_slimbus_core_clks_ck, CK_443X),
+ CLK(NULL, "secure_32k_clk_src_ck", &secure_32k_clk_src_ck, CK_443X),
+ CLK(NULL, "slimbus_clk", &slimbus_clk, CK_443X),
+ CLK(NULL, "sys_32k_ck", &sys_32k_ck, CK_443X),
+ CLK(NULL, "virt_12000000_ck", &virt_12000000_ck, CK_443X),
+ CLK(NULL, "virt_13000000_ck", &virt_13000000_ck, CK_443X),
+ CLK(NULL, "virt_16800000_ck", &virt_16800000_ck, CK_443X),
+ CLK(NULL, "virt_19200000_ck", &virt_19200000_ck, CK_443X),
+ CLK(NULL, "virt_26000000_ck", &virt_26000000_ck, CK_443X),
+ CLK(NULL, "virt_27000000_ck", &virt_27000000_ck, CK_443X),
+ CLK(NULL, "virt_38400000_ck", &virt_38400000_ck, CK_443X),
+ CLK(NULL, "sys_clkin_ck", &sys_clkin_ck, CK_443X),
+ CLK(NULL, "tie_low_clock_ck", &tie_low_clock_ck, CK_443X),
+ CLK(NULL, "utmi_phy_clkout_ck", &utmi_phy_clkout_ck, CK_443X),
+ CLK(NULL, "xclk60mhsp1_ck", &xclk60mhsp1_ck, CK_443X),
+ CLK(NULL, "xclk60mhsp2_ck", &xclk60mhsp2_ck, CK_443X),
+ CLK(NULL, "xclk60motg_ck", &xclk60motg_ck, CK_443X),
+ CLK(NULL, "abe_dpll_bypass_clk_mux_ck", &abe_dpll_bypass_clk_mux_ck, CK_443X),
+ CLK(NULL, "abe_dpll_refclk_mux_ck", &abe_dpll_refclk_mux_ck, CK_443X),
+ CLK(NULL, "dpll_abe_ck", &dpll_abe_ck, CK_443X),
+ CLK(NULL, "dpll_abe_x2_ck", &dpll_abe_x2_ck, CK_443X),
+ CLK(NULL, "dpll_abe_m2x2_ck", &dpll_abe_m2x2_ck, CK_443X),
+ CLK(NULL, "abe_24m_fclk", &abe_24m_fclk, CK_443X),
+ CLK(NULL, "abe_clk", &abe_clk, CK_443X),
+ CLK(NULL, "aess_fclk", &aess_fclk, CK_443X),
+ CLK(NULL, "dpll_abe_m3x2_ck", &dpll_abe_m3x2_ck, CK_443X),
+ CLK(NULL, "core_hsd_byp_clk_mux_ck", &core_hsd_byp_clk_mux_ck, CK_443X),
+ CLK(NULL, "dpll_core_ck", &dpll_core_ck, CK_443X),
+ CLK(NULL, "dpll_core_x2_ck", &dpll_core_x2_ck, CK_443X),
+ CLK(NULL, "dpll_core_m6x2_ck", &dpll_core_m6x2_ck, CK_443X),
+ CLK(NULL, "dbgclk_mux_ck", &dbgclk_mux_ck, CK_443X),
+ CLK(NULL, "dpll_core_m2_ck", &dpll_core_m2_ck, CK_443X),
+ CLK(NULL, "ddrphy_ck", &ddrphy_ck, CK_443X),
+ CLK(NULL, "dpll_core_m5x2_ck", &dpll_core_m5x2_ck, CK_443X),
+ CLK(NULL, "div_core_ck", &div_core_ck, CK_443X),
+ CLK(NULL, "div_iva_hs_clk", &div_iva_hs_clk, CK_443X),
+ CLK(NULL, "div_mpu_hs_clk", &div_mpu_hs_clk, CK_443X),
+ CLK(NULL, "dpll_core_m4x2_ck", &dpll_core_m4x2_ck, CK_443X),
+ CLK(NULL, "dll_clk_div_ck", &dll_clk_div_ck, CK_443X),
+ CLK(NULL, "dpll_abe_m2_ck", &dpll_abe_m2_ck, CK_443X),
+ CLK(NULL, "dpll_core_m3x2_ck", &dpll_core_m3x2_ck, CK_443X),
+ CLK(NULL, "dpll_core_m7x2_ck", &dpll_core_m7x2_ck, CK_443X),
+ CLK(NULL, "iva_hsd_byp_clk_mux_ck", &iva_hsd_byp_clk_mux_ck, CK_443X),
+ CLK(NULL, "dpll_iva_ck", &dpll_iva_ck, CK_443X),
+ CLK(NULL, "dpll_iva_x2_ck", &dpll_iva_x2_ck, CK_443X),
+ CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_443X),
+ CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_443X),
+ CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X),
+ CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X),
+ CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_443X),
+ CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_443X),
+ CLK(NULL, "dpll_per_ck", &dpll_per_ck, CK_443X),
+ CLK(NULL, "dpll_per_m2_ck", &dpll_per_m2_ck, CK_443X),
+ CLK(NULL, "dpll_per_x2_ck", &dpll_per_x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m3x2_ck", &dpll_per_m3x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m5x2_ck", &dpll_per_m5x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m6x2_ck", &dpll_per_m6x2_ck, CK_443X),
+ CLK(NULL, "dpll_per_m7x2_ck", &dpll_per_m7x2_ck, CK_443X),
+ CLK(NULL, "dpll_unipro_ck", &dpll_unipro_ck, CK_443X),
+ CLK(NULL, "dpll_unipro_x2_ck", &dpll_unipro_x2_ck, CK_443X),
+ CLK(NULL, "dpll_unipro_m2x2_ck", &dpll_unipro_m2x2_ck, CK_443X),
+ CLK(NULL, "usb_hs_clk_div_ck", &usb_hs_clk_div_ck, CK_443X),
+ CLK(NULL, "dpll_usb_ck", &dpll_usb_ck, CK_443X),
+ CLK(NULL, "dpll_usb_clkdcoldo_ck", &dpll_usb_clkdcoldo_ck, CK_443X),
+ CLK(NULL, "dpll_usb_m2_ck", &dpll_usb_m2_ck, CK_443X),
+ CLK(NULL, "ducati_clk_mux_ck", &ducati_clk_mux_ck, CK_443X),
+ CLK(NULL, "func_12m_fclk", &func_12m_fclk, CK_443X),
+ CLK(NULL, "func_24m_clk", &func_24m_clk, CK_443X),
+ CLK(NULL, "func_24mc_fclk", &func_24mc_fclk, CK_443X),
+ CLK(NULL, "func_48m_fclk", &func_48m_fclk, CK_443X),
+ CLK(NULL, "func_48mc_fclk", &func_48mc_fclk, CK_443X),
+ CLK(NULL, "func_64m_fclk", &func_64m_fclk, CK_443X),
+ CLK(NULL, "func_96m_fclk", &func_96m_fclk, CK_443X),
+ CLK(NULL, "hsmmc6_fclk", &hsmmc6_fclk, CK_443X),
+ CLK(NULL, "init_60m_fclk", &init_60m_fclk, CK_443X),
+ CLK(NULL, "l3_div_ck", &l3_div_ck, CK_443X),
+ CLK(NULL, "l4_div_ck", &l4_div_ck, CK_443X),
+ CLK(NULL, "lp_clk_div_ck", &lp_clk_div_ck, CK_443X),
+ CLK(NULL, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, CK_443X),
+ CLK(NULL, "per_abe_nc_fclk", &per_abe_nc_fclk, CK_443X),
+ CLK(NULL, "mcasp2_fclk", &mcasp2_fclk, CK_443X),
+ CLK(NULL, "mcasp3_fclk", &mcasp3_fclk, CK_443X),
+ CLK(NULL, "ocp_abe_iclk", &ocp_abe_iclk, CK_443X),
+ CLK(NULL, "per_abe_24m_fclk", &per_abe_24m_fclk, CK_443X),
+ CLK(NULL, "pmd_stm_clock_mux_ck", &pmd_stm_clock_mux_ck, CK_443X),
+ CLK(NULL, "pmd_trace_clk_mux_ck", &pmd_trace_clk_mux_ck, CK_443X),
+ CLK(NULL, "syc_clk_div_ck", &syc_clk_div_ck, CK_443X),
+ CLK(NULL, "aes1_fck", &aes1_fck, CK_443X),
+ CLK(NULL, "aes2_fck", &aes2_fck, CK_443X),
+ CLK(NULL, "aess_fck", &aess_fck, CK_443X),
+ CLK(NULL, "bandgap_fclk", &bandgap_fclk, CK_443X),
+ CLK(NULL, "des3des_fck", &des3des_fck, CK_443X),
+ CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
+ CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
+ CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
+ CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X),
+ CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X),
+ CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X),
+ CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X),
+ CLK("omapdss_dss", "ick", &dss_fck, CK_443X),
+ CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
+ CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
+ CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
+ CLK(NULL, "fdif_fck", &fdif_fck, CK_443X),
+ CLK(NULL, "fpka_fck", &fpka_fck, CK_443X),
+ CLK(NULL, "gpio1_dbclk", &gpio1_dbclk, CK_443X),
+ CLK(NULL, "gpio1_ick", &gpio1_ick, CK_443X),
+ CLK(NULL, "gpio2_dbclk", &gpio2_dbclk, CK_443X),
+ CLK(NULL, "gpio2_ick", &gpio2_ick, CK_443X),
+ CLK(NULL, "gpio3_dbclk", &gpio3_dbclk, CK_443X),
+ CLK(NULL, "gpio3_ick", &gpio3_ick, CK_443X),
+ CLK(NULL, "gpio4_dbclk", &gpio4_dbclk, CK_443X),
+ CLK(NULL, "gpio4_ick", &gpio4_ick, CK_443X),
+ CLK(NULL, "gpio5_dbclk", &gpio5_dbclk, CK_443X),
+ CLK(NULL, "gpio5_ick", &gpio5_ick, CK_443X),
+ CLK(NULL, "gpio6_dbclk", &gpio6_dbclk, CK_443X),
+ CLK(NULL, "gpio6_ick", &gpio6_ick, CK_443X),
+ CLK(NULL, "gpmc_ick", &gpmc_ick, CK_443X),
+ CLK(NULL, "gpu_fck", &gpu_fck, CK_443X),
+ CLK("omap2_hdq.0", "fck", &hdq1w_fck, CK_443X),
+ CLK(NULL, "hsi_fck", &hsi_fck, CK_443X),
+ CLK("omap_i2c.1", "fck", &i2c1_fck, CK_443X),
+ CLK("omap_i2c.2", "fck", &i2c2_fck, CK_443X),
+ CLK("omap_i2c.3", "fck", &i2c3_fck, CK_443X),
+ CLK("omap_i2c.4", "fck", &i2c4_fck, CK_443X),
+ CLK(NULL, "ipu_fck", &ipu_fck, CK_443X),
+ CLK(NULL, "iss_ctrlclk", &iss_ctrlclk, CK_443X),
+ CLK(NULL, "iss_fck", &iss_fck, CK_443X),
+ CLK(NULL, "iva_fck", &iva_fck, CK_443X),
+ CLK(NULL, "kbd_fck", &kbd_fck, CK_443X),
+ CLK(NULL, "l3_instr_ick", &l3_instr_ick, CK_443X),
+ CLK(NULL, "l3_main_3_ick", &l3_main_3_ick, CK_443X),
+ CLK(NULL, "mcasp_sync_mux_ck", &mcasp_sync_mux_ck, CK_443X),
+ CLK(NULL, "mcasp_fck", &mcasp_fck, CK_443X),
+ CLK(NULL, "mcbsp1_sync_mux_ck", &mcbsp1_sync_mux_ck, CK_443X),
+ CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_443X),
+ CLK(NULL, "mcbsp2_sync_mux_ck", &mcbsp2_sync_mux_ck, CK_443X),
+ CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_443X),
+ CLK(NULL, "mcbsp3_sync_mux_ck", &mcbsp3_sync_mux_ck, CK_443X),
+ CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_443X),
+ CLK(NULL, "mcbsp4_sync_mux_ck", &mcbsp4_sync_mux_ck, CK_443X),
+ CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_443X),
+ CLK(NULL, "mcpdm_fck", &mcpdm_fck, CK_443X),
+ CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_443X),
+ CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_443X),
+ CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_443X),
+ CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_443X),
+ CLK("omap_hsmmc.0", "fck", &mmc1_fck, CK_443X),
+ CLK("omap_hsmmc.1", "fck", &mmc2_fck, CK_443X),
+ CLK("omap_hsmmc.2", "fck", &mmc3_fck, CK_443X),
+ CLK("omap_hsmmc.3", "fck", &mmc4_fck, CK_443X),
+ CLK("omap_hsmmc.4", "fck", &mmc5_fck, CK_443X),
+ CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X),
+ CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X),
+ CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X),
+ CLK("omap_rng", "ick", &rng_ick, CK_443X),
+ CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X),
+ CLK(NULL, "sl2if_ick", &sl2if_ick, CK_443X),
+ CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X),
+ CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X),
+ CLK(NULL, "slimbus1_fclk_2", &slimbus1_fclk_2, CK_443X),
+ CLK(NULL, "slimbus1_slimbus_clk", &slimbus1_slimbus_clk, CK_443X),
+ CLK(NULL, "slimbus1_fck", &slimbus1_fck, CK_443X),
+ CLK(NULL, "slimbus2_fclk_1", &slimbus2_fclk_1, CK_443X),
+ CLK(NULL, "slimbus2_fclk_0", &slimbus2_fclk_0, CK_443X),
+ CLK(NULL, "slimbus2_slimbus_clk", &slimbus2_slimbus_clk, CK_443X),
+ CLK(NULL, "slimbus2_fck", &slimbus2_fck, CK_443X),
+ CLK(NULL, "smartreflex_core_fck", &smartreflex_core_fck, CK_443X),
+ CLK(NULL, "smartreflex_iva_fck", &smartreflex_iva_fck, CK_443X),
+ CLK(NULL, "smartreflex_mpu_fck", &smartreflex_mpu_fck, CK_443X),
+ CLK(NULL, "gpt1_fck", &timer1_fck, CK_443X),
+ CLK(NULL, "gpt10_fck", &timer10_fck, CK_443X),
+ CLK(NULL, "gpt11_fck", &timer11_fck, CK_443X),
+ CLK(NULL, "gpt2_fck", &timer2_fck, CK_443X),
+ CLK(NULL, "gpt3_fck", &timer3_fck, CK_443X),
+ CLK(NULL, "gpt4_fck", &timer4_fck, CK_443X),
+ CLK(NULL, "gpt5_fck", &timer5_fck, CK_443X),
+ CLK(NULL, "gpt6_fck", &timer6_fck, CK_443X),
+ CLK(NULL, "gpt7_fck", &timer7_fck, CK_443X),
+ CLK(NULL, "gpt8_fck", &timer8_fck, CK_443X),
+ CLK(NULL, "gpt9_fck", &timer9_fck, CK_443X),
+ CLK(NULL, "uart1_fck", &uart1_fck, CK_443X),
+ CLK(NULL, "uart2_fck", &uart2_fck, CK_443X),
+ CLK(NULL, "uart3_fck", &uart3_fck, CK_443X),
+ CLK(NULL, "uart4_fck", &uart4_fck, CK_443X),
+ CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X),
+ CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X),
+ CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X),
+ CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p2_clk", &usb_host_hs_utmi_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_utmi_p3_clk", &usb_host_hs_utmi_p3_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic480m_p1_clk", &usb_host_hs_hsic480m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p1_clk", &usb_host_hs_hsic60m_p1_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic60m_p2_clk", &usb_host_hs_hsic60m_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X),
+ CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X),
+ CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X),
+ CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X),
+ CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X),
+ CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X),
+ CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X),
+ CLK(NULL, "usb_phy_cm_clk32k", &usb_phy_cm_clk32k, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch2_clk", &usb_tll_hs_usb_ch2_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X),
+ CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X),
+ CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X),
+ CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X),
+ CLK(NULL, "usim_ck", &usim_ck, CK_443X),
+ CLK(NULL, "usim_fclk", &usim_fclk, CK_443X),
+ CLK(NULL, "usim_fck", &usim_fck, CK_443X),
+ CLK("omap_wdt", "fck", &wd_timer2_fck, CK_443X),
+ CLK(NULL, "mailboxes_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "wd_timer3_fck", &wd_timer3_fck, CK_443X),
+ CLK(NULL, "stm_clk_div_ck", &stm_clk_div_ck, CK_443X),
+ CLK(NULL, "trace_clk_div_ck", &trace_clk_div_ck, CK_443X),
+ CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt1_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt2_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt3_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt4_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt5_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt6_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt7_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt8_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt9_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt10_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "gpt11_ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap_i2c.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap_hsmmc.0", "ick", &dummy_ck, CK_443X),
+ CLK("omap_hsmmc.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap_hsmmc.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap_hsmmc.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap_hsmmc.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
+ CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
+ CLK(NULL, "uart1_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
+ CLK(NULL, "uart4_ick", &dummy_ck, CK_443X),
+ CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
+ CLK(NULL, "auxclk0_ck", &auxclk0_ck, CK_443X),
+ CLK(NULL, "auxclk1_ck", &auxclk1_ck, CK_443X),
+ CLK(NULL, "auxclk2_ck", &auxclk2_ck, CK_443X),
+ CLK(NULL, "auxclk3_ck", &auxclk3_ck, CK_443X),
+ CLK(NULL, "auxclk4_ck", &auxclk4_ck, CK_443X),
+ CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X),
+ CLK(NULL, "auxclkreq0_ck", &auxclkreq0_ck, CK_443X),
+ CLK(NULL, "auxclkreq1_ck", &auxclkreq1_ck, CK_443X),
+ CLK(NULL, "auxclkreq2_ck", &auxclkreq2_ck, CK_443X),
+ CLK(NULL, "auxclkreq3_ck", &auxclkreq3_ck, CK_443X),
+ CLK(NULL, "auxclkreq4_ck", &auxclkreq4_ck, CK_443X),
+ CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X),
+};
+
+int __init omap4xxx_clk_init(void)
+{
+ struct omap_clk *c;
+ u32 cpu_clkflg;
+
+ if (cpu_is_omap44xx()) {
+ cpu_mask = RATE_IN_4430;
+ cpu_clkflg = CK_443X;
+ }
+
+ clk_init(&omap2_clk_functions);
+
+ for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
+ c++)
+ clk_preinit(c->lk.clk);
+
+ for (c = omap44xx_clks; c < omap44xx_clks + ARRAY_SIZE(omap44xx_clks);
+ c++)
+ if (c->cpu & cpu_clkflg) {
+ clkdev_add(&c->lk);
+ clk_register(c->lk.clk);
+ omap2_init_clk_clkdm(c->lk.clk);
+ }
+
+ /* Disable autoidle on all clocks; let the PM code enable it later */
+ omap_clk_disable_autoidle_all();
+
+ recalculate_root_clocks();
+
+ /*
+ * Only enable those clocks we will need, let the drivers
+ * enable other clocks as necessary
+ */
+ clk_enable_init_clocks();
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/clock_common_data.c b/arch/arm/mach-omap2/clock_common_data.c
new file mode 100644
index 00000000..6424d46b
--- /dev/null
+++ b/arch/arm/mach-omap2/clock_common_data.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-omap2/clock_common_data.c
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Contacts:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains clock data that is common to both the OMAP2xxx and
+ * OMAP3xxx clock definition files.
+ */
+
+#include "clock.h"
+
+/* clksel_rate data common to 24xx/343x */
+const struct clksel_rate gpt_32k_rates[] = {
+ { .div = 1, .val = 0, .flags = RATE_IN_24XX | RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+const struct clksel_rate gpt_sys_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+const struct clksel_rate gfx_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX | RATE_IN_3XXX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX | RATE_IN_3XXX },
+ { .div = 3, .val = 3, .flags = RATE_IN_243X | RATE_IN_3XXX },
+ { .div = 4, .val = 4, .flags = RATE_IN_243X | RATE_IN_3XXX },
+ { .div = 0 }
+};
+
+const struct clksel_rate dsp_ick_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 3, .val = 3, .flags = RATE_IN_243X },
+ { .div = 0 },
+};
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
new file mode 100644
index 00000000..6cb6c032
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -0,0 +1,890 @@
+/*
+ * OMAP2/3/4 clockdomain framework functions
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Paul Walmsley and Jouni Högander
+ * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/limits.h>
+#include <linux/err.h>
+
+#include <linux/io.h>
+
+#include <linux/bitops.h>
+
+#include <plat/clock.h>
+#include "clockdomain.h"
+
+/* clkdm_list contains all registered struct clockdomains */
+static LIST_HEAD(clkdm_list);
+
+/* array of clockdomain deps to be added/removed when clkdm in hwsup mode */
+static struct clkdm_autodep *autodeps;
+
+static struct clkdm_ops *arch_clkdm;
+
+/* Private functions */
+
+static struct clockdomain *_clkdm_lookup(const char *name)
+{
+ struct clockdomain *clkdm, *temp_clkdm;
+
+ if (!name)
+ return NULL;
+
+ clkdm = NULL;
+
+ list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+ if (!strcmp(name, temp_clkdm->name)) {
+ clkdm = temp_clkdm;
+ break;
+ }
+ }
+
+ return clkdm;
+}
+
+/**
+ * _clkdm_register - register a clockdomain
+ * @clkdm: struct clockdomain * to register
+ *
+ * Adds a clockdomain to the internal clockdomain list.
+ * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+static int _clkdm_register(struct clockdomain *clkdm)
+{
+ struct powerdomain *pwrdm;
+
+ if (!clkdm || !clkdm->name)
+ return -EINVAL;
+
+ if (!omap_chip_is(clkdm->omap_chip))
+ return -EINVAL;
+
+ pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
+ if (!pwrdm) {
+ pr_err("clockdomain: %s: powerdomain %s does not exist\n",
+ clkdm->name, clkdm->pwrdm.name);
+ return -EINVAL;
+ }
+ clkdm->pwrdm.ptr = pwrdm;
+
+ /* Verify that the clockdomain is not already registered */
+ if (_clkdm_lookup(clkdm->name))
+ return -EEXIST;
+
+ list_add(&clkdm->node, &clkdm_list);
+
+ pwrdm_add_clkdm(pwrdm, clkdm);
+
+ pr_debug("clockdomain: registered %s\n", clkdm->name);
+
+ return 0;
+}
+
+/* _clkdm_deps_lookup - look up the specified clockdomain in a clkdm list */
+static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
+ struct clkdm_dep *deps)
+{
+ struct clkdm_dep *cd;
+
+ if (!clkdm || !deps || !omap_chip_is(clkdm->omap_chip))
+ return ERR_PTR(-EINVAL);
+
+ for (cd = deps; cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+
+ if (!cd->clkdm && cd->clkdm_name)
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+ if (cd->clkdm == clkdm)
+ break;
+ }
+
+ if (!cd->clkdm_name)
+ return ERR_PTR(-ENOENT);
+
+ return cd;
+}
+
+/*
+ * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store
+ * @autodep: struct clkdm_autodep * to resolve
+ *
+ * Resolve autodep clockdomain names to clockdomain pointers via
+ * clkdm_lookup() and store the pointers in the autodep structure. An
+ * "autodep" is a clockdomain sleep/wakeup dependency that is
+ * automatically added and removed whenever clocks in the associated
+ * clockdomain are enabled or disabled (respectively) when the
+ * clockdomain is in hardware-supervised mode. Meant to be called
+ * once at clockdomain layer initialization, since these should remain
+ * fixed for a particular architecture. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
+ */
+static void _autodep_lookup(struct clkdm_autodep *autodep)
+{
+ struct clockdomain *clkdm;
+
+ if (!autodep)
+ return;
+
+ if (!omap_chip_is(autodep->omap_chip))
+ return;
+
+ clkdm = clkdm_lookup(autodep->clkdm.name);
+ if (!clkdm) {
+ pr_err("clockdomain: autodeps: clockdomain %s does not exist\n",
+ autodep->clkdm.name);
+ clkdm = ERR_PTR(-ENOENT);
+ }
+ autodep->clkdm.ptr = clkdm;
+}
+
+/*
+ * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
+ * @clkdm: struct clockdomain *
+ *
+ * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
+ * in hardware-supervised mode. Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is enabled. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
+ */
+void _clkdm_add_autodeps(struct clockdomain *clkdm)
+{
+ struct clkdm_autodep *autodep;
+
+ if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
+ return;
+
+ for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
+ if (IS_ERR(autodep->clkdm.ptr))
+ continue;
+
+ if (!omap_chip_is(autodep->omap_chip))
+ continue;
+
+ pr_debug("clockdomain: adding %s sleepdep/wkdep for "
+ "clkdm %s\n", autodep->clkdm.ptr->name,
+ clkdm->name);
+
+ clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr);
+ clkdm_add_wkdep(clkdm, autodep->clkdm.ptr);
+ }
+}
+
+/*
+ * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
+ * in hardware-supervised mode. Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is disabled. No return value.
+ *
+ * XXX autodeps are deprecated and should be removed at the earliest
+ * opportunity
+ */
+void _clkdm_del_autodeps(struct clockdomain *clkdm)
+{
+ struct clkdm_autodep *autodep;
+
+ if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS)
+ return;
+
+ for (autodep = autodeps; autodep->clkdm.ptr; autodep++) {
+ if (IS_ERR(autodep->clkdm.ptr))
+ continue;
+
+ if (!omap_chip_is(autodep->omap_chip))
+ continue;
+
+ pr_debug("clockdomain: removing %s sleepdep/wkdep for "
+ "clkdm %s\n", autodep->clkdm.ptr->name,
+ clkdm->name);
+
+ clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr);
+ clkdm_del_wkdep(clkdm, autodep->clkdm.ptr);
+ }
+}
+
+/**
+ * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
+ * @clkdm: clockdomain that we are resolving dependencies for
+ * @clkdm_deps: ptr to array of struct clkdm_deps to resolve
+ *
+ * Iterates through @clkdm_deps, looking up the struct clockdomain named by
+ * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep.
+ * No return value.
+ */
+static void _resolve_clkdm_deps(struct clockdomain *clkdm,
+ struct clkdm_dep *clkdm_deps)
+{
+ struct clkdm_dep *cd;
+
+ for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ if (cd->clkdm)
+ continue;
+ cd->clkdm = _clkdm_lookup(cd->clkdm_name);
+
+ WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen",
+ clkdm->name, cd->clkdm_name);
+ }
+}
+
+/* Public functions */
+
+/**
+ * clkdm_init - set up the clockdomain layer
+ * @clkdms: optional pointer to an array of clockdomains to register
+ * @init_autodeps: optional pointer to an array of autodeps to register
+ * @custom_funcs: func pointers for arch specific implementations
+ *
+ * Set up internal state. If a pointer to an array of clockdomains
+ * @clkdms was supplied, loop through the list of clockdomains,
+ * register all that are available on the current platform. Similarly,
+ * if a pointer to an array of clockdomain autodependencies
+ * @init_autodeps was provided, register those. No return value.
+ */
+void clkdm_init(struct clockdomain **clkdms,
+ struct clkdm_autodep *init_autodeps,
+ struct clkdm_ops *custom_funcs)
+{
+ struct clockdomain **c = NULL;
+ struct clockdomain *clkdm;
+ struct clkdm_autodep *autodep = NULL;
+
+ if (!custom_funcs)
+ WARN(1, "No custom clkdm functions registered\n");
+ else
+ arch_clkdm = custom_funcs;
+
+ if (clkdms)
+ for (c = clkdms; *c; c++)
+ _clkdm_register(*c);
+
+ autodeps = init_autodeps;
+ if (autodeps)
+ for (autodep = autodeps; autodep->clkdm.ptr; autodep++)
+ _autodep_lookup(autodep);
+
+ /*
+ * Put all clockdomains into software-supervised mode; PM code
+ * should later enable hardware-supervised mode as appropriate
+ */
+ list_for_each_entry(clkdm, &clkdm_list, node) {
+ if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
+ clkdm_wakeup(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
+ clkdm_deny_idle(clkdm);
+
+ _resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
+ clkdm_clear_all_wkdeps(clkdm);
+
+ _resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
+ clkdm_clear_all_sleepdeps(clkdm);
+ }
+}
+
+/**
+ * clkdm_lookup - look up a clockdomain by name, return a pointer
+ * @name: name of clockdomain
+ *
+ * Find a registered clockdomain by its name @name. Returns a pointer
+ * to the struct clockdomain if found, or NULL otherwise.
+ */
+struct clockdomain *clkdm_lookup(const char *name)
+{
+ struct clockdomain *clkdm, *temp_clkdm;
+
+ if (!name)
+ return NULL;
+
+ clkdm = NULL;
+
+ list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+ if (!strcmp(name, temp_clkdm->name)) {
+ clkdm = temp_clkdm;
+ break;
+ }
+ }
+
+ return clkdm;
+}
+
+/**
+ * clkdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each registered clockdomain.
+ * The callback function @fn can return anything but 0 to bail
+ * out early from the iterator. The callback function is called with
+ * the clkdm_mutex held, so no clockdomain structure manipulation
+ * functions should be called from the callback, although hardware
+ * clockdomain control functions are fine. Returns the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure; or -EINVAL if the function pointer
+ * is null.
+ */
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+ void *user)
+{
+ struct clockdomain *clkdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(clkdm, &clkdm_list, node) {
+ ret = (*fn)(clkdm, user);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+ * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in
+ * @clkdm: struct clockdomain *
+ *
+ * Return a pointer to the struct powerdomain that the specified clockdomain
+ * @clkdm exists in, or returns NULL if @clkdm is NULL.
+ */
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return NULL;
+
+ return clkdm->pwrdm.ptr;
+}
+
+
+/* Hardware clockdomain control */
+
+/**
+ * clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * When the clockdomain represented by @clkdm2 wakes up, wake up
+ * @clkdm1. Implemented in hardware on the OMAP, this feature is
+ * designed to reduce wakeup latency of the dependent clockdomain @clkdm1.
+ * Returns -EINVAL if presented with invalid clockdomain pointers,
+ * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon
+ * success.
+ */
+int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+ return ret;
+ }
+
+ if (atomic_inc_return(&cd->wkdep_usecount) == 1) {
+ pr_debug("clockdomain: hardware will wake up %s when %s wakes "
+ "up\n", clkdm1->name, clkdm2->name);
+
+ ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
+ }
+
+ return ret;
+}
+
+/**
+ * clkdm_del_wkdep - remove a wakeup dependency from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2
+ * wakes up. Returns -EINVAL if presented with invalid clockdomain
+ * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or
+ * 0 upon success.
+ */
+int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+ return ret;
+ }
+
+ if (atomic_dec_return(&cd->wkdep_usecount) == 0) {
+ pr_debug("clockdomain: hardware will no longer wake up %s "
+ "after %s wakes up\n", clkdm1->name, clkdm2->name);
+
+ ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2);
+ }
+
+ return ret;
+}
+
+/**
+ * clkdm_read_wkdep - read wakeup dependency state from clkdm2 to clkdm1
+ * @clkdm1: wake this struct clockdomain * up (dependent)
+ * @clkdm2: when this struct clockdomain * wakes up (source)
+ *
+ * Return 1 if a hardware wakeup dependency exists wherein @clkdm1 will be
+ * awoken when @clkdm2 wakes up; 0 if dependency is not set; -EINVAL
+ * if either clockdomain pointer is invalid; or -ENOENT if the hardware
+ * is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * wakeup dependencies. Wakeup dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_read_wkdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", clkdm1->name, clkdm2->name);
+ return ret;
+ }
+
+ /* XXX It's faster to return the atomic wkdep_usecount */
+ return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);
+}
+
+/**
+ * clkdm_clear_all_wkdeps - remove all wakeup dependencies from target clkdm
+ * @clkdm: struct clockdomain * to remove all wakeup dependencies from
+ *
+ * Remove all inter-clockdomain wakeup dependencies that could cause
+ * @clkdm to wake. Intended to be used during boot to initialize the
+ * PRCM to a known state, after all clockdomains are put into swsup idle
+ * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
+ * 0 upon success.
+ */
+int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_wkdeps)
+ return -EINVAL;
+
+ return arch_clkdm->clkdm_clear_all_wkdeps(clkdm);
+}
+
+/**
+ * clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Prevent @clkdm1 from automatically going inactive (and then to
+ * retention or off) if @clkdm2 is active. Returns -EINVAL if
+ * presented with invalid clockdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep
+ * dependencies, -ENOENT if the specified dependency cannot be set in
+ * hardware, or 0 upon success.
+ */
+int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", clkdm1->name,
+ clkdm2->name);
+ return ret;
+ }
+
+ if (atomic_inc_return(&cd->sleepdep_usecount) == 1) {
+ pr_debug("clockdomain: will prevent %s from sleeping if %s "
+ "is active\n", clkdm1->name, clkdm2->name);
+
+ ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);
+ }
+
+ return ret;
+}
+
+/**
+ * clkdm_del_sleepdep - remove a sleep dependency from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Allow @clkdm1 to automatically go inactive (and then to retention or
+ * off), independent of the activity state of @clkdm2. Returns -EINVAL
+ * if presented with invalid clockdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be cleared in hardware, or
+ * 0 upon success.
+ */
+int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", clkdm1->name,
+ clkdm2->name);
+ return ret;
+ }
+
+ if (atomic_dec_return(&cd->sleepdep_usecount) == 0) {
+ pr_debug("clockdomain: will no longer prevent %s from "
+ "sleeping if %s is active\n", clkdm1->name,
+ clkdm2->name);
+
+ ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2);
+ }
+
+ return ret;
+}
+
+/**
+ * clkdm_read_sleepdep - read sleep dependency state from clkdm2 to clkdm1
+ * @clkdm1: prevent this struct clockdomain * from sleeping (dependent)
+ * @clkdm2: when this struct clockdomain * is active (source)
+ *
+ * Return 1 if a hardware sleep dependency exists wherein @clkdm1 will
+ * not be allowed to automatically go inactive if @clkdm2 is active;
+ * 0 if @clkdm1's automatic power state inactivity transition is independent
+ * of @clkdm2's; -EINVAL if either clockdomain pointer is invalid or called
+ * on a machine that does not support software-configurable hardware sleep
+ * dependencies; or -ENOENT if the hardware is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * sleep dependencies. Sleep dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
+{
+ struct clkdm_dep *cd;
+ int ret = 0;
+
+ if (!clkdm1 || !clkdm2)
+ return -EINVAL;
+
+ cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
+ if (IS_ERR(cd))
+ ret = PTR_ERR(cd);
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_read_sleepdep)
+ ret = -EINVAL;
+
+ if (ret) {
+ pr_debug("clockdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", clkdm1->name,
+ clkdm2->name);
+ return ret;
+ }
+
+ /* XXX It's faster to return the atomic sleepdep_usecount */
+ return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);
+}
+
+/**
+ * clkdm_clear_all_sleepdeps - remove all sleep dependencies from target clkdm
+ * @clkdm: struct clockdomain * to remove all sleep dependencies from
+ *
+ * Remove all inter-clockdomain sleep dependencies that could prevent
+ * @clkdm from idling. Intended to be used during boot to initialize the
+ * PRCM to a known state, after all clockdomains are put into swsup idle
+ * and woken up. Returns -EINVAL if @clkdm pointer is invalid, or
+ * 0 upon success.
+ */
+int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_clear_all_sleepdeps)
+ return -EINVAL;
+
+ return arch_clkdm->clkdm_clear_all_sleepdeps(clkdm);
+}
+
+/**
+ * clkdm_sleep - force clockdomain sleep transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a sleep transition on the specified
+ * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if
+ * clockdomain does not support software-initiated sleep; 0 upon
+ * success.
+ */
+int clkdm_sleep(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ pr_debug("clockdomain: %s does not support forcing "
+ "sleep via software\n", clkdm->name);
+ return -EINVAL;
+ }
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_sleep)
+ return -EINVAL;
+
+ pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
+
+ return arch_clkdm->clkdm_sleep(clkdm);
+}
+
+/**
+ * clkdm_wakeup - force clockdomain wakeup transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a wakeup transition on the specified
+ * clockdomain @clkdm. Returns -EINVAL if @clkdm is NULL or if the
+ * clockdomain does not support software-controlled wakeup; 0 upon
+ * success.
+ */
+int clkdm_wakeup(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+ pr_debug("clockdomain: %s does not support forcing "
+ "wakeup via software\n", clkdm->name);
+ return -EINVAL;
+ }
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_wakeup)
+ return -EINVAL;
+
+ pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
+
+ return arch_clkdm->clkdm_wakeup(clkdm);
+}
+
+/**
+ * clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Allow the hardware to automatically switch the clockdomain @clkdm into
+ * active or idle states, as needed by downstream clocks. If the
+ * clockdomain has any downstream clocks enabled in the clock
+ * framework, wkdep/sleepdep autodependencies are added; this is so
+ * device drivers can read and write to the device. No return value.
+ */
+void clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+ pr_debug("clock: automatic idle transitions cannot be enabled "
+ "on clockdomain %s\n", clkdm->name);
+ return;
+ }
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
+ return;
+
+ pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
+ clkdm->name);
+
+ arch_clkdm->clkdm_allow_idle(clkdm);
+ pwrdm_clkdm_state_switch(clkdm);
+}
+
+/**
+ * clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Prevent the hardware from automatically switching the clockdomain
+ * @clkdm into inactive or idle states. If the clockdomain has
+ * downstream clocks enabled in the clock framework, wkdep/sleepdep
+ * autodependencies are removed. No return value.
+ */
+void clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
+ pr_debug("clockdomain: automatic idle transitions cannot be "
+ "disabled on %s\n", clkdm->name);
+ return;
+ }
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
+ return;
+
+ pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
+ clkdm->name);
+
+ arch_clkdm->clkdm_deny_idle(clkdm);
+}
+
+
+/* Clockdomain-to-clock framework interface code */
+
+/**
+ * clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the enabled downstream clock
+ *
+ * Increment the usecount of the clockdomain @clkdm and ensure that it
+ * is awake before @clk is enabled. Intended to be called by
+ * clk_enable() code. If the clockdomain is in software-supervised
+ * idle mode, force the clockdomain to wake. If the clockdomain is in
+ * hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
+ * ensure that devices in the clockdomain can be read from/written to
+ * by on-chip processors. Returns -EINVAL if passed null pointers;
+ * returns 0 upon success or if the clockdomain is in hwsup idle mode.
+ */
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
+{
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream clocks for debugging purposes?
+ */
+
+ if (!clkdm || !clk)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_clk_enable)
+ return -EINVAL;
+
+ if (atomic_inc_return(&clkdm->usecount) > 1)
+ return 0;
+
+ /* Clockdomain now has one enabled downstream clock */
+
+ pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
+ clk->name);
+
+ arch_clkdm->clkdm_clk_enable(clkdm);
+ pwrdm_wait_transition(clkdm->pwrdm.ptr);
+ pwrdm_clkdm_state_switch(clkdm);
+
+ return 0;
+}
+
+/**
+ * clkdm_clk_disable - remove an enabled downstream clock from this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the disabled downstream clock
+ *
+ * Decrement the usecount of this clockdomain @clkdm when @clk is
+ * disabled. Intended to be called by clk_disable() code. If the
+ * clockdomain usecount goes to 0, put the clockdomain to sleep
+ * (software-supervised mode) or remove the clkdm autodependencies
+ * (hardware-supervised mode). Returns -EINVAL if passed null
+ * pointers; -ERANGE if the @clkdm usecount underflows and debugging
+ * is enabled; or returns 0 upon success or if the clockdomain is in
+ * hwsup idle mode.
+ */
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+{
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream clocks for debugging purposes?
+ */
+
+ if (!clkdm || !clk)
+ return -EINVAL;
+
+ if (!arch_clkdm || !arch_clkdm->clkdm_clk_disable)
+ return -EINVAL;
+
+#ifdef DEBUG
+ if (atomic_read(&clkdm->usecount) == 0) {
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+#endif
+
+ if (atomic_dec_return(&clkdm->usecount) > 0)
+ return 0;
+
+ /* All downstream clocks of this clockdomain are now disabled */
+
+ pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
+ clk->name);
+
+ arch_clkdm->clkdm_clk_disable(clkdm);
+ pwrdm_clkdm_state_switch(clkdm);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
new file mode 100644
index 00000000..5823584d
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -0,0 +1,197 @@
+/*
+ * arch/arm/plat-omap/include/mach/clockdomain.h
+ *
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008-2011 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H
+
+#include <linux/init.h>
+
+#include "powerdomain.h"
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/*
+ * Clockdomain flags
+ *
+ * XXX Document CLKDM_CAN_* flags
+ *
+ * CLKDM_NO_AUTODEPS: Prevent "autodeps" from being added/removed from this
+ * clockdomain. (Currently, this applies to OMAP3 clockdomains only.)
+ */
+#define CLKDM_CAN_FORCE_SLEEP (1 << 0)
+#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)
+#define CLKDM_CAN_ENABLE_AUTO (1 << 2)
+#define CLKDM_CAN_DISABLE_AUTO (1 << 3)
+#define CLKDM_NO_AUTODEPS (1 << 4)
+
+#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
+#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
+#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
+
+/**
+ * struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
+ * @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
+ * @omap_chip: OMAP chip types that this autodep is valid on
+ *
+ * A clockdomain that should have wkdeps and sleepdeps added when a
+ * clockdomain should stay active in hwsup mode; and conversely,
+ * removed when the clockdomain should be allowed to go inactive in
+ * hwsup mode.
+ *
+ * Autodeps are deprecated and should be removed after
+ * omap_hwmod-based fine-grained module idle control is added.
+ */
+struct clkdm_autodep {
+ union {
+ const char *name;
+ struct clockdomain *ptr;
+ } clkdm;
+ const struct omap_chip_id omap_chip;
+};
+
+/**
+ * struct clkdm_dep - encode dependencies between clockdomains
+ * @clkdm_name: clockdomain name
+ * @clkdm: pointer to the struct clockdomain of @clkdm_name
+ * @omap_chip: OMAP chip types that this dependency is valid on
+ * @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake
+ * @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle
+ *
+ * Statically defined. @clkdm is resolved from @clkdm_name at runtime and
+ * should not be pre-initialized.
+ *
+ * XXX Should also include hardware (fixed) dependencies.
+ */
+struct clkdm_dep {
+ const char *clkdm_name;
+ struct clockdomain *clkdm;
+ atomic_t wkdep_usecount;
+ atomic_t sleepdep_usecount;
+ const struct omap_chip_id omap_chip;
+};
+
+/**
+ * struct clockdomain - OMAP clockdomain
+ * @name: clockdomain name
+ * @pwrdm: powerdomain containing this clockdomain
+ * @clktrctrl_reg: CLKSTCTRL reg for the given clock domain
+ * @clktrctrl_mask: CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg
+ * @flags: Clockdomain capability flags
+ * @dep_bit: Bit shift of this clockdomain's PM_WKDEP/CM_SLEEPDEP bit
+ * @prcm_partition: (OMAP4 only) PRCM partition ID for this clkdm's registers
+ * @cm_inst: (OMAP4 only) CM instance register offset
+ * @clkdm_offs: (OMAP4 only) CM clockdomain register offset
+ * @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
+ * @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
+ * @omap_chip: OMAP chip types that this clockdomain is valid on
+ * @usecount: Usecount tracking
+ * @node: list_head to link all clockdomains together
+ *
+ * @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only)
+ * @cm_inst should be a macro ending in _INST from the OMAP4 CM instance
+ * definitions (OMAP4 only)
+ * @clkdm_offs should be a macro ending in _CDOFFS from the OMAP4 CM instance
+ * definitions (OMAP4 only)
+ */
+struct clockdomain {
+ const char *name;
+ union {
+ const char *name;
+ struct powerdomain *ptr;
+ } pwrdm;
+ const u16 clktrctrl_mask;
+ const u8 flags;
+ const u8 dep_bit;
+ const u8 prcm_partition;
+ const s16 cm_inst;
+ const u16 clkdm_offs;
+ struct clkdm_dep *wkdep_srcs;
+ struct clkdm_dep *sleepdep_srcs;
+ const struct omap_chip_id omap_chip;
+ atomic_t usecount;
+ struct list_head node;
+};
+
+/**
+ * struct clkdm_ops - Arch specific function implementations
+ * @clkdm_add_wkdep: Add a wakeup dependency between clk domains
+ * @clkdm_del_wkdep: Delete a wakeup dependency between clk domains
+ * @clkdm_read_wkdep: Read wakeup dependency state between clk domains
+ * @clkdm_clear_all_wkdeps: Remove all wakeup dependencies from the clk domain
+ * @clkdm_add_sleepdep: Add a sleep dependency between clk domains
+ * @clkdm_del_sleepdep: Delete a sleep dependency between clk domains
+ * @clkdm_read_sleepdep: Read sleep dependency state between clk domains
+ * @clkdm_clear_all_sleepdeps: Remove all sleep dependencies from the clk domain
+ * @clkdm_sleep: Force a clockdomain to sleep
+ * @clkdm_wakeup: Force a clockdomain to wakeup
+ * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain
+ * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
+ * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
+ * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ */
+struct clkdm_ops {
+ int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_del_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_read_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_clear_all_wkdeps)(struct clockdomain *clkdm);
+ int (*clkdm_add_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_del_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_read_sleepdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+ int (*clkdm_clear_all_sleepdeps)(struct clockdomain *clkdm);
+ int (*clkdm_sleep)(struct clockdomain *clkdm);
+ int (*clkdm_wakeup)(struct clockdomain *clkdm);
+ void (*clkdm_allow_idle)(struct clockdomain *clkdm);
+ void (*clkdm_deny_idle)(struct clockdomain *clkdm);
+ int (*clkdm_clk_enable)(struct clockdomain *clkdm);
+ int (*clkdm_clk_disable)(struct clockdomain *clkdm);
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps,
+ struct clkdm_ops *custom_funcs);
+struct clockdomain *clkdm_lookup(const char *name);
+
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
+ void *user);
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
+
+int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_clear_all_wkdeps(struct clockdomain *clkdm);
+int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
+int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm);
+
+void clkdm_allow_idle(struct clockdomain *clkdm);
+void clkdm_deny_idle(struct clockdomain *clkdm);
+
+int clkdm_wakeup(struct clockdomain *clkdm);
+int clkdm_sleep(struct clockdomain *clkdm);
+
+int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+
+extern void __init omap2xxx_clockdomains_init(void);
+extern void __init omap3xxx_clockdomains_init(void);
+extern void __init omap44xx_clockdomains_init(void);
+extern void _clkdm_add_autodeps(struct clockdomain *clkdm);
+extern void _clkdm_del_autodeps(struct clockdomain *clkdm);
+
+extern struct clkdm_ops omap2_clkdm_operations;
+extern struct clkdm_ops omap3_clkdm_operations;
+extern struct clkdm_ops omap4_clkdm_operations;
+
+#endif
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
new file mode 100644
index 00000000..48d0db7e
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -0,0 +1,274 @@
+/*
+ * OMAP2 and OMAP3 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <plat/prcm.h>
+#include "prm.h"
+#include "prm2xxx_3xxx.h"
+#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-24xx.h"
+#include "clockdomain.h"
+
+static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ return 0;
+}
+
+static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP);
+ return 0;
+}
+
+static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ PM_WKDEP, (1 << clkdm2->dep_bit));
+}
+
+static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->wkdep_usecount, 0);
+ }
+
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ PM_WKDEP);
+ return 0;
+}
+
+static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
+}
+
+static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
+}
+
+static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit));
+}
+
+static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ /* PRM accesses are slow, so minimize them */
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->sleepdep_usecount, 0);
+ }
+ omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,
+ OMAP3430_CM_SLEEPDEP);
+ return 0;
+}
+
+static int omap2_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
+ clkdm->pwrdm.ptr->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
+static void _enable_hwsup(struct clockdomain *clkdm)
+{
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void _disable_hwsup(struct clockdomain *clkdm)
+{
+ if (cpu_is_omap24xx())
+ omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ else if (cpu_is_omap34xx())
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+
+static int omap2_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ _disable_hwsup(clkdm);
+ _clkdm_add_autodeps(clkdm);
+ _enable_hwsup(clkdm);
+ } else {
+ clkdm_wakeup(clkdm);
+ }
+
+ return 0;
+}
+
+static int omap2_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ if (!clkdm->clktrctrl_mask)
+ return 0;
+
+ hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (hwsup) {
+ /* Disable HW transitions when we are changing deps */
+ _disable_hwsup(clkdm);
+ _clkdm_del_autodeps(clkdm);
+ _enable_hwsup(clkdm);
+ } else {
+ clkdm_sleep(clkdm);
+ }
+
+ return 0;
+}
+
+static int omap3_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static int omap3_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+ return 0;
+}
+
+static void omap3_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+}
+
+static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,
+ clkdm->clktrctrl_mask);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
+struct clkdm_ops omap2_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_sleep = omap2_clkdm_sleep,
+ .clkdm_wakeup = omap2_clkdm_wakeup,
+ .clkdm_allow_idle = omap2_clkdm_allow_idle,
+ .clkdm_deny_idle = omap2_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
+};
+
+struct clkdm_ops omap3_clkdm_operations = {
+ .clkdm_add_wkdep = omap2_clkdm_add_wkdep,
+ .clkdm_del_wkdep = omap2_clkdm_del_wkdep,
+ .clkdm_read_wkdep = omap2_clkdm_read_wkdep,
+ .clkdm_clear_all_wkdeps = omap2_clkdm_clear_all_wkdeps,
+ .clkdm_add_sleepdep = omap3_clkdm_add_sleepdep,
+ .clkdm_del_sleepdep = omap3_clkdm_del_sleepdep,
+ .clkdm_read_sleepdep = omap3_clkdm_read_sleepdep,
+ .clkdm_clear_all_sleepdeps = omap3_clkdm_clear_all_sleepdeps,
+ .clkdm_sleep = omap3_clkdm_sleep,
+ .clkdm_wakeup = omap3_clkdm_wakeup,
+ .clkdm_allow_idle = omap3_clkdm_allow_idle,
+ .clkdm_deny_idle = omap3_clkdm_deny_idle,
+ .clkdm_clk_enable = omap2_clkdm_clk_enable,
+ .clkdm_clk_disable = omap2_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
new file mode 100644
index 00000000..a1a4ecd2
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -0,0 +1,137 @@
+/*
+ * OMAP4 clockdomain control
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/clockdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include "clockdomain.h"
+#include "cminst44xx.h"
+#include "cm44xx.h"
+
+static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->prcm_partition,
+ clkdm1->cm_inst, clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit),
+ clkdm1->prcm_partition,
+ clkdm1->cm_inst, clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1,
+ struct clockdomain *clkdm2)
+{
+ return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition,
+ clkdm1->cm_inst, clkdm1->clkdm_offs +
+ OMAP4_CM_STATICDEP,
+ (1 << clkdm2->dep_bit));
+}
+
+static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
+{
+ struct clkdm_dep *cd;
+ u32 mask = 0;
+
+ for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
+ if (!omap_chip_is(cd->omap_chip))
+ continue;
+ if (!cd->clkdm)
+ continue; /* only happens if data is erroneous */
+
+ mask |= 1 << cd->clkdm->dep_bit;
+ atomic_set(&cd->wkdep_usecount, 0);
+ }
+
+ omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs +
+ OMAP4_CM_STATICDEP);
+ return 0;
+}
+
+static int omap4_clkdm_sleep(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static int omap4_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+ return 0;
+}
+
+static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+}
+
+static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup)
+ clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
+{
+ bool hwsup = false;
+
+ hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition,
+ clkdm->cm_inst, clkdm->clkdm_offs);
+
+ if (!hwsup)
+ clkdm_sleep(clkdm);
+
+ return 0;
+}
+
+struct clkdm_ops omap4_clkdm_operations = {
+ .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
+ .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
+ .clkdm_read_wkdep = omap4_clkdm_read_wkup_sleep_dep,
+ .clkdm_clear_all_wkdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
+ .clkdm_add_sleepdep = omap4_clkdm_add_wkup_sleep_dep,
+ .clkdm_del_sleepdep = omap4_clkdm_del_wkup_sleep_dep,
+ .clkdm_read_sleepdep = omap4_clkdm_read_wkup_sleep_dep,
+ .clkdm_clear_all_sleepdeps = omap4_clkdm_clear_all_wkup_sleep_deps,
+ .clkdm_sleep = omap4_clkdm_sleep,
+ .clkdm_wakeup = omap4_clkdm_wakeup,
+ .clkdm_allow_idle = omap4_clkdm_allow_idle,
+ .clkdm_deny_idle = omap4_clkdm_deny_idle,
+ .clkdm_clk_enable = omap4_clkdm_clk_enable,
+ .clkdm_clk_disable = omap4_clkdm_clk_disable,
+};
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
new file mode 100644
index 00000000..13bde95b
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -0,0 +1,868 @@
+/*
+ * OMAP2/3 clockdomains
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This file contains clockdomains and clockdomain wakeup/sleep
+ * dependencies for the OMAP2/3 chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs or sleepdep_srcs array must have a
+ * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
+ * software-controllable dependencies. Non-software-controllable
+ * dependencies do exist, but they are not encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ *
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+/*
+ * To-Do List
+ * -> Port the Sleep/Wakeup dependencies for the domains
+ * from the Power domain framework
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps/sleepdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* OMAP2/3-common wakeup dependencies */
+
+/*
+ * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ * These can share data since they will never be present simultaneously
+ * on the same device.
+ */
+static struct clkdm_dep gfx_sgx_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/* 24XX-specific possible dependencies */
+
+#ifdef CONFIG_ARCH_OMAP2
+
+/* Wakeup dependency source arrays */
+
+/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
+static struct clkdm_dep dsp_24xx_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
+ * 2430 adds MDM
+ */
+static struct clkdm_dep mpu_24xx_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "dsp_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "mdm_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ },
+ { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
+ * 2430 adds MDM
+ */
+static struct clkdm_dep core_24xx_wkdeps[] = {
+ {
+ .clkdm_name = "dsp_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "gfx_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "mdm_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ },
+ { NULL },
+};
+
+#endif /* CONFIG_ARCH_OMAP2 */
+
+/* 2430-specific possible wakeup dependencies */
+
+#ifdef CONFIG_SOC_OMAP2430
+
+/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
+static struct clkdm_dep mdm_2430_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ { NULL },
+};
+
+#endif /* CONFIG_SOC_OMAP2430 */
+
+
+/* OMAP3-specific possible dependencies */
+
+#ifdef CONFIG_ARCH_OMAP3
+
+/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep per_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep usbhost_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
+static struct clkdm_dep mpu_3xxx_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "dss_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
+static struct clkdm_dep iva2_wkdeps[] = {
+ {
+ .clkdm_name = "core_l3_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "core_l4_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "dss_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
+static struct clkdm_dep cam_wkdeps[] = {
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
+static struct clkdm_dep dss_wkdeps[] = {
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct clkdm_dep neon_wkdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/* Sleep dependency source arrays for OMAP3-specific clkdms */
+
+/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
+static struct clkdm_dep dss_sleepdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
+static struct clkdm_dep per_sleepdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
+static struct clkdm_dep usbhost_sleepdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm_name = "iva2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_CAM: MPU */
+static struct clkdm_dep cam_sleepdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/*
+ * 3430ES1: CM_SLEEPDEP_GFX: MPU
+ * 3430ES2: CM_SLEEPDEP_SGX: MPU
+ * These can share data since they will never be present simultaneously
+ * on the same device.
+ */
+static struct clkdm_dep gfx_sgx_sleepdeps[] = {
+ {
+ .clkdm_name = "mpu_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+#endif /* CONFIG_ARCH_OMAP3 */
+
+
+/*
+ * OMAP2/3-common clockdomains
+ *
+ * Even though the 2420 has a single PRCM module from the
+ * interconnect's perspective, internally it does appear to have
+ * separate PRM and CM clockdomains. The usual test case is
+ * sys_clkout/sys_clkout2.
+ */
+
+/* This is an implicit clockdomain - it is never defined as such in TRM */
+static struct clockdomain wkup_clkdm = {
+ .name = "wkup_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .dep_bit = OMAP_EN_WKUP_SHIFT,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain prm_clkdm = {
+ .name = "prm_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cm_clkdm = {
+ .name = "cm_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+/*
+ * 2420-only clockdomains
+ */
+
+#if defined(CONFIG_SOC_OMAP2420)
+
+static struct clockdomain mpu_2420_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = mpu_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain iva1_2420_clkdm = {
+ .name = "iva1_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+ .wkdep_srcs = dsp_24xx_wkdeps,
+ .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain dsp_2420_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain gfx_2420_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain core_l3_2420_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain core_l4_2420_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain dss_2420_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+#endif /* CONFIG_SOC_OMAP2420 */
+
+
+/*
+ * 2430-only clockdomains
+ */
+
+#if defined(CONFIG_SOC_OMAP2430)
+
+static struct clockdomain mpu_2430_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = mpu_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* Another case of bit name collisions between several registers: EN_MDM */
+static struct clockdomain mdm_clkdm = {
+ .name = "mdm_clkdm",
+ .pwrdm = { .name = "mdm_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
+ .wkdep_srcs = mdm_2430_wkdeps,
+ .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static struct clockdomain dsp_2430_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+ .wkdep_srcs = dsp_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static struct clockdomain gfx_2430_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_2430_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP24XX_EN_CORE_SHIFT,
+ .wkdep_srcs = core_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_2430_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP24XX_EN_CORE_SHIFT,
+ .wkdep_srcs = core_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static struct clockdomain dss_2430_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+#endif /* CONFIG_SOC_OMAP2430 */
+
+
+/*
+ * OMAP3 clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP3)
+
+static struct clockdomain mpu_3xxx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+ .dep_bit = OMAP3430_EN_MPU_SHIFT,
+ .wkdep_srcs = mpu_3xxx_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain neon_clkdm = {
+ .name = "neon_clkdm",
+ .pwrdm = { .name = "neon_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = neon_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain iva2_clkdm = {
+ .name = "iva2_clkdm",
+ .pwrdm = { .name = "iva2_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+ .wkdep_srcs = iva2_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain gfx_3430es1_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
+};
+
+static struct clockdomain sgx_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+/*
+ * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
+ * then that information was removed from the 34xx ES2+ TRM. It is
+ * unclear whether the core is still there, but the clockdomain logic
+ * is there, and must be programmed to an appropriate state if the
+ * CORE clockdomain is to become inactive.
+ */
+static struct clockdomain d2d_clkdm = {
+ .name = "d2d_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_3xxx_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_3xxx_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* Another case of bit name collisions between several registers: EN_DSS */
+static struct clockdomain dss_3xxx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "dss_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+ .wkdep_srcs = dss_wkdeps,
+ .sleepdep_srcs = dss_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cam_clkdm = {
+ .name = "cam_clkdm",
+ .pwrdm = { .name = "cam_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = cam_wkdeps,
+ .sleepdep_srcs = cam_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain usbhost_clkdm = {
+ .name = "usbhost_clkdm",
+ .pwrdm = { .name = "usbhost_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = usbhost_wkdeps,
+ .sleepdep_srcs = usbhost_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+static struct clockdomain per_clkdm = {
+ .name = "per_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_EN_PER_SHIFT,
+ .wkdep_srcs = per_wkdeps,
+ .sleepdep_srcs = per_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
+ * switched of even if sdti is in use
+ */
+static struct clockdomain emu_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll1_clkdm = {
+ .name = "dpll1_clkdm",
+ .pwrdm = { .name = "dpll1_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll2_clkdm = {
+ .name = "dpll2_clkdm",
+ .pwrdm = { .name = "dpll2_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll3_clkdm = {
+ .name = "dpll3_clkdm",
+ .pwrdm = { .name = "dpll3_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll4_clkdm = {
+ .name = "dpll4_clkdm",
+ .pwrdm = { .name = "dpll4_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dpll5_clkdm = {
+ .name = "dpll5_clkdm",
+ .pwrdm = { .name = "dpll5_pwrdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+#endif /* CONFIG_ARCH_OMAP3 */
+
+/*
+ * Clockdomain hwsup dependencies (OMAP3 only)
+ */
+
+static struct clkdm_autodep clkdm_autodeps[] = {
+ {
+ .clkdm = { .name = "mpu_clkdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm = { .name = "iva2_clkdm" },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .clkdm = { .name = NULL },
+ }
+};
+
+static struct clockdomain *clockdomains_omap2[] __initdata = {
+ &wkup_clkdm,
+ &cm_clkdm,
+ &prm_clkdm,
+
+#ifdef CONFIG_SOC_OMAP2420
+ &mpu_2420_clkdm,
+ &iva1_2420_clkdm,
+ &dsp_2420_clkdm,
+ &gfx_2420_clkdm,
+ &core_l3_2420_clkdm,
+ &core_l4_2420_clkdm,
+ &dss_2420_clkdm,
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+ &mpu_2430_clkdm,
+ &mdm_clkdm,
+ &dsp_2430_clkdm,
+ &gfx_2430_clkdm,
+ &core_l3_2430_clkdm,
+ &core_l4_2430_clkdm,
+ &dss_2430_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+ &mpu_3xxx_clkdm,
+ &neon_clkdm,
+ &iva2_clkdm,
+ &gfx_3430es1_clkdm,
+ &sgx_clkdm,
+ &d2d_clkdm,
+ &core_l3_3xxx_clkdm,
+ &core_l4_3xxx_clkdm,
+ &dss_3xxx_clkdm,
+ &cam_clkdm,
+ &usbhost_clkdm,
+ &per_clkdm,
+ &emu_clkdm,
+ &dpll1_clkdm,
+ &dpll2_clkdm,
+ &dpll3_clkdm,
+ &dpll4_clkdm,
+ &dpll5_clkdm,
+#endif
+ NULL,
+};
+
+void __init omap2xxx_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
+}
+
+void __init omap3xxx_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations);
+}
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
new file mode 100644
index 00000000..a607ec19
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -0,0 +1,689 @@
+/*
+ * OMAP4 Clock domains framework
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+
+#include "cm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu44xx.h"
+
+/* Static Dependencies for OMAP4 Clock Domains */
+
+static struct clkdm_dep ducati_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_dss_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_gfx_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_init_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_secure_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "tesla_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep iss_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l3_d2d_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_init_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ducati_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_dss_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_init_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_secure_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_secure_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep mpuss_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ducati_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_dss_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_gfx_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_init_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_secure_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "tesla_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clkdm_dep tesla_wkup_sleep_deps[] = {
+ {
+ .clkdm_name = "abe_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "ivahd_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_1_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_2_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_emif_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l3_init_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_cfg_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_per_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ {
+ .clkdm_name = "l4_wkup_clkdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
+ },
+ { NULL },
+};
+
+static struct clockdomain l4_cefuse_44xx_clkdm = {
+ .name = "l4_cefuse_clkdm",
+ .pwrdm = { .name = "cefuse_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CEFUSE_INST,
+ .clkdm_offs = OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_cfg_44xx_clkdm = {
+ .name = "l4_cfg_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS,
+ .dep_bit = OMAP4430_L4CFG_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain tesla_44xx_clkdm = {
+ .name = "tesla_clkdm",
+ .pwrdm = { .name = "tesla_pwrdm" },
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_TESLA_INST,
+ .clkdm_offs = OMAP4430_CM1_TESLA_TESLA_CDOFFS,
+ .dep_bit = OMAP4430_TESLA_STATDEP_SHIFT,
+ .wkdep_srcs = tesla_wkup_sleep_deps,
+ .sleepdep_srcs = tesla_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_gfx_44xx_clkdm = {
+ .name = "l3_gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_GFX_INST,
+ .clkdm_offs = OMAP4430_CM2_GFX_GFX_CDOFFS,
+ .dep_bit = OMAP4430_GFX_STATDEP_SHIFT,
+ .wkdep_srcs = l3_gfx_wkup_sleep_deps,
+ .sleepdep_srcs = l3_gfx_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain ivahd_44xx_clkdm = {
+ .name = "ivahd_clkdm",
+ .pwrdm = { .name = "ivahd_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_IVAHD_INST,
+ .clkdm_offs = OMAP4430_CM2_IVAHD_IVAHD_CDOFFS,
+ .dep_bit = OMAP4430_IVAHD_STATDEP_SHIFT,
+ .wkdep_srcs = ivahd_wkup_sleep_deps,
+ .sleepdep_srcs = ivahd_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_secure_44xx_clkdm = {
+ .name = "l4_secure_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L4PER_INST,
+ .clkdm_offs = OMAP4430_CM2_L4PER_L4SEC_CDOFFS,
+ .dep_bit = OMAP4430_L4SEC_STATDEP_SHIFT,
+ .wkdep_srcs = l4_secure_wkup_sleep_deps,
+ .sleepdep_srcs = l4_secure_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_per_44xx_clkdm = {
+ .name = "l4_per_clkdm",
+ .pwrdm = { .name = "l4per_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L4PER_INST,
+ .clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS,
+ .dep_bit = OMAP4430_L4PER_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain abe_44xx_clkdm = {
+ .name = "abe_clkdm",
+ .pwrdm = { .name = "abe_pwrdm" },
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_ABE_INST,
+ .clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS,
+ .dep_bit = OMAP4430_ABE_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_instr_44xx_clkdm = {
+ .name = "l3_instr_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3INSTR_CDOFFS,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_init_44xx_clkdm = {
+ .name = "l3_init_clkdm",
+ .pwrdm = { .name = "l3init_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_L3INIT_INST,
+ .clkdm_offs = OMAP4430_CM2_L3INIT_L3INIT_CDOFFS,
+ .dep_bit = OMAP4430_L3INIT_STATDEP_SHIFT,
+ .wkdep_srcs = l3_init_wkup_sleep_deps,
+ .sleepdep_srcs = l3_init_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpuss_44xx_clkdm = {
+ .name = "mpuss_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .prcm_partition = OMAP4430_CM1_PARTITION,
+ .cm_inst = OMAP4430_CM1_MPU_INST,
+ .clkdm_offs = OMAP4430_CM1_MPU_MPU_CDOFFS,
+ .wkdep_srcs = mpuss_wkup_sleep_deps,
+ .sleepdep_srcs = mpuss_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpu0_44xx_clkdm = {
+ .name = "mpu0_clkdm",
+ .pwrdm = { .name = "cpu0_pwrdm" },
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP4430_PRCM_MPU_CPU0_INST,
+ .clkdm_offs = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain mpu1_44xx_clkdm = {
+ .name = "mpu1_clkdm",
+ .pwrdm = { .name = "cpu1_pwrdm" },
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .cm_inst = OMAP4430_PRCM_MPU_CPU1_INST,
+ .clkdm_offs = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_emif_44xx_clkdm = {
+ .name = "l3_emif_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS,
+ .dep_bit = OMAP4430_MEMIF_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_ao_44xx_clkdm = {
+ .name = "l4_ao_clkdm",
+ .pwrdm = { .name = "always_on_core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_ALWAYS_ON_INST,
+ .clkdm_offs = OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain ducati_44xx_clkdm = {
+ .name = "ducati_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_DUCATI_CDOFFS,
+ .dep_bit = OMAP4430_DUCATI_STATDEP_SHIFT,
+ .wkdep_srcs = ducati_wkup_sleep_deps,
+ .sleepdep_srcs = ducati_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_2_44xx_clkdm = {
+ .name = "l3_2_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS,
+ .dep_bit = OMAP4430_L3_2_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_1_44xx_clkdm = {
+ .name = "l3_1_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS,
+ .dep_bit = OMAP4430_L3_1_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_d2d_44xx_clkdm = {
+ .name = "l3_d2d_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_D2D_CDOFFS,
+ .wkdep_srcs = l3_d2d_wkup_sleep_deps,
+ .sleepdep_srcs = l3_d2d_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain iss_44xx_clkdm = {
+ .name = "iss_clkdm",
+ .pwrdm = { .name = "cam_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CAM_INST,
+ .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS,
+ .wkdep_srcs = iss_wkup_sleep_deps,
+ .sleepdep_srcs = iss_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_dss_44xx_clkdm = {
+ .name = "l3_dss_clkdm",
+ .pwrdm = { .name = "dss_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_DSS_INST,
+ .clkdm_offs = OMAP4430_CM2_DSS_DSS_CDOFFS,
+ .dep_bit = OMAP4430_DSS_STATDEP_SHIFT,
+ .wkdep_srcs = l3_dss_wkup_sleep_deps,
+ .sleepdep_srcs = l3_dss_wkup_sleep_deps,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l4_wkup_44xx_clkdm = {
+ .name = "l4_wkup_clkdm",
+ .pwrdm = { .name = "wkup_pwrdm" },
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .cm_inst = OMAP4430_PRM_WKUP_CM_INST,
+ .clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
+ .dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT,
+ .flags = CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain emu_sys_44xx_clkdm = {
+ .name = "emu_sys_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .cm_inst = OMAP4430_PRM_EMU_CM_INST,
+ .clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
+ .flags = CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain l3_dma_44xx_clkdm = {
+ .name = "l3_dma_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .prcm_partition = OMAP4430_CM2_PARTITION,
+ .cm_inst = OMAP4430_CM2_CORE_INST,
+ .clkdm_offs = OMAP4430_CM2_CORE_SDMA_CDOFFS,
+ .wkdep_srcs = l3_dma_wkup_sleep_deps,
+ .sleepdep_srcs = l3_dma_wkup_sleep_deps,
+ .flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct clockdomain *clockdomains_omap44xx[] __initdata = {
+ &l4_cefuse_44xx_clkdm,
+ &l4_cfg_44xx_clkdm,
+ &tesla_44xx_clkdm,
+ &l3_gfx_44xx_clkdm,
+ &ivahd_44xx_clkdm,
+ &l4_secure_44xx_clkdm,
+ &l4_per_44xx_clkdm,
+ &abe_44xx_clkdm,
+ &l3_instr_44xx_clkdm,
+ &l3_init_44xx_clkdm,
+ &mpuss_44xx_clkdm,
+ &mpu0_44xx_clkdm,
+ &mpu1_44xx_clkdm,
+ &l3_emif_44xx_clkdm,
+ &l4_ao_44xx_clkdm,
+ &ducati_44xx_clkdm,
+ &l3_2_44xx_clkdm,
+ &l3_1_44xx_clkdm,
+ &l3_d2d_44xx_clkdm,
+ &iss_44xx_clkdm,
+ &l3_dss_44xx_clkdm,
+ &l4_wkup_44xx_clkdm,
+ &emu_sys_44xx_clkdm,
+ &l3_dma_44xx_clkdm,
+ NULL,
+};
+
+void __init omap44xx_clockdomains_init(void)
+{
+ clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations);
+}
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
new file mode 100644
index 00000000..68629043
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -0,0 +1,445 @@
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_24XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_24XX_H
+
+/*
+ * OMAP24XX Clock Management register bits
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Bits shared between registers */
+
+/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */
+#define OMAP24XX_EN_CAM_SHIFT 31
+#define OMAP24XX_EN_CAM_MASK (1 << 31)
+#define OMAP24XX_EN_WDT4_SHIFT 29
+#define OMAP24XX_EN_WDT4_MASK (1 << 29)
+#define OMAP2420_EN_WDT3_SHIFT 28
+#define OMAP2420_EN_WDT3_MASK (1 << 28)
+#define OMAP24XX_EN_MSPRO_SHIFT 27
+#define OMAP24XX_EN_MSPRO_MASK (1 << 27)
+#define OMAP24XX_EN_FAC_SHIFT 25
+#define OMAP24XX_EN_FAC_MASK (1 << 25)
+#define OMAP2420_EN_EAC_SHIFT 24
+#define OMAP2420_EN_EAC_MASK (1 << 24)
+#define OMAP24XX_EN_HDQ_SHIFT 23
+#define OMAP24XX_EN_HDQ_MASK (1 << 23)
+#define OMAP2420_EN_I2C2_SHIFT 20
+#define OMAP2420_EN_I2C2_MASK (1 << 20)
+#define OMAP2420_EN_I2C1_SHIFT 19
+#define OMAP2420_EN_I2C1_MASK (1 << 19)
+
+/* CM_FCLKEN2_CORE and CM_ICLKEN2_CORE shared bits */
+#define OMAP2430_EN_MCBSP5_SHIFT 5
+#define OMAP2430_EN_MCBSP5_MASK (1 << 5)
+#define OMAP2430_EN_MCBSP4_SHIFT 4
+#define OMAP2430_EN_MCBSP4_MASK (1 << 4)
+#define OMAP2430_EN_MCBSP3_SHIFT 3
+#define OMAP2430_EN_MCBSP3_MASK (1 << 3)
+#define OMAP24XX_EN_SSI_SHIFT 1
+#define OMAP24XX_EN_SSI_MASK (1 << 1)
+
+/* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */
+#define OMAP24XX_EN_MPU_WDT_SHIFT 3
+#define OMAP24XX_EN_MPU_WDT_MASK (1 << 3)
+
+/* Bits specific to each register */
+
+/* CM_IDLEST_MPU */
+/* 2430 only */
+#define OMAP2430_ST_MPU_MASK (1 << 0)
+
+/* CM_CLKSEL_MPU */
+#define OMAP24XX_CLKSEL_MPU_SHIFT 0
+#define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0)
+
+/* CM_CLKSTCTRL_MPU */
+#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0
+#define OMAP24XX_AUTOSTATE_MPU_MASK (1 << 0)
+
+/* CM_FCLKEN1_CORE specific bits*/
+#define OMAP24XX_EN_TV_SHIFT 2
+#define OMAP24XX_EN_TV_MASK (1 << 2)
+#define OMAP24XX_EN_DSS2_SHIFT 1
+#define OMAP24XX_EN_DSS2_MASK (1 << 1)
+#define OMAP24XX_EN_DSS1_SHIFT 0
+#define OMAP24XX_EN_DSS1_MASK (1 << 0)
+
+/* CM_FCLKEN2_CORE specific bits */
+#define OMAP2430_EN_I2CHS2_SHIFT 20
+#define OMAP2430_EN_I2CHS2_MASK (1 << 20)
+#define OMAP2430_EN_I2CHS1_SHIFT 19
+#define OMAP2430_EN_I2CHS1_MASK (1 << 19)
+#define OMAP2430_EN_MMCHSDB2_SHIFT 17
+#define OMAP2430_EN_MMCHSDB2_MASK (1 << 17)
+#define OMAP2430_EN_MMCHSDB1_SHIFT 16
+#define OMAP2430_EN_MMCHSDB1_MASK (1 << 16)
+
+/* CM_ICLKEN1_CORE specific bits */
+#define OMAP24XX_EN_MAILBOXES_SHIFT 30
+#define OMAP24XX_EN_MAILBOXES_MASK (1 << 30)
+#define OMAP24XX_EN_DSS_SHIFT 0
+#define OMAP24XX_EN_DSS_MASK (1 << 0)
+
+/* CM_ICLKEN2_CORE specific bits */
+
+/* CM_ICLKEN3_CORE */
+/* 2430 only */
+#define OMAP2430_EN_SDRC_SHIFT 2
+#define OMAP2430_EN_SDRC_MASK (1 << 2)
+
+/* CM_ICLKEN4_CORE */
+#define OMAP24XX_EN_PKA_SHIFT 4
+#define OMAP24XX_EN_PKA_MASK (1 << 4)
+#define OMAP24XX_EN_AES_SHIFT 3
+#define OMAP24XX_EN_AES_MASK (1 << 3)
+#define OMAP24XX_EN_RNG_SHIFT 2
+#define OMAP24XX_EN_RNG_MASK (1 << 2)
+#define OMAP24XX_EN_SHA_SHIFT 1
+#define OMAP24XX_EN_SHA_MASK (1 << 1)
+#define OMAP24XX_EN_DES_SHIFT 0
+#define OMAP24XX_EN_DES_MASK (1 << 0)
+
+/* CM_IDLEST1_CORE specific bits */
+#define OMAP24XX_ST_MAILBOXES_SHIFT 30
+#define OMAP24XX_ST_MAILBOXES_MASK (1 << 30)
+#define OMAP24XX_ST_WDT4_SHIFT 29
+#define OMAP24XX_ST_WDT4_MASK (1 << 29)
+#define OMAP2420_ST_WDT3_SHIFT 28
+#define OMAP2420_ST_WDT3_MASK (1 << 28)
+#define OMAP24XX_ST_MSPRO_SHIFT 27
+#define OMAP24XX_ST_MSPRO_MASK (1 << 27)
+#define OMAP24XX_ST_FAC_SHIFT 25
+#define OMAP24XX_ST_FAC_MASK (1 << 25)
+#define OMAP2420_ST_EAC_SHIFT 24
+#define OMAP2420_ST_EAC_MASK (1 << 24)
+#define OMAP24XX_ST_HDQ_SHIFT 23
+#define OMAP24XX_ST_HDQ_MASK (1 << 23)
+#define OMAP2420_ST_I2C2_SHIFT 20
+#define OMAP2420_ST_I2C2_MASK (1 << 20)
+#define OMAP2430_ST_I2CHS1_SHIFT 19
+#define OMAP2430_ST_I2CHS1_MASK (1 << 19)
+#define OMAP2420_ST_I2C1_SHIFT 19
+#define OMAP2420_ST_I2C1_MASK (1 << 19)
+#define OMAP2430_ST_I2CHS2_SHIFT 20
+#define OMAP2430_ST_I2CHS2_MASK (1 << 20)
+#define OMAP24XX_ST_MCBSP2_SHIFT 16
+#define OMAP24XX_ST_MCBSP2_MASK (1 << 16)
+#define OMAP24XX_ST_MCBSP1_SHIFT 15
+#define OMAP24XX_ST_MCBSP1_MASK (1 << 15)
+#define OMAP24XX_ST_DSS_SHIFT 0
+#define OMAP24XX_ST_DSS_MASK (1 << 0)
+
+/* CM_IDLEST2_CORE */
+#define OMAP2430_ST_MCBSP5_SHIFT 5
+#define OMAP2430_ST_MCBSP5_MASK (1 << 5)
+#define OMAP2430_ST_MCBSP4_SHIFT 4
+#define OMAP2430_ST_MCBSP4_MASK (1 << 4)
+#define OMAP2430_ST_MCBSP3_SHIFT 3
+#define OMAP2430_ST_MCBSP3_MASK (1 << 3)
+#define OMAP24XX_ST_SSI_SHIFT 1
+#define OMAP24XX_ST_SSI_MASK (1 << 1)
+
+/* CM_IDLEST3_CORE */
+/* 2430 only */
+#define OMAP2430_ST_SDRC_MASK (1 << 2)
+
+/* CM_IDLEST4_CORE */
+#define OMAP24XX_ST_PKA_SHIFT 4
+#define OMAP24XX_ST_PKA_MASK (1 << 4)
+#define OMAP24XX_ST_AES_SHIFT 3
+#define OMAP24XX_ST_AES_MASK (1 << 3)
+#define OMAP24XX_ST_RNG_SHIFT 2
+#define OMAP24XX_ST_RNG_MASK (1 << 2)
+#define OMAP24XX_ST_SHA_SHIFT 1
+#define OMAP24XX_ST_SHA_MASK (1 << 1)
+#define OMAP24XX_ST_DES_SHIFT 0
+#define OMAP24XX_ST_DES_MASK (1 << 0)
+
+/* CM_AUTOIDLE1_CORE */
+#define OMAP24XX_AUTO_CAM_MASK (1 << 31)
+#define OMAP24XX_AUTO_MAILBOXES_MASK (1 << 30)
+#define OMAP24XX_AUTO_WDT4_MASK (1 << 29)
+#define OMAP2420_AUTO_WDT3_MASK (1 << 28)
+#define OMAP24XX_AUTO_MSPRO_MASK (1 << 27)
+#define OMAP2420_AUTO_MMC_MASK (1 << 26)
+#define OMAP24XX_AUTO_FAC_MASK (1 << 25)
+#define OMAP2420_AUTO_EAC_MASK (1 << 24)
+#define OMAP24XX_AUTO_HDQ_MASK (1 << 23)
+#define OMAP24XX_AUTO_UART2_MASK (1 << 22)
+#define OMAP24XX_AUTO_UART1_MASK (1 << 21)
+#define OMAP24XX_AUTO_I2C2_MASK (1 << 20)
+#define OMAP24XX_AUTO_I2C1_MASK (1 << 19)
+#define OMAP24XX_AUTO_MCSPI2_MASK (1 << 18)
+#define OMAP24XX_AUTO_MCSPI1_MASK (1 << 17)
+#define OMAP24XX_AUTO_MCBSP2_MASK (1 << 16)
+#define OMAP24XX_AUTO_MCBSP1_MASK (1 << 15)
+#define OMAP24XX_AUTO_GPT12_MASK (1 << 14)
+#define OMAP24XX_AUTO_GPT11_MASK (1 << 13)
+#define OMAP24XX_AUTO_GPT10_MASK (1 << 12)
+#define OMAP24XX_AUTO_GPT9_MASK (1 << 11)
+#define OMAP24XX_AUTO_GPT8_MASK (1 << 10)
+#define OMAP24XX_AUTO_GPT7_MASK (1 << 9)
+#define OMAP24XX_AUTO_GPT6_MASK (1 << 8)
+#define OMAP24XX_AUTO_GPT5_MASK (1 << 7)
+#define OMAP24XX_AUTO_GPT4_MASK (1 << 6)
+#define OMAP24XX_AUTO_GPT3_MASK (1 << 5)
+#define OMAP24XX_AUTO_GPT2_MASK (1 << 4)
+#define OMAP2420_AUTO_VLYNQ_MASK (1 << 3)
+#define OMAP24XX_AUTO_DSS_MASK (1 << 0)
+
+/* CM_AUTOIDLE2_CORE */
+#define OMAP2430_AUTO_MDM_INTC_MASK (1 << 11)
+#define OMAP2430_AUTO_GPIO5_MASK (1 << 10)
+#define OMAP2430_AUTO_MCSPI3_MASK (1 << 9)
+#define OMAP2430_AUTO_MMCHS2_MASK (1 << 8)
+#define OMAP2430_AUTO_MMCHS1_MASK (1 << 7)
+#define OMAP2430_AUTO_USBHS_MASK (1 << 6)
+#define OMAP2430_AUTO_MCBSP5_MASK (1 << 5)
+#define OMAP2430_AUTO_MCBSP4_MASK (1 << 4)
+#define OMAP2430_AUTO_MCBSP3_MASK (1 << 3)
+#define OMAP24XX_AUTO_UART3_MASK (1 << 2)
+#define OMAP24XX_AUTO_SSI_MASK (1 << 1)
+#define OMAP24XX_AUTO_USB_MASK (1 << 0)
+
+/* CM_AUTOIDLE3_CORE */
+#define OMAP24XX_AUTO_SDRC_SHIFT 2
+#define OMAP24XX_AUTO_SDRC_MASK (1 << 2)
+#define OMAP24XX_AUTO_GPMC_SHIFT 1
+#define OMAP24XX_AUTO_GPMC_MASK (1 << 1)
+#define OMAP24XX_AUTO_SDMA_SHIFT 0
+#define OMAP24XX_AUTO_SDMA_MASK (1 << 0)
+
+/* CM_AUTOIDLE4_CORE */
+#define OMAP24XX_AUTO_PKA_MASK (1 << 4)
+#define OMAP24XX_AUTO_AES_MASK (1 << 3)
+#define OMAP24XX_AUTO_RNG_MASK (1 << 2)
+#define OMAP24XX_AUTO_SHA_MASK (1 << 1)
+#define OMAP24XX_AUTO_DES_MASK (1 << 0)
+
+/* CM_CLKSEL1_CORE */
+#define OMAP24XX_CLKSEL_USB_SHIFT 25
+#define OMAP24XX_CLKSEL_USB_MASK (0x7 << 25)
+#define OMAP24XX_CLKSEL_SSI_SHIFT 20
+#define OMAP24XX_CLKSEL_SSI_MASK (0x1f << 20)
+#define OMAP2420_CLKSEL_VLYNQ_SHIFT 15
+#define OMAP2420_CLKSEL_VLYNQ_MASK (0x1f << 15)
+#define OMAP24XX_CLKSEL_DSS2_SHIFT 13
+#define OMAP24XX_CLKSEL_DSS2_MASK (0x1 << 13)
+#define OMAP24XX_CLKSEL_DSS1_SHIFT 8
+#define OMAP24XX_CLKSEL_DSS1_MASK (0x1f << 8)
+#define OMAP24XX_CLKSEL_L4_SHIFT 5
+#define OMAP24XX_CLKSEL_L4_MASK (0x3 << 5)
+#define OMAP24XX_CLKSEL_L3_SHIFT 0
+#define OMAP24XX_CLKSEL_L3_MASK (0x1f << 0)
+
+/* CM_CLKSEL2_CORE */
+#define OMAP24XX_CLKSEL_GPT12_SHIFT 22
+#define OMAP24XX_CLKSEL_GPT12_MASK (0x3 << 22)
+#define OMAP24XX_CLKSEL_GPT11_SHIFT 20
+#define OMAP24XX_CLKSEL_GPT11_MASK (0x3 << 20)
+#define OMAP24XX_CLKSEL_GPT10_SHIFT 18
+#define OMAP24XX_CLKSEL_GPT10_MASK (0x3 << 18)
+#define OMAP24XX_CLKSEL_GPT9_SHIFT 16
+#define OMAP24XX_CLKSEL_GPT9_MASK (0x3 << 16)
+#define OMAP24XX_CLKSEL_GPT8_SHIFT 14
+#define OMAP24XX_CLKSEL_GPT8_MASK (0x3 << 14)
+#define OMAP24XX_CLKSEL_GPT7_SHIFT 12
+#define OMAP24XX_CLKSEL_GPT7_MASK (0x3 << 12)
+#define OMAP24XX_CLKSEL_GPT6_SHIFT 10
+#define OMAP24XX_CLKSEL_GPT6_MASK (0x3 << 10)
+#define OMAP24XX_CLKSEL_GPT5_SHIFT 8
+#define OMAP24XX_CLKSEL_GPT5_MASK (0x3 << 8)
+#define OMAP24XX_CLKSEL_GPT4_SHIFT 6
+#define OMAP24XX_CLKSEL_GPT4_MASK (0x3 << 6)
+#define OMAP24XX_CLKSEL_GPT3_SHIFT 4
+#define OMAP24XX_CLKSEL_GPT3_MASK (0x3 << 4)
+#define OMAP24XX_CLKSEL_GPT2_SHIFT 2
+#define OMAP24XX_CLKSEL_GPT2_MASK (0x3 << 2)
+
+/* CM_CLKSTCTRL_CORE */
+#define OMAP24XX_AUTOSTATE_DSS_SHIFT 2
+#define OMAP24XX_AUTOSTATE_DSS_MASK (1 << 2)
+#define OMAP24XX_AUTOSTATE_L4_SHIFT 1
+#define OMAP24XX_AUTOSTATE_L4_MASK (1 << 1)
+#define OMAP24XX_AUTOSTATE_L3_SHIFT 0
+#define OMAP24XX_AUTOSTATE_L3_MASK (1 << 0)
+
+/* CM_FCLKEN_GFX */
+#define OMAP24XX_EN_3D_SHIFT 2
+#define OMAP24XX_EN_3D_MASK (1 << 2)
+#define OMAP24XX_EN_2D_SHIFT 1
+#define OMAP24XX_EN_2D_MASK (1 << 1)
+
+/* CM_ICLKEN_GFX specific bits */
+
+/* CM_IDLEST_GFX specific bits */
+
+/* CM_CLKSEL_GFX specific bits */
+
+/* CM_CLKSTCTRL_GFX */
+#define OMAP24XX_AUTOSTATE_GFX_SHIFT 0
+#define OMAP24XX_AUTOSTATE_GFX_MASK (1 << 0)
+
+/* CM_FCLKEN_WKUP specific bits */
+
+/* CM_ICLKEN_WKUP specific bits */
+#define OMAP2430_EN_ICR_SHIFT 6
+#define OMAP2430_EN_ICR_MASK (1 << 6)
+#define OMAP24XX_EN_OMAPCTRL_SHIFT 5
+#define OMAP24XX_EN_OMAPCTRL_MASK (1 << 5)
+#define OMAP24XX_EN_WDT1_SHIFT 4
+#define OMAP24XX_EN_WDT1_MASK (1 << 4)
+#define OMAP24XX_EN_32KSYNC_SHIFT 1
+#define OMAP24XX_EN_32KSYNC_MASK (1 << 1)
+
+/* CM_IDLEST_WKUP specific bits */
+#define OMAP2430_ST_ICR_SHIFT 6
+#define OMAP2430_ST_ICR_MASK (1 << 6)
+#define OMAP24XX_ST_OMAPCTRL_SHIFT 5
+#define OMAP24XX_ST_OMAPCTRL_MASK (1 << 5)
+#define OMAP24XX_ST_WDT1_SHIFT 4
+#define OMAP24XX_ST_WDT1_MASK (1 << 4)
+#define OMAP24XX_ST_MPU_WDT_SHIFT 3
+#define OMAP24XX_ST_MPU_WDT_MASK (1 << 3)
+#define OMAP24XX_ST_32KSYNC_SHIFT 1
+#define OMAP24XX_ST_32KSYNC_MASK (1 << 1)
+
+/* CM_AUTOIDLE_WKUP */
+#define OMAP24XX_AUTO_OMAPCTRL_MASK (1 << 5)
+#define OMAP24XX_AUTO_WDT1_MASK (1 << 4)
+#define OMAP24XX_AUTO_MPU_WDT_MASK (1 << 3)
+#define OMAP24XX_AUTO_GPIOS_MASK (1 << 2)
+#define OMAP24XX_AUTO_32KSYNC_MASK (1 << 1)
+#define OMAP24XX_AUTO_GPT1_MASK (1 << 0)
+
+/* CM_CLKSEL_WKUP */
+#define OMAP24XX_CLKSEL_GPT1_SHIFT 0
+#define OMAP24XX_CLKSEL_GPT1_MASK (0x3 << 0)
+
+/* CM_CLKEN_PLL */
+#define OMAP24XX_EN_54M_PLL_SHIFT 6
+#define OMAP24XX_EN_54M_PLL_MASK (0x3 << 6)
+#define OMAP24XX_EN_96M_PLL_SHIFT 2
+#define OMAP24XX_EN_96M_PLL_MASK (0x3 << 2)
+#define OMAP24XX_EN_DPLL_SHIFT 0
+#define OMAP24XX_EN_DPLL_MASK (0x3 << 0)
+
+/* CM_IDLEST_CKGEN */
+#define OMAP24XX_ST_54M_APLL_MASK (1 << 9)
+#define OMAP24XX_ST_96M_APLL_MASK (1 << 8)
+#define OMAP24XX_ST_54M_CLK_MASK (1 << 6)
+#define OMAP24XX_ST_12M_CLK_MASK (1 << 5)
+#define OMAP24XX_ST_48M_CLK_MASK (1 << 4)
+#define OMAP24XX_ST_96M_CLK_MASK (1 << 2)
+#define OMAP24XX_ST_CORE_CLK_SHIFT 0
+#define OMAP24XX_ST_CORE_CLK_MASK (0x3 << 0)
+
+/* CM_AUTOIDLE_PLL */
+#define OMAP24XX_AUTO_54M_SHIFT 6
+#define OMAP24XX_AUTO_54M_MASK (0x3 << 6)
+#define OMAP24XX_AUTO_96M_SHIFT 2
+#define OMAP24XX_AUTO_96M_MASK (0x3 << 2)
+#define OMAP24XX_AUTO_DPLL_SHIFT 0
+#define OMAP24XX_AUTO_DPLL_MASK (0x3 << 0)
+
+/* CM_CLKSEL1_PLL */
+#define OMAP2430_MAXDPLLFASTLOCK_SHIFT 28
+#define OMAP2430_MAXDPLLFASTLOCK_MASK (0x7 << 28)
+#define OMAP24XX_APLLS_CLKIN_SHIFT 23
+#define OMAP24XX_APLLS_CLKIN_MASK (0x7 << 23)
+#define OMAP24XX_DPLL_MULT_SHIFT 12
+#define OMAP24XX_DPLL_MULT_MASK (0x3ff << 12)
+#define OMAP24XX_DPLL_DIV_SHIFT 8
+#define OMAP24XX_DPLL_DIV_MASK (0xf << 8)
+#define OMAP24XX_54M_SOURCE_SHIFT 5
+#define OMAP24XX_54M_SOURCE_MASK (1 << 5)
+#define OMAP2430_96M_SOURCE_SHIFT 4
+#define OMAP2430_96M_SOURCE_MASK (1 << 4)
+#define OMAP24XX_48M_SOURCE_SHIFT 3
+#define OMAP24XX_48M_SOURCE_MASK (1 << 3)
+#define OMAP2430_ALTCLK_SOURCE_SHIFT 0
+#define OMAP2430_ALTCLK_SOURCE_MASK (0x7 << 0)
+
+/* CM_CLKSEL2_PLL */
+#define OMAP24XX_CORE_CLK_SRC_SHIFT 0
+#define OMAP24XX_CORE_CLK_SRC_MASK (0x3 << 0)
+
+/* CM_FCLKEN_DSP */
+#define OMAP2420_EN_IVA_COP_SHIFT 10
+#define OMAP2420_EN_IVA_COP_MASK (1 << 10)
+#define OMAP2420_EN_IVA_MPU_SHIFT 8
+#define OMAP2420_EN_IVA_MPU_MASK (1 << 8)
+#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT 0
+#define OMAP24XX_CM_FCLKEN_DSP_EN_DSP_MASK (1 << 0)
+
+/* CM_ICLKEN_DSP */
+#define OMAP2420_EN_DSP_IPI_SHIFT 1
+#define OMAP2420_EN_DSP_IPI_MASK (1 << 1)
+
+/* CM_IDLEST_DSP */
+#define OMAP2420_ST_IVA_MASK (1 << 8)
+#define OMAP2420_ST_IPI_MASK (1 << 1)
+#define OMAP24XX_ST_DSP_MASK (1 << 0)
+
+/* CM_AUTOIDLE_DSP */
+#define OMAP2420_AUTO_DSP_IPI_MASK (1 << 1)
+
+/* CM_CLKSEL_DSP */
+#define OMAP2420_SYNC_IVA_MASK (1 << 13)
+#define OMAP2420_CLKSEL_IVA_SHIFT 8
+#define OMAP2420_CLKSEL_IVA_MASK (0x1f << 8)
+#define OMAP24XX_SYNC_DSP_MASK (1 << 7)
+#define OMAP24XX_CLKSEL_DSP_IF_SHIFT 5
+#define OMAP24XX_CLKSEL_DSP_IF_MASK (0x3 << 5)
+#define OMAP24XX_CLKSEL_DSP_SHIFT 0
+#define OMAP24XX_CLKSEL_DSP_MASK (0x1f << 0)
+
+/* CM_CLKSTCTRL_DSP */
+#define OMAP2420_AUTOSTATE_IVA_SHIFT 8
+#define OMAP2420_AUTOSTATE_IVA_MASK (1 << 8)
+#define OMAP24XX_AUTOSTATE_DSP_SHIFT 0
+#define OMAP24XX_AUTOSTATE_DSP_MASK (1 << 0)
+
+/* CM_FCLKEN_MDM */
+/* 2430 only */
+#define OMAP2430_EN_OSC_SHIFT 1
+#define OMAP2430_EN_OSC_MASK (1 << 1)
+
+/* CM_ICLKEN_MDM */
+/* 2430 only */
+#define OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT 0
+#define OMAP2430_CM_ICLKEN_MDM_EN_MDM_MASK (1 << 0)
+
+/* CM_IDLEST_MDM specific bits */
+/* 2430 only */
+
+/* CM_AUTOIDLE_MDM */
+/* 2430 only */
+#define OMAP2430_AUTO_OSC_MASK (1 << 1)
+#define OMAP2430_AUTO_MDM_MASK (1 << 0)
+
+/* CM_CLKSEL_MDM */
+/* 2430 only */
+#define OMAP2430_SYNC_MDM_MASK (1 << 4)
+#define OMAP2430_CLKSEL_MDM_SHIFT 0
+#define OMAP2430_CLKSEL_MDM_MASK (0xf << 0)
+
+/* CM_CLKSTCTRL_MDM */
+/* 2430 only */
+#define OMAP2430_AUTOSTATE_MDM_SHIFT 0
+#define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0)
+
+/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
+
+
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
new file mode 100644
index 00000000..b9127590
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -0,0 +1,812 @@
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_34XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_34XX_H
+
+/*
+ * OMAP3430 Clock Management register bits
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Bits shared between registers */
+
+/* CM_FCLKEN1_CORE and CM_ICLKEN1_CORE shared bits */
+#define OMAP3430ES2_EN_MMC3_MASK (1 << 30)
+#define OMAP3430ES2_EN_MMC3_SHIFT 30
+#define OMAP3430_EN_MSPRO_MASK (1 << 23)
+#define OMAP3430_EN_MSPRO_SHIFT 23
+#define OMAP3430_EN_HDQ_MASK (1 << 22)
+#define OMAP3430_EN_HDQ_SHIFT 22
+#define OMAP3430ES1_EN_FSHOSTUSB_MASK (1 << 5)
+#define OMAP3430ES1_EN_FSHOSTUSB_SHIFT 5
+#define OMAP3430ES1_EN_D2D_MASK (1 << 3)
+#define OMAP3430ES1_EN_D2D_SHIFT 3
+#define OMAP3430_EN_SSI_MASK (1 << 0)
+#define OMAP3430_EN_SSI_SHIFT 0
+
+/* CM_FCLKEN3_CORE and CM_ICLKEN3_CORE shared bits */
+#define OMAP3430ES2_EN_USBTLL_SHIFT 2
+#define OMAP3430ES2_EN_USBTLL_MASK (1 << 2)
+
+/* CM_FCLKEN_WKUP and CM_ICLKEN_WKUP shared bits */
+#define OMAP3430_EN_WDT2_MASK (1 << 5)
+#define OMAP3430_EN_WDT2_SHIFT 5
+
+/* CM_ICLKEN_CAM, CM_FCLKEN_CAM shared bits */
+#define OMAP3430_EN_CAM_MASK (1 << 0)
+#define OMAP3430_EN_CAM_SHIFT 0
+
+/* CM_FCLKEN_PER, CM_ICLKEN_PER shared bits */
+#define OMAP3430_EN_WDT3_MASK (1 << 12)
+#define OMAP3430_EN_WDT3_SHIFT 12
+
+/* CM_CLKSEL2_EMU, CM_CLKSEL3_EMU shared bits */
+#define OMAP3430_OVERRIDE_ENABLE_MASK (1 << 19)
+
+
+/* Bits specific to each register */
+
+/* CM_FCLKEN_IVA2 */
+#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK (1 << 0)
+#define OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT 0
+
+/* CM_CLKEN_PLL_IVA2 */
+#define OMAP3430_IVA2_DPLL_RAMPTIME_SHIFT 8
+#define OMAP3430_IVA2_DPLL_RAMPTIME_MASK (0x3 << 8)
+#define OMAP3430_IVA2_DPLL_FREQSEL_SHIFT 4
+#define OMAP3430_IVA2_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_MASK (1 << 3)
+#define OMAP3430_EN_IVA2_DPLL_SHIFT 0
+#define OMAP3430_EN_IVA2_DPLL_MASK (0x7 << 0)
+
+/* CM_IDLEST_IVA2 */
+#define OMAP3430_ST_IVA2_MASK (1 << 0)
+
+/* CM_IDLEST_PLL_IVA2 */
+#define OMAP3430_ST_IVA2_CLK_SHIFT 0
+#define OMAP3430_ST_IVA2_CLK_MASK (1 << 0)
+
+/* CM_AUTOIDLE_PLL_IVA2 */
+#define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0
+#define OMAP3430_AUTO_IVA2_DPLL_MASK (0x7 << 0)
+
+/* CM_CLKSEL1_PLL_IVA2 */
+#define OMAP3430_IVA2_CLK_SRC_SHIFT 19
+#define OMAP3430_IVA2_CLK_SRC_MASK (0x3 << 19)
+#define OMAP3430_IVA2_DPLL_MULT_SHIFT 8
+#define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430_IVA2_DPLL_DIV_SHIFT 0
+#define OMAP3430_IVA2_DPLL_DIV_MASK (0x7f << 0)
+
+/* CM_CLKSEL2_PLL_IVA2 */
+#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP3430_IVA2_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
+
+/* CM_CLKSTCTRL_IVA2 */
+#define OMAP3430_CLKTRCTRL_IVA2_SHIFT 0
+#define OMAP3430_CLKTRCTRL_IVA2_MASK (0x3 << 0)
+
+/* CM_CLKSTST_IVA2 */
+#define OMAP3430_CLKACTIVITY_IVA2_SHIFT 0
+#define OMAP3430_CLKACTIVITY_IVA2_MASK (1 << 0)
+
+/* CM_REVISION specific bits */
+
+/* CM_SYSCONFIG specific bits */
+
+/* CM_CLKEN_PLL_MPU */
+#define OMAP3430_MPU_DPLL_RAMPTIME_SHIFT 8
+#define OMAP3430_MPU_DPLL_RAMPTIME_MASK (0x3 << 8)
+#define OMAP3430_MPU_DPLL_FREQSEL_SHIFT 4
+#define OMAP3430_MPU_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430_EN_MPU_DPLL_DRIFTGUARD_MASK (1 << 3)
+#define OMAP3430_EN_MPU_DPLL_SHIFT 0
+#define OMAP3430_EN_MPU_DPLL_MASK (0x7 << 0)
+
+/* CM_IDLEST_MPU */
+#define OMAP3430_ST_MPU_MASK (1 << 0)
+
+/* CM_IDLEST_PLL_MPU */
+#define OMAP3430_ST_MPU_CLK_SHIFT 0
+#define OMAP3430_ST_MPU_CLK_MASK (1 << 0)
+
+/* CM_AUTOIDLE_PLL_MPU */
+#define OMAP3430_AUTO_MPU_DPLL_SHIFT 0
+#define OMAP3430_AUTO_MPU_DPLL_MASK (0x7 << 0)
+
+/* CM_CLKSEL1_PLL_MPU */
+#define OMAP3430_MPU_CLK_SRC_SHIFT 19
+#define OMAP3430_MPU_CLK_SRC_MASK (0x3 << 19)
+#define OMAP3430_MPU_DPLL_MULT_SHIFT 8
+#define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430_MPU_DPLL_DIV_SHIFT 0
+#define OMAP3430_MPU_DPLL_DIV_MASK (0x7f << 0)
+
+/* CM_CLKSEL2_PLL_MPU */
+#define OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP3430_MPU_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
+
+/* CM_CLKSTCTRL_MPU */
+#define OMAP3430_CLKTRCTRL_MPU_SHIFT 0
+#define OMAP3430_CLKTRCTRL_MPU_MASK (0x3 << 0)
+
+/* CM_CLKSTST_MPU */
+#define OMAP3430_CLKACTIVITY_MPU_SHIFT 0
+#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0)
+
+/* CM_FCLKEN1_CORE specific bits */
+#define OMAP3430_EN_MODEM_MASK (1 << 31)
+#define OMAP3430_EN_MODEM_SHIFT 31
+
+/* CM_ICLKEN1_CORE specific bits */
+#define OMAP3430_EN_ICR_MASK (1 << 29)
+#define OMAP3430_EN_ICR_SHIFT 29
+#define OMAP3430_EN_AES2_MASK (1 << 28)
+#define OMAP3430_EN_AES2_SHIFT 28
+#define OMAP3430_EN_SHA12_MASK (1 << 27)
+#define OMAP3430_EN_SHA12_SHIFT 27
+#define OMAP3430_EN_DES2_MASK (1 << 26)
+#define OMAP3430_EN_DES2_SHIFT 26
+#define OMAP3430ES1_EN_FAC_MASK (1 << 8)
+#define OMAP3430ES1_EN_FAC_SHIFT 8
+#define OMAP3430_EN_MAILBOXES_MASK (1 << 7)
+#define OMAP3430_EN_MAILBOXES_SHIFT 7
+#define OMAP3430_EN_OMAPCTRL_MASK (1 << 6)
+#define OMAP3430_EN_OMAPCTRL_SHIFT 6
+#define OMAP3430_EN_SAD2D_MASK (1 << 3)
+#define OMAP3430_EN_SAD2D_SHIFT 3
+#define OMAP3430_EN_SDRC_MASK (1 << 1)
+#define OMAP3430_EN_SDRC_SHIFT 1
+
+/* AM35XX specific CM_ICLKEN1_CORE bits */
+#define AM35XX_EN_IPSS_MASK (1 << 4)
+#define AM35XX_EN_IPSS_SHIFT 4
+#define AM35XX_EN_UART4_MASK (1 << 23)
+#define AM35XX_EN_UART4_SHIFT 23
+
+/* CM_ICLKEN2_CORE */
+#define OMAP3430_EN_PKA_MASK (1 << 4)
+#define OMAP3430_EN_PKA_SHIFT 4
+#define OMAP3430_EN_AES1_MASK (1 << 3)
+#define OMAP3430_EN_AES1_SHIFT 3
+#define OMAP3430_EN_RNG_MASK (1 << 2)
+#define OMAP3430_EN_RNG_SHIFT 2
+#define OMAP3430_EN_SHA11_MASK (1 << 1)
+#define OMAP3430_EN_SHA11_SHIFT 1
+#define OMAP3430_EN_DES1_MASK (1 << 0)
+#define OMAP3430_EN_DES1_SHIFT 0
+
+/* CM_ICLKEN3_CORE */
+#define OMAP3430_EN_MAD2D_SHIFT 3
+#define OMAP3430_EN_MAD2D_MASK (1 << 3)
+
+/* CM_FCLKEN3_CORE specific bits */
+#define OMAP3430ES2_EN_TS_SHIFT 1
+#define OMAP3430ES2_EN_TS_MASK (1 << 1)
+#define OMAP3430ES2_EN_CPEFUSE_SHIFT 0
+#define OMAP3430ES2_EN_CPEFUSE_MASK (1 << 0)
+
+/* CM_IDLEST1_CORE specific bits */
+#define OMAP3430ES2_ST_MMC3_SHIFT 30
+#define OMAP3430ES2_ST_MMC3_MASK (1 << 30)
+#define OMAP3430_ST_ICR_SHIFT 29
+#define OMAP3430_ST_ICR_MASK (1 << 29)
+#define OMAP3430_ST_AES2_SHIFT 28
+#define OMAP3430_ST_AES2_MASK (1 << 28)
+#define OMAP3430_ST_SHA12_SHIFT 27
+#define OMAP3430_ST_SHA12_MASK (1 << 27)
+#define OMAP3430_ST_DES2_SHIFT 26
+#define OMAP3430_ST_DES2_MASK (1 << 26)
+#define OMAP3430_ST_MSPRO_SHIFT 23
+#define OMAP3430_ST_MSPRO_MASK (1 << 23)
+#define OMAP3430_ST_HDQ_SHIFT 22
+#define OMAP3430_ST_HDQ_MASK (1 << 22)
+#define OMAP3430ES1_ST_FAC_SHIFT 8
+#define OMAP3430ES1_ST_FAC_MASK (1 << 8)
+#define OMAP3430ES2_ST_SSI_IDLE_SHIFT 8
+#define OMAP3430ES2_ST_SSI_IDLE_MASK (1 << 8)
+#define OMAP3430_ST_MAILBOXES_SHIFT 7
+#define OMAP3430_ST_MAILBOXES_MASK (1 << 7)
+#define OMAP3430_ST_OMAPCTRL_SHIFT 6
+#define OMAP3430_ST_OMAPCTRL_MASK (1 << 6)
+#define OMAP3430_ST_SDMA_SHIFT 2
+#define OMAP3430_ST_SDMA_MASK (1 << 2)
+#define OMAP3430_ST_SDRC_SHIFT 1
+#define OMAP3430_ST_SDRC_MASK (1 << 1)
+#define OMAP3430_ST_SSI_STDBY_SHIFT 0
+#define OMAP3430_ST_SSI_STDBY_MASK (1 << 0)
+
+/* AM35xx specific CM_IDLEST1_CORE bits */
+#define AM35XX_ST_IPSS_SHIFT 5
+#define AM35XX_ST_IPSS_MASK (1 << 5)
+
+/* CM_IDLEST2_CORE */
+#define OMAP3430_ST_PKA_SHIFT 4
+#define OMAP3430_ST_PKA_MASK (1 << 4)
+#define OMAP3430_ST_AES1_SHIFT 3
+#define OMAP3430_ST_AES1_MASK (1 << 3)
+#define OMAP3430_ST_RNG_SHIFT 2
+#define OMAP3430_ST_RNG_MASK (1 << 2)
+#define OMAP3430_ST_SHA11_SHIFT 1
+#define OMAP3430_ST_SHA11_MASK (1 << 1)
+#define OMAP3430_ST_DES1_SHIFT 0
+#define OMAP3430_ST_DES1_MASK (1 << 0)
+
+/* CM_IDLEST3_CORE */
+#define OMAP3430ES2_ST_USBTLL_SHIFT 2
+#define OMAP3430ES2_ST_USBTLL_MASK (1 << 2)
+#define OMAP3430ES2_ST_CPEFUSE_SHIFT 0
+#define OMAP3430ES2_ST_CPEFUSE_MASK (1 << 0)
+
+/* CM_AUTOIDLE1_CORE */
+#define OMAP3430_AUTO_MODEM_MASK (1 << 31)
+#define OMAP3430_AUTO_MODEM_SHIFT 31
+#define OMAP3430ES2_AUTO_MMC3_MASK (1 << 30)
+#define OMAP3430ES2_AUTO_MMC3_SHIFT 30
+#define OMAP3430ES2_AUTO_ICR_MASK (1 << 29)
+#define OMAP3430ES2_AUTO_ICR_SHIFT 29
+#define OMAP3430_AUTO_AES2_MASK (1 << 28)
+#define OMAP3430_AUTO_AES2_SHIFT 28
+#define OMAP3430_AUTO_SHA12_MASK (1 << 27)
+#define OMAP3430_AUTO_SHA12_SHIFT 27
+#define OMAP3430_AUTO_DES2_MASK (1 << 26)
+#define OMAP3430_AUTO_DES2_SHIFT 26
+#define OMAP3430_AUTO_MMC2_MASK (1 << 25)
+#define OMAP3430_AUTO_MMC2_SHIFT 25
+#define OMAP3430_AUTO_MMC1_MASK (1 << 24)
+#define OMAP3430_AUTO_MMC1_SHIFT 24
+#define OMAP3430_AUTO_MSPRO_MASK (1 << 23)
+#define OMAP3430_AUTO_MSPRO_SHIFT 23
+#define OMAP3430_AUTO_HDQ_MASK (1 << 22)
+#define OMAP3430_AUTO_HDQ_SHIFT 22
+#define OMAP3430_AUTO_MCSPI4_MASK (1 << 21)
+#define OMAP3430_AUTO_MCSPI4_SHIFT 21
+#define OMAP3430_AUTO_MCSPI3_MASK (1 << 20)
+#define OMAP3430_AUTO_MCSPI3_SHIFT 20
+#define OMAP3430_AUTO_MCSPI2_MASK (1 << 19)
+#define OMAP3430_AUTO_MCSPI2_SHIFT 19
+#define OMAP3430_AUTO_MCSPI1_MASK (1 << 18)
+#define OMAP3430_AUTO_MCSPI1_SHIFT 18
+#define OMAP3430_AUTO_I2C3_MASK (1 << 17)
+#define OMAP3430_AUTO_I2C3_SHIFT 17
+#define OMAP3430_AUTO_I2C2_MASK (1 << 16)
+#define OMAP3430_AUTO_I2C2_SHIFT 16
+#define OMAP3430_AUTO_I2C1_MASK (1 << 15)
+#define OMAP3430_AUTO_I2C1_SHIFT 15
+#define OMAP3430_AUTO_UART2_MASK (1 << 14)
+#define OMAP3430_AUTO_UART2_SHIFT 14
+#define OMAP3430_AUTO_UART1_MASK (1 << 13)
+#define OMAP3430_AUTO_UART1_SHIFT 13
+#define OMAP3430_AUTO_GPT11_MASK (1 << 12)
+#define OMAP3430_AUTO_GPT11_SHIFT 12
+#define OMAP3430_AUTO_GPT10_MASK (1 << 11)
+#define OMAP3430_AUTO_GPT10_SHIFT 11
+#define OMAP3430_AUTO_MCBSP5_MASK (1 << 10)
+#define OMAP3430_AUTO_MCBSP5_SHIFT 10
+#define OMAP3430_AUTO_MCBSP1_MASK (1 << 9)
+#define OMAP3430_AUTO_MCBSP1_SHIFT 9
+#define OMAP3430ES1_AUTO_FAC_MASK (1 << 8)
+#define OMAP3430ES1_AUTO_FAC_SHIFT 8
+#define OMAP3430_AUTO_MAILBOXES_MASK (1 << 7)
+#define OMAP3430_AUTO_MAILBOXES_SHIFT 7
+#define OMAP3430_AUTO_OMAPCTRL_MASK (1 << 6)
+#define OMAP3430_AUTO_OMAPCTRL_SHIFT 6
+#define OMAP3430ES1_AUTO_FSHOSTUSB_MASK (1 << 5)
+#define OMAP3430ES1_AUTO_FSHOSTUSB_SHIFT 5
+#define OMAP3430_AUTO_HSOTGUSB_MASK (1 << 4)
+#define OMAP3430_AUTO_HSOTGUSB_SHIFT 4
+#define OMAP3430ES1_AUTO_D2D_MASK (1 << 3)
+#define OMAP3430ES1_AUTO_D2D_SHIFT 3
+#define OMAP3430_AUTO_SAD2D_MASK (1 << 3)
+#define OMAP3430_AUTO_SAD2D_SHIFT 3
+#define OMAP3430_AUTO_SSI_MASK (1 << 0)
+#define OMAP3430_AUTO_SSI_SHIFT 0
+
+/* CM_AUTOIDLE2_CORE */
+#define OMAP3430_AUTO_PKA_MASK (1 << 4)
+#define OMAP3430_AUTO_PKA_SHIFT 4
+#define OMAP3430_AUTO_AES1_MASK (1 << 3)
+#define OMAP3430_AUTO_AES1_SHIFT 3
+#define OMAP3430_AUTO_RNG_MASK (1 << 2)
+#define OMAP3430_AUTO_RNG_SHIFT 2
+#define OMAP3430_AUTO_SHA11_MASK (1 << 1)
+#define OMAP3430_AUTO_SHA11_SHIFT 1
+#define OMAP3430_AUTO_DES1_MASK (1 << 0)
+#define OMAP3430_AUTO_DES1_SHIFT 0
+
+/* CM_AUTOIDLE3_CORE */
+#define OMAP3430ES2_AUTO_USBHOST (1 << 0)
+#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0
+#define OMAP3430ES2_AUTO_USBTLL (1 << 2)
+#define OMAP3430ES2_AUTO_USBTLL_SHIFT 2
+#define OMAP3430ES2_AUTO_USBTLL_MASK (1 << 2)
+#define OMAP3430_AUTO_MAD2D_SHIFT 3
+#define OMAP3430_AUTO_MAD2D_MASK (1 << 3)
+
+/* CM_CLKSEL_CORE */
+#define OMAP3430_CLKSEL_SSI_SHIFT 8
+#define OMAP3430_CLKSEL_SSI_MASK (0xf << 8)
+#define OMAP3430_CLKSEL_GPT11_MASK (1 << 7)
+#define OMAP3430_CLKSEL_GPT11_SHIFT 7
+#define OMAP3430_CLKSEL_GPT10_MASK (1 << 6)
+#define OMAP3430_CLKSEL_GPT10_SHIFT 6
+#define OMAP3430ES1_CLKSEL_FSHOSTUSB_SHIFT 4
+#define OMAP3430ES1_CLKSEL_FSHOSTUSB_MASK (0x3 << 4)
+#define OMAP3430_CLKSEL_L4_SHIFT 2
+#define OMAP3430_CLKSEL_L4_MASK (0x3 << 2)
+#define OMAP3430_CLKSEL_L3_SHIFT 0
+#define OMAP3430_CLKSEL_L3_MASK (0x3 << 0)
+#define OMAP3630_CLKSEL_96M_SHIFT 12
+#define OMAP3630_CLKSEL_96M_MASK (0x3 << 12)
+
+/* CM_CLKSTCTRL_CORE */
+#define OMAP3430ES1_CLKTRCTRL_D2D_SHIFT 4
+#define OMAP3430ES1_CLKTRCTRL_D2D_MASK (0x3 << 4)
+#define OMAP3430_CLKTRCTRL_L4_SHIFT 2
+#define OMAP3430_CLKTRCTRL_L4_MASK (0x3 << 2)
+#define OMAP3430_CLKTRCTRL_L3_SHIFT 0
+#define OMAP3430_CLKTRCTRL_L3_MASK (0x3 << 0)
+
+/* CM_CLKSTST_CORE */
+#define OMAP3430ES1_CLKACTIVITY_D2D_SHIFT 2
+#define OMAP3430ES1_CLKACTIVITY_D2D_MASK (1 << 2)
+#define OMAP3430_CLKACTIVITY_L4_SHIFT 1
+#define OMAP3430_CLKACTIVITY_L4_MASK (1 << 1)
+#define OMAP3430_CLKACTIVITY_L3_SHIFT 0
+#define OMAP3430_CLKACTIVITY_L3_MASK (1 << 0)
+
+/* CM_FCLKEN_GFX */
+#define OMAP3430ES1_EN_3D_MASK (1 << 2)
+#define OMAP3430ES1_EN_3D_SHIFT 2
+#define OMAP3430ES1_EN_2D_MASK (1 << 1)
+#define OMAP3430ES1_EN_2D_SHIFT 1
+
+/* CM_ICLKEN_GFX specific bits */
+
+/* CM_IDLEST_GFX specific bits */
+
+/* CM_CLKSEL_GFX specific bits */
+
+/* CM_SLEEPDEP_GFX specific bits */
+
+/* CM_CLKSTCTRL_GFX */
+#define OMAP3430ES1_CLKTRCTRL_GFX_SHIFT 0
+#define OMAP3430ES1_CLKTRCTRL_GFX_MASK (0x3 << 0)
+
+/* CM_CLKSTST_GFX */
+#define OMAP3430ES1_CLKACTIVITY_GFX_SHIFT 0
+#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0)
+
+/* CM_FCLKEN_SGX */
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_SHIFT 1
+#define OMAP3430ES2_CM_FCLKEN_SGX_EN_SGX_MASK (1 << 1)
+
+/* CM_IDLEST_SGX */
+#define OMAP3430ES2_ST_SGX_SHIFT 1
+#define OMAP3430ES2_ST_SGX_MASK (1 << 1)
+
+/* CM_ICLKEN_SGX */
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_SHIFT 0
+#define OMAP3430ES2_CM_ICLKEN_SGX_EN_SGX_MASK (1 << 0)
+
+/* CM_CLKSEL_SGX */
+#define OMAP3430ES2_CLKSEL_SGX_SHIFT 0
+#define OMAP3430ES2_CLKSEL_SGX_MASK (0x7 << 0)
+
+/* CM_CLKSTCTRL_SGX */
+#define OMAP3430ES2_CLKTRCTRL_SGX_SHIFT 0
+#define OMAP3430ES2_CLKTRCTRL_SGX_MASK (0x3 << 0)
+
+/* CM_CLKSTST_SGX */
+#define OMAP3430ES2_CLKACTIVITY_SGX_SHIFT 0
+#define OMAP3430ES2_CLKACTIVITY_SGX_MASK (1 << 0)
+
+/* CM_FCLKEN_WKUP specific bits */
+#define OMAP3430ES2_EN_USIMOCP_SHIFT 9
+#define OMAP3430ES2_EN_USIMOCP_MASK (1 << 9)
+
+/* CM_ICLKEN_WKUP specific bits */
+#define OMAP3430_EN_WDT1_MASK (1 << 4)
+#define OMAP3430_EN_WDT1_SHIFT 4
+#define OMAP3430_EN_32KSYNC_MASK (1 << 2)
+#define OMAP3430_EN_32KSYNC_SHIFT 2
+
+/* CM_IDLEST_WKUP specific bits */
+#define OMAP3430ES2_ST_USIMOCP_SHIFT 9
+#define OMAP3430ES2_ST_USIMOCP_MASK (1 << 9)
+#define OMAP3430_ST_WDT2_SHIFT 5
+#define OMAP3430_ST_WDT2_MASK (1 << 5)
+#define OMAP3430_ST_WDT1_SHIFT 4
+#define OMAP3430_ST_WDT1_MASK (1 << 4)
+#define OMAP3430_ST_32KSYNC_SHIFT 2
+#define OMAP3430_ST_32KSYNC_MASK (1 << 2)
+
+/* CM_AUTOIDLE_WKUP */
+#define OMAP3430ES2_AUTO_USIMOCP_MASK (1 << 9)
+#define OMAP3430ES2_AUTO_USIMOCP_SHIFT 9
+#define OMAP3430_AUTO_WDT2_MASK (1 << 5)
+#define OMAP3430_AUTO_WDT2_SHIFT 5
+#define OMAP3430_AUTO_WDT1_MASK (1 << 4)
+#define OMAP3430_AUTO_WDT1_SHIFT 4
+#define OMAP3430_AUTO_GPIO1_MASK (1 << 3)
+#define OMAP3430_AUTO_GPIO1_SHIFT 3
+#define OMAP3430_AUTO_32KSYNC_MASK (1 << 2)
+#define OMAP3430_AUTO_32KSYNC_SHIFT 2
+#define OMAP3430_AUTO_GPT12_MASK (1 << 1)
+#define OMAP3430_AUTO_GPT12_SHIFT 1
+#define OMAP3430_AUTO_GPT1_MASK (1 << 0)
+#define OMAP3430_AUTO_GPT1_SHIFT 0
+
+/* CM_CLKSEL_WKUP */
+#define OMAP3430ES2_CLKSEL_USIMOCP_MASK (0xf << 3)
+#define OMAP3430_CLKSEL_RM_SHIFT 1
+#define OMAP3430_CLKSEL_RM_MASK (0x3 << 1)
+#define OMAP3430_CLKSEL_GPT1_SHIFT 0
+#define OMAP3430_CLKSEL_GPT1_MASK (1 << 0)
+
+/* CM_CLKEN_PLL */
+#define OMAP3430_PWRDN_EMU_PERIPH_SHIFT 31
+#define OMAP3430_PWRDN_CAM_SHIFT 30
+#define OMAP3430_PWRDN_DSS1_SHIFT 29
+#define OMAP3430_PWRDN_TV_SHIFT 28
+#define OMAP3430_PWRDN_96M_SHIFT 27
+#define OMAP3430_PERIPH_DPLL_RAMPTIME_SHIFT 24
+#define OMAP3430_PERIPH_DPLL_RAMPTIME_MASK (0x3 << 24)
+#define OMAP3430_PERIPH_DPLL_FREQSEL_SHIFT 20
+#define OMAP3430_PERIPH_DPLL_FREQSEL_MASK (0xf << 20)
+#define OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT 19
+#define OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_MASK (1 << 19)
+#define OMAP3430_EN_PERIPH_DPLL_SHIFT 16
+#define OMAP3430_EN_PERIPH_DPLL_MASK (0x7 << 16)
+#define OMAP3430_PWRDN_EMU_CORE_SHIFT 12
+#define OMAP3430_CORE_DPLL_RAMPTIME_SHIFT 8
+#define OMAP3430_CORE_DPLL_RAMPTIME_MASK (0x3 << 8)
+#define OMAP3430_CORE_DPLL_FREQSEL_SHIFT 4
+#define OMAP3430_CORE_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430_EN_CORE_DPLL_DRIFTGUARD_MASK (1 << 3)
+#define OMAP3430_EN_CORE_DPLL_SHIFT 0
+#define OMAP3430_EN_CORE_DPLL_MASK (0x7 << 0)
+
+/* CM_CLKEN2_PLL */
+#define OMAP3430ES2_EN_PERIPH2_DPLL_LPMODE_SHIFT 10
+#define OMAP3430ES2_PERIPH2_DPLL_RAMPTIME_MASK (0x3 << 8)
+#define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_SHIFT 4
+#define OMAP3430ES2_PERIPH2_DPLL_FREQSEL_MASK (0xf << 4)
+#define OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT 3
+#define OMAP3430ES2_EN_PERIPH2_DPLL_SHIFT 0
+#define OMAP3430ES2_EN_PERIPH2_DPLL_MASK (0x7 << 0)
+
+/* CM_IDLEST_CKGEN */
+#define OMAP3430_ST_54M_CLK_MASK (1 << 5)
+#define OMAP3430_ST_12M_CLK_MASK (1 << 4)
+#define OMAP3430_ST_48M_CLK_MASK (1 << 3)
+#define OMAP3430_ST_96M_CLK_MASK (1 << 2)
+#define OMAP3430_ST_PERIPH_CLK_SHIFT 1
+#define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1)
+#define OMAP3430_ST_CORE_CLK_SHIFT 0
+#define OMAP3430_ST_CORE_CLK_MASK (1 << 0)
+
+/* CM_IDLEST2_CKGEN */
+#define OMAP3430ES2_ST_USIM_CLK_SHIFT 2
+#define OMAP3430ES2_ST_USIM_CLK_MASK (1 << 2)
+#define OMAP3430ES2_ST_120M_CLK_SHIFT 1
+#define OMAP3430ES2_ST_120M_CLK_MASK (1 << 1)
+#define OMAP3430ES2_ST_PERIPH2_CLK_SHIFT 0
+#define OMAP3430ES2_ST_PERIPH2_CLK_MASK (1 << 0)
+
+/* CM_AUTOIDLE_PLL */
+#define OMAP3430_AUTO_PERIPH_DPLL_SHIFT 3
+#define OMAP3430_AUTO_PERIPH_DPLL_MASK (0x7 << 3)
+#define OMAP3430_AUTO_CORE_DPLL_SHIFT 0
+#define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0)
+
+/* CM_AUTOIDLE2_PLL */
+#define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0
+#define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0)
+
+/* CM_CLKSEL1_PLL */
+/* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */
+#define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27
+#define OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK (0x1f << 27)
+#define OMAP3430_CORE_DPLL_MULT_SHIFT 16
+#define OMAP3430_CORE_DPLL_MULT_MASK (0x7ff << 16)
+#define OMAP3430_CORE_DPLL_DIV_SHIFT 8
+#define OMAP3430_CORE_DPLL_DIV_MASK (0x7f << 8)
+#define OMAP3430_SOURCE_96M_SHIFT 6
+#define OMAP3430_SOURCE_96M_MASK (1 << 6)
+#define OMAP3430_SOURCE_54M_SHIFT 5
+#define OMAP3430_SOURCE_54M_MASK (1 << 5)
+#define OMAP3430_SOURCE_48M_SHIFT 3
+#define OMAP3430_SOURCE_48M_MASK (1 << 3)
+
+/* CM_CLKSEL2_PLL */
+#define OMAP3430_PERIPH_DPLL_MULT_SHIFT 8
+#define OMAP3430_PERIPH_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3630_PERIPH_DPLL_MULT_MASK (0xfff << 8)
+#define OMAP3430_PERIPH_DPLL_DIV_SHIFT 0
+#define OMAP3430_PERIPH_DPLL_DIV_MASK (0x7f << 0)
+#define OMAP3630_PERIPH_DPLL_DCO_SEL_SHIFT 21
+#define OMAP3630_PERIPH_DPLL_DCO_SEL_MASK (0x7 << 21)
+#define OMAP3630_PERIPH_DPLL_SD_DIV_SHIFT 24
+#define OMAP3630_PERIPH_DPLL_SD_DIV_MASK (0xff << 24)
+
+/* CM_CLKSEL3_PLL */
+#define OMAP3430_DIV_96M_SHIFT 0
+#define OMAP3430_DIV_96M_MASK (0x1f << 0)
+#define OMAP3630_DIV_96M_MASK (0x3f << 0)
+
+/* CM_CLKSEL4_PLL */
+#define OMAP3430ES2_PERIPH2_DPLL_MULT_SHIFT 8
+#define OMAP3430ES2_PERIPH2_DPLL_MULT_MASK (0x7ff << 8)
+#define OMAP3430ES2_PERIPH2_DPLL_DIV_SHIFT 0
+#define OMAP3430ES2_PERIPH2_DPLL_DIV_MASK (0x7f << 0)
+
+/* CM_CLKSEL5_PLL */
+#define OMAP3430ES2_DIV_120M_SHIFT 0
+#define OMAP3430ES2_DIV_120M_MASK (0x1f << 0)
+
+/* CM_CLKOUT_CTRL */
+#define OMAP3430_CLKOUT2_EN_SHIFT 7
+#define OMAP3430_CLKOUT2_EN_MASK (1 << 7)
+#define OMAP3430_CLKOUT2_DIV_SHIFT 3
+#define OMAP3430_CLKOUT2_DIV_MASK (0x7 << 3)
+#define OMAP3430_CLKOUT2SOURCE_SHIFT 0
+#define OMAP3430_CLKOUT2SOURCE_MASK (0x3 << 0)
+
+/* CM_FCLKEN_DSS */
+#define OMAP3430_EN_TV_MASK (1 << 2)
+#define OMAP3430_EN_TV_SHIFT 2
+#define OMAP3430_EN_DSS2_MASK (1 << 1)
+#define OMAP3430_EN_DSS2_SHIFT 1
+#define OMAP3430_EN_DSS1_MASK (1 << 0)
+#define OMAP3430_EN_DSS1_SHIFT 0
+
+/* CM_ICLKEN_DSS */
+#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_MASK (1 << 0)
+#define OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT 0
+
+/* CM_IDLEST_DSS */
+#define OMAP3430ES2_ST_DSS_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_DSS_IDLE_MASK (1 << 1)
+#define OMAP3430ES2_ST_DSS_STDBY_SHIFT 0
+#define OMAP3430ES2_ST_DSS_STDBY_MASK (1 << 0)
+#define OMAP3430ES1_ST_DSS_SHIFT 0
+#define OMAP3430ES1_ST_DSS_MASK (1 << 0)
+
+/* CM_AUTOIDLE_DSS */
+#define OMAP3430_AUTO_DSS_MASK (1 << 0)
+#define OMAP3430_AUTO_DSS_SHIFT 0
+
+/* CM_CLKSEL_DSS */
+#define OMAP3430_CLKSEL_TV_SHIFT 8
+#define OMAP3430_CLKSEL_TV_MASK (0x1f << 8)
+#define OMAP3630_CLKSEL_TV_MASK (0x3f << 8)
+#define OMAP3430_CLKSEL_DSS1_SHIFT 0
+#define OMAP3430_CLKSEL_DSS1_MASK (0x1f << 0)
+#define OMAP3630_CLKSEL_DSS1_MASK (0x3f << 0)
+
+/* CM_SLEEPDEP_DSS specific bits */
+
+/* CM_CLKSTCTRL_DSS */
+#define OMAP3430_CLKTRCTRL_DSS_SHIFT 0
+#define OMAP3430_CLKTRCTRL_DSS_MASK (0x3 << 0)
+
+/* CM_CLKSTST_DSS */
+#define OMAP3430_CLKACTIVITY_DSS_SHIFT 0
+#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0)
+
+/* CM_FCLKEN_CAM specific bits */
+#define OMAP3430_EN_CSI2_MASK (1 << 1)
+#define OMAP3430_EN_CSI2_SHIFT 1
+
+/* CM_ICLKEN_CAM specific bits */
+
+/* CM_IDLEST_CAM */
+#define OMAP3430_ST_CAM_MASK (1 << 0)
+
+/* CM_AUTOIDLE_CAM */
+#define OMAP3430_AUTO_CAM_MASK (1 << 0)
+#define OMAP3430_AUTO_CAM_SHIFT 0
+
+/* CM_CLKSEL_CAM */
+#define OMAP3430_CLKSEL_CAM_SHIFT 0
+#define OMAP3430_CLKSEL_CAM_MASK (0x1f << 0)
+#define OMAP3630_CLKSEL_CAM_MASK (0x3f << 0)
+
+/* CM_SLEEPDEP_CAM specific bits */
+
+/* CM_CLKSTCTRL_CAM */
+#define OMAP3430_CLKTRCTRL_CAM_SHIFT 0
+#define OMAP3430_CLKTRCTRL_CAM_MASK (0x3 << 0)
+
+/* CM_CLKSTST_CAM */
+#define OMAP3430_CLKACTIVITY_CAM_SHIFT 0
+#define OMAP3430_CLKACTIVITY_CAM_MASK (1 << 0)
+
+/* CM_FCLKEN_PER specific bits */
+
+/* CM_ICLKEN_PER specific bits */
+
+/* CM_IDLEST_PER */
+#define OMAP3430_ST_WDT3_SHIFT 12
+#define OMAP3430_ST_WDT3_MASK (1 << 12)
+#define OMAP3430_ST_MCBSP4_SHIFT 2
+#define OMAP3430_ST_MCBSP4_MASK (1 << 2)
+#define OMAP3430_ST_MCBSP3_SHIFT 1
+#define OMAP3430_ST_MCBSP3_MASK (1 << 1)
+#define OMAP3430_ST_MCBSP2_SHIFT 0
+#define OMAP3430_ST_MCBSP2_MASK (1 << 0)
+
+/* CM_AUTOIDLE_PER */
+#define OMAP3630_AUTO_UART4_MASK (1 << 18)
+#define OMAP3630_AUTO_UART4_SHIFT 18
+#define OMAP3430_AUTO_GPIO6_MASK (1 << 17)
+#define OMAP3430_AUTO_GPIO6_SHIFT 17
+#define OMAP3430_AUTO_GPIO5_MASK (1 << 16)
+#define OMAP3430_AUTO_GPIO5_SHIFT 16
+#define OMAP3430_AUTO_GPIO4_MASK (1 << 15)
+#define OMAP3430_AUTO_GPIO4_SHIFT 15
+#define OMAP3430_AUTO_GPIO3_MASK (1 << 14)
+#define OMAP3430_AUTO_GPIO3_SHIFT 14
+#define OMAP3430_AUTO_GPIO2_MASK (1 << 13)
+#define OMAP3430_AUTO_GPIO2_SHIFT 13
+#define OMAP3430_AUTO_WDT3_MASK (1 << 12)
+#define OMAP3430_AUTO_WDT3_SHIFT 12
+#define OMAP3430_AUTO_UART3_MASK (1 << 11)
+#define OMAP3430_AUTO_UART3_SHIFT 11
+#define OMAP3430_AUTO_GPT9_MASK (1 << 10)
+#define OMAP3430_AUTO_GPT9_SHIFT 10
+#define OMAP3430_AUTO_GPT8_MASK (1 << 9)
+#define OMAP3430_AUTO_GPT8_SHIFT 9
+#define OMAP3430_AUTO_GPT7_MASK (1 << 8)
+#define OMAP3430_AUTO_GPT7_SHIFT 8
+#define OMAP3430_AUTO_GPT6_MASK (1 << 7)
+#define OMAP3430_AUTO_GPT6_SHIFT 7
+#define OMAP3430_AUTO_GPT5_MASK (1 << 6)
+#define OMAP3430_AUTO_GPT5_SHIFT 6
+#define OMAP3430_AUTO_GPT4_MASK (1 << 5)
+#define OMAP3430_AUTO_GPT4_SHIFT 5
+#define OMAP3430_AUTO_GPT3_MASK (1 << 4)
+#define OMAP3430_AUTO_GPT3_SHIFT 4
+#define OMAP3430_AUTO_GPT2_MASK (1 << 3)
+#define OMAP3430_AUTO_GPT2_SHIFT 3
+#define OMAP3430_AUTO_MCBSP4_MASK (1 << 2)
+#define OMAP3430_AUTO_MCBSP4_SHIFT 2
+#define OMAP3430_AUTO_MCBSP3_MASK (1 << 1)
+#define OMAP3430_AUTO_MCBSP3_SHIFT 1
+#define OMAP3430_AUTO_MCBSP2_MASK (1 << 0)
+#define OMAP3430_AUTO_MCBSP2_SHIFT 0
+
+/* CM_CLKSEL_PER */
+#define OMAP3430_CLKSEL_GPT9_MASK (1 << 7)
+#define OMAP3430_CLKSEL_GPT9_SHIFT 7
+#define OMAP3430_CLKSEL_GPT8_MASK (1 << 6)
+#define OMAP3430_CLKSEL_GPT8_SHIFT 6
+#define OMAP3430_CLKSEL_GPT7_MASK (1 << 5)
+#define OMAP3430_CLKSEL_GPT7_SHIFT 5
+#define OMAP3430_CLKSEL_GPT6_MASK (1 << 4)
+#define OMAP3430_CLKSEL_GPT6_SHIFT 4
+#define OMAP3430_CLKSEL_GPT5_MASK (1 << 3)
+#define OMAP3430_CLKSEL_GPT5_SHIFT 3
+#define OMAP3430_CLKSEL_GPT4_MASK (1 << 2)
+#define OMAP3430_CLKSEL_GPT4_SHIFT 2
+#define OMAP3430_CLKSEL_GPT3_MASK (1 << 1)
+#define OMAP3430_CLKSEL_GPT3_SHIFT 1
+#define OMAP3430_CLKSEL_GPT2_MASK (1 << 0)
+#define OMAP3430_CLKSEL_GPT2_SHIFT 0
+
+/* CM_SLEEPDEP_PER specific bits */
+#define OMAP3430_CM_SLEEPDEP_PER_EN_IVA2_MASK (1 << 2)
+
+/* CM_CLKSTCTRL_PER */
+#define OMAP3430_CLKTRCTRL_PER_SHIFT 0
+#define OMAP3430_CLKTRCTRL_PER_MASK (0x3 << 0)
+
+/* CM_CLKSTST_PER */
+#define OMAP3430_CLKACTIVITY_PER_SHIFT 0
+#define OMAP3430_CLKACTIVITY_PER_MASK (1 << 0)
+
+/* CM_CLKSEL1_EMU */
+#define OMAP3430_DIV_DPLL4_SHIFT 24
+#define OMAP3430_DIV_DPLL4_MASK (0x1f << 24)
+#define OMAP3630_DIV_DPLL4_MASK (0x3f << 24)
+#define OMAP3430_DIV_DPLL3_SHIFT 16
+#define OMAP3430_DIV_DPLL3_MASK (0x1f << 16)
+#define OMAP3430_CLKSEL_TRACECLK_SHIFT 11
+#define OMAP3430_CLKSEL_TRACECLK_MASK (0x7 << 11)
+#define OMAP3430_CLKSEL_PCLK_SHIFT 8
+#define OMAP3430_CLKSEL_PCLK_MASK (0x7 << 8)
+#define OMAP3430_CLKSEL_PCLKX2_SHIFT 6
+#define OMAP3430_CLKSEL_PCLKX2_MASK (0x3 << 6)
+#define OMAP3430_CLKSEL_ATCLK_SHIFT 4
+#define OMAP3430_CLKSEL_ATCLK_MASK (0x3 << 4)
+#define OMAP3430_TRACE_MUX_CTRL_SHIFT 2
+#define OMAP3430_TRACE_MUX_CTRL_MASK (0x3 << 2)
+#define OMAP3430_MUX_CTRL_SHIFT 0
+#define OMAP3430_MUX_CTRL_MASK (0x3 << 0)
+
+/* CM_CLKSTCTRL_EMU */
+#define OMAP3430_CLKTRCTRL_EMU_SHIFT 0
+#define OMAP3430_CLKTRCTRL_EMU_MASK (0x3 << 0)
+
+/* CM_CLKSTST_EMU */
+#define OMAP3430_CLKACTIVITY_EMU_SHIFT 0
+#define OMAP3430_CLKACTIVITY_EMU_MASK (1 << 0)
+
+/* CM_CLKSEL2_EMU specific bits */
+#define OMAP3430_CORE_DPLL_EMU_MULT_SHIFT 8
+#define OMAP3430_CORE_DPLL_EMU_MULT_MASK (0x7ff << 8)
+#define OMAP3430_CORE_DPLL_EMU_DIV_SHIFT 0
+#define OMAP3430_CORE_DPLL_EMU_DIV_MASK (0x7f << 0)
+
+/* CM_CLKSEL3_EMU specific bits */
+#define OMAP3430_PERIPH_DPLL_EMU_MULT_SHIFT 8
+#define OMAP3430_PERIPH_DPLL_EMU_MULT_MASK (0x7ff << 8)
+#define OMAP3430_PERIPH_DPLL_EMU_DIV_SHIFT 0
+#define OMAP3430_PERIPH_DPLL_EMU_DIV_MASK (0x7f << 0)
+
+/* CM_POLCTRL */
+#define OMAP3430_CLKOUT2_POL_MASK (1 << 0)
+
+/* CM_IDLEST_NEON */
+#define OMAP3430_ST_NEON_MASK (1 << 0)
+
+/* CM_CLKSTCTRL_NEON */
+#define OMAP3430_CLKTRCTRL_NEON_SHIFT 0
+#define OMAP3430_CLKTRCTRL_NEON_MASK (0x3 << 0)
+
+/* CM_FCLKEN_USBHOST */
+#define OMAP3430ES2_EN_USBHOST2_SHIFT 1
+#define OMAP3430ES2_EN_USBHOST2_MASK (1 << 1)
+#define OMAP3430ES2_EN_USBHOST1_SHIFT 0
+#define OMAP3430ES2_EN_USBHOST1_MASK (1 << 0)
+
+/* CM_ICLKEN_USBHOST */
+#define OMAP3430ES2_EN_USBHOST_SHIFT 0
+#define OMAP3430ES2_EN_USBHOST_MASK (1 << 0)
+
+/* CM_IDLEST_USBHOST */
+#define OMAP3430ES2_ST_USBHOST_IDLE_SHIFT 1
+#define OMAP3430ES2_ST_USBHOST_IDLE_MASK (1 << 1)
+#define OMAP3430ES2_ST_USBHOST_STDBY_SHIFT 0
+#define OMAP3430ES2_ST_USBHOST_STDBY_MASK (1 << 0)
+
+/* CM_AUTOIDLE_USBHOST */
+#define OMAP3430ES2_AUTO_USBHOST_SHIFT 0
+#define OMAP3430ES2_AUTO_USBHOST_MASK (1 << 0)
+
+/* CM_SLEEPDEP_USBHOST */
+#define OMAP3430ES2_EN_MPU_SHIFT 1
+#define OMAP3430ES2_EN_MPU_MASK (1 << 1)
+#define OMAP3430ES2_EN_IVA2_SHIFT 2
+#define OMAP3430ES2_EN_IVA2_MASK (1 << 2)
+
+/* CM_CLKSTCTRL_USBHOST */
+#define OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT 0
+#define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK (3 << 0)
+
+/* CM_CLKSTST_USBHOST */
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT 0
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK (1 << 0)
+
+/*
+ *
+ */
+
+/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
+#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1
+#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
+#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
+
+
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-44xx.h b/arch/arm/mach-omap2/cm-regbits-44xx.h
new file mode 100644
index 00000000..9d47a05b
--- /dev/null
+++ b/arch/arm/mach-omap2/cm-regbits-44xx.h
@@ -0,0 +1,1524 @@
+/*
+ * OMAP44xx Clock Management register bits
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_REGBITS_44XX_H
+
+/*
+ * Used by CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP,
+ * CM_TESLA_DYNAMICDEP
+ */
+#define OMAP4430_ABE_DYNDEP_SHIFT 3
+#define OMAP4430_ABE_DYNDEP_MASK (1 << 3)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_ABE_STATDEP_SHIFT 3
+#define OMAP4430_ABE_STATDEP_MASK (1 << 3)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
+#define OMAP4430_ALWONCORE_DYNDEP_SHIFT 16
+#define OMAP4430_ALWONCORE_DYNDEP_MASK (1 << 16)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
+#define OMAP4430_ALWONCORE_STATDEP_SHIFT 16
+#define OMAP4430_ALWONCORE_STATDEP_MASK (1 << 16)
+
+/*
+ * Used by CM_AUTOIDLE_DPLL_ABE, CM_AUTOIDLE_DPLL_CORE,
+ * CM_AUTOIDLE_DPLL_CORE_RESTORE, CM_AUTOIDLE_DPLL_DDRPHY,
+ * CM_AUTOIDLE_DPLL_IVA, CM_AUTOIDLE_DPLL_MPU, CM_AUTOIDLE_DPLL_PER,
+ * CM_AUTOIDLE_DPLL_UNIPRO, CM_AUTOIDLE_DPLL_USB
+ */
+#define OMAP4430_AUTO_DPLL_MODE_SHIFT 0
+#define OMAP4430_AUTO_DPLL_MODE_MASK (0x7 << 0)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
+#define OMAP4430_CEFUSE_DYNDEP_SHIFT 17
+#define OMAP4430_CEFUSE_DYNDEP_MASK (1 << 17)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_TESLA_STATICDEP */
+#define OMAP4430_CEFUSE_STATDEP_SHIFT 17
+#define OMAP4430_CEFUSE_STATDEP_MASK (1 << 17)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_ABE_24M_GFCLK_MASK (1 << 13)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_ABE_ALWON_32K_CLK_MASK (1 << 12)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_ABE_LP_CLK_MASK (1 << 9)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_ABE_SYSCLK_MASK (1 << 11)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_ABE_X2_CLK_MASK (1 << 8)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_ASYNC_DLL_CLK_MASK (1 << 11)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY1_CLK_MASK (1 << 12)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_ASYNC_PHY2_CLK_MASK (1 << 13)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CAM_PHY_CTRL_GCLK_MASK (1 << 9)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_CORE_ALWON_32K_GFCLK_MASK (1 << 12)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CORE_DPLL_EMU_CLK_MASK (1 << 9)
+
+/* Used by CM_CEFUSE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_CUST_EFUSE_SYS_CLK_MASK (1 << 9)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DLL_CLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DLL_CLK_MASK (1 << 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DMT10_GFCLK_MASK (1 << 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_DMT11_GFCLK_MASK (1 << 10)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_DMT2_GFCLK_MASK (1 << 11)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_DMT3_GFCLK_MASK (1 << 12)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_DMT4_GFCLK_MASK (1 << 13)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_SHIFT 14
+#define OMAP4430_CLKACTIVITY_DMT9_GFCLK_MASK (1 << 14)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_DSS_ALWON_SYS_CLK_MASK (1 << 10)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_DSS_FCLK_MASK (1 << 9)
+
+/* Used by CM_DUCATI_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_DUCATI_GCLK_MASK (1 << 8)
+
+/* Used by CM_EMU_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_EMU_SYS_CLK_MASK (1 << 8)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_FDIF_GFCLK_MASK (1 << 10)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_SHIFT 15
+#define OMAP4430_CLKACTIVITY_FUNC_12M_GFCLK_MASK (1 << 15)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_FUNC_24M_GFCLK_MASK (1 << 10)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_HDMI_PHY_48MHZ_GFCLK_MASK (1 << 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_SHIFT 20
+#define OMAP4430_CLKACTIVITY_HSIC_P1_480M_GFCLK_MASK (1 << 20)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_SHIFT 26
+#define OMAP4430_CLKACTIVITY_HSIC_P1_GFCLK_MASK (1 << 26)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_SHIFT 21
+#define OMAP4430_CLKACTIVITY_HSIC_P2_480M_GFCLK_MASK (1 << 21)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_SHIFT 27
+#define OMAP4430_CLKACTIVITY_HSIC_P2_GFCLK_MASK (1 << 27)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_SHIFT 13
+#define OMAP4430_CLKACTIVITY_INIT_48MC_GFCLK_MASK (1 << 13)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_INIT_48M_GFCLK_MASK (1 << 12)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_SHIFT 28
+#define OMAP4430_CLKACTIVITY_INIT_60M_P1_GFCLK_MASK (1 << 28)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_SHIFT 29
+#define OMAP4430_CLKACTIVITY_INIT_60M_P2_GFCLK_MASK (1 << 29)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_INIT_96M_GFCLK_MASK (1 << 11)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_SHIFT 16
+#define OMAP4430_CLKACTIVITY_INIT_HSI_GFCLK_MASK (1 << 16)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_SHIFT 17
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC1_GFCLK_MASK (1 << 17)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_SHIFT 18
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC2_GFCLK_MASK (1 << 18)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_SHIFT 19
+#define OMAP4430_CLKACTIVITY_INIT_HSMMC6_GFCLK_MASK (1 << 19)
+
+/* Used by CM_CAM_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_ISS_GCLK_MASK (1 << 8)
+
+/* Used by CM_IVAHD_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_IVAHD_ROOT_CLK_MASK (1 << 8)
+
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_L3X2_D2D_GICLK_MASK (1 << 10)
+
+/* Used by CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_1_GICLK_MASK (1 << 8)
+
+/* Used by CM_L3_2_CLKSTCTRL, CM_L3_2_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_2_GICLK_MASK (1 << 8)
+
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_D2D_GICLK_MASK (1 << 8)
+
+/* Used by CM_SDMA_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_DMA_GICLK_MASK (1 << 8)
+
+/* Used by CM_DSS_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_DSS_GICLK_MASK (1 << 8)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_EMIF_GICLK_MASK (1 << 8)
+
+/* Used by CM_GFX_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_GFX_GICLK_MASK (1 << 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_INIT_GICLK_MASK (1 << 8)
+
+/* Used by CM_L3INSTR_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_INSTR_GICLK_MASK (1 << 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L3_SECURE_GICLK_MASK (1 << 8)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_AO_ICLK_MASK (1 << 8)
+
+/* Used by CM_CEFUSE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_CEFUSE_GICLK_MASK (1 << 8)
+
+/* Used by CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_CFG_GICLK_MASK (1 << 8)
+
+/* Used by CM_D2D_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_D2D_GICLK_MASK (1 << 9)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_INIT_GICLK_MASK (1 << 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_L4_PER_GICLK_MASK (1 << 8)
+
+/* Used by CM_L4SEC_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_L4_SECURE_GICLK_MASK (1 << 9)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_SHIFT 12
+#define OMAP4430_CLKACTIVITY_L4_WKUP_GICLK_MASK (1 << 12)
+
+/* Used by CM_MPU_CLKSTCTRL, CM_MPU_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_MPU_DPLL_CLK_MASK (1 << 8)
+
+/* Used by CM1_ABE_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_OCP_ABE_GICLK_MASK (1 << 9)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_SHIFT 16
+#define OMAP4430_CLKACTIVITY_PER_24MC_GFCLK_MASK (1 << 16)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_SHIFT 17
+#define OMAP4430_CLKACTIVITY_PER_32K_GFCLK_MASK (1 << 17)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_SHIFT 18
+#define OMAP4430_CLKACTIVITY_PER_48M_GFCLK_MASK (1 << 18)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_SHIFT 19
+#define OMAP4430_CLKACTIVITY_PER_96M_GFCLK_MASK (1 << 19)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_SHIFT 25
+#define OMAP4430_CLKACTIVITY_PER_ABE_24M_GFCLK_MASK (1 << 25)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_SHIFT 20
+#define OMAP4430_CLKACTIVITY_PER_MCASP2_GFCLK_MASK (1 << 20)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_SHIFT 21
+#define OMAP4430_CLKACTIVITY_PER_MCASP3_GFCLK_MASK (1 << 21)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_SHIFT 22
+#define OMAP4430_CLKACTIVITY_PER_MCBSP4_GFCLK_MASK (1 << 22)
+
+/* Used by CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_SHIFT 24
+#define OMAP4430_CLKACTIVITY_PER_SYS_GFCLK_MASK (1 << 24)
+
+/* Used by CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_PHY_ROOT_CLK_MASK (1 << 10)
+
+/* Used by CM_GFX_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_SGX_GFCLK_MASK (1 << 9)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_SR_CORE_SYSCLK_MASK (1 << 11)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_SR_IVA_SYSCLK_MASK (1 << 10)
+
+/* Used by CM_ALWON_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_SHIFT 9
+#define OMAP4430_CLKACTIVITY_SR_MPU_SYSCLK_MASK (1 << 9)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_SYS_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_SYS_CLK_MASK (1 << 8)
+
+/* Used by CM_TESLA_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_SHIFT 8
+#define OMAP4430_CLKACTIVITY_TESLA_ROOT_CLK_MASK (1 << 8)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_SHIFT 22
+#define OMAP4430_CLKACTIVITY_TLL_CH0_GFCLK_MASK (1 << 22)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_SHIFT 23
+#define OMAP4430_CLKACTIVITY_TLL_CH1_GFCLK_MASK (1 << 23)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_SHIFT 24
+#define OMAP4430_CLKACTIVITY_TLL_CH2_GFCLK_MASK (1 << 24)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_UNIPRO_DPLL_CLK_MASK (1 << 10)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_SHIFT 14
+#define OMAP4430_CLKACTIVITY_USB_DPLL_CLK_MASK (1 << 14)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_SHIFT 15
+#define OMAP4430_CLKACTIVITY_USB_DPLL_HS_CLK_MASK (1 << 15)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_SHIFT 10
+#define OMAP4430_CLKACTIVITY_USIM_GFCLK_MASK (1 << 10)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_SHIFT 30
+#define OMAP4430_CLKACTIVITY_UTMI_P3_GFCLK_MASK (1 << 30)
+
+/* Used by CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE */
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_SHIFT 25
+#define OMAP4430_CLKACTIVITY_UTMI_ROOT_GFCLK_MASK (1 << 25)
+
+/* Used by CM_WKUP_CLKSTCTRL */
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_SHIFT 11
+#define OMAP4430_CLKACTIVITY_WKUP_32K_GFCLK_MASK (1 << 11)
+
+/*
+ * Used by CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL,
+ * CM1_ABE_TIMER7_CLKCTRL, CM1_ABE_TIMER8_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL,
+ * CM_L3INIT_MMC2_CLKCTRL, CM_L3INIT_MMC6_CLKCTRL, CM_L4PER_DMTIMER10_CLKCTRL,
+ * CM_L4PER_DMTIMER11_CLKCTRL, CM_L4PER_DMTIMER2_CLKCTRL,
+ * CM_L4PER_DMTIMER3_CLKCTRL, CM_L4PER_DMTIMER4_CLKCTRL,
+ * CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL,
+ * CM_WKUP_TIMER1_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_SHIFT 24
+#define OMAP4430_CLKSEL_MASK (1 << 24)
+
+/*
+ * Renamed from CLKSEL Used by CM_ABE_DSS_SYS_CLKSEL, CM_ABE_PLL_REF_CLKSEL,
+ * CM_L4_WKUP_CLKSEL, CM_CLKSEL_DUCATI_ISS_ROOT, CM_CLKSEL_USB_60MHZ
+ */
+#define OMAP4430_CLKSEL_0_0_SHIFT 0
+#define OMAP4430_CLKSEL_0_0_MASK (1 << 0)
+
+/* Renamed from CLKSEL Used by CM_BYPCLK_DPLL_IVA, CM_BYPCLK_DPLL_MPU */
+#define OMAP4430_CLKSEL_0_1_SHIFT 0
+#define OMAP4430_CLKSEL_0_1_MASK (0x3 << 0)
+
+/* Renamed from CLKSEL Used by CM_L3INIT_HSI_CLKCTRL */
+#define OMAP4430_CLKSEL_24_25_SHIFT 24
+#define OMAP4430_CLKSEL_24_25_MASK (0x3 << 24)
+
+/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
+#define OMAP4430_CLKSEL_60M_SHIFT 24
+#define OMAP4430_CLKSEL_60M_MASK (1 << 24)
+
+/* Used by CM1_ABE_AESS_CLKCTRL */
+#define OMAP4430_CLKSEL_AESS_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_AESS_FCLK_MASK (1 << 24)
+
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
+#define OMAP4430_CLKSEL_CORE_SHIFT 0
+#define OMAP4430_CLKSEL_CORE_MASK (1 << 0)
+
+/*
+ * Renamed from CLKSEL_CORE Used by CM_SHADOW_FREQ_CONFIG2_RESTORE,
+ * CM_SHADOW_FREQ_CONFIG2
+ */
+#define OMAP4430_CLKSEL_CORE_1_1_SHIFT 1
+#define OMAP4430_CLKSEL_CORE_1_1_MASK (1 << 1)
+
+/* Used by CM_WKUP_USIM_CLKCTRL */
+#define OMAP4430_CLKSEL_DIV_SHIFT 24
+#define OMAP4430_CLKSEL_DIV_MASK (1 << 24)
+
+/* Used by CM_CAM_FDIF_CLKCTRL */
+#define OMAP4430_CLKSEL_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_FCLK_MASK (0x3 << 24)
+
+/* Used by CM_L4PER_MCBSP4_CLKCTRL */
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT 25
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_MASK (1 << 25)
+
+/*
+ * Renamed from CLKSEL_INTERNAL_SOURCE Used by CM1_ABE_DMIC_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_SHIFT 26
+#define OMAP4430_CLKSEL_INTERNAL_SOURCE_CM1_ABE_DMIC_MASK (0x3 << 26)
+
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
+#define OMAP4430_CLKSEL_L3_SHIFT 4
+#define OMAP4430_CLKSEL_L3_MASK (1 << 4)
+
+/*
+ * Renamed from CLKSEL_L3 Used by CM_SHADOW_FREQ_CONFIG2_RESTORE,
+ * CM_SHADOW_FREQ_CONFIG2
+ */
+#define OMAP4430_CLKSEL_L3_SHADOW_SHIFT 2
+#define OMAP4430_CLKSEL_L3_SHADOW_MASK (1 << 2)
+
+/* Used by CM_CLKSEL_CORE, CM_CLKSEL_CORE_RESTORE */
+#define OMAP4430_CLKSEL_L4_SHIFT 8
+#define OMAP4430_CLKSEL_L4_MASK (1 << 8)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_CLKSEL_OPP_SHIFT 0
+#define OMAP4430_CLKSEL_OPP_MASK (0x3 << 0)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_CLKSEL_PMD_STM_CLK_SHIFT 27
+#define OMAP4430_CLKSEL_PMD_STM_CLK_MASK (0x7 << 27)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_SHIFT 24
+#define OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK (0x7 << 24)
+
+/* Used by CM_GFX_GFX_CLKCTRL */
+#define OMAP4430_CLKSEL_SGX_FCLK_SHIFT 24
+#define OMAP4430_CLKSEL_SGX_FCLK_MASK (1 << 24)
+
+/*
+ * Used by CM1_ABE_DMIC_CLKCTRL, CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL,
+ * CM1_ABE_MCBSP2_CLKCTRL, CM1_ABE_MCBSP3_CLKCTRL
+ */
+#define OMAP4430_CLKSEL_SOURCE_SHIFT 24
+#define OMAP4430_CLKSEL_SOURCE_MASK (0x3 << 24)
+
+/* Renamed from CLKSEL_SOURCE Used by CM_L4PER_MCBSP4_CLKCTRL */
+#define OMAP4430_CLKSEL_SOURCE_24_24_SHIFT 24
+#define OMAP4430_CLKSEL_SOURCE_24_24_MASK (1 << 24)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_CLKSEL_UTMI_P1_SHIFT 24
+#define OMAP4430_CLKSEL_UTMI_P1_MASK (1 << 24)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_CLKSEL_UTMI_P2_SHIFT 25
+#define OMAP4430_CLKSEL_UTMI_P2_MASK (1 << 25)
+
+/*
+ * Used by CM1_ABE_CLKSTCTRL, CM_ALWON_CLKSTCTRL, CM_CAM_CLKSTCTRL,
+ * CM_CEFUSE_CLKSTCTRL, CM_D2D_CLKSTCTRL, CM_DSS_CLKSTCTRL,
+ * CM_DUCATI_CLKSTCTRL, CM_EMU_CLKSTCTRL, CM_GFX_CLKSTCTRL, CM_IVAHD_CLKSTCTRL,
+ * CM_L3INIT_CLKSTCTRL, CM_L3INIT_CLKSTCTRL_RESTORE, CM_L3INSTR_CLKSTCTRL,
+ * CM_L3_1_CLKSTCTRL, CM_L3_1_CLKSTCTRL_RESTORE, CM_L3_2_CLKSTCTRL,
+ * CM_L3_2_CLKSTCTRL_RESTORE, CM_L4CFG_CLKSTCTRL, CM_L4CFG_CLKSTCTRL_RESTORE,
+ * CM_L4PER_CLKSTCTRL, CM_L4PER_CLKSTCTRL_RESTORE, CM_L4SEC_CLKSTCTRL,
+ * CM_MEMIF_CLKSTCTRL, CM_MEMIF_CLKSTCTRL_RESTORE, CM_MPU_CLKSTCTRL,
+ * CM_MPU_CLKSTCTRL_RESTORE, CM_SDMA_CLKSTCTRL, CM_TESLA_CLKSTCTRL,
+ * CM_WKUP_CLKSTCTRL
+ */
+#define OMAP4430_CLKTRCTRL_SHIFT 0
+#define OMAP4430_CLKTRCTRL_MASK (0x3 << 0)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_CORE_DPLL_EMU_DIV_SHIFT 0
+#define OMAP4430_CORE_DPLL_EMU_DIV_MASK (0x7f << 0)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_CORE_DPLL_EMU_MULT_SHIFT 8
+#define OMAP4430_CORE_DPLL_EMU_MULT_MASK (0x7ff << 8)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_CUSTOM_SHIFT 6
+#define OMAP4430_CUSTOM_MASK (0x3 << 6)
+
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE
+ */
+#define OMAP4430_D2D_DYNDEP_SHIFT 18
+#define OMAP4430_D2D_DYNDEP_MASK (1 << 18)
+
+/* Used by CM_MPU_STATICDEP */
+#define OMAP4430_D2D_STATDEP_SHIFT 18
+#define OMAP4430_D2D_STATDEP_MASK (1 << 18)
+
+/*
+ * Used by CM_SSC_DELTAMSTEP_DPLL_ABE, CM_SSC_DELTAMSTEP_DPLL_CORE,
+ * CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE, CM_SSC_DELTAMSTEP_DPLL_DDRPHY,
+ * CM_SSC_DELTAMSTEP_DPLL_IVA, CM_SSC_DELTAMSTEP_DPLL_MPU,
+ * CM_SSC_DELTAMSTEP_DPLL_PER, CM_SSC_DELTAMSTEP_DPLL_UNIPRO,
+ * CM_SSC_DELTAMSTEP_DPLL_USB
+ */
+#define OMAP4430_DELTAMSTEP_SHIFT 0
+#define OMAP4430_DELTAMSTEP_MASK (0xfffff << 0)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
+#define OMAP4430_DLL_OVERRIDE_SHIFT 2
+#define OMAP4430_DLL_OVERRIDE_MASK (1 << 2)
+
+/* Renamed from DLL_OVERRIDE Used by CM_DLL_CTRL */
+#define OMAP4430_DLL_OVERRIDE_0_0_SHIFT 0
+#define OMAP4430_DLL_OVERRIDE_0_0_MASK (1 << 0)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
+#define OMAP4430_DLL_RESET_SHIFT 3
+#define OMAP4430_DLL_RESET_MASK (1 << 3)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO,
+ * CM_CLKSEL_DPLL_USB
+ */
+#define OMAP4430_DPLL_BYP_CLKSEL_SHIFT 23
+#define OMAP4430_DPLL_BYP_CLKSEL_MASK (1 << 23)
+
+/* Used by CM_CLKDCOLDO_DPLL_USB */
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_MASK (1 << 8)
+
+/* Used by CM_CLKSEL_DPLL_CORE, CM_CLKSEL_DPLL_CORE_RESTORE */
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_SHIFT 20
+#define OMAP4430_DPLL_CLKOUTHIF_CLKSEL_MASK (1 << 20)
+
+/*
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_SHIFT 0
+#define OMAP4430_DPLL_CLKOUTHIF_DIV_MASK (0x1f << 0)
+
+/*
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_SHIFT 5
+#define OMAP4430_DPLL_CLKOUTHIF_DIVCHACK_MASK (1 << 5)
+
+/*
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_MASK (1 << 8)
+
+/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_SHIFT 10
+#define OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK (1 << 10)
+
+/*
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_CLKOUT_DIV_SHIFT 0
+#define OMAP4430_DPLL_CLKOUT_DIV_MASK (0x1f << 0)
+
+/* Renamed from DPLL_CLKOUT_DIV Used by CM_DIV_M2_DPLL_USB */
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_SHIFT 0
+#define OMAP4430_DPLL_CLKOUT_DIV_0_6_MASK (0x7f << 0)
+
+/*
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_SHIFT 5
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_MASK (1 << 5)
+
+/* Renamed from DPLL_CLKOUT_DIVCHACK Used by CM_DIV_M2_DPLL_USB */
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_SHIFT 7
+#define OMAP4430_DPLL_CLKOUT_DIVCHACK_M2_USB_MASK (1 << 7)
+
+/*
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
+ */
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT 8
+#define OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK (1 << 8)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
+#define OMAP4430_DPLL_CORE_DPLL_EN_SHIFT 8
+#define OMAP4430_DPLL_CORE_DPLL_EN_MASK (0x7 << 8)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
+#define OMAP4430_DPLL_CORE_M2_DIV_SHIFT 11
+#define OMAP4430_DPLL_CORE_M2_DIV_MASK (0x1f << 11)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2, CM_SHADOW_FREQ_CONFIG2_RESTORE */
+#define OMAP4430_DPLL_CORE_M5_DIV_SHIFT 3
+#define OMAP4430_DPLL_CORE_M5_DIV_MASK (0x1f << 3)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_DIV_SHIFT 0
+#define OMAP4430_DPLL_DIV_MASK (0x7f << 0)
+
+/* Renamed from DPLL_DIV Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_DIV_0_7_SHIFT 0
+#define OMAP4430_DPLL_DIV_0_7_MASK (0xff << 0)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER
+ */
+#define OMAP4430_DPLL_DRIFTGUARD_EN_SHIFT 8
+#define OMAP4430_DPLL_DRIFTGUARD_EN_MASK (1 << 8)
+
+/* Renamed from DPLL_DRIFTGUARD_EN Used by CM_CLKMODE_DPLL_UNIPRO */
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_SHIFT 3
+#define OMAP4430_DPLL_DRIFTGUARD_EN_3_3_MASK (1 << 3)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
+ */
+#define OMAP4430_DPLL_EN_SHIFT 0
+#define OMAP4430_DPLL_EN_MASK (0x7 << 0)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_LPMODE_EN_SHIFT 10
+#define OMAP4430_DPLL_LPMODE_EN_MASK (1 << 10)
+
+/*
+ * Used by CM_CLKSEL_DPLL_ABE, CM_CLKSEL_DPLL_CORE,
+ * CM_CLKSEL_DPLL_CORE_RESTORE, CM_CLKSEL_DPLL_DDRPHY, CM_CLKSEL_DPLL_IVA,
+ * CM_CLKSEL_DPLL_MPU, CM_CLKSEL_DPLL_PER, CM_CLKSEL_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_MULT_SHIFT 8
+#define OMAP4430_DPLL_MULT_MASK (0x7ff << 8)
+
+/* Renamed from DPLL_MULT Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_MULT_USB_SHIFT 8
+#define OMAP4430_DPLL_MULT_USB_MASK (0xfff << 8)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO
+ */
+#define OMAP4430_DPLL_REGM4XEN_SHIFT 11
+#define OMAP4430_DPLL_REGM4XEN_MASK (1 << 11)
+
+/* Used by CM_CLKSEL_DPLL_USB */
+#define OMAP4430_DPLL_SD_DIV_SHIFT 24
+#define OMAP4430_DPLL_SD_DIV_MASK (0xff << 24)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
+ */
+#define OMAP4430_DPLL_SSC_ACK_SHIFT 13
+#define OMAP4430_DPLL_SSC_ACK_MASK (1 << 13)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
+ */
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_SHIFT 14
+#define OMAP4430_DPLL_SSC_DOWNSPREAD_MASK (1 << 14)
+
+/*
+ * Used by CM_CLKMODE_DPLL_ABE, CM_CLKMODE_DPLL_CORE,
+ * CM_CLKMODE_DPLL_CORE_RESTORE, CM_CLKMODE_DPLL_DDRPHY, CM_CLKMODE_DPLL_IVA,
+ * CM_CLKMODE_DPLL_MPU, CM_CLKMODE_DPLL_PER, CM_CLKMODE_DPLL_UNIPRO,
+ * CM_CLKMODE_DPLL_USB
+ */
+#define OMAP4430_DPLL_SSC_EN_SHIFT 12
+#define OMAP4430_DPLL_SSC_EN_MASK (1 << 12)
+
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP, CM_L4PER_DYNAMICDEP_RESTORE
+ */
+#define OMAP4430_DSS_DYNDEP_SHIFT 8
+#define OMAP4430_DSS_DYNDEP_MASK (1 << 8)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE
+ */
+#define OMAP4430_DSS_STATDEP_SHIFT 8
+#define OMAP4430_DSS_STATDEP_MASK (1 << 8)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
+#define OMAP4430_DUCATI_DYNDEP_SHIFT 0
+#define OMAP4430_DUCATI_DYNDEP_MASK (1 << 0)
+
+/* Used by CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE */
+#define OMAP4430_DUCATI_STATDEP_SHIFT 0
+#define OMAP4430_DUCATI_STATDEP_MASK (1 << 0)
+
+/* Used by CM_SHADOW_FREQ_CONFIG1, CM_SHADOW_FREQ_CONFIG1_RESTORE */
+#define OMAP4430_FREQ_UPDATE_SHIFT 0
+#define OMAP4430_FREQ_UPDATE_MASK (1 << 0)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_FUNC_SHIFT 16
+#define OMAP4430_FUNC_MASK (0xfff << 16)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
+#define OMAP4430_GFX_DYNDEP_SHIFT 10
+#define OMAP4430_GFX_DYNDEP_MASK (1 << 10)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_GFX_STATDEP_SHIFT 10
+#define OMAP4430_GFX_STATDEP_MASK (1 << 10)
+
+/* Used by CM_SHADOW_FREQ_CONFIG2, CM_SHADOW_FREQ_CONFIG2_RESTORE */
+#define OMAP4430_GPMC_FREQ_UPDATE_SHIFT 0
+#define OMAP4430_GPMC_FREQ_UPDATE_MASK (1 << 0)
+
+/*
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIV_MASK (0x1f << 0)
+
+/*
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT1_DIVCHACK_MASK (1 << 5)
+
+/*
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT1_GATE_CTRL_MASK (1 << 8)
+
+/*
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT1_PWDN_MASK (1 << 12)
+
+/*
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIV_MASK (0x1f << 0)
+
+/*
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT2_DIVCHACK_MASK (1 << 5)
+
+/*
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT2_GATE_CTRL_MASK (1 << 8)
+
+/*
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT2_PWDN_MASK (1 << 12)
+
+/*
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIV_MASK (0x1f << 0)
+
+/*
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT3_DIVCHACK_MASK (1 << 5)
+
+/*
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT3_GATE_CTRL_MASK (1 << 8)
+
+/*
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT3_PWDN_MASK (1 << 12)
+
+/*
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_SHIFT 0
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIV_MASK (0x1f << 0)
+
+/*
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_SHIFT 5
+#define OMAP4430_HSDIVIDER_CLKOUT4_DIVCHACK_MASK (1 << 5)
+
+/*
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_SHIFT 8
+#define OMAP4430_HSDIVIDER_CLKOUT4_GATE_CTRL_MASK (1 << 8)
+
+/*
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
+ */
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_SHIFT 12
+#define OMAP4430_HSDIVIDER_CLKOUT4_PWDN_MASK (1 << 12)
+
+/*
+ * Used by CM1_ABE_AESS_CLKCTRL, CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
+ * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
+ * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_CM1_PROFILING_CLKCTRL, CM_CM1_PROFILING_CLKCTRL_RESTORE,
+ * CM_CM2_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL_RESTORE,
+ * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL_RESTORE, CM_L3INIT_XHPI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE,
+ * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
+ * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
+ * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
+ * CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
+ * CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
+ * CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL,
+ * CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL,
+ * CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
+ * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
+ * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
+ * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
+ * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
+ */
+#define OMAP4430_IDLEST_SHIFT 16
+#define OMAP4430_IDLEST_MASK (0x3 << 16)
+
+/*
+ * Used by CM_DUCATI_DYNAMICDEP, CM_L3_2_DYNAMICDEP,
+ * CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE
+ */
+#define OMAP4430_ISS_DYNDEP_SHIFT 9
+#define OMAP4430_ISS_DYNDEP_MASK (1 << 9)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_ISS_STATDEP_SHIFT 9
+#define OMAP4430_ISS_STATDEP_MASK (1 << 9)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_TESLA_DYNAMICDEP */
+#define OMAP4430_IVAHD_DYNDEP_SHIFT 2
+#define OMAP4430_IVAHD_DYNDEP_MASK (1 << 2)
+
+/*
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_IVAHD_STATDEP_SHIFT 2
+#define OMAP4430_IVAHD_STATDEP_MASK (1 << 2)
+
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP, CM_L4PER_DYNAMICDEP_RESTORE
+ */
+#define OMAP4430_L3INIT_DYNDEP_SHIFT 7
+#define OMAP4430_L3INIT_DYNDEP_MASK (1 << 7)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_MPU_STATICDEP, CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE,
+ * CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3INIT_STATDEP_SHIFT 7
+#define OMAP4430_L3INIT_STATDEP_MASK (1 << 7)
+
+/*
+ * Used by CM_DSS_DYNAMICDEP, CM_L3INIT_DYNAMICDEP, CM_L3_2_DYNAMICDEP,
+ * CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ */
+#define OMAP4430_L3_1_DYNDEP_SHIFT 5
+#define OMAP4430_L3_1_DYNDEP_MASK (1 << 5)
+
+/*
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3_1_STATDEP_SHIFT 5
+#define OMAP4430_L3_1_STATDEP_MASK (1 << 5)
+
+/*
+ * Used by CM_CAM_DYNAMICDEP, CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE,
+ * CM_DUCATI_DYNAMICDEP, CM_EMU_DYNAMICDEP, CM_GFX_DYNAMICDEP,
+ * CM_IVAHD_DYNAMICDEP, CM_L3INIT_DYNAMICDEP, CM_L3_1_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4SEC_DYNAMICDEP, CM_SDMA_DYNAMICDEP
+ */
+#define OMAP4430_L3_2_DYNDEP_SHIFT 6
+#define OMAP4430_L3_2_DYNDEP_MASK (1 << 6)
+
+/*
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L3_2_STATDEP_SHIFT 6
+#define OMAP4430_L3_2_STATDEP_MASK (1 << 6)
+
+/* Used by CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE */
+#define OMAP4430_L4CFG_DYNDEP_SHIFT 12
+#define OMAP4430_L4CFG_DYNDEP_MASK (1 << 12)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_MPU_STATICDEP, CM_SDMA_STATICDEP,
+ * CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4CFG_STATDEP_SHIFT 12
+#define OMAP4430_L4CFG_STATDEP_MASK (1 << 12)
+
+/* Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE */
+#define OMAP4430_L4PER_DYNDEP_SHIFT 13
+#define OMAP4430_L4PER_DYNDEP_MASK (1 << 13)
+
+/*
+ * Used by CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE, CM_DUCATI_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4PER_STATDEP_SHIFT 13
+#define OMAP4430_L4PER_STATDEP_MASK (1 << 13)
+
+/*
+ * Used by CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP,
+ * CM_L4PER_DYNAMICDEP_RESTORE
+ */
+#define OMAP4430_L4SEC_DYNDEP_SHIFT 14
+#define OMAP4430_L4SEC_DYNDEP_MASK (1 << 14)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_L3INIT_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE
+ */
+#define OMAP4430_L4SEC_STATDEP_SHIFT 14
+#define OMAP4430_L4SEC_STATDEP_MASK (1 << 14)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
+#define OMAP4430_L4WKUP_DYNDEP_SHIFT 15
+#define OMAP4430_L4WKUP_DYNDEP_MASK (1 << 15)
+
+/*
+ * Used by CM_DUCATI_STATICDEP, CM_L3INIT_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_L4WKUP_STATDEP_SHIFT 15
+#define OMAP4430_L4WKUP_STATDEP_MASK (1 << 15)
+
+/*
+ * Used by CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE, CM_L3_1_DYNAMICDEP,
+ * CM_L3_1_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP
+ */
+#define OMAP4430_MEMIF_DYNDEP_SHIFT 4
+#define OMAP4430_MEMIF_DYNDEP_MASK (1 << 4)
+
+/*
+ * Used by CM_CAM_STATICDEP, CM_D2D_STATICDEP, CM_D2D_STATICDEP_RESTORE,
+ * CM_DSS_STATICDEP, CM_DUCATI_STATICDEP, CM_GFX_STATICDEP, CM_IVAHD_STATICDEP,
+ * CM_L3INIT_STATICDEP, CM_L4SEC_STATICDEP, CM_MPU_STATICDEP,
+ * CM_SDMA_STATICDEP, CM_SDMA_STATICDEP_RESTORE, CM_TESLA_STATICDEP
+ */
+#define OMAP4430_MEMIF_STATDEP_SHIFT 4
+#define OMAP4430_MEMIF_STATDEP_MASK (1 << 4)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE, CM_SSC_MODFREQDIV_DPLL_DDRPHY,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB
+ */
+#define OMAP4430_MODFREQDIV_EXPONENT_SHIFT 8
+#define OMAP4430_MODFREQDIV_EXPONENT_MASK (0x7 << 8)
+
+/*
+ * Used by CM_SSC_MODFREQDIV_DPLL_ABE, CM_SSC_MODFREQDIV_DPLL_CORE,
+ * CM_SSC_MODFREQDIV_DPLL_CORE_RESTORE, CM_SSC_MODFREQDIV_DPLL_DDRPHY,
+ * CM_SSC_MODFREQDIV_DPLL_IVA, CM_SSC_MODFREQDIV_DPLL_MPU,
+ * CM_SSC_MODFREQDIV_DPLL_PER, CM_SSC_MODFREQDIV_DPLL_UNIPRO,
+ * CM_SSC_MODFREQDIV_DPLL_USB
+ */
+#define OMAP4430_MODFREQDIV_MANTISSA_SHIFT 0
+#define OMAP4430_MODFREQDIV_MANTISSA_MASK (0x7f << 0)
+
+/*
+ * Used by CM1_ABE_AESS_CLKCTRL, CM1_ABE_DMIC_CLKCTRL, CM1_ABE_L4ABE_CLKCTRL,
+ * CM1_ABE_MCASP_CLKCTRL, CM1_ABE_MCBSP1_CLKCTRL, CM1_ABE_MCBSP2_CLKCTRL,
+ * CM1_ABE_MCBSP3_CLKCTRL, CM1_ABE_PDM_CLKCTRL, CM1_ABE_SLIMBUS_CLKCTRL,
+ * CM1_ABE_TIMER5_CLKCTRL, CM1_ABE_TIMER6_CLKCTRL, CM1_ABE_TIMER7_CLKCTRL,
+ * CM1_ABE_TIMER8_CLKCTRL, CM1_ABE_WDT3_CLKCTRL, CM_ALWON_MDMINTC_CLKCTRL,
+ * CM_ALWON_SR_CORE_CLKCTRL, CM_ALWON_SR_IVA_CLKCTRL, CM_ALWON_SR_MPU_CLKCTRL,
+ * CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL, CM_CEFUSE_CEFUSE_CLKCTRL,
+ * CM_CM1_PROFILING_CLKCTRL, CM_CM1_PROFILING_CLKCTRL_RESTORE,
+ * CM_CM2_PROFILING_CLKCTRL, CM_CM2_PROFILING_CLKCTRL_RESTORE,
+ * CM_D2D_MODEM_ICR_CLKCTRL, CM_D2D_SAD2D_CLKCTRL, CM_D2D_SAD2D_FW_CLKCTRL,
+ * CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL, CM_DUCATI_DUCATI_CLKCTRL,
+ * CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL, CM_IVAHD_IVAHD_CLKCTRL,
+ * CM_IVAHD_SL2_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL_RESTORE, CM_L3INIT_USB_HOST_FS_CLKCTRL,
+ * CM_L3INIT_USB_OTG_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL,
+ * CM_L3INIT_USB_TLL_CLKCTRL_RESTORE, CM_L3INIT_XHPI_CLKCTRL,
+ * CM_L3INSTR_L3_3_CLKCTRL, CM_L3INSTR_L3_3_CLKCTRL_RESTORE,
+ * CM_L3INSTR_L3_INSTR_CLKCTRL, CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE,
+ * CM_L3INSTR_OCP_WP1_CLKCTRL, CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE,
+ * CM_L3_1_L3_1_CLKCTRL, CM_L3_2_GPMC_CLKCTRL, CM_L3_2_L3_2_CLKCTRL,
+ * CM_L3_2_OCMC_RAM_CLKCTRL, CM_L4CFG_HW_SEM_CLKCTRL, CM_L4CFG_L4_CFG_CLKCTRL,
+ * CM_L4CFG_MAILBOX_CLKCTRL, CM_L4CFG_SAR_ROM_CLKCTRL, CM_L4PER_ADC_CLKCTRL,
+ * CM_L4PER_DMTIMER10_CLKCTRL, CM_L4PER_DMTIMER11_CLKCTRL,
+ * CM_L4PER_DMTIMER2_CLKCTRL, CM_L4PER_DMTIMER3_CLKCTRL,
+ * CM_L4PER_DMTIMER4_CLKCTRL, CM_L4PER_DMTIMER9_CLKCTRL, CM_L4PER_ELM_CLKCTRL,
+ * CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE,
+ * CM_L4PER_HDQ1W_CLKCTRL, CM_L4PER_HECC1_CLKCTRL, CM_L4PER_HECC2_CLKCTRL,
+ * CM_L4PER_I2C1_CLKCTRL, CM_L4PER_I2C2_CLKCTRL, CM_L4PER_I2C3_CLKCTRL,
+ * CM_L4PER_I2C4_CLKCTRL, CM_L4PER_I2C5_CLKCTRL, CM_L4PER_L4PER_CLKCTRL,
+ * CM_L4PER_MCASP2_CLKCTRL, CM_L4PER_MCASP3_CLKCTRL, CM_L4PER_MCBSP4_CLKCTRL,
+ * CM_L4PER_MCSPI1_CLKCTRL, CM_L4PER_MCSPI2_CLKCTRL, CM_L4PER_MCSPI3_CLKCTRL,
+ * CM_L4PER_MCSPI4_CLKCTRL, CM_L4PER_MGATE_CLKCTRL, CM_L4PER_MMCSD3_CLKCTRL,
+ * CM_L4PER_MMCSD4_CLKCTRL, CM_L4PER_MMCSD5_CLKCTRL, CM_L4PER_MSPROHG_CLKCTRL,
+ * CM_L4PER_SLIMBUS2_CLKCTRL, CM_L4PER_UART1_CLKCTRL, CM_L4PER_UART2_CLKCTRL,
+ * CM_L4PER_UART3_CLKCTRL, CM_L4PER_UART4_CLKCTRL, CM_L4SEC_AES1_CLKCTRL,
+ * CM_L4SEC_AES2_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_L4SEC_DES3DES_CLKCTRL,
+ * CM_L4SEC_PKAEIP29_CLKCTRL, CM_L4SEC_RNG_CLKCTRL, CM_L4SEC_SHA2MD51_CLKCTRL,
+ * CM_MEMIF_DMM_CLKCTRL, CM_MEMIF_EMIF_1_CLKCTRL, CM_MEMIF_EMIF_2_CLKCTRL,
+ * CM_MEMIF_EMIF_FW_CLKCTRL, CM_MEMIF_EMIF_H1_CLKCTRL,
+ * CM_MEMIF_EMIF_H2_CLKCTRL, CM_MPU_MPU_CLKCTRL, CM_SDMA_SDMA_CLKCTRL,
+ * CM_TESLA_TESLA_CLKCTRL, CM_WKUP_GPIO1_CLKCTRL, CM_WKUP_KEYBOARD_CLKCTRL,
+ * CM_WKUP_L4WKUP_CLKCTRL, CM_WKUP_RTC_CLKCTRL, CM_WKUP_SARRAM_CLKCTRL,
+ * CM_WKUP_SYNCTIMER_CLKCTRL, CM_WKUP_TIMER12_CLKCTRL, CM_WKUP_TIMER1_CLKCTRL,
+ * CM_WKUP_USIM_CLKCTRL, CM_WKUP_WDT1_CLKCTRL, CM_WKUP_WDT2_CLKCTRL
+ */
+#define OMAP4430_MODULEMODE_SHIFT 0
+#define OMAP4430_MODULEMODE_MASK (0x3 << 0)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_48MHZ_CLK_MASK (1 << 9)
+
+/* Used by CM_WKUP_BANDGAP_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_BGAP_32K_MASK (1 << 8)
+
+/* Used by CM_ALWON_USBPHY_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_CLK32K_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CLK32K_MASK (1 << 8)
+
+/* Used by CM_CAM_ISS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_CTRLCLK_MASK (1 << 8)
+
+/*
+ * Used by CM_L4PER_GPIO2_CLKCTRL, CM_L4PER_GPIO2_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO3_CLKCTRL, CM_L4PER_GPIO3_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO4_CLKCTRL, CM_L4PER_GPIO4_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO5_CLKCTRL, CM_L4PER_GPIO5_CLKCTRL_RESTORE,
+ * CM_L4PER_GPIO6_CLKCTRL, CM_L4PER_GPIO6_CLKCTRL_RESTORE, CM_WKUP_GPIO1_CLKCTRL
+ */
+#define OMAP4430_OPTFCLKEN_DBCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DBCLK_MASK (1 << 8)
+
+/* Used by CM_MEMIF_DLL_CLKCTRL, CM_MEMIF_DLL_H_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_DLL_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DLL_CLK_MASK (1 << 8)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_DSSCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_DSSCLK_MASK (1 << 8)
+
+/* Used by CM_WKUP_USIM_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK_MASK (1 << 8)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK0_SHIFT 8
+#define OMAP4430_OPTFCLKEN_FCLK0_MASK (1 << 8)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK1_SHIFT 9
+#define OMAP4430_OPTFCLKEN_FCLK1_MASK (1 << 9)
+
+/* Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_FCLK2_SHIFT 10
+#define OMAP4430_OPTFCLKEN_FCLK2_MASK (1 << 10)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_SHIFT 15
+#define OMAP4430_OPTFCLKEN_FUNC48MCLK_MASK (1 << 15)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_SHIFT 13
+#define OMAP4430_OPTFCLKEN_HSIC480M_P1_CLK_MASK (1 << 13)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_SHIFT 14
+#define OMAP4430_OPTFCLKEN_HSIC480M_P2_CLK_MASK (1 << 14)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_HSIC60M_P1_CLK_MASK (1 << 11)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_SHIFT 12
+#define OMAP4430_OPTFCLKEN_HSIC60M_P2_CLK_MASK (1 << 12)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_PER24MC_GFCLK_MASK (1 << 8)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_MASK (1 << 9)
+
+/* Used by CM_L3INIT_USBPHYOCP2SCP_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_PHY_48M_SHIFT 8
+#define OMAP4430_OPTFCLKEN_PHY_48M_MASK (1 << 8)
+
+/* Used by CM_L4PER_SLIMBUS2_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_MASK (1 << 10)
+
+/* Renamed from OPTFCLKEN_SLIMBUS_CLK Used by CM1_ABE_SLIMBUS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT 11
+#define OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_MASK (1 << 11)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_SYS_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_SYS_CLK_MASK (1 << 10)
+
+/* Used by CM_DSS_DSS_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_TV_CLK_SHIFT 11
+#define OMAP4430_OPTFCLKEN_TV_CLK_MASK (1 << 11)
+
+/* Used by CM_L3INIT_UNIPRO1_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_TXPHYCLK_MASK (1 << 8)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_USB_CH0_CLK_MASK (1 << 8)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_USB_CH1_CLK_MASK (1 << 9)
+
+/* Used by CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_USB_CH2_CLK_MASK (1 << 10)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_UTMI_P1_CLK_MASK (1 << 8)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_SHIFT 9
+#define OMAP4430_OPTFCLKEN_UTMI_P2_CLK_MASK (1 << 9)
+
+/* Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE */
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_SHIFT 10
+#define OMAP4430_OPTFCLKEN_UTMI_P3_CLK_MASK (1 << 10)
+
+/* Used by CM_L3INIT_USB_OTG_CLKCTRL */
+#define OMAP4430_OPTFCLKEN_XCLK_SHIFT 8
+#define OMAP4430_OPTFCLKEN_XCLK_MASK (1 << 8)
+
+/* Used by CM_EMU_OVERRIDE_DPLL_CORE */
+#define OMAP4430_OVERRIDE_ENABLE_SHIFT 19
+#define OMAP4430_OVERRIDE_ENABLE_MASK (1 << 19)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_PAD_CLKS_GATE_SHIFT 8
+#define OMAP4430_PAD_CLKS_GATE_MASK (1 << 8)
+
+/* Used by CM_CORE_DVFS_CURRENT, CM_IVA_DVFS_CURRENT */
+#define OMAP4430_PERF_CURRENT_SHIFT 0
+#define OMAP4430_PERF_CURRENT_MASK (0xff << 0)
+
+/*
+ * Used by CM_CORE_DVFS_PERF1, CM_CORE_DVFS_PERF2, CM_CORE_DVFS_PERF3,
+ * CM_CORE_DVFS_PERF4, CM_IVA_DVFS_PERF_ABE, CM_IVA_DVFS_PERF_IVAHD,
+ * CM_IVA_DVFS_PERF_TESLA
+ */
+#define OMAP4430_PERF_REQ_SHIFT 0
+#define OMAP4430_PERF_REQ_MASK (0xff << 0)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE1_COMPLETED_SHIFT 0
+#define OMAP4430_PHASE1_COMPLETED_MASK (1 << 0)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE2A_COMPLETED_SHIFT 1
+#define OMAP4430_PHASE2A_COMPLETED_MASK (1 << 1)
+
+/* Used by CM_RESTORE_ST */
+#define OMAP4430_PHASE2B_COMPLETED_SHIFT 2
+#define OMAP4430_PHASE2B_COMPLETED_MASK (1 << 2)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_PMD_STM_MUX_CTRL_SHIFT 20
+#define OMAP4430_PMD_STM_MUX_CTRL_MASK (0x3 << 20)
+
+/* Used by CM_EMU_DEBUGSS_CLKCTRL */
+#define OMAP4430_PMD_TRACE_MUX_CTRL_SHIFT 22
+#define OMAP4430_PMD_TRACE_MUX_CTRL_MASK (0x3 << 22)
+
+/* Used by CM_DYN_DEP_PRESCAL, CM_DYN_DEP_PRESCAL_RESTORE */
+#define OMAP4430_PRESCAL_SHIFT 0
+#define OMAP4430_PRESCAL_MASK (0x3f << 0)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_R_RTL_SHIFT 11
+#define OMAP4430_R_RTL_MASK (0x1f << 11)
+
+/*
+ * Used by CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
+ * CM_L3INIT_USB_TLL_CLKCTRL, CM_L3INIT_USB_TLL_CLKCTRL_RESTORE
+ */
+#define OMAP4430_SAR_MODE_SHIFT 4
+#define OMAP4430_SAR_MODE_MASK (1 << 4)
+
+/* Used by CM_SCALE_FCLK */
+#define OMAP4430_SCALE_FCLK_SHIFT 0
+#define OMAP4430_SCALE_FCLK_MASK (1 << 0)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_SCHEME_SHIFT 30
+#define OMAP4430_SCHEME_MASK (0x3 << 30)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
+#define OMAP4430_SDMA_DYNDEP_SHIFT 11
+#define OMAP4430_SDMA_DYNDEP_MASK (1 << 11)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_SDMA_STATDEP_SHIFT 11
+#define OMAP4430_SDMA_STATDEP_MASK (1 << 11)
+
+/* Used by CM_CLKSEL_ABE */
+#define OMAP4430_SLIMBUS_CLK_GATE_SHIFT 10
+#define OMAP4430_SLIMBUS_CLK_GATE_MASK (1 << 10)
+
+/*
+ * Used by CM1_ABE_AESS_CLKCTRL, CM_CAM_FDIF_CLKCTRL, CM_CAM_ISS_CLKCTRL,
+ * CM_D2D_SAD2D_CLKCTRL, CM_DSS_DEISS_CLKCTRL, CM_DSS_DSS_CLKCTRL,
+ * CM_DUCATI_DUCATI_CLKCTRL, CM_EMU_DEBUGSS_CLKCTRL, CM_GFX_GFX_CLKCTRL,
+ * CM_IVAHD_IVAHD_CLKCTRL, CM_L3INIT_CCPTX_CLKCTRL, CM_L3INIT_EMAC_CLKCTRL,
+ * CM_L3INIT_HSI_CLKCTRL, CM_L3INIT_MMC1_CLKCTRL, CM_L3INIT_MMC2_CLKCTRL,
+ * CM_L3INIT_MMC6_CLKCTRL, CM_L3INIT_P1500_CLKCTRL, CM_L3INIT_PCIESS_CLKCTRL,
+ * CM_L3INIT_SATA_CLKCTRL, CM_L3INIT_TPPSS_CLKCTRL, CM_L3INIT_UNIPRO1_CLKCTRL,
+ * CM_L3INIT_USB_HOST_CLKCTRL, CM_L3INIT_USB_HOST_CLKCTRL_RESTORE,
+ * CM_L3INIT_USB_HOST_FS_CLKCTRL, CM_L3INIT_USB_OTG_CLKCTRL,
+ * CM_L3INIT_XHPI_CLKCTRL, CM_L4SEC_CRYPTODMA_CLKCTRL, CM_MPU_MPU_CLKCTRL,
+ * CM_SDMA_SDMA_CLKCTRL, CM_TESLA_TESLA_CLKCTRL
+ */
+#define OMAP4430_STBYST_SHIFT 18
+#define OMAP4430_STBYST_MASK (1 << 18)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
+ * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER,
+ * CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
+ */
+#define OMAP4430_ST_DPLL_CLK_SHIFT 0
+#define OMAP4430_ST_DPLL_CLK_MASK (1 << 0)
+
+/* Used by CM_CLKDCOLDO_DPLL_USB */
+#define OMAP4430_ST_DPLL_CLKDCOLDO_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKDCOLDO_MASK (1 << 9)
+
+/*
+ * Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_CORE,
+ * CM_DIV_M2_DPLL_CORE_RESTORE, CM_DIV_M2_DPLL_DDRPHY, CM_DIV_M2_DPLL_MPU,
+ * CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_USB
+ */
+#define OMAP4430_ST_DPLL_CLKOUT_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKOUT_MASK (1 << 9)
+
+/*
+ * Used by CM_DIV_M3_DPLL_ABE, CM_DIV_M3_DPLL_CORE,
+ * CM_DIV_M3_DPLL_CORE_RESTORE, CM_DIV_M3_DPLL_PER
+ */
+#define OMAP4430_ST_DPLL_CLKOUTHIF_SHIFT 9
+#define OMAP4430_ST_DPLL_CLKOUTHIF_MASK (1 << 9)
+
+/* Used by CM_DIV_M2_DPLL_ABE, CM_DIV_M2_DPLL_PER, CM_DIV_M2_DPLL_UNIPRO */
+#define OMAP4430_ST_DPLL_CLKOUTX2_SHIFT 11
+#define OMAP4430_ST_DPLL_CLKOUTX2_MASK (1 << 11)
+
+/*
+ * Used by CM_DIV_M4_DPLL_CORE, CM_DIV_M4_DPLL_CORE_RESTORE,
+ * CM_DIV_M4_DPLL_DDRPHY, CM_DIV_M4_DPLL_IVA, CM_DIV_M4_DPLL_PER
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT1_MASK (1 << 9)
+
+/*
+ * Used by CM_DIV_M5_DPLL_CORE, CM_DIV_M5_DPLL_CORE_RESTORE,
+ * CM_DIV_M5_DPLL_DDRPHY, CM_DIV_M5_DPLL_IVA, CM_DIV_M5_DPLL_PER
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT2_MASK (1 << 9)
+
+/*
+ * Used by CM_DIV_M6_DPLL_CORE, CM_DIV_M6_DPLL_CORE_RESTORE,
+ * CM_DIV_M6_DPLL_DDRPHY, CM_DIV_M6_DPLL_PER
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT3_MASK (1 << 9)
+
+/*
+ * Used by CM_DIV_M7_DPLL_CORE, CM_DIV_M7_DPLL_CORE_RESTORE,
+ * CM_DIV_M7_DPLL_PER
+ */
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_SHIFT 9
+#define OMAP4430_ST_HSDIVIDER_CLKOUT4_MASK (1 << 9)
+
+/*
+ * Used by CM_IDLEST_DPLL_ABE, CM_IDLEST_DPLL_CORE, CM_IDLEST_DPLL_DDRPHY,
+ * CM_IDLEST_DPLL_IVA, CM_IDLEST_DPLL_MPU, CM_IDLEST_DPLL_PER,
+ * CM_IDLEST_DPLL_UNIPRO, CM_IDLEST_DPLL_USB
+ */
+#define OMAP4430_ST_MN_BYPASS_SHIFT 8
+#define OMAP4430_ST_MN_BYPASS_MASK (1 << 8)
+
+/* Used by CM_SYS_CLKSEL */
+#define OMAP4430_SYS_CLKSEL_SHIFT 0
+#define OMAP4430_SYS_CLKSEL_MASK (0x7 << 0)
+
+/* Used by CM_L4CFG_DYNAMICDEP, CM_L4CFG_DYNAMICDEP_RESTORE */
+#define OMAP4430_TESLA_DYNDEP_SHIFT 1
+#define OMAP4430_TESLA_DYNDEP_MASK (1 << 1)
+
+/* Used by CM_DUCATI_STATICDEP, CM_MPU_STATICDEP */
+#define OMAP4430_TESLA_STATDEP_SHIFT 1
+#define OMAP4430_TESLA_STATDEP_MASK (1 << 1)
+
+/*
+ * Used by CM_D2D_DYNAMICDEP, CM_D2D_DYNAMICDEP_RESTORE, CM_DUCATI_DYNAMICDEP,
+ * CM_EMU_DYNAMICDEP, CM_L3_1_DYNAMICDEP, CM_L3_1_DYNAMICDEP_RESTORE,
+ * CM_L3_2_DYNAMICDEP, CM_L3_2_DYNAMICDEP_RESTORE, CM_L4CFG_DYNAMICDEP,
+ * CM_L4CFG_DYNAMICDEP_RESTORE, CM_L4PER_DYNAMICDEP,
+ * CM_L4PER_DYNAMICDEP_RESTORE, CM_MPU_DYNAMICDEP, CM_TESLA_DYNAMICDEP
+ */
+#define OMAP4430_WINDOWSIZE_SHIFT 24
+#define OMAP4430_WINDOWSIZE_MASK (0xf << 24)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_X_MAJOR_SHIFT 8
+#define OMAP4430_X_MAJOR_MASK (0x7 << 8)
+
+/* Used by REVISION_CM1, REVISION_CM2 */
+#define OMAP4430_Y_MINOR_SHIFT 0
+#define OMAP4430_Y_MINOR_MASK (0x3f << 0)
+#endif
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
new file mode 100644
index 00000000..a7bc096b
--- /dev/null
+++ b/arch/arm/mach-omap2/cm.h
@@ -0,0 +1,25 @@
+/*
+ * OMAP2+ Clock Management prototypes
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM_H
+#define __ARCH_ASM_MACH_OMAP2_CM_H
+
+/*
+ * MAX_MODULE_READY_TIME: max duration in microseconds to wait for the
+ * PRCM to request that a module exit the inactive state in the case of
+ * OMAP2 & 3.
+ * In the case of OMAP4 this is the max duration in microseconds for the
+ * module to reach the functionnal state from an inactive state.
+ */
+#define MAX_MODULE_READY_TIME 2000
+
+#endif
diff --git a/arch/arm/mach-omap2/cm1_44xx.h b/arch/arm/mach-omap2/cm1_44xx.h
new file mode 100644
index 00000000..e2d7a56b
--- /dev/null
+++ b/arch/arm/mach-omap2/cm1_44xx.h
@@ -0,0 +1,261 @@
+/*
+ * OMAP44xx CM1 instance offset macros
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM1_44XX_H
+
+/* CM1 base address */
+#define OMAP4430_CM1_BASE 0x4a004000
+
+#define OMAP44XX_CM1_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_CM1_BASE + (inst) + (reg))
+
+/* CM1 instances */
+#define OMAP4430_CM1_OCP_SOCKET_INST 0x0000
+#define OMAP4430_CM1_CKGEN_INST 0x0100
+#define OMAP4430_CM1_MPU_INST 0x0300
+#define OMAP4430_CM1_TESLA_INST 0x0400
+#define OMAP4430_CM1_ABE_INST 0x0500
+#define OMAP4430_CM1_RESTORE_INST 0x0e00
+#define OMAP4430_CM1_INSTR_INST 0x0f00
+
+/* CM1 clockdomain register offsets (from instance start) */
+#define OMAP4430_CM1_ABE_ABE_CDOFFS 0x0000
+#define OMAP4430_CM1_MPU_MPU_CDOFFS 0x0000
+#define OMAP4430_CM1_TESLA_TESLA_CDOFFS 0x0000
+
+/* CM1 */
+
+/* CM1.OCP_SOCKET_CM1 register offsets */
+#define OMAP4_REVISION_CM1_OFFSET 0x0000
+#define OMAP4430_REVISION_CM1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0000)
+#define OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_OCP_SOCKET_INST, 0x0040)
+
+/* CM1.CKGEN_CM1 register offsets */
+#define OMAP4_CM_CLKSEL_CORE_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0000)
+#define OMAP4_CM_CLKSEL_ABE_OFFSET 0x0008
+#define OMAP4430_CM_CLKSEL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0008)
+#define OMAP4_CM_DLL_CTRL_OFFSET 0x0010
+#define OMAP4430_CM_DLL_CTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0010)
+#define OMAP4_CM_CLKMODE_DPLL_CORE_OFFSET 0x0020
+#define OMAP4430_CM_CLKMODE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0020)
+#define OMAP4_CM_IDLEST_DPLL_CORE_OFFSET 0x0024
+#define OMAP4430_CM_IDLEST_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0024)
+#define OMAP4_CM_AUTOIDLE_DPLL_CORE_OFFSET 0x0028
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0028)
+#define OMAP4_CM_CLKSEL_DPLL_CORE_OFFSET 0x002c
+#define OMAP4430_CM_CLKSEL_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x002c)
+#define OMAP4_CM_DIV_M2_DPLL_CORE_OFFSET 0x0030
+#define OMAP4430_CM_DIV_M2_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0030)
+#define OMAP4_CM_DIV_M3_DPLL_CORE_OFFSET 0x0034
+#define OMAP4430_CM_DIV_M3_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0034)
+#define OMAP4_CM_DIV_M4_DPLL_CORE_OFFSET 0x0038
+#define OMAP4430_CM_DIV_M4_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0038)
+#define OMAP4_CM_DIV_M5_DPLL_CORE_OFFSET 0x003c
+#define OMAP4430_CM_DIV_M5_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x003c)
+#define OMAP4_CM_DIV_M6_DPLL_CORE_OFFSET 0x0040
+#define OMAP4430_CM_DIV_M6_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0040)
+#define OMAP4_CM_DIV_M7_DPLL_CORE_OFFSET 0x0044
+#define OMAP4430_CM_DIV_M7_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0044)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_OFFSET 0x0048
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0048)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_OFFSET 0x004c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x004c)
+#define OMAP4_CM_EMU_OVERRIDE_DPLL_CORE_OFFSET 0x0050
+#define OMAP4430_CM_EMU_OVERRIDE_DPLL_CORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0050)
+#define OMAP4_CM_CLKMODE_DPLL_MPU_OFFSET 0x0060
+#define OMAP4430_CM_CLKMODE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0060)
+#define OMAP4_CM_IDLEST_DPLL_MPU_OFFSET 0x0064
+#define OMAP4430_CM_IDLEST_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0064)
+#define OMAP4_CM_AUTOIDLE_DPLL_MPU_OFFSET 0x0068
+#define OMAP4430_CM_AUTOIDLE_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0068)
+#define OMAP4_CM_CLKSEL_DPLL_MPU_OFFSET 0x006c
+#define OMAP4430_CM_CLKSEL_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x006c)
+#define OMAP4_CM_DIV_M2_DPLL_MPU_OFFSET 0x0070
+#define OMAP4430_CM_DIV_M2_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0070)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_MPU_OFFSET 0x0088
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0088)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_MPU_OFFSET 0x008c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x008c)
+#define OMAP4_CM_BYPCLK_DPLL_MPU_OFFSET 0x009c
+#define OMAP4430_CM_BYPCLK_DPLL_MPU OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x009c)
+#define OMAP4_CM_CLKMODE_DPLL_IVA_OFFSET 0x00a0
+#define OMAP4430_CM_CLKMODE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a0)
+#define OMAP4_CM_IDLEST_DPLL_IVA_OFFSET 0x00a4
+#define OMAP4430_CM_IDLEST_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a4)
+#define OMAP4_CM_AUTOIDLE_DPLL_IVA_OFFSET 0x00a8
+#define OMAP4430_CM_AUTOIDLE_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00a8)
+#define OMAP4_CM_CLKSEL_DPLL_IVA_OFFSET 0x00ac
+#define OMAP4430_CM_CLKSEL_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ac)
+#define OMAP4_CM_DIV_M4_DPLL_IVA_OFFSET 0x00b8
+#define OMAP4430_CM_DIV_M4_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00b8)
+#define OMAP4_CM_DIV_M5_DPLL_IVA_OFFSET 0x00bc
+#define OMAP4430_CM_DIV_M5_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00bc)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_IVA_OFFSET 0x00c8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00c8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_IVA_OFFSET 0x00cc
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00cc)
+#define OMAP4_CM_BYPCLK_DPLL_IVA_OFFSET 0x00dc
+#define OMAP4430_CM_BYPCLK_DPLL_IVA OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00dc)
+#define OMAP4_CM_CLKMODE_DPLL_ABE_OFFSET 0x00e0
+#define OMAP4430_CM_CLKMODE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e0)
+#define OMAP4_CM_IDLEST_DPLL_ABE_OFFSET 0x00e4
+#define OMAP4430_CM_IDLEST_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e4)
+#define OMAP4_CM_AUTOIDLE_DPLL_ABE_OFFSET 0x00e8
+#define OMAP4430_CM_AUTOIDLE_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00e8)
+#define OMAP4_CM_CLKSEL_DPLL_ABE_OFFSET 0x00ec
+#define OMAP4430_CM_CLKSEL_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00ec)
+#define OMAP4_CM_DIV_M2_DPLL_ABE_OFFSET 0x00f0
+#define OMAP4430_CM_DIV_M2_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f0)
+#define OMAP4_CM_DIV_M3_DPLL_ABE_OFFSET 0x00f4
+#define OMAP4430_CM_DIV_M3_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x00f4)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_ABE_OFFSET 0x0108
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0108)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_ABE_OFFSET 0x010c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_ABE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x010c)
+#define OMAP4_CM_CLKMODE_DPLL_DDRPHY_OFFSET 0x0120
+#define OMAP4430_CM_CLKMODE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0120)
+#define OMAP4_CM_IDLEST_DPLL_DDRPHY_OFFSET 0x0124
+#define OMAP4430_CM_IDLEST_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0124)
+#define OMAP4_CM_AUTOIDLE_DPLL_DDRPHY_OFFSET 0x0128
+#define OMAP4430_CM_AUTOIDLE_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0128)
+#define OMAP4_CM_CLKSEL_DPLL_DDRPHY_OFFSET 0x012c
+#define OMAP4430_CM_CLKSEL_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x012c)
+#define OMAP4_CM_DIV_M2_DPLL_DDRPHY_OFFSET 0x0130
+#define OMAP4430_CM_DIV_M2_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0130)
+#define OMAP4_CM_DIV_M4_DPLL_DDRPHY_OFFSET 0x0138
+#define OMAP4430_CM_DIV_M4_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0138)
+#define OMAP4_CM_DIV_M5_DPLL_DDRPHY_OFFSET 0x013c
+#define OMAP4430_CM_DIV_M5_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x013c)
+#define OMAP4_CM_DIV_M6_DPLL_DDRPHY_OFFSET 0x0140
+#define OMAP4430_CM_DIV_M6_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0140)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_DDRPHY_OFFSET 0x0148
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0148)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_DDRPHY_OFFSET 0x014c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_DDRPHY OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x014c)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG1_OFFSET 0x0160
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0160)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG2_OFFSET 0x0164
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2 OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0164)
+#define OMAP4_CM_DYN_DEP_PRESCAL_OFFSET 0x0170
+#define OMAP4430_CM_DYN_DEP_PRESCAL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0170)
+#define OMAP4_CM_RESTORE_ST_OFFSET 0x0180
+#define OMAP4430_CM_RESTORE_ST OMAP44XX_CM1_REGADDR(OMAP4430_CM1_CKGEN_INST, 0x0180)
+
+/* CM1.MPU_CM1 register offsets */
+#define OMAP4_CM_MPU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_MPU_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0000)
+#define OMAP4_CM_MPU_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_MPU_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0004)
+#define OMAP4_CM_MPU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_MPU_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0008)
+#define OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_MPU_MPU_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_MPU_INST, 0x0020)
+
+/* CM1.TESLA_CM1 register offsets */
+#define OMAP4_CM_TESLA_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_TESLA_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0000)
+#define OMAP4_CM_TESLA_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_TESLA_STATICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0004)
+#define OMAP4_CM_TESLA_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_TESLA_DYNAMICDEP OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0008)
+#define OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_TESLA_TESLA_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_TESLA_INST, 0x0020)
+
+/* CM1.ABE_CM1 register offsets */
+#define OMAP4_CM1_ABE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM1_ABE_CLKSTCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0000)
+#define OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM1_ABE_L4ABE_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0020)
+#define OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM1_ABE_AESS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0028)
+#define OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM1_ABE_PDM_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0030)
+#define OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM1_ABE_DMIC_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0038)
+#define OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM1_ABE_MCASP_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0040)
+#define OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET 0x0048
+#define OMAP4430_CM1_ABE_MCBSP1_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0048)
+#define OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET 0x0050
+#define OMAP4430_CM1_ABE_MCBSP2_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0050)
+#define OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM1_ABE_MCBSP3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0058)
+#define OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0060)
+#define OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM1_ABE_TIMER5_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0068)
+#define OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET 0x0070
+#define OMAP4430_CM1_ABE_TIMER6_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0070)
+#define OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM1_ABE_TIMER7_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0078)
+#define OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM1_ABE_TIMER8_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0080)
+#define OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)
+
+/* CM1.RESTORE_CM1 register offsets */
+#define OMAP4_CM_CLKSEL_CORE_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0000)
+#define OMAP4_CM_DIV_M2_DPLL_CORE_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_DIV_M2_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0004)
+#define OMAP4_CM_DIV_M3_DPLL_CORE_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_DIV_M3_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0008)
+#define OMAP4_CM_DIV_M4_DPLL_CORE_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_DIV_M4_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x000c)
+#define OMAP4_CM_DIV_M5_DPLL_CORE_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_DIV_M5_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0010)
+#define OMAP4_CM_DIV_M6_DPLL_CORE_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_DIV_M6_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0014)
+#define OMAP4_CM_DIV_M7_DPLL_CORE_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_DIV_M7_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0018)
+#define OMAP4_CM_CLKSEL_DPLL_CORE_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_CLKSEL_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x001c)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0020)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0024)
+#define OMAP4_CM_CLKMODE_DPLL_CORE_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_CLKMODE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0028)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG2_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG2_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x002c)
+#define OMAP4_CM_SHADOW_FREQ_CONFIG1_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_SHADOW_FREQ_CONFIG1_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0030)
+#define OMAP4_CM_AUTOIDLE_DPLL_CORE_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_AUTOIDLE_DPLL_CORE_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0034)
+#define OMAP4_CM_MPU_CLKSTCTRL_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_MPU_CLKSTCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0038)
+#define OMAP4_CM_CM1_PROFILING_CLKCTRL_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_CM1_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x003c)
+#define OMAP4_CM_DYN_DEP_PRESCAL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_DYN_DEP_PRESCAL_RESTORE OMAP44XX_CM1_REGADDR(OMAP4430_CM1_RESTORE_INST, 0x0040)
+
+/* Function prototypes */
+extern u32 omap4_cm1_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm1_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2_44xx.h b/arch/arm/mach-omap2/cm2_44xx.h
new file mode 100644
index 00000000..aa474504
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2_44xx.h
@@ -0,0 +1,508 @@
+/*
+ * OMAP44xx CM2 instance offset macros
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM2_44XX_H
+
+/* CM2 base address */
+#define OMAP4430_CM2_BASE 0x4a008000
+
+#define OMAP44XX_CM2_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE + (inst) + (reg))
+
+/* CM2 instances */
+#define OMAP4430_CM2_OCP_SOCKET_INST 0x0000
+#define OMAP4430_CM2_CKGEN_INST 0x0100
+#define OMAP4430_CM2_ALWAYS_ON_INST 0x0600
+#define OMAP4430_CM2_CORE_INST 0x0700
+#define OMAP4430_CM2_IVAHD_INST 0x0f00
+#define OMAP4430_CM2_CAM_INST 0x1000
+#define OMAP4430_CM2_DSS_INST 0x1100
+#define OMAP4430_CM2_GFX_INST 0x1200
+#define OMAP4430_CM2_L3INIT_INST 0x1300
+#define OMAP4430_CM2_L4PER_INST 0x1400
+#define OMAP4430_CM2_CEFUSE_INST 0x1600
+#define OMAP4430_CM2_RESTORE_INST 0x1e00
+#define OMAP4430_CM2_INSTR_INST 0x1f00
+
+/* CM2 clockdomain register offsets (from instance start) */
+#define OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS 0x0000
+#define OMAP4430_CM2_CORE_L3_1_CDOFFS 0x0000
+#define OMAP4430_CM2_CORE_L3_2_CDOFFS 0x0100
+#define OMAP4430_CM2_CORE_DUCATI_CDOFFS 0x0200
+#define OMAP4430_CM2_CORE_SDMA_CDOFFS 0x0300
+#define OMAP4430_CM2_CORE_MEMIF_CDOFFS 0x0400
+#define OMAP4430_CM2_CORE_D2D_CDOFFS 0x0500
+#define OMAP4430_CM2_CORE_L4CFG_CDOFFS 0x0600
+#define OMAP4430_CM2_CORE_L3INSTR_CDOFFS 0x0700
+#define OMAP4430_CM2_IVAHD_IVAHD_CDOFFS 0x0000
+#define OMAP4430_CM2_CAM_CAM_CDOFFS 0x0000
+#define OMAP4430_CM2_DSS_DSS_CDOFFS 0x0000
+#define OMAP4430_CM2_GFX_GFX_CDOFFS 0x0000
+#define OMAP4430_CM2_L3INIT_L3INIT_CDOFFS 0x0000
+#define OMAP4430_CM2_L4PER_L4PER_CDOFFS 0x0000
+#define OMAP4430_CM2_L4PER_L4SEC_CDOFFS 0x0180
+#define OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS 0x0000
+
+
+/* CM2 */
+
+/* CM2.OCP_SOCKET_CM2 register offsets */
+#define OMAP4_REVISION_CM2_OFFSET 0x0000
+#define OMAP4430_REVISION_CM2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0000)
+#define OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_OCP_SOCKET_INST, 0x0040)
+
+/* CM2.CKGEN_CM2 register offsets */
+#define OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET 0x0000
+#define OMAP4430_CM_CLKSEL_DUCATI_ISS_ROOT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0000)
+#define OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET 0x0004
+#define OMAP4430_CM_CLKSEL_USB_60MHZ OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0004)
+#define OMAP4_CM_SCALE_FCLK_OFFSET 0x0008
+#define OMAP4430_CM_SCALE_FCLK OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0008)
+#define OMAP4_CM_CORE_DVFS_PERF1_OFFSET 0x0010
+#define OMAP4430_CM_CORE_DVFS_PERF1 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0010)
+#define OMAP4_CM_CORE_DVFS_PERF2_OFFSET 0x0014
+#define OMAP4430_CM_CORE_DVFS_PERF2 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0014)
+#define OMAP4_CM_CORE_DVFS_PERF3_OFFSET 0x0018
+#define OMAP4430_CM_CORE_DVFS_PERF3 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0018)
+#define OMAP4_CM_CORE_DVFS_PERF4_OFFSET 0x001c
+#define OMAP4430_CM_CORE_DVFS_PERF4 OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x001c)
+#define OMAP4_CM_CORE_DVFS_CURRENT_OFFSET 0x0024
+#define OMAP4430_CM_CORE_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0024)
+#define OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET 0x0028
+#define OMAP4430_CM_IVA_DVFS_PERF_TESLA OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0028)
+#define OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET 0x002c
+#define OMAP4430_CM_IVA_DVFS_PERF_IVAHD OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x002c)
+#define OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET 0x0030
+#define OMAP4430_CM_IVA_DVFS_PERF_ABE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0030)
+#define OMAP4_CM_IVA_DVFS_CURRENT_OFFSET 0x0038
+#define OMAP4430_CM_IVA_DVFS_CURRENT OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0038)
+#define OMAP4_CM_CLKMODE_DPLL_PER_OFFSET 0x0040
+#define OMAP4430_CM_CLKMODE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0040)
+#define OMAP4_CM_IDLEST_DPLL_PER_OFFSET 0x0044
+#define OMAP4430_CM_IDLEST_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0044)
+#define OMAP4_CM_AUTOIDLE_DPLL_PER_OFFSET 0x0048
+#define OMAP4430_CM_AUTOIDLE_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0048)
+#define OMAP4_CM_CLKSEL_DPLL_PER_OFFSET 0x004c
+#define OMAP4430_CM_CLKSEL_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x004c)
+#define OMAP4_CM_DIV_M2_DPLL_PER_OFFSET 0x0050
+#define OMAP4430_CM_DIV_M2_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0050)
+#define OMAP4_CM_DIV_M3_DPLL_PER_OFFSET 0x0054
+#define OMAP4430_CM_DIV_M3_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0054)
+#define OMAP4_CM_DIV_M4_DPLL_PER_OFFSET 0x0058
+#define OMAP4430_CM_DIV_M4_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0058)
+#define OMAP4_CM_DIV_M5_DPLL_PER_OFFSET 0x005c
+#define OMAP4430_CM_DIV_M5_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x005c)
+#define OMAP4_CM_DIV_M6_DPLL_PER_OFFSET 0x0060
+#define OMAP4430_CM_DIV_M6_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0060)
+#define OMAP4_CM_DIV_M7_DPLL_PER_OFFSET 0x0064
+#define OMAP4430_CM_DIV_M7_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0064)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_PER_OFFSET 0x0068
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0068)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_PER_OFFSET 0x006c
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_PER OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x006c)
+#define OMAP4_CM_CLKMODE_DPLL_USB_OFFSET 0x0080
+#define OMAP4430_CM_CLKMODE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0080)
+#define OMAP4_CM_IDLEST_DPLL_USB_OFFSET 0x0084
+#define OMAP4430_CM_IDLEST_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0084)
+#define OMAP4_CM_AUTOIDLE_DPLL_USB_OFFSET 0x0088
+#define OMAP4430_CM_AUTOIDLE_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0088)
+#define OMAP4_CM_CLKSEL_DPLL_USB_OFFSET 0x008c
+#define OMAP4430_CM_CLKSEL_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x008c)
+#define OMAP4_CM_DIV_M2_DPLL_USB_OFFSET 0x0090
+#define OMAP4430_CM_DIV_M2_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x0090)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_USB_OFFSET 0x00a8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00a8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_USB_OFFSET 0x00ac
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ac)
+#define OMAP4_CM_CLKDCOLDO_DPLL_USB_OFFSET 0x00b4
+#define OMAP4430_CM_CLKDCOLDO_DPLL_USB OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00b4)
+#define OMAP4_CM_CLKMODE_DPLL_UNIPRO_OFFSET 0x00c0
+#define OMAP4430_CM_CLKMODE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c0)
+#define OMAP4_CM_IDLEST_DPLL_UNIPRO_OFFSET 0x00c4
+#define OMAP4430_CM_IDLEST_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c4)
+#define OMAP4_CM_AUTOIDLE_DPLL_UNIPRO_OFFSET 0x00c8
+#define OMAP4430_CM_AUTOIDLE_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00c8)
+#define OMAP4_CM_CLKSEL_DPLL_UNIPRO_OFFSET 0x00cc
+#define OMAP4430_CM_CLKSEL_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00cc)
+#define OMAP4_CM_DIV_M2_DPLL_UNIPRO_OFFSET 0x00d0
+#define OMAP4430_CM_DIV_M2_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00d0)
+#define OMAP4_CM_SSC_DELTAMSTEP_DPLL_UNIPRO_OFFSET 0x00e8
+#define OMAP4430_CM_SSC_DELTAMSTEP_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00e8)
+#define OMAP4_CM_SSC_INSTFREQDIV_DPLL_UNIPRO_OFFSET 0x00ec
+#define OMAP4430_CM_SSC_INSTFREQDIV_DPLL_UNIPRO OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CKGEN_INST, 0x00ec)
+
+/* CM2.ALWAYS_ON_CM2 register offsets */
+#define OMAP4_CM_ALWON_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_ALWON_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0000)
+#define OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_ALWON_MDMINTC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0020)
+#define OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_ALWON_SR_MPU_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0028)
+#define OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_ALWON_SR_IVA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0030)
+#define OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_ALWON_SR_CORE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0038)
+#define OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_ALWON_USBPHY_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_ALWAYS_ON_INST, 0x0040)
+
+/* CM2.CORE_CM2 register offsets */
+#define OMAP4_CM_L3_1_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L3_1_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0000)
+#define OMAP4_CM_L3_1_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L3_1_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0008)
+#define OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_L3_1_L3_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0020)
+#define OMAP4_CM_L3_2_CLKSTCTRL_OFFSET 0x0100
+#define OMAP4430_CM_L3_2_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0100)
+#define OMAP4_CM_L3_2_DYNAMICDEP_OFFSET 0x0108
+#define OMAP4430_CM_L3_2_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0108)
+#define OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET 0x0120
+#define OMAP4430_CM_L3_2_L3_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0120)
+#define OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET 0x0128
+#define OMAP4430_CM_L3_2_GPMC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0128)
+#define OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET 0x0130
+#define OMAP4430_CM_L3_2_OCMC_RAM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0130)
+#define OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET 0x0200
+#define OMAP4430_CM_DUCATI_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0200)
+#define OMAP4_CM_DUCATI_STATICDEP_OFFSET 0x0204
+#define OMAP4430_CM_DUCATI_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0204)
+#define OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET 0x0208
+#define OMAP4430_CM_DUCATI_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0208)
+#define OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET 0x0220
+#define OMAP4430_CM_DUCATI_DUCATI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0220)
+#define OMAP4_CM_SDMA_CLKSTCTRL_OFFSET 0x0300
+#define OMAP4430_CM_SDMA_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0300)
+#define OMAP4_CM_SDMA_STATICDEP_OFFSET 0x0304
+#define OMAP4430_CM_SDMA_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0304)
+#define OMAP4_CM_SDMA_DYNAMICDEP_OFFSET 0x0308
+#define OMAP4430_CM_SDMA_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0308)
+#define OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET 0x0320
+#define OMAP4430_CM_SDMA_SDMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0320)
+#define OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET 0x0400
+#define OMAP4430_CM_MEMIF_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0400)
+#define OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET 0x0420
+#define OMAP4430_CM_MEMIF_DMM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0420)
+#define OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET 0x0428
+#define OMAP4430_CM_MEMIF_EMIF_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0428)
+#define OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET 0x0430
+#define OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0430)
+#define OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET 0x0438
+#define OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0438)
+#define OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET 0x0440
+#define OMAP4430_CM_MEMIF_DLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0440)
+#define OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET 0x0450
+#define OMAP4430_CM_MEMIF_EMIF_H1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0450)
+#define OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET 0x0458
+#define OMAP4430_CM_MEMIF_EMIF_H2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0458)
+#define OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET 0x0460
+#define OMAP4430_CM_MEMIF_DLL_H_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0460)
+#define OMAP4_CM_D2D_CLKSTCTRL_OFFSET 0x0500
+#define OMAP4430_CM_D2D_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0500)
+#define OMAP4_CM_D2D_STATICDEP_OFFSET 0x0504
+#define OMAP4430_CM_D2D_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0504)
+#define OMAP4_CM_D2D_DYNAMICDEP_OFFSET 0x0508
+#define OMAP4430_CM_D2D_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0508)
+#define OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET 0x0520
+#define OMAP4430_CM_D2D_SAD2D_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0520)
+#define OMAP4_CM_D2D_INSTEM_ICR_CLKCTRL_OFFSET 0x0528
+#define OMAP4430_CM_D2D_INSTEM_ICR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0528)
+#define OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET 0x0530
+#define OMAP4430_CM_D2D_SAD2D_FW_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0530)
+#define OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET 0x0600
+#define OMAP4430_CM_L4CFG_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0600)
+#define OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET 0x0608
+#define OMAP4430_CM_L4CFG_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0608)
+#define OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET 0x0620
+#define OMAP4430_CM_L4CFG_L4_CFG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0620)
+#define OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET 0x0628
+#define OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0628)
+#define OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET 0x0630
+#define OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0630)
+#define OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET 0x0638
+#define OMAP4430_CM_L4CFG_SAR_ROM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0638)
+#define OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET 0x0700
+#define OMAP4430_CM_L3INSTR_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0700)
+#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET 0x0720
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0720)
+#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET 0x0728
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0728)
+#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET 0x0740
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CORE_INST, 0x0740)
+
+/* CM2.IVAHD_CM2 register offsets */
+#define OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_IVAHD_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0000)
+#define OMAP4_CM_IVAHD_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_IVAHD_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0004)
+#define OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_IVAHD_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0008)
+#define OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_IVAHD_IVAHD_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0020)
+#define OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_IVAHD_SL2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_IVAHD_INST, 0x0028)
+
+/* CM2.CAM_CM2 register offsets */
+#define OMAP4_CM_CAM_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_CAM_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0000)
+#define OMAP4_CM_CAM_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_CAM_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0004)
+#define OMAP4_CM_CAM_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_CAM_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0008)
+#define OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_CAM_ISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0020)
+#define OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_CAM_FDIF_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CAM_INST, 0x0028)
+
+/* CM2.DSS_CM2 register offsets */
+#define OMAP4_CM_DSS_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_DSS_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0000)
+#define OMAP4_CM_DSS_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_DSS_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0004)
+#define OMAP4_CM_DSS_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_DSS_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0008)
+#define OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_DSS_DSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0020)
+#define OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_DSS_DEISS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_DSS_INST, 0x0028)
+
+/* CM2.GFX_CM2 register offsets */
+#define OMAP4_CM_GFX_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_GFX_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0000)
+#define OMAP4_CM_GFX_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_GFX_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0004)
+#define OMAP4_CM_GFX_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_GFX_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0008)
+#define OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_GFX_GFX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_GFX_INST, 0x0020)
+
+/* CM2.L3INIT_CM2 register offsets */
+#define OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L3INIT_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0000)
+#define OMAP4_CM_L3INIT_STATICDEP_OFFSET 0x0004
+#define OMAP4430_CM_L3INIT_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0004)
+#define OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L3INIT_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0008)
+#define OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_L3INIT_MMC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0028)
+#define OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_L3INIT_MMC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0030)
+#define OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_L3INIT_HSI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0038)
+#define OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_L3INIT_UNIPRO1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0040)
+#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0058)
+#define OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0060)
+#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0068)
+#define OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM_L3INIT_P1500_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0078)
+#define OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM_L3INIT_EMAC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0080)
+#define OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM_L3INIT_SATA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0088)
+#define OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET 0x0090
+#define OMAP4430_CM_L3INIT_TPPSS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0090)
+#define OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET 0x0098
+#define OMAP4430_CM_L3INIT_PCIESS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x0098)
+#define OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET 0x00a8
+#define OMAP4430_CM_L3INIT_CCPTX_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00a8)
+#define OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET 0x00c0
+#define OMAP4430_CM_L3INIT_XHPI_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c0)
+#define OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET 0x00c8
+#define OMAP4430_CM_L3INIT_MMC6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00c8)
+#define OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET 0x00d0
+#define OMAP4430_CM_L3INIT_USB_HOST_FS_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00d0)
+#define OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET 0x00e0
+#define OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L3INIT_INST, 0x00e0)
+
+/* CM2.L4PER_CM2 register offsets */
+#define OMAP4_CM_L4PER_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_L4PER_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0000)
+#define OMAP4_CM_L4PER_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_L4PER_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0008)
+#define OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_L4PER_ADC_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0020)
+#define OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0028)
+#define OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0030)
+#define OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0038)
+#define OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0040)
+#define OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET 0x0048
+#define OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0048)
+#define OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET 0x0050
+#define OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0050)
+#define OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM_L4PER_ELM_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0058)
+#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0060)
+#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET 0x0068
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0068)
+#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET 0x0070
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0070)
+#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0078)
+#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0080)
+#define OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM_L4PER_HDQ1W_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0088)
+#define OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET 0x0090
+#define OMAP4430_CM_L4PER_HECC1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0090)
+#define OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET 0x0098
+#define OMAP4430_CM_L4PER_HECC2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0098)
+#define OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET 0x00a0
+#define OMAP4430_CM_L4PER_I2C1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a0)
+#define OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET 0x00a8
+#define OMAP4430_CM_L4PER_I2C2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00a8)
+#define OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET 0x00b0
+#define OMAP4430_CM_L4PER_I2C3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b0)
+#define OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET 0x00b8
+#define OMAP4430_CM_L4PER_I2C4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00b8)
+#define OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET 0x00c0
+#define OMAP4430_CM_L4PER_L4PER_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00c0)
+#define OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET 0x00d0
+#define OMAP4430_CM_L4PER_MCASP2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d0)
+#define OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET 0x00d8
+#define OMAP4430_CM_L4PER_MCASP3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00d8)
+#define OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET 0x00e0
+#define OMAP4430_CM_L4PER_MCBSP4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e0)
+#define OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET 0x00e8
+#define OMAP4430_CM_L4PER_MGATE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00e8)
+#define OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET 0x00f0
+#define OMAP4430_CM_L4PER_MCSPI1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f0)
+#define OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET 0x00f8
+#define OMAP4430_CM_L4PER_MCSPI2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x00f8)
+#define OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET 0x0100
+#define OMAP4430_CM_L4PER_MCSPI3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0100)
+#define OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET 0x0108
+#define OMAP4430_CM_L4PER_MCSPI4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0108)
+#define OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET 0x0120
+#define OMAP4430_CM_L4PER_MMCSD3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0120)
+#define OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET 0x0128
+#define OMAP4430_CM_L4PER_MMCSD4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0128)
+#define OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET 0x0130
+#define OMAP4430_CM_L4PER_MSPROHG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0130)
+#define OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET 0x0138
+#define OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0138)
+#define OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET 0x0140
+#define OMAP4430_CM_L4PER_UART1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0140)
+#define OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET 0x0148
+#define OMAP4430_CM_L4PER_UART2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0148)
+#define OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET 0x0150
+#define OMAP4430_CM_L4PER_UART3_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0150)
+#define OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET 0x0158
+#define OMAP4430_CM_L4PER_UART4_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0158)
+#define OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET 0x0160
+#define OMAP4430_CM_L4PER_MMCSD5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0160)
+#define OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET 0x0168
+#define OMAP4430_CM_L4PER_I2C5_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0168)
+#define OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET 0x0180
+#define OMAP4430_CM_L4SEC_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0180)
+#define OMAP4_CM_L4SEC_STATICDEP_OFFSET 0x0184
+#define OMAP4430_CM_L4SEC_STATICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0184)
+#define OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET 0x0188
+#define OMAP4430_CM_L4SEC_DYNAMICDEP OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x0188)
+#define OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET 0x01a0
+#define OMAP4430_CM_L4SEC_AES1_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a0)
+#define OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET 0x01a8
+#define OMAP4430_CM_L4SEC_AES2_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01a8)
+#define OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET 0x01b0
+#define OMAP4430_CM_L4SEC_DES3DES_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b0)
+#define OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET 0x01b8
+#define OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01b8)
+#define OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET 0x01c0
+#define OMAP4430_CM_L4SEC_RNG_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c0)
+#define OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET 0x01c8
+#define OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01c8)
+#define OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET 0x01d8
+#define OMAP4430_CM_L4SEC_CRYPTODMA_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_L4PER_INST, 0x01d8)
+
+/* CM2.CEFUSE_CM2 register offsets */
+#define OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_CEFUSE_CLKSTCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0000)
+#define OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)
+
+/* CM2.RESTORE_CM2 register offsets */
+#define OMAP4_CM_L3_1_CLKSTCTRL_RESTORE_OFFSET 0x0000
+#define OMAP4430_CM_L3_1_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0000)
+#define OMAP4_CM_L3_2_CLKSTCTRL_RESTORE_OFFSET 0x0004
+#define OMAP4430_CM_L3_2_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0004)
+#define OMAP4_CM_L4CFG_CLKSTCTRL_RESTORE_OFFSET 0x0008
+#define OMAP4430_CM_L4CFG_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0008)
+#define OMAP4_CM_MEMIF_CLKSTCTRL_RESTORE_OFFSET 0x000c
+#define OMAP4430_CM_MEMIF_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x000c)
+#define OMAP4_CM_L4PER_CLKSTCTRL_RESTORE_OFFSET 0x0010
+#define OMAP4430_CM_L4PER_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0010)
+#define OMAP4_CM_L3INIT_CLKSTCTRL_RESTORE_OFFSET 0x0014
+#define OMAP4430_CM_L3INIT_CLKSTCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0014)
+#define OMAP4_CM_L3INSTR_L3_3_CLKCTRL_RESTORE_OFFSET 0x0018
+#define OMAP4430_CM_L3INSTR_L3_3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0018)
+#define OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE_OFFSET 0x001c
+#define OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x001c)
+#define OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE_OFFSET 0x0020
+#define OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0020)
+#define OMAP4_CM_CM2_PROFILING_CLKCTRL_RESTORE_OFFSET 0x0024
+#define OMAP4430_CM_CM2_PROFILING_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0024)
+#define OMAP4_CM_D2D_STATICDEP_RESTORE_OFFSET 0x0028
+#define OMAP4430_CM_D2D_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0028)
+#define OMAP4_CM_L3_1_DYNAMICDEP_RESTORE_OFFSET 0x002c
+#define OMAP4430_CM_L3_1_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x002c)
+#define OMAP4_CM_L3_2_DYNAMICDEP_RESTORE_OFFSET 0x0030
+#define OMAP4430_CM_L3_2_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0030)
+#define OMAP4_CM_D2D_DYNAMICDEP_RESTORE_OFFSET 0x0034
+#define OMAP4430_CM_D2D_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0034)
+#define OMAP4_CM_L4CFG_DYNAMICDEP_RESTORE_OFFSET 0x0038
+#define OMAP4430_CM_L4CFG_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0038)
+#define OMAP4_CM_L4PER_DYNAMICDEP_RESTORE_OFFSET 0x003c
+#define OMAP4430_CM_L4PER_DYNAMICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x003c)
+#define OMAP4_CM_L4PER_GPIO2_CLKCTRL_RESTORE_OFFSET 0x0040
+#define OMAP4430_CM_L4PER_GPIO2_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0040)
+#define OMAP4_CM_L4PER_GPIO3_CLKCTRL_RESTORE_OFFSET 0x0044
+#define OMAP4430_CM_L4PER_GPIO3_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0044)
+#define OMAP4_CM_L4PER_GPIO4_CLKCTRL_RESTORE_OFFSET 0x0048
+#define OMAP4430_CM_L4PER_GPIO4_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0048)
+#define OMAP4_CM_L4PER_GPIO5_CLKCTRL_RESTORE_OFFSET 0x004c
+#define OMAP4430_CM_L4PER_GPIO5_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x004c)
+#define OMAP4_CM_L4PER_GPIO6_CLKCTRL_RESTORE_OFFSET 0x0050
+#define OMAP4430_CM_L4PER_GPIO6_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0050)
+#define OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE_OFFSET 0x0054
+#define OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0054)
+#define OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE_OFFSET 0x0058
+#define OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x0058)
+#define OMAP4_CM_SDMA_STATICDEP_RESTORE_OFFSET 0x005c
+#define OMAP4430_CM_SDMA_STATICDEP_RESTORE OMAP44XX_CM2_REGADDR(OMAP4430_CM2_RESTORE_INST, 0x005c)
+
+/* Function prototypes */
+extern u32 omap4_cm2_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_cm2_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.c b/arch/arm/mach-omap2/cm2xxx_3xxx.c
new file mode 100644
index 00000000..38830d8d
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.c
@@ -0,0 +1,557 @@
+/*
+ * OMAP2/3 CM module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "cm-regbits-34xx.h"
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */
+#define DPLL_AUTOIDLE_DISABLE 0x0
+#define OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP 0x3
+
+/* CM_AUTOIDLE_PLL.AUTO_* bit values for APLLs (OMAP2xxx only) */
+#define OMAP2XXX_APLL_AUTOIDLE_DISABLE 0x0
+#define OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP 0x3
+
+static const u8 cm_idlest_offs[] = {
+ CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
+};
+
+u32 omap2_cm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(cm_base + module + idx);
+}
+
+void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, cm_base + module + idx);
+}
+
+/* Read-modify-write a register in a CM module. Caller must lock */
+u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_cm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+
+u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_cm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+/*
+ *
+ */
+
+static void _write_clktrctrl(u8 c, s16 module, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= ~mask;
+ v |= c << __ffs(mask);
+ omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
+}
+
+bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
+{
+ u32 v;
+ bool ret = 0;
+
+ BUG_ON(!cpu_is_omap24xx() && !cpu_is_omap34xx());
+
+ v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ if (cpu_is_omap24xx())
+ ret = (v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+ else
+ ret = (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
+
+ return ret;
+}
+
+void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP24XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
+}
+
+void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
+{
+ _write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
+}
+
+/*
+ * DPLL autoidle control
+ */
+
+static void _omap2xxx_set_dpll_autoidle(u8 m)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+ v &= ~OMAP24XX_AUTO_DPLL_MASK;
+ v |= m << OMAP24XX_AUTO_DPLL_SHIFT;
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_dpll_disable_autoidle(void)
+{
+ _omap2xxx_set_dpll_autoidle(OMAP2XXX_DPLL_AUTOIDLE_LOW_POWER_STOP);
+}
+
+void omap2xxx_cm_set_dpll_auto_low_power_stop(void)
+{
+ _omap2xxx_set_dpll_autoidle(DPLL_AUTOIDLE_DISABLE);
+}
+
+/*
+ * APLL autoidle control
+ */
+
+static void _omap2xxx_set_apll_autoidle(u8 m, u32 mask)
+{
+ u32 v;
+
+ v = omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+ v &= ~mask;
+ v |= m << __ffs(mask);
+ omap2_cm_write_mod_reg(v, PLL_MOD, CM_AUTOIDLE);
+}
+
+void omap2xxx_cm_set_apll54_disable_autoidle(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+ OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll54_auto_low_power_stop(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+ OMAP24XX_AUTO_54M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_disable_autoidle(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_LOW_POWER_STOP,
+ OMAP24XX_AUTO_96M_MASK);
+}
+
+void omap2xxx_cm_set_apll96_auto_low_power_stop(void)
+{
+ _omap2xxx_set_apll_autoidle(OMAP2XXX_APLL_AUTOIDLE_DISABLE,
+ OMAP24XX_AUTO_96M_MASK);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap2_cm_wait_idlest_ready - wait for a module to leave idle or standby
+ * @prcm_mod: PRCM module offset
+ * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
+ * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
+ *
+ * XXX document
+ */
+int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
+{
+ int ena = 0, i = 0;
+ u8 cm_idlest_reg;
+ u32 mask;
+
+ if (!idlest_id || (idlest_id > ARRAY_SIZE(cm_idlest_offs)))
+ return -EINVAL;
+
+ cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
+
+ mask = 1 << idlest_shift;
+
+ if (cpu_is_omap24xx())
+ ena = mask;
+ else if (cpu_is_omap34xx())
+ ena = 0;
+ else
+ BUG();
+
+ omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
+/*
+ * Context save/restore code - OMAP3 only
+ */
+#ifdef CONFIG_ARCH_OMAP3
+struct omap3_cm_regs {
+ u32 iva2_cm_clksel1;
+ u32 iva2_cm_clksel2;
+ u32 cm_sysconfig;
+ u32 sgx_cm_clksel;
+ u32 dss_cm_clksel;
+ u32 cam_cm_clksel;
+ u32 per_cm_clksel;
+ u32 emu_cm_clksel;
+ u32 emu_cm_clkstctrl;
+ u32 pll_cm_autoidle;
+ u32 pll_cm_autoidle2;
+ u32 pll_cm_clksel4;
+ u32 pll_cm_clksel5;
+ u32 pll_cm_clken2;
+ u32 cm_polctrl;
+ u32 iva2_cm_fclken;
+ u32 iva2_cm_clken_pll;
+ u32 core_cm_fclken1;
+ u32 core_cm_fclken3;
+ u32 sgx_cm_fclken;
+ u32 wkup_cm_fclken;
+ u32 dss_cm_fclken;
+ u32 cam_cm_fclken;
+ u32 per_cm_fclken;
+ u32 usbhost_cm_fclken;
+ u32 core_cm_iclken1;
+ u32 core_cm_iclken2;
+ u32 core_cm_iclken3;
+ u32 sgx_cm_iclken;
+ u32 wkup_cm_iclken;
+ u32 dss_cm_iclken;
+ u32 cam_cm_iclken;
+ u32 per_cm_iclken;
+ u32 usbhost_cm_iclken;
+ u32 iva2_cm_autoidle2;
+ u32 mpu_cm_autoidle2;
+ u32 iva2_cm_clkstctrl;
+ u32 mpu_cm_clkstctrl;
+ u32 core_cm_clkstctrl;
+ u32 sgx_cm_clkstctrl;
+ u32 dss_cm_clkstctrl;
+ u32 cam_cm_clkstctrl;
+ u32 per_cm_clkstctrl;
+ u32 neon_cm_clkstctrl;
+ u32 usbhost_cm_clkstctrl;
+ u32 core_cm_autoidle1;
+ u32 core_cm_autoidle2;
+ u32 core_cm_autoidle3;
+ u32 wkup_cm_autoidle;
+ u32 dss_cm_autoidle;
+ u32 cam_cm_autoidle;
+ u32 per_cm_autoidle;
+ u32 usbhost_cm_autoidle;
+ u32 sgx_cm_sleepdep;
+ u32 dss_cm_sleepdep;
+ u32 cam_cm_sleepdep;
+ u32 per_cm_sleepdep;
+ u32 usbhost_cm_sleepdep;
+ u32 cm_clkout_ctrl;
+};
+
+static struct omap3_cm_regs cm_context;
+
+void omap3_cm_save_context(void)
+{
+ cm_context.iva2_cm_clksel1 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
+ cm_context.iva2_cm_clksel2 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
+ cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
+ cm_context.sgx_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
+ cm_context.dss_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
+ cm_context.cam_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
+ cm_context.per_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
+ cm_context.emu_cm_clksel =
+ omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
+ cm_context.emu_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
+ /*
+ * As per erratum i671, ROM code does not respect the PER DPLL
+ * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+ * In this case, even though this register has been saved in
+ * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
+ * by ourselves. So, we need to save it anyway.
+ */
+ cm_context.pll_cm_autoidle =
+ omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
+ cm_context.pll_cm_autoidle2 =
+ omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
+ cm_context.pll_cm_clksel4 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
+ cm_context.pll_cm_clksel5 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
+ cm_context.pll_cm_clken2 =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
+ cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
+ cm_context.iva2_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
+ cm_context.iva2_cm_clken_pll =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
+ cm_context.core_cm_fclken1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ cm_context.core_cm_fclken3 =
+ omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
+ cm_context.sgx_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
+ cm_context.wkup_cm_fclken =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
+ cm_context.dss_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
+ cm_context.cam_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
+ cm_context.per_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
+ cm_context.usbhost_cm_fclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ cm_context.core_cm_iclken1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
+ cm_context.core_cm_iclken2 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
+ cm_context.core_cm_iclken3 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
+ cm_context.sgx_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
+ cm_context.wkup_cm_iclken =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
+ cm_context.dss_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
+ cm_context.cam_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
+ cm_context.per_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
+ cm_context.usbhost_cm_iclken =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ cm_context.iva2_cm_autoidle2 =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
+ cm_context.mpu_cm_autoidle2 =
+ omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
+ cm_context.iva2_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.mpu_cm_clkstctrl =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_clkstctrl =
+ omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.sgx_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.dss_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.cam_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.per_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.neon_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
+ cm_context.usbhost_cm_clkstctrl =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ cm_context.core_cm_autoidle1 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
+ cm_context.core_cm_autoidle2 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
+ cm_context.core_cm_autoidle3 =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
+ cm_context.wkup_cm_autoidle =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
+ cm_context.dss_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
+ cm_context.cam_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
+ cm_context.per_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ cm_context.usbhost_cm_autoidle =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ cm_context.sgx_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_context.dss_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.cam_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.per_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
+ cm_context.usbhost_cm_sleepdep =
+ omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ cm_context.cm_clkout_ctrl =
+ omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
+ OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+
+void omap3_cm_restore_context(void)
+{
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
+ CM_CLKSEL1);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
+ CM_CLKSEL2);
+ __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
+ CM_CLKSEL);
+ omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
+ CM_CLKSEL1);
+ omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ /*
+ * As per erratum i671, ROM code does not respect the PER DPLL
+ * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
+ * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
+ */
+ omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL4);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
+ OMAP3430ES2_CM_CLKSEL5);
+ omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
+ OMAP3430ES2_CM_CLKEN2);
+ __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
+ OMAP3430_CM_CLKEN_PLL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
+ CM_FCLKEN1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
+ OMAP3430ES2_CM_FCLKEN3);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
+ CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
+ OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
+ CM_ICLKEN1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
+ CM_ICLKEN2);
+ omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
+ CM_ICLKEN3);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
+ CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
+ OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
+ OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
+ OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
+ CM_AUTOIDLE1);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
+ CM_AUTOIDLE2);
+ omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
+ CM_AUTOIDLE3);
+ omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
+ CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
+ OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
+ omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
+ OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
+ OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
+ omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
+ OMAP3_CM_CLKOUT_CTRL_OFFSET);
+}
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h
new file mode 100644
index 00000000..088bbad7
--- /dev/null
+++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h
@@ -0,0 +1,155 @@
+/*
+ * OMAP2/3 Clock Management (CM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The CM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The CM modules/instances on OMAP4 are quite different, so
+ * they are handled in a separate file.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
+#define __ARCH_ASM_MACH_OMAP2_CM2XXX_3XXX_H
+
+#include "prcm-common.h"
+
+#define OMAP2420_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
+#define OMAP2430_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE + (module) + (reg))
+#define OMAP34XX_CM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP3-specific global CM registers
+ * Use cm_{read,write}_reg() with these registers.
+ * These registers appear once per CM module.
+ */
+
+#define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
+#define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
+
+#define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific CM register offsets from CM_BASE + domain offset
+ * Use cm_{read,write}_mod_reg() with these registers.
+ * These register offsets generally appear in more than one PRCM submodule.
+ */
+
+/* Common between OMAP2 and OMAP3 */
+
+#define CM_FCLKEN 0x0000
+#define CM_FCLKEN1 CM_FCLKEN
+#define CM_CLKEN CM_FCLKEN
+#define CM_ICLKEN 0x0010
+#define CM_ICLKEN1 CM_ICLKEN
+#define CM_ICLKEN2 0x0014
+#define CM_ICLKEN3 0x0018
+#define CM_IDLEST 0x0020
+#define CM_IDLEST1 CM_IDLEST
+#define CM_IDLEST2 0x0024
+#define CM_AUTOIDLE 0x0030
+#define CM_AUTOIDLE1 CM_AUTOIDLE
+#define CM_AUTOIDLE2 0x0034
+#define CM_AUTOIDLE3 0x0038
+#define CM_CLKSEL 0x0040
+#define CM_CLKSEL1 CM_CLKSEL
+#define CM_CLKSEL2 0x0044
+#define OMAP2_CM_CLKSTCTRL 0x0048
+
+/* OMAP2-specific register offsets */
+
+#define OMAP24XX_CM_FCLKEN2 0x0004
+#define OMAP24XX_CM_ICLKEN4 0x001c
+#define OMAP24XX_CM_AUTOIDLE4 0x003c
+
+#define OMAP2430_CM_IDLEST3 0x0028
+
+/* OMAP3-specific register offsets */
+
+#define OMAP3430_CM_CLKEN_PLL 0x0004
+#define OMAP3430ES2_CM_CLKEN2 0x0004
+#define OMAP3430ES2_CM_FCLKEN3 0x0008
+#define OMAP3430_CM_IDLEST_PLL CM_IDLEST2
+#define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2
+#define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2
+#define OMAP3430_CM_CLKSEL1 CM_CLKSEL
+#define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL
+#define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2
+#define OMAP3430_CM_SLEEPDEP CM_CLKSEL2
+#define OMAP3430_CM_CLKSEL3 OMAP2_CM_CLKSTCTRL
+#define OMAP3430_CM_CLKSTST 0x004c
+#define OMAP3430ES2_CM_CLKSEL4 0x004c
+#define OMAP3430ES2_CM_CLKSEL5 0x0050
+#define OMAP3430_CM_CLKSEL2_EMU 0x0050
+#define OMAP3430_CM_CLKSEL3_EMU 0x0054
+
+
+/* CM_IDLEST bit field values to indicate deasserted IdleReq */
+
+#define OMAP24XX_CM_IDLEST_VAL 0
+#define OMAP34XX_CM_IDLEST_VAL 1
+
+
+/* Clock management domain register get/set */
+
+#ifndef __ASSEMBLER__
+
+extern u32 omap2_cm_read_mod_reg(s16 module, u16 idx);
+extern void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+
+extern int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id,
+ u8 idlest_shift);
+extern u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+
+extern bool omap2_cm_is_clkdm_in_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap2xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+
+extern void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask);
+extern void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask);
+
+extern void omap2xxx_cm_set_dpll_disable_autoidle(void);
+extern void omap2xxx_cm_set_dpll_auto_low_power_stop(void);
+
+extern void omap2xxx_cm_set_apll54_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll54_auto_low_power_stop(void);
+extern void omap2xxx_cm_set_apll96_disable_autoidle(void);
+extern void omap2xxx_cm_set_apll96_auto_low_power_stop(void);
+
+#endif
+
+/* CM register bits shared between 24XX and 3430 */
+
+/* CM_CLKSEL_GFX */
+#define OMAP_CLKSEL_GFX_SHIFT 0
+#define OMAP_CLKSEL_GFX_MASK (0x7 << 0)
+
+/* CM_ICLKEN_GFX */
+#define OMAP_EN_GFX_SHIFT 0
+#define OMAP_EN_GFX_MASK (1 << 0)
+
+/* CM_IDLEST_GFX */
+#define OMAP_ST_GFX_MASK (1 << 0)
+
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+extern void omap3_cm_save_context(void);
+extern void omap3_cm_restore_context(void);
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c
new file mode 100644
index 00000000..e96f53ea
--- /dev/null
+++ b/arch/arm/mach-omap2/cm44xx.c
@@ -0,0 +1,52 @@
+/*
+ * OMAP4 CM1, CM2 module low-level functions
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These functions are intended to be used only by the cminst44xx.c file.
+ * XXX Perhaps we should just move them there and make them static.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm-regbits-44xx.h"
+
+/* CM1 hardware module low-level functions */
+
+/* Read a register in CM1 */
+u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_CM1_REGADDR(inst, reg));
+}
+
+/* Write into a register in CM1 */
+void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_CM1_REGADDR(inst, reg));
+}
+
+/* Read a register in CM2 */
+u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_CM2_REGADDR(inst, reg));
+}
+
+/* Write into a register in CM2 */
+void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg));
+}
diff --git a/arch/arm/mach-omap2/cm44xx.h b/arch/arm/mach-omap2/cm44xx.h
new file mode 100644
index 00000000..0b87ec82
--- /dev/null
+++ b/arch/arm/mach-omap2/cm44xx.h
@@ -0,0 +1,32 @@
+/*
+ * OMAP4 Clock Management (CM) definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * OMAP4 has two separate CM blocks, CM1 and CM2. This file contains
+ * macros and function prototypes that are applicable to both.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CM44XX_H
+#define __ARCH_ASM_MACH_OMAP2_CM44XX_H
+
+
+#include "prcm-common.h"
+#include "cm.h"
+
+#define OMAP4_CM_CLKSTCTRL 0x0000
+#define OMAP4_CM_STATICDEP 0x0004
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+
+extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
+
+# endif
+#endif
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
new file mode 100644
index 00000000..a482bfa0
--- /dev/null
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -0,0 +1,235 @@
+/*
+ * OMAP4 CM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This is needed since CM instances can be in the PRM, PRCM_MPU, CM1,
+ * or CM2 hardware modules. For example, the EMU_CM CM instance is in
+ * the PRM hardware module. What a mess...
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "cm.h"
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "cm44xx.h"
+#include "cminst44xx.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prm44xx.h"
+#include "prcm_mpu44xx.h"
+
+static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
+ [OMAP4430_INVALID_PRCM_PARTITION] = 0,
+ [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
+ [OMAP4430_CM1_PARTITION] = OMAP4430_CM1_BASE,
+ [OMAP4430_CM2_PARTITION] = OMAP4430_CM2_BASE,
+ [OMAP4430_SCRM_PARTITION] = 0,
+ [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
+};
+
+/* Read a register in a CM instance */
+u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx));
+}
+
+/* Write into a register in a CM instance */
+void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_cm_bases[part]);
+ __raw_writel(val, OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx));
+}
+
+/* Read-modify-write a register in CM1. Caller must lock */
+u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
+ s16 idx)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, idx);
+ v &= ~mask;
+ v |= bits;
+ omap4_cminst_write_inst_reg(v, part, inst, idx);
+
+ return v;
+}
+
+u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+{
+ return omap4_cminst_rmw_inst_reg_bits(bits, bits, part, inst, idx);
+}
+
+u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst, s16 idx)
+{
+ return omap4_cminst_rmw_inst_reg_bits(bits, 0x0, part, inst, idx);
+}
+
+u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+/*
+ *
+ */
+
+/**
+ * _clktrctrl_write - write @c to a CM_CLKSTCTRL.CLKTRCTRL register bitfield
+ * @c: CLKTRCTRL register bitfield (LSB = bit 0, i.e., unshifted)
+ * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * @c must be the unshifted value for CLKTRCTRL - i.e., this function
+ * will handle the shift itself.
+ */
+static void _clktrctrl_write(u8 c, u8 part, s16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+ v &= ~OMAP4430_CLKTRCTRL_MASK;
+ v |= c << OMAP4430_CLKTRCTRL_SHIFT;
+ omap4_cminst_write_inst_reg(v, part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+}
+
+/**
+ * omap4_cminst_is_clkdm_in_hwsup - is a clockdomain in hwsup idle mode?
+ * @part: PRCM partition ID that the CM_CLKSTCTRL register exists in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Returns true if the clockdomain referred to by (@part, @inst, @cdoffs)
+ * is in hardware-supervised idle mode, or 0 otherwise.
+ */
+bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ u32 v;
+
+ v = omap4_cminst_read_inst_reg(part, inst, cdoffs + OMAP4_CM_CLKSTCTRL);
+ v &= OMAP4430_CLKTRCTRL_MASK;
+ v >>= OMAP4430_CLKTRCTRL_SHIFT;
+
+ return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? true : false;
+}
+
+/**
+ * omap4_cminst_clkdm_enable_hwsup - put a clockdomain in hwsup-idle mode
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
+ * hardware-supervised idle mode. No return value.
+ */
+void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_disable_hwsup - put a clockdomain in swsup-idle mode
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into
+ * software-supervised idle mode, i.e., controlled manually by the
+ * Linux OMAP clockdomain code. No return value.
+ */
+void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Put a clockdomain referred to by (@part, @inst, @cdoffs) into idle
+ * No return value.
+ */
+void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
+}
+
+/**
+ * omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
+ * @part: PRCM partition ID that the clockdomain registers exist in
+ * @inst: CM instance register offset (*_INST macro)
+ * @cdoffs: Clockdomain register offset (*_CDOFFS macro)
+ *
+ * Take a clockdomain referred to by (@part, @inst, @cdoffs) out of idle,
+ * waking it up. No return value.
+ */
+void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
+{
+ _clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, part, inst, cdoffs);
+}
+
+/*
+ *
+ */
+
+/**
+ * omap4_cm_wait_module_ready - wait for a module to be in 'func' state
+ * @clkctrl_reg: CLKCTRL module address
+ *
+ * Wait for the module IDLEST to be functional. If the idle state is in any
+ * the non functional state (trans, idle or disabled), module and thus the
+ * sysconfig cannot be accessed and will probably lead to an "imprecise
+ * external abort"
+ *
+ * Module idle state:
+ * 0x0 func: Module is fully functional, including OCP
+ * 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
+ * abortion
+ * 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
+ * using separate functional clock
+ * 0x3 disabled: Module is disabled and cannot be accessed
+ *
+ */
+int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
+{
+ int i = 0;
+
+ if (!clkctrl_reg)
+ return 0;
+
+ omap_test_timeout((
+ ((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
+ (((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
+ OMAP4430_IDLEST_SHIFT) == 0x2)),
+ MAX_MODULE_READY_TIME, i);
+
+ return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+}
+
diff --git a/arch/arm/mach-omap2/cminst44xx.h b/arch/arm/mach-omap2/cminst44xx.h
new file mode 100644
index 00000000..2b32c181
--- /dev/null
+++ b/arch/arm/mach-omap2/cminst44xx.h
@@ -0,0 +1,37 @@
+/*
+ * OMAP4 Clock Management (CM) function prototypes
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
+#define __ARCH_ASM_MACH_OMAP2_CMINST44XX_H
+
+extern bool omap4_cminst_is_clkdm_in_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
+extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
+
+/*
+ * In an ideal world, we would not export these low-level functions,
+ * but this will probably take some time to fix properly
+ */
+extern u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx);
+extern void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
+extern u32 omap4_cminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
+ s16 inst, s16 idx);
+extern u32 omap4_cminst_set_inst_reg_bits(u32 bits, u8 part, s16 inst,
+ s16 idx);
+extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
+ s16 idx);
+extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
+ u32 mask);
+
+extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);
+
+#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c
new file mode 100644
index 00000000..94ccf464
--- /dev/null
+++ b/arch/arm/mach-omap2/common-board-devices.c
@@ -0,0 +1,163 @@
+/*
+ * common-board-devices.c
+ *
+ * Copyright (C) 2011 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <plat/i2c.h>
+#include <plat/mcspi.h>
+#include <plat/nand.h>
+
+#include "common-board-devices.h"
+
+static struct i2c_board_info __initdata pmic_i2c_board_info = {
+ .addr = 0x48,
+ .flags = I2C_CLIENT_WAKE,
+};
+
+void __init omap_pmic_init(int bus, u32 clkrate,
+ const char *pmic_type, int pmic_irq,
+ struct twl4030_platform_data *pmic_data)
+{
+ strncpy(pmic_i2c_board_info.type, pmic_type,
+ sizeof(pmic_i2c_board_info.type));
+ pmic_i2c_board_info.irq = pmic_irq;
+ pmic_i2c_board_info.platform_data = pmic_data;
+
+ omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
+}
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+ .turbo_mode = 0,
+ .single_channel = 1, /* 0: slave, 1: master */
+};
+
+static struct ads7846_platform_data ads7846_config = {
+ .x_max = 0x0fff,
+ .y_max = 0x0fff,
+ .x_plate_ohms = 180,
+ .pressure_max = 255,
+ .debounce_max = 10,
+ .debounce_tol = 3,
+ .debounce_rep = 1,
+ .gpio_pendown = -EINVAL,
+ .keep_vref_on = 1,
+};
+
+static struct spi_board_info ads7846_spi_board_info __initdata = {
+ .modalias = "ads7846",
+ .bus_num = -EINVAL,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .controller_data = &ads7846_mcspi_config,
+ .irq = -EINVAL,
+ .platform_data = &ads7846_config,
+};
+
+void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+ struct ads7846_platform_data *board_pdata)
+{
+ struct spi_board_info *spi_bi = &ads7846_spi_board_info;
+ int err;
+
+ if (board_pdata && board_pdata->get_pendown_state) {
+ err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+ if (err) {
+ pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+ return;
+ }
+ gpio_export(gpio_pendown, 0);
+
+ if (gpio_debounce)
+ gpio_set_debounce(gpio_pendown, gpio_debounce);
+ }
+
+ ads7846_config.gpio_pendown = gpio_pendown;
+
+ spi_bi->bus_num = bus_num;
+ spi_bi->irq = OMAP_GPIO_IRQ(gpio_pendown);
+
+ if (board_pdata)
+ spi_bi->platform_data = board_pdata;
+
+ spi_register_board_info(&ads7846_spi_board_info, 1);
+}
+#else
+void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+ struct ads7846_platform_data *board_pdata)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+static struct omap_nand_platform_data nand_data = {
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+};
+
+void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
+ int nr_parts)
+{
+ u8 cs = 0;
+ u8 nandcs = GPMC_CS_NUM + 1;
+
+ /* find out the chip-select on which NAND exists */
+ while (cs < GPMC_CS_NUM) {
+ u32 ret = 0;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ if ((ret & 0xC00) == 0x800) {
+ printk(KERN_INFO "Found NAND on CS%d\n", cs);
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ }
+ cs++;
+ }
+
+ if (nandcs > GPMC_CS_NUM) {
+ printk(KERN_INFO "NAND: Unable to find configuration "
+ "in GPMC\n ");
+ return;
+ }
+
+ if (nandcs < GPMC_CS_NUM) {
+ nand_data.cs = nandcs;
+ nand_data.parts = parts;
+ nand_data.nr_parts = nr_parts;
+ nand_data.options = options;
+
+ printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+ if (gpmc_nand_init(&nand_data) < 0)
+ printk(KERN_ERR "Unable to register NAND device\n");
+ }
+}
+#else
+void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
+ int nr_parts)
+{
+}
+#endif
diff --git a/arch/arm/mach-omap2/common-board-devices.h b/arch/arm/mach-omap2/common-board-devices.h
new file mode 100644
index 00000000..67971905
--- /dev/null
+++ b/arch/arm/mach-omap2/common-board-devices.h
@@ -0,0 +1,37 @@
+#ifndef __OMAP_COMMON_BOARD_DEVICES__
+#define __OMAP_COMMON_BOARD_DEVICES__
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+struct twl4030_platform_data;
+struct mtd_partition;
+
+void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
+ struct twl4030_platform_data *pmic_data);
+
+static inline void omap2_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data)
+{
+ omap_pmic_init(2, 2600, pmic_type, INT_24XX_SYS_NIRQ, pmic_data);
+}
+
+static inline void omap3_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data)
+{
+ omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
+}
+
+static inline void omap4_pmic_init(const char *pmic_type,
+ struct twl4030_platform_data *pmic_data)
+{
+ /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
+ omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
+}
+
+struct ads7846_platform_data;
+
+void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+ struct ads7846_platform_data *board_pdata);
+void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts);
+
+#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
new file mode 100644
index 00000000..3f20cbb9
--- /dev/null
+++ b/arch/arm/mach-omap2/common.c
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/arm/mach-omap2/common.c
+ *
+ * Code common to all OMAP2+ machines.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/mux.h>
+
+#include <plat/clock.h>
+
+#include "sdrc.h"
+#include "control.h"
+
+/* Global address base setup code */
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+
+static void __init __omap2_set_globals(struct omap_globals *omap2_globals)
+{
+ omap2_set_globals_tap(omap2_globals);
+ omap2_set_globals_sdrc(omap2_globals);
+ omap2_set_globals_control(omap2_globals);
+ omap2_set_globals_prcm(omap2_globals);
+}
+
+#endif
+
+#if defined(CONFIG_SOC_OMAP2420)
+
+static struct omap_globals omap242x_globals = {
+ .class = OMAP242X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x48014000),
+ .sdrc = OMAP2420_SDRC_BASE,
+ .sms = OMAP2420_SMS_BASE,
+ .ctrl = OMAP242X_CTRL_BASE,
+ .prm = OMAP2420_PRM_BASE,
+ .cm = OMAP2420_CM_BASE,
+};
+
+void __init omap2_set_globals_242x(void)
+{
+ __omap2_set_globals(&omap242x_globals);
+}
+#endif
+
+#if defined(CONFIG_SOC_OMAP2430)
+
+static struct omap_globals omap243x_globals = {
+ .class = OMAP243X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x4900a000),
+ .sdrc = OMAP243X_SDRC_BASE,
+ .sms = OMAP243X_SMS_BASE,
+ .ctrl = OMAP243X_CTRL_BASE,
+ .prm = OMAP2430_PRM_BASE,
+ .cm = OMAP2430_CM_BASE,
+};
+
+void __init omap2_set_globals_243x(void)
+{
+ __omap2_set_globals(&omap243x_globals);
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+
+static struct omap_globals omap3_globals = {
+ .class = OMAP343X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(0x4830A000),
+ .sdrc = OMAP343X_SDRC_BASE,
+ .sms = OMAP343X_SMS_BASE,
+ .ctrl = OMAP343X_CTRL_BASE,
+ .prm = OMAP3430_PRM_BASE,
+ .cm = OMAP3430_CM_BASE,
+};
+
+void __init omap2_set_globals_3xxx(void)
+{
+ __omap2_set_globals(&omap3_globals);
+}
+
+void __init omap3_map_io(void)
+{
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
+}
+
+/*
+ * Adjust TAP register base such that omap3_check_revision accesses the correct
+ * TI816X register for checking device ID (it adds 0x204 to tap base while
+ * TI816X DEVICE ID register is at offset 0x600 from control base).
+ */
+#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \
+ TI816X_CONTROL_DEVICE_ID - 0x204)
+
+static struct omap_globals ti816x_globals = {
+ .class = OMAP343X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE),
+ .ctrl = TI816X_CTRL_BASE,
+ .prm = TI816X_PRCM_BASE,
+ .cm = TI816X_PRCM_BASE,
+};
+
+void __init omap2_set_globals_ti816x(void)
+{
+ __omap2_set_globals(&ti816x_globals);
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4)
+static struct omap_globals omap4_globals = {
+ .class = OMAP443X_CLASS,
+ .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE),
+ .ctrl = OMAP443X_SCM_BASE,
+ .ctrl_pad = OMAP443X_CTRL_BASE,
+ .prm = OMAP4430_PRM_BASE,
+ .cm = OMAP4430_CM_BASE,
+ .cm2 = OMAP4430_CM2_BASE,
+};
+
+void __init omap2_set_globals_443x(void)
+{
+ omap2_set_globals_tap(&omap4_globals);
+ omap2_set_globals_control(&omap4_globals);
+ omap2_set_globals_prcm(&omap4_globals);
+}
+#endif
+
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
new file mode 100644
index 00000000..da53ba39
--- /dev/null
+++ b/arch/arm/mach-omap2/control.c
@@ -0,0 +1,570 @@
+/*
+ * OMAP2/3 System Control Module register access
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/sdrc.h>
+
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "sdrc.h"
+#include "pm.h"
+#include "control.h"
+
+/* Used by omap3_ctrl_save_padconf() */
+#define START_PADCONF_SAVE 0x2
+#define PADCONF_SAVE_DONE 0x1
+
+static void __iomem *omap2_ctrl_base;
+static void __iomem *omap4_ctrl_pad_base;
+
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+struct omap3_scratchpad {
+ u32 boot_config_ptr;
+ u32 public_restore_ptr;
+ u32 secure_ram_restore_ptr;
+ u32 sdrc_module_semaphore;
+ u32 prcm_block_offset;
+ u32 sdrc_block_offset;
+};
+
+struct omap3_scratchpad_prcm_block {
+ u32 prm_clksrc_ctrl;
+ u32 prm_clksel;
+ u32 cm_clksel_core;
+ u32 cm_clksel_wkup;
+ u32 cm_clken_pll;
+ u32 cm_autoidle_pll;
+ u32 cm_clksel1_pll;
+ u32 cm_clksel2_pll;
+ u32 cm_clksel3_pll;
+ u32 cm_clken_pll_mpu;
+ u32 cm_autoidle_pll_mpu;
+ u32 cm_clksel1_pll_mpu;
+ u32 cm_clksel2_pll_mpu;
+ u32 prcm_block_size;
+};
+
+struct omap3_scratchpad_sdrc_block {
+ u16 sysconfig;
+ u16 cs_cfg;
+ u16 sharing;
+ u16 err_type;
+ u32 dll_a_ctrl;
+ u32 dll_b_ctrl;
+ u32 power;
+ u32 cs_0;
+ u32 mcfg_0;
+ u16 mr_0;
+ u16 emr_1_0;
+ u16 emr_2_0;
+ u16 emr_3_0;
+ u32 actim_ctrla_0;
+ u32 actim_ctrlb_0;
+ u32 rfr_ctrl_0;
+ u32 cs_1;
+ u32 mcfg_1;
+ u16 mr_1;
+ u16 emr_1_1;
+ u16 emr_2_1;
+ u16 emr_3_1;
+ u32 actim_ctrla_1;
+ u32 actim_ctrlb_1;
+ u32 rfr_ctrl_1;
+ u16 dcdl_1_ctrl;
+ u16 dcdl_2_ctrl;
+ u32 flags;
+ u32 block_size;
+};
+
+void *omap3_secure_ram_storage;
+
+/*
+ * This is used to store ARM registers in SDRAM before attempting
+ * an MPU OFF. The save and restore happens from the SRAM sleep code.
+ * The address is stored in scratchpad, so that it can be used
+ * during the restore path.
+ */
+u32 omap3_arm_context[128];
+
+struct omap3_control_regs {
+ u32 sysconfig;
+ u32 devconf0;
+ u32 mem_dftrw0;
+ u32 mem_dftrw1;
+ u32 msuspendmux_0;
+ u32 msuspendmux_1;
+ u32 msuspendmux_2;
+ u32 msuspendmux_3;
+ u32 msuspendmux_4;
+ u32 msuspendmux_5;
+ u32 sec_ctrl;
+ u32 devconf1;
+ u32 csirxfe;
+ u32 iva2_bootaddr;
+ u32 iva2_bootmod;
+ u32 debobs_0;
+ u32 debobs_1;
+ u32 debobs_2;
+ u32 debobs_3;
+ u32 debobs_4;
+ u32 debobs_5;
+ u32 debobs_6;
+ u32 debobs_7;
+ u32 debobs_8;
+ u32 prog_io0;
+ u32 prog_io1;
+ u32 dss_dpll_spreading;
+ u32 core_dpll_spreading;
+ u32 per_dpll_spreading;
+ u32 usbhost_dpll_spreading;
+ u32 pbias_lite;
+ u32 temp_sensor;
+ u32 sramldo4;
+ u32 sramldo5;
+ u32 csi;
+ u32 padconf_sys_nirq;
+};
+
+static struct omap3_control_regs control_context;
+#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+
+#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
+#define OMAP4_CTRL_PAD_REGADDR(reg) (omap4_ctrl_pad_base + (reg))
+
+void __init omap2_set_globals_control(struct omap_globals *omap2_globals)
+{
+ /* Static mapping, never released */
+ if (omap2_globals->ctrl) {
+ omap2_ctrl_base = ioremap(omap2_globals->ctrl, SZ_4K);
+ WARN_ON(!omap2_ctrl_base);
+ }
+
+ /* Static mapping, never released */
+ if (omap2_globals->ctrl_pad) {
+ omap4_ctrl_pad_base = ioremap(omap2_globals->ctrl_pad, SZ_4K);
+ WARN_ON(!omap4_ctrl_pad_base);
+ }
+}
+
+void __iomem *omap_ctrl_base_get(void)
+{
+ return omap2_ctrl_base;
+}
+
+u8 omap_ctrl_readb(u16 offset)
+{
+ return __raw_readb(OMAP_CTRL_REGADDR(offset));
+}
+
+u16 omap_ctrl_readw(u16 offset)
+{
+ return __raw_readw(OMAP_CTRL_REGADDR(offset));
+}
+
+u32 omap_ctrl_readl(u16 offset)
+{
+ return __raw_readl(OMAP_CTRL_REGADDR(offset));
+}
+
+void omap_ctrl_writeb(u8 val, u16 offset)
+{
+ __raw_writeb(val, OMAP_CTRL_REGADDR(offset));
+}
+
+void omap_ctrl_writew(u16 val, u16 offset)
+{
+ __raw_writew(val, OMAP_CTRL_REGADDR(offset));
+}
+
+void omap_ctrl_writel(u32 val, u16 offset)
+{
+ __raw_writel(val, OMAP_CTRL_REGADDR(offset));
+}
+
+/*
+ * On OMAP4 control pad are not addressable from control
+ * core base. So the common omap_ctrl_read/write APIs breaks
+ * Hence export separate APIs to manage the omap4 pad control
+ * registers. This APIs will work only for OMAP4
+ */
+
+u32 omap4_ctrl_pad_readl(u16 offset)
+{
+ return __raw_readl(OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
+void omap4_ctrl_pad_writel(u32 val, u16 offset)
+{
+ __raw_writel(val, OMAP4_CTRL_PAD_REGADDR(offset));
+}
+
+#ifdef CONFIG_ARCH_OMAP3
+
+/**
+ * omap3_ctrl_write_boot_mode - set scratchpad boot mode for the next boot
+ * @bootmode: 8-bit value to pass to some boot code
+ *
+ * Set the bootmode in the scratchpad RAM. This is used after the
+ * system restarts. Not sure what actually uses this - it may be the
+ * bootloader, rather than the boot ROM - contrary to the preserved
+ * comment below. No return value.
+ */
+void omap3_ctrl_write_boot_mode(u8 bootmode)
+{
+ u32 l;
+
+ l = ('B' << 24) | ('M' << 16) | bootmode;
+
+ /*
+ * Reserve the first word in scratchpad for communicating
+ * with the boot ROM. A pointer to a data structure
+ * describing the boot process can be stored there,
+ * cf. OMAP34xx TRM, Initialization / Software Booting
+ * Configuration.
+ *
+ * XXX This should use some omap_ctrl_writel()-type function
+ */
+ __raw_writel(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4));
+}
+
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+/*
+ * Clears the scratchpad contents in case of cold boot-
+ * called during bootup
+ */
+void omap3_clear_scratchpad_contents(void)
+{
+ u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET;
+ void __iomem *v_addr;
+ u32 offset = 0;
+ v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
+ if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
+ OMAP3430_GLOBAL_COLD_RST_MASK) {
+ for ( ; offset <= max_offset; offset += 0x4)
+ __raw_writel(0x0, (v_addr + offset));
+ omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_RSTST_OFFSET);
+ }
+}
+
+/* Populate the scratchpad structure with restore structure */
+void omap3_save_scratchpad_contents(void)
+{
+ void __iomem *scratchpad_address;
+ u32 arm_context_addr;
+ struct omap3_scratchpad scratchpad_contents;
+ struct omap3_scratchpad_prcm_block prcm_block_contents;
+ struct omap3_scratchpad_sdrc_block sdrc_block_contents;
+
+ /*
+ * Populate the Scratchpad contents
+ *
+ * The "get_*restore_pointer" functions are used to provide a
+ * physical restore address where the ROM code jumps while waking
+ * up from MPU OFF/OSWR state.
+ * The restore pointer is stored into the scratchpad.
+ */
+ scratchpad_contents.boot_config_ptr = 0x0;
+ if (cpu_is_omap3630())
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(get_omap3630_restore_pointer());
+ else if (omap_rev() != OMAP3430_REV_ES3_0 &&
+ omap_rev() != OMAP3430_REV_ES3_1)
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(get_restore_pointer());
+ else
+ scratchpad_contents.public_restore_ptr =
+ virt_to_phys(get_es3_restore_pointer());
+ if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+ scratchpad_contents.secure_ram_restore_ptr = 0x0;
+ else
+ scratchpad_contents.secure_ram_restore_ptr =
+ (u32) __pa(omap3_secure_ram_storage);
+ scratchpad_contents.sdrc_module_semaphore = 0x0;
+ scratchpad_contents.prcm_block_offset = 0x2C;
+ scratchpad_contents.sdrc_block_offset = 0x64;
+
+ /* Populate the PRCM block contents */
+ prcm_block_contents.prm_clksrc_ctrl =
+ omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+ prcm_block_contents.prm_clksel =
+ omap2_prm_read_mod_reg(OMAP3430_CCR_MOD,
+ OMAP3_PRM_CLKSEL_OFFSET);
+ prcm_block_contents.cm_clksel_core =
+ omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL);
+ prcm_block_contents.cm_clksel_wkup =
+ omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL);
+ prcm_block_contents.cm_clken_pll =
+ omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
+ /*
+ * As per erratum i671, ROM code does not respect the PER DPLL
+ * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1.
+ * Then, in anycase, clear these bits to avoid extra latencies.
+ */
+ prcm_block_contents.cm_autoidle_pll =
+ omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) &
+ ~OMAP3430_AUTO_PERIPH_DPLL_MASK;
+ prcm_block_contents.cm_clksel1_pll =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ prcm_block_contents.cm_clksel2_pll =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL2_PLL);
+ prcm_block_contents.cm_clksel3_pll =
+ omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL3);
+ prcm_block_contents.cm_clken_pll_mpu =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKEN_PLL);
+ prcm_block_contents.cm_autoidle_pll_mpu =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL);
+ prcm_block_contents.cm_clksel1_pll_mpu =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL);
+ prcm_block_contents.cm_clksel2_pll_mpu =
+ omap2_cm_read_mod_reg(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL);
+ prcm_block_contents.prcm_block_size = 0x0;
+
+ /* Populate the SDRC block contents */
+ sdrc_block_contents.sysconfig =
+ (sdrc_read_reg(SDRC_SYSCONFIG) & 0xFFFF);
+ sdrc_block_contents.cs_cfg =
+ (sdrc_read_reg(SDRC_CS_CFG) & 0xFFFF);
+ sdrc_block_contents.sharing =
+ (sdrc_read_reg(SDRC_SHARING) & 0xFFFF);
+ sdrc_block_contents.err_type =
+ (sdrc_read_reg(SDRC_ERR_TYPE) & 0xFFFF);
+ sdrc_block_contents.dll_a_ctrl = sdrc_read_reg(SDRC_DLLA_CTRL);
+ sdrc_block_contents.dll_b_ctrl = 0x0;
+ /*
+ * Due to a OMAP3 errata (1.142), on EMU/HS devices SRDC should
+ * be programed to issue automatic self refresh on timeout
+ * of AUTO_CNT = 1 prior to any transition to OFF mode.
+ */
+ if ((omap_type() != OMAP2_DEVICE_TYPE_GP)
+ && (omap_rev() >= OMAP3430_REV_ES3_0))
+ sdrc_block_contents.power = (sdrc_read_reg(SDRC_POWER) &
+ ~(SDRC_POWER_AUTOCOUNT_MASK|
+ SDRC_POWER_CLKCTRL_MASK)) |
+ (1 << SDRC_POWER_AUTOCOUNT_SHIFT) |
+ SDRC_SELF_REFRESH_ON_AUTOCOUNT;
+ else
+ sdrc_block_contents.power = sdrc_read_reg(SDRC_POWER);
+
+ sdrc_block_contents.cs_0 = 0x0;
+ sdrc_block_contents.mcfg_0 = sdrc_read_reg(SDRC_MCFG_0);
+ sdrc_block_contents.mr_0 = (sdrc_read_reg(SDRC_MR_0) & 0xFFFF);
+ sdrc_block_contents.emr_1_0 = 0x0;
+ sdrc_block_contents.emr_2_0 = 0x0;
+ sdrc_block_contents.emr_3_0 = 0x0;
+ sdrc_block_contents.actim_ctrla_0 =
+ sdrc_read_reg(SDRC_ACTIM_CTRL_A_0);
+ sdrc_block_contents.actim_ctrlb_0 =
+ sdrc_read_reg(SDRC_ACTIM_CTRL_B_0);
+ sdrc_block_contents.rfr_ctrl_0 =
+ sdrc_read_reg(SDRC_RFR_CTRL_0);
+ sdrc_block_contents.cs_1 = 0x0;
+ sdrc_block_contents.mcfg_1 = sdrc_read_reg(SDRC_MCFG_1);
+ sdrc_block_contents.mr_1 = sdrc_read_reg(SDRC_MR_1) & 0xFFFF;
+ sdrc_block_contents.emr_1_1 = 0x0;
+ sdrc_block_contents.emr_2_1 = 0x0;
+ sdrc_block_contents.emr_3_1 = 0x0;
+ sdrc_block_contents.actim_ctrla_1 =
+ sdrc_read_reg(SDRC_ACTIM_CTRL_A_1);
+ sdrc_block_contents.actim_ctrlb_1 =
+ sdrc_read_reg(SDRC_ACTIM_CTRL_B_1);
+ sdrc_block_contents.rfr_ctrl_1 =
+ sdrc_read_reg(SDRC_RFR_CTRL_1);
+ sdrc_block_contents.dcdl_1_ctrl = 0x0;
+ sdrc_block_contents.dcdl_2_ctrl = 0x0;
+ sdrc_block_contents.flags = 0x0;
+ sdrc_block_contents.block_size = 0x0;
+
+ arm_context_addr = virt_to_phys(omap3_arm_context);
+
+ /* Copy all the contents to the scratchpad location */
+ scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
+ memcpy_toio(scratchpad_address, &scratchpad_contents,
+ sizeof(scratchpad_contents));
+ /* Scratchpad contents being 32 bits, a divide by 4 done here */
+ memcpy_toio(scratchpad_address +
+ scratchpad_contents.prcm_block_offset,
+ &prcm_block_contents, sizeof(prcm_block_contents));
+ memcpy_toio(scratchpad_address +
+ scratchpad_contents.sdrc_block_offset,
+ &sdrc_block_contents, sizeof(sdrc_block_contents));
+ /*
+ * Copies the address of the location in SDRAM where ARM
+ * registers get saved during a MPU OFF transition.
+ */
+ memcpy_toio(scratchpad_address +
+ scratchpad_contents.sdrc_block_offset +
+ sizeof(sdrc_block_contents), &arm_context_addr, 4);
+}
+
+void omap3_control_save_context(void)
+{
+ control_context.sysconfig = omap_ctrl_readl(OMAP2_CONTROL_SYSCONFIG);
+ control_context.devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ control_context.mem_dftrw0 =
+ omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW0);
+ control_context.mem_dftrw1 =
+ omap_ctrl_readl(OMAP343X_CONTROL_MEM_DFTRW1);
+ control_context.msuspendmux_0 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_0);
+ control_context.msuspendmux_1 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_1);
+ control_context.msuspendmux_2 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_2);
+ control_context.msuspendmux_3 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_3);
+ control_context.msuspendmux_4 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_4);
+ control_context.msuspendmux_5 =
+ omap_ctrl_readl(OMAP2_CONTROL_MSUSPENDMUX_5);
+ control_context.sec_ctrl = omap_ctrl_readl(OMAP2_CONTROL_SEC_CTRL);
+ control_context.devconf1 = omap_ctrl_readl(OMAP343X_CONTROL_DEVCONF1);
+ control_context.csirxfe = omap_ctrl_readl(OMAP343X_CONTROL_CSIRXFE);
+ control_context.iva2_bootaddr =
+ omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTADDR);
+ control_context.iva2_bootmod =
+ omap_ctrl_readl(OMAP343X_CONTROL_IVA2_BOOTMOD);
+ control_context.debobs_0 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(0));
+ control_context.debobs_1 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(1));
+ control_context.debobs_2 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(2));
+ control_context.debobs_3 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(3));
+ control_context.debobs_4 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(4));
+ control_context.debobs_5 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(5));
+ control_context.debobs_6 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(6));
+ control_context.debobs_7 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(7));
+ control_context.debobs_8 = omap_ctrl_readl(OMAP343X_CONTROL_DEBOBS(8));
+ control_context.prog_io0 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO0);
+ control_context.prog_io1 = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
+ control_context.dss_dpll_spreading =
+ omap_ctrl_readl(OMAP343X_CONTROL_DSS_DPLL_SPREADING);
+ control_context.core_dpll_spreading =
+ omap_ctrl_readl(OMAP343X_CONTROL_CORE_DPLL_SPREADING);
+ control_context.per_dpll_spreading =
+ omap_ctrl_readl(OMAP343X_CONTROL_PER_DPLL_SPREADING);
+ control_context.usbhost_dpll_spreading =
+ omap_ctrl_readl(OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
+ control_context.pbias_lite =
+ omap_ctrl_readl(OMAP343X_CONTROL_PBIAS_LITE);
+ control_context.temp_sensor =
+ omap_ctrl_readl(OMAP343X_CONTROL_TEMP_SENSOR);
+ control_context.sramldo4 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO4);
+ control_context.sramldo5 = omap_ctrl_readl(OMAP343X_CONTROL_SRAMLDO5);
+ control_context.csi = omap_ctrl_readl(OMAP343X_CONTROL_CSI);
+ control_context.padconf_sys_nirq =
+ omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_SYSNIRQ);
+ return;
+}
+
+void omap3_control_restore_context(void)
+{
+ omap_ctrl_writel(control_context.sysconfig, OMAP2_CONTROL_SYSCONFIG);
+ omap_ctrl_writel(control_context.devconf0, OMAP2_CONTROL_DEVCONF0);
+ omap_ctrl_writel(control_context.mem_dftrw0,
+ OMAP343X_CONTROL_MEM_DFTRW0);
+ omap_ctrl_writel(control_context.mem_dftrw1,
+ OMAP343X_CONTROL_MEM_DFTRW1);
+ omap_ctrl_writel(control_context.msuspendmux_0,
+ OMAP2_CONTROL_MSUSPENDMUX_0);
+ omap_ctrl_writel(control_context.msuspendmux_1,
+ OMAP2_CONTROL_MSUSPENDMUX_1);
+ omap_ctrl_writel(control_context.msuspendmux_2,
+ OMAP2_CONTROL_MSUSPENDMUX_2);
+ omap_ctrl_writel(control_context.msuspendmux_3,
+ OMAP2_CONTROL_MSUSPENDMUX_3);
+ omap_ctrl_writel(control_context.msuspendmux_4,
+ OMAP2_CONTROL_MSUSPENDMUX_4);
+ omap_ctrl_writel(control_context.msuspendmux_5,
+ OMAP2_CONTROL_MSUSPENDMUX_5);
+ omap_ctrl_writel(control_context.sec_ctrl, OMAP2_CONTROL_SEC_CTRL);
+ omap_ctrl_writel(control_context.devconf1, OMAP343X_CONTROL_DEVCONF1);
+ omap_ctrl_writel(control_context.csirxfe, OMAP343X_CONTROL_CSIRXFE);
+ omap_ctrl_writel(control_context.iva2_bootaddr,
+ OMAP343X_CONTROL_IVA2_BOOTADDR);
+ omap_ctrl_writel(control_context.iva2_bootmod,
+ OMAP343X_CONTROL_IVA2_BOOTMOD);
+ omap_ctrl_writel(control_context.debobs_0, OMAP343X_CONTROL_DEBOBS(0));
+ omap_ctrl_writel(control_context.debobs_1, OMAP343X_CONTROL_DEBOBS(1));
+ omap_ctrl_writel(control_context.debobs_2, OMAP343X_CONTROL_DEBOBS(2));
+ omap_ctrl_writel(control_context.debobs_3, OMAP343X_CONTROL_DEBOBS(3));
+ omap_ctrl_writel(control_context.debobs_4, OMAP343X_CONTROL_DEBOBS(4));
+ omap_ctrl_writel(control_context.debobs_5, OMAP343X_CONTROL_DEBOBS(5));
+ omap_ctrl_writel(control_context.debobs_6, OMAP343X_CONTROL_DEBOBS(6));
+ omap_ctrl_writel(control_context.debobs_7, OMAP343X_CONTROL_DEBOBS(7));
+ omap_ctrl_writel(control_context.debobs_8, OMAP343X_CONTROL_DEBOBS(8));
+ omap_ctrl_writel(control_context.prog_io0, OMAP343X_CONTROL_PROG_IO0);
+ omap_ctrl_writel(control_context.prog_io1, OMAP343X_CONTROL_PROG_IO1);
+ omap_ctrl_writel(control_context.dss_dpll_spreading,
+ OMAP343X_CONTROL_DSS_DPLL_SPREADING);
+ omap_ctrl_writel(control_context.core_dpll_spreading,
+ OMAP343X_CONTROL_CORE_DPLL_SPREADING);
+ omap_ctrl_writel(control_context.per_dpll_spreading,
+ OMAP343X_CONTROL_PER_DPLL_SPREADING);
+ omap_ctrl_writel(control_context.usbhost_dpll_spreading,
+ OMAP343X_CONTROL_USBHOST_DPLL_SPREADING);
+ omap_ctrl_writel(control_context.pbias_lite,
+ OMAP343X_CONTROL_PBIAS_LITE);
+ omap_ctrl_writel(control_context.temp_sensor,
+ OMAP343X_CONTROL_TEMP_SENSOR);
+ omap_ctrl_writel(control_context.sramldo4, OMAP343X_CONTROL_SRAMLDO4);
+ omap_ctrl_writel(control_context.sramldo5, OMAP343X_CONTROL_SRAMLDO5);
+ omap_ctrl_writel(control_context.csi, OMAP343X_CONTROL_CSI);
+ omap_ctrl_writel(control_context.padconf_sys_nirq,
+ OMAP343X_CONTROL_PADCONF_SYSNIRQ);
+ return;
+}
+
+void omap3630_ctrl_disable_rta(void)
+{
+ if (!cpu_is_omap3630())
+ return;
+ omap_ctrl_writel(OMAP36XX_RTA_DISABLE, OMAP36XX_CONTROL_MEM_RTA_CTRL);
+}
+
+/**
+ * omap3_ctrl_save_padconf - save padconf registers to scratchpad RAM
+ *
+ * Tell the SCM to start saving the padconf registers, then wait for
+ * the process to complete. Returns 0 unconditionally, although it
+ * should also eventually be able to return -ETIMEDOUT, if the save
+ * does not complete.
+ *
+ * XXX This function is missing a timeout. What should it be?
+ */
+int omap3_ctrl_save_padconf(void)
+{
+ u32 cpo;
+
+ /* Save the padconf registers */
+ cpo = omap_ctrl_readl(OMAP343X_CONTROL_PADCONF_OFF);
+ cpo |= START_PADCONF_SAVE;
+ omap_ctrl_writel(cpo, OMAP343X_CONTROL_PADCONF_OFF);
+
+ /* wait for the save to complete */
+ while (!(omap_ctrl_readl(OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS)
+ & PADCONF_SAVE_DONE))
+ udelay(1);
+
+ return 0;
+}
+
+#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
new file mode 100644
index 00000000..a016c8b5
--- /dev/null
+++ b/arch/arm/mach-omap2/control.h
@@ -0,0 +1,412 @@
+/*
+ * arch/arm/mach-omap2/control.h
+ *
+ * OMAP2/3/4 System Control Module definitions
+ *
+ * Copyright (C) 2007-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2010 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CONTROL_H
+#define __ARCH_ARM_MACH_OMAP2_CONTROL_H
+
+#include <mach/io.h>
+#include <mach/ctrl_module_core_44xx.h>
+#include <mach/ctrl_module_wkup_44xx.h>
+#include <mach/ctrl_module_pad_core_44xx.h>
+#include <mach/ctrl_module_pad_wkup_44xx.h>
+
+#ifndef __ASSEMBLY__
+#define OMAP242X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#else
+#define OMAP242X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#endif /* __ASSEMBLY__ */
+
+/*
+ * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
+ * OMAP24XX and OMAP34XX.
+ */
+
+/* Control submodule offsets */
+
+#define OMAP2_CONTROL_INTERFACE 0x000
+#define OMAP2_CONTROL_PADCONFS 0x030
+#define OMAP2_CONTROL_GENERAL 0x270
+#define OMAP343X_CONTROL_MEM_WKUP 0x600
+#define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00
+#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60
+
+/* TI816X spefic control submodules */
+#define TI816X_CONTROL_DEVCONF 0x600
+
+/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
+
+#define OMAP2_CONTROL_SYSCONFIG (OMAP2_CONTROL_INTERFACE + 0x10)
+
+/* CONTROL_GENERAL register offsets common to OMAP2 & 3 */
+#define OMAP2_CONTROL_DEVCONF0 (OMAP2_CONTROL_GENERAL + 0x0004)
+#define OMAP2_CONTROL_MSUSPENDMUX_0 (OMAP2_CONTROL_GENERAL + 0x0020)
+#define OMAP2_CONTROL_MSUSPENDMUX_1 (OMAP2_CONTROL_GENERAL + 0x0024)
+#define OMAP2_CONTROL_MSUSPENDMUX_2 (OMAP2_CONTROL_GENERAL + 0x0028)
+#define OMAP2_CONTROL_MSUSPENDMUX_3 (OMAP2_CONTROL_GENERAL + 0x002c)
+#define OMAP2_CONTROL_MSUSPENDMUX_4 (OMAP2_CONTROL_GENERAL + 0x0030)
+#define OMAP2_CONTROL_MSUSPENDMUX_5 (OMAP2_CONTROL_GENERAL + 0x0034)
+#define OMAP2_CONTROL_SEC_CTRL (OMAP2_CONTROL_GENERAL + 0x0040)
+#define OMAP2_CONTROL_RPUB_KEY_H_0 (OMAP2_CONTROL_GENERAL + 0x0090)
+#define OMAP2_CONTROL_RPUB_KEY_H_1 (OMAP2_CONTROL_GENERAL + 0x0094)
+#define OMAP2_CONTROL_RPUB_KEY_H_2 (OMAP2_CONTROL_GENERAL + 0x0098)
+#define OMAP2_CONTROL_RPUB_KEY_H_3 (OMAP2_CONTROL_GENERAL + 0x009c)
+
+/* 242x-only CONTROL_GENERAL register offsets */
+#define OMAP242X_CONTROL_DEVCONF OMAP2_CONTROL_DEVCONF0 /* match TRM */
+#define OMAP242X_CONTROL_OCM_RAM_PERM (OMAP2_CONTROL_GENERAL + 0x0068)
+
+/* 243x-only CONTROL_GENERAL register offsets */
+/* CONTROL_IVA2_BOOT{ADDR,MOD} are at the same place on 343x - noted below */
+#define OMAP243X_CONTROL_DEVCONF1 (OMAP2_CONTROL_GENERAL + 0x0078)
+#define OMAP243X_CONTROL_CSIRXFE (OMAP2_CONTROL_GENERAL + 0x007c)
+#define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
+#define OMAP243X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP243X_CONTROL_IVA2_GEMCFG (OMAP2_CONTROL_GENERAL + 0x0198)
+#define OMAP243X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x0230)
+
+/* 24xx-only CONTROL_GENERAL register offsets */
+#define OMAP24XX_CONTROL_DEBOBS (OMAP2_CONTROL_GENERAL + 0x0000)
+#define OMAP24XX_CONTROL_EMU_SUPPORT (OMAP2_CONTROL_GENERAL + 0x0008)
+#define OMAP24XX_CONTROL_SEC_TEST (OMAP2_CONTROL_GENERAL + 0x0044)
+#define OMAP24XX_CONTROL_PSA_CTRL (OMAP2_CONTROL_GENERAL + 0x0048)
+#define OMAP24XX_CONTROL_PSA_CMD (OMAP2_CONTROL_GENERAL + 0x004c)
+#define OMAP24XX_CONTROL_PSA_VALUE (OMAP2_CONTROL_GENERAL + 0x0050)
+#define OMAP24XX_CONTROL_SEC_EMU (OMAP2_CONTROL_GENERAL + 0x0060)
+#define OMAP24XX_CONTROL_SEC_TAP (OMAP2_CONTROL_GENERAL + 0x0064)
+#define OMAP24XX_CONTROL_OCM_PUB_RAM_ADD (OMAP2_CONTROL_GENERAL + 0x006c)
+#define OMAP24XX_CONTROL_EXT_SEC_RAM_START_ADD (OMAP2_CONTROL_GENERAL + 0x0070)
+#define OMAP24XX_CONTROL_EXT_SEC_RAM_STOP_ADD (OMAP2_CONTROL_GENERAL + 0x0074)
+#define OMAP24XX_CONTROL_SEC_STATUS (OMAP2_CONTROL_GENERAL + 0x0080)
+#define OMAP24XX_CONTROL_SEC_ERR_STATUS (OMAP2_CONTROL_GENERAL + 0x0084)
+#define OMAP24XX_CONTROL_STATUS (OMAP2_CONTROL_GENERAL + 0x0088)
+#define OMAP24XX_CONTROL_GENERAL_PURPOSE_STATUS (OMAP2_CONTROL_GENERAL + 0x008c)
+#define OMAP24XX_CONTROL_RAND_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00a0)
+#define OMAP24XX_CONTROL_RAND_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00a4)
+#define OMAP24XX_CONTROL_RAND_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00a8)
+#define OMAP24XX_CONTROL_RAND_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00ac)
+#define OMAP24XX_CONTROL_CUST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00b0)
+#define OMAP24XX_CONTROL_CUST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00b4)
+#define OMAP24XX_CONTROL_TEST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00c0)
+#define OMAP24XX_CONTROL_TEST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00c4)
+#define OMAP24XX_CONTROL_TEST_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00c8)
+#define OMAP24XX_CONTROL_TEST_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00cc)
+#define OMAP24XX_CONTROL_TEST_KEY_4 (OMAP2_CONTROL_GENERAL + 0x00d0)
+#define OMAP24XX_CONTROL_TEST_KEY_5 (OMAP2_CONTROL_GENERAL + 0x00d4)
+#define OMAP24XX_CONTROL_TEST_KEY_6 (OMAP2_CONTROL_GENERAL + 0x00d8)
+#define OMAP24XX_CONTROL_TEST_KEY_7 (OMAP2_CONTROL_GENERAL + 0x00dc)
+#define OMAP24XX_CONTROL_TEST_KEY_8 (OMAP2_CONTROL_GENERAL + 0x00e0)
+#define OMAP24XX_CONTROL_TEST_KEY_9 (OMAP2_CONTROL_GENERAL + 0x00e4)
+
+#define OMAP343X_CONTROL_PADCONF_SYSNIRQ (OMAP2_CONTROL_INTERFACE + 0x01b0)
+
+/* 34xx-only CONTROL_GENERAL register offsets */
+#define OMAP343X_CONTROL_PADCONF_OFF (OMAP2_CONTROL_GENERAL + 0x0000)
+#define OMAP343X_CONTROL_MEM_DFTRW0 (OMAP2_CONTROL_GENERAL + 0x0008)
+#define OMAP343X_CONTROL_MEM_DFTRW1 (OMAP2_CONTROL_GENERAL + 0x000c)
+#define OMAP343X_CONTROL_DEVCONF1 (OMAP2_CONTROL_GENERAL + 0x0068)
+#define OMAP343X_CONTROL_CSIRXFE (OMAP2_CONTROL_GENERAL + 0x006c)
+#define OMAP343X_CONTROL_SEC_STATUS (OMAP2_CONTROL_GENERAL + 0x0070)
+#define OMAP343X_CONTROL_SEC_ERR_STATUS (OMAP2_CONTROL_GENERAL + 0x0074)
+#define OMAP343X_CONTROL_SEC_ERR_STATUS_DEBUG (OMAP2_CONTROL_GENERAL + 0x0078)
+#define OMAP343X_CONTROL_STATUS (OMAP2_CONTROL_GENERAL + 0x0080)
+#define OMAP343X_CONTROL_GENERAL_PURPOSE_STATUS (OMAP2_CONTROL_GENERAL + 0x0084)
+#define OMAP343X_CONTROL_RPUB_KEY_H_4 (OMAP2_CONTROL_GENERAL + 0x00a0)
+#define OMAP343X_CONTROL_RAND_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00a8)
+#define OMAP343X_CONTROL_RAND_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00ac)
+#define OMAP343X_CONTROL_RAND_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00b0)
+#define OMAP343X_CONTROL_RAND_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00b4)
+#define OMAP343X_CONTROL_TEST_KEY_0 (OMAP2_CONTROL_GENERAL + 0x00c8)
+#define OMAP343X_CONTROL_TEST_KEY_1 (OMAP2_CONTROL_GENERAL + 0x00cc)
+#define OMAP343X_CONTROL_TEST_KEY_2 (OMAP2_CONTROL_GENERAL + 0x00d0)
+#define OMAP343X_CONTROL_TEST_KEY_3 (OMAP2_CONTROL_GENERAL + 0x00d4)
+#define OMAP343X_CONTROL_TEST_KEY_4 (OMAP2_CONTROL_GENERAL + 0x00d8)
+#define OMAP343X_CONTROL_TEST_KEY_5 (OMAP2_CONTROL_GENERAL + 0x00dc)
+#define OMAP343X_CONTROL_TEST_KEY_6 (OMAP2_CONTROL_GENERAL + 0x00e0)
+#define OMAP343X_CONTROL_TEST_KEY_7 (OMAP2_CONTROL_GENERAL + 0x00e4)
+#define OMAP343X_CONTROL_TEST_KEY_8 (OMAP2_CONTROL_GENERAL + 0x00e8)
+#define OMAP343X_CONTROL_TEST_KEY_9 (OMAP2_CONTROL_GENERAL + 0x00ec)
+#define OMAP343X_CONTROL_TEST_KEY_10 (OMAP2_CONTROL_GENERAL + 0x00f0)
+#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)
+#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)
+#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c)
+#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124)
+#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c)
+#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
+#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
+#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \
+ + ((i) >> 1) * 4 + (!((i) & 1)) * 2)
+#define OMAP343X_CONTROL_PROG_IO0 (OMAP2_CONTROL_GENERAL + 0x01D4)
+#define OMAP343X_CONTROL_PROG_IO1 (OMAP2_CONTROL_GENERAL + 0x01D8)
+#define OMAP343X_CONTROL_DSS_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E0)
+#define OMAP343X_CONTROL_CORE_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E4)
+#define OMAP343X_CONTROL_PER_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01E8)
+#define OMAP343X_CONTROL_USBHOST_DPLL_SPREADING (OMAP2_CONTROL_GENERAL + 0x01EC)
+#define OMAP343X_CONTROL_PBIAS_LITE (OMAP2_CONTROL_GENERAL + 0x02B0)
+#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02B4)
+#define OMAP343X_CONTROL_SRAMLDO4 (OMAP2_CONTROL_GENERAL + 0x02B8)
+#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)
+#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4)
+
+/* OMAP3630 only CONTROL_GENERAL register offsets */
+#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
+#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
+#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
+#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C)
+
+/* OMAP44xx control efuse offsets */
+#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C
+#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
+#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232
+#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235
+#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240
+#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243
+#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246
+#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
+#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
+
+/* AM35XX only CONTROL_GENERAL register offsets */
+#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
+#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
+#define AM35XX_CONTROL_DEVCONF3 (OMAP2_CONTROL_GENERAL + 0x0314)
+#define AM35XX_CONTROL_CBA_PRIORITY (OMAP2_CONTROL_GENERAL + 0x0320)
+#define AM35XX_CONTROL_LVL_INTR_CLEAR (OMAP2_CONTROL_GENERAL + 0x0324)
+#define AM35XX_CONTROL_IP_SW_RESET (OMAP2_CONTROL_GENERAL + 0x0328)
+#define AM35XX_CONTROL_IPSS_CLK_CTRL (OMAP2_CONTROL_GENERAL + 0x032C)
+
+/* 34xx PADCONF register offsets */
+#define OMAP343X_PADCONF_ETK(i) (OMAP2_CONTROL_PADCONFS + 0x5a8 + \
+ (i)*2)
+#define OMAP343X_PADCONF_ETK_CLK OMAP343X_PADCONF_ETK(0)
+#define OMAP343X_PADCONF_ETK_CTL OMAP343X_PADCONF_ETK(1)
+#define OMAP343X_PADCONF_ETK_D0 OMAP343X_PADCONF_ETK(2)
+#define OMAP343X_PADCONF_ETK_D1 OMAP343X_PADCONF_ETK(3)
+#define OMAP343X_PADCONF_ETK_D2 OMAP343X_PADCONF_ETK(4)
+#define OMAP343X_PADCONF_ETK_D3 OMAP343X_PADCONF_ETK(5)
+#define OMAP343X_PADCONF_ETK_D4 OMAP343X_PADCONF_ETK(6)
+#define OMAP343X_PADCONF_ETK_D5 OMAP343X_PADCONF_ETK(7)
+#define OMAP343X_PADCONF_ETK_D6 OMAP343X_PADCONF_ETK(8)
+#define OMAP343X_PADCONF_ETK_D7 OMAP343X_PADCONF_ETK(9)
+#define OMAP343X_PADCONF_ETK_D8 OMAP343X_PADCONF_ETK(10)
+#define OMAP343X_PADCONF_ETK_D9 OMAP343X_PADCONF_ETK(11)
+#define OMAP343X_PADCONF_ETK_D10 OMAP343X_PADCONF_ETK(12)
+#define OMAP343X_PADCONF_ETK_D11 OMAP343X_PADCONF_ETK(13)
+#define OMAP343X_PADCONF_ETK_D12 OMAP343X_PADCONF_ETK(14)
+#define OMAP343X_PADCONF_ETK_D13 OMAP343X_PADCONF_ETK(15)
+#define OMAP343X_PADCONF_ETK_D14 OMAP343X_PADCONF_ETK(16)
+#define OMAP343X_PADCONF_ETK_D15 OMAP343X_PADCONF_ETK(17)
+
+/* 34xx GENERAL_WKUP regist offsets */
+#define OMAP343X_CONTROL_WKUP_DEBOBSMUX(i) (OMAP343X_CONTROL_GENERAL_WKUP + \
+ 0x008 + (i))
+#define OMAP343X_CONTROL_WKUP_DEBOBS0 (OMAP343X_CONTROL_GENERAL_WKUP + 0x008)
+#define OMAP343X_CONTROL_WKUP_DEBOBS1 (OMAP343X_CONTROL_GENERAL_WKUP + 0x00C)
+#define OMAP343X_CONTROL_WKUP_DEBOBS2 (OMAP343X_CONTROL_GENERAL_WKUP + 0x010)
+#define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
+#define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
+
+/* 36xx-only RTA - Retention till Access control registers and bits */
+#define OMAP36XX_CONTROL_MEM_RTA_CTRL 0x40C
+#define OMAP36XX_RTA_DISABLE 0x0
+
+/* 34xx D2D idle-related pins, handled by PM core */
+#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
+#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
+
+/* TI816X CONTROL_DEVCONF register offsets */
+#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000)
+
+/*
+ * REVISIT: This list of registers is not comprehensive - there are more
+ * that should be added.
+ */
+
+/*
+ * Control module register bit defines - these should eventually go into
+ * their own regbits file. Some of these will be complicated, depending
+ * on the device type (general-purpose, emulator, test, secure, bad, other)
+ * and the security mode (secure, non-secure, don't care)
+ */
+/* CONTROL_DEVCONF0 bits */
+#define OMAP2_MMCSDIO1ADPCLKISEL (1 << 24) /* MMC1 loop back clock */
+#define OMAP24XX_USBSTANDBYCTRL (1 << 15)
+#define OMAP2_MCBSP2_CLKS_MASK (1 << 6)
+#define OMAP2_MCBSP1_FSR_MASK (1 << 4)
+#define OMAP2_MCBSP1_CLKR_MASK (1 << 3)
+#define OMAP2_MCBSP1_CLKS_MASK (1 << 2)
+
+/* CONTROL_DEVCONF1 bits */
+#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31)
+#define OMAP2_MMCSDIO2ADPCLKISEL (1 << 6) /* MMC2 loop back clock */
+#define OMAP2_MCBSP5_CLKS_MASK (1 << 4) /* > 242x */
+#define OMAP2_MCBSP4_CLKS_MASK (1 << 2) /* > 242x */
+#define OMAP2_MCBSP3_CLKS_MASK (1 << 0) /* > 242x */
+
+/* CONTROL_STATUS bits */
+#define OMAP2_DEVICETYPE_MASK (0x7 << 8)
+#define OMAP2_SYSBOOT_5_MASK (1 << 5)
+#define OMAP2_SYSBOOT_4_MASK (1 << 4)
+#define OMAP2_SYSBOOT_3_MASK (1 << 3)
+#define OMAP2_SYSBOOT_2_MASK (1 << 2)
+#define OMAP2_SYSBOOT_1_MASK (1 << 1)
+#define OMAP2_SYSBOOT_0_MASK (1 << 0)
+
+/* CONTROL_PBIAS_LITE bits */
+#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15)
+#define OMAP343X_PBIASLITEVMODEERROR1 (1 << 11)
+#define OMAP343X_PBIASSPEEDCTRL1 (1 << 10)
+#define OMAP343X_PBIASLITEPWRDNZ1 (1 << 9)
+#define OMAP343X_PBIASLITEVMODE1 (1 << 8)
+#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7)
+#define OMAP343X_PBIASLITEVMODEERROR0 (1 << 3)
+#define OMAP2_PBIASSPEEDCTRL0 (1 << 2)
+#define OMAP2_PBIASLITEPWRDNZ0 (1 << 1)
+#define OMAP2_PBIASLITEVMODE0 (1 << 0)
+
+/* CONTROL_PROG_IO1 bits */
+#define OMAP3630_PRG_SDMMC1_SPEEDCTRL (1 << 20)
+
+/* CONTROL_IVA2_BOOTMOD bits */
+#define OMAP3_IVA2_BOOTMOD_SHIFT 0
+#define OMAP3_IVA2_BOOTMOD_MASK (0xf << 0)
+#define OMAP3_IVA2_BOOTMOD_IDLE (0x1 << 0)
+
+/* CONTROL_PADCONF_X bits */
+#define OMAP3_PADCONF_WAKEUPEVENT0 (1 << 15)
+#define OMAP3_PADCONF_WAKEUPENABLE0 (1 << 14)
+
+#define OMAP343X_SCRATCHPAD_ROM (OMAP343X_CTRL_BASE + 0x860)
+#define OMAP343X_SCRATCHPAD (OMAP343X_CTRL_BASE + 0x910)
+#define OMAP343X_SCRATCHPAD_ROM_OFFSET 0x19C
+#define OMAP343X_SCRATCHPAD_REGADDR(reg) OMAP2_L4_IO_ADDRESS(\
+ OMAP343X_SCRATCHPAD + reg)
+
+/* AM35XX_CONTROL_IPSS_CLK_CTRL bits */
+#define AM35XX_USBOTG_VBUSP_CLK_SHIFT 0
+#define AM35XX_CPGMAC_VBUSP_CLK_SHIFT 1
+#define AM35XX_VPFE_VBUSP_CLK_SHIFT 2
+#define AM35XX_HECC_VBUSP_CLK_SHIFT 3
+#define AM35XX_USBOTG_FCLK_SHIFT 8
+#define AM35XX_CPGMAC_FCLK_SHIFT 9
+#define AM35XX_VPFE_FCLK_SHIFT 10
+
+/*AM35XX CONTROL_LVL_INTR_CLEAR bits*/
+#define AM35XX_CPGMAC_C0_MISC_PULSE_CLR BIT(0)
+#define AM35XX_CPGMAC_C0_RX_PULSE_CLR BIT(1)
+#define AM35XX_CPGMAC_C0_RX_THRESH_CLR BIT(2)
+#define AM35XX_CPGMAC_C0_TX_PULSE_CLR BIT(3)
+#define AM35XX_USBOTGSS_INT_CLR BIT(4)
+#define AM35XX_VPFE_CCDC_VD0_INT_CLR BIT(5)
+#define AM35XX_VPFE_CCDC_VD1_INT_CLR BIT(6)
+#define AM35XX_VPFE_CCDC_VD2_INT_CLR BIT(7)
+
+/*AM35XX CONTROL_IP_SW_RESET bits*/
+#define AM35XX_USBOTGSS_SW_RST BIT(0)
+#define AM35XX_CPGMACSS_SW_RST BIT(1)
+#define AM35XX_VPFE_VBUSP_SW_RST BIT(2)
+#define AM35XX_HECC_SW_RST BIT(3)
+#define AM35XX_VPFE_PCLK_SW_RST BIT(4)
+
+/*
+ * CONTROL OMAP STATUS register to identify OMAP3 features
+ */
+#define OMAP3_CONTROL_OMAP_STATUS 0x044c
+
+#define OMAP3_SGX_SHIFT 13
+#define OMAP3_SGX_MASK (3 << OMAP3_SGX_SHIFT)
+#define FEAT_SGX_FULL 0
+#define FEAT_SGX_HALF 1
+#define FEAT_SGX_NONE 2
+
+#define OMAP3_IVA_SHIFT 12
+#define OMAP3_IVA_MASK (1 << OMAP3_IVA_SHIFT)
+#define FEAT_IVA 0
+#define FEAT_IVA_NONE 1
+
+#define OMAP3_L2CACHE_SHIFT 10
+#define OMAP3_L2CACHE_MASK (3 << OMAP3_L2CACHE_SHIFT)
+#define FEAT_L2CACHE_NONE 0
+#define FEAT_L2CACHE_64KB 1
+#define FEAT_L2CACHE_128KB 2
+#define FEAT_L2CACHE_256KB 3
+
+#define OMAP3_ISP_SHIFT 5
+#define OMAP3_ISP_MASK (1 << OMAP3_ISP_SHIFT)
+#define FEAT_ISP 0
+#define FEAT_ISP_NONE 1
+
+#define OMAP3_NEON_SHIFT 4
+#define OMAP3_NEON_MASK (1 << OMAP3_NEON_SHIFT)
+#define FEAT_NEON 0
+#define FEAT_NEON_NONE 1
+
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_ARCH_OMAP2PLUS
+extern void __iomem *omap_ctrl_base_get(void);
+extern u8 omap_ctrl_readb(u16 offset);
+extern u16 omap_ctrl_readw(u16 offset);
+extern u32 omap_ctrl_readl(u16 offset);
+extern u32 omap4_ctrl_pad_readl(u16 offset);
+extern void omap_ctrl_writeb(u8 val, u16 offset);
+extern void omap_ctrl_writew(u16 val, u16 offset);
+extern void omap_ctrl_writel(u32 val, u16 offset);
+extern void omap4_ctrl_pad_writel(u32 val, u16 offset);
+
+extern void omap3_save_scratchpad_contents(void);
+extern void omap3_clear_scratchpad_contents(void);
+extern u32 *get_restore_pointer(void);
+extern u32 *get_es3_restore_pointer(void);
+extern u32 *get_omap3630_restore_pointer(void);
+extern u32 omap3_arm_context[128];
+extern void omap3_control_save_context(void);
+extern void omap3_control_restore_context(void);
+extern void omap3_ctrl_write_boot_mode(u8 bootmode);
+extern void omap3630_ctrl_disable_rta(void);
+extern int omap3_ctrl_save_padconf(void);
+#else
+#define omap_ctrl_base_get() 0
+#define omap_ctrl_readb(x) 0
+#define omap_ctrl_readw(x) 0
+#define omap_ctrl_readl(x) 0
+#define omap4_ctrl_pad_readl(x) 0
+#define omap_ctrl_writeb(x, y) WARN_ON(1)
+#define omap_ctrl_writew(x, y) WARN_ON(1)
+#define omap_ctrl_writel(x, y) WARN_ON(1)
+#define omap4_ctrl_pad_writel(x, y) WARN_ON(1)
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM_MACH_OMAP2_CONTROL_H */
+
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
new file mode 100644
index 00000000..4bf6e6e8
--- /dev/null
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -0,0 +1,405 @@
+/*
+ * linux/arch/arm/mach-omap2/cpuidle34xx.c
+ *
+ * OMAP3 CPU IDLE Routines
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Karthik Dasu <karthik-dp@ti.com>
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Based on pm.c for omap2
+ *
+ * This program is free software; you can 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/cpuidle.h>
+
+#include <plat/prcm.h>
+#include <plat/irqs.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include <plat/serial.h>
+
+#include "pm.h"
+#include "control.h"
+
+#ifdef CONFIG_CPU_IDLE
+
+/*
+ * The latencies/thresholds for various C states have
+ * to be configured from the respective board files.
+ * These are some default values (which might not provide
+ * the best power savings) used on boards which do not
+ * pass these details from the board file.
+ */
+static struct cpuidle_params cpuidle_params_table[] = {
+ /* C1 */
+ {2 + 2, 5, 1},
+ /* C2 */
+ {10 + 10, 30, 1},
+ /* C3 */
+ {50 + 50, 300, 1},
+ /* C4 */
+ {1500 + 1800, 4000, 1},
+ /* C5 */
+ {2500 + 7500, 12000, 1},
+ /* C6 */
+ {3000 + 8500, 15000, 1},
+ /* C7 */
+ {10000 + 30000, 300000, 1},
+};
+#define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
+
+/* Mach specific information to be recorded in the C-state driver_data */
+struct omap3_idle_statedata {
+ u32 mpu_state;
+ u32 core_state;
+ u8 valid;
+};
+struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES];
+
+struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
+
+static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm)
+{
+ clkdm_allow_idle(clkdm);
+ return 0;
+}
+
+static int _cpuidle_deny_idle(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm)
+{
+ clkdm_deny_idle(clkdm);
+ return 0;
+}
+
+/**
+ * omap3_enter_idle - Programs OMAP3 to enter the specified state
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * Called from the CPUidle framework to program the device to the
+ * specified target state selected by the governor.
+ */
+static int omap3_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
+ struct timespec ts_preidle, ts_postidle, ts_idle;
+ u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
+
+ /* Used to keep track of the total time in idle */
+ getnstimeofday(&ts_preidle);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ pwrdm_set_next_pwrst(mpu_pd, mpu_state);
+ pwrdm_set_next_pwrst(core_pd, core_state);
+
+ if (omap_irq_pending() || need_resched())
+ goto return_sleep_time;
+
+ /* Deny idle for C1 */
+ if (state == &dev->states[0]) {
+ pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
+ pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
+ }
+
+ /* Execute ARM wfi */
+ omap_sram_idle();
+
+ /* Re-allow idle for C1 */
+ if (state == &dev->states[0]) {
+ pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
+ pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
+ }
+
+return_sleep_time:
+ getnstimeofday(&ts_postidle);
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ return ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC;
+}
+
+/**
+ * next_valid_state - Find next valid C-state
+ * @dev: cpuidle device
+ * @state: Currently selected C-state
+ *
+ * If the current state is valid, it is returned back to the caller.
+ * Else, this function searches for a lower c-state which is still
+ * valid.
+ *
+ * A state is valid if the 'valid' field is enabled and
+ * if it satisfies the enable_off_mode condition.
+ */
+static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
+ struct cpuidle_state *curr)
+{
+ struct cpuidle_state *next = NULL;
+ struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+ u32 mpu_deepest_state = PWRDM_POWER_RET;
+ u32 core_deepest_state = PWRDM_POWER_RET;
+
+ if (enable_off_mode) {
+ mpu_deepest_state = PWRDM_POWER_OFF;
+ /*
+ * Erratum i583: valable for ES rev < Es1.2 on 3630.
+ * CORE OFF mode is not supported in a stable form, restrict
+ * instead the CORE state to RET.
+ */
+ if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
+ core_deepest_state = PWRDM_POWER_OFF;
+ }
+
+ /* Check if current state is valid */
+ if ((cx->valid) &&
+ (cx->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state)) {
+ return curr;
+ } else {
+ int idx = OMAP3_NUM_STATES - 1;
+
+ /* Reach the current state starting at highest C-state */
+ for (; idx >= 0; idx--) {
+ if (&dev->states[idx] == curr) {
+ next = &dev->states[idx];
+ break;
+ }
+ }
+
+ /* Should never hit this condition */
+ WARN_ON(next == NULL);
+
+ /*
+ * Drop to next valid state.
+ * Start search from the next (lower) state.
+ */
+ idx--;
+ for (; idx >= 0; idx--) {
+ cx = cpuidle_get_statedata(&dev->states[idx]);
+ if ((cx->valid) &&
+ (cx->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state)) {
+ next = &dev->states[idx];
+ break;
+ }
+ }
+ /*
+ * C1 is always valid.
+ * So, no need to check for 'next==NULL' outside this loop.
+ */
+ }
+
+ return next;
+}
+
+/**
+ * omap3_enter_idle_bm - Checks for any bus activity
+ * @dev: cpuidle device
+ * @state: The target state to be programmed
+ *
+ * This function checks for any pending activity and then programs
+ * the device to the specified or a safer state.
+ */
+static int omap3_enter_idle_bm(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct cpuidle_state *new_state;
+ u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
+ struct omap3_idle_statedata *cx;
+ int ret;
+
+ if (!omap3_can_sleep()) {
+ new_state = dev->safe_state;
+ goto select_state;
+ }
+
+ /*
+ * Prevent idle completely if CAM is active.
+ * CAM does not have wakeup capability in OMAP3.
+ */
+ cam_state = pwrdm_read_pwrst(cam_pd);
+ if (cam_state == PWRDM_POWER_ON) {
+ new_state = dev->safe_state;
+ goto select_state;
+ }
+
+ /*
+ * FIXME: we currently manage device-specific idle states
+ * for PER and CORE in combination with CPU-specific
+ * idle states. This is wrong, and device-specific
+ * idle management needs to be separated out into
+ * its own code.
+ */
+
+ /*
+ * Prevent PER off if CORE is not in retention or off as this
+ * would disable PER wakeups completely.
+ */
+ cx = cpuidle_get_statedata(state);
+ core_next_state = cx->core_state;
+ per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
+ if ((per_next_state == PWRDM_POWER_OFF) &&
+ (core_next_state > PWRDM_POWER_RET))
+ per_next_state = PWRDM_POWER_RET;
+
+ /* Are we changing PER target state? */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_next_state);
+
+ new_state = next_valid_state(dev, state);
+
+select_state:
+ dev->last_state = new_state;
+ ret = omap3_enter_idle(dev, new_state);
+
+ /* Restore original PER state if it was modified */
+ if (per_next_state != per_saved_state)
+ pwrdm_set_next_pwrst(per_pd, per_saved_state);
+
+ return ret;
+}
+
+DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
+
+void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
+{
+ int i;
+
+ if (!cpuidle_board_params)
+ return;
+
+ for (i = 0; i < OMAP3_NUM_STATES; i++) {
+ cpuidle_params_table[i].valid = cpuidle_board_params[i].valid;
+ cpuidle_params_table[i].exit_latency =
+ cpuidle_board_params[i].exit_latency;
+ cpuidle_params_table[i].target_residency =
+ cpuidle_board_params[i].target_residency;
+ }
+ return;
+}
+
+struct cpuidle_driver omap3_idle_driver = {
+ .name = "omap3_idle",
+ .owner = THIS_MODULE,
+};
+
+/* Helper to fill the C-state common data and register the driver_data */
+static inline struct omap3_idle_statedata *_fill_cstate(
+ struct cpuidle_device *dev,
+ int idx, const char *descr)
+{
+ struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
+ struct cpuidle_state *state = &dev->states[idx];
+
+ state->exit_latency = cpuidle_params_table[idx].exit_latency;
+ state->target_residency = cpuidle_params_table[idx].target_residency;
+ state->flags = CPUIDLE_FLAG_TIME_VALID;
+ state->enter = omap3_enter_idle_bm;
+ cx->valid = cpuidle_params_table[idx].valid;
+ sprintf(state->name, "C%d", idx + 1);
+ strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
+ cpuidle_set_statedata(state, cx);
+
+ return cx;
+}
+
+/**
+ * omap3_idle_init - Init routine for OMAP3 idle
+ *
+ * Registers the OMAP3 specific cpuidle driver to the cpuidle
+ * framework with the valid set of states.
+ */
+int __init omap3_idle_init(void)
+{
+ struct cpuidle_device *dev;
+ struct omap3_idle_statedata *cx;
+
+ mpu_pd = pwrdm_lookup("mpu_pwrdm");
+ core_pd = pwrdm_lookup("core_pwrdm");
+ per_pd = pwrdm_lookup("per_pwrdm");
+ cam_pd = pwrdm_lookup("cam_pwrdm");
+
+ cpuidle_register_driver(&omap3_idle_driver);
+ dev = &per_cpu(omap3_idle_dev, smp_processor_id());
+
+ /* C1 . MPU WFI + Core active */
+ cx = _fill_cstate(dev, 0, "MPU ON + CORE ON");
+ (&dev->states[0])->enter = omap3_enter_idle;
+ dev->safe_state = &dev->states[0];
+ cx->valid = 1; /* C1 is always valid */
+ cx->mpu_state = PWRDM_POWER_ON;
+ cx->core_state = PWRDM_POWER_ON;
+
+ /* C2 . MPU WFI + Core inactive */
+ cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
+ cx->mpu_state = PWRDM_POWER_ON;
+ cx->core_state = PWRDM_POWER_ON;
+
+ /* C3 . MPU CSWR + Core inactive */
+ cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
+ cx->mpu_state = PWRDM_POWER_RET;
+ cx->core_state = PWRDM_POWER_ON;
+
+ /* C4 . MPU OFF + Core inactive */
+ cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
+ cx->mpu_state = PWRDM_POWER_OFF;
+ cx->core_state = PWRDM_POWER_ON;
+
+ /* C5 . MPU RET + Core RET */
+ cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
+ cx->mpu_state = PWRDM_POWER_RET;
+ cx->core_state = PWRDM_POWER_RET;
+
+ /* C6 . MPU OFF + Core RET */
+ cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
+ cx->mpu_state = PWRDM_POWER_OFF;
+ cx->core_state = PWRDM_POWER_RET;
+
+ /* C7 . MPU OFF + Core OFF */
+ cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
+ /*
+ * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+ * enable OFF mode in a stable form for previous revisions.
+ * We disable C7 state as a result.
+ */
+ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
+ cx->valid = 0;
+ pr_warn("%s: core off state C7 disabled due to i583\n",
+ __func__);
+ }
+ cx->mpu_state = PWRDM_POWER_OFF;
+ cx->core_state = PWRDM_POWER_OFF;
+
+ dev->state_count = OMAP3_NUM_STATES;
+ if (cpuidle_register_device(dev)) {
+ printk(KERN_ERR "%s: CPUidle register device failed\n",
+ __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+#else
+int __init omap3_idle_init(void)
+{
+ return 0;
+}
+#endif /* CONFIG_CPU_IDLE */
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
new file mode 100644
index 00000000..5b8ca680
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.c
@@ -0,0 +1,733 @@
+/*
+ * linux/arch/arm/mach-omap2/devices.c
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/pmu.h>
+
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/mcbsp.h>
+#include <mach/gpio.h>
+#include <plat/mmc.h>
+#include <plat/dma.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/omap4-keypad.h>
+
+#include "mux.h"
+#include "control.h"
+#include "devices.h"
+
+#define L3_MODULES_MAX_LEN 12
+#define L3_MODULES 3
+
+static int __init omap3_l3_init(void)
+{
+ int l;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ char oh_name[L3_MODULES_MAX_LEN];
+
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!(cpu_is_omap34xx()))
+ return -ENODEV;
+
+ l = snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main");
+
+ oh = omap_hwmod_lookup(oh_name);
+
+ if (!oh)
+ pr_err("could not look up %s\n", oh_name);
+
+ od = omap_device_build("omap_l3_smx", 0, oh, NULL, 0,
+ NULL, 0, 0);
+
+ WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
+
+ return IS_ERR(od) ? PTR_ERR(od) : 0;
+}
+postcore_initcall(omap3_l3_init);
+
+static int __init omap4_l3_init(void)
+{
+ int l, i;
+ struct omap_hwmod *oh[3];
+ struct omap_device *od;
+ char oh_name[L3_MODULES_MAX_LEN];
+
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!(cpu_is_omap44xx()))
+ return -ENODEV;
+
+ for (i = 0; i < L3_MODULES; i++) {
+ l = snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main_%d", i+1);
+
+ oh[i] = omap_hwmod_lookup(oh_name);
+ if (!(oh[i]))
+ pr_err("could not look up %s\n", oh_name);
+ }
+
+ od = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL,
+ 0, NULL, 0, 0);
+
+ WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
+
+ return IS_ERR(od) ? PTR_ERR(od) : 0;
+}
+postcore_initcall(omap4_l3_init);
+
+#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
+
+static struct resource omap2cam_resources[] = {
+ {
+ .start = OMAP24XX_CAMERA_BASE,
+ .end = OMAP24XX_CAMERA_BASE + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_CAM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device omap2cam_device = {
+ .name = "omap24xxcam",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap2cam_resources),
+ .resource = omap2cam_resources,
+};
+#endif
+
+static struct resource omap3isp_resources[] = {
+ {
+ .start = OMAP3430_ISP_BASE,
+ .end = OMAP3430_ISP_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCP2_BASE,
+ .end = OMAP3430_ISP_CCP2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCDC_BASE,
+ .end = OMAP3430_ISP_CCDC_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_HIST_BASE,
+ .end = OMAP3430_ISP_HIST_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_H3A_BASE,
+ .end = OMAP3430_ISP_H3A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_PREV_BASE,
+ .end = OMAP3430_ISP_PREV_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_RESZ_BASE,
+ .end = OMAP3430_ISP_RESZ_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_SBL_BASE,
+ .end = OMAP3430_ISP_SBL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2A_REGS1_BASE,
+ .end = OMAP3430_ISP_CSI2A_REGS1_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSIPHY2_BASE,
+ .end = OMAP3430_ISP_CSIPHY2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3630_ISP_CSI2A_REGS2_BASE,
+ .end = OMAP3630_ISP_CSI2A_REGS2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3630_ISP_CSI2C_REGS1_BASE,
+ .end = OMAP3630_ISP_CSI2C_REGS1_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3630_ISP_CSIPHY1_BASE,
+ .end = OMAP3630_ISP_CSIPHY1_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3630_ISP_CSI2C_REGS2_BASE,
+ .end = OMAP3630_ISP_CSI2C_REGS2_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_34XX_CAM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device omap3isp_device = {
+ .name = "omap3isp",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap3isp_resources),
+ .resource = omap3isp_resources,
+};
+
+int omap3_init_camera(struct isp_platform_data *pdata)
+{
+ omap3isp_device.dev.platform_data = pdata;
+ return platform_device_register(&omap3isp_device);
+}
+
+static inline void omap_init_camera(void)
+{
+#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
+ if (cpu_is_omap24xx())
+ platform_device_register(&omap2cam_device);
+#endif
+}
+
+struct omap_device_pm_latency omap_keyboard_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+int __init omap4_keyboard_init(struct omap4_keypad_platform_data
+ *sdp4430_keypad_data)
+{
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+ struct omap4_keypad_platform_data *keypad_data;
+ unsigned int id = -1;
+ char *oh_name = "kbd";
+ char *name = "omap4-keypad";
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -ENODEV;
+ }
+
+ keypad_data = sdp4430_keypad_data;
+
+ od = omap_device_build(name, id, oh, keypad_data,
+ sizeof(struct omap4_keypad_platform_data),
+ omap_keyboard_latency,
+ ARRAY_SIZE(omap_keyboard_latency), 0);
+
+ if (IS_ERR(od)) {
+ WARN(1, "Can't build omap_device for %s:%s.\n",
+ name, oh->name);
+ return PTR_ERR(od);
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
+static struct omap_device_pm_latency mbox_latencies[] = {
+ [0] = {
+ .activate_func = omap_device_enable_hwmods,
+ .deactivate_func = omap_device_idle_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static inline void omap_init_mbox(void)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+
+ oh = omap_hwmod_lookup("mailbox");
+ if (!oh) {
+ pr_err("%s: unable to find hwmod\n", __func__);
+ return;
+ }
+
+ od = omap_device_build("omap-mailbox", -1, oh, NULL, 0,
+ mbox_latencies, ARRAY_SIZE(mbox_latencies), 0);
+ WARN(IS_ERR(od), "%s: could not build device, err %ld\n",
+ __func__, PTR_ERR(od));
+}
+#else
+static inline void omap_init_mbox(void) { }
+#endif /* CONFIG_OMAP_MBOX_FWK */
+
+static inline void omap_init_sti(void) {}
+
+#if defined(CONFIG_SND_SOC) || defined(CONFIG_SND_SOC_MODULE)
+
+static struct platform_device omap_pcm = {
+ .name = "omap-pcm-audio",
+ .id = -1,
+};
+
+/*
+ * OMAP2420 has 2 McBSP ports
+ * OMAP2430 has 5 McBSP ports
+ * OMAP3 has 5 McBSP ports
+ * OMAP4 has 4 McBSP ports
+ */
+OMAP_MCBSP_PLATFORM_DEVICE(1);
+OMAP_MCBSP_PLATFORM_DEVICE(2);
+OMAP_MCBSP_PLATFORM_DEVICE(3);
+OMAP_MCBSP_PLATFORM_DEVICE(4);
+OMAP_MCBSP_PLATFORM_DEVICE(5);
+
+static void omap_init_audio(void)
+{
+ platform_device_register(&omap_mcbsp1);
+ platform_device_register(&omap_mcbsp2);
+ if (cpu_is_omap243x() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ platform_device_register(&omap_mcbsp3);
+ platform_device_register(&omap_mcbsp4);
+ }
+ if (cpu_is_omap243x() || cpu_is_omap34xx())
+ platform_device_register(&omap_mcbsp5);
+
+ platform_device_register(&omap_pcm);
+}
+
+#else
+static inline void omap_init_audio(void) {}
+#endif
+
+#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
+
+#include <plat/mcspi.h>
+
+struct omap_device_pm_latency omap_mcspi_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
+{
+ struct omap_device *od;
+ char *name = "omap2_mcspi";
+ struct omap2_mcspi_platform_config *pdata;
+ static int spi_num;
+ struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr;
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("Memory allocation for McSPI device failed\n");
+ return -ENOMEM;
+ }
+
+ pdata->num_cs = mcspi_attrib->num_chipselect;
+ switch (oh->class->rev) {
+ case OMAP2_MCSPI_REV:
+ case OMAP3_MCSPI_REV:
+ pdata->regs_offset = 0;
+ break;
+ case OMAP4_MCSPI_REV:
+ pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET;
+ break;
+ default:
+ pr_err("Invalid McSPI Revision value\n");
+ return -EINVAL;
+ }
+
+ spi_num++;
+ od = omap_device_build(name, spi_num, oh, pdata,
+ sizeof(*pdata), omap_mcspi_latency,
+ ARRAY_SIZE(omap_mcspi_latency), 0);
+ WARN(IS_ERR(od), "Can't build omap_device for %s:%s\n",
+ name, oh->name);
+ kfree(pdata);
+ return 0;
+}
+
+static void omap_init_mcspi(void)
+{
+ omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL);
+}
+
+#else
+static inline void omap_init_mcspi(void) {}
+#endif
+
+static struct resource omap2_pmu_resource = {
+ .start = 3,
+ .end = 3,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct resource omap3_pmu_resource = {
+ .start = INT_34XX_BENCH_MPU_EMUL,
+ .end = INT_34XX_BENCH_MPU_EMUL,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device omap_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = 1,
+};
+
+static void omap_init_pmu(void)
+{
+ if (cpu_is_omap24xx())
+ omap_pmu_device.resource = &omap2_pmu_resource;
+ else if (cpu_is_omap34xx())
+ omap_pmu_device.resource = &omap3_pmu_resource;
+ else
+ return;
+
+ platform_device_register(&omap_pmu_device);
+}
+
+
+#if defined(CONFIG_CRYPTO_DEV_OMAP_SHAM) || defined(CONFIG_CRYPTO_DEV_OMAP_SHAM_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct resource omap2_sham_resources[] = {
+ {
+ .start = OMAP24XX_SEC_SHA1MD5_BASE,
+ .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_SHA1MD5,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+static int omap2_sham_resources_sz = ARRAY_SIZE(omap2_sham_resources);
+#else
+#define omap2_sham_resources NULL
+#define omap2_sham_resources_sz 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct resource omap3_sham_resources[] = {
+ {
+ .start = OMAP34XX_SEC_SHA1MD5_BASE,
+ .end = OMAP34XX_SEC_SHA1MD5_BASE + 0x64,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_34XX_SHA1MD52_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = OMAP34XX_DMA_SHA1MD5_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+static int omap3_sham_resources_sz = ARRAY_SIZE(omap3_sham_resources);
+#else
+#define omap3_sham_resources NULL
+#define omap3_sham_resources_sz 0
+#endif
+
+static struct platform_device sham_device = {
+ .name = "omap-sham",
+ .id = -1,
+};
+
+static void omap_init_sham(void)
+{
+ if (cpu_is_omap24xx()) {
+ sham_device.resource = omap2_sham_resources;
+ sham_device.num_resources = omap2_sham_resources_sz;
+ } else if (cpu_is_omap34xx()) {
+ sham_device.resource = omap3_sham_resources;
+ sham_device.num_resources = omap3_sham_resources_sz;
+ } else {
+ pr_err("%s: platform not supported\n", __func__);
+ return;
+ }
+ platform_device_register(&sham_device);
+}
+#else
+static inline void omap_init_sham(void) { }
+#endif
+
+#if defined(CONFIG_CRYPTO_DEV_OMAP_AES) || defined(CONFIG_CRYPTO_DEV_OMAP_AES_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct resource omap2_aes_resources[] = {
+ {
+ .start = OMAP24XX_SEC_AES_BASE,
+ .end = OMAP24XX_SEC_AES_BASE + 0x4C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP24XX_DMA_AES_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = OMAP24XX_DMA_AES_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+static int omap2_aes_resources_sz = ARRAY_SIZE(omap2_aes_resources);
+#else
+#define omap2_aes_resources NULL
+#define omap2_aes_resources_sz 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct resource omap3_aes_resources[] = {
+ {
+ .start = OMAP34XX_SEC_AES_BASE,
+ .end = OMAP34XX_SEC_AES_BASE + 0x4C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP34XX_DMA_AES2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ {
+ .start = OMAP34XX_DMA_AES2_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+static int omap3_aes_resources_sz = ARRAY_SIZE(omap3_aes_resources);
+#else
+#define omap3_aes_resources NULL
+#define omap3_aes_resources_sz 0
+#endif
+
+static struct platform_device aes_device = {
+ .name = "omap-aes",
+ .id = -1,
+};
+
+static void omap_init_aes(void)
+{
+ if (cpu_is_omap24xx()) {
+ aes_device.resource = omap2_aes_resources;
+ aes_device.num_resources = omap2_aes_resources_sz;
+ } else if (cpu_is_omap34xx()) {
+ aes_device.resource = omap3_aes_resources;
+ aes_device.num_resources = omap3_aes_resources_sz;
+ } else {
+ pr_err("%s: platform not supported\n", __func__);
+ return;
+ }
+ platform_device_register(&aes_device);
+}
+
+#else
+static inline void omap_init_aes(void) { }
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap242x_mmc_mux(struct omap_mmc_platform_data
+ *mmc_controller)
+{
+ if ((mmc_controller->slots[0].switch_pin > 0) && \
+ (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
+ OMAP_PIN_INPUT_PULLUP);
+ if ((mmc_controller->slots[0].gpio_wp > 0) && \
+ (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
+ OMAP_PIN_INPUT_PULLUP);
+
+ omap_mux_init_signal("sdmmc_cmd", 0);
+ omap_mux_init_signal("sdmmc_clki", 0);
+ omap_mux_init_signal("sdmmc_clko", 0);
+ omap_mux_init_signal("sdmmc_dat0", 0);
+ omap_mux_init_signal("sdmmc_dat_dir0", 0);
+ omap_mux_init_signal("sdmmc_cmd_dir", 0);
+ if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) {
+ omap_mux_init_signal("sdmmc_dat1", 0);
+ omap_mux_init_signal("sdmmc_dat2", 0);
+ omap_mux_init_signal("sdmmc_dat3", 0);
+ omap_mux_init_signal("sdmmc_dat_dir1", 0);
+ omap_mux_init_signal("sdmmc_dat_dir2", 0);
+ omap_mux_init_signal("sdmmc_dat_dir3", 0);
+ }
+
+ /*
+ * Use internal loop-back in MMC/SDIO Module Input Clock
+ * selection
+ */
+ if (mmc_controller->slots[0].internal_clock) {
+ u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ v |= (1 << 24);
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+ }
+}
+
+void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
+{
+ char *name = "mmci-omap";
+
+ if (!mmc_data[0]) {
+ pr_err("%s fails: Incomplete platform data\n", __func__);
+ return;
+ }
+
+ omap242x_mmc_mux(mmc_data[0]);
+ omap_mmc_add(name, 0, OMAP2_MMC1_BASE, OMAP2420_MMC_SIZE,
+ INT_24XX_MMC_IRQ, mmc_data[0]);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430)
+#define OMAP_HDQ_BASE 0x480B2000
+#endif
+static struct resource omap_hdq_resources[] = {
+ {
+ .start = OMAP_HDQ_BASE,
+ .end = OMAP_HDQ_BASE + 0x1C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_HDQ_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device omap_hdq_dev = {
+ .name = "omap_hdq",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+ .num_resources = ARRAY_SIZE(omap_hdq_resources),
+ .resource = omap_hdq_resources,
+};
+static inline void omap_hdq_init(void)
+{
+ (void) platform_device_register(&omap_hdq_dev);
+}
+#else
+static inline void omap_hdq_init(void) {}
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
+ defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
+#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
+};
+#else
+static struct resource omap_vout_resource[2] = {
+};
+#endif
+
+static struct platform_device omap_vout_device = {
+ .name = "omap_vout",
+ .num_resources = ARRAY_SIZE(omap_vout_resource),
+ .resource = &omap_vout_resource[0],
+ .id = -1,
+};
+static void omap_init_vout(void)
+{
+ if (platform_device_register(&omap_vout_device) < 0)
+ printk(KERN_ERR "Unable to register OMAP-VOUT device\n");
+}
+#else
+static inline void omap_init_vout(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int __init omap2_init_devices(void)
+{
+ /*
+ * please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_audio();
+ omap_init_camera();
+ omap_init_mbox();
+ omap_init_mcspi();
+ omap_init_pmu();
+ omap_hdq_init();
+ omap_init_sti();
+ omap_init_sham();
+ omap_init_aes();
+ omap_init_vout();
+
+ return 0;
+}
+arch_initcall(omap2_init_devices);
+
+#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
+static struct omap_device_pm_latency omap_wdt_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int __init omap_init_wdt(void)
+{
+ int id = -1;
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+
+ if (!cpu_class_is_omap2())
+ return 0;
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up wd_timer%d hwmod\n", id);
+ return -EINVAL;
+ }
+
+ od = omap_device_build(dev_name, id, oh, NULL, 0,
+ omap_wdt_latency,
+ ARRAY_SIZE(omap_wdt_latency), 0);
+ WARN(IS_ERR(od), "Can't build omap_device for %s:%s.\n",
+ dev_name, oh->name);
+ return 0;
+}
+subsys_initcall(omap_init_wdt);
+#endif
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
new file mode 100644
index 00000000..f61eb6e5
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-omap2/devices.h
+ *
+ * OMAP2 platform device setup/initialization
+ *
+ * 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 __ARCH_ARM_MACH_OMAP_DEVICES_H
+#define __ARCH_ARM_MACH_OMAP_DEVICES_H
+
+struct isp_platform_data;
+
+int omap3_init_camera(struct isp_platform_data *pdata);
+
+#endif
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
new file mode 100644
index 00000000..543fcb8b
--- /dev/null
+++ b/arch/arm/mach-omap2/display.c
@@ -0,0 +1,148 @@
+/*
+ * OMAP2plus display device setup / initialization.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Senthilvadivu Guruswamy
+ * Sumit Semwal
+ *
+ * This program is free software; you can 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 "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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <video/omapdss.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct platform_device omap_display_device = {
+ .name = "omapdss",
+ .id = -1,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+static struct omap_device_pm_latency omap_dss_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+/* oh_core is used for getting opt-clocks */
+static struct omap_hwmod *oh_core;
+
+static bool opt_clock_available(const char *clk_role)
+{
+ int i;
+
+ for (i = 0; i < oh_core->opt_clks_cnt; i++) {
+ if (!strcmp(oh_core->opt_clks[i].role, clk_role))
+ return true;
+ }
+ return false;
+}
+
+struct omap_dss_hwmod_data {
+ const char *oh_name;
+ const char *dev_name;
+ const int id;
+};
+
+static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initdata = {
+ { "dss_core", "omapdss_dss", -1 },
+ { "dss_dispc", "omapdss_dispc", -1 },
+ { "dss_rfbi", "omapdss_rfbi", -1 },
+ { "dss_venc", "omapdss_venc", -1 },
+};
+
+static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
+ { "dss_core", "omapdss_dss", -1 },
+ { "dss_dispc", "omapdss_dispc", -1 },
+ { "dss_rfbi", "omapdss_rfbi", -1 },
+ { "dss_venc", "omapdss_venc", -1 },
+ { "dss_dsi1", "omapdss_dsi1", -1 },
+};
+
+static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
+ { "dss_core", "omapdss_dss", -1 },
+ { "dss_dispc", "omapdss_dispc", -1 },
+ { "dss_rfbi", "omapdss_rfbi", -1 },
+ { "dss_venc", "omapdss_venc", -1 },
+ { "dss_dsi1", "omapdss_dsi1", -1 },
+ { "dss_dsi2", "omapdss_dsi2", -1 },
+ { "dss_hdmi", "omapdss_hdmi", -1 },
+};
+
+int __init omap_display_init(struct omap_dss_board_info *board_data)
+{
+ int r = 0;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ int i, oh_count;
+ struct omap_display_platform_data pdata;
+ const struct omap_dss_hwmod_data *curr_dss_hwmod;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ if (cpu_is_omap24xx()) {
+ curr_dss_hwmod = omap2_dss_hwmod_data;
+ oh_count = ARRAY_SIZE(omap2_dss_hwmod_data);
+ } else if (cpu_is_omap34xx()) {
+ curr_dss_hwmod = omap3_dss_hwmod_data;
+ oh_count = ARRAY_SIZE(omap3_dss_hwmod_data);
+ } else {
+ curr_dss_hwmod = omap4_dss_hwmod_data;
+ oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
+ }
+
+ /* opt_clks are always associated with dss hwmod */
+ oh_core = omap_hwmod_lookup("dss_core");
+ if (!oh_core) {
+ pr_err("Could not look up dss_core.\n");
+ return -ENODEV;
+ }
+
+ pdata.board_data = board_data;
+ pdata.board_data->get_last_off_on_transaction_id = NULL;
+ pdata.opt_clock_available = opt_clock_available;
+
+ for (i = 0; i < oh_count; i++) {
+ oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n",
+ curr_dss_hwmod[i].oh_name);
+ return -ENODEV;
+ }
+
+ od = omap_device_build(curr_dss_hwmod[i].dev_name,
+ curr_dss_hwmod[i].id, oh, &pdata,
+ sizeof(struct omap_display_platform_data),
+ omap_dss_latency,
+ ARRAY_SIZE(omap_dss_latency), 0);
+
+ if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
+ curr_dss_hwmod[i].oh_name))
+ return -ENODEV;
+ }
+ omap_display_device.dev.platform_data = board_data;
+
+ r = platform_device_register(&omap_display_device);
+ if (r < 0)
+ printk(KERN_ERR "Unable to register OMAP-Display device\n");
+
+ return r;
+}
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
new file mode 100644
index 00000000..c9ff0e79
--- /dev/null
+++ b/arch/arm/mach-omap2/dma.c
@@ -0,0 +1,297 @@
+/*
+ * OMAP2+ DMA driver
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into platform driver
+ * - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/dma.h>
+
+#define OMAP2_DMA_STRIDE 0x60
+
+static u32 errata;
+static u8 dma_stride;
+
+static struct omap_dma_dev_attr *d;
+
+static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end;
+
+static u16 reg_map[] = {
+ [REVISION] = 0x00,
+ [GCR] = 0x78,
+ [IRQSTATUS_L0] = 0x08,
+ [IRQSTATUS_L1] = 0x0c,
+ [IRQSTATUS_L2] = 0x10,
+ [IRQSTATUS_L3] = 0x14,
+ [IRQENABLE_L0] = 0x18,
+ [IRQENABLE_L1] = 0x1c,
+ [IRQENABLE_L2] = 0x20,
+ [IRQENABLE_L3] = 0x24,
+ [SYSSTATUS] = 0x28,
+ [OCP_SYSCONFIG] = 0x2c,
+ [CAPS_0] = 0x64,
+ [CAPS_2] = 0x6c,
+ [CAPS_3] = 0x70,
+ [CAPS_4] = 0x74,
+
+ /* Common register offsets */
+ [CCR] = 0x80,
+ [CLNK_CTRL] = 0x84,
+ [CICR] = 0x88,
+ [CSR] = 0x8c,
+ [CSDP] = 0x90,
+ [CEN] = 0x94,
+ [CFN] = 0x98,
+ [CSEI] = 0xa4,
+ [CSFI] = 0xa8,
+ [CDEI] = 0xac,
+ [CDFI] = 0xb0,
+ [CSAC] = 0xb4,
+ [CDAC] = 0xb8,
+
+ /* Channel specific register offsets */
+ [CSSA] = 0x9c,
+ [CDSA] = 0xa0,
+ [CCEN] = 0xbc,
+ [CCFN] = 0xc0,
+ [COLOR] = 0xc4,
+
+ /* OMAP4 specific registers */
+ [CDP] = 0xd0,
+ [CNDP] = 0xd4,
+ [CCDN] = 0xd8,
+};
+
+static struct omap_device_pm_latency omap2_dma_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void __iomem *dma_base;
+static inline void dma_write(u32 val, int reg, int lch)
+{
+ u8 stride;
+ u32 offset;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+ __raw_writel(val, dma_base + offset);
+}
+
+static inline u32 dma_read(int reg, int lch)
+{
+ u8 stride;
+ u32 offset, val;
+
+ stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
+ offset = reg_map[reg] + (stride * lch);
+ val = __raw_readl(dma_base + offset);
+ return val;
+}
+
+static inline void omap2_disable_irq_lch(int lch)
+{
+ u32 val;
+
+ val = dma_read(IRQENABLE_L0, lch);
+ val &= ~(1 << lch);
+ dma_write(val, IRQENABLE_L0, lch);
+}
+
+static void omap2_clear_dma(int lch)
+{
+ int i = dma_common_ch_start;
+
+ for (; i <= dma_common_ch_end; i += 1)
+ dma_write(0, i, lch);
+}
+
+static void omap2_show_dma_caps(void)
+{
+ u8 revision = dma_read(REVISION, 0) & 0xff;
+ printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
+ revision >> 4, revision & 0xf);
+ return;
+}
+
+static u32 configure_dma_errata(void)
+{
+
+ /*
+ * Errata applicable for OMAP2430ES1.0 and all omap2420
+ *
+ * I.
+ * Erratum ID: Not Available
+ * Inter Frame DMA buffering issue DMA will wrongly
+ * buffer elements if packing and bursting is enabled. This might
+ * result in data gets stalled in FIFO at the end of the block.
+ * Workaround: DMA channels must have BUFFERING_DISABLED bit set to
+ * guarantee no data will stay in the DMA FIFO in case inter frame
+ * buffering occurs
+ *
+ * II.
+ * Erratum ID: Not Available
+ * DMA may hang when several channels are used in parallel
+ * In the following configuration, DMA channel hanging can occur:
+ * a. Channel i, hardware synchronized, is enabled
+ * b. Another channel (Channel x), software synchronized, is enabled.
+ * c. Channel i is disabled before end of transfer
+ * d. Channel i is reenabled.
+ * e. Steps 1 to 4 are repeated a certain number of times.
+ * f. A third channel (Channel y), software synchronized, is enabled.
+ * Channel x and Channel y may hang immediately after step 'f'.
+ * Workaround:
+ * For any channel used - make sure NextLCH_ID is set to the value j.
+ */
+ if (cpu_is_omap2420() || (cpu_is_omap2430() &&
+ (omap_type() == OMAP2430_REV_ES1_0))) {
+
+ SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING);
+ SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS);
+ }
+
+ /*
+ * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled
+ * after a transaction error.
+ * Workaround: SW should explicitely disable the channel.
+ */
+ if (cpu_class_is_omap2())
+ SET_DMA_ERRATA(DMA_ERRATA_i378);
+
+ /*
+ * Erratum ID: i541: sDMA FIFO draining does not finish
+ * If sDMA channel is disabled on the fly, sDMA enters standby even
+ * through FIFO Drain is still in progress
+ * Workaround: Put sDMA in NoStandby more before a logical channel is
+ * disabled, then put it back to SmartStandby right after the channel
+ * finishes FIFO draining.
+ */
+ if (cpu_is_omap34xx())
+ SET_DMA_ERRATA(DMA_ERRATA_i541);
+
+ /*
+ * Erratum ID: i88 : Special programming model needed to disable DMA
+ * before end of block.
+ * Workaround: software must ensure that the DMA is configured in No
+ * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01")
+ */
+ if (omap_type() == OMAP3430_REV_ES1_0)
+ SET_DMA_ERRATA(DMA_ERRATA_i88);
+
+ /*
+ * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ SET_DMA_ERRATA(DMA_ERRATA_3_3);
+
+ /*
+ * Erratum ID: Not Available
+ * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
+ * after secure sram context save and restore.
+ * Work around: Hence we need to manually clear those IRQs to avoid
+ * spurious interrupts. This affects only secure devices.
+ */
+ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ SET_DMA_ERRATA(DMA_ROMCODE_BUG);
+
+ return errata;
+}
+
+/* One time initializations */
+static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
+{
+ struct omap_device *od;
+ struct omap_system_dma_plat_info *p;
+ struct resource *mem;
+ char *name = "omap_dma_system";
+
+ dma_stride = OMAP2_DMA_STRIDE;
+ dma_common_ch_start = CSDP;
+ if (cpu_is_omap3630() || cpu_is_omap4430())
+ dma_common_ch_end = CCDN;
+ else
+ dma_common_ch_end = CCFN;
+
+ p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
+ if (!p) {
+ pr_err("%s: Unable to allocate pdata for %s:%s\n",
+ __func__, name, oh->name);
+ return -ENOMEM;
+ }
+
+ p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
+ p->disable_irq_lch = omap2_disable_irq_lch;
+ p->show_dma_caps = omap2_show_dma_caps;
+ p->clear_dma = omap2_clear_dma;
+ p->dma_write = dma_write;
+ p->dma_read = dma_read;
+
+ p->clear_lch_regs = NULL;
+
+ p->errata = configure_dma_errata();
+
+ od = omap_device_build(name, 0, oh, p, sizeof(*p),
+ omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
+ kfree(p);
+ if (IS_ERR(od)) {
+ pr_err("%s: Can't build omap_device for %s:%s.\n",
+ __func__, name, oh->name);
+ return PTR_ERR(od);
+ }
+
+ mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+ return -EINVAL;
+ }
+ dma_base = ioremap(mem->start, resource_size(mem));
+ if (!dma_base) {
+ dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+ return -ENOMEM;
+ }
+
+ d = oh->dev_attr;
+ d->chan = kzalloc(sizeof(struct omap_dma_lch) *
+ (d->lch_count), GFP_KERNEL);
+
+ if (!d->chan) {
+ dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int __init omap2_system_dma_init(void)
+{
+ return omap_hwmod_for_each_by_class("dma",
+ omap2_system_dma_init_dev, NULL);
+}
+arch_initcall(omap2_system_dma_init);
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
new file mode 100644
index 00000000..f77022be
--- /dev/null
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -0,0 +1,614 @@
+/*
+ * OMAP3/4 - specific DPLL control functions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Testing and integration fixes by Jouni Högander
+ *
+ * 36xx support added by Vishwanath BS, Richard Woodruff, and Nishanth
+ * Menon
+ *
+ * Parts of this code are based on code written by
+ * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu
+ *
+ * This program is free software; you can 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/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/clkdev.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+
+/* CM_AUTOIDLE_PLL*.AUTO_* bit values */
+#define DPLL_AUTOIDLE_DISABLE 0x0
+#define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1
+
+#define MAX_DPLL_WAIT_TRIES 1000000
+
+/* Private functions */
+
+/* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */
+static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ dd = clk->dpll_data;
+
+ v = __raw_readl(dd->control_reg);
+ v &= ~dd->enable_mask;
+ v |= clken_bits << __ffs(dd->enable_mask);
+ __raw_writel(v, dd->control_reg);
+}
+
+/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
+static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
+{
+ const struct dpll_data *dd;
+ int i = 0;
+ int ret = -EINVAL;
+
+ dd = clk->dpll_data;
+
+ state <<= __ffs(dd->idlest_mask);
+
+ while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) &&
+ i < MAX_DPLL_WAIT_TRIES) {
+ i++;
+ udelay(1);
+ }
+
+ if (i == MAX_DPLL_WAIT_TRIES) {
+ printk(KERN_ERR "clock: %s failed transition to '%s'\n",
+ clk->name, (state) ? "locked" : "bypassed");
+ } else {
+ pr_debug("clock: %s transition to '%s' in %d loops\n",
+ clk->name, (state) ? "locked" : "bypassed", i);
+
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/* From 3430 TRM ES2 4.7.6.2 */
+static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
+{
+ unsigned long fint;
+ u16 f = 0;
+
+ fint = clk->dpll_data->clk_ref->rate / n;
+
+ pr_debug("clock: fint is %lu\n", fint);
+
+ if (fint >= 750000 && fint <= 1000000)
+ f = 0x3;
+ else if (fint > 1000000 && fint <= 1250000)
+ f = 0x4;
+ else if (fint > 1250000 && fint <= 1500000)
+ f = 0x5;
+ else if (fint > 1500000 && fint <= 1750000)
+ f = 0x6;
+ else if (fint > 1750000 && fint <= 2100000)
+ f = 0x7;
+ else if (fint > 7500000 && fint <= 10000000)
+ f = 0xB;
+ else if (fint > 10000000 && fint <= 12500000)
+ f = 0xC;
+ else if (fint > 12500000 && fint <= 15000000)
+ f = 0xD;
+ else if (fint > 15000000 && fint <= 17500000)
+ f = 0xE;
+ else if (fint > 17500000 && fint <= 21000000)
+ f = 0xF;
+ else
+ pr_debug("clock: unknown freqsel setting for %d\n", n);
+
+ return f;
+}
+
+/*
+ * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report
+ * readiness before returning. Will save and restore the DPLL's
+ * autoidle state across the enable, per the CDP code. If the DPLL
+ * locked successfully, return 0; if the DPLL did not lock in the time
+ * allotted, or DPLL3 was passed in, return -EINVAL.
+ */
+static int _omap3_noncore_dpll_lock(struct clk *clk)
+{
+ u8 ai;
+ int r;
+
+ pr_debug("clock: locking DPLL %s\n", clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ omap3_dpll_deny_idle(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOCKED);
+
+ r = _omap3_wait_dpll_status(clk, 1);
+
+ if (ai)
+ omap3_dpll_allow_idle(clk);
+
+ return r;
+}
+
+/*
+ * _omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power bypass mode. In
+ * bypass mode, the DPLL's rate is set equal to its parent clock's
+ * rate. Waits for the DPLL to report readiness before returning.
+ * Will save and restore the DPLL's autoidle state across the enable,
+ * per the CDP code. If the DPLL entered bypass mode successfully,
+ * return 0; if the DPLL did not enter bypass in the time allotted, or
+ * DPLL3 was passed in, or the DPLL does not support low-power bypass,
+ * return -EINVAL.
+ */
+static int _omap3_noncore_dpll_bypass(struct clk *clk)
+{
+ int r;
+ u8 ai;
+
+ if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS)))
+ return -EINVAL;
+
+ pr_debug("clock: configuring DPLL %s for low-power bypass\n",
+ clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS);
+
+ r = _omap3_wait_dpll_status(clk, 0);
+
+ if (ai)
+ omap3_dpll_allow_idle(clk);
+ else
+ omap3_dpll_deny_idle(clk);
+
+ return r;
+}
+
+/*
+ * _omap3_noncore_dpll_stop - instruct a DPLL to stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop. Will save and
+ * restore the DPLL's autoidle state across the stop, per the CDP
+ * code. If DPLL3 was passed in, or the DPLL does not support
+ * low-power stop, return -EINVAL; otherwise, return 0.
+ */
+static int _omap3_noncore_dpll_stop(struct clk *clk)
+{
+ u8 ai;
+
+ if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP)))
+ return -EINVAL;
+
+ pr_debug("clock: stopping DPLL %s\n", clk->name);
+
+ ai = omap3_dpll_autoidle_read(clk);
+
+ _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP);
+
+ if (ai)
+ omap3_dpll_allow_idle(clk);
+ else
+ omap3_dpll_deny_idle(clk);
+
+ return 0;
+}
+
+/**
+ * _lookup_dco - Lookup DCO used by j-type DPLL
+ * @clk: pointer to a DPLL struct clk
+ * @dco: digital control oscillator selector
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ *
+ * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
+ *
+ * XXX This code is not needed for 3430/AM35xx; can it be optimized
+ * out in non-multi-OMAP builds for those chips?
+ */
+static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n)
+{
+ unsigned long fint, clkinp; /* watch out for overflow */
+
+ clkinp = clk->parent->rate;
+ fint = (clkinp / n) * m;
+
+ if (fint < 1000000000)
+ *dco = 2;
+ else
+ *dco = 4;
+}
+
+/**
+ * _lookup_sddiv - Calculate sigma delta divider for j-type DPLL
+ * @clk: pointer to a DPLL struct clk
+ * @sd_div: target sigma-delta divider
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ *
+ * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)"
+ *
+ * XXX This code is not needed for 3430/AM35xx; can it be optimized
+ * out in non-multi-OMAP builds for those chips?
+ */
+static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
+{
+ unsigned long clkinp, sd; /* watch out for overflow */
+ int mod1, mod2;
+
+ clkinp = clk->parent->rate;
+
+ /*
+ * target sigma-delta to near 250MHz
+ * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)]
+ */
+ clkinp /= 100000; /* shift from MHz to 10*Hz for 38.4 and 19.2 */
+ mod1 = (clkinp * m) % (250 * n);
+ sd = (clkinp * m) / (250 * n);
+ mod2 = sd % 10;
+ sd /= 10;
+
+ if (mod1 || mod2)
+ sd++;
+ *sd_div = sd;
+}
+
+/*
+ * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly
+ * @clk: struct clk * of DPLL to set
+ * @m: DPLL multiplier to set
+ * @n: DPLL divider to set
+ * @freqsel: FREQSEL value to set
+ *
+ * Program the DPLL with the supplied M, N values, and wait for the DPLL to
+ * lock.. Returns -EINVAL upon error, or 0 upon success.
+ */
+static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
+{
+ struct dpll_data *dd = clk->dpll_data;
+ u8 dco, sd_div;
+ u32 v;
+
+ /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */
+ _omap3_noncore_dpll_bypass(clk);
+
+ /*
+ * Set jitter correction. No jitter correction for OMAP4 and 3630
+ * since freqsel field is no longer present
+ */
+ if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
+ v = __raw_readl(dd->control_reg);
+ v &= ~dd->freqsel_mask;
+ v |= freqsel << __ffs(dd->freqsel_mask);
+ __raw_writel(v, dd->control_reg);
+ }
+
+ /* Set DPLL multiplier, divider */
+ v = __raw_readl(dd->mult_div1_reg);
+ v &= ~(dd->mult_mask | dd->div1_mask);
+ v |= m << __ffs(dd->mult_mask);
+ v |= (n - 1) << __ffs(dd->div1_mask);
+
+ /* Configure dco and sd_div for dplls that have these fields */
+ if (dd->dco_mask) {
+ _lookup_dco(clk, &dco, m, n);
+ v &= ~(dd->dco_mask);
+ v |= dco << __ffs(dd->dco_mask);
+ }
+ if (dd->sddiv_mask) {
+ _lookup_sddiv(clk, &sd_div, m, n);
+ v &= ~(dd->sddiv_mask);
+ v |= sd_div << __ffs(dd->sddiv_mask);
+ }
+
+ __raw_writel(v, dd->mult_div1_reg);
+
+ /* We let the clock framework set the other output dividers later */
+
+ /* REVISIT: Set ramp-up delay? */
+
+ _omap3_noncore_dpll_lock(clk);
+
+ return 0;
+}
+
+/* Public functions */
+
+/**
+ * omap3_dpll_recalc - recalculate DPLL rate
+ * @clk: DPLL struct clk
+ *
+ * Recalculate and propagate the DPLL rate.
+ */
+unsigned long omap3_dpll_recalc(struct clk *clk)
+{
+ return omap2_get_dpll_rate(clk);
+}
+
+/* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */
+
+/**
+ * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock.
+ * The choice of modes depends on the DPLL's programmed rate: if it is
+ * the same as the DPLL's parent clock, it will enter bypass;
+ * otherwise, it will enter lock. This code will wait for the DPLL to
+ * indicate readiness before returning, unless the DPLL takes too long
+ * to enter the target state. Intended to be used as the struct clk's
+ * enable function. If DPLL3 was passed in, or the DPLL does not
+ * support low-power stop, or if the DPLL took too long to enter
+ * bypass or lock, return -EINVAL; otherwise, return 0.
+ */
+int omap3_noncore_dpll_enable(struct clk *clk)
+{
+ int r;
+ struct dpll_data *dd;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (clk->rate == dd->clk_bypass->rate) {
+ WARN_ON(clk->parent != dd->clk_bypass);
+ r = _omap3_noncore_dpll_bypass(clk);
+ } else {
+ WARN_ON(clk->parent != dd->clk_ref);
+ r = _omap3_noncore_dpll_lock(clk);
+ }
+ /*
+ *FIXME: this is dubious - if clk->rate has changed, what about
+ * propagating?
+ */
+ if (!r)
+ clk->rate = omap2_get_dpll_rate(clk);
+
+ return r;
+}
+
+/**
+ * omap3_noncore_dpll_disable - instruct a DPLL to enter low-power stop
+ * @clk: pointer to a DPLL struct clk
+ *
+ * Instructs a non-CORE DPLL to enter low-power stop. This function is
+ * intended for use in struct clkops. No return value.
+ */
+void omap3_noncore_dpll_disable(struct clk *clk)
+{
+ _omap3_noncore_dpll_stop(clk);
+}
+
+
+/* Non-CORE DPLL rate set code */
+
+/**
+ * omap3_noncore_dpll_set_rate - set non-core DPLL rate
+ * @clk: struct clk * of DPLL to set
+ * @rate: rounded target rate
+ *
+ * Set the DPLL CLKOUT to the target rate. If the DPLL can enter
+ * low-power bypass, and the target rate is the bypass source clock
+ * rate, then configure the DPLL for bypass. Otherwise, round the
+ * target rate if it hasn't been done already, then program and lock
+ * the DPLL. Returns -EINVAL upon error, or 0 upon success.
+ */
+int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *new_parent = NULL;
+ u16 freqsel = 0;
+ struct dpll_data *dd;
+ int ret;
+
+ if (!clk || !rate)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+ if (!dd)
+ return -EINVAL;
+
+ if (rate == omap2_get_dpll_rate(clk))
+ return 0;
+
+ /*
+ * Ensure both the bypass and ref clocks are enabled prior to
+ * doing anything; we need the bypass clock running to reprogram
+ * the DPLL.
+ */
+ omap2_clk_enable(dd->clk_bypass);
+ omap2_clk_enable(dd->clk_ref);
+
+ if (dd->clk_bypass->rate == rate &&
+ (clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
+ pr_debug("clock: %s: set rate: entering bypass.\n", clk->name);
+
+ ret = _omap3_noncore_dpll_bypass(clk);
+ if (!ret)
+ new_parent = dd->clk_bypass;
+ } else {
+ if (dd->last_rounded_rate != rate)
+ omap2_dpll_round_rate(clk, rate);
+
+ if (dd->last_rounded_rate == 0)
+ return -EINVAL;
+
+ /* No freqsel on OMAP4 and OMAP3630 */
+ if (!cpu_is_omap44xx() && !cpu_is_omap3630()) {
+ freqsel = _omap3_dpll_compute_freqsel(clk,
+ dd->last_rounded_n);
+ if (!freqsel)
+ WARN_ON(1);
+ }
+
+ pr_debug("clock: %s: set rate: locking rate to %lu.\n",
+ clk->name, rate);
+
+ ret = omap3_noncore_dpll_program(clk, dd->last_rounded_m,
+ dd->last_rounded_n, freqsel);
+ if (!ret)
+ new_parent = dd->clk_ref;
+ }
+ if (!ret) {
+ /*
+ * Switch the parent clock in the hierarchy, and make sure
+ * that the new parent's usecount is correct. Note: we
+ * enable the new parent before disabling the old to avoid
+ * any unnecessary hardware disable->enable transitions.
+ */
+ if (clk->usecount) {
+ omap2_clk_enable(new_parent);
+ omap2_clk_disable(clk->parent);
+ }
+ clk_reparent(clk, new_parent);
+ clk->rate = rate;
+ }
+ omap2_clk_disable(dd->clk_ref);
+ omap2_clk_disable(dd->clk_bypass);
+
+ return 0;
+}
+
+/* DPLL autoidle read/set code */
+
+/**
+ * omap3_dpll_autoidle_read - read a DPLL's autoidle bits
+ * @clk: struct clk * of the DPLL to read
+ *
+ * Return the DPLL's autoidle bits, shifted down to bit 0. Returns
+ * -EINVAL if passed a null pointer or if the struct clk does not
+ * appear to refer to a DPLL.
+ */
+u32 omap3_dpll_autoidle_read(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return -EINVAL;
+
+ dd = clk->dpll_data;
+
+ v = __raw_readl(dd->autoidle_reg);
+ v &= dd->autoidle_mask;
+ v >>= __ffs(dd->autoidle_mask);
+
+ return v;
+}
+
+/**
+ * omap3_dpll_allow_idle - enable DPLL autoidle bits
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Enable DPLL automatic idle control. This automatic idle mode
+ * switching takes effect only when the DPLL is locked, at least on
+ * OMAP3430. The DPLL will enter low-power stop when its downstream
+ * clocks are gated. No return value.
+ */
+void omap3_dpll_allow_idle(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ /*
+ * REVISIT: CORE DPLL can optionally enter low-power bypass
+ * by writing 0x5 instead of 0x1. Add some mechanism to
+ * optionally enter this mode.
+ */
+ v = __raw_readl(dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+ __raw_writel(v, dd->autoidle_reg);
+}
+
+/**
+ * omap3_dpll_deny_idle - prevent DPLL from automatically idling
+ * @clk: struct clk * of the DPLL to operate on
+ *
+ * Disable DPLL automatic idle control. No return value.
+ */
+void omap3_dpll_deny_idle(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ u32 v;
+
+ if (!clk || !clk->dpll_data)
+ return;
+
+ dd = clk->dpll_data;
+
+ v = __raw_readl(dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+ __raw_writel(v, dd->autoidle_reg);
+
+}
+
+/* Clock control for DPLL outputs */
+
+/**
+ * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
+ * @clk: DPLL output struct clk
+ *
+ * Using parent clock DPLL data, look up DPLL state. If locked, set our
+ * rate to the dpll_clk * 2; otherwise, just use dpll_clk.
+ */
+unsigned long omap3_clkoutx2_recalc(struct clk *clk)
+{
+ const struct dpll_data *dd;
+ unsigned long rate;
+ u32 v;
+ struct clk *pclk;
+
+ /* Walk up the parents of clk, looking for a DPLL */
+ pclk = clk->parent;
+ while (pclk && !pclk->dpll_data)
+ pclk = pclk->parent;
+
+ /* clk does not have a DPLL as a parent? */
+ WARN_ON(!pclk);
+
+ dd = pclk->dpll_data;
+
+ WARN_ON(!dd->enable_mask);
+
+ v = __raw_readl(dd->control_reg) & dd->enable_mask;
+ v >>= __ffs(dd->enable_mask);
+ if ((v != OMAP3XXX_EN_DPLL_LOCKED) || (dd->flags & DPLL_J_TYPE))
+ rate = clk->parent->rate;
+ else
+ rate = clk->parent->rate * 2;
+ return rate;
+}
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
new file mode 100644
index 00000000..4e4da616
--- /dev/null
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -0,0 +1,84 @@
+/*
+ * OMAP4-specific DPLL control functions
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Rajendra Nayak
+ *
+ * This program is free software; you can 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/clk.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+
+#include "clock.h"
+#include "cm-regbits-44xx.h"
+
+/* Supported only on OMAP4 */
+int omap4_dpllmx_gatectrl_read(struct clk *clk)
+{
+ u32 v;
+ u32 mask;
+
+ if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+ return -EINVAL;
+
+ mask = clk->flags & CLOCK_CLKOUTX2 ?
+ OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+ OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+ v = __raw_readl(clk->clksel_reg);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+void omap4_dpllmx_allow_gatectrl(struct clk *clk)
+{
+ u32 v;
+ u32 mask;
+
+ if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+ return;
+
+ mask = clk->flags & CLOCK_CLKOUTX2 ?
+ OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+ OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+ v = __raw_readl(clk->clksel_reg);
+ /* Clear the bit to allow gatectrl */
+ v &= ~mask;
+ __raw_writel(v, clk->clksel_reg);
+}
+
+void omap4_dpllmx_deny_gatectrl(struct clk *clk)
+{
+ u32 v;
+ u32 mask;
+
+ if (!clk || !clk->clksel_reg || !cpu_is_omap44xx())
+ return;
+
+ mask = clk->flags & CLOCK_CLKOUTX2 ?
+ OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
+ OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
+
+ v = __raw_readl(clk->clksel_reg);
+ /* Set the bit to deny gatectrl */
+ v |= mask;
+ __raw_writel(v, clk->clksel_reg);
+}
+
+const struct clkops clkops_omap4_dpllmx_ops = {
+ .allow_idle = omap4_dpllmx_allow_gatectrl,
+ .deny_idle = omap4_dpllmx_deny_gatectrl,
+};
+
diff --git a/arch/arm/mach-omap2/dsp.c b/arch/arm/mach-omap2/dsp.c
new file mode 100644
index 00000000..911cd2e6
--- /dev/null
+++ b/arch/arm/mach-omap2/dsp.c
@@ -0,0 +1,92 @@
+/*
+ * TI's OMAP DSP platform device registration
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * XXX The function pointers to the PRM/CM functions are incorrect and
+ * should be removed. No device driver should be changing PRM/CM bits
+ * directly; that's a layering violation -- those bits are the responsibility
+ * of the OMAP PM core code.
+ */
+
+#include <linux/platform_device.h>
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#ifdef CONFIG_BRIDGE_DVFS
+#include <plat/omap-pm.h>
+#endif
+
+#include <plat/dsp.h>
+
+extern phys_addr_t omap_dsp_get_mempool_base(void);
+
+static struct platform_device *omap_dsp_pdev;
+
+static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
+#ifdef CONFIG_BRIDGE_DVFS
+ .dsp_set_min_opp = omap_pm_dsp_set_min_opp,
+ .dsp_get_opp = omap_pm_dsp_get_opp,
+ .cpu_set_freq = omap_pm_cpu_set_freq,
+ .cpu_get_freq = omap_pm_cpu_get_freq,
+#endif
+ .dsp_prm_read = omap2_prm_read_mod_reg,
+ .dsp_prm_write = omap2_prm_write_mod_reg,
+ .dsp_prm_rmw_bits = omap2_prm_rmw_mod_reg_bits,
+ .dsp_cm_read = omap2_cm_read_mod_reg,
+ .dsp_cm_write = omap2_cm_write_mod_reg,
+ .dsp_cm_rmw_bits = omap2_cm_rmw_mod_reg_bits,
+};
+
+static int __init omap_dsp_init(void)
+{
+ struct platform_device *pdev;
+ int err = -ENOMEM;
+ struct omap_dsp_platform_data *pdata = &omap_dsp_pdata;
+
+ pdata->phys_mempool_base = omap_dsp_get_mempool_base();
+
+ if (pdata->phys_mempool_base) {
+ pdata->phys_mempool_size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
+ pr_info("%s: %x bytes @ %x\n", __func__,
+ pdata->phys_mempool_size, pdata->phys_mempool_base);
+ }
+
+ pdev = platform_device_alloc("omap-dsp", -1);
+ if (!pdev)
+ goto err_out;
+
+ err = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (err)
+ goto err_out;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_out;
+
+ omap_dsp_pdev = pdev;
+ return 0;
+
+err_out:
+ platform_device_put(pdev);
+ return err;
+}
+module_init(omap_dsp_init);
+
+static void __exit omap_dsp_exit(void)
+{
+ platform_device_unregister(omap_dsp_pdev);
+}
+module_exit(omap_dsp_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU");
+MODULE_DESCRIPTION("TI's OMAP DSP platform device registration");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c
new file mode 100644
index 00000000..9c442e29
--- /dev/null
+++ b/arch/arm/mach-omap2/emu.c
@@ -0,0 +1,69 @@
+/*
+ * emu.c
+ *
+ * ETM and ETB CoreSight components' resources as found in OMAP3xxx.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+/* Cortex CoreSight components within omap3xxx EMU */
+#define ETM_BASE (L4_EMU_34XX_PHYS + 0x10000)
+#define DBG_BASE (L4_EMU_34XX_PHYS + 0x11000)
+#define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000)
+#define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000)
+
+static struct amba_device omap3_etb_device = {
+ .dev = {
+ .init_name = "etb",
+ },
+ .res = {
+ .start = ETB_BASE,
+ .end = ETB_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x000bb907,
+};
+
+static struct amba_device omap3_etm_device = {
+ .dev = {
+ .init_name = "etm",
+ },
+ .res = {
+ .start = ETM_BASE,
+ .end = ETM_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .periphid = 0x102bb921,
+};
+
+static int __init emu_init(void)
+{
+ if (!cpu_is_omap34xx())
+ return -ENODEV;
+
+ amba_device_register(&omap3_etb_device, &iomem_resource);
+ amba_device_register(&omap3_etm_device, &iomem_resource);
+
+ return 0;
+}
+
+subsys_initcall(emu_init);
+
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
new file mode 100644
index 00000000..9529842a
--- /dev/null
+++ b/arch/arm/mach-omap2/gpio.c
@@ -0,0 +1,104 @@
+/*
+ * OMAP2+ specific gpio initialization
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Author:
+ * Charulatha V <charu@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation 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.
+ */
+
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct omap_device_pm_latency omap_gpio_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
+{
+ struct omap_device *od;
+ struct omap_gpio_platform_data *pdata;
+ struct omap_gpio_dev_attr *dev_attr;
+ char *name = "omap_gpio";
+ int id;
+
+ /*
+ * extract the device id from name field available in the
+ * hwmod database and use the same for constructing ids for
+ * gpio devices.
+ * CAUTION: Make sure the name in the hwmod database does
+ * not change. If changed, make corresponding change here
+ * or make use of static variable mechanism to handle this.
+ */
+ sscanf(oh->name, "gpio%d", &id);
+
+ pdata = kzalloc(sizeof(struct omap_gpio_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("gpio%d: Memory allocation failed\n", id);
+ return -ENOMEM;
+ }
+
+ dev_attr = (struct omap_gpio_dev_attr *)oh->dev_attr;
+ pdata->bank_width = dev_attr->bank_width;
+ pdata->dbck_flag = dev_attr->dbck_flag;
+ pdata->virtual_irq_start = IH_GPIO_BASE + 32 * (id - 1);
+
+ switch (oh->class->rev) {
+ case 0:
+ case 1:
+ pdata->bank_type = METHOD_GPIO_24XX;
+ break;
+ case 2:
+ pdata->bank_type = METHOD_GPIO_44XX;
+ break;
+ default:
+ WARN(1, "Invalid gpio bank_type\n");
+ kfree(pdata);
+ return -EINVAL;
+ }
+
+ od = omap_device_build(name, id - 1, oh, pdata,
+ sizeof(*pdata), omap_gpio_latency,
+ ARRAY_SIZE(omap_gpio_latency),
+ false);
+ kfree(pdata);
+
+ if (IS_ERR(od)) {
+ WARN(1, "Can't build omap_device for %s:%s.\n",
+ name, oh->name);
+ return PTR_ERR(od);
+ }
+
+ gpio_bank_count++;
+ return 0;
+}
+
+/*
+ * gpio_init needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence gpio_init is a postcore_initcall.
+ */
+static int __init omap2_gpio_init(void)
+{
+ return omap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init,
+ NULL);
+}
+postcore_initcall(omap2_gpio_init);
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
new file mode 100644
index 00000000..c1791d08
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -0,0 +1,126 @@
+/*
+ * gpmc-nand.c
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Vimal Singh <vimalsingh@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/nand.h>
+
+#include <asm/mach/flash.h>
+
+#include <plat/nand.h>
+#include <plat/board.h>
+#include <plat/gpmc.h>
+
+static struct omap_nand_platform_data *gpmc_nand_data;
+
+static struct resource gpmc_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gpmc_nand_device = {
+ .name = "omap2-nand",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &gpmc_nand_resource,
+};
+
+static int omap2_nand_gpmc_retime(void)
+{
+ struct gpmc_timings t;
+ int err;
+
+ if (!gpmc_nand_data->gpmc_t)
+ return 0;
+
+ memset(&t, 0, sizeof(t));
+ t.sync_clk = gpmc_nand_data->gpmc_t->sync_clk;
+ t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
+ t.adv_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->adv_on);
+
+ /* Read */
+ t.adv_rd_off = gpmc_round_ns_to_ticks(
+ gpmc_nand_data->gpmc_t->adv_rd_off);
+ t.oe_on = t.adv_on;
+ t.access = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->access);
+ t.oe_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->oe_off);
+ t.cs_rd_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_rd_off);
+ t.rd_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->rd_cycle);
+
+ /* Write */
+ t.adv_wr_off = gpmc_round_ns_to_ticks(
+ gpmc_nand_data->gpmc_t->adv_wr_off);
+ t.we_on = t.oe_on;
+ if (cpu_is_omap34xx()) {
+ t.wr_data_mux_bus = gpmc_round_ns_to_ticks(
+ gpmc_nand_data->gpmc_t->wr_data_mux_bus);
+ t.wr_access = gpmc_round_ns_to_ticks(
+ gpmc_nand_data->gpmc_t->wr_access);
+ }
+ t.we_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->we_off);
+ t.cs_wr_off = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_wr_off);
+ t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle);
+
+ /* Configure GPMC */
+ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1);
+ else
+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0);
+ gpmc_cs_configure(gpmc_nand_data->cs,
+ GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND);
+ err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+int __init gpmc_nand_init(struct omap_nand_platform_data *_nand_data)
+{
+ int err = 0;
+ struct device *dev = &gpmc_nand_device.dev;
+
+ gpmc_nand_data = _nand_data;
+ gpmc_nand_data->nand_setup = omap2_nand_gpmc_retime;
+ gpmc_nand_device.dev.platform_data = gpmc_nand_data;
+
+ err = gpmc_cs_request(gpmc_nand_data->cs, NAND_IO_SIZE,
+ &gpmc_nand_data->phys_base);
+ if (err < 0) {
+ dev_err(dev, "Cannot request GPMC CS\n");
+ return err;
+ }
+
+ /* Set timings in GPMC */
+ err = omap2_nand_gpmc_retime();
+ if (err < 0) {
+ dev_err(dev, "Unable to set gpmc timings: %d\n", err);
+ return err;
+ }
+
+ /* Enable RD PIN Monitoring Reg */
+ if (gpmc_nand_data->dev_ready) {
+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_RDY_BSY, 1);
+ }
+
+ err = platform_device_register(&gpmc_nand_device);
+ if (err < 0) {
+ dev_err(dev, "Unable to register NAND device\n");
+ goto out_free_cs;
+ }
+
+ return 0;
+
+out_free_cs:
+ gpmc_cs_free(gpmc_nand_data->cs);
+
+ return err;
+}
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
new file mode 100644
index 00000000..d776ded9
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -0,0 +1,407 @@
+/*
+ * linux/arch/arm/mach-omap2/gpmc-onenand.c
+ *
+ * Copyright (C) 2006 - 2009 Nokia Corporation
+ * Contacts: Juha Yrjola
+ * Tony Lindgren
+ *
+ * This program is free software; you can 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/mtd/onenand_regs.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+
+#include <plat/onenand.h>
+#include <plat/board.h>
+#include <plat/gpmc.h>
+
+static struct omap_onenand_platform_data *gpmc_onenand_data;
+
+static struct platform_device gpmc_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+};
+
+static int omap2_onenand_set_async_mode(int cs, void __iomem *onenand_base)
+{
+ struct gpmc_timings t;
+ u32 reg;
+ int err;
+
+ const int t_cer = 15;
+ const int t_avdp = 12;
+ const int t_aavdh = 7;
+ const int t_ce = 76;
+ const int t_aa = 76;
+ const int t_oe = 20;
+ const int t_cez = 20; /* max of t_cez, t_oez */
+ const int t_ds = 30;
+ const int t_wpl = 40;
+ const int t_wph = 30;
+
+ /* Ensure sync read and sync write are disabled */
+ reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
+ reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
+ writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
+
+ memset(&t, 0, sizeof(t));
+ t.sync_clk = 0;
+ t.cs_on = 0;
+ t.adv_on = 0;
+
+ /* Read */
+ t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
+ t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
+ t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
+ t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
+ t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
+ t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
+ t.cs_rd_off = t.oe_off;
+ t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
+
+ /* Write */
+ t.adv_wr_off = t.adv_rd_off;
+ t.we_on = t.oe_on;
+ if (cpu_is_omap34xx()) {
+ t.wr_data_mux_bus = t.we_on;
+ t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
+ }
+ t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
+ t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
+ t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+
+ /* Configure GPMC for asynchronous read */
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_DEVICESIZE_16 |
+ GPMC_CONFIG1_MUXADDDATA);
+
+ err = gpmc_cs_set_timings(cs, &t);
+ if (err)
+ return err;
+
+ /* Ensure sync read and sync write are disabled */
+ reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
+ reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
+ writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
+
+ return 0;
+}
+
+static void set_onenand_cfg(void __iomem *onenand_base, int latency,
+ int sync_read, int sync_write, int hf, int vhf)
+{
+ u32 reg;
+
+ reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
+ reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
+ reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
+ ONENAND_SYS_CFG1_BL_16;
+ if (sync_read)
+ reg |= ONENAND_SYS_CFG1_SYNC_READ;
+ else
+ reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
+ if (sync_write)
+ reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+ else
+ reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
+ if (hf)
+ reg |= ONENAND_SYS_CFG1_HF;
+ else
+ reg &= ~ONENAND_SYS_CFG1_HF;
+ if (vhf)
+ reg |= ONENAND_SYS_CFG1_VHF;
+ else
+ reg &= ~ONENAND_SYS_CFG1_VHF;
+ writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
+}
+
+static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
+ void __iomem *onenand_base, bool *clk_dep)
+{
+ u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
+ int freq = 0;
+
+ if (cfg->get_freq) {
+ struct onenand_freq_info fi;
+
+ fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
+ fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
+ fi.ver_id = ver;
+ freq = cfg->get_freq(&fi, clk_dep);
+ if (freq)
+ return freq;
+ }
+
+ switch ((ver >> 4) & 0xf) {
+ case 0:
+ freq = 40;
+ break;
+ case 1:
+ freq = 54;
+ break;
+ case 2:
+ freq = 66;
+ break;
+ case 3:
+ freq = 83;
+ break;
+ case 4:
+ freq = 104;
+ break;
+ default:
+ freq = 54;
+ break;
+ }
+
+ return freq;
+}
+
+static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
+ void __iomem *onenand_base,
+ int *freq_ptr)
+{
+ struct gpmc_timings t;
+ const int t_cer = 15;
+ const int t_avdp = 12;
+ const int t_cez = 20; /* max of t_cez, t_oez */
+ const int t_ds = 30;
+ const int t_wpl = 40;
+ const int t_wph = 30;
+ int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+ int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency;
+ int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0;
+ int err, ticks_cez;
+ int cs = cfg->cs, freq = *freq_ptr;
+ u32 reg;
+ bool clk_dep = false;
+
+ if (cfg->flags & ONENAND_SYNC_READ) {
+ sync_read = 1;
+ } else if (cfg->flags & ONENAND_SYNC_READWRITE) {
+ sync_read = 1;
+ sync_write = 1;
+ } else
+ return omap2_onenand_set_async_mode(cs, onenand_base);
+
+ if (!freq) {
+ /* Very first call freq is not known */
+ err = omap2_onenand_set_async_mode(cs, onenand_base);
+ if (err)
+ return err;
+ freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
+ first_time = 1;
+ }
+
+ switch (freq) {
+ case 104:
+ min_gpmc_clk_period = 9600; /* 104 MHz */
+ t_ces = 3;
+ t_avds = 4;
+ t_avdh = 2;
+ t_ach = 3;
+ t_aavdh = 6;
+ t_rdyo = 6;
+ break;
+ case 83:
+ min_gpmc_clk_period = 12000; /* 83 MHz */
+ t_ces = 5;
+ t_avds = 4;
+ t_avdh = 2;
+ t_ach = 6;
+ t_aavdh = 6;
+ t_rdyo = 9;
+ break;
+ case 66:
+ min_gpmc_clk_period = 15000; /* 66 MHz */
+ t_ces = 6;
+ t_avds = 5;
+ t_avdh = 2;
+ t_ach = 6;
+ t_aavdh = 6;
+ t_rdyo = 11;
+ break;
+ default:
+ min_gpmc_clk_period = 18500; /* 54 MHz */
+ t_ces = 7;
+ t_avds = 7;
+ t_avdh = 7;
+ t_ach = 9;
+ t_aavdh = 7;
+ t_rdyo = 15;
+ sync_write = 0;
+ break;
+ }
+
+ tick_ns = gpmc_ticks_to_ns(1);
+ div = gpmc_cs_calc_divider(cs, min_gpmc_clk_period);
+ gpmc_clk_ns = gpmc_ticks_to_ns(div);
+ if (gpmc_clk_ns < 15) /* >66Mhz */
+ hf = 1;
+ if (gpmc_clk_ns < 12) /* >83Mhz */
+ vhf = 1;
+ if (vhf)
+ latency = 8;
+ else if (hf)
+ latency = 6;
+ else if (gpmc_clk_ns >= 25) /* 40 MHz*/
+ latency = 3;
+ else
+ latency = 4;
+
+ if (clk_dep) {
+ if (gpmc_clk_ns < 12) { /* >83Mhz */
+ t_ces = 3;
+ t_avds = 4;
+ } else if (gpmc_clk_ns < 15) { /* >66Mhz */
+ t_ces = 5;
+ t_avds = 4;
+ } else if (gpmc_clk_ns < 25) { /* >40Mhz */
+ t_ces = 6;
+ t_avds = 5;
+ } else {
+ t_ces = 7;
+ t_avds = 7;
+ }
+ }
+
+ if (first_time)
+ set_onenand_cfg(onenand_base, latency,
+ sync_read, sync_write, hf, vhf);
+
+ if (div == 1) {
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
+ reg |= (1 << 7);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
+ reg |= (1 << 7);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
+ reg |= (1 << 7);
+ reg |= (1 << 23);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+ } else {
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
+ reg &= ~(1 << 7);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
+ reg &= ~(1 << 7);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
+ reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
+ reg &= ~(1 << 7);
+ reg &= ~(1 << 23);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
+ }
+
+ /* Set synchronous read timings */
+ memset(&t, 0, sizeof(t));
+ t.sync_clk = min_gpmc_clk_period;
+ t.cs_on = 0;
+ t.adv_on = 0;
+ fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
+ fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
+ t.page_burst_access = gpmc_clk_ns;
+
+ /* Read */
+ t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
+ t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
+ /* Force at least 1 clk between AVD High to OE Low */
+ if (t.oe_on <= t.adv_rd_off)
+ t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
+ t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
+ t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
+ t.cs_rd_off = t.oe_off;
+ ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
+ t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
+ ticks_cez);
+
+ /* Write */
+ if (sync_write) {
+ t.adv_wr_off = t.adv_rd_off;
+ t.we_on = 0;
+ t.we_off = t.cs_rd_off;
+ t.cs_wr_off = t.cs_rd_off;
+ t.wr_cycle = t.rd_cycle;
+ if (cpu_is_omap34xx()) {
+ t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
+ gpmc_ps_to_ticks(min_gpmc_clk_period +
+ t_rdyo * 1000));
+ t.wr_access = t.access;
+ }
+ } else {
+ t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
+ t_avdp, t_cer));
+ t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
+ t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
+ t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
+ t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
+ if (cpu_is_omap34xx()) {
+ t.wr_data_mux_bus = t.we_on;
+ t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
+ }
+ }
+
+ /* Configure GPMC for synchronous read */
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_WRAPBURST_SUPP |
+ GPMC_CONFIG1_READMULTIPLE_SUPP |
+ (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
+ (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
+ (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
+ GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
+ GPMC_CONFIG1_PAGE_LEN(2) |
+ (cpu_is_omap34xx() ? 0 :
+ (GPMC_CONFIG1_WAIT_READ_MON |
+ GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
+ GPMC_CONFIG1_DEVICESIZE_16 |
+ GPMC_CONFIG1_DEVICETYPE_NOR |
+ GPMC_CONFIG1_MUXADDDATA);
+
+ err = gpmc_cs_set_timings(cs, &t);
+ if (err)
+ return err;
+
+ set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf);
+
+ *freq_ptr = freq;
+
+ return 0;
+}
+
+static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
+{
+ struct device *dev = &gpmc_onenand_device.dev;
+
+ /* Set sync timings in GPMC */
+ if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base,
+ freq_ptr) < 0) {
+ dev_err(dev, "Unable to set synchronous mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
+{
+ gpmc_onenand_data = _onenand_data;
+ gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
+ gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
+
+ if (cpu_is_omap24xx() &&
+ (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
+ printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
+ gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
+ gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
+ }
+
+ if (platform_device_register(&gpmc_onenand_device) < 0) {
+ printk(KERN_ERR "Unable to register OneNAND device\n");
+ return;
+ }
+}
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c b/arch/arm/mach-omap2/gpmc-smc91x.c
new file mode 100644
index 00000000..ba10c24f
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -0,0 +1,190 @@
+/*
+ * linux/arch/arm/mach-omap2/gpmc-smc91x.c
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Contact: Tony Lindgren
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/smc91x.h>
+
+#include <plat/board.h>
+#include <plat/gpmc.h>
+#include <plat/gpmc-smc91x.h>
+
+static struct omap_smc91x_platform_data *gpmc_cfg;
+
+static struct resource gpmc_smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smc91x_platdata gpmc_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_0,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct platform_device gpmc_smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpmc_smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(gpmc_smc91x_resources),
+ .resource = gpmc_smc91x_resources,
+};
+
+/*
+ * Set the gpmc timings for smc91c96. The timings are taken
+ * from the data sheet available at:
+ * http://www.smsc.com/main/catalog/lan91c96.html
+ * REVISIT: Level shifters can add at least to the access latency.
+ */
+static int smc91c96_gpmc_retime(void)
+{
+ struct gpmc_timings t;
+ const int t3 = 10; /* Figure 12.2 read and 12.4 write */
+ const int t4_r = 20; /* Figure 12.2 read */
+ const int t4_w = 5; /* Figure 12.4 write */
+ const int t5 = 25; /* Figure 12.2 read */
+ const int t6 = 15; /* Figure 12.2 read */
+ const int t7 = 5; /* Figure 12.4 write */
+ const int t8 = 5; /* Figure 12.4 write */
+ const int t20 = 185; /* Figure 12.2 read and 12.4 write */
+ u32 l;
+
+ memset(&t, 0, sizeof(t));
+
+ /* Read timings */
+ t.cs_on = 0;
+ t.adv_on = t.cs_on;
+ t.oe_on = t.adv_on + t3;
+ t.access = t.oe_on + t5;
+ t.oe_off = t.access;
+ t.adv_rd_off = t.oe_off + max(t4_r, t6);
+ t.cs_rd_off = t.oe_off;
+ t.rd_cycle = t20 - t.oe_on;
+
+ /* Write timings */
+ t.we_on = t.adv_on + t3;
+
+ if (cpu_is_omap34xx() && (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)) {
+ t.wr_data_mux_bus = t.we_on;
+ t.we_off = t.wr_data_mux_bus + t7;
+ } else
+ t.we_off = t.we_on + t7;
+ if (cpu_is_omap34xx())
+ t.wr_access = t.we_off;
+ t.adv_wr_off = t.we_off + max(t4_w, t8);
+ t.cs_wr_off = t.we_off + t4_w;
+ t.wr_cycle = t20 - t.we_on;
+
+ l = GPMC_CONFIG1_DEVICESIZE_16;
+ if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
+ l |= GPMC_CONFIG1_MUXADDDATA;
+ if (gpmc_cfg->flags & GPMC_READ_MON)
+ l |= GPMC_CONFIG1_WAIT_READ_MON;
+ if (gpmc_cfg->flags & GPMC_WRITE_MON)
+ l |= GPMC_CONFIG1_WAIT_WRITE_MON;
+ if (gpmc_cfg->wait_pin)
+ l |= GPMC_CONFIG1_WAIT_PIN_SEL(gpmc_cfg->wait_pin);
+ gpmc_cs_write_reg(gpmc_cfg->cs, GPMC_CS_CONFIG1, l);
+
+ /*
+ * FIXME: Calculate the address and data bus muxed timings.
+ * Note that at least adv_rd_off needs to be changed according
+ * to omap3430 TRM Figure 11-11. Are the sdp boards using the
+ * FPGA in between smc91x and omap as the timings are different
+ * from above?
+ */
+ if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA)
+ return 0;
+
+ return gpmc_cs_set_timings(gpmc_cfg->cs, &t);
+}
+
+/*
+ * Initialize smc91x device connected to the GPMC. Note that we
+ * assume that pin multiplexing is done in the board-*.c file,
+ * or in the bootloader.
+ */
+void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
+{
+ unsigned long cs_mem_base;
+ int ret;
+
+ gpmc_cfg = board_data;
+
+ if (gpmc_cfg->flags & GPMC_TIMINGS_SMC91C96)
+ gpmc_cfg->retime = smc91c96_gpmc_retime;
+
+ if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
+ printk(KERN_ERR "Failed to request GPMC mem for smc91x\n");
+ return;
+ }
+
+ gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
+ gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
+ gpmc_smc91x_resources[1].flags |= (gpmc_cfg->flags & IRQF_TRIGGER_MASK);
+
+ if (gpmc_cfg->retime) {
+ ret = gpmc_cfg->retime();
+ if (ret != 0)
+ goto free1;
+ }
+
+ if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0)
+ goto free1;
+
+ gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
+
+ if (gpmc_cfg->gpio_pwrdwn) {
+ ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn,
+ GPIOF_OUT_INIT_LOW, "SMC91X powerdown");
+ if (ret)
+ goto free2;
+ }
+
+ if (gpmc_cfg->gpio_reset) {
+ ret = gpio_request_one(gpmc_cfg->gpio_reset,
+ GPIOF_OUT_INIT_LOW, "SMC91X reset");
+ if (ret)
+ goto free3;
+
+ gpio_set_value(gpmc_cfg->gpio_reset, 1);
+ msleep(100);
+ gpio_set_value(gpmc_cfg->gpio_reset, 0);
+ }
+
+ if (platform_device_register(&gpmc_smc91x_device) < 0) {
+ printk(KERN_ERR "Unable to register smc91x device\n");
+ gpio_free(gpmc_cfg->gpio_reset);
+ goto free3;
+ }
+
+ return;
+
+free3:
+ if (gpmc_cfg->gpio_pwrdwn)
+ gpio_free(gpmc_cfg->gpio_pwrdwn);
+free2:
+ gpio_free(gpmc_cfg->gpio_irq);
+free1:
+ gpmc_cs_free(gpmc_cfg->cs);
+
+ printk(KERN_ERR "Could not initialize smc91x\n");
+}
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
new file mode 100644
index 00000000..99703312
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -0,0 +1,107 @@
+/*
+ * linux/arch/arm/mach-omap2/gpmc-smsc911x.c
+ *
+ * Copyright (C) 2009 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+
+#include <plat/board.h>
+#include <plat/gpmc.h>
+#include <plat/gpmc-smsc911x.h>
+
+static struct omap_smsc911x_platform_data *gpmc_cfg;
+
+static struct resource gpmc_smsc911x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config gpmc_smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_16BIT,
+};
+
+/*
+ * Initialize smsc911x device connected to the GPMC. Note that we
+ * assume that pin multiplexing is done in the board-*.c file,
+ * or in the bootloader.
+ */
+void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data)
+{
+ struct platform_device *pdev;
+ unsigned long cs_mem_base;
+ int ret;
+
+ gpmc_cfg = board_data;
+
+ if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
+ pr_err("Failed to request GPMC mem region\n");
+ return;
+ }
+
+ gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
+ gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
+
+ if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) {
+ pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq);
+ goto free1;
+ }
+
+ gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
+
+ if (gpio_is_valid(gpmc_cfg->gpio_reset)) {
+ ret = gpio_request_one(gpmc_cfg->gpio_reset,
+ GPIOF_OUT_INIT_HIGH, "smsc911x reset");
+ if (ret) {
+ pr_err("Failed to request reset GPIO%d\n",
+ gpmc_cfg->gpio_reset);
+ goto free2;
+ }
+
+ gpio_set_value(gpmc_cfg->gpio_reset, 0);
+ msleep(100);
+ gpio_set_value(gpmc_cfg->gpio_reset, 1);
+ }
+
+ if (gpmc_cfg->flags)
+ gpmc_smsc911x_config.flags = gpmc_cfg->flags;
+
+ pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id,
+ gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
+ &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
+ if (!pdev) {
+ pr_err("Unable to register platform device\n");
+ gpio_free(gpmc_cfg->gpio_reset);
+ goto free2;
+ }
+
+ return;
+
+free2:
+ gpio_free(gpmc_cfg->gpio_irq);
+free1:
+ gpmc_cs_free(gpmc_cfg->cs);
+
+ pr_err("Could not initialize smsc911x device\n");
+}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
new file mode 100644
index 00000000..dfffbbf4
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -0,0 +1,920 @@
+/*
+ * GPMC support functions
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * Author: Juha Yrjola
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <plat/gpmc.h>
+
+#include <plat/sdrc.h>
+
+/* GPMC register offsets */
+#define GPMC_REVISION 0x00
+#define GPMC_SYSCONFIG 0x10
+#define GPMC_SYSSTATUS 0x14
+#define GPMC_IRQSTATUS 0x18
+#define GPMC_IRQENABLE 0x1c
+#define GPMC_TIMEOUT_CONTROL 0x40
+#define GPMC_ERR_ADDRESS 0x44
+#define GPMC_ERR_TYPE 0x48
+#define GPMC_CONFIG 0x50
+#define GPMC_STATUS 0x54
+#define GPMC_PREFETCH_CONFIG1 0x1e0
+#define GPMC_PREFETCH_CONFIG2 0x1e4
+#define GPMC_PREFETCH_CONTROL 0x1ec
+#define GPMC_PREFETCH_STATUS 0x1f0
+#define GPMC_ECC_CONFIG 0x1f4
+#define GPMC_ECC_CONTROL 0x1f8
+#define GPMC_ECC_SIZE_CONFIG 0x1fc
+#define GPMC_ECC1_RESULT 0x200
+
+#define GPMC_CS0_OFFSET 0x60
+#define GPMC_CS_SIZE 0x30
+
+#define GPMC_MEM_START 0x00000000
+#define GPMC_MEM_END 0x3FFFFFFF
+#define BOOT_ROM_SPACE 0x100000 /* 1MB */
+
+#define GPMC_CHUNK_SHIFT 24 /* 16 MB */
+#define GPMC_SECTION_SHIFT 28 /* 128 MB */
+
+#define CS_NUM_SHIFT 24
+#define ENABLE_PREFETCH (0x1 << 7)
+#define DMA_MPU_MODE 2
+
+/* Structure to save gpmc cs context */
+struct gpmc_cs_config {
+ u32 config1;
+ u32 config2;
+ u32 config3;
+ u32 config4;
+ u32 config5;
+ u32 config6;
+ u32 config7;
+ int is_valid;
+};
+
+/*
+ * Structure to save/restore gpmc context
+ * to support core off on OMAP3
+ */
+struct omap3_gpmc_regs {
+ u32 sysconfig;
+ u32 irqenable;
+ u32 timeout_ctrl;
+ u32 config;
+ u32 prefetch_config1;
+ u32 prefetch_config2;
+ u32 prefetch_control;
+ struct gpmc_cs_config cs_context[GPMC_CS_NUM];
+};
+
+static struct resource gpmc_mem_root;
+static struct resource gpmc_cs_mem[GPMC_CS_NUM];
+static DEFINE_SPINLOCK(gpmc_mem_lock);
+static unsigned int gpmc_cs_map; /* flag for cs which are initialized */
+static int gpmc_ecc_used = -EINVAL; /* cs using ecc engine */
+
+static void __iomem *gpmc_base;
+
+static struct clk *gpmc_l3_clk;
+
+static irqreturn_t gpmc_handle_irq(int irq, void *dev);
+
+static void gpmc_write_reg(int idx, u32 val)
+{
+ __raw_writel(val, gpmc_base + idx);
+}
+
+static u32 gpmc_read_reg(int idx)
+{
+ return __raw_readl(gpmc_base + idx);
+}
+
+static void gpmc_cs_write_byte(int cs, int idx, u8 val)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ __raw_writeb(val, reg_addr);
+}
+
+static u8 gpmc_cs_read_byte(int cs, int idx)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ return __raw_readb(reg_addr);
+}
+
+void gpmc_cs_write_reg(int cs, int idx, u32 val)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ __raw_writel(val, reg_addr);
+}
+
+u32 gpmc_cs_read_reg(int cs, int idx)
+{
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx;
+ return __raw_readl(reg_addr);
+}
+
+/* TODO: Add support for gpmc_fck to clock framework and use it */
+unsigned long gpmc_get_fclk_period(void)
+{
+ unsigned long rate = clk_get_rate(gpmc_l3_clk);
+
+ if (rate == 0) {
+ printk(KERN_WARNING "gpmc_l3_clk not enabled\n");
+ return 0;
+ }
+
+ rate /= 1000;
+ rate = 1000000000 / rate; /* In picoseconds */
+
+ return rate;
+}
+
+unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ns * 1000 + tick_ps - 1) / tick_ps;
+}
+
+unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = gpmc_get_fclk_period();
+
+ return (time_ps + tick_ps - 1) / tick_ps;
+}
+
+unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+{
+ return ticks * gpmc_get_fclk_period() / 1000;
+}
+
+unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
+{
+ unsigned long ticks = gpmc_ns_to_ticks(time_ns);
+
+ return ticks * gpmc_get_fclk_period() / 1000;
+}
+
+#ifdef DEBUG
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+ int time, const char *name)
+#else
+static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
+ int time)
+#endif
+{
+ u32 l;
+ int ticks, mask, nr_bits;
+
+ if (time == 0)
+ ticks = 0;
+ else
+ ticks = gpmc_ns_to_ticks(time);
+ nr_bits = end_bit - st_bit + 1;
+ if (ticks >= 1 << nr_bits) {
+#ifdef DEBUG
+ printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+ cs, name, time, ticks, 1 << nr_bits);
+#endif
+ return -1;
+ }
+
+ mask = (1 << nr_bits) - 1;
+ l = gpmc_cs_read_reg(cs, reg);
+#ifdef DEBUG
+ printk(KERN_INFO
+ "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
+ cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
+ (l >> st_bit) & mask, time);
+#endif
+ l &= ~(mask << st_bit);
+ l |= ticks << st_bit;
+ gpmc_cs_write_reg(cs, reg, l);
+
+ return 0;
+}
+
+#ifdef DEBUG
+#define GPMC_SET_ONE(reg, st, end, field) \
+ if (set_gpmc_timing_reg(cs, (reg), (st), (end), \
+ t->field, #field) < 0) \
+ return -1
+#else
+#define GPMC_SET_ONE(reg, st, end, field) \
+ if (set_gpmc_timing_reg(cs, (reg), (st), (end), t->field) < 0) \
+ return -1
+#endif
+
+int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
+{
+ int div;
+ u32 l;
+
+ l = sync_clk + (gpmc_get_fclk_period() - 1);
+ div = l / gpmc_get_fclk_period();
+ if (div > 4)
+ return -1;
+ if (div <= 0)
+ div = 1;
+
+ return div;
+}
+
+int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
+{
+ int div;
+ u32 l;
+
+ div = gpmc_cs_calc_divider(cs, t->sync_clk);
+ if (div < 0)
+ return -1;
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 0, 3, cs_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 8, 12, cs_rd_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG2, 16, 20, cs_wr_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 0, 3, adv_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 8, 12, adv_rd_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG3, 16, 20, adv_wr_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 0, 3, oe_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 8, 12, oe_off);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 16, 19, we_on);
+ GPMC_SET_ONE(GPMC_CS_CONFIG4, 24, 28, we_off);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 0, 4, rd_cycle);
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 8, 12, wr_cycle);
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 16, 20, access);
+
+ GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+
+ if (cpu_is_omap34xx()) {
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
+ }
+
+ /* caller is expected to have initialized CONFIG1 to cover
+ * at least sync vs async
+ */
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+ if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
+#ifdef DEBUG
+ printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
+ cs, (div * gpmc_get_fclk_period()) / 1000, div);
+#endif
+ l &= ~0x03;
+ l |= (div - 1);
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
+ }
+
+ return 0;
+}
+
+static void gpmc_cs_enable_mem(int cs, u32 base, u32 size)
+{
+ u32 l;
+ u32 mask;
+
+ mask = (1 << GPMC_SECTION_SHIFT) - size;
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ l &= ~0x3f;
+ l = (base >> GPMC_CHUNK_SHIFT) & 0x3f;
+ l &= ~(0x0f << 8);
+ l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8;
+ l |= GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+}
+
+static void gpmc_cs_disable_mem(int cs)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ l &= ~GPMC_CONFIG7_CSVALID;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l);
+}
+
+static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size)
+{
+ u32 l;
+ u32 mask;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ *base = (l & 0x3f) << GPMC_CHUNK_SHIFT;
+ mask = (l >> 8) & 0x0f;
+ *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT);
+}
+
+static int gpmc_cs_mem_enabled(int cs)
+{
+ u32 l;
+
+ l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ return l & GPMC_CONFIG7_CSVALID;
+}
+
+int gpmc_cs_set_reserved(int cs, int reserved)
+{
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+
+ gpmc_cs_map &= ~(1 << cs);
+ gpmc_cs_map |= (reserved ? 1 : 0) << cs;
+
+ return 0;
+}
+
+int gpmc_cs_reserved(int cs)
+{
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+
+ return gpmc_cs_map & (1 << cs);
+}
+
+static unsigned long gpmc_mem_align(unsigned long size)
+{
+ int order;
+
+ size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1);
+ order = GPMC_CHUNK_SHIFT - 1;
+ do {
+ size >>= 1;
+ order++;
+ } while (size);
+ size = 1 << order;
+ return size;
+}
+
+static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r;
+
+ size = gpmc_mem_align(size);
+ spin_lock(&gpmc_mem_lock);
+ res->start = base;
+ res->end = base + size - 1;
+ r = request_resource(&gpmc_mem_root, res);
+ spin_unlock(&gpmc_mem_lock);
+
+ return r;
+}
+
+int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+{
+ struct resource *res = &gpmc_cs_mem[cs];
+ int r = -1;
+
+ if (cs > GPMC_CS_NUM)
+ return -ENODEV;
+
+ size = gpmc_mem_align(size);
+ if (size > (1 << GPMC_SECTION_SHIFT))
+ return -ENOMEM;
+
+ spin_lock(&gpmc_mem_lock);
+ if (gpmc_cs_reserved(cs)) {
+ r = -EBUSY;
+ goto out;
+ }
+ if (gpmc_cs_mem_enabled(cs))
+ r = adjust_resource(res, res->start & ~(size - 1), size);
+ if (r < 0)
+ r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0,
+ size, NULL, NULL);
+ if (r < 0)
+ goto out;
+
+ gpmc_cs_enable_mem(cs, res->start, resource_size(res));
+ *base = res->start;
+ gpmc_cs_set_reserved(cs, 1);
+out:
+ spin_unlock(&gpmc_mem_lock);
+ return r;
+}
+EXPORT_SYMBOL(gpmc_cs_request);
+
+void gpmc_cs_free(int cs)
+{
+ spin_lock(&gpmc_mem_lock);
+ if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) {
+ printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
+ BUG();
+ spin_unlock(&gpmc_mem_lock);
+ return;
+ }
+ gpmc_cs_disable_mem(cs);
+ release_resource(&gpmc_cs_mem[cs]);
+ gpmc_cs_set_reserved(cs, 0);
+ spin_unlock(&gpmc_mem_lock);
+}
+EXPORT_SYMBOL(gpmc_cs_free);
+
+/**
+ * gpmc_read_status - read access request to get the different gpmc status
+ * @cmd: command type
+ * @return status
+ */
+int gpmc_read_status(int cmd)
+{
+ int status = -EINVAL;
+ u32 regval = 0;
+
+ switch (cmd) {
+ case GPMC_GET_IRQ_STATUS:
+ status = gpmc_read_reg(GPMC_IRQSTATUS);
+ break;
+
+ case GPMC_PREFETCH_FIFO_CNT:
+ regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
+ status = GPMC_PREFETCH_STATUS_FIFO_CNT(regval);
+ break;
+
+ case GPMC_PREFETCH_COUNT:
+ regval = gpmc_read_reg(GPMC_PREFETCH_STATUS);
+ status = GPMC_PREFETCH_STATUS_COUNT(regval);
+ break;
+
+ case GPMC_STATUS_BUFFER:
+ regval = gpmc_read_reg(GPMC_STATUS);
+ /* 1 : buffer is available to write */
+ status = regval & GPMC_STATUS_BUFF_EMPTY;
+ break;
+
+ default:
+ printk(KERN_ERR "gpmc_read_status: Not supported\n");
+ }
+ return status;
+}
+EXPORT_SYMBOL(gpmc_read_status);
+
+/**
+ * gpmc_cs_configure - write request to configure gpmc
+ * @cs: chip select number
+ * @cmd: command type
+ * @wval: value to write
+ * @return status of the operation
+ */
+int gpmc_cs_configure(int cs, int cmd, int wval)
+{
+ int err = 0;
+ u32 regval = 0;
+
+ switch (cmd) {
+ case GPMC_ENABLE_IRQ:
+ gpmc_write_reg(GPMC_IRQENABLE, wval);
+ break;
+
+ case GPMC_SET_IRQ_STATUS:
+ gpmc_write_reg(GPMC_IRQSTATUS, wval);
+ break;
+
+ case GPMC_CONFIG_WP:
+ regval = gpmc_read_reg(GPMC_CONFIG);
+ if (wval)
+ regval &= ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */
+ else
+ regval |= GPMC_CONFIG_WRITEPROTECT; /* WP is OFF */
+ gpmc_write_reg(GPMC_CONFIG, regval);
+ break;
+
+ case GPMC_CONFIG_RDY_BSY:
+ regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+ if (wval)
+ regval |= WR_RD_PIN_MONITORING;
+ else
+ regval &= ~WR_RD_PIN_MONITORING;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+ break;
+
+ case GPMC_CONFIG_DEV_SIZE:
+ regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /* clear 2 target bits */
+ regval &= ~GPMC_CONFIG1_DEVICESIZE(3);
+
+ /* set the proper value */
+ regval |= GPMC_CONFIG1_DEVICESIZE(wval);
+
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+ break;
+
+ case GPMC_CONFIG_DEV_TYPE:
+ regval = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+ regval |= GPMC_CONFIG1_DEVICETYPE(wval);
+ if (wval == GPMC_DEVICETYPE_NOR)
+ regval |= GPMC_CONFIG1_MUXADDDATA;
+ gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, regval);
+ break;
+
+ default:
+ printk(KERN_ERR "gpmc_configure_cs: Not supported\n");
+ err = -EINVAL;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL(gpmc_cs_configure);
+
+/**
+ * gpmc_nand_read - nand specific read access request
+ * @cs: chip select number
+ * @cmd: command type
+ */
+int gpmc_nand_read(int cs, int cmd)
+{
+ int rval = -EINVAL;
+
+ switch (cmd) {
+ case GPMC_NAND_DATA:
+ rval = gpmc_cs_read_byte(cs, GPMC_CS_NAND_DATA);
+ break;
+
+ default:
+ printk(KERN_ERR "gpmc_read_nand_ctrl: Not supported\n");
+ }
+ return rval;
+}
+EXPORT_SYMBOL(gpmc_nand_read);
+
+/**
+ * gpmc_nand_write - nand specific write request
+ * @cs: chip select number
+ * @cmd: command type
+ * @wval: value to write
+ */
+int gpmc_nand_write(int cs, int cmd, int wval)
+{
+ int err = 0;
+
+ switch (cmd) {
+ case GPMC_NAND_COMMAND:
+ gpmc_cs_write_byte(cs, GPMC_CS_NAND_COMMAND, wval);
+ break;
+
+ case GPMC_NAND_ADDRESS:
+ gpmc_cs_write_byte(cs, GPMC_CS_NAND_ADDRESS, wval);
+ break;
+
+ case GPMC_NAND_DATA:
+ gpmc_cs_write_byte(cs, GPMC_CS_NAND_DATA, wval);
+
+ default:
+ printk(KERN_ERR "gpmc_write_nand_ctrl: Not supported\n");
+ err = -EINVAL;
+ }
+ return err;
+}
+EXPORT_SYMBOL(gpmc_nand_write);
+
+
+
+/**
+ * gpmc_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @dma_mode: dma mode enable (1) or disable (0)
+ * @u32_count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
+ unsigned int u32_count, int is_write)
+{
+
+ if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) {
+ pr_err("gpmc: fifo threshold is not supported\n");
+ return -1;
+ } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) {
+ /* Set the amount of bytes to be prefetched */
+ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count);
+
+ /* Set dma/mpu mode, the prefetch read / post write and
+ * enable the engine. Set which cs is has requested for.
+ */
+ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) |
+ PREFETCH_FIFOTHRESHOLD(fifo_th) |
+ ENABLE_PREFETCH |
+ (dma_mode << DMA_MPU_MODE) |
+ (0x1 & is_write)));
+
+ /* Start the prefetch engine */
+ gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x1);
+ } else {
+ return -EBUSY;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(gpmc_prefetch_enable);
+
+/**
+ * gpmc_prefetch_reset - disables and stops the prefetch engine
+ */
+int gpmc_prefetch_reset(int cs)
+{
+ u32 config1;
+
+ /* check if the same module/cs is trying to reset */
+ config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
+ if (((config1 >> CS_NUM_SHIFT) & 0x7) != cs)
+ return -EINVAL;
+
+ /* Stop the PFPW engine */
+ gpmc_write_reg(GPMC_PREFETCH_CONTROL, 0x0);
+
+ /* Reset/disable the PFPW engine */
+ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, 0x0);
+
+ return 0;
+}
+EXPORT_SYMBOL(gpmc_prefetch_reset);
+
+static void __init gpmc_mem_init(void)
+{
+ int cs;
+ unsigned long boot_rom_space = 0;
+
+ /* never allocate the first page, to facilitate bug detection;
+ * even if we didn't boot from ROM.
+ */
+ boot_rom_space = BOOT_ROM_SPACE;
+ /* In apollon the CS0 is mapped as 0x0000 0000 */
+ if (machine_is_omap_apollon())
+ boot_rom_space = 0;
+ gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space;
+ gpmc_mem_root.end = GPMC_MEM_END;
+
+ /* Reserve all regions that has been set up by bootloader */
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ u32 base, size;
+
+ if (!gpmc_cs_mem_enabled(cs))
+ continue;
+ gpmc_cs_get_memconf(cs, &base, &size);
+ if (gpmc_cs_insert_mem(cs, base, size) < 0)
+ BUG();
+ }
+}
+
+static int __init gpmc_init(void)
+{
+ u32 l, irq;
+ int cs, ret = -EINVAL;
+ int gpmc_irq;
+ char *ck = NULL;
+
+ if (cpu_is_omap24xx()) {
+ ck = "core_l3_ck";
+ if (cpu_is_omap2420())
+ l = OMAP2420_GPMC_BASE;
+ else
+ l = OMAP34XX_GPMC_BASE;
+ gpmc_irq = INT_34XX_GPMC_IRQ;
+ } else if (cpu_is_omap34xx()) {
+ ck = "gpmc_fck";
+ l = OMAP34XX_GPMC_BASE;
+ gpmc_irq = INT_34XX_GPMC_IRQ;
+ } else if (cpu_is_omap44xx()) {
+ ck = "gpmc_ck";
+ l = OMAP44XX_GPMC_BASE;
+ gpmc_irq = OMAP44XX_IRQ_GPMC;
+ }
+
+ if (WARN_ON(!ck))
+ return ret;
+
+ gpmc_l3_clk = clk_get(NULL, ck);
+ if (IS_ERR(gpmc_l3_clk)) {
+ printk(KERN_ERR "Could not get GPMC clock %s\n", ck);
+ BUG();
+ }
+
+ gpmc_base = ioremap(l, SZ_4K);
+ if (!gpmc_base) {
+ clk_put(gpmc_l3_clk);
+ printk(KERN_ERR "Could not get GPMC register memory\n");
+ BUG();
+ }
+
+ clk_enable(gpmc_l3_clk);
+
+ l = gpmc_read_reg(GPMC_REVISION);
+ printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
+ /* Set smart idle mode and automatic L3 clock gating */
+ l = gpmc_read_reg(GPMC_SYSCONFIG);
+ l &= 0x03 << 3;
+ l |= (0x02 << 3) | (1 << 0);
+ gpmc_write_reg(GPMC_SYSCONFIG, l);
+ gpmc_mem_init();
+
+ /* initalize the irq_chained */
+ irq = OMAP_GPMC_IRQ_BASE;
+ for (cs = 0; cs < GPMC_CS_NUM; cs++) {
+ irq_set_chip_and_handler(irq, &dummy_irq_chip,
+ handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ irq++;
+ }
+
+ ret = request_irq(gpmc_irq,
+ gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base);
+ if (ret)
+ pr_err("gpmc: irq-%d could not claim: err %d\n",
+ gpmc_irq, ret);
+ return ret;
+}
+postcore_initcall(gpmc_init);
+
+static irqreturn_t gpmc_handle_irq(int irq, void *dev)
+{
+ u8 cs;
+
+ /* check cs to invoke the irq */
+ cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7;
+ if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END)
+ generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap3_gpmc_regs gpmc_context;
+
+void omap3_gpmc_save_context(void)
+{
+ int i;
+
+ gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG);
+ gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE);
+ gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL);
+ gpmc_context.config = gpmc_read_reg(GPMC_CONFIG);
+ gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1);
+ gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2);
+ gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL);
+ for (i = 0; i < GPMC_CS_NUM; i++) {
+ gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i);
+ if (gpmc_context.cs_context[i].is_valid) {
+ gpmc_context.cs_context[i].config1 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG1);
+ gpmc_context.cs_context[i].config2 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG2);
+ gpmc_context.cs_context[i].config3 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG3);
+ gpmc_context.cs_context[i].config4 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG4);
+ gpmc_context.cs_context[i].config5 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG5);
+ gpmc_context.cs_context[i].config6 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG6);
+ gpmc_context.cs_context[i].config7 =
+ gpmc_cs_read_reg(i, GPMC_CS_CONFIG7);
+ }
+ }
+}
+
+void omap3_gpmc_restore_context(void)
+{
+ int i;
+
+ gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig);
+ gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable);
+ gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl);
+ gpmc_write_reg(GPMC_CONFIG, gpmc_context.config);
+ gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1);
+ gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2);
+ gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control);
+ for (i = 0; i < GPMC_CS_NUM; i++) {
+ if (gpmc_context.cs_context[i].is_valid) {
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG1,
+ gpmc_context.cs_context[i].config1);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG2,
+ gpmc_context.cs_context[i].config2);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG3,
+ gpmc_context.cs_context[i].config3);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG4,
+ gpmc_context.cs_context[i].config4);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG5,
+ gpmc_context.cs_context[i].config5);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG6,
+ gpmc_context.cs_context[i].config6);
+ gpmc_cs_write_reg(i, GPMC_CS_CONFIG7,
+ gpmc_context.cs_context[i].config7);
+ }
+ }
+}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+/**
+ * gpmc_enable_hwecc - enable hardware ecc functionality
+ * @cs: chip select number
+ * @mode: read/write mode
+ * @dev_width: device bus width(1 for x16, 0 for x8)
+ * @ecc_size: bytes for which ECC will be generated
+ */
+int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size)
+{
+ unsigned int val;
+
+ /* check if ecc module is in used */
+ if (gpmc_ecc_used != -EINVAL)
+ return -EINVAL;
+
+ gpmc_ecc_used = cs;
+
+ /* clear ecc and enable bits */
+ val = ((0x00000001<<8) | 0x00000001);
+ gpmc_write_reg(GPMC_ECC_CONTROL, val);
+
+ /* program ecc and result sizes */
+ val = ((((ecc_size >> 1) - 1) << 22) | (0x0000000F));
+ gpmc_write_reg(GPMC_ECC_SIZE_CONFIG, val);
+
+ switch (mode) {
+ case GPMC_ECC_READ:
+ gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
+ break;
+ case GPMC_ECC_READSYN:
+ gpmc_write_reg(GPMC_ECC_CONTROL, 0x100);
+ break;
+ case GPMC_ECC_WRITE:
+ gpmc_write_reg(GPMC_ECC_CONTROL, 0x101);
+ break;
+ default:
+ printk(KERN_INFO "Error: Unrecognized Mode[%d]!\n", mode);
+ break;
+ }
+
+ /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */
+ val = (dev_width << 7) | (cs << 1) | (0x1);
+ gpmc_write_reg(GPMC_ECC_CONFIG, val);
+ return 0;
+}
+
+/**
+ * gpmc_calculate_ecc - generate non-inverted ecc bytes
+ * @cs: chip select number
+ * @dat: data pointer over which ecc is computed
+ * @ecc_code: ecc code buffer
+ *
+ * Using non-inverted ECC is considered ugly since writing a blank
+ * page (padding) will clear the ECC bytes. This is not a problem as long
+ * no one is trying to write data on the seemingly unused page. Reading
+ * an erased page will produce an ECC mismatch between generated and read
+ * ECC bytes that has to be dealt with separately.
+ */
+int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code)
+{
+ unsigned int val = 0x0;
+
+ if (gpmc_ecc_used != cs)
+ return -EINVAL;
+
+ /* read ecc result */
+ val = gpmc_read_reg(GPMC_ECC1_RESULT);
+ *ecc_code++ = val; /* P128e, ..., P1e */
+ *ecc_code++ = val >> 16; /* P128o, ..., P1o */
+ /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */
+ *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0);
+
+ gpmc_ecc_used = -EINVAL;
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
new file mode 100644
index 00000000..66868c5d
--- /dev/null
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -0,0 +1,524 @@
+/*
+ * linux/arch/arm/mach-omap2/hsmmc.c
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Texas Instruments
+ *
+ * This program is free software; you can 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/slab.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <mach/hardware.h>
+#include <plat/mmc.h>
+#include <plat/omap-pm.h>
+#include <plat/mux.h>
+#include <plat/omap_device.h>
+
+#include "mux.h"
+#include "hsmmc.h"
+#include "control.h"
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+static u16 control_pbias_offset;
+static u16 control_devconf1_offset;
+static u16 control_mmc1;
+
+#define HSMMC_NAME_LEN 9
+
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+
+static int hsmmc_get_context_loss(struct device *dev)
+{
+ return omap_pm_get_dev_context_loss_count(dev);
+}
+
+#else
+#define hsmmc_get_context_loss NULL
+#endif
+
+static void omap_hsmmc1_before_set_reg(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ u32 reg, prog_io;
+ struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+ if (mmc->slots[0].remux)
+ mmc->slots[0].remux(dev, slot, power_on);
+
+ /*
+ * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
+ * card with Vcc regulator (from twl4030 or whatever). OMAP has both
+ * 1.8V and 3.0V modes, controlled by the PBIAS register.
+ *
+ * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
+ * is most naturally TWL VSIM; those pins also use PBIAS.
+ *
+ * FIXME handle VMMC1A as needed ...
+ */
+ if (power_on) {
+ if (cpu_is_omap2430()) {
+ reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
+ if ((1 << vdd) >= MMC_VDD_30_31)
+ reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
+ else
+ reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
+ omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
+ }
+
+ if (mmc->slots[0].internal_clock) {
+ reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ reg |= OMAP2_MMCSDIO1ADPCLKISEL;
+ omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
+ }
+
+ reg = omap_ctrl_readl(control_pbias_offset);
+ if (cpu_is_omap3630()) {
+ /* Set MMC I/O to 52Mhz */
+ prog_io = omap_ctrl_readl(OMAP343X_CONTROL_PROG_IO1);
+ prog_io |= OMAP3630_PRG_SDMMC1_SPEEDCTRL;
+ omap_ctrl_writel(prog_io, OMAP343X_CONTROL_PROG_IO1);
+ } else {
+ reg |= OMAP2_PBIASSPEEDCTRL0;
+ }
+ reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+ omap_ctrl_writel(reg, control_pbias_offset);
+ } else {
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+ omap_ctrl_writel(reg, control_pbias_offset);
+ }
+}
+
+static void omap_hsmmc1_after_set_reg(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ u32 reg;
+
+ /* 100ms delay required for PBIAS configuration */
+ msleep(100);
+
+ if (power_on) {
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
+ if ((1 << vdd) <= MMC_VDD_165_195)
+ reg &= ~OMAP2_PBIASLITEVMODE0;
+ else
+ reg |= OMAP2_PBIASLITEVMODE0;
+ omap_ctrl_writel(reg, control_pbias_offset);
+ } else {
+ reg = omap_ctrl_readl(control_pbias_offset);
+ reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
+ OMAP2_PBIASLITEVMODE0);
+ omap_ctrl_writel(reg, control_pbias_offset);
+ }
+}
+
+static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ u32 reg;
+
+ /*
+ * Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
+ * card with Vcc regulator (from twl4030 or whatever). OMAP has both
+ * 1.8V and 3.0V modes, controlled by the PBIAS register.
+ *
+ * In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
+ * is most naturally TWL VSIM; those pins also use PBIAS.
+ *
+ * FIXME handle VMMC1A as needed ...
+ */
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
+}
+
+static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ u32 reg;
+ unsigned long timeout;
+
+ if (power_on) {
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg |= OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK;
+ if ((1 << vdd) <= MMC_VDD_165_195)
+ reg &= ~OMAP4_MMC1_PBIASLITE_VMODE_MASK;
+ else
+ reg |= OMAP4_MMC1_PBIASLITE_VMODE_MASK;
+ reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
+
+ timeout = jiffies + msecs_to_jiffies(5);
+ do {
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ if (!(reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK))
+ break;
+ usleep_range(100, 200);
+ } while (!time_after(jiffies, timeout));
+
+ if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
+ pr_err("Pbias Voltage is not same as LDO\n");
+ /* Caution : On VMODE_ERROR Power Down MMC IO */
+ reg &= ~(OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
+ }
+ } else {
+ reg = omap4_ctrl_pad_readl(control_pbias_offset);
+ reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
+ OMAP4_MMC1_PWRDNZ_MASK |
+ OMAP4_MMC1_PBIASLITE_VMODE_MASK |
+ OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ omap4_ctrl_pad_writel(reg, control_pbias_offset);
+ }
+}
+
+static void hsmmc23_before_set_reg(struct device *dev, int slot,
+ int power_on, int vdd)
+{
+ struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+ if (mmc->slots[0].remux)
+ mmc->slots[0].remux(dev, slot, power_on);
+
+ if (power_on) {
+ /* Only MMC2 supports a CLKIN */
+ if (mmc->slots[0].internal_clock) {
+ u32 reg;
+
+ reg = omap_ctrl_readl(control_devconf1_offset);
+ reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+ omap_ctrl_writel(reg, control_devconf1_offset);
+ }
+ }
+}
+
+static int nop_mmc_set_power(struct device *dev, int slot, int power_on,
+ int vdd)
+{
+ return 0;
+}
+
+static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller,
+ int controller_nr)
+{
+ if ((mmc_controller->slots[0].switch_pin > 0) && \
+ (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->slots[0].switch_pin,
+ OMAP_PIN_INPUT_PULLUP);
+ if ((mmc_controller->slots[0].gpio_wp > 0) && \
+ (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES))
+ omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp,
+ OMAP_PIN_INPUT_PULLUP);
+ if (cpu_is_omap34xx()) {
+ if (controller_nr == 0) {
+ omap_mux_init_signal("sdmmc1_clk",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_cmd",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat0",
+ OMAP_PIN_INPUT_PULLUP);
+ if (mmc_controller->slots[0].caps &
+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
+ omap_mux_init_signal("sdmmc1_dat1",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat2",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat3",
+ OMAP_PIN_INPUT_PULLUP);
+ }
+ if (mmc_controller->slots[0].caps &
+ MMC_CAP_8_BIT_DATA) {
+ omap_mux_init_signal("sdmmc1_dat4",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat5",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat6",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc1_dat7",
+ OMAP_PIN_INPUT_PULLUP);
+ }
+ }
+ if (controller_nr == 1) {
+ /* MMC2 */
+ omap_mux_init_signal("sdmmc2_clk",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_cmd",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat0",
+ OMAP_PIN_INPUT_PULLUP);
+
+ /*
+ * For 8 wire configurations, Lines DAT4, 5, 6 and 7
+ * need to be muxed in the board-*.c files
+ */
+ if (mmc_controller->slots[0].caps &
+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) {
+ omap_mux_init_signal("sdmmc2_dat1",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat2",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat3",
+ OMAP_PIN_INPUT_PULLUP);
+ }
+ if (mmc_controller->slots[0].caps &
+ MMC_CAP_8_BIT_DATA) {
+ omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7",
+ OMAP_PIN_INPUT_PULLUP);
+ }
+ }
+
+ /*
+ * For MMC3 the pins need to be muxed in the board-*.c files
+ */
+ }
+}
+
+static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
+ struct omap_mmc_platform_data *mmc)
+{
+ char *hc_name;
+
+ hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
+ if (!hc_name) {
+ pr_err("Cannot allocate memory for controller slot name\n");
+ kfree(hc_name);
+ return -ENOMEM;
+ }
+
+ if (c->name)
+ strncpy(hc_name, c->name, HSMMC_NAME_LEN);
+ else
+ snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i",
+ c->mmc, 1);
+ mmc->slots[0].name = hc_name;
+ mmc->nr_slots = 1;
+ mmc->slots[0].caps = c->caps;
+ mmc->slots[0].internal_clock = !c->ext_clock;
+ mmc->dma_mask = 0xffffffff;
+ if (cpu_is_omap44xx())
+ mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
+ else
+ mmc->reg_offset = 0;
+
+ mmc->get_context_loss_count = hsmmc_get_context_loss;
+
+ mmc->slots[0].switch_pin = c->gpio_cd;
+ mmc->slots[0].gpio_wp = c->gpio_wp;
+
+ mmc->slots[0].remux = c->remux;
+ mmc->slots[0].init_card = c->init_card;
+
+ if (c->cover_only)
+ mmc->slots[0].cover = 1;
+
+ if (c->nonremovable)
+ mmc->slots[0].nonremovable = 1;
+
+ if (c->power_saving)
+ mmc->slots[0].power_saving = 1;
+
+ if (c->no_off)
+ mmc->slots[0].no_off = 1;
+
+ if (c->no_off_init)
+ mmc->slots[0].no_regulator_off_init = c->no_off_init;
+
+ if (c->vcc_aux_disable_is_sleep)
+ mmc->slots[0].vcc_aux_disable_is_sleep = 1;
+
+ /*
+ * NOTE: MMC slots should have a Vcc regulator set up.
+ * This may be from a TWL4030-family chip, another
+ * controllable regulator, or a fixed supply.
+ *
+ * temporary HACK: ocr_mask instead of fixed supply
+ */
+ mmc->slots[0].ocr_mask = c->ocr_mask;
+
+ if (cpu_is_omap3517() || cpu_is_omap3505())
+ mmc->slots[0].set_power = nop_mmc_set_power;
+ else
+ mmc->slots[0].features |= HSMMC_HAS_PBIAS;
+
+ if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0))
+ mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET;
+
+ switch (c->mmc) {
+ case 1:
+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
+ /* on-chip level shifting via PBIAS0/PBIAS1 */
+ if (cpu_is_omap44xx()) {
+ mmc->slots[0].before_set_reg =
+ omap4_hsmmc1_before_set_reg;
+ mmc->slots[0].after_set_reg =
+ omap4_hsmmc1_after_set_reg;
+ } else {
+ mmc->slots[0].before_set_reg =
+ omap_hsmmc1_before_set_reg;
+ mmc->slots[0].after_set_reg =
+ omap_hsmmc1_after_set_reg;
+ }
+ }
+
+ /* OMAP3630 HSMMC1 supports only 4-bit */
+ if (cpu_is_omap3630() &&
+ (c->caps & MMC_CAP_8_BIT_DATA)) {
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
+ c->caps |= MMC_CAP_4_BIT_DATA;
+ mmc->slots[0].caps = c->caps;
+ }
+ break;
+ case 2:
+ if (c->ext_clock)
+ c->transceiver = 1;
+ if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) {
+ c->caps &= ~MMC_CAP_8_BIT_DATA;
+ c->caps |= MMC_CAP_4_BIT_DATA;
+ }
+ /* FALLTHROUGH */
+ case 3:
+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) {
+ /* off-chip level shifting, or none */
+ mmc->slots[0].before_set_reg = hsmmc23_before_set_reg;
+ mmc->slots[0].after_set_reg = NULL;
+ }
+ break;
+ case 4:
+ case 5:
+ mmc->slots[0].before_set_reg = NULL;
+ mmc->slots[0].after_set_reg = NULL;
+ break;
+ default:
+ pr_err("MMC%d configuration not supported!\n", c->mmc);
+ kfree(hc_name);
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static struct omap_device_pm_latency omap_hsmmc_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+ /*
+ * XXX There should also be an entry here to power off/on the
+ * MMC regulators/PBIAS cells, etc.
+ */
+};
+
+#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
+
+void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct omap_device_pm_latency *ohl;
+ char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
+ struct omap_mmc_platform_data *mmc_data;
+ struct omap_mmc_dev_attr *mmc_dev_attr;
+ char *name;
+ int l;
+ int ohl_cnt = 0;
+
+ mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+ if (!mmc_data) {
+ pr_err("Cannot allocate memory for mmc device!\n");
+ goto done;
+ }
+
+ if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
+ pr_err("%s fails!\n", __func__);
+ goto done;
+ }
+ omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
+
+ name = "omap_hsmmc";
+ ohl = omap_hsmmc_latency;
+ ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency);
+
+ l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
+ "mmc%d", ctrl_nr);
+ WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
+ "String buffer overflow in MMC%d device setup\n", ctrl_nr);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ kfree(mmc_data->slots[0].name);
+ goto done;
+ }
+
+ if (oh->dev_attr != NULL) {
+ mmc_dev_attr = oh->dev_attr;
+ mmc_data->controller_flags = mmc_dev_attr->flags;
+ }
+
+ od = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
+ sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false);
+ if (IS_ERR(od)) {
+ WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
+ kfree(mmc_data->slots[0].name);
+ goto done;
+ }
+ /*
+ * return device handle to board setup code
+ * required to populate for regulator framework structure
+ */
+ hsmmcinfo->dev = &od->pdev.dev;
+
+done:
+ kfree(mmc_data);
+}
+
+void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ u32 reg;
+
+ if (!cpu_is_omap44xx()) {
+ if (cpu_is_omap2430()) {
+ control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
+ control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
+ } else {
+ control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+ control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
+ }
+ } else {
+ control_pbias_offset =
+ OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE;
+ control_mmc1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1;
+ reg = omap4_ctrl_pad_readl(control_mmc1);
+ reg |= (OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK |
+ OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK);
+ reg &= ~(OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK |
+ OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK);
+ reg |= (OMAP4_USBC1_DR0_SPEEDCTRL_MASK|
+ OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK |
+ OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK);
+ omap4_ctrl_pad_writel(reg, control_mmc1);
+ }
+
+ for (; controllers->mmc; controllers++)
+ omap_init_hsmmc(controllers, controllers->mmc);
+
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/hsmmc.h b/arch/arm/mach-omap2/hsmmc.h
new file mode 100644
index 00000000..f757e78d
--- /dev/null
+++ b/arch/arm/mach-omap2/hsmmc.h
@@ -0,0 +1,44 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * This program is free software; you can 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 mmc_card;
+
+struct omap2_hsmmc_info {
+ u8 mmc; /* controller 1/2/3 */
+ u32 caps; /* 4/8 wires and any additional host
+ * capabilities OR'd (ref. linux/mmc/host.h) */
+ bool transceiver; /* MMC-2 option */
+ bool ext_clock; /* use external pin for input clock */
+ bool cover_only; /* No card detect - just cover switch */
+ bool nonremovable; /* Nonremovable e.g. eMMC */
+ bool power_saving; /* Try to sleep or power off when possible */
+ bool no_off; /* power_saving and power is not to go off */
+ bool no_off_init; /* no power off when not in MMC sleep state */
+ bool vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
+ int gpio_cd; /* or -EINVAL */
+ int gpio_wp; /* or -EINVAL */
+ char *name; /* or NULL for default */
+ struct device *dev; /* returned: pointer to mmc adapter */
+ int ocr_mask; /* temporary HACK */
+ /* Remux (pad configuration) when powering on/off */
+ void (*remux)(struct device *dev, int slot, int power_on);
+ /* init some special card */
+ void (*init_card)(struct mmc_card *card);
+};
+
+#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+void omap2_hsmmc_init(struct omap2_hsmmc_info *);
+
+#else
+
+static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
new file mode 100644
index 00000000..06d4a806
--- /dev/null
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP hardware spinlock device initialization
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Contact: Simon Que <sque@ti.com>
+ * Hari Kanigeri <h-kanigeri2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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/err.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+struct omap_device_pm_latency omap_spinlock_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ }
+};
+
+int __init hwspinlocks_init(void)
+{
+ int retval = 0;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ const char *oh_name = "spinlock";
+ const char *dev_name = "omap_hwspinlock";
+
+ /*
+ * Hwmod lookup will fail in case our platform doesn't support the
+ * hardware spinlock module, so it is safe to run this initcall
+ * on all omaps
+ */
+ oh = omap_hwmod_lookup(oh_name);
+ if (oh == NULL)
+ return -EINVAL;
+
+ od = omap_device_build(dev_name, 0, oh, NULL, 0,
+ omap_spinlock_latency,
+ ARRAY_SIZE(omap_spinlock_latency), false);
+ if (IS_ERR(od)) {
+ pr_err("Can't build omap_device for %s:%s\n", dev_name,
+ oh_name);
+ retval = PTR_ERR(od);
+ }
+
+ return retval;
+}
+/* early board code might need to reserve specific hwspinlock instances */
+postcore_initcall(hwspinlocks_init);
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
new file mode 100644
index 00000000..79c478c4
--- /dev/null
+++ b/arch/arm/mach-omap2/i2c.c
@@ -0,0 +1,39 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <plat/cpu.h>
+#include <plat/i2c.h>
+
+#include "mux.h"
+
+void __init omap2_i2c_mux_pins(int bus_id)
+{
+ char mux_name[sizeof("i2c2_scl.i2c2_scl")];
+
+ /* First I2C bus is not muxable */
+ if (bus_id == 1)
+ return;
+
+ sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
+ omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
+ sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
+ omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
+}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
new file mode 100644
index 00000000..2537090a
--- /dev/null
+++ b/arch/arm/mach-omap2/id.c
@@ -0,0 +1,559 @@
+/*
+ * linux/arch/arm/mach-omap2/id.c
+ *
+ * OMAP2 CPU identification code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009-11 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+
+#include <mach/id.h>
+
+#include "control.h"
+
+static struct omap_chip_id omap_chip;
+static unsigned int omap_revision;
+
+u32 omap3_features;
+
+unsigned int omap_rev(void)
+{
+ return omap_revision;
+}
+EXPORT_SYMBOL(omap_rev);
+
+/**
+ * omap_chip_is - test whether currently running OMAP matches a chip type
+ * @oc: omap_chip_t to test against
+ *
+ * Test whether the currently-running OMAP chip matches the supplied
+ * chip type 'oc'. Returns 1 upon a match; 0 upon failure.
+ */
+int omap_chip_is(struct omap_chip_id oci)
+{
+ return (oci.oc & omap_chip.oc) ? 1 : 0;
+}
+EXPORT_SYMBOL(omap_chip_is);
+
+int omap_type(void)
+{
+ u32 val = 0;
+
+ if (cpu_is_omap24xx()) {
+ val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+ } else if (cpu_is_omap34xx()) {
+ val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
+ } else if (cpu_is_omap44xx()) {
+ val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
+ } else {
+ pr_err("Cannot detect omap type!\n");
+ goto out;
+ }
+
+ val &= OMAP2_DEVICETYPE_MASK;
+ val >>= 8;
+
+out:
+ return val;
+}
+EXPORT_SYMBOL(omap_type);
+
+
+/*----------------------------------------------------------------------------*/
+
+#define OMAP_TAP_IDCODE 0x0204
+#define OMAP_TAP_DIE_ID_0 0x0218
+#define OMAP_TAP_DIE_ID_1 0x021C
+#define OMAP_TAP_DIE_ID_2 0x0220
+#define OMAP_TAP_DIE_ID_3 0x0224
+
+#define OMAP_TAP_DIE_ID_44XX_0 0x0200
+#define OMAP_TAP_DIE_ID_44XX_1 0x0208
+#define OMAP_TAP_DIE_ID_44XX_2 0x020c
+#define OMAP_TAP_DIE_ID_44XX_3 0x0210
+
+#define read_tap_reg(reg) __raw_readl(tap_base + (reg))
+
+struct omap_id {
+ u16 hawkeye; /* Silicon type (Hawkeye id) */
+ u8 dev; /* Device type from production_id reg */
+ u32 type; /* Combined type id copied to omap_revision */
+};
+
+/* Register values to detect the OMAP version */
+static struct omap_id omap_ids[] __initdata = {
+ { .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
+ { .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
+ { .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
+ { .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
+ { .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
+ { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
+};
+
+static void __iomem *tap_base;
+static u16 tap_prod_id;
+
+void omap_get_die_id(struct omap_die_id *odi)
+{
+ if (cpu_is_omap44xx()) {
+ odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
+ odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
+ odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
+ odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);
+
+ return;
+ }
+ odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
+ odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
+ odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
+ odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
+}
+
+static void __init omap24xx_check_revision(void)
+{
+ int i, j;
+ u32 idcode, prod_id;
+ u16 hawkeye;
+ u8 dev_type, rev;
+ struct omap_die_id odi;
+
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ prod_id = read_tap_reg(tap_prod_id);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0x0f;
+ dev_type = (prod_id >> 16) & 0x0f;
+ omap_get_die_id(&odi);
+
+ pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
+ idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
+ pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
+ pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
+ odi.id_1, (odi.id_1 >> 28) & 0xf);
+ pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
+ pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
+ pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
+ prod_id, dev_type);
+
+ /* Check hawkeye ids */
+ for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
+ if (hawkeye == omap_ids[i].hawkeye)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(omap_ids)) {
+ printk(KERN_ERR "Unknown OMAP CPU id\n");
+ return;
+ }
+
+ for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
+ if (dev_type == omap_ids[j].dev)
+ break;
+ }
+
+ if (j == ARRAY_SIZE(omap_ids)) {
+ printk(KERN_ERR "Unknown OMAP device type. "
+ "Handling it as OMAP%04x\n",
+ omap_ids[i].type >> 16);
+ j = i;
+ }
+
+ pr_info("OMAP%04x", omap_rev() >> 16);
+ if ((omap_rev() >> 8) & 0x0f)
+ pr_info("ES%x", (omap_rev() >> 12) & 0xf);
+ pr_info("\n");
+}
+
+#define OMAP3_CHECK_FEATURE(status,feat) \
+ if (((status & OMAP3_ ##feat## _MASK) \
+ >> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \
+ omap3_features |= OMAP3_HAS_ ##feat; \
+ }
+
+static void __init omap3_check_features(void)
+{
+ u32 status;
+
+ omap3_features = 0;
+
+ status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
+
+ OMAP3_CHECK_FEATURE(status, L2CACHE);
+ OMAP3_CHECK_FEATURE(status, IVA);
+ OMAP3_CHECK_FEATURE(status, SGX);
+ OMAP3_CHECK_FEATURE(status, NEON);
+ OMAP3_CHECK_FEATURE(status, ISP);
+ if (cpu_is_omap3630())
+ omap3_features |= OMAP3_HAS_192MHZ_CLK;
+ if (!cpu_is_omap3505() && !cpu_is_omap3517())
+ omap3_features |= OMAP3_HAS_IO_WAKEUP;
+
+ omap3_features |= OMAP3_HAS_SDRC;
+
+ /*
+ * TODO: Get additional info (where applicable)
+ * e.g. Size of L2 cache.
+ */
+}
+
+static void __init ti816x_check_features(void)
+{
+ omap3_features = OMAP3_HAS_NEON;
+}
+
+static void __init omap3_check_revision(void)
+{
+ u32 cpuid, idcode;
+ u16 hawkeye;
+ u8 rev;
+
+ omap_chip.oc = CHIP_IS_OMAP3430;
+
+ /*
+ * We cannot access revision registers on ES1.0.
+ * If the processor type is Cortex-A8 and the revision is 0x0
+ * it means its Cortex r0p0 which is 3430 ES1.0.
+ */
+ cpuid = read_cpuid(CPUID_ID);
+ if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
+ omap_revision = OMAP3430_REV_ES1_0;
+ omap_chip.oc |= CHIP_IS_OMAP3430ES1;
+ return;
+ }
+
+ /*
+ * Detection for 34xx ES2.0 and above can be done with just
+ * hawkeye and rev. See TRM 1.5.2 Device Identification.
+ * Note that rev does not map directly to our defined processor
+ * revision numbers as ES1.0 uses value 0.
+ */
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0xff;
+
+ switch (hawkeye) {
+ case 0xb7ae:
+ /* Handle 34xx/35xx devices */
+ switch (rev) {
+ case 0: /* Take care of early samples */
+ case 1:
+ omap_revision = OMAP3430_REV_ES2_0;
+ omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ break;
+ case 2:
+ omap_revision = OMAP3430_REV_ES2_1;
+ omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ break;
+ case 3:
+ omap_revision = OMAP3430_REV_ES3_0;
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
+ break;
+ case 4:
+ omap_revision = OMAP3430_REV_ES3_1;
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ break;
+ case 7:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ omap_revision = OMAP3430_REV_ES3_1_2;
+
+ /* REVISIT: Add CHIP_IS_OMAP3430ES3_1_2? */
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ }
+ break;
+ case 0xb868:
+ /* Handle OMAP35xx/AM35xx devices
+ *
+ * Set the device to be OMAP3505 here. Actual device
+ * is identified later based on the features.
+ *
+ * REVISIT: AM3505/AM3517 should have their own CHIP_IS
+ */
+ omap_revision = OMAP3505_REV(rev);
+ omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ break;
+ case 0xb891:
+ /* Handle 36xx devices */
+ omap_chip.oc |= CHIP_IS_OMAP3630ES1;
+
+ switch(rev) {
+ case 0: /* Take care of early samples */
+ omap_revision = OMAP3630_REV_ES1_0;
+ break;
+ case 1:
+ omap_revision = OMAP3630_REV_ES1_1;
+ omap_chip.oc |= CHIP_IS_OMAP3630ES1_1;
+ break;
+ case 2:
+ default:
+ omap_revision = OMAP3630_REV_ES1_2;
+ omap_chip.oc |= CHIP_IS_OMAP3630ES1_2;
+ }
+ break;
+ case 0xb81e:
+ omap_chip.oc = CHIP_IS_TI816X;
+
+ switch (rev) {
+ case 0:
+ omap_revision = TI8168_REV_ES1_0;
+ break;
+ case 1:
+ omap_revision = TI8168_REV_ES1_1;
+ break;
+ default:
+ omap_revision = TI8168_REV_ES1_1;
+ }
+ break;
+ default:
+ /* Unknown default to latest silicon rev as default*/
+ omap_revision = OMAP3630_REV_ES1_2;
+ omap_chip.oc |= CHIP_IS_OMAP3630ES1_2;
+ }
+}
+
+static void __init omap4_check_revision(void)
+{
+ u32 idcode;
+ u16 hawkeye;
+ u8 rev;
+
+ /*
+ * The IC rev detection is done with hawkeye and rev.
+ * Note that rev does not map directly to defined processor
+ * revision numbers as ES1.0 uses value 0.
+ */
+ idcode = read_tap_reg(OMAP_TAP_IDCODE);
+ hawkeye = (idcode >> 12) & 0xffff;
+ rev = (idcode >> 28) & 0xf;
+
+ /*
+ * Few initial ES2.0 samples IDCODE is same as ES1.0
+ * Use ARM register to detect the correct ES version
+ */
+ if (!rev) {
+ idcode = read_cpuid(CPUID_ID);
+ rev = (idcode & 0xf) - 1;
+ }
+
+ switch (hawkeye) {
+ case 0xb852:
+ switch (rev) {
+ case 0:
+ omap_revision = OMAP4430_REV_ES1_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES1;
+ break;
+ case 1:
+ default:
+ omap_revision = OMAP4430_REV_ES2_0;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2;
+ }
+ break;
+ case 0xb95c:
+ switch (rev) {
+ case 3:
+ omap_revision = OMAP4430_REV_ES2_1;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_1;
+ break;
+ case 4:
+ default:
+ omap_revision = OMAP4430_REV_ES2_2;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
+ }
+ break;
+ default:
+ /* Unknown default to latest silicon rev as default */
+ omap_revision = OMAP4430_REV_ES2_2;
+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
+ }
+
+ pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16,
+ ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf));
+}
+
+#define OMAP3_SHOW_FEATURE(feat) \
+ if (omap3_has_ ##feat()) \
+ printk(#feat" ");
+
+static void __init omap3_cpuinfo(void)
+{
+ u8 rev = GET_OMAP_REVISION();
+ char cpu_name[16], cpu_rev[16];
+
+ /* OMAP3430 and OMAP3530 are assumed to be same.
+ *
+ * OMAP3525, OMAP3515 and OMAP3503 can be detected only based
+ * on available features. Upon detection, update the CPU id
+ * and CPU class bits.
+ */
+ if (cpu_is_omap3630()) {
+ strcpy(cpu_name, "OMAP3630");
+ } else if (cpu_is_omap3505()) {
+ /*
+ * AM35xx devices
+ */
+ if (omap3_has_sgx()) {
+ omap_revision = OMAP3517_REV(rev);
+ strcpy(cpu_name, "AM3517");
+ } else {
+ /* Already set in omap3_check_revision() */
+ strcpy(cpu_name, "AM3505");
+ }
+ } else if (cpu_is_ti816x()) {
+ strcpy(cpu_name, "TI816X");
+ } else if (omap3_has_iva() && omap3_has_sgx()) {
+ /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
+ strcpy(cpu_name, "OMAP3430/3530");
+ } else if (omap3_has_iva()) {
+ omap_revision = OMAP3525_REV(rev);
+ strcpy(cpu_name, "OMAP3525");
+ } else if (omap3_has_sgx()) {
+ omap_revision = OMAP3515_REV(rev);
+ strcpy(cpu_name, "OMAP3515");
+ } else {
+ omap_revision = OMAP3503_REV(rev);
+ strcpy(cpu_name, "OMAP3503");
+ }
+
+ if (cpu_is_omap3630() || cpu_is_ti816x()) {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ strcpy(cpu_rev, "1.1");
+ break;
+ case OMAP_REVBITS_02:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "1.2");
+ }
+ } else if (cpu_is_omap3505() || cpu_is_omap3517()) {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "1.1");
+ }
+ } else {
+ switch (rev) {
+ case OMAP_REVBITS_00:
+ strcpy(cpu_rev, "1.0");
+ break;
+ case OMAP_REVBITS_01:
+ strcpy(cpu_rev, "2.0");
+ break;
+ case OMAP_REVBITS_02:
+ strcpy(cpu_rev, "2.1");
+ break;
+ case OMAP_REVBITS_03:
+ strcpy(cpu_rev, "3.0");
+ break;
+ case OMAP_REVBITS_04:
+ strcpy(cpu_rev, "3.1");
+ break;
+ case OMAP_REVBITS_05:
+ /* FALLTHROUGH */
+ default:
+ /* Use the latest known revision as default */
+ strcpy(cpu_rev, "3.1.2");
+ }
+ }
+
+ /* Print verbose information */
+ pr_info("%s ES%s (", cpu_name, cpu_rev);
+
+ OMAP3_SHOW_FEATURE(l2cache);
+ OMAP3_SHOW_FEATURE(iva);
+ OMAP3_SHOW_FEATURE(sgx);
+ OMAP3_SHOW_FEATURE(neon);
+ OMAP3_SHOW_FEATURE(isp);
+ OMAP3_SHOW_FEATURE(192mhz_clk);
+
+ printk(")\n");
+}
+
+/*
+ * Try to detect the exact revision of the omap we're running on
+ */
+void __init omap2_check_revision(void)
+{
+ /*
+ * At this point we have an idea about the processor revision set
+ * earlier with omap2_set_globals_tap().
+ */
+ if (cpu_is_omap24xx()) {
+ omap24xx_check_revision();
+ } else if (cpu_is_omap34xx()) {
+ omap3_check_revision();
+
+ /* TI816X doesn't have feature register */
+ if (!cpu_is_ti816x())
+ omap3_check_features();
+ else
+ ti816x_check_features();
+
+ omap3_cpuinfo();
+ return;
+ } else if (cpu_is_omap44xx()) {
+ omap4_check_revision();
+ return;
+ } else {
+ pr_err("OMAP revision unknown, please fix!\n");
+ }
+
+ /*
+ * OK, now we know the exact revision. Initialize omap_chip bits
+ * for powerdowmain and clockdomain code.
+ */
+ if (cpu_is_omap243x()) {
+ /* Currently only supports 2430ES2.1 and 2430-all */
+ omap_chip.oc |= CHIP_IS_OMAP2430;
+ return;
+ } else if (cpu_is_omap242x()) {
+ /* Currently only supports 2420ES2.1.1 and 2420-all */
+ omap_chip.oc |= CHIP_IS_OMAP2420;
+ return;
+ }
+
+ pr_err("Uninitialized omap_chip, please fix!\n");
+}
+
+/*
+ * Set up things for map_io and processor detection later on. Gets called
+ * pretty much first thing from board init. For multi-omap, this gets
+ * cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
+ * detect the exact revision later on in omap2_detect_revision() once map_io
+ * is done.
+ */
+void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
+{
+ omap_revision = omap2_globals->class;
+ tap_base = omap2_globals->tap;
+
+ if (cpu_is_omap34xx())
+ tap_prod_id = 0x0210;
+ else
+ tap_prod_id = 0x0208;
+}
diff --git a/arch/arm/mach-omap2/include/mach/am35xx.h b/arch/arm/mach-omap2/include/mach/am35xx.h
new file mode 100644
index 00000000..f1e13d1c
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/am35xx.h
@@ -0,0 +1,44 @@
+/*:
+ * Address mappings and base address for AM35XX specific interconnects
+ * and peripherals.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: Sriramakrishnan <srk@ti.com>
+ * Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_AM35XX_H
+#define __ASM_ARCH_AM35XX_H
+
+/*
+ * Base addresses
+ * Note: OMAP3430 IVA2 memory space is being used for AM35xx IPSS modules
+ */
+#define AM35XX_IPSS_EMAC_BASE 0x5C000000
+#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
+#define AM35XX_IPSS_HECC_BASE 0x5C050000
+#define AM35XX_IPSS_VPFE_BASE 0x5C060000
+
+
+/* HECC module specifc offset definitions */
+#define AM35XX_HECC_SCC_HECC_OFFSET (0x0)
+#define AM35XX_HECC_SCC_RAM_OFFSET (0x3000)
+#define AM35XX_HECC_RAM_OFFSET (0x3000)
+#define AM35XX_HECC_MBOX_OFFSET (0x2000)
+#define AM35XX_HECC_INT_LINE (0x0)
+#define AM35XX_HECC_VERSION (0x1)
+
+#define AM35XX_EMAC_CNTRL_OFFSET (0x10000)
+#define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0)
+#define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000)
+#define AM35XX_EMAC_MDIO_OFFSET (0x30000)
+#define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000)
+#define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \
+ AM3517_EMAC_CNTRL_RAM_OFFSET)
+#define AM35XX_EMAC_HW_RAM_ADDR (0x01E20000)
+
+#endif /* __ASM_ARCH_AM35XX_H */
diff --git a/arch/arm/mach-omap2/include/mach/board-rx51.h b/arch/arm/mach-omap2/include/mach/board-rx51.h
new file mode 100644
index 00000000..b76f49e7
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/board-rx51.h
@@ -0,0 +1,11 @@
+/*
+ * Defines for rx51 boards
+ */
+
+#ifndef _OMAP_BOARD_RX51_H
+#define _OMAP_BOARD_RX51_H
+
+extern void __init rx51_peripherals_init(void);
+extern void __init rx51_video_mem_init(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h
new file mode 100644
index 00000000..775fdc3b
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
@@ -0,0 +1,12 @@
+/*
+ * Defines for zoom boards
+ */
+#include <video/omapdss.h>
+
+#define ZOOM_NAND_CS 0
+
+extern int __init zoom_debugboard_init(void);
+extern void __init zoom_peripherals_init(void);
+extern void __init zoom_display_init(void);
+
+#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
diff --git a/arch/arm/mach-omap2/include/mach/clkdev.h b/arch/arm/mach-omap2/include/mach/clkdev.h
new file mode 100644
index 00000000..53b02744
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/clkdev.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/clkdev.h
+ */
+
+#include <plat/clkdev.h>
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
new file mode 100644
index 00000000..2f7ac70a
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_core_44xx.h
@@ -0,0 +1,391 @@
+/*
+ * OMAP44xx CTRL_MODULE_CORE registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_CORE_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_CORE 0x4a002000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_CORE_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_CORE_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_CORE_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_0 0x0200
+#define OMAP4_CTRL_MODULE_CORE_ID_CODE 0x0204
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_1 0x0208
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_2 0x020c
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_DIE_ID_3 0x0210
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_0 0x0214
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1 0x0218
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_USB_CONF 0x021c
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_VDD_WKUP 0x0228
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP 0x0260
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_0 0x0264
+#define OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_DPLL_1 0x0268
+#define OMAP4_CTRL_MODULE_CORE_STATUS 0x02c4
+#define OMAP4_CTRL_MODULE_CORE_DEV_CONF 0x0300
+#define OMAP4_CTRL_MODULE_CORE_LDOVBB_IVA_VOLTAGE_CTRL 0x0314
+#define OMAP4_CTRL_MODULE_CORE_LDOVBB_MPU_VOLTAGE_CTRL 0x0318
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_IVA_VOLTAGE_CTRL 0x0320
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_MPU_VOLTAGE_CTRL 0x0324
+#define OMAP4_CTRL_MODULE_CORE_LDOSRAM_CORE_VOLTAGE_CTRL 0x0328
+#define OMAP4_CTRL_MODULE_CORE_TEMP_SENSOR 0x032c
+#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_0 0x0330
+#define OMAP4_CTRL_MODULE_CORE_DPLL_NWELL_TRIM_1 0x0334
+#define OMAP4_CTRL_MODULE_CORE_USBOTGHS_CONTROL 0x033c
+#define OMAP4_CTRL_MODULE_CORE_DSS_CONTROL 0x0340
+#define OMAP4_CTRL_MODULE_CORE_HWOBS_CONTROL 0x0350
+#define OMAP4_CTRL_MODULE_CORE_DEBOBS_FINAL_MUX_SEL 0x0400
+#define OMAP4_CTRL_MODULE_CORE_DEBOBS_MMR_MPU 0x0408
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL0 0x042c
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL1 0x0430
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL2 0x0434
+#define OMAP4_CTRL_MODULE_CORE_CONF_SDMA_REQ_SEL3 0x0438
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL0 0x0440
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL1 0x0444
+#define OMAP4_CTRL_MODULE_CORE_CONF_CLK_SEL2 0x0448
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_FREQLOCK_SEL 0x044c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_TINITZ_SEL 0x0450
+#define OMAP4_CTRL_MODULE_CORE_CONF_DPLL_PHASELOCK_SEL 0x0454
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_0 0x0480
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_1 0x0484
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_2 0x0488
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_3 0x048c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_4 0x0490
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_5 0x0494
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_6 0x0498
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_7 0x049c
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_8 0x04a0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_9 0x04a4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_10 0x04a8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_11 0x04ac
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_12 0x04b0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_13 0x04b4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_14 0x04b8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_15 0x04bc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_16 0x04c0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_17 0x04c4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_18 0x04c8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_19 0x04cc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_20 0x04d0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_21 0x04d4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_22 0x04d8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_23 0x04dc
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_24 0x04e0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_25 0x04e4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_26 0x04e8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_27 0x04ec
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_28 0x04f0
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_29 0x04f4
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_30 0x04f8
+#define OMAP4_CTRL_MODULE_CORE_CONF_DEBUG_SEL_TST_31 0x04fc
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* STD_FUSE_DIE_ID_0 */
+#define OMAP4_STD_FUSE_DIE_ID_0_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_0_MASK (0xffffffff << 0)
+
+/* ID_CODE */
+#define OMAP4_STD_FUSE_IDCODE_SHIFT 0
+#define OMAP4_STD_FUSE_IDCODE_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_1 */
+#define OMAP4_STD_FUSE_DIE_ID_1_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_1_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_2 */
+#define OMAP4_STD_FUSE_DIE_ID_2_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_2_MASK (0xffffffff << 0)
+
+/* STD_FUSE_DIE_ID_3 */
+#define OMAP4_STD_FUSE_DIE_ID_3_SHIFT 0
+#define OMAP4_STD_FUSE_DIE_ID_3_MASK (0xffffffff << 0)
+
+/* STD_FUSE_PROD_ID_0 */
+#define OMAP4_STD_FUSE_PROD_ID_0_SHIFT 0
+#define OMAP4_STD_FUSE_PROD_ID_0_MASK (0xffffffff << 0)
+
+/* STD_FUSE_PROD_ID_1 */
+#define OMAP4_STD_FUSE_PROD_ID_1_SHIFT 0
+#define OMAP4_STD_FUSE_PROD_ID_1_MASK (0xffffffff << 0)
+
+/* STD_FUSE_USB_CONF */
+#define OMAP4_USB_PROD_ID_SHIFT 16
+#define OMAP4_USB_PROD_ID_MASK (0xffff << 16)
+#define OMAP4_USB_VENDOR_ID_SHIFT 0
+#define OMAP4_USB_VENDOR_ID_MASK (0xffff << 0)
+
+/* STD_FUSE_OPP_VDD_WKUP */
+#define OMAP4_STD_FUSE_OPP_VDD_WKUP_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_VDD_WKUP_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_BGAP */
+#define OMAP4_STD_FUSE_OPP_BGAP_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_BGAP_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_DPLL_0 */
+#define OMAP4_STD_FUSE_OPP_DPLL_0_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_DPLL_0_MASK (0xffffffff << 0)
+
+/* STD_FUSE_OPP_DPLL_1 */
+#define OMAP4_STD_FUSE_OPP_DPLL_1_SHIFT 0
+#define OMAP4_STD_FUSE_OPP_DPLL_1_MASK (0xffffffff << 0)
+
+/* STATUS */
+#define OMAP4_ATTILA_CONF_SHIFT 11
+#define OMAP4_ATTILA_CONF_MASK (0x3 << 11)
+#define OMAP4_DEVICE_TYPE_SHIFT 8
+#define OMAP4_DEVICE_TYPE_MASK (0x7 << 8)
+#define OMAP4_SYS_BOOT_SHIFT 0
+#define OMAP4_SYS_BOOT_MASK (0xff << 0)
+
+/* DEV_CONF */
+#define OMAP4_DEV_CONF_SHIFT 1
+#define OMAP4_DEV_CONF_MASK (0x7fffffff << 1)
+#define OMAP4_USBPHY_PD_SHIFT 0
+#define OMAP4_USBPHY_PD_MASK (1 << 0)
+
+/* LDOVBB_IVA_VOLTAGE_CTRL */
+#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOVBBIVA_RBB_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOVBBIVA_RBB_VSET_IN_SHIFT 21
+#define OMAP4_LDOVBBIVA_RBB_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_SHIFT 16
+#define OMAP4_LDOVBBIVA_RBB_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOVBBIVA_FBB_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOVBBIVA_FBB_VSET_IN_SHIFT 5
+#define OMAP4_LDOVBBIVA_FBB_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_SHIFT 0
+#define OMAP4_LDOVBBIVA_FBB_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOVBB_MPU_VOLTAGE_CTRL */
+#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOVBBMPU_RBB_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOVBBMPU_RBB_VSET_IN_SHIFT 21
+#define OMAP4_LDOVBBMPU_RBB_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_SHIFT 16
+#define OMAP4_LDOVBBMPU_RBB_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOVBBMPU_FBB_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOVBBMPU_FBB_VSET_IN_SHIFT 5
+#define OMAP4_LDOVBBMPU_FBB_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_SHIFT 0
+#define OMAP4_LDOVBBMPU_FBB_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_IVA_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMIVA_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMIVA_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMIVA_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMIVA_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_MPU_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMMPU_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMMPU_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMMPU_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMMPU_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* LDOSRAM_CORE_VOLTAGE_CTRL */
+#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_SHIFT 26
+#define OMAP4_LDOSRAMCORE_RETMODE_MUX_CTRL_MASK (1 << 26)
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_SHIFT 21
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_IN_MASK (0x1f << 21)
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_SHIFT 16
+#define OMAP4_LDOSRAMCORE_RETMODE_VSET_OUT_MASK (0x1f << 16)
+#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_SHIFT 10
+#define OMAP4_LDOSRAMCORE_ACTMODE_MUX_CTRL_MASK (1 << 10)
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_SHIFT 5
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_IN_MASK (0x1f << 5)
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_SHIFT 0
+#define OMAP4_LDOSRAMCORE_ACTMODE_VSET_OUT_MASK (0x1f << 0)
+
+/* TEMP_SENSOR */
+#define OMAP4_BGAP_TEMPSOFF_SHIFT 12
+#define OMAP4_BGAP_TEMPSOFF_MASK (1 << 12)
+#define OMAP4_BGAP_TSHUT_SHIFT 11
+#define OMAP4_BGAP_TSHUT_MASK (1 << 11)
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_SHIFT 10
+#define OMAP4_BGAP_TEMP_SENSOR_CONTCONV_MASK (1 << 10)
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_SHIFT 9
+#define OMAP4_BGAP_TEMP_SENSOR_SOC_MASK (1 << 9)
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_SHIFT 8
+#define OMAP4_BGAP_TEMP_SENSOR_EOCZ_MASK (1 << 8)
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_SHIFT 0
+#define OMAP4_BGAP_TEMP_SENSOR_DTEMP_MASK (0xff << 0)
+
+/* DPLL_NWELL_TRIM_0 */
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_SHIFT 29
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MUX_CTRL_MASK (1 << 29)
+#define OMAP4_DPLL_ABE_NWELL_TRIM_SHIFT 24
+#define OMAP4_DPLL_ABE_NWELL_TRIM_MASK (0x1f << 24)
+#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_SHIFT 23
+#define OMAP4_DPLL_PER_NWELL_TRIM_MUX_CTRL_MASK (1 << 23)
+#define OMAP4_DPLL_PER_NWELL_TRIM_SHIFT 18
+#define OMAP4_DPLL_PER_NWELL_TRIM_MASK (0x1f << 18)
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_SHIFT 17
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MUX_CTRL_MASK (1 << 17)
+#define OMAP4_DPLL_CORE_NWELL_TRIM_SHIFT 12
+#define OMAP4_DPLL_CORE_NWELL_TRIM_MASK (0x1f << 12)
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_SHIFT 11
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MUX_CTRL_MASK (1 << 11)
+#define OMAP4_DPLL_IVA_NWELL_TRIM_SHIFT 6
+#define OMAP4_DPLL_IVA_NWELL_TRIM_MASK (0x1f << 6)
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_SHIFT 5
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MUX_CTRL_MASK (1 << 5)
+#define OMAP4_DPLL_MPU_NWELL_TRIM_SHIFT 0
+#define OMAP4_DPLL_MPU_NWELL_TRIM_MASK (0x1f << 0)
+
+/* DPLL_NWELL_TRIM_1 */
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_SHIFT 29
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MUX_CTRL_MASK (1 << 29)
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_SHIFT 24
+#define OMAP4_DPLL_UNIPRO_NWELL_TRIM_MASK (0x1f << 24)
+#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_SHIFT 23
+#define OMAP4_DPLL_USB_NWELL_TRIM_MUX_CTRL_MASK (1 << 23)
+#define OMAP4_DPLL_USB_NWELL_TRIM_SHIFT 18
+#define OMAP4_DPLL_USB_NWELL_TRIM_MASK (0x1f << 18)
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_SHIFT 17
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MUX_CTRL_MASK (1 << 17)
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_SHIFT 12
+#define OMAP4_DPLL_HDMI_NWELL_TRIM_MASK (0x1f << 12)
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_SHIFT 11
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MUX_CTRL_MASK (1 << 11)
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_SHIFT 6
+#define OMAP4_DPLL_DSI2_NWELL_TRIM_MASK (0x1f << 6)
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_SHIFT 5
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MUX_CTRL_MASK (1 << 5)
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_SHIFT 0
+#define OMAP4_DPLL_DSI1_NWELL_TRIM_MASK (0x1f << 0)
+
+/* USBOTGHS_CONTROL */
+#define OMAP4_DISCHRGVBUS_SHIFT 8
+#define OMAP4_DISCHRGVBUS_MASK (1 << 8)
+#define OMAP4_CHRGVBUS_SHIFT 7
+#define OMAP4_CHRGVBUS_MASK (1 << 7)
+#define OMAP4_DRVVBUS_SHIFT 6
+#define OMAP4_DRVVBUS_MASK (1 << 6)
+#define OMAP4_IDPULLUP_SHIFT 5
+#define OMAP4_IDPULLUP_MASK (1 << 5)
+#define OMAP4_IDDIG_SHIFT 4
+#define OMAP4_IDDIG_MASK (1 << 4)
+#define OMAP4_SESSEND_SHIFT 3
+#define OMAP4_SESSEND_MASK (1 << 3)
+#define OMAP4_VBUSVALID_SHIFT 2
+#define OMAP4_VBUSVALID_MASK (1 << 2)
+#define OMAP4_BVALID_SHIFT 1
+#define OMAP4_BVALID_MASK (1 << 1)
+#define OMAP4_AVALID_SHIFT 0
+#define OMAP4_AVALID_MASK (1 << 0)
+
+/* DSS_CONTROL */
+#define OMAP4_DSS_MUX6_SELECT_SHIFT 0
+#define OMAP4_DSS_MUX6_SELECT_MASK (1 << 0)
+
+/* HWOBS_CONTROL */
+#define OMAP4_HWOBS_CLKDIV_SEL_SHIFT 3
+#define OMAP4_HWOBS_CLKDIV_SEL_MASK (0x1f << 3)
+#define OMAP4_HWOBS_ALL_ZERO_MODE_SHIFT 2
+#define OMAP4_HWOBS_ALL_ZERO_MODE_MASK (1 << 2)
+#define OMAP4_HWOBS_ALL_ONE_MODE_SHIFT 1
+#define OMAP4_HWOBS_ALL_ONE_MODE_MASK (1 << 1)
+#define OMAP4_HWOBS_MACRO_ENABLE_SHIFT 0
+#define OMAP4_HWOBS_MACRO_ENABLE_MASK (1 << 0)
+
+/* DEBOBS_FINAL_MUX_SEL */
+#define OMAP4_SELECT_SHIFT 0
+#define OMAP4_SELECT_MASK (0xffffffff << 0)
+
+/* DEBOBS_MMR_MPU */
+#define OMAP4_SELECT_DEBOBS_MMR_MPU_SHIFT 0
+#define OMAP4_SELECT_DEBOBS_MMR_MPU_MASK (0xf << 0)
+
+/* CONF_SDMA_REQ_SEL0 */
+#define OMAP4_MULT_SHIFT 0
+#define OMAP4_MULT_MASK (0x7f << 0)
+
+/* CONF_CLK_SEL0 */
+#define OMAP4_MULT_CONF_CLK_SEL0_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL0_MASK (0x7 << 0)
+
+/* CONF_CLK_SEL1 */
+#define OMAP4_MULT_CONF_CLK_SEL1_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL1_MASK (0x7 << 0)
+
+/* CONF_CLK_SEL2 */
+#define OMAP4_MULT_CONF_CLK_SEL2_SHIFT 0
+#define OMAP4_MULT_CONF_CLK_SEL2_MASK (0x7 << 0)
+
+/* CONF_DPLL_FREQLOCK_SEL */
+#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_FREQLOCK_SEL_MASK (0x7 << 0)
+
+/* CONF_DPLL_TINITZ_SEL */
+#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_TINITZ_SEL_MASK (0x7 << 0)
+
+/* CONF_DPLL_PHASELOCK_SEL */
+#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_SHIFT 0
+#define OMAP4_MULT_CONF_DPLL_PHASELOCK_SEL_MASK (0x7 << 0)
+
+/* CONF_DEBUG_SEL_TST_0 */
+#define OMAP4_MODE_SHIFT 0
+#define OMAP4_MODE_MASK (0xf << 0)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
new file mode 100644
index 00000000..c88420de
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_core_44xx.h
@@ -0,0 +1,1409 @@
+/*
+ * OMAP44xx CTRL_MODULE_PAD_CORE registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_CORE_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_PAD_CORE 0x4a100000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_PAD_CORE_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_0 0x01d8
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_1 0x01dc
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_2 0x01e0
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_3 0x01e4
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_4 0x01e8
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_5 0x01ec
+#define OMAP4_CTRL_MODULE_PAD_CORE_PADCONF_WAKEUPEVENT_6 0x01f0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_GLOBAL 0x05a0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PADCONF_MODE 0x05a4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_0 0x05a8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART1IO_PADCONF_1 0x05ac
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_0 0x05b0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART2IO_PADCONF_1 0x05b4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_0 0x05b8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_1 0x05bc
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SMART3IO_PADCONF_2 0x05c0
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC 0x05c4
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_SLIMBUS 0x05c8
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_PBIASLITE 0x0600
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_0 0x0604
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_CAMERA_RX 0x0608
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_AVDAC 0x060c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDMI_TX_PHY 0x0610
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC2 0x0614
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_DSIPHY 0x0618
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP 0x061c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB2PHYCORE 0x0620
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1 0x0624
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MMC1 0x0628
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HSI 0x062c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USB 0x0630
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_HDQ 0x0634
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_0 0x0638
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_1 0x063c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_2 0x0640
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO1_3 0x0644
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_0 0x0648
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_1 0x064c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_2 0x0650
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_LPDDR2IO2_3 0x0654
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_BUS_HOLD 0x0658
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_C2C 0x065c
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_RW 0x0660
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R 0x0664
+#define OMAP4_CTRL_MODULE_PAD_CORE_CORE_CONTROL_SPARE_R_C0 0x0668
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_1 0x0700
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_2 0x0704
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_3 0x0708
+#define OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_EFUSE_4 0x070c
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* PADCONF_WAKEUPEVENT_0 */
+#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_GPMC_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_GPMC_NWP_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_GPMC_NCS3_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_GPMC_NCS2_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_GPMC_NCS1_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_GPMC_NCS0_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_GPMC_A25_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_GPMC_A24_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_GPMC_A23_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_GPMC_A22_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_GPMC_A21_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_GPMC_A20_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_GPMC_A19_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_GPMC_A18_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_GPMC_A17_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_GPMC_A16_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_GPMC_AD15_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_GPMC_AD14_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_GPMC_AD13_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_GPMC_AD12_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_GPMC_AD11_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_GPMC_AD10_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_GPMC_AD9_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_GPMC_AD8_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_GPMC_AD7_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_GPMC_AD6_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_GPMC_AD5_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_GPMC_AD4_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_GPMC_AD3_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_GPMC_AD2_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_GPMC_AD1_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_GPMC_AD0_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_1 */
+#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_CAM_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_CAM_SHUTTER_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_CSI22_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_CSI22_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_CSI22_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_CSI22_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_CSI21_DY4_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_CSI21_DX4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_CSI21_DY3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_CSI21_DX3_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_CSI21_DY2_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_CSI21_DX2_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_CSI21_DY1_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_CSI21_DX1_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_CSI21_DY0_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_CSI21_DX0_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_HDMI_DDC_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_HDMI_DDC_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_HDMI_CEC_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_HDMI_HPD_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_C2C_DATA15_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_C2C_DATA14_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_C2C_DATA13_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_C2C_DATA12_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_C2C_DATA11_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_GPMC_WAIT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_GPMC_WAIT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_GPMC_NBE1_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_GPMC_NBE0_CLE_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_GPMC_NWE_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_GPMC_NOE_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_GPMC_NADV_ALE_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_2 */
+#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_ABE_MCBSP1_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_ABE_MCBSP2_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_ABE_MCBSP2_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_ABE_MCBSP2_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_ABE_MCBSP2_CLKX_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_SDMMC1_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_SDMMC1_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_SDMMC1_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_SDMMC1_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_SDMMC1_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_SDMMC1_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_SDMMC1_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_SDMMC1_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SDMMC1_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SDMMC1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_USBC1_ICUSB_DM_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_USBC1_ICUSB_DP_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_USBB1_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_USBB1_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_USBB1_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_USBB1_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_USBB1_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_USBB1_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_USBB1_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_USBB1_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_USBB1_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_USBB1_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_USBB1_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_USBB1_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_USBB1_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_USBB1_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_CAM_GLOBALRESET_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_3 */
+#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_MCSPI1_CS3_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_MCSPI1_CS2_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_MCSPI1_CS1_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_MCSPI1_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_MCSPI1_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_MCSPI1_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_MCSPI1_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_I2C4_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_I2C4_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_I2C3_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_I2C3_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_I2C2_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_I2C2_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_I2C1_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_I2C1_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_HDQ_SIO_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_UART2_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_UART2_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_UART2_RTS_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_UART2_CTS_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_ABE_DMIC_DIN3_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_ABE_DMIC_DIN2_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_ABE_DMIC_DIN1_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_ABE_DMIC_CLK1_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_ABE_CLKS_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_ABE_PDM_LB_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_ABE_PDM_FRAME_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_ABE_PDM_DL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_ABE_PDM_UL_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_ABE_MCBSP1_FSX_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_ABE_MCBSP1_DX_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_ABE_MCBSP1_DR_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_4 */
+#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_UNIPRO_TY0_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_UNIPRO_TX0_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_USBB2_HSIC_STROBE_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_USBB2_HSIC_DATA_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_USBB2_ULPITLL_DAT7_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_USBB2_ULPITLL_DAT6_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_USBB2_ULPITLL_DAT5_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_USBB2_ULPITLL_DAT4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_USBB2_ULPITLL_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_USBB2_ULPITLL_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_USBB2_ULPITLL_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_USBB2_ULPITLL_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_USBB2_ULPITLL_NXT_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_USBB2_ULPITLL_DIR_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_USBB2_ULPITLL_STP_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_USBB2_ULPITLL_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_UART4_TX_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_UART4_RX_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_MCSPI4_CS0_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_MCSPI4_SOMI_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_MCSPI4_SIMO_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_MCSPI4_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_SDMMC5_DAT3_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_SDMMC5_DAT2_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_SDMMC5_DAT1_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_SDMMC5_DAT0_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_SDMMC5_CMD_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_SDMMC5_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_UART3_TX_IRTX_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_UART3_RX_IRRX_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_UART3_RTS_SD_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_UART3_CTS_RCTX_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_5 */
+#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_SHIFT 31
+#define OMAP4_DPM_EMU11_DUPLICATEWAKEUPEVENT_MASK (1 << 31)
+#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_SHIFT 30
+#define OMAP4_DPM_EMU10_DUPLICATEWAKEUPEVENT_MASK (1 << 30)
+#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_SHIFT 29
+#define OMAP4_DPM_EMU9_DUPLICATEWAKEUPEVENT_MASK (1 << 29)
+#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_SHIFT 28
+#define OMAP4_DPM_EMU8_DUPLICATEWAKEUPEVENT_MASK (1 << 28)
+#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_SHIFT 27
+#define OMAP4_DPM_EMU7_DUPLICATEWAKEUPEVENT_MASK (1 << 27)
+#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_SHIFT 26
+#define OMAP4_DPM_EMU6_DUPLICATEWAKEUPEVENT_MASK (1 << 26)
+#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_SHIFT 25
+#define OMAP4_DPM_EMU5_DUPLICATEWAKEUPEVENT_MASK (1 << 25)
+#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_DPM_EMU4_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_DPM_EMU3_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_DPM_EMU2_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_DPM_EMU1_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_DPM_EMU0_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_SYS_BOOT5_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SYS_BOOT4_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SYS_BOOT3_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_SYS_BOOT2_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_SYS_BOOT1_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_SYS_BOOT0_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_SYS_NIRQ2_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_SYS_NIRQ1_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_FREF_CLK2_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_FREF_CLK1_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_UNIPRO_RY2_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_UNIPRO_RX2_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_UNIPRO_RY1_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_UNIPRO_RX1_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_UNIPRO_RY0_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_UNIPRO_RX0_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_UNIPRO_TY2_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_UNIPRO_TX2_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_UNIPRO_TY1_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_UNIPRO_TX1_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* PADCONF_WAKEUPEVENT_6 */
+#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_DPM_EMU19_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_DPM_EMU18_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_DPM_EMU17_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_DPM_EMU16_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_DPM_EMU15_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_DPM_EMU14_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_DPM_EMU13_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_DPM_EMU12_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* CONTROL_PADCONF_GLOBAL */
+#define OMAP4_FORCE_OFFMODE_EN_SHIFT 31
+#define OMAP4_FORCE_OFFMODE_EN_MASK (1 << 31)
+
+/* CONTROL_PADCONF_MODE */
+#define OMAP4_VDDS_DV_BANK0_SHIFT 31
+#define OMAP4_VDDS_DV_BANK0_MASK (1 << 31)
+#define OMAP4_VDDS_DV_BANK1_SHIFT 30
+#define OMAP4_VDDS_DV_BANK1_MASK (1 << 30)
+#define OMAP4_VDDS_DV_BANK3_SHIFT 29
+#define OMAP4_VDDS_DV_BANK3_MASK (1 << 29)
+#define OMAP4_VDDS_DV_BANK4_SHIFT 28
+#define OMAP4_VDDS_DV_BANK4_MASK (1 << 28)
+#define OMAP4_VDDS_DV_BANK5_SHIFT 27
+#define OMAP4_VDDS_DV_BANK5_MASK (1 << 27)
+#define OMAP4_VDDS_DV_BANK6_SHIFT 26
+#define OMAP4_VDDS_DV_BANK6_MASK (1 << 26)
+#define OMAP4_VDDS_DV_C2C_SHIFT 25
+#define OMAP4_VDDS_DV_C2C_MASK (1 << 25)
+#define OMAP4_VDDS_DV_CAM_SHIFT 24
+#define OMAP4_VDDS_DV_CAM_MASK (1 << 24)
+#define OMAP4_VDDS_DV_GPMC_SHIFT 23
+#define OMAP4_VDDS_DV_GPMC_MASK (1 << 23)
+#define OMAP4_VDDS_DV_SDMMC2_SHIFT 22
+#define OMAP4_VDDS_DV_SDMMC2_MASK (1 << 22)
+
+/* CONTROL_SMART1IO_PADCONF_0 */
+#define OMAP4_ABE_DR0_SC_SHIFT 30
+#define OMAP4_ABE_DR0_SC_MASK (0x3 << 30)
+#define OMAP4_CAM_DR0_SC_SHIFT 28
+#define OMAP4_CAM_DR0_SC_MASK (0x3 << 28)
+#define OMAP4_FREF_DR2_SC_SHIFT 26
+#define OMAP4_FREF_DR2_SC_MASK (0x3 << 26)
+#define OMAP4_FREF_DR3_SC_SHIFT 24
+#define OMAP4_FREF_DR3_SC_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR8_SC_SHIFT 22
+#define OMAP4_GPIO_DR8_SC_MASK (0x3 << 22)
+#define OMAP4_GPIO_DR9_SC_SHIFT 20
+#define OMAP4_GPIO_DR9_SC_MASK (0x3 << 20)
+#define OMAP4_GPMC_DR2_SC_SHIFT 18
+#define OMAP4_GPMC_DR2_SC_MASK (0x3 << 18)
+#define OMAP4_GPMC_DR3_SC_SHIFT 16
+#define OMAP4_GPMC_DR3_SC_MASK (0x3 << 16)
+#define OMAP4_GPMC_DR6_SC_SHIFT 14
+#define OMAP4_GPMC_DR6_SC_MASK (0x3 << 14)
+#define OMAP4_HDMI_DR0_SC_SHIFT 12
+#define OMAP4_HDMI_DR0_SC_MASK (0x3 << 12)
+#define OMAP4_MCSPI1_DR0_SC_SHIFT 10
+#define OMAP4_MCSPI1_DR0_SC_MASK (0x3 << 10)
+#define OMAP4_UART1_DR0_SC_SHIFT 8
+#define OMAP4_UART1_DR0_SC_MASK (0x3 << 8)
+#define OMAP4_UART3_DR0_SC_SHIFT 6
+#define OMAP4_UART3_DR0_SC_MASK (0x3 << 6)
+#define OMAP4_UART3_DR1_SC_SHIFT 4
+#define OMAP4_UART3_DR1_SC_MASK (0x3 << 4)
+#define OMAP4_UNIPRO_DR0_SC_SHIFT 2
+#define OMAP4_UNIPRO_DR0_SC_MASK (0x3 << 2)
+#define OMAP4_UNIPRO_DR1_SC_SHIFT 0
+#define OMAP4_UNIPRO_DR1_SC_MASK (0x3 << 0)
+
+/* CONTROL_SMART1IO_PADCONF_1 */
+#define OMAP4_ABE_DR0_LB_SHIFT 30
+#define OMAP4_ABE_DR0_LB_MASK (0x3 << 30)
+#define OMAP4_CAM_DR0_LB_SHIFT 28
+#define OMAP4_CAM_DR0_LB_MASK (0x3 << 28)
+#define OMAP4_FREF_DR2_LB_SHIFT 26
+#define OMAP4_FREF_DR2_LB_MASK (0x3 << 26)
+#define OMAP4_FREF_DR3_LB_SHIFT 24
+#define OMAP4_FREF_DR3_LB_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR8_LB_SHIFT 22
+#define OMAP4_GPIO_DR8_LB_MASK (0x3 << 22)
+#define OMAP4_GPIO_DR9_LB_SHIFT 20
+#define OMAP4_GPIO_DR9_LB_MASK (0x3 << 20)
+#define OMAP4_GPMC_DR2_LB_SHIFT 18
+#define OMAP4_GPMC_DR2_LB_MASK (0x3 << 18)
+#define OMAP4_GPMC_DR3_LB_SHIFT 16
+#define OMAP4_GPMC_DR3_LB_MASK (0x3 << 16)
+#define OMAP4_GPMC_DR6_LB_SHIFT 14
+#define OMAP4_GPMC_DR6_LB_MASK (0x3 << 14)
+#define OMAP4_HDMI_DR0_LB_SHIFT 12
+#define OMAP4_HDMI_DR0_LB_MASK (0x3 << 12)
+#define OMAP4_MCSPI1_DR0_LB_SHIFT 10
+#define OMAP4_MCSPI1_DR0_LB_MASK (0x3 << 10)
+#define OMAP4_UART1_DR0_LB_SHIFT 8
+#define OMAP4_UART1_DR0_LB_MASK (0x3 << 8)
+#define OMAP4_UART3_DR0_LB_SHIFT 6
+#define OMAP4_UART3_DR0_LB_MASK (0x3 << 6)
+#define OMAP4_UART3_DR1_LB_SHIFT 4
+#define OMAP4_UART3_DR1_LB_MASK (0x3 << 4)
+#define OMAP4_UNIPRO_DR0_LB_SHIFT 2
+#define OMAP4_UNIPRO_DR0_LB_MASK (0x3 << 2)
+#define OMAP4_UNIPRO_DR1_LB_SHIFT 0
+#define OMAP4_UNIPRO_DR1_LB_MASK (0x3 << 0)
+
+/* CONTROL_SMART2IO_PADCONF_0 */
+#define OMAP4_C2C_DR0_LB_SHIFT 31
+#define OMAP4_C2C_DR0_LB_MASK (1 << 31)
+#define OMAP4_DPM_DR1_LB_SHIFT 30
+#define OMAP4_DPM_DR1_LB_MASK (1 << 30)
+#define OMAP4_DPM_DR2_LB_SHIFT 29
+#define OMAP4_DPM_DR2_LB_MASK (1 << 29)
+#define OMAP4_DPM_DR3_LB_SHIFT 28
+#define OMAP4_DPM_DR3_LB_MASK (1 << 28)
+#define OMAP4_GPIO_DR0_LB_SHIFT 27
+#define OMAP4_GPIO_DR0_LB_MASK (1 << 27)
+#define OMAP4_GPIO_DR1_LB_SHIFT 26
+#define OMAP4_GPIO_DR1_LB_MASK (1 << 26)
+#define OMAP4_GPIO_DR10_LB_SHIFT 25
+#define OMAP4_GPIO_DR10_LB_MASK (1 << 25)
+#define OMAP4_GPIO_DR2_LB_SHIFT 24
+#define OMAP4_GPIO_DR2_LB_MASK (1 << 24)
+#define OMAP4_GPMC_DR0_LB_SHIFT 23
+#define OMAP4_GPMC_DR0_LB_MASK (1 << 23)
+#define OMAP4_GPMC_DR1_LB_SHIFT 22
+#define OMAP4_GPMC_DR1_LB_MASK (1 << 22)
+#define OMAP4_GPMC_DR4_LB_SHIFT 21
+#define OMAP4_GPMC_DR4_LB_MASK (1 << 21)
+#define OMAP4_GPMC_DR5_LB_SHIFT 20
+#define OMAP4_GPMC_DR5_LB_MASK (1 << 20)
+#define OMAP4_GPMC_DR7_LB_SHIFT 19
+#define OMAP4_GPMC_DR7_LB_MASK (1 << 19)
+#define OMAP4_HSI2_DR0_LB_SHIFT 18
+#define OMAP4_HSI2_DR0_LB_MASK (1 << 18)
+#define OMAP4_HSI2_DR1_LB_SHIFT 17
+#define OMAP4_HSI2_DR1_LB_MASK (1 << 17)
+#define OMAP4_HSI2_DR2_LB_SHIFT 16
+#define OMAP4_HSI2_DR2_LB_MASK (1 << 16)
+#define OMAP4_KPD_DR0_LB_SHIFT 15
+#define OMAP4_KPD_DR0_LB_MASK (1 << 15)
+#define OMAP4_KPD_DR1_LB_SHIFT 14
+#define OMAP4_KPD_DR1_LB_MASK (1 << 14)
+#define OMAP4_PDM_DR0_LB_SHIFT 13
+#define OMAP4_PDM_DR0_LB_MASK (1 << 13)
+#define OMAP4_SDMMC2_DR0_LB_SHIFT 12
+#define OMAP4_SDMMC2_DR0_LB_MASK (1 << 12)
+#define OMAP4_SDMMC3_DR0_LB_SHIFT 11
+#define OMAP4_SDMMC3_DR0_LB_MASK (1 << 11)
+#define OMAP4_SDMMC4_DR0_LB_SHIFT 10
+#define OMAP4_SDMMC4_DR0_LB_MASK (1 << 10)
+#define OMAP4_SDMMC4_DR1_LB_SHIFT 9
+#define OMAP4_SDMMC4_DR1_LB_MASK (1 << 9)
+#define OMAP4_SPI3_DR0_LB_SHIFT 8
+#define OMAP4_SPI3_DR0_LB_MASK (1 << 8)
+#define OMAP4_SPI3_DR1_LB_SHIFT 7
+#define OMAP4_SPI3_DR1_LB_MASK (1 << 7)
+#define OMAP4_UART3_DR2_LB_SHIFT 6
+#define OMAP4_UART3_DR2_LB_MASK (1 << 6)
+#define OMAP4_UART3_DR3_LB_SHIFT 5
+#define OMAP4_UART3_DR3_LB_MASK (1 << 5)
+#define OMAP4_UART3_DR4_LB_SHIFT 4
+#define OMAP4_UART3_DR4_LB_MASK (1 << 4)
+#define OMAP4_UART3_DR5_LB_SHIFT 3
+#define OMAP4_UART3_DR5_LB_MASK (1 << 3)
+#define OMAP4_USBA0_DR1_LB_SHIFT 2
+#define OMAP4_USBA0_DR1_LB_MASK (1 << 2)
+#define OMAP4_USBA_DR2_LB_SHIFT 1
+#define OMAP4_USBA_DR2_LB_MASK (1 << 1)
+
+/* CONTROL_SMART2IO_PADCONF_1 */
+#define OMAP4_USBB1_DR0_LB_SHIFT 31
+#define OMAP4_USBB1_DR0_LB_MASK (1 << 31)
+#define OMAP4_USBB2_DR0_LB_SHIFT 30
+#define OMAP4_USBB2_DR0_LB_MASK (1 << 30)
+#define OMAP4_USBA0_DR0_LB_SHIFT 29
+#define OMAP4_USBA0_DR0_LB_MASK (1 << 29)
+
+/* CONTROL_SMART3IO_PADCONF_0 */
+#define OMAP4_DMIC_DR0_MB_SHIFT 30
+#define OMAP4_DMIC_DR0_MB_MASK (0x3 << 30)
+#define OMAP4_GPIO_DR3_MB_SHIFT 28
+#define OMAP4_GPIO_DR3_MB_MASK (0x3 << 28)
+#define OMAP4_GPIO_DR4_MB_SHIFT 26
+#define OMAP4_GPIO_DR4_MB_MASK (0x3 << 26)
+#define OMAP4_GPIO_DR5_MB_SHIFT 24
+#define OMAP4_GPIO_DR5_MB_MASK (0x3 << 24)
+#define OMAP4_GPIO_DR6_MB_SHIFT 22
+#define OMAP4_GPIO_DR6_MB_MASK (0x3 << 22)
+#define OMAP4_HSI_DR1_MB_SHIFT 20
+#define OMAP4_HSI_DR1_MB_MASK (0x3 << 20)
+#define OMAP4_HSI_DR2_MB_SHIFT 18
+#define OMAP4_HSI_DR2_MB_MASK (0x3 << 18)
+#define OMAP4_HSI_DR3_MB_SHIFT 16
+#define OMAP4_HSI_DR3_MB_MASK (0x3 << 16)
+#define OMAP4_MCBSP2_DR0_MB_SHIFT 14
+#define OMAP4_MCBSP2_DR0_MB_MASK (0x3 << 14)
+#define OMAP4_MCSPI4_DR0_MB_SHIFT 12
+#define OMAP4_MCSPI4_DR0_MB_MASK (0x3 << 12)
+#define OMAP4_MCSPI4_DR1_MB_SHIFT 10
+#define OMAP4_MCSPI4_DR1_MB_MASK (0x3 << 10)
+#define OMAP4_SDMMC3_DR0_MB_SHIFT 8
+#define OMAP4_SDMMC3_DR0_MB_MASK (0x3 << 8)
+#define OMAP4_SPI2_DR0_MB_SHIFT 0
+#define OMAP4_SPI2_DR0_MB_MASK (0x3 << 0)
+
+/* CONTROL_SMART3IO_PADCONF_1 */
+#define OMAP4_SPI2_DR1_MB_SHIFT 30
+#define OMAP4_SPI2_DR1_MB_MASK (0x3 << 30)
+#define OMAP4_SPI2_DR2_MB_SHIFT 28
+#define OMAP4_SPI2_DR2_MB_MASK (0x3 << 28)
+#define OMAP4_UART2_DR0_MB_SHIFT 26
+#define OMAP4_UART2_DR0_MB_MASK (0x3 << 26)
+#define OMAP4_UART2_DR1_MB_SHIFT 24
+#define OMAP4_UART2_DR1_MB_MASK (0x3 << 24)
+#define OMAP4_UART4_DR0_MB_SHIFT 22
+#define OMAP4_UART4_DR0_MB_MASK (0x3 << 22)
+#define OMAP4_HSI_DR0_MB_SHIFT 20
+#define OMAP4_HSI_DR0_MB_MASK (0x3 << 20)
+
+/* CONTROL_SMART3IO_PADCONF_2 */
+#define OMAP4_DMIC_DR0_LB_SHIFT 31
+#define OMAP4_DMIC_DR0_LB_MASK (1 << 31)
+#define OMAP4_GPIO_DR3_LB_SHIFT 30
+#define OMAP4_GPIO_DR3_LB_MASK (1 << 30)
+#define OMAP4_GPIO_DR4_LB_SHIFT 29
+#define OMAP4_GPIO_DR4_LB_MASK (1 << 29)
+#define OMAP4_GPIO_DR5_LB_SHIFT 28
+#define OMAP4_GPIO_DR5_LB_MASK (1 << 28)
+#define OMAP4_GPIO_DR6_LB_SHIFT 27
+#define OMAP4_GPIO_DR6_LB_MASK (1 << 27)
+#define OMAP4_HSI_DR1_LB_SHIFT 26
+#define OMAP4_HSI_DR1_LB_MASK (1 << 26)
+#define OMAP4_HSI_DR2_LB_SHIFT 25
+#define OMAP4_HSI_DR2_LB_MASK (1 << 25)
+#define OMAP4_HSI_DR3_LB_SHIFT 24
+#define OMAP4_HSI_DR3_LB_MASK (1 << 24)
+#define OMAP4_MCBSP2_DR0_LB_SHIFT 23
+#define OMAP4_MCBSP2_DR0_LB_MASK (1 << 23)
+#define OMAP4_MCSPI4_DR0_LB_SHIFT 22
+#define OMAP4_MCSPI4_DR0_LB_MASK (1 << 22)
+#define OMAP4_MCSPI4_DR1_LB_SHIFT 21
+#define OMAP4_MCSPI4_DR1_LB_MASK (1 << 21)
+#define OMAP4_SLIMBUS2_DR0_LB_SHIFT 18
+#define OMAP4_SLIMBUS2_DR0_LB_MASK (1 << 18)
+#define OMAP4_SPI2_DR0_LB_SHIFT 16
+#define OMAP4_SPI2_DR0_LB_MASK (1 << 16)
+#define OMAP4_SPI2_DR1_LB_SHIFT 15
+#define OMAP4_SPI2_DR1_LB_MASK (1 << 15)
+#define OMAP4_SPI2_DR2_LB_SHIFT 14
+#define OMAP4_SPI2_DR2_LB_MASK (1 << 14)
+#define OMAP4_UART2_DR0_LB_SHIFT 13
+#define OMAP4_UART2_DR0_LB_MASK (1 << 13)
+#define OMAP4_UART2_DR1_LB_SHIFT 12
+#define OMAP4_UART2_DR1_LB_MASK (1 << 12)
+#define OMAP4_UART4_DR0_LB_SHIFT 11
+#define OMAP4_UART4_DR0_LB_MASK (1 << 11)
+#define OMAP4_HSI_DR0_LB_SHIFT 10
+#define OMAP4_HSI_DR0_LB_MASK (1 << 10)
+
+/* CONTROL_USBB_HSIC */
+#define OMAP4_USBB2_DR1_SR_SHIFT 30
+#define OMAP4_USBB2_DR1_SR_MASK (0x3 << 30)
+#define OMAP4_USBB2_DR1_I_SHIFT 27
+#define OMAP4_USBB2_DR1_I_MASK (0x7 << 27)
+#define OMAP4_USBB1_DR1_SR_SHIFT 25
+#define OMAP4_USBB1_DR1_SR_MASK (0x3 << 25)
+#define OMAP4_USBB1_DR1_I_SHIFT 22
+#define OMAP4_USBB1_DR1_I_MASK (0x7 << 22)
+#define OMAP4_USBB1_HSIC_DATA_WD_SHIFT 20
+#define OMAP4_USBB1_HSIC_DATA_WD_MASK (0x3 << 20)
+#define OMAP4_USBB1_HSIC_STROBE_WD_SHIFT 18
+#define OMAP4_USBB1_HSIC_STROBE_WD_MASK (0x3 << 18)
+#define OMAP4_USBB2_HSIC_DATA_WD_SHIFT 16
+#define OMAP4_USBB2_HSIC_DATA_WD_MASK (0x3 << 16)
+#define OMAP4_USBB2_HSIC_STROBE_WD_SHIFT 14
+#define OMAP4_USBB2_HSIC_STROBE_WD_MASK (0x3 << 14)
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 13
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 13)
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_SHIFT 11
+#define OMAP4_USBB1_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 11)
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 10
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 10)
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_SHIFT 8
+#define OMAP4_USBB1_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 8)
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_SHIFT 7
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_ENABLE_MASK (1 << 7)
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_SHIFT 5
+#define OMAP4_USBB2_HSIC_DATA_OFFMODE_WD_MASK (0x3 << 5)
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_SHIFT 4
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_ENABLE_MASK (1 << 4)
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_SHIFT 2
+#define OMAP4_USBB2_HSIC_STROBE_OFFMODE_WD_MASK (0x3 << 2)
+
+/* CONTROL_SLIMBUS */
+#define OMAP4_SLIMBUS1_DR0_MB_SHIFT 30
+#define OMAP4_SLIMBUS1_DR0_MB_MASK (0x3 << 30)
+#define OMAP4_SLIMBUS1_DR1_MB_SHIFT 28
+#define OMAP4_SLIMBUS1_DR1_MB_MASK (0x3 << 28)
+#define OMAP4_SLIMBUS2_DR0_MB_SHIFT 26
+#define OMAP4_SLIMBUS2_DR0_MB_MASK (0x3 << 26)
+#define OMAP4_SLIMBUS2_DR1_MB_SHIFT 24
+#define OMAP4_SLIMBUS2_DR1_MB_MASK (0x3 << 24)
+#define OMAP4_SLIMBUS2_DR2_MB_SHIFT 22
+#define OMAP4_SLIMBUS2_DR2_MB_MASK (0x3 << 22)
+#define OMAP4_SLIMBUS2_DR3_MB_SHIFT 20
+#define OMAP4_SLIMBUS2_DR3_MB_MASK (0x3 << 20)
+#define OMAP4_SLIMBUS1_DR0_LB_SHIFT 19
+#define OMAP4_SLIMBUS1_DR0_LB_MASK (1 << 19)
+#define OMAP4_SLIMBUS2_DR1_LB_SHIFT 18
+#define OMAP4_SLIMBUS2_DR1_LB_MASK (1 << 18)
+
+/* CONTROL_PBIASLITE */
+#define OMAP4_USIM_PBIASLITE_HIZ_MODE_SHIFT 31
+#define OMAP4_USIM_PBIASLITE_HIZ_MODE_MASK (1 << 31)
+#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_SHIFT 30
+#define OMAP4_USIM_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 30)
+#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_SHIFT 29
+#define OMAP4_USIM_PBIASLITE_VMODE_ERROR_MASK (1 << 29)
+#define OMAP4_USIM_PBIASLITE_PWRDNZ_SHIFT 28
+#define OMAP4_USIM_PBIASLITE_PWRDNZ_MASK (1 << 28)
+#define OMAP4_USIM_PBIASLITE_VMODE_SHIFT 27
+#define OMAP4_USIM_PBIASLITE_VMODE_MASK (1 << 27)
+#define OMAP4_MMC1_PWRDNZ_SHIFT 26
+#define OMAP4_MMC1_PWRDNZ_MASK (1 << 26)
+#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_SHIFT 25
+#define OMAP4_MMC1_PBIASLITE_HIZ_MODE_MASK (1 << 25)
+#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_SHIFT 24
+#define OMAP4_MMC1_PBIASLITE_SUPPLY_HI_OUT_MASK (1 << 24)
+#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_SHIFT 23
+#define OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK (1 << 23)
+#define OMAP4_MMC1_PBIASLITE_PWRDNZ_SHIFT 22
+#define OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK (1 << 22)
+#define OMAP4_MMC1_PBIASLITE_VMODE_SHIFT 21
+#define OMAP4_MMC1_PBIASLITE_VMODE_MASK (1 << 21)
+#define OMAP4_USBC1_ICUSB_PWRDNZ_SHIFT 20
+#define OMAP4_USBC1_ICUSB_PWRDNZ_MASK (1 << 20)
+
+/* CONTROL_I2C_0 */
+#define OMAP4_I2C4_SDA_GLFENB_SHIFT 31
+#define OMAP4_I2C4_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_I2C4_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_I2C4_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_I2C4_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_I2C4_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_I2C3_SDA_GLFENB_SHIFT 27
+#define OMAP4_I2C3_SDA_GLFENB_MASK (1 << 27)
+#define OMAP4_I2C3_SDA_LOAD_BITS_SHIFT 25
+#define OMAP4_I2C3_SDA_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_I2C3_SDA_PULLUPRESX_SHIFT 24
+#define OMAP4_I2C3_SDA_PULLUPRESX_MASK (1 << 24)
+#define OMAP4_I2C2_SDA_GLFENB_SHIFT 23
+#define OMAP4_I2C2_SDA_GLFENB_MASK (1 << 23)
+#define OMAP4_I2C2_SDA_LOAD_BITS_SHIFT 21
+#define OMAP4_I2C2_SDA_LOAD_BITS_MASK (0x3 << 21)
+#define OMAP4_I2C2_SDA_PULLUPRESX_SHIFT 20
+#define OMAP4_I2C2_SDA_PULLUPRESX_MASK (1 << 20)
+#define OMAP4_I2C1_SDA_GLFENB_SHIFT 19
+#define OMAP4_I2C1_SDA_GLFENB_MASK (1 << 19)
+#define OMAP4_I2C1_SDA_LOAD_BITS_SHIFT 17
+#define OMAP4_I2C1_SDA_LOAD_BITS_MASK (0x3 << 17)
+#define OMAP4_I2C1_SDA_PULLUPRESX_SHIFT 16
+#define OMAP4_I2C1_SDA_PULLUPRESX_MASK (1 << 16)
+#define OMAP4_I2C4_SCL_GLFENB_SHIFT 15
+#define OMAP4_I2C4_SCL_GLFENB_MASK (1 << 15)
+#define OMAP4_I2C4_SCL_LOAD_BITS_SHIFT 13
+#define OMAP4_I2C4_SCL_LOAD_BITS_MASK (0x3 << 13)
+#define OMAP4_I2C4_SCL_PULLUPRESX_SHIFT 12
+#define OMAP4_I2C4_SCL_PULLUPRESX_MASK (1 << 12)
+#define OMAP4_I2C3_SCL_GLFENB_SHIFT 11
+#define OMAP4_I2C3_SCL_GLFENB_MASK (1 << 11)
+#define OMAP4_I2C3_SCL_LOAD_BITS_SHIFT 9
+#define OMAP4_I2C3_SCL_LOAD_BITS_MASK (0x3 << 9)
+#define OMAP4_I2C3_SCL_PULLUPRESX_SHIFT 8
+#define OMAP4_I2C3_SCL_PULLUPRESX_MASK (1 << 8)
+#define OMAP4_I2C2_SCL_GLFENB_SHIFT 7
+#define OMAP4_I2C2_SCL_GLFENB_MASK (1 << 7)
+#define OMAP4_I2C2_SCL_LOAD_BITS_SHIFT 5
+#define OMAP4_I2C2_SCL_LOAD_BITS_MASK (0x3 << 5)
+#define OMAP4_I2C2_SCL_PULLUPRESX_SHIFT 4
+#define OMAP4_I2C2_SCL_PULLUPRESX_MASK (1 << 4)
+#define OMAP4_I2C1_SCL_GLFENB_SHIFT 3
+#define OMAP4_I2C1_SCL_GLFENB_MASK (1 << 3)
+#define OMAP4_I2C1_SCL_LOAD_BITS_SHIFT 1
+#define OMAP4_I2C1_SCL_LOAD_BITS_MASK (0x3 << 1)
+#define OMAP4_I2C1_SCL_PULLUPRESX_SHIFT 0
+#define OMAP4_I2C1_SCL_PULLUPRESX_MASK (1 << 0)
+
+/* CONTROL_CAMERA_RX */
+#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_SHIFT 31
+#define OMAP4_CAMERARX_UNIPRO_CTRLCLKEN_MASK (1 << 31)
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_SHIFT 29
+#define OMAP4_CAMERARX_CSI22_LANEENABLE_MASK (0x3 << 29)
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_SHIFT 24
+#define OMAP4_CAMERARX_CSI21_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_CAMERARX_UNIPRO_CAMMODE_SHIFT 22
+#define OMAP4_CAMERARX_UNIPRO_CAMMODE_MASK (0x3 << 22)
+#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_SHIFT 21
+#define OMAP4_CAMERARX_CSI22_CTRLCLKEN_MASK (1 << 21)
+#define OMAP4_CAMERARX_CSI22_CAMMODE_SHIFT 19
+#define OMAP4_CAMERARX_CSI22_CAMMODE_MASK (0x3 << 19)
+#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_SHIFT 18
+#define OMAP4_CAMERARX_CSI21_CTRLCLKEN_MASK (1 << 18)
+#define OMAP4_CAMERARX_CSI21_CAMMODE_SHIFT 16
+#define OMAP4_CAMERARX_CSI21_CAMMODE_MASK (0x3 << 16)
+
+/* CONTROL_AVDAC */
+#define OMAP4_AVDAC_ACEN_SHIFT 31
+#define OMAP4_AVDAC_ACEN_MASK (1 << 31)
+#define OMAP4_AVDAC_TVOUTBYPASS_SHIFT 30
+#define OMAP4_AVDAC_TVOUTBYPASS_MASK (1 << 30)
+#define OMAP4_AVDAC_INPUTINV_SHIFT 29
+#define OMAP4_AVDAC_INPUTINV_MASK (1 << 29)
+#define OMAP4_AVDAC_CTL_SHIFT 13
+#define OMAP4_AVDAC_CTL_MASK (0xffff << 13)
+#define OMAP4_AVDAC_CTL_WR_ACK_SHIFT 12
+#define OMAP4_AVDAC_CTL_WR_ACK_MASK (1 << 12)
+
+/* CONTROL_HDMI_TX_PHY */
+#define OMAP4_HDMITXPHY_PADORDER_SHIFT 31
+#define OMAP4_HDMITXPHY_PADORDER_MASK (1 << 31)
+#define OMAP4_HDMITXPHY_TXVALID_SHIFT 30
+#define OMAP4_HDMITXPHY_TXVALID_MASK (1 << 30)
+#define OMAP4_HDMITXPHY_ENBYPASSCLK_SHIFT 29
+#define OMAP4_HDMITXPHY_ENBYPASSCLK_MASK (1 << 29)
+#define OMAP4_HDMITXPHY_PD_PULLUPDET_SHIFT 28
+#define OMAP4_HDMITXPHY_PD_PULLUPDET_MASK (1 << 28)
+
+/* CONTROL_MMC2 */
+#define OMAP4_MMC2_FEEDBACK_CLK_SEL_SHIFT 31
+#define OMAP4_MMC2_FEEDBACK_CLK_SEL_MASK (1 << 31)
+
+/* CONTROL_DSIPHY */
+#define OMAP4_DSI2_LANEENABLE_SHIFT 29
+#define OMAP4_DSI2_LANEENABLE_MASK (0x7 << 29)
+#define OMAP4_DSI1_LANEENABLE_SHIFT 24
+#define OMAP4_DSI1_LANEENABLE_MASK (0x1f << 24)
+#define OMAP4_DSI1_PIPD_SHIFT 19
+#define OMAP4_DSI1_PIPD_MASK (0x1f << 19)
+#define OMAP4_DSI2_PIPD_SHIFT 14
+#define OMAP4_DSI2_PIPD_MASK (0x1f << 14)
+
+/* CONTROL_MCBSPLP */
+#define OMAP4_ALBCTRLRX_FSX_SHIFT 31
+#define OMAP4_ALBCTRLRX_FSX_MASK (1 << 31)
+#define OMAP4_ALBCTRLRX_CLKX_SHIFT 30
+#define OMAP4_ALBCTRLRX_CLKX_MASK (1 << 30)
+#define OMAP4_ABE_MCBSP1_DR_EN_SHIFT 29
+#define OMAP4_ABE_MCBSP1_DR_EN_MASK (1 << 29)
+
+/* CONTROL_USB2PHYCORE */
+#define OMAP4_USB2PHY_AUTORESUME_EN_SHIFT 31
+#define OMAP4_USB2PHY_AUTORESUME_EN_MASK (1 << 31)
+#define OMAP4_USB2PHY_DISCHGDET_SHIFT 30
+#define OMAP4_USB2PHY_DISCHGDET_MASK (1 << 30)
+#define OMAP4_USB2PHY_GPIOMODE_SHIFT 29
+#define OMAP4_USB2PHY_GPIOMODE_MASK (1 << 29)
+#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_SHIFT 28
+#define OMAP4_USB2PHY_CHG_DET_EXT_CTL_MASK (1 << 28)
+#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_SHIFT 27
+#define OMAP4_USB2PHY_RDM_PD_CHGDET_EN_MASK (1 << 27)
+#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_SHIFT 26
+#define OMAP4_USB2PHY_RDP_PU_CHGDET_EN_MASK (1 << 26)
+#define OMAP4_USB2PHY_CHG_VSRC_EN_SHIFT 25
+#define OMAP4_USB2PHY_CHG_VSRC_EN_MASK (1 << 25)
+#define OMAP4_USB2PHY_CHG_ISINK_EN_SHIFT 24
+#define OMAP4_USB2PHY_CHG_ISINK_EN_MASK (1 << 24)
+#define OMAP4_USB2PHY_CHG_DET_STATUS_SHIFT 21
+#define OMAP4_USB2PHY_CHG_DET_STATUS_MASK (0x7 << 21)
+#define OMAP4_USB2PHY_CHG_DET_DM_COMP_SHIFT 20
+#define OMAP4_USB2PHY_CHG_DET_DM_COMP_MASK (1 << 20)
+#define OMAP4_USB2PHY_CHG_DET_DP_COMP_SHIFT 19
+#define OMAP4_USB2PHY_CHG_DET_DP_COMP_MASK (1 << 19)
+#define OMAP4_USB2PHY_DATADET_SHIFT 18
+#define OMAP4_USB2PHY_DATADET_MASK (1 << 18)
+#define OMAP4_USB2PHY_SINKONDP_SHIFT 17
+#define OMAP4_USB2PHY_SINKONDP_MASK (1 << 17)
+#define OMAP4_USB2PHY_SRCONDM_SHIFT 16
+#define OMAP4_USB2PHY_SRCONDM_MASK (1 << 16)
+#define OMAP4_USB2PHY_RESTARTCHGDET_SHIFT 15
+#define OMAP4_USB2PHY_RESTARTCHGDET_MASK (1 << 15)
+#define OMAP4_USB2PHY_CHGDETDONE_SHIFT 14
+#define OMAP4_USB2PHY_CHGDETDONE_MASK (1 << 14)
+#define OMAP4_USB2PHY_CHGDETECTED_SHIFT 13
+#define OMAP4_USB2PHY_CHGDETECTED_MASK (1 << 13)
+#define OMAP4_USB2PHY_MCPCPUEN_SHIFT 12
+#define OMAP4_USB2PHY_MCPCPUEN_MASK (1 << 12)
+#define OMAP4_USB2PHY_MCPCMODEEN_SHIFT 11
+#define OMAP4_USB2PHY_MCPCMODEEN_MASK (1 << 11)
+#define OMAP4_USB2PHY_RESETDONEMCLK_SHIFT 10
+#define OMAP4_USB2PHY_RESETDONEMCLK_MASK (1 << 10)
+#define OMAP4_USB2PHY_UTMIRESETDONE_SHIFT 9
+#define OMAP4_USB2PHY_UTMIRESETDONE_MASK (1 << 9)
+#define OMAP4_USB2PHY_TXBITSTUFFENABLE_SHIFT 8
+#define OMAP4_USB2PHY_TXBITSTUFFENABLE_MASK (1 << 8)
+#define OMAP4_USB2PHY_DATAPOLARITYN_SHIFT 7
+#define OMAP4_USB2PHY_DATAPOLARITYN_MASK (1 << 7)
+#define OMAP4_USBDPLL_FREQLOCK_SHIFT 6
+#define OMAP4_USBDPLL_FREQLOCK_MASK (1 << 6)
+#define OMAP4_USB2PHY_RESETDONETCLK_SHIFT 5
+#define OMAP4_USB2PHY_RESETDONETCLK_MASK (1 << 5)
+
+/* CONTROL_I2C_1 */
+#define OMAP4_HDMI_DDC_SDA_GLFENB_SHIFT 31
+#define OMAP4_HDMI_DDC_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_HDMI_DDC_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_HDMI_DDC_SCL_GLFENB_SHIFT 27
+#define OMAP4_HDMI_DDC_SCL_GLFENB_MASK (1 << 27)
+#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_SHIFT 25
+#define OMAP4_HDMI_DDC_SCL_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_SHIFT 24
+#define OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK (1 << 24)
+#define OMAP4_HDMI_DDC_SDA_HSMODE_SHIFT 23
+#define OMAP4_HDMI_DDC_SDA_HSMODE_MASK (1 << 23)
+#define OMAP4_HDMI_DDC_SDA_NMODE_SHIFT 22
+#define OMAP4_HDMI_DDC_SDA_NMODE_MASK (1 << 22)
+#define OMAP4_HDMI_DDC_SCL_HSMODE_SHIFT 21
+#define OMAP4_HDMI_DDC_SCL_HSMODE_MASK (1 << 21)
+#define OMAP4_HDMI_DDC_SCL_NMODE_SHIFT 20
+#define OMAP4_HDMI_DDC_SCL_NMODE_MASK (1 << 20)
+
+/* CONTROL_MMC1 */
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_SHIFT 31
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP0_MASK (1 << 31)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_SHIFT 30
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP1_MASK (1 << 30)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_SHIFT 29
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP2_MASK (1 << 29)
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_SHIFT 28
+#define OMAP4_SDMMC1_PUSTRENGTH_GRP3_MASK (1 << 28)
+#define OMAP4_SDMMC1_DR0_SPEEDCTRL_SHIFT 27
+#define OMAP4_SDMMC1_DR0_SPEEDCTRL_MASK (1 << 27)
+#define OMAP4_SDMMC1_DR1_SPEEDCTRL_SHIFT 26
+#define OMAP4_SDMMC1_DR1_SPEEDCTRL_MASK (1 << 26)
+#define OMAP4_SDMMC1_DR2_SPEEDCTRL_SHIFT 25
+#define OMAP4_SDMMC1_DR2_SPEEDCTRL_MASK (1 << 25)
+#define OMAP4_USBC1_DR0_SPEEDCTRL_SHIFT 24
+#define OMAP4_USBC1_DR0_SPEEDCTRL_MASK (1 << 24)
+#define OMAP4_USB_FD_CDEN_SHIFT 23
+#define OMAP4_USB_FD_CDEN_MASK (1 << 23)
+#define OMAP4_USBC1_ICUSB_DP_PDDIS_SHIFT 22
+#define OMAP4_USBC1_ICUSB_DP_PDDIS_MASK (1 << 22)
+#define OMAP4_USBC1_ICUSB_DM_PDDIS_SHIFT 21
+#define OMAP4_USBC1_ICUSB_DM_PDDIS_MASK (1 << 21)
+
+/* CONTROL_HSI */
+#define OMAP4_HSI1_CALLOOP_SEL_SHIFT 31
+#define OMAP4_HSI1_CALLOOP_SEL_MASK (1 << 31)
+#define OMAP4_HSI1_CALMUX_SEL_SHIFT 30
+#define OMAP4_HSI1_CALMUX_SEL_MASK (1 << 30)
+#define OMAP4_HSI2_CALLOOP_SEL_SHIFT 29
+#define OMAP4_HSI2_CALLOOP_SEL_MASK (1 << 29)
+#define OMAP4_HSI2_CALMUX_SEL_SHIFT 28
+#define OMAP4_HSI2_CALMUX_SEL_MASK (1 << 28)
+
+/* CONTROL_USB */
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_SHIFT 31
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT0_AUTO_EN_MASK (1 << 31)
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_SHIFT 30
+#define OMAP4_CARKIT_USBA0_ULPIPHY_DAT1_AUTO_EN_MASK (1 << 30)
+
+/* CONTROL_HDQ */
+#define OMAP4_HDQ_SIO_PWRDNZ_SHIFT 31
+#define OMAP4_HDQ_SIO_PWRDNZ_MASK (1 << 31)
+
+/* CONTROL_LPDDR2IO1_0 */
+#define OMAP4_LPDDR2IO1_GR4_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR4_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR4_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR4_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR4_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR4_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR3_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR3_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR3_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR3_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR3_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR3_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR2_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR2_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR2_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR2_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR2_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR2_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO1_GR1_SR_SHIFT 6
+#define OMAP4_LPDDR2IO1_GR1_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO1_GR1_I_SHIFT 3
+#define OMAP4_LPDDR2IO1_GR1_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO1_GR1_WD_SHIFT 1
+#define OMAP4_LPDDR2IO1_GR1_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO1_1 */
+#define OMAP4_LPDDR2IO1_GR8_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR8_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR8_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR8_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR8_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR8_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR7_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR7_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR7_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR7_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR7_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR7_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR6_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR6_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR6_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR6_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR6_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR6_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO1_GR5_SR_SHIFT 6
+#define OMAP4_LPDDR2IO1_GR5_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO1_GR5_I_SHIFT 3
+#define OMAP4_LPDDR2IO1_GR5_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO1_GR5_WD_SHIFT 1
+#define OMAP4_LPDDR2IO1_GR5_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO1_2 */
+#define OMAP4_LPDDR2IO1_GR11_SR_SHIFT 30
+#define OMAP4_LPDDR2IO1_GR11_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO1_GR11_I_SHIFT 27
+#define OMAP4_LPDDR2IO1_GR11_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO1_GR11_WD_SHIFT 25
+#define OMAP4_LPDDR2IO1_GR11_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO1_GR10_SR_SHIFT 22
+#define OMAP4_LPDDR2IO1_GR10_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO1_GR10_I_SHIFT 19
+#define OMAP4_LPDDR2IO1_GR10_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO1_GR10_WD_SHIFT 17
+#define OMAP4_LPDDR2IO1_GR10_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO1_GR9_SR_SHIFT 14
+#define OMAP4_LPDDR2IO1_GR9_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO1_GR9_I_SHIFT 11
+#define OMAP4_LPDDR2IO1_GR9_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO1_GR9_WD_SHIFT 9
+#define OMAP4_LPDDR2IO1_GR9_WD_MASK (0x3 << 9)
+
+/* CONTROL_LPDDR2IO1_3 */
+#define OMAP4_LPDDR21_VREF_CA_CCAP0_SHIFT 31
+#define OMAP4_LPDDR21_VREF_CA_CCAP0_MASK (1 << 31)
+#define OMAP4_LPDDR21_VREF_CA_CCAP1_SHIFT 30
+#define OMAP4_LPDDR21_VREF_CA_CCAP1_MASK (1 << 30)
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_SHIFT 29
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP0_MASK (1 << 29)
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_SHIFT 28
+#define OMAP4_LPDDR21_VREF_CA_INT_CCAP1_MASK (1 << 28)
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_SHIFT 27
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP0_MASK (1 << 27)
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_SHIFT 26
+#define OMAP4_LPDDR21_VREF_CA_INT_TAP1_MASK (1 << 26)
+#define OMAP4_LPDDR21_VREF_CA_TAP0_SHIFT 25
+#define OMAP4_LPDDR21_VREF_CA_TAP0_MASK (1 << 25)
+#define OMAP4_LPDDR21_VREF_CA_TAP1_SHIFT 24
+#define OMAP4_LPDDR21_VREF_CA_TAP1_MASK (1 << 24)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_SHIFT 23
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP0_MASK (1 << 23)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_SHIFT 22
+#define OMAP4_LPDDR21_VREF_DQ0_INT_CCAP1_MASK (1 << 22)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_SHIFT 21
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP0_MASK (1 << 21)
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_SHIFT 20
+#define OMAP4_LPDDR21_VREF_DQ0_INT_TAP1_MASK (1 << 20)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_SHIFT 19
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP0_MASK (1 << 19)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_SHIFT 18
+#define OMAP4_LPDDR21_VREF_DQ1_INT_CCAP1_MASK (1 << 18)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_SHIFT 17
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP0_MASK (1 << 17)
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_SHIFT 16
+#define OMAP4_LPDDR21_VREF_DQ1_INT_TAP1_MASK (1 << 16)
+#define OMAP4_LPDDR21_VREF_DQ_CCAP0_SHIFT 15
+#define OMAP4_LPDDR21_VREF_DQ_CCAP0_MASK (1 << 15)
+#define OMAP4_LPDDR21_VREF_DQ_CCAP1_SHIFT 14
+#define OMAP4_LPDDR21_VREF_DQ_CCAP1_MASK (1 << 14)
+#define OMAP4_LPDDR21_VREF_DQ_TAP0_SHIFT 13
+#define OMAP4_LPDDR21_VREF_DQ_TAP0_MASK (1 << 13)
+#define OMAP4_LPDDR21_VREF_DQ_TAP1_SHIFT 12
+#define OMAP4_LPDDR21_VREF_DQ_TAP1_MASK (1 << 12)
+
+/* CONTROL_LPDDR2IO2_0 */
+#define OMAP4_LPDDR2IO2_GR4_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR4_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR4_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR4_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR4_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR4_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR3_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR3_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR3_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR3_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR3_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR3_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR2_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR2_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR2_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR2_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR2_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR2_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO2_GR1_SR_SHIFT 6
+#define OMAP4_LPDDR2IO2_GR1_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO2_GR1_I_SHIFT 3
+#define OMAP4_LPDDR2IO2_GR1_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO2_GR1_WD_SHIFT 1
+#define OMAP4_LPDDR2IO2_GR1_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO2_1 */
+#define OMAP4_LPDDR2IO2_GR8_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR8_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR8_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR8_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR8_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR8_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR7_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR7_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR7_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR7_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR7_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR7_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR6_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR6_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR6_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR6_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR6_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR6_WD_MASK (0x3 << 9)
+#define OMAP4_LPDDR2IO2_GR5_SR_SHIFT 6
+#define OMAP4_LPDDR2IO2_GR5_SR_MASK (0x3 << 6)
+#define OMAP4_LPDDR2IO2_GR5_I_SHIFT 3
+#define OMAP4_LPDDR2IO2_GR5_I_MASK (0x7 << 3)
+#define OMAP4_LPDDR2IO2_GR5_WD_SHIFT 1
+#define OMAP4_LPDDR2IO2_GR5_WD_MASK (0x3 << 1)
+
+/* CONTROL_LPDDR2IO2_2 */
+#define OMAP4_LPDDR2IO2_GR11_SR_SHIFT 30
+#define OMAP4_LPDDR2IO2_GR11_SR_MASK (0x3 << 30)
+#define OMAP4_LPDDR2IO2_GR11_I_SHIFT 27
+#define OMAP4_LPDDR2IO2_GR11_I_MASK (0x7 << 27)
+#define OMAP4_LPDDR2IO2_GR11_WD_SHIFT 25
+#define OMAP4_LPDDR2IO2_GR11_WD_MASK (0x3 << 25)
+#define OMAP4_LPDDR2IO2_GR10_SR_SHIFT 22
+#define OMAP4_LPDDR2IO2_GR10_SR_MASK (0x3 << 22)
+#define OMAP4_LPDDR2IO2_GR10_I_SHIFT 19
+#define OMAP4_LPDDR2IO2_GR10_I_MASK (0x7 << 19)
+#define OMAP4_LPDDR2IO2_GR10_WD_SHIFT 17
+#define OMAP4_LPDDR2IO2_GR10_WD_MASK (0x3 << 17)
+#define OMAP4_LPDDR2IO2_GR9_SR_SHIFT 14
+#define OMAP4_LPDDR2IO2_GR9_SR_MASK (0x3 << 14)
+#define OMAP4_LPDDR2IO2_GR9_I_SHIFT 11
+#define OMAP4_LPDDR2IO2_GR9_I_MASK (0x7 << 11)
+#define OMAP4_LPDDR2IO2_GR9_WD_SHIFT 9
+#define OMAP4_LPDDR2IO2_GR9_WD_MASK (0x3 << 9)
+
+/* CONTROL_LPDDR2IO2_3 */
+#define OMAP4_LPDDR22_VREF_CA_CCAP0_SHIFT 31
+#define OMAP4_LPDDR22_VREF_CA_CCAP0_MASK (1 << 31)
+#define OMAP4_LPDDR22_VREF_CA_CCAP1_SHIFT 30
+#define OMAP4_LPDDR22_VREF_CA_CCAP1_MASK (1 << 30)
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_SHIFT 29
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP0_MASK (1 << 29)
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_SHIFT 28
+#define OMAP4_LPDDR22_VREF_CA_INT_CCAP1_MASK (1 << 28)
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_SHIFT 27
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP0_MASK (1 << 27)
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_SHIFT 26
+#define OMAP4_LPDDR22_VREF_CA_INT_TAP1_MASK (1 << 26)
+#define OMAP4_LPDDR22_VREF_CA_TAP0_SHIFT 25
+#define OMAP4_LPDDR22_VREF_CA_TAP0_MASK (1 << 25)
+#define OMAP4_LPDDR22_VREF_CA_TAP1_SHIFT 24
+#define OMAP4_LPDDR22_VREF_CA_TAP1_MASK (1 << 24)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_SHIFT 23
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP0_MASK (1 << 23)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_SHIFT 22
+#define OMAP4_LPDDR22_VREF_DQ0_INT_CCAP1_MASK (1 << 22)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_SHIFT 21
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP0_MASK (1 << 21)
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_SHIFT 20
+#define OMAP4_LPDDR22_VREF_DQ0_INT_TAP1_MASK (1 << 20)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_SHIFT 19
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP0_MASK (1 << 19)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_SHIFT 18
+#define OMAP4_LPDDR22_VREF_DQ1_INT_CCAP1_MASK (1 << 18)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_SHIFT 17
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP0_MASK (1 << 17)
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_SHIFT 16
+#define OMAP4_LPDDR22_VREF_DQ1_INT_TAP1_MASK (1 << 16)
+#define OMAP4_LPDDR22_VREF_DQ_CCAP0_SHIFT 15
+#define OMAP4_LPDDR22_VREF_DQ_CCAP0_MASK (1 << 15)
+#define OMAP4_LPDDR22_VREF_DQ_CCAP1_SHIFT 14
+#define OMAP4_LPDDR22_VREF_DQ_CCAP1_MASK (1 << 14)
+#define OMAP4_LPDDR22_VREF_DQ_TAP0_SHIFT 13
+#define OMAP4_LPDDR22_VREF_DQ_TAP0_MASK (1 << 13)
+#define OMAP4_LPDDR22_VREF_DQ_TAP1_SHIFT 12
+#define OMAP4_LPDDR22_VREF_DQ_TAP1_MASK (1 << 12)
+
+/* CONTROL_BUS_HOLD */
+#define OMAP4_ABE_DMIC_DIN3_EN_SHIFT 31
+#define OMAP4_ABE_DMIC_DIN3_EN_MASK (1 << 31)
+#define OMAP4_MCSPI1_CS3_EN_SHIFT 30
+#define OMAP4_MCSPI1_CS3_EN_MASK (1 << 30)
+
+/* CONTROL_C2C */
+#define OMAP4_MIRROR_MODE_EN_SHIFT 31
+#define OMAP4_MIRROR_MODE_EN_MASK (1 << 31)
+#define OMAP4_C2C_SPARE_SHIFT 24
+#define OMAP4_C2C_SPARE_MASK (0x7f << 24)
+
+/* CORE_CONTROL_SPARE_RW */
+#define OMAP4_CORE_CONTROL_SPARE_RW_SHIFT 0
+#define OMAP4_CORE_CONTROL_SPARE_RW_MASK (0xffffffff << 0)
+
+/* CORE_CONTROL_SPARE_R */
+#define OMAP4_CORE_CONTROL_SPARE_R_SHIFT 0
+#define OMAP4_CORE_CONTROL_SPARE_R_MASK (0xffffffff << 0)
+
+/* CORE_CONTROL_SPARE_R_C0 */
+#define OMAP4_CORE_CONTROL_SPARE_R_C0_SHIFT 31
+#define OMAP4_CORE_CONTROL_SPARE_R_C0_MASK (1 << 31)
+#define OMAP4_CORE_CONTROL_SPARE_R_C1_SHIFT 30
+#define OMAP4_CORE_CONTROL_SPARE_R_C1_MASK (1 << 30)
+#define OMAP4_CORE_CONTROL_SPARE_R_C2_SHIFT 29
+#define OMAP4_CORE_CONTROL_SPARE_R_C2_MASK (1 << 29)
+#define OMAP4_CORE_CONTROL_SPARE_R_C3_SHIFT 28
+#define OMAP4_CORE_CONTROL_SPARE_R_C3_MASK (1 << 28)
+#define OMAP4_CORE_CONTROL_SPARE_R_C4_SHIFT 27
+#define OMAP4_CORE_CONTROL_SPARE_R_C4_MASK (1 << 27)
+#define OMAP4_CORE_CONTROL_SPARE_R_C5_SHIFT 26
+#define OMAP4_CORE_CONTROL_SPARE_R_C5_MASK (1 << 26)
+#define OMAP4_CORE_CONTROL_SPARE_R_C6_SHIFT 25
+#define OMAP4_CORE_CONTROL_SPARE_R_C6_MASK (1 << 25)
+#define OMAP4_CORE_CONTROL_SPARE_R_C7_SHIFT 24
+#define OMAP4_CORE_CONTROL_SPARE_R_C7_MASK (1 << 24)
+
+/* CONTROL_EFUSE_1 */
+#define OMAP4_AVDAC_TRIM_BYTE3_SHIFT 24
+#define OMAP4_AVDAC_TRIM_BYTE3_MASK (0x7f << 24)
+#define OMAP4_AVDAC_TRIM_BYTE2_SHIFT 16
+#define OMAP4_AVDAC_TRIM_BYTE2_MASK (0xff << 16)
+#define OMAP4_AVDAC_TRIM_BYTE1_SHIFT 8
+#define OMAP4_AVDAC_TRIM_BYTE1_MASK (0xff << 8)
+#define OMAP4_AVDAC_TRIM_BYTE0_SHIFT 0
+#define OMAP4_AVDAC_TRIM_BYTE0_MASK (0xff << 0)
+
+/* CONTROL_EFUSE_2 */
+#define OMAP4_EFUSE_SMART2TEST_P0_SHIFT 31
+#define OMAP4_EFUSE_SMART2TEST_P0_MASK (1 << 31)
+#define OMAP4_EFUSE_SMART2TEST_P1_SHIFT 30
+#define OMAP4_EFUSE_SMART2TEST_P1_MASK (1 << 30)
+#define OMAP4_EFUSE_SMART2TEST_P2_SHIFT 29
+#define OMAP4_EFUSE_SMART2TEST_P2_MASK (1 << 29)
+#define OMAP4_EFUSE_SMART2TEST_P3_SHIFT 28
+#define OMAP4_EFUSE_SMART2TEST_P3_MASK (1 << 28)
+#define OMAP4_EFUSE_SMART2TEST_N0_SHIFT 27
+#define OMAP4_EFUSE_SMART2TEST_N0_MASK (1 << 27)
+#define OMAP4_EFUSE_SMART2TEST_N1_SHIFT 26
+#define OMAP4_EFUSE_SMART2TEST_N1_MASK (1 << 26)
+#define OMAP4_EFUSE_SMART2TEST_N2_SHIFT 25
+#define OMAP4_EFUSE_SMART2TEST_N2_MASK (1 << 25)
+#define OMAP4_EFUSE_SMART2TEST_N3_SHIFT 24
+#define OMAP4_EFUSE_SMART2TEST_N3_MASK (1 << 24)
+#define OMAP4_LPDDR2_PTV_N1_SHIFT 23
+#define OMAP4_LPDDR2_PTV_N1_MASK (1 << 23)
+#define OMAP4_LPDDR2_PTV_N2_SHIFT 22
+#define OMAP4_LPDDR2_PTV_N2_MASK (1 << 22)
+#define OMAP4_LPDDR2_PTV_N3_SHIFT 21
+#define OMAP4_LPDDR2_PTV_N3_MASK (1 << 21)
+#define OMAP4_LPDDR2_PTV_N4_SHIFT 20
+#define OMAP4_LPDDR2_PTV_N4_MASK (1 << 20)
+#define OMAP4_LPDDR2_PTV_N5_SHIFT 19
+#define OMAP4_LPDDR2_PTV_N5_MASK (1 << 19)
+#define OMAP4_LPDDR2_PTV_P1_SHIFT 18
+#define OMAP4_LPDDR2_PTV_P1_MASK (1 << 18)
+#define OMAP4_LPDDR2_PTV_P2_SHIFT 17
+#define OMAP4_LPDDR2_PTV_P2_MASK (1 << 17)
+#define OMAP4_LPDDR2_PTV_P3_SHIFT 16
+#define OMAP4_LPDDR2_PTV_P3_MASK (1 << 16)
+#define OMAP4_LPDDR2_PTV_P4_SHIFT 15
+#define OMAP4_LPDDR2_PTV_P4_MASK (1 << 15)
+#define OMAP4_LPDDR2_PTV_P5_SHIFT 14
+#define OMAP4_LPDDR2_PTV_P5_MASK (1 << 14)
+
+/* CONTROL_EFUSE_3 */
+#define OMAP4_STD_FUSE_SPARE_1_SHIFT 24
+#define OMAP4_STD_FUSE_SPARE_1_MASK (0xff << 24)
+#define OMAP4_STD_FUSE_SPARE_2_SHIFT 16
+#define OMAP4_STD_FUSE_SPARE_2_MASK (0xff << 16)
+#define OMAP4_STD_FUSE_SPARE_3_SHIFT 8
+#define OMAP4_STD_FUSE_SPARE_3_MASK (0xff << 8)
+#define OMAP4_STD_FUSE_SPARE_4_SHIFT 0
+#define OMAP4_STD_FUSE_SPARE_4_MASK (0xff << 0)
+
+/* CONTROL_EFUSE_4 */
+#define OMAP4_STD_FUSE_SPARE_5_SHIFT 24
+#define OMAP4_STD_FUSE_SPARE_5_MASK (0xff << 24)
+#define OMAP4_STD_FUSE_SPARE_6_SHIFT 16
+#define OMAP4_STD_FUSE_SPARE_6_MASK (0xff << 16)
+#define OMAP4_STD_FUSE_SPARE_7_SHIFT 8
+#define OMAP4_STD_FUSE_SPARE_7_MASK (0xff << 8)
+#define OMAP4_STD_FUSE_SPARE_8_SHIFT 0
+#define OMAP4_STD_FUSE_SPARE_8_MASK (0xff << 0)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h
new file mode 100644
index 00000000..17c9b370
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_pad_wkup_44xx.h
@@ -0,0 +1,236 @@
+/*
+ * OMAP44xx CTRL_MODULE_PAD_WKUP registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_PAD_WKUP_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_PAD_WKUP 0x4a31e000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_PAD_WKUP_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_PAD_WKUP_PADCONF_WAKEUPEVENT_0 0x007c
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_0 0x05a0
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SMART1NOPMIO_PADCONF_1 0x05a4
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_PADCONF_MODE 0x05a8
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_XTAL_OSCILLATOR 0x05ac
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_USIMIO 0x0600
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2 0x0604
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_JTAG 0x0608
+#define OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_SYS 0x060c
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_RW 0x0614
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R 0x0618
+#define OMAP4_CTRL_MODULE_PAD_WKUP_WKUP_CONTROL_SPARE_R_C0 0x061c
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* PADCONF_WAKEUPEVENT_0 */
+#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_SHIFT 24
+#define OMAP4_JTAG_TDO_DUPLICATEWAKEUPEVENT_MASK (1 << 24)
+#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_SHIFT 23
+#define OMAP4_JTAG_TDI_DUPLICATEWAKEUPEVENT_MASK (1 << 23)
+#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_SHIFT 22
+#define OMAP4_JTAG_TMS_TMSC_DUPLICATEWAKEUPEVENT_MASK (1 << 22)
+#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_SHIFT 21
+#define OMAP4_JTAG_RTCK_DUPLICATEWAKEUPEVENT_MASK (1 << 21)
+#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_SHIFT 20
+#define OMAP4_JTAG_TCK_DUPLICATEWAKEUPEVENT_MASK (1 << 20)
+#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_SHIFT 19
+#define OMAP4_JTAG_NTRST_DUPLICATEWAKEUPEVENT_MASK (1 << 19)
+#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_SHIFT 18
+#define OMAP4_SYS_BOOT7_DUPLICATEWAKEUPEVENT_MASK (1 << 18)
+#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_SHIFT 17
+#define OMAP4_SYS_BOOT6_DUPLICATEWAKEUPEVENT_MASK (1 << 17)
+#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_SHIFT 16
+#define OMAP4_SYS_PWRON_RESET_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 16)
+#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_SHIFT 15
+#define OMAP4_SYS_PWR_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 15)
+#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_SHIFT 14
+#define OMAP4_SYS_NRESWARM_DUPLICATEWAKEUPEVENT_MASK (1 << 14)
+#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_SHIFT 13
+#define OMAP4_SYS_32K_DUPLICATEWAKEUPEVENT_MASK (1 << 13)
+#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_SHIFT 12
+#define OMAP4_FREF_CLK4_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 12)
+#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_SHIFT 11
+#define OMAP4_FREF_CLK4_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 11)
+#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_SHIFT 10
+#define OMAP4_FREF_CLK3_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 10)
+#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_SHIFT 9
+#define OMAP4_FREF_CLK3_REQ_DUPLICATEWAKEUPEVENT_MASK (1 << 9)
+#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_SHIFT 8
+#define OMAP4_FREF_CLK0_OUT_DUPLICATEWAKEUPEVENT_MASK (1 << 8)
+#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_SHIFT 7
+#define OMAP4_FREF_CLK_IOREQ_DUPLICATEWAKEUPEVENT_MASK (1 << 7)
+#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_SHIFT 6
+#define OMAP4_SR_SDA_DUPLICATEWAKEUPEVENT_MASK (1 << 6)
+#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_SHIFT 5
+#define OMAP4_SR_SCL_DUPLICATEWAKEUPEVENT_MASK (1 << 5)
+#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_SHIFT 4
+#define OMAP4_SIM_PWRCTRL_DUPLICATEWAKEUPEVENT_MASK (1 << 4)
+#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_SHIFT 3
+#define OMAP4_SIM_CD_DUPLICATEWAKEUPEVENT_MASK (1 << 3)
+#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_SHIFT 2
+#define OMAP4_SIM_RESET_DUPLICATEWAKEUPEVENT_MASK (1 << 2)
+#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_SHIFT 1
+#define OMAP4_SIM_CLK_DUPLICATEWAKEUPEVENT_MASK (1 << 1)
+#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_SHIFT 0
+#define OMAP4_SIM_IO_DUPLICATEWAKEUPEVENT_MASK (1 << 0)
+
+/* CONTROL_SMART1NOPMIO_PADCONF_0 */
+#define OMAP4_FREF_DR0_SC_SHIFT 30
+#define OMAP4_FREF_DR0_SC_MASK (0x3 << 30)
+#define OMAP4_FREF_DR1_SC_SHIFT 28
+#define OMAP4_FREF_DR1_SC_MASK (0x3 << 28)
+#define OMAP4_FREF_DR4_SC_SHIFT 26
+#define OMAP4_FREF_DR4_SC_MASK (0x3 << 26)
+#define OMAP4_FREF_DR5_SC_SHIFT 24
+#define OMAP4_FREF_DR5_SC_MASK (0x3 << 24)
+#define OMAP4_FREF_DR6_SC_SHIFT 22
+#define OMAP4_FREF_DR6_SC_MASK (0x3 << 22)
+#define OMAP4_FREF_DR7_SC_SHIFT 20
+#define OMAP4_FREF_DR7_SC_MASK (0x3 << 20)
+#define OMAP4_GPIO_DR7_SC_SHIFT 18
+#define OMAP4_GPIO_DR7_SC_MASK (0x3 << 18)
+#define OMAP4_DPM_DR0_SC_SHIFT 14
+#define OMAP4_DPM_DR0_SC_MASK (0x3 << 14)
+#define OMAP4_SIM_DR0_SC_SHIFT 12
+#define OMAP4_SIM_DR0_SC_MASK (0x3 << 12)
+
+/* CONTROL_SMART1NOPMIO_PADCONF_1 */
+#define OMAP4_FREF_DR0_LB_SHIFT 30
+#define OMAP4_FREF_DR0_LB_MASK (0x3 << 30)
+#define OMAP4_FREF_DR1_LB_SHIFT 28
+#define OMAP4_FREF_DR1_LB_MASK (0x3 << 28)
+#define OMAP4_FREF_DR4_LB_SHIFT 26
+#define OMAP4_FREF_DR4_LB_MASK (0x3 << 26)
+#define OMAP4_FREF_DR5_LB_SHIFT 24
+#define OMAP4_FREF_DR5_LB_MASK (0x3 << 24)
+#define OMAP4_FREF_DR6_LB_SHIFT 22
+#define OMAP4_FREF_DR6_LB_MASK (0x3 << 22)
+#define OMAP4_FREF_DR7_LB_SHIFT 20
+#define OMAP4_FREF_DR7_LB_MASK (0x3 << 20)
+#define OMAP4_GPIO_DR7_LB_SHIFT 18
+#define OMAP4_GPIO_DR7_LB_MASK (0x3 << 18)
+#define OMAP4_DPM_DR0_LB_SHIFT 14
+#define OMAP4_DPM_DR0_LB_MASK (0x3 << 14)
+#define OMAP4_SIM_DR0_LB_SHIFT 12
+#define OMAP4_SIM_DR0_LB_MASK (0x3 << 12)
+
+/* CONTROL_PADCONF_MODE */
+#define OMAP4_VDDS_DV_FREF_SHIFT 31
+#define OMAP4_VDDS_DV_FREF_MASK (1 << 31)
+#define OMAP4_VDDS_DV_BANK2_SHIFT 30
+#define OMAP4_VDDS_DV_BANK2_MASK (1 << 30)
+
+/* CONTROL_XTAL_OSCILLATOR */
+#define OMAP4_OSCILLATOR_BOOST_SHIFT 31
+#define OMAP4_OSCILLATOR_BOOST_MASK (1 << 31)
+#define OMAP4_OSCILLATOR_OS_OUT_SHIFT 30
+#define OMAP4_OSCILLATOR_OS_OUT_MASK (1 << 30)
+
+/* CONTROL_USIMIO */
+#define OMAP4_PAD_USIM_CLK_LOW_SHIFT 31
+#define OMAP4_PAD_USIM_CLK_LOW_MASK (1 << 31)
+#define OMAP4_PAD_USIM_RST_LOW_SHIFT 29
+#define OMAP4_PAD_USIM_RST_LOW_MASK (1 << 29)
+#define OMAP4_USIM_PWRDNZ_SHIFT 28
+#define OMAP4_USIM_PWRDNZ_MASK (1 << 28)
+
+/* CONTROL_I2C_2 */
+#define OMAP4_SR_SDA_GLFENB_SHIFT 31
+#define OMAP4_SR_SDA_GLFENB_MASK (1 << 31)
+#define OMAP4_SR_SDA_LOAD_BITS_SHIFT 29
+#define OMAP4_SR_SDA_LOAD_BITS_MASK (0x3 << 29)
+#define OMAP4_SR_SDA_PULLUPRESX_SHIFT 28
+#define OMAP4_SR_SDA_PULLUPRESX_MASK (1 << 28)
+#define OMAP4_SR_SCL_GLFENB_SHIFT 27
+#define OMAP4_SR_SCL_GLFENB_MASK (1 << 27)
+#define OMAP4_SR_SCL_LOAD_BITS_SHIFT 25
+#define OMAP4_SR_SCL_LOAD_BITS_MASK (0x3 << 25)
+#define OMAP4_SR_SCL_PULLUPRESX_SHIFT 24
+#define OMAP4_SR_SCL_PULLUPRESX_MASK (1 << 24)
+
+/* CONTROL_JTAG */
+#define OMAP4_JTAG_NTRST_EN_SHIFT 31
+#define OMAP4_JTAG_NTRST_EN_MASK (1 << 31)
+#define OMAP4_JTAG_TCK_EN_SHIFT 30
+#define OMAP4_JTAG_TCK_EN_MASK (1 << 30)
+#define OMAP4_JTAG_RTCK_EN_SHIFT 29
+#define OMAP4_JTAG_RTCK_EN_MASK (1 << 29)
+#define OMAP4_JTAG_TDI_EN_SHIFT 28
+#define OMAP4_JTAG_TDI_EN_MASK (1 << 28)
+#define OMAP4_JTAG_TDO_EN_SHIFT 27
+#define OMAP4_JTAG_TDO_EN_MASK (1 << 27)
+
+/* CONTROL_SYS */
+#define OMAP4_SYS_NRESWARM_PIPU_SHIFT 31
+#define OMAP4_SYS_NRESWARM_PIPU_MASK (1 << 31)
+
+/* WKUP_CONTROL_SPARE_RW */
+#define OMAP4_WKUP_CONTROL_SPARE_RW_SHIFT 0
+#define OMAP4_WKUP_CONTROL_SPARE_RW_MASK (0xffffffff << 0)
+
+/* WKUP_CONTROL_SPARE_R */
+#define OMAP4_WKUP_CONTROL_SPARE_R_SHIFT 0
+#define OMAP4_WKUP_CONTROL_SPARE_R_MASK (0xffffffff << 0)
+
+/* WKUP_CONTROL_SPARE_R_C0 */
+#define OMAP4_WKUP_CONTROL_SPARE_R_C0_SHIFT 31
+#define OMAP4_WKUP_CONTROL_SPARE_R_C0_MASK (1 << 31)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C1_SHIFT 30
+#define OMAP4_WKUP_CONTROL_SPARE_R_C1_MASK (1 << 30)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C2_SHIFT 29
+#define OMAP4_WKUP_CONTROL_SPARE_R_C2_MASK (1 << 29)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C3_SHIFT 28
+#define OMAP4_WKUP_CONTROL_SPARE_R_C3_MASK (1 << 28)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C4_SHIFT 27
+#define OMAP4_WKUP_CONTROL_SPARE_R_C4_MASK (1 << 27)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C5_SHIFT 26
+#define OMAP4_WKUP_CONTROL_SPARE_R_C5_MASK (1 << 26)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C6_SHIFT 25
+#define OMAP4_WKUP_CONTROL_SPARE_R_C6_MASK (1 << 25)
+#define OMAP4_WKUP_CONTROL_SPARE_R_C7_SHIFT 24
+#define OMAP4_WKUP_CONTROL_SPARE_R_C7_MASK (1 << 24)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
new file mode 100644
index 00000000..a0af9bae
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h
@@ -0,0 +1,92 @@
+/*
+ * OMAP44xx CTRL_MODULE_WKUP registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H
+
+
+/* Base address */
+#define OMAP4_CTRL_MODULE_WKUP 0x4a30c000
+
+/* Registers offset */
+#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000
+#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004
+#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_3 0x046c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_4 0x0470
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_5 0x0474
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_6 0x0478
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_7 0x047c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_8 0x0480
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_9 0x0484
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_10 0x0488
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_11 0x048c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_12 0x0490
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_13 0x0494
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_14 0x0498
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_15 0x049c
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_16 0x04a0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_17 0x04a4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_18 0x04a8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_19 0x04ac
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_20 0x04b0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_21 0x04b4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_22 0x04b8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_23 0x04bc
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_24 0x04c0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_25 0x04c4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_26 0x04c8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_27 0x04cc
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_28 0x04d0
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_29 0x04d4
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_30 0x04d8
+#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_31 0x04dc
+
+/* Registers shifts and masks */
+
+/* IP_REVISION */
+#define OMAP4_IP_REV_SCHEME_SHIFT 30
+#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30)
+#define OMAP4_IP_REV_FUNC_SHIFT 16
+#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16)
+#define OMAP4_IP_REV_RTL_SHIFT 11
+#define OMAP4_IP_REV_RTL_MASK (0x1f << 11)
+#define OMAP4_IP_REV_MAJOR_SHIFT 8
+#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8)
+#define OMAP4_IP_REV_CUSTOM_SHIFT 6
+#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6)
+#define OMAP4_IP_REV_MINOR_SHIFT 0
+#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0)
+
+/* IP_HWINFO */
+#define OMAP4_IP_HWINFO_SHIFT 0
+#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0)
+
+/* IP_SYSCONFIG */
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2
+#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2)
+
+/* CONF_DEBUG_SEL_TST_0 */
+#define OMAP4_WKUP_MODE_SHIFT 0
+#define OMAP4_WKUP_MODE_MASK (1 << 0)
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S
new file mode 100644
index 00000000..48adfe9f
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/debug-macro.S
@@ -0,0 +1,159 @@
+/* arch/arm/mach-omap2/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+
+#include <plat/serial.h>
+
+#define UART_OFFSET(addr) ((addr) & 0x00ffffff)
+
+#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
+ .pushsection .data
+omap_uart_phys: .word 0
+omap_uart_virt: .word 0
+omap_uart_lsr: .word 0
+ .popsection
+
+ /*
+ * Note that this code won't work if the bootloader passes
+ * a wrong machine ID number in r1. To debug, just hardcode
+ * the desired UART phys and virt addresses temporarily into
+ * the omap_uart_phys and omap_uart_virt above.
+ */
+ .macro addruart, rp, rv
+
+ /* Use omap_uart_phys/virt if already configured */
+10: mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
+ ldrne \rp, =omap_uart_phys @ MMU enabled
+ add \rv, \rp, #4 @ omap_uart_virt
+ ldr \rp, [\rp, #0]
+ ldr \rv, [\rv, #0]
+ cmp \rp, #0 @ is port configured?
+ cmpne \rv, #0
+ bne 99f @ already configured
+
+ /* Check the debug UART configuration set in uncompress.h */
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
+ ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled
+ ldr \rp, [\rp, #0]
+
+ /* Select the UART to use based on the UART1 scratchpad value */
+ cmp \rp, #0 @ no port configured?
+ beq 21f @ if none, try to use UART1
+ cmp \rp, #OMAP2UART1 @ OMAP2/3/4UART1
+ beq 21f @ configure OMAP2/3/4UART1
+ cmp \rp, #OMAP2UART2 @ OMAP2/3/4UART2
+ beq 22f @ configure OMAP2/3/4UART2
+ cmp \rp, #OMAP2UART3 @ only on 24xx
+ beq 23f @ configure OMAP2UART3
+ cmp \rp, #OMAP3UART3 @ only on 34xx
+ beq 33f @ configure OMAP3UART3
+ cmp \rp, #OMAP4UART3 @ only on 44xx
+ beq 43f @ configure OMAP4UART3
+ cmp \rp, #OMAP3UART4 @ only on 36xx
+ beq 34f @ configure OMAP3UART4
+ cmp \rp, #OMAP4UART4 @ only on 44xx
+ beq 44f @ configure OMAP4UART4
+ cmp \rp, #TI816XUART1 @ ti816x UART offsets different
+ beq 81f @ configure UART1
+ cmp \rp, #TI816XUART2 @ ti816x UART offsets different
+ beq 82f @ configure UART2
+ cmp \rp, #TI816XUART3 @ ti816x UART offsets different
+ beq 83f @ configure UART3
+ cmp \rp, #ZOOM_UART @ only on zoom2/3
+ beq 95f @ configure ZOOM_UART
+
+ /* Configure the UART offset from the phys/virt base */
+21: mov \rp, #UART_OFFSET(OMAP2_UART1_BASE) @ omap2/3/4
+ b 98f
+22: mov \rp, #UART_OFFSET(OMAP2_UART2_BASE) @ omap2/3/4
+ b 98f
+23: mov \rp, #UART_OFFSET(OMAP2_UART3_BASE)
+ b 98f
+33: mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00006000 @ OMAP3_UART3_BASE
+ b 98f
+34: mov \rp, #UART_OFFSET(OMAP3_UART1_BASE)
+ add \rp, \rp, #0x00fb0000
+ add \rp, \rp, #0x00028000 @ OMAP3_UART4_BASE
+ b 98f
+43: mov \rp, #UART_OFFSET(OMAP4_UART3_BASE)
+ b 98f
+44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE)
+ b 98f
+81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE)
+ b 98f
+82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE)
+ b 98f
+83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE)
+ b 98f
+95: ldr \rp, =ZOOM_UART_BASE
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ ldr \rp, =ZOOM_UART_VIRT
+ add \rv, \rv, #4 @ omap_uart_virt
+ str \rp, [\rv, #0]
+ mov \rp, #(UART_LSR << ZOOM_PORT_SHIFT)
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
+ b 10b
+
+ /* Store both phys and virt address for the uart */
+98: add \rp, \rp, #0x48000000 @ phys base
+ mrc p15, 0, \rv, c1, c0
+ tst \rv, #1 @ MMU enabled?
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
+ ldrne \rv, =omap_uart_phys @ MMU enabled
+ str \rp, [\rv, #0]
+ sub \rp, \rp, #0x48000000 @ phys base
+ add \rp, \rp, #0xfa000000 @ virt base
+ add \rv, \rv, #4 @ omap_uart_virt
+ str \rp, [\rv, #0]
+ mov \rp, #(UART_LSR << OMAP_PORT_SHIFT)
+ add \rv, \rv, #4 @ omap_uart_lsr
+ str \rp, [\rv, #0]
+
+ b 10b
+99:
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro busyuart,rd,rx
+1001: mrc p15, 0, \rd, c1, c0
+ tst \rd, #1 @ MMU enabled?
+ ldreq \rd, =omap_uart_v2p(omap_uart_lsr) @ MMU disabled
+ ldrne \rd, =omap_uart_lsr @ MMU enabled
+ ldr \rd, [\rd, #0]
+ ldrb \rd, [\rx, \rd]
+ and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
+ bne 1001b
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S
new file mode 100644
index 00000000..a48690b9
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/entry-macro.S
@@ -0,0 +1,170 @@
+/*
+ * arch/arm/plat-omap/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for OMAP-based platforms
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/io.h>
+#include <mach/irqs.h>
+#include <asm/hardware/gic.h>
+
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+#include <plat/omap44xx.h>
+
+#include <plat/multi.h>
+
+#define OMAP2_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE)
+#define OMAP3_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE)
+#define OMAP4_IRQ_BASE OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)
+#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* omap2/3 active interrupt offset */
+#define ACTIVEIRQ_MASK 0x7f /* omap2/3 active interrupt bits */
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+/*
+ * Unoptimized irq functions for multi-omap2, 3 and 4
+ */
+
+#ifdef MULTI_OMAP2
+ /*
+ * Configure the interrupt base on the first interrupt.
+ * See also omap_irq_base_init for setting omap_irq_base.
+ */
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =omap_irq_base @ irq base address
+ ldr \base, [\base, #0] @ irq base value
+ .endm
+
+ /* Check the pending interrupts. Note that base already set */
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ tst \base, #0x100 @ gic address?
+ bne 4401f @ found gic
+
+ /* Handle omap2 and omap3 */
+ ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */
+ cmp \irqnr, #0x0
+ bne 9998f
+ ldr \irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
+ cmp \irqnr, #0x0
+ bne 9998f
+ ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
+ cmp \irqnr, #0x0
+ bne 9998f
+
+ /*
+ * ti816x has additional IRQ pending register. Checking this
+ * register on omap2 & omap3 has no effect (read as 0).
+ */
+ ldr \irqnr, [\base, #0xf8] /* IRQ pending reg 4 */
+ cmp \irqnr, #0x0
+9998:
+ ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+ and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
+ b 9999f
+
+ /* Handle omap4 */
+4401: ldr \irqstat, [\base, #GIC_CPU_INTACK]
+ ldr \tmp, =1021
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+9999:
+ .endm
+
+#ifdef CONFIG_SMP
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt
+ * on the controller, since this requires the original irqstat
+ * value which we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ it cc
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ it cs
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ itt eq
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+#endif /* CONFIG_SMP */
+
+#else /* MULTI_OMAP2 */
+
+
+/*
+ * Optimized irq functions for omap2, 3 and 4
+ */
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ .macro get_irqnr_preamble, base, tmp
+#ifdef CONFIG_ARCH_OMAP2
+ ldr \base, =OMAP2_IRQ_BASE
+#else
+ ldr \base, =OMAP3_IRQ_BASE
+#endif
+ .endm
+
+ /* Check the pending interrupts. Note that base already set */
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */
+ cmp \irqnr, #0x0
+ bne 9999f
+ ldr \irqnr, [\base, #0xb8] /* IRQ pending reg 2 */
+ cmp \irqnr, #0x0
+ bne 9999f
+ ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
+ cmp \irqnr, #0x0
+#ifdef CONFIG_SOC_OMAPTI816X
+ bne 9999f
+ ldr \irqnr, [\base, #0xf8] /* IRQ pending reg 4 */
+ cmp \irqnr, #0x0
+#endif
+9999:
+ ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
+ and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */
+
+ .endm
+#endif
+
+
+#ifdef CONFIG_ARCH_OMAP4
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =OMAP4_IRQ_BASE
+ .endm
+
+#endif
+
+#endif /* MULTI_OMAP2 */
+
+ .macro irq_prio_table
+ .endm
diff --git a/arch/arm/mach-omap2/include/mach/gpio.h b/arch/arm/mach-omap2/include/mach/gpio.h
new file mode 100644
index 00000000..be4d290d
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/gpio.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/gpio.h
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-omap2/include/mach/hardware.h b/arch/arm/mach-omap2/include/mach/hardware.h
new file mode 100644
index 00000000..78edf9d3
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/hardware.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/hardware.h
+ */
+
+#include <plat/hardware.h>
diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h
new file mode 100644
index 00000000..02ed3aa5
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/id.h
@@ -0,0 +1,22 @@
+/*
+ * OMAP2 CPU identification code
+ *
+ * Copyright (C) 2010 Kan-Ru Chen <kanru@0xlab.org>
+ *
+ * This program is free software; you can 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 OMAP2_ARCH_ID_H
+#define OMAP2_ARCH_ID_H
+
+struct omap_die_id {
+ u32 id_0;
+ u32 id_1;
+ u32 id_2;
+ u32 id_3;
+};
+
+void omap_get_die_id(struct omap_die_id *odi);
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/io.h b/arch/arm/mach-omap2/include/mach/io.h
new file mode 100644
index 00000000..fd78f31a
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/io.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/io.h
+ */
+
+#include <plat/io.h>
diff --git a/arch/arm/mach-omap2/include/mach/irqs.h b/arch/arm/mach-omap2/include/mach/irqs.h
new file mode 100644
index 00000000..44dab772
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/irqs.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/irqs.h
+ */
+
+#include <plat/irqs.h>
diff --git a/arch/arm/mach-omap2/include/mach/memory.h b/arch/arm/mach-omap2/include/mach/memory.h
new file mode 100644
index 00000000..ca6d32a9
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/memory.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/memory.h
+ */
+
+#include <plat/memory.h>
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
new file mode 100644
index 00000000..e4bd8761
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -0,0 +1,43 @@
+/*
+ * omap4-common.h: OMAP4 specific common header file
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef OMAP_ARCH_OMAP4_COMMON_H
+#define OMAP_ARCH_OMAP4_COMMON_H
+
+/*
+ * wfi used in low power code. Directly opcode is used instead
+ * of instruction to avoid mulit-omap build break
+ */
+#ifdef CONFIG_THUMB2_KERNEL
+#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#else
+#define do_wfi() \
+ __asm__ __volatile__ (".word 0xe320f003" : : : "memory")
+#endif
+
+#ifdef CONFIG_CACHE_L2X0
+extern void __iomem *l2cache_base;
+#endif
+
+extern void __iomem *gic_dist_base_addr;
+
+extern void __init gic_init_irq(void);
+extern void omap_smc1(u32 fn, u32 arg);
+
+#ifdef CONFIG_SMP
+/* Needed for secondary core boot */
+extern void omap_secondary_startup(void);
+extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
+extern void omap_auxcoreboot_addr(u32 cpu_addr);
+extern u32 omap_read_auxcoreboot0(void);
+#endif
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/smp.h b/arch/arm/mach-omap2/include/mach/smp.h
new file mode 100644
index 00000000..323675f2
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/smp.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/smp.h
+ */
+
+#include <plat/smp.h>
diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h
new file mode 100644
index 00000000..d488721a
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/system.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/system.h
+ */
+
+#include <plat/system.h>
diff --git a/arch/arm/mach-omap2/include/mach/timex.h b/arch/arm/mach-omap2/include/mach/timex.h
new file mode 100644
index 00000000..de9f8fc4
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/timex.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/timex.h
+ */
+
+#include <plat/timex.h>
diff --git a/arch/arm/mach-omap2/include/mach/uncompress.h b/arch/arm/mach-omap2/include/mach/uncompress.h
new file mode 100644
index 00000000..78e0557b
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/uncompress.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-omap2/include/mach/uncompress.h
+ */
+
+#include <plat/uncompress.h>
diff --git a/arch/arm/mach-omap2/include/mach/vmalloc.h b/arch/arm/mach-omap2/include/mach/vmalloc.h
new file mode 100644
index 00000000..86631994
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-omap/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xf8000000UL
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
new file mode 100644
index 00000000..441e79d0
--- /dev/null
+++ b/arch/arm/mach-omap2/io.c
@@ -0,0 +1,466 @@
+/*
+ * linux/arch/arm/mach-omap2/io.c
+ *
+ * OMAP2 I/O mapping code
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2007-2009 Texas Instruments
+ *
+ * Author:
+ * Juha Yrjola <juha.yrjola@nokia.com>
+ * Syed Khasim <x0khasim@ti.com>
+ *
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/omapfb.h>
+
+#include <asm/tlb.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/sram.h>
+#include <plat/sdrc.h>
+#include <plat/serial.h>
+
+#include "clock2xxx.h"
+#include "clock3xxx.h"
+#include "clock44xx.h"
+#include "io.h"
+
+#include <plat/omap-pm.h>
+#include "powerdomain.h"
+
+#include "clockdomain.h"
+#include <plat/omap_hwmod.h>
+#include <plat/multi.h>
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct map_desc omap24xx_io_desc[] __initdata = {
+ {
+ .virtual = L3_24XX_VIRT,
+ .pfn = __phys_to_pfn(L3_24XX_PHYS),
+ .length = L3_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_24XX_VIRT,
+ .pfn = __phys_to_pfn(L4_24XX_PHYS),
+ .length = L4_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+#ifdef CONFIG_SOC_OMAP2420
+static struct map_desc omap242x_io_desc[] __initdata = {
+ {
+ .virtual = DSP_MEM_2420_VIRT,
+ .pfn = __phys_to_pfn(DSP_MEM_2420_PHYS),
+ .length = DSP_MEM_2420_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DSP_IPI_2420_VIRT,
+ .pfn = __phys_to_pfn(DSP_IPI_2420_PHYS),
+ .length = DSP_IPI_2420_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DSP_MMU_2420_VIRT,
+ .pfn = __phys_to_pfn(DSP_MMU_2420_PHYS),
+ .length = DSP_MMU_2420_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+static struct map_desc omap243x_io_desc[] __initdata = {
+ {
+ .virtual = L4_WK_243X_VIRT,
+ .pfn = __phys_to_pfn(L4_WK_243X_PHYS),
+ .length = L4_WK_243X_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP243X_GPMC_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_GPMC_PHYS),
+ .length = OMAP243X_GPMC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP243X_SDRC_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS),
+ .length = OMAP243X_SDRC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP243X_SMS_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS),
+ .length = OMAP243X_SMS_SIZE,
+ .type = MT_DEVICE
+ },
+};
+#endif
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct map_desc omap34xx_io_desc[] __initdata = {
+ {
+ .virtual = L3_34XX_VIRT,
+ .pfn = __phys_to_pfn(L3_34XX_PHYS),
+ .length = L3_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_34XX_PHYS),
+ .length = L4_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP34XX_GPMC_VIRT,
+ .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS),
+ .length = OMAP34XX_GPMC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP343X_SMS_VIRT,
+ .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS),
+ .length = OMAP343X_SMS_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP343X_SDRC_VIRT,
+ .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS),
+ .length = OMAP343X_SDRC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_PER_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_PER_34XX_PHYS),
+ .length = L4_PER_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_EMU_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS),
+ .length = L4_EMU_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+#if defined(CONFIG_DEBUG_LL) && \
+ (defined(CONFIG_MACH_OMAP_ZOOM2) || defined(CONFIG_MACH_OMAP_ZOOM3))
+ {
+ .virtual = ZOOM_UART_VIRT,
+ .pfn = __phys_to_pfn(ZOOM_UART_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ },
+#endif
+};
+#endif
+
+#ifdef CONFIG_SOC_OMAPTI816X
+static struct map_desc omapti816x_io_desc[] __initdata = {
+ {
+ .virtual = L4_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_34XX_PHYS),
+ .length = L4_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static struct map_desc omap44xx_io_desc[] __initdata = {
+ {
+ .virtual = L3_44XX_VIRT,
+ .pfn = __phys_to_pfn(L3_44XX_PHYS),
+ .length = L3_44XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_44XX_VIRT,
+ .pfn = __phys_to_pfn(L4_44XX_PHYS),
+ .length = L4_44XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = OMAP44XX_GPMC_VIRT,
+ .pfn = __phys_to_pfn(OMAP44XX_GPMC_PHYS),
+ .length = OMAP44XX_GPMC_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = OMAP44XX_EMIF1_VIRT,
+ .pfn = __phys_to_pfn(OMAP44XX_EMIF1_PHYS),
+ .length = OMAP44XX_EMIF1_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = OMAP44XX_EMIF2_VIRT,
+ .pfn = __phys_to_pfn(OMAP44XX_EMIF2_PHYS),
+ .length = OMAP44XX_EMIF2_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = OMAP44XX_DMM_VIRT,
+ .pfn = __phys_to_pfn(OMAP44XX_DMM_PHYS),
+ .length = OMAP44XX_DMM_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_PER_44XX_VIRT,
+ .pfn = __phys_to_pfn(L4_PER_44XX_PHYS),
+ .length = L4_PER_44XX_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = L4_EMU_44XX_VIRT,
+ .pfn = __phys_to_pfn(L4_EMU_44XX_PHYS),
+ .length = L4_EMU_44XX_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+#endif
+
+static void __init _omap2_map_common_io(void)
+{
+ /* Normally devicemaps_init() would flush caches and tlb after
+ * mdesc->map_io(), but we must also do it here because of the CPU
+ * revision check below.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ omap2_check_revision();
+ omap_sram_init();
+}
+
+#ifdef CONFIG_SOC_OMAP2420
+void __init omap242x_map_common_io(void)
+{
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
+ _omap2_map_common_io();
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+void __init omap243x_map_common_io(void)
+{
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
+ _omap2_map_common_io();
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+void __init omap34xx_map_common_io(void)
+{
+ iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
+ _omap2_map_common_io();
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAPTI816X
+void __init omapti816x_map_common_io(void)
+{
+ iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc));
+ _omap2_map_common_io();
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+void __init omap44xx_map_common_io(void)
+{
+ iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
+ _omap2_map_common_io();
+}
+#endif
+
+/*
+ * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters
+ *
+ * Sets the CORE DPLL3 M2 divider to the same value that it's at
+ * currently. This has the effect of setting the SDRC SDRAM AC timing
+ * registers to the values currently defined by the kernel. Currently
+ * only defined for OMAP3; will return 0 if called on OMAP2. Returns
+ * -EINVAL if the dpll3_m2_ck cannot be found, 0 if called on OMAP2,
+ * or passes along the return value of clk_set_rate().
+ */
+static int __init _omap2_init_reprogram_sdrc(void)
+{
+ struct clk *dpll3_m2_ck;
+ int v = -EINVAL;
+ long rate;
+
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck");
+ if (IS_ERR(dpll3_m2_ck))
+ return -EINVAL;
+
+ rate = clk_get_rate(dpll3_m2_ck);
+ pr_info("Reprogramming SDRC clock to %ld Hz\n", rate);
+ v = clk_set_rate(dpll3_m2_ck, rate);
+ if (v)
+ pr_err("dpll3_m2_clk rate change failed: %d\n", v);
+
+ clk_put(dpll3_m2_ck);
+
+ return v;
+}
+
+static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
+{
+ return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
+}
+
+void __iomem *omap_irq_base;
+
+/*
+ * Initialize asm_irq_base for entry-macro.S
+ */
+static inline void omap_irq_base_init(void)
+{
+ if (cpu_is_omap24xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE);
+ else if (cpu_is_omap34xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE);
+ else if (cpu_is_omap44xx())
+ omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE);
+ else
+ pr_err("Could not initialize omap_irq_base\n");
+}
+
+void __init omap2_init_common_infrastructure(void)
+{
+ u8 postsetup_state;
+
+ if (cpu_is_omap242x()) {
+ omap2xxx_powerdomains_init();
+ omap2xxx_clockdomains_init();
+ omap2420_hwmod_init();
+ } else if (cpu_is_omap243x()) {
+ omap2xxx_powerdomains_init();
+ omap2xxx_clockdomains_init();
+ omap2430_hwmod_init();
+ } else if (cpu_is_omap34xx()) {
+ omap3xxx_powerdomains_init();
+ omap3xxx_clockdomains_init();
+ omap3xxx_hwmod_init();
+ } else if (cpu_is_omap44xx()) {
+ omap44xx_powerdomains_init();
+ omap44xx_clockdomains_init();
+ omap44xx_hwmod_init();
+ } else {
+ pr_err("Could not init hwmod data - unknown SoC\n");
+ }
+
+ /* Set the default postsetup state for all hwmods */
+#ifdef CONFIG_PM_RUNTIME
+ postsetup_state = _HWMOD_STATE_IDLE;
+#else
+ postsetup_state = _HWMOD_STATE_ENABLED;
+#endif
+ omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
+
+ /*
+ * Set the default postsetup state for unusual modules (like
+ * MPU WDT).
+ *
+ * The postsetup_state is not actually used until
+ * omap_hwmod_late_init(), so boards that desire full watchdog
+ * coverage of kernel initialization can reprogram the
+ * postsetup_state between the calls to
+ * omap2_init_common_infra() and omap2_init_common_devices().
+ *
+ * XXX ideally we could detect whether the MPU WDT was currently
+ * enabled here and make this conditional
+ */
+ postsetup_state = _HWMOD_STATE_DISABLED;
+ omap_hwmod_for_each_by_class("wd_timer",
+ _set_hwmod_postsetup_state,
+ &postsetup_state);
+
+ omap_pm_if_early_init();
+
+ if (cpu_is_omap2420())
+ omap2420_clk_init();
+ else if (cpu_is_omap2430())
+ omap2430_clk_init();
+ else if (cpu_is_omap34xx())
+ omap3xxx_clk_init();
+ else if (cpu_is_omap44xx())
+ omap4xxx_clk_init();
+ else
+ pr_err("Could not init clock framework - unknown SoC\n");
+}
+
+void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1)
+{
+ if (cpu_is_omap24xx() || omap3_has_sdrc()) {
+ omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
+ _omap2_init_reprogram_sdrc();
+ }
+
+ omap_irq_base_init();
+}
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+u8 omap_readb(u32 pa)
+{
+ return __raw_readb(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readb);
+
+u16 omap_readw(u32 pa)
+{
+ return __raw_readw(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readw);
+
+u32 omap_readl(u32 pa)
+{
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_readl);
+
+void omap_writeb(u8 v, u32 pa)
+{
+ __raw_writeb(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writeb);
+
+void omap_writew(u16 v, u32 pa)
+{
+ __raw_writew(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writew);
+
+void omap_writel(u32 v, u32 pa)
+{
+ __raw_writel(v, OMAP2_L4_IO_ADDRESS(pa));
+}
+EXPORT_SYMBOL(omap_writel);
diff --git a/arch/arm/mach-omap2/io.h b/arch/arm/mach-omap2/io.h
new file mode 100644
index 00000000..fd230c6c
--- /dev/null
+++ b/arch/arm/mach-omap2/io.h
@@ -0,0 +1,7 @@
+
+#ifndef __MACH_OMAP2_IO_H__
+#define __MACH_OMAP2_IO_H__
+
+extern int __init omap_sram_init(void);
+
+#endif /* __MACH_OMAP2_IO_H__ */
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
new file mode 100644
index 00000000..adb083e4
--- /dev/null
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -0,0 +1,358 @@
+/*
+ * omap iommu: omap2/3 architecture specific functions
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
+ * Paul Mundt and Toshihiro Kobayashi
+ *
+ * This program is free software; you can 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/device.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/stringify.h>
+
+#include <plat/iommu.h>
+
+/*
+ * omap2 architecture specific register bit definitions
+ */
+#define IOMMU_ARCH_VERSION 0x00000011
+
+/* SYSCONF */
+#define MMU_SYS_IDLE_SHIFT 3
+#define MMU_SYS_IDLE_FORCE (0 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_NONE (1 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_SMART (2 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_MASK (3 << MMU_SYS_IDLE_SHIFT)
+
+#define MMU_SYS_SOFTRESET (1 << 1)
+#define MMU_SYS_AUTOIDLE 1
+
+/* SYSSTATUS */
+#define MMU_SYS_RESETDONE 1
+
+/* IRQSTATUS & IRQENABLE */
+#define MMU_IRQ_MULTIHITFAULT (1 << 4)
+#define MMU_IRQ_TABLEWALKFAULT (1 << 3)
+#define MMU_IRQ_EMUMISS (1 << 2)
+#define MMU_IRQ_TRANSLATIONFAULT (1 << 1)
+#define MMU_IRQ_TLBMISS (1 << 0)
+
+#define __MMU_IRQ_FAULT \
+ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT)
+#define MMU_IRQ_MASK \
+ (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS)
+#define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT)
+#define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS)
+
+/* MMU_CNTL */
+#define MMU_CNTL_SHIFT 1
+#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT)
+#define MMU_CNTL_EML_TLB (1 << 3)
+#define MMU_CNTL_TWL_EN (1 << 2)
+#define MMU_CNTL_MMU_EN (1 << 1)
+
+#define get_cam_va_mask(pgsz) \
+ (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \
+ ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \
+ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
+ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
+
+
+static void __iommu_set_twl(struct iommu *obj, bool on)
+{
+ u32 l = iommu_read_reg(obj, MMU_CNTL);
+
+ if (on)
+ iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE);
+ else
+ iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE);
+
+ l &= ~MMU_CNTL_MASK;
+ if (on)
+ l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
+ else
+ l |= (MMU_CNTL_MMU_EN);
+
+ iommu_write_reg(obj, l, MMU_CNTL);
+}
+
+
+static int omap2_iommu_enable(struct iommu *obj)
+{
+ u32 l, pa;
+ unsigned long timeout;
+
+ if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K))
+ return -EINVAL;
+
+ pa = virt_to_phys(obj->iopgd);
+ if (!IS_ALIGNED(pa, SZ_16K))
+ return -EINVAL;
+
+ iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
+
+ timeout = jiffies + msecs_to_jiffies(20);
+ do {
+ l = iommu_read_reg(obj, MMU_SYSSTATUS);
+ if (l & MMU_SYS_RESETDONE)
+ break;
+ } while (!time_after(jiffies, timeout));
+
+ if (!(l & MMU_SYS_RESETDONE)) {
+ dev_err(obj->dev, "can't take mmu out of reset\n");
+ return -ENODEV;
+ }
+
+ l = iommu_read_reg(obj, MMU_REVISION);
+ dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
+ (l >> 4) & 0xf, l & 0xf);
+
+ l = iommu_read_reg(obj, MMU_SYSCONFIG);
+ l &= ~MMU_SYS_IDLE_MASK;
+ l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
+ iommu_write_reg(obj, l, MMU_SYSCONFIG);
+
+ iommu_write_reg(obj, pa, MMU_TTB);
+
+ __iommu_set_twl(obj, true);
+
+ return 0;
+}
+
+static void omap2_iommu_disable(struct iommu *obj)
+{
+ u32 l = iommu_read_reg(obj, MMU_CNTL);
+
+ l &= ~MMU_CNTL_MASK;
+ iommu_write_reg(obj, l, MMU_CNTL);
+ iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
+
+ dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
+}
+
+static void omap2_iommu_set_twl(struct iommu *obj, bool on)
+{
+ __iommu_set_twl(obj, false);
+}
+
+static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
+{
+ u32 stat, da;
+ u32 errs = 0;
+
+ stat = iommu_read_reg(obj, MMU_IRQSTATUS);
+ stat &= MMU_IRQ_MASK;
+ if (!stat) {
+ *ra = 0;
+ return 0;
+ }
+
+ da = iommu_read_reg(obj, MMU_FAULT_AD);
+ *ra = da;
+
+ if (stat & MMU_IRQ_TLBMISS)
+ errs |= OMAP_IOMMU_ERR_TLB_MISS;
+ if (stat & MMU_IRQ_TRANSLATIONFAULT)
+ errs |= OMAP_IOMMU_ERR_TRANS_FAULT;
+ if (stat & MMU_IRQ_EMUMISS)
+ errs |= OMAP_IOMMU_ERR_EMU_MISS;
+ if (stat & MMU_IRQ_TABLEWALKFAULT)
+ errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT;
+ if (stat & MMU_IRQ_MULTIHITFAULT)
+ errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT;
+ iommu_write_reg(obj, stat, MMU_IRQSTATUS);
+
+ return errs;
+}
+
+static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ cr->cam = iommu_read_reg(obj, MMU_READ_CAM);
+ cr->ram = iommu_read_reg(obj, MMU_READ_RAM);
+}
+
+static void omap2_tlb_load_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM);
+ iommu_write_reg(obj, cr->ram, MMU_RAM);
+}
+
+static u32 omap2_cr_to_virt(struct cr_regs *cr)
+{
+ u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK;
+ u32 mask = get_cam_va_mask(cr->cam & page_size);
+
+ return cr->cam & mask;
+}
+
+static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e)
+{
+ struct cr_regs *cr;
+
+ if (e->da & ~(get_cam_va_mask(e->pgsz))) {
+ dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__,
+ e->da);
+ return ERR_PTR(-EINVAL);
+ }
+
+ cr = kmalloc(sizeof(*cr), GFP_KERNEL);
+ if (!cr)
+ return ERR_PTR(-ENOMEM);
+
+ cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz | e->valid;
+ cr->ram = e->pa | e->endian | e->elsz | e->mixed;
+
+ return cr;
+}
+
+static inline int omap2_cr_valid(struct cr_regs *cr)
+{
+ return cr->cam & MMU_CAM_V;
+}
+
+static u32 omap2_get_pte_attr(struct iotlb_entry *e)
+{
+ u32 attr;
+
+ attr = e->mixed << 5;
+ attr |= e->endian;
+ attr |= e->elsz >> 3;
+ attr <<= ((e->pgsz & MMU_CAM_PGSZ_4K) ? 0 : 6);
+
+ return attr;
+}
+
+static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
+{
+ char *p = buf;
+
+ /* FIXME: Need more detail analysis of cam/ram */
+ p += sprintf(p, "%08x %08x %01x\n", cr->cam, cr->ram,
+ (cr->cam & MMU_CAM_P) ? 1 : 0);
+
+ return p - buf;
+}
+
+#define pr_reg(name) \
+ do { \
+ ssize_t bytes; \
+ const char *str = "%20s: %08x\n"; \
+ const int maxcol = 32; \
+ bytes = snprintf(p, maxcol, str, __stringify(name), \
+ iommu_read_reg(obj, MMU_##name)); \
+ p += bytes; \
+ len -= bytes; \
+ if (len < maxcol) \
+ goto out; \
+ } while (0)
+
+static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len)
+{
+ char *p = buf;
+
+ pr_reg(REVISION);
+ pr_reg(SYSCONFIG);
+ pr_reg(SYSSTATUS);
+ pr_reg(IRQSTATUS);
+ pr_reg(IRQENABLE);
+ pr_reg(WALKING_ST);
+ pr_reg(CNTL);
+ pr_reg(FAULT_AD);
+ pr_reg(TTB);
+ pr_reg(LOCK);
+ pr_reg(LD_TLB);
+ pr_reg(CAM);
+ pr_reg(RAM);
+ pr_reg(GFLUSH);
+ pr_reg(FLUSH_ENTRY);
+ pr_reg(READ_CAM);
+ pr_reg(READ_RAM);
+ pr_reg(EMU_FAULT_AD);
+out:
+ return p - buf;
+}
+
+static void omap2_iommu_save_ctx(struct iommu *obj)
+{
+ int i;
+ u32 *p = obj->ctx;
+
+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
+ p[i] = iommu_read_reg(obj, i * sizeof(u32));
+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
+ }
+
+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+}
+
+static void omap2_iommu_restore_ctx(struct iommu *obj)
+{
+ int i;
+ u32 *p = obj->ctx;
+
+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
+ iommu_write_reg(obj, p[i], i * sizeof(u32));
+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
+ }
+
+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+}
+
+static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
+{
+ e->da = cr->cam & MMU_CAM_VATAG_MASK;
+ e->pa = cr->ram & MMU_RAM_PADDR_MASK;
+ e->valid = cr->cam & MMU_CAM_V;
+ e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK;
+ e->endian = cr->ram & MMU_RAM_ENDIAN_MASK;
+ e->elsz = cr->ram & MMU_RAM_ELSZ_MASK;
+ e->mixed = cr->ram & MMU_RAM_MIXED;
+}
+
+static const struct iommu_functions omap2_iommu_ops = {
+ .version = IOMMU_ARCH_VERSION,
+
+ .enable = omap2_iommu_enable,
+ .disable = omap2_iommu_disable,
+ .set_twl = omap2_iommu_set_twl,
+ .fault_isr = omap2_iommu_fault_isr,
+
+ .tlb_read_cr = omap2_tlb_read_cr,
+ .tlb_load_cr = omap2_tlb_load_cr,
+
+ .cr_to_e = omap2_cr_to_e,
+ .cr_to_virt = omap2_cr_to_virt,
+ .alloc_cr = omap2_alloc_cr,
+ .cr_valid = omap2_cr_valid,
+ .dump_cr = omap2_dump_cr,
+
+ .get_pte_attr = omap2_get_pte_attr,
+
+ .save_ctx = omap2_iommu_save_ctx,
+ .restore_ctx = omap2_iommu_restore_ctx,
+ .dump_ctx = omap2_iommu_dump_ctx,
+};
+
+static int __init omap2_iommu_init(void)
+{
+ return install_iommu_arch(&omap2_iommu_ops);
+}
+module_init(omap2_iommu_init);
+
+static void __exit omap2_iommu_exit(void)
+{
+ uninstall_iommu_arch(&omap2_iommu_ops);
+}
+module_exit(omap2_iommu_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
+MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
new file mode 100644
index 00000000..3af2b7a1
--- /dev/null
+++ b/arch/arm/mach-omap2/irq.c
@@ -0,0 +1,256 @@
+/*
+ * linux/arch/arm/mach-omap2/irq.c
+ *
+ * Interrupt handler for OMAP2 boards.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+
+
+/* selected INTC register offsets */
+
+#define INTC_REVISION 0x0000
+#define INTC_SYSCONFIG 0x0010
+#define INTC_SYSSTATUS 0x0014
+#define INTC_SIR 0x0040
+#define INTC_CONTROL 0x0048
+#define INTC_PROTECTION 0x004C
+#define INTC_IDLE 0x0050
+#define INTC_THRESHOLD 0x0068
+#define INTC_MIR0 0x0084
+#define INTC_MIR_CLEAR0 0x0088
+#define INTC_MIR_SET0 0x008c
+#define INTC_PENDING_IRQ0 0x0098
+/* Number of IRQ state bits in each MIR register */
+#define IRQ_BITS_PER_REG 32
+
+/*
+ * OMAP2 has a number of different interrupt controllers, each interrupt
+ * controller is identified as its own "bank". Register definitions are
+ * fairly consistent for each bank, but not all registers are implemented
+ * for each bank.. when in doubt, consult the TRM.
+ */
+static struct omap_irq_bank {
+ void __iomem *base_reg;
+ unsigned int nr_irqs;
+} __attribute__ ((aligned(4))) irq_banks[] = {
+ {
+ /* MPU INTC */
+ .nr_irqs = 96,
+ },
+};
+
+/* Structure to save interrupt controller context */
+struct omap3_intc_regs {
+ u32 sysconfig;
+ u32 protection;
+ u32 idle;
+ u32 threshold;
+ u32 ilr[INTCPS_NR_IRQS];
+ u32 mir[INTCPS_NR_MIR_REGS];
+};
+
+/* INTC bank register get/set */
+
+static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
+{
+ __raw_writel(val, bank->base_reg + reg);
+}
+
+static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg)
+{
+ return __raw_readl(bank->base_reg + reg);
+}
+
+/* XXX: FIQ and additional INTC support (only MPU at the moment) */
+static void omap_ack_irq(struct irq_data *d)
+{
+ intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
+}
+
+static void omap_mask_ack_irq(struct irq_data *d)
+{
+ irq_gc_mask_disable_reg(d);
+ omap_ack_irq(d);
+}
+
+static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
+{
+ unsigned long tmp;
+
+ tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff;
+ printk(KERN_INFO "IRQ: Found an INTC at 0x%p "
+ "(revision %ld.%ld) with %d interrupts\n",
+ bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
+
+ tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG);
+ tmp |= 1 << 1; /* soft reset */
+ intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG);
+
+ while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1))
+ /* Wait for reset to complete */;
+
+ /* Enable autoidle */
+ intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
+}
+
+int omap_irq_pending(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
+ struct omap_irq_bank *bank = irq_banks + i;
+ int irq;
+
+ for (irq = 0; irq < bank->nr_irqs; irq += 32)
+ if (intc_bank_read_reg(bank, INTC_PENDING_IRQ0 +
+ ((irq >> 5) << 5)))
+ return 1;
+ }
+ return 0;
+}
+
+static __init void
+omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
+ handle_level_irq);
+ ct = gc->chip_types;
+ ct->chip.irq_ack = omap_mask_ack_irq;
+ ct->chip.irq_mask = irq_gc_mask_disable_reg;
+ ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+
+ ct->regs.ack = INTC_CONTROL;
+ ct->regs.enable = INTC_MIR_CLEAR0;
+ ct->regs.disable = INTC_MIR_SET0;
+ irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
+void __init omap_init_irq(void)
+{
+ unsigned long nr_of_irqs = 0;
+ unsigned int nr_banks = 0;
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
+ unsigned long base = 0;
+ struct omap_irq_bank *bank = irq_banks + i;
+
+ if (cpu_is_omap24xx())
+ base = OMAP24XX_IC_BASE;
+ else if (cpu_is_omap34xx())
+ base = OMAP34XX_IC_BASE;
+
+ BUG_ON(!base);
+
+ if (cpu_is_ti816x())
+ bank->nr_irqs = 128;
+
+ /* Static mapping, never released */
+ bank->base_reg = ioremap(base, SZ_4K);
+ if (!bank->base_reg) {
+ printk(KERN_ERR "Could not ioremap irq bank%i\n", i);
+ continue;
+ }
+
+ omap_irq_bank_init_one(bank);
+
+ for (i = 0, j = 0; i < bank->nr_irqs; i += 32, j += 0x20)
+ omap_alloc_gc(bank->base_reg + j, i, 32);
+
+ nr_of_irqs += bank->nr_irqs;
+ nr_banks++;
+ }
+
+ printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
+ nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+}
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)];
+
+void omap_intc_save_context(void)
+{
+ int ind = 0, i = 0;
+ for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
+ struct omap_irq_bank *bank = irq_banks + ind;
+ intc_context[ind].sysconfig =
+ intc_bank_read_reg(bank, INTC_SYSCONFIG);
+ intc_context[ind].protection =
+ intc_bank_read_reg(bank, INTC_PROTECTION);
+ intc_context[ind].idle =
+ intc_bank_read_reg(bank, INTC_IDLE);
+ intc_context[ind].threshold =
+ intc_bank_read_reg(bank, INTC_THRESHOLD);
+ for (i = 0; i < INTCPS_NR_IRQS; i++)
+ intc_context[ind].ilr[i] =
+ intc_bank_read_reg(bank, (0x100 + 0x4*i));
+ for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
+ intc_context[ind].mir[i] =
+ intc_bank_read_reg(&irq_banks[0], INTC_MIR0 +
+ (0x20 * i));
+ }
+}
+
+void omap_intc_restore_context(void)
+{
+ int ind = 0, i = 0;
+
+ for (ind = 0; ind < ARRAY_SIZE(irq_banks); ind++) {
+ struct omap_irq_bank *bank = irq_banks + ind;
+ intc_bank_write_reg(intc_context[ind].sysconfig,
+ bank, INTC_SYSCONFIG);
+ intc_bank_write_reg(intc_context[ind].sysconfig,
+ bank, INTC_SYSCONFIG);
+ intc_bank_write_reg(intc_context[ind].protection,
+ bank, INTC_PROTECTION);
+ intc_bank_write_reg(intc_context[ind].idle,
+ bank, INTC_IDLE);
+ intc_bank_write_reg(intc_context[ind].threshold,
+ bank, INTC_THRESHOLD);
+ for (i = 0; i < INTCPS_NR_IRQS; i++)
+ intc_bank_write_reg(intc_context[ind].ilr[i],
+ bank, (0x100 + 0x4*i));
+ for (i = 0; i < INTCPS_NR_MIR_REGS; i++)
+ intc_bank_write_reg(intc_context[ind].mir[i],
+ &irq_banks[0], INTC_MIR0 + (0x20 * i));
+ }
+ /* MIRs are saved and restore with other PRCM registers */
+}
+
+void omap3_intc_suspend(void)
+{
+ /* A pending interrupt would prevent OMAP from entering suspend */
+ omap_ack_irq(0);
+}
+
+void omap3_intc_prepare_idle(void)
+{
+ /*
+ * Disable autoidle as it can stall interrupt controller,
+ * cf. errata ID i540 for 3430 (all revisions up to 3.1.x)
+ */
+ intc_bank_write_reg(0, &irq_banks[0], INTC_SYSCONFIG);
+}
+
+void omap3_intc_resume_idle(void)
+{
+ /* Re-enable autoidle */
+ intc_bank_write_reg(1, &irq_banks[0], INTC_SYSCONFIG);
+}
+#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
new file mode 100644
index 00000000..86d564a6
--- /dev/null
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -0,0 +1,421 @@
+/*
+ * Mailbox reservation modules for OMAP2/3
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation
+ * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ * and Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <plat/mailbox.h>
+#include <mach/irqs.h>
+
+#define MAILBOX_REVISION 0x000
+#define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
+#define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
+#define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m))
+#define MAILBOX_IRQSTATUS(u) (0x100 + 8 * (u))
+#define MAILBOX_IRQENABLE(u) (0x104 + 8 * (u))
+
+#define OMAP4_MAILBOX_IRQSTATUS(u) (0x104 + 10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE(u) (0x108 + 10 * (u))
+#define OMAP4_MAILBOX_IRQENABLE_CLR(u) (0x10c + 10 * (u))
+
+#define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m)))
+#define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1))
+
+#define MBOX_REG_SIZE 0x120
+
+#define OMAP4_MBOX_REG_SIZE 0x130
+
+#define MBOX_NR_REGS (MBOX_REG_SIZE / sizeof(u32))
+#define OMAP4_MBOX_NR_REGS (OMAP4_MBOX_REG_SIZE / sizeof(u32))
+
+static void __iomem *mbox_base;
+
+struct omap_mbox2_fifo {
+ unsigned long msg;
+ unsigned long fifo_stat;
+ unsigned long msg_stat;
+};
+
+struct omap_mbox2_priv {
+ struct omap_mbox2_fifo tx_fifo;
+ struct omap_mbox2_fifo rx_fifo;
+ unsigned long irqenable;
+ unsigned long irqstatus;
+ u32 newmsg_bit;
+ u32 notfull_bit;
+ u32 ctx[OMAP4_MBOX_NR_REGS];
+ unsigned long irqdisable;
+};
+
+static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
+ omap_mbox_type_t irq);
+
+static inline unsigned int mbox_read_reg(size_t ofs)
+{
+ return __raw_readl(mbox_base + ofs);
+}
+
+static inline void mbox_write_reg(u32 val, size_t ofs)
+{
+ __raw_writel(val, mbox_base + ofs);
+}
+
+/* Mailbox H/W preparations */
+static int omap2_mbox_startup(struct omap_mbox *mbox)
+{
+ u32 l;
+
+ pm_runtime_enable(mbox->dev->parent);
+ pm_runtime_get_sync(mbox->dev->parent);
+
+ l = mbox_read_reg(MAILBOX_REVISION);
+ pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f));
+
+ omap2_mbox_enable_irq(mbox, IRQ_RX);
+
+ return 0;
+}
+
+static void omap2_mbox_shutdown(struct omap_mbox *mbox)
+{
+ pm_runtime_put_sync(mbox->dev->parent);
+ pm_runtime_disable(mbox->dev->parent);
+}
+
+/* Mailbox FIFO handle functions */
+static mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
+{
+ struct omap_mbox2_fifo *fifo =
+ &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+ return (mbox_msg_t) mbox_read_reg(fifo->msg);
+}
+
+static void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ struct omap_mbox2_fifo *fifo =
+ &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+ mbox_write_reg(msg, fifo->msg);
+}
+
+static int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
+{
+ struct omap_mbox2_fifo *fifo =
+ &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+ return (mbox_read_reg(fifo->msg_stat) == 0);
+}
+
+static int omap2_mbox_fifo_full(struct omap_mbox *mbox)
+{
+ struct omap_mbox2_fifo *fifo =
+ &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+ return mbox_read_reg(fifo->fifo_stat);
+}
+
+/* Mailbox IRQ handle functions */
+static void omap2_mbox_enable_irq(struct omap_mbox *mbox,
+ omap_mbox_type_t irq)
+{
+ struct omap_mbox2_priv *p = mbox->priv;
+ u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+ l = mbox_read_reg(p->irqenable);
+ l |= bit;
+ mbox_write_reg(l, p->irqenable);
+}
+
+static void omap2_mbox_disable_irq(struct omap_mbox *mbox,
+ omap_mbox_type_t irq)
+{
+ struct omap_mbox2_priv *p = mbox->priv;
+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+ if (!cpu_is_omap44xx())
+ bit = mbox_read_reg(p->irqdisable) & ~bit;
+
+ mbox_write_reg(bit, p->irqdisable);
+}
+
+static void omap2_mbox_ack_irq(struct omap_mbox *mbox,
+ omap_mbox_type_t irq)
+{
+ struct omap_mbox2_priv *p = mbox->priv;
+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+ mbox_write_reg(bit, p->irqstatus);
+
+ /* Flush posted write for irq status to avoid spurious interrupts */
+ mbox_read_reg(p->irqstatus);
+}
+
+static int omap2_mbox_is_irq(struct omap_mbox *mbox,
+ omap_mbox_type_t irq)
+{
+ struct omap_mbox2_priv *p = mbox->priv;
+ u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+ u32 enable = mbox_read_reg(p->irqenable);
+ u32 status = mbox_read_reg(p->irqstatus);
+
+ return (int)(enable & status & bit);
+}
+
+static void omap2_mbox_save_ctx(struct omap_mbox *mbox)
+{
+ int i;
+ struct omap_mbox2_priv *p = mbox->priv;
+ int nr_regs;
+ if (cpu_is_omap44xx())
+ nr_regs = OMAP4_MBOX_NR_REGS;
+ else
+ nr_regs = MBOX_NR_REGS;
+ for (i = 0; i < nr_regs; i++) {
+ p->ctx[i] = mbox_read_reg(i * sizeof(u32));
+
+ dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+ i, p->ctx[i]);
+ }
+}
+
+static void omap2_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+ int i;
+ struct omap_mbox2_priv *p = mbox->priv;
+ int nr_regs;
+ if (cpu_is_omap44xx())
+ nr_regs = OMAP4_MBOX_NR_REGS;
+ else
+ nr_regs = MBOX_NR_REGS;
+ for (i = 0; i < nr_regs; i++) {
+ mbox_write_reg(p->ctx[i], i * sizeof(u32));
+
+ dev_dbg(mbox->dev, "%s: [%02x] %08x\n", __func__,
+ i, p->ctx[i]);
+ }
+}
+
+static struct omap_mbox_ops omap2_mbox_ops = {
+ .type = OMAP_MBOX_TYPE2,
+ .startup = omap2_mbox_startup,
+ .shutdown = omap2_mbox_shutdown,
+ .fifo_read = omap2_mbox_fifo_read,
+ .fifo_write = omap2_mbox_fifo_write,
+ .fifo_empty = omap2_mbox_fifo_empty,
+ .fifo_full = omap2_mbox_fifo_full,
+ .enable_irq = omap2_mbox_enable_irq,
+ .disable_irq = omap2_mbox_disable_irq,
+ .ack_irq = omap2_mbox_ack_irq,
+ .is_irq = omap2_mbox_is_irq,
+ .save_ctx = omap2_mbox_save_ctx,
+ .restore_ctx = omap2_mbox_restore_ctx,
+};
+
+/*
+ * MAILBOX 0: ARM -> DSP,
+ * MAILBOX 1: ARM <- DSP.
+ * MAILBOX 2: ARM -> IVA,
+ * MAILBOX 3: ARM <- IVA.
+ */
+
+/* FIXME: the following structs should be filled automatically by the user id */
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP2)
+/* DSP */
+static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
+ .tx_fifo = {
+ .msg = MAILBOX_MESSAGE(0),
+ .fifo_stat = MAILBOX_FIFOSTATUS(0),
+ },
+ .rx_fifo = {
+ .msg = MAILBOX_MESSAGE(1),
+ .msg_stat = MAILBOX_MSGSTATUS(1),
+ },
+ .irqenable = MAILBOX_IRQENABLE(0),
+ .irqstatus = MAILBOX_IRQSTATUS(0),
+ .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
+ .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
+ .irqdisable = MAILBOX_IRQENABLE(0),
+};
+
+struct omap_mbox mbox_dsp_info = {
+ .name = "dsp",
+ .ops = &omap2_mbox_ops,
+ .priv = &omap2_mbox_dsp_priv,
+};
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL };
+#endif
+
+#if defined(CONFIG_SOC_OMAP2420)
+/* IVA */
+static struct omap_mbox2_priv omap2_mbox_iva_priv = {
+ .tx_fifo = {
+ .msg = MAILBOX_MESSAGE(2),
+ .fifo_stat = MAILBOX_FIFOSTATUS(2),
+ },
+ .rx_fifo = {
+ .msg = MAILBOX_MESSAGE(3),
+ .msg_stat = MAILBOX_MSGSTATUS(3),
+ },
+ .irqenable = MAILBOX_IRQENABLE(3),
+ .irqstatus = MAILBOX_IRQSTATUS(3),
+ .notfull_bit = MAILBOX_IRQ_NOTFULL(2),
+ .newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
+ .irqdisable = MAILBOX_IRQENABLE(3),
+};
+
+static struct omap_mbox mbox_iva_info = {
+ .name = "iva",
+ .ops = &omap2_mbox_ops,
+ .priv = &omap2_mbox_iva_priv,
+};
+
+struct omap_mbox *omap2_mboxes[] = { &mbox_dsp_info, &mbox_iva_info, NULL };
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4)
+/* OMAP4 */
+static struct omap_mbox2_priv omap2_mbox_1_priv = {
+ .tx_fifo = {
+ .msg = MAILBOX_MESSAGE(0),
+ .fifo_stat = MAILBOX_FIFOSTATUS(0),
+ },
+ .rx_fifo = {
+ .msg = MAILBOX_MESSAGE(1),
+ .msg_stat = MAILBOX_MSGSTATUS(1),
+ },
+ .irqenable = OMAP4_MAILBOX_IRQENABLE(0),
+ .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
+ .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
+ .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
+ .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
+};
+
+struct omap_mbox mbox_1_info = {
+ .name = "mailbox-1",
+ .ops = &omap2_mbox_ops,
+ .priv = &omap2_mbox_1_priv,
+};
+
+static struct omap_mbox2_priv omap2_mbox_2_priv = {
+ .tx_fifo = {
+ .msg = MAILBOX_MESSAGE(3),
+ .fifo_stat = MAILBOX_FIFOSTATUS(3),
+ },
+ .rx_fifo = {
+ .msg = MAILBOX_MESSAGE(2),
+ .msg_stat = MAILBOX_MSGSTATUS(2),
+ },
+ .irqenable = OMAP4_MAILBOX_IRQENABLE(0),
+ .irqstatus = OMAP4_MAILBOX_IRQSTATUS(0),
+ .notfull_bit = MAILBOX_IRQ_NOTFULL(3),
+ .newmsg_bit = MAILBOX_IRQ_NEWMSG(2),
+ .irqdisable = OMAP4_MAILBOX_IRQENABLE_CLR(0),
+};
+
+struct omap_mbox mbox_2_info = {
+ .name = "mailbox-2",
+ .ops = &omap2_mbox_ops,
+ .priv = &omap2_mbox_2_priv,
+};
+
+struct omap_mbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
+#endif
+
+static int __devinit omap2_mbox_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ int ret;
+ struct omap_mbox **list;
+
+ if (false)
+ ;
+#if defined(CONFIG_ARCH_OMAP3)
+ else if (cpu_is_omap34xx()) {
+ list = omap3_mboxes;
+
+ list[0]->irq = platform_get_irq(pdev, 0);
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP2)
+ else if (cpu_is_omap2430()) {
+ list = omap2_mboxes;
+
+ list[0]->irq = platform_get_irq(pdev, 0);
+ } else if (cpu_is_omap2420()) {
+ list = omap2_mboxes;
+
+ list[0]->irq = platform_get_irq_byname(pdev, "dsp");
+ list[1]->irq = platform_get_irq_byname(pdev, "iva");
+ }
+#endif
+#if defined(CONFIG_ARCH_OMAP4)
+ else if (cpu_is_omap44xx()) {
+ list = omap4_mboxes;
+
+ list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
+ }
+#endif
+ else {
+ pr_err("%s: platform not supported\n", __func__);
+ return -ENODEV;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mbox_base = ioremap(mem->start, resource_size(mem));
+ if (!mbox_base)
+ return -ENOMEM;
+
+ ret = omap_mbox_register(&pdev->dev, list);
+ if (ret) {
+ iounmap(mbox_base);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devexit omap2_mbox_remove(struct platform_device *pdev)
+{
+ omap_mbox_unregister();
+ iounmap(mbox_base);
+ return 0;
+}
+
+static struct platform_driver omap2_mbox_driver = {
+ .probe = omap2_mbox_probe,
+ .remove = __devexit_p(omap2_mbox_remove),
+ .driver = {
+ .name = "omap-mailbox",
+ },
+};
+
+static int __init omap2_mbox_init(void)
+{
+ return platform_driver_register(&omap2_mbox_driver);
+}
+
+static void __exit omap2_mbox_exit(void)
+{
+ platform_driver_unregister(&omap2_mbox_driver);
+}
+
+module_init(omap2_mbox_init);
+module_exit(omap2_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: omap2/3/4 architecture specific functions");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_AUTHOR("Paul Mundt");
+MODULE_ALIAS("platform:omap2-mailbox");
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
new file mode 100644
index 00000000..4a6ef6ab
--- /dev/null
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -0,0 +1,171 @@
+/*
+ * linux/arch/arm/mach-omap2/mcbsp.c
+ *
+ * Copyright (C) 2008 Instituto Nokia de Tecnologia
+ * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Multichannel mode not supported.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <mach/irqs.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
+#include <plat/mcbsp.h>
+#include <plat/omap_device.h>
+#include <linux/pm_runtime.h>
+
+#include "control.h"
+
+/* McBSP internal signal muxing functions */
+
+void omap2_mcbsp1_mux_clkr_src(u8 mux)
+{
+ u32 v;
+
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ if (mux == CLKR_SRC_CLKR)
+ v &= ~OMAP2_MCBSP1_CLKR_MASK;
+ else if (mux == CLKR_SRC_CLKX)
+ v |= OMAP2_MCBSP1_CLKR_MASK;
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+}
+EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
+
+void omap2_mcbsp1_mux_fsr_src(u8 mux)
+{
+ u32 v;
+
+ v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ if (mux == FSR_SRC_FSR)
+ v &= ~OMAP2_MCBSP1_FSR_MASK;
+ else if (mux == FSR_SRC_FSX)
+ v |= OMAP2_MCBSP1_FSR_MASK;
+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+}
+EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
+
+/* McBSP CLKS source switching function */
+
+int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
+{
+ struct omap_mcbsp *mcbsp;
+ struct clk *fck_src;
+ char *fck_src_name;
+ int r;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
+ return -EINVAL;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (fck_src_id == MCBSP_CLKS_PAD_SRC)
+ fck_src_name = "pad_fck";
+ else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
+ fck_src_name = "prcm_fck";
+ else
+ return -EINVAL;
+
+ fck_src = clk_get(mcbsp->dev, fck_src_name);
+ if (IS_ERR_OR_NULL(fck_src)) {
+ pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
+ fck_src_name);
+ return -EINVAL;
+ }
+
+ pm_runtime_put_sync(mcbsp->dev);
+
+ r = clk_set_parent(mcbsp->fclk, fck_src);
+ if (IS_ERR_VALUE(r)) {
+ pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
+ "clks", fck_src_name);
+ clk_put(fck_src);
+ return -EINVAL;
+ }
+
+ pm_runtime_get_sync(mcbsp->dev);
+
+ clk_put(fck_src);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
+
+struct omap_device_pm_latency omap2_mcbsp_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
+{
+ int id, count = 1;
+ char *name = "omap-mcbsp";
+ struct omap_hwmod *oh_device[2];
+ struct omap_mcbsp_platform_data *pdata = NULL;
+ struct omap_device *od;
+
+ sscanf(oh->name, "mcbsp%d", &id);
+
+ pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: No memory for mcbsp\n", __func__);
+ return -ENOMEM;
+ }
+
+ pdata->mcbsp_config_type = oh->class->rev;
+
+ if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
+ if (id == 2)
+ /* The FIFO has 1024 + 256 locations */
+ pdata->buffer_size = 0x500;
+ else
+ /* The FIFO has 128 locations */
+ pdata->buffer_size = 0x80;
+ }
+
+ oh_device[0] = oh;
+
+ if (oh->dev_attr) {
+ oh_device[1] = omap_hwmod_lookup((
+ (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
+ count++;
+ }
+ od = omap_device_build_ss(name, id, oh_device, count, pdata,
+ sizeof(*pdata), omap2_mcbsp_latency,
+ ARRAY_SIZE(omap2_mcbsp_latency), false);
+ kfree(pdata);
+ if (IS_ERR(od)) {
+ pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
+ name, oh->name);
+ return PTR_ERR(od);
+ }
+ omap_mcbsp_count++;
+ return 0;
+}
+
+static int __init omap2_mcbsp_init(void)
+{
+ omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
+
+ mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+ GFP_KERNEL);
+ if (!mcbsp_ptr)
+ return -ENOMEM;
+
+ return omap_mcbsp_init();
+}
+arch_initcall(omap2_mcbsp_init);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
new file mode 100644
index 00000000..c7fb22ab
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.c
@@ -0,0 +1,1080 @@
+/*
+ * linux/arch/arm/mach-omap2/mux.c
+ *
+ * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
+ *
+ * Copyright (C) 2004 - 2010 Texas Instruments Inc.
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+
+#include <asm/system.h>
+
+#include <plat/omap_hwmod.h>
+
+#include "control.h"
+#include "mux.h"
+
+#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
+#define OMAP_MUX_BASE_SZ 0x5ca
+
+struct omap_mux_entry {
+ struct omap_mux mux;
+ struct list_head node;
+};
+
+static LIST_HEAD(mux_partitions);
+static DEFINE_MUTEX(muxmode_mutex);
+
+struct omap_mux_partition *omap_mux_get(const char *name)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ if (!strcmp(name, partition->name))
+ return partition;
+ }
+
+ return NULL;
+}
+
+u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
+{
+ if (partition->flags & OMAP_MUX_REG_8BIT)
+ return __raw_readb(partition->base + reg);
+ else
+ return __raw_readw(partition->base + reg);
+}
+
+void omap_mux_write(struct omap_mux_partition *partition, u16 val,
+ u16 reg)
+{
+ if (partition->flags & OMAP_MUX_REG_8BIT)
+ __raw_writeb(val, partition->base + reg);
+ else
+ __raw_writew(val, partition->base + reg);
+}
+
+void omap_mux_write_array(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
+{
+ if (!board_mux)
+ return;
+
+ while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
+ omap_mux_write(partition, board_mux->value,
+ board_mux->reg_offset);
+ board_mux++;
+ }
+}
+
+#ifdef CONFIG_OMAP_MUX
+
+static char *omap_mux_options;
+
+static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
+ int gpio, int val)
+{
+ struct omap_mux_entry *e;
+ struct omap_mux *gpio_mux = NULL;
+ u16 old_mode;
+ u16 mux_mode;
+ int found = 0;
+ struct list_head *muxmodes = &partition->muxmodes;
+
+ if (!gpio)
+ return -EINVAL;
+
+ list_for_each_entry(e, muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+ if (gpio == m->gpio) {
+ gpio_mux = m;
+ found++;
+ }
+ }
+
+ if (found == 0) {
+ pr_err("%s: Could not set gpio%i\n", __func__, gpio);
+ return -ENODEV;
+ }
+
+ if (found > 1) {
+ pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
+ found, gpio);
+ return -EINVAL;
+ }
+
+ old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
+ mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
+ if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
+ mux_mode |= OMAP_MUX_MODE3;
+ else
+ mux_mode |= OMAP_MUX_MODE4;
+ pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
+ gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
+ omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
+
+ return 0;
+}
+
+int __init omap_mux_init_gpio(int gpio, int val)
+{
+ struct omap_mux_partition *partition;
+ int ret;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ ret = _omap_mux_init_gpio(partition, gpio, val);
+ if (!ret)
+ return ret;
+ }
+
+ return -ENODEV;
+}
+
+static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
+ const char *muxname,
+ struct omap_mux **found_mux)
+{
+ struct omap_mux *mux = NULL;
+ struct omap_mux_entry *e;
+ const char *mode_name;
+ int found = 0, found_mode = 0, mode0_len = 0;
+ struct list_head *muxmodes = &partition->muxmodes;
+
+ mode_name = strchr(muxname, '.');
+ if (mode_name) {
+ mode0_len = strlen(muxname) - strlen(mode_name);
+ mode_name++;
+ } else {
+ mode_name = muxname;
+ }
+
+ list_for_each_entry(e, muxmodes, node) {
+ char *m0_entry;
+ int i;
+
+ mux = &e->mux;
+ m0_entry = mux->muxnames[0];
+
+ /* First check for full name in mode0.muxmode format */
+ if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
+ continue;
+
+ /* Then check for muxmode only */
+ for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
+ char *mode_cur = mux->muxnames[i];
+
+ if (!mode_cur)
+ continue;
+
+ if (!strcmp(mode_name, mode_cur)) {
+ *found_mux = mux;
+ found++;
+ found_mode = i;
+ }
+ }
+ }
+
+ if (found == 1) {
+ return found_mode;
+ }
+
+ if (found > 1) {
+ pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
+ found, muxname);
+ return -EINVAL;
+ }
+
+ pr_err("%s: Could not find signal %s\n", __func__, muxname);
+
+ return -ENODEV;
+}
+
+static int __init
+omap_mux_get_by_name(const char *muxname,
+ struct omap_mux_partition **found_partition,
+ struct omap_mux **found_mux)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct omap_mux *mux = NULL;
+ int mux_mode = _omap_mux_get_by_name(partition, muxname, &mux);
+ if (mux_mode < 0)
+ continue;
+
+ *found_partition = partition;
+ *found_mux = mux;
+
+ return mux_mode;
+ }
+
+ return -ENODEV;
+}
+
+int __init omap_mux_init_signal(const char *muxname, int val)
+{
+ struct omap_mux_partition *partition = NULL;
+ struct omap_mux *mux = NULL;
+ u16 old_mode;
+ int mux_mode;
+
+ mux_mode = omap_mux_get_by_name(muxname, &partition, &mux);
+ if (mux_mode < 0)
+ return mux_mode;
+
+ old_mode = omap_mux_read(partition, mux->reg_offset);
+ mux_mode |= val;
+ pr_debug("%s: Setting signal %s 0x%04x -> 0x%04x\n",
+ __func__, muxname, old_mode, mux_mode);
+ omap_mux_write(partition, mux_mode, mux->reg_offset);
+
+ return 0;
+}
+
+struct omap_hwmod_mux_info * __init
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+ struct omap_hwmod_mux_info *hmux;
+ int i, nr_pads_dynamic = 0;
+
+ if (!bpads || nr_pads < 1)
+ return NULL;
+
+ hmux = kzalloc(sizeof(struct omap_hwmod_mux_info), GFP_KERNEL);
+ if (!hmux)
+ goto err1;
+
+ hmux->nr_pads = nr_pads;
+
+ hmux->pads = kzalloc(sizeof(struct omap_device_pad) *
+ nr_pads, GFP_KERNEL);
+ if (!hmux->pads)
+ goto err2;
+
+ for (i = 0; i < hmux->nr_pads; i++) {
+ struct omap_mux_partition *partition;
+ struct omap_device_pad *bpad = &bpads[i], *pad = &hmux->pads[i];
+ struct omap_mux *mux;
+ int mux_mode;
+
+ mux_mode = omap_mux_get_by_name(bpad->name, &partition, &mux);
+ if (mux_mode < 0)
+ goto err3;
+ if (!pad->partition)
+ pad->partition = partition;
+ if (!pad->mux)
+ pad->mux = mux;
+
+ pad->name = kzalloc(strlen(bpad->name) + 1, GFP_KERNEL);
+ if (!pad->name) {
+ int j;
+
+ for (j = i - 1; j >= 0; j--)
+ kfree(hmux->pads[j].name);
+ goto err3;
+ }
+ strcpy(pad->name, bpad->name);
+
+ pad->flags = bpad->flags;
+ pad->enable = bpad->enable;
+ pad->idle = bpad->idle;
+ pad->off = bpad->off;
+
+ if (pad->flags & OMAP_DEVICE_PAD_REMUX)
+ nr_pads_dynamic++;
+
+ pr_debug("%s: Initialized %s\n", __func__, pad->name);
+ }
+
+ if (!nr_pads_dynamic)
+ return hmux;
+
+ /*
+ * Add pads that need dynamic muxing into a separate list
+ */
+
+ hmux->nr_pads_dynamic = nr_pads_dynamic;
+ hmux->pads_dynamic = kzalloc(sizeof(struct omap_device_pad *) *
+ nr_pads_dynamic, GFP_KERNEL);
+ if (!hmux->pads_dynamic) {
+ pr_err("%s: Could not allocate dynamic pads\n", __func__);
+ return hmux;
+ }
+
+ nr_pads_dynamic = 0;
+ for (i = 0; i < hmux->nr_pads; i++) {
+ struct omap_device_pad *pad = &hmux->pads[i];
+
+ if (pad->flags & OMAP_DEVICE_PAD_REMUX) {
+ pr_debug("%s: pad %s tagged dynamic\n",
+ __func__, pad->name);
+ hmux->pads_dynamic[nr_pads_dynamic] = pad;
+ nr_pads_dynamic++;
+ }
+ }
+
+ return hmux;
+
+err3:
+ kfree(hmux->pads);
+err2:
+ kfree(hmux);
+err1:
+ pr_err("%s: Could not allocate device mux entry\n", __func__);
+
+ return NULL;
+}
+
+/* Assumes the calling function takes care of locking */
+void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
+{
+ int i;
+
+ /* Runtime idling of dynamic pads */
+ if (state == _HWMOD_STATE_IDLE && hmux->enabled) {
+ for (i = 0; i < hmux->nr_pads_dynamic; i++) {
+ struct omap_device_pad *pad = hmux->pads_dynamic[i];
+ int val = -EINVAL;
+
+ val = pad->idle;
+ omap_mux_write(pad->partition, val,
+ pad->mux->reg_offset);
+ }
+
+ return;
+ }
+
+ /* Runtime enabling of dynamic pads */
+ if ((state == _HWMOD_STATE_ENABLED) && hmux->pads_dynamic
+ && hmux->enabled) {
+ for (i = 0; i < hmux->nr_pads_dynamic; i++) {
+ struct omap_device_pad *pad = hmux->pads_dynamic[i];
+ int val = -EINVAL;
+
+ val = pad->enable;
+ omap_mux_write(pad->partition, val,
+ pad->mux->reg_offset);
+ }
+
+ return;
+ }
+
+ /* Enabling or disabling of all pads */
+ for (i = 0; i < hmux->nr_pads; i++) {
+ struct omap_device_pad *pad = &hmux->pads[i];
+ int flags, val = -EINVAL;
+
+ flags = pad->flags;
+
+ switch (state) {
+ case _HWMOD_STATE_ENABLED:
+ val = pad->enable;
+ pr_debug("%s: Enabling %s %x\n", __func__,
+ pad->name, val);
+ break;
+ case _HWMOD_STATE_DISABLED:
+ /* Use safe mode unless OMAP_DEVICE_PAD_REMUX */
+ if (flags & OMAP_DEVICE_PAD_REMUX)
+ val = pad->off;
+ else
+ val = OMAP_MUX_MODE7;
+ pr_debug("%s: Disabling %s %x\n", __func__,
+ pad->name, val);
+ break;
+ default:
+ /* Nothing to be done */
+ break;
+ };
+
+ if (val >= 0) {
+ omap_mux_write(pad->partition, val,
+ pad->mux->reg_offset);
+ pad->flags = flags;
+ }
+ }
+
+ if (state == _HWMOD_STATE_ENABLED)
+ hmux->enabled = true;
+ else
+ hmux->enabled = false;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define OMAP_MUX_MAX_NR_FLAGS 10
+#define OMAP_MUX_TEST_FLAG(val, mask) \
+ if (((val) & (mask)) == (mask)) { \
+ i++; \
+ flags[i] = #mask; \
+ }
+
+/* REVISIT: Add checking for non-optimal mux settings */
+static inline void omap_mux_decode(struct seq_file *s, u16 val)
+{
+ char *flags[OMAP_MUX_MAX_NR_FLAGS];
+ char mode[sizeof("OMAP_MUX_MODE") + 1];
+ int i = -1;
+
+ sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
+ i++;
+ flags[i] = mode;
+
+ OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
+ if (val & OMAP_OFF_EN) {
+ if (!(val & OMAP_OFFOUT_EN)) {
+ if (!(val & OMAP_OFF_PULL_UP)) {
+ OMAP_MUX_TEST_FLAG(val,
+ OMAP_PIN_OFF_INPUT_PULLDOWN);
+ } else {
+ OMAP_MUX_TEST_FLAG(val,
+ OMAP_PIN_OFF_INPUT_PULLUP);
+ }
+ } else {
+ if (!(val & OMAP_OFFOUT_VAL)) {
+ OMAP_MUX_TEST_FLAG(val,
+ OMAP_PIN_OFF_OUTPUT_LOW);
+ } else {
+ OMAP_MUX_TEST_FLAG(val,
+ OMAP_PIN_OFF_OUTPUT_HIGH);
+ }
+ }
+ }
+
+ if (val & OMAP_INPUT_EN) {
+ if (val & OMAP_PULL_ENA) {
+ if (!(val & OMAP_PULL_UP)) {
+ OMAP_MUX_TEST_FLAG(val,
+ OMAP_PIN_INPUT_PULLDOWN);
+ } else {
+ OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
+ }
+ } else {
+ OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
+ }
+ } else {
+ i++;
+ flags[i] = "OMAP_PIN_OUTPUT";
+ }
+
+ do {
+ seq_printf(s, "%s", flags[i]);
+ if (i > 0)
+ seq_printf(s, " | ");
+ } while (i-- > 0);
+}
+
+#define OMAP_MUX_DEFNAME_LEN 32
+
+static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
+{
+ struct omap_mux_partition *partition = s->private;
+ struct omap_mux_entry *e;
+ u8 omap_gen = omap_rev() >> 28;
+
+ list_for_each_entry(e, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+ char m0_def[OMAP_MUX_DEFNAME_LEN];
+ char *m0_name = m->muxnames[0];
+ u16 val;
+ int i, mode;
+
+ if (!m0_name)
+ continue;
+
+ /* REVISIT: Needs to be updated if mode0 names get longer */
+ for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
+ if (m0_name[i] == '\0') {
+ m0_def[i] = m0_name[i];
+ break;
+ }
+ m0_def[i] = toupper(m0_name[i]);
+ }
+ val = omap_mux_read(partition, m->reg_offset);
+ mode = val & OMAP_MUX_MODE7;
+ if (mode != 0)
+ seq_printf(s, "/* %s */\n", m->muxnames[mode]);
+
+ /*
+ * XXX: Might be revisited to support differences across
+ * same OMAP generation.
+ */
+ seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
+ omap_mux_decode(s, val);
+ seq_printf(s, "),\n");
+ }
+
+ return 0;
+}
+
+static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, omap_mux_dbg_board_show, inode->i_private);
+}
+
+static const struct file_operations omap_mux_dbg_board_fops = {
+ .open = omap_mux_dbg_board_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct list_head *muxmodes = &partition->muxmodes;
+ struct omap_mux_entry *e;
+
+ list_for_each_entry(e, muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+
+ if (m == mux)
+ return partition;
+ }
+ }
+
+ return NULL;
+}
+
+static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
+{
+ struct omap_mux *m = s->private;
+ struct omap_mux_partition *partition;
+ const char *none = "NA";
+ u16 val;
+ int mode;
+
+ partition = omap_mux_get_partition(m);
+ if (!partition)
+ return 0;
+
+ val = omap_mux_read(partition, m->reg_offset);
+ mode = val & OMAP_MUX_MODE7;
+
+ seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
+ m->muxnames[0], m->muxnames[mode],
+ partition->phys + m->reg_offset, m->reg_offset, val,
+ m->balls[0] ? m->balls[0] : none,
+ m->balls[1] ? m->balls[1] : none);
+ seq_printf(s, "mode: ");
+ omap_mux_decode(s, val);
+ seq_printf(s, "\n");
+ seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
+ m->muxnames[0] ? m->muxnames[0] : none,
+ m->muxnames[1] ? m->muxnames[1] : none,
+ m->muxnames[2] ? m->muxnames[2] : none,
+ m->muxnames[3] ? m->muxnames[3] : none,
+ m->muxnames[4] ? m->muxnames[4] : none,
+ m->muxnames[5] ? m->muxnames[5] : none,
+ m->muxnames[6] ? m->muxnames[6] : none,
+ m->muxnames[7] ? m->muxnames[7] : none);
+
+ return 0;
+}
+
+#define OMAP_MUX_MAX_ARG_CHAR 7
+
+static ssize_t omap_mux_dbg_signal_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ char buf[OMAP_MUX_MAX_ARG_CHAR];
+ struct seq_file *seqf;
+ struct omap_mux *m;
+ unsigned long val;
+ int buf_size, ret;
+ struct omap_mux_partition *partition;
+
+ if (count > OMAP_MUX_MAX_ARG_CHAR)
+ return -EINVAL;
+
+ memset(buf, 0, sizeof(buf));
+ buf_size = min(count, sizeof(buf) - 1);
+
+ if (copy_from_user(buf, user_buf, buf_size))
+ return -EFAULT;
+
+ ret = strict_strtoul(buf, 0x10, &val);
+ if (ret < 0)
+ return ret;
+
+ if (val > 0xffff)
+ return -EINVAL;
+
+ seqf = file->private_data;
+ m = seqf->private;
+
+ partition = omap_mux_get_partition(m);
+ if (!partition)
+ return -ENODEV;
+
+ omap_mux_write(partition, (u16)val, m->reg_offset);
+ *ppos += count;
+
+ return count;
+}
+
+static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
+}
+
+static const struct file_operations omap_mux_dbg_signal_fops = {
+ .open = omap_mux_dbg_signal_open,
+ .read = seq_read,
+ .write = omap_mux_dbg_signal_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static struct dentry *mux_dbg_dir;
+
+static void __init omap_mux_dbg_create_entry(
+ struct omap_mux_partition *partition,
+ struct dentry *mux_dbg_dir)
+{
+ struct omap_mux_entry *e;
+
+ list_for_each_entry(e, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+
+ (void)debugfs_create_file(m->muxnames[0], S_IWUSR, mux_dbg_dir,
+ m, &omap_mux_dbg_signal_fops);
+ }
+}
+
+static void __init omap_mux_dbg_init(void)
+{
+ struct omap_mux_partition *partition;
+ static struct dentry *mux_dbg_board_dir;
+
+ mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
+ if (!mux_dbg_dir)
+ return;
+
+ mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
+ if (!mux_dbg_board_dir)
+ return;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ omap_mux_dbg_create_entry(partition, mux_dbg_dir);
+ (void)debugfs_create_file(partition->name, S_IRUGO,
+ mux_dbg_board_dir, partition,
+ &omap_mux_dbg_board_fops);
+ }
+}
+
+#else
+static inline void omap_mux_dbg_init(void)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static void __init omap_mux_free_names(struct omap_mux *m)
+{
+ int i;
+
+ for (i = 0; i < OMAP_MUX_NR_MODES; i++)
+ kfree(m->muxnames[i]);
+
+#ifdef CONFIG_DEBUG_FS
+ for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
+ kfree(m->balls[i]);
+#endif
+
+}
+
+/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
+static int __init omap_mux_late_init(void)
+{
+ struct omap_mux_partition *partition;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ struct omap_mux_entry *e, *tmp;
+ list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+ u16 mode = omap_mux_read(partition, m->reg_offset);
+
+ if (OMAP_MODE_GPIO(mode))
+ continue;
+
+#ifndef CONFIG_DEBUG_FS
+ mutex_lock(&muxmode_mutex);
+ list_del(&e->node);
+ mutex_unlock(&muxmode_mutex);
+ omap_mux_free_names(m);
+ kfree(m);
+#endif
+ }
+ }
+
+ omap_mux_dbg_init();
+
+ return 0;
+}
+late_initcall(omap_mux_late_init);
+
+static void __init omap_mux_package_fixup(struct omap_mux *p,
+ struct omap_mux *superset)
+{
+ while (p->reg_offset != OMAP_MUX_TERMINATOR) {
+ struct omap_mux *s = superset;
+ int found = 0;
+
+ while (s->reg_offset != OMAP_MUX_TERMINATOR) {
+ if (s->reg_offset == p->reg_offset) {
+ *s = *p;
+ found++;
+ break;
+ }
+ s++;
+ }
+ if (!found)
+ pr_err("%s: Unknown entry offset 0x%x\n", __func__,
+ p->reg_offset);
+ p++;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static void __init omap_mux_package_init_balls(struct omap_ball *b,
+ struct omap_mux *superset)
+{
+ while (b->reg_offset != OMAP_MUX_TERMINATOR) {
+ struct omap_mux *s = superset;
+ int found = 0;
+
+ while (s->reg_offset != OMAP_MUX_TERMINATOR) {
+ if (s->reg_offset == b->reg_offset) {
+ s->balls[0] = b->balls[0];
+ s->balls[1] = b->balls[1];
+ found++;
+ break;
+ }
+ s++;
+ }
+ if (!found)
+ pr_err("%s: Unknown ball offset 0x%x\n", __func__,
+ b->reg_offset);
+ b++;
+ }
+}
+
+#else /* CONFIG_DEBUG_FS */
+
+static inline void omap_mux_package_init_balls(struct omap_ball *b,
+ struct omap_mux *superset)
+{
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __init omap_mux_setup(char *options)
+{
+ if (!options)
+ return 0;
+
+ omap_mux_options = options;
+
+ return 1;
+}
+__setup("omap_mux=", omap_mux_setup);
+
+/*
+ * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
+ * cmdline options only override the bootloader values.
+ * During development, please enable CONFIG_DEBUG_FS, and use the
+ * signal specific entries under debugfs.
+ */
+static void __init omap_mux_set_cmdline_signals(void)
+{
+ char *options, *next_opt, *token;
+
+ if (!omap_mux_options)
+ return;
+
+ options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL);
+ if (!options)
+ return;
+
+ strcpy(options, omap_mux_options);
+ next_opt = options;
+
+ while ((token = strsep(&next_opt, ",")) != NULL) {
+ char *keyval, *name;
+ unsigned long val;
+
+ keyval = token;
+ name = strsep(&keyval, "=");
+ if (name) {
+ int res;
+
+ res = strict_strtoul(keyval, 0x10, &val);
+ if (res < 0)
+ continue;
+
+ omap_mux_init_signal(name, (u16)val);
+ }
+ }
+
+ kfree(options);
+}
+
+static int __init omap_mux_copy_names(struct omap_mux *src,
+ struct omap_mux *dst)
+{
+ int i;
+
+ for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
+ if (src->muxnames[i]) {
+ dst->muxnames[i] =
+ kmalloc(strlen(src->muxnames[i]) + 1,
+ GFP_KERNEL);
+ if (!dst->muxnames[i])
+ goto free;
+ strcpy(dst->muxnames[i], src->muxnames[i]);
+ }
+ }
+
+#ifdef CONFIG_DEBUG_FS
+ for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
+ if (src->balls[i]) {
+ dst->balls[i] =
+ kmalloc(strlen(src->balls[i]) + 1,
+ GFP_KERNEL);
+ if (!dst->balls[i])
+ goto free;
+ strcpy(dst->balls[i], src->balls[i]);
+ }
+ }
+#endif
+
+ return 0;
+
+free:
+ omap_mux_free_names(dst);
+ return -ENOMEM;
+
+}
+
+#endif /* CONFIG_OMAP_MUX */
+
+static struct omap_mux *omap_mux_get_by_gpio(
+ struct omap_mux_partition *partition,
+ int gpio)
+{
+ struct omap_mux_entry *e;
+ struct omap_mux *ret = NULL;
+
+ list_for_each_entry(e, &partition->muxmodes, node) {
+ struct omap_mux *m = &e->mux;
+ if (m->gpio == gpio) {
+ ret = m;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/* Needed for dynamic muxing of GPIO pins for off-idle */
+u16 omap_mux_get_gpio(int gpio)
+{
+ struct omap_mux_partition *partition;
+ struct omap_mux *m = NULL;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ m = omap_mux_get_by_gpio(partition, gpio);
+ if (m)
+ return omap_mux_read(partition, m->reg_offset);
+ }
+
+ if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
+ pr_err("%s: Could not get gpio%i\n", __func__, gpio);
+
+ return OMAP_MUX_TERMINATOR;
+}
+
+/* Needed for dynamic muxing of GPIO pins for off-idle */
+void omap_mux_set_gpio(u16 val, int gpio)
+{
+ struct omap_mux_partition *partition;
+ struct omap_mux *m = NULL;
+
+ list_for_each_entry(partition, &mux_partitions, node) {
+ m = omap_mux_get_by_gpio(partition, gpio);
+ if (m) {
+ omap_mux_write(partition, val, m->reg_offset);
+ return;
+ }
+ }
+
+ if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
+ pr_err("%s: Could not set gpio%i\n", __func__, gpio);
+}
+
+static struct omap_mux * __init omap_mux_list_add(
+ struct omap_mux_partition *partition,
+ struct omap_mux *src)
+{
+ struct omap_mux_entry *entry;
+ struct omap_mux *m;
+
+ entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
+ if (!entry)
+ return NULL;
+
+ m = &entry->mux;
+ entry->mux = *src;
+
+#ifdef CONFIG_OMAP_MUX
+ if (omap_mux_copy_names(src, m)) {
+ kfree(entry);
+ return NULL;
+ }
+#endif
+
+ mutex_lock(&muxmode_mutex);
+ list_add_tail(&entry->node, &partition->muxmodes);
+ mutex_unlock(&muxmode_mutex);
+
+ return m;
+}
+
+/*
+ * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
+ * the GPIO to mux offset mapping that is needed for dynamic muxing
+ * of GPIO pins for off-idle.
+ */
+static void __init omap_mux_init_list(struct omap_mux_partition *partition,
+ struct omap_mux *superset)
+{
+ while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
+ struct omap_mux *entry;
+
+#ifdef CONFIG_OMAP_MUX
+ if (!superset->muxnames || !superset->muxnames[0]) {
+ superset++;
+ continue;
+ }
+#else
+ /* Skip pins that are not muxed as GPIO by bootloader */
+ if (!OMAP_MODE_GPIO(omap_mux_read(partition,
+ superset->reg_offset))) {
+ superset++;
+ continue;
+ }
+#endif
+
+ entry = omap_mux_list_add(partition, superset);
+ if (!entry) {
+ pr_err("%s: Could not add entry\n", __func__);
+ return;
+ }
+ superset++;
+ }
+}
+
+#ifdef CONFIG_OMAP_MUX
+
+static void omap_mux_init_package(struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_ball *package_balls)
+{
+ if (package_subset)
+ omap_mux_package_fixup(package_subset, superset);
+ if (package_balls)
+ omap_mux_package_init_balls(package_balls, superset);
+}
+
+static void omap_mux_init_signals(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
+{
+ omap_mux_set_cmdline_signals();
+ omap_mux_write_array(partition, board_mux);
+}
+
+#else
+
+static void omap_mux_init_package(struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_ball *package_balls)
+{
+}
+
+static void omap_mux_init_signals(struct omap_mux_partition *partition,
+ struct omap_board_mux *board_mux)
+{
+}
+
+#endif
+
+static u32 mux_partitions_cnt;
+
+int __init omap_mux_init(const char *name, u32 flags,
+ u32 mux_pbase, u32 mux_size,
+ struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_board_mux *board_mux,
+ struct omap_ball *package_balls)
+{
+ struct omap_mux_partition *partition;
+
+ partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
+ if (!partition)
+ return -ENOMEM;
+
+ partition->name = name;
+ partition->flags = flags;
+ partition->size = mux_size;
+ partition->phys = mux_pbase;
+ partition->base = ioremap(mux_pbase, mux_size);
+ if (!partition->base) {
+ pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
+ __func__, partition->phys);
+ kfree(partition);
+ return -ENODEV;
+ }
+
+ INIT_LIST_HEAD(&partition->muxmodes);
+
+ list_add_tail(&partition->node, &mux_partitions);
+ mux_partitions_cnt++;
+ pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
+ mux_partitions_cnt, partition->name, partition->flags);
+
+ omap_mux_init_package(superset, package_subset, package_balls);
+ omap_mux_init_list(partition, superset);
+ omap_mux_init_signals(partition, board_mux);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
new file mode 100644
index 00000000..2132308a
--- /dev/null
+++ b/arch/arm/mach-omap2/mux.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009-2010 Texas Instruments
+ *
+ * This program is free software; you can 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 "mux2420.h"
+#include "mux2430.h"
+#include "mux34xx.h"
+#include "mux44xx.h"
+
+#define OMAP_MUX_TERMINATOR 0xffff
+
+/* 34xx mux mode options for each pin. See TRM for options */
+#define OMAP_MUX_MODE0 0
+#define OMAP_MUX_MODE1 1
+#define OMAP_MUX_MODE2 2
+#define OMAP_MUX_MODE3 3
+#define OMAP_MUX_MODE4 4
+#define OMAP_MUX_MODE5 5
+#define OMAP_MUX_MODE6 6
+#define OMAP_MUX_MODE7 7
+
+/* 24xx/34xx mux bit defines */
+#define OMAP_PULL_ENA (1 << 3)
+#define OMAP_PULL_UP (1 << 4)
+#define OMAP_ALTELECTRICALSEL (1 << 5)
+
+/* 34xx specific mux bit defines */
+#define OMAP_INPUT_EN (1 << 8)
+#define OMAP_OFF_EN (1 << 9)
+#define OMAP_OFFOUT_EN (1 << 10)
+#define OMAP_OFFOUT_VAL (1 << 11)
+#define OMAP_OFF_PULL_EN (1 << 12)
+#define OMAP_OFF_PULL_UP (1 << 13)
+#define OMAP_WAKEUP_EN (1 << 14)
+
+/* 44xx specific mux bit defines */
+#define OMAP_WAKEUP_EVENT (1 << 15)
+
+/* Active pin states */
+#define OMAP_PIN_OUTPUT 0
+#define OMAP_PIN_INPUT OMAP_INPUT_EN
+#define OMAP_PIN_INPUT_PULLUP (OMAP_PULL_ENA | OMAP_INPUT_EN \
+ | OMAP_PULL_UP)
+#define OMAP_PIN_INPUT_PULLDOWN (OMAP_PULL_ENA | OMAP_INPUT_EN)
+
+/* Off mode states */
+#define OMAP_PIN_OFF_NONE 0
+#define OMAP_PIN_OFF_OUTPUT_HIGH (OMAP_OFF_EN | OMAP_OFFOUT_EN \
+ | OMAP_OFFOUT_VAL)
+#define OMAP_PIN_OFF_OUTPUT_LOW (OMAP_OFF_EN | OMAP_OFFOUT_EN)
+#define OMAP_PIN_OFF_INPUT_PULLUP (OMAP_OFF_EN | OMAP_OFF_PULL_EN \
+ | OMAP_OFF_PULL_UP)
+#define OMAP_PIN_OFF_INPUT_PULLDOWN (OMAP_OFF_EN | OMAP_OFF_PULL_EN)
+#define OMAP_PIN_OFF_WAKEUPENABLE OMAP_WAKEUP_EN
+
+#define OMAP_MODE_GPIO(x) (((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)
+
+/* Flags for omapX_mux_init */
+#define OMAP_PACKAGE_MASK 0xffff
+#define OMAP_PACKAGE_CBS 8 /* 547-pin 0.40 0.40 */
+#define OMAP_PACKAGE_CBL 7 /* 547-pin 0.40 0.40 */
+#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */
+#define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CBC 3 /* 515-pin 0.50 0.65 */
+#define OMAP_PACKAGE_ZAC 2 /* 24xx 447-pin POP */
+#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */
+
+
+#define OMAP_MUX_NR_MODES 8 /* Available modes */
+#define OMAP_MUX_NR_SIDES 2 /* Bottom & top */
+
+/*
+ * omap_mux_init flags definition:
+ *
+ * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
+ * The default value is 16 bits.
+ * OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.
+ * The default is mode4.
+ */
+#define OMAP_MUX_REG_8BIT (1 << 0)
+#define OMAP_MUX_GPIO_IN_MODE3 (1 << 1)
+
+/**
+ * struct omap_board_data - board specific device data
+ * @id: instance id
+ * @flags: additional flags for platform init code
+ * @pads: array of device specific pads
+ * @pads_cnt: ARRAY_SIZE() of pads
+ */
+struct omap_board_data {
+ int id;
+ u32 flags;
+ struct omap_device_pad *pads;
+ int pads_cnt;
+};
+
+/**
+ * struct mux_partition - contain partition related information
+ * @name: name of the current partition
+ * @flags: flags specific to this partition
+ * @phys: physical address
+ * @size: partition size
+ * @base: virtual address after ioremap
+ * @muxmodes: list of nodes that belong to a partition
+ * @node: list node for the partitions linked list
+ */
+struct omap_mux_partition {
+ const char *name;
+ u32 flags;
+ u32 phys;
+ u32 size;
+ void __iomem *base;
+ struct list_head muxmodes;
+ struct list_head node;
+};
+
+/**
+ * struct omap_mux - data for omap mux register offset and it's value
+ * @reg_offset: mux register offset from the mux base
+ * @gpio: GPIO number
+ * @muxnames: available signal modes for a ball
+ * @balls: available balls on the package
+ * @partition: mux partition
+ */
+struct omap_mux {
+ u16 reg_offset;
+ u16 gpio;
+#ifdef CONFIG_OMAP_MUX
+ char *muxnames[OMAP_MUX_NR_MODES];
+#ifdef CONFIG_DEBUG_FS
+ char *balls[OMAP_MUX_NR_SIDES];
+#endif
+#endif
+};
+
+/**
+ * struct omap_ball - data for balls on omap package
+ * @reg_offset: mux register offset from the mux base
+ * @balls: available balls on the package
+ */
+struct omap_ball {
+ u16 reg_offset;
+ char *balls[OMAP_MUX_NR_SIDES];
+};
+
+/**
+ * struct omap_board_mux - data for initializing mux registers
+ * @reg_offset: mux register offset from the mux base
+ * @mux_value: desired mux value to set
+ */
+struct omap_board_mux {
+ u16 reg_offset;
+ u16 value;
+};
+
+#define OMAP_DEVICE_PAD_REMUX BIT(1) /* Dynamically remux a pad,
+ needs enable, idle and off
+ values */
+#define OMAP_DEVICE_PAD_WAKEUP BIT(0) /* Pad is wake-up capable */
+
+/**
+ * struct omap_device_pad - device specific pad configuration
+ * @name: signal name
+ * @flags: pad specific runtime flags
+ * @enable: runtime value for a pad
+ * @idle: idle value for a pad
+ * @off: off value for a pad, defaults to safe mode
+ * @partition: mux partition
+ * @mux: mux register
+ */
+struct omap_device_pad {
+ char *name;
+ u8 flags;
+ u16 enable;
+ u16 idle;
+ u16 off;
+ struct omap_mux_partition *partition;
+ struct omap_mux *mux;
+};
+
+struct omap_hwmod_mux_info;
+
+#define OMAP_MUX_STATIC(signal, mode) \
+{ \
+ .name = (signal), \
+ .enable = (mode), \
+}
+
+#if defined(CONFIG_OMAP_MUX)
+
+/**
+ * omap_mux_init_gpio - initialize a signal based on the GPIO number
+ * @gpio: GPIO number
+ * @val: Options for the mux register value
+ */
+int omap_mux_init_gpio(int gpio, int val);
+
+/**
+ * omap_mux_init_signal - initialize a signal based on the signal name
+ * @muxname: Mux name in mode0_name.signal_name format
+ * @val: Options for the mux register value
+ */
+int omap_mux_init_signal(const char *muxname, int val);
+
+/**
+ * omap_hwmod_mux_init - initialize hwmod specific mux data
+ * @bpads: Board specific device signal names
+ * @nr_pads: Number of signal names for the device
+ */
+extern struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads);
+
+/**
+ * omap_hwmod_mux - omap hwmod specific pin muxing
+ * @hmux: Pads for a hwmod
+ * @state: Desired _HWMOD_STATE
+ *
+ * Called only from omap_hwmod.c, do not use.
+ */
+void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state);
+
+#else
+
+static inline int omap_mux_init_gpio(int gpio, int val)
+{
+ return 0;
+}
+static inline int omap_mux_init_signal(char *muxname, int val)
+{
+ return 0;
+}
+
+static inline struct omap_hwmod_mux_info *
+omap_hwmod_mux_init(struct omap_device_pad *bpads, int nr_pads)
+{
+ return NULL;
+}
+
+static inline void omap_hwmod_mux(struct omap_hwmod_mux_info *hmux, u8 state)
+{
+}
+
+static struct omap_board_mux *board_mux __initdata __maybe_unused;
+
+#endif
+
+/**
+ * omap_mux_get_gpio() - get mux register value based on GPIO number
+ * @gpio: GPIO number
+ *
+ */
+u16 omap_mux_get_gpio(int gpio);
+
+/**
+ * omap_mux_set_gpio() - set mux register value based on GPIO number
+ * @val: New mux register value
+ * @gpio: GPIO number
+ *
+ */
+void omap_mux_set_gpio(u16 val, int gpio);
+
+/**
+ * omap_mux_get() - get a mux partition by name
+ * @name: Name of the mux partition
+ *
+ */
+struct omap_mux_partition *omap_mux_get(const char *name);
+
+/**
+ * omap_mux_read() - read mux register
+ * @partition: Mux partition
+ * @mux_offset: Offset of the mux register
+ *
+ */
+u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset);
+
+/**
+ * omap_mux_write() - write mux register
+ * @partition: Mux partition
+ * @val: New mux register value
+ * @mux_offset: Offset of the mux register
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset);
+
+/**
+ * omap_mux_write_array() - write an array of mux registers
+ * @partition: Mux partition
+ * @board_mux: Array of mux registers terminated by MAP_MUX_TERMINATOR
+ *
+ * This should be only needed for dynamic remuxing of non-gpio signals.
+ */
+void omap_mux_write_array(struct omap_mux_partition *p,
+ struct omap_board_mux *board_mux);
+
+/**
+ * omap2420_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap2420_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
+ * omap2430_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap2430_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
+ * omap3_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
+ * omap4_mux_init() - initialize mux system with board specific set
+ * @board_subset: Board specific mux table
+ * @board_wkup_subset: Board specific mux table for wakeup instance
+ * @flags: OMAP package type used for the board
+ */
+int omap4_mux_init(struct omap_board_mux *board_subset,
+ struct omap_board_mux *board_wkup_subset, int flags);
+
+/**
+ * omap_mux_init - private mux init function, do not call
+ */
+int omap_mux_init(const char *name, u32 flags,
+ u32 mux_pbase, u32 mux_size,
+ struct omap_mux *superset,
+ struct omap_mux *package_subset,
+ struct omap_board_mux *board_mux,
+ struct omap_ball *package_balls);
+
diff --git a/arch/arm/mach-omap2/mux2420.c b/arch/arm/mach-omap2/mux2420.c
new file mode 100644
index 00000000..cf6de097
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2420.c
@@ -0,0 +1,690 @@
+/*
+ * Copyright (C) 2010 Nokia
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can 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/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP2420_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP2420_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP2420_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap2420
+ */
+static struct omap_mux __initdata omap2420_muxmodes[] = {
+ _OMAP2420_MUXENTRY(CAM_D0, 54,
+ "cam_d0", "hw_dbg2", "sti_dout", "gpio_54",
+ NULL, NULL, "etk_d2", NULL),
+ _OMAP2420_MUXENTRY(CAM_D1, 53,
+ "cam_d1", "hw_dbg3", "sti_din", "gpio_53",
+ NULL, NULL, "etk_d3", NULL),
+ _OMAP2420_MUXENTRY(CAM_D2, 52,
+ "cam_d2", "hw_dbg4", "mcbsp1_clkx", "gpio_52",
+ NULL, NULL, "etk_d4", NULL),
+ _OMAP2420_MUXENTRY(CAM_D3, 51,
+ "cam_d3", "hw_dbg5", "mcbsp1_dr", "gpio_51",
+ NULL, NULL, "etk_d5", NULL),
+ _OMAP2420_MUXENTRY(CAM_D4, 50,
+ "cam_d4", "hw_dbg6", "mcbsp1_fsr", "gpio_50",
+ NULL, NULL, "etk_d6", NULL),
+ _OMAP2420_MUXENTRY(CAM_D5, 49,
+ "cam_d5", "hw_dbg7", "mcbsp1_clkr", "gpio_49",
+ NULL, NULL, "etk_d7", NULL),
+ _OMAP2420_MUXENTRY(CAM_D6, 0,
+ "cam_d6", "hw_dbg8", NULL, NULL,
+ NULL, NULL, "etk_d8", NULL),
+ _OMAP2420_MUXENTRY(CAM_D7, 0,
+ "cam_d7", "hw_dbg9", NULL, NULL,
+ NULL, NULL, "etk_d9", NULL),
+ _OMAP2420_MUXENTRY(CAM_D8, 54,
+ "cam_d8", "hw_dbg10", NULL, "gpio_54",
+ NULL, NULL, "etk_d10", NULL),
+ _OMAP2420_MUXENTRY(CAM_D9, 53,
+ "cam_d9", "hw_dbg11", NULL, "gpio_53",
+ NULL, NULL, "etk_d11", NULL),
+ _OMAP2420_MUXENTRY(CAM_HS, 55,
+ "cam_hs", "hw_dbg1", "mcbsp1_dx", "gpio_55",
+ NULL, NULL, "etk_d1", NULL),
+ _OMAP2420_MUXENTRY(CAM_LCLK, 57,
+ "cam_lclk", NULL, "mcbsp_clks", "gpio_57",
+ NULL, NULL, "etk_c1", NULL),
+ _OMAP2420_MUXENTRY(CAM_VS, 56,
+ "cam_vs", "hw_dbg0", "mcbsp1_fsx", "gpio_56",
+ NULL, NULL, "etk_d0", NULL),
+ _OMAP2420_MUXENTRY(CAM_XCLK, 0,
+ "cam_xclk", NULL, "sti_clk", NULL,
+ NULL, NULL, "etk_c2", NULL),
+ _OMAP2420_MUXENTRY(DSS_ACBIAS, 48,
+ "dss_acbias", NULL, "mcbsp2_fsx", "gpio_48",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA10, 40,
+ "dss_data10", NULL, NULL, "gpio_40",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA11, 41,
+ "dss_data11", NULL, NULL, "gpio_41",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA12, 42,
+ "dss_data12", NULL, NULL, "gpio_42",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA13, 43,
+ "dss_data13", NULL, NULL, "gpio_43",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA14, 44,
+ "dss_data14", NULL, NULL, "gpio_44",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA15, 45,
+ "dss_data15", NULL, NULL, "gpio_45",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA16, 46,
+ "dss_data16", NULL, NULL, "gpio_46",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA17, 47,
+ "dss_data17", NULL, NULL, "gpio_47",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA8, 38,
+ "dss_data8", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA9, 39,
+ "dss_data9", NULL, NULL, "gpio_39",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_DIN, 115,
+ "eac_ac_din", "mcbsp2_dr", NULL, "gpio_115",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_DOUT, 116,
+ "eac_ac_dout", "mcbsp2_dx", NULL, "gpio_116",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_FS, 114,
+ "eac_ac_fs", "mcbsp2_fsx", NULL, "gpio_114",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_MCLK, 117,
+ "eac_ac_mclk", NULL, NULL, "gpio_117",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_RST, 118,
+ "eac_ac_rst", "eac_bt_din", NULL, "gpio_118",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_SCLK, 113,
+ "eac_ac_sclk", "mcbsp2_clkx", NULL, "gpio_113",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_DIN, 73,
+ "eac_bt_din", NULL, NULL, "gpio_73",
+ NULL, NULL, "etk_d9", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_DOUT, 74,
+ "eac_bt_dout", NULL, "sti_clk", "gpio_74",
+ NULL, NULL, "etk_d8", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_FS, 72,
+ "eac_bt_fs", NULL, NULL, "gpio_72",
+ NULL, NULL, "etk_d10", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_SCLK, 71,
+ "eac_bt_sclk", NULL, NULL, "gpio_71",
+ NULL, NULL, "etk_d11", NULL),
+ _OMAP2420_MUXENTRY(GPIO_119, 119,
+ "gpio_119", NULL, "sti_din", "gpio_119",
+ NULL, "sys_boot0", "etk_d12", NULL),
+ _OMAP2420_MUXENTRY(GPIO_120, 120,
+ "gpio_120", NULL, "sti_dout", "gpio_120",
+ "cam_d9", "sys_boot1", "etk_d13", NULL),
+ _OMAP2420_MUXENTRY(GPIO_121, 121,
+ "gpio_121", NULL, NULL, "gpio_121",
+ "jtag_emu2", "sys_boot2", "etk_d14", NULL),
+ _OMAP2420_MUXENTRY(GPIO_122, 122,
+ "gpio_122", NULL, NULL, "gpio_122",
+ "jtag_emu3", "sys_boot3", "etk_d15", NULL),
+ _OMAP2420_MUXENTRY(GPIO_124, 124,
+ "gpio_124", NULL, NULL, "gpio_124",
+ NULL, "sys_boot5", NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_125, 125,
+ "gpio_125", "sys_jtagsel1", "sys_jtagsel2", "gpio_125",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_36, 36,
+ "gpio_36", NULL, NULL, "gpio_36",
+ NULL, "sys_boot4", NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_62, 62,
+ "gpio_62", "uart1_rx", "usb1_dat", "gpio_62",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_6, 6,
+ "gpio_6", "tv_detpulse", NULL, "gpio_6",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A10, 3,
+ "gpmc_a10", NULL, "sys_ndmareq5", "gpio_3",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A1, 12,
+ "gpmc_a1", "dss_data18", NULL, "gpio_12",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A2, 11,
+ "gpmc_a2", "dss_data19", NULL, "gpio_11",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A3, 10,
+ "gpmc_a3", "dss_data20", NULL, "gpio_10",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A4, 9,
+ "gpmc_a4", "dss_data21", NULL, "gpio_9",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A5, 8,
+ "gpmc_a5", "dss_data22", NULL, "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A6, 7,
+ "gpmc_a6", "dss_data23", NULL, "gpio_7",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A7, 6,
+ "gpmc_a7", NULL, "sys_ndmareq2", "gpio_6",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A8, 5,
+ "gpmc_a8", NULL, "sys_ndmareq3", "gpio_5",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A9, 4,
+ "gpmc_a9", NULL, "sys_ndmareq4", "gpio_4",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_CLK, 21,
+ "gpmc_clk", NULL, NULL, "gpio_21",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D10, 18,
+ "gpmc_d10", "ssi2_rdy_rx", NULL, "gpio_18",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D11, 17,
+ "gpmc_d11", "ssi2_flag_rx", NULL, "gpio_17",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D12, 16,
+ "gpmc_d12", "ssi2_dat_rx", NULL, "gpio_16",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D13, 15,
+ "gpmc_d13", "ssi2_rdy_tx", NULL, "gpio_15",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D14, 14,
+ "gpmc_d14", "ssi2_flag_tx", NULL, "gpio_14",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D15, 13,
+ "gpmc_d15", "ssi2_dat_tx", NULL, "gpio_13",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D8, 20,
+ "gpmc_d8", NULL, NULL, "gpio_20",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D9, 19,
+ "gpmc_d9", "ssi2_wake", NULL, "gpio_19",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NBE0, 29,
+ "gpmc_nbe0", NULL, NULL, "gpio_29",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NBE1, 30,
+ "gpmc_nbe1", NULL, NULL, "gpio_30",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS1, 22,
+ "gpmc_ncs1", NULL, NULL, "gpio_22",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS2, 23,
+ "gpmc_ncs2", NULL, NULL, "gpio_23",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS3, 24,
+ "gpmc_ncs3", "gpmc_io_dir", NULL, "gpio_24",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS4, 25,
+ "gpmc_ncs4", NULL, NULL, "gpio_25",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS5, 26,
+ "gpmc_ncs5", NULL, NULL, "gpio_26",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS6, 27,
+ "gpmc_ncs6", NULL, NULL, "gpio_27",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS7, 28,
+ "gpmc_ncs7", "gpmc_io_dir", "gpio_28", NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NWP, 31,
+ "gpmc_nwp", NULL, NULL, "gpio_31",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT1, 33,
+ "gpmc_wait1", NULL, NULL, "gpio_33",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT2, 34,
+ "gpmc_wait2", NULL, NULL, "gpio_34",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT3, 35,
+ "gpmc_wait3", NULL, NULL, "gpio_35",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(HDQ_SIO, 101,
+ "hdq_sio", "usb2_tllse0", "sys_altclk", "gpio_101",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(I2C2_SCL, 99,
+ "i2c2_scl", NULL, "gpt9_pwm_evt", "gpio_99",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(I2C2_SDA, 100,
+ "i2c2_sda", NULL, "spi2_ncs1", "gpio_100",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(JTAG_EMU0, 127,
+ "jtag_emu0", NULL, NULL, "gpio_127",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(JTAG_EMU1, 126,
+ "jtag_emu1", NULL, NULL, "gpio_126",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_CLKR, 92,
+ "mcbsp1_clkr", "ssi2_dat_tx", "vlynq_tx1", "gpio_92",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_CLKX, 98,
+ "mcbsp1_clkx", "ssi2_wake", "vlynq_nla", "gpio_98",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_DR, 95,
+ "mcbsp1_dr", "ssi2_dat_rx", "vlynq_rx1", "gpio_95",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_DX, 94,
+ "mcbsp1_dx", "ssi2_rdy_tx", "vlynq_clk", "gpio_94",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_FSR, 93,
+ "mcbsp1_fsr", "ssi2_flag_tx", "vlynq_tx0", "gpio_93",
+ "spi2_ncs1", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_FSX, 97,
+ "mcbsp1_fsx", "ssi2_rdy_rx", NULL, "gpio_97",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP2_CLKX, 12,
+ "mcbsp2_clkx", NULL, "dss_data23", "gpio_12",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP2_DR, 11,
+ "mcbsp2_dr", NULL, "dss_data22", "gpio_11",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP_CLKS, 96,
+ "mcbsp_clks", "ssi2_flag_rx", "vlynq_rx0", "gpio_96",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CLKI, 59,
+ "sdmmc_clki", "ms_clki", NULL, "gpio_59",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CLKO, 0,
+ "sdmmc_clko", "ms_clko", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CMD_DIR, 8,
+ "sdmmc_cmd_dir", NULL, NULL, "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CMD, 0,
+ "sdmmc_cmd", "ms_bs", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR0, 7,
+ "sdmmc_dat_dir0", "ms_dat0_dir", NULL, "gpio_7",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT0, 0,
+ "sdmmc_dat0", "ms_dat0", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR1, 78,
+ "sdmmc_dat_dir1", "ms_datu_dir", "uart2_rts", "gpio_78",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT1, 75,
+ "sdmmc_dat1", "ms_dat1", NULL, "gpio_75",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR2, 79,
+ "sdmmc_dat_dir2", "ms_datu_dir", "uart2_tx", "gpio_79",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT2, 76,
+ "sdmmc_dat2", "ms_dat2", "uart2_cts", "gpio_76",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR3, 80,
+ "sdmmc_dat_dir3", "ms_datu_dir", "uart2_rx", "gpio_80",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT3, 77,
+ "sdmmc_dat3", "ms_dat3", NULL, "gpio_77",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A12, 2,
+ "sdrc_a12", NULL, NULL, "gpio_2",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A13, 1,
+ "sdrc_a13", NULL, NULL, "gpio_1",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A14, 0,
+ "sdrc_a14", NULL, NULL, "gpio_0",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_CKE1, 38,
+ "sdrc_cke1", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_NCS1, 37,
+ "sdrc_ncs1", NULL, NULL, "gpio_37",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_CLK, 81,
+ "spi1_clk", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS0, 84,
+ "spi1_ncs0", NULL, NULL, "gpio_84",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS1, 85,
+ "spi1_ncs1", NULL, NULL, "gpio_85",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS2, 86,
+ "spi1_ncs2", NULL, NULL, "gpio_86",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS3, 87,
+ "spi1_ncs3", NULL, NULL, "gpio_87",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_SIMO, 82,
+ "spi1_simo", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_SOMI, 83,
+ "spi1_somi", NULL, NULL, "gpio_83",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_CLK, 88,
+ "spi2_clk", NULL, NULL, "gpio_88",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_NCS0, 91,
+ "spi2_ncs0", "gpt12_pwm_evt", NULL, "gpio_91",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_SIMO, 89,
+ "spi2_simo", "gpt10_pwm_evt", NULL, "gpio_89",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_SOMI, 90,
+ "spi2_somi", "gpt11_pwm_evt", NULL, "gpio_90",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_DAT_RX, 63,
+ "ssi1_dat_rx", "eac_md_sclk", NULL, "gpio_63",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_DAT_TX, 59,
+ "ssi1_dat_tx", "uart1_tx", "usb1_se0", "gpio_59",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_FLAG_RX, 64,
+ "ssi1_flag_rx", "eac_md_din", NULL, "gpio_64",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_FLAG_TX, 25,
+ "ssi1_flag_tx", "uart1_rts", "usb1_rcv", "gpio_25",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_RDY_RX, 65,
+ "ssi1_rdy_rx", "eac_md_dout", NULL, "gpio_65",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_RDY_TX, 61,
+ "ssi1_rdy_tx", "uart1_cts", "usb1_txen", "gpio_61",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_WAKE, 66,
+ "ssi1_wake", "eac_md_fs", NULL, "gpio_66",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_CLKOUT, 123,
+ "sys_clkout", NULL, NULL, "gpio_123",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_CLKREQ, 52,
+ "sys_clkreq", NULL, NULL, "gpio_52",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_NIRQ, 60,
+ "sys_nirq", NULL, NULL, "gpio_60",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_CTS, 32,
+ "uart1_cts", NULL, "dss_data18", "gpio_32",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_RTS, 8,
+ "uart1_rts", NULL, "dss_data19", "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_RX, 10,
+ "uart1_rx", NULL, "dss_data21", "gpio_10",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_TX, 9,
+ "uart1_tx", NULL, "dss_data20", "gpio_9",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_CTS, 67,
+ "uart2_cts", "usb1_rcv", "gpt9_pwm_evt", "gpio_67",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_RTS, 68,
+ "uart2_rts", "usb1_txen", "gpt10_pwm_evt", "gpio_68",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_RX, 70,
+ "uart2_rx", "usb1_dat", "gpt12_pwm_evt", "gpio_70",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_TX, 69,
+ "uart2_tx", "usb1_se0", "gpt11_pwm_evt", "gpio_69",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_CTS_RCTX, 102,
+ "uart3_cts_rctx", "uart3_rx_irrx", NULL, "gpio_102",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_RTS_SD, 103,
+ "uart3_rts_sd", "uart3_tx_irtx", NULL, "gpio_103",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_RX_IRRX, 105,
+ "uart3_rx_irrx", NULL, NULL, "gpio_105",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_TX_IRTX, 104,
+ "uart3_tx_irtx", "uart3_cts_rctx", NULL, "gpio_104",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_DAT, 112,
+ "usb0_dat", "uart3_rx_irrx", "uart2_rx", "gpio_112",
+ "uart2_tx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_PUEN, 106,
+ "usb0_puen", "mcbsp2_dx", NULL, "gpio_106",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_RCV, 109,
+ "usb0_rcv", "mcbsp2_fsx", NULL, "gpio_109",
+ "uart2_cts", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_SE0, 111,
+ "usb0_se0", "uart3_tx_irtx", "uart2_tx", "gpio_111",
+ "uart2_rx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_TXEN, 110,
+ "usb0_txen", "uart3_cts_rctx", "uart2_cts", "gpio_110",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_VM, 108,
+ "usb0_vm", "mcbsp2_clkx", NULL, "gpio_108",
+ "uart2_rx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_VP, 107,
+ "usb0_vp", "mcbsp2_dr", NULL, "gpio_107",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_CLK, 13,
+ "vlynq_clk", "usb2_se0", "sys_ndmareq0", "gpio_13",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_NLA, 58,
+ "vlynq_nla", NULL, NULL, "gpio_58",
+ "cam_d6", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_RX0, 15,
+ "vlynq_rx0", "usb2_tllse0", NULL, "gpio_15",
+ "cam_d7", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_RX1, 14,
+ "vlynq_rx1", "usb2_rcv", "sys_ndmareq1", "gpio_14",
+ "cam_d8", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_TX0, 17,
+ "vlynq_tx0", "usb2_txen", NULL, "gpio_17",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_TX1, 16,
+ "vlynq_tx1", "usb2_dat", "sys_clkout2", "gpio_16",
+ NULL, NULL, NULL, NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 447-pin POP package
+ */
+#ifdef CONFIG_DEBUG_FS
+static struct omap_ball __initdata omap2420_pop_ball[] = {
+ _OMAP2420_BALLENTRY(CAM_D0, "y4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D1, "y3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D2, "u7", NULL),
+ _OMAP2420_BALLENTRY(CAM_D3, "ab3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D4, "v2", NULL),
+ _OMAP2420_BALLENTRY(CAM_D5, "ad3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D6, "aa4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D7, "ab4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D8, "ac6", NULL),
+ _OMAP2420_BALLENTRY(CAM_D9, "ac7", NULL),
+ _OMAP2420_BALLENTRY(CAM_HS, "v4", NULL),
+ _OMAP2420_BALLENTRY(CAM_LCLK, "ad6", NULL),
+ _OMAP2420_BALLENTRY(CAM_VS, "p7", NULL),
+ _OMAP2420_BALLENTRY(CAM_XCLK, "w4", NULL),
+ _OMAP2420_BALLENTRY(DSS_ACBIAS, "ae8", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA10, "ac12", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA11, "ae11", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA12, "ae13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA13, "ad13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA14, "ac13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA15, "y12", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA16, "ad14", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA17, "y13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA8, "ad11", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA9, "ad12", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_DIN, "ad19", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_DOUT, "af22", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_FS, "ad16", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_MCLK, "y17", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_RST, "ae22", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_SCLK, "ac18", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_DIN, "u8", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_DOUT, "ad5", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_FS, "w7", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_SCLK, "ad4", NULL),
+ _OMAP2420_BALLENTRY(GPIO_119, "af6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_120, "af4", NULL),
+ _OMAP2420_BALLENTRY(GPIO_121, "ae6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_122, "w3", NULL),
+ _OMAP2420_BALLENTRY(GPIO_124, "y19", NULL),
+ _OMAP2420_BALLENTRY(GPIO_125, "ae24", NULL),
+ _OMAP2420_BALLENTRY(GPIO_36, "y18", NULL),
+ _OMAP2420_BALLENTRY(GPIO_6, "d6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_62, "ad18", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A1, "m8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A10, "d5", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A2, "w9", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A3, "af10", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A4, "w8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A5, "ae16", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A6, "af9", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A7, "e4", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A8, "j7", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A9, "ae18", NULL),
+ _OMAP2420_BALLENTRY(GPMC_CLK, "p1", "l1"),
+ _OMAP2420_BALLENTRY(GPMC_D10, "t1", "n1"),
+ _OMAP2420_BALLENTRY(GPMC_D11, "u2", "p2"),
+ _OMAP2420_BALLENTRY(GPMC_D12, "u1", "p1"),
+ _OMAP2420_BALLENTRY(GPMC_D13, "p2", "m1"),
+ _OMAP2420_BALLENTRY(GPMC_D14, "h2", "j2"),
+ _OMAP2420_BALLENTRY(GPMC_D15, "h1", "k2"),
+ _OMAP2420_BALLENTRY(GPMC_D8, "v1", "r1"),
+ _OMAP2420_BALLENTRY(GPMC_D9, "y1", "t1"),
+ _OMAP2420_BALLENTRY(GPMC_NBE0, "af12", "aa10"),
+ _OMAP2420_BALLENTRY(GPMC_NBE1, "u3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS1, "af14", "w1"),
+ _OMAP2420_BALLENTRY(GPMC_NCS2, "g4", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS3, "t8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS4, "h8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS5, "k3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS6, "m7", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS7, "p3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NWP, "ae15", "y5"),
+ _OMAP2420_BALLENTRY(GPMC_WAIT1, "ae20", "y8"),
+ _OMAP2420_BALLENTRY(GPMC_WAIT2, "n2", NULL),
+ _OMAP2420_BALLENTRY(GPMC_WAIT3, "t4", NULL),
+ _OMAP2420_BALLENTRY(HDQ_SIO, "t23", NULL),
+ _OMAP2420_BALLENTRY(I2C2_SCL, "l2", NULL),
+ _OMAP2420_BALLENTRY(I2C2_SDA, "k19", NULL),
+ _OMAP2420_BALLENTRY(JTAG_EMU0, "n24", NULL),
+ _OMAP2420_BALLENTRY(JTAG_EMU1, "ac22", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_CLKR, "y24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_CLKX, "t19", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_DR, "u23", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_DX, "r24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_FSR, "r20", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_FSX, "r23", NULL),
+ _OMAP2420_BALLENTRY(MCBSP2_CLKX, "t24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP2_DR, "p20", NULL),
+ _OMAP2420_BALLENTRY(MCBSP_CLKS, "p23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CLKI, "c23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CLKO, "h23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CMD, "j23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CMD_DIR, "j24", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT0, "h17", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR0, "f23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT1, "g19", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR1, "d23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT2, "h20", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR2, "g23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT3, "d24", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR3, "e23", NULL),
+ _OMAP2420_BALLENTRY(SDRC_A12, "w26", "r21"),
+ _OMAP2420_BALLENTRY(SDRC_A13, "w25", "aa15"),
+ _OMAP2420_BALLENTRY(SDRC_A14, "aa26", "y12"),
+ _OMAP2420_BALLENTRY(SDRC_CKE1, "ae25", "y13"),
+ _OMAP2420_BALLENTRY(SDRC_NCS1, "y25", "t20"),
+ _OMAP2420_BALLENTRY(SPI1_CLK, "y23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS0, "w24", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS1, "w23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS2, "v23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS3, "u20", NULL),
+ _OMAP2420_BALLENTRY(SPI1_SIMO, "h10", NULL),
+ _OMAP2420_BALLENTRY(SPI1_SOMI, "v19", NULL),
+ _OMAP2420_BALLENTRY(SPI2_CLK, "v24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_NCS0, "aa24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_SIMO, "u24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_SOMI, "v25", NULL),
+ _OMAP2420_BALLENTRY(SSI1_DAT_RX, "w15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_DAT_TX, "w13", NULL),
+ _OMAP2420_BALLENTRY(SSI1_FLAG_RX, "af11", NULL),
+ _OMAP2420_BALLENTRY(SSI1_FLAG_TX, "ac15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_RDY_RX, "ac16", NULL),
+ _OMAP2420_BALLENTRY(SSI1_RDY_TX, "af15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_WAKE, "ad15", NULL),
+ _OMAP2420_BALLENTRY(SYS_CLKOUT, "ae19", NULL),
+ _OMAP2420_BALLENTRY(SYS_CLKREQ, "ad20", NULL),
+ _OMAP2420_BALLENTRY(SYS_NIRQ, "y20", NULL),
+ _OMAP2420_BALLENTRY(UART1_CTS, "g20", NULL),
+ _OMAP2420_BALLENTRY(UART1_RTS, "k20", NULL),
+ _OMAP2420_BALLENTRY(UART1_RX, "t20", NULL),
+ _OMAP2420_BALLENTRY(UART1_TX, "h12", NULL),
+ _OMAP2420_BALLENTRY(UART2_CTS, "ac24", NULL),
+ _OMAP2420_BALLENTRY(UART2_RTS, "w20", NULL),
+ _OMAP2420_BALLENTRY(UART2_RX, "ad24", NULL),
+ _OMAP2420_BALLENTRY(UART2_TX, "ab24", NULL),
+ _OMAP2420_BALLENTRY(UART3_CTS_RCTX, "k24", NULL),
+ _OMAP2420_BALLENTRY(UART3_RTS_SD, "m20", NULL),
+ _OMAP2420_BALLENTRY(UART3_RX_IRRX, "h24", NULL),
+ _OMAP2420_BALLENTRY(UART3_TX_IRTX, "g24", NULL),
+ _OMAP2420_BALLENTRY(USB0_DAT, "j25", NULL),
+ _OMAP2420_BALLENTRY(USB0_PUEN, "l23", NULL),
+ _OMAP2420_BALLENTRY(USB0_RCV, "k23", NULL),
+ _OMAP2420_BALLENTRY(USB0_SE0, "l24", NULL),
+ _OMAP2420_BALLENTRY(USB0_TXEN, "m24", NULL),
+ _OMAP2420_BALLENTRY(USB0_VM, "n23", NULL),
+ _OMAP2420_BALLENTRY(USB0_VP, "m23", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_CLK, "w12", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_NLA, "ae10", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_RX0, "ad7", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_RX1, "w10", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_TX0, "y15", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_TX1, "w14", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap2420_pop_ball NULL
+#endif
+
+int __init omap2420_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_ball *package_balls = NULL;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_ZAC:
+ package_balls = omap2420_pop_ball;
+ break;
+ case OMAP_PACKAGE_ZAF:
+ /* REVISIT: Please add data */
+ default:
+ pr_warning("%s: No ball data available for omap2420 package\n",
+ __func__);
+ }
+
+ return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
+ OMAP2420_CONTROL_PADCONF_MUX_PBASE,
+ OMAP2420_CONTROL_PADCONF_MUX_SIZE,
+ omap2420_muxmodes, NULL, board_subset,
+ package_balls);
+}
diff --git a/arch/arm/mach-omap2/mux2420.h b/arch/arm/mach-omap2/mux2420.h
new file mode 100644
index 00000000..0f555aa8
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2420.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP2420_CONTROL_PADCONF_MUX_PBASE 0x48000030LU
+
+#define OMAP2420_MUX(mode0, mux_value) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##mode0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/*
+ * OMAP2420 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM. Add 0x48000030 to these values to get the
+ * absolute addresses. The name in the macro is the mode-0 name of
+ * the pin. NOTE: These registers are 8-bits wide.
+ */
+#define OMAP2420_CONTROL_PADCONF_SDRC_A14_OFFSET 0x000
+#define OMAP2420_CONTROL_PADCONF_SDRC_A13_OFFSET 0x001
+#define OMAP2420_CONTROL_PADCONF_SDRC_A12_OFFSET 0x002
+#define OMAP2420_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x003
+#define OMAP2420_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x004
+#define OMAP2420_CONTROL_PADCONF_SDRC_A11_OFFSET 0x005
+#define OMAP2420_CONTROL_PADCONF_SDRC_A10_OFFSET 0x006
+#define OMAP2420_CONTROL_PADCONF_SDRC_A9_OFFSET 0x007
+#define OMAP2420_CONTROL_PADCONF_SDRC_A8_OFFSET 0x008
+#define OMAP2420_CONTROL_PADCONF_SDRC_A7_OFFSET 0x009
+#define OMAP2420_CONTROL_PADCONF_SDRC_A6_OFFSET 0x00a
+#define OMAP2420_CONTROL_PADCONF_SDRC_A5_OFFSET 0x00b
+#define OMAP2420_CONTROL_PADCONF_SDRC_A4_OFFSET 0x00c
+#define OMAP2420_CONTROL_PADCONF_SDRC_A3_OFFSET 0x00d
+#define OMAP2420_CONTROL_PADCONF_SDRC_A2_OFFSET 0x00e
+#define OMAP2420_CONTROL_PADCONF_SDRC_A1_OFFSET 0x00f
+#define OMAP2420_CONTROL_PADCONF_SDRC_A0_OFFSET 0x010
+#define OMAP2420_CONTROL_PADCONF_SDRC_D31_OFFSET 0x021
+#define OMAP2420_CONTROL_PADCONF_SDRC_D30_OFFSET 0x022
+#define OMAP2420_CONTROL_PADCONF_SDRC_D29_OFFSET 0x023
+#define OMAP2420_CONTROL_PADCONF_SDRC_D28_OFFSET 0x024
+#define OMAP2420_CONTROL_PADCONF_SDRC_D27_OFFSET 0x025
+#define OMAP2420_CONTROL_PADCONF_SDRC_D26_OFFSET 0x026
+#define OMAP2420_CONTROL_PADCONF_SDRC_D25_OFFSET 0x027
+#define OMAP2420_CONTROL_PADCONF_SDRC_D24_OFFSET 0x028
+#define OMAP2420_CONTROL_PADCONF_SDRC_D23_OFFSET 0x029
+#define OMAP2420_CONTROL_PADCONF_SDRC_D22_OFFSET 0x02a
+#define OMAP2420_CONTROL_PADCONF_SDRC_D21_OFFSET 0x02b
+#define OMAP2420_CONTROL_PADCONF_SDRC_D20_OFFSET 0x02c
+#define OMAP2420_CONTROL_PADCONF_SDRC_D19_OFFSET 0x02d
+#define OMAP2420_CONTROL_PADCONF_SDRC_D18_OFFSET 0x02e
+#define OMAP2420_CONTROL_PADCONF_SDRC_D17_OFFSET 0x02f
+#define OMAP2420_CONTROL_PADCONF_SDRC_D16_OFFSET 0x030
+#define OMAP2420_CONTROL_PADCONF_SDRC_D15_OFFSET 0x031
+#define OMAP2420_CONTROL_PADCONF_SDRC_D14_OFFSET 0x032
+#define OMAP2420_CONTROL_PADCONF_SDRC_D13_OFFSET 0x033
+#define OMAP2420_CONTROL_PADCONF_SDRC_D12_OFFSET 0x034
+#define OMAP2420_CONTROL_PADCONF_SDRC_D11_OFFSET 0x035
+#define OMAP2420_CONTROL_PADCONF_SDRC_D10_OFFSET 0x036
+#define OMAP2420_CONTROL_PADCONF_SDRC_D9_OFFSET 0x037
+#define OMAP2420_CONTROL_PADCONF_SDRC_D8_OFFSET 0x038
+#define OMAP2420_CONTROL_PADCONF_SDRC_D7_OFFSET 0x039
+#define OMAP2420_CONTROL_PADCONF_SDRC_D6_OFFSET 0x03a
+#define OMAP2420_CONTROL_PADCONF_SDRC_D5_OFFSET 0x03b
+#define OMAP2420_CONTROL_PADCONF_SDRC_D4_OFFSET 0x03c
+#define OMAP2420_CONTROL_PADCONF_SDRC_D3_OFFSET 0x03d
+#define OMAP2420_CONTROL_PADCONF_SDRC_D2_OFFSET 0x03e
+#define OMAP2420_CONTROL_PADCONF_SDRC_D1_OFFSET 0x03f
+#define OMAP2420_CONTROL_PADCONF_SDRC_D0_OFFSET 0x040
+#define OMAP2420_CONTROL_PADCONF_GPMC_A10_OFFSET 0x041
+#define OMAP2420_CONTROL_PADCONF_GPMC_A9_OFFSET 0x042
+#define OMAP2420_CONTROL_PADCONF_GPMC_A8_OFFSET 0x043
+#define OMAP2420_CONTROL_PADCONF_GPMC_A7_OFFSET 0x044
+#define OMAP2420_CONTROL_PADCONF_GPMC_A6_OFFSET 0x045
+#define OMAP2420_CONTROL_PADCONF_GPMC_A5_OFFSET 0x046
+#define OMAP2420_CONTROL_PADCONF_GPMC_A4_OFFSET 0x047
+#define OMAP2420_CONTROL_PADCONF_GPMC_A3_OFFSET 0x048
+#define OMAP2420_CONTROL_PADCONF_GPMC_A2_OFFSET 0x049
+#define OMAP2420_CONTROL_PADCONF_GPMC_A1_OFFSET 0x04a
+#define OMAP2420_CONTROL_PADCONF_GPMC_D15_OFFSET 0x04b
+#define OMAP2420_CONTROL_PADCONF_GPMC_D14_OFFSET 0x04c
+#define OMAP2420_CONTROL_PADCONF_GPMC_D13_OFFSET 0x04d
+#define OMAP2420_CONTROL_PADCONF_GPMC_D12_OFFSET 0x04e
+#define OMAP2420_CONTROL_PADCONF_GPMC_D11_OFFSET 0x04f
+#define OMAP2420_CONTROL_PADCONF_GPMC_D10_OFFSET 0x050
+#define OMAP2420_CONTROL_PADCONF_GPMC_D9_OFFSET 0x051
+#define OMAP2420_CONTROL_PADCONF_GPMC_D8_OFFSET 0x052
+#define OMAP2420_CONTROL_PADCONF_GPMC_D7_OFFSET 0x053
+#define OMAP2420_CONTROL_PADCONF_GPMC_D6_OFFSET 0x054
+#define OMAP2420_CONTROL_PADCONF_GPMC_D5_OFFSET 0x055
+#define OMAP2420_CONTROL_PADCONF_GPMC_D4_OFFSET 0x056
+#define OMAP2420_CONTROL_PADCONF_GPMC_D3_OFFSET 0x057
+#define OMAP2420_CONTROL_PADCONF_GPMC_D2_OFFSET 0x058
+#define OMAP2420_CONTROL_PADCONF_GPMC_D1_OFFSET 0x059
+#define OMAP2420_CONTROL_PADCONF_GPMC_D0_OFFSET 0x05a
+#define OMAP2420_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x05b
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x05c
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x05d
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x05e
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x05f
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x060
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x061
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x062
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x063
+#define OMAP2420_CONTROL_PADCONF_GPMC_NALE_ALE_OFFSET 0x064
+#define OMAP2420_CONTROL_PADCONF_GPMC_NOE_OFFSET 0x065
+#define OMAP2420_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x066
+#define OMAP2420_CONTROL_PADCONF_GPMC_NBE0_OFFSET 0x067
+#define OMAP2420_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x068
+#define OMAP2420_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x069
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x06a
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x06b
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x06c
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x06d
+#define OMAP2420_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x06e
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x06f
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x070
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x071
+#define OMAP2420_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x072
+#define OMAP2420_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x073
+#define OMAP2420_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x074
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x075
+#define OMAP2420_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x076
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x077
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x078
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x079
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x07a
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x07f
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x080
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x081
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x082
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x083
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x084
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x085
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x086
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x087
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x088
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x089
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x08a
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x08b
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x08c
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x08d
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x08e
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x08f
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x090
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x091
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x092
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x093
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x094
+#define OMAP2420_CONTROL_PADCONF_UART1_CTS_OFFSET 0x095
+#define OMAP2420_CONTROL_PADCONF_UART1_RTS_OFFSET 0x096
+#define OMAP2420_CONTROL_PADCONF_UART1_TX_OFFSET 0x097
+#define OMAP2420_CONTROL_PADCONF_UART1_RX_OFFSET 0x098
+#define OMAP2420_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x099
+#define OMAP2420_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x09a
+#define OMAP2420_CONTROL_PADCONF_DSS_PCL_OFFSET 0x09b
+#define OMAP2420_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x09c
+#define OMAP2420_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x09d
+#define OMAP2420_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x09e
+#define OMAP2420_CONTROL_PADCONF_CAM_D9_OFFSET 0x09f
+#define OMAP2420_CONTROL_PADCONF_CAM_D8_OFFSET 0x0a0
+#define OMAP2420_CONTROL_PADCONF_CAM_D7_OFFSET 0x0a1
+#define OMAP2420_CONTROL_PADCONF_CAM_D6_OFFSET 0x0a2
+#define OMAP2420_CONTROL_PADCONF_CAM_D5_OFFSET 0x0a3
+#define OMAP2420_CONTROL_PADCONF_CAM_D4_OFFSET 0x0a4
+#define OMAP2420_CONTROL_PADCONF_CAM_D3_OFFSET 0x0a5
+#define OMAP2420_CONTROL_PADCONF_CAM_D2_OFFSET 0x0a6
+#define OMAP2420_CONTROL_PADCONF_CAM_D1_OFFSET 0x0a7
+#define OMAP2420_CONTROL_PADCONF_CAM_D0_OFFSET 0x0a8
+#define OMAP2420_CONTROL_PADCONF_CAM_HS_OFFSET 0x0a9
+#define OMAP2420_CONTROL_PADCONF_CAM_VS_OFFSET 0x0aa
+#define OMAP2420_CONTROL_PADCONF_CAM_LCLK_OFFSET 0x0ab
+#define OMAP2420_CONTROL_PADCONF_CAM_XCLK_OFFSET 0x0ac
+#define OMAP2420_CONTROL_PADCONF_SSI1_DAT_TX_OFFSET 0x0ad
+#define OMAP2420_CONTROL_PADCONF_SSI1_FLAG_TX_OFFSET 0x0ae
+#define OMAP2420_CONTROL_PADCONF_SSI1_RDY_TX_OFFSET 0x0af
+#define OMAP2420_CONTROL_PADCONF_GPIO_62_OFFSET 0x0b0
+#define OMAP2420_CONTROL_PADCONF_SSI1_DAT_RX_OFFSET 0x0b1
+#define OMAP2420_CONTROL_PADCONF_SSI1_FLAG_RX_OFFSET 0x0b2
+#define OMAP2420_CONTROL_PADCONF_SSI1_RDY_RX_OFFSET 0x0b3
+#define OMAP2420_CONTROL_PADCONF_SSI1_WAKE_OFFSET 0x0b4
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_CLK_OFFSET 0x0b5
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_RX1_OFFSET 0x0b6
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_RX0_OFFSET 0x0b7
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_TX1_OFFSET 0x0b8
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_TX0_OFFSET 0x0b9
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_NLA_OFFSET 0x0ba
+#define OMAP2420_CONTROL_PADCONF_UART2_CTS_OFFSET 0x0bb
+#define OMAP2420_CONTROL_PADCONF_UART2_RTS_OFFSET 0x0bc
+#define OMAP2420_CONTROL_PADCONF_UART2_TX_OFFSET 0x0bd
+#define OMAP2420_CONTROL_PADCONF_UART2_RX_OFFSET 0x0be
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_SCLK_OFFSET 0x0bf
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_FS_OFFSET 0x0c0
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_DIN_OFFSET 0x0c1
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_DOUT_OFFSET 0x0c2
+#define OMAP2420_CONTROL_PADCONF_MMC_CLKO_OFFSET 0x0c3
+#define OMAP2420_CONTROL_PADCONF_MMC_CMD_OFFSET 0x0c4
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT0_OFFSET 0x0c5
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT1_OFFSET 0x0c6
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT2_OFFSET 0x0c7
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT3_OFFSET 0x0c8
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR0_OFFSET 0x0c9
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR1_OFFSET 0x0ca
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR2_OFFSET 0x0cb
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR3_OFFSET 0x0cc
+#define OMAP2420_CONTROL_PADCONF_MMC_CMD_DIR_OFFSET 0x0cd
+#define OMAP2420_CONTROL_PADCONF_MMC_CLKI_OFFSET 0x0ce
+#define OMAP2420_CONTROL_PADCONF_SPI1_CLK_OFFSET 0x0cf
+#define OMAP2420_CONTROL_PADCONF_SPI1_SIMO_OFFSET 0x0d0
+#define OMAP2420_CONTROL_PADCONF_SPI1_SOMI_OFFSET 0x0d1
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS0_OFFSET 0x0d2
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS1_OFFSET 0x0d3
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS2_OFFSET 0x0d4
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS3_OFFSET 0x0d5
+#define OMAP2420_CONTROL_PADCONF_SPI2_CLK_OFFSET 0x0d6
+#define OMAP2420_CONTROL_PADCONF_SPI2_SIMO_OFFSET 0x0d7
+#define OMAP2420_CONTROL_PADCONF_SPI2_SOMI_OFFSET 0x0d8
+#define OMAP2420_CONTROL_PADCONF_SPI2_NCS0_OFFSET 0x0d9
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x0da
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x0db
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x0dc
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x0dd
+#define OMAP2420_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x0de
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x0df
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x0e0
+#define OMAP2420_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x0e1
+#define OMAP2420_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x0e2
+#define OMAP2420_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x0e3
+#define OMAP2420_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x0e4
+#define OMAP2420_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x0e5
+#define OMAP2420_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x0e6
+#define OMAP2420_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x0e7
+#define OMAP2420_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x0e8
+#define OMAP2420_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x0e9
+#define OMAP2420_CONTROL_PADCONF_TV_CVBS_OFFSET 0x0ea
+#define OMAP2420_CONTROL_PADCONF_TV_VREF_OFFSET 0x0eb
+#define OMAP2420_CONTROL_PADCONF_TV_RREF_OFFSET 0x0ec
+#define OMAP2420_CONTROL_PADCONF_USB0_PUEN_OFFSET 0x0ed
+#define OMAP2420_CONTROL_PADCONF_USB0_VP_OFFSET 0x0ee
+#define OMAP2420_CONTROL_PADCONF_USB0_VM_OFFSET 0x0ef
+#define OMAP2420_CONTROL_PADCONF_USB0_RCV_OFFSET 0x0f0
+#define OMAP2420_CONTROL_PADCONF_USB0_TXEN_OFFSET 0x0f1
+#define OMAP2420_CONTROL_PADCONF_USB0_SE0_OFFSET 0x0f2
+#define OMAP2420_CONTROL_PADCONF_USB0_DAT_OFFSET 0x0f3
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_SCLK_OFFSET 0x0f4
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_FS_OFFSET 0x0f5
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_DIN_OFFSET 0x0f6
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_DOUT_OFFSET 0x0f7
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_MCLK_OFFSET 0x0f8
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_RST_OFFSET 0x0f9
+#define OMAP2420_CONTROL_PADCONF_SYS_NRESPWRON_OFFSET 0x0fa
+#define OMAP2420_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x0fb
+#define OMAP2420_CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x0fc
+#define OMAP2420_CONTROL_PADCONF_SYS_NV_OFFSET 0x0fd
+#define OMAP2420_CONTROL_PADCONF_GPIO_119_OFFSET 0x0fe
+#define OMAP2420_CONTROL_PADCONF_GPIO_120_OFFSET 0x0ff
+#define OMAP2420_CONTROL_PADCONF_GPIO_121_OFFSET 0x100
+#define OMAP2420_CONTROL_PADCONF_GPIO_122_OFFSET 0x101
+#define OMAP2420_CONTROL_PADCONF_SYS_32K_OFFSET 0x102
+#define OMAP2420_CONTROL_PADCONF_SYS_XTALIN_OFFSET 0x103
+#define OMAP2420_CONTROL_PADCONF_SYS_XTALOUT_OFFSET 0x104
+#define OMAP2420_CONTROL_PADCONF_GPIO_36_OFFSET 0x105
+#define OMAP2420_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x106
+#define OMAP2420_CONTROL_PADCONF_SYS_CLKOUT_OFFSET 0x107
+#define OMAP2420_CONTROL_PADCONF_GPIO_6_OFFSET 0x108
+#define OMAP2420_CONTROL_PADCONF_GPIO_124_OFFSET 0x109
+#define OMAP2420_CONTROL_PADCONF_GPIO_125_OFFSET 0x10a
+#define OMAP2420_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x10b
+#define OMAP2420_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x10c
+#define OMAP2420_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x10d
+#define OMAP2420_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x10e
+#define OMAP2420_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0x10f
+#define OMAP2420_CONTROL_PADCONF_JTAG_TMS_OFFSET 0x110
+#define OMAP2420_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x111
+#define OMAP2420_CONTROL_PADCONF_JTAG_TDO_OFFSET 0x112
+
+#define OMAP2420_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP2420_CONTROL_PADCONF_JTAG_TDO_OFFSET + 0x1)
diff --git a/arch/arm/mach-omap2/mux2430.c b/arch/arm/mach-omap2/mux2430.c
new file mode 100644
index 00000000..4185f925
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2430.c
@@ -0,0 +1,793 @@
+/*
+ * Copyright (C) 2010 Nokia
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can 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/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP2430_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP2430_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP2430_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap2430
+ */
+static struct omap_mux __initdata omap2430_muxmodes[] = {
+ _OMAP2430_MUXENTRY(CAM_D0, 133,
+ "cam_d0", "hw_dbg0", "sti_dout", "gpio_133",
+ NULL, NULL, "etk_d2", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D10, 146,
+ "cam_d10", NULL, NULL, "gpio_146",
+ NULL, NULL, "etk_d12", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D11, 145,
+ "cam_d11", NULL, NULL, "gpio_145",
+ NULL, NULL, "etk_d13", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D1, 132,
+ "cam_d1", "hw_dbg1", "sti_din", "gpio_132",
+ NULL, NULL, "etk_d3", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D2, 129,
+ "cam_d2", "hw_dbg2", "mcbsp1_clkx", "gpio_129",
+ NULL, NULL, "etk_d4", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D3, 128,
+ "cam_d3", "hw_dbg3", "mcbsp1_dr", "gpio_128",
+ NULL, NULL, "etk_d5", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D4, 143,
+ "cam_d4", "hw_dbg4", "mcbsp1_fsr", "gpio_143",
+ NULL, NULL, "etk_d6", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D5, 112,
+ "cam_d5", "hw_dbg5", "mcbsp1_clkr", "gpio_112",
+ NULL, NULL, "etk_d7", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D6, 137,
+ "cam_d6", "hw_dbg6", NULL, "gpio_137",
+ NULL, NULL, "etk_d8", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D7, 136,
+ "cam_d7", "hw_dbg7", NULL, "gpio_136",
+ NULL, NULL, "etk_d9", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D8, 135,
+ "cam_d8", "hw_dbg8", NULL, "gpio_135",
+ NULL, NULL, "etk_d10", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D9, 134,
+ "cam_d9", "hw_dbg9", NULL, "gpio_134",
+ NULL, NULL, "etk_d11", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_HS, 11,
+ "cam_hs", "hw_dbg10", "mcbsp1_dx", "gpio_11",
+ NULL, NULL, "etk_d1", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_LCLK, 0,
+ "cam_lclk", NULL, "mcbsp_clks", NULL,
+ NULL, NULL, "etk_c1", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_VS, 12,
+ "cam_vs", "hw_dbg11", "mcbsp1_fsx", "gpio_12",
+ NULL, NULL, "etk_d0", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_XCLK, 0,
+ "cam_xclk", NULL, "sti_clk", NULL,
+ NULL, NULL, "etk_c2", NULL),
+ _OMAP2430_MUXENTRY(DSS_ACBIAS, 48,
+ "dss_acbias", NULL, "mcbsp2_fsx", "gpio_48",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA0, 40,
+ "dss_data0", "uart1_cts", NULL, "gpio_40",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA10, 128,
+ "dss_data10", "sdi_data1n", NULL, "gpio_128",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA11, 129,
+ "dss_data11", "sdi_data1p", NULL, "gpio_129",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA12, 130,
+ "dss_data12", "sdi_data2n", NULL, "gpio_130",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA13, 131,
+ "dss_data13", "sdi_data2p", NULL, "gpio_131",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA14, 132,
+ "dss_data14", "sdi_data3n", NULL, "gpio_132",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA15, 133,
+ "dss_data15", "sdi_data3p", NULL, "gpio_133",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA16, 46,
+ "dss_data16", NULL, NULL, "gpio_46",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA17, 47,
+ "dss_data17", NULL, NULL, "gpio_47",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA1, 41,
+ "dss_data1", "uart1_rts", NULL, "gpio_41",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA2, 42,
+ "dss_data2", "uart1_tx", NULL, "gpio_42",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA3, 43,
+ "dss_data3", "uart1_rx", NULL, "gpio_43",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA4, 44,
+ "dss_data4", "uart3_rx_irrx", NULL, "gpio_44",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA5, 45,
+ "dss_data5", "uart3_tx_irtx", NULL, "gpio_45",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA6, 144,
+ "dss_data6", NULL, NULL, "gpio_144",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA7, 147,
+ "dss_data7", NULL, NULL, "gpio_147",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA8, 38,
+ "dss_data8", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA9, 39,
+ "dss_data9", NULL, NULL, "gpio_39",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_HSYNC, 110,
+ "dss_hsync", NULL, NULL, "gpio_110",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_113, 113,
+ "gpio_113", "mcbsp2_clkx", NULL, "gpio_113",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_114, 114,
+ "gpio_114", "mcbsp2_fsx", NULL, "gpio_114",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_115, 115,
+ "gpio_115", "mcbsp2_dr", NULL, "gpio_115",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_116, 116,
+ "gpio_116", "mcbsp2_dx", NULL, "gpio_116",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_128, 128,
+ "gpio_128", NULL, "sti_din", "gpio_128",
+ NULL, "sys_boot0", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_129, 129,
+ "gpio_129", NULL, "sti_dout", "gpio_129",
+ NULL, "sys_boot1", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_130, 130,
+ "gpio_130", NULL, NULL, "gpio_130",
+ "jtag_emu2", "sys_boot2", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_131, 131,
+ "gpio_131", NULL, NULL, "gpio_131",
+ "jtag_emu3", "sys_boot3", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_132, 132,
+ "gpio_132", NULL, NULL, "gpio_132",
+ NULL, "sys_boot4", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_133, 133,
+ "gpio_133", NULL, NULL, "gpio_133",
+ NULL, "sys_boot5", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_134, 134,
+ "gpio_134", "ccp_datn", NULL, "gpio_134",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_135, 135,
+ "gpio_135", "ccp_datp", NULL, "gpio_135",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_136, 136,
+ "gpio_136", "ccp_clkn", NULL, "gpio_136",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_137, 137,
+ "gpio_137", "ccp_clkp", NULL, "gpio_137",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_138, 138,
+ "gpio_138", "spi3_clk", NULL, "gpio_138",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_139, 139,
+ "gpio_139", "spi3_cs0", "sys_ndmareq3", "gpio_139",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_140, 140,
+ "gpio_140", "spi3_simo", "sys_ndmareq4", "gpio_140",
+ NULL, NULL, "etk_d14", "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_141, 141,
+ "gpio_141", "spi3_somi", NULL, "gpio_141",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_142, 142,
+ "gpio_142", "spi3_cs1", "sys_ndmareq2", "gpio_142",
+ NULL, NULL, "etk_d15", "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_148, 148,
+ "gpio_148", "mcbsp5_fsx", NULL, "gpio_148",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_149, 149,
+ "gpio_149", "mcbsp5_dx", NULL, "gpio_149",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_150, 150,
+ "gpio_150", "mcbsp5_dr", NULL, "gpio_150",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_151, 151,
+ "gpio_151", "sys_pwrok", NULL, "gpio_151",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_152, 152,
+ "gpio_152", "uart1_cts", "sys_ndmareq1", "gpio_152",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_153, 153,
+ "gpio_153", "uart1_rx", "sys_ndmareq0", "gpio_153",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_154, 154,
+ "gpio_154", "mcbsp5_clkx", NULL, "gpio_154",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_63, 63,
+ "gpio_63", "mcbsp4_clkx", NULL, "gpio_63",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_78, 78,
+ "gpio_78", NULL, "uart2_rts", "gpio_78",
+ "uart3_rts_sd", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_79, 79,
+ "gpio_79", "secure_indicator", "uart2_tx", "gpio_79",
+ "uart3_tx_irtx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_7, 7,
+ "gpio_7", NULL, "uart2_cts", "gpio_7",
+ "uart3_cts_rctx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_80, 80,
+ "gpio_80", NULL, "uart2_rx", "gpio_80",
+ "uart3_rx_irrx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A10, 3,
+ "gpmc_a10", NULL, "sys_ndmareq0", "gpio_3",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A1, 31,
+ "gpmc_a1", NULL, NULL, "gpio_31",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A2, 30,
+ "gpmc_a2", NULL, NULL, "gpio_30",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A3, 29,
+ "gpmc_a3", NULL, NULL, "gpio_29",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A4, 49,
+ "gpmc_a4", NULL, NULL, "gpio_49",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A5, 53,
+ "gpmc_a5", NULL, NULL, "gpio_53",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A6, 52,
+ "gpmc_a6", NULL, NULL, "gpio_52",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A7, 6,
+ "gpmc_a7", NULL, NULL, "gpio_6",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A8, 5,
+ "gpmc_a8", NULL, NULL, "gpio_5",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A9, 4,
+ "gpmc_a9", NULL, "sys_ndmareq1", "gpio_4",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_CLK, 21,
+ "gpmc_clk", NULL, NULL, "gpio_21",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D10, 18,
+ "gpmc_d10", NULL, NULL, "gpio_18",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D11, 57,
+ "gpmc_d11", NULL, NULL, "gpio_57",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D12, 77,
+ "gpmc_d12", NULL, NULL, "gpio_77",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D13, 76,
+ "gpmc_d13", NULL, NULL, "gpio_76",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D14, 55,
+ "gpmc_d14", NULL, NULL, "gpio_55",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D15, 54,
+ "gpmc_d15", NULL, NULL, "gpio_54",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D8, 20,
+ "gpmc_d8", NULL, NULL, "gpio_20",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D9, 19,
+ "gpmc_d9", NULL, NULL, "gpio_19",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS1, 22,
+ "gpmc_ncs1", NULL, NULL, "gpio_22",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS2, 23,
+ "gpmc_ncs2", NULL, NULL, "gpio_23",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS3, 24,
+ "gpmc_ncs3", "gpmc_io_dir", NULL, "gpio_24",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS4, 25,
+ "gpmc_ncs4", NULL, NULL, "gpio_25",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS5, 26,
+ "gpmc_ncs5", NULL, NULL, "gpio_26",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS6, 27,
+ "gpmc_ncs6", NULL, NULL, "gpio_27",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS7, 28,
+ "gpmc_ncs7", "gpmc_io_dir", NULL, "gpio_28",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT1, 33,
+ "gpmc_wait1", NULL, NULL, "gpio_33",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT2, 34,
+ "gpmc_wait2", NULL, NULL, "gpio_34",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT3, 35,
+ "gpmc_wait3", NULL, NULL, "gpio_35",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(HDQ_SIO, 101,
+ "hdq_sio", "usb2_tllse0", "sys_altclk", "gpio_101",
+ "uart3_rx_irrx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C1_SCL, 50,
+ "i2c1_scl", NULL, NULL, "gpio_50",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C1_SDA, 51,
+ "i2c1_sda", NULL, NULL, "gpio_51",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C2_SCL, 99,
+ "i2c2_scl", NULL, NULL, "gpio_99",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C2_SDA, 100,
+ "i2c2_sda", NULL, NULL, "gpio_100",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(JTAG_EMU0, 127,
+ "jtag_emu0", "secure_indicator", NULL, "gpio_127",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(JTAG_EMU1, 126,
+ "jtag_emu1", NULL, NULL, "gpio_126",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_CLKR, 92,
+ "mcbsp1_clkr", "ssi2_dat_tx", NULL, "gpio_92",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_CLKX, 98,
+ "mcbsp1_clkx", "ssi2_wake", NULL, "gpio_98",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_DR, 95,
+ "mcbsp1_dr", "ssi2_dat_rx", NULL, "gpio_95",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_DX, 94,
+ "mcbsp1_dx", "ssi2_rdy_tx", NULL, "gpio_94",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_FSR, 93,
+ "mcbsp1_fsr", "ssi2_flag_tx", NULL, "gpio_93",
+ "spi2_cs1", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_FSX, 97,
+ "mcbsp1_fsx", "ssi2_rdy_rx", NULL, "gpio_97",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP2_CLKX, 147,
+ "mcbsp2_clkx", "sdi_clkp", "dss_data23", "gpio_147",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP2_DR, 144,
+ "mcbsp2_dr", "sdi_clkn", "dss_data22", "gpio_144",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_CLKX, 71,
+ "mcbsp3_clkx", NULL, NULL, "gpio_71",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_DR, 73,
+ "mcbsp3_dr", NULL, NULL, "gpio_73",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_DX, 74,
+ "mcbsp3_dx", NULL, "sti_clk", "gpio_74",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_FSX, 72,
+ "mcbsp3_fsx", NULL, NULL, "gpio_72",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP_CLKS, 96,
+ "mcbsp_clks", "ssi2_flag_rx", NULL, "gpio_96",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_CLKO, 0,
+ "sdmmc1_clko", "ms_clko", NULL, NULL,
+ NULL, "hw_dbg9", "hw_dbg3", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_CMD, 0,
+ "sdmmc1_cmd", "ms_bs", NULL, NULL,
+ NULL, "hw_dbg8", "hw_dbg2", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT0, 0,
+ "sdmmc1_dat0", "ms_dat0", NULL, NULL,
+ NULL, "hw_dbg7", "hw_dbg1", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT1, 75,
+ "sdmmc1_dat1", "ms_dat1", NULL, "gpio_75",
+ NULL, "hw_dbg6", "hw_dbg0", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT2, 0,
+ "sdmmc1_dat2", "ms_dat2", NULL, NULL,
+ NULL, "hw_dbg5", "hw_dbg10", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT3, 0,
+ "sdmmc1_dat3", "ms_dat3", NULL, NULL,
+ NULL, "hw_dbg4", "hw_dbg11", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_CLKO, 13,
+ "sdmmc2_clko", NULL, NULL, "gpio_13",
+ NULL, "spi3_clk", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_CMD, 15,
+ "sdmmc2_cmd", "usb2_rcv", NULL, "gpio_15",
+ NULL, "spi3_simo", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT0, 16,
+ "sdmmc2_dat0", "usb2_tllse0", NULL, "gpio_16",
+ NULL, "spi3_somi", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT1, 58,
+ "sdmmc2_dat1", "usb2_txen", NULL, "gpio_58",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT2, 17,
+ "sdmmc2_dat2", "usb2_dat", NULL, "gpio_17",
+ NULL, "spi3_cs1", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT3, 14,
+ "sdmmc2_dat3", "usb2_se0", NULL, "gpio_14",
+ NULL, "spi3_cs0", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A12, 2,
+ "sdrc_a12", NULL, NULL, "gpio_2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A13, 1,
+ "sdrc_a13", NULL, NULL, "gpio_1",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A14, 0,
+ "sdrc_a14", NULL, NULL, "gpio_0",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_CKE1, 36,
+ "sdrc_cke1", NULL, NULL, "gpio_36",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_NCS1, 37,
+ "sdrc_ncs1", NULL, NULL, "gpio_37",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CLK, 81,
+ "spi1_clk", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS0, 84,
+ "spi1_cs0", NULL, NULL, "gpio_84",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS1, 85,
+ "spi1_cs1", NULL, NULL, "gpio_85",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS2, 86,
+ "spi1_cs2", NULL, NULL, "gpio_86",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS3, 87,
+ "spi1_cs3", "spi2_cs1", NULL, "gpio_87",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_SIMO, 82,
+ "spi1_simo", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_SOMI, 83,
+ "spi1_somi", NULL, NULL, "gpio_83",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_CLK, 88,
+ "spi2_clk", "gpt9_pwm_evt", NULL, "gpio_88",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_CS0, 91,
+ "spi2_cs0", "gpt12_pwm_evt", NULL, "gpio_91",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_SIMO, 89,
+ "spi2_simo", "gpt10_pwm_evt", NULL, "gpio_89",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_SOMI, 90,
+ "spi2_somi", "gpt11_pwm_evt", NULL, "gpio_90",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_DAT_RX, 62,
+ "ssi1_dat_rx", "uart1_rx", "usb1_dat", "gpio_62",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_DAT_TX, 59,
+ "ssi1_dat_tx", "uart1_tx", "usb1_se0", "gpio_59",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_FLAG_RX, 64,
+ "ssi1_flag_rx", "mcbsp4_dr", NULL, "gpio_64",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_FLAG_TX, 60,
+ "ssi1_flag_tx", "uart1_rts", "usb1_rcv", "gpio_60",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_RDY_RX, 65,
+ "ssi1_rdy_rx", "mcbsp4_dx", NULL, "gpio_65",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_RDY_TX, 61,
+ "ssi1_rdy_tx", "uart1_cts", "usb1_txen", "gpio_61",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_WAKE, 66,
+ "ssi1_wake", "mcbsp4_fsx", NULL, "gpio_66",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_CLKOUT, 111,
+ "sys_clkout", NULL, NULL, "gpio_111",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_DRM_MSECURE, 118,
+ "sys_drm_msecure", NULL, "sys_ndmareq6", "gpio_118",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_NIRQ0, 56,
+ "sys_nirq0", NULL, NULL, "gpio_56",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_NIRQ1, 125,
+ "sys_nirq1", NULL, "sys_ndmareq5", "gpio_125",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_CTS, 32,
+ "uart1_cts", "sdi_vsync", "dss_data18", "gpio_32",
+ "mcbsp5_clkx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_RTS, 8,
+ "uart1_rts", "sdi_hsync", "dss_data19", "gpio_8",
+ "mcbsp5_fsx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_RX, 10,
+ "uart1_rx", "sdi_stp", "dss_data21", "gpio_10",
+ "mcbsp5_dr", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_TX, 9,
+ "uart1_tx", "sdi_den", "dss_data20", "gpio_9",
+ "mcbsp5_dx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_CTS, 67,
+ "uart2_cts", "usb1_rcv", "gpt9_pwm_evt", "gpio_67",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_RTS, 68,
+ "uart2_rts", "usb1_txen", "gpt10_pwm_evt", "gpio_68",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_RX, 70,
+ "uart2_rx", "usb1_dat", "gpt12_pwm_evt", "gpio_70",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_TX, 69,
+ "uart2_tx", "usb1_se0", "gpt11_pwm_evt", "gpio_69",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_CTS_RCTX, 102,
+ "uart3_cts_rctx", "uart3_rx_irrx", NULL, "gpio_102",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_RTS_SD, 103,
+ "uart3_rts_sd", "uart3_tx_irtx", NULL, "gpio_103",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_RX_IRRX, 105,
+ "uart3_rx_irrx", NULL, NULL, "gpio_105",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_TX_IRTX, 104,
+ "uart3_tx_irtx", "uart3_cts_rctx", NULL, "gpio_104",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_CLK, 120,
+ "usb0hs_clk", NULL, NULL, "gpio_120",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA0, 0,
+ "usb0hs_data0", "uart3_tx_irtx", NULL, NULL,
+ "usb0_txen", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA1, 0,
+ "usb0hs_data1", "uart3_rx_irrx", NULL, NULL,
+ "usb0_dat", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA2, 0,
+ "usb0hs_data2", "uart3_rts_sd", NULL, NULL,
+ "usb0_se0", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA3, 106,
+ "usb0hs_data3", NULL, "uart3_cts_rctx", "gpio_106",
+ "usb0_puen", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA4, 107,
+ "usb0hs_data4", "mcbsp2_dr", NULL, "gpio_107",
+ "usb0_vp", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA5, 108,
+ "usb0hs_data5", "mcbsp2_dx", NULL, "gpio_108",
+ "usb0_vm", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA6, 109,
+ "usb0hs_data6", "mcbsp2_fsx", NULL, "gpio_109",
+ "usb0_rcv", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA7, 124,
+ "usb0hs_data7", "mcbsp2_clkx", NULL, "gpio_124",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DIR, 121,
+ "usb0hs_dir", NULL, NULL, "gpio_121",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_NXT, 123,
+ "usb0hs_nxt", NULL, NULL, "gpio_123",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_STP, 122,
+ "usb0hs_stp", NULL, NULL, "gpio_122",
+ NULL, NULL, NULL, "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for POP package
+ * 447-pin s-PBGA Package, 0.00mm Ball Pitch (Bottom)
+ */
+#ifdef CONFIG_DEBUG_FS
+static struct omap_ball __initdata omap2430_pop_ball[] = {
+ _OMAP2430_BALLENTRY(CAM_D0, "t8", NULL),
+ _OMAP2430_BALLENTRY(CAM_D1, "t4", NULL),
+ _OMAP2430_BALLENTRY(CAM_D10, "r4", NULL),
+ _OMAP2430_BALLENTRY(CAM_D11, "w3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D2, "r2", NULL),
+ _OMAP2430_BALLENTRY(CAM_D3, "u3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D4, "u2", NULL),
+ _OMAP2430_BALLENTRY(CAM_D5, "v1", NULL),
+ _OMAP2430_BALLENTRY(CAM_D6, "t3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D7, "r3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D8, "u7", NULL),
+ _OMAP2430_BALLENTRY(CAM_D9, "t7", NULL),
+ _OMAP2430_BALLENTRY(CAM_HS, "p2", NULL),
+ _OMAP2430_BALLENTRY(CAM_LCLK, "r7", NULL),
+ _OMAP2430_BALLENTRY(CAM_VS, "n2", NULL),
+ _OMAP2430_BALLENTRY(CAM_XCLK, "p3", NULL),
+ _OMAP2430_BALLENTRY(DSS_ACBIAS, "y3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA0, "v8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA1, "w1", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA10, "k25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA11, "j25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA12, "k24", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA13, "j24", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA14, "h25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA15, "g25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA16, "ac3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA17, "y7", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA2, "u8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA3, "u4", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA4, "v3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA5, "aa4", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA6, "w8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA7, "y1", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA8, "aa2", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA9, "ab4", NULL),
+ _OMAP2430_BALLENTRY(DSS_HSYNC, "v2", NULL),
+ _OMAP2430_BALLENTRY(GPIO_113, "ad16", NULL),
+ _OMAP2430_BALLENTRY(GPIO_114, "ac10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_115, "ad13", NULL),
+ _OMAP2430_BALLENTRY(GPIO_116, "ae15", NULL),
+ _OMAP2430_BALLENTRY(GPIO_128, "p1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_129, "r1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_130, "p7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_131, "l8", NULL),
+ _OMAP2430_BALLENTRY(GPIO_132, "w24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_133, "aa24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_134, "ae12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_135, "ae11", NULL),
+ _OMAP2430_BALLENTRY(GPIO_136, "ad12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_137, "ad11", NULL),
+ _OMAP2430_BALLENTRY(GPIO_138, "y12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_139, "ad17", NULL),
+ _OMAP2430_BALLENTRY(GPIO_140, "l7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_141, "ac24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_142, "m3", NULL),
+ _OMAP2430_BALLENTRY(GPIO_148, "af12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_149, "k7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_150, "m1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_151, "ad14", NULL),
+ _OMAP2430_BALLENTRY(GPIO_152, "ad18", NULL),
+ _OMAP2430_BALLENTRY(GPIO_153, "u24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_154, "ae16", NULL),
+ _OMAP2430_BALLENTRY(GPIO_63, "n3", NULL),
+ _OMAP2430_BALLENTRY(GPIO_7, "ac23", NULL),
+ _OMAP2430_BALLENTRY(GPIO_78, "ad10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_79, "ae10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_80, "ae13", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A1, "a9", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A10, "g12", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A2, "b8", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A3, "g10", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A4, "g11", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A5, "a10", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A6, "g13", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A7, "a6", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A8, "h1", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A9, "c8", NULL),
+ _OMAP2430_BALLENTRY(GPMC_CLK, "n1", "l1"),
+ _OMAP2430_BALLENTRY(GPMC_D10, "d1", "n1"),
+ _OMAP2430_BALLENTRY(GPMC_D11, "d2", "p2"),
+ _OMAP2430_BALLENTRY(GPMC_D12, "e1", "p1"),
+ _OMAP2430_BALLENTRY(GPMC_D13, "e3", "m1"),
+ _OMAP2430_BALLENTRY(GPMC_D14, "c7", "j2"),
+ _OMAP2430_BALLENTRY(GPMC_D15, "f3", "k2"),
+ _OMAP2430_BALLENTRY(GPMC_D8, "e2", "r1"),
+ _OMAP2430_BALLENTRY(GPMC_D9, "ab1", "t1"),
+ _OMAP2430_BALLENTRY(GPMC_NCS1, "ac1", "w1"),
+ _OMAP2430_BALLENTRY(GPMC_NCS2, "c6", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS3, "b9", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS4, "b4", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS5, "a4", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS6, "f1", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS7, "a7", NULL),
+ _OMAP2430_BALLENTRY(GPMC_WAIT1, "j1", "y8"),
+ _OMAP2430_BALLENTRY(GPMC_WAIT2, "b7", NULL),
+ _OMAP2430_BALLENTRY(GPMC_WAIT3, "g14", NULL),
+ _OMAP2430_BALLENTRY(HDQ_SIO, "h20", NULL),
+ _OMAP2430_BALLENTRY(I2C1_SCL, "y17", NULL),
+ _OMAP2430_BALLENTRY(I2C1_SDA, "ac19", NULL),
+ _OMAP2430_BALLENTRY(I2C2_SCL, "n7", NULL),
+ _OMAP2430_BALLENTRY(I2C2_SDA, "m4", NULL),
+ _OMAP2430_BALLENTRY(JTAG_EMU0, "e25", NULL),
+ _OMAP2430_BALLENTRY(JTAG_EMU1, "e24", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_CLKR, "ab2", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_CLKX, "y9", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_DR, "af3", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_DX, "aa1", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_FSR, "ad5", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_FSX, "ab3", NULL),
+ _OMAP2430_BALLENTRY(MCBSP2_CLKX, "j26", NULL),
+ _OMAP2430_BALLENTRY(MCBSP2_DR, "k26", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_CLKX, "ac9", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_DR, "ae2", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_DX, "af4", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_FSX, "ae4", NULL),
+ _OMAP2430_BALLENTRY(MCBSP_CLKS, "ad6", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_CLKO, "n23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_CMD, "l23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT0, "m24", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT1, "p23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT2, "t20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT3, "r20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_CLKO, "v26", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_CMD, "w20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT0, "v23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT1, "y24", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT2, "v25", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT3, "v24", NULL),
+ _OMAP2430_BALLENTRY(SDRC_A12, "w26", "r21"),
+ _OMAP2430_BALLENTRY(SDRC_A13, "af20", "aa15"),
+ _OMAP2430_BALLENTRY(SDRC_A14, "af16", "y12"),
+ _OMAP2430_BALLENTRY(SDRC_CKE1, "af15", "y13"),
+ _OMAP2430_BALLENTRY(SDRC_NCS1, "aa25", "t20"),
+ _OMAP2430_BALLENTRY(SPI1_CLK, "y18", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS0, "u1", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS1, "af19", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS2, "ae19", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS3, "h24", NULL),
+ _OMAP2430_BALLENTRY(SPI1_SIMO, "ad15", NULL),
+ _OMAP2430_BALLENTRY(SPI1_SOMI, "ae17", NULL),
+ _OMAP2430_BALLENTRY(SPI2_CLK, "y20", NULL),
+ _OMAP2430_BALLENTRY(SPI2_CS0, "y19", NULL),
+ _OMAP2430_BALLENTRY(SPI2_SIMO, "ac20", NULL),
+ _OMAP2430_BALLENTRY(SPI2_SOMI, "ad19", NULL),
+ _OMAP2430_BALLENTRY(SSI1_DAT_RX, "aa26", NULL),
+ _OMAP2430_BALLENTRY(SSI1_DAT_TX, "ad24", NULL),
+ _OMAP2430_BALLENTRY(SSI1_FLAG_RX, "ad23", NULL),
+ _OMAP2430_BALLENTRY(SSI1_FLAG_TX, "ab24", NULL),
+ _OMAP2430_BALLENTRY(SSI1_RDY_RX, "ab25", NULL),
+ _OMAP2430_BALLENTRY(SSI1_RDY_TX, "y25", NULL),
+ _OMAP2430_BALLENTRY(SSI1_WAKE, "ac25", NULL),
+ _OMAP2430_BALLENTRY(SYS_CLKOUT, "r25", NULL),
+ _OMAP2430_BALLENTRY(SYS_DRM_MSECURE, "ae3", NULL),
+ _OMAP2430_BALLENTRY(SYS_NIRQ0, "w25", NULL),
+ _OMAP2430_BALLENTRY(SYS_NIRQ1, "ad21", NULL),
+ _OMAP2430_BALLENTRY(UART1_CTS, "p24", NULL),
+ _OMAP2430_BALLENTRY(UART1_RTS, "p25", NULL),
+ _OMAP2430_BALLENTRY(UART1_RX, "n24", NULL),
+ _OMAP2430_BALLENTRY(UART1_TX, "r24", NULL),
+ _OMAP2430_BALLENTRY(UART2_CTS, "u25", NULL),
+ _OMAP2430_BALLENTRY(UART2_RTS, "t23", NULL),
+ _OMAP2430_BALLENTRY(UART2_RX, "t24", NULL),
+ _OMAP2430_BALLENTRY(UART2_TX, "u20", NULL),
+ _OMAP2430_BALLENTRY(UART3_CTS_RCTX, "m2", NULL),
+ _OMAP2430_BALLENTRY(UART3_RTS_SD, "k2", NULL),
+ _OMAP2430_BALLENTRY(UART3_RX_IRRX, "l3", NULL),
+ _OMAP2430_BALLENTRY(UART3_TX_IRTX, "l2", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_CLK, "ae8", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA0, "ad4", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA1, "ae6", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA2, "af9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA3, "ad9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA4, "y11", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA5, "ad7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA6, "ae7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA7, "ac7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DIR, "ad8", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_NXT, "ae9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_STP, "ae5", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap2430_pop_ball NULL
+#endif
+
+int __init omap2430_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_ball *package_balls = NULL;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_ZAC:
+ package_balls = omap2430_pop_ball;
+ break;
+ default:
+ pr_warning("%s: No ball data available for omap2420 package\n",
+ __func__);
+ }
+
+ return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
+ OMAP2430_CONTROL_PADCONF_MUX_PBASE,
+ OMAP2430_CONTROL_PADCONF_MUX_SIZE,
+ omap2430_muxmodes, NULL, board_subset,
+ package_balls);
+}
diff --git a/arch/arm/mach-omap2/mux2430.h b/arch/arm/mach-omap2/mux2430.h
new file mode 100644
index 00000000..9fd93149
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2430.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP2430_CONTROL_PADCONF_MUX_PBASE 0x49002030LU
+
+#define OMAP2430_MUX(mode0, mux_value) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##mode0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/*
+ * OMAP2430 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM. Add 0x49002030 to these values to get the
+ * absolute addresses. The name in the macro is the mode-0 name of
+ * the pin. NOTE: These registers are 8-bits wide.
+ *
+ * Note that these defines use SDMMC instead of MMC for compatibility
+ * with signal names used in 3630.
+ */
+#define OMAP2430_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x000
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x001
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x002
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x003
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x004
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x005
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x006
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x007
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x008
+#define OMAP2430_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET 0x009
+#define OMAP2430_CONTROL_PADCONF_GPMC_NOE_NRE_OFFSET 0x00a
+#define OMAP2430_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x00b
+#define OMAP2430_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET 0x00c
+#define OMAP2430_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x00d
+#define OMAP2430_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x00e
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x00f
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x010
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x011
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x012
+#define OMAP2430_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x013
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x014
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x015
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x016
+#define OMAP2430_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x017
+#define OMAP2430_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x018
+#define OMAP2430_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x019
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x01a
+#define OMAP2430_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x01b
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x01c
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x01d
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x01e
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x01f
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x020
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x021
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x022
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x023
+#define OMAP2430_CONTROL_PADCONF_SDRC_A14_OFFSET 0x024
+#define OMAP2430_CONTROL_PADCONF_SDRC_A13_OFFSET 0x025
+#define OMAP2430_CONTROL_PADCONF_SDRC_A12_OFFSET 0x026
+#define OMAP2430_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x027
+#define OMAP2430_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x028
+#define OMAP2430_CONTROL_PADCONF_SDRC_A11_OFFSET 0x029
+#define OMAP2430_CONTROL_PADCONF_SDRC_A10_OFFSET 0x02a
+#define OMAP2430_CONTROL_PADCONF_SDRC_A9_OFFSET 0x02b
+#define OMAP2430_CONTROL_PADCONF_SDRC_A8_OFFSET 0x02c
+#define OMAP2430_CONTROL_PADCONF_SDRC_A7_OFFSET 0x02d
+#define OMAP2430_CONTROL_PADCONF_SDRC_A6_OFFSET 0x02e
+#define OMAP2430_CONTROL_PADCONF_SDRC_A5_OFFSET 0x02f
+#define OMAP2430_CONTROL_PADCONF_SDRC_A4_OFFSET 0x030
+#define OMAP2430_CONTROL_PADCONF_SDRC_A3_OFFSET 0x031
+#define OMAP2430_CONTROL_PADCONF_SDRC_A2_OFFSET 0x032
+#define OMAP2430_CONTROL_PADCONF_SDRC_A1_OFFSET 0x033
+#define OMAP2430_CONTROL_PADCONF_SDRC_A0_OFFSET 0x034
+#define OMAP2430_CONTROL_PADCONF_SDRC_D31_OFFSET 0x035
+#define OMAP2430_CONTROL_PADCONF_SDRC_D30_OFFSET 0x036
+#define OMAP2430_CONTROL_PADCONF_SDRC_D29_OFFSET 0x037
+#define OMAP2430_CONTROL_PADCONF_SDRC_D28_OFFSET 0x038
+#define OMAP2430_CONTROL_PADCONF_SDRC_D27_OFFSET 0x039
+#define OMAP2430_CONTROL_PADCONF_SDRC_D26_OFFSET 0x03a
+#define OMAP2430_CONTROL_PADCONF_SDRC_D25_OFFSET 0x03b
+#define OMAP2430_CONTROL_PADCONF_SDRC_D24_OFFSET 0x03c
+#define OMAP2430_CONTROL_PADCONF_SDRC_D23_OFFSET 0x03d
+#define OMAP2430_CONTROL_PADCONF_SDRC_D22_OFFSET 0x03e
+#define OMAP2430_CONTROL_PADCONF_SDRC_D21_OFFSET 0x03f
+#define OMAP2430_CONTROL_PADCONF_SDRC_D20_OFFSET 0x040
+#define OMAP2430_CONTROL_PADCONF_SDRC_D19_OFFSET 0x041
+#define OMAP2430_CONTROL_PADCONF_SDRC_D18_OFFSET 0x042
+#define OMAP2430_CONTROL_PADCONF_SDRC_D17_OFFSET 0x043
+#define OMAP2430_CONTROL_PADCONF_SDRC_D16_OFFSET 0x044
+#define OMAP2430_CONTROL_PADCONF_SDRC_D15_OFFSET 0x045
+#define OMAP2430_CONTROL_PADCONF_SDRC_D14_OFFSET 0x046
+#define OMAP2430_CONTROL_PADCONF_SDRC_D13_OFFSET 0x047
+#define OMAP2430_CONTROL_PADCONF_SDRC_D12_OFFSET 0x048
+#define OMAP2430_CONTROL_PADCONF_SDRC_D11_OFFSET 0x049
+#define OMAP2430_CONTROL_PADCONF_SDRC_D10_OFFSET 0x04a
+#define OMAP2430_CONTROL_PADCONF_SDRC_D9_OFFSET 0x04b
+#define OMAP2430_CONTROL_PADCONF_SDRC_D8_OFFSET 0x04c
+#define OMAP2430_CONTROL_PADCONF_SDRC_D7_OFFSET 0x04d
+#define OMAP2430_CONTROL_PADCONF_SDRC_D6_OFFSET 0x04e
+#define OMAP2430_CONTROL_PADCONF_SDRC_D5_OFFSET 0x04f
+#define OMAP2430_CONTROL_PADCONF_SDRC_D4_OFFSET 0x050
+#define OMAP2430_CONTROL_PADCONF_SDRC_D3_OFFSET 0x051
+#define OMAP2430_CONTROL_PADCONF_SDRC_D2_OFFSET 0x052
+#define OMAP2430_CONTROL_PADCONF_SDRC_D1_OFFSET 0x053
+#define OMAP2430_CONTROL_PADCONF_SDRC_D0_OFFSET 0x054
+#define OMAP2430_CONTROL_PADCONF_GPMC_A10_OFFSET 0x055
+#define OMAP2430_CONTROL_PADCONF_GPMC_A9_OFFSET 0x056
+#define OMAP2430_CONTROL_PADCONF_GPMC_A8_OFFSET 0x057
+#define OMAP2430_CONTROL_PADCONF_GPMC_A7_OFFSET 0x058
+#define OMAP2430_CONTROL_PADCONF_GPMC_A6_OFFSET 0x059
+#define OMAP2430_CONTROL_PADCONF_GPMC_A5_OFFSET 0x05a
+#define OMAP2430_CONTROL_PADCONF_GPMC_A4_OFFSET 0x05b
+#define OMAP2430_CONTROL_PADCONF_GPMC_A3_OFFSET 0x05c
+#define OMAP2430_CONTROL_PADCONF_GPMC_A2_OFFSET 0x05d
+#define OMAP2430_CONTROL_PADCONF_GPMC_A1_OFFSET 0x05e
+#define OMAP2430_CONTROL_PADCONF_GPMC_D15_OFFSET 0x05f
+#define OMAP2430_CONTROL_PADCONF_GPMC_D14_OFFSET 0x060
+#define OMAP2430_CONTROL_PADCONF_GPMC_D13_OFFSET 0x061
+#define OMAP2430_CONTROL_PADCONF_GPMC_D12_OFFSET 0x062
+#define OMAP2430_CONTROL_PADCONF_GPMC_D11_OFFSET 0x063
+#define OMAP2430_CONTROL_PADCONF_GPMC_D10_OFFSET 0x064
+#define OMAP2430_CONTROL_PADCONF_GPMC_D9_OFFSET 0x065
+#define OMAP2430_CONTROL_PADCONF_GPMC_D8_OFFSET 0x066
+#define OMAP2430_CONTROL_PADCONF_GPMC_D7_OFFSET 0x067
+#define OMAP2430_CONTROL_PADCONF_GPMC_D6_OFFSET 0x068
+#define OMAP2430_CONTROL_PADCONF_GPMC_D5_OFFSET 0x069
+#define OMAP2430_CONTROL_PADCONF_GPMC_D4_OFFSET 0x06a
+#define OMAP2430_CONTROL_PADCONF_GPMC_D3_OFFSET 0x06b
+#define OMAP2430_CONTROL_PADCONF_GPMC_D2_OFFSET 0x06c
+#define OMAP2430_CONTROL_PADCONF_GPMC_D1_OFFSET 0x06d
+#define OMAP2430_CONTROL_PADCONF_GPMC_D0_OFFSET 0x06e
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x06f
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x070
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x071
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x072
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x073
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x074
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x075
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x076
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x077
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x078
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x079
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x07a
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x07b
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x07c
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x07d
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x07e
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x07f
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x080
+#define OMAP2430_CONTROL_PADCONF_UART1_CTS_OFFSET 0x081
+#define OMAP2430_CONTROL_PADCONF_UART1_RTS_OFFSET 0x082
+#define OMAP2430_CONTROL_PADCONF_UART1_TX_OFFSET 0x083
+#define OMAP2430_CONTROL_PADCONF_UART1_RX_OFFSET 0x084
+#define OMAP2430_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x085
+#define OMAP2430_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x086
+#define OMAP2430_CONTROL_PADCONF_DSS_PCLK_OFFSET 0x087
+#define OMAP2430_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x088
+#define OMAP2430_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x089
+#define OMAP2430_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x08a
+#define OMAP2430_CONTROL_PADCONF_SYS_NRESPWRON_OFFSET 0x08b
+#define OMAP2430_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x08c
+#define OMAP2430_CONTROL_PADCONF_SYS_NIRQ0_OFFSET 0x08d
+#define OMAP2430_CONTROL_PADCONF_SYS_NIRQ1_OFFSET 0x08e
+#define OMAP2430_CONTROL_PADCONF_SYS_VMODE_OFFSET 0x08f
+#define OMAP2430_CONTROL_PADCONF_GPIO_128_OFFSET 0x090
+#define OMAP2430_CONTROL_PADCONF_GPIO_129_OFFSET 0x091
+#define OMAP2430_CONTROL_PADCONF_GPIO_130_OFFSET 0x092
+#define OMAP2430_CONTROL_PADCONF_GPIO_131_OFFSET 0x093
+#define OMAP2430_CONTROL_PADCONF_SYS_32K_OFFSET 0x094
+#define OMAP2430_CONTROL_PADCONF_SYS_XTALIN_OFFSET 0x095
+#define OMAP2430_CONTROL_PADCONF_SYS_XTALOUT_OFFSET 0x096
+#define OMAP2430_CONTROL_PADCONF_GPIO_132_OFFSET 0x097
+#define OMAP2430_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x098
+#define OMAP2430_CONTROL_PADCONF_SYS_CLKOUT_OFFSET 0x099
+#define OMAP2430_CONTROL_PADCONF_GPIO_151_OFFSET 0x09a
+#define OMAP2430_CONTROL_PADCONF_GPIO_133_OFFSET 0x09b
+#define OMAP2430_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x09c
+#define OMAP2430_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x09d
+#define OMAP2430_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x09e
+#define OMAP2430_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x09f
+#define OMAP2430_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0x0a0
+#define OMAP2430_CONTROL_PADCONF_JTAG_TMS_OFFSET 0x0a1
+#define OMAP2430_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x0a2
+#define OMAP2430_CONTROL_PADCONF_JTAG_TDO_OFFSET 0x0a3
+#define OMAP2430_CONTROL_PADCONF_CAM_D9_OFFSET 0x0a4
+#define OMAP2430_CONTROL_PADCONF_CAM_D8_OFFSET 0x0a5
+#define OMAP2430_CONTROL_PADCONF_CAM_D7_OFFSET 0x0a6
+#define OMAP2430_CONTROL_PADCONF_CAM_D6_OFFSET 0x0a7
+#define OMAP2430_CONTROL_PADCONF_CAM_D5_OFFSET 0x0a8
+#define OMAP2430_CONTROL_PADCONF_CAM_D4_OFFSET 0x0a9
+#define OMAP2430_CONTROL_PADCONF_CAM_D3_OFFSET 0x0aa
+#define OMAP2430_CONTROL_PADCONF_CAM_D2_OFFSET 0x0ab
+#define OMAP2430_CONTROL_PADCONF_CAM_D1_OFFSET 0x0ac
+#define OMAP2430_CONTROL_PADCONF_CAM_D0_OFFSET 0x0ad
+#define OMAP2430_CONTROL_PADCONF_CAM_HS_OFFSET 0x0ae
+#define OMAP2430_CONTROL_PADCONF_CAM_VS_OFFSET 0x0af
+#define OMAP2430_CONTROL_PADCONF_CAM_LCLK_OFFSET 0x0b0
+#define OMAP2430_CONTROL_PADCONF_CAM_XCLK_OFFSET 0x0b1
+#define OMAP2430_CONTROL_PADCONF_CAM_D11_OFFSET 0x0b2
+#define OMAP2430_CONTROL_PADCONF_CAM_D10_OFFSET 0x0b3
+#define OMAP2430_CONTROL_PADCONF_GPIO_134_OFFSET 0x0b4
+#define OMAP2430_CONTROL_PADCONF_GPIO_135_OFFSET 0x0b5
+#define OMAP2430_CONTROL_PADCONF_GPIO_136_OFFSET 0x0b6
+#define OMAP2430_CONTROL_PADCONF_GPIO_137_OFFSET 0x0b7
+#define OMAP2430_CONTROL_PADCONF_GPIO_138_OFFSET 0x0b8
+#define OMAP2430_CONTROL_PADCONF_GPIO_139_OFFSET 0x0b9
+#define OMAP2430_CONTROL_PADCONF_GPIO_140_OFFSET 0x0ba
+#define OMAP2430_CONTROL_PADCONF_GPIO_141_OFFSET 0x0bb
+#define OMAP2430_CONTROL_PADCONF_GPIO_142_OFFSET 0x0bc
+#define OMAP2430_CONTROL_PADCONF_GPIO_154_OFFSET 0x0bd
+#define OMAP2430_CONTROL_PADCONF_GPIO_148_OFFSET 0x0be
+#define OMAP2430_CONTROL_PADCONF_GPIO_149_OFFSET 0x0bf
+#define OMAP2430_CONTROL_PADCONF_GPIO_150_OFFSET 0x0c0
+#define OMAP2430_CONTROL_PADCONF_GPIO_152_OFFSET 0x0c1
+#define OMAP2430_CONTROL_PADCONF_GPIO_153_OFFSET 0x0c2
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_CLKO_OFFSET 0x0c3
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_CMD_OFFSET 0x0c4
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET 0x0c5
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET 0x0c6
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET 0x0c7
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET 0x0c8
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_CLKO_OFFSET 0x0c9
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET 0x0ca
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_CMD_OFFSET 0x0cb
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET 0x0cc
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET 0x0cd
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET 0x0ce
+#define OMAP2430_CONTROL_PADCONF_UART2_CTS_OFFSET 0x0cf
+#define OMAP2430_CONTROL_PADCONF_UART2_RTS_OFFSET 0x0d0
+#define OMAP2430_CONTROL_PADCONF_UART2_TX_OFFSET 0x0d1
+#define OMAP2430_CONTROL_PADCONF_UART2_RX_OFFSET 0x0d2
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET 0x0d3
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_FSX_OFFSET 0x0d4
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_DR_OFFSET 0x0d5
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_DX_OFFSET 0x0d6
+#define OMAP2430_CONTROL_PADCONF_SSI1_DAT_TX_OFFSET 0x0d7
+#define OMAP2430_CONTROL_PADCONF_SSI1_FLAG_TX_OFFSET 0x0d8
+#define OMAP2430_CONTROL_PADCONF_SSI1_RDY_TX_OFFSET 0x0d9
+#define OMAP2430_CONTROL_PADCONF_SSI1_DAT_RX_OFFSET 0x0da
+#define OMAP2430_CONTROL_PADCONF_GPIO_63_OFFSET 0x0db
+#define OMAP2430_CONTROL_PADCONF_SSI1_FLAG_RX_OFFSET 0x0dc
+#define OMAP2430_CONTROL_PADCONF_SSI1_RDY_RX_OFFSET 0x0dd
+#define OMAP2430_CONTROL_PADCONF_SSI1_WAKE_OFFSET 0x0de
+#define OMAP2430_CONTROL_PADCONF_SPI1_CLK_OFFSET 0x0df
+#define OMAP2430_CONTROL_PADCONF_SPI1_SIMO_OFFSET 0x0e0
+#define OMAP2430_CONTROL_PADCONF_SPI1_SOMI_OFFSET 0x0e1
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS0_OFFSET 0x0e2
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS1_OFFSET 0x0e3
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS2_OFFSET 0x0e4
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS3_OFFSET 0x0e5
+#define OMAP2430_CONTROL_PADCONF_SPI2_CLK_OFFSET 0x0e6
+#define OMAP2430_CONTROL_PADCONF_SPI2_SIMO_OFFSET 0x0e7
+#define OMAP2430_CONTROL_PADCONF_SPI2_SOMI_OFFSET 0x0e8
+#define OMAP2430_CONTROL_PADCONF_SPI2_CS0_OFFSET 0x0e9
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x0ea
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x0eb
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x0ec
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x0ed
+#define OMAP2430_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x0ee
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x0ef
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x0f0
+#define OMAP2430_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x0f1
+#define OMAP2430_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x0f2
+#define OMAP2430_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x0f3
+#define OMAP2430_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x0f4
+#define OMAP2430_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x0f5
+#define OMAP2430_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x0f6
+#define OMAP2430_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x0f7
+#define OMAP2430_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x0f8
+#define OMAP2430_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x0f9
+#define OMAP2430_CONTROL_PADCONF_GPIO_7_OFFSET 0x0fa
+#define OMAP2430_CONTROL_PADCONF_GPIO_78_OFFSET 0x0fb
+#define OMAP2430_CONTROL_PADCONF_GPIO_79_OFFSET 0x0fc
+#define OMAP2430_CONTROL_PADCONF_GPIO_80_OFFSET 0x0fd
+#define OMAP2430_CONTROL_PADCONF_GPIO_113_OFFSET 0x0fe
+#define OMAP2430_CONTROL_PADCONF_GPIO_114_OFFSET 0x0ff
+#define OMAP2430_CONTROL_PADCONF_GPIO_115_OFFSET 0x100
+#define OMAP2430_CONTROL_PADCONF_GPIO_116_OFFSET 0x101
+#define OMAP2430_CONTROL_PADCONF_SYS_DRM_MSECURE_OFFSET 0x102
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA3_OFFSET 0x103
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA4_OFFSET 0x104
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA5_OFFSET 0x105
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA6_OFFSET 0x106
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA2_OFFSET 0x107
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA0_OFFSET 0x108
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA1_OFFSET 0x109
+#define OMAP2430_CONTROL_PADCONF_USB0HS_CLK_OFFSET 0x10a
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DIR_OFFSET 0x10b
+#define OMAP2430_CONTROL_PADCONF_USB0HS_STP_OFFSET 0x10c
+#define OMAP2430_CONTROL_PADCONF_USB0HS_NXT_OFFSET 0x10d
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA7_OFFSET 0x10e
+#define OMAP2430_CONTROL_PADCONF_TV_OUT_OFFSET 0x10f
+#define OMAP2430_CONTROL_PADCONF_TV_VREF_OFFSET 0x110
+#define OMAP2430_CONTROL_PADCONF_TV_RSET_OFFSET 0x111
+#define OMAP2430_CONTROL_PADCONF_TV_VFB_OFFSET 0x112
+#define OMAP2430_CONTROL_PADCONF_TV_DACOUT_OFFSET 0x113
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD0_OFFSET 0x114
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD1_OFFSET 0x115
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD2_OFFSET 0x116
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD3_OFFSET 0x117
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD4_OFFSET 0x118
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD5_OFFSET 0x119
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD6_OFFSET 0x11a
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD7_OFFSET 0x11b
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD8_OFFSET 0x11c
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD9_OFFSET 0x11d
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD10_OFFSET 0x11e
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD11_OFFSET 0x11f
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD12_OFFSET 0x120
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD13_OFFSET 0x121
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD14_OFFSET 0x122
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD15_OFFSET 0x123
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD16_OFFSET 0x124
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD17_OFFSET 0x125
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD18_OFFSET 0x126
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD19_OFFSET 0x127
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD20_OFFSET 0x128
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD21_OFFSET 0x129
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD22_OFFSET 0x12a
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD23_OFFSET 0x12b
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD24_OFFSET 0x12c
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD25_OFFSET 0x12d
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD26_OFFSET 0x12e
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD27_OFFSET 0x12f
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD28_OFFSET 0x130
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD29_OFFSET 0x131
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD30_OFFSET 0x132
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD31_OFFSET 0x133
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD32_OFFSET 0x134
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD33_OFFSET 0x135
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD34_OFFSET 0x136
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD35_OFFSET 0x137
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD36_OFFSET 0x138
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD37_OFFSET 0x139
+#define OMAP2430_CONTROL_PADCONF_AD2DMWRITE_OFFSET 0x13a
+#define OMAP2430_CONTROL_PADCONF_D2DCLK26MI_OFFSET 0x13b
+#define OMAP2430_CONTROL_PADCONF_D2DNRESPWRON1_OFFSET 0x13c
+#define OMAP2430_CONTROL_PADCONF_D2DNRESWARM_OFFSET 0x13d
+#define OMAP2430_CONTROL_PADCONF_D2DARM9NIRQ_OFFSET 0x13e
+#define OMAP2430_CONTROL_PADCONF_D2DUMA2P6FIQ_OFFSET 0x13f
+#define OMAP2430_CONTROL_PADCONF_D2DSPINT_OFFSET 0x140
+#define OMAP2430_CONTROL_PADCONF_D2DFRINT_OFFSET 0x141
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ0_OFFSET 0x142
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ1_OFFSET 0x143
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ2_OFFSET 0x144
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ3_OFFSET 0x145
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTRST_OFFSET 0x146
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTDI_OFFSET 0x147
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTDO_OFFSET 0x148
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTMS_OFFSET 0x149
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTCK_OFFSET 0x14a
+#define OMAP2430_CONTROL_PADCONF_D2DN3GRTCK_OFFSET 0x14b
+#define OMAP2430_CONTROL_PADCONF_D2DMSTDBY_OFFSET 0x14c
+#define OMAP2430_CONTROL_PADCONF_AD2DSREAD_OFFSET 0x14d
+#define OMAP2430_CONTROL_PADCONF_D2DSWAKEUP_OFFSET 0x14e
+#define OMAP2430_CONTROL_PADCONF_D2DIDLEREQ_OFFSET 0x14f
+#define OMAP2430_CONTROL_PADCONF_D2DIDLEACK_OFFSET 0x150
+#define OMAP2430_CONTROL_PADCONF_D2DSPARE0_OFFSET 0x151
+#define OMAP2430_CONTROL_PADCONF_AD2DSWRITE_OFFSET 0x152
+#define OMAP2430_CONTROL_PADCONF_AD2DMREAD_OFFSET 0x153
+
+#define OMAP2430_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP2430_CONTROL_PADCONF_AD2DMREAD_OFFSET + 0x1)
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
new file mode 100644
index 00000000..17f80e4a
--- /dev/null
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -0,0 +1,2061 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can 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/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP3_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP3_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP3_CONTROL_PADCONF_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap3
+ */
+static struct omap_mux __initdata omap3_muxmodes[] = {
+ _OMAP3_MUXENTRY(CAM_D0, 99,
+ "cam_d0", NULL, NULL, NULL,
+ "gpio_99", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D1, 100,
+ "cam_d1", NULL, NULL, NULL,
+ "gpio_100", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D10, 109,
+ "cam_d10", NULL, NULL, NULL,
+ "gpio_109", "hw_dbg8", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D11, 110,
+ "cam_d11", NULL, NULL, NULL,
+ "gpio_110", "hw_dbg9", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D2, 101,
+ "cam_d2", NULL, NULL, NULL,
+ "gpio_101", "hw_dbg4", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D3, 102,
+ "cam_d3", NULL, NULL, NULL,
+ "gpio_102", "hw_dbg5", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D4, 103,
+ "cam_d4", NULL, NULL, NULL,
+ "gpio_103", "hw_dbg6", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D5, 104,
+ "cam_d5", NULL, NULL, NULL,
+ "gpio_104", "hw_dbg7", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D6, 105,
+ "cam_d6", NULL, NULL, NULL,
+ "gpio_105", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D7, 106,
+ "cam_d7", NULL, NULL, NULL,
+ "gpio_106", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D8, 107,
+ "cam_d8", NULL, NULL, NULL,
+ "gpio_107", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D9, 108,
+ "cam_d9", NULL, NULL, NULL,
+ "gpio_108", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_FLD, 98,
+ "cam_fld", NULL, "cam_global_reset", NULL,
+ "gpio_98", "hw_dbg3", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_HS, 94,
+ "cam_hs", NULL, NULL, NULL,
+ "gpio_94", "hw_dbg0", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_PCLK, 97,
+ "cam_pclk", NULL, NULL, NULL,
+ "gpio_97", "hw_dbg2", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_STROBE, 126,
+ "cam_strobe", NULL, NULL, NULL,
+ "gpio_126", "hw_dbg11", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_VS, 95,
+ "cam_vs", NULL, NULL, NULL,
+ "gpio_95", "hw_dbg1", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_WEN, 167,
+ "cam_wen", NULL, "cam_shutter", NULL,
+ "gpio_167", "hw_dbg10", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_XCLKA, 96,
+ "cam_xclka", NULL, NULL, NULL,
+ "gpio_96", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_XCLKB, 111,
+ "cam_xclkb", NULL, NULL, NULL,
+ "gpio_111", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CSI2_DX0, 112,
+ "csi2_dx0", NULL, NULL, NULL,
+ "gpio_112", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CSI2_DX1, 114,
+ "csi2_dx1", NULL, NULL, NULL,
+ "gpio_114", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CSI2_DY0, 113,
+ "csi2_dy0", NULL, NULL, NULL,
+ "gpio_113", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CSI2_DY1, 115,
+ "csi2_dy1", NULL, NULL, NULL,
+ "gpio_115", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_ACBIAS, 69,
+ "dss_acbias", NULL, NULL, NULL,
+ "gpio_69", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA0, 70,
+ "dss_data0", NULL, "uart1_cts", NULL,
+ "gpio_70", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA1, 71,
+ "dss_data1", NULL, "uart1_rts", NULL,
+ "gpio_71", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA10, 80,
+ "dss_data10", NULL, NULL, NULL,
+ "gpio_80", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA11, 81,
+ "dss_data11", NULL, NULL, NULL,
+ "gpio_81", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA12, 82,
+ "dss_data12", NULL, NULL, NULL,
+ "gpio_82", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA13, 83,
+ "dss_data13", NULL, NULL, NULL,
+ "gpio_83", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA14, 84,
+ "dss_data14", NULL, NULL, NULL,
+ "gpio_84", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA15, 85,
+ "dss_data15", NULL, NULL, NULL,
+ "gpio_85", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA16, 86,
+ "dss_data16", NULL, NULL, NULL,
+ "gpio_86", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA17, 87,
+ "dss_data17", NULL, NULL, NULL,
+ "gpio_87", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA18, 88,
+ "dss_data18", NULL, "mcspi3_clk", "dss_data0",
+ "gpio_88", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA19, 89,
+ "dss_data19", NULL, "mcspi3_simo", "dss_data1",
+ "gpio_89", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA20, 90,
+ "dss_data20", NULL, "mcspi3_somi", "dss_data2",
+ "gpio_90", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA21, 91,
+ "dss_data21", NULL, "mcspi3_cs0", "dss_data3",
+ "gpio_91", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA22, 92,
+ "dss_data22", NULL, "mcspi3_cs1", "dss_data4",
+ "gpio_92", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA23, 93,
+ "dss_data23", NULL, NULL, "dss_data5",
+ "gpio_93", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA2, 72,
+ "dss_data2", NULL, NULL, NULL,
+ "gpio_72", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA3, 73,
+ "dss_data3", NULL, NULL, NULL,
+ "gpio_73", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA4, 74,
+ "dss_data4", NULL, "uart3_rx_irrx", NULL,
+ "gpio_74", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA5, 75,
+ "dss_data5", NULL, "uart3_tx_irtx", NULL,
+ "gpio_75", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA6, 76,
+ "dss_data6", NULL, "uart1_tx", NULL,
+ "gpio_76", "hw_dbg14", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA7, 77,
+ "dss_data7", NULL, "uart1_rx", NULL,
+ "gpio_77", "hw_dbg15", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA8, 78,
+ "dss_data8", NULL, NULL, NULL,
+ "gpio_78", "hw_dbg16", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA9, 79,
+ "dss_data9", NULL, NULL, NULL,
+ "gpio_79", "hw_dbg17", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_HSYNC, 67,
+ "dss_hsync", NULL, NULL, NULL,
+ "gpio_67", "hw_dbg13", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_PCLK, 66,
+ "dss_pclk", NULL, NULL, NULL,
+ "gpio_66", "hw_dbg12", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_VSYNC, 68,
+ "dss_vsync", NULL, NULL, NULL,
+ "gpio_68", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(ETK_CLK, 12,
+ "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+ "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", "hw_dbg0"),
+ _OMAP3_MUXENTRY(ETK_CTL, 13,
+ "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+ "gpio_13", NULL, "hsusb1_tll_clk", "hw_dbg1"),
+ _OMAP3_MUXENTRY(ETK_D0, 14,
+ "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+ "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", "hw_dbg2"),
+ _OMAP3_MUXENTRY(ETK_D1, 15,
+ "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+ "gpio_15", "mm1_txse0", "hsusb1_tll_data1", "hw_dbg3"),
+ _OMAP3_MUXENTRY(ETK_D10, 24,
+ "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+ "gpio_24", NULL, "hsusb2_tll_clk", "hw_dbg12"),
+ _OMAP3_MUXENTRY(ETK_D11, 25,
+ "etk_d11", NULL, NULL, "hsusb2_stp",
+ "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", "hw_dbg13"),
+ _OMAP3_MUXENTRY(ETK_D12, 26,
+ "etk_d12", NULL, NULL, "hsusb2_dir",
+ "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
+ _OMAP3_MUXENTRY(ETK_D13, 27,
+ "etk_d13", NULL, NULL, "hsusb2_nxt",
+ "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", "hw_dbg15"),
+ _OMAP3_MUXENTRY(ETK_D14, 28,
+ "etk_d14", NULL, NULL, "hsusb2_data0",
+ "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", "hw_dbg16"),
+ _OMAP3_MUXENTRY(ETK_D15, 29,
+ "etk_d15", NULL, NULL, "hsusb2_data1",
+ "gpio_29", "mm2_txse0", "hsusb2_tll_data1", "hw_dbg17"),
+ _OMAP3_MUXENTRY(ETK_D2, 16,
+ "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+ "gpio_16", "mm1_txdat", "hsusb1_tll_data2", "hw_dbg4"),
+ _OMAP3_MUXENTRY(ETK_D3, 17,
+ "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+ "gpio_17", NULL, "hsusb1_tll_data7", "hw_dbg5"),
+ _OMAP3_MUXENTRY(ETK_D4, 18,
+ "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+ "gpio_18", NULL, "hsusb1_tll_data4", "hw_dbg6"),
+ _OMAP3_MUXENTRY(ETK_D5, 19,
+ "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+ "gpio_19", NULL, "hsusb1_tll_data5", "hw_dbg7"),
+ _OMAP3_MUXENTRY(ETK_D6, 20,
+ "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+ "gpio_20", NULL, "hsusb1_tll_data6", "hw_dbg8"),
+ _OMAP3_MUXENTRY(ETK_D7, 21,
+ "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+ "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", "hw_dbg9"),
+ _OMAP3_MUXENTRY(ETK_D8, 22,
+ "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+ "gpio_22", NULL, "hsusb1_tll_dir", "hw_dbg10"),
+ _OMAP3_MUXENTRY(ETK_D9, 23,
+ "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+ "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", "hw_dbg11"),
+ _OMAP3_MUXENTRY(GPMC_A1, 34,
+ "gpmc_a1", NULL, NULL, NULL,
+ "gpio_34", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A10, 43,
+ "gpmc_a10", "sys_ndmareq3", NULL, NULL,
+ "gpio_43", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A2, 35,
+ "gpmc_a2", NULL, NULL, NULL,
+ "gpio_35", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A3, 36,
+ "gpmc_a3", NULL, NULL, NULL,
+ "gpio_36", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A4, 37,
+ "gpmc_a4", NULL, NULL, NULL,
+ "gpio_37", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A5, 38,
+ "gpmc_a5", NULL, NULL, NULL,
+ "gpio_38", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A6, 39,
+ "gpmc_a6", NULL, NULL, NULL,
+ "gpio_39", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A7, 40,
+ "gpmc_a7", NULL, NULL, NULL,
+ "gpio_40", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A8, 41,
+ "gpmc_a8", NULL, NULL, NULL,
+ "gpio_41", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_A9, 42,
+ "gpmc_a9", "sys_ndmareq2", NULL, NULL,
+ "gpio_42", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_CLK, 59,
+ "gpmc_clk", NULL, NULL, NULL,
+ "gpio_59", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D10, 46,
+ "gpmc_d10", NULL, NULL, NULL,
+ "gpio_46", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D11, 47,
+ "gpmc_d11", NULL, NULL, NULL,
+ "gpio_47", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D12, 48,
+ "gpmc_d12", NULL, NULL, NULL,
+ "gpio_48", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D13, 49,
+ "gpmc_d13", NULL, NULL, NULL,
+ "gpio_49", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D14, 50,
+ "gpmc_d14", NULL, NULL, NULL,
+ "gpio_50", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D15, 51,
+ "gpmc_d15", NULL, NULL, NULL,
+ "gpio_51", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D8, 44,
+ "gpmc_d8", NULL, NULL, NULL,
+ "gpio_44", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_D9, 45,
+ "gpmc_d9", NULL, NULL, NULL,
+ "gpio_45", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NBE0_CLE, 60,
+ "gpmc_nbe0_cle", NULL, NULL, NULL,
+ "gpio_60", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NBE1, 61,
+ "gpmc_nbe1", NULL, NULL, NULL,
+ "gpio_61", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS1, 52,
+ "gpmc_ncs1", NULL, NULL, NULL,
+ "gpio_52", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS2, 53,
+ "gpmc_ncs2", NULL, NULL, NULL,
+ "gpio_53", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS3, 54,
+ "gpmc_ncs3", "sys_ndmareq0", NULL, NULL,
+ "gpio_54", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS4, 55,
+ "gpmc_ncs4", "sys_ndmareq1", "mcbsp4_clkx", "gpt9_pwm_evt",
+ "gpio_55", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS5, 56,
+ "gpmc_ncs5", "sys_ndmareq2", "mcbsp4_dr", "gpt10_pwm_evt",
+ "gpio_56", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS6, 57,
+ "gpmc_ncs6", "sys_ndmareq3", "mcbsp4_dx", "gpt11_pwm_evt",
+ "gpio_57", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NCS7, 58,
+ "gpmc_ncs7", "gpmc_io_dir", "mcbsp4_fsx", "gpt8_pwm_evt",
+ "gpio_58", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_NWP, 62,
+ "gpmc_nwp", NULL, NULL, NULL,
+ "gpio_62", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_WAIT1, 63,
+ "gpmc_wait1", NULL, NULL, NULL,
+ "gpio_63", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_WAIT2, 64,
+ "gpmc_wait2", NULL, NULL, NULL,
+ "gpio_64", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_WAIT3, 65,
+ "gpmc_wait3", "sys_ndmareq1", NULL, NULL,
+ "gpio_65", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HDQ_SIO, 170,
+ "hdq_sio", "sys_altclk", "i2c2_sccbe", "i2c3_sccbe",
+ "gpio_170", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_CLK, 120,
+ "hsusb0_clk", NULL, NULL, NULL,
+ "gpio_120", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
+ "hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
+ "gpio_125", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
+ "hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
+ "gpio_130", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
+ "hsusb0_data2", NULL, "uart3_rts_sd", NULL,
+ "gpio_131", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
+ "hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
+ "gpio_169", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA4, 188,
+ "hsusb0_data4", NULL, NULL, NULL,
+ "gpio_188", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA5, 189,
+ "hsusb0_data5", NULL, NULL, NULL,
+ "gpio_189", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA6, 190,
+ "hsusb0_data6", NULL, NULL, NULL,
+ "gpio_190", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA7, 191,
+ "hsusb0_data7", NULL, NULL, NULL,
+ "gpio_191", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DIR, 122,
+ "hsusb0_dir", NULL, NULL, NULL,
+ "gpio_122", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_NXT, 124,
+ "hsusb0_nxt", NULL, NULL, NULL,
+ "gpio_124", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_STP, 121,
+ "hsusb0_stp", NULL, NULL, NULL,
+ "gpio_121", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C2_SCL, 168,
+ "i2c2_scl", NULL, NULL, NULL,
+ "gpio_168", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C2_SDA, 183,
+ "i2c2_sda", NULL, NULL, NULL,
+ "gpio_183", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C3_SCL, 184,
+ "i2c3_scl", NULL, NULL, NULL,
+ "gpio_184", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C3_SDA, 185,
+ "i2c3_sda", NULL, NULL, NULL,
+ "gpio_185", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C4_SCL, 0,
+ "i2c4_scl", "sys_nvmode1", NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(I2C4_SDA, 0,
+ "i2c4_sda", "sys_nvmode2", NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(JTAG_EMU0, 11,
+ "jtag_emu0", NULL, NULL, NULL,
+ "gpio_11", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(JTAG_EMU1, 31,
+ "jtag_emu1", NULL, NULL, NULL,
+ "gpio_31", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
+ "mcbsp1_clkr", "mcspi4_clk", NULL, NULL,
+ "gpio_156", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_CLKX, 162,
+ "mcbsp1_clkx", NULL, "mcbsp3_clkx", NULL,
+ "gpio_162", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_DR, 159,
+ "mcbsp1_dr", "mcspi4_somi", "mcbsp3_dr", NULL,
+ "gpio_159", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_DX, 158,
+ "mcbsp1_dx", "mcspi4_simo", "mcbsp3_dx", NULL,
+ "gpio_158", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_FSR, 157,
+ "mcbsp1_fsr", NULL, "cam_global_reset", NULL,
+ "gpio_157", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_FSX, 161,
+ "mcbsp1_fsx", "mcspi4_cs0", "mcbsp3_fsx", NULL,
+ "gpio_161", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP2_CLKX, 117,
+ "mcbsp2_clkx", NULL, NULL, NULL,
+ "gpio_117", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP2_DR, 118,
+ "mcbsp2_dr", NULL, NULL, NULL,
+ "gpio_118", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP2_DX, 119,
+ "mcbsp2_dx", NULL, NULL, NULL,
+ "gpio_119", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP2_FSX, 116,
+ "mcbsp2_fsx", NULL, NULL, NULL,
+ "gpio_116", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
+ "mcbsp3_clkx", "uart2_tx", NULL, NULL,
+ "gpio_142", "hsusb3_tll_data6", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_DR, 141,
+ "mcbsp3_dr", "uart2_rts", NULL, NULL,
+ "gpio_141", "hsusb3_tll_data5", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_DX, 140,
+ "mcbsp3_dx", "uart2_cts", NULL, NULL,
+ "gpio_140", "hsusb3_tll_data4", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_FSX, 143,
+ "mcbsp3_fsx", "uart2_rx", NULL, NULL,
+ "gpio_143", "hsusb3_tll_data7", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
+ "mcbsp4_clkx", NULL, NULL, NULL,
+ "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_DR, 153,
+ "mcbsp4_dr", NULL, NULL, NULL,
+ "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_DX, 154,
+ "mcbsp4_dx", NULL, NULL, NULL,
+ "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_FSX, 155,
+ "mcbsp4_fsx", NULL, NULL, NULL,
+ "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP_CLKS, 160,
+ "mcbsp_clks", NULL, "cam_shutter", NULL,
+ "gpio_160", "uart1_cts", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CLK, 171,
+ "mcspi1_clk", "sdmmc2_dat4", NULL, NULL,
+ "gpio_171", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CS0, 174,
+ "mcspi1_cs0", "sdmmc2_dat7", NULL, NULL,
+ "gpio_174", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CS1, 175,
+ "mcspi1_cs1", NULL, NULL, "sdmmc3_cmd",
+ "gpio_175", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CS2, 176,
+ "mcspi1_cs2", NULL, NULL, "sdmmc3_clk",
+ "gpio_176", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CS3, 177,
+ "mcspi1_cs3", NULL, "hsusb2_tll_data2", "hsusb2_data2",
+ "gpio_177", "mm2_txdat", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_SIMO, 172,
+ "mcspi1_simo", "sdmmc2_dat5", NULL, NULL,
+ "gpio_172", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_SOMI, 173,
+ "mcspi1_somi", "sdmmc2_dat6", NULL, NULL,
+ "gpio_173", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI2_CLK, 178,
+ "mcspi2_clk", NULL, "hsusb2_tll_data7", "hsusb2_data7",
+ "gpio_178", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI2_CS0, 181,
+ "mcspi2_cs0", "gpt11_pwm_evt",
+ "hsusb2_tll_data6", "hsusb2_data6",
+ "gpio_181", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI2_CS1, 182,
+ "mcspi2_cs1", "gpt8_pwm_evt",
+ "hsusb2_tll_data3", "hsusb2_data3",
+ "gpio_182", "mm2_txen_n", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI2_SIMO, 179,
+ "mcspi2_simo", "gpt9_pwm_evt",
+ "hsusb2_tll_data4", "hsusb2_data4",
+ "gpio_179", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI2_SOMI, 180,
+ "mcspi2_somi", "gpt10_pwm_evt",
+ "hsusb2_tll_data5", "hsusb2_data5",
+ "gpio_180", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_CLK, 120,
+ "sdmmc1_clk", NULL, NULL, NULL,
+ "gpio_120", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_CMD, 121,
+ "sdmmc1_cmd", NULL, NULL, NULL,
+ "gpio_121", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
+ "sdmmc1_dat0", NULL, NULL, NULL,
+ "gpio_122", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
+ "sdmmc1_dat1", NULL, NULL, NULL,
+ "gpio_123", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
+ "sdmmc1_dat2", NULL, NULL, NULL,
+ "gpio_124", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
+ "sdmmc1_dat3", NULL, NULL, NULL,
+ "gpio_125", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT4, 126,
+ "sdmmc1_dat4", NULL, "sim_io", NULL,
+ "gpio_126", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT5, 127,
+ "sdmmc1_dat5", NULL, "sim_clk", NULL,
+ "gpio_127", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT6, 128,
+ "sdmmc1_dat6", NULL, "sim_pwrctrl", NULL,
+ "gpio_128", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT7, 129,
+ "sdmmc1_dat7", NULL, "sim_rst", NULL,
+ "gpio_129", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_CLK, 130,
+ "sdmmc2_clk", "mcspi3_clk", NULL, NULL,
+ "gpio_130", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_CMD, 131,
+ "sdmmc2_cmd", "mcspi3_simo", NULL, NULL,
+ "gpio_131", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT0, 132,
+ "sdmmc2_dat0", "mcspi3_somi", NULL, NULL,
+ "gpio_132", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT1, 133,
+ "sdmmc2_dat1", NULL, NULL, NULL,
+ "gpio_133", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT2, 134,
+ "sdmmc2_dat2", "mcspi3_cs1", NULL, NULL,
+ "gpio_134", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT3, 135,
+ "sdmmc2_dat3", "mcspi3_cs0", NULL, NULL,
+ "gpio_135", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT4, 136,
+ "sdmmc2_dat4", "sdmmc2_dir_dat0", NULL, "sdmmc3_dat0",
+ "gpio_136", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
+ "sdmmc2_dat5", "sdmmc2_dir_dat1",
+ "cam_global_reset", "sdmmc3_dat1",
+ "gpio_137", "hsusb3_tll_stp", "mm3_rxdp", "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
+ "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
+ "gpio_138", "hsusb3_tll_dir", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
+ "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
+ "gpio_139", "hsusb3_tll_nxt", "mm3_rxdm", "safe_mode"),
+ _OMAP3_MUXENTRY(SDRC_CKE0, 0,
+ "sdrc_cke0", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDRC_CKE1, 0,
+ "sdrc_cke1", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT0, 2,
+ "sys_boot0", NULL, NULL, NULL,
+ "gpio_2", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT1, 3,
+ "sys_boot1", NULL, NULL, NULL,
+ "gpio_3", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT2, 4,
+ "sys_boot2", NULL, NULL, NULL,
+ "gpio_4", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT3, 5,
+ "sys_boot3", NULL, NULL, NULL,
+ "gpio_5", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT4, 6,
+ "sys_boot4", "sdmmc2_dir_dat2", NULL, NULL,
+ "gpio_6", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT5, 7,
+ "sys_boot5", "sdmmc2_dir_dat3", NULL, NULL,
+ "gpio_7", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT6, 8,
+ "sys_boot6", NULL, NULL, NULL,
+ "gpio_8", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_CLKOUT1, 10,
+ "sys_clkout1", NULL, NULL, NULL,
+ "gpio_10", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_CLKOUT2, 186,
+ "sys_clkout2", NULL, NULL, NULL,
+ "gpio_186", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_CLKREQ, 1,
+ "sys_clkreq", NULL, NULL, NULL,
+ "gpio_1", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_NIRQ, 0,
+ "sys_nirq", NULL, NULL, NULL,
+ "gpio_0", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_NRESWARM, 30,
+ "sys_nreswarm", NULL, NULL, NULL,
+ "gpio_30", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_OFF_MODE, 9,
+ "sys_off_mode", NULL, NULL, NULL,
+ "gpio_9", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_CTS, 150,
+ "uart1_cts", NULL, NULL, NULL,
+ "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_RTS, 149,
+ "uart1_rts", NULL, NULL, NULL,
+ "gpio_149", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_RX, 151,
+ "uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk",
+ "gpio_151", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_TX, 148,
+ "uart1_tx", NULL, NULL, NULL,
+ "gpio_148", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART2_CTS, 144,
+ "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL,
+ "gpio_144", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART2_RTS, 145,
+ "uart2_rts", "mcbsp3_dr", "gpt10_pwm_evt", NULL,
+ "gpio_145", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART2_RX, 147,
+ "uart2_rx", "mcbsp3_fsx", "gpt8_pwm_evt", NULL,
+ "gpio_147", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART2_TX, 146,
+ "uart2_tx", "mcbsp3_clkx", "gpt11_pwm_evt", NULL,
+ "gpio_146", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART3_CTS_RCTX, 163,
+ "uart3_cts_rctx", NULL, NULL, NULL,
+ "gpio_163", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART3_RTS_SD, 164,
+ "uart3_rts_sd", NULL, NULL, NULL,
+ "gpio_164", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART3_RX_IRRX, 165,
+ "uart3_rx_irrx", NULL, NULL, NULL,
+ "gpio_165", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART3_TX_IRTX, 166,
+ "uart3_tx_irtx", NULL, NULL, NULL,
+ "gpio_166", NULL, NULL, "safe_mode"),
+
+ /* Only on 3630, see omap36xx_cbp_subset for the signals */
+ _OMAP3_MUXENTRY(GPMC_A11, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MREAD, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SREAD, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(GPMC_A11, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Signals different on CBC package compared to the superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBC)
+static struct omap_mux __initdata omap3_cbc_subset[] = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbc_subset NULL
+#endif
+
+/*
+ * Balls for CBC package
+ * 515-pin s-PBGA Package, 0.65mm Ball Pitch (Top), 0.50mm Ball Pitch (Bottom)
+ *
+ * FIXME: What's up with the outdated TI documentation? See:
+ *
+ * http://wiki.davincidsp.com/index.php/Datasheet_Errata_for_OMAP35x_CBC_Package
+ * http://community.ti.com/forums/t/10982.aspx
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBC)
+static struct omap_ball __initdata omap3_cbc_ball[] = {
+ _OMAP3_BALLENTRY(CAM_D0, "ae16", NULL),
+ _OMAP3_BALLENTRY(CAM_D1, "ae15", NULL),
+ _OMAP3_BALLENTRY(CAM_D10, "d25", NULL),
+ _OMAP3_BALLENTRY(CAM_D11, "e26", NULL),
+ _OMAP3_BALLENTRY(CAM_D2, "a24", NULL),
+ _OMAP3_BALLENTRY(CAM_D3, "b24", NULL),
+ _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+ _OMAP3_BALLENTRY(CAM_D5, "c24", NULL),
+ _OMAP3_BALLENTRY(CAM_D6, "p25", NULL),
+ _OMAP3_BALLENTRY(CAM_D7, "p26", NULL),
+ _OMAP3_BALLENTRY(CAM_D8, "n25", NULL),
+ _OMAP3_BALLENTRY(CAM_D9, "n26", NULL),
+ _OMAP3_BALLENTRY(CAM_FLD, "b23", NULL),
+ _OMAP3_BALLENTRY(CAM_HS, "c23", NULL),
+ _OMAP3_BALLENTRY(CAM_PCLK, "c26", NULL),
+ _OMAP3_BALLENTRY(CAM_STROBE, "d26", NULL),
+ _OMAP3_BALLENTRY(CAM_VS, "d23", NULL),
+ _OMAP3_BALLENTRY(CAM_WEN, "a23", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKB, "e25", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX0, "ad17", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX1, "ae18", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY0, "ad16", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY1, "ae17", NULL),
+ _OMAP3_BALLENTRY(DSS_ACBIAS, "f26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA0, "ae21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA1, "ae22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA10, "ac26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA11, "ad26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA12, "aa25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA13, "y25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA14, "aa26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA15, "ab26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA16, "l25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA17, "l26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA18, "m24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA19, "m26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA2, "ae23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA20, "f25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA21, "n24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA22, "ac25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA23, "ab25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA3, "ae24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA4, "ad23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA5, "ad24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA6, "g26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA7, "h25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA8, "h26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA9, "j26", NULL),
+ _OMAP3_BALLENTRY(DSS_HSYNC, "k24", NULL),
+ _OMAP3_BALLENTRY(DSS_PCLK, "g25", NULL),
+ _OMAP3_BALLENTRY(DSS_VSYNC, "m25", NULL),
+ _OMAP3_BALLENTRY(ETK_CLK, "ab2", NULL),
+ _OMAP3_BALLENTRY(ETK_CTL, "ab3", NULL),
+ _OMAP3_BALLENTRY(ETK_D0, "ac3", NULL),
+ _OMAP3_BALLENTRY(ETK_D1, "ad4", NULL),
+ _OMAP3_BALLENTRY(ETK_D10, "ae4", NULL),
+ _OMAP3_BALLENTRY(ETK_D11, "af6", NULL),
+ _OMAP3_BALLENTRY(ETK_D12, "ae6", NULL),
+ _OMAP3_BALLENTRY(ETK_D13, "af7", NULL),
+ _OMAP3_BALLENTRY(ETK_D14, "af9", NULL),
+ _OMAP3_BALLENTRY(ETK_D15, "ae9", NULL),
+ _OMAP3_BALLENTRY(ETK_D2, "ad3", NULL),
+ _OMAP3_BALLENTRY(ETK_D3, "aa3", NULL),
+ _OMAP3_BALLENTRY(ETK_D4, "y3", NULL),
+ _OMAP3_BALLENTRY(ETK_D5, "ab1", NULL),
+ _OMAP3_BALLENTRY(ETK_D6, "ae3", NULL),
+ _OMAP3_BALLENTRY(ETK_D7, "ad2", NULL),
+ _OMAP3_BALLENTRY(ETK_D8, "aa4", NULL),
+ _OMAP3_BALLENTRY(ETK_D9, "v2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A1, "j2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A10, "d2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A2, "h1", NULL),
+ _OMAP3_BALLENTRY(GPMC_A3, "h2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A4, "g2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A5, "f1", NULL),
+ _OMAP3_BALLENTRY(GPMC_A6, "f2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A7, "e1", NULL),
+ _OMAP3_BALLENTRY(GPMC_A8, "e2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A9, "d1", NULL),
+ _OMAP3_BALLENTRY(GPMC_CLK, "n1", "l1"),
+ _OMAP3_BALLENTRY(GPMC_D10, "t1", "n1"),
+ _OMAP3_BALLENTRY(GPMC_D11, "u2", "p2"),
+ _OMAP3_BALLENTRY(GPMC_D12, "u1", "p1"),
+ _OMAP3_BALLENTRY(GPMC_D13, "p1", "m1"),
+ _OMAP3_BALLENTRY(GPMC_D14, "l2", "j2"),
+ _OMAP3_BALLENTRY(GPMC_D15, "m2", "k2"),
+ _OMAP3_BALLENTRY(GPMC_D8, "v1", "r1"),
+ _OMAP3_BALLENTRY(GPMC_D9, "y1", "t1"),
+ _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k2", NULL),
+ _OMAP3_BALLENTRY(GPMC_NBE1, "j1", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS1, "ad1", "w1"),
+ _OMAP3_BALLENTRY(GPMC_NCS2, "a3", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS3, "b6", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS4, "b4", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS5, "c4", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS6, "b5", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS7, "c5", NULL),
+ _OMAP3_BALLENTRY(GPMC_NWP, "ac6", "y5"),
+ _OMAP3_BALLENTRY(GPMC_WAIT1, "ac8", "y8"),
+ _OMAP3_BALLENTRY(GPMC_WAIT2, "b3", NULL),
+ _OMAP3_BALLENTRY(GPMC_WAIT3, "c6", NULL),
+ _OMAP3_BALLENTRY(HDQ_SIO, "j23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_CLK, "w19", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA0, "v20", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA1, "y20", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA2, "v18", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA3, "w20", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA4, "w17", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA5, "y18", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA6, "y19", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA7, "y17", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DIR, "v19", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_NXT, "w18", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_STP, "u20", NULL),
+ _OMAP3_BALLENTRY(I2C2_SCL, "c2", NULL),
+ _OMAP3_BALLENTRY(I2C2_SDA, "c1", NULL),
+ _OMAP3_BALLENTRY(I2C3_SCL, "ab4", NULL),
+ _OMAP3_BALLENTRY(I2C3_SDA, "ac4", NULL),
+ _OMAP3_BALLENTRY(I2C4_SCL, "ad15", NULL),
+ _OMAP3_BALLENTRY(I2C4_SDA, "w16", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU0, "y15", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU1, "y14", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKR, "u19", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKX, "t17", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DR, "t20", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DX, "u17", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSR, "v17", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSX, "p20", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_CLKX, "r18", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DR, "t18", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DX, "r19", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_FSX, "u18", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_CLKX, "u3", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DR, "n3", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DX, "p3", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_FSX, "w3", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_CLKX, "v3", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DR, "u4", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DX, "r3", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_FSX, "t3", NULL),
+ _OMAP3_BALLENTRY(MCBSP_CLKS, "t19", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CLK, "p9", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS0, "r7", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS1, "r8", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS2, "r9", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS3, "t8", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SIMO, "p8", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SOMI, "p7", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CLK, "w7", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS0, "v8", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS1, "v9", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SIMO, "w8", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SOMI, "u8", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CLK, "n19", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CMD, "l18", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT0, "m19", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT1, "m18", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT2, "k18", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT3, "n20", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT4, "m20", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT5, "p17", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT6, "p18", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT7, "p19", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CLK, "w10", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CMD, "r10", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT0, "t10", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT1, "t9", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT2, "u10", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT3, "u9", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT4, "v10", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT5, "m3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT6, "l3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT7, "k3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT0, "f3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT1, "d3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT2, "c3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT3, "e3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT4, "e4", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT5, "g3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT6, "d4", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT1, "ae14", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT2, "w11", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKREQ, "w15", NULL),
+ _OMAP3_BALLENTRY(SYS_NIRQ, "v16", NULL),
+ _OMAP3_BALLENTRY(SYS_NRESWARM, "ad7", "aa5"),
+ _OMAP3_BALLENTRY(SYS_OFF_MODE, "v12", NULL),
+ _OMAP3_BALLENTRY(UART1_CTS, "w2", NULL),
+ _OMAP3_BALLENTRY(UART1_RTS, "r2", NULL),
+ _OMAP3_BALLENTRY(UART1_RX, "h3", NULL),
+ _OMAP3_BALLENTRY(UART1_TX, "l4", NULL),
+ _OMAP3_BALLENTRY(UART2_CTS, "y24", NULL),
+ _OMAP3_BALLENTRY(UART2_RTS, "aa24", NULL),
+ _OMAP3_BALLENTRY(UART2_RX, "ad21", NULL),
+ _OMAP3_BALLENTRY(UART2_TX, "ad22", NULL),
+ _OMAP3_BALLENTRY(UART3_CTS_RCTX, "f23", NULL),
+ _OMAP3_BALLENTRY(UART3_RTS_SD, "f24", NULL),
+ _OMAP3_BALLENTRY(UART3_RX_IRRX, "h24", NULL),
+ _OMAP3_BALLENTRY(UART3_TX_IRTX, "g24", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbc_ball NULL
+#endif
+
+/*
+ * Signals different on CUS package compared to superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CUS)
+static struct omap_mux __initdata omap3_cus_subset[] = {
+ _OMAP3_MUXENTRY(CAM_D10, 109,
+ "cam_d10", NULL, NULL, NULL,
+ "gpio_109", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D11, 110,
+ "cam_d11", NULL, NULL, NULL,
+ "gpio_110", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D2, 101,
+ "cam_d2", NULL, NULL, NULL,
+ "gpio_101", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D3, 102,
+ "cam_d3", NULL, NULL, NULL,
+ "gpio_102", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D4, 103,
+ "cam_d4", NULL, NULL, NULL,
+ "gpio_103", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D5, 104,
+ "cam_d5", NULL, NULL, NULL,
+ "gpio_104", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_FLD, 98,
+ "cam_fld", NULL, "cam_global_reset", NULL,
+ "gpio_98", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_HS, 94,
+ "cam_hs", NULL, NULL, NULL,
+ "gpio_94", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_PCLK, 97,
+ "cam_pclk", NULL, NULL, NULL,
+ "gpio_97", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_STROBE, 126,
+ "cam_strobe", NULL, NULL, NULL,
+ "gpio_126", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_VS, 95,
+ "cam_vs", NULL, NULL, NULL,
+ "gpio_95", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_WEN, 167,
+ "cam_wen", NULL, "cam_shutter", NULL,
+ "gpio_167", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA6, 76,
+ "dss_data6", NULL, "uart1_tx", NULL,
+ "gpio_76", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA7, 77,
+ "dss_data7", NULL, "uart1_rx", NULL,
+ "gpio_77", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA8, 78,
+ "dss_data8", NULL, NULL, NULL,
+ "gpio_78", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA9, 79,
+ "dss_data9", NULL, NULL, NULL,
+ "gpio_79", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_HSYNC, 67,
+ "dss_hsync", NULL, NULL, NULL,
+ "gpio_67", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_PCLK, 66,
+ "dss_pclk", NULL, NULL, NULL,
+ "gpio_66", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(ETK_CLK, 12,
+ "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+ "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
+ _OMAP3_MUXENTRY(ETK_CTL, 13,
+ "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+ "gpio_13", NULL, "hsusb1_tll_clk", NULL),
+ _OMAP3_MUXENTRY(ETK_D0, 14,
+ "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+ "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
+ _OMAP3_MUXENTRY(ETK_D1, 15,
+ "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+ "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
+ _OMAP3_MUXENTRY(ETK_D10, 24,
+ "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+ "gpio_24", NULL, "hsusb2_tll_clk", NULL),
+ _OMAP3_MUXENTRY(ETK_D11, 25,
+ "etk_d11", NULL, NULL, "hsusb2_stp",
+ "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
+ _OMAP3_MUXENTRY(ETK_D12, 26,
+ "etk_d12", NULL, NULL, "hsusb2_dir",
+ "gpio_26", NULL, "hsusb2_tll_dir", NULL),
+ _OMAP3_MUXENTRY(ETK_D13, 27,
+ "etk_d13", NULL, NULL, "hsusb2_nxt",
+ "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
+ _OMAP3_MUXENTRY(ETK_D14, 28,
+ "etk_d14", NULL, NULL, "hsusb2_data0",
+ "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
+ _OMAP3_MUXENTRY(ETK_D15, 29,
+ "etk_d15", NULL, NULL, "hsusb2_data1",
+ "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
+ _OMAP3_MUXENTRY(ETK_D2, 16,
+ "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+ "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
+ _OMAP3_MUXENTRY(ETK_D3, 17,
+ "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+ "gpio_17", NULL, "hsusb1_tll_data7", NULL),
+ _OMAP3_MUXENTRY(ETK_D4, 18,
+ "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+ "gpio_18", NULL, "hsusb1_tll_data4", NULL),
+ _OMAP3_MUXENTRY(ETK_D5, 19,
+ "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+ "gpio_19", NULL, "hsusb1_tll_data5", NULL),
+ _OMAP3_MUXENTRY(ETK_D6, 20,
+ "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+ "gpio_20", NULL, "hsusb1_tll_data6", NULL),
+ _OMAP3_MUXENTRY(ETK_D7, 21,
+ "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+ "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
+ _OMAP3_MUXENTRY(ETK_D8, 22,
+ "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+ "gpio_22", NULL, "hsusb1_tll_dir", NULL),
+ _OMAP3_MUXENTRY(ETK_D9, 23,
+ "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+ "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
+ _OMAP3_MUXENTRY(MCBSP3_CLKX, 142,
+ "mcbsp3_clkx", "uart2_tx", NULL, NULL,
+ "gpio_142", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_DR, 141,
+ "mcbsp3_dr", "uart2_rts", NULL, NULL,
+ "gpio_141", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_DX, 140,
+ "mcbsp3_dx", "uart2_cts", NULL, NULL,
+ "gpio_140", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP3_FSX, 143,
+ "mcbsp3_fsx", "uart2_rx", NULL, NULL,
+ "gpio_143", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT5, 137,
+ "sdmmc2_dat5", "sdmmc2_dir_dat1",
+ "cam_global_reset", "sdmmc3_dat1",
+ "gpio_137", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT6, 138,
+ "sdmmc2_dat6", "sdmmc2_dir_cmd", "cam_shutter", "sdmmc3_dat2",
+ "gpio_138", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC2_DAT7, 139,
+ "sdmmc2_dat7", "sdmmc2_clkin", NULL, "sdmmc3_dat3",
+ "gpio_139", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_CTS, 150,
+ "uart1_cts", NULL, NULL, NULL,
+ "gpio_150", NULL, NULL, "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cus_subset NULL
+#endif
+
+/*
+ * Balls for CUS package
+ * 423-pin s-PBGA Package, 0.65mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CUS)
+static struct omap_ball __initdata omap3_cus_ball[] = {
+ _OMAP3_BALLENTRY(CAM_D0, "ab18", NULL),
+ _OMAP3_BALLENTRY(CAM_D1, "ac18", NULL),
+ _OMAP3_BALLENTRY(CAM_D10, "f21", NULL),
+ _OMAP3_BALLENTRY(CAM_D11, "g21", NULL),
+ _OMAP3_BALLENTRY(CAM_D2, "g19", NULL),
+ _OMAP3_BALLENTRY(CAM_D3, "f19", NULL),
+ _OMAP3_BALLENTRY(CAM_D4, "g20", NULL),
+ _OMAP3_BALLENTRY(CAM_D5, "b21", NULL),
+ _OMAP3_BALLENTRY(CAM_D6, "l24", NULL),
+ _OMAP3_BALLENTRY(CAM_D7, "k24", NULL),
+ _OMAP3_BALLENTRY(CAM_D8, "j23", NULL),
+ _OMAP3_BALLENTRY(CAM_D9, "k23", NULL),
+ _OMAP3_BALLENTRY(CAM_FLD, "h24", NULL),
+ _OMAP3_BALLENTRY(CAM_HS, "a22", NULL),
+ _OMAP3_BALLENTRY(CAM_PCLK, "j19", NULL),
+ _OMAP3_BALLENTRY(CAM_STROBE, "j20", NULL),
+ _OMAP3_BALLENTRY(CAM_VS, "e18", NULL),
+ _OMAP3_BALLENTRY(CAM_WEN, "f18", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKA, "b22", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKB, "c22", NULL),
+ _OMAP3_BALLENTRY(DSS_ACBIAS, "j21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA0, "ac19", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA1, "ab19", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA10, "ac22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA11, "ac23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA12, "ab22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA13, "y22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA14, "w22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA15, "v22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA16, "j22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA17, "g23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA18, "g24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA19, "h23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA2, "ad20", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA20, "d23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA21, "k22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA22, "v21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA23, "w21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA3, "ac20", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA4, "ad21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA5, "ac21", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA6, "d24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA7, "e23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA8, "e24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA9, "f23", NULL),
+ _OMAP3_BALLENTRY(DSS_HSYNC, "e22", NULL),
+ _OMAP3_BALLENTRY(DSS_PCLK, "g22", NULL),
+ _OMAP3_BALLENTRY(DSS_VSYNC, "f22", NULL),
+ _OMAP3_BALLENTRY(ETK_CLK, "ac1", NULL),
+ _OMAP3_BALLENTRY(ETK_CTL, "ad3", NULL),
+ _OMAP3_BALLENTRY(ETK_D0, "ad6", NULL),
+ _OMAP3_BALLENTRY(ETK_D1, "ac6", NULL),
+ _OMAP3_BALLENTRY(ETK_D10, "ac3", NULL),
+ _OMAP3_BALLENTRY(ETK_D11, "ac9", NULL),
+ _OMAP3_BALLENTRY(ETK_D12, "ac10", NULL),
+ _OMAP3_BALLENTRY(ETK_D13, "ad11", NULL),
+ _OMAP3_BALLENTRY(ETK_D14, "ac11", NULL),
+ _OMAP3_BALLENTRY(ETK_D15, "ad12", NULL),
+ _OMAP3_BALLENTRY(ETK_D2, "ac7", NULL),
+ _OMAP3_BALLENTRY(ETK_D3, "ad8", NULL),
+ _OMAP3_BALLENTRY(ETK_D4, "ac5", NULL),
+ _OMAP3_BALLENTRY(ETK_D5, "ad2", NULL),
+ _OMAP3_BALLENTRY(ETK_D6, "ac8", NULL),
+ _OMAP3_BALLENTRY(ETK_D7, "ad9", NULL),
+ _OMAP3_BALLENTRY(ETK_D8, "ac4", NULL),
+ _OMAP3_BALLENTRY(ETK_D9, "ad5", NULL),
+ _OMAP3_BALLENTRY(GPMC_A1, "k4", NULL),
+ _OMAP3_BALLENTRY(GPMC_A10, "g2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A2, "k3", NULL),
+ _OMAP3_BALLENTRY(GPMC_A3, "k2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A4, "j4", NULL),
+ _OMAP3_BALLENTRY(GPMC_A5, "j3", NULL),
+ _OMAP3_BALLENTRY(GPMC_A6, "j2", NULL),
+ _OMAP3_BALLENTRY(GPMC_A7, "j1", NULL),
+ _OMAP3_BALLENTRY(GPMC_A8, "h1", NULL),
+ _OMAP3_BALLENTRY(GPMC_A9, "h2", NULL),
+ _OMAP3_BALLENTRY(GPMC_CLK, "w2", NULL),
+ _OMAP3_BALLENTRY(GPMC_D10, "u1", NULL),
+ _OMAP3_BALLENTRY(GPMC_D11, "r3", NULL),
+ _OMAP3_BALLENTRY(GPMC_D12, "t3", NULL),
+ _OMAP3_BALLENTRY(GPMC_D13, "u2", NULL),
+ _OMAP3_BALLENTRY(GPMC_D14, "v1", NULL),
+ _OMAP3_BALLENTRY(GPMC_D15, "v2", NULL),
+ _OMAP3_BALLENTRY(GPMC_D8, "r2", NULL),
+ _OMAP3_BALLENTRY(GPMC_D9, "t2", NULL),
+ _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "k5", NULL),
+ _OMAP3_BALLENTRY(GPMC_NBE1, "l1", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS3, "d2", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS4, "f4", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS5, "g5", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS6, "f3", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS7, "g4", NULL),
+ _OMAP3_BALLENTRY(GPMC_NWP, "e1", NULL),
+ _OMAP3_BALLENTRY(GPMC_WAIT3, "c2", NULL),
+ _OMAP3_BALLENTRY(HDQ_SIO, "a24", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_CLK, "r21", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA0, "t24", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA1, "t23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA2, "u24", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA3, "u23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA4, "w24", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA5, "v23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA6, "w23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA7, "t22", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DIR, "p23", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_NXT, "r22", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_STP, "r23", NULL),
+ _OMAP3_BALLENTRY(I2C2_SCL, "ac15", NULL),
+ _OMAP3_BALLENTRY(I2C2_SDA, "ac14", NULL),
+ _OMAP3_BALLENTRY(I2C3_SCL, "ac13", NULL),
+ _OMAP3_BALLENTRY(I2C3_SDA, "ac12", NULL),
+ _OMAP3_BALLENTRY(I2C4_SCL, "y16", NULL),
+ _OMAP3_BALLENTRY(I2C4_SDA, "y15", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU0, "ac24", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU1, "ad24", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKR, "w19", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKX, "v18", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DR, "y18", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DX, "w18", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSR, "ab20", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSX, "aa19", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_CLKX, "t21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DR, "v19", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DX, "r20", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_FSX, "v20", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_CLKX, "w4", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DR, "v5", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DX, "v6", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_FSX, "v4", NULL),
+ _OMAP3_BALLENTRY(MCBSP_CLKS, "aa18", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CLK, "t5", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS0, "t6", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS3, "r5", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SIMO, "r4", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SOMI, "t4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CLK, "n5", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS0, "m5", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS1, "m4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SIMO, "n4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SOMI, "n3", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CLK, "m23", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CMD, "l23", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT0, "m22", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT1, "m21", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT2, "m20", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT3, "n23", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT4, "n22", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT5, "n21", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT6, "n20", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT7, "p24", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CLK, "y1", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CMD, "ab5", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT0, "ab3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT1, "y3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT2, "w3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT3, "v3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT4, "ab2", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT5, "aa2", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT6, "y2", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT7, "aa1", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT0, "ab12", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT1, "ac16", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT2, "ad17", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT3, "ad18", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT4, "ac17", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT5, "ab16", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT6, "aa15", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT1, "y7", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT2, "aa6", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKREQ, "y13", NULL),
+ _OMAP3_BALLENTRY(SYS_NIRQ, "w16", NULL),
+ _OMAP3_BALLENTRY(SYS_NRESWARM, "y10", NULL),
+ _OMAP3_BALLENTRY(SYS_OFF_MODE, "ad23", NULL),
+ _OMAP3_BALLENTRY(UART1_CTS, "ac2", NULL),
+ _OMAP3_BALLENTRY(UART1_RTS, "w6", NULL),
+ _OMAP3_BALLENTRY(UART1_RX, "v7", NULL),
+ _OMAP3_BALLENTRY(UART1_TX, "w7", NULL),
+ _OMAP3_BALLENTRY(UART3_CTS_RCTX, "a23", NULL),
+ _OMAP3_BALLENTRY(UART3_RTS_SD, "b23", NULL),
+ _OMAP3_BALLENTRY(UART3_RX_IRRX, "b24", NULL),
+ _OMAP3_BALLENTRY(UART3_TX_IRTX, "c23", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cus_ball NULL
+#endif
+
+/*
+ * Signals different on CBB package comapared to superset
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBB)
+static struct omap_mux __initdata omap3_cbb_subset[] = {
+ _OMAP3_MUXENTRY(CAM_D10, 109,
+ "cam_d10", NULL, NULL, NULL,
+ "gpio_109", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D11, 110,
+ "cam_d11", NULL, NULL, NULL,
+ "gpio_110", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D2, 101,
+ "cam_d2", NULL, NULL, NULL,
+ "gpio_101", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D3, 102,
+ "cam_d3", NULL, NULL, NULL,
+ "gpio_102", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D4, 103,
+ "cam_d4", NULL, NULL, NULL,
+ "gpio_103", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D5, 104,
+ "cam_d5", NULL, NULL, NULL,
+ "gpio_104", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_FLD, 98,
+ "cam_fld", NULL, "cam_global_reset", NULL,
+ "gpio_98", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_HS, 94,
+ "cam_hs", NULL, NULL, NULL,
+ "gpio_94", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_PCLK, 97,
+ "cam_pclk", NULL, NULL, NULL,
+ "gpio_97", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_STROBE, 126,
+ "cam_strobe", NULL, NULL, NULL,
+ "gpio_126", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_VS, 95,
+ "cam_vs", NULL, NULL, NULL,
+ "gpio_95", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_WEN, 167,
+ "cam_wen", NULL, "cam_shutter", NULL,
+ "gpio_167", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA6, 76,
+ "dss_data6", NULL, "uart1_tx", NULL,
+ "gpio_76", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA7, 77,
+ "dss_data7", NULL, "uart1_rx", NULL,
+ "gpio_77", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA8, 78,
+ "dss_data8", NULL, NULL, NULL,
+ "gpio_78", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA9, 79,
+ "dss_data9", NULL, NULL, NULL,
+ "gpio_79", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_HSYNC, 67,
+ "dss_hsync", NULL, NULL, NULL,
+ "gpio_67", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_PCLK, 66,
+ "dss_pclk", NULL, NULL, NULL,
+ "gpio_66", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(ETK_CLK, 12,
+ "etk_clk", "mcbsp5_clkx", "sdmmc3_clk", "hsusb1_stp",
+ "gpio_12", "mm1_rxdp", "hsusb1_tll_stp", NULL),
+ _OMAP3_MUXENTRY(ETK_CTL, 13,
+ "etk_ctl", NULL, "sdmmc3_cmd", "hsusb1_clk",
+ "gpio_13", NULL, "hsusb1_tll_clk", NULL),
+ _OMAP3_MUXENTRY(ETK_D0, 14,
+ "etk_d0", "mcspi3_simo", "sdmmc3_dat4", "hsusb1_data0",
+ "gpio_14", "mm1_rxrcv", "hsusb1_tll_data0", NULL),
+ _OMAP3_MUXENTRY(ETK_D1, 15,
+ "etk_d1", "mcspi3_somi", NULL, "hsusb1_data1",
+ "gpio_15", "mm1_txse0", "hsusb1_tll_data1", NULL),
+ _OMAP3_MUXENTRY(ETK_D10, 24,
+ "etk_d10", NULL, "uart1_rx", "hsusb2_clk",
+ "gpio_24", NULL, "hsusb2_tll_clk", NULL),
+ _OMAP3_MUXENTRY(ETK_D11, 25,
+ "etk_d11", NULL, NULL, "hsusb2_stp",
+ "gpio_25", "mm2_rxdp", "hsusb2_tll_stp", NULL),
+ _OMAP3_MUXENTRY(ETK_D12, 26,
+ "etk_d12", NULL, NULL, "hsusb2_dir",
+ "gpio_26", NULL, "hsusb2_tll_dir", NULL),
+ _OMAP3_MUXENTRY(ETK_D13, 27,
+ "etk_d13", NULL, NULL, "hsusb2_nxt",
+ "gpio_27", "mm2_rxdm", "hsusb2_tll_nxt", NULL),
+ _OMAP3_MUXENTRY(ETK_D14, 28,
+ "etk_d14", NULL, NULL, "hsusb2_data0",
+ "gpio_28", "mm2_rxrcv", "hsusb2_tll_data0", NULL),
+ _OMAP3_MUXENTRY(ETK_D15, 29,
+ "etk_d15", NULL, NULL, "hsusb2_data1",
+ "gpio_29", "mm2_txse0", "hsusb2_tll_data1", NULL),
+ _OMAP3_MUXENTRY(ETK_D2, 16,
+ "etk_d2", "mcspi3_cs0", NULL, "hsusb1_data2",
+ "gpio_16", "mm1_txdat", "hsusb1_tll_data2", NULL),
+ _OMAP3_MUXENTRY(ETK_D3, 17,
+ "etk_d3", "mcspi3_clk", "sdmmc3_dat3", "hsusb1_data7",
+ "gpio_17", NULL, "hsusb1_tll_data7", NULL),
+ _OMAP3_MUXENTRY(ETK_D4, 18,
+ "etk_d4", "mcbsp5_dr", "sdmmc3_dat0", "hsusb1_data4",
+ "gpio_18", NULL, "hsusb1_tll_data4", NULL),
+ _OMAP3_MUXENTRY(ETK_D5, 19,
+ "etk_d5", "mcbsp5_fsx", "sdmmc3_dat1", "hsusb1_data5",
+ "gpio_19", NULL, "hsusb1_tll_data5", NULL),
+ _OMAP3_MUXENTRY(ETK_D6, 20,
+ "etk_d6", "mcbsp5_dx", "sdmmc3_dat2", "hsusb1_data6",
+ "gpio_20", NULL, "hsusb1_tll_data6", NULL),
+ _OMAP3_MUXENTRY(ETK_D7, 21,
+ "etk_d7", "mcspi3_cs1", "sdmmc3_dat7", "hsusb1_data3",
+ "gpio_21", "mm1_txen_n", "hsusb1_tll_data3", NULL),
+ _OMAP3_MUXENTRY(ETK_D8, 22,
+ "etk_d8", "sys_drm_msecure", "sdmmc3_dat6", "hsusb1_dir",
+ "gpio_22", NULL, "hsusb1_tll_dir", NULL),
+ _OMAP3_MUXENTRY(ETK_D9, 23,
+ "etk_d9", "sys_secure_indicator", "sdmmc3_dat5", "hsusb1_nxt",
+ "gpio_23", "mm1_rxdm", "hsusb1_tll_nxt", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbb_subset NULL
+#endif
+
+/*
+ * Balls for CBB package
+ * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBB)
+static struct omap_ball __initdata omap3_cbb_ball[] = {
+ _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
+ _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
+ _OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
+ _OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
+ _OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
+ _OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
+ _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+ _OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
+ _OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
+ _OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
+ _OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
+ _OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
+ _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
+ _OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
+ _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
+ _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
+ _OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
+ _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
+ _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
+ _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
+ _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
+ _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
+ _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
+ _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
+ _OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
+ _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
+ _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
+ _OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
+ _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
+ _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
+ _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
+ _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
+ _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
+ _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
+ _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
+ _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
+ _OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
+ _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
+ _OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
+ _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
+ _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
+ _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
+ _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
+ _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
+ _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
+ _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
+ _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
+ _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
+ _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
+ _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
+ _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
+ _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
+ _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
+ _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
+ _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
+ _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
+ _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
+ _OMAP3_BALLENTRY(GPMC_D8, "h2", "ab3"),
+ _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
+ _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
+ _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
+ _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
+ _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
+ _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
+ _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
+ _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
+ _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
+ _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
+ _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
+ _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
+ _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
+ _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
+ _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT4, "p27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT5, "p26", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT6, "r27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT7, "r25", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
+ _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
+ _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
+ _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
+ _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
+ _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
+ _OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
+ _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
+ _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
+ _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
+ _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
+ _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
+ _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
+ _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
+ _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap3_cbb_ball NULL
+#endif
+
+/*
+ * Signals different on 36XX CBP package comapared to 34XX CBC package
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_OMAP_PACKAGE_CBP)
+static struct omap_mux __initdata omap36xx_cbp_subset[] = {
+ _OMAP3_MUXENTRY(CAM_D0, 99,
+ "cam_d0", NULL, "csi2_dx2", NULL,
+ "gpio_99", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D1, 100,
+ "cam_d1", NULL, "csi2_dy2", NULL,
+ "gpio_100", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D10, 109,
+ "cam_d10", "ssi2_wake", NULL, NULL,
+ "gpio_109", "hw_dbg8", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D2, 101,
+ "cam_d2", "ssi2_rdy_tx", NULL, NULL,
+ "gpio_101", "hw_dbg4", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D3, 102,
+ "cam_d3", "ssi2_dat_rx", NULL, NULL,
+ "gpio_102", "hw_dbg5", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D4, 103,
+ "cam_d4", "ssi2_flag_rx", NULL, NULL,
+ "gpio_103", "hw_dbg6", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_D5, 104,
+ "cam_d5", "ssi2_rdy_rx", NULL, NULL,
+ "gpio_104", "hw_dbg7", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_HS, 94,
+ "cam_hs", "ssi2_dat_tx", NULL, NULL,
+ "gpio_94", "hw_dbg0", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(CAM_VS, 95,
+ "cam_vs", "ssi2_flag_tx", NULL, NULL,
+ "gpio_95", "hw_dbg1", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA0, 70,
+ "dss_data0", "dsi_dx0", "uart1_cts", NULL,
+ "gpio_70", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA1, 71,
+ "dss_data1", "dsi_dy0", "uart1_rts", NULL,
+ "gpio_71", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA2, 72,
+ "dss_data2", "dsi_dx1", NULL, NULL,
+ "gpio_72", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA3, 73,
+ "dss_data3", "dsi_dy1", NULL, NULL,
+ "gpio_73", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA4, 74,
+ "dss_data4", "dsi_dx2", "uart3_rx_irrx", NULL,
+ "gpio_74", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA5, 75,
+ "dss_data5", "dsi_dy2", "uart3_tx_irtx", NULL,
+ "gpio_75", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA6, 76,
+ "dss_data6", NULL, "uart1_tx", "dssvenc656_data6",
+ "gpio_76", "hw_dbg14", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA7, 77,
+ "dss_data7", NULL, "uart1_rx", "dssvenc656_data7",
+ "gpio_77", "hw_dbg15", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA8, 78,
+ "dss_data8", NULL, "uart3_rx_irrx", NULL,
+ "gpio_78", "hw_dbg16", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(DSS_DATA9, 79,
+ "dss_data9", NULL, "uart3_tx_irtx", NULL,
+ "gpio_79", "hw_dbg17", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(ETK_D12, 26,
+ "etk_d12", "sys_drm_msecure", NULL, "hsusb2_dir",
+ "gpio_26", NULL, "hsusb2_tll_dir", "hw_dbg14"),
+ _OMAP3_MUXENTRY(GPMC_A11, 0,
+ "gpmc_a11", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_WAIT2, 64,
+ "gpmc_wait2", NULL, "uart4_tx", NULL,
+ "gpio_64", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(GPMC_WAIT3, 65,
+ "gpmc_wait3", "sys_ndmareq1", "uart4_rx", NULL,
+ "gpio_65", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA0, 125,
+ "hsusb0_data0", NULL, "uart3_tx_irtx", NULL,
+ "gpio_125", "uart2_tx", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA1, 130,
+ "hsusb0_data1", NULL, "uart3_rx_irrx", NULL,
+ "gpio_130", "uart2_rx", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA2, 131,
+ "hsusb0_data2", NULL, "uart3_rts_sd", NULL,
+ "gpio_131", "uart2_rts", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(HSUSB0_DATA3, 169,
+ "hsusb0_data3", NULL, "uart3_cts_rctx", NULL,
+ "gpio_169", "uart2_cts", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_CLKR, 156,
+ "mcbsp1_clkr", "mcspi4_clk", "sim_cd", NULL,
+ "gpio_156", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP1_FSR, 157,
+ "mcbsp1_fsr", "adpllv2d_dithering_en1",
+ "cam_global_reset", NULL,
+ "gpio_157", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_CLKX, 152,
+ "mcbsp4_clkx", "ssi1_dat_rx", NULL, NULL,
+ "gpio_152", "hsusb3_tll_data1", "mm3_txse0", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_DR, 153,
+ "mcbsp4_dr", "ssi1_flag_rx", NULL, NULL,
+ "gpio_153", "hsusb3_tll_data0", "mm3_rxrcv", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_DX, 154,
+ "mcbsp4_dx", "ssi1_rdy_rx", NULL, NULL,
+ "gpio_154", "hsusb3_tll_data2", "mm3_txdat", "safe_mode"),
+ _OMAP3_MUXENTRY(MCBSP4_FSX, 155,
+ "mcbsp4_fsx", "ssi1_wake", NULL, NULL,
+ "gpio_155", "hsusb3_tll_data3", "mm3_txen_n", "safe_mode"),
+ _OMAP3_MUXENTRY(MCSPI1_CS1, 175,
+ "mcspi1_cs1", "adpllv2d_dithering_en2", NULL, "sdmmc3_cmd",
+ "gpio_175", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SAD2D_MBUSFLAG, 0,
+ "sad2d_mbusflag", "mad2d_sbusflag", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD28, 0,
+ "sad2d_mcad28", "mad2d_mcad28", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD29, 0,
+ "sad2d_mcad29", "mad2d_mcad29", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD32, 0,
+ "sad2d_mcad32", "mad2d_mcad32", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD33, 0,
+ "sad2d_mcad33", "mad2d_mcad33", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD34, 0,
+ "sad2d_mcad34", "mad2d_mcad34", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD35, 0,
+ "sad2d_mcad35", "mad2d_mcad35", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MCAD36, 0,
+ "sad2d_mcad36", "mad2d_mcad36", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MREAD, 0,
+ "sad2d_mread", "mad2d_sread", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_MWRITE, 0,
+ "sad2d_mwrite", "mad2d_swrite", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SBUSFLAG, 0,
+ "sad2d_sbusflag", "mad2d_mbusflag", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SREAD, 0,
+ "sad2d_sread", "mad2d_mread", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SAD2D_SWRITE, 0,
+ "sad2d_swrite", "mad2d_mwrite", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP3_MUXENTRY(SDMMC1_CLK, 120,
+ "sdmmc1_clk", "ms_clk", NULL, NULL,
+ "gpio_120", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_CMD, 121,
+ "sdmmc1_cmd", "ms_bs", NULL, NULL,
+ "gpio_121", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT0, 122,
+ "sdmmc1_dat0", "ms_dat0", NULL, NULL,
+ "gpio_122", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT1, 123,
+ "sdmmc1_dat1", "ms_dat1", NULL, NULL,
+ "gpio_123", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT2, 124,
+ "sdmmc1_dat2", "ms_dat2", NULL, NULL,
+ "gpio_124", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDMMC1_DAT3, 125,
+ "sdmmc1_dat3", "ms_dat3", NULL, NULL,
+ "gpio_125", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SDRC_CKE0, 0,
+ "sdrc_cke0", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode_out1"),
+ _OMAP3_MUXENTRY(SDRC_CKE1, 0,
+ "sdrc_cke1", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode_out1"),
+ _OMAP3_MUXENTRY(SIM_IO, 126,
+ "sim_io", "sim_io_low_impedance", NULL, NULL,
+ "gpio_126", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SIM_CLK, 127,
+ "sim_clk", NULL, NULL, NULL,
+ "gpio_127", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SIM_PWRCTRL, 128,
+ "sim_pwrctrl", NULL, NULL, NULL,
+ "gpio_128", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SIM_RST, 129,
+ "sim_rst", NULL, NULL, NULL,
+ "gpio_129", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT0, 2,
+ "sys_boot0", NULL, NULL, "dss_data18",
+ "gpio_2", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT1, 3,
+ "sys_boot1", NULL, NULL, "dss_data19",
+ "gpio_3", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT3, 5,
+ "sys_boot3", NULL, NULL, "dss_data20",
+ "gpio_5", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT4, 6,
+ "sys_boot4", "sdmmc2_dir_dat2", NULL, "dss_data21",
+ "gpio_6", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT5, 7,
+ "sys_boot5", "sdmmc2_dir_dat3", NULL, "dss_data22",
+ "gpio_7", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(SYS_BOOT6, 8,
+ "sys_boot6", NULL, NULL, "dss_data23",
+ "gpio_8", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_CTS, 150,
+ "uart1_cts", "ssi1_rdy_tx", NULL, NULL,
+ "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_RTS, 149,
+ "uart1_rts", "ssi1_flag_tx", NULL, NULL,
+ "gpio_149", NULL, NULL, "safe_mode"),
+ _OMAP3_MUXENTRY(UART1_TX, 148,
+ "uart1_tx", "ssi1_dat_tx", NULL, NULL,
+ "gpio_148", NULL, NULL, "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap36xx_cbp_subset NULL
+#endif
+
+/*
+ * Balls for 36XX CBP package
+ * 515-pin s-PBGA Package, 0.50mm Ball Pitch (Top), 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined (CONFIG_OMAP_PACKAGE_CBP)
+static struct omap_ball __initdata omap36xx_cbp_ball[] = {
+ _OMAP3_BALLENTRY(CAM_D0, "ag17", NULL),
+ _OMAP3_BALLENTRY(CAM_D1, "ah17", NULL),
+ _OMAP3_BALLENTRY(CAM_D10, "b25", NULL),
+ _OMAP3_BALLENTRY(CAM_D11, "c26", NULL),
+ _OMAP3_BALLENTRY(CAM_D2, "b24", NULL),
+ _OMAP3_BALLENTRY(CAM_D3, "c24", NULL),
+ _OMAP3_BALLENTRY(CAM_D4, "d24", NULL),
+ _OMAP3_BALLENTRY(CAM_D5, "a25", NULL),
+ _OMAP3_BALLENTRY(CAM_D6, "k28", NULL),
+ _OMAP3_BALLENTRY(CAM_D7, "l28", NULL),
+ _OMAP3_BALLENTRY(CAM_D8, "k27", NULL),
+ _OMAP3_BALLENTRY(CAM_D9, "l27", NULL),
+ _OMAP3_BALLENTRY(CAM_FLD, "c23", NULL),
+ _OMAP3_BALLENTRY(CAM_HS, "a24", NULL),
+ _OMAP3_BALLENTRY(CAM_PCLK, "c27", NULL),
+ _OMAP3_BALLENTRY(CAM_STROBE, "d25", NULL),
+ _OMAP3_BALLENTRY(CAM_VS, "a23", NULL),
+ _OMAP3_BALLENTRY(CAM_WEN, "b23", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKA, "c25", NULL),
+ _OMAP3_BALLENTRY(CAM_XCLKB, "b26", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX0, "ag19", NULL),
+ _OMAP3_BALLENTRY(CSI2_DX1, "ag18", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY0, "ah19", NULL),
+ _OMAP3_BALLENTRY(CSI2_DY1, "ah18", NULL),
+ _OMAP3_BALLENTRY(DSS_ACBIAS, "e27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA0, "ag22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA1, "ah22", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA10, "ad28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA11, "ad27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA12, "ab28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA13, "ab27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA14, "aa28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA15, "aa27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA16, "g25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA17, "h27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA18, "h26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA19, "h25", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA2, "ag23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA20, "e28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA21, "j26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA22, "ac27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA23, "ac28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA3, "ah23", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA4, "ag24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA5, "ah24", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA6, "e26", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA7, "f28", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA8, "f27", NULL),
+ _OMAP3_BALLENTRY(DSS_DATA9, "g26", NULL),
+ _OMAP3_BALLENTRY(DSS_HSYNC, "d26", NULL),
+ _OMAP3_BALLENTRY(DSS_PCLK, "d28", NULL),
+ _OMAP3_BALLENTRY(DSS_VSYNC, "d27", NULL),
+ _OMAP3_BALLENTRY(ETK_CLK, "af10", NULL),
+ _OMAP3_BALLENTRY(ETK_CTL, "ae10", NULL),
+ _OMAP3_BALLENTRY(ETK_D0, "af11", NULL),
+ _OMAP3_BALLENTRY(ETK_D1, "ag12", NULL),
+ _OMAP3_BALLENTRY(ETK_D10, "ae7", NULL),
+ _OMAP3_BALLENTRY(ETK_D11, "af7", NULL),
+ _OMAP3_BALLENTRY(ETK_D12, "ag7", NULL),
+ _OMAP3_BALLENTRY(ETK_D13, "ah7", NULL),
+ _OMAP3_BALLENTRY(ETK_D14, "ag8", NULL),
+ _OMAP3_BALLENTRY(ETK_D15, "ah8", NULL),
+ _OMAP3_BALLENTRY(ETK_D2, "ah12", NULL),
+ _OMAP3_BALLENTRY(ETK_D3, "ae13", NULL),
+ _OMAP3_BALLENTRY(ETK_D4, "ae11", NULL),
+ _OMAP3_BALLENTRY(ETK_D5, "ah9", NULL),
+ _OMAP3_BALLENTRY(ETK_D6, "af13", NULL),
+ _OMAP3_BALLENTRY(ETK_D7, "ah14", NULL),
+ _OMAP3_BALLENTRY(ETK_D8, "af9", NULL),
+ _OMAP3_BALLENTRY(ETK_D9, "ag9", NULL),
+ _OMAP3_BALLENTRY(GPMC_A1, "n4", "ac15"),
+ _OMAP3_BALLENTRY(GPMC_A10, "k3", "ab19"),
+ _OMAP3_BALLENTRY(GPMC_A11, NULL, "ac20"),
+ _OMAP3_BALLENTRY(GPMC_A2, "m4", "ab15"),
+ _OMAP3_BALLENTRY(GPMC_A3, "l4", "ac16"),
+ _OMAP3_BALLENTRY(GPMC_A4, "k4", "ab16"),
+ _OMAP3_BALLENTRY(GPMC_A5, "t3", "ac17"),
+ _OMAP3_BALLENTRY(GPMC_A6, "r3", "ab17"),
+ _OMAP3_BALLENTRY(GPMC_A7, "n3", "ac18"),
+ _OMAP3_BALLENTRY(GPMC_A8, "m3", "ab18"),
+ _OMAP3_BALLENTRY(GPMC_A9, "l3", "ac19"),
+ _OMAP3_BALLENTRY(GPMC_CLK, "t4", "w2"),
+ _OMAP3_BALLENTRY(GPMC_D10, "p1", "ab4"),
+ _OMAP3_BALLENTRY(GPMC_D11, "r1", "ac4"),
+ _OMAP3_BALLENTRY(GPMC_D12, "r2", "ab6"),
+ _OMAP3_BALLENTRY(GPMC_D13, "t2", "ac6"),
+ _OMAP3_BALLENTRY(GPMC_D14, "w1", "ab7"),
+ _OMAP3_BALLENTRY(GPMC_D15, "y1", "ac7"),
+ _OMAP3_BALLENTRY(GPMC_D9, "k2", "ac3"),
+ _OMAP3_BALLENTRY(GPMC_NBE0_CLE, "g3", "ac12"),
+ _OMAP3_BALLENTRY(GPMC_NBE1, "u3", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS1, "h3", "y1"),
+ _OMAP3_BALLENTRY(GPMC_NCS2, "v8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS3, "u8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS4, "t8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS5, "r8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS6, "p8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NCS7, "n8", NULL),
+ _OMAP3_BALLENTRY(GPMC_NWP, "h1", "ab10"),
+ _OMAP3_BALLENTRY(GPMC_WAIT1, "l8", "ac10"),
+ _OMAP3_BALLENTRY(GPMC_WAIT2, "k8", NULL),
+ _OMAP3_BALLENTRY(GPMC_WAIT3, "j8", NULL),
+ _OMAP3_BALLENTRY(HDQ_SIO, "j25", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_CLK, "t28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA0, "t27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA1, "u28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA2, "u27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA3, "u26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA4, "u25", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA5, "v28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA6, "v27", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DATA7, "v26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_DIR, "r28", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_NXT, "t26", NULL),
+ _OMAP3_BALLENTRY(HSUSB0_STP, "t25", NULL),
+ _OMAP3_BALLENTRY(I2C2_SCL, "af15", NULL),
+ _OMAP3_BALLENTRY(I2C2_SDA, "ae15", NULL),
+ _OMAP3_BALLENTRY(I2C3_SCL, "af14", NULL),
+ _OMAP3_BALLENTRY(I2C3_SDA, "ag14", NULL),
+ _OMAP3_BALLENTRY(I2C4_SCL, "ad26", NULL),
+ _OMAP3_BALLENTRY(I2C4_SDA, "ae26", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU0, "aa11", NULL),
+ _OMAP3_BALLENTRY(JTAG_EMU1, "aa10", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKR, "y21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_CLKX, "w21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DR, "u21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_DX, "v21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSR, "aa21", NULL),
+ _OMAP3_BALLENTRY(MCBSP1_FSX, "k26", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_CLKX, "n21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DR, "r21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_DX, "m21", NULL),
+ _OMAP3_BALLENTRY(MCBSP2_FSX, "p21", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_CLKX, "af5", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DR, "ae6", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_DX, "af6", NULL),
+ _OMAP3_BALLENTRY(MCBSP3_FSX, "ae5", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_CLKX, "ae1", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DR, "ad1", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_DX, "ad2", NULL),
+ _OMAP3_BALLENTRY(MCBSP4_FSX, "ac1", NULL),
+ _OMAP3_BALLENTRY(MCBSP_CLKS, "t21", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CLK, "ab3", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS0, "ac2", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS1, "ac3", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS2, "ab1", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_CS3, "ab2", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SIMO, "ab4", NULL),
+ _OMAP3_BALLENTRY(MCSPI1_SOMI, "aa4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CLK, "aa3", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS0, "y4", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_CS1, "v3", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SIMO, "y2", NULL),
+ _OMAP3_BALLENTRY(MCSPI2_SOMI, "y3", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CLK, "n28", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_CMD, "m27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT0, "n27", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT1, "n26", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT2, "n25", NULL),
+ _OMAP3_BALLENTRY(SDMMC1_DAT3, "p28", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CLK, "ae2", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_CMD, "ag5", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT0, "ah5", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT1, "ah4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT2, "ag4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT3, "af4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT4, "ae4", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT5, "ah3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT6, "af3", NULL),
+ _OMAP3_BALLENTRY(SDMMC2_DAT7, "ae3", NULL),
+ _OMAP3_BALLENTRY(SDRC_CKE0, "h16", "j22"),
+ _OMAP3_BALLENTRY(SDRC_CKE1, "h17", "j23"),
+ _OMAP3_BALLENTRY(SIM_CLK, "p26", NULL),
+ _OMAP3_BALLENTRY(SIM_IO, "p27", NULL),
+ _OMAP3_BALLENTRY(SIM_PWRCTRL, "r27", NULL),
+ _OMAP3_BALLENTRY(SIM_RST, "r25", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT0, "ah26", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT1, "ag26", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT2, "ae14", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT3, "af18", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT4, "af19", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT5, "ae21", NULL),
+ _OMAP3_BALLENTRY(SYS_BOOT6, "af21", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT1, "ag25", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKOUT2, "ae22", NULL),
+ _OMAP3_BALLENTRY(SYS_CLKREQ, "af25", NULL),
+ _OMAP3_BALLENTRY(SYS_NIRQ, "af26", NULL),
+ _OMAP3_BALLENTRY(SYS_NRESWARM, "af24", NULL),
+ _OMAP3_BALLENTRY(SYS_OFF_MODE, "af22", NULL),
+ _OMAP3_BALLENTRY(UART1_CTS, "w8", NULL),
+ _OMAP3_BALLENTRY(UART1_RTS, "aa9", NULL),
+ _OMAP3_BALLENTRY(UART1_RX, "y8", NULL),
+ _OMAP3_BALLENTRY(UART1_TX, "aa8", NULL),
+ _OMAP3_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP3_BALLENTRY(UART2_RTS, "ab25", NULL),
+ _OMAP3_BALLENTRY(UART2_RX, "ad25", NULL),
+ _OMAP3_BALLENTRY(UART2_TX, "aa25", NULL),
+ _OMAP3_BALLENTRY(UART3_CTS_RCTX, "h18", NULL),
+ _OMAP3_BALLENTRY(UART3_RTS_SD, "h19", NULL),
+ _OMAP3_BALLENTRY(UART3_RX_IRRX, "h20", NULL),
+ _OMAP3_BALLENTRY(UART3_TX_IRTX, "h21", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap36xx_cbp_ball NULL
+#endif
+
+int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_mux *package_subset;
+ struct omap_ball *package_balls;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_CBC:
+ package_subset = omap3_cbc_subset;
+ package_balls = omap3_cbc_ball;
+ break;
+ case OMAP_PACKAGE_CBB:
+ package_subset = omap3_cbb_subset;
+ package_balls = omap3_cbb_ball;
+ break;
+ case OMAP_PACKAGE_CUS:
+ package_subset = omap3_cus_subset;
+ package_balls = omap3_cus_ball;
+ break;
+ case OMAP_PACKAGE_CBP:
+ package_subset = omap36xx_cbp_subset;
+ package_balls = omap36xx_cbp_ball;
+ break;
+ default:
+ pr_err("%s Unknown omap package, mux disabled\n", __func__);
+ return -EINVAL;
+ }
+
+ return omap_mux_init("core", 0,
+ OMAP3_CONTROL_PADCONF_MUX_PBASE,
+ OMAP3_CONTROL_PADCONF_MUX_SIZE,
+ omap3_muxmodes, package_subset, board_subset,
+ package_balls);
+}
diff --git a/arch/arm/mach-omap2/mux34xx.h b/arch/arm/mach-omap2/mux34xx.h
new file mode 100644
index 00000000..6543ebf8
--- /dev/null
+++ b/arch/arm/mach-omap2/mux34xx.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP3_CONTROL_PADCONF_MUX_PBASE 0x48002030LU
+
+#define OMAP3_MUX(mode0, mux_value) \
+{ \
+ .reg_offset = (OMAP3_CONTROL_PADCONF_##mode0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/*
+ * OMAP3 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM. Add 0x48002030 to these values to get the
+ * absolute addresses. The name in the macro is the mode-0 name of
+ * the pin. NOTE: These registers are 16-bits wide.
+ *
+ * Note that 34XX TRM uses MMC instead of SDMMC and SAD2D instead
+ * of CHASSIS for some registers. For the defines, we follow the
+ * 36XX naming, and use SDMMC and CHASSIS.
+ */
+#define OMAP3_CONTROL_PADCONF_SDRC_D0_OFFSET 0x000
+#define OMAP3_CONTROL_PADCONF_SDRC_D1_OFFSET 0x002
+#define OMAP3_CONTROL_PADCONF_SDRC_D2_OFFSET 0x004
+#define OMAP3_CONTROL_PADCONF_SDRC_D3_OFFSET 0x006
+#define OMAP3_CONTROL_PADCONF_SDRC_D4_OFFSET 0x008
+#define OMAP3_CONTROL_PADCONF_SDRC_D5_OFFSET 0x00a
+#define OMAP3_CONTROL_PADCONF_SDRC_D6_OFFSET 0x00c
+#define OMAP3_CONTROL_PADCONF_SDRC_D7_OFFSET 0x00e
+#define OMAP3_CONTROL_PADCONF_SDRC_D8_OFFSET 0x010
+#define OMAP3_CONTROL_PADCONF_SDRC_D9_OFFSET 0x012
+#define OMAP3_CONTROL_PADCONF_SDRC_D10_OFFSET 0x014
+#define OMAP3_CONTROL_PADCONF_SDRC_D11_OFFSET 0x016
+#define OMAP3_CONTROL_PADCONF_SDRC_D12_OFFSET 0x018
+#define OMAP3_CONTROL_PADCONF_SDRC_D13_OFFSET 0x01a
+#define OMAP3_CONTROL_PADCONF_SDRC_D14_OFFSET 0x01c
+#define OMAP3_CONTROL_PADCONF_SDRC_D15_OFFSET 0x01e
+#define OMAP3_CONTROL_PADCONF_SDRC_D16_OFFSET 0x020
+#define OMAP3_CONTROL_PADCONF_SDRC_D17_OFFSET 0x022
+#define OMAP3_CONTROL_PADCONF_SDRC_D18_OFFSET 0x024
+#define OMAP3_CONTROL_PADCONF_SDRC_D19_OFFSET 0x026
+#define OMAP3_CONTROL_PADCONF_SDRC_D20_OFFSET 0x028
+#define OMAP3_CONTROL_PADCONF_SDRC_D21_OFFSET 0x02a
+#define OMAP3_CONTROL_PADCONF_SDRC_D22_OFFSET 0x02c
+#define OMAP3_CONTROL_PADCONF_SDRC_D23_OFFSET 0x02e
+#define OMAP3_CONTROL_PADCONF_SDRC_D24_OFFSET 0x030
+#define OMAP3_CONTROL_PADCONF_SDRC_D25_OFFSET 0x032
+#define OMAP3_CONTROL_PADCONF_SDRC_D26_OFFSET 0x034
+#define OMAP3_CONTROL_PADCONF_SDRC_D27_OFFSET 0x036
+#define OMAP3_CONTROL_PADCONF_SDRC_D28_OFFSET 0x038
+#define OMAP3_CONTROL_PADCONF_SDRC_D29_OFFSET 0x03a
+#define OMAP3_CONTROL_PADCONF_SDRC_D30_OFFSET 0x03c
+#define OMAP3_CONTROL_PADCONF_SDRC_D31_OFFSET 0x03e
+#define OMAP3_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x040
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x042
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x044
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x046
+#define OMAP3_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x048
+#define OMAP3_CONTROL_PADCONF_GPMC_A1_OFFSET 0x04a
+#define OMAP3_CONTROL_PADCONF_GPMC_A2_OFFSET 0x04c
+#define OMAP3_CONTROL_PADCONF_GPMC_A3_OFFSET 0x04e
+#define OMAP3_CONTROL_PADCONF_GPMC_A4_OFFSET 0x050
+#define OMAP3_CONTROL_PADCONF_GPMC_A5_OFFSET 0x052
+#define OMAP3_CONTROL_PADCONF_GPMC_A6_OFFSET 0x054
+#define OMAP3_CONTROL_PADCONF_GPMC_A7_OFFSET 0x056
+#define OMAP3_CONTROL_PADCONF_GPMC_A8_OFFSET 0x058
+#define OMAP3_CONTROL_PADCONF_GPMC_A9_OFFSET 0x05a
+#define OMAP3_CONTROL_PADCONF_GPMC_A10_OFFSET 0x05c
+#define OMAP3_CONTROL_PADCONF_GPMC_D0_OFFSET 0x05e
+#define OMAP3_CONTROL_PADCONF_GPMC_D1_OFFSET 0x060
+#define OMAP3_CONTROL_PADCONF_GPMC_D2_OFFSET 0x062
+#define OMAP3_CONTROL_PADCONF_GPMC_D3_OFFSET 0x064
+#define OMAP3_CONTROL_PADCONF_GPMC_D4_OFFSET 0x066
+#define OMAP3_CONTROL_PADCONF_GPMC_D5_OFFSET 0x068
+#define OMAP3_CONTROL_PADCONF_GPMC_D6_OFFSET 0x06a
+#define OMAP3_CONTROL_PADCONF_GPMC_D7_OFFSET 0x06c
+#define OMAP3_CONTROL_PADCONF_GPMC_D8_OFFSET 0x06e
+#define OMAP3_CONTROL_PADCONF_GPMC_D9_OFFSET 0x070
+#define OMAP3_CONTROL_PADCONF_GPMC_D10_OFFSET 0x072
+#define OMAP3_CONTROL_PADCONF_GPMC_D11_OFFSET 0x074
+#define OMAP3_CONTROL_PADCONF_GPMC_D12_OFFSET 0x076
+#define OMAP3_CONTROL_PADCONF_GPMC_D13_OFFSET 0x078
+#define OMAP3_CONTROL_PADCONF_GPMC_D14_OFFSET 0x07a
+#define OMAP3_CONTROL_PADCONF_GPMC_D15_OFFSET 0x07c
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x07e
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x080
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x082
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x084
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x086
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x088
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x08a
+#define OMAP3_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x08c
+#define OMAP3_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x08e
+#define OMAP3_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET 0x090
+#define OMAP3_CONTROL_PADCONF_GPMC_NOE_OFFSET 0x092
+#define OMAP3_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x094
+#define OMAP3_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET 0x096
+#define OMAP3_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x098
+#define OMAP3_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x09a
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x09c
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x09e
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x0a0
+#define OMAP3_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x0a2
+#define OMAP3_CONTROL_PADCONF_DSS_PCLK_OFFSET 0x0a4
+#define OMAP3_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x0a6
+#define OMAP3_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x0a8
+#define OMAP3_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x0aa
+#define OMAP3_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x0ac
+#define OMAP3_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x0ae
+#define OMAP3_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x0b0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x0b2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x0b4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x0b6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x0b8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x0ba
+#define OMAP3_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x0bc
+#define OMAP3_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x0be
+#define OMAP3_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x0c0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x0c2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x0c4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x0c6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x0c8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x0ca
+#define OMAP3_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x0cc
+#define OMAP3_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x0ce
+#define OMAP3_CONTROL_PADCONF_DSS_DATA18_OFFSET 0x0d0
+#define OMAP3_CONTROL_PADCONF_DSS_DATA19_OFFSET 0x0d2
+#define OMAP3_CONTROL_PADCONF_DSS_DATA20_OFFSET 0x0d4
+#define OMAP3_CONTROL_PADCONF_DSS_DATA21_OFFSET 0x0d6
+#define OMAP3_CONTROL_PADCONF_DSS_DATA22_OFFSET 0x0d8
+#define OMAP3_CONTROL_PADCONF_DSS_DATA23_OFFSET 0x0da
+#define OMAP3_CONTROL_PADCONF_CAM_HS_OFFSET 0x0dc
+#define OMAP3_CONTROL_PADCONF_CAM_VS_OFFSET 0x0de
+#define OMAP3_CONTROL_PADCONF_CAM_XCLKA_OFFSET 0x0e0
+#define OMAP3_CONTROL_PADCONF_CAM_PCLK_OFFSET 0x0e2
+#define OMAP3_CONTROL_PADCONF_CAM_FLD_OFFSET 0x0e4
+#define OMAP3_CONTROL_PADCONF_CAM_D0_OFFSET 0x0e6
+#define OMAP3_CONTROL_PADCONF_CAM_D1_OFFSET 0x0e8
+#define OMAP3_CONTROL_PADCONF_CAM_D2_OFFSET 0x0ea
+#define OMAP3_CONTROL_PADCONF_CAM_D3_OFFSET 0x0ec
+#define OMAP3_CONTROL_PADCONF_CAM_D4_OFFSET 0x0ee
+#define OMAP3_CONTROL_PADCONF_CAM_D5_OFFSET 0x0f0
+#define OMAP3_CONTROL_PADCONF_CAM_D6_OFFSET 0x0f2
+#define OMAP3_CONTROL_PADCONF_CAM_D7_OFFSET 0x0f4
+#define OMAP3_CONTROL_PADCONF_CAM_D8_OFFSET 0x0f6
+#define OMAP3_CONTROL_PADCONF_CAM_D9_OFFSET 0x0f8
+#define OMAP3_CONTROL_PADCONF_CAM_D10_OFFSET 0x0fa
+#define OMAP3_CONTROL_PADCONF_CAM_D11_OFFSET 0x0fc
+#define OMAP3_CONTROL_PADCONF_CAM_XCLKB_OFFSET 0x0fe
+#define OMAP3_CONTROL_PADCONF_CAM_WEN_OFFSET 0x100
+#define OMAP3_CONTROL_PADCONF_CAM_STROBE_OFFSET 0x102
+#define OMAP3_CONTROL_PADCONF_CSI2_DX0_OFFSET 0x104
+#define OMAP3_CONTROL_PADCONF_CSI2_DY0_OFFSET 0x106
+#define OMAP3_CONTROL_PADCONF_CSI2_DX1_OFFSET 0x108
+#define OMAP3_CONTROL_PADCONF_CSI2_DY1_OFFSET 0x10a
+#define OMAP3_CONTROL_PADCONF_MCBSP2_FSX_OFFSET 0x10c
+#define OMAP3_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x10e
+#define OMAP3_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x110
+#define OMAP3_CONTROL_PADCONF_MCBSP2_DX_OFFSET 0x112
+#define OMAP3_CONTROL_PADCONF_SDMMC1_CLK_OFFSET 0x114
+#define OMAP3_CONTROL_PADCONF_SDMMC1_CMD_OFFSET 0x116
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET 0x118
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET 0x11a
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET 0x11c
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET 0x11e
+
+/* SDMMC1_DAT4 - DAT7 are SIM_IO SIM_CLK SIM_PWRCTRL and SIM_RST on 36xx */
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT4_OFFSET 0x120
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT5_OFFSET 0x122
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT6_OFFSET 0x124
+#define OMAP3_CONTROL_PADCONF_SDMMC1_DAT7_OFFSET 0x126
+
+#define OMAP3_CONTROL_PADCONF_SDMMC2_CLK_OFFSET 0x128
+#define OMAP3_CONTROL_PADCONF_SDMMC2_CMD_OFFSET 0x12a
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET 0x12c
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET 0x12e
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET 0x130
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET 0x132
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT4_OFFSET 0x134
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT5_OFFSET 0x136
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT6_OFFSET 0x138
+#define OMAP3_CONTROL_PADCONF_SDMMC2_DAT7_OFFSET 0x13a
+#define OMAP3_CONTROL_PADCONF_MCBSP3_DX_OFFSET 0x13c
+#define OMAP3_CONTROL_PADCONF_MCBSP3_DR_OFFSET 0x13e
+#define OMAP3_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET 0x140
+#define OMAP3_CONTROL_PADCONF_MCBSP3_FSX_OFFSET 0x142
+#define OMAP3_CONTROL_PADCONF_UART2_CTS_OFFSET 0x144
+#define OMAP3_CONTROL_PADCONF_UART2_RTS_OFFSET 0x146
+#define OMAP3_CONTROL_PADCONF_UART2_TX_OFFSET 0x148
+#define OMAP3_CONTROL_PADCONF_UART2_RX_OFFSET 0x14a
+#define OMAP3_CONTROL_PADCONF_UART1_TX_OFFSET 0x14c
+#define OMAP3_CONTROL_PADCONF_UART1_RTS_OFFSET 0x14e
+#define OMAP3_CONTROL_PADCONF_UART1_CTS_OFFSET 0x150
+#define OMAP3_CONTROL_PADCONF_UART1_RX_OFFSET 0x152
+#define OMAP3_CONTROL_PADCONF_MCBSP4_CLKX_OFFSET 0x154
+#define OMAP3_CONTROL_PADCONF_MCBSP4_DR_OFFSET 0x156
+#define OMAP3_CONTROL_PADCONF_MCBSP4_DX_OFFSET 0x158
+#define OMAP3_CONTROL_PADCONF_MCBSP4_FSX_OFFSET 0x15a
+#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x15c
+#define OMAP3_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x15e
+#define OMAP3_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x160
+#define OMAP3_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x162
+#define OMAP3_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x164
+#define OMAP3_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x166
+#define OMAP3_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x168
+#define OMAP3_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x16a
+#define OMAP3_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x16c
+#define OMAP3_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x16e
+#define OMAP3_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x170
+#define OMAP3_CONTROL_PADCONF_HSUSB0_CLK_OFFSET 0x172
+#define OMAP3_CONTROL_PADCONF_HSUSB0_STP_OFFSET 0x174
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DIR_OFFSET 0x176
+#define OMAP3_CONTROL_PADCONF_HSUSB0_NXT_OFFSET 0x178
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA0_OFFSET 0x17a
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA1_OFFSET 0x17c
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA2_OFFSET 0x17e
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA3_OFFSET 0x180
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA4_OFFSET 0x182
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA5_OFFSET 0x184
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA6_OFFSET 0x186
+#define OMAP3_CONTROL_PADCONF_HSUSB0_DATA7_OFFSET 0x188
+#define OMAP3_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x18a
+#define OMAP3_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x18c
+#define OMAP3_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x18e
+#define OMAP3_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x190
+#define OMAP3_CONTROL_PADCONF_I2C3_SCL_OFFSET 0x192
+#define OMAP3_CONTROL_PADCONF_I2C3_SDA_OFFSET 0x194
+#define OMAP3_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x196
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CLK_OFFSET 0x198
+#define OMAP3_CONTROL_PADCONF_MCSPI1_SIMO_OFFSET 0x19a
+#define OMAP3_CONTROL_PADCONF_MCSPI1_SOMI_OFFSET 0x19c
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS0_OFFSET 0x19e
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS1_OFFSET 0x1a0
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS2_OFFSET 0x1a2
+#define OMAP3_CONTROL_PADCONF_MCSPI1_CS3_OFFSET 0x1a4
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CLK_OFFSET 0x1a6
+#define OMAP3_CONTROL_PADCONF_MCSPI2_SIMO_OFFSET 0x1a8
+#define OMAP3_CONTROL_PADCONF_MCSPI2_SOMI_OFFSET 0x1aa
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CS0_OFFSET 0x1ac
+#define OMAP3_CONTROL_PADCONF_MCSPI2_CS1_OFFSET 0x1ae
+#define OMAP3_CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x1b0
+#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT2_OFFSET 0x1b2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD0_OFFSET 0x1b4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD1_OFFSET 0x1b6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD2_OFFSET 0x1b8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD3_OFFSET 0x1ba
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD4_OFFSET 0x1bc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD5_OFFSET 0x1be
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD6_OFFSET 0x1c0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD7_OFFSET 0x1c2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD8_OFFSET 0x1c4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD9_OFFSET 0x1c6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD10_OFFSET 0x1c8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD11_OFFSET 0x1ca
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD12_OFFSET 0x1cc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD13_OFFSET 0x1ce
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD14_OFFSET 0x1d0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD15_OFFSET 0x1d2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD16_OFFSET 0x1d4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD17_OFFSET 0x1d6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD18_OFFSET 0x1d8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD19_OFFSET 0x1da
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD20_OFFSET 0x1dc
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD21_OFFSET 0x1de
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD22_OFFSET 0x1e0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD23_OFFSET 0x1e2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD24_OFFSET 0x1e4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD25_OFFSET 0x1e6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD26_OFFSET 0x1e8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD27_OFFSET 0x1ea
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD28_OFFSET 0x1ec
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD29_OFFSET 0x1ee
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD30_OFFSET 0x1f0
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD31_OFFSET 0x1f2
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD32_OFFSET 0x1f4
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD33_OFFSET 0x1f6
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD34_OFFSET 0x1f8
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD35_OFFSET 0x1fa
+#define OMAP3_CONTROL_PADCONF_SAD2D_MCAD36_OFFSET 0x1fc
+
+/* Note that 34xx TRM has SAD2D instead of CHASSIS for these */
+#define OMAP3_CONTROL_PADCONF_CHASSIS_CLK26MI_OFFSET 0x1fe
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESPWRON_OFFSET 0x200
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NRESWARW_OFFSET 0x202
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NIRQ_OFFSET 0x204
+#define OMAP3_CONTROL_PADCONF_CHASSIS_FIQ_OFFSET 0x206
+#define OMAP3_CONTROL_PADCONF_CHASSIS_ARMIRQ_OFFSET 0x208
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IVAIRQ_OFFSET 0x20a
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ0_OFFSET 0x20c
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ1_OFFSET 0x20e
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ2_OFFSET 0x210
+#define OMAP3_CONTROL_PADCONF_CHASSIS_DMAREQ3_OFFSET 0x212
+#define OMAP3_CONTROL_PADCONF_CHASSIS_NTRST_OFFSET 0x214
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TDI_OFFSET 0x216
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TDO_OFFSET 0x218
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TMS_OFFSET 0x21a
+#define OMAP3_CONTROL_PADCONF_CHASSIS_TCK_OFFSET 0x21c
+#define OMAP3_CONTROL_PADCONF_CHASSIS_RTCK_OFFSET 0x21e
+#define OMAP3_CONTROL_PADCONF_CHASSIS_MSTDBY_OFFSET 0x220
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEREQ_OFFSET 0x222
+#define OMAP3_CONTROL_PADCONF_CHASSIS_IDLEACK_OFFSET 0x224
+
+#define OMAP3_CONTROL_PADCONF_SAD2D_MWRITE_OFFSET 0x226
+#define OMAP3_CONTROL_PADCONF_SAD2D_SWRITE_OFFSET 0x228
+#define OMAP3_CONTROL_PADCONF_SAD2D_MREAD_OFFSET 0x22a
+#define OMAP3_CONTROL_PADCONF_SAD2D_SREAD_OFFSET 0x22c
+#define OMAP3_CONTROL_PADCONF_SAD2D_MBUSFLAG_OFFSET 0x22e
+#define OMAP3_CONTROL_PADCONF_SAD2D_SBUSFLAG_OFFSET 0x230
+#define OMAP3_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x232
+#define OMAP3_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x234
+
+/* 36xx only */
+#define OMAP3_CONTROL_PADCONF_GPMC_A11_OFFSET 0x236
+#define OMAP3_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x570
+#define OMAP3_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x572
+#define OMAP3_CONTROL_PADCONF_SDRC_A0_OFFSET 0x574
+#define OMAP3_CONTROL_PADCONF_SDRC_A1_OFFSET 0x576
+#define OMAP3_CONTROL_PADCONF_SDRC_A2_OFFSET 0x578
+#define OMAP3_CONTROL_PADCONF_SDRC_A3_OFFSET 0x57a
+#define OMAP3_CONTROL_PADCONF_SDRC_A4_OFFSET 0x57c
+#define OMAP3_CONTROL_PADCONF_SDRC_A5_OFFSET 0x57e
+#define OMAP3_CONTROL_PADCONF_SDRC_A6_OFFSET 0x580
+#define OMAP3_CONTROL_PADCONF_SDRC_A7_OFFSET 0x582
+#define OMAP3_CONTROL_PADCONF_SDRC_A8_OFFSET 0x584
+#define OMAP3_CONTROL_PADCONF_SDRC_A9_OFFSET 0x586
+#define OMAP3_CONTROL_PADCONF_SDRC_A10_OFFSET 0x588
+#define OMAP3_CONTROL_PADCONF_SDRC_A11_OFFSET 0x58a
+#define OMAP3_CONTROL_PADCONF_SDRC_A12_OFFSET 0x58c
+#define OMAP3_CONTROL_PADCONF_SDRC_A13_OFFSET 0x58e
+#define OMAP3_CONTROL_PADCONF_SDRC_A14_OFFSET 0x590
+#define OMAP3_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x592
+#define OMAP3_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x594
+#define OMAP3_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x596
+#define OMAP3_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x598
+#define OMAP3_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x59a
+#define OMAP3_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x59c
+#define OMAP3_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x59e
+#define OMAP3_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x5a0
+#define OMAP3_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x5a2
+#define OMAP3_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x5a4
+
+/* 36xx only, these are SDMMC1_DAT4 - DAT7 on 34xx */
+#define OMAP3_CONTROL_PADCONF_SIM_IO_OFFSET 0x120
+#define OMAP3_CONTROL_PADCONF_SIM_CLK_OFFSET 0x122
+#define OMAP3_CONTROL_PADCONF_SIM_PWRCTRL_OFFSET 0x124
+#define OMAP3_CONTROL_PADCONF_SIM_RST_OFFSET 0x126
+
+#define OMAP3_CONTROL_PADCONF_ETK_CLK_OFFSET 0x5a8
+#define OMAP3_CONTROL_PADCONF_ETK_CTL_OFFSET 0x5aa
+#define OMAP3_CONTROL_PADCONF_ETK_D0_OFFSET 0x5ac
+#define OMAP3_CONTROL_PADCONF_ETK_D1_OFFSET 0x5ae
+#define OMAP3_CONTROL_PADCONF_ETK_D2_OFFSET 0x5b0
+#define OMAP3_CONTROL_PADCONF_ETK_D3_OFFSET 0x5b2
+#define OMAP3_CONTROL_PADCONF_ETK_D4_OFFSET 0x5b4
+#define OMAP3_CONTROL_PADCONF_ETK_D5_OFFSET 0x5b6
+#define OMAP3_CONTROL_PADCONF_ETK_D6_OFFSET 0x5b8
+#define OMAP3_CONTROL_PADCONF_ETK_D7_OFFSET 0x5ba
+#define OMAP3_CONTROL_PADCONF_ETK_D8_OFFSET 0x5bc
+#define OMAP3_CONTROL_PADCONF_ETK_D9_OFFSET 0x5be
+#define OMAP3_CONTROL_PADCONF_ETK_D10_OFFSET 0x5c0
+#define OMAP3_CONTROL_PADCONF_ETK_D11_OFFSET 0x5c2
+#define OMAP3_CONTROL_PADCONF_ETK_D12_OFFSET 0x5c4
+#define OMAP3_CONTROL_PADCONF_ETK_D13_OFFSET 0x5c6
+#define OMAP3_CONTROL_PADCONF_ETK_D14_OFFSET 0x5c8
+#define OMAP3_CONTROL_PADCONF_ETK_D15_OFFSET 0x5ca
+#define OMAP3_CONTROL_PADCONF_I2C4_SCL_OFFSET 0x9d0
+#define OMAP3_CONTROL_PADCONF_I2C4_SDA_OFFSET 0x9d2
+#define OMAP3_CONTROL_PADCONF_SYS_32K_OFFSET 0x9d4
+#define OMAP3_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x9d6
+#define OMAP3_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x9d8
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT0_OFFSET 0x9da
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT1_OFFSET 0x9dc
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT2_OFFSET 0x9de
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT3_OFFSET 0x9e0
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT4_OFFSET 0x9e2
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT5_OFFSET 0x9e4
+#define OMAP3_CONTROL_PADCONF_SYS_BOOT6_OFFSET 0x9e6
+#define OMAP3_CONTROL_PADCONF_SYS_OFF_MODE_OFFSET 0x9e8
+#define OMAP3_CONTROL_PADCONF_SYS_CLKOUT1_OFFSET 0x9ea
+#define OMAP3_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x9ec
+#define OMAP3_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x9ee
+#define OMAP3_CONTROL_PADCONF_JTAG_TMS_TMSC_OFFSET 0x9f0
+#define OMAP3_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x9f2
+#define OMAP3_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x9f4
+#define OMAP3_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x9f6
+#define OMAP3_CONTROL_PADCONF_SAD2D_SWAKEUP_OFFSET 0xa1c
+#define OMAP3_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0xa1e
+#define OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET 0xa20
+
+#define OMAP3_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP3_CONTROL_PADCONF_JTAG_TDO_OFFSET + 0x2)
diff --git a/arch/arm/mach-omap2/mux44xx.c b/arch/arm/mach-omap2/mux44xx.c
new file mode 100644
index 00000000..f5a74daa
--- /dev/null
+++ b/arch/arm/mach-omap2/mux44xx.c
@@ -0,0 +1,1356 @@
+/*
+ * OMAP44xx ES1.0 pin mux definition
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * - Based on mux34xx.c done by Tony Lindgren <tony@atomide.com>
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP4_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP4_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap4 ES1.0
+ */
+static struct omap_mux __initdata omap4_core_muxmodes[] = {
+ _OMAP4_MUXENTRY(GPMC_AD0, 0, "gpmc_ad0", "sdmmc2_dat0", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD1, 0, "gpmc_ad1", "sdmmc2_dat1", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD2, 0, "gpmc_ad2", "sdmmc2_dat2", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD3, 0, "gpmc_ad3", "sdmmc2_dat3", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD4, 0, "gpmc_ad4", "sdmmc2_dat4",
+ "sdmmc2_dir_dat0", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD5, 0, "gpmc_ad5", "sdmmc2_dat5",
+ "sdmmc2_dir_dat1", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD6, 0, "gpmc_ad6", "sdmmc2_dat6",
+ "sdmmc2_dir_cmd", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD7, 0, "gpmc_ad7", "sdmmc2_dat7",
+ "sdmmc2_clk_fdbk", NULL, NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
+ "gpio_32", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
+ "gpio_33", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
+ "gpio_34", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
+ "gpio_35", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
+ "gpio_36", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
+ "gpio_37", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
+ "gpio_38", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
+ "gpio_39", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
+ "gpio_40", "venc_656_data0", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A17, 41, "gpmc_a17", "kpd_row5", "c2c_datain1",
+ "gpio_41", "venc_656_data1", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A18, 42, "gpmc_a18", "kpd_row6", "c2c_datain2",
+ "gpio_42", "venc_656_data2", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A19, 43, "gpmc_a19", "kpd_row7", "c2c_datain3",
+ "gpio_43", "venc_656_data3", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A20, 44, "gpmc_a20", "kpd_col4", "c2c_datain4",
+ "gpio_44", "venc_656_data4", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A21, 45, "gpmc_a21", "kpd_col5", "c2c_datain5",
+ "gpio_45", "venc_656_data5", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A22, 46, "gpmc_a22", "kpd_col6", "c2c_datain6",
+ "gpio_46", "venc_656_data6", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A23, 47, "gpmc_a23", "kpd_col7", "c2c_datain7",
+ "gpio_47", "venc_656_data7", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", NULL, "c2c_clkout0",
+ "gpio_48", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A25, 49, "gpmc_a25", NULL, "c2c_clkout1",
+ "gpio_49", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS0, 50, "gpmc_ncs0", NULL, NULL, "gpio_50",
+ "sys_ndmareq0", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NCS1, 51, "gpmc_ncs1", NULL, "c2c_dataout6",
+ "gpio_51", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", NULL, "c2c_dataout7",
+ "gpio_52", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS3, 53, "gpmc_ncs3", "gpmc_dir",
+ "c2c_dataout4", "gpio_53", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NWP, 54, "gpmc_nwp", "dsi1_te0", NULL, "gpio_54",
+ "sys_ndmareq1", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
+ "sys_ndmareq2", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
+ "gpio_56", "sys_ndmareq3", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NOE, 0, "gpmc_noe", "sdmmc2_clk", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NWE, 0, "gpmc_nwe", "sdmmc2_cmd", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE0_CLE, 59, "gpmc_nbe0_cle", "dsi2_te0", NULL,
+ "gpio_59", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NBE1, 60, "gpmc_nbe1", NULL, "c2c_dataout5",
+ "gpio_60", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_WAIT0, 61, "gpmc_wait0", "dsi2_te1", NULL,
+ "gpio_61", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_WAIT1, 62, "gpmc_wait1", NULL, "c2c_dataout2",
+ "gpio_62", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA11, 100, "c2c_data11", "usbc1_icusb_txen",
+ "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA12, 101, "c2c_data12", "dsi1_te0",
+ "c2c_clkin0", "gpio_101", "sys_ndmareq1", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA13, 102, "c2c_data13", "dsi1_te1",
+ "c2c_clkin1", "gpio_102", "sys_ndmareq2", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA14, 103, "c2c_data14", "dsi2_te0",
+ "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(C2C_DATA15, 104, "c2c_data15", "dsi2_te1",
+ "c2c_dataout1", "gpio_104", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_HPD, 63, "hdmi_hpd", NULL, NULL, "gpio_63", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_CEC, 64, "hdmi_cec", NULL, NULL, "gpio_64", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SCL, 65, "hdmi_ddc_scl", NULL, NULL,
+ "gpio_65", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDMI_DDC_SDA, 66, "hdmi_ddc_sda", NULL, NULL,
+ "gpio_66", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX0, 0, "csi21_dx0", NULL, NULL, "gpi_67", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY0, 0, "csi21_dy0", NULL, NULL, "gpi_68", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX1, 0, "csi21_dx1", NULL, NULL, "gpi_69", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY1, 0, "csi21_dy1", NULL, NULL, "gpi_70", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX2, 0, "csi21_dx2", NULL, NULL, "gpi_71", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY2, 0, "csi21_dy2", NULL, NULL, "gpi_72", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX3, 0, "csi21_dx3", NULL, NULL, "gpi_73", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY3, 0, "csi21_dy3", NULL, NULL, "gpi_74", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DX4, 0, "csi21_dx4", NULL, NULL, "gpi_75", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI21_DY4, 0, "csi21_dy4", NULL, NULL, "gpi_76", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX0, 0, "csi22_dx0", NULL, NULL, "gpi_77", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY0, 0, "csi22_dy0", NULL, NULL, "gpi_78", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DX1, 0, "csi22_dx1", NULL, NULL, "gpi_79", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CSI22_DY1, 0, "csi22_dy1", NULL, NULL, "gpi_80", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_SHUTTER, 81, "cam_shutter", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_STROBE, 82, "cam_strobe", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(CAM_GLOBALRESET, 83, "cam_globalreset", NULL, NULL,
+ "gpio_83", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_CLK, 84, "usbb1_ulpitll_clk",
+ "hsi1_cawake", NULL, "gpio_84", "usbb1_ulpiphy_clk",
+ NULL, "hw_dbg20", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_STP, 85, "usbb1_ulpitll_stp",
+ "hsi1_cadata", "mcbsp4_clkr", "gpio_85",
+ "usbb1_ulpiphy_stp", "usbb1_mm_rxdp", "hw_dbg21",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DIR, 86, "usbb1_ulpitll_dir",
+ "hsi1_caflag", "mcbsp4_fsr", "gpio_86",
+ "usbb1_ulpiphy_dir", NULL, "hw_dbg22", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_NXT, 87, "usbb1_ulpitll_nxt",
+ "hsi1_acready", "mcbsp4_fsx", "gpio_87",
+ "usbb1_ulpiphy_nxt", "usbb1_mm_rxdm", "hw_dbg23",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
+ "hsi1_acwake", "mcbsp4_clkx", "gpio_88",
+ "usbb1_ulpiphy_dat0", "usbb1_mm_rxrcv", "hw_dbg24",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
+ "hsi1_acdata", "mcbsp4_dx", "gpio_89",
+ "usbb1_ulpiphy_dat1", "usbb1_mm_txse0", "hw_dbg25",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
+ "hsi1_acflag", "mcbsp4_dr", "gpio_90",
+ "usbb1_ulpiphy_dat2", "usbb1_mm_txdat", "hw_dbg26",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
+ "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
+ "usbb1_mm_txen", "hw_dbg27", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT4, 92, "usbb1_ulpitll_dat4",
+ "dmtimer8_pwm_evt", "abe_mcbsp3_dr", "gpio_92",
+ "usbb1_ulpiphy_dat4", NULL, "hw_dbg28", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT5, 93, "usbb1_ulpitll_dat5",
+ "dmtimer9_pwm_evt", "abe_mcbsp3_dx", "gpio_93",
+ "usbb1_ulpiphy_dat5", NULL, "hw_dbg29", "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT6, 94, "usbb1_ulpitll_dat6",
+ "dmtimer10_pwm_evt", "abe_mcbsp3_clkx", "gpio_94",
+ "usbb1_ulpiphy_dat6", "abe_dmic_din3", "hw_dbg30",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT7, 95, "usbb1_ulpitll_dat7",
+ "dmtimer11_pwm_evt", "abe_mcbsp3_fsx", "gpio_95",
+ "usbb1_ulpiphy_dat7", "abe_dmic_clk3", "hw_dbg31",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_DATA, 96, "usbb1_hsic_data", NULL, NULL,
+ "gpio_96", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_HSIC_STROBE, 97, "usbb1_hsic_strobe", NULL,
+ NULL, "gpio_97", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DP, 98, "usbc1_icusb_dp", NULL, NULL,
+ "gpio_98", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBC1_ICUSB_DM, 99, "usbc1_icusb_dm", NULL, NULL,
+ "gpio_99", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CLK, 100, "sdmmc1_clk", NULL, "dpm_emu19",
+ "gpio_100", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_CMD, 101, "sdmmc1_cmd", NULL, "uart1_rx",
+ "gpio_101", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT0, 102, "sdmmc1_dat0", NULL, "dpm_emu18",
+ "gpio_102", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT1, 103, "sdmmc1_dat1", NULL, "dpm_emu17",
+ "gpio_103", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT2, 104, "sdmmc1_dat2", NULL, "dpm_emu16",
+ "gpio_104", "jtag_tms_tmsc", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT3, 105, "sdmmc1_dat3", NULL, "dpm_emu15",
+ "gpio_105", "jtag_tck", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT4, 106, "sdmmc1_dat4", NULL, NULL,
+ "gpio_106", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT5, 107, "sdmmc1_dat5", NULL, NULL,
+ "gpio_107", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT6, 108, "sdmmc1_dat6", NULL, NULL,
+ "gpio_108", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC1_DAT7, 109, "sdmmc1_dat7", NULL, NULL,
+ "gpio_109", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_CLKX, 110, "abe_mcbsp2_clkx", "mcspi2_clk",
+ "abe_mcasp_ahclkx", "gpio_110", "usbb2_mm_rxdm",
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DR, 111, "abe_mcbsp2_dr", "mcspi2_somi",
+ "abe_mcasp_axr", "gpio_111", "usbb2_mm_rxdp", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_DX, 112, "abe_mcbsp2_dx", "mcspi2_simo",
+ "abe_mcasp_amute", "gpio_112", "usbb2_mm_rxrcv", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP2_FSX, 113, "abe_mcbsp2_fsx", "mcspi2_cs0",
+ "abe_mcasp_afsx", "gpio_113", "usbb2_mm_txen", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_CLKX, 114, "abe_mcbsp1_clkx",
+ "abe_slimbus1_clock", NULL, "gpio_114", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DR, 115, "abe_mcbsp1_dr",
+ "abe_slimbus1_data", NULL, "gpio_115", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_DX, 116, "abe_mcbsp1_dx", "sdmmc3_dat2",
+ "abe_mcasp_aclkx", "gpio_116", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_MCBSP1_FSX, 117, "abe_mcbsp1_fsx", "sdmmc3_dat3",
+ "abe_mcasp_amutein", "gpio_117", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_UL_DATA, 0, "abe_pdm_ul_data",
+ "abe_mcbsp3_dr", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_DL_DATA, 0, "abe_pdm_dl_data",
+ "abe_mcbsp3_dx", NULL, NULL, NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_FRAME, 0, "abe_pdm_frame", "abe_mcbsp3_clkx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_PDM_LB_CLK, 0, "abe_pdm_lb_clk", "abe_mcbsp3_fsx",
+ NULL, NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_CLKS, 118, "abe_clks", NULL, NULL, "gpio_118",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
+ "gpio_119", "usbb2_mm_txse0", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
+ "gpio_120", "usbb2_mm_txdat", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
+ NULL, "gpio_121", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
+ "abe_dmic_clk2", "gpio_122", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_CTS, 123, "uart2_cts", "sdmmc3_clk", NULL,
+ "gpio_123", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RTS, 124, "uart2_rts", "sdmmc3_cmd", NULL,
+ "gpio_124", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_RX, 125, "uart2_rx", "sdmmc3_dat0", NULL,
+ "gpio_125", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART2_TX, 126, "uart2_tx", "sdmmc3_dat1", NULL,
+ "gpio_126", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(HDQ_SIO, 127, "hdq_sio", "i2c3_sccb", "i2c2_sccb",
+ "gpio_127", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C1_SCL, 0, "i2c1_scl", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C1_SDA, 0, "i2c1_sda", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(I2C2_SCL, 128, "i2c2_scl", "uart1_rx", NULL,
+ "gpio_128", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C2_SDA, 129, "i2c2_sda", "uart1_tx", NULL,
+ "gpio_129", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SCL, 130, "i2c3_scl", NULL, NULL, "gpio_130",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C3_SDA, 131, "i2c3_sda", NULL, NULL, "gpio_131",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SCL, 132, "i2c4_scl", NULL, NULL, "gpio_132",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(I2C4_SDA, 133, "i2c4_sda", NULL, NULL, "gpio_133",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CLK, 134, "mcspi1_clk", NULL, NULL, "gpio_134",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SOMI, 135, "mcspi1_somi", NULL, NULL,
+ "gpio_135", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_SIMO, 136, "mcspi1_simo", NULL, NULL,
+ "gpio_136", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS0, 137, "mcspi1_cs0", NULL, NULL, "gpio_137",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS1, 138, "mcspi1_cs1", "uart1_rx", NULL,
+ "gpio_138", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS2, 139, "mcspi1_cs2", "uart1_cts",
+ "slimbus2_clock", "gpio_139", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI1_CS3, 140, "mcspi1_cs3", "uart1_rts",
+ "slimbus2_data", "gpio_140", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_CTS_RCTX, 141, "uart3_cts_rctx", "uart1_tx",
+ NULL, "gpio_141", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RTS_SD, 142, "uart3_rts_sd", NULL, NULL,
+ "gpio_142", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_RX_IRRX, 143, "uart3_rx_irrx",
+ "dmtimer8_pwm_evt", NULL, "gpio_143", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART3_TX_IRTX, 144, "uart3_tx_irtx",
+ "dmtimer9_pwm_evt", NULL, "gpio_144", NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
+ "usbc1_icusb_dp", "gpio_145", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
+ "usbc1_icusb_dm", "gpio_146", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
+ "usbc1_icusb_rcv", "gpio_147", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
+ "usbc1_icusb_txen", "gpio_148", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
+ "gpio_149", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
+ "gpio_150", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk", NULL,
+ "gpio_151", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd", NULL,
+ "gpio_152", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0", NULL,
+ "gpio_153", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3", NULL,
+ "gpio_154", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", NULL,
+ "gpio_155", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", NULL,
+ "gpio_156", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_CLK, 157, "usbb2_ulpitll_clk",
+ "usbb2_ulpiphy_clk", "sdmmc4_cmd", "gpio_157",
+ "hsi2_cawake", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
+ "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
+ "hsi2_cadata", "dispc2_data23", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
+ "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
+ "hsi2_caflag", "dispc2_data22", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
+ "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
+ "hsi2_acready", "dispc2_data21", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
+ "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
+ "hsi2_acwake", "dispc2_data20", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
+ "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
+ "hsi2_acdata", "dispc2_data19", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
+ "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
+ "hsi2_acflag", "dispc2_data18", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
+ "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
+ "hsi2_caready", "dispc2_data15", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
+ "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
+ "mcspi3_somi", "dispc2_data14", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
+ "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
+ "mcspi3_cs0", "dispc2_data13", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
+ "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
+ "mcspi3_simo", "dispc2_data12", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
+ "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
+ "mcspi3_clk", "dispc2_data11", NULL, "reserved"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_DATA, 169, "usbb2_hsic_data", NULL, NULL,
+ "gpio_169", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_HSIC_STROBE, 170, "usbb2_hsic_strobe", NULL,
+ NULL, "gpio_170", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX0, 171, "unipro_tx0", "kpd_col0", NULL,
+ "gpio_171", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY0, 172, "unipro_ty0", "kpd_col1", NULL,
+ "gpio_172", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX1, 173, "unipro_tx1", "kpd_col2", NULL,
+ "gpio_173", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY1, 174, "unipro_ty1", "kpd_col3", NULL,
+ "gpio_174", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TX2, 0, "unipro_tx2", "kpd_col4", NULL,
+ "gpio_0", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_TY2, 1, "unipro_ty2", "kpd_col5", NULL,
+ "gpio_1", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX0, 0, "unipro_rx0", "kpd_row0", NULL,
+ "gpi_175", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY0, 0, "unipro_ry0", "kpd_row1", NULL,
+ "gpi_176", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX1, 0, "unipro_rx1", "kpd_row2", NULL,
+ "gpi_177", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY1, 0, "unipro_ry1", "kpd_row3", NULL,
+ "gpi_178", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RX2, 0, "unipro_rx2", "kpd_row4", NULL,
+ "gpi_2", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UNIPRO_RY2, 0, "unipro_ry2", "kpd_row5", NULL,
+ "gpi_3", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_CE, 0, "usba0_otg_ce", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(USBA0_OTG_DP, 179, "usba0_otg_dp", "uart3_rx_irrx",
+ "uart2_rx", "gpio_179", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_DM, 180, "usba0_otg_dm", "uart3_tx_irtx",
+ "uart2_tx", "gpio_180", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK1_OUT, 181, "fref_clk1_out", NULL, NULL,
+ "gpio_181", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK2_OUT, 182, "fref_clk2_out", NULL, NULL,
+ "gpio_182", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ1, 0, "sys_nirq1", NULL, NULL, NULL, NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_NIRQ2, 183, "sys_nirq2", NULL, NULL, "gpio_183",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT0, 184, "sys_boot0", NULL, NULL, "gpio_184",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT1, 185, "sys_boot1", NULL, NULL, "gpio_185",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT2, 186, "sys_boot2", NULL, NULL, "gpio_186",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT3, 187, "sys_boot3", NULL, NULL, "gpio_187",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT4, 188, "sys_boot4", NULL, NULL, "gpio_188",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT5, 189, "sys_boot5", NULL, NULL, "gpio_189",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU0, 11, "dpm_emu0", NULL, NULL, "gpio_11", NULL,
+ NULL, "hw_dbg0", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU1, 12, "dpm_emu1", NULL, NULL, "gpio_12", NULL,
+ NULL, "hw_dbg1", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
+ "gpio_13", NULL, "dispc2_fid", "hw_dbg2", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
+ "gpio_14", NULL, "dispc2_data10", "hw_dbg3",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
+ "gpio_15", NULL, "dispc2_data9", "hw_dbg4",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
+ "gpio_16", "rfbi_te_vsync0", "dispc2_data16",
+ "hw_dbg5", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
+ "uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
+ "dispc2_data17", "hw_dbg6", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
+ "uart3_rx_irrx", "gpio_18", "rfbi_cs0",
+ "dispc2_hsync", "hw_dbg7", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
+ "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
+ "hw_dbg8", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
+ "uart3_cts_rctx", "gpio_20", "rfbi_we",
+ "dispc2_vsync", "hw_dbg9", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
+ NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
+ "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
+ NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
+ "hw_dbg11", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
+ NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
+ "hw_dbg12", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
+ NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
+ "hw_dbg13", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
+ "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
+ "hw_dbg14", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
+ NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
+ "hw_dbg15", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
+ "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
+ "hw_dbg16", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
+ "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
+ "hw_dbg17", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
+ "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
+ "hw_dbg18", "reserved"),
+ _OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
+ "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
+ "hw_dbg19", "reserved"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBL package
+ * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBL)
+static struct omap_ball __initdata omap4_core_cbl_ball[] = {
+ _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
+ _OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
+ _OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA11, "d23", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA12, "a24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA13, "b24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA14, "c24", NULL),
+ _OMAP4_BALLENTRY(C2C_DATA15, "d24", NULL),
+ _OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
+ _OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
+ _OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
+ _OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
+ _OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
+ _OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
+ _OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
+ _OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
+ _OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
+ _OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
+ _OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
+ _OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
+ _OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
+ _OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
+ _OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
+ _OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
+ _OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
+ _OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
+ _OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
+ _OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
+ _OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
+ _OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX0, "g26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY0, "g25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX1, "h26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY1, "h25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TX2, "j27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_TY2, "h27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX0, "j26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY0, "j25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX1, "k26", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY1, "k25", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RX2, "l27", NULL),
+ _OMAP4_BALLENTRY(UNIPRO_RY2, "k27", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_core_cbl_ball NULL
+#endif
+
+/*
+ * Signals different on ES2.0 compared to superset
+ */
+static struct omap_mux __initdata omap4_es2_core_subset[] = {
+ _OMAP4_MUXENTRY(GPMC_AD8, 32, "gpmc_ad8", "kpd_row0", "c2c_data15",
+ "gpio_32", NULL, "sdmmc1_dat0", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD9, 33, "gpmc_ad9", "kpd_row1", "c2c_data14",
+ "gpio_33", NULL, "sdmmc1_dat1", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD10, 34, "gpmc_ad10", "kpd_row2", "c2c_data13",
+ "gpio_34", NULL, "sdmmc1_dat2", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD11, 35, "gpmc_ad11", "kpd_row3", "c2c_data12",
+ "gpio_35", NULL, "sdmmc1_dat3", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD12, 36, "gpmc_ad12", "kpd_col0", "c2c_data11",
+ "gpio_36", NULL, "sdmmc1_dat4", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD13, 37, "gpmc_ad13", "kpd_col1", "c2c_data10",
+ "gpio_37", NULL, "sdmmc1_dat5", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD14, 38, "gpmc_ad14", "kpd_col2", "c2c_data9",
+ "gpio_38", NULL, "sdmmc1_dat6", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_AD15, 39, "gpmc_ad15", "kpd_col3", "c2c_data8",
+ "gpio_39", NULL, "sdmmc1_dat7", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_A16, 40, "gpmc_a16", "kpd_row4", "c2c_datain0",
+ "gpio_40", "venc_656_data0", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_A24, 48, "gpmc_a24", "kpd_col8", "c2c_clkout0",
+ "gpio_48", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS2, 52, "gpmc_ncs2", "kpd_row8",
+ "c2c_dataout7", "gpio_52", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_CLK, 55, "gpmc_clk", NULL, NULL, "gpio_55",
+ "sys_ndmareq2", "sdmmc1_cmd", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_NADV_ALE, 56, "gpmc_nadv_ale", "dsi1_te1", NULL,
+ "gpio_56", "sys_ndmareq3", "sdmmc1_clk", NULL, NULL),
+ _OMAP4_MUXENTRY(GPMC_WAIT2, 100, "gpmc_wait2", "usbc1_icusb_txen",
+ "c2c_dataout3", "gpio_100", "sys_ndmareq0", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS4, 101, "gpmc_ncs4", "dsi1_te0", "c2c_clkin0",
+ "gpio_101", "sys_ndmareq1", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS5, 102, "gpmc_ncs5", "dsi1_te1", "c2c_clkin1",
+ "gpio_102", "sys_ndmareq2", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS6, 103, "gpmc_ncs6", "dsi2_te0",
+ "c2c_dataout0", "gpio_103", "sys_ndmareq3", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(GPMC_NCS7, 104, "gpmc_ncs7", "dsi2_te1",
+ "c2c_dataout1", "gpio_104", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT0, 88, "usbb1_ulpitll_dat0",
+ "hsi1_acwake", "mcbsp4_clkx", "gpio_88",
+ "usbb1_ulpiphy_dat0", "usbb1_mm_txen", "hw_dbg24",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT1, 89, "usbb1_ulpitll_dat1",
+ "hsi1_acdata", "mcbsp4_dx", "gpio_89",
+ "usbb1_ulpiphy_dat1", "usbb1_mm_txdat", "hw_dbg25",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT2, 90, "usbb1_ulpitll_dat2",
+ "hsi1_acflag", "mcbsp4_dr", "gpio_90",
+ "usbb1_ulpiphy_dat2", "usbb1_mm_txse0", "hw_dbg26",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB1_ULPITLL_DAT3, 91, "usbb1_ulpitll_dat3",
+ "hsi1_caready", NULL, "gpio_91", "usbb1_ulpiphy_dat3",
+ "usbb1_mm_rxrcv", "hw_dbg27", "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_CLK1, 119, "abe_dmic_clk1", NULL, NULL,
+ "gpio_119", "usbb2_mm_txse0", "uart4_cts", NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN1, 120, "abe_dmic_din1", NULL, NULL,
+ "gpio_120", "usbb2_mm_txdat", "uart4_rts", NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN2, 121, "abe_dmic_din2", "slimbus2_clock",
+ "abe_mcasp_axr", "gpio_121", NULL,
+ "dmtimer11_pwm_evt", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(ABE_DMIC_DIN3, 122, "abe_dmic_din3", "slimbus2_data",
+ "abe_dmic_clk2", "gpio_122", NULL, "dmtimer9_pwm_evt",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CLK, 145, "sdmmc5_clk", "mcspi2_clk",
+ "usbc1_icusb_dp", "gpio_145", NULL, "sdmmc2_clk",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_CMD, 146, "sdmmc5_cmd", "mcspi2_simo",
+ "usbc1_icusb_dm", "gpio_146", NULL, "sdmmc2_cmd",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT0, 147, "sdmmc5_dat0", "mcspi2_somi",
+ "usbc1_icusb_rcv", "gpio_147", NULL, "sdmmc2_dat0",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT1, 148, "sdmmc5_dat1", NULL,
+ "usbc1_icusb_txen", "gpio_148", NULL, "sdmmc2_dat1",
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT2, 149, "sdmmc5_dat2", "mcspi2_cs1", NULL,
+ "gpio_149", NULL, "sdmmc2_dat2", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SDMMC5_DAT3, 150, "sdmmc5_dat3", "mcspi2_cs0", NULL,
+ "gpio_150", NULL, "sdmmc2_dat3", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CLK, 151, "mcspi4_clk", "sdmmc4_clk",
+ "kpd_col6", "gpio_151", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SIMO, 152, "mcspi4_simo", "sdmmc4_cmd",
+ "kpd_col7", "gpio_152", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_SOMI, 153, "mcspi4_somi", "sdmmc4_dat0",
+ "kpd_row6", "gpio_153", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(MCSPI4_CS0, 154, "mcspi4_cs0", "sdmmc4_dat3",
+ "kpd_row7", "gpio_154", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_RX, 155, "uart4_rx", "sdmmc4_dat2", "kpd_row8",
+ "gpio_155", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(UART4_TX, 156, "uart4_tx", "sdmmc4_dat1", "kpd_col8",
+ "gpio_156", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_STP, 158, "usbb2_ulpitll_stp",
+ "usbb2_ulpiphy_stp", "sdmmc4_clk", "gpio_158",
+ "hsi2_cadata", "dispc2_data23", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DIR, 159, "usbb2_ulpitll_dir",
+ "usbb2_ulpiphy_dir", "sdmmc4_dat0", "gpio_159",
+ "hsi2_caflag", "dispc2_data22", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_NXT, 160, "usbb2_ulpitll_nxt",
+ "usbb2_ulpiphy_nxt", "sdmmc4_dat1", "gpio_160",
+ "hsi2_acready", "dispc2_data21", NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT0, 161, "usbb2_ulpitll_dat0",
+ "usbb2_ulpiphy_dat0", "sdmmc4_dat2", "gpio_161",
+ "hsi2_acwake", "dispc2_data20", "usbb2_mm_txen",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT1, 162, "usbb2_ulpitll_dat1",
+ "usbb2_ulpiphy_dat1", "sdmmc4_dat3", "gpio_162",
+ "hsi2_acdata", "dispc2_data19", "usbb2_mm_txdat",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT2, 163, "usbb2_ulpitll_dat2",
+ "usbb2_ulpiphy_dat2", "sdmmc3_dat2", "gpio_163",
+ "hsi2_acflag", "dispc2_data18", "usbb2_mm_txse0",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT3, 164, "usbb2_ulpitll_dat3",
+ "usbb2_ulpiphy_dat3", "sdmmc3_dat1", "gpio_164",
+ "hsi2_caready", "dispc2_data15", "rfbi_data15",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT4, 165, "usbb2_ulpitll_dat4",
+ "usbb2_ulpiphy_dat4", "sdmmc3_dat0", "gpio_165",
+ "mcspi3_somi", "dispc2_data14", "rfbi_data14",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT5, 166, "usbb2_ulpitll_dat5",
+ "usbb2_ulpiphy_dat5", "sdmmc3_dat3", "gpio_166",
+ "mcspi3_cs0", "dispc2_data13", "rfbi_data13",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT6, 167, "usbb2_ulpitll_dat6",
+ "usbb2_ulpiphy_dat6", "sdmmc3_cmd", "gpio_167",
+ "mcspi3_simo", "dispc2_data12", "rfbi_data12",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(USBB2_ULPITLL_DAT7, 168, "usbb2_ulpitll_dat7",
+ "usbb2_ulpiphy_dat7", "sdmmc3_clk", "gpio_168",
+ "mcspi3_clk", "dispc2_data11", "rfbi_data11",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL3, 171, "kpd_col3", "kpd_col0", NULL,
+ "gpio_171", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL4, 172, "kpd_col4", "kpd_col1", NULL,
+ "gpio_172", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL5, 173, "kpd_col5", "kpd_col2", NULL,
+ "gpio_173", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL0, 174, "kpd_col0", "kpd_col3", NULL,
+ "gpio_174", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL1, 0, "kpd_col1", "kpd_col4", NULL, "gpio_0",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_COL2, 1, "kpd_col2", "kpd_col5", NULL, "gpio_1",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW3, 175, "kpd_row3", "kpd_row0", NULL,
+ "gpio_175", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW4, 176, "kpd_row4", "kpd_row1", NULL,
+ "gpio_176", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW5, 177, "kpd_row5", "kpd_row2", NULL,
+ "gpio_177", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW0, 178, "kpd_row0", "kpd_row3", NULL,
+ "gpio_178", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW1, 2, "kpd_row1", "kpd_row4", NULL, "gpio_2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(KPD_ROW2, 3, "kpd_row2", "kpd_row5", NULL, "gpio_3",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_DP, 0, "usba0_otg_dp", "uart3_rx_irrx",
+ "uart2_rx", NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(USBA0_OTG_DM, 0, "usba0_otg_dm", "uart3_tx_irtx",
+ "uart2_tx", NULL, NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU2, 13, "dpm_emu2", "usba0_ulpiphy_clk", NULL,
+ "gpio_13", NULL, "dispc2_fid", "hw_dbg2",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU3, 14, "dpm_emu3", "usba0_ulpiphy_stp", NULL,
+ "gpio_14", "rfbi_data10", "dispc2_data10", "hw_dbg3",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU4, 15, "dpm_emu4", "usba0_ulpiphy_dir", NULL,
+ "gpio_15", "rfbi_data9", "dispc2_data9", "hw_dbg4",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU5, 16, "dpm_emu5", "usba0_ulpiphy_nxt", NULL,
+ "gpio_16", "rfbi_te_vsync0", "dispc2_data16",
+ "hw_dbg5", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU6, 17, "dpm_emu6", "usba0_ulpiphy_dat0",
+ "uart3_tx_irtx", "gpio_17", "rfbi_hsync0",
+ "dispc2_data17", "hw_dbg6", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU7, 18, "dpm_emu7", "usba0_ulpiphy_dat1",
+ "uart3_rx_irrx", "gpio_18", "rfbi_cs0",
+ "dispc2_hsync", "hw_dbg7", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU8, 19, "dpm_emu8", "usba0_ulpiphy_dat2",
+ "uart3_rts_sd", "gpio_19", "rfbi_re", "dispc2_pclk",
+ "hw_dbg8", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU9, 20, "dpm_emu9", "usba0_ulpiphy_dat3",
+ "uart3_cts_rctx", "gpio_20", "rfbi_we",
+ "dispc2_vsync", "hw_dbg9", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU10, 21, "dpm_emu10", "usba0_ulpiphy_dat4",
+ NULL, "gpio_21", "rfbi_a0", "dispc2_de", "hw_dbg10",
+ "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU11, 22, "dpm_emu11", "usba0_ulpiphy_dat5",
+ NULL, "gpio_22", "rfbi_data8", "dispc2_data8",
+ "hw_dbg11", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU12, 23, "dpm_emu12", "usba0_ulpiphy_dat6",
+ NULL, "gpio_23", "rfbi_data7", "dispc2_data7",
+ "hw_dbg12", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU13, 24, "dpm_emu13", "usba0_ulpiphy_dat7",
+ NULL, "gpio_24", "rfbi_data6", "dispc2_data6",
+ "hw_dbg13", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU14, 25, "dpm_emu14", "sys_drm_msecure",
+ "uart1_rx", "gpio_25", "rfbi_data5", "dispc2_data5",
+ "hw_dbg14", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU15, 26, "dpm_emu15", "sys_secure_indicator",
+ NULL, "gpio_26", "rfbi_data4", "dispc2_data4",
+ "hw_dbg15", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU16, 27, "dpm_emu16", "dmtimer8_pwm_evt",
+ "dsi1_te0", "gpio_27", "rfbi_data3", "dispc2_data3",
+ "hw_dbg16", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU17, 28, "dpm_emu17", "dmtimer9_pwm_evt",
+ "dsi1_te1", "gpio_28", "rfbi_data2", "dispc2_data2",
+ "hw_dbg17", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU18, 190, "dpm_emu18", "dmtimer10_pwm_evt",
+ "dsi2_te0", "gpio_190", "rfbi_data1", "dispc2_data1",
+ "hw_dbg18", "safe_mode"),
+ _OMAP4_MUXENTRY(DPM_EMU19, 191, "dpm_emu19", "dmtimer11_pwm_evt",
+ "dsi2_te1", "gpio_191", "rfbi_data0", "dispc2_data0",
+ "hw_dbg19", "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBS package
+ * 547-pin CBL ES2.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBS)
+static struct omap_ball __initdata omap4_core_cbs_ball[] = {
+ _OMAP4_BALLENTRY(GPMC_AD0, "c12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD1, "d12", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD2, "c13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD3, "d13", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD4, "c15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD5, "d15", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD6, "a16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD7, "b16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD8, "c16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD9, "d16", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD10, "c17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD11, "d17", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD12, "c18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD13, "d18", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD14, "c19", NULL),
+ _OMAP4_BALLENTRY(GPMC_AD15, "d19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A16, "b17", NULL),
+ _OMAP4_BALLENTRY(GPMC_A17, "a18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A18, "b18", NULL),
+ _OMAP4_BALLENTRY(GPMC_A19, "a19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A20, "b19", NULL),
+ _OMAP4_BALLENTRY(GPMC_A21, "b20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A22, "a21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A23, "b21", NULL),
+ _OMAP4_BALLENTRY(GPMC_A24, "c20", NULL),
+ _OMAP4_BALLENTRY(GPMC_A25, "d20", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS0, "b25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS1, "c21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS2, "d21", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS3, "c22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWP, "c25", NULL),
+ _OMAP4_BALLENTRY(GPMC_CLK, "b22", NULL),
+ _OMAP4_BALLENTRY(GPMC_NADV_ALE, "d25", NULL),
+ _OMAP4_BALLENTRY(GPMC_NOE, "b11", NULL),
+ _OMAP4_BALLENTRY(GPMC_NWE, "b12", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE0_CLE, "c23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NBE1, "d22", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT0, "b26", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT1, "b23", NULL),
+ _OMAP4_BALLENTRY(GPMC_WAIT2, "d23", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS4, "a24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS5, "b24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS6, "c24", NULL),
+ _OMAP4_BALLENTRY(GPMC_NCS7, "d24", NULL),
+ _OMAP4_BALLENTRY(HDMI_HPD, "b9", NULL),
+ _OMAP4_BALLENTRY(HDMI_CEC, "b10", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SCL, "a8", NULL),
+ _OMAP4_BALLENTRY(HDMI_DDC_SDA, "b8", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX0, "r26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY0, "r25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX1, "t26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY1, "t25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX2, "u26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY2, "u25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX3, "v26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY3, "v25", NULL),
+ _OMAP4_BALLENTRY(CSI21_DX4, "w26", NULL),
+ _OMAP4_BALLENTRY(CSI21_DY4, "w25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX0, "m26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY0, "m25", NULL),
+ _OMAP4_BALLENTRY(CSI22_DX1, "n26", NULL),
+ _OMAP4_BALLENTRY(CSI22_DY1, "n25", NULL),
+ _OMAP4_BALLENTRY(CAM_SHUTTER, "t27", NULL),
+ _OMAP4_BALLENTRY(CAM_STROBE, "u27", NULL),
+ _OMAP4_BALLENTRY(CAM_GLOBALRESET, "v27", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_CLK, "ae18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_STP, "ag19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DIR, "af19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_NXT, "ae19", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT0, "af18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT1, "ag18", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT2, "ae17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT3, "af17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT4, "ah17", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT5, "ae16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT6, "af16", NULL),
+ _OMAP4_BALLENTRY(USBB1_ULPITLL_DAT7, "ag16", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_DATA, "af14", NULL),
+ _OMAP4_BALLENTRY(USBB1_HSIC_STROBE, "ae14", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DP, "h2", NULL),
+ _OMAP4_BALLENTRY(USBC1_ICUSB_DM, "h3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CLK, "d2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_CMD, "e3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT0, "e4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT1, "e2", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT2, "e1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT3, "f4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT4, "f3", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT5, "f1", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT6, "g4", NULL),
+ _OMAP4_BALLENTRY(SDMMC1_DAT7, "g3", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_CLKX, "ad27", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DR, "ad26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_DX, "ad25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP2_FSX, "ac28", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_CLKX, "ac26", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DR, "ac25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_DX, "ab25", NULL),
+ _OMAP4_BALLENTRY(ABE_MCBSP1_FSX, "ac27", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_UL_DATA, "ag25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_DL_DATA, "af25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_FRAME, "ae25", NULL),
+ _OMAP4_BALLENTRY(ABE_PDM_LB_CLK, "af26", NULL),
+ _OMAP4_BALLENTRY(ABE_CLKS, "ah26", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_CLK1, "ae24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN1, "af24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN2, "ag24", NULL),
+ _OMAP4_BALLENTRY(ABE_DMIC_DIN3, "ah24", NULL),
+ _OMAP4_BALLENTRY(UART2_CTS, "ab26", NULL),
+ _OMAP4_BALLENTRY(UART2_RTS, "ab27", NULL),
+ _OMAP4_BALLENTRY(UART2_RX, "aa25", NULL),
+ _OMAP4_BALLENTRY(UART2_TX, "aa26", NULL),
+ _OMAP4_BALLENTRY(HDQ_SIO, "aa27", NULL),
+ _OMAP4_BALLENTRY(I2C1_SCL, "ae28", NULL),
+ _OMAP4_BALLENTRY(I2C1_SDA, "ae26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SCL, "c26", NULL),
+ _OMAP4_BALLENTRY(I2C2_SDA, "d26", NULL),
+ _OMAP4_BALLENTRY(I2C3_SCL, "w27", NULL),
+ _OMAP4_BALLENTRY(I2C3_SDA, "y27", NULL),
+ _OMAP4_BALLENTRY(I2C4_SCL, "ag21", NULL),
+ _OMAP4_BALLENTRY(I2C4_SDA, "ah22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CLK, "af22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SOMI, "ae22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_SIMO, "ag22", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS0, "ae23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS1, "af23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS2, "ag23", NULL),
+ _OMAP4_BALLENTRY(MCSPI1_CS3, "ah23", NULL),
+ _OMAP4_BALLENTRY(UART3_CTS_RCTX, "f27", NULL),
+ _OMAP4_BALLENTRY(UART3_RTS_SD, "f28", NULL),
+ _OMAP4_BALLENTRY(UART3_RX_IRRX, "g27", NULL),
+ _OMAP4_BALLENTRY(UART3_TX_IRTX, "g28", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CLK, "ae5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_CMD, "af5", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT0, "ae4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT1, "af4", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT2, "ag3", NULL),
+ _OMAP4_BALLENTRY(SDMMC5_DAT3, "af3", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CLK, "ae21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SIMO, "af20", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_SOMI, "af21", NULL),
+ _OMAP4_BALLENTRY(MCSPI4_CS0, "ae20", NULL),
+ _OMAP4_BALLENTRY(UART4_RX, "ag20", NULL),
+ _OMAP4_BALLENTRY(UART4_TX, "ah19", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_CLK, "ag12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_STP, "af12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DIR, "ae12", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_NXT, "ag13", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT0, "ae11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT1, "af11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT2, "ag11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT3, "ah11", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT4, "ae10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT5, "af10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT6, "ag10", NULL),
+ _OMAP4_BALLENTRY(USBB2_ULPITLL_DAT7, "ae9", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_DATA, "af13", NULL),
+ _OMAP4_BALLENTRY(USBB2_HSIC_STROBE, "ae13", NULL),
+ _OMAP4_BALLENTRY(KPD_COL3, "g26", NULL),
+ _OMAP4_BALLENTRY(KPD_COL4, "g25", NULL),
+ _OMAP4_BALLENTRY(KPD_COL5, "h26", NULL),
+ _OMAP4_BALLENTRY(KPD_COL0, "h25", NULL),
+ _OMAP4_BALLENTRY(KPD_COL1, "j27", NULL),
+ _OMAP4_BALLENTRY(KPD_COL2, "h27", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW3, "j26", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW4, "j25", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW5, "k26", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW0, "k25", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW1, "l27", NULL),
+ _OMAP4_BALLENTRY(KPD_ROW2, "k27", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_CE, "c3", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DP, "b5", NULL),
+ _OMAP4_BALLENTRY(USBA0_OTG_DM, "b4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK1_OUT, "aa28", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK2_OUT, "y28", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ1, "ae6", NULL),
+ _OMAP4_BALLENTRY(SYS_NIRQ2, "af6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT0, "f26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT1, "e27", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT2, "e26", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT3, "e25", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT4, "d28", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT5, "d27", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU0, "m2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU1, "n2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU2, "p2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU3, "v1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU4, "v2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU5, "w1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU6, "w2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU7, "w3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU8, "w4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU9, "y2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU10, "y3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU11, "y4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU12, "aa1", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU13, "aa2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU14, "aa3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU15, "aa4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU16, "ab2", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU17, "ab3", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU18, "ab4", NULL),
+ _OMAP4_BALLENTRY(DPM_EMU19, "ac4", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_core_cbs_ball NULL
+#endif
+
+/*
+ * Superset of all mux modes for omap4
+ */
+static struct omap_mux __initdata omap4_wkup_muxmodes[] = {
+ _OMAP4_MUXENTRY(SIM_IO, 0, "sim_io", NULL, NULL, "gpio_wk0", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_CLK, 1, "sim_clk", NULL, NULL, "gpio_wk1", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_RESET, 2, "sim_reset", NULL, NULL, "gpio_wk2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_CD, 3, "sim_cd", NULL, NULL, "gpio_wk3", NULL,
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SIM_PWRCTRL, 4, "sim_pwrctrl", NULL, NULL, "gpio_wk4",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(SR_SCL, 0, "sr_scl", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(SR_SDA, 0, "sr_sda", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_XTAL_IN, 0, "fref_xtal_in", NULL, NULL, NULL,
+ "c2c_wakereqin", NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_SLICER_IN, 0, "fref_slicer_in", NULL, NULL,
+ "gpi_wk5", "c2c_wakereqin", NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK_IOREQ, 0, "fref_clk_ioreq", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_CLK0_OUT, 6, "fref_clk0_out", "fref_clk1_req",
+ "sys_drm_msecure", "gpio_wk6", NULL, NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK3_REQ, 30, "fref_clk3_req", "fref_clk1_req",
+ "sys_drm_msecure", "gpio_wk30", "c2c_wakereqin", NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK3_OUT, 31, "fref_clk3_out", "fref_clk2_req",
+ "sys_secure_indicator", "gpio_wk31", "c2c_wakereqout",
+ NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(FREF_CLK4_REQ, 7, "fref_clk4_req", "fref_clk5_out",
+ NULL, "gpio_wk7", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(FREF_CLK4_OUT, 8, "fref_clk4_out", NULL, NULL,
+ "gpio_wk8", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_32K, 0, "sys_32k", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_NRESPWRON, 0, "sys_nrespwron", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_NRESWARM, 0, "sys_nreswarm", NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_PWR_REQ, 0, "sys_pwr_req", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_PWRON_RESET_OUT, 29, "sys_pwron_reset_out", NULL,
+ NULL, "gpio_wk29", NULL, NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(SYS_BOOT6, 9, "sys_boot6", "dpm_emu18", NULL,
+ "gpio_wk9", "c2c_wakereqout", NULL, NULL,
+ "safe_mode"),
+ _OMAP4_MUXENTRY(SYS_BOOT7, 10, "sys_boot7", "dpm_emu19", NULL,
+ "gpio_wk10", NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_NTRST, 0, "jtag_ntrst", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TCK, 0, "jtag_tck", NULL, NULL, NULL, NULL, NULL,
+ NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_RTCK, 0, "jtag_rtck", NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TMS_TMSC, 0, "jtag_tms_tmsc", NULL, NULL, NULL,
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP4_MUXENTRY(JTAG_TDI, 0, "jtag_tdi", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ _OMAP4_MUXENTRY(JTAG_TDO, 0, "jtag_tdo", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 44XX CBL & CBS package - wakeup partition
+ * 547-pin CBL ES1.0 S-FPGA-N547, 0.40mm Ball Pitch (Top),
+ * 0.40mm Ball Pitch (Bottom)
+ */
+#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) \
+ && defined(CONFIG_OMAP_PACKAGE_CBL)
+static struct omap_ball __initdata omap4_wkup_cbl_cbs_ball[] = {
+ _OMAP4_BALLENTRY(SIM_IO, "h4", NULL),
+ _OMAP4_BALLENTRY(SIM_CLK, "j2", NULL),
+ _OMAP4_BALLENTRY(SIM_RESET, "g2", NULL),
+ _OMAP4_BALLENTRY(SIM_CD, "j1", NULL),
+ _OMAP4_BALLENTRY(SIM_PWRCTRL, "k1", NULL),
+ _OMAP4_BALLENTRY(SR_SCL, "ag9", NULL),
+ _OMAP4_BALLENTRY(SR_SDA, "af9", NULL),
+ _OMAP4_BALLENTRY(FREF_XTAL_IN, "ah6", NULL),
+ _OMAP4_BALLENTRY(FREF_SLICER_IN, "ag8", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK_IOREQ, "ad1", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK0_OUT, "ad2", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK3_REQ, "ad3", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK3_OUT, "ad4", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK4_REQ, "ac2", NULL),
+ _OMAP4_BALLENTRY(FREF_CLK4_OUT, "ac3", NULL),
+ _OMAP4_BALLENTRY(SYS_32K, "ag7", NULL),
+ _OMAP4_BALLENTRY(SYS_NRESPWRON, "ae7", NULL),
+ _OMAP4_BALLENTRY(SYS_NRESWARM, "af7", NULL),
+ _OMAP4_BALLENTRY(SYS_PWR_REQ, "ah7", NULL),
+ _OMAP4_BALLENTRY(SYS_PWRON_RESET_OUT, "ag6", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT6, "af8", NULL),
+ _OMAP4_BALLENTRY(SYS_BOOT7, "ae8", NULL),
+ _OMAP4_BALLENTRY(JTAG_NTRST, "ah2", NULL),
+ _OMAP4_BALLENTRY(JTAG_TCK, "ag1", NULL),
+ _OMAP4_BALLENTRY(JTAG_RTCK, "ae3", NULL),
+ _OMAP4_BALLENTRY(JTAG_TMS_TMSC, "ah1", NULL),
+ _OMAP4_BALLENTRY(JTAG_TDI, "ae1", NULL),
+ _OMAP4_BALLENTRY(JTAG_TDO, "ae2", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap4_wkup_cbl_cbs_ball NULL
+#endif
+
+int __init omap4_mux_init(struct omap_board_mux *board_subset,
+ struct omap_board_mux *board_wkup_subset, int flags)
+{
+ struct omap_ball *package_balls_core;
+ struct omap_ball *package_balls_wkup = omap4_wkup_cbl_cbs_ball;
+ struct omap_mux *core_muxmodes;
+ struct omap_mux *core_subset = NULL;
+ int ret;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_CBL:
+ pr_debug("%s: OMAP4430 ES1.0 -> OMAP_PACKAGE_CBL\n", __func__);
+ package_balls_core = omap4_core_cbl_ball;
+ core_muxmodes = omap4_core_muxmodes;
+ break;
+ case OMAP_PACKAGE_CBS:
+ pr_debug("%s: OMAP4430 ES2.X -> OMAP_PACKAGE_CBS\n", __func__);
+ package_balls_core = omap4_core_cbs_ball;
+ core_muxmodes = omap4_core_muxmodes;
+ core_subset = omap4_es2_core_subset;
+ break;
+ default:
+ pr_err("%s: Unknown omap package, mux disabled\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = omap_mux_init("core",
+ OMAP_MUX_GPIO_IN_MODE3,
+ OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE,
+ OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE,
+ core_muxmodes, core_subset, board_subset,
+ package_balls_core);
+ if (ret)
+ return ret;
+
+ ret = omap_mux_init("wkup",
+ OMAP_MUX_GPIO_IN_MODE3,
+ OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE,
+ OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE,
+ omap4_wkup_muxmodes, NULL, board_wkup_subset,
+ package_balls_wkup);
+
+ return ret;
+}
+
diff --git a/arch/arm/mach-omap2/mux44xx.h b/arch/arm/mach-omap2/mux44xx.h
new file mode 100644
index 00000000..c635026c
--- /dev/null
+++ b/arch/arm/mach-omap2/mux44xx.h
@@ -0,0 +1,298 @@
+/*
+ * OMAP44xx MUX registers and bitfields
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_MUX_44XX_H
+
+#define OMAP4_MUX(M0, mux_value) \
+{ \
+ .reg_offset = (OMAP4_CTRL_MODULE_PAD_##M0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/* ctrl_module_pad_core base address */
+#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_PBASE 0x4a100000
+
+/* ctrl_module_pad_core registers offset */
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET 0x0040
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD1_OFFSET 0x0042
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD2_OFFSET 0x0044
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD3_OFFSET 0x0046
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD4_OFFSET 0x0048
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD5_OFFSET 0x004a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD6_OFFSET 0x004c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD7_OFFSET 0x004e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD8_OFFSET 0x0050
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD9_OFFSET 0x0052
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD10_OFFSET 0x0054
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD11_OFFSET 0x0056
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD12_OFFSET 0x0058
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD13_OFFSET 0x005a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD14_OFFSET 0x005c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_AD15_OFFSET 0x005e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A16_OFFSET 0x0060
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A17_OFFSET 0x0062
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A18_OFFSET 0x0064
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A19_OFFSET 0x0066
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A20_OFFSET 0x0068
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A21_OFFSET 0x006a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A22_OFFSET 0x006c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A23_OFFSET 0x006e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A24_OFFSET 0x0070
+#define OMAP4_CTRL_MODULE_PAD_GPMC_A25_OFFSET 0x0072
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS0_OFFSET 0x0074
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS1_OFFSET 0x0076
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS2_OFFSET 0x0078
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS3_OFFSET 0x007a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NWP_OFFSET 0x007c
+#define OMAP4_CTRL_MODULE_PAD_GPMC_CLK_OFFSET 0x007e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NADV_ALE_OFFSET 0x0080
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NOE_OFFSET 0x0082
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NWE_OFFSET 0x0084
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE0_CLE_OFFSET 0x0086
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NBE1_OFFSET 0x0088
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT0_OFFSET 0x008a
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT1_OFFSET 0x008c
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA11_OFFSET 0x008e
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA12_OFFSET 0x0090
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA13_OFFSET 0x0092
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA14_OFFSET 0x0094
+#define OMAP4_CTRL_MODULE_PAD_C2C_DATA15_OFFSET 0x0096
+#define OMAP4_CTRL_MODULE_PAD_HDMI_HPD_OFFSET 0x0098
+#define OMAP4_CTRL_MODULE_PAD_HDMI_CEC_OFFSET 0x009a
+#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SCL_OFFSET 0x009c
+#define OMAP4_CTRL_MODULE_PAD_HDMI_DDC_SDA_OFFSET 0x009e
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX0_OFFSET 0x00a0
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY0_OFFSET 0x00a2
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX1_OFFSET 0x00a4
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY1_OFFSET 0x00a6
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX2_OFFSET 0x00a8
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY2_OFFSET 0x00aa
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX3_OFFSET 0x00ac
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY3_OFFSET 0x00ae
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DX4_OFFSET 0x00b0
+#define OMAP4_CTRL_MODULE_PAD_CSI21_DY4_OFFSET 0x00b2
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DX0_OFFSET 0x00b4
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DY0_OFFSET 0x00b6
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DX1_OFFSET 0x00b8
+#define OMAP4_CTRL_MODULE_PAD_CSI22_DY1_OFFSET 0x00ba
+#define OMAP4_CTRL_MODULE_PAD_CAM_SHUTTER_OFFSET 0x00bc
+#define OMAP4_CTRL_MODULE_PAD_CAM_STROBE_OFFSET 0x00be
+#define OMAP4_CTRL_MODULE_PAD_CAM_GLOBALRESET_OFFSET 0x00c0
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_CLK_OFFSET 0x00c2
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_STP_OFFSET 0x00c4
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DIR_OFFSET 0x00c6
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_NXT_OFFSET 0x00c8
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT0_OFFSET 0x00ca
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT1_OFFSET 0x00cc
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT2_OFFSET 0x00ce
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT3_OFFSET 0x00d0
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT4_OFFSET 0x00d2
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT5_OFFSET 0x00d4
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT6_OFFSET 0x00d6
+#define OMAP4_CTRL_MODULE_PAD_USBB1_ULPITLL_DAT7_OFFSET 0x00d8
+#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_DATA_OFFSET 0x00da
+#define OMAP4_CTRL_MODULE_PAD_USBB1_HSIC_STROBE_OFFSET 0x00dc
+#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DP_OFFSET 0x00de
+#define OMAP4_CTRL_MODULE_PAD_USBC1_ICUSB_DM_OFFSET 0x00e0
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CLK_OFFSET 0x00e2
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_CMD_OFFSET 0x00e4
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT0_OFFSET 0x00e6
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT1_OFFSET 0x00e8
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT2_OFFSET 0x00ea
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT3_OFFSET 0x00ec
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT4_OFFSET 0x00ee
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT5_OFFSET 0x00f0
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT6_OFFSET 0x00f2
+#define OMAP4_CTRL_MODULE_PAD_SDMMC1_DAT7_OFFSET 0x00f4
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_CLKX_OFFSET 0x00f6
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DR_OFFSET 0x00f8
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_DX_OFFSET 0x00fa
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP2_FSX_OFFSET 0x00fc
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_CLKX_OFFSET 0x00fe
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DR_OFFSET 0x0100
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_DX_OFFSET 0x0102
+#define OMAP4_CTRL_MODULE_PAD_ABE_MCBSP1_FSX_OFFSET 0x0104
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_UL_DATA_OFFSET 0x0106
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_DL_DATA_OFFSET 0x0108
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_FRAME_OFFSET 0x010a
+#define OMAP4_CTRL_MODULE_PAD_ABE_PDM_LB_CLK_OFFSET 0x010c
+#define OMAP4_CTRL_MODULE_PAD_ABE_CLKS_OFFSET 0x010e
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_CLK1_OFFSET 0x0110
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN1_OFFSET 0x0112
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN2_OFFSET 0x0114
+#define OMAP4_CTRL_MODULE_PAD_ABE_DMIC_DIN3_OFFSET 0x0116
+#define OMAP4_CTRL_MODULE_PAD_UART2_CTS_OFFSET 0x0118
+#define OMAP4_CTRL_MODULE_PAD_UART2_RTS_OFFSET 0x011a
+#define OMAP4_CTRL_MODULE_PAD_UART2_RX_OFFSET 0x011c
+#define OMAP4_CTRL_MODULE_PAD_UART2_TX_OFFSET 0x011e
+#define OMAP4_CTRL_MODULE_PAD_HDQ_SIO_OFFSET 0x0120
+#define OMAP4_CTRL_MODULE_PAD_I2C1_SCL_OFFSET 0x0122
+#define OMAP4_CTRL_MODULE_PAD_I2C1_SDA_OFFSET 0x0124
+#define OMAP4_CTRL_MODULE_PAD_I2C2_SCL_OFFSET 0x0126
+#define OMAP4_CTRL_MODULE_PAD_I2C2_SDA_OFFSET 0x0128
+#define OMAP4_CTRL_MODULE_PAD_I2C3_SCL_OFFSET 0x012a
+#define OMAP4_CTRL_MODULE_PAD_I2C3_SDA_OFFSET 0x012c
+#define OMAP4_CTRL_MODULE_PAD_I2C4_SCL_OFFSET 0x012e
+#define OMAP4_CTRL_MODULE_PAD_I2C4_SDA_OFFSET 0x0130
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CLK_OFFSET 0x0132
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SOMI_OFFSET 0x0134
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_SIMO_OFFSET 0x0136
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS0_OFFSET 0x0138
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS1_OFFSET 0x013a
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS2_OFFSET 0x013c
+#define OMAP4_CTRL_MODULE_PAD_MCSPI1_CS3_OFFSET 0x013e
+#define OMAP4_CTRL_MODULE_PAD_UART3_CTS_RCTX_OFFSET 0x0140
+#define OMAP4_CTRL_MODULE_PAD_UART3_RTS_SD_OFFSET 0x0142
+#define OMAP4_CTRL_MODULE_PAD_UART3_RX_IRRX_OFFSET 0x0144
+#define OMAP4_CTRL_MODULE_PAD_UART3_TX_IRTX_OFFSET 0x0146
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CLK_OFFSET 0x0148
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_CMD_OFFSET 0x014a
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT0_OFFSET 0x014c
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT1_OFFSET 0x014e
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT2_OFFSET 0x0150
+#define OMAP4_CTRL_MODULE_PAD_SDMMC5_DAT3_OFFSET 0x0152
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CLK_OFFSET 0x0154
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SIMO_OFFSET 0x0156
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_SOMI_OFFSET 0x0158
+#define OMAP4_CTRL_MODULE_PAD_MCSPI4_CS0_OFFSET 0x015a
+#define OMAP4_CTRL_MODULE_PAD_UART4_RX_OFFSET 0x015c
+#define OMAP4_CTRL_MODULE_PAD_UART4_TX_OFFSET 0x015e
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_CLK_OFFSET 0x0160
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_STP_OFFSET 0x0162
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DIR_OFFSET 0x0164
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_NXT_OFFSET 0x0166
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT0_OFFSET 0x0168
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT1_OFFSET 0x016a
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT2_OFFSET 0x016c
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT3_OFFSET 0x016e
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT4_OFFSET 0x0170
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT5_OFFSET 0x0172
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT6_OFFSET 0x0174
+#define OMAP4_CTRL_MODULE_PAD_USBB2_ULPITLL_DAT7_OFFSET 0x0176
+#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_DATA_OFFSET 0x0178
+#define OMAP4_CTRL_MODULE_PAD_USBB2_HSIC_STROBE_OFFSET 0x017a
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX0_OFFSET 0x017c
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY0_OFFSET 0x017e
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX1_OFFSET 0x0180
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY1_OFFSET 0x0182
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TX2_OFFSET 0x0184
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_TY2_OFFSET 0x0186
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX0_OFFSET 0x0188
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY0_OFFSET 0x018a
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX1_OFFSET 0x018c
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY1_OFFSET 0x018e
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RX2_OFFSET 0x0190
+#define OMAP4_CTRL_MODULE_PAD_UNIPRO_RY2_OFFSET 0x0192
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_CE_OFFSET 0x0194
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DP_OFFSET 0x0196
+#define OMAP4_CTRL_MODULE_PAD_USBA0_OTG_DM_OFFSET 0x0198
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK1_OUT_OFFSET 0x019a
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK2_OUT_OFFSET 0x019c
+#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ1_OFFSET 0x019e
+#define OMAP4_CTRL_MODULE_PAD_SYS_NIRQ2_OFFSET 0x01a0
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT0_OFFSET 0x01a2
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT1_OFFSET 0x01a4
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT2_OFFSET 0x01a6
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT3_OFFSET 0x01a8
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT4_OFFSET 0x01aa
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT5_OFFSET 0x01ac
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU0_OFFSET 0x01ae
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU1_OFFSET 0x01b0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU2_OFFSET 0x01b2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU3_OFFSET 0x01b4
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU4_OFFSET 0x01b6
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU5_OFFSET 0x01b8
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU6_OFFSET 0x01ba
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU7_OFFSET 0x01bc
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU8_OFFSET 0x01be
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU9_OFFSET 0x01c0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU10_OFFSET 0x01c2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU11_OFFSET 0x01c4
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU12_OFFSET 0x01c6
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU13_OFFSET 0x01c8
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU14_OFFSET 0x01ca
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU15_OFFSET 0x01cc
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU16_OFFSET 0x01ce
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU17_OFFSET 0x01d0
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU18_OFFSET 0x01d2
+#define OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET 0x01d4
+
+/* ES2.0 only */
+#define OMAP4_CTRL_MODULE_PAD_GPMC_WAIT2_OFFSET 0x008e
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS4_OFFSET 0x0090
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS5_OFFSET 0x0092
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS6_OFFSET 0x0094
+#define OMAP4_CTRL_MODULE_PAD_GPMC_NCS7_OFFSET 0x0096
+
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL3_OFFSET 0x017c
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL4_OFFSET 0x017e
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL5_OFFSET 0x0180
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL0_OFFSET 0x0182
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL1_OFFSET 0x0184
+#define OMAP4_CTRL_MODULE_PAD_KPD_COL2_OFFSET 0x0186
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW3_OFFSET 0x0188
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW4_OFFSET 0x018a
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW5_OFFSET 0x018c
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW0_OFFSET 0x018e
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW1_OFFSET 0x0190
+#define OMAP4_CTRL_MODULE_PAD_KPD_ROW2_OFFSET 0x0192
+
+
+#define OMAP4_CTRL_MODULE_PAD_CORE_MUX_SIZE \
+ (OMAP4_CTRL_MODULE_PAD_DPM_EMU19_OFFSET \
+ - OMAP4_CTRL_MODULE_PAD_GPMC_AD0_OFFSET + 2)
+
+/* ctrl_module_pad_wkup base address */
+#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE 0x4a31e000
+
+/* ctrl_module_pad_wkup registers offset */
+#define OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET 0x0040
+#define OMAP4_CTRL_MODULE_PAD_SIM_CLK_OFFSET 0x0042
+#define OMAP4_CTRL_MODULE_PAD_SIM_RESET_OFFSET 0x0044
+#define OMAP4_CTRL_MODULE_PAD_SIM_CD_OFFSET 0x0046
+#define OMAP4_CTRL_MODULE_PAD_SIM_PWRCTRL_OFFSET 0x0048
+#define OMAP4_CTRL_MODULE_PAD_SR_SCL_OFFSET 0x004a
+#define OMAP4_CTRL_MODULE_PAD_SR_SDA_OFFSET 0x004c
+#define OMAP4_CTRL_MODULE_PAD_FREF_XTAL_IN_OFFSET 0x004e
+#define OMAP4_CTRL_MODULE_PAD_FREF_SLICER_IN_OFFSET 0x0050
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK_IOREQ_OFFSET 0x0052
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK0_OUT_OFFSET 0x0054
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_REQ_OFFSET 0x0056
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK3_OUT_OFFSET 0x0058
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_REQ_OFFSET 0x005a
+#define OMAP4_CTRL_MODULE_PAD_FREF_CLK4_OUT_OFFSET 0x005c
+#define OMAP4_CTRL_MODULE_PAD_SYS_32K_OFFSET 0x005e
+#define OMAP4_CTRL_MODULE_PAD_SYS_NRESPWRON_OFFSET 0x0060
+#define OMAP4_CTRL_MODULE_PAD_SYS_NRESWARM_OFFSET 0x0062
+#define OMAP4_CTRL_MODULE_PAD_SYS_PWR_REQ_OFFSET 0x0064
+#define OMAP4_CTRL_MODULE_PAD_SYS_PWRON_RESET_OUT_OFFSET 0x0066
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT6_OFFSET 0x0068
+#define OMAP4_CTRL_MODULE_PAD_SYS_BOOT7_OFFSET 0x006a
+#define OMAP4_CTRL_MODULE_PAD_JTAG_NTRST_OFFSET 0x006c
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TCK_OFFSET 0x006e
+#define OMAP4_CTRL_MODULE_PAD_JTAG_RTCK_OFFSET 0x0070
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TMS_TMSC_OFFSET 0x0072
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TDI_OFFSET 0x0074
+#define OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET 0x0076
+
+#define OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE \
+ (OMAP4_CTRL_MODULE_PAD_JTAG_TDO_OFFSET \
+ - OMAP4_CTRL_MODULE_PAD_SIM_IO_OFFSET + 2)
+
+#endif
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
new file mode 100644
index 00000000..4ee6aeca
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -0,0 +1,49 @@
+/*
+ * Secondary CPU startup routine source file.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Interface functions needed for the SMP. This file is based on arm
+ * realview smp platform.
+ * Copyright (c) 2003 ARM Limited.
+ *
+ * This program is free software,you can 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/linkage.h>
+#include <linux/init.h>
+
+/* Physical address needed since MMU not enabled yet on secondary core */
+#define OMAP4_AUX_CORE_BOOT1_PA 0x48281804
+
+ __INIT
+
+/*
+ * OMAP4 specific entry point for secondary CPU to jump from ROM
+ * code. This routine also provides a holding flag into which
+ * secondary core is held until we're ready for it to initialise.
+ * The primary core will update this flag using a hardware
+ * register AuxCoreBoot0.
+ */
+ENTRY(omap_secondary_startup)
+hold: ldr r12,=0x103
+ dsb
+ smc #0 @ read from AuxCoreBoot0
+ mov r0, r0, lsr #9
+ mrc p15, 0, r4, c0, c0, 5
+ and r4, r4, #0x0f
+ cmp r0, r4
+ bne hold
+
+ /*
+ * we've been released from the wait loop,secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+ENDPROC(omap_secondary_startup)
+
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
new file mode 100644
index 00000000..4976b939
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -0,0 +1,67 @@
+/*
+ * OMAP4 SMP cpu-hotplug support
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Platform file needed for the OMAP4 SMP. This file is based on arm
+ * realview smp platform.
+ * Copyright (c) 2002 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <mach/omap4-common.h>
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ flush_cache_all();
+ dsb();
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
+ printk(KERN_CRIT "Secure clear status failed\n");
+
+ for (;;) {
+ /*
+ * Execute WFI
+ */
+ do_wfi();
+
+ if (omap_read_auxcoreboot0() == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ pr_debug("CPU%u: spurious wakeup call\n", cpu);
+ }
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
new file mode 100644
index 00000000..3fc5dc72
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -0,0 +1,165 @@
+/*
+ * omap iommu: omap device registration
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+
+#include <plat/iommu.h>
+#include <plat/irqs.h>
+
+struct iommu_device {
+ resource_size_t base;
+ int irq;
+ struct iommu_platform_data pdata;
+ struct resource res[2];
+};
+static struct iommu_device *devices;
+static int num_iommu_devices;
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct iommu_device omap3_devices[] = {
+ {
+ .base = 0x480bd400,
+ .irq = 24,
+ .pdata = {
+ .name = "isp",
+ .nr_tlb_entries = 8,
+ .clk_name = "cam_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
+ },
+ },
+#if defined(CONFIG_OMAP_IOMMU_IVA2)
+ {
+ .base = 0x5d000000,
+ .irq = 28,
+ .pdata = {
+ .name = "iva2",
+ .nr_tlb_entries = 32,
+ .clk_name = "iva2_ck",
+ .da_start = 0x11000000,
+ .da_end = 0xFFFFF000,
+ },
+ },
+#endif
+};
+#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
+static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
+#else
+#define omap3_devices NULL
+#define NR_OMAP3_IOMMU_DEVICES 0
+#define omap3_iommu_pdev NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static struct iommu_device omap4_devices[] = {
+ {
+ .base = OMAP4_MMU1_BASE,
+ .irq = OMAP44XX_IRQ_DUCATI_MMU,
+ .pdata = {
+ .name = "ducati",
+ .nr_tlb_entries = 32,
+ .clk_name = "ducati_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
+ },
+ },
+#if defined(CONFIG_MPU_TESLA_IOMMU)
+ {
+ .base = OMAP4_MMU2_BASE,
+ .irq = INT_44XX_DSP_MMU,
+ .pdata = {
+ .name = "tesla",
+ .nr_tlb_entries = 32,
+ .clk_name = "tesla_ick",
+ .da_start = 0x0,
+ .da_end = 0xFFFFF000,
+ },
+ },
+#endif
+};
+#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
+static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES];
+#else
+#define omap4_devices NULL
+#define NR_OMAP4_IOMMU_DEVICES 0
+#define omap4_iommu_pdev NULL
+#endif
+
+static struct platform_device **omap_iommu_pdev;
+
+static int __init omap_iommu_init(void)
+{
+ int i, err;
+ struct resource res[] = {
+ { .flags = IORESOURCE_MEM },
+ { .flags = IORESOURCE_IRQ },
+ };
+
+ if (cpu_is_omap34xx()) {
+ devices = omap3_devices;
+ omap_iommu_pdev = omap3_iommu_pdev;
+ num_iommu_devices = NR_OMAP3_IOMMU_DEVICES;
+ } else if (cpu_is_omap44xx()) {
+ devices = omap4_devices;
+ omap_iommu_pdev = omap4_iommu_pdev;
+ num_iommu_devices = NR_OMAP4_IOMMU_DEVICES;
+ } else
+ return -ENODEV;
+
+ for (i = 0; i < num_iommu_devices; i++) {
+ struct platform_device *pdev;
+ const struct iommu_device *d = &devices[i];
+
+ pdev = platform_device_alloc("omap-iommu", i);
+ if (!pdev) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ res[0].start = d->base;
+ res[0].end = d->base + MMU_REG_SIZE - 1;
+ res[1].start = res[1].end = d->irq;
+
+ err = platform_device_add_resources(pdev, res,
+ ARRAY_SIZE(res));
+ if (err)
+ goto err_out;
+ err = platform_device_add_data(pdev, &d->pdata,
+ sizeof(d->pdata));
+ if (err)
+ goto err_out;
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_out;
+ omap_iommu_pdev[i] = pdev;
+ }
+ return 0;
+
+err_out:
+ while (i--)
+ platform_device_put(omap_iommu_pdev[i]);
+ return err;
+}
+module_init(omap_iommu_init);
+
+static void __exit omap_iommu_exit(void)
+{
+ int i;
+
+ for (i = 0; i < num_iommu_devices; i++)
+ platform_device_unregister(omap_iommu_pdev[i]);
+}
+module_exit(omap_iommu_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU");
+MODULE_DESCRIPTION("omap iommu: omap device registration");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
new file mode 100644
index 00000000..ecfe93c4
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -0,0 +1,143 @@
+/*
+ * OMAP4 SMP source file. It contains platform specific fucntions
+ * needed for the linux smp kernel.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Platform file needed for the OMAP4 SMP. This file is based on arm
+ * realview smp platform.
+ * * Copyright (c) 2002 ARM Limited.
+ *
+ * This program is free software; you can 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/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+
+/* SCU base address */
+static void __iomem *scu_base;
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * Update the AuxCoreBoot0 with boot state for secondary core.
+ * omap_secondary_startup() routine will hold the secondary core till
+ * the AuxCoreBoot1 register is updated with cpu state
+ * A barrier is added to ensure that write buffer is drained
+ */
+ omap_modify_auxcoreboot0(0x200, 0xfffffdff);
+ flush_cache_all();
+ smp_wmb();
+ gic_raise_softirq(cpumask_of(cpu), 1);
+
+ /*
+ * Now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+static void __init wakeup_secondary(void)
+{
+ /*
+ * Write the address of secondary startup routine into the
+ * AuxCoreBoot1 where ROM code will jump and start executing
+ * on secondary core once out of WFE
+ * A barrier is added to ensure that write buffer is drained
+ */
+ omap_auxcoreboot_addr(virt_to_phys(omap_secondary_startup));
+ smp_wmb();
+
+ /*
+ * Send a 'sev' to wake the secondary core from WFE.
+ * Drain the outstanding writes to memory
+ */
+ dsb_sev();
+ mb();
+}
+
+/*
+ * 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)
+{
+ unsigned int i, ncores;
+
+ /* Never released */
+ scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256);
+ BUG_ON(!scu_base);
+
+ ncores = scu_get_core_count(scu_base);
+
+ /* sanity check */
+ if (ncores > NR_CPUS) {
+ printk(KERN_WARNING
+ "OMAP4: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ /*
+ * Initialise the SCU and wake up the secondary core using
+ * wakeup_secondary().
+ */
+ scu_enable(scu_base);
+ wakeup_secondary();
+}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
new file mode 100644
index 00000000..9ef8c29d
--- /dev/null
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -0,0 +1,113 @@
+/*
+ * OMAP4 specific common source file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+
+#ifdef CONFIG_CACHE_L2X0
+void __iomem *l2cache_base;
+#endif
+
+void __iomem *gic_dist_base_addr;
+
+
+void __init gic_init_irq(void)
+{
+ void __iomem *gic_cpu_base;
+
+ /* Static mapping, never released */
+ gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
+ BUG_ON(!gic_dist_base_addr);
+
+ /* Static mapping, never released */
+ gic_cpu_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
+ BUG_ON(!gic_cpu_base);
+
+ gic_init(0, 29, gic_dist_base_addr, gic_cpu_base);
+}
+
+#ifdef CONFIG_CACHE_L2X0
+
+static void omap4_l2x0_disable(void)
+{
+ /* Disable PL310 L2 Cache controller */
+ omap_smc1(0x102, 0x0);
+}
+
+static void omap4_l2x0_set_debug(unsigned long val)
+{
+ /* Program PL310 L2 Cache controller debug register */
+ omap_smc1(0x100, val);
+}
+
+static int __init omap_l2_cache_init(void)
+{
+ u32 aux_ctrl = 0;
+
+ /*
+ * To avoid code running on other OMAPs in
+ * multi-omap builds
+ */
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ /* Static mapping, never released */
+ l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
+ BUG_ON(!l2cache_base);
+
+ /*
+ * 16-way associativity, parity disabled
+ * Way size - 32KB (es1.0)
+ * Way size - 64KB (es2.0 +)
+ */
+ aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
+ (0x1 << 25) |
+ (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
+ (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
+
+ if (omap_rev() == OMAP4430_REV_ES1_0) {
+ aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
+ } else {
+ aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
+ (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+ (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
+ (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
+ }
+ if (omap_rev() != OMAP4430_REV_ES1_0)
+ omap_smc1(0x109, aux_ctrl);
+
+ /* Enable PL310 L2 Cache controller */
+ omap_smc1(0x102, 0x1);
+
+ l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
+
+ /*
+ * Override default outer_cache.disable with a OMAP4
+ * specific one
+ */
+ outer_cache.disable = omap4_l2x0_disable;
+ outer_cache.set_debug = omap4_l2x0_set_debug;
+
+ return 0;
+}
+early_initcall(omap_l2_cache_init);
+#endif
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
new file mode 100644
index 00000000..e69d37d9
--- /dev/null
+++ b/arch/arm/mach-omap2/omap44xx-smc.S
@@ -0,0 +1,57 @@
+/*
+ * OMAP44xx secure APIs file.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Written by Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ *
+ * This program is free software,you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+/*
+ * This is common routine to manage secure monitor API
+ * used to modify the PL310 secure registers.
+ * 'r0' contains the value to be modified and 'r12' contains
+ * the monitor API number. It uses few CPU registers
+ * internally and hence they need be backed up including
+ * link register "lr".
+ * Function signature : void omap_smc1(u32 fn, u32 arg)
+ */
+
+ENTRY(omap_smc1)
+ stmfd sp!, {r2-r12, lr}
+ mov r12, r0
+ mov r0, r1
+ dsb
+ smc #0
+ ldmfd sp!, {r2-r12, pc}
+ENDPROC(omap_smc1)
+
+ENTRY(omap_modify_auxcoreboot0)
+ stmfd sp!, {r1-r12, lr}
+ ldr r12, =0x104
+ dsb
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+ENDPROC(omap_modify_auxcoreboot0)
+
+ENTRY(omap_auxcoreboot_addr)
+ stmfd sp!, {r2-r12, lr}
+ ldr r12, =0x105
+ dsb
+ smc #0
+ ldmfd sp!, {r2-r12, pc}
+ENDPROC(omap_auxcoreboot_addr)
+
+ENTRY(omap_read_auxcoreboot0)
+ stmfd sp!, {r2-r12, lr}
+ ldr r12, =0x103
+ dsb
+ smc #0
+ mov r0, r0, lsr #9
+ ldmfd sp!, {r2-r12, pc}
+ENDPROC(omap_read_auxcoreboot0)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
new file mode 100644
index 00000000..293fa6cd
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -0,0 +1,2371 @@
+/*
+ * omap_hwmod implementation for OMAP2/3/4
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ *
+ * Paul Walmsley, Benoît Cousson, Kevin Hilman
+ *
+ * Created in collaboration with (alphabetical order): Thara Gopinath,
+ * Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari Poussa, Anand
+ * Sawant, Santosh Shilimkar, Richard Woodruff
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Introduction
+ * ------------
+ * One way to view an OMAP SoC is as a collection of largely unrelated
+ * IP blocks connected by interconnects. The IP blocks include
+ * devices such as ARM processors, audio serial interfaces, UARTs,
+ * etc. Some of these devices, like the DSP, are created by TI;
+ * others, like the SGX, largely originate from external vendors. In
+ * TI's documentation, on-chip devices are referred to as "OMAP
+ * modules." Some of these IP blocks are identical across several
+ * OMAP versions. Others are revised frequently.
+ *
+ * These OMAP modules are tied together by various interconnects.
+ * Most of the address and data flow between modules is via OCP-based
+ * interconnects such as the L3 and L4 buses; but there are other
+ * interconnects that distribute the hardware clock tree, handle idle
+ * and reset signaling, supply power, and connect the modules to
+ * various pads or balls on the OMAP package.
+ *
+ * OMAP hwmod provides a consistent way to describe the on-chip
+ * hardware blocks and their integration into the rest of the chip.
+ * This description can be automatically generated from the TI
+ * hardware database. OMAP hwmod provides a standard, consistent API
+ * to reset, enable, idle, and disable these hardware blocks. And
+ * hwmod provides a way for other core code, such as the Linux device
+ * code or the OMAP power management and address space mapping code,
+ * to query the hardware database.
+ *
+ * Using hwmod
+ * -----------
+ * Drivers won't call hwmod functions directly. That is done by the
+ * omap_device code, and in rare occasions, by custom integration code
+ * in arch/arm/ *omap*. The omap_device code includes functions to
+ * build a struct platform_device using omap_hwmod data, and that is
+ * currently how hwmod data is communicated to drivers and to the
+ * Linux driver model. Most drivers will call omap_hwmod functions only
+ * indirectly, via pm_runtime*() functions.
+ *
+ * From a layering perspective, here is where the OMAP hwmod code
+ * fits into the kernel software stack:
+ *
+ * +-------------------------------+
+ * | Device driver code |
+ * | (e.g., drivers/) |
+ * +-------------------------------+
+ * | Linux driver model |
+ * | (platform_device / |
+ * | platform_driver data/code) |
+ * +-------------------------------+
+ * | OMAP core-driver integration |
+ * |(arch/arm/mach-omap2/devices.c)|
+ * +-------------------------------+
+ * | omap_device code |
+ * | (../plat-omap/omap_device.c) |
+ * +-------------------------------+
+ * ----> | omap_hwmod code/data | <-----
+ * | (../mach-omap2/omap_hwmod*) |
+ * +-------------------------------+
+ * | OMAP clock/PRCM/register fns |
+ * | (__raw_{read,write}l, clk*) |
+ * +-------------------------------+
+ *
+ * Device drivers should not contain any OMAP-specific code or data in
+ * them. They should only contain code to operate the IP block that
+ * the driver is responsible for. This is because these IP blocks can
+ * also appear in other SoCs, either from TI (such as DaVinci) or from
+ * other manufacturers; and drivers should be reusable across other
+ * platforms.
+ *
+ * The OMAP hwmod code also will attempt to reset and idle all on-chip
+ * devices upon boot. The goal here is for the kernel to be
+ * completely self-reliant and independent from bootloaders. This is
+ * to ensure a repeatable configuration, both to ensure consistent
+ * runtime behavior, and to make it easier for others to reproduce
+ * bugs.
+ *
+ * OMAP module activity states
+ * ---------------------------
+ * The hwmod code considers modules to be in one of several activity
+ * states. IP blocks start out in an UNKNOWN state, then once they
+ * are registered via the hwmod code, proceed to the REGISTERED state.
+ * Once their clock names are resolved to clock pointers, the module
+ * enters the CLKS_INITED state; and finally, once the module has been
+ * reset and the integration registers programmed, the INITIALIZED state
+ * is entered. The hwmod code will then place the module into either
+ * the IDLE state to save power, or in the case of a critical system
+ * module, the ENABLED state.
+ *
+ * OMAP core integration code can then call omap_hwmod*() functions
+ * directly to move the module between the IDLE, ENABLED, and DISABLED
+ * states, as needed. This is done during both the PM idle loop, and
+ * in the OMAP core integration code's implementation of the PM runtime
+ * functions.
+ *
+ * References
+ * ----------
+ * This is a partial list.
+ * - OMAP2420 Multimedia Processor Silicon Revision 2.1.1, 2.2 (SWPU064)
+ * - OMAP2430 Multimedia Device POP Silicon Revision 2.1 (SWPU090)
+ * - OMAP34xx Multimedia Device Silicon Revision 3.1 (SWPU108)
+ * - OMAP4430 Multimedia Device Silicon Revision 1.0 (SWPU140)
+ * - Open Core Protocol Specification 2.2
+ *
+ * To do:
+ * - handle IO mapping
+ * - bus throughput & module latency measurement code
+ *
+ * XXX add tests at the beginning of each function to ensure the hwmod is
+ * in the appropriate state
+ * XXX error return values should be checked to ensure that they are
+ * appropriate
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include <plat/clock.h>
+#include <plat/omap_hwmod.h>
+#include <plat/prcm.h>
+
+#include "cm2xxx_3xxx.h"
+#include "cm44xx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "mux.h"
+
+/* Maximum microseconds to wait for OMAP module to softreset */
+#define MAX_MODULE_SOFTRESET_WAIT 10000
+
+/* Name of the OMAP hwmod for the MPU */
+#define MPU_INITIATOR_NAME "mpu"
+
+/* omap_hwmod_list contains all registered struct omap_hwmods */
+static LIST_HEAD(omap_hwmod_list);
+
+/* mpu_oh: used to add/remove MPU initiator from sleepdep list */
+static struct omap_hwmod *mpu_oh;
+
+
+/* Private functions */
+
+/**
+ * _update_sysc_cache - return the module OCP_SYSCONFIG register, keep copy
+ * @oh: struct omap_hwmod *
+ *
+ * Load the current value of the hwmod OCP_SYSCONFIG register into the
+ * struct omap_hwmod for later use. Returns -EINVAL if the hwmod has no
+ * OCP_SYSCONFIG register or 0 upon success.
+ */
+static int _update_sysc_cache(struct omap_hwmod *oh)
+{
+ if (!oh->class->sysc) {
+ WARN(1, "omap_hwmod: %s: cannot read OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
+ return -EINVAL;
+ }
+
+ /* XXX ensure module interface clock is up */
+
+ oh->_sysc_cache = omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
+
+ if (!(oh->class->sysc->sysc_flags & SYSC_NO_CACHE))
+ oh->_int_flags |= _HWMOD_SYSCONFIG_LOADED;
+
+ return 0;
+}
+
+/**
+ * _write_sysconfig - write a value to the module's OCP_SYSCONFIG register
+ * @v: OCP_SYSCONFIG value to write
+ * @oh: struct omap_hwmod *
+ *
+ * Write @v into the module class' OCP_SYSCONFIG register, if it has
+ * one. No return value.
+ */
+static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
+{
+ if (!oh->class->sysc) {
+ WARN(1, "omap_hwmod: %s: cannot write OCP_SYSCONFIG: not defined on hwmod's class\n", oh->name);
+ return;
+ }
+
+ /* XXX ensure module interface clock is up */
+
+ /* Module might have lost context, always update cache and register */
+ oh->_sysc_cache = v;
+ omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs);
+}
+
+/**
+ * _set_master_standbymode: set the OCP_SYSCONFIG MIDLEMODE field in @v
+ * @oh: struct omap_hwmod *
+ * @standbymode: MIDLEMODE field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the master standby mode bits in @v to be @standbymode for
+ * the @oh hwmod. Does not write to the hardware. Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
+ u32 *v)
+{
+ u32 mstandby_mask;
+ u8 mstandby_shift;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_MIDLEMODE))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ mstandby_shift = oh->class->sysc->sysc_fields->midle_shift;
+ mstandby_mask = (0x3 << mstandby_shift);
+
+ *v &= ~mstandby_mask;
+ *v |= __ffs(standbymode) << mstandby_shift;
+
+ return 0;
+}
+
+/**
+ * _set_slave_idlemode: set the OCP_SYSCONFIG SIDLEMODE field in @v
+ * @oh: struct omap_hwmod *
+ * @idlemode: SIDLEMODE field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the slave idle mode bits in @v to be @idlemode for the @oh
+ * hwmod. Does not write to the hardware. Returns -EINVAL upon error
+ * or 0 upon success.
+ */
+static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
+{
+ u32 sidle_mask;
+ u8 sidle_shift;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_SIDLEMODE))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ sidle_shift = oh->class->sysc->sysc_fields->sidle_shift;
+ sidle_mask = (0x3 << sidle_shift);
+
+ *v &= ~sidle_mask;
+ *v |= __ffs(idlemode) << sidle_shift;
+
+ return 0;
+}
+
+/**
+ * _set_clockactivity: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
+ * @oh: struct omap_hwmod *
+ * @clockact: CLOCKACTIVITY field bits
+ * @v: pointer to register contents to modify
+ *
+ * Update the clockactivity mode bits in @v to be @clockact for the
+ * @oh hwmod. Used for additional powersaving on some modules. Does
+ * not write to the hardware. Returns -EINVAL upon error or 0 upon
+ * success.
+ */
+static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
+{
+ u32 clkact_mask;
+ u8 clkact_shift;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ clkact_shift = oh->class->sysc->sysc_fields->clkact_shift;
+ clkact_mask = (0x3 << clkact_shift);
+
+ *v &= ~clkact_mask;
+ *v |= clockact << clkact_shift;
+
+ return 0;
+}
+
+/**
+ * _set_softreset: set OCP_SYSCONFIG.CLOCKACTIVITY bits in @v
+ * @oh: struct omap_hwmod *
+ * @v: pointer to register contents to modify
+ *
+ * Set the SOFTRESET bit in @v for hwmod @oh. Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_softreset(struct omap_hwmod *oh, u32 *v)
+{
+ u32 softrst_mask;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift);
+
+ *v |= softrst_mask;
+
+ return 0;
+}
+
+/**
+ * _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ * @v: pointer to register contents to modify
+ *
+ * Update the module autoidle bit in @v to be @autoidle for the @oh
+ * hwmod. The autoidle bit controls whether the module can gate
+ * internal clocks automatically when it isn't doing anything; the
+ * exact function of this bit varies on a per-module basis. This
+ * function does not write to the hardware. Returns -EINVAL upon
+ * error or 0 upon success.
+ */
+static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
+ u32 *v)
+{
+ u32 autoidle_mask;
+ u8 autoidle_shift;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_AUTOIDLE))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ autoidle_shift = oh->class->sysc->sysc_fields->autoidle_shift;
+ autoidle_mask = (0x1 << autoidle_shift);
+
+ *v &= ~autoidle_mask;
+ *v |= autoidle << autoidle_shift;
+
+ return 0;
+}
+
+/**
+ * _enable_wakeup: set OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
+ * @oh: struct omap_hwmod *
+ *
+ * Allow the hardware module @oh to send wakeups. Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
+{
+ u32 wakeup_mask;
+
+ if (!oh->class->sysc ||
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
+
+ *v |= wakeup_mask;
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
+
+ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+ oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
+
+ return 0;
+}
+
+/**
+ * _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hardware module @oh to send wakeups. Returns -EINVAL
+ * upon error or 0 upon success.
+ */
+static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
+{
+ u32 wakeup_mask;
+
+ if (!oh->class->sysc ||
+ !((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
+ (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)))
+ return -EINVAL;
+
+ if (!oh->class->sysc->sysc_fields) {
+ WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
+ return -EINVAL;
+ }
+
+ wakeup_mask = (0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
+
+ *v &= ~wakeup_mask;
+
+ if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
+
+ /* XXX test pwrdm_get_wken for this hwmod's subsystem */
+
+ oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
+
+ return 0;
+}
+
+/**
+ * _add_initiator_dep: prevent @oh from smart-idling while @init_oh is active
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hardware module @oh from entering idle while the
+ * hardare module initiator @init_oh is active. Useful when a module
+ * will be accessed by a particular initiator (e.g., if a module will
+ * be accessed by the IVA, there should be a sleepdep between the IVA
+ * initiator and the module). Only applies to modules in smart-idle
+ * mode. If the clockdomain is marked as not needing autodeps, return
+ * 0 without doing anything. Otherwise, returns -EINVAL upon error or
+ * passes along clkdm_add_sleepdep() value upon success.
+ */
+static int _add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
+{
+ if (!oh->_clk)
+ return -EINVAL;
+
+ if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+ return 0;
+
+ return clkdm_add_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+}
+
+/**
+ * _del_initiator_dep: allow @oh to smart-idle even if @init_oh is active
+ * @oh: struct omap_hwmod *
+ *
+ * Allow the hardware module @oh to enter idle while the hardare
+ * module initiator @init_oh is active. Useful when a module will not
+ * be accessed by a particular initiator (e.g., if a module will not
+ * be accessed by the IVA, there should be no sleepdep between the IVA
+ * initiator and the module). Only applies to modules in smart-idle
+ * mode. If the clockdomain is marked as not needing autodeps, return
+ * 0 without doing anything. Returns -EINVAL upon error or passes
+ * along clkdm_del_sleepdep() value upon success.
+ */
+static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
+{
+ if (!oh->_clk)
+ return -EINVAL;
+
+ if (oh->_clk->clkdm && oh->_clk->clkdm->flags & CLKDM_NO_AUTODEPS)
+ return 0;
+
+ return clkdm_del_sleepdep(oh->_clk->clkdm, init_oh->_clk->clkdm);
+}
+
+/**
+ * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks(). Populates the @oh _clk (main
+ * functional clock pointer) if a main_clk is present. Returns 0 on
+ * success or -EINVAL on error.
+ */
+static int _init_main_clk(struct omap_hwmod *oh)
+{
+ int ret = 0;
+
+ if (!oh->main_clk)
+ return 0;
+
+ oh->_clk = omap_clk_get_by_name(oh->main_clk);
+ if (!oh->_clk) {
+ pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n",
+ oh->name, oh->main_clk);
+ return -EINVAL;
+ }
+
+ if (!oh->_clk->clkdm)
+ pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n",
+ oh->main_clk, oh->_clk->name);
+
+ return ret;
+}
+
+/**
+ * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks(). Populates the @oh OCP slave interface
+ * clock pointers. Returns 0 on success or -EINVAL on error.
+ */
+static int _init_interface_clks(struct omap_hwmod *oh)
+{
+ struct clk *c;
+ int i;
+ int ret = 0;
+
+ if (oh->slaves_cnt == 0)
+ return 0;
+
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+
+ if (!os->clk)
+ continue;
+
+ c = omap_clk_get_by_name(os->clk);
+ if (!c) {
+ pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n",
+ oh->name, os->clk);
+ ret = -EINVAL;
+ }
+ os->_clk = c;
+ }
+
+ return ret;
+}
+
+/**
+ * _init_opt_clk - get a struct clk * for the the hwmod's optional clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Called from _init_clocks(). Populates the @oh omap_hwmod_opt_clk
+ * clock pointers. Returns 0 on success or -EINVAL on error.
+ */
+static int _init_opt_clks(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ struct clk *c;
+ int i;
+ int ret = 0;
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) {
+ c = omap_clk_get_by_name(oc->clk);
+ if (!c) {
+ pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n",
+ oh->name, oc->clk);
+ ret = -EINVAL;
+ }
+ oc->_clk = c;
+ }
+
+ return ret;
+}
+
+/**
+ * _enable_clocks - enable hwmod main clock and interface clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Enables all clocks necessary for register reads and writes to succeed
+ * on the hwmod @oh. Returns 0.
+ */
+static int _enable_clocks(struct omap_hwmod *oh)
+{
+ int i;
+
+ pr_debug("omap_hwmod: %s: enabling clocks\n", oh->name);
+
+ if (oh->_clk)
+ clk_enable(oh->_clk);
+
+ if (oh->slaves_cnt > 0) {
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+ struct clk *c = os->_clk;
+
+ if (c && (os->flags & OCPIF_SWSUP_IDLE))
+ clk_enable(c);
+ }
+ }
+
+ /* The opt clocks are controlled by the device driver. */
+
+ return 0;
+}
+
+/**
+ * _disable_clocks - disable hwmod main clock and interface clocks
+ * @oh: struct omap_hwmod *
+ *
+ * Disables the hwmod @oh main functional and interface clocks. Returns 0.
+ */
+static int _disable_clocks(struct omap_hwmod *oh)
+{
+ int i;
+
+ pr_debug("omap_hwmod: %s: disabling clocks\n", oh->name);
+
+ if (oh->_clk)
+ clk_disable(oh->_clk);
+
+ if (oh->slaves_cnt > 0) {
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+ struct clk *c = os->_clk;
+
+ if (c && (os->flags & OCPIF_SWSUP_IDLE))
+ clk_disable(c);
+ }
+ }
+
+ /* The opt clocks are controlled by the device driver. */
+
+ return 0;
+}
+
+static void _enable_optional_clocks(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ int i;
+
+ pr_debug("omap_hwmod: %s: enabling optional clocks\n", oh->name);
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk) {
+ pr_debug("omap_hwmod: enable %s:%s\n", oc->role,
+ oc->_clk->name);
+ clk_enable(oc->_clk);
+ }
+}
+
+static void _disable_optional_clocks(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_opt_clk *oc;
+ int i;
+
+ pr_debug("omap_hwmod: %s: disabling optional clocks\n", oh->name);
+
+ for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++)
+ if (oc->_clk) {
+ pr_debug("omap_hwmod: disable %s:%s\n", oc->role,
+ oc->_clk->name);
+ clk_disable(oc->_clk);
+ }
+}
+
+/**
+ * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the array index of the OCP slave port that the MPU
+ * addresses the device on, or -EINVAL upon error or not found.
+ */
+static int __init _find_mpu_port_index(struct omap_hwmod *oh)
+{
+ int i;
+ int found = 0;
+
+ if (!oh || oh->slaves_cnt == 0)
+ return -EINVAL;
+
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+
+ if (os->user & OCP_USER_MPU) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ pr_debug("omap_hwmod: %s: MPU OCP slave port ID %d\n",
+ oh->name, i);
+ else
+ pr_debug("omap_hwmod: %s: no MPU OCP slave port found\n",
+ oh->name);
+
+ return (found) ? i : -EINVAL;
+}
+
+/**
+ * _find_mpu_rt_base - find hwmod register target base addr accessible by MPU
+ * @oh: struct omap_hwmod *
+ *
+ * Return the virtual address of the base of the register target of
+ * device @oh, or NULL on error.
+ */
+static void __iomem * __init _find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
+{
+ struct omap_hwmod_ocp_if *os;
+ struct omap_hwmod_addr_space *mem;
+ int i;
+ int found = 0;
+ void __iomem *va_start;
+
+ if (!oh || oh->slaves_cnt == 0)
+ return NULL;
+
+ os = oh->slaves[index];
+
+ for (i = 0, mem = os->addr; i < os->addr_cnt; i++, mem++) {
+ if (mem->flags & ADDR_TYPE_RT) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
+ if (!va_start) {
+ pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
+ return NULL;
+ }
+ pr_debug("omap_hwmod: %s: MPU register target at va %p\n",
+ oh->name, va_start);
+ } else {
+ pr_debug("omap_hwmod: %s: no MPU register target found\n",
+ oh->name);
+ }
+
+ return (found) ? va_start : NULL;
+}
+
+/**
+ * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * If module is marked as SWSUP_SIDLE, force the module out of slave
+ * idle; otherwise, configure it for smart-idle. If module is marked
+ * as SWSUP_MSUSPEND, force the module out of master standby;
+ * otherwise, configure it for smart-standby. No return value.
+ */
+static void _enable_sysc(struct omap_hwmod *oh)
+{
+ u8 idlemode, sf;
+ u32 v;
+
+ if (!oh->class->sysc)
+ return;
+
+ v = oh->_sysc_cache;
+ sf = oh->class->sysc->sysc_flags;
+
+ if (sf & SYSC_HAS_SIDLEMODE) {
+ idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
+ HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+ _set_slave_idlemode(oh, idlemode, &v);
+ }
+
+ if (sf & SYSC_HAS_MIDLEMODE) {
+ idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
+ HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+ _set_master_standbymode(oh, idlemode, &v);
+ }
+
+ /*
+ * XXX The clock framework should handle this, by
+ * calling into this code. But this must wait until the
+ * clock structures are tagged with omap_hwmod entries
+ */
+ if ((oh->flags & HWMOD_SET_DEFAULT_CLOCKACT) &&
+ (sf & SYSC_HAS_CLOCKACTIVITY))
+ _set_clockactivity(oh, oh->class->sysc->clockact, &v);
+
+ /* If slave is in SMARTIDLE, also enable wakeup */
+ if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
+ _enable_wakeup(oh, &v);
+
+ _write_sysconfig(v, oh);
+
+ /*
+ * Set the autoidle bit only after setting the smartidle bit
+ * Setting this will not have any impact on the other modules.
+ */
+ if (sf & SYSC_HAS_AUTOIDLE) {
+ idlemode = (oh->flags & HWMOD_NO_OCP_AUTOIDLE) ?
+ 0 : 1;
+ _set_module_autoidle(oh, idlemode, &v);
+ _write_sysconfig(v, oh);
+ }
+}
+
+/**
+ * _idle_sysc - try to put a module into idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * If module is marked as SWSUP_SIDLE, force the module into slave
+ * idle; otherwise, configure it for smart-idle. If module is marked
+ * as SWSUP_MSUSPEND, force the module into master standby; otherwise,
+ * configure it for smart-standby. No return value.
+ */
+static void _idle_sysc(struct omap_hwmod *oh)
+{
+ u8 idlemode, sf;
+ u32 v;
+
+ if (!oh->class->sysc)
+ return;
+
+ v = oh->_sysc_cache;
+ sf = oh->class->sysc->sysc_flags;
+
+ if (sf & SYSC_HAS_SIDLEMODE) {
+ idlemode = (oh->flags & HWMOD_SWSUP_SIDLE) ?
+ HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
+ _set_slave_idlemode(oh, idlemode, &v);
+ }
+
+ if (sf & SYSC_HAS_MIDLEMODE) {
+ idlemode = (oh->flags & HWMOD_SWSUP_MSTANDBY) ?
+ HWMOD_IDLEMODE_FORCE : HWMOD_IDLEMODE_SMART;
+ _set_master_standbymode(oh, idlemode, &v);
+ }
+
+ /* If slave is in SMARTIDLE, also enable wakeup */
+ if ((sf & SYSC_HAS_SIDLEMODE) && !(oh->flags & HWMOD_SWSUP_SIDLE))
+ _enable_wakeup(oh, &v);
+
+ _write_sysconfig(v, oh);
+}
+
+/**
+ * _shutdown_sysc - force a module into idle via OCP_SYSCONFIG
+ * @oh: struct omap_hwmod *
+ *
+ * Force the module into slave idle and master suspend. No return
+ * value.
+ */
+static void _shutdown_sysc(struct omap_hwmod *oh)
+{
+ u32 v;
+ u8 sf;
+
+ if (!oh->class->sysc)
+ return;
+
+ v = oh->_sysc_cache;
+ sf = oh->class->sysc->sysc_flags;
+
+ if (sf & SYSC_HAS_SIDLEMODE)
+ _set_slave_idlemode(oh, HWMOD_IDLEMODE_FORCE, &v);
+
+ if (sf & SYSC_HAS_MIDLEMODE)
+ _set_master_standbymode(oh, HWMOD_IDLEMODE_FORCE, &v);
+
+ if (sf & SYSC_HAS_AUTOIDLE)
+ _set_module_autoidle(oh, 1, &v);
+
+ _write_sysconfig(v, oh);
+}
+
+/**
+ * _lookup - find an omap_hwmod by name
+ * @name: find an omap_hwmod by name
+ *
+ * Return a pointer to an omap_hwmod by name, or NULL if not found.
+ */
+static struct omap_hwmod *_lookup(const char *name)
+{
+ struct omap_hwmod *oh, *temp_oh;
+
+ oh = NULL;
+
+ list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+ if (!strcmp(name, temp_oh->name)) {
+ oh = temp_oh;
+ break;
+ }
+ }
+
+ return oh;
+}
+
+/**
+ * _init_clocks - clk_get() all clocks associated with this hwmod
+ * @oh: struct omap_hwmod *
+ * @data: not used; pass NULL
+ *
+ * Called by omap_hwmod_setup_*() (after omap2_clk_init()).
+ * Resolves all clock names embedded in the hwmod. Returns 0 on
+ * success, or a negative error code on failure.
+ */
+static int _init_clocks(struct omap_hwmod *oh, void *data)
+{
+ int ret = 0;
+
+ if (oh->_state != _HWMOD_STATE_REGISTERED)
+ return 0;
+
+ pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name);
+
+ ret |= _init_main_clk(oh);
+ ret |= _init_interface_clks(oh);
+ ret |= _init_opt_clks(oh);
+
+ if (!ret)
+ oh->_state = _HWMOD_STATE_CLKS_INITED;
+
+ return ret;
+}
+
+/**
+ * _wait_target_ready - wait for a module to leave slave idle
+ * @oh: struct omap_hwmod *
+ *
+ * Wait for a module @oh to leave slave idle. Returns 0 if the module
+ * does not have an IDLEST bit or if the module successfully leaves
+ * slave idle; otherwise, pass along the return value of the
+ * appropriate *_cm_wait_module_ready() function.
+ */
+static int _wait_target_ready(struct omap_hwmod *oh)
+{
+ struct omap_hwmod_ocp_if *os;
+ int ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return 0;
+
+ os = oh->slaves[oh->_mpu_port_index];
+
+ if (oh->flags & HWMOD_NO_IDLEST)
+ return 0;
+
+ /* XXX check module SIDLEMODE */
+
+ /* XXX check clock enable states */
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+ ret = omap2_cm_wait_module_ready(oh->prcm.omap2.module_offs,
+ oh->prcm.omap2.idlest_reg_id,
+ oh->prcm.omap2.idlest_idle_bit);
+ } else if (cpu_is_omap44xx()) {
+ ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg);
+ } else {
+ BUG();
+ };
+
+ return ret;
+}
+
+/**
+ * _lookup_hardreset - fill register bit info for this hwmod/reset line
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line in the context of this hwmod
+ * @ohri: struct omap_hwmod_rst_info * that this function will fill in
+ *
+ * Return the bit position of the reset line that match the
+ * input name. Return -ENOENT if not found.
+ */
+static u8 _lookup_hardreset(struct omap_hwmod *oh, const char *name,
+ struct omap_hwmod_rst_info *ohri)
+{
+ int i;
+
+ for (i = 0; i < oh->rst_lines_cnt; i++) {
+ const char *rst_line = oh->rst_lines[i].name;
+ if (!strcmp(rst_line, name)) {
+ ohri->rst_shift = oh->rst_lines[i].rst_shift;
+ ohri->st_shift = oh->rst_lines[i].st_shift;
+ pr_debug("omap_hwmod: %s: %s: %s: rst %d st %d\n",
+ oh->name, __func__, rst_line, ohri->rst_shift,
+ ohri->st_shift);
+
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+/**
+ * _assert_hardreset - assert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to lookup and assert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP.
+ */
+static int _assert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ u8 ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return omap2_prm_assert_hardreset(oh->prcm.omap2.module_offs,
+ ohri.rst_shift);
+ else if (cpu_is_omap44xx())
+ return omap4_prm_assert_hardreset(oh->prcm.omap4.rstctrl_reg,
+ ohri.rst_shift);
+ else
+ return -EINVAL;
+}
+
+/**
+ * _deassert_hardreset - deassert the HW reset line of submodules contained
+ * in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and deassert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP.
+ */
+static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ int ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+ ret = omap2_prm_deassert_hardreset(oh->prcm.omap2.module_offs,
+ ohri.rst_shift,
+ ohri.st_shift);
+ } else if (cpu_is_omap44xx()) {
+ if (ohri.st_shift)
+ pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
+ oh->name, name);
+ ret = omap4_prm_deassert_hardreset(oh->prcm.omap4.rstctrl_reg,
+ ohri.rst_shift);
+ } else {
+ return -EINVAL;
+ }
+
+ if (ret == -EBUSY)
+ pr_warning("omap_hwmod: %s: failed to hardreset\n", oh->name);
+
+ return ret;
+}
+
+/**
+ * _read_hardreset - read the HW reset line state of submodules
+ * contained in the hwmod module
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and read
+ *
+ * Return the state of the reset line.
+ */
+static int _read_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ struct omap_hwmod_rst_info ohri;
+ u8 ret;
+
+ if (!oh)
+ return -EINVAL;
+
+ ret = _lookup_hardreset(oh, name, &ohri);
+ if (IS_ERR_VALUE(ret))
+ return ret;
+
+ if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+ return omap2_prm_is_hardreset_asserted(oh->prcm.omap2.module_offs,
+ ohri.st_shift);
+ } else if (cpu_is_omap44xx()) {
+ return omap4_prm_is_hardreset_asserted(oh->prcm.omap4.rstctrl_reg,
+ ohri.rst_shift);
+ } else {
+ return -EINVAL;
+ }
+}
+
+/**
+ * _ocp_softreset - reset an omap_hwmod via the OCP_SYSCONFIG bit
+ * @oh: struct omap_hwmod *
+ *
+ * Resets an omap_hwmod @oh via the OCP_SYSCONFIG bit. hwmod must be
+ * enabled for this to work. Returns -EINVAL if the hwmod cannot be
+ * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
+ * the module did not reset in time, or 0 upon success.
+ *
+ * In OMAP3 a specific SYSSTATUS register is used to get the reset status.
+ * Starting in OMAP4, some IPs do not have SYSSTATUS registers and instead
+ * use the SYSCONFIG softreset bit to provide the status.
+ *
+ * Note that some IP like McBSP do have reset control but don't have
+ * reset status.
+ */
+static int _ocp_softreset(struct omap_hwmod *oh)
+{
+ u32 v;
+ int c = 0;
+ int ret = 0;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_SOFTRESET))
+ return -EINVAL;
+
+ /* clocks must be on for this operation */
+ if (oh->_state != _HWMOD_STATE_ENABLED) {
+ pr_warning("omap_hwmod: %s: reset can only be entered from "
+ "enabled state\n", oh->name);
+ return -EINVAL;
+ }
+
+ /* For some modules, all optionnal clocks need to be enabled as well */
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _enable_optional_clocks(oh);
+
+ pr_debug("omap_hwmod: %s: resetting via OCP SOFTRESET\n", oh->name);
+
+ v = oh->_sysc_cache;
+ ret = _set_softreset(oh, &v);
+ if (ret)
+ goto dis_opt_clks;
+ _write_sysconfig(v, oh);
+
+ if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
+ omap_test_timeout((omap_hwmod_read(oh,
+ oh->class->sysc->syss_offs)
+ & SYSS_RESETDONE_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+ else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS)
+ omap_test_timeout(!(omap_hwmod_read(oh,
+ oh->class->sysc->sysc_offs)
+ & SYSC_TYPE2_SOFTRESET_MASK),
+ MAX_MODULE_SOFTRESET_WAIT, c);
+
+ if (c == MAX_MODULE_SOFTRESET_WAIT)
+ pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n",
+ oh->name, MAX_MODULE_SOFTRESET_WAIT);
+ else
+ pr_debug("omap_hwmod: %s: softreset in %d usec\n", oh->name, c);
+
+ /*
+ * XXX add _HWMOD_STATE_WEDGED for modules that don't come back from
+ * _wait_target_ready() or _reset()
+ */
+
+ ret = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0;
+
+dis_opt_clks:
+ if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET)
+ _disable_optional_clocks(oh);
+
+ return ret;
+}
+
+/**
+ * _reset - reset an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Resets an omap_hwmod @oh. The default software reset mechanism for
+ * most OMAP IP blocks is triggered via the OCP_SYSCONFIG.SOFTRESET
+ * bit. However, some hwmods cannot be reset via this method: some
+ * are not targets and therefore have no OCP header registers to
+ * access; others (like the IVA) have idiosyncratic reset sequences.
+ * So for these relatively rare cases, custom reset code can be
+ * supplied in the struct omap_hwmod_class .reset function pointer.
+ * Passes along the return value from either _reset() or the custom
+ * reset function - these must return -EINVAL if the hwmod cannot be
+ * reset this way or if the hwmod is in the wrong state, -ETIMEDOUT if
+ * the module did not reset in time, or 0 upon success.
+ */
+static int _reset(struct omap_hwmod *oh)
+{
+ int ret;
+
+ pr_debug("omap_hwmod: %s: resetting\n", oh->name);
+
+ ret = (oh->class->reset) ? oh->class->reset(oh) : _ocp_softreset(oh);
+
+ return ret;
+}
+
+/**
+ * _enable - enable an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Enables an omap_hwmod @oh such that the MPU can access the hwmod's
+ * register target. Returns -EINVAL if the hwmod is in the wrong
+ * state or passes along the return value of _wait_target_ready().
+ */
+static int _enable(struct omap_hwmod *oh)
+{
+ int r;
+
+ if (oh->_state != _HWMOD_STATE_INITIALIZED &&
+ oh->_state != _HWMOD_STATE_IDLE &&
+ oh->_state != _HWMOD_STATE_DISABLED) {
+ WARN(1, "omap_hwmod: %s: enabled state can only be entered "
+ "from initialized, idle, or disabled state\n", oh->name);
+ return -EINVAL;
+ }
+
+ pr_debug("omap_hwmod: %s: enabling\n", oh->name);
+
+ /*
+ * If an IP contains only one HW reset line, then de-assert it in order
+ * to allow to enable the clocks. Otherwise the PRCM will return
+ * Intransition status, and the init will failed.
+ */
+ if ((oh->_state == _HWMOD_STATE_INITIALIZED ||
+ oh->_state == _HWMOD_STATE_DISABLED) && oh->rst_lines_cnt == 1)
+ _deassert_hardreset(oh, oh->rst_lines[0].name);
+
+ /* Mux pins for device runtime if populated */
+ if (oh->mux && (!oh->mux->enabled ||
+ ((oh->_state == _HWMOD_STATE_IDLE) &&
+ oh->mux->pads_dynamic)))
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED);
+
+ _add_initiator_dep(oh, mpu_oh);
+ _enable_clocks(oh);
+
+ r = _wait_target_ready(oh);
+ if (!r) {
+ oh->_state = _HWMOD_STATE_ENABLED;
+
+ /* Access the sysconfig only if the target is ready */
+ if (oh->class->sysc) {
+ if (!(oh->_int_flags & _HWMOD_SYSCONFIG_LOADED))
+ _update_sysc_cache(oh);
+ _enable_sysc(oh);
+ }
+ } else {
+ _disable_clocks(oh);
+ pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
+ oh->name, r);
+ }
+
+ return r;
+}
+
+/**
+ * _idle - idle an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Idles an omap_hwmod @oh. This should be called once the hwmod has
+ * no further work. Returns -EINVAL if the hwmod is in the wrong
+ * state or returns 0.
+ */
+static int _idle(struct omap_hwmod *oh)
+{
+ if (oh->_state != _HWMOD_STATE_ENABLED) {
+ WARN(1, "omap_hwmod: %s: idle state can only be entered from "
+ "enabled state\n", oh->name);
+ return -EINVAL;
+ }
+
+ pr_debug("omap_hwmod: %s: idling\n", oh->name);
+
+ if (oh->class->sysc)
+ _idle_sysc(oh);
+ _del_initiator_dep(oh, mpu_oh);
+ _disable_clocks(oh);
+
+ /* Mux pins for device idle if populated */
+ if (oh->mux && oh->mux->pads_dynamic)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_IDLE);
+
+ oh->_state = _HWMOD_STATE_IDLE;
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_set_ocp_autoidle - set the hwmod's OCP autoidle bit
+ * @oh: struct omap_hwmod *
+ * @autoidle: desired AUTOIDLE bitfield value (0 or 1)
+ *
+ * Sets the IP block's OCP autoidle bit in hardware, and updates our
+ * local copy. Intended to be used by drivers that require
+ * direct manipulation of the AUTOIDLE bits.
+ * Returns -EINVAL if @oh is null or is not in the ENABLED state, or passes
+ * along the return value from _set_module_autoidle().
+ *
+ * Any users of this function should be scrutinized carefully.
+ */
+int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle)
+{
+ u32 v;
+ int retval = 0;
+ unsigned long flags;
+
+ if (!oh || oh->_state != _HWMOD_STATE_ENABLED)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+
+ v = oh->_sysc_cache;
+
+ retval = _set_module_autoidle(oh, autoidle, &v);
+
+ if (!retval)
+ _write_sysconfig(v, oh);
+
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return retval;
+}
+
+/**
+ * _shutdown - shutdown an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Shut down an omap_hwmod @oh. This should be called when the driver
+ * used for the hwmod is removed or unloaded or if the driver is not
+ * used by the system. Returns -EINVAL if the hwmod is in the wrong
+ * state or returns 0.
+ */
+static int _shutdown(struct omap_hwmod *oh)
+{
+ int ret;
+ u8 prev_state;
+
+ if (oh->_state != _HWMOD_STATE_IDLE &&
+ oh->_state != _HWMOD_STATE_ENABLED) {
+ WARN(1, "omap_hwmod: %s: disabled state can only be entered "
+ "from idle, or enabled state\n", oh->name);
+ return -EINVAL;
+ }
+
+ pr_debug("omap_hwmod: %s: disabling\n", oh->name);
+
+ if (oh->class->pre_shutdown) {
+ prev_state = oh->_state;
+ if (oh->_state == _HWMOD_STATE_IDLE)
+ _enable(oh);
+ ret = oh->class->pre_shutdown(oh);
+ if (ret) {
+ if (prev_state == _HWMOD_STATE_IDLE)
+ _idle(oh);
+ return ret;
+ }
+ }
+
+ if (oh->class->sysc)
+ _shutdown_sysc(oh);
+
+ /*
+ * If an IP contains only one HW reset line, then assert it
+ * before disabling the clocks and shutting down the IP.
+ */
+ if (oh->rst_lines_cnt == 1)
+ _assert_hardreset(oh, oh->rst_lines[0].name);
+
+ /* clocks and deps are already disabled in idle */
+ if (oh->_state == _HWMOD_STATE_ENABLED) {
+ _del_initiator_dep(oh, mpu_oh);
+ /* XXX what about the other system initiators here? dma, dsp */
+ _disable_clocks(oh);
+ }
+ /* XXX Should this code also force-disable the optional clocks? */
+
+ /* Mux pins to safe mode or use populated off mode values */
+ if (oh->mux)
+ omap_hwmod_mux(oh->mux, _HWMOD_STATE_DISABLED);
+
+ oh->_state = _HWMOD_STATE_DISABLED;
+
+ return 0;
+}
+
+/**
+ * _setup - do initial configuration of omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
+ * OCP_SYSCONFIG register. Returns 0.
+ */
+static int _setup(struct omap_hwmod *oh, void *data)
+{
+ int i, r;
+ u8 postsetup_state;
+
+ if (oh->_state != _HWMOD_STATE_CLKS_INITED)
+ return 0;
+
+ /* Set iclk autoidle mode */
+ if (oh->slaves_cnt > 0) {
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os = oh->slaves[i];
+ struct clk *c = os->_clk;
+
+ if (!c)
+ continue;
+
+ if (os->flags & OCPIF_SWSUP_IDLE) {
+ /* XXX omap_iclk_deny_idle(c); */
+ } else {
+ /* XXX omap_iclk_allow_idle(c); */
+ clk_enable(c);
+ }
+ }
+ }
+
+ oh->_state = _HWMOD_STATE_INITIALIZED;
+
+ /*
+ * In the case of hwmod with hardreset that should not be
+ * de-assert at boot time, we have to keep the module
+ * initialized, because we cannot enable it properly with the
+ * reset asserted. Exit without warning because that behavior is
+ * expected.
+ */
+ if ((oh->flags & HWMOD_INIT_NO_RESET) && oh->rst_lines_cnt == 1)
+ return 0;
+
+ r = _enable(oh);
+ if (r) {
+ pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
+ oh->name, oh->_state);
+ return 0;
+ }
+
+ if (!(oh->flags & HWMOD_INIT_NO_RESET)) {
+ _reset(oh);
+
+ /*
+ * OCP_SYSCONFIG bits need to be reprogrammed after a softreset.
+ * The _enable() function should be split to
+ * avoid the rewrite of the OCP_SYSCONFIG register.
+ */
+ if (oh->class->sysc) {
+ _update_sysc_cache(oh);
+ _enable_sysc(oh);
+ }
+ }
+
+ postsetup_state = oh->_postsetup_state;
+ if (postsetup_state == _HWMOD_STATE_UNKNOWN)
+ postsetup_state = _HWMOD_STATE_ENABLED;
+
+ /*
+ * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data -
+ * it should be set by the core code as a runtime flag during startup
+ */
+ if ((oh->flags & HWMOD_INIT_NO_IDLE) &&
+ (postsetup_state == _HWMOD_STATE_IDLE))
+ postsetup_state = _HWMOD_STATE_ENABLED;
+
+ if (postsetup_state == _HWMOD_STATE_IDLE)
+ _idle(oh);
+ else if (postsetup_state == _HWMOD_STATE_DISABLED)
+ _shutdown(oh);
+ else if (postsetup_state != _HWMOD_STATE_ENABLED)
+ WARN(1, "hwmod: %s: unknown postsetup state %d! defaulting to enabled\n",
+ oh->name, postsetup_state);
+
+ return 0;
+}
+
+/**
+ * _register - register a struct omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Registers the omap_hwmod @oh. Returns -EEXIST if an omap_hwmod
+ * already has been registered by the same name; -EINVAL if the
+ * omap_hwmod is in the wrong state, if @oh is NULL, if the
+ * omap_hwmod's class field is NULL; if the omap_hwmod is missing a
+ * name, or if the omap_hwmod's class is missing a name; or 0 upon
+ * success.
+ *
+ * XXX The data should be copied into bootmem, so the original data
+ * should be marked __initdata and freed after init. This would allow
+ * unneeded omap_hwmods to be freed on multi-OMAP configurations. Note
+ * that the copy process would be relatively complex due to the large number
+ * of substructures.
+ */
+static int __init _register(struct omap_hwmod *oh)
+{
+ int ms_id;
+
+ if (!oh || !oh->name || !oh->class || !oh->class->name ||
+ (oh->_state != _HWMOD_STATE_UNKNOWN))
+ return -EINVAL;
+
+ pr_debug("omap_hwmod: %s: registering\n", oh->name);
+
+ if (_lookup(oh->name))
+ return -EEXIST;
+
+ ms_id = _find_mpu_port_index(oh);
+ if (!IS_ERR_VALUE(ms_id))
+ oh->_mpu_port_index = ms_id;
+ else
+ oh->_int_flags |= _HWMOD_NO_MPU_PORT;
+
+ list_add_tail(&oh->node, &omap_hwmod_list);
+
+ spin_lock_init(&oh->_lock);
+
+ oh->_state = _HWMOD_STATE_REGISTERED;
+
+ /*
+ * XXX Rather than doing a strcmp(), this should test a flag
+ * set in the hwmod data, inserted by the autogenerator code.
+ */
+ if (!strcmp(oh->name, MPU_INITIATOR_NAME))
+ mpu_oh = oh;
+
+ return 0;
+}
+
+
+/* Public functions */
+
+u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs)
+{
+ if (oh->flags & HWMOD_16BIT_REG)
+ return __raw_readw(oh->_mpu_rt_va + reg_offs);
+ else
+ return __raw_readl(oh->_mpu_rt_va + reg_offs);
+}
+
+void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs)
+{
+ if (oh->flags & HWMOD_16BIT_REG)
+ __raw_writew(v, oh->_mpu_rt_va + reg_offs);
+ else
+ __raw_writel(v, oh->_mpu_rt_va + reg_offs);
+}
+
+/**
+ * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
+ * @oh: struct omap_hwmod *
+ * @idlemode: SIDLEMODE field bits (shifted to bit 0)
+ *
+ * Sets the IP block's OCP slave idlemode in hardware, and updates our
+ * local copy. Intended to be used by drivers that have some erratum
+ * that requires direct manipulation of the SIDLEMODE bits. Returns
+ * -EINVAL if @oh is null, or passes along the return value from
+ * _set_slave_idlemode().
+ *
+ * XXX Does this function have any current users? If not, we should
+ * remove it; it is better to let the rest of the hwmod code handle this.
+ * Any users of this function should be scrutinized carefully.
+ */
+int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
+{
+ u32 v;
+ int retval = 0;
+
+ if (!oh)
+ return -EINVAL;
+
+ v = oh->_sysc_cache;
+
+ retval = _set_slave_idlemode(oh, idlemode, &v);
+ if (!retval)
+ _write_sysconfig(v, oh);
+
+ return retval;
+}
+
+/**
+ * omap_hwmod_lookup - look up a registered omap_hwmod by name
+ * @name: name of the omap_hwmod to look up
+ *
+ * Given a @name of an omap_hwmod, return a pointer to the registered
+ * struct omap_hwmod *, or NULL upon error.
+ */
+struct omap_hwmod *omap_hwmod_lookup(const char *name)
+{
+ struct omap_hwmod *oh;
+
+ if (!name)
+ return NULL;
+
+ oh = _lookup(name);
+
+ return oh;
+}
+
+/**
+ * omap_hwmod_for_each - call function for each registered omap_hwmod
+ * @fn: pointer to a callback function
+ * @data: void * data to pass to callback function
+ *
+ * Call @fn for each registered omap_hwmod, passing @data to each
+ * function. @fn must return 0 for success or any other value for
+ * failure. If @fn returns non-zero, the iteration across omap_hwmods
+ * will stop and the non-zero return value will be passed to the
+ * caller of omap_hwmod_for_each(). @fn is called with
+ * omap_hwmod_for_each() held.
+ */
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+ void *data)
+{
+ struct omap_hwmod *temp_oh;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+ ret = (*fn)(temp_oh, data);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_register - register an array of hwmods
+ * @ohs: pointer to an array of omap_hwmods to register
+ *
+ * Intended to be called early in boot before the clock framework is
+ * initialized. If @ohs is not null, will register all omap_hwmods
+ * listed in @ohs that are valid for this chip. Returns 0.
+ */
+int __init omap_hwmod_register(struct omap_hwmod **ohs)
+{
+ int r, i;
+
+ if (!ohs)
+ return 0;
+
+ i = 0;
+ do {
+ if (!omap_chip_is(ohs[i]->omap_chip))
+ continue;
+
+ r = _register(ohs[i]);
+ WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name,
+ r);
+ } while (ohs[++i]);
+
+ return 0;
+}
+
+/*
+ * _populate_mpu_rt_base - populate the virtual address for a hwmod
+ *
+ * Must be called only from omap_hwmod_setup_*() so ioremap works properly.
+ * Assumes the caller takes care of locking if needed.
+ */
+static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data)
+{
+ if (oh->_state != _HWMOD_STATE_REGISTERED)
+ return 0;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return 0;
+
+ oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
+ if (!oh->_mpu_rt_va)
+ pr_warning("omap_hwmod: %s found no _mpu_rt_va for %s\n",
+ __func__, oh->name);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_setup_one - set up a single hwmod
+ * @oh_name: const char * name of the already-registered hwmod to set up
+ *
+ * Must be called after omap2_clk_init(). Resolves the struct clk
+ * names to struct clk pointers for each registered omap_hwmod. Also
+ * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon
+ * success.
+ */
+int __init omap_hwmod_setup_one(const char *oh_name)
+{
+ struct omap_hwmod *oh;
+ int r;
+
+ pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__);
+
+ if (!mpu_oh) {
+ pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n",
+ oh_name, MPU_INITIATOR_NAME);
+ return -EINVAL;
+ }
+
+ oh = _lookup(oh_name);
+ if (!oh) {
+ WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name);
+ return -EINVAL;
+ }
+
+ if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh)
+ omap_hwmod_setup_one(MPU_INITIATOR_NAME);
+
+ r = _populate_mpu_rt_base(oh, NULL);
+ if (IS_ERR_VALUE(r)) {
+ WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name);
+ return -EINVAL;
+ }
+
+ r = _init_clocks(oh, NULL);
+ if (IS_ERR_VALUE(r)) {
+ WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name);
+ return -EINVAL;
+ }
+
+ _setup(oh, NULL);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_setup - do some post-clock framework initialization
+ *
+ * Must be called after omap2_clk_init(). Resolves the struct clk names
+ * to struct clk pointers for each registered omap_hwmod. Also calls
+ * _setup() on each hwmod. Returns 0 upon success.
+ */
+static int __init omap_hwmod_setup_all(void)
+{
+ int r;
+
+ if (!mpu_oh) {
+ pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n",
+ __func__, MPU_INITIATOR_NAME);
+ return -EINVAL;
+ }
+
+ r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL);
+
+ r = omap_hwmod_for_each(_init_clocks, NULL);
+ WARN(IS_ERR_VALUE(r),
+ "omap_hwmod: %s: _init_clocks failed\n", __func__);
+
+ omap_hwmod_for_each(_setup, NULL);
+
+ return 0;
+}
+core_initcall(omap_hwmod_setup_all);
+
+/**
+ * omap_hwmod_enable - enable an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Enable an omap_hwmod @oh. Intended to be called by omap_device_enable().
+ * Returns -EINVAL on error or passes along the return value from _enable().
+ */
+int omap_hwmod_enable(struct omap_hwmod *oh)
+{
+ int r;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ r = _enable(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return r;
+}
+
+/**
+ * omap_hwmod_idle - idle an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Idle an omap_hwmod @oh. Intended to be called by omap_device_idle().
+ * Returns -EINVAL on error or passes along the return value from _idle().
+ */
+int omap_hwmod_idle(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ _idle(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_shutdown - shutdown an omap_hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Shutdown an omap_hwmod @oh. Intended to be called by
+ * omap_device_shutdown(). Returns -EINVAL on error or passes along
+ * the return value from _shutdown().
+ */
+int omap_hwmod_shutdown(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ _shutdown(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by the omap_device code.
+ */
+int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ _enable_clocks(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by the omap_device code.
+ */
+int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ _disable_clocks(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
+ * @oh: struct omap_hwmod *oh
+ *
+ * Intended to be called by drivers and core code when all posted
+ * writes to a device must complete before continuing further
+ * execution (for example, after clearing some device IRQSTATUS
+ * register bits)
+ *
+ * XXX what about targets with multiple OCP threads?
+ */
+void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
+{
+ BUG_ON(!oh);
+
+ if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
+ WARN(1, "omap_device: %s: OCP barrier impossible due to "
+ "device configuration\n", oh->name);
+ return;
+ }
+
+ /*
+ * Forces posted writes to complete on the OCP thread handling
+ * register writes
+ */
+ omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
+}
+
+/**
+ * omap_hwmod_reset - reset the hwmod
+ * @oh: struct omap_hwmod *
+ *
+ * Under some conditions, a driver may wish to reset the entire device.
+ * Called from omap_device code. Returns -EINVAL on error or passes along
+ * the return value from _reset().
+ */
+int omap_hwmod_reset(struct omap_hwmod *oh)
+{
+ int r;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ r = _reset(oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return r;
+}
+
+/**
+ * omap_hwmod_count_resources - count number of struct resources needed by hwmod
+ * @oh: struct omap_hwmod *
+ * @res: pointer to the first element of an array of struct resource to fill
+ *
+ * Count the number of struct resource array elements necessary to
+ * contain omap_hwmod @oh resources. Intended to be called by code
+ * that registers omap_devices. Intended to be used to determine the
+ * size of a dynamically-allocated struct resource array, before
+ * calling omap_hwmod_fill_resources(). Returns the number of struct
+ * resource array elements needed.
+ *
+ * XXX This code is not optimized. It could attempt to merge adjacent
+ * resource IDs.
+ *
+ */
+int omap_hwmod_count_resources(struct omap_hwmod *oh)
+{
+ int ret, i;
+
+ ret = oh->mpu_irqs_cnt + oh->sdma_reqs_cnt;
+
+ for (i = 0; i < oh->slaves_cnt; i++)
+ ret += oh->slaves[i]->addr_cnt;
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_fill_resources - fill struct resource array with hwmod data
+ * @oh: struct omap_hwmod *
+ * @res: pointer to the first element of an array of struct resource to fill
+ *
+ * Fill the struct resource array @res with resource data from the
+ * omap_hwmod @oh. Intended to be called by code that registers
+ * omap_devices. See also omap_hwmod_count_resources(). Returns the
+ * number of array elements filled.
+ */
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
+{
+ int i, j;
+ int r = 0;
+
+ /* For each IRQ, DMA, memory area, fill in array.*/
+
+ for (i = 0; i < oh->mpu_irqs_cnt; i++) {
+ (res + r)->name = (oh->mpu_irqs + i)->name;
+ (res + r)->start = (oh->mpu_irqs + i)->irq;
+ (res + r)->end = (oh->mpu_irqs + i)->irq;
+ (res + r)->flags = IORESOURCE_IRQ;
+ r++;
+ }
+
+ for (i = 0; i < oh->sdma_reqs_cnt; i++) {
+ (res + r)->name = (oh->sdma_reqs + i)->name;
+ (res + r)->start = (oh->sdma_reqs + i)->dma_req;
+ (res + r)->end = (oh->sdma_reqs + i)->dma_req;
+ (res + r)->flags = IORESOURCE_DMA;
+ r++;
+ }
+
+ for (i = 0; i < oh->slaves_cnt; i++) {
+ struct omap_hwmod_ocp_if *os;
+
+ os = oh->slaves[i];
+
+ for (j = 0; j < os->addr_cnt; j++) {
+ (res + r)->name = (os->addr + j)->name;
+ (res + r)->start = (os->addr + j)->pa_start;
+ (res + r)->end = (os->addr + j)->pa_end;
+ (res + r)->flags = IORESOURCE_MEM;
+ r++;
+ }
+ }
+
+ return r;
+}
+
+/**
+ * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain
+ * @oh: struct omap_hwmod *
+ *
+ * Return the powerdomain pointer associated with the OMAP module
+ * @oh's main clock. If @oh does not have a main clk, return the
+ * powerdomain associated with the interface clock associated with the
+ * module's MPU port. (XXX Perhaps this should use the SDMA port
+ * instead?) Returns NULL on error, or a struct powerdomain * on
+ * success.
+ */
+struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
+{
+ struct clk *c;
+
+ if (!oh)
+ return NULL;
+
+ if (oh->_clk) {
+ c = oh->_clk;
+ } else {
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return NULL;
+ c = oh->slaves[oh->_mpu_port_index]->_clk;
+ }
+
+ if (!c->clkdm)
+ return NULL;
+
+ return c->clkdm->pwrdm.ptr;
+
+}
+
+/**
+ * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the virtual address corresponding to the beginning of the
+ * module's register target, in the address range that is intended to
+ * be used by the MPU. Returns the virtual address upon success or NULL
+ * upon error.
+ */
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return NULL;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return NULL;
+
+ if (oh->_state == _HWMOD_STATE_UNKNOWN)
+ return NULL;
+
+ return oh->_mpu_rt_va;
+}
+
+/**
+ * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
+ * @oh: struct omap_hwmod *
+ * @init_oh: struct omap_hwmod * (initiator)
+ *
+ * Add a sleep dependency between the initiator @init_oh and @oh.
+ * Intended to be called by DSP/Bridge code via platform_data for the
+ * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
+ * code needs to add/del initiator dependencies dynamically
+ * before/after accessing a device. Returns the return value from
+ * _add_initiator_dep().
+ *
+ * XXX Keep a usecount in the clockdomain code
+ */
+int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
+ struct omap_hwmod *init_oh)
+{
+ return _add_initiator_dep(oh, init_oh);
+}
+
+/*
+ * XXX what about functions for drivers to save/restore ocp_sysconfig
+ * for context save/restore operations?
+ */
+
+/**
+ * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
+ * @oh: struct omap_hwmod *
+ * @init_oh: struct omap_hwmod * (initiator)
+ *
+ * Remove a sleep dependency between the initiator @init_oh and @oh.
+ * Intended to be called by DSP/Bridge code via platform_data for the
+ * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
+ * code needs to add/del initiator dependencies dynamically
+ * before/after accessing a device. Returns the return value from
+ * _del_initiator_dep().
+ *
+ * XXX Keep a usecount in the clockdomain code
+ */
+int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
+ struct omap_hwmod *init_oh)
+{
+ return _del_initiator_dep(oh, init_oh);
+}
+
+/**
+ * omap_hwmod_enable_wakeup - allow device to wake up the system
+ * @oh: struct omap_hwmod *
+ *
+ * Sets the module OCP socket ENAWAKEUP bit to allow the module to
+ * send wakeups to the PRCM. Eventually this should sets PRCM wakeup
+ * registers to cause the PRCM to receive wakeup events from the
+ * module. Does not set any wakeup routing registers beyond this
+ * point - if the module is to wake up any other module or subsystem,
+ * that must be set separately. Called by omap_device code. Returns
+ * -EINVAL on error or 0 upon success.
+ */
+int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+ u32 v;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ v = oh->_sysc_cache;
+ _enable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_disable_wakeup - prevent device from waking the system
+ * @oh: struct omap_hwmod *
+ *
+ * Clears the module OCP socket ENAWAKEUP bit to prevent the module
+ * from sending wakeups to the PRCM. Eventually this should clear
+ * PRCM wakeup registers to cause the PRCM to ignore wakeup events
+ * from the module. Does not set any wakeup routing registers beyond
+ * this point - if the module is to wake up any other module or
+ * subsystem, that must be set separately. Called by omap_device
+ * code. Returns -EINVAL on error or 0 upon success.
+ */
+int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
+{
+ unsigned long flags;
+ u32 v;
+
+ if (!oh->class->sysc ||
+ !(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP))
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ v = oh->_sysc_cache;
+ _disable_wakeup(oh, &v);
+ _write_sysconfig(v, oh);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return 0;
+}
+
+/**
+ * omap_hwmod_assert_hardreset - assert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to lookup and assert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP. Returns -EINVAL if @oh is null or if the operation is not
+ * yet supported on this OMAP; otherwise, passes along the return value
+ * from _assert_hardreset().
+ */
+int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ ret = _assert_hardreset(oh, name);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_deassert_hardreset - deassert the HW reset line of submodules
+ * contained in the hwmod module.
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and deassert
+ *
+ * Some IP like dsp, ipu or iva contain processor that require
+ * an HW reset line to be assert / deassert in order to enable fully
+ * the IP. Returns -EINVAL if @oh is null or if the operation is not
+ * yet supported on this OMAP; otherwise, passes along the return value
+ * from _deassert_hardreset().
+ */
+int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ ret = _deassert_hardreset(oh, name);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_read_hardreset - read the HW reset line state of submodules
+ * contained in the hwmod module
+ * @oh: struct omap_hwmod *
+ * @name: name of the reset line to look up and read
+ *
+ * Return the current state of the hwmod @oh's reset line named @name:
+ * returns -EINVAL upon parameter error or if this operation
+ * is unsupported on the current OMAP; otherwise, passes along the return
+ * value from _read_hardreset().
+ */
+int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
+{
+ int ret;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+ ret = _read_hardreset(oh, name);
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return ret;
+}
+
+
+/**
+ * omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
+ * @classname: struct omap_hwmod_class name to search for
+ * @fn: callback function pointer to call for each hwmod in class @classname
+ * @user: arbitrary context data to pass to the callback function
+ *
+ * For each omap_hwmod of class @classname, call @fn.
+ * If the callback function returns something other than
+ * zero, the iterator is terminated, and the callback function's return
+ * value is passed back to the caller. Returns 0 upon success, -EINVAL
+ * if @classname or @fn are NULL, or passes back the error code from @fn.
+ */
+int omap_hwmod_for_each_by_class(const char *classname,
+ int (*fn)(struct omap_hwmod *oh,
+ void *user),
+ void *user)
+{
+ struct omap_hwmod *temp_oh;
+ int ret = 0;
+
+ if (!classname || !fn)
+ return -EINVAL;
+
+ pr_debug("omap_hwmod: %s: looking for modules of class %s\n",
+ __func__, classname);
+
+ list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
+ if (!strcmp(temp_oh->class->name, classname)) {
+ pr_debug("omap_hwmod: %s: %s: calling callback fn\n",
+ __func__, temp_oh->name);
+ ret = (*fn)(temp_oh, user);
+ if (ret)
+ break;
+ }
+ }
+
+ if (ret)
+ pr_debug("omap_hwmod: %s: iterator terminated early: %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_set_postsetup_state - set the post-_setup() state for this hwmod
+ * @oh: struct omap_hwmod *
+ * @state: state that _setup() should leave the hwmod in
+ *
+ * Sets the hwmod state that @oh will enter at the end of _setup()
+ * (called by omap_hwmod_setup_*()). Only valid to call between
+ * calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns
+ * 0 upon success or -EINVAL if there is a problem with the arguments
+ * or if the hwmod is in the wrong state.
+ */
+int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state)
+{
+ int ret;
+ unsigned long flags;
+
+ if (!oh)
+ return -EINVAL;
+
+ if (state != _HWMOD_STATE_DISABLED &&
+ state != _HWMOD_STATE_ENABLED &&
+ state != _HWMOD_STATE_IDLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&oh->_lock, flags);
+
+ if (oh->_state != _HWMOD_STATE_REGISTERED) {
+ ret = -EINVAL;
+ goto ohsps_unlock;
+ }
+
+ oh->_postsetup_state = state;
+ ret = 0;
+
+ohsps_unlock:
+ spin_unlock_irqrestore(&oh->_lock, flags);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_get_context_loss_count - get lost context count
+ * @oh: struct omap_hwmod *
+ *
+ * Query the powerdomain of of @oh to get the context loss
+ * count for this device.
+ *
+ * Returns the context loss count of the powerdomain assocated with @oh
+ * upon success, or zero if no powerdomain exists for @oh.
+ */
+u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
+{
+ struct powerdomain *pwrdm;
+ int ret = 0;
+
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ if (pwrdm)
+ ret = pwrdm_get_context_loss_count(pwrdm);
+
+ return ret;
+}
+
+/**
+ * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup
+ * @oh: struct omap_hwmod *
+ *
+ * Prevent the hwmod @oh from being reset during the setup process.
+ * Intended for use by board-*.c files on boards with devices that
+ * cannot tolerate being reset. Must be called before the hwmod has
+ * been set up. Returns 0 upon success or negative error code upon
+ * failure.
+ */
+int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return -EINVAL;
+
+ if (oh->_state != _HWMOD_STATE_REGISTERED) {
+ pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
+ oh->name);
+ return -EINVAL;
+ }
+
+ oh->flags |= HWMOD_INIT_NO_RESET;
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
new file mode 100644
index 00000000..c4d0ae87
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -0,0 +1,2201 @@
+/*
+ * omap_hwmod_2420_data.c - hardware modules present on the OMAP2420 chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+#include <plat/serial.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
+#include <plat/mcspi.h>
+#include <plat/dmtimer.h>
+#include <plat/l3_2xxx.h>
+#include <plat/l4_2xxx.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+#include "wd_timer.h"
+
+/*
+ * OMAP2420 hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation. Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap2420_mpu_hwmod;
+static struct omap_hwmod omap2420_iva_hwmod;
+static struct omap_hwmod omap2420_l3_main_hwmod;
+static struct omap_hwmod omap2420_l4_core_hwmod;
+static struct omap_hwmod omap2420_dss_core_hwmod;
+static struct omap_hwmod omap2420_dss_dispc_hwmod;
+static struct omap_hwmod omap2420_dss_rfbi_hwmod;
+static struct omap_hwmod omap2420_dss_venc_hwmod;
+static struct omap_hwmod omap2420_wd_timer2_hwmod;
+static struct omap_hwmod omap2420_gpio1_hwmod;
+static struct omap_hwmod omap2420_gpio2_hwmod;
+static struct omap_hwmod omap2420_gpio3_hwmod;
+static struct omap_hwmod omap2420_gpio4_hwmod;
+static struct omap_hwmod omap2420_dma_system_hwmod;
+static struct omap_hwmod omap2420_mcspi1_hwmod;
+static struct omap_hwmod omap2420_mcspi2_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
+ .master = &omap2420_l3_main_hwmod,
+ .slave = &omap2420_l4_core_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2420_mpu__l3_main = {
+ .master = &omap2420_mpu_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
+ &omap2420_mpu__l3_main,
+};
+
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap2420_dss__l3 = {
+ .master = &omap2420_dss_core_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
+ &omap2420_l3_main__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2420_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &l3_hwmod_class,
+ .masters = omap2420_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
+ .slaves = omap2420_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod omap2420_l4_wkup_hwmod;
+static struct omap_hwmod omap2420_uart1_hwmod;
+static struct omap_hwmod omap2420_uart2_hwmod;
+static struct omap_hwmod omap2420_uart3_hwmod;
+static struct omap_hwmod omap2420_i2c1_hwmod;
+static struct omap_hwmod omap2420_i2c2_hwmod;
+static struct omap_hwmod omap2420_mcbsp1_hwmod;
+static struct omap_hwmod omap2420_mcbsp2_hwmod;
+
+/* l4 core -> mcspi1 interface */
+static struct omap_hwmod_addr_space omap2420_mcspi1_addr_space[] = {
+ {
+ .pa_start = 0x48098000,
+ .pa_end = 0x480980ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_mcspi1_hwmod,
+ .clk = "mcspi1_ick",
+ .addr = omap2420_mcspi1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_mcspi1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi2 interface */
+static struct omap_hwmod_addr_space omap2420_mcspi2_addr_space[] = {
+ {
+ .pa_start = 0x4809a000,
+ .pa_end = 0x4809a0ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_mcspi2_hwmod,
+ .clk = "mcspi2_ick",
+ .addr = omap2420_mcspi2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_mcspi2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_l4_wkup_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap2420_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART1_BASE,
+ .pa_end = OMAP2_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap2420_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap2420_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART2_BASE,
+ .pa_end = OMAP2_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap2420_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap2420_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART3_BASE,
+ .pa_end = OMAP2_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap2420_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap2420_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap2420_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_i2c1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap2420_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_core__i2c2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap2420_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_i2c2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
+ &omap2420_l3_main__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
+ &omap2420_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
+ &omap2420_l4_core__i2c1,
+ &omap2420_l4_core__i2c2
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2420_l4_core_hwmod = {
+ .name = "l4_core",
+ .class = &l4_hwmod_class,
+ .masters = omap2420_l4_core_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
+ .slaves = omap2420_l4_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_slaves[] = {
+ &omap2420_l4_core__l4_wkup,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2420_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &l4_hwmod_class,
+ .masters = omap2420_l4_wkup_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
+ .slaves = omap2420_l4_wkup_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
+ &omap2420_mpu__l3_main,
+};
+
+/* MPU */
+static struct omap_hwmod omap2420_mpu_hwmod = {
+ .name = "mpu",
+ .class = &mpu_hwmod_class,
+ .main_clk = "mpu_ck",
+ .masters = omap2420_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/*
+ * IVA1 interface data
+ */
+
+/* IVA <- L3 interface */
+static struct omap_hwmod_ocp_if omap2420_l3__iva = {
+ .master = &omap2420_l3_main_hwmod,
+ .slave = &omap2420_iva_hwmod,
+ .clk = "iva1_ifck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2420_iva_masters[] = {
+ &omap2420_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2420_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap2420_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* Timer Common */
+static struct omap_hwmod_class_sysconfig omap2420_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap2420_timer_sysc,
+ .rev = OMAP_TIMER_IP_VERSION_1,
+};
+
+/* timer1 */
+static struct omap_hwmod omap2420_timer1_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer1_mpu_irqs[] = {
+ { .irq = 37, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer1_addrs[] = {
+ {
+ .pa_start = 0x48028000,
+ .pa_end = 0x48028000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__timer1 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_timer1_hwmod,
+ .clk = "gpt1_ick",
+ .addr = omap2420_timer1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer1 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer1_slaves[] = {
+ &omap2420_l4_wkup__timer1,
+};
+
+/* timer1 hwmod */
+static struct omap_hwmod omap2420_timer1_hwmod = {
+ .name = "timer1",
+ .mpu_irqs = omap2420_timer1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer1_mpu_irqs),
+ .main_clk = "gpt1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer1_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer2 */
+static struct omap_hwmod omap2420_timer2_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer2_mpu_irqs[] = {
+ { .irq = 38, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer2_addrs[] = {
+ {
+ .pa_start = 0x4802a000,
+ .pa_end = 0x4802a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer2 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer2_hwmod,
+ .clk = "gpt2_ick",
+ .addr = omap2420_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer2 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer2_slaves[] = {
+ &omap2420_l4_core__timer2,
+};
+
+/* timer2 hwmod */
+static struct omap_hwmod omap2420_timer2_hwmod = {
+ .name = "timer2",
+ .mpu_irqs = omap2420_timer2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer2_mpu_irqs),
+ .main_clk = "gpt2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer2_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer3 */
+static struct omap_hwmod omap2420_timer3_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer3_mpu_irqs[] = {
+ { .irq = 39, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer3_addrs[] = {
+ {
+ .pa_start = 0x48078000,
+ .pa_end = 0x48078000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer3 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer3 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer3_hwmod,
+ .clk = "gpt3_ick",
+ .addr = omap2420_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer3 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer3_slaves[] = {
+ &omap2420_l4_core__timer3,
+};
+
+/* timer3 hwmod */
+static struct omap_hwmod omap2420_timer3_hwmod = {
+ .name = "timer3",
+ .mpu_irqs = omap2420_timer3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer3_mpu_irqs),
+ .main_clk = "gpt3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer3_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer4 */
+static struct omap_hwmod omap2420_timer4_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer4_mpu_irqs[] = {
+ { .irq = 40, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer4_addrs[] = {
+ {
+ .pa_start = 0x4807a000,
+ .pa_end = 0x4807a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer4 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer4 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer4_hwmod,
+ .clk = "gpt4_ick",
+ .addr = omap2420_timer4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer4 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer4_slaves[] = {
+ &omap2420_l4_core__timer4,
+};
+
+/* timer4 hwmod */
+static struct omap_hwmod omap2420_timer4_hwmod = {
+ .name = "timer4",
+ .mpu_irqs = omap2420_timer4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer4_mpu_irqs),
+ .main_clk = "gpt4_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer4_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer5 */
+static struct omap_hwmod omap2420_timer5_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer5_mpu_irqs[] = {
+ { .irq = 41, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer5_addrs[] = {
+ {
+ .pa_start = 0x4807c000,
+ .pa_end = 0x4807c000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer5 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer5 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer5_hwmod,
+ .clk = "gpt5_ick",
+ .addr = omap2420_timer5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer5 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer5_slaves[] = {
+ &omap2420_l4_core__timer5,
+};
+
+/* timer5 hwmod */
+static struct omap_hwmod omap2420_timer5_hwmod = {
+ .name = "timer5",
+ .mpu_irqs = omap2420_timer5_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer5_mpu_irqs),
+ .main_clk = "gpt5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer5_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+
+/* timer6 */
+static struct omap_hwmod omap2420_timer6_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer6_mpu_irqs[] = {
+ { .irq = 42, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer6_addrs[] = {
+ {
+ .pa_start = 0x4807e000,
+ .pa_end = 0x4807e000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer6 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer6 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer6_hwmod,
+ .clk = "gpt6_ick",
+ .addr = omap2420_timer6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer6 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer6_slaves[] = {
+ &omap2420_l4_core__timer6,
+};
+
+/* timer6 hwmod */
+static struct omap_hwmod omap2420_timer6_hwmod = {
+ .name = "timer6",
+ .mpu_irqs = omap2420_timer6_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer6_mpu_irqs),
+ .main_clk = "gpt6_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer6_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer7 */
+static struct omap_hwmod omap2420_timer7_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer7_mpu_irqs[] = {
+ { .irq = 43, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer7_addrs[] = {
+ {
+ .pa_start = 0x48080000,
+ .pa_end = 0x48080000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer7 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer7 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer7_hwmod,
+ .clk = "gpt7_ick",
+ .addr = omap2420_timer7_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer7_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer7 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer7_slaves[] = {
+ &omap2420_l4_core__timer7,
+};
+
+/* timer7 hwmod */
+static struct omap_hwmod omap2420_timer7_hwmod = {
+ .name = "timer7",
+ .mpu_irqs = omap2420_timer7_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer7_mpu_irqs),
+ .main_clk = "gpt7_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer7_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer7_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer8 */
+static struct omap_hwmod omap2420_timer8_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer8_mpu_irqs[] = {
+ { .irq = 44, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer8_addrs[] = {
+ {
+ .pa_start = 0x48082000,
+ .pa_end = 0x48082000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer8 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer8 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer8_hwmod,
+ .clk = "gpt8_ick",
+ .addr = omap2420_timer8_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer8_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer8 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer8_slaves[] = {
+ &omap2420_l4_core__timer8,
+};
+
+/* timer8 hwmod */
+static struct omap_hwmod omap2420_timer8_hwmod = {
+ .name = "timer8",
+ .mpu_irqs = omap2420_timer8_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer8_mpu_irqs),
+ .main_clk = "gpt8_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer8_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer8_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer9 */
+static struct omap_hwmod omap2420_timer9_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer9_mpu_irqs[] = {
+ { .irq = 45, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer9_addrs[] = {
+ {
+ .pa_start = 0x48084000,
+ .pa_end = 0x48084000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer9 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer9 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer9_hwmod,
+ .clk = "gpt9_ick",
+ .addr = omap2420_timer9_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer9_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer9 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer9_slaves[] = {
+ &omap2420_l4_core__timer9,
+};
+
+/* timer9 hwmod */
+static struct omap_hwmod omap2420_timer9_hwmod = {
+ .name = "timer9",
+ .mpu_irqs = omap2420_timer9_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer9_mpu_irqs),
+ .main_clk = "gpt9_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer9_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer9_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer10 */
+static struct omap_hwmod omap2420_timer10_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer10_mpu_irqs[] = {
+ { .irq = 46, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer10_addrs[] = {
+ {
+ .pa_start = 0x48086000,
+ .pa_end = 0x48086000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer10 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer10 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer10_hwmod,
+ .clk = "gpt10_ick",
+ .addr = omap2420_timer10_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer10_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer10 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer10_slaves[] = {
+ &omap2420_l4_core__timer10,
+};
+
+/* timer10 hwmod */
+static struct omap_hwmod omap2420_timer10_hwmod = {
+ .name = "timer10",
+ .mpu_irqs = omap2420_timer10_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer10_mpu_irqs),
+ .main_clk = "gpt10_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer10_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer10_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer11 */
+static struct omap_hwmod omap2420_timer11_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer11_mpu_irqs[] = {
+ { .irq = 47, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer11_addrs[] = {
+ {
+ .pa_start = 0x48088000,
+ .pa_end = 0x48088000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer11 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer11 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer11_hwmod,
+ .clk = "gpt11_ick",
+ .addr = omap2420_timer11_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer11_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer11 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer11_slaves[] = {
+ &omap2420_l4_core__timer11,
+};
+
+/* timer11 hwmod */
+static struct omap_hwmod omap2420_timer11_hwmod = {
+ .name = "timer11",
+ .mpu_irqs = omap2420_timer11_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer11_mpu_irqs),
+ .main_clk = "gpt11_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer11_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer11_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* timer12 */
+static struct omap_hwmod omap2420_timer12_hwmod;
+static struct omap_hwmod_irq_info omap2420_timer12_mpu_irqs[] = {
+ { .irq = 48, },
+};
+
+static struct omap_hwmod_addr_space omap2420_timer12_addrs[] = {
+ {
+ .pa_start = 0x4808a000,
+ .pa_end = 0x4808a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer12 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__timer12 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_timer12_hwmod,
+ .clk = "gpt12_ick",
+ .addr = omap2420_timer12_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_timer12_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer12 slave port */
+static struct omap_hwmod_ocp_if *omap2420_timer12_slaves[] = {
+ &omap2420_l4_core__timer12,
+};
+
+/* timer12 hwmod */
+static struct omap_hwmod omap2420_timer12_hwmod = {
+ .name = "timer12",
+ .mpu_irqs = omap2420_timer12_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer12_mpu_irqs),
+ .main_clk = "gpt12_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT,
+ },
+ },
+ .slaves = omap2420_timer12_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_timer12_slaves),
+ .class = &omap2420_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap2420_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x48022000,
+ .pa_end = 0x4802207f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__wd_timer2 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .addr = omap2420_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap2420_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap2420_wd_timer2_slaves[] = {
+ &omap2420_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap2420_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap2420_wd_timer_hwmod_class,
+ .main_clk = "mpu_wdt_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT,
+ },
+ },
+ .slaves = omap2420_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart1_slaves[] = {
+ &omap2_l4_core__uart1,
+};
+
+static struct omap_hwmod omap2420_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart2_slaves[] = {
+ &omap2_l4_core__uart2,
+};
+
+static struct omap_hwmod omap2420_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_uart3_slaves[] = {
+ &omap2_l4_core__uart3,
+};
+
+static struct omap_hwmod omap2420_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP24XX_EN_UART3_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap2420_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap2420_dss_sysc,
+};
+
+static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_masters[] = {
+ &omap2420_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = {
+ &omap2420_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+ { .role = "sys_clk", .clk = "dss2_fck" },
+};
+
+static struct omap_hwmod omap2420_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2420_dss_hwmod_class,
+ .main_clk = "dss1_fck", /* instead of dss_fck */
+ .sdma_reqs = omap2420_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap2420_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_slaves),
+ .masters = omap2420_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2420_dispc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap2420_dispc_irqs[] = {
+ { .irq = 25 },
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_dispc = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_dispc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = {
+ &omap2420_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap2420_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap2420_dispc_hwmod_class,
+ .mpu_irqs = omap2420_dispc_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dispc_irqs),
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .slaves = omap2420_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap2420_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_rfbi = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_rfbi_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = {
+ &omap2420_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2420_rfbi_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2420_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap2420_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap2420_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_venc_hwmod,
+ .clk = "dss_54m_fck",
+ .addr = omap2420_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_venc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .flags = OCPIF_SWSUP_IDLE,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = {
+ &omap2420_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap2420_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2420_venc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2420_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr;
+
+/* I2C1 */
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_i2c1_slaves[] = {
+ &omap2420_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap2420_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2420_EN_I2C1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2420_ST_I2C1_SHIFT,
+ },
+ },
+ .slaves = omap2420_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* I2C2 */
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2420_i2c2_slaves[] = {
+ &omap2420_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap2420_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2420_EN_I2C2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2420_ST_I2C2_SHIFT,
+ },
+ },
+ .slaves = omap2420_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_16BIT_REG,
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap2420_gpio1_addr_space[] = {
+ {
+ .pa_start = 0x48018000,
+ .pa_end = 0x480181ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio1 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_addr_space omap2420_gpio2_addr_space[] = {
+ {
+ .pa_start = 0x4801a000,
+ .pa_end = 0x4801a1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio2 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_addr_space omap2420_gpio3_addr_space[] = {
+ {
+ .pa_start = 0x4801c000,
+ .pa_end = 0x4801c1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio3 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_addr_space omap2420_gpio4_addr_space[] = {
+ {
+ .pa_start = 0x4801e000,
+ .pa_end = 0x4801e1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = {
+ .master = &omap2420_l4_wkup_hwmod,
+ .slave = &omap2420_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2420_gpio4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2420_gpio4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap242x_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+static struct omap_hwmod_class omap242x_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap242x_gpio_sysc,
+ .rev = 0,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap242x_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = {
+ &omap2420_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2420_gpio1_hwmod = {
+ .name = "gpio1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap242x_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio1_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap242x_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = {
+ &omap2420_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2420_gpio2_hwmod = {
+ .name = "gpio2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap242x_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio2_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap242x_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = {
+ &omap2420_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2420_gpio3_hwmod = {
+ .name = "gpio3",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap242x_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio3_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap242x_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = {
+ &omap2420_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2420_gpio4_hwmod = {
+ .name = "gpio4",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap242x_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2420_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_gpio4_slaves),
+ .class = &omap242x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* system dma */
+static struct omap_hwmod_class_sysconfig omap2420_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap2420_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x48056fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = {
+ .master = &omap2420_dma_system_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_masters[] = {
+ &omap2420_dma_system__l3,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2420_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dma_system_slaves[] = {
+ &omap2420_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2420_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2420_dma_hwmod_class,
+ .mpu_irqs = omap2420_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dma_system_irqs),
+ .main_clk = "core_l3_ck",
+ .slaves = omap2420_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dma_system_slaves),
+ .masters = omap2420_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors
+ * using a queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_mailbox_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap2420_mailbox_sysc,
+};
+
+/* mailbox */
+static struct omap_hwmod omap2420_mailbox_hwmod;
+static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = {
+ { .name = "dsp", .irq = 26 },
+ { .name = "iva", .irq = 34 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mailbox_addrs[] = {
+ {
+ .pa_start = 0x48094000,
+ .pa_end = 0x480941ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* l4_core -> mailbox */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mailbox = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_mailbox_hwmod,
+ .addr = omap2420_mailbox_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_mailbox_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mailbox slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mailbox_slaves[] = {
+ &omap2420_l4_core__mailbox,
+};
+
+static struct omap_hwmod omap2420_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap2420_mailbox_hwmod_class,
+ .mpu_irqs = omap2420_mailbox_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mailbox_irqs),
+ .main_clk = "mailboxes_ick",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
+ },
+ },
+ .slaves = omap2420_mailbox_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_mailbox_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_mcspi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &omap2420_mcspi_sysc,
+ .rev = OMAP2_MCSPI_REV,
+};
+
+/* mcspi1 */
+static struct omap_hwmod_irq_info omap2420_mcspi1_mpu_irqs[] = {
+ { .irq = 65 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcspi1_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */
+ { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */
+ { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */
+ { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */
+ { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */
+ { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */
+ { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */
+ { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_mcspi1_slaves[] = {
+ &omap2420_l4_core__mcspi1,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap2420_mcspi1_hwmod = {
+ .name = "mcspi1_hwmod",
+ .mpu_irqs = omap2420_mcspi1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi1_mpu_irqs),
+ .sdma_reqs = omap2420_mcspi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi1_sdma_reqs),
+ .main_clk = "mcspi1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT,
+ },
+ },
+ .slaves = omap2420_mcspi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_mcspi1_slaves),
+ .class = &omap2420_mcspi_class,
+ .dev_attr = &omap_mcspi1_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* mcspi2 */
+static struct omap_hwmod_irq_info omap2420_mcspi2_mpu_irqs[] = {
+ { .irq = 66 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcspi2_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */
+ { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */
+ { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */
+ { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2420_mcspi2_slaves[] = {
+ &omap2420_l4_core__mcspi2,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap2420_mcspi2_hwmod = {
+ .name = "mcspi2_hwmod",
+ .mpu_irqs = omap2420_mcspi2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi2_mpu_irqs),
+ .sdma_reqs = omap2420_mcspi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi2_sdma_reqs),
+ .main_clk = "mcspi2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT,
+ },
+ },
+ .slaves = omap2420_mcspi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_mcspi2_slaves),
+ .class = &omap2420_mcspi_class,
+ .dev_attr = &omap_mcspi2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap2420_mcbsp1_irqs[] = {
+ { .name = "tx", .irq = 59 },
+ { .name = "rx", .irq = 60 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp1_sdma_chs[] = {
+ { .name = "rx", .dma_req = 32 },
+ { .name = "tx", .dma_req = 31 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp1_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48074000,
+ .pa_end = 0x480740ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_mcbsp1_hwmod,
+ .clk = "mcbsp1_ick",
+ .addr = omap2420_mcbsp1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_mcbsp1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp1_slaves[] = {
+ &omap2420_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap2420_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap2420_mcbsp_hwmod_class,
+ .mpu_irqs = omap2420_mcbsp1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcbsp1_irqs),
+ .sdma_reqs = omap2420_mcbsp1_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcbsp1_sdma_chs),
+ .main_clk = "mcbsp1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT,
+ },
+ },
+ .slaves = omap2420_mcbsp1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_mcbsp1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap2420_mcbsp2_irqs[] = {
+ { .name = "tx", .irq = 62 },
+ { .name = "rx", .irq = 63 },
+};
+
+static struct omap_hwmod_dma_info omap2420_mcbsp2_sdma_chs[] = {
+ { .name = "rx", .dma_req = 34 },
+ { .name = "tx", .dma_req = 33 },
+};
+
+static struct omap_hwmod_addr_space omap2420_mcbsp2_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48076000,
+ .pa_end = 0x480760ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_mcbsp2_hwmod,
+ .clk = "mcbsp2_ick",
+ .addr = omap2420_mcbsp2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_mcbsp2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap2420_mcbsp2_slaves[] = {
+ &omap2420_l4_core__mcbsp2,
+};
+
+static struct omap_hwmod omap2420_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap2420_mcbsp_hwmod_class,
+ .mpu_irqs = omap2420_mcbsp2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcbsp2_irqs),
+ .sdma_reqs = omap2420_mcbsp2_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcbsp2_sdma_chs),
+ .main_clk = "mcbsp2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT,
+ },
+ },
+ .slaves = omap2420_mcbsp2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_mcbsp2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static __initdata struct omap_hwmod *omap2420_hwmods[] = {
+ &omap2420_l3_main_hwmod,
+ &omap2420_l4_core_hwmod,
+ &omap2420_l4_wkup_hwmod,
+ &omap2420_mpu_hwmod,
+ &omap2420_iva_hwmod,
+
+ &omap2420_timer1_hwmod,
+ &omap2420_timer2_hwmod,
+ &omap2420_timer3_hwmod,
+ &omap2420_timer4_hwmod,
+ &omap2420_timer5_hwmod,
+ &omap2420_timer6_hwmod,
+ &omap2420_timer7_hwmod,
+ &omap2420_timer8_hwmod,
+ &omap2420_timer9_hwmod,
+ &omap2420_timer10_hwmod,
+ &omap2420_timer11_hwmod,
+ &omap2420_timer12_hwmod,
+
+ &omap2420_wd_timer2_hwmod,
+ &omap2420_uart1_hwmod,
+ &omap2420_uart2_hwmod,
+ &omap2420_uart3_hwmod,
+ /* dss class */
+ &omap2420_dss_core_hwmod,
+ &omap2420_dss_dispc_hwmod,
+ &omap2420_dss_rfbi_hwmod,
+ &omap2420_dss_venc_hwmod,
+ /* i2c class */
+ &omap2420_i2c1_hwmod,
+ &omap2420_i2c2_hwmod,
+
+ /* gpio class */
+ &omap2420_gpio1_hwmod,
+ &omap2420_gpio2_hwmod,
+ &omap2420_gpio3_hwmod,
+ &omap2420_gpio4_hwmod,
+
+ /* dma_system class*/
+ &omap2420_dma_system_hwmod,
+
+ /* mailbox class */
+ &omap2420_mailbox_hwmod,
+
+ /* mcbsp class */
+ &omap2420_mcbsp1_hwmod,
+ &omap2420_mcbsp2_hwmod,
+
+ /* mcspi class */
+ &omap2420_mcspi1_hwmod,
+ &omap2420_mcspi2_hwmod,
+ NULL,
+};
+
+int __init omap2420_hwmod_init(void)
+{
+ return omap_hwmod_register(omap2420_hwmods);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
new file mode 100644
index 00000000..9682dd51
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -0,0 +1,2741 @@
+/*
+ * omap_hwmod_2430_data.c - hardware modules present on the OMAP2430 chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX handle crossbar/shared link difference for L3?
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+#include <plat/serial.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
+#include <plat/mcbsp.h>
+#include <plat/mcspi.h>
+#include <plat/dmtimer.h>
+#include <plat/mmc.h>
+#include <plat/l3_2xxx.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "prm-regbits-24xx.h"
+#include "cm-regbits-24xx.h"
+#include "wd_timer.h"
+
+/*
+ * OMAP2430 hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation. Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap2430_mpu_hwmod;
+static struct omap_hwmod omap2430_iva_hwmod;
+static struct omap_hwmod omap2430_l3_main_hwmod;
+static struct omap_hwmod omap2430_l4_core_hwmod;
+static struct omap_hwmod omap2430_dss_core_hwmod;
+static struct omap_hwmod omap2430_dss_dispc_hwmod;
+static struct omap_hwmod omap2430_dss_rfbi_hwmod;
+static struct omap_hwmod omap2430_dss_venc_hwmod;
+static struct omap_hwmod omap2430_wd_timer2_hwmod;
+static struct omap_hwmod omap2430_gpio1_hwmod;
+static struct omap_hwmod omap2430_gpio2_hwmod;
+static struct omap_hwmod omap2430_gpio3_hwmod;
+static struct omap_hwmod omap2430_gpio4_hwmod;
+static struct omap_hwmod omap2430_gpio5_hwmod;
+static struct omap_hwmod omap2430_dma_system_hwmod;
+static struct omap_hwmod omap2430_mcbsp1_hwmod;
+static struct omap_hwmod omap2430_mcbsp2_hwmod;
+static struct omap_hwmod omap2430_mcbsp3_hwmod;
+static struct omap_hwmod omap2430_mcbsp4_hwmod;
+static struct omap_hwmod omap2430_mcbsp5_hwmod;
+static struct omap_hwmod omap2430_mcspi1_hwmod;
+static struct omap_hwmod omap2430_mcspi2_hwmod;
+static struct omap_hwmod omap2430_mcspi3_hwmod;
+static struct omap_hwmod omap2430_mmc1_hwmod;
+static struct omap_hwmod omap2430_mmc2_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
+ .master = &omap2430_l3_main_hwmod,
+ .slave = &omap2430_l4_core_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap2430_mpu__l3_main = {
+ .master = &omap2430_mpu_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
+ &omap2430_mpu__l3_main,
+};
+
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap2430_dss__l3 = {
+ .master = &omap2430_dss_core_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
+ &omap2430_l3_main__l4_core,
+};
+
+/* L3 */
+static struct omap_hwmod omap2430_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &l3_hwmod_class,
+ .masters = omap2430_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
+ .slaves = omap2430_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod omap2430_l4_wkup_hwmod;
+static struct omap_hwmod omap2430_uart1_hwmod;
+static struct omap_hwmod omap2430_uart2_hwmod;
+static struct omap_hwmod omap2430_uart3_hwmod;
+static struct omap_hwmod omap2430_i2c1_hwmod;
+static struct omap_hwmod omap2430_i2c2_hwmod;
+
+static struct omap_hwmod omap2430_usbhsotg_hwmod;
+
+/* l3_core -> usbhsotg interface */
+static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = {
+ .master = &omap2430_usbhsotg_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap2430_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap2430_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_i2c1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap2430_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__i2c2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap2430_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_i2c2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_l4_wkup_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap2430_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART1_BASE,
+ .pa_end = OMAP2_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap2430_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap2430_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART2_BASE,
+ .pa_end = OMAP2_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap2430_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap2430_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP2_UART3_BASE,
+ .pa_end = OMAP2_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2_l4_core__uart3 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap2430_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+* usbhsotg interface data
+*/
+static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = {
+ {
+ .pa_start = OMAP243X_HS_BASE,
+ .pa_end = OMAP243X_HS_BASE + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core ->usbhsotg interface */
+static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_usbhsotg_hwmod,
+ .clk = "usb_l4_ick",
+ .addr = omap2430_usbhsotg_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_usbhsotg_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_usbhsotg_masters[] = {
+ &omap2430_usbhsotg__l3,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_usbhsotg_slaves[] = {
+ &omap2430_l4_core__usbhsotg,
+};
+
+/* L4 CORE -> MMC1 interface */
+static struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = {
+ {
+ .pa_start = 0x4809c000,
+ .pa_end = 0x4809c1ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mmc1_hwmod,
+ .clk = "mmchs1_ick",
+ .addr = omap2430_mmc1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_mmc1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> MMC2 interface */
+static struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = {
+ {
+ .pa_start = 0x480b4000,
+ .pa_end = 0x480b41ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mmc2_hwmod,
+ .addr = omap2430_mmc2_addr_space,
+ .clk = "mmchs2_ick",
+ .addr_cnt = ARRAY_SIZE(omap2430_mmc2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
+ &omap2430_l3_main__l4_core,
+};
+
+/* Master interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
+ &omap2430_l4_core__l4_wkup,
+ &omap2430_l4_core__mmc1,
+ &omap2430_l4_core__mmc2,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap2430_l4_core_hwmod = {
+ .name = "l4_core",
+ .class = &l4_hwmod_class,
+ .masters = omap2430_l4_core_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
+ .slaves = omap2430_l4_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_slaves[] = {
+ &omap2430_l4_core__l4_wkup,
+ &omap2_l4_core__uart1,
+ &omap2_l4_core__uart2,
+ &omap2_l4_core__uart3,
+};
+
+/* Master interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
+};
+
+/* l4 core -> mcspi1 interface */
+static struct omap_hwmod_addr_space omap2430_mcspi1_addr_space[] = {
+ {
+ .pa_start = 0x48098000,
+ .pa_end = 0x480980ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcspi1_hwmod,
+ .clk = "mcspi1_ick",
+ .addr = omap2430_mcspi1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi2 interface */
+static struct omap_hwmod_addr_space omap2430_mcspi2_addr_space[] = {
+ {
+ .pa_start = 0x4809a000,
+ .pa_end = 0x4809a0ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcspi2_hwmod,
+ .clk = "mcspi2_ick",
+ .addr = omap2430_mcspi2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi3 interface */
+static struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = {
+ {
+ .pa_start = 0x480b8000,
+ .pa_end = 0x480b80ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi3 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcspi3_hwmod,
+ .clk = "mcspi3_ick",
+ .addr = omap2430_mcspi3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap2430_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &l4_hwmod_class,
+ .masters = omap2430_l4_wkup_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
+ .slaves = omap2430_l4_wkup_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
+ &omap2430_mpu__l3_main,
+};
+
+/* MPU */
+static struct omap_hwmod omap2430_mpu_hwmod = {
+ .name = "mpu",
+ .class = &mpu_hwmod_class,
+ .main_clk = "mpu_ck",
+ .masters = omap2430_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * IVA2_1 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap2430_l3__iva = {
+ .master = &omap2430_l3_main_hwmod,
+ .slave = &omap2430_iva_hwmod,
+ .clk = "dsp_fck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_iva_masters[] = {
+ &omap2430_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2430_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap2430_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* Timer Common */
+static struct omap_hwmod_class_sysconfig omap2430_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap2430_timer_sysc,
+ .rev = OMAP_TIMER_IP_VERSION_1,
+};
+
+/* timer1 */
+static struct omap_hwmod omap2430_timer1_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer1_mpu_irqs[] = {
+ { .irq = 37, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer1_addrs[] = {
+ {
+ .pa_start = 0x49018000,
+ .pa_end = 0x49018000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__timer1 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_timer1_hwmod,
+ .clk = "gpt1_ick",
+ .addr = omap2430_timer1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer1 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer1_slaves[] = {
+ &omap2430_l4_wkup__timer1,
+};
+
+/* timer1 hwmod */
+static struct omap_hwmod omap2430_timer1_hwmod = {
+ .name = "timer1",
+ .mpu_irqs = omap2430_timer1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer1_mpu_irqs),
+ .main_clk = "gpt1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer1_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer2 */
+static struct omap_hwmod omap2430_timer2_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer2_mpu_irqs[] = {
+ { .irq = 38, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer2_addrs[] = {
+ {
+ .pa_start = 0x4802a000,
+ .pa_end = 0x4802a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer2 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer2_hwmod,
+ .clk = "gpt2_ick",
+ .addr = omap2430_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer2 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer2_slaves[] = {
+ &omap2430_l4_core__timer2,
+};
+
+/* timer2 hwmod */
+static struct omap_hwmod omap2430_timer2_hwmod = {
+ .name = "timer2",
+ .mpu_irqs = omap2430_timer2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer2_mpu_irqs),
+ .main_clk = "gpt2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT2_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer2_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer3 */
+static struct omap_hwmod omap2430_timer3_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer3_mpu_irqs[] = {
+ { .irq = 39, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer3_addrs[] = {
+ {
+ .pa_start = 0x48078000,
+ .pa_end = 0x48078000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer3 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer3 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer3_hwmod,
+ .clk = "gpt3_ick",
+ .addr = omap2430_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer3 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer3_slaves[] = {
+ &omap2430_l4_core__timer3,
+};
+
+/* timer3 hwmod */
+static struct omap_hwmod omap2430_timer3_hwmod = {
+ .name = "timer3",
+ .mpu_irqs = omap2430_timer3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer3_mpu_irqs),
+ .main_clk = "gpt3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT3_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer3_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer4 */
+static struct omap_hwmod omap2430_timer4_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer4_mpu_irqs[] = {
+ { .irq = 40, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer4_addrs[] = {
+ {
+ .pa_start = 0x4807a000,
+ .pa_end = 0x4807a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer4 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer4 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer4_hwmod,
+ .clk = "gpt4_ick",
+ .addr = omap2430_timer4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer4 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer4_slaves[] = {
+ &omap2430_l4_core__timer4,
+};
+
+/* timer4 hwmod */
+static struct omap_hwmod omap2430_timer4_hwmod = {
+ .name = "timer4",
+ .mpu_irqs = omap2430_timer4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer4_mpu_irqs),
+ .main_clk = "gpt4_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT4_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer4_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer5 */
+static struct omap_hwmod omap2430_timer5_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer5_mpu_irqs[] = {
+ { .irq = 41, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer5_addrs[] = {
+ {
+ .pa_start = 0x4807c000,
+ .pa_end = 0x4807c000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer5 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer5 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer5_hwmod,
+ .clk = "gpt5_ick",
+ .addr = omap2430_timer5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer5 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer5_slaves[] = {
+ &omap2430_l4_core__timer5,
+};
+
+/* timer5 hwmod */
+static struct omap_hwmod omap2430_timer5_hwmod = {
+ .name = "timer5",
+ .mpu_irqs = omap2430_timer5_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer5_mpu_irqs),
+ .main_clk = "gpt5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer5_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer6 */
+static struct omap_hwmod omap2430_timer6_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer6_mpu_irqs[] = {
+ { .irq = 42, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer6_addrs[] = {
+ {
+ .pa_start = 0x4807e000,
+ .pa_end = 0x4807e000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer6 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer6 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer6_hwmod,
+ .clk = "gpt6_ick",
+ .addr = omap2430_timer6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer6 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer6_slaves[] = {
+ &omap2430_l4_core__timer6,
+};
+
+/* timer6 hwmod */
+static struct omap_hwmod omap2430_timer6_hwmod = {
+ .name = "timer6",
+ .mpu_irqs = omap2430_timer6_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer6_mpu_irqs),
+ .main_clk = "gpt6_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT6_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer6_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer7 */
+static struct omap_hwmod omap2430_timer7_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer7_mpu_irqs[] = {
+ { .irq = 43, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer7_addrs[] = {
+ {
+ .pa_start = 0x48080000,
+ .pa_end = 0x48080000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer7 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer7 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer7_hwmod,
+ .clk = "gpt7_ick",
+ .addr = omap2430_timer7_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer7_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer7 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer7_slaves[] = {
+ &omap2430_l4_core__timer7,
+};
+
+/* timer7 hwmod */
+static struct omap_hwmod omap2430_timer7_hwmod = {
+ .name = "timer7",
+ .mpu_irqs = omap2430_timer7_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer7_mpu_irqs),
+ .main_clk = "gpt7_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT7_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer7_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer7_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer8 */
+static struct omap_hwmod omap2430_timer8_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer8_mpu_irqs[] = {
+ { .irq = 44, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer8_addrs[] = {
+ {
+ .pa_start = 0x48082000,
+ .pa_end = 0x48082000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer8 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer8 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer8_hwmod,
+ .clk = "gpt8_ick",
+ .addr = omap2430_timer8_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer8_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer8 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer8_slaves[] = {
+ &omap2430_l4_core__timer8,
+};
+
+/* timer8 hwmod */
+static struct omap_hwmod omap2430_timer8_hwmod = {
+ .name = "timer8",
+ .mpu_irqs = omap2430_timer8_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer8_mpu_irqs),
+ .main_clk = "gpt8_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT8_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer8_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer8_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer9 */
+static struct omap_hwmod omap2430_timer9_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer9_mpu_irqs[] = {
+ { .irq = 45, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer9_addrs[] = {
+ {
+ .pa_start = 0x48084000,
+ .pa_end = 0x48084000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer9 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer9 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer9_hwmod,
+ .clk = "gpt9_ick",
+ .addr = omap2430_timer9_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer9_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer9 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer9_slaves[] = {
+ &omap2430_l4_core__timer9,
+};
+
+/* timer9 hwmod */
+static struct omap_hwmod omap2430_timer9_hwmod = {
+ .name = "timer9",
+ .mpu_irqs = omap2430_timer9_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer9_mpu_irqs),
+ .main_clk = "gpt9_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT9_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer9_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer9_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer10 */
+static struct omap_hwmod omap2430_timer10_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer10_mpu_irqs[] = {
+ { .irq = 46, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer10_addrs[] = {
+ {
+ .pa_start = 0x48086000,
+ .pa_end = 0x48086000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer10 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer10 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer10_hwmod,
+ .clk = "gpt10_ick",
+ .addr = omap2430_timer10_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer10_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer10 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer10_slaves[] = {
+ &omap2430_l4_core__timer10,
+};
+
+/* timer10 hwmod */
+static struct omap_hwmod omap2430_timer10_hwmod = {
+ .name = "timer10",
+ .mpu_irqs = omap2430_timer10_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer10_mpu_irqs),
+ .main_clk = "gpt10_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT10_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer10_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer10_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer11 */
+static struct omap_hwmod omap2430_timer11_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer11_mpu_irqs[] = {
+ { .irq = 47, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer11_addrs[] = {
+ {
+ .pa_start = 0x48088000,
+ .pa_end = 0x48088000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer11 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer11 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer11_hwmod,
+ .clk = "gpt11_ick",
+ .addr = omap2430_timer11_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer11_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer11 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer11_slaves[] = {
+ &omap2430_l4_core__timer11,
+};
+
+/* timer11 hwmod */
+static struct omap_hwmod omap2430_timer11_hwmod = {
+ .name = "timer11",
+ .mpu_irqs = omap2430_timer11_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer11_mpu_irqs),
+ .main_clk = "gpt11_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT11_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer11_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer11_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* timer12 */
+static struct omap_hwmod omap2430_timer12_hwmod;
+static struct omap_hwmod_irq_info omap2430_timer12_mpu_irqs[] = {
+ { .irq = 48, },
+};
+
+static struct omap_hwmod_addr_space omap2430_timer12_addrs[] = {
+ {
+ .pa_start = 0x4808a000,
+ .pa_end = 0x4808a000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer12 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__timer12 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_timer12_hwmod,
+ .clk = "gpt12_ick",
+ .addr = omap2430_timer12_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_timer12_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer12 slave port */
+static struct omap_hwmod_ocp_if *omap2430_timer12_slaves[] = {
+ &omap2430_l4_core__timer12,
+};
+
+/* timer12 hwmod */
+static struct omap_hwmod omap2430_timer12_hwmod = {
+ .name = "timer12",
+ .mpu_irqs = omap2430_timer12_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer12_mpu_irqs),
+ .main_clk = "gpt12_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPT12_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT,
+ },
+ },
+ .slaves = omap2430_timer12_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_timer12_slaves),
+ .class = &omap2430_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap2430_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x49016000,
+ .pa_end = 0x4901607f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_wd_timer2_hwmod,
+ .clk = "mpu_wdt_ick",
+ .addr = omap2430_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap2430_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap2430_wd_timer2_slaves[] = {
+ &omap2430_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap2430_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap2430_wd_timer_hwmod_class,
+ .main_clk = "mpu_wdt_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT,
+ },
+ },
+ .slaves = omap2430_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart1_slaves[] = {
+ &omap2_l4_core__uart1,
+};
+
+static struct omap_hwmod omap2430_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart2_slaves[] = {
+ &omap2_l4_core__uart2,
+};
+
+static struct omap_hwmod omap2430_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_uart3_slaves[] = {
+ &omap2_l4_core__uart3,
+};
+
+static struct omap_hwmod omap2430_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP24XX_EN_UART3_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap2430_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap2430_dss_sysc,
+};
+
+static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_masters[] = {
+ &omap2430_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = {
+ &omap2430_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+ { .role = "sys_clk", .clk = "dss2_fck" },
+};
+
+static struct omap_hwmod omap2430_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2430_dss_hwmod_class,
+ .main_clk = "dss1_fck", /* instead of dss_fck */
+ .sdma_reqs = omap2430_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap2430_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_slaves),
+ .masters = omap2430_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2430_dispc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap2430_dispc_irqs[] = {
+ { .irq = 25 },
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_dispc = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_dispc_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = {
+ &omap2430_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap2430_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap2430_dispc_hwmod_class,
+ .mpu_irqs = omap2430_dispc_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dispc_irqs),
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .slaves = omap2430_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap2430_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_rfbi = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_rfbi_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = {
+ &omap2430_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2430_rfbi_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2430_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap2430_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap2430_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_venc_hwmod,
+ .clk = "dss_54m_fck",
+ .addr = omap2430_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_venc_addrs),
+ .flags = OCPIF_SWSUP_IDLE,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = {
+ &omap2430_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap2430_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2430_venc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2430_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_i2c_dev_attr i2c_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+/* I2C1 */
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = {
+ &omap2430_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap2430_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2chs1_fck",
+ .prcm = {
+ .omap2 = {
+ /*
+ * NOTE: The CM_FCLKEN* and CM_ICLKEN* for
+ * I2CHS IP's do not follow the usual pattern.
+ * prcm_reg_id alone cannot be used to program
+ * the iclk and fclk. Needs to be handled using
+ * additional flags when clk handling is moved
+ * to hwmod framework.
+ */
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_I2CHS1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT,
+ },
+ },
+ .slaves = omap2430_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* I2C2 */
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = {
+ &omap2430_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap2430_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2chs2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_I2CHS2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT,
+ },
+ },
+ .slaves = omap2430_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = {
+ {
+ .pa_start = 0x4900C000,
+ .pa_end = 0x4900C1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio1_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio2 */
+static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = {
+ {
+ .pa_start = 0x4900E000,
+ .pa_end = 0x4900E1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio2_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio3 */
+static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = {
+ {
+ .pa_start = 0x49010000,
+ .pa_end = 0x490101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio3_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup -> gpio4 */
+static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = {
+ {
+ .pa_start = 0x49012000,
+ .pa_end = 0x490121ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = {
+ .master = &omap2430_l4_wkup_hwmod,
+ .slave = &omap2430_gpio4_hwmod,
+ .clk = "gpios_ick",
+ .addr = omap2430_gpio4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_core -> gpio5 */
+static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = {
+ {
+ .pa_start = 0x480B6000,
+ .pa_end = 0x480B61ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_gpio5_hwmod,
+ .clk = "gpio5_ick",
+ .addr = omap2430_gpio5_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap2430_gpio5_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = false,
+};
+
+static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+static struct omap_hwmod_class omap243x_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap243x_gpio_sysc,
+ .rev = 0,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = {
+ &omap2430_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap2430_gpio1_hwmod = {
+ .name = "gpio1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap243x_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio1_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = {
+ &omap2430_l4_wkup__gpio2,
+};
+
+static struct omap_hwmod omap2430_gpio2_hwmod = {
+ .name = "gpio2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap243x_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio2_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = {
+ &omap2430_l4_wkup__gpio3,
+};
+
+static struct omap_hwmod omap2430_gpio3_hwmod = {
+ .name = "gpio3",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap243x_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio3_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = {
+ &omap2430_l4_wkup__gpio4,
+};
+
+static struct omap_hwmod omap2430_gpio4_hwmod = {
+ .name = "gpio4",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap243x_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs),
+ .main_clk = "gpios_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio4_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* gpio5 */
+static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = {
+ { .irq = 33 }, /* INT_24XX_GPIO_BANK5 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = {
+ &omap2430_l4_core__gpio5,
+};
+
+static struct omap_hwmod omap2430_gpio5_hwmod = {
+ .name = "gpio5",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap243x_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs),
+ .main_clk = "gpio5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 2,
+ .module_bit = OMAP2430_EN_GPIO5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT,
+ },
+ },
+ .slaves = omap2430_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio5_slaves),
+ .class = &omap243x_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* dma_system */
+static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap2430_dma_sysc,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x48056fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = {
+ .master = &omap2430_dma_system_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .clk = "core_l3_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_masters[] = {
+ &omap2430_dma_system__l3,
+};
+
+/* l4_core -> dma_system */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dma_system_hwmod,
+ .clk = "sdma_ick",
+ .addr = omap2430_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dma_system_slaves[] = {
+ &omap2430_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap2430_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap2430_dma_hwmod_class,
+ .mpu_irqs = omap2430_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dma_system_irqs),
+ .main_clk = "core_l3_ck",
+ .slaves = omap2430_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dma_system_slaves),
+ .masters = omap2430_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors
+ * using a queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_mailbox_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap2430_mailbox_sysc,
+};
+
+/* mailbox */
+static struct omap_hwmod omap2430_mailbox_hwmod;
+static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = {
+ { .irq = 26 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mailbox_addrs[] = {
+ {
+ .pa_start = 0x48094000,
+ .pa_end = 0x480941ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* l4_core -> mailbox */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mailbox = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mailbox_hwmod,
+ .addr = omap2430_mailbox_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mailbox_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mailbox slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mailbox_slaves[] = {
+ &omap2430_l4_core__mailbox,
+};
+
+static struct omap_hwmod omap2430_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap2430_mailbox_hwmod_class,
+ .mpu_irqs = omap2430_mailbox_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mailbox_irqs),
+ .main_clk = "mailboxes_ick",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT,
+ },
+ },
+ .slaves = omap2430_mailbox_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mailbox_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_mcspi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &omap2430_mcspi_sysc,
+ .rev = OMAP2_MCSPI_REV,
+};
+
+/* mcspi1 */
+static struct omap_hwmod_irq_info omap2430_mcspi1_mpu_irqs[] = {
+ { .irq = 65 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcspi1_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */
+ { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */
+ { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */
+ { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */
+ { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */
+ { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */
+ { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */
+ { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_mcspi1_slaves[] = {
+ &omap2430_l4_core__mcspi1,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap2430_mcspi1_hwmod = {
+ .name = "mcspi1_hwmod",
+ .mpu_irqs = omap2430_mcspi1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi1_mpu_irqs),
+ .sdma_reqs = omap2430_mcspi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi1_sdma_reqs),
+ .main_clk = "mcspi1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCSPI1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcspi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi1_slaves),
+ .class = &omap2430_mcspi_class,
+ .dev_attr = &omap_mcspi1_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcspi2 */
+static struct omap_hwmod_irq_info omap2430_mcspi2_mpu_irqs[] = {
+ { .irq = 66 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcspi2_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */
+ { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */
+ { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */
+ { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_mcspi2_slaves[] = {
+ &omap2430_l4_core__mcspi2,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap2430_mcspi2_hwmod = {
+ .name = "mcspi2_hwmod",
+ .mpu_irqs = omap2430_mcspi2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi2_mpu_irqs),
+ .sdma_reqs = omap2430_mcspi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi2_sdma_reqs),
+ .main_clk = "mcspi2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCSPI2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcspi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi2_slaves),
+ .class = &omap2430_mcspi_class,
+ .dev_attr = &omap_mcspi2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcspi3 */
+static struct omap_hwmod_irq_info omap2430_mcspi3_mpu_irqs[] = {
+ { .irq = 91 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcspi3_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 15 }, /* DMA_SPI3_TX0 */
+ { .name = "rx0", .dma_req = 16 }, /* DMA_SPI3_RX0 */
+ { .name = "tx1", .dma_req = 23 }, /* DMA_SPI3_TX1 */
+ { .name = "rx1", .dma_req = 24 }, /* DMA_SPI3_RX1 */
+};
+
+static struct omap_hwmod_ocp_if *omap2430_mcspi3_slaves[] = {
+ &omap2430_l4_core__mcspi3,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap2430_mcspi3_hwmod = {
+ .name = "mcspi3_hwmod",
+ .mpu_irqs = omap2430_mcspi3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi3_mpu_irqs),
+ .sdma_reqs = omap2430_mcspi3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi3_sdma_reqs),
+ .main_clk = "mcspi3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP2430_EN_MCSPI3_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MCSPI3_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcspi3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi3_slaves),
+ .class = &omap2430_mcspi_class,
+ .dev_attr = &omap_mcspi3_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/*
+ * usbhsotg
+ */
+static struct omap_hwmod_class_sysconfig omap2430_usbhsotg_sysc = {
+ .rev_offs = 0x0400,
+ .sysc_offs = 0x0404,
+ .syss_offs = 0x0408,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE|
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class usbotg_class = {
+ .name = "usbotg",
+ .sysc = &omap2430_usbhsotg_sysc,
+};
+
+/* usb_otg_hs */
+static struct omap_hwmod_irq_info omap2430_usbhsotg_mpu_irqs[] = {
+
+ { .name = "mc", .irq = 92 },
+ { .name = "dma", .irq = 93 },
+};
+
+static struct omap_hwmod omap2430_usbhsotg_hwmod = {
+ .name = "usb_otg_hs",
+ .mpu_irqs = omap2430_usbhsotg_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_usbhsotg_mpu_irqs),
+ .main_clk = "usbhs_ick",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_USBHS_MASK,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP2430_ST_USBHS_SHIFT,
+ },
+ },
+ .masters = omap2430_usbhsotg_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_usbhsotg_masters),
+ .slaves = omap2430_usbhsotg_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_usbhsotg_slaves),
+ .class = &usbotg_class,
+ /*
+ * Erratum ID: i479 idle_req / idle_ack mechanism potentially
+ * broken when autoidle is enabled
+ * workaround is to disable the autoidle bit at module level.
+ */
+ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
+ | HWMOD_SWSUP_MSTANDBY,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = {
+ .rev_offs = 0x007C,
+ .sysc_offs = 0x008C,
+ .sysc_flags = (SYSC_HAS_SOFTRESET),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+ .sysc = &omap2430_mcbsp_sysc,
+ .rev = MCBSP_CONFIG_TYPE2,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap2430_mcbsp1_irqs[] = {
+ { .name = "tx", .irq = 59 },
+ { .name = "rx", .irq = 60 },
+ { .name = "ovr", .irq = 61 },
+ { .name = "common", .irq = 64 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp1_sdma_chs[] = {
+ { .name = "rx", .dma_req = 32 },
+ { .name = "tx", .dma_req = 31 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp1_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48074000,
+ .pa_end = 0x480740ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp1 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcbsp1_hwmod,
+ .clk = "mcbsp1_ick",
+ .addr = omap2430_mcbsp1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp1_slaves[] = {
+ &omap2430_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap2430_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .mpu_irqs = omap2430_mcbsp1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp1_irqs),
+ .sdma_reqs = omap2430_mcbsp1_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp1_sdma_chs),
+ .main_clk = "mcbsp1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCBSP1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcbsp1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap2430_mcbsp2_irqs[] = {
+ { .name = "tx", .irq = 62 },
+ { .name = "rx", .irq = 63 },
+ { .name = "common", .irq = 16 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp2_sdma_chs[] = {
+ { .name = "rx", .dma_req = 34 },
+ { .name = "tx", .dma_req = 33 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp2_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48076000,
+ .pa_end = 0x480760ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp2 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcbsp2_hwmod,
+ .clk = "mcbsp2_ick",
+ .addr = omap2430_mcbsp2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp2_slaves[] = {
+ &omap2430_l4_core__mcbsp2,
+};
+
+static struct omap_hwmod omap2430_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .mpu_irqs = omap2430_mcbsp2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp2_irqs),
+ .sdma_reqs = omap2430_mcbsp2_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp2_sdma_chs),
+ .main_clk = "mcbsp2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_MCBSP2_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcbsp2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_irq_info omap2430_mcbsp3_irqs[] = {
+ { .name = "tx", .irq = 89 },
+ { .name = "rx", .irq = 90 },
+ { .name = "common", .irq = 17 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp3_sdma_chs[] = {
+ { .name = "rx", .dma_req = 18 },
+ { .name = "tx", .dma_req = 17 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp3_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x4808C000,
+ .pa_end = 0x4808C0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp3 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcbsp3_hwmod,
+ .clk = "mcbsp3_ick",
+ .addr = omap2430_mcbsp3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp3_slaves[] = {
+ &omap2430_l4_core__mcbsp3,
+};
+
+static struct omap_hwmod omap2430_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .mpu_irqs = omap2430_mcbsp3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp3_irqs),
+ .sdma_reqs = omap2430_mcbsp3_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp3_sdma_chs),
+ .main_clk = "mcbsp3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_MCBSP3_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcbsp3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_irq_info omap2430_mcbsp4_irqs[] = {
+ { .name = "tx", .irq = 54 },
+ { .name = "rx", .irq = 55 },
+ { .name = "common", .irq = 18 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp4_sdma_chs[] = {
+ { .name = "rx", .dma_req = 20 },
+ { .name = "tx", .dma_req = 19 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp4_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x4808E000,
+ .pa_end = 0x4808E0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp4 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcbsp4_hwmod,
+ .clk = "mcbsp4_ick",
+ .addr = omap2430_mcbsp4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp4_slaves[] = {
+ &omap2430_l4_core__mcbsp4,
+};
+
+static struct omap_hwmod omap2430_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .mpu_irqs = omap2430_mcbsp4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp4_irqs),
+ .sdma_reqs = omap2430_mcbsp4_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp4_sdma_chs),
+ .main_clk = "mcbsp4_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_MCBSP4_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcbsp4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod_irq_info omap2430_mcbsp5_irqs[] = {
+ { .name = "tx", .irq = 81 },
+ { .name = "rx", .irq = 82 },
+ { .name = "common", .irq = 19 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mcbsp5_sdma_chs[] = {
+ { .name = "rx", .dma_req = 22 },
+ { .name = "tx", .dma_req = 21 },
+};
+
+static struct omap_hwmod_addr_space omap2430_mcbsp5_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48096000,
+ .pa_end = 0x480960ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp5 */
+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_mcbsp5_hwmod,
+ .clk = "mcbsp5_ick",
+ .addr = omap2430_mcbsp5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp5 slave ports */
+static struct omap_hwmod_ocp_if *omap2430_mcbsp5_slaves[] = {
+ &omap2430_l4_core__mcbsp5,
+};
+
+static struct omap_hwmod omap2430_mcbsp5_hwmod = {
+ .name = "mcbsp5",
+ .class = &omap2430_mcbsp_hwmod_class,
+ .mpu_irqs = omap2430_mcbsp5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp5_irqs),
+ .sdma_reqs = omap2430_mcbsp5_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp5_sdma_chs),
+ .main_clk = "mcbsp5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP2430_EN_MCBSP5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT,
+ },
+ },
+ .slaves = omap2430_mcbsp5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* MMC/SD/SDIO common */
+
+static struct omap_hwmod_class_sysconfig omap2430_mmc_sysc = {
+ .rev_offs = 0x1fc,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_mmc_class = {
+ .name = "mmc",
+ .sysc = &omap2430_mmc_sysc,
+};
+
+/* MMC/SD/SDIO1 */
+
+static struct omap_hwmod_irq_info omap2430_mmc1_mpu_irqs[] = {
+ { .irq = 83 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mmc1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 61 }, /* DMA_MMC1_TX */
+ { .name = "rx", .dma_req = 62 }, /* DMA_MMC1_RX */
+};
+
+static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "mmchsdb1_fck" },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_mmc1_slaves[] = {
+ &omap2430_l4_core__mmc1,
+};
+
+static struct omap_mmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod omap2430_mmc1_hwmod = {
+ .name = "mmc1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2430_mmc1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mmc1_mpu_irqs),
+ .sdma_reqs = omap2430_mmc1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mmc1_sdma_reqs),
+ .opt_clks = omap2430_mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc1_opt_clks),
+ .main_clk = "mmchs1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP2430_EN_MMCHS1_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MMCHS1_SHIFT,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .slaves = omap2430_mmc1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mmc1_slaves),
+ .class = &omap2430_mmc_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+/* MMC/SD/SDIO2 */
+
+static struct omap_hwmod_irq_info omap2430_mmc2_mpu_irqs[] = {
+ { .irq = 86 },
+};
+
+static struct omap_hwmod_dma_info omap2430_mmc2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 47 }, /* DMA_MMC2_TX */
+ { .name = "rx", .dma_req = 48 }, /* DMA_MMC2_RX */
+};
+
+static struct omap_hwmod_opt_clk omap2430_mmc2_opt_clks[] = {
+ { .role = "dbck", .clk = "mmchsdb2_fck" },
+};
+
+static struct omap_hwmod_ocp_if *omap2430_mmc2_slaves[] = {
+ &omap2430_l4_core__mmc2,
+};
+
+static struct omap_hwmod omap2430_mmc2_hwmod = {
+ .name = "mmc2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap2430_mmc2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mmc2_mpu_irqs),
+ .sdma_reqs = omap2430_mmc2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mmc2_sdma_reqs),
+ .opt_clks = omap2430_mmc2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc2_opt_clks),
+ .main_clk = "mmchs2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 2,
+ .module_bit = OMAP2430_EN_MMCHS2_SHIFT,
+ .idlest_reg_id = 2,
+ .idlest_idle_bit = OMAP2430_ST_MMCHS2_SHIFT,
+ },
+ },
+ .slaves = omap2430_mmc2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_mmc2_slaves),
+ .class = &omap2430_mmc_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static __initdata struct omap_hwmod *omap2430_hwmods[] = {
+ &omap2430_l3_main_hwmod,
+ &omap2430_l4_core_hwmod,
+ &omap2430_l4_wkup_hwmod,
+ &omap2430_mpu_hwmod,
+ &omap2430_iva_hwmod,
+
+ &omap2430_timer1_hwmod,
+ &omap2430_timer2_hwmod,
+ &omap2430_timer3_hwmod,
+ &omap2430_timer4_hwmod,
+ &omap2430_timer5_hwmod,
+ &omap2430_timer6_hwmod,
+ &omap2430_timer7_hwmod,
+ &omap2430_timer8_hwmod,
+ &omap2430_timer9_hwmod,
+ &omap2430_timer10_hwmod,
+ &omap2430_timer11_hwmod,
+ &omap2430_timer12_hwmod,
+
+ &omap2430_wd_timer2_hwmod,
+ &omap2430_uart1_hwmod,
+ &omap2430_uart2_hwmod,
+ &omap2430_uart3_hwmod,
+ /* dss class */
+ &omap2430_dss_core_hwmod,
+ &omap2430_dss_dispc_hwmod,
+ &omap2430_dss_rfbi_hwmod,
+ &omap2430_dss_venc_hwmod,
+ /* i2c class */
+ &omap2430_i2c1_hwmod,
+ &omap2430_i2c2_hwmod,
+ &omap2430_mmc1_hwmod,
+ &omap2430_mmc2_hwmod,
+
+ /* gpio class */
+ &omap2430_gpio1_hwmod,
+ &omap2430_gpio2_hwmod,
+ &omap2430_gpio3_hwmod,
+ &omap2430_gpio4_hwmod,
+ &omap2430_gpio5_hwmod,
+
+ /* dma_system class*/
+ &omap2430_dma_system_hwmod,
+
+ /* mcbsp class */
+ &omap2430_mcbsp1_hwmod,
+ &omap2430_mcbsp2_hwmod,
+ &omap2430_mcbsp3_hwmod,
+ &omap2430_mcbsp4_hwmod,
+ &omap2430_mcbsp5_hwmod,
+
+ /* mailbox class */
+ &omap2430_mailbox_hwmod,
+
+ /* mcspi class */
+ &omap2430_mcspi1_hwmod,
+ &omap2430_mcspi2_hwmod,
+ &omap2430_mcspi3_hwmod,
+
+ /* usbotg class*/
+ &omap2430_usbhsotg_hwmod,
+
+ NULL,
+};
+
+int __init omap2430_hwmod_init(void)
+{
+ return omap_hwmod_register(omap2430_hwmods);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
new file mode 100644
index 00000000..909a84de
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -0,0 +1,3665 @@
+/*
+ * omap_hwmod_3xxx_data.c - hardware modules present on the OMAP3xxx chips
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The data in this file should be completely autogeneratable from
+ * the TI hardware database or other technical documentation.
+ *
+ * XXX these should be marked initdata for multi-OMAP kernels
+ */
+#include <plat/omap_hwmod.h>
+#include <mach/irqs.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
+#include <plat/serial.h>
+#include <plat/l3_3xxx.h>
+#include <plat/l4_3xxx.h>
+#include <plat/i2c.h>
+#include <plat/gpio.h>
+#include <plat/mmc.h>
+#include <plat/mcbsp.h>
+#include <plat/mcspi.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "prm-regbits-34xx.h"
+#include "cm-regbits-34xx.h"
+#include "wd_timer.h"
+#include <mach/am35xx.h>
+
+/*
+ * OMAP3xxx hardware module integration data
+ *
+ * ALl of the data in this section should be autogeneratable from the
+ * TI hardware database or other technical documentation. Data that
+ * is driver-specific or driver-kernel integration-specific belongs
+ * elsewhere.
+ */
+
+static struct omap_hwmod omap3xxx_mpu_hwmod;
+static struct omap_hwmod omap3xxx_iva_hwmod;
+static struct omap_hwmod omap3xxx_l3_main_hwmod;
+static struct omap_hwmod omap3xxx_l4_core_hwmod;
+static struct omap_hwmod omap3xxx_l4_per_hwmod;
+static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
+static struct omap_hwmod omap3430es1_dss_core_hwmod;
+static struct omap_hwmod omap3xxx_dss_core_hwmod;
+static struct omap_hwmod omap3xxx_dss_dispc_hwmod;
+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod;
+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod;
+static struct omap_hwmod omap3xxx_dss_venc_hwmod;
+static struct omap_hwmod omap3xxx_i2c1_hwmod;
+static struct omap_hwmod omap3xxx_i2c2_hwmod;
+static struct omap_hwmod omap3xxx_i2c3_hwmod;
+static struct omap_hwmod omap3xxx_gpio1_hwmod;
+static struct omap_hwmod omap3xxx_gpio2_hwmod;
+static struct omap_hwmod omap3xxx_gpio3_hwmod;
+static struct omap_hwmod omap3xxx_gpio4_hwmod;
+static struct omap_hwmod omap3xxx_gpio5_hwmod;
+static struct omap_hwmod omap3xxx_gpio6_hwmod;
+static struct omap_hwmod omap34xx_sr1_hwmod;
+static struct omap_hwmod omap34xx_sr2_hwmod;
+static struct omap_hwmod omap34xx_mcspi1;
+static struct omap_hwmod omap34xx_mcspi2;
+static struct omap_hwmod omap34xx_mcspi3;
+static struct omap_hwmod omap34xx_mcspi4;
+static struct omap_hwmod omap3xxx_mmc1_hwmod;
+static struct omap_hwmod omap3xxx_mmc2_hwmod;
+static struct omap_hwmod omap3xxx_mmc3_hwmod;
+static struct omap_hwmod am35xx_usbhsotg_hwmod;
+
+static struct omap_hwmod omap3xxx_dma_system_hwmod;
+
+static struct omap_hwmod omap3xxx_mcbsp1_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp2_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp3_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp4_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp5_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod;
+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod;
+
+/* L3 -> L4_CORE interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_l4_core_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L3 -> L4_PER interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_l4_per_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L3 taret configuration and error log registers */
+static struct omap_hwmod_irq_info omap3xxx_l3_main_irqs[] = {
+ { .irq = INT_34XX_L3_DBG_IRQ },
+ { .irq = INT_34XX_L3_APP_IRQ },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_l3_main_addrs[] = {
+ {
+ .pa_start = 0x68000000,
+ .pa_end = 0x6800ffff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* MPU -> L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
+ .master = &omap3xxx_mpu_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .addr = omap3xxx_l3_main_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_l3_main_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* Slave interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
+ &omap3xxx_mpu__l3_main,
+};
+
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = {
+ .master = &omap3xxx_dss_core_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* Master interfaces on the L3 interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
+ &omap3xxx_l3_main__l4_core,
+ &omap3xxx_l3_main__l4_per,
+};
+
+/* L3 */
+static struct omap_hwmod omap3xxx_l3_main_hwmod = {
+ .name = "l3_main",
+ .class = &l3_hwmod_class,
+ .mpu_irqs = omap3xxx_l3_main_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_l3_main_irqs),
+ .masters = omap3xxx_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
+ .slaves = omap3xxx_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
+static struct omap_hwmod omap3xxx_uart1_hwmod;
+static struct omap_hwmod omap3xxx_uart2_hwmod;
+static struct omap_hwmod omap3xxx_uart3_hwmod;
+static struct omap_hwmod omap3xxx_uart4_hwmod;
+static struct omap_hwmod omap3xxx_usbhsotg_hwmod;
+
+/* l3_core -> usbhsotg interface */
+static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = {
+ .master = &omap3xxx_usbhsotg_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU,
+};
+
+/* l3_core -> am35xx_usbhsotg interface */
+static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = {
+ .master = &am35xx_usbhsotg_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU,
+};
+/* L4_CORE -> L4_WKUP interface */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_l4_wkup_hwmod,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> MMC1 interface */
+static struct omap_hwmod_addr_space omap3xxx_mmc1_addr_space[] = {
+ {
+ .pa_start = 0x4809c000,
+ .pa_end = 0x4809c1ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mmc1_hwmod,
+ .clk = "mmchs1_ick",
+ .addr = omap3xxx_mmc1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+/* L4 CORE -> MMC2 interface */
+static struct omap_hwmod_addr_space omap3xxx_mmc2_addr_space[] = {
+ {
+ .pa_start = 0x480b4000,
+ .pa_end = 0x480b41ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mmc2_hwmod,
+ .clk = "mmchs2_ick",
+ .addr = omap3xxx_mmc2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+/* L4 CORE -> MMC3 interface */
+static struct omap_hwmod_addr_space omap3xxx_mmc3_addr_space[] = {
+ {
+ .pa_start = 0x480ad000,
+ .pa_end = 0x480ad1ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc3 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mmc3_hwmod,
+ .clk = "mmchs3_ick",
+ .addr = omap3xxx_mmc3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+ .flags = OMAP_FIREWALL_L4
+};
+
+/* L4 CORE -> UART1 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart1_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART1_BASE,
+ .pa_end = OMAP3_UART1_BASE + SZ_8K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__uart1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_uart1_hwmod,
+ .clk = "uart1_ick",
+ .addr = omap3xxx_uart1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> UART2 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart2_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART2_BASE,
+ .pa_end = OMAP3_UART2_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__uart2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_uart2_hwmod,
+ .clk = "uart2_ick",
+ .addr = omap3xxx_uart2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART3 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart3_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART3_BASE,
+ .pa_end = OMAP3_UART3_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_per__uart3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_uart3_hwmod,
+ .clk = "uart3_ick",
+ .addr = omap3xxx_uart3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 PER -> UART4 interface */
+static struct omap_hwmod_addr_space omap3xxx_uart4_addr_space[] = {
+ {
+ .pa_start = OMAP3_UART4_BASE,
+ .pa_end = OMAP3_UART4_BASE + SZ_1K - 1,
+ .flags = ADDR_MAP_ON_INIT | ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_per__uart4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_uart4_hwmod,
+ .clk = "uart4_ick",
+ .addr = omap3xxx_uart4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_uart4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* I2C IP block address space length (in bytes) */
+#define OMAP2_I2C_AS_LEN 128
+
+/* L4 CORE -> I2C1 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c1_addr_space[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c1_hwmod,
+ .clk = "i2c1_ick",
+ .addr = omap3xxx_i2c1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c1_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C1_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C2 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c2_addr_space[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c2_hwmod,
+ .clk = "i2c2_ick",
+ .addr = omap3xxx_i2c2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c2_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C2_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> I2C3 interface */
+static struct omap_hwmod_addr_space omap3xxx_i2c3_addr_space[] = {
+ {
+ .pa_start = 0x48060000,
+ .pa_end = 0x48060000 + OMAP2_I2C_AS_LEN - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_i2c3_hwmod,
+ .clk = "i2c3_ick",
+ .addr = omap3xxx_i2c3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_i2c3_addr_space),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_I2C3_REGION,
+ .l4_prot_group = 7,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
+ {
+ .pa_start = OMAP34XX_SR1_BASE,
+ .pa_end = OMAP34XX_SR1_BASE + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr1_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3_sr1_addr_space),
+ .user = OCP_USER_MPU,
+};
+
+/* L4 CORE -> SR1 interface */
+static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = {
+ {
+ .pa_start = OMAP34XX_SR2_BASE,
+ .pa_end = OMAP34XX_SR2_BASE + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_sr2_hwmod,
+ .clk = "sr_l4_ick",
+ .addr = omap3_sr2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap3_sr2_addr_space),
+ .user = OCP_USER_MPU,
+};
+
+/*
+* usbhsotg interface data
+*/
+
+static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = {
+ {
+ .pa_start = OMAP34XX_HSUSB_OTG_BASE,
+ .pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> usbhsotg */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_usbhsotg_hwmod,
+ .clk = "l4_ick",
+ .addr = omap3xxx_usbhsotg_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_masters[] = {
+ &omap3xxx_usbhsotg__l3,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_slaves[] = {
+ &omap3xxx_l4_core__usbhsotg,
+};
+
+static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = {
+ {
+ .pa_start = AM35XX_IPSS_USBOTGSS_BASE,
+ .pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> usbhsotg */
+static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &am35xx_usbhsotg_hwmod,
+ .clk = "l4_ick",
+ .addr = am35xx_usbhsotg_addrs,
+ .addr_cnt = ARRAY_SIZE(am35xx_usbhsotg_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *am35xx_usbhsotg_masters[] = {
+ &am35xx_usbhsotg__l3,
+};
+
+static struct omap_hwmod_ocp_if *am35xx_usbhsotg_slaves[] = {
+ &am35xx_l4_core__usbhsotg,
+};
+/* Slave interfaces on the L4_CORE interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
+ &omap3xxx_l3_main__l4_core,
+};
+
+/* L4 CORE */
+static struct omap_hwmod omap3xxx_l4_core_hwmod = {
+ .name = "l4_core",
+ .class = &l4_hwmod_class,
+ .slaves = omap3xxx_l4_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Slave interfaces on the L4_PER interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
+ &omap3xxx_l3_main__l4_per,
+};
+
+/* L4 PER */
+static struct omap_hwmod omap3xxx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &l4_hwmod_class,
+ .slaves = omap3xxx_l4_per_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Slave interfaces on the L4_WKUP interconnect */
+static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_slaves[] = {
+ &omap3xxx_l4_core__l4_wkup,
+};
+
+/* L4 WKUP */
+static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &l4_hwmod_class,
+ .slaves = omap3xxx_l4_wkup_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* Master interfaces on the MPU device */
+static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
+ &omap3xxx_mpu__l3_main,
+};
+
+/* MPU */
+static struct omap_hwmod omap3xxx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &mpu_hwmod_class,
+ .main_clk = "arm_fck",
+ .masters = omap3xxx_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * IVA2_2 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_iva_hwmod,
+ .clk = "iva2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
+ &omap3xxx_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap3xxx_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap3xxx_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer class */
+static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap3xxx_timer_1ms_sysc,
+ .rev = OMAP_TIMER_IP_VERSION_1,
+};
+
+static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap3xxx_timer_sysc,
+ .rev = OMAP_TIMER_IP_VERSION_1,
+};
+
+/* timer1 */
+static struct omap_hwmod omap3xxx_timer1_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer1_mpu_irqs[] = {
+ { .irq = 37, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer1_addrs[] = {
+ {
+ .pa_start = 0x48318000,
+ .pa_end = 0x48318000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__timer1 = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_timer1_hwmod,
+ .clk = "gpt1_ick",
+ .addr = omap3xxx_timer1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer1 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer1_slaves[] = {
+ &omap3xxx_l4_wkup__timer1,
+};
+
+/* timer1 hwmod */
+static struct omap_hwmod omap3xxx_timer1_hwmod = {
+ .name = "timer1",
+ .mpu_irqs = omap3xxx_timer1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer1_mpu_irqs),
+ .main_clk = "gpt1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer1_slaves),
+ .class = &omap3xxx_timer_1ms_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer2 */
+static struct omap_hwmod omap3xxx_timer2_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer2_mpu_irqs[] = {
+ { .irq = 38, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer2_addrs[] = {
+ {
+ .pa_start = 0x49032000,
+ .pa_end = 0x49032000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer2 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer2 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer2_hwmod,
+ .clk = "gpt2_ick",
+ .addr = omap3xxx_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer2 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer2_slaves[] = {
+ &omap3xxx_l4_per__timer2,
+};
+
+/* timer2 hwmod */
+static struct omap_hwmod omap3xxx_timer2_hwmod = {
+ .name = "timer2",
+ .mpu_irqs = omap3xxx_timer2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer2_mpu_irqs),
+ .main_clk = "gpt2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT2_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer2_slaves),
+ .class = &omap3xxx_timer_1ms_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer3 */
+static struct omap_hwmod omap3xxx_timer3_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer3_mpu_irqs[] = {
+ { .irq = 39, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer3_addrs[] = {
+ {
+ .pa_start = 0x49034000,
+ .pa_end = 0x49034000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer3 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer3_hwmod,
+ .clk = "gpt3_ick",
+ .addr = omap3xxx_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer3 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer3_slaves[] = {
+ &omap3xxx_l4_per__timer3,
+};
+
+/* timer3 hwmod */
+static struct omap_hwmod omap3xxx_timer3_hwmod = {
+ .name = "timer3",
+ .mpu_irqs = omap3xxx_timer3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer3_mpu_irqs),
+ .main_clk = "gpt3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT3_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer3_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer4 */
+static struct omap_hwmod omap3xxx_timer4_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer4_mpu_irqs[] = {
+ { .irq = 40, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer4_addrs[] = {
+ {
+ .pa_start = 0x49036000,
+ .pa_end = 0x49036000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer4 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer4_hwmod,
+ .clk = "gpt4_ick",
+ .addr = omap3xxx_timer4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer4 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer4_slaves[] = {
+ &omap3xxx_l4_per__timer4,
+};
+
+/* timer4 hwmod */
+static struct omap_hwmod omap3xxx_timer4_hwmod = {
+ .name = "timer4",
+ .mpu_irqs = omap3xxx_timer4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer4_mpu_irqs),
+ .main_clk = "gpt4_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT4_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer4_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer5 */
+static struct omap_hwmod omap3xxx_timer5_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer5_mpu_irqs[] = {
+ { .irq = 41, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer5_addrs[] = {
+ {
+ .pa_start = 0x49038000,
+ .pa_end = 0x49038000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer5 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer5 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer5_hwmod,
+ .clk = "gpt5_ick",
+ .addr = omap3xxx_timer5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer5 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer5_slaves[] = {
+ &omap3xxx_l4_per__timer5,
+};
+
+/* timer5 hwmod */
+static struct omap_hwmod omap3xxx_timer5_hwmod = {
+ .name = "timer5",
+ .mpu_irqs = omap3xxx_timer5_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer5_mpu_irqs),
+ .main_clk = "gpt5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT5_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer5_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer6 */
+static struct omap_hwmod omap3xxx_timer6_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer6_mpu_irqs[] = {
+ { .irq = 42, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer6_addrs[] = {
+ {
+ .pa_start = 0x4903A000,
+ .pa_end = 0x4903A000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer6 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer6 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer6_hwmod,
+ .clk = "gpt6_ick",
+ .addr = omap3xxx_timer6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer6 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer6_slaves[] = {
+ &omap3xxx_l4_per__timer6,
+};
+
+/* timer6 hwmod */
+static struct omap_hwmod omap3xxx_timer6_hwmod = {
+ .name = "timer6",
+ .mpu_irqs = omap3xxx_timer6_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer6_mpu_irqs),
+ .main_clk = "gpt6_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT6_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer6_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer7 */
+static struct omap_hwmod omap3xxx_timer7_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer7_mpu_irqs[] = {
+ { .irq = 43, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer7_addrs[] = {
+ {
+ .pa_start = 0x4903C000,
+ .pa_end = 0x4903C000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer7 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer7 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer7_hwmod,
+ .clk = "gpt7_ick",
+ .addr = omap3xxx_timer7_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer7_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer7 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer7_slaves[] = {
+ &omap3xxx_l4_per__timer7,
+};
+
+/* timer7 hwmod */
+static struct omap_hwmod omap3xxx_timer7_hwmod = {
+ .name = "timer7",
+ .mpu_irqs = omap3xxx_timer7_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer7_mpu_irqs),
+ .main_clk = "gpt7_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT7_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer7_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer7_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer8 */
+static struct omap_hwmod omap3xxx_timer8_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer8_mpu_irqs[] = {
+ { .irq = 44, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer8_addrs[] = {
+ {
+ .pa_start = 0x4903E000,
+ .pa_end = 0x4903E000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer8 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer8 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer8_hwmod,
+ .clk = "gpt8_ick",
+ .addr = omap3xxx_timer8_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer8_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer8 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer8_slaves[] = {
+ &omap3xxx_l4_per__timer8,
+};
+
+/* timer8 hwmod */
+static struct omap_hwmod omap3xxx_timer8_hwmod = {
+ .name = "timer8",
+ .mpu_irqs = omap3xxx_timer8_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer8_mpu_irqs),
+ .main_clk = "gpt8_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT8_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer8_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer8_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer9 */
+static struct omap_hwmod omap3xxx_timer9_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer9_mpu_irqs[] = {
+ { .irq = 45, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer9_addrs[] = {
+ {
+ .pa_start = 0x49040000,
+ .pa_end = 0x49040000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer9 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer9 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_timer9_hwmod,
+ .clk = "gpt9_ick",
+ .addr = omap3xxx_timer9_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer9_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer9 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer9_slaves[] = {
+ &omap3xxx_l4_per__timer9,
+};
+
+/* timer9 hwmod */
+static struct omap_hwmod omap3xxx_timer9_hwmod = {
+ .name = "timer9",
+ .mpu_irqs = omap3xxx_timer9_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer9_mpu_irqs),
+ .main_clk = "gpt9_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT9_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer9_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer9_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer10 */
+static struct omap_hwmod omap3xxx_timer10_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer10_mpu_irqs[] = {
+ { .irq = 46, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer10_addrs[] = {
+ {
+ .pa_start = 0x48086000,
+ .pa_end = 0x48086000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer10 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer10 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_timer10_hwmod,
+ .clk = "gpt10_ick",
+ .addr = omap3xxx_timer10_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer10_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer10 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer10_slaves[] = {
+ &omap3xxx_l4_core__timer10,
+};
+
+/* timer10 hwmod */
+static struct omap_hwmod omap3xxx_timer10_hwmod = {
+ .name = "timer10",
+ .mpu_irqs = omap3xxx_timer10_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer10_mpu_irqs),
+ .main_clk = "gpt10_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT10_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer10_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer10_slaves),
+ .class = &omap3xxx_timer_1ms_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer11 */
+static struct omap_hwmod omap3xxx_timer11_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer11_mpu_irqs[] = {
+ { .irq = 47, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer11_addrs[] = {
+ {
+ .pa_start = 0x48088000,
+ .pa_end = 0x48088000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer11 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer11 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_timer11_hwmod,
+ .clk = "gpt11_ick",
+ .addr = omap3xxx_timer11_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer11_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer11 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer11_slaves[] = {
+ &omap3xxx_l4_core__timer11,
+};
+
+/* timer11 hwmod */
+static struct omap_hwmod omap3xxx_timer11_hwmod = {
+ .name = "timer11",
+ .mpu_irqs = omap3xxx_timer11_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer11_mpu_irqs),
+ .main_clk = "gpt11_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT11_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer11_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer11_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* timer12*/
+static struct omap_hwmod omap3xxx_timer12_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_timer12_mpu_irqs[] = {
+ { .irq = 95, },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_timer12_addrs[] = {
+ {
+ .pa_start = 0x48304000,
+ .pa_end = 0x48304000 + SZ_1K - 1,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> timer12 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer12 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_timer12_hwmod,
+ .clk = "gpt12_ick",
+ .addr = omap3xxx_timer12_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer12_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer12 slave port */
+static struct omap_hwmod_ocp_if *omap3xxx_timer12_slaves[] = {
+ &omap3xxx_l4_core__timer12,
+};
+
+/* timer12 hwmod */
+static struct omap_hwmod omap3xxx_timer12_hwmod = {
+ .name = "timer12",
+ .mpu_irqs = omap3xxx_timer12_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer12_mpu_irqs),
+ .main_clk = "gpt12_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPT12_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_timer12_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer12_slaves),
+ .class = &omap3xxx_timer_hwmod_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x48314000,
+ .pa_end = 0x4831407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_wd_timer2_hwmod,
+ .clk = "wdt2_ick",
+ .addr = omap3xxx_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x00,
+ .sysc_offs = 0x20,
+ .syss_offs = 0x10,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap3xxx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable
+};
+
+/* wd_timer2 */
+static struct omap_hwmod_ocp_if *omap3xxx_wd_timer2_slaves[] = {
+ &omap3xxx_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap3xxx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap3xxx_wd_timer_hwmod_class,
+ .main_clk = "wdt2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_WDT2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_WDT2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ /*
+ * XXX: Use software supervised mode, HW supervised smartidle seems to
+ * block CORE power domain idle transitions. Maybe a HW bug in wdt2?
+ */
+ .flags = HWMOD_SWSUP_SIDLE,
+};
+
+/* UART common */
+
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+/* UART1 */
+
+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = {
+ { .irq = INT_24XX_UART1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart1_slaves[] = {
+ &omap3_l4_core__uart1,
+};
+
+static struct omap_hwmod omap3xxx_uart1_hwmod = {
+ .name = "uart1",
+ .mpu_irqs = uart1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs),
+ .sdma_reqs = uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart1_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART2 */
+
+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = {
+ { .irq = INT_24XX_UART2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart2_slaves[] = {
+ &omap3_l4_core__uart2,
+};
+
+static struct omap_hwmod omap3xxx_uart2_hwmod = {
+ .name = "uart2",
+ .mpu_irqs = uart2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs),
+ .sdma_reqs = uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart2_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART3 */
+
+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = {
+ { .irq = INT_24XX_UART3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart3_slaves[] = {
+ &omap3_l4_per__uart3,
+};
+
+static struct omap_hwmod omap3xxx_uart3_hwmod = {
+ .name = "uart3",
+ .mpu_irqs = uart3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs),
+ .sdma_reqs = uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_PER_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_UART3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_UART3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart3_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* UART4 */
+
+static struct omap_hwmod_irq_info uart4_mpu_irqs[] = {
+ { .irq = INT_36XX_UART4_IRQ, },
+};
+
+static struct omap_hwmod_dma_info uart4_sdma_reqs[] = {
+ { .name = "rx", .dma_req = OMAP36XX_DMA_UART4_RX, },
+ { .name = "tx", .dma_req = OMAP36XX_DMA_UART4_TX, },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_uart4_slaves[] = {
+ &omap3_l4_per__uart4,
+};
+
+static struct omap_hwmod omap3xxx_uart4_hwmod = {
+ .name = "uart4",
+ .mpu_irqs = uart4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(uart4_mpu_irqs),
+ .sdma_reqs = uart4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(uart4_sdma_reqs),
+ .main_clk = "uart4_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = OMAP3430_PER_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3630_EN_UART4_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3630_EN_UART4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_uart4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart4_slaves),
+ .class = &uart_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap3xxx_dss_sysc,
+};
+
+static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+ { .name = "dsi1", .dma_req = 74 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_masters[] = {
+ &omap3xxx_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3430es1_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap3430es1_dss_slaves[] = {
+ &omap3430es1_l4_core__dss,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
+ &omap3xxx_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_tv_fck" },
+ { .role = "video_clk", .clk = "dss_96m_fck" },
+ { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
+static struct omap_hwmod omap3430es1_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap3xxx_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .sdma_reqs = omap3xxx_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
+
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP3430ES1_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap3430es1_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3430es1_dss_slaves),
+ .masters = omap3xxx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod omap3xxx_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap3xxx_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .sdma_reqs = omap3xxx_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
+
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT,
+ .idlest_stdby_bit = OMAP3430ES2_ST_DSS_STDBY_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap3xxx_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_slaves),
+ .masters = omap3xxx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2 |
+ CHIP_IS_OMAP3630ES1 | CHIP_GE_OMAP3630ES1_1),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap3xxx_dispc_sysc,
+};
+
+static struct omap_hwmod_irq_info omap3xxx_dispc_irqs[] = {
+ { .irq = 25 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
+ &omap3xxx_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap3xxx_dispc_hwmod_class,
+ .mpu_irqs = omap3xxx_dispc_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dispc_irqs),
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dsi' class
+ * display serial interface controller
+ */
+
+static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
+ .name = "dsi",
+};
+
+static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = {
+ { .irq = 25 },
+};
+
+/* dss_dsi1 */
+static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
+ {
+ .pa_start = 0x4804FC00,
+ .pa_end = 0x4804FFFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_dsi1_hwmod,
+ .addr = omap3xxx_dss_dsi1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dsi1 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
+ &omap3xxx_l4_core__dss_dsi1,
+};
+
+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap3xxx_dsi_hwmod_class,
+ .mpu_irqs = omap3xxx_dsi1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dsi1_irqs),
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_dsi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap3xxx_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP ,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = {
+ &omap3xxx_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap3xxx_rfbi_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap3xxx_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap3xxx_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_venc_hwmod,
+ .clk = "dss_tv_fck",
+ .addr = omap3xxx_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_venc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .flags = OCPIF_SWSUP_IDLE,
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = {
+ &omap3xxx_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap3xxx_venc_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/* I2C1 */
+
+static struct omap_i2c_dev_attr i2c1_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C1_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = {
+ &omap3_l4_core__i2c1,
+};
+
+static struct omap_hwmod omap3xxx_i2c1_hwmod = {
+ .name = "i2c1",
+ .mpu_irqs = i2c1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs),
+ .sdma_reqs = i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c1_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c1_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* I2C2 */
+
+static struct omap_i2c_dev_attr i2c2_dev_attr = {
+ .fifo_depth = 8, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = {
+ { .irq = INT_24XX_I2C2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX },
+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = {
+ &omap3_l4_core__i2c2,
+};
+
+static struct omap_hwmod omap3xxx_i2c2_hwmod = {
+ .name = "i2c2",
+ .mpu_irqs = i2c2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs),
+ .sdma_reqs = i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c2_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* I2C3 */
+
+static struct omap_i2c_dev_attr i2c3_dev_attr = {
+ .fifo_depth = 64, /* bytes */
+};
+
+static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = {
+ { .irq = INT_34XX_I2C3_IRQ, },
+};
+
+static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = OMAP34XX_DMA_I2C3_TX },
+ { .name = "rx", .dma_req = OMAP34XX_DMA_I2C3_RX },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = {
+ &omap3_l4_core__i2c3,
+};
+
+static struct omap_hwmod omap3xxx_i2c3_hwmod = {
+ .name = "i2c3",
+ .mpu_irqs = i2c3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(i2c3_mpu_irqs),
+ .sdma_reqs = i2c3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(i2c3_sdma_reqs),
+ .main_clk = "i2c3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_I2C3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_I2C3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_i2c3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c3_slaves),
+ .class = &i2c_class,
+ .dev_attr = &i2c3_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_addr_space omap3xxx_gpio1_addrs[] = {
+ {
+ .pa_start = 0x48310000,
+ .pa_end = 0x483101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__gpio1 = {
+ .master = &omap3xxx_l4_wkup_hwmod,
+ .slave = &omap3xxx_gpio1_hwmod,
+ .addr = omap3xxx_gpio1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_addr_space omap3xxx_gpio2_addrs[] = {
+ {
+ .pa_start = 0x49050000,
+ .pa_end = 0x490501ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio2 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio2_hwmod,
+ .addr = omap3xxx_gpio2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_addr_space omap3xxx_gpio3_addrs[] = {
+ {
+ .pa_start = 0x49052000,
+ .pa_end = 0x490521ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio3_hwmod,
+ .addr = omap3xxx_gpio3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_addr_space omap3xxx_gpio4_addrs[] = {
+ {
+ .pa_start = 0x49054000,
+ .pa_end = 0x490541ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio4_hwmod,
+ .addr = omap3xxx_gpio4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_addr_space omap3xxx_gpio5_addrs[] = {
+ {
+ .pa_start = 0x49056000,
+ .pa_end = 0x490561ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio5 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio5_hwmod,
+ .addr = omap3xxx_gpio5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_addr_space omap3xxx_gpio6_addrs[] = {
+ {
+ .pa_start = 0x49058000,
+ .pa_end = 0x490581ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_gpio6_hwmod,
+ .addr = omap3xxx_gpio6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_gpio6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap3xxx_gpio_sysc,
+ .rev = 1,
+};
+
+/* gpio_dev_attr*/
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod_irq_info omap3xxx_gpio1_irqs[] = {
+ { .irq = 29 }, /* INT_34XX_GPIO_BANK1 */
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = {
+ &omap3xxx_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod omap3xxx_gpio1_hwmod = {
+ .name = "gpio1",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs),
+ .main_clk = "gpio1_ick",
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio1_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio2 */
+static struct omap_hwmod_irq_info omap3xxx_gpio2_irqs[] = {
+ { .irq = 30 }, /* INT_34XX_GPIO_BANK2 */
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = {
+ &omap3xxx_l4_per__gpio2,
+};
+
+static struct omap_hwmod omap3xxx_gpio2_hwmod = {
+ .name = "gpio2",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs),
+ .main_clk = "gpio2_ick",
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO2_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio2_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio3 */
+static struct omap_hwmod_irq_info omap3xxx_gpio3_irqs[] = {
+ { .irq = 31 }, /* INT_34XX_GPIO_BANK3 */
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = {
+ &omap3xxx_l4_per__gpio3,
+};
+
+static struct omap_hwmod omap3xxx_gpio3_hwmod = {
+ .name = "gpio3",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs),
+ .main_clk = "gpio3_ick",
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO3_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio3_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio4 */
+static struct omap_hwmod_irq_info omap3xxx_gpio4_irqs[] = {
+ { .irq = 32 }, /* INT_34XX_GPIO_BANK4 */
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = {
+ &omap3xxx_l4_per__gpio4,
+};
+
+static struct omap_hwmod omap3xxx_gpio4_hwmod = {
+ .name = "gpio4",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs),
+ .main_clk = "gpio4_ick",
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO4_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio4_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio5 */
+static struct omap_hwmod_irq_info omap3xxx_gpio5_irqs[] = {
+ { .irq = 33 }, /* INT_34XX_GPIO_BANK5 */
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = {
+ &omap3xxx_l4_per__gpio5,
+};
+
+static struct omap_hwmod omap3xxx_gpio5_hwmod = {
+ .name = "gpio5",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs),
+ .main_clk = "gpio5_ick",
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO5_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO5_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio5_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* gpio6 */
+static struct omap_hwmod_irq_info omap3xxx_gpio6_irqs[] = {
+ { .irq = 34 }, /* INT_34XX_GPIO_BANK6 */
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = {
+ &omap3xxx_l4_per__gpio6,
+};
+
+static struct omap_hwmod omap3xxx_gpio6_hwmod = {
+ .name = "gpio6",
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap3xxx_gpio6_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs),
+ .main_clk = "gpio6_ick",
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_GPIO6_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_GPIO6_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_gpio6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_gpio6_slaves),
+ .class = &omap3xxx_gpio_hwmod_class,
+ .dev_attr = &gpio_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* dma_system -> L3 */
+static struct omap_hwmod_ocp_if omap3xxx_dma_system__l3 = {
+ .master = &omap3xxx_dma_system_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .clk = "core_l3_ick",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma attributes */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap3xxx_dma_sysc,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */
+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */
+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */
+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x48056000,
+ .pa_end = 0x48056fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_masters[] = {
+ &omap3xxx_dma_system__l3,
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dma_system_hwmod,
+ .clk = "core_l4_ick",
+ .addr = omap3xxx_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dma_system_slaves[] = {
+ &omap3xxx_l4_core__dma_system,
+};
+
+static struct omap_hwmod omap3xxx_dma_system_hwmod = {
+ .name = "dma",
+ .class = &omap3xxx_dma_hwmod_class,
+ .mpu_irqs = omap3xxx_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dma_system_irqs),
+ .main_clk = "core_l3_ick",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_ST_SDMA_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_SDMA_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dma_system_slaves),
+ .masters = omap3xxx_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dma_system_masters),
+ .dev_attr = &dma_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = {
+ .sysc_offs = 0x008c,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+ .clockact = 0x2,
+};
+
+static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+ .sysc = &omap3xxx_mcbsp_sysc,
+ .rev = MCBSP_CONFIG_TYPE3,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = {
+ { .name = "irq", .irq = 16 },
+ { .name = "tx", .irq = 59 },
+ { .name = "rx", .irq = 60 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp1_sdma_chs[] = {
+ { .name = "rx", .dma_req = 32 },
+ { .name = "tx", .dma_req = 31 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp1_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48074000,
+ .pa_end = 0x480740ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mcbsp1_hwmod,
+ .clk = "mcbsp1_ick",
+ .addr = omap3xxx_mcbsp1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp1_slaves[] = {
+ &omap3xxx_l4_core__mcbsp1,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_irqs),
+ .sdma_reqs = omap3xxx_mcbsp1_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_sdma_chs),
+ .main_clk = "mcbsp1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = {
+ { .name = "irq", .irq = 17 },
+ { .name = "tx", .irq = 62 },
+ { .name = "rx", .irq = 63 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp2_sdma_chs[] = {
+ { .name = "rx", .dma_req = 34 },
+ { .name = "tx", .dma_req = 33 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x49022000,
+ .pa_end = 0x490220ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_mcbsp2_hwmod,
+ .clk = "mcbsp2_ick",
+ .addr = omap3xxx_mcbsp2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_slaves[] = {
+ &omap3xxx_l4_per__mcbsp2,
+};
+
+static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = {
+ .sidetone = "mcbsp2_sidetone",
+};
+
+static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_irqs),
+ .sdma_reqs = omap3xxx_mcbsp2_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sdma_chs),
+ .main_clk = "mcbsp2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP2_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_slaves),
+ .dev_attr = &omap34xx_mcbsp2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = {
+ { .name = "irq", .irq = 22 },
+ { .name = "tx", .irq = 89 },
+ { .name = "rx", .irq = 90 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp3_sdma_chs[] = {
+ { .name = "rx", .dma_req = 18 },
+ { .name = "tx", .dma_req = 17 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x49024000,
+ .pa_end = 0x490240ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_mcbsp3_hwmod,
+ .clk = "mcbsp3_ick",
+ .addr = omap3xxx_mcbsp3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_slaves[] = {
+ &omap3xxx_l4_per__mcbsp3,
+};
+
+static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = {
+ .sidetone = "mcbsp3_sidetone",
+};
+
+static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_irqs),
+ .sdma_reqs = omap3xxx_mcbsp3_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sdma_chs),
+ .main_clk = "mcbsp3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP3_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_slaves),
+ .dev_attr = &omap34xx_mcbsp3_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = {
+ { .name = "irq", .irq = 23 },
+ { .name = "tx", .irq = 54 },
+ { .name = "rx", .irq = 55 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = {
+ { .name = "rx", .dma_req = 20 },
+ { .name = "tx", .dma_req = 19 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp4_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x49026000,
+ .pa_end = 0x490260ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp4 = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_mcbsp4_hwmod,
+ .clk = "mcbsp4_ick",
+ .addr = omap3xxx_mcbsp4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp4_slaves[] = {
+ &omap3xxx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_irqs),
+ .sdma_reqs = omap3xxx_mcbsp4_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_sdma_chs),
+ .main_clk = "mcbsp4_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP4_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp5 */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = {
+ { .name = "irq", .irq = 27 },
+ { .name = "tx", .irq = 81 },
+ { .name = "rx", .irq = 82 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = {
+ { .name = "rx", .dma_req = 22 },
+ { .name = "tx", .dma_req = 21 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp5_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x48096000,
+ .pa_end = 0x480960ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> mcbsp5 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp5 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mcbsp5_hwmod,
+ .clk = "mcbsp5_ick",
+ .addr = omap3xxx_mcbsp5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp5 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp5_slaves[] = {
+ &omap3xxx_l4_core__mcbsp5,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
+ .name = "mcbsp5",
+ .class = &omap3xxx_mcbsp_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_irqs),
+ .sdma_reqs = omap3xxx_mcbsp5_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_sdma_chs),
+ .main_clk = "mcbsp5_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP5_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+/* 'mcbsp sidetone' class */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = {
+ .sysc_offs = 0x0010,
+ .sysc_flags = SYSC_HAS_AUTOIDLE,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = {
+ .name = "mcbsp_sidetone",
+ .sysc = &omap3xxx_mcbsp_sidetone_sysc,
+};
+
+/* mcbsp2_sidetone */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_sidetone_irqs[] = {
+ { .name = "irq", .irq = 4 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_sidetone_addrs[] = {
+ {
+ .name = "sidetone",
+ .pa_start = 0x49028000,
+ .pa_end = 0x490280ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp2_sidetone */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2_sidetone = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_mcbsp2_sidetone_hwmod,
+ .clk = "mcbsp2_ick",
+ .addr = omap3xxx_mcbsp2_sidetone_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* mcbsp2_sidetone slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_sidetone_slaves[] = {
+ &omap3xxx_l4_per__mcbsp2_sidetone,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
+ .name = "mcbsp2_sidetone",
+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_irqs),
+ .main_clk = "mcbsp2_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP2_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp2_sidetone_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcbsp3_sidetone */
+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = {
+ { .name = "irq", .irq = 5 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_sidetone_addrs[] = {
+ {
+ .name = "sidetone",
+ .pa_start = 0x4902A000,
+ .pa_end = 0x4902A0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp3_sidetone */
+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = {
+ .master = &omap3xxx_l4_per_hwmod,
+ .slave = &omap3xxx_mcbsp3_sidetone_hwmod,
+ .clk = "mcbsp3_ick",
+ .addr = omap3xxx_mcbsp3_sidetone_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* mcbsp3_sidetone slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_sidetone_slaves[] = {
+ &omap3xxx_l4_per__mcbsp3_sidetone,
+};
+
+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
+ .name = "mcbsp3_sidetone",
+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class,
+ .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_irqs),
+ .main_clk = "mcbsp3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCBSP3_SHIFT,
+ .module_offs = OMAP3430_PER_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mcbsp3_sidetone_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+
+/* SR common */
+static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = {
+ .clkact_shift = 20,
+};
+
+static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
+ .sysc_offs = 0x24,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
+ .clockact = CLOCKACT_TEST_ICLK,
+ .sysc_fields = &omap34xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap34xx_sr_sysc,
+ .rev = 1,
+};
+
+static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = {
+ .sidle_shift = 24,
+ .enwkup_shift = 26
+};
+
+static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
+ .sysc_offs = 0x38,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_NO_CACHE),
+ .sysc_fields = &omap36xx_sr_sysc_fields,
+};
+
+static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap36xx_sr_sysc,
+ .rev = 2,
+};
+
+/* SR1 */
+static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
+ &omap3_l4_core__sr1,
+};
+
+static struct omap_hwmod omap34xx_sr1_hwmod = {
+ .name = "sr1_hwmod",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
+ },
+ },
+ .slaves = omap3_sr1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0 |
+ CHIP_IS_OMAP3430ES3_1),
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr1_hwmod = {
+ .name = "sr1_hwmod",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr1_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR1_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
+ },
+ },
+ .slaves = omap3_sr1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
+/* SR2 */
+static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
+ &omap3_l4_core__sr2,
+};
+
+static struct omap_hwmod omap34xx_sr2_hwmod = {
+ .name = "sr2_hwmod",
+ .class = &omap34xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
+ },
+ },
+ .slaves = omap3_sr2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0 |
+ CHIP_IS_OMAP3430ES3_1),
+ .flags = HWMOD_SET_DEFAULT_CLOCKACT,
+};
+
+static struct omap_hwmod omap36xx_sr2_hwmod = {
+ .name = "sr2_hwmod",
+ .class = &omap36xx_smartreflex_hwmod_class,
+ .main_clk = "sr2_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_SR2_SHIFT,
+ .module_offs = WKUP_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
+ },
+ },
+ .slaves = omap3_sr2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors
+ * using a queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_mailbox_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap3xxx_mailbox_sysc,
+};
+
+static struct omap_hwmod omap3xxx_mailbox_hwmod;
+static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = {
+ { .irq = 26 },
+};
+
+static struct omap_hwmod_addr_space omap3xxx_mailbox_addrs[] = {
+ {
+ .pa_start = 0x48094000,
+ .pa_end = 0x480941ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* l4_core -> mailbox */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mailbox = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_mailbox_hwmod,
+ .addr = omap3xxx_mailbox_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_mailbox_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mailbox slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_mailbox_slaves[] = {
+ &omap3xxx_l4_core__mailbox,
+};
+
+static struct omap_hwmod omap3xxx_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap3xxx_mailbox_hwmod_class,
+ .mpu_irqs = omap3xxx_mailbox_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mailbox_irqs),
+ .main_clk = "mailboxes_ick",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MAILBOXES_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mailbox_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mailbox_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* l4 core -> mcspi1 interface */
+static struct omap_hwmod_addr_space omap34xx_mcspi1_addr_space[] = {
+ {
+ .pa_start = 0x48098000,
+ .pa_end = 0x480980ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi1,
+ .clk = "mcspi1_ick",
+ .addr = omap34xx_mcspi1_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi1_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi2 interface */
+static struct omap_hwmod_addr_space omap34xx_mcspi2_addr_space[] = {
+ {
+ .pa_start = 0x4809a000,
+ .pa_end = 0x4809a0ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi2,
+ .clk = "mcspi2_ick",
+ .addr = omap34xx_mcspi2_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi2_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi3 interface */
+static struct omap_hwmod_addr_space omap34xx_mcspi3_addr_space[] = {
+ {
+ .pa_start = 0x480b8000,
+ .pa_end = 0x480b80ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi3,
+ .clk = "mcspi3_ick",
+ .addr = omap34xx_mcspi3_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi3_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4 core -> mcspi4 interface */
+static struct omap_hwmod_addr_space omap34xx_mcspi4_addr_space[] = {
+ {
+ .pa_start = 0x480ba000,
+ .pa_end = 0x480ba0ff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi4 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap34xx_mcspi4,
+ .clk = "mcspi4_ick",
+ .addr = omap34xx_mcspi4_addr_space,
+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi4_addr_space),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &omap34xx_mcspi_sysc,
+ .rev = OMAP3_MCSPI_REV,
+};
+
+/* mcspi1 */
+static struct omap_hwmod_irq_info omap34xx_mcspi1_mpu_irqs[] = {
+ { .name = "irq", .irq = 65 },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mcspi1_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 35 },
+ { .name = "rx0", .dma_req = 36 },
+ { .name = "tx1", .dma_req = 37 },
+ { .name = "rx1", .dma_req = 38 },
+ { .name = "tx2", .dma_req = 39 },
+ { .name = "rx2", .dma_req = 40 },
+ { .name = "tx3", .dma_req = 41 },
+ { .name = "rx3", .dma_req = 42 },
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_mcspi1_slaves[] = {
+ &omap34xx_l4_core__mcspi1,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap34xx_mcspi1 = {
+ .name = "mcspi1",
+ .mpu_irqs = omap34xx_mcspi1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_mpu_irqs),
+ .sdma_reqs = omap34xx_mcspi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_sdma_reqs),
+ .main_clk = "mcspi1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCSPI1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCSPI1_SHIFT,
+ },
+ },
+ .slaves = omap34xx_mcspi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi1_slaves),
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi1_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcspi2 */
+static struct omap_hwmod_irq_info omap34xx_mcspi2_mpu_irqs[] = {
+ { .name = "irq", .irq = 66 },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mcspi2_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 43 },
+ { .name = "rx0", .dma_req = 44 },
+ { .name = "tx1", .dma_req = 45 },
+ { .name = "rx1", .dma_req = 46 },
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_mcspi2_slaves[] = {
+ &omap34xx_l4_core__mcspi2,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap34xx_mcspi2 = {
+ .name = "mcspi2",
+ .mpu_irqs = omap34xx_mcspi2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_mpu_irqs),
+ .sdma_reqs = omap34xx_mcspi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_sdma_reqs),
+ .main_clk = "mcspi2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCSPI2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCSPI2_SHIFT,
+ },
+ },
+ .slaves = omap34xx_mcspi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi2_slaves),
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi2_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* mcspi3 */
+static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = {
+ { .name = "irq", .irq = 91 }, /* 91 */
+};
+
+static struct omap_hwmod_dma_info omap34xx_mcspi3_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 15 },
+ { .name = "rx0", .dma_req = 16 },
+ { .name = "tx1", .dma_req = 23 },
+ { .name = "rx1", .dma_req = 24 },
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_mcspi3_slaves[] = {
+ &omap34xx_l4_core__mcspi3,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap34xx_mcspi3 = {
+ .name = "mcspi3",
+ .mpu_irqs = omap34xx_mcspi3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_mpu_irqs),
+ .sdma_reqs = omap34xx_mcspi3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_sdma_reqs),
+ .main_clk = "mcspi3_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCSPI3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCSPI3_SHIFT,
+ },
+ },
+ .slaves = omap34xx_mcspi3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi3_slaves),
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi3_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* SPI4 */
+static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = {
+ { .name = "irq", .irq = INT_34XX_SPI4_IRQ }, /* 48 */
+};
+
+static struct omap_hwmod_dma_info omap34xx_mcspi4_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 70 }, /* DMA_SPI4_TX0 */
+ { .name = "rx0", .dma_req = 71 }, /* DMA_SPI4_RX0 */
+};
+
+static struct omap_hwmod_ocp_if *omap34xx_mcspi4_slaves[] = {
+ &omap34xx_l4_core__mcspi4,
+};
+
+static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = {
+ .num_chipselect = 1,
+};
+
+static struct omap_hwmod omap34xx_mcspi4 = {
+ .name = "mcspi4",
+ .mpu_irqs = omap34xx_mcspi4_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_mpu_irqs),
+ .sdma_reqs = omap34xx_mcspi4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_sdma_reqs),
+ .main_clk = "mcspi4_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MCSPI4_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MCSPI4_SHIFT,
+ },
+ },
+ .slaves = omap34xx_mcspi4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi4_slaves),
+ .class = &omap34xx_mcspi_class,
+ .dev_attr = &omap_mcspi4_dev_attr,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/*
+ * usbhsotg
+ */
+static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = {
+ .rev_offs = 0x0400,
+ .sysc_offs = 0x0404,
+ .syss_offs = 0x0408,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE|
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class usbotg_class = {
+ .name = "usbotg",
+ .sysc = &omap3xxx_usbhsotg_sysc,
+};
+/* usb_otg_hs */
+static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = {
+
+ { .name = "mc", .irq = 92 },
+ { .name = "dma", .irq = 93 },
+};
+
+static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
+ .name = "usb_otg_hs",
+ .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_mpu_irqs),
+ .main_clk = "hsotgusb_ick",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT,
+ .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT
+ },
+ },
+ .masters = omap3xxx_usbhsotg_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_masters),
+ .slaves = omap3xxx_usbhsotg_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_slaves),
+ .class = &usbotg_class,
+
+ /*
+ * Erratum ID: i479 idle_req / idle_ack mechanism potentially
+ * broken when autoidle is enabled
+ * workaround is to disable the autoidle bit at module level.
+ */
+ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
+ | HWMOD_SWSUP_MSTANDBY,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
+/* usb_otg_hs */
+static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = {
+
+ { .name = "mc", .irq = 71 },
+};
+
+static struct omap_hwmod_class am35xx_usbotg_class = {
+ .name = "am35xx_usbotg",
+ .sysc = NULL,
+};
+
+static struct omap_hwmod am35xx_usbhsotg_hwmod = {
+ .name = "am35x_otg_hs",
+ .mpu_irqs = am35xx_usbhsotg_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(am35xx_usbhsotg_mpu_irqs),
+ .main_clk = NULL,
+ .prcm = {
+ .omap2 = {
+ },
+ },
+ .masters = am35xx_usbhsotg_masters,
+ .masters_cnt = ARRAY_SIZE(am35xx_usbhsotg_masters),
+ .slaves = am35xx_usbhsotg_slaves,
+ .slaves_cnt = ARRAY_SIZE(am35xx_usbhsotg_slaves),
+ .class = &am35xx_usbotg_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1)
+};
+
+/* MMC/SD/SDIO common */
+
+static struct omap_hwmod_class_sysconfig omap34xx_mmc_sysc = {
+ .rev_offs = 0x1fc,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap34xx_mmc_class = {
+ .name = "mmc",
+ .sysc = &omap34xx_mmc_sysc,
+};
+
+/* MMC/SD/SDIO1 */
+
+static struct omap_hwmod_irq_info omap34xx_mmc1_mpu_irqs[] = {
+ { .irq = 83, },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 61, },
+ { .name = "rx", .dma_req = 62, },
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_mmc1_slaves[] = {
+ &omap3xxx_l4_core__mmc1,
+};
+
+static struct omap_mmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod omap3xxx_mmc1_hwmod = {
+ .name = "mmc1",
+ .mpu_irqs = omap34xx_mmc1_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc1_mpu_irqs),
+ .sdma_reqs = omap34xx_mmc1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc1_sdma_reqs),
+ .opt_clks = omap34xx_mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks),
+ .main_clk = "mmchs1_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MMC1_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .slaves = omap3xxx_mmc1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves),
+ .class = &omap34xx_mmc_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* MMC/SD/SDIO2 */
+
+static struct omap_hwmod_irq_info omap34xx_mmc2_mpu_irqs[] = {
+ { .irq = INT_24XX_MMC2_IRQ, },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 47, },
+ { .name = "rx", .dma_req = 48, },
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_mmc2_slaves[] = {
+ &omap3xxx_l4_core__mmc2,
+};
+
+static struct omap_hwmod omap3xxx_mmc2_hwmod = {
+ .name = "mmc2",
+ .mpu_irqs = omap34xx_mmc2_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc2_mpu_irqs),
+ .sdma_reqs = omap34xx_mmc2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc2_sdma_reqs),
+ .opt_clks = omap34xx_mmc2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks),
+ .main_clk = "mmchs2_fck",
+ .prcm = {
+ .omap2 = {
+ .module_offs = CORE_MOD,
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MMC2_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mmc2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves),
+ .class = &omap34xx_mmc_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+/* MMC/SD/SDIO3 */
+
+static struct omap_hwmod_irq_info omap34xx_mmc3_mpu_irqs[] = {
+ { .irq = 94, },
+};
+
+static struct omap_hwmod_dma_info omap34xx_mmc3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 77, },
+ { .name = "rx", .dma_req = 78, },
+};
+
+static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = {
+ { .role = "dbck", .clk = "omap_32k_fck", },
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_mmc3_slaves[] = {
+ &omap3xxx_l4_core__mmc3,
+};
+
+static struct omap_hwmod omap3xxx_mmc3_hwmod = {
+ .name = "mmc3",
+ .mpu_irqs = omap34xx_mmc3_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc3_mpu_irqs),
+ .sdma_reqs = omap34xx_mmc3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc3_sdma_reqs),
+ .opt_clks = omap34xx_mmc3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc3_opt_clks),
+ .main_clk = "mmchs3_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_MMC3_SHIFT,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430_ST_MMC3_SHIFT,
+ },
+ },
+ .slaves = omap3xxx_mmc3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc3_slaves),
+ .class = &omap34xx_mmc_class,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
+ &omap3xxx_l3_main_hwmod,
+ &omap3xxx_l4_core_hwmod,
+ &omap3xxx_l4_per_hwmod,
+ &omap3xxx_l4_wkup_hwmod,
+ &omap3xxx_mmc1_hwmod,
+ &omap3xxx_mmc2_hwmod,
+ &omap3xxx_mmc3_hwmod,
+ &omap3xxx_mpu_hwmod,
+ &omap3xxx_iva_hwmod,
+
+ &omap3xxx_timer1_hwmod,
+ &omap3xxx_timer2_hwmod,
+ &omap3xxx_timer3_hwmod,
+ &omap3xxx_timer4_hwmod,
+ &omap3xxx_timer5_hwmod,
+ &omap3xxx_timer6_hwmod,
+ &omap3xxx_timer7_hwmod,
+ &omap3xxx_timer8_hwmod,
+ &omap3xxx_timer9_hwmod,
+ &omap3xxx_timer10_hwmod,
+ &omap3xxx_timer11_hwmod,
+ &omap3xxx_timer12_hwmod,
+
+ &omap3xxx_wd_timer2_hwmod,
+ &omap3xxx_uart1_hwmod,
+ &omap3xxx_uart2_hwmod,
+ &omap3xxx_uart3_hwmod,
+ &omap3xxx_uart4_hwmod,
+ /* dss class */
+ &omap3430es1_dss_core_hwmod,
+ &omap3xxx_dss_core_hwmod,
+ &omap3xxx_dss_dispc_hwmod,
+ &omap3xxx_dss_dsi1_hwmod,
+ &omap3xxx_dss_rfbi_hwmod,
+ &omap3xxx_dss_venc_hwmod,
+
+ /* i2c class */
+ &omap3xxx_i2c1_hwmod,
+ &omap3xxx_i2c2_hwmod,
+ &omap3xxx_i2c3_hwmod,
+ &omap34xx_sr1_hwmod,
+ &omap34xx_sr2_hwmod,
+ &omap36xx_sr1_hwmod,
+ &omap36xx_sr2_hwmod,
+
+
+ /* gpio class */
+ &omap3xxx_gpio1_hwmod,
+ &omap3xxx_gpio2_hwmod,
+ &omap3xxx_gpio3_hwmod,
+ &omap3xxx_gpio4_hwmod,
+ &omap3xxx_gpio5_hwmod,
+ &omap3xxx_gpio6_hwmod,
+
+ /* dma_system class*/
+ &omap3xxx_dma_system_hwmod,
+
+ /* mcbsp class */
+ &omap3xxx_mcbsp1_hwmod,
+ &omap3xxx_mcbsp2_hwmod,
+ &omap3xxx_mcbsp3_hwmod,
+ &omap3xxx_mcbsp4_hwmod,
+ &omap3xxx_mcbsp5_hwmod,
+ &omap3xxx_mcbsp2_sidetone_hwmod,
+ &omap3xxx_mcbsp3_sidetone_hwmod,
+
+ /* mailbox class */
+ &omap3xxx_mailbox_hwmod,
+
+ /* mcspi class */
+ &omap34xx_mcspi1,
+ &omap34xx_mcspi2,
+ &omap34xx_mcspi3,
+ &omap34xx_mcspi4,
+
+ /* usbotg class */
+ &omap3xxx_usbhsotg_hwmod,
+
+ /* usbotg for am35x */
+ &am35xx_usbhsotg_hwmod,
+
+ NULL,
+};
+
+int __init omap3xxx_hwmod_init(void)
+{
+ return omap_hwmod_register(omap3xxx_hwmods);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
new file mode 100644
index 00000000..e1c69ffe
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -0,0 +1,5183 @@
+/*
+ * Hardware modules present on the OMAP44xx chips
+ *
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ * Benoit Cousson
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+
+#include <plat/omap_hwmod.h>
+#include <plat/cpu.h>
+#include <plat/gpio.h>
+#include <plat/dma.h>
+#include <plat/mcspi.h>
+#include <plat/mcbsp.h>
+#include <plat/mmc.h>
+
+#include "omap_hwmod_common_data.h"
+
+#include "cm1_44xx.h"
+#include "cm2_44xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "wd_timer.h"
+
+/* Base offset for all OMAP4 interrupts external to MPUSS */
+#define OMAP44XX_IRQ_GIC_START 32
+
+/* Base offset for all OMAP4 dma requests */
+#define OMAP44XX_DMA_REQ_START 1
+
+/* Backward references (IPs with Bus Master capability) */
+static struct omap_hwmod omap44xx_aess_hwmod;
+static struct omap_hwmod omap44xx_dma_system_hwmod;
+static struct omap_hwmod omap44xx_dmm_hwmod;
+static struct omap_hwmod omap44xx_dsp_hwmod;
+static struct omap_hwmod omap44xx_dss_hwmod;
+static struct omap_hwmod omap44xx_emif_fw_hwmod;
+static struct omap_hwmod omap44xx_hsi_hwmod;
+static struct omap_hwmod omap44xx_ipu_hwmod;
+static struct omap_hwmod omap44xx_iss_hwmod;
+static struct omap_hwmod omap44xx_iva_hwmod;
+static struct omap_hwmod omap44xx_l3_instr_hwmod;
+static struct omap_hwmod omap44xx_l3_main_1_hwmod;
+static struct omap_hwmod omap44xx_l3_main_2_hwmod;
+static struct omap_hwmod omap44xx_l3_main_3_hwmod;
+static struct omap_hwmod omap44xx_l4_abe_hwmod;
+static struct omap_hwmod omap44xx_l4_cfg_hwmod;
+static struct omap_hwmod omap44xx_l4_per_hwmod;
+static struct omap_hwmod omap44xx_l4_wkup_hwmod;
+static struct omap_hwmod omap44xx_mmc1_hwmod;
+static struct omap_hwmod omap44xx_mmc2_hwmod;
+static struct omap_hwmod omap44xx_mpu_hwmod;
+static struct omap_hwmod omap44xx_mpu_private_hwmod;
+static struct omap_hwmod omap44xx_usb_otg_hs_hwmod;
+
+/*
+ * Interconnects omap_hwmod structures
+ * hwmods that compose the global OMAP interconnect
+ */
+
+/*
+ * 'dmm' class
+ * instance(s): dmm
+ */
+static struct omap_hwmod_class omap44xx_dmm_hwmod_class = {
+ .name = "dmm",
+};
+
+/* dmm interface data */
+/* l3_main_1 -> dmm */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_dmm_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dmm_addrs[] = {
+ {
+ .pa_start = 0x4e000000,
+ .pa_end = 0x4e0007ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* mpu -> dmm */
+static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_dmm_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dmm_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dmm_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dmm slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dmm_slaves[] = {
+ &omap44xx_l3_main_1__dmm,
+ &omap44xx_mpu__dmm,
+};
+
+static struct omap_hwmod_irq_info omap44xx_dmm_irqs[] = {
+ { .irq = 113 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod omap44xx_dmm_hwmod = {
+ .name = "dmm",
+ .class = &omap44xx_dmm_hwmod_class,
+ .slaves = omap44xx_dmm_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
+ .mpu_irqs = omap44xx_dmm_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmm_irqs),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'emif_fw' class
+ * instance(s): emif_fw
+ */
+static struct omap_hwmod_class omap44xx_emif_fw_hwmod_class = {
+ .name = "emif_fw",
+};
+
+/* emif_fw interface data */
+/* dmm -> emif_fw */
+static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = {
+ .master = &omap44xx_dmm_hwmod,
+ .slave = &omap44xx_emif_fw_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_emif_fw_addrs[] = {
+ {
+ .pa_start = 0x4a20c000,
+ .pa_end = 0x4a20c0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> emif_fw */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__emif_fw = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_emif_fw_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_emif_fw_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_emif_fw_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* emif_fw slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_emif_fw_slaves[] = {
+ &omap44xx_dmm__emif_fw,
+ &omap44xx_l4_cfg__emif_fw,
+};
+
+static struct omap_hwmod omap44xx_emif_fw_hwmod = {
+ .name = "emif_fw",
+ .class = &omap44xx_emif_fw_hwmod_class,
+ .slaves = omap44xx_emif_fw_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'l3' class
+ * instance(s): l3_instr, l3_main_1, l3_main_2, l3_main_3
+ */
+static struct omap_hwmod_class omap44xx_l3_hwmod_class = {
+ .name = "l3",
+};
+
+/* l3_instr interface data */
+/* iva -> l3_instr */
+static struct omap_hwmod_ocp_if omap44xx_iva__l3_instr = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_l3_instr_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_3 -> l3_instr */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = {
+ .master = &omap44xx_l3_main_3_hwmod,
+ .slave = &omap44xx_l3_instr_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_instr slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_instr_slaves[] = {
+ &omap44xx_iva__l3_instr,
+ &omap44xx_l3_main_3__l3_instr,
+};
+
+static struct omap_hwmod omap44xx_l3_instr_hwmod = {
+ .name = "l3_instr",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_instr_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_1 interface data */
+/* dsp -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = {
+ .master = &omap44xx_dss_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_1 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc1 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_mmc1__l3_main_1 = {
+ .master = &omap44xx_mmc1_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc2 -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_mmc2__l3_main_1 = {
+ .master = &omap44xx_mmc2_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* L3 target configuration and error log registers */
+static struct omap_hwmod_irq_info omap44xx_l3_targ_irqs[] = {
+ { .irq = 9 + OMAP44XX_IRQ_GIC_START },
+ { .irq = 10 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_l3_main_1_addrs[] = {
+ {
+ .pa_start = 0x44000000,
+ .pa_end = 0x44000fff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* mpu -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_l3_main_1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_l3_main_1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
+ &omap44xx_dsp__l3_main_1,
+ &omap44xx_dss__l3_main_1,
+ &omap44xx_l3_main_2__l3_main_1,
+ &omap44xx_l4_cfg__l3_main_1,
+ &omap44xx_mmc1__l3_main_1,
+ &omap44xx_mmc2__l3_main_1,
+ &omap44xx_mpu__l3_main_1,
+};
+
+static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
+ .name = "l3_main_1",
+ .class = &omap44xx_l3_hwmod_class,
+ .mpu_irqs = omap44xx_l3_targ_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_l3_targ_irqs),
+ .slaves = omap44xx_l3_main_1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_2 interface data */
+/* dma_system -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
+ .master = &omap44xx_dma_system_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* hsi -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = {
+ .master = &omap44xx_hsi_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* ipu -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_ipu__l3_main_2 = {
+ .master = &omap44xx_ipu_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iss -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = {
+ .master = &omap44xx_iss_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iva -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = {
+ .master = &omap44xx_iva_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_l3_main_2_addrs[] = {
+ {
+ .pa_start = 0x44800000,
+ .pa_end = 0x44801fff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* l3_main_1 -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_2 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_l3_main_2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_l3_main_2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* usb_otg_hs -> l3_main_2 */
+static struct omap_hwmod_ocp_if omap44xx_usb_otg_hs__l3_main_2 = {
+ .master = &omap44xx_usb_otg_hs_hwmod,
+ .slave = &omap44xx_l3_main_2_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = {
+ &omap44xx_dma_system__l3_main_2,
+ &omap44xx_hsi__l3_main_2,
+ &omap44xx_ipu__l3_main_2,
+ &omap44xx_iss__l3_main_2,
+ &omap44xx_iva__l3_main_2,
+ &omap44xx_l3_main_1__l3_main_2,
+ &omap44xx_l4_cfg__l3_main_2,
+ &omap44xx_usb_otg_hs__l3_main_2,
+};
+
+static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
+ .name = "l3_main_2",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_main_2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l3_main_3 interface data */
+static struct omap_hwmod_addr_space omap44xx_l3_main_3_addrs[] = {
+ {
+ .pa_start = 0x45000000,
+ .pa_end = 0x45000fff,
+ .flags = ADDR_TYPE_RT,
+ },
+};
+
+/* l3_main_1 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l3_main_3 = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_l3_main_3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_l3_main_3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_2 -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_3 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg -> l3_main_3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l3_main_3_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l3_main_3_slaves[] = {
+ &omap44xx_l3_main_1__l3_main_3,
+ &omap44xx_l3_main_2__l3_main_3,
+ &omap44xx_l4_cfg__l3_main_3,
+};
+
+static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
+ .name = "l3_main_3",
+ .class = &omap44xx_l3_hwmod_class,
+ .slaves = omap44xx_l3_main_3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'l4' class
+ * instance(s): l4_abe, l4_cfg, l4_per, l4_wkup
+ */
+static struct omap_hwmod_class omap44xx_l4_hwmod_class = {
+ .name = "l4",
+};
+
+/* l4_abe interface data */
+/* aess -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_aess__l4_abe = {
+ .master = &omap44xx_aess_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "ocp_abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dsp -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "ocp_abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l3_main_1 -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_abe = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu -> l4_abe */
+static struct omap_hwmod_ocp_if omap44xx_mpu__l4_abe = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_l4_abe_hwmod,
+ .clk = "ocp_abe_iclk",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_abe slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = {
+ &omap44xx_aess__l4_abe,
+ &omap44xx_dsp__l4_abe,
+ &omap44xx_l3_main_1__l4_abe,
+ &omap44xx_mpu__l4_abe,
+};
+
+static struct omap_hwmod omap44xx_l4_abe_hwmod = {
+ .name = "l4_abe",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_abe_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_cfg interface data */
+/* l3_main_1 -> l4_cfg */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_1__l4_cfg = {
+ .master = &omap44xx_l3_main_1_hwmod,
+ .slave = &omap44xx_l4_cfg_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_cfg slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_cfg_slaves[] = {
+ &omap44xx_l3_main_1__l4_cfg,
+};
+
+static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
+ .name = "l4_cfg",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_cfg_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_per interface data */
+/* l3_main_2 -> l4_per */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l4_per = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_l4_per_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_per slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_per_slaves[] = {
+ &omap44xx_l3_main_2__l4_per,
+};
+
+static struct omap_hwmod omap44xx_l4_per_hwmod = {
+ .name = "l4_per",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_per_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* l4_wkup interface data */
+/* l4_cfg -> l4_wkup */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l4_wkup = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_l4_wkup_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* l4_wkup slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_l4_wkup_slaves[] = {
+ &omap44xx_l4_cfg__l4_wkup,
+};
+
+static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
+ .name = "l4_wkup",
+ .class = &omap44xx_l4_hwmod_class,
+ .slaves = omap44xx_l4_wkup_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mpu_bus' class
+ * instance(s): mpu_private
+ */
+static struct omap_hwmod_class omap44xx_mpu_bus_hwmod_class = {
+ .name = "mpu_bus",
+};
+
+/* mpu_private interface data */
+/* mpu -> mpu_private */
+static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = {
+ .master = &omap44xx_mpu_hwmod,
+ .slave = &omap44xx_mpu_private_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mpu_private slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mpu_private_slaves[] = {
+ &omap44xx_mpu__mpu_private,
+};
+
+static struct omap_hwmod omap44xx_mpu_private_hwmod = {
+ .name = "mpu_private",
+ .class = &omap44xx_mpu_bus_hwmod_class,
+ .slaves = omap44xx_mpu_private_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * Modules omap_hwmod structures
+ *
+ * The following IPs are excluded for the moment because:
+ * - They do not need an explicit SW control using omap_hwmod API.
+ * - They still need to be validated with the driver
+ * properly adapted to omap_hwmod / omap_device
+ *
+ * c2c
+ * c2c_target_fw
+ * cm_core
+ * cm_core_aon
+ * ctrl_module_core
+ * ctrl_module_pad_core
+ * ctrl_module_pad_wkup
+ * ctrl_module_wkup
+ * debugss
+ * efuse_ctrl_cust
+ * efuse_ctrl_std
+ * elm
+ * emif1
+ * emif2
+ * fdif
+ * gpmc
+ * gpu
+ * hdq1w
+ * hsi
+ * ocmc_ram
+ * ocp2scp_usb_phy
+ * ocp_wp_noc
+ * prcm_mpu
+ * prm
+ * scrm
+ * sl2if
+ * slimbus1
+ * slimbus2
+ * usb_host_fs
+ * usb_host_hs
+ * usb_phy_cm
+ * usb_tll_hs
+ * usim
+ */
+
+/*
+ * 'aess' class
+ * audio engine sub system
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
+ .name = "aess",
+ .sysc = &omap44xx_aess_sysc,
+};
+
+/* aess */
+static struct omap_hwmod_irq_info omap44xx_aess_irqs[] = {
+ { .irq = 99 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_aess_sdma_reqs[] = {
+ { .name = "fifo0", .dma_req = 100 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo1", .dma_req = 101 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo2", .dma_req = 102 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo3", .dma_req = 103 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo4", .dma_req = 104 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo5", .dma_req = 105 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo6", .dma_req = 106 + OMAP44XX_DMA_REQ_START },
+ { .name = "fifo7", .dma_req = 107 + OMAP44XX_DMA_REQ_START },
+};
+
+/* aess master ports */
+static struct omap_hwmod_ocp_if *omap44xx_aess_masters[] = {
+ &omap44xx_aess__l4_abe,
+};
+
+static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = {
+ {
+ .pa_start = 0x401f1000,
+ .pa_end = 0x401f13ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> aess */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_aess_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_aess_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_aess_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = {
+ {
+ .pa_start = 0x490f1000,
+ .pa_end = 0x490f13ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> aess (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_aess_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_aess_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_aess_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* aess slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_aess_slaves[] = {
+ &omap44xx_l4_abe__aess,
+ &omap44xx_l4_abe__aess_dma,
+};
+
+static struct omap_hwmod omap44xx_aess_hwmod = {
+ .name = "aess",
+ .class = &omap44xx_aess_hwmod_class,
+ .mpu_irqs = omap44xx_aess_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_aess_irqs),
+ .sdma_reqs = omap44xx_aess_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_aess_sdma_reqs),
+ .main_clk = "aess_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_aess_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_aess_slaves),
+ .masters = omap44xx_aess_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_aess_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'bandgap' class
+ * bangap reference for ldo regulators
+ */
+
+static struct omap_hwmod_class omap44xx_bandgap_hwmod_class = {
+ .name = "bandgap",
+};
+
+/* bandgap */
+static struct omap_hwmod_opt_clk bandgap_opt_clks[] = {
+ { .role = "fclk", .clk = "bandgap_fclk" },
+};
+
+static struct omap_hwmod omap44xx_bandgap_hwmod = {
+ .name = "bandgap",
+ .class = &omap44xx_bandgap_hwmod_class,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,
+ },
+ },
+ .opt_clks = bandgap_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(bandgap_opt_clks),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'counter' class
+ * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0004,
+ .sysc_flags = SYSC_HAS_SIDLEMODE,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_counter_hwmod_class = {
+ .name = "counter",
+ .sysc = &omap44xx_counter_sysc,
+};
+
+/* counter_32k */
+static struct omap_hwmod omap44xx_counter_32k_hwmod;
+static struct omap_hwmod_addr_space omap44xx_counter_32k_addrs[] = {
+ {
+ .pa_start = 0x4a304000,
+ .pa_end = 0x4a30401f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> counter_32k */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_counter_32k_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_counter_32k_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_counter_32k_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* counter_32k slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_counter_32k_slaves[] = {
+ &omap44xx_l4_wkup__counter_32k,
+};
+
+static struct omap_hwmod omap44xx_counter_32k_hwmod = {
+ .name = "counter_32k",
+ .class = &omap44xx_counter_hwmod_class,
+ .flags = HWMOD_SWSUP_SIDLE,
+ .main_clk = "sys_32k_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_counter_32k_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_counter_32k_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dma' class
+ * dma controller for data exchange between memory to memory (i.e. internal or
+ * external memory) and gp peripherals to memory or memory to gp peripherals
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dma_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x002c,
+ .syss_offs = 0x0028,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dma_hwmod_class = {
+ .name = "dma",
+ .sysc = &omap44xx_dma_sysc,
+};
+
+/* dma dev_attr */
+static struct omap_dma_dev_attr dma_dev_attr = {
+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
+ .lch_count = 32,
+};
+
+/* dma_system */
+static struct omap_hwmod_irq_info omap44xx_dma_system_irqs[] = {
+ { .name = "0", .irq = 12 + OMAP44XX_IRQ_GIC_START },
+ { .name = "1", .irq = 13 + OMAP44XX_IRQ_GIC_START },
+ { .name = "2", .irq = 14 + OMAP44XX_IRQ_GIC_START },
+ { .name = "3", .irq = 15 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* dma_system master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = {
+ &omap44xx_dma_system__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = {
+ {
+ .pa_start = 0x4a056000,
+ .pa_end = 0x4a056fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> dma_system */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dma_system = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_dma_system_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dma_system_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dma_system_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dma_system slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dma_system_slaves[] = {
+ &omap44xx_l4_cfg__dma_system,
+};
+
+static struct omap_hwmod omap44xx_dma_system_hwmod = {
+ .name = "dma_system",
+ .class = &omap44xx_dma_hwmod_class,
+ .mpu_irqs = omap44xx_dma_system_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dma_system_irqs),
+ .main_clk = "l3_div_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_SDMA_SDMA_CLKCTRL,
+ },
+ },
+ .dev_attr = &dma_dev_attr,
+ .slaves = omap44xx_dma_system_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dma_system_slaves),
+ .masters = omap44xx_dma_system_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dma_system_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dmic' class
+ * digital microphone controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dmic_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_dmic_hwmod_class = {
+ .name = "dmic",
+ .sysc = &omap44xx_dmic_sysc,
+};
+
+/* dmic */
+static struct omap_hwmod omap44xx_dmic_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dmic_irqs[] = {
+ { .irq = 114 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = {
+ { .dma_req = 66 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = {
+ {
+ .pa_start = 0x4012e000,
+ .pa_end = 0x4012e07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> dmic */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_dmic_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_dmic_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dmic_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = {
+ {
+ .pa_start = 0x4902e000,
+ .pa_end = 0x4902e07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> dmic (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_dmic_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_dmic_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dmic_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dmic slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dmic_slaves[] = {
+ &omap44xx_l4_abe__dmic,
+ &omap44xx_l4_abe__dmic_dma,
+};
+
+static struct omap_hwmod omap44xx_dmic_hwmod = {
+ .name = "dmic",
+ .class = &omap44xx_dmic_hwmod_class,
+ .mpu_irqs = omap44xx_dmic_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmic_irqs),
+ .sdma_reqs = omap44xx_dmic_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dmic_sdma_reqs),
+ .main_clk = "dmic_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dmic_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dmic_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dsp' class
+ * dsp sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_dsp_hwmod_class = {
+ .name = "dsp",
+};
+
+/* dsp */
+static struct omap_hwmod_irq_info omap44xx_dsp_irqs[] = {
+ { .irq = 28 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_rst_info omap44xx_dsp_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_dsp_c0_resets[] = {
+ { .name = "dsp", .rst_shift = 0 },
+};
+
+/* dsp -> iva */
+static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
+ .master = &omap44xx_dsp_hwmod,
+ .slave = &omap44xx_iva_hwmod,
+ .clk = "dpll_iva_m5x2_ck",
+};
+
+/* dsp master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dsp_masters[] = {
+ &omap44xx_dsp__l3_main_1,
+ &omap44xx_dsp__l4_abe,
+ &omap44xx_dsp__iva,
+};
+
+/* l4_cfg -> dsp */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_dsp_hwmod,
+ .clk = "l4_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dsp slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dsp_slaves[] = {
+ &omap44xx_l4_cfg__dsp,
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
+ .name = "dsp_c0",
+ .class = &omap44xx_dsp_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_dsp_c0_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_c0_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct omap_hwmod omap44xx_dsp_hwmod = {
+ .name = "dsp",
+ .class = &omap44xx_dsp_hwmod_class,
+ .mpu_irqs = omap44xx_dsp_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dsp_irqs),
+ .rst_lines = omap44xx_dsp_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_dsp_resets),
+ .main_clk = "dsp_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_TESLA_TESLA_CLKCTRL,
+ .rstctrl_reg = OMAP4430_RM_TESLA_RSTCTRL,
+ },
+ },
+ .slaves = omap44xx_dsp_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dsp_slaves),
+ .masters = omap44xx_dsp_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dsp_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+};
+
+static struct omap_hwmod_class omap44xx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap44xx_dss_sysc,
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_masters[] = {
+ &omap44xx_dss__l3_main_1,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = {
+ {
+ .pa_start = 0x58000000,
+ .pa_end = 0x5800007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_addrs[] = {
+ {
+ .pa_start = 0x48040000,
+ .pa_end = 0x4804007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = {
+ &omap44xx_l3_main_2__dss,
+ &omap44xx_l4_per__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+ { .role = "tv_clk", .clk = "dss_tv_clk" },
+ { .role = "dss_clk", .clk = "dss_dss_clk" },
+ { .role = "video_clk", .clk = "dss_48mhz_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_hwmod = {
+ .name = "dss_core",
+ .class = &omap44xx_dss_hwmod_class,
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap44xx_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_slaves),
+ .masters = omap44xx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap44xx_dispc_sysc,
+};
+
+/* dss_dispc */
+static struct omap_hwmod omap44xx_dss_dispc_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dss_dispc_irqs[] = {
+ { .irq = 25 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = {
+ { .dma_req = 5 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = {
+ {
+ .pa_start = 0x58001000,
+ .pa_end = 0x58001fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dispc */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dispc_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dispc_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48041000,
+ .pa_end = 0x48041fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dispc */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dispc_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
+ &omap44xx_l3_main_2__dss_dispc,
+ &omap44xx_l4_per__dss_dispc,
+};
+
+static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap44xx_dispc_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dispc_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs),
+ .sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dsi' class
+ * display serial interface controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dsi_hwmod_class = {
+ .name = "dsi",
+ .sysc = &omap44xx_dsi_sysc,
+};
+
+/* dss_dsi1 */
+static struct omap_hwmod omap44xx_dss_dsi1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dss_dsi1_irqs[] = {
+ { .irq = 53 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = {
+ { .dma_req = 74 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = {
+ {
+ .pa_start = 0x58004000,
+ .pa_end = 0x580041ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dsi1_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dsi1_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_addrs[] = {
+ {
+ .pa_start = 0x48044000,
+ .pa_end = 0x480441ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dsi1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dsi1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_dsi1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = {
+ &omap44xx_l3_main_2__dss_dsi1,
+ &omap44xx_l4_per__dss_dsi1,
+};
+
+static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap44xx_dsi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dsi1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_irqs),
+ .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dsi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* dss_dsi2 */
+static struct omap_hwmod omap44xx_dss_dsi2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = {
+ { .irq = 84 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = {
+ { .dma_req = 83 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = {
+ {
+ .pa_start = 0x58005000,
+ .pa_end = 0x580051ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dsi2 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dsi2_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dsi2_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_addrs[] = {
+ {
+ .pa_start = 0x48045000,
+ .pa_end = 0x480451ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dsi2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dsi2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dsi2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_dsi2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = {
+ &omap44xx_l3_main_2__dss_dsi2,
+ &omap44xx_l4_per__dss_dsi2,
+};
+
+static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
+ .name = "dss_dsi2",
+ .class = &omap44xx_dsi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dsi2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_irqs),
+ .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dsi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'hdmi' class
+ * hdmi controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_hdmi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = {
+ .name = "hdmi",
+ .sysc = &omap44xx_hdmi_sysc,
+};
+
+/* dss_hdmi */
+static struct omap_hwmod omap44xx_dss_hdmi_hwmod;
+static struct omap_hwmod_irq_info omap44xx_dss_hdmi_irqs[] = {
+ { .irq = 101 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = {
+ { .dma_req = 75 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = {
+ {
+ .pa_start = 0x58006000,
+ .pa_end = 0x58006fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_hdmi */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_hdmi_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_hdmi_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_addrs[] = {
+ {
+ .pa_start = 0x48046000,
+ .pa_end = 0x48046fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_hdmi */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_hdmi_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_hdmi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_hdmi slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = {
+ &omap44xx_l3_main_2__dss_hdmi,
+ &omap44xx_l4_per__dss_hdmi,
+};
+
+static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
+ .name = "dss_hdmi",
+ .class = &omap44xx_hdmi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_hdmi_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_irqs),
+ .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_hdmi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap44xx_rfbi_sysc,
+};
+
+/* dss_rfbi */
+static struct omap_hwmod omap44xx_dss_rfbi_hwmod;
+static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = {
+ { .dma_req = 13 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = {
+ {
+ .pa_start = 0x58002000,
+ .pa_end = 0x580020ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_rfbi_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_rfbi_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48042000,
+ .pa_end = 0x480420ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_rfbi_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = {
+ &omap44xx_l3_main_2__dss_rfbi,
+ &omap44xx_l4_per__dss_rfbi,
+};
+
+static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap44xx_rfbi_hwmod_class,
+ .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap44xx_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod omap44xx_dss_venc_hwmod;
+static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = {
+ {
+ .pa_start = 0x58003000,
+ .pa_end = 0x580030ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_venc */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_venc_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_venc_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48043000,
+ .pa_end = 0x480430ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_venc */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_venc_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = {
+ &omap44xx_l3_main_2__dss_venc,
+ &omap44xx_l4_per__dss_venc,
+};
+
+static struct omap_hwmod omap44xx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap44xx_venc_hwmod_class,
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'gpio' class
+ * general purpose io module
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0114,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &omap44xx_gpio_sysc,
+ .rev = 2,
+};
+
+/* gpio dev_attr */
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+/* gpio1 */
+static struct omap_hwmod omap44xx_gpio1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = {
+ { .irq = 29 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = {
+ {
+ .pa_start = 0x4a310000,
+ .pa_end = 0x4a3101ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> gpio1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_gpio1_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_gpio1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = {
+ &omap44xx_l4_wkup__gpio1,
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio1_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .class = &omap44xx_gpio_hwmod_class,
+ .mpu_irqs = omap44xx_gpio1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs),
+ .main_clk = "gpio1_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio2 */
+static struct omap_hwmod omap44xx_gpio2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = {
+ { .irq = 30 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = {
+ {
+ .pa_start = 0x48055000,
+ .pa_end = 0x480551ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = {
+ &omap44xx_l4_per__gpio2,
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio2_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs),
+ .main_clk = "gpio2_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio3 */
+static struct omap_hwmod omap44xx_gpio3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = {
+ { .irq = 31 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = {
+ {
+ .pa_start = 0x48057000,
+ .pa_end = 0x480571ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = {
+ &omap44xx_l4_per__gpio3,
+};
+
+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio3_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio3_hwmod = {
+ .name = "gpio3",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio3_irqs),
+ .main_clk = "gpio3_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio3_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio4 */
+static struct omap_hwmod omap44xx_gpio4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = {
+ { .irq = 32 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = {
+ {
+ .pa_start = 0x48059000,
+ .pa_end = 0x480591ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = {
+ &omap44xx_l4_per__gpio4,
+};
+
+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio4_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio4_hwmod = {
+ .name = "gpio4",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio4_irqs),
+ .main_clk = "gpio4_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio4_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio5 */
+static struct omap_hwmod omap44xx_gpio5_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = {
+ { .irq = 33 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = {
+ {
+ .pa_start = 0x4805b000,
+ .pa_end = 0x4805b1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio5 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio5_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio5 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = {
+ &omap44xx_l4_per__gpio5,
+};
+
+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio5_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio5_hwmod = {
+ .name = "gpio5",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio5_irqs),
+ .main_clk = "gpio5_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio5_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* gpio6 */
+static struct omap_hwmod omap44xx_gpio6_hwmod;
+static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = {
+ { .irq = 34 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = {
+ {
+ .pa_start = 0x4805d000,
+ .pa_end = 0x4805d1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> gpio6 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_gpio6_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_gpio6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio6_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* gpio6 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = {
+ &omap44xx_l4_per__gpio6,
+};
+
+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = {
+ { .role = "dbclk", .clk = "gpio6_dbclk" },
+};
+
+static struct omap_hwmod omap44xx_gpio6_hwmod = {
+ .name = "gpio6",
+ .class = &omap44xx_gpio_hwmod_class,
+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET,
+ .mpu_irqs = omap44xx_gpio6_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio6_irqs),
+ .main_clk = "gpio6_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL,
+ },
+ },
+ .opt_clks = gpio6_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+ .slaves = omap44xx_gpio6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'hsi' class
+ * mipi high-speed synchronous serial interface (multichannel and full-duplex
+ * serial if)
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_hsi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_hsi_hwmod_class = {
+ .name = "hsi",
+ .sysc = &omap44xx_hsi_sysc,
+};
+
+/* hsi */
+static struct omap_hwmod_irq_info omap44xx_hsi_irqs[] = {
+ { .name = "mpu_p1", .irq = 67 + OMAP44XX_IRQ_GIC_START },
+ { .name = "mpu_p2", .irq = 68 + OMAP44XX_IRQ_GIC_START },
+ { .name = "mpu_dma", .irq = 71 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* hsi master ports */
+static struct omap_hwmod_ocp_if *omap44xx_hsi_masters[] = {
+ &omap44xx_hsi__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_hsi_addrs[] = {
+ {
+ .pa_start = 0x4a058000,
+ .pa_end = 0x4a05bfff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> hsi */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__hsi = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_hsi_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_hsi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_hsi_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* hsi slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_hsi_slaves[] = {
+ &omap44xx_l4_cfg__hsi,
+};
+
+static struct omap_hwmod omap44xx_hsi_hwmod = {
+ .name = "hsi",
+ .class = &omap44xx_hsi_hwmod_class,
+ .mpu_irqs = omap44xx_hsi_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_hsi_irqs),
+ .main_clk = "hsi_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_hsi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_hsi_slaves),
+ .masters = omap44xx_hsi_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_hsi_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'i2c' class
+ * multimaster high-speed i2c controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = {
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0090,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_i2c_hwmod_class = {
+ .name = "i2c",
+ .sysc = &omap44xx_i2c_sysc,
+};
+
+/* i2c1 */
+static struct omap_hwmod omap44xx_i2c1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = {
+ { .irq = 56 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = {
+ {
+ .pa_start = 0x48070000,
+ .pa_end = 0x480700ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = {
+ &omap44xx_l4_per__i2c1,
+};
+
+static struct omap_hwmod omap44xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs),
+ .sdma_reqs = omap44xx_i2c1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c1_sdma_reqs),
+ .main_clk = "i2c1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c2 */
+static struct omap_hwmod omap44xx_i2c2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = {
+ { .irq = 57 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = {
+ {
+ .pa_start = 0x48072000,
+ .pa_end = 0x480720ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = {
+ &omap44xx_l4_per__i2c2,
+};
+
+static struct omap_hwmod omap44xx_i2c2_hwmod = {
+ .name = "i2c2",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs),
+ .sdma_reqs = omap44xx_i2c2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c2_sdma_reqs),
+ .main_clk = "i2c2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c3 */
+static struct omap_hwmod omap44xx_i2c3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = {
+ { .irq = 61 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = {
+ {
+ .pa_start = 0x48060000,
+ .pa_end = 0x480600ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = {
+ &omap44xx_l4_per__i2c3,
+};
+
+static struct omap_hwmod omap44xx_i2c3_hwmod = {
+ .name = "i2c3",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs),
+ .sdma_reqs = omap44xx_i2c3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c3_sdma_reqs),
+ .main_clk = "i2c3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* i2c4 */
+static struct omap_hwmod omap44xx_i2c4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = {
+ { .irq = 62 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = {
+ {
+ .pa_start = 0x48350000,
+ .pa_end = 0x483500ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> i2c4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_i2c4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_i2c4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* i2c4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = {
+ &omap44xx_l4_per__i2c4,
+};
+
+static struct omap_hwmod omap44xx_i2c4_hwmod = {
+ .name = "i2c4",
+ .class = &omap44xx_i2c_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .mpu_irqs = omap44xx_i2c4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs),
+ .sdma_reqs = omap44xx_i2c4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c4_sdma_reqs),
+ .main_clk = "i2c4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_i2c4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'ipu' class
+ * imaging processor unit
+ */
+
+static struct omap_hwmod_class omap44xx_ipu_hwmod_class = {
+ .name = "ipu",
+};
+
+/* ipu */
+static struct omap_hwmod_irq_info omap44xx_ipu_irqs[] = {
+ { .irq = 100 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_rst_info omap44xx_ipu_c0_resets[] = {
+ { .name = "cpu0", .rst_shift = 0 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_ipu_c1_resets[] = {
+ { .name = "cpu1", .rst_shift = 1 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = {
+ { .name = "mmu_cache", .rst_shift = 2 },
+};
+
+/* ipu master ports */
+static struct omap_hwmod_ocp_if *omap44xx_ipu_masters[] = {
+ &omap44xx_ipu__l3_main_2,
+};
+
+/* l3_main_2 -> ipu */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_ipu_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* ipu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_ipu_slaves[] = {
+ &omap44xx_l3_main_2__ipu,
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
+ .name = "ipu_c0",
+ .class = &omap44xx_ipu_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_ipu_c0_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c0_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
+ .name = "ipu_c1",
+ .class = &omap44xx_ipu_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_ipu_c1_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c1_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct omap_hwmod omap44xx_ipu_hwmod = {
+ .name = "ipu",
+ .class = &omap44xx_ipu_hwmod_class,
+ .mpu_irqs = omap44xx_ipu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_ipu_irqs),
+ .rst_lines = omap44xx_ipu_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets),
+ .main_clk = "ipu_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL,
+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL,
+ },
+ },
+ .slaves = omap44xx_ipu_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_ipu_slaves),
+ .masters = omap44xx_ipu_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_ipu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'iss' class
+ * external images sensor pixel data processor
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_iss_hwmod_class = {
+ .name = "iss",
+ .sysc = &omap44xx_iss_sysc,
+};
+
+/* iss */
+static struct omap_hwmod_irq_info omap44xx_iss_irqs[] = {
+ { .irq = 24 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_iss_sdma_reqs[] = {
+ { .name = "1", .dma_req = 8 + OMAP44XX_DMA_REQ_START },
+ { .name = "2", .dma_req = 9 + OMAP44XX_DMA_REQ_START },
+ { .name = "3", .dma_req = 11 + OMAP44XX_DMA_REQ_START },
+ { .name = "4", .dma_req = 12 + OMAP44XX_DMA_REQ_START },
+};
+
+/* iss master ports */
+static struct omap_hwmod_ocp_if *omap44xx_iss_masters[] = {
+ &omap44xx_iss__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_iss_addrs[] = {
+ {
+ .pa_start = 0x52000000,
+ .pa_end = 0x520000ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> iss */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_iss_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_iss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_iss_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* iss slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_iss_slaves[] = {
+ &omap44xx_l3_main_2__iss,
+};
+
+static struct omap_hwmod_opt_clk iss_opt_clks[] = {
+ { .role = "ctrlclk", .clk = "iss_ctrlclk" },
+};
+
+static struct omap_hwmod omap44xx_iss_hwmod = {
+ .name = "iss",
+ .class = &omap44xx_iss_hwmod_class,
+ .mpu_irqs = omap44xx_iss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iss_irqs),
+ .sdma_reqs = omap44xx_iss_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_iss_sdma_reqs),
+ .main_clk = "iss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_CAM_ISS_CLKCTRL,
+ },
+ },
+ .opt_clks = iss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(iss_opt_clks),
+ .slaves = omap44xx_iss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_iss_slaves),
+ .masters = omap44xx_iss_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_iss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'iva' class
+ * multi-standard video encoder/decoder hardware accelerator
+ */
+
+static struct omap_hwmod_class omap44xx_iva_hwmod_class = {
+ .name = "iva",
+};
+
+/* iva */
+static struct omap_hwmod_irq_info omap44xx_iva_irqs[] = {
+ { .name = "sync_1", .irq = 103 + OMAP44XX_IRQ_GIC_START },
+ { .name = "sync_0", .irq = 104 + OMAP44XX_IRQ_GIC_START },
+ { .name = "mailbox_0", .irq = 107 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_resets[] = {
+ { .name = "logic", .rst_shift = 2 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_seq0_resets[] = {
+ { .name = "seq0", .rst_shift = 0 },
+};
+
+static struct omap_hwmod_rst_info omap44xx_iva_seq1_resets[] = {
+ { .name = "seq1", .rst_shift = 1 },
+};
+
+/* iva master ports */
+static struct omap_hwmod_ocp_if *omap44xx_iva_masters[] = {
+ &omap44xx_iva__l3_main_2,
+ &omap44xx_iva__l3_instr,
+};
+
+static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = {
+ {
+ .pa_start = 0x5a000000,
+ .pa_end = 0x5a07ffff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> iva */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_iva_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_iva_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_iva_addrs),
+ .user = OCP_USER_MPU,
+};
+
+/* iva slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = {
+ &omap44xx_dsp__iva,
+ &omap44xx_l3_main_2__iva,
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
+ .name = "iva_seq0",
+ .class = &omap44xx_iva_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_iva_seq0_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* Pseudo hwmod for reset control purpose only */
+static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
+ .name = "iva_seq1",
+ .class = &omap44xx_iva_hwmod_class,
+ .flags = HWMOD_INIT_NO_RESET,
+ .rst_lines = omap44xx_iva_seq1_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets),
+ .prcm = {
+ .omap4 = {
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static struct omap_hwmod omap44xx_iva_hwmod = {
+ .name = "iva",
+ .class = &omap44xx_iva_hwmod_class,
+ .mpu_irqs = omap44xx_iva_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iva_irqs),
+ .rst_lines = omap44xx_iva_resets,
+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets),
+ .main_clk = "iva_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL,
+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL,
+ },
+ },
+ .slaves = omap44xx_iva_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves),
+ .masters = omap44xx_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'kbd' class
+ * keyboard controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_kbd_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_kbd_hwmod_class = {
+ .name = "kbd",
+ .sysc = &omap44xx_kbd_sysc,
+};
+
+/* kbd */
+static struct omap_hwmod omap44xx_kbd_hwmod;
+static struct omap_hwmod_irq_info omap44xx_kbd_irqs[] = {
+ { .irq = 120 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_kbd_addrs[] = {
+ {
+ .pa_start = 0x4a31c000,
+ .pa_end = 0x4a31c07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> kbd */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_kbd_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_kbd_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_kbd_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* kbd slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_kbd_slaves[] = {
+ &omap44xx_l4_wkup__kbd,
+};
+
+static struct omap_hwmod omap44xx_kbd_hwmod = {
+ .name = "kbd",
+ .class = &omap44xx_kbd_hwmod_class,
+ .mpu_irqs = omap44xx_kbd_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_kbd_irqs),
+ .main_clk = "kbd_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_kbd_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_kbd_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mailbox' class
+ * mailbox module allowing communication between the on-chip processors using a
+ * queued mailbox-interrupt mechanism.
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mailbox_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &omap44xx_mailbox_sysc,
+};
+
+/* mailbox */
+static struct omap_hwmod omap44xx_mailbox_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mailbox_irqs[] = {
+ { .irq = 26 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mailbox_addrs[] = {
+ {
+ .pa_start = 0x4a0f4000,
+ .pa_end = 0x4a0f41ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> mailbox */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mailbox = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_mailbox_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mailbox_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mailbox_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mailbox slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mailbox_slaves[] = {
+ &omap44xx_l4_cfg__mailbox,
+};
+
+static struct omap_hwmod omap44xx_mailbox_hwmod = {
+ .name = "mailbox",
+ .class = &omap44xx_mailbox_hwmod_class,
+ .mpu_irqs = omap44xx_mailbox_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mailbox_irqs),
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mailbox_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mailbox_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mcbsp' class
+ * multi channel buffered serial port controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
+ .sysc_offs = 0x008c,
+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = {
+ .name = "mcbsp",
+ .sysc = &omap44xx_mcbsp_sysc,
+ .rev = MCBSP_CONFIG_TYPE4,
+};
+
+/* mcbsp1 */
+static struct omap_hwmod omap44xx_mcbsp1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = {
+ { .irq = 17 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x40122000,
+ .pa_end = 0x401220ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp1_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp1_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = {
+ {
+ .name = "dma",
+ .pa_start = 0x49022000,
+ .pa_end = 0x490220ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp1 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp1_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp1_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp1_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* mcbsp1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = {
+ &omap44xx_l4_abe__mcbsp1,
+ &omap44xx_l4_abe__mcbsp1_dma,
+};
+
+static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
+ .name = "mcbsp1",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .mpu_irqs = omap44xx_mcbsp1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp1_irqs),
+ .sdma_reqs = omap44xx_mcbsp1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp1_sdma_reqs),
+ .main_clk = "mcbsp1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mcbsp1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp2 */
+static struct omap_hwmod omap44xx_mcbsp2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = {
+ { .irq = 22 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x40124000,
+ .pa_end = 0x401240ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp2_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp2_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = {
+ {
+ .name = "dma",
+ .pa_start = 0x49024000,
+ .pa_end = 0x490240ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp2 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp2_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp2_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp2_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* mcbsp2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = {
+ &omap44xx_l4_abe__mcbsp2,
+ &omap44xx_l4_abe__mcbsp2_dma,
+};
+
+static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
+ .name = "mcbsp2",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .mpu_irqs = omap44xx_mcbsp2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp2_irqs),
+ .sdma_reqs = omap44xx_mcbsp2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp2_sdma_reqs),
+ .main_clk = "mcbsp2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mcbsp2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp3 */
+static struct omap_hwmod omap44xx_mcbsp3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = {
+ { .irq = 23 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = {
+ {
+ .name = "mpu",
+ .pa_start = 0x40126000,
+ .pa_end = 0x401260ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp3_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = {
+ {
+ .name = "dma",
+ .pa_start = 0x49026000,
+ .pa_end = 0x490260ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcbsp3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcbsp3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcbsp3_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp3_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* mcbsp3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = {
+ &omap44xx_l4_abe__mcbsp3,
+ &omap44xx_l4_abe__mcbsp3_dma,
+};
+
+static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
+ .name = "mcbsp3",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .mpu_irqs = omap44xx_mcbsp3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp3_irqs),
+ .sdma_reqs = omap44xx_mcbsp3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp3_sdma_reqs),
+ .main_clk = "mcbsp3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mcbsp3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcbsp4 */
+static struct omap_hwmod omap44xx_mcbsp4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = {
+ { .irq = 16 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = {
+ {
+ .pa_start = 0x48096000,
+ .pa_end = 0x480960ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcbsp4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mcbsp4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mcbsp4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcbsp4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = {
+ &omap44xx_l4_per__mcbsp4,
+};
+
+static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
+ .name = "mcbsp4",
+ .class = &omap44xx_mcbsp_hwmod_class,
+ .mpu_irqs = omap44xx_mcbsp4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp4_irqs),
+ .sdma_reqs = omap44xx_mcbsp4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp4_sdma_reqs),
+ .main_clk = "mcbsp4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mcbsp4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mcpdm' class
+ * multi channel pdm controller (proprietary interface with phoenix power
+ * ic)
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcpdm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_mcpdm_hwmod_class = {
+ .name = "mcpdm",
+ .sysc = &omap44xx_mcpdm_sysc,
+};
+
+/* mcpdm */
+static struct omap_hwmod omap44xx_mcpdm_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcpdm_irqs[] = {
+ { .irq = 112 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcpdm_sdma_reqs[] = {
+ { .name = "up_link", .dma_req = 64 + OMAP44XX_DMA_REQ_START },
+ { .name = "dn_link", .dma_req = 65 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = {
+ {
+ .pa_start = 0x40132000,
+ .pa_end = 0x4013207f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcpdm */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcpdm_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcpdm_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcpdm_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = {
+ {
+ .pa_start = 0x49032000,
+ .pa_end = 0x4903207f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> mcpdm (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_mcpdm_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_mcpdm_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcpdm_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* mcpdm slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcpdm_slaves[] = {
+ &omap44xx_l4_abe__mcpdm,
+ &omap44xx_l4_abe__mcpdm_dma,
+};
+
+static struct omap_hwmod omap44xx_mcpdm_hwmod = {
+ .name = "mcpdm",
+ .class = &omap44xx_mcpdm_hwmod_class,
+ .mpu_irqs = omap44xx_mcpdm_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcpdm_irqs),
+ .sdma_reqs = omap44xx_mcpdm_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcpdm_sdma_reqs),
+ .main_clk = "mcpdm_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mcpdm_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcpdm_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mcspi' class
+ * multichannel serial port interface (mcspi) / master/slave synchronous serial
+ * bus
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = {
+ .name = "mcspi",
+ .sysc = &omap44xx_mcspi_sysc,
+ .rev = OMAP4_MCSPI_REV,
+};
+
+/* mcspi1 */
+static struct omap_hwmod omap44xx_mcspi1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcspi1_irqs[] = {
+ { .irq = 65 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcspi1_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 34 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx0", .dma_req = 35 + OMAP44XX_DMA_REQ_START },
+ { .name = "tx1", .dma_req = 36 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx1", .dma_req = 37 + OMAP44XX_DMA_REQ_START },
+ { .name = "tx2", .dma_req = 38 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx2", .dma_req = 39 + OMAP44XX_DMA_REQ_START },
+ { .name = "tx3", .dma_req = 40 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx3", .dma_req = 41 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcspi1_addrs[] = {
+ {
+ .pa_start = 0x48098000,
+ .pa_end = 0x480981ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcspi1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mcspi1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mcspi1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcspi1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcspi1_slaves[] = {
+ &omap44xx_l4_per__mcspi1,
+};
+
+/* mcspi1 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod omap44xx_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .class = &omap44xx_mcspi_hwmod_class,
+ .mpu_irqs = omap44xx_mcspi1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi1_irqs),
+ .sdma_reqs = omap44xx_mcspi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi1_sdma_reqs),
+ .main_clk = "mcspi1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL,
+ },
+ },
+ .dev_attr = &mcspi1_dev_attr,
+ .slaves = omap44xx_mcspi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcspi2 */
+static struct omap_hwmod omap44xx_mcspi2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcspi2_irqs[] = {
+ { .irq = 66 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcspi2_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 42 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx0", .dma_req = 43 + OMAP44XX_DMA_REQ_START },
+ { .name = "tx1", .dma_req = 44 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx1", .dma_req = 45 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcspi2_addrs[] = {
+ {
+ .pa_start = 0x4809a000,
+ .pa_end = 0x4809a1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcspi2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mcspi2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mcspi2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcspi2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcspi2_slaves[] = {
+ &omap44xx_l4_per__mcspi2,
+};
+
+/* mcspi2 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi2_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap44xx_mcspi2_hwmod = {
+ .name = "mcspi2",
+ .class = &omap44xx_mcspi_hwmod_class,
+ .mpu_irqs = omap44xx_mcspi2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi2_irqs),
+ .sdma_reqs = omap44xx_mcspi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi2_sdma_reqs),
+ .main_clk = "mcspi2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL,
+ },
+ },
+ .dev_attr = &mcspi2_dev_attr,
+ .slaves = omap44xx_mcspi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcspi3 */
+static struct omap_hwmod omap44xx_mcspi3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcspi3_irqs[] = {
+ { .irq = 91 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcspi3_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 14 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx0", .dma_req = 15 + OMAP44XX_DMA_REQ_START },
+ { .name = "tx1", .dma_req = 22 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx1", .dma_req = 23 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcspi3_addrs[] = {
+ {
+ .pa_start = 0x480b8000,
+ .pa_end = 0x480b81ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcspi3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mcspi3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mcspi3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcspi3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcspi3_slaves[] = {
+ &omap44xx_l4_per__mcspi3,
+};
+
+/* mcspi3 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi3_dev_attr = {
+ .num_chipselect = 2,
+};
+
+static struct omap_hwmod omap44xx_mcspi3_hwmod = {
+ .name = "mcspi3",
+ .class = &omap44xx_mcspi_hwmod_class,
+ .mpu_irqs = omap44xx_mcspi3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi3_irqs),
+ .sdma_reqs = omap44xx_mcspi3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi3_sdma_reqs),
+ .main_clk = "mcspi3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL,
+ },
+ },
+ .dev_attr = &mcspi3_dev_attr,
+ .slaves = omap44xx_mcspi3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mcspi4 */
+static struct omap_hwmod omap44xx_mcspi4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mcspi4_irqs[] = {
+ { .irq = 48 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mcspi4_sdma_reqs[] = {
+ { .name = "tx0", .dma_req = 69 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx0", .dma_req = 70 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mcspi4_addrs[] = {
+ {
+ .pa_start = 0x480ba000,
+ .pa_end = 0x480ba1ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mcspi4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mcspi4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mcspi4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mcspi4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mcspi4_slaves[] = {
+ &omap44xx_l4_per__mcspi4,
+};
+
+/* mcspi4 dev_attr */
+static struct omap2_mcspi_dev_attr mcspi4_dev_attr = {
+ .num_chipselect = 1,
+};
+
+static struct omap_hwmod omap44xx_mcspi4_hwmod = {
+ .name = "mcspi4",
+ .class = &omap44xx_mcspi_hwmod_class,
+ .mpu_irqs = omap44xx_mcspi4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi4_irqs),
+ .sdma_reqs = omap44xx_mcspi4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi4_sdma_reqs),
+ .main_clk = "mcspi4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL,
+ },
+ },
+ .dev_attr = &mcspi4_dev_attr,
+ .slaves = omap44xx_mcspi4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mmc' class
+ * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_mmc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_mmc_hwmod_class = {
+ .name = "mmc",
+ .sysc = &omap44xx_mmc_sysc,
+};
+
+/* mmc1 */
+
+static struct omap_hwmod_irq_info omap44xx_mmc1_irqs[] = {
+ { .irq = 83 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mmc1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 60 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 61 + OMAP44XX_DMA_REQ_START },
+};
+
+/* mmc1 master ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc1_masters[] = {
+ &omap44xx_mmc1__l3_main_1,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmc1_addrs[] = {
+ {
+ .pa_start = 0x4809c000,
+ .pa_end = 0x4809c3ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mmc1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mmc1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmc1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc1_slaves[] = {
+ &omap44xx_l4_per__mmc1,
+};
+
+/* mmc1 dev_attr */
+static struct omap_mmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod omap44xx_mmc1_hwmod = {
+ .name = "mmc1",
+ .class = &omap44xx_mmc_hwmod_class,
+ .mpu_irqs = omap44xx_mmc1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc1_irqs),
+ .sdma_reqs = omap44xx_mmc1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc1_sdma_reqs),
+ .main_clk = "mmc1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .slaves = omap44xx_mmc1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc1_slaves),
+ .masters = omap44xx_mmc1_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_mmc1_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mmc2 */
+static struct omap_hwmod_irq_info omap44xx_mmc2_irqs[] = {
+ { .irq = 86 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mmc2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 46 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 47 + OMAP44XX_DMA_REQ_START },
+};
+
+/* mmc2 master ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc2_masters[] = {
+ &omap44xx_mmc2__l3_main_1,
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmc2_addrs[] = {
+ {
+ .pa_start = 0x480b4000,
+ .pa_end = 0x480b43ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mmc2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mmc2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmc2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc2_slaves[] = {
+ &omap44xx_l4_per__mmc2,
+};
+
+static struct omap_hwmod omap44xx_mmc2_hwmod = {
+ .name = "mmc2",
+ .class = &omap44xx_mmc_hwmod_class,
+ .mpu_irqs = omap44xx_mmc2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc2_irqs),
+ .sdma_reqs = omap44xx_mmc2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc2_sdma_reqs),
+ .main_clk = "mmc2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mmc2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc2_slaves),
+ .masters = omap44xx_mmc2_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_mmc2_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mmc3 */
+static struct omap_hwmod omap44xx_mmc3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mmc3_irqs[] = {
+ { .irq = 94 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mmc3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 76 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 77 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmc3_addrs[] = {
+ {
+ .pa_start = 0x480ad000,
+ .pa_end = 0x480ad3ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mmc3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mmc3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmc3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc3_slaves[] = {
+ &omap44xx_l4_per__mmc3,
+};
+
+static struct omap_hwmod omap44xx_mmc3_hwmod = {
+ .name = "mmc3",
+ .class = &omap44xx_mmc_hwmod_class,
+ .mpu_irqs = omap44xx_mmc3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc3_irqs),
+ .sdma_reqs = omap44xx_mmc3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc3_sdma_reqs),
+ .main_clk = "mmc3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mmc3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mmc4 */
+static struct omap_hwmod omap44xx_mmc4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mmc4_irqs[] = {
+ { .irq = 96 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mmc4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 56 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 57 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmc4_addrs[] = {
+ {
+ .pa_start = 0x480d1000,
+ .pa_end = 0x480d13ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mmc4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mmc4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmc4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc4_slaves[] = {
+ &omap44xx_l4_per__mmc4,
+};
+
+static struct omap_hwmod omap44xx_mmc4_hwmod = {
+ .name = "mmc4",
+ .class = &omap44xx_mmc_hwmod_class,
+ .mpu_irqs = omap44xx_mmc4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc4_irqs),
+ .sdma_reqs = omap44xx_mmc4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc4_sdma_reqs),
+ .main_clk = "mmc4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mmc4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* mmc5 */
+static struct omap_hwmod omap44xx_mmc5_hwmod;
+static struct omap_hwmod_irq_info omap44xx_mmc5_irqs[] = {
+ { .irq = 59 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_mmc5_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 58 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 59 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_mmc5_addrs[] = {
+ {
+ .pa_start = 0x480d5000,
+ .pa_end = 0x480d53ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> mmc5 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_mmc5_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_mmc5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc5_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* mmc5 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_mmc5_slaves[] = {
+ &omap44xx_l4_per__mmc5,
+};
+
+static struct omap_hwmod omap44xx_mmc5_hwmod = {
+ .name = "mmc5",
+ .class = &omap44xx_mmc_hwmod_class,
+ .mpu_irqs = omap44xx_mmc5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc5_irqs),
+ .sdma_reqs = omap44xx_mmc5_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc5_sdma_reqs),
+ .main_clk = "mmc5_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_mmc5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'mpu' class
+ * mpu sub-system
+ */
+
+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
+ .name = "mpu",
+};
+
+/* mpu */
+static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = {
+ { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START },
+ { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* mpu master ports */
+static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = {
+ &omap44xx_mpu__l3_main_1,
+ &omap44xx_mpu__l4_abe,
+ &omap44xx_mpu__dmm,
+};
+
+static struct omap_hwmod omap44xx_mpu_hwmod = {
+ .name = "mpu",
+ .class = &omap44xx_mpu_hwmod_class,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .mpu_irqs = omap44xx_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
+ .main_clk = "dpll_mpu_m2_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
+ },
+ },
+ .masters = omap44xx_mpu_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'smartreflex' class
+ * smartreflex module (monitor silicon performance and outputs a measure of
+ * performance error)
+ */
+
+/* The IP is not compliant to type1 / type2 scheme */
+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
+ .sidle_shift = 24,
+ .enwkup_shift = 26,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
+ .sysc_offs = 0x0038,
+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type_smartreflex,
+};
+
+static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
+ .name = "smartreflex",
+ .sysc = &omap44xx_smartreflex_sysc,
+ .rev = 2,
+};
+
+/* smartreflex_core */
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
+ { .irq = 19 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
+ {
+ .pa_start = 0x4a0dd000,
+ .pa_end = 0x4a0dd03f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_core */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_core_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_core slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_core,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
+ .name = "smartreflex_core",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_core_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
+ .main_clk = "smartreflex_core_fck",
+ .vdd_name = "core",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_core_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* smartreflex_iva */
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
+ { .irq = 102 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
+ {
+ .pa_start = 0x4a0db000,
+ .pa_end = 0x4a0db03f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_iva */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_iva_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_iva_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_iva slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_iva,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
+ .name = "smartreflex_iva",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_iva_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
+ .main_clk = "smartreflex_iva_fck",
+ .vdd_name = "iva",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_iva_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* smartreflex_mpu */
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
+static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
+ { .irq = 18 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
+ {
+ .pa_start = 0x4a0d9000,
+ .pa_end = 0x4a0d903f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> smartreflex_mpu */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_smartreflex_mpu_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_smartreflex_mpu_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* smartreflex_mpu slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
+ &omap44xx_l4_cfg__smartreflex_mpu,
+};
+
+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
+ .name = "smartreflex_mpu",
+ .class = &omap44xx_smartreflex_hwmod_class,
+ .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
+ .main_clk = "smartreflex_mpu_fck",
+ .vdd_name = "mpu",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_smartreflex_mpu_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'spinlock' class
+ * spinlock provides hardware assistance for synchronizing the processes
+ * running on multiple processors
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_spinlock_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_spinlock_hwmod_class = {
+ .name = "spinlock",
+ .sysc = &omap44xx_spinlock_sysc,
+};
+
+/* spinlock */
+static struct omap_hwmod omap44xx_spinlock_hwmod;
+static struct omap_hwmod_addr_space omap44xx_spinlock_addrs[] = {
+ {
+ .pa_start = 0x4a0f6000,
+ .pa_end = 0x4a0f6fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> spinlock */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__spinlock = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_spinlock_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_spinlock_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_spinlock_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* spinlock slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_spinlock_slaves[] = {
+ &omap44xx_l4_cfg__spinlock,
+};
+
+static struct omap_hwmod omap44xx_spinlock_hwmod = {
+ .name = "spinlock",
+ .class = &omap44xx_spinlock_hwmod_class,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_spinlock_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_spinlock_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'timer' class
+ * general purpose timer module with accurate 1ms tick
+ * This class contains several variants: ['timer_1ms', 'timer']
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap44xx_timer_1ms_sysc,
+};
+
+static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &omap44xx_timer_sysc,
+};
+
+/* timer1 */
+static struct omap_hwmod omap44xx_timer1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
+ { .irq = 37 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer1_addrs[] = {
+ {
+ .pa_start = 0x4a318000,
+ .pa_end = 0x4a31807f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> timer1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_timer1_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_timer1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer1_slaves[] = {
+ &omap44xx_l4_wkup__timer1,
+};
+
+static struct omap_hwmod omap44xx_timer1_hwmod = {
+ .name = "timer1",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .mpu_irqs = omap44xx_timer1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer1_irqs),
+ .main_clk = "timer1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer2 */
+static struct omap_hwmod omap44xx_timer2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer2_irqs[] = {
+ { .irq = 38 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer2_addrs[] = {
+ {
+ .pa_start = 0x48032000,
+ .pa_end = 0x4803207f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer2_slaves[] = {
+ &omap44xx_l4_per__timer2,
+};
+
+static struct omap_hwmod omap44xx_timer2_hwmod = {
+ .name = "timer2",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .mpu_irqs = omap44xx_timer2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer2_irqs),
+ .main_clk = "timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer3 */
+static struct omap_hwmod omap44xx_timer3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer3_irqs[] = {
+ { .irq = 39 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer3_addrs[] = {
+ {
+ .pa_start = 0x48034000,
+ .pa_end = 0x4803407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer3_slaves[] = {
+ &omap44xx_l4_per__timer3,
+};
+
+static struct omap_hwmod omap44xx_timer3_hwmod = {
+ .name = "timer3",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer3_irqs),
+ .main_clk = "timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer4 */
+static struct omap_hwmod omap44xx_timer4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer4_irqs[] = {
+ { .irq = 40 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer4_addrs[] = {
+ {
+ .pa_start = 0x48036000,
+ .pa_end = 0x4803607f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer4_slaves[] = {
+ &omap44xx_l4_per__timer4,
+};
+
+static struct omap_hwmod omap44xx_timer4_hwmod = {
+ .name = "timer4",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer4_irqs),
+ .main_clk = "timer4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer5 */
+static struct omap_hwmod omap44xx_timer5_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer5_irqs[] = {
+ { .irq = 41 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer5_addrs[] = {
+ {
+ .pa_start = 0x40138000,
+ .pa_end = 0x4013807f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer5 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer5_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer5_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer5_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer5_dma_addrs[] = {
+ {
+ .pa_start = 0x49038000,
+ .pa_end = 0x4903807f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer5 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer5_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer5_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer5_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* timer5 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer5_slaves[] = {
+ &omap44xx_l4_abe__timer5,
+ &omap44xx_l4_abe__timer5_dma,
+};
+
+static struct omap_hwmod omap44xx_timer5_hwmod = {
+ .name = "timer5",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer5_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer5_irqs),
+ .main_clk = "timer5_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer5_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer5_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer6 */
+static struct omap_hwmod omap44xx_timer6_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer6_irqs[] = {
+ { .irq = 42 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer6_addrs[] = {
+ {
+ .pa_start = 0x4013a000,
+ .pa_end = 0x4013a07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer6 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer6_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer6_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer6_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer6_dma_addrs[] = {
+ {
+ .pa_start = 0x4903a000,
+ .pa_end = 0x4903a07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer6 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer6_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer6_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer6_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* timer6 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer6_slaves[] = {
+ &omap44xx_l4_abe__timer6,
+ &omap44xx_l4_abe__timer6_dma,
+};
+
+static struct omap_hwmod omap44xx_timer6_hwmod = {
+ .name = "timer6",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer6_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer6_irqs),
+ .main_clk = "timer6_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer6_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer6_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer7 */
+static struct omap_hwmod omap44xx_timer7_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer7_irqs[] = {
+ { .irq = 43 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer7_addrs[] = {
+ {
+ .pa_start = 0x4013c000,
+ .pa_end = 0x4013c07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer7 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer7_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer7_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer7_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer7_dma_addrs[] = {
+ {
+ .pa_start = 0x4903c000,
+ .pa_end = 0x4903c07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer7 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer7_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer7_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer7_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* timer7 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer7_slaves[] = {
+ &omap44xx_l4_abe__timer7,
+ &omap44xx_l4_abe__timer7_dma,
+};
+
+static struct omap_hwmod omap44xx_timer7_hwmod = {
+ .name = "timer7",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer7_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer7_irqs),
+ .main_clk = "timer7_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer7_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer7_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer8 */
+static struct omap_hwmod omap44xx_timer8_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer8_irqs[] = {
+ { .irq = 44 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer8_addrs[] = {
+ {
+ .pa_start = 0x4013e000,
+ .pa_end = 0x4013e07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer8 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer8_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer8_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer8_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer8_dma_addrs[] = {
+ {
+ .pa_start = 0x4903e000,
+ .pa_end = 0x4903e07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> timer8 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_timer8_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_timer8_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer8_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* timer8 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer8_slaves[] = {
+ &omap44xx_l4_abe__timer8,
+ &omap44xx_l4_abe__timer8_dma,
+};
+
+static struct omap_hwmod omap44xx_timer8_hwmod = {
+ .name = "timer8",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer8_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer8_irqs),
+ .main_clk = "timer8_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer8_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer8_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer9 */
+static struct omap_hwmod omap44xx_timer9_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer9_irqs[] = {
+ { .irq = 45 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer9_addrs[] = {
+ {
+ .pa_start = 0x4803e000,
+ .pa_end = 0x4803e07f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer9 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer9 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer9_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer9_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer9_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer9 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer9_slaves[] = {
+ &omap44xx_l4_per__timer9,
+};
+
+static struct omap_hwmod omap44xx_timer9_hwmod = {
+ .name = "timer9",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer9_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer9_irqs),
+ .main_clk = "timer9_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer9_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer9_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer10 */
+static struct omap_hwmod omap44xx_timer10_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer10_irqs[] = {
+ { .irq = 46 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer10_addrs[] = {
+ {
+ .pa_start = 0x48086000,
+ .pa_end = 0x4808607f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer10 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer10 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer10_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer10_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer10_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer10 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer10_slaves[] = {
+ &omap44xx_l4_per__timer10,
+};
+
+static struct omap_hwmod omap44xx_timer10_hwmod = {
+ .name = "timer10",
+ .class = &omap44xx_timer_1ms_hwmod_class,
+ .mpu_irqs = omap44xx_timer10_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer10_irqs),
+ .main_clk = "timer10_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer10_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer10_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* timer11 */
+static struct omap_hwmod omap44xx_timer11_hwmod;
+static struct omap_hwmod_irq_info omap44xx_timer11_irqs[] = {
+ { .irq = 47 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_timer11_addrs[] = {
+ {
+ .pa_start = 0x48088000,
+ .pa_end = 0x4808807f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> timer11 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer11 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_timer11_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_timer11_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_timer11_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* timer11 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_timer11_slaves[] = {
+ &omap44xx_l4_per__timer11,
+};
+
+static struct omap_hwmod omap44xx_timer11_hwmod = {
+ .name = "timer11",
+ .class = &omap44xx_timer_hwmod_class,
+ .mpu_irqs = omap44xx_timer11_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer11_irqs),
+ .main_clk = "timer11_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_timer11_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer11_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'uart' class
+ * universal asynchronous receiver/transmitter (uart)
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_uart_sysc = {
+ .rev_offs = 0x0050,
+ .sysc_offs = 0x0054,
+ .syss_offs = 0x0058,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_uart_hwmod_class = {
+ .name = "uart",
+ .sysc = &omap44xx_uart_sysc,
+};
+
+/* uart1 */
+static struct omap_hwmod omap44xx_uart1_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart1_irqs[] = {
+ { .irq = 72 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart1_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 48 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 49 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart1_addrs[] = {
+ {
+ .pa_start = 0x4806a000,
+ .pa_end = 0x4806a0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart1_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart1_slaves[] = {
+ &omap44xx_l4_per__uart1,
+};
+
+static struct omap_hwmod omap44xx_uart1_hwmod = {
+ .name = "uart1",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart1_irqs),
+ .sdma_reqs = omap44xx_uart1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart1_sdma_reqs),
+ .main_clk = "uart1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART1_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart2 */
+static struct omap_hwmod omap44xx_uart2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart2_irqs[] = {
+ { .irq = 73 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart2_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 50 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 51 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart2_addrs[] = {
+ {
+ .pa_start = 0x4806c000,
+ .pa_end = 0x4806c0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart2_slaves[] = {
+ &omap44xx_l4_per__uart2,
+};
+
+static struct omap_hwmod omap44xx_uart2_hwmod = {
+ .name = "uart2",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart2_irqs),
+ .sdma_reqs = omap44xx_uart2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart2_sdma_reqs),
+ .main_clk = "uart2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart3 */
+static struct omap_hwmod omap44xx_uart3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart3_irqs[] = {
+ { .irq = 74 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart3_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 52 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 53 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart3_addrs[] = {
+ {
+ .pa_start = 0x48020000,
+ .pa_end = 0x480200ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart3 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart3_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart3_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart3_slaves[] = {
+ &omap44xx_l4_per__uart3,
+};
+
+static struct omap_hwmod omap44xx_uart3_hwmod = {
+ .name = "uart3",
+ .class = &omap44xx_uart_hwmod_class,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+ .mpu_irqs = omap44xx_uart3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart3_irqs),
+ .sdma_reqs = omap44xx_uart3_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart3_sdma_reqs),
+ .main_clk = "uart3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* uart4 */
+static struct omap_hwmod omap44xx_uart4_hwmod;
+static struct omap_hwmod_irq_info omap44xx_uart4_irqs[] = {
+ { .irq = 70 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_uart4_sdma_reqs[] = {
+ { .name = "tx", .dma_req = 54 + OMAP44XX_DMA_REQ_START },
+ { .name = "rx", .dma_req = 55 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_uart4_addrs[] = {
+ {
+ .pa_start = 0x4806e000,
+ .pa_end = 0x4806e0ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> uart4 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_uart4_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_uart4_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_uart4_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* uart4 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_uart4_slaves[] = {
+ &omap44xx_l4_per__uart4,
+};
+
+static struct omap_hwmod omap44xx_uart4_hwmod = {
+ .name = "uart4",
+ .class = &omap44xx_uart_hwmod_class,
+ .mpu_irqs = omap44xx_uart4_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_uart4_irqs),
+ .sdma_reqs = omap44xx_uart4_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_uart4_sdma_reqs),
+ .main_clk = "uart4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L4PER_UART4_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_uart4_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_uart4_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'usb_otg_hs' class
+ * high-speed on-the-go universal serial bus (usb_otg_hs) controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_usb_otg_hs_sysc = {
+ .rev_offs = 0x0400,
+ .sysc_offs = 0x0404,
+ .syss_offs = 0x0408,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
+ MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_usb_otg_hs_hwmod_class = {
+ .name = "usb_otg_hs",
+ .sysc = &omap44xx_usb_otg_hs_sysc,
+};
+
+/* usb_otg_hs */
+static struct omap_hwmod_irq_info omap44xx_usb_otg_hs_irqs[] = {
+ { .name = "mc", .irq = 92 + OMAP44XX_IRQ_GIC_START },
+ { .name = "dma", .irq = 93 + OMAP44XX_IRQ_GIC_START },
+};
+
+/* usb_otg_hs master ports */
+static struct omap_hwmod_ocp_if *omap44xx_usb_otg_hs_masters[] = {
+ &omap44xx_usb_otg_hs__l3_main_2,
+};
+
+static struct omap_hwmod_addr_space omap44xx_usb_otg_hs_addrs[] = {
+ {
+ .pa_start = 0x4a0ab000,
+ .pa_end = 0x4a0ab003,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_cfg -> usb_otg_hs */
+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_otg_hs = {
+ .master = &omap44xx_l4_cfg_hwmod,
+ .slave = &omap44xx_usb_otg_hs_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_usb_otg_hs_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* usb_otg_hs slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_usb_otg_hs_slaves[] = {
+ &omap44xx_l4_cfg__usb_otg_hs,
+};
+
+static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = {
+ { .role = "xclk", .clk = "usb_otg_hs_xclk" },
+};
+
+static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
+ .name = "usb_otg_hs",
+ .class = &omap44xx_usb_otg_hs_hwmod_class,
+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
+ .mpu_irqs = omap44xx_usb_otg_hs_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_irqs),
+ .main_clk = "usb_otg_hs_ick",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL,
+ },
+ },
+ .opt_clks = usb_otg_hs_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_hs_opt_clks),
+ .slaves = omap44xx_usb_otg_hs_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_slaves),
+ .masters = omap44xx_usb_otg_hs_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'wd_timer' class
+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on
+ * overflow condition
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_wd_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = {
+ .name = "wd_timer",
+ .sysc = &omap44xx_wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+};
+
+/* wd_timer2 */
+static struct omap_hwmod omap44xx_wd_timer2_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer2_irqs[] = {
+ { .irq = 80 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer2_addrs[] = {
+ {
+ .pa_start = 0x4a314000,
+ .pa_end = 0x4a31407f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_wkup -> wd_timer2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__wd_timer2 = {
+ .master = &omap44xx_l4_wkup_hwmod,
+ .slave = &omap44xx_wd_timer2_hwmod,
+ .clk = "l4_wkup_clk_mux_ck",
+ .addr = omap44xx_wd_timer2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer2_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* wd_timer2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer2_slaves[] = {
+ &omap44xx_l4_wkup__wd_timer2,
+};
+
+static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
+ .name = "wd_timer2",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer2_irqs),
+ .main_clk = "wd_timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_WKUP_WDT2_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* wd_timer3 */
+static struct omap_hwmod omap44xx_wd_timer3_hwmod;
+static struct omap_hwmod_irq_info omap44xx_wd_timer3_irqs[] = {
+ { .irq = 36 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_addrs[] = {
+ {
+ .pa_start = 0x40130000,
+ .pa_end = 0x4013007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> wd_timer3 */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3 = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_wd_timer3_dma_addrs[] = {
+ {
+ .pa_start = 0x49030000,
+ .pa_end = 0x4903007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_abe -> wd_timer3 (dma) */
+static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = {
+ .master = &omap44xx_l4_abe_hwmod,
+ .slave = &omap44xx_wd_timer3_hwmod,
+ .clk = "ocp_abe_iclk",
+ .addr = omap44xx_wd_timer3_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_wd_timer3_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* wd_timer3 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_wd_timer3_slaves[] = {
+ &omap44xx_l4_abe__wd_timer3,
+ &omap44xx_l4_abe__wd_timer3_dma,
+};
+
+static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
+ .name = "wd_timer3",
+ .class = &omap44xx_wd_timer_hwmod_class,
+ .mpu_irqs = omap44xx_wd_timer3_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_wd_timer3_irqs),
+ .main_clk = "wd_timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM1_ABE_WDT3_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_wd_timer3_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
+
+ /* dmm class */
+ &omap44xx_dmm_hwmod,
+
+ /* emif_fw class */
+ &omap44xx_emif_fw_hwmod,
+
+ /* l3 class */
+ &omap44xx_l3_instr_hwmod,
+ &omap44xx_l3_main_1_hwmod,
+ &omap44xx_l3_main_2_hwmod,
+ &omap44xx_l3_main_3_hwmod,
+
+ /* l4 class */
+ &omap44xx_l4_abe_hwmod,
+ &omap44xx_l4_cfg_hwmod,
+ &omap44xx_l4_per_hwmod,
+ &omap44xx_l4_wkup_hwmod,
+
+ /* mpu_bus class */
+ &omap44xx_mpu_private_hwmod,
+
+ /* aess class */
+/* &omap44xx_aess_hwmod, */
+
+ /* bandgap class */
+ &omap44xx_bandgap_hwmod,
+
+ /* counter class */
+/* &omap44xx_counter_32k_hwmod, */
+
+ /* dma class */
+ &omap44xx_dma_system_hwmod,
+
+ /* dmic class */
+ &omap44xx_dmic_hwmod,
+
+ /* dsp class */
+ &omap44xx_dsp_hwmod,
+ &omap44xx_dsp_c0_hwmod,
+
+ /* dss class */
+ &omap44xx_dss_hwmod,
+ &omap44xx_dss_dispc_hwmod,
+ &omap44xx_dss_dsi1_hwmod,
+ &omap44xx_dss_dsi2_hwmod,
+ &omap44xx_dss_hdmi_hwmod,
+ &omap44xx_dss_rfbi_hwmod,
+ &omap44xx_dss_venc_hwmod,
+
+ /* gpio class */
+ &omap44xx_gpio1_hwmod,
+ &omap44xx_gpio2_hwmod,
+ &omap44xx_gpio3_hwmod,
+ &omap44xx_gpio4_hwmod,
+ &omap44xx_gpio5_hwmod,
+ &omap44xx_gpio6_hwmod,
+
+ /* hsi class */
+/* &omap44xx_hsi_hwmod, */
+
+ /* i2c class */
+ &omap44xx_i2c1_hwmod,
+ &omap44xx_i2c2_hwmod,
+ &omap44xx_i2c3_hwmod,
+ &omap44xx_i2c4_hwmod,
+
+ /* ipu class */
+ &omap44xx_ipu_hwmod,
+ &omap44xx_ipu_c0_hwmod,
+ &omap44xx_ipu_c1_hwmod,
+
+ /* iss class */
+/* &omap44xx_iss_hwmod, */
+
+ /* iva class */
+ &omap44xx_iva_hwmod,
+ &omap44xx_iva_seq0_hwmod,
+ &omap44xx_iva_seq1_hwmod,
+
+ /* kbd class */
+ &omap44xx_kbd_hwmod,
+
+ /* mailbox class */
+ &omap44xx_mailbox_hwmod,
+
+ /* mcbsp class */
+ &omap44xx_mcbsp1_hwmod,
+ &omap44xx_mcbsp2_hwmod,
+ &omap44xx_mcbsp3_hwmod,
+ &omap44xx_mcbsp4_hwmod,
+
+ /* mcpdm class */
+/* &omap44xx_mcpdm_hwmod, */
+
+ /* mcspi class */
+ &omap44xx_mcspi1_hwmod,
+ &omap44xx_mcspi2_hwmod,
+ &omap44xx_mcspi3_hwmod,
+ &omap44xx_mcspi4_hwmod,
+
+ /* mmc class */
+ &omap44xx_mmc1_hwmod,
+ &omap44xx_mmc2_hwmod,
+ &omap44xx_mmc3_hwmod,
+ &omap44xx_mmc4_hwmod,
+ &omap44xx_mmc5_hwmod,
+
+ /* mpu class */
+ &omap44xx_mpu_hwmod,
+
+ /* smartreflex class */
+ &omap44xx_smartreflex_core_hwmod,
+ &omap44xx_smartreflex_iva_hwmod,
+ &omap44xx_smartreflex_mpu_hwmod,
+
+ /* spinlock class */
+ &omap44xx_spinlock_hwmod,
+
+ /* timer class */
+ &omap44xx_timer1_hwmod,
+ &omap44xx_timer2_hwmod,
+ &omap44xx_timer3_hwmod,
+ &omap44xx_timer4_hwmod,
+ &omap44xx_timer5_hwmod,
+ &omap44xx_timer6_hwmod,
+ &omap44xx_timer7_hwmod,
+ &omap44xx_timer8_hwmod,
+ &omap44xx_timer9_hwmod,
+ &omap44xx_timer10_hwmod,
+ &omap44xx_timer11_hwmod,
+
+ /* uart class */
+ &omap44xx_uart1_hwmod,
+ &omap44xx_uart2_hwmod,
+ &omap44xx_uart3_hwmod,
+ &omap44xx_uart4_hwmod,
+
+ /* usb_otg_hs class */
+ &omap44xx_usb_otg_hs_hwmod,
+
+ /* wd_timer class */
+ &omap44xx_wd_timer2_hwmod,
+ &omap44xx_wd_timer3_hwmod,
+
+ NULL,
+};
+
+int __init omap44xx_hwmod_init(void)
+{
+ return omap_hwmod_register(omap44xx_hwmods);
+}
+
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c
new file mode 100644
index 00000000..08a13424
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -0,0 +1,71 @@
+/*
+ * omap_hwmod common data structures
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ * Benoît Cousson
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This data/structures are to be used while defining OMAP on-chip module
+ * data and their integration with other OMAP modules and Linux.
+ */
+
+#include <plat/omap_hwmod.h>
+
+#include "omap_hwmod_common_data.h"
+
+/**
+ * struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme.
+ *
+ * To be used by hwmod structure to specify the sysconfig offsets
+ * if the device ip is compliant with the original PRCM protocol
+ * defined for OMAP2420.
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1 = {
+ .midle_shift = SYSC_TYPE1_MIDLEMODE_SHIFT,
+ .clkact_shift = SYSC_TYPE1_CLOCKACTIVITY_SHIFT,
+ .sidle_shift = SYSC_TYPE1_SIDLEMODE_SHIFT,
+ .enwkup_shift = SYSC_TYPE1_ENAWAKEUP_SHIFT,
+ .srst_shift = SYSC_TYPE1_SOFTRESET_SHIFT,
+ .autoidle_shift = SYSC_TYPE1_AUTOIDLE_SHIFT,
+};
+
+/**
+ * struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme.
+ *
+ * To be used by hwmod structure to specify the sysconfig offsets if the
+ * device ip is compliant with the new PRCM protocol defined for new
+ * OMAP4 IPs.
+ */
+struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
+ .midle_shift = SYSC_TYPE2_MIDLEMODE_SHIFT,
+ .sidle_shift = SYSC_TYPE2_SIDLEMODE_SHIFT,
+ .srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT,
+};
+
+
+/*
+ * omap_hwmod class data
+ */
+
+struct omap_hwmod_class l3_hwmod_class = {
+ .name = "l3"
+};
+
+struct omap_hwmod_class l4_hwmod_class = {
+ .name = "l4"
+};
+
+struct omap_hwmod_class mpu_hwmod_class = {
+ .name = "mpu"
+};
+
+struct omap_hwmod_class iva_hwmod_class = {
+ .name = "iva"
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
new file mode 100644
index 00000000..c34e98bf
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -0,0 +1,25 @@
+/*
+ * omap_hwmod_common_data.h - OMAP hwmod common macros and declarations
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Benoît Cousson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_HWMOD_COMMON_DATA_H
+
+#include <plat/omap_hwmod.h>
+
+/* OMAP hwmod classes - forward declarations */
+extern struct omap_hwmod_class l3_hwmod_class;
+extern struct omap_hwmod_class l4_hwmod_class;
+extern struct omap_hwmod_class mpu_hwmod_class;
+extern struct omap_hwmod_class iva_hwmod_class;
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c
new file mode 100644
index 00000000..7b9f1909
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_l3_noc.c
@@ -0,0 +1,248 @@
+/*
+ * OMAP4XXX L3 Interconnect error handling driver
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "omap_l3_noc.h"
+
+/*
+ * Interrupt Handler for L3 error detection.
+ * 1) Identify the L3 clockdomain partition to which the error belongs to.
+ * 2) Identify the slave where the error information is logged
+ * 3) Print the logged information.
+ * 4) Add dump stack to provide kernel trace.
+ *
+ * Two Types of errors :
+ * 1) Custom errors in L3 :
+ * Target like DMM/FW/EMIF generates SRESP=ERR error
+ * 2) Standard L3 error:
+ * - Unsupported CMD.
+ * L3 tries to access target while it is idle
+ * - OCP disconnect.
+ * - Address hole error:
+ * If DSS/ISS/FDIF/USBHOSTFS access a target where they
+ * do not have connectivity, the error is logged in
+ * their default target which is DMM2.
+ *
+ * On High Secure devices, firewall errors are possible and those
+ * can be trapped as well. But the trapping is implemented as part
+ * secure software and hence need not be implemented here.
+ */
+static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
+{
+
+ struct omap4_l3 *l3 = _l3;
+ int inttype, i, j;
+ int err_src = 0;
+ u32 std_err_main_addr, std_err_main, err_reg;
+ u32 base, slave_addr, clear;
+ char *source_name;
+
+ /* Get the Type of interrupt */
+ inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
+
+ for (i = 0; i < L3_MODULES; i++) {
+ /*
+ * Read the regerr register of the clock domain
+ * to determine the source
+ */
+ base = (u32)l3->l3_base[i];
+ err_reg = readl(base + l3_flagmux[i] + (inttype << 3));
+
+ /* Get the corresponding error and analyse */
+ if (err_reg) {
+ /* Identify the source from control status register */
+ for (j = 0; !(err_reg & (1 << j)); j++)
+ ;
+
+ err_src = j;
+ /* Read the stderrlog_main_source from clk domain */
+ std_err_main_addr = base + *(l3_targ[i] + err_src);
+ std_err_main = readl(std_err_main_addr);
+
+ switch (std_err_main & CUSTOM_ERROR) {
+ case STANDARD_ERROR:
+ source_name =
+ l3_targ_stderrlog_main_name[i][err_src];
+
+ slave_addr = std_err_main_addr +
+ L3_SLAVE_ADDRESS_OFFSET;
+ WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n",
+ source_name, readl(slave_addr));
+ /* clear the std error log*/
+ clear = std_err_main | CLEAR_STDERR_LOG;
+ writel(clear, std_err_main_addr);
+ break;
+
+ case CUSTOM_ERROR:
+ source_name =
+ l3_targ_stderrlog_main_name[i][err_src];
+
+ WARN(true, "CUSTOM SRESP error with SOURCE:%s\n",
+ source_name);
+ /* clear the std error log*/
+ clear = std_err_main | CLEAR_STDERR_LOG;
+ writel(clear, std_err_main_addr);
+ break;
+
+ default:
+ /* Nothing to be handled here as of now */
+ break;
+ }
+ /* Error found so break the for loop */
+ break;
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int __init omap4_l3_probe(struct platform_device *pdev)
+{
+ static struct omap4_l3 *l3;
+ struct resource *res;
+ int ret;
+ int irq;
+
+ l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
+ if (!l3)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, l3);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "couldn't find resource 0\n");
+ ret = -ENODEV;
+ goto err0;
+ }
+
+ l3->l3_base[0] = ioremap(res->start, resource_size(res));
+ if (!l3->l3_base[0]) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "couldn't find resource 1\n");
+ ret = -ENODEV;
+ goto err1;
+ }
+
+ l3->l3_base[1] = ioremap(res->start, resource_size(res));
+ if (!l3->l3_base[1]) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+ if (!res) {
+ dev_err(&pdev->dev, "couldn't find resource 2\n");
+ ret = -ENODEV;
+ goto err2;
+ }
+
+ l3->l3_base[2] = ioremap(res->start, resource_size(res));
+ if (!l3->l3_base[2]) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+
+ /*
+ * Setup interrupt Handlers
+ */
+ irq = platform_get_irq(pdev, 0);
+ ret = request_irq(irq,
+ l3_interrupt_handler,
+ IRQF_DISABLED, "l3-dbg-irq", l3);
+ if (ret) {
+ pr_crit("L3: request_irq failed to register for 0x%x\n",
+ OMAP44XX_IRQ_L3_DBG);
+ goto err3;
+ }
+ l3->debug_irq = irq;
+
+ irq = platform_get_irq(pdev, 1);
+ ret = request_irq(irq,
+ l3_interrupt_handler,
+ IRQF_DISABLED, "l3-app-irq", l3);
+ if (ret) {
+ pr_crit("L3: request_irq failed to register for 0x%x\n",
+ OMAP44XX_IRQ_L3_APP);
+ goto err4;
+ }
+ l3->app_irq = irq;
+
+ return 0;
+
+err4:
+ free_irq(l3->debug_irq, l3);
+err3:
+ iounmap(l3->l3_base[2]);
+err2:
+ iounmap(l3->l3_base[1]);
+err1:
+ iounmap(l3->l3_base[0]);
+err0:
+ kfree(l3);
+ return ret;
+}
+
+static int __exit omap4_l3_remove(struct platform_device *pdev)
+{
+ struct omap4_l3 *l3 = platform_get_drvdata(pdev);
+
+ free_irq(l3->app_irq, l3);
+ free_irq(l3->debug_irq, l3);
+ iounmap(l3->l3_base[0]);
+ iounmap(l3->l3_base[1]);
+ iounmap(l3->l3_base[2]);
+ kfree(l3);
+
+ return 0;
+}
+
+static struct platform_driver omap4_l3_driver = {
+ .remove = __exit_p(omap4_l3_remove),
+ .driver = {
+ .name = "omap_l3_noc",
+ },
+};
+
+static int __init omap4_l3_init(void)
+{
+ return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe);
+}
+postcore_initcall_sync(omap4_l3_init);
+
+static void __exit omap4_l3_exit(void)
+{
+ platform_driver_unregister(&omap4_l3_driver);
+}
+module_exit(omap4_l3_exit);
diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h
new file mode 100644
index 00000000..359b8334
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_l3_noc.h
@@ -0,0 +1,132 @@
+ /*
+ * OMAP4XXX L3 Interconnect error handling driver header
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
+
+/*
+ * L3 register offsets
+ */
+#define L3_MODULES 3
+#define CLEAR_STDERR_LOG (1 << 31)
+#define CUSTOM_ERROR 0x2
+#define STANDARD_ERROR 0x0
+#define INBAND_ERROR 0x0
+#define EMIF_KERRLOG_OFFSET 0x10
+#define L3_SLAVE_ADDRESS_OFFSET 0x14
+#define LOGICAL_ADDR_ERRORLOG 0x4
+#define L3_APPLICATION_ERROR 0x0
+#define L3_DEBUG_ERROR 0x1
+
+u32 l3_flagmux[L3_MODULES] = {
+ 0x50C,
+ 0x100C,
+ 0X020C
+};
+
+/*
+ * L3 Target standard Error register offsets
+ */
+u32 l3_targ_stderrlog_main_clk1[] = {
+ 0x148, /* DMM1 */
+ 0x248, /* DMM2 */
+ 0x348, /* ABE */
+ 0x448, /* L4CFG */
+ 0x648 /* CLK2 PWR DISC */
+};
+
+u32 l3_targ_stderrlog_main_clk2[] = {
+ 0x548, /* CORTEX M3 */
+ 0x348, /* DSS */
+ 0x148, /* GPMC */
+ 0x448, /* ISS */
+ 0x748, /* IVAHD */
+ 0xD48, /* missing in TRM corresponds to AES1*/
+ 0x948, /* L4 PER0*/
+ 0x248, /* OCMRAM */
+ 0x148, /* missing in TRM corresponds to GPMC sERROR*/
+ 0x648, /* SGX */
+ 0x848, /* SL2 */
+ 0x1648, /* C2C */
+ 0x1148, /* missing in TRM corresponds PWR DISC CLK1*/
+ 0xF48, /* missing in TRM corrsponds to SHA1*/
+ 0xE48, /* missing in TRM corresponds to AES2*/
+ 0xC48, /* L4 PER3 */
+ 0xA48, /* L4 PER1*/
+ 0xB48 /* L4 PER2*/
+};
+
+u32 l3_targ_stderrlog_main_clk3[] = {
+ 0x0148 /* EMUSS */
+};
+
+char *l3_targ_stderrlog_main_name[L3_MODULES][18] = {
+ {
+ "DMM1",
+ "DMM2",
+ "ABE",
+ "L4CFG",
+ "CLK2 PWR DISC",
+ },
+ {
+ "CORTEX M3" ,
+ "DSS ",
+ "GPMC ",
+ "ISS ",
+ "IVAHD ",
+ "AES1",
+ "L4 PER0",
+ "OCMRAM ",
+ "GPMC sERROR",
+ "SGX ",
+ "SL2 ",
+ "C2C ",
+ "PWR DISC CLK1",
+ "SHA1",
+ "AES2",
+ "L4 PER3",
+ "L4 PER1",
+ "L4 PER2",
+ },
+ {
+ "EMUSS",
+ },
+};
+
+u32 *l3_targ[L3_MODULES] = {
+ l3_targ_stderrlog_main_clk1,
+ l3_targ_stderrlog_main_clk2,
+ l3_targ_stderrlog_main_clk3,
+};
+
+struct omap4_l3 {
+ struct device *dev;
+ struct clk *ick;
+
+ /* memory base */
+ void __iomem *l3_base[4];
+
+ int debug_irq;
+ int app_irq;
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c
new file mode 100644
index 00000000..873c0e33
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_l3_smx.c
@@ -0,0 +1,299 @@
+ /*
+ * OMAP3XXX L3 Interconnect Driver
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Felipe Balbi <balbi@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/slab.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include "omap_l3_smx.h"
+
+static inline u64 omap3_l3_readll(void __iomem *base, u16 reg)
+{
+ return __raw_readll(base + reg);
+}
+
+static inline void omap3_l3_writell(void __iomem *base, u16 reg, u64 value)
+{
+ __raw_writell(value, base + reg);
+}
+
+static inline enum omap3_l3_code omap3_l3_decode_error_code(u64 error)
+{
+ return (error & 0x0f000000) >> L3_ERROR_LOG_CODE;
+}
+
+static inline u32 omap3_l3_decode_addr(u64 error_addr)
+{
+ return error_addr & 0xffffffff;
+}
+
+static inline unsigned omap3_l3_decode_cmd(u64 error)
+{
+ return (error & 0x07) >> L3_ERROR_LOG_CMD;
+}
+
+static inline enum omap3_l3_initiator_id omap3_l3_decode_initid(u64 error)
+{
+ return (error & 0xff00) >> L3_ERROR_LOG_INITID;
+}
+
+static inline unsigned omap3_l3_decode_req_info(u64 error)
+{
+ return (error >> 32) & 0xffff;
+}
+
+static char *omap3_l3_code_string(u8 code)
+{
+ switch (code) {
+ case OMAP_L3_CODE_NOERROR:
+ return "No Error";
+ case OMAP_L3_CODE_UNSUP_CMD:
+ return "Unsupported Command";
+ case OMAP_L3_CODE_ADDR_HOLE:
+ return "Address Hole";
+ case OMAP_L3_CODE_PROTECT_VIOLATION:
+ return "Protection Violation";
+ case OMAP_L3_CODE_IN_BAND_ERR:
+ return "In-band Error";
+ case OMAP_L3_CODE_REQ_TOUT_NOT_ACCEPT:
+ return "Request Timeout Not Accepted";
+ case OMAP_L3_CODE_REQ_TOUT_NO_RESP:
+ return "Request Timeout, no response";
+ default:
+ return "UNKNOWN error";
+ }
+}
+
+static char *omap3_l3_initiator_string(u8 initid)
+{
+ switch (initid) {
+ case OMAP_L3_LCD:
+ return "LCD";
+ case OMAP_L3_SAD2D:
+ return "SAD2D";
+ case OMAP_L3_IA_MPU_SS_1:
+ case OMAP_L3_IA_MPU_SS_2:
+ case OMAP_L3_IA_MPU_SS_3:
+ case OMAP_L3_IA_MPU_SS_4:
+ case OMAP_L3_IA_MPU_SS_5:
+ return "MPU";
+ case OMAP_L3_IA_IVA_SS_1:
+ case OMAP_L3_IA_IVA_SS_2:
+ case OMAP_L3_IA_IVA_SS_3:
+ return "IVA_SS";
+ case OMAP_L3_IA_IVA_SS_DMA_1:
+ case OMAP_L3_IA_IVA_SS_DMA_2:
+ case OMAP_L3_IA_IVA_SS_DMA_3:
+ case OMAP_L3_IA_IVA_SS_DMA_4:
+ case OMAP_L3_IA_IVA_SS_DMA_5:
+ case OMAP_L3_IA_IVA_SS_DMA_6:
+ return "IVA_SS_DMA";
+ case OMAP_L3_IA_SGX:
+ return "SGX";
+ case OMAP_L3_IA_CAM_1:
+ case OMAP_L3_IA_CAM_2:
+ case OMAP_L3_IA_CAM_3:
+ return "CAM";
+ case OMAP_L3_IA_DAP:
+ return "DAP";
+ case OMAP_L3_SDMA_WR_1:
+ case OMAP_L3_SDMA_WR_2:
+ return "SDMA_WR";
+ case OMAP_L3_SDMA_RD_1:
+ case OMAP_L3_SDMA_RD_2:
+ case OMAP_L3_SDMA_RD_3:
+ case OMAP_L3_SDMA_RD_4:
+ return "SDMA_RD";
+ case OMAP_L3_USBOTG:
+ return "USB_OTG";
+ case OMAP_L3_USBHOST:
+ return "USB_HOST";
+ default:
+ return "UNKNOWN Initiator";
+ }
+}
+
+/**
+ * omap3_l3_block_irq - handles a register block's irq
+ * @l3: struct omap3_l3 *
+ * @base: register block base address
+ * @error: L3_ERROR_LOG register of our block
+ *
+ * Called in hard-irq context. Caller should take care of locking
+ *
+ * OMAP36xx TRM gives, on page 2001, Figure 9-10, the Typical Error
+ * Analysis Sequence, we are following that sequence here, please
+ * refer to that Figure for more information on the subject.
+ */
+static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3,
+ u64 error, int error_addr)
+{
+ u8 code = omap3_l3_decode_error_code(error);
+ u8 initid = omap3_l3_decode_initid(error);
+ u8 multi = error & L3_ERROR_LOG_MULTI;
+ u32 address = omap3_l3_decode_addr(error_addr);
+
+ WARN(true, "%s seen by %s %s at address %x\n",
+ omap3_l3_code_string(code),
+ omap3_l3_initiator_string(initid),
+ multi ? "Multiple Errors" : "",
+ address);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
+{
+ struct omap3_l3 *l3 = _l3;
+ u64 status, clear;
+ u64 error;
+ u64 error_addr;
+ u64 err_source = 0;
+ void __iomem *base;
+ int int_type;
+ irqreturn_t ret = IRQ_NONE;
+
+ int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
+ if (!int_type) {
+ status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_0);
+ /*
+ * if we have a timeout error, there's nothing we can
+ * do besides rebooting the board. So let's BUG on any
+ * of such errors and handle the others. timeout error
+ * is severe and not expected to occur.
+ */
+ BUG_ON(status & L3_STATUS_0_TIMEOUT_MASK);
+ } else {
+ status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_1);
+ /* No timeout error for debug sources */
+ }
+
+ /* identify the error source */
+ for (err_source = 0; !(status & (1 << err_source)); err_source++)
+ ;
+
+ base = l3->rt + *(omap3_l3_bases[int_type] + err_source);
+ error = omap3_l3_readll(base, L3_ERROR_LOG);
+ if (error) {
+ error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR);
+
+ ret |= omap3_l3_block_irq(l3, error, error_addr);
+ }
+
+ /* Clear the status register */
+ clear = (L3_AGENT_STATUS_CLEAR_IA << int_type) |
+ L3_AGENT_STATUS_CLEAR_TA;
+ omap3_l3_writell(base, L3_AGENT_STATUS, clear);
+
+ /* clear the error log register */
+ omap3_l3_writell(base, L3_ERROR_LOG, error);
+
+ return ret;
+}
+
+static int __init omap3_l3_probe(struct platform_device *pdev)
+{
+ struct omap3_l3 *l3;
+ struct resource *res;
+ int ret;
+
+ l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
+ if (!l3)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, l3);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "couldn't find resource\n");
+ ret = -ENODEV;
+ goto err0;
+ }
+ l3->rt = ioremap(res->start, resource_size(res));
+ if (!l3->rt) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err0;
+ }
+
+ l3->debug_irq = platform_get_irq(pdev, 0);
+ ret = request_irq(l3->debug_irq, omap3_l3_app_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ "l3-debug-irq", l3);
+ if (ret) {
+ dev_err(&pdev->dev, "couldn't request debug irq\n");
+ goto err1;
+ }
+
+ l3->app_irq = platform_get_irq(pdev, 1);
+ ret = request_irq(l3->app_irq, omap3_l3_app_irq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ "l3-app-irq", l3);
+ if (ret) {
+ dev_err(&pdev->dev, "couldn't request app irq\n");
+ goto err2;
+ }
+
+ return 0;
+
+err2:
+ free_irq(l3->debug_irq, l3);
+err1:
+ iounmap(l3->rt);
+err0:
+ kfree(l3);
+ return ret;
+}
+
+static int __exit omap3_l3_remove(struct platform_device *pdev)
+{
+ struct omap3_l3 *l3 = platform_get_drvdata(pdev);
+
+ free_irq(l3->app_irq, l3);
+ free_irq(l3->debug_irq, l3);
+ iounmap(l3->rt);
+ kfree(l3);
+
+ return 0;
+}
+
+static struct platform_driver omap3_l3_driver = {
+ .remove = __exit_p(omap3_l3_remove),
+ .driver = {
+ .name = "omap_l3_smx",
+ },
+};
+
+static int __init omap3_l3_init(void)
+{
+ return platform_driver_probe(&omap3_l3_driver, omap3_l3_probe);
+}
+postcore_initcall_sync(omap3_l3_init);
+
+static void __exit omap3_l3_exit(void)
+{
+ platform_driver_unregister(&omap3_l3_driver);
+}
+module_exit(omap3_l3_exit);
diff --git a/arch/arm/mach-omap2/omap_l3_smx.h b/arch/arm/mach-omap2/omap_l3_smx.h
new file mode 100644
index 00000000..ba2ed9a8
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_l3_smx.h
@@ -0,0 +1,338 @@
+ /*
+ * OMAP3XXX L3 Interconnect Driver header
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Felipe Balbi <balbi@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
+
+/* Register definitions. All 64-bit wide */
+#define L3_COMPONENT 0x000
+#define L3_CORE 0x018
+#define L3_AGENT_CONTROL 0x020
+#define L3_AGENT_STATUS 0x028
+#define L3_ERROR_LOG 0x058
+
+#define L3_ERROR_LOG_MULTI (1 << 31)
+#define L3_ERROR_LOG_SECONDARY (1 << 30)
+
+#define L3_ERROR_LOG_ADDR 0x060
+
+/* Register definitions for Sideband Interconnect */
+#define L3_SI_CONTROL 0x020
+#define L3_SI_FLAG_STATUS_0 0x510
+
+const u64 shift = 1;
+
+#define L3_STATUS_0_MPUIA_BRST (shift << 0)
+#define L3_STATUS_0_MPUIA_RSP (shift << 1)
+#define L3_STATUS_0_MPUIA_INBAND (shift << 2)
+#define L3_STATUS_0_IVAIA_BRST (shift << 6)
+#define L3_STATUS_0_IVAIA_RSP (shift << 7)
+#define L3_STATUS_0_IVAIA_INBAND (shift << 8)
+#define L3_STATUS_0_SGXIA_BRST (shift << 9)
+#define L3_STATUS_0_SGXIA_RSP (shift << 10)
+#define L3_STATUS_0_SGXIA_MERROR (shift << 11)
+#define L3_STATUS_0_CAMIA_BRST (shift << 12)
+#define L3_STATUS_0_CAMIA_RSP (shift << 13)
+#define L3_STATUS_0_CAMIA_INBAND (shift << 14)
+#define L3_STATUS_0_DISPIA_BRST (shift << 15)
+#define L3_STATUS_0_DISPIA_RSP (shift << 16)
+#define L3_STATUS_0_DMARDIA_BRST (shift << 18)
+#define L3_STATUS_0_DMARDIA_RSP (shift << 19)
+#define L3_STATUS_0_DMAWRIA_BRST (shift << 21)
+#define L3_STATUS_0_DMAWRIA_RSP (shift << 22)
+#define L3_STATUS_0_USBOTGIA_BRST (shift << 24)
+#define L3_STATUS_0_USBOTGIA_RSP (shift << 25)
+#define L3_STATUS_0_USBOTGIA_INBAND (shift << 26)
+#define L3_STATUS_0_USBHOSTIA_BRST (shift << 27)
+#define L3_STATUS_0_USBHOSTIA_INBAND (shift << 28)
+#define L3_STATUS_0_SMSTA_REQ (shift << 48)
+#define L3_STATUS_0_GPMCTA_REQ (shift << 49)
+#define L3_STATUS_0_OCMRAMTA_REQ (shift << 50)
+#define L3_STATUS_0_OCMROMTA_REQ (shift << 51)
+#define L3_STATUS_0_IVATA_REQ (shift << 54)
+#define L3_STATUS_0_SGXTA_REQ (shift << 55)
+#define L3_STATUS_0_SGXTA_SERROR (shift << 56)
+#define L3_STATUS_0_GPMCTA_SERROR (shift << 57)
+#define L3_STATUS_0_L4CORETA_REQ (shift << 58)
+#define L3_STATUS_0_L4PERTA_REQ (shift << 59)
+#define L3_STATUS_0_L4EMUTA_REQ (shift << 60)
+#define L3_STATUS_0_MAD2DTA_REQ (shift << 61)
+
+#define L3_STATUS_0_TIMEOUT_MASK (L3_STATUS_0_MPUIA_BRST \
+ | L3_STATUS_0_MPUIA_RSP \
+ | L3_STATUS_0_IVAIA_BRST \
+ | L3_STATUS_0_IVAIA_RSP \
+ | L3_STATUS_0_SGXIA_BRST \
+ | L3_STATUS_0_SGXIA_RSP \
+ | L3_STATUS_0_CAMIA_BRST \
+ | L3_STATUS_0_CAMIA_RSP \
+ | L3_STATUS_0_DISPIA_BRST \
+ | L3_STATUS_0_DISPIA_RSP \
+ | L3_STATUS_0_DMARDIA_BRST \
+ | L3_STATUS_0_DMARDIA_RSP \
+ | L3_STATUS_0_DMAWRIA_BRST \
+ | L3_STATUS_0_DMAWRIA_RSP \
+ | L3_STATUS_0_USBOTGIA_BRST \
+ | L3_STATUS_0_USBOTGIA_RSP \
+ | L3_STATUS_0_USBHOSTIA_BRST \
+ | L3_STATUS_0_SMSTA_REQ \
+ | L3_STATUS_0_GPMCTA_REQ \
+ | L3_STATUS_0_OCMRAMTA_REQ \
+ | L3_STATUS_0_OCMROMTA_REQ \
+ | L3_STATUS_0_IVATA_REQ \
+ | L3_STATUS_0_SGXTA_REQ \
+ | L3_STATUS_0_L4CORETA_REQ \
+ | L3_STATUS_0_L4PERTA_REQ \
+ | L3_STATUS_0_L4EMUTA_REQ \
+ | L3_STATUS_0_MAD2DTA_REQ)
+
+#define L3_SI_FLAG_STATUS_1 0x530
+
+#define L3_STATUS_1_MPU_DATAIA (1 << 0)
+#define L3_STATUS_1_DAPIA0 (1 << 3)
+#define L3_STATUS_1_DAPIA1 (1 << 4)
+#define L3_STATUS_1_IVAIA (1 << 6)
+
+#define L3_PM_ERROR_LOG 0x020
+#define L3_PM_CONTROL 0x028
+#define L3_PM_ERROR_CLEAR_SINGLE 0x030
+#define L3_PM_ERROR_CLEAR_MULTI 0x038
+#define L3_PM_REQ_INFO_PERMISSION(n) (0x048 + (0x020 * n))
+#define L3_PM_READ_PERMISSION(n) (0x050 + (0x020 * n))
+#define L3_PM_WRITE_PERMISSION(n) (0x058 + (0x020 * n))
+#define L3_PM_ADDR_MATCH(n) (0x060 + (0x020 * n))
+
+/* L3 error log bit fields. Common for IA and TA */
+#define L3_ERROR_LOG_CODE 24
+#define L3_ERROR_LOG_INITID 8
+#define L3_ERROR_LOG_CMD 0
+
+/* L3 agent status bit fields. */
+#define L3_AGENT_STATUS_CLEAR_IA 0x10000000
+#define L3_AGENT_STATUS_CLEAR_TA 0x01000000
+
+#define OMAP34xx_IRQ_L3_APP 10
+#define L3_APPLICATION_ERROR 0x0
+#define L3_DEBUG_ERROR 0x1
+
+enum omap3_l3_initiator_id {
+ /* LCD has 1 ID */
+ OMAP_L3_LCD = 29,
+ /* SAD2D has 1 ID */
+ OMAP_L3_SAD2D = 28,
+ /* MPU has 5 IDs */
+ OMAP_L3_IA_MPU_SS_1 = 27,
+ OMAP_L3_IA_MPU_SS_2 = 26,
+ OMAP_L3_IA_MPU_SS_3 = 25,
+ OMAP_L3_IA_MPU_SS_4 = 24,
+ OMAP_L3_IA_MPU_SS_5 = 23,
+ /* IVA2.2 SS has 3 IDs*/
+ OMAP_L3_IA_IVA_SS_1 = 22,
+ OMAP_L3_IA_IVA_SS_2 = 21,
+ OMAP_L3_IA_IVA_SS_3 = 20,
+ /* IVA 2.2 SS DMA has 6 IDS */
+ OMAP_L3_IA_IVA_SS_DMA_1 = 19,
+ OMAP_L3_IA_IVA_SS_DMA_2 = 18,
+ OMAP_L3_IA_IVA_SS_DMA_3 = 17,
+ OMAP_L3_IA_IVA_SS_DMA_4 = 16,
+ OMAP_L3_IA_IVA_SS_DMA_5 = 15,
+ OMAP_L3_IA_IVA_SS_DMA_6 = 14,
+ /* SGX has 1 ID */
+ OMAP_L3_IA_SGX = 13,
+ /* CAM has 3 ID */
+ OMAP_L3_IA_CAM_1 = 12,
+ OMAP_L3_IA_CAM_2 = 11,
+ OMAP_L3_IA_CAM_3 = 10,
+ /* DAP has 1 ID */
+ OMAP_L3_IA_DAP = 9,
+ /* SDMA WR has 2 IDs */
+ OMAP_L3_SDMA_WR_1 = 8,
+ OMAP_L3_SDMA_WR_2 = 7,
+ /* SDMA RD has 4 IDs */
+ OMAP_L3_SDMA_RD_1 = 6,
+ OMAP_L3_SDMA_RD_2 = 5,
+ OMAP_L3_SDMA_RD_3 = 4,
+ OMAP_L3_SDMA_RD_4 = 3,
+ /* HSUSB OTG has 1 ID */
+ OMAP_L3_USBOTG = 2,
+ /* HSUSB HOST has 1 ID */
+ OMAP_L3_USBHOST = 1,
+};
+
+enum omap3_l3_code {
+ OMAP_L3_CODE_NOERROR = 0,
+ OMAP_L3_CODE_UNSUP_CMD = 1,
+ OMAP_L3_CODE_ADDR_HOLE = 2,
+ OMAP_L3_CODE_PROTECT_VIOLATION = 3,
+ OMAP_L3_CODE_IN_BAND_ERR = 4,
+ /* codes 5 and 6 are reserved */
+ OMAP_L3_CODE_REQ_TOUT_NOT_ACCEPT = 7,
+ OMAP_L3_CODE_REQ_TOUT_NO_RESP = 8,
+ /* codes 9 - 15 are also reserved */
+};
+
+struct omap3_l3 {
+ struct device *dev;
+ struct clk *ick;
+
+ /* memory base*/
+ void __iomem *rt;
+
+ int debug_irq;
+ int app_irq;
+
+ /* true when and inband functional error occurs */
+ unsigned inband:1;
+};
+
+/* offsets for l3 agents in order with the Flag status register */
+unsigned int __iomem omap3_l3_app_bases[] = {
+ /* MPU IA */
+ 0x1400,
+ 0x1400,
+ 0x1400,
+ /* RESERVED */
+ 0,
+ 0,
+ 0,
+ /* IVA 2.2 IA */
+ 0x1800,
+ 0x1800,
+ 0x1800,
+ /* SGX IA */
+ 0x1c00,
+ 0x1c00,
+ /* RESERVED */
+ 0,
+ /* CAMERA IA */
+ 0x5800,
+ 0x5800,
+ 0x5800,
+ /* DISPLAY IA */
+ 0x5400,
+ 0x5400,
+ /* RESERVED */
+ 0,
+ /*SDMA RD IA */
+ 0x4c00,
+ 0x4c00,
+ /* RESERVED */
+ 0,
+ /* SDMA WR IA */
+ 0x5000,
+ 0x5000,
+ /* RESERVED */
+ 0,
+ /* USB OTG IA */
+ 0x4400,
+ 0x4400,
+ 0x4400,
+ /* USB HOST IA */
+ 0x4000,
+ 0x4000,
+ /* RESERVED */
+ 0,
+ 0,
+ 0,
+ 0,
+ /* SAD2D IA */
+ 0x3000,
+ 0x3000,
+ 0x3000,
+ /* RESERVED */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ /* SMA TA */
+ 0x2000,
+ /* GPMC TA */
+ 0x2400,
+ /* OCM RAM TA */
+ 0x2800,
+ /* OCM ROM TA */
+ 0x2C00,
+ /* L4 CORE TA */
+ 0x6800,
+ /* L4 PER TA */
+ 0x6c00,
+ /* IVA 2.2 TA */
+ 0x6000,
+ /* SGX TA */
+ 0x6400,
+ /* L4 EMU TA */
+ 0x7000,
+ /* GPMC TA */
+ 0x2400,
+ /* L4 CORE TA */
+ 0x6800,
+ /* L4 PER TA */
+ 0x6c00,
+ /* L4 EMU TA */
+ 0x7000,
+ /* MAD2D TA */
+ 0x3400,
+ /* RESERVED */
+ 0,
+ 0,
+};
+
+unsigned int __iomem omap3_l3_debug_bases[] = {
+ /* MPU DATA IA */
+ 0x1400,
+ /* RESERVED */
+ 0,
+ 0,
+ /* DAP IA */
+ 0x5c00,
+ 0x5c00,
+ /* RESERVED */
+ 0,
+ /* IVA 2.2 IA */
+ 0x1800,
+ /* REST RESERVED */
+};
+
+u32 *omap3_l3_bases[] = {
+ omap3_l3_app_bases,
+ omap3_l3_debug_bases,
+};
+
+/*
+ * REVISIT define __raw_readll/__raw_writell here, but move them to
+ * <asm/io.h> at some point
+ */
+#define __raw_writell(v, a) (__chk_io_ptr(a), \
+ *(volatile u64 __force *)(a) = (v))
+#define __raw_readll(a) (__chk_io_ptr(a), \
+ *(volatile u64 __force *)(a))
+
+#endif
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
new file mode 100644
index 00000000..c784c12f
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -0,0 +1,96 @@
+/*
+ * OMAP SoC specific OPP Data helpers
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "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 __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
+
+#include <plat/omap_hwmod.h>
+
+#include "voltage.h"
+
+/*
+ * *BIG FAT WARNING*:
+ * USE the following ONLY in opp data initialization common to an SoC.
+ * DO NOT USE these in board files/pm core etc.
+ */
+
+/**
+ * struct omap_opp_def - OMAP OPP Definition
+ * @hwmod_name: Name of the hwmod for this domain
+ * @freq: Frequency in hertz corresponding to this OPP
+ * @u_volt: Nominal voltage in microvolts corresponding to this OPP
+ * @default_available: True/false - is this OPP available by default
+ *
+ * OMAP SOCs have a standard set of tuples consisting of frequency and voltage
+ * pairs that the device will support per voltage domain. This is called
+ * Operating Points or OPP. The actual definitions of OMAP Operating Points
+ * varies over silicon within the same family of devices. For a specific
+ * domain, you can have a set of {frequency, voltage} pairs and this is denoted
+ * by an array of omap_opp_def. As the kernel boots and more information is
+ * available, a set of these are activated based on the precise nature of
+ * device the kernel boots up on. It is interesting to remember that each IP
+ * which belongs to a voltage domain may define their own set of OPPs on top
+ * of this - but this is handled by the appropriate driver.
+ */
+struct omap_opp_def {
+ char *hwmod_name;
+
+ unsigned long freq;
+ unsigned long u_volt;
+
+ bool default_available;
+};
+
+/*
+ * Initialization wrapper used to define an OPP for OMAP variants.
+ */
+#define OPP_INITIALIZER(_hwmod_name, _enabled, _freq, _uv) \
+{ \
+ .hwmod_name = _hwmod_name, \
+ .default_available = _enabled, \
+ .freq = _freq, \
+ .u_volt = _uv, \
+}
+
+/*
+ * Initialization wrapper used to define SmartReflex process data
+ * XXX Is this needed? Just use C99 initializers in data files?
+ */
+#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \
+{ \
+ .volt_nominal = _v_nom, \
+ .sr_efuse_offs = _efuse_offs, \
+ .sr_errminlimit = _errminlimit, \
+ .vp_errgain = _errgain \
+}
+
+/* Use this to initialize the default table */
+extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
+ u32 opp_def_size);
+
+
+extern struct omap_volt_data omap34xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap34xx_vddcore_volt_data[];
+extern struct omap_volt_data omap36xx_vddmpu_volt_data[];
+extern struct omap_volt_data omap36xx_vddcore_volt_data[];
+
+extern struct omap_volt_data omap44xx_vdd_mpu_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_iva_volt_data[];
+extern struct omap_volt_data omap44xx_vdd_core_volt_data[];
+
+#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
new file mode 100644
index 00000000..58775e3c
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -0,0 +1,262 @@
+/*
+ * This file configures the internal USB PHY in OMAP4430. Used
+ * with TWL6030 transceiver and MUSB on OMAP4430.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Author: Hema HK <hemahk@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/types.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/usb.h>
+
+#include <plat/usb.h>
+#include "control.h"
+
+/* OMAP control module register for UTMI PHY */
+#define CONTROL_DEV_CONF 0x300
+#define PHY_PD 0x1
+
+#define USBOTGHS_CONTROL 0x33c
+#define AVALID BIT(0)
+#define BVALID BIT(1)
+#define VBUSVALID BIT(2)
+#define SESSEND BIT(3)
+#define IDDIG BIT(4)
+
+static struct clk *phyclk, *clk48m, *clk32k;
+static void __iomem *ctrl_base;
+static int usbotghs_control;
+
+int omap4430_phy_init(struct device *dev)
+{
+ ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
+ if (!ctrl_base) {
+ pr_err("control module ioremap failed\n");
+ return -ENOMEM;
+ }
+ /* Power down the phy */
+ __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+
+ if (!dev) {
+ iounmap(ctrl_base);
+ return 0;
+ }
+
+ phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
+ if (IS_ERR(phyclk)) {
+ dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
+ iounmap(ctrl_base);
+ return PTR_ERR(phyclk);
+ }
+
+ clk48m = clk_get(dev, "ocp2scp_usb_phy_phy_48m");
+ if (IS_ERR(clk48m)) {
+ dev_err(dev, "cannot clk_get ocp2scp_usb_phy_phy_48m\n");
+ clk_put(phyclk);
+ iounmap(ctrl_base);
+ return PTR_ERR(clk48m);
+ }
+
+ clk32k = clk_get(dev, "usb_phy_cm_clk32k");
+ if (IS_ERR(clk32k)) {
+ dev_err(dev, "cannot clk_get usb_phy_cm_clk32k\n");
+ clk_put(phyclk);
+ clk_put(clk48m);
+ iounmap(ctrl_base);
+ return PTR_ERR(clk32k);
+ }
+ return 0;
+}
+
+int omap4430_phy_set_clk(struct device *dev, int on)
+{
+ static int state;
+
+ if (on && !state) {
+ /* Enable the phy clocks */
+ clk_enable(phyclk);
+ clk_enable(clk48m);
+ clk_enable(clk32k);
+ state = 1;
+ } else if (state) {
+ /* Disable the phy clocks */
+ clk_disable(phyclk);
+ clk_disable(clk48m);
+ clk_disable(clk32k);
+ state = 0;
+ }
+ return 0;
+}
+
+int omap4430_phy_power(struct device *dev, int ID, int on)
+{
+ if (on) {
+ if (ID)
+ /* enable VBUS valid, IDDIG groung */
+ __raw_writel(AVALID | VBUSVALID, ctrl_base +
+ USBOTGHS_CONTROL);
+ else
+ /*
+ * Enable VBUS Valid, AValid and IDDIG
+ * high impedance
+ */
+ __raw_writel(IDDIG | AVALID | VBUSVALID,
+ ctrl_base + USBOTGHS_CONTROL);
+ } else {
+ /* Enable session END and IDIG to high impedance. */
+ __raw_writel(SESSEND | IDDIG, ctrl_base +
+ USBOTGHS_CONTROL);
+ }
+ return 0;
+}
+
+int omap4430_phy_suspend(struct device *dev, int suspend)
+{
+ if (suspend) {
+ /* Disable the clocks */
+ omap4430_phy_set_clk(dev, 0);
+ /* Power down the phy */
+ __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+
+ /* save the context */
+ usbotghs_control = __raw_readl(ctrl_base + USBOTGHS_CONTROL);
+ } else {
+ /* Enable the internel phy clcoks */
+ omap4430_phy_set_clk(dev, 1);
+ /* power on the phy */
+ if (__raw_readl(ctrl_base + CONTROL_DEV_CONF) & PHY_PD) {
+ __raw_writel(~PHY_PD, ctrl_base + CONTROL_DEV_CONF);
+ mdelay(200);
+ }
+
+ /* restore the context */
+ __raw_writel(usbotghs_control, ctrl_base + USBOTGHS_CONTROL);
+ }
+
+ return 0;
+}
+
+int omap4430_phy_exit(struct device *dev)
+{
+ if (ctrl_base)
+ iounmap(ctrl_base);
+ if (phyclk)
+ clk_put(phyclk);
+ if (clk48m)
+ clk_put(clk48m);
+ if (clk32k)
+ clk_put(clk32k);
+
+ return 0;
+}
+
+void am35x_musb_reset(void)
+{
+ u32 regval;
+
+ /* Reset the musb interface */
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+
+ regval |= AM35XX_USBOTGSS_SW_RST;
+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+
+ regval &= ~AM35XX_USBOTGSS_SW_RST;
+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+}
+
+void am35x_musb_phy_power(u8 on)
+{
+ unsigned long timeout = jiffies + msecs_to_jiffies(100);
+ u32 devconf2;
+
+ if (on) {
+ /*
+ * Start the on-chip PHY and its PLL.
+ */
+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
+ devconf2 |= CONF2_PHY_PLLON;
+
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+ pr_info(KERN_INFO "Waiting for PHY clock good...\n");
+ while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
+ & CONF2_PHYCLKGD)) {
+ cpu_relax();
+
+ if (time_after(jiffies, timeout)) {
+ pr_err(KERN_ERR "musb PHY clock good timed out\n");
+ break;
+ }
+ }
+ } else {
+ /*
+ * Power down the on-chip PHY.
+ */
+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ devconf2 &= ~CONF2_PHY_PLLON;
+ devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN;
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+ }
+}
+
+void am35x_musb_clear_irq(void)
+{
+ u32 regval;
+
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval |= AM35XX_USBOTGSS_INT_CLR;
+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+void am35x_set_mode(u8 musb_mode)
+{
+ u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+ devconf2 &= ~CONF2_OTGMODE;
+ switch (musb_mode) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+ case MUSB_HOST: /* Force VBUS valid, ID = 0 */
+ devconf2 |= CONF2_FORCE_HOST;
+ break;
+#endif
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+ case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */
+ devconf2 |= CONF2_FORCE_DEVICE;
+ break;
+#endif
+#ifdef CONFIG_USB_MUSB_OTG
+ case MUSB_OTG: /* Don't override the VBUS/ID comparators */
+ devconf2 |= CONF2_NO_OVERRIDE;
+ break;
+#endif
+ default:
+ pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
+ }
+
+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+}
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
new file mode 100644
index 00000000..07d6140b
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -0,0 +1,339 @@
+/**
+ * OMAP and TWL PMIC specific intializations.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated.
+ * Thara Gopinath
+ * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Nishanth Menon
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/i2c/twl.h>
+
+#include "voltage.h"
+
+#include "pm.h"
+
+#define OMAP3_SRI2C_SLAVE_ADDR 0x12
+#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
+#define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01
+#define OMAP3_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP3_VP_VSTEPMIN_VSTEPMIN 0x1
+#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
+
+#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
+#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
+#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
+#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
+
+#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
+#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
+#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
+#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
+
+#define OMAP4_SRI2C_SLAVE_ADDR 0x12
+#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
+
+#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
+#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
+
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
+
+static bool is_offset_valid;
+static u8 smps_offset;
+/*
+ * Flag to ensure Smartreflex bit in TWL
+ * being cleared in board file is not overwritten.
+ */
+static bool __initdata twl_sr_enable_autoinit;
+
+#define TWL4030_DCDC_GLOBAL_CFG 0x06
+#define REG_SMPS_OFFSET 0xE0
+#define SMARTREFLEX_ENABLE BIT(3)
+
+static unsigned long twl4030_vsel_to_uv(const u8 vsel)
+{
+ return (((vsel * 125) + 6000)) * 100;
+}
+
+static u8 twl4030_uv_to_vsel(unsigned long uv)
+{
+ return DIV_ROUND_UP(uv - 600000, 12500);
+}
+
+static unsigned long twl6030_vsel_to_uv(const u8 vsel)
+{
+ /*
+ * In TWL6030 depending on the value of SMPS_OFFSET
+ * efuse register the voltage range supported in
+ * standard mode can be either between 0.6V - 1.3V or
+ * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
+ * is programmed to all 0's where as starting from
+ * TWL6030 ES1.1 the efuse is programmed to 1
+ */
+ if (!is_offset_valid) {
+ twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
+ REG_SMPS_OFFSET);
+ is_offset_valid = true;
+ }
+
+ /*
+ * There is no specific formula for voltage to vsel
+ * conversion above 1.3V. There are special hardcoded
+ * values for voltages above 1.3V. Currently we are
+ * hardcoding only for 1.35 V which is used for 1GH OPP for
+ * OMAP4430.
+ */
+ if (vsel == 0x3A)
+ return 1350000;
+
+ if (smps_offset & 0x8)
+ return ((((vsel - 1) * 125) + 7000)) * 100;
+ else
+ return ((((vsel - 1) * 125) + 6000)) * 100;
+}
+
+static u8 twl6030_uv_to_vsel(unsigned long uv)
+{
+ /*
+ * In TWL6030 depending on the value of SMPS_OFFSET
+ * efuse register the voltage range supported in
+ * standard mode can be either between 0.6V - 1.3V or
+ * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
+ * is programmed to all 0's where as starting from
+ * TWL6030 ES1.1 the efuse is programmed to 1
+ */
+ if (!is_offset_valid) {
+ twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
+ REG_SMPS_OFFSET);
+ is_offset_valid = true;
+ }
+
+ /*
+ * There is no specific formula for voltage to vsel
+ * conversion above 1.3V. There are special hardcoded
+ * values for voltages above 1.3V. Currently we are
+ * hardcoding only for 1.35 V which is used for 1GH OPP for
+ * OMAP4430.
+ */
+ if (uv == 1350000)
+ return 0x3A;
+
+ if (smps_offset & 0x8)
+ return DIV_ROUND_UP(uv - 700000, 12500) + 1;
+ else
+ return DIV_ROUND_UP(uv - 600000, 12500) + 1;
+}
+
+static struct omap_volt_pmic_info omap3_mpu_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1200000,
+ .onlp_volt = 1000000,
+ .ret_volt = 975000,
+ .off_volt = 600000,
+ .volt_setup_time = 0xfff,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap3_core_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1200000,
+ .onlp_volt = 1000000,
+ .ret_volt = 975000,
+ .off_volt = 600000,
+ .volt_setup_time = 0xfff,
+ .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .vsel_to_uv = twl4030_vsel_to_uv,
+ .uv_to_vsel = twl4030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_mpu_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1350000,
+ .onlp_volt = 1350000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_iva_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1100000,
+ .onlp_volt = 1100000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+static struct omap_volt_pmic_info omap4_core_volt_info = {
+ .slew_rate = 4000,
+ .step_size = 12500,
+ .on_volt = 1100000,
+ .onlp_volt = 1100000,
+ .ret_volt = 837500,
+ .off_volt = 600000,
+ .volt_setup_time = 0,
+ .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
+ .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
+ .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
+ .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
+ .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
+ .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
+ .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
+ .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .vsel_to_uv = twl6030_vsel_to_uv,
+ .uv_to_vsel = twl6030_uv_to_vsel,
+};
+
+int __init omap4_twl_init(void)
+{
+ struct voltagedomain *voltdm;
+
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ voltdm = omap_voltage_domain_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("iva");
+ omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
+
+ return 0;
+}
+
+int __init omap3_twl_init(void)
+{
+ struct voltagedomain *voltdm;
+
+ if (!cpu_is_omap34xx())
+ return -ENODEV;
+
+ if (cpu_is_omap3630()) {
+ omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
+ omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
+ omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
+ omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+ }
+
+ /*
+ * The smartreflex bit on twl4030 specifies if the setting of voltage
+ * is done over the I2C_SR path. Since this setting is independent of
+ * the actual usage of smartreflex AVS module, we enable TWL SR bit
+ * by default irrespective of whether smartreflex AVS module is enabled
+ * on the OMAP side or not. This is because without this bit enabled,
+ * the voltage scaling through vp forceupdate/bypass mechanism of
+ * voltage scaling will not function on TWL over I2C_SR.
+ */
+ if (!twl_sr_enable_autoinit)
+ omap3_twl_set_sr_bit(true);
+
+ voltdm = omap_voltage_domain_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
+
+ voltdm = omap_voltage_domain_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
+
+ return 0;
+}
+
+/**
+ * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL
+ * @enable: enable SR mode in twl or not
+ *
+ * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure
+ * voltage scaling through OMAP SR works. Else, the smartreflex bit
+ * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but
+ * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct
+ * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages,
+ * in those scenarios this bit is to be cleared (enable = false).
+ *
+ * Returns 0 on success, error is returned if I2C read/write fails.
+ */
+int __init omap3_twl_set_sr_bit(bool enable)
+{
+ u8 temp;
+ int ret;
+ if (twl_sr_enable_autoinit)
+ pr_warning("%s: unexpected multiple calls\n", __func__);
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+ if (ret)
+ goto err;
+
+ if (enable)
+ temp |= SMARTREFLEX_ENABLE;
+ else
+ temp &= ~SMARTREFLEX_ENABLE;
+
+ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+ if (!ret) {
+ twl_sr_enable_autoinit = true;
+ return 0;
+ }
+err:
+ pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret);
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
new file mode 100644
index 00000000..ab8b35b7
--- /dev/null
+++ b/arch/arm/mach-omap2/opp.c
@@ -0,0 +1,93 @@
+/*
+ * OMAP SoC specific OPP wrapper function
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010 Nokia Corporation.
+ * Eduardo Valentin
+ *
+ * This program is free software; you can 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 "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.
+ */
+#include <linux/module.h>
+#include <linux/opp.h>
+
+#include <plat/omap_device.h>
+
+#include "omap_opp_data.h"
+
+/* Temp variable to allow multiple calls */
+static u8 __initdata omap_table_init;
+
+/**
+ * omap_init_opp_table() - Initialize opp table as per the CPU type
+ * @opp_def: opp default list for this silicon
+ * @opp_def_size: number of opp entries for this silicon
+ *
+ * Register the initial OPP table with the OPP library based on the CPU
+ * type. This is meant to be used only by SoC specific registration.
+ */
+int __init omap_init_opp_table(struct omap_opp_def *opp_def,
+ u32 opp_def_size)
+{
+ int i, r;
+
+ if (!opp_def || !opp_def_size) {
+ pr_err("%s: invalid params!\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Initialize only if not already initialized even if the previous
+ * call failed, because, no reason we'd succeed again.
+ */
+ if (omap_table_init)
+ return -EEXIST;
+ omap_table_init = 1;
+
+ /* Lets now register with OPP library */
+ for (i = 0; i < opp_def_size; i++) {
+ struct omap_hwmod *oh;
+ struct device *dev;
+
+ if (!opp_def->hwmod_name) {
+ pr_err("%s: NULL name of omap_hwmod, failing [%d].\n",
+ __func__, i);
+ return -EINVAL;
+ }
+ oh = omap_hwmod_lookup(opp_def->hwmod_name);
+ if (!oh || !oh->od) {
+ pr_warn("%s: no hwmod or odev for %s, [%d] "
+ "cannot add OPPs.\n", __func__,
+ opp_def->hwmod_name, i);
+ return -EINVAL;
+ }
+ dev = &oh->od->pdev.dev;
+
+ r = opp_add(dev, opp_def->freq, opp_def->u_volt);
+ if (r) {
+ dev_err(dev, "%s: add OPP %ld failed for %s [%d] "
+ "result=%d\n",
+ __func__, opp_def->freq,
+ opp_def->hwmod_name, i, r);
+ } else {
+ if (!opp_def->default_available)
+ r = opp_disable(dev, opp_def->freq);
+ if (r)
+ dev_err(dev, "%s: disable %ld failed for %s "
+ "[%d] result=%d\n",
+ __func__, opp_def->freq,
+ opp_def->hwmod_name, i, r);
+ }
+ opp_def++;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/opp2420_data.c b/arch/arm/mach-omap2/opp2420_data.c
new file mode 100644
index 00000000..e6dda694
--- /dev/null
+++ b/arch/arm/mach-omap2/opp2420_data.c
@@ -0,0 +1,128 @@
+/*
+ * opp2420_data.c - old-style "OPP" table for OMAP2420
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratios' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio.
+ *
+ * XXX Missing voltage data.
+ * XXX Missing 19.2MHz sys_clk rate sets (needed for N800/N810)
+ *
+ * THe format described in this file is deprecated. Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ *
+ * Considerable work is still needed to fully support dynamic frequency
+ * changes on OMAP2xxx-series chips. Readers interested in such a
+ * project are encouraged to review the Maemo Diablo RX-34 and RX-44
+ * kernel source at:
+ * http://repository.maemo.org/pool/diablo/free/k/kernel-source-diablo/
+ */
+
+#include "opp2xxx.h"
+#include "sdrc.h"
+#include "clock.h"
+
+/*
+ * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on H4 boards available. There are quite a
+ * few more rate combinations which could be defined.
+ *
+ * When multiple values are defined the start up will try and choose
+ * the fastest one. If a 'fast' value is defined, then automatically,
+ * the /2 one should be included as it can be used. Generally having
+ * more than one fast set does not make sense, as static timings need
+ * to be changed to change the set. The exception is the bypass
+ * setting which is available for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ **/
+const struct prcm_config omap2420_rate_table[] = {
+ /* PRCM I - FAST */
+ {S12M, S660M, S330M, RI_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */
+ RI_CM_CLKSEL_DSP_VAL, RI_CM_CLKSEL_GFX_VAL,
+ RI_CM_CLKSEL1_CORE_VAL, MI_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_165MHz,
+ RATE_IN_242X},
+
+ /* PRCM II - FAST */
+ {S12M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ {S13M, S600M, S300M, RII_CM_CLKSEL_MPU_VAL, /* 300MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ /* PRCM III - FAST */
+ {S12M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ {S13M, S532M, S266M, RIII_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ /* PRCM II - SLOW */
+ {S12M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ {S13M, S300M, S150M, RII_CM_CLKSEL_MPU_VAL, /* 150MHz ARM */
+ RII_CM_CLKSEL_DSP_VAL, RII_CM_CLKSEL_GFX_VAL,
+ RII_CM_CLKSEL1_CORE_VAL, MII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_100MHz,
+ RATE_IN_242X},
+
+ /* PRCM III - SLOW */
+ {S12M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ {S13M, S266M, S133M, RIII_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ RIII_CM_CLKSEL_DSP_VAL, RIII_CM_CLKSEL_GFX_VAL,
+ RIII_CM_CLKSEL1_CORE_VAL, MIII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_133MHz,
+ RATE_IN_242X},
+
+ /* PRCM-VII (boot-bypass) */
+ {S12M, S12M, S12M, RVII_CM_CLKSEL_MPU_VAL, /* 12MHz ARM*/
+ RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+ RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_242X},
+
+ /* PRCM-VII (boot-bypass) */
+ {S13M, S13M, S13M, RVII_CM_CLKSEL_MPU_VAL, /* 13MHz ARM */
+ RVII_CM_CLKSEL_DSP_VAL, RVII_CM_CLKSEL_GFX_VAL,
+ RVII_CM_CLKSEL1_CORE_VAL, MVII_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, 0, SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_242X},
+
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
diff --git a/arch/arm/mach-omap2/opp2430_data.c b/arch/arm/mach-omap2/opp2430_data.c
new file mode 100644
index 00000000..1b9596ae
--- /dev/null
+++ b/arch/arm/mach-omap2/opp2430_data.c
@@ -0,0 +1,133 @@
+/*
+ * opp2430_data.c - old-style "OPP" table for OMAP2430
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratios' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ *
+ * XXX Missing voltage data.
+ * XXX Missing 19.2MHz sys_clk rate sets.
+ *
+ * THe format described in this file is deprecated. Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ */
+
+#include "opp2xxx.h"
+#include "sdrc.h"
+#include "clock.h"
+
+/*
+ * Key dividers which make up a PRCM set. Ratios for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,
+ * CM_CLKSEL_DSP, CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL,
+ * CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * Filling in table based on 2430-SDPs variants available. There are
+ * quite a few more rate combinations which could be defined.
+ *
+ * When multiple values are defined the start up will try and choose
+ * the fastest one. If a 'fast' value is defined, then automatically,
+ * the /2 one should be included as it can be used. Generally having
+ * more than one fast set does not make sense, as static timings need
+ * to be changed to change the set. The exception is the bypass
+ * setting which is available for low power bypass.
+ *
+ * Note: This table needs to be sorted, fastest to slowest.
+ */
+const struct prcm_config omap2430_rate_table[] = {
+ /* PRCM #4 - ratio2 (ES2.1) - FAST */
+ {S13M, S798M, S399M, R2_CM_CLKSEL_MPU_VAL, /* 399MHz ARM */
+ R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+ R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R2_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #2 - ratio1 (ES2) - FAST */
+ {S13M, S658M, S329M, R1_CM_CLKSEL_MPU_VAL, /* 330MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_165MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5a - ratio1 - FAST */
+ {S13M, S532M, S266M, R1_CM_CLKSEL_MPU_VAL, /* 266MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5b - ratio1 - FAST */
+ {S13M, S400M, S200M, R1_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_100MHz,
+ RATE_IN_243X},
+
+ /* PRCM #4 - ratio1 (ES2.1) - SLOW */
+ {S13M, S399M, S199M, R2_CM_CLKSEL_MPU_VAL, /* 200MHz ARM */
+ R2_CM_CLKSEL_DSP_VAL, R2_CM_CLKSEL_GFX_VAL,
+ R2_CM_CLKSEL1_CORE_VAL, M4_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R2_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #2 - ratio1 (ES2) - SLOW */
+ {S13M, S329M, S164M, R1_CM_CLKSEL_MPU_VAL, /* 165MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M2_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_165MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5a - ratio1 - SLOW */
+ {S13M, S266M, S133M, R1_CM_CLKSEL_MPU_VAL, /* 133MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5A_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_133MHz,
+ RATE_IN_243X},
+
+ /* PRCM #5b - ratio1 - SLOW*/
+ {S13M, S200M, S100M, R1_CM_CLKSEL_MPU_VAL, /* 100MHz ARM */
+ R1_CM_CLKSEL_DSP_VAL, R1_CM_CLKSEL_GFX_VAL,
+ R1_CM_CLKSEL1_CORE_VAL, M5B_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_1x_VAL, R1_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_100MHz,
+ RATE_IN_243X},
+
+ /* PRCM-boot/bypass */
+ {S13M, S13M, S13M, RB_CM_CLKSEL_MPU_VAL, /* 13Mhz */
+ RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+ RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_13_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_243X},
+
+ /* PRCM-boot/bypass */
+ {S12M, S12M, S12M, RB_CM_CLKSEL_MPU_VAL, /* 12Mhz */
+ RB_CM_CLKSEL_DSP_VAL, RB_CM_CLKSEL_GFX_VAL,
+ RB_CM_CLKSEL1_CORE_VAL, MB_CM_CLKSEL1_PLL_12_VAL,
+ MX_CLKSEL2_PLL_2x_VAL, RB_CM_CLKSEL_MDM_VAL,
+ SDRC_RFR_CTRL_BYPASS,
+ RATE_IN_243X},
+
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+};
diff --git a/arch/arm/mach-omap2/opp2xxx.h b/arch/arm/mach-omap2/opp2xxx.h
new file mode 100644
index 00000000..8affc66a
--- /dev/null
+++ b/arch/arm/mach-omap2/opp2xxx.h
@@ -0,0 +1,429 @@
+/*
+ * opp2xxx.h - macros for old-style OMAP2xxx "OPP" definitions
+ *
+ * Copyright (C) 2005-2009 Texas Instruments, Inc.
+ * Copyright (C) 2004-2009 Nokia Corporation
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * The OMAP2 processor can be run at several discrete 'PRCM configurations'.
+ * These configurations are characterized by voltage and speed for clocks.
+ * The device is only validated for certain combinations. One way to express
+ * these combinations is via the 'ratio's' which the clocks operate with
+ * respect to each other. These ratio sets are for a given voltage/DPLL
+ * setting. All configurations can be described by a DPLL setting and a ratio
+ * There are 3 ratio sets for the 2430 and X ratio sets for 2420.
+ *
+ * 2430 differs from 2420 in that there are no more phase synchronizers used.
+ * They both have a slightly different clock domain setup. 2420(iva1,dsp) vs
+ * 2430 (iva2.1, NOdsp, mdm)
+ *
+ * XXX Missing voltage data.
+ *
+ * THe format described in this file is deprecated. Once a reasonable
+ * OPP API exists, the data in this file should be converted to use it.
+ *
+ * This is technically part of the OMAP2xxx clock code.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OPP2XXX_H
+#define __ARCH_ARM_MACH_OMAP2_OPP2XXX_H
+
+/**
+ * struct prcm_config - define clock rates on a per-OPP basis (24xx)
+ *
+ * Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated.
+ * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP
+ * CM_CLKSEL_GFX, CM_CLKSEL1_CORE, CM_CLKSEL1_PLL CM_CLKSEL2_PLL, CM_CLKSEL_MDM
+ *
+ * This is deprecated. As soon as we have a decent OPP API, we should
+ * move all this stuff to it.
+ */
+struct prcm_config {
+ unsigned long xtal_speed; /* crystal rate */
+ unsigned long dpll_speed; /* dpll: out*xtal*M/(N-1)table_recalc */
+ unsigned long mpu_speed; /* speed of MPU */
+ unsigned long cm_clksel_mpu; /* mpu divider */
+ unsigned long cm_clksel_dsp; /* dsp+iva1 div(2420), iva2.1(2430) */
+ unsigned long cm_clksel_gfx; /* gfx dividers */
+ unsigned long cm_clksel1_core; /* major subsystem dividers */
+ unsigned long cm_clksel1_pll; /* m,n */
+ unsigned long cm_clksel2_pll; /* dpllx1 or x2 out */
+ unsigned long cm_clksel_mdm; /* modem dividers 2430 only */
+ unsigned long base_sdrc_rfr; /* base refresh timing for a set */
+ unsigned char flags;
+};
+
+
+/* Core fields for cm_clksel, not ratio governed */
+#define RX_CLKSEL_DSS1 (0x10 << 8)
+#define RX_CLKSEL_DSS2 (0x0 << 13)
+#define RX_CLKSEL_SSI (0x5 << 20)
+
+/*-------------------------------------------------------------------------
+ * Voltage/DPLL ratios
+ *-------------------------------------------------------------------------*/
+
+/* 2430 Ratio's, 2430-Ratio Config 1 */
+#define R1_CLKSEL_L3 (4 << 0)
+#define R1_CLKSEL_L4 (2 << 5)
+#define R1_CLKSEL_USB (4 << 25)
+#define R1_CM_CLKSEL1_CORE_VAL (R1_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ R1_CLKSEL_L4 | R1_CLKSEL_L3)
+#define R1_CLKSEL_MPU (2 << 0)
+#define R1_CM_CLKSEL_MPU_VAL R1_CLKSEL_MPU
+#define R1_CLKSEL_DSP (2 << 0)
+#define R1_CLKSEL_DSP_IF (2 << 5)
+#define R1_CM_CLKSEL_DSP_VAL (R1_CLKSEL_DSP | R1_CLKSEL_DSP_IF)
+#define R1_CLKSEL_GFX (2 << 0)
+#define R1_CM_CLKSEL_GFX_VAL R1_CLKSEL_GFX
+#define R1_CLKSEL_MDM (4 << 0)
+#define R1_CM_CLKSEL_MDM_VAL R1_CLKSEL_MDM
+
+/* 2430-Ratio Config 2 */
+#define R2_CLKSEL_L3 (6 << 0)
+#define R2_CLKSEL_L4 (2 << 5)
+#define R2_CLKSEL_USB (2 << 25)
+#define R2_CM_CLKSEL1_CORE_VAL (R2_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ R2_CLKSEL_L4 | R2_CLKSEL_L3)
+#define R2_CLKSEL_MPU (2 << 0)
+#define R2_CM_CLKSEL_MPU_VAL R2_CLKSEL_MPU
+#define R2_CLKSEL_DSP (2 << 0)
+#define R2_CLKSEL_DSP_IF (3 << 5)
+#define R2_CM_CLKSEL_DSP_VAL (R2_CLKSEL_DSP | R2_CLKSEL_DSP_IF)
+#define R2_CLKSEL_GFX (2 << 0)
+#define R2_CM_CLKSEL_GFX_VAL R2_CLKSEL_GFX
+#define R2_CLKSEL_MDM (6 << 0)
+#define R2_CM_CLKSEL_MDM_VAL R2_CLKSEL_MDM
+
+/* 2430-Ratio Bootm (BYPASS) */
+#define RB_CLKSEL_L3 (1 << 0)
+#define RB_CLKSEL_L4 (1 << 5)
+#define RB_CLKSEL_USB (1 << 25)
+#define RB_CM_CLKSEL1_CORE_VAL (RB_CLKSEL_USB | RX_CLKSEL_SSI | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ RB_CLKSEL_L4 | RB_CLKSEL_L3)
+#define RB_CLKSEL_MPU (1 << 0)
+#define RB_CM_CLKSEL_MPU_VAL RB_CLKSEL_MPU
+#define RB_CLKSEL_DSP (1 << 0)
+#define RB_CLKSEL_DSP_IF (1 << 5)
+#define RB_CM_CLKSEL_DSP_VAL (RB_CLKSEL_DSP | RB_CLKSEL_DSP_IF)
+#define RB_CLKSEL_GFX (1 << 0)
+#define RB_CM_CLKSEL_GFX_VAL RB_CLKSEL_GFX
+#define RB_CLKSEL_MDM (1 << 0)
+#define RB_CM_CLKSEL_MDM_VAL RB_CLKSEL_MDM
+
+/* 2420 Ratio Equivalents */
+#define RXX_CLKSEL_VLYNQ (0x12 << 15)
+#define RXX_CLKSEL_SSI (0x8 << 20)
+
+/* 2420-PRCM III 532MHz core */
+#define RIII_CLKSEL_L3 (4 << 0) /* 133MHz */
+#define RIII_CLKSEL_L4 (2 << 5) /* 66.5MHz */
+#define RIII_CLKSEL_USB (4 << 25) /* 33.25MHz */
+#define RIII_CM_CLKSEL1_CORE_VAL (RIII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+ RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+ RX_CLKSEL_DSS1 | RIII_CLKSEL_L4 | \
+ RIII_CLKSEL_L3)
+#define RIII_CLKSEL_MPU (2 << 0) /* 266MHz */
+#define RIII_CM_CLKSEL_MPU_VAL RIII_CLKSEL_MPU
+#define RIII_CLKSEL_DSP (3 << 0) /* c5x - 177.3MHz */
+#define RIII_CLKSEL_DSP_IF (2 << 5) /* c5x - 88.67MHz */
+#define RIII_SYNC_DSP (1 << 7) /* Enable sync */
+#define RIII_CLKSEL_IVA (6 << 8) /* iva1 - 88.67MHz */
+#define RIII_SYNC_IVA (1 << 13) /* Enable sync */
+#define RIII_CM_CLKSEL_DSP_VAL (RIII_SYNC_IVA | RIII_CLKSEL_IVA | \
+ RIII_SYNC_DSP | RIII_CLKSEL_DSP_IF | \
+ RIII_CLKSEL_DSP)
+#define RIII_CLKSEL_GFX (2 << 0) /* 66.5MHz */
+#define RIII_CM_CLKSEL_GFX_VAL RIII_CLKSEL_GFX
+
+/* 2420-PRCM II 600MHz core */
+#define RII_CLKSEL_L3 (6 << 0) /* 100MHz */
+#define RII_CLKSEL_L4 (2 << 5) /* 50MHz */
+#define RII_CLKSEL_USB (2 << 25) /* 50MHz */
+#define RII_CM_CLKSEL1_CORE_VAL (RII_CLKSEL_USB | RXX_CLKSEL_SSI | \
+ RXX_CLKSEL_VLYNQ | RX_CLKSEL_DSS2 | \
+ RX_CLKSEL_DSS1 | RII_CLKSEL_L4 | \
+ RII_CLKSEL_L3)
+#define RII_CLKSEL_MPU (2 << 0) /* 300MHz */
+#define RII_CM_CLKSEL_MPU_VAL RII_CLKSEL_MPU
+#define RII_CLKSEL_DSP (3 << 0) /* c5x - 200MHz */
+#define RII_CLKSEL_DSP_IF (2 << 5) /* c5x - 100MHz */
+#define RII_SYNC_DSP (0 << 7) /* Bypass sync */
+#define RII_CLKSEL_IVA (3 << 8) /* iva1 - 200MHz */
+#define RII_SYNC_IVA (0 << 13) /* Bypass sync */
+#define RII_CM_CLKSEL_DSP_VAL (RII_SYNC_IVA | RII_CLKSEL_IVA | \
+ RII_SYNC_DSP | RII_CLKSEL_DSP_IF | \
+ RII_CLKSEL_DSP)
+#define RII_CLKSEL_GFX (2 << 0) /* 50MHz */
+#define RII_CM_CLKSEL_GFX_VAL RII_CLKSEL_GFX
+
+/* 2420-PRCM I 660MHz core */
+#define RI_CLKSEL_L3 (4 << 0) /* 165MHz */
+#define RI_CLKSEL_L4 (2 << 5) /* 82.5MHz */
+#define RI_CLKSEL_USB (4 << 25) /* 41.25MHz */
+#define RI_CM_CLKSEL1_CORE_VAL (RI_CLKSEL_USB | \
+ RXX_CLKSEL_SSI | RXX_CLKSEL_VLYNQ | \
+ RX_CLKSEL_DSS2 | RX_CLKSEL_DSS1 | \
+ RI_CLKSEL_L4 | RI_CLKSEL_L3)
+#define RI_CLKSEL_MPU (2 << 0) /* 330MHz */
+#define RI_CM_CLKSEL_MPU_VAL RI_CLKSEL_MPU
+#define RI_CLKSEL_DSP (3 << 0) /* c5x - 220MHz */
+#define RI_CLKSEL_DSP_IF (2 << 5) /* c5x - 110MHz */
+#define RI_SYNC_DSP (1 << 7) /* Activate sync */
+#define RI_CLKSEL_IVA (4 << 8) /* iva1 - 165MHz */
+#define RI_SYNC_IVA (0 << 13) /* Bypass sync */
+#define RI_CM_CLKSEL_DSP_VAL (RI_SYNC_IVA | RI_CLKSEL_IVA | \
+ RI_SYNC_DSP | RI_CLKSEL_DSP_IF | \
+ RI_CLKSEL_DSP)
+#define RI_CLKSEL_GFX (1 << 0) /* 165MHz */
+#define RI_CM_CLKSEL_GFX_VAL RI_CLKSEL_GFX
+
+/* 2420-PRCM VII (boot) */
+#define RVII_CLKSEL_L3 (1 << 0)
+#define RVII_CLKSEL_L4 (1 << 5)
+#define RVII_CLKSEL_DSS1 (1 << 8)
+#define RVII_CLKSEL_DSS2 (0 << 13)
+#define RVII_CLKSEL_VLYNQ (1 << 15)
+#define RVII_CLKSEL_SSI (1 << 20)
+#define RVII_CLKSEL_USB (1 << 25)
+
+#define RVII_CM_CLKSEL1_CORE_VAL (RVII_CLKSEL_USB | RVII_CLKSEL_SSI | \
+ RVII_CLKSEL_VLYNQ | \
+ RVII_CLKSEL_DSS2 | RVII_CLKSEL_DSS1 | \
+ RVII_CLKSEL_L4 | RVII_CLKSEL_L3)
+
+#define RVII_CLKSEL_MPU (1 << 0) /* all divide by 1 */
+#define RVII_CM_CLKSEL_MPU_VAL RVII_CLKSEL_MPU
+
+#define RVII_CLKSEL_DSP (1 << 0)
+#define RVII_CLKSEL_DSP_IF (1 << 5)
+#define RVII_SYNC_DSP (0 << 7)
+#define RVII_CLKSEL_IVA (1 << 8)
+#define RVII_SYNC_IVA (0 << 13)
+#define RVII_CM_CLKSEL_DSP_VAL (RVII_SYNC_IVA | RVII_CLKSEL_IVA | \
+ RVII_SYNC_DSP | RVII_CLKSEL_DSP_IF | \
+ RVII_CLKSEL_DSP)
+
+#define RVII_CLKSEL_GFX (1 << 0)
+#define RVII_CM_CLKSEL_GFX_VAL RVII_CLKSEL_GFX
+
+/*-------------------------------------------------------------------------
+ * 2430 Target modes: Along with each configuration the CPU has several
+ * modes which goes along with them. Modes mainly are the addition of
+ * describe DPLL combinations to go along with a ratio.
+ *-------------------------------------------------------------------------*/
+
+/* Hardware governed */
+#define MX_48M_SRC (0 << 3)
+#define MX_54M_SRC (0 << 5)
+#define MX_APLLS_CLIKIN_12 (3 << 23)
+#define MX_APLLS_CLIKIN_13 (2 << 23)
+#define MX_APLLS_CLIKIN_19_2 (0 << 23)
+
+/*
+ * 2430 - standalone, 2*ref*M/(n+1), M/N is for exactness not relock speed
+ * #5a (ratio1) baseport-target, target DPLL = 266*2 = 532MHz
+ */
+#define M5A_DPLL_MULT_12 (133 << 12)
+#define M5A_DPLL_DIV_12 (5 << 8)
+#define M5A_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_12 | M5A_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+#define M5A_DPLL_MULT_13 (61 << 12)
+#define M5A_DPLL_DIV_13 (2 << 8)
+#define M5A_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_13 | M5A_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+#define M5A_DPLL_MULT_19 (55 << 12)
+#define M5A_DPLL_DIV_19 (3 << 8)
+#define M5A_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5A_DPLL_DIV_19 | M5A_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2)
+/* #5b (ratio1) target DPLL = 200*2 = 400MHz */
+#define M5B_DPLL_MULT_12 (50 << 12)
+#define M5B_DPLL_DIV_12 (2 << 8)
+#define M5B_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_12 | M5B_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+#define M5B_DPLL_MULT_13 (200 << 12)
+#define M5B_DPLL_DIV_13 (12 << 8)
+
+#define M5B_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_13 | M5B_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+#define M5B_DPLL_MULT_19 (125 << 12)
+#define M5B_DPLL_DIV_19 (31 << 8)
+#define M5B_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M5B_DPLL_DIV_19 | M5B_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2)
+/*
+ * #4 (ratio2), DPLL = 399*2 = 798MHz, L3=133MHz
+ */
+#define M4_DPLL_MULT_12 (133 << 12)
+#define M4_DPLL_DIV_12 (3 << 8)
+#define M4_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M4_DPLL_DIV_12 | M4_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+
+#define M4_DPLL_MULT_13 (399 << 12)
+#define M4_DPLL_DIV_13 (12 << 8)
+#define M4_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M4_DPLL_DIV_13 | M4_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+
+#define M4_DPLL_MULT_19 (145 << 12)
+#define M4_DPLL_DIV_19 (6 << 8)
+#define M4_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M4_DPLL_DIV_19 | M4_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2)
+
+/*
+ * #3 (ratio2) baseport-target, target DPLL = 330*2 = 660MHz
+ */
+#define M3_DPLL_MULT_12 (55 << 12)
+#define M3_DPLL_DIV_12 (1 << 8)
+#define M3_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_12 | M3_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+#define M3_DPLL_MULT_13 (76 << 12)
+#define M3_DPLL_DIV_13 (2 << 8)
+#define M3_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_13 | M3_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+#define M3_DPLL_MULT_19 (17 << 12)
+#define M3_DPLL_DIV_19 (0 << 8)
+#define M3_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M3_DPLL_DIV_19 | M3_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2)
+
+/*
+ * #2 (ratio1) DPLL = 330*2 = 660MHz, L3=165MHz
+ */
+#define M2_DPLL_MULT_12 (55 << 12)
+#define M2_DPLL_DIV_12 (1 << 8)
+#define M2_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M2_DPLL_DIV_12 | M2_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+
+/* Speed changes - Used 658.7MHz instead of 660MHz for LP-Refresh M=76 N=2,
+ * relock time issue */
+/* Core frequency changed from 330/165 to 329/164 MHz*/
+#define M2_DPLL_MULT_13 (76 << 12)
+#define M2_DPLL_DIV_13 (2 << 8)
+#define M2_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M2_DPLL_DIV_13 | M2_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+
+#define M2_DPLL_MULT_19 (17 << 12)
+#define M2_DPLL_DIV_19 (0 << 8)
+#define M2_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ M2_DPLL_DIV_19 | M2_DPLL_MULT_19 | \
+ MX_APLLS_CLIKIN_19_2)
+
+/* boot (boot) */
+#define MB_DPLL_MULT (1 << 12)
+#define MB_DPLL_DIV (0 << 8)
+#define MB_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MB_DPLL_DIV | MB_DPLL_MULT | \
+ MX_APLLS_CLIKIN_12)
+
+#define MB_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MB_DPLL_DIV | MB_DPLL_MULT | \
+ MX_APLLS_CLIKIN_13)
+
+#define MB_CM_CLKSEL1_PLL_19_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MB_DPLL_DIV | MB_DPLL_MULT | \
+ MX_APLLS_CLIKIN_19)
+
+/*
+ * 2430 - chassis (sedna)
+ * 165 (ratio1) same as above #2
+ * 150 (ratio1)
+ * 133 (ratio2) same as above #4
+ * 110 (ratio2) same as above #3
+ * 104 (ratio2)
+ * boot (boot)
+ */
+
+/* PRCM I target DPLL = 2*330MHz = 660MHz */
+#define MI_DPLL_MULT_12 (55 << 12)
+#define MI_DPLL_DIV_12 (1 << 8)
+#define MI_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MI_DPLL_DIV_12 | MI_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+
+/*
+ * 2420 Equivalent - mode registers
+ * PRCM II , target DPLL = 2*300MHz = 600MHz
+ */
+#define MII_DPLL_MULT_12 (50 << 12)
+#define MII_DPLL_DIV_12 (1 << 8)
+#define MII_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MII_DPLL_DIV_12 | MII_DPLL_MULT_12 | \
+ MX_APLLS_CLIKIN_12)
+#define MII_DPLL_MULT_13 (300 << 12)
+#define MII_DPLL_DIV_13 (12 << 8)
+#define MII_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MII_DPLL_DIV_13 | MII_DPLL_MULT_13 | \
+ MX_APLLS_CLIKIN_13)
+
+/* PRCM III target DPLL = 2*266 = 532MHz*/
+#define MIII_DPLL_MULT_12 (133 << 12)
+#define MIII_DPLL_DIV_12 (5 << 8)
+#define MIII_CM_CLKSEL1_PLL_12_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MIII_DPLL_DIV_12 | \
+ MIII_DPLL_MULT_12 | MX_APLLS_CLIKIN_12)
+#define MIII_DPLL_MULT_13 (266 << 12)
+#define MIII_DPLL_DIV_13 (12 << 8)
+#define MIII_CM_CLKSEL1_PLL_13_VAL (MX_48M_SRC | MX_54M_SRC | \
+ MIII_DPLL_DIV_13 | \
+ MIII_DPLL_MULT_13 | MX_APLLS_CLIKIN_13)
+
+/* PRCM VII (boot bypass) */
+#define MVII_CM_CLKSEL1_PLL_12_VAL MB_CM_CLKSEL1_PLL_12_VAL
+#define MVII_CM_CLKSEL1_PLL_13_VAL MB_CM_CLKSEL1_PLL_13_VAL
+
+/* High and low operation value */
+#define MX_CLKSEL2_PLL_2x_VAL (2 << 0)
+#define MX_CLKSEL2_PLL_1x_VAL (1 << 0)
+
+/* MPU speed defines */
+#define S12M 12000000
+#define S13M 13000000
+#define S19M 19200000
+#define S26M 26000000
+#define S100M 100000000
+#define S133M 133000000
+#define S150M 150000000
+#define S164M 164000000
+#define S165M 165000000
+#define S199M 199000000
+#define S200M 200000000
+#define S266M 266000000
+#define S300M 300000000
+#define S329M 329000000
+#define S330M 330000000
+#define S399M 399000000
+#define S400M 400000000
+#define S532M 532000000
+#define S600M 600000000
+#define S658M 658000000
+#define S660M 660000000
+#define S798M 798000000
+
+
+extern const struct prcm_config omap2420_rate_table[];
+
+#ifdef CONFIG_SOC_OMAP2430
+extern const struct prcm_config omap2430_rate_table[];
+#else
+#define omap2430_rate_table NULL
+#endif
+extern const struct prcm_config *rate_table;
+extern const struct prcm_config *curr_prcm_set;
+
+#endif
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
new file mode 100644
index 00000000..d95f3f94
--- /dev/null
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -0,0 +1,172 @@
+/*
+ * OMAP3 OPP table definitions.
+ *
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Copyright (C) 2010-2011 Nokia Corporation.
+ * Eduardo Valentin
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#include <linux/module.h>
+
+#include <plat/cpu.h>
+
+#include "control.h"
+#include "omap_opp_data.h"
+#include "pm.h"
+
+/* 34xx */
+
+/* VDD1 */
+
+#define OMAP3430_VDD_MPU_OPP1_UV 975000
+#define OMAP3430_VDD_MPU_OPP2_UV 1075000
+#define OMAP3430_VDD_MPU_OPP3_UV 1200000
+#define OMAP3430_VDD_MPU_OPP4_UV 1270000
+#define OMAP3430_VDD_MPU_OPP5_UV 1350000
+
+struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3430_VDD_CORE_OPP1_UV 975000
+#define OMAP3430_VDD_CORE_OPP2_UV 1050000
+#define OMAP3430_VDD_CORE_OPP3_UV 1150000
+
+struct omap_volt_data omap34xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* 36xx */
+
+/* VDD1 */
+
+#define OMAP3630_VDD_MPU_OPP50_UV 1012500
+#define OMAP3630_VDD_MPU_OPP100_UV 1200000
+#define OMAP3630_VDD_MPU_OPP120_UV 1325000
+#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
+
+struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* VDD2 */
+
+#define OMAP3630_VDD_CORE_OPP50_UV 1000000
+#define OMAP3630_VDD_CORE_OPP100_UV 1200000
+
+struct omap_volt_data omap36xx_vddcore_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+/* OPP data */
+
+static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
+ /* MPU OPP1 */
+ OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV),
+ /* MPU OPP2 */
+ OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV),
+ /* MPU OPP3 */
+ OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV),
+ /* MPU OPP4 */
+ OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
+ /* MPU OPP5 */
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
+
+ /*
+ * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
+ * almost the same than the one at 83MHz thus providing very little
+ * gain for the power point of view. In term of energy it will even
+ * increase the consumption due to the very negative performance
+ * impact that frequency will do to the MPU and the whole system in
+ * general.
+ */
+ OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV),
+ /* L3 OPP2 */
+ OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV),
+ /* L3 OPP3 */
+ OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV),
+
+ /* DSP OPP1 */
+ OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV),
+ /* DSP OPP2 */
+ OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV),
+ /* DSP OPP3 */
+ OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV),
+ /* DSP OPP4 */
+ OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
+ /* DSP OPP5 */
+ OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
+};
+
+static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV),
+ /* MPU OPP4 - OPP-SB */
+ OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV),
+
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV),
+ /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
+ OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV),
+
+ /* DSP OPP1 - OPP50 */
+ OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV),
+ /* DSP OPP2 - OPP100 */
+ OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV),
+ /* DSP OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV),
+ /* DSP OPP4 - OPP-SB */
+ OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV),
+};
+
+/**
+ * omap3_opp_init() - initialize omap3 opp table
+ */
+int __init omap3_opp_init(void)
+{
+ int r = -ENODEV;
+
+ if (!cpu_is_omap34xx())
+ return r;
+
+ if (cpu_is_omap3630())
+ r = omap_init_opp_table(omap36xx_opp_def_list,
+ ARRAY_SIZE(omap36xx_opp_def_list));
+ else
+ r = omap_init_opp_table(omap34xx_opp_def_list,
+ ARRAY_SIZE(omap34xx_opp_def_list));
+
+ return r;
+}
+device_initcall(omap3_opp_init);
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
new file mode 100644
index 00000000..2293ba27
--- /dev/null
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -0,0 +1,105 @@
+/*
+ * OMAP4 OPP table definitions.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Nishanth Menon
+ * Kevin Hilman
+ * Thara Gopinath
+ * Copyright (C) 2010-2011 Nokia Corporation.
+ * Eduardo Valentin
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+#include <linux/module.h>
+
+#include <plat/cpu.h>
+
+#include "control.h"
+#include "omap_opp_data.h"
+#include "pm.h"
+
+/*
+ * Structures containing OMAP4430 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+
+#define OMAP4430_VDD_MPU_OPP50_UV 1025000
+#define OMAP4430_VDD_MPU_OPP100_UV 1200000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000
+
+struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_IVA_OPP50_UV 1013000
+#define OMAP4430_VDD_IVA_OPP100_UV 1188000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000
+
+struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+#define OMAP4430_VDD_CORE_OPP50_UV 1025000
+#define OMAP4430_VDD_CORE_OPP100_UV 1200000
+
+struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
+ VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
+ VOLT_DATA_DEFINE(0, 0, 0, 0),
+};
+
+
+static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
+ /* MPU OPP1 - OPP50 */
+ OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
+ /* MPU OPP2 - OPP100 */
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV),
+ /* MPU OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV),
+ /* MPU OPP4 - OPP-SB */
+ OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV),
+ /* L3 OPP1 - OPP50 */
+ OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV),
+ /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
+ OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV),
+ /* IVA OPP1 - OPP50 */
+ OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV),
+ /* IVA OPP2 - OPP100 */
+ OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV),
+ /* IVA OPP3 - OPP-Turbo */
+ OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV),
+ /* TODO: add DSP, aess, fdif, gpu */
+};
+
+/**
+ * omap4_opp_init() - initialize omap4 opp table
+ */
+int __init omap4_opp_init(void)
+{
+ int r = -ENODEV;
+
+ if (!cpu_is_omap44xx())
+ return r;
+
+ r = omap_init_opp_table(omap44xx_opp_def_list,
+ ARRAY_SIZE(omap44xx_opp_def_list));
+
+ return r;
+}
+device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
new file mode 100644
index 00000000..e01da45c
--- /dev/null
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -0,0 +1,655 @@
+/*
+ * OMAP Power Management debug routines
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Copyright (C) 2006-2008 Nokia Corporation
+ *
+ * Written by:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Tony Lindgren
+ * Juha Yrjola
+ * Amit Kucheria <amit.kucheria@nokia.com>
+ * Igor Stoppa <igor.stoppa@nokia.com>
+ * Jouni Hogander
+ *
+ * Based on pm.c for omap2
+ *
+ * This program is free software; you can 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/sched.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <plat/clock.h>
+#include <plat/board.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include <plat/dmtimer.h>
+#include <plat/omap-pm.h>
+
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "pm.h"
+
+int omap2_pm_debug;
+u32 enable_off_mode;
+u32 sleep_while_idle;
+u32 wakeup_timer_seconds;
+u32 wakeup_timer_milliseconds;
+
+#define DUMP_PRM_MOD_REG(mod, reg) \
+ regs[reg_count].name = #mod "." #reg; \
+ regs[reg_count++].val = omap2_prm_read_mod_reg(mod, reg)
+#define DUMP_CM_MOD_REG(mod, reg) \
+ regs[reg_count].name = #mod "." #reg; \
+ regs[reg_count++].val = omap2_cm_read_mod_reg(mod, reg)
+#define DUMP_PRM_REG(reg) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = __raw_readl(reg)
+#define DUMP_CM_REG(reg) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = __raw_readl(reg)
+#define DUMP_INTC_REG(reg, off) \
+ regs[reg_count].name = #reg; \
+ regs[reg_count++].val = \
+ __raw_readl(OMAP2_L4_IO_ADDRESS(0x480fe000 + (off)))
+
+void omap2_pm_dump(int mode, int resume, unsigned int us)
+{
+ struct reg {
+ const char *name;
+ u32 val;
+ } regs[32];
+ int reg_count = 0, i;
+ const char *s1 = NULL, *s2 = NULL;
+
+ if (!resume) {
+#if 0
+ /* MPU */
+ DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRM_IRQENABLE_MPU_OFFSET);
+ DUMP_CM_MOD_REG(MPU_MOD, OMAP2_CM_CLKSTCTRL);
+ DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTCTRL);
+ DUMP_PRM_MOD_REG(MPU_MOD, OMAP2_PM_PWSTST);
+ DUMP_PRM_MOD_REG(MPU_MOD, PM_WKDEP);
+#endif
+#if 0
+ /* INTC */
+ DUMP_INTC_REG(INTC_MIR0, 0x0084);
+ DUMP_INTC_REG(INTC_MIR1, 0x00a4);
+ DUMP_INTC_REG(INTC_MIR2, 0x00c4);
+#endif
+#if 0
+ DUMP_CM_MOD_REG(CORE_MOD, CM_FCLKEN1);
+ if (cpu_is_omap24xx()) {
+ DUMP_CM_MOD_REG(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
+ OMAP2_PRCM_CLKEMUL_CTRL_OFFSET);
+ DUMP_PRM_MOD_REG(OMAP24XX_GR_MOD,
+ OMAP2_PRCM_CLKSRC_CTRL_OFFSET);
+ }
+ DUMP_CM_MOD_REG(WKUP_MOD, CM_FCLKEN);
+ DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN1);
+ DUMP_CM_MOD_REG(CORE_MOD, CM_ICLKEN2);
+ DUMP_CM_MOD_REG(WKUP_MOD, CM_ICLKEN);
+ DUMP_CM_MOD_REG(PLL_MOD, CM_CLKEN);
+ DUMP_CM_MOD_REG(PLL_MOD, CM_AUTOIDLE);
+ DUMP_PRM_MOD_REG(CORE_MOD, OMAP2_PM_PWSTST);
+#endif
+#if 0
+ /* DSP */
+ if (cpu_is_omap24xx()) {
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_FCLKEN);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_ICLKEN);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_IDLEST);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_AUTOIDLE);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, CM_CLKSEL);
+ DUMP_CM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_CM_CLKSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_RM_RSTST);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTCTRL);
+ DUMP_PRM_MOD_REG(OMAP24XX_DSP_MOD, OMAP2_PM_PWSTST);
+ }
+#endif
+ } else {
+ DUMP_PRM_MOD_REG(CORE_MOD, PM_WKST1);
+ if (cpu_is_omap24xx())
+ DUMP_PRM_MOD_REG(CORE_MOD, OMAP24XX_PM_WKST2);
+ DUMP_PRM_MOD_REG(WKUP_MOD, PM_WKST);
+ DUMP_PRM_MOD_REG(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+#if 1
+ DUMP_INTC_REG(INTC_PENDING_IRQ0, 0x0098);
+ DUMP_INTC_REG(INTC_PENDING_IRQ1, 0x00b8);
+ DUMP_INTC_REG(INTC_PENDING_IRQ2, 0x00d8);
+#endif
+ }
+
+ switch (mode) {
+ case 0:
+ s1 = "full";
+ s2 = "retention";
+ break;
+ case 1:
+ s1 = "MPU";
+ s2 = "retention";
+ break;
+ case 2:
+ s1 = "MPU";
+ s2 = "idle";
+ break;
+ }
+
+ if (!resume)
+#ifdef CONFIG_NO_HZ
+ printk(KERN_INFO
+ "--- Going to %s %s (next timer after %u ms)\n", s1, s2,
+ jiffies_to_msecs(get_next_timer_interrupt(jiffies) -
+ jiffies));
+#else
+ printk(KERN_INFO "--- Going to %s %s\n", s1, s2);
+#endif
+ else
+ printk(KERN_INFO "--- Woke up (slept for %u.%03u ms)\n",
+ us / 1000, us % 1000);
+
+ for (i = 0; i < reg_count; i++)
+ printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val);
+}
+
+void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds)
+{
+ u32 tick_rate, cycles;
+
+ if (!seconds && !milliseconds)
+ return;
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup));
+ cycles = tick_rate * seconds + tick_rate * milliseconds / 1000;
+ omap_dm_timer_stop(gptimer_wakeup);
+ omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles);
+
+ pr_info("PM: Resume timer in %u.%03u secs"
+ " (%d ticks at %d ticks/sec.)\n",
+ seconds, milliseconds, cycles, tick_rate);
+}
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void pm_dbg_regset_store(u32 *ptr);
+
+static struct dentry *pm_dbg_dir;
+
+static int pm_dbg_init_done;
+
+static int pm_dbg_init(void);
+
+enum {
+ DEBUG_FILE_COUNTERS = 0,
+ DEBUG_FILE_TIMERS,
+};
+
+struct pm_module_def {
+ char name[8]; /* Name of the module */
+ short type; /* CM or PRM */
+ unsigned short offset;
+ int low; /* First register address on this module */
+ int high; /* Last register address on this module */
+};
+
+#define MOD_CM 0
+#define MOD_PRM 1
+
+static const struct pm_module_def *pm_dbg_reg_modules;
+static const struct pm_module_def omap3_pm_reg_modules[] = {
+ { "IVA2", MOD_CM, OMAP3430_IVA2_MOD, 0, 0x4c },
+ { "OCP", MOD_CM, OCP_MOD, 0, 0x10 },
+ { "MPU", MOD_CM, MPU_MOD, 4, 0x4c },
+ { "CORE", MOD_CM, CORE_MOD, 0, 0x4c },
+ { "SGX", MOD_CM, OMAP3430ES2_SGX_MOD, 0, 0x4c },
+ { "WKUP", MOD_CM, WKUP_MOD, 0, 0x40 },
+ { "CCR", MOD_CM, PLL_MOD, 0, 0x70 },
+ { "DSS", MOD_CM, OMAP3430_DSS_MOD, 0, 0x4c },
+ { "CAM", MOD_CM, OMAP3430_CAM_MOD, 0, 0x4c },
+ { "PER", MOD_CM, OMAP3430_PER_MOD, 0, 0x4c },
+ { "EMU", MOD_CM, OMAP3430_EMU_MOD, 0x40, 0x54 },
+ { "NEON", MOD_CM, OMAP3430_NEON_MOD, 0x20, 0x48 },
+ { "USB", MOD_CM, OMAP3430ES2_USBHOST_MOD, 0, 0x4c },
+
+ { "IVA2", MOD_PRM, OMAP3430_IVA2_MOD, 0x50, 0xfc },
+ { "OCP", MOD_PRM, OCP_MOD, 4, 0x1c },
+ { "MPU", MOD_PRM, MPU_MOD, 0x58, 0xe8 },
+ { "CORE", MOD_PRM, CORE_MOD, 0x58, 0xf8 },
+ { "SGX", MOD_PRM, OMAP3430ES2_SGX_MOD, 0x58, 0xe8 },
+ { "WKUP", MOD_PRM, WKUP_MOD, 0xa0, 0xb0 },
+ { "CCR", MOD_PRM, PLL_MOD, 0x40, 0x70 },
+ { "DSS", MOD_PRM, OMAP3430_DSS_MOD, 0x58, 0xe8 },
+ { "CAM", MOD_PRM, OMAP3430_CAM_MOD, 0x58, 0xe8 },
+ { "PER", MOD_PRM, OMAP3430_PER_MOD, 0x58, 0xe8 },
+ { "EMU", MOD_PRM, OMAP3430_EMU_MOD, 0x58, 0xe4 },
+ { "GLBL", MOD_PRM, OMAP3430_GR_MOD, 0x20, 0xe4 },
+ { "NEON", MOD_PRM, OMAP3430_NEON_MOD, 0x58, 0xe8 },
+ { "USB", MOD_PRM, OMAP3430ES2_USBHOST_MOD, 0x58, 0xe8 },
+ { "", 0, 0, 0, 0 },
+};
+
+#define PM_DBG_MAX_REG_SETS 4
+
+static void *pm_dbg_reg_set[PM_DBG_MAX_REG_SETS];
+
+static int pm_dbg_get_regset_size(void)
+{
+ static int regset_size;
+
+ if (regset_size == 0) {
+ int i = 0;
+
+ while (pm_dbg_reg_modules[i].name[0] != 0) {
+ regset_size += pm_dbg_reg_modules[i].high +
+ 4 - pm_dbg_reg_modules[i].low;
+ i++;
+ }
+ }
+ return regset_size;
+}
+
+static int pm_dbg_show_regs(struct seq_file *s, void *unused)
+{
+ int i, j;
+ unsigned long val;
+ int reg_set = (int)s->private;
+ u32 *ptr;
+ void *store = NULL;
+ int regs;
+ int linefeed;
+
+ if (reg_set == 0) {
+ store = kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
+ ptr = store;
+ pm_dbg_regset_store(ptr);
+ } else {
+ ptr = pm_dbg_reg_set[reg_set - 1];
+ }
+
+ i = 0;
+
+ while (pm_dbg_reg_modules[i].name[0] != 0) {
+ regs = 0;
+ linefeed = 0;
+ if (pm_dbg_reg_modules[i].type == MOD_CM)
+ seq_printf(s, "MOD: CM_%s (%08x)\n",
+ pm_dbg_reg_modules[i].name,
+ (u32)(OMAP3430_CM_BASE +
+ pm_dbg_reg_modules[i].offset));
+ else
+ seq_printf(s, "MOD: PRM_%s (%08x)\n",
+ pm_dbg_reg_modules[i].name,
+ (u32)(OMAP3430_PRM_BASE +
+ pm_dbg_reg_modules[i].offset));
+
+ for (j = pm_dbg_reg_modules[i].low;
+ j <= pm_dbg_reg_modules[i].high; j += 4) {
+ val = *(ptr++);
+ if (val != 0) {
+ regs++;
+ if (linefeed) {
+ seq_printf(s, "\n");
+ linefeed = 0;
+ }
+ seq_printf(s, " %02x => %08lx", j, val);
+ if (regs % 4 == 0)
+ linefeed = 1;
+ }
+ }
+ seq_printf(s, "\n");
+ i++;
+ }
+
+ if (store != NULL)
+ kfree(store);
+
+ return 0;
+}
+
+static void pm_dbg_regset_store(u32 *ptr)
+{
+ int i, j;
+ u32 val;
+
+ i = 0;
+
+ while (pm_dbg_reg_modules[i].name[0] != 0) {
+ for (j = pm_dbg_reg_modules[i].low;
+ j <= pm_dbg_reg_modules[i].high; j += 4) {
+ if (pm_dbg_reg_modules[i].type == MOD_CM)
+ val = omap2_cm_read_mod_reg(
+ pm_dbg_reg_modules[i].offset, j);
+ else
+ val = omap2_prm_read_mod_reg(
+ pm_dbg_reg_modules[i].offset, j);
+ *(ptr++) = val;
+ }
+ i++;
+ }
+}
+
+int pm_dbg_regset_save(int reg_set)
+{
+ if (pm_dbg_reg_set[reg_set-1] == NULL)
+ return -EINVAL;
+
+ pm_dbg_regset_store(pm_dbg_reg_set[reg_set-1]);
+
+ return 0;
+}
+
+static const char pwrdm_state_names[][PWRDM_MAX_PWRSTS] = {
+ "OFF",
+ "RET",
+ "INA",
+ "ON"
+};
+
+void pm_dbg_update_time(struct powerdomain *pwrdm, int prev)
+{
+ s64 t;
+
+ if (!pm_dbg_init_done)
+ return ;
+
+ /* Update timer for previous state */
+ t = sched_clock();
+
+ pwrdm->state_timer[prev] += t - pwrdm->timer;
+
+ pwrdm->timer = t;
+}
+
+static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)
+{
+ struct seq_file *s = (struct seq_file *)user;
+
+ if (strcmp(clkdm->name, "emu_clkdm") == 0 ||
+ strcmp(clkdm->name, "wkup_clkdm") == 0 ||
+ strncmp(clkdm->name, "dpll", 4) == 0)
+ return 0;
+
+ seq_printf(s, "%s->%s (%d)", clkdm->name,
+ clkdm->pwrdm.ptr->name,
+ atomic_read(&clkdm->usecount));
+ seq_printf(s, "\n");
+
+ return 0;
+}
+
+static int pwrdm_dbg_show_counter(struct powerdomain *pwrdm, void *user)
+{
+ struct seq_file *s = (struct seq_file *)user;
+ int i;
+
+ if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
+ strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
+ strncmp(pwrdm->name, "dpll", 4) == 0)
+ return 0;
+
+ if (pwrdm->state != pwrdm_read_pwrst(pwrdm))
+ printk(KERN_ERR "pwrdm state mismatch(%s) %d != %d\n",
+ pwrdm->name, pwrdm->state, pwrdm_read_pwrst(pwrdm));
+
+ seq_printf(s, "%s (%s)", pwrdm->name,
+ pwrdm_state_names[pwrdm->state]);
+ for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+ seq_printf(s, ",%s:%d", pwrdm_state_names[i],
+ pwrdm->state_counter[i]);
+
+ seq_printf(s, ",RET-LOGIC-OFF:%d", pwrdm->ret_logic_off_counter);
+ for (i = 0; i < pwrdm->banks; i++)
+ seq_printf(s, ",RET-MEMBANK%d-OFF:%d", i + 1,
+ pwrdm->ret_mem_off_counter[i]);
+
+ seq_printf(s, "\n");
+
+ return 0;
+}
+
+static int pwrdm_dbg_show_timer(struct powerdomain *pwrdm, void *user)
+{
+ struct seq_file *s = (struct seq_file *)user;
+ int i;
+
+ if (strcmp(pwrdm->name, "emu_pwrdm") == 0 ||
+ strcmp(pwrdm->name, "wkup_pwrdm") == 0 ||
+ strncmp(pwrdm->name, "dpll", 4) == 0)
+ return 0;
+
+ pwrdm_state_switch(pwrdm);
+
+ seq_printf(s, "%s (%s)", pwrdm->name,
+ pwrdm_state_names[pwrdm->state]);
+
+ for (i = 0; i < 4; i++)
+ seq_printf(s, ",%s:%lld", pwrdm_state_names[i],
+ pwrdm->state_timer[i]);
+
+ seq_printf(s, "\n");
+ return 0;
+}
+
+static int pm_dbg_show_counters(struct seq_file *s, void *unused)
+{
+ pwrdm_for_each(pwrdm_dbg_show_counter, s);
+ clkdm_for_each(clkdm_dbg_show_counter, s);
+
+ return 0;
+}
+
+static int pm_dbg_show_timers(struct seq_file *s, void *unused)
+{
+ pwrdm_for_each(pwrdm_dbg_show_timer, s);
+ return 0;
+}
+
+static int pm_dbg_open(struct inode *inode, struct file *file)
+{
+ switch ((int)inode->i_private) {
+ case DEBUG_FILE_COUNTERS:
+ return single_open(file, pm_dbg_show_counters,
+ &inode->i_private);
+ case DEBUG_FILE_TIMERS:
+ default:
+ return single_open(file, pm_dbg_show_timers,
+ &inode->i_private);
+ };
+}
+
+static int pm_dbg_reg_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pm_dbg_show_regs, inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = pm_dbg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations debug_reg_fops = {
+ .open = pm_dbg_reg_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+int pm_dbg_regset_init(int reg_set)
+{
+ char name[2];
+
+ if (!pm_dbg_init_done)
+ pm_dbg_init();
+
+ if (reg_set < 1 || reg_set > PM_DBG_MAX_REG_SETS ||
+ pm_dbg_reg_set[reg_set-1] != NULL)
+ return -EINVAL;
+
+ pm_dbg_reg_set[reg_set-1] =
+ kmalloc(pm_dbg_get_regset_size(), GFP_KERNEL);
+
+ if (pm_dbg_reg_set[reg_set-1] == NULL)
+ return -ENOMEM;
+
+ if (pm_dbg_dir != NULL) {
+ sprintf(name, "%d", reg_set);
+
+ (void) debugfs_create_file(name, S_IRUGO,
+ pm_dbg_dir, (void *)reg_set, &debug_reg_fops);
+ }
+
+ return 0;
+}
+
+static int pwrdm_suspend_get(void *data, u64 *val)
+{
+ int ret = -EINVAL;
+
+ if (cpu_is_omap34xx())
+ ret = omap3_pm_get_suspend_state((struct powerdomain *)data);
+ *val = ret;
+
+ if (ret >= 0)
+ return 0;
+ return *val;
+}
+
+static int pwrdm_suspend_set(void *data, u64 val)
+{
+ if (cpu_is_omap34xx())
+ return omap3_pm_set_suspend_state(
+ (struct powerdomain *)data, (int)val);
+ return -EINVAL;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pwrdm_suspend_fops, pwrdm_suspend_get,
+ pwrdm_suspend_set, "%llu\n");
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *dir)
+{
+ int i;
+ s64 t;
+ struct dentry *d;
+
+ t = sched_clock();
+
+ for (i = 0; i < 4; i++)
+ pwrdm->state_timer[i] = 0;
+
+ pwrdm->timer = t;
+
+ if (strncmp(pwrdm->name, "dpll", 4) == 0)
+ return 0;
+
+ d = debugfs_create_dir(pwrdm->name, (struct dentry *)dir);
+
+ (void) debugfs_create_file("suspend", S_IRUGO|S_IWUSR, d,
+ (void *)pwrdm, &pwrdm_suspend_fops);
+
+ return 0;
+}
+
+static int option_get(void *data, u64 *val)
+{
+ u32 *option = data;
+
+ *val = *option;
+
+ return 0;
+}
+
+static int option_set(void *data, u64 val)
+{
+ u32 *option = data;
+
+ if (option == &wakeup_timer_milliseconds && val >= 1000)
+ return -EINVAL;
+
+ *option = val;
+
+ if (option == &enable_off_mode) {
+ if (val)
+ omap_pm_enable_off_mode();
+ else
+ omap_pm_disable_off_mode();
+ if (cpu_is_omap34xx())
+ omap3_pm_off_mode_enable(val);
+ }
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
+
+static int pm_dbg_init(void)
+{
+ int i;
+ struct dentry *d;
+ char name[2];
+
+ if (pm_dbg_init_done)
+ return 0;
+
+ if (cpu_is_omap34xx())
+ pm_dbg_reg_modules = omap3_pm_reg_modules;
+ else {
+ printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
+ return -ENODEV;
+ }
+
+ d = debugfs_create_dir("pm_debug", NULL);
+ if (IS_ERR(d))
+ return PTR_ERR(d);
+
+ (void) debugfs_create_file("count", S_IRUGO,
+ d, (void *)DEBUG_FILE_COUNTERS, &debug_fops);
+ (void) debugfs_create_file("time", S_IRUGO,
+ d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
+
+ pwrdm_for_each(pwrdms_setup, (void *)d);
+
+ pm_dbg_dir = debugfs_create_dir("registers", d);
+ if (IS_ERR(pm_dbg_dir))
+ return PTR_ERR(pm_dbg_dir);
+
+ (void) debugfs_create_file("current", S_IRUGO,
+ pm_dbg_dir, (void *)0, &debug_reg_fops);
+
+ for (i = 0; i < PM_DBG_MAX_REG_SETS; i++)
+ if (pm_dbg_reg_set[i] != NULL) {
+ sprintf(name, "%d", i+1);
+ (void) debugfs_create_file(name, S_IRUGO,
+ pm_dbg_dir, (void *)(i+1), &debug_reg_fops);
+
+ }
+
+ (void) debugfs_create_file("enable_off_mode", S_IRUGO | S_IWUSR, d,
+ &enable_off_mode, &pm_dbg_option_fops);
+ (void) debugfs_create_file("sleep_while_idle", S_IRUGO | S_IWUSR, d,
+ &sleep_while_idle, &pm_dbg_option_fops);
+ (void) debugfs_create_file("wakeup_timer_seconds", S_IRUGO | S_IWUSR, d,
+ &wakeup_timer_seconds, &pm_dbg_option_fops);
+ (void) debugfs_create_file("wakeup_timer_milliseconds",
+ S_IRUGO | S_IWUSR, d, &wakeup_timer_milliseconds,
+ &pm_dbg_option_fops);
+ pm_dbg_init_done = 1;
+
+ return 0;
+}
+arch_initcall(pm_dbg_init);
+
+#endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644
index 00000000..49486f52
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,270 @@
+/*
+ * pm.c - Common OMAP2+ power management-related code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/opp.h>
+
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+#include <plat/common.h>
+
+#include "voltage.h"
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include "pm.h"
+
+static struct omap_device_pm_latency *pm_lats;
+
+static struct device *mpu_dev;
+static struct device *iva_dev;
+static struct device *l3_dev;
+static struct device *dsp_dev;
+
+struct device *omap2_get_mpuss_device(void)
+{
+ WARN_ON_ONCE(!mpu_dev);
+ return mpu_dev;
+}
+
+struct device *omap2_get_iva_device(void)
+{
+ WARN_ON_ONCE(!iva_dev);
+ return iva_dev;
+}
+
+struct device *omap2_get_l3_device(void)
+{
+ WARN_ON_ONCE(!l3_dev);
+ return l3_dev;
+}
+
+struct device *omap4_get_dsp_device(void)
+{
+ WARN_ON_ONCE(!dsp_dev);
+ return dsp_dev;
+}
+EXPORT_SYMBOL(omap4_get_dsp_device);
+
+/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
+static int _init_omap_device(char *name, struct device **new_dev)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+
+ oh = omap_hwmod_lookup(name);
+ if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
+ if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ *new_dev = &od->pdev.dev;
+
+ return 0;
+}
+
+/*
+ * Build omap_devices for processors and bus.
+ */
+static void omap2_init_processor_devices(void)
+{
+ _init_omap_device("mpu", &mpu_dev);
+ if (omap3_has_iva())
+ _init_omap_device("iva", &iva_dev);
+
+ if (cpu_is_omap44xx()) {
+ _init_omap_device("l3_main_1", &l3_dev);
+ _init_omap_device("dsp", &dsp_dev);
+ _init_omap_device("iva", &iva_dev);
+ } else {
+ _init_omap_device("l3_main", &l3_dev);
+ }
+}
+
+/* Types of sleep_switch used in omap_set_pwrdm_state */
+#define FORCEWAKEUP_SWITCH 0
+#define LOWPOWERSTATE_SWITCH 1
+
+/*
+ * This sets pwrdm state (other than mpu & core. Currently only ON &
+ * RET are supported.
+ */
+int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
+{
+ u32 cur_state;
+ int sleep_switch = 0;
+ int ret = 0;
+
+ if (pwrdm == NULL || IS_ERR(pwrdm))
+ return -EINVAL;
+
+ while (!(pwrdm->pwrsts & (1 << state))) {
+ if (state == PWRDM_POWER_OFF)
+ return ret;
+ state--;
+ }
+
+ cur_state = pwrdm_read_next_pwrst(pwrdm);
+ if (cur_state == state)
+ return ret;
+
+ if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
+ if ((pwrdm_read_pwrst(pwrdm) > state) &&
+ (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) {
+ sleep_switch = LOWPOWERSTATE_SWITCH;
+ } else {
+ clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
+ pwrdm_wait_transition(pwrdm);
+ sleep_switch = FORCEWAKEUP_SWITCH;
+ }
+ }
+
+ ret = pwrdm_set_next_pwrst(pwrdm, state);
+ if (ret) {
+ printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
+ pwrdm->name);
+ goto err;
+ }
+
+ switch (sleep_switch) {
+ case FORCEWAKEUP_SWITCH:
+ if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO)
+ clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
+ else
+ clkdm_sleep(pwrdm->pwrdm_clkdms[0]);
+ break;
+ case LOWPOWERSTATE_SWITCH:
+ pwrdm_set_lowpwrstchange(pwrdm);
+ break;
+ default:
+ return ret;
+ }
+
+ pwrdm_wait_transition(pwrdm);
+ pwrdm_state_switch(pwrdm);
+err:
+ return ret;
+}
+
+/*
+ * This API is to be called during init to put the various voltage
+ * domains to the voltage as per the opp table. Typically we boot up
+ * at the nominal voltage. So this function finds out the rate of
+ * the clock associated with the voltage domain, finds out the correct
+ * opp entry and puts the voltage domain to the voltage specifies
+ * in the opp entry
+ */
+static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
+ struct device *dev)
+{
+ struct voltagedomain *voltdm;
+ struct clk *clk;
+ struct opp *opp;
+ unsigned long freq, bootup_volt;
+
+ if (!vdd_name || !clk_name || !dev) {
+ printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
+ goto exit;
+ }
+
+ voltdm = omap_voltage_domain_lookup(vdd_name);
+ if (IS_ERR(voltdm)) {
+ printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ clk = clk_get(NULL, clk_name);
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "%s: unable to get clk %s\n",
+ __func__, clk_name);
+ goto exit;
+ }
+
+ freq = clk->rate;
+ clk_put(clk);
+
+ opp = opp_find_freq_ceil(dev, &freq);
+ if (IS_ERR(opp)) {
+ printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n",
+ __func__, vdd_name);
+ goto exit;
+ }
+
+ bootup_volt = opp_get_voltage(opp);
+ if (!bootup_volt) {
+ printk(KERN_ERR "%s: unable to find voltage corresponding"
+ "to the bootup OPP for vdd_%s\n", __func__, vdd_name);
+ goto exit;
+ }
+
+ omap_voltage_scale_vdd(voltdm, bootup_volt);
+ return 0;
+
+exit:
+ printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n",
+ __func__, vdd_name);
+ return -EINVAL;
+}
+
+static void __init omap3_init_voltages(void)
+{
+ if (!cpu_is_omap34xx())
+ return;
+
+ omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev);
+ omap2_set_init_voltage("core", "l3_ick", l3_dev);
+}
+
+static void __init omap4_init_voltages(void)
+{
+ if (!cpu_is_omap44xx())
+ return;
+
+ omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
+ omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
+ omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
+}
+
+static int __init omap2_common_pm_init(void)
+{
+ omap2_init_processor_devices();
+ omap_pm_if_init();
+
+ return 0;
+}
+postcore_initcall(omap2_common_pm_init);
+
+static int __init omap2_common_pm_late_init(void)
+{
+ /* Init the OMAP TWL parameters */
+ omap3_twl_init();
+ omap4_twl_init();
+
+ /* Init the voltage layer */
+ omap_voltage_late_init();
+
+ /* Initialize the voltages */
+ omap3_init_voltages();
+ omap4_init_voltages();
+
+ /* Smartreflex device init */
+ omap_devinit_smartreflex();
+
+ return 0;
+}
+late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
new file mode 100644
index 00000000..45bcfce7
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.h
@@ -0,0 +1,143 @@
+/*
+ * OMAP2/3 Power Management Routines
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Jouni Hogander
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
+#define __ARCH_ARM_MACH_OMAP2_PM_H
+
+#include <linux/err.h>
+
+#include "powerdomain.h"
+
+extern void *omap3_secure_ram_storage;
+extern void omap3_pm_off_mode_enable(int);
+extern void omap_sram_idle(void);
+extern int omap3_can_sleep(void);
+extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int omap3_idle_init(void);
+
+#if defined(CONFIG_PM_OPP)
+extern int omap3_opp_init(void);
+extern int omap4_opp_init(void);
+#else
+static inline int omap3_opp_init(void)
+{
+ return -EINVAL;
+}
+static inline int omap4_opp_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+/*
+ * cpuidle mach specific parameters
+ *
+ * The board code can override the default C-states definition using
+ * omap3_pm_init_cpuidle
+ */
+struct cpuidle_params {
+ u32 exit_latency; /* exit_latency = sleep + wake-up latencies */
+ u32 target_residency;
+ u8 valid; /* validates the C-state */
+};
+
+#if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
+extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params);
+#else
+static
+inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
+{
+}
+#endif
+
+extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
+extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
+
+extern u32 wakeup_timer_seconds;
+extern u32 wakeup_timer_milliseconds;
+extern struct omap_dm_timer *gptimer_wakeup;
+
+#ifdef CONFIG_PM_DEBUG
+extern void omap2_pm_dump(int mode, int resume, unsigned int us);
+extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds);
+extern int omap2_pm_debug;
+extern u32 enable_off_mode;
+extern u32 sleep_while_idle;
+#else
+#define omap2_pm_dump(mode, resume, us) do {} while (0);
+#define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0);
+#define omap2_pm_debug 0
+#define enable_off_mode 0
+#define sleep_while_idle 0
+#endif
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev);
+extern int pm_dbg_regset_save(int reg_set);
+extern int pm_dbg_regset_init(int reg_set);
+#else
+#define pm_dbg_update_time(pwrdm, prev) do {} while (0);
+#define pm_dbg_regset_save(reg_set) do {} while (0);
+#define pm_dbg_regset_init(reg_set) do {} while (0);
+#endif /* CONFIG_PM_DEBUG */
+
+extern void omap24xx_idle_loop_suspend(void);
+
+extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
+ void __iomem *sdrc_power);
+extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
+extern int save_secure_ram_context(u32 *addr);
+extern void omap3_save_scratchpad_contents(void);
+
+extern unsigned int omap24xx_idle_loop_suspend_sz;
+extern unsigned int save_secure_ram_context_sz;
+extern unsigned int omap24xx_cpu_suspend_sz;
+extern unsigned int omap34xx_cpu_suspend_sz;
+
+#define PM_RTA_ERRATUM_i608 (1 << 0)
+#define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1)
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+extern u16 pm34xx_errata;
+#define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id))
+extern void enable_omap3630_toggle_l2_on_restore(void);
+#else
+#define IS_PM34XX_ERRATUM(id) 0
+static inline void enable_omap3630_toggle_l2_on_restore(void) { }
+#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+extern int omap_devinit_smartreflex(void);
+extern void omap_enable_smartreflex_on_init(void);
+#else
+static inline int omap_devinit_smartreflex(void)
+{
+ return -EINVAL;
+}
+
+static inline void omap_enable_smartreflex_on_init(void) {}
+#endif
+
+#ifdef CONFIG_TWL4030_CORE
+extern int omap3_twl_init(void);
+extern int omap4_twl_init(void);
+extern int omap3_twl_set_sr_bit(bool enable);
+#else
+static inline int omap3_twl_init(void)
+{
+ return -EINVAL;
+}
+static inline int omap4_twl_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
new file mode 100644
index 00000000..df3ded6f
--- /dev/null
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -0,0 +1,524 @@
+/*
+ * OMAP2 Power Management Routines
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Copyright (C) 2006-2008 Nokia Corporation
+ *
+ * Written by:
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Tony Lindgren
+ * Juha Yrjola
+ * Amit Kucheria <amit.kucheria@nokia.com>
+ * Igor Stoppa <igor.stoppa@nokia.com>
+ *
+ * Based on pm.c for omap1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/suspend.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <linux/gpio.h>
+#include <linux/console.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+#include <plat/dma.h>
+#include <plat/board.h>
+
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "sdrc.h"
+#include "pm.h"
+#include "control.h"
+
+#include "powerdomain.h"
+#include "clockdomain.h"
+
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
+
+static void (*omap2_sram_idle)(void);
+static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,
+ void __iomem *sdrc_power);
+
+static struct powerdomain *mpu_pwrdm, *core_pwrdm;
+static struct clockdomain *dsp_clkdm, *mpu_clkdm, *wkup_clkdm, *gfx_clkdm;
+
+static struct clk *osc_ck, *emul_ck;
+
+static int omap2_fclks_active(void)
+{
+ u32 f1, f2;
+
+ f1 = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ f2 = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+
+ /* Ignore UART clocks. These are handled by UART core (serial.c) */
+ f1 &= ~(OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_UART2_MASK);
+ f2 &= ~OMAP24XX_EN_UART3_MASK;
+
+ if (f1 | f2)
+ return 1;
+ return 0;
+}
+
+static void omap2_enter_full_retention(void)
+{
+ u32 l;
+ struct timespec ts_preidle, ts_postidle, ts_idle;
+
+ /* There is 1 reference hold for all children of the oscillator
+ * clock, the following will remove it. If no one else uses the
+ * oscillator itself it will be disabled if/when we enter retention
+ * mode.
+ */
+ clk_disable(osc_ck);
+
+ /* Clear old wake-up events */
+ /* REVISIT: These write to reserved bits? */
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
+
+ /*
+ * Set MPU powerdomain's next power state to RETENTION;
+ * preserve logic state during retention
+ */
+ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+
+ /* Workaround to kill USB */
+ l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
+ omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
+
+ omap2_gpio_prepare_for_idle(0);
+
+ if (omap2_pm_debug) {
+ omap2_pm_dump(0, 0, 0);
+ getnstimeofday(&ts_preidle);
+ }
+
+ /* One last check for pending IRQs to avoid extra latency due
+ * to sleeping unnecessarily. */
+ if (omap_irq_pending())
+ goto no_sleep;
+
+ /* Block console output in case it is on one of the OMAP UARTs */
+ if (!is_suspending())
+ if (!console_trylock())
+ goto no_sleep;
+
+ omap_uart_prepare_idle(0);
+ omap_uart_prepare_idle(1);
+ omap_uart_prepare_idle(2);
+
+ /* Jump to SRAM suspend code */
+ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
+ OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
+ OMAP_SDRC_REGADDR(SDRC_POWER));
+
+ omap_uart_resume_idle(2);
+ omap_uart_resume_idle(1);
+ omap_uart_resume_idle(0);
+
+ if (!is_suspending())
+ console_unlock();
+
+no_sleep:
+ if (omap2_pm_debug) {
+ unsigned long long tmp;
+
+ getnstimeofday(&ts_postidle);
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
+ tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
+ omap2_pm_dump(0, 1, tmp);
+ }
+ omap2_gpio_resume_after_idle();
+
+ clk_enable(osc_ck);
+
+ /* clear CORE wake-up events */
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+
+ /* wakeup domain events - bit 1: GPT1, bit5 GPIO */
+ omap2_prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST);
+
+ /* MPU domain wake events */
+ l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+ if (l & 0x01)
+ omap2_prm_write_mod_reg(0x01, OCP_MOD,
+ OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+ if (l & 0x20)
+ omap2_prm_write_mod_reg(0x20, OCP_MOD,
+ OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+
+ /* Mask future PRCM-to-MPU interrupts */
+ omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
+}
+
+static int omap2_i2c_active(void)
+{
+ u32 l;
+
+ l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK);
+}
+
+static int sti_console_enabled;
+
+static int omap2_allow_mpu_retention(void)
+{
+ u32 l;
+
+ /* Check for MMC, UART2, UART1, McSPI2, McSPI1 and DSS1. */
+ l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
+ if (l & (OMAP2420_EN_MMC_MASK | OMAP24XX_EN_UART2_MASK |
+ OMAP24XX_EN_UART1_MASK | OMAP24XX_EN_MCSPI2_MASK |
+ OMAP24XX_EN_MCSPI1_MASK | OMAP24XX_EN_DSS1_MASK))
+ return 0;
+ /* Check for UART3. */
+ l = omap2_cm_read_mod_reg(CORE_MOD, OMAP24XX_CM_FCLKEN2);
+ if (l & OMAP24XX_EN_UART3_MASK)
+ return 0;
+ if (sti_console_enabled)
+ return 0;
+
+ return 1;
+}
+
+static void omap2_enter_mpu_retention(void)
+{
+ int only_idle = 0;
+ struct timespec ts_preidle, ts_postidle, ts_idle;
+
+ /* Putting MPU into the WFI state while a transfer is active
+ * seems to cause the I2C block to timeout. Why? Good question. */
+ if (omap2_i2c_active())
+ return;
+
+ /* The peripherals seem not to be able to wake up the MPU when
+ * it is in retention mode. */
+ if (omap2_allow_mpu_retention()) {
+ /* REVISIT: These write to reserved bits? */
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);
+ omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);
+
+ /* Try to enter MPU retention */
+ omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) |
+ OMAP_LOGICRETSTATE_MASK,
+ MPU_MOD, OMAP2_PM_PWSTCTRL);
+ } else {
+ /* Block MPU retention */
+
+ omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD,
+ OMAP2_PM_PWSTCTRL);
+ only_idle = 1;
+ }
+
+ if (omap2_pm_debug) {
+ omap2_pm_dump(only_idle ? 2 : 1, 0, 0);
+ getnstimeofday(&ts_preidle);
+ }
+
+ omap2_sram_idle();
+
+ if (omap2_pm_debug) {
+ unsigned long long tmp;
+
+ getnstimeofday(&ts_postidle);
+ ts_idle = timespec_sub(ts_postidle, ts_preidle);
+ tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
+ omap2_pm_dump(only_idle ? 2 : 1, 1, tmp);
+ }
+}
+
+static int omap2_can_sleep(void)
+{
+ if (omap2_fclks_active())
+ return 0;
+ if (!omap_uart_can_sleep())
+ return 0;
+ if (osc_ck->usecount > 1)
+ return 0;
+ if (omap_dma_running())
+ return 0;
+
+ return 1;
+}
+
+static void omap2_pm_idle(void)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ if (!omap2_can_sleep()) {
+ if (omap_irq_pending())
+ goto out;
+ omap2_enter_mpu_retention();
+ goto out;
+ }
+
+ if (omap_irq_pending())
+ goto out;
+
+ omap2_enter_full_retention();
+
+out:
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+#ifdef CONFIG_SUSPEND
+static int omap2_pm_begin(suspend_state_t state)
+{
+ disable_hlt();
+ suspend_state = state;
+ return 0;
+}
+
+static int omap2_pm_suspend(void)
+{
+ u32 wken_wkup, mir1;
+
+ wken_wkup = omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+ wken_wkup &= ~OMAP24XX_EN_GPT1_MASK;
+ omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
+
+ /* Mask GPT1 */
+ mir1 = omap_readl(0x480fe0a4);
+ omap_writel(1 << 5, 0x480fe0ac);
+
+ omap_uart_prepare_suspend();
+ omap2_enter_full_retention();
+
+ omap_writel(mir1, 0x480fe0a4);
+ omap2_prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN);
+
+ return 0;
+}
+
+static int omap2_pm_enter(suspend_state_t state)
+{
+ int ret = 0;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ ret = omap2_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void omap2_pm_end(void)
+{
+ suspend_state = PM_SUSPEND_ON;
+ enable_hlt();
+}
+
+static const struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap2_pm_begin,
+ .enter = omap2_pm_enter,
+ .end = omap2_pm_end,
+ .valid = suspend_valid_only_mem,
+};
+#else
+static const struct platform_suspend_ops __initdata omap_pm_ops;
+#endif /* CONFIG_SUSPEND */
+
+/* XXX This function should be shareable between OMAP2xxx and OMAP3 */
+static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
+{
+ if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+ clkdm_allow_idle(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+ atomic_read(&clkdm->usecount) == 0)
+ clkdm_sleep(clkdm);
+ return 0;
+}
+
+static void __init prcm_setup_regs(void)
+{
+ int i, num_mem_banks;
+ struct powerdomain *pwrdm;
+
+ /*
+ * Enable autoidle
+ * XXX This should be handled by hwmod code or PRCM init code
+ */
+ omap2_prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD,
+ OMAP2_PRCM_SYSCONFIG_OFFSET);
+
+ /*
+ * Set CORE powerdomain memory banks to retain their contents
+ * during RETENTION
+ */
+ num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm);
+ for (i = 0; i < num_mem_banks; i++)
+ pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET);
+
+ /* Set CORE powerdomain's next power state to RETENTION */
+ pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);
+
+ /*
+ * Set MPU powerdomain's next power state to RETENTION;
+ * preserve logic state during retention
+ */
+ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET);
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);
+
+ /* Force-power down DSP, GFX powerdomains */
+
+ pwrdm = clkdm_get_pwrdm(dsp_clkdm);
+ pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+ clkdm_sleep(dsp_clkdm);
+
+ pwrdm = clkdm_get_pwrdm(gfx_clkdm);
+ pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
+ clkdm_sleep(gfx_clkdm);
+
+ /* Enable hardware-supervised idle for all clkdms */
+ clkdm_for_each(clkdms_setup, NULL);
+ clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
+
+ /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk
+ * stabilisation */
+ omap2_prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP2_PRCM_CLKSSETUP_OFFSET);
+
+ /* Configure automatic voltage transition */
+ omap2_prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD,
+ OMAP2_PRCM_VOLTSETUP_OFFSET);
+ omap2_prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK |
+ (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) |
+ OMAP24XX_MEMRETCTRL_MASK |
+ (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) |
+ (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT),
+ OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET);
+
+ /* Enable wake-up events */
+ omap2_prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK,
+ WKUP_MOD, PM_WKEN);
+}
+
+static int __init omap2_pm_init(void)
+{
+ u32 l;
+
+ if (!cpu_is_omap24xx())
+ return -ENODEV;
+
+ printk(KERN_INFO "Power Management for OMAP2 initializing\n");
+ l = omap2_prm_read_mod_reg(OCP_MOD, OMAP2_PRCM_REVISION_OFFSET);
+ printk(KERN_INFO "PRCM revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
+
+ /* Look up important powerdomains */
+
+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+ if (!mpu_pwrdm)
+ pr_err("PM: mpu_pwrdm not found\n");
+
+ core_pwrdm = pwrdm_lookup("core_pwrdm");
+ if (!core_pwrdm)
+ pr_err("PM: core_pwrdm not found\n");
+
+ /* Look up important clockdomains */
+
+ mpu_clkdm = clkdm_lookup("mpu_clkdm");
+ if (!mpu_clkdm)
+ pr_err("PM: mpu_clkdm not found\n");
+
+ wkup_clkdm = clkdm_lookup("wkup_clkdm");
+ if (!wkup_clkdm)
+ pr_err("PM: wkup_clkdm not found\n");
+
+ dsp_clkdm = clkdm_lookup("dsp_clkdm");
+ if (!dsp_clkdm)
+ pr_err("PM: dsp_clkdm not found\n");
+
+ gfx_clkdm = clkdm_lookup("gfx_clkdm");
+ if (!gfx_clkdm)
+ pr_err("PM: gfx_clkdm not found\n");
+
+
+ osc_ck = clk_get(NULL, "osc_ck");
+ if (IS_ERR(osc_ck)) {
+ printk(KERN_ERR "could not get osc_ck\n");
+ return -ENODEV;
+ }
+
+ if (cpu_is_omap242x()) {
+ emul_ck = clk_get(NULL, "emul_ck");
+ if (IS_ERR(emul_ck)) {
+ printk(KERN_ERR "could not get emul_ck\n");
+ clk_put(osc_ck);
+ return -ENODEV;
+ }
+ }
+
+ prcm_setup_regs();
+
+ /* Hack to prevent MPU retention when STI console is enabled. */
+ {
+ const struct omap_sti_console_config *sti;
+
+ sti = omap_get_config(OMAP_TAG_STI_CONSOLE,
+ struct omap_sti_console_config);
+ if (sti != NULL && sti->enable)
+ sti_console_enabled = 1;
+ }
+
+ /*
+ * We copy the assembler sleep/wakeup routines to SRAM.
+ * These routines need to be in SRAM as that's the only
+ * memory the MPU can see when it wakes up.
+ */
+ if (cpu_is_omap24xx()) {
+ omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend,
+ omap24xx_idle_loop_suspend_sz);
+
+ omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,
+ omap24xx_cpu_suspend_sz);
+ }
+
+ suspend_set_ops(&omap_pm_ops);
+ pm_idle = omap2_pm_idle;
+
+ return 0;
+}
+
+late_initcall(omap2_pm_init);
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
new file mode 100644
index 00000000..c155c9d1
--- /dev/null
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -0,0 +1,970 @@
+/*
+ * OMAP3 Power Management Routines
+ *
+ * Copyright (C) 2006-2008 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * Jouni Hogander
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * Copyright (C) 2005 Texas Instruments, Inc.
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * Based on pm.c for omap1
+ *
+ * This program is free software; you can 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/pm.h>
+#include <linux/suspend.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/console.h>
+#include <trace/events/power.h>
+
+#include <plat/sram.h>
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include <plat/serial.h>
+#include <plat/sdrc.h>
+#include <plat/prcm.h>
+#include <plat/gpmc.h>
+#include <plat/dma.h>
+
+#include <asm/tlbflush.h>
+
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+
+#include "prm2xxx_3xxx.h"
+#include "pm.h"
+#include "sdrc.h"
+#include "control.h"
+
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state = PM_SUSPEND_ON;
+static inline bool is_suspending(void)
+{
+ return (suspend_state != PM_SUSPEND_ON);
+}
+#else
+static inline bool is_suspending(void)
+{
+ return false;
+}
+#endif
+
+/* Scratchpad offsets */
+#define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4
+#define OMAP343X_TABLE_VALUE_OFFSET 0xc0
+#define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8
+
+/* pm34xx errata defined in pm.h */
+u16 pm34xx_errata;
+
+struct power_state {
+ struct powerdomain *pwrdm;
+ u32 next_state;
+#ifdef CONFIG_SUSPEND
+ u32 saved_state;
+#endif
+ struct list_head node;
+};
+
+static LIST_HEAD(pwrst_list);
+
+static void (*_omap_sram_idle)(u32 *addr, int save_state);
+
+static int (*_omap_save_secure_sram)(u32 *addr);
+
+static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
+static struct powerdomain *core_pwrdm, *per_pwrdm;
+static struct powerdomain *cam_pwrdm;
+
+static inline void omap3_per_save_context(void)
+{
+ omap_gpio_save_context();
+}
+
+static inline void omap3_per_restore_context(void)
+{
+ omap_gpio_restore_context();
+}
+
+static void omap3_enable_io_chain(void)
+{
+ int timeout = 0;
+
+ if (omap_rev() >= OMAP3430_REV_ES3_1) {
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+ /* Do a readback to assure write has been done */
+ omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
+
+ while (!(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN) &
+ OMAP3430_ST_IO_CHAIN_MASK)) {
+ timeout++;
+ if (timeout > 1000) {
+ printk(KERN_ERR "Wake up daisy chain "
+ "activation failed.\n");
+ return;
+ }
+ omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK,
+ WKUP_MOD, PM_WKEN);
+ }
+ }
+}
+
+static void omap3_disable_io_chain(void)
+{
+ if (omap_rev() >= OMAP3430_REV_ES3_1)
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
+ PM_WKEN);
+}
+
+static void omap3_core_save_context(void)
+{
+ omap3_ctrl_save_padconf();
+
+ /*
+ * Force write last pad into memory, as this can fail in some
+ * cases according to errata 1.157, 1.185
+ */
+ omap_ctrl_writel(omap_ctrl_readl(OMAP343X_PADCONF_ETK_D14),
+ OMAP343X_CONTROL_MEM_WKUP + 0x2a0);
+
+ /* Save the Interrupt controller context */
+ omap_intc_save_context();
+ /* Save the GPMC context */
+ omap3_gpmc_save_context();
+ /* Save the system control module context, padconf already save above*/
+ omap3_control_save_context();
+ omap_dma_global_context_save();
+}
+
+static void omap3_core_restore_context(void)
+{
+ /* Restore the control module context, padconf restored by h/w */
+ omap3_control_restore_context();
+ /* Restore the GPMC context */
+ omap3_gpmc_restore_context();
+ /* Restore the interrupt controller context */
+ omap_intc_restore_context();
+ omap_dma_global_context_restore();
+}
+
+/*
+ * FIXME: This function should be called before entering off-mode after
+ * OMAP3 secure services have been accessed. Currently it is only called
+ * once during boot sequence, but this works as we are not using secure
+ * services.
+ */
+static void omap3_save_secure_ram_context(void)
+{
+ u32 ret;
+ int mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ /*
+ * MPU next state must be set to POWER_ON temporarily,
+ * otherwise the WFI executed inside the ROM code
+ * will hang the system.
+ */
+ pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
+ ret = _omap_save_secure_sram((u32 *)
+ __pa(omap3_secure_ram_storage));
+ pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state);
+ /* Following is for error tracking, it should not happen */
+ if (ret) {
+ printk(KERN_ERR "save_secure_sram() returns %08x\n",
+ ret);
+ while (1)
+ ;
+ }
+ }
+}
+
+/*
+ * PRCM Interrupt Handler Helper Function
+ *
+ * The purpose of this function is to clear any wake-up events latched
+ * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
+ * may occur whilst attempting to clear a PM_WKST_x register and thus
+ * set another bit in this register. A while loop is used to ensure
+ * that any peripheral wake-up events occurring while attempting to
+ * clear the PM_WKST_x are detected and cleared.
+ */
+static int prcm_clear_mod_irqs(s16 module, u8 regs)
+{
+ u32 wkst, fclk, iclk, clken;
+ u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
+ u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
+ u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
+ u16 grpsel_off = (regs == 3) ?
+ OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
+ int c = 0;
+
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
+ wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
+ if (wkst) {
+ iclk = omap2_cm_read_mod_reg(module, iclk_off);
+ fclk = omap2_cm_read_mod_reg(module, fclk_off);
+ while (wkst) {
+ clken = wkst;
+ omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
+ /*
+ * For USBHOST, we don't know whether HOST1 or
+ * HOST2 woke us up, so enable both f-clocks
+ */
+ if (module == OMAP3430ES2_USBHOST_MOD)
+ clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
+ omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
+ omap2_prm_write_mod_reg(wkst, module, wkst_off);
+ wkst = omap2_prm_read_mod_reg(module, wkst_off);
+ c++;
+ }
+ omap2_cm_write_mod_reg(iclk, module, iclk_off);
+ omap2_cm_write_mod_reg(fclk, module, fclk_off);
+ }
+
+ return c;
+}
+
+static int _prcm_int_handle_wakeup(void)
+{
+ int c;
+
+ c = prcm_clear_mod_irqs(WKUP_MOD, 1);
+ c += prcm_clear_mod_irqs(CORE_MOD, 1);
+ c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ c += prcm_clear_mod_irqs(CORE_MOD, 3);
+ c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
+ }
+
+ return c;
+}
+
+/*
+ * PRCM Interrupt Handler
+ *
+ * The PRM_IRQSTATUS_MPU register indicates if there are any pending
+ * interrupts from the PRCM for the MPU. These bits must be cleared in
+ * order to clear the PRCM interrupt. The PRCM interrupt handler is
+ * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
+ * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
+ * register indicates that a wake-up event is pending for the MPU and
+ * this bit can only be cleared if the all the wake-up events latched
+ * in the various PM_WKST_x registers have been cleared. The interrupt
+ * handler is implemented using a do-while loop so that if a wake-up
+ * event occurred during the processing of the prcm interrupt handler
+ * (setting a bit in the corresponding PM_WKST_x register and thus
+ * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
+ * this would be handled.
+ */
+static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
+{
+ u32 irqenable_mpu, irqstatus_mpu;
+ int c = 0;
+
+ irqenable_mpu = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+ irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ irqstatus_mpu &= irqenable_mpu;
+
+ do {
+ if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK |
+ OMAP3430_IO_ST_MASK)) {
+ c = _prcm_int_handle_wakeup();
+
+ /*
+ * Is the MPU PRCM interrupt handler racing with the
+ * IVA2 PRCM interrupt handler ?
+ */
+ WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
+ "but no wakeup sources are marked\n");
+ } else {
+ /* XXX we need to expand our PRCM interrupt handler */
+ WARN(1, "prcm: WARNING: PRCM interrupt received, but "
+ "no code to handle it (%08x)\n", irqstatus_mpu);
+ }
+
+ omap2_prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ irqstatus_mpu = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ irqstatus_mpu &= irqenable_mpu;
+
+ } while (irqstatus_mpu);
+
+ return IRQ_HANDLED;
+}
+
+/* Function to restore the table entry that was modified for enabling MMU */
+static void restore_table_entry(void)
+{
+ void __iomem *scratchpad_address;
+ u32 previous_value, control_reg_value;
+ u32 *address;
+
+ scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD);
+
+ /* Get address of entry that was modified */
+ address = (u32 *)__raw_readl(scratchpad_address +
+ OMAP343X_TABLE_ADDRESS_OFFSET);
+ /* Get the previous value which needs to be restored */
+ previous_value = __raw_readl(scratchpad_address +
+ OMAP343X_TABLE_VALUE_OFFSET);
+ address = __va(address);
+ *address = previous_value;
+ flush_tlb_all();
+ control_reg_value = __raw_readl(scratchpad_address
+ + OMAP343X_CONTROL_REG_VALUE_OFFSET);
+ /* This will enable caches and prediction */
+ set_cr(control_reg_value);
+}
+
+void omap_sram_idle(void)
+{
+ /* Variable to tell what needs to be saved and restored
+ * in omap_sram_idle*/
+ /* save_state = 0 => Nothing to save and restored */
+ /* save_state = 1 => Only L1 and logic lost */
+ /* save_state = 2 => Only L2 lost */
+ /* save_state = 3 => L1, L2 and logic lost */
+ int save_state = 0;
+ int mpu_next_state = PWRDM_POWER_ON;
+ int per_next_state = PWRDM_POWER_ON;
+ int core_next_state = PWRDM_POWER_ON;
+ int per_going_off;
+ int core_prev_state, per_prev_state;
+ u32 sdrc_pwr = 0;
+
+ if (!_omap_sram_idle)
+ return;
+
+ pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
+ pwrdm_clear_all_prev_pwrst(neon_pwrdm);
+ pwrdm_clear_all_prev_pwrst(core_pwrdm);
+ pwrdm_clear_all_prev_pwrst(per_pwrdm);
+
+ mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
+ switch (mpu_next_state) {
+ case PWRDM_POWER_ON:
+ case PWRDM_POWER_RET:
+ /* No need to save context */
+ save_state = 0;
+ break;
+ case PWRDM_POWER_OFF:
+ save_state = 3;
+ break;
+ default:
+ /* Invalid state */
+ printk(KERN_ERR "Invalid mpu state in sram_idle\n");
+ return;
+ }
+ pwrdm_pre_transition();
+
+ /* NEON control */
+ if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
+ pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
+
+ /* Enable IO-PAD and IO-CHAIN wakeups */
+ per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
+ core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
+ if (omap3_has_io_wakeup() &&
+ (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)) {
+ omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
+ omap3_enable_io_chain();
+ }
+
+ /* Block console output in case it is on one of the OMAP UARTs */
+ if (!is_suspending())
+ if (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)
+ if (!console_trylock())
+ goto console_still_active;
+
+ /* PER */
+ if (per_next_state < PWRDM_POWER_ON) {
+ per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
+ omap_uart_prepare_idle(2);
+ omap_uart_prepare_idle(3);
+ omap2_gpio_prepare_for_idle(per_going_off);
+ if (per_next_state == PWRDM_POWER_OFF)
+ omap3_per_save_context();
+ }
+
+ /* CORE */
+ if (core_next_state < PWRDM_POWER_ON) {
+ omap_uart_prepare_idle(0);
+ omap_uart_prepare_idle(1);
+ if (core_next_state == PWRDM_POWER_OFF) {
+ omap3_core_save_context();
+ omap3_cm_save_context();
+ }
+ }
+
+ omap3_intc_prepare_idle();
+
+ /*
+ * On EMU/HS devices ROM code restores a SRDC value
+ * from scratchpad which has automatic self refresh on timeout
+ * of AUTO_CNT = 1 enabled. This takes care of erratum ID i443.
+ * Hence store/restore the SDRC_POWER register here.
+ */
+ if (omap_rev() >= OMAP3430_REV_ES3_0 &&
+ omap_type() != OMAP2_DEVICE_TYPE_GP &&
+ core_next_state == PWRDM_POWER_OFF)
+ sdrc_pwr = sdrc_read_reg(SDRC_POWER);
+
+ /*
+ * omap3_arm_context is the location where ARM registers
+ * get saved. The restore path then reads from this
+ * location and restores them back.
+ */
+ _omap_sram_idle(omap3_arm_context, save_state);
+ cpu_init();
+
+ /* Restore normal SDRC POWER settings */
+ if (omap_rev() >= OMAP3430_REV_ES3_0 &&
+ omap_type() != OMAP2_DEVICE_TYPE_GP &&
+ core_next_state == PWRDM_POWER_OFF)
+ sdrc_write_reg(sdrc_pwr, SDRC_POWER);
+
+ /* Restore table entry modified during MMU restoration */
+ if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF)
+ restore_table_entry();
+
+ /* CORE */
+ if (core_next_state < PWRDM_POWER_ON) {
+ core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm);
+ if (core_prev_state == PWRDM_POWER_OFF) {
+ omap3_core_restore_context();
+ omap3_cm_restore_context();
+ omap3_sram_restore_context();
+ omap2_sms_restore_context();
+ }
+ omap_uart_resume_idle(0);
+ omap_uart_resume_idle(1);
+ if (core_next_state == PWRDM_POWER_OFF)
+ omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_VOLTCTRL_OFFSET);
+ }
+ omap3_intc_resume_idle();
+
+ /* PER */
+ if (per_next_state < PWRDM_POWER_ON) {
+ per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm);
+ omap2_gpio_resume_after_idle();
+ if (per_prev_state == PWRDM_POWER_OFF)
+ omap3_per_restore_context();
+ omap_uart_resume_idle(2);
+ omap_uart_resume_idle(3);
+ }
+
+ if (!is_suspending())
+ console_unlock();
+
+console_still_active:
+ /* Disable IO-PAD and IO-CHAIN wakeup */
+ if (omap3_has_io_wakeup() &&
+ (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)) {
+ omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
+ PM_WKEN);
+ omap3_disable_io_chain();
+ }
+
+ pwrdm_post_transition();
+
+ clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]);
+}
+
+int omap3_can_sleep(void)
+{
+ if (!sleep_while_idle)
+ return 0;
+ if (!omap_uart_can_sleep())
+ return 0;
+ return 1;
+}
+
+static void omap3_pm_idle(void)
+{
+ local_irq_disable();
+ local_fiq_disable();
+
+ if (!omap3_can_sleep())
+ goto out;
+
+ if (omap_irq_pending() || need_resched())
+ goto out;
+
+ trace_power_start(POWER_CSTATE, 1, smp_processor_id());
+ trace_cpu_idle(1, smp_processor_id());
+
+ omap_sram_idle();
+
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
+
+out:
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+#ifdef CONFIG_SUSPEND
+static int omap3_pm_suspend(void)
+{
+ struct power_state *pwrst;
+ int state, ret = 0;
+
+ if (wakeup_timer_seconds || wakeup_timer_milliseconds)
+ omap2_pm_wakeup_on_timer(wakeup_timer_seconds,
+ wakeup_timer_milliseconds);
+
+ /* Read current next_pwrsts */
+ list_for_each_entry(pwrst, &pwrst_list, node)
+ pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+ /* Set ones wanted by suspend */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
+ goto restore;
+ if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
+ goto restore;
+ }
+
+ omap_uart_prepare_suspend();
+ omap3_intc_suspend();
+
+ omap_sram_idle();
+
+restore:
+ /* Restore next_pwrsts */
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
+ if (state > pwrst->next_state) {
+ printk(KERN_INFO "Powerdomain (%s) didn't enter "
+ "target state %d\n",
+ pwrst->pwrdm->name, pwrst->next_state);
+ ret = -1;
+ }
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+ }
+ if (ret)
+ printk(KERN_ERR "Could not enter target state in pm_suspend\n");
+ else
+ printk(KERN_INFO "Successfully put all powerdomains "
+ "to target state\n");
+
+ return ret;
+}
+
+static int omap3_pm_enter(suspend_state_t unused)
+{
+ int ret = 0;
+
+ switch (suspend_state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ ret = omap3_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Hooks to enable / disable UART interrupts during suspend */
+static int omap3_pm_begin(suspend_state_t state)
+{
+ disable_hlt();
+ suspend_state = state;
+ omap_uart_enable_irqs(0);
+ return 0;
+}
+
+static void omap3_pm_end(void)
+{
+ suspend_state = PM_SUSPEND_ON;
+ omap_uart_enable_irqs(1);
+ enable_hlt();
+ return;
+}
+
+static const struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap3_pm_begin,
+ .end = omap3_pm_end,
+ .enter = omap3_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+#endif /* CONFIG_SUSPEND */
+
+
+/**
+ * omap3_iva_idle(): ensure IVA is in idle so it can be put into
+ * retention
+ *
+ * In cases where IVA2 is activated by bootcode, it may prevent
+ * full-chip retention or off-mode because it is not idle. This
+ * function forces the IVA2 into idle state so it can go
+ * into retention/off and thus allow full-chip retention/off.
+ *
+ **/
+static void __init omap3_iva_idle(void)
+{
+ /* ensure IVA2 clock is disabled */
+ omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
+
+ /* if no clock activity, nothing else to do */
+ if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
+ OMAP3430_CLKACTIVITY_IVA2_MASK))
+ return;
+
+ /* Reset IVA2 */
+ omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
+ OMAP3430_RST2_IVA2_MASK |
+ OMAP3430_RST3_IVA2_MASK,
+ OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
+ /* Enable IVA2 clock */
+ omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
+ OMAP3430_IVA2_MOD, CM_FCLKEN);
+
+ /* Set IVA2 boot mode to 'idle' */
+ omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
+ OMAP343X_CONTROL_IVA2_BOOTMOD);
+
+ /* Un-reset IVA2 */
+ omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+
+ /* Disable IVA2 clock */
+ omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
+
+ /* Reset IVA2 */
+ omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
+ OMAP3430_RST2_IVA2_MASK |
+ OMAP3430_RST3_IVA2_MASK,
+ OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
+}
+
+static void __init omap3_d2d_idle(void)
+{
+ u16 mask, padconf;
+
+ /* In a stand alone OMAP3430 where there is not a stacked
+ * modem for the D2D Idle Ack and D2D MStandby must be pulled
+ * high. S CONTROL_PADCONF_SAD2D_IDLEACK and
+ * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */
+ mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
+ padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
+ padconf |= mask;
+ omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);
+
+ padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
+ padconf |= mask;
+ omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
+
+ /* reset modem */
+ omap2_prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
+ OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK,
+ CORE_MOD, OMAP2_RM_RSTCTRL);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
+}
+
+static void __init prcm_setup_regs(void)
+{
+ u32 omap3630_en_uart4_mask = cpu_is_omap3630() ?
+ OMAP3630_EN_UART4_MASK : 0;
+ u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ?
+ OMAP3630_GRPSEL_UART4_MASK : 0;
+
+ /* XXX This should be handled by hwmod code or SCM init code */
+ omap_ctrl_writel(OMAP3430_AUTOIDLE_MASK, OMAP2_CONTROL_SYSCONFIG);
+
+ /*
+ * Enable control of expternal oscillator through
+ * sys_clkreq. In the long run clock framework should
+ * take care of this.
+ */
+ omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
+ 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
+ OMAP3430_GR_MOD,
+ OMAP3_PRM_CLKSRC_CTRL_OFFSET);
+
+ /* setup wakup source */
+ omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK |
+ OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK,
+ WKUP_MOD, PM_WKEN);
+ /* No need to write EN_IO, that is always enabled */
+ omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK |
+ OMAP3430_GRPSEL_GPT1_MASK |
+ OMAP3430_GRPSEL_GPT12_MASK,
+ WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
+ /* For some reason IO doesn't generate wakeup event even if
+ * it is selected to mpu wakeup goup */
+ omap2_prm_write_mod_reg(OMAP3430_IO_EN_MASK | OMAP3430_WKUP_EN_MASK,
+ OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
+
+ /* Enable PM_WKEN to support DSS LPR */
+ omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
+ OMAP3430_DSS_MOD, PM_WKEN);
+
+ /* Enable wakeups in PER */
+ omap2_prm_write_mod_reg(omap3630_en_uart4_mask |
+ OMAP3430_EN_GPIO2_MASK | OMAP3430_EN_GPIO3_MASK |
+ OMAP3430_EN_GPIO4_MASK | OMAP3430_EN_GPIO5_MASK |
+ OMAP3430_EN_GPIO6_MASK | OMAP3430_EN_UART3_MASK |
+ OMAP3430_EN_MCBSP2_MASK | OMAP3430_EN_MCBSP3_MASK |
+ OMAP3430_EN_MCBSP4_MASK,
+ OMAP3430_PER_MOD, PM_WKEN);
+ /* and allow them to wake up MPU */
+ omap2_prm_write_mod_reg(omap3630_grpsel_uart4_mask |
+ OMAP3430_GRPSEL_GPIO2_MASK |
+ OMAP3430_GRPSEL_GPIO3_MASK |
+ OMAP3430_GRPSEL_GPIO4_MASK |
+ OMAP3430_GRPSEL_GPIO5_MASK |
+ OMAP3430_GRPSEL_GPIO6_MASK |
+ OMAP3430_GRPSEL_UART3_MASK |
+ OMAP3430_GRPSEL_MCBSP2_MASK |
+ OMAP3430_GRPSEL_MCBSP3_MASK |
+ OMAP3430_GRPSEL_MCBSP4_MASK,
+ OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
+
+ /* Don't attach IVA interrupts */
+ omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
+ omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+ omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+
+ /* Clear any pending 'reset' flags */
+ omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
+ omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, OMAP2_RM_RSTST);
+
+ /* Clear any pending PRCM interrupts */
+ omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
+ omap3_iva_idle();
+ omap3_d2d_idle();
+}
+
+void omap3_pm_off_mode_enable(int enable)
+{
+ struct power_state *pwrst;
+ u32 state;
+
+ if (enable)
+ state = PWRDM_POWER_OFF;
+ else
+ state = PWRDM_POWER_RET;
+
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
+ pwrst->pwrdm == core_pwrdm &&
+ state == PWRDM_POWER_OFF) {
+ pwrst->next_state = PWRDM_POWER_RET;
+ pr_warn("%s: Core OFF disabled due to errata i583\n",
+ __func__);
+ } else {
+ pwrst->next_state = state;
+ }
+ omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+ }
+}
+
+int omap3_pm_get_suspend_state(struct powerdomain *pwrdm)
+{
+ struct power_state *pwrst;
+
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ if (pwrst->pwrdm == pwrdm)
+ return pwrst->next_state;
+ }
+ return -EINVAL;
+}
+
+int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state)
+{
+ struct power_state *pwrst;
+
+ list_for_each_entry(pwrst, &pwrst_list, node) {
+ if (pwrst->pwrdm == pwrdm) {
+ pwrst->next_state = state;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
+{
+ struct power_state *pwrst;
+
+ if (!pwrdm->pwrsts)
+ return 0;
+
+ pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
+ if (!pwrst)
+ return -ENOMEM;
+ pwrst->pwrdm = pwrdm;
+ pwrst->next_state = PWRDM_POWER_RET;
+ list_add(&pwrst->node, &pwrst_list);
+
+ if (pwrdm_has_hdwr_sar(pwrdm))
+ pwrdm_enable_hdwr_sar(pwrdm);
+
+ return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+}
+
+/*
+ * Enable hw supervised mode for all clockdomains if it's
+ * supported. Initiate sleep transition for other clockdomains, if
+ * they are not used
+ */
+static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
+{
+ if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
+ clkdm_allow_idle(clkdm);
+ else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
+ atomic_read(&clkdm->usecount) == 0)
+ clkdm_sleep(clkdm);
+ return 0;
+}
+
+void omap_push_sram_idle(void)
+{
+ _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
+ omap34xx_cpu_suspend_sz);
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+ _omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
+ save_secure_ram_context_sz);
+}
+
+static void __init pm_errata_configure(void)
+{
+ if (cpu_is_omap3630()) {
+ pm34xx_errata |= PM_RTA_ERRATUM_i608;
+ /* Enable the l2 cache toggling in sleep logic */
+ enable_omap3630_toggle_l2_on_restore();
+ if (omap_rev() < OMAP3630_REV_ES1_2)
+ pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583;
+ }
+}
+
+static int __init omap3_pm_init(void)
+{
+ struct power_state *pwrst, *tmp;
+ struct clockdomain *neon_clkdm, *per_clkdm, *mpu_clkdm, *core_clkdm;
+ int ret;
+
+ if (!cpu_is_omap34xx())
+ return -ENODEV;
+
+ pm_errata_configure();
+
+ /* XXX prcm_setup_regs needs to be before enabling hw
+ * supervised mode for powerdomains */
+ prcm_setup_regs();
+
+ ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
+ (irq_handler_t)prcm_interrupt_handler,
+ IRQF_DISABLED, "prcm", NULL);
+ if (ret) {
+ printk(KERN_ERR "request_irq failed to register for 0x%x\n",
+ INT_34XX_PRCM_MPU_IRQ);
+ goto err1;
+ }
+
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ printk(KERN_ERR "Failed to setup powerdomains\n");
+ goto err2;
+ }
+
+ (void) clkdm_for_each(clkdms_setup, NULL);
+
+ mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
+ if (mpu_pwrdm == NULL) {
+ printk(KERN_ERR "Failed to get mpu_pwrdm\n");
+ goto err2;
+ }
+
+ neon_pwrdm = pwrdm_lookup("neon_pwrdm");
+ per_pwrdm = pwrdm_lookup("per_pwrdm");
+ core_pwrdm = pwrdm_lookup("core_pwrdm");
+ cam_pwrdm = pwrdm_lookup("cam_pwrdm");
+
+ neon_clkdm = clkdm_lookup("neon_clkdm");
+ mpu_clkdm = clkdm_lookup("mpu_clkdm");
+ per_clkdm = clkdm_lookup("per_clkdm");
+ core_clkdm = clkdm_lookup("core_clkdm");
+
+ omap_push_sram_idle();
+#ifdef CONFIG_SUSPEND
+ suspend_set_ops(&omap_pm_ops);
+#endif /* CONFIG_SUSPEND */
+
+ pm_idle = omap3_pm_idle;
+ omap3_idle_init();
+
+ /*
+ * RTA is disabled during initialization as per erratum i608
+ * it is safer to disable RTA by the bootloader, but we would like
+ * to be doubly sure here and prevent any mishaps.
+ */
+ if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608))
+ omap3630_ctrl_disable_rta();
+
+ clkdm_add_wkdep(neon_clkdm, mpu_clkdm);
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ omap3_secure_ram_storage =
+ kmalloc(0x803F, GFP_KERNEL);
+ if (!omap3_secure_ram_storage)
+ printk(KERN_ERR "Memory allocation failed when"
+ "allocating for secure sram context\n");
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ omap_dma_global_context_save();
+ omap3_save_secure_ram_context();
+ omap_dma_global_context_restore();
+
+ local_irq_enable();
+ local_fiq_enable();
+ }
+
+ omap3_save_scratchpad_contents();
+err1:
+ return ret;
+err2:
+ free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
+ list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
+ list_del(&pwrst->node);
+ kfree(pwrst);
+ }
+ return ret;
+}
+
+late_initcall(omap3_pm_init);
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
new file mode 100644
index 00000000..59a870be
--- /dev/null
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -0,0 +1,121 @@
+/*
+ * OMAP4 Power Management Routines
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include "powerdomain.h"
+#include <mach/omap4-common.h>
+
+struct power_state {
+ struct powerdomain *pwrdm;
+ u32 next_state;
+#ifdef CONFIG_SUSPEND
+ u32 saved_state;
+#endif
+ struct list_head node;
+};
+
+static LIST_HEAD(pwrst_list);
+
+#ifdef CONFIG_SUSPEND
+static int omap4_pm_suspend(void)
+{
+ do_wfi();
+ return 0;
+}
+
+static int omap4_pm_enter(suspend_state_t suspend_state)
+{
+ int ret = 0;
+
+ switch (suspend_state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ ret = omap4_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int omap4_pm_begin(suspend_state_t state)
+{
+ disable_hlt();
+ return 0;
+}
+
+static void omap4_pm_end(void)
+{
+ enable_hlt();
+ return;
+}
+
+static const struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap4_pm_begin,
+ .end = omap4_pm_end,
+ .enter = omap4_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+#endif /* CONFIG_SUSPEND */
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
+{
+ struct power_state *pwrst;
+
+ if (!pwrdm->pwrsts)
+ return 0;
+
+ pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
+ if (!pwrst)
+ return -ENOMEM;
+ pwrst->pwrdm = pwrdm;
+ pwrst->next_state = PWRDM_POWER_ON;
+ list_add(&pwrst->node, &pwrst_list);
+
+ return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state);
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4 PM
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ */
+static int __init omap4_pm_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ pr_err("Power Management for TI OMAP4.\n");
+
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ pr_err("Failed to setup powerdomains\n");
+ goto err2;
+ }
+
+#ifdef CONFIG_SUSPEND
+ suspend_set_ops(&omap_pm_ops);
+#endif /* CONFIG_SUSPEND */
+
+err2:
+ return ret;
+}
+late_initcall(omap4_pm_init);
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
new file mode 100644
index 00000000..171fccd2
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -0,0 +1,110 @@
+/*
+ * linux/arch/arm/mach-omap2/powerdomain-common.c
+ * Contains common powerdomain framework functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include "pm.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "cm-regbits-44xx.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+
+/*
+ * OMAP3 and OMAP4 specific register bit initialisations
+ * Notice that the names here are not according to each power
+ * domain but the bit mapping used applies to all of them
+ */
+/* OMAP3 and OMAP4 Memory Onstate Masks (common across all power domains) */
+#define OMAP_MEM0_ONSTATE_MASK OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK
+#define OMAP_MEM1_ONSTATE_MASK OMAP3430_L1FLATMEMONSTATE_MASK
+#define OMAP_MEM2_ONSTATE_MASK OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK
+#define OMAP_MEM3_ONSTATE_MASK OMAP3430_L2FLATMEMONSTATE_MASK
+#define OMAP_MEM4_ONSTATE_MASK OMAP4430_OCP_NRET_BANK_ONSTATE_MASK
+
+/* OMAP3 and OMAP4 Memory Retstate Masks (common across all power domains) */
+#define OMAP_MEM0_RETSTATE_MASK OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK
+#define OMAP_MEM1_RETSTATE_MASK OMAP3430_L1FLATMEMRETSTATE_MASK
+#define OMAP_MEM2_RETSTATE_MASK OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK
+#define OMAP_MEM3_RETSTATE_MASK OMAP3430_L2FLATMEMRETSTATE_MASK
+#define OMAP_MEM4_RETSTATE_MASK OMAP4430_OCP_NRET_BANK_RETSTATE_MASK
+
+/* OMAP3 and OMAP4 Memory Status bits */
+#define OMAP_MEM0_STATEST_MASK OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK
+#define OMAP_MEM1_STATEST_MASK OMAP3430_L1FLATMEMSTATEST_MASK
+#define OMAP_MEM2_STATEST_MASK OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK
+#define OMAP_MEM3_STATEST_MASK OMAP3430_L2FLATMEMSTATEST_MASK
+#define OMAP_MEM4_STATEST_MASK OMAP4430_OCP_NRET_BANK_STATEST_MASK
+
+/* Common Internal functions used across OMAP rev's*/
+u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_ONSTATE_MASK;
+ case 1:
+ return OMAP_MEM1_ONSTATE_MASK;
+ case 2:
+ return OMAP_MEM2_ONSTATE_MASK;
+ case 3:
+ return OMAP_MEM3_ONSTATE_MASK;
+ case 4:
+ return OMAP_MEM4_ONSTATE_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_RETSTATE_MASK;
+ case 1:
+ return OMAP_MEM1_RETSTATE_MASK;
+ case 2:
+ return OMAP_MEM2_RETSTATE_MASK;
+ case 3:
+ return OMAP_MEM3_RETSTATE_MASK;
+ case 4:
+ return OMAP_MEM4_RETSTATE_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP_MEM0_STATEST_MASK;
+ case 1:
+ return OMAP_MEM1_STATEST_MASK;
+ case 2:
+ return OMAP_MEM2_STATEST_MASK;
+ case 3:
+ return OMAP_MEM3_STATEST_MASK;
+ case 4:
+ return OMAP_MEM4_STATEST_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
new file mode 100644
index 00000000..9af08473
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -0,0 +1,1001 @@
+/*
+ * OMAP powerdomain control
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Added OMAP4 specific support by Abhijit Pagare <abhijitpagare@ti.com>
+ * State counting code by Tero Kristo <tero.kristo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <trace/events/power.h>
+
+#include "cm2xxx_3xxx.h"
+#include "prcm44xx.h"
+#include "cm44xx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+
+#include <asm/cpu.h>
+#include <plat/cpu.h>
+#include "powerdomain.h"
+#include "clockdomain.h"
+#include <plat/prcm.h>
+
+#include "pm.h"
+
+#define PWRDM_TRACE_STATES_FLAG (1<<31)
+
+enum {
+ PWRDM_STATE_NOW = 0,
+ PWRDM_STATE_PREV,
+};
+
+
+/* pwrdm_list contains all registered struct powerdomains */
+static LIST_HEAD(pwrdm_list);
+
+static struct pwrdm_ops *arch_pwrdm;
+
+/* Private functions */
+
+static struct powerdomain *_pwrdm_lookup(const char *name)
+{
+ struct powerdomain *pwrdm, *temp_pwrdm;
+
+ pwrdm = NULL;
+
+ list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+ if (!strcmp(name, temp_pwrdm->name)) {
+ pwrdm = temp_pwrdm;
+ break;
+ }
+ }
+
+ return pwrdm;
+}
+
+/**
+ * _pwrdm_register - register a powerdomain
+ * @pwrdm: struct powerdomain * to register
+ *
+ * Adds a powerdomain to the internal powerdomain list. Returns
+ * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+static int _pwrdm_register(struct powerdomain *pwrdm)
+{
+ int i;
+
+ if (!pwrdm || !pwrdm->name)
+ return -EINVAL;
+
+ if (!omap_chip_is(pwrdm->omap_chip))
+ return -EINVAL;
+
+ if (cpu_is_omap44xx() &&
+ pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
+ pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
+ pwrdm->name);
+ return -EINVAL;
+ }
+
+ if (_pwrdm_lookup(pwrdm->name))
+ return -EEXIST;
+
+ list_add(&pwrdm->node, &pwrdm_list);
+
+ /* Initialize the powerdomain's state counter */
+ for (i = 0; i < PWRDM_MAX_PWRSTS; i++)
+ pwrdm->state_counter[i] = 0;
+
+ pwrdm->ret_logic_off_counter = 0;
+ for (i = 0; i < pwrdm->banks; i++)
+ pwrdm->ret_mem_off_counter[i] = 0;
+
+ pwrdm_wait_transition(pwrdm);
+ pwrdm->state = pwrdm_read_pwrst(pwrdm);
+ pwrdm->state_counter[pwrdm->state] = 1;
+
+ pr_debug("powerdomain: registered %s\n", pwrdm->name);
+
+ return 0;
+}
+
+static void _update_logic_membank_counters(struct powerdomain *pwrdm)
+{
+ int i;
+ u8 prev_logic_pwrst, prev_mem_pwrst;
+
+ prev_logic_pwrst = pwrdm_read_prev_logic_pwrst(pwrdm);
+ if ((pwrdm->pwrsts_logic_ret == PWRSTS_OFF_RET) &&
+ (prev_logic_pwrst == PWRDM_POWER_OFF))
+ pwrdm->ret_logic_off_counter++;
+
+ for (i = 0; i < pwrdm->banks; i++) {
+ prev_mem_pwrst = pwrdm_read_prev_mem_pwrst(pwrdm, i);
+
+ if ((pwrdm->pwrsts_mem_ret[i] == PWRSTS_OFF_RET) &&
+ (prev_mem_pwrst == PWRDM_POWER_OFF))
+ pwrdm->ret_mem_off_counter[i]++;
+ }
+}
+
+static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)
+{
+
+ int prev, state, trace_state = 0;
+
+ if (pwrdm == NULL)
+ return -EINVAL;
+
+ state = pwrdm_read_pwrst(pwrdm);
+
+ switch (flag) {
+ case PWRDM_STATE_NOW:
+ prev = pwrdm->state;
+ break;
+ case PWRDM_STATE_PREV:
+ prev = pwrdm_read_prev_pwrst(pwrdm);
+ if (pwrdm->state != prev)
+ pwrdm->state_counter[prev]++;
+ if (prev == PWRDM_POWER_RET)
+ _update_logic_membank_counters(pwrdm);
+ /*
+ * If the power domain did not hit the desired state,
+ * generate a trace event with both the desired and hit states
+ */
+ if (state != prev) {
+ trace_state = (PWRDM_TRACE_STATES_FLAG |
+ ((state & OMAP_POWERSTATE_MASK) << 8) |
+ ((prev & OMAP_POWERSTATE_MASK) << 0));
+ trace_power_domain_target(pwrdm->name, trace_state,
+ smp_processor_id());
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state != prev)
+ pwrdm->state_counter[state]++;
+
+ pm_dbg_update_time(pwrdm, prev);
+
+ pwrdm->state = state;
+
+ return 0;
+}
+
+static int _pwrdm_pre_transition_cb(struct powerdomain *pwrdm, void *unused)
+{
+ pwrdm_clear_all_prev_pwrst(pwrdm);
+ _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+ return 0;
+}
+
+static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
+{
+ _pwrdm_state_switch(pwrdm, PWRDM_STATE_PREV);
+ return 0;
+}
+
+/* Public functions */
+
+/**
+ * pwrdm_init - set up the powerdomain layer
+ * @pwrdm_list: array of struct powerdomain pointers to register
+ * @custom_funcs: func pointers for arch specific implementations
+ *
+ * Loop through the array of powerdomains @pwrdm_list, registering all
+ * that are available on the current CPU. If pwrdm_list is supplied
+ * and not null, all of the referenced powerdomains will be
+ * registered. No return value. XXX pwrdm_list is not really a
+ * "list"; it is an array. Rename appropriately.
+ */
+void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs)
+{
+ struct powerdomain **p = NULL;
+
+ if (!custom_funcs)
+ WARN(1, "powerdomain: No custom pwrdm functions registered\n");
+ else
+ arch_pwrdm = custom_funcs;
+
+ if (pwrdm_list) {
+ for (p = pwrdm_list; *p; p++)
+ _pwrdm_register(*p);
+ }
+}
+
+/**
+ * pwrdm_lookup - look up a powerdomain by name, return a pointer
+ * @name: name of powerdomain
+ *
+ * Find a registered powerdomain by its name @name. Returns a pointer
+ * to the struct powerdomain if found, or NULL otherwise.
+ */
+struct powerdomain *pwrdm_lookup(const char *name)
+{
+ struct powerdomain *pwrdm;
+
+ if (!name)
+ return NULL;
+
+ pwrdm = _pwrdm_lookup(name);
+
+ return pwrdm;
+}
+
+/**
+ * pwrdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each registered powerdomain.
+ * The callback function @fn can return anything but 0 to bail out
+ * early from the iterator. Returns the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure; or -EINVAL if the function pointer is null.
+ */
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user)
+{
+ struct powerdomain *temp_pwrdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+ ret = (*fn)(temp_pwrdm, user);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * pwrdm_add_clkdm - add a clockdomain to a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Associate the clockdomain @clkdm with a powerdomain @pwrdm. This
+ * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
+ */
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ int i;
+ int ret = -EINVAL;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: associating clockdomain %s with powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
+ if (!pwrdm->pwrdm_clkdms[i])
+ break;
+#ifdef DEBUG
+ if (pwrdm->pwrdm_clkdms[i] == clkdm) {
+ ret = -EINVAL;
+ goto pac_exit;
+ }
+#endif
+ }
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
+ "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
+ WARN_ON(1);
+ ret = -ENOMEM;
+ goto pac_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = clkdm;
+
+ ret = 0;
+
+pac_exit:
+ return ret;
+}
+
+/**
+ * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Dissociate the clockdomain @clkdm from the powerdomain
+ * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
+ * if @clkdm was not associated with the powerdomain, or 0 upon
+ * success.
+ */
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ int ret = -EINVAL;
+ int i;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
+ if (pwrdm->pwrdm_clkdms[i] == clkdm)
+ break;
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: clkdm %s not associated with pwrdm "
+ "%s ?!\n", clkdm->name, pwrdm->name);
+ ret = -ENOENT;
+ goto pdc_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = NULL;
+
+ ret = 0;
+
+pdc_exit:
+ return ret;
+}
+
+/**
+ * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
+ * @pwrdm: struct powerdomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each clockdomain in the powerdomain
+ * @pwrdm. The callback function can return anything but 0 to bail
+ * out early from the iterator. Returns -EINVAL if presented with
+ * invalid pointers; or passes along the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure.
+ */
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm))
+{
+ int ret = 0;
+ int i;
+
+ if (!fn)
+ return -EINVAL;
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
+ ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
+
+ return ret;
+}
+
+/**
+ * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
+ * @pwrdm: struct powerdomain *
+ *
+ * Return the number of controllable memory banks in powerdomain @pwrdm,
+ * starting with 1. Returns -EINVAL if the powerdomain pointer is null.
+ */
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return pwrdm->banks;
+}
+
+/**
+ * pwrdm_set_next_pwrst - set next powerdomain power state
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the powerdomain @pwrdm's next power state to @pwrst. The powerdomain
+ * may not enter this state immediately if the preconditions for this state
+ * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
+ * null or if the power state is invalid for the powerdomin, or returns 0
+ * upon success.
+ */
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->pwrsts & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
+ pwrdm->name, pwrst);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
+ /* Trace the pwrdm desired target state */
+ trace_power_domain_target(pwrdm->name, pwrst,
+ smp_processor_id());
+ /* Program the pwrdm desired target state */
+ ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
+ }
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_next_pwrst - get next powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's next power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the next power state
+ * upon success.
+ */
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
+ ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_pwrst - get current powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain @pwrdm's current power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the current power state
+ * upon success.
+ */
+int pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
+ ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_prev_pwrst - get previous powerdomain power state
+ * @pwrdm: struct powerdomain * to get previous power state
+ *
+ * Return the powerdomain @pwrdm's previous power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the previous power state
+ * upon success.
+ */
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state @pwrst that the logic portion of the
+ * powerdomain @pwrdm will enter when the powerdomain enters retention.
+ * This will be either RETENTION or OFF, if supported. Returns
+ * -EINVAL if the powerdomain pointer is null or the target power
+ * state is not not supported, or returns 0 upon success.
+ */
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
+ pwrdm->name, pwrst);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_logic_retst)
+ ret = arch_pwrdm->pwrdm_set_logic_retst(pwrdm, pwrst);
+
+ return ret;
+}
+
+/**
+ * pwrdm_set_mem_onst - set memory power state while powerdomain ON
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state @pwrst that memory bank @bank of the
+ * powerdomain @pwrdm will enter when the powerdomain enters the ON
+ * state. @bank will be a number from 0 to 3, and represents different
+ * types of memory, depending on the powerdomain. Returns -EINVAL if
+ * the powerdomain pointer is null or the target power state is not
+ * not supported for this memory bank, -EEXIST if the target memory
+ * bank does not exist or is not controllable, or returns 0 upon
+ * success.
+ */
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next memory powerstate for domain %s "
+ "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_onst)
+ ret = arch_pwrdm->pwrdm_set_mem_onst(pwrdm, bank, pwrst);
+
+ return ret;
+}
+
+/**
+ * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state @pwrst that memory bank @bank of the
+ * powerdomain @pwrdm will enter when the powerdomain enters the
+ * RETENTION state. Bank will be a number from 0 to 3, and represents
+ * different types of memory, depending on the powerdomain. @pwrst
+ * will be either RETENTION or OFF, if supported. Returns -EINVAL if
+ * the powerdomain pointer is null or the target power state is not
+ * not supported for this memory bank, -EEXIST if the target memory
+ * bank does not exist or is not controllable, or returns 0 upon
+ * success.
+ */
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next memory powerstate for domain %s "
+ "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_mem_retst)
+ ret = arch_pwrdm->pwrdm_set_mem_retst(pwrdm, bank, pwrst);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
+ * @pwrdm: struct powerdomain * to get current logic retention power state
+ *
+ * Return the power state that the logic portion of powerdomain @pwrdm
+ * will enter when the powerdomain enters retention. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the logic retention
+ * power state upon success.
+ */
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_pwrst)
+ ret = arch_pwrdm->pwrdm_read_logic_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
+ * @pwrdm: struct powerdomain * to get previous logic power state
+ *
+ * Return the powerdomain @pwrdm's previous logic power state. Returns
+ * -EINVAL if the powerdomain pointer is null or returns the previous
+ * logic power state upon success.
+ */
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_logic_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_logic_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_logic_retst - get next powerdomain logic power state
+ * @pwrdm: struct powerdomain * to get next logic power state
+ *
+ * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the next logic
+ * power state upon success.
+ */
+int pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_logic_retst)
+ ret = arch_pwrdm->pwrdm_read_logic_retst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_mem_pwrst - get current memory bank power state
+ * @pwrdm: struct powerdomain * to get current memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain @pwrdm's current memory power state for bank
+ * @bank. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the current memory power state upon success.
+ */
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ if (pwrdm->banks < (bank + 1))
+ return ret;
+
+ if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
+ bank = 1;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_pwrst)
+ ret = arch_pwrdm->pwrdm_read_mem_pwrst(pwrdm, bank);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
+ * @pwrdm: struct powerdomain * to get previous memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain @pwrdm's previous memory power state for
+ * bank @bank. Returns -EINVAL if the powerdomain pointer is null,
+ * -EEXIST if the target memory bank does not exist or is not
+ * controllable, or returns the previous memory power state upon
+ * success.
+ */
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ if (pwrdm->banks < (bank + 1))
+ return ret;
+
+ if (pwrdm->flags & PWRDM_HAS_MPU_QUIRK)
+ bank = 1;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_prev_mem_pwrst)
+ ret = arch_pwrdm->pwrdm_read_prev_mem_pwrst(pwrdm, bank);
+
+ return ret;
+}
+
+/**
+ * pwrdm_read_mem_retst - get next memory bank power state
+ * @pwrdm: struct powerdomain * to get mext memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's next memory power state for bank
+ * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the next memory power state upon success.
+ */
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ if (pwrdm->banks < (bank + 1))
+ return ret;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_read_mem_retst)
+ ret = arch_pwrdm->pwrdm_read_mem_retst(pwrdm, bank);
+
+ return ret;
+}
+
+/**
+ * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
+ * @pwrdm: struct powerdomain * to clear
+ *
+ * Clear the powerdomain's previous power state register @pwrdm.
+ * Clears the entire register, including logic and memory bank
+ * previous power states. Returns -EINVAL if the powerdomain pointer
+ * is null, or returns 0 upon success.
+ */
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ /*
+ * XXX should get the powerdomain's current state here;
+ * warn & fail if it is not ON.
+ */
+
+ pr_debug("powerdomain: clearing previous power state reg for %s\n",
+ pwrdm->name);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_clear_all_prev_pwrst)
+ ret = arch_pwrdm->pwrdm_clear_all_prev_pwrst(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Enable automatic context save-and-restore upon power state change
+ * for some devices in the powerdomain @pwrdm. Warning: this only
+ * affects a subset of devices in a powerdomain; check the TRM
+ * closely. Returns -EINVAL if the powerdomain pointer is null or if
+ * the powerdomain does not support automatic save-and-restore, or
+ * returns 0 upon success.
+ */
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+ return ret;
+
+ pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
+ pwrdm->name);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_enable_hdwr_sar)
+ ret = arch_pwrdm->pwrdm_enable_hdwr_sar(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Disable automatic context save-and-restore upon power state change
+ * for some devices in the powerdomain @pwrdm. Warning: this only
+ * affects a subset of devices in a powerdomain; check the TRM
+ * closely. Returns -EINVAL if the powerdomain pointer is null or if
+ * the powerdomain does not support automatic save-and-restore, or
+ * returns 0 upon success.
+ */
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return ret;
+
+ if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+ return ret;
+
+ pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
+ pwrdm->name);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_disable_hdwr_sar)
+ ret = arch_pwrdm->pwrdm_disable_hdwr_sar(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
+ * @pwrdm: struct powerdomain *
+ *
+ * Returns 1 if powerdomain @pwrdm supports hardware save-and-restore
+ * for some devices, or 0 if it does not.
+ */
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
+}
+
+/**
+ * pwrdm_set_lowpwrstchange - Request a low power state change
+ * @pwrdm: struct powerdomain *
+ *
+ * Allows a powerdomain to transtion to a lower power sleep state
+ * from an existing sleep state without waking up the powerdomain.
+ * Returns -EINVAL if the powerdomain pointer is null or if the
+ * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0
+ * upon success.
+ */
+int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE))
+ return -EINVAL;
+
+ pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n",
+ pwrdm->name);
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange)
+ ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm);
+
+ return ret;
+}
+
+/**
+ * pwrdm_wait_transition - wait for powerdomain power transition to finish
+ * @pwrdm: struct powerdomain * to wait for
+ *
+ * If the powerdomain @pwrdm is in the process of a state transition,
+ * spin until it completes the power transition, or until an iteration
+ * bailout value is reached. Returns -EINVAL if the powerdomain
+ * pointer is null, -EAGAIN if the bailout value was reached, or
+ * returns 0 upon success.
+ */
+int pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
+ ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
+
+ return ret;
+}
+
+int pwrdm_state_switch(struct powerdomain *pwrdm)
+{
+ return _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
+}
+
+int pwrdm_clkdm_state_switch(struct clockdomain *clkdm)
+{
+ if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) {
+ pwrdm_wait_transition(clkdm->pwrdm.ptr);
+ return pwrdm_state_switch(clkdm->pwrdm.ptr);
+ }
+
+ return -EINVAL;
+}
+
+int pwrdm_pre_transition(void)
+{
+ pwrdm_for_each(_pwrdm_pre_transition_cb, NULL);
+ return 0;
+}
+
+int pwrdm_post_transition(void)
+{
+ pwrdm_for_each(_pwrdm_post_transition_cb, NULL);
+ return 0;
+}
+
+/**
+ * pwrdm_get_context_loss_count - get powerdomain's context loss count
+ * @pwrdm: struct powerdomain * to wait for
+ *
+ * Context loss count is the sum of powerdomain off-mode counter, the
+ * logic off counter and the per-bank memory off counter. Returns 0
+ * (and WARNs) upon error, otherwise, returns the context loss count.
+ */
+u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
+{
+ int i, count;
+
+ if (!pwrdm) {
+ WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
+ return 0;
+ }
+
+ count = pwrdm->state_counter[PWRDM_POWER_OFF];
+ count += pwrdm->ret_logic_off_counter;
+
+ for (i = 0; i < pwrdm->banks; i++)
+ count += pwrdm->ret_mem_off_counter[i];
+
+ pr_debug("powerdomain: %s: context loss count = %u\n",
+ pwrdm->name, count);
+
+ return count;
+}
+
+/**
+ * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
+ * @pwrdm: struct powerdomain *
+ *
+ * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
+ * can lose either memory or logic context or if @pwrdm is invalid, or
+ * returns 0 otherwise. This function is not concerned with how the
+ * powerdomain registers are programmed (i.e., to go off or not); it's
+ * concerned with whether it's ever possible for this powerdomain to
+ * go off while some other part of the chip is active. This function
+ * assumes that every powerdomain can go to either ON or INACTIVE.
+ */
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
+{
+ int i;
+
+ if (IS_ERR_OR_NULL(pwrdm)) {
+ pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
+ __func__);
+ return 1;
+ }
+
+ if (pwrdm->pwrsts & PWRSTS_OFF)
+ return 1;
+
+ if (pwrdm->pwrsts & PWRSTS_RET) {
+ if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
+ return 1;
+
+ for (i = 0; i < pwrdm->banks; i++)
+ if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
+ return 1;
+ }
+
+ for (i = 0; i < pwrdm->banks; i++)
+ if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
+ return 1;
+
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
new file mode 100644
index 00000000..d23d979b
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -0,0 +1,230 @@
+/*
+ * OMAP2/3/4 powerdomain control
+ *
+ * Copyright (C) 2007-2008, 2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This should be moved to the mach-omap2/ directory at the earliest
+ * opportunity.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
+#define __ARCH_ARM_MACH_OMAP2_POWERDOMAIN_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <linux/atomic.h>
+
+#include <plat/cpu.h>
+
+/* Powerdomain basic power states */
+#define PWRDM_POWER_OFF 0x0
+#define PWRDM_POWER_RET 0x1
+#define PWRDM_POWER_INACTIVE 0x2
+#define PWRDM_POWER_ON 0x3
+
+#define PWRDM_MAX_PWRSTS 4
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_ON (1 << PWRDM_POWER_ON)
+#define PWRSTS_INACTIVE (1 << PWRDM_POWER_INACTIVE)
+#define PWRSTS_RET (1 << PWRDM_POWER_RET)
+#define PWRSTS_OFF (1 << PWRDM_POWER_OFF)
+
+#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
+#define PWRSTS_OFF_RET (PWRSTS_OFF | PWRSTS_RET)
+#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
+#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | PWRSTS_ON)
+
+
+/* Powerdomain flags */
+#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
+#define PWRDM_HAS_MPU_QUIRK (1 << 1) /* MPU pwr domain has MEM bank 0 bits
+ * in MEM bank 1 position. This is
+ * true for OMAP3430
+ */
+#define PWRDM_HAS_LOWPOWERSTATECHANGE (1 << 2) /*
+ * support to transition from a
+ * sleep state to a lower sleep
+ * state without waking up the
+ * powerdomain
+ */
+
+/*
+ * Number of memory banks that are power-controllable. On OMAP4430, the
+ * maximum is 5.
+ */
+#define PWRDM_MAX_MEM_BANKS 5
+
+/*
+ * Maximum number of clockdomains that can be associated with a powerdomain.
+ * CORE powerdomain on OMAP4 is the worst case
+ */
+#define PWRDM_MAX_CLKDMS 9
+
+/* XXX A completely arbitrary number. What is reasonable here? */
+#define PWRDM_TRANSITION_BAILOUT 100000
+
+struct clockdomain;
+struct powerdomain;
+
+/**
+ * struct powerdomain - OMAP powerdomain
+ * @name: Powerdomain name
+ * @omap_chip: represents the OMAP chip types containing this pwrdm
+ * @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
+ * @pwrsts: Possible powerdomain power states
+ * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
+ * @flags: Powerdomain flags
+ * @banks: Number of software-controllable memory banks in this powerdomain
+ * @pwrsts_mem_ret: Possible memory bank pwrstates when pwrdm in RETENTION
+ * @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
+ * @pwrdm_clkdms: Clockdomains in this powerdomain
+ * @node: list_head linking all powerdomains
+ * @state:
+ * @state_counter:
+ * @timer:
+ * @state_timer:
+ *
+ * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.
+ */
+struct powerdomain {
+ const char *name;
+ const struct omap_chip_id omap_chip;
+ const s16 prcm_offs;
+ const u8 pwrsts;
+ const u8 pwrsts_logic_ret;
+ const u8 flags;
+ const u8 banks;
+ const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
+ const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+ const u8 prcm_partition;
+ struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
+ struct list_head node;
+ int state;
+ unsigned state_counter[PWRDM_MAX_PWRSTS];
+ unsigned ret_logic_off_counter;
+ unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS];
+
+#ifdef CONFIG_PM_DEBUG
+ s64 timer;
+ s64 state_timer[PWRDM_MAX_PWRSTS];
+#endif
+};
+
+/**
+ * struct pwrdm_ops - Arch specific function implementations
+ * @pwrdm_set_next_pwrst: Set the target power state for a pd
+ * @pwrdm_read_next_pwrst: Read the target power state set for a pd
+ * @pwrdm_read_pwrst: Read the current power state of a pd
+ * @pwrdm_read_prev_pwrst: Read the prev power state entered by the pd
+ * @pwrdm_set_logic_retst: Set the logic state in RET for a pd
+ * @pwrdm_set_mem_onst: Set the Memory state in ON for a pd
+ * @pwrdm_set_mem_retst: Set the Memory state in RET for a pd
+ * @pwrdm_read_logic_pwrst: Read the current logic state of a pd
+ * @pwrdm_read_prev_logic_pwrst: Read the previous logic state entered by a pd
+ * @pwrdm_read_logic_retst: Read the logic state in RET for a pd
+ * @pwrdm_read_mem_pwrst: Read the current memory state of a pd
+ * @pwrdm_read_prev_mem_pwrst: Read the previous memory state entered by a pd
+ * @pwrdm_read_mem_retst: Read the memory state in RET for a pd
+ * @pwrdm_clear_all_prev_pwrst: Clear all previous power states logged for a pd
+ * @pwrdm_enable_hdwr_sar: Enable Hardware Save-Restore feature for the pd
+ * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd
+ * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep
+ * @pwrdm_wait_transition: Wait for a pd state transition to complete
+ */
+struct pwrdm_ops {
+ int (*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst);
+ int (*pwrdm_read_next_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_prev_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_set_logic_retst)(struct powerdomain *pwrdm, u8 pwrst);
+ int (*pwrdm_set_mem_onst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+ int (*pwrdm_set_mem_retst)(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+ int (*pwrdm_read_logic_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_prev_logic_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_logic_retst)(struct powerdomain *pwrdm);
+ int (*pwrdm_read_mem_pwrst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_read_prev_mem_pwrst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_read_mem_retst)(struct powerdomain *pwrdm, u8 bank);
+ int (*pwrdm_clear_all_prev_pwrst)(struct powerdomain *pwrdm);
+ int (*pwrdm_enable_hdwr_sar)(struct powerdomain *pwrdm);
+ int (*pwrdm_disable_hdwr_sar)(struct powerdomain *pwrdm);
+ int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
+ int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
+};
+
+void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs);
+
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user);
+int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
+ void *user);
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm));
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_logic_retst(struct powerdomain *pwrdm);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+int pwrdm_state_switch(struct powerdomain *pwrdm);
+int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
+int pwrdm_pre_transition(void);
+int pwrdm_post_transition(void);
+int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
+u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
+bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
+
+extern void omap2xxx_powerdomains_init(void);
+extern void omap3xxx_powerdomains_init(void);
+extern void omap44xx_powerdomains_init(void);
+
+extern struct pwrdm_ops omap2_pwrdm_operations;
+extern struct pwrdm_ops omap3_pwrdm_operations;
+extern struct pwrdm_ops omap4_pwrdm_operations;
+
+/* Common Internal functions used across OMAP rev's */
+extern u32 omap2_pwrdm_get_mem_bank_onstate_mask(u8 bank);
+extern u32 omap2_pwrdm_get_mem_bank_retst_mask(u8 bank);
+extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);
+
+extern struct powerdomain wkup_omap2_pwrdm;
+extern struct powerdomain gfx_omap2_pwrdm;
+
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
new file mode 100644
index 00000000..cf600e22
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
@@ -0,0 +1,241 @@
+/*
+ * OMAP2 and OMAP3 powerdomain control
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include <plat/prcm.h>
+
+#include "powerdomain.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
+
+
+/* Common functions across OMAP2 and OMAP3 */
+static int omap2_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap2_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
+}
+
+static int omap2_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
+}
+
+static int omap2_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP2_PM_PWSTST,
+ m);
+}
+
+static int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL, m);
+}
+
+static int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE_MASK);
+ omap2_prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE_MASK, v,
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP2_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ printk(KERN_ERR "powerdomain: waited too long for "
+ "powerdomain %s to complete transition\n", pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+/* Applicable only for OMAP3. Not supported on OMAP2 */
+static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTPOWERSTATEENTERED_MASK);
+}
+
+static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTST,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL,
+ OMAP3430_LOGICSTATEST_MASK);
+}
+
+static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTLOGICSTATEENTERED_MASK);
+}
+
+static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
+{
+ switch (bank) {
+ case 0:
+ return OMAP3430_LASTMEM1STATEENTERED_MASK;
+ case 1:
+ return OMAP3430_LASTMEM2STATEENTERED_MASK;
+ case 2:
+ return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
+ case 3:
+ return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+ return 0;
+}
+
+static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ m = omap3_get_mem_bank_lastmemst_mask(bank);
+
+ return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST, m);
+}
+
+static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+ return 0;
+}
+
+static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(0,
+ 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
+}
+
+static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ 0, pwrdm->prcm_offs,
+ OMAP2_PM_PWSTCTRL);
+}
+
+struct pwrdm_ops omap2_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
+
+struct pwrdm_ops omap3_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap2_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap2_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap2_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
+ .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
+ .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
+ .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
+ .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
+ .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
+ .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
+ .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
+ .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
+};
diff --git a/arch/arm/mach-omap2/powerdomain44xx.c b/arch/arm/mach-omap2/powerdomain44xx.c
new file mode 100644
index 00000000..a7880af4
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain44xx.c
@@ -0,0 +1,225 @@
+/*
+ * OMAP4 powerdomain control
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+
+#include "powerdomain.h"
+#include <plat/prcm.h>
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-44xx.h"
+
+static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP_POWERSTATE_MASK;
+ v >>= OMAP_POWERSTATE_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP_POWERSTATEST_MASK;
+ v >>= OMAP_POWERSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
+ v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
+ (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
+ return 0;
+}
+
+static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ OMAP4430_LASTPOWERSTATEENTERED_MASK,
+ pwrdm->prcm_partition,
+ pwrdm->prcm_offs, OMAP4_PM_PWSTST);
+ return 0;
+}
+
+static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ u32 v;
+
+ v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
+ omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
+ u8 pwrst)
+{
+ u32 m;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+
+ return 0;
+}
+
+static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= OMAP4430_LOGICSTATEST_MASK;
+ v >>= OMAP4430_LOGICSTATEST_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= OMAP4430_LOGICRETSTATE_MASK;
+ v >>= OMAP4430_LOGICRETSTATE_SHIFT;
+
+ return v;
+}
+
+static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m, v;
+
+ m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
+
+ v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
+ OMAP4_PM_PWSTCTRL);
+ v &= m;
+ v >>= __ffs(m);
+
+ return v;
+}
+
+static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
+ pwrdm->prcm_offs,
+ OMAP4_PM_PWSTST) &
+ OMAP_INTRANSITION_MASK) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c > PWRDM_TRANSITION_BAILOUT) {
+ printk(KERN_ERR "powerdomain: waited too long for "
+ "powerdomain %s to complete transition\n", pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+struct pwrdm_ops omap4_pwrdm_operations = {
+ .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
+ .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
+ .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
+ .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
+ .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
+ .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
+ .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
+ .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
+ .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
+ .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
+ .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
+ .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
+ .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
+ .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
+};
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
new file mode 100644
index 00000000..4210c339
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -0,0 +1,80 @@
+/*
+ * OMAP2/3 common powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * To Do List
+ * -> Move the Sleep/Wakeup dependencies from Power Domain framework to
+ * Clock Domain Framework
+ */
+
+/*
+ * This file contains all of the powerdomains that have some element
+ * of software control for the OMAP24xx and OMAP34xx chips.
+ *
+ * This is not an exhaustive listing of powerdomains on the chips; only
+ * powerdomains that can be controlled in software.
+ */
+
+/*
+ * The names for the DSP/IVA2 powerdomains are confusing.
+ *
+ * Most OMAP chips have an on-board DSP.
+ *
+ * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its
+ * powerdomain is called the "DSP power domain." On the 2430, the
+ * on-board DSP is a 'C64 DSP, now called (along with its hardware
+ * accelerators) the IVA2 or IVA2.1. Its powerdomain is still called
+ * the "DSP power domain." On the 3430, the DSP is a 'C64 DSP like the
+ * 2430, also known as the IVA2; but its powerdomain is now called the
+ * "IVA2 power domain."
+ *
+ * The 2420 also has something called the IVA, which is a separate ARM
+ * core, and has nothing to do with the DSP/IVA2.
+ *
+ * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
+ * address offset is different between the C55 and C64 DSPs.
+ */
+
+#include "powerdomain.h"
+
+#include "prcm-common.h"
+#include "prm.h"
+
+/* OMAP2/3-common powerdomains */
+
+/*
+ * The GFX powerdomain is not present on 3430ES2, but currently we do not
+ * have a macro to filter it out at compile-time.
+ */
+struct powerdomain gfx_omap2_pwrdm = {
+ .name = "gfx_pwrdm",
+ .prcm_offs = GFX_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430ES1),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+struct powerdomain wkup_omap2_pwrdm = {
+ .name = "wkup_pwrdm",
+ .prcm_offs = WKUP_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_ON,
+};
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h
new file mode 100644
index 00000000..fa311669
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.h
@@ -0,0 +1,22 @@
+/*
+ * OMAP2/3 common powerdomains - prototypes
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H
+#define __ARCH_ARM_MACH_OMAP2_POWERDOMAINS2XXX_3XXX_DATA_H
+
+#include "powerdomain.h"
+
+extern struct powerdomain gfx_omap2_pwrdm;
+extern struct powerdomain wkup_omap2_pwrdm;
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
new file mode 100644
index 00000000..cc389fb2
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -0,0 +1,123 @@
+/*
+ * OMAP2XXX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This program is free software; you can 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 "powerdomain.h"
+#include "powerdomains2xxx_3xxx_data.h"
+
+#include "prcm-common.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+
+/* 24XX powerdomains and dependencies */
+
+/* Powerdomains */
+
+static struct powerdomain dsp_pwrdm = {
+ .name = "dsp_pwrdm",
+ .prcm_offs = OMAP24XX_DSP_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON,
+ },
+};
+
+static struct powerdomain mpu_24xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON,
+ },
+};
+
+static struct powerdomain core_24xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ [2] = PWRSTS_OFF_RET, /* MEM3RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
+ },
+};
+
+
+/*
+ * 2430-specific powerdomains
+ */
+
+#ifdef CONFIG_SOC_OMAP2430
+
+/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
+
+static struct powerdomain mdm_pwrdm = {
+ .name = "mdm_pwrdm",
+ .prcm_offs = OMAP2430_MDM_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+#endif /* CONFIG_SOC_OMAP2430 */
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap2xxx[] __initdata = {
+
+ &wkup_omap2_pwrdm,
+ &gfx_omap2_pwrdm,
+
+#ifdef CONFIG_ARCH_OMAP2
+ &dsp_pwrdm,
+ &mpu_24xx_pwrdm,
+ &core_24xx_pwrdm,
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+ &mdm_pwrdm,
+#endif
+ NULL
+};
+
+void __init omap2xxx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap2xxx, &omap2_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
new file mode 100644
index 00000000..469a920a
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -0,0 +1,287 @@
+/*
+ * OMAP3 powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2011 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This program is free software; you can 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 "powerdomain.h"
+#include "powerdomains2xxx_3xxx_data.h"
+
+#include "prcm-common.h"
+#include "prm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * 34XX-specific powerdomains, dependencies
+ */
+
+#ifdef CONFIG_ARCH_OMAP3
+
+/*
+ * Powerdomains
+ */
+
+static struct powerdomain iva2_pwrdm = {
+ .name = "iva2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET,
+ [1] = PWRSTS_OFF_RET,
+ [2] = PWRSTS_OFF_RET,
+ [3] = PWRSTS_OFF_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON,
+ [1] = PWRSTS_ON,
+ [2] = PWRSTS_OFF_ON,
+ [3] = PWRSTS_ON,
+ },
+};
+
+static struct powerdomain mpu_3xxx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .flags = PWRDM_HAS_MPU_QUIRK,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_ON,
+ },
+};
+
+/*
+ * The USBTLL Save-and-Restore mechanism is broken on
+ * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
+ * needs to be disabled on these chips.
+ * Refer: 3430 errata ID i459 and 3630 errata ID i579
+ *
+ * Note: setting the SAR flag could help for errata ID i478
+ * which applies to 3430 <= ES3.1, but since the SAR feature
+ * is broken, do not use it.
+ */
+static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_IS_OMAP3430ES2 |
+ CHIP_IS_OMAP3430ES3_0 |
+ CHIP_IS_OMAP3630ES1),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ },
+};
+
+static struct powerdomain core_3xxx_es3_1_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ /*
+ * Setting the SAR flag for errata ID i478 which applies
+ * to 3430 <= ES3.1
+ */
+ .flags = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ },
+};
+
+static struct powerdomain dss_pwrdm = {
+ .name = "dss_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .prcm_offs = OMAP3430_DSS_MOD,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+/*
+ * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
+ * possible SGX powerstate, the SGX device itself does not support
+ * retention.
+ */
+static struct powerdomain sgx_pwrdm = {
+ .name = "sgx_pwrdm",
+ .prcm_offs = OMAP3430ES2_SGX_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+ /* XXX This is accurate for 3430 SGX, but what about GFX? */
+ .pwrsts = PWRSTS_OFF_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain cam_pwrdm = {
+ .name = "cam_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .prcm_offs = OMAP3430_CAM_MOD,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain per_pwrdm = {
+ .name = "per_pwrdm",
+ .prcm_offs = OMAP3430_PER_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain emu_pwrdm = {
+ .name = "emu_pwrdm",
+ .prcm_offs = OMAP3430_EMU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain neon_pwrdm = {
+ .name = "neon_pwrdm",
+ .prcm_offs = OMAP3430_NEON_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+};
+
+static struct powerdomain usbhost_pwrdm = {
+ .name = "usbhost_pwrdm",
+ .prcm_offs = OMAP3430ES2_USBHOST_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_RET,
+ /*
+ * REVISIT: Enabling usb host save and restore mechanism seems to
+ * leave the usb host domain permanently in ACTIVE mode after
+ * changing the usb host power domain state from OFF to active once.
+ * Disabling for now.
+ */
+ /*.flags = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain dpll1_pwrdm = {
+ .name = "dpll1_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll2_pwrdm = {
+ .name = "dpll2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll3_pwrdm = {
+ .name = "dpll3_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll4_pwrdm = {
+ .name = "dpll4_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain dpll5_pwrdm = {
+ .name = "dpll5_pwrdm",
+ .prcm_offs = PLL_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+};
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap3xxx[] __initdata = {
+
+ &wkup_omap2_pwrdm,
+ &gfx_omap2_pwrdm,
+ &iva2_pwrdm,
+ &mpu_3xxx_pwrdm,
+ &neon_pwrdm,
+ &core_3xxx_pre_es3_1_pwrdm,
+ &core_3xxx_es3_1_pwrdm,
+ &cam_pwrdm,
+ &dss_pwrdm,
+ &per_pwrdm,
+ &emu_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+ &dpll1_pwrdm,
+ &dpll2_pwrdm,
+ &dpll3_pwrdm,
+ &dpll4_pwrdm,
+ &dpll5_pwrdm,
+#endif
+ NULL
+};
+
+
+void __init omap3xxx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap3xxx, &omap3_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
new file mode 100644
index 00000000..c4222c70
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -0,0 +1,355 @@
+/*
+ * OMAP4 Power domains framework
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Nokia Corporation
+ *
+ * Abhijit Pagare (abhijitpagare@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley (paul@pwsan.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "powerdomain.h"
+
+#include "prcm-common.h"
+#include "prcm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm_mpu44xx.h"
+
+/* core_44xx_pwrdm: CORE power domain */
+static struct powerdomain core_44xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = OMAP4430_PRM_CORE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 5,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_RET, /* core_other_bank */
+ [3] = PWRSTS_OFF_RET, /* ducati_l2ram */
+ [4] = PWRSTS_OFF_RET, /* ducati_unicache */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* core_nret_bank */
+ [1] = PWRSTS_OFF_RET, /* core_ocmram */
+ [2] = PWRSTS_ON, /* core_other_bank */
+ [3] = PWRSTS_ON, /* ducati_l2ram */
+ [4] = PWRSTS_ON, /* ducati_unicache */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* gfx_44xx_pwrdm: 3D accelerator power domain */
+static struct powerdomain gfx_44xx_pwrdm = {
+ .name = "gfx_pwrdm",
+ .prcm_offs = OMAP4430_PRM_GFX_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* gfx_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* gfx_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* abe_44xx_pwrdm: Audio back end power domain */
+static struct powerdomain abe_44xx_pwrdm = {
+ .name = "abe_pwrdm",
+ .prcm_offs = OMAP4430_PRM_ABE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* aessmem */
+ [1] = PWRSTS_OFF, /* periphmem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* aessmem */
+ [1] = PWRSTS_ON, /* periphmem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* dss_44xx_pwrdm: Display subsystem power domain */
+static struct powerdomain dss_44xx_pwrdm = {
+ .name = "dss_pwrdm",
+ .prcm_offs = OMAP4430_PRM_DSS_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* dss_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* dss_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* tesla_44xx_pwrdm: Tesla processor power domain */
+static struct powerdomain tesla_44xx_pwrdm = {
+ .name = "tesla_pwrdm",
+ .prcm_offs = OMAP4430_PRM_TESLA_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_RET, /* tesla_edma */
+ [1] = PWRSTS_OFF_RET, /* tesla_l1 */
+ [2] = PWRSTS_OFF_RET, /* tesla_l2 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* tesla_edma */
+ [1] = PWRSTS_ON, /* tesla_l1 */
+ [2] = PWRSTS_ON, /* tesla_l2 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* wkup_44xx_pwrdm: Wake-up power domain */
+static struct powerdomain wkup_44xx_pwrdm = {
+ .name = "wkup_pwrdm",
+ .prcm_offs = OMAP4430_PRM_WKUP_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* wkup_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* wkup_bank */
+ },
+};
+
+/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
+static struct powerdomain cpu0_44xx_pwrdm = {
+ .name = "cpu0_pwrdm",
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu0_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu0_l1 */
+ },
+};
+
+/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
+static struct powerdomain cpu1_44xx_pwrdm = {
+ .name = "cpu1_pwrdm",
+ .prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST,
+ .prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* cpu1_l1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cpu1_l1 */
+ },
+};
+
+/* emu_44xx_pwrdm: Emulation power domain */
+static struct powerdomain emu_44xx_pwrdm = {
+ .name = "emu_pwrdm",
+ .prcm_offs = OMAP4430_PRM_EMU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* emu_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* emu_bank */
+ },
+};
+
+/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
+static struct powerdomain mpu_44xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = OMAP4430_PRM_MPU_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* mpu_l1 */
+ [1] = PWRSTS_OFF_RET, /* mpu_l2 */
+ [2] = PWRSTS_RET, /* mpu_ram */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* mpu_l1 */
+ [1] = PWRSTS_ON, /* mpu_l2 */
+ [2] = PWRSTS_ON, /* mpu_ram */
+ },
+};
+
+/* ivahd_44xx_pwrdm: IVA-HD power domain */
+static struct powerdomain ivahd_44xx_pwrdm = {
+ .name = "ivahd_pwrdm",
+ .prcm_offs = OMAP4430_PRM_IVAHD_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* hwa_mem */
+ [1] = PWRSTS_OFF_RET, /* sl2_mem */
+ [2] = PWRSTS_OFF_RET, /* tcm1_mem */
+ [3] = PWRSTS_OFF_RET, /* tcm2_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* hwa_mem */
+ [1] = PWRSTS_ON, /* sl2_mem */
+ [2] = PWRSTS_ON, /* tcm1_mem */
+ [3] = PWRSTS_ON, /* tcm2_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* cam_44xx_pwrdm: Camera subsystem power domain */
+static struct powerdomain cam_44xx_pwrdm = {
+ .name = "cam_pwrdm",
+ .prcm_offs = OMAP4430_PRM_CAM_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_ON,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* cam_mem */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* cam_mem */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */
+static struct powerdomain l3init_44xx_pwrdm = {
+ .name = "l3init_pwrdm",
+ .prcm_offs = OMAP4430_PRM_L3INIT_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* l3init_bank1 */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* l3init_bank1 */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/* l4per_44xx_pwrdm: Target peripherals power domain */
+static struct powerdomain l4per_44xx_pwrdm = {
+ .name = "l4per_pwrdm",
+ .prcm_offs = OMAP4430_PRM_L4PER_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF, /* nonretained_bank */
+ [1] = PWRSTS_RET, /* retained_bank */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_ON, /* nonretained_bank */
+ [1] = PWRSTS_ON, /* retained_bank */
+ },
+ .flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
+};
+
+/*
+ * always_on_core_44xx_pwrdm: Always ON logic that sits in VDD_CORE voltage
+ * domain
+ */
+static struct powerdomain always_on_core_44xx_pwrdm = {
+ .name = "always_on_core_pwrdm",
+ .prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_ON,
+};
+
+/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
+static struct powerdomain cefuse_44xx_pwrdm = {
+ .name = "cefuse_pwrdm",
+ .prcm_offs = OMAP4430_PRM_CEFUSE_INST,
+ .prcm_partition = OMAP4430_PRM_PARTITION,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+ .pwrsts = PWRSTS_OFF_ON,
+};
+
+/*
+ * The following power domains are not under SW control
+ *
+ * always_on_iva
+ * always_on_mpu
+ * stdefuse
+ */
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap44xx[] __initdata = {
+ &core_44xx_pwrdm,
+ &gfx_44xx_pwrdm,
+ &abe_44xx_pwrdm,
+ &dss_44xx_pwrdm,
+ &tesla_44xx_pwrdm,
+ &wkup_44xx_pwrdm,
+ &cpu0_44xx_pwrdm,
+ &cpu1_44xx_pwrdm,
+ &emu_44xx_pwrdm,
+ &mpu_44xx_pwrdm,
+ &ivahd_44xx_pwrdm,
+ &cam_44xx_pwrdm,
+ &l3init_44xx_pwrdm,
+ &l4per_44xx_pwrdm,
+ &always_on_core_44xx_pwrdm,
+ &cefuse_44xx_pwrdm,
+ NULL
+};
+
+void __init omap44xx_powerdomains_init(void)
+{
+ pwrdm_init(powerdomains_omap44xx, &omap4_pwrdm_operations);
+}
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
new file mode 100644
index 00000000..0363dcb0
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -0,0 +1,414 @@
+#ifndef __ARCH_ASM_MACH_OMAP2_PRCM_COMMON_H
+#define __ARCH_ASM_MACH_OMAP2_PRCM_COMMON_H
+
+/*
+ * OMAP2/3 PRCM base and module definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2009 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Module offsets from both CM_BASE & PRM_BASE */
+
+/*
+ * Offsets that are the same on 24xx and 34xx
+ *
+ * Technically, in terms of the TRM, OCP_MOD is 34xx only; PLL_MOD is
+ * CCR_MOD on 3430; and GFX_MOD only exists < 3430ES2.
+ */
+#define OCP_MOD 0x000
+#define MPU_MOD 0x100
+#define CORE_MOD 0x200
+#define GFX_MOD 0x300
+#define WKUP_MOD 0x400
+#define PLL_MOD 0x500
+
+
+/* Chip-specific module offsets */
+#define OMAP24XX_GR_MOD OCP_MOD
+#define OMAP24XX_DSP_MOD 0x800
+
+#define OMAP2430_MDM_MOD 0xc00
+
+/* IVA2 module is < base on 3430 */
+#define OMAP3430_IVA2_MOD -0x800
+#define OMAP3430ES2_SGX_MOD GFX_MOD
+#define OMAP3430_CCR_MOD PLL_MOD
+#define OMAP3430_DSS_MOD 0x600
+#define OMAP3430_CAM_MOD 0x700
+#define OMAP3430_PER_MOD 0x800
+#define OMAP3430_EMU_MOD 0x900
+#define OMAP3430_GR_MOD 0xa00
+#define OMAP3430_NEON_MOD 0xb00
+#define OMAP3430ES2_USBHOST_MOD 0xc00
+
+/* 24XX register bits shared between CM & PRM registers */
+
+/* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
+#define OMAP2420_EN_MMC_SHIFT 26
+#define OMAP2420_EN_MMC_MASK (1 << 26)
+#define OMAP24XX_EN_UART2_SHIFT 22
+#define OMAP24XX_EN_UART2_MASK (1 << 22)
+#define OMAP24XX_EN_UART1_SHIFT 21
+#define OMAP24XX_EN_UART1_MASK (1 << 21)
+#define OMAP24XX_EN_MCSPI2_SHIFT 18
+#define OMAP24XX_EN_MCSPI2_MASK (1 << 18)
+#define OMAP24XX_EN_MCSPI1_SHIFT 17
+#define OMAP24XX_EN_MCSPI1_MASK (1 << 17)
+#define OMAP24XX_EN_MCBSP2_SHIFT 16
+#define OMAP24XX_EN_MCBSP2_MASK (1 << 16)
+#define OMAP24XX_EN_MCBSP1_SHIFT 15
+#define OMAP24XX_EN_MCBSP1_MASK (1 << 15)
+#define OMAP24XX_EN_GPT12_SHIFT 14
+#define OMAP24XX_EN_GPT12_MASK (1 << 14)
+#define OMAP24XX_EN_GPT11_SHIFT 13
+#define OMAP24XX_EN_GPT11_MASK (1 << 13)
+#define OMAP24XX_EN_GPT10_SHIFT 12
+#define OMAP24XX_EN_GPT10_MASK (1 << 12)
+#define OMAP24XX_EN_GPT9_SHIFT 11
+#define OMAP24XX_EN_GPT9_MASK (1 << 11)
+#define OMAP24XX_EN_GPT8_SHIFT 10
+#define OMAP24XX_EN_GPT8_MASK (1 << 10)
+#define OMAP24XX_EN_GPT7_SHIFT 9
+#define OMAP24XX_EN_GPT7_MASK (1 << 9)
+#define OMAP24XX_EN_GPT6_SHIFT 8
+#define OMAP24XX_EN_GPT6_MASK (1 << 8)
+#define OMAP24XX_EN_GPT5_SHIFT 7
+#define OMAP24XX_EN_GPT5_MASK (1 << 7)
+#define OMAP24XX_EN_GPT4_SHIFT 6
+#define OMAP24XX_EN_GPT4_MASK (1 << 6)
+#define OMAP24XX_EN_GPT3_SHIFT 5
+#define OMAP24XX_EN_GPT3_MASK (1 << 5)
+#define OMAP24XX_EN_GPT2_SHIFT 4
+#define OMAP24XX_EN_GPT2_MASK (1 << 4)
+#define OMAP2420_EN_VLYNQ_SHIFT 3
+#define OMAP2420_EN_VLYNQ_MASK (1 << 3)
+
+/* CM_FCLKEN2_CORE, CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */
+#define OMAP2430_EN_GPIO5_SHIFT 10
+#define OMAP2430_EN_GPIO5_MASK (1 << 10)
+#define OMAP2430_EN_MCSPI3_SHIFT 9
+#define OMAP2430_EN_MCSPI3_MASK (1 << 9)
+#define OMAP2430_EN_MMCHS2_SHIFT 8
+#define OMAP2430_EN_MMCHS2_MASK (1 << 8)
+#define OMAP2430_EN_MMCHS1_SHIFT 7
+#define OMAP2430_EN_MMCHS1_MASK (1 << 7)
+#define OMAP24XX_EN_UART3_SHIFT 2
+#define OMAP24XX_EN_UART3_MASK (1 << 2)
+#define OMAP24XX_EN_USB_SHIFT 0
+#define OMAP24XX_EN_USB_MASK (1 << 0)
+
+/* CM_ICLKEN2_CORE, PM_WKEN2_CORE shared bits */
+#define OMAP2430_EN_MDM_INTC_SHIFT 11
+#define OMAP2430_EN_MDM_INTC_MASK (1 << 11)
+#define OMAP2430_EN_USBHS_SHIFT 6
+#define OMAP2430_EN_USBHS_MASK (1 << 6)
+
+/* CM_IDLEST1_CORE, PM_WKST1_CORE shared bits */
+#define OMAP2420_ST_MMC_SHIFT 26
+#define OMAP2420_ST_MMC_MASK (1 << 26)
+#define OMAP24XX_ST_UART2_SHIFT 22
+#define OMAP24XX_ST_UART2_MASK (1 << 22)
+#define OMAP24XX_ST_UART1_SHIFT 21
+#define OMAP24XX_ST_UART1_MASK (1 << 21)
+#define OMAP24XX_ST_MCSPI2_SHIFT 18
+#define OMAP24XX_ST_MCSPI2_MASK (1 << 18)
+#define OMAP24XX_ST_MCSPI1_SHIFT 17
+#define OMAP24XX_ST_MCSPI1_MASK (1 << 17)
+#define OMAP24XX_ST_MCBSP2_SHIFT 16
+#define OMAP24XX_ST_MCBSP2_MASK (1 << 16)
+#define OMAP24XX_ST_MCBSP1_SHIFT 15
+#define OMAP24XX_ST_MCBSP1_MASK (1 << 15)
+#define OMAP24XX_ST_GPT12_SHIFT 14
+#define OMAP24XX_ST_GPT12_MASK (1 << 14)
+#define OMAP24XX_ST_GPT11_SHIFT 13
+#define OMAP24XX_ST_GPT11_MASK (1 << 13)
+#define OMAP24XX_ST_GPT10_SHIFT 12
+#define OMAP24XX_ST_GPT10_MASK (1 << 12)
+#define OMAP24XX_ST_GPT9_SHIFT 11
+#define OMAP24XX_ST_GPT9_MASK (1 << 11)
+#define OMAP24XX_ST_GPT8_SHIFT 10
+#define OMAP24XX_ST_GPT8_MASK (1 << 10)
+#define OMAP24XX_ST_GPT7_SHIFT 9
+#define OMAP24XX_ST_GPT7_MASK (1 << 9)
+#define OMAP24XX_ST_GPT6_SHIFT 8
+#define OMAP24XX_ST_GPT6_MASK (1 << 8)
+#define OMAP24XX_ST_GPT5_SHIFT 7
+#define OMAP24XX_ST_GPT5_MASK (1 << 7)
+#define OMAP24XX_ST_GPT4_SHIFT 6
+#define OMAP24XX_ST_GPT4_MASK (1 << 6)
+#define OMAP24XX_ST_GPT3_SHIFT 5
+#define OMAP24XX_ST_GPT3_MASK (1 << 5)
+#define OMAP24XX_ST_GPT2_SHIFT 4
+#define OMAP24XX_ST_GPT2_MASK (1 << 4)
+#define OMAP2420_ST_VLYNQ_SHIFT 3
+#define OMAP2420_ST_VLYNQ_MASK (1 << 3)
+
+/* CM_IDLEST2_CORE, PM_WKST2_CORE shared bits */
+#define OMAP2430_ST_MDM_INTC_SHIFT 11
+#define OMAP2430_ST_MDM_INTC_MASK (1 << 11)
+#define OMAP2430_ST_GPIO5_SHIFT 10
+#define OMAP2430_ST_GPIO5_MASK (1 << 10)
+#define OMAP2430_ST_MCSPI3_SHIFT 9
+#define OMAP2430_ST_MCSPI3_MASK (1 << 9)
+#define OMAP2430_ST_MMCHS2_SHIFT 8
+#define OMAP2430_ST_MMCHS2_MASK (1 << 8)
+#define OMAP2430_ST_MMCHS1_SHIFT 7
+#define OMAP2430_ST_MMCHS1_MASK (1 << 7)
+#define OMAP2430_ST_USBHS_SHIFT 6
+#define OMAP2430_ST_USBHS_MASK (1 << 6)
+#define OMAP24XX_ST_UART3_SHIFT 2
+#define OMAP24XX_ST_UART3_MASK (1 << 2)
+#define OMAP24XX_ST_USB_SHIFT 0
+#define OMAP24XX_ST_USB_MASK (1 << 0)
+
+/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
+#define OMAP24XX_EN_GPIOS_SHIFT 2
+#define OMAP24XX_EN_GPIOS_MASK (1 << 2)
+#define OMAP24XX_EN_GPT1_SHIFT 0
+#define OMAP24XX_EN_GPT1_MASK (1 << 0)
+
+/* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */
+#define OMAP24XX_ST_GPIOS_SHIFT 2
+#define OMAP24XX_ST_GPIOS_MASK (1 << 2)
+#define OMAP24XX_ST_GPT1_SHIFT 0
+#define OMAP24XX_ST_GPT1_MASK (1 << 0)
+
+/* CM_IDLEST_MDM and PM_WKST_MDM shared bits */
+#define OMAP2430_ST_MDM_SHIFT 0
+#define OMAP2430_ST_MDM_MASK (1 << 0)
+
+
+/* 3430 register bits shared between CM & PRM registers */
+
+/* CM_REVISION, PRM_REVISION shared bits */
+#define OMAP3430_REV_SHIFT 0
+#define OMAP3430_REV_MASK (0xff << 0)
+
+/* CM_SYSCONFIG, PRM_SYSCONFIG shared bits */
+#define OMAP3430_AUTOIDLE_MASK (1 << 0)
+
+/* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
+#define OMAP3430_EN_MMC3_MASK (1 << 30)
+#define OMAP3430_EN_MMC3_SHIFT 30
+#define OMAP3430_EN_MMC2_MASK (1 << 25)
+#define OMAP3430_EN_MMC2_SHIFT 25
+#define OMAP3430_EN_MMC1_MASK (1 << 24)
+#define OMAP3430_EN_MMC1_SHIFT 24
+#define OMAP3430_EN_MCSPI4_MASK (1 << 21)
+#define OMAP3430_EN_MCSPI4_SHIFT 21
+#define OMAP3430_EN_MCSPI3_MASK (1 << 20)
+#define OMAP3430_EN_MCSPI3_SHIFT 20
+#define OMAP3430_EN_MCSPI2_MASK (1 << 19)
+#define OMAP3430_EN_MCSPI2_SHIFT 19
+#define OMAP3430_EN_MCSPI1_MASK (1 << 18)
+#define OMAP3430_EN_MCSPI1_SHIFT 18
+#define OMAP3430_EN_I2C3_MASK (1 << 17)
+#define OMAP3430_EN_I2C3_SHIFT 17
+#define OMAP3430_EN_I2C2_MASK (1 << 16)
+#define OMAP3430_EN_I2C2_SHIFT 16
+#define OMAP3430_EN_I2C1_MASK (1 << 15)
+#define OMAP3430_EN_I2C1_SHIFT 15
+#define OMAP3430_EN_UART2_MASK (1 << 14)
+#define OMAP3430_EN_UART2_SHIFT 14
+#define OMAP3430_EN_UART1_MASK (1 << 13)
+#define OMAP3430_EN_UART1_SHIFT 13
+#define OMAP3430_EN_GPT11_MASK (1 << 12)
+#define OMAP3430_EN_GPT11_SHIFT 12
+#define OMAP3430_EN_GPT10_MASK (1 << 11)
+#define OMAP3430_EN_GPT10_SHIFT 11
+#define OMAP3430_EN_MCBSP5_MASK (1 << 10)
+#define OMAP3430_EN_MCBSP5_SHIFT 10
+#define OMAP3430_EN_MCBSP1_MASK (1 << 9)
+#define OMAP3430_EN_MCBSP1_SHIFT 9
+#define OMAP3430_EN_FSHOSTUSB_MASK (1 << 5)
+#define OMAP3430_EN_FSHOSTUSB_SHIFT 5
+#define OMAP3430_EN_D2D_MASK (1 << 3)
+#define OMAP3430_EN_D2D_SHIFT 3
+
+/* CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */
+#define OMAP3430_EN_HSOTGUSB_MASK (1 << 4)
+#define OMAP3430_EN_HSOTGUSB_SHIFT 4
+
+/* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */
+#define OMAP3430_ST_MMC3_SHIFT 30
+#define OMAP3430_ST_MMC3_MASK (1 << 30)
+#define OMAP3430_ST_MMC2_SHIFT 25
+#define OMAP3430_ST_MMC2_MASK (1 << 25)
+#define OMAP3430_ST_MMC1_SHIFT 24
+#define OMAP3430_ST_MMC1_MASK (1 << 24)
+#define OMAP3430_ST_MCSPI4_SHIFT 21
+#define OMAP3430_ST_MCSPI4_MASK (1 << 21)
+#define OMAP3430_ST_MCSPI3_SHIFT 20
+#define OMAP3430_ST_MCSPI3_MASK (1 << 20)
+#define OMAP3430_ST_MCSPI2_SHIFT 19
+#define OMAP3430_ST_MCSPI2_MASK (1 << 19)
+#define OMAP3430_ST_MCSPI1_SHIFT 18
+#define OMAP3430_ST_MCSPI1_MASK (1 << 18)
+#define OMAP3430_ST_I2C3_SHIFT 17
+#define OMAP3430_ST_I2C3_MASK (1 << 17)
+#define OMAP3430_ST_I2C2_SHIFT 16
+#define OMAP3430_ST_I2C2_MASK (1 << 16)
+#define OMAP3430_ST_I2C1_SHIFT 15
+#define OMAP3430_ST_I2C1_MASK (1 << 15)
+#define OMAP3430_ST_UART2_SHIFT 14
+#define OMAP3430_ST_UART2_MASK (1 << 14)
+#define OMAP3430_ST_UART1_SHIFT 13
+#define OMAP3430_ST_UART1_MASK (1 << 13)
+#define OMAP3430_ST_GPT11_SHIFT 12
+#define OMAP3430_ST_GPT11_MASK (1 << 12)
+#define OMAP3430_ST_GPT10_SHIFT 11
+#define OMAP3430_ST_GPT10_MASK (1 << 11)
+#define OMAP3430_ST_MCBSP5_SHIFT 10
+#define OMAP3430_ST_MCBSP5_MASK (1 << 10)
+#define OMAP3430_ST_MCBSP1_SHIFT 9
+#define OMAP3430_ST_MCBSP1_MASK (1 << 9)
+#define OMAP3430ES1_ST_FSHOSTUSB_SHIFT 5
+#define OMAP3430ES1_ST_FSHOSTUSB_MASK (1 << 5)
+#define OMAP3430ES1_ST_HSOTGUSB_SHIFT 4
+#define OMAP3430ES1_ST_HSOTGUSB_MASK (1 << 4)
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT 5
+#define OMAP3430ES2_ST_HSOTGUSB_IDLE_MASK (1 << 5)
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT 4
+#define OMAP3430ES2_ST_HSOTGUSB_STDBY_MASK (1 << 4)
+#define OMAP3430_ST_D2D_SHIFT 3
+#define OMAP3430_ST_D2D_MASK (1 << 3)
+
+/* CM_FCLKEN_WKUP, CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
+#define OMAP3430_EN_GPIO1_MASK (1 << 3)
+#define OMAP3430_EN_GPIO1_SHIFT 3
+#define OMAP3430_EN_GPT12_MASK (1 << 1)
+#define OMAP3430_EN_GPT12_SHIFT 1
+#define OMAP3430_EN_GPT1_MASK (1 << 0)
+#define OMAP3430_EN_GPT1_SHIFT 0
+
+/* CM_FCLKEN_WKUP, PM_WKEN_WKUP shared bits */
+#define OMAP3430_EN_SR2_MASK (1 << 7)
+#define OMAP3430_EN_SR2_SHIFT 7
+#define OMAP3430_EN_SR1_MASK (1 << 6)
+#define OMAP3430_EN_SR1_SHIFT 6
+
+/* CM_ICLKEN_WKUP, PM_WKEN_WKUP shared bits */
+#define OMAP3430_EN_GPT12_MASK (1 << 1)
+#define OMAP3430_EN_GPT12_SHIFT 1
+
+/* CM_IDLEST_WKUP, PM_WKST_WKUP shared bits */
+#define OMAP3430_ST_SR2_SHIFT 7
+#define OMAP3430_ST_SR2_MASK (1 << 7)
+#define OMAP3430_ST_SR1_SHIFT 6
+#define OMAP3430_ST_SR1_MASK (1 << 6)
+#define OMAP3430_ST_GPIO1_SHIFT 3
+#define OMAP3430_ST_GPIO1_MASK (1 << 3)
+#define OMAP3430_ST_GPT12_SHIFT 1
+#define OMAP3430_ST_GPT12_MASK (1 << 1)
+#define OMAP3430_ST_GPT1_SHIFT 0
+#define OMAP3430_ST_GPT1_MASK (1 << 0)
+
+/*
+ * CM_SLEEPDEP_GFX, CM_SLEEPDEP_DSS, CM_SLEEPDEP_CAM,
+ * CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_GFX,
+ * PM_WKDEP_DSS, PM_WKDEP_CAM, PM_WKDEP_PER, PM_WKDEP_NEON shared bits
+ */
+#define OMAP3430_EN_MPU_MASK (1 << 1)
+#define OMAP3430_EN_MPU_SHIFT 1
+
+/* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER shared bits */
+
+#define OMAP3630_EN_UART4_MASK (1 << 18)
+#define OMAP3630_EN_UART4_SHIFT 18
+#define OMAP3430_EN_GPIO6_MASK (1 << 17)
+#define OMAP3430_EN_GPIO6_SHIFT 17
+#define OMAP3430_EN_GPIO5_MASK (1 << 16)
+#define OMAP3430_EN_GPIO5_SHIFT 16
+#define OMAP3430_EN_GPIO4_MASK (1 << 15)
+#define OMAP3430_EN_GPIO4_SHIFT 15
+#define OMAP3430_EN_GPIO3_MASK (1 << 14)
+#define OMAP3430_EN_GPIO3_SHIFT 14
+#define OMAP3430_EN_GPIO2_MASK (1 << 13)
+#define OMAP3430_EN_GPIO2_SHIFT 13
+#define OMAP3430_EN_UART3_MASK (1 << 11)
+#define OMAP3430_EN_UART3_SHIFT 11
+#define OMAP3430_EN_GPT9_MASK (1 << 10)
+#define OMAP3430_EN_GPT9_SHIFT 10
+#define OMAP3430_EN_GPT8_MASK (1 << 9)
+#define OMAP3430_EN_GPT8_SHIFT 9
+#define OMAP3430_EN_GPT7_MASK (1 << 8)
+#define OMAP3430_EN_GPT7_SHIFT 8
+#define OMAP3430_EN_GPT6_MASK (1 << 7)
+#define OMAP3430_EN_GPT6_SHIFT 7
+#define OMAP3430_EN_GPT5_MASK (1 << 6)
+#define OMAP3430_EN_GPT5_SHIFT 6
+#define OMAP3430_EN_GPT4_MASK (1 << 5)
+#define OMAP3430_EN_GPT4_SHIFT 5
+#define OMAP3430_EN_GPT3_MASK (1 << 4)
+#define OMAP3430_EN_GPT3_SHIFT 4
+#define OMAP3430_EN_GPT2_MASK (1 << 3)
+#define OMAP3430_EN_GPT2_SHIFT 3
+
+/* CM_FCLKEN_PER, CM_ICLKEN_PER, PM_WKEN_PER, PM_WKST_PER shared bits */
+/* XXX Possible TI documentation bug: should the PM_WKST_PER EN_* bits
+ * be ST_* bits instead? */
+#define OMAP3430_EN_MCBSP4_MASK (1 << 2)
+#define OMAP3430_EN_MCBSP4_SHIFT 2
+#define OMAP3430_EN_MCBSP3_MASK (1 << 1)
+#define OMAP3430_EN_MCBSP3_SHIFT 1
+#define OMAP3430_EN_MCBSP2_MASK (1 << 0)
+#define OMAP3430_EN_MCBSP2_SHIFT 0
+
+/* CM_IDLEST_PER, PM_WKST_PER shared bits */
+#define OMAP3630_ST_UART4_SHIFT 18
+#define OMAP3630_ST_UART4_MASK (1 << 18)
+#define OMAP3430_ST_GPIO6_SHIFT 17
+#define OMAP3430_ST_GPIO6_MASK (1 << 17)
+#define OMAP3430_ST_GPIO5_SHIFT 16
+#define OMAP3430_ST_GPIO5_MASK (1 << 16)
+#define OMAP3430_ST_GPIO4_SHIFT 15
+#define OMAP3430_ST_GPIO4_MASK (1 << 15)
+#define OMAP3430_ST_GPIO3_SHIFT 14
+#define OMAP3430_ST_GPIO3_MASK (1 << 14)
+#define OMAP3430_ST_GPIO2_SHIFT 13
+#define OMAP3430_ST_GPIO2_MASK (1 << 13)
+#define OMAP3430_ST_UART3_SHIFT 11
+#define OMAP3430_ST_UART3_MASK (1 << 11)
+#define OMAP3430_ST_GPT9_SHIFT 10
+#define OMAP3430_ST_GPT9_MASK (1 << 10)
+#define OMAP3430_ST_GPT8_SHIFT 9
+#define OMAP3430_ST_GPT8_MASK (1 << 9)
+#define OMAP3430_ST_GPT7_SHIFT 8
+#define OMAP3430_ST_GPT7_MASK (1 << 8)
+#define OMAP3430_ST_GPT6_SHIFT 7
+#define OMAP3430_ST_GPT6_MASK (1 << 7)
+#define OMAP3430_ST_GPT5_SHIFT 6
+#define OMAP3430_ST_GPT5_MASK (1 << 6)
+#define OMAP3430_ST_GPT4_SHIFT 5
+#define OMAP3430_ST_GPT4_MASK (1 << 5)
+#define OMAP3430_ST_GPT3_SHIFT 4
+#define OMAP3430_ST_GPT3_MASK (1 << 4)
+#define OMAP3430_ST_GPT2_SHIFT 3
+#define OMAP3430_ST_GPT2_MASK (1 << 3)
+
+/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
+#define OMAP3430_EN_CORE_SHIFT 0
+#define OMAP3430_EN_CORE_MASK (1 << 0)
+
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+# ifndef __ASSEMBLER__
+extern void __iomem *prm_base;
+extern void __iomem *cm_base;
+extern void __iomem *cm2_base;
+# endif
+
+#endif
+
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c
new file mode 100644
index 00000000..6be14389
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm.c
@@ -0,0 +1,167 @@
+/*
+ * linux/arch/arm/mach-omap2/prcm.c
+ *
+ * OMAP 24xx Power Reset and Clock Management (PRCM) functions
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * Some pieces of code Copyright (C) 2005 Texas Instruments, Inc.
+ * Upgraded with OMAP4 support by Abhijit Pagare <abhijitpagare@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <mach/system.h>
+#include <plat/common.h>
+#include <plat/prcm.h>
+#include <plat/irqs.h>
+
+#include "clock.h"
+#include "clock2xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "prm44xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-44xx.h"
+#include "control.h"
+
+void __iomem *prm_base;
+void __iomem *cm_base;
+void __iomem *cm2_base;
+
+#define MAX_MODULE_ENABLE_WAIT 100000
+
+u32 omap_prcm_get_reset_sources(void)
+{
+ /* XXX This presumably needs modification for 34XX */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ return omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
+ if (cpu_is_omap44xx())
+ return omap2_prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_prcm_get_reset_sources);
+
+/* Resets clock rates and reboots the system. Only called from system.h */
+static void omap_prcm_arch_reset(char mode, const char *cmd)
+{
+ s16 prcm_offs = 0;
+
+ if (cpu_is_omap24xx()) {
+ omap2xxx_clk_prepare_for_reboot();
+
+ prcm_offs = WKUP_MOD;
+ } else if (cpu_is_omap34xx()) {
+ prcm_offs = OMAP3430_GR_MOD;
+ omap3_ctrl_write_boot_mode((cmd ? (u8)*cmd : 0));
+ } else if (cpu_is_omap44xx()) {
+ omap4_prm_global_warm_sw_reset(); /* never returns */
+ } else {
+ WARN_ON(1);
+ }
+
+ /*
+ * As per Errata i520, in some cases, user will not be able to
+ * access DDR memory after warm-reset.
+ * This situation occurs while the warm-reset happens during a read
+ * access to DDR memory. In that particular condition, DDR memory
+ * does not respond to a corrupted read command due to the warm
+ * reset occurrence but SDRC is waiting for read completion.
+ * SDRC is not sensitive to the warm reset, but the interconnect is
+ * reset on the fly, thus causing a misalignment between SDRC logic,
+ * interconnect logic and DDR memory state.
+ * WORKAROUND:
+ * Steps to perform before a Warm reset is trigged:
+ * 1. enable self-refresh on idle request
+ * 2. put SDRC in idle
+ * 3. wait until SDRC goes to idle
+ * 4. generate SW reset (Global SW reset)
+ *
+ * Steps to be performed after warm reset occurs (in bootloader):
+ * if HW warm reset is the source, apply below steps before any
+ * accesses to SDRAM:
+ * 1. Reset SMS and SDRC and wait till reset is complete
+ * 2. Re-initialize SMS, SDRC and memory
+ *
+ * NOTE: Above work around is required only if arch reset is implemented
+ * using Global SW reset(GLOBAL_SW_RST). DPLL3 reset does not need
+ * the WA since it resets SDRC as well as part of cold reset.
+ */
+
+ /* XXX should be moved to some OMAP2/3 specific code */
+ omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, prcm_offs,
+ OMAP2_RM_RSTCTRL);
+ omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */
+}
+
+void (*arch_reset)(char, const char *) = omap_prcm_arch_reset;
+
+/**
+ * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
+ * @reg: physical address of module IDLEST register
+ * @mask: value to mask against to determine if the module is active
+ * @idlest: idle state indicator (0 or 1) for the clock
+ * @name: name of the clock (for printk)
+ *
+ * Returns 1 if the module indicated readiness in time, or 0 if it
+ * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
+ *
+ * XXX This function is deprecated. It should be removed once the
+ * hwmod conversion is complete.
+ */
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
+ const char *name)
+{
+ int i = 0;
+ int ena = 0;
+
+ if (idlest)
+ ena = 0;
+ else
+ ena = mask;
+
+ /* Wait for lock */
+ omap_test_timeout(((__raw_readl(reg) & mask) == ena),
+ MAX_MODULE_ENABLE_WAIT, i);
+
+ if (i < MAX_MODULE_ENABLE_WAIT)
+ pr_debug("cm: Module associated with clock %s ready after %d "
+ "loops\n", name, i);
+ else
+ pr_err("cm: Module associated with clock %s didn't enable in "
+ "%d tries\n", name, MAX_MODULE_ENABLE_WAIT);
+
+ return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
+};
+
+void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
+{
+ /* Static mapping, never released */
+ if (omap2_globals->prm) {
+ prm_base = ioremap(omap2_globals->prm, SZ_8K);
+ WARN_ON(!prm_base);
+ }
+ if (omap2_globals->cm) {
+ cm_base = ioremap(omap2_globals->cm, SZ_8K);
+ WARN_ON(!cm_base);
+ }
+ if (omap2_globals->cm2) {
+ cm2_base = ioremap(omap2_globals->cm2, SZ_8K);
+ WARN_ON(!cm2_base);
+ }
+}
diff --git a/arch/arm/mach-omap2/prcm44xx.h b/arch/arm/mach-omap2/prcm44xx.h
new file mode 100644
index 00000000..7334ffb9
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm44xx.h
@@ -0,0 +1,42 @@
+/*
+ * OMAP4 PRCM definitions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains macros and functions that are common to all of
+ * the PRM/CM/PRCM blocks on the OMAP4 devices: PRM, CM1, CM2,
+ * PRCM_MPU, SCRM
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM44XX_H
+
+/*
+ * OMAP4 PRCM partition IDs
+ *
+ * The numbers and order are arbitrary, but 0 is reserved for the
+ * 'invalid' partition in case someone forgets to add a
+ * .prcm_partition field.
+ */
+#define OMAP4430_INVALID_PRCM_PARTITION 0
+#define OMAP4430_PRM_PARTITION 1
+#define OMAP4430_CM1_PARTITION 2
+#define OMAP4430_CM2_PARTITION 3
+#define OMAP4430_SCRM_PARTITION 4
+#define OMAP4430_PRCM_MPU_PARTITION 5
+
+/*
+ * OMAP4_MAX_PRCM_PARTITIONS: set to the highest value of the PRCM partition
+ * IDs, plus one
+ */
+#define OMAP4_MAX_PRCM_PARTITIONS 6
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c
new file mode 100644
index 00000000..171fe171
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.c
@@ -0,0 +1,45 @@
+/*
+ * OMAP4 PRCM_MPU module functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "prcm_mpu44xx.h"
+#include "cm-regbits-44xx.h"
+
+/* PRCM_MPU low-level functions */
+
+u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_PRCM_MPU_REGADDR(inst, reg));
+}
+
+void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_PRCM_MPU_REGADDR(inst, reg));
+}
+
+u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
+{
+ u32 v;
+
+ v = omap4_prcm_mpu_read_inst_reg(inst, reg);
+ v &= ~mask;
+ v |= bits;
+ omap4_prcm_mpu_write_inst_reg(v, inst, reg);
+
+ return v;
+}
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h
new file mode 100644
index 00000000..d22d1b43
--- /dev/null
+++ b/arch/arm/mach-omap2/prcm_mpu44xx.h
@@ -0,0 +1,104 @@
+/*
+ * OMAP44xx PRCM MPU instance offset macros
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H
+
+#define OMAP4430_PRCM_MPU_BASE 0x48243000
+
+#define OMAP44XX_PRCM_MPU_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE + (inst) + (reg))
+
+/* PRCM_MPU instances */
+
+#define OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST 0x0000
+#define OMAP4430_PRCM_MPU_DEVICE_PRM_INST 0x0200
+#define OMAP4430_PRCM_MPU_CPU0_INST 0x0400
+#define OMAP4430_PRCM_MPU_CPU1_INST 0x0800
+
+/* PRCM_MPU clockdomain register offsets (from instance start) */
+#define OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS 0x0018
+#define OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS 0x0018
+
+
+/*
+ * PRCM_MPU
+ *
+ * The PRCM_MPU is a local PRCM inside the MPU subsystem. For the PRCM (global)
+ * point of view the PRCM_MPU is a single entity. It shares the same
+ * programming model as the global PRCM and thus can be assimilate as two new
+ * MOD inside the PRCM
+ */
+
+/* PRCM_MPU.OCP_SOCKET_PRCM register offsets */
+#define OMAP4_REVISION_PRCM_OFFSET 0x0000
+#define OMAP4430_REVISION_PRCM OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_OCP_SOCKET_PRCM_INST, 0x0000)
+
+/* PRCM_MPU.DEVICE_PRM register offsets */
+#define OMAP4_PRCM_MPU_PRM_RSTST_OFFSET 0x0000
+#define OMAP4430_PRCM_MPU_PRM_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0000)
+#define OMAP4_PRCM_MPU_PRM_PSCON_COUNT_OFFSET 0x0004
+#define OMAP4430_PRCM_MPU_PRM_PSCON_COUNT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_DEVICE_PRM_INST, 0x0004)
+
+/* PRCM_MPU.CPU0 register offsets */
+#define OMAP4_PM_CPU0_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CPU0_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0000)
+#define OMAP4_PM_CPU0_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CPU0_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0004)
+#define OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET 0x0008
+#define OMAP4430_RM_CPU0_CPU0_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0008)
+#define OMAP4_RM_CPU0_CPU0_RSTCTRL_OFFSET 0x000c
+#define OMAP4430_RM_CPU0_CPU0_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x000c)
+#define OMAP4_RM_CPU0_CPU0_RSTST_OFFSET 0x0010
+#define OMAP4430_RM_CPU0_CPU0_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0010)
+#define OMAP4_CM_CPU0_CPU0_CLKCTRL_OFFSET 0x0014
+#define OMAP4430_CM_CPU0_CPU0_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0014)
+#define OMAP4_CM_CPU0_CLKSTCTRL_OFFSET 0x0018
+#define OMAP4430_CM_CPU0_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU0_INST, 0x0018)
+
+/* PRCM_MPU.CPU1 register offsets */
+#define OMAP4_PM_CPU1_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CPU1_PWRSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0000)
+#define OMAP4_PM_CPU1_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CPU1_PWRSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0004)
+#define OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET 0x0008
+#define OMAP4430_RM_CPU1_CPU1_CONTEXT OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0008)
+#define OMAP4_RM_CPU1_CPU1_RSTCTRL_OFFSET 0x000c
+#define OMAP4430_RM_CPU1_CPU1_RSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x000c)
+#define OMAP4_RM_CPU1_CPU1_RSTST_OFFSET 0x0010
+#define OMAP4430_RM_CPU1_CPU1_RSTST OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0010)
+#define OMAP4_CM_CPU1_CPU1_CLKCTRL_OFFSET 0x0014
+#define OMAP4430_CM_CPU1_CPU1_CLKCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0014)
+#define OMAP4_CM_CPU1_CLKSTCTRL_OFFSET 0x0018
+#define OMAP4430_CM_CPU1_CLKSTCTRL OMAP44XX_PRCM_MPU_REGADDR(OMAP4430_PRCM_MPU_CPU1_INST, 0x0018)
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst,
+ s16 idx);
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h
new file mode 100644
index 00000000..6ac96610
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -0,0 +1,283 @@
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_24XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_24XX_H
+
+/*
+ * OMAP24XX Power/Reset Management register bits
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "prm2xxx_3xxx.h"
+
+/* Bits shared between registers */
+
+/* PRCM_IRQSTATUS_MPU, PM_IRQSTATUS_DSP, PRCM_IRQSTATUS_IVA shared bits */
+#define OMAP24XX_VOLTTRANS_ST_MASK (1 << 2)
+#define OMAP24XX_WKUP2_ST_MASK (1 << 1)
+#define OMAP24XX_WKUP1_ST_MASK (1 << 0)
+
+/* PRCM_IRQENABLE_MPU, PM_IRQENABLE_DSP, PRCM_IRQENABLE_IVA shared bits */
+#define OMAP24XX_VOLTTRANS_EN_MASK (1 << 2)
+#define OMAP24XX_WKUP2_EN_MASK (1 << 1)
+#define OMAP24XX_WKUP1_EN_MASK (1 << 0)
+
+/* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */
+#define OMAP24XX_EN_MPU_SHIFT 1
+#define OMAP24XX_EN_MPU_MASK (1 << 1)
+#define OMAP24XX_EN_CORE_SHIFT 0
+#define OMAP24XX_EN_CORE_MASK (1 << 0)
+
+/*
+ * PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM
+ * shared bits
+ */
+#define OMAP24XX_MEMONSTATE_SHIFT 10
+#define OMAP24XX_MEMONSTATE_MASK (0x3 << 10)
+#define OMAP24XX_MEMRETSTATE_MASK (1 << 3)
+
+/* PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM shared bits */
+#define OMAP24XX_FORCESTATE_MASK (1 << 18)
+
+/*
+ * PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP,
+ * PM_PWSTST_MDM shared bits
+ */
+#define OMAP24XX_CLKACTIVITY_MASK (1 << 19)
+
+/* PM_PWSTST_MPU, PM_PWSTST_CORE, PM_PWSTST_DSP shared bits */
+#define OMAP24XX_LASTSTATEENTERED_SHIFT 4
+#define OMAP24XX_LASTSTATEENTERED_MASK (0x3 << 4)
+
+/* PM_PWSTST_MPU and PM_PWSTST_DSP shared bits */
+#define OMAP2430_MEMSTATEST_SHIFT 10
+#define OMAP2430_MEMSTATEST_MASK (0x3 << 10)
+
+/* PM_PWSTST_GFX, PM_PWSTST_DSP, PM_PWSTST_MDM shared bits */
+#define OMAP24XX_POWERSTATEST_SHIFT 0
+#define OMAP24XX_POWERSTATEST_MASK (0x3 << 0)
+
+
+/* Bits specific to each register */
+
+/* PRCM_REVISION */
+#define OMAP24XX_REV_SHIFT 0
+#define OMAP24XX_REV_MASK (0xff << 0)
+
+/* PRCM_SYSCONFIG */
+#define OMAP24XX_AUTOIDLE_MASK (1 << 0)
+
+/* PRCM_IRQSTATUS_MPU specific bits */
+#define OMAP2430_DPLL_RECAL_ST_MASK (1 << 6)
+#define OMAP24XX_TRANSITION_ST_MASK (1 << 5)
+#define OMAP24XX_EVGENOFF_ST_MASK (1 << 4)
+#define OMAP24XX_EVGENON_ST_MASK (1 << 3)
+
+/* PRCM_IRQENABLE_MPU specific bits */
+#define OMAP2430_DPLL_RECAL_EN_MASK (1 << 6)
+#define OMAP24XX_TRANSITION_EN_MASK (1 << 5)
+#define OMAP24XX_EVGENOFF_EN_MASK (1 << 4)
+#define OMAP24XX_EVGENON_EN_MASK (1 << 3)
+
+/* PRCM_VOLTCTRL */
+#define OMAP24XX_AUTO_EXTVOLT_MASK (1 << 15)
+#define OMAP24XX_FORCE_EXTVOLT_MASK (1 << 14)
+#define OMAP24XX_SETOFF_LEVEL_SHIFT 12
+#define OMAP24XX_SETOFF_LEVEL_MASK (0x3 << 12)
+#define OMAP24XX_MEMRETCTRL_MASK (1 << 8)
+#define OMAP24XX_SETRET_LEVEL_SHIFT 6
+#define OMAP24XX_SETRET_LEVEL_MASK (0x3 << 6)
+#define OMAP24XX_VOLT_LEVEL_SHIFT 0
+#define OMAP24XX_VOLT_LEVEL_MASK (0x3 << 0)
+
+/* PRCM_VOLTST */
+#define OMAP24XX_ST_VOLTLEVEL_SHIFT 0
+#define OMAP24XX_ST_VOLTLEVEL_MASK (0x3 << 0)
+
+/* PRCM_CLKSRC_CTRL specific bits */
+
+/* PRCM_CLKOUT_CTRL */
+#define OMAP2420_CLKOUT2_EN_SHIFT 15
+#define OMAP2420_CLKOUT2_EN_MASK (1 << 15)
+#define OMAP2420_CLKOUT2_DIV_SHIFT 11
+#define OMAP2420_CLKOUT2_DIV_MASK (0x7 << 11)
+#define OMAP2420_CLKOUT2_SOURCE_SHIFT 8
+#define OMAP2420_CLKOUT2_SOURCE_MASK (0x3 << 8)
+#define OMAP24XX_CLKOUT_EN_SHIFT 7
+#define OMAP24XX_CLKOUT_EN_MASK (1 << 7)
+#define OMAP24XX_CLKOUT_DIV_SHIFT 3
+#define OMAP24XX_CLKOUT_DIV_MASK (0x7 << 3)
+#define OMAP24XX_CLKOUT_SOURCE_SHIFT 0
+#define OMAP24XX_CLKOUT_SOURCE_MASK (0x3 << 0)
+
+/* PRCM_CLKEMUL_CTRL */
+#define OMAP24XX_EMULATION_EN_SHIFT 0
+#define OMAP24XX_EMULATION_EN_MASK (1 << 0)
+
+/* PRCM_CLKCFG_CTRL */
+#define OMAP24XX_VALID_CONFIG_MASK (1 << 0)
+
+/* PRCM_CLKCFG_STATUS */
+#define OMAP24XX_CONFIG_STATUS_MASK (1 << 0)
+
+/* PRCM_VOLTSETUP specific bits */
+
+/* PRCM_CLKSSETUP specific bits */
+
+/* PRCM_POLCTRL */
+#define OMAP2420_CLKOUT2_POL_MASK (1 << 10)
+#define OMAP24XX_CLKOUT_POL_MASK (1 << 9)
+#define OMAP24XX_CLKREQ_POL_MASK (1 << 8)
+#define OMAP2430_USE_POWEROK_MASK (1 << 2)
+#define OMAP2430_POWEROK_POL_MASK (1 << 1)
+#define OMAP24XX_EXTVOL_POL_MASK (1 << 0)
+
+/* RM_RSTST_MPU specific bits */
+/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */
+
+/* PM_WKDEP_MPU specific bits */
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK (1 << 5)
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK (1 << 2)
+
+/* PM_EVGENCTRL_MPU specific bits */
+
+/* PM_EVEGENONTIM_MPU specific bits */
+
+/* PM_EVEGENOFFTIM_MPU specific bits */
+
+/* PM_PWSTCTRL_MPU specific bits */
+#define OMAP2430_FORCESTATE_MASK (1 << 18)
+
+/* PM_PWSTST_MPU specific bits */
+/* INTRANSITION, CLKACTIVITY, POWERSTATE, MEMSTATEST are 2430 only */
+
+/* PM_WKEN1_CORE specific bits */
+
+/* PM_WKEN2_CORE specific bits */
+
+/* PM_WKST1_CORE specific bits*/
+
+/* PM_WKST2_CORE specific bits */
+
+/* PM_WKDEP_CORE specific bits*/
+#define OMAP2430_PM_WKDEP_CORE_EN_MDM_MASK (1 << 5)
+#define OMAP24XX_PM_WKDEP_CORE_EN_GFX_MASK (1 << 3)
+#define OMAP24XX_PM_WKDEP_CORE_EN_DSP_MASK (1 << 2)
+
+/* PM_PWSTCTRL_CORE specific bits */
+#define OMAP24XX_MEMORYCHANGE_MASK (1 << 20)
+#define OMAP24XX_MEM3ONSTATE_SHIFT 14
+#define OMAP24XX_MEM3ONSTATE_MASK (0x3 << 14)
+#define OMAP24XX_MEM2ONSTATE_SHIFT 12
+#define OMAP24XX_MEM2ONSTATE_MASK (0x3 << 12)
+#define OMAP24XX_MEM1ONSTATE_SHIFT 10
+#define OMAP24XX_MEM1ONSTATE_MASK (0x3 << 10)
+#define OMAP24XX_MEM3RETSTATE_MASK (1 << 5)
+#define OMAP24XX_MEM2RETSTATE_MASK (1 << 4)
+#define OMAP24XX_MEM1RETSTATE_MASK (1 << 3)
+
+/* PM_PWSTST_CORE specific bits */
+#define OMAP24XX_MEM3STATEST_SHIFT 14
+#define OMAP24XX_MEM3STATEST_MASK (0x3 << 14)
+#define OMAP24XX_MEM2STATEST_SHIFT 12
+#define OMAP24XX_MEM2STATEST_MASK (0x3 << 12)
+#define OMAP24XX_MEM1STATEST_SHIFT 10
+#define OMAP24XX_MEM1STATEST_MASK (0x3 << 10)
+
+/* RM_RSTCTRL_GFX */
+#define OMAP24XX_GFX_RST_MASK (1 << 0)
+
+/* RM_RSTST_GFX specific bits */
+#define OMAP24XX_GFX_SW_RST_MASK (1 << 4)
+
+/* PM_PWSTCTRL_GFX specific bits */
+
+/* PM_WKDEP_GFX specific bits */
+/* 2430 often calls EN_WAKEUP "EN_WKUP" */
+
+/* RM_RSTCTRL_WKUP specific bits */
+
+/* RM_RSTTIME_WKUP specific bits */
+
+/* RM_RSTST_WKUP specific bits */
+/* 2430 calls EXTWMPU_RST "EXTWARM_RST" and GLOBALWMPU_RST "GLOBALWARM_RST" */
+#define OMAP24XX_EXTWMPU_RST_MASK (1 << 6)
+#define OMAP24XX_SECU_WD_RST_MASK (1 << 5)
+#define OMAP24XX_MPU_WD_RST_MASK (1 << 4)
+#define OMAP24XX_SECU_VIOL_RST_MASK (1 << 3)
+
+/* PM_WKEN_WKUP specific bits */
+
+/* PM_WKST_WKUP specific bits */
+
+/* RM_RSTCTRL_DSP */
+#define OMAP2420_RST_IVA_MASK (1 << 8)
+#define OMAP24XX_RST2_DSP_MASK (1 << 1)
+#define OMAP24XX_RST1_DSP_MASK (1 << 0)
+
+/* RM_RSTST_DSP specific bits */
+/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" */
+#define OMAP2420_IVA_SW_RST_MASK (1 << 8)
+#define OMAP24XX_DSP_SW_RST2_MASK (1 << 5)
+#define OMAP24XX_DSP_SW_RST1_MASK (1 << 4)
+
+/* PM_WKDEP_DSP specific bits */
+
+/* PM_PWSTCTRL_DSP specific bits */
+/* 2430 only: MEMONSTATE, MEMRETSTATE */
+#define OMAP2420_MEMIONSTATE_SHIFT 12
+#define OMAP2420_MEMIONSTATE_MASK (0x3 << 12)
+#define OMAP2420_MEMIRETSTATE_MASK (1 << 4)
+
+/* PM_PWSTST_DSP specific bits */
+/* MEMSTATEST is 2430 only */
+#define OMAP2420_MEMISTATEST_SHIFT 12
+#define OMAP2420_MEMISTATEST_MASK (0x3 << 12)
+
+/* PRCM_IRQSTATUS_DSP specific bits */
+
+/* PRCM_IRQENABLE_DSP specific bits */
+
+/* RM_RSTCTRL_MDM */
+/* 2430 only */
+#define OMAP2430_PWRON1_MDM_MASK (1 << 1)
+#define OMAP2430_RST1_MDM_MASK (1 << 0)
+
+/* RM_RSTST_MDM specific bits */
+/* 2430 only */
+#define OMAP2430_MDM_SECU_VIOL_MASK (1 << 6)
+#define OMAP2430_MDM_SW_PWRON1_MASK (1 << 5)
+#define OMAP2430_MDM_SW_RST1_MASK (1 << 4)
+
+/* PM_WKEN_MDM */
+/* 2430 only */
+#define OMAP2430_PM_WKEN_MDM_EN_MDM_MASK (1 << 0)
+
+/* PM_WKST_MDM specific bits */
+/* 2430 only */
+
+/* PM_WKDEP_MDM specific bits */
+/* 2430 only */
+
+/* PM_PWSTCTRL_MDM specific bits */
+/* 2430 only */
+#define OMAP2430_KILLDOMAINWKUP_MASK (1 << 19)
+
+/* PM_PWSTST_MDM specific bits */
+/* 2430 only */
+
+/* PRCM_IRQSTATUS_IVA */
+/* 2420 only */
+
+/* PRCM_IRQENABLE_IVA */
+/* 2420 only */
+
+#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
new file mode 100644
index 00000000..64c087af
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -0,0 +1,600 @@
+/*
+ * OMAP3430 Power/Reset Management register bits
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_34XX_H
+
+
+#include "prm2xxx_3xxx.h"
+
+/* Shared register bits */
+
+/* PRM_VC_CMD_VAL_0, PRM_VC_CMD_VAL_1 shared bits */
+#define OMAP3430_ON_SHIFT 24
+#define OMAP3430_ON_MASK (0xff << 24)
+#define OMAP3430_ONLP_SHIFT 16
+#define OMAP3430_ONLP_MASK (0xff << 16)
+#define OMAP3430_RET_SHIFT 8
+#define OMAP3430_RET_MASK (0xff << 8)
+#define OMAP3430_OFF_SHIFT 0
+#define OMAP3430_OFF_MASK (0xff << 0)
+
+/* PRM_VP1_CONFIG, PRM_VP2_CONFIG shared bits */
+#define OMAP3430_ERROROFFSET_SHIFT 24
+#define OMAP3430_ERROROFFSET_MASK (0xff << 24)
+#define OMAP3430_ERRORGAIN_SHIFT 16
+#define OMAP3430_ERRORGAIN_MASK (0xff << 16)
+#define OMAP3430_INITVOLTAGE_SHIFT 8
+#define OMAP3430_INITVOLTAGE_MASK (0xff << 8)
+#define OMAP3430_TIMEOUTEN_MASK (1 << 3)
+#define OMAP3430_INITVDD_MASK (1 << 2)
+#define OMAP3430_FORCEUPDATE_MASK (1 << 1)
+#define OMAP3430_VPENABLE_MASK (1 << 0)
+
+/* PRM_VP1_VSTEPMIN, PRM_VP2_VSTEPMIN shared bits */
+#define OMAP3430_SMPSWAITTIMEMIN_SHIFT 8
+#define OMAP3430_SMPSWAITTIMEMIN_MASK (0xffff << 8)
+#define OMAP3430_VSTEPMIN_SHIFT 0
+#define OMAP3430_VSTEPMIN_MASK (0xff << 0)
+
+/* PRM_VP1_VSTEPMAX, PRM_VP2_VSTEPMAX shared bits */
+#define OMAP3430_SMPSWAITTIMEMAX_SHIFT 8
+#define OMAP3430_SMPSWAITTIMEMAX_MASK (0xffff << 8)
+#define OMAP3430_VSTEPMAX_SHIFT 0
+#define OMAP3430_VSTEPMAX_MASK (0xff << 0)
+
+/* PRM_VP1_VLIMITTO, PRM_VP2_VLIMITTO shared bits */
+#define OMAP3430_VDDMAX_SHIFT 24
+#define OMAP3430_VDDMAX_MASK (0xff << 24)
+#define OMAP3430_VDDMIN_SHIFT 16
+#define OMAP3430_VDDMIN_MASK (0xff << 16)
+#define OMAP3430_TIMEOUT_SHIFT 0
+#define OMAP3430_TIMEOUT_MASK (0xffff << 0)
+
+/* PRM_VP1_VOLTAGE, PRM_VP2_VOLTAGE shared bits */
+#define OMAP3430_VPVOLTAGE_SHIFT 0
+#define OMAP3430_VPVOLTAGE_MASK (0xff << 0)
+
+/* PRM_VP1_STATUS, PRM_VP2_STATUS shared bits */
+#define OMAP3430_VPINIDLE_MASK (1 << 0)
+
+/* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */
+#define OMAP3430_EN_PER_SHIFT 7
+#define OMAP3430_EN_PER_MASK (1 << 7)
+
+/* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */
+#define OMAP3430_MEMORYCHANGE_MASK (1 << 3)
+
+/* PM_PWSTST_IVA2, PM_PWSTST_CORE shared bits */
+#define OMAP3430_LOGICSTATEST_MASK (1 << 2)
+
+/* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */
+#define OMAP3430_LASTLOGICSTATEENTERED_MASK (1 << 2)
+
+/*
+ * PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE,
+ * PM_PREPWSTST_GFX, PM_PREPWSTST_DSS, PM_PREPWSTST_CAM,
+ * PM_PREPWSTST_PER, PM_PREPWSTST_NEON shared bits
+ */
+#define OMAP3430_LASTPOWERSTATEENTERED_SHIFT 0
+#define OMAP3430_LASTPOWERSTATEENTERED_MASK (0x3 << 0)
+
+/* PRM_IRQSTATUS_IVA2, PRM_IRQSTATUS_MPU shared bits */
+#define OMAP3430_WKUP_ST_MASK (1 << 0)
+
+/* PRM_IRQENABLE_IVA2, PRM_IRQENABLE_MPU shared bits */
+#define OMAP3430_WKUP_EN_MASK (1 << 0)
+
+/* PM_MPUGRPSEL1_CORE, PM_IVA2GRPSEL1_CORE shared bits */
+#define OMAP3430_GRPSEL_MMC2_MASK (1 << 25)
+#define OMAP3430_GRPSEL_MMC1_MASK (1 << 24)
+#define OMAP3430_GRPSEL_MCSPI4_MASK (1 << 21)
+#define OMAP3430_GRPSEL_MCSPI3_MASK (1 << 20)
+#define OMAP3430_GRPSEL_MCSPI2_MASK (1 << 19)
+#define OMAP3430_GRPSEL_MCSPI1_MASK (1 << 18)
+#define OMAP3430_GRPSEL_I2C3_SHIFT 17
+#define OMAP3430_GRPSEL_I2C3_MASK (1 << 17)
+#define OMAP3430_GRPSEL_I2C2_SHIFT 16
+#define OMAP3430_GRPSEL_I2C2_MASK (1 << 16)
+#define OMAP3430_GRPSEL_I2C1_SHIFT 15
+#define OMAP3430_GRPSEL_I2C1_MASK (1 << 15)
+#define OMAP3430_GRPSEL_UART2_MASK (1 << 14)
+#define OMAP3430_GRPSEL_UART1_MASK (1 << 13)
+#define OMAP3430_GRPSEL_GPT11_MASK (1 << 12)
+#define OMAP3430_GRPSEL_GPT10_MASK (1 << 11)
+#define OMAP3430_GRPSEL_MCBSP5_MASK (1 << 10)
+#define OMAP3430_GRPSEL_MCBSP1_MASK (1 << 9)
+#define OMAP3430_GRPSEL_HSOTGUSB_MASK (1 << 4)
+#define OMAP3430_GRPSEL_D2D_MASK (1 << 3)
+
+/*
+ * PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM,
+ * PM_PWSTCTRL_PER shared bits
+ */
+#define OMAP3430_MEMONSTATE_SHIFT 16
+#define OMAP3430_MEMONSTATE_MASK (0x3 << 16)
+#define OMAP3430_MEMRETSTATE_MASK (1 << 8)
+
+/* PM_MPUGRPSEL_PER, PM_IVA2GRPSEL_PER shared bits */
+#define OMAP3630_GRPSEL_UART4_MASK (1 << 18)
+#define OMAP3430_GRPSEL_GPIO6_MASK (1 << 17)
+#define OMAP3430_GRPSEL_GPIO5_MASK (1 << 16)
+#define OMAP3430_GRPSEL_GPIO4_MASK (1 << 15)
+#define OMAP3430_GRPSEL_GPIO3_MASK (1 << 14)
+#define OMAP3430_GRPSEL_GPIO2_MASK (1 << 13)
+#define OMAP3430_GRPSEL_UART3_MASK (1 << 11)
+#define OMAP3430_GRPSEL_GPT9_MASK (1 << 10)
+#define OMAP3430_GRPSEL_GPT8_MASK (1 << 9)
+#define OMAP3430_GRPSEL_GPT7_MASK (1 << 8)
+#define OMAP3430_GRPSEL_GPT6_MASK (1 << 7)
+#define OMAP3430_GRPSEL_GPT5_MASK (1 << 6)
+#define OMAP3430_GRPSEL_GPT4_MASK (1 << 5)
+#define OMAP3430_GRPSEL_GPT3_MASK (1 << 4)
+#define OMAP3430_GRPSEL_GPT2_MASK (1 << 3)
+#define OMAP3430_GRPSEL_MCBSP4_MASK (1 << 2)
+#define OMAP3430_GRPSEL_MCBSP3_MASK (1 << 1)
+#define OMAP3430_GRPSEL_MCBSP2_MASK (1 << 0)
+
+/* PM_MPUGRPSEL_WKUP, PM_IVA2GRPSEL_WKUP shared bits */
+#define OMAP3430_GRPSEL_IO_MASK (1 << 8)
+#define OMAP3430_GRPSEL_SR2_MASK (1 << 7)
+#define OMAP3430_GRPSEL_SR1_MASK (1 << 6)
+#define OMAP3430_GRPSEL_GPIO1_MASK (1 << 3)
+#define OMAP3430_GRPSEL_GPT12_MASK (1 << 1)
+#define OMAP3430_GRPSEL_GPT1_MASK (1 << 0)
+
+/* Bits specific to each register */
+
+/* RM_RSTCTRL_IVA2 */
+#define OMAP3430_RST3_IVA2_MASK (1 << 2)
+#define OMAP3430_RST2_IVA2_MASK (1 << 1)
+#define OMAP3430_RST1_IVA2_MASK (1 << 0)
+
+/* RM_RSTST_IVA2 specific bits */
+#define OMAP3430_EMULATION_VSEQ_RST_MASK (1 << 13)
+#define OMAP3430_EMULATION_VHWA_RST_MASK (1 << 12)
+#define OMAP3430_EMULATION_IVA2_RST_MASK (1 << 11)
+#define OMAP3430_IVA2_SW_RST3_MASK (1 << 10)
+#define OMAP3430_IVA2_SW_RST2_MASK (1 << 9)
+#define OMAP3430_IVA2_SW_RST1_MASK (1 << 8)
+
+/* PM_WKDEP_IVA2 specific bits */
+
+/* PM_PWSTCTRL_IVA2 specific bits */
+#define OMAP3430_L2FLATMEMONSTATE_SHIFT 22
+#define OMAP3430_L2FLATMEMONSTATE_MASK (0x3 << 22)
+#define OMAP3430_SHAREDL2CACHEFLATONSTATE_SHIFT 20
+#define OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK (0x3 << 20)
+#define OMAP3430_L1FLATMEMONSTATE_SHIFT 18
+#define OMAP3430_L1FLATMEMONSTATE_MASK (0x3 << 18)
+#define OMAP3430_SHAREDL1CACHEFLATONSTATE_SHIFT 16
+#define OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK (0x3 << 16)
+#define OMAP3430_L2FLATMEMRETSTATE_MASK (1 << 11)
+#define OMAP3430_SHAREDL2CACHEFLATRETSTATE_MASK (1 << 10)
+#define OMAP3430_L1FLATMEMRETSTATE_MASK (1 << 9)
+#define OMAP3430_SHAREDL1CACHEFLATRETSTATE_MASK (1 << 8)
+
+/* PM_PWSTST_IVA2 specific bits */
+#define OMAP3430_L2FLATMEMSTATEST_SHIFT 10
+#define OMAP3430_L2FLATMEMSTATEST_MASK (0x3 << 10)
+#define OMAP3430_SHAREDL2CACHEFLATSTATEST_SHIFT 8
+#define OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK (0x3 << 8)
+#define OMAP3430_L1FLATMEMSTATEST_SHIFT 6
+#define OMAP3430_L1FLATMEMSTATEST_MASK (0x3 << 6)
+#define OMAP3430_SHAREDL1CACHEFLATSTATEST_SHIFT 4
+#define OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK (0x3 << 4)
+
+/* PM_PREPWSTST_IVA2 specific bits */
+#define OMAP3430_LASTL2FLATMEMSTATEENTERED_SHIFT 10
+#define OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK (0x3 << 10)
+#define OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_SHIFT 8
+#define OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK (0x3 << 8)
+#define OMAP3430_LASTL1FLATMEMSTATEENTERED_SHIFT 6
+#define OMAP3430_LASTL1FLATMEMSTATEENTERED_MASK (0x3 << 6)
+#define OMAP3430_LASTSHAREDL1CACHEFLATSTATEENTERED_SHIFT 4
+#define OMAP3430_LASTSHAREDL1CACHEFLATSTATEENTERED_MASK (0x3 << 4)
+
+/* PRM_IRQSTATUS_IVA2 specific bits */
+#define OMAP3430_PRM_IRQSTATUS_IVA2_IVA2_DPLL_ST_MASK (1 << 2)
+#define OMAP3430_FORCEWKUP_ST_MASK (1 << 1)
+
+/* PRM_IRQENABLE_IVA2 specific bits */
+#define OMAP3430_PRM_IRQENABLE_IVA2_IVA2_DPLL_RECAL_EN_MASK (1 << 2)
+#define OMAP3430_FORCEWKUP_EN_MASK (1 << 1)
+
+/* PRM_REVISION specific bits */
+
+/* PRM_SYSCONFIG specific bits */
+
+/* PRM_IRQSTATUS_MPU specific bits */
+#define OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT 25
+#define OMAP3430ES2_SND_PERIPH_DPLL_ST_MASK (1 << 25)
+#define OMAP3430_VC_TIMEOUTERR_ST_MASK (1 << 24)
+#define OMAP3430_VC_RAERR_ST_MASK (1 << 23)
+#define OMAP3430_VC_SAERR_ST_MASK (1 << 22)
+#define OMAP3430_VP2_TRANXDONE_ST_MASK (1 << 21)
+#define OMAP3430_VP2_EQVALUE_ST_MASK (1 << 20)
+#define OMAP3430_VP2_NOSMPSACK_ST_MASK (1 << 19)
+#define OMAP3430_VP2_MAXVDD_ST_MASK (1 << 18)
+#define OMAP3430_VP2_MINVDD_ST_MASK (1 << 17)
+#define OMAP3430_VP2_OPPCHANGEDONE_ST_MASK (1 << 16)
+#define OMAP3430_VP1_TRANXDONE_ST_MASK (1 << 15)
+#define OMAP3430_VP1_EQVALUE_ST_MASK (1 << 14)
+#define OMAP3430_VP1_NOSMPSACK_ST_MASK (1 << 13)
+#define OMAP3430_VP1_MAXVDD_ST_MASK (1 << 12)
+#define OMAP3430_VP1_MINVDD_ST_MASK (1 << 11)
+#define OMAP3430_VP1_OPPCHANGEDONE_ST_MASK (1 << 10)
+#define OMAP3430_IO_ST_MASK (1 << 9)
+#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_MASK (1 << 8)
+#define OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT 8
+#define OMAP3430_MPU_DPLL_ST_MASK (1 << 7)
+#define OMAP3430_MPU_DPLL_ST_SHIFT 7
+#define OMAP3430_PERIPH_DPLL_ST_MASK (1 << 6)
+#define OMAP3430_PERIPH_DPLL_ST_SHIFT 6
+#define OMAP3430_CORE_DPLL_ST_MASK (1 << 5)
+#define OMAP3430_CORE_DPLL_ST_SHIFT 5
+#define OMAP3430_TRANSITION_ST_MASK (1 << 4)
+#define OMAP3430_EVGENOFF_ST_MASK (1 << 3)
+#define OMAP3430_EVGENON_ST_MASK (1 << 2)
+#define OMAP3430_FS_USB_WKUP_ST_MASK (1 << 1)
+
+/* PRM_IRQENABLE_MPU specific bits */
+#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT 25
+#define OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_MASK (1 << 25)
+#define OMAP3430_VC_TIMEOUTERR_EN_MASK (1 << 24)
+#define OMAP3430_VC_RAERR_EN_MASK (1 << 23)
+#define OMAP3430_VC_SAERR_EN_MASK (1 << 22)
+#define OMAP3430_VP2_TRANXDONE_EN_MASK (1 << 21)
+#define OMAP3430_VP2_EQVALUE_EN_MASK (1 << 20)
+#define OMAP3430_VP2_NOSMPSACK_EN_MASK (1 << 19)
+#define OMAP3430_VP2_MAXVDD_EN_MASK (1 << 18)
+#define OMAP3430_VP2_MINVDD_EN_MASK (1 << 17)
+#define OMAP3430_VP2_OPPCHANGEDONE_EN_MASK (1 << 16)
+#define OMAP3430_VP1_TRANXDONE_EN_MASK (1 << 15)
+#define OMAP3430_VP1_EQVALUE_EN_MASK (1 << 14)
+#define OMAP3430_VP1_NOSMPSACK_EN_MASK (1 << 13)
+#define OMAP3430_VP1_MAXVDD_EN_MASK (1 << 12)
+#define OMAP3430_VP1_MINVDD_EN_MASK (1 << 11)
+#define OMAP3430_VP1_OPPCHANGEDONE_EN_MASK (1 << 10)
+#define OMAP3430_IO_EN_MASK (1 << 9)
+#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_MASK (1 << 8)
+#define OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT 8
+#define OMAP3430_MPU_DPLL_RECAL_EN_MASK (1 << 7)
+#define OMAP3430_MPU_DPLL_RECAL_EN_SHIFT 7
+#define OMAP3430_PERIPH_DPLL_RECAL_EN_MASK (1 << 6)
+#define OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT 6
+#define OMAP3430_CORE_DPLL_RECAL_EN_MASK (1 << 5)
+#define OMAP3430_CORE_DPLL_RECAL_EN_SHIFT 5
+#define OMAP3430_TRANSITION_EN_MASK (1 << 4)
+#define OMAP3430_EVGENOFF_EN_MASK (1 << 3)
+#define OMAP3430_EVGENON_EN_MASK (1 << 2)
+#define OMAP3430_FS_USB_WKUP_EN_MASK (1 << 1)
+
+/* RM_RSTST_MPU specific bits */
+#define OMAP3430_EMULATION_MPU_RST_MASK (1 << 11)
+
+/* PM_WKDEP_MPU specific bits */
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5)
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2)
+
+/* PM_EVGENCTRL_MPU */
+#define OMAP3430_OFFLOADMODE_SHIFT 3
+#define OMAP3430_OFFLOADMODE_MASK (0x3 << 3)
+#define OMAP3430_ONLOADMODE_SHIFT 1
+#define OMAP3430_ONLOADMODE_MASK (0x3 << 1)
+#define OMAP3430_ENABLE_MASK (1 << 0)
+
+/* PM_EVGENONTIM_MPU */
+#define OMAP3430_ONTIMEVAL_SHIFT 0
+#define OMAP3430_ONTIMEVAL_MASK (0xffffffff << 0)
+
+/* PM_EVGENOFFTIM_MPU */
+#define OMAP3430_OFFTIMEVAL_SHIFT 0
+#define OMAP3430_OFFTIMEVAL_MASK (0xffffffff << 0)
+
+/* PM_PWSTCTRL_MPU specific bits */
+#define OMAP3430_L2CACHEONSTATE_SHIFT 16
+#define OMAP3430_L2CACHEONSTATE_MASK (0x3 << 16)
+#define OMAP3430_L2CACHERETSTATE_MASK (1 << 8)
+#define OMAP3430_LOGICL1CACHERETSTATE_MASK (1 << 2)
+
+/* PM_PWSTST_MPU specific bits */
+#define OMAP3430_L2CACHESTATEST_SHIFT 6
+#define OMAP3430_L2CACHESTATEST_MASK (0x3 << 6)
+#define OMAP3430_LOGICL1CACHESTATEST_MASK (1 << 2)
+
+/* PM_PREPWSTST_MPU specific bits */
+#define OMAP3430_LASTL2CACHESTATEENTERED_SHIFT 6
+#define OMAP3430_LASTL2CACHESTATEENTERED_MASK (0x3 << 6)
+#define OMAP3430_LASTLOGICL1CACHESTATEENTERED_MASK (1 << 2)
+
+/* RM_RSTCTRL_CORE */
+#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK (1 << 1)
+#define OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK (1 << 0)
+
+/* RM_RSTST_CORE specific bits */
+#define OMAP3430_MODEM_SECURITY_VIOL_RST_MASK (1 << 10)
+#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RSTPWRON_MASK (1 << 9)
+#define OMAP3430_RM_RSTST_CORE_MODEM_SW_RST_MASK (1 << 8)
+
+/* PM_WKEN1_CORE specific bits */
+
+/* PM_MPUGRPSEL1_CORE specific bits */
+#define OMAP3430_GRPSEL_FSHOSTUSB_MASK (1 << 5)
+
+/* PM_IVA2GRPSEL1_CORE specific bits */
+
+/* PM_WKST1_CORE specific bits */
+
+/* PM_PWSTCTRL_CORE specific bits */
+#define OMAP3430_MEM2ONSTATE_SHIFT 18
+#define OMAP3430_MEM2ONSTATE_MASK (0x3 << 18)
+#define OMAP3430_MEM1ONSTATE_SHIFT 16
+#define OMAP3430_MEM1ONSTATE_MASK (0x3 << 16)
+#define OMAP3430_MEM2RETSTATE_MASK (1 << 9)
+#define OMAP3430_MEM1RETSTATE_MASK (1 << 8)
+
+/* PM_PWSTST_CORE specific bits */
+#define OMAP3430_MEM2STATEST_SHIFT 6
+#define OMAP3430_MEM2STATEST_MASK (0x3 << 6)
+#define OMAP3430_MEM1STATEST_SHIFT 4
+#define OMAP3430_MEM1STATEST_MASK (0x3 << 4)
+
+/* PM_PREPWSTST_CORE specific bits */
+#define OMAP3430_LASTMEM2STATEENTERED_SHIFT 6
+#define OMAP3430_LASTMEM2STATEENTERED_MASK (0x3 << 6)
+#define OMAP3430_LASTMEM1STATEENTERED_SHIFT 4
+#define OMAP3430_LASTMEM1STATEENTERED_MASK (0x3 << 4)
+
+/* RM_RSTST_GFX specific bits */
+
+/* PM_WKDEP_GFX specific bits */
+#define OMAP3430_PM_WKDEP_GFX_EN_IVA2_MASK (1 << 2)
+
+/* PM_PWSTCTRL_GFX specific bits */
+
+/* PM_PWSTST_GFX specific bits */
+
+/* PM_PREPWSTST_GFX specific bits */
+
+/* PM_WKEN_WKUP specific bits */
+#define OMAP3430_EN_IO_CHAIN_MASK (1 << 16)
+#define OMAP3430_EN_IO_MASK (1 << 8)
+#define OMAP3430_EN_GPIO1_MASK (1 << 3)
+
+/* PM_MPUGRPSEL_WKUP specific bits */
+
+/* PM_IVA2GRPSEL_WKUP specific bits */
+
+/* PM_WKST_WKUP specific bits */
+#define OMAP3430_ST_IO_CHAIN_MASK (1 << 16)
+#define OMAP3430_ST_IO_MASK (1 << 8)
+
+/* PRM_CLKSEL */
+#define OMAP3430_SYS_CLKIN_SEL_SHIFT 0
+#define OMAP3430_SYS_CLKIN_SEL_MASK (0x7 << 0)
+
+/* PRM_CLKOUT_CTRL */
+#define OMAP3430_CLKOUT_EN_MASK (1 << 7)
+#define OMAP3430_CLKOUT_EN_SHIFT 7
+
+/* RM_RSTST_DSS specific bits */
+
+/* PM_WKEN_DSS */
+#define OMAP3430_PM_WKEN_DSS_EN_DSS_MASK (1 << 0)
+
+/* PM_WKDEP_DSS specific bits */
+#define OMAP3430_PM_WKDEP_DSS_EN_IVA2_MASK (1 << 2)
+
+/* PM_PWSTCTRL_DSS specific bits */
+
+/* PM_PWSTST_DSS specific bits */
+
+/* PM_PREPWSTST_DSS specific bits */
+
+/* RM_RSTST_CAM specific bits */
+
+/* PM_WKDEP_CAM specific bits */
+#define OMAP3430_PM_WKDEP_CAM_EN_IVA2_MASK (1 << 2)
+
+/* PM_PWSTCTRL_CAM specific bits */
+
+/* PM_PWSTST_CAM specific bits */
+
+/* PM_PREPWSTST_CAM specific bits */
+
+/* PM_PWSTCTRL_USBHOST specific bits */
+#define OMAP3430ES2_SAVEANDRESTORE_SHIFT 4
+
+/* RM_RSTST_PER specific bits */
+
+/* PM_WKEN_PER specific bits */
+
+/* PM_MPUGRPSEL_PER specific bits */
+
+/* PM_IVA2GRPSEL_PER specific bits */
+
+/* PM_WKST_PER specific bits */
+
+/* PM_WKDEP_PER specific bits */
+#define OMAP3430_PM_WKDEP_PER_EN_IVA2_MASK (1 << 2)
+
+/* PM_PWSTCTRL_PER specific bits */
+
+/* PM_PWSTST_PER specific bits */
+
+/* PM_PREPWSTST_PER specific bits */
+
+/* RM_RSTST_EMU specific bits */
+
+/* PM_PWSTST_EMU specific bits */
+
+/* PRM_VC_SMPS_SA */
+#define OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT 16
+#define OMAP3430_PRM_VC_SMPS_SA_SA1_MASK (0x7f << 16)
+#define OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT 0
+#define OMAP3430_PRM_VC_SMPS_SA_SA0_MASK (0x7f << 0)
+
+/* PRM_VC_SMPS_VOL_RA */
+#define OMAP3430_VOLRA1_SHIFT 16
+#define OMAP3430_VOLRA1_MASK (0xff << 16)
+#define OMAP3430_VOLRA0_SHIFT 0
+#define OMAP3430_VOLRA0_MASK (0xff << 0)
+
+/* PRM_VC_SMPS_CMD_RA */
+#define OMAP3430_CMDRA1_SHIFT 16
+#define OMAP3430_CMDRA1_MASK (0xff << 16)
+#define OMAP3430_CMDRA0_SHIFT 0
+#define OMAP3430_CMDRA0_MASK (0xff << 0)
+
+/* PRM_VC_CMD_VAL_0 specific bits */
+#define OMAP3430_VC_CMD_ON_SHIFT 24
+#define OMAP3430_VC_CMD_ON_MASK (0xFF << 24)
+#define OMAP3430_VC_CMD_ONLP_SHIFT 16
+#define OMAP3430_VC_CMD_ONLP_MASK (0xFF << 16)
+#define OMAP3430_VC_CMD_RET_SHIFT 8
+#define OMAP3430_VC_CMD_RET_MASK (0xFF << 8)
+#define OMAP3430_VC_CMD_OFF_SHIFT 0
+#define OMAP3430_VC_CMD_OFF_MASK (0xFF << 0)
+
+/* PRM_VC_CMD_VAL_1 specific bits */
+
+/* PRM_VC_CH_CONF */
+#define OMAP3430_CMD1_MASK (1 << 20)
+#define OMAP3430_RACEN1_MASK (1 << 19)
+#define OMAP3430_RAC1_MASK (1 << 18)
+#define OMAP3430_RAV1_MASK (1 << 17)
+#define OMAP3430_PRM_VC_CH_CONF_SA1_MASK (1 << 16)
+#define OMAP3430_CMD0_MASK (1 << 4)
+#define OMAP3430_RACEN0_MASK (1 << 3)
+#define OMAP3430_RAC0_MASK (1 << 2)
+#define OMAP3430_RAV0_MASK (1 << 1)
+#define OMAP3430_PRM_VC_CH_CONF_SA0_MASK (1 << 0)
+
+/* PRM_VC_I2C_CFG */
+#define OMAP3430_HSMASTER_MASK (1 << 5)
+#define OMAP3430_SREN_MASK (1 << 4)
+#define OMAP3430_HSEN_MASK (1 << 3)
+#define OMAP3430_MCODE_SHIFT 0
+#define OMAP3430_MCODE_MASK (0x7 << 0)
+
+/* PRM_VC_BYPASS_VAL */
+#define OMAP3430_VALID_MASK (1 << 24)
+#define OMAP3430_DATA_SHIFT 16
+#define OMAP3430_DATA_MASK (0xff << 16)
+#define OMAP3430_REGADDR_SHIFT 8
+#define OMAP3430_REGADDR_MASK (0xff << 8)
+#define OMAP3430_SLAVEADDR_SHIFT 0
+#define OMAP3430_SLAVEADDR_MASK (0x7f << 0)
+
+/* PRM_RSTCTRL */
+#define OMAP3430_RST_DPLL3_MASK (1 << 2)
+#define OMAP3430_RST_GS_MASK (1 << 1)
+
+/* PRM_RSTTIME */
+#define OMAP3430_RSTTIME2_SHIFT 8
+#define OMAP3430_RSTTIME2_MASK (0x1f << 8)
+#define OMAP3430_RSTTIME1_SHIFT 0
+#define OMAP3430_RSTTIME1_MASK (0xff << 0)
+
+/* PRM_RSTST */
+#define OMAP3430_ICECRUSHER_RST_MASK (1 << 10)
+#define OMAP3430_ICEPICK_RST_MASK (1 << 9)
+#define OMAP3430_VDD2_VOLTAGE_MANAGER_RST_MASK (1 << 8)
+#define OMAP3430_VDD1_VOLTAGE_MANAGER_RST_MASK (1 << 7)
+#define OMAP3430_EXTERNAL_WARM_RST_MASK (1 << 6)
+#define OMAP3430_SECURE_WD_RST_MASK (1 << 5)
+#define OMAP3430_MPU_WD_RST_MASK (1 << 4)
+#define OMAP3430_SECURITY_VIOL_RST_MASK (1 << 3)
+#define OMAP3430_GLOBAL_SW_RST_MASK (1 << 1)
+#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
+
+/* PRM_VOLTCTRL */
+#define OMAP3430_SEL_VMODE_MASK (1 << 4)
+#define OMAP3430_SEL_OFF_MASK (1 << 3)
+#define OMAP3430_AUTO_OFF_MASK (1 << 2)
+#define OMAP3430_AUTO_RET_MASK (1 << 1)
+#define OMAP3430_AUTO_SLEEP_MASK (1 << 0)
+
+/* PRM_SRAM_PCHARGE */
+#define OMAP3430_PCHARGE_TIME_SHIFT 0
+#define OMAP3430_PCHARGE_TIME_MASK (0xff << 0)
+
+/* PRM_CLKSRC_CTRL */
+#define OMAP3430_SYSCLKDIV_SHIFT 6
+#define OMAP3430_SYSCLKDIV_MASK (0x3 << 6)
+#define OMAP3430_AUTOEXTCLKMODE_SHIFT 3
+#define OMAP3430_AUTOEXTCLKMODE_MASK (0x3 << 3)
+#define OMAP3430_SYSCLKSEL_SHIFT 0
+#define OMAP3430_SYSCLKSEL_MASK (0x3 << 0)
+
+/* PRM_VOLTSETUP1 */
+#define OMAP3430_SETUP_TIME2_SHIFT 16
+#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)
+#define OMAP3430_SETUP_TIME1_SHIFT 0
+#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0)
+
+/* PRM_VOLTOFFSET */
+#define OMAP3430_OFFSET_TIME_SHIFT 0
+#define OMAP3430_OFFSET_TIME_MASK (0xffff << 0)
+
+/* PRM_CLKSETUP */
+#define OMAP3430_SETUP_TIME_SHIFT 0
+#define OMAP3430_SETUP_TIME_MASK (0xffff << 0)
+
+/* PRM_POLCTRL */
+#define OMAP3430_OFFMODE_POL_MASK (1 << 3)
+#define OMAP3430_CLKOUT_POL_MASK (1 << 2)
+#define OMAP3430_CLKREQ_POL_MASK (1 << 1)
+#define OMAP3430_EXTVOL_POL_MASK (1 << 0)
+
+/* PRM_VOLTSETUP2 */
+#define OMAP3430_OFFMODESETUPTIME_SHIFT 0
+#define OMAP3430_OFFMODESETUPTIME_MASK (0xffff << 0)
+
+/* PRM_VP1_CONFIG specific bits */
+
+/* PRM_VP1_VSTEPMIN specific bits */
+
+/* PRM_VP1_VSTEPMAX specific bits */
+
+/* PRM_VP1_VLIMITTO specific bits */
+
+/* PRM_VP1_VOLTAGE specific bits */
+
+/* PRM_VP1_STATUS specific bits */
+
+/* PRM_VP2_CONFIG specific bits */
+
+/* PRM_VP2_VSTEPMIN specific bits */
+
+/* PRM_VP2_VSTEPMAX specific bits */
+
+/* PRM_VP2_VLIMITTO specific bits */
+
+/* PRM_VP2_VOLTAGE specific bits */
+
+/* PRM_VP2_STATUS specific bits */
+
+/* RM_RSTST_NEON specific bits */
+
+/* PM_WKDEP_NEON specific bits */
+
+/* PM_PWSTCTRL_NEON specific bits */
+
+/* PM_PWSTST_NEON specific bits */
+
+/* PM_PREPWSTST_NEON specific bits */
+
+#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-44xx.h b/arch/arm/mach-omap2/prm-regbits-44xx.h
new file mode 100644
index 00000000..6d2776f6
--- /dev/null
+++ b/arch/arm/mach-omap2/prm-regbits-44xx.h
@@ -0,0 +1,2319 @@
+/*
+ * OMAP44xx Power Management register bits
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_REGBITS_44XX_H
+
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ABBOFF_ACT_EXPORT_SHIFT 1
+#define OMAP4430_ABBOFF_ACT_EXPORT_MASK (1 << 1)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_SHIFT 2
+#define OMAP4430_ABBOFF_SLEEP_EXPORT_MASK (1 << 2)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_ABB_IVA_DONE_EN_SHIFT 31
+#define OMAP4430_ABB_IVA_DONE_EN_MASK (1 << 31)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_ABB_IVA_DONE_ST_SHIFT 31
+#define OMAP4430_ABB_IVA_DONE_ST_MASK (1 << 31)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_ABB_MPU_DONE_EN_SHIFT 7
+#define OMAP4430_ABB_MPU_DONE_EN_MASK (1 << 7)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_ABB_MPU_DONE_ST_SHIFT 7
+#define OMAP4430_ABB_MPU_DONE_ST_MASK (1 << 7)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_ACTIVE_FBB_SEL_SHIFT 2
+#define OMAP4430_ACTIVE_FBB_SEL_MASK (1 << 2)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_ACTIVE_RBB_SEL_SHIFT 1
+#define OMAP4430_ACTIVE_RBB_SEL_MASK (1 << 1)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_AESSMEM_ONSTATE_SHIFT 16
+#define OMAP4430_AESSMEM_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_AESSMEM_RETSTATE_SHIFT 8
+#define OMAP4430_AESSMEM_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP4430_AESSMEM_STATEST_SHIFT 4
+#define OMAP4430_AESSMEM_STATEST_MASK (0x3 << 4)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_AIPOFF_SHIFT 8
+#define OMAP4430_AIPOFF_MASK (1 << 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_SHIFT 0
+#define OMAP4430_AUTO_CTRL_VDD_CORE_L_MASK (0x3 << 0)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_SHIFT 4
+#define OMAP4430_AUTO_CTRL_VDD_IVA_L_MASK (0x3 << 4)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_SHIFT 2
+#define OMAP4430_AUTO_CTRL_VDD_MPU_L_MASK (0x3 << 2)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_RA_ERR_SHIFT 25
+#define OMAP4430_BYPS_RA_ERR_MASK (1 << 25)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_SA_ERR_SHIFT 24
+#define OMAP4430_BYPS_SA_ERR_MASK (1 << 24)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_BYPS_TIMEOUT_ERR_SHIFT 26
+#define OMAP4430_BYPS_TIMEOUT_ERR_MASK (1 << 26)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_C2C_RST_SHIFT 10
+#define OMAP4430_C2C_RST_MASK (1 << 10)
+
+/* Used by PM_CAM_PWRSTCTRL */
+#define OMAP4430_CAM_MEM_ONSTATE_SHIFT 16
+#define OMAP4430_CAM_MEM_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_CAM_PWRSTST */
+#define OMAP4430_CAM_MEM_STATEST_SHIFT 4
+#define OMAP4430_CAM_MEM_STATEST_MASK (0x3 << 4)
+
+/* Used by PRM_CLKREQCTRL */
+#define OMAP4430_CLKREQ_COND_SHIFT 0
+#define OMAP4430_CLKREQ_COND_MASK (0x7 << 0)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_CORE_L_SHIFT 0
+#define OMAP4430_CMDRA_VDD_CORE_L_MASK (0xff << 0)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_IVA_L_SHIFT 8
+#define OMAP4430_CMDRA_VDD_IVA_L_MASK (0xff << 8)
+
+/* Used by PRM_VC_VAL_SMPS_RA_CMD */
+#define OMAP4430_CMDRA_VDD_MPU_L_SHIFT 16
+#define OMAP4430_CMDRA_VDD_MPU_L_MASK (0xff << 16)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_CORE_L_SHIFT 4
+#define OMAP4430_CMD_VDD_CORE_L_MASK (1 << 4)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_IVA_L_SHIFT 12
+#define OMAP4430_CMD_VDD_IVA_L_MASK (1 << 12)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_CMD_VDD_MPU_L_SHIFT 17
+#define OMAP4430_CMD_VDD_MPU_L_MASK (1 << 17)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OCMRAM_ONSTATE_SHIFT 18
+#define OMAP4430_CORE_OCMRAM_ONSTATE_MASK (0x3 << 18)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OCMRAM_RETSTATE_SHIFT 9
+#define OMAP4430_CORE_OCMRAM_RETSTATE_MASK (1 << 9)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_CORE_OCMRAM_STATEST_SHIFT 6
+#define OMAP4430_CORE_OCMRAM_STATEST_MASK (0x3 << 6)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_SHIFT 16
+#define OMAP4430_CORE_OTHER_BANK_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_SHIFT 8
+#define OMAP4430_CORE_OTHER_BANK_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_CORE_OTHER_BANK_STATEST_SHIFT 4
+#define OMAP4430_CORE_OTHER_BANK_STATEST_MASK (0x3 << 4)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_CUSTOM_SHIFT 6
+#define OMAP4430_CUSTOM_MASK (0x3 << 6)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_DATA_SHIFT 16
+#define OMAP4430_DATA_MASK (0xff << 16)
+
+/* Used by PRM_DEVICE_OFF_CTRL */
+#define OMAP4430_DEVICE_OFF_ENABLE_SHIFT 0
+#define OMAP4430_DEVICE_OFF_ENABLE_MASK (1 << 0)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_DFILTEREN_SHIFT 6
+#define OMAP4430_DFILTEREN_MASK (1 << 6)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP, PRM_SRAM_WKUP_SETUP
+ */
+#define OMAP4430_DISABLE_RTA_EXPORT_SHIFT 0
+#define OMAP4430_DISABLE_RTA_EXPORT_MASK (1 << 0)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
+#define OMAP4430_DPLL_ABE_RECAL_EN_SHIFT 4
+#define OMAP4430_DPLL_ABE_RECAL_EN_MASK (1 << 4)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_DPLL_ABE_RECAL_ST_SHIFT 4
+#define OMAP4430_DPLL_ABE_RECAL_ST_MASK (1 << 4)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_CORE_RECAL_EN_SHIFT 0
+#define OMAP4430_DPLL_CORE_RECAL_EN_MASK (1 << 0)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_CORE_RECAL_ST_SHIFT 0
+#define OMAP4430_DPLL_CORE_RECAL_ST_MASK (1 << 0)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_SHIFT 6
+#define OMAP4430_DPLL_DDRPHY_RECAL_EN_MASK (1 << 6)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_SHIFT 6
+#define OMAP4430_DPLL_DDRPHY_RECAL_ST_MASK (1 << 6)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU, PRM_IRQENABLE_TESLA */
+#define OMAP4430_DPLL_IVA_RECAL_EN_SHIFT 2
+#define OMAP4430_DPLL_IVA_RECAL_EN_MASK (1 << 2)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_DPLL_IVA_RECAL_ST_SHIFT 2
+#define OMAP4430_DPLL_IVA_RECAL_ST_MASK (1 << 2)
+
+/* Used by PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_MPU_RECAL_EN_SHIFT 1
+#define OMAP4430_DPLL_MPU_RECAL_EN_MASK (1 << 1)
+
+/* Used by PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_MPU_RECAL_ST_SHIFT 1
+#define OMAP4430_DPLL_MPU_RECAL_ST_MASK (1 << 1)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_PER_RECAL_EN_SHIFT 3
+#define OMAP4430_DPLL_PER_RECAL_EN_MASK (1 << 3)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_PER_RECAL_ST_SHIFT 3
+#define OMAP4430_DPLL_PER_RECAL_ST_MASK (1 << 3)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_SHIFT 7
+#define OMAP4430_DPLL_UNIPRO_RECAL_EN_MASK (1 << 7)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_SHIFT 7
+#define OMAP4430_DPLL_UNIPRO_RECAL_ST_MASK (1 << 7)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP4430_DSS_MEM_ONSTATE_SHIFT 16
+#define OMAP4430_DSS_MEM_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_DSS_PWRSTCTRL */
+#define OMAP4430_DSS_MEM_RETSTATE_SHIFT 8
+#define OMAP4430_DSS_MEM_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_DSS_PWRSTST */
+#define OMAP4430_DSS_MEM_STATEST_SHIFT 4
+#define OMAP4430_DSS_MEM_STATEST_MASK (0x3 << 4)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_SHIFT 20
+#define OMAP4430_DUCATI_L2RAM_ONSTATE_MASK (0x3 << 20)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_SHIFT 10
+#define OMAP4430_DUCATI_L2RAM_RETSTATE_MASK (1 << 10)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_DUCATI_L2RAM_STATEST_SHIFT 8
+#define OMAP4430_DUCATI_L2RAM_STATEST_MASK (0x3 << 8)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_SHIFT 22
+#define OMAP4430_DUCATI_UNICACHE_ONSTATE_MASK (0x3 << 22)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_SHIFT 11
+#define OMAP4430_DUCATI_UNICACHE_RETSTATE_MASK (1 << 11)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_DUCATI_UNICACHE_STATEST_SHIFT 10
+#define OMAP4430_DUCATI_UNICACHE_STATEST_MASK (0x3 << 10)
+
+/* Used by RM_MPU_RSTST */
+#define OMAP4430_EMULATION_RST_SHIFT 0
+#define OMAP4430_EMULATION_RST_MASK (1 << 0)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_EMULATION_RST1ST_SHIFT 3
+#define OMAP4430_EMULATION_RST1ST_MASK (1 << 3)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_EMULATION_RST2ST_SHIFT 4
+#define OMAP4430_EMULATION_RST2ST_MASK (1 << 4)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_EMULATION_SEQ1_RST1ST_SHIFT 3
+#define OMAP4430_EMULATION_SEQ1_RST1ST_MASK (1 << 3)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_EMULATION_SEQ2_RST2ST_SHIFT 4
+#define OMAP4430_EMULATION_SEQ2_RST2ST_MASK (1 << 4)
+
+/* Used by PM_EMU_PWRSTCTRL */
+#define OMAP4430_EMU_BANK_ONSTATE_SHIFT 16
+#define OMAP4430_EMU_BANK_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_EMU_PWRSTST */
+#define OMAP4430_EMU_BANK_STATEST_SHIFT 4
+#define OMAP4430_EMU_BANK_STATEST_MASK (0x3 << 4)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC1_EXPORT_SHIFT 3
+#define OMAP4430_ENFUNC1_EXPORT_MASK (1 << 3)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC3_EXPORT_SHIFT 5
+#define OMAP4430_ENFUNC3_EXPORT_MASK (1 << 5)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC4_SHIFT 6
+#define OMAP4430_ENFUNC4_MASK (1 << 6)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_SETUP, PRM_LDO_SRAM_IVA_SETUP,
+ * PRM_LDO_SRAM_MPU_SETUP
+ */
+#define OMAP4430_ENFUNC5_SHIFT 7
+#define OMAP4430_ENFUNC5_MASK (1 << 7)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_ERRORGAIN_SHIFT 16
+#define OMAP4430_ERRORGAIN_MASK (0xff << 16)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_ERROROFFSET_SHIFT 24
+#define OMAP4430_ERROROFFSET_MASK (0xff << 24)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_EXTERNAL_WARM_RST_SHIFT 5
+#define OMAP4430_EXTERNAL_WARM_RST_MASK (1 << 5)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_FORCEUPDATE_SHIFT 1
+#define OMAP4430_FORCEUPDATE_MASK (1 << 1)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP4430_FORCEUPDATEWAIT_SHIFT 8
+#define OMAP4430_FORCEUPDATEWAIT_MASK (0xffffff << 8)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_TESLA */
+#define OMAP4430_FORCEWKUP_EN_SHIFT 10
+#define OMAP4430_FORCEWKUP_EN_MASK (1 << 10)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_TESLA */
+#define OMAP4430_FORCEWKUP_ST_SHIFT 10
+#define OMAP4430_FORCEWKUP_ST_MASK (1 << 10)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_FUNC_SHIFT 16
+#define OMAP4430_FUNC_MASK (0xfff << 16)
+
+/* Used by PM_GFX_PWRSTCTRL */
+#define OMAP4430_GFX_MEM_ONSTATE_SHIFT 16
+#define OMAP4430_GFX_MEM_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_GFX_PWRSTST */
+#define OMAP4430_GFX_MEM_STATEST_SHIFT 4
+#define OMAP4430_GFX_MEM_STATEST_MASK (0x3 << 4)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_GLOBAL_COLD_RST_SHIFT 0
+#define OMAP4430_GLOBAL_COLD_RST_MASK (1 << 0)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1
+#define OMAP4430_GLOBAL_WARM_SW_RST_MASK (1 << 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_GLOBAL_WUEN_SHIFT 16
+#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_HSMCODE_SHIFT 0
+#define OMAP4430_HSMCODE_MASK (0x7 << 0)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_HSMODEEN_SHIFT 3
+#define OMAP4430_HSMODEEN_MASK (1 << 3)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSSCLH_SHIFT 16
+#define OMAP4430_HSSCLH_MASK (0xff << 16)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_HSSCLL_SHIFT 24
+#define OMAP4430_HSSCLL_MASK (0xff << 24)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_HWA_MEM_ONSTATE_SHIFT 16
+#define OMAP4430_HWA_MEM_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_HWA_MEM_RETSTATE_SHIFT 8
+#define OMAP4430_HWA_MEM_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_HWA_MEM_STATEST_SHIFT 4
+#define OMAP4430_HWA_MEM_STATEST_MASK (0x3 << 4)
+
+/* Used by RM_MPU_RSTST */
+#define OMAP4430_ICECRUSHER_MPU_RST_SHIFT 1
+#define OMAP4430_ICECRUSHER_MPU_RST_MASK (1 << 1)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_ICECRUSHER_RST1ST_SHIFT 5
+#define OMAP4430_ICECRUSHER_RST1ST_MASK (1 << 5)
+
+/* Used by RM_DUCATI_RSTST */
+#define OMAP4430_ICECRUSHER_RST2ST_SHIFT 6
+#define OMAP4430_ICECRUSHER_RST2ST_MASK (1 << 6)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_SHIFT 5
+#define OMAP4430_ICECRUSHER_SEQ1_RST1ST_MASK (1 << 5)
+
+/* Used by RM_IVAHD_RSTST */
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_SHIFT 6
+#define OMAP4430_ICECRUSHER_SEQ2_RST2ST_MASK (1 << 6)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_ICEPICK_RST_SHIFT 9
+#define OMAP4430_ICEPICK_RST_MASK (1 << 9)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_INITVDD_SHIFT 2
+#define OMAP4430_INITVDD_MASK (1 << 2)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_INITVOLTAGE_SHIFT 8
+#define OMAP4430_INITVOLTAGE_MASK (0xff << 8)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
+ */
+#define OMAP4430_INTRANSITION_SHIFT 20
+#define OMAP4430_INTRANSITION_MASK (1 << 20)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_IO_EN_SHIFT 9
+#define OMAP4430_IO_EN_MASK (1 << 9)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_IO_ON_STATUS_SHIFT 5
+#define OMAP4430_IO_ON_STATUS_MASK (1 << 5)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_IO_ST_SHIFT 9
+#define OMAP4430_IO_ST_MASK (1 << 9)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOCLK_OVERRIDE_SHIFT 0
+#define OMAP4430_ISOCLK_OVERRIDE_MASK (1 << 0)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOCLK_STATUS_SHIFT 1
+#define OMAP4430_ISOCLK_STATUS_MASK (1 << 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_ISOOVR_EXTEND_SHIFT 4
+#define OMAP4430_ISOOVR_EXTEND_MASK (1 << 4)
+
+/* Used by PRM_IO_COUNT */
+#define OMAP4430_ISO_2_ON_TIME_SHIFT 0
+#define OMAP4430_ISO_2_ON_TIME_MASK (0xff << 0)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP4430_L3INIT_BANK1_ONSTATE_SHIFT 16
+#define OMAP4430_L3INIT_BANK1_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_L3INIT_PWRSTCTRL */
+#define OMAP4430_L3INIT_BANK1_RETSTATE_SHIFT 8
+#define OMAP4430_L3INIT_BANK1_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_L3INIT_PWRSTST */
+#define OMAP4430_L3INIT_BANK1_STATEST_SHIFT 4
+#define OMAP4430_L3INIT_BANK1_STATEST_MASK (0x3 << 4)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CORE_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
+ */
+#define OMAP4430_LASTPOWERSTATEENTERED_SHIFT 24
+#define OMAP4430_LASTPOWERSTATEENTERED_MASK (0x3 << 24)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL,
+ * PM_IVAHD_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
+ */
+#define OMAP4430_LOGICRETSTATE_SHIFT 2
+#define OMAP4430_LOGICRETSTATE_MASK (1 << 2)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
+ */
+#define OMAP4430_LOGICSTATEST_SHIFT 2
+#define OMAP4430_LOGICSTATEST_MASK (1 << 2)
+
+/*
+ * Used by RM_ABE_AESS_CONTEXT, RM_ABE_DMIC_CONTEXT, RM_ABE_MCASP_CONTEXT,
+ * RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT, RM_ABE_MCBSP3_CONTEXT,
+ * RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT, RM_ABE_TIMER5_CONTEXT,
+ * RM_ABE_TIMER6_CONTEXT, RM_ABE_TIMER7_CONTEXT, RM_ABE_TIMER8_CONTEXT,
+ * RM_ABE_WDT3_CONTEXT, RM_ALWON_MDMINTC_CONTEXT, RM_ALWON_SR_CORE_CONTEXT,
+ * RM_ALWON_SR_IVA_CONTEXT, RM_ALWON_SR_MPU_CONTEXT, RM_CAM_FDIF_CONTEXT,
+ * RM_CAM_ISS_CONTEXT, RM_CEFUSE_CEFUSE_CONTEXT, RM_D2D_SAD2D_CONTEXT,
+ * RM_D2D_SAD2D_FW_CONTEXT, RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT,
+ * RM_DUCATI_DUCATI_CONTEXT, RM_EMU_DEBUGSS_CONTEXT, RM_GFX_GFX_CONTEXT,
+ * RM_IVAHD_IVAHD_CONTEXT, RM_IVAHD_SL2_CONTEXT, RM_L3INIT_CCPTX_CONTEXT,
+ * RM_L3INIT_EMAC_CONTEXT, RM_L3INIT_P1500_CONTEXT, RM_L3INIT_PCIESS_CONTEXT,
+ * RM_L3INIT_SATA_CONTEXT, RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
+ * RM_L3INIT_USBPHYOCP2SCP_CONTEXT, RM_L3INIT_XHPI_CONTEXT,
+ * RM_L3INSTR_L3_3_CONTEXT, RM_L3INSTR_L3_INSTR_CONTEXT,
+ * RM_L3INSTR_OCP_WP1_CONTEXT, RM_L3_1_L3_1_CONTEXT, RM_L3_2_L3_2_CONTEXT,
+ * RM_L3_2_OCMC_RAM_CONTEXT, RM_L4CFG_L4_CFG_CONTEXT, RM_L4CFG_SAR_ROM_CONTEXT,
+ * RM_L4PER_ADC_CONTEXT, RM_L4PER_DMTIMER10_CONTEXT,
+ * RM_L4PER_DMTIMER11_CONTEXT, RM_L4PER_DMTIMER2_CONTEXT,
+ * RM_L4PER_DMTIMER3_CONTEXT, RM_L4PER_DMTIMER4_CONTEXT,
+ * RM_L4PER_DMTIMER9_CONTEXT, RM_L4PER_ELM_CONTEXT, RM_L4PER_HDQ1W_CONTEXT,
+ * RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT, RM_L4PER_I2C2_CONTEXT,
+ * RM_L4PER_I2C3_CONTEXT, RM_L4PER_I2C4_CONTEXT, RM_L4PER_I2C5_CONTEXT,
+ * RM_L4PER_L4_PER_CONTEXT, RM_L4PER_MCASP2_CONTEXT, RM_L4PER_MCASP3_CONTEXT,
+ * RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MCSPI1_CONTEXT, RM_L4PER_MCSPI2_CONTEXT,
+ * RM_L4PER_MCSPI3_CONTEXT, RM_L4PER_MCSPI4_CONTEXT, RM_L4PER_MGATE_CONTEXT,
+ * RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT, RM_L4PER_MMCSD5_CONTEXT,
+ * RM_L4PER_MSPROHG_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT,
+ * RM_L4SEC_PKAEIP29_CONTEXT, RM_MEMIF_DLL_CONTEXT, RM_MEMIF_DLL_H_CONTEXT,
+ * RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT, RM_MEMIF_EMIF_2_CONTEXT,
+ * RM_MEMIF_EMIF_FW_CONTEXT, RM_MPU_MPU_CONTEXT, RM_TESLA_TESLA_CONTEXT,
+ * RM_WKUP_GPIO1_CONTEXT, RM_WKUP_KEYBOARD_CONTEXT, RM_WKUP_L4WKUP_CONTEXT,
+ * RM_WKUP_RTC_CONTEXT, RM_WKUP_SARRAM_CONTEXT, RM_WKUP_SYNCTIMER_CONTEXT,
+ * RM_WKUP_TIMER12_CONTEXT, RM_WKUP_TIMER1_CONTEXT, RM_WKUP_USIM_CONTEXT,
+ * RM_WKUP_WDT1_CONTEXT, RM_WKUP_WDT2_CONTEXT
+ */
+#define OMAP4430_LOSTCONTEXT_DFF_SHIFT 0
+#define OMAP4430_LOSTCONTEXT_DFF_MASK (1 << 0)
+
+/*
+ * Used by RM_D2D_MODEM_ICR_CONTEXT, RM_D2D_SAD2D_CONTEXT,
+ * RM_D2D_SAD2D_FW_CONTEXT, RM_DSS_DSS_CONTEXT, RM_DUCATI_DUCATI_CONTEXT,
+ * RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT,
+ * RM_L3INIT_MMC6_CONTEXT, RM_L3INIT_USB_HOST_CONTEXT,
+ * RM_L3INIT_USB_HOST_FS_CONTEXT, RM_L3INIT_USB_OTG_CONTEXT,
+ * RM_L3INIT_USB_TLL_CONTEXT, RM_L3INSTR_L3_3_CONTEXT,
+ * RM_L3INSTR_OCP_WP1_CONTEXT, RM_L3_1_L3_1_CONTEXT, RM_L3_2_GPMC_CONTEXT,
+ * RM_L3_2_L3_2_CONTEXT, RM_L4CFG_HW_SEM_CONTEXT, RM_L4CFG_L4_CFG_CONTEXT,
+ * RM_L4CFG_MAILBOX_CONTEXT, RM_L4PER_GPIO2_CONTEXT, RM_L4PER_GPIO3_CONTEXT,
+ * RM_L4PER_GPIO4_CONTEXT, RM_L4PER_GPIO5_CONTEXT, RM_L4PER_GPIO6_CONTEXT,
+ * RM_L4PER_I2C1_CONTEXT, RM_L4PER_L4_PER_CONTEXT, RM_L4PER_UART1_CONTEXT,
+ * RM_L4PER_UART2_CONTEXT, RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT,
+ * RM_L4SEC_AES1_CONTEXT, RM_L4SEC_AES2_CONTEXT, RM_L4SEC_CRYPTODMA_CONTEXT,
+ * RM_L4SEC_DES3DES_CONTEXT, RM_L4SEC_RNG_CONTEXT, RM_L4SEC_SHA2MD51_CONTEXT,
+ * RM_MEMIF_DMM_CONTEXT, RM_MEMIF_EMIF_1_CONTEXT, RM_MEMIF_EMIF_2_CONTEXT,
+ * RM_MEMIF_EMIF_FW_CONTEXT, RM_MEMIF_EMIF_H1_CONTEXT,
+ * RM_MEMIF_EMIF_H2_CONTEXT, RM_SDMA_SDMA_CONTEXT, RM_TESLA_TESLA_CONTEXT
+ */
+#define OMAP4430_LOSTCONTEXT_RFF_SHIFT 1
+#define OMAP4430_LOSTCONTEXT_RFF_MASK (1 << 1)
+
+/* Used by RM_ABE_AESS_CONTEXT */
+#define OMAP4430_LOSTMEM_AESSMEM_SHIFT 8
+#define OMAP4430_LOSTMEM_AESSMEM_MASK (1 << 8)
+
+/* Used by RM_CAM_FDIF_CONTEXT, RM_CAM_ISS_CONTEXT */
+#define OMAP4430_LOSTMEM_CAM_MEM_SHIFT 8
+#define OMAP4430_LOSTMEM_CAM_MEM_MASK (1 << 8)
+
+/* Used by RM_L3INSTR_OCP_WP1_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_MASK (1 << 8)
+
+/* Renamed from LOSTMEM_CORE_NRET_BANK Used by RM_MEMIF_DMM_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_SHIFT 9
+#define OMAP4430_LOSTMEM_CORE_NRET_BANK_9_9_MASK (1 << 9)
+
+/* Used by RM_L3_2_OCMC_RAM_CONTEXT */
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_SHIFT 8
+#define OMAP4430_LOSTMEM_CORE_OCMRAM_MASK (1 << 8)
+
+/*
+ * Used by RM_D2D_MODEM_ICR_CONTEXT, RM_MEMIF_DMM_CONTEXT,
+ * RM_SDMA_SDMA_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_CORE_OTHER_BANK_MASK (1 << 8)
+
+/* Used by RM_DSS_DEISS_CONTEXT, RM_DSS_DSS_CONTEXT */
+#define OMAP4430_LOSTMEM_DSS_MEM_SHIFT 8
+#define OMAP4430_LOSTMEM_DSS_MEM_MASK (1 << 8)
+
+/* Used by RM_DUCATI_DUCATI_CONTEXT */
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_SHIFT 9
+#define OMAP4430_LOSTMEM_DUCATI_L2RAM_MASK (1 << 9)
+
+/* Used by RM_DUCATI_DUCATI_CONTEXT */
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_SHIFT 8
+#define OMAP4430_LOSTMEM_DUCATI_UNICACHE_MASK (1 << 8)
+
+/* Used by RM_EMU_DEBUGSS_CONTEXT */
+#define OMAP4430_LOSTMEM_EMU_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_EMU_BANK_MASK (1 << 8)
+
+/* Used by RM_GFX_GFX_CONTEXT */
+#define OMAP4430_LOSTMEM_GFX_MEM_SHIFT 8
+#define OMAP4430_LOSTMEM_GFX_MEM_MASK (1 << 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_HWA_MEM_SHIFT 10
+#define OMAP4430_LOSTMEM_HWA_MEM_MASK (1 << 10)
+
+/*
+ * Used by RM_L3INIT_CCPTX_CONTEXT, RM_L3INIT_EMAC_CONTEXT,
+ * RM_L3INIT_HSI_CONTEXT, RM_L3INIT_MMC1_CONTEXT, RM_L3INIT_MMC2_CONTEXT,
+ * RM_L3INIT_MMC6_CONTEXT, RM_L3INIT_PCIESS_CONTEXT, RM_L3INIT_SATA_CONTEXT,
+ * RM_L3INIT_TPPSS_CONTEXT, RM_L3INIT_UNIPRO1_CONTEXT,
+ * RM_L3INIT_USB_OTG_CONTEXT, RM_L3INIT_XHPI_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_SHIFT 8
+#define OMAP4430_LOSTMEM_L3INIT_BANK1_MASK (1 << 8)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_L1_SHIFT 8
+#define OMAP4430_LOSTMEM_MPU_L1_MASK (1 << 8)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_L2_SHIFT 9
+#define OMAP4430_LOSTMEM_MPU_L2_MASK (1 << 9)
+
+/* Used by RM_MPU_MPU_CONTEXT */
+#define OMAP4430_LOSTMEM_MPU_RAM_SHIFT 10
+#define OMAP4430_LOSTMEM_MPU_RAM_MASK (1 << 10)
+
+/*
+ * Used by RM_L4PER_HECC1_CONTEXT, RM_L4PER_HECC2_CONTEXT,
+ * RM_L4PER_MCBSP4_CONTEXT, RM_L4PER_MMCSD3_CONTEXT, RM_L4PER_MMCSD4_CONTEXT,
+ * RM_L4PER_MMCSD5_CONTEXT, RM_L4PER_SLIMBUS2_CONTEXT, RM_L4SEC_PKAEIP29_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_NONRETAINED_BANK_MASK (1 << 8)
+
+/*
+ * Used by RM_ABE_DMIC_CONTEXT, RM_ABE_MCBSP1_CONTEXT, RM_ABE_MCBSP2_CONTEXT,
+ * RM_ABE_MCBSP3_CONTEXT, RM_ABE_PDM_CONTEXT, RM_ABE_SLIMBUS_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_PERIHPMEM_SHIFT 8
+#define OMAP4430_LOSTMEM_PERIHPMEM_MASK (1 << 8)
+
+/*
+ * Used by RM_L4PER_MSPROHG_CONTEXT, RM_L4PER_UART1_CONTEXT,
+ * RM_L4PER_UART2_CONTEXT, RM_L4PER_UART3_CONTEXT, RM_L4PER_UART4_CONTEXT,
+ * RM_L4SEC_CRYPTODMA_CONTEXT
+ */
+#define OMAP4430_LOSTMEM_RETAINED_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_RETAINED_BANK_MASK (1 << 8)
+
+/* Used by RM_IVAHD_SL2_CONTEXT */
+#define OMAP4430_LOSTMEM_SL2_MEM_SHIFT 8
+#define OMAP4430_LOSTMEM_SL2_MEM_MASK (1 << 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_TCM1_MEM_SHIFT 8
+#define OMAP4430_LOSTMEM_TCM1_MEM_MASK (1 << 8)
+
+/* Used by RM_IVAHD_IVAHD_CONTEXT */
+#define OMAP4430_LOSTMEM_TCM2_MEM_SHIFT 9
+#define OMAP4430_LOSTMEM_TCM2_MEM_MASK (1 << 9)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_EDMA_SHIFT 10
+#define OMAP4430_LOSTMEM_TESLA_EDMA_MASK (1 << 10)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_L1_SHIFT 8
+#define OMAP4430_LOSTMEM_TESLA_L1_MASK (1 << 8)
+
+/* Used by RM_TESLA_TESLA_CONTEXT */
+#define OMAP4430_LOSTMEM_TESLA_L2_SHIFT 9
+#define OMAP4430_LOSTMEM_TESLA_L2_MASK (1 << 9)
+
+/* Used by RM_WKUP_SARRAM_CONTEXT */
+#define OMAP4430_LOSTMEM_WKUP_BANK_SHIFT 8
+#define OMAP4430_LOSTMEM_WKUP_BANK_MASK (1 << 8)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
+ * PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_GFX_PWRSTCTRL, PM_IVAHD_PWRSTCTRL,
+ * PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL, PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
+ */
+#define OMAP4430_LOWPOWERSTATECHANGE_SHIFT 4
+#define OMAP4430_LOWPOWERSTATECHANGE_MASK (1 << 4)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_READY_SHIFT 1
+#define OMAP4430_MODEM_READY_MASK (1 << 1)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_SHIFT 9
+#define OMAP4430_MODEM_SHUTDOWN_IRQ_MASK (1 << 9)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_SLEEP_ST_SHIFT 16
+#define OMAP4430_MODEM_SLEEP_ST_MASK (1 << 16)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_MODEM_WAKE_IRQ_SHIFT 8
+#define OMAP4430_MODEM_WAKE_IRQ_MASK (1 << 8)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L1_ONSTATE_SHIFT 16
+#define OMAP4430_MPU_L1_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L1_RETSTATE_SHIFT 8
+#define OMAP4430_MPU_L1_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_L1_STATEST_SHIFT 4
+#define OMAP4430_MPU_L1_STATEST_MASK (0x3 << 4)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L2_ONSTATE_SHIFT 18
+#define OMAP4430_MPU_L2_ONSTATE_MASK (0x3 << 18)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_L2_RETSTATE_SHIFT 9
+#define OMAP4430_MPU_L2_RETSTATE_MASK (1 << 9)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_L2_STATEST_SHIFT 6
+#define OMAP4430_MPU_L2_STATEST_MASK (0x3 << 6)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_RAM_ONSTATE_SHIFT 20
+#define OMAP4430_MPU_RAM_ONSTATE_MASK (0x3 << 20)
+
+/* Used by PM_MPU_PWRSTCTRL */
+#define OMAP4430_MPU_RAM_RETSTATE_SHIFT 10
+#define OMAP4430_MPU_RAM_RETSTATE_MASK (1 << 10)
+
+/* Used by PM_MPU_PWRSTST */
+#define OMAP4430_MPU_RAM_STATEST_SHIFT 8
+#define OMAP4430_MPU_RAM_STATEST_MASK (0x3 << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT 2
+#define OMAP4430_MPU_SECURITY_VIOL_RST_MASK (1 << 2)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_MPU_WDT_RST_SHIFT 3
+#define OMAP4430_MPU_WDT_RST_MASK (1 << 3)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_SHIFT 18
+#define OMAP4430_NONRETAINED_BANK_ONSTATE_MASK (0x3 << 18)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_SHIFT 9
+#define OMAP4430_NONRETAINED_BANK_RETSTATE_MASK (1 << 9)
+
+/* Used by PM_L4PER_PWRSTST */
+#define OMAP4430_NONRETAINED_BANK_STATEST_SHIFT 6
+#define OMAP4430_NONRETAINED_BANK_STATEST_MASK (0x3 << 6)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_SHIFT 24
+#define OMAP4430_OCP_NRET_BANK_ONSTATE_MASK (0x3 << 24)
+
+/* Used by PM_CORE_PWRSTCTRL */
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_SHIFT 12
+#define OMAP4430_OCP_NRET_BANK_RETSTATE_MASK (1 << 12)
+
+/* Used by PM_CORE_PWRSTST */
+#define OMAP4430_OCP_NRET_BANK_STATEST_SHIFT 12
+#define OMAP4430_OCP_NRET_BANK_STATEST_MASK (0x3 << 12)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_OFF_SHIFT 0
+#define OMAP4430_OFF_MASK (0xff << 0)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_ON_SHIFT 24
+#define OMAP4430_ON_MASK (0xff << 24)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_ONLP_SHIFT 16
+#define OMAP4430_ONLP_MASK (0xff << 16)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_OPP_CHANGE_SHIFT 2
+#define OMAP4430_OPP_CHANGE_MASK (1 << 2)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_OPP_SEL_SHIFT 0
+#define OMAP4430_OPP_SEL_MASK (0x3 << 0)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_PCHARGECNT_VALUE_SHIFT 0
+#define OMAP4430_PCHARGECNT_VALUE_MASK (0x3f << 0)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP4430_PCHARGE_TIME_SHIFT 0
+#define OMAP4430_PCHARGE_TIME_MASK (0xff << 0)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_PERIPHMEM_ONSTATE_SHIFT 20
+#define OMAP4430_PERIPHMEM_ONSTATE_MASK (0x3 << 20)
+
+/* Used by PM_ABE_PWRSTCTRL */
+#define OMAP4430_PERIPHMEM_RETSTATE_SHIFT 10
+#define OMAP4430_PERIPHMEM_RETSTATE_MASK (1 << 10)
+
+/* Used by PM_ABE_PWRSTST */
+#define OMAP4430_PERIPHMEM_STATEST_SHIFT 8
+#define OMAP4430_PERIPHMEM_STATEST_MASK (0x3 << 8)
+
+/* Used by PRM_PHASE1_CNDP */
+#define OMAP4430_PHASE1_CNDP_SHIFT 0
+#define OMAP4430_PHASE1_CNDP_MASK (0xffffffff << 0)
+
+/* Used by PRM_PHASE2A_CNDP */
+#define OMAP4430_PHASE2A_CNDP_SHIFT 0
+#define OMAP4430_PHASE2A_CNDP_MASK (0xffffffff << 0)
+
+/* Used by PRM_PHASE2B_CNDP */
+#define OMAP4430_PHASE2B_CNDP_SHIFT 0
+#define OMAP4430_PHASE2B_CNDP_MASK (0xffffffff << 0)
+
+/* Used by PRM_PSCON_COUNT */
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_SHIFT 8
+#define OMAP4430_PONOUT_2_PGOODIN_TIME_MASK (0xff << 8)
+
+/*
+ * Used by PM_ABE_PWRSTCTRL, PM_CAM_PWRSTCTRL, PM_CEFUSE_PWRSTCTRL,
+ * PM_CORE_PWRSTCTRL, PM_DSS_PWRSTCTRL, PM_EMU_PWRSTCTRL, PM_GFX_PWRSTCTRL,
+ * PM_IVAHD_PWRSTCTRL, PM_L3INIT_PWRSTCTRL, PM_L4PER_PWRSTCTRL,
+ * PM_MPU_PWRSTCTRL, PM_TESLA_PWRSTCTRL
+ */
+#define OMAP4430_POWERSTATE_SHIFT 0
+#define OMAP4430_POWERSTATE_MASK (0x3 << 0)
+
+/*
+ * Used by PM_ABE_PWRSTST, PM_CAM_PWRSTST, PM_CEFUSE_PWRSTST, PM_CORE_PWRSTST,
+ * PM_DSS_PWRSTST, PM_EMU_PWRSTST, PM_GFX_PWRSTST, PM_IVAHD_PWRSTST,
+ * PM_L3INIT_PWRSTST, PM_L4PER_PWRSTST, PM_MPU_PWRSTST, PM_TESLA_PWRSTST
+ */
+#define OMAP4430_POWERSTATEST_SHIFT 0
+#define OMAP4430_POWERSTATEST_MASK (0x3 << 0)
+
+/* Used by PRM_PWRREQCTRL */
+#define OMAP4430_PWRREQ_COND_SHIFT 0
+#define OMAP4430_PWRREQ_COND_MASK (0x3 << 0)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_CORE_L_SHIFT 3
+#define OMAP4430_RACEN_VDD_CORE_L_MASK (1 << 3)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_IVA_L_SHIFT 11
+#define OMAP4430_RACEN_VDD_IVA_L_MASK (1 << 11)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RACEN_VDD_MPU_L_SHIFT 20
+#define OMAP4430_RACEN_VDD_MPU_L_MASK (1 << 20)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_CORE_L_SHIFT 2
+#define OMAP4430_RAC_VDD_CORE_L_MASK (1 << 2)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_IVA_L_SHIFT 10
+#define OMAP4430_RAC_VDD_IVA_L_MASK (1 << 10)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAC_VDD_MPU_L_SHIFT 19
+#define OMAP4430_RAC_VDD_MPU_L_MASK (1 << 19)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_DOWN_COUNT_SHIFT 16
+#define OMAP4430_RAMP_DOWN_COUNT_MASK (0x3f << 16)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_DOWN_PRESCAL_SHIFT 24
+#define OMAP4430_RAMP_DOWN_PRESCAL_MASK (0x3 << 24)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_UP_COUNT_SHIFT 0
+#define OMAP4430_RAMP_UP_COUNT_MASK (0x3f << 0)
+
+/*
+ * Used by PRM_VOLTSETUP_CORE_OFF, PRM_VOLTSETUP_CORE_RET_SLEEP,
+ * PRM_VOLTSETUP_IVA_OFF, PRM_VOLTSETUP_IVA_RET_SLEEP, PRM_VOLTSETUP_MPU_OFF,
+ * PRM_VOLTSETUP_MPU_RET_SLEEP
+ */
+#define OMAP4430_RAMP_UP_PRESCAL_SHIFT 8
+#define OMAP4430_RAMP_UP_PRESCAL_MASK (0x3 << 8)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_CORE_L_SHIFT 1
+#define OMAP4430_RAV_VDD_CORE_L_MASK (1 << 1)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_IVA_L_SHIFT 9
+#define OMAP4430_RAV_VDD_IVA_L_MASK (1 << 9)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_RAV_VDD_MPU_L_SHIFT 18
+#define OMAP4430_RAV_VDD_MPU_L_MASK (1 << 18)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_REGADDR_SHIFT 8
+#define OMAP4430_REGADDR_MASK (0xff << 8)
+
+/*
+ * Used by PRM_VC_VAL_CMD_VDD_CORE_L, PRM_VC_VAL_CMD_VDD_IVA_L,
+ * PRM_VC_VAL_CMD_VDD_MPU_L
+ */
+#define OMAP4430_RET_SHIFT 8
+#define OMAP4430_RET_MASK (0xff << 8)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_RETAINED_BANK_ONSTATE_SHIFT 16
+#define OMAP4430_RETAINED_BANK_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_L4PER_PWRSTCTRL */
+#define OMAP4430_RETAINED_BANK_RETSTATE_SHIFT 8
+#define OMAP4430_RETAINED_BANK_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_L4PER_PWRSTST */
+#define OMAP4430_RETAINED_BANK_STATEST_SHIFT 4
+#define OMAP4430_RETAINED_BANK_STATEST_MASK (0x3 << 4)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_RETMODE_ENABLE_SHIFT 0
+#define OMAP4430_RETMODE_ENABLE_MASK (1 << 0)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL, RM_TESLA_RSTCTRL */
+#define OMAP4430_RST1_SHIFT 0
+#define OMAP4430_RST1_MASK (1 << 0)
+
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST, RM_TESLA_RSTST */
+#define OMAP4430_RST1ST_SHIFT 0
+#define OMAP4430_RST1ST_MASK (1 << 0)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL, RM_TESLA_RSTCTRL */
+#define OMAP4430_RST2_SHIFT 1
+#define OMAP4430_RST2_MASK (1 << 1)
+
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST, RM_TESLA_RSTST */
+#define OMAP4430_RST2ST_SHIFT 1
+#define OMAP4430_RST2ST_MASK (1 << 1)
+
+/* Used by RM_DUCATI_RSTCTRL, RM_IVAHD_RSTCTRL */
+#define OMAP4430_RST3_SHIFT 2
+#define OMAP4430_RST3_MASK (1 << 2)
+
+/* Used by RM_DUCATI_RSTST, RM_IVAHD_RSTST */
+#define OMAP4430_RST3ST_SHIFT 2
+#define OMAP4430_RST3ST_MASK (1 << 2)
+
+/* Used by PRM_RSTTIME */
+#define OMAP4430_RSTTIME1_SHIFT 0
+#define OMAP4430_RSTTIME1_MASK (0x3ff << 0)
+
+/* Used by PRM_RSTTIME */
+#define OMAP4430_RSTTIME2_SHIFT 10
+#define OMAP4430_RSTTIME2_MASK (0x1f << 10)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP4430_RST_GLOBAL_COLD_SW_SHIFT 1
+#define OMAP4430_RST_GLOBAL_COLD_SW_MASK (1 << 1)
+
+/* Used by PRM_RSTCTRL */
+#define OMAP4430_RST_GLOBAL_WARM_SW_SHIFT 0
+#define OMAP4430_RST_GLOBAL_WARM_SW_MASK (1 << 0)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_R_RTL_SHIFT 11
+#define OMAP4430_R_RTL_MASK (0x1f << 11)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_CORE_L_SHIFT 0
+#define OMAP4430_SA_VDD_CORE_L_MASK (1 << 0)
+
+/* Renamed from SA_VDD_CORE_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_CORE_L_0_6_SHIFT 0
+#define OMAP4430_SA_VDD_CORE_L_0_6_MASK (0x7f << 0)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_IVA_L_SHIFT 8
+#define OMAP4430_SA_VDD_IVA_L_MASK (1 << 8)
+
+/* Renamed from SA_VDD_IVA_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT 8
+#define OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK (0x7f << 8)
+
+/* Used by PRM_VC_CFG_CHANNEL */
+#define OMAP4430_SA_VDD_MPU_L_SHIFT 16
+#define OMAP4430_SA_VDD_MPU_L_MASK (1 << 16)
+
+/* Renamed from SA_VDD_MPU_L Used by PRM_VC_SMPS_SA */
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT 16
+#define OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK (0x7f << 16)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_SCHEME_SHIFT 30
+#define OMAP4430_SCHEME_MASK (0x3 << 30)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_SCLH_SHIFT 0
+#define OMAP4430_SCLH_MASK (0xff << 0)
+
+/* Used by PRM_VC_CFG_I2C_CLK */
+#define OMAP4430_SCLL_SHIFT 8
+#define OMAP4430_SCLL_MASK (0xff << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_SECURE_WDT_RST_SHIFT 4
+#define OMAP4430_SECURE_WDT_RST_MASK (1 << 4)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_SL2_MEM_ONSTATE_SHIFT 18
+#define OMAP4430_SL2_MEM_ONSTATE_MASK (0x3 << 18)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_SL2_MEM_RETSTATE_SHIFT 9
+#define OMAP4430_SL2_MEM_RETSTATE_MASK (1 << 9)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_SL2_MEM_STATEST_SHIFT 6
+#define OMAP4430_SL2_MEM_STATEST_MASK (0x3 << 6)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_SLAVEADDR_SHIFT 0
+#define OMAP4430_SLAVEADDR_MASK (0x7f << 0)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SLEEP_RBB_SEL_SHIFT 3
+#define OMAP4430_SLEEP_RBB_SEL_MASK (1 << 3)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_SLPCNT_VALUE_SHIFT 16
+#define OMAP4430_SLPCNT_VALUE_MASK (0xff << 16)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP4430_SMPSWAITTIMEMAX_SHIFT 8
+#define OMAP4430_SMPSWAITTIMEMAX_MASK (0xffff << 8)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP4430_SMPSWAITTIMEMIN_SHIFT 8
+#define OMAP4430_SMPSWAITTIMEMIN_MASK (0xffff << 8)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_CORE_SHIFT 1
+#define OMAP4430_SMPS_RA_ERR_CORE_MASK (1 << 1)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_IVA_SHIFT 9
+#define OMAP4430_SMPS_RA_ERR_IVA_MASK (1 << 9)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_RA_ERR_MPU_SHIFT 17
+#define OMAP4430_SMPS_RA_ERR_MPU_MASK (1 << 17)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_CORE_SHIFT 0
+#define OMAP4430_SMPS_SA_ERR_CORE_MASK (1 << 0)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_IVA_SHIFT 8
+#define OMAP4430_SMPS_SA_ERR_IVA_MASK (1 << 8)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_SA_ERR_MPU_SHIFT 16
+#define OMAP4430_SMPS_SA_ERR_MPU_MASK (1 << 16)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_CORE_SHIFT 2
+#define OMAP4430_SMPS_TIMEOUT_ERR_CORE_MASK (1 << 2)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_IVA_SHIFT 10
+#define OMAP4430_SMPS_TIMEOUT_ERR_IVA_MASK (1 << 10)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_SMPS_TIMEOUT_ERR_MPU_SHIFT 18
+#define OMAP4430_SMPS_TIMEOUT_ERR_MPU_MASK (1 << 18)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SR2EN_SHIFT 0
+#define OMAP4430_SR2EN_MASK (1 << 0)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_SR2_IN_TRANSITION_SHIFT 6
+#define OMAP4430_SR2_IN_TRANSITION_MASK (1 << 6)
+
+/* Used by PRM_LDO_ABB_IVA_CTRL, PRM_LDO_ABB_MPU_CTRL */
+#define OMAP4430_SR2_STATUS_SHIFT 3
+#define OMAP4430_SR2_STATUS_MASK (0x3 << 3)
+
+/* Used by PRM_LDO_ABB_IVA_SETUP, PRM_LDO_ABB_MPU_SETUP */
+#define OMAP4430_SR2_WTCNT_VALUE_SHIFT 8
+#define OMAP4430_SR2_WTCNT_VALUE_MASK (0xff << 8)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_SRAMLDO_STATUS_SHIFT 8
+#define OMAP4430_SRAMLDO_STATUS_MASK (1 << 8)
+
+/*
+ * Used by PRM_LDO_SRAM_CORE_CTRL, PRM_LDO_SRAM_IVA_CTRL,
+ * PRM_LDO_SRAM_MPU_CTRL
+ */
+#define OMAP4430_SRAM_IN_TRANSITION_SHIFT 9
+#define OMAP4430_SRAM_IN_TRANSITION_MASK (1 << 9)
+
+/* Used by PRM_VC_CFG_I2C_MODE */
+#define OMAP4430_SRMODEEN_SHIFT 4
+#define OMAP4430_SRMODEEN_MASK (1 << 4)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP4430_STABLE_COUNT_SHIFT 0
+#define OMAP4430_STABLE_COUNT_MASK (0x3f << 0)
+
+/* Used by PRM_VOLTSETUP_WARMRESET */
+#define OMAP4430_STABLE_PRESCAL_SHIFT 8
+#define OMAP4430_STABLE_PRESCAL_MASK (0x3 << 8)
+
+/* Used by PRM_LDO_BANDGAP_SETUP */
+#define OMAP4430_STARTUP_COUNT_SHIFT 0
+#define OMAP4430_STARTUP_COUNT_MASK (0xff << 0)
+
+/* Renamed from STARTUP_COUNT Used by PRM_SRAM_COUNT */
+#define OMAP4430_STARTUP_COUNT_24_31_SHIFT 24
+#define OMAP4430_STARTUP_COUNT_24_31_MASK (0xff << 24)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM1_MEM_ONSTATE_SHIFT 20
+#define OMAP4430_TCM1_MEM_ONSTATE_MASK (0x3 << 20)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM1_MEM_RETSTATE_SHIFT 10
+#define OMAP4430_TCM1_MEM_RETSTATE_MASK (1 << 10)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_TCM1_MEM_STATEST_SHIFT 8
+#define OMAP4430_TCM1_MEM_STATEST_MASK (0x3 << 8)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM2_MEM_ONSTATE_SHIFT 22
+#define OMAP4430_TCM2_MEM_ONSTATE_MASK (0x3 << 22)
+
+/* Used by PM_IVAHD_PWRSTCTRL */
+#define OMAP4430_TCM2_MEM_RETSTATE_SHIFT 11
+#define OMAP4430_TCM2_MEM_RETSTATE_MASK (1 << 11)
+
+/* Used by PM_IVAHD_PWRSTST */
+#define OMAP4430_TCM2_MEM_STATEST_SHIFT 10
+#define OMAP4430_TCM2_MEM_STATEST_MASK (0x3 << 10)
+
+/* Used by RM_TESLA_RSTST */
+#define OMAP4430_TESLASS_EMU_RSTST_SHIFT 2
+#define OMAP4430_TESLASS_EMU_RSTST_MASK (1 << 2)
+
+/* Used by RM_TESLA_RSTST */
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_SHIFT 3
+#define OMAP4430_TESLA_DSP_EMU_REQ_RSTST_MASK (1 << 3)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_EDMA_ONSTATE_SHIFT 20
+#define OMAP4430_TESLA_EDMA_ONSTATE_MASK (0x3 << 20)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_EDMA_RETSTATE_SHIFT 10
+#define OMAP4430_TESLA_EDMA_RETSTATE_MASK (1 << 10)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_EDMA_STATEST_SHIFT 8
+#define OMAP4430_TESLA_EDMA_STATEST_MASK (0x3 << 8)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L1_ONSTATE_SHIFT 16
+#define OMAP4430_TESLA_L1_ONSTATE_MASK (0x3 << 16)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L1_RETSTATE_SHIFT 8
+#define OMAP4430_TESLA_L1_RETSTATE_MASK (1 << 8)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_L1_STATEST_SHIFT 4
+#define OMAP4430_TESLA_L1_STATEST_MASK (0x3 << 4)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L2_ONSTATE_SHIFT 18
+#define OMAP4430_TESLA_L2_ONSTATE_MASK (0x3 << 18)
+
+/* Used by PM_TESLA_PWRSTCTRL */
+#define OMAP4430_TESLA_L2_RETSTATE_SHIFT 9
+#define OMAP4430_TESLA_L2_RETSTATE_MASK (1 << 9)
+
+/* Used by PM_TESLA_PWRSTST */
+#define OMAP4430_TESLA_L2_STATEST_SHIFT 6
+#define OMAP4430_TESLA_L2_STATEST_MASK (0x3 << 6)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_TIMEOUT_SHIFT 0
+#define OMAP4430_TIMEOUT_MASK (0xffff << 0)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_TIMEOUTEN_SHIFT 3
+#define OMAP4430_TIMEOUTEN_MASK (1 << 3)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_TRANSITION_EN_SHIFT 8
+#define OMAP4430_TRANSITION_EN_MASK (1 << 8)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_TRANSITION_ST_SHIFT 8
+#define OMAP4430_TRANSITION_ST_MASK (1 << 8)
+
+/* Used by PRM_VC_VAL_BYPASS */
+#define OMAP4430_VALID_SHIFT 24
+#define OMAP4430_VALID_MASK (1 << 24)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_BYPASSACK_EN_SHIFT 14
+#define OMAP4430_VC_BYPASSACK_EN_MASK (1 << 14)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_BYPASSACK_ST_SHIFT 14
+#define OMAP4430_VC_BYPASSACK_ST_MASK (1 << 14)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_CORE_VPACK_EN_SHIFT 22
+#define OMAP4430_VC_CORE_VPACK_EN_MASK (1 << 22)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_CORE_VPACK_ST_SHIFT 22
+#define OMAP4430_VC_CORE_VPACK_ST_MASK (1 << 22)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_IVA_VPACK_EN_SHIFT 30
+#define OMAP4430_VC_IVA_VPACK_EN_MASK (1 << 30)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_IVA_VPACK_ST_SHIFT 30
+#define OMAP4430_VC_IVA_VPACK_ST_MASK (1 << 30)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VC_MPU_VPACK_EN_SHIFT 6
+#define OMAP4430_VC_MPU_VPACK_EN_MASK (1 << 6)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VC_MPU_VPACK_ST_SHIFT 6
+#define OMAP4430_VC_MPU_VPACK_ST_MASK (1 << 6)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_RAERR_EN_SHIFT 12
+#define OMAP4430_VC_RAERR_EN_MASK (1 << 12)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_RAERR_ST_SHIFT 12
+#define OMAP4430_VC_RAERR_ST_MASK (1 << 12)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_SAERR_EN_SHIFT 11
+#define OMAP4430_VC_SAERR_EN_MASK (1 << 11)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_SAERR_ST_SHIFT 11
+#define OMAP4430_VC_SAERR_ST_MASK (1 << 11)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VC_TOERR_EN_SHIFT 13
+#define OMAP4430_VC_TOERR_EN_MASK (1 << 13)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VC_TOERR_ST_SHIFT 13
+#define OMAP4430_VC_TOERR_ST_MASK (1 << 13)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_VDDMAX_SHIFT 24
+#define OMAP4430_VDDMAX_MASK (0xff << 24)
+
+/* Used by PRM_VP_CORE_VLIMITTO, PRM_VP_IVA_VLIMITTO, PRM_VP_MPU_VLIMITTO */
+#define OMAP4430_VDDMIN_SHIFT 16
+#define OMAP4430_VDDMIN_MASK (0xff << 16)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_CORE_I2C_DISABLE_SHIFT 12
+#define OMAP4430_VDD_CORE_I2C_DISABLE_MASK (1 << 12)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT 8
+#define OMAP4430_VDD_CORE_VOLT_MGR_RST_MASK (1 << 8)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_IVA_I2C_DISABLE_SHIFT 14
+#define OMAP4430_VDD_IVA_I2C_DISABLE_MASK (1 << 14)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_IVA_PRESENCE_SHIFT 9
+#define OMAP4430_VDD_IVA_PRESENCE_MASK (1 << 9)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT 7
+#define OMAP4430_VDD_IVA_VOLT_MGR_RST_MASK (1 << 7)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_MPU_I2C_DISABLE_SHIFT 13
+#define OMAP4430_VDD_MPU_I2C_DISABLE_MASK (1 << 13)
+
+/* Used by PRM_VOLTCTRL */
+#define OMAP4430_VDD_MPU_PRESENCE_SHIFT 8
+#define OMAP4430_VDD_MPU_PRESENCE_MASK (1 << 8)
+
+/* Used by PRM_RSTST */
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT 6
+#define OMAP4430_VDD_MPU_VOLT_MGR_RST_MASK (1 << 6)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_CORE_SHIFT 4
+#define OMAP4430_VFSM_RA_ERR_CORE_MASK (1 << 4)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_IVA_SHIFT 12
+#define OMAP4430_VFSM_RA_ERR_IVA_MASK (1 << 12)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_RA_ERR_MPU_SHIFT 20
+#define OMAP4430_VFSM_RA_ERR_MPU_MASK (1 << 20)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_CORE_SHIFT 3
+#define OMAP4430_VFSM_SA_ERR_CORE_MASK (1 << 3)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_IVA_SHIFT 11
+#define OMAP4430_VFSM_SA_ERR_IVA_MASK (1 << 11)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_SA_ERR_MPU_SHIFT 19
+#define OMAP4430_VFSM_SA_ERR_MPU_MASK (1 << 19)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_CORE_SHIFT 5
+#define OMAP4430_VFSM_TIMEOUT_ERR_CORE_MASK (1 << 5)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_IVA_SHIFT 13
+#define OMAP4430_VFSM_TIMEOUT_ERR_IVA_MASK (1 << 13)
+
+/* Used by PRM_VC_ERRST */
+#define OMAP4430_VFSM_TIMEOUT_ERR_MPU_SHIFT 21
+#define OMAP4430_VFSM_TIMEOUT_ERR_MPU_MASK (1 << 21)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_CORE_L_SHIFT 0
+#define OMAP4430_VOLRA_VDD_CORE_L_MASK (0xff << 0)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_IVA_L_SHIFT 8
+#define OMAP4430_VOLRA_VDD_IVA_L_MASK (0xff << 8)
+
+/* Used by PRM_VC_VAL_SMPS_RA_VOL */
+#define OMAP4430_VOLRA_VDD_MPU_L_SHIFT 16
+#define OMAP4430_VOLRA_VDD_MPU_L_MASK (0xff << 16)
+
+/* Used by PRM_VP_CORE_CONFIG, PRM_VP_IVA_CONFIG, PRM_VP_MPU_CONFIG */
+#define OMAP4430_VPENABLE_SHIFT 0
+#define OMAP4430_VPENABLE_MASK (1 << 0)
+
+/* Used by PRM_VP_CORE_STATUS, PRM_VP_IVA_STATUS, PRM_VP_MPU_STATUS */
+#define OMAP4430_VPINIDLE_SHIFT 0
+#define OMAP4430_VPINIDLE_MASK (1 << 0)
+
+/* Used by PRM_VP_CORE_VOLTAGE, PRM_VP_IVA_VOLTAGE, PRM_VP_MPU_VOLTAGE */
+#define OMAP4430_VPVOLTAGE_SHIFT 0
+#define OMAP4430_VPVOLTAGE_MASK (0xff << 0)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_EQVALUE_EN_SHIFT 20
+#define OMAP4430_VP_CORE_EQVALUE_EN_MASK (1 << 20)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_EQVALUE_ST_SHIFT 20
+#define OMAP4430_VP_CORE_EQVALUE_ST_MASK (1 << 20)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_MAXVDD_EN_SHIFT 18
+#define OMAP4430_VP_CORE_MAXVDD_EN_MASK (1 << 18)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_MAXVDD_ST_SHIFT 18
+#define OMAP4430_VP_CORE_MAXVDD_ST_MASK (1 << 18)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_MINVDD_EN_SHIFT 17
+#define OMAP4430_VP_CORE_MINVDD_EN_MASK (1 << 17)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_MINVDD_ST_SHIFT 17
+#define OMAP4430_VP_CORE_MINVDD_ST_MASK (1 << 17)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_SHIFT 19
+#define OMAP4430_VP_CORE_NOSMPSACK_EN_MASK (1 << 19)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_SHIFT 19
+#define OMAP4430_VP_CORE_NOSMPSACK_ST_MASK (1 << 19)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_SHIFT 16
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_EN_MASK (1 << 16)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_SHIFT 16
+#define OMAP4430_VP_CORE_OPPCHANGEDONE_ST_MASK (1 << 16)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_CORE_TRANXDONE_EN_SHIFT 21
+#define OMAP4430_VP_CORE_TRANXDONE_EN_MASK (1 << 21)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_CORE_TRANXDONE_ST_SHIFT 21
+#define OMAP4430_VP_CORE_TRANXDONE_ST_MASK (1 << 21)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_EQVALUE_EN_SHIFT 28
+#define OMAP4430_VP_IVA_EQVALUE_EN_MASK (1 << 28)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_EQVALUE_ST_SHIFT 28
+#define OMAP4430_VP_IVA_EQVALUE_ST_MASK (1 << 28)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_MAXVDD_EN_SHIFT 26
+#define OMAP4430_VP_IVA_MAXVDD_EN_MASK (1 << 26)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_MAXVDD_ST_SHIFT 26
+#define OMAP4430_VP_IVA_MAXVDD_ST_MASK (1 << 26)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_MINVDD_EN_SHIFT 25
+#define OMAP4430_VP_IVA_MINVDD_EN_MASK (1 << 25)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_MINVDD_ST_SHIFT 25
+#define OMAP4430_VP_IVA_MINVDD_ST_MASK (1 << 25)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_SHIFT 27
+#define OMAP4430_VP_IVA_NOSMPSACK_EN_MASK (1 << 27)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_SHIFT 27
+#define OMAP4430_VP_IVA_NOSMPSACK_ST_MASK (1 << 27)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_SHIFT 24
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_EN_MASK (1 << 24)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_SHIFT 24
+#define OMAP4430_VP_IVA_OPPCHANGEDONE_ST_MASK (1 << 24)
+
+/* Used by PRM_IRQENABLE_DUCATI, PRM_IRQENABLE_MPU */
+#define OMAP4430_VP_IVA_TRANXDONE_EN_SHIFT 29
+#define OMAP4430_VP_IVA_TRANXDONE_EN_MASK (1 << 29)
+
+/* Used by PRM_IRQSTATUS_DUCATI, PRM_IRQSTATUS_MPU */
+#define OMAP4430_VP_IVA_TRANXDONE_ST_SHIFT 29
+#define OMAP4430_VP_IVA_TRANXDONE_ST_MASK (1 << 29)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_EQVALUE_EN_SHIFT 4
+#define OMAP4430_VP_MPU_EQVALUE_EN_MASK (1 << 4)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_EQVALUE_ST_SHIFT 4
+#define OMAP4430_VP_MPU_EQVALUE_ST_MASK (1 << 4)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_MAXVDD_EN_SHIFT 2
+#define OMAP4430_VP_MPU_MAXVDD_EN_MASK (1 << 2)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_MAXVDD_ST_SHIFT 2
+#define OMAP4430_VP_MPU_MAXVDD_ST_MASK (1 << 2)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_MINVDD_EN_SHIFT 1
+#define OMAP4430_VP_MPU_MINVDD_EN_MASK (1 << 1)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_MINVDD_ST_SHIFT 1
+#define OMAP4430_VP_MPU_MINVDD_ST_MASK (1 << 1)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_SHIFT 3
+#define OMAP4430_VP_MPU_NOSMPSACK_EN_MASK (1 << 3)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_SHIFT 3
+#define OMAP4430_VP_MPU_NOSMPSACK_ST_MASK (1 << 3)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_SHIFT 0
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_EN_MASK (1 << 0)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_SHIFT 0
+#define OMAP4430_VP_MPU_OPPCHANGEDONE_ST_MASK (1 << 0)
+
+/* Used by PRM_IRQENABLE_MPU_2 */
+#define OMAP4430_VP_MPU_TRANXDONE_EN_SHIFT 5
+#define OMAP4430_VP_MPU_TRANXDONE_EN_MASK (1 << 5)
+
+/* Used by PRM_IRQSTATUS_MPU_2 */
+#define OMAP4430_VP_MPU_TRANXDONE_ST_SHIFT 5
+#define OMAP4430_VP_MPU_TRANXDONE_ST_MASK (1 << 5)
+
+/* Used by PRM_SRAM_COUNT */
+#define OMAP4430_VSETUPCNT_VALUE_SHIFT 8
+#define OMAP4430_VSETUPCNT_VALUE_MASK (0xff << 8)
+
+/* Used by PRM_VP_CORE_VSTEPMAX, PRM_VP_IVA_VSTEPMAX, PRM_VP_MPU_VSTEPMAX */
+#define OMAP4430_VSTEPMAX_SHIFT 0
+#define OMAP4430_VSTEPMAX_MASK (0xff << 0)
+
+/* Used by PRM_VP_CORE_VSTEPMIN, PRM_VP_IVA_VSTEPMIN, PRM_VP_MPU_VSTEPMIN */
+#define OMAP4430_VSTEPMIN_SHIFT 0
+#define OMAP4430_VSTEPMIN_MASK (0xff << 0)
+
+/* Used by PRM_MODEM_IF_CTRL */
+#define OMAP4430_WAKE_MODEM_SHIFT 0
+#define OMAP4430_WAKE_MODEM_MASK (1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_DISPC_DUCATI_MASK (1 << 1)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DISPC_MPU_MASK (1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_DISPC_SDMA_MASK (1 << 3)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DISPC_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_DISPC_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_DMIC_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_DMIC_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMIC_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_DMIC_WKDEP */
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_DMIC_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_DMTIMER10_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER10_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_DMTIMER11_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_DMTIMER11_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_DMTIMER11_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER11_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_DMTIMER2_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER2_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_DMTIMER3_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_DMTIMER3_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_DMTIMER3_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER3_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_DMTIMER4_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_DMTIMER4_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_DMTIMER4_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER4_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_DMTIMER9_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_DMTIMER9_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_DMTIMER9_WKDEP */
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_DMTIMER9_MPU_MASK (1 << 0)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_SHIFT 5
+#define OMAP4430_WKUPDEP_DSI1_DUCATI_MASK (1 << 5)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_MPU_SHIFT 4
+#define OMAP4430_WKUPDEP_DSI1_MPU_MASK (1 << 4)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_DSI1_SDMA_MASK (1 << 7)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI1_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_DSI1_TESLA_MASK (1 << 6)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_SHIFT 9
+#define OMAP4430_WKUPDEP_DSI2_DUCATI_MASK (1 << 9)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_MPU_SHIFT 8
+#define OMAP4430_WKUPDEP_DSI2_MPU_MASK (1 << 8)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_SDMA_SHIFT 11
+#define OMAP4430_WKUPDEP_DSI2_SDMA_MASK (1 << 11)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_DSI2_TESLA_SHIFT 10
+#define OMAP4430_WKUPDEP_DSI2_TESLA_MASK (1 << 10)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_DUCATI_MASK (1 << 1)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO1_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_GPIO1_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO1_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO2_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_GPIO2_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO2_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO3_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_GPIO3_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO3_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO4_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_GPIO4_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO4_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO5_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_GPIO5_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO5_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_GPIO6_IRQ1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_GPIO6_WKDEP */
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_GPIO6_IRQ2_TESLA_MASK (1 << 6)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_SHIFT 19
+#define OMAP4430_WKUPDEP_HDMIDMA_SDMA_MASK (1 << 19)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_SHIFT 13
+#define OMAP4430_WKUPDEP_HDMIIRQ_DUCATI_MASK (1 << 13)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_SHIFT 12
+#define OMAP4430_WKUPDEP_HDMIIRQ_MPU_MASK (1 << 12)
+
+/* Used by PM_DSS_DSS_WKDEP */
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_SHIFT 14
+#define OMAP4430_WKUPDEP_HDMIIRQ_TESLA_MASK (1 << 14)
+
+/* Used by PM_L4PER_HECC1_WKDEP */
+#define OMAP4430_WKUPDEP_HECC1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_HECC1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_HECC2_WKDEP */
+#define OMAP4430_WKUPDEP_HECC2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_HECC2_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_HSI_DSP_TESLA_MASK (1 << 6)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_HSI_MCU_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_HSI_MCU_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_I2C1_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_I2C1_IRQ_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_I2C1_WKDEP */
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_I2C1_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_I2C2_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_I2C2_IRQ_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_I2C2_WKDEP */
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_I2C2_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_I2C3_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_I2C3_IRQ_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_I2C3_WKDEP */
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_I2C3_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_I2C4_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_I2C4_IRQ_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_I2C4_WKDEP */
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_I2C4_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_I2C5_WKDEP */
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_I2C5_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_I2C5_WKDEP */
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_I2C5_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_KEYBOARD_WKDEP */
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_KEYBOARD_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_MCASP1_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_MCASP1_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_MCASP_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCASP1_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_MCASP2_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_MCASP2_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCASP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCASP2_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_MCASP3_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_MCASP3_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCASP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCASP3_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCBSP1_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCBSP1_SDMA_MASK (1 << 3)
+
+/* Used by PM_ABE_MCBSP1_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCBSP1_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCBSP2_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCBSP2_SDMA_MASK (1 << 3)
+
+/* Used by PM_ABE_MCBSP2_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCBSP2_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCBSP3_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCBSP3_SDMA_MASK (1 << 3)
+
+/* Used by PM_ABE_MCBSP3_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCBSP3_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCBSP4_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCBSP4_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MCBSP4_WKDEP */
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCBSP4_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MCSPI1_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCSPI1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCSPI1_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MCSPI1_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MCSPI1_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MCSPI2_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCSPI2_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCSPI2_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCSPI2_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCSPI3_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCSPI3_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCSPI3_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MCSPI4_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MCSPI4_WKDEP */
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MCSPI4_SDMA_MASK (1 << 3)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMC1_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMC1_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MMC1_SDMA_MASK (1 << 3)
+
+/* Used by PM_L3INIT_MMC1_WKDEP */
+#define OMAP4430_WKUPDEP_MMC1_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MMC1_TESLA_MASK (1 << 2)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMC2_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMC2_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MMC2_SDMA_MASK (1 << 3)
+
+/* Used by PM_L3INIT_MMC2_WKDEP */
+#define OMAP4430_WKUPDEP_MMC2_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MMC2_TESLA_MASK (1 << 2)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMC6_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMC6_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_MMC6_WKDEP */
+#define OMAP4430_WKUPDEP_MMC6_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_MMC6_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMCSD3_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMCSD3_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MMCSD3_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MMCSD3_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMCSD4_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMCSD4_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MMCSD4_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MMCSD4_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_MMCSD5_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_MMCSD5_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_MMCSD5_WKDEP */
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_MMCSD5_SDMA_MASK (1 << 3)
+
+/* Used by PM_L3INIT_PCIESS_WKDEP */
+#define OMAP4430_WKUPDEP_PCIESS_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_PCIESS_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_PCIESS_WKDEP */
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_PCIESS_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_PDM_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_PDM_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_PDM_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_PDM_WKDEP */
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_PDM_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_WKUP_RTC_WKDEP */
+#define OMAP4430_WKUPDEP_RTC_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_RTC_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_SATA_WKDEP */
+#define OMAP4430_WKUPDEP_SATA_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SATA_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_SATA_WKDEP */
+#define OMAP4430_WKUPDEP_SATA_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_SATA_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_SLIMBUS1_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_SLIMBUS_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_SLIMBUS1_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_SHIFT 7
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_SDMA_MASK (1 << 7)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_SHIFT 6
+#define OMAP4430_WKUPDEP_SLIMBUS2_DMA_TESLA_MASK (1 << 6)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_SLIMBUS2_WKDEP */
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_SLIMBUS2_IRQ_TESLA_MASK (1 << 2)
+
+/* Used by PM_ALWON_SR_CORE_WKDEP */
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_SR_CORE_DUCATI_MASK (1 << 1)
+
+/* Used by PM_ALWON_SR_CORE_WKDEP */
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SR_CORE_MPU_MASK (1 << 0)
+
+/* Used by PM_ALWON_SR_IVA_WKDEP */
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_SR_IVA_DUCATI_MASK (1 << 1)
+
+/* Used by PM_ALWON_SR_IVA_WKDEP */
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SR_IVA_MPU_MASK (1 << 0)
+
+/* Used by PM_ALWON_SR_MPU_WKDEP */
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_SR_MPU_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_TIMER12_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER12_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER12_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_TIMER1_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER1_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER5_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER5_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_TIMER5_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_TIMER5_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER6_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER6_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_TIMER6_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_TIMER6_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER7_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER7_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_TIMER7_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_TIMER7_TESLA_MASK (1 << 2)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER8_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_TIMER8_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_TIMER8_WKDEP */
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_TIMER8_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP4430_WKUPDEP_UART1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_UART1_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_UART1_WKDEP */
+#define OMAP4430_WKUPDEP_UART1_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_UART1_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP4430_WKUPDEP_UART2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_UART2_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_UART2_WKDEP */
+#define OMAP4430_WKUPDEP_UART2_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_UART2_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_UART3_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_UART3_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_UART3_SDMA_MASK (1 << 3)
+
+/* Used by PM_L4PER_UART3_WKDEP */
+#define OMAP4430_WKUPDEP_UART3_TESLA_SHIFT 2
+#define OMAP4430_WKUPDEP_UART3_TESLA_MASK (1 << 2)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP4430_WKUPDEP_UART4_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_UART4_MPU_MASK (1 << 0)
+
+/* Used by PM_L4PER_UART4_WKDEP */
+#define OMAP4430_WKUPDEP_UART4_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_UART4_SDMA_MASK (1 << 3)
+
+/* Used by PM_L3INIT_UNIPRO1_WKDEP */
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_UNIPRO1_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_UNIPRO1_WKDEP */
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_UNIPRO1_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_USB_HOST_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_USB_HOST_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_USB_HOST_FS_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_USB_HOST_FS_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_USB_HOST_FS_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_USB_HOST_WKDEP */
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_USB_HOST_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_USB_OTG_WKDEP */
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_USB_OTG_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_USB_OTG_WKDEP */
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_USB_OTG_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_USB_TLL_WKDEP */
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_USB_TLL_DUCATI_MASK (1 << 1)
+
+/* Used by PM_L3INIT_USB_TLL_WKDEP */
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_USB_TLL_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_USIM_WKDEP */
+#define OMAP4430_WKUPDEP_USIM_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_USIM_MPU_MASK (1 << 0)
+
+/* Used by PM_WKUP_USIM_WKDEP */
+#define OMAP4430_WKUPDEP_USIM_SDMA_SHIFT 3
+#define OMAP4430_WKUPDEP_USIM_SDMA_MASK (1 << 3)
+
+/* Used by PM_WKUP_WDT2_WKDEP */
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_WDT2_DUCATI_MASK (1 << 1)
+
+/* Used by PM_WKUP_WDT2_WKDEP */
+#define OMAP4430_WKUPDEP_WDT2_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_WDT2_MPU_MASK (1 << 0)
+
+/* Used by PM_ABE_WDT3_WKDEP */
+#define OMAP4430_WKUPDEP_WDT3_MPU_SHIFT 0
+#define OMAP4430_WKUPDEP_WDT3_MPU_MASK (1 << 0)
+
+/* Used by PM_L3INIT_HSI_WKDEP */
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_SHIFT 8
+#define OMAP4430_WKUPDEP_WGM_HSI_WAKE_MPU_MASK (1 << 8)
+
+/* Used by PM_L3INIT_XHPI_WKDEP */
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_SHIFT 1
+#define OMAP4430_WKUPDEP_XHPI_DUCATI_MASK (1 << 1)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_WUCLK_CTRL_SHIFT 8
+#define OMAP4430_WUCLK_CTRL_MASK (1 << 8)
+
+/* Used by PRM_IO_PMCTRL */
+#define OMAP4430_WUCLK_STATUS_SHIFT 9
+#define OMAP4430_WUCLK_STATUS_MASK (1 << 9)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_X_MAJOR_SHIFT 8
+#define OMAP4430_X_MAJOR_MASK (0x7 << 8)
+
+/* Used by REVISION_PRM */
+#define OMAP4430_Y_MINOR_SHIFT 0
+#define OMAP4430_Y_MINOR_MASK (0x3f << 0)
+#endif
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
new file mode 100644
index 00000000..39d56216
--- /dev/null
+++ b/arch/arm/mach-omap2/prm.h
@@ -0,0 +1,56 @@
+/*
+ * OMAP2/3/4 Power/Reset Management (PRM) bitfield definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM_H
+#define __ARCH_ARM_MACH_OMAP2_PRM_H
+
+#include "prcm-common.h"
+
+/*
+ * 24XX: PM_PWSTST_CORE, PM_PWSTST_GFX, PM_PWSTST_MPU, PM_PWSTST_DSP
+ *
+ * 2430: PM_PWSTST_MDM
+ *
+ * 3430: PM_PWSTST_IVA2, PM_PWSTST_MPU, PM_PWSTST_CORE, PM_PWSTST_GFX,
+ * PM_PWSTST_DSS, PM_PWSTST_CAM, PM_PWSTST_PER, PM_PWSTST_EMU,
+ * PM_PWSTST_NEON
+ */
+#define OMAP_INTRANSITION_MASK (1 << 20)
+
+
+/*
+ * 24XX: PM_PWSTST_GFX, PM_PWSTST_DSP
+ *
+ * 2430: PM_PWSTST_MDM
+ *
+ * 3430: PM_PWSTST_IVA2, PM_PWSTST_MPU, PM_PWSTST_CORE, PM_PWSTST_GFX,
+ * PM_PWSTST_DSS, PM_PWSTST_CAM, PM_PWSTST_PER, PM_PWSTST_EMU,
+ * PM_PWSTST_NEON
+ */
+#define OMAP_POWERSTATEST_SHIFT 0
+#define OMAP_POWERSTATEST_MASK (0x3 << 0)
+
+/*
+ * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
+ * PM_PWSTCTRL_DSP, PM_PWSTST_MPU
+ *
+ * 2430: PM_PWSTCTRL_MDM shared bits
+ *
+ * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE,
+ * PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER,
+ * PM_PWSTCTRL_NEON shared bits
+ */
+#define OMAP_POWERSTATE_SHIFT 0
+#define OMAP_POWERSTATE_MASK (0x3 << 0)
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
new file mode 100644
index 00000000..051213fb
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -0,0 +1,158 @@
+/*
+ * OMAP2/3 PRM module functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-24xx.h"
+#include "prm-regbits-34xx.h"
+
+u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+ return __raw_readl(prm_base + module + idx);
+}
+
+void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ __raw_writel(val, prm_base + module + idx);
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(module, idx);
+ v &= ~mask;
+ v |= bits;
+ omap2_prm_write_mod_reg(v, module, idx);
+
+ return v;
+}
+
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = omap2_prm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, bits, module, idx);
+}
+
+u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ return omap2_prm_rmw_mod_reg_bits(bits, 0x0, module, idx);
+}
+
+
+/**
+ * omap2_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @shift: register bit shift corresponding to the reset line to check
+ *
+ * Returns 1 if the (sub)module hardreset line is currently asserted,
+ * 0 if the (sub)module hardreset line is not currently asserted, or
+ * -EINVAL if called while running on a non-OMAP2/3 chip.
+ */
+int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
+{
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ return omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL,
+ (1 << shift));
+}
+
+/**
+ * omap2_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @shift: register bit shift corresponding to the reset line to assert
+ *
+ * Some IPs like dsp or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * place the submodule into reset. Returns 0 upon success or -EINVAL
+ * upon an argument error.
+ */
+int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
+{
+ u32 mask;
+
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ mask = 1 << shift;
+ omap2_prm_rmw_mod_reg_bits(mask, mask, prm_mod, OMAP2_RM_RSTCTRL);
+
+ return 0;
+}
+
+/**
+ * omap2_prm_deassert_hardreset - deassert a submodule hardreset line and wait
+ * @prm_mod: PRM submodule base (e.g. CORE_MOD)
+ * @rst_shift: register bit shift corresponding to the reset line to deassert
+ * @st_shift: register bit shift for the status of the deasserted submodule
+ *
+ * Some IPs like dsp or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * take the submodule out of reset and wait until the PRCM indicates
+ * that the reset has completed before returning. Returns 0 upon success or
+ * -EINVAL upon an argument error, -EEXIST if the submodule was already out
+ * of reset, or -EBUSY if the submodule did not exit reset promptly.
+ */
+int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
+{
+ u32 rst, st;
+ int c;
+
+ if (!(cpu_is_omap24xx() || cpu_is_omap34xx()))
+ return -EINVAL;
+
+ rst = 1 << rst_shift;
+ st = 1 << st_shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTCTRL, rst) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ omap2_prm_rmw_mod_reg_bits(0xffffffff, st, prm_mod, OMAP2_RM_RSTST);
+ /* de-assert the reset control line */
+ omap2_prm_rmw_mod_reg_bits(rst, 0, prm_mod, OMAP2_RM_RSTCTRL);
+ /* wait the status to be set */
+ omap_test_timeout(omap2_prm_read_mod_bits_shift(prm_mod, OMAP2_RM_RSTST,
+ st),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
new file mode 100644
index 00000000..a1fc62a3
--- /dev/null
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -0,0 +1,429 @@
+/*
+ * OMAP2/3 Power/Reset Management (PRM) register definitions
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The PRM hardware modules on the OMAP2/3 are quite similar to each
+ * other. The PRM on OMAP4 has a new register layout, and is handled
+ * in a separate file.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM2XXX_3XXX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+
+#define OMAP2420_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
+#define OMAP2430_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE + (module) + (reg))
+#define OMAP34XX_PRM_REGADDR(module, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE + (module) + (reg))
+
+
+/*
+ * OMAP2-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ *
+ */
+
+#define OMAP2_PRCM_REVISION_OFFSET 0x0000
+#define OMAP2420_PRCM_REVISION OMAP2420_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2_PRCM_SYSCONFIG_OFFSET 0x0010
+#define OMAP2420_PRCM_SYSCONFIG OMAP2420_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2_PRCM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP2420_PRCM_IRQSTATUS_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2_PRCM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP2420_PRCM_IRQENABLE_MPU OMAP2420_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2_PRCM_VOLTCTRL_OFFSET 0x0050
+#define OMAP2420_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2_PRCM_VOLTST_OFFSET 0x0054
+#define OMAP2420_PRCM_VOLTST OMAP2420_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2_PRCM_CLKSRC_CTRL_OFFSET 0x0060
+#define OMAP2420_PRCM_CLKSRC_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2_PRCM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP2420_PRCM_CLKOUT_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2_PRCM_CLKEMUL_CTRL_OFFSET 0x0078
+#define OMAP2420_PRCM_CLKEMUL_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2_PRCM_CLKCFG_CTRL_OFFSET 0x0080
+#define OMAP2420_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2_PRCM_CLKCFG_STATUS_OFFSET 0x0084
+#define OMAP2420_PRCM_CLKCFG_STATUS OMAP2420_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2_PRCM_VOLTSETUP_OFFSET 0x0090
+#define OMAP2420_PRCM_VOLTSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2_PRCM_CLKSSETUP_OFFSET 0x0094
+#define OMAP2420_PRCM_CLKSSETUP OMAP2420_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2_PRCM_POLCTRL_OFFSET 0x0098
+#define OMAP2420_PRCM_POLCTRL OMAP2420_PRM_REGADDR(OCP_MOD, 0x0098)
+
+#define OMAP2430_PRCM_REVISION OMAP2430_PRM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP2430_PRCM_SYSCONFIG OMAP2430_PRM_REGADDR(OCP_MOD, 0x0010)
+
+#define OMAP2430_PRCM_IRQSTATUS_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP2430_PRCM_IRQENABLE_MPU OMAP2430_PRM_REGADDR(OCP_MOD, 0x001c)
+
+#define OMAP2430_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0050)
+#define OMAP2430_PRCM_VOLTST OMAP2430_PRM_REGADDR(OCP_MOD, 0x0054)
+#define OMAP2430_PRCM_CLKSRC_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0060)
+#define OMAP2430_PRCM_CLKOUT_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0070)
+#define OMAP2430_PRCM_CLKEMUL_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0078)
+#define OMAP2430_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0080)
+#define OMAP2430_PRCM_CLKCFG_STATUS OMAP2430_PRM_REGADDR(OCP_MOD, 0x0084)
+#define OMAP2430_PRCM_VOLTSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0090)
+#define OMAP2430_PRCM_CLKSSETUP OMAP2430_PRM_REGADDR(OCP_MOD, 0x0094)
+#define OMAP2430_PRCM_POLCTRL OMAP2430_PRM_REGADDR(OCP_MOD, 0x0098)
+
+/*
+ * OMAP3-specific global PRM registers
+ * Use __raw_{read,write}l() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE
+ * bits.)
+ */
+
+#define OMAP3_PRM_REVISION_OFFSET 0x0004
+#define OMAP3430_PRM_REVISION OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0004)
+#define OMAP3_PRM_SYSCONFIG_OFFSET 0x0014
+#define OMAP3430_PRM_SYSCONFIG OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0014)
+
+#define OMAP3_PRM_IRQSTATUS_MPU_OFFSET 0x0018
+#define OMAP3430_PRM_IRQSTATUS_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x0018)
+#define OMAP3_PRM_IRQENABLE_MPU_OFFSET 0x001c
+#define OMAP3430_PRM_IRQENABLE_MPU OMAP34XX_PRM_REGADDR(OCP_MOD, 0x001c)
+
+
+#define OMAP3_PRM_VC_SMPS_SA_OFFSET 0x0020
+#define OMAP3430_PRM_VC_SMPS_SA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020)
+#define OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET 0x0024
+#define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024)
+#define OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET 0x0028
+#define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028)
+#define OMAP3_PRM_VC_CMD_VAL_0_OFFSET 0x002c
+#define OMAP3430_PRM_VC_CMD_VAL_0 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x002c)
+#define OMAP3_PRM_VC_CMD_VAL_1_OFFSET 0x0030
+#define OMAP3430_PRM_VC_CMD_VAL_1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0030)
+#define OMAP3_PRM_VC_CH_CONF_OFFSET 0x0034
+#define OMAP3430_PRM_VC_CH_CONF OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0034)
+#define OMAP3_PRM_VC_I2C_CFG_OFFSET 0x0038
+#define OMAP3430_PRM_VC_I2C_CFG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0038)
+#define OMAP3_PRM_VC_BYPASS_VAL_OFFSET 0x003c
+#define OMAP3430_PRM_VC_BYPASS_VAL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x003c)
+#define OMAP3_PRM_RSTCTRL_OFFSET 0x0050
+#define OMAP3430_PRM_RSTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0050)
+#define OMAP3_PRM_RSTTIME_OFFSET 0x0054
+#define OMAP3430_PRM_RSTTIME OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0054)
+#define OMAP3_PRM_RSTST_OFFSET 0x0058
+#define OMAP3430_PRM_RSTST OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0058)
+#define OMAP3_PRM_VOLTCTRL_OFFSET 0x0060
+#define OMAP3430_PRM_VOLTCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0060)
+#define OMAP3_PRM_SRAM_PCHARGE_OFFSET 0x0064
+#define OMAP3430_PRM_SRAM_PCHARGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0064)
+#define OMAP3_PRM_CLKSRC_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKSRC_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0070)
+#define OMAP3_PRM_VOLTSETUP1_OFFSET 0x0090
+#define OMAP3430_PRM_VOLTSETUP1 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0090)
+#define OMAP3_PRM_VOLTOFFSET_OFFSET 0x0094
+#define OMAP3430_PRM_VOLTOFFSET OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0094)
+#define OMAP3_PRM_CLKSETUP_OFFSET 0x0098
+#define OMAP3430_PRM_CLKSETUP OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x0098)
+#define OMAP3_PRM_POLCTRL_OFFSET 0x009c
+#define OMAP3430_PRM_POLCTRL OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x009c)
+#define OMAP3_PRM_VOLTSETUP2_OFFSET 0x00a0
+#define OMAP3430_PRM_VOLTSETUP2 OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00a0)
+#define OMAP3_PRM_VP1_CONFIG_OFFSET 0x00b0
+#define OMAP3430_PRM_VP1_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b0)
+#define OMAP3_PRM_VP1_VSTEPMIN_OFFSET 0x00b4
+#define OMAP3430_PRM_VP1_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b4)
+#define OMAP3_PRM_VP1_VSTEPMAX_OFFSET 0x00b8
+#define OMAP3430_PRM_VP1_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00b8)
+#define OMAP3_PRM_VP1_VLIMITTO_OFFSET 0x00bc
+#define OMAP3430_PRM_VP1_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00bc)
+#define OMAP3_PRM_VP1_VOLTAGE_OFFSET 0x00c0
+#define OMAP3430_PRM_VP1_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c0)
+#define OMAP3_PRM_VP1_STATUS_OFFSET 0x00c4
+#define OMAP3430_PRM_VP1_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00c4)
+#define OMAP3_PRM_VP2_CONFIG_OFFSET 0x00d0
+#define OMAP3430_PRM_VP2_CONFIG OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d0)
+#define OMAP3_PRM_VP2_VSTEPMIN_OFFSET 0x00d4
+#define OMAP3430_PRM_VP2_VSTEPMIN OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d4)
+#define OMAP3_PRM_VP2_VSTEPMAX_OFFSET 0x00d8
+#define OMAP3430_PRM_VP2_VSTEPMAX OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00d8)
+#define OMAP3_PRM_VP2_VLIMITTO_OFFSET 0x00dc
+#define OMAP3430_PRM_VP2_VLIMITTO OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00dc)
+#define OMAP3_PRM_VP2_VOLTAGE_OFFSET 0x00e0
+#define OMAP3430_PRM_VP2_VOLTAGE OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e0)
+#define OMAP3_PRM_VP2_STATUS_OFFSET 0x00e4
+#define OMAP3430_PRM_VP2_STATUS OMAP34XX_PRM_REGADDR(OMAP3430_GR_MOD, 0x00e4)
+
+#define OMAP3_PRM_CLKSEL_OFFSET 0x0040
+#define OMAP3430_PRM_CLKSEL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0040)
+#define OMAP3_PRM_CLKOUT_CTRL_OFFSET 0x0070
+#define OMAP3430_PRM_CLKOUT_CTRL OMAP34XX_PRM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
+
+/*
+ * Module specific PRM register offsets from PRM_BASE + domain offset
+ *
+ * Use prm_{read,write}_mod_reg() with these registers.
+ *
+ * With a few exceptions, these are the register names beginning with
+ * {PM,RM}_* on both OMAP2/3 SoC families.. (The exceptions are the
+ * IRQSTATUS and IRQENABLE bits.)
+ */
+
+/* Register offsets appearing on both OMAP2 and OMAP3 */
+
+#define OMAP2_RM_RSTCTRL 0x0050
+#define OMAP2_RM_RSTTIME 0x0054
+#define OMAP2_RM_RSTST 0x0058
+#define OMAP2_PM_PWSTCTRL 0x00e0
+#define OMAP2_PM_PWSTST 0x00e4
+
+#define PM_WKEN 0x00a0
+#define PM_WKEN1 PM_WKEN
+#define PM_WKST 0x00b0
+#define PM_WKST1 PM_WKST
+#define PM_WKDEP 0x00c8
+#define PM_EVGENCTRL 0x00d4
+#define PM_EVGENONTIM 0x00d8
+#define PM_EVGENOFFTIM 0x00dc
+
+/* OMAP2xxx specific register offsets */
+#define OMAP24XX_PM_WKEN2 0x00a4
+#define OMAP24XX_PM_WKST2 0x00b4
+
+#define OMAP24XX_PRCM_IRQSTATUS_DSP 0x00f0 /* IVA mod */
+#define OMAP24XX_PRCM_IRQENABLE_DSP 0x00f4 /* IVA mod */
+#define OMAP24XX_PRCM_IRQSTATUS_IVA 0x00f8
+#define OMAP24XX_PRCM_IRQENABLE_IVA 0x00fc
+
+/* OMAP3 specific register offsets */
+#define OMAP3430ES2_PM_WKEN3 0x00f0
+#define OMAP3430ES2_PM_WKST3 0x00b8
+
+#define OMAP3430_PM_MPUGRPSEL 0x00a4
+#define OMAP3430_PM_MPUGRPSEL1 OMAP3430_PM_MPUGRPSEL
+#define OMAP3430ES2_PM_MPUGRPSEL3 0x00f8
+
+#define OMAP3430_PM_IVAGRPSEL 0x00a8
+#define OMAP3430_PM_IVAGRPSEL1 OMAP3430_PM_IVAGRPSEL
+#define OMAP3430ES2_PM_IVAGRPSEL3 0x00f4
+
+#define OMAP3430_PM_PREPWSTST 0x00e8
+
+#define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8
+#define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc
+
+
+#ifndef __ASSEMBLER__
+/*
+ * Stub omap2xxx/omap3xxx functions so that common files
+ * continue to build when custom builds are used
+ */
+#if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) || \
+ defined(CONFIG_ARCH_OMAP3))
+static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+}
+static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
+ s16 module, s16 idx)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
+ u8 st_shift)
+{
+ WARN(1, "prm: omap2xxx/omap3xxx specific function and "
+ "not suppose to be used on omap4\n");
+ return 0;
+}
+#else
+/* Power/reset management domain register get/set */
+extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
+extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
+extern u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx);
+extern u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask);
+
+/* These omap2_ PRM functions apply to both OMAP2 and 3 */
+extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
+extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
+extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
+
+#endif /* CONFIG_ARCH_OMAP4 */
+#endif
+
+/*
+ * Bits common to specific registers
+ *
+ * The 3430 register and bit names are generally used,
+ * since they tend to make more sense
+ */
+
+/* PM_EVGENONTIM_MPU */
+/* Named PM_EVEGENONTIM_MPU on the 24XX */
+#define OMAP_ONTIMEVAL_SHIFT 0
+#define OMAP_ONTIMEVAL_MASK (0xffffffff << 0)
+
+/* PM_EVGENOFFTIM_MPU */
+/* Named PM_EVEGENOFFTIM_MPU on the 24XX */
+#define OMAP_OFFTIMEVAL_SHIFT 0
+#define OMAP_OFFTIMEVAL_MASK (0xffffffff << 0)
+
+/* PRM_CLKSETUP and PRCM_VOLTSETUP */
+/* Named PRCM_CLKSSETUP on the 24XX */
+#define OMAP_SETUP_TIME_SHIFT 0
+#define OMAP_SETUP_TIME_MASK (0xffff << 0)
+
+/* PRM_CLKSRC_CTRL */
+/* Named PRCM_CLKSRC_CTRL on the 24XX */
+#define OMAP_SYSCLKDIV_SHIFT 6
+#define OMAP_SYSCLKDIV_MASK (0x3 << 6)
+#define OMAP_AUTOEXTCLKMODE_SHIFT 3
+#define OMAP_AUTOEXTCLKMODE_MASK (0x3 << 3)
+#define OMAP_SYSCLKSEL_SHIFT 0
+#define OMAP_SYSCLKSEL_MASK (0x3 << 0)
+
+/* PM_EVGENCTRL_MPU */
+#define OMAP_OFFLOADMODE_SHIFT 3
+#define OMAP_OFFLOADMODE_MASK (0x3 << 3)
+#define OMAP_ONLOADMODE_SHIFT 1
+#define OMAP_ONLOADMODE_MASK (0x3 << 1)
+#define OMAP_ENABLE_MASK (1 << 0)
+
+/* PRM_RSTTIME */
+/* Named RM_RSTTIME_WKUP on the 24xx */
+#define OMAP_RSTTIME2_SHIFT 8
+#define OMAP_RSTTIME2_MASK (0x1f << 8)
+#define OMAP_RSTTIME1_SHIFT 0
+#define OMAP_RSTTIME1_MASK (0xff << 0)
+
+/* PRM_RSTCTRL */
+/* Named RM_RSTCTRL_WKUP on the 24xx */
+/* 2420 calls RST_DPLL3 'RST_DPLL' */
+#define OMAP_RST_DPLL3_MASK (1 << 2)
+#define OMAP_RST_GS_MASK (1 << 1)
+
+
+/*
+ * Bits common to module-shared registers
+ *
+ * Not all registers of a particular type support all of these bits -
+ * check TRM if you are unsure
+ */
+
+/*
+ * 24XX: RM_RSTST_MPU and RM_RSTST_DSP - on 24XX, 'COREDOMAINWKUP_RST' is
+ * called 'COREWKUP_RST'
+ *
+ * 3430: RM_RSTST_IVA2, RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSS,
+ * RM_RSTST_CAM, RM_RSTST_PER, RM_RSTST_NEON
+ */
+#define OMAP_COREDOMAINWKUP_RST_MASK (1 << 3)
+
+/*
+ * 24XX: RM_RSTST_MPU, RM_RSTST_GFX, RM_RSTST_DSP
+ *
+ * 2430: RM_RSTST_MDM
+ *
+ * 3430: RM_RSTST_CORE, RM_RSTST_EMU
+ */
+#define OMAP_DOMAINWKUP_RST_MASK (1 << 2)
+
+/*
+ * 24XX: RM_RSTST_MPU, RM_RSTST_WKUP, RM_RSTST_DSP
+ * On 24XX, 'GLOBALWARM_RST' is called 'GLOBALWMPU_RST'.
+ *
+ * 2430: RM_RSTST_MDM
+ *
+ * 3430: RM_RSTST_CORE, RM_RSTST_EMU
+ */
+#define OMAP_GLOBALWARM_RST_MASK (1 << 1)
+#define OMAP_GLOBALCOLD_RST_MASK (1 << 0)
+
+/*
+ * 24XX: PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_CORE, PM_WKDEP_DSP
+ * 2420 TRM sometimes uses "EN_WAKEUP" instead of "EN_WKUP"
+ *
+ * 2430: PM_WKDEP_MDM
+ *
+ * 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM,
+ * PM_WKDEP_PER
+ */
+#define OMAP_EN_WKUP_SHIFT 4
+#define OMAP_EN_WKUP_MASK (1 << 4)
+
+/*
+ * 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
+ * PM_PWSTCTRL_DSP
+ *
+ * 2430: PM_PWSTCTRL_MDM
+ *
+ * 3430: PM_PWSTCTRL_IVA2, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
+ * PM_PWSTCTRL_DSS, PM_PWSTCTRL_CAM, PM_PWSTCTRL_PER,
+ * PM_PWSTCTRL_NEON
+ */
+#define OMAP_LOGICRETSTATE_MASK (1 << 2)
+
+
+/*
+ * MAX_MODULE_HARDRESET_WAIT: Maximum microseconds to wait for an OMAP
+ * submodule to exit hardreset
+ */
+#define MAX_MODULE_HARDRESET_WAIT 10000
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
new file mode 100644
index 00000000..a2a04bfa
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -0,0 +1,195 @@
+/*
+ * OMAP4 PRM module functions
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ * Benoît Cousson
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+#include <plat/prcm.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+
+/*
+ * Address offset (in bytes) between the reset control and the reset
+ * status registers: 4 bytes on OMAP4
+ */
+#define OMAP4_RST_CTRL_ST_OFFSET 4
+
+/* PRM low-level functions */
+
+/* Read a register in a CM/PRM instance in the PRM module */
+u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
+{
+ return __raw_readl(OMAP44XX_PRM_REGADDR(inst, reg));
+}
+
+/* Write into a register in a CM/PRM instance in the PRM module */
+void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
+{
+ __raw_writel(val, OMAP44XX_PRM_REGADDR(inst, reg));
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
+{
+ u32 v;
+
+ v = omap4_prm_read_inst_reg(inst, reg);
+ v &= ~mask;
+ v |= bits;
+ omap4_prm_write_inst_reg(v, inst, reg);
+
+ return v;
+}
+
+/* Read a PRM register, AND it, and shift the result down to bit 0 */
+/* XXX deprecated */
+u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+/* Read-modify-write a register in a PRM module. Caller must lock */
+/* XXX deprecated */
+u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg)
+{
+ u32 v;
+
+ v = __raw_readl(reg);
+ v &= ~mask;
+ v |= bits;
+ __raw_writel(v, reg);
+
+ return v;
+}
+
+u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 reg)
+{
+ return omap4_prm_rmw_inst_reg_bits(bits, bits, inst, reg);
+}
+
+u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 reg)
+{
+ return omap4_prm_rmw_inst_reg_bits(bits, 0x0, inst, reg);
+}
+
+/**
+ * omap4_prm_is_hardreset_asserted - read the HW reset line state of
+ * submodules contained in the hwmod module
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to check
+ *
+ * Returns 1 if the (sub)module hardreset line is currently asserted,
+ * 0 if the (sub)module hardreset line is not currently asserted, or
+ * -EINVAL upon parameter error.
+ */
+int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift)
+{
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ return omap4_prm_read_bits_shift(rstctrl_reg, (1 << shift));
+}
+
+/**
+ * omap4_prm_assert_hardreset - assert the HW reset line of a submodule
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to assert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * place the submodule into reset. Returns 0 upon success or -EINVAL
+ * upon an argument error.
+ */
+int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift)
+{
+ u32 mask;
+
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ mask = 1 << shift;
+ omap4_prm_rmw_reg_bits(mask, mask, rstctrl_reg);
+
+ return 0;
+}
+
+/**
+ * omap4_prm_deassert_hardreset - deassert a submodule hardreset line and wait
+ * @rstctrl_reg: RM_RSTCTRL register address for this module
+ * @shift: register bit shift corresponding to the reset line to deassert
+ *
+ * Some IPs like dsp, ipu or iva contain processors that require an HW
+ * reset line to be asserted / deasserted in order to fully enable the
+ * IP. These modules may have multiple hard-reset lines that reset
+ * different 'submodules' inside the IP block. This function will
+ * take the submodule out of reset and wait until the PRCM indicates
+ * that the reset has completed before returning. Returns 0 upon success or
+ * -EINVAL upon an argument error, -EEXIST if the submodule was already out
+ * of reset, or -EBUSY if the submodule did not exit reset promptly.
+ */
+int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift)
+{
+ u32 mask;
+ void __iomem *rstst_reg;
+ int c;
+
+ if (!cpu_is_omap44xx() || !rstctrl_reg)
+ return -EINVAL;
+
+ rstst_reg = rstctrl_reg + OMAP4_RST_CTRL_ST_OFFSET;
+
+ mask = 1 << shift;
+
+ /* Check the current status to avoid de-asserting the line twice */
+ if (omap4_prm_read_bits_shift(rstctrl_reg, mask) == 0)
+ return -EEXIST;
+
+ /* Clear the reset status by writing 1 to the status bit */
+ omap4_prm_rmw_reg_bits(0xffffffff, mask, rstst_reg);
+ /* de-assert the reset control line */
+ omap4_prm_rmw_reg_bits(mask, 0, rstctrl_reg);
+ /* wait the status to be set */
+ omap_test_timeout(omap4_prm_read_bits_shift(rstst_reg, mask),
+ MAX_MODULE_HARDRESET_WAIT, c);
+
+ return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
+}
+
+void omap4_prm_global_warm_sw_reset(void)
+{
+ u32 v;
+
+ v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+ v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
+ omap4_prm_write_inst_reg(v, OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+
+ /* OCP barrier */
+ v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
+ OMAP4_RM_RSTCTRL);
+}
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
new file mode 100644
index 00000000..67a0d3fe
--- /dev/null
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -0,0 +1,778 @@
+/*
+ * OMAP44xx PRM instance offset macros
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Paul Walmsley (paul@pwsan.com)
+ * Rajendra Nayak (rnayak@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * XXX This file needs to be updated to align on one of "OMAP4", "OMAP44XX",
+ * or "OMAP4430".
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_PRM44XX_H
+#define __ARCH_ARM_MACH_OMAP2_PRM44XX_H
+
+#include "prcm-common.h"
+#include "prm.h"
+
+#define OMAP4430_PRM_BASE 0x4a306000
+
+#define OMAP44XX_PRM_REGADDR(inst, reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE + (inst) + (reg))
+
+
+/* PRM instances */
+#define OMAP4430_PRM_OCP_SOCKET_INST 0x0000
+#define OMAP4430_PRM_CKGEN_INST 0x0100
+#define OMAP4430_PRM_MPU_INST 0x0300
+#define OMAP4430_PRM_TESLA_INST 0x0400
+#define OMAP4430_PRM_ABE_INST 0x0500
+#define OMAP4430_PRM_ALWAYS_ON_INST 0x0600
+#define OMAP4430_PRM_CORE_INST 0x0700
+#define OMAP4430_PRM_IVAHD_INST 0x0f00
+#define OMAP4430_PRM_CAM_INST 0x1000
+#define OMAP4430_PRM_DSS_INST 0x1100
+#define OMAP4430_PRM_GFX_INST 0x1200
+#define OMAP4430_PRM_L3INIT_INST 0x1300
+#define OMAP4430_PRM_L4PER_INST 0x1400
+#define OMAP4430_PRM_CEFUSE_INST 0x1600
+#define OMAP4430_PRM_WKUP_INST 0x1700
+#define OMAP4430_PRM_WKUP_CM_INST 0x1800
+#define OMAP4430_PRM_EMU_INST 0x1900
+#define OMAP4430_PRM_EMU_CM_INST 0x1a00
+#define OMAP4430_PRM_DEVICE_INST 0x1b00
+#define OMAP4430_PRM_INSTR_INST 0x1f00
+
+/* PRM clockdomain register offsets (from instance start) */
+#define OMAP4430_PRM_MPU_MPU_CDOFFS 0x0000
+#define OMAP4430_PRM_TESLA_TESLA_CDOFFS 0x0000
+#define OMAP4430_PRM_ABE_ABE_CDOFFS 0x0000
+#define OMAP4430_PRM_CORE_CORE_CDOFFS 0x0000
+#define OMAP4430_PRM_IVAHD_IVAHD_CDOFFS 0x0000
+#define OMAP4430_PRM_CAM_CAM_CDOFFS 0x0000
+#define OMAP4430_PRM_DSS_DSS_CDOFFS 0x0000
+#define OMAP4430_PRM_GFX_GFX_CDOFFS 0x0000
+#define OMAP4430_PRM_L3INIT_L3INIT_CDOFFS 0x0000
+#define OMAP4430_PRM_L4PER_L4PER_CDOFFS 0x0000
+#define OMAP4430_PRM_CEFUSE_CEFUSE_CDOFFS 0x0000
+#define OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS 0x0000
+#define OMAP4430_PRM_EMU_EMU_CDOFFS 0x0000
+#define OMAP4430_PRM_EMU_CM_EMU_CDOFFS 0x0000
+
+/* OMAP4 specific register offsets */
+#define OMAP4_RM_RSTCTRL 0x0000
+#define OMAP4_RM_RSTTIME 0x0004
+#define OMAP4_RM_RSTST 0x0008
+#define OMAP4_PM_PWSTCTRL 0x0000
+#define OMAP4_PM_PWSTST 0x0004
+
+
+/* PRM */
+
+/* PRM.OCP_SOCKET_PRM register offsets */
+#define OMAP4_REVISION_PRM_OFFSET 0x0000
+#define OMAP4430_REVISION_PRM OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0000)
+#define OMAP4_PRM_IRQSTATUS_MPU_OFFSET 0x0010
+#define OMAP4430_PRM_IRQSTATUS_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0010)
+#define OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET 0x0014
+#define OMAP4430_PRM_IRQSTATUS_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0014)
+#define OMAP4_PRM_IRQENABLE_MPU_OFFSET 0x0018
+#define OMAP4430_PRM_IRQENABLE_MPU OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0018)
+#define OMAP4_PRM_IRQENABLE_MPU_2_OFFSET 0x001c
+#define OMAP4430_PRM_IRQENABLE_MPU_2 OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x001c)
+#define OMAP4_PRM_IRQSTATUS_DUCATI_OFFSET 0x0020
+#define OMAP4430_PRM_IRQSTATUS_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0020)
+#define OMAP4_PRM_IRQENABLE_DUCATI_OFFSET 0x0028
+#define OMAP4430_PRM_IRQENABLE_DUCATI OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0028)
+#define OMAP4_PRM_IRQSTATUS_TESLA_OFFSET 0x0030
+#define OMAP4430_PRM_IRQSTATUS_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0030)
+#define OMAP4_PRM_IRQENABLE_TESLA_OFFSET 0x0038
+#define OMAP4430_PRM_IRQENABLE_TESLA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0038)
+#define OMAP4_CM_PRM_PROFILING_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_PRM_PROFILING_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_OCP_SOCKET_INST, 0x0040)
+
+/* PRM.CKGEN_PRM register offsets */
+#define OMAP4_CM_ABE_DSS_SYS_CLKSEL_OFFSET 0x0000
+#define OMAP4430_CM_ABE_DSS_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0000)
+#define OMAP4_CM_L4_WKUP_CLKSEL_OFFSET 0x0008
+#define OMAP4430_CM_L4_WKUP_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0008)
+#define OMAP4_CM_ABE_PLL_REF_CLKSEL_OFFSET 0x000c
+#define OMAP4430_CM_ABE_PLL_REF_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x000c)
+#define OMAP4_CM_SYS_CLKSEL_OFFSET 0x0010
+#define OMAP4430_CM_SYS_CLKSEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CKGEN_INST, 0x0010)
+
+/* PRM.MPU_PRM register offsets */
+#define OMAP4_PM_MPU_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_MPU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0000)
+#define OMAP4_PM_MPU_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_MPU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0004)
+#define OMAP4_RM_MPU_RSTST_OFFSET 0x0014
+#define OMAP4430_RM_MPU_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0014)
+#define OMAP4_RM_MPU_MPU_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_MPU_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_MPU_INST, 0x0024)
+
+/* PRM.TESLA_PRM register offsets */
+#define OMAP4_PM_TESLA_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_TESLA_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0000)
+#define OMAP4_PM_TESLA_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_TESLA_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0004)
+#define OMAP4_RM_TESLA_RSTCTRL_OFFSET 0x0010
+#define OMAP4430_RM_TESLA_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0010)
+#define OMAP4_RM_TESLA_RSTST_OFFSET 0x0014
+#define OMAP4430_RM_TESLA_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0014)
+#define OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_TESLA_TESLA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_TESLA_INST, 0x0024)
+
+/* PRM.ABE_PRM register offsets */
+#define OMAP4_PM_ABE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_ABE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0000)
+#define OMAP4_PM_ABE_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_ABE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0004)
+#define OMAP4_RM_ABE_AESS_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_ABE_AESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x002c)
+#define OMAP4_PM_ABE_PDM_WKDEP_OFFSET 0x0030
+#define OMAP4430_PM_ABE_PDM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0030)
+#define OMAP4_RM_ABE_PDM_CONTEXT_OFFSET 0x0034
+#define OMAP4430_RM_ABE_PDM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0034)
+#define OMAP4_PM_ABE_DMIC_WKDEP_OFFSET 0x0038
+#define OMAP4430_PM_ABE_DMIC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0038)
+#define OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET 0x003c
+#define OMAP4430_RM_ABE_DMIC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x003c)
+#define OMAP4_PM_ABE_MCASP_WKDEP_OFFSET 0x0040
+#define OMAP4430_PM_ABE_MCASP_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0040)
+#define OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET 0x0044
+#define OMAP4430_RM_ABE_MCASP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0044)
+#define OMAP4_PM_ABE_MCBSP1_WKDEP_OFFSET 0x0048
+#define OMAP4430_PM_ABE_MCBSP1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0048)
+#define OMAP4_RM_ABE_MCBSP1_CONTEXT_OFFSET 0x004c
+#define OMAP4430_RM_ABE_MCBSP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x004c)
+#define OMAP4_PM_ABE_MCBSP2_WKDEP_OFFSET 0x0050
+#define OMAP4430_PM_ABE_MCBSP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0050)
+#define OMAP4_RM_ABE_MCBSP2_CONTEXT_OFFSET 0x0054
+#define OMAP4430_RM_ABE_MCBSP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0054)
+#define OMAP4_PM_ABE_MCBSP3_WKDEP_OFFSET 0x0058
+#define OMAP4430_PM_ABE_MCBSP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0058)
+#define OMAP4_RM_ABE_MCBSP3_CONTEXT_OFFSET 0x005c
+#define OMAP4430_RM_ABE_MCBSP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x005c)
+#define OMAP4_PM_ABE_SLIMBUS_WKDEP_OFFSET 0x0060
+#define OMAP4430_PM_ABE_SLIMBUS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0060)
+#define OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET 0x0064
+#define OMAP4430_RM_ABE_SLIMBUS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0064)
+#define OMAP4_PM_ABE_TIMER5_WKDEP_OFFSET 0x0068
+#define OMAP4430_PM_ABE_TIMER5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0068)
+#define OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET 0x006c
+#define OMAP4430_RM_ABE_TIMER5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x006c)
+#define OMAP4_PM_ABE_TIMER6_WKDEP_OFFSET 0x0070
+#define OMAP4430_PM_ABE_TIMER6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0070)
+#define OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET 0x0074
+#define OMAP4430_RM_ABE_TIMER6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0074)
+#define OMAP4_PM_ABE_TIMER7_WKDEP_OFFSET 0x0078
+#define OMAP4430_PM_ABE_TIMER7_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0078)
+#define OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET 0x007c
+#define OMAP4430_RM_ABE_TIMER7_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x007c)
+#define OMAP4_PM_ABE_TIMER8_WKDEP_OFFSET 0x0080
+#define OMAP4430_PM_ABE_TIMER8_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0080)
+#define OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET 0x0084
+#define OMAP4430_RM_ABE_TIMER8_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0084)
+#define OMAP4_PM_ABE_WDT3_WKDEP_OFFSET 0x0088
+#define OMAP4430_PM_ABE_WDT3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x0088)
+#define OMAP4_RM_ABE_WDT3_CONTEXT_OFFSET 0x008c
+#define OMAP4430_RM_ABE_WDT3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ABE_INST, 0x008c)
+
+/* PRM.ALWAYS_ON_PRM register offsets */
+#define OMAP4_RM_ALWON_MDMINTC_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_ALWON_MDMINTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0024)
+#define OMAP4_PM_ALWON_SR_MPU_WKDEP_OFFSET 0x0028
+#define OMAP4430_PM_ALWON_SR_MPU_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0028)
+#define OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_ALWON_SR_MPU_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x002c)
+#define OMAP4_PM_ALWON_SR_IVA_WKDEP_OFFSET 0x0030
+#define OMAP4430_PM_ALWON_SR_IVA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0030)
+#define OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET 0x0034
+#define OMAP4430_RM_ALWON_SR_IVA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0034)
+#define OMAP4_PM_ALWON_SR_CORE_WKDEP_OFFSET 0x0038
+#define OMAP4430_PM_ALWON_SR_CORE_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x0038)
+#define OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET 0x003c
+#define OMAP4430_RM_ALWON_SR_CORE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_ALWAYS_ON_INST, 0x003c)
+
+/* PRM.CORE_PRM register offsets */
+#define OMAP4_PM_CORE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CORE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0000)
+#define OMAP4_PM_CORE_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CORE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0004)
+#define OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_L3_1_L3_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0024)
+#define OMAP4_RM_L3_2_L3_2_CONTEXT_OFFSET 0x0124
+#define OMAP4430_RM_L3_2_L3_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0124)
+#define OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET 0x012c
+#define OMAP4430_RM_L3_2_GPMC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x012c)
+#define OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET 0x0134
+#define OMAP4430_RM_L3_2_OCMC_RAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0134)
+#define OMAP4_RM_DUCATI_RSTCTRL_OFFSET 0x0210
+#define OMAP4430_RM_DUCATI_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0210)
+#define OMAP4_RM_DUCATI_RSTST_OFFSET 0x0214
+#define OMAP4430_RM_DUCATI_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0214)
+#define OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET 0x0224
+#define OMAP4430_RM_DUCATI_DUCATI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0224)
+#define OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET 0x0324
+#define OMAP4430_RM_SDMA_SDMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0324)
+#define OMAP4_RM_MEMIF_DMM_CONTEXT_OFFSET 0x0424
+#define OMAP4430_RM_MEMIF_DMM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0424)
+#define OMAP4_RM_MEMIF_EMIF_FW_CONTEXT_OFFSET 0x042c
+#define OMAP4430_RM_MEMIF_EMIF_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x042c)
+#define OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET 0x0434
+#define OMAP4430_RM_MEMIF_EMIF_1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0434)
+#define OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET 0x043c
+#define OMAP4430_RM_MEMIF_EMIF_2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x043c)
+#define OMAP4_RM_MEMIF_DLL_CONTEXT_OFFSET 0x0444
+#define OMAP4430_RM_MEMIF_DLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0444)
+#define OMAP4_RM_MEMIF_EMIF_H1_CONTEXT_OFFSET 0x0454
+#define OMAP4430_RM_MEMIF_EMIF_H1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0454)
+#define OMAP4_RM_MEMIF_EMIF_H2_CONTEXT_OFFSET 0x045c
+#define OMAP4430_RM_MEMIF_EMIF_H2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x045c)
+#define OMAP4_RM_MEMIF_DLL_H_CONTEXT_OFFSET 0x0464
+#define OMAP4430_RM_MEMIF_DLL_H_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0464)
+#define OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET 0x0524
+#define OMAP4430_RM_D2D_SAD2D_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0524)
+#define OMAP4_RM_D2D_INSTEM_ICR_CONTEXT_OFFSET 0x052c
+#define OMAP4430_RM_D2D_INSTEM_ICR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x052c)
+#define OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET 0x0534
+#define OMAP4430_RM_D2D_SAD2D_FW_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0534)
+#define OMAP4_RM_L4CFG_L4_CFG_CONTEXT_OFFSET 0x0624
+#define OMAP4430_RM_L4CFG_L4_CFG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0624)
+#define OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET 0x062c
+#define OMAP4430_RM_L4CFG_HW_SEM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x062c)
+#define OMAP4_RM_L4CFG_MAILBOX_CONTEXT_OFFSET 0x0634
+#define OMAP4430_RM_L4CFG_MAILBOX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0634)
+#define OMAP4_RM_L4CFG_SAR_ROM_CONTEXT_OFFSET 0x063c
+#define OMAP4430_RM_L4CFG_SAR_ROM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x063c)
+#define OMAP4_RM_L3INSTR_L3_3_CONTEXT_OFFSET 0x0724
+#define OMAP4430_RM_L3INSTR_L3_3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0724)
+#define OMAP4_RM_L3INSTR_L3_INSTR_CONTEXT_OFFSET 0x072c
+#define OMAP4430_RM_L3INSTR_L3_INSTR_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x072c)
+#define OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET 0x0744
+#define OMAP4430_RM_L3INSTR_OCP_WP1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CORE_INST, 0x0744)
+
+/* PRM.IVAHD_PRM register offsets */
+#define OMAP4_PM_IVAHD_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_IVAHD_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0000)
+#define OMAP4_PM_IVAHD_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_IVAHD_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0004)
+#define OMAP4_RM_IVAHD_RSTCTRL_OFFSET 0x0010
+#define OMAP4430_RM_IVAHD_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0010)
+#define OMAP4_RM_IVAHD_RSTST_OFFSET 0x0014
+#define OMAP4430_RM_IVAHD_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0014)
+#define OMAP4_RM_IVAHD_IVAHD_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_IVAHD_IVAHD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x0024)
+#define OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_IVAHD_SL2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_IVAHD_INST, 0x002c)
+
+/* PRM.CAM_PRM register offsets */
+#define OMAP4_PM_CAM_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CAM_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0000)
+#define OMAP4_PM_CAM_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CAM_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0004)
+#define OMAP4_RM_CAM_ISS_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_CAM_ISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x0024)
+#define OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_CAM_FDIF_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CAM_INST, 0x002c)
+
+/* PRM.DSS_PRM register offsets */
+#define OMAP4_PM_DSS_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_DSS_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0000)
+#define OMAP4_PM_DSS_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_DSS_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0004)
+#define OMAP4_PM_DSS_DSS_WKDEP_OFFSET 0x0020
+#define OMAP4430_PM_DSS_DSS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0020)
+#define OMAP4_RM_DSS_DSS_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_DSS_DSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x0024)
+#define OMAP4_RM_DSS_DEISS_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_DSS_DEISS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DSS_INST, 0x002c)
+
+/* PRM.GFX_PRM register offsets */
+#define OMAP4_PM_GFX_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_GFX_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0000)
+#define OMAP4_PM_GFX_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_GFX_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0004)
+#define OMAP4_RM_GFX_GFX_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_GFX_GFX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_GFX_INST, 0x0024)
+
+/* PRM.L3INIT_PRM register offsets */
+#define OMAP4_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_L3INIT_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0000)
+#define OMAP4_PM_L3INIT_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_L3INIT_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0004)
+#define OMAP4_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028
+#define OMAP4430_PM_L3INIT_MMC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0028)
+#define OMAP4_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_L3INIT_MMC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x002c)
+#define OMAP4_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030
+#define OMAP4430_PM_L3INIT_MMC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0030)
+#define OMAP4_RM_L3INIT_MMC2_CONTEXT_OFFSET 0x0034
+#define OMAP4430_RM_L3INIT_MMC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0034)
+#define OMAP4_PM_L3INIT_HSI_WKDEP_OFFSET 0x0038
+#define OMAP4430_PM_L3INIT_HSI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0038)
+#define OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET 0x003c
+#define OMAP4430_RM_L3INIT_HSI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x003c)
+#define OMAP4_PM_L3INIT_UNIPRO1_WKDEP_OFFSET 0x0040
+#define OMAP4430_PM_L3INIT_UNIPRO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0040)
+#define OMAP4_RM_L3INIT_UNIPRO1_CONTEXT_OFFSET 0x0044
+#define OMAP4430_RM_L3INIT_UNIPRO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0044)
+#define OMAP4_PM_L3INIT_USB_HOST_WKDEP_OFFSET 0x0058
+#define OMAP4430_PM_L3INIT_USB_HOST_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0058)
+#define OMAP4_RM_L3INIT_USB_HOST_CONTEXT_OFFSET 0x005c
+#define OMAP4430_RM_L3INIT_USB_HOST_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x005c)
+#define OMAP4_PM_L3INIT_USB_OTG_WKDEP_OFFSET 0x0060
+#define OMAP4430_PM_L3INIT_USB_OTG_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0060)
+#define OMAP4_RM_L3INIT_USB_OTG_CONTEXT_OFFSET 0x0064
+#define OMAP4430_RM_L3INIT_USB_OTG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0064)
+#define OMAP4_PM_L3INIT_USB_TLL_WKDEP_OFFSET 0x0068
+#define OMAP4430_PM_L3INIT_USB_TLL_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0068)
+#define OMAP4_RM_L3INIT_USB_TLL_CONTEXT_OFFSET 0x006c
+#define OMAP4430_RM_L3INIT_USB_TLL_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x006c)
+#define OMAP4_RM_L3INIT_P1500_CONTEXT_OFFSET 0x007c
+#define OMAP4430_RM_L3INIT_P1500_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x007c)
+#define OMAP4_RM_L3INIT_EMAC_CONTEXT_OFFSET 0x0084
+#define OMAP4430_RM_L3INIT_EMAC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0084)
+#define OMAP4_PM_L3INIT_SATA_WKDEP_OFFSET 0x0088
+#define OMAP4430_PM_L3INIT_SATA_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0088)
+#define OMAP4_RM_L3INIT_SATA_CONTEXT_OFFSET 0x008c
+#define OMAP4430_RM_L3INIT_SATA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x008c)
+#define OMAP4_RM_L3INIT_TPPSS_CONTEXT_OFFSET 0x0094
+#define OMAP4430_RM_L3INIT_TPPSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0094)
+#define OMAP4_PM_L3INIT_PCIESS_WKDEP_OFFSET 0x0098
+#define OMAP4430_PM_L3INIT_PCIESS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x0098)
+#define OMAP4_RM_L3INIT_PCIESS_CONTEXT_OFFSET 0x009c
+#define OMAP4430_RM_L3INIT_PCIESS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x009c)
+#define OMAP4_RM_L3INIT_CCPTX_CONTEXT_OFFSET 0x00ac
+#define OMAP4430_RM_L3INIT_CCPTX_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00ac)
+#define OMAP4_PM_L3INIT_XHPI_WKDEP_OFFSET 0x00c0
+#define OMAP4430_PM_L3INIT_XHPI_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c0)
+#define OMAP4_RM_L3INIT_XHPI_CONTEXT_OFFSET 0x00c4
+#define OMAP4430_RM_L3INIT_XHPI_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c4)
+#define OMAP4_PM_L3INIT_MMC6_WKDEP_OFFSET 0x00c8
+#define OMAP4430_PM_L3INIT_MMC6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00c8)
+#define OMAP4_RM_L3INIT_MMC6_CONTEXT_OFFSET 0x00cc
+#define OMAP4430_RM_L3INIT_MMC6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00cc)
+#define OMAP4_PM_L3INIT_USB_HOST_FS_WKDEP_OFFSET 0x00d0
+#define OMAP4430_PM_L3INIT_USB_HOST_FS_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d0)
+#define OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET 0x00d4
+#define OMAP4430_RM_L3INIT_USB_HOST_FS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00d4)
+#define OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET 0x00e4
+#define OMAP4430_RM_L3INIT_USBPHYOCP2SCP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L3INIT_INST, 0x00e4)
+
+/* PRM.L4PER_PRM register offsets */
+#define OMAP4_PM_L4PER_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_L4PER_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0000)
+#define OMAP4_PM_L4PER_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_L4PER_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0004)
+#define OMAP4_RM_L4PER_ADC_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_L4PER_ADC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0024)
+#define OMAP4_PM_L4PER_DMTIMER10_WKDEP_OFFSET 0x0028
+#define OMAP4430_PM_L4PER_DMTIMER10_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0028)
+#define OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_L4PER_DMTIMER10_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x002c)
+#define OMAP4_PM_L4PER_DMTIMER11_WKDEP_OFFSET 0x0030
+#define OMAP4430_PM_L4PER_DMTIMER11_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0030)
+#define OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET 0x0034
+#define OMAP4430_RM_L4PER_DMTIMER11_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0034)
+#define OMAP4_PM_L4PER_DMTIMER2_WKDEP_OFFSET 0x0038
+#define OMAP4430_PM_L4PER_DMTIMER2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0038)
+#define OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET 0x003c
+#define OMAP4430_RM_L4PER_DMTIMER2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x003c)
+#define OMAP4_PM_L4PER_DMTIMER3_WKDEP_OFFSET 0x0040
+#define OMAP4430_PM_L4PER_DMTIMER3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0040)
+#define OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET 0x0044
+#define OMAP4430_RM_L4PER_DMTIMER3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0044)
+#define OMAP4_PM_L4PER_DMTIMER4_WKDEP_OFFSET 0x0048
+#define OMAP4430_PM_L4PER_DMTIMER4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0048)
+#define OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET 0x004c
+#define OMAP4430_RM_L4PER_DMTIMER4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x004c)
+#define OMAP4_PM_L4PER_DMTIMER9_WKDEP_OFFSET 0x0050
+#define OMAP4430_PM_L4PER_DMTIMER9_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0050)
+#define OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET 0x0054
+#define OMAP4430_RM_L4PER_DMTIMER9_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0054)
+#define OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET 0x005c
+#define OMAP4430_RM_L4PER_ELM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x005c)
+#define OMAP4_PM_L4PER_GPIO2_WKDEP_OFFSET 0x0060
+#define OMAP4430_PM_L4PER_GPIO2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0060)
+#define OMAP4_RM_L4PER_GPIO2_CONTEXT_OFFSET 0x0064
+#define OMAP4430_RM_L4PER_GPIO2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0064)
+#define OMAP4_PM_L4PER_GPIO3_WKDEP_OFFSET 0x0068
+#define OMAP4430_PM_L4PER_GPIO3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0068)
+#define OMAP4_RM_L4PER_GPIO3_CONTEXT_OFFSET 0x006c
+#define OMAP4430_RM_L4PER_GPIO3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x006c)
+#define OMAP4_PM_L4PER_GPIO4_WKDEP_OFFSET 0x0070
+#define OMAP4430_PM_L4PER_GPIO4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0070)
+#define OMAP4_RM_L4PER_GPIO4_CONTEXT_OFFSET 0x0074
+#define OMAP4430_RM_L4PER_GPIO4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0074)
+#define OMAP4_PM_L4PER_GPIO5_WKDEP_OFFSET 0x0078
+#define OMAP4430_PM_L4PER_GPIO5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0078)
+#define OMAP4_RM_L4PER_GPIO5_CONTEXT_OFFSET 0x007c
+#define OMAP4430_RM_L4PER_GPIO5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x007c)
+#define OMAP4_PM_L4PER_GPIO6_WKDEP_OFFSET 0x0080
+#define OMAP4430_PM_L4PER_GPIO6_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0080)
+#define OMAP4_RM_L4PER_GPIO6_CONTEXT_OFFSET 0x0084
+#define OMAP4430_RM_L4PER_GPIO6_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0084)
+#define OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET 0x008c
+#define OMAP4430_RM_L4PER_HDQ1W_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x008c)
+#define OMAP4_PM_L4PER_HECC1_WKDEP_OFFSET 0x0090
+#define OMAP4430_PM_L4PER_HECC1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0090)
+#define OMAP4_RM_L4PER_HECC1_CONTEXT_OFFSET 0x0094
+#define OMAP4430_RM_L4PER_HECC1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0094)
+#define OMAP4_PM_L4PER_HECC2_WKDEP_OFFSET 0x0098
+#define OMAP4430_PM_L4PER_HECC2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0098)
+#define OMAP4_RM_L4PER_HECC2_CONTEXT_OFFSET 0x009c
+#define OMAP4430_RM_L4PER_HECC2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x009c)
+#define OMAP4_PM_L4PER_I2C1_WKDEP_OFFSET 0x00a0
+#define OMAP4430_PM_L4PER_I2C1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a0)
+#define OMAP4_RM_L4PER_I2C1_CONTEXT_OFFSET 0x00a4
+#define OMAP4430_RM_L4PER_I2C1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a4)
+#define OMAP4_PM_L4PER_I2C2_WKDEP_OFFSET 0x00a8
+#define OMAP4430_PM_L4PER_I2C2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00a8)
+#define OMAP4_RM_L4PER_I2C2_CONTEXT_OFFSET 0x00ac
+#define OMAP4430_RM_L4PER_I2C2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ac)
+#define OMAP4_PM_L4PER_I2C3_WKDEP_OFFSET 0x00b0
+#define OMAP4430_PM_L4PER_I2C3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b0)
+#define OMAP4_RM_L4PER_I2C3_CONTEXT_OFFSET 0x00b4
+#define OMAP4430_RM_L4PER_I2C3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b4)
+#define OMAP4_PM_L4PER_I2C4_WKDEP_OFFSET 0x00b8
+#define OMAP4430_PM_L4PER_I2C4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00b8)
+#define OMAP4_RM_L4PER_I2C4_CONTEXT_OFFSET 0x00bc
+#define OMAP4430_RM_L4PER_I2C4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00bc)
+#define OMAP4_RM_L4PER_L4_PER_CONTEXT_OFFSET 0x00c0
+#define OMAP4430_RM_L4PER_L4_PER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00c0)
+#define OMAP4_PM_L4PER_MCASP2_WKDEP_OFFSET 0x00d0
+#define OMAP4430_PM_L4PER_MCASP2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d0)
+#define OMAP4_RM_L4PER_MCASP2_CONTEXT_OFFSET 0x00d4
+#define OMAP4430_RM_L4PER_MCASP2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d4)
+#define OMAP4_PM_L4PER_MCASP3_WKDEP_OFFSET 0x00d8
+#define OMAP4430_PM_L4PER_MCASP3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00d8)
+#define OMAP4_RM_L4PER_MCASP3_CONTEXT_OFFSET 0x00dc
+#define OMAP4430_RM_L4PER_MCASP3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00dc)
+#define OMAP4_PM_L4PER_MCBSP4_WKDEP_OFFSET 0x00e0
+#define OMAP4430_PM_L4PER_MCBSP4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e0)
+#define OMAP4_RM_L4PER_MCBSP4_CONTEXT_OFFSET 0x00e4
+#define OMAP4430_RM_L4PER_MCBSP4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00e4)
+#define OMAP4_RM_L4PER_MGATE_CONTEXT_OFFSET 0x00ec
+#define OMAP4430_RM_L4PER_MGATE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00ec)
+#define OMAP4_PM_L4PER_MCSPI1_WKDEP_OFFSET 0x00f0
+#define OMAP4430_PM_L4PER_MCSPI1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f0)
+#define OMAP4_RM_L4PER_MCSPI1_CONTEXT_OFFSET 0x00f4
+#define OMAP4430_RM_L4PER_MCSPI1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f4)
+#define OMAP4_PM_L4PER_MCSPI2_WKDEP_OFFSET 0x00f8
+#define OMAP4430_PM_L4PER_MCSPI2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00f8)
+#define OMAP4_RM_L4PER_MCSPI2_CONTEXT_OFFSET 0x00fc
+#define OMAP4430_RM_L4PER_MCSPI2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x00fc)
+#define OMAP4_PM_L4PER_MCSPI3_WKDEP_OFFSET 0x0100
+#define OMAP4430_PM_L4PER_MCSPI3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0100)
+#define OMAP4_RM_L4PER_MCSPI3_CONTEXT_OFFSET 0x0104
+#define OMAP4430_RM_L4PER_MCSPI3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0104)
+#define OMAP4_PM_L4PER_MCSPI4_WKDEP_OFFSET 0x0108
+#define OMAP4430_PM_L4PER_MCSPI4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0108)
+#define OMAP4_RM_L4PER_MCSPI4_CONTEXT_OFFSET 0x010c
+#define OMAP4430_RM_L4PER_MCSPI4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x010c)
+#define OMAP4_PM_L4PER_MMCSD3_WKDEP_OFFSET 0x0120
+#define OMAP4430_PM_L4PER_MMCSD3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0120)
+#define OMAP4_RM_L4PER_MMCSD3_CONTEXT_OFFSET 0x0124
+#define OMAP4430_RM_L4PER_MMCSD3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0124)
+#define OMAP4_PM_L4PER_MMCSD4_WKDEP_OFFSET 0x0128
+#define OMAP4430_PM_L4PER_MMCSD4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0128)
+#define OMAP4_RM_L4PER_MMCSD4_CONTEXT_OFFSET 0x012c
+#define OMAP4430_RM_L4PER_MMCSD4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x012c)
+#define OMAP4_RM_L4PER_MSPROHG_CONTEXT_OFFSET 0x0134
+#define OMAP4430_RM_L4PER_MSPROHG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0134)
+#define OMAP4_PM_L4PER_SLIMBUS2_WKDEP_OFFSET 0x0138
+#define OMAP4430_PM_L4PER_SLIMBUS2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0138)
+#define OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET 0x013c
+#define OMAP4430_RM_L4PER_SLIMBUS2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x013c)
+#define OMAP4_PM_L4PER_UART1_WKDEP_OFFSET 0x0140
+#define OMAP4430_PM_L4PER_UART1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0140)
+#define OMAP4_RM_L4PER_UART1_CONTEXT_OFFSET 0x0144
+#define OMAP4430_RM_L4PER_UART1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0144)
+#define OMAP4_PM_L4PER_UART2_WKDEP_OFFSET 0x0148
+#define OMAP4430_PM_L4PER_UART2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0148)
+#define OMAP4_RM_L4PER_UART2_CONTEXT_OFFSET 0x014c
+#define OMAP4430_RM_L4PER_UART2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x014c)
+#define OMAP4_PM_L4PER_UART3_WKDEP_OFFSET 0x0150
+#define OMAP4430_PM_L4PER_UART3_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0150)
+#define OMAP4_RM_L4PER_UART3_CONTEXT_OFFSET 0x0154
+#define OMAP4430_RM_L4PER_UART3_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0154)
+#define OMAP4_PM_L4PER_UART4_WKDEP_OFFSET 0x0158
+#define OMAP4430_PM_L4PER_UART4_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0158)
+#define OMAP4_RM_L4PER_UART4_CONTEXT_OFFSET 0x015c
+#define OMAP4430_RM_L4PER_UART4_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x015c)
+#define OMAP4_PM_L4PER_MMCSD5_WKDEP_OFFSET 0x0160
+#define OMAP4430_PM_L4PER_MMCSD5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0160)
+#define OMAP4_RM_L4PER_MMCSD5_CONTEXT_OFFSET 0x0164
+#define OMAP4430_RM_L4PER_MMCSD5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0164)
+#define OMAP4_PM_L4PER_I2C5_WKDEP_OFFSET 0x0168
+#define OMAP4430_PM_L4PER_I2C5_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x0168)
+#define OMAP4_RM_L4PER_I2C5_CONTEXT_OFFSET 0x016c
+#define OMAP4430_RM_L4PER_I2C5_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x016c)
+#define OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET 0x01a4
+#define OMAP4430_RM_L4SEC_AES1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01a4)
+#define OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET 0x01ac
+#define OMAP4430_RM_L4SEC_AES2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01ac)
+#define OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET 0x01b4
+#define OMAP4430_RM_L4SEC_DES3DES_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01b4)
+#define OMAP4_RM_L4SEC_PKAEIP29_CONTEXT_OFFSET 0x01bc
+#define OMAP4430_RM_L4SEC_PKAEIP29_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01bc)
+#define OMAP4_RM_L4SEC_RNG_CONTEXT_OFFSET 0x01c4
+#define OMAP4430_RM_L4SEC_RNG_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01c4)
+#define OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET 0x01cc
+#define OMAP4430_RM_L4SEC_SHA2MD51_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01cc)
+#define OMAP4_RM_L4SEC_CRYPTODMA_CONTEXT_OFFSET 0x01dc
+#define OMAP4430_RM_L4SEC_CRYPTODMA_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_L4PER_INST, 0x01dc)
+
+/* PRM.CEFUSE_PRM register offsets */
+#define OMAP4_PM_CEFUSE_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_CEFUSE_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0000)
+#define OMAP4_PM_CEFUSE_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_CEFUSE_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0004)
+#define OMAP4_RM_CEFUSE_CEFUSE_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_CEFUSE_CEFUSE_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_CEFUSE_INST, 0x0024)
+
+/* PRM.WKUP_PRM register offsets */
+#define OMAP4_RM_WKUP_L4WKUP_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_WKUP_L4WKUP_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0024)
+#define OMAP4_RM_WKUP_WDT1_CONTEXT_OFFSET 0x002c
+#define OMAP4430_RM_WKUP_WDT1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x002c)
+#define OMAP4_PM_WKUP_WDT2_WKDEP_OFFSET 0x0030
+#define OMAP4430_PM_WKUP_WDT2_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0030)
+#define OMAP4_RM_WKUP_WDT2_CONTEXT_OFFSET 0x0034
+#define OMAP4430_RM_WKUP_WDT2_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0034)
+#define OMAP4_PM_WKUP_GPIO1_WKDEP_OFFSET 0x0038
+#define OMAP4430_PM_WKUP_GPIO1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0038)
+#define OMAP4_RM_WKUP_GPIO1_CONTEXT_OFFSET 0x003c
+#define OMAP4430_RM_WKUP_GPIO1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x003c)
+#define OMAP4_PM_WKUP_TIMER1_WKDEP_OFFSET 0x0040
+#define OMAP4430_PM_WKUP_TIMER1_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0040)
+#define OMAP4_RM_WKUP_TIMER1_CONTEXT_OFFSET 0x0044
+#define OMAP4430_RM_WKUP_TIMER1_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0044)
+#define OMAP4_PM_WKUP_TIMER12_WKDEP_OFFSET 0x0048
+#define OMAP4430_PM_WKUP_TIMER12_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0048)
+#define OMAP4_RM_WKUP_TIMER12_CONTEXT_OFFSET 0x004c
+#define OMAP4430_RM_WKUP_TIMER12_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x004c)
+#define OMAP4_RM_WKUP_SYNCTIMER_CONTEXT_OFFSET 0x0054
+#define OMAP4430_RM_WKUP_SYNCTIMER_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0054)
+#define OMAP4_PM_WKUP_USIM_WKDEP_OFFSET 0x0058
+#define OMAP4430_PM_WKUP_USIM_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0058)
+#define OMAP4_RM_WKUP_USIM_CONTEXT_OFFSET 0x005c
+#define OMAP4430_RM_WKUP_USIM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x005c)
+#define OMAP4_RM_WKUP_SARRAM_CONTEXT_OFFSET 0x0064
+#define OMAP4430_RM_WKUP_SARRAM_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0064)
+#define OMAP4_PM_WKUP_KEYBOARD_WKDEP_OFFSET 0x0078
+#define OMAP4430_PM_WKUP_KEYBOARD_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0078)
+#define OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET 0x007c
+#define OMAP4430_RM_WKUP_KEYBOARD_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x007c)
+#define OMAP4_PM_WKUP_RTC_WKDEP_OFFSET 0x0080
+#define OMAP4430_PM_WKUP_RTC_WKDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0080)
+#define OMAP4_RM_WKUP_RTC_CONTEXT_OFFSET 0x0084
+#define OMAP4430_RM_WKUP_RTC_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_INST, 0x0084)
+
+/* PRM.WKUP_CM register offsets */
+#define OMAP4_CM_WKUP_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_WKUP_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0000)
+#define OMAP4_CM_WKUP_L4WKUP_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_WKUP_L4WKUP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0020)
+#define OMAP4_CM_WKUP_WDT1_CLKCTRL_OFFSET 0x0028
+#define OMAP4430_CM_WKUP_WDT1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0028)
+#define OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET 0x0030
+#define OMAP4430_CM_WKUP_WDT2_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0030)
+#define OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET 0x0038
+#define OMAP4430_CM_WKUP_GPIO1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0038)
+#define OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET 0x0040
+#define OMAP4430_CM_WKUP_TIMER1_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0040)
+#define OMAP4_CM_WKUP_TIMER12_CLKCTRL_OFFSET 0x0048
+#define OMAP4430_CM_WKUP_TIMER12_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0048)
+#define OMAP4_CM_WKUP_SYNCTIMER_CLKCTRL_OFFSET 0x0050
+#define OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0050)
+#define OMAP4_CM_WKUP_USIM_CLKCTRL_OFFSET 0x0058
+#define OMAP4430_CM_WKUP_USIM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0058)
+#define OMAP4_CM_WKUP_SARRAM_CLKCTRL_OFFSET 0x0060
+#define OMAP4430_CM_WKUP_SARRAM_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0060)
+#define OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET 0x0078
+#define OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0078)
+#define OMAP4_CM_WKUP_RTC_CLKCTRL_OFFSET 0x0080
+#define OMAP4430_CM_WKUP_RTC_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0080)
+#define OMAP4_CM_WKUP_BANDGAP_CLKCTRL_OFFSET 0x0088
+#define OMAP4430_CM_WKUP_BANDGAP_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_WKUP_CM_INST, 0x0088)
+
+/* PRM.EMU_PRM register offsets */
+#define OMAP4_PM_EMU_PWRSTCTRL_OFFSET 0x0000
+#define OMAP4430_PM_EMU_PWRSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0000)
+#define OMAP4_PM_EMU_PWRSTST_OFFSET 0x0004
+#define OMAP4430_PM_EMU_PWRSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0004)
+#define OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET 0x0024
+#define OMAP4430_RM_EMU_DEBUGSS_CONTEXT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_INST, 0x0024)
+
+/* PRM.EMU_CM register offsets */
+#define OMAP4_CM_EMU_CLKSTCTRL_OFFSET 0x0000
+#define OMAP4430_CM_EMU_CLKSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0000)
+#define OMAP4_CM_EMU_DYNAMICDEP_OFFSET 0x0008
+#define OMAP4430_CM_EMU_DYNAMICDEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0008)
+#define OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET 0x0020
+#define OMAP4430_CM_EMU_DEBUGSS_CLKCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_EMU_CM_INST, 0x0020)
+
+/* PRM.DEVICE_PRM register offsets */
+#define OMAP4_PRM_RSTCTRL_OFFSET 0x0000
+#define OMAP4430_PRM_RSTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0000)
+#define OMAP4_PRM_RSTST_OFFSET 0x0004
+#define OMAP4430_PRM_RSTST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0004)
+#define OMAP4_PRM_RSTTIME_OFFSET 0x0008
+#define OMAP4430_PRM_RSTTIME OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0008)
+#define OMAP4_PRM_CLKREQCTRL_OFFSET 0x000c
+#define OMAP4430_PRM_CLKREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x000c)
+#define OMAP4_PRM_VOLTCTRL_OFFSET 0x0010
+#define OMAP4430_PRM_VOLTCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0010)
+#define OMAP4_PRM_PWRREQCTRL_OFFSET 0x0014
+#define OMAP4430_PRM_PWRREQCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0014)
+#define OMAP4_PRM_PSCON_COUNT_OFFSET 0x0018
+#define OMAP4430_PRM_PSCON_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0018)
+#define OMAP4_PRM_IO_COUNT_OFFSET 0x001c
+#define OMAP4430_PRM_IO_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x001c)
+#define OMAP4_PRM_IO_PMCTRL_OFFSET 0x0020
+#define OMAP4430_PRM_IO_PMCTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0020)
+#define OMAP4_PRM_VOLTSETUP_WARMRESET_OFFSET 0x0024
+#define OMAP4430_PRM_VOLTSETUP_WARMRESET OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0024)
+#define OMAP4_PRM_VOLTSETUP_CORE_OFF_OFFSET 0x0028
+#define OMAP4430_PRM_VOLTSETUP_CORE_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0028)
+#define OMAP4_PRM_VOLTSETUP_MPU_OFF_OFFSET 0x002c
+#define OMAP4430_PRM_VOLTSETUP_MPU_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x002c)
+#define OMAP4_PRM_VOLTSETUP_IVA_OFF_OFFSET 0x0030
+#define OMAP4430_PRM_VOLTSETUP_IVA_OFF OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0030)
+#define OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET 0x0034
+#define OMAP4430_PRM_VOLTSETUP_CORE_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0034)
+#define OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET 0x0038
+#define OMAP4430_PRM_VOLTSETUP_MPU_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0038)
+#define OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET 0x003c
+#define OMAP4430_PRM_VOLTSETUP_IVA_RET_SLEEP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x003c)
+#define OMAP4_PRM_VP_CORE_CONFIG_OFFSET 0x0040
+#define OMAP4430_PRM_VP_CORE_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0040)
+#define OMAP4_PRM_VP_CORE_STATUS_OFFSET 0x0044
+#define OMAP4430_PRM_VP_CORE_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0044)
+#define OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET 0x0048
+#define OMAP4430_PRM_VP_CORE_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0048)
+#define OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET 0x004c
+#define OMAP4430_PRM_VP_CORE_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x004c)
+#define OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET 0x0050
+#define OMAP4430_PRM_VP_CORE_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0050)
+#define OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET 0x0054
+#define OMAP4430_PRM_VP_CORE_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0054)
+#define OMAP4_PRM_VP_MPU_CONFIG_OFFSET 0x0058
+#define OMAP4430_PRM_VP_MPU_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0058)
+#define OMAP4_PRM_VP_MPU_STATUS_OFFSET 0x005c
+#define OMAP4430_PRM_VP_MPU_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x005c)
+#define OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET 0x0060
+#define OMAP4430_PRM_VP_MPU_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0060)
+#define OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET 0x0064
+#define OMAP4430_PRM_VP_MPU_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0064)
+#define OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET 0x0068
+#define OMAP4430_PRM_VP_MPU_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0068)
+#define OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET 0x006c
+#define OMAP4430_PRM_VP_MPU_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x006c)
+#define OMAP4_PRM_VP_IVA_CONFIG_OFFSET 0x0070
+#define OMAP4430_PRM_VP_IVA_CONFIG OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0070)
+#define OMAP4_PRM_VP_IVA_STATUS_OFFSET 0x0074
+#define OMAP4430_PRM_VP_IVA_STATUS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0074)
+#define OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET 0x0078
+#define OMAP4430_PRM_VP_IVA_VLIMITTO OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0078)
+#define OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET 0x007c
+#define OMAP4430_PRM_VP_IVA_VOLTAGE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x007c)
+#define OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET 0x0080
+#define OMAP4430_PRM_VP_IVA_VSTEPMAX OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0080)
+#define OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET 0x0084
+#define OMAP4430_PRM_VP_IVA_VSTEPMIN OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0084)
+#define OMAP4_PRM_VC_SMPS_SA_OFFSET 0x0088
+#define OMAP4430_PRM_VC_SMPS_SA OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0088)
+#define OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET 0x008c
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_VOL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x008c)
+#define OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET 0x0090
+#define OMAP4430_PRM_VC_VAL_SMPS_RA_CMD OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0090)
+#define OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET 0x0094
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_CORE_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0094)
+#define OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET 0x0098
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_MPU_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x0098)
+#define OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET 0x009c
+#define OMAP4430_PRM_VC_VAL_CMD_VDD_IVA_L OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x009c)
+#define OMAP4_PRM_VC_VAL_BYPASS_OFFSET 0x00a0
+#define OMAP4430_PRM_VC_VAL_BYPASS OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a0)
+#define OMAP4_PRM_VC_CFG_CHANNEL_OFFSET 0x00a4
+#define OMAP4430_PRM_VC_CFG_CHANNEL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a4)
+#define OMAP4_PRM_VC_CFG_I2C_INSTE_OFFSET 0x00a8
+#define OMAP4430_PRM_VC_CFG_I2C_INSTE OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00a8)
+#define OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET 0x00ac
+#define OMAP4430_PRM_VC_CFG_I2C_CLK OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ac)
+#define OMAP4_PRM_SRAM_COUNT_OFFSET 0x00b0
+#define OMAP4430_PRM_SRAM_COUNT OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b0)
+#define OMAP4_PRM_SRAM_WKUP_SETUP_OFFSET 0x00b4
+#define OMAP4430_PRM_SRAM_WKUP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b4)
+#define OMAP4_PRM_LDO_SRAM_CORE_SETUP_OFFSET 0x00b8
+#define OMAP4430_PRM_LDO_SRAM_CORE_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00b8)
+#define OMAP4_PRM_LDO_SRAM_CORE_CTRL_OFFSET 0x00bc
+#define OMAP4430_PRM_LDO_SRAM_CORE_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00bc)
+#define OMAP4_PRM_LDO_SRAM_MPU_SETUP_OFFSET 0x00c0
+#define OMAP4430_PRM_LDO_SRAM_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c0)
+#define OMAP4_PRM_LDO_SRAM_MPU_CTRL_OFFSET 0x00c4
+#define OMAP4430_PRM_LDO_SRAM_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c4)
+#define OMAP4_PRM_LDO_SRAM_IVA_SETUP_OFFSET 0x00c8
+#define OMAP4430_PRM_LDO_SRAM_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00c8)
+#define OMAP4_PRM_LDO_SRAM_IVA_CTRL_OFFSET 0x00cc
+#define OMAP4430_PRM_LDO_SRAM_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00cc)
+#define OMAP4_PRM_LDO_ABB_MPU_SETUP_OFFSET 0x00d0
+#define OMAP4430_PRM_LDO_ABB_MPU_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d0)
+#define OMAP4_PRM_LDO_ABB_MPU_CTRL_OFFSET 0x00d4
+#define OMAP4430_PRM_LDO_ABB_MPU_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d4)
+#define OMAP4_PRM_LDO_ABB_IVA_SETUP_OFFSET 0x00d8
+#define OMAP4430_PRM_LDO_ABB_IVA_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00d8)
+#define OMAP4_PRM_LDO_ABB_IVA_CTRL_OFFSET 0x00dc
+#define OMAP4430_PRM_LDO_ABB_IVA_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00dc)
+#define OMAP4_PRM_LDO_BANDGAP_SETUP_OFFSET 0x00e0
+#define OMAP4430_PRM_LDO_BANDGAP_SETUP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e0)
+#define OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET 0x00e4
+#define OMAP4430_PRM_DEVICE_OFF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e4)
+#define OMAP4_PRM_PHASE1_CNDP_OFFSET 0x00e8
+#define OMAP4430_PRM_PHASE1_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00e8)
+#define OMAP4_PRM_PHASE2A_CNDP_OFFSET 0x00ec
+#define OMAP4430_PRM_PHASE2A_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00ec)
+#define OMAP4_PRM_PHASE2B_CNDP_OFFSET 0x00f0
+#define OMAP4430_PRM_PHASE2B_CNDP OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f0)
+#define OMAP4_PRM_INSTEM_IF_CTRL_OFFSET 0x00f4
+#define OMAP4430_PRM_INSTEM_IF_CTRL OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f4)
+#define OMAP4_PRM_VC_ERRST_OFFSET 0x00f8
+#define OMAP4430_PRM_VC_ERRST OMAP44XX_PRM_REGADDR(OMAP4430_PRM_DEVICE_INST, 0x00f8)
+
+/* Function prototypes */
+# ifndef __ASSEMBLER__
+
+extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
+extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
+extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *reg);
+extern u32 omap4_prm_set_inst_reg_bits(u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_clear_inst_reg_bits(u32 bits, s16 inst, s16 idx);
+extern u32 omap4_prm_read_bits_shift(void __iomem *reg, u32 mask);
+
+extern int omap4_prm_is_hardreset_asserted(void __iomem *rstctrl_reg, u8 shift);
+extern int omap4_prm_assert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+extern int omap4_prm_deassert_hardreset(void __iomem *rstctrl_reg, u8 shift);
+
+extern void omap4_prm_global_warm_sw_reset(void);
+
+# endif
+
+#endif
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
new file mode 100644
index 00000000..a3032429
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -0,0 +1,66 @@
+/*
+ * OMAP4 PRM instance functions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prminst44xx.h"
+#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prcm_mpu44xx.h"
+
+static u32 _prm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
+ [OMAP4430_INVALID_PRCM_PARTITION] = 0,
+ [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
+ [OMAP4430_CM1_PARTITION] = 0,
+ [OMAP4430_CM2_PARTITION] = 0,
+ [OMAP4430_SCRM_PARTITION] = 0,
+ [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
+};
+
+/* Read a register in a PRM instance */
+u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_prm_bases[part]);
+ return __raw_readl(OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst +
+ idx));
+}
+
+/* Write into a register in a PRM instance */
+void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx)
+{
+ BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
+ part == OMAP4430_INVALID_PRCM_PARTITION ||
+ !_prm_bases[part]);
+ __raw_writel(val, OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst + idx));
+}
+
+/* Read-modify-write a register in PRM. Caller must lock */
+u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst,
+ s16 idx)
+{
+ u32 v;
+
+ v = omap4_prminst_read_inst_reg(part, inst, idx);
+ v &= ~mask;
+ v |= bits;
+ omap4_prminst_write_inst_reg(v, part, inst, idx);
+
+ return v;
+}
diff --git a/arch/arm/mach-omap2/prminst44xx.h b/arch/arm/mach-omap2/prminst44xx.h
new file mode 100644
index 00000000..02dd66dd
--- /dev/null
+++ b/arch/arm/mach-omap2/prminst44xx.h
@@ -0,0 +1,25 @@
+/*
+ * OMAP4 Power/Reset Management (PRM) function prototypes
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
+#define __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
+
+/*
+ * In an ideal world, we would not export these low-level functions,
+ * but this will probably take some time to fix properly
+ */
+extern u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx);
+extern void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx);
+extern u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part,
+ s16 inst, s16 idx);
+
+extern void omap4_prm_global_warm_sw_reset(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/scrm44xx.h b/arch/arm/mach-omap2/scrm44xx.h
new file mode 100644
index 00000000..701bf2d3
--- /dev/null
+++ b/arch/arm/mach-omap2/scrm44xx.h
@@ -0,0 +1,175 @@
+/*
+ * OMAP44xx SCRM registers and bitfields
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H
+#define __ARCH_ARM_MACH_OMAP2_SCRM_44XX_H
+
+#define OMAP4_SCRM_BASE 0x4a30a000
+
+#define OMAP44XX_SCRM_REGADDR(reg) \
+ OMAP2_L4_IO_ADDRESS(OMAP4_SCRM_BASE + (reg))
+
+/* Registers offset */
+#define OMAP4_SCRM_REVISION_SCRM_OFFSET 0x0000
+#define OMAP4_SCRM_REVISION_SCRM OMAP44XX_SCRM_REGADDR(0x0000)
+#define OMAP4_SCRM_CLKSETUPTIME_OFFSET 0x0100
+#define OMAP4_SCRM_CLKSETUPTIME OMAP44XX_SCRM_REGADDR(0x0100)
+#define OMAP4_SCRM_PMICSETUPTIME_OFFSET 0x0104
+#define OMAP4_SCRM_PMICSETUPTIME OMAP44XX_SCRM_REGADDR(0x0104)
+#define OMAP4_SCRM_ALTCLKSRC_OFFSET 0x0110
+#define OMAP4_SCRM_ALTCLKSRC OMAP44XX_SCRM_REGADDR(0x0110)
+#define OMAP4_SCRM_MODEMCLKM_OFFSET 0x0118
+#define OMAP4_SCRM_MODEMCLKM OMAP44XX_SCRM_REGADDR(0x0118)
+#define OMAP4_SCRM_D2DCLKM_OFFSET 0x011c
+#define OMAP4_SCRM_D2DCLKM OMAP44XX_SCRM_REGADDR(0x011c)
+#define OMAP4_SCRM_EXTCLKREQ_OFFSET 0x0200
+#define OMAP4_SCRM_EXTCLKREQ OMAP44XX_SCRM_REGADDR(0x0200)
+#define OMAP4_SCRM_ACCCLKREQ_OFFSET 0x0204
+#define OMAP4_SCRM_ACCCLKREQ OMAP44XX_SCRM_REGADDR(0x0204)
+#define OMAP4_SCRM_PWRREQ_OFFSET 0x0208
+#define OMAP4_SCRM_PWRREQ OMAP44XX_SCRM_REGADDR(0x0208)
+#define OMAP4_SCRM_AUXCLKREQ0_OFFSET 0x0210
+#define OMAP4_SCRM_AUXCLKREQ0 OMAP44XX_SCRM_REGADDR(0x0210)
+#define OMAP4_SCRM_AUXCLKREQ1_OFFSET 0x0214
+#define OMAP4_SCRM_AUXCLKREQ1 OMAP44XX_SCRM_REGADDR(0x0214)
+#define OMAP4_SCRM_AUXCLKREQ2_OFFSET 0x0218
+#define OMAP4_SCRM_AUXCLKREQ2 OMAP44XX_SCRM_REGADDR(0x0218)
+#define OMAP4_SCRM_AUXCLKREQ3_OFFSET 0x021c
+#define OMAP4_SCRM_AUXCLKREQ3 OMAP44XX_SCRM_REGADDR(0x021c)
+#define OMAP4_SCRM_AUXCLKREQ4_OFFSET 0x0220
+#define OMAP4_SCRM_AUXCLKREQ4 OMAP44XX_SCRM_REGADDR(0x0220)
+#define OMAP4_SCRM_AUXCLKREQ5_OFFSET 0x0224
+#define OMAP4_SCRM_AUXCLKREQ5 OMAP44XX_SCRM_REGADDR(0x0224)
+#define OMAP4_SCRM_D2DCLKREQ_OFFSET 0x0234
+#define OMAP4_SCRM_D2DCLKREQ OMAP44XX_SCRM_REGADDR(0x0234)
+#define OMAP4_SCRM_AUXCLK0_OFFSET 0x0310
+#define OMAP4_SCRM_AUXCLK0 OMAP44XX_SCRM_REGADDR(0x0310)
+#define OMAP4_SCRM_AUXCLK1_OFFSET 0x0314
+#define OMAP4_SCRM_AUXCLK1 OMAP44XX_SCRM_REGADDR(0x0314)
+#define OMAP4_SCRM_AUXCLK2_OFFSET 0x0318
+#define OMAP4_SCRM_AUXCLK2 OMAP44XX_SCRM_REGADDR(0x0318)
+#define OMAP4_SCRM_AUXCLK3_OFFSET 0x031c
+#define OMAP4_SCRM_AUXCLK3 OMAP44XX_SCRM_REGADDR(0x031c)
+#define OMAP4_SCRM_AUXCLK4_OFFSET 0x0320
+#define OMAP4_SCRM_AUXCLK4 OMAP44XX_SCRM_REGADDR(0x0320)
+#define OMAP4_SCRM_AUXCLK5_OFFSET 0x0324
+#define OMAP4_SCRM_AUXCLK5 OMAP44XX_SCRM_REGADDR(0x0324)
+#define OMAP4_SCRM_RSTTIME_OFFSET 0x0400
+#define OMAP4_SCRM_RSTTIME OMAP44XX_SCRM_REGADDR(0x0400)
+#define OMAP4_SCRM_MODEMRSTCTRL_OFFSET 0x0418
+#define OMAP4_SCRM_MODEMRSTCTRL OMAP44XX_SCRM_REGADDR(0x0418)
+#define OMAP4_SCRM_D2DRSTCTRL_OFFSET 0x041c
+#define OMAP4_SCRM_D2DRSTCTRL OMAP44XX_SCRM_REGADDR(0x041c)
+#define OMAP4_SCRM_EXTPWRONRSTCTRL_OFFSET 0x0420
+#define OMAP4_SCRM_EXTPWRONRSTCTRL OMAP44XX_SCRM_REGADDR(0x0420)
+#define OMAP4_SCRM_EXTWARMRSTST_OFFSET 0x0510
+#define OMAP4_SCRM_EXTWARMRSTST OMAP44XX_SCRM_REGADDR(0x0510)
+#define OMAP4_SCRM_APEWARMRSTST_OFFSET 0x0514
+#define OMAP4_SCRM_APEWARMRSTST OMAP44XX_SCRM_REGADDR(0x0514)
+#define OMAP4_SCRM_MODEMWARMRSTST_OFFSET 0x0518
+#define OMAP4_SCRM_MODEMWARMRSTST OMAP44XX_SCRM_REGADDR(0x0518)
+#define OMAP4_SCRM_D2DWARMRSTST_OFFSET 0x051c
+#define OMAP4_SCRM_D2DWARMRSTST OMAP44XX_SCRM_REGADDR(0x051c)
+
+/* Registers shifts and masks */
+
+/* REVISION_SCRM */
+#define OMAP4_REV_SHIFT 0
+#define OMAP4_REV_MASK (0xff << 0)
+
+/* CLKSETUPTIME */
+#define OMAP4_DOWNTIME_SHIFT 16
+#define OMAP4_DOWNTIME_MASK (0x3f << 16)
+#define OMAP4_SETUPTIME_SHIFT 0
+#define OMAP4_SETUPTIME_MASK (0xfff << 0)
+
+/* PMICSETUPTIME */
+#define OMAP4_WAKEUPTIME_SHIFT 16
+#define OMAP4_WAKEUPTIME_MASK (0x3f << 16)
+#define OMAP4_SLEEPTIME_SHIFT 0
+#define OMAP4_SLEEPTIME_MASK (0x3f << 0)
+
+/* ALTCLKSRC */
+#define OMAP4_ENABLE_EXT_SHIFT 3
+#define OMAP4_ENABLE_EXT_MASK (1 << 3)
+#define OMAP4_ENABLE_INT_SHIFT 2
+#define OMAP4_ENABLE_INT_MASK (1 << 2)
+#define OMAP4_ALTCLKSRC_MODE_SHIFT 0
+#define OMAP4_ALTCLKSRC_MODE_MASK (0x3 << 0)
+
+/* MODEMCLKM */
+#define OMAP4_CLK_32KHZ_SHIFT 0
+#define OMAP4_CLK_32KHZ_MASK (1 << 0)
+
+/* D2DCLKM */
+#define OMAP4_SYSCLK_SHIFT 1
+#define OMAP4_SYSCLK_MASK (1 << 1)
+
+/* EXTCLKREQ */
+#define OMAP4_POLARITY_SHIFT 0
+#define OMAP4_POLARITY_MASK (1 << 0)
+
+/* AUXCLKREQ0 */
+#define OMAP4_MAPPING_SHIFT 2
+#define OMAP4_MAPPING_MASK (0x7 << 2)
+#define OMAP4_ACCURACY_SHIFT 1
+#define OMAP4_ACCURACY_MASK (1 << 1)
+
+/* AUXCLK0 */
+#define OMAP4_CLKDIV_SHIFT 16
+#define OMAP4_CLKDIV_MASK (0xf << 16)
+#define OMAP4_DISABLECLK_SHIFT 9
+#define OMAP4_DISABLECLK_MASK (1 << 9)
+#define OMAP4_ENABLE_SHIFT 8
+#define OMAP4_ENABLE_MASK (1 << 8)
+#define OMAP4_SRCSELECT_SHIFT 1
+#define OMAP4_SRCSELECT_MASK (0x3 << 1)
+
+/* RSTTIME */
+#define OMAP4_RSTTIME_SHIFT 0
+#define OMAP4_RSTTIME_MASK (0xf << 0)
+
+/* MODEMRSTCTRL */
+#define OMAP4_WARMRST_SHIFT 1
+#define OMAP4_WARMRST_MASK (1 << 1)
+#define OMAP4_COLDRST_SHIFT 0
+#define OMAP4_COLDRST_MASK (1 << 0)
+
+/* EXTPWRONRSTCTRL */
+#define OMAP4_PWRONRST_SHIFT 1
+#define OMAP4_PWRONRST_MASK (1 << 1)
+#define OMAP4_ENABLE_EXTPWRONRSTCTRL_SHIFT 0
+#define OMAP4_ENABLE_EXTPWRONRSTCTRL_MASK (1 << 0)
+
+/* EXTWARMRSTST */
+#define OMAP4_EXTWARMRSTST_SHIFT 0
+#define OMAP4_EXTWARMRSTST_MASK (1 << 0)
+
+/* APEWARMRSTST */
+#define OMAP4_APEWARMRSTST_SHIFT 1
+#define OMAP4_APEWARMRSTST_MASK (1 << 1)
+
+/* MODEMWARMRSTST */
+#define OMAP4_MODEMWARMRSTST_SHIFT 2
+#define OMAP4_MODEMWARMRSTST_MASK (1 << 2)
+
+/* D2DWARMRSTST */
+#define OMAP4_D2DWARMRSTST_SHIFT 3
+#define OMAP4_D2DWARMRSTST_MASK (1 << 3)
+
+#endif
diff --git a/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h b/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h
new file mode 100644
index 00000000..8bfaf342
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-hynix-h8mbx00u0mer-0em.h
@@ -0,0 +1,51 @@
+/*
+ * SDRC register values for the Hynix H8MBX00U0MER-0EM
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
+#define __ARCH_ARM_MACH_OMAP2_SDRAM_HYNIX_H8MBX00U0MER0EM
+
+#include <plat/sdrc.h>
+
+/* Hynix H8MBX00U0MER-0EM */
+static struct omap_sdrc_params h8mbx00u0mer0em_sdrc_params[] = {
+ [0] = {
+ .rate = 200000000,
+ .actim_ctrla = 0xa2e1b4c6,
+ .actim_ctrlb = 0x0002131c,
+ .rfr_ctrl = 0x0005e601,
+ .mr = 0x00000032,
+ },
+ [1] = {
+ .rate = 166000000,
+ .actim_ctrla = 0x629db4c6,
+ .actim_ctrlb = 0x00012214,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [2] = {
+ .rate = 100000000,
+ .actim_ctrla = 0x51912284,
+ .actim_ctrlb = 0x0002120e,
+ .rfr_ctrl = 0x0002d101,
+ .mr = 0x00000022,
+ },
+ [3] = {
+ .rate = 83000000,
+ .actim_ctrla = 0x31512283,
+ .actim_ctrlb = 0x0001220a,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000022,
+ },
+ [4] = {
+ .rate = 0
+ },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
new file mode 100644
index 00000000..a391b493
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-micron-mt46h32m32lf-6.h
@@ -0,0 +1,55 @@
+/*
+ * SDRC register values for the Micron MT46H32M32LF-6
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
+#define ARCH_ARM_MACH_OMAP2_SDRAM_MICRON_MT46H32M32LF
+
+#include <plat/sdrc.h>
+
+/* Micron MT46H32M32LF-6 */
+/* XXX Using ARE = 0x1 (no autorefresh burst) -- can this be changed? */
+static struct omap_sdrc_params mt46h32m32lf6_sdrc_params[] = {
+ [0] = {
+ .rate = 166000000,
+ .actim_ctrla = 0x9a9db4c6,
+ .actim_ctrlb = 0x00011217,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [1] = {
+ .rate = 165941176,
+ .actim_ctrla = 0x9a9db4c6,
+ .actim_ctrlb = 0x00011217,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [2] = {
+ .rate = 83000000,
+ .actim_ctrla = 0x51512283,
+ .actim_ctrlb = 0x0001120c,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000032,
+ },
+ [3] = {
+ .rate = 82970588,
+ .actim_ctrla = 0x51512283,
+ .actim_ctrlb = 0x0001120c,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000032,
+ },
+ [4] = {
+ .rate = 0
+ },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c
new file mode 100644
index 00000000..14caa228
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-nokia.c
@@ -0,0 +1,279 @@
+/*
+ * SDRC register values for Nokia boards
+ *
+ * Copyright (C) 2008, 2010 Nokia Corporation
+ *
+ * Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ *
+ * Original code by Juha Yrjola <juha.yrjola@solidboot.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/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <plat/io.h>
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sdrc.h>
+
+#include "sdram-nokia.h"
+
+/* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */
+struct sdram_timings {
+ u32 casl;
+ u32 tDAL;
+ u32 tDPL;
+ u32 tRRD;
+ u32 tRCD;
+ u32 tRP;
+ u32 tRAS;
+ u32 tRC;
+ u32 tRFC;
+ u32 tXSR;
+
+ u32 tREF; /* in ns */
+
+ u32 tXP;
+ u32 tCKE;
+ u32 tWTR;
+};
+
+static const struct sdram_timings nokia_97dot6mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 30725,
+ .tDPL = 15362,
+ .tRRD = 10241,
+ .tRCD = 20483,
+ .tRP = 15362,
+ .tRAS = 40967,
+ .tRC = 56330,
+ .tRFC = 138266,
+ .tXSR = 204839,
+
+ .tREF = 7798,
+
+ .tXP = 2,
+ .tCKE = 4,
+ .tWTR = 2,
+ },
+};
+
+static const struct sdram_timings nokia_166mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 33000,
+ .tDPL = 15000,
+ .tRRD = 12000,
+ .tRCD = 22500,
+ .tRP = 18000,
+ .tRAS = 42000,
+ .tRC = 66000,
+ .tRFC = 138000,
+ .tXSR = 200000,
+
+ .tREF = 7800,
+
+ .tXP = 2,
+ .tCKE = 2,
+ .tWTR = 2
+ },
+};
+
+static const struct sdram_timings nokia_195dot2mhz_timings[] = {
+ {
+ .casl = 3,
+ .tDAL = 30725,
+ .tDPL = 15362,
+ .tRRD = 10241,
+ .tRCD = 20483,
+ .tRP = 15362,
+ .tRAS = 40967,
+ .tRC = 56330,
+ .tRFC = 138266,
+ .tXSR = 204839,
+
+ .tREF = 7752,
+
+ .tXP = 2,
+ .tCKE = 4,
+ .tWTR = 2,
+ },
+};
+
+static const struct {
+ long rate;
+ struct sdram_timings const *data;
+} nokia_timings[] = {
+ { 83000000, nokia_166mhz_timings },
+ { 97600000, nokia_97dot6mhz_timings },
+ { 166000000, nokia_166mhz_timings },
+ { 195200000, nokia_195dot2mhz_timings },
+};
+static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1];
+
+static unsigned long sdrc_get_fclk_period(long rate)
+{
+ /* In picoseconds */
+ return 1000000000 / rate;
+}
+
+static unsigned int sdrc_ps_to_ticks(unsigned int time_ps, long rate)
+{
+ unsigned long tick_ps;
+
+ /* Calculate in picosecs to yield more exact results */
+ tick_ps = sdrc_get_fclk_period(rate);
+
+ return (time_ps + tick_ps - 1) / tick_ps;
+}
+#undef DEBUG
+#ifdef DEBUG
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+ int ticks, long rate, const char *name)
+#else
+static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit,
+ int ticks)
+#endif
+{
+ int mask, nr_bits;
+
+ nr_bits = end_bit - st_bit + 1;
+ if (ticks >= 1 << nr_bits)
+ return -1;
+ mask = (1 << nr_bits) - 1;
+ *regval &= ~(mask << st_bit);
+ *regval |= ticks << st_bit;
+#ifdef DEBUG
+ printk(KERN_INFO "SDRC %s: %i ticks %i ns\n", name, ticks,
+ (unsigned int)sdrc_get_fclk_period(rate) * ticks /
+ 1000);
+#endif
+
+ return 0;
+}
+
+#ifdef DEBUG
+#define SDRC_SET_ONE(reg, st, end, field, rate) \
+ if (set_sdrc_timing_regval((reg), (st), (end), \
+ memory_timings->field, (rate), #field) < 0) \
+ err = -1;
+#else
+#define SDRC_SET_ONE(reg, st, end, field, rate) \
+ if (set_sdrc_timing_regval((reg), (st), (end), \
+ memory_timings->field) < 0) \
+ err = -1;
+#endif
+
+#ifdef DEBUG
+static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
+ int time, long rate, const char *name)
+#else
+static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit,
+ int time, long rate)
+#endif
+{
+ int ticks, ret;
+ ret = 0;
+
+ if (time == 0)
+ ticks = 0;
+ else
+ ticks = sdrc_ps_to_ticks(time, rate);
+
+#ifdef DEBUG
+ ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks,
+ rate, name);
+#else
+ ret = set_sdrc_timing_regval(regval, st_bit, end_bit, ticks);
+#endif
+
+ return ret;
+}
+
+#ifdef DEBUG
+#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
+ if (set_sdrc_timing_regval_ps((reg), (st), (end), \
+ memory_timings->field, \
+ (rate), #field) < 0) \
+ err = -1;
+
+#else
+#define SDRC_SET_ONE_PS(reg, st, end, field, rate) \
+ if (set_sdrc_timing_regval_ps((reg), (st), (end), \
+ memory_timings->field, (rate)) < 0) \
+ err = -1;
+#endif
+
+static int sdrc_timings(int id, long rate,
+ const struct sdram_timings *memory_timings)
+{
+ u32 ticks_per_ms;
+ u32 rfr, l;
+ u32 actim_ctrla = 0, actim_ctrlb = 0;
+ u32 rfr_ctrl;
+ int err = 0;
+ long l3_rate = rate / 1000;
+
+ SDRC_SET_ONE_PS(&actim_ctrla, 0, 4, tDAL, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 6, 8, tDPL, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 9, 11, tRRD, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 12, 14, tRCD, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 15, 17, tRP, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 18, 21, tRAS, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 22, 26, tRC, l3_rate);
+ SDRC_SET_ONE_PS(&actim_ctrla, 27, 31, tRFC, l3_rate);
+
+ SDRC_SET_ONE_PS(&actim_ctrlb, 0, 7, tXSR, l3_rate);
+
+ SDRC_SET_ONE(&actim_ctrlb, 8, 10, tXP, l3_rate);
+ SDRC_SET_ONE(&actim_ctrlb, 12, 14, tCKE, l3_rate);
+ SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate);
+
+ ticks_per_ms = l3_rate;
+ rfr = memory_timings[0].tREF * ticks_per_ms / 1000000;
+ if (rfr > 65535 + 50)
+ rfr = 65535;
+ else
+ rfr -= 50;
+
+#ifdef DEBUG
+ printk(KERN_INFO "SDRC tREF: %i ticks\n", rfr);
+#endif
+
+ l = rfr << 8;
+ rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */
+
+ nokia_sdrc_params[id].rate = rate;
+ nokia_sdrc_params[id].actim_ctrla = actim_ctrla;
+ nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb;
+ nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl;
+ nokia_sdrc_params[id].mr = 0x32;
+
+ nokia_sdrc_params[id + 1].rate = 0;
+
+ return err;
+}
+
+struct omap_sdrc_params *nokia_get_sdram_timings(void)
+{
+ int err = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) {
+ err |= sdrc_timings(i, nokia_timings[i].rate,
+ nokia_timings[i].data);
+ if (err)
+ pr_err("%s: error with rate %ld: %d\n", __func__,
+ nokia_timings[i].rate, err);
+ }
+
+ return err ? NULL : nokia_sdrc_params;
+}
+
diff --git a/arch/arm/mach-omap2/sdram-nokia.h b/arch/arm/mach-omap2/sdram-nokia.h
new file mode 100644
index 00000000..ee63da5f
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-nokia.h
@@ -0,0 +1,12 @@
+/*
+ * SDRC register values for Nokia boards
+ *
+ * Copyright (C) 2010 Nokia
+ *
+ * This program is free software; you can 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 omap_sdrc_params *nokia_get_sdram_timings(void);
+
diff --git a/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h b/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h
new file mode 100644
index 00000000..cd435291
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-numonyx-m65kxxxxam.h
@@ -0,0 +1,51 @@
+/*
+ * SDRC register values for the Numonyx M65KXXXXAM
+ *
+ * Copyright (C) 2009 Integration Software and Electronic Engineering.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
+#define __ARCH_ARM_MACH_OMAP2_SDRAM_NUMONYX_M65KXXXXAM
+
+#include <plat/sdrc.h>
+
+/* Numonyx M65KXXXXAM */
+static struct omap_sdrc_params m65kxxxxam_sdrc_params[] = {
+ [0] = {
+ .rate = 200000000,
+ .actim_ctrla = 0xe321d4c6,
+ .actim_ctrlb = 0x00022328,
+ .rfr_ctrl = 0x0005e601,
+ .mr = 0x00000032,
+ },
+ [1] = {
+ .rate = 166000000,
+ .actim_ctrla = 0xba9dc485,
+ .actim_ctrlb = 0x00022321,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [2] = {
+ .rate = 133000000,
+ .actim_ctrla = 0x9a19b485,
+ .actim_ctrlb = 0x0002231b,
+ .rfr_ctrl = 0x0003de01,
+ .mr = 0x00000032,
+ },
+ [3] = {
+ .rate = 83000000,
+ .actim_ctrla = 0x594ca242,
+ .actim_ctrlb = 0x00022310,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000032,
+ },
+ [4] = {
+ .rate = 0
+ },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
new file mode 100644
index 00000000..0e518a72
--- /dev/null
+++ b/arch/arm/mach-omap2/sdram-qimonda-hyb18m512160af-6.h
@@ -0,0 +1,54 @@
+/*
+ * SDRC register values for the Qimonda HYB18M512160AF-6
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
+#define ARCH_ARM_MACH_OMAP2_SDRAM_QIMONDA_HYB18M512160AF6
+
+#include <plat/sdrc.h>
+
+/* Qimonda HYB18M512160AF-6 */
+static struct omap_sdrc_params hyb18m512160af6_sdrc_params[] = {
+ [0] = {
+ .rate = 166000000,
+ .actim_ctrla = 0x629db4c6,
+ .actim_ctrlb = 0x00012214,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [1] = {
+ .rate = 165941176,
+ .actim_ctrla = 0x629db4c6,
+ .actim_ctrlb = 0x00012214,
+ .rfr_ctrl = 0x0004dc01,
+ .mr = 0x00000032,
+ },
+ [2] = {
+ .rate = 83000000,
+ .actim_ctrla = 0x31512283,
+ .actim_ctrlb = 0x0001220a,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000022,
+ },
+ [3] = {
+ .rate = 82970588,
+ .actim_ctrla = 0x31512283,
+ .actim_ctrlb = 0x0001220a,
+ .rfr_ctrl = 0x00025501,
+ .mr = 0x00000022,
+ },
+ [4] = {
+ .rate = 0
+ },
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c
new file mode 100644
index 00000000..da6f3a63
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc.c
@@ -0,0 +1,183 @@
+/*
+ * SMS/SDRC (SDRAM controller) common code for OMAP2/3
+ *
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
+ *
+ * Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+
+#include <plat/sdrc.h>
+#include "sdrc.h"
+
+static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
+
+void __iomem *omap2_sdrc_base;
+void __iomem *omap2_sms_base;
+
+struct omap2_sms_regs {
+ u32 sms_sysconfig;
+};
+
+static struct omap2_sms_regs sms_context;
+
+/* SDRC_POWER register bits */
+#define SDRC_POWER_EXTCLKDIS_SHIFT 3
+#define SDRC_POWER_PWDENA_SHIFT 2
+#define SDRC_POWER_PAGEPOLICY_SHIFT 0
+
+/**
+ * omap2_sms_save_context - Save SMS registers
+ *
+ * Save SMS registers that need to be restored after off mode.
+ */
+void omap2_sms_save_context(void)
+{
+ sms_context.sms_sysconfig = sms_read_reg(SMS_SYSCONFIG);
+}
+
+/**
+ * omap2_sms_restore_context - Restore SMS registers
+ *
+ * Restore SMS registers that need to be Restored after off mode.
+ */
+void omap2_sms_restore_context(void)
+{
+ sms_write_reg(sms_context.sms_sysconfig, SMS_SYSCONFIG);
+}
+
+/**
+ * omap2_sdrc_get_params - return SDRC register values for a given clock rate
+ * @r: SDRC clock rate (in Hz)
+ * @sdrc_cs0: chip select 0 ram timings **
+ * @sdrc_cs1: chip select 1 ram timings **
+ *
+ * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
+ * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01]
+ * structs,for a given SDRC clock rate 'r'.
+ * These parameters control various timing delays in the SDRAM controller
+ * that are expressed in terms of the number of SDRC clock cycles to
+ * wait; hence the clock rate dependency.
+ *
+ * Supports 2 different timing parameters for both chip selects.
+ *
+ * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending.
+ * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size
+ * as sdrc_init_params_cs_0.
+ *
+ * Fills in the struct omap_sdrc_params * for each chip select.
+ * Returns 0 upon success or -1 upon failure.
+ */
+int omap2_sdrc_get_params(unsigned long r,
+ struct omap_sdrc_params **sdrc_cs0,
+ struct omap_sdrc_params **sdrc_cs1)
+{
+ struct omap_sdrc_params *sp0, *sp1;
+
+ if (!sdrc_init_params_cs0)
+ return -1;
+
+ sp0 = sdrc_init_params_cs0;
+ sp1 = sdrc_init_params_cs1;
+
+ while (sp0->rate && sp0->rate != r) {
+ sp0++;
+ if (sdrc_init_params_cs1)
+ sp1++;
+ }
+
+ if (!sp0->rate)
+ return -1;
+
+ *sdrc_cs0 = sp0;
+ *sdrc_cs1 = sp1;
+ return 0;
+}
+
+
+void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
+{
+ /* Static mapping, never released */
+ if (omap2_globals->sdrc) {
+ omap2_sdrc_base = ioremap(omap2_globals->sdrc, SZ_64K);
+ WARN_ON(!omap2_sdrc_base);
+ }
+ if (omap2_globals->sms) {
+ omap2_sms_base = ioremap(omap2_globals->sms, SZ_64K);
+ WARN_ON(!omap2_sms_base);
+ }
+}
+
+/**
+ * omap2_sdrc_init - initialize SMS, SDRC devices on boot
+ * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params
+ * Support for 2 chip selects timings
+ *
+ * Turn on smart idle modes for SDRAM scheduler and controller.
+ * Program a known-good configuration for the SDRC to deal with buggy
+ * bootloaders.
+ */
+void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1)
+{
+ u32 l;
+
+ l = sms_read_reg(SMS_SYSCONFIG);
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ sms_write_reg(l, SMS_SYSCONFIG);
+
+ l = sdrc_read_reg(SDRC_SYSCONFIG);
+ l &= ~(0x3 << 3);
+ l |= (0x2 << 3);
+ sdrc_write_reg(l, SDRC_SYSCONFIG);
+
+ sdrc_init_params_cs0 = sdrc_cs0;
+ sdrc_init_params_cs1 = sdrc_cs1;
+
+ /* XXX Enable SRFRONIDLEREQ here also? */
+ /*
+ * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
+ * can cause random memory corruption
+ */
+ l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
+ (1 << SDRC_POWER_PAGEPOLICY_SHIFT);
+ sdrc_write_reg(l, SDRC_POWER);
+ omap2_sms_save_context();
+}
+
+void omap2_sms_write_rot_control(u32 val, unsigned ctx)
+{
+ sms_write_reg(val, SMS_ROT_CONTROL(ctx));
+}
+
+void omap2_sms_write_rot_size(u32 val, unsigned ctx)
+{
+ sms_write_reg(val, SMS_ROT_SIZE(ctx));
+}
+
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx)
+{
+ sms_write_reg(val, SMS_ROT_PHYSICAL_BA(ctx));
+}
+
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h
new file mode 100644
index 00000000..b3f83799
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc.h
@@ -0,0 +1,77 @@
+#ifndef __ARCH_ARM_MACH_OMAP2_SDRC_H
+#define __ARCH_ARM_MACH_OMAP2_SDRC_H
+
+/*
+ * OMAP2 SDRC register definitions
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <plat/sdrc.h>
+
+#ifndef __ASSEMBLER__
+
+#include <linux/io.h>
+
+extern void __iomem *omap2_sdrc_base;
+extern void __iomem *omap2_sms_base;
+
+#define OMAP_SDRC_REGADDR(reg) (omap2_sdrc_base + (reg))
+#define OMAP_SMS_REGADDR(reg) (omap2_sms_base + (reg))
+
+/* SDRC global register get/set */
+
+static inline void sdrc_write_reg(u32 val, u16 reg)
+{
+ __raw_writel(val, OMAP_SDRC_REGADDR(reg));
+}
+
+static inline u32 sdrc_read_reg(u16 reg)
+{
+ return __raw_readl(OMAP_SDRC_REGADDR(reg));
+}
+
+/* SMS global register get/set */
+
+static inline void sms_write_reg(u32 val, u16 reg)
+{
+ __raw_writel(val, OMAP_SMS_REGADDR(reg));
+}
+
+static inline u32 sms_read_reg(u16 reg)
+{
+ return __raw_readl(OMAP_SMS_REGADDR(reg));
+}
+#else
+#define OMAP242X_SDRC_REGADDR(reg) \
+ OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE + (reg))
+#define OMAP243X_SDRC_REGADDR(reg) \
+ OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE + (reg))
+#define OMAP34XX_SDRC_REGADDR(reg) \
+ OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE + (reg))
+#endif /* __ASSEMBLER__ */
+
+/* Minimum frequency that the SDRC DLL can lock at */
+#define MIN_SDRC_DLL_LOCK_FREQ 83000000
+
+/* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */
+#define SDRC_MPURATE_SCALE 8
+
+/* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */
+#define SDRC_MPURATE_BASE_SHIFT 9
+
+/*
+ * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at
+ * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize
+ */
+#define SDRC_MPURATE_LOOPS 96
+
+#endif
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c
new file mode 100644
index 00000000..ccdb010f
--- /dev/null
+++ b/arch/arm/mach-omap2/sdrc2xxx.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-omap2/sdrc2xxx.c
+ *
+ * SDRAM timing related functions for OMAP2xxx
+ *
+ * Copyright (C) 2005, 2008 Texas Instruments Inc.
+ * Copyright (C) 2005, 2008 Nokia Corporation
+ *
+ * Tony Lindgren <tony@atomide.com>
+ * Paul Walmsley
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <plat/common.h>
+#include <plat/clock.h>
+#include <plat/sram.h>
+
+#include "prm2xxx_3xxx.h"
+#include "clock.h"
+#include <plat/sdrc.h>
+#include "sdrc.h"
+
+/* Memory timing, DLL mode flags */
+#define M_DDR 1
+#define M_LOCK_CTRL (1 << 2)
+#define M_UNLOCK 0
+#define M_LOCK 1
+
+
+static struct memory_timings mem_timings;
+static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2;
+
+static u32 omap2xxx_sdrc_get_slow_dll_ctrl(void)
+{
+ return mem_timings.slow_dll_ctrl;
+}
+
+static u32 omap2xxx_sdrc_get_fast_dll_ctrl(void)
+{
+ return mem_timings.fast_dll_ctrl;
+}
+
+static u32 omap2xxx_sdrc_get_type(void)
+{
+ return mem_timings.m_type;
+}
+
+/*
+ * Check the DLL lock state, and return tue if running in unlock mode.
+ * This is needed to compensate for the shifted DLL value in unlock mode.
+ */
+u32 omap2xxx_sdrc_dll_is_unlocked(void)
+{
+ /* dlla and dllb are a set */
+ u32 dll_state = sdrc_read_reg(SDRC_DLLA_CTRL);
+
+ if ((dll_state & (1 << 2)) == (1 << 2))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * 'level' is the value to store to CM_CLKSEL2_PLL.CORE_CLK_SRC.
+ * Practical values are CORE_CLK_SRC_DPLL (for CORE_CLK = DPLL_CLK) or
+ * CORE_CLK_SRC_DPLL_X2 (for CORE_CLK = * DPLL_CLK * 2)
+ *
+ * Used by the clock framework during CORE DPLL changes
+ */
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force)
+{
+ u32 dll_ctrl, m_type;
+ u32 prev = curr_perf_level;
+ unsigned long flags;
+
+ if ((curr_perf_level == level) && !force)
+ return prev;
+
+ if (level == CORE_CLK_SRC_DPLL)
+ dll_ctrl = omap2xxx_sdrc_get_slow_dll_ctrl();
+ else if (level == CORE_CLK_SRC_DPLL_X2)
+ dll_ctrl = omap2xxx_sdrc_get_fast_dll_ctrl();
+ else
+ return prev;
+
+ m_type = omap2xxx_sdrc_get_type();
+
+ local_irq_save(flags);
+ /*
+ * XXX These calls should be abstracted out through a
+ * prm2xxx.c function
+ */
+ if (cpu_is_omap2420())
+ __raw_writel(0xffff, OMAP2420_PRCM_VOLTSETUP);
+ else
+ __raw_writel(0xffff, OMAP2430_PRCM_VOLTSETUP);
+ omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type);
+ curr_perf_level = level;
+ local_irq_restore(flags);
+
+ return prev;
+}
+
+/* Used by the clock framework during CORE DPLL changes */
+void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode)
+{
+ unsigned long dll_cnt;
+ u32 fast_dll = 0;
+
+ /* DDR = 1, SDR = 0 */
+ mem_timings.m_type = !((sdrc_read_reg(SDRC_MR_0) & 0x3) == 0x1);
+
+ /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
+ * In the case of 2422, its ok to use CS1 instead of CS0.
+ */
+ if (cpu_is_omap2422())
+ mem_timings.base_cs = 1;
+ else
+ mem_timings.base_cs = 0;
+
+ if (mem_timings.m_type != M_DDR)
+ return;
+
+ /* With DDR we need to determine the low frequency DLL value */
+ if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
+ mem_timings.dll_mode = M_UNLOCK;
+ else
+ mem_timings.dll_mode = M_LOCK;
+
+ if (mem_timings.base_cs == 0) {
+ fast_dll = sdrc_read_reg(SDRC_DLLA_CTRL);
+ dll_cnt = sdrc_read_reg(SDRC_DLLA_STATUS) & 0xff00;
+ } else {
+ fast_dll = sdrc_read_reg(SDRC_DLLB_CTRL);
+ dll_cnt = sdrc_read_reg(SDRC_DLLB_STATUS) & 0xff00;
+ }
+ if (force_lock_to_unlock_mode) {
+ fast_dll &= ~0xff00;
+ fast_dll |= dll_cnt; /* Current lock mode */
+ }
+ /* set fast timings with DLL filter disabled */
+ mem_timings.fast_dll_ctrl = (fast_dll | (3 << 8));
+
+ /* No disruptions, DDR will be offline & C-ABI not followed */
+ omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
+ mem_timings.fast_dll_ctrl,
+ mem_timings.base_cs,
+ force_lock_to_unlock_mode);
+ mem_timings.slow_dll_ctrl &= 0xff00; /* Keep lock value */
+
+ /* Turn status into unlock ctrl */
+ mem_timings.slow_dll_ctrl |=
+ ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
+
+ /* 90 degree phase for anything below 133Mhz + disable DLL filter */
+ mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8));
+}
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
new file mode 100644
index 00000000..1ac361b7
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.c
@@ -0,0 +1,877 @@
+/*
+ * arch/arm/mach-omap2/serial.c
+ *
+ * OMAP2 serial support.
+ *
+ * Copyright (C) 2005-2008 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ *
+ * Major rework for PM support by Kevin Hilman
+ *
+ * Based off of arch/arm/mach-omap/omap1/serial.c
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/serial_reg.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/serial_8250.h>
+#include <linux/pm_runtime.h>
+#include <linux/console.h>
+
+#ifdef CONFIG_SERIAL_OMAP
+#include <plat/omap-serial.h>
+#endif
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/clock.h>
+#include <plat/dma.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+#include "prm2xxx_3xxx.h"
+#include "pm.h"
+#include "cm2xxx_3xxx.h"
+#include "prm-regbits-34xx.h"
+#include "control.h"
+#include "mux.h"
+
+#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
+#define UART_OMAP_WER 0x17 /* Wake-up enable register */
+
+#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
+#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
+
+/*
+ * NOTE: By default the serial timeout is disabled as it causes lost characters
+ * over the serial ports. This means that the UART clocks will stay on until
+ * disabled via sysfs. This also causes that any deeper omap sleep states are
+ * blocked.
+ */
+#define DEFAULT_TIMEOUT 0
+
+#define MAX_UART_HWMOD_NAME_LEN 16
+
+struct omap_uart_state {
+ int num;
+ int can_sleep;
+ struct timer_list timer;
+ u32 timeout;
+
+ void __iomem *wk_st;
+ void __iomem *wk_en;
+ u32 wk_mask;
+ u32 padconf;
+ u32 dma_enabled;
+
+ struct clk *ick;
+ struct clk *fck;
+ int clocked;
+
+ int irq;
+ int regshift;
+ int irqflags;
+ void __iomem *membase;
+ resource_size_t mapbase;
+
+ struct list_head node;
+ struct omap_hwmod *oh;
+ struct platform_device *pdev;
+
+ u32 errata;
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+ int context_valid;
+
+ /* Registers to be saved/restored for OFF-mode */
+ u16 dll;
+ u16 dlh;
+ u16 ier;
+ u16 sysc;
+ u16 scr;
+ u16 wer;
+ u16 mcr;
+#endif
+};
+
+static LIST_HEAD(uart_list);
+static u8 num_uarts;
+
+static int uart_idle_hwmod(struct omap_device *od)
+{
+ omap_hwmod_idle(od->hwmods[0]);
+
+ return 0;
+}
+
+static int uart_enable_hwmod(struct omap_device *od)
+{
+ omap_hwmod_enable(od->hwmods[0]);
+
+ return 0;
+}
+
+static struct omap_device_pm_latency omap_uart_latency[] = {
+ {
+ .deactivate_func = uart_idle_hwmod,
+ .activate_func = uart_enable_hwmod,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static inline unsigned int __serial_read_reg(struct uart_port *up,
+ int offset)
+{
+ offset <<= up->regshift;
+ return (unsigned int)__raw_readb(up->membase + offset);
+}
+
+static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
+ int offset)
+{
+ offset <<= uart->regshift;
+ return (unsigned int)__raw_readb(uart->membase + offset);
+}
+
+static inline void __serial_write_reg(struct uart_port *up, int offset,
+ int value)
+{
+ offset <<= up->regshift;
+ __raw_writeb(value, up->membase + offset);
+}
+
+static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
+ int value)
+{
+ offset <<= uart->regshift;
+ __raw_writeb(value, uart->membase + offset);
+}
+
+/*
+ * Internal UARTs need to be initialized for the 8250 autoconfig to work
+ * properly. Note that the TX watermark initialization may not be needed
+ * once the 8250.c watermark handling code is merged.
+ */
+
+static inline void __init omap_uart_reset(struct omap_uart_state *uart)
+{
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+ serial_write_reg(uart, UART_OMAP_SCR, 0x08);
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
+}
+
+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+
+/*
+ * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
+ * The access to uart register after MDR1 Access
+ * causes UART to corrupt data.
+ *
+ * Need a delay =
+ * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
+ * give 10 times as much
+ */
+static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
+ u8 fcr_val)
+{
+ u8 timeout = 255;
+
+ serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
+ udelay(2);
+ serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
+ UART_FCR_CLEAR_RCVR);
+ /*
+ * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+ * TX_FIFO_E bit is 1.
+ */
+ while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
+ (UART_LSR_THRE | UART_LSR_DR))) {
+ timeout--;
+ if (!timeout) {
+ /* Should *never* happen. we warn and carry on */
+ dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
+ serial_read_reg(uart, UART_LSR));
+ break;
+ }
+ udelay(1);
+ }
+}
+
+static void omap_uart_save_context(struct omap_uart_state *uart)
+{
+ u16 lcr = 0;
+
+ if (!enable_off_mode)
+ return;
+
+ lcr = serial_read_reg(uart, UART_LCR);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
+ uart->dll = serial_read_reg(uart, UART_DLL);
+ uart->dlh = serial_read_reg(uart, UART_DLM);
+ serial_write_reg(uart, UART_LCR, lcr);
+ uart->ier = serial_read_reg(uart, UART_IER);
+ uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
+ uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
+ uart->wer = serial_read_reg(uart, UART_OMAP_WER);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
+ uart->mcr = serial_read_reg(uart, UART_MCR);
+ serial_write_reg(uart, UART_LCR, lcr);
+
+ uart->context_valid = 1;
+}
+
+static void omap_uart_restore_context(struct omap_uart_state *uart)
+{
+ u16 efr = 0;
+
+ if (!enable_off_mode)
+ return;
+
+ if (!uart->context_valid)
+ return;
+
+ uart->context_valid = 0;
+
+ if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
+ omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
+ else
+ serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
+ efr = serial_read_reg(uart, UART_EFR);
+ serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
+ serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
+ serial_write_reg(uart, UART_IER, 0x0);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
+ serial_write_reg(uart, UART_DLL, uart->dll);
+ serial_write_reg(uart, UART_DLM, uart->dlh);
+ serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
+ serial_write_reg(uart, UART_IER, uart->ier);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
+ serial_write_reg(uart, UART_MCR, uart->mcr);
+ serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
+ serial_write_reg(uart, UART_EFR, efr);
+ serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
+ serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
+ serial_write_reg(uart, UART_OMAP_WER, uart->wer);
+ serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
+
+ if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
+ omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
+ else
+ /* UART 16x mode */
+ serial_write_reg(uart, UART_OMAP_MDR1,
+ UART_OMAP_MDR1_16X_MODE);
+}
+#else
+static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
+static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
+#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
+
+static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
+{
+ if (uart->clocked)
+ return;
+
+ omap_device_enable(uart->pdev);
+ uart->clocked = 1;
+ omap_uart_restore_context(uart);
+}
+
+#ifdef CONFIG_PM
+
+static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
+{
+ if (!uart->clocked)
+ return;
+
+ omap_uart_save_context(uart);
+ uart->clocked = 0;
+ omap_device_idle(uart->pdev);
+}
+
+static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
+{
+ /* Set wake-enable bit */
+ if (uart->wk_en && uart->wk_mask) {
+ u32 v = __raw_readl(uart->wk_en);
+ v |= uart->wk_mask;
+ __raw_writel(v, uart->wk_en);
+ }
+
+ /* Ensure IOPAD wake-enables are set */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 v = omap_ctrl_readw(uart->padconf);
+ v |= OMAP3_PADCONF_WAKEUPENABLE0;
+ omap_ctrl_writew(v, uart->padconf);
+ }
+}
+
+static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
+{
+ /* Clear wake-enable bit */
+ if (uart->wk_en && uart->wk_mask) {
+ u32 v = __raw_readl(uart->wk_en);
+ v &= ~uart->wk_mask;
+ __raw_writel(v, uart->wk_en);
+ }
+
+ /* Ensure IOPAD wake-enables are cleared */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 v = omap_ctrl_readw(uart->padconf);
+ v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
+ omap_ctrl_writew(v, uart->padconf);
+ }
+}
+
+static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
+ int enable)
+{
+ u8 idlemode;
+
+ if (enable) {
+ /**
+ * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
+ * in Smartidle Mode When Configured for DMA Operations.
+ */
+ if (uart->dma_enabled)
+ idlemode = HWMOD_IDLEMODE_FORCE;
+ else
+ idlemode = HWMOD_IDLEMODE_SMART;
+ } else {
+ idlemode = HWMOD_IDLEMODE_NO;
+ }
+
+ omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
+}
+
+static void omap_uart_block_sleep(struct omap_uart_state *uart)
+{
+ omap_uart_enable_clocks(uart);
+
+ omap_uart_smart_idle_enable(uart, 0);
+ uart->can_sleep = 0;
+ if (uart->timeout)
+ mod_timer(&uart->timer, jiffies + uart->timeout);
+ else
+ del_timer(&uart->timer);
+}
+
+static void omap_uart_allow_sleep(struct omap_uart_state *uart)
+{
+ if (device_may_wakeup(&uart->pdev->dev))
+ omap_uart_enable_wakeup(uart);
+ else
+ omap_uart_disable_wakeup(uart);
+
+ if (!uart->clocked)
+ return;
+
+ omap_uart_smart_idle_enable(uart, 1);
+ uart->can_sleep = 1;
+ del_timer(&uart->timer);
+}
+
+static void omap_uart_idle_timer(unsigned long data)
+{
+ struct omap_uart_state *uart = (struct omap_uart_state *)data;
+
+ omap_uart_allow_sleep(uart);
+}
+
+void omap_uart_prepare_idle(int num)
+{
+ struct omap_uart_state *uart;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ if (num == uart->num && uart->can_sleep) {
+ omap_uart_disable_clocks(uart);
+ return;
+ }
+ }
+}
+
+void omap_uart_resume_idle(int num)
+{
+ struct omap_uart_state *uart;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ if (num == uart->num && uart->can_sleep) {
+ omap_uart_enable_clocks(uart);
+
+ /* Check for IO pad wakeup */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 p = omap_ctrl_readw(uart->padconf);
+
+ if (p & OMAP3_PADCONF_WAKEUPEVENT0)
+ omap_uart_block_sleep(uart);
+ }
+
+ /* Check for normal UART wakeup */
+ if (__raw_readl(uart->wk_st) & uart->wk_mask)
+ omap_uart_block_sleep(uart);
+ return;
+ }
+ }
+}
+
+void omap_uart_prepare_suspend(void)
+{
+ struct omap_uart_state *uart;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ omap_uart_allow_sleep(uart);
+ }
+}
+
+int omap_uart_can_sleep(void)
+{
+ struct omap_uart_state *uart;
+ int can_sleep = 1;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ if (!uart->clocked)
+ continue;
+
+ if (!uart->can_sleep) {
+ can_sleep = 0;
+ continue;
+ }
+
+ /* This UART can now safely sleep. */
+ omap_uart_allow_sleep(uart);
+ }
+
+ return can_sleep;
+}
+
+/**
+ * omap_uart_interrupt()
+ *
+ * This handler is used only to detect that *any* UART interrupt has
+ * occurred. It does _nothing_ to handle the interrupt. Rather,
+ * any UART interrupt will trigger the inactivity timer so the
+ * UART will not idle or sleep for its timeout period.
+ *
+ **/
+/* static int first_interrupt; */
+static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
+{
+ struct omap_uart_state *uart = dev_id;
+
+ omap_uart_block_sleep(uart);
+
+ return IRQ_NONE;
+}
+
+static void omap_uart_idle_init(struct omap_uart_state *uart)
+{
+ int ret;
+
+ uart->can_sleep = 0;
+ uart->timeout = DEFAULT_TIMEOUT;
+ setup_timer(&uart->timer, omap_uart_idle_timer,
+ (unsigned long) uart);
+ if (uart->timeout)
+ mod_timer(&uart->timer, jiffies + uart->timeout);
+ omap_uart_smart_idle_enable(uart, 0);
+
+ if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
+ u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD;
+ u32 wk_mask = 0;
+ u32 padconf = 0;
+
+ /* XXX These PRM accesses do not belong here */
+ uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
+ uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
+ switch (uart->num) {
+ case 0:
+ wk_mask = OMAP3430_ST_UART1_MASK;
+ padconf = 0x182;
+ break;
+ case 1:
+ wk_mask = OMAP3430_ST_UART2_MASK;
+ padconf = 0x17a;
+ break;
+ case 2:
+ wk_mask = OMAP3430_ST_UART3_MASK;
+ padconf = 0x19e;
+ break;
+ case 3:
+ wk_mask = OMAP3630_ST_UART4_MASK;
+ padconf = 0x0d2;
+ break;
+ }
+ uart->wk_mask = wk_mask;
+ uart->padconf = padconf;
+ } else if (cpu_is_omap24xx()) {
+ u32 wk_mask = 0;
+ u32 wk_en = PM_WKEN1, wk_st = PM_WKST1;
+
+ switch (uart->num) {
+ case 0:
+ wk_mask = OMAP24XX_ST_UART1_MASK;
+ break;
+ case 1:
+ wk_mask = OMAP24XX_ST_UART2_MASK;
+ break;
+ case 2:
+ wk_en = OMAP24XX_PM_WKEN2;
+ wk_st = OMAP24XX_PM_WKST2;
+ wk_mask = OMAP24XX_ST_UART3_MASK;
+ break;
+ }
+ uart->wk_mask = wk_mask;
+ if (cpu_is_omap2430()) {
+ uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en);
+ uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st);
+ } else if (cpu_is_omap2420()) {
+ uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en);
+ uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st);
+ }
+ } else {
+ uart->wk_en = NULL;
+ uart->wk_st = NULL;
+ uart->wk_mask = 0;
+ uart->padconf = 0;
+ }
+
+ uart->irqflags |= IRQF_SHARED;
+ ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
+ IRQF_SHARED, "serial idle", (void *)uart);
+ WARN_ON(ret);
+}
+
+void omap_uart_enable_irqs(int enable)
+{
+ int ret;
+ struct omap_uart_state *uart;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ if (enable) {
+ pm_runtime_put_sync(&uart->pdev->dev);
+ ret = request_threaded_irq(uart->irq, NULL,
+ omap_uart_interrupt,
+ IRQF_SHARED,
+ "serial idle",
+ (void *)uart);
+ } else {
+ pm_runtime_get_noresume(&uart->pdev->dev);
+ free_irq(uart->irq, (void *)uart);
+ }
+ }
+}
+
+static ssize_t sleep_timeout_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *odev = to_omap_device(pdev);
+ struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
+
+ return sprintf(buf, "%u\n", uart->timeout / HZ);
+}
+
+static ssize_t sleep_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t n)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *odev = to_omap_device(pdev);
+ struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
+ unsigned int value;
+
+ if (sscanf(buf, "%u", &value) != 1) {
+ dev_err(dev, "sleep_timeout_store: Invalid value\n");
+ return -EINVAL;
+ }
+
+ uart->timeout = value * HZ;
+ if (uart->timeout)
+ mod_timer(&uart->timer, jiffies + uart->timeout);
+ else
+ /* A zero value means disable timeout feature */
+ omap_uart_block_sleep(uart);
+
+ return n;
+}
+
+static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
+ sleep_timeout_store);
+#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
+#else
+static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
+static void omap_uart_block_sleep(struct omap_uart_state *uart)
+{
+ /* Needed to enable UART clocks when built without CONFIG_PM */
+ omap_uart_enable_clocks(uart);
+}
+#define DEV_CREATE_FILE(dev, attr)
+#endif /* CONFIG_PM */
+
+#ifndef CONFIG_SERIAL_OMAP
+/*
+ * Override the default 8250 read handler: mem_serial_in()
+ * Empty RX fifo read causes an abort on omap3630 and omap4
+ * This function makes sure that an empty rx fifo is not read on these silicons
+ * (OMAP1/2/3430 are not affected)
+ */
+static unsigned int serial_in_override(struct uart_port *up, int offset)
+{
+ if (UART_RX == offset) {
+ unsigned int lsr;
+ lsr = __serial_read_reg(up, UART_LSR);
+ if (!(lsr & UART_LSR_DR))
+ return -EPERM;
+ }
+
+ return __serial_read_reg(up, offset);
+}
+
+static void serial_out_override(struct uart_port *up, int offset, int value)
+{
+ unsigned int status, tmout = 10000;
+
+ status = __serial_read_reg(up, UART_LSR);
+ while (!(status & UART_LSR_THRE)) {
+ /* Wait up to 10ms for the character(s) to be sent. */
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ status = __serial_read_reg(up, UART_LSR);
+ }
+ __serial_write_reg(up, offset, value);
+}
+#endif
+
+static int __init omap_serial_early_init(void)
+{
+ int i = 0;
+
+ do {
+ char oh_name[MAX_UART_HWMOD_NAME_LEN];
+ struct omap_hwmod *oh;
+ struct omap_uart_state *uart;
+
+ snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
+ "uart%d", i + 1);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh)
+ break;
+
+ uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
+ if (WARN_ON(!uart))
+ return -ENODEV;
+
+ uart->oh = oh;
+ uart->num = i++;
+ list_add_tail(&uart->node, &uart_list);
+ num_uarts++;
+
+ /*
+ * NOTE: omap_hwmod_setup*() has not yet been called,
+ * so no hwmod functions will work yet.
+ */
+
+ /*
+ * During UART early init, device need to be probed
+ * to determine SoC specific init before omap_device
+ * is ready. Therefore, don't allow idle here
+ */
+ uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
+ } while (1);
+
+ return 0;
+}
+core_initcall(omap_serial_early_init);
+
+/**
+ * omap_serial_init_port() - initialize single serial port
+ * @bdata: port specific board data pointer
+ *
+ * This function initialies serial driver for given port only.
+ * Platforms can call this function instead of omap_serial_init()
+ * if they don't plan to use all available UARTs as serial ports.
+ *
+ * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
+ * use only one of the two.
+ */
+void __init omap_serial_init_port(struct omap_board_data *bdata)
+{
+ struct omap_uart_state *uart;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ void *pdata = NULL;
+ u32 pdata_size = 0;
+ char *name;
+#ifndef CONFIG_SERIAL_OMAP
+ struct plat_serial8250_port ports[2] = {
+ {},
+ {.flags = 0},
+ };
+ struct plat_serial8250_port *p = &ports[0];
+#else
+ struct omap_uart_port_info omap_up;
+#endif
+
+ if (WARN_ON(!bdata))
+ return;
+ if (WARN_ON(bdata->id < 0))
+ return;
+ if (WARN_ON(bdata->id >= num_uarts))
+ return;
+
+ list_for_each_entry(uart, &uart_list, node)
+ if (bdata->id == uart->num)
+ break;
+
+ oh = uart->oh;
+ uart->dma_enabled = 0;
+#ifndef CONFIG_SERIAL_OMAP
+ name = "serial8250";
+
+ /*
+ * !! 8250 driver does not use standard IORESOURCE* It
+ * has it's own custom pdata that can be taken from
+ * the hwmod resource data. But, this needs to be
+ * done after the build.
+ *
+ * ?? does it have to be done before the register ??
+ * YES, because platform_device_data_add() copies
+ * pdata, it does not use a pointer.
+ */
+ p->flags = UPF_BOOT_AUTOCONF;
+ p->iotype = UPIO_MEM;
+ p->regshift = 2;
+ p->uartclk = OMAP24XX_BASE_BAUD * 16;
+ p->irq = oh->mpu_irqs[0].irq;
+ p->mapbase = oh->slaves[0]->addr->pa_start;
+ p->membase = omap_hwmod_get_mpu_rt_va(oh);
+ p->irqflags = IRQF_SHARED;
+ p->private_data = uart;
+
+ /*
+ * omap44xx, ti816x: Never read empty UART fifo
+ * omap3xxx: Never read empty UART fifo on UARTs
+ * with IP rev >=0x52
+ */
+ uart->regshift = p->regshift;
+ uart->membase = p->membase;
+ if (cpu_is_omap44xx() || cpu_is_ti816x())
+ uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
+ else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
+ >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
+ uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
+
+ if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
+ p->serial_in = serial_in_override;
+ p->serial_out = serial_out_override;
+ }
+
+ pdata = &ports[0];
+ pdata_size = 2 * sizeof(struct plat_serial8250_port);
+#else
+
+ name = DRIVER_NAME;
+
+ omap_up.dma_enabled = uart->dma_enabled;
+ omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
+ omap_up.mapbase = oh->slaves[0]->addr->pa_start;
+ omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
+ omap_up.irqflags = IRQF_SHARED;
+ omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+
+ pdata = &omap_up;
+ pdata_size = sizeof(struct omap_uart_port_info);
+#endif
+
+ if (WARN_ON(!oh))
+ return;
+
+ od = omap_device_build(name, uart->num, oh, pdata, pdata_size,
+ omap_uart_latency,
+ ARRAY_SIZE(omap_uart_latency), false);
+ WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
+ name, oh->name);
+
+ oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
+
+ uart->irq = oh->mpu_irqs[0].irq;
+ uart->regshift = 2;
+ uart->mapbase = oh->slaves[0]->addr->pa_start;
+ uart->membase = omap_hwmod_get_mpu_rt_va(oh);
+ uart->pdev = &od->pdev;
+
+ oh->dev_attr = uart;
+
+ console_lock(); /* in case the earlycon is on the UART */
+
+ /*
+ * Because of early UART probing, UART did not get idled
+ * on init. Now that omap_device is ready, ensure full idle
+ * before doing omap_device_enable().
+ */
+ omap_hwmod_idle(uart->oh);
+
+ omap_device_enable(uart->pdev);
+ omap_uart_idle_init(uart);
+ omap_uart_reset(uart);
+ omap_hwmod_enable_wakeup(uart->oh);
+ omap_device_idle(uart->pdev);
+
+ /*
+ * Need to block sleep long enough for interrupt driven
+ * driver to start. Console driver is in polling mode
+ * so device needs to be kept enabled while polling driver
+ * is in use.
+ */
+ if (uart->timeout)
+ uart->timeout = (30 * HZ);
+ omap_uart_block_sleep(uart);
+ uart->timeout = DEFAULT_TIMEOUT;
+
+ console_unlock();
+
+ if ((cpu_is_omap34xx() && uart->padconf) ||
+ (uart->wk_en && uart->wk_mask)) {
+ device_init_wakeup(&od->pdev.dev, true);
+ DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
+ }
+
+ /* Enable the MDR1 errata for OMAP3 */
+ if (cpu_is_omap34xx() && !cpu_is_ti816x())
+ uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
+}
+
+/**
+ * omap_serial_init() - initialize all supported serial ports
+ *
+ * Initializes all available UARTs as serial ports. Platforms
+ * can call this function when they want to have default behaviour
+ * for serial ports (e.g initialize them all as serial ports).
+ */
+void __init omap_serial_init(void)
+{
+ struct omap_uart_state *uart;
+ struct omap_board_data bdata;
+
+ list_for_each_entry(uart, &uart_list, node) {
+ bdata.id = uart->num;
+ bdata.flags = 0;
+ bdata.pads = NULL;
+ bdata.pads_cnt = 0;
+ omap_serial_init_port(&bdata);
+
+ }
+}
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
new file mode 100644
index 00000000..b5071a47
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/mach-omap2/sleep.S
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * (C) Copyright 2006 Nokia Corporation
+ * Fixed idle loop sleep
+ * Igor Stoppa <igor.stoppa@nokia.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/linkage.h>
+#include <asm/assembler.h>
+#include <mach/io.h>
+
+#include <plat/omap24xx.h>
+
+#include "sdrc.h"
+
+/* First address of reserved address space? apparently valid for OMAP2 & 3 */
+#define A_SDRC0_V (0xC0000000)
+
+ .text
+
+/*
+ * Forces OMAP into idle state
+ *
+ * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI
+ * for normal idles.
+ *
+ * Note: This code get's copied to internal SRAM at boot. When the OMAP
+ * wakes up it continues execution at the point it went to sleep.
+ */
+ .align 3
+ENTRY(omap24xx_idle_loop_suspend)
+ stmfd sp!, {r0, lr} @ save registers on stack
+ mov r0, #0 @ clear for mcr setup
+ mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
+ ldmfd sp!, {r0, pc} @ restore regs and return
+
+ENTRY(omap24xx_idle_loop_suspend_sz)
+ .word . - omap24xx_idle_loop_suspend
+
+/*
+ * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing
+ * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore
+ * SDRC.
+ *
+ * Input:
+ * R0 : DLL ctrl value pre-Sleep
+ * R1 : SDRC_DLLA_CTRL
+ * R2 : SDRC_POWER
+ *
+ * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
+ * when we get called, but the DLL probably isn't. We will wait a bit more in
+ * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
+ * if in unlocked mode.
+ *
+ * For less than 242x-ES2.2 upon wake from a sleep mode where the external
+ * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
+ * clock can pass into the PRCM can cause problems at DSP and IVA.
+ * To work around this the code will switch to the 32kHz source prior to sleep.
+ * Post sleep we will shift back to using the DPLL. Apparently,
+ * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
+ * 3x12MHz + 3x32kHz clocks for a full switch.
+ *
+ * The DLL load value is not kept in RETENTION or OFF. It needs to be restored
+ * at wake
+ */
+ .align 3
+ENTRY(omap24xx_cpu_suspend)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+ mov r3, #0x0 @ clear for mcr call
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
+ nop
+ nop
+ ldr r4, [r2] @ read SDRC_POWER
+ orr r4, r4, #0x40 @ enable self refresh on idle req
+ mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
+ str r4, [r2] @ make it so
+ nop
+ mcr p15, 0, r3, c7, c0, 4 @ wait for interrupt
+ nop
+loop:
+ subs r5, r5, #0x1 @ awake, wait just a bit
+ bne loop
+
+ /* The DPLL has to be on before we take the DDR out of self refresh */
+ bic r4, r4, #0x40 @ now clear self refresh bit.
+ str r4, [r2] @ write to SDRC_POWER
+ ldr r4, A_SDRC0 @ make a clock happen
+ ldr r4, [r4] @ read A_SDRC0
+ nop @ start auto refresh only after clk ok
+ movs r0, r0 @ see if DDR or SDR
+ strne r0, [r1] @ rewrite DLLA to force DLL reload
+ addne r1, r1, #0x8 @ move to DLLB
+ strne r0, [r1] @ rewrite DLLB to force DLL reload
+
+ mov r5, #0x1000
+loop2:
+ subs r5, r5, #0x1
+ bne loop2
+ /* resume*/
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+A_SDRC0:
+ .word A_SDRC0_V
+
+ENTRY(omap24xx_cpu_suspend_sz)
+ .word . - omap24xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
new file mode 100644
index 00000000..63f10669
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -0,0 +1,754 @@
+/*
+ * (C) Copyright 2007
+ * Texas Instruments
+ * Karthik Dasu <karthik-dp@ti.com>
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <plat/sram.h>
+#include <mach/io.h>
+
+#include "cm2xxx_3xxx.h"
+#include "prm2xxx_3xxx.h"
+#include "sdrc.h"
+#include "control.h"
+
+/*
+ * Registers access definitions
+ */
+#define SDRC_SCRATCHPAD_SEM_OFFS 0xc
+#define SDRC_SCRATCHPAD_SEM_V OMAP343X_SCRATCHPAD_REGADDR\
+ (SDRC_SCRATCHPAD_SEM_OFFS)
+#define PM_PREPWSTST_CORE_P OMAP3430_PRM_BASE + CORE_MOD +\
+ OMAP3430_PM_PREPWSTST
+#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL
+#define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1)
+#define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST)
+#define SRAM_BASE_P OMAP3_SRAM_PA
+#define CONTROL_STAT OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS
+#define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE +\
+ OMAP36XX_CONTROL_MEM_RTA_CTRL)
+
+/* Move this as correct place is available */
+#define SCRATCHPAD_MEM_OFFS 0x310
+#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE +\
+ OMAP343X_CONTROL_MEM_WKUP +\
+ SCRATCHPAD_MEM_OFFS)
+#define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+#define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG)
+#define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0)
+#define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0)
+#define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0)
+#define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1)
+#define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1)
+#define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1)
+#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
+#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
+
+/*
+ * This file needs be built unconditionally as ARM to interoperate correctly
+ * with non-Thumb-2-capable firmware.
+ */
+ .arm
+
+/*
+ * API functions
+ */
+
+/*
+ * The "get_*restore_pointer" functions are used to provide a
+ * physical restore address where the ROM code jumps while waking
+ * up from MPU OFF/OSWR state.
+ * The restore pointer is stored into the scratchpad.
+ */
+
+ .text
+/* Function call to get the restore pointer for resume from OFF */
+ENTRY(get_restore_pointer)
+ stmfd sp!, {lr} @ save registers on stack
+ adr r0, restore
+ ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_restore_pointer)
+ .align
+ENTRY(get_restore_pointer_sz)
+ .word . - get_restore_pointer
+
+ .text
+/* Function call to get the restore pointer for 3630 resume from OFF */
+ENTRY(get_omap3630_restore_pointer)
+ stmfd sp!, {lr} @ save registers on stack
+ adr r0, restore_3630
+ ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_omap3630_restore_pointer)
+ .align
+ENTRY(get_omap3630_restore_pointer_sz)
+ .word . - get_omap3630_restore_pointer
+
+ .text
+/* Function call to get the restore pointer for ES3 to resume from OFF */
+ENTRY(get_es3_restore_pointer)
+ stmfd sp!, {lr} @ save registers on stack
+ adr r0, restore_es3
+ ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_es3_restore_pointer)
+ .align
+ENTRY(get_es3_restore_pointer_sz)
+ .word . - get_es3_restore_pointer
+
+ .text
+/*
+ * L2 cache needs to be toggled for stable OFF mode functionality on 3630.
+ * This function sets up a flag that will allow for this toggling to take
+ * place on 3630. Hopefully some version in the future may not need this.
+ */
+ENTRY(enable_omap3630_toggle_l2_on_restore)
+ stmfd sp!, {lr} @ save registers on stack
+ /* Setup so that we will disable and enable l2 */
+ mov r1, #0x1
+ adrl r2, l2dis_3630 @ may be too distant for plain adr
+ str r1, [r2]
+ ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(enable_omap3630_toggle_l2_on_restore)
+
+ .text
+/* Function to call rom code to save secure ram context */
+ .align 3
+ENTRY(save_secure_ram_context)
+ stmfd sp!, {r1-r12, lr} @ save registers on stack
+ adr r3, api_params @ r3 points to parameters
+ str r0, [r3,#0x4] @ r0 has sdram address
+ ldr r12, high_mask
+ and r3, r3, r12
+ ldr r12, sram_phy_addr_mask
+ orr r3, r3, r12
+ mov r0, #25 @ set service ID for PPA
+ mov r12, r0 @ copy secure service ID in r12
+ mov r1, #0 @ set task id for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
+ mov r6, #0xff
+ dsb @ data write barrier
+ dmb @ data memory barrier
+ smc #1 @ call SMI monitor (smi #1)
+ nop
+ nop
+ nop
+ nop
+ ldmfd sp!, {r1-r12, pc}
+ .align
+sram_phy_addr_mask:
+ .word SRAM_BASE_P
+high_mask:
+ .word 0xffff
+api_params:
+ .word 0x4, 0x0, 0x0, 0x1, 0x1
+ENDPROC(save_secure_ram_context)
+ENTRY(save_secure_ram_context_sz)
+ .word . - save_secure_ram_context
+
+/*
+ * ======================
+ * == Idle entry point ==
+ * ======================
+ */
+
+/*
+ * Forces OMAP into idle state
+ *
+ * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed
+ * and executes the WFI instruction. Calling WFI effectively changes the
+ * power domains states to the desired target power states.
+ *
+ *
+ * Notes:
+ * - this code gets copied to internal SRAM at boot and after wake-up
+ * from OFF mode. The execution pointer in SRAM is _omap_sram_idle.
+ * - when the OMAP wakes up it continues at different execution points
+ * depending on the low power mode (non-OFF vs OFF modes),
+ * cf. 'Resume path for xxx mode' comments.
+ */
+ .align 3
+ENTRY(omap34xx_cpu_suspend)
+ stmfd sp!, {r0-r12, lr} @ save registers on stack
+
+ /*
+ * r0 contains CPU context save/restore pointer in sdram
+ * r1 contains information about saving context:
+ * 0 - No context lost
+ * 1 - Only L1 and logic lost
+ * 2 - Only L2 lost (Even L1 is retained we clean it along with L2)
+ * 3 - Both L1 and L2 lost and logic lost
+ */
+
+ /* Directly jump to WFI is the context save is not required */
+ cmp r1, #0x0
+ beq omap3_do_wfi
+
+ /* Otherwise fall through to the save context code */
+save_context_wfi:
+ mov r8, r0 @ Store SDRAM address in r8
+ mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register
+ mov r4, #0x1 @ Number of parameters for restore call
+ stmia r8!, {r4-r5} @ Push parameters for restore call
+ mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register
+ stmia r8!, {r4-r5} @ Push parameters for restore call
+
+ /* Check what that target sleep state is from r1 */
+ cmp r1, #0x2 @ Only L2 lost, no need to save context
+ beq clean_caches
+
+l1_logic_lost:
+ mov r4, sp @ Store sp
+ mrs r5, spsr @ Store spsr
+ mov r6, lr @ Store lr
+ stmia r8!, {r4-r6}
+
+ mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register
+ mrc p15, 0, r5, c2, c0, 0 @ TTBR0
+ mrc p15, 0, r6, c2, c0, 1 @ TTBR1
+ mrc p15, 0, r7, c2, c0, 2 @ TTBCR
+ stmia r8!, {r4-r7}
+
+ mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register
+ mrc p15, 0, r5, c10, c2, 0 @ PRRR
+ mrc p15, 0, r6, c10, c2, 1 @ NMRR
+ stmia r8!,{r4-r6}
+
+ mrc p15, 0, r4, c13, c0, 1 @ Context ID
+ mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
+ mrs r7, cpsr @ Store current cpsr
+ stmia r8!, {r4-r7}
+
+ mrc p15, 0, r4, c1, c0, 0 @ save control register
+ stmia r8!, {r4}
+
+clean_caches:
+ /*
+ * jump out to kernel flush routine
+ * - reuse that code is better
+ * - it executes in a cached space so is faster than refetch per-block
+ * - should be faster and will change with kernel
+ * - 'might' have to copy address, load and jump to it
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ ldr r1, kernel_flush
+ mov lr, pc
+ bx r1
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
+ */
+ ldr r1, kernel_flush
+ blx r1
+ /*
+ * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
+ * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
+ * This sequence switches back to ARM. Note that .align may insert a
+ * nop: bx pc needs to be word-aligned in order to work.
+ */
+ THUMB( .thumb )
+ THUMB( .align )
+ THUMB( bx pc )
+ THUMB( nop )
+ .arm
+
+omap3_do_wfi:
+ ldr r4, sdrc_power @ read the SDRC_POWER register
+ ldr r5, [r4] @ read the contents of SDRC_POWER
+ orr r5, r5, #0x40 @ enable self refresh on idle req
+ str r5, [r4] @ write back to SDRC_POWER register
+
+ /* Data memory barrier and Data sync barrier */
+ dsb
+ dmb
+
+/*
+ * ===================================
+ * == WFI instruction => Enter idle ==
+ * ===================================
+ */
+ wfi @ wait for interrupt
+
+/*
+ * ===================================
+ * == Resume path for non-OFF modes ==
+ * ===================================
+ */
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ bl wait_sdrc_ok
+
+ mrc p15, 0, r0, c1, c0, 0
+ tst r0, #(1 << 2) @ Check C bit enabled?
+ orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
+ mcreq p15, 0, r0, c1, c0, 0
+ isb
+
+/*
+ * ===================================
+ * == Exit point from non-OFF modes ==
+ * ===================================
+ */
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+
+/*
+ * ==============================
+ * == Resume path for OFF mode ==
+ * ==============================
+ */
+
+/*
+ * The restore_* functions are called by the ROM code
+ * when back from WFI in OFF mode.
+ * Cf. the get_*restore_pointer functions.
+ *
+ * restore_es3: applies to 34xx >= ES3.0
+ * restore_3630: applies to 36xx
+ * restore: common code for 3xxx
+ */
+restore_es3:
+ ldr r5, pm_prepwstst_core_p
+ ldr r4, [r5]
+ and r4, r4, #0x3
+ cmp r4, #0x0 @ Check if previous power state of CORE is OFF
+ bne restore
+ adr r0, es3_sdrc_fix
+ ldr r1, sram_base
+ ldr r2, es3_sdrc_fix_sz
+ mov r2, r2, ror #2
+copy_to_sram:
+ ldmia r0!, {r3} @ val = *src
+ stmia r1!, {r3} @ *dst = val
+ subs r2, r2, #0x1 @ num_words--
+ bne copy_to_sram
+ ldr r1, sram_base
+ blx r1
+ b restore
+
+restore_3630:
+ ldr r1, pm_prepwstst_core_p
+ ldr r2, [r1]
+ and r2, r2, #0x3
+ cmp r2, #0x0 @ Check if previous power state of CORE is OFF
+ bne restore
+ /* Disable RTA before giving control */
+ ldr r1, control_mem_rta
+ mov r2, #OMAP36XX_RTA_DISABLE
+ str r2, [r1]
+
+ /* Fall through to common code for the remaining logic */
+
+restore:
+ /*
+ * Check what was the reason for mpu reset and store the reason in r9:
+ * 0 - No context lost
+ * 1 - Only L1 and logic lost
+ * 2 - Only L2 lost - In this case, we wont be here
+ * 3 - Both L1 and L2 lost
+ */
+ ldr r1, pm_pwstctrl_mpu
+ ldr r2, [r1]
+ and r2, r2, #0x3
+ cmp r2, #0x0 @ Check if target power state was OFF or RET
+ moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
+ movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
+ bne logic_l1_restore
+
+ ldr r0, l2dis_3630
+ cmp r0, #0x1 @ should we disable L2 on 3630?
+ bne skipl2dis
+ mrc p15, 0, r0, c1, c0, 1
+ bic r0, r0, #2 @ disable L2 cache
+ mcr p15, 0, r0, c1, c0, 1
+skipl2dis:
+ ldr r0, control_stat
+ ldr r1, [r0]
+ and r1, #0x700
+ cmp r1, #0x300
+ beq l2_inv_gp
+ mov r0, #40 @ set service ID for PPA
+ mov r12, r0 @ copy secure Service ID in r12
+ mov r1, #0 @ set task id for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
+ mov r6, #0xff
+ adr r3, l2_inv_api_params @ r3 points to dummy parameters
+ dsb @ data write barrier
+ dmb @ data memory barrier
+ smc #1 @ call SMI monitor (smi #1)
+ /* Write to Aux control register to set some bits */
+ mov r0, #42 @ set service ID for PPA
+ mov r12, r0 @ copy secure Service ID in r12
+ mov r1, #0 @ set task id for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
+ mov r6, #0xff
+ ldr r4, scratchpad_base
+ ldr r3, [r4, #0xBC] @ r3 points to parameters
+ dsb @ data write barrier
+ dmb @ data memory barrier
+ smc #1 @ call SMI monitor (smi #1)
+
+#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+ /* Restore L2 aux control register */
+ @ set service ID for PPA
+ mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
+ mov r12, r0 @ copy service ID in r12
+ mov r1, #0 @ set task ID for ROM code in r1
+ mov r2, #4 @ set some flags in r2, r6
+ mov r6, #0xff
+ ldr r4, scratchpad_base
+ ldr r3, [r4, #0xBC]
+ adds r3, r3, #8 @ r3 points to parameters
+ dsb @ data write barrier
+ dmb @ data memory barrier
+ smc #1 @ call SMI monitor (smi #1)
+#endif
+ b logic_l1_restore
+
+ .align
+l2_inv_api_params:
+ .word 0x1, 0x00
+l2_inv_gp:
+ /* Execute smi to invalidate L2 cache */
+ mov r12, #0x1 @ set up to invalidate L2
+ smc #0 @ Call SMI monitor (smieq)
+ /* Write to Aux control register to set some bits */
+ ldr r4, scratchpad_base
+ ldr r3, [r4,#0xBC]
+ ldr r0, [r3,#4]
+ mov r12, #0x3
+ smc #0 @ Call SMI monitor (smieq)
+ ldr r4, scratchpad_base
+ ldr r3, [r4,#0xBC]
+ ldr r0, [r3,#12]
+ mov r12, #0x2
+ smc #0 @ Call SMI monitor (smieq)
+logic_l1_restore:
+ ldr r1, l2dis_3630
+ cmp r1, #0x1 @ Test if L2 re-enable needed on 3630
+ bne skipl2reen
+ mrc p15, 0, r1, c1, c0, 1
+ orr r1, r1, #2 @ re-enable L2 cache
+ mcr p15, 0, r1, c1, c0, 1
+skipl2reen:
+ mov r1, #0
+ /*
+ * Invalidate all instruction caches to PoU
+ * and flush branch target cache
+ */
+ mcr p15, 0, r1, c7, c5, 0
+
+ ldr r4, scratchpad_base
+ ldr r3, [r4,#0xBC]
+ adds r3, r3, #16
+
+ ldmia r3!, {r4-r6}
+ mov sp, r4 @ Restore sp
+ msr spsr_cxsf, r5 @ Restore spsr
+ mov lr, r6 @ Restore lr
+
+ ldmia r3!, {r4-r7}
+ mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register
+ mcr p15, 0, r5, c2, c0, 0 @ TTBR0
+ mcr p15, 0, r6, c2, c0, 1 @ TTBR1
+ mcr p15, 0, r7, c2, c0, 2 @ TTBCR
+
+ ldmia r3!,{r4-r6}
+ mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register
+ mcr p15, 0, r5, c10, c2, 0 @ PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ NMRR
+
+
+ ldmia r3!,{r4-r7}
+ mcr p15, 0, r4, c13, c0, 1 @ Context ID
+ mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
+ msr cpsr, r7 @ store cpsr
+
+ /* Enabling MMU here */
+ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
+ /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
+ and r7, #0x7
+ cmp r7, #0x0
+ beq usettbr0
+ttbr_error:
+ /*
+ * More work needs to be done to support N[0:2] value other than 0
+ * So looping here so that the error can be detected
+ */
+ b ttbr_error
+usettbr0:
+ mrc p15, 0, r2, c2, c0, 0
+ ldr r5, ttbrbit_mask
+ and r2, r5
+ mov r4, pc
+ ldr r5, table_index_mask
+ and r4, r5 @ r4 = 31 to 20 bits of pc
+ /* Extract the value to be written to table entry */
+ ldr r1, table_entry
+ /* r1 has the value to be written to table entry*/
+ add r1, r1, r4
+ /* Getting the address of table entry to modify */
+ lsr r4, #18
+ /* r2 has the location which needs to be modified */
+ add r2, r4
+ /* Storing previous entry of location being modified */
+ ldr r5, scratchpad_base
+ ldr r4, [r2]
+ str r4, [r5, #0xC0]
+ /* Modify the table entry */
+ str r1, [r2]
+ /*
+ * Storing address of entry being modified
+ * - will be restored after enabling MMU
+ */
+ ldr r5, scratchpad_base
+ str r2, [r5, #0xC4]
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
+ mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
+ mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
+ /*
+ * Restore control register. This enables the MMU.
+ * The caches and prediction are not enabled here, they
+ * will be enabled after restoring the MMU table entry.
+ */
+ ldmia r3!, {r4}
+ /* Store previous value of control register in scratchpad */
+ str r4, [r5, #0xC8]
+ ldr r2, cache_pred_disable_mask
+ and r4, r2
+ mcr p15, 0, r4, c1, c0, 0
+ dsb
+ isb
+ ldr r0, =restoremmu_on
+ bx r0
+
+/*
+ * ==============================
+ * == Exit point from OFF mode ==
+ * ==============================
+ */
+restoremmu_on:
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+
+/*
+ * Internal functions
+ */
+
+/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
+ .text
+ .align 3
+ENTRY(es3_sdrc_fix)
+ ldr r4, sdrc_syscfg @ get config addr
+ ldr r5, [r4] @ get value
+ tst r5, #0x100 @ is part access blocked
+ it eq
+ biceq r5, r5, #0x100 @ clear bit if set
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_mr_0 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_emr2_0 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_manual_0 @ get config addr
+ mov r5, #0x2 @ autorefresh command
+ str r5, [r4] @ kick off refreshes
+ ldr r4, sdrc_mr_1 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_emr2_1 @ get config addr
+ ldr r5, [r4] @ get value
+ str r5, [r4] @ write back change
+ ldr r4, sdrc_manual_1 @ get config addr
+ mov r5, #0x2 @ autorefresh command
+ str r5, [r4] @ kick off refreshes
+ bx lr
+
+ .align
+sdrc_syscfg:
+ .word SDRC_SYSCONFIG_P
+sdrc_mr_0:
+ .word SDRC_MR_0_P
+sdrc_emr2_0:
+ .word SDRC_EMR2_0_P
+sdrc_manual_0:
+ .word SDRC_MANUAL_0_P
+sdrc_mr_1:
+ .word SDRC_MR_1_P
+sdrc_emr2_1:
+ .word SDRC_EMR2_1_P
+sdrc_manual_1:
+ .word SDRC_MANUAL_1_P
+ENDPROC(es3_sdrc_fix)
+ENTRY(es3_sdrc_fix_sz)
+ .word . - es3_sdrc_fix
+
+/*
+ * This function implements the erratum ID i581 WA:
+ * SDRC state restore before accessing the SDRAM
+ *
+ * Only used at return from non-OFF mode. For OFF
+ * mode the ROM code configures the SDRC and
+ * the DPLL before calling the restore code directly
+ * from DDR.
+ */
+
+/* Make sure SDRC accesses are ok */
+wait_sdrc_ok:
+
+/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
+ ldr r4, cm_idlest_ckgen
+wait_dpll3_lock:
+ ldr r5, [r4]
+ tst r5, #1
+ beq wait_dpll3_lock
+
+ ldr r4, cm_idlest1_core
+wait_sdrc_ready:
+ ldr r5, [r4]
+ tst r5, #0x2
+ bne wait_sdrc_ready
+ /* allow DLL powerdown upon hw idle req */
+ ldr r4, sdrc_power
+ ldr r5, [r4]
+ bic r5, r5, #0x40
+ str r5, [r4]
+
+/*
+ * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
+ * base instead.
+ * Be careful not to clobber r7 when maintaing this code.
+ */
+
+is_dll_in_lock_mode:
+ /* Is dll in lock mode? */
+ ldr r4, sdrc_dlla_ctrl
+ ldr r5, [r4]
+ tst r5, #0x4
+ bxne lr @ Return if locked
+ /* wait till dll locks */
+ adr r7, kick_counter
+wait_dll_lock_timed:
+ ldr r4, wait_dll_lock_counter
+ add r4, r4, #1
+ str r4, [r7, #wait_dll_lock_counter - kick_counter]
+ ldr r4, sdrc_dlla_status
+ /* Wait 20uS for lock */
+ mov r6, #8
+wait_dll_lock:
+ subs r6, r6, #0x1
+ beq kick_dll
+ ldr r5, [r4]
+ and r5, r5, #0x4
+ cmp r5, #0x4
+ bne wait_dll_lock
+ bx lr @ Return when locked
+
+ /* disable/reenable DLL if not locked */
+kick_dll:
+ ldr r4, sdrc_dlla_ctrl
+ ldr r5, [r4]
+ mov r6, r5
+ bic r6, #(1<<3) @ disable dll
+ str r6, [r4]
+ dsb
+ orr r6, r6, #(1<<3) @ enable dll
+ str r6, [r4]
+ dsb
+ ldr r4, kick_counter
+ add r4, r4, #1
+ str r4, [r7] @ kick_counter
+ b wait_dll_lock_timed
+
+ .align
+cm_idlest1_core:
+ .word CM_IDLEST1_CORE_V
+cm_idlest_ckgen:
+ .word CM_IDLEST_CKGEN_V
+sdrc_dlla_status:
+ .word SDRC_DLLA_STATUS_V
+sdrc_dlla_ctrl:
+ .word SDRC_DLLA_CTRL_V
+pm_prepwstst_core_p:
+ .word PM_PREPWSTST_CORE_P
+pm_pwstctrl_mpu:
+ .word PM_PWSTCTRL_MPU_P
+scratchpad_base:
+ .word SCRATCHPAD_BASE_P
+sram_base:
+ .word SRAM_BASE_P + 0x8000
+sdrc_power:
+ .word SDRC_POWER_V
+ttbrbit_mask:
+ .word 0xFFFFC000
+table_index_mask:
+ .word 0xFFF00000
+table_entry:
+ .word 0x00000C02
+cache_pred_disable_mask:
+ .word 0xFFFFE7FB
+control_stat:
+ .word CONTROL_STAT
+control_mem_rta:
+ .word CONTROL_MEM_RTA_CTRL
+kernel_flush:
+ .word v7_flush_dcache_all
+l2dis_3630:
+ .word 0
+ /*
+ * When exporting to userspace while the counters are in SRAM,
+ * these 2 words need to be at the end to facilitate retrival!
+ */
+kick_counter:
+ .word 0
+wait_dll_lock_counter:
+ .word 0
+ENDPROC(omap34xx_cpu_suspend)
+
+ENTRY(omap34xx_cpu_suspend_sz)
+ .word . - omap34xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
new file mode 100644
index 00000000..f438cf4d
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -0,0 +1,59 @@
+/*
+ * Smart reflex Class 3 specific implementations
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "smartreflex.h"
+
+static int sr_class3_enable(struct voltagedomain *voltdm)
+{
+ unsigned long volt = omap_voltage_get_nom_volt(voltdm);
+
+ if (!volt) {
+ pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n",
+ __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ omap_vp_enable(voltdm);
+ return sr_enable(voltdm, volt);
+}
+
+static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
+{
+ omap_vp_disable(voltdm);
+ sr_disable(voltdm);
+ if (is_volt_reset)
+ omap_voltage_reset(voltdm);
+
+ return 0;
+}
+
+static int sr_class3_configure(struct voltagedomain *voltdm)
+{
+ return sr_configure_errgen(voltdm);
+}
+
+/* SR class3 structure */
+static struct omap_sr_class_data class3_data = {
+ .enable = sr_class3_enable,
+ .disable = sr_class3_disable,
+ .configure = sr_class3_configure,
+ .class_type = SR_CLASS3,
+};
+
+/* Smartreflex Class3 init API to be called from board file */
+static int __init sr_class3_init(void)
+{
+ pr_info("SmartReflex Class3 initialized\n");
+ return sr_register_class(&class3_data);
+}
+late_initcall(sr_class3_init);
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
new file mode 100644
index 00000000..f5a6bc12
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -0,0 +1,1043 @@
+/*
+ * OMAP SmartReflex Voltage Control
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+
+#include <plat/common.h>
+
+#include "pm.h"
+#include "smartreflex.h"
+
+#define SMARTREFLEX_NAME_LEN 16
+#define NVALUE_NAME_LEN 40
+#define SR_DISABLE_TIMEOUT 200
+
+struct omap_sr {
+ int srid;
+ int ip_type;
+ int nvalue_count;
+ bool autocomp_active;
+ u32 clk_length;
+ u32 err_weight;
+ u32 err_minlimit;
+ u32 err_maxlimit;
+ u32 accum_data;
+ u32 senn_avgweight;
+ u32 senp_avgweight;
+ u32 senp_mod;
+ u32 senn_mod;
+ unsigned int irq;
+ void __iomem *base;
+ struct platform_device *pdev;
+ struct list_head node;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+ struct dentry *dbg_dir;
+};
+
+/* sr_list contains all the instances of smartreflex module */
+static LIST_HEAD(sr_list);
+
+static struct omap_sr_class_data *sr_class;
+static struct omap_sr_pmic_data *sr_pmic_data;
+
+static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
+{
+ __raw_writel(value, (sr->base + offset));
+}
+
+static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
+ u32 value)
+{
+ u32 reg_val;
+ u32 errconfig_offs = 0, errconfig_mask = 0;
+
+ reg_val = __raw_readl(sr->base + offset);
+ reg_val &= ~mask;
+
+ /*
+ * Smartreflex error config register is special as it contains
+ * certain status bits which if written a 1 into means a clear
+ * of those bits. So in order to make sure no accidental write of
+ * 1 happens to those status bits, do a clear of them in the read
+ * value. This mean this API doesn't rewrite values in these bits
+ * if they are currently set, but does allow the caller to write
+ * those bits.
+ */
+ if (sr->ip_type == SR_TYPE_V1) {
+ errconfig_offs = ERRCONFIG_V1;
+ errconfig_mask = ERRCONFIG_STATUS_V1_MASK;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ errconfig_offs = ERRCONFIG_V2;
+ errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2;
+ }
+
+ if (offset == errconfig_offs)
+ reg_val &= ~errconfig_mask;
+
+ reg_val |= value;
+
+ __raw_writel(reg_val, (sr->base + offset));
+}
+
+static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
+{
+ return __raw_readl(sr->base + offset);
+}
+
+static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr_info;
+
+ if (!voltdm) {
+ pr_err("%s: Null voltage domain passed!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ list_for_each_entry(sr_info, &sr_list, node) {
+ if (voltdm == sr_info->voltdm)
+ return sr_info;
+ }
+
+ return ERR_PTR(-ENODATA);
+}
+
+static irqreturn_t sr_interrupt(int irq, void *data)
+{
+ struct omap_sr *sr_info = (struct omap_sr *)data;
+ u32 status = 0;
+
+ if (sr_info->ip_type == SR_TYPE_V1) {
+ /* Read the status bits */
+ status = sr_read_reg(sr_info, ERRCONFIG_V1);
+
+ /* Clear them by writing back */
+ sr_write_reg(sr_info, ERRCONFIG_V1, status);
+ } else if (sr_info->ip_type == SR_TYPE_V2) {
+ /* Read the status bits */
+ status = sr_read_reg(sr_info, IRQSTATUS);
+
+ /* Clear them by writing back */
+ sr_write_reg(sr_info, IRQSTATUS, status);
+ }
+
+ if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
+ sr_class->notify(sr_info->voltdm, status);
+
+ return IRQ_HANDLED;
+}
+
+static void sr_set_clk_length(struct omap_sr *sr)
+{
+ struct clk *sys_ck;
+ u32 sys_clk_speed;
+
+ if (cpu_is_omap34xx())
+ sys_ck = clk_get(NULL, "sys_ck");
+ else
+ sys_ck = clk_get(NULL, "sys_clkin_ck");
+
+ if (IS_ERR(sys_ck)) {
+ dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
+ __func__);
+ return;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+
+ switch (sys_clk_speed) {
+ case 12000000:
+ sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
+ break;
+ case 13000000:
+ sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
+ break;
+ case 19200000:
+ sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
+ break;
+ case 26000000:
+ sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
+ break;
+ case 38400000:
+ sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
+ break;
+ default:
+ dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
+ __func__, sys_clk_speed);
+ break;
+ }
+}
+
+static void sr_set_regfields(struct omap_sr *sr)
+{
+ /*
+ * For time being these values are defined in smartreflex.h
+ * and populated during init. May be they can be moved to board
+ * file or pmic specific data structure. In that case these structure
+ * fields will have to be populated using the pdata or pmic structure.
+ */
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ sr->err_weight = OMAP3430_SR_ERRWEIGHT;
+ sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
+ sr->accum_data = OMAP3430_SR_ACCUMDATA;
+ if (!(strcmp(sr->voltdm->name, "mpu"))) {
+ sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
+ sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
+ } else {
+ sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
+ sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
+ }
+ }
+}
+
+static void sr_start_vddautocomp(struct omap_sr *sr)
+{
+ if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
+ dev_warn(&sr->pdev->dev,
+ "%s: smartreflex class driver not registered\n",
+ __func__);
+ return;
+ }
+
+ if (!sr_class->enable(sr->voltdm))
+ sr->autocomp_active = true;
+}
+
+static void sr_stop_vddautocomp(struct omap_sr *sr)
+{
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev,
+ "%s: smartreflex class driver not registered\n",
+ __func__);
+ return;
+ }
+
+ if (sr->autocomp_active) {
+ sr_class->disable(sr->voltdm, 1);
+ sr->autocomp_active = false;
+ }
+}
+
+/*
+ * This function handles the intializations which have to be done
+ * only when both sr device and class driver regiter has
+ * completed. This will be attempted to be called from both sr class
+ * driver register and sr device intializtion API's. Only one call
+ * will ultimately succeed.
+ *
+ * Currently this function registers interrrupt handler for a particular SR
+ * if smartreflex class driver is already registered and has
+ * requested for interrupts and the SR interrupt line in present.
+ */
+static int sr_late_init(struct omap_sr *sr_info)
+{
+ char *name;
+ struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
+ struct resource *mem;
+ int ret = 0;
+
+ if (sr_class->class_type == SR_CLASS2 &&
+ sr_class->notify_flags && sr_info->irq) {
+
+ name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
+ if (name == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+ ret = request_irq(sr_info->irq, sr_interrupt,
+ 0, name, (void *)sr_info);
+ if (ret)
+ goto error;
+ }
+
+ if (pdata && pdata->enable_on_init)
+ sr_start_vddautocomp(sr_info);
+
+ return ret;
+
+error:
+ iounmap(sr_info->base);
+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ list_del(&sr_info->node);
+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
+ "interrupt handler. Smartreflex will"
+ "not function as desired\n", __func__);
+ kfree(name);
+ kfree(sr_info);
+ return ret;
+}
+
+static void sr_v1_disable(struct omap_sr *sr)
+{
+ int timeout = 0;
+
+ /* Enable MCUDisableAcknowledge interrupt */
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
+
+ /* SRCONFIG - disable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+ /* Disable all other SR interrupts and clear the status */
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+ ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
+ (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
+ ERRCONFIG_MCUBOUNDINTST |
+ ERRCONFIG_VPBOUNDINTST_V1));
+
+ /*
+ * Wait for SR to be disabled.
+ * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
+ */
+ omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
+ ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
+ timeout);
+
+ if (timeout >= SR_DISABLE_TIMEOUT)
+ dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
+ __func__);
+
+ /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+ sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
+ ERRCONFIG_MCUDISACKINTST);
+}
+
+static void sr_v2_disable(struct omap_sr *sr)
+{
+ int timeout = 0;
+
+ /* Enable MCUDisableAcknowledge interrupt */
+ sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
+
+ /* SRCONFIG - disable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
+
+ /* Disable all other SR interrupts and clear the status */
+ sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
+ ERRCONFIG_VPBOUNDINTST_V2);
+ sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
+ IRQENABLE_MCUVALIDINT |
+ IRQENABLE_MCUBOUNDSINT));
+ sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
+ IRQSTATUS_MCVALIDINT |
+ IRQSTATUS_MCBOUNDSINT));
+
+ /*
+ * Wait for SR to be disabled.
+ * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
+ */
+ omap_test_timeout((sr_read_reg(sr, IRQSTATUS) &
+ IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
+ timeout);
+
+ if (timeout >= SR_DISABLE_TIMEOUT)
+ dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
+ __func__);
+
+ /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
+ sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
+ sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
+}
+
+static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
+{
+ int i;
+
+ if (!sr->nvalue_table) {
+ dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
+ __func__);
+ return 0;
+ }
+
+ for (i = 0; i < sr->nvalue_count; i++) {
+ if (sr->nvalue_table[i].efuse_offs == efuse_offs)
+ return sr->nvalue_table[i].nvalue;
+ }
+
+ return 0;
+}
+
+/* Public Functions */
+
+/**
+ * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
+ * error generator module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the error generator module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module. Returns 0 on success and error value in case of failure.
+ */
+int sr_configure_errgen(struct voltagedomain *voltdm)
+{
+ u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en;
+ u32 vpboundint_st, senp_en = 0, senn_en = 0;
+ u8 senp_shift, senn_shift;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!sr->clk_length)
+ sr_set_clk_length(sr);
+
+ senp_en = sr->senp_mod;
+ senn_en = sr->senn_mod;
+
+ sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+ SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
+
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_config |= SRCONFIG_DELAYCTRL;
+ senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
+ errconfig_offs = ERRCONFIG_V1;
+ vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
+ vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
+ errconfig_offs = ERRCONFIG_V2;
+ vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
+ vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
+ } else {
+ dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+ "module without specifying the ip\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
+ sr_write_reg(sr, SRCONFIG, sr_config);
+ sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
+ (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
+ (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT);
+ sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
+ SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
+ sr_errconfig);
+
+ /* Enabling the interrupts if the ERROR module is used */
+ sr_modify_reg(sr, errconfig_offs,
+ vpboundint_en, (vpboundint_en | vpboundint_st));
+
+ return 0;
+}
+
+/**
+ * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
+ * minmaxavg module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * configure the minmaxavg module inside the smartreflex module.
+ * SR settings if using the ERROR module inside Smartreflex.
+ * SR CLASS 3 by default uses only the ERROR module where as
+ * SR CLASS 2 can choose between ERROR module and MINMAXAVG
+ * module. Returns 0 on success and error value in case of failure.
+ */
+int sr_configure_minmax(struct voltagedomain *voltdm)
+{
+ u32 sr_config, sr_avgwt;
+ u32 senp_en = 0, senn_en = 0;
+ u8 senp_shift, senn_shift;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!sr->clk_length)
+ sr_set_clk_length(sr);
+
+ senp_en = sr->senp_mod;
+ senn_en = sr->senn_mod;
+
+ sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
+ SRCONFIG_SENENABLE |
+ (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
+
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_config |= SRCONFIG_DELAYCTRL;
+ senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
+ senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
+ } else {
+ dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
+ "module without specifying the ip\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
+ sr_write_reg(sr, SRCONFIG, sr_config);
+ sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
+ (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
+ sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
+
+ /*
+ * Enabling the interrupts if MINMAXAVG module is used.
+ * TODO: check if all the interrupts are mandatory
+ */
+ if (sr->ip_type == SR_TYPE_V1) {
+ sr_modify_reg(sr, ERRCONFIG_V1,
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
+ ERRCONFIG_MCUBOUNDINTEN),
+ (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
+ ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
+ ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
+ } else if (sr->ip_type == SR_TYPE_V2) {
+ sr_write_reg(sr, IRQSTATUS,
+ IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
+ IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
+ sr_write_reg(sr, IRQENABLE_SET,
+ IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
+ IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
+ }
+
+ return 0;
+}
+
+/**
+ * sr_enable() - Enables the smartreflex module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ * @volt: The voltage at which the Voltage domain associated with
+ * the smartreflex module is operating at.
+ * This is required only to program the correct Ntarget value.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * enable a smartreflex module. Returns 0 on success. Returns error
+ * value if the voltage passed is wrong or if ntarget value is wrong.
+ */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
+{
+ u32 nvalue_reciprocal;
+ struct omap_volt_data *volt_data;
+ struct omap_sr *sr = _sr_lookup(voltdm);
+ int ret;
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
+
+ if (IS_ERR(volt_data)) {
+ dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
+ "for nominal voltage %ld\n", __func__, volt);
+ return -ENODATA;
+ }
+
+ nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
+
+ if (!nvalue_reciprocal) {
+ dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n",
+ __func__, volt);
+ return -ENODATA;
+ }
+
+ /* errminlimit is opp dependent and hence linked to voltage */
+ sr->err_minlimit = volt_data->sr_errminlimit;
+
+ pm_runtime_get_sync(&sr->pdev->dev);
+
+ /* Check if SR is already enabled. If yes do nothing */
+ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
+ return 0;
+
+ /* Configure SR */
+ ret = sr_class->configure(voltdm);
+ if (ret)
+ return ret;
+
+ sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
+
+ /* SRCONFIG - enable SR */
+ sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
+ return 0;
+}
+
+/**
+ * sr_disable() - Disables the smartreflex module.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the smartreflex class driver to
+ * disable a smartreflex module.
+ */
+void sr_disable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* Check if SR clocks are already disabled. If yes do nothing */
+ if (pm_runtime_suspended(&sr->pdev->dev))
+ return;
+
+ /*
+ * Disable SR if only it is indeed enabled. Else just
+ * disable the clocks.
+ */
+ if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
+ if (sr->ip_type == SR_TYPE_V1)
+ sr_v1_disable(sr);
+ else if (sr->ip_type == SR_TYPE_V2)
+ sr_v2_disable(sr);
+ }
+
+ pm_runtime_put_sync(&sr->pdev->dev);
+}
+
+/**
+ * sr_register_class() - API to register a smartreflex class parameters.
+ * @class_data: The structure containing various sr class specific data.
+ *
+ * This API is to be called by the smartreflex class driver to register itself
+ * with the smartreflex driver during init. Returns 0 on success else the
+ * error value.
+ */
+int sr_register_class(struct omap_sr_class_data *class_data)
+{
+ struct omap_sr *sr_info;
+
+ if (!class_data) {
+ pr_warning("%s:, Smartreflex class data passed is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (sr_class) {
+ pr_warning("%s: Smartreflex class driver already registered\n",
+ __func__);
+ return -EBUSY;
+ }
+
+ sr_class = class_data;
+
+ /*
+ * Call into late init to do intializations that require
+ * both sr driver and sr class driver to be initiallized.
+ */
+ list_for_each_entry(sr_info, &sr_list, node)
+ sr_late_init(sr_info);
+
+ return 0;
+}
+
+/**
+ * omap_sr_enable() - API to enable SR clocks and to call into the
+ * registered smartreflex class enable API.
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to enable
+ * a particular smartreflex module. This API will do the initial
+ * configurations to turn on the smartreflex module and in turn call
+ * into the registered smartreflex class enable API.
+ */
+void omap_sr_enable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->enable(voltdm);
+}
+
+/**
+ * omap_sr_disable() - API to disable SR without resetting the voltage
+ * processor voltage
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to disable
+ * a particular smartreflex module. This API will in turn call
+ * into the registered smartreflex class disable API. This API will tell
+ * the smartreflex class disable not to reset the VP voltage after
+ * disabling smartreflex.
+ */
+void omap_sr_disable(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->disable(voltdm, 0);
+}
+
+/**
+ * omap_sr_disable_reset_volt() - API to disable SR and reset the
+ * voltage processor voltage
+ * @voltdm: VDD pointer to which the SR module to be configured belongs to.
+ *
+ * This API is to be called from the kernel in order to disable
+ * a particular smartreflex module. This API will in turn call
+ * into the registered smartreflex class disable API. This API will tell
+ * the smartreflex class disable to reset the VP voltage after
+ * disabling smartreflex.
+ */
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
+{
+ struct omap_sr *sr = _sr_lookup(voltdm);
+
+ if (IS_ERR(sr)) {
+ pr_warning("%s: omap_sr struct for sr_%s not found\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!sr->autocomp_active)
+ return;
+
+ if (!sr_class || !(sr_class->disable)) {
+ dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
+ "registered\n", __func__);
+ return;
+ }
+
+ sr_class->disable(voltdm, 1);
+}
+
+/**
+ * omap_sr_register_pmic() - API to register pmic specific info.
+ * @pmic_data: The structure containing pmic specific data.
+ *
+ * This API is to be called from the PMIC specific code to register with
+ * smartreflex driver pmic specific info. Currently the only info required
+ * is the smartreflex init on the PMIC side.
+ */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
+{
+ if (!pmic_data) {
+ pr_warning("%s: Trying to register NULL PMIC data structure"
+ "with smartreflex\n", __func__);
+ return;
+ }
+
+ sr_pmic_data = pmic_data;
+}
+
+/* PM Debug Fs enteries to enable disable smartreflex. */
+static int omap_sr_autocomp_show(void *data, u64 *val)
+{
+ struct omap_sr *sr_info = (struct omap_sr *) data;
+
+ if (!sr_info) {
+ pr_warning("%s: omap_sr struct not found\n", __func__);
+ return -EINVAL;
+ }
+
+ *val = sr_info->autocomp_active;
+
+ return 0;
+}
+
+static int omap_sr_autocomp_store(void *data, u64 val)
+{
+ struct omap_sr *sr_info = (struct omap_sr *) data;
+
+ if (!sr_info) {
+ pr_warning("%s: omap_sr struct not found\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Sanity check */
+ if (val && (val != 1)) {
+ pr_warning("%s: Invalid argument %lld\n", __func__, val);
+ return -EINVAL;
+ }
+
+ if (!val)
+ sr_stop_vddautocomp(sr_info);
+ else
+ sr_start_vddautocomp(sr_info);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
+ omap_sr_autocomp_store, "%llu\n");
+
+static int __init omap_sr_probe(struct platform_device *pdev)
+{
+ struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+ struct omap_sr_data *pdata = pdev->dev.platform_data;
+ struct resource *mem, *irq;
+ struct dentry *vdd_dbg_dir, *nvalue_dir;
+ struct omap_volt_data *volt_data;
+ int i, ret = 0;
+
+ if (!sr_info) {
+ dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+ ret = -EINVAL;
+ goto err_free_devinfo;
+ }
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem) {
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
+ ret = -ENODEV;
+ goto err_free_devinfo;
+ }
+
+ mem = request_mem_region(mem->start, resource_size(mem),
+ dev_name(&pdev->dev));
+ if (!mem) {
+ dev_err(&pdev->dev, "%s: no mem region\n", __func__);
+ ret = -EBUSY;
+ goto err_free_devinfo;
+ }
+
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ pm_runtime_enable(&pdev->dev);
+
+ sr_info->pdev = pdev;
+ sr_info->srid = pdev->id;
+ sr_info->voltdm = pdata->voltdm;
+ sr_info->nvalue_table = pdata->nvalue_table;
+ sr_info->nvalue_count = pdata->nvalue_count;
+ sr_info->senn_mod = pdata->senn_mod;
+ sr_info->senp_mod = pdata->senp_mod;
+ sr_info->autocomp_active = false;
+ sr_info->ip_type = pdata->ip_type;
+ sr_info->base = ioremap(mem->start, resource_size(mem));
+ if (!sr_info->base) {
+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+ ret = -ENOMEM;
+ goto err_release_region;
+ }
+
+ if (irq)
+ sr_info->irq = irq->start;
+
+ sr_set_clk_length(sr_info);
+ sr_set_regfields(sr_info);
+
+ list_add(&sr_info->node, &sr_list);
+
+ /*
+ * Call into late init to do intializations that require
+ * both sr driver and sr class driver to be initiallized.
+ */
+ if (sr_class) {
+ ret = sr_late_init(sr_info);
+ if (ret) {
+ pr_warning("%s: Error in SR late init\n", __func__);
+ return ret;
+ }
+ }
+
+ dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
+
+ /*
+ * If the voltage domain debugfs directory is not created, do
+ * not try to create rest of the debugfs entries.
+ */
+ vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
+ if (!vdd_dbg_dir) {
+ ret = -EINVAL;
+ goto err_iounmap;
+ }
+
+ sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
+ if (IS_ERR(sr_info->dbg_dir)) {
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
+ __func__);
+ ret = PTR_ERR(sr_info->dbg_dir);
+ goto err_iounmap;
+ }
+
+ (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
+ sr_info->dbg_dir, (void *)sr_info, &pm_sr_fops);
+ (void) debugfs_create_x32("errweight", S_IRUGO, sr_info->dbg_dir,
+ &sr_info->err_weight);
+ (void) debugfs_create_x32("errmaxlimit", S_IRUGO, sr_info->dbg_dir,
+ &sr_info->err_maxlimit);
+ (void) debugfs_create_x32("errminlimit", S_IRUGO, sr_info->dbg_dir,
+ &sr_info->err_minlimit);
+
+ nvalue_dir = debugfs_create_dir("nvalue", sr_info->dbg_dir);
+ if (IS_ERR(nvalue_dir)) {
+ dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
+ "for n-values\n", __func__);
+ ret = PTR_ERR(nvalue_dir);
+ goto err_debugfs;
+ }
+
+ omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
+ if (!volt_data) {
+ dev_warn(&pdev->dev, "%s: No Voltage table for the"
+ " corresponding vdd vdd_%s. Cannot create debugfs"
+ "entries for n-values\n",
+ __func__, sr_info->voltdm->name);
+ ret = -ENODATA;
+ goto err_debugfs;
+ }
+
+ for (i = 0; i < sr_info->nvalue_count; i++) {
+ char name[NVALUE_NAME_LEN + 1];
+
+ snprintf(name, sizeof(name), "volt_%d",
+ volt_data[i].volt_nominal);
+ (void) debugfs_create_x32(name, S_IRUGO | S_IWUSR, nvalue_dir,
+ &(sr_info->nvalue_table[i].nvalue));
+ }
+
+ return ret;
+
+err_debugfs:
+ debugfs_remove_recursive(sr_info->dbg_dir);
+err_iounmap:
+ list_del(&sr_info->node);
+ iounmap(sr_info->base);
+err_release_region:
+ release_mem_region(mem->start, resource_size(mem));
+err_free_devinfo:
+ kfree(sr_info);
+
+ return ret;
+}
+
+static int __devexit omap_sr_remove(struct platform_device *pdev)
+{
+ struct omap_sr_data *pdata = pdev->dev.platform_data;
+ struct omap_sr *sr_info;
+ struct resource *mem;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
+ return -EINVAL;
+ }
+
+ sr_info = _sr_lookup(pdata->voltdm);
+ if (IS_ERR(sr_info)) {
+ dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (sr_info->autocomp_active)
+ sr_stop_vddautocomp(sr_info);
+ if (sr_info->dbg_dir)
+ debugfs_remove_recursive(sr_info->dbg_dir);
+
+ list_del(&sr_info->node);
+ iounmap(sr_info->base);
+ kfree(sr_info);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ return 0;
+}
+
+static struct platform_driver smartreflex_driver = {
+ .remove = omap_sr_remove,
+ .driver = {
+ .name = "smartreflex",
+ },
+};
+
+static int __init sr_init(void)
+{
+ int ret = 0;
+
+ /*
+ * sr_init is a late init. If by then a pmic specific API is not
+ * registered either there is no need for anything to be done on
+ * the PMIC side or somebody has forgotten to register a PMIC
+ * handler. Warn for the second condition.
+ */
+ if (sr_pmic_data && sr_pmic_data->sr_pmic_init)
+ sr_pmic_data->sr_pmic_init();
+ else
+ pr_warning("%s: No PMIC hook to init smartreflex\n", __func__);
+
+ ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
+ if (ret) {
+ pr_err("%s: platform driver register failed for SR\n",
+ __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void __exit sr_exit(void)
+{
+ platform_driver_unregister(&smartreflex_driver);
+}
+late_initcall(sr_init);
+module_exit(sr_exit);
+
+MODULE_DESCRIPTION("OMAP Smartreflex Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
new file mode 100644
index 00000000..5f35b9e2
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -0,0 +1,246 @@
+/*
+ * OMAP Smartreflex Defines and Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
+#define __ASM_ARM_OMAP_SMARTREFLEX_H
+
+#include <linux/platform_device.h>
+
+#include "voltage.h"
+
+/*
+ * Different Smartreflex IPs version. The v1 is the 65nm version used in
+ * OMAP3430. The v2 is the update for the 45nm version of the IP
+ * used in OMAP3630 and OMAP4430
+ */
+#define SR_TYPE_V1 1
+#define SR_TYPE_V2 2
+
+/* SMART REFLEX REG ADDRESS OFFSET */
+#define SRCONFIG 0x00
+#define SRSTATUS 0x04
+#define SENVAL 0x08
+#define SENMIN 0x0C
+#define SENMAX 0x10
+#define SENAVG 0x14
+#define AVGWEIGHT 0x18
+#define NVALUERECIPROCAL 0x1c
+#define SENERROR_V1 0x20
+#define ERRCONFIG_V1 0x24
+#define IRQ_EOI 0x20
+#define IRQSTATUS_RAW 0x24
+#define IRQSTATUS 0x28
+#define IRQENABLE_SET 0x2C
+#define IRQENABLE_CLR 0x30
+#define SENERROR_V2 0x34
+#define ERRCONFIG_V2 0x38
+
+/* Bit/Shift Positions */
+
+/* SRCONFIG */
+#define SRCONFIG_ACCUMDATA_SHIFT 22
+#define SRCONFIG_SRCLKLENGTH_SHIFT 12
+#define SRCONFIG_SENNENABLE_V1_SHIFT 5
+#define SRCONFIG_SENPENABLE_V1_SHIFT 3
+#define SRCONFIG_SENNENABLE_V2_SHIFT 1
+#define SRCONFIG_SENPENABLE_V2_SHIFT 0
+#define SRCONFIG_CLKCTRL_SHIFT 0
+
+#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
+
+#define SRCONFIG_SRENABLE BIT(11)
+#define SRCONFIG_SENENABLE BIT(10)
+#define SRCONFIG_ERRGEN_EN BIT(9)
+#define SRCONFIG_MINMAXAVG_EN BIT(8)
+#define SRCONFIG_DELAYCTRL BIT(2)
+
+/* AVGWEIGHT */
+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
+
+/* NVALUERECIPROCAL */
+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
+
+/* ERRCONFIG */
+#define ERRCONFIG_ERRWEIGHT_SHIFT 16
+#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
+#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
+
+#define SR_ERRWEIGHT_MASK (0x07 << 16)
+#define SR_ERRMAXLIMIT_MASK (0xff << 8)
+#define SR_ERRMINLIMIT_MASK (0xff << 0)
+
+#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
+#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
+#define ERRCONFIG_MCUACCUMINTEN BIT(29)
+#define ERRCONFIG_MCUACCUMINTST BIT(28)
+#define ERRCONFIG_MCUVALIDINTEN BIT(27)
+#define ERRCONFIG_MCUVALIDINTST BIT(26)
+#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
+#define ERRCONFIG_MCUBOUNDINTST BIT(24)
+#define ERRCONFIG_MCUDISACKINTEN BIT(23)
+#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
+#define ERRCONFIG_MCUDISACKINTST BIT(22)
+#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
+
+#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
+ ERRCONFIG_MCUACCUMINTST | \
+ ERRCONFIG_MCUVALIDINTST | \
+ ERRCONFIG_MCUBOUNDINTST | \
+ ERRCONFIG_MCUDISACKINTST)
+/* IRQSTATUS */
+#define IRQSTATUS_MCUACCUMINT BIT(3)
+#define IRQSTATUS_MCVALIDINT BIT(2)
+#define IRQSTATUS_MCBOUNDSINT BIT(1)
+#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
+
+/* IRQENABLE_SET and IRQENABLE_CLEAR */
+#define IRQENABLE_MCUACCUMINT BIT(3)
+#define IRQENABLE_MCUVALIDINT BIT(2)
+#define IRQENABLE_MCUBOUNDSINT BIT(1)
+#define IRQENABLE_MCUDISABLEACKINT BIT(0)
+
+/* Common Bit values */
+
+#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
+#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
+#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
+#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
+#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
+
+/*
+ * 3430 specific values. Maybe these should be passed from board file or
+ * pmic structures.
+ */
+#define OMAP3430_SR_ACCUMDATA 0x1f4
+
+#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
+#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
+
+#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
+#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
+
+#define OMAP3430_SR_ERRWEIGHT 0x04
+#define OMAP3430_SR_ERRMAXLIMIT 0x02
+
+/**
+ * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
+ * pmic specific info to smartreflex driver
+ *
+ * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
+ */
+struct omap_sr_pmic_data {
+ void (*sr_pmic_init) (void);
+};
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+/*
+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
+ * The smartreflex class driver should pass the class type.
+ * Should be used to populate the class_type field of the
+ * omap_smartreflex_class_data structure.
+ */
+#define SR_CLASS1 0x1
+#define SR_CLASS2 0x2
+#define SR_CLASS3 0x3
+
+/**
+ * struct omap_sr_class_data - Smartreflex class driver info
+ *
+ * @enable: API to enable a particular class smaartreflex.
+ * @disable: API to disable a particular class smartreflex.
+ * @configure: API to configure a particular class smartreflex.
+ * @notify: API to notify the class driver about an event in SR.
+ * Not needed for class3.
+ * @notify_flags: specify the events to be notified to the class driver
+ * @class_type: specify which smartreflex class.
+ * Can be used by the SR driver to take any class
+ * based decisions.
+ */
+struct omap_sr_class_data {
+ int (*enable)(struct voltagedomain *voltdm);
+ int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
+ int (*configure)(struct voltagedomain *voltdm);
+ int (*notify)(struct voltagedomain *voltdm, u32 status);
+ u8 notify_flags;
+ u8 class_type;
+};
+
+/**
+ * struct omap_sr_nvalue_table - Smartreflex n-target value info
+ *
+ * @efuse_offs: The offset of the efuse where n-target values are stored.
+ * @nvalue: The n-target value.
+ */
+struct omap_sr_nvalue_table {
+ u32 efuse_offs;
+ u32 nvalue;
+};
+
+/**
+ * struct omap_sr_data - Smartreflex platform data.
+ *
+ * @ip_type: Smartreflex IP type.
+ * @senp_mod: SENPENABLE value for the sr
+ * @senn_mod: SENNENABLE value for sr
+ * @nvalue_count: Number of distinct nvalues in the nvalue table
+ * @enable_on_init: whether this sr module needs to enabled at
+ * boot up or not.
+ * @nvalue_table: table containing the efuse offsets and nvalues
+ * corresponding to them.
+ * @voltdm: Pointer to the voltage domain associated with the SR
+ */
+struct omap_sr_data {
+ int ip_type;
+ u32 senp_mod;
+ u32 senn_mod;
+ int nvalue_count;
+ bool enable_on_init;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+};
+
+/* Smartreflex module enable/disable interface */
+void omap_sr_enable(struct voltagedomain *voltdm);
+void omap_sr_disable(struct voltagedomain *voltdm);
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
+
+/* API to register the pmic specific data with the smartreflex driver. */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
+
+/* Smartreflex driver hooks to be called from Smartreflex class driver */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
+void sr_disable(struct voltagedomain *voltdm);
+int sr_configure_errgen(struct voltagedomain *voltdm);
+int sr_configure_minmax(struct voltagedomain *voltdm);
+
+/* API to register the smartreflex class driver with the smartreflex driver */
+int sr_register_class(struct omap_sr_class_data *class_data);
+#else
+static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable_reset_volt(
+ struct voltagedomain *voltdm) {}
+static inline void omap_sr_register_pmic(
+ struct omap_sr_pmic_data *pmic_data) {}
+#endif
+#endif
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
new file mode 100644
index 00000000..10d3c5ee
--- /dev/null
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -0,0 +1,147 @@
+/*
+ * OMAP3/OMAP4 smartreflex device file
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Based originally on code from smartreflex.c
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+
+#include <plat/omap_device.h>
+
+#include "smartreflex.h"
+#include "voltage.h"
+#include "control.h"
+#include "pm.h"
+
+static bool sr_enable_on_init;
+
+static struct omap_device_pm_latency omap_sr_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
+ },
+};
+
+/* Read EFUSE values from control registers for OMAP3430 */
+static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
+ struct omap_sr_data *sr_data)
+{
+ struct omap_sr_nvalue_table *nvalue_table;
+ int i, count = 0;
+
+ while (volt_data[count].volt_nominal)
+ count++;
+
+ nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
+ GFP_KERNEL);
+
+ for (i = 0; i < count; i++) {
+ u32 v;
+ /*
+ * In OMAP4 the efuse registers are 24 bit aligned.
+ * A __raw_readl will fail for non-32 bit aligned address
+ * and hence the 8-bit read and shift.
+ */
+ if (cpu_is_omap44xx()) {
+ u16 offset = volt_data[i].sr_efuse_offs;
+
+ v = omap_ctrl_readb(offset) |
+ omap_ctrl_readb(offset + 1) << 8 |
+ omap_ctrl_readb(offset + 2) << 16;
+ } else {
+ v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
+ }
+
+ nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs;
+ nvalue_table[i].nvalue = v;
+ }
+
+ sr_data->nvalue_table = nvalue_table;
+ sr_data->nvalue_count = count;
+}
+
+static int sr_dev_init(struct omap_hwmod *oh, void *user)
+{
+ struct omap_sr_data *sr_data;
+ struct omap_device *od;
+ struct omap_volt_data *volt_data;
+ char *name = "smartreflex";
+ static int i;
+
+ sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);
+ if (!sr_data) {
+ pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n",
+ __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ if (!oh->vdd_name) {
+ pr_err("%s: No voltage domain specified for %s."
+ "Cannot initialize\n", __func__, oh->name);
+ goto exit;
+ }
+
+ sr_data->ip_type = oh->class->rev;
+ sr_data->senn_mod = 0x1;
+ sr_data->senp_mod = 0x1;
+
+ sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ if (IS_ERR(sr_data->voltdm)) {
+ pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
+ __func__, oh->vdd_name);
+ goto exit;
+ }
+
+ omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
+ if (!volt_data) {
+ pr_warning("%s: No Voltage table registerd fo VDD%d."
+ "Something really wrong\n\n", __func__, i + 1);
+ goto exit;
+ }
+
+ sr_set_nvalues(volt_data, sr_data);
+
+ sr_data->enable_on_init = sr_enable_on_init;
+
+ od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
+ omap_sr_latency,
+ ARRAY_SIZE(omap_sr_latency), 0);
+ if (IS_ERR(od))
+ pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
+ __func__, name, oh->name);
+exit:
+ i++;
+ kfree(sr_data);
+ return 0;
+}
+
+/*
+ * API to be called from board files to enable smartreflex
+ * autocompensation at init.
+ */
+void __init omap_enable_smartreflex_on_init(void)
+{
+ sr_enable_on_init = true;
+}
+
+int __init omap_devinit_smartreflex(void)
+{
+ return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
+}
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
new file mode 100644
index 00000000..ff9b9dbc
--- /dev/null
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -0,0 +1,330 @@
+/*
+ * linux/arch/arm/mach-omap2/sram242x.S
+ *
+ * Omap2 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/io.h>
+#include <mach/hardware.h>
+
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "sdrc.h"
+
+ .text
+
+ .align 3
+ENTRY(omap242x_sram_ddr_init)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ mov r12, r2 @ capture CS1 vs CS0
+ mov r8, r3 @ capture force parameter
+
+ /* frequency shift down */
+ ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg
+ mov r3, #0x1 @ value for 1x operation
+ str r3, [r2] @ go to L1-freq operation
+
+ /* voltage shift down */
+ mov r9, #0x1 @ set up for L1 voltage call
+ bl voltage_shift @ go drop voltage
+
+ /* dll lock mode */
+ ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r10, [r11] @ get current val
+ cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
+ addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode.
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
+ str r10, [r11] @ commit to DLLA_CTRL
+ bl i_dll_wait @ wait for dll to lock
+
+ /* get dll value */
+ add r11, r11, #0x4 @ get addr of status reg
+ ldr r10, [r11] @ get locked value
+
+ /* voltage shift up */
+ mov r9, #0x0 @ shift back to L0-voltage
+ bl voltage_shift @ go raise voltage
+
+ /* frequency shift up */
+ mov r3, #0x2 @ value for 2x operation
+ str r3, [r2] @ go to L0-freq operation
+
+ /* reset entry mode for dllctrl */
+ sub r11, r11, #0x4 @ move from status to ctrl
+ cmp r12, #0x1 @ normalize if cs1 based
+ subeq r11, r11, #0x8 @ possibly back to DLLA
+ cmp r8, #0x1 @ if forced unlock exit
+ orreq r1, r1, #0x4 @ make sure exit with unlocked value
+ str r1, [r11] @ restore DLLA_CTRL high value
+ add r11, r11, #0x8 @ move to DLLB_CTRL addr
+ str r1, [r11] @ set value DLLB_CTRL
+ bl i_dll_wait @ wait for possible lock
+
+ /* set up for return, DDR should be good */
+ str r10, [r0] @ write dll_status and return counter
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+ /* ensure the DLL has relocked */
+i_dll_wait:
+ mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
+i_dll_delay:
+ subs r4, r4, #0x1
+ bne i_dll_delay
+ mov pc, lr
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift:
+ ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl.
+ ldr r5, [r4] @ get value.
+ ldr r6, prcm_mask_val @ get value of mask
+ and r5, r5, r6 @ apply mask to clear bits
+ orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
+ str r5, [r4] @ set up for change.
+ mov r3, #0x4000 @ get val for force
+ orr r5, r5, r3 @ build value for force
+ str r5, [r4] @ Force transition to L1
+
+ ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter
+ ldr r5, [r3] @ get value
+ add r5, r5, #0x3 @ give it at most 93uS
+volt_delay:
+ ldr r7, [r3] @ get timer value
+ cmp r5, r7 @ time up?
+ bhi volt_delay @ not yet->branch
+ mov pc, lr @ back to caller.
+
+omap242x_sdi_cm_clksel2_pll:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap242x_sdi_sdrc_dlla_ctrl:
+ .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap242x_sdi_prcm_voltctrl:
+ .word OMAP2420_PRCM_VOLTCTRL
+prcm_mask_val:
+ .word 0xFFFF3FFC
+omap242x_sdi_timer_32ksynct_cr:
+ .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+ENTRY(omap242x_sram_ddr_init_sz)
+ .word . - omap242x_sram_ddr_init
+
+/*
+ * Reprograms memory timings.
+ * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
+ * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
+ */
+ .align 3
+ENTRY(omap242x_sram_reprogram_sdrc)
+ stmfd sp!, {r0 - r10, lr} @ save registers on stack
+ mov r3, #0x0 @ clear for mrc call
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
+ nop
+ nop
+ ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg
+ ldr r5, [r6] @ get value
+ mov r5, r5, lsr #8 @ isolate rfr field and drop burst
+
+ cmp r0, #0x1 @ going to half speed?
+ movne r9, #0x0 @ if up set flag up for pre up, hi volt
+
+ blne voltage_shift_c @ adjust voltage
+
+ cmp r0, #0x1 @ going to half speed (post branch link)
+ moveq r5, r5, lsr #1 @ divide by 2 if to half
+ movne r5, r5, lsl #1 @ mult by 2 if to full
+ mov r5, r5, lsl #8 @ put rfr field back into place
+ add r5, r5, #0x1 @ turn on burst of 1
+ ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg
+ ldr r3, [r4] @ get curr value
+ orr r3, r3, #0x3
+ bic r3, r3, #0x3 @ clear lower bits
+ orr r3, r3, r0 @ new state value
+ str r3, [r4] @ set new state (pll/x, x=1 or 2)
+ nop
+ nop
+
+ moveq r9, #0x1 @ if speed down, post down, drop volt
+ bleq voltage_shift_c
+
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier
+ str r5, [r6] @ set new RFR_1 value
+ add r6, r6, #0x30 @ get RFR_2 addr
+ str r5, [r6] @ set RFR_2
+ nop
+ cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
+ bne freq_out @ leave if SDR, no DLL function
+
+ /* With DDR, we need to take care of the DLL for the frequency change */
+ ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl
+ str r1, [r2] @ write out new SDRC_DLLA_CTRL
+ add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
+ str r1, [r2] @ commit to SDRC_DLLB_CTRL
+ mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
+dll_wait:
+ subs r1, r1, #0x1
+ bne dll_wait
+freq_out:
+ ldmfd sp!, {r0 - r10, pc} @ restore regs and return
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift_c:
+ ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl
+ ldr r8, [r10] @ get value
+ ldr r7, ddr_prcm_mask_val @ get value of mask
+ and r8, r8, r7 @ apply mask to clear bits
+ orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
+ str r8, [r10] @ set up for change.
+ mov r7, #0x4000 @ get val for force
+ orr r8, r8, r7 @ build value for force
+ str r8, [r10] @ Force transition to L1
+
+ ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter
+ ldr r8, [r10] @ get value
+ add r8, r8, #0x2 @ give it at most 62uS (min 31+)
+volt_delay_c:
+ ldr r7, [r10] @ get timer value
+ cmp r8, r7 @ time up?
+ bhi volt_delay_c @ not yet->branch
+ mov pc, lr @ back to caller
+
+omap242x_srs_cm_clksel2_pll:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap242x_srs_sdrc_dlla_ctrl:
+ .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap242x_srs_sdrc_rfr_ctrl:
+ .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap242x_srs_prcm_voltctrl:
+ .word OMAP2420_PRCM_VOLTCTRL
+ddr_prcm_mask_val:
+ .word 0xFFFF3FFC
+omap242x_srs_timer_32ksynct:
+ .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010)
+
+ENTRY(omap242x_sram_reprogram_sdrc_sz)
+ .word . - omap242x_sram_reprogram_sdrc
+
+/*
+ * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
+ */
+ .align 3
+ENTRY(omap242x_sram_set_prcm)
+ stmfd sp!, {r0-r12, lr} @ regs to stack
+ adr r4, pbegin @ addr of preload start
+ adr r8, pend @ addr of preload end
+ mcrr p15, 1, r8, r4, c12 @ preload into icache
+pbegin:
+ /* move into fast relock bypass */
+ ldr r8, omap242x_ssp_pll_ctl @ get addr
+ ldr r5, [r8] @ get val
+ mvn r6, #0x3 @ clear mask
+ and r5, r5, r6 @ clear field
+ orr r7, r5, #0x2 @ fast relock val
+ str r7, [r8] @ go to fast relock
+ ldr r4, omap242x_ssp_pll_stat @ addr of stat
+block:
+ /* wait for bypass */
+ ldr r8, [r4] @ stat value
+ and r8, r8, #0x3 @ mask for stat
+ cmp r8, #0x1 @ there yet
+ bne block @ loop if not
+
+ /* set new dpll dividers _after_ in bypass */
+ ldr r4, omap242x_ssp_pll_div @ get addr
+ str r0, [r4] @ set dpll ctrl val
+
+ ldr r4, omap242x_ssp_set_config @ get addr
+ mov r8, #1 @ valid cfg msk
+ str r8, [r4] @ make dividers take
+
+ mov r4, #100 @ dead spin a bit
+wait_a_bit:
+ subs r4, r4, #1 @ dec loop
+ bne wait_a_bit @ delay done?
+
+ /* check if staying in bypass */
+ cmp r2, #0x1 @ stay in bypass?
+ beq pend @ jump over dpll relock
+
+ /* relock DPLL with new vals */
+ ldr r5, omap242x_ssp_pll_stat @ get addr
+ ldr r4, omap242x_ssp_pll_ctl @ get addr
+ orr r8, r7, #0x3 @ val for lock dpll
+ str r8, [r4] @ set val
+ mov r0, #1000 @ dead spin a bit
+wait_more:
+ subs r0, r0, #1 @ dec loop
+ bne wait_more @ delay done?
+wait_lock:
+ ldr r8, [r5] @ get lock val
+ and r8, r8, #3 @ isolate field
+ cmp r8, #2 @ locked?
+ bne wait_lock @ wait if not
+pend:
+ /* update memory timings & briefly lock dll */
+ ldr r4, omap242x_ssp_sdrc_rfr @ get addr
+ str r1, [r4] @ update refresh timing
+ ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl
+ ldr r10, [r11] @ get current val
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ str r10, [r11] @ commit to DLLA_CTRL
+ add r11, r11, #0x8 @ move to dllb
+ str r10, [r11] @ hit DLLB also
+
+ mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
+wait_dll_lock:
+ subs r4, r4, #0x1
+ bne wait_dll_lock
+ nop
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+omap242x_ssp_set_config:
+ .word OMAP2420_PRCM_CLKCFG_CTRL
+omap242x_ssp_pll_ctl:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN)
+omap242x_ssp_pll_stat:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST)
+omap242x_ssp_pll_div:
+ .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap242x_ssp_sdrc_rfr:
+ .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap242x_ssp_dlla_ctrl:
+ .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+
+ENTRY(omap242x_sram_set_prcm_sz)
+ .word . - omap242x_sram_set_prcm
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
new file mode 100644
index 00000000..76730209
--- /dev/null
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -0,0 +1,330 @@
+/*
+ * linux/arch/arm/mach-omap2/sram243x.S
+ *
+ * Omap2 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/io.h>
+#include <mach/hardware.h>
+
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "sdrc.h"
+
+ .text
+
+ .align 3
+ENTRY(omap243x_sram_ddr_init)
+ stmfd sp!, {r0 - r12, lr} @ save registers on stack
+
+ mov r12, r2 @ capture CS1 vs CS0
+ mov r8, r3 @ capture force parameter
+
+ /* frequency shift down */
+ ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg
+ mov r3, #0x1 @ value for 1x operation
+ str r3, [r2] @ go to L1-freq operation
+
+ /* voltage shift down */
+ mov r9, #0x1 @ set up for L1 voltage call
+ bl voltage_shift @ go drop voltage
+
+ /* dll lock mode */
+ ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl
+ ldr r10, [r11] @ get current val
+ cmp r12, #0x1 @ cs1 base (2422 es2.05/1)
+ addeq r11, r11, #0x8 @ if cs1 base, move to DLLB
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode.
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz
+ str r10, [r11] @ commit to DLLA_CTRL
+ bl i_dll_wait @ wait for dll to lock
+
+ /* get dll value */
+ add r11, r11, #0x4 @ get addr of status reg
+ ldr r10, [r11] @ get locked value
+
+ /* voltage shift up */
+ mov r9, #0x0 @ shift back to L0-voltage
+ bl voltage_shift @ go raise voltage
+
+ /* frequency shift up */
+ mov r3, #0x2 @ value for 2x operation
+ str r3, [r2] @ go to L0-freq operation
+
+ /* reset entry mode for dllctrl */
+ sub r11, r11, #0x4 @ move from status to ctrl
+ cmp r12, #0x1 @ normalize if cs1 based
+ subeq r11, r11, #0x8 @ possibly back to DLLA
+ cmp r8, #0x1 @ if forced unlock exit
+ orreq r1, r1, #0x4 @ make sure exit with unlocked value
+ str r1, [r11] @ restore DLLA_CTRL high value
+ add r11, r11, #0x8 @ move to DLLB_CTRL addr
+ str r1, [r11] @ set value DLLB_CTRL
+ bl i_dll_wait @ wait for possible lock
+
+ /* set up for return, DDR should be good */
+ str r10, [r0] @ write dll_status and return counter
+ ldmfd sp!, {r0 - r12, pc} @ restore regs and return
+
+ /* ensure the DLL has relocked */
+i_dll_wait:
+ mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks
+i_dll_delay:
+ subs r4, r4, #0x1
+ bne i_dll_delay
+ mov pc, lr
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift:
+ ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl.
+ ldr r5, [r4] @ get value.
+ ldr r6, prcm_mask_val @ get value of mask
+ and r5, r5, r6 @ apply mask to clear bits
+ orr r5, r5, r9 @ bulld value for L0/L1-volt operation.
+ str r5, [r4] @ set up for change.
+ mov r3, #0x4000 @ get val for force
+ orr r5, r5, r3 @ build value for force
+ str r5, [r4] @ Force transition to L1
+
+ ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter
+ ldr r5, [r3] @ get value
+ add r5, r5, #0x3 @ give it at most 93uS
+volt_delay:
+ ldr r7, [r3] @ get timer value
+ cmp r5, r7 @ time up?
+ bhi volt_delay @ not yet->branch
+ mov pc, lr @ back to caller.
+
+omap243x_sdi_cm_clksel2_pll:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap243x_sdi_sdrc_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap243x_sdi_prcm_voltctrl:
+ .word OMAP2430_PRCM_VOLTCTRL
+prcm_mask_val:
+ .word 0xFFFF3FFC
+omap243x_sdi_timer_32ksynct_cr:
+ .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+ENTRY(omap243x_sram_ddr_init_sz)
+ .word . - omap243x_sram_ddr_init
+
+/*
+ * Reprograms memory timings.
+ * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
+ * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
+ */
+ .align 3
+ENTRY(omap243x_sram_reprogram_sdrc)
+ stmfd sp!, {r0 - r10, lr} @ save registers on stack
+ mov r3, #0x0 @ clear for mrc call
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR
+ nop
+ nop
+ ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg
+ ldr r5, [r6] @ get value
+ mov r5, r5, lsr #8 @ isolate rfr field and drop burst
+
+ cmp r0, #0x1 @ going to half speed?
+ movne r9, #0x0 @ if up set flag up for pre up, hi volt
+
+ blne voltage_shift_c @ adjust voltage
+
+ cmp r0, #0x1 @ going to half speed (post branch link)
+ moveq r5, r5, lsr #1 @ divide by 2 if to half
+ movne r5, r5, lsl #1 @ mult by 2 if to full
+ mov r5, r5, lsl #8 @ put rfr field back into place
+ add r5, r5, #0x1 @ turn on burst of 1
+ ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg
+ ldr r3, [r4] @ get curr value
+ orr r3, r3, #0x3
+ bic r3, r3, #0x3 @ clear lower bits
+ orr r3, r3, r0 @ new state value
+ str r3, [r4] @ set new state (pll/x, x=1 or 2)
+ nop
+ nop
+
+ moveq r9, #0x1 @ if speed down, post down, drop volt
+ bleq voltage_shift_c
+
+ mcr p15, 0, r3, c7, c10, 4 @ memory barrier
+ str r5, [r6] @ set new RFR_1 value
+ add r6, r6, #0x30 @ get RFR_2 addr
+ str r5, [r6] @ set RFR_2
+ nop
+ cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL
+ bne freq_out @ leave if SDR, no DLL function
+
+ /* With DDR, we need to take care of the DLL for the frequency change */
+ ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl
+ str r1, [r2] @ write out new SDRC_DLLA_CTRL
+ add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL
+ str r1, [r2] @ commit to SDRC_DLLB_CTRL
+ mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks
+dll_wait:
+ subs r1, r1, #0x1
+ bne dll_wait
+freq_out:
+ ldmfd sp!, {r0 - r10, pc} @ restore regs and return
+
+ /*
+ * shift up or down voltage, use R9 as input to tell level.
+ * wait for it to finish, use 32k sync counter, 1tick=31uS.
+ */
+voltage_shift_c:
+ ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl
+ ldr r8, [r10] @ get value
+ ldr r7, ddr_prcm_mask_val @ get value of mask
+ and r8, r8, r7 @ apply mask to clear bits
+ orr r8, r8, r9 @ bulld value for L0/L1-volt operation.
+ str r8, [r10] @ set up for change.
+ mov r7, #0x4000 @ get val for force
+ orr r8, r8, r7 @ build value for force
+ str r8, [r10] @ Force transition to L1
+
+ ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter
+ ldr r8, [r10] @ get value
+ add r8, r8, #0x2 @ give it at most 62uS (min 31+)
+volt_delay_c:
+ ldr r7, [r10] @ get timer value
+ cmp r8, r7 @ time up?
+ bhi volt_delay_c @ not yet->branch
+ mov pc, lr @ back to caller
+
+omap243x_srs_cm_clksel2_pll:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2)
+omap243x_srs_sdrc_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+omap243x_srs_sdrc_rfr_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap243x_srs_prcm_voltctrl:
+ .word OMAP2430_PRCM_VOLTCTRL
+ddr_prcm_mask_val:
+ .word 0xFFFF3FFC
+omap243x_srs_timer_32ksynct:
+ .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010)
+
+ENTRY(omap243x_sram_reprogram_sdrc_sz)
+ .word . - omap243x_sram_reprogram_sdrc
+
+/*
+ * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
+ */
+ .align 3
+ENTRY(omap243x_sram_set_prcm)
+ stmfd sp!, {r0-r12, lr} @ regs to stack
+ adr r4, pbegin @ addr of preload start
+ adr r8, pend @ addr of preload end
+ mcrr p15, 1, r8, r4, c12 @ preload into icache
+pbegin:
+ /* move into fast relock bypass */
+ ldr r8, omap243x_ssp_pll_ctl @ get addr
+ ldr r5, [r8] @ get val
+ mvn r6, #0x3 @ clear mask
+ and r5, r5, r6 @ clear field
+ orr r7, r5, #0x2 @ fast relock val
+ str r7, [r8] @ go to fast relock
+ ldr r4, omap243x_ssp_pll_stat @ addr of stat
+block:
+ /* wait for bypass */
+ ldr r8, [r4] @ stat value
+ and r8, r8, #0x3 @ mask for stat
+ cmp r8, #0x1 @ there yet
+ bne block @ loop if not
+
+ /* set new dpll dividers _after_ in bypass */
+ ldr r4, omap243x_ssp_pll_div @ get addr
+ str r0, [r4] @ set dpll ctrl val
+
+ ldr r4, omap243x_ssp_set_config @ get addr
+ mov r8, #1 @ valid cfg msk
+ str r8, [r4] @ make dividers take
+
+ mov r4, #100 @ dead spin a bit
+wait_a_bit:
+ subs r4, r4, #1 @ dec loop
+ bne wait_a_bit @ delay done?
+
+ /* check if staying in bypass */
+ cmp r2, #0x1 @ stay in bypass?
+ beq pend @ jump over dpll relock
+
+ /* relock DPLL with new vals */
+ ldr r5, omap243x_ssp_pll_stat @ get addr
+ ldr r4, omap243x_ssp_pll_ctl @ get addr
+ orr r8, r7, #0x3 @ val for lock dpll
+ str r8, [r4] @ set val
+ mov r0, #1000 @ dead spin a bit
+wait_more:
+ subs r0, r0, #1 @ dec loop
+ bne wait_more @ delay done?
+wait_lock:
+ ldr r8, [r5] @ get lock val
+ and r8, r8, #3 @ isolate field
+ cmp r8, #2 @ locked?
+ bne wait_lock @ wait if not
+pend:
+ /* update memory timings & briefly lock dll */
+ ldr r4, omap243x_ssp_sdrc_rfr @ get addr
+ str r1, [r4] @ update refresh timing
+ ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl
+ ldr r10, [r11] @ get current val
+ mvn r9, #0x4 @ mask to get clear bit2
+ and r10, r10, r9 @ clear bit2 for lock mode
+ orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos)
+ str r10, [r11] @ commit to DLLA_CTRL
+ add r11, r11, #0x8 @ move to dllb
+ str r10, [r11] @ hit DLLB also
+
+ mov r4, #0x800 @ relock time (min 0x400 L3 clocks)
+wait_dll_lock:
+ subs r4, r4, #0x1
+ bne wait_dll_lock
+ nop
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+omap243x_ssp_set_config:
+ .word OMAP2430_PRCM_CLKCFG_CTRL
+omap243x_ssp_pll_ctl:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN)
+omap243x_ssp_pll_stat:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST)
+omap243x_ssp_pll_div:
+ .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap243x_ssp_sdrc_rfr:
+ .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap243x_ssp_dlla_ctrl:
+ .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL)
+
+ENTRY(omap243x_sram_set_prcm_sz)
+ .word . - omap243x_sram_set_prcm
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
new file mode 100644
index 00000000..6f5849aa
--- /dev/null
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -0,0 +1,346 @@
+/*
+ * linux/arch/arm/mach-omap3/sram.S
+ *
+ * Omap3 specific functions that need to be run in internal SRAM
+ *
+ * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Rajendra Nayak <rnayak@ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Paul Walmsley
+ *
+ * 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 <mach/hardware.h>
+
+#include <mach/io.h>
+
+#include "sdrc.h"
+#include "cm2xxx_3xxx.h"
+
+/*
+ * This file needs be built unconditionally as ARM to interoperate correctly
+ * with non-Thumb-2-capable firmware.
+ */
+ .arm
+
+ .text
+
+/* r1 parameters */
+#define SDRC_NO_UNLOCK_DLL 0x0
+#define SDRC_UNLOCK_DLL 0x1
+
+/* SDRC_DLLA_CTRL bit settings */
+#define FIXEDDELAY_SHIFT 24
+#define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT)
+#define DLLIDLE_MASK 0x4
+
+/*
+ * SDRC_DLLA_CTRL default values: TI hardware team indicates that
+ * FIXEDDELAY should be initialized to 0xf. This apparently was
+ * empirically determined during process testing, so no derivation
+ * was provided.
+ */
+#define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT)
+
+/* SDRC_DLLA_STATUS bit settings */
+#define LOCKSTATUS_MASK 0x4
+
+/* SDRC_POWER bit settings */
+#define SRFRONIDLEREQ_MASK 0x40
+
+/* CM_IDLEST1_CORE bit settings */
+#define ST_SDRC_MASK 0x2
+
+/* CM_ICLKEN1_CORE bit settings */
+#define EN_SDRC_MASK 0x2
+
+/* CM_CLKSEL1_PLL bit settings */
+#define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b
+
+/*
+ * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
+ *
+ * Params passed in registers:
+ * r0 = new M2 divider setting (only 1 and 2 supported right now)
+ * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for
+ * SDRC rates < 83MHz
+ * r2 = number of MPU cycles to wait for SDRC to stabilize after
+ * reprogramming the SDRC when switching to a slower MPU speed
+ * r3 = increasing SDRC rate? (1 = yes, 0 = no)
+ *
+ * Params passed via the stack. The needed params will be copied in SRAM
+ * before use by the code in SRAM (SDRAM is not accessible during SDRC
+ * reconfiguration):
+ * new SDRC_RFR_CTRL_0 register contents
+ * new SDRC_ACTIM_CTRL_A_0 register contents
+ * new SDRC_ACTIM_CTRL_B_0 register contents
+ * new SDRC_MR_0 register value
+ * new SDRC_RFR_CTRL_1 register contents
+ * new SDRC_ACTIM_CTRL_A_1 register contents
+ * new SDRC_ACTIM_CTRL_B_1 register contents
+ * new SDRC_MR_1 register value
+ *
+ * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into
+ * the SDRC CS1 registers
+ *
+ * NOTE: This code no longer attempts to program the SDRC AC timing and MR
+ * registers. This is because the code currently cannot ensure that all
+ * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the
+ * SDRAM when the registers are written. If the registers are changed while
+ * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC
+ * may enter an unpredictable state. In the future, the intent is to
+ * re-enable this code in cases where we can ensure that no initiators are
+ * touching the SDRAM. Until that time, users who know that their use case
+ * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING
+ * option.
+ *
+ * Richard Woodruff notes that any changes to this code must be carefully
+ * audited and tested to ensure that they don't cause a TLB miss while
+ * the SDRAM is inaccessible. Such a situation will crash the system
+ * since it will cause the ARM MMU to attempt to walk the page tables.
+ * These crashes may be intermittent.
+ */
+ .align 3
+ENTRY(omap3_sram_configure_core_dpll)
+ stmfd sp!, {r1-r12, lr} @ store regs to stack
+
+ @ pull the extra args off the stack
+ @ and store them in SRAM
+
+/*
+ * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour
+ * in Thumb-2: use a r7 as a base instead.
+ * Be careful not to clobber r7 when maintaing this file.
+ */
+ THUMB( adr r7, omap3_sram_configure_core_dpll )
+ .macro strtext Rt:req, label:req
+ ARM( str \Rt, \label )
+ THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] )
+ .endm
+
+ ldr r4, [sp, #52]
+ strtext r4, omap_sdrc_rfr_ctrl_0_val
+ ldr r4, [sp, #56]
+ strtext r4, omap_sdrc_actim_ctrl_a_0_val
+ ldr r4, [sp, #60]
+ strtext r4, omap_sdrc_actim_ctrl_b_0_val
+ ldr r4, [sp, #64]
+ strtext r4, omap_sdrc_mr_0_val
+ ldr r4, [sp, #68]
+ strtext r4, omap_sdrc_rfr_ctrl_1_val
+ cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0,
+ beq skip_cs1_params @ do not use cs1 params
+ ldr r4, [sp, #72]
+ strtext r4, omap_sdrc_actim_ctrl_a_1_val
+ ldr r4, [sp, #76]
+ strtext r4, omap_sdrc_actim_ctrl_b_1_val
+ ldr r4, [sp, #80]
+ strtext r4, omap_sdrc_mr_1_val
+skip_cs1_params:
+ mrc p15, 0, r8, c1, c0, 0 @ read ctrl register
+ bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction
+ mcr p15, 0, r10, c1, c0, 0 @ write ctrl register
+ dsb @ flush buffered writes to interconnect
+ isb @ prevent speculative exec past here
+ cmp r3, #1 @ if increasing SDRC clk rate,
+ bleq configure_sdrc @ program the SDRC regs early (for RFR)
+ cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state
+ bleq unlock_dll
+ blne lock_dll
+ bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC
+ bl configure_core_dpll @ change the DPLL3 M2 divider
+ mov r12, r2
+ bl wait_clk_stable @ wait for SDRC to stabilize
+ bl enable_sdrc @ take SDRC out of idle
+ cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change
+ bleq wait_dll_unlock
+ blne wait_dll_lock
+ cmp r3, #1 @ if increasing SDRC clk rate,
+ beq return_to_sdram @ return to SDRAM code, otherwise,
+ bl configure_sdrc @ reprogram SDRC regs now
+return_to_sdram:
+ mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register
+ isb @ prevent speculative exec past here
+ mov r0, #0 @ return value
+ ldmfd sp!, {r1-r12, pc} @ restore regs and return
+unlock_dll:
+ ldr r11, omap3_sdrc_dlla_ctrl
+ ldr r12, [r11]
+ bic r12, r12, #FIXEDDELAY_MASK
+ orr r12, r12, #FIXEDDELAY_DEFAULT
+ orr r12, r12, #DLLIDLE_MASK
+ str r12, [r11] @ (no OCP barrier needed)
+ bx lr
+lock_dll:
+ ldr r11, omap3_sdrc_dlla_ctrl
+ ldr r12, [r11]
+ bic r12, r12, #DLLIDLE_MASK
+ str r12, [r11] @ (no OCP barrier needed)
+ bx lr
+sdram_in_selfrefresh:
+ ldr r11, omap3_sdrc_power @ read the SDRC_POWER register
+ ldr r12, [r11] @ read the contents of SDRC_POWER
+ mov r9, r12 @ keep a copy of SDRC_POWER bits
+ orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle
+ str r12, [r11] @ write back to SDRC_POWER register
+ ldr r12, [r11] @ posted-write barrier for SDRC
+idle_sdrc:
+ ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
+ ldr r12, [r11]
+ bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC
+ str r12, [r11]
+wait_sdrc_idle:
+ ldr r11, omap3_cm_idlest1_core
+ ldr r12, [r11]
+ and r12, r12, #ST_SDRC_MASK @ check for SDRC idle
+ cmp r12, #ST_SDRC_MASK
+ bne wait_sdrc_idle
+ bx lr
+configure_core_dpll:
+ ldr r11, omap3_cm_clksel1_pll
+ ldr r12, [r11]
+ ldr r10, core_m2_mask_val @ modify m2 for core dpll
+ and r12, r12, r10
+ orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
+ str r12, [r11]
+ ldr r12, [r11] @ posted-write barrier for CM
+ bx lr
+wait_clk_stable:
+ subs r12, r12, #1
+ bne wait_clk_stable
+ bx lr
+enable_sdrc:
+ ldr r11, omap3_cm_iclken1_core
+ ldr r12, [r11]
+ orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC
+ str r12, [r11]
+wait_sdrc_idle1:
+ ldr r11, omap3_cm_idlest1_core
+ ldr r12, [r11]
+ and r12, r12, #ST_SDRC_MASK
+ cmp r12, #0
+ bne wait_sdrc_idle1
+restore_sdrc_power_val:
+ ldr r11, omap3_sdrc_power
+ str r9, [r11] @ restore SDRC_POWER, no barrier needed
+ bx lr
+wait_dll_lock:
+ ldr r11, omap3_sdrc_dlla_status
+ ldr r12, [r11]
+ and r12, r12, #LOCKSTATUS_MASK
+ cmp r12, #LOCKSTATUS_MASK
+ bne wait_dll_lock
+ bx lr
+wait_dll_unlock:
+ ldr r11, omap3_sdrc_dlla_status
+ ldr r12, [r11]
+ and r12, r12, #LOCKSTATUS_MASK
+ cmp r12, #0x0
+ bne wait_dll_unlock
+ bx lr
+configure_sdrc:
+ ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM
+ ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM
+ str r12, [r11] @ store
+#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
+ ldr r12, omap_sdrc_actim_ctrl_a_0_val
+ ldr r11, omap3_sdrc_actim_ctrl_a_0
+ str r12, [r11]
+ ldr r12, omap_sdrc_actim_ctrl_b_0_val
+ ldr r11, omap3_sdrc_actim_ctrl_b_0
+ str r12, [r11]
+ ldr r12, omap_sdrc_mr_0_val
+ ldr r11, omap3_sdrc_mr_0
+ str r12, [r11]
+#endif
+ ldr r12, omap_sdrc_rfr_ctrl_1_val
+ cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0,
+ beq skip_cs1_prog @ do not program cs1 params
+ ldr r11, omap3_sdrc_rfr_ctrl_1
+ str r12, [r11]
+#ifdef CONFIG_OMAP3_SDRC_AC_TIMING
+ ldr r12, omap_sdrc_actim_ctrl_a_1_val
+ ldr r11, omap3_sdrc_actim_ctrl_a_1
+ str r12, [r11]
+ ldr r12, omap_sdrc_actim_ctrl_b_1_val
+ ldr r11, omap3_sdrc_actim_ctrl_b_1
+ str r12, [r11]
+ ldr r12, omap_sdrc_mr_1_val
+ ldr r11, omap3_sdrc_mr_1
+ str r12, [r11]
+#endif
+skip_cs1_prog:
+ ldr r12, [r11] @ posted-write barrier for SDRC
+ bx lr
+
+ .align
+omap3_sdrc_power:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+omap3_cm_clksel1_pll:
+ .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap3_cm_idlest1_core:
+ .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST)
+omap3_cm_iclken1_core:
+ .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
+
+omap3_sdrc_rfr_ctrl_0:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap3_sdrc_rfr_ctrl_1:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1)
+omap3_sdrc_actim_ctrl_a_0:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
+omap3_sdrc_actim_ctrl_a_1:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1)
+omap3_sdrc_actim_ctrl_b_0:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
+omap3_sdrc_actim_ctrl_b_1:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1)
+omap3_sdrc_mr_0:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0)
+omap3_sdrc_mr_1:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1)
+omap_sdrc_rfr_ctrl_0_val:
+ .word 0xDEADBEEF
+omap_sdrc_rfr_ctrl_1_val:
+ .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_a_0_val:
+ .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_a_1_val:
+ .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_b_0_val:
+ .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_b_1_val:
+ .word 0xDEADBEEF
+omap_sdrc_mr_0_val:
+ .word 0xDEADBEEF
+omap_sdrc_mr_1_val:
+ .word 0xDEADBEEF
+
+omap3_sdrc_dlla_status:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
+omap3_sdrc_dlla_ctrl:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
+core_m2_mask_val:
+ .word 0x07FFFFFF
+ENDPROC(omap3_sram_configure_core_dpll)
+
+ENTRY(omap3_sram_configure_core_dpll_sz)
+ .word . - omap3_sram_configure_core_dpll
+
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
new file mode 100644
index 00000000..3b9cf85f
--- /dev/null
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -0,0 +1,266 @@
+/*
+ * linux/arch/arm/mach-omap2/timer-gp.c
+ *
+ * OMAP2 GP timer support.
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Update to use new clocksource/clockevent layers
+ * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *
+ * Original driver:
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Paul Mundt <paul.mundt@nokia.com>
+ * Juha Yrjölä <juha.yrjola@nokia.com>
+ * OMAP Dual-mode timer framework support by Timo Teras
+ *
+ * Some parts based off of TI's 24xx code:
+ *
+ * Copyright (C) 2004-2009 Texas Instruments, Inc.
+ *
+ * Roughly modelled after the OMAP1 MPU timer code.
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+#include <plat/dmtimer.h>
+#include <asm/localtimer.h>
+#include <asm/sched_clock.h>
+#include <plat/common.h>
+#include <plat/omap_hwmod.h>
+
+#include "timer-gp.h"
+
+
+/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
+#define MAX_GPTIMER_ID 12
+
+static struct omap_dm_timer *gptimer;
+static struct clock_event_device clockevent_gpt;
+static u8 __initdata gptimer_id = 1;
+static u8 __initdata inited;
+struct omap_dm_timer *gptimer_wakeup;
+
+static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
+{
+ struct omap_dm_timer *gpt = (struct omap_dm_timer *)dev_id;
+ struct clock_event_device *evt = &clockevent_gpt;
+
+ omap_dm_timer_write_status(gpt, OMAP_TIMER_INT_OVERFLOW);
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap2_gp_timer_irq = {
+ .name = "gp timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = omap2_gp_timer_interrupt,
+};
+
+static int omap2_gp_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles);
+
+ return 0;
+}
+
+static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 period;
+
+ omap_dm_timer_stop(gptimer);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ;
+ period -= 1;
+ omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period);
+ 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 clockevent_gpt = {
+ .name = "gp timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_next_event = omap2_gp_timer_set_next_event,
+ .set_mode = omap2_gp_timer_set_mode,
+};
+
+/**
+ * omap2_gp_clockevent_set_gptimer - set which GPTIMER is used for clockevents
+ * @id: GPTIMER to use (1..MAX_GPTIMER_ID)
+ *
+ * Define the GPTIMER that the system should use for the tick timer.
+ * Meant to be called from board-*.c files in the event that GPTIMER1, the
+ * default, is unsuitable. Returns -EINVAL on error or 0 on success.
+ */
+int __init omap2_gp_clockevent_set_gptimer(u8 id)
+{
+ if (id < 1 || id > MAX_GPTIMER_ID)
+ return -EINVAL;
+
+ BUG_ON(inited);
+
+ gptimer_id = id;
+
+ return 0;
+}
+
+static void __init omap2_gp_clockevent_init(void)
+{
+ u32 tick_rate;
+ int src;
+ char clockevent_hwmod_name[8]; /* 8 = sizeof("timerXX0") */
+
+ inited = 1;
+
+ sprintf(clockevent_hwmod_name, "timer%d", gptimer_id);
+ omap_hwmod_setup_one(clockevent_hwmod_name);
+
+ gptimer = omap_dm_timer_request_specific(gptimer_id);
+ BUG_ON(gptimer == NULL);
+ gptimer_wakeup = gptimer;
+
+#if defined(CONFIG_OMAP_32K_TIMER)
+ src = OMAP_TIMER_SRC_32_KHZ;
+#else
+ src = OMAP_TIMER_SRC_SYS_CLK;
+ WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the "
+ "secure 32KiHz clock source\n");
+#endif
+
+ if (gptimer_id != 12)
+ WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)),
+ "timer-gp: omap_dm_timer_set_source() failed\n");
+
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer));
+
+ pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n",
+ gptimer_id, tick_rate);
+
+ omap2_gp_timer_irq.dev_id = (void *)gptimer;
+ setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
+ omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
+
+ clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC,
+ clockevent_gpt.shift);
+ clockevent_gpt.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &clockevent_gpt);
+ clockevent_gpt.min_delta_ns =
+ clockevent_delta2ns(3, &clockevent_gpt);
+ /* Timer internal resynch latency. */
+
+ clockevent_gpt.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_gpt);
+}
+
+/* Clocksource code */
+
+#ifdef CONFIG_OMAP_32K_TIMER
+/*
+ * When 32k-timer is enabled, don't use GPTimer for clocksource
+ * instead, just leave default clocksource which uses the 32k
+ * sync counter. See clocksource setup in plat-omap/counter_32k.c
+ */
+
+static void __init omap2_gp_clocksource_init(void)
+{
+ omap_init_clocksource_32k();
+}
+
+#else
+/*
+ * clocksource
+ */
+static DEFINE_CLOCK_DATA(cd);
+static struct omap_dm_timer *gpt_clocksource;
+static cycle_t clocksource_read_cycles(struct clocksource *cs)
+{
+ return (cycle_t)omap_dm_timer_read_counter(gpt_clocksource);
+}
+
+static struct clocksource clocksource_gpt = {
+ .name = "gp timer",
+ .rating = 300,
+ .read = clocksource_read_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void notrace dmtimer_update_sched_clock(void)
+{
+ u32 cyc;
+
+ cyc = omap_dm_timer_read_counter(gpt_clocksource);
+
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/* Setup free-running counter for clocksource */
+static void __init omap2_gp_clocksource_init(void)
+{
+ static struct omap_dm_timer *gpt;
+ u32 tick_rate;
+ static char err1[] __initdata = KERN_ERR
+ "%s: failed to request dm-timer\n";
+ static char err2[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ gpt = omap_dm_timer_request();
+ if (!gpt)
+ printk(err1, clocksource_gpt.name);
+ gpt_clocksource = gpt;
+
+ omap_dm_timer_set_source(gpt, OMAP_TIMER_SRC_SYS_CLK);
+ tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt));
+
+ omap_dm_timer_set_load_start(gpt, 1, 0);
+
+ init_sched_clock(&cd, dmtimer_update_sched_clock, 32, tick_rate);
+
+ if (clocksource_register_hz(&clocksource_gpt, tick_rate))
+ printk(err2, clocksource_gpt.name);
+}
+#endif
+
+static void __init omap2_gp_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+ if (cpu_is_omap44xx()) {
+ twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
+ BUG_ON(!twd_base);
+ }
+#endif
+ omap_dm_timer_init();
+
+ omap2_gp_clockevent_init();
+ omap2_gp_clocksource_init();
+}
+
+struct sys_timer omap_timer = {
+ .init = omap2_gp_timer_init,
+};
diff --git a/arch/arm/mach-omap2/timer-gp.h b/arch/arm/mach-omap2/timer-gp.h
new file mode 100644
index 00000000..5c1072c6
--- /dev/null
+++ b/arch/arm/mach-omap2/timer-gp.h
@@ -0,0 +1,16 @@
+/*
+ * OMAP2/3 GPTIMER support.headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_TIMER_GP_H
+
+extern int __init omap2_gp_clockevent_set_gptimer(u8 id);
+
+#endif
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
new file mode 100644
index 00000000..31c0ac4c
--- /dev/null
+++ b/arch/arm/mach-omap2/timer-mpu.c
@@ -0,0 +1,39 @@
+/*
+ * The MPU local timer source file. In OMAP4, both cortex-a9 cores have
+ * own timer in it's MPU domain. These timers will be driving the
+ * linux kernel SMP tick framework when active. These timers are not
+ * part of the wake up domain.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This file is based on arm realview smp platform file.
+ * Copyright (C) 2002 ARM 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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/irq.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+int __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ /* Local timers are not supprted on OMAP4430 ES1.0 */
+ if (omap_rev() == OMAP4430_REV_ES1_0)
+ return -ENXIO;
+
+ evt->irq = OMAP44XX_IRQ_LOCALTIMER;
+ twd_timer_setup(evt);
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c
new file mode 100644
index 00000000..14810787
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-fs.c
@@ -0,0 +1,359 @@
+/*
+ * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
+ *
+ * Copyright (C) 2004 Texas Instruments, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/irq.h>
+
+#include <plat/usb.h>
+#include <plat/board.h>
+
+#include "control.h"
+#include "mux.h"
+
+#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
+#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
+#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
+#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
+#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
+
+#if defined(CONFIG_ARCH_OMAP2)
+
+#ifdef CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+ /* order is significant! */
+ { /* registers */
+ .start = UDC_BASE,
+ .end = UDC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, { /* general IRQ */
+ .start = INT_USB_IRQ_GEN,
+ .flags = IORESOURCE_IRQ,
+ }, { /* PIO IRQ */
+ .start = INT_USB_IRQ_NISO,
+ .flags = IORESOURCE_IRQ,
+ }, { /* SOF IRQ */
+ .start = INT_USB_IRQ_ISO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+ .name = "omap_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+};
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+ pdata->udc_device = &udc_device;
+}
+
+#else
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = OMAP_OHCI_BASE,
+ .end = OMAP_OHCI_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_IRQ_HGEN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+ pdata->ohci_device = &ohci_device;
+}
+
+#else
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+ /* order is significant! */
+ {
+ .start = OTG_BASE,
+ .end = OTG_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_USB_IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device otg_device = {
+ .name = "omap_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(otg_resources),
+ .resource = otg_resources,
+};
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+ pdata->otg_device = &otg_device;
+}
+
+#else
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+static void omap2_usb_devconf_clear(u8 port, u32 mask)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r &= ~USBTXWRMODEI(port, mask);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb_devconf_set(u8 port, u32 mask)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r |= USBTXWRMODEI(port, mask);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb2_disable_5pinbitll(void)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb2_enable_5pinunitll(void)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI;
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb_devconf_clear(0, USB_BIDIR_TLL);
+
+ if (nwires == 0)
+ return 0;
+
+ if (is_device)
+ omap_mux_init_signal("usb0_puen", 0);
+
+ omap_mux_init_signal("usb0_dat", 0);
+ omap_mux_init_signal("usb0_txen", 0);
+ omap_mux_init_signal("usb0_se0", 0);
+ if (nwires != 3)
+ omap_mux_init_signal("usb0_rcv", 0);
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(0, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(0, USB_BIDIR);
+ break;
+ case 6:
+ syscon1 = 3;
+ omap_mux_init_signal("usb0_vp", 0);
+ omap_mux_init_signal("usb0_vm", 0);
+ omap2_usb_devconf_set(0, USB_UNIDIR);
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 0, nwires);
+ }
+
+ return syscon1 << 16;
+}
+
+static u32 __init omap2_usb1_init(unsigned nwires)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb_devconf_clear(1, USB_BIDIR_TLL);
+
+ if (nwires == 0)
+ return 0;
+
+ /* NOTE: board-specific code must set up pin muxing for usb1,
+ * since each signal could come out on either of two balls.
+ */
+
+ switch (nwires) {
+ case 2:
+ /* NOTE: board-specific code must override this setting if
+ * this TLL link is not using DP/DM
+ */
+ syscon1 = 1;
+ omap2_usb_devconf_set(1, USB_BIDIR_TLL);
+ break;
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(1, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(1, USB_BIDIR);
+ break;
+ case 6:
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 1, nwires);
+ }
+
+ return syscon1 << 20;
+}
+
+static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb2_disable_5pinbitll();
+ alt_pingroup = 0;
+
+ /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
+ if (alt_pingroup || nwires == 0)
+ return 0;
+
+ omap_mux_init_signal("usb2_dat", 0);
+ omap_mux_init_signal("usb2_se0", 0);
+ if (nwires > 2)
+ omap_mux_init_signal("usb2_txen", 0);
+ if (nwires > 3)
+ omap_mux_init_signal("usb2_rcv", 0);
+
+ switch (nwires) {
+ case 2:
+ /* NOTE: board-specific code must override this setting if
+ * this TLL link is not using DP/DM
+ */
+ syscon1 = 1;
+ omap2_usb_devconf_set(2, USB_BIDIR_TLL);
+ break;
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(2, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(2, USB_BIDIR);
+ break;
+ case 5:
+ /* NOTE: board-specific code must mux this setting depending
+ * on TLL link using DP/DM. Something must also
+ * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
+ * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0
+ * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0
+ */
+
+ syscon1 = 3;
+ omap2_usb2_enable_5pinunitll();
+ break;
+ case 6:
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 2, nwires);
+ }
+
+ return syscon1 << 24;
+}
+
+void __init omap2_usbfs_init(struct omap_usb_config *pdata)
+{
+ struct clk *ick;
+
+ if (!cpu_is_omap24xx())
+ return;
+
+ ick = clk_get(NULL, "usb_l4_ick");
+ if (IS_ERR(ick))
+ return;
+
+ clk_enable(ick);
+ pdata->usb0_init = omap2_usb0_init;
+ pdata->usb1_init = omap2_usb1_init;
+ pdata->usb2_init = omap2_usb2_init;
+ udc_device_init(pdata);
+ ohci_device_init(pdata);
+ otg_device_init(pdata);
+ omap_otg_init(pdata);
+ clk_disable(ick);
+ clk_put(ick);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
new file mode 100644
index 00000000..89ae2984
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -0,0 +1,574 @@
+/*
+ * usb-host.c - OMAP USB Host
+ *
+ * This file will contain the board specific details for the
+ * Synopsys EHCI/OHCI host controller on OMAP3430 and onwards
+ *
+ * Copyright (C) 2007-2011 Texas Instruments
+ * Author: Vikram Pandita <vikram.pandita@ti.com>
+ * Author: Keshava Munegowda <keshava_mgowda@ti.com>
+ *
+ * Generalization by:
+ * Felipe Balbi <balbi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <plat/usb.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_MFD_OMAP_USB_HOST
+
+#define OMAP_USBHS_DEVICE "usbhs-omap"
+
+static struct resource usbhs_resources[] = {
+ {
+ .name = "uhh",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "tll",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ehci",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ehci-irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "ohci",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ohci-irq",
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device usbhs_device = {
+ .name = OMAP_USBHS_DEVICE,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(usbhs_resources),
+ .resource = usbhs_resources,
+};
+
+static struct usbhs_omap_platform_data usbhs_data;
+static struct ehci_hcd_omap_platform_data ehci_data;
+static struct ohci_hcd_omap_platform_data ohci_data;
+
+/* MUX settings for EHCI pins */
+/*
+ * setup_ehci_io_mux - initialize IO pad mux for USBHOST
+ */
+static void setup_ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
+{
+ switch (port_mode[0]) {
+ case OMAP_EHCI_PORT_MODE_PHY:
+ omap_mux_init_signal("hsusb1_stp", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("hsusb1_clk", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("hsusb1_dir", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_nxt", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data0", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data1", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data2", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data3", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data4", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data5", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data6", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_data7", OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_EHCI_PORT_MODE_TLL:
+ omap_mux_init_signal("hsusb1_tll_stp",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hsusb1_tll_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb1_tll_data7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+
+ switch (port_mode[1]) {
+ case OMAP_EHCI_PORT_MODE_PHY:
+ omap_mux_init_signal("hsusb2_stp", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("hsusb2_clk", OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("hsusb2_dir", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_nxt", OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_data7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_EHCI_PORT_MODE_TLL:
+ omap_mux_init_signal("hsusb2_tll_stp",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hsusb2_tll_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb2_tll_data7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+
+ switch (port_mode[2]) {
+ case OMAP_EHCI_PORT_MODE_PHY:
+ printk(KERN_WARNING "Port3 can't be used in PHY mode\n");
+ break;
+ case OMAP_EHCI_PORT_MODE_TLL:
+ omap_mux_init_signal("hsusb3_tll_stp",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hsusb3_tll_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("hsusb3_tll_data7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+
+ return;
+}
+
+static void setup_4430ehci_io_mux(const enum usbhs_omap_port_mode *port_mode)
+{
+ switch (port_mode[0]) {
+ case OMAP_EHCI_PORT_MODE_PHY:
+ omap_mux_init_signal("usbb1_ulpiphy_stp",
+ OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("usbb1_ulpiphy_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpiphy_dat7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_EHCI_PORT_MODE_TLL:
+ omap_mux_init_signal("usbb1_ulpitll_stp",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("usbb1_ulpitll_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_ulpitll_dat7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ default:
+ break;
+ }
+ switch (port_mode[1]) {
+ case OMAP_EHCI_PORT_MODE_PHY:
+ omap_mux_init_signal("usbb2_ulpiphy_stp",
+ OMAP_PIN_OUTPUT);
+ omap_mux_init_signal("usbb2_ulpiphy_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpiphy_dat7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_EHCI_PORT_MODE_TLL:
+ omap_mux_init_signal("usbb2_ulpitll_stp",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("usbb2_ulpitll_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_ulpitll_dat7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ default:
+ break;
+ }
+}
+
+static void setup_ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
+{
+ switch (port_mode[0]) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ omap_mux_init_signal("mm1_rxdp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm1_rxdm",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ omap_mux_init_signal("mm1_rxrcv",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ omap_mux_init_signal("mm1_txen_n", OMAP_PIN_OUTPUT);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ omap_mux_init_signal("mm1_txse0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm1_txdat",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+ switch (port_mode[1]) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ omap_mux_init_signal("mm2_rxdp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm2_rxdm",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ omap_mux_init_signal("mm2_rxrcv",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ omap_mux_init_signal("mm2_txen_n", OMAP_PIN_OUTPUT);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ omap_mux_init_signal("mm2_txse0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm2_txdat",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+ switch (port_mode[2]) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ omap_mux_init_signal("mm3_rxdp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm3_rxdm",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ omap_mux_init_signal("mm3_rxrcv",
+ OMAP_PIN_INPUT_PULLDOWN);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ omap_mux_init_signal("mm3_txen_n", OMAP_PIN_OUTPUT);
+ /* FALLTHROUGH */
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ omap_mux_init_signal("mm3_txse0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("mm3_txdat",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ /* FALLTHROUGH */
+ default:
+ break;
+ }
+}
+
+static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
+{
+ switch (port_mode[0]) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ omap_mux_init_signal("usbb1_mm_rxdp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_mm_rxdm",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ omap_mux_init_signal("usbb1_mm_rxrcv",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ omap_mux_init_signal("usbb1_mm_txen",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ omap_mux_init_signal("usbb1_mm_txdat",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb1_mm_txse0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ default:
+ break;
+ }
+
+ switch (port_mode[1]) {
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+ omap_mux_init_signal("usbb2_mm_rxdp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_mm_rxdm",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+ case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+ case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+ omap_mux_init_signal("usbb2_mm_rxrcv",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+ case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+ omap_mux_init_signal("usbb2_mm_txen",
+ OMAP_PIN_INPUT_PULLDOWN);
+
+
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+ case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+ omap_mux_init_signal("usbb2_mm_txdat",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usbb2_mm_txse0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+
+ case OMAP_USBHS_PORT_MODE_UNUSED:
+ default:
+ break;
+ }
+}
+
+void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
+{
+ int i;
+
+ for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
+ usbhs_data.port_mode[i] = pdata->port_mode[i];
+ ohci_data.port_mode[i] = pdata->port_mode[i];
+ ehci_data.port_mode[i] = pdata->port_mode[i];
+ ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
+ ehci_data.regulator[i] = pdata->regulator[i];
+ }
+ ehci_data.phy_reset = pdata->phy_reset;
+ ohci_data.es2_compatibility = pdata->es2_compatibility;
+ usbhs_data.ehci_data = &ehci_data;
+ usbhs_data.ohci_data = &ohci_data;
+
+ if (cpu_is_omap34xx()) {
+ usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE;
+ usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1;
+ usbhs_resources[1].start = OMAP34XX_USBTLL_BASE;
+ usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1;
+ usbhs_resources[2].start = OMAP34XX_EHCI_BASE;
+ usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1;
+ usbhs_resources[3].start = INT_34XX_EHCI_IRQ;
+ usbhs_resources[4].start = OMAP34XX_OHCI_BASE;
+ usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1;
+ usbhs_resources[5].start = INT_34XX_OHCI_IRQ;
+ setup_ehci_io_mux(pdata->port_mode);
+ setup_ohci_io_mux(pdata->port_mode);
+ } else if (cpu_is_omap44xx()) {
+ usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE;
+ usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1;
+ usbhs_resources[1].start = OMAP44XX_USBTLL_BASE;
+ usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1;
+ usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE;
+ usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1;
+ usbhs_resources[3].start = OMAP44XX_IRQ_EHCI;
+ usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE;
+ usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1;
+ usbhs_resources[5].start = OMAP44XX_IRQ_OHCI;
+ setup_4430ehci_io_mux(pdata->port_mode);
+ setup_4430ohci_io_mux(pdata->port_mode);
+ }
+
+ if (platform_device_add_data(&usbhs_device,
+ &usbhs_data, sizeof(usbhs_data)) < 0) {
+ printk(KERN_ERR "USBHS platform_device_add_data failed\n");
+ goto init_end;
+ }
+
+ if (platform_device_register(&usbhs_device) < 0)
+ printk(KERN_ERR "USBHS platform_device_register failed\n");
+
+init_end:
+ return;
+}
+
+#else
+
+void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
+{
+}
+
+#endif
+
+
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
new file mode 100644
index 00000000..c7ed540d
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -0,0 +1,185 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-musb.c
+ *
+ * This file will contain the board specific details for the
+ * MENTOR USB OTG controller on OMAP3430
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Vikram Pandita
+ *
+ * Generalization by:
+ * Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <linux/usb/musb.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/am35xx.h>
+#include <plat/usb.h>
+#include <plat/omap_device.h>
+#include "mux.h"
+
+#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X)
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 16,
+ .ram_bits = 12,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#ifdef CONFIG_USB_MUSB_OTG
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
+ .mode = MUSB_HOST,
+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
+ .mode = MUSB_PERIPHERAL,
+#endif
+ /* .clock is set dynamically */
+ .config = &musb_config,
+
+ /* REVISIT charge pump on TWL4030 can supply up to
+ * 100 mA ... but this value is board-specific, like
+ * "mode", and should be passed to usb_musb_init().
+ */
+ .power = 50, /* up to 100 mA */
+};
+
+static u64 musb_dmamask = DMA_BIT_MASK(32);
+
+static struct omap_device_pm_latency omap_musb_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
+{
+ switch (board_data->interface_type) {
+ case MUSB_INTERFACE_UTMI:
+ omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT);
+ omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT);
+ break;
+ case MUSB_INTERFACE_ULPI:
+ omap_mux_init_signal("usba0_ulpiphy_clk",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_stp",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dir",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_nxt",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat0",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat1",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat2",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat3",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat4",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat5",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat6",
+ OMAP_PIN_INPUT_PULLDOWN);
+ omap_mux_init_signal("usba0_ulpiphy_dat7",
+ OMAP_PIN_INPUT_PULLDOWN);
+ break;
+ default:
+ break;
+ }
+}
+
+static struct omap_musb_board_data musb_default_board_data = {
+ .interface_type = MUSB_INTERFACE_ULPI,
+ .mode = MUSB_OTG,
+ .power = 100,
+};
+
+void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ struct platform_device *pdev;
+ struct device *dev;
+ int bus_id = -1;
+ const char *oh_name, *name;
+ struct omap_musb_board_data *board_data;
+
+ if (musb_board_data)
+ board_data = musb_board_data;
+ else
+ board_data = &musb_default_board_data;
+
+ /*
+ * REVISIT: This line can be removed once all the platforms using
+ * musb_core.c have been converted to use use clkdev.
+ */
+ musb_plat.clock = "ick";
+ musb_plat.board_data = board_data;
+ musb_plat.power = board_data->power >> 1;
+ musb_plat.mode = board_data->mode;
+ musb_plat.extvbus = board_data->extvbus;
+
+ if (cpu_is_omap44xx())
+ omap4430_phy_init(dev);
+
+ if (cpu_is_omap3517() || cpu_is_omap3505()) {
+ oh_name = "am35x_otg_hs";
+ name = "musb-am35x";
+ } else {
+ oh_name = "usb_otg_hs";
+ name = "musb-omap2430";
+ }
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return;
+ }
+
+ od = omap_device_build(name, bus_id, oh, &musb_plat,
+ sizeof(musb_plat), omap_musb_latency,
+ ARRAY_SIZE(omap_musb_latency), false);
+ if (IS_ERR(od)) {
+ pr_err("Could not build omap_device for %s %s\n",
+ name, oh_name);
+ return;
+ }
+
+ pdev = &od->pdev;
+ dev = &pdev->dev;
+ get_device(dev);
+ dev->dma_mask = &musb_dmamask;
+ dev->coherent_dma_mask = musb_dmamask;
+ put_device(dev);
+
+ if (cpu_is_omap44xx())
+ omap4430_phy_init(dev);
+}
+
+#else
+void __init usb_musb_init(struct omap_musb_board_data *board_data)
+{
+ if (cpu_is_omap44xx())
+ omap4430_phy_init(NULL);
+}
+#endif /* CONFIG_USB_MUSB_SOC */
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
new file mode 100644
index 00000000..8dd26b76
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -0,0 +1,348 @@
+/*
+ * linux/arch/arm/mach-omap2/usb-tusb6010.c
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <linux/usb/musb.h>
+
+#include <plat/gpmc.h>
+
+#include "mux.h"
+
+static u8 async_cs, sync_cs;
+static unsigned refclk_psec;
+
+
+/* t2_ps, when quantized to fclk units, must happen no earlier than
+ * the clock after after t1_NS.
+ *
+ * Return a possibly updated value of t2_ps, converted to nsec.
+ */
+static unsigned
+next_clk(unsigned t1_NS, unsigned t2_ps, unsigned fclk_ps)
+{
+ unsigned t1_ps = t1_NS * 1000;
+ unsigned t1_f, t2_f;
+
+ if ((t1_ps + fclk_ps) < t2_ps)
+ return t2_ps / 1000;
+
+ t1_f = (t1_ps + fclk_ps - 1) / fclk_ps;
+ t2_f = (t2_ps + fclk_ps - 1) / fclk_ps;
+
+ if (t1_f >= t2_f)
+ t2_f = t1_f + 1;
+
+ return (t2_f * fclk_ps) / 1000;
+}
+
+/* NOTE: timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
+
+static int tusb_set_async_mode(unsigned sysclk_ps, unsigned fclk_ps)
+{
+ struct gpmc_timings t;
+ unsigned t_acsnh_advnh = sysclk_ps + 3000;
+ unsigned tmp;
+
+ memset(&t, 0, sizeof(t));
+
+ /* CS_ON = t_acsnh_acsnl */
+ t.cs_on = 8;
+ /* ADV_ON = t_acsnh_advnh - t_advn */
+ t.adv_on = next_clk(t.cs_on, t_acsnh_advnh - 7000, fclk_ps);
+
+ /*
+ * READ ... from omap2420 TRM fig 12-13
+ */
+
+ /* ADV_RD_OFF = t_acsnh_advnh */
+ t.adv_rd_off = next_clk(t.adv_on, t_acsnh_advnh, fclk_ps);
+
+ /* OE_ON = t_acsnh_advnh + t_advn_oen (then wait for nRDY) */
+ t.oe_on = next_clk(t.adv_on, t_acsnh_advnh + 1000, fclk_ps);
+
+ /* ACCESS = counters continue only after nRDY */
+ tmp = t.oe_on * 1000 + 300;
+ t.access = next_clk(t.oe_on, tmp, fclk_ps);
+
+ /* OE_OFF = after data gets sampled */
+ tmp = t.access * 1000;
+ t.oe_off = next_clk(t.access, tmp, fclk_ps);
+
+ t.cs_rd_off = t.oe_off;
+
+ tmp = t.cs_rd_off * 1000 + 7000 /* t_acsn_rdy_z */;
+ t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
+
+ /*
+ * WRITE ... from omap2420 TRM fig 12-15
+ */
+
+ /* ADV_WR_OFF = t_acsnh_advnh */
+ t.adv_wr_off = t.adv_rd_off;
+
+ /* WE_ON = t_acsnh_advnh + t_advn_wen (then wait for nRDY) */
+ t.we_on = next_clk(t.adv_wr_off, t_acsnh_advnh + 1000, fclk_ps);
+
+ /* WE_OFF = after data gets sampled */
+ tmp = t.we_on * 1000 + 300;
+ t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+
+ t.cs_wr_off = t.we_off;
+
+ tmp = t.cs_wr_off * 1000 + 7000 /* t_acsn_rdy_z */;
+ t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+
+ return gpmc_cs_set_timings(async_cs, &t);
+}
+
+static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
+{
+ struct gpmc_timings t;
+ unsigned t_scsnh_advnh = sysclk_ps + 3000;
+ unsigned tmp;
+
+ memset(&t, 0, sizeof(t));
+ t.cs_on = 8;
+
+ /* ADV_ON = t_acsnh_advnh - t_advn */
+ t.adv_on = next_clk(t.cs_on, t_scsnh_advnh - 7000, fclk_ps);
+
+ /* GPMC_CLK rate = fclk rate / div */
+ t.sync_clk = 11100 /* 11.1 nsec */;
+ tmp = (t.sync_clk + fclk_ps - 1) / fclk_ps;
+ if (tmp > 4)
+ return -ERANGE;
+ if (tmp <= 0)
+ tmp = 1;
+ t.page_burst_access = (fclk_ps * tmp) / 1000;
+
+ /*
+ * READ ... based on omap2420 TRM fig 12-19, 12-20
+ */
+
+ /* ADV_RD_OFF = t_scsnh_advnh */
+ t.adv_rd_off = next_clk(t.adv_on, t_scsnh_advnh, fclk_ps);
+
+ /* OE_ON = t_scsnh_advnh + t_advn_oen * fclk_ps (then wait for nRDY) */
+ tmp = (t.adv_rd_off * 1000) + (3 * fclk_ps);
+ t.oe_on = next_clk(t.adv_on, tmp, fclk_ps);
+
+ /* ACCESS = number of clock cycles after t_adv_eon */
+ tmp = (t.oe_on * 1000) + (5 * fclk_ps);
+ t.access = next_clk(t.oe_on, tmp, fclk_ps);
+
+ /* OE_OFF = after data gets sampled */
+ tmp = (t.access * 1000) + (1 * fclk_ps);
+ t.oe_off = next_clk(t.access, tmp, fclk_ps);
+
+ t.cs_rd_off = t.oe_off;
+
+ tmp = t.cs_rd_off * 1000 + 7000 /* t_scsn_rdy_z */;
+ t.rd_cycle = next_clk(t.cs_rd_off, tmp, fclk_ps);
+
+ /*
+ * WRITE ... based on omap2420 TRM fig 12-21
+ */
+
+ /* ADV_WR_OFF = t_scsnh_advnh */
+ t.adv_wr_off = t.adv_rd_off;
+
+ /* WE_ON = t_scsnh_advnh + t_advn_wen * fclk_ps (then wait for nRDY) */
+ tmp = (t.adv_wr_off * 1000) + (3 * fclk_ps);
+ t.we_on = next_clk(t.adv_wr_off, tmp, fclk_ps);
+
+ /* WE_OFF = number of clock cycles after t_adv_wen */
+ tmp = (t.we_on * 1000) + (6 * fclk_ps);
+ t.we_off = next_clk(t.we_on, tmp, fclk_ps);
+
+ t.cs_wr_off = t.we_off;
+
+ tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
+ t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
+
+ return gpmc_cs_set_timings(sync_cs, &t);
+}
+
+extern unsigned long gpmc_get_fclk_period(void);
+
+/* tusb driver calls this when it changes the chip's clocking */
+int tusb6010_platform_retime(unsigned is_refclk)
+{
+ static const char error[] =
+ KERN_ERR "tusb6010 %s retime error %d\n";
+
+ unsigned fclk_ps = gpmc_get_fclk_period();
+ unsigned sysclk_ps;
+ int status;
+
+ if (!refclk_psec || fclk_ps == 0)
+ return -ENODEV;
+
+ sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
+
+ status = tusb_set_async_mode(sysclk_ps, fclk_ps);
+ if (status < 0) {
+ printk(error, "async", status);
+ goto done;
+ }
+ status = tusb_set_sync_mode(sysclk_ps, fclk_ps);
+ if (status < 0)
+ printk(error, "sync", status);
+done:
+ return status;
+}
+EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
+
+static struct resource tusb_resources[] = {
+ /* Order is significant! The start/end fields
+ * are updated during setup..
+ */
+ { /* Asynchronous access */
+ .flags = IORESOURCE_MEM,
+ },
+ { /* Synchronous access */
+ .flags = IORESOURCE_MEM,
+ },
+ { /* IRQ */
+ .name = "mc",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 tusb_dmamask = ~(u32)0;
+
+static struct platform_device tusb_device = {
+ .name = "musb-tusb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &tusb_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(tusb_resources),
+ .resource = tusb_resources,
+};
+
+
+/* this may be called only from board-*.c setup code */
+int __init
+tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
+ unsigned ps_refclk, unsigned waitpin,
+ unsigned async, unsigned sync,
+ unsigned irq, unsigned dmachan)
+{
+ int status;
+ static char error[] __initdata =
+ KERN_ERR "tusb6010 init error %d, %d\n";
+
+ /* ASYNC region, primarily for PIO */
+ status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
+ &tusb_resources[0].start);
+ if (status < 0) {
+ printk(error, 1, status);
+ return status;
+ }
+ tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
+ async_cs = async;
+ gpmc_cs_write_reg(async, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_PAGE_LEN(2)
+ | GPMC_CONFIG1_WAIT_READ_MON
+ | GPMC_CONFIG1_WAIT_WRITE_MON
+ | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+ | GPMC_CONFIG1_READTYPE_ASYNC
+ | GPMC_CONFIG1_WRITETYPE_ASYNC
+ | GPMC_CONFIG1_DEVICESIZE_16
+ | GPMC_CONFIG1_DEVICETYPE_NOR
+ | GPMC_CONFIG1_MUXADDDATA);
+
+
+ /* SYNC region, primarily for DMA */
+ status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
+ &tusb_resources[1].start);
+ if (status < 0) {
+ printk(error, 2, status);
+ return status;
+ }
+ tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
+ sync_cs = sync;
+ gpmc_cs_write_reg(sync, GPMC_CS_CONFIG1,
+ GPMC_CONFIG1_READMULTIPLE_SUPP
+ | GPMC_CONFIG1_READTYPE_SYNC
+ | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
+ | GPMC_CONFIG1_WRITETYPE_SYNC
+ | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
+ | GPMC_CONFIG1_PAGE_LEN(2)
+ | GPMC_CONFIG1_WAIT_READ_MON
+ | GPMC_CONFIG1_WAIT_WRITE_MON
+ | GPMC_CONFIG1_WAIT_PIN_SEL(waitpin)
+ | GPMC_CONFIG1_DEVICESIZE_16
+ | GPMC_CONFIG1_DEVICETYPE_NOR
+ | GPMC_CONFIG1_MUXADDDATA
+ /* fclk divider gets set later */
+ );
+
+ /* IRQ */
+ status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
+ if (status < 0) {
+ printk(error, 3, status);
+ return status;
+ }
+ tusb_resources[2].start = irq + IH_GPIO_BASE;
+
+ /* set up memory timings ... can speed them up later */
+ if (!ps_refclk) {
+ printk(error, 4, status);
+ return -ENODEV;
+ }
+ refclk_psec = ps_refclk;
+ status = tusb6010_platform_retime(1);
+ if (status < 0) {
+ printk(error, 5, status);
+ return status;
+ }
+
+ /* finish device setup ... */
+ if (!data) {
+ printk(error, 6, status);
+ return -ENODEV;
+ }
+ tusb_device.dev.platform_data = data;
+
+ /* REVISIT let the driver know what DMA channels work */
+ if (!dmachan)
+ tusb_device.dev.dma_mask = NULL;
+ else {
+ /* assume OMAP 2420 ES2.0 and later */
+ if (dmachan & (1 << 0))
+ omap_mux_init_signal("sys_ndmareq0", 0);
+ if (dmachan & (1 << 1))
+ omap_mux_init_signal("sys_ndmareq1", 0);
+ if (dmachan & (1 << 2))
+ omap_mux_init_signal("sys_ndmareq2", 0);
+ if (dmachan & (1 << 3))
+ omap_mux_init_signal("sys_ndmareq3", 0);
+ if (dmachan & (1 << 4))
+ omap_mux_init_signal("sys_ndmareq4", 0);
+ if (dmachan & (1 << 5))
+ omap_mux_init_signal("sys_ndmareq5", 0);
+ }
+
+ /* so far so good ... register the device */
+ status = platform_device_register(&tusb_device);
+ if (status < 0) {
+ printk(error, 7, status);
+ return status;
+ }
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
new file mode 100644
index 00000000..e7767771
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.h
@@ -0,0 +1,83 @@
+/*
+ * OMAP3/4 Voltage Controller (VC) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VC_H
+#define __ARCH_ARM_MACH_OMAP2_VC_H
+
+#include <linux/kernel.h>
+
+/**
+ * struct omap_vc_common_data - per-VC register/bitfield data
+ * @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
+ * @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
+ * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
+ * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
+ * @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start
+ * @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register
+ * @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register
+ * @regaddr_shift: REGADDR field shift in PRM_VC_BYPASS_VAL register
+ * @cmd_on_shift: ON field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
+ * @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
+ *
+ * XXX One of cmd_on_mask and cmd_on_shift are not needed
+ * XXX VALID should probably be a shift, not a mask
+ */
+struct omap_vc_common_data {
+ u32 cmd_on_mask;
+ u32 valid;
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 bypass_val_reg;
+ u8 data_shift;
+ u8 slaveaddr_shift;
+ u8 regaddr_shift;
+ u8 cmd_on_shift;
+ u8 cmd_onlp_shift;
+ u8 cmd_ret_shift;
+ u8 cmd_off_shift;
+};
+
+/**
+ * struct omap_vc_instance_data - VC per-instance data
+ * @vc_common: pointer to VC common data for this platform
+ * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
+ * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
+ * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
+ *
+ * XXX It is not necessary to have both a *_mask and a *_shift -
+ * remove one
+ */
+struct omap_vc_instance_data {
+ const struct omap_vc_common_data *vc_common;
+ u32 smps_sa_mask;
+ u32 smps_volra_mask;
+ u8 cmdval_reg;
+ u8 smps_sa_shift;
+ u8 smps_volra_shift;
+};
+
+extern struct omap_vc_instance_data omap3_vc1_data;
+extern struct omap_vc_instance_data omap3_vc2_data;
+
+extern struct omap_vc_instance_data omap4_vc_mpu_data;
+extern struct omap_vc_instance_data omap4_vc_iva_data;
+extern struct omap_vc_instance_data omap4_vc_core_data;
+
+#endif
+
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
new file mode 100644
index 00000000..f37dc4bc
--- /dev/null
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -0,0 +1,63 @@
+/*
+ * OMAP3 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static struct omap_vc_common_data omap3_vc_common = {
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
+ .data_shift = OMAP3430_DATA_SHIFT,
+ .slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
+ .regaddr_shift = OMAP3430_REGADDR_SHIFT,
+ .valid = OMAP3430_VALID_MASK,
+ .cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT,
+ .cmd_on_mask = OMAP3430_VC_CMD_ON_MASK,
+ .cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT,
+ .cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT,
+ .cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT,
+};
+
+struct omap_vc_instance_data omap3_vc1_data = {
+ .vc_common = &omap3_vc_common,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
+ .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
+ .smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
+ .smps_volra_mask = OMAP3430_VOLRA0_MASK,
+};
+
+struct omap_vc_instance_data omap3_vc2_data = {
+ .vc_common = &omap3_vc_common,
+ .cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
+ .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
+ .smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
+ .smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
+ .smps_volra_mask = OMAP3430_VOLRA1_MASK,
+};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
new file mode 100644
index 00000000..a98da8dd
--- /dev/null
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -0,0 +1,75 @@
+/*
+ * OMAP4 Voltage Controller (VC) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vc.h"
+
+/*
+ * VC data common to 44xx chips
+ * XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
+ */
+static const struct omap_vc_common_data omap4_vc_common = {
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
+ .data_shift = OMAP4430_DATA_SHIFT,
+ .slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
+ .regaddr_shift = OMAP4430_REGADDR_SHIFT,
+ .valid = OMAP4430_VALID_MASK,
+ .cmd_on_shift = OMAP4430_ON_SHIFT,
+ .cmd_on_mask = OMAP4430_ON_MASK,
+ .cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
+ .cmd_ret_shift = OMAP4430_RET_SHIFT,
+ .cmd_off_shift = OMAP4430_OFF_SHIFT,
+};
+
+/* VC instance data for each controllable voltage line */
+struct omap_vc_instance_data omap4_vc_mpu_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_iva_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+};
+
+struct omap_vc_instance_data omap4_vc_core_data = {
+ .vc_common = &omap4_vc_common,
+ .cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
+ .smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
+ .smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
+ .smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
+ .smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+};
+
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
new file mode 100644
index 00000000..9ef3789d
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.c
@@ -0,0 +1,1106 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "control.h"
+
+#include "voltage.h"
+
+#include "vc.h"
+#include "vp.h"
+
+#define VOLTAGE_DIR_SIZE 16
+
+
+static struct omap_vdd_info **vdd_info;
+
+/*
+ * Number of scalable voltage domains.
+ */
+static int nr_scalable_vdd;
+
+/* XXX document */
+static s16 prm_mod_offs;
+static s16 prm_irqst_ocp_mod_offs;
+
+static struct dentry *voltage_dir;
+
+/* Init function pointers */
+static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt);
+
+static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
+{
+ return omap2_prm_read_mod_reg(mod, offset);
+}
+
+static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)
+{
+ omap2_prm_write_mod_reg(val, mod, offset);
+}
+
+static u32 omap4_voltage_read_reg(u16 mod, u8 offset)
+{
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ mod, offset);
+}
+
+static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
+{
+ omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
+}
+
+static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
+{
+ char *sys_ck_name;
+ struct clk *sys_ck;
+ u32 sys_clk_speed, timeout_val, waittime;
+
+ /*
+ * XXX Clockfw should handle this, or this should be in a
+ * struct record
+ */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ sys_ck_name = "sys_ck";
+ else if (cpu_is_omap44xx())
+ sys_ck_name = "sys_clkin_ck";
+ else
+ return -EINVAL;
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, sys_ck_name);
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys clk to calculate"
+ "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+
+ /* Generic voltage parameters */
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ vdd->vp_enabled = false;
+
+ vdd->vp_rt_data.vpconfig_erroroffset =
+ (vdd->pmic_info->vp_erroroffset <<
+ vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
+
+ timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
+ vdd->vp_rt_data.vlimitto_timeout = timeout_val;
+ vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
+ vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
+
+ waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
+ sys_clk_speed) / 1000;
+ vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
+ vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
+ vdd->vp_rt_data.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
+ vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
+
+ return 0;
+}
+
+/* Voltage debugfs support */
+static int vp_volt_debug_get(void *data, u64 *val)
+{
+ struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
+ u8 vsel;
+
+ if (!vdd) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
+ }
+
+ vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
+
+ if (!vdd->pmic_info->vsel_to_uv) {
+ pr_warning("PMIC function to convert vsel to voltage"
+ "in uV not registerd\n");
+ return -EINVAL;
+ }
+
+ *val = vdd->pmic_info->vsel_to_uv(vsel);
+ return 0;
+}
+
+static int nom_volt_debug_get(void *data, u64 *val)
+{
+ struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
+
+ if (!vdd) {
+ pr_warning("Wrong paramater passed\n");
+ return -EINVAL;
+ }
+
+ *val = omap_voltage_get_nom_volt(&vdd->voltdm);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
+ "%llu\n");
+static void vp_latch_vsel(struct omap_vdd_info *vdd)
+{
+ u32 vpconfig;
+ unsigned long uvdc;
+ char vsel;
+
+ uvdc = omap_voltage_get_nom_volt(&vdd->voltdm);
+ if (!uvdc) {
+ pr_warning("%s: unable to find current voltage for vdd_%s\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+ pr_warning("%s: PMIC function to convert voltage in uV to"
+ " vsel not registered\n", __func__);
+ return;
+ }
+
+ vsel = vdd->pmic_info->uv_to_vsel(uvdc);
+
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
+ vdd->vp_data->vp_common->vpconfig_initvdd);
+ vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
+
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
+ prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /* Clear initVDD copy trigger bit */
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+}
+
+/* Generic voltage init functions */
+static void __init vp_init(struct omap_vdd_info *vdd)
+{
+ u32 vp_val;
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
+ (vdd->vp_rt_data.vpconfig_errorgain <<
+ vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
+ vdd->vp_data->vp_common->vpconfig_timeouten;
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
+ vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
+ (vdd->vp_rt_data.vstepmin_stepmin <<
+ vdd->vp_data->vp_common->vstepmin_stepmin_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmin);
+
+ vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
+ vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
+ (vdd->vp_rt_data.vstepmax_stepmax <<
+ vdd->vp_data->vp_common->vstepmax_stepmax_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmax);
+
+ vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
+ vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
+ (vdd->vp_rt_data.vlimitto_vddmin <<
+ vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
+ (vdd->vp_rt_data.vlimitto_timeout <<
+ vdd->vp_data->vp_common->vlimitto_timeout_shift));
+ vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vlimitto);
+}
+
+static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
+{
+ char *name;
+
+ name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
+ if (!name) {
+ pr_warning("%s: Unable to allocate memory for debugfs"
+ " directory name for vdd_%s",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+ strcpy(name, "vdd_");
+ strcat(name, vdd->voltdm.name);
+
+ vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
+ kfree(name);
+ if (IS_ERR(vdd->debug_dir)) {
+ pr_warning("%s: Unable to create debugfs directory for"
+ " vdd_%s\n", __func__, vdd->voltdm.name);
+ vdd->debug_dir = NULL;
+ return;
+ }
+
+ (void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vpconfig_errorgain));
+ (void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
+ vdd->debug_dir,
+ &(vdd->vp_rt_data.vstepmin_smpswaittimemin));
+ (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vstepmin_stepmin));
+ (void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
+ vdd->debug_dir,
+ &(vdd->vp_rt_data.vstepmax_smpswaittimemax));
+ (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vstepmax_stepmax));
+ (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vlimitto_vddmax));
+ (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vlimitto_vddmin));
+ (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
+ &(vdd->vp_rt_data.vlimitto_timeout));
+ (void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
+ (void *) vdd, &vp_volt_debug_fops);
+ (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
+ vdd->debug_dir, (void *) vdd,
+ &nom_volt_debug_fops);
+}
+
+/* Voltage scale and accessory APIs */
+static int _pre_volt_scale(struct omap_vdd_info *vdd,
+ unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
+{
+ struct omap_volt_data *volt_data;
+ const struct omap_vc_common_data *vc_common;
+ const struct omap_vp_common_data *vp_common;
+ u32 vc_cmdval, vp_errgain_val;
+
+ vc_common = vdd->vc_data->vc_common;
+ vp_common = vdd->vp_data->vp_common;
+
+ /* Check if suffiecient pmic info is available for this vdd */
+ if (!vdd->pmic_info) {
+ pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ if (!vdd->pmic_info->uv_to_vsel) {
+ pr_err("%s: PMIC function to convert voltage in uV to"
+ "vsel not registered. Hence unable to scale voltage"
+ "for vdd_%s\n", __func__, vdd->voltdm.name);
+ return -ENODATA;
+ }
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return -EINVAL;
+ }
+
+ /* Get volt_data corresponding to target_volt */
+ volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
+ if (IS_ERR(volt_data))
+ volt_data = NULL;
+
+ *target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
+ *current_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
+
+ /* Setting the ON voltage to the new target voltage */
+ vc_cmdval = vdd->read_reg(prm_mod_offs, vdd->vc_data->cmdval_reg);
+ vc_cmdval &= ~vc_common->cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vc_common->cmd_on_shift);
+ vdd->write_reg(vc_cmdval, prm_mod_offs, vdd->vc_data->cmdval_reg);
+
+ /* Setting vp errorgain based on the voltage */
+ if (volt_data) {
+ vp_errgain_val = vdd->read_reg(prm_mod_offs,
+ vdd->vp_data->vpconfig);
+ vdd->vp_rt_data.vpconfig_errorgain = volt_data->vp_errgain;
+ vp_errgain_val &= ~vp_common->vpconfig_errorgain_mask;
+ vp_errgain_val |= vdd->vp_rt_data.vpconfig_errorgain <<
+ vp_common->vpconfig_errorgain_shift;
+ vdd->write_reg(vp_errgain_val, prm_mod_offs,
+ vdd->vp_data->vpconfig);
+ }
+
+ return 0;
+}
+
+static void _post_volt_scale(struct omap_vdd_info *vdd,
+ unsigned long target_volt, u8 target_vsel, u8 current_vsel)
+{
+ u32 smps_steps = 0, smps_delay = 0;
+
+ smps_steps = abs(target_vsel - current_vsel);
+ /* SMPS slew rate / step size. 2us added as buffer. */
+ smps_delay = ((smps_steps * vdd->pmic_info->step_size) /
+ vdd->pmic_info->slew_rate) + 2;
+ udelay(smps_delay);
+
+ vdd->curr_volt = target_volt;
+}
+
+/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
+static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt)
+{
+ u32 loop_cnt = 0, retries_cnt = 0;
+ u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
+ u8 target_vsel, current_vsel;
+ int ret;
+
+ ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ vc_valid = vdd->vc_data->vc_common->valid;
+ vc_bypass_val_reg = vdd->vc_data->vc_common->bypass_val_reg;
+ vc_bypass_value = (target_vsel << vdd->vc_data->vc_common->data_shift) |
+ (vdd->pmic_info->pmic_reg <<
+ vdd->vc_data->vc_common->regaddr_shift) |
+ (vdd->pmic_info->i2c_slave_addr <<
+ vdd->vc_data->vc_common->slaveaddr_shift);
+
+ vdd->write_reg(vc_bypass_value, prm_mod_offs, vc_bypass_val_reg);
+ vdd->write_reg(vc_bypass_value | vc_valid, prm_mod_offs,
+ vc_bypass_val_reg);
+
+ vc_bypass_value = vdd->read_reg(prm_mod_offs, vc_bypass_val_reg);
+ /*
+ * Loop till the bypass command is acknowledged from the SMPS.
+ * NOTE: This is legacy code. The loop count and retry count needs
+ * to be revisited.
+ */
+ while (!(vc_bypass_value & vc_valid)) {
+ loop_cnt++;
+
+ if (retries_cnt > 10) {
+ pr_warning("%s: Retry count exceeded\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (loop_cnt > 50) {
+ retries_cnt++;
+ loop_cnt = 0;
+ udelay(10);
+ }
+ vc_bypass_value = vdd->read_reg(prm_mod_offs,
+ vc_bypass_val_reg);
+ }
+
+ _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
+ return 0;
+}
+
+/* VP force update method of voltage scaling */
+static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
+ unsigned long target_volt)
+{
+ u32 vpconfig;
+ u8 target_vsel, current_vsel, prm_irqst_reg;
+ int ret, timeout = 0;
+
+ ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ prm_irqst_reg = vdd->vp_data->prm_irqst_data->prm_irqst_reg;
+
+ /*
+ * Clear all pending TransactionDone interrupt/status. Typical latency
+ * is <3us
+ */
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
+ prm_irqst_ocp_mod_offs, prm_irqst_reg);
+ if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status))
+ break;
+ udelay(1);
+ }
+ if (timeout >= VP_TRANXDONE_TIMEOUT) {
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
+ "Voltage change aborted", __func__, vdd->voltdm.name);
+ return -ETIMEDOUT;
+ }
+
+ /* Configure for VP-Force Update */
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
+ vdd->vp_data->vp_common->vpconfig_forceupdate |
+ vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
+ vpconfig |= ((target_vsel <<
+ vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /* Force update of voltage */
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /*
+ * Wait for TransactionDone. Typical latency is <200us.
+ * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+ */
+ timeout = 0;
+ omap_test_timeout((vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status),
+ VP_TRANXDONE_TIMEOUT, timeout);
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
+ "TRANXDONE never got set after the voltage update\n",
+ __func__, vdd->voltdm.name);
+
+ _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
+
+ /*
+ * Disable TransactionDone interrupt , clear all status, clear
+ * control registers
+ */
+ timeout = 0;
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
+ prm_irqst_ocp_mod_offs, prm_irqst_reg);
+ if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
+ vdd->vp_data->prm_irqst_data->tranxdone_status))
+ break;
+ udelay(1);
+ }
+
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
+ "to clear the TRANXDONE status\n",
+ __func__, vdd->voltdm.name);
+
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ /* Clear initVDD copy trigger bit */
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+ /* Clear force bit */
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ return 0;
+}
+
+static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)
+{
+ /*
+ * Voltage Manager FSM parameters init
+ * XXX This data should be passed in from the board file
+ */
+ vdd->write_reg(OMAP3_CLKSETUP, prm_mod_offs, OMAP3_PRM_CLKSETUP_OFFSET);
+ vdd->write_reg(OMAP3_VOLTOFFSET, prm_mod_offs,
+ OMAP3_PRM_VOLTOFFSET_OFFSET);
+ vdd->write_reg(OMAP3_VOLTSETUP2, prm_mod_offs,
+ OMAP3_PRM_VOLTSETUP2_OFFSET);
+}
+
+static void __init omap3_vc_init(struct omap_vdd_info *vdd)
+{
+ static bool is_initialized;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ u32 vc_val;
+
+ if (is_initialized)
+ return;
+
+ /* Set up the on, inactive, retention and off voltage */
+ on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
+ onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
+ ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
+ off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
+ vc_val = ((on_vsel << vdd->vc_data->vc_common->cmd_on_shift) |
+ (onlp_vsel << vdd->vc_data->vc_common->cmd_onlp_shift) |
+ (ret_vsel << vdd->vc_data->vc_common->cmd_ret_shift) |
+ (off_vsel << vdd->vc_data->vc_common->cmd_off_shift));
+ vdd->write_reg(vc_val, prm_mod_offs, vdd->vc_data->cmdval_reg);
+
+ /*
+ * Generic VC parameters init
+ * XXX This data should be abstracted out
+ */
+ vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, prm_mod_offs,
+ OMAP3_PRM_VC_CH_CONF_OFFSET);
+ vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, prm_mod_offs,
+ OMAP3_PRM_VC_I2C_CFG_OFFSET);
+
+ omap3_vfsm_init(vdd);
+
+ is_initialized = true;
+}
+
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init(struct omap_vdd_info *vdd)
+{
+ static bool is_initialized;
+ u32 vc_val;
+
+ if (is_initialized)
+ return;
+
+ /* TODO: Configure setup times and CMD_VAL values*/
+
+ /*
+ * Generic VC parameters init
+ * XXX This data should be abstracted out
+ */
+ vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
+ OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
+ OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
+ vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
+
+ /* XXX These are magic numbers and do not belong! */
+ vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
+ vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+
+ is_initialized = true;
+}
+
+static void __init omap_vc_init(struct omap_vdd_info *vdd)
+{
+ u32 vc_val;
+
+ if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+ pr_err("%s: PMIC info requried to configure vc for"
+ "vdd_%s not populated.Hence cannot initialize vc\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ /* Set up the SMPS_SA(i2c slave address in VC */
+ vc_val = vdd->read_reg(prm_mod_offs,
+ vdd->vc_data->vc_common->smps_sa_reg);
+ vc_val &= ~vdd->vc_data->smps_sa_mask;
+ vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_data->smps_sa_shift;
+ vdd->write_reg(vc_val, prm_mod_offs,
+ vdd->vc_data->vc_common->smps_sa_reg);
+
+ /* Setup the VOLRA(pmic reg addr) in VC */
+ vc_val = vdd->read_reg(prm_mod_offs,
+ vdd->vc_data->vc_common->smps_volra_reg);
+ vc_val &= ~vdd->vc_data->smps_volra_mask;
+ vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_data->smps_volra_shift;
+ vdd->write_reg(vc_val, prm_mod_offs,
+ vdd->vc_data->vc_common->smps_volra_reg);
+
+ /* Configure the setup times */
+ vc_val = vdd->read_reg(prm_mod_offs, vdd->vfsm->voltsetup_reg);
+ vc_val &= ~vdd->vfsm->voltsetup_mask;
+ vc_val |= vdd->pmic_info->volt_setup_time <<
+ vdd->vfsm->voltsetup_shift;
+ vdd->write_reg(vc_val, prm_mod_offs, vdd->vfsm->voltsetup_reg);
+
+ if (cpu_is_omap34xx())
+ omap3_vc_init(vdd);
+ else if (cpu_is_omap44xx())
+ omap4_vc_init(vdd);
+}
+
+static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd)
+{
+ int ret = -EINVAL;
+
+ if (!vdd->pmic_info) {
+ pr_err("%s: PMIC info requried to configure vdd_%s not"
+ "populated.Hence cannot initialize vdd_%s\n",
+ __func__, vdd->voltdm.name, vdd->voltdm.name);
+ goto ovdc_out;
+ }
+
+ if (IS_ERR_VALUE(_config_common_vdd_data(vdd)))
+ goto ovdc_out;
+
+ if (cpu_is_omap34xx()) {
+ vdd->read_reg = omap3_voltage_read_reg;
+ vdd->write_reg = omap3_voltage_write_reg;
+ ret = 0;
+ } else if (cpu_is_omap44xx()) {
+ vdd->read_reg = omap4_voltage_read_reg;
+ vdd->write_reg = omap4_voltage_write_reg;
+ ret = 0;
+ }
+
+ovdc_out:
+ return ret;
+}
+
+/* Public functions */
+/**
+ * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
+ * @voltdm: pointer to the VDD for which current voltage info is needed
+ *
+ * API to get the current non-auto-compensated voltage for a VDD.
+ * Returns 0 in case of error else returns the current voltage for the VDD.
+ */
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ return vdd->curr_volt;
+}
+
+/**
+ * omap_vp_get_curr_volt() - API to get the current vp voltage.
+ * @voltdm: pointer to the VDD.
+ *
+ * This API returns the current voltage for the specified voltage processor
+ */
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u8 curr_vsel;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return 0;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg) {
+ pr_err("%s: No read API for reading vdd_%s regs\n",
+ __func__, voltdm->name);
+ return 0;
+ }
+
+ curr_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
+
+ if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
+ pr_warning("%s: PMIC function to convert vsel to voltage"
+ "in uV not registerd\n", __func__);
+ return 0;
+ }
+
+ return vdd->pmic_info->vsel_to_uv(curr_vsel);
+}
+
+/**
+ * omap_vp_enable() - API to enable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be enabled.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_enable(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u32 vpconfig;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already enabled, do nothing. Return */
+ if (vdd->vp_enabled)
+ return;
+
+ vp_latch_vsel(vdd);
+
+ /* Enable VP */
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+ vdd->vp_enabled = true;
+}
+
+/**
+ * omap_vp_disable() - API to disable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be disabled.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_disable(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+ u32 vpconfig;
+ int timeout;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+ if (!vdd->read_reg || !vdd->write_reg) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already disabled, do nothing. Return */
+ if (!vdd->vp_enabled) {
+ pr_warning("%s: Trying to disable VP for vdd_%s when"
+ "it is already disabled\n", __func__, voltdm->name);
+ return;
+ }
+
+ /* Disable VP */
+ vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
+ vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
+ vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
+
+ /*
+ * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+ */
+ omap_test_timeout((vdd->read_reg(prm_mod_offs, vdd->vp_data->vstatus)),
+ VP_IDLE_TIMEOUT, timeout);
+
+ if (timeout >= VP_IDLE_TIMEOUT)
+ pr_warning("%s: vdd_%s idle timedout\n",
+ __func__, voltdm->name);
+
+ vdd->vp_enabled = false;
+
+ return;
+}
+
+/**
+ * omap_voltage_scale_vdd() - API to scale voltage of a particular
+ * voltage domain.
+ * @voltdm: pointer to the VDD which is to be scaled.
+ * @target_volt: The target voltage of the voltage domain
+ *
+ * This API should be called by the kernel to do the voltage scaling
+ * for a particular voltage domain during dvfs or any other situation.
+ */
+int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ if (!vdd->volt_scale) {
+ pr_err("%s: No voltage scale API registered for vdd_%s\n",
+ __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ return vdd->volt_scale(vdd, target_volt);
+}
+
+/**
+ * omap_voltage_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the VDD whose voltage is to be reset.
+ *
+ * This API finds out the correct voltage the voltage domain is supposed
+ * to be at and resets the voltage to that level. Should be used especially
+ * while disabling any voltage compensation modules.
+ */
+void omap_voltage_reset(struct voltagedomain *voltdm)
+{
+ unsigned long target_uvdc;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ target_uvdc = omap_voltage_get_nom_volt(voltdm);
+ if (!target_uvdc) {
+ pr_err("%s: unable to find current voltage for vdd_%s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ omap_voltage_scale_vdd(voltdm, target_uvdc);
+}
+
+/**
+ * omap_voltage_get_volttable() - API to get the voltage table associated with a
+ * particular voltage domain.
+ * @voltdm: pointer to the VDD for which the voltage table is required
+ * @volt_data: the voltage table for the particular vdd which is to be
+ * populated by this API
+ *
+ * This API populates the voltage table associated with a VDD into the
+ * passed parameter pointer. Returns the count of distinct voltages
+ * supported by this vdd.
+ *
+ */
+void omap_voltage_get_volttable(struct voltagedomain *voltdm,
+ struct omap_volt_data **volt_data)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ *volt_data = vdd->volt_data;
+}
+
+/**
+ * omap_voltage_get_voltdata() - API to get the voltage table entry for a
+ * particular voltage
+ * @voltdm: pointer to the VDD whose voltage table has to be searched
+ * @volt: the voltage to be searched in the voltage table
+ *
+ * This API searches through the voltage table for the required voltage
+ * domain and tries to find a matching entry for the passed voltage volt.
+ * If a matching entry is found volt_data is populated with that entry.
+ * This API searches only through the non-compensated voltages int the
+ * voltage table.
+ * Returns pointer to the voltage table entry corresponding to volt on
+ * success. Returns -ENODATA if no voltage table exisits for the passed voltage
+ * domain or if there is no matching entry.
+ */
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt)
+{
+ struct omap_vdd_info *vdd;
+ int i;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ if (!vdd->volt_data) {
+ pr_warning("%s: voltage table does not exist for vdd_%s\n",
+ __func__, voltdm->name);
+ return ERR_PTR(-ENODATA);
+ }
+
+ for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
+ if (vdd->volt_data[i].volt_nominal == volt)
+ return &vdd->volt_data[i];
+ }
+
+ pr_notice("%s: Unable to match the current voltage with the voltage"
+ "table for vdd_%s\n", __func__, voltdm->name);
+
+ return ERR_PTR(-ENODATA);
+}
+
+/**
+ * omap_voltage_register_pmic() - API to register PMIC specific data
+ * @voltdm: pointer to the VDD for which the PMIC specific data is
+ * to be registered
+ * @pmic_info: the structure containing pmic info
+ *
+ * This API is to be called by the SOC/PMIC file to specify the
+ * pmic specific info as present in omap_volt_pmic_info structure.
+ */
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ vdd->pmic_info = pmic_info;
+
+ return 0;
+}
+
+/**
+ * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
+ * corresponding to a voltage domain.
+ *
+ * @voltdm: pointer to the VDD whose debug directory is required.
+ *
+ * This API returns pointer to the debugfs directory corresponding
+ * to the voltage domain. Should be used by drivers requiring to
+ * add any debug entry for a particular voltage domain. Returns NULL
+ * in case of error.
+ */
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return NULL;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ return vdd->debug_dir;
+}
+
+/**
+ * omap_change_voltscale_method() - API to change the voltage scaling method.
+ * @voltdm: pointer to the VDD whose voltage scaling method
+ * has to be changed.
+ * @voltscale_method: the method to be used for voltage scaling.
+ *
+ * This API can be used by the board files to change the method of voltage
+ * scaling between vpforceupdate and vcbypass. The parameter values are
+ * defined in voltage.h
+ */
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method)
+{
+ struct omap_vdd_info *vdd;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ switch (voltscale_method) {
+ case VOLTSCALE_VPFORCEUPDATE:
+ vdd->volt_scale = vp_forceupdate_scale_voltage;
+ return;
+ case VOLTSCALE_VCBYPASS:
+ vdd->volt_scale = vc_bypass_scale_voltage;
+ return;
+ default:
+ pr_warning("%s: Trying to change the method of voltage scaling"
+ "to an unsupported one!\n", __func__);
+ }
+}
+
+/**
+ * omap_voltage_domain_lookup() - API to get the voltage domain pointer
+ * @name: Name of the voltage domain
+ *
+ * This API looks up in the global vdd_info struct for the
+ * existence of voltage domain <name>. If it exists, the API returns
+ * a pointer to the voltage domain structure corresponding to the
+ * VDD<name>. Else retuns error pointer.
+ */
+struct voltagedomain *omap_voltage_domain_lookup(char *name)
+{
+ int i;
+
+ if (!vdd_info) {
+ pr_err("%s: Voltage driver init not yet happened.Faulting!\n",
+ __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (!name) {
+ pr_err("%s: No name to get the votage domain!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ for (i = 0; i < nr_scalable_vdd; i++) {
+ if (!(strcmp(name, vdd_info[i]->voltdm.name)))
+ return &vdd_info[i]->voltdm;
+ }
+
+ return ERR_PTR(-EINVAL);
+}
+
+/**
+ * omap_voltage_late_init() - Init the various voltage parameters
+ *
+ * This API is to be called in the later stages of the
+ * system boot to init the voltage controller and
+ * voltage processors.
+ */
+int __init omap_voltage_late_init(void)
+{
+ int i;
+
+ if (!vdd_info) {
+ pr_err("%s: Voltage driver support not added\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ voltage_dir = debugfs_create_dir("voltage", NULL);
+ if (IS_ERR(voltage_dir))
+ pr_err("%s: Unable to create voltage debugfs main dir\n",
+ __func__);
+ for (i = 0; i < nr_scalable_vdd; i++) {
+ if (omap_vdd_data_configure(vdd_info[i]))
+ continue;
+ omap_vc_init(vdd_info[i]);
+ vp_init(vdd_info[i]);
+ vdd_debugfs_init(vdd_info[i]);
+ }
+
+ return 0;
+}
+
+/* XXX document */
+int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_ocp_mod,
+ struct omap_vdd_info *omap_vdd_array[],
+ u8 omap_vdd_count)
+{
+ prm_mod_offs = prm_mod;
+ prm_irqst_ocp_mod_offs = prm_irqst_ocp_mod;
+ vdd_info = omap_vdd_array;
+ nr_scalable_vdd = omap_vdd_count;
+ return 0;
+}
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
new file mode 100644
index 00000000..e9f54082
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.h
@@ -0,0 +1,184 @@
+/*
+ * OMAP Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+
+#include <linux/err.h>
+
+#include "vc.h"
+#include "vp.h"
+
+/* XXX document */
+#define VOLTSCALE_VPFORCEUPDATE 1
+#define VOLTSCALE_VCBYPASS 2
+
+/*
+ * OMAP3 GENERIC setup times. Revisit to see if these needs to be
+ * passed from board or PMIC file
+ */
+#define OMAP3_CLKSETUP 0xff
+#define OMAP3_VOLTOFFSET 0xff
+#define OMAP3_VOLTSETUP2 0xff
+
+/**
+ * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
+ * data
+ * @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
+ * @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
+ * @voltsetup_shift: SETUP_TIME* field shift in the PRM_VOLTSETUP* register
+ *
+ * XXX What about VOLTOFFSET/VOLTCTRL?
+ * XXX It is not necessary to have both a _mask and a _shift for the same
+ * bitfield - remove one!
+ */
+struct omap_vfsm_instance_data {
+ u32 voltsetup_mask;
+ u8 voltsetup_reg;
+ u8 voltsetup_shift;
+};
+
+/**
+ * struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as a unique
+ * identifier.
+ */
+struct voltagedomain {
+ char *name;
+};
+
+/**
+ * struct omap_volt_data - Omap voltage specific data.
+ * @voltage_nominal: The possible voltage value in uV
+ * @sr_efuse_offs: The offset of the efuse register(from system
+ * control module base address) from where to read
+ * the n-target value for the smartreflex module.
+ * @sr_errminlimit: Error min limit value for smartreflex. This value
+ * differs at differnet opp and thus is linked
+ * with voltage.
+ * @vp_errorgain: Error gain value for the voltage processor. This
+ * field also differs according to the voltage/opp.
+ */
+struct omap_volt_data {
+ u32 volt_nominal;
+ u32 sr_efuse_offs;
+ u8 sr_errminlimit;
+ u8 vp_errgain;
+};
+
+/**
+ * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * @slew_rate: PMIC slew rate (in uv/us)
+ * @step_size: PMIC voltage step size (in uv)
+ * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
+ * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
+ */
+struct omap_volt_pmic_info {
+ int slew_rate;
+ int step_size;
+ u32 on_volt;
+ u32 onlp_volt;
+ u32 ret_volt;
+ u32 off_volt;
+ u16 volt_setup_time;
+ u8 vp_erroroffset;
+ u8 vp_vstepmin;
+ u8 vp_vstepmax;
+ u8 vp_vddmin;
+ u8 vp_vddmax;
+ u8 vp_timeout_us;
+ u8 i2c_slave_addr;
+ u8 pmic_reg;
+ unsigned long (*vsel_to_uv) (const u8 vsel);
+ u8 (*uv_to_vsel) (unsigned long uV);
+};
+
+/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data : voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
+ * @pmic_info : pmic specific parameters which should be populted by
+ * the pmic drivers.
+ * @vp_data : the register values, shifts, masks for various
+ * vp registers
+ * @vp_rt_data : VP data derived at runtime, not predefined
+ * @vc_data : structure containing various various vc registers,
+ * shifts, masks etc.
+ * @vfsm : voltage manager FSM data
+ * @voltdm : pointer to the voltage domain structure
+ * @debug_dir : debug directory for this voltage domain.
+ * @curr_volt : current voltage for this vdd.
+ * @vp_enabled : flag to keep track of whether vp is enabled or not
+ * @volt_scale : API to scale the voltage of the vdd.
+ */
+struct omap_vdd_info {
+ struct omap_volt_data *volt_data;
+ struct omap_volt_pmic_info *pmic_info;
+ struct omap_vp_instance_data *vp_data;
+ struct omap_vp_runtime_data vp_rt_data;
+ struct omap_vc_instance_data *vc_data;
+ const struct omap_vfsm_instance_data *vfsm;
+ struct voltagedomain voltdm;
+ struct dentry *debug_dir;
+ u32 curr_volt;
+ bool vp_enabled;
+ u32 (*read_reg) (u16 mod, u8 offset);
+ void (*write_reg) (u32 val, u16 mod, u8 offset);
+ int (*volt_scale) (struct omap_vdd_info *vdd,
+ unsigned long target_volt);
+};
+
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+void omap_voltage_reset(struct voltagedomain *voltdm);
+void omap_voltage_get_volttable(struct voltagedomain *voltdm,
+ struct omap_volt_data **volt_data);
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt);
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
+ struct omap_vdd_info *omap_vdd_array[],
+ u8 omap_vdd_count);
+#ifdef CONFIG_PM
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info);
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method);
+/* API to get the voltagedomain pointer */
+struct voltagedomain *omap_voltage_domain_lookup(char *name);
+
+int omap_voltage_late_init(void);
+#else
+static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info)
+{
+ return -EINVAL;
+}
+static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method) {}
+static inline int omap_voltage_late_init(void)
+{
+ return -EINVAL;
+}
+static inline struct voltagedomain *omap_voltage_domain_lookup(char *name)
+{
+ return ERR_PTR(-EINVAL);
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
new file mode 100644
index 00000000..def230fd
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -0,0 +1,95 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+#include <plat/cpu.h>
+
+#include "prm-regbits-34xx.h"
+#include "omap_opp_data.h"
+#include "voltage.h"
+#include "vc.h"
+#include "vp.h"
+
+/*
+ * VDD data
+ */
+
+static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
+ .voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd1_info = {
+ .vp_data = &omap3_vp1_data,
+ .vc_data = &omap3_vc1_data,
+ .vfsm = &omap3_vdd1_vfsm_data,
+ .voltdm = {
+ .name = "mpu",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
+ .voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
+ .voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
+ .voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
+};
+
+static struct omap_vdd_info omap3_vdd2_info = {
+ .vp_data = &omap3_vp2_data,
+ .vc_data = &omap3_vc2_data,
+ .vfsm = &omap3_vdd2_vfsm_data,
+ .voltdm = {
+ .name = "core",
+ },
+};
+
+/* OMAP3 VDD structures */
+static struct omap_vdd_info *omap3_vdd_info[] = {
+ &omap3_vdd1_info,
+ &omap3_vdd2_info,
+};
+
+/* OMAP3 specific voltage init functions */
+static int __init omap3xxx_voltage_early_init(void)
+{
+ s16 prm_mod = OMAP3430_GR_MOD;
+ s16 prm_irqst_ocp_mod = OCP_MOD;
+
+ if (!cpu_is_omap34xx())
+ return 0;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+ if (cpu_is_omap3630()) {
+ omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
+ omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
+ } else {
+ omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
+ omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
+ }
+
+ return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+ omap3_vdd_info,
+ ARRAY_SIZE(omap3_vdd_info));
+};
+core_initcall(omap3xxx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
new file mode 100644
index 00000000..cb64996d
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -0,0 +1,102 @@
+/*
+ * OMAP3/OMAP4 Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
+#include "voltage.h"
+#include "omap_opp_data.h"
+#include "vc.h"
+#include "vp.h"
+
+static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_mpu_info = {
+ .vp_data = &omap4_vp_mpu_data,
+ .vc_data = &omap4_vc_mpu_data,
+ .vfsm = &omap4_vdd_mpu_vfsm_data,
+ .voltdm = {
+ .name = "mpu",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_iva_info = {
+ .vp_data = &omap4_vp_iva_data,
+ .vc_data = &omap4_vc_iva_data,
+ .vfsm = &omap4_vdd_iva_vfsm_data,
+ .voltdm = {
+ .name = "iva",
+ },
+};
+
+static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+};
+
+static struct omap_vdd_info omap4_vdd_core_info = {
+ .vp_data = &omap4_vp_core_data,
+ .vc_data = &omap4_vc_core_data,
+ .vfsm = &omap4_vdd_core_vfsm_data,
+ .voltdm = {
+ .name = "core",
+ },
+};
+
+/* OMAP4 VDD structures */
+static struct omap_vdd_info *omap4_vdd_info[] = {
+ &omap4_vdd_mpu_info,
+ &omap4_vdd_iva_info,
+ &omap4_vdd_core_info,
+};
+
+/* OMAP4 specific voltage init functions */
+static int __init omap44xx_voltage_early_init(void)
+{
+ s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
+ s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+
+ if (!cpu_is_omap44xx())
+ return 0;
+
+ /*
+ * XXX Will depend on the process, validation, and binning
+ * for the currently-running IC
+ */
+ omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
+ omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
+ omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+
+ return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
+ omap4_vdd_info,
+ ARRAY_SIZE(omap4_vdd_info));
+};
+core_initcall(omap44xx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
new file mode 100644
index 00000000..7ce134f7
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.h
@@ -0,0 +1,143 @@
+/*
+ * OMAP3/4 Voltage Processor (VP) structure and macro definitions
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_VP_H
+#define __ARCH_ARM_MACH_OMAP2_VP_H
+
+#include <linux/kernel.h>
+
+/* XXX document */
+#define VP_IDLE_TIMEOUT 200
+#define VP_TRANXDONE_TIMEOUT 300
+
+
+/**
+ * struct omap_vp_common_data - register data common to all VDDs
+ * @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
+ * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ *
+ * XXX It it not necessary to have both a mask and a shift for the same
+ * bitfield - remove one
+ * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
+ */
+struct omap_vp_common_data {
+ u32 vpconfig_errorgain_mask;
+ u32 vpconfig_initvoltage_mask;
+ u32 vpconfig_timeouten;
+ u32 vpconfig_initvdd;
+ u32 vpconfig_forceupdate;
+ u32 vpconfig_vpenable;
+ u8 vpconfig_erroroffset_shift;
+ u8 vpconfig_errorgain_shift;
+ u8 vpconfig_initvoltage_shift;
+ u8 vstepmin_stepmin_shift;
+ u8 vstepmin_smpswaittimemin_shift;
+ u8 vstepmax_stepmax_shift;
+ u8 vstepmax_smpswaittimemax_shift;
+ u8 vlimitto_vddmin_shift;
+ u8 vlimitto_vddmax_shift;
+ u8 vlimitto_timeout_shift;
+};
+
+/**
+ * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
+ * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ *
+ * XXX prm_irqst_reg does not belong here
+ * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
+ * hardware bug
+ * XXX This structure is probably not needed
+ */
+struct omap_vp_prm_irqst_data {
+ u8 prm_irqst_reg;
+ u32 tranxdone_status;
+};
+
+/**
+ * struct omap_vp_instance_data - VP register offsets (per-VDD)
+ * @vp_common: pointer to struct omap_vp_common_data * for this SoC
+ * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
+ * @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
+ * @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
+ * @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
+ * @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
+ * @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
+ *
+ * XXX vp_common is probably not needed since it is per-SoC
+ */
+struct omap_vp_instance_data {
+ const struct omap_vp_common_data *vp_common;
+ const struct omap_vp_prm_irqst_data *prm_irqst_data;
+ u8 vpconfig;
+ u8 vstepmin;
+ u8 vstepmax;
+ u8 vlimitto;
+ u8 vstatus;
+ u8 voltage;
+};
+
+/**
+ * struct omap_vp_runtime_data - VP data populated at runtime by code
+ * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
+ * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
+ * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
+ * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
+ * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
+ * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
+ * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
+ *
+ * XXX Is this structure really needed? Why not just program the
+ * device directly? They are in PRM space, therefore in the WKUP
+ * powerdomain, so register contents should not be lost in off-mode.
+ * XXX Some of these fields are incorrectly named, e.g., vstep*
+ */
+struct omap_vp_runtime_data {
+ u32 vpconfig_erroroffset;
+ u16 vpconfig_errorgain;
+ u16 vstepmin_smpswaittimemin;
+ u16 vstepmax_smpswaittimemax;
+ u16 vlimitto_timeout;
+ u8 vstepmin_stepmin;
+ u8 vstepmax_stepmax;
+ u8 vlimitto_vddmin;
+ u8 vlimitto_vddmax;
+};
+
+extern struct omap_vp_instance_data omap3_vp1_data;
+extern struct omap_vp_instance_data omap3_vp2_data;
+
+extern struct omap_vp_instance_data omap4_vp_mpu_data;
+extern struct omap_vp_instance_data omap4_vp_iva_data;
+extern struct omap_vp_instance_data omap4_vp_core_data;
+
+#endif
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
new file mode 100644
index 00000000..64521709
--- /dev/null
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -0,0 +1,82 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm-regbits-34xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 34xx/36xx chips
+ * XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap3_vp_common = {
+ .vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
+ .vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
+ .vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
+ .vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
+ .vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
+ .vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
+ .vpconfig_initvdd = OMAP3430_INITVDD_MASK,
+ .vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK,
+ .vpconfig_vpenable = OMAP3430_VPENABLE_MASK,
+ .vstepmin_smpswaittimemin_shift = OMAP3430_SMPSWAITTIMEMIN_SHIFT,
+ .vstepmax_smpswaittimemax_shift = OMAP3430_SMPSWAITTIMEMAX_SHIFT,
+ .vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT,
+ .vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT,
+ .vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
+ .vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
+ .vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
+ .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp1_data = {
+ .vp_common = &omap3_vp_common,
+ .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap3_vp1_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
+ .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap3_vp2_data = {
+ .vp_common = &omap3_vp_common,
+ .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
+ .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
+ .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
+ .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap3_vp2_prm_irqst_data,
+};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
new file mode 100644
index 00000000..65d1ad63
--- /dev/null
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -0,0 +1,100 @@
+/*
+ * OMAP3 Voltage Processor (VP) data
+ *
+ * Copyright (C) 2007, 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ * Lesly A M <x0080970@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008, 2011 Nokia Corporation
+ * Kalle Jokiniemi
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
+#include "voltage.h"
+
+#include "vp.h"
+
+/*
+ * VP data common to 44xx chips
+ * XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
+ */
+static const struct omap_vp_common_data omap4_vp_common = {
+ .vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
+ .vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
+ .vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
+ .vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
+ .vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
+ .vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
+ .vpconfig_initvdd = OMAP4430_INITVDD_MASK,
+ .vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK,
+ .vpconfig_vpenable = OMAP4430_VPENABLE_MASK,
+ .vstepmin_smpswaittimemin_shift = OMAP4430_SMPSWAITTIMEMIN_SHIFT,
+ .vstepmax_smpswaittimemax_shift = OMAP4430_SMPSWAITTIMEMAX_SHIFT,
+ .vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT,
+ .vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT,
+ .vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
+ .vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
+ .vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+ .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_mpu_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_iva_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
+};
+
+static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
+ .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+};
+
+struct omap_vp_instance_data omap4_vp_core_data = {
+ .vp_common = &omap4_vp_common,
+ .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
+ .prm_irqst_data = &omap4_vp_core_prm_irqst_data,
+};
+
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
new file mode 100644
index 00000000..4067669d
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.c
@@ -0,0 +1,56 @@
+/*
+ * OMAP2+ MPU WD_TIMER-specific code
+ *
+ * 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/io.h>
+#include <linux/err.h>
+
+#include <plat/omap_hwmod.h>
+
+#include "wd_timer.h"
+
+/*
+ * In order to avoid any assumptions from bootloader regarding WDT
+ * settings, WDT module is reset during init. This enables the watchdog
+ * timer. Hence it is required to disable the watchdog after the WDT reset
+ * during init. Otherwise the system would reboot as per the default
+ * watchdog timer registers settings.
+ */
+#define OMAP_WDT_WPS 0x34
+#define OMAP_WDT_SPR 0x48
+
+
+int omap2_wd_timer_disable(struct omap_hwmod *oh)
+{
+ void __iomem *base;
+
+ if (!oh) {
+ pr_err("%s: Could not look up wdtimer_hwmod\n", __func__);
+ return -EINVAL;
+ }
+
+ base = omap_hwmod_get_mpu_rt_va(oh);
+ if (!base) {
+ pr_err("%s: Could not get the base address for %s\n",
+ oh->name, __func__);
+ return -EINVAL;
+ }
+
+ /* sequence required to disable watchdog */
+ __raw_writel(0xAAAA, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ __raw_writel(0x5555, base + OMAP_WDT_SPR);
+ while (__raw_readl(base + OMAP_WDT_WPS) & 0x10)
+ cpu_relax();
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/wd_timer.h b/arch/arm/mach-omap2/wd_timer.h
new file mode 100644
index 00000000..e0054a2d
--- /dev/null
+++ b/arch/arm/mach-omap2/wd_timer.h
@@ -0,0 +1,17 @@
+/*
+ * OMAP2+ MPU WD_TIMER-specific function prototypes
+ *
+ * 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 __ARCH_ARM_MACH_OMAP2_WD_TIMER_H
+#define __ARCH_ARM_MACH_OMAP2_WD_TIMER_H
+
+#include <plat/omap_hwmod.h>
+
+extern int omap2_wd_timer_disable(struct omap_hwmod *oh);
+
+#endif
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
new file mode 100644
index 00000000..6604fc6c
--- /dev/null
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -0,0 +1,160 @@
+if ARCH_ORION5X
+
+menu "Orion Implementations"
+
+config MACH_DB88F5281
+ bool "Marvell Orion-2 Development Board"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-2 (88F5281) Development Board
+
+config MACH_RD88F5182
+ bool "Marvell Orion-NAS Reference Design"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-NAS (88F5182) RD2
+
+config MACH_KUROBOX_PRO
+ bool "KuroBox Pro"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ KuroBox Pro platform.
+
+config MACH_DNS323
+ bool "D-Link DNS-323"
+ select I2C_BOARDINFO
+ select PHYLIB
+ help
+ Say 'Y' here if you want your kernel to support the
+ D-Link DNS-323 platform.
+
+config MACH_TS209
+ bool "QNAP TS-109/TS-209"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-109/TS-209 platform.
+
+config MACH_TERASTATION_PRO2
+ bool "Buffalo Terastation Pro II/Live"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Terastation Pro II/Live platform.
+
+config MACH_LINKSTATION_PRO
+ bool "Buffalo Linkstation Pro/Live"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation Pro/Live platform. Both v1 and
+ v2 devices are supported.
+
+config MACH_LINKSTATION_LSCHL
+ bool "Buffalo Linkstation Live v3 (LS-CHL)"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation Live v3 (LS-CHL) platform.
+
+config MACH_LINKSTATION_MINI
+ bool "Buffalo Linkstation Mini"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation Mini platform.
+
+config MACH_LINKSTATION_LS_HGL
+ bool "Buffalo Linkstation LS-HGL"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation LS-HGL platform.
+
+config MACH_TS409
+ bool "QNAP TS-409"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-409 platform.
+
+config MACH_WRT350N_V2
+ bool "Linksys WRT350N v2"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Linksys WRT350N v2 platform.
+
+config MACH_TS78XX
+ bool "Technologic Systems TS-78xx"
+ select PM
+ help
+ Say 'Y' here if you want your kernel to support the
+ Technologic Systems TS-78xx platform.
+
+config MACH_MV2120
+ bool "HP Media Vault mv2120"
+ help
+ Say 'Y' here if you want your kernel to support the
+ HP Media Vault mv2120 or mv5100.
+
+config MACH_EDMINI_V2
+ bool "LaCie Ethernet Disk mini V2"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Ethernet Disk mini V2.
+
+config MACH_D2NET
+ bool "LaCie d2 Network"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie d2 Network NAS.
+
+config MACH_BIGDISK
+ bool "LaCie Big Disk Network"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Big Disk Network NAS.
+
+config MACH_NET2BIG
+ bool "LaCie 2Big Network"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie 2Big Network NAS.
+
+config MACH_MSS2
+ bool "Maxtor Shared Storage II"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Maxtor Shared Storage II platform.
+
+config MACH_WNR854T
+ bool "Netgear WNR854T"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Netgear WNR854T platform.
+
+config MACH_RD88F5181L_GE
+ bool "Marvell Orion-VoIP GE Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-VoIP GE (88F5181L) RD.
+
+config MACH_RD88F5181L_FXO
+ bool "Marvell Orion-VoIP FXO Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-VoIP FXO (88F5181L) RD.
+
+config MACH_RD88F6183AP_GE
+ bool "Marvell Orion-1-90 AP GE Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-1-90 (88F6183) AP GE RD.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
new file mode 100644
index 00000000..7f18cdac
--- /dev/null
+++ b/arch/arm/mach-orion5x/Makefile
@@ -0,0 +1,24 @@
+obj-y += common.o addr-map.o pci.o irq.o mpp.o
+obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
+obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
+obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
+obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_LS_HGL) += ls_hgl-setup.o
+obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
+obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
+obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o
+obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o
+obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o
+obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o
+obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o
+obj-$(CONFIG_MACH_D2NET) += d2net-setup.o
+obj-$(CONFIG_MACH_BIGDISK) += d2net-setup.o
+obj-$(CONFIG_MACH_NET2BIG) += net2big-setup.o
+obj-$(CONFIG_MACH_MSS2) += mss2-setup.o
+obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
+obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
+obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
+obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_LSCHL) += ls-chl-setup.o
diff --git a/arch/arm/mach-orion5x/Makefile.boot b/arch/arm/mach-orion5x/Makefile.boot
new file mode 100644
index 00000000..67039c3e
--- /dev/null
+++ b/arch/arm/mach-orion5x/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
new file mode 100644
index 00000000..5ceafdcc
--- /dev/null
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -0,0 +1,206 @@
+/*
+ * arch/arm/mach-orion5x/addr-map.c
+ *
+ * Address map functions for Marvell Orion 5x SoCs
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <mach/hardware.h>
+#include "common.h"
+
+/*
+ * The Orion has fully programmable address map. There's a separate address
+ * map for each of the device _master_ interfaces, e.g. CPU, PCI, PCIe, USB,
+ * Gigabit Ethernet, DMA/XOR engines, etc. Each interface has its own
+ * address decode windows that allow it to access any of the Orion resources.
+ *
+ * CPU address decoding --
+ * Linux assumes that it is the boot loader that already setup the access to
+ * DDR and internal registers.
+ * Setup access to PCI and PCIe IO/MEM space is issued by this file.
+ * Setup access to various devices located on the device bus interface (e.g.
+ * flashes, RTC, etc) should be issued by machine-setup.c according to
+ * specific board population (by using orion5x_setup_*_win()).
+ *
+ * Non-CPU Masters address decoding --
+ * Unlike the CPU, we setup the access from Orion's master interfaces to DDR
+ * banks only (the typical use case).
+ * Setup access for each master to DDR is issued by platform device setup.
+ */
+
+/*
+ * Generic Address Decode Windows bit settings
+ */
+#define TARGET_DDR 0
+#define TARGET_DEV_BUS 1
+#define TARGET_PCI 3
+#define TARGET_PCIE 4
+#define TARGET_SRAM 9
+#define ATTR_PCIE_MEM 0x59
+#define ATTR_PCIE_IO 0x51
+#define ATTR_PCIE_WA 0x79
+#define ATTR_PCI_MEM 0x59
+#define ATTR_PCI_IO 0x51
+#define ATTR_DEV_CS0 0x1e
+#define ATTR_DEV_CS1 0x1d
+#define ATTR_DEV_CS2 0x1b
+#define ATTR_DEV_BOOT 0xf
+#define ATTR_SRAM 0x0
+
+/*
+ * Helpers to get DDR bank info
+ */
+#define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x))
+#define DDR_BASE_CS(n) ORION5X_DDR_REG(0x1500 + ((n) << 3))
+#define DDR_SIZE_CS(n) ORION5X_DDR_REG(0x1504 + ((n) << 3))
+
+/*
+ * CPU Address Decode Windows registers
+ */
+#define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x))
+#define CPU_WIN_CTRL(n) ORION5X_BRIDGE_REG(0x000 | ((n) << 4))
+#define CPU_WIN_BASE(n) ORION5X_BRIDGE_REG(0x004 | ((n) << 4))
+#define CPU_WIN_REMAP_LO(n) ORION5X_BRIDGE_REG(0x008 | ((n) << 4))
+#define CPU_WIN_REMAP_HI(n) ORION5X_BRIDGE_REG(0x00c | ((n) << 4))
+
+
+struct mbus_dram_target_info orion5x_mbus_dram_info;
+static int __initdata win_alloc_count;
+
+static int __init orion5x_cpu_win_can_remap(int win)
+{
+ u32 dev, rev;
+
+ orion5x_pcie_id(&dev, &rev);
+ if ((dev == MV88F5281_DEV_ID && win < 4)
+ || (dev == MV88F5182_DEV_ID && win < 2)
+ || (dev == MV88F5181_DEV_ID && win < 2)
+ || (dev == MV88F6183_DEV_ID && win < 4))
+ return 1;
+
+ return 0;
+}
+
+static int __init setup_cpu_win(int win, u32 base, u32 size,
+ u8 target, u8 attr, int remap)
+{
+ if (win >= 8) {
+ printk(KERN_ERR "setup_cpu_win: trying to allocate "
+ "window %d\n", win);
+ return -ENOSPC;
+ }
+
+ writel(base & 0xffff0000, CPU_WIN_BASE(win));
+ writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1,
+ CPU_WIN_CTRL(win));
+
+ if (orion5x_cpu_win_can_remap(win)) {
+ if (remap < 0)
+ remap = base;
+
+ writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
+ writel(0, CPU_WIN_REMAP_HI(win));
+ }
+ return 0;
+}
+
+void __init orion5x_setup_cpu_mbus_bridge(void)
+{
+ int i;
+ int cs;
+
+ /*
+ * First, disable and clear windows.
+ */
+ for (i = 0; i < 8; i++) {
+ writel(0, CPU_WIN_BASE(i));
+ writel(0, CPU_WIN_CTRL(i));
+ if (orion5x_cpu_win_can_remap(i)) {
+ writel(0, CPU_WIN_REMAP_LO(i));
+ writel(0, CPU_WIN_REMAP_HI(i));
+ }
+ }
+
+ /*
+ * Setup windows for PCI+PCIe IO+MEM space.
+ */
+ setup_cpu_win(0, ORION5X_PCIE_IO_PHYS_BASE, ORION5X_PCIE_IO_SIZE,
+ TARGET_PCIE, ATTR_PCIE_IO, ORION5X_PCIE_IO_BUS_BASE);
+ setup_cpu_win(1, ORION5X_PCI_IO_PHYS_BASE, ORION5X_PCI_IO_SIZE,
+ TARGET_PCI, ATTR_PCI_IO, ORION5X_PCI_IO_BUS_BASE);
+ setup_cpu_win(2, ORION5X_PCIE_MEM_PHYS_BASE, ORION5X_PCIE_MEM_SIZE,
+ TARGET_PCIE, ATTR_PCIE_MEM, -1);
+ setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
+ TARGET_PCI, ATTR_PCI_MEM, -1);
+ win_alloc_count = 4;
+
+ /*
+ * Setup MBUS dram target info.
+ */
+ orion5x_mbus_dram_info.mbus_dram_target_id = TARGET_DDR;
+
+ for (i = 0, cs = 0; i < 4; i++) {
+ u32 base = readl(DDR_BASE_CS(i));
+ u32 size = readl(DDR_SIZE_CS(i));
+
+ /*
+ * Chip select enabled?
+ */
+ if (size & 1) {
+ struct mbus_dram_window *w;
+
+ w = &orion5x_mbus_dram_info.cs[cs++];
+ w->cs_index = i;
+ w->mbus_attr = 0xf & ~(1 << i);
+ w->base = base & 0xffff0000;
+ w->size = (size | 0x0000ffff) + 1;
+ }
+ }
+ orion5x_mbus_dram_info.num_cs = cs;
+}
+
+void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
+{
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
+}
+
+void __init orion5x_setup_dev0_win(u32 base, u32 size)
+{
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
+}
+
+void __init orion5x_setup_dev1_win(u32 base, u32 size)
+{
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
+}
+
+void __init orion5x_setup_dev2_win(u32 base, u32 size)
+{
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
+}
+
+void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
+{
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_PCIE, ATTR_PCIE_WA, -1);
+}
+
+int __init orion5x_setup_sram_win(void)
+{
+ return setup_cpu_win(win_alloc_count++, ORION5X_SRAM_PHYS_BASE,
+ ORION5X_SRAM_SIZE, TARGET_SRAM, ATTR_SRAM, -1);
+}
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
new file mode 100644
index 00000000..8a98da0b
--- /dev/null
+++ b/arch/arm/mach-orion5x/common.c
@@ -0,0 +1,325 @@
+/*
+ * arch/arm/mach-orion5x/common.c
+ *
+ * Core functions for Marvell Orion 5x SoCs
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/mv643xx_i2c.h>
+#include <linux/ata_platform.h>
+#include <net/dsa.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/timex.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/bridge-regs.h>
+#include <mach/hardware.h>
+#include <mach/orion5x.h>
+#include <plat/orion_nand.h>
+#include <plat/ehci-orion.h>
+#include <plat/time.h>
+#include <plat/common.h>
+#include "common.h"
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc orion5x_io_desc[] __initdata = {
+ {
+ .virtual = ORION5X_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
+ .length = ORION5X_REGS_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = ORION5X_PCIE_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
+ .length = ORION5X_PCIE_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = ORION5X_PCI_IO_VIRT_BASE,
+ .pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
+ .length = ORION5X_PCI_IO_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = ORION5X_PCIE_WA_VIRT_BASE,
+ .pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
+ .length = ORION5X_PCIE_WA_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init orion5x_map_io(void)
+{
+ iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
+}
+
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+void __init orion5x_ehci0_init(void)
+{
+ orion_ehci_init(&orion5x_mbus_dram_info,
+ ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL,
+ EHCI_PHY_ORION);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+void __init orion5x_ehci1_init(void)
+{
+ orion_ehci_1_init(&orion5x_mbus_dram_info,
+ ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
+}
+
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
+{
+ orion_ge00_init(eth_data, &orion5x_mbus_dram_info,
+ ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
+ IRQ_ORION5X_ETH_ERR, orion5x_tclk);
+}
+
+
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
+{
+ orion_ge00_switch_init(d, irq);
+}
+
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+void __init orion5x_i2c_init(void)
+{
+ orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8);
+
+}
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
+{
+ orion_sata_init(sata_data, &orion5x_mbus_dram_info,
+ ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
+}
+
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+void __init orion5x_spi_init()
+{
+ orion_spi_init(SPI_PHYS_BASE, orion5x_tclk);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+void __init orion5x_uart0_init(void)
+{
+ orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+ IRQ_ORION5X_UART0, orion5x_tclk);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+void __init orion5x_uart1_init(void)
+{
+ orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+ IRQ_ORION5X_UART1, orion5x_tclk);
+}
+
+/*****************************************************************************
+ * XOR engine
+ ****************************************************************************/
+void __init orion5x_xor_init(void)
+{
+ orion_xor0_init(&orion5x_mbus_dram_info,
+ ORION5X_XOR_PHYS_BASE,
+ ORION5X_XOR_PHYS_BASE + 0x200,
+ IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1);
+}
+
+/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+static void __init orion5x_crypto_init(void)
+{
+ int ret;
+
+ ret = orion5x_setup_sram_win();
+ if (ret)
+ return;
+
+ orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
+ SZ_8K, IRQ_ORION5X_CESA);
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+void __init orion5x_wdt_init(void)
+{
+ orion_wdt_init(orion5x_tclk);
+}
+
+
+/*****************************************************************************
+ * Time handling
+ ****************************************************************************/
+void __init orion5x_init_early(void)
+{
+ orion_time_set_base(TIMER_VIRT_BASE);
+}
+
+int orion5x_tclk;
+
+int __init orion5x_find_tclk(void)
+{
+ u32 dev, rev;
+
+ orion5x_pcie_id(&dev, &rev);
+ if (dev == MV88F6183_DEV_ID &&
+ (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
+ return 133333333;
+
+ return 166666667;
+}
+
+static void orion5x_timer_init(void)
+{
+ orion5x_tclk = orion5x_find_tclk();
+
+ orion_time_init(ORION5X_BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR,
+ IRQ_ORION5X_BRIDGE, orion5x_tclk);
+}
+
+struct sys_timer orion5x_timer = {
+ .init = orion5x_timer_init,
+};
+
+
+/*****************************************************************************
+ * General
+ ****************************************************************************/
+/*
+ * Identify device ID and rev from PCIe configuration header space '0'.
+ */
+static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
+{
+ orion5x_pcie_id(dev, rev);
+
+ if (*dev == MV88F5281_DEV_ID) {
+ if (*rev == MV88F5281_REV_D2) {
+ *dev_name = "MV88F5281-D2";
+ } else if (*rev == MV88F5281_REV_D1) {
+ *dev_name = "MV88F5281-D1";
+ } else if (*rev == MV88F5281_REV_D0) {
+ *dev_name = "MV88F5281-D0";
+ } else {
+ *dev_name = "MV88F5281-Rev-Unsupported";
+ }
+ } else if (*dev == MV88F5182_DEV_ID) {
+ if (*rev == MV88F5182_REV_A2) {
+ *dev_name = "MV88F5182-A2";
+ } else {
+ *dev_name = "MV88F5182-Rev-Unsupported";
+ }
+ } else if (*dev == MV88F5181_DEV_ID) {
+ if (*rev == MV88F5181_REV_B1) {
+ *dev_name = "MV88F5181-Rev-B1";
+ } else if (*rev == MV88F5181L_REV_A1) {
+ *dev_name = "MV88F5181L-Rev-A1";
+ } else {
+ *dev_name = "MV88F5181(L)-Rev-Unsupported";
+ }
+ } else if (*dev == MV88F6183_DEV_ID) {
+ if (*rev == MV88F6183_REV_B0) {
+ *dev_name = "MV88F6183-Rev-B0";
+ } else {
+ *dev_name = "MV88F6183-Rev-Unsupported";
+ }
+ } else {
+ *dev_name = "Device-Unknown";
+ }
+}
+
+void __init orion5x_init(void)
+{
+ char *dev_name;
+ u32 dev, rev;
+
+ orion5x_id(&dev, &rev, &dev_name);
+ printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
+
+ /*
+ * Setup Orion address map
+ */
+ orion5x_setup_cpu_mbus_bridge();
+
+ /*
+ * Don't issue "Wait for Interrupt" instruction if we are
+ * running on D0 5281 silicon.
+ */
+ if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
+ printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
+ disable_hlt();
+ }
+
+ /*
+ * The 5082/5181l/5182/6082/6082l/6183 have crypto
+ * while 5180n/5181/5281 don't have crypto.
+ */
+ if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
+ dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
+ orion5x_crypto_init();
+
+ /*
+ * Register watchdog driver
+ */
+ orion5x_wdt_init();
+}
+
+/*
+ * Many orion-based systems have buggy bootloader implementations.
+ * This is a common fixup for bogus memory tags.
+ */
+void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t,
+ char **from, struct meminfo *meminfo)
+{
+ for (; t->hdr.size; t = tag_next(t))
+ if (t->hdr.tag == ATAG_MEM &&
+ (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
+ t->u.mem.start & ~PAGE_MASK)) {
+ printk(KERN_WARNING
+ "Clearing invalid memory bank %dKB@0x%08x\n",
+ t->u.mem.size / 1024, t->u.mem.start);
+ t->hdr.tag = 0;
+ }
+}
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
new file mode 100644
index 00000000..f2b2b35e
--- /dev/null
+++ b/arch/arm/mach-orion5x/common.h
@@ -0,0 +1,63 @@
+#ifndef __ARCH_ORION5X_COMMON_H
+#define __ARCH_ORION5X_COMMON_H
+
+struct dsa_platform_data;
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
+/*
+ * Basic Orion init functions used early by machine-setup.
+ */
+void orion5x_map_io(void);
+void orion5x_init_early(void);
+void orion5x_init_irq(void);
+void orion5x_init(void);
+extern int orion5x_tclk;
+extern struct sys_timer orion5x_timer;
+
+/*
+ * Enumerations and functions for Orion windows mapping. Used by Orion core
+ * functions to map its interfaces and by the machine-setup to map its on-
+ * board devices. Details in /mach-orion/addr-map.c
+ */
+extern struct mbus_dram_target_info orion5x_mbus_dram_info;
+void orion5x_setup_cpu_mbus_bridge(void);
+void orion5x_setup_dev_boot_win(u32 base, u32 size);
+void orion5x_setup_dev0_win(u32 base, u32 size);
+void orion5x_setup_dev1_win(u32 base, u32 size);
+void orion5x_setup_dev2_win(u32 base, u32 size);
+void orion5x_setup_pcie_wa_win(u32 base, u32 size);
+int orion5x_setup_sram_win(void);
+
+void orion5x_ehci0_init(void);
+void orion5x_ehci1_init(void);
+void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
+void orion5x_eth_switch_init(struct dsa_platform_data *d, int irq);
+void orion5x_i2c_init(void);
+void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
+void orion5x_spi_init(void);
+void orion5x_uart0_init(void);
+void orion5x_uart1_init(void);
+void orion5x_xor_init(void);
+
+/*
+ * PCIe/PCI functions.
+ */
+struct pci_bus;
+struct pci_sys_data;
+
+void orion5x_pcie_id(u32 *dev, u32 *rev);
+void orion5x_pci_disable(void);
+void orion5x_pci_set_cardbus_mode(void);
+int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys);
+struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
+int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
+
+struct machine_desc;
+struct meminfo;
+struct tag;
+extern void __init tag_fixup_mem32(struct machine_desc *, struct tag *,
+ char **, struct meminfo *);
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/d2net-setup.c b/arch/arm/mach-orion5x/d2net-setup.c
new file mode 100644
index 00000000..19cf5bf9
--- /dev/null
+++ b/arch/arm/mach-orion5x/d2net-setup.c
@@ -0,0 +1,360 @@
+/*
+ * arch/arm/mach-orion5x/d2net-setup.c
+ *
+ * LaCie d2Network and Big Disk Network NAS setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * LaCie d2 Network Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define D2NET_NOR_BOOT_BASE 0xfff80000
+#define D2NET_NOR_BOOT_SIZE SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on Boot Device
+ ****************************************************************************/
+
+/*
+ * TODO: Check write support on flash MX29LV400CBTC-70G
+ */
+
+static struct mtd_partition d2net_partitions[] = {
+ {
+ .name = "Full512kb",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data d2net_nor_flash_data = {
+ .width = 1,
+ .parts = d2net_partitions,
+ .nr_parts = ARRAY_SIZE(d2net_partitions),
+};
+
+static struct resource d2net_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = D2NET_NOR_BOOT_BASE,
+ .end = D2NET_NOR_BOOT_BASE
+ + D2NET_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device d2net_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &d2net_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &d2net_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data d2net_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+/*
+ * i2c addr | chip | description
+ * 0x32 | Ricoh 5C372b | RTC
+ * 0x3e | GMT G762 | PWM fan controller
+ * 0x50 | HT24LC08 | eeprom (1kB)
+ *
+ * TODO: Add G762 support to the g760a driver.
+ */
+static struct i2c_board_info __initdata d2net_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372b", 0x32),
+ }, {
+ I2C_BOARD_INFO("24c08", 0x50),
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data d2net_sata_data = {
+ .n_ports = 2,
+};
+
+#define D2NET_GPIO_SATA0_POWER 3
+#define D2NET_GPIO_SATA1_POWER 12
+
+static void __init d2net_sata_power_init(void)
+{
+ int err;
+
+ err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power");
+ if (err == 0) {
+ err = gpio_direction_output(D2NET_GPIO_SATA0_POWER, 1);
+ if (err)
+ gpio_free(D2NET_GPIO_SATA0_POWER);
+ }
+ if (err)
+ pr_err("d2net: failed to configure SATA0 power GPIO\n");
+
+ err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power");
+ if (err == 0) {
+ err = gpio_direction_output(D2NET_GPIO_SATA1_POWER, 1);
+ if (err)
+ gpio_free(D2NET_GPIO_SATA1_POWER);
+ }
+ if (err)
+ pr_err("d2net: failed to configure SATA1 power GPIO\n");
+}
+
+/*****************************************************************************
+ * GPIO LED's
+ ****************************************************************************/
+
+/*
+ * The blue front LED is wired to the CPLD and can blink in relation with the
+ * SATA activity.
+ *
+ * The following array detail the different LED registers and the combination
+ * of their possible values:
+ *
+ * led_off | blink_ctrl | SATA active | LED state
+ * | | |
+ * 1 | x | x | off
+ * 0 | 0 | 0 | off
+ * 0 | 1 | 0 | blink (rate 300ms)
+ * 0 | x | 1 | on
+ *
+ * Notes: The blue and the red front LED's can't be on at the same time.
+ * Red LED have priority.
+ */
+
+#define D2NET_GPIO_RED_LED 6
+#define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16
+#define D2NET_GPIO_BLUE_LED_OFF 23
+
+static struct gpio_led d2net_leds[] = {
+ {
+ .name = "d2net:blue:sata",
+ .default_trigger = "default-on",
+ .gpio = D2NET_GPIO_BLUE_LED_OFF,
+ .active_low = 1,
+ },
+ {
+ .name = "d2net:red:fail",
+ .gpio = D2NET_GPIO_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data d2net_led_data = {
+ .num_leds = ARRAY_SIZE(d2net_leds),
+ .leds = d2net_leds,
+};
+
+static struct platform_device d2net_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_led_data,
+ },
+};
+
+static void __init d2net_gpio_leds_init(void)
+{
+ int err;
+
+ /* Configure GPIO over MPP max number. */
+ orion_gpio_set_valid(D2NET_GPIO_BLUE_LED_OFF, 1);
+
+ /* Configure register blink_ctrl to allow SATA activity LED blinking. */
+ err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink");
+ if (err == 0) {
+ err = gpio_direction_output(D2NET_GPIO_BLUE_LED_BLINK_CTRL, 1);
+ if (err)
+ gpio_free(D2NET_GPIO_BLUE_LED_BLINK_CTRL);
+ }
+ if (err)
+ pr_err("d2net: failed to configure blue LED blink GPIO\n");
+
+ platform_device_register(&d2net_gpio_leds);
+}
+
+/****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define D2NET_GPIO_PUSH_BUTTON 18
+#define D2NET_GPIO_POWER_SWITCH_ON 8
+#define D2NET_GPIO_POWER_SWITCH_OFF 9
+
+#define D2NET_SWITCH_POWER_ON 0x1
+#define D2NET_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button d2net_buttons[] = {
+ {
+ .type = EV_SW,
+ .code = D2NET_SWITCH_POWER_OFF,
+ .gpio = D2NET_GPIO_POWER_SWITCH_OFF,
+ .desc = "Power rocker switch (auto|off)",
+ .active_low = 0,
+ },
+ {
+ .type = EV_SW,
+ .code = D2NET_SWITCH_POWER_ON,
+ .gpio = D2NET_GPIO_POWER_SWITCH_ON,
+ .desc = "Power rocker switch (on|auto)",
+ .active_low = 0,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_POWER,
+ .gpio = D2NET_GPIO_PUSH_BUTTON,
+ .desc = "Front Push Button",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data d2net_button_data = {
+ .buttons = d2net_buttons,
+ .nbuttons = ARRAY_SIZE(d2net_buttons),
+};
+
+static struct platform_device d2net_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &d2net_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int d2net_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Board ID (bit 0) */
+ MPP1_GPIO, /* Board ID (bit 1) */
+ MPP2_GPIO, /* Board ID (bit 2) */
+ MPP3_GPIO, /* SATA 0 power */
+ MPP4_UNUSED,
+ MPP5_GPIO, /* Fan fail detection */
+ MPP6_GPIO, /* Red front LED */
+ MPP7_UNUSED,
+ MPP8_GPIO, /* Rear power switch (on|auto) */
+ MPP9_GPIO, /* Rear power switch (auto|off) */
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_GPIO, /* SATA 1 power */
+ MPP13_UNUSED,
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_GPIO, /* Blue front LED blink control */
+ MPP17_UNUSED,
+ MPP18_GPIO, /* Front button (0 = Released, 1 = Pushed ) */
+ MPP19_UNUSED,
+ 0,
+ /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
+ /* 23: Blue front LED off */
+ /* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
+};
+
+#define D2NET_GPIO_INHIBIT_POWER_OFF 24
+
+static void __init d2net_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(d2net_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&d2net_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+
+ d2net_sata_power_init();
+ orion5x_sata_init(&d2net_sata_data);
+
+ orion5x_setup_dev_boot_win(D2NET_NOR_BOOT_BASE,
+ D2NET_NOR_BOOT_SIZE);
+ platform_device_register(&d2net_nor_flash);
+
+ platform_device_register(&d2net_gpio_buttons);
+
+ d2net_gpio_leds_init();
+
+ pr_notice("d2net: Flash write are not yet supported.\n");
+
+ i2c_register_board_info(0, d2net_i2c_devices,
+ ARRAY_SIZE(d2net_i2c_devices));
+
+ orion_gpio_set_valid(D2NET_GPIO_INHIBIT_POWER_OFF, 1);
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+
+#ifdef CONFIG_MACH_D2NET
+MACHINE_START(D2NET, "LaCie d2 Network")
+ .boot_params = 0x00000100,
+ .init_machine = d2net_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BIGDISK
+MACHINE_START(BIGDISK, "LaCie Big Disk Network")
+ .boot_params = 0x00000100,
+ .init_machine = d2net_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
new file mode 100644
index 00000000..f95d3cb0
--- /dev/null
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -0,0 +1,367 @@
+/*
+ * arch/arm/mach-orion5x/db88f5281-setup.c
+ *
+ * Marvell Orion-2 Development Board Setup
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/timer.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include <plat/orion_nand.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * DB-88F5281 on board devices
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define DB88F5281_NOR_BOOT_BASE 0xf4000000
+#define DB88F5281_NOR_BOOT_SIZE SZ_512K
+
+/*
+ * 7-Segment on Device bus chip select 0
+ */
+
+#define DB88F5281_7SEG_BASE 0xfa000000
+#define DB88F5281_7SEG_SIZE SZ_1K
+
+/*
+ * 32M NOR flash on Device bus chip select 1
+ */
+
+#define DB88F5281_NOR_BASE 0xfc000000
+#define DB88F5281_NOR_SIZE SZ_32M
+
+/*
+ * 32M NAND flash on Device bus chip select 2
+ */
+
+#define DB88F5281_NAND_BASE 0xfa800000
+#define DB88F5281_NAND_SIZE SZ_1K
+
+/*
+ * PCI
+ */
+
+#define DB88F5281_PCI_SLOT0_OFFS 7
+#define DB88F5281_PCI_SLOT0_IRQ_PIN 12
+#define DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN 13
+
+/*****************************************************************************
+ * 512M NOR Flash on Device bus Boot CS
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_boot_flash_data = {
+ .width = 1, /* 8 bit bus width */
+};
+
+static struct resource db88f5281_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = DB88F5281_NOR_BOOT_BASE,
+ .end = DB88F5281_NOR_BOOT_BASE + DB88F5281_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device db88f5281_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &db88f5281_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &db88f5281_boot_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data db88f5281_nor_flash_data = {
+ .width = 4, /* 32 bit bus width */
+};
+
+static struct resource db88f5281_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = DB88F5281_NOR_BASE,
+ .end = DB88F5281_NOR_BASE + DB88F5281_NOR_SIZE - 1,
+};
+
+static struct platform_device db88f5281_nor_flash = {
+ .name = "physmap-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &db88f5281_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &db88f5281_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * 32M NAND Flash on Device bus CS2
+ ****************************************************************************/
+
+static struct mtd_partition db88f5281_nand_parts[] = {
+ {
+ .name = "kernel",
+ .offset = 0,
+ .size = SZ_2M,
+ }, {
+ .name = "root",
+ .offset = SZ_2M,
+ .size = (SZ_16M - SZ_2M),
+ }, {
+ .name = "user",
+ .offset = SZ_16M,
+ .size = SZ_8M,
+ }, {
+ .name = "recovery",
+ .offset = (SZ_16M + SZ_8M),
+ .size = SZ_8M,
+ },
+};
+
+static struct resource db88f5281_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = DB88F5281_NAND_BASE,
+ .end = DB88F5281_NAND_BASE + DB88F5281_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data db88f5281_nand_data = {
+ .parts = db88f5281_nand_parts,
+ .nr_parts = ARRAY_SIZE(db88f5281_nand_parts),
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+};
+
+static struct platform_device db88f5281_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &db88f5281_nand_data,
+ },
+ .resource = &db88f5281_nand_resource,
+ .num_resources = 1,
+};
+
+/*****************************************************************************
+ * 7-Segment on Device bus CS0
+ * Dummy counter every 2 sec
+ ****************************************************************************/
+
+static void __iomem *db88f5281_7seg;
+static struct timer_list db88f5281_timer;
+
+static void db88f5281_7seg_event(unsigned long data)
+{
+ static int count = 0;
+ writel(0, db88f5281_7seg + (count << 4));
+ count = (count + 1) & 7;
+ mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+}
+
+static int __init db88f5281_7seg_init(void)
+{
+ if (machine_is_db88f5281()) {
+ db88f5281_7seg = ioremap(DB88F5281_7SEG_BASE,
+ DB88F5281_7SEG_SIZE);
+ if (!db88f5281_7seg) {
+ printk(KERN_ERR "Failed to ioremap db88f5281_7seg\n");
+ return -EIO;
+ }
+ setup_timer(&db88f5281_timer, db88f5281_7seg_event, 0);
+ mod_timer(&db88f5281_timer, jiffies + 2 * HZ);
+ }
+
+ return 0;
+}
+
+__initcall(db88f5281_7seg_init);
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init db88f5281_pci_preinit(void)
+{
+ int pin;
+
+ /*
+ * Configure PCI GPIO IRQ pins
+ */
+ pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int1") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "db88f5281_pci_preinit faield to "
+ "set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+ }
+
+ pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int2") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "db88f5281_pci_preinit faield "
+ "to set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "db88f5281_pci_preinit failed to gpio_request %d\n", pin);
+ }
+}
+
+static int __init db88f5281_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI IRQs are connected via GPIOs.
+ */
+ switch (slot - DB88F5281_PCI_SLOT0_OFFS) {
+ case 0:
+ return gpio_to_irq(DB88F5281_PCI_SLOT0_IRQ_PIN);
+ case 1:
+ case 2:
+ return gpio_to_irq(DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN);
+ default:
+ return -1;
+ }
+}
+
+static struct hw_pci db88f5281_pci __initdata = {
+ .nr_controllers = 2,
+ .preinit = db88f5281_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = db88f5281_pci_map_irq,
+};
+
+static int __init db88f5281_pci_init(void)
+{
+ if (machine_is_db88f5281())
+ pci_common_init(&db88f5281_pci);
+
+ return 0;
+}
+
+subsys_initcall(db88f5281_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data db88f5281_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * RTC DS1339 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
+ I2C_BOARD_INFO("ds1339", 0x68),
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int db88f5281_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* USB Over Current */
+ MPP1_GPIO, /* USB Vbat input */
+ MPP2_PCI_ARB, /* PCI_REQn[2] */
+ MPP3_PCI_ARB, /* PCI_GNTn[2] */
+ MPP4_PCI_ARB, /* PCI_REQn[3] */
+ MPP5_PCI_ARB, /* PCI_GNTn[3] */
+ MPP6_GPIO, /* JP0, CON17.2 */
+ MPP7_GPIO, /* JP1, CON17.1 */
+ MPP8_GPIO, /* JP2, CON11.2 */
+ MPP9_GPIO, /* JP3, CON11.3 */
+ MPP10_GPIO, /* RTC int */
+ MPP11_GPIO, /* Baud Rate Generator */
+ MPP12_GPIO, /* PCI int 1 */
+ MPP13_GPIO, /* PCI int 2 */
+ MPP14_NAND, /* NAND_REn[2] */
+ MPP15_NAND, /* NAND_WEn[2] */
+ MPP16_UART, /* UART1_RX */
+ MPP17_UART, /* UART1_TX */
+ MPP18_UART, /* UART1_CTSn */
+ MPP19_UART, /* UART1_RTSn */
+ 0,
+};
+
+static void __init db88f5281_init(void)
+{
+ /*
+ * Basic Orion setup. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(db88f5281_mpp_modes);
+ writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&db88f5281_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
+ orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE,
+ DB88F5281_NOR_BOOT_SIZE);
+ platform_device_register(&db88f5281_boot_flash);
+
+ orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE);
+
+ orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
+ platform_device_register(&db88f5281_nor_flash);
+
+ orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
+ platform_device_register(&db88f5281_nand_flash);
+
+ i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
+}
+
+MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
+ /* Maintainer: Tzachi Perelstein <tzachi@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = db88f5281_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
new file mode 100644
index 00000000..855e0e77
--- /dev/null
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -0,0 +1,740 @@
+/*
+ * arch/arm/mach-orion5x/dns323-setup.c
+ *
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ *
+ * Support for HW Rev C1:
+ *
+ * Copyright (C) 2010 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/phy.h>
+#include <linux/marvell_phy.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/* Rev A1 and B1 */
+#define DNS323_GPIO_LED_RIGHT_AMBER 1
+#define DNS323_GPIO_LED_LEFT_AMBER 2
+#define DNS323_GPIO_SYSTEM_UP 3
+#define DNS323_GPIO_LED_POWER1 4
+#define DNS323_GPIO_LED_POWER2 5
+#define DNS323_GPIO_OVERTEMP 6
+#define DNS323_GPIO_RTC 7
+#define DNS323_GPIO_POWER_OFF 8
+#define DNS323_GPIO_KEY_POWER 9
+#define DNS323_GPIO_KEY_RESET 10
+
+/* Rev C1 */
+#define DNS323C_GPIO_KEY_POWER 1
+#define DNS323C_GPIO_POWER_OFF 2
+#define DNS323C_GPIO_LED_RIGHT_AMBER 8
+#define DNS323C_GPIO_LED_LEFT_AMBER 9
+#define DNS323C_GPIO_LED_POWER 17
+#define DNS323C_GPIO_FAN_BIT1 18
+#define DNS323C_GPIO_FAN_BIT0 19
+
+/* Exposed to userspace, do not change */
+enum {
+ DNS323_REV_A1, /* 0 */
+ DNS323_REV_B1, /* 1 */
+ DNS323_REV_C1, /* 2 */
+};
+
+
+/****************************************************************************
+ * PCI setup
+ */
+
+static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ return -1;
+}
+
+static struct hw_pci dns323_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = dns323_pci_map_irq,
+};
+
+static int __init dns323_pci_init(void)
+{
+ /* Rev B1 and C1 doesn't really use its PCI bus, and initialising PCI
+ * gets in the way of initialising the SATA controller.
+ */
+ if (machine_is_dns323() && system_rev == DNS323_REV_A1)
+ pci_common_init(&dns323_pci);
+
+ return 0;
+}
+
+subsys_initcall(dns323_pci_init);
+
+/****************************************************************************
+ * 8MiB NOR flash (Spansion S29GL064M90TFIR4)
+ *
+ * Layout as used by D-Link:
+ * 0x00000000-0x00010000 : "MTD1"
+ * 0x00010000-0x00020000 : "MTD2"
+ * 0x00020000-0x001a0000 : "Linux Kernel"
+ * 0x001a0000-0x007d0000 : "File System"
+ * 0x007d0000-0x00800000 : "u-boot"
+ */
+
+#define DNS323_NOR_BOOT_BASE 0xf4000000
+#define DNS323_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition dns323_partitions[] = {
+ {
+ .name = "MTD1",
+ .size = 0x00010000,
+ .offset = 0,
+ }, {
+ .name = "MTD2",
+ .size = 0x00010000,
+ .offset = 0x00010000,
+ }, {
+ .name = "Linux Kernel",
+ .size = 0x00180000,
+ .offset = 0x00020000,
+ }, {
+ .name = "File System",
+ .size = 0x00630000,
+ .offset = 0x001A0000,
+ }, {
+ .name = "u-boot",
+ .size = 0x00030000,
+ .offset = 0x007d0000,
+ },
+};
+
+static struct physmap_flash_data dns323_nor_flash_data = {
+ .width = 1,
+ .parts = dns323_partitions,
+ .nr_parts = ARRAY_SIZE(dns323_partitions)
+};
+
+static struct resource dns323_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = DNS323_NOR_BOOT_BASE,
+ .end = DNS323_NOR_BOOT_BASE + DNS323_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device dns323_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &dns323_nor_flash_data,
+ },
+ .resource = &dns323_nor_flash_resource,
+ .num_resources = 1,
+};
+
+/****************************************************************************
+ * Ethernet
+ */
+
+static struct mv643xx_eth_platform_data dns323_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these
+ * functions be kept somewhere?
+ */
+static int __init dns323_parse_hex_nibble(char n)
+{
+ if (n >= '0' && n <= '9')
+ return n - '0';
+
+ if (n >= 'A' && n <= 'F')
+ return n - 'A' + 10;
+
+ if (n >= 'a' && n <= 'f')
+ return n - 'a' + 10;
+
+ return -1;
+}
+
+static int __init dns323_parse_hex_byte(const char *b)
+{
+ int hi;
+ int lo;
+
+ hi = dns323_parse_hex_nibble(b[0]);
+ lo = dns323_parse_hex_nibble(b[1]);
+
+ if (hi < 0 || lo < 0)
+ return -1;
+
+ return (hi << 4) | lo;
+}
+
+static int __init dns323_read_mac_addr(void)
+{
+ u_int8_t addr[6];
+ int i;
+ char *mac_page;
+
+ /* MAC address is stored as a regular ol' string in /dev/mtdblock4
+ * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80).
+ */
+ mac_page = ioremap(DNS323_NOR_BOOT_BASE + 0x7d0000 + 196480, 1024);
+ if (!mac_page)
+ return -ENOMEM;
+
+ /* Sanity check the string we're looking at */
+ for (i = 0; i < 5; i++) {
+ if (*(mac_page + (i * 3) + 2) != ':') {
+ goto error_fail;
+ }
+ }
+
+ for (i = 0; i < 6; i++) {
+ int byte;
+
+ byte = dns323_parse_hex_byte(mac_page + (i * 3));
+ if (byte < 0) {
+ goto error_fail;
+ }
+
+ addr[i] = byte;
+ }
+
+ iounmap(mac_page);
+ printk("DNS-323: Found ethernet MAC address: ");
+ for (i = 0; i < 6; i++)
+ printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
+
+ memcpy(dns323_eth_data.mac_addr, addr, 6);
+
+ return 0;
+
+error_fail:
+ iounmap(mac_page);
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * GPIO LEDs (simple - doesn't use hardware blinking support)
+ */
+
+#define ORION_BLINK_HALF_PERIOD 100 /* ms */
+
+static int dns323_gpio_blink_set(unsigned gpio, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+
+ if (delay_on && delay_off && !*delay_on && !*delay_off)
+ *delay_on = *delay_off = ORION_BLINK_HALF_PERIOD;
+
+ switch(state) {
+ case GPIO_LED_NO_BLINK_LOW:
+ case GPIO_LED_NO_BLINK_HIGH:
+ orion_gpio_set_blink(gpio, 0);
+ gpio_set_value(gpio, state);
+ break;
+ case GPIO_LED_BLINK:
+ orion_gpio_set_blink(gpio, 1);
+ }
+ return 0;
+}
+
+static struct gpio_led dns323ab_leds[] = {
+ {
+ .name = "power:blue",
+ .gpio = DNS323_GPIO_LED_POWER2,
+ .default_trigger = "default-on",
+ }, {
+ .name = "right:amber",
+ .gpio = DNS323_GPIO_LED_RIGHT_AMBER,
+ .active_low = 1,
+ }, {
+ .name = "left:amber",
+ .gpio = DNS323_GPIO_LED_LEFT_AMBER,
+ .active_low = 1,
+ },
+};
+
+
+static struct gpio_led dns323c_leds[] = {
+ {
+ .name = "power:blue",
+ .gpio = DNS323C_GPIO_LED_POWER,
+ .default_trigger = "timer",
+ .active_low = 1,
+ }, {
+ .name = "right:amber",
+ .gpio = DNS323C_GPIO_LED_RIGHT_AMBER,
+ .active_low = 1,
+ }, {
+ .name = "left:amber",
+ .gpio = DNS323C_GPIO_LED_LEFT_AMBER,
+ .active_low = 1,
+ },
+};
+
+
+static struct gpio_led_platform_data dns323ab_led_data = {
+ .num_leds = ARRAY_SIZE(dns323ab_leds),
+ .leds = dns323ab_leds,
+ .gpio_blink_set = dns323_gpio_blink_set,
+};
+
+static struct gpio_led_platform_data dns323c_led_data = {
+ .num_leds = ARRAY_SIZE(dns323c_leds),
+ .leds = dns323c_leds,
+ .gpio_blink_set = dns323_gpio_blink_set,
+};
+
+static struct platform_device dns323_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &dns323ab_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ */
+
+static struct gpio_keys_button dns323ab_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = DNS323_GPIO_KEY_RESET,
+ .desc = "Reset Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_POWER,
+ .gpio = DNS323_GPIO_KEY_POWER,
+ .desc = "Power Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data dns323ab_button_data = {
+ .buttons = dns323ab_buttons,
+ .nbuttons = ARRAY_SIZE(dns323ab_buttons),
+};
+
+static struct gpio_keys_button dns323c_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = DNS323C_GPIO_KEY_POWER,
+ .desc = "Power Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data dns323c_button_data = {
+ .buttons = dns323c_buttons,
+ .nbuttons = ARRAY_SIZE(dns323c_buttons),
+};
+
+static struct platform_device dns323_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &dns323ab_button_data,
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ */
+static struct mv_sata_platform_data dns323_sata_data = {
+ .n_ports = 2,
+};
+
+/****************************************************************************
+ * General Setup
+ */
+static unsigned int dns323a_mpp_modes[] __initdata = {
+ MPP0_PCIE_RST_OUTn,
+ MPP1_GPIO, /* right amber LED (sata ch0) */
+ MPP2_GPIO, /* left amber LED (sata ch1) */
+ MPP3_UNUSED,
+ MPP4_GPIO, /* power button LED */
+ MPP5_GPIO, /* power button LED */
+ MPP6_GPIO, /* GMT G751-2f overtemp */
+ MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */
+ MPP8_GPIO, /* triggers power off */
+ MPP9_GPIO, /* power button switch */
+ MPP10_GPIO, /* reset button switch */
+ MPP11_UNUSED,
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_UNUSED,
+ MPP15_UNUSED,
+ MPP16_UNUSED,
+ MPP17_UNUSED,
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static unsigned int dns323b_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_GPIO, /* right amber LED (sata ch0) */
+ MPP2_GPIO, /* left amber LED (sata ch1) */
+ MPP3_GPIO, /* system up flag */
+ MPP4_GPIO, /* power button LED */
+ MPP5_GPIO, /* power button LED */
+ MPP6_GPIO, /* GMT G751-2f overtemp */
+ MPP7_GPIO, /* M41T80 nIRQ/OUT/SQW */
+ MPP8_GPIO, /* triggers power off */
+ MPP9_GPIO, /* power button switch */
+ MPP10_GPIO, /* reset button switch */
+ MPP11_UNUSED,
+ MPP12_SATA_LED,
+ MPP13_SATA_LED,
+ MPP14_SATA_LED,
+ MPP15_SATA_LED,
+ MPP16_UNUSED,
+ MPP17_UNUSED,
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static unsigned int dns323c_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* ? input */
+ MPP1_GPIO, /* input power switch (0 = pressed) */
+ MPP2_GPIO, /* output power off */
+ MPP3_UNUSED, /* ? output */
+ MPP4_UNUSED, /* ? output */
+ MPP5_UNUSED, /* ? output */
+ MPP6_UNUSED, /* ? output */
+ MPP7_UNUSED, /* ? output */
+ MPP8_GPIO, /* i/o right amber LED */
+ MPP9_GPIO, /* i/o left amber LED */
+ MPP10_GPIO, /* input */
+ MPP11_UNUSED,
+ MPP12_SATA_LED,
+ MPP13_SATA_LED,
+ MPP14_SATA_LED,
+ MPP15_SATA_LED,
+ MPP16_UNUSED,
+ MPP17_GPIO, /* power button LED */
+ MPP18_GPIO, /* fan speed bit 0 */
+ MPP19_GPIO, /* fan speed bit 1 */
+ 0,
+};
+
+/* Rev C1 Fan speed notes:
+ *
+ * The fan is controlled by 2 GPIOs on this board. The settings
+ * of the bits is as follow:
+ *
+ * GPIO 18 GPIO 19 Fan
+ *
+ * 0 0 stopped
+ * 0 1 low speed
+ * 1 0 high speed
+ * 1 1 don't do that (*)
+ *
+ * (*) I think the two bits control two feed-in resistors into a fixed
+ * PWN circuit, setting both bits will basically go a 'bit' faster
+ * than high speed, but d-link doesn't do it and you may get out of
+ * HW spec so don't do it.
+ */
+
+/*
+ * On the DNS-323 A1 and B1 the following devices are attached via I2C:
+ *
+ * i2c addr | chip | description
+ * 0x3e | GMT G760Af | fan speed PWM controller
+ * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
+ * 0x68 | ST M41T80 | RTC w/ alarm
+ */
+static struct i2c_board_info __initdata dns323ab_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("g760a", 0x3e),
+ }, {
+ I2C_BOARD_INFO("lm75", 0x48),
+ }, {
+ I2C_BOARD_INFO("m41t80", 0x68),
+ },
+};
+
+/*
+ * On the DNS-323 C1 the following devices are attached via I2C:
+ *
+ * i2c addr | chip | description
+ * 0x48 | GMT G751-2f | temp. sensor and therm. watchdog (LM75 compatible)
+ * 0x68 | ST M41T80 | RTC w/ alarm
+ */
+static struct i2c_board_info __initdata dns323c_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("lm75", 0x48),
+ }, {
+ I2C_BOARD_INFO("m41t80", 0x68),
+ },
+};
+
+/* DNS-323 rev. A specific power off method */
+static void dns323a_power_off(void)
+{
+ pr_info("DNS-323: Triggering power-off...\n");
+ gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+}
+
+/* DNS-323 rev B specific power off method */
+static void dns323b_power_off(void)
+{
+ pr_info("DNS-323: Triggering power-off...\n");
+ /* Pin has to be changed to 1 and back to 0 to do actual power off. */
+ gpio_set_value(DNS323_GPIO_POWER_OFF, 1);
+ mdelay(100);
+ gpio_set_value(DNS323_GPIO_POWER_OFF, 0);
+}
+
+/* DNS-323 rev. C specific power off method */
+static void dns323c_power_off(void)
+{
+ pr_info("DNS-323: Triggering power-off...\n");
+ gpio_set_value(DNS323C_GPIO_POWER_OFF, 1);
+}
+
+static int dns323c_phy_fixup(struct phy_device *phy)
+{
+ phy->dev_flags |= MARVELL_PHY_M1118_DNS323_LEDS;
+
+ return 0;
+}
+
+static int __init dns323_identify_rev(void)
+{
+ u32 dev, rev, i, reg;
+
+ pr_debug("DNS-323: Identifying board ... \n");
+
+ /* Rev A1 has a 5181 */
+ orion5x_pcie_id(&dev, &rev);
+ if (dev == MV88F5181_DEV_ID) {
+ pr_debug("DNS-323: 5181 found, board is A1\n");
+ return DNS323_REV_A1;
+ }
+ pr_debug("DNS-323: 5182 found, board is B1 or C1, checking PHY...\n");
+
+ /* Rev B1 and C1 both have 5182, let's poke at the eth PHY. This is
+ * a bit gross but we want to do that without links into the eth
+ * driver so let's poke at it directly. We default to rev B1 in
+ * case the accesses fail
+ */
+
+#define ETH_SMI_REG (ORION5X_ETH_VIRT_BASE + 0x2000 + 0x004)
+#define SMI_BUSY 0x10000000
+#define SMI_READ_VALID 0x08000000
+#define SMI_OPCODE_READ 0x04000000
+#define SMI_OPCODE_WRITE 0x00000000
+
+ for (i = 0; i < 1000; i++) {
+ reg = readl(ETH_SMI_REG);
+ if (!(reg & SMI_BUSY))
+ break;
+ }
+ if (i >= 1000) {
+ pr_warning("DNS-323: Timeout accessing PHY, assuming rev B1\n");
+ return DNS323_REV_B1;
+ }
+ writel((3 << 21) /* phy ID reg */ |
+ (8 << 16) /* phy addr */ |
+ SMI_OPCODE_READ, ETH_SMI_REG);
+ for (i = 0; i < 1000; i++) {
+ reg = readl(ETH_SMI_REG);
+ if (reg & SMI_READ_VALID)
+ break;
+ }
+ if (i >= 1000) {
+ pr_warning("DNS-323: Timeout reading PHY, assuming rev B1\n");
+ return DNS323_REV_B1;
+ }
+ pr_debug("DNS-323: Ethernet PHY ID 0x%x\n", reg & 0xffff);
+
+ /* Note: the Marvell tools mask the ID with 0x3f0 before comparison
+ * but I don't see that making a difference here, at least with
+ * any known Marvell PHY ID
+ */
+ switch(reg & 0xfff0) {
+ case 0x0cc0: /* MV88E1111 */
+ return DNS323_REV_B1;
+ case 0x0e10: /* MV88E1118 */
+ return DNS323_REV_C1;
+ default:
+ pr_warning("DNS-323: Unknown PHY ID 0x%04x, assuming rev B1\n",
+ reg & 0xffff);
+ }
+ return DNS323_REV_B1;
+}
+
+static void __init dns323_init(void)
+{
+ /* Setup basic Orion functions. Need to be called early. */
+ orion5x_init();
+
+ /* Identify revision */
+ system_rev = dns323_identify_rev();
+ pr_info("DNS-323: Identified HW revision %c1\n", 'A' + system_rev);
+
+ /* Just to be tricky, the 5182 has a completely different
+ * set of MPP modes to the 5181.
+ */
+ switch(system_rev) {
+ case DNS323_REV_A1:
+ orion5x_mpp_conf(dns323a_mpp_modes);
+ writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
+ break;
+ case DNS323_REV_B1:
+ orion5x_mpp_conf(dns323b_mpp_modes);
+ break;
+ case DNS323_REV_C1:
+ orion5x_mpp_conf(dns323c_mpp_modes);
+ break;
+ }
+
+ /* setup flash mapping
+ * CS3 holds a 8 MB Spansion S29GL064M90TFIR4
+ */
+ orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
+ platform_device_register(&dns323_nor_flash);
+
+ /* Sort out LEDs, Buttons and i2c devices */
+ switch(system_rev) {
+ case DNS323_REV_A1:
+ /* The 5181 power LED is active low and requires
+ * DNS323_GPIO_LED_POWER1 to also be low.
+ */
+ dns323ab_leds[0].active_low = 1;
+ gpio_request(DNS323_GPIO_LED_POWER1, "Power Led Enable");
+ gpio_direction_output(DNS323_GPIO_LED_POWER1, 0);
+ /* Fall through */
+ case DNS323_REV_B1:
+ i2c_register_board_info(0, dns323ab_i2c_devices,
+ ARRAY_SIZE(dns323ab_i2c_devices));
+ break;
+ case DNS323_REV_C1:
+ /* Hookup LEDs & Buttons */
+ dns323_gpio_leds.dev.platform_data = &dns323c_led_data;
+ dns323_button_device.dev.platform_data = &dns323c_button_data;
+
+ /* Hookup i2c devices and fan driver */
+ i2c_register_board_info(0, dns323c_i2c_devices,
+ ARRAY_SIZE(dns323c_i2c_devices));
+ platform_device_register_simple("dns323c-fan", 0, NULL, 0);
+
+ /* Register fixup for the PHY LEDs */
+ phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1118,
+ MARVELL_PHY_ID_MASK,
+ dns323c_phy_fixup);
+ }
+
+ platform_device_register(&dns323_gpio_leds);
+ platform_device_register(&dns323_button_device);
+
+ /*
+ * Configure peripherals.
+ */
+ if (dns323_read_mac_addr() < 0)
+ printk("DNS-323: Failed to read MAC address\n");
+ orion5x_ehci0_init();
+ orion5x_eth_init(&dns323_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+
+ /* Remaining GPIOs */
+ switch(system_rev) {
+ case DNS323_REV_A1:
+ /* Poweroff GPIO */
+ if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
+ pr_err("DNS-323: failed to setup power-off GPIO\n");
+ pm_power_off = dns323a_power_off;
+ break;
+ case DNS323_REV_B1:
+ /* 5182 built-in SATA init */
+ orion5x_sata_init(&dns323_sata_data);
+
+ /* The DNS323 rev B1 has flag to indicate the system is up.
+ * Without this flag set, power LED will flash and cannot be
+ * controlled via leds-gpio.
+ */
+ if (gpio_request(DNS323_GPIO_SYSTEM_UP, "SYS_READY") == 0)
+ gpio_direction_output(DNS323_GPIO_SYSTEM_UP, 1);
+
+ /* Poweroff GPIO */
+ if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
+ pr_err("DNS-323: failed to setup power-off GPIO\n");
+ pm_power_off = dns323b_power_off;
+ break;
+ case DNS323_REV_C1:
+ /* 5182 built-in SATA init */
+ orion5x_sata_init(&dns323_sata_data);
+
+ /* Poweroff GPIO */
+ if (gpio_request(DNS323C_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(DNS323C_GPIO_POWER_OFF, 0) != 0)
+ pr_err("DNS-323: failed to setup power-off GPIO\n");
+ pm_power_off = dns323c_power_off;
+
+ /* Now, -this- should theorically be done by the sata_mv driver
+ * once I figure out what's going on there. Maybe the behaviour
+ * of the LEDs should be somewhat passed via the platform_data.
+ * for now, just whack the register and make the LEDs happy
+ *
+ * Note: AFAIK, rev B1 needs the same treatement but I'll let
+ * somebody else test it.
+ */
+ writel(0x5, ORION5X_SATA_VIRT_BASE | 0x2c);
+ break;
+ }
+}
+
+/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
+MACHINE_START(DNS323, "D-Link DNS-323")
+ /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
+ .boot_params = 0x00000100,
+ .init_machine = dns323_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c
new file mode 100644
index 00000000..b67cff0d
--- /dev/null
+++ b/arch/arm/mach-orion5x/edmini_v2-setup.c
@@ -0,0 +1,261 @@
+/*
+ * arch/arm/mach-orion5x/edmini_v2-setup.c
+ *
+ * LaCie Ethernet Disk mini V2 Setup
+ *
+ * Copyright (C) 2008 Christopher Moore <moore@free.fr>
+ * Copyright (C) 2008 Albert Aribaud <albert.aribaud@free.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * TODO: add Orion USB device port init when kernel.org support is added.
+ * TODO: add flash write support: see below.
+ * TODO: add power-off support.
+ * TODO: add I2C EEPROM support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * EDMINI_V2 Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define EDMINI_V2_NOR_BOOT_BASE 0xfff80000
+#define EDMINI_V2_NOR_BOOT_SIZE SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+/*
+ * Currently the MTD code does not recognize the MX29LV400CBCT as a bottom
+ * -type device. This could cause risks of accidentally erasing critical
+ * flash sectors. We thus define a single, write-protected partition covering
+ * the whole flash.
+ * TODO: once the flash part TOP/BOTTOM detection issue is sorted out in the MTD
+ * code, break this into at least three partitions: 'u-boot code', 'u-boot
+ * environment' and 'whatever is left'.
+ */
+
+static struct mtd_partition edmini_v2_partitions[] = {
+ {
+ .name = "Full512kb",
+ .size = 0x00080000,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data edmini_v2_nor_flash_data = {
+ .width = 1,
+ .parts = edmini_v2_partitions,
+ .nr_parts = ARRAY_SIZE(edmini_v2_partitions),
+};
+
+static struct resource edmini_v2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = EDMINI_V2_NOR_BOOT_BASE,
+ .end = EDMINI_V2_NOR_BOOT_BASE
+ + EDMINI_V2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device edmini_v2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &edmini_v2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &edmini_v2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data edmini_v2_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define EDMINIV2_RTC_GPIO 3
+
+static struct i2c_board_info __initdata edmini_v2_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+ .irq = 0,
+};
+
+/*****************************************************************************
+ * Sata
+ ****************************************************************************/
+
+static struct mv_sata_platform_data edmini_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO LED (simple - doesn't use hardware blinking support)
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_LED_POWER 16
+
+static struct gpio_led edmini_v2_leds[] = {
+ {
+ .name = "power:blue",
+ .gpio = EDMINI_V2_GPIO_LED_POWER,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data edmini_v2_led_data = {
+ .num_leds = ARRAY_SIZE(edmini_v2_leds),
+ .leds = edmini_v2_leds,
+};
+
+static struct platform_device edmini_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &edmini_v2_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO key
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_KEY_POWER 18
+
+static struct gpio_keys_button edmini_v2_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = EDMINI_V2_GPIO_KEY_POWER,
+ .desc = "Power Button",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data edmini_v2_button_data = {
+ .buttons = edmini_v2_buttons,
+ .nbuttons = ARRAY_SIZE(edmini_v2_buttons),
+};
+
+static struct platform_device edmini_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &edmini_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int edminiv2_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_UNUSED,
+ MPP2_UNUSED,
+ MPP3_GPIO, /* RTC interrupt */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_UNUSED,
+ MPP7_UNUSED,
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_SATA_LED, /* SATA 0 presence */
+ MPP13_SATA_LED, /* SATA 1 presence */
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ /* 16: Power LED control (0 = On, 1 = Off) */
+ MPP16_GPIO,
+ /* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */
+ MPP17_GPIO,
+ /* 18: Power button status (0 = Released, 1 = Pressed) */
+ MPP18_GPIO,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init edmini_v2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(edminiv2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&edmini_v2_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&edmini_v2_sata_data);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
+ EDMINI_V2_NOR_BOOT_SIZE);
+ platform_device_register(&edmini_v2_nor_flash);
+ platform_device_register(&edmini_v2_gpio_leds);
+ platform_device_register(&edmini_v2_gpio_buttons);
+
+ pr_notice("edmini_v2: USB device port, flash write and power-off "
+ "are not yet supported.\n");
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(EDMINIV2_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(EDMINIV2_RTC_GPIO) == 0)
+ edmini_v2_i2c_rtc.irq = gpio_to_irq(EDMINIV2_RTC_GPIO);
+ else
+ gpio_free(EDMINIV2_RTC_GPIO);
+ }
+
+ if (edmini_v2_i2c_rtc.irq == 0)
+ pr_warning("edmini_v2: failed to get RTC IRQ\n");
+
+ i2c_register_board_info(0, &edmini_v2_i2c_rtc, 1);
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")
+ /* Maintainer: Christopher Moore <moore@free.fr> */
+ .boot_params = 0x00000100,
+ .init_machine = edmini_v2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/include/mach/bridge-regs.h b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
new file mode 100644
index 00000000..96484bcd
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/bridge-regs.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/bridge-regs.h
+ *
+ * Orion CPU Bridge Registers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_BRIDGE_REGS_H
+#define __ASM_ARCH_BRIDGE_REGS_H
+
+#include <mach/orion5x.h>
+
+#define CPU_CONF (ORION5X_BRIDGE_VIRT_BASE | 0x100)
+
+#define CPU_CTRL (ORION5X_BRIDGE_VIRT_BASE | 0x104)
+
+#define RSTOUTn_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x108)
+#define WDT_RESET_OUT_EN 0x0002
+
+#define CPU_SOFT_RESET (ORION5X_BRIDGE_VIRT_BASE | 0x10c)
+
+#define BRIDGE_CAUSE (ORION5X_BRIDGE_VIRT_BASE | 0x110)
+
+#define POWER_MNG_CTRL_REG (ORION5X_BRIDGE_VIRT_BASE | 0x11C)
+
+#define WDT_INT_REQ 0x0008
+
+#define BRIDGE_INT_TIMER1_CLR (~0x0004)
+
+#define MAIN_IRQ_CAUSE (ORION5X_BRIDGE_VIRT_BASE | 0x200)
+
+#define MAIN_IRQ_MASK (ORION5X_BRIDGE_VIRT_BASE | 0x204)
+
+#define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300)
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/debug-macro.S b/arch/arm/mach-orion5x/include/mach/debug-macro.S
new file mode 100644
index 00000000..5e3bf5b6
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/debug-macro.S
+ *
+ * Debugging macro include 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.
+*/
+
+#include <mach/orion5x.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =ORION5X_REGS_PHYS_BASE
+ ldr \rv, =ORION5X_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-orion5x/include/mach/entry-macro.S b/arch/arm/mach-orion5x/include/mach/entry-macro.S
new file mode 100644
index 00000000..d658992e
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/entry-macro.S
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Orion platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/bridge-regs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =MAIN_IRQ_CAUSE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #0] @ main cause
+ ldr \tmp, [\base, #(MAIN_IRQ_MASK - MAIN_IRQ_CAUSE)] @ main mask
+ mov \irqnr, #0 @ default irqnr
+ @ find cause bits that are unmasked
+ ands \irqstat, \irqstat, \tmp @ clear Z flag if any
+ clzne \irqnr, \irqstat @ calc irqnr
+ rsbne \irqnr, \irqnr, #31
+ .endm
diff --git a/arch/arm/mach-orion5x/include/mach/gpio.h b/arch/arm/mach-orion5x/include/mach/gpio.h
new file mode 100644
index 00000000..a1d0b78d
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/gpio.h
@@ -0,0 +1,9 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/gpio.h>
diff --git a/arch/arm/mach-orion5x/include/mach/hardware.h b/arch/arm/mach-orion5x/include/mach/hardware.h
new file mode 100644
index 00000000..e51aaf4b
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/hardware.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "orion5x.h"
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE ORION5X_PCIE_MEM_PHYS_BASE
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h
new file mode 100644
index 00000000..c5196101
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/io.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/io.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "orion5x.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *
+__arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype)
+{
+ void __iomem *retval;
+ unsigned long offs = paddr - ORION5X_REGS_PHYS_BASE;
+ if (mtype == MT_DEVICE && size && offs < ORION5X_REGS_SIZE &&
+ size <= ORION5X_REGS_SIZE && offs + size <= ORION5X_REGS_SIZE) {
+ retval = (void __iomem *)ORION5X_REGS_VIRT_BASE + offs;
+ } else {
+ retval = __arm_ioremap(paddr, size, mtype);
+ }
+
+ return retval;
+}
+
+static inline void
+__arch_iounmap(void __iomem *addr)
+{
+ if (addr < (void __iomem *)ORION5X_REGS_VIRT_BASE ||
+ addr >= (void __iomem *)(ORION5X_REGS_VIRT_BASE + ORION5X_REGS_SIZE))
+ __iounmap(addr);
+}
+
+#define __arch_ioremap __arch_ioremap
+#define __arch_iounmap __arch_iounmap
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+
+/*****************************************************************************
+ * Helpers to access Orion registers
+ ****************************************************************************/
+/*
+ * These are not preempt-safe. Locks, if needed, must be taken
+ * care of by the caller.
+ */
+#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r))
+#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r))
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/irqs.h b/arch/arm/mach-orion5x/include/mach/irqs.h
new file mode 100644
index 00000000..a6fa9d8f
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/irqs.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/irqs.h
+ *
+ * IRQ definitions for Orion SoC
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * Orion Main Interrupt Controller
+ */
+#define IRQ_ORION5X_BRIDGE 0
+#define IRQ_ORION5X_DOORBELL_H2C 1
+#define IRQ_ORION5X_DOORBELL_C2H 2
+#define IRQ_ORION5X_UART0 3
+#define IRQ_ORION5X_UART1 4
+#define IRQ_ORION5X_I2C 5
+#define IRQ_ORION5X_GPIO_0_7 6
+#define IRQ_ORION5X_GPIO_8_15 7
+#define IRQ_ORION5X_GPIO_16_23 8
+#define IRQ_ORION5X_GPIO_24_31 9
+#define IRQ_ORION5X_PCIE0_ERR 10
+#define IRQ_ORION5X_PCIE0_INT 11
+#define IRQ_ORION5X_USB1_CTRL 12
+#define IRQ_ORION5X_DEV_BUS_ERR 14
+#define IRQ_ORION5X_PCI_ERR 15
+#define IRQ_ORION5X_USB_BR_ERR 16
+#define IRQ_ORION5X_USB0_CTRL 17
+#define IRQ_ORION5X_ETH_RX 18
+#define IRQ_ORION5X_ETH_TX 19
+#define IRQ_ORION5X_ETH_MISC 20
+#define IRQ_ORION5X_ETH_SUM 21
+#define IRQ_ORION5X_ETH_ERR 22
+#define IRQ_ORION5X_IDMA_ERR 23
+#define IRQ_ORION5X_IDMA_0 24
+#define IRQ_ORION5X_IDMA_1 25
+#define IRQ_ORION5X_IDMA_2 26
+#define IRQ_ORION5X_IDMA_3 27
+#define IRQ_ORION5X_CESA 28
+#define IRQ_ORION5X_SATA 29
+#define IRQ_ORION5X_XOR0 30
+#define IRQ_ORION5X_XOR1 31
+
+/*
+ * Orion General Purpose Pins
+ */
+#define IRQ_ORION5X_GPIO_START 32
+#define NR_GPIO_IRQS 32
+
+#define NR_IRQS (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/memory.h b/arch/arm/mach-orion5x/include/mach/memory.h
new file mode 100644
index 00000000..67699178
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/memory.h
@@ -0,0 +1,12 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/memory.h
+ *
+ * Marvell Orion memory definitions
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
new file mode 100644
index 00000000..0a28bbc7
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -0,0 +1,143 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/orion5x.h
+ *
+ * Generic definitions of Orion SoC flavors:
+ * Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_ORION5X_H
+#define __ASM_ARCH_ORION5X_H
+
+/*****************************************************************************
+ * Orion Address Maps
+ *
+ * phys
+ * e0000000 PCIe MEM space
+ * e8000000 PCI MEM space
+ * f0000000 PCIe WA space (Orion-1/Orion-NAS only)
+ * f1000000 on-chip peripheral registers
+ * f2000000 PCIe I/O space
+ * f2100000 PCI I/O space
+ * f2200000 SRAM dedicated for the crypto unit
+ * f4000000 device bus mappings (boot)
+ * fa000000 device bus mappings (cs0)
+ * fa800000 device bus mappings (cs2)
+ * fc000000 device bus mappings (cs0/cs1)
+ *
+ * virt phys size
+ * fdd00000 f1000000 1M on-chip peripheral registers
+ * fde00000 f2000000 1M PCIe I/O space
+ * fdf00000 f2100000 1M PCI I/O space
+ * fe000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
+ ****************************************************************************/
+#define ORION5X_REGS_PHYS_BASE 0xf1000000
+#define ORION5X_REGS_VIRT_BASE 0xfdd00000
+#define ORION5X_REGS_SIZE SZ_1M
+
+#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
+#define ORION5X_PCIE_IO_VIRT_BASE 0xfde00000
+#define ORION5X_PCIE_IO_BUS_BASE 0x00000000
+#define ORION5X_PCIE_IO_SIZE SZ_1M
+
+#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
+#define ORION5X_PCI_IO_VIRT_BASE 0xfdf00000
+#define ORION5X_PCI_IO_BUS_BASE 0x00100000
+#define ORION5X_PCI_IO_SIZE SZ_1M
+
+#define ORION5X_SRAM_PHYS_BASE (0xf2200000)
+#define ORION5X_SRAM_SIZE SZ_8K
+
+/* Relevant only for Orion-1/Orion-NAS */
+#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
+#define ORION5X_PCIE_WA_VIRT_BASE 0xfe000000
+#define ORION5X_PCIE_WA_SIZE SZ_16M
+
+#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000
+#define ORION5X_PCIE_MEM_SIZE SZ_128M
+
+#define ORION5X_PCI_MEM_PHYS_BASE 0xe8000000
+#define ORION5X_PCI_MEM_SIZE SZ_128M
+
+/*******************************************************************************
+ * Orion Registers Map
+ ******************************************************************************/
+
+#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000)
+
+#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
+#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
+#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
+#define GPIO_VIRT_BASE ORION5X_DEV_BUS_REG(0x0100)
+#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x0600)
+#define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
+#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
+#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
+#define UART1_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2100)
+#define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100)
+
+#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000)
+
+#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000)
+
+#define ORION5X_PCIE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x40000)
+
+#define ORION5X_USB0_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x50000)
+#define ORION5X_USB0_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x50000)
+
+#define ORION5X_XOR_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x60900)
+#define ORION5X_XOR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x60900)
+
+#define ORION5X_ETH_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x70000)
+#define ORION5X_ETH_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x70000)
+
+#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x80000)
+#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x80000)
+
+#define ORION5X_CRYPTO_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x90000)
+
+#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0xa0000)
+#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0xa0000)
+
+/*******************************************************************************
+ * Device Bus Registers
+ ******************************************************************************/
+#define MPP_0_7_CTRL ORION5X_DEV_BUS_REG(0x000)
+#define MPP_8_15_CTRL ORION5X_DEV_BUS_REG(0x004)
+#define MPP_16_19_CTRL ORION5X_DEV_BUS_REG(0x050)
+#define MPP_DEV_CTRL ORION5X_DEV_BUS_REG(0x008)
+#define MPP_RESET_SAMPLE ORION5X_DEV_BUS_REG(0x010)
+#define DEV_BANK_0_PARAM ORION5X_DEV_BUS_REG(0x45c)
+#define DEV_BANK_1_PARAM ORION5X_DEV_BUS_REG(0x460)
+#define DEV_BANK_2_PARAM ORION5X_DEV_BUS_REG(0x464)
+#define DEV_BANK_BOOT_PARAM ORION5X_DEV_BUS_REG(0x46c)
+#define DEV_BUS_CTRL ORION5X_DEV_BUS_REG(0x4c0)
+#define DEV_BUS_INT_CAUSE ORION5X_DEV_BUS_REG(0x4d0)
+#define DEV_BUS_INT_MASK ORION5X_DEV_BUS_REG(0x4d4)
+
+/*******************************************************************************
+ * Supported Devices & Revisions
+ ******************************************************************************/
+/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
+#define MV88F5181_DEV_ID 0x5181
+#define MV88F5181_REV_B1 3
+#define MV88F5181L_REV_A0 8
+#define MV88F5181L_REV_A1 9
+/* Orion-NAS (88F5182) */
+#define MV88F5182_DEV_ID 0x5182
+#define MV88F5182_REV_A2 2
+/* Orion-2 (88F5281) */
+#define MV88F5281_DEV_ID 0x5281
+#define MV88F5281_REV_D0 4
+#define MV88F5281_REV_D1 5
+#define MV88F5281_REV_D2 6
+/* Orion-1-90 (88F6183) */
+#define MV88F6183_DEV_ID 0x6183
+#define MV88F6183_REV_B0 3
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
new file mode 100644
index 00000000..a1d6e46a
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/system.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/system.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/bridge-regs.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * Enable and issue soft reset
+ */
+ orion5x_setbits(RSTOUTn_MASK, (1 << 2));
+ orion5x_setbits(CPU_SOFT_RESET, 1);
+ mdelay(200);
+ orion5x_clrbits(CPU_SOFT_RESET, 1);
+}
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/timex.h b/arch/arm/mach-orion5x/include/mach/timex.h
new file mode 100644
index 00000000..4c69820e
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/timex.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/timex.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-orion5x/include/mach/uncompress.h b/arch/arm/mach-orion5x/include/mach/uncompress.h
new file mode 100644
index 00000000..4322dba4
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/uncompress.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/uncompress.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/orion5x.h>
+
+#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-orion5x/include/mach/vmalloc.h b/arch/arm/mach-orion5x/include/mach/vmalloc.h
new file mode 100644
index 00000000..06b50aef
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfd800000UL
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
new file mode 100644
index 00000000..43cf8bc9
--- /dev/null
+++ b/arch/arm/mach-orion5x/irq.c
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-orion5x/irq.c
+ *
+ * Core IRQ functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+#include <mach/bridge-regs.h>
+#include <plat/irq.h>
+#include "common.h"
+
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);
+
+ orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3);
+}
+
+void __init orion5x_init_irq(void)
+{
+ orion_irq_init(0, (void __iomem *)MAIN_IRQ_MASK);
+
+ /*
+ * Initialize gpiolib for GPIOs 0-31.
+ */
+ orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler);
+}
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
new file mode 100644
index 00000000..c0eb6462
--- /dev/null
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -0,0 +1,403 @@
+/*
+ * arch/arm/mach-orion5x/kurobox_pro-setup.c
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include <plat/orion_nand.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * KUROBOX-PRO Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define KUROBOX_PRO_NOR_BOOT_BASE 0xf4000000
+#define KUROBOX_PRO_NOR_BOOT_SIZE SZ_256K
+
+/*
+ * 256M NAND flash on Device bus chip select 1
+ */
+
+#define KUROBOX_PRO_NAND_BASE 0xfc000000
+#define KUROBOX_PRO_NAND_SIZE SZ_2M
+
+/*****************************************************************************
+ * 256MB NAND Flash on Device bus CS0
+ ****************************************************************************/
+
+static struct mtd_partition kurobox_pro_nand_parts[] = {
+ {
+ .name = "uImage",
+ .offset = 0,
+ .size = SZ_4M,
+ }, {
+ .name = "rootfs",
+ .offset = SZ_4M,
+ .size = SZ_64M,
+ }, {
+ .name = "extra",
+ .offset = SZ_4M + SZ_64M,
+ .size = SZ_256M - (SZ_4M + SZ_64M),
+ },
+};
+
+static struct resource kurobox_pro_nand_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KUROBOX_PRO_NAND_BASE,
+ .end = KUROBOX_PRO_NAND_BASE + KUROBOX_PRO_NAND_SIZE - 1,
+};
+
+static struct orion_nand_data kurobox_pro_nand_data = {
+ .parts = kurobox_pro_nand_parts,
+ .nr_parts = ARRAY_SIZE(kurobox_pro_nand_parts),
+ .cle = 0,
+ .ale = 1,
+ .width = 8,
+};
+
+static struct platform_device kurobox_pro_nand_flash = {
+ .name = "orion_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &kurobox_pro_nand_data,
+ },
+ .resource = &kurobox_pro_nand_resource,
+ .num_resources = 1,
+};
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data kurobox_pro_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource kurobox_pro_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = KUROBOX_PRO_NOR_BOOT_BASE,
+ .end = KUROBOX_PRO_NOR_BOOT_BASE + KUROBOX_PRO_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device kurobox_pro_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &kurobox_pro_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &kurobox_pro_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI isn't used on the Kuro
+ */
+ return -1;
+}
+
+static struct hw_pci kurobox_pro_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = kurobox_pro_pci_map_irq,
+};
+
+static int __init kurobox_pro_pci_init(void)
+{
+ if (machine_is_kurobox_pro()) {
+ orion5x_pci_disable();
+ pci_common_init(&kurobox_pro_pci);
+ }
+
+ return 0;
+}
+
+subsys_initcall(kurobox_pro_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data kurobox_pro_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * Kurobox Pro specific power off method via UART1-attached microcontroller
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+static int kurobox_pro_miconread(unsigned char *buf, int count)
+{
+ int i;
+ int timeout;
+
+ for (i = 0; i < count; i++) {
+ timeout = 10;
+
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
+ if (--timeout == 0)
+ break;
+ udelay(1000);
+ }
+
+ if (timeout == 0)
+ break;
+ buf[i] = readl(UART1_REG(RX));
+ }
+
+ /* return read bytes */
+ return i;
+}
+
+static int kurobox_pro_miconwrite(const unsigned char *buf, int count)
+{
+ int i = 0;
+
+ while (count--) {
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
+ barrier();
+ writel(buf[i++], UART1_REG(TX));
+ }
+
+ return 0;
+}
+
+static int kurobox_pro_miconsend(const unsigned char *data, int count)
+{
+ int i;
+ unsigned char checksum = 0;
+ unsigned char recv_buf[40];
+ unsigned char send_buf[40];
+ unsigned char correct_ack[3];
+ int retry = 2;
+
+ /* Generate checksum */
+ for (i = 0; i < count; i++)
+ checksum -= data[i];
+
+ do {
+ /* Send data */
+ kurobox_pro_miconwrite(data, count);
+
+ /* send checksum */
+ kurobox_pro_miconwrite(&checksum, 1);
+
+ if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
+ printk(KERN_ERR ">%s: receive failed.\n", __func__);
+
+ /* send preamble to clear the receive buffer */
+ memset(&send_buf, 0xff, sizeof(send_buf));
+ kurobox_pro_miconwrite(send_buf, sizeof(send_buf));
+
+ /* make dummy reads */
+ mdelay(100);
+ kurobox_pro_miconread(recv_buf, sizeof(recv_buf));
+ } else {
+ /* Generate expected ack */
+ correct_ack[0] = 0x01;
+ correct_ack[1] = data[1];
+ correct_ack[2] = 0x00;
+
+ /* checksum Check */
+ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+ recv_buf[3]) & 0xFF) {
+ printk(KERN_ERR ">%s: Checksum Error : "
+ "Received data[%02x, %02x, %02x, %02x]"
+ "\n", __func__, recv_buf[0],
+ recv_buf[1], recv_buf[2], recv_buf[3]);
+ } else {
+ /* Check Received Data */
+ if (correct_ack[0] == recv_buf[0] &&
+ correct_ack[1] == recv_buf[1] &&
+ correct_ack[2] == recv_buf[2]) {
+ /* Interval for next command */
+ mdelay(10);
+
+ /* Receive ACK */
+ return 0;
+ }
+ }
+ /* Received NAK or illegal Data */
+ printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
+ "Received\n", __func__);
+ }
+ } while (retry--);
+
+ /* Interval for next command */
+ mdelay(10);
+
+ return -1;
+}
+
+static void kurobox_pro_power_off(void)
+{
+ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
+ const unsigned char shutdownwait[] = {0x00, 0x0c};
+ const unsigned char poweroff[] = {0x00, 0x06};
+ /* 38400 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x1b, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x07, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* Send the commands to shutdown the Kurobox Pro */
+ kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;
+ kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;
+ kurobox_pro_miconsend(poweroff, sizeof(poweroff));
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int kurobox_pro_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_UNUSED,
+ MPP2_GPIO, /* GPIO Micon */
+ MPP3_GPIO, /* GPIO Rtc */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_NAND, /* NAND Flash REn */
+ MPP7_NAND, /* NAND Flash WEn */
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_SATA_LED, /* SATA 0 presence */
+ MPP13_SATA_LED, /* SATA 1 presence */
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_UART, /* UART1 RXD */
+ MPP17_UART, /* UART1 TXD */
+ MPP18_UART, /* UART1 CTSn */
+ MPP19_UART, /* UART1 RTSn */
+ 0,
+};
+
+static void __init kurobox_pro_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(kurobox_pro_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&kurobox_pro_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&kurobox_pro_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
+ KUROBOX_PRO_NOR_BOOT_SIZE);
+ platform_device_register(&kurobox_pro_nor_flash);
+
+ if (machine_is_kurobox_pro()) {
+ orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,
+ KUROBOX_PRO_NAND_SIZE);
+ platform_device_register(&kurobox_pro_nand_flash);
+ }
+
+ i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
+
+ /* register Kurobox Pro specific power-off method */
+ pm_power_off = kurobox_pro_power_off;
+}
+
+#ifdef CONFIG_MACH_KUROBOX_PRO
+MACHINE_START(KUROBOX_PRO, "Buffalo/Revogear Kurobox Pro")
+ /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = kurobox_pro_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_LINKSTATION_PRO
+MACHINE_START(LINKSTATION_PRO, "Buffalo Linkstation Pro/Live")
+ /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
+ .boot_params = 0x00000100,
+ .init_machine = kurobox_pro_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-orion5x/ls-chl-setup.c b/arch/arm/mach-orion5x/ls-chl-setup.c
new file mode 100644
index 00000000..5065803c
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls-chl-setup.c
@@ -0,0 +1,328 @@
+/*
+ * arch/arm/mach-orion5x/ls-chl-setup.c
+ *
+ * Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio-fan.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Linkstation LS-CHL Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LSCHL_NOR_BOOT_BASE 0xf4000000
+#define LSCHL_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data lschl_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource lschl_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LSCHL_NOR_BOOT_BASE,
+ .end = LSCHL_NOR_BOOT_BASE + LSCHL_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lschl_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lschl_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &lschl_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data lschl_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata lschl_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LSCHL_GPIO_LED_ALARM 2
+#define LSCHL_GPIO_LED_INFO 3
+#define LSCHL_GPIO_LED_FUNC 17
+#define LSCHL_GPIO_LED_PWR 0
+
+static struct gpio_led lschl_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LSCHL_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LSCHL_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LSCHL_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LSCHL_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data lschl_led_data = {
+ .leds = lschl_led_pins,
+ .num_leds = ARRAY_SIZE(lschl_led_pins),
+};
+
+static struct platform_device lschl_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &lschl_led_data,
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data lschl_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * LS-CHL specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the LS-CHL, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ * to move the switch to ON position
+ *
+ */
+
+static void lschl_power_off(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+#define LSCHL_GPIO_USB_POWER 9
+#define LSCHL_GPIO_AUTO_POWER 17
+#define LSCHL_GPIO_POWER 18
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+#define LSCHL_GPIO_KEY_FUNC 15
+#define LSCHL_GPIO_KEY_POWER 8
+#define LSCHL_GPIO_KEY_AUTOPOWER 10
+#define LSCHL_SW_POWER 0x00
+#define LSCHL_SW_AUTOPOWER 0x01
+#define LSCHL_SW_FUNC 0x02
+
+static struct gpio_keys_button lschl_buttons[] = {
+ {
+ .type = EV_SW,
+ .code = LSCHL_SW_POWER,
+ .gpio = LSCHL_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSCHL_SW_AUTOPOWER,
+ .gpio = LSCHL_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSCHL_SW_FUNC,
+ .gpio = LSCHL_GPIO_KEY_FUNC,
+ .desc = "Function Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data lschl_button_data = {
+ .buttons = lschl_buttons,
+ .nbuttons = ARRAY_SIZE(lschl_buttons),
+};
+
+static struct platform_device lschl_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lschl_button_data,
+ },
+};
+
+#define LSCHL_GPIO_HDD_POWER 1
+
+/****************************************************************************
+ * GPIO Fan
+ ****************************************************************************/
+
+#define LSCHL_GPIO_FAN_LOW 16
+#define LSCHL_GPIO_FAN_HIGH 14
+#define LSCHL_GPIO_FAN_LOCK 6
+
+static struct gpio_fan_alarm lschl_alarm = {
+ .gpio = LSCHL_GPIO_FAN_LOCK,
+};
+
+static struct gpio_fan_speed lschl_speeds[] = {
+ {
+ .rpm = 0,
+ .ctrl_val = 3,
+ }, {
+ .rpm = 1500,
+ .ctrl_val = 2,
+ }, {
+ .rpm = 3250,
+ .ctrl_val = 1,
+ }, {
+ .rpm = 5000,
+ .ctrl_val = 0,
+ },
+};
+
+static int lschl_gpio_list[] = {
+ LSCHL_GPIO_FAN_HIGH, LSCHL_GPIO_FAN_LOW,
+};
+
+static struct gpio_fan_platform_data lschl_fan_data = {
+ .num_ctrl = ARRAY_SIZE(lschl_gpio_list),
+ .ctrl = lschl_gpio_list,
+ .alarm = &lschl_alarm,
+ .num_speed = ARRAY_SIZE(lschl_speeds),
+ .speed = lschl_speeds,
+};
+
+static struct platform_device lschl_fan_device = {
+ .name = "gpio-fan",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lschl_fan_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Data
+ ****************************************************************************/
+
+static unsigned int lschl_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* LED POWER */
+ MPP1_GPIO, /* HDD POWER */
+ MPP2_GPIO, /* LED ALARM */
+ MPP3_GPIO, /* LED INFO */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_GPIO, /* FAN LOCK */
+ MPP7_GPIO, /* SW INIT */
+ MPP8_GPIO, /* SW POWER */
+ MPP9_GPIO, /* USB POWER */
+ MPP10_GPIO, /* SW AUTO POWER */
+ MPP11_UNUSED,
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_GPIO, /* FAN HIGH */
+ MPP15_GPIO, /* SW FUNC */
+ MPP16_GPIO, /* FAN LOW */
+ MPP17_GPIO, /* LED FUNC */
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init lschl_init(void)
+{
+ /*
+ * Setup basic Orion functions. Needs to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(lschl_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&lschl_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&lschl_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LSCHL_NOR_BOOT_BASE,
+ LSCHL_NOR_BOOT_SIZE);
+ platform_device_register(&lschl_nor_flash);
+
+ platform_device_register(&lschl_leds);
+
+ platform_device_register(&lschl_button_device);
+
+ platform_device_register(&lschl_fan_device);
+
+ i2c_register_board_info(0, &lschl_i2c_rtc, 1);
+
+ /* usb power on */
+ gpio_set_value(LSCHL_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = lschl_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+MACHINE_START(LINKSTATION_LSCHL, "Buffalo Linkstation LiveV3 (LS-CHL)")
+ /* Maintainer: Ash Hughes <ashley.hughes@blueyonder.co.uk> */
+ .boot_params = 0x00000100,
+ .init_machine = lschl_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ls_hgl-setup.c b/arch/arm/mach-orion5x/ls_hgl-setup.c
new file mode 100644
index 00000000..8503d0a4
--- /dev/null
+++ b/arch/arm/mach-orion5x/ls_hgl-setup.c
@@ -0,0 +1,275 @@
+/*
+ * arch/arm/mach-orion5x/ls_hgl-setup.c
+ *
+ * Maintainer: Zhu Qingsen <zhuqs@cn.fujitsu.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Linkstation LS-HGL Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LS_HGL_NOR_BOOT_BASE 0xf4000000
+#define LS_HGL_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data ls_hgl_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource ls_hgl_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LS_HGL_NOR_BOOT_BASE,
+ .end = LS_HGL_NOR_BOOT_BASE + LS_HGL_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device ls_hgl_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ls_hgl_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ls_hgl_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data ls_hgl_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata ls_hgl_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_LED_ALARM 2
+#define LS_HGL_GPIO_LED_INFO 3
+#define LS_HGL_GPIO_LED_FUNC 17
+#define LS_HGL_GPIO_LED_PWR 0
+
+
+static struct gpio_led ls_hgl_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LS_HGL_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LS_HGL_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LS_HGL_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LS_HGL_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data ls_hgl_led_data = {
+ .leds = ls_hgl_led_pins,
+ .num_leds = ARRAY_SIZE(ls_hgl_led_pins),
+};
+
+static struct platform_device ls_hgl_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ls_hgl_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+#define LS_HGL_GPIO_KEY_FUNC 15
+#define LS_HGL_GPIO_KEY_POWER 8
+#define LS_HGL_GPIO_KEY_AUTOPOWER 10
+
+#define LS_HGL_SW_POWER 0x00
+#define LS_HGL_SW_AUTOPOWER 0x01
+
+static struct gpio_keys_button ls_hgl_buttons[] = {
+ {
+ .code = KEY_OPTION,
+ .gpio = LS_HGL_GPIO_KEY_FUNC,
+ .desc = "Function Button",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LS_HGL_SW_POWER,
+ .gpio = LS_HGL_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LS_HGL_SW_AUTOPOWER,
+ .gpio = LS_HGL_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data ls_hgl_button_data = {
+ .buttons = ls_hgl_buttons,
+ .nbuttons = ARRAY_SIZE(ls_hgl_buttons),
+};
+
+static struct platform_device ls_hgl_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ls_hgl_button_data,
+ },
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data ls_hgl_sata_data = {
+ .n_ports = 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation LS-HGL specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation LS-HGL, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ * to move the switch to ON position
+ */
+
+static void ls_hgl_power_off(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LS_HGL_GPIO_USB_POWER 9
+#define LS_HGL_GPIO_AUTO_POWER 10
+#define LS_HGL_GPIO_POWER 8
+
+#define LS_HGL_GPIO_HDD_POWER 1
+
+static unsigned int ls_hgl_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* LED_PWR */
+ MPP1_GPIO, /* HDD_PWR */
+ MPP2_GPIO, /* LED_ALARM */
+ MPP3_GPIO, /* LED_INFO */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_GPIO, /* FAN_LCK */
+ MPP7_GPIO, /* INIT */
+ MPP8_GPIO, /* POWER */
+ MPP9_GPIO, /* USB_PWR */
+ MPP10_GPIO, /* AUTO_POWER */
+ MPP11_UNUSED, /* LED_ETH (dummy) */
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_UNUSED,
+ MPP15_GPIO, /* FUNC */
+ MPP16_UNUSED,
+ MPP17_GPIO, /* LED_FUNC */
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init ls_hgl_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ls_hgl_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&ls_hgl_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&ls_hgl_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LS_HGL_NOR_BOOT_BASE,
+ LS_HGL_NOR_BOOT_SIZE);
+ platform_device_register(&ls_hgl_nor_flash);
+
+ platform_device_register(&ls_hgl_button_device);
+
+ platform_device_register(&ls_hgl_leds);
+
+ i2c_register_board_info(0, &ls_hgl_i2c_rtc, 1);
+
+ /* enable USB power */
+ gpio_set_value(LS_HGL_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = ls_hgl_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+MACHINE_START(LINKSTATION_LS_HGL, "Buffalo Linkstation LS-HGL")
+ /* Maintainer: Zhu Qingsen <zhuqs@cn.fujistu.com> */
+ .boot_params = 0x00000100,
+ .init_machine = ls_hgl_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
new file mode 100644
index 00000000..9c82723c
--- /dev/null
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -0,0 +1,278 @@
+/*
+ * arch/arm/mach-orion5x/lsmini-setup.c
+ *
+ * Maintainer: Alexey Kopytko <alexey@kopytko.ru>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/system.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Linkstation Mini Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LSMINI_NOR_BOOT_BASE 0xf4000000
+#define LSMINI_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data lsmini_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource lsmini_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LSMINI_NOR_BOOT_BASE,
+ .end = LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lsmini_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lsmini_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &lsmini_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data lsmini_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata lsmini_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LSMINI_GPIO_LED_ALARM 2
+#define LSMINI_GPIO_LED_INFO 3
+#define LSMINI_GPIO_LED_FUNC 9
+#define LSMINI_GPIO_LED_PWR 14
+
+static struct gpio_led lsmini_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LSMINI_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LSMINI_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LSMINI_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LSMINI_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data lsmini_led_data = {
+ .leds = lsmini_led_pins,
+ .num_leds = ARRAY_SIZE(lsmini_led_pins),
+};
+
+static struct platform_device lsmini_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &lsmini_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+
+#define LSMINI_GPIO_KEY_FUNC 15
+#define LSMINI_GPIO_KEY_POWER 18
+#define LSMINI_GPIO_KEY_AUTOPOWER 17
+
+#define LSMINI_SW_POWER 0x00
+#define LSMINI_SW_AUTOPOWER 0x01
+
+static struct gpio_keys_button lsmini_buttons[] = {
+ {
+ .code = KEY_OPTION,
+ .gpio = LSMINI_GPIO_KEY_FUNC,
+ .desc = "Function Button",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSMINI_SW_POWER,
+ .gpio = LSMINI_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSMINI_SW_AUTOPOWER,
+ .gpio = LSMINI_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data lsmini_button_data = {
+ .buttons = lsmini_buttons,
+ .nbuttons = ARRAY_SIZE(lsmini_buttons),
+};
+
+static struct platform_device lsmini_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lsmini_button_data,
+ },
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data lsmini_sata_data = {
+ .n_ports = 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation Mini specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation Mini, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ * to move the switch to ON position
+ */
+
+static void lsmini_power_off(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LSMINI_GPIO_USB_POWER 16
+#define LSMINI_GPIO_AUTO_POWER 17
+#define LSMINI_GPIO_POWER 18
+
+#define LSMINI_GPIO_HDD_POWER0 1
+#define LSMINI_GPIO_HDD_POWER1 19
+
+static unsigned int lsmini_mpp_modes[] __initdata = {
+ MPP0_UNUSED, /* LED_RESERVE1 (unused) */
+ MPP1_GPIO, /* HDD_PWR */
+ MPP2_GPIO, /* LED_ALARM */
+ MPP3_GPIO, /* LED_INFO */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_UNUSED,
+ MPP7_UNUSED,
+ MPP8_UNUSED,
+ MPP9_GPIO, /* LED_FUNC */
+ MPP10_UNUSED,
+ MPP11_UNUSED, /* LED_ETH (dummy) */
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_GPIO, /* LED_PWR */
+ MPP15_GPIO, /* FUNC */
+ MPP16_GPIO, /* USB_PWR */
+ MPP17_GPIO, /* AUTO_POWER */
+ MPP18_GPIO, /* POWER */
+ MPP19_GPIO, /* HDD_PWR1 */
+ 0,
+};
+
+static void __init lsmini_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(lsmini_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&lsmini_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&lsmini_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
+ LSMINI_NOR_BOOT_SIZE);
+ platform_device_register(&lsmini_nor_flash);
+
+ platform_device_register(&lsmini_button_device);
+
+ platform_device_register(&lsmini_leds);
+
+ i2c_register_board_info(0, &lsmini_i2c_rtc, 1);
+
+ /* enable USB power */
+ gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = lsmini_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+#ifdef CONFIG_MACH_LINKSTATION_MINI
+MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
+ /* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */
+ .boot_params = 0x00000100,
+ .init_machine = lsmini_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
new file mode 100644
index 00000000..f12c41b9
--- /dev/null
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-orion5x/mpp.c
+ *
+ * MPP functions for Marvell Orion 5x SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <plat/mpp.h>
+#include "mpp.h"
+#include "common.h"
+
+static unsigned int __init orion5x_variant(void)
+{
+ u32 dev;
+ u32 rev;
+
+ orion5x_pcie_id(&dev, &rev);
+
+ if (dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0)
+ return MPP_F5181_MASK;
+
+ if (dev == MV88F5182_DEV_ID)
+ return MPP_F5182_MASK;
+
+ if (dev == MV88F5281_DEV_ID)
+ return MPP_F5281_MASK;
+
+ printk(KERN_ERR "MPP setup: unknown orion5x variant "
+ "(dev %#x rev %#x)\n", dev, rev);
+ return 0;
+}
+
+void __init orion5x_mpp_conf(unsigned int *mpp_list)
+{
+ orion_mpp_conf(mpp_list, orion5x_variant(),
+ MPP_MAX, ORION5X_DEV_BUS_VIRT_BASE);
+}
diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h
new file mode 100644
index 00000000..db70e79a
--- /dev/null
+++ b/arch/arm/mach-orion5x/mpp.h
@@ -0,0 +1,129 @@
+#ifndef __ARCH_ORION5X_MPP_H
+#define __ARCH_ORION5X_MPP_H
+
+#define MPP(_num, _sel, _in, _out, _F5181l, _F5182, _F5281) ( \
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13) | \
+ /* available on F5181l */ ((!!(_F5181l)) << 14) | \
+ /* available on F5182 */ ((!!(_F5182)) << 15) | \
+ /* available on F5281 */ ((!!(_F5281)) << 16))
+
+ /* num sel i o 5181 5182 5281 */
+
+#define MPP_F5181_MASK MPP(0, 0x0, 0, 0, 1, 0, 0)
+#define MPP_F5182_MASK MPP(0, 0x0, 0, 0, 0, 1, 0)
+#define MPP_F5281_MASK MPP(0, 0x0, 0, 0, 0, 0, 1)
+
+#define MPP0_UNUSED MPP(0, 0x3, 0, 0, 1, 1, 1)
+#define MPP0_GPIO MPP(0, 0x3, 1, 1, 1, 1, 1)
+#define MPP0_PCIE_RST_OUTn MPP(0, 0x0, 0, 0, 1, 1, 1)
+#define MPP0_PCI_ARB MPP(0, 0x2, 0, 0, 1, 1, 1)
+
+#define MPP1_UNUSED MPP(1, 0x0, 0, 0, 1, 1, 1)
+#define MPP1_GPIO MPP(1, 0x0, 1, 1, 1, 1, 1)
+#define MPP1_PCI_ARB MPP(1, 0x2, 0, 0, 1, 1, 1)
+
+#define MPP2_UNUSED MPP(2, 0x0, 0, 0, 1, 1, 1)
+#define MPP2_GPIO MPP(2, 0x0, 1, 1, 1, 1, 1)
+#define MPP2_PCI_ARB MPP(2, 0x2, 0, 0, 1, 1, 1)
+#define MPP2_PCI_PMEn MPP(2, 0x3, 0, 0, 1, 1, 1)
+
+#define MPP3_UNUSED MPP(3, 0x0, 0, 0, 1, 1, 1)
+#define MPP3_GPIO MPP(3, 0x0, 1, 1, 1, 1, 1)
+#define MPP3_PCI_ARB MPP(3, 0x2, 0, 0, 1, 1, 1)
+
+#define MPP4_UNUSED MPP(4, 0x0, 0, 0, 1, 1, 1)
+#define MPP4_GPIO MPP(4, 0x0, 1, 1, 1, 1, 1)
+#define MPP4_PCI_ARB MPP(4, 0x2, 0, 0, 1, 1, 1)
+#define MPP4_NAND MPP(4, 0x4, 0, 0, 0, 1, 1)
+#define MPP4_SATA_LED MPP(4, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP5_UNUSED MPP(5, 0x0, 0, 0, 1, 1, 1)
+#define MPP5_GPIO MPP(5, 0x0, 1, 1, 1, 1, 1)
+#define MPP5_PCI_ARB MPP(5, 0x2, 0, 0, 1, 1, 1)
+#define MPP5_NAND MPP(5, 0x4, 0, 0, 0, 1, 1)
+#define MPP5_SATA_LED MPP(5, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP6_UNUSED MPP(6, 0x0, 0, 0, 1, 1, 1)
+#define MPP6_GPIO MPP(6, 0x0, 1, 1, 1, 1, 1)
+#define MPP6_PCI_ARB MPP(6, 0x2, 0, 0, 1, 1, 1)
+#define MPP6_NAND MPP(6, 0x4, 0, 0, 0, 1, 1)
+#define MPP6_PCI_CLK MPP(6, 0x5, 0, 0, 1, 0, 0)
+#define MPP6_SATA_LED MPP(6, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP7_UNUSED MPP(7, 0x0, 0, 0, 1, 1, 1)
+#define MPP7_GPIO MPP(7, 0x0, 1, 1, 1, 1, 1)
+#define MPP7_PCI_ARB MPP(7, 0x2, 0, 0, 1, 1, 1)
+#define MPP7_NAND MPP(7, 0x4, 0, 0, 0, 1, 1)
+#define MPP7_PCI_CLK MPP(7, 0x5, 0, 0, 1, 0, 0)
+#define MPP7_SATA_LED MPP(7, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP8_UNUSED MPP(8, 0x0, 0, 0, 1, 1, 1)
+#define MPP8_GPIO MPP(8, 0x0, 1, 1, 1, 1, 1)
+#define MPP8_GIGE MPP(8, 0x1, 0, 0, 1, 1, 1)
+
+#define MPP9_UNUSED MPP(9, 0x0, 0, 0, 1, 1, 1)
+#define MPP9_GPIO MPP(9, 0x0, 1, 1, 1, 1, 1)
+#define MPP9_GIGE MPP(9, 0x1, 0, 0, 1, 1, 1)
+
+#define MPP10_UNUSED MPP(10, 0x0, 0, 0, 1, 1, 1)
+#define MPP10_GPIO MPP(10, 0x0, 1, 1, 1, 1, 1)
+#define MPP10_GIGE MPP(10, 0x1, 0, 0, 1, 1, 1)
+
+#define MPP11_UNUSED MPP(11, 0x0, 0, 0, 1, 1, 1)
+#define MPP11_GPIO MPP(11, 0x0, 1, 1, 1, 1, 1)
+#define MPP11_GIGE MPP(11, 0x1, 0, 0, 1, 1, 1)
+
+#define MPP12_UNUSED MPP(12, 0x0, 0, 0, 1, 1, 1)
+#define MPP12_GPIO MPP(12, 0x0, 1, 1, 1, 1, 1)
+#define MPP12_GIGE MPP(12, 0x1, 0, 0, 1, 1, 1)
+#define MPP12_NAND MPP(12, 0x4, 0, 0, 0, 1, 1)
+#define MPP12_SATA_LED MPP(12, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP13_UNUSED MPP(13, 0x0, 0, 0, 1, 1, 1)
+#define MPP13_GPIO MPP(13, 0x0, 1, 1, 1, 1, 1)
+#define MPP13_GIGE MPP(13, 0x1, 0, 0, 1, 1, 1)
+#define MPP13_NAND MPP(13, 0x4, 0, 0, 0, 1, 1)
+#define MPP13_SATA_LED MPP(13, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP14_UNUSED MPP(14, 0x0, 0, 0, 1, 1, 1)
+#define MPP14_GPIO MPP(14, 0x0, 1, 1, 1, 1, 1)
+#define MPP14_GIGE MPP(14, 0x1, 0, 0, 1, 1, 1)
+#define MPP14_NAND MPP(14, 0x4, 0, 0, 0, 1, 1)
+#define MPP14_SATA_LED MPP(14, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP15_UNUSED MPP(15, 0x0, 0, 0, 1, 1, 1)
+#define MPP15_GPIO MPP(15, 0x0, 1, 1, 1, 1, 1)
+#define MPP15_GIGE MPP(15, 0x1, 0, 0, 1, 1, 1)
+#define MPP15_NAND MPP(15, 0x4, 0, 0, 0, 1, 1)
+#define MPP15_SATA_LED MPP(15, 0x5, 0, 0, 0, 1, 0)
+
+#define MPP16_UNUSED MPP(16, 0x0, 0, 0, 1, 1, 1)
+#define MPP16_GPIO MPP(16, 0x5, 1, 1, 0, 1, 0)
+#define MPP16_GIGE MPP(16, 0x1, 0, 0, 1, 1, 1)
+#define MPP16_NAND MPP(16, 0x4, 0, 0, 0, 1, 1)
+#define MPP16_UART MPP(16, 0x0, 0, 0, 0, 1, 1)
+
+#define MPP17_UNUSED MPP(17, 0x0, 0, 0, 1, 1, 1)
+#define MPP17_GPIO MPP(17, 0x5, 1, 1, 0, 1, 0)
+#define MPP17_GIGE MPP(17, 0x1, 0, 0, 1, 1, 1)
+#define MPP17_NAND MPP(17, 0x4, 0, 0, 0, 1, 1)
+#define MPP17_UART MPP(17, 0x0, 0, 0, 0, 1, 1)
+
+#define MPP18_UNUSED MPP(18, 0x0, 0, 0, 1, 1, 1)
+#define MPP18_GPIO MPP(18, 0x5, 1, 1, 0, 1, 0)
+#define MPP18_GIGE MPP(18, 0x1, 0, 0, 1, 1, 1)
+#define MPP18_UART MPP(18, 0x0, 0, 0, 0, 1, 1)
+
+#define MPP19_UNUSED MPP(19, 0x0, 0, 0, 1, 1, 1)
+#define MPP19_GPIO MPP(19, 0x5, 1, 1, 0, 1, 0)
+#define MPP19_GIGE MPP(19, 0x1, 0, 0, 1, 1, 1)
+#define MPP19_UART MPP(19, 0x0, 0, 0, 0, 1, 1)
+
+#define MPP_MAX 19
+
+void orion5x_mpp_conf(unsigned int *mpp_list);
+
+#endif
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c
new file mode 100644
index 00000000..59263b73
--- /dev/null
+++ b/arch/arm/mach-orion5x/mss2-setup.c
@@ -0,0 +1,271 @@
+/*
+ * Maxtor Shared Storage II Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include <mach/bridge-regs.h>
+#include "common.h"
+#include "mpp.h"
+
+#define MSS2_NOR_BOOT_BASE 0xff800000
+#define MSS2_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * Maxtor Shared Storage II Info
+ ****************************************************************************/
+
+/*
+ * Maxtor Shared Storage II hardware :
+ * - Marvell 88F5182-A2 C500
+ * - Marvell 88E1111 Gigabit Ethernet PHY
+ * - RTC M41T81 (@0x68) on I2C bus
+ * - 256KB NOR flash
+ * - 64MB of RAM
+ */
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data mss2_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource mss2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MSS2_NOR_BOOT_BASE,
+ .end = MSS2_NOR_BOOT_BASE + MSS2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device mss2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mss2_nor_flash_data,
+ },
+ .resource = &mss2_nor_flash_resource,
+ .num_resources = 1,
+};
+
+/****************************************************************************
+ * PCI setup
+ ****************************************************************************/
+static int __init mss2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ return -1;
+}
+
+static struct hw_pci mss2_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = mss2_pci_map_irq,
+};
+
+static int __init mss2_pci_init(void)
+{
+ if (machine_is_mss2())
+ pci_common_init(&mss2_pci);
+
+ return 0;
+}
+subsys_initcall(mss2_pci_init);
+
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data mss2_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data mss2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO buttons
+ ****************************************************************************/
+
+#define MSS2_GPIO_KEY_RESET 12
+#define MSS2_GPIO_KEY_POWER 11
+
+static struct gpio_keys_button mss2_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = MSS2_GPIO_KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ }, {
+ .code = KEY_RESTART,
+ .gpio = MSS2_GPIO_KEY_RESET,
+ .desc = "Reset",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mss2_button_data = {
+ .buttons = mss2_buttons,
+ .nbuttons = ARRAY_SIZE(mss2_buttons),
+};
+
+static struct platform_device mss2_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &mss2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * RTC m41t81 on I2C bus
+ ****************************************************************************/
+
+#define MSS2_GPIO_RTC_IRQ 3
+
+static struct i2c_board_info __initdata mss2_i2c_rtc = {
+ I2C_BOARD_INFO("m41t81", 0x68),
+};
+
+/*****************************************************************************
+ * MSS2 power off method
+ ****************************************************************************/
+/*
+ * On the Maxtor Shared Storage II, the shutdown process is the following :
+ * - Userland modifies U-boot env to tell U-boot to go idle at next boot
+ * - The board reboots
+ * - U-boot starts and go into an idle mode until the user press "power"
+ */
+static void mss2_power_off(void)
+{
+ u32 reg;
+
+ /*
+ * Enable and issue soft reset
+ */
+ reg = readl(RSTOUTn_MASK);
+ reg |= 1 << 2;
+ writel(reg, RSTOUTn_MASK);
+
+ reg = readl(CPU_SOFT_RESET);
+ reg |= 1;
+ writel(reg, CPU_SOFT_RESET);
+}
+
+/****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int mss2_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Power LED */
+ MPP1_GPIO, /* Error LED */
+ MPP2_UNUSED,
+ MPP3_GPIO, /* RTC interrupt */
+ MPP4_GPIO, /* HDD ind. (Single/Dual)*/
+ MPP5_GPIO, /* HD0 5V control */
+ MPP6_GPIO, /* HD0 12V control */
+ MPP7_GPIO, /* HD1 5V control */
+ MPP8_GPIO, /* HD1 12V control */
+ MPP9_UNUSED,
+ MPP10_GPIO, /* Fan control */
+ MPP11_GPIO, /* Power button */
+ MPP12_GPIO, /* Reset button */
+ MPP13_UNUSED,
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_UNUSED,
+ MPP17_UNUSED,
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init mss2_init(void)
+{
+ /* Setup basic Orion functions. Need to be called early. */
+ orion5x_init();
+
+ orion5x_mpp_conf(mss2_mpp_modes);
+
+ /*
+ * MPP[20] Unused
+ * MPP[21] PCI clock
+ * MPP[22] USB 0 over current
+ * MPP[23] USB 1 over current
+ */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&mss2_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&mss2_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE);
+ platform_device_register(&mss2_nor_flash);
+
+ platform_device_register(&mss2_button_device);
+
+ if (gpio_request(MSS2_GPIO_RTC_IRQ, "rtc") == 0) {
+ if (gpio_direction_input(MSS2_GPIO_RTC_IRQ) == 0)
+ mss2_i2c_rtc.irq = gpio_to_irq(MSS2_GPIO_RTC_IRQ);
+ else
+ gpio_free(MSS2_GPIO_RTC_IRQ);
+ }
+ i2c_register_board_info(0, &mss2_i2c_rtc, 1);
+
+ /* register mss2 specific power-off method */
+ pm_power_off = mss2_power_off;
+}
+
+MACHINE_START(MSS2, "Maxtor Shared Storage II")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
+ .boot_params = 0x00000100,
+ .init_machine = mss2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
new file mode 100644
index 00000000..63ff10c3
--- /dev/null
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+#define MV2120_NOR_BOOT_BASE 0xf4000000
+#define MV2120_NOR_BOOT_SIZE SZ_512K
+
+#define MV2120_GPIO_RTC_IRQ 3
+#define MV2120_GPIO_KEY_RESET 17
+#define MV2120_GPIO_KEY_POWER 18
+#define MV2120_GPIO_POWER_OFF 19
+
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data mv2120_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data mv2120_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mtd_partition mv2120_partitions[] = {
+ {
+ .name = "firmware",
+ .size = 0x00080000,
+ .offset = 0,
+ },
+};
+
+static struct physmap_flash_data mv2120_nor_flash_data = {
+ .width = 1,
+ .parts = mv2120_partitions,
+ .nr_parts = ARRAY_SIZE(mv2120_partitions)
+};
+
+static struct resource mv2120_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MV2120_NOR_BOOT_BASE,
+ .end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device mv2120_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mv2120_nor_flash_data,
+ },
+ .resource = &mv2120_nor_flash_resource,
+ .num_resources = 1,
+};
+
+static struct gpio_keys_button mv2120_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = MV2120_GPIO_KEY_RESET,
+ .desc = "reset",
+ .active_low = 1,
+ }, {
+ .code = KEY_POWER,
+ .gpio = MV2120_GPIO_KEY_POWER,
+ .desc = "power",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mv2120_button_data = {
+ .buttons = mv2120_buttons,
+ .nbuttons = ARRAY_SIZE(mv2120_buttons),
+};
+
+static struct platform_device mv2120_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &mv2120_button_data,
+ },
+};
+
+
+/****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int mv2120_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Sys status LED */
+ MPP1_GPIO, /* Sys error LED */
+ MPP2_GPIO, /* OverTemp interrupt */
+ MPP3_GPIO, /* RTC interrupt */
+ MPP4_GPIO, /* V_LED 5V */
+ MPP5_GPIO, /* V_LED 3.3V */
+ MPP6_UNUSED,
+ MPP7_UNUSED,
+ MPP8_GPIO, /* SATA 0 fail LED */
+ MPP9_GPIO, /* SATA 1 fail LED */
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_SATA_LED, /* SATA 0 presence */
+ MPP13_SATA_LED, /* SATA 1 presence */
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_UNUSED,
+ MPP17_GPIO, /* Reset button */
+ MPP18_GPIO, /* Power button */
+ MPP19_GPIO, /* Power off */
+ 0,
+};
+
+static struct i2c_board_info __initdata mv2120_i2c_rtc = {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ .irq = 0,
+};
+
+static struct gpio_led mv2120_led_pins[] = {
+ {
+ .name = "mv2120:blue:health",
+ .gpio = 0,
+ },
+ {
+ .name = "mv2120:red:health",
+ .gpio = 1,
+ },
+ {
+ .name = "mv2120:led:bright",
+ .gpio = 4,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "mv2120:led:dimmed",
+ .gpio = 5,
+ },
+ {
+ .name = "mv2120:red:sata0",
+ .gpio = 8,
+ .active_low = 1,
+ },
+ {
+ .name = "mv2120:red:sata1",
+ .gpio = 9,
+ .active_low = 1,
+ },
+
+};
+
+static struct gpio_led_platform_data mv2120_led_data = {
+ .leds = mv2120_led_pins,
+ .num_leds = ARRAY_SIZE(mv2120_led_pins),
+};
+
+static struct platform_device mv2120_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mv2120_led_data,
+ }
+};
+
+static void mv2120_power_off(void)
+{
+ pr_info("%s: triggering power-off...\n", __func__);
+ gpio_set_value(MV2120_GPIO_POWER_OFF, 0);
+}
+
+static void __init mv2120_init(void)
+{
+ /* Setup basic Orion functions. Need to be called early. */
+ orion5x_init();
+
+ orion5x_mpp_conf(mv2120_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&mv2120_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&mv2120_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE);
+ platform_device_register(&mv2120_nor_flash);
+
+ platform_device_register(&mv2120_button_device);
+
+ if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) {
+ if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0)
+ mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ);
+ else
+ gpio_free(MV2120_GPIO_RTC_IRQ);
+ }
+ i2c_register_board_info(0, &mv2120_i2c_rtc, 1);
+ platform_device_register(&mv2120_leds);
+
+ /* register mv2120 specific power-off method */
+ if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0)
+ pr_err("mv2120: failed to setup power-off GPIO\n");
+ pm_power_off = mv2120_power_off;
+}
+
+/* Warning: HP uses a wrong mach-type (=526) in their bootloader */
+MACHINE_START(MV2120, "HP Media Vault mv2120")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .boot_params = 0x00000100,
+ .init_machine = mv2120_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/net2big-setup.c b/arch/arm/mach-orion5x/net2big-setup.c
new file mode 100644
index 00000000..e43b39cc
--- /dev/null
+++ b/arch/arm/mach-orion5x/net2big-setup.c
@@ -0,0 +1,430 @@
+/*
+ * arch/arm/mach-orion5x/net2big-setup.c
+ *
+ * LaCie 2Big Network NAS setup
+ *
+ * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * LaCie 2Big Network Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define NET2BIG_NOR_BOOT_BASE 0xfff80000
+#define NET2BIG_NOR_BOOT_SIZE SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on Boot Device
+ ****************************************************************************/
+
+/*
+ * TODO: Check write support on flash MX29LV400CBTC-70G
+ */
+
+static struct mtd_partition net2big_partitions[] = {
+ {
+ .name = "Full512kb",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data net2big_nor_flash_data = {
+ .width = 1,
+ .parts = net2big_partitions,
+ .nr_parts = ARRAY_SIZE(net2big_partitions),
+};
+
+static struct resource net2big_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = NET2BIG_NOR_BOOT_BASE,
+ .end = NET2BIG_NOR_BOOT_BASE
+ + NET2BIG_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device net2big_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &net2big_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &net2big_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data net2big_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * I2C devices
+ ****************************************************************************/
+
+/*
+ * i2c addr | chip | description
+ * 0x32 | Ricoh 5C372b | RTC
+ * 0x50 | HT24LC08 | eeprom (1kB)
+ */
+static struct i2c_board_info __initdata net2big_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("rs5c372b", 0x32),
+ }, {
+ I2C_BOARD_INFO("24c08", 0x50),
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data net2big_sata_data = {
+ .n_ports = 2,
+};
+
+#define NET2BIG_GPIO_SATA_POWER_REQ 19
+#define NET2BIG_GPIO_SATA0_POWER 23
+#define NET2BIG_GPIO_SATA1_POWER 25
+
+static void __init net2big_sata_power_init(void)
+{
+ int err;
+
+ /* Configure GPIOs over MPP max number. */
+ orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
+ orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
+
+ err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
+ if (err == 0) {
+ err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
+ if (err)
+ gpio_free(NET2BIG_GPIO_SATA0_POWER);
+ }
+ if (err) {
+ pr_err("net2big: failed to setup SATA0 power GPIO\n");
+ return;
+ }
+
+ err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
+ if (err == 0) {
+ err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
+ if (err)
+ gpio_free(NET2BIG_GPIO_SATA1_POWER);
+ }
+ if (err) {
+ pr_err("net2big: failed to setup SATA1 power GPIO\n");
+ goto err_free_1;
+ }
+
+ err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
+ if (err == 0) {
+ err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
+ if (err)
+ gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
+ }
+ if (err) {
+ pr_err("net2big: failed to setup SATA power request GPIO\n");
+ goto err_free_2;
+ }
+
+ if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
+ gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
+ return;
+ }
+
+ /*
+ * SATA power up on both disk is done by pulling high the CPLD power
+ * request line. The 300ms delay is related to the CPLD clock and is
+ * needed to be sure that the CPLD has take into account the low line
+ * status.
+ */
+ msleep(300);
+ gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
+ pr_info("net2big: power up SATA hard disks\n");
+
+ return;
+
+err_free_2:
+ gpio_free(NET2BIG_GPIO_SATA1_POWER);
+err_free_1:
+ gpio_free(NET2BIG_GPIO_SATA0_POWER);
+
+ return;
+}
+
+/*****************************************************************************
+ * GPIO LEDs
+ ****************************************************************************/
+
+/*
+ * The power front LEDs (blue and red) and SATA red LEDs are controlled via a
+ * single GPIO line and are compatible with the leds-gpio driver.
+ *
+ * The SATA blue LEDs have some hardware blink capabilities which are detailed
+ * in the following array:
+ *
+ * SATAx blue LED | SATAx activity | LED state
+ * | |
+ * 0 | 0 | blink (rate 300ms)
+ * 1 | 0 | off
+ * ? | 1 | on
+ *
+ * Notes: The blue and the red front LED's can't be on at the same time.
+ * Blue LED have priority.
+ */
+
+#define NET2BIG_GPIO_PWR_RED_LED 6
+#define NET2BIG_GPIO_PWR_BLUE_LED 16
+#define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7
+
+#define NET2BIG_GPIO_SATA0_RED_LED 11
+#define NET2BIG_GPIO_SATA1_RED_LED 10
+
+#define NET2BIG_GPIO_SATA0_BLUE_LED 17
+#define NET2BIG_GPIO_SATA1_BLUE_LED 13
+
+static struct gpio_led net2big_leds[] = {
+ {
+ .name = "net2big:red:power",
+ .gpio = NET2BIG_GPIO_PWR_RED_LED,
+ },
+ {
+ .name = "net2big:blue:power",
+ .gpio = NET2BIG_GPIO_PWR_BLUE_LED,
+ },
+ {
+ .name = "net2big:red:sata0",
+ .gpio = NET2BIG_GPIO_SATA0_RED_LED,
+ },
+ {
+ .name = "net2big:red:sata1",
+ .gpio = NET2BIG_GPIO_SATA1_RED_LED,
+ },
+};
+
+static struct gpio_led_platform_data net2big_led_data = {
+ .num_leds = ARRAY_SIZE(net2big_leds),
+ .leds = net2big_leds,
+};
+
+static struct platform_device net2big_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &net2big_led_data,
+ },
+};
+
+static void __init net2big_gpio_leds_init(void)
+{
+ int err;
+
+ /* Stop initial CPLD slow red/blue blinking on power LED. */
+ err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
+ "Power LED blink stop");
+ if (err == 0) {
+ err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
+ if (err)
+ gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
+ }
+ if (err)
+ pr_err("net2big: failed to setup power LED blink GPIO\n");
+
+ /*
+ * Configure SATA0 and SATA1 blue LEDs to blink in relation with the
+ * hard disk activity.
+ */
+ err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
+ "SATA0 blue LED control");
+ if (err == 0) {
+ err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
+ if (err)
+ gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
+ }
+ if (err)
+ pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
+
+ err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
+ "SATA1 blue LED control");
+ if (err == 0) {
+ err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
+ if (err)
+ gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
+ }
+ if (err)
+ pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
+
+ platform_device_register(&net2big_gpio_leds);
+}
+
+/****************************************************************************
+ * GPIO keys
+ ****************************************************************************/
+
+#define NET2BIG_GPIO_PUSH_BUTTON 18
+#define NET2BIG_GPIO_POWER_SWITCH_ON 8
+#define NET2BIG_GPIO_POWER_SWITCH_OFF 9
+
+#define NET2BIG_SWITCH_POWER_ON 0x1
+#define NET2BIG_SWITCH_POWER_OFF 0x2
+
+static struct gpio_keys_button net2big_buttons[] = {
+ {
+ .type = EV_SW,
+ .code = NET2BIG_SWITCH_POWER_OFF,
+ .gpio = NET2BIG_GPIO_POWER_SWITCH_OFF,
+ .desc = "Power rocker switch (auto|off)",
+ .active_low = 0,
+ },
+ {
+ .type = EV_SW,
+ .code = NET2BIG_SWITCH_POWER_ON,
+ .gpio = NET2BIG_GPIO_POWER_SWITCH_ON,
+ .desc = "Power rocker switch (on|auto)",
+ .active_low = 0,
+ },
+ {
+ .type = EV_KEY,
+ .code = KEY_POWER,
+ .gpio = NET2BIG_GPIO_PUSH_BUTTON,
+ .desc = "Front Push Button",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data net2big_button_data = {
+ .buttons = net2big_buttons,
+ .nbuttons = ARRAY_SIZE(net2big_buttons),
+};
+
+static struct platform_device net2big_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &net2big_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+static unsigned int net2big_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Raid mode (bit 0) */
+ MPP1_GPIO, /* USB port 2 fuse (0 = Fail, 1 = Ok) */
+ MPP2_GPIO, /* Raid mode (bit 1) */
+ MPP3_GPIO, /* Board ID (bit 0) */
+ MPP4_GPIO, /* Fan activity (0 = Off, 1 = On) */
+ MPP5_GPIO, /* Fan fail detection */
+ MPP6_GPIO, /* Red front LED (0 = Off, 1 = On) */
+ MPP7_GPIO, /* Disable initial blinking on front LED */
+ MPP8_GPIO, /* Rear power switch (on|auto) */
+ MPP9_GPIO, /* Rear power switch (auto|off) */
+ MPP10_GPIO, /* SATA 1 red LED (0 = Off, 1 = On) */
+ MPP11_GPIO, /* SATA 0 red LED (0 = Off, 1 = On) */
+ MPP12_GPIO, /* Board ID (bit 1) */
+ MPP13_GPIO, /* SATA 1 blue LED blink control */
+ MPP14_SATA_LED,
+ MPP15_SATA_LED,
+ MPP16_GPIO, /* Blue front LED control */
+ MPP17_GPIO, /* SATA 0 blue LED blink control */
+ MPP18_GPIO, /* Front button (0 = Released, 1 = Pushed ) */
+ MPP19_GPIO, /* SATA{0,1} power On/Off request */
+ 0,
+ /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
+ /* 23: SATA 0 power status */
+ /* 24: Board power off */
+ /* 25: SATA 1 power status */
+};
+
+#define NET2BIG_GPIO_POWER_OFF 24
+
+static void net2big_power_off(void)
+{
+ gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
+}
+
+static void __init net2big_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(net2big_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&net2big_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ net2big_sata_power_init();
+ orion5x_sata_init(&net2big_sata_data);
+
+ orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
+ NET2BIG_NOR_BOOT_SIZE);
+ platform_device_register(&net2big_nor_flash);
+
+ platform_device_register(&net2big_gpio_buttons);
+ net2big_gpio_leds_init();
+
+ i2c_register_board_info(0, net2big_i2c_devices,
+ ARRAY_SIZE(net2big_i2c_devices));
+
+ orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
+
+ if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
+ gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
+ pm_power_off = net2big_power_off;
+ else
+ pr_err("net2big: failed to configure power-off GPIO\n");
+
+ pr_notice("net2big: Flash writing is not yet supported.\n");
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+MACHINE_START(NET2BIG, "LaCie 2Big Network")
+ .boot_params = 0x00000100,
+ .init_machine = net2big_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
new file mode 100644
index 00000000..e8706f15
--- /dev/null
+++ b/arch/arm/mach-orion5x/pci.c
@@ -0,0 +1,601 @@
+/*
+ * arch/arm/mach-orion5x/pci.c
+ *
+ * PCI and PCIe functions for Marvell Orion System On Chip
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/mbus.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include "common.h"
+
+/*****************************************************************************
+ * Orion has one PCIe controller and one PCI controller.
+ *
+ * Note1: The local PCIe bus number is '0'. The local PCI bus number
+ * follows the scanned PCIe bridged busses, if any.
+ *
+ * Note2: It is possible for PCI/PCIe agents to access many subsystem's
+ * space, by configuring BARs and Address Decode Windows, e.g. flashes on
+ * device bus, Orion registers, etc. However this code only enable the
+ * access to DDR banks.
+ ****************************************************************************/
+
+
+/*****************************************************************************
+ * PCIe controller
+ ****************************************************************************/
+#define PCIE_BASE ((void __iomem *)ORION5X_PCIE_VIRT_BASE)
+
+void __init orion5x_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id(PCIE_BASE);
+ *rev = orion_pcie_rev(PCIE_BASE);
+}
+
+static int pcie_valid_config(int bus, int dev)
+{
+ /*
+ * Don't go out when trying to access --
+ * 1. nonexisting device on local bus
+ * 2. where there's no device connected (no link)
+ */
+ if (bus == 0 && dev == 0)
+ return 1;
+
+ if (!orion_pcie_link_up(PCIE_BASE))
+ return 0;
+
+ if (bus == 0 && dev != 1)
+ return 0;
+
+ return 1;
+}
+
+
+/*
+ * PCIe config cycles are done by programming the PCIE_CONF_ADDR register
+ * and then reading the PCIE_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion5x_pcie_lock);
+
+static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ spin_lock_irqsave(&orion5x_pcie_lock, flags);
+ ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
+
+ return ret;
+}
+
+static int pcie_rd_conf_wa(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 *val)
+{
+ int ret;
+
+ if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ /*
+ * We only support access to the non-extended configuration
+ * space when using the WA access method (or we would have to
+ * sacrifice 256M of CPU virtual address space.)
+ */
+ if (where >= 0x100) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ ret = orion_pcie_rd_conf_wa((void __iomem *)ORION5X_PCIE_WA_VIRT_BASE,
+ bus, devfn, where, size, val);
+
+ return ret;
+}
+
+static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ unsigned long flags;
+ int ret;
+
+ if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ spin_lock_irqsave(&orion5x_pcie_lock, flags);
+ ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
+
+ return ret;
+}
+
+static struct pci_ops pcie_ops = {
+ .read = pcie_rd_conf,
+ .write = pcie_wr_conf,
+};
+
+
+static int __init pcie_setup(struct pci_sys_data *sys)
+{
+ struct resource *res;
+ int dev;
+
+ /*
+ * Generic PCIe unit setup.
+ */
+ orion_pcie_setup(PCIE_BASE, &orion5x_mbus_dram_info);
+
+ /*
+ * Check whether to apply Orion-1/Orion-NAS PCIe config
+ * read transaction workaround.
+ */
+ dev = orion_pcie_dev_id(PCIE_BASE);
+ if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
+ printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
+ "read transaction workaround\n");
+ orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
+ ORION5X_PCIE_WA_SIZE);
+ pcie_ops.read = pcie_rd_conf_wa;
+ }
+
+ /*
+ * Request resources.
+ */
+ res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+ if (!res)
+ panic("pcie_setup unable to alloc resources");
+
+ /*
+ * IORESOURCE_IO
+ */
+ res[0].name = "PCIe I/O Space";
+ res[0].flags = IORESOURCE_IO;
+ res[0].start = ORION5X_PCIE_IO_BUS_BASE;
+ res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
+ if (request_resource(&ioport_resource, &res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ res[1].name = "PCIe Memory Space";
+ res[1].flags = IORESOURCE_MEM;
+ res[1].start = ORION5X_PCIE_MEM_PHYS_BASE;
+ res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1;
+ if (request_resource(&iomem_resource, &res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &res[1];
+
+ sys->resource[2] = NULL;
+ sys->io_offset = 0;
+
+ return 1;
+}
+
+/*****************************************************************************
+ * PCI controller
+ ****************************************************************************/
+#define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE | (x))
+#define PCI_MODE ORION5X_PCI_REG(0xd00)
+#define PCI_CMD ORION5X_PCI_REG(0xc00)
+#define PCI_P2P_CONF ORION5X_PCI_REG(0x1d14)
+#define PCI_CONF_ADDR ORION5X_PCI_REG(0xc78)
+#define PCI_CONF_DATA ORION5X_PCI_REG(0xc7c)
+
+/*
+ * PCI_MODE bits
+ */
+#define PCI_MODE_64BIT (1 << 2)
+#define PCI_MODE_PCIX ((1 << 4) | (1 << 5))
+
+/*
+ * PCI_CMD bits
+ */
+#define PCI_CMD_HOST_REORDER (1 << 29)
+
+/*
+ * PCI_P2P_CONF bits
+ */
+#define PCI_P2P_BUS_OFFS 16
+#define PCI_P2P_BUS_MASK (0xff << PCI_P2P_BUS_OFFS)
+#define PCI_P2P_DEV_OFFS 24
+#define PCI_P2P_DEV_MASK (0x1f << PCI_P2P_DEV_OFFS)
+
+/*
+ * PCI_CONF_ADDR bits
+ */
+#define PCI_CONF_REG(reg) ((reg) & 0xfc)
+#define PCI_CONF_FUNC(func) (((func) & 0x3) << 8)
+#define PCI_CONF_DEV(dev) (((dev) & 0x1f) << 11)
+#define PCI_CONF_BUS(bus) (((bus) & 0xff) << 16)
+#define PCI_CONF_ADDR_EN (1 << 31)
+
+/*
+ * Internal configuration space
+ */
+#define PCI_CONF_FUNC_STAT_CMD 0
+#define PCI_CONF_REG_STAT_CMD 4
+#define PCIX_STAT 0x64
+#define PCIX_STAT_BUS_OFFS 8
+#define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS)
+
+/*
+ * PCI Address Decode Windows registers
+ */
+#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
+ ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
+ ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
+ ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
+#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
+ ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
+ ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
+ ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
+#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
+#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
+
+/*
+ * PCI configuration helpers for BAR settings
+ */
+#define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1)
+#define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10)
+#define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14)
+
+/*
+ * PCI config cycles are done by programming the PCI_CONF_ADDR register
+ * and then reading the PCI_CONF_DATA register. Need to make sure these
+ * transactions are atomic.
+ */
+static DEFINE_SPINLOCK(orion5x_pci_lock);
+
+static int orion5x_pci_cardbus_mode;
+
+static int orion5x_pci_local_bus_nr(void)
+{
+ u32 conf = readl(PCI_P2P_CONF);
+ return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
+}
+
+static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func,
+ u32 where, u32 size, u32 *val)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&orion5x_pci_lock, flags);
+
+ writel(PCI_CONF_BUS(bus) |
+ PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+ PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
+
+ *val = readl(PCI_CONF_DATA);
+
+ if (size == 1)
+ *val = (*val >> (8*(where & 0x3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8*(where & 0x3))) & 0xffff;
+
+ spin_unlock_irqrestore(&orion5x_pci_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
+ u32 where, u32 size, u32 val)
+{
+ unsigned long flags;
+ int ret = PCIBIOS_SUCCESSFUL;
+
+ spin_lock_irqsave(&orion5x_pci_lock, flags);
+
+ writel(PCI_CONF_BUS(bus) |
+ PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+ PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
+
+ if (size == 4) {
+ __raw_writel(val, PCI_CONF_DATA);
+ } else if (size == 2) {
+ __raw_writew(val, PCI_CONF_DATA + (where & 0x3));
+ } else if (size == 1) {
+ __raw_writeb(val, PCI_CONF_DATA + (where & 0x3));
+ } else {
+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ spin_unlock_irqrestore(&orion5x_pci_lock, flags);
+
+ return ret;
+}
+
+static int orion5x_pci_valid_config(int bus, u32 devfn)
+{
+ if (bus == orion5x_pci_local_bus_nr()) {
+ /*
+ * Don't go out for local device
+ */
+ if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
+ return 0;
+
+ /*
+ * When the PCI signals are directly connected to a
+ * Cardbus slot, ignore all but device IDs 0 and 1.
+ */
+ if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 *val)
+{
+ if (!orion5x_pci_valid_config(bus->number, devfn)) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return orion5x_pci_hw_rd_conf(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where, size, val);
+}
+
+static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ if (!orion5x_pci_valid_config(bus->number, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where, size, val);
+}
+
+static struct pci_ops pci_ops = {
+ .read = orion5x_pci_rd_conf,
+ .write = orion5x_pci_wr_conf,
+};
+
+static void __init orion5x_pci_set_bus_nr(int nr)
+{
+ u32 p2p = readl(PCI_P2P_CONF);
+
+ if (readl(PCI_MODE) & PCI_MODE_PCIX) {
+ /*
+ * PCI-X mode
+ */
+ u32 pcix_status, bus, dev;
+ bus = (p2p & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS;
+ dev = (p2p & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS;
+ orion5x_pci_hw_rd_conf(bus, dev, 0, PCIX_STAT, 4, &pcix_status);
+ pcix_status &= ~PCIX_STAT_BUS_MASK;
+ pcix_status |= (nr << PCIX_STAT_BUS_OFFS);
+ orion5x_pci_hw_wr_conf(bus, dev, 0, PCIX_STAT, 4, pcix_status);
+ } else {
+ /*
+ * PCI Conventional mode
+ */
+ p2p &= ~PCI_P2P_BUS_MASK;
+ p2p |= (nr << PCI_P2P_BUS_OFFS);
+ writel(p2p, PCI_P2P_CONF);
+ }
+}
+
+static void __init orion5x_pci_master_slave_enable(void)
+{
+ int bus_nr, func, reg;
+ u32 val;
+
+ bus_nr = orion5x_pci_local_bus_nr();
+ func = PCI_CONF_FUNC_STAT_CMD;
+ reg = PCI_CONF_REG_STAT_CMD;
+ orion5x_pci_hw_rd_conf(bus_nr, 0, func, reg, 4, &val);
+ val |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ orion5x_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
+}
+
+static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
+{
+ u32 win_enable;
+ int bus;
+ int i;
+
+ /*
+ * First, disable windows.
+ */
+ win_enable = 0xffffffff;
+ writel(win_enable, PCI_BAR_ENABLE);
+
+ /*
+ * Setup windows for DDR banks.
+ */
+ bus = orion5x_pci_local_bus_nr();
+
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+ u32 func = PCI_CONF_FUNC_BAR_CS(cs->cs_index);
+ u32 reg;
+ u32 val;
+
+ /*
+ * Write DRAM bank base address register.
+ */
+ reg = PCI_CONF_REG_BAR_LO_CS(cs->cs_index);
+ orion5x_pci_hw_rd_conf(bus, 0, func, reg, 4, &val);
+ val = (cs->base & 0xfffff000) | (val & 0xfff);
+ orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, val);
+
+ /*
+ * Write DRAM bank size register.
+ */
+ reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
+ orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
+ writel((cs->size - 1) & 0xfffff000,
+ PCI_BAR_SIZE_DDR_CS(cs->cs_index));
+ writel(cs->base & 0xfffff000,
+ PCI_BAR_REMAP_DDR_CS(cs->cs_index));
+
+ /*
+ * Enable decode window for this chip select.
+ */
+ win_enable &= ~(1 << cs->cs_index);
+ }
+
+ /*
+ * Re-enable decode windows.
+ */
+ writel(win_enable, PCI_BAR_ENABLE);
+
+ /*
+ * Disable automatic update of address remapping when writing to BARs.
+ */
+ orion5x_setbits(PCI_ADDR_DECODE_CTRL, 1);
+}
+
+static int __init pci_setup(struct pci_sys_data *sys)
+{
+ struct resource *res;
+
+ /*
+ * Point PCI unit MBUS decode windows to DRAM space.
+ */
+ orion5x_setup_pci_wins(&orion5x_mbus_dram_info);
+
+ /*
+ * Master + Slave enable
+ */
+ orion5x_pci_master_slave_enable();
+
+ /*
+ * Force ordering
+ */
+ orion5x_setbits(PCI_CMD, PCI_CMD_HOST_REORDER);
+
+ /*
+ * Request resources
+ */
+ res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
+ if (!res)
+ panic("pci_setup unable to alloc resources");
+
+ /*
+ * IORESOURCE_IO
+ */
+ res[0].name = "PCI I/O Space";
+ res[0].flags = IORESOURCE_IO;
+ res[0].start = ORION5X_PCI_IO_BUS_BASE;
+ res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
+ if (request_resource(&ioport_resource, &res[0]))
+ panic("Request PCI IO resource failed\n");
+ sys->resource[0] = &res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ res[1].name = "PCI Memory Space";
+ res[1].flags = IORESOURCE_MEM;
+ res[1].start = ORION5X_PCI_MEM_PHYS_BASE;
+ res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1;
+ if (request_resource(&iomem_resource, &res[1]))
+ panic("Request PCI Memory resource failed\n");
+ sys->resource[1] = &res[1];
+
+ sys->resource[2] = NULL;
+ sys->io_offset = 0;
+
+ return 1;
+}
+
+
+/*****************************************************************************
+ * General PCIe + PCI
+ ****************************************************************************/
+static void __devinit rc_pci_fixup(struct pci_dev *dev)
+{
+ /*
+ * Prevent enumeration of root complex.
+ */
+ if (dev->bus->parent == NULL && dev->devfn == 0) {
+ int i;
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+
+static int orion5x_pci_disabled __initdata;
+
+void __init orion5x_pci_disable(void)
+{
+ orion5x_pci_disabled = 1;
+}
+
+void __init orion5x_pci_set_cardbus_mode(void)
+{
+ orion5x_pci_cardbus_mode = 1;
+}
+
+int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ if (nr == 0) {
+ orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr);
+ ret = pcie_setup(sys);
+ } else if (nr == 1 && !orion5x_pci_disabled) {
+ orion5x_pci_set_bus_nr(sys->busnr);
+ ret = pci_setup(sys);
+ }
+
+ return ret;
+}
+
+struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr == 0) {
+ bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
+ } else if (nr == 1 && !orion5x_pci_disabled) {
+ bus = pci_scan_bus(sys->busnr, &pci_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+int __init orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int bus = dev->bus->number;
+
+ /*
+ * PCIe endpoint?
+ */
+ if (orion5x_pci_disabled || bus < orion5x_pci_local_bus_nr())
+ return IRQ_ORION5X_PCIE0_INT;
+
+ return -1;
+}
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
new file mode 100644
index 00000000..9eec7c23
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -0,0 +1,179 @@
+/*
+ * arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+ *
+ * Marvell Orion-VoIP FXO Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * RD-88F5181L FXO Info
+ ****************************************************************************/
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define RD88F5181L_FXO_NOR_BOOT_BASE 0xff800000
+#define RD88F5181L_FXO_NOR_BOOT_SIZE SZ_8M
+
+
+/*****************************************************************************
+ * 8M NOR Flash on Device bus Boot chip select
+ ****************************************************************************/
+static struct physmap_flash_data rd88f5181l_fxo_nor_boot_flash_data = {
+ .width = 1,
+};
+
+static struct resource rd88f5181l_fxo_nor_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = RD88F5181L_FXO_NOR_BOOT_BASE,
+ .end = RD88F5181L_FXO_NOR_BOOT_BASE +
+ RD88F5181L_FXO_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device rd88f5181l_fxo_nor_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &rd88f5181l_fxo_nor_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &rd88f5181l_fxo_nor_boot_flash_resource,
+};
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int rd88f5181l_fxo_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* LED1 CardBus LED (front panel) */
+ MPP1_GPIO, /* PCI_intA */
+ MPP2_GPIO, /* Hard Reset / Factory Init*/
+ MPP3_GPIO, /* FXS or DAA select */
+ MPP4_GPIO, /* LED6 - phone LED (front panel) */
+ MPP5_GPIO, /* LED5 - phone LED (front panel) */
+ MPP6_PCI_CLK, /* CPU PCI refclk */
+ MPP7_PCI_CLK, /* PCI/PCIe refclk */
+ MPP8_GPIO, /* CardBus reset */
+ MPP9_GPIO, /* GE_RXERR */
+ MPP10_GPIO, /* LED2 MiniPCI LED (front panel) */
+ MPP11_GPIO, /* Lifeline control */
+ MPP12_GIGE, /* GE_TXD[4] */
+ MPP13_GIGE, /* GE_TXD[5] */
+ MPP14_GIGE, /* GE_TXD[6] */
+ MPP15_GIGE, /* GE_TXD[7] */
+ MPP16_GIGE, /* GE_RXD[4] */
+ MPP17_GIGE, /* GE_RXD[5] */
+ MPP18_GIGE, /* GE_RXD[6] */
+ MPP19_GIGE, /* GE_RXD[7] */
+ 0,
+};
+
+static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
+ .port_names[0] = "lan2",
+ .port_names[1] = "lan1",
+ .port_names[2] = "wan",
+ .port_names[3] = "cpu",
+ .port_names[5] = "lan4",
+ .port_names[7] = "lan3",
+};
+
+static struct dsa_platform_data rd88f5181l_fxo_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f5181l_fxo_switch_chip_data,
+};
+
+static void __init rd88f5181l_fxo_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(rd88f5181l_fxo_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f5181l_fxo_eth_data);
+ orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
+ RD88F5181L_FXO_NOR_BOOT_SIZE);
+ platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
+}
+
+static int __init
+rd88f5181l_fxo_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI / Cardbus slot.
+ */
+ return gpio_to_irq(1);
+}
+
+static struct hw_pci rd88f5181l_fxo_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = rd88f5181l_fxo_pci_map_irq,
+};
+
+static int __init rd88f5181l_fxo_pci_init(void)
+{
+ if (machine_is_rd88f5181l_fxo()) {
+ orion5x_pci_set_cardbus_mode();
+ pci_common_init(&rd88f5181l_fxo_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f5181l_fxo_pci_init);
+
+MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")
+ /* Maintainer: Nicolas Pitre <nico@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f5181l_fxo_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
new file mode 100644
index 00000000..0cc90bbf
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -0,0 +1,191 @@
+/*
+ * arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+ *
+ * Marvell Orion-VoIP GE Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/i2c.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * RD-88F5181L GE Info
+ ****************************************************************************/
+/*
+ * 16M NOR flash Device bus boot chip select
+ */
+#define RD88F5181L_GE_NOR_BOOT_BASE 0xff000000
+#define RD88F5181L_GE_NOR_BOOT_SIZE SZ_16M
+
+
+/*****************************************************************************
+ * 16M NOR Flash on Device bus Boot chip select
+ ****************************************************************************/
+static struct physmap_flash_data rd88f5181l_ge_nor_boot_flash_data = {
+ .width = 1,
+};
+
+static struct resource rd88f5181l_ge_nor_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = RD88F5181L_GE_NOR_BOOT_BASE,
+ .end = RD88F5181L_GE_NOR_BOOT_BASE +
+ RD88F5181L_GE_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device rd88f5181l_ge_nor_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &rd88f5181l_ge_nor_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &rd88f5181l_ge_nor_boot_flash_resource,
+};
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int rd88f5181l_ge_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* LED1 */
+ MPP1_GPIO, /* LED5 */
+ MPP2_GPIO, /* LED4 */
+ MPP3_GPIO, /* LED3 */
+ MPP4_GPIO, /* PCI_intA */
+ MPP5_GPIO, /* RTC interrupt */
+ MPP6_PCI_CLK, /* CPU PCI refclk */
+ MPP7_PCI_CLK, /* PCI/PCIe refclk */
+ MPP8_GPIO, /* 88e6131 interrupt */
+ MPP9_GPIO, /* GE_RXERR */
+ MPP10_GPIO, /* PCI_intB */
+ MPP11_GPIO, /* LED2 */
+ MPP12_GIGE, /* GE_TXD[4] */
+ MPP13_GIGE, /* GE_TXD[5] */
+ MPP14_GIGE, /* GE_TXD[6] */
+ MPP15_GIGE, /* GE_TXD[7] */
+ MPP16_GIGE, /* GE_RXD[4] */
+ MPP17_GIGE, /* GE_RXD[5] */
+ MPP18_GIGE, /* GE_RXD[6] */
+ MPP19_GIGE, /* GE_RXD[7] */
+ 0,
+};
+
+static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
+ .port_names[0] = "lan2",
+ .port_names[1] = "lan1",
+ .port_names[2] = "wan",
+ .port_names[3] = "cpu",
+ .port_names[5] = "lan4",
+ .port_names[7] = "lan3",
+};
+
+static struct dsa_platform_data rd88f5181l_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f5181l_ge_switch_chip_data,
+};
+
+static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+static void __init rd88f5181l_ge_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(rd88f5181l_ge_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f5181l_ge_eth_data);
+ orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data,
+ gpio_to_irq(8));
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE,
+ RD88F5181L_GE_NOR_BOOT_SIZE);
+ platform_device_register(&rd88f5181l_ge_nor_boot_flash);
+
+ i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
+}
+
+static int __init
+rd88f5181l_ge_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Cardbus slot.
+ */
+ if (pin == 1)
+ return gpio_to_irq(4);
+ else
+ return gpio_to_irq(10);
+}
+
+static struct hw_pci rd88f5181l_ge_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = rd88f5181l_ge_pci_map_irq,
+};
+
+static int __init rd88f5181l_ge_pci_init(void)
+{
+ if (machine_is_rd88f5181l_ge()) {
+ orion5x_pci_set_cardbus_mode();
+ pci_common_init(&rd88f5181l_ge_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f5181l_ge_pci_init);
+
+MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f5181l_ge_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
new file mode 100644
index 00000000..48da39b9
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -0,0 +1,314 @@
+/*
+ * arch/arm/mach-orion5x/rd88f5182-setup.c
+ *
+ * Marvell Orion-NAS Reference Design Setup
+ *
+ * Maintainer: Ronen Shitrit <rshitrit@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * RD-88F5182 Info
+ ****************************************************************************/
+
+/*
+ * 512K NOR flash Device bus boot chip select
+ */
+
+#define RD88F5182_NOR_BOOT_BASE 0xf4000000
+#define RD88F5182_NOR_BOOT_SIZE SZ_512K
+
+/*
+ * 16M NOR flash on Device bus chip select 1
+ */
+
+#define RD88F5182_NOR_BASE 0xfc000000
+#define RD88F5182_NOR_SIZE SZ_16M
+
+/*
+ * PCI
+ */
+
+#define RD88F5182_PCI_SLOT0_OFFS 7
+#define RD88F5182_PCI_SLOT0_IRQ_A_PIN 7
+#define RD88F5182_PCI_SLOT0_IRQ_B_PIN 6
+
+/*
+ * GPIO Debug LED
+ */
+
+#define RD88F5182_GPIO_DBG_LED 0
+
+/*****************************************************************************
+ * 16M NOR Flash on Device bus CS1
+ ****************************************************************************/
+
+static struct physmap_flash_data rd88f5182_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource rd88f5182_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = RD88F5182_NOR_BASE,
+ .end = RD88F5182_NOR_BASE + RD88F5182_NOR_SIZE - 1,
+};
+
+static struct platform_device rd88f5182_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &rd88f5182_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &rd88f5182_nor_flash_resource,
+};
+
+#ifdef CONFIG_LEDS
+
+/*****************************************************************************
+ * Use GPIO debug led as CPU active indication
+ ****************************************************************************/
+
+static void rd88f5182_dbgled_event(led_event_t evt)
+{
+ int val;
+
+ if (evt == led_idle_end)
+ val = 1;
+ else if (evt == led_idle_start)
+ val = 0;
+ else
+ return;
+
+ gpio_set_value(RD88F5182_GPIO_DBG_LED, val);
+}
+
+static int __init rd88f5182_dbgled_init(void)
+{
+ int pin;
+
+ if (machine_is_rd88f5182()) {
+ pin = RD88F5182_GPIO_DBG_LED;
+
+ if (gpio_request(pin, "DBGLED") == 0) {
+ if (gpio_direction_output(pin, 0) != 0) {
+ printk(KERN_ERR "rd88f5182_dbgled_init failed "
+ "to set output pin %d\n", pin);
+ gpio_free(pin);
+ return 0;
+ }
+ } else {
+ printk(KERN_ERR "rd88f5182_dbgled_init failed "
+ "to request gpio %d\n", pin);
+ return 0;
+ }
+
+ leds_event = rd88f5182_dbgled_event;
+ }
+
+ return 0;
+}
+
+__initcall(rd88f5182_dbgled_init);
+
+#endif
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+void __init rd88f5182_pci_preinit(void)
+{
+ int pin;
+
+ /*
+ * Configure PCI GPIO IRQ pins
+ */
+ pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
+ if (gpio_request(pin, "PCI IntA") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+ "set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "rd88f5182_pci_preinit failed to request gpio %d\n", pin);
+ }
+
+ pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
+ if (gpio_request(pin, "PCI IntB") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "rd88f5182_pci_preinit faield to "
+ "set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "rd88f5182_pci_preinit failed to gpio_request %d\n", pin);
+ }
+}
+
+static int __init rd88f5182_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI IRQs are connected via GPIOs
+ */
+ switch (slot - RD88F5182_PCI_SLOT0_OFFS) {
+ case 0:
+ if (pin == 1)
+ return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_A_PIN);
+ else
+ return gpio_to_irq(RD88F5182_PCI_SLOT0_IRQ_B_PIN);
+ default:
+ return -1;
+ }
+}
+
+static struct hw_pci rd88f5182_pci __initdata = {
+ .nr_controllers = 2,
+ .preinit = rd88f5182_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = rd88f5182_pci_map_irq,
+};
+
+static int __init rd88f5182_pci_init(void)
+{
+ if (machine_is_rd88f5182())
+ pci_common_init(&rd88f5182_pci);
+
+ return 0;
+}
+
+subsys_initcall(rd88f5182_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * RTC DS1338 on I2C bus
+ ****************************************************************************/
+static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+/*****************************************************************************
+ * Sata
+ ****************************************************************************/
+static struct mv_sata_platform_data rd88f5182_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int rd88f5182_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Debug Led */
+ MPP1_GPIO, /* Reset Switch */
+ MPP2_UNUSED,
+ MPP3_GPIO, /* RTC Int */
+ MPP4_GPIO,
+ MPP5_GPIO,
+ MPP6_GPIO, /* PCI_intA */
+ MPP7_GPIO, /* PCI_intB */
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_SATA_LED, /* SATA 0 presence */
+ MPP13_SATA_LED, /* SATA 1 presence */
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_UNUSED,
+ MPP17_UNUSED,
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init rd88f5182_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(rd88f5182_mpp_modes);
+
+ /*
+ * MPP[20] PCI Clock to MV88F5182
+ * MPP[21] PCI Clock to mini PCI CON11
+ * MPP[22] USB 0 over current indication
+ * MPP[23] USB 1 over current indication
+ * MPP[24] USB 1 over current enable
+ * MPP[25] USB 0 over current enable
+ */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&rd88f5182_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&rd88f5182_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
+ RD88F5182_NOR_BOOT_SIZE);
+
+ orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
+ platform_device_register(&rd88f5182_nor_flash);
+
+ i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
+}
+
+MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
+ /* Maintainer: Ronen Shitrit <rshitrit@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f5182_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
new file mode 100644
index 00000000..ad2eba92
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -0,0 +1,132 @@
+/*
+ * arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c
+ *
+ * Marvell Orion-1-90 AP GE Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/ethtool.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+
+static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
+ .phy_addr = -1,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
+ .port_names[0] = "lan1",
+ .port_names[1] = "lan2",
+ .port_names[2] = "lan3",
+ .port_names[3] = "lan4",
+ .port_names[4] = "wan",
+ .port_names[5] = "cpu",
+};
+
+static struct dsa_platform_data rd88f6183ap_ge_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &rd88f6183ap_ge_switch_chip_data,
+};
+
+static struct mtd_partition rd88f6183ap_ge_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00200000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x00200000,
+ .size = 0x00500000,
+ }, {
+ .name = "nvram",
+ .offset = 0x00700000,
+ .size = 0x00080000,
+ },
+};
+
+static struct flash_platform_data rd88f6183ap_ge_spi_slave_data = {
+ .type = "m25p64",
+ .nr_parts = ARRAY_SIZE(rd88f6183ap_ge_partitions),
+ .parts = rd88f6183ap_ge_partitions,
+};
+
+static struct spi_board_info __initdata rd88f6183ap_ge_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &rd88f6183ap_ge_spi_slave_data,
+ .irq = NO_IRQ,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static void __init rd88f6183ap_ge_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f6183ap_ge_eth_data);
+ orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data,
+ gpio_to_irq(3));
+ spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
+ ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
+ orion5x_spi_init();
+ orion5x_uart0_init();
+}
+
+static struct hw_pci rd88f6183ap_ge_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = orion5x_pci_map_irq,
+};
+
+static int __init rd88f6183ap_ge_pci_init(void)
+{
+ if (machine_is_rd88f6183ap_ge()) {
+ orion5x_pci_disable();
+ pci_common_init(&rd88f6183ap_ge_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f6183ap_ge_pci_init);
+
+MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = rd88f6183ap_ge_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
new file mode 100644
index 00000000..29ce826c
--- /dev/null
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -0,0 +1,368 @@
+/*
+ * Buffalo Terastation Pro II/Live Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Terastation Pro 2/Live Info
+ ****************************************************************************/
+
+/*
+ * Terastation Pro 2 hardware :
+ * - Marvell 88F5281-D0
+ * - Marvell 88SX6042 SATA controller (PCI)
+ * - Marvell 88E1118 Gigabit Ethernet PHY
+ * - 256KB NOR flash
+ * - 128MB of DDR RAM
+ * - PCIe port (not equipped)
+ */
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define TSP2_NOR_BOOT_BASE 0xf4000000
+#define TSP2_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data tsp2_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource tsp2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TSP2_NOR_BOOT_BASE,
+ .end = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device tsp2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &tsp2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &tsp2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+#define TSP2_PCI_SLOT0_OFFS 7
+#define TSP2_PCI_SLOT0_IRQ_PIN 11
+
+void __init tsp2_pci_preinit(void)
+{
+ int pin;
+
+ /*
+ * Configure PCI GPIO IRQ pins
+ */
+ pin = TSP2_PCI_SLOT0_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int1") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "tsp2_pci_preinit failed "
+ "to set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "tsp2_pci_preinit failed to "
+ "gpio_request %d\n", pin);
+ }
+}
+
+static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI IRQs are connected via GPIOs.
+ */
+ if (slot == TSP2_PCI_SLOT0_OFFS)
+ return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);
+
+ return -1;
+}
+
+static struct hw_pci tsp2_pci __initdata = {
+ .nr_controllers = 2,
+ .preinit = tsp2_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = tsp2_pci_map_irq,
+};
+
+static int __init tsp2_pci_init(void)
+{
+ if (machine_is_terastation_pro2())
+ pci_common_init(&tsp2_pci);
+
+ return 0;
+}
+
+subsys_initcall(tsp2_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data tsp2_eth_data = {
+ .phy_addr = 0,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define TSP2_RTC_GPIO 9
+
+static struct i2c_board_info __initdata tsp2_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * Terastation Pro II specific power off method via UART1-attached
+ * microcontroller
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+static int tsp2_miconread(unsigned char *buf, int count)
+{
+ int i;
+ int timeout;
+
+ for (i = 0; i < count; i++) {
+ timeout = 10;
+
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
+ if (--timeout == 0)
+ break;
+ udelay(1000);
+ }
+
+ if (timeout == 0)
+ break;
+ buf[i] = readl(UART1_REG(RX));
+ }
+
+ /* return read bytes */
+ return i;
+}
+
+static int tsp2_miconwrite(const unsigned char *buf, int count)
+{
+ int i = 0;
+
+ while (count--) {
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
+ barrier();
+ writel(buf[i++], UART1_REG(TX));
+ }
+
+ return 0;
+}
+
+static int tsp2_miconsend(const unsigned char *data, int count)
+{
+ int i;
+ unsigned char checksum = 0;
+ unsigned char recv_buf[40];
+ unsigned char send_buf[40];
+ unsigned char correct_ack[3];
+ int retry = 2;
+
+ /* Generate checksum */
+ for (i = 0; i < count; i++)
+ checksum -= data[i];
+
+ do {
+ /* Send data */
+ tsp2_miconwrite(data, count);
+
+ /* send checksum */
+ tsp2_miconwrite(&checksum, 1);
+
+ if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
+ printk(KERN_ERR ">%s: receive failed.\n", __func__);
+
+ /* send preamble to clear the receive buffer */
+ memset(&send_buf, 0xff, sizeof(send_buf));
+ tsp2_miconwrite(send_buf, sizeof(send_buf));
+
+ /* make dummy reads */
+ mdelay(100);
+ tsp2_miconread(recv_buf, sizeof(recv_buf));
+ } else {
+ /* Generate expected ack */
+ correct_ack[0] = 0x01;
+ correct_ack[1] = data[1];
+ correct_ack[2] = 0x00;
+
+ /* checksum Check */
+ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+ recv_buf[3]) & 0xFF) {
+ printk(KERN_ERR ">%s: Checksum Error : "
+ "Received data[%02x, %02x, %02x, %02x]"
+ "\n", __func__, recv_buf[0],
+ recv_buf[1], recv_buf[2], recv_buf[3]);
+ } else {
+ /* Check Received Data */
+ if (correct_ack[0] == recv_buf[0] &&
+ correct_ack[1] == recv_buf[1] &&
+ correct_ack[2] == recv_buf[2]) {
+ /* Interval for next command */
+ mdelay(10);
+
+ /* Receive ACK */
+ return 0;
+ }
+ }
+ /* Received NAK or illegal Data */
+ printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
+ "Received\n", __func__);
+ }
+ } while (retry--);
+
+ /* Interval for next command */
+ mdelay(10);
+
+ return -1;
+}
+
+static void tsp2_power_off(void)
+{
+ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
+ const unsigned char shutdownwait[] = {0x00, 0x0c};
+ const unsigned char poweroff[] = {0x00, 0x06};
+ /* 38400 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x1b, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x07, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* Send the commands to shutdown the Terastation Pro II */
+ tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
+ tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
+ tsp2_miconsend(poweroff, sizeof(poweroff));
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int tsp2_mpp_modes[] __initdata = {
+ MPP0_PCIE_RST_OUTn,
+ MPP1_UNUSED,
+ MPP2_UNUSED,
+ MPP3_UNUSED,
+ MPP4_NAND, /* BOOT NAND Flash REn */
+ MPP5_NAND, /* BOOT NAND Flash WEn */
+ MPP6_NAND, /* BOOT NAND Flash HREn[0] */
+ MPP7_NAND, /* BOOT NAND Flash WEn[0] */
+ MPP8_GPIO, /* MICON int */
+ MPP9_GPIO, /* RTC int */
+ MPP10_UNUSED,
+ MPP11_GPIO, /* PCI Int A */
+ MPP12_UNUSED,
+ MPP13_GPIO, /* UPS on UART0 enable */
+ MPP14_GPIO, /* UPS low battery detection */
+ MPP15_UNUSED,
+ MPP16_UART, /* UART1 RXD */
+ MPP17_UART, /* UART1 TXD */
+ MPP18_UART, /* UART1 CTSn */
+ MPP19_UART, /* UART1 RTSn */
+ 0,
+};
+
+static void __init tsp2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(tsp2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
+ TSP2_NOR_BOOT_SIZE);
+ platform_device_register(&tsp2_nor_flash);
+
+ orion5x_ehci0_init();
+ orion5x_eth_init(&tsp2_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TSP2_RTC_GPIO) == 0)
+ tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);
+ else
+ gpio_free(TSP2_RTC_GPIO);
+ }
+ if (tsp2_i2c_rtc.irq == 0)
+ pr_warning("tsp2_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
+
+ /* register Terastation Pro II specific power-off method */
+ pm_power_off = tsp2_power_off;
+}
+
+MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
+ .boot_params = 0x00000100,
+ .init_machine = tsp2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
new file mode 100644
index 00000000..47162fd5
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -0,0 +1,332 @@
+/*
+ * QNAP TS-109/TS-209 Board Setup
+ *
+ * Maintainer: Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx09-common.h"
+
+#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
+#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
+
+/****************************************************************************
+ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
+ * partitions on the device because we want to keep compatibility with
+ * existing QNAP firmware.
+ *
+ * Layout as used by QNAP:
+ * [2] 0x00000000-0x00200000 : "Kernel"
+ * [3] 0x00200000-0x00600000 : "RootFS1"
+ * [4] 0x00600000-0x00700000 : "RootFS2"
+ * [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
+ * [5] 0x00760000-0x00780000 : "U-Boot Config"
+ * [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
+ ***************************************************************************/
+static struct mtd_partition qnap_ts209_partitions[] = {
+ {
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0x00780000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0,
+ }, {
+ .name = "RootFS1",
+ .size = 0x00400000,
+ .offset = 0x00200000,
+ }, {
+ .name = "RootFS2",
+ .size = 0x00100000,
+ .offset = 0x00600000,
+ }, {
+ .name = "U-Boot Config",
+ .size = 0x00020000,
+ .offset = 0x00760000,
+ }, {
+ .name = "NAS Config",
+ .size = 0x00060000,
+ .offset = 0x00700000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data qnap_ts209_nor_flash_data = {
+ .width = 1,
+ .parts = qnap_ts209_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
+};
+
+static struct resource qnap_ts209_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = QNAP_TS209_NOR_BOOT_BASE,
+ .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device qnap_ts209_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &qnap_ts209_nor_flash_data,
+ },
+ .resource = &qnap_ts209_nor_flash_resource,
+ .num_resources = 1,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+#define QNAP_TS209_PCI_SLOT0_OFFS 7
+#define QNAP_TS209_PCI_SLOT0_IRQ_PIN 6
+#define QNAP_TS209_PCI_SLOT1_IRQ_PIN 7
+
+void __init qnap_ts209_pci_preinit(void)
+{
+ int pin;
+
+ /*
+ * Configure PCI GPIO IRQ pins
+ */
+ pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int1") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
+ "set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+ "%d\n", pin);
+ }
+
+ pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int2") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "qnap_ts209_pci_preinit failed "
+ "to set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "qnap_ts209_pci_preinit failed to gpio_request "
+ "%d\n", pin);
+ }
+}
+
+static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI IRQs are connected via GPIOs.
+ */
+ switch (slot - QNAP_TS209_PCI_SLOT0_OFFS) {
+ case 0:
+ return gpio_to_irq(QNAP_TS209_PCI_SLOT0_IRQ_PIN);
+ case 1:
+ return gpio_to_irq(QNAP_TS209_PCI_SLOT1_IRQ_PIN);
+ default:
+ return -1;
+ }
+}
+
+static struct hw_pci qnap_ts209_pci __initdata = {
+ .nr_controllers = 2,
+ .preinit = qnap_ts209_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = qnap_ts209_pci_map_irq,
+};
+
+static int __init qnap_ts209_pci_init(void)
+{
+ if (machine_is_ts_x09())
+ pci_common_init(&qnap_ts209_pci);
+
+ return 0;
+}
+
+subsys_initcall(qnap_ts209_pci_init);
+
+/*****************************************************************************
+ * RTC S35390A on I2C bus
+ ****************************************************************************/
+
+#define TS209_RTC_GPIO 3
+
+static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+ .irq = 0,
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ * Power button is attached to the PIC microcontroller
+ ****************************************************************************/
+
+#define QNAP_TS209_GPIO_KEY_MEDIA 1
+#define QNAP_TS209_GPIO_KEY_RESET 2
+
+static struct gpio_keys_button qnap_ts209_buttons[] = {
+ {
+ .code = KEY_COPY,
+ .gpio = QNAP_TS209_GPIO_KEY_MEDIA,
+ .desc = "USB Copy Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_RESTART,
+ .gpio = QNAP_TS209_GPIO_KEY_RESET,
+ .desc = "Reset Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts209_button_data = {
+ .buttons = qnap_ts209_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts209_buttons),
+};
+
+static struct platform_device qnap_ts209_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts209_button_data,
+ },
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data qnap_ts209_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+
+ * General Setup
+ ****************************************************************************/
+static unsigned int ts209_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_GPIO, /* USB copy button */
+ MPP2_GPIO, /* Load defaults button */
+ MPP3_GPIO, /* GPIO RTC */
+ MPP4_UNUSED,
+ MPP5_UNUSED,
+ MPP6_GPIO, /* PCI Int A */
+ MPP7_GPIO, /* PCI Int B */
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_SATA_LED, /* SATA 0 presence */
+ MPP13_SATA_LED, /* SATA 1 presence */
+ MPP14_SATA_LED, /* SATA 0 active */
+ MPP15_SATA_LED, /* SATA 1 active */
+ MPP16_UART, /* UART1 RXD */
+ MPP17_UART, /* UART1 TXD */
+ MPP18_GPIO, /* SW_RST */
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init qnap_ts209_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ts209_mpp_modes);
+
+ /*
+ * MPP[20] PCI clock 0
+ * MPP[21] PCI clock 1
+ * MPP[22] USB 0 over current
+ * MPP[23-25] Reserved
+ */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
+ QNAP_TS209_NOR_BOOT_SIZE);
+ platform_device_register(&qnap_ts209_nor_flash);
+
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE +
+ qnap_ts209_partitions[5].offset,
+ qnap_ts209_partitions[5].size);
+ orion5x_eth_init(&qnap_tsx09_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&qnap_ts209_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
+
+ platform_device_register(&qnap_ts209_button_device);
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TS209_RTC_GPIO) == 0)
+ qnap_ts209_i2c_rtc.irq = gpio_to_irq(TS209_RTC_GPIO);
+ else
+ gpio_free(TS209_RTC_GPIO);
+ }
+ if (qnap_ts209_i2c_rtc.irq == 0)
+ pr_warning("qnap_ts209_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
+
+ /* register tsx09 specific power-off method */
+ pm_power_off = qnap_tsx09_power_off;
+}
+
+MACHINE_START(TS209, "QNAP TS-109/TS-209")
+ /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts209_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
new file mode 100644
index 00000000..5aacc7ac
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -0,0 +1,321 @@
+/*
+ * QNAP TS-409 Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com>
+ *
+ * Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com>
+ * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx09-common.h"
+
+/*****************************************************************************
+ * QNAP TS-409 Info
+ ****************************************************************************/
+
+/*
+ * QNAP TS-409 hardware :
+ * - Marvell 88F5281-D0
+ * - Marvell 88SX7042 SATA controller (PCIe)
+ * - Marvell 88E1118 Gigabit Ethernet PHY
+ * - RTC S35390A (@0x30) on I2C bus
+ * - 8MB NOR flash
+ * - 256MB of DDR-2 RAM
+ */
+
+/*
+ * 8MB NOR flash Device bus boot chip select
+ */
+
+#define QNAP_TS409_NOR_BOOT_BASE 0xff800000
+#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
+
+/****************************************************************************
+ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
+ * partitions on the device because we want to keep compatibility with
+ * existing QNAP firmware.
+ *
+ * Layout as used by QNAP:
+ * [2] 0x00000000-0x00200000 : "Kernel"
+ * [3] 0x00200000-0x00600000 : "RootFS1"
+ * [4] 0x00600000-0x00700000 : "RootFS2"
+ * [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
+ * [5] 0x00760000-0x00780000 : "U-Boot Config"
+ * [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
+ ***************************************************************************/
+static struct mtd_partition qnap_ts409_partitions[] = {
+ {
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0x00780000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0,
+ }, {
+ .name = "RootFS1",
+ .size = 0x00400000,
+ .offset = 0x00200000,
+ }, {
+ .name = "RootFS2",
+ .size = 0x00100000,
+ .offset = 0x00600000,
+ }, {
+ .name = "U-Boot Config",
+ .size = 0x00020000,
+ .offset = 0x00760000,
+ }, {
+ .name = "NAS Config",
+ .size = 0x00060000,
+ .offset = 0x00700000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data qnap_ts409_nor_flash_data = {
+ .width = 1,
+ .parts = qnap_ts409_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_ts409_partitions)
+};
+
+static struct resource qnap_ts409_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = QNAP_TS409_NOR_BOOT_BASE,
+ .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device qnap_ts409_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = { .platform_data = &qnap_ts409_nor_flash_data, },
+ .num_resources = 1,
+ .resource = &qnap_ts409_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI isn't used on the TS-409
+ */
+ return -1;
+}
+
+static struct hw_pci qnap_ts409_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = qnap_ts409_pci_map_irq,
+};
+
+static int __init qnap_ts409_pci_init(void)
+{
+ if (machine_is_ts409())
+ pci_common_init(&qnap_ts409_pci);
+
+ return 0;
+}
+
+subsys_initcall(qnap_ts409_pci_init);
+
+/*****************************************************************************
+ * RTC S35390A on I2C bus
+ ****************************************************************************/
+
+#define TS409_RTC_GPIO 10
+
+static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+static struct gpio_led ts409_led_pins[] = {
+ {
+ .name = "ts409:red:sata1",
+ .gpio = 4,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata2",
+ .gpio = 5,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata3",
+ .gpio = 6,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata4",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data ts409_led_data = {
+ .leds = ts409_led_pins,
+ .num_leds = ARRAY_SIZE(ts409_led_pins),
+};
+
+static struct platform_device ts409_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts409_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ * Power button is attached to the PIC microcontroller
+ ****************************************************************************/
+
+#define QNAP_TS409_GPIO_KEY_RESET 14
+#define QNAP_TS409_GPIO_KEY_MEDIA 15
+
+static struct gpio_keys_button qnap_ts409_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = QNAP_TS409_GPIO_KEY_RESET,
+ .desc = "Reset Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_COPY,
+ .gpio = QNAP_TS409_GPIO_KEY_MEDIA,
+ .desc = "USB Copy Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts409_button_data = {
+ .buttons = qnap_ts409_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts409_buttons),
+};
+
+static struct platform_device qnap_ts409_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts409_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int ts409_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_UNUSED,
+ MPP2_UNUSED,
+ MPP3_UNUSED,
+ MPP4_GPIO, /* HDD 1 status */
+ MPP5_GPIO, /* HDD 2 status */
+ MPP6_GPIO, /* HDD 3 status */
+ MPP7_GPIO, /* HDD 4 status */
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_GPIO, /* RTC int */
+ MPP11_UNUSED,
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_GPIO, /* SW_RST */
+ MPP15_GPIO, /* USB copy button */
+ MPP16_UART, /* UART1 RXD */
+ MPP17_UART, /* UART1 TXD */
+ MPP18_UNUSED,
+ MPP19_UNUSED,
+ 0,
+};
+
+static void __init qnap_ts409_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ts409_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE,
+ QNAP_TS409_NOR_BOOT_SIZE);
+ platform_device_register(&qnap_ts409_nor_flash);
+
+ orion5x_ehci0_init();
+ qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE +
+ qnap_ts409_partitions[5].offset,
+ qnap_ts409_partitions[5].size);
+ orion5x_eth_init(&qnap_tsx09_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
+ platform_device_register(&qnap_ts409_button_device);
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TS409_RTC_GPIO) == 0)
+ qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO);
+ else
+ gpio_free(TS409_RTC_GPIO);
+ }
+ if (qnap_ts409_i2c_rtc.irq == 0)
+ pr_warning("qnap_ts409_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
+ platform_device_register(&ts409_leds);
+
+ /* register tsx09 specific power-off method */
+ pm_power_off = qnap_tsx09_power_off;
+}
+
+MACHINE_START(TS409, "QNAP TS-409")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts409_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ts78xx-fpga.h b/arch/arm/mach-orion5x/ts78xx-fpga.h
new file mode 100644
index 00000000..151e89e1
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-fpga.h
@@ -0,0 +1,41 @@
+#define TS7800_FPGA_MAGIC 0x00b480
+#define FPGAID(_magic, _rev) ((_magic << 8) + _rev)
+
+/*
+ * get yer id's from http://ts78xx.digriz.org.uk/
+ * do *not* make up your own or 'borrow' any!
+ */
+enum fpga_ids {
+ /* Technologic Systems */
+ TS7800_REV_1 = FPGAID(TS7800_FPGA_MAGIC, 0x01),
+ TS7800_REV_2 = FPGAID(TS7800_FPGA_MAGIC, 0x02),
+ TS7800_REV_3 = FPGAID(TS7800_FPGA_MAGIC, 0x03),
+ TS7800_REV_4 = FPGAID(TS7800_FPGA_MAGIC, 0x04),
+ TS7800_REV_5 = FPGAID(TS7800_FPGA_MAGIC, 0x05),
+ TS7800_REV_6 = FPGAID(TS7800_FPGA_MAGIC, 0x06),
+ TS7800_REV_7 = FPGAID(TS7800_FPGA_MAGIC, 0x07),
+ TS7800_REV_8 = FPGAID(TS7800_FPGA_MAGIC, 0x08),
+ TS7800_REV_9 = FPGAID(TS7800_FPGA_MAGIC, 0x09),
+
+ /* Unaffordable & Expensive */
+ UAE_DUMMY = FPGAID(0xffffff, 0x01),
+};
+
+struct fpga_device {
+ unsigned present:1;
+ unsigned init:1;
+};
+
+struct fpga_devices {
+ /* Technologic Systems */
+ struct fpga_device ts_rtc;
+ struct fpga_device ts_nand;
+ struct fpga_device ts_rng;
+};
+
+struct ts78xx_fpga_data {
+ unsigned int id;
+ int state;
+
+ struct fpga_devices supports;
+};
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
new file mode 100644
index 00000000..6b7b5411
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -0,0 +1,630 @@
+/*
+ * arch/arm/mach-orion5x/ts78xx-setup.c
+ *
+ * Maintainer: Alexander Clouter <alex@digriz.org.uk>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/m48t86.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/timeriomem-rng.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+#include "ts78xx-fpga.h"
+
+/*****************************************************************************
+ * TS-78xx Info
+ ****************************************************************************/
+
+/*
+ * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE
+ */
+#define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000
+#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000
+#define TS78XX_FPGA_REGS_SIZE SZ_1M
+
+static struct ts78xx_fpga_data ts78xx_fpga = {
+ .id = 0,
+ .state = 1,
+/* .supports = ... - populated by ts78xx_fpga_supports() */
+};
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc ts78xx_io_desc[] __initdata = {
+ {
+ .virtual = TS78XX_FPGA_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
+ .length = TS78XX_FPGA_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init ts78xx_map_io(void)
+{
+ orion5x_map_io();
+ iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
+}
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data ts78xx_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data ts78xx_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
+ ****************************************************************************/
+#define TS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
+#define TS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+
+static unsigned char ts78xx_ts_rtc_readbyte(unsigned long addr)
+{
+ writeb(addr, TS_RTC_CTRL);
+ return readb(TS_RTC_DATA);
+}
+
+static void ts78xx_ts_rtc_writebyte(unsigned char value, unsigned long addr)
+{
+ writeb(addr, TS_RTC_CTRL);
+ writeb(value, TS_RTC_DATA);
+}
+
+static struct m48t86_ops ts78xx_ts_rtc_ops = {
+ .readbyte = ts78xx_ts_rtc_readbyte,
+ .writebyte = ts78xx_ts_rtc_writebyte,
+};
+
+static struct platform_device ts78xx_ts_rtc_device = {
+ .name = "rtc-m48t86",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_ts_rtc_ops,
+ },
+ .num_resources = 0,
+};
+
+/*
+ * TS uses some of the user storage space on the RTC chip so see if it is
+ * present; as it's an optional feature at purchase time and not all boards
+ * will have it present
+ *
+ * I've used the method TS use in their rtc7800.c example for the detection
+ *
+ * TODO: track down a guinea pig without an RTC to see if we can work out a
+ * better RTC detection routine
+ */
+static int ts78xx_ts_rtc_load(void)
+{
+ int rc;
+ unsigned char tmp_rtc0, tmp_rtc1;
+
+ tmp_rtc0 = ts78xx_ts_rtc_readbyte(126);
+ tmp_rtc1 = ts78xx_ts_rtc_readbyte(127);
+
+ ts78xx_ts_rtc_writebyte(0x00, 126);
+ ts78xx_ts_rtc_writebyte(0x55, 127);
+ if (ts78xx_ts_rtc_readbyte(127) == 0x55) {
+ ts78xx_ts_rtc_writebyte(0xaa, 127);
+ if (ts78xx_ts_rtc_readbyte(127) == 0xaa
+ && ts78xx_ts_rtc_readbyte(126) == 0x00) {
+ ts78xx_ts_rtc_writebyte(tmp_rtc0, 126);
+ ts78xx_ts_rtc_writebyte(tmp_rtc1, 127);
+
+ if (ts78xx_fpga.supports.ts_rtc.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_rtc_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_rtc.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_rtc_device);
+
+ return rc;
+ }
+ }
+
+ return -ENODEV;
+};
+
+static void ts78xx_ts_rtc_unload(void)
+{
+ platform_device_del(&ts78xx_ts_rtc_device);
+}
+
+/*****************************************************************************
+ * NAND Flash
+ ****************************************************************************/
+#define TS_NAND_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x800) /* VIRT */
+#define TS_NAND_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x804) /* PHYS */
+
+/*
+ * hardware specific access to control-lines
+ *
+ * ctrl:
+ * NAND_NCE: bit 0 -> bit 2
+ * NAND_CLE: bit 1 -> bit 1
+ * NAND_ALE: bit 2 -> bit 0
+ */
+static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ unsigned char bits;
+
+ bits = (ctrl & NAND_NCE) << 2;
+ bits |= ctrl & NAND_CLE;
+ bits |= (ctrl & NAND_ALE) >> 2;
+
+ writeb((readb(TS_NAND_CTRL) & ~0x7) | bits, TS_NAND_CTRL);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W);
+}
+
+static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
+{
+ return readb(TS_NAND_CTRL) & 0x20;
+}
+
+static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ void __iomem *io_base = chip->IO_ADDR_W;
+ unsigned long off = ((unsigned long)buf & 3);
+ int sz;
+
+ if (off) {
+ sz = min_t(int, 4 - off, len);
+ writesb(io_base, buf, sz);
+ buf += sz;
+ len -= sz;
+ }
+
+ sz = len >> 2;
+ if (sz) {
+ u32 *buf32 = (u32 *)buf;
+ writesl(io_base, buf32, sz);
+ buf += sz << 2;
+ len -= sz << 2;
+ }
+
+ if (len)
+ writesb(io_base, buf, len);
+}
+
+static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd,
+ uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+ void __iomem *io_base = chip->IO_ADDR_R;
+ unsigned long off = ((unsigned long)buf & 3);
+ int sz;
+
+ if (off) {
+ sz = min_t(int, 4 - off, len);
+ readsb(io_base, buf, sz);
+ buf += sz;
+ len -= sz;
+ }
+
+ sz = len >> 2;
+ if (sz) {
+ u32 *buf32 = (u32 *)buf;
+ readsl(io_base, buf32, sz);
+ buf += sz << 2;
+ len -= sz << 2;
+ }
+
+ if (len)
+ readsb(io_base, buf, len);
+}
+
+const char *ts_nand_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition ts78xx_ts_nand_parts[] = {
+ {
+ .name = "mbr",
+ .offset = 0,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ }, {
+ .name = "initrd",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct platform_nand_data ts78xx_ts_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .part_probe_types = ts_nand_part_probes,
+ .partitions = ts78xx_ts_nand_parts,
+ .nr_partitions = ARRAY_SIZE(ts78xx_ts_nand_parts),
+ .chip_delay = 15,
+ .options = NAND_USE_FLASH_BBT,
+ },
+ .ctrl = {
+ /*
+ * The HW ECC offloading functions, used to give about a 9%
+ * performance increase for 'dd if=/dev/mtdblockX' and 5% for
+ * nanddump. This all however was changed by git commit
+ * e6cf5df1838c28bb060ac45b5585e48e71bbc740 so now there is
+ * no performance advantage to be had so we no longer bother
+ */
+ .cmd_ctrl = ts78xx_ts_nand_cmd_ctrl,
+ .dev_ready = ts78xx_ts_nand_dev_ready,
+ .write_buf = ts78xx_ts_nand_write_buf,
+ .read_buf = ts78xx_ts_nand_read_buf,
+ },
+};
+
+static struct resource ts78xx_ts_nand_resources = {
+ .start = TS_NAND_DATA,
+ .end = TS_NAND_DATA + 4,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ts78xx_ts_nand_device = {
+ .name = "gen_nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_ts_nand_data,
+ },
+ .resource = &ts78xx_ts_nand_resources,
+ .num_resources = 1,
+};
+
+static int ts78xx_ts_nand_load(void)
+{
+ int rc;
+
+ if (ts78xx_fpga.supports.ts_nand.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_nand_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_nand.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_nand_device);
+
+ return rc;
+};
+
+static void ts78xx_ts_nand_unload(void)
+{
+ platform_device_del(&ts78xx_ts_nand_device);
+}
+
+/*****************************************************************************
+ * HW RNG
+ ****************************************************************************/
+#define TS_RNG_DATA (TS78XX_FPGA_REGS_PHYS_BASE | 0x044)
+
+static struct resource ts78xx_ts_rng_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TS_RNG_DATA,
+ .end = TS_RNG_DATA + 4 - 1,
+};
+
+static struct timeriomem_rng_data ts78xx_ts_rng_data = {
+ .period = 1000000, /* one second */
+};
+
+static struct platform_device ts78xx_ts_rng_device = {
+ .name = "timeriomem_rng",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_ts_rng_data,
+ },
+ .resource = &ts78xx_ts_rng_resource,
+ .num_resources = 1,
+};
+
+static int ts78xx_ts_rng_load(void)
+{
+ int rc;
+
+ if (ts78xx_fpga.supports.ts_rng.init == 0) {
+ rc = platform_device_register(&ts78xx_ts_rng_device);
+ if (!rc)
+ ts78xx_fpga.supports.ts_rng.init = 1;
+ } else
+ rc = platform_device_add(&ts78xx_ts_rng_device);
+
+ return rc;
+};
+
+static void ts78xx_ts_rng_unload(void)
+{
+ platform_device_del(&ts78xx_ts_rng_device);
+}
+
+/*****************************************************************************
+ * FPGA 'hotplug' support code
+ ****************************************************************************/
+static void ts78xx_fpga_devices_zero_init(void)
+{
+ ts78xx_fpga.supports.ts_rtc.init = 0;
+ ts78xx_fpga.supports.ts_nand.init = 0;
+ ts78xx_fpga.supports.ts_rng.init = 0;
+}
+
+static void ts78xx_fpga_supports(void)
+{
+ /* TODO: put this 'table' into ts78xx-fpga.h */
+ switch (ts78xx_fpga.id) {
+ case TS7800_REV_1:
+ case TS7800_REV_2:
+ case TS7800_REV_3:
+ case TS7800_REV_4:
+ case TS7800_REV_5:
+ case TS7800_REV_6:
+ case TS7800_REV_7:
+ case TS7800_REV_8:
+ case TS7800_REV_9:
+ ts78xx_fpga.supports.ts_rtc.present = 1;
+ ts78xx_fpga.supports.ts_nand.present = 1;
+ ts78xx_fpga.supports.ts_rng.present = 1;
+ break;
+ default:
+ /* enable devices if magic matches */
+ switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
+ case TS7800_FPGA_MAGIC:
+ pr_warning("TS-7800 FPGA: unrecognized revision 0x%.2x\n",
+ ts78xx_fpga.id & 0xff);
+ ts78xx_fpga.supports.ts_rtc.present = 1;
+ ts78xx_fpga.supports.ts_nand.present = 1;
+ ts78xx_fpga.supports.ts_rng.present = 1;
+ break;
+ default:
+ ts78xx_fpga.supports.ts_rtc.present = 0;
+ ts78xx_fpga.supports.ts_nand.present = 0;
+ ts78xx_fpga.supports.ts_rng.present = 0;
+ }
+ }
+}
+
+static int ts78xx_fpga_load_devices(void)
+{
+ int tmp, ret = 0;
+
+ if (ts78xx_fpga.supports.ts_rtc.present == 1) {
+ tmp = ts78xx_ts_rtc_load();
+ if (tmp) {
+ pr_info("TS-78xx: RTC not registered\n");
+ ts78xx_fpga.supports.ts_rtc.present = 0;
+ }
+ ret |= tmp;
+ }
+ if (ts78xx_fpga.supports.ts_nand.present == 1) {
+ tmp = ts78xx_ts_nand_load();
+ if (tmp) {
+ pr_info("TS-78xx: NAND not registered\n");
+ ts78xx_fpga.supports.ts_nand.present = 0;
+ }
+ ret |= tmp;
+ }
+ if (ts78xx_fpga.supports.ts_rng.present == 1) {
+ tmp = ts78xx_ts_rng_load();
+ if (tmp) {
+ pr_info("TS-78xx: RNG not registered\n");
+ ts78xx_fpga.supports.ts_rng.present = 0;
+ }
+ ret |= tmp;
+ }
+
+ return ret;
+}
+
+static int ts78xx_fpga_unload_devices(void)
+{
+ int ret = 0;
+
+ if (ts78xx_fpga.supports.ts_rtc.present == 1)
+ ts78xx_ts_rtc_unload();
+ if (ts78xx_fpga.supports.ts_nand.present == 1)
+ ts78xx_ts_nand_unload();
+ if (ts78xx_fpga.supports.ts_rng.present == 1)
+ ts78xx_ts_rng_unload();
+
+ return ret;
+}
+
+static int ts78xx_fpga_load(void)
+{
+ ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+ pr_info("TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+ (ts78xx_fpga.id >> 8) & 0xffffff,
+ ts78xx_fpga.id & 0xff);
+
+ ts78xx_fpga_supports();
+
+ if (ts78xx_fpga_load_devices()) {
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ return 0;
+};
+
+static int ts78xx_fpga_unload(void)
+{
+ unsigned int fpga_id;
+
+ fpga_id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
+
+ /*
+ * There does not seem to be a feasible way to block access to the GPIO
+ * pins from userspace (/dev/mem). This if clause should hopefully warn
+ * those foolish enough not to follow 'policy' :)
+ *
+ * UrJTAG SVN since r1381 can be used to reprogram the FPGA
+ */
+ if (ts78xx_fpga.id != fpga_id) {
+ pr_err("TS-78xx FPGA: magic/rev mismatch\n"
+ "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
+ (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
+ (fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ if (ts78xx_fpga_unload_devices()) {
+ ts78xx_fpga.state = -1;
+ return -EBUSY;
+ }
+
+ return 0;
+};
+
+static ssize_t ts78xx_fpga_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ if (ts78xx_fpga.state < 0)
+ return sprintf(buf, "borked\n");
+
+ return sprintf(buf, "%s\n", (ts78xx_fpga.state) ? "online" : "offline");
+}
+
+static ssize_t ts78xx_fpga_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t n)
+{
+ int value, ret;
+
+ if (ts78xx_fpga.state < 0) {
+ pr_err("TS-78xx FPGA: borked, you must powercycle asap\n");
+ return -EBUSY;
+ }
+
+ if (strncmp(buf, "online", sizeof("online") - 1) == 0)
+ value = 1;
+ else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
+ value = 0;
+ else {
+ pr_err("ts78xx_fpga_store: Invalid value\n");
+ return -EINVAL;
+ }
+
+ if (ts78xx_fpga.state == value)
+ return n;
+
+ ret = (ts78xx_fpga.state == 0)
+ ? ts78xx_fpga_load()
+ : ts78xx_fpga_unload();
+
+ if (!(ret < 0))
+ ts78xx_fpga.state = value;
+
+ return n;
+}
+
+static struct kobj_attribute ts78xx_fpga_attr =
+ __ATTR(ts78xx_fpga, 0644, ts78xx_fpga_show, ts78xx_fpga_store);
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static unsigned int ts78xx_mpp_modes[] __initdata = {
+ MPP0_UNUSED,
+ MPP1_GPIO, /* JTAG Clock */
+ MPP2_GPIO, /* JTAG Data In */
+ MPP3_GPIO, /* Lat ECP2 256 FPGA - PB2B */
+ MPP4_GPIO, /* JTAG Data Out */
+ MPP5_GPIO, /* JTAG TMS */
+ MPP6_GPIO, /* Lat ECP2 256 FPGA - PB31A_CLK4+ */
+ MPP7_GPIO, /* Lat ECP2 256 FPGA - PB22B */
+ MPP8_UNUSED,
+ MPP9_UNUSED,
+ MPP10_UNUSED,
+ MPP11_UNUSED,
+ MPP12_UNUSED,
+ MPP13_UNUSED,
+ MPP14_UNUSED,
+ MPP15_UNUSED,
+ MPP16_UART,
+ MPP17_UART,
+ MPP18_UART,
+ MPP19_UART,
+ /*
+ * MPP[20] PCI Clock Out 1
+ * MPP[21] PCI Clock Out 0
+ * MPP[22] Unused
+ * MPP[23] Unused
+ * MPP[24] Unused
+ * MPP[25] Unused
+ */
+ 0,
+};
+
+static void __init ts78xx_init(void)
+{
+ int ret;
+
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ts78xx_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&ts78xx_eth_data);
+ orion5x_sata_init(&ts78xx_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
+
+ /* FPGA init */
+ ts78xx_fpga_devices_zero_init();
+ ret = ts78xx_fpga_load();
+ ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
+ if (ret)
+ pr_err("sysfs_create_file failed: %d\n", ret);
+}
+
+MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
+ /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
+ .boot_params = 0x00000100,
+ .init_machine = ts78xx_init,
+ .map_io = ts78xx_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c
new file mode 100644
index 00000000..c9abb8fb
--- /dev/null
+++ b/arch/arm/mach-orion5x/tsx09-common.c
@@ -0,0 +1,134 @@
+/*
+ * QNAP TS-x09 Boards common functions
+ *
+ * Maintainers: Lennert Buytenhek <buytenh@marvell.com>
+ * Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/timex.h>
+#include <linux/serial_reg.h>
+#include "tsx09-common.h"
+#include "common.h"
+
+/*****************************************************************************
+ * QNAP TS-x09 specific power off method via UART1-attached PIC
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+void qnap_tsx09_power_off(void)
+{
+ /* 19200 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (19200,8n1) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x03, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x00, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* send the power-off command 'A' to PIC */
+ writel('A', UART1_REG(TX));
+}
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static int __init qnap_tsx09_parse_hex_nibble(char n)
+{
+ if (n >= '0' && n <= '9')
+ return n - '0';
+
+ if (n >= 'A' && n <= 'F')
+ return n - 'A' + 10;
+
+ if (n >= 'a' && n <= 'f')
+ return n - 'a' + 10;
+
+ return -1;
+}
+
+static int __init qnap_tsx09_parse_hex_byte(const char *b)
+{
+ int hi;
+ int lo;
+
+ hi = qnap_tsx09_parse_hex_nibble(b[0]);
+ lo = qnap_tsx09_parse_hex_nibble(b[1]);
+
+ if (hi < 0 || lo < 0)
+ return -1;
+
+ return (hi << 4) | lo;
+}
+
+static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
+{
+ u_int8_t addr[6];
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ int byte;
+
+ /*
+ * Enforce "xx:xx:xx:xx:xx:xx\n" format.
+ */
+ if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
+ return -1;
+
+ byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
+ if (byte < 0)
+ return -1;
+ addr[i] = byte;
+ }
+
+ printk(KERN_INFO "tsx09: found ethernet mac address ");
+ for (i = 0; i < 6; i++)
+ printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
+
+ memcpy(qnap_tsx09_eth_data.mac_addr, addr, 6);
+
+ return 0;
+}
+
+/*
+ * The 'NAS Config' flash partition has an ext2 filesystem which
+ * contains a file that has the ethernet MAC address in plain text
+ * (format "xx:xx:xx:xx:xx:xx\n").
+ */
+void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
+{
+ unsigned long addr;
+
+ for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
+ char *nor_page;
+ int ret = 0;
+
+ nor_page = ioremap(addr, 1024);
+ if (nor_page != NULL) {
+ ret = qnap_tsx09_check_mac_addr(nor_page);
+ iounmap(nor_page);
+ }
+
+ if (ret == 0)
+ break;
+ }
+}
diff --git a/arch/arm/mach-orion5x/tsx09-common.h b/arch/arm/mach-orion5x/tsx09-common.h
new file mode 100644
index 00000000..09842646
--- /dev/null
+++ b/arch/arm/mach-orion5x/tsx09-common.h
@@ -0,0 +1,20 @@
+#ifndef __ARCH_ORION5X_TSX09_COMMON_H
+#define __ARCH_ORION5X_TSX09_COMMON_H
+
+/*
+ * QNAP TS-x09 Boards power-off function
+ */
+extern void qnap_tsx09_power_off(void);
+
+/*
+ * QNAP TS-x09 Boards function to find Ethernet MAC address in flash memory
+ */
+extern void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size);
+
+/*
+ * QNAP TS-x09 Boards ethernet declaration
+ */
+extern struct mv643xx_eth_platform_data qnap_tsx09_eth_data;
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
new file mode 100644
index 00000000..444a1c7f
--- /dev/null
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -0,0 +1,182 @@
+/*
+ * arch/arm/mach-orion5x/wnr854t-setup.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+static unsigned int wnr854t_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Power LED green (0=on) */
+ MPP1_GPIO, /* Reset Button (0=off) */
+ MPP2_GPIO, /* Power LED blink (0=off) */
+ MPP3_GPIO, /* WAN Status LED amber (0=off) */
+ MPP4_GPIO, /* PCI int */
+ MPP5_GPIO, /* ??? */
+ MPP6_GPIO, /* ??? */
+ MPP7_GPIO, /* ??? */
+ MPP8_UNUSED, /* ??? */
+ MPP9_GIGE, /* GE_RXERR */
+ MPP10_UNUSED, /* ??? */
+ MPP11_UNUSED, /* ??? */
+ MPP12_GIGE, /* GE_TXD[4] */
+ MPP13_GIGE, /* GE_TXD[5] */
+ MPP14_GIGE, /* GE_TXD[6] */
+ MPP15_GIGE, /* GE_TXD[7] */
+ MPP16_GIGE, /* GE_RXD[4] */
+ MPP17_GIGE, /* GE_RXD[5] */
+ MPP18_GIGE, /* GE_RXD[6] */
+ MPP19_GIGE, /* GE_RXD[7] */
+ 0,
+};
+
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define WNR854T_NOR_BOOT_BASE 0xf4000000
+#define WNR854T_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition wnr854t_nor_flash_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00100000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x00100000,
+ .size = 0x00660000,
+ }, {
+ .name = "uboot",
+ .offset = 0x00760000,
+ .size = 0x00040000,
+ },
+};
+
+static struct physmap_flash_data wnr854t_nor_flash_data = {
+ .width = 2,
+ .parts = wnr854t_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(wnr854t_nor_flash_partitions),
+};
+
+static struct resource wnr854t_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = WNR854T_NOR_BOOT_BASE,
+ .end = WNR854T_NOR_BOOT_BASE + WNR854T_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device wnr854t_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &wnr854t_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &wnr854t_nor_flash_resource,
+};
+
+static struct mv643xx_eth_platform_data wnr854t_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data wnr854t_switch_chip_data = {
+ .port_names[0] = "lan3",
+ .port_names[1] = "lan4",
+ .port_names[2] = "wan",
+ .port_names[3] = "cpu",
+ .port_names[5] = "lan1",
+ .port_names[7] = "lan2",
+};
+
+static struct dsa_platform_data wnr854t_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &wnr854t_switch_chip_data,
+};
+
+static void __init wnr854t_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(wnr854t_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_eth_init(&wnr854t_eth_data);
+ orion5x_eth_switch_init(&wnr854t_switch_plat_data, NO_IRQ);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
+ WNR854T_NOR_BOOT_SIZE);
+ platform_device_register(&wnr854t_nor_flash);
+}
+
+static int __init wnr854t_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI slot.
+ */
+ if (slot == 7)
+ return gpio_to_irq(4);
+
+ return -1;
+}
+
+static struct hw_pci wnr854t_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = wnr854t_pci_map_irq,
+};
+
+static int __init wnr854t_pci_init(void)
+{
+ if (machine_is_wnr854t())
+ pci_common_init(&wnr854t_pci);
+
+ return 0;
+}
+subsys_initcall(wnr854t_pci_init);
+
+MACHINE_START(WNR854T, "Netgear WNR854T")
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+ .boot_params = 0x00000100,
+ .init_machine = wnr854t_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
new file mode 100644
index 00000000..d1952be0
--- /dev/null
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -0,0 +1,270 @@
+/*
+ * arch/arm/mach-orion5x/wrt350n-v2-setup.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <net/dsa.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*
+ * LEDs attached to GPIO
+ */
+static struct gpio_led wrt350n_v2_led_pins[] = {
+ {
+ .name = "wrt350nv2:green:power",
+ .gpio = 0,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:security",
+ .gpio = 1,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:orange:power",
+ .gpio = 5,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:usb",
+ .gpio = 6,
+ .active_low = 1,
+ }, {
+ .name = "wrt350nv2:green:wireless",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data wrt350n_v2_led_data = {
+ .leds = wrt350n_v2_led_pins,
+ .num_leds = ARRAY_SIZE(wrt350n_v2_led_pins),
+};
+
+static struct platform_device wrt350n_v2_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wrt350n_v2_led_data,
+ },
+};
+
+/*
+ * Buttons attached to GPIO
+ */
+static struct gpio_keys_button wrt350n_v2_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = 3,
+ .desc = "Reset Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_WPS_BUTTON,
+ .gpio = 2,
+ .desc = "WPS Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data wrt350n_v2_button_data = {
+ .buttons = wrt350n_v2_buttons,
+ .nbuttons = ARRAY_SIZE(wrt350n_v2_buttons),
+};
+
+static struct platform_device wrt350n_v2_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &wrt350n_v2_button_data,
+ },
+};
+
+/*
+ * General setup
+ */
+static unsigned int wrt350n_v2_mpp_modes[] __initdata = {
+ MPP0_GPIO, /* Power LED green (0=on) */
+ MPP1_GPIO, /* Security LED (0=on) */
+ MPP2_GPIO, /* Internal Button (0=on) */
+ MPP3_GPIO, /* Reset Button (0=on) */
+ MPP4_GPIO, /* PCI int */
+ MPP5_GPIO, /* Power LED orange (0=on) */
+ MPP6_GPIO, /* USB LED (0=on) */
+ MPP7_GPIO, /* Wireless LED (0=on) */
+ MPP8_UNUSED, /* ??? */
+ MPP9_GIGE, /* GE_RXERR */
+ MPP10_UNUSED, /* ??? */
+ MPP11_UNUSED, /* ??? */
+ MPP12_GIGE, /* GE_TXD[4] */
+ MPP13_GIGE, /* GE_TXD[5] */
+ MPP14_GIGE, /* GE_TXD[6] */
+ MPP15_GIGE, /* GE_TXD[7] */
+ MPP16_GIGE, /* GE_RXD[4] */
+ MPP17_GIGE, /* GE_RXD[5] */
+ MPP18_GIGE, /* GE_RXD[6] */
+ MPP19_GIGE, /* GE_RXD[7] */
+ 0,
+};
+
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define WRT350N_V2_NOR_BOOT_BASE 0xf4000000
+#define WRT350N_V2_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00760000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x001a0000,
+ .size = 0x005c0000,
+ }, {
+ .name = "lang",
+ .offset = 0x00760000,
+ .size = 0x00040000,
+ }, {
+ .name = "nvram",
+ .offset = 0x007a0000,
+ .size = 0x00020000,
+ }, {
+ .name = "u-boot",
+ .offset = 0x007c0000,
+ .size = 0x00040000,
+ },
+};
+
+static struct physmap_flash_data wrt350n_v2_nor_flash_data = {
+ .width = 1,
+ .parts = wrt350n_v2_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions),
+};
+
+static struct resource wrt350n_v2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = WRT350N_V2_NOR_BOOT_BASE,
+ .end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device wrt350n_v2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &wrt350n_v2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &wrt350n_v2_nor_flash_resource,
+};
+
+static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
+ .port_names[0] = "lan2",
+ .port_names[1] = "lan1",
+ .port_names[2] = "wan",
+ .port_names[3] = "cpu",
+ .port_names[5] = "lan3",
+ .port_names[7] = "lan4",
+};
+
+static struct dsa_platform_data wrt350n_v2_switch_plat_data = {
+ .nr_chips = 1,
+ .chip = &wrt350n_v2_switch_chip_data,
+};
+
+static void __init wrt350n_v2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(wrt350n_v2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&wrt350n_v2_eth_data);
+ orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
+ WRT350N_V2_NOR_BOOT_SIZE);
+ platform_device_register(&wrt350n_v2_nor_flash);
+ platform_device_register(&wrt350n_v2_leds);
+ platform_device_register(&wrt350n_v2_button_device);
+}
+
+static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI slot.
+ */
+ if (slot == 7)
+ return gpio_to_irq(4);
+
+ return -1;
+}
+
+static struct hw_pci wrt350n_v2_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = wrt350n_v2_pci_map_irq,
+};
+
+static int __init wrt350n_v2_pci_init(void)
+{
+ if (machine_is_wrt350n_v2())
+ pci_common_init(&wrt350n_v2_pci);
+
+ return 0;
+}
+subsys_initcall(wrt350n_v2_pci_init);
+
+MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .boot_params = 0x00000100,
+ .init_machine = wrt350n_v2_init,
+ .map_io = orion5x_map_io,
+ .init_early = orion5x_init_early,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-pnx4008/Makefile b/arch/arm/mach-pnx4008/Makefile
new file mode 100644
index 00000000..777564c9
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o i2c.o
+obj-m :=
+obj-n :=
+obj- :=
+
+# Power Management
+obj-$(CONFIG_PM) += pm.o sleep.o
+
diff --git a/arch/arm/mach-pnx4008/Makefile.boot b/arch/arm/mach-pnx4008/Makefile.boot
new file mode 100644
index 00000000..44c7117e
--- /dev/null
+++ b/arch/arm/mach-pnx4008/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
+
diff --git a/arch/arm/mach-pnx4008/clock.c b/arch/arm/mach-pnx4008/clock.c
new file mode 100644
index 00000000..a4a3819c
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.c
@@ -0,0 +1,1001 @@
+/*
+ * arch/arm/mach-pnx4008/clock.c
+ *
+ * Clock control driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ * Generic clock management functions are partially based on:
+ * linux/arch/arm/mach-omap/clock.c
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include "clock.h"
+
+/*forward declaration*/
+static struct clk per_ck;
+static struct clk hclk_ck;
+static struct clk ck_1MHz;
+static struct clk ck_13MHz;
+static struct clk ck_pll1;
+static int local_set_rate(struct clk *clk, u32 rate);
+
+static inline void clock_lock(void)
+{
+ local_irq_disable();
+}
+
+static inline void clock_unlock(void)
+{
+ local_irq_enable();
+}
+
+static void propagate_rate(struct clk *clk)
+{
+ struct clk *tmp_clk;
+
+ tmp_clk = clk;
+ while (tmp_clk->propagate_next) {
+ tmp_clk = tmp_clk->propagate_next;
+ local_set_rate(tmp_clk, tmp_clk->user_rate);
+ }
+}
+
+static void clk_reg_disable(struct clk *clk)
+{
+ if (clk->enable_reg)
+ __raw_writel(__raw_readl(clk->enable_reg) &
+ ~(1 << clk->enable_shift), clk->enable_reg);
+}
+
+static int clk_reg_enable(struct clk *clk)
+{
+ if (clk->enable_reg)
+ __raw_writel(__raw_readl(clk->enable_reg) |
+ (1 << clk->enable_shift), clk->enable_reg);
+ return 0;
+}
+
+static inline void clk_reg_disable1(struct clk *clk)
+{
+ if (clk->enable_reg1)
+ __raw_writel(__raw_readl(clk->enable_reg1) &
+ ~(1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static inline void clk_reg_enable1(struct clk *clk)
+{
+ if (clk->enable_reg1)
+ __raw_writel(__raw_readl(clk->enable_reg1) |
+ (1 << clk->enable_shift1), clk->enable_reg1);
+}
+
+static int clk_wait_for_pll_lock(struct clk *clk)
+{
+ int i;
+ i = 0;
+ while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
+
+ if (!(__raw_readl(clk->scale_reg) & 1)) {
+ printk(KERN_ERR
+ "%s ERROR: failed to lock, scale reg data: %x\n",
+ clk->name, __raw_readl(clk->scale_reg));
+ return -1;
+ }
+ return 0;
+}
+
+static int switch_to_dirty_13mhz(struct clk *clk)
+{
+ int i;
+ int ret;
+ u32 tmp_reg;
+
+ ret = 0;
+
+ if (!clk->rate)
+ clk_reg_enable1(clk);
+
+ tmp_reg = __raw_readl(clk->parent_switch_reg);
+ /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
+ if (!(tmp_reg & 1)) {
+ tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
+ __raw_writel(tmp_reg, clk->parent_switch_reg);
+ i = 0;
+ while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
+
+ if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
+ printk(KERN_ERR
+ "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
+ clk->name, __raw_readl(clk->parent_switch_reg));
+ ret = -1;
+ }
+ }
+
+ if (!clk->rate)
+ clk_reg_disable1(clk);
+
+ return ret;
+}
+
+static int switch_to_clean_13mhz(struct clk *clk)
+{
+ int i;
+ int ret;
+ u32 tmp_reg;
+
+ ret = 0;
+
+ if (!clk->rate)
+ clk_reg_enable1(clk);
+
+ tmp_reg = __raw_readl(clk->parent_switch_reg);
+ /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
+ if (tmp_reg & 1) {
+ tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
+ __raw_writel(tmp_reg, clk->parent_switch_reg);
+ i = 0;
+ while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
+
+ if (__raw_readl(clk->parent_switch_reg) & 1) {
+ printk(KERN_ERR
+ "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
+ clk->name, __raw_readl(clk->parent_switch_reg));
+ ret = -1;
+ }
+ }
+
+ if (!clk->rate)
+ clk_reg_disable1(clk);
+
+ return ret;
+}
+
+static int set_13MHz_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+
+ if (parent == &ck_13MHz)
+ ret = switch_to_clean_13mhz(clk);
+ else if (parent == &ck_pll1)
+ ret = switch_to_dirty_13mhz(clk);
+
+ return ret;
+}
+
+#define PLL160_MIN_FCCO 156000
+#define PLL160_MAX_FCCO 320000
+
+/*
+ * Calculate pll160 settings.
+ * Possible input: up to 320MHz with step of clk->parent->rate.
+ * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
+ * Ignored paths: "feedback" (bit 13 set), "div-by-N".
+ * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
+ * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
+ * Please refer to PNX4008 IC manual for details.
+ */
+
+static int pll160_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp_reg, tmp_m, tmp_2p, i;
+ u32 parent_rate;
+ int ret = -EINVAL;
+
+ parent_rate = clk->parent->rate;
+
+ if (!parent_rate)
+ goto out;
+
+ /* set direct run for ARM or disable output for others */
+ clk_reg_disable(clk);
+
+ /* disable source input as well (ignored for ARM) */
+ clk_reg_disable1(clk);
+
+ tmp_reg = __raw_readl(clk->scale_reg);
+ tmp_reg &= ~0x1ffff; /*clear all settings, power down */
+ __raw_writel(tmp_reg, clk->scale_reg);
+
+ rate -= rate % parent_rate; /*round down the input */
+
+ if (rate > PLL160_MAX_FCCO)
+ rate = PLL160_MAX_FCCO;
+
+ if (!rate) {
+ clk->rate = 0;
+ ret = 0;
+ goto out;
+ }
+
+ clk_reg_enable1(clk);
+ tmp_reg = __raw_readl(clk->scale_reg);
+
+ if (rate == parent_rate) {
+ /*enter direct bypass mode */
+ tmp_reg |= ((1 << 14) | (1 << 15));
+ __raw_writel(tmp_reg, clk->scale_reg);
+ clk->rate = parent_rate;
+ clk_reg_enable(clk);
+ ret = 0;
+ goto out;
+ }
+
+ i = 0;
+ for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
+ if (rate * tmp_2p >= PLL160_MIN_FCCO)
+ break;
+ i++;
+ }
+
+ if (tmp_2p > 1)
+ tmp_reg |= ((i - 1) << 11);
+ else
+ tmp_reg |= (1 << 14); /*direct mode, no divide */
+
+ tmp_m = rate * tmp_2p;
+ tmp_m /= parent_rate;
+
+ tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
+ tmp_reg |= (1 << 16); /*power up PLL */
+ __raw_writel(tmp_reg, clk->scale_reg);
+
+ if (clk_wait_for_pll_lock(clk) < 0) {
+ clk_reg_disable(clk);
+ clk_reg_disable1(clk);
+
+ tmp_reg = __raw_readl(clk->scale_reg);
+ tmp_reg &= ~0x1ffff; /*clear all settings, power down */
+ __raw_writel(tmp_reg, clk->scale_reg);
+ clk->rate = 0;
+ ret = -EFAULT;
+ goto out;
+ }
+
+ clk->rate = (tmp_m * parent_rate) / tmp_2p;
+
+ if (clk->flags & RATE_PROPAGATES)
+ propagate_rate(clk);
+
+ clk_reg_enable(clk);
+ ret = 0;
+
+out:
+ return ret;
+}
+
+/*configure PER_CLK*/
+static int per_clk_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(clk->scale_reg);
+ tmp &= ~(0x1f << 2);
+ tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
+ __raw_writel(tmp, clk->scale_reg);
+ clk->rate = rate;
+ return 0;
+}
+
+/*configure HCLK*/
+static int hclk_set_rate(struct clk *clk, u32 rate)
+{
+ u32 tmp;
+ tmp = __raw_readl(clk->scale_reg);
+ tmp = tmp & ~0x3;
+ switch (rate) {
+ case 1:
+ break;
+ case 2:
+ tmp |= 1;
+ break;
+ case 4:
+ tmp |= 2;
+ break;
+ }
+
+ __raw_writel(tmp, clk->scale_reg);
+ clk->rate = rate;
+ return 0;
+}
+
+static u32 hclk_round_rate(struct clk *clk, u32 rate)
+{
+ switch (rate) {
+ case 1:
+ case 4:
+ return rate;
+ }
+ return 2;
+}
+
+static u32 per_clk_round_rate(struct clk *clk, u32 rate)
+{
+ return CLK_RATE_13MHZ;
+}
+
+static int on_off_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_enable(clk);
+ clk->rate = 1;
+ } else {
+ clk_reg_disable(clk);
+ clk->rate = 0;
+ }
+ return 0;
+}
+
+static int on_off_inv_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ clk->rate = 1;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+ return 0;
+}
+
+static u32 on_off_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? 1 : 0);
+}
+
+static u32 pll4_round_rate(struct clk *clk, u32 rate)
+{
+ if (rate > CLK_RATE_208MHZ)
+ rate = CLK_RATE_208MHZ;
+ if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
+ rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
+ return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
+}
+
+static u32 pll3_round_rate(struct clk *clk, u32 rate)
+{
+ if (rate > CLK_RATE_208MHZ)
+ rate = CLK_RATE_208MHZ;
+ return (rate - rate % CLK_RATE_13MHZ);
+}
+
+static u32 pll5_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? CLK_RATE_48MHZ : 0);
+}
+
+static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
+{
+ return (rate ? CLK_RATE_13MHZ : 0);
+}
+
+static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
+{
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ udelay(500);
+ clk->rate = CLK_RATE_13MHZ;
+ ck_1MHz.rate = CLK_RATE_1MHZ;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ ck_1MHz.rate = 0;
+ }
+ return 0;
+}
+
+static int pll1_set_rate(struct clk *clk, u32 rate)
+{
+#if 0 /* doesn't work on some boards, probably a HW BUG */
+ if (rate) {
+ clk_reg_disable(clk); /*enable bit is inverted */
+ if (!clk_wait_for_pll_lock(clk)) {
+ clk->rate = CLK_RATE_13MHZ;
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+
+ } else {
+ clk_reg_enable(clk);
+ clk->rate = 0;
+ }
+#endif
+ return 0;
+}
+
+/* Clock sources */
+
+static struct clk osc_13MHz = {
+ .name = "osc_13MHz",
+ .flags = FIXED_RATE,
+ .rate = CLK_RATE_13MHZ,
+};
+
+static struct clk ck_13MHz = {
+ .name = "ck_13MHz",
+ .parent = &osc_13MHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &ck_13MHz_round_rate,
+ .set_rate = &ck_13MHz_set_rate,
+ .enable_reg = OSC13CTRL_REG,
+ .enable_shift = 0,
+ .rate = CLK_RATE_13MHZ,
+};
+
+static struct clk osc_32KHz = {
+ .name = "osc_32KHz",
+ .flags = FIXED_RATE,
+ .rate = CLK_RATE_32KHZ,
+};
+
+/*attached to PLL5*/
+static struct clk ck_1MHz = {
+ .name = "ck_1MHz",
+ .flags = FIXED_RATE | PARENT_SET_RATE,
+ .parent = &ck_13MHz,
+};
+
+/* PLL1 (397) - provides 13' MHz clock */
+static struct clk ck_pll1 = {
+ .name = "ck_pll1",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &ck_13MHz_round_rate,
+ .set_rate = &pll1_set_rate,
+ .enable_reg = PLLCTRL_REG,
+ .enable_shift = 1,
+ .scale_reg = PLLCTRL_REG,
+ .rate = CLK_RATE_13MHZ,
+};
+
+/* CPU/Bus PLL */
+static struct clk ck_pll4 = {
+ .name = "ck_pll4",
+ .parent = &ck_pll1,
+ .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
+ .propagate_next = &per_ck,
+ .round_rate = &pll4_round_rate,
+ .set_rate = &pll160_set_rate,
+ .rate = CLK_RATE_208MHZ,
+ .scale_reg = HCLKPLLCTRL_REG,
+ .enable_reg = PWRCTRL_REG,
+ .enable_shift = 2,
+ .parent_switch_reg = SYSCLKCTRL_REG,
+ .set_parent = &set_13MHz_parent,
+};
+
+/* USB PLL */
+static struct clk ck_pll5 = {
+ .name = "ck_pll5",
+ .parent = &ck_1MHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &pll5_round_rate,
+ .set_rate = &pll160_set_rate,
+ .scale_reg = USBCTRL_REG,
+ .enable_reg = USBCTRL_REG,
+ .enable_shift = 18,
+ .enable_reg1 = USBCTRL_REG,
+ .enable_shift1 = 17,
+};
+
+/* XPERTTeak DSP PLL */
+static struct clk ck_pll3 = {
+ .name = "ck_pll3",
+ .parent = &ck_pll1,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &pll3_round_rate,
+ .set_rate = &pll160_set_rate,
+ .scale_reg = DSPPLLCTRL_REG,
+ .enable_reg = DSPCLKCTRL_REG,
+ .enable_shift = 3,
+ .enable_reg1 = DSPCLKCTRL_REG,
+ .enable_shift1 = 2,
+ .parent_switch_reg = DSPCLKCTRL_REG,
+ .set_parent = &set_13MHz_parent,
+};
+
+static struct clk hclk_ck = {
+ .name = "hclk_ck",
+ .parent = &ck_pll4,
+ .flags = PARENT_SET_RATE,
+ .set_rate = &hclk_set_rate,
+ .round_rate = &hclk_round_rate,
+ .scale_reg = HCLKDIVCTRL_REG,
+ .rate = 2,
+ .user_rate = 2,
+};
+
+static struct clk per_ck = {
+ .name = "per_ck",
+ .parent = &ck_pll4,
+ .flags = FIXED_RATE,
+ .propagate_next = &hclk_ck,
+ .set_rate = &per_clk_set_rate,
+ .round_rate = &per_clk_round_rate,
+ .scale_reg = HCLKDIVCTRL_REG,
+ .rate = CLK_RATE_13MHZ,
+ .user_rate = CLK_RATE_13MHZ,
+};
+
+static struct clk m2hclk_ck = {
+ .name = "m2hclk_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_inv_set_rate,
+ .rate = 1,
+ .enable_shift = 6,
+ .enable_reg = PWRCTRL_REG,
+};
+
+static struct clk vfp9_ck = {
+ .name = "vfp9_ck",
+ .parent = &ck_pll4,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 4,
+ .enable_reg = VFP9CLKCTRL_REG,
+};
+
+static struct clk keyscan_ck = {
+ .name = "keyscan_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = KEYCLKCTRL_REG,
+};
+
+static struct clk touch_ck = {
+ .name = "touch_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = TSCLKCTRL_REG,
+};
+
+static struct clk pwm1_ck = {
+ .name = "pwm1_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk pwm2_ck = {
+ .name = "pwm2_ck",
+ .parent = &osc_32KHz,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 2,
+ .enable_reg = PWMCLKCTRL_REG,
+};
+
+static struct clk jpeg_ck = {
+ .name = "jpeg_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = JPEGCLKCTRL_REG,
+};
+
+static struct clk ms_ck = {
+ .name = "ms_ck",
+ .parent = &ck_pll4,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 5,
+ .enable_reg = MSCTRL_REG,
+};
+
+static struct clk dum_ck = {
+ .name = "dum_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = DUMCLKCTRL_REG,
+};
+
+static struct clk flash_ck = {
+ .name = "flash_ck",
+ .parent = &hclk_ck,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 1, /* Only MLC clock supported */
+ .enable_reg = FLASHCLKCTRL_REG,
+};
+
+static struct clk i2c0_ck = {
+ .name = "i2c0_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION | FIXED_RATE,
+ .enable_shift = 0,
+ .enable_reg = I2CCLKCTRL_REG,
+ .rate = 13000000,
+ .enable = clk_reg_enable,
+ .disable = clk_reg_disable,
+};
+
+static struct clk i2c1_ck = {
+ .name = "i2c1_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION | FIXED_RATE,
+ .enable_shift = 1,
+ .enable_reg = I2CCLKCTRL_REG,
+ .rate = 13000000,
+ .enable = clk_reg_enable,
+ .disable = clk_reg_disable,
+};
+
+static struct clk i2c2_ck = {
+ .name = "i2c2_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION | FIXED_RATE,
+ .enable_shift = 2,
+ .enable_reg = USB_OTG_CLKCTRL_REG,
+ .rate = 13000000,
+ .enable = clk_reg_enable,
+ .disable = clk_reg_disable,
+};
+
+static struct clk spi0_ck = {
+ .name = "spi0_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = SPICTRL_REG,
+};
+
+static struct clk spi1_ck = {
+ .name = "spi1_ck",
+ .parent = &hclk_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 4,
+ .enable_reg = SPICTRL_REG,
+};
+
+static struct clk dma_ck = {
+ .name = "dma_ck",
+ .parent = &hclk_ck,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 0,
+ .enable_reg = DMACLKCTRL_REG,
+};
+
+static struct clk uart3_ck = {
+ .name = "uart3_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 0,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart4_ck = {
+ .name = "uart4_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 1,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart5_ck = {
+ .name = "uart5_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .rate = 1,
+ .enable_shift = 2,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk uart6_ck = {
+ .name = "uart6_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .round_rate = &on_off_round_rate,
+ .set_rate = &on_off_set_rate,
+ .enable_shift = 3,
+ .enable_reg = UARTCLKCTRL_REG,
+};
+
+static struct clk wdt_ck = {
+ .name = "wdt_ck",
+ .parent = &per_ck,
+ .flags = NEEDS_INITIALIZATION,
+ .enable_shift = 0,
+ .enable_reg = TIMCLKCTRL_REG,
+ .enable = clk_reg_enable,
+ .disable = clk_reg_disable,
+};
+
+/* These clocks are visible outside this module
+ * and can be initialized
+ */
+static struct clk *onchip_clks[] __initdata = {
+ &ck_13MHz,
+ &ck_pll1,
+ &ck_pll4,
+ &ck_pll5,
+ &ck_pll3,
+ &vfp9_ck,
+ &m2hclk_ck,
+ &hclk_ck,
+ &dma_ck,
+ &flash_ck,
+ &dum_ck,
+ &keyscan_ck,
+ &pwm1_ck,
+ &pwm2_ck,
+ &jpeg_ck,
+ &ms_ck,
+ &touch_ck,
+ &i2c0_ck,
+ &i2c1_ck,
+ &i2c2_ck,
+ &spi0_ck,
+ &spi1_ck,
+ &uart3_ck,
+ &uart4_ck,
+ &uart5_ck,
+ &uart6_ck,
+ &wdt_ck,
+};
+
+static struct clk_lookup onchip_clkreg[] = {
+ { .clk = &ck_13MHz, .con_id = "ck_13MHz" },
+ { .clk = &ck_pll1, .con_id = "ck_pll1" },
+ { .clk = &ck_pll4, .con_id = "ck_pll4" },
+ { .clk = &ck_pll5, .con_id = "ck_pll5" },
+ { .clk = &ck_pll3, .con_id = "ck_pll3" },
+ { .clk = &vfp9_ck, .con_id = "vfp9_ck" },
+ { .clk = &m2hclk_ck, .con_id = "m2hclk_ck" },
+ { .clk = &hclk_ck, .con_id = "hclk_ck" },
+ { .clk = &dma_ck, .con_id = "dma_ck" },
+ { .clk = &flash_ck, .con_id = "flash_ck" },
+ { .clk = &dum_ck, .con_id = "dum_ck" },
+ { .clk = &keyscan_ck, .con_id = "keyscan_ck" },
+ { .clk = &pwm1_ck, .con_id = "pwm1_ck" },
+ { .clk = &pwm2_ck, .con_id = "pwm2_ck" },
+ { .clk = &jpeg_ck, .con_id = "jpeg_ck" },
+ { .clk = &ms_ck, .con_id = "ms_ck" },
+ { .clk = &touch_ck, .con_id = "touch_ck" },
+ { .clk = &i2c0_ck, .dev_id = "pnx-i2c.0" },
+ { .clk = &i2c1_ck, .dev_id = "pnx-i2c.1" },
+ { .clk = &i2c2_ck, .dev_id = "pnx-i2c.2" },
+ { .clk = &spi0_ck, .con_id = "spi0_ck" },
+ { .clk = &spi1_ck, .con_id = "spi1_ck" },
+ { .clk = &uart3_ck, .con_id = "uart3_ck" },
+ { .clk = &uart4_ck, .con_id = "uart4_ck" },
+ { .clk = &uart5_ck, .con_id = "uart5_ck" },
+ { .clk = &uart6_ck, .con_id = "uart6_ck" },
+ { .clk = &wdt_ck, .dev_id = "pnx4008-watchdog" },
+};
+
+static void local_clk_disable(struct clk *clk)
+{
+ if (WARN_ON(clk->usecount == 0))
+ return;
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
+ clk->set_rate(clk, 0);
+ if (clk->parent)
+ local_clk_disable(clk->parent);
+ }
+}
+
+static int local_clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->usecount == 0) {
+ if (clk->parent) {
+ ret = local_clk_enable(clk->parent);
+ if (ret != 0)
+ goto out;
+ }
+
+ if (clk->enable)
+ ret = clk->enable(clk);
+ else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
+ && clk->user_rate)
+ ret = clk->set_rate(clk, clk->user_rate);
+
+ if (ret != 0 && clk->parent) {
+ local_clk_disable(clk->parent);
+ goto out;
+ }
+
+ clk->usecount++;
+ }
+out:
+ return ret;
+}
+
+static int local_set_rate(struct clk *clk, u32 rate)
+{
+ int ret = -EINVAL;
+ if (clk->set_rate) {
+
+ if (clk->user_rate == clk->rate && clk->parent->rate) {
+ /* if clock enabled or rate not set */
+ clk->user_rate = clk->round_rate(clk, rate);
+ ret = clk->set_rate(clk, clk->user_rate);
+ } else
+ clk->user_rate = clk->round_rate(clk, rate);
+ ret = 0;
+ }
+ return ret;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk->flags & FIXED_RATE)
+ goto out;
+
+ clock_lock();
+ if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
+
+ clk->user_rate = clk->round_rate(clk, rate);
+ /* parent clock needs to be refreshed
+ for the setting to take effect */
+ } else {
+ ret = local_set_rate(clk, rate);
+ }
+ ret = 0;
+ clock_unlock();
+
+out:
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_set_rate);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long ret;
+ clock_lock();
+ ret = clk->rate;
+ clock_unlock();
+ return ret;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_enable(struct clk *clk)
+{
+ int ret;
+
+ clock_lock();
+ ret = local_clk_enable(clk);
+ clock_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ clock_lock();
+ local_clk_disable(clk);
+ clock_unlock();
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ long ret;
+ clock_lock();
+ if (clk->round_rate)
+ ret = clk->round_rate(clk, rate);
+ else
+ ret = clk->rate;
+ clock_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -ENODEV;
+ if (!clk->set_parent)
+ goto out;
+
+ clock_lock();
+ ret = clk->set_parent(clk, parent);
+ if (!ret)
+ clk->parent = parent;
+ clock_unlock();
+
+out:
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_set_parent);
+
+static int __init clk_init(void)
+{
+ struct clk **clkp;
+
+ /* Disable autoclocking, as it doesn't seem to work */
+ __raw_writel(0xff, AUTOCLK_CTRL);
+
+ for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
+ clkp++) {
+ struct clk *clk = *clkp;
+ if (clk->flags & NEEDS_INITIALIZATION) {
+ if (clk->set_rate) {
+ clk->user_rate = clk->rate;
+ local_set_rate(clk, clk->user_rate);
+ if (clk->set_parent)
+ clk->set_parent(clk, clk->parent);
+ }
+ if (clk->enable && clk->usecount)
+ clk->enable(clk);
+ if (clk->disable && !clk->usecount)
+ clk->disable(clk);
+ }
+ pr_debug("%s: clock %s, rate %ld\n",
+ __func__, clk->name, clk->rate);
+ }
+
+ local_clk_enable(&ck_pll4);
+
+ /* if ck_13MHz is not used, disable it. */
+ if (ck_13MHz.usecount == 0)
+ local_clk_disable(&ck_13MHz);
+
+ /* Disable autoclocking */
+ __raw_writeb(0xff, AUTOCLK_CTRL);
+
+ clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
+
+ return 0;
+}
+
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-pnx4008/clock.h b/arch/arm/mach-pnx4008/clock.h
new file mode 100644
index 00000000..39720d6c
--- /dev/null
+++ b/arch/arm/mach-pnx4008/clock.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-pnx4008/clock.h
+ *
+ * Clock control driver for PNX4008 - internal header file
+ *
+ * Author: Vitaly Wool <source@mvista.com>
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __ARCH_ARM_PNX4008_CLOCK_H__
+#define __ARCH_ARM_PNX4008_CLOCK_H__
+
+struct clk {
+ const char *name;
+ struct clk *parent;
+ struct clk *propagate_next;
+ u32 rate;
+ u32 user_rate;
+ s8 usecount;
+ u32 flags;
+ u32 scale_reg;
+ u8 enable_shift;
+ u32 enable_reg;
+ u8 enable_shift1;
+ u32 enable_reg1;
+ u32 parent_switch_reg;
+ u32(*round_rate) (struct clk *, u32);
+ int (*set_rate) (struct clk *, u32);
+ int (*set_parent) (struct clk * clk, struct clk * parent);
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+};
+
+/* Flags */
+#define RATE_PROPAGATES (1<<0)
+#define NEEDS_INITIALIZATION (1<<1)
+#define PARENT_SET_RATE (1<<2)
+#define FIXED_RATE (1<<3)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c
new file mode 100644
index 00000000..63399755
--- /dev/null
+++ b/arch/arm/mach-pnx4008/core.c
@@ -0,0 +1,272 @@
+/*
+ * arch/arm/mach-pnx4008/core.c
+ *
+ * PNX4008 core startup code
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev,
+ * Grigory Tolstolytkin, Dmitry Pervushin <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/serial_8250.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/irq.h>
+#include <mach/clock.h>
+#include <mach/dma.h>
+
+struct resource spipnx_0_resources[] = {
+ {
+ .start = PNX4008_SPI1_BASE,
+ .end = PNX4008_SPI1_BASE + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = PER_SPI1_REC_XMIT,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = SPI1_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .flags = 0,
+ },
+};
+
+struct resource spipnx_1_resources[] = {
+ {
+ .start = PNX4008_SPI2_BASE,
+ .end = PNX4008_SPI2_BASE + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = PER_SPI2_REC_XMIT,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = SPI2_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+static struct platform_device spipnx_1 = {
+ .name = "spipnx",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(spipnx_0_resources),
+ .resource = spipnx_0_resources,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static struct platform_device spipnx_2 = {
+ .name = "spipnx",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(spipnx_1_resources),
+ .resource = spipnx_1_resources,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static struct plat_serial8250_port platform_serial_ports[] = {
+ {
+ .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART5_BASE)),
+ .mapbase = (unsigned long)PNX4008_UART5_BASE,
+ .irq = IIR5_INT,
+ .uartclk = PNX4008_UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+ },
+ {
+ .membase = (void *)__iomem(IO_ADDRESS(PNX4008_UART3_BASE)),
+ .mapbase = (unsigned long)PNX4008_UART3_BASE,
+ .irq = IIR3_INT,
+ .uartclk = PNX4008_UART_CLK,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_BUGGY_UART | UPF_SKIP_TEST,
+ },
+ {}
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = &platform_serial_ports,
+ },
+};
+
+static struct platform_device nand_flash_device = {
+ .name = "pnx4008-flash",
+ .id = -1,
+ .dev = {
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32) 0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = IO_ADDRESS(PNX4008_USB_CONFIG_BASE),
+ .end = IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x100),
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = USB_HOST_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "pnx4008-usb-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+static struct platform_device sdum_device = {
+ .name = "pnx4008-sdum",
+ .id = 0,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device rgbfb_device = {
+ .name = "pnx4008-rgbfb",
+ .id = 0,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ }
+};
+
+struct resource watchdog_resources[] = {
+ {
+ .start = PNX4008_WDOG_BASE,
+ .end = PNX4008_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device watchdog_device = {
+ .name = "pnx4008-watchdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(watchdog_resources),
+ .resource = watchdog_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &spipnx_1,
+ &spipnx_2,
+ &serial_device,
+ &ohci_device,
+ &nand_flash_device,
+ &sdum_device,
+ &rgbfb_device,
+ &watchdog_device,
+};
+
+
+extern void pnx4008_uart_init(void);
+
+static void __init pnx4008_init(void)
+{
+ /*disable all START interrupt sources,
+ and clear all START interrupt flags */
+ __raw_writel(0, START_INT_ER_REG(SE_PIN_BASE_INT));
+ __raw_writel(0, START_INT_ER_REG(SE_INT_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+ /* Switch on the UART clocks */
+ pnx4008_uart_init();
+}
+
+static struct map_desc pnx4008_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(PNX4008_IRAM_BASE),
+ .pfn = __phys_to_pfn(PNX4008_IRAM_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_NDF_FLASH_BASE),
+ .pfn = __phys_to_pfn(PNX4008_NDF_FLASH_BASE),
+ .length = SZ_1M - SZ_128K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_JPEG_CONFIG_BASE),
+ .pfn = __phys_to_pfn(PNX4008_JPEG_CONFIG_BASE),
+ .length = SZ_128K * 3,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_DMA_CONFIG_BASE),
+ .pfn = __phys_to_pfn(PNX4008_DMA_CONFIG_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(PNX4008_AHB2FAB_BASE),
+ .pfn = __phys_to_pfn(PNX4008_AHB2FAB_BASE),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init pnx4008_map_io(void)
+{
+ iotable_init(pnx4008_io_desc, ARRAY_SIZE(pnx4008_io_desc));
+}
+
+extern struct sys_timer pnx4008_timer;
+
+MACHINE_START(PNX4008, "Philips PNX4008")
+ /* Maintainer: MontaVista Software Inc. */
+ .boot_params = 0x80000100,
+ .map_io = pnx4008_map_io,
+ .init_irq = pnx4008_init_irq,
+ .init_machine = pnx4008_init,
+ .timer = &pnx4008_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pnx4008/dma.c b/arch/arm/mach-pnx4008/dma.c
new file mode 100644
index 00000000..7fa4bf2e
--- /dev/null
+++ b/arch/arm/mach-pnx4008/dma.c
@@ -0,0 +1,1106 @@
+/*
+ * linux/arch/arm/mach-pnx4008/dma.c
+ *
+ * PNX4008 DMA registration and IRQ dispatching
+ *
+ * Author: Vitaly Wool
+ * Copyright: MontaVista Software Inc. (c) 2005
+ *
+ * Based on the code from Nicolas Pitre
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/gfp.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <asm/dma-mapping.h>
+#include <mach/clock.h>
+
+static struct dma_channel {
+ char *name;
+ void (*irq_handler) (int, int, void *);
+ void *data;
+ struct pnx4008_dma_ll *ll;
+ u32 ll_dma;
+ void *target_addr;
+ int target_id;
+} dma_channels[MAX_DMA_CHANNELS];
+
+static struct ll_pool {
+ void *vaddr;
+ void *cur;
+ dma_addr_t dma_addr;
+ int count;
+} ll_pool;
+
+static DEFINE_SPINLOCK(ll_lock);
+
+struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t * ll_dma)
+{
+ struct pnx4008_dma_ll *ll = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ll_lock, flags);
+ if (ll_pool.count > 4) { /* can give one more */
+ ll = *(struct pnx4008_dma_ll **) ll_pool.cur;
+ *ll_dma = ll_pool.dma_addr + ((void *)ll - ll_pool.vaddr);
+ *(void **)ll_pool.cur = **(void ***)ll_pool.cur;
+ memset(ll, 0, sizeof(*ll));
+ ll_pool.count--;
+ }
+ spin_unlock_irqrestore(&ll_lock, flags);
+
+ return ll;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_alloc_ll_entry);
+
+void pnx4008_free_ll_entry(struct pnx4008_dma_ll * ll, dma_addr_t ll_dma)
+{
+ unsigned long flags;
+
+ if (ll) {
+ if ((unsigned long)((long)ll - (long)ll_pool.vaddr) > 0x4000) {
+ printk(KERN_ERR "Trying to free entry not allocated by DMA\n");
+ BUG();
+ }
+
+ if (ll->flags & DMA_BUFFER_ALLOCATED)
+ ll->free(ll->alloc_data);
+
+ spin_lock_irqsave(&ll_lock, flags);
+ *(long *)ll = *(long *)ll_pool.cur;
+ *(long *)ll_pool.cur = (long)ll;
+ ll_pool.count++;
+ spin_unlock_irqrestore(&ll_lock, flags);
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll_entry);
+
+void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll * ll)
+{
+ struct pnx4008_dma_ll *ptr;
+ u32 dma;
+
+ while (ll) {
+ dma = ll->next_dma;
+ ptr = ll->next;
+ pnx4008_free_ll_entry(ll, ll_dma);
+
+ ll_dma = dma;
+ ll = ptr;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_ll);
+
+static int dma_channels_requested = 0;
+
+static inline void dma_increment_usage(void)
+{
+ if (!dma_channels_requested++) {
+ struct clk *clk = clk_get(0, "dma_ck");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, 1);
+ clk_put(clk);
+ }
+ pnx4008_config_dma(-1, -1, 1);
+ }
+}
+static inline void dma_decrement_usage(void)
+{
+ if (!--dma_channels_requested) {
+ struct clk *clk = clk_get(0, "dma_ck");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, 0);
+ clk_put(clk);
+ }
+ pnx4008_config_dma(-1, -1, 0);
+
+ }
+}
+
+static DEFINE_SPINLOCK(dma_lock);
+
+static inline void pnx4008_dma_lock(void)
+{
+ spin_lock_irq(&dma_lock);
+}
+
+static inline void pnx4008_dma_unlock(void)
+{
+ spin_unlock_irq(&dma_lock);
+}
+
+#define VALID_CHANNEL(c) (((c) >= 0) && ((c) < MAX_DMA_CHANNELS))
+
+int pnx4008_request_channel(char *name, int ch,
+ void (*irq_handler) (int, int, void *), void *data)
+{
+ int i, found = 0;
+
+ /* basic sanity checks */
+ if (!name || (ch != -1 && !VALID_CHANNEL(ch)))
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+
+ /* try grabbing a DMA channel with the requested priority */
+ for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+ if (!dma_channels[i].name && (ch == -1 || ch == i)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ dma_increment_usage();
+ dma_channels[i].name = name;
+ dma_channels[i].irq_handler = irq_handler;
+ dma_channels[i].data = data;
+ dma_channels[i].ll = NULL;
+ dma_channels[i].ll_dma = 0;
+ } else {
+ printk(KERN_WARNING "No more available DMA channels for %s\n",
+ name);
+ i = -ENODEV;
+ }
+
+ pnx4008_dma_unlock();
+ return i;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_request_channel);
+
+void pnx4008_free_channel(int ch)
+{
+ if (!dma_channels[ch].name) {
+ printk(KERN_CRIT
+ "%s: trying to free channel %d which is already freed\n",
+ __func__, ch);
+ return;
+ }
+
+ pnx4008_dma_lock();
+ pnx4008_free_ll(dma_channels[ch].ll_dma, dma_channels[ch].ll);
+ dma_channels[ch].ll = NULL;
+ dma_decrement_usage();
+
+ dma_channels[ch].name = NULL;
+ pnx4008_dma_unlock();
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_free_channel);
+
+int pnx4008_config_dma(int ahb_m1_be, int ahb_m2_be, int enable)
+{
+ unsigned long dma_cfg = __raw_readl(DMAC_CONFIG);
+
+ switch (ahb_m1_be) {
+ case 0:
+ dma_cfg &= ~(1 << 1);
+ break;
+ case 1:
+ dma_cfg |= (1 << 1);
+ break;
+ default:
+ break;
+ }
+
+ switch (ahb_m2_be) {
+ case 0:
+ dma_cfg &= ~(1 << 2);
+ break;
+ case 1:
+ dma_cfg |= (1 << 2);
+ break;
+ default:
+ break;
+ }
+
+ switch (enable) {
+ case 0:
+ dma_cfg &= ~(1 << 0);
+ break;
+ case 1:
+ dma_cfg |= (1 << 0);
+ break;
+ default:
+ break;
+ }
+
+ pnx4008_dma_lock();
+ __raw_writel(dma_cfg, DMAC_CONFIG);
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_dma);
+
+int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl * ch_ctrl,
+ unsigned long *ctrl)
+{
+ int i = 0, dbsize, sbsize, err = 0;
+
+ if (!ctrl || !ch_ctrl) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ *ctrl = 0;
+
+ switch (ch_ctrl->tc_mask) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 31);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+
+ switch (ch_ctrl->cacheable) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 30);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->bufferable) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 29);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->priv_mode) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 28);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->di) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 27);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->si) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 26);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->dest_ahb1) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 25);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->src_ahb1) {
+ case 0:
+ break;
+ case 1:
+ *ctrl |= (1 << 24);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->dwidth) {
+ case WIDTH_BYTE:
+ *ctrl &= ~(7 << 21);
+ break;
+ case WIDTH_HWORD:
+ *ctrl &= ~(7 << 21);
+ *ctrl |= (1 << 21);
+ break;
+ case WIDTH_WORD:
+ *ctrl &= ~(7 << 21);
+ *ctrl |= (2 << 21);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_ctrl->swidth) {
+ case WIDTH_BYTE:
+ *ctrl &= ~(7 << 18);
+ break;
+ case WIDTH_HWORD:
+ *ctrl &= ~(7 << 18);
+ *ctrl |= (1 << 18);
+ break;
+ case WIDTH_WORD:
+ *ctrl &= ~(7 << 18);
+ *ctrl |= (2 << 18);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ dbsize = ch_ctrl->dbsize;
+ while (!(dbsize & 1)) {
+ i++;
+ dbsize >>= 1;
+ }
+ if (ch_ctrl->dbsize != 1 || i > 8 || i == 1) {
+ err = -EINVAL;
+ goto out;
+ } else if (i > 1)
+ i--;
+ *ctrl &= ~(7 << 15);
+ *ctrl |= (i << 15);
+
+ sbsize = ch_ctrl->sbsize;
+ while (!(sbsize & 1)) {
+ i++;
+ sbsize >>= 1;
+ }
+ if (ch_ctrl->sbsize != 1 || i > 8 || i == 1) {
+ err = -EINVAL;
+ goto out;
+ } else if (i > 1)
+ i--;
+ *ctrl &= ~(7 << 12);
+ *ctrl |= (i << 12);
+
+ if (ch_ctrl->tr_size > 0x7ff) {
+ err = -E2BIG;
+ goto out;
+ }
+ *ctrl &= ~0x7ff;
+ *ctrl |= ch_ctrl->tr_size & 0x7ff;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_control);
+
+int pnx4008_dma_parse_control(unsigned long ctrl,
+ struct pnx4008_dma_ch_ctrl * ch_ctrl)
+{
+ int err = 0;
+
+ if (!ch_ctrl) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ ch_ctrl->tr_size = ctrl & 0x7ff;
+ ctrl >>= 12;
+
+ ch_ctrl->sbsize = 1 << (ctrl & 7);
+ if (ch_ctrl->sbsize > 1)
+ ch_ctrl->sbsize <<= 1;
+ ctrl >>= 3;
+
+ ch_ctrl->dbsize = 1 << (ctrl & 7);
+ if (ch_ctrl->dbsize > 1)
+ ch_ctrl->dbsize <<= 1;
+ ctrl >>= 3;
+
+ switch (ctrl & 7) {
+ case 0:
+ ch_ctrl->swidth = WIDTH_BYTE;
+ break;
+ case 1:
+ ch_ctrl->swidth = WIDTH_HWORD;
+ break;
+ case 2:
+ ch_ctrl->swidth = WIDTH_WORD;
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ ctrl >>= 3;
+
+ switch (ctrl & 7) {
+ case 0:
+ ch_ctrl->dwidth = WIDTH_BYTE;
+ break;
+ case 1:
+ ch_ctrl->dwidth = WIDTH_HWORD;
+ break;
+ case 2:
+ ch_ctrl->dwidth = WIDTH_WORD;
+ break;
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ ctrl >>= 3;
+
+ ch_ctrl->src_ahb1 = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->dest_ahb1 = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->si = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->di = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->priv_mode = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->bufferable = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->cacheable = ctrl & 1;
+ ctrl >>= 1;
+
+ ch_ctrl->tc_mask = ctrl & 1;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_control);
+
+int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config * ch_cfg,
+ unsigned long *cfg)
+{
+ int err = 0;
+
+ if (!cfg || !ch_cfg) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ *cfg = 0;
+
+ switch (ch_cfg->halt) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 18);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->active) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 17);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->lock) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 16);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->itc) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 15);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->ie) {
+ case 0:
+ break;
+ case 1:
+ *cfg |= (1 << 14);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ switch (ch_cfg->flow_cntrl) {
+ case FC_MEM2MEM_DMA:
+ *cfg &= ~(7 << 11);
+ break;
+ case FC_MEM2PER_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (1 << 11);
+ break;
+ case FC_PER2MEM_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (2 << 11);
+ break;
+ case FC_PER2PER_DMA:
+ *cfg &= ~(7 << 11);
+ *cfg |= (3 << 11);
+ break;
+ case FC_PER2PER_DPER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (4 << 11);
+ break;
+ case FC_MEM2PER_PER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (5 << 11);
+ break;
+ case FC_PER2MEM_PER:
+ *cfg &= ~(7 << 11);
+ *cfg |= (6 << 11);
+ break;
+ case FC_PER2PER_SPER:
+ *cfg |= (7 << 11);
+ break;
+
+ default:
+ err = -EINVAL;
+ goto out;
+ }
+ *cfg &= ~(0x1f << 6);
+ *cfg |= ((ch_cfg->dest_per & 0x1f) << 6);
+
+ *cfg &= ~(0x1f << 1);
+ *cfg |= ((ch_cfg->src_per & 0x1f) << 1);
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_pack_config);
+
+int pnx4008_dma_parse_config(unsigned long cfg,
+ struct pnx4008_dma_ch_config * ch_cfg)
+{
+ int err = 0;
+
+ if (!ch_cfg) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ cfg >>= 1;
+
+ ch_cfg->src_per = cfg & 0x1f;
+ cfg >>= 5;
+
+ ch_cfg->dest_per = cfg & 0x1f;
+ cfg >>= 5;
+
+ switch (cfg & 7) {
+ case 0:
+ ch_cfg->flow_cntrl = FC_MEM2MEM_DMA;
+ break;
+ case 1:
+ ch_cfg->flow_cntrl = FC_MEM2PER_DMA;
+ break;
+ case 2:
+ ch_cfg->flow_cntrl = FC_PER2MEM_DMA;
+ break;
+ case 3:
+ ch_cfg->flow_cntrl = FC_PER2PER_DMA;
+ break;
+ case 4:
+ ch_cfg->flow_cntrl = FC_PER2PER_DPER;
+ break;
+ case 5:
+ ch_cfg->flow_cntrl = FC_MEM2PER_PER;
+ break;
+ case 6:
+ ch_cfg->flow_cntrl = FC_PER2MEM_PER;
+ break;
+ case 7:
+ ch_cfg->flow_cntrl = FC_PER2PER_SPER;
+ }
+ cfg >>= 3;
+
+ ch_cfg->ie = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->itc = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->lock = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->active = cfg & 1;
+ cfg >>= 1;
+
+ ch_cfg->halt = cfg & 1;
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_parse_config);
+
+void pnx4008_dma_split_head_entry(struct pnx4008_dma_config * config,
+ struct pnx4008_dma_ch_ctrl * ctrl)
+{
+ int new_len = ctrl->tr_size, num_entries = 0;
+ int old_len = new_len;
+ int src_width, dest_width, count = 1;
+
+ switch (ctrl->swidth) {
+ case WIDTH_BYTE:
+ src_width = 1;
+ break;
+ case WIDTH_HWORD:
+ src_width = 2;
+ break;
+ case WIDTH_WORD:
+ src_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ switch (ctrl->dwidth) {
+ case WIDTH_BYTE:
+ dest_width = 1;
+ break;
+ case WIDTH_HWORD:
+ dest_width = 2;
+ break;
+ case WIDTH_WORD:
+ dest_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ while (new_len > 0x7FF) {
+ num_entries++;
+ new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+ }
+ if (num_entries != 0) {
+ struct pnx4008_dma_ll *ll = NULL;
+ config->ch_ctrl &= ~0x7ff;
+ config->ch_ctrl |= new_len;
+ if (!config->is_ll) {
+ config->is_ll = 1;
+ while (num_entries) {
+ if (!ll) {
+ config->ll =
+ pnx4008_alloc_ll_entry(&config->
+ ll_dma);
+ ll = config->ll;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ config->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = config->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ config->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = config->dest_addr;
+ ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ } else {
+ struct pnx4008_dma_ll *ll_old = config->ll;
+ unsigned long ll_dma_old = config->ll_dma;
+ while (num_entries) {
+ if (!ll) {
+ config->ll =
+ pnx4008_alloc_ll_entry(&config->
+ ll_dma);
+ ll = config->ll;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ config->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = config->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ config->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = config->dest_addr;
+ ll->ch_ctrl = config->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ ll->next_dma = ll_dma_old;
+ ll->next = ll_old;
+ }
+ /* adjust last length/tc */
+ ll->ch_ctrl = config->ch_ctrl & (~0x7ff);
+ ll->ch_ctrl |= old_len - new_len * (count - 1);
+ config->ch_ctrl &= 0x7fffffff;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_head_entry);
+
+void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll * cur_ll,
+ struct pnx4008_dma_ch_ctrl * ctrl)
+{
+ int new_len = ctrl->tr_size, num_entries = 0;
+ int old_len = new_len;
+ int src_width, dest_width, count = 1;
+
+ switch (ctrl->swidth) {
+ case WIDTH_BYTE:
+ src_width = 1;
+ break;
+ case WIDTH_HWORD:
+ src_width = 2;
+ break;
+ case WIDTH_WORD:
+ src_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ switch (ctrl->dwidth) {
+ case WIDTH_BYTE:
+ dest_width = 1;
+ break;
+ case WIDTH_HWORD:
+ dest_width = 2;
+ break;
+ case WIDTH_WORD:
+ dest_width = 4;
+ break;
+ default:
+ return;
+ }
+
+ while (new_len > 0x7FF) {
+ num_entries++;
+ new_len = (ctrl->tr_size + num_entries) / (num_entries + 1);
+ }
+ if (num_entries != 0) {
+ struct pnx4008_dma_ll *ll = NULL;
+ cur_ll->ch_ctrl &= ~0x7ff;
+ cur_ll->ch_ctrl |= new_len;
+ if (!cur_ll->next) {
+ while (num_entries) {
+ if (!ll) {
+ cur_ll->next =
+ pnx4008_alloc_ll_entry(&cur_ll->
+ next_dma);
+ ll = cur_ll->next;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ cur_ll->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = cur_ll->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ cur_ll->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = cur_ll->dest_addr;
+ ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+ } else {
+ struct pnx4008_dma_ll *ll_old = cur_ll->next;
+ unsigned long ll_dma_old = cur_ll->next_dma;
+ while (num_entries) {
+ if (!ll) {
+ cur_ll->next =
+ pnx4008_alloc_ll_entry(&cur_ll->
+ next_dma);
+ ll = cur_ll->next;
+ } else {
+ ll->next =
+ pnx4008_alloc_ll_entry(&ll->
+ next_dma);
+ ll = ll->next;
+ }
+
+ if (ctrl->si)
+ ll->src_addr =
+ cur_ll->src_addr +
+ src_width * new_len * count;
+ else
+ ll->src_addr = cur_ll->src_addr;
+ if (ctrl->di)
+ ll->dest_addr =
+ cur_ll->dest_addr +
+ dest_width * new_len * count;
+ else
+ ll->dest_addr = cur_ll->dest_addr;
+ ll->ch_ctrl = cur_ll->ch_ctrl & 0x7fffffff;
+ ll->next_dma = 0;
+ ll->next = NULL;
+ num_entries--;
+ count++;
+ }
+
+ ll->next_dma = ll_dma_old;
+ ll->next = ll_old;
+ }
+ /* adjust last length/tc */
+ ll->ch_ctrl = cur_ll->ch_ctrl & (~0x7ff);
+ ll->ch_ctrl |= old_len - new_len * (count - 1);
+ cur_ll->ch_ctrl &= 0x7fffffff;
+ }
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_split_ll_entry);
+
+int pnx4008_config_channel(int ch, struct pnx4008_dma_config * config)
+{
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ __raw_writel(config->src_addr, DMAC_Cx_SRC_ADDR(ch));
+ __raw_writel(config->dest_addr, DMAC_Cx_DEST_ADDR(ch));
+
+ if (config->is_ll)
+ __raw_writel(config->ll_dma, DMAC_Cx_LLI(ch));
+ else
+ __raw_writel(0, DMAC_Cx_LLI(ch));
+
+ __raw_writel(config->ch_ctrl, DMAC_Cx_CONTROL(ch));
+ __raw_writel(config->ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_config_channel);
+
+int pnx4008_channel_get_config(int ch, struct pnx4008_dma_config * config)
+{
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name || !config)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ config->ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ config->ch_ctrl = __raw_readl(DMAC_Cx_CONTROL(ch));
+
+ config->ll_dma = __raw_readl(DMAC_Cx_LLI(ch));
+ config->is_ll = config->ll_dma ? 1 : 0;
+
+ config->src_addr = __raw_readl(DMAC_Cx_SRC_ADDR(ch));
+ config->dest_addr = __raw_readl(DMAC_Cx_DEST_ADDR(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_channel_get_config);
+
+int pnx4008_dma_ch_enable(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ ch_cfg |= 1;
+ __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enable);
+
+int pnx4008_dma_ch_disable(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ ch_cfg &= ~1;
+ __raw_writel(ch_cfg, DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_disable);
+
+int pnx4008_dma_ch_enabled(int ch)
+{
+ unsigned long ch_cfg;
+
+ if (!VALID_CHANNEL(ch) || !dma_channels[ch].name)
+ return -EINVAL;
+
+ pnx4008_dma_lock();
+ ch_cfg = __raw_readl(DMAC_Cx_CONFIG(ch));
+ pnx4008_dma_unlock();
+
+ return ch_cfg & 1;
+}
+
+EXPORT_SYMBOL_GPL(pnx4008_dma_ch_enabled);
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+ int i;
+ unsigned long dint = __raw_readl(DMAC_INT_STAT);
+ unsigned long tcint = __raw_readl(DMAC_INT_TC_STAT);
+ unsigned long eint = __raw_readl(DMAC_INT_ERR_STAT);
+ unsigned long i_bit;
+
+ for (i = MAX_DMA_CHANNELS - 1; i >= 0; i--) {
+ i_bit = 1 << i;
+ if (dint & i_bit) {
+ struct dma_channel *channel = &dma_channels[i];
+
+ if (channel->name && channel->irq_handler) {
+ int cause = 0;
+
+ if (eint & i_bit)
+ cause |= DMA_ERR_INT;
+ if (tcint & i_bit)
+ cause |= DMA_TC_INT;
+ channel->irq_handler(i, cause, channel->data);
+ } else {
+ /*
+ * IRQ for an unregistered DMA channel
+ */
+ printk(KERN_WARNING
+ "spurious IRQ for DMA channel %d\n", i);
+ }
+ if (tcint & i_bit)
+ __raw_writel(i_bit, DMAC_INT_TC_CLEAR);
+ if (eint & i_bit)
+ __raw_writel(i_bit, DMAC_INT_ERR_CLEAR);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int __init pnx4008_dma_init(void)
+{
+ int ret, i;
+
+ ret = request_irq(DMA_INT, dma_irq_handler, 0, "DMA", NULL);
+ if (ret) {
+ printk(KERN_CRIT "Wow! Can't register IRQ for DMA\n");
+ goto out;
+ }
+
+ ll_pool.count = 0x4000 / sizeof(struct pnx4008_dma_ll);
+ ll_pool.cur = ll_pool.vaddr =
+ dma_alloc_coherent(NULL, ll_pool.count * sizeof(struct pnx4008_dma_ll),
+ &ll_pool.dma_addr, GFP_KERNEL);
+
+ if (!ll_pool.vaddr) {
+ ret = -ENOMEM;
+ free_irq(DMA_INT, NULL);
+ goto out;
+ }
+
+ for (i = 0; i < ll_pool.count - 1; i++) {
+ void **addr = ll_pool.vaddr + i * sizeof(struct pnx4008_dma_ll);
+ *addr = (void *)addr + sizeof(struct pnx4008_dma_ll);
+ }
+ *(long *)(ll_pool.vaddr +
+ (ll_pool.count - 1) * sizeof(struct pnx4008_dma_ll)) =
+ (long)ll_pool.vaddr;
+
+ __raw_writel(1, DMAC_CONFIG);
+
+out:
+ return ret;
+}
+arch_initcall(pnx4008_dma_init);
diff --git a/arch/arm/mach-pnx4008/gpio.c b/arch/arm/mach-pnx4008/gpio.c
new file mode 100644
index 00000000..f219914f
--- /dev/null
+++ b/arch/arm/mach-pnx4008/gpio.c
@@ -0,0 +1,329 @@
+/*
+ * arch/arm/mach-pnx4008/gpio.c
+ *
+ * PNX4008 GPIO driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
+ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <mach/gpio.h>
+
+/* register definitions */
+#define PIO_VA_BASE IO_ADDRESS(PNX4008_PIO_BASE)
+
+#define PIO_INP_STATE (0x00U)
+#define PIO_OUTP_SET (0x04U)
+#define PIO_OUTP_CLR (0x08U)
+#define PIO_OUTP_STATE (0x0CU)
+#define PIO_DRV_SET (0x10U)
+#define PIO_DRV_CLR (0x14U)
+#define PIO_DRV_STATE (0x18U)
+#define PIO_SDINP_STATE (0x1CU)
+#define PIO_SDOUTP_SET (0x20U)
+#define PIO_SDOUTP_CLR (0x24U)
+#define PIO_MUX_SET (0x28U)
+#define PIO_MUX_CLR (0x2CU)
+#define PIO_MUX_STATE (0x30U)
+
+static inline void gpio_lock(void)
+{
+ local_irq_disable();
+}
+
+static inline void gpio_unlock(void)
+{
+ local_irq_enable();
+}
+
+/* Inline functions */
+static inline int gpio_read_bit(u32 reg, int gpio)
+{
+ u32 bit, val;
+ int ret = -EFAULT;
+
+ if (gpio < 0)
+ goto out;
+
+ bit = GPIO_BIT(gpio);
+ if (bit) {
+ val = __raw_readl(PIO_VA_BASE + reg);
+ ret = (val & bit) ? 1 : 0;
+ }
+out:
+ return ret;
+}
+
+static inline int gpio_set_bit(u32 reg, int gpio)
+{
+ u32 bit, val;
+ int ret = -EFAULT;
+
+ if (gpio < 0)
+ goto out;
+
+ bit = GPIO_BIT(gpio);
+ if (bit) {
+ val = __raw_readl(PIO_VA_BASE + reg);
+ val |= bit;
+ __raw_writel(val, PIO_VA_BASE + reg);
+ ret = 0;
+ }
+out:
+ return ret;
+}
+
+/* Very simple access control, bitmap for allocated/free */
+static unsigned long access_map[4];
+#define INP_INDEX 0
+#define OUTP_INDEX 1
+#define GPIO_INDEX 2
+#define MUX_INDEX 3
+
+/*GPIO to Input Mapping */
+static short gpio_to_inp_map[32] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 24, -1
+};
+
+/*GPIO to Mux Mapping */
+static short gpio_to_mux_map[32] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 0, 1, 4, 5, -1
+};
+
+/*Output to Mux Mapping */
+static short outp_to_mux_map[32] = {
+ -1, -1, -1, 6, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 2, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+int pnx4008_gpio_register_pin(unsigned short pin)
+{
+ unsigned long bit = GPIO_BIT(pin);
+ int ret = -EBUSY; /* Already in use */
+
+ gpio_lock();
+
+ if (GPIO_ISBID(pin)) {
+ if (access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] |= bit;
+
+ } else if (GPIO_ISRAM(pin)) {
+ if (access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] |= bit;
+
+ } else if (GPIO_ISMUX(pin)) {
+ if (access_map[MUX_INDEX] & bit)
+ goto out;
+ access_map[MUX_INDEX] |= bit;
+
+ } else if (GPIO_ISOUT(pin)) {
+ if (access_map[OUTP_INDEX] & bit)
+ goto out;
+ access_map[OUTP_INDEX] |= bit;
+
+ } else if (GPIO_ISIN(pin)) {
+ if (access_map[INP_INDEX] & bit)
+ goto out;
+ access_map[INP_INDEX] |= bit;
+ } else
+ goto out;
+ ret = 0;
+
+out:
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_register_pin);
+
+int pnx4008_gpio_unregister_pin(unsigned short pin)
+{
+ unsigned long bit = GPIO_BIT(pin);
+ int ret = -EFAULT; /* Not registered */
+
+ gpio_lock();
+
+ if (GPIO_ISBID(pin)) {
+ if (~access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] &= ~bit;
+ } else if (GPIO_ISRAM(pin)) {
+ if (~access_map[GPIO_INDEX] & bit)
+ goto out;
+ access_map[GPIO_INDEX] &= ~bit;
+ } else if (GPIO_ISMUX(pin)) {
+ if (~access_map[MUX_INDEX] & bit)
+ goto out;
+ access_map[MUX_INDEX] &= ~bit;
+ } else if (GPIO_ISOUT(pin)) {
+ if (~access_map[OUTP_INDEX] & bit)
+ goto out;
+ access_map[OUTP_INDEX] &= ~bit;
+ } else if (GPIO_ISIN(pin)) {
+ if (~access_map[INP_INDEX] & bit)
+ goto out;
+ access_map[INP_INDEX] &= ~bit;
+ } else
+ goto out;
+ ret = 0;
+
+out:
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_unregister_pin);
+
+unsigned long pnx4008_gpio_read_pin(unsigned short pin)
+{
+ unsigned long ret = -EFAULT;
+ int gpio = GPIO_BIT_MASK(pin);
+ gpio_lock();
+ if (GPIO_ISOUT(pin)) {
+ ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+ } else if (GPIO_ISRAM(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) == 0) {
+ ret = gpio_read_bit(PIO_SDINP_STATE, gpio);
+ }
+ } else if (GPIO_ISBID(pin)) {
+ ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+ if (ret > 0)
+ ret = gpio_read_bit(PIO_OUTP_STATE, gpio);
+ else if (ret == 0)
+ ret =
+ gpio_read_bit(PIO_INP_STATE, gpio_to_inp_map[gpio]);
+ } else if (GPIO_ISIN(pin)) {
+ ret = gpio_read_bit(PIO_INP_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin);
+
+/* Write Value to output */
+int pnx4008_gpio_write_pin(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISOUT(pin)) {
+ printk( "writing '%x' to '%x'\n",
+ gpio, output ? PIO_OUTP_SET : PIO_OUTP_CLR );
+ ret = gpio_set_bit(output ? PIO_OUTP_SET : PIO_OUTP_CLR, gpio);
+ } else if (GPIO_ISRAM(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+ ret = gpio_set_bit(output ? PIO_SDOUTP_SET :
+ PIO_SDOUTP_CLR, gpio);
+ } else if (GPIO_ISBID(pin)) {
+ if (gpio_read_bit(PIO_DRV_STATE, gpio) > 0)
+ ret = gpio_set_bit(output ? PIO_OUTP_SET :
+ PIO_OUTP_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_write_pin);
+
+/* Value = 1 : Set GPIO pin as output */
+/* Value = 0 : Set GPIO pin as input */
+int pnx4008_gpio_set_pin_direction(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+ ret = gpio_set_bit(output ? PIO_DRV_SET : PIO_DRV_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_direction);
+
+/* Read GPIO pin direction: 0= pin used as input, 1= pin used as output*/
+int pnx4008_gpio_read_pin_direction(unsigned short pin)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin) || GPIO_ISRAM(pin)) {
+ ret = gpio_read_bit(PIO_DRV_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_direction);
+
+/* Value = 1 : Set pin to muxed function */
+/* Value = 0 : Set pin as GPIO */
+int pnx4008_gpio_set_pin_mux(unsigned short pin, int output)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin)) {
+ ret =
+ gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+ gpio_to_mux_map[gpio]);
+ } else if (GPIO_ISOUT(pin)) {
+ ret =
+ gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR,
+ outp_to_mux_map[gpio]);
+ } else if (GPIO_ISMUX(pin)) {
+ ret = gpio_set_bit(output ? PIO_MUX_SET : PIO_MUX_CLR, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_set_pin_mux);
+
+/* Read pin mux function: 0= pin used as GPIO, 1= pin used for muxed function*/
+int pnx4008_gpio_read_pin_mux(unsigned short pin)
+{
+ int gpio = GPIO_BIT_MASK(pin);
+ int ret = -EFAULT;
+
+ gpio_lock();
+ if (GPIO_ISBID(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, gpio_to_mux_map[gpio]);
+ } else if (GPIO_ISOUT(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, outp_to_mux_map[gpio]);
+ } else if (GPIO_ISMUX(pin)) {
+ ret = gpio_read_bit(PIO_MUX_STATE, gpio);
+ }
+ gpio_unlock();
+ return ret;
+}
+
+EXPORT_SYMBOL(pnx4008_gpio_read_pin_mux);
diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c
new file mode 100644
index 00000000..8103f964
--- /dev/null
+++ b/arch/arm/mach-pnx4008/i2c.c
@@ -0,0 +1,72 @@
+/*
+ * I2C initialization for PNX4008.
+ *
+ * Author: Vitaly Wool <vitalywool@gmail.com>
+ *
+ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/i2c-pnx.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <mach/platform.h>
+#include <mach/irqs.h>
+#include <mach/i2c.h>
+
+static struct i2c_pnx_data i2c0_data = {
+ .name = I2C_CHIP_NAME "0",
+ .base = PNX4008_I2C1_BASE,
+ .irq = I2C_1_INT,
+};
+
+static struct i2c_pnx_data i2c1_data = {
+ .name = I2C_CHIP_NAME "1",
+ .base = PNX4008_I2C2_BASE,
+ .irq = I2C_2_INT,
+};
+
+static struct i2c_pnx_data i2c2_data = {
+ .name = "USB-I2C",
+ .base = (PNX4008_USB_CONFIG_BASE + 0x300),
+ .irq = USB_I2C_INT,
+};
+
+static struct platform_device i2c0_device = {
+ .name = "pnx-i2c",
+ .id = 0,
+ .dev = {
+ .platform_data = &i2c0_data,
+ },
+};
+
+static struct platform_device i2c1_device = {
+ .name = "pnx-i2c",
+ .id = 1,
+ .dev = {
+ .platform_data = &i2c1_data,
+ },
+};
+
+static struct platform_device i2c2_device = {
+ .name = "pnx-i2c",
+ .id = 2,
+ .dev = {
+ .platform_data = &i2c2_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &i2c2_device,
+};
+
+void __init pnx4008_register_i2c_devices(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
diff --git a/arch/arm/mach-pnx4008/include/mach/clkdev.h b/arch/arm/mach-pnx4008/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/clock.h b/arch/arm/mach-pnx4008/include/mach/clock.h
new file mode 100644
index 00000000..8d2a5ef5
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/clock.h
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/clock.h
+ *
+ * Clock control driver for PNX4008 - header file
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __PNX4008_CLOCK_H__
+#define __PNX4008_CLOCK_H__
+
+struct module;
+struct clk;
+
+#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
+#define HCLKDIVCTRL_REG (PWRMAN_VA_BASE + 0x40)
+#define PWRCTRL_REG (PWRMAN_VA_BASE + 0x44)
+#define PLLCTRL_REG (PWRMAN_VA_BASE + 0x48)
+#define OSC13CTRL_REG (PWRMAN_VA_BASE + 0x4c)
+#define SYSCLKCTRL_REG (PWRMAN_VA_BASE + 0x50)
+#define HCLKPLLCTRL_REG (PWRMAN_VA_BASE + 0x58)
+#define USBCTRL_REG (PWRMAN_VA_BASE + 0x64)
+#define SDRAMCLKCTRL_REG (PWRMAN_VA_BASE + 0x68)
+#define MSCTRL_REG (PWRMAN_VA_BASE + 0x80)
+#define BTCLKCTRL (PWRMAN_VA_BASE + 0x84)
+#define DUMCLKCTRL_REG (PWRMAN_VA_BASE + 0x90)
+#define I2CCLKCTRL_REG (PWRMAN_VA_BASE + 0xac)
+#define KEYCLKCTRL_REG (PWRMAN_VA_BASE + 0xb0)
+#define TSCLKCTRL_REG (PWRMAN_VA_BASE + 0xb4)
+#define PWMCLKCTRL_REG (PWRMAN_VA_BASE + 0xb8)
+#define TIMCLKCTRL_REG (PWRMAN_VA_BASE + 0xbc)
+#define SPICTRL_REG (PWRMAN_VA_BASE + 0xc4)
+#define FLASHCLKCTRL_REG (PWRMAN_VA_BASE + 0xc8)
+#define UART3CLK_REG (PWRMAN_VA_BASE + 0xd0)
+#define UARTCLKCTRL_REG (PWRMAN_VA_BASE + 0xe4)
+#define DMACLKCTRL_REG (PWRMAN_VA_BASE + 0xe8)
+#define AUTOCLK_CTRL (PWRMAN_VA_BASE + 0xec)
+#define JPEGCLKCTRL_REG (PWRMAN_VA_BASE + 0xfc)
+
+#define AUDIOCONFIG_VA_BASE IO_ADDRESS(PNX4008_AUDIOCONFIG_BASE)
+#define DSPPLLCTRL_REG (AUDIOCONFIG_VA_BASE + 0x60)
+#define DSPCLKCTRL_REG (AUDIOCONFIG_VA_BASE + 0x64)
+#define AUDIOCLKCTRL_REG (AUDIOCONFIG_VA_BASE + 0x68)
+#define AUDIOPLLCTRL_REG (AUDIOCONFIG_VA_BASE + 0x6C)
+
+#define USB_OTG_CLKCTRL_REG IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xff4)
+
+#define VFP9CLKCTRL_REG IO_ADDRESS(PNX4008_DEBUG_BASE)
+
+#define CLK_RATE_13MHZ 13000
+#define CLK_RATE_1MHZ 1000
+#define CLK_RATE_208MHZ 208000
+#define CLK_RATE_48MHZ 48000
+#define CLK_RATE_32KHZ 32
+
+#define PNX4008_UART_CLK CLK_RATE_13MHZ * 1000 /* in MHz */
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/debug-macro.S b/arch/arm/mach-pnx4008/include/mach/debug-macro.S
new file mode 100644
index 00000000..931afeba
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/* arch/arm/mach-pnx4008/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00090000
+ add \rv, \rp, #0xf4000000 @ virtual
+ add \rp, \rp, #0x40000000 @ physical
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-pnx4008/include/mach/dma.h b/arch/arm/mach-pnx4008/include/mach/dma.h
new file mode 100644
index 00000000..f094bf8b
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/dma.h
@@ -0,0 +1,160 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/dma.h
+ *
+ * PNX4008 DMA header file
+ *
+ * Author: Vitaly Wool
+ * Copyright: MontaVista Software Inc. (c) 2005
+ *
+ * This program is free software; you can 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_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include "platform.h"
+
+#define MAX_DMA_CHANNELS 8
+
+#define DMAC_BASE IO_ADDRESS(PNX4008_DMA_CONFIG_BASE)
+#define DMAC_INT_STAT (DMAC_BASE + 0x0000)
+#define DMAC_INT_TC_STAT (DMAC_BASE + 0x0004)
+#define DMAC_INT_TC_CLEAR (DMAC_BASE + 0x0008)
+#define DMAC_INT_ERR_STAT (DMAC_BASE + 0x000c)
+#define DMAC_INT_ERR_CLEAR (DMAC_BASE + 0x0010)
+#define DMAC_SOFT_SREQ (DMAC_BASE + 0x0024)
+#define DMAC_CONFIG (DMAC_BASE + 0x0030)
+#define DMAC_Cx_SRC_ADDR(c) (DMAC_BASE + 0x0100 + (c) * 0x20)
+#define DMAC_Cx_DEST_ADDR(c) (DMAC_BASE + 0x0104 + (c) * 0x20)
+#define DMAC_Cx_LLI(c) (DMAC_BASE + 0x0108 + (c) * 0x20)
+#define DMAC_Cx_CONTROL(c) (DMAC_BASE + 0x010c + (c) * 0x20)
+#define DMAC_Cx_CONFIG(c) (DMAC_BASE + 0x0110 + (c) * 0x20)
+
+enum {
+ WIDTH_BYTE = 0,
+ WIDTH_HWORD,
+ WIDTH_WORD
+};
+
+enum {
+ FC_MEM2MEM_DMA,
+ FC_MEM2PER_DMA,
+ FC_PER2MEM_DMA,
+ FC_PER2PER_DMA,
+ FC_PER2PER_DPER,
+ FC_MEM2PER_PER,
+ FC_PER2MEM_PER,
+ FC_PER2PER_SPER
+};
+
+enum {
+ DMA_INT_UNKNOWN = 0,
+ DMA_ERR_INT = 1,
+ DMA_TC_INT = 2,
+};
+
+enum {
+ DMA_BUFFER_ALLOCATED = 1,
+ DMA_HAS_LL = 2,
+};
+
+enum {
+ PER_CAM_DMA_1 = 0,
+ PER_NDF_FLASH = 1,
+ PER_MBX_SLAVE_FIFO = 2,
+ PER_SPI2_REC_XMIT = 3,
+ PER_MS_SD_RX_XMIT = 4,
+ PER_HS_UART_1_XMIT = 5,
+ PER_HS_UART_1_RX = 6,
+ PER_HS_UART_2_XMIT = 7,
+ PER_HS_UART_2_RX = 8,
+ PER_HS_UART_7_XMIT = 9,
+ PER_HS_UART_7_RX = 10,
+ PER_SPI1_REC_XMIT = 11,
+ PER_MLC_NDF_SREC = 12,
+ PER_CAM_DMA_2 = 13,
+ PER_PRNG_INFIFO = 14,
+ PER_PRNG_OUTFIFO = 15,
+};
+
+struct pnx4008_dma_ch_ctrl {
+ int tc_mask;
+ int cacheable;
+ int bufferable;
+ int priv_mode;
+ int di;
+ int si;
+ int dest_ahb1;
+ int src_ahb1;
+ int dwidth;
+ int swidth;
+ int dbsize;
+ int sbsize;
+ int tr_size;
+};
+
+struct pnx4008_dma_ch_config {
+ int halt;
+ int active;
+ int lock;
+ int itc;
+ int ie;
+ int flow_cntrl;
+ int dest_per;
+ int src_per;
+};
+
+struct pnx4008_dma_ll {
+ unsigned long src_addr;
+ unsigned long dest_addr;
+ u32 next_dma;
+ unsigned long ch_ctrl;
+ struct pnx4008_dma_ll *next;
+ int flags;
+ void *alloc_data;
+ int (*free) (void *);
+};
+
+struct pnx4008_dma_config {
+ int is_ll;
+ unsigned long src_addr;
+ unsigned long dest_addr;
+ unsigned long ch_ctrl;
+ unsigned long ch_cfg;
+ struct pnx4008_dma_ll *ll;
+ u32 ll_dma;
+ int flags;
+ void *alloc_data;
+ int (*free) (void *);
+};
+
+extern struct pnx4008_dma_ll *pnx4008_alloc_ll_entry(dma_addr_t *);
+extern void pnx4008_free_ll_entry(struct pnx4008_dma_ll *, dma_addr_t);
+extern void pnx4008_free_ll(u32 ll_dma, struct pnx4008_dma_ll *);
+
+extern int pnx4008_request_channel(char *, int,
+ void (*)(int, int, void *),
+ void *);
+extern void pnx4008_free_channel(int);
+extern int pnx4008_config_dma(int, int, int);
+extern int pnx4008_dma_pack_control(const struct pnx4008_dma_ch_ctrl *,
+ unsigned long *);
+extern int pnx4008_dma_parse_control(unsigned long,
+ struct pnx4008_dma_ch_ctrl *);
+extern int pnx4008_dma_pack_config(const struct pnx4008_dma_ch_config *,
+ unsigned long *);
+extern int pnx4008_dma_parse_config(unsigned long,
+ struct pnx4008_dma_ch_config *);
+extern int pnx4008_config_channel(int, struct pnx4008_dma_config *);
+extern int pnx4008_channel_get_config(int, struct pnx4008_dma_config *);
+extern int pnx4008_dma_ch_enable(int);
+extern int pnx4008_dma_ch_disable(int);
+extern int pnx4008_dma_ch_enabled(int);
+extern void pnx4008_dma_split_head_entry(struct pnx4008_dma_config *,
+ struct pnx4008_dma_ch_ctrl *);
+extern void pnx4008_dma_split_ll_entry(struct pnx4008_dma_ll *,
+ struct pnx4008_dma_ch_ctrl *);
+
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-pnx4008/include/mach/entry-macro.S b/arch/arm/mach-pnx4008/include/mach/entry-macro.S
new file mode 100644
index 00000000..80030375
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/entry-macro.S
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for PNX4008-based platforms
+ *
+ * 2005-2006 (c) MontaVista Software, Inc.
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include "platform.h"
+
+#define IO_BASE 0xF0000000
+#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
+
+#define INTRC_MASK 0x00
+#define INTRC_RAW_STAT 0x04
+#define INTRC_STAT 0x08
+#define INTRC_POLAR 0x0C
+#define INTRC_ACT_TYPE 0x10
+#define INTRC_TYPE 0x14
+
+#define SIC1_BASE_INT 32
+#define SIC2_BASE_INT 64
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+/* decode the MIC interrupt numbers */
+ ldr \base, =IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
+ ldr \irqstat, [\base, #INTRC_STAT]
+
+ cmp \irqstat,#1<<16
+ movhs \irqnr,#16
+ movlo \irqnr,#0
+ movhs \irqstat,\irqstat,lsr#16
+ cmp \irqstat,#1<<8
+ addhs \irqnr,\irqnr,#8
+ movhs \irqstat,\irqstat,lsr#8
+ cmp \irqstat,#1<<4
+ addhs \irqnr,\irqnr,#4
+ movhs \irqstat,\irqstat,lsr#4
+ cmp \irqstat,#1<<2
+ addhs \irqnr,\irqnr,#2
+ movhs \irqstat,\irqstat,lsr#2
+ cmp \irqstat,#1<<1
+ addhs \irqnr,\irqnr,#1
+
+/* was there an interrupt ? if not then drop out with EQ status */
+ teq \irqstat,#0
+ beq 1003f
+
+/* and now check for extended IRQ reasons */
+ cmp \irqnr,#1
+ bls 1003f
+ cmp \irqnr,#30
+ blo 1002f
+
+/* IRQ 31,30 : High priority cascade IRQ handle */
+/* read the correct SIC */
+/* decoding status after compare : eq is 30 (SIC1) , ne is 31 (SIC2) */
+/* set the base IRQ number */
+ ldreq \base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+ moveq \irqnr,#SIC1_BASE_INT
+ ldrne \base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+ movne \irqnr,#SIC2_BASE_INT
+ ldr \irqstat, [\base, #INTRC_STAT]
+ ldr \tmp, [\base, #INTRC_TYPE]
+/* and with inverted mask : low priority interrupts */
+ and \irqstat,\irqstat,\tmp
+ b 1004f
+
+1003:
+/* IRQ 1,0 : Low priority cascade IRQ handle */
+/* read the correct SIC */
+/* decoding status after compare : eq is 1 (SIC2) , ne is 0 (SIC1)*/
+/* read the correct SIC */
+/* set the base IRQ number */
+ ldrne \base, =IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+ movne \irqnr,#SIC1_BASE_INT
+ ldreq \base, =IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+ moveq \irqnr,#SIC2_BASE_INT
+ ldr \irqstat, [\base, #INTRC_STAT]
+ ldr \tmp, [\base, #INTRC_TYPE]
+/* and with inverted mask : low priority interrupts */
+ bic \irqstat,\irqstat,\tmp
+
+1004:
+
+ cmp \irqstat,#1<<16
+ addhs \irqnr,\irqnr,#16
+ movhs \irqstat,\irqstat,lsr#16
+ cmp \irqstat,#1<<8
+ addhs \irqnr,\irqnr,#8
+ movhs \irqstat,\irqstat,lsr#8
+ cmp \irqstat,#1<<4
+ addhs \irqnr,\irqnr,#4
+ movhs \irqstat,\irqstat,lsr#4
+ cmp \irqstat,#1<<2
+ addhs \irqnr,\irqnr,#2
+ movhs \irqstat,\irqstat,lsr#2
+ cmp \irqstat,#1<<1
+ addhs \irqnr,\irqnr,#1
+
+
+/* is irqstat not zero */
+
+1002:
+/* we assert that irqstat is not equal to zero and return ne status if true*/
+ teq \irqstat,#0
+1003:
+ .endm
+
+
+ .macro irq_prio_table
+ .endm
+
+
diff --git a/arch/arm/mach-pnx4008/include/mach/gpio.h b/arch/arm/mach-pnx4008/include/mach/gpio.h
new file mode 100644
index 00000000..9591467e
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/gpio.h
@@ -0,0 +1,241 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/gpio.h
+ *
+ * PNX4008 GPIO driver - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code by Iwo Mergler and Z.Tabaaloute from Philips:
+ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef _PNX4008_GPIO_H_
+#define _PNX4008_GPIO_H_
+
+
+/* Block numbers */
+#define GPIO_IN (0)
+#define GPIO_OUT (0x100)
+#define GPIO_BID (0x200)
+#define GPIO_RAM (0x300)
+#define GPIO_MUX (0x400)
+
+#define GPIO_TYPE_MASK(K) ((K) & 0x700)
+
+/* INPUT GPIOs */
+/* GPI */
+#define GPI_00 (GPIO_IN | 0)
+#define GPI_01 (GPIO_IN | 1)
+#define GPI_02 (GPIO_IN | 2)
+#define GPI_03 (GPIO_IN | 3)
+#define GPI_04 (GPIO_IN | 4)
+#define GPI_05 (GPIO_IN | 5)
+#define GPI_06 (GPIO_IN | 6)
+#define GPI_07 (GPIO_IN | 7)
+#define GPI_08 (GPIO_IN | 8)
+#define GPI_09 (GPIO_IN | 9)
+#define U1_RX (GPIO_IN | 15)
+#define U2_HTCS (GPIO_IN | 16)
+#define U2_RX (GPIO_IN | 17)
+#define U3_RX (GPIO_IN | 18)
+#define U4_RX (GPIO_IN | 19)
+#define U5_RX (GPIO_IN | 20)
+#define U6_IRRX (GPIO_IN | 21)
+#define U7_HCTS (GPIO_IN | 22)
+#define U7_RX (GPIO_IN | 23)
+/* MISC IN */
+#define SPI1_DATIN (GPIO_IN | 25)
+#define DISP_SYNC (GPIO_IN | 26)
+#define SPI2_DATIN (GPIO_IN | 27)
+#define GPI_11 (GPIO_IN | 28)
+
+#define GPIO_IN_MASK 0x1eff83ff
+
+/* OUTPUT GPIOs */
+/* GPO */
+#define GPO_00 (GPIO_OUT | 0)
+#define GPO_01 (GPIO_OUT | 1)
+#define GPO_02 (GPIO_OUT | 2)
+#define GPO_03 (GPIO_OUT | 3)
+#define GPO_04 (GPIO_OUT | 4)
+#define GPO_05 (GPIO_OUT | 5)
+#define GPO_06 (GPIO_OUT | 6)
+#define GPO_07 (GPIO_OUT | 7)
+#define GPO_08 (GPIO_OUT | 8)
+#define GPO_09 (GPIO_OUT | 9)
+#define GPO_10 (GPIO_OUT | 10)
+#define GPO_11 (GPIO_OUT | 11)
+#define GPO_12 (GPIO_OUT | 12)
+#define GPO_13 (GPIO_OUT | 13)
+#define GPO_14 (GPIO_OUT | 14)
+#define GPO_15 (GPIO_OUT | 15)
+#define GPO_16 (GPIO_OUT | 16)
+#define GPO_17 (GPIO_OUT | 17)
+#define GPO_18 (GPIO_OUT | 18)
+#define GPO_19 (GPIO_OUT | 19)
+#define GPO_20 (GPIO_OUT | 20)
+#define GPO_21 (GPIO_OUT | 21)
+#define GPO_22 (GPIO_OUT | 22)
+#define GPO_23 (GPIO_OUT | 23)
+
+#define GPIO_OUT_MASK 0xffffff
+
+/* BIDIRECTIONAL GPIOs */
+/* RAM pins */
+#define RAM_D19 (GPIO_RAM | 0)
+#define RAM_D20 (GPIO_RAM | 1)
+#define RAM_D21 (GPIO_RAM | 2)
+#define RAM_D22 (GPIO_RAM | 3)
+#define RAM_D23 (GPIO_RAM | 4)
+#define RAM_D24 (GPIO_RAM | 5)
+#define RAM_D25 (GPIO_RAM | 6)
+#define RAM_D26 (GPIO_RAM | 7)
+#define RAM_D27 (GPIO_RAM | 8)
+#define RAM_D28 (GPIO_RAM | 9)
+#define RAM_D29 (GPIO_RAM | 10)
+#define RAM_D30 (GPIO_RAM | 11)
+#define RAM_D31 (GPIO_RAM | 12)
+
+#define GPIO_RAM_MASK 0x1fff
+
+/* I/O pins */
+#define GPIO_00 (GPIO_BID | 25)
+#define GPIO_01 (GPIO_BID | 26)
+#define GPIO_02 (GPIO_BID | 27)
+#define GPIO_03 (GPIO_BID | 28)
+#define GPIO_04 (GPIO_BID | 29)
+#define GPIO_05 (GPIO_BID | 30)
+
+#define GPIO_BID_MASK 0x7e000000
+
+/* Non-GPIO multiplexed PIOs. For multiplexing with GPIO, please use GPIO macros */
+#define GPIO_SDRAM_SEL (GPIO_MUX | 3)
+
+#define GPIO_MUX_MASK 0x8
+
+/* Extraction/assembly macros */
+#define GPIO_BIT_MASK(K) ((K) & 0x1F)
+#define GPIO_BIT(K) (1 << GPIO_BIT_MASK(K))
+#define GPIO_ISMUX(K) ((GPIO_TYPE_MASK(K) == GPIO_MUX) && (GPIO_BIT(K) & GPIO_MUX_MASK))
+#define GPIO_ISRAM(K) ((GPIO_TYPE_MASK(K) == GPIO_RAM) && (GPIO_BIT(K) & GPIO_RAM_MASK))
+#define GPIO_ISBID(K) ((GPIO_TYPE_MASK(K) == GPIO_BID) && (GPIO_BIT(K) & GPIO_BID_MASK))
+#define GPIO_ISOUT(K) ((GPIO_TYPE_MASK(K) == GPIO_OUT) && (GPIO_BIT(K) & GPIO_OUT_MASK))
+#define GPIO_ISIN(K) ((GPIO_TYPE_MASK(K) == GPIO_IN) && (GPIO_BIT(K) & GPIO_IN_MASK))
+
+/* Start Enable Pin Interrupts - table 58 page 66 */
+
+#define SE_PIN_BASE_INT 32
+
+#define SE_U7_RX_INT 63
+#define SE_U7_HCTS_INT 62
+#define SE_BT_CLKREQ_INT 61
+#define SE_U6_IRRX_INT 60
+/*59 unused*/
+#define SE_U5_RX_INT 58
+#define SE_GPI_11_INT 57
+#define SE_U3_RX_INT 56
+#define SE_U2_HCTS_INT 55
+#define SE_U2_RX_INT 54
+#define SE_U1_RX_INT 53
+#define SE_DISP_SYNC_INT 52
+/*51 unused*/
+#define SE_SDIO_INT_N 50
+#define SE_MSDIO_START_INT 49
+#define SE_GPI_06_INT 48
+#define SE_GPI_05_INT 47
+#define SE_GPI_04_INT 46
+#define SE_GPI_03_INT 45
+#define SE_GPI_02_INT 44
+#define SE_GPI_01_INT 43
+#define SE_GPI_00_INT 42
+#define SE_SYSCLKEN_PIN_INT 41
+#define SE_SPI1_DATAIN_INT 40
+#define SE_GPI_07_INT 39
+#define SE_SPI2_DATAIN_INT 38
+#define SE_GPI_10_INT 37
+#define SE_GPI_09_INT 36
+#define SE_GPI_08_INT 35
+/*34-32 unused*/
+
+/* Start Enable Internal Interrupts - table 57 page 65 */
+
+#define SE_INT_BASE_INT 0
+
+#define SE_TS_IRQ 31
+#define SE_TS_P_INT 30
+#define SE_TS_AUX_INT 29
+/*27-28 unused*/
+#define SE_USB_AHB_NEED_CLK_INT 26
+#define SE_MSTIMER_INT 25
+#define SE_RTC_INT 24
+#define SE_USB_NEED_CLK_INT 23
+#define SE_USB_INT 22
+#define SE_USB_I2C_INT 21
+#define SE_USB_OTG_TIMER_INT 20
+#define SE_USB_OTG_ATX_INT_N 19
+/*18 unused*/
+#define SE_DSP_GPIO4_INT 17
+#define SE_KEY_IRQ 16
+#define SE_DSP_SLAVEPORT_INT 15
+#define SE_DSP_GPIO1_INT 14
+#define SE_DSP_GPIO0_INT 13
+#define SE_DSP_AHB_INT 12
+/*11-6 unused*/
+#define SE_GPIO_05_INT 5
+#define SE_GPIO_04_INT 4
+#define SE_GPIO_03_INT 3
+#define SE_GPIO_02_INT 2
+#define SE_GPIO_01_INT 1
+#define SE_GPIO_00_INT 0
+
+#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
+
+#define START_INT_ER_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_RSR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_SR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_APR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
+
+extern int pnx4008_gpio_register_pin(unsigned short pin);
+extern int pnx4008_gpio_unregister_pin(unsigned short pin);
+extern unsigned long pnx4008_gpio_read_pin(unsigned short pin);
+extern int pnx4008_gpio_write_pin(unsigned short pin, int output);
+extern int pnx4008_gpio_set_pin_direction(unsigned short pin, int output);
+extern int pnx4008_gpio_read_pin_direction(unsigned short pin);
+extern int pnx4008_gpio_set_pin_mux(unsigned short pin, int output);
+extern int pnx4008_gpio_read_pin_mux(unsigned short pin);
+
+static inline void start_int_umask(u8 irq)
+{
+ __raw_writel(__raw_readl(START_INT_ER_REG(irq)) |
+ START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
+}
+
+static inline void start_int_mask(u8 irq)
+{
+ __raw_writel(__raw_readl(START_INT_ER_REG(irq)) &
+ ~START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
+}
+
+static inline void start_int_ack(u8 irq)
+{
+ __raw_writel(START_INT_REG_BIT(irq), START_INT_RSR_REG(irq));
+}
+
+static inline void start_int_set_falling_edge(u8 irq)
+{
+ __raw_writel(__raw_readl(START_INT_APR_REG(irq)) &
+ ~START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
+}
+
+static inline void start_int_set_rising_edge(u8 irq)
+{
+ __raw_writel(__raw_readl(START_INT_APR_REG(irq)) |
+ START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
+}
+
+#endif /* _PNX4008_GPIO_H_ */
diff --git a/arch/arm/mach-pnx4008/include/mach/hardware.h b/arch/arm/mach-pnx4008/include/mach/hardware.h
new file mode 100644
index 00000000..7b98b828
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/hardware.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/hardware.h
+ *
+ * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/platform.h>
+
+/* Start of virtual addresses for IO devices */
+#define IO_BASE 0xF0000000
+
+/* This macro relies on fact that for all HW i/o addresses bits 20-23 are 0 */
+#define IO_ADDRESS(x) (((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) | IO_BASE)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/i2c.h b/arch/arm/mach-pnx4008/include/mach/i2c.h
new file mode 100644
index 00000000..259ac53a
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/i2c.h
@@ -0,0 +1,64 @@
+/*
+ * PNX4008-specific tweaks for I2C IP3204 block
+ *
+ * Author: Vitaly Wool <vwool@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARCH_I2C_H__
+#define __ASM_ARCH_I2C_H__
+
+enum {
+ mstatus_tdi = 0x00000001,
+ mstatus_afi = 0x00000002,
+ mstatus_nai = 0x00000004,
+ mstatus_drmi = 0x00000008,
+ mstatus_active = 0x00000020,
+ mstatus_scl = 0x00000040,
+ mstatus_sda = 0x00000080,
+ mstatus_rff = 0x00000100,
+ mstatus_rfe = 0x00000200,
+ mstatus_tff = 0x00000400,
+ mstatus_tfe = 0x00000800,
+};
+
+enum {
+ mcntrl_tdie = 0x00000001,
+ mcntrl_afie = 0x00000002,
+ mcntrl_naie = 0x00000004,
+ mcntrl_drmie = 0x00000008,
+ mcntrl_daie = 0x00000020,
+ mcntrl_rffie = 0x00000040,
+ mcntrl_tffie = 0x00000080,
+ mcntrl_reset = 0x00000100,
+ mcntrl_cdbmode = 0x00000400,
+};
+
+enum {
+ rw_bit = 1 << 0,
+ start_bit = 1 << 8,
+ stop_bit = 1 << 9,
+};
+
+#define I2C_REG_RX(a) ((a)->ioaddr) /* Rx FIFO reg (RO) */
+#define I2C_REG_TX(a) ((a)->ioaddr) /* Tx FIFO reg (WO) */
+#define I2C_REG_STS(a) ((a)->ioaddr + 0x04) /* Status reg (RO) */
+#define I2C_REG_CTL(a) ((a)->ioaddr + 0x08) /* Ctl reg */
+#define I2C_REG_CKL(a) ((a)->ioaddr + 0x0c) /* Clock divider low */
+#define I2C_REG_CKH(a) ((a)->ioaddr + 0x10) /* Clock divider high */
+#define I2C_REG_ADR(a) ((a)->ioaddr + 0x14) /* I2C address */
+#define I2C_REG_RFL(a) ((a)->ioaddr + 0x18) /* Rx FIFO level (RO) */
+#define I2C_REG_TFL(a) ((a)->ioaddr + 0x1c) /* Tx FIFO level (RO) */
+#define I2C_REG_RXB(a) ((a)->ioaddr + 0x20) /* Num of bytes Rx-ed (RO) */
+#define I2C_REG_TXB(a) ((a)->ioaddr + 0x24) /* Num of bytes Tx-ed (RO) */
+#define I2C_REG_TXS(a) ((a)->ioaddr + 0x28) /* Tx slave FIFO (RO) */
+#define I2C_REG_STFL(a) ((a)->ioaddr + 0x2c) /* Tx slave FIFO level (RO) */
+
+#define HCLK_MHZ 13
+#define I2C_CHIP_NAME "PNX4008-I2C"
+
+#endif /* __ASM_ARCH_I2C_H___ */
diff --git a/arch/arm/mach-pnx4008/include/mach/io.h b/arch/arm/mach-pnx4008/include/mach/io.h
new file mode 100644
index 00000000..cbf09045
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/io.h
@@ -0,0 +1,21 @@
+
+/*
+ * arch/arm/mach-pnx4008/include/mach/io.h
+ *
+ * Author: Dmitry Chigirev <chigirev@ru.mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/irq.h b/arch/arm/mach-pnx4008/include/mach/irq.h
new file mode 100644
index 00000000..2a690ca3
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/irq.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/irq.h
+ *
+ * PNX4008 IRQ controller driver - header file
+ * this one is used in entry-arnv.S as well so it cannot contain C code
+ *
+ * Copyright (c) 2005 Philips Semiconductors
+ * Copyright (c) 2005 MontaVista Software, 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.
+ */
+#ifndef __PNX4008_IRQ_H__
+#define __PNX4008_IRQ_H__
+
+#define MIC_VA_BASE IO_ADDRESS(PNX4008_INTCTRLMIC_BASE)
+#define SIC1_VA_BASE IO_ADDRESS(PNX4008_INTCTRLSIC1_BASE)
+#define SIC2_VA_BASE IO_ADDRESS(PNX4008_INTCTRLSIC2_BASE)
+
+/* Manual: Chapter 20, page 195 */
+
+#define INTC_BIT(irq) (1<< ((irq) & 0x1F))
+
+#define INTC_ER(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x0 + (((irq)&(0x3<<5))<<9)))
+#define INTC_RSR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x4 + (((irq)&(0x3<<5))<<9)))
+#define INTC_SR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x8 + (((irq)&(0x3<<5))<<9)))
+#define INTC_APR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0xC + (((irq)&(0x3<<5))<<9)))
+#define INTC_ATR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x10 + (((irq)&(0x3<<5))<<9)))
+#define INTC_ITR(irq) IO_ADDRESS((PNX4008_INTCTRLMIC_BASE + 0x14 + (((irq)&(0x3<<5))<<9)))
+
+#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
+
+#define START_INT_ER_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_RSR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_SR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
+#define START_INT_APR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
+
+extern void __init pnx4008_init_irq(void);
+
+#endif /* __PNX4008_IRQ_H__ */
diff --git a/arch/arm/mach-pnx4008/include/mach/irqs.h b/arch/arm/mach-pnx4008/include/mach/irqs.h
new file mode 100644
index 00000000..f6b33cf2
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/irqs.h
@@ -0,0 +1,215 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/irqs.h
+ *
+ * PNX4008 IRQ controller driver - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef __PNX4008_IRQS_h__
+#define __PNX4008_IRQS_h__
+
+#define NR_IRQS 96
+
+/*Manual: table 259, page 199*/
+
+/*SUB2 Interrupt Routing (SIC2)*/
+
+#define SIC2_BASE_INT 64
+
+#define CLK_SWITCH_ARM_INT 95 /*manual: Clkswitch ARM */
+#define CLK_SWITCH_DSP_INT 94 /*manual: ClkSwitch DSP */
+#define CLK_SWITCH_AUD_INT 93 /*manual: Clkswitch AUD */
+#define GPI_06_INT 92
+#define GPI_05_INT 91
+#define GPI_04_INT 90
+#define GPI_03_INT 89
+#define GPI_02_INT 88
+#define GPI_01_INT 87
+#define GPI_00_INT 86
+#define BT_CLKREQ_INT 85
+#define SPI1_DATIN_INT 84
+#define U5_RX_INT 83
+#define SDIO_INT_N 82
+#define CAM_HS_INT 81
+#define CAM_VS_INT 80
+#define GPI_07_INT 79
+#define DISP_SYNC_INT 78
+#define DSP_INT8 77
+#define U7_HCTS_INT 76
+#define GPI_10_INT 75
+#define GPI_09_INT 74
+#define GPI_08_INT 73
+#define DSP_INT7 72
+#define U2_HCTS_INT 71
+#define SPI2_DATIN_INT 70
+#define GPIO_05_INT 69
+#define GPIO_04_INT 68
+#define GPIO_03_INT 67
+#define GPIO_02_INT 66
+#define GPIO_01_INT 65
+#define GPIO_00_INT 64
+
+/*Manual: table 258, page 198*/
+
+/*SUB1 Interrupt Routing (SIC1)*/
+
+#define SIC1_BASE_INT 32
+
+#define USB_I2C_INT 63
+#define USB_DEV_HP_INT 62
+#define USB_DEV_LP_INT 61
+#define USB_DEV_DMA_INT 60
+#define USB_HOST_INT 59
+#define USB_OTG_ATX_INT_N 58
+#define USB_OTG_TIMER_INT 57
+#define SW_INT 56
+#define SPI1_INT 55
+#define KEY_IRQ 54
+#define DSP_M_INT 53
+#define RTC_INT 52
+#define I2C_1_INT 51
+#define I2C_2_INT 50
+#define PLL1_LOCK_INT 49
+#define PLL2_LOCK_INT 48
+#define PLL3_LOCK_INT 47
+#define PLL4_LOCK_INT 46
+#define PLL5_LOCK_INT 45
+#define SPI2_INT 44
+#define DSP_INT1 43
+#define DSP_INT2 42
+#define DSP_TDM_INT2 41
+#define TS_AUX_INT 40
+#define TS_IRQ 39
+#define TS_P_INT 38
+#define UOUT1_TO_PAD_INT 37
+#define GPI_11_INT 36
+#define DSP_INT4 35
+#define JTAG_COMM_RX_INT 34
+#define JTAG_COMM_TX_INT 33
+#define DSP_INT3 32
+
+/*Manual: table 257, page 197*/
+
+/*MAIN Interrupt Routing*/
+
+#define MAIN_BASE_INT 0
+
+#define SUB2_FIQ_N 31 /*active low */
+#define SUB1_FIQ_N 30 /*active low */
+#define JPEG_INT 29
+#define DMA_INT 28
+#define MSTIMER_INT 27
+#define IIR1_INT 26
+#define IIR2_INT 25
+#define IIR7_INT 24
+#define DSP_TDM_INT0 23
+#define DSP_TDM_INT1 22
+#define DSP_P_INT 21
+#define DSP_INT0 20
+#define DUM_INT 19
+#define UOUT0_TO_PAD_INT 18
+#define MP4_ENC_INT 17
+#define MP4_DEC_INT 16
+#define SD0_INT 15
+#define MBX_INT 14
+#define SD1_INT 13
+#define MS_INT_N 12
+#define FLASH_INT 11 /*NAND*/
+#define IIR6_INT 10
+#define IIR5_INT 9
+#define IIR4_INT 8
+#define IIR3_INT 7
+#define WATCH_INT 6
+#define HSTIMER_INT 5
+#define ARCH_TIMER_IRQ HSTIMER_INT
+#define CAM_INT 4
+#define PRNG_INT 3
+#define CRYPTO_INT 2
+#define SUB2_IRQ_N 1 /*active low */
+#define SUB1_IRQ_N 0 /*active low */
+
+#define PNX4008_IRQ_TYPES \
+{ /*IRQ #'s: */ \
+IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, /* 0, 1, 2, 3 */ \
+IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 4, 5, 6, 7 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 8, 9,10,11 */ \
+IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 12,13,14,15 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 16,17,18,19 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 20,21,22,23 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 24,25,26,27 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, /* 28,29,30,31 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 32,33,34,35 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_EDGE_FALLING, IRQ_TYPE_LEVEL_HIGH, /* 36,37,38,39 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 40,41,42,43 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 44,45,46,47 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_LOW, /* 48,49,50,51 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 52,53,54,55 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_LOW, IRQ_TYPE_LEVEL_HIGH, /* 56,57,58,59 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 60,61,62,63 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 64,65,66,67 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 68,69,70,71 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 72,73,74,75 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 76,77,78,79 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 80,81,82,83 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 84,85,86,87 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 88,89,90,91 */ \
+IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, IRQ_TYPE_LEVEL_HIGH, /* 92,93,94,95 */ \
+}
+
+/* Start Enable Pin Interrupts - table 58 page 66 */
+
+#define SE_PIN_BASE_INT 32
+
+#define SE_U7_RX_INT 63
+#define SE_U7_HCTS_INT 62
+#define SE_BT_CLKREQ_INT 61
+#define SE_U6_IRRX_INT 60
+/*59 unused*/
+#define SE_U5_RX_INT 58
+#define SE_GPI_11_INT 57
+#define SE_U3_RX_INT 56
+#define SE_U2_HCTS_INT 55
+#define SE_U2_RX_INT 54
+#define SE_U1_RX_INT 53
+#define SE_DISP_SYNC_INT 52
+/*51 unused*/
+#define SE_SDIO_INT_N 50
+#define SE_MSDIO_START_INT 49
+#define SE_GPI_06_INT 48
+#define SE_GPI_05_INT 47
+#define SE_GPI_04_INT 46
+#define SE_GPI_03_INT 45
+#define SE_GPI_02_INT 44
+#define SE_GPI_01_INT 43
+#define SE_GPI_00_INT 42
+#define SE_SYSCLKEN_PIN_INT 41
+#define SE_SPI1_DATAIN_INT 40
+#define SE_GPI_07_INT 39
+#define SE_SPI2_DATAIN_INT 38
+#define SE_GPI_10_INT 37
+#define SE_GPI_09_INT 36
+#define SE_GPI_08_INT 35
+/*34-32 unused*/
+
+/* Start Enable Internal Interrupts - table 57 page 65 */
+
+#define SE_INT_BASE_INT 0
+
+#define SE_TS_IRQ 31
+#define SE_TS_P_INT 30
+#define SE_TS_AUX_INT 29
+/*27-28 unused*/
+#define SE_USB_AHB_NEED_CLK_INT 26
+#define SE_MSTIMER_INT 25
+#define SE_RTC_INT 24
+#define SE_USB_NEED_CLK_INT 23
+#define SE_USB_INT 22
+#define SE_USB_I2C_INT 21
+#define SE_USB_OTG_TIMER_INT 20
+
+#endif /* __PNX4008_IRQS_h__ */
diff --git a/arch/arm/mach-pnx4008/include/mach/memory.h b/arch/arm/mach-pnx4008/include/mach/memory.h
new file mode 100644
index 00000000..1275db61
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/memory.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/memory.h
+ *
+ * Copyright (c) 2005 Philips Semiconductors
+ * Copyright (c) 2005 MontaVista Software, 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.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x80000000)
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/param.h b/arch/arm/mach-pnx4008/include/mach/param.h
new file mode 100644
index 00000000..6ea02f21
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/param.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/param.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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
+ */
+
+#define HZ 100
diff --git a/arch/arm/mach-pnx4008/include/mach/platform.h b/arch/arm/mach-pnx4008/include/mach/platform.h
new file mode 100644
index 00000000..368c2c10
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/platform.h
@@ -0,0 +1,69 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/platform.h
+ *
+ * PNX4008 Base addresses - header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+
+#ifndef __ASM_ARCH_PLATFORM_H__
+#define __ASM_ARCH_PLATFORM_H__
+
+#define PNX4008_IRAM_BASE 0x08000000
+#define PNX4008_IRAM_SIZE 0x00010000
+#define PNX4008_YUV_SLAVE_BASE 0x10000000
+#define PNX4008_DUM_SLAVE_BASE 0x18000000
+#define PNX4008_NDF_FLASH_BASE 0x20020000
+#define PNX4008_SPI1_BASE 0x20088000
+#define PNX4008_SPI2_BASE 0x20090000
+#define PNX4008_SD_CONFIG_BASE 0x20098000
+#define PNX4008_FLASH_DATA 0x200B0000
+#define PNX4008_MLC_FLASH_BASE 0x200B8000
+#define PNX4008_JPEG_CONFIG_BASE 0x300A0000
+#define PNX4008_DMA_CONFIG_BASE 0x31000000
+#define PNX4008_USB_CONFIG_BASE 0x31020000
+#define PNX4008_SDRAM_CFG_BASE 0x31080000
+#define PNX4008_AHB2FAB_BASE 0x40000000
+#define PNX4008_PWRMAN_BASE 0x40004000
+#define PNX4008_INTCTRLMIC_BASE 0x40008000
+#define PNX4008_INTCTRLSIC1_BASE 0x4000C000
+#define PNX4008_INTCTRLSIC2_BASE 0x40010000
+#define PNX4008_HSUART1_BASE 0x40014000
+#define PNX4008_HSUART2_BASE 0x40018000
+#define PNX4008_HSUART7_BASE 0x4001C000
+#define PNX4008_RTC_BASE 0x40024000
+#define PNX4008_PIO_BASE 0x40028000
+#define PNX4008_MSTIMER_BASE 0x40034000
+#define PNX4008_HSTIMER_BASE 0x40038000
+#define PNX4008_WDOG_BASE 0x4003C000
+#define PNX4008_DEBUG_BASE 0x40040000
+#define PNX4008_TOUCH1_BASE 0x40048000
+#define PNX4008_KEYSCAN_BASE 0x40050000
+#define PNX4008_UARTCTRL_BASE 0x40054000
+#define PNX4008_PWM_BASE 0x4005C000
+#define PNX4008_UART3_BASE 0x40080000
+#define PNX4008_UART4_BASE 0x40088000
+#define PNX4008_UART5_BASE 0x40090000
+#define PNX4008_UART6_BASE 0x40098000
+#define PNX4008_I2C1_BASE 0x400A0000
+#define PNX4008_I2C2_BASE 0x400A8000
+#define PNX4008_MAGICGATE_BASE 0x400B0000
+#define PNX4008_DUMCONF_BASE 0x400B8000
+#define PNX4008_DUM_MAINCFG_BASE 0x400BC000
+#define PNX4008_DSP_BASE 0x400C0000
+#define PNX4008_PROFCOUNTER_BASE 0x400C8000
+#define PNX4008_CRYPTO_BASE 0x400D0000
+#define PNX4008_CAMIFCONF_BASE 0x400D8000
+#define PNX4008_YUV2RGB_BASE 0x400E0000
+#define PNX4008_AUDIOCONFIG_BASE 0x400E8000
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/pm.h b/arch/arm/mach-pnx4008/include/mach/pm.h
new file mode 100644
index 00000000..2fa685bf
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/pm.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/pm.h
+ *
+ * PNX4008 Power Management Routiness - header file
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_ARCH_PNX4008_PM_H
+#define __ASM_ARCH_PNX4008_PM_H
+
+#ifndef __ASSEMBLER__
+#include "irq.h"
+#include "irqs.h"
+#include "clock.h"
+
+extern void pnx4008_pm_idle(void);
+extern void pnx4008_pm_suspend(void);
+extern unsigned int pnx4008_cpu_suspend_sz;
+extern void pnx4008_cpu_suspend(void);
+extern unsigned int pnx4008_cpu_standby_sz;
+extern void pnx4008_cpu_standby(void);
+
+extern int pnx4008_startup_pll(struct clk *);
+extern int pnx4008_shutdown_pll(struct clk *);
+
+#endif /* ASSEMBLER */
+#endif /* __ASM_ARCH_PNX4008_PM_H */
diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h
new file mode 100644
index 00000000..5dda2bb5
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/system.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/system.h
+ *
+ * Copyright (C) 2003 Philips Semiconductors
+ * Copyright (C) 2005 MontaVista Software, 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+static void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/timex.h b/arch/arm/mach-pnx4008/include/mach/timex.h
new file mode 100644
index 00000000..b383c7de
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/timex.h
+ *
+ * PNX4008 timers header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __PNX4008_TIMEX_H
+#define __PNX4008_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/uncompress.h b/arch/arm/mach-pnx4008/include/mach/uncompress.h
new file mode 100644
index 00000000..bb4751ee
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2006 MontaVista Software, 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
+ */
+
+#define UART5_BASE 0x40090000
+
+#define UART5_DR (*(volatile unsigned char *) (UART5_BASE))
+#define UART5_FR (*(volatile unsigned char *) (UART5_BASE + 18))
+
+static __inline__ void putc(char c)
+{
+ while (UART5_FR & (1 << 5))
+ barrier();
+
+ UART5_DR = c;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-pnx4008/include/mach/vmalloc.h b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
new file mode 100644
index 00000000..184913c7
--- /dev/null
+++ b/arch/arm/mach-pnx4008/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/vmalloc.h
+ *
+ * Author: Vitaly Wool <source@mvista.com>
+ *
+ * 2006 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+/*
+ * Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
new file mode 100644
index 00000000..7608c7a2
--- /dev/null
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -0,0 +1,122 @@
+/*
+ * arch/arm/mach-pnx4008/irq.c
+ *
+ * PNX4008 IRQ controller driver
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * Based on reference code received from Philips:
+ * Copyright (C) 2003 Philips Semiconductors
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+#include <mach/irq.h>
+
+static u8 pnx4008_irq_type[NR_IRQS] = PNX4008_IRQ_TYPES;
+
+static void pnx4008_mask_irq(struct irq_data *d)
+{
+ __raw_writel(__raw_readl(INTC_ER(d->irq)) & ~INTC_BIT(d->irq), INTC_ER(d->irq)); /* mask interrupt */
+}
+
+static void pnx4008_unmask_irq(struct irq_data *d)
+{
+ __raw_writel(__raw_readl(INTC_ER(d->irq)) | INTC_BIT(d->irq), INTC_ER(d->irq)); /* unmask interrupt */
+}
+
+static void pnx4008_mask_ack_irq(struct irq_data *d)
+{
+ __raw_writel(__raw_readl(INTC_ER(d->irq)) & ~INTC_BIT(d->irq), INTC_ER(d->irq)); /* mask interrupt */
+ __raw_writel(INTC_BIT(d->irq), INTC_SR(d->irq)); /* clear interrupt status */
+}
+
+static int pnx4008_set_irq_type(struct irq_data *d, unsigned int type)
+{
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ __raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */
+ __raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /*rising edge */
+ irq_set_handler(d->irq, handle_edge_irq);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ __raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */
+ __raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*falling edge */
+ irq_set_handler(d->irq, handle_edge_irq);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ __raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */
+ __raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*low level */
+ irq_set_handler(d->irq, handle_level_irq);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ __raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */
+ __raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /* high level */
+ irq_set_handler(d->irq, handle_level_irq);
+ break;
+
+ /* IRQ_TYPE_EDGE_BOTH is not supported */
+ default:
+ printk(KERN_ERR "PNX4008 IRQ: Unsupported irq type %d\n", type);
+ return -1;
+ }
+ return 0;
+}
+
+static struct irq_chip pnx4008_irq_chip = {
+ .irq_ack = pnx4008_mask_ack_irq,
+ .irq_mask = pnx4008_mask_irq,
+ .irq_unmask = pnx4008_unmask_irq,
+ .irq_set_type = pnx4008_set_irq_type,
+};
+
+void __init pnx4008_init_irq(void)
+{
+ unsigned int i;
+
+ /* configure IRQ's */
+ for (i = 0; i < NR_IRQS; i++) {
+ set_irq_flags(i, IRQF_VALID);
+ irq_set_chip(i, &pnx4008_irq_chip);
+ pnx4008_set_irq_type(irq_get_irq_data(i), pnx4008_irq_type[i]);
+ }
+
+ /* configure and enable IRQ 0,1,30,31 (cascade interrupts) */
+ pnx4008_set_irq_type(irq_get_irq_data(SUB1_IRQ_N),
+ pnx4008_irq_type[SUB1_IRQ_N]);
+ pnx4008_set_irq_type(irq_get_irq_data(SUB2_IRQ_N),
+ pnx4008_irq_type[SUB2_IRQ_N]);
+ pnx4008_set_irq_type(irq_get_irq_data(SUB1_FIQ_N),
+ pnx4008_irq_type[SUB1_FIQ_N]);
+ pnx4008_set_irq_type(irq_get_irq_data(SUB2_FIQ_N),
+ pnx4008_irq_type[SUB2_FIQ_N]);
+
+ /* mask all others */
+ __raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
+ (1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
+ INTC_ER(MAIN_BASE_INT));
+ __raw_writel(0, INTC_ER(SIC1_BASE_INT));
+ __raw_writel(0, INTC_ER(SIC2_BASE_INT));
+}
+
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c
new file mode 100644
index 00000000..f3e60a04
--- /dev/null
+++ b/arch/arm/mach-pnx4008/pm.c
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-pnx4008/pm.c
+ *
+ * Power Management driver for PNX4008
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/pm.h>
+#include <linux/rtc.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <linux/suspend.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/hardware.h>
+#include <mach/pm.h>
+#include <mach/clock.h>
+
+#define SRAM_VA IO_ADDRESS(PNX4008_IRAM_BASE)
+
+static void *saved_sram;
+
+static struct clk *pll4_clk;
+
+static inline void pnx4008_standby(void)
+{
+ void (*pnx4008_cpu_standby_ptr) (void);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ clk_disable(pll4_clk);
+
+ /*saving portion of SRAM to be used by suspend function. */
+ memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_standby_sz);
+
+ /*make sure SRAM copy gets physically written into SDRAM.
+ SDRAM will be placed into self-refresh during power down */
+ flush_cache_all();
+
+ /*copy suspend function into SRAM */
+ memcpy((void *)SRAM_VA, pnx4008_cpu_standby, pnx4008_cpu_standby_sz);
+
+ /*do suspend */
+ pnx4008_cpu_standby_ptr = (void *)SRAM_VA;
+ pnx4008_cpu_standby_ptr();
+
+ /*restoring portion of SRAM that was used by suspend function */
+ memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_standby_sz);
+
+ clk_enable(pll4_clk);
+
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+static inline void pnx4008_suspend(void)
+{
+ void (*pnx4008_cpu_suspend_ptr) (void);
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ clk_disable(pll4_clk);
+
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_PIN_BASE_INT));
+ __raw_writel(0xffffffff, START_INT_RSR_REG(SE_INT_BASE_INT));
+
+ /*saving portion of SRAM to be used by suspend function. */
+ memcpy(saved_sram, (void *)SRAM_VA, pnx4008_cpu_suspend_sz);
+
+ /*make sure SRAM copy gets physically written into SDRAM.
+ SDRAM will be placed into self-refresh during power down */
+ flush_cache_all();
+
+ /*copy suspend function into SRAM */
+ memcpy((void *)SRAM_VA, pnx4008_cpu_suspend, pnx4008_cpu_suspend_sz);
+
+ /*do suspend */
+ pnx4008_cpu_suspend_ptr = (void *)SRAM_VA;
+ pnx4008_cpu_suspend_ptr();
+
+ /*restoring portion of SRAM that was used by suspend function */
+ memcpy((void *)SRAM_VA, saved_sram, pnx4008_cpu_suspend_sz);
+
+ clk_enable(pll4_clk);
+
+ local_fiq_enable();
+ local_irq_enable();
+}
+
+static int pnx4008_pm_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ pnx4008_standby();
+ break;
+ case PM_SUSPEND_MEM:
+ pnx4008_suspend();
+ break;
+ }
+ return 0;
+}
+
+static int pnx4008_pm_valid(suspend_state_t state)
+{
+ return (state == PM_SUSPEND_STANDBY) ||
+ (state == PM_SUSPEND_MEM);
+}
+
+static const struct platform_suspend_ops pnx4008_pm_ops = {
+ .enter = pnx4008_pm_enter,
+ .valid = pnx4008_pm_valid,
+};
+
+static int __init pnx4008_pm_init(void)
+{
+ u32 sram_size_to_allocate;
+
+ pll4_clk = clk_get(0, "ck_pll4");
+ if (IS_ERR(pll4_clk)) {
+ printk(KERN_ERR
+ "PM Suspend cannot acquire ARM(PLL4) clock control\n");
+ return PTR_ERR(pll4_clk);
+ }
+
+ if (pnx4008_cpu_standby_sz > pnx4008_cpu_suspend_sz)
+ sram_size_to_allocate = pnx4008_cpu_standby_sz;
+ else
+ sram_size_to_allocate = pnx4008_cpu_suspend_sz;
+
+ saved_sram = kmalloc(sram_size_to_allocate, GFP_ATOMIC);
+ if (!saved_sram) {
+ printk(KERN_ERR
+ "PM Suspend: cannot allocate memory to save portion of SRAM\n");
+ clk_put(pll4_clk);
+ return -ENOMEM;
+ }
+
+ suspend_set_ops(&pnx4008_pm_ops);
+ return 0;
+}
+
+late_initcall(pnx4008_pm_init);
diff --git a/arch/arm/mach-pnx4008/serial.c b/arch/arm/mach-pnx4008/serial.c
new file mode 100644
index 00000000..f40961e5
--- /dev/null
+++ b/arch/arm/mach-pnx4008/serial.c
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/mach-pnx4008/serial.c
+ *
+ * PNX4008 UART initialization
+ *
+ * Copyright: MontaVista Software Inc. (c) 2005
+ *
+ * This program is free software; you can 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 <mach/platform.h>
+#include <mach/hardware.h>
+
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <mach/gpio.h>
+
+#include <mach/clock.h>
+
+#define UART_3 0
+#define UART_4 1
+#define UART_5 2
+#define UART_6 3
+#define UART_UNKNOWN (-1)
+
+#define UART3_BASE_VA IO_ADDRESS(PNX4008_UART3_BASE)
+#define UART4_BASE_VA IO_ADDRESS(PNX4008_UART4_BASE)
+#define UART5_BASE_VA IO_ADDRESS(PNX4008_UART5_BASE)
+#define UART6_BASE_VA IO_ADDRESS(PNX4008_UART6_BASE)
+
+#define UART_FCR_OFFSET 8
+#define UART_FIFO_SIZE 64
+
+void pnx4008_uart_init(void)
+{
+ u32 tmp;
+ int i = UART_FIFO_SIZE;
+
+ __raw_writel(0xC1, UART5_BASE_VA + UART_FCR_OFFSET);
+ __raw_writel(0xC1, UART3_BASE_VA + UART_FCR_OFFSET);
+
+ /* Send a NULL to fix the UART HW bug */
+ __raw_writel(0x00, UART5_BASE_VA);
+ __raw_writel(0x00, UART3_BASE_VA);
+
+ while (i--) {
+ tmp = __raw_readl(UART5_BASE_VA);
+ tmp = __raw_readl(UART3_BASE_VA);
+ }
+ __raw_writel(0, UART5_BASE_VA + UART_FCR_OFFSET);
+ __raw_writel(0, UART3_BASE_VA + UART_FCR_OFFSET);
+
+ /* setup wakeup interrupt */
+ start_int_set_rising_edge(SE_U3_RX_INT);
+ start_int_ack(SE_U3_RX_INT);
+ start_int_umask(SE_U3_RX_INT);
+
+ start_int_set_rising_edge(SE_U5_RX_INT);
+ start_int_ack(SE_U5_RX_INT);
+ start_int_umask(SE_U5_RX_INT);
+}
+
diff --git a/arch/arm/mach-pnx4008/sleep.S b/arch/arm/mach-pnx4008/sleep.S
new file mode 100644
index 00000000..f4eed495
--- /dev/null
+++ b/arch/arm/mach-pnx4008/sleep.S
@@ -0,0 +1,195 @@
+/*
+ * linux/arch/arm/mach-pnx4008/sleep.S
+ *
+ * PNX4008 support for STOP mode and SDRAM self-refresh
+ *
+ * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+#define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
+#define PWR_CTRL_REG_OFFS 0x44
+
+#define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
+#define MPMC_STATUS_REG_OFFS 0x4
+
+ .text
+
+ENTRY(pnx4008_cpu_suspend)
+ @this function should be entered in Direct run mode.
+
+ @ save registers on stack
+ stmfd sp!, {r0 - r6, lr}
+
+ @ setup Power Manager base address in r4
+ @ and put it's value in r5
+ mov r4, #(PWRMAN_VA_BASE & 0xff000000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+ ldr r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ setup SDRAM controller base address in r2
+ @ and put it's value in r3
+ mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+ ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do save current bit settings in r1
+ mov r1, r5
+
+ @ set SDRAM self-refresh bit
+ orr r5, r5, #(1 << 9)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get into self-refresh mode
+2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #(1 << 2)
+ beq 2b
+
+ @ to prepare SDRAM to get out of self-refresh mode after wakeup
+ orr r5, r5, #(1 << 7)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do enter stop mode
+ orr r5, r5, #(1 << 0)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+ @ sleeping now...
+
+ @ coming out of STOP mode into Direct Run mode
+ @ clear STOP mode and SDRAM self-refresh bits
+ str r1, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get out self-refresh mode
+3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #5
+ bne 3b
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_suspend_sz)
+ .word . - pnx4008_cpu_suspend
+
+ENTRY(pnx4008_cpu_standby)
+ @ save registers on stack
+ stmfd sp!, {r0 - r6, lr}
+
+ @ setup Power Manager base address in r4
+ @ and put it's value in r5
+ mov r4, #(PWRMAN_VA_BASE & 0xff000000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
+ orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
+ ldr r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ setup SDRAM controller base address in r2
+ @ and put it's value in r3
+ mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
+ orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
+ ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ do save current bit settings in r1
+ mov r1, r5
+
+ @ set SDRAM self-refresh bit
+ orr r5, r5, #(1 << 9)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit
+ and r5, r5, #(~(1 << 9))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get into self-refresh mode
+2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #(1 << 2)
+ beq 2b
+
+ @ set 'get out of self-refresh mode after wakeup' bit
+ orr r5, r5, #(1 << 7)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
+
+ @ set SDRAM self-refresh bit latch
+ orr r5, r5, #(1 << 8)
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ clear SDRAM self-refresh bit latch
+ and r5, r5, #(~(1 << 8))
+ str r5, [r4, #PWR_CTRL_REG_OFFS]
+
+ @ wait for SDRAM to get out self-refresh mode
+3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
+ tst r3, #5
+ bne 3b
+
+ @ restore regs and return
+ ldmfd sp!, {r0 - r6, pc}
+
+ENTRY(pnx4008_cpu_standby_sz)
+ .word . - pnx4008_cpu_standby
+
+ENTRY(pnx4008_cache_clean_invalidate)
+ stmfd sp!, {r0 - r6, lr}
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
+ bne 1b
+#endif
+ ldmfd sp!, {r0 - r6, pc}
diff --git a/arch/arm/mach-pnx4008/time.c b/arch/arm/mach-pnx4008/time.c
new file mode 100644
index 00000000..0c8aad4b
--- /dev/null
+++ b/arch/arm/mach-pnx4008/time.c
@@ -0,0 +1,135 @@
+/*
+ * arch/arm/mach-pnx4008/time.c
+ *
+ * PNX4008 Timers
+ *
+ * Authors: Vitaly Wool, Dmitry Chigirev, Grigory Tolstolytkin <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach/time.h>
+#include <asm/errno.h>
+
+#include "time.h"
+
+/*! Note: all timers are UPCOUNTING */
+
+/*!
+ * Returns number of us since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ */
+static unsigned long pnx4008_gettimeoffset(void)
+{
+ u32 ticks_to_match =
+ __raw_readl(HSTIM_MATCH0) - __raw_readl(HSTIM_COUNTER);
+ u32 elapsed = LATCH - ticks_to_match;
+ return (elapsed * (tick_nsec / 1000)) / LATCH;
+}
+
+/*!
+ * IRQ handler for the timer
+ */
+static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
+{
+ if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
+
+ do {
+ timer_tick();
+
+ /*
+ * this algorithm takes care of possible delay
+ * for this interrupt handling longer than a normal
+ * timer period
+ */
+ __raw_writel(__raw_readl(HSTIM_MATCH0) + LATCH,
+ HSTIM_MATCH0);
+ __raw_writel(MATCH0_INT, HSTIM_INT); /* clear interrupt */
+
+ /*
+ * The goal is to keep incrementing HSTIM_MATCH0
+ * register until HSTIM_MATCH0 indicates time after
+ * what HSTIM_COUNTER indicates.
+ */
+ } while ((signed)
+ (__raw_readl(HSTIM_MATCH0) -
+ __raw_readl(HSTIM_COUNTER)) < 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction pnx4008_timer_irq = {
+ .name = "PNX4008 Tick Timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = pnx4008_timer_interrupt
+};
+
+/*!
+ * Set up timer and timer interrupt.
+ */
+static __init void pnx4008_setup_timer(void)
+{
+ __raw_writel(RESET_COUNT, MSTIM_CTRL);
+ while (__raw_readl(MSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
+ __raw_writel(0, MSTIM_CTRL); /* stop the timer */
+ __raw_writel(0, MSTIM_MCTRL);
+
+ __raw_writel(RESET_COUNT, HSTIM_CTRL);
+ while (__raw_readl(HSTIM_COUNTER)) ; /* wait for reset to complete. 100% guarantee event */
+ __raw_writel(0, HSTIM_CTRL);
+ __raw_writel(0, HSTIM_MCTRL);
+ __raw_writel(0, HSTIM_CCR);
+ __raw_writel(12, HSTIM_PMATCH); /* scale down to 1 MHZ */
+ __raw_writel(LATCH, HSTIM_MATCH0);
+ __raw_writel(MR0_INT, HSTIM_MCTRL);
+
+ setup_irq(HSTIMER_INT, &pnx4008_timer_irq);
+
+ __raw_writel(COUNT_ENAB | DEBUG_EN, HSTIM_CTRL); /*start timer, stop when JTAG active */
+}
+
+/* Timer Clock Control in PM register */
+#define TIMCLK_CTRL_REG IO_ADDRESS((PNX4008_PWRMAN_BASE + 0xBC))
+#define WATCHDOG_CLK_EN 1
+#define TIMER_CLK_EN 2 /* HS and MS timers? */
+
+static u32 timclk_ctrl_reg_save;
+
+void pnx4008_timer_suspend(void)
+{
+ timclk_ctrl_reg_save = __raw_readl(TIMCLK_CTRL_REG);
+ __raw_writel(0, TIMCLK_CTRL_REG); /* disable timers */
+}
+
+void pnx4008_timer_resume(void)
+{
+ __raw_writel(timclk_ctrl_reg_save, TIMCLK_CTRL_REG); /* enable timers */
+}
+
+struct sys_timer pnx4008_timer = {
+ .init = pnx4008_setup_timer,
+ .offset = pnx4008_gettimeoffset,
+ .suspend = pnx4008_timer_suspend,
+ .resume = pnx4008_timer_resume,
+};
+
diff --git a/arch/arm/mach-pnx4008/time.h b/arch/arm/mach-pnx4008/time.h
new file mode 100644
index 00000000..75e88c57
--- /dev/null
+++ b/arch/arm/mach-pnx4008/time.h
@@ -0,0 +1,70 @@
+/*
+ * arch/arm/mach-pnx4008/include/mach/timex.h
+ *
+ * PNX4008 timers header file
+ *
+ * Author: Dmitry Chigirev <source@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+#ifndef PNX_TIME_H
+#define PNX_TIME_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define TICKS2USECS(x) (x)
+
+/* MilliSecond Timer - Chapter 21 Page 202 */
+
+#define MSTIM_INT IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x0))
+#define MSTIM_CTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x4))
+#define MSTIM_COUNTER IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x8))
+#define MSTIM_MCTRL IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x14))
+#define MSTIM_MATCH0 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x18))
+#define MSTIM_MATCH1 IO_ADDRESS((PNX4008_MSTIMER_BASE + 0x1c))
+
+/* High Speed Timer - Chpater 22, Page 205 */
+
+#define HSTIM_INT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x0))
+#define HSTIM_CTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x4))
+#define HSTIM_COUNTER IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x8))
+#define HSTIM_PMATCH IO_ADDRESS((PNX4008_HSTIMER_BASE + 0xC))
+#define HSTIM_PCOUNT IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x10))
+#define HSTIM_MCTRL IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x14))
+#define HSTIM_MATCH0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x18))
+#define HSTIM_MATCH1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x1c))
+#define HSTIM_MATCH2 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x20))
+#define HSTIM_CCR IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x28))
+#define HSTIM_CR0 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x2C))
+#define HSTIM_CR1 IO_ADDRESS((PNX4008_HSTIMER_BASE + 0x30))
+
+/* IMPORTANT: both timers are UPCOUNTING */
+
+/* xSTIM_MCTRL bit definitions */
+#define MR0_INT 1
+#define RESET_COUNT0 (1<<1)
+#define STOP_COUNT0 (1<<2)
+#define MR1_INT (1<<3)
+#define RESET_COUNT1 (1<<4)
+#define STOP_COUNT1 (1<<5)
+#define MR2_INT (1<<6)
+#define RESET_COUNT2 (1<<7)
+#define STOP_COUNT2 (1<<8)
+
+/* xSTIM_CTRL bit definitions */
+#define COUNT_ENAB 1
+#define RESET_COUNT (1<<1)
+#define DEBUG_EN (1<<2)
+
+/* xSTIM_INT bit definitions */
+#define MATCH0_INT 1
+#define MATCH1_INT (1<<1)
+#define MATCH2_INT (1<<2)
+#define RTC_TICK0 (1<<4)
+#define RTC_TICK1 (1<<5)
+
+#endif
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
new file mode 100644
index 00000000..cd19309f
--- /dev/null
+++ b/arch/arm/mach-pxa/Kconfig
@@ -0,0 +1,699 @@
+if ARCH_PXA
+
+menu "Intel PXA2xx/PXA3xx Implementations"
+
+comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
+
+config ARCH_LUBBOCK
+ bool "Intel DBPXA250 Development Platform (aka Lubbock)"
+ select PXA25x
+ select SA1111
+
+config MACH_MAINSTONE
+ bool "Intel HCDDBBVA0 Development Platform (aka Mainstone)"
+ select PXA27x
+ select HAVE_PWM
+
+config MACH_ZYLONITE
+ bool
+ select PXA3xx
+ select HAVE_PWM
+
+config MACH_ZYLONITE300
+ bool "PXA3xx Development Platform (aka Zylonite) PXA300/310"
+ select CPU_PXA300
+ select CPU_PXA310
+ select MACH_ZYLONITE
+
+config MACH_ZYLONITE320
+ bool "PXA3xx Development Platform (aka Zylonite) PXA320"
+ select CPU_PXA320
+ select MACH_ZYLONITE
+
+config MACH_LITTLETON
+ bool "PXA3xx Form Factor Platform (aka Littleton)"
+ select PXA3xx
+ select CPU_PXA300
+ select CPU_PXA310
+
+config MACH_TAVOREVB
+ bool "PXA930 Evaluation Board (aka TavorEVB)"
+ select PXA3xx
+ select CPU_PXA930
+
+config MACH_TAVOREVB3
+ bool "PXA95x Development Platform (aka TavorEVB III)"
+ select CPU_PXA950
+
+config MACH_SAAR
+ bool "PXA930 Handheld Platform (aka SAAR)"
+ select PXA3xx
+ select CPU_PXA930
+
+config MACH_SAARB
+ bool "PXA955 Handheld Platform (aka SAARB)"
+ select CPU_PXA955
+
+comment "Third Party Dev Platforms (sorted by vendor name)"
+
+config ARCH_PXA_IDP
+ bool "Accelent Xscale IDP"
+ select PXA25x
+
+config ARCH_VIPER
+ bool "Arcom/Eurotech VIPER SBC"
+ select PXA25x
+ select ISA
+ select I2C_GPIO
+ select HAVE_PWM
+ select PXA_HAVE_ISA_IRQS
+ select ARCOM_PCMCIA
+
+config MACH_ARCOM_ZEUS
+ bool "Arcom/Eurotech ZEUS SBC"
+ select PXA27x
+ select ISA
+ select PXA_HAVE_ISA_IRQS
+ select ARCOM_PCMCIA
+
+config MACH_BALLOON3
+ bool "Balloon 3 board"
+ select PXA27x
+ select IWMMXT
+
+config MACH_CSB726
+ bool "Enable Cogent CSB726 System On a Module"
+ select PXA27x
+ select IWMMXT
+ help
+ Say Y here if you intend to run this kernel on a Cogent
+ CSB726 System On Module.
+
+config CSB726_CSB701
+ bool "Enable support for CSB701 baseboard"
+ depends on MACH_CSB726
+
+config MACH_ARMCORE
+ bool "CompuLab CM-X255/CM-X270 modules"
+ select PXA27x
+ select IWMMXT
+ select PXA25x
+ select MIGHT_HAVE_PCI
+
+config MACH_EM_X270
+ bool "CompuLab EM-x270 platform"
+ select PXA27x
+
+config MACH_EXEDA
+ bool "CompuLab eXeda platform"
+ select PXA27x
+
+config MACH_CM_X300
+ bool "CompuLab CM-X300 modules"
+ select PXA3xx
+ select CPU_PXA300
+ select CPU_PXA310
+ select HAVE_PWM
+
+config MACH_CAPC7117
+ bool "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM"
+ select CPU_PXA320
+ select PXA3xx
+
+config ARCH_GUMSTIX
+ bool "Gumstix XScale 255 boards"
+ select PXA25x
+ help
+ Say Y here if you intend to run this kernel on
+ Basix, Connex, ws-200ax, ws-400ax systems
+
+choice
+ prompt "Gumstix Carrier/Expansion Board"
+ depends on ARCH_GUMSTIX
+
+config GUMSTIX_AM200EPD
+ bool "Enable AM200EPD board support"
+
+config GUMSTIX_AM300EPD
+ bool "Enable AM300EPD board support"
+
+endchoice
+
+config MACH_INTELMOTE2
+ bool "Intel Mote 2 Platform"
+ select PXA27x
+ select IWMMXT
+
+config MACH_STARGATE2
+ bool "Intel Stargate 2 Platform"
+ select PXA27x
+ select IWMMXT
+
+config MACH_XCEP
+ bool "Iskratel Electronics XCEP"
+ select PXA25x
+ select MTD
+ select MTD_PHYSMAP
+ select MTD_CFI_INTELEXT
+ select MTD_CFI
+ select MTD_CHAR
+ select SMC91X
+ help
+ PXA255 based Single Board Computer with SMC 91C111 ethernet chip and 64 MB of flash.
+ Tuned for usage in Libera instruments for particle accelerators.
+
+config TRIZEPS_PXA
+ bool "PXA based Keith und Koep Trizeps DIMM-Modules"
+
+config MACH_TRIZEPS4
+ bool "Keith und Koep Trizeps4 DIMM-Module"
+ depends on TRIZEPS_PXA
+ select TRIZEPS_PCMCIA
+ select PXA27x
+
+config MACH_TRIZEPS4WL
+ bool "Keith und Koep Trizeps4-WL DIMM-Module"
+ depends on TRIZEPS_PXA
+ select TRIZEPS_PCMCIA
+ select PXA27x
+
+choice
+ prompt "Select base board for Trizeps module"
+ depends on TRIZEPS_PXA
+
+config MACH_TRIZEPS_CONXS
+ bool "ConXS Eval Board"
+
+config MACH_TRIZEPS_UCONXS
+ bool "uConXS Eval Board"
+
+config MACH_TRIZEPS_ANY
+ bool "another Board"
+
+endchoice
+
+config ARCOM_PCMCIA
+ bool
+ help
+ Generic option for Arcom Viper/Zeus PCMCIA
+
+config TRIZEPS_PCMCIA
+ bool
+ help
+ Enable PCMCIA support for Trizeps modules
+
+config MACH_LOGICPD_PXA270
+ bool "LogicPD PXA270 Card Engine Development Platform"
+ select PXA27x
+ select HAVE_PWM
+
+config MACH_PCM027
+ bool "Phytec phyCORE-PXA270 CPU module (PCM-027)"
+ select PXA27x
+ select IWMMXT
+
+config MACH_PCM990_BASEBOARD
+ bool "PHYTEC PCM-990 development board"
+ select HAVE_PWM
+ depends on MACH_PCM027
+
+choice
+ prompt "display on pcm990"
+ depends on MACH_PCM990_BASEBOARD
+
+config PCM990_DISPLAY_SHARP
+ bool "sharp lq084v1dg21 stn display"
+
+config PCM990_DISPLAY_NEC
+ bool "nec nl6448bc20_18d tft display"
+
+config PCM990_DISPLAY_NONE
+ bool "no display"
+
+endchoice
+
+config MACH_COLIBRI
+ bool "Toradex Colibri PXA270"
+ select PXA27x
+
+config MACH_COLIBRI_PXA270_INCOME
+ bool "Income s.r.o. PXA270 SBC"
+ depends on MACH_COLIBRI
+ select PXA27x
+ select HAVE_PWM
+
+config MACH_COLIBRI300
+ bool "Toradex Colibri PXA300/310"
+ select PXA3xx
+ select CPU_PXA300
+ select CPU_PXA310
+
+config MACH_COLIBRI320
+ bool "Toradex Colibri PXA320"
+ select PXA3xx
+ select CPU_PXA320
+
+config MACH_COLIBRI_EVALBOARD
+ bool "Toradex Colibri Evaluation Carrier Board support"
+ depends on MACH_COLIBRI || MACH_COLIBRI300 || MACH_COLIBRI320
+
+config MACH_VPAC270
+ bool "Voipac PXA270"
+ select PXA27x
+ select HAVE_PATA_PLATFORM
+ help
+ PXA270 based Single Board Computer.
+
+comment "End-user Products (sorted by vendor name)"
+
+config MACH_H4700
+ bool "HP iPAQ hx4700"
+ select PXA27x
+ select IWMMXT
+ select HAVE_PWM
+
+config MACH_H5000
+ bool "HP iPAQ h5000"
+ select PXA25x
+
+config MACH_HIMALAYA
+ bool "HTC Himalaya Support"
+ select CPU_PXA26x
+
+config MACH_MAGICIAN
+ bool "Enable HTC Magician Support"
+ select PXA27x
+ select IWMMXT
+ select HAVE_PWM
+
+config MACH_MIOA701
+ bool "Mitac Mio A701 Support"
+ select PXA27x
+ select IWMMXT
+ select HAVE_PWM
+ select GPIO_SYSFS
+ help
+ Say Y here if you intend to run this kernel on a
+ MIO A701. Currently there is only basic support
+ for this PDA.
+
+config PXA_EZX
+ bool "Motorola EZX Platform"
+ select PXA27x
+ select IWMMXT
+ select HAVE_PWM
+
+config MACH_EZX_A780
+ bool "Motorola EZX A780"
+ default y
+ depends on PXA_EZX
+
+config MACH_EZX_E680
+ bool "Motorola EZX E680"
+ default y
+ depends on PXA_EZX
+
+config MACH_EZX_A1200
+ bool "Motorola EZX A1200"
+ default y
+ depends on PXA_EZX
+
+config MACH_EZX_A910
+ bool "Motorola EZX A910"
+ default y
+ depends on PXA_EZX
+
+config MACH_EZX_E6
+ bool "Motorola EZX E6"
+ default y
+ depends on PXA_EZX
+
+config MACH_EZX_E2
+ bool "Motorola EZX E2"
+ default y
+ depends on PXA_EZX
+
+config MACH_MP900C
+ bool "Nec Mobilepro 900/c"
+ select PXA25x
+
+config ARCH_PXA_PALM
+ bool "PXA based Palm PDAs"
+ select HAVE_PWM
+
+config MACH_PALM27X
+ bool
+
+config MACH_PALMTE2
+ bool "Palm Tungsten|E2"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA25x
+ help
+ Say Y here if you intend to run this kernel on a Palm Tungsten|E2
+ handheld computer.
+
+config MACH_PALMTC
+ bool "Palm Tungsten|C"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA25x
+ help
+ Say Y here if you intend to run this kernel on a Palm Tungsten|C
+ handheld computer.
+
+config MACH_PALMT5
+ bool "Palm Tungsten|T5"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select MACH_PALM27X
+ help
+ Say Y here if you intend to run this kernel on a Palm Tungsten|T5
+ handheld computer.
+
+config MACH_PALMTX
+ bool "Palm T|X"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select MACH_PALM27X
+ help
+ Say Y here if you intend to run this kernel on a Palm T|X
+ handheld computer.
+
+config MACH_PALMZ72
+ bool "Palm Zire 72"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select MACH_PALM27X
+ help
+ Say Y here if you intend to run this kernel on Palm Zire 72
+ handheld computer.
+
+config MACH_PALMLD
+ bool "Palm LifeDrive"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select MACH_PALM27X
+ help
+ Say Y here if you intend to run this kernel on a Palm LifeDrive
+ handheld computer.
+
+config PALM_TREO
+ bool
+ depends on ARCH_PXA_PALM
+
+config MACH_CENTRO
+ bool "Palm Centro 685 (GSM)"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select PALM_TREO
+ help
+ Say Y here if you intend to run this kernel on Palm Centro 685 (GSM)
+ smartphone.
+
+config MACH_TREO680
+ bool "Palm Treo 680"
+ default y
+ depends on ARCH_PXA_PALM
+ select PXA27x
+ select IWMMXT
+ select PALM_TREO
+ help
+ Say Y here if you intend to run this kernel on Palm Treo 680
+ smartphone.
+
+config MACH_RAUMFELD_RC
+ bool "Raumfeld Controller"
+ select PXA3xx
+ select CPU_PXA300
+ select HAVE_PWM
+
+config MACH_RAUMFELD_CONNECTOR
+ bool "Raumfeld Connector"
+ select PXA3xx
+ select CPU_PXA300
+
+config MACH_RAUMFELD_SPEAKER
+ bool "Raumfeld Speaker"
+ select PXA3xx
+ select CPU_PXA300
+
+config PXA_SHARPSL
+ bool "SHARP Zaurus SL-5600, SL-C7xx and SL-Cxx00 Models"
+ select SHARP_SCOOP
+ select SHARP_PARAM
+ help
+ Say Y here if you intend to run this kernel on a
+ Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi),
+ SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita),
+ SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
+ handheld computer.
+
+config PXA_SHARPSL_DETECT_MACH_ID
+ bool "Detect machine ID at run-time in the decompressor"
+ depends on PXA_SHARPSL
+ help
+ Say Y here if you want the zImage decompressor to detect
+ the Zaurus machine ID at run-time. For latest kexec-based
+ boot loader, this is not necessary.
+
+config MACH_POODLE
+ bool "Enable Sharp SL-5600 (Poodle) Support"
+ depends on PXA_SHARPSL
+ select PXA25x
+ select SHARP_LOCOMO
+
+config MACH_CORGI
+ bool "Enable Sharp SL-C700 (Corgi) Support"
+ depends on PXA_SHARPSL
+ select PXA25x
+ select PXA_SHARP_C7xx
+
+config MACH_SHEPHERD
+ bool "Enable Sharp SL-C750 (Shepherd) Support"
+ depends on PXA_SHARPSL
+ select PXA25x
+ select PXA_SHARP_C7xx
+
+config MACH_HUSKY
+ bool "Enable Sharp SL-C760 (Husky) Support"
+ depends on PXA_SHARPSL
+ select PXA25x
+ select PXA_SHARP_C7xx
+
+config MACH_AKITA
+ bool "Enable Sharp SL-1000 (Akita) Support"
+ depends on PXA_SHARPSL
+ select PXA27x
+ select PXA_SHARP_Cxx00
+ select MACH_SPITZ
+ select I2C
+ select I2C_PXA
+
+config MACH_SPITZ
+ bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
+ depends on PXA_SHARPSL
+ select PXA27x
+ select PXA_SHARP_Cxx00
+
+config MACH_BORZOI
+ bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support"
+ depends on PXA_SHARPSL
+ select PXA27x
+ select PXA_SHARP_Cxx00
+
+config MACH_TOSA
+ bool "Enable Sharp SL-6000x (Tosa) Support"
+ depends on PXA_SHARPSL
+ select PXA25x
+
+config TOSA_BT
+ tristate "Control the state of built-in bluetooth chip on Sharp SL-6000"
+ depends on MACH_TOSA
+ select RFKILL
+ help
+ This is a simple driver that is able to control
+ the state of built in bluetooth chip on tosa.
+
+config TOSA_USE_EXT_KEYCODES
+ bool "Tosa keyboard: use extended keycodes"
+ depends on MACH_TOSA
+ default n
+ help
+ Say Y here to enable the tosa keyboard driver to generate extended
+ (>= 127) keycodes. Be aware, that they can't be correctly interpreted
+ by either console keyboard driver or by Kdrive keybd driver.
+
+ Say Y only if you know, what you are doing!
+
+config MACH_ICONTROL
+ bool "TMT iControl/SafeTCam based on the MXM-8x10 CoM"
+ select CPU_PXA320
+ select PXA3xx
+
+config ARCH_PXA_ESERIES
+ bool "PXA based Toshiba e-series PDAs"
+ select PXA25x
+ select FB_W100
+
+config MACH_E330
+ bool "Toshiba e330"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e330 family PDA.
+
+config MACH_E350
+ bool "Toshiba e350"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e350 family PDA.
+
+config MACH_E740
+ bool "Toshiba e740"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e740 family PDA.
+
+config MACH_E750
+ bool "Toshiba e750"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e750 family PDA.
+
+config MACH_E400
+ bool "Toshiba e400"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e400 family PDA.
+
+config MACH_E800
+ bool "Toshiba e800"
+ default y
+ depends on ARCH_PXA_ESERIES
+ help
+ Say Y here if you intend to run this kernel on a Toshiba
+ e800 family PDA.
+
+config MACH_ZIPIT2
+ bool "Zipit Z2 Handheld"
+ select PXA27x
+ select HAVE_PWM
+
+endmenu
+
+config PXA25x
+ bool
+ select CPU_XSCALE
+ help
+ Select code specific to PXA21x/25x/26x variants
+
+config PXA27x
+ bool
+ select CPU_XSCALE
+ help
+ Select code specific to PXA27x variants
+
+config CPU_PXA26x
+ bool
+ select PXA25x
+ help
+ Select code specific to PXA26x (codename Dalhart)
+
+config PXA3xx
+ bool
+ select CPU_XSC3
+ help
+ Select code specific to PXA3xx variants
+
+config CPU_PXA300
+ bool
+ select PXA3xx
+ help
+ PXA300 (codename Monahans-L)
+
+config CPU_PXA310
+ bool
+ select CPU_PXA300
+ select PXA310_ULPI if USB_ULPI
+ help
+ PXA310 (codename Monahans-LV)
+
+config CPU_PXA320
+ bool
+ select PXA3xx
+ help
+ PXA320 (codename Monahans-P)
+
+config CPU_PXA930
+ bool
+ select PXA3xx
+ help
+ PXA930 (codename Tavor-P)
+
+config CPU_PXA935
+ bool
+ select CPU_PXA930
+ help
+ PXA935 (codename Tavor-P65)
+
+config PXA95x
+ bool
+ select CPU_PJ4
+ help
+ Select code specific to PXA95x variants
+
+config CPU_PXA955
+ bool
+ select PXA95x
+ help
+ PXA950 (codename MG1)
+
+config PXA_SHARP_C7xx
+ bool
+ select SHARPSL_PM
+ help
+ Enable support for all Sharp C7xx models
+
+config PXA_SHARP_Cxx00
+ bool
+ select SHARPSL_PM
+ help
+ Enable common support for Sharp Cxx00 models
+
+config SHARPSL_PM
+ bool
+ select APM_EMULATION
+ select SHARPSL_PM_MAX1111
+
+config SHARPSL_PM_MAX1111
+ bool
+ select HWMON
+ select SENSORS_MAX1111
+
+config PXA_HAVE_ISA_IRQS
+ bool
+
+config PXA310_ULPI
+ bool
+
+endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
new file mode 100644
index 00000000..cc39d17b
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile
@@ -0,0 +1,106 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += clock.o devices.o generic.o irq.o \
+ time.o reset.o
+obj-$(CONFIG_PM) += pm.o sleep.o standby.o
+
+ifeq ($(CONFIG_CPU_FREQ),y)
+obj-$(CONFIG_PXA25x) += cpufreq-pxa2xx.o
+obj-$(CONFIG_PXA27x) += cpufreq-pxa2xx.o
+obj-$(CONFIG_PXA3xx) += cpufreq-pxa3xx.o
+endif
+
+# Generic drivers that other drivers may depend upon
+
+# SoC-specific code
+obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa25x.o
+obj-$(CONFIG_PXA27x) += mfp-pxa2xx.o clock-pxa2xx.o pxa2xx.o pxa27x.o
+obj-$(CONFIG_PXA3xx) += mfp-pxa3xx.o clock-pxa3xx.o pxa3xx.o smemc.o pxa3xx-ulpi.o
+obj-$(CONFIG_PXA95x) += mfp-pxa3xx.o clock-pxa3xx.o pxa95x.o smemc.o
+obj-$(CONFIG_CPU_PXA300) += pxa300.o
+obj-$(CONFIG_CPU_PXA320) += pxa320.o
+obj-$(CONFIG_CPU_PXA930) += pxa930.o
+
+# NOTE: keep the order of boards in accordance to their order in Kconfig
+
+# Intel/Marvell Dev Platforms
+obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
+obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
+obj-$(CONFIG_MACH_ZYLONITE300) += zylonite.o zylonite_pxa300.o
+obj-$(CONFIG_MACH_ZYLONITE320) += zylonite.o zylonite_pxa320.o
+obj-$(CONFIG_MACH_LITTLETON) += littleton.o
+obj-$(CONFIG_MACH_TAVOREVB) += tavorevb.o
+obj-$(CONFIG_MACH_TAVOREVB3) += tavorevb3.o
+obj-$(CONFIG_MACH_SAAR) += saar.o
+obj-$(CONFIG_MACH_SAARB) += saarb.o
+
+# 3rd Party Dev Platforms
+obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
+obj-$(CONFIG_ARCH_VIPER) += viper.o
+obj-$(CONFIG_MACH_ARCOM_ZEUS) += zeus.o
+obj-$(CONFIG_MACH_BALLOON3) += balloon3.o
+obj-$(CONFIG_MACH_CSB726) += csb726.o
+obj-$(CONFIG_CSB726_CSB701) += csb701.o
+obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx.o cm-x255.o cm-x270.o
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MACH_ARMCORE) += cm-x2xx-pci.o
+endif
+obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+obj-$(CONFIG_MACH_CM_X300) += cm-x300.o
+obj-$(CONFIG_MACH_CAPC7117) += capc7117.o mxm8x10.o
+obj-$(CONFIG_ARCH_GUMSTIX) += gumstix.o
+obj-$(CONFIG_GUMSTIX_AM200EPD) += am200epd.o
+obj-$(CONFIG_GUMSTIX_AM300EPD) += am300epd.o
+obj-$(CONFIG_MACH_INTELMOTE2) += stargate2.o
+obj-$(CONFIG_MACH_STARGATE2) += stargate2.o
+obj-$(CONFIG_MACH_XCEP) += xcep.o
+obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
+obj-$(CONFIG_MACH_LOGICPD_PXA270) += lpd270.o
+obj-$(CONFIG_MACH_PCM027) += pcm027.o
+obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
+obj-$(CONFIG_MACH_COLIBRI) += colibri-pxa270.o
+obj-$(CONFIG_MACH_COLIBRI_EVALBOARD) += colibri-evalboard.o
+obj-$(CONFIG_MACH_COLIBRI_PXA270_INCOME) += colibri-pxa270-income.o
+obj-$(CONFIG_MACH_COLIBRI300) += colibri-pxa3xx.o colibri-pxa300.o
+obj-$(CONFIG_MACH_COLIBRI320) += colibri-pxa3xx.o colibri-pxa320.o
+obj-$(CONFIG_MACH_VPAC270) += vpac270.o
+
+# End-user Products
+obj-$(CONFIG_MACH_H4700) += hx4700.o
+obj-$(CONFIG_MACH_H5000) += h5000.o
+obj-$(CONFIG_MACH_HIMALAYA) += himalaya.o
+obj-$(CONFIG_MACH_MAGICIAN) += magician.o
+obj-$(CONFIG_MACH_MIOA701) += mioa701.o mioa701_bootresume.o
+obj-$(CONFIG_PXA_EZX) += ezx.o
+obj-$(CONFIG_MACH_MP900C) += mp900.o
+obj-$(CONFIG_MACH_PALMTE2) += palmte2.o
+obj-$(CONFIG_MACH_PALMTC) += palmtc.o
+obj-$(CONFIG_MACH_PALM27X) += palm27x.o
+obj-$(CONFIG_MACH_PALMT5) += palmt5.o
+obj-$(CONFIG_MACH_PALMTX) += palmtx.o
+obj-$(CONFIG_MACH_PALMZ72) += palmz72.o
+obj-$(CONFIG_MACH_PALMLD) += palmld.o
+obj-$(CONFIG_PALM_TREO) += palmtreo.o
+obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o
+obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o
+obj-$(CONFIG_MACH_POODLE) += poodle.o
+obj-$(CONFIG_MACH_TOSA) += tosa.o
+obj-$(CONFIG_MACH_ICONTROL) += icontrol.o mxm8x10.o
+obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
+obj-$(CONFIG_MACH_RAUMFELD_RC) += raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o
+obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o
+obj-$(CONFIG_MACH_ZIPIT2) += z2.o
+
+# Support for blinky lights
+led-y := leds.o
+led-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
+led-$(CONFIG_MACH_MAINSTONE) += leds-mainstone.o
+led-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
+
+obj-$(CONFIG_LEDS) += $(led-y)
+
+obj-$(CONFIG_TOSA_BT) += tosa-bt.o
diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot
new file mode 100644
index 00000000..1ead6717
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0xa0008000
+
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
new file mode 100644
index 00000000..4cb069fd
--- /dev/null
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -0,0 +1,387 @@
+/*
+ * am200epd.c -- Platform device for AM200 EPD kit
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
+ *
+ * This work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Metronome display controller.
+ * on the AM200 EPD prototype kit/development kit with an E-Ink 800x600
+ * Vizplex EPD on a Gumstix board using the Lyre interface board.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/pxa25x.h>
+#include <mach/gumstix.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+
+#include <video/metronomefb.h>
+
+static unsigned int panel_type = 6;
+static struct platform_device *am200_device;
+static struct metronome_board am200_board;
+
+static struct pxafb_mode_info am200_fb_mode_9inch7 = {
+ .pixclock = 40000,
+ .xres = 1200,
+ .yres = 842,
+ .bpp = 16,
+ .hsync_len = 2,
+ .left_margin = 2,
+ .right_margin = 2,
+ .vsync_len = 1,
+ .upper_margin = 2,
+ .lower_margin = 25,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info am200_fb_mode_8inch = {
+ .pixclock = 40000,
+ .xres = 1088,
+ .yres = 791,
+ .bpp = 16,
+ .hsync_len = 28,
+ .left_margin = 8,
+ .right_margin = 30,
+ .vsync_len = 8,
+ .upper_margin = 10,
+ .lower_margin = 8,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info am200_fb_mode_6inch = {
+ .pixclock = 40189,
+ .xres = 832,
+ .yres = 622,
+ .bpp = 16,
+ .hsync_len = 28,
+ .left_margin = 34,
+ .right_margin = 34,
+ .vsync_len = 25,
+ .upper_margin = 0,
+ .lower_margin = 2,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info am200_fb_info = {
+ .modes = &am200_fb_mode_6inch,
+ .num_modes = 1,
+ .lcd_conn = LCD_TYPE_COLOR_TFT | LCD_PCLK_EDGE_FALL |
+ LCD_AC_BIAS_FREQ(24),
+};
+
+/* register offsets for gpio control */
+#define LED_GPIO_PIN 51
+#define STDBY_GPIO_PIN 48
+#define RST_GPIO_PIN 49
+#define RDY_GPIO_PIN 32
+#define ERR_GPIO_PIN 17
+#define PCBPWR_GPIO_PIN 16
+static int gpios[] = { LED_GPIO_PIN , STDBY_GPIO_PIN , RST_GPIO_PIN,
+ RDY_GPIO_PIN, ERR_GPIO_PIN, PCBPWR_GPIO_PIN };
+static char *gpio_names[] = { "LED" , "STDBY" , "RST", "RDY", "ERR", "PCBPWR" };
+
+static int am200_init_gpio_regs(struct metronomefb_par *par)
+{
+ int i;
+ int err;
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+ err = gpio_request(gpios[i], gpio_names[i]);
+ if (err) {
+ dev_err(&am200_device->dev, "failed requesting "
+ "gpio %s, err=%d\n", gpio_names[i], err);
+ goto err_req_gpio;
+ }
+ }
+
+ gpio_direction_output(LED_GPIO_PIN, 0);
+ gpio_direction_output(STDBY_GPIO_PIN, 0);
+ gpio_direction_output(RST_GPIO_PIN, 0);
+
+ gpio_direction_input(RDY_GPIO_PIN);
+ gpio_direction_input(ERR_GPIO_PIN);
+
+ gpio_direction_output(PCBPWR_GPIO_PIN, 0);
+
+ return 0;
+
+err_req_gpio:
+ while (--i >= 0)
+ gpio_free(gpios[i]);
+
+ return err;
+}
+
+static void am200_cleanup(struct metronomefb_par *par)
+{
+ int i;
+
+ free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++)
+ gpio_free(gpios[i]);
+}
+
+static int am200_share_video_mem(struct fb_info *info)
+{
+ /* rough check if this is our desired fb and not something else */
+ if ((info->var.xres != am200_fb_info.modes->xres)
+ || (info->var.yres != am200_fb_info.modes->yres))
+ return 0;
+
+ /* we've now been notified that we have our new fb */
+ am200_board.metromem = info->screen_base;
+ am200_board.host_fbinfo = info;
+
+ /* try to refcount host drv since we are the consumer after this */
+ if (!try_module_get(info->fbops->owner))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int am200_unshare_video_mem(struct fb_info *info)
+{
+ dev_dbg(&am200_device->dev, "ENTER %s\n", __func__);
+
+ if (info != am200_board.host_fbinfo)
+ return 0;
+
+ module_put(am200_board.host_fbinfo->fbops->owner);
+ return 0;
+}
+
+static int am200_fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ struct fb_info *info = evdata->info;
+
+ dev_dbg(&am200_device->dev, "ENTER %s\n", __func__);
+
+ if (event == FB_EVENT_FB_REGISTERED)
+ return am200_share_video_mem(info);
+ else if (event == FB_EVENT_FB_UNREGISTERED)
+ return am200_unshare_video_mem(info);
+
+ return 0;
+}
+
+static struct notifier_block am200_fb_notif = {
+ .notifier_call = am200_fb_notifier_callback,
+};
+
+/* this gets called as part of our init. these steps must be done now so
+ * that we can use pxa_set_fb_info */
+static void __init am200_presetup_fb(void)
+{
+ int fw;
+ int fh;
+ int padding_size;
+ int totalsize;
+
+ switch (panel_type) {
+ case 6:
+ am200_fb_info.modes = &am200_fb_mode_6inch;
+ break;
+ case 8:
+ am200_fb_info.modes = &am200_fb_mode_8inch;
+ break;
+ case 97:
+ am200_fb_info.modes = &am200_fb_mode_9inch7;
+ break;
+ default:
+ dev_err(&am200_device->dev, "invalid panel_type selection,"
+ " setting to 6\n");
+ am200_fb_info.modes = &am200_fb_mode_6inch;
+ break;
+ }
+
+ /* the frame buffer is divided as follows:
+ command | CRC | padding
+ 16kb waveform data | CRC | padding
+ image data | CRC
+ */
+
+ fw = am200_fb_info.modes->xres;
+ fh = am200_fb_info.modes->yres;
+
+ /* waveform must be 16k + 2 for checksum */
+ am200_board.wfm_size = roundup(16*1024 + 2, fw);
+
+ padding_size = PAGE_SIZE + (4 * fw);
+
+ /* total is 1 cmd , 1 wfm, padding and image */
+ totalsize = fw + am200_board.wfm_size + padding_size + (fw*fh);
+
+ /* save this off because we're manipulating fw after this and
+ * we'll need it when we're ready to setup the framebuffer */
+ am200_board.fw = fw;
+ am200_board.fh = fh;
+
+ /* the reason we do this adjustment is because we want to acquire
+ * more framebuffer memory without imposing custom awareness on the
+ * underlying pxafb driver */
+ am200_fb_info.modes->yres = DIV_ROUND_UP(totalsize, fw);
+
+ /* we divide since we told the LCD controller we're 16bpp */
+ am200_fb_info.modes->xres /= 2;
+
+ pxa_set_fb_info(NULL, &am200_fb_info);
+
+}
+
+/* this gets called by metronomefb as part of its init, in our case, we
+ * have already completed initial framebuffer init in presetup_fb so we
+ * can just setup the fb access pointers */
+static int am200_setup_fb(struct metronomefb_par *par)
+{
+ int fw;
+ int fh;
+
+ fw = am200_board.fw;
+ fh = am200_board.fh;
+
+ /* metromem was set up by the notifier in share_video_mem so now
+ * we can use its value to calculate the other entries */
+ par->metromem_cmd = (struct metromem_cmd *) am200_board.metromem;
+ par->metromem_wfm = am200_board.metromem + fw;
+ par->metromem_img = par->metromem_wfm + am200_board.wfm_size;
+ par->metromem_img_csum = (u16 *) (par->metromem_img + (fw * fh));
+ par->metromem_dma = am200_board.host_fbinfo->fix.smem_start;
+
+ return 0;
+}
+
+static int am200_get_panel_type(void)
+{
+ return panel_type;
+}
+
+static irqreturn_t am200_handle_irq(int irq, void *dev_id)
+{
+ struct metronomefb_par *par = dev_id;
+
+ wake_up_interruptible(&par->waitq);
+ return IRQ_HANDLED;
+}
+
+static int am200_setup_irq(struct fb_info *info)
+{
+ int ret;
+
+ ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am200_handle_irq,
+ IRQF_DISABLED|IRQF_TRIGGER_FALLING,
+ "AM200", info->par);
+ if (ret)
+ dev_err(&am200_device->dev, "request_irq failed: %d\n", ret);
+
+ return ret;
+}
+
+static void am200_set_rst(struct metronomefb_par *par, int state)
+{
+ gpio_set_value(RST_GPIO_PIN, state);
+}
+
+static void am200_set_stdby(struct metronomefb_par *par, int state)
+{
+ gpio_set_value(STDBY_GPIO_PIN, state);
+}
+
+static int am200_wait_event(struct metronomefb_par *par)
+{
+ return wait_event_timeout(par->waitq, gpio_get_value(RDY_GPIO_PIN), HZ);
+}
+
+static int am200_wait_event_intr(struct metronomefb_par *par)
+{
+ return wait_event_interruptible_timeout(par->waitq,
+ gpio_get_value(RDY_GPIO_PIN), HZ);
+}
+
+static struct metronome_board am200_board = {
+ .owner = THIS_MODULE,
+ .setup_irq = am200_setup_irq,
+ .setup_io = am200_init_gpio_regs,
+ .setup_fb = am200_setup_fb,
+ .set_rst = am200_set_rst,
+ .set_stdby = am200_set_stdby,
+ .met_wait_event = am200_wait_event,
+ .met_wait_event_intr = am200_wait_event_intr,
+ .get_panel_type = am200_get_panel_type,
+ .cleanup = am200_cleanup,
+};
+
+static unsigned long am200_pin_config[] __initdata = {
+ GPIO51_GPIO,
+ GPIO49_GPIO,
+ GPIO48_GPIO,
+ GPIO32_GPIO,
+ GPIO17_GPIO,
+ GPIO16_GPIO,
+};
+
+int __init am200_init(void)
+{
+ int ret;
+
+ /* before anything else, we request notification for any fb
+ * creation events */
+ fb_register_client(&am200_fb_notif);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(am200_pin_config));
+
+ /* request our platform independent driver */
+ request_module("metronomefb");
+
+ am200_device = platform_device_alloc("metronomefb", -1);
+ if (!am200_device)
+ return -ENOMEM;
+
+ /* the am200_board that will be seen by metronomefb is a copy */
+ platform_device_add_data(am200_device, &am200_board,
+ sizeof(am200_board));
+
+ /* this _add binds metronomefb to am200. metronomefb refcounts am200 */
+ ret = platform_device_add(am200_device);
+
+ if (ret) {
+ platform_device_put(am200_device);
+ fb_unregister_client(&am200_fb_notif);
+ return ret;
+ }
+
+ am200_presetup_fb();
+
+ return 0;
+}
+
+module_param(panel_type, uint, 0);
+MODULE_PARM_DESC(panel_type, "Select the panel type: 6, 8, 97");
+
+MODULE_DESCRIPTION("board driver for am200 metronome epd kit");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
new file mode 100644
index 00000000..fa8bad23
--- /dev/null
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -0,0 +1,296 @@
+/*
+ * am300epd.c -- Platform device for AM300 EPD kit
+ *
+ * Copyright (C) 2008, Jaya Kumar
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * This work was made possible by help and equipment support from E-Ink
+ * Corporation. http://support.eink.com/community
+ *
+ * This driver is written to be used with the Broadsheet display controller.
+ * on the AM300 EPD prototype kit/development kit with an E-Ink 800x600
+ * Vizplex EPD on a Gumstix board using the Broadsheet interface board.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <mach/gumstix.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/pxafb.h>
+
+#include "generic.h"
+
+#include <video/broadsheetfb.h>
+
+static unsigned int panel_type = 6;
+static struct platform_device *am300_device;
+static struct broadsheet_board am300_board;
+
+static unsigned long am300_pin_config[] __initdata = {
+ GPIO16_GPIO,
+ GPIO17_GPIO,
+ GPIO32_GPIO,
+ GPIO48_GPIO,
+ GPIO49_GPIO,
+ GPIO51_GPIO,
+ GPIO74_GPIO,
+ GPIO75_GPIO,
+ GPIO76_GPIO,
+ GPIO77_GPIO,
+
+ /* this is the 16-bit hdb bus 58-73 */
+ GPIO58_GPIO,
+ GPIO59_GPIO,
+ GPIO60_GPIO,
+ GPIO61_GPIO,
+
+ GPIO62_GPIO,
+ GPIO63_GPIO,
+ GPIO64_GPIO,
+ GPIO65_GPIO,
+
+ GPIO66_GPIO,
+ GPIO67_GPIO,
+ GPIO68_GPIO,
+ GPIO69_GPIO,
+
+ GPIO70_GPIO,
+ GPIO71_GPIO,
+ GPIO72_GPIO,
+ GPIO73_GPIO,
+};
+
+/* register offsets for gpio control */
+#define PWR_GPIO_PIN 16
+#define CFG_GPIO_PIN 17
+#define RDY_GPIO_PIN 32
+#define DC_GPIO_PIN 48
+#define RST_GPIO_PIN 49
+#define LED_GPIO_PIN 51
+#define RD_GPIO_PIN 74
+#define WR_GPIO_PIN 75
+#define CS_GPIO_PIN 76
+#define IRQ_GPIO_PIN 77
+
+/* hdb bus */
+#define DB0_GPIO_PIN 58
+#define DB15_GPIO_PIN 73
+
+static int gpios[] = { PWR_GPIO_PIN, CFG_GPIO_PIN, RDY_GPIO_PIN, DC_GPIO_PIN,
+ RST_GPIO_PIN, RD_GPIO_PIN, WR_GPIO_PIN, CS_GPIO_PIN,
+ IRQ_GPIO_PIN, LED_GPIO_PIN };
+static char *gpio_names[] = { "PWR", "CFG", "RDY", "DC", "RST", "RD", "WR",
+ "CS", "IRQ", "LED" };
+
+static int am300_wait_event(struct broadsheetfb_par *par)
+{
+ /* todo: improve err recovery */
+ wait_event(par->waitq, gpio_get_value(RDY_GPIO_PIN));
+ return 0;
+}
+
+static int am300_init_gpio_regs(struct broadsheetfb_par *par)
+{
+ int i;
+ int err;
+ char dbname[8];
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++) {
+ err = gpio_request(gpios[i], gpio_names[i]);
+ if (err) {
+ dev_err(&am300_device->dev, "failed requesting "
+ "gpio %s, err=%d\n", gpio_names[i], err);
+ goto err_req_gpio;
+ }
+ }
+
+ /* we also need to take care of the hdb bus */
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++) {
+ sprintf(dbname, "DB%d", i);
+ err = gpio_request(i, dbname);
+ if (err) {
+ dev_err(&am300_device->dev, "failed requesting "
+ "gpio %d, err=%d\n", i, err);
+ goto err_req_gpio2;
+ }
+ }
+
+ /* setup the outputs and init values */
+ gpio_direction_output(PWR_GPIO_PIN, 0);
+ gpio_direction_output(CFG_GPIO_PIN, 1);
+ gpio_direction_output(DC_GPIO_PIN, 0);
+ gpio_direction_output(RD_GPIO_PIN, 1);
+ gpio_direction_output(WR_GPIO_PIN, 1);
+ gpio_direction_output(CS_GPIO_PIN, 1);
+ gpio_direction_output(RST_GPIO_PIN, 0);
+
+ /* setup the inputs */
+ gpio_direction_input(RDY_GPIO_PIN);
+ gpio_direction_input(IRQ_GPIO_PIN);
+
+ /* start the hdb bus as an input */
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+ gpio_direction_output(i, 0);
+
+ /* go into command mode */
+ gpio_set_value(CFG_GPIO_PIN, 1);
+ gpio_set_value(RST_GPIO_PIN, 0);
+ msleep(10);
+ gpio_set_value(RST_GPIO_PIN, 1);
+ msleep(10);
+ am300_wait_event(par);
+
+ return 0;
+
+err_req_gpio2:
+ while (--i >= DB0_GPIO_PIN)
+ gpio_free(i);
+ i = ARRAY_SIZE(gpios);
+err_req_gpio:
+ while (--i >= 0)
+ gpio_free(gpios[i]);
+
+ return err;
+}
+
+static int am300_init_board(struct broadsheetfb_par *par)
+{
+ return am300_init_gpio_regs(par);
+}
+
+static void am300_cleanup(struct broadsheetfb_par *par)
+{
+ int i;
+
+ free_irq(IRQ_GPIO(RDY_GPIO_PIN), par);
+
+ for (i = 0; i < ARRAY_SIZE(gpios); i++)
+ gpio_free(gpios[i]);
+
+ for (i = DB0_GPIO_PIN; i <= DB15_GPIO_PIN; i++)
+ gpio_free(i);
+
+}
+
+static u16 am300_get_hdb(struct broadsheetfb_par *par)
+{
+ u16 res = 0;
+ int i;
+
+ for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+ res |= (gpio_get_value(DB0_GPIO_PIN + i)) ? (1 << i) : 0;
+
+ return res;
+}
+
+static void am300_set_hdb(struct broadsheetfb_par *par, u16 data)
+{
+ int i;
+
+ for (i = 0; i <= (DB15_GPIO_PIN - DB0_GPIO_PIN) ; i++)
+ gpio_set_value(DB0_GPIO_PIN + i, (data >> i) & 0x01);
+}
+
+
+static void am300_set_ctl(struct broadsheetfb_par *par, unsigned char bit,
+ u8 state)
+{
+ switch (bit) {
+ case BS_CS:
+ gpio_set_value(CS_GPIO_PIN, state);
+ break;
+ case BS_DC:
+ gpio_set_value(DC_GPIO_PIN, state);
+ break;
+ case BS_WR:
+ gpio_set_value(WR_GPIO_PIN, state);
+ break;
+ }
+}
+
+static int am300_get_panel_type(void)
+{
+ return panel_type;
+}
+
+static irqreturn_t am300_handle_irq(int irq, void *dev_id)
+{
+ struct broadsheetfb_par *par = dev_id;
+
+ wake_up(&par->waitq);
+ return IRQ_HANDLED;
+}
+
+static int am300_setup_irq(struct fb_info *info)
+{
+ int ret;
+ struct broadsheetfb_par *par = info->par;
+
+ ret = request_irq(IRQ_GPIO(RDY_GPIO_PIN), am300_handle_irq,
+ IRQF_DISABLED|IRQF_TRIGGER_RISING,
+ "AM300", par);
+ if (ret)
+ dev_err(&am300_device->dev, "request_irq failed: %d\n", ret);
+
+ return ret;
+}
+
+static struct broadsheet_board am300_board = {
+ .owner = THIS_MODULE,
+ .init = am300_init_board,
+ .cleanup = am300_cleanup,
+ .set_hdb = am300_set_hdb,
+ .get_hdb = am300_get_hdb,
+ .set_ctl = am300_set_ctl,
+ .wait_for_rdy = am300_wait_event,
+ .get_panel_type = am300_get_panel_type,
+ .setup_irq = am300_setup_irq,
+};
+
+int __init am300_init(void)
+{
+ int ret;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(am300_pin_config));
+
+ /* request our platform independent driver */
+ request_module("broadsheetfb");
+
+ am300_device = platform_device_alloc("broadsheetfb", -1);
+ if (!am300_device)
+ return -ENOMEM;
+
+ /* the am300_board that will be seen by broadsheetfb is a copy */
+ platform_device_add_data(am300_device, &am300_board,
+ sizeof(am300_board));
+
+ ret = platform_device_add(am300_device);
+
+ if (ret) {
+ platform_device_put(am300_device);
+ return ret;
+ }
+
+ return 0;
+}
+
+module_param(panel_type, uint, 0);
+MODULE_PARM_DESC(panel_type, "Select the panel type: 37, 6, 97");
+
+MODULE_DESCRIPTION("board driver for am300 epd kit");
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
new file mode 100644
index 00000000..6ca327d9
--- /dev/null
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -0,0 +1,831 @@
+/*
+ * linux/arch/arm/mach-pxa/balloon3.c
+ *
+ * Support for Balloonboard.org Balloon3 board.
+ *
+ * Author: Nick Bane, Wookey, Jonathan McDowell
+ * Created: June, 2006
+ * Copyright: Toby Churchill Ltd
+ * Derived from mainstone.c, by Nico Pitre
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <linux/ucb1400.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/types.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/physmap.h>
+#include <linux/regulator/max1586.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/balloon3.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long balloon3_pin_config[] __initdata = {
+ /* Select BTUART 'COM1/ttyS0' as IO option for pins 42/43/44/45 */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* Reset, configured as GPIO wakeup source */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+};
+
+/******************************************************************************
+ * Compatibility: Parameter parsing
+ ******************************************************************************/
+static unsigned long balloon3_irq_enabled;
+
+static unsigned long balloon3_features_present =
+ (1 << BALLOON3_FEATURE_OHCI) | (1 << BALLOON3_FEATURE_CF) |
+ (1 << BALLOON3_FEATURE_AUDIO) |
+ (1 << BALLOON3_FEATURE_TOPPOLY);
+
+int balloon3_has(enum balloon3_features feature)
+{
+ return (balloon3_features_present & (1 << feature)) ? 1 : 0;
+}
+EXPORT_SYMBOL_GPL(balloon3_has);
+
+int __init parse_balloon3_features(char *arg)
+{
+ if (!arg)
+ return 0;
+
+ return strict_strtoul(arg, 0, &balloon3_features_present);
+}
+early_param("balloon3_features", parse_balloon3_features);
+
+/******************************************************************************
+ * Compact Flash slot
+ ******************************************************************************/
+#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
+static unsigned long balloon3_cf_pin_config[] __initdata = {
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+};
+
+static void __init balloon3_cf_init(void)
+{
+ if (!balloon3_has(BALLOON3_FEATURE_CF))
+ return;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_cf_pin_config));
+}
+#else
+static inline void balloon3_cf_init(void) {}
+#endif
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition balloon3_nor_partitions[] = {
+ {
+ .name = "Flash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data balloon3_flash_data[] = {
+ {
+ .width = 2, /* bankwidth in bytes */
+ .parts = balloon3_nor_partitions,
+ .nr_parts = ARRAY_SIZE(balloon3_nor_partitions)
+ }
+};
+
+static struct resource balloon3_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device balloon3_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &balloon3_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = balloon3_flash_data,
+ },
+};
+static void __init balloon3_nor_init(void)
+{
+ platform_device_register(&balloon3_flash);
+}
+#else
+static inline void balloon3_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Audio and Touchscreen
+ ******************************************************************************/
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static unsigned long balloon3_ac97_pin_config[] __initdata = {
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+ GPIO95_GPIO,
+};
+
+static struct ucb1400_pdata vpac270_ucb1400_pdata = {
+ .irq = IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ),
+};
+
+
+static struct platform_device balloon3_ucb1400_device = {
+ .name = "ucb1400_core",
+ .id = -1,
+ .dev = {
+ .platform_data = &vpac270_ucb1400_pdata,
+ },
+};
+
+static void __init balloon3_ts_init(void)
+{
+ if (!balloon3_has(BALLOON3_FEATURE_AUDIO))
+ return;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_ac97_pin_config));
+ pxa_set_ac97_info(NULL);
+ platform_device_register(&balloon3_ucb1400_device);
+}
+#else
+static inline void balloon3_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static unsigned long balloon3_lcd_pin_config[] __initdata = {
+ GPIOxx_LCD_TFT_16BPP,
+ GPIO99_GPIO,
+};
+
+static struct pxafb_mode_info balloon3_lcd_modes[] = {
+ {
+ .pixclock = 38000,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 8,
+ .left_margin = 8,
+ .right_margin = 8,
+ .vsync_len = 2,
+ .upper_margin = 4,
+ .lower_margin = 5,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info balloon3_lcd_screen = {
+ .modes = balloon3_lcd_modes,
+ .num_modes = ARRAY_SIZE(balloon3_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void balloon3_backlight_power(int on)
+{
+ gpio_set_value(BALLOON3_GPIO_RUN_BACKLIGHT, on);
+}
+
+static void __init balloon3_lcd_init(void)
+{
+ int ret;
+
+ if (!balloon3_has(BALLOON3_FEATURE_TOPPOLY))
+ return;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_lcd_pin_config));
+
+ ret = gpio_request(BALLOON3_GPIO_RUN_BACKLIGHT, "BKL-ON");
+ if (ret) {
+ pr_err("Requesting BKL-ON GPIO failed!\n");
+ goto err;
+ }
+
+ ret = gpio_direction_output(BALLOON3_GPIO_RUN_BACKLIGHT, 1);
+ if (ret) {
+ pr_err("Setting BKL-ON GPIO direction failed!\n");
+ goto err2;
+ }
+
+ balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
+ pxa_set_fb_info(NULL, &balloon3_lcd_screen);
+ return;
+
+err2:
+ gpio_free(BALLOON3_GPIO_RUN_BACKLIGHT);
+err:
+ return;
+}
+#else
+static inline void balloon3_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static unsigned long balloon3_mmc_pin_config[] __initdata = {
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+};
+
+static struct pxamci_platform_data balloon3_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+ .detect_delay_ms = 200,
+};
+
+static void __init balloon3_mmc_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_mmc_pin_config));
+ pxa_set_mci_info(&balloon3_mci_platform_data);
+}
+#else
+static inline void balloon3_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Gadget
+ ******************************************************************************/
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
+static void balloon3_udc_command(int cmd)
+{
+ if (cmd == PXA2XX_UDC_CMD_CONNECT)
+ UP2OCR |= UP2OCR_DPPUE | UP2OCR_DPPUBE;
+ else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+ UP2OCR &= ~UP2OCR_DPPUE;
+}
+
+static int balloon3_udc_is_connected(void)
+{
+ return 1;
+}
+
+static struct pxa2xx_udc_mach_info balloon3_udc_info __initdata = {
+ .udc_command = balloon3_udc_command,
+ .udc_is_connected = balloon3_udc_is_connected,
+ .gpio_pullup = -1,
+};
+
+static void __init balloon3_udc_init(void)
+{
+ pxa_set_udc_info(&balloon3_udc_info);
+ platform_device_register(&balloon3_gpio_vbus);
+}
+#else
+static inline void balloon3_udc_init(void) {}
+#endif
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
+static struct pxaficp_platform_data balloon3_ficp_platform_data = {
+ .transceiver_cap = IR_FIRMODE | IR_SIRMODE | IR_OFF,
+};
+
+static void __init balloon3_irda_init(void)
+{
+ pxa_set_ficp_info(&balloon3_ficp_platform_data);
+}
+#else
+static inline void balloon3_irda_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static unsigned long balloon3_uhc_pin_config[] __initdata = {
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+};
+
+static struct pxaohci_platform_data balloon3_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static void __init balloon3_uhc_init(void)
+{
+ if (!balloon3_has(BALLOON3_FEATURE_OHCI))
+ return;
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_uhc_pin_config));
+ pxa_set_ohci_info(&balloon3_ohci_info);
+}
+#else
+static inline void balloon3_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static unsigned long balloon3_led_pin_config[] __initdata = {
+ GPIO9_GPIO, /* NAND activity LED */
+ GPIO10_GPIO, /* Heartbeat LED */
+};
+
+struct gpio_led balloon3_gpio_leds[] = {
+ {
+ .name = "balloon3:green:idle",
+ .default_trigger = "heartbeat",
+ .gpio = BALLOON3_GPIO_LED_IDLE,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:green:nand",
+ .default_trigger = "nand-disk",
+ .gpio = BALLOON3_GPIO_LED_NAND,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data balloon3_gpio_led_info = {
+ .leds = balloon3_gpio_leds,
+ .num_leds = ARRAY_SIZE(balloon3_gpio_leds),
+};
+
+static struct platform_device balloon3_leds = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &balloon3_gpio_led_info,
+ }
+};
+
+struct gpio_led balloon3_pcf_gpio_leds[] = {
+ {
+ .name = "balloon3:green:led0",
+ .gpio = BALLOON3_PCF_GPIO_LED0,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:green:led1",
+ .gpio = BALLOON3_PCF_GPIO_LED1,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:orange:led2",
+ .gpio = BALLOON3_PCF_GPIO_LED2,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:orange:led3",
+ .gpio = BALLOON3_PCF_GPIO_LED3,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:orange:led4",
+ .gpio = BALLOON3_PCF_GPIO_LED4,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:orange:led5",
+ .gpio = BALLOON3_PCF_GPIO_LED5,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:red:led6",
+ .gpio = BALLOON3_PCF_GPIO_LED6,
+ .active_low = 1,
+ }, {
+ .name = "balloon3:red:led7",
+ .gpio = BALLOON3_PCF_GPIO_LED7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data balloon3_pcf_gpio_led_info = {
+ .leds = balloon3_pcf_gpio_leds,
+ .num_leds = ARRAY_SIZE(balloon3_pcf_gpio_leds),
+};
+
+static struct platform_device balloon3_pcf_leds = {
+ .name = "leds-gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &balloon3_pcf_gpio_led_info,
+ }
+};
+
+static void __init balloon3_leds_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_led_pin_config));
+ platform_device_register(&balloon3_leds);
+ platform_device_register(&balloon3_pcf_leds);
+}
+#else
+static inline void balloon3_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * FPGA IRQ
+ ******************************************************************************/
+static void balloon3_mask_irq(struct irq_data *d)
+{
+ int balloon3_irq = (d->irq - BALLOON3_IRQ(0));
+ balloon3_irq_enabled &= ~(1 << balloon3_irq);
+ __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
+}
+
+static void balloon3_unmask_irq(struct irq_data *d)
+{
+ int balloon3_irq = (d->irq - BALLOON3_IRQ(0));
+ balloon3_irq_enabled |= (1 << balloon3_irq);
+ __raw_writel(~balloon3_irq_enabled, BALLOON3_INT_CONTROL_REG);
+}
+
+static struct irq_chip balloon3_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = balloon3_mask_irq,
+ .irq_mask = balloon3_mask_irq,
+ .irq_unmask = balloon3_unmask_irq,
+};
+
+static void balloon3_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
+ balloon3_irq_enabled;
+ do {
+ /* clear useless edge notification */
+ if (desc->irq_data.chip->irq_ack) {
+ struct irq_data *d;
+
+ d = irq_get_irq_data(BALLOON3_AUX_NIRQ);
+ desc->irq_data.chip->irq_ack(d);
+ }
+
+ while (pending) {
+ irq = BALLOON3_IRQ(0) + __ffs(pending);
+ generic_handle_irq(irq);
+ pending &= pending - 1;
+ }
+ pending = __raw_readl(BALLOON3_INT_CONTROL_REG) &
+ balloon3_irq_enabled;
+ } while (pending);
+}
+
+static void __init balloon3_init_irq(void)
+{
+ int irq;
+
+ pxa27x_init_irq();
+ /* setup extra Balloon3 irqs */
+ for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) {
+ irq_set_chip_and_handler(irq, &balloon3_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ irq_set_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler);
+ irq_set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING);
+
+ pr_debug("%s: chained handler installed - irq %d automatically "
+ "enabled\n", __func__, BALLOON3_AUX_NIRQ);
+}
+
+/******************************************************************************
+ * GPIO expander
+ ******************************************************************************/
+#if defined(CONFIG_GPIO_PCF857X) || defined(CONFIG_GPIO_PCF857X_MODULE)
+static struct pcf857x_platform_data balloon3_pcf857x_pdata = {
+ .gpio_base = BALLOON3_PCF_GPIO_BASE,
+ .n_latch = 0,
+ .setup = NULL,
+ .teardown = NULL,
+ .context = NULL,
+};
+
+static struct i2c_board_info __initdata balloon3_i2c_devs[] = {
+ {
+ I2C_BOARD_INFO("pcf8574a", 0x38),
+ .platform_data = &balloon3_pcf857x_pdata,
+ },
+};
+
+static void __init balloon3_i2c_init(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(balloon3_i2c_devs));
+}
+#else
+static inline void balloon3_i2c_init(void) {}
+#endif
+
+/******************************************************************************
+ * NAND
+ ******************************************************************************/
+#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_CLE)
+ balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLCLE;
+ else
+ balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLCLE;
+
+ if (ctrl & NAND_ALE)
+ balloon3_ctl_set |= BALLOON3_NAND_CONTROL_FLALE;
+ else
+ balloon3_ctl_clr |= BALLOON3_NAND_CONTROL_FLALE;
+
+ if (balloon3_ctl_clr)
+ __raw_writel(balloon3_ctl_clr,
+ BALLOON3_NAND_CONTROL_REG);
+ if (balloon3_ctl_set)
+ __raw_writel(balloon3_ctl_set,
+ BALLOON3_NAND_CONTROL_REG |
+ BALLOON3_FPGA_SETnCLR);
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, this->IO_ADDR_W);
+}
+
+static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ if (chip < 0 || chip > 3)
+ return;
+
+ /* Assert all nCE lines */
+ __raw_writew(
+ BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
+ BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3,
+ BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
+
+ /* Deassert correct nCE line */
+ __raw_writew(BALLOON3_NAND_CONTROL_FLCE0 << chip,
+ BALLOON3_NAND_CONTROL_REG);
+}
+
+static int balloon3_nand_dev_ready(struct mtd_info *mtd)
+{
+ return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
+}
+
+static int balloon3_nand_probe(struct platform_device *pdev)
+{
+ uint16_t ver;
+ int ret;
+
+ __raw_writew(BALLOON3_NAND_CONTROL2_16BIT,
+ BALLOON3_NAND_CONTROL2_REG | BALLOON3_FPGA_SETnCLR);
+
+ ver = __raw_readw(BALLOON3_FPGA_VER);
+ if (ver < 0x4f08)
+ pr_warn("The FPGA code, version 0x%04x, is too old. "
+ "NAND support might be broken in this version!", ver);
+
+ /* Power up the NAND chips */
+ ret = gpio_request(BALLOON3_GPIO_RUN_NAND, "NAND");
+ if (ret)
+ goto err1;
+
+ ret = gpio_direction_output(BALLOON3_GPIO_RUN_NAND, 1);
+ if (ret)
+ goto err2;
+
+ gpio_set_value(BALLOON3_GPIO_RUN_NAND, 1);
+
+ /* Deassert all nCE lines and write protect line */
+ __raw_writel(
+ BALLOON3_NAND_CONTROL_FLCE0 | BALLOON3_NAND_CONTROL_FLCE1 |
+ BALLOON3_NAND_CONTROL_FLCE2 | BALLOON3_NAND_CONTROL_FLCE3 |
+ BALLOON3_NAND_CONTROL_FLWP,
+ BALLOON3_NAND_CONTROL_REG | BALLOON3_FPGA_SETnCLR);
+ return 0;
+
+err2:
+ gpio_free(BALLOON3_GPIO_RUN_NAND);
+err1:
+ return ret;
+}
+
+static void balloon3_nand_remove(struct platform_device *pdev)
+{
+ /* Power down the NAND chips */
+ gpio_set_value(BALLOON3_GPIO_RUN_NAND, 0);
+ gpio_free(BALLOON3_GPIO_RUN_NAND);
+}
+
+static struct mtd_partition balloon3_partition_info[] = {
+ [0] = {
+ .name = "Boot",
+ .offset = 0,
+ .size = SZ_4M,
+ },
+ [1] = {
+ .name = "RootFS",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static const char *balloon3_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data balloon3_nand_pdata = {
+ .chip = {
+ .nr_chips = 4,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(balloon3_partition_info),
+ .partitions = balloon3_partition_info,
+ .chip_delay = 50,
+ .part_probe_types = balloon3_part_probes,
+ },
+ .ctrl = {
+ .hwcontrol = 0,
+ .dev_ready = balloon3_nand_dev_ready,
+ .select_chip = balloon3_nand_select_chip,
+ .cmd_ctrl = balloon3_nand_cmd_ctl,
+ .probe = balloon3_nand_probe,
+ .remove = balloon3_nand_remove,
+ },
+};
+
+static struct resource balloon3_nand_resource[] = {
+ [0] = {
+ .start = BALLOON3_NAND_BASE,
+ .end = BALLOON3_NAND_BASE + 0x4,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device balloon3_nand = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(balloon3_nand_resource),
+ .resource = balloon3_nand_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &balloon3_nand_pdata,
+ }
+};
+
+static void __init balloon3_nand_init(void)
+{
+ platform_device_register(&balloon3_nand);
+}
+#else
+static inline void balloon3_nand_init(void) {}
+#endif
+
+/******************************************************************************
+ * Core power regulator
+ ******************************************************************************/
+#if defined(CONFIG_REGULATOR_MAX1586) || \
+ defined(CONFIG_REGULATOR_MAX1586_MODULE)
+static struct regulator_consumer_supply balloon3_max1587a_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data balloon3_max1587a_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 900000,
+ .max_uV = 1705000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = balloon3_max1587a_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(balloon3_max1587a_consumers),
+};
+
+static struct max1586_subdev_data balloon3_max1587a_subdevs[] = {
+ {
+ .name = "vcc_core",
+ .id = MAX1586_V3,
+ .platform_data = &balloon3_max1587a_v3_info,
+ }
+};
+
+static struct max1586_platform_data balloon3_max1587a_info = {
+ .subdevs = balloon3_max1587a_subdevs,
+ .num_subdevs = ARRAY_SIZE(balloon3_max1587a_subdevs),
+ .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
+};
+
+static struct i2c_board_info __initdata balloon3_pi2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &balloon3_max1587a_info,
+ },
+};
+
+static void __init balloon3_pmic_init(void)
+{
+ pxa27x_set_i2c_power_info(NULL);
+ i2c_register_board_info(1, ARRAY_AND_SIZE(balloon3_pi2c_board_info));
+}
+#else
+static inline void balloon3_pmic_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init balloon3_init(void)
+{
+ ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(balloon3_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ balloon3_i2c_init();
+ balloon3_irda_init();
+ balloon3_lcd_init();
+ balloon3_leds_init();
+ balloon3_mmc_init();
+ balloon3_nand_init();
+ balloon3_nor_init();
+ balloon3_pmic_init();
+ balloon3_ts_init();
+ balloon3_udc_init();
+ balloon3_uhc_init();
+ balloon3_cf_init();
+}
+
+static struct map_desc balloon3_io_desc[] __initdata = {
+ { /* CPLD/FPGA */
+ .virtual = BALLOON3_FPGA_VIRT,
+ .pfn = __phys_to_pfn(BALLOON3_FPGA_PHYS),
+ .length = BALLOON3_FPGA_LENGTH,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init balloon3_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(balloon3_io_desc, ARRAY_SIZE(balloon3_io_desc));
+}
+
+MACHINE_START(BALLOON3, "Balloon3")
+ /* Maintainer: Nick Bane. */
+ .map_io = balloon3_map_io,
+ .nr_irqs = BALLOON3_NR_IRQS,
+ .init_irq = balloon3_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = balloon3_init,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c
new file mode 100644
index 00000000..4284513f
--- /dev/null
+++ b/arch/arm/mach-pxa/capc7117.c
@@ -0,0 +1,156 @@
+/*
+ * linux/arch/arm/mach-pxa/capc7117.c
+ *
+ * Support for the Embedian CAPC-7117 Evaluation Kit
+ * based on the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ * rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ * Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ * rework for upstream merge
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/serial_8250.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include "generic.h"
+
+/* IDE (PATA) Support */
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 1
+};
+
+static struct resource capc7117_ide_resources[] = {
+ [0] = {
+ .start = 0x11000020,
+ .end = 0x1100003f,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = 0x1100001c,
+ .end = 0x1100001c,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO76)),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING
+ }
+};
+
+static struct platform_device capc7117_ide_device = {
+ .name = "pata_platform",
+ .num_resources = ARRAY_SIZE(capc7117_ide_resources),
+ .resource = capc7117_ide_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ .coherent_dma_mask = ~0 /* grumble */
+ }
+};
+
+static void __init capc7117_ide_init(void)
+{
+ platform_device_register(&capc7117_ide_device);
+}
+
+/* TI16C752 UART support */
+#define TI16C752_FLAGS (UPF_BOOT_AUTOCONF | \
+ UPF_IOREMAP | \
+ UPF_BUGGY_UART | \
+ UPF_SKIP_TEST)
+#define TI16C752_UARTCLK (22118400)
+static struct plat_serial8250_port ti16c752_platform_data[] = {
+ [0] = {
+ .mapbase = 0x14000000,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO78)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [1] = {
+ .mapbase = 0x14000040,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO79)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [2] = {
+ .mapbase = 0x14000080,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO80)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [3] = {
+ .mapbase = 0x140000c0,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO81)),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .flags = TI16C752_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 1,
+ .uartclk = TI16C752_UARTCLK
+ },
+ [4] = {
+ /* end of array */
+ }
+};
+
+static struct platform_device ti16c752_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = ti16c752_platform_data
+ }
+};
+
+static void __init capc7117_uarts_init(void)
+{
+ platform_device_register(&ti16c752_device);
+}
+
+static void __init capc7117_init(void)
+{
+ /* Init CoM */
+ mxm_8x10_barebones_init();
+
+ /* Init evaluation board peripherals */
+ mxm_8x10_ac97_init();
+ mxm_8x10_usb_host_init();
+ mxm_8x10_mmc_init();
+
+ capc7117_uarts_init();
+ capc7117_ide_init();
+}
+
+MACHINE_START(CAPC7117,
+ "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = capc7117_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/clock-pxa2xx.c b/arch/arm/mach-pxa/clock-pxa2xx.c
new file mode 100644
index 00000000..1d5859d9
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa2xx.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-pxa/clock-pxa2xx.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/pxa2xx-regs.h>
+
+#include "clock.h"
+
+void clk_pxa2xx_cken_enable(struct clk *clk)
+{
+ CKEN |= 1 << clk->cken;
+}
+
+void clk_pxa2xx_cken_disable(struct clk *clk)
+{
+ CKEN &= ~(1 << clk->cken);
+}
+
+const struct clkops clk_pxa2xx_cken_ops = {
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
+};
+
+#ifdef CONFIG_PM
+static uint32_t saved_cken;
+
+static int pxa2xx_clock_suspend(void)
+{
+ saved_cken = CKEN;
+ return 0;
+}
+
+static void pxa2xx_clock_resume(void)
+{
+ CKEN = saved_cken;
+}
+#else
+#define pxa2xx_clock_suspend NULL
+#define pxa2xx_clock_resume NULL
+#endif
+
+struct syscore_ops pxa2xx_clock_syscore_ops = {
+ .suspend = pxa2xx_clock_suspend,
+ .resume = pxa2xx_clock_resume,
+};
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c
new file mode 100644
index 00000000..2a37a9a8
--- /dev/null
+++ b/arch/arm/mach-pxa/clock-pxa3xx.c
@@ -0,0 +1,208 @@
+/*
+ * linux/arch/arm/mach-pxa/clock-pxa3xx.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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
+
+#include "clock.h"
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK 13000000
+
+/* Ring Oscillator Clock: 60MHz */
+#define RO_CLK 60000000
+
+#define ACCR_D0CS (1 << 26)
+#define ACCR_PCCE (1 << 11)
+
+/* crystal frequency to HSIO bus frequency multiplier (HSS) */
+static unsigned char hss_mult[4] = { 8, 12, 16, 24 };
+
+/*
+ * Get the clock frequency as reflected by CCSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa3xx_get_clk_frequency_khz(int info)
+{
+ unsigned long acsr, xclkcfg;
+ unsigned int t, xl, xn, hss, ro, XL, XN, CLK, HSS;
+
+ /* Read XCLKCFG register turbo bit */
+ __asm__ __volatile__("mrc\tp14, 0, %0, c6, c0, 0" : "=r"(xclkcfg));
+ t = xclkcfg & 0x1;
+
+ acsr = ACSR;
+
+ xl = acsr & 0x1f;
+ xn = (acsr >> 8) & 0x7;
+ hss = (acsr >> 14) & 0x3;
+
+ XL = xl * BASE_CLK;
+ XN = xn * XL;
+
+ ro = acsr & ACCR_D0CS;
+
+ CLK = (ro) ? RO_CLK : ((t) ? XN : XL);
+ HSS = (ro) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ if (info) {
+ pr_info("RO Mode clock: %d.%02dMHz (%sactive)\n",
+ RO_CLK / 1000000, (RO_CLK % 1000000) / 10000,
+ (ro) ? "" : "in");
+ pr_info("Run Mode clock: %d.%02dMHz (*%d)\n",
+ XL / 1000000, (XL % 1000000) / 10000, xl);
+ pr_info("Turbo Mode clock: %d.%02dMHz (*%d, %sactive)\n",
+ XN / 1000000, (XN % 1000000) / 10000, xn,
+ (t) ? "" : "in");
+ pr_info("HSIO bus clock: %d.%02dMHz\n",
+ HSS / 1000000, (HSS % 1000000) / 10000);
+ }
+
+ return CLK / 1000;
+}
+
+/*
+ * Return the current AC97 clock frequency.
+ */
+static unsigned long clk_pxa3xx_ac97_getrate(struct clk *clk)
+{
+ unsigned long rate = 312000000;
+ unsigned long ac97_div;
+
+ ac97_div = AC97_DIV;
+
+ /* This may loose precision for some rates but won't for the
+ * standard 24.576MHz.
+ */
+ rate /= (ac97_div >> 12) & 0x7fff;
+ rate *= (ac97_div & 0xfff);
+
+ return rate;
+}
+
+/*
+ * Return the current HSIO bus clock frequency
+ */
+static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
+{
+ unsigned long acsr;
+ unsigned int hss, hsio_clk;
+
+ acsr = ACSR;
+
+ hss = (acsr >> 14) & 0x3;
+ hsio_clk = (acsr & ACCR_D0CS) ? RO_CLK : hss_mult[hss] * BASE_CLK;
+
+ return hsio_clk;
+}
+
+/* crystal frequency to static memory controller multiplier (SMCFS) */
+static unsigned int smcfs_mult[8] = { 6, 0, 8, 0, 0, 16, };
+static unsigned int df_clkdiv[4] = { 1, 2, 4, 1 };
+
+static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk)
+{
+ unsigned long acsr = ACSR;
+ unsigned long memclkcfg = __raw_readl(MEMCLKCFG);
+
+ return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] /
+ df_clkdiv[(memclkcfg >> 16) & 0x3];
+}
+
+void clk_pxa3xx_cken_enable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ if (clk->cken < 32)
+ CKENA |= mask;
+ else
+ CKENB |= mask;
+}
+
+void clk_pxa3xx_cken_disable(struct clk *clk)
+{
+ unsigned long mask = 1ul << (clk->cken & 0x1f);
+
+ if (clk->cken < 32)
+ CKENA &= ~mask;
+ else
+ CKENB &= ~mask;
+}
+
+const struct clkops clk_pxa3xx_cken_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+};
+
+const struct clkops clk_pxa3xx_hsio_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_hsio_getrate,
+};
+
+const struct clkops clk_pxa3xx_ac97_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_ac97_getrate,
+};
+
+const struct clkops clk_pxa3xx_smemc_ops = {
+ .enable = clk_pxa3xx_cken_enable,
+ .disable = clk_pxa3xx_cken_disable,
+ .getrate = clk_pxa3xx_smemc_getrate,
+};
+
+static void clk_pout_enable(struct clk *clk)
+{
+ OSCC |= OSCC_PEN;
+}
+
+static void clk_pout_disable(struct clk *clk)
+{
+ OSCC &= ~OSCC_PEN;
+}
+
+const struct clkops clk_pxa3xx_pout_ops = {
+ .enable = clk_pout_enable,
+ .disable = clk_pout_disable,
+};
+
+#ifdef CONFIG_PM
+static uint32_t cken[2];
+static uint32_t accr;
+
+static int pxa3xx_clock_suspend(void)
+{
+ cken[0] = CKENA;
+ cken[1] = CKENB;
+ accr = ACCR;
+ return 0;
+}
+
+static void pxa3xx_clock_resume(void)
+{
+ ACCR = accr;
+ CKENA = cken[0];
+ CKENB = cken[1];
+}
+#else
+#define pxa3xx_clock_suspend NULL
+#define pxa3xx_clock_resume NULL
+#endif
+
+struct syscore_ops pxa3xx_clock_syscore_ops = {
+ .suspend = pxa3xx_clock_suspend,
+ .resume = pxa3xx_clock_resume,
+};
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
new file mode 100644
index 00000000..d5152220
--- /dev/null
+++ b/arch/arm/mach-pxa/clock.c
@@ -0,0 +1,71 @@
+/*
+ * linux/arch/arm/mach-sa1100/clock.c
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clkdev.h>
+
+#include "clock.h"
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ clk->ops->enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ if (clk->delay)
+ udelay(clk->delay);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ clk->ops->disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ rate = clk->rate;
+ if (clk->ops->getrate)
+ rate = clk->ops->getrate(clk);
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_dummy_enable(struct clk *clk)
+{
+}
+
+void clk_dummy_disable(struct clk *clk)
+{
+}
+
+const struct clkops clk_dummy_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+};
+
+struct clk clk_dummy = {
+ .ops = &clk_dummy_ops,
+};
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
new file mode 100644
index 00000000..1f2fb9c4
--- /dev/null
+++ b/arch/arm/mach-pxa/clock.h
@@ -0,0 +1,79 @@
+#include <linux/clkdev.h>
+#include <linux/syscore_ops.h>
+
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ unsigned long (*getrate)(struct clk *);
+};
+
+struct clk {
+ const struct clkops *ops;
+ unsigned long rate;
+ unsigned int cken;
+ unsigned int delay;
+ unsigned int enabled;
+};
+
+void clk_dummy_enable(struct clk *);
+void clk_dummy_disable(struct clk *);
+
+extern const struct clkops clk_dummy_ops;
+extern struct clk clk_dummy;
+
+#define INIT_CLKREG(_clk,_devname,_conname) \
+ { \
+ .clk = _clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
+#define DEFINE_CK(_name, _cken, _ops) \
+struct clk clk_##_name = { \
+ .ops = _ops, \
+ .cken = CKEN_##_cken, \
+ }
+
+#define DEFINE_CLK(_name, _ops, _rate, _delay) \
+struct clk clk_##_name = { \
+ .ops = _ops, \
+ .rate = _rate, \
+ .delay = _delay, \
+ }
+
+#define DEFINE_PXA2_CKEN(_name, _cken, _rate, _delay) \
+struct clk clk_##_name = { \
+ .ops = &clk_pxa2xx_cken_ops, \
+ .rate = _rate, \
+ .cken = CKEN_##_cken, \
+ .delay = _delay, \
+ }
+
+extern const struct clkops clk_pxa2xx_cken_ops;
+
+void clk_pxa2xx_cken_enable(struct clk *clk);
+void clk_pxa2xx_cken_disable(struct clk *clk);
+
+extern struct syscore_ops pxa2xx_clock_syscore_ops;
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+#define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay) \
+struct clk clk_##_name = { \
+ .ops = &clk_pxa3xx_cken_ops, \
+ .rate = _rate, \
+ .cken = CKEN_##_cken, \
+ .delay = _delay, \
+ }
+
+extern const struct clkops clk_pxa3xx_cken_ops;
+extern const struct clkops clk_pxa3xx_hsio_ops;
+extern const struct clkops clk_pxa3xx_ac97_ops;
+extern const struct clkops clk_pxa3xx_pout_ops;
+extern const struct clkops clk_pxa3xx_smemc_ops;
+
+extern void clk_pxa3xx_cken_enable(struct clk *);
+extern void clk_pxa3xx_cken_disable(struct clk *);
+
+extern struct syscore_ops pxa3xx_clock_syscore_ops;
+
+#endif
diff --git a/arch/arm/mach-pxa/cm-x255.c b/arch/arm/mach-pxa/cm-x255.c
new file mode 100644
index 00000000..93f59f87
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x255.c
@@ -0,0 +1,237 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x255.c
+ *
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand-gpio.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa25x.h>
+
+#include "generic.h"
+
+#define GPIO_NAND_CS (5)
+#define GPIO_NAND_ALE (4)
+#define GPIO_NAND_CLE (3)
+#define GPIO_NAND_RB (10)
+
+static unsigned long cmx255_pin_config[] = {
+ /* AC'97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* SSP2 */
+ GPIO81_SSP2_CLK_OUT,
+ GPIO82_SSP2_FRM_OUT,
+ GPIO83_SSP2_TXD,
+ GPIO84_SSP2_RXD,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* SDRAM and local bus */
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+ GPIO33_nCS_5,
+ GPIO18_RDY,
+
+ /* GPIO */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,
+ GPIO9_GPIO, /* PC card reset */
+
+ /* NAND controls */
+ GPIO5_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
+ GPIO4_GPIO | MFP_LPM_DRIVE_LOW, /* NAND ALE */
+ GPIO3_GPIO | MFP_LPM_DRIVE_LOW, /* NAND CLE */
+ GPIO10_GPIO, /* NAND Ready/Busy */
+
+ /* interrupts */
+ GPIO22_GPIO, /* DM9000 interrupt */
+};
+
+#if defined(CONFIG_SPI_PXA2XX)
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+ .num_chipselect = 1,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "rtc-max6902",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+static void __init cmx255_init_rtc(void)
+{
+ pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
+ spi_register_board_info(ARRAY_AND_SIZE(spi_board_info));
+}
+#else
+static inline void cmx255_init_rtc(void) {}
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition cmx255_nor_partitions[] = {
+ {
+ .name = "ARMmon",
+ .size = 0x00030000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ } , {
+ .name = "ARMmon setup block",
+ .size = 0x00010000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ } , {
+ .name = "kernel",
+ .size = 0x00160000,
+ .offset = MTDPART_OFS_APPEND,
+ } , {
+ .name = "ramdisk",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND
+ }
+};
+
+static struct physmap_flash_data cmx255_nor_flash_data[] = {
+ {
+ .width = 2, /* bankwidth in bytes */
+ .parts = cmx255_nor_partitions,
+ .nr_parts = ARRAY_SIZE(cmx255_nor_partitions)
+ }
+};
+
+static struct resource cmx255_nor_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device cmx255_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = cmx255_nor_flash_data,
+ },
+ .resource = &cmx255_nor_resource,
+ .num_resources = 1,
+};
+
+static void __init cmx255_init_nor(void)
+{
+ platform_device_register(&cmx255_nor);
+}
+#else
+static inline void cmx255_init_nor(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE)
+static struct resource cmx255_nand_resource[] = {
+ [0] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + 11,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS5_PHYS,
+ .end = PXA_CS5_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition cmx255_nand_parts[] = {
+ [0] = {
+ .name = "cmx255-nand",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0,
+ },
+};
+
+static struct gpio_nand_platdata cmx255_nand_platdata = {
+ .gpio_nce = GPIO_NAND_CS,
+ .gpio_cle = GPIO_NAND_CLE,
+ .gpio_ale = GPIO_NAND_ALE,
+ .gpio_rdy = GPIO_NAND_RB,
+ .gpio_nwp = -1,
+ .parts = cmx255_nand_parts,
+ .num_parts = ARRAY_SIZE(cmx255_nand_parts),
+ .chip_delay = 25,
+};
+
+static struct platform_device cmx255_nand = {
+ .name = "gpio-nand",
+ .num_resources = ARRAY_SIZE(cmx255_nand_resource),
+ .resource = cmx255_nand_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &cmx255_nand_platdata,
+ }
+};
+
+static void __init cmx255_init_nand(void)
+{
+ platform_device_register(&cmx255_nand);
+}
+#else
+static inline void cmx255_init_nand(void) {}
+#endif
+
+void __init cmx255_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx255_pin_config));
+
+ cmx255_init_rtc();
+ cmx255_init_nor();
+ cmx255_init_nand();
+}
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
new file mode 100644
index 00000000..13518a70
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -0,0 +1,412 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x270.c
+ *
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <linux/rtc-v3020.h>
+#include <video/mbxfb.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/spi/libertas_spi.h>
+
+#include <mach/pxa27x.h>
+#include <mach/ohci.h>
+#include <mach/mmc.h>
+
+#include "generic.h"
+
+/* physical address if local-bus attached devices */
+#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22))
+
+/* GPIO IRQ usage */
+#define GPIO83_MMC_IRQ (83)
+
+#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ)
+
+/* MMC power enable */
+#define GPIO105_MMC_POWER (105)
+
+/* WLAN GPIOS */
+#define GPIO19_WLAN_STRAP (19)
+#define GPIO102_WLAN_RST (102)
+
+static unsigned long cmx270_pin_config[] = {
+ /* AC'97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO98_AC97_SYSCLK,
+ GPIO113_AC97_nRESET,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* MCI controller */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* SSP2 */
+ GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */
+ GPIO14_GPIO,
+ GPIO87_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* SDRAM and local bus */
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+ GPIO33_nCS_5,
+ GPIO49_nPWE,
+ GPIO18_RDY,
+
+ /* GPIO */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH,
+ GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */
+ GPIO53_GPIO, /* PC card reset */
+ GPIO102_GPIO, /* WLAN reset */
+
+ /* NAND controls */
+ GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
+ GPIO89_GPIO, /* NAND Ready/Busy */
+
+ /* interrupts */
+ GPIO10_GPIO, /* DM9000 interrupt */
+ GPIO83_GPIO, /* MMC card detect */
+ GPIO95_GPIO, /* WLAN interrupt */
+};
+
+/* V3020 RTC */
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+static struct resource cmx270_v3020_resource[] = {
+ [0] = {
+ .start = RTC_PHYS_BASE,
+ .end = RTC_PHYS_BASE + 4,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct v3020_platform_data cmx270_v3020_pdata = {
+ .leftshift = 16,
+};
+
+static struct platform_device cmx270_rtc_device = {
+ .name = "v3020",
+ .num_resources = ARRAY_SIZE(cmx270_v3020_resource),
+ .resource = cmx270_v3020_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &cmx270_v3020_pdata,
+ }
+};
+
+static void __init cmx270_init_rtc(void)
+{
+ platform_device_register(&cmx270_rtc_device);
+}
+#else
+static inline void cmx270_init_rtc(void) {}
+#endif
+
+/* 2700G graphics */
+#if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE)
+static u64 fb_dma_mask = ~(u64)0;
+
+static struct resource cmx270_2700G_resource[] = {
+ /* frame buffer memory including ODFB and External SDRAM */
+ [0] = {
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 0x01ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ /* Marathon registers */
+ [1] = {
+ .start = PXA_CS2_PHYS + 0x03fe0000,
+ .end = PXA_CS2_PHYS + 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static unsigned long cmx270_marathon_on[] = {
+ GPIO58_GPIO,
+ GPIO59_GPIO,
+ GPIO60_GPIO,
+ GPIO61_GPIO,
+ GPIO62_GPIO,
+ GPIO63_GPIO,
+ GPIO64_GPIO,
+ GPIO65_GPIO,
+ GPIO66_GPIO,
+ GPIO67_GPIO,
+ GPIO68_GPIO,
+ GPIO69_GPIO,
+ GPIO70_GPIO,
+ GPIO71_GPIO,
+ GPIO72_GPIO,
+ GPIO73_GPIO,
+ GPIO74_GPIO,
+ GPIO75_GPIO,
+ GPIO76_GPIO,
+ GPIO77_GPIO,
+};
+
+static unsigned long cmx270_marathon_off[] = {
+ GPIOxx_LCD_TFT_16BPP,
+};
+
+static int cmx270_marathon_probe(struct fb_info *fb)
+{
+ int gpio, err;
+
+ for (gpio = 58; gpio <= 77; gpio++) {
+ err = gpio_request(gpio, "LCD");
+ if (err)
+ return err;
+ gpio_direction_input(gpio);
+ }
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_on));
+ return 0;
+}
+
+static int cmx270_marathon_remove(struct fb_info *fb)
+{
+ int gpio;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off));
+
+ for (gpio = 58; gpio <= 77; gpio++)
+ gpio_free(gpio);
+
+ return 0;
+}
+
+static struct mbxfb_platform_data cmx270_2700G_data = {
+ .xres = {
+ .min = 240,
+ .max = 1200,
+ .defval = 640,
+ },
+ .yres = {
+ .min = 240,
+ .max = 1200,
+ .defval = 480,
+ },
+ .bpp = {
+ .min = 16,
+ .max = 32,
+ .defval = 16,
+ },
+ .memsize = 8*1024*1024,
+ .probe = cmx270_marathon_probe,
+ .remove = cmx270_marathon_remove,
+};
+
+static struct platform_device cmx270_2700G = {
+ .name = "mbx-fb",
+ .dev = {
+ .platform_data = &cmx270_2700G_data,
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(cmx270_2700G_resource),
+ .resource = cmx270_2700G_resource,
+ .id = -1,
+};
+
+static void __init cmx270_init_2700G(void)
+{
+ platform_device_register(&cmx270_2700G);
+}
+#else
+static inline void cmx270_init_2700G(void) {}
+#endif
+
+/* PXA27x OHCI controller setup */
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data cmx270_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
+};
+
+static void __init cmx270_init_ohci(void)
+{
+ pxa_set_ohci_info(&cmx270_ohci_platform_data);
+}
+#else
+static inline void cmx270_init_ohci(void) {}
+#endif
+
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+static struct pxamci_platform_data cmx270_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = GPIO83_MMC_IRQ,
+ .gpio_card_ro = -1,
+ .gpio_power = GPIO105_MMC_POWER,
+ .gpio_power_invert = 1,
+};
+
+static void __init cmx270_init_mmc(void)
+{
+ pxa_set_mci_info(&cmx270_mci_platform_data);
+}
+#else
+static inline void cmx270_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master cm_x270_spi_info = {
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+static struct pxa2xx_spi_chip cm_x270_libertas_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .timeout = 1000,
+ .gpio_cs = 14,
+};
+
+static unsigned long cm_x270_libertas_pin_config[] = {
+ /* SSP2 */
+ GPIO19_SSP2_SCLK,
+ GPIO14_GPIO,
+ GPIO87_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+
+};
+
+static int cm_x270_libertas_setup(struct spi_device *spi)
+{
+ int err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP");
+ if (err)
+ return err;
+
+ err = gpio_request(GPIO102_WLAN_RST, "WLAN RST");
+ if (err)
+ goto err_free_strap;
+
+ err = gpio_direction_output(GPIO102_WLAN_RST, 0);
+ if (err)
+ goto err_free_strap;
+ msleep(100);
+
+ err = gpio_direction_output(GPIO19_WLAN_STRAP, 1);
+ if (err)
+ goto err_free_strap;
+ msleep(100);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cm_x270_libertas_pin_config));
+
+ gpio_set_value(GPIO102_WLAN_RST, 1);
+ msleep(100);
+
+ spi->bits_per_word = 16;
+ spi_setup(spi);
+
+ return 0;
+
+err_free_strap:
+ gpio_free(GPIO19_WLAN_STRAP);
+
+ return err;
+}
+
+static int cm_x270_libertas_teardown(struct spi_device *spi)
+{
+ gpio_set_value(GPIO102_WLAN_RST, 0);
+ gpio_free(GPIO102_WLAN_RST);
+ gpio_free(GPIO19_WLAN_STRAP);
+
+ return 0;
+}
+
+struct libertas_spi_platform_data cm_x270_libertas_pdata = {
+ .use_dummy_writes = 1,
+ .setup = cm_x270_libertas_setup,
+ .teardown = cm_x270_libertas_teardown,
+};
+
+static struct spi_board_info cm_x270_spi_devices[] __initdata = {
+ {
+ .modalias = "libertas_spi",
+ .max_speed_hz = 13000000,
+ .bus_num = 2,
+ .irq = gpio_to_irq(95),
+ .chip_select = 0,
+ .controller_data = &cm_x270_libertas_chip,
+ .platform_data = &cm_x270_libertas_pdata,
+ },
+};
+
+static void __init cmx270_init_spi(void)
+{
+ pxa2xx_set_spi_info(2, &cm_x270_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(cm_x270_spi_devices));
+}
+#else
+static inline void cmx270_init_spi(void) {}
+#endif
+
+void __init cmx270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config));
+
+#ifdef CONFIG_PM
+ pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
+#endif
+
+ cmx270_init_rtc();
+ cmx270_init_mmc();
+ cmx270_init_ohci();
+ cmx270_init_2700G();
+ cmx270_init_spi();
+}
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
new file mode 100644
index 00000000..1afc0fb7
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -0,0 +1,197 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x2xx-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ *
+ * Copyright (C) 2007, 2008 Compulab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/it8152.h>
+
+unsigned long it8152_base_address;
+static int cmx2xx_it8152_irq_gpio;
+
+static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
+{
+ /* clear our parent irq */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ it8152_irq_demux(irq, desc);
+}
+
+void __cmx2xx_pci_init_irq(int irq_gpio)
+{
+ it8152_init_irq();
+
+ cmx2xx_it8152_irq_gpio = irq_gpio;
+
+ irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
+
+ irq_set_chained_handler(gpio_to_irq(irq_gpio),
+ cmx2xx_it8152_irq_demux);
+}
+
+#ifdef CONFIG_PM
+static unsigned long sleep_save_ite[10];
+
+void __cmx2xx_pci_suspend(void)
+{
+ /* save ITE state */
+ sleep_save_ite[0] = __raw_readl(IT8152_INTC_PDCNIMR);
+ sleep_save_ite[1] = __raw_readl(IT8152_INTC_LPCNIMR);
+ sleep_save_ite[2] = __raw_readl(IT8152_INTC_LPNIAR);
+
+ /* Clear ITE IRQ's */
+ __raw_writel((0), IT8152_INTC_PDCNIRR);
+ __raw_writel((0), IT8152_INTC_LPCNIRR);
+}
+
+void __cmx2xx_pci_resume(void)
+{
+ /* restore IT8152 state */
+ __raw_writel((sleep_save_ite[0]), IT8152_INTC_PDCNIMR);
+ __raw_writel((sleep_save_ite[1]), IT8152_INTC_LPCNIMR);
+ __raw_writel((sleep_save_ite[2]), IT8152_INTC_LPNIAR);
+}
+#else
+void cmx2xx_pci_suspend(void) {}
+void cmx2xx_pci_resume(void) {}
+#endif
+
+/* PCI IRQ mapping*/
+static int __init cmx2xx_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ dev_dbg(&dev->dev, "%s: slot=%x, pin=%x\n", __func__, slot, pin);
+
+ irq = it8152_pci_map_irq(dev, slot, pin);
+ if (irq)
+ return irq;
+
+ /*
+ Here comes the ugly part. The routing is baseboard specific,
+ but defining a platform for each possible base of CM-X2XX is
+ unrealistic. Here we keep mapping for ATXBase and SB-X2XX.
+ */
+ /* ATXBASE PCI slot */
+ if (slot == 7)
+ return IT8152_PCI_INTA;
+
+ /* ATXBase/SB-X2XX CardBus */
+ if (slot == 8 || slot == 0)
+ return IT8152_PCI_INTB;
+
+ /* ATXBase Ethernet */
+ if (slot == 9)
+ return IT8152_PCI_INTA;
+
+ /* CM-x255 Onboard Ethernet */
+ if (slot == 15)
+ return IT8152_PCI_INTC;
+
+ /* SB-x2xx Ethernet */
+ if (slot == 16)
+ return IT8152_PCI_INTA;
+
+ /* PC104+ interrupt routing */
+ if ((slot == 17) || (slot == 19))
+ return IT8152_PCI_INTA;
+ if ((slot == 18) || (slot == 20))
+ return IT8152_PCI_INTB;
+
+ return(0);
+}
+
+static void cmx2xx_pci_preinit(void)
+{
+ pr_info("Initializing CM-X2XX PCI subsystem\n");
+
+ __raw_writel(0x800, IT8152_PCI_CFG_ADDR);
+ if (__raw_readl(IT8152_PCI_CFG_DATA) == 0x81521283) {
+ pr_info("PCI Bridge found.\n");
+
+ /* set PCI I/O base at 0 */
+ writel(0x848, IT8152_PCI_CFG_ADDR);
+ writel(0, IT8152_PCI_CFG_DATA);
+
+ /* set PCI memory base at 0 */
+ writel(0x840, IT8152_PCI_CFG_ADDR);
+ writel(0, IT8152_PCI_CFG_DATA);
+
+ writel(0x20, IT8152_GPIO_GPDR);
+
+ /* CardBus Controller on ATXbase baseboard */
+ writel(0x4000, IT8152_PCI_CFG_ADDR);
+ if (readl(IT8152_PCI_CFG_DATA) == 0xAC51104C) {
+ pr_info("CardBus Bridge found.\n");
+
+ /* Configure socket 0 */
+ writel(0x408C, IT8152_PCI_CFG_ADDR);
+ writel(0x1022, IT8152_PCI_CFG_DATA);
+
+ writel(0x4080, IT8152_PCI_CFG_ADDR);
+ writel(0x3844d060, IT8152_PCI_CFG_DATA);
+
+ writel(0x4090, IT8152_PCI_CFG_ADDR);
+ writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
+ 0x60440000),
+ IT8152_PCI_CFG_DATA);
+
+ writel(0x4018, IT8152_PCI_CFG_ADDR);
+ writel(0xb0000000, IT8152_PCI_CFG_DATA);
+
+ /* Configure socket 1 */
+ writel(0x418C, IT8152_PCI_CFG_ADDR);
+ writel(0x1022, IT8152_PCI_CFG_DATA);
+
+ writel(0x4180, IT8152_PCI_CFG_ADDR);
+ writel(0x3844d060, IT8152_PCI_CFG_DATA);
+
+ writel(0x4190, IT8152_PCI_CFG_ADDR);
+ writel(((readl(IT8152_PCI_CFG_DATA) & 0xffff) |
+ 0x60440000),
+ IT8152_PCI_CFG_DATA);
+
+ writel(0x4118, IT8152_PCI_CFG_ADDR);
+ writel(0xb0000000, IT8152_PCI_CFG_DATA);
+ }
+ }
+}
+
+static struct hw_pci cmx2xx_pci __initdata = {
+ .swizzle = pci_std_swizzle,
+ .map_irq = cmx2xx_pci_map_irq,
+ .nr_controllers = 1,
+ .setup = it8152_pci_setup,
+ .scan = it8152_pci_scan_bus,
+ .preinit = cmx2xx_pci_preinit,
+};
+
+static int __init cmx2xx_init_pci(void)
+{
+ if (machine_is_armcore())
+ pci_common_init(&cmx2xx_pci);
+
+ return 0;
+}
+
+subsys_initcall(cmx2xx_init_pci);
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.h b/arch/arm/mach-pxa/cm-x2xx-pci.h
new file mode 100644
index 00000000..e24aad2e
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.h
@@ -0,0 +1,13 @@
+extern void __cmx2xx_pci_init_irq(int irq_gpio);
+extern void __cmx2xx_pci_suspend(void);
+extern void __cmx2xx_pci_resume(void);
+
+#ifdef CONFIG_PCI
+#define cmx2xx_pci_init_irq(x) __cmx2xx_pci_init_irq(x)
+#define cmx2xx_pci_suspend(x) __cmx2xx_pci_suspend(x)
+#define cmx2xx_pci_resume(x) __cmx2xx_pci_resume(x)
+#else
+#define cmx2xx_pci_init_irq(x) do {} while (0)
+#define cmx2xx_pci_suspend(x) do {} while (0)
+#define cmx2xx_pci_resume(x) do {} while (0)
+#endif
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
new file mode 100644
index 00000000..a1099678
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -0,0 +1,521 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x2xx.c
+ *
+ * Copyright (C) 2008 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+
+#include <linux/dm9000.h>
+#include <linux/leds.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/smemc.h>
+
+#include <asm/hardware/it8152.h>
+
+#include "generic.h"
+#include "cm-x2xx-pci.h"
+
+extern void cmx255_init(void);
+extern void cmx270_init(void);
+
+/* reserve IRQs for IT8152 */
+#define CMX2XX_NR_IRQS (IRQ_BOARD_START + 40)
+
+/* virtual addresses for statically mapped regions */
+#define CMX2XX_VIRT_BASE (0xe8000000)
+#define CMX2XX_IT8152_VIRT (CMX2XX_VIRT_BASE)
+
+/* physical address if local-bus attached devices */
+#define CMX255_DM9000_PHYS_BASE (PXA_CS1_PHYS + (8 << 22))
+#define CMX270_DM9000_PHYS_BASE (PXA_CS1_PHYS + (6 << 22))
+
+/* leds */
+#define CMX255_GPIO_RED (27)
+#define CMX255_GPIO_GREEN (32)
+#define CMX270_GPIO_RED (93)
+#define CMX270_GPIO_GREEN (94)
+
+/* GPIO IRQ usage */
+#define GPIO22_ETHIRQ (22)
+#define GPIO10_ETHIRQ (10)
+#define CMX255_GPIO_IT8152_IRQ (0)
+#define CMX270_GPIO_IT8152_IRQ (22)
+
+#define CMX255_ETHIRQ IRQ_GPIO(GPIO22_ETHIRQ)
+#define CMX270_ETHIRQ IRQ_GPIO(GPIO10_ETHIRQ)
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource cmx255_dm9000_resource[] = {
+ [0] = {
+ .start = CMX255_DM9000_PHYS_BASE,
+ .end = CMX255_DM9000_PHYS_BASE + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CMX255_DM9000_PHYS_BASE + 4,
+ .end = CMX255_DM9000_PHYS_BASE + 4 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = CMX255_ETHIRQ,
+ .end = CMX255_ETHIRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct resource cmx270_dm9000_resource[] = {
+ [0] = {
+ .start = CMX270_DM9000_PHYS_BASE,
+ .end = CMX270_DM9000_PHYS_BASE + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CMX270_DM9000_PHYS_BASE + 8,
+ .end = CMX270_DM9000_PHYS_BASE + 8 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = CMX270_ETHIRQ,
+ .end = CMX270_ETHIRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data cmx270_dm9000_platdata = {
+ .flags = DM9000_PLATF_32BITONLY | DM9000_PLATF_NO_EEPROM,
+};
+
+static struct platform_device cmx2xx_dm9000_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cmx270_dm9000_resource),
+ .dev = {
+ .platform_data = &cmx270_dm9000_platdata,
+ }
+};
+
+static void __init cmx2xx_init_dm9000(void)
+{
+ if (cpu_is_pxa25x())
+ cmx2xx_dm9000_device.resource = cmx255_dm9000_resource;
+ else
+ cmx2xx_dm9000_device.resource = cmx270_dm9000_resource;
+ platform_device_register(&cmx2xx_dm9000_device);
+}
+#else
+static inline void cmx2xx_init_dm9000(void) {}
+#endif
+
+/* UCB1400 touchscreen controller */
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static struct platform_device cmx2xx_ts_device = {
+ .name = "ucb1400_core",
+ .id = -1,
+};
+
+static void __init cmx2xx_init_touchscreen(void)
+{
+ platform_device_register(&cmx2xx_ts_device);
+}
+#else
+static inline void cmx2xx_init_touchscreen(void) {}
+#endif
+
+/* CM-X270 LEDs */
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cmx2xx_leds[] = {
+ [0] = {
+ .name = "cm-x2xx:red",
+ .default_trigger = "nand-disk",
+ .active_low = 1,
+ },
+ [1] = {
+ .name = "cm-x2xx:green",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data cmx2xx_gpio_led_pdata = {
+ .num_leds = ARRAY_SIZE(cmx2xx_leds),
+ .leds = cmx2xx_leds,
+};
+
+static struct platform_device cmx2xx_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cmx2xx_gpio_led_pdata,
+ },
+};
+
+static void __init cmx2xx_init_leds(void)
+{
+ if (cpu_is_pxa25x()) {
+ cmx2xx_leds[0].gpio = CMX255_GPIO_RED;
+ cmx2xx_leds[1].gpio = CMX255_GPIO_GREEN;
+ } else {
+ cmx2xx_leds[0].gpio = CMX270_GPIO_RED;
+ cmx2xx_leds[1].gpio = CMX270_GPIO_GREEN;
+ }
+ platform_device_register(&cmx2xx_led_device);
+}
+#else
+static inline void cmx2xx_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+/*
+ Display definitions
+ keep these for backwards compatibility, although symbolic names (as
+ e.g. in lpd270.c) looks better
+*/
+#define MTYPE_STN320x240 0
+#define MTYPE_TFT640x480 1
+#define MTYPE_CRT640x480 2
+#define MTYPE_CRT800x600 3
+#define MTYPE_TFT320x240 6
+#define MTYPE_STN640x480 7
+
+static struct pxafb_mode_info generic_stn_320x240_mode = {
+ .pixclock = 76923,
+ .bpp = 8,
+ .xres = 320,
+ .yres = 240,
+ .hsync_len = 3,
+ .vsync_len = 2,
+ .left_margin = 3,
+ .upper_margin = 0,
+ .right_margin = 3,
+ .lower_margin = 0,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_320x240 = {
+ .modes = &generic_stn_320x240_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_STN_8BPP | LCD_PCLK_EDGE_FALL |\
+ LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_tft_640x480_mode = {
+ .pixclock = 38461,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 60,
+ .vsync_len = 2,
+ .left_margin = 70,
+ .upper_margin = 10,
+ .right_margin = 70,
+ .lower_margin = 5,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_640x480 = {
+ .modes = &generic_tft_640x480_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_PCLK_EDGE_FALL |\
+ LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_crt_640x480_mode = {
+ .pixclock = 38461,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 63,
+ .vsync_len = 2,
+ .left_margin = 81,
+ .upper_margin = 33,
+ .right_margin = 16,
+ .lower_margin = 10,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_640x480 = {
+ .modes = &generic_crt_640x480_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_crt_800x600_mode = {
+ .pixclock = 28846,
+ .bpp = 8,
+ .xres = 800,
+ .yres = 600,
+ .hsync_len = 63,
+ .vsync_len = 2,
+ .left_margin = 26,
+ .upper_margin = 21,
+ .right_margin = 26,
+ .lower_margin = 11,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_crt_800x600 = {
+ .modes = &generic_crt_800x600_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_8BPP | LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_tft_320x240_mode = {
+ .pixclock = 134615,
+ .bpp = 16,
+ .xres = 320,
+ .yres = 240,
+ .hsync_len = 63,
+ .vsync_len = 7,
+ .left_margin = 75,
+ .upper_margin = 0,
+ .right_margin = 15,
+ .lower_margin = 15,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_tft_320x240 = {
+ .modes = &generic_tft_320x240_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mode_info generic_stn_640x480_mode = {
+ .pixclock = 57692,
+ .bpp = 8,
+ .xres = 640,
+ .yres = 480,
+ .hsync_len = 4,
+ .vsync_len = 2,
+ .left_margin = 10,
+ .upper_margin = 5,
+ .right_margin = 10,
+ .lower_margin = 5,
+ .sync = (FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT),
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info generic_stn_640x480 = {
+ .modes = &generic_stn_640x480_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_STN_8BPP | LCD_AC_BIAS_FREQ(0xff),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+};
+
+static struct pxafb_mach_info *cmx2xx_display = &generic_crt_640x480;
+
+static int __init cmx2xx_set_display(char *str)
+{
+ int disp_type = simple_strtol(str, NULL, 0);
+ switch (disp_type) {
+ case MTYPE_STN320x240:
+ cmx2xx_display = &generic_stn_320x240;
+ break;
+ case MTYPE_TFT640x480:
+ cmx2xx_display = &generic_tft_640x480;
+ break;
+ case MTYPE_CRT640x480:
+ cmx2xx_display = &generic_crt_640x480;
+ break;
+ case MTYPE_CRT800x600:
+ cmx2xx_display = &generic_crt_800x600;
+ break;
+ case MTYPE_TFT320x240:
+ cmx2xx_display = &generic_tft_320x240;
+ break;
+ case MTYPE_STN640x480:
+ cmx2xx_display = &generic_stn_640x480;
+ break;
+ default: /* fallback to CRT 640x480 */
+ cmx2xx_display = &generic_crt_640x480;
+ break;
+ }
+ return 1;
+}
+
+/*
+ This should be done really early to get proper configuration for
+ frame buffer.
+ Indeed, pxafb parameters can be used istead, but CM-X2XX bootloader
+ has limitied line length for kernel command line, and also it will
+ break compatibitlty with proprietary releases already in field.
+*/
+__setup("monitor=", cmx2xx_set_display);
+
+static void __init cmx2xx_init_display(void)
+{
+ pxa_set_fb_info(NULL, cmx2xx_display);
+}
+#else
+static inline void cmx2xx_init_display(void) {}
+#endif
+
+#ifdef CONFIG_PM
+static unsigned long sleep_save_msc[10];
+
+static int cmx2xx_suspend(void)
+{
+ cmx2xx_pci_suspend();
+
+ /* save MSC registers */
+ sleep_save_msc[0] = __raw_readl(MSC0);
+ sleep_save_msc[1] = __raw_readl(MSC1);
+ sleep_save_msc[2] = __raw_readl(MSC2);
+
+ /* setup power saving mode registers */
+ PCFR = 0x0;
+ PSLR = 0xff400000;
+ PMCR = 0x00000005;
+ PWER = 0x80000000;
+ PFER = 0x00000000;
+ PRER = 0x00000000;
+ PGSR0 = 0xC0018800;
+ PGSR1 = 0x004F0002;
+ PGSR2 = 0x6021C000;
+ PGSR3 = 0x00020000;
+
+ return 0;
+}
+
+static void cmx2xx_resume(void)
+{
+ cmx2xx_pci_resume();
+
+ /* restore MSC registers */
+ __raw_writel(sleep_save_msc[0], MSC0);
+ __raw_writel(sleep_save_msc[1], MSC1);
+ __raw_writel(sleep_save_msc[2], MSC2);
+}
+
+static struct syscore_ops cmx2xx_pm_syscore_ops = {
+ .resume = cmx2xx_resume,
+ .suspend = cmx2xx_suspend,
+};
+
+static int __init cmx2xx_pm_init(void)
+{
+ register_syscore_ops(&cmx2xx_pm_syscore_ops);
+
+ return 0;
+}
+#else
+static int __init cmx2xx_pm_init(void) { return 0; }
+#endif
+
+#if defined(CONFIG_SND_PXA2XX_AC97) || defined(CONFIG_SND_PXA2XX_AC97_MODULE)
+static void __init cmx2xx_init_ac97(void)
+{
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void cmx2xx_init_ac97(void) {}
+#endif
+
+static void __init cmx2xx_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ cmx2xx_pm_init();
+
+ if (cpu_is_pxa25x())
+ cmx255_init();
+ else
+ cmx270_init();
+
+ cmx2xx_init_dm9000();
+ cmx2xx_init_display();
+ cmx2xx_init_ac97();
+ cmx2xx_init_touchscreen();
+ cmx2xx_init_leds();
+}
+
+static void __init cmx2xx_init_irq(void)
+{
+ if (cpu_is_pxa25x()) {
+ pxa25x_init_irq();
+ cmx2xx_pci_init_irq(CMX255_GPIO_IT8152_IRQ);
+ } else {
+ pxa27x_init_irq();
+ cmx2xx_pci_init_irq(CMX270_GPIO_IT8152_IRQ);
+ }
+}
+
+#ifdef CONFIG_PCI
+/* Map PCI companion statically */
+static struct map_desc cmx2xx_io_desc[] __initdata = {
+ [0] = { /* PCI bridge */
+ .virtual = CMX2XX_IT8152_VIRT,
+ .pfn = __phys_to_pfn(PXA_CS4_PHYS),
+ .length = SZ_64M,
+ .type = MT_DEVICE
+ },
+};
+
+static void __init cmx2xx_map_io(void)
+{
+ if (cpu_is_pxa25x())
+ pxa25x_map_io();
+
+ if (cpu_is_pxa27x())
+ pxa27x_map_io();
+
+ iotable_init(cmx2xx_io_desc, ARRAY_SIZE(cmx2xx_io_desc));
+
+ it8152_base_address = CMX2XX_IT8152_VIRT;
+}
+#else
+static void __init cmx2xx_map_io(void)
+{
+ if (cpu_is_pxa25x())
+ pxa25x_map_io();
+
+ if (cpu_is_pxa27x())
+ pxa27x_map_io();
+}
+#endif
+
+MACHINE_START(ARMCORE, "Compulab CM-X2XX")
+ .boot_params = 0xa0000100,
+ .map_io = cmx2xx_map_io,
+ .nr_irqs = CMX2XX_NR_IRQS,
+ .init_irq = cmx2xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = cmx2xx_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
new file mode 100644
index 00000000..8a034872
--- /dev/null
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -0,0 +1,865 @@
+/*
+ * linux/arch/arm/mach-pxa/cm-x300.c
+ *
+ * Support for the CompuLab CM-X300 modules
+ *
+ * Copyright (C) 2008,2009 CompuLab Ltd.
+ *
+ * Mike Rapoport <mike@compulab.co.il>
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
+#include <linux/leds.h>
+#include <linux/rtc-v3020.h>
+#include <linux/pwm_backlight.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/spi/tdo24m.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+
+#include <mach/pxa300.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <plat/pxa3xx_nand.h>
+#include <mach/audio.h>
+#include <mach/pxa3xx-u2d.h>
+
+#include <asm/mach/map.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#define CM_X300_ETH_PHYS 0x08000010
+
+#define GPIO82_MMC_IRQ (82)
+#define GPIO85_MMC_WP (85)
+
+#define CM_X300_MMC_IRQ IRQ_GPIO(GPIO82_MMC_IRQ)
+
+#define GPIO95_RTC_CS (95)
+#define GPIO96_RTC_WR (96)
+#define GPIO97_RTC_RD (97)
+#define GPIO98_RTC_IO (98)
+
+#define GPIO_ULPI_PHY_RST (127)
+
+static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+
+ /* BTUART */
+ GPIO111_UART2_RTS,
+ GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
+ GPIO113_UART2_TXD,
+ GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
+
+ /* STUART */
+ GPIO109_UART3_TXD,
+ GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
+
+ /* AC97 */
+ GPIO23_AC97_nACRESET,
+ GPIO24_AC97_SYSCLK,
+ GPIO29_AC97_BITCLK,
+ GPIO25_AC97_SDATA_IN_0,
+ GPIO27_AC97_SDATA_OUT,
+ GPIO28_AC97_SYNC,
+
+ /* Keypad */
+ GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+ GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+ GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+ GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+ GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+ GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+ GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+ GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+ GPIO4_2_KP_MKOUT_5,
+
+ /* MMC1 */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD, /* CMD0 for slot 0 */
+
+ /* MMC2 */
+ GPIO9_MMC2_DAT0,
+ GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO11_MMC2_DAT2,
+ GPIO12_MMC2_DAT3,
+ GPIO13_MMC2_CLK,
+ GPIO14_MMC2_CMD,
+
+ /* FFUART */
+ GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
+ GPIO31_UART1_TXD,
+ GPIO32_UART1_CTS,
+ GPIO37_UART1_RTS,
+ GPIO33_UART1_DCD,
+ GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
+ GPIO35_UART1_RI,
+ GPIO36_UART1_DTR,
+
+ /* GPIOs */
+ GPIO82_GPIO | MFP_PULL_HIGH, /* MMC CD */
+ GPIO85_GPIO, /* MMC WP */
+ GPIO99_GPIO, /* Ethernet IRQ */
+
+ /* RTC GPIOs */
+ GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */
+ GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */
+ GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */
+ GPIO98_GPIO, /* RTC IO */
+
+ /* Standard I2C */
+ GPIO21_I2C_SCL,
+ GPIO22_I2C_SDA,
+
+ /* PWM Backlight */
+ GPIO19_PWM2_OUT,
+};
+
+static mfp_cfg_t cm_x3xx_rev_lt130_mfp_cfg[] __initdata = {
+ /* GPIOs */
+ GPIO79_GPIO, /* LED */
+ GPIO77_GPIO, /* WiFi reset */
+ GPIO78_GPIO, /* BT reset */
+};
+
+static mfp_cfg_t cm_x3xx_rev_ge130_mfp_cfg[] __initdata = {
+ /* GPIOs */
+ GPIO76_GPIO, /* LED */
+ GPIO71_GPIO, /* WiFi reset */
+ GPIO70_GPIO, /* BT reset */
+};
+
+static mfp_cfg_t cm_x310_mfp_cfg[] __initdata = {
+ /* USB PORT 2 */
+ ULPI_STP,
+ ULPI_NXT,
+ ULPI_DIR,
+ GPIO30_ULPI_DATA_OUT_0,
+ GPIO31_ULPI_DATA_OUT_1,
+ GPIO32_ULPI_DATA_OUT_2,
+ GPIO33_ULPI_DATA_OUT_3,
+ GPIO34_ULPI_DATA_OUT_4,
+ GPIO35_ULPI_DATA_OUT_5,
+ GPIO36_ULPI_DATA_OUT_6,
+ GPIO37_ULPI_DATA_OUT_7,
+ GPIO38_ULPI_CLK,
+ /* external PHY reset pin */
+ GPIO127_GPIO,
+
+ /* USB PORT 3 */
+ GPIO77_USB_P3_1,
+ GPIO78_USB_P3_2,
+ GPIO79_USB_P3_3,
+ GPIO80_USB_P3_4,
+ GPIO81_USB_P3_5,
+ GPIO82_USB_P3_6,
+ GPIO0_2_USBH_PEN,
+};
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+ [0] = {
+ .start = CM_X300_ETH_PHYS,
+ .end = CM_X300_ETH_PHYS + 0x3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CM_X300_ETH_PHYS + 0x4,
+ .end = CM_X300_ETH_PHYS + 0x4 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)),
+ .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO99)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data cm_x300_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+};
+
+static struct platform_device dm9000_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000_resources),
+ .resource = dm9000_resources,
+ .dev = {
+ .platform_data = &cm_x300_dm9000_platdata,
+ }
+
+};
+
+static void __init cm_x300_init_dm9000(void)
+{
+ platform_device_register(&dm9000_device);
+}
+#else
+static inline void cm_x300_init_dm9000(void) {}
+#endif
+
+/* LCD */
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info cm_x300_lcd_modes[] = {
+ [0] = {
+ .pixclock = 38250,
+ .bpp = 16,
+ .xres = 480,
+ .yres = 640,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 24,
+ .lower_margin = 4,
+ .cmap_greyscale = 0,
+ },
+ [1] = {
+ .pixclock = 153800,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 88,
+ .lower_margin = 2,
+ .cmap_greyscale = 0,
+ },
+};
+
+static struct pxafb_mach_info cm_x300_lcd = {
+ .modes = cm_x300_lcd_modes,
+ .num_modes = ARRAY_SIZE(cm_x300_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init cm_x300_init_lcd(void)
+{
+ pxa_set_fb_info(NULL, &cm_x300_lcd);
+}
+#else
+static inline void cm_x300_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct platform_pwm_backlight_data cm_x300_backlight_data = {
+ .pwm_id = 2,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 10000,
+};
+
+static struct platform_device cm_x300_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &cm_x300_backlight_data,
+ },
+};
+
+static void cm_x300_init_bl(void)
+{
+ platform_device_register(&cm_x300_backlight_device);
+}
+#else
+static inline void cm_x300_init_bl(void) {}
+#endif
+
+#if defined(CONFIG_SPI_GPIO) || defined(CONFIG_SPI_GPIO_MODULE)
+#define GPIO_LCD_BASE (144)
+#define GPIO_LCD_DIN (GPIO_LCD_BASE + 8) /* aux_gpio3_0 */
+#define GPIO_LCD_DOUT (GPIO_LCD_BASE + 9) /* aux_gpio3_1 */
+#define GPIO_LCD_SCL (GPIO_LCD_BASE + 10) /* aux_gpio3_2 */
+#define GPIO_LCD_CS (GPIO_LCD_BASE + 11) /* aux_gpio3_3 */
+#define LCD_SPI_BUS_NUM (1)
+
+static struct spi_gpio_platform_data cm_x300_spi_gpio_pdata = {
+ .sck = GPIO_LCD_SCL,
+ .mosi = GPIO_LCD_DIN,
+ .miso = GPIO_LCD_DOUT,
+ .num_chipselect = 1,
+};
+
+static struct platform_device cm_x300_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_SPI_BUS_NUM,
+ .dev = {
+ .platform_data = &cm_x300_spi_gpio_pdata,
+ },
+};
+
+static struct tdo24m_platform_data cm_x300_tdo24m_pdata = {
+ .model = TDO35S,
+};
+
+static struct spi_board_info cm_x300_spi_devices[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .max_speed_hz = 1000000,
+ .bus_num = LCD_SPI_BUS_NUM,
+ .chip_select = 0,
+ .controller_data = (void *) GPIO_LCD_CS,
+ .platform_data = &cm_x300_tdo24m_pdata,
+ },
+};
+
+static void __init cm_x300_init_spi(void)
+{
+ spi_register_board_info(cm_x300_spi_devices,
+ ARRAY_SIZE(cm_x300_spi_devices));
+ platform_device_register(&cm_x300_spi_gpio);
+}
+#else
+static inline void cm_x300_init_spi(void) {}
+#endif
+
+#if defined(CONFIG_SND_PXA2XX_LIB_AC97)
+static void __init cm_x300_init_ac97(void)
+{
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void cm_x300_init_ac97(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition cm_x300_nand_partitions[] = {
+ [0] = {
+ .name = "OBM",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [1] = {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [2] = {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ },
+ [3] = {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K + SZ_1M,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [4] = {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ },
+ [5] = {
+ .name = "fs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct pxa3xx_nand_platform_data cm_x300_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = cm_x300_nand_partitions,
+ .nr_parts = ARRAY_SIZE(cm_x300_nand_partitions),
+};
+
+static void __init cm_x300_init_nand(void)
+{
+ pxa3xx_set_nand_info(&cm_x300_nand_info);
+}
+#else
+static inline void cm_x300_init_nand(void) {}
+#endif
+
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+static struct pxamci_platform_data cm_x300_mci_platform_data = {
+ .detect_delay_ms = 200,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = GPIO82_MMC_IRQ,
+ .gpio_card_ro = GPIO85_MMC_WP,
+ .gpio_power = -1,
+};
+
+/* The second MMC slot of CM-X300 is hardwired to Libertas card and has
+ no detection/ro pins */
+static int cm_x300_mci2_init(struct device *dev,
+ irq_handler_t cm_x300_detect_int,
+ void *data)
+{
+ return 0;
+}
+
+static void cm_x300_mci2_exit(struct device *dev, void *data)
+{
+}
+
+static struct pxamci_platform_data cm_x300_mci2_platform_data = {
+ .detect_delay_ms = 200,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = cm_x300_mci2_init,
+ .exit = cm_x300_mci2_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void __init cm_x300_init_mmc(void)
+{
+ pxa_set_mci_info(&cm_x300_mci_platform_data);
+ pxa3xx_set_mci2_info(&cm_x300_mci2_platform_data);
+}
+#else
+static inline void cm_x300_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_PXA310_ULPI)
+static struct clk *pout_clk;
+
+static int cm_x300_ulpi_phy_reset(void)
+{
+ int err;
+
+ /* reset the PHY */
+ err = gpio_request(GPIO_ULPI_PHY_RST, "ulpi reset");
+ if (err) {
+ pr_err("%s: failed to request ULPI reset GPIO: %d\n",
+ __func__, err);
+ return err;
+ }
+
+ gpio_direction_output(GPIO_ULPI_PHY_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO_ULPI_PHY_RST, 1);
+ msleep(10);
+
+ gpio_free(GPIO_ULPI_PHY_RST);
+
+ return 0;
+}
+
+static inline int cm_x300_u2d_init(struct device *dev)
+{
+ int err = 0;
+
+ if (cpu_is_pxa310()) {
+ /* CLK_POUT is connected to the ULPI PHY */
+ pout_clk = clk_get(NULL, "CLK_POUT");
+ if (IS_ERR(pout_clk)) {
+ err = PTR_ERR(pout_clk);
+ pr_err("%s: failed to get CLK_POUT: %d\n",
+ __func__, err);
+ return err;
+ }
+ clk_enable(pout_clk);
+
+ err = cm_x300_ulpi_phy_reset();
+ if (err) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+ }
+
+ return err;
+}
+
+static void cm_x300_u2d_exit(struct device *dev)
+{
+ if (cpu_is_pxa310()) {
+ clk_disable(pout_clk);
+ clk_put(pout_clk);
+ }
+}
+
+static struct pxa3xx_u2d_platform_data cm_x300_u2d_platform_data = {
+ .ulpi_mode = ULPI_SER_6PIN,
+ .init = cm_x300_u2d_init,
+ .exit = cm_x300_u2d_exit,
+};
+
+static void cm_x300_init_u2d(void)
+{
+ pxa3xx_set_u2d_info(&cm_x300_u2d_platform_data);
+}
+#else
+static inline void cm_x300_init_u2d(void) {}
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int cm_x300_ohci_init(struct device *dev)
+{
+ if (cpu_is_pxa300())
+ UP2OCR = UP2OCR_HXS
+ | UP2OCR_HXOE | UP2OCR_DMPDE | UP2OCR_DPPDE;
+
+ return 0;
+}
+
+static struct pxaohci_platform_data cm_x300_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW,
+ .init = cm_x300_ohci_init,
+};
+
+static void __init cm_x300_init_ohci(void)
+{
+ pxa_set_ohci_info(&cm_x300_ohci_platform_data);
+}
+#else
+static inline void cm_x300_init_ohci(void) {}
+#endif
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led cm_x300_leds[] = {
+ [0] = {
+ .name = "cm-x300:green",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data cm_x300_gpio_led_pdata = {
+ .num_leds = ARRAY_SIZE(cm_x300_leds),
+ .leds = cm_x300_leds,
+};
+
+static struct platform_device cm_x300_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_x300_gpio_led_pdata,
+ },
+};
+
+static void __init cm_x300_init_leds(void)
+{
+ if (system_rev < 130)
+ cm_x300_leds[0].gpio = 79;
+ else
+ cm_x300_leds[0].gpio = 76;
+
+ platform_device_register(&cm_x300_led_device);
+}
+#else
+static inline void cm_x300_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+/* PCA9555 */
+static struct pca953x_platform_data cm_x300_gpio_ext_pdata_0 = {
+ .gpio_base = 128,
+};
+
+static struct pca953x_platform_data cm_x300_gpio_ext_pdata_1 = {
+ .gpio_base = 144,
+};
+
+static struct i2c_board_info cm_x300_gpio_ext_info[] = {
+ [0] = {
+ I2C_BOARD_INFO("pca9555", 0x24),
+ .platform_data = &cm_x300_gpio_ext_pdata_0,
+ },
+ [1] = {
+ I2C_BOARD_INFO("pca9555", 0x25),
+ .platform_data = &cm_x300_gpio_ext_pdata_1,
+ },
+};
+
+static void __init cm_x300_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, cm_x300_gpio_ext_info,
+ ARRAY_SIZE(cm_x300_gpio_ext_info));
+}
+#else
+static inline void cm_x300_init_i2c(void) {}
+#endif
+
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+struct v3020_platform_data cm_x300_v3020_pdata = {
+ .use_gpio = 1,
+ .gpio_cs = GPIO95_RTC_CS,
+ .gpio_wr = GPIO96_RTC_WR,
+ .gpio_rd = GPIO97_RTC_RD,
+ .gpio_io = GPIO98_RTC_IO,
+};
+
+static struct platform_device cm_x300_rtc_device = {
+ .name = "v3020",
+ .id = -1,
+ .dev = {
+ .platform_data = &cm_x300_v3020_pdata,
+ }
+};
+
+static void __init cm_x300_init_rtc(void)
+{
+ platform_device_register(&cm_x300_rtc_device);
+}
+#else
+static inline void cm_x300_init_rtc(void) {}
+#endif
+
+/* Battery */
+struct power_supply_info cm_x300_psy_info = {
+ .name = "battery",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .voltage_max_design = 4200000,
+ .voltage_min_design = 3000000,
+ .use_for_apm = 1,
+};
+
+static void cm_x300_battery_low(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+ apm_queue_event(APM_LOW_BATTERY);
+#endif
+}
+
+static void cm_x300_battery_critical(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+#endif
+}
+
+struct da9030_battery_info cm_x300_battery_info = {
+ .battery_info = &cm_x300_psy_info,
+
+ .charge_milliamp = 1000,
+ .charge_millivolt = 4200,
+
+ .vbat_low = 3600,
+ .vbat_crit = 3400,
+ .vbat_charge_start = 4100,
+ .vbat_charge_stop = 4200,
+ .vbat_charge_restart = 4000,
+
+ .vcharge_min = 3200,
+ .vcharge_max = 5500,
+
+ .tbat_low = 197,
+ .tbat_high = 78,
+ .tbat_restart = 100,
+
+ .batmon_interval = 0,
+
+ .battery_low = cm_x300_battery_low,
+ .battery_critical = cm_x300_battery_critical,
+};
+
+static struct regulator_consumer_supply buck2_consumers[] = {
+ {
+ .dev = NULL,
+ .supply = "vcc_core",
+ },
+};
+
+static struct regulator_init_data buck2_data = {
+ .constraints = {
+ .min_uV = 1375000,
+ .max_uV = 1375000,
+ .state_mem = {
+ .enabled = 0,
+ },
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ .apply_uV = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_consumers),
+ .consumer_supplies = buck2_consumers,
+};
+
+/* DA9030 */
+struct da903x_subdev_info cm_x300_da9030_subdevs[] = {
+ {
+ .name = "da903x-battery",
+ .id = DA9030_ID_BAT,
+ .platform_data = &cm_x300_battery_info,
+ },
+ {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_BUCK2,
+ .platform_data = &buck2_data,
+ },
+};
+
+static struct da903x_platform_data cm_x300_da9030_info = {
+ .num_subdevs = ARRAY_SIZE(cm_x300_da9030_subdevs),
+ .subdevs = cm_x300_da9030_subdevs,
+};
+
+static struct i2c_board_info cm_x300_pmic_info = {
+ I2C_BOARD_INFO("da9030", 0x49),
+ .irq = IRQ_WAKEUP0,
+ .platform_data = &cm_x300_da9030_info,
+};
+
+static struct i2c_pxa_platform_data cm_x300_pwr_i2c_info = {
+ .use_pio = 1,
+};
+
+static void __init cm_x300_init_da9030(void)
+{
+ pxa3xx_set_i2c_power_info(&cm_x300_pwr_i2c_info);
+ i2c_register_board_info(1, &cm_x300_pmic_info, 1);
+ irq_set_irq_wake(IRQ_WAKEUP0, 1);
+}
+
+static void __init cm_x300_init_wi2wi(void)
+{
+ int bt_reset, wlan_en;
+ int err;
+
+ if (system_rev < 130) {
+ wlan_en = 77;
+ bt_reset = 78;
+ } else {
+ wlan_en = 71;
+ bt_reset = 70;
+ }
+
+ /* Libertas and CSR reset */
+ err = gpio_request(wlan_en, "wlan en");
+ if (err) {
+ pr_err("CM-X300: failed to request wlan en gpio: %d\n", err);
+ } else {
+ gpio_direction_output(wlan_en, 1);
+ gpio_free(wlan_en);
+ }
+
+ err = gpio_request(bt_reset, "bt reset");
+ if (err) {
+ pr_err("CM-X300: failed to request bt reset gpio: %d\n", err);
+ } else {
+ gpio_direction_output(bt_reset, 1);
+ udelay(10);
+ gpio_set_value(bt_reset, 0);
+ udelay(10);
+ gpio_set_value(bt_reset, 1);
+ gpio_free(bt_reset);
+ }
+}
+
+/* MFP */
+static void __init cm_x300_init_mfp(void)
+{
+ /* board-processor specific GPIO initialization */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_mfp_cfg));
+
+ if (system_rev < 130)
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_lt130_mfp_cfg));
+ else
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x3xx_rev_ge130_mfp_cfg));
+
+ if (cpu_is_pxa310())
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(cm_x310_mfp_cfg));
+}
+
+static void __init cm_x300_init(void)
+{
+ cm_x300_init_mfp();
+
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ if (cpu_is_pxa300())
+ pxa_set_ffuart_info(NULL);
+
+ cm_x300_init_da9030();
+ cm_x300_init_dm9000();
+ cm_x300_init_lcd();
+ cm_x300_init_u2d();
+ cm_x300_init_ohci();
+ cm_x300_init_mmc();
+ cm_x300_init_nand();
+ cm_x300_init_leds();
+ cm_x300_init_i2c();
+ cm_x300_init_spi();
+ cm_x300_init_rtc();
+ cm_x300_init_ac97();
+ cm_x300_init_wi2wi();
+ cm_x300_init_bl();
+}
+
+static void __init cm_x300_fixup(struct machine_desc *mdesc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ /* Make sure that mi->bank[0].start = PHYS_ADDR */
+ for (; tags->hdr.size; tags = tag_next(tags))
+ if (tags->hdr.tag == ATAG_MEM &&
+ tags->u.mem.start == 0x80000000) {
+ tags->u.mem.start = 0xa0000000;
+ break;
+ }
+}
+
+MACHINE_START(CM_X300, "CM-X300 module")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = cm_x300_init,
+ .fixup = cm_x300_fixup,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/colibri-evalboard.c b/arch/arm/mach-pxa/colibri-evalboard.c
new file mode 100644
index 00000000..d28e802e
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-evalboard.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-pxa/colibri-evalboard.c
+ *
+ * Support for Toradex Colibri Evaluation Carrier Board
+ * Daniel Mack <daniel@caiaq.de>
+ * Marek Vasut <marek.vasut@gmail.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/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/mach/arch.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <mach/pxa27x.h>
+#include <mach/colibri.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa27x-udc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data colibri_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_power = -1,
+ .gpio_card_ro = -1,
+ .detect_delay_ms = 200,
+};
+
+static void __init colibri_mmc_init(void)
+{
+ if (machine_is_colibri()) /* PXA270 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO0_COLIBRI_PXA270_SD_DETECT;
+ if (machine_is_colibri300()) /* PXA300 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO13_COLIBRI_PXA300_SD_DETECT;
+ else /* PXA320 Colibri */
+ colibri_mci_platform_data.gpio_card_detect =
+ GPIO28_COLIBRI_PXA320_SD_DETECT;
+
+ pxa_set_mci_info(&colibri_mci_platform_data);
+}
+#else
+static inline void colibri_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int colibri_ohci_init(struct device *dev)
+{
+ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+ return 0;
+}
+
+static struct pxaohci_platform_data colibri_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 |
+ POWER_CONTROL_LOW | POWER_SENSE_LOW,
+ .init = colibri_ohci_init,
+};
+
+static void __init colibri_uhc_init(void)
+{
+ /* Colibri PXA270 has two usb ports, TBA for 320 */
+ if (machine_is_colibri())
+ colibri_ohci_info.flags |= ENABLE_PORT2;
+
+ pxa_set_ohci_info(&colibri_ohci_info);
+}
+#else
+static inline void colibri_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * I2C RTC
+ ******************************************************************************/
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+static struct i2c_board_info __initdata colibri_i2c_devs[] = {
+ {
+ I2C_BOARD_INFO("m41t00", 0x68),
+ },
+};
+
+static void __init colibri_rtc_init(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(colibri_i2c_devs));
+}
+#else
+static inline void colibri_rtc_init(void) {}
+#endif
+
+void __init colibri_evalboard_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ colibri_mmc_init();
+ colibri_uhc_init();
+ colibri_rtc_init();
+}
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c
new file mode 100644
index 00000000..80538b88
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa270-income.c
@@ -0,0 +1,223 @@
+/*
+ * linux/arch/arm/mach-pxa/income.c
+ *
+ * Support for Income s.r.o. SH-Dmaster PXA270 SBC
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.com>
+ * Pavel Revak <palo@bielyvlk.sk>
+ *
+ * This program is free software; you can 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/bitops.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/pxafb.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define GPIO114_INCOME_ETH_IRQ (114)
+#define GPIO0_INCOME_SD_DETECT (0)
+#define GPIO0_INCOME_SD_RO (1)
+#define GPIO54_INCOME_LED_A (54)
+#define GPIO55_INCOME_LED_B (55)
+#define GPIO113_INCOME_TS_IRQ (113)
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data income_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_power = -1,
+ .gpio_card_detect = GPIO0_INCOME_SD_DETECT,
+ .gpio_card_ro = GPIO0_INCOME_SD_RO,
+ .detect_delay_ms = 200,
+};
+
+static void __init income_mmc_init(void)
+{
+ pxa_set_mci_info(&income_mci_platform_data);
+}
+#else
+static inline void income_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data income_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static void __init income_uhc_init(void)
+{
+ pxa_set_ohci_info(&income_ohci_info);
+}
+#else
+static inline void income_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LED
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led income_gpio_leds[] = {
+ {
+ .name = "income:green:leda",
+ .default_trigger = "none",
+ .gpio = GPIO54_INCOME_LED_A,
+ .active_low = 1,
+ },
+ {
+ .name = "income:green:ledb",
+ .default_trigger = "none",
+ .gpio = GPIO55_INCOME_LED_B,
+ .active_low = 1,
+ }
+};
+
+static struct gpio_led_platform_data income_gpio_led_info = {
+ .leds = income_gpio_leds,
+ .num_leds = ARRAY_SIZE(income_gpio_leds),
+};
+
+static struct platform_device income_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &income_gpio_led_info,
+ }
+};
+
+static void __init income_led_init(void)
+{
+ platform_device_register(&income_leds);
+}
+#else
+static inline void income_led_init(void) {}
+#endif
+
+/******************************************************************************
+ * I2C
+ ******************************************************************************/
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct i2c_board_info __initdata income_i2c_devs[] = {
+ {
+ I2C_BOARD_INFO("ds1340", 0x68),
+ }, {
+ I2C_BOARD_INFO("lm75", 0x4f),
+ },
+};
+
+static void __init income_i2c_init(void)
+{
+ pxa_set_i2c_info(NULL);
+ pxa27x_set_i2c_power_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(income_i2c_devs));
+}
+#else
+static inline void income_i2c_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info income_lcd_modes[] = {
+{
+ .pixclock = 144700,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 32,
+ .depth = 18,
+
+ .left_margin = 10,
+ .right_margin = 10,
+ .upper_margin = 7,
+ .lower_margin = 8,
+
+ .hsync_len = 20,
+ .vsync_len = 2,
+
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+},
+};
+
+static struct pxafb_mach_info income_lcd_screen = {
+ .modes = income_lcd_modes,
+ .num_modes = ARRAY_SIZE(income_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_18BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init income_lcd_init(void)
+{
+ pxa_set_fb_info(NULL, &income_lcd_screen);
+}
+#else
+static inline void income_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM__MODULE)
+static struct platform_pwm_backlight_data income_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 0x3ff,
+ .dft_brightness = 0x1ff,
+ .pwm_period_ns = 1000000,
+};
+
+static struct platform_device income_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &income_backlight_data,
+ },
+};
+
+static void __init income_pwm_init(void)
+{
+ platform_device_register(&income_backlight);
+}
+#else
+static inline void income_pwm_init(void) {}
+#endif
+
+void __init colibri_pxa270_income_boardinit(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ income_mmc_init();
+ income_uhc_init();
+ income_led_init();
+ income_i2c_init();
+ income_lcd_init();
+ income_pwm_init();
+}
+
diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c
new file mode 100644
index 00000000..7545a48e
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa270.c
@@ -0,0 +1,323 @@
+/*
+ * linux/arch/arm/mach-pxa/colibri-pxa270.c
+ *
+ * Support for Toradex PXA270 based Colibri module
+ * Daniel Mack <daniel@caiaq.de>
+ * Marek Vasut <marek.vasut@gmail.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/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/platform_device.h>
+#include <linux/ucb1400.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+
+#include <mach/audio.h>
+#include <mach/colibri.h>
+#include <mach/pxa27x.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/******************************************************************************
+ * Evaluation board MFP
+ ******************************************************************************/
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO0_GPIO, /* SD detect */
+
+ /* FFUART */
+ GPIO39_FFUART_TXD,
+ GPIO34_FFUART_RXD,
+
+ /* UHC */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+ GPIO119_USBH2_PWR,
+ GPIO120_USBH2_PEN,
+
+ /* PCMCIA */
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO49_nPWE,
+ GPIO48_nPOE,
+ GPIO57_nIOIS16,
+ GPIO56_nPWAIT,
+ GPIO104_PSKTSEL,
+ GPIO53_GPIO, /* RESET */
+ GPIO83_GPIO, /* BVD1 */
+ GPIO82_GPIO, /* BVD2 */
+ GPIO1_GPIO, /* READY */
+ GPIO84_GPIO, /* DETECT */
+ GPIO107_GPIO, /* PPEN */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+#else
+static mfp_cfg_t colibri_pxa270_evalboard_pin_config[] __initdata = {};
+#endif
+
+#ifdef CONFIG_MACH_COLIBRI_PXA270_INCOME
+static mfp_cfg_t income_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO0_GPIO, /* SD detect */
+ GPIO1_GPIO, /* SD read-only */
+
+ /* FFUART */
+ GPIO39_FFUART_TXD,
+ GPIO34_FFUART_RXD,
+
+ /* BFUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* UHC */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* LED */
+ GPIO54_GPIO, /* LED A */
+ GPIO55_GPIO, /* LED B */
+};
+#else
+static mfp_cfg_t income_pin_config[] __initdata = {};
+#endif
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static mfp_cfg_t colibri_pxa270_pin_config[] __initdata = {
+ /* Ethernet */
+ GPIO78_nCS_2, /* Ethernet CS */
+ GPIO114_GPIO, /* Ethernet IRQ */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO95_AC97_nRESET,
+ GPIO98_AC97_SYSCLK,
+ GPIO113_GPIO, /* Touchscreen IRQ */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition colibri_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Kernel",
+ .offset = 0x00040000,
+ .size = 0x00400000,
+ .mask_flags = 0
+ }, {
+ .name = "Rootfs",
+ .offset = 0x00440000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data colibri_flash_data[] = {
+ {
+ .width = 4, /* bankwidth in bytes */
+ .parts = colibri_partitions,
+ .nr_parts = ARRAY_SIZE(colibri_partitions)
+ }
+};
+
+static struct resource colibri_pxa270_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device colibri_pxa270_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = colibri_flash_data,
+ },
+ .resource = &colibri_pxa270_flash_resource,
+ .num_resources = 1,
+};
+
+static void __init colibri_pxa270_nor_init(void)
+{
+ platform_device_register(&colibri_pxa270_flash_device);
+}
+#else
+static inline void colibri_pxa270_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Ethernet
+ ******************************************************************************/
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource colibri_pxa270_dm9000_resources[] = {
+ {
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PXA_CS2_PHYS + 4,
+ .end = PXA_CS2_PHYS + 4 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ),
+ .end = gpio_to_irq(GPIO114_COLIBRI_PXA270_ETH_IRQ),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING,
+ },
+};
+
+static struct platform_device colibri_pxa270_dm9000_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(colibri_pxa270_dm9000_resources),
+ .resource = colibri_pxa270_dm9000_resources,
+};
+
+static void __init colibri_pxa270_eth_init(void)
+{
+ platform_device_register(&colibri_pxa270_dm9000_device);
+}
+#else
+static inline void colibri_pxa270_eth_init(void) {}
+#endif
+
+/******************************************************************************
+ * Audio and Touchscreen
+ ******************************************************************************/
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static pxa2xx_audio_ops_t colibri_pxa270_ac97_pdata = {
+ .reset_gpio = 95,
+};
+
+static struct ucb1400_pdata colibri_pxa270_ucb1400_pdata = {
+ .irq = gpio_to_irq(GPIO113_COLIBRI_PXA270_TS_IRQ),
+};
+
+static struct platform_device colibri_pxa270_ucb1400_device = {
+ .name = "ucb1400_core",
+ .id = -1,
+ .dev = {
+ .platform_data = &colibri_pxa270_ucb1400_pdata,
+ },
+};
+
+static void __init colibri_pxa270_tsc_init(void)
+{
+ pxa_set_ac97_info(&colibri_pxa270_ac97_pdata);
+ platform_device_register(&colibri_pxa270_ucb1400_device);
+}
+#else
+static inline void colibri_pxa270_tsc_init(void) {}
+#endif
+
+static int colibri_pxa270_baseboard;
+core_param(colibri_pxa270_baseboard, colibri_pxa270_baseboard, int, 0444);
+
+static void __init colibri_pxa270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa270_pin_config));
+
+ colibri_pxa270_nor_init();
+ colibri_pxa270_eth_init();
+ colibri_pxa270_tsc_init();
+
+ switch (colibri_pxa270_baseboard) {
+ case COLIBRI_EVALBOARD:
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(
+ colibri_pxa270_evalboard_pin_config));
+ colibri_evalboard_init();
+ break;
+ case COLIBRI_PXA270_INCOME:
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(income_pin_config));
+ colibri_pxa270_income_boardinit();
+ break;
+ default:
+ printk(KERN_ERR "Illegal colibri_pxa270_baseboard type %d\n",
+ colibri_pxa270_baseboard);
+ }
+}
+
+/* The "Income s.r.o. SH-Dmaster PXA270 SBC" board can be booted either
+ * with the INCOME mach type or with COLIBRI and the kernel parameter
+ * "colibri_pxa270_baseboard=1"
+ */
+static void __init colibri_pxa270_income_init(void)
+{
+ colibri_pxa270_baseboard = COLIBRI_PXA270_INCOME;
+ colibri_pxa270_init();
+}
+
+MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
+ .boot_params = COLIBRI_SDRAM_BASE + 0x100,
+ .init_machine = colibri_pxa270_init,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
+MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
+ .boot_params = 0xa0000100,
+ .init_machine = colibri_pxa270_income_init,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c
new file mode 100644
index 00000000..66dd81cb
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa300.c
@@ -0,0 +1,192 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa300.c
+ *
+ * Support for Toradex PXA300/310 based Colibri module
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ * Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa300.h>
+#include <mach/colibri.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+#include <mach/audio.h>
+
+#include "generic.h"
+#include "devices.h"
+
+
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO7_MMC1_CLK,
+ GPIO14_MMC1_CMD,
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO13_GPIO, /* GPIO13_COLIBRI_PXA300_SD_DETECT */
+
+ /* UHC */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+ GPIO77_USB_P3_1,
+ GPIO78_USB_P3_2,
+ GPIO79_USB_P3_3,
+ GPIO80_USB_P3_4,
+ GPIO81_USB_P3_5,
+ GPIO82_USB_P3_6,
+
+ /* I2C */
+ GPIO21_I2C_SCL,
+ GPIO22_I2C_SDA,
+};
+#else
+static mfp_cfg_t colibri_pxa300_evalboard_pin_config[] __initdata = {};
+#endif
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO26_GPIO)
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+ .flags = 0, /* defined later */
+ .wordlength = 2,
+};
+
+static struct resource colibri_asix_resource[] = {
+ [0] = {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct platform_device asix_device = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(colibri_asix_resource),
+ .resource = colibri_asix_resource,
+ .dev = {
+ .platform_data = &colibri_asix_platdata
+ }
+};
+
+static mfp_cfg_t colibri_pxa300_eth_pin_config[] __initdata = {
+ GPIO1_nCS2, /* AX88796 chip select */
+ GPIO26_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */
+};
+
+static void __init colibri_pxa300_init_eth(void)
+{
+ colibri_pxa3xx_init_eth(&colibri_asix_platdata);
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_eth_pin_config));
+ platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa300_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa300_lcd_pin_config[] __initdata = {
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO62_LCD_CS_N,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+ GPIO76_LCD_VSYNC,
+};
+
+static void __init colibri_pxa300_init_lcd(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_lcd_pin_config));
+}
+
+#else
+static inline void colibri_pxa300_init_lcd(void) {}
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
+
+#if defined(CONFIG_SND_AC97_CODEC) || defined(CONFIG_SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa310_ac97_pin_config[] __initdata = {
+ GPIO24_AC97_SYSCLK,
+ GPIO23_AC97_nACRESET,
+ GPIO25_AC97_SDATA_IN_0,
+ GPIO27_AC97_SDATA_OUT,
+ GPIO28_AC97_SYNC,
+ GPIO29_AC97_BITCLK
+};
+
+static inline void __init colibri_pxa310_init_ac97(void)
+{
+ /* no AC97 codec on Colibri PXA300 */
+ if (!cpu_is_pxa310())
+ return;
+
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa310_ac97_pin_config));
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa310_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa300_init(void)
+{
+ colibri_pxa300_init_eth();
+ colibri_pxa3xx_init_nand();
+ colibri_pxa300_init_lcd();
+ colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO39_GPIO));
+ colibri_pxa310_init_ac97();
+
+ /* Evalboard init */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa300_evalboard_pin_config));
+ colibri_evalboard_init();
+}
+
+MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
+ .boot_params = COLIBRI_SDRAM_BASE + 0x100,
+ .init_machine = colibri_pxa300_init,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c
new file mode 100644
index 00000000..fdf611cd
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa320.c
@@ -0,0 +1,263 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa320.c
+ *
+ * Support for Toradex PXA320/310 based Colibri module
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ * Matthias Meier <matthias.j.meier@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+#include <mach/colibri.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/audio.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#ifdef CONFIG_MACH_COLIBRI_EVALBOARD
+static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {
+ /* MMC */
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO28_GPIO, /* SD detect */
+
+ /* UART 1 configuration (may be set by bootloader) */
+ GPIO99_UART1_CTS,
+ GPIO104_UART1_RTS,
+ GPIO97_UART1_RXD,
+ GPIO98_UART1_TXD,
+ GPIO101_UART1_DTR,
+ GPIO103_UART1_DSR,
+ GPIO100_UART1_DCD,
+ GPIO102_UART1_RI,
+
+ /* UART 2 configuration */
+ GPIO109_UART2_CTS,
+ GPIO112_UART2_RTS,
+ GPIO110_UART2_RXD,
+ GPIO111_UART2_TXD,
+
+ /* UART 3 configuration */
+ GPIO30_UART3_RXD,
+ GPIO31_UART3_TXD,
+
+ /* UHC */
+ GPIO2_2_USBH_PEN,
+ GPIO3_2_USBH_PWR,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* PCMCIA */
+ MFP_CFG(GPIO59, AF7), /* PRST ; AF7 to tristate */
+ MFP_CFG(GPIO61, AF7), /* PCE1 ; AF7 to tristate */
+ MFP_CFG(GPIO60, AF7), /* PCE2 ; AF7 to tristate */
+ MFP_CFG(GPIO62, AF7), /* PCD ; AF7 to tristate */
+ MFP_CFG(GPIO56, AF7), /* PSKTSEL ; AF7 to tristate */
+ GPIO27_GPIO, /* RDnWR ; input/tristate */
+ GPIO50_GPIO, /* PREG ; input/tristate */
+ GPIO2_RDY,
+ GPIO5_NPIOR,
+ GPIO6_NPIOW,
+ GPIO7_NPIOS16,
+ GPIO8_NPWAIT,
+ GPIO29_GPIO, /* PRDY (READY GPIO) */
+ GPIO57_GPIO, /* PPEN (POWER GPIO) */
+ GPIO81_GPIO, /* PCD (DETECT GPIO) */
+ GPIO77_GPIO, /* PRST (RESET GPIO) */
+ GPIO53_GPIO, /* PBVD1 */
+ GPIO79_GPIO, /* PBVD2 */
+ GPIO54_GPIO, /* POE */
+};
+#else
+static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {};
+#endif
+
+#if defined(CONFIG_AX88796)
+#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO)
+/*
+ * Asix AX88796 Ethernet
+ */
+static struct ax_plat_data colibri_asix_platdata = {
+ .flags = 0, /* defined later */
+ .wordlength = 2,
+};
+
+static struct resource colibri_asix_resource[] = {
+ [0] = {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct platform_device asix_device = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(colibri_asix_resource),
+ .resource = colibri_asix_resource,
+ .dev = {
+ .platform_data = &colibri_asix_platdata
+ }
+};
+
+static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = {
+ GPIO3_nCS2, /* AX88796 chip select */
+ GPIO36_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */
+};
+
+static void __init colibri_pxa320_init_eth(void)
+{
+ colibri_pxa3xx_init_eth(&colibri_asix_platdata);
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config));
+ platform_device_register(&asix_device);
+}
+#else
+static inline void __init colibri_pxa320_init_eth(void) {}
+#endif /* CONFIG_AX88796 */
+
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
+static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = {
+ .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96),
+ .gpio_pullup = -1,
+};
+
+static struct platform_device colibri_pxa320_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &colibri_pxa320_gpio_vbus_info,
+ },
+};
+
+static void colibri_pxa320_udc_command(int cmd)
+{
+ if (cmd == PXA2XX_UDC_CMD_CONNECT)
+ UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+ else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+ UP2OCR = UP2OCR_HXOE;
+}
+
+static struct pxa2xx_udc_mach_info colibri_pxa320_udc_info __initdata = {
+ .udc_command = colibri_pxa320_udc_command,
+ .gpio_pullup = -1,
+};
+
+static void __init colibri_pxa320_init_udc(void)
+{
+ pxa_set_udc_info(&colibri_pxa320_udc_info);
+ platform_device_register(&colibri_pxa320_gpio_vbus);
+}
+#else
+static inline void colibri_pxa320_init_udc(void) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = {
+ GPIO6_2_LCD_LDD_0,
+ GPIO7_2_LCD_LDD_1,
+ GPIO8_2_LCD_LDD_2,
+ GPIO9_2_LCD_LDD_3,
+ GPIO10_2_LCD_LDD_4,
+ GPIO11_2_LCD_LDD_5,
+ GPIO12_2_LCD_LDD_6,
+ GPIO13_2_LCD_LDD_7,
+ GPIO63_LCD_LDD_8,
+ GPIO64_LCD_LDD_9,
+ GPIO65_LCD_LDD_10,
+ GPIO66_LCD_LDD_11,
+ GPIO67_LCD_LDD_12,
+ GPIO68_LCD_LDD_13,
+ GPIO69_LCD_LDD_14,
+ GPIO70_LCD_LDD_15,
+ GPIO71_LCD_LDD_16,
+ GPIO72_LCD_LDD_17,
+ GPIO73_LCD_CS_N,
+ GPIO74_LCD_VSYNC,
+ GPIO14_2_LCD_FCLK,
+ GPIO15_2_LCD_LCLK,
+ GPIO16_2_LCD_PCLK,
+ GPIO17_2_LCD_BIAS,
+};
+
+static void __init colibri_pxa320_init_lcd(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config));
+}
+#else
+static inline void colibri_pxa320_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_SND_AC97_CODEC) || \
+ defined(CONFIG_SND_AC97_CODEC_MODULE)
+static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = {
+ GPIO34_AC97_SYSCLK,
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET
+};
+
+static inline void __init colibri_pxa320_init_ac97(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config));
+ pxa_set_ac97_info(NULL);
+}
+#else
+static inline void colibri_pxa320_init_ac97(void) {}
+#endif
+
+void __init colibri_pxa320_init(void)
+{
+ colibri_pxa320_init_eth();
+ colibri_pxa3xx_init_nand();
+ colibri_pxa320_init_lcd();
+ colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO));
+ colibri_pxa320_init_ac97();
+ colibri_pxa320_init_udc();
+
+ /* Evalboard init */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_evalboard_pin_config));
+ colibri_evalboard_init();
+}
+
+MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
+ .boot_params = COLIBRI_SDRAM_BASE + 0x100,
+ .init_machine = colibri_pxa320_init,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
new file mode 100644
index 00000000..3f9be419
--- /dev/null
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -0,0 +1,151 @@
+/*
+ * arch/arm/mach-pxa/colibri-pxa3xx.c
+ *
+ * Common functions for all Toradex PXA3xx modules
+ *
+ * Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/colibri.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "generic.h"
+#include "devices.h"
+
+#if defined(CONFIG_AX88796)
+#define ETHER_ADDR_LEN 6
+static u8 ether_mac_addr[ETHER_ADDR_LEN];
+
+void __init colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data)
+{
+ int i;
+ u64 serial = ((u64) system_serial_high << 32) | system_serial_low;
+
+ /*
+ * If the bootloader passed in a serial boot tag, which contains a
+ * valid ethernet MAC, pass it to the interface. Toradex ships the
+ * modules with their own bootloader which provides a valid MAC
+ * this way.
+ */
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ ether_mac_addr[i] = serial & 0xff;
+ serial >>= 8;
+ }
+
+ if (is_valid_ether_addr(ether_mac_addr)) {
+ plat_data->flags |= AXFLG_MAC_FROMPLATFORM;
+ plat_data->mac_addr = ether_mac_addr;
+ printk(KERN_INFO "%s(): taking MAC from serial boot tag\n",
+ __func__);
+ } else {
+ plat_data->flags |= AXFLG_MAC_FROMDEV;
+ printk(KERN_INFO "%s(): no valid serial boot tag found, "
+ "taking MAC from device\n", __func__);
+ }
+}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static int lcd_bl_pin;
+
+/*
+ * LCD panel (Sharp LQ043T3DX02)
+ */
+static void colibri_lcd_backlight(int on)
+{
+ gpio_set_value(lcd_bl_pin, !!on);
+}
+
+static struct pxafb_mode_info sharp_lq43_mode = {
+ .pixclock = 101936,
+ .xres = 480,
+ .yres = 272,
+ .bpp = 32,
+ .depth = 18,
+ .hsync_len = 41,
+ .left_margin = 2,
+ .right_margin = 2,
+ .vsync_len = 10,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lq43_info = {
+ .modes = &sharp_lq43_mode,
+ .num_modes = 1,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .lcd_conn = LCD_COLOR_TFT_18BPP,
+ .pxafb_backlight_power = colibri_lcd_backlight,
+};
+
+void __init colibri_pxa3xx_init_lcd(int bl_pin)
+{
+ lcd_bl_pin = bl_pin;
+ gpio_request(bl_pin, "lcd backlight");
+ gpio_direction_output(bl_pin, 0);
+ pxa_set_fb_info(NULL, &sharp_lq43_info);
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition colibri_nand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_512K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "fs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct pxa3xx_nand_platform_data colibri_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = colibri_nand_partitions,
+ .nr_parts = ARRAY_SIZE(colibri_nand_partitions),
+};
+
+void __init colibri_pxa3xx_init_nand(void)
+{
+ pxa3xx_set_nand_info(&colibri_nand_info);
+}
+#endif
+
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
new file mode 100644
index 00000000..3a5507e3
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi.c
@@ -0,0 +1,749 @@
+/*
+ * Support for Sharp SL-C7xx PDAs
+ * Models: SL-C700 (Corgi), SL-C750 (Shepherd), SL-C760 (Husky)
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/mmc/host.h>
+#include <linux/mtd/physmap.h>
+#include <linux/pm.h>
+#include <linux/gpio.h>
+#include <linux/backlight.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/corgi_lcd.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mtd/sharpsl.h>
+#include <linux/input/matrix_keypad.h>
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa25x.h>
+#include <mach/irda.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/corgi.h>
+#include <mach/sharpsl_pm.h>
+
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/scoop.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long corgi_pin_config[] __initdata = {
+ /* Static Memory I/O */
+ GPIO78_nCS_2, /* w100fb */
+ GPIO80_nCS_4, /* scoop */
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+ GPIO24_GPIO, /* CORGI_GPIO_ADS7846_CS - SFRM as chip select */
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO32_I2S_SYSCLK,
+
+ /* Infra-Red */
+ GPIO47_FICP_TXD,
+ GPIO46_FICP_RXD,
+
+ /* FFUART */
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+ GPIO39_FFUART_TXD,
+ GPIO37_FFUART_DSR,
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+
+ /* GPIO Matrix Keypad */
+ GPIO66_GPIO | MFP_LPM_DRIVE_HIGH, /* column 0 */
+ GPIO67_GPIO | MFP_LPM_DRIVE_HIGH, /* column 1 */
+ GPIO68_GPIO | MFP_LPM_DRIVE_HIGH, /* column 2 */
+ GPIO69_GPIO | MFP_LPM_DRIVE_HIGH, /* column 3 */
+ GPIO70_GPIO | MFP_LPM_DRIVE_HIGH, /* column 4 */
+ GPIO71_GPIO | MFP_LPM_DRIVE_HIGH, /* column 5 */
+ GPIO72_GPIO | MFP_LPM_DRIVE_HIGH, /* column 6 */
+ GPIO73_GPIO | MFP_LPM_DRIVE_HIGH, /* column 7 */
+ GPIO74_GPIO | MFP_LPM_DRIVE_HIGH, /* column 8 */
+ GPIO75_GPIO | MFP_LPM_DRIVE_HIGH, /* column 9 */
+ GPIO76_GPIO | MFP_LPM_DRIVE_HIGH, /* column 10 */
+ GPIO77_GPIO | MFP_LPM_DRIVE_HIGH, /* column 11 */
+ GPIO58_GPIO, /* row 0 */
+ GPIO59_GPIO, /* row 1 */
+ GPIO60_GPIO, /* row 2 */
+ GPIO61_GPIO, /* row 3 */
+ GPIO62_GPIO, /* row 4 */
+ GPIO63_GPIO, /* row 5 */
+ GPIO64_GPIO, /* row 6 */
+ GPIO65_GPIO, /* row 7 */
+
+ /* GPIO */
+ GPIO9_GPIO, /* CORGI_GPIO_nSD_DETECT */
+ GPIO7_GPIO, /* CORGI_GPIO_nSD_WP */
+ GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_MAIN_BAT_{LOW,COVER} */
+ GPIO13_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_LED_ORANGE */
+ GPIO21_GPIO, /* CORGI_GPIO_ADC_TEMP */
+ GPIO22_GPIO, /* CORGI_GPIO_IR_ON */
+ GPIO33_GPIO, /* CORGI_GPIO_SD_PWR */
+ GPIO38_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_ON */
+ GPIO43_GPIO | MFP_LPM_KEEP_OUTPUT, /* CORGI_GPIO_CHRG_UKN */
+ GPIO44_GPIO, /* CORGI_GPIO_HSYNC */
+
+ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_KEY_INT */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* CORGI_GPIO_AC_IN */
+ GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* CORGI_GPIO_WAKEUP */
+};
+
+/*
+ * Corgi SCOOP Device
+ */
+static struct resource corgi_scoop_resources[] = {
+ [0] = {
+ .start = 0x10800000,
+ .end = 0x10800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config corgi_scoop_setup = {
+ .io_dir = CORGI_SCOOP_IO_DIR,
+ .io_out = CORGI_SCOOP_IO_OUT,
+ .gpio_base = CORGI_SCOOP_GPIO_BASE,
+};
+
+struct platform_device corgiscoop_device = {
+ .name = "sharp-scoop",
+ .id = -1,
+ .dev = {
+ .platform_data = &corgi_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(corgi_scoop_resources),
+ .resource = corgi_scoop_resources,
+};
+
+static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = {
+{
+ .dev = &corgiscoop_device.dev,
+ .irq = CORGI_IRQ_GPIO_CF_IRQ,
+ .cd_irq = CORGI_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+},
+};
+
+static struct scoop_pcmcia_config corgi_pcmcia_config = {
+ .devs = &corgi_pcmcia_scoop[0],
+ .num_devs = 1,
+};
+
+static struct w100_mem_info corgi_fb_mem = {
+ .ext_cntl = 0x00040003,
+ .sdram_mode_reg = 0x00650021,
+ .ext_timing_cntl = 0x10002a4a,
+ .io_cntl = 0x7ff87012,
+ .size = 0x1fffff,
+};
+
+static struct w100_gen_regs corgi_fb_regs = {
+ .lcd_format = 0x00000003,
+ .lcdd_cntl1 = 0x01CC0000,
+ .lcdd_cntl2 = 0x0003FFFF,
+ .genlcd_cntl1 = 0x00FFFF0D,
+ .genlcd_cntl2 = 0x003F3003,
+ .genlcd_cntl3 = 0x000102aa,
+};
+
+static struct w100_gpio_regs corgi_fb_gpio = {
+ .init_data1 = 0x000000bf,
+ .init_data2 = 0x00000000,
+ .gpio_dir1 = 0x00000000,
+ .gpio_oe1 = 0x03c0feff,
+ .gpio_dir2 = 0x00000000,
+ .gpio_oe2 = 0x00000000,
+};
+
+static struct w100_mode corgi_fb_modes[] = {
+{
+ .xres = 480,
+ .yres = 640,
+ .left_margin = 0x56,
+ .right_margin = 0x55,
+ .upper_margin = 0x03,
+ .lower_margin = 0x00,
+ .crtc_ss = 0x82360056,
+ .crtc_ls = 0xA0280000,
+ .crtc_gs = 0x80280028,
+ .crtc_vpos_gs = 0x02830002,
+ .crtc_rev = 0x00400008,
+ .crtc_dclk = 0xA0000000,
+ .crtc_gclk = 0x8015010F,
+ .crtc_goe = 0x80100110,
+ .crtc_ps1_active = 0x41060010,
+ .pll_freq = 75,
+ .fast_pll_freq = 100,
+ .sysclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .pixclk_src = CLK_SRC_PLL,
+ .pixclk_divider = 2,
+ .pixclk_divider_rotated = 6,
+},{
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 0x27,
+ .right_margin = 0x2e,
+ .upper_margin = 0x01,
+ .lower_margin = 0x00,
+ .crtc_ss = 0x81170027,
+ .crtc_ls = 0xA0140000,
+ .crtc_gs = 0xC0140014,
+ .crtc_vpos_gs = 0x00010141,
+ .crtc_rev = 0x00400008,
+ .crtc_dclk = 0xA0000000,
+ .crtc_gclk = 0x8015010F,
+ .crtc_goe = 0x80100110,
+ .crtc_ps1_active = 0x41060010,
+ .pll_freq = 0,
+ .fast_pll_freq = 0,
+ .sysclk_src = CLK_SRC_XTAL,
+ .sysclk_divider = 0,
+ .pixclk_src = CLK_SRC_XTAL,
+ .pixclk_divider = 1,
+ .pixclk_divider_rotated = 1,
+},
+
+};
+
+static struct w100fb_mach_info corgi_fb_info = {
+ .init_mode = INIT_MODE_ROTATED,
+ .mem = &corgi_fb_mem,
+ .regs = &corgi_fb_regs,
+ .modelist = &corgi_fb_modes[0],
+ .num_modes = 2,
+ .gpio = &corgi_fb_gpio,
+ .xtal_freq = 12500000,
+ .xtal_dbl = 0,
+};
+
+static struct resource corgi_fb_resources[] = {
+ [0] = {
+ .start = 0x08000000,
+ .end = 0x08ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device corgifb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(corgi_fb_resources),
+ .resource = corgi_fb_resources,
+ .dev = {
+ .platform_data = &corgi_fb_info,
+ },
+
+};
+
+/*
+ * Corgi Keyboard Device
+ */
+#define CORGI_KEY_CALENDER KEY_F1
+#define CORGI_KEY_ADDRESS KEY_F2
+#define CORGI_KEY_FN KEY_F3
+#define CORGI_KEY_CANCEL KEY_F4
+#define CORGI_KEY_OFF KEY_SUSPEND
+#define CORGI_KEY_EXOK KEY_F5
+#define CORGI_KEY_EXCANCEL KEY_F6
+#define CORGI_KEY_EXJOGDOWN KEY_F7
+#define CORGI_KEY_EXJOGUP KEY_F8
+#define CORGI_KEY_JAP1 KEY_LEFTCTRL
+#define CORGI_KEY_JAP2 KEY_LEFTALT
+#define CORGI_KEY_MAIL KEY_F10
+#define CORGI_KEY_OK KEY_F11
+#define CORGI_KEY_MENU KEY_F12
+
+static const uint32_t corgikbd_keymap[] = {
+ KEY(0, 1, KEY_1),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_5),
+ KEY(0, 4, KEY_6),
+ KEY(0, 5, KEY_7),
+ KEY(0, 6, KEY_9),
+ KEY(0, 7, KEY_0),
+ KEY(0, 8, KEY_BACKSPACE),
+ KEY(1, 1, KEY_2),
+ KEY(1, 2, KEY_4),
+ KEY(1, 3, KEY_R),
+ KEY(1, 4, KEY_Y),
+ KEY(1, 5, KEY_8),
+ KEY(1, 6, KEY_I),
+ KEY(1, 7, KEY_O),
+ KEY(1, 8, KEY_P),
+ KEY(2, 0, KEY_TAB),
+ KEY(2, 1, KEY_Q),
+ KEY(2, 2, KEY_E),
+ KEY(2, 3, KEY_T),
+ KEY(2, 4, KEY_G),
+ KEY(2, 5, KEY_U),
+ KEY(2, 6, KEY_J),
+ KEY(2, 7, KEY_K),
+ KEY(3, 0, CORGI_KEY_CALENDER),
+ KEY(3, 1, KEY_W),
+ KEY(3, 2, KEY_S),
+ KEY(3, 3, KEY_F),
+ KEY(3, 4, KEY_V),
+ KEY(3, 5, KEY_H),
+ KEY(3, 6, KEY_M),
+ KEY(3, 7, KEY_L),
+ KEY(3, 9, KEY_RIGHTSHIFT),
+ KEY(4, 0, CORGI_KEY_ADDRESS),
+ KEY(4, 1, KEY_A),
+ KEY(4, 2, KEY_D),
+ KEY(4, 3, KEY_C),
+ KEY(4, 4, KEY_B),
+ KEY(4, 5, KEY_N),
+ KEY(4, 6, KEY_DOT),
+ KEY(4, 8, KEY_ENTER),
+ KEY(4, 10, KEY_LEFTSHIFT),
+ KEY(5, 0, CORGI_KEY_MAIL),
+ KEY(5, 1, KEY_Z),
+ KEY(5, 2, KEY_X),
+ KEY(5, 3, KEY_MINUS),
+ KEY(5, 4, KEY_SPACE),
+ KEY(5, 5, KEY_COMMA),
+ KEY(5, 7, KEY_UP),
+ KEY(5, 11, CORGI_KEY_FN),
+ KEY(6, 0, KEY_SYSRQ),
+ KEY(6, 1, CORGI_KEY_JAP1),
+ KEY(6, 2, CORGI_KEY_JAP2),
+ KEY(6, 3, CORGI_KEY_CANCEL),
+ KEY(6, 4, CORGI_KEY_OK),
+ KEY(6, 5, CORGI_KEY_MENU),
+ KEY(6, 6, KEY_LEFT),
+ KEY(6, 7, KEY_DOWN),
+ KEY(6, 8, KEY_RIGHT),
+ KEY(7, 0, CORGI_KEY_OFF),
+ KEY(7, 1, CORGI_KEY_EXOK),
+ KEY(7, 2, CORGI_KEY_EXCANCEL),
+ KEY(7, 3, CORGI_KEY_EXJOGDOWN),
+ KEY(7, 4, CORGI_KEY_EXJOGUP),
+};
+
+static struct matrix_keymap_data corgikbd_keymap_data = {
+ .keymap = corgikbd_keymap,
+ .keymap_size = ARRAY_SIZE(corgikbd_keymap),
+};
+
+static const int corgikbd_row_gpios[] =
+ { 58, 59, 60, 61, 62, 63, 64, 65 };
+static const int corgikbd_col_gpios[] =
+ { 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77 };
+
+static struct matrix_keypad_platform_data corgikbd_pdata = {
+ .keymap_data = &corgikbd_keymap_data,
+ .row_gpios = corgikbd_row_gpios,
+ .col_gpios = corgikbd_col_gpios,
+ .num_row_gpios = ARRAY_SIZE(corgikbd_row_gpios),
+ .num_col_gpios = ARRAY_SIZE(corgikbd_col_gpios),
+ .col_scan_delay_us = 10,
+ .debounce_ms = 10,
+ .wakeup = 1,
+};
+
+static struct platform_device corgikbd_device = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &corgikbd_pdata,
+ },
+};
+
+/*
+ * Corgi LEDs
+ */
+static struct gpio_led corgi_gpio_leds[] = {
+ {
+ .name = "corgi:amber:charge",
+ .default_trigger = "sharpsl-charge",
+ .gpio = CORGI_GPIO_LED_ORANGE,
+ },
+ {
+ .name = "corgi:green:mail",
+ .default_trigger = "nand-disk",
+ .gpio = CORGI_GPIO_LED_GREEN,
+ },
+};
+
+static struct gpio_led_platform_data corgi_gpio_leds_info = {
+ .leds = corgi_gpio_leds,
+ .num_leds = ARRAY_SIZE(corgi_gpio_leds),
+};
+
+static struct platform_device corgiled_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &corgi_gpio_leds_info,
+ },
+};
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static struct pxamci_platform_data corgi_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = CORGI_GPIO_nSD_DETECT,
+ .gpio_card_ro = CORGI_GPIO_nSD_WP,
+ .gpio_power = CORGI_GPIO_SD_PWR,
+};
+
+
+/*
+ * Irda
+ */
+static struct pxaficp_platform_data corgi_ficp_platform_data = {
+ .gpio_pwdown = CORGI_GPIO_IR_ON,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+
+/*
+ * USB Device Controller
+ */
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ /* no connect GPIO; corgi can't tell connection status */
+ .gpio_pullup = CORGI_GPIO_USB_PULLUP,
+};
+
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MASTER)
+static struct pxa2xx_spi_master corgi_spi_info = {
+ .num_chipselect = 3,
+};
+
+static void corgi_wait_for_hsync(void)
+{
+ while (gpio_get_value(CORGI_GPIO_HSYNC))
+ cpu_relax();
+
+ while (!gpio_get_value(CORGI_GPIO_HSYNC))
+ cpu_relax();
+}
+
+static struct ads7846_platform_data corgi_ads7846_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .gpio_pendown = CORGI_GPIO_TP_INT,
+ .wait_for_sync = corgi_wait_for_hsync,
+};
+
+static struct pxa2xx_spi_chip corgi_ads7846_chip = {
+ .gpio_cs = CORGI_GPIO_ADS7846_CS,
+};
+
+static void corgi_bl_kick_battery(void)
+{
+ void (*kick_batt)(void);
+
+ kick_batt = symbol_get(sharpsl_battery_kick);
+ if (kick_batt) {
+ kick_batt();
+ symbol_put(sharpsl_battery_kick);
+ }
+}
+
+static struct corgi_lcd_platform_data corgi_lcdcon_info = {
+ .init_mode = CORGI_LCD_MODE_VGA,
+ .max_intensity = 0x2f,
+ .default_intensity = 0x1f,
+ .limit_mask = 0x0b,
+ .gpio_backlight_cont = CORGI_GPIO_BACKLIGHT_CONT,
+ .gpio_backlight_on = -1,
+ .kick_battery = corgi_bl_kick_battery,
+};
+
+static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
+ .gpio_cs = CORGI_GPIO_LCDCON_CS,
+};
+
+static struct pxa2xx_spi_chip corgi_max1111_chip = {
+ .gpio_cs = CORGI_GPIO_MAX1111_CS,
+};
+
+static struct spi_board_info corgi_spi_devices[] = {
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 1200000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .platform_data = &corgi_ads7846_info,
+ .controller_data= &corgi_ads7846_chip,
+ .irq = gpio_to_irq(CORGI_GPIO_TP_INT),
+ }, {
+ .modalias = "corgi-lcd",
+ .max_speed_hz = 50000,
+ .bus_num = 1,
+ .chip_select = 1,
+ .platform_data = &corgi_lcdcon_info,
+ .controller_data= &corgi_lcdcon_chip,
+ }, {
+ .modalias = "max1111",
+ .max_speed_hz = 450000,
+ .bus_num = 1,
+ .chip_select = 2,
+ .controller_data= &corgi_max1111_chip,
+ },
+};
+
+static void __init corgi_init_spi(void)
+{
+ pxa2xx_set_spi_info(1, &corgi_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
+}
+#else
+static inline void corgi_init_spi(void) {}
+#endif
+
+static struct mtd_partition sharpsl_nand_partitions[] = {
+ {
+ .name = "System Area",
+ .offset = 0,
+ .size = 7 * 1024 * 1024,
+ },
+ {
+ .name = "Root Filesystem",
+ .offset = 7 * 1024 * 1024,
+ .size = 25 * 1024 * 1024,
+ },
+ {
+ .name = "Home Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr sharpsl_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 2,
+ .pattern = scan_ff_pattern
+};
+
+static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
+ .badblock_pattern = &sharpsl_bbt,
+ .partitions = sharpsl_nand_partitions,
+ .nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions),
+};
+
+static struct resource sharpsl_nand_resources[] = {
+ {
+ .start = 0x0C000000,
+ .end = 0x0C000FFF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sharpsl_nand_device = {
+ .name = "sharpsl-nand",
+ .id = -1,
+ .resource = sharpsl_nand_resources,
+ .num_resources = ARRAY_SIZE(sharpsl_nand_resources),
+ .dev.platform_data = &sharpsl_nand_platform_data,
+};
+
+static struct mtd_partition sharpsl_rom_parts[] = {
+ {
+ .name ="Boot PROM Filesystem",
+ .offset = 0x00120000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data sharpsl_rom_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(sharpsl_rom_parts),
+ .parts = sharpsl_rom_parts,
+};
+
+static struct resource sharpsl_rom_resources[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x007fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sharpsl_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = sharpsl_rom_resources,
+ .num_resources = ARRAY_SIZE(sharpsl_rom_resources),
+ .dev.platform_data = &sharpsl_rom_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &corgiscoop_device,
+ &corgifb_device,
+ &corgikbd_device,
+ &corgiled_device,
+ &sharpsl_nand_device,
+ &sharpsl_rom_device,
+};
+
+static struct i2c_board_info __initdata corgi_i2c_devices[] = {
+ { I2C_BOARD_INFO("wm8731", 0x1b) },
+};
+
+static void corgi_poweroff(void)
+{
+ if (!machine_is_corgi())
+ /* Green LED off tells the bootloader to halt */
+ gpio_set_value(CORGI_GPIO_LED_GREEN, 0);
+
+ arm_machine_restart('h', NULL);
+}
+
+static void corgi_restart(char mode, const char *cmd)
+{
+ if (!machine_is_corgi())
+ /* Green LED on tells the bootloader to reboot */
+ gpio_set_value(CORGI_GPIO_LED_GREEN, 1);
+
+ arm_machine_restart('h', cmd);
+}
+
+static void __init corgi_init(void)
+{
+ pm_power_off = corgi_poweroff;
+ arm_pm_restart = corgi_restart;
+
+ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+ PCFR |= PCFR_OPDE;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(corgi_pin_config));
+
+ /* allow wakeup from various GPIOs */
+ gpio_set_wake(CORGI_GPIO_KEY_INT, 1);
+ gpio_set_wake(CORGI_GPIO_WAKEUP, 1);
+ gpio_set_wake(CORGI_GPIO_AC_IN, 1);
+ gpio_set_wake(CORGI_GPIO_CHRG_FULL, 1);
+
+ if (!machine_is_corgi())
+ gpio_set_wake(CORGI_GPIO_MAIN_BAT_LOW, 1);
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ corgi_init_spi();
+
+ pxa_set_udc_info(&udc_info);
+ pxa_set_mci_info(&corgi_mci_platform_data);
+ pxa_set_ficp_info(&corgi_ficp_platform_data);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(corgi_i2c_devices));
+
+ platform_scoop_config = &corgi_pcmcia_config;
+
+ if (machine_is_husky())
+ sharpsl_nand_partitions[1].size = 53 * 1024 * 1024;
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init fixup_corgi(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xa0000000;
+ if (machine_is_corgi())
+ mi->bank[0].size = (32*1024*1024);
+ else
+ mi->bank[0].size = (64*1024*1024);
+}
+
+#ifdef CONFIG_MACH_CORGI
+MACHINE_START(CORGI, "SHARP Corgi")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = corgi_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_SHEPHERD
+MACHINE_START(SHEPHERD, "SHARP Shepherd")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = corgi_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_HUSKY
+MACHINE_START(HUSKY, "SHARP Husky")
+ .fixup = fixup_corgi,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = corgi_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
new file mode 100644
index 00000000..29034778
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -0,0 +1,215 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can 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/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <mach/corgi.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/sharpsl_pm.h>
+
+#include "generic.h"
+
+#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
+
+static struct gpio charger_gpios[] = {
+ { CORGI_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+ { CORGI_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
+ { CORGI_GPIO_CHRG_UKN, GPIOF_OUT_INIT_LOW, "Charger Unknown" },
+ { CORGI_GPIO_KEY_INT, GPIOF_IN, "Key Interrupt" },
+};
+
+static void corgi_charger_init(void)
+{
+ gpio_request_array(ARRAY_AND_SIZE(charger_gpios));
+}
+
+static void corgi_measure_temp(int on)
+{
+ gpio_set_value(CORGI_GPIO_ADC_TEMP_ON, on);
+}
+
+static void corgi_charge(int on)
+{
+ if (on) {
+ if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
+ gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+ gpio_set_value(CORGI_GPIO_CHRG_UKN, 1);
+ } else {
+ gpio_set_value(CORGI_GPIO_CHRG_ON, 1);
+ gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
+ }
+ } else {
+ gpio_set_value(CORGI_GPIO_CHRG_ON, 0);
+ gpio_set_value(CORGI_GPIO_CHRG_UKN, 0);
+ }
+}
+
+static void corgi_discharge(int on)
+{
+ gpio_set_value(CORGI_GPIO_DISCHARGE_ON, on);
+}
+
+static void corgi_presuspend(void)
+{
+}
+
+static void corgi_postsuspend(void)
+{
+}
+
+/*
+ * Check what brought us out of the suspend.
+ * Return: 0 to sleep, otherwise wake
+ */
+static int corgi_should_wakeup(unsigned int resume_on_alarm)
+{
+ int is_resume = 0;
+
+ dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
+
+ if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
+ if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+ /* charge on */
+ dev_dbg(sharpsl_pm.dev, "ac insert\n");
+ sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+ } else {
+ /* charge off */
+ dev_dbg(sharpsl_pm.dev, "ac remove\n");
+ sharpsl_pm_led(SHARPSL_LED_OFF);
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ }
+ }
+
+ if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL)))
+ dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
+
+ if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT))
+ is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
+
+ if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP))
+ is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
+
+ if (resume_on_alarm && (PEDR & PWER_RTC))
+ is_resume |= PWER_RTC;
+
+ dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+ return is_resume;
+}
+
+static unsigned long corgi_charger_wakeup(void)
+{
+ return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
+}
+
+unsigned long corgipm_read_devdata(int type)
+{
+ switch(type) {
+ case SHARPSL_STATUS_ACIN:
+ return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
+ case SHARPSL_STATUS_LOCK:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
+ case SHARPSL_STATUS_CHRGFULL:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull);
+ case SHARPSL_STATUS_FATAL:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_fatal);
+ case SHARPSL_ACIN_VOLT:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
+ case SHARPSL_BATT_TEMP:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
+ case SHARPSL_BATT_VOLT:
+ default:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
+ }
+}
+
+static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
+ .init = corgi_charger_init,
+ .exit = NULL,
+ .gpio_batlock = CORGI_GPIO_BAT_COVER,
+ .gpio_acin = CORGI_GPIO_AC_IN,
+ .gpio_batfull = CORGI_GPIO_CHRG_FULL,
+ .discharge = corgi_discharge,
+ .charge = corgi_charge,
+ .measure_temp = corgi_measure_temp,
+ .presuspend = corgi_presuspend,
+ .postsuspend = corgi_postsuspend,
+ .read_devdata = corgipm_read_devdata,
+ .charger_wakeup = corgi_charger_wakeup,
+ .should_wakeup = corgi_should_wakeup,
+#if defined(CONFIG_LCD_CORGI)
+ .backlight_limit = corgi_lcd_limit_intensity,
+#endif
+ .charge_on_volt = SHARPSL_CHARGE_ON_VOLT,
+ .charge_on_temp = SHARPSL_CHARGE_ON_TEMP,
+ .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
+ .charge_acin_low = SHARPSL_CHARGE_ON_ACIN_LOW,
+ .fatal_acin_volt = SHARPSL_FATAL_ACIN_VOLT,
+ .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
+ .bat_levels = 40,
+ .bat_levels_noac = sharpsl_battery_levels_noac,
+ .bat_levels_acin = sharpsl_battery_levels_acin,
+ .status_high_acin = 188,
+ .status_low_acin = 178,
+ .status_high_noac = 185,
+ .status_low_noac = 175,
+};
+
+static struct platform_device *corgipm_device;
+
+static int __devinit corgipm_init(void)
+{
+ int ret;
+
+ if (!machine_is_corgi() && !machine_is_shepherd()
+ && !machine_is_husky())
+ return -ENODEV;
+
+ corgipm_device = platform_device_alloc("sharpsl-pm", -1);
+ if (!corgipm_device)
+ return -ENOMEM;
+
+ if (!machine_is_corgi())
+ corgi_pm_machinfo.batfull_irq = 1;
+
+ corgipm_device->dev.platform_data = &corgi_pm_machinfo;
+ ret = platform_device_add(corgipm_device);
+
+ if (ret)
+ platform_device_put(corgipm_device);
+
+ return ret;
+}
+
+static void corgipm_exit(void)
+{
+ platform_device_unregister(corgipm_device);
+}
+
+module_init(corgipm_init);
+module_exit(corgipm_exit);
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
new file mode 100644
index 00000000..6a7aeab4
--- /dev/null
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -0,0 +1,494 @@
+/*
+ * linux/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+ *
+ * Copyright (C) 2002,2003 Intrinsyc Software
+ *
+ * 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
+ *
+ * History:
+ * 31-Jul-2002 : Initial version [FB]
+ * 29-Jan-2003 : added PXA255 support [FB]
+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
+ *
+ * Note:
+ * This driver may change the memory bus clock rate, but will not do any
+ * platform specific access timing changes... for example if you have flash
+ * memory connected to CS0, you will need to register a platform specific
+ * notifier which will adjust the memory access strobes to maintain a
+ * minimum strobe width.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/smemc.h>
+
+#ifdef DEBUG
+static unsigned int freq_debug;
+module_param(freq_debug, uint, 0);
+MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
+#else
+#define freq_debug 0
+#endif
+
+static struct regulator *vcc_core;
+
+static unsigned int pxa27x_maxfreq;
+module_param(pxa27x_maxfreq, uint, 0);
+MODULE_PARM_DESC(pxa27x_maxfreq, "Set the pxa27x maxfreq in MHz"
+ "(typically 624=>pxa270, 416=>pxa271, 520=>pxa272)");
+
+typedef struct {
+ unsigned int khz;
+ unsigned int membus;
+ unsigned int cccr;
+ unsigned int div2;
+ unsigned int cclkcfg;
+ int vmin;
+ int vmax;
+} pxa_freqs_t;
+
+/* Define the refresh period in mSec for the SDRAM and the number of rows */
+#define SDRAM_TREF 64 /* standard 64ms SDRAM */
+static unsigned int sdram_rows;
+
+#define CCLKCFG_TURBO 0x1
+#define CCLKCFG_FCS 0x2
+#define CCLKCFG_HALFTURBO 0x4
+#define CCLKCFG_FASTBUS 0x8
+#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
+#define MDREFR_DRI_MASK 0xFFF
+
+#define MDCNFG_DRAC2(mdcnfg) (((mdcnfg) >> 21) & 0x3)
+#define MDCNFG_DRAC0(mdcnfg) (((mdcnfg) >> 5) & 0x3)
+
+/*
+ * PXA255 definitions
+ */
+/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
+#define CCLKCFG CCLKCFG_TURBO | CCLKCFG_FCS
+
+static pxa_freqs_t pxa255_run_freqs[] =
+{
+ /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
+ { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
+ {132700, 132700, 0x123, 1, CCLKCFG, -1, -1}, /* 133, 133, 66, 66 */
+ {199100, 99500, 0x141, 0, CCLKCFG, -1, -1}, /* 199, 199, 99, 99 */
+ {265400, 132700, 0x143, 1, CCLKCFG, -1, -1}, /* 265, 265, 133, 66 */
+ {331800, 165900, 0x145, 1, CCLKCFG, -1, -1}, /* 331, 331, 166, 83 */
+ {398100, 99500, 0x161, 0, CCLKCFG, -1, -1}, /* 398, 398, 196, 99 */
+};
+
+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
+static pxa_freqs_t pxa255_turbo_freqs[] =
+{
+ /* CPU MEMBUS CCCR DIV2 CCLKCFG run turbo PXbus SDRAM */
+ { 99500, 99500, 0x121, 1, CCLKCFG, -1, -1}, /* 99, 99, 50, 50 */
+ {199100, 99500, 0x221, 0, CCLKCFG, -1, -1}, /* 99, 199, 50, 99 */
+ {298500, 99500, 0x321, 0, CCLKCFG, -1, -1}, /* 99, 287, 50, 99 */
+ {298600, 99500, 0x1c1, 0, CCLKCFG, -1, -1}, /* 199, 287, 99, 99 */
+ {398100, 99500, 0x241, 0, CCLKCFG, -1, -1}, /* 199, 398, 99, 99 */
+};
+
+#define NUM_PXA25x_RUN_FREQS ARRAY_SIZE(pxa255_run_freqs)
+#define NUM_PXA25x_TURBO_FREQS ARRAY_SIZE(pxa255_turbo_freqs)
+
+static struct cpufreq_frequency_table
+ pxa255_run_freq_table[NUM_PXA25x_RUN_FREQS+1];
+static struct cpufreq_frequency_table
+ pxa255_turbo_freq_table[NUM_PXA25x_TURBO_FREQS+1];
+
+static unsigned int pxa255_turbo_table;
+module_param(pxa255_turbo_table, uint, 0);
+MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table, !0 = turbo table)");
+
+/*
+ * PXA270 definitions
+ *
+ * For the PXA27x:
+ * Control variables are A, L, 2N for CCCR; B, HT, T for CLKCFG.
+ *
+ * A = 0 => memory controller clock from table 3-7,
+ * A = 1 => memory controller clock = system bus clock
+ * Run mode frequency = 13 MHz * L
+ * Turbo mode frequency = 13 MHz * L * N
+ * System bus frequency = 13 MHz * L / (B + 1)
+ *
+ * In CCCR:
+ * A = 1
+ * L = 16 oscillator to run mode ratio
+ * 2N = 6 2 * (turbo mode to run mode ratio)
+ *
+ * In CCLKCFG:
+ * B = 1 Fast bus mode
+ * HT = 0 Half-Turbo mode
+ * T = 1 Turbo mode
+ *
+ * For now, just support some of the combinations in table 3-7 of
+ * PXA27x Processor Family Developer's Manual to simplify frequency
+ * change sequences.
+ */
+#define PXA27x_CCCR(A, L, N2) (A << 25 | N2 << 7 | L)
+#define CCLKCFG2(B, HT, T) \
+ (CCLKCFG_FCS | \
+ ((B) ? CCLKCFG_FASTBUS : 0) | \
+ ((HT) ? CCLKCFG_HALFTURBO : 0) | \
+ ((T) ? CCLKCFG_TURBO : 0))
+
+static pxa_freqs_t pxa27x_freqs[] = {
+ {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 },
+ {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
+ {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
+ {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
+ {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
+ {520000, 208000, PXA27x_CCCR(1, 16, 5), 1, CCLKCFG2(1, 0, 1), 1450000, 1705000 },
+ {624000, 208000, PXA27x_CCCR(1, 16, 6), 1, CCLKCFG2(1, 0, 1), 1550000, 1705000 }
+};
+
+#define NUM_PXA27x_FREQS ARRAY_SIZE(pxa27x_freqs)
+static struct cpufreq_frequency_table
+ pxa27x_freq_table[NUM_PXA27x_FREQS+1];
+
+extern unsigned get_clk_frequency_khz(int info);
+
+#ifdef CONFIG_REGULATOR
+
+static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
+{
+ int ret = 0;
+ int vmin, vmax;
+
+ if (!cpu_is_pxa27x())
+ return 0;
+
+ vmin = pxa_freq->vmin;
+ vmax = pxa_freq->vmax;
+ if ((vmin == -1) || (vmax == -1))
+ return 0;
+
+ ret = regulator_set_voltage(vcc_core, vmin, vmax);
+ if (ret)
+ pr_err("cpufreq: Failed to set vcc_core in [%dmV..%dmV]\n",
+ vmin, vmax);
+ return ret;
+}
+
+static __init void pxa_cpufreq_init_voltages(void)
+{
+ vcc_core = regulator_get(NULL, "vcc_core");
+ if (IS_ERR(vcc_core)) {
+ pr_info("cpufreq: Didn't find vcc_core regulator\n");
+ vcc_core = NULL;
+ } else {
+ pr_info("cpufreq: Found vcc_core regulator\n");
+ }
+}
+#else
+static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq)
+{
+ return 0;
+}
+
+static __init void pxa_cpufreq_init_voltages(void) { }
+#endif
+
+static void find_freq_tables(struct cpufreq_frequency_table **freq_table,
+ pxa_freqs_t **pxa_freqs)
+{
+ if (cpu_is_pxa25x()) {
+ if (!pxa255_turbo_table) {
+ *pxa_freqs = pxa255_run_freqs;
+ *freq_table = pxa255_run_freq_table;
+ } else {
+ *pxa_freqs = pxa255_turbo_freqs;
+ *freq_table = pxa255_turbo_freq_table;
+ }
+ }
+ if (cpu_is_pxa27x()) {
+ *pxa_freqs = pxa27x_freqs;
+ *freq_table = pxa27x_freq_table;
+ }
+}
+
+static void pxa27x_guess_max_freq(void)
+{
+ if (!pxa27x_maxfreq) {
+ pxa27x_maxfreq = 416000;
+ printk(KERN_INFO "PXA CPU 27x max frequency not defined "
+ "(pxa27x_maxfreq), assuming pxa271 with %dkHz maxfreq\n",
+ pxa27x_maxfreq);
+ } else {
+ pxa27x_maxfreq *= 1000;
+ }
+}
+
+static void init_sdram_rows(void)
+{
+ uint32_t mdcnfg = __raw_readl(MDCNFG);
+ unsigned int drac2 = 0, drac0 = 0;
+
+ if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3))
+ drac2 = MDCNFG_DRAC2(mdcnfg);
+
+ if (mdcnfg & (MDCNFG_DE0 | MDCNFG_DE1))
+ drac0 = MDCNFG_DRAC0(mdcnfg);
+
+ sdram_rows = 1 << (11 + max(drac0, drac2));
+}
+
+static u32 mdrefr_dri(unsigned int freq)
+{
+ u32 interval = freq * SDRAM_TREF / sdram_rows;
+
+ return (interval - (cpu_is_pxa27x() ? 31 : 0)) / 32;
+}
+
+/* find a valid frequency point */
+static int pxa_verify_policy(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *pxa_freqs_table;
+ pxa_freqs_t *pxa_freqs;
+ int ret;
+
+ find_freq_tables(&pxa_freqs_table, &pxa_freqs);
+ ret = cpufreq_frequency_table_verify(policy, pxa_freqs_table);
+
+ if (freq_debug)
+ pr_debug("Verified CPU policy: %dKhz min to %dKhz max\n",
+ policy->min, policy->max);
+
+ return ret;
+}
+
+static unsigned int pxa_cpufreq_get(unsigned int cpu)
+{
+ return get_clk_frequency_khz(0);
+}
+
+static int pxa_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_frequency_table *pxa_freqs_table;
+ pxa_freqs_t *pxa_freq_settings;
+ struct cpufreq_freqs freqs;
+ unsigned int idx;
+ unsigned long flags;
+ unsigned int new_freq_cpu, new_freq_mem;
+ unsigned int unused, preset_mdrefr, postset_mdrefr, cclkcfg;
+ int ret = 0;
+
+ /* Get the current policy */
+ find_freq_tables(&pxa_freqs_table, &pxa_freq_settings);
+
+ /* Lookup the next frequency */
+ if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
+ target_freq, relation, &idx)) {
+ return -EINVAL;
+ }
+
+ new_freq_cpu = pxa_freq_settings[idx].khz;
+ new_freq_mem = pxa_freq_settings[idx].membus;
+ freqs.old = policy->cur;
+ freqs.new = new_freq_cpu;
+ freqs.cpu = policy->cpu;
+
+ if (freq_debug)
+ pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
+ freqs.new / 1000, (pxa_freq_settings[idx].div2) ?
+ (new_freq_mem / 2000) : (new_freq_mem / 1000));
+
+ if (vcc_core && freqs.new > freqs.old)
+ ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
+ if (ret)
+ return ret;
+ /*
+ * Tell everyone what we're about to do...
+ * you should add a notify client with any platform specific
+ * Vcc changing capability
+ */
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
+ * we need to preset the smaller DRI before the change. If we're
+ * speeding up we need to set the larger DRI value after the change.
+ */
+ preset_mdrefr = postset_mdrefr = __raw_readl(MDREFR);
+ if ((preset_mdrefr & MDREFR_DRI_MASK) > mdrefr_dri(new_freq_mem)) {
+ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK);
+ preset_mdrefr |= mdrefr_dri(new_freq_mem);
+ }
+ postset_mdrefr =
+ (postset_mdrefr & ~MDREFR_DRI_MASK) | mdrefr_dri(new_freq_mem);
+
+ /* If we're dividing the memory clock by two for the SDRAM clock, this
+ * must be set prior to the change. Clearing the divide must be done
+ * after the change.
+ */
+ if (pxa_freq_settings[idx].div2) {
+ preset_mdrefr |= MDREFR_DB2_MASK;
+ postset_mdrefr |= MDREFR_DB2_MASK;
+ } else {
+ postset_mdrefr &= ~MDREFR_DB2_MASK;
+ }
+
+ local_irq_save(flags);
+
+ /* Set new the CCCR and prepare CCLKCFG */
+ CCCR = pxa_freq_settings[idx].cccr;
+ cclkcfg = pxa_freq_settings[idx].cclkcfg;
+
+ asm volatile(" \n\
+ ldr r4, [%1] /* load MDREFR */ \n\
+ b 2f \n\
+ .align 5 \n\
+1: \n\
+ str %3, [%1] /* preset the MDREFR */ \n\
+ mcr p14, 0, %2, c6, c0, 0 /* set CCLKCFG[FCS] */ \n\
+ str %4, [%1] /* postset the MDREFR */ \n\
+ \n\
+ b 3f \n\
+2: b 1b \n\
+3: nop \n\
+ "
+ : "=&r" (unused)
+ : "r" (MDREFR), "r" (cclkcfg),
+ "r" (preset_mdrefr), "r" (postset_mdrefr)
+ : "r4", "r5");
+ local_irq_restore(flags);
+
+ /*
+ * Tell everyone what we've just done...
+ * you should add a notify client with any platform specific
+ * SDRAM refresh timer adjustments
+ */
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ /*
+ * Even if voltage setting fails, we don't report it, as the frequency
+ * change succeeded. The voltage reduction is not a critical failure,
+ * only power savings will suffer from this.
+ *
+ * Note: if the voltage change fails, and a return value is returned, a
+ * bug is triggered (seems a deadlock). Should anybody find out where,
+ * the "return 0" should become a "return ret".
+ */
+ if (vcc_core && freqs.new < freqs.old)
+ ret = pxa_cpufreq_change_voltage(&pxa_freq_settings[idx]);
+
+ return 0;
+}
+
+static int pxa_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int i;
+ unsigned int freq;
+ struct cpufreq_frequency_table *pxa255_freq_table;
+ pxa_freqs_t *pxa255_freqs;
+
+ /* try to guess pxa27x cpu */
+ if (cpu_is_pxa27x())
+ pxa27x_guess_max_freq();
+
+ pxa_cpufreq_init_voltages();
+
+ init_sdram_rows();
+
+ /* set default policy and cpuinfo */
+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
+ policy->cur = get_clk_frequency_khz(0); /* current freq */
+ policy->min = policy->max = policy->cur;
+
+ /* Generate pxa25x the run cpufreq_frequency_table struct */
+ for (i = 0; i < NUM_PXA25x_RUN_FREQS; i++) {
+ pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
+ pxa255_run_freq_table[i].index = i;
+ }
+ pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ /* Generate pxa25x the turbo cpufreq_frequency_table struct */
+ for (i = 0; i < NUM_PXA25x_TURBO_FREQS; i++) {
+ pxa255_turbo_freq_table[i].frequency =
+ pxa255_turbo_freqs[i].khz;
+ pxa255_turbo_freq_table[i].index = i;
+ }
+ pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ pxa255_turbo_table = !!pxa255_turbo_table;
+
+ /* Generate the pxa27x cpufreq_frequency_table struct */
+ for (i = 0; i < NUM_PXA27x_FREQS; i++) {
+ freq = pxa27x_freqs[i].khz;
+ if (freq > pxa27x_maxfreq)
+ break;
+ pxa27x_freq_table[i].frequency = freq;
+ pxa27x_freq_table[i].index = i;
+ }
+ pxa27x_freq_table[i].index = i;
+ pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ /*
+ * Set the policy's minimum and maximum frequencies from the tables
+ * just constructed. This sets cpuinfo.mxx_freq, min and max.
+ */
+ if (cpu_is_pxa25x()) {
+ find_freq_tables(&pxa255_freq_table, &pxa255_freqs);
+ pr_info("PXA255 cpufreq using %s frequency table\n",
+ pxa255_turbo_table ? "turbo" : "run");
+ cpufreq_frequency_table_cpuinfo(policy, pxa255_freq_table);
+ }
+ else if (cpu_is_pxa27x())
+ cpufreq_frequency_table_cpuinfo(policy, pxa27x_freq_table);
+
+ printk(KERN_INFO "PXA CPU frequency change support initialized\n");
+
+ return 0;
+}
+
+static struct cpufreq_driver pxa_cpufreq_driver = {
+ .verify = pxa_verify_policy,
+ .target = pxa_set_target,
+ .init = pxa_cpufreq_init,
+ .get = pxa_cpufreq_get,
+ .name = "PXA2xx",
+};
+
+static int __init pxa_cpu_init(void)
+{
+ int ret = -ENODEV;
+ if (cpu_is_pxa25x() || cpu_is_pxa27x())
+ ret = cpufreq_register_driver(&pxa_cpufreq_driver);
+ return ret;
+}
+
+static void __exit pxa_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&pxa_cpufreq_driver);
+}
+
+
+MODULE_AUTHOR("Intrinsyc Software Inc.");
+MODULE_DESCRIPTION("CPU frequency changing driver for the PXA architecture");
+MODULE_LICENSE("GPL");
+module_init(pxa_cpu_init);
+module_exit(pxa_cpu_exit);
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
new file mode 100644
index 00000000..88fbec05
--- /dev/null
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -0,0 +1,257 @@
+/*
+ * linux/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+ *
+ * Copyright (C) 2008 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include <mach/pxa3xx-regs.h>
+
+#include "generic.h"
+
+#define HSS_104M (0)
+#define HSS_156M (1)
+#define HSS_208M (2)
+#define HSS_312M (3)
+
+#define SMCFS_78M (0)
+#define SMCFS_104M (2)
+#define SMCFS_208M (5)
+
+#define SFLFS_104M (0)
+#define SFLFS_156M (1)
+#define SFLFS_208M (2)
+#define SFLFS_312M (3)
+
+#define XSPCLK_156M (0)
+#define XSPCLK_NONE (3)
+
+#define DMCFS_26M (0)
+#define DMCFS_260M (3)
+
+struct pxa3xx_freq_info {
+ unsigned int cpufreq_mhz;
+ unsigned int core_xl : 5;
+ unsigned int core_xn : 3;
+ unsigned int hss : 2;
+ unsigned int dmcfs : 2;
+ unsigned int smcfs : 3;
+ unsigned int sflfs : 2;
+ unsigned int df_clkdiv : 3;
+
+ int vcc_core; /* in mV */
+ int vcc_sram; /* in mV */
+};
+
+#define OP(cpufreq, _xl, _xn, _hss, _dmc, _smc, _sfl, _dfi, vcore, vsram) \
+{ \
+ .cpufreq_mhz = cpufreq, \
+ .core_xl = _xl, \
+ .core_xn = _xn, \
+ .hss = HSS_##_hss##M, \
+ .dmcfs = DMCFS_##_dmc##M, \
+ .smcfs = SMCFS_##_smc##M, \
+ .sflfs = SFLFS_##_sfl##M, \
+ .df_clkdiv = _dfi, \
+ .vcc_core = vcore, \
+ .vcc_sram = vsram, \
+}
+
+static struct pxa3xx_freq_info pxa300_freqs[] = {
+ /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */
+ OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */
+ OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */
+ OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */
+ OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */
+};
+
+static struct pxa3xx_freq_info pxa320_freqs[] = {
+ /* CPU XL XN HSS DMEM SMEM SRAM DFI VCC_CORE VCC_SRAM */
+ OP(104, 8, 1, 104, 260, 78, 104, 3, 1000, 1100), /* 104MHz */
+ OP(208, 16, 1, 104, 260, 104, 156, 2, 1000, 1100), /* 208MHz */
+ OP(416, 16, 2, 156, 260, 104, 208, 2, 1100, 1200), /* 416MHz */
+ OP(624, 24, 2, 208, 260, 208, 312, 3, 1375, 1400), /* 624MHz */
+ OP(806, 31, 2, 208, 260, 208, 312, 3, 1400, 1400), /* 806MHz */
+};
+
+static unsigned int pxa3xx_freqs_num;
+static struct pxa3xx_freq_info *pxa3xx_freqs;
+static struct cpufreq_frequency_table *pxa3xx_freqs_table;
+
+static int setup_freqs_table(struct cpufreq_policy *policy,
+ struct pxa3xx_freq_info *freqs, int num)
+{
+ struct cpufreq_frequency_table *table;
+ int i;
+
+ table = kzalloc((num + 1) * sizeof(*table), GFP_KERNEL);
+ if (table == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < num; i++) {
+ table[i].index = i;
+ table[i].frequency = freqs[i].cpufreq_mhz * 1000;
+ }
+ table[num].index = i;
+ table[num].frequency = CPUFREQ_TABLE_END;
+
+ pxa3xx_freqs = freqs;
+ pxa3xx_freqs_num = num;
+ pxa3xx_freqs_table = table;
+
+ return cpufreq_frequency_table_cpuinfo(policy, table);
+}
+
+static void __update_core_freq(struct pxa3xx_freq_info *info)
+{
+ uint32_t mask = ACCR_XN_MASK | ACCR_XL_MASK;
+ uint32_t accr = ACCR;
+ uint32_t xclkcfg;
+
+ accr &= ~(ACCR_XN_MASK | ACCR_XL_MASK | ACCR_XSPCLK_MASK);
+ accr |= ACCR_XN(info->core_xn) | ACCR_XL(info->core_xl);
+
+ /* No clock until core PLL is re-locked */
+ accr |= ACCR_XSPCLK(XSPCLK_NONE);
+
+ xclkcfg = (info->core_xn == 2) ? 0x3 : 0x2; /* turbo bit */
+
+ ACCR = accr;
+ __asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg));
+
+ while ((ACSR & mask) != (accr & mask))
+ cpu_relax();
+}
+
+static void __update_bus_freq(struct pxa3xx_freq_info *info)
+{
+ uint32_t mask;
+ uint32_t accr = ACCR;
+
+ mask = ACCR_SMCFS_MASK | ACCR_SFLFS_MASK | ACCR_HSS_MASK |
+ ACCR_DMCFS_MASK;
+
+ accr &= ~mask;
+ accr |= ACCR_SMCFS(info->smcfs) | ACCR_SFLFS(info->sflfs) |
+ ACCR_HSS(info->hss) | ACCR_DMCFS(info->dmcfs);
+
+ ACCR = accr;
+
+ while ((ACSR & mask) != (accr & mask))
+ cpu_relax();
+}
+
+static int pxa3xx_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, pxa3xx_freqs_table);
+}
+
+static unsigned int pxa3xx_cpufreq_get(unsigned int cpu)
+{
+ return pxa3xx_get_clk_frequency_khz(0);
+}
+
+static int pxa3xx_cpufreq_set(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct pxa3xx_freq_info *next;
+ struct cpufreq_freqs freqs;
+ unsigned long flags;
+ int idx;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ /* Lookup the next frequency */
+ if (cpufreq_frequency_table_target(policy, pxa3xx_freqs_table,
+ target_freq, relation, &idx))
+ return -EINVAL;
+
+ next = &pxa3xx_freqs[idx];
+
+ freqs.old = policy->cur;
+ freqs.new = next->cpufreq_mhz * 1000;
+ freqs.cpu = policy->cpu;
+
+ pr_debug("CPU frequency from %d MHz to %d MHz%s\n",
+ freqs.old / 1000, freqs.new / 1000,
+ (freqs.old == freqs.new) ? " (skipped)" : "");
+
+ if (freqs.old == target_freq)
+ return 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ local_irq_save(flags);
+ __update_core_freq(next);
+ __update_bus_freq(next);
+ local_irq_restore(flags);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret = -EINVAL;
+
+ /* set default policy and cpuinfo */
+ policy->cpuinfo.min_freq = 104000;
+ policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
+ policy->max = pxa3xx_get_clk_frequency_khz(0);
+ policy->cur = policy->min = policy->max;
+
+ if (cpu_is_pxa300() || cpu_is_pxa310())
+ ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs));
+
+ if (cpu_is_pxa320())
+ ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs));
+
+ if (ret) {
+ pr_err("failed to setup frequency table\n");
+ return ret;
+ }
+
+ pr_info("CPUFREQ support for PXA3xx initialized\n");
+ return 0;
+}
+
+static struct cpufreq_driver pxa3xx_cpufreq_driver = {
+ .verify = pxa3xx_cpufreq_verify,
+ .target = pxa3xx_cpufreq_set,
+ .init = pxa3xx_cpufreq_init,
+ .get = pxa3xx_cpufreq_get,
+ .name = "pxa3xx-cpufreq",
+};
+
+static int __init cpufreq_init(void)
+{
+ if (cpu_is_pxa3xx())
+ return cpufreq_register_driver(&pxa3xx_cpufreq_driver);
+
+ return 0;
+}
+module_init(cpufreq_init);
+
+static void __exit cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&pxa3xx_cpufreq_driver);
+}
+module_exit(cpufreq_exit);
+
+MODULE_DESCRIPTION("CPU frequency scaling driver for PXA3xx");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-pxa/csb701.c b/arch/arm/mach-pxa/csb701.c
new file mode 100644
index 00000000..5a221a49
--- /dev/null
+++ b/arch/arm/mach-pxa/csb701.c
@@ -0,0 +1,66 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+
+static struct gpio_keys_button csb701_buttons[] = {
+ {
+ .code = 0x7,
+ .gpio = 1,
+ .active_low = 1,
+ .desc = "SW2",
+ .type = EV_SW,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data csb701_gpio_keys_data = {
+ .buttons = csb701_buttons,
+ .nbuttons = ARRAY_SIZE(csb701_buttons),
+};
+
+static struct gpio_led csb701_leds[] = {
+ {
+ .name = "csb701:yellow:heartbeat",
+ .default_trigger = "heartbeat",
+ .gpio = 11,
+ .active_low = 1,
+ },
+};
+
+static struct platform_device csb701_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev.platform_data = &csb701_gpio_keys_data,
+};
+
+static struct gpio_led_platform_data csb701_leds_gpio_data = {
+ .leds = csb701_leds,
+ .num_leds = ARRAY_SIZE(csb701_leds),
+};
+
+static struct platform_device csb701_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &csb701_leds_gpio_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &csb701_gpio_keys,
+ &csb701_leds_gpio,
+};
+
+static int __init csb701_init(void)
+{
+ if (!machine_is_csb726())
+ return -ENODEV;
+
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+module_init(csb701_init);
+
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
new file mode 100644
index 00000000..0481c29a
--- /dev/null
+++ b/arch/arm/mach-pxa/csb726.c
@@ -0,0 +1,281 @@
+/*
+ * Support for Cogent CSB726
+ *
+ * Copyright (c) 2008 Dmitry Eremin-Solenikov
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/sm501.h>
+#include <linux/smsc911x.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/csb726.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/audio.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/*
+ * n/a: 2, 5, 6, 7, 8, 23, 24, 25, 26, 27, 87, 88, 89,
+ * nu: 58 -- 77, 90, 91, 93, 102, 105-108, 114-116,
+ * XXX: 21,
+ * XXX: 79 CS_3 for LAN9215 or PSKTSEL on R2, R3
+ * XXX: 33 CS_5 for LAN9215 on R1
+ */
+
+static unsigned long csb726_pin_config[] = {
+ GPIO78_nCS_2, /* EXP_CS */
+ GPIO79_nCS_3, /* SMSC9215 */
+ GPIO80_nCS_4, /* SM501 */
+
+ GPIO52_GPIO, /* #SMSC9251 int */
+ GPIO53_GPIO, /* SM501 int */
+
+ GPIO1_GPIO, /* GPIO0 */
+ GPIO11_GPIO, /* GPIO1 */
+ GPIO9_GPIO, /* GPIO2 */
+ GPIO10_GPIO, /* GPIO3 */
+ GPIO16_PWM0_OUT, /* or GPIO4 */
+ GPIO17_PWM1_OUT, /* or GPIO5 */
+ GPIO94_GPIO, /* GPIO6 */
+ GPIO95_GPIO, /* GPIO7 */
+ GPIO96_GPIO, /* GPIO8 */
+ GPIO97_GPIO, /* GPIO9 */
+ GPIO15_GPIO, /* EXP_IRQ */
+ GPIO18_RDY, /* EXP_WAIT */
+
+ GPIO0_GPIO, /* PWR_INT */
+ GPIO104_GPIO, /* PWR_OFF */
+
+ GPIO12_GPIO, /* touch irq */
+
+ GPIO13_SSP2_TXD,
+ GPIO14_SSP2_SFRM,
+ MFP_CFG_OUT(GPIO19, AF1, DRIVE_LOW),/* SSP2_SYSCLK */
+ GPIO22_SSP2_SCLK,
+
+ GPIO81_SSP3_TXD,
+ GPIO82_SSP3_RXD,
+ GPIO83_SSP3_SFRM,
+ GPIO84_SSP3_SCLK,
+
+ GPIO20_GPIO, /* SDIO int */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO100_GPIO, /* SD CD */
+ GPIO101_GPIO, /* SD WP */
+
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO113_AC97_nRESET,
+
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO36_FFUART_DCD,
+ GPIO37_FFUART_DSR,
+ GPIO38_FFUART_RI,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16, /* maybe unused */
+ GPIO85_nPCE_1,
+ GPIO98_GPIO, /* CF IRQ */
+ GPIO99_GPIO, /* CF CD */
+ GPIO103_GPIO, /* Reset */
+
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+
+static struct pxamci_platform_data csb726_mci = {
+ .detect_delay_ms = 500,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ /* FIXME setpower */
+ .gpio_card_detect = CSB726_GPIO_MMC_DETECT,
+ .gpio_card_ro = CSB726_GPIO_MMC_RO,
+ .gpio_power = -1,
+};
+
+static struct pxaohci_platform_data csb726_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ .flags = ENABLE_PORT1 | NO_OC_PROTECTION,
+};
+
+static struct mtd_partition csb726_flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = CSB726_FLASH_uMON,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "root",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data csb726_flash_data = {
+ .width = 2,
+ .parts = csb726_flash_partitions,
+ .nr_parts = ARRAY_SIZE(csb726_flash_partitions),
+};
+
+static struct resource csb726_flash_resources[] = {
+ {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + CSB726_FLASH_SIZE - 1 ,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device csb726_flash = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &csb726_flash_data,
+ },
+ .resource = csb726_flash_resources,
+ .num_resources = ARRAY_SIZE(csb726_flash_resources),
+};
+
+static struct resource csb726_sm501_resources[] = {
+ {
+ .start = PXA_CS4_PHYS,
+ .end = PXA_CS4_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "sm501-localmem",
+ },
+ {
+ .start = PXA_CS4_PHYS + SZ_64M - SZ_2M,
+ .end = PXA_CS4_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "sm501-regs",
+ },
+ {
+ .start = CSB726_IRQ_SM501,
+ .end = CSB726_IRQ_SM501,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sm501_initdata csb726_sm501_initdata = {
+/* .devices = SM501_USE_USB_HOST, */
+ .devices = SM501_USE_USB_HOST | SM501_USE_UART0 | SM501_USE_UART1,
+};
+
+static struct sm501_platdata csb726_sm501_platdata = {
+ .init = &csb726_sm501_initdata,
+};
+
+static struct platform_device csb726_sm501 = {
+ .name = "sm501",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(csb726_sm501_resources),
+ .resource = csb726_sm501_resources,
+ .dev = {
+ .platform_data = &csb726_sm501_platdata,
+ },
+};
+
+static struct resource csb726_lan_resources[] = {
+ {
+ .start = PXA_CS3_PHYS,
+ .end = PXA_CS3_PHYS + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = CSB726_IRQ_LAN,
+ .end = CSB726_IRQ_LAN,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+struct smsc911x_platform_config csb726_lan_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
+static struct platform_device csb726_lan = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(csb726_lan_resources),
+ .resource = csb726_lan_resources,
+ .dev = {
+ .platform_data = &csb726_lan_config,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &csb726_flash,
+ &csb726_sm501,
+ &csb726_lan,
+};
+
+static void __init csb726_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(csb726_pin_config));
+/* __raw_writel(0x7ffc3ffc, MSC1); *//* LAN9215/EXP_CS */
+/* __raw_writel(0x06697ff4, MSC2); *//* none/SM501 */
+ __raw_writel((__raw_readl(MSC2) & ~0xffff) | 0x7ff4, MSC2); /* SM501 */
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_i2c_info(NULL);
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_mci_info(&csb726_mci);
+ pxa_set_ohci_info(&csb726_ohci_platform_data);
+ pxa_set_ac97_info(NULL);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(CSB726, "Cogent CSB726")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = csb726_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 00000000..2e042540
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,1069 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/pmu.h>
+#include <mach/udc.h>
+#include <mach/pxa3xx-u2d.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/camera.h>
+#include <mach/audio.h>
+#include <mach/hardware.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "devices.h"
+#include "generic.h"
+
+void __init pxa_register_device(struct platform_device *dev, void *data)
+{
+ int ret;
+
+ dev->dev.platform_data = data;
+
+ ret = platform_device_register(dev);
+ if (ret)
+ dev_err(&dev->dev, "unable to register device: %d\n", ret);
+}
+
+static struct resource pxa_resource_pmu = {
+ .start = IRQ_PMU,
+ .end = IRQ_PMU,
+ .flags = IORESOURCE_IRQ,
+};
+
+struct platform_device pxa_device_pmu = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .resource = &pxa_resource_pmu,
+ .num_resources = 1,
+};
+
+static struct resource pxamci_resources[] = {
+ [0] = {
+ .start = 0x41100000,
+ .end = 0x41100fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MMC,
+ .end = IRQ_MMC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 21,
+ .end = 21,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = 22,
+ .end = 22,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 pxamci_dmamask = 0xffffffffUL;
+
+struct platform_device pxa_device_mci = {
+ .name = "pxa2xx-mci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &pxamci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxamci_resources),
+ .resource = pxamci_resources,
+};
+
+void __init pxa_set_mci_info(struct pxamci_platform_data *info)
+{
+ pxa_register_device(&pxa_device_mci, info);
+}
+
+
+static struct pxa2xx_udc_mach_info pxa_udc_info = {
+ .gpio_pullup = -1,
+};
+
+void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
+{
+ memcpy(&pxa_udc_info, info, sizeof *info);
+}
+
+static struct resource pxa2xx_udc_resources[] = {
+ [0] = {
+ .start = 0x40600000,
+ .end = 0x4060ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB,
+ .end = IRQ_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dma_mask = ~(u32)0;
+
+struct platform_device pxa25x_device_udc = {
+ .name = "pxa25x-udc",
+ .id = -1,
+ .resource = pxa2xx_udc_resources,
+ .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
+ .dev = {
+ .platform_data = &pxa_udc_info,
+ .dma_mask = &udc_dma_mask,
+ }
+};
+
+struct platform_device pxa27x_device_udc = {
+ .name = "pxa27x-udc",
+ .id = -1,
+ .resource = pxa2xx_udc_resources,
+ .num_resources = ARRAY_SIZE(pxa2xx_udc_resources),
+ .dev = {
+ .platform_data = &pxa_udc_info,
+ .dma_mask = &udc_dma_mask,
+ }
+};
+
+#ifdef CONFIG_PXA3xx
+static struct resource pxa3xx_u2d_resources[] = {
+ [0] = {
+ .start = 0x54100000,
+ .end = 0x54100fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB2,
+ .end = IRQ_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa3xx_device_u2d = {
+ .name = "pxa3xx-u2d",
+ .id = -1,
+ .resource = pxa3xx_u2d_resources,
+ .num_resources = ARRAY_SIZE(pxa3xx_u2d_resources),
+};
+
+void __init pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_u2d, info);
+}
+#endif /* CONFIG_PXA3xx */
+
+static struct resource pxafb_resources[] = {
+ [0] = {
+ .start = 0x44000000,
+ .end = 0x4400ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 fb_dma_mask = ~(u64)0;
+
+struct platform_device pxa_device_fb = {
+ .name = "pxa2xx-fb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxafb_resources),
+ .resource = pxafb_resources,
+};
+
+void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info)
+{
+ pxa_device_fb.dev.parent = parent;
+ pxa_register_device(&pxa_device_fb, info);
+}
+
+static struct resource pxa_resource_ffuart[] = {
+ {
+ .start = 0x40100000,
+ .end = 0x40100023,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_FFUART,
+ .end = IRQ_FFUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device pxa_device_ffuart = {
+ .name = "pxa2xx-uart",
+ .id = 0,
+ .resource = pxa_resource_ffuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_ffuart),
+};
+
+void __init pxa_set_ffuart_info(void *info)
+{
+ pxa_register_device(&pxa_device_ffuart, info);
+}
+
+static struct resource pxa_resource_btuart[] = {
+ {
+ .start = 0x40200000,
+ .end = 0x40200023,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_BTUART,
+ .end = IRQ_BTUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device pxa_device_btuart = {
+ .name = "pxa2xx-uart",
+ .id = 1,
+ .resource = pxa_resource_btuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_btuart),
+};
+
+void __init pxa_set_btuart_info(void *info)
+{
+ pxa_register_device(&pxa_device_btuart, info);
+}
+
+static struct resource pxa_resource_stuart[] = {
+ {
+ .start = 0x40700000,
+ .end = 0x40700023,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_STUART,
+ .end = IRQ_STUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device pxa_device_stuart = {
+ .name = "pxa2xx-uart",
+ .id = 2,
+ .resource = pxa_resource_stuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_stuart),
+};
+
+void __init pxa_set_stuart_info(void *info)
+{
+ pxa_register_device(&pxa_device_stuart, info);
+}
+
+static struct resource pxa_resource_hwuart[] = {
+ {
+ .start = 0x41600000,
+ .end = 0x4160002F,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_HWUART,
+ .end = IRQ_HWUART,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device pxa_device_hwuart = {
+ .name = "pxa2xx-uart",
+ .id = 3,
+ .resource = pxa_resource_hwuart,
+ .num_resources = ARRAY_SIZE(pxa_resource_hwuart),
+};
+
+void __init pxa_set_hwuart_info(void *info)
+{
+ if (cpu_is_pxa255())
+ pxa_register_device(&pxa_device_hwuart, info);
+ else
+ pr_info("UART: Ignoring attempt to register HWUART on non-PXA255 hardware");
+}
+
+static struct resource pxai2c_resources[] = {
+ {
+ .start = 0x40301680,
+ .end = 0x403016a3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_I2C,
+ .end = IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa_device_i2c = {
+ .name = "pxa2xx-i2c",
+ .id = 0,
+ .resource = pxai2c_resources,
+ .num_resources = ARRAY_SIZE(pxai2c_resources),
+};
+
+void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
+{
+ pxa_register_device(&pxa_device_i2c, info);
+}
+
+#ifdef CONFIG_PXA27x
+static struct resource pxa27x_resources_i2c_power[] = {
+ {
+ .start = 0x40f00180,
+ .end = 0x40f001a3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PWRI2C,
+ .end = IRQ_PWRI2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_i2c_power = {
+ .name = "pxa2xx-i2c",
+ .id = 1,
+ .resource = pxa27x_resources_i2c_power,
+ .num_resources = ARRAY_SIZE(pxa27x_resources_i2c_power),
+};
+#endif
+
+static struct resource pxai2s_resources[] = {
+ {
+ .start = 0x40400000,
+ .end = 0x40400083,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_I2S,
+ .end = IRQ_I2S,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa_device_i2s = {
+ .name = "pxa2xx-i2s",
+ .id = -1,
+ .resource = pxai2s_resources,
+ .num_resources = ARRAY_SIZE(pxai2s_resources),
+};
+
+struct platform_device pxa_device_asoc_ssp1 = {
+ .name = "pxa-ssp-dai",
+ .id = 0,
+};
+
+struct platform_device pxa_device_asoc_ssp2= {
+ .name = "pxa-ssp-dai",
+ .id = 1,
+};
+
+struct platform_device pxa_device_asoc_ssp3 = {
+ .name = "pxa-ssp-dai",
+ .id = 2,
+};
+
+struct platform_device pxa_device_asoc_ssp4 = {
+ .name = "pxa-ssp-dai",
+ .id = 3,
+};
+
+struct platform_device pxa_device_asoc_platform = {
+ .name = "pxa-pcm-audio",
+ .id = -1,
+};
+
+static u64 pxaficp_dmamask = ~(u32)0;
+
+struct platform_device pxa_device_ficp = {
+ .name = "pxa2xx-ir",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxaficp_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
+{
+ pxa_register_device(&pxa_device_ficp, info);
+}
+
+static struct resource pxa_rtc_resources[] = {
+ [0] = {
+ .start = 0x40900000,
+ .end = 0x40900000 + 0x3b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC1Hz,
+ .end = IRQ_RTC1Hz,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_RTCAlrm,
+ .end = IRQ_RTCAlrm,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device sa1100_device_rtc = {
+ .name = "sa1100-rtc",
+ .id = -1,
+};
+
+struct platform_device pxa_device_rtc = {
+ .name = "pxa-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa_rtc_resources),
+ .resource = pxa_rtc_resources,
+};
+
+static struct resource pxa_ac97_resources[] = {
+ [0] = {
+ .start = 0x40500000,
+ .end = 0x40500000 + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_AC97,
+ .end = IRQ_AC97,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 pxa_ac97_dmamask = 0xffffffffUL;
+
+struct platform_device pxa_device_ac97 = {
+ .name = "pxa2xx-ac97",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxa_ac97_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxa_ac97_resources),
+ .resource = pxa_ac97_resources,
+};
+
+void __init pxa_set_ac97_info(pxa2xx_audio_ops_t *ops)
+{
+ pxa_register_device(&pxa_device_ac97, ops);
+}
+
+#ifdef CONFIG_PXA25x
+
+static struct resource pxa25x_resource_pwm0[] = {
+ [0] = {
+ .start = 0x40b00000,
+ .end = 0x40b0000f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device pxa25x_device_pwm0 = {
+ .name = "pxa25x-pwm",
+ .id = 0,
+ .resource = pxa25x_resource_pwm0,
+ .num_resources = ARRAY_SIZE(pxa25x_resource_pwm0),
+};
+
+static struct resource pxa25x_resource_pwm1[] = {
+ [0] = {
+ .start = 0x40c00000,
+ .end = 0x40c0000f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device pxa25x_device_pwm1 = {
+ .name = "pxa25x-pwm",
+ .id = 1,
+ .resource = pxa25x_resource_pwm1,
+ .num_resources = ARRAY_SIZE(pxa25x_resource_pwm1),
+};
+
+static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_ssp[] = {
+ [0] = {
+ .start = 0x41000000,
+ .end = 0x4100001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP,
+ .end = IRQ_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 13,
+ .end = 13,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 14,
+ .end = 14,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa25x_device_ssp = {
+ .name = "pxa25x-ssp",
+ .id = 0,
+ .dev = {
+ .dma_mask = &pxa25x_ssp_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa25x_resource_ssp,
+ .num_resources = ARRAY_SIZE(pxa25x_resource_ssp),
+};
+
+static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_nssp[] = {
+ [0] = {
+ .start = 0x41400000,
+ .end = 0x4140002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_NSSP,
+ .end = IRQ_NSSP,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 15,
+ .end = 15,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 16,
+ .end = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa25x_device_nssp = {
+ .name = "pxa25x-nssp",
+ .id = 1,
+ .dev = {
+ .dma_mask = &pxa25x_nssp_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa25x_resource_nssp,
+ .num_resources = ARRAY_SIZE(pxa25x_resource_nssp),
+};
+
+static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa25x_resource_assp[] = {
+ [0] = {
+ .start = 0x41500000,
+ .end = 0x4150002f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ASSP,
+ .end = IRQ_ASSP,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 23,
+ .end = 23,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 24,
+ .end = 24,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa25x_device_assp = {
+ /* ASSP is basically equivalent to NSSP */
+ .name = "pxa25x-nssp",
+ .id = 2,
+ .dev = {
+ .dma_mask = &pxa25x_assp_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa25x_resource_assp,
+ .num_resources = ARRAY_SIZE(pxa25x_resource_assp),
+};
+#endif /* CONFIG_PXA25x */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+static struct resource pxa27x_resource_camera[] = {
+ [0] = {
+ .start = 0x50000000,
+ .end = 0x50000fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CAMERA,
+ .end = IRQ_CAMERA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 pxa27x_dma_mask_camera = DMA_BIT_MASK(32);
+
+static struct platform_device pxa27x_device_camera = {
+ .name = "pxa27x-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &pxa27x_dma_mask_camera,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxa27x_resource_camera),
+ .resource = pxa27x_resource_camera,
+};
+
+void __init pxa_set_camera_info(struct pxacamera_platform_data *info)
+{
+ pxa_register_device(&pxa27x_device_camera, info);
+}
+
+static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ohci[] = {
+ [0] = {
+ .start = 0x4C000000,
+ .end = 0x4C00ff6f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH1,
+ .end = IRQ_USBH1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_ohci = {
+ .name = "pxa27x-ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxa27x_ohci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(pxa27x_resource_ohci),
+ .resource = pxa27x_resource_ohci,
+};
+
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+ pxa_register_device(&pxa27x_device_ohci, info);
+}
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+static struct resource pxa27x_resource_keypad[] = {
+ [0] = {
+ .start = 0x41500000,
+ .end = 0x4150004c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KEYPAD,
+ .end = IRQ_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa27x_device_keypad = {
+ .name = "pxa27x-keypad",
+ .id = -1,
+ .resource = pxa27x_resource_keypad,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_keypad),
+};
+
+void __init pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info)
+{
+ pxa_register_device(&pxa27x_device_keypad, info);
+}
+
+static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp1[] = {
+ [0] = {
+ .start = 0x41000000,
+ .end = 0x4100003f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP,
+ .end = IRQ_SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 13,
+ .end = 13,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 14,
+ .end = 14,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa27x_device_ssp1 = {
+ .name = "pxa27x-ssp",
+ .id = 0,
+ .dev = {
+ .dma_mask = &pxa27x_ssp1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa27x_resource_ssp1,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1),
+};
+
+static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp2[] = {
+ [0] = {
+ .start = 0x41700000,
+ .end = 0x4170003f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP2,
+ .end = IRQ_SSP2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 15,
+ .end = 15,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 16,
+ .end = 16,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa27x_device_ssp2 = {
+ .name = "pxa27x-ssp",
+ .id = 1,
+ .dev = {
+ .dma_mask = &pxa27x_ssp2_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa27x_resource_ssp2,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2),
+};
+
+static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa27x_resource_ssp3[] = {
+ [0] = {
+ .start = 0x41900000,
+ .end = 0x4190003f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP3,
+ .end = IRQ_SSP3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 66,
+ .end = 66,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 67,
+ .end = 67,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa27x_device_ssp3 = {
+ .name = "pxa27x-ssp",
+ .id = 2,
+ .dev = {
+ .dma_mask = &pxa27x_ssp3_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa27x_resource_ssp3,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3),
+};
+
+static struct resource pxa27x_resource_pwm0[] = {
+ [0] = {
+ .start = 0x40b00000,
+ .end = 0x40b0001f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device pxa27x_device_pwm0 = {
+ .name = "pxa27x-pwm",
+ .id = 0,
+ .resource = pxa27x_resource_pwm0,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_pwm0),
+};
+
+static struct resource pxa27x_resource_pwm1[] = {
+ [0] = {
+ .start = 0x40c00000,
+ .end = 0x40c0001f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device pxa27x_device_pwm1 = {
+ .name = "pxa27x-pwm",
+ .id = 1,
+ .resource = pxa27x_resource_pwm1,
+ .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1),
+};
+#endif /* CONFIG_PXA27x || CONFIG_PXA3xx || CONFIG_PXA95x*/
+
+#ifdef CONFIG_PXA3xx
+static struct resource pxa3xx_resources_mci2[] = {
+ [0] = {
+ .start = 0x42000000,
+ .end = 0x42000fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MMC2,
+ .end = IRQ_MMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 93,
+ .end = 93,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = 94,
+ .end = 94,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa3xx_device_mci2 = {
+ .name = "pxa2xx-mci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &pxamci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2),
+ .resource = pxa3xx_resources_mci2,
+};
+
+void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_mci2, info);
+}
+
+static struct resource pxa3xx_resources_mci3[] = {
+ [0] = {
+ .start = 0x42500000,
+ .end = 0x42500fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MMC3,
+ .end = IRQ_MMC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 100,
+ .end = 100,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = 101,
+ .end = 101,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa3xx_device_mci3 = {
+ .name = "pxa2xx-mci",
+ .id = 2,
+ .dev = {
+ .dma_mask = &pxamci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3),
+ .resource = pxa3xx_resources_mci3,
+};
+
+void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_mci3, info);
+}
+
+static struct resource pxa3xx_resources_gcu[] = {
+ {
+ .start = 0x54000000,
+ .end = 0x54000fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_GCU,
+ .end = IRQ_GCU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 pxa3xx_gcu_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device pxa3xx_device_gcu = {
+ .name = "pxa3xx-gcu",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_gcu),
+ .resource = pxa3xx_resources_gcu,
+ .dev = {
+ .dma_mask = &pxa3xx_gcu_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+#endif /* CONFIG_PXA3xx */
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
+static struct resource pxa3xx_resources_i2c_power[] = {
+ {
+ .start = 0x40f500c0,
+ .end = 0x40f500d3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PWRI2C,
+ .end = IRQ_PWRI2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa3xx_device_i2c_power = {
+ .name = "pxa3xx-pwri2c",
+ .id = 1,
+ .resource = pxa3xx_resources_i2c_power,
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_i2c_power),
+};
+
+static struct resource pxa3xx_resources_nand[] = {
+ [0] = {
+ .start = 0x43100000,
+ .end = 0x43100053,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_NAND,
+ .end = IRQ_NAND,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for Data DMA */
+ .start = 97,
+ .end = 97,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for Command DMA */
+ .start = 99,
+ .end = 99,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 pxa3xx_nand_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device pxa3xx_device_nand = {
+ .name = "pxa3xx-nand",
+ .id = -1,
+ .dev = {
+ .dma_mask = &pxa3xx_nand_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(pxa3xx_resources_nand),
+ .resource = pxa3xx_resources_nand,
+};
+
+void __init pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_nand, info);
+}
+
+static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource pxa3xx_resource_ssp4[] = {
+ [0] = {
+ .start = 0x41a00000,
+ .end = 0x41a0003f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP4,
+ .end = IRQ_SSP4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* DRCMR for RX */
+ .start = 2,
+ .end = 2,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ /* DRCMR for TX */
+ .start = 3,
+ .end = 3,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device pxa3xx_device_ssp4 = {
+ /* PXA3xx SSP is basically equivalent to PXA27x */
+ .name = "pxa27x-ssp",
+ .id = 3,
+ .dev = {
+ .dma_mask = &pxa3xx_ssp4_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = pxa3xx_resource_ssp4,
+ .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
+};
+#endif /* CONFIG_PXA3xx || CONFIG_PXA95x */
+
+/* pxa2xx-spi platform-device ID equals respective SSP platform-device ID + 1.
+ * See comment in arch/arm/mach-pxa/ssp.c::ssp_probe() */
+void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
+{
+ struct platform_device *pd;
+
+ pd = platform_device_alloc("pxa2xx-spi", id);
+ if (pd == NULL) {
+ printk(KERN_ERR "pxa2xx-spi: failed to allocate device id %d\n",
+ id);
+ return;
+ }
+
+ pd->dev.platform_data = info;
+ platform_device_add(pd);
+}
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
new file mode 100644
index 00000000..2fd5a8b3
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.h
@@ -0,0 +1,48 @@
+extern struct platform_device pxa_device_pmu;
+extern struct platform_device pxa_device_mci;
+extern struct platform_device pxa3xx_device_mci2;
+extern struct platform_device pxa3xx_device_mci3;
+extern struct platform_device pxa25x_device_udc;
+extern struct platform_device pxa27x_device_udc;
+extern struct platform_device pxa3xx_device_u2d;
+extern struct platform_device pxa_device_fb;
+extern struct platform_device pxa_device_ffuart;
+extern struct platform_device pxa_device_btuart;
+extern struct platform_device pxa_device_stuart;
+extern struct platform_device pxa_device_hwuart;
+extern struct platform_device pxa_device_i2c;
+extern struct platform_device pxa_device_i2s;
+extern struct platform_device pxa_device_ficp;
+extern struct platform_device sa1100_device_rtc;
+extern struct platform_device pxa_device_rtc;
+extern struct platform_device pxa_device_ac97;
+
+extern struct platform_device pxa27x_device_i2c_power;
+extern struct platform_device pxa27x_device_ohci;
+extern struct platform_device pxa27x_device_keypad;
+
+extern struct platform_device pxa25x_device_ssp;
+extern struct platform_device pxa25x_device_nssp;
+extern struct platform_device pxa25x_device_assp;
+extern struct platform_device pxa27x_device_ssp1;
+extern struct platform_device pxa27x_device_ssp2;
+extern struct platform_device pxa27x_device_ssp3;
+extern struct platform_device pxa3xx_device_ssp4;
+
+extern struct platform_device pxa25x_device_pwm0;
+extern struct platform_device pxa25x_device_pwm1;
+extern struct platform_device pxa27x_device_pwm0;
+extern struct platform_device pxa27x_device_pwm1;
+
+extern struct platform_device pxa3xx_device_nand;
+extern struct platform_device pxa3xx_device_i2c_power;
+
+extern struct platform_device pxa3xx_device_gcu;
+
+extern struct platform_device pxa_device_asoc_platform;
+extern struct platform_device pxa_device_asoc_ssp1;
+extern struct platform_device pxa_device_asoc_ssp2;
+extern struct platform_device pxa_device_asoc_ssp3;
+extern struct platform_device pxa_device_asoc_ssp4;
+
+void __init pxa_register_device(struct platform_device *dev, void *data);
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
new file mode 100644
index 00000000..f8a6e9d7
--- /dev/null
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -0,0 +1,1315 @@
+/*
+ * Support for CompuLab EM-X270 platform
+ *
+ * Copyright (C) 2007, 2008 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <linux/dm9000.h>
+#include <linux/rtc-v3020.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/mfd/da903x.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tdo24m.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/power_supply.h>
+#include <linux/apm-emulation.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/regulator/userspace-consumer.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/mmc.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/camera.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/* EM-X270 specific GPIOs */
+#define GPIO13_MMC_CD (13)
+#define GPIO95_MMC_WP (95)
+#define GPIO56_NAND_RB (56)
+#define GPIO93_CAM_RESET (93)
+#define GPIO16_USB_HUB_RESET (16)
+
+/* eXeda specific GPIOs */
+#define GPIO114_MMC_CD (114)
+#define GPIO20_NAND_RB (20)
+#define GPIO38_SD_PWEN (38)
+#define GPIO37_WLAN_RST (37)
+#define GPIO95_TOUCHPAD_INT (95)
+#define GPIO130_CAM_RESET (130)
+#define GPIO10_USB_HUB_RESET (10)
+
+/* common GPIOs */
+#define GPIO11_NAND_CS (11)
+#define GPIO41_ETHIRQ (41)
+#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
+#define GPIO115_WLAN_PWEN (115)
+#define GPIO19_WLAN_STRAP (19)
+#define GPIO9_USB_VBUS_EN (9)
+
+static int mmc_cd;
+static int nand_rb;
+static int dm9000_flags;
+static int cam_reset;
+static int usb_hub_reset;
+
+static unsigned long common_pin_config[] = {
+ /* AC'97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO98_AC97_SYSCLK,
+ GPIO113_AC97_nRESET,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* MCI controller */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* QCI */
+ GPIO84_CIF_FV,
+ GPIO25_CIF_LV,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO81_CIF_DD_0,
+ GPIO55_CIF_DD_1,
+ GPIO51_CIF_DD_2,
+ GPIO50_CIF_DD_3,
+ GPIO52_CIF_DD_4,
+ GPIO48_CIF_DD_5,
+ GPIO17_CIF_DD_6,
+ GPIO12_CIF_DD_7,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* Keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+ GPIO96_KP_MKOUT_6,
+ GPIO22_KP_MKOUT_7,
+
+ /* SSP1 */
+ GPIO26_SSP1_RXD,
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO57_SSP1_TXD,
+
+ /* SSP2 */
+ GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */
+ GPIO14_GPIO,
+ GPIO89_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+
+ /* SDRAM and local bus */
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+ GPIO49_nPWE,
+ GPIO18_RDY,
+
+ /* GPIO */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */
+
+ /* power controls */
+ GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
+ GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */
+
+ /* NAND controls */
+ GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
+
+ /* interrupts */
+ GPIO41_GPIO, /* DM9000 interrupt */
+};
+
+static unsigned long em_x270_pin_config[] = {
+ GPIO13_GPIO, /* MMC card detect */
+ GPIO16_GPIO, /* USB hub reset */
+ GPIO56_GPIO, /* NAND Ready/Busy */
+ GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */
+ GPIO95_GPIO, /* MMC Write protect */
+};
+
+static unsigned long exeda_pin_config[] = {
+ GPIO10_GPIO, /* USB hub reset */
+ GPIO20_GPIO, /* NAND Ready/Busy */
+ GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */
+ GPIO95_GPIO, /* touchpad IRQ */
+ GPIO114_GPIO, /* MMC card detect */
+};
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource em_x270_dm9000_resource[] = {
+ [0] = {
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS2_PHYS + 8,
+ .end = PXA_CS2_PHYS + 8 + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = EM_X270_ETHIRQ,
+ .end = EM_X270_ETHIRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data em_x270_dm9000_platdata = {
+ .flags = DM9000_PLATF_NO_EEPROM,
+};
+
+static struct platform_device em_x270_dm9000 = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(em_x270_dm9000_resource),
+ .resource = em_x270_dm9000_resource,
+ .dev = {
+ .platform_data = &em_x270_dm9000_platdata,
+ }
+};
+
+static void __init em_x270_init_dm9000(void)
+{
+ em_x270_dm9000_platdata.flags |= dm9000_flags;
+ platform_device_register(&em_x270_dm9000);
+}
+#else
+static inline void em_x270_init_dm9000(void) {}
+#endif
+
+/* V3020 RTC */
+#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
+static struct resource em_x270_v3020_resource[] = {
+ [0] = {
+ .start = PXA_CS4_PHYS,
+ .end = PXA_CS4_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct v3020_platform_data em_x270_v3020_platdata = {
+ .leftshift = 0,
+};
+
+static struct platform_device em_x270_rtc = {
+ .name = "v3020",
+ .num_resources = ARRAY_SIZE(em_x270_v3020_resource),
+ .resource = em_x270_v3020_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &em_x270_v3020_platdata,
+ }
+};
+
+static void __init em_x270_init_rtc(void)
+{
+ platform_device_register(&em_x270_rtc);
+}
+#else
+static inline void em_x270_init_rtc(void) {}
+#endif
+
+/* NAND flash */
+#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+static inline void nand_cs_on(void)
+{
+ gpio_set_value(GPIO11_NAND_CS, 0);
+}
+
+static void nand_cs_off(void)
+{
+ dsb();
+
+ gpio_set_value(GPIO11_NAND_CS, 1);
+}
+
+/* hardware specific access to control-lines */
+static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+ dsb();
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_ALE)
+ nandaddr |= (1 << 3);
+ else
+ nandaddr &= ~(1 << 3);
+ if (ctrl & NAND_CLE)
+ nandaddr |= (1 << 2);
+ else
+ nandaddr &= ~(1 << 2);
+ if (ctrl & NAND_NCE)
+ nand_cs_on();
+ else
+ nand_cs_off();
+ }
+
+ dsb();
+ this->IO_ADDR_W = (void __iomem *)nandaddr;
+ if (dat != NAND_CMD_NONE)
+ writel(dat, this->IO_ADDR_W);
+
+ dsb();
+}
+
+/* read device ready pin */
+static int em_x270_nand_device_ready(struct mtd_info *mtd)
+{
+ dsb();
+
+ return gpio_get_value(nand_rb);
+}
+
+static struct mtd_partition em_x270_partition_info[] = {
+ [0] = {
+ .name = "em_x270-0",
+ .offset = 0,
+ .size = SZ_4M,
+ },
+ [1] = {
+ .name = "em_x270-1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data em_x270_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(em_x270_partition_info),
+ .partitions = em_x270_partition_info,
+ .chip_delay = 20,
+ .part_probe_types = em_x270_part_probes,
+ },
+ .ctrl = {
+ .hwcontrol = 0,
+ .dev_ready = em_x270_nand_device_ready,
+ .select_chip = 0,
+ .cmd_ctrl = em_x270_nand_cmd_ctl,
+ },
+};
+
+static struct resource em_x270_nand_resource[] = {
+ [0] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + 12,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device em_x270_nand = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(em_x270_nand_resource),
+ .resource = em_x270_nand_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &em_x270_nand_platdata,
+ }
+};
+
+static void __init em_x270_init_nand(void)
+{
+ int err;
+
+ err = gpio_request(GPIO11_NAND_CS, "NAND CS");
+ if (err) {
+ pr_warning("EM-X270: failed to request NAND CS gpio\n");
+ return;
+ }
+
+ gpio_direction_output(GPIO11_NAND_CS, 1);
+
+ err = gpio_request(nand_rb, "NAND R/B");
+ if (err) {
+ pr_warning("EM-X270: failed to request NAND R/B gpio\n");
+ gpio_free(GPIO11_NAND_CS);
+ return;
+ }
+
+ gpio_direction_input(nand_rb);
+
+ platform_device_register(&em_x270_nand);
+}
+#else
+static inline void em_x270_init_nand(void) {}
+#endif
+
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition em_x270_nor_parts[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000,
+ .size = 0x00050000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Environment",
+ .offset = 0x00050000,
+ .size = 0x00010000,
+ }, {
+ .name = "Reserved",
+ .offset = 0x00060000,
+ .size = 0x00050000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Splashscreen",
+ .offset = 0x000b0000,
+ .size = 0x00050000,
+ }
+};
+
+static struct physmap_flash_data em_x270_nor_data[] = {
+ [0] = {
+ .width = 2,
+ .parts = em_x270_nor_parts,
+ .nr_parts = ARRAY_SIZE(em_x270_nor_parts),
+ },
+};
+
+static struct resource em_x270_nor_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device em_x270_physmap_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &em_x270_nor_flash_resource,
+ .dev = {
+ .platform_data = &em_x270_nor_data,
+ },
+};
+
+static void __init em_x270_init_nor(void)
+{
+ platform_device_register(&em_x270_physmap_flash);
+}
+#else
+static inline void em_x270_init_nor(void) {}
+#endif
+
+/* PXA27x OHCI controller setup */
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct regulator *em_x270_usb_ldo;
+
+static int em_x270_usb_hub_init(void)
+{
+ int err;
+
+ em_x270_usb_ldo = regulator_get(NULL, "vcc usb");
+ if (IS_ERR(em_x270_usb_ldo))
+ return PTR_ERR(em_x270_usb_ldo);
+
+ err = gpio_request(GPIO9_USB_VBUS_EN, "vbus en");
+ if (err)
+ goto err_free_usb_ldo;
+
+ err = gpio_request(usb_hub_reset, "hub rst");
+ if (err)
+ goto err_free_vbus_gpio;
+
+ /* USB Hub power-on and reset */
+ gpio_direction_output(usb_hub_reset, 1);
+ gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
+ regulator_enable(em_x270_usb_ldo);
+ gpio_set_value(usb_hub_reset, 0);
+ gpio_set_value(usb_hub_reset, 1);
+ regulator_disable(em_x270_usb_ldo);
+ regulator_enable(em_x270_usb_ldo);
+ gpio_set_value(usb_hub_reset, 0);
+ gpio_set_value(GPIO9_USB_VBUS_EN, 1);
+
+ return 0;
+
+err_free_vbus_gpio:
+ gpio_free(GPIO9_USB_VBUS_EN);
+err_free_usb_ldo:
+ regulator_put(em_x270_usb_ldo);
+
+ return err;
+}
+
+static int em_x270_ohci_init(struct device *dev)
+{
+ int err;
+
+ /* we don't want to entirely disable USB if the HUB init failed */
+ err = em_x270_usb_hub_init();
+ if (err)
+ pr_err("USB Hub initialization failed: %d\n", err);
+
+ /* enable port 2 transiever */
+ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
+
+ return 0;
+}
+
+static void em_x270_ohci_exit(struct device *dev)
+{
+ gpio_free(usb_hub_reset);
+ gpio_free(GPIO9_USB_VBUS_EN);
+
+ if (!IS_ERR(em_x270_usb_ldo)) {
+ if (regulator_is_enabled(em_x270_usb_ldo))
+ regulator_disable(em_x270_usb_ldo);
+
+ regulator_put(em_x270_usb_ldo);
+ }
+}
+
+static struct pxaohci_platform_data em_x270_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
+ .init = em_x270_ohci_init,
+ .exit = em_x270_ohci_exit,
+};
+
+static void __init em_x270_init_ohci(void)
+{
+ pxa_set_ohci_info(&em_x270_ohci_platform_data);
+}
+#else
+static inline void em_x270_init_ohci(void) {}
+#endif
+
+/* MCI controller setup */
+#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
+static struct regulator *em_x270_sdio_ldo;
+
+static int em_x270_mci_init(struct device *dev,
+ irq_handler_t em_x270_detect_int,
+ void *data)
+{
+ int err;
+
+ em_x270_sdio_ldo = regulator_get(dev, "vcc sdio");
+ if (IS_ERR(em_x270_sdio_ldo)) {
+ dev_err(dev, "can't request SDIO power supply: %ld\n",
+ PTR_ERR(em_x270_sdio_ldo));
+ return PTR_ERR(em_x270_sdio_ldo);
+ }
+
+ err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "MMC card detect", data);
+ if (err) {
+ dev_err(dev, "can't request MMC card detect IRQ: %d\n", err);
+ goto err_irq;
+ }
+
+ if (machine_is_em_x270()) {
+ err = gpio_request(GPIO95_MMC_WP, "MMC WP");
+ if (err) {
+ dev_err(dev, "can't request MMC write protect: %d\n",
+ err);
+ goto err_gpio_wp;
+ }
+ gpio_direction_input(GPIO95_MMC_WP);
+ } else {
+ err = gpio_request(GPIO38_SD_PWEN, "sdio power");
+ if (err) {
+ dev_err(dev, "can't request MMC power control : %d\n",
+ err);
+ goto err_gpio_wp;
+ }
+ gpio_direction_output(GPIO38_SD_PWEN, 1);
+ }
+
+ return 0;
+
+err_gpio_wp:
+ free_irq(gpio_to_irq(mmc_cd), data);
+err_irq:
+ regulator_put(em_x270_sdio_ldo);
+
+ return err;
+}
+
+static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask) {
+ int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
+
+ regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
+ regulator_enable(em_x270_sdio_ldo);
+ } else {
+ regulator_disable(em_x270_sdio_ldo);
+ }
+}
+
+static void em_x270_mci_exit(struct device *dev, void *data)
+{
+ free_irq(gpio_to_irq(mmc_cd), data);
+ regulator_put(em_x270_sdio_ldo);
+
+ if (machine_is_em_x270())
+ gpio_free(GPIO95_MMC_WP);
+ else
+ gpio_free(GPIO38_SD_PWEN);
+}
+
+static int em_x270_mci_get_ro(struct device *dev)
+{
+ return gpio_get_value(GPIO95_MMC_WP);
+}
+
+static struct pxamci_platform_data em_x270_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
+ MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
+ MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
+ MMC_VDD_30_31|MMC_VDD_31_32,
+ .init = em_x270_mci_init,
+ .setpower = em_x270_mci_setpower,
+ .exit = em_x270_mci_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void __init em_x270_init_mmc(void)
+{
+ if (machine_is_em_x270())
+ em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
+
+ pxa_set_mci_info(&em_x270_mci_platform_data);
+}
+#else
+static inline void em_x270_init_mmc(void) {}
+#endif
+
+/* LCD */
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info em_x270_lcd_modes[] = {
+ [0] = {
+ .pixclock = 38250,
+ .bpp = 16,
+ .xres = 480,
+ .yres = 640,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 24,
+ .lower_margin = 4,
+ .sync = 0,
+ },
+ [1] = {
+ .pixclock = 153800,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 2,
+ .right_margin = 88,
+ .lower_margin = 2,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info em_x270_lcd = {
+ .modes = em_x270_lcd_modes,
+ .num_modes = 2,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+};
+
+static void __init em_x270_init_lcd(void)
+{
+ pxa_set_fb_info(NULL, &em_x270_lcd);
+}
+#else
+static inline void em_x270_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master em_x270_spi_info = {
+ .num_chipselect = 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_tdo24m_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .gpio_cs = -1,
+};
+
+static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
+ .model = TDO35S,
+};
+
+static struct pxa2xx_spi_master em_x270_spi_2_info = {
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+static struct pxa2xx_spi_chip em_x270_libertas_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .timeout = 1000,
+ .gpio_cs = 14,
+};
+
+static unsigned long em_x270_libertas_pin_config[] = {
+ /* SSP2 */
+ GPIO19_SSP2_SCLK,
+ GPIO14_GPIO,
+ GPIO89_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+};
+
+static int em_x270_libertas_setup(struct spi_device *spi)
+{
+ int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN");
+ if (err)
+ return err;
+
+ err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP");
+ if (err)
+ goto err_free_pwen;
+
+ if (machine_is_exeda()) {
+ err = gpio_request(GPIO37_WLAN_RST, "WLAN RST");
+ if (err)
+ goto err_free_strap;
+
+ gpio_direction_output(GPIO37_WLAN_RST, 1);
+ msleep(100);
+ }
+
+ gpio_direction_output(GPIO19_WLAN_STRAP, 1);
+ msleep(100);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config));
+
+ gpio_direction_output(GPIO115_WLAN_PWEN, 0);
+ msleep(100);
+ gpio_set_value(GPIO115_WLAN_PWEN, 1);
+ msleep(100);
+
+ spi->bits_per_word = 16;
+ spi_setup(spi);
+
+ return 0;
+
+err_free_strap:
+ gpio_free(GPIO19_WLAN_STRAP);
+err_free_pwen:
+ gpio_free(GPIO115_WLAN_PWEN);
+
+ return err;
+}
+
+static int em_x270_libertas_teardown(struct spi_device *spi)
+{
+ gpio_set_value(GPIO115_WLAN_PWEN, 0);
+ gpio_free(GPIO115_WLAN_PWEN);
+ gpio_free(GPIO19_WLAN_STRAP);
+
+ if (machine_is_exeda()) {
+ gpio_set_value(GPIO37_WLAN_RST, 0);
+ gpio_free(GPIO37_WLAN_RST);
+ }
+
+ return 0;
+}
+
+struct libertas_spi_platform_data em_x270_libertas_pdata = {
+ .use_dummy_writes = 1,
+ .setup = em_x270_libertas_setup,
+ .teardown = em_x270_libertas_teardown,
+};
+
+static struct spi_board_info em_x270_spi_devices[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .max_speed_hz = 1000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .controller_data = &em_x270_tdo24m_chip,
+ .platform_data = &em_x270_tdo24m_pdata,
+ },
+ {
+ .modalias = "libertas_spi",
+ .max_speed_hz = 13000000,
+ .bus_num = 2,
+ .irq = IRQ_GPIO(116),
+ .chip_select = 0,
+ .controller_data = &em_x270_libertas_chip,
+ .platform_data = &em_x270_libertas_pdata,
+ },
+};
+
+static void __init em_x270_init_spi(void)
+{
+ pxa2xx_set_spi_info(1, &em_x270_spi_info);
+ pxa2xx_set_spi_info(2, &em_x270_spi_2_info);
+ spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices));
+}
+#else
+static inline void em_x270_init_spi(void) {}
+#endif
+
+#if defined(CONFIG_SND_PXA2XX_LIB_AC97)
+static pxa2xx_audio_ops_t em_x270_ac97_info = {
+ .reset_gpio = 113,
+};
+
+static void __init em_x270_init_ac97(void)
+{
+ pxa_set_ac97_info(&em_x270_ac97_info);
+}
+#else
+static inline void em_x270_init_ac97(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int em_x270_module_matrix_keys[] = {
+ KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
+ KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
+ KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
+};
+
+struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
+ /* code map for the matrix keys */
+ .matrix_key_rows = 3,
+ .matrix_key_cols = 3,
+ .matrix_key_map = em_x270_module_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(em_x270_module_matrix_keys),
+};
+
+static unsigned int em_x270_exeda_matrix_keys[] = {
+ KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
+ KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
+ KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
+ KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH),
+
+ KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M),
+ KEY(1, 2, KEY_N), KEY(1, 3, KEY_B),
+ KEY(1, 4, KEY_V), KEY(1, 5, KEY_C),
+ KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z),
+
+ KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON),
+ KEY(2, 2, KEY_L), KEY(2, 3, KEY_K),
+ KEY(2, 4, KEY_J), KEY(2, 5, KEY_H),
+ KEY(2, 6, KEY_G), KEY(2, 7, KEY_F),
+
+ KEY(3, 0, KEY_D), KEY(3, 1, KEY_S),
+ KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB),
+ KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P),
+ KEY(3, 6, KEY_O), KEY(3, 7, KEY_I),
+
+ KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y),
+ KEY(4, 2, KEY_T), KEY(4, 3, KEY_R),
+ KEY(4, 4, KEY_E), KEY(4, 5, KEY_W),
+ KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS),
+
+ KEY(5, 0, KEY_0), KEY(5, 1, KEY_9),
+ KEY(5, 2, KEY_8), KEY(5, 3, KEY_7),
+ KEY(5, 4, KEY_6), KEY(5, 5, KEY_5),
+ KEY(5, 6, KEY_4), KEY(5, 7, KEY_3),
+
+ KEY(6, 0, KEY_2), KEY(6, 1, KEY_1),
+ KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END),
+ KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP),
+ KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1),
+
+ KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT),
+ KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME),
+ KEY(7, 4, 0), KEY(7, 5, 0),
+ KEY(7, 6, 0), KEY(7, 7, 0),
+};
+
+struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
+ /* code map for the matrix keys */
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 8,
+ .matrix_key_map = em_x270_exeda_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(em_x270_exeda_matrix_keys),
+};
+
+static void __init em_x270_init_keypad(void)
+{
+ if (machine_is_em_x270())
+ pxa_set_keypad_info(&em_x270_module_keypad_info);
+ else
+ pxa_set_keypad_info(&em_x270_exeda_keypad_info);
+}
+#else
+static inline void em_x270_init_keypad(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button gpio_keys_button[] = {
+ [0] = {
+ .desc = "sleep/wakeup",
+ .code = KEY_SUSPEND,
+ .type = EV_PWR,
+ .gpio = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
+ .buttons = gpio_keys_button,
+ .nbuttons = 1,
+};
+
+static struct platform_device em_x270_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &em_x270_gpio_keys_data,
+ },
+};
+
+static void __init em_x270_init_gpio_keys(void)
+{
+ platform_device_register(&em_x270_gpio_keys);
+}
+#else
+static inline void em_x270_init_gpio_keys(void) {}
+#endif
+
+/* Quick Capture Interface and sensor setup */
+#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+static struct regulator *em_x270_camera_ldo;
+
+static int em_x270_sensor_init(void)
+{
+ int ret;
+
+ ret = gpio_request(cam_reset, "camera reset");
+ if (ret)
+ return ret;
+
+ gpio_direction_output(cam_reset, 0);
+
+ em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
+ if (em_x270_camera_ldo == NULL) {
+ gpio_free(cam_reset);
+ return -ENODEV;
+ }
+
+ ret = regulator_enable(em_x270_camera_ldo);
+ if (ret) {
+ regulator_put(em_x270_camera_ldo);
+ gpio_free(cam_reset);
+ return ret;
+ }
+
+ gpio_set_value(cam_reset, 1);
+
+ return 0;
+}
+
+struct pxacamera_platform_data em_x270_camera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 2600,
+};
+
+static int em_x270_sensor_power(struct device *dev, int on)
+{
+ int ret;
+ int is_on = regulator_is_enabled(em_x270_camera_ldo);
+
+ if (on == is_on)
+ return 0;
+
+ gpio_set_value(cam_reset, !on);
+
+ if (on)
+ ret = regulator_enable(em_x270_camera_ldo);
+ else
+ ret = regulator_disable(em_x270_camera_ldo);
+
+ if (ret)
+ return ret;
+
+ gpio_set_value(cam_reset, on);
+
+ return 0;
+}
+
+static struct i2c_board_info em_x270_i2c_cam_info[] = {
+ {
+ I2C_BOARD_INFO("mt9m111", 0x48),
+ },
+};
+
+static struct soc_camera_link iclink = {
+ .bus_id = 0,
+ .power = em_x270_sensor_power,
+ .board_info = &em_x270_i2c_cam_info[0],
+ .i2c_adapter_id = 0,
+};
+
+static struct platform_device em_x270_camera = {
+ .name = "soc-camera-pdrv",
+ .id = -1,
+ .dev = {
+ .platform_data = &iclink,
+ },
+};
+
+static void __init em_x270_init_camera(void)
+{
+ if (em_x270_sensor_init() == 0) {
+ pxa_set_camera_info(&em_x270_camera_platform_data);
+ platform_device_register(&em_x270_camera);
+ }
+}
+#else
+static inline void em_x270_init_camera(void) {}
+#endif
+
+static struct regulator_bulk_data em_x270_gps_consumer_supply = {
+ .supply = "vcc gps",
+};
+
+static struct regulator_userspace_consumer_data em_x270_gps_consumer_data = {
+ .name = "vcc gps",
+ .num_supplies = 1,
+ .supplies = &em_x270_gps_consumer_supply,
+};
+
+static struct platform_device em_x270_gps_userspace_consumer = {
+ .name = "reg-userspace-consumer",
+ .id = 0,
+ .dev = {
+ .platform_data = &em_x270_gps_consumer_data,
+ },
+};
+
+static struct regulator_bulk_data em_x270_gprs_consumer_supply = {
+ .supply = "vcc gprs",
+};
+
+static struct regulator_userspace_consumer_data em_x270_gprs_consumer_data = {
+ .name = "vcc gprs",
+ .num_supplies = 1,
+ .supplies = &em_x270_gprs_consumer_supply
+};
+
+static struct platform_device em_x270_gprs_userspace_consumer = {
+ .name = "reg-userspace-consumer",
+ .id = 1,
+ .dev = {
+ .platform_data = &em_x270_gprs_consumer_data,
+ }
+};
+
+static struct platform_device *em_x270_userspace_consumers[] = {
+ &em_x270_gps_userspace_consumer,
+ &em_x270_gprs_userspace_consumer,
+};
+
+static void __init em_x270_userspace_consumers_init(void)
+{
+ platform_add_devices(ARRAY_AND_SIZE(em_x270_userspace_consumers));
+}
+
+/* DA9030 related initializations */
+#define REGULATOR_CONSUMER(_name, _dev, _supply) \
+ static struct regulator_consumer_supply _name##_consumers[] = { \
+ { \
+ .dev = _dev, \
+ .supply = _supply, \
+ }, \
+ }
+
+REGULATOR_CONSUMER(ldo3, &em_x270_gps_userspace_consumer.dev, "vcc gps");
+REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
+REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio");
+REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
+REGULATOR_CONSUMER(ldo19, &em_x270_gprs_userspace_consumer.dev, "vcc gprs");
+REGULATOR_CONSUMER(buck2, NULL, "vcc_core");
+
+#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \
+ static struct regulator_init_data _ldo##_data = { \
+ .constraints = { \
+ .min_uV = _min_uV, \
+ .max_uV = _max_uV, \
+ .state_mem = { \
+ .enabled = 0, \
+ }, \
+ .valid_ops_mask = _ops_mask, \
+ .apply_uV = 1, \
+ }, \
+ .num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \
+ .consumer_supplies = _ldo##_consumers, \
+ };
+
+REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo10, 2000000, 3200000,
+ REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE);
+REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
+REGULATOR_INIT(buck2, 1000000, 1650000, REGULATOR_CHANGE_VOLTAGE);
+
+struct led_info em_x270_led_info = {
+ .name = "em-x270:orange",
+ .default_trigger = "battery-charging-or-full",
+};
+
+struct power_supply_info em_x270_psy_info = {
+ .name = "battery",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .voltage_max_design = 4200000,
+ .voltage_min_design = 3000000,
+ .use_for_apm = 1,
+};
+
+static void em_x270_battery_low(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+ apm_queue_event(APM_LOW_BATTERY);
+#endif
+}
+
+static void em_x270_battery_critical(void)
+{
+#if defined(CONFIG_APM_EMULATION)
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+#endif
+}
+
+struct da9030_battery_info em_x270_batterty_info = {
+ .battery_info = &em_x270_psy_info,
+
+ .charge_milliamp = 1000,
+ .charge_millivolt = 4200,
+
+ .vbat_low = 3600,
+ .vbat_crit = 3400,
+ .vbat_charge_start = 4100,
+ .vbat_charge_stop = 4200,
+ .vbat_charge_restart = 4000,
+
+ .vcharge_min = 3200,
+ .vcharge_max = 5500,
+
+ .tbat_low = 197,
+ .tbat_high = 78,
+ .tbat_restart = 100,
+
+ .batmon_interval = 0,
+
+ .battery_low = em_x270_battery_low,
+ .battery_critical = em_x270_battery_critical,
+};
+
+#define DA9030_SUBDEV(_name, _id, _pdata) \
+ { \
+ .name = "da903x-" #_name, \
+ .id = DA9030_ID_##_id, \
+ .platform_data = _pdata, \
+ }
+
+#define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data)
+
+struct da903x_subdev_info em_x270_da9030_subdevs[] = {
+ DA9030_LDO(3),
+ DA9030_LDO(5),
+ DA9030_LDO(10),
+ DA9030_LDO(12),
+ DA9030_LDO(19),
+
+ DA9030_SUBDEV(regulator, BUCK2, &buck2_data),
+
+ DA9030_SUBDEV(led, LED_PC, &em_x270_led_info),
+ DA9030_SUBDEV(backlight, WLED, &em_x270_led_info),
+ DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info),
+};
+
+static struct da903x_platform_data em_x270_da9030_info = {
+ .num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs),
+ .subdevs = em_x270_da9030_subdevs,
+};
+
+static struct i2c_board_info em_x270_i2c_pmic_info = {
+ I2C_BOARD_INFO("da9030", 0x49),
+ .irq = IRQ_GPIO(0),
+ .platform_data = &em_x270_da9030_info,
+};
+
+static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = {
+ .use_pio = 1,
+};
+
+static void __init em_x270_init_da9030(void)
+{
+ pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info);
+ i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1);
+}
+
+static struct pca953x_platform_data exeda_gpio_ext_pdata = {
+ .gpio_base = 128,
+};
+
+static struct i2c_board_info exeda_i2c_info[] = {
+ {
+ I2C_BOARD_INFO("pca9555", 0x21),
+ .platform_data = &exeda_gpio_ext_pdata,
+ },
+};
+
+static struct i2c_pxa_platform_data em_x270_i2c_info = {
+ .fast_mode = 1,
+};
+
+static void __init em_x270_init_i2c(void)
+{
+ pxa_set_i2c_info(&em_x270_i2c_info);
+
+ if (machine_is_exeda())
+ i2c_register_board_info(0, ARRAY_AND_SIZE(exeda_i2c_info));
+}
+
+static void __init em_x270_module_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
+
+ mmc_cd = GPIO13_MMC_CD;
+ nand_rb = GPIO56_NAND_RB;
+ dm9000_flags = DM9000_PLATF_32BITONLY;
+ cam_reset = GPIO93_CAM_RESET;
+ usb_hub_reset = GPIO16_USB_HUB_RESET;
+}
+
+static void __init em_x270_exeda_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config));
+
+ mmc_cd = GPIO114_MMC_CD;
+ nand_rb = GPIO20_NAND_RB;
+ dm9000_flags = DM9000_PLATF_16BITONLY;
+ cam_reset = GPIO130_CAM_RESET;
+ usb_hub_reset = GPIO10_USB_HUB_RESET;
+}
+
+static void __init em_x270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+#ifdef CONFIG_PM
+ pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
+#endif
+
+ if (machine_is_em_x270())
+ em_x270_module_init();
+ else if (machine_is_exeda())
+ em_x270_exeda_init();
+ else
+ panic("Unsupported machine: %d\n", machine_arch_type);
+
+ em_x270_init_da9030();
+ em_x270_init_dm9000();
+ em_x270_init_rtc();
+ em_x270_init_nand();
+ em_x270_init_nor();
+ em_x270_init_lcd();
+ em_x270_init_mmc();
+ em_x270_init_ohci();
+ em_x270_init_keypad();
+ em_x270_init_gpio_keys();
+ em_x270_init_ac97();
+ em_x270_init_spi();
+ em_x270_init_i2c();
+ em_x270_init_camera();
+ em_x270_userspace_consumers_init();
+}
+
+MACHINE_START(EM_X270, "Compulab EM-X270")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = em_x270_init,
+MACHINE_END
+
+MACHINE_START(EXEDA, "Compulab eXeda")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = em_x270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
new file mode 100644
index 00000000..2e3970fd
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.c
@@ -0,0 +1,954 @@
+/*
+ * Hardware definitions for the Toshiba eseries PDAs
+ *
+ * Copyright (c) 2003 Ian Molton <spyro@f2s.com>
+ *
+ * This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/tc6387xb.h>
+#include <linux/mfd/tc6393xb.h>
+#include <linux/mfd/t7l66xb.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/pxa25x.h>
+#include <mach/eseries-gpio.h>
+#include <mach/eseries-irq.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/udc.h>
+#include <mach/irda.h>
+
+#include "devices.h"
+#include "generic.h"
+#include "clock.h"
+
+/* Only e800 has 128MB RAM */
+void __init eseries_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xa0000000;
+ if (machine_is_e800())
+ mi->bank[0].size = (128*1024*1024);
+ else
+ mi->bank[0].size = (64*1024*1024);
+}
+
+struct gpio_vbus_mach_info e7xx_udc_info = {
+ .gpio_vbus = GPIO_E7XX_USB_DISC,
+ .gpio_pullup = GPIO_E7XX_USB_PULLUP,
+ .gpio_pullup_inverted = 1
+};
+
+static struct platform_device e7xx_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &e7xx_udc_info,
+ },
+};
+
+struct pxaficp_platform_data e7xx_ficp_platform_data = {
+ .gpio_pwdown = GPIO_E7XX_IR_OFF,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+int eseries_tmio_enable(struct platform_device *dev)
+{
+ /* Reset - bring SUSPEND high before PCLR */
+ gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
+ gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
+ msleep(1);
+ gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
+ msleep(1);
+ gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 1);
+ msleep(1);
+ return 0;
+}
+
+int eseries_tmio_disable(struct platform_device *dev)
+{
+ gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
+ gpio_set_value(GPIO_ESERIES_TMIO_PCLR, 0);
+ return 0;
+}
+
+int eseries_tmio_suspend(struct platform_device *dev)
+{
+ gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 0);
+ return 0;
+}
+
+int eseries_tmio_resume(struct platform_device *dev)
+{
+ gpio_set_value(GPIO_ESERIES_TMIO_SUSPEND, 1);
+ msleep(1);
+ return 0;
+}
+
+void eseries_get_tmio_gpios(void)
+{
+ gpio_request(GPIO_ESERIES_TMIO_SUSPEND, NULL);
+ gpio_request(GPIO_ESERIES_TMIO_PCLR, NULL);
+ gpio_direction_output(GPIO_ESERIES_TMIO_SUSPEND, 0);
+ gpio_direction_output(GPIO_ESERIES_TMIO_PCLR, 0);
+}
+
+/* TMIO controller uses the same resources on all e-series machines. */
+struct resource eseries_tmio_resources[] = {
+ [0] = {
+ .start = PXA_CS4_PHYS,
+ .end = PXA_CS4_PHYS + 0x1fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ),
+ .end = IRQ_GPIO(GPIO_ESERIES_TMIO_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Some e-series hardware cannot control the 32K clock */
+static void clk_32k_dummy(struct clk *clk)
+{
+}
+
+static const struct clkops clk_32k_dummy_ops = {
+ .enable = clk_32k_dummy,
+ .disable = clk_32k_dummy,
+};
+
+static struct clk tmio_dummy_clk = {
+ .ops = &clk_32k_dummy_ops,
+ .rate = 32768,
+};
+
+static struct clk_lookup eseries_clkregs[] = {
+ INIT_CLKREG(&tmio_dummy_clk, NULL, "CLK_CK32K"),
+};
+
+void eseries_register_clks(void)
+{
+ clkdev_add_table(eseries_clkregs, ARRAY_SIZE(eseries_clkregs));
+}
+
+#ifdef CONFIG_MACH_E330
+/* -------------------- e330 tc6387xb parameters -------------------- */
+
+static struct tc6387xb_platform_data e330_tc6387xb_info = {
+ .enable = &eseries_tmio_enable,
+ .disable = &eseries_tmio_disable,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+};
+
+static struct platform_device e330_tc6387xb_device = {
+ .name = "tc6387xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e330_tc6387xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* --------------------------------------------------------------- */
+
+static struct platform_device *e330_devices[] __initdata = {
+ &e330_tc6387xb_device,
+ &e7xx_gpio_vbus,
+};
+
+static void __init e330_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ eseries_register_clks();
+ eseries_get_tmio_gpios();
+ platform_add_devices(ARRAY_AND_SIZE(e330_devices));
+}
+
+MACHINE_START(E330, "Toshiba e330")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e330_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E350
+/* -------------------- e350 t7l66xb parameters -------------------- */
+
+static struct t7l66xb_platform_data e350_t7l66xb_info = {
+ .irq_base = IRQ_BOARD_START,
+ .enable = &eseries_tmio_enable,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+};
+
+static struct platform_device e350_t7l66xb_device = {
+ .name = "t7l66xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e350_t7l66xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* ---------------------------------------------------------- */
+
+static struct platform_device *e350_devices[] __initdata = {
+ &e350_t7l66xb_device,
+ &e7xx_gpio_vbus,
+};
+
+static void __init e350_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ eseries_register_clks();
+ eseries_get_tmio_gpios();
+ platform_add_devices(ARRAY_AND_SIZE(e350_devices));
+}
+
+MACHINE_START(E350, "Toshiba e350")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e350_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E400
+/* ------------------------ E400 LCD definitions ------------------------ */
+
+static struct pxafb_mode_info e400_pxafb_mode_info = {
+ .pixclock = 140703,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 28,
+ .right_margin = 8,
+ .vsync_len = 3,
+ .upper_margin = 5,
+ .lower_margin = 6,
+ .sync = 0,
+};
+
+static struct pxafb_mach_info e400_pxafb_mach_info = {
+ .modes = &e400_pxafb_mode_info,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+ .lccr3 = 0,
+ .pxafb_backlight_power = NULL,
+};
+
+/* ------------------------ E400 MFP config ----------------------------- */
+
+static unsigned long e400_pin_config[] __initdata = {
+ /* Chip selects */
+ GPIO15_nCS_1, /* CS1 - Flash */
+ GPIO80_nCS_4, /* CS4 - TMIO */
+
+ /* Clocks */
+ GPIO12_32KHz,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+
+ /* TMIO controller */
+ GPIO19_GPIO, /* t7l66xb #PCLR */
+ GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */
+
+ /* wakeup */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+/* ---------------------------------------------------------------------- */
+
+static struct mtd_partition partition_a = {
+ .name = "Internal NAND flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr e400_t7l66xb_nand_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 2,
+ .pattern = scan_ff_pattern
+};
+
+static struct tmio_nand_data e400_t7l66xb_nand_config = {
+ .num_partitions = 1,
+ .partition = &partition_a,
+ .badblock_pattern = &e400_t7l66xb_nand_bbt,
+};
+
+static struct t7l66xb_platform_data e400_t7l66xb_info = {
+ .irq_base = IRQ_BOARD_START,
+ .enable = &eseries_tmio_enable,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+
+ .nand_data = &e400_t7l66xb_nand_config,
+};
+
+static struct platform_device e400_t7l66xb_device = {
+ .name = "t7l66xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e400_t7l66xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* ---------------------------------------------------------- */
+
+static struct platform_device *e400_devices[] __initdata = {
+ &e400_t7l66xb_device,
+ &e7xx_gpio_vbus,
+};
+
+static void __init e400_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ /* Fixme - e400 may have a switched clock */
+ eseries_register_clks();
+ eseries_get_tmio_gpios();
+ pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
+ platform_add_devices(ARRAY_AND_SIZE(e400_devices));
+}
+
+MACHINE_START(E400, "Toshiba e400")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e400_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E740
+/* ------------------------ e740 video support --------------------------- */
+
+static struct w100_gen_regs e740_lcd_regs = {
+ .lcd_format = 0x00008023,
+ .lcdd_cntl1 = 0x0f000000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x00ffff03,
+ .genlcd_cntl2 = 0x003c0f03,
+ .genlcd_cntl3 = 0x000143aa,
+};
+
+static struct w100_mode e740_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 20,
+ .right_margin = 28,
+ .upper_margin = 9,
+ .lower_margin = 8,
+ .crtc_ss = 0x80140013,
+ .crtc_ls = 0x81150110,
+ .crtc_gs = 0x80050005,
+ .crtc_vpos_gs = 0x000a0009,
+ .crtc_rev = 0x0040010a,
+ .crtc_dclk = 0xa906000a,
+ .crtc_gclk = 0x80050108,
+ .crtc_goe = 0x80050108,
+ .pll_freq = 57,
+ .pixclk_divider = 4,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_XTAL,
+ .sysclk_divider = 1,
+ .sysclk_src = CLK_SRC_PLL,
+ .crtc_ps1_active = 0x41060010,
+};
+
+static struct w100_gpio_regs e740_w100_gpio_info = {
+ .init_data1 = 0x21002103,
+ .gpio_dir1 = 0xffffdeff,
+ .gpio_oe1 = 0x03c00643,
+ .init_data2 = 0x003f003f,
+ .gpio_dir2 = 0xffffffff,
+ .gpio_oe2 = 0x000000ff,
+};
+
+static struct w100fb_mach_info e740_fb_info = {
+ .modelist = &e740_lcd_mode,
+ .num_modes = 1,
+ .regs = &e740_lcd_regs,
+ .gpio = &e740_w100_gpio_info,
+ .xtal_freq = 14318000,
+ .xtal_dbl = 1,
+};
+
+static struct resource e740_fb_resources[] = {
+ [0] = {
+ .start = 0x0c000000,
+ .end = 0x0cffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device e740_fb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e740_fb_info,
+ },
+ .num_resources = ARRAY_SIZE(e740_fb_resources),
+ .resource = e740_fb_resources,
+};
+
+/* --------------------------- MFP Pin config -------------------------- */
+
+static unsigned long e740_pin_config[] __initdata = {
+ /* Chip selects */
+ GPIO15_nCS_1, /* CS1 - Flash */
+ GPIO79_nCS_3, /* CS3 - IMAGEON */
+ GPIO80_nCS_4, /* CS4 - TMIO */
+
+ /* Clocks */
+ GPIO12_32KHz,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+
+ /* TMIO controller */
+ GPIO19_GPIO, /* t7l66xb #PCLR */
+ GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */
+
+ /* UDC */
+ GPIO13_GPIO,
+ GPIO3_GPIO,
+
+ /* IrDA */
+ GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* Audio power control */
+ GPIO16_GPIO, /* AC97 codec AVDD2 supply (analogue power) */
+ GPIO40_GPIO, /* Mic amp power */
+ GPIO41_GPIO, /* Headphone amp power */
+
+ /* PC Card */
+ GPIO8_GPIO, /* CD0 */
+ GPIO44_GPIO, /* CD1 */
+ GPIO11_GPIO, /* IRQ0 */
+ GPIO6_GPIO, /* IRQ1 */
+ GPIO27_GPIO, /* RST0 */
+ GPIO24_GPIO, /* RST1 */
+ GPIO20_GPIO, /* PWR0 */
+ GPIO23_GPIO, /* PWR1 */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* wakeup */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+/* -------------------- e740 t7l66xb parameters -------------------- */
+
+static struct t7l66xb_platform_data e740_t7l66xb_info = {
+ .irq_base = IRQ_BOARD_START,
+ .enable = &eseries_tmio_enable,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+};
+
+static struct platform_device e740_t7l66xb_device = {
+ .name = "t7l66xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e740_t7l66xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *e740_devices[] __initdata = {
+ &e740_fb_device,
+ &e740_t7l66xb_device,
+ &e7xx_gpio_vbus,
+};
+
+static void __init e740_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ eseries_register_clks();
+ clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
+ "UDCCLK", &pxa25x_device_udc.dev),
+ eseries_get_tmio_gpios();
+ platform_add_devices(ARRAY_AND_SIZE(e740_devices));
+ pxa_set_ac97_info(NULL);
+ pxa_set_ficp_info(&e7xx_ficp_platform_data);
+}
+
+MACHINE_START(E740, "Toshiba e740")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e740_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E750
+/* ---------------------- E750 LCD definitions -------------------- */
+
+static struct w100_gen_regs e750_lcd_regs = {
+ .lcd_format = 0x00008003,
+ .lcdd_cntl1 = 0x00000000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x00fff003,
+ .genlcd_cntl2 = 0x003c0f03,
+ .genlcd_cntl3 = 0x000143aa,
+};
+
+static struct w100_mode e750_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 21,
+ .right_margin = 22,
+ .upper_margin = 5,
+ .lower_margin = 4,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0x8014000d,
+ .crtc_gs = 0xc1000005,
+ .crtc_vpos_gs = 0x00020147,
+ .crtc_rev = 0x0040010a,
+ .crtc_dclk = 0xa1700030,
+ .crtc_gclk = 0x80cc0015,
+ .crtc_goe = 0x80cc0015,
+ .crtc_ps1_active = 0x61060017,
+ .pll_freq = 57,
+ .pixclk_divider = 4,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_XTAL,
+ .sysclk_divider = 1,
+ .sysclk_src = CLK_SRC_PLL,
+};
+
+static struct w100_gpio_regs e750_w100_gpio_info = {
+ .init_data1 = 0x01192f1b,
+ .gpio_dir1 = 0xd5ffdeff,
+ .gpio_oe1 = 0x000020bf,
+ .init_data2 = 0x010f010f,
+ .gpio_dir2 = 0xffffffff,
+ .gpio_oe2 = 0x000001cf,
+};
+
+static struct w100fb_mach_info e750_fb_info = {
+ .modelist = &e750_lcd_mode,
+ .num_modes = 1,
+ .regs = &e750_lcd_regs,
+ .gpio = &e750_w100_gpio_info,
+ .xtal_freq = 14318000,
+ .xtal_dbl = 1,
+};
+
+static struct resource e750_fb_resources[] = {
+ [0] = {
+ .start = 0x0c000000,
+ .end = 0x0cffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device e750_fb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e750_fb_info,
+ },
+ .num_resources = ARRAY_SIZE(e750_fb_resources),
+ .resource = e750_fb_resources,
+};
+
+/* -------------------- e750 MFP parameters -------------------- */
+
+static unsigned long e750_pin_config[] __initdata = {
+ /* Chip selects */
+ GPIO15_nCS_1, /* CS1 - Flash */
+ GPIO79_nCS_3, /* CS3 - IMAGEON */
+ GPIO80_nCS_4, /* CS4 - TMIO */
+
+ /* Clocks */
+ GPIO11_3_6MHz,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+
+ /* TMIO controller */
+ GPIO19_GPIO, /* t7l66xb #PCLR */
+ GPIO45_GPIO, /* t7l66xb #SUSPEND (NOT BTUART!) */
+
+ /* UDC */
+ GPIO13_GPIO,
+ GPIO3_GPIO,
+
+ /* IrDA */
+ GPIO38_GPIO | MFP_LPM_DRIVE_HIGH,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* Audio power control */
+ GPIO4_GPIO, /* Headphone amp power */
+ GPIO7_GPIO, /* Speaker amp power */
+ GPIO37_GPIO, /* Headphone detect */
+
+ /* PC Card */
+ GPIO8_GPIO, /* CD0 */
+ GPIO44_GPIO, /* CD1 */
+ GPIO11_GPIO, /* IRQ0 */
+ GPIO6_GPIO, /* IRQ1 */
+ GPIO27_GPIO, /* RST0 */
+ GPIO24_GPIO, /* RST1 */
+ GPIO20_GPIO, /* PWR0 */
+ GPIO23_GPIO, /* PWR1 */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* wakeup */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+/* ----------------- e750 tc6393xb parameters ------------------ */
+
+static struct tc6393xb_platform_data e750_tc6393xb_info = {
+ .irq_base = IRQ_BOARD_START,
+ .scr_pll2cr = 0x0cc1,
+ .scr_gper = 0,
+ .gpio_base = -1,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+ .enable = &eseries_tmio_enable,
+ .disable = &eseries_tmio_disable,
+};
+
+static struct platform_device e750_tc6393xb_device = {
+ .name = "tc6393xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e750_tc6393xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* ------------------------------------------------------------- */
+
+static struct platform_device *e750_devices[] __initdata = {
+ &e750_fb_device,
+ &e750_tc6393xb_device,
+ &e7xx_gpio_vbus,
+};
+
+static void __init e750_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e750_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
+ "GPIO11_CLK", NULL),
+ eseries_get_tmio_gpios();
+ platform_add_devices(ARRAY_AND_SIZE(e750_devices));
+ pxa_set_ac97_info(NULL);
+ pxa_set_ficp_info(&e7xx_ficp_platform_data);
+}
+
+MACHINE_START(E750, "Toshiba e750")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e750_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_E800
+/* ------------------------ e800 LCD definitions ------------------------- */
+
+static unsigned long e800_pin_config[] __initdata = {
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+};
+
+static struct w100_gen_regs e800_lcd_regs = {
+ .lcd_format = 0x00008003,
+ .lcdd_cntl1 = 0x02a00000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x000ff2a3,
+ .genlcd_cntl2 = 0x000002a3,
+ .genlcd_cntl3 = 0x000102aa,
+};
+
+static struct w100_mode e800_lcd_mode[2] = {
+ [0] = {
+ .xres = 480,
+ .yres = 640,
+ .left_margin = 52,
+ .right_margin = 148,
+ .upper_margin = 2,
+ .lower_margin = 6,
+ .crtc_ss = 0x80350034,
+ .crtc_ls = 0x802b0026,
+ .crtc_gs = 0x80160016,
+ .crtc_vpos_gs = 0x00020003,
+ .crtc_rev = 0x0040001d,
+ .crtc_dclk = 0xe0000000,
+ .crtc_gclk = 0x82a50049,
+ .crtc_goe = 0x80ee001c,
+ .crtc_ps1_active = 0x00000000,
+ .pll_freq = 128,
+ .pixclk_divider = 4,
+ .pixclk_divider_rotated = 6,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+ },
+ [1] = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 15,
+ .right_margin = 88,
+ .upper_margin = 0,
+ .lower_margin = 7,
+ .crtc_ss = 0xd010000f,
+ .crtc_ls = 0x80070003,
+ .crtc_gs = 0x80000000,
+ .crtc_vpos_gs = 0x01460147,
+ .crtc_rev = 0x00400003,
+ .crtc_dclk = 0xa1700030,
+ .crtc_gclk = 0x814b0008,
+ .crtc_goe = 0x80cc0015,
+ .crtc_ps1_active = 0x00000000,
+ .pll_freq = 100,
+ .pixclk_divider = 6, /* Wince uses 14 which gives a */
+ .pixclk_divider_rotated = 6, /* 7MHz Pclk. We use a 14MHz one */
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+ }
+};
+
+
+static struct w100_gpio_regs e800_w100_gpio_info = {
+ .init_data1 = 0xc13fc019,
+ .gpio_dir1 = 0x3e40df7f,
+ .gpio_oe1 = 0x003c3000,
+ .init_data2 = 0x00000000,
+ .gpio_dir2 = 0x00000000,
+ .gpio_oe2 = 0x00000000,
+};
+
+static struct w100_mem_info e800_w100_mem_info = {
+ .ext_cntl = 0x09640011,
+ .sdram_mode_reg = 0x00600021,
+ .ext_timing_cntl = 0x10001545,
+ .io_cntl = 0x7ddd7333,
+ .size = 0x1fffff,
+};
+
+static void e800_tg_change(struct w100fb_par *par)
+{
+ unsigned long tmp;
+
+ tmp = w100fb_gpio_read(W100_GPIO_PORT_A);
+ if (par->mode->xres == 480)
+ tmp |= 0x100;
+ else
+ tmp &= ~0x100;
+ w100fb_gpio_write(W100_GPIO_PORT_A, tmp);
+}
+
+static struct w100_tg_info e800_tg_info = {
+ .change = e800_tg_change,
+};
+
+static struct w100fb_mach_info e800_fb_info = {
+ .modelist = e800_lcd_mode,
+ .num_modes = 2,
+ .regs = &e800_lcd_regs,
+ .gpio = &e800_w100_gpio_info,
+ .mem = &e800_w100_mem_info,
+ .tg = &e800_tg_info,
+ .xtal_freq = 16000000,
+};
+
+static struct resource e800_fb_resources[] = {
+ [0] = {
+ .start = 0x0c000000,
+ .end = 0x0cffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device e800_fb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e800_fb_info,
+ },
+ .num_resources = ARRAY_SIZE(e800_fb_resources),
+ .resource = e800_fb_resources,
+};
+
+/* --------------------------- UDC definitions --------------------------- */
+
+static struct gpio_vbus_mach_info e800_udc_info = {
+ .gpio_vbus = GPIO_E800_USB_DISC,
+ .gpio_pullup = GPIO_E800_USB_PULLUP,
+ .gpio_pullup_inverted = 1
+};
+
+static struct platform_device e800_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &e800_udc_info,
+ },
+};
+
+
+/* ----------------- e800 tc6393xb parameters ------------------ */
+
+static struct tc6393xb_platform_data e800_tc6393xb_info = {
+ .irq_base = IRQ_BOARD_START,
+ .scr_pll2cr = 0x0cc1,
+ .scr_gper = 0,
+ .gpio_base = -1,
+ .suspend = &eseries_tmio_suspend,
+ .resume = &eseries_tmio_resume,
+ .enable = &eseries_tmio_enable,
+ .disable = &eseries_tmio_disable,
+};
+
+static struct platform_device e800_tc6393xb_device = {
+ .name = "tc6393xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &e800_tc6393xb_info,
+ },
+ .num_resources = 2,
+ .resource = eseries_tmio_resources,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *e800_devices[] __initdata = {
+ &e800_fb_device,
+ &e800_tc6393xb_device,
+ &e800_gpio_vbus,
+};
+
+static void __init e800_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e800_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
+ "GPIO11_CLK", NULL),
+ eseries_get_tmio_gpios();
+ platform_add_devices(ARRAY_AND_SIZE(e800_devices));
+ pxa_set_ac97_info(NULL);
+}
+
+MACHINE_START(E800, "Toshiba e800")
+ /* Maintainer: Ian Molton (spyro@f2s.com) */
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = ESERIES_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .fixup = eseries_fixup,
+ .init_machine = e800_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h
new file mode 100644
index 00000000..5930f5e2
--- /dev/null
+++ b/arch/arm/mach-pxa/eseries.h
@@ -0,0 +1,16 @@
+void __init eseries_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi);
+
+extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info;
+extern struct pxaficp_platform_data e7xx_ficp_platform_data;
+extern int e7xx_irda_init(void);
+
+extern int eseries_tmio_enable(struct platform_device *dev);
+extern int eseries_tmio_disable(struct platform_device *dev);
+extern int eseries_tmio_suspend(struct platform_device *dev);
+extern int eseries_tmio_resume(struct platform_device *dev);
+extern void eseries_get_tmio_gpios(void);
+extern struct resource eseries_tmio_resources[];
+extern struct platform_device e300_tc6387xb_device;
+extern void eseries_register_clks(void);
+
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
new file mode 100644
index 00000000..d88aed8f
--- /dev/null
+++ b/arch/arm/mach-pxa/ezx.c
@@ -0,0 +1,1231 @@
+/*
+ * ezx.c - Common code for the EZX platform.
+ *
+ * Copyright (C) 2005-2006 Harald Welte <laforge@openezx.org>,
+ * 2007-2008 Daniel Ribeiro <drwyrm@gmail.com>,
+ * 2007-2008 Stefan Schmidt <stefan@datenfreihafen.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/pwm_backlight.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/leds-lp3944.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/hardware.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/camera.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define EZX_NR_IRQS (IRQ_BOARD_START + 24)
+
+#define GPIO12_A780_FLIP_LID 12
+#define GPIO15_A1200_FLIP_LID 15
+#define GPIO15_A910_FLIP_LID 15
+#define GPIO12_E680_LOCK_SWITCH 12
+#define GPIO15_E6_LOCK_SWITCH 15
+#define GPIO50_nCAM_EN 50
+#define GPIO19_GEN1_CAM_RST 19
+#define GPIO28_GEN2_CAM_RST 28
+
+static struct platform_pwm_backlight_data ezx_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1023,
+ .dft_brightness = 1023,
+ .pwm_period_ns = 78770,
+};
+
+static struct platform_device ezx_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &ezx_backlight_data,
+ },
+};
+
+static struct pxafb_mode_info mode_ezx_old = {
+ .pixclock = 150000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 10,
+ .left_margin = 20,
+ .right_margin = 10,
+ .vsync_len = 2,
+ .upper_margin = 3,
+ .lower_margin = 2,
+ .sync = 0,
+};
+
+static struct pxafb_mach_info ezx_fb_info_1 = {
+ .modes = &mode_ezx_old,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+};
+
+static struct pxafb_mode_info mode_72r89803y01 = {
+ .pixclock = 192308,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 32,
+ .depth = 18,
+ .hsync_len = 10,
+ .left_margin = 20,
+ .right_margin = 10,
+ .vsync_len = 2,
+ .upper_margin = 3,
+ .lower_margin = 2,
+ .sync = 0,
+};
+
+static struct pxafb_mach_info ezx_fb_info_2 = {
+ .modes = &mode_72r89803y01,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_18BPP,
+};
+
+static struct platform_device *ezx_devices[] __initdata = {
+ &ezx_backlight_device,
+};
+
+static unsigned long ezx_pin_config[] __initdata = {
+ /* PWM backlight */
+ GPIO16_PWM0_OUT,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* PCAP SSP */
+ GPIO29_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+ GPIO24_GPIO, /* pcap chip select */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* pcap interrupt */
+ GPIO4_GPIO | MFP_LPM_DRIVE_HIGH, /* WDI_AP */
+ GPIO55_GPIO | MFP_LPM_DRIVE_HIGH, /* SYS_RESTART */
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO11_GPIO, /* mmc detect */
+
+ /* usb to external transceiver */
+ GPIO34_USB_P2_2,
+ GPIO35_USB_P2_1,
+ GPIO36_USB_P2_4,
+ GPIO39_USB_P2_6,
+ GPIO40_USB_P2_5,
+ GPIO53_USB_P2_3,
+
+ /* usb to Neptune GSM chip */
+ GPIO30_USB_P3_2,
+ GPIO31_USB_P3_6,
+ GPIO90_USB_P3_5,
+ GPIO91_USB_P3_1,
+ GPIO56_USB_P3_4,
+ GPIO113_USB_P3_3,
+};
+
+#if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680)
+static unsigned long gen1_pin_config[] __initdata = {
+ /* flip / lockswitch */
+ GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH,
+
+ /* bluetooth (bcm2035) */
+ GPIO14_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */
+ GPIO48_GPIO, /* RESET */
+ GPIO28_GPIO, /* WAKEUP */
+
+ /* Neptune handshake */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */
+ GPIO57_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */
+ GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI */
+ GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI2 */
+ GPIO82_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */
+ GPIO99_GPIO | MFP_LPM_DRIVE_HIGH, /* TC_MM_EN */
+
+ /* sound */
+ GPIO52_SSP3_SCLK,
+ GPIO83_SSP3_SFRM,
+ GPIO81_SSP3_TXD,
+ GPIO89_SSP3_RXD,
+
+ /* ssp2 pins to in */
+ GPIO22_GPIO, /* SSP2_SCLK */
+ GPIO37_GPIO, /* SSP2_SFRM */
+ GPIO38_GPIO, /* SSP2_TXD */
+ GPIO88_GPIO, /* SSP2_RXD */
+
+ /* camera */
+ GPIO23_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO85_CIF_LV,
+ GPIO84_CIF_FV,
+ GPIO27_CIF_DD_0,
+ GPIO114_CIF_DD_1,
+ GPIO51_CIF_DD_2,
+ GPIO115_CIF_DD_3,
+ GPIO95_CIF_DD_4,
+ GPIO94_CIF_DD_5,
+ GPIO17_CIF_DD_6,
+ GPIO108_CIF_DD_7,
+ GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */
+ GPIO19_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */
+
+ /* EMU */
+ GPIO120_GPIO, /* EMU_MUX1 */
+ GPIO119_GPIO, /* EMU_MUX2 */
+ GPIO86_GPIO, /* SNP_INT_CTL */
+ GPIO87_GPIO, /* SNP_INT_IN */
+};
+#endif
+
+#if defined(CONFIG_MACH_EZX_A1200) || defined(CONFIG_MACH_EZX_A910) || \
+ defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6)
+static unsigned long gen2_pin_config[] __initdata = {
+ /* flip / lockswitch */
+ GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH,
+
+ /* EOC */
+ GPIO10_GPIO | WAKEUP_ON_EDGE_RISE,
+
+ /* bluetooth (bcm2045) */
+ GPIO13_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */
+ GPIO37_GPIO, /* RESET */
+ GPIO57_GPIO, /* WAKEUP */
+
+ /* Neptune handshake */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */
+ GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */
+ GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* WDI */
+ GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */
+ GPIO41_GPIO, /* BP_FLASH */
+
+ /* sound */
+ GPIO52_SSP3_SCLK,
+ GPIO83_SSP3_SFRM,
+ GPIO81_SSP3_TXD,
+ GPIO82_SSP3_RXD,
+
+ /* ssp2 pins to in */
+ GPIO22_GPIO, /* SSP2_SCLK */
+ GPIO14_GPIO, /* SSP2_SFRM */
+ GPIO38_GPIO, /* SSP2_TXD */
+ GPIO88_GPIO, /* SSP2_RXD */
+
+ /* camera */
+ GPIO23_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO85_CIF_LV,
+ GPIO84_CIF_FV,
+ GPIO27_CIF_DD_0,
+ GPIO114_CIF_DD_1,
+ GPIO51_CIF_DD_2,
+ GPIO115_CIF_DD_3,
+ GPIO95_CIF_DD_4,
+ GPIO48_CIF_DD_5,
+ GPIO93_CIF_DD_6,
+ GPIO12_CIF_DD_7,
+ GPIO50_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_EN */
+ GPIO28_GPIO | MFP_LPM_DRIVE_HIGH, /* CAM_RST */
+ GPIO17_GPIO, /* CAM_FLASH */
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_A780
+static unsigned long a780_pin_config[] __initdata = {
+ /* keypad */
+ GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+
+ /* attenuate sound */
+ GPIO96_GPIO,
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_E680
+static unsigned long e680_pin_config[] __initdata = {
+ /* keypad */
+ GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO96_KP_DKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_DKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_DKIN_5 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+
+ /* MIDI */
+ GPIO79_GPIO, /* VA_SEL_BUL */
+ GPIO80_GPIO, /* FLT_SEL_BUL */
+ GPIO78_GPIO, /* MIDI_RESET */
+ GPIO33_GPIO, /* MIDI_CS */
+ GPIO15_GPIO, /* MIDI_IRQ */
+ GPIO49_GPIO, /* MIDI_NPWE */
+ GPIO18_GPIO, /* MIDI_RDY */
+
+ /* leds */
+ GPIO46_GPIO,
+ GPIO47_GPIO,
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_A1200
+static unsigned long a1200_pin_config[] __initdata = {
+ /* keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_A910
+static unsigned long a910_pin_config[] __initdata = {
+ /* keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+
+ /* WLAN */
+ GPIO89_GPIO, /* RESET */
+ GPIO33_GPIO, /* WAKEUP */
+ GPIO94_GPIO | WAKEUP_ON_LEVEL_HIGH, /* HOSTWAKE */
+
+ /* MMC CS */
+ GPIO20_GPIO,
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_E2
+static unsigned long e2_pin_config[] __initdata = {
+ /* keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+};
+#endif
+
+#ifdef CONFIG_MACH_EZX_E6
+static unsigned long e6_pin_config[] __initdata = {
+ /* keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+};
+#endif
+
+/* KEYPAD */
+#ifdef CONFIG_MACH_EZX_A780
+static unsigned int a780_key_map[] = {
+ KEY(0, 0, KEY_SEND),
+ KEY(0, 1, KEY_BACK),
+ KEY(0, 2, KEY_END),
+ KEY(0, 3, KEY_PAGEUP),
+ KEY(0, 4, KEY_UP),
+
+ KEY(1, 0, KEY_NUMERIC_1),
+ KEY(1, 1, KEY_NUMERIC_2),
+ KEY(1, 2, KEY_NUMERIC_3),
+ KEY(1, 3, KEY_SELECT),
+ KEY(1, 4, KEY_KPENTER),
+
+ KEY(2, 0, KEY_NUMERIC_4),
+ KEY(2, 1, KEY_NUMERIC_5),
+ KEY(2, 2, KEY_NUMERIC_6),
+ KEY(2, 3, KEY_RECORD),
+ KEY(2, 4, KEY_LEFT),
+
+ KEY(3, 0, KEY_NUMERIC_7),
+ KEY(3, 1, KEY_NUMERIC_8),
+ KEY(3, 2, KEY_NUMERIC_9),
+ KEY(3, 3, KEY_HOME),
+ KEY(3, 4, KEY_RIGHT),
+
+ KEY(4, 0, KEY_NUMERIC_STAR),
+ KEY(4, 1, KEY_NUMERIC_0),
+ KEY(4, 2, KEY_NUMERIC_POUND),
+ KEY(4, 3, KEY_PAGEDOWN),
+ KEY(4, 4, KEY_DOWN),
+};
+
+static struct pxa27x_keypad_platform_data a780_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 5,
+ .matrix_key_map = a780_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(a780_key_map),
+
+ .direct_key_map = { KEY_CAMERA },
+ .direct_key_num = 1,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A780 */
+
+#ifdef CONFIG_MACH_EZX_E680
+static unsigned int e680_key_map[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_RESERVED),
+ KEY(0, 3, KEY_SEND),
+
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_PAGEUP),
+ KEY(1, 3, KEY_PAGEDOWN),
+
+ KEY(2, 0, KEY_RESERVED),
+ KEY(2, 1, KEY_RESERVED),
+ KEY(2, 2, KEY_RESERVED),
+ KEY(2, 3, KEY_KPENTER),
+};
+
+static struct pxa27x_keypad_platform_data e680_keypad_platform_data = {
+ .matrix_key_rows = 3,
+ .matrix_key_cols = 4,
+ .matrix_key_map = e680_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(e680_key_map),
+
+ .direct_key_map = {
+ KEY_CAMERA,
+ KEY_RESERVED,
+ KEY_RESERVED,
+ KEY_F1,
+ KEY_CANCEL,
+ KEY_F2,
+ },
+ .direct_key_num = 6,
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_E680 */
+
+#ifdef CONFIG_MACH_EZX_A1200
+static unsigned int a1200_key_map[] = {
+ KEY(0, 0, KEY_RESERVED),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_PAGEDOWN),
+ KEY(0, 3, KEY_RESERVED),
+ KEY(0, 4, KEY_RESERVED),
+ KEY(0, 5, KEY_RESERVED),
+
+ KEY(1, 0, KEY_RESERVED),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_CAMERA),
+ KEY(1, 3, KEY_RESERVED),
+ KEY(1, 4, KEY_RESERVED),
+ KEY(1, 5, KEY_RESERVED),
+
+ KEY(2, 0, KEY_RESERVED),
+ KEY(2, 1, KEY_KPENTER),
+ KEY(2, 2, KEY_RECORD),
+ KEY(2, 3, KEY_RESERVED),
+ KEY(2, 4, KEY_RESERVED),
+ KEY(2, 5, KEY_SELECT),
+
+ KEY(3, 0, KEY_RESERVED),
+ KEY(3, 1, KEY_UP),
+ KEY(3, 2, KEY_SEND),
+ KEY(3, 3, KEY_RESERVED),
+ KEY(3, 4, KEY_RESERVED),
+ KEY(3, 5, KEY_RESERVED),
+
+ KEY(4, 0, KEY_RESERVED),
+ KEY(4, 1, KEY_LEFT),
+ KEY(4, 2, KEY_PAGEUP),
+ KEY(4, 3, KEY_RESERVED),
+ KEY(4, 4, KEY_RESERVED),
+ KEY(4, 5, KEY_RESERVED),
+};
+
+static struct pxa27x_keypad_platform_data a1200_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_key_map = a1200_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(a1200_key_map),
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A1200 */
+
+#ifdef CONFIG_MACH_EZX_E6
+static unsigned int e6_key_map[] = {
+ KEY(0, 0, KEY_RESERVED),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_PAGEDOWN),
+ KEY(0, 3, KEY_RESERVED),
+ KEY(0, 4, KEY_RESERVED),
+ KEY(0, 5, KEY_NEXTSONG),
+
+ KEY(1, 0, KEY_RESERVED),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_PROG1),
+ KEY(1, 3, KEY_RESERVED),
+ KEY(1, 4, KEY_RESERVED),
+ KEY(1, 5, KEY_RESERVED),
+
+ KEY(2, 0, KEY_RESERVED),
+ KEY(2, 1, KEY_ENTER),
+ KEY(2, 2, KEY_CAMERA),
+ KEY(2, 3, KEY_RESERVED),
+ KEY(2, 4, KEY_RESERVED),
+ KEY(2, 5, KEY_WWW),
+
+ KEY(3, 0, KEY_RESERVED),
+ KEY(3, 1, KEY_UP),
+ KEY(3, 2, KEY_SEND),
+ KEY(3, 3, KEY_RESERVED),
+ KEY(3, 4, KEY_RESERVED),
+ KEY(3, 5, KEY_PLAYPAUSE),
+
+ KEY(4, 0, KEY_RESERVED),
+ KEY(4, 1, KEY_LEFT),
+ KEY(4, 2, KEY_PAGEUP),
+ KEY(4, 3, KEY_RESERVED),
+ KEY(4, 4, KEY_RESERVED),
+ KEY(4, 5, KEY_PREVIOUSSONG),
+};
+
+static struct pxa27x_keypad_platform_data e6_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_key_map = e6_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(e6_key_map),
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_E6 */
+
+#ifdef CONFIG_MACH_EZX_A910
+static unsigned int a910_key_map[] = {
+ KEY(0, 0, KEY_NUMERIC_6),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_PAGEDOWN),
+ KEY(0, 3, KEY_KPENTER),
+ KEY(0, 4, KEY_NUMERIC_5),
+ KEY(0, 5, KEY_CAMERA),
+
+ KEY(1, 0, KEY_NUMERIC_8),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_RESERVED),
+ KEY(1, 3, KEY_F1), /* Left SoftKey */
+ KEY(1, 4, KEY_NUMERIC_STAR),
+ KEY(1, 5, KEY_RESERVED),
+
+ KEY(2, 0, KEY_NUMERIC_7),
+ KEY(2, 1, KEY_NUMERIC_9),
+ KEY(2, 2, KEY_RECORD),
+ KEY(2, 3, KEY_F2), /* Right SoftKey */
+ KEY(2, 4, KEY_BACK),
+ KEY(2, 5, KEY_SELECT),
+
+ KEY(3, 0, KEY_NUMERIC_2),
+ KEY(3, 1, KEY_UP),
+ KEY(3, 2, KEY_SEND),
+ KEY(3, 3, KEY_NUMERIC_0),
+ KEY(3, 4, KEY_NUMERIC_1),
+ KEY(3, 5, KEY_RECORD),
+
+ KEY(4, 0, KEY_NUMERIC_4),
+ KEY(4, 1, KEY_LEFT),
+ KEY(4, 2, KEY_PAGEUP),
+ KEY(4, 3, KEY_NUMERIC_POUND),
+ KEY(4, 4, KEY_NUMERIC_3),
+ KEY(4, 5, KEY_RESERVED),
+};
+
+static struct pxa27x_keypad_platform_data a910_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_key_map = a910_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(a910_key_map),
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_A910 */
+
+#ifdef CONFIG_MACH_EZX_E2
+static unsigned int e2_key_map[] = {
+ KEY(0, 0, KEY_NUMERIC_6),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_NUMERIC_9),
+ KEY(0, 3, KEY_NEXTSONG),
+ KEY(0, 4, KEY_NUMERIC_5),
+ KEY(0, 5, KEY_F1), /* Left SoftKey */
+
+ KEY(1, 0, KEY_NUMERIC_8),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 2, KEY_RESERVED),
+ KEY(1, 3, KEY_PAGEUP),
+ KEY(1, 4, KEY_NUMERIC_STAR),
+ KEY(1, 5, KEY_F2), /* Right SoftKey */
+
+ KEY(2, 0, KEY_NUMERIC_7),
+ KEY(2, 1, KEY_KPENTER),
+ KEY(2, 2, KEY_RECORD),
+ KEY(2, 3, KEY_PAGEDOWN),
+ KEY(2, 4, KEY_BACK),
+ KEY(2, 5, KEY_NUMERIC_0),
+
+ KEY(3, 0, KEY_NUMERIC_2),
+ KEY(3, 1, KEY_UP),
+ KEY(3, 2, KEY_SEND),
+ KEY(3, 3, KEY_PLAYPAUSE),
+ KEY(3, 4, KEY_NUMERIC_1),
+ KEY(3, 5, KEY_SOUND), /* Music SoftKey */
+
+ KEY(4, 0, KEY_NUMERIC_4),
+ KEY(4, 1, KEY_LEFT),
+ KEY(4, 2, KEY_NUMERIC_POUND),
+ KEY(4, 3, KEY_PREVIOUSSONG),
+ KEY(4, 4, KEY_NUMERIC_3),
+ KEY(4, 5, KEY_RESERVED),
+};
+
+static struct pxa27x_keypad_platform_data e2_keypad_platform_data = {
+ .matrix_key_rows = 5,
+ .matrix_key_cols = 6,
+ .matrix_key_map = e2_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(e2_key_map),
+
+ .debounce_interval = 30,
+};
+#endif /* CONFIG_MACH_EZX_E2 */
+
+#ifdef CONFIG_MACH_EZX_A780
+/* gpio_keys */
+static struct gpio_keys_button a780_buttons[] = {
+ [0] = {
+ .code = SW_LID,
+ .gpio = GPIO12_A780_FLIP_LID,
+ .active_low = 0,
+ .desc = "A780 flip lid",
+ .type = EV_SW,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data a780_gpio_keys_platform_data = {
+ .buttons = a780_buttons,
+ .nbuttons = ARRAY_SIZE(a780_buttons),
+};
+
+static struct platform_device a780_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &a780_gpio_keys_platform_data,
+ },
+};
+
+/* camera */
+static int a780_camera_init(void)
+{
+ int err;
+
+ /*
+ * GPIO50_nCAM_EN is active low
+ * GPIO19_GEN1_CAM_RST is active on rising edge
+ */
+ err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
+ if (err) {
+ pr_err("%s: Failed to request nCAM_EN\n", __func__);
+ goto fail;
+ }
+
+ err = gpio_request(GPIO19_GEN1_CAM_RST, "CAM_RST");
+ if (err) {
+ pr_err("%s: Failed to request CAM_RST\n", __func__);
+ goto fail_gpio_cam_rst;
+ }
+
+ gpio_direction_output(GPIO50_nCAM_EN, 1);
+ gpio_direction_output(GPIO19_GEN1_CAM_RST, 0);
+
+ return 0;
+
+fail_gpio_cam_rst:
+ gpio_free(GPIO50_nCAM_EN);
+fail:
+ return err;
+}
+
+static int a780_camera_power(struct device *dev, int on)
+{
+ gpio_set_value(GPIO50_nCAM_EN, !on);
+ return 0;
+}
+
+static int a780_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO19_GEN1_CAM_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO19_GEN1_CAM_RST, 1);
+
+ return 0;
+}
+
+struct pxacamera_platform_data a780_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 5000,
+};
+
+static struct i2c_board_info a780_camera_i2c_board_info = {
+ I2C_BOARD_INFO("mt9m111", 0x5d),
+};
+
+static struct soc_camera_link a780_iclink = {
+ .bus_id = 0,
+ .flags = SOCAM_SENSOR_INVERT_PCLK,
+ .i2c_adapter_id = 0,
+ .board_info = &a780_camera_i2c_board_info,
+ .power = a780_camera_power,
+ .reset = a780_camera_reset,
+};
+
+static struct platform_device a780_camera = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &a780_iclink,
+ },
+};
+
+static struct platform_device *a780_devices[] __initdata = {
+ &a780_gpio_keys,
+};
+
+static void __init a780_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(a780_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_1);
+
+ pxa_set_keypad_info(&a780_keypad_platform_data);
+
+ if (a780_camera_init() == 0) {
+ pxa_set_camera_info(&a780_pxacamera_platform_data);
+ platform_device_register(&a780_camera);
+ }
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(a780_devices));
+}
+
+MACHINE_START(EZX_A780, "Motorola EZX A780")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = a780_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E680
+/* gpio_keys */
+static struct gpio_keys_button e680_buttons[] = {
+ [0] = {
+ .code = KEY_SCREENLOCK,
+ .gpio = GPIO12_E680_LOCK_SWITCH,
+ .active_low = 0,
+ .desc = "E680 lock switch",
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data e680_gpio_keys_platform_data = {
+ .buttons = e680_buttons,
+ .nbuttons = ARRAY_SIZE(e680_buttons),
+};
+
+static struct platform_device e680_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &e680_gpio_keys_platform_data,
+ },
+};
+
+static struct i2c_board_info __initdata e680_i2c_board_info[] = {
+ { I2C_BOARD_INFO("tea5767", 0x81) },
+};
+
+static struct platform_device *e680_devices[] __initdata = {
+ &e680_gpio_keys,
+};
+
+static void __init e680_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen1_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e680_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_1);
+
+ pxa_set_keypad_info(&e680_keypad_platform_data);
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(e680_devices));
+}
+
+MACHINE_START(EZX_E680, "Motorola EZX E680")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = e680_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_A1200
+/* gpio_keys */
+static struct gpio_keys_button a1200_buttons[] = {
+ [0] = {
+ .code = SW_LID,
+ .gpio = GPIO15_A1200_FLIP_LID,
+ .active_low = 0,
+ .desc = "A1200 flip lid",
+ .type = EV_SW,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data a1200_gpio_keys_platform_data = {
+ .buttons = a1200_buttons,
+ .nbuttons = ARRAY_SIZE(a1200_buttons),
+};
+
+static struct platform_device a1200_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &a1200_gpio_keys_platform_data,
+ },
+};
+
+static struct i2c_board_info __initdata a1200_i2c_board_info[] = {
+ { I2C_BOARD_INFO("tea5767", 0x81) },
+};
+
+static struct platform_device *a1200_devices[] __initdata = {
+ &a1200_gpio_keys,
+};
+
+static void __init a1200_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(a1200_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
+
+ pxa_set_keypad_info(&a1200_keypad_platform_data);
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(a1200_devices));
+}
+
+MACHINE_START(EZX_A1200, "Motorola EZX A1200")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = a1200_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_A910
+/* gpio_keys */
+static struct gpio_keys_button a910_buttons[] = {
+ [0] = {
+ .code = SW_LID,
+ .gpio = GPIO15_A910_FLIP_LID,
+ .active_low = 0,
+ .desc = "A910 flip lid",
+ .type = EV_SW,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data a910_gpio_keys_platform_data = {
+ .buttons = a910_buttons,
+ .nbuttons = ARRAY_SIZE(a910_buttons),
+};
+
+static struct platform_device a910_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &a910_gpio_keys_platform_data,
+ },
+};
+
+/* camera */
+static int a910_camera_init(void)
+{
+ int err;
+
+ /*
+ * GPIO50_nCAM_EN is active low
+ * GPIO28_GEN2_CAM_RST is active on rising edge
+ */
+ err = gpio_request(GPIO50_nCAM_EN, "nCAM_EN");
+ if (err) {
+ pr_err("%s: Failed to request nCAM_EN\n", __func__);
+ goto fail;
+ }
+
+ err = gpio_request(GPIO28_GEN2_CAM_RST, "CAM_RST");
+ if (err) {
+ pr_err("%s: Failed to request CAM_RST\n", __func__);
+ goto fail_gpio_cam_rst;
+ }
+
+ gpio_direction_output(GPIO50_nCAM_EN, 1);
+ gpio_direction_output(GPIO28_GEN2_CAM_RST, 0);
+
+ return 0;
+
+fail_gpio_cam_rst:
+ gpio_free(GPIO50_nCAM_EN);
+fail:
+ return err;
+}
+
+static int a910_camera_power(struct device *dev, int on)
+{
+ gpio_set_value(GPIO50_nCAM_EN, !on);
+ return 0;
+}
+
+static int a910_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO28_GEN2_CAM_RST, 0);
+ msleep(10);
+ gpio_set_value(GPIO28_GEN2_CAM_RST, 1);
+
+ return 0;
+}
+
+struct pxacamera_platform_data a910_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 5000,
+};
+
+static struct i2c_board_info a910_camera_i2c_board_info = {
+ I2C_BOARD_INFO("mt9m111", 0x5d),
+};
+
+static struct soc_camera_link a910_iclink = {
+ .bus_id = 0,
+ .i2c_adapter_id = 0,
+ .board_info = &a910_camera_i2c_board_info,
+ .power = a910_camera_power,
+ .reset = a910_camera_reset,
+};
+
+static struct platform_device a910_camera = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &a910_iclink,
+ },
+};
+
+/* leds-lp3944 */
+static struct lp3944_platform_data a910_lp3944_leds = {
+ .leds_size = LP3944_LEDS_MAX,
+ .leds = {
+ [0] = {
+ .name = "a910:red:",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED,
+ },
+ [1] = {
+ .name = "a910:green:",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED,
+ },
+ [2] {
+ .name = "a910:blue:",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED,
+ },
+ /* Leds 3 and 4 are used as display power switches */
+ [3] = {
+ .name = "a910::cli_display",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED_INVERTED
+ },
+ [4] = {
+ .name = "a910::main_display",
+ .status = LP3944_LED_STATUS_ON,
+ .type = LP3944_LED_TYPE_LED_INVERTED
+ },
+ [5] = { .type = LP3944_LED_TYPE_NONE },
+ [6] = {
+ .name = "a910::torch",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED,
+ },
+ [7] = {
+ .name = "a910::flash",
+ .status = LP3944_LED_STATUS_OFF,
+ .type = LP3944_LED_TYPE_LED_INVERTED,
+ },
+ },
+};
+
+static struct i2c_board_info __initdata a910_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("lp3944", 0x60),
+ .platform_data = &a910_lp3944_leds,
+ },
+};
+
+static struct platform_device *a910_devices[] __initdata = {
+ &a910_gpio_keys,
+};
+
+static void __init a910_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(a910_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
+
+ pxa_set_keypad_info(&a910_keypad_platform_data);
+
+ if (a910_camera_init() == 0) {
+ pxa_set_camera_info(&a910_pxacamera_platform_data);
+ platform_device_register(&a910_camera);
+ }
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(a910_devices));
+}
+
+MACHINE_START(EZX_A910, "Motorola EZX A910")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = a910_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E6
+/* gpio_keys */
+static struct gpio_keys_button e6_buttons[] = {
+ [0] = {
+ .code = KEY_SCREENLOCK,
+ .gpio = GPIO15_E6_LOCK_SWITCH,
+ .active_low = 0,
+ .desc = "E6 lock switch",
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data e6_gpio_keys_platform_data = {
+ .buttons = e6_buttons,
+ .nbuttons = ARRAY_SIZE(e6_buttons),
+};
+
+static struct platform_device e6_gpio_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &e6_gpio_keys_platform_data,
+ },
+};
+
+static struct i2c_board_info __initdata e6_i2c_board_info[] = {
+ { I2C_BOARD_INFO("tea5767", 0x81) },
+};
+
+static struct platform_device *e6_devices[] __initdata = {
+ &e6_gpio_keys,
+};
+
+static void __init e6_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e6_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
+
+ pxa_set_keypad_info(&e6_keypad_platform_data);
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(e6_devices));
+}
+
+MACHINE_START(EZX_E6, "Motorola EZX E6")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = e6_init,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_EZX_E2
+static struct i2c_board_info __initdata e2_i2c_board_info[] = {
+ { I2C_BOARD_INFO("tea5767", 0x81) },
+};
+
+static struct platform_device *e2_devices[] __initdata = {
+};
+
+static void __init e2_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(ezx_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gen2_pin_config));
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(e2_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
+
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
+
+ pxa_set_keypad_info(&e2_keypad_platform_data);
+
+ platform_add_devices(ARRAY_AND_SIZE(ezx_devices));
+ platform_add_devices(ARRAY_AND_SIZE(e2_devices));
+}
+
+MACHINE_START(EZX_E2, "Motorola EZX E2")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = EZX_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = e2_init,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
new file mode 100644
index 00000000..f5d91efc
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.c
@@ -0,0 +1,98 @@
+/*
+ * linux/arch/arm/mach-pxa/generic.c
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * Code common to all PXA machines.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Since this file should be linked before any other machine specific file,
+ * the __initcall() here will be executed first. This serves as default
+ * initialization stuff for PXA machines which can be overridden later if
+ * need be.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/system.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/reset.h>
+#include <mach/gpio.h>
+#include <mach/smemc.h>
+#include <mach/pxa3xx-regs.h>
+
+#include "generic.h"
+
+void clear_reset_status(unsigned int mask)
+{
+ if (cpu_is_pxa2xx())
+ pxa2xx_clear_reset_status(mask);
+ else {
+ /* RESET_STATUS_* has a 1:1 mapping with ARSR */
+ ARSR = mask;
+ }
+}
+
+unsigned long get_clock_tick_rate(void)
+{
+ unsigned long clock_tick_rate;
+
+ if (cpu_is_pxa25x())
+ clock_tick_rate = 3686400;
+ else if (machine_is_mainstone())
+ clock_tick_rate = 3249600;
+ else
+ clock_tick_rate = 3250000;
+
+ return clock_tick_rate;
+}
+EXPORT_SYMBOL(get_clock_tick_rate);
+
+/*
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int get_clk_frequency_khz(int info)
+{
+ if (cpu_is_pxa25x())
+ return pxa25x_get_clk_frequency_khz(info);
+ else if (cpu_is_pxa27x())
+ return pxa27x_get_clk_frequency_khz(info);
+ return 0;
+}
+EXPORT_SYMBOL(get_clk_frequency_khz);
+
+/*
+ * Intel PXA2xx internal register mapping.
+ *
+ * Note: virtual 0xfffe0000-0xffffffff is reserved for the vector table
+ * and cache flush area.
+ */
+static struct map_desc common_io_desc[] __initdata = {
+ { /* Devs */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* UNCACHED_PHYS_0 */
+ .virtual = 0xff000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
+};
+
+void __init pxa_map_io(void)
+{
+ iotable_init(ARRAY_AND_SIZE(common_io_desc));
+}
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
new file mode 100644
index 00000000..e6c9344a
--- /dev/null
+++ b/arch/arm/mach-pxa/generic.h
@@ -0,0 +1,72 @@
+/*
+ * linux/arch/arm/mach-pxa/generic.h
+ *
+ * Author: Nicolas Pitre
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+struct irq_data;
+struct sys_timer;
+
+extern struct sys_timer pxa_timer;
+extern void __init pxa_init_irq(int irq_nr,
+ int (*set_wake)(struct irq_data *,
+ unsigned int));
+extern void __init pxa25x_init_irq(void);
+#ifdef CONFIG_CPU_PXA26x
+extern void __init pxa26x_init_irq(void);
+#endif
+extern void __init pxa27x_init_irq(void);
+extern void __init pxa3xx_init_irq(void);
+extern void __init pxa95x_init_irq(void);
+
+extern void __init pxa_map_io(void);
+extern void __init pxa25x_map_io(void);
+extern void __init pxa27x_map_io(void);
+extern void __init pxa3xx_map_io(void);
+
+extern unsigned int get_clk_frequency_khz(int info);
+
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size)
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#ifdef CONFIG_PXA25x
+extern unsigned pxa25x_get_clk_frequency_khz(int);
+#else
+#define pxa25x_get_clk_frequency_khz(x) (0)
+#endif
+
+#ifdef CONFIG_PXA27x
+extern unsigned pxa27x_get_clk_frequency_khz(int);
+#else
+#define pxa27x_get_clk_frequency_khz(x) (0)
+#endif
+
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
+extern void pxa2xx_clear_reset_status(unsigned int);
+#else
+static inline void pxa2xx_clear_reset_status(unsigned int mask) {}
+#endif
+
+#ifdef CONFIG_PXA3xx
+extern unsigned pxa3xx_get_clk_frequency_khz(int);
+#else
+#define pxa3xx_get_clk_frequency_khz(x) (0)
+#endif
+
+extern struct syscore_ops pxa_irq_syscore_ops;
+extern struct syscore_ops pxa_gpio_syscore_ops;
+extern struct syscore_ops pxa2xx_mfp_syscore_ops;
+extern struct syscore_ops pxa3xx_mfp_syscore_ops;
+
+void __init pxa_set_ffuart_info(void *info);
+void __init pxa_set_btuart_info(void *info);
+void __init pxa_set_stuart_info(void *info);
+void __init pxa_set_hwuart_info(void *info);
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
new file mode 100644
index 00000000..b9e8233a
--- /dev/null
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -0,0 +1,241 @@
+/*
+ * linux/arch/arm/mach-pxa/gumstix.c
+ *
+ * Support for the Gumstix motherboards.
+ *
+ * Original Author: Craig Hughes
+ * Created: Feb 14, 2008
+ * Copyright: Craig Hughes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Implemented based on lubbock.c by Nicolas Pitre and code from Craig
+ * Hughes
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa25x.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/gumstix.h>
+
+#include "generic.h"
+
+static struct resource flash_resource = {
+ .start = 0x00000000,
+ .end = SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition gumstix_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ } , {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND
+ }
+};
+
+static struct flash_platform_data gumstix_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = gumstix_partitions,
+ .nr_parts = ARRAY_SIZE(gumstix_partitions),
+ .width = 2,
+};
+
+static struct platform_device gumstix_flash_device = {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &gumstix_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &gumstix_flash_device,
+};
+
+#ifdef CONFIG_MMC_PXA
+static struct pxamci_platform_data gumstix_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void __init gumstix_mmc_init(void)
+{
+ pxa_set_mci_info(&gumstix_mci_platform_data);
+}
+#else
+static void __init gumstix_mmc_init(void)
+{
+ pr_debug("Gumstix mmc disabled\n");
+}
+#endif
+
+#ifdef CONFIG_USB_PXA25X
+static struct gpio_vbus_mach_info gumstix_udc_info = {
+ .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn,
+ .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx,
+};
+
+static struct platform_device gumstix_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &gumstix_udc_info,
+ },
+};
+
+static void __init gumstix_udc_init(void)
+{
+ platform_device_register(&gumstix_gpio_vbus);
+}
+#else
+static void gumstix_udc_init(void)
+{
+ pr_debug("Gumstix udc is disabled\n");
+}
+#endif
+
+#ifdef CONFIG_BT
+/* Normally, the bootloader would have enabled this 32kHz clock but many
+** boards still have u-boot 1.1.4 so we check if it has been turned on and
+** if not, we turn it on with a warning message. */
+static void gumstix_setup_bt_clock(void)
+{
+ int timeout = 500;
+
+ if (!(OSCC & OSCC_OOK))
+ pr_warning("32kHz clock was not on. Bootloader may need to "
+ "be updated\n");
+ else
+ return;
+
+ OSCC |= OSCC_OON;
+ do {
+ if (OSCC & OSCC_OOK)
+ break;
+ udelay(1);
+ } while (--timeout);
+ if (!timeout)
+ pr_err("Failed to start 32kHz clock\n");
+}
+
+static void __init gumstix_bluetooth_init(void)
+{
+ int err;
+
+ gumstix_setup_bt_clock();
+
+ err = gpio_request(GPIO_GUMSTIX_BTRESET, "BTRST");
+ if (err) {
+ pr_err("gumstix: failed request gpio for bluetooth reset\n");
+ return;
+ }
+
+ err = gpio_direction_output(GPIO_GUMSTIX_BTRESET, 1);
+ if (err) {
+ pr_err("gumstix: can't reset bluetooth\n");
+ return;
+ }
+ gpio_set_value(GPIO_GUMSTIX_BTRESET, 0);
+ udelay(100);
+ gpio_set_value(GPIO_GUMSTIX_BTRESET, 1);
+}
+#else
+static void gumstix_bluetooth_init(void)
+{
+ pr_debug("Gumstix Bluetooth is disabled\n");
+}
+#endif
+
+static unsigned long gumstix_pin_config[] __initdata = {
+ GPIO12_32KHz,
+ /* BTUART */
+ GPIO42_HWUART_RXD,
+ GPIO43_HWUART_TXD,
+ GPIO44_HWUART_CTS,
+ GPIO45_HWUART_RTS,
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO53_MMC_CLK,
+ GPIO8_MMC_CS0,
+};
+
+int __attribute__((weak)) am200_init(void)
+{
+ return 0;
+}
+
+int __attribute__((weak)) am300_init(void)
+{
+ return 0;
+}
+
+static void __init carrier_board_init(void)
+{
+ /*
+ * put carrier/expansion board init here if
+ * they cannot be detected programatically
+ */
+ am200_init();
+ am300_init();
+}
+
+static void __init gumstix_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(gumstix_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_hwuart_info(NULL);
+
+ gumstix_bluetooth_init();
+ gumstix_udc_init();
+ gumstix_mmc_init();
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+ carrier_board_init();
+}
+
+MACHINE_START(GUMSTIX, "Gumstix")
+ .boot_params = 0xa0000100, /* match u-boot bi_boot_params */
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = gumstix_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c
new file mode 100644
index 00000000..657db469
--- /dev/null
+++ b/arch/arm/mach-pxa/h5000.c
@@ -0,0 +1,210 @@
+/*
+ * Hardware definitions for HP iPAQ h5xxx Handheld Computers
+ *
+ * Copyright 2000-2003 Hewlett-Packard Company.
+ * Copyright 2002 Jamey Hicks <jamey.hicks@hp.com>
+ * Copyright 2004-2005 Phil Blundell <pb@handhelds.org>
+ * Copyright 2007-2008 Anton Vorontsov <cbouatmailru@gmail.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.
+ *
+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * Author: Jamey Hicks.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa25x.h>
+#include <mach/h5000.h>
+#include <mach/udc.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+
+/*
+ * Flash
+ */
+
+static struct mtd_partition h5000_flash0_partitions[] = {
+ {
+ .name = "bootldr",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "root",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static struct mtd_partition h5000_flash1_partitions[] = {
+ {
+ .name = "second root",
+ .size = SZ_16M - 0x00040000,
+ .offset = 0,
+ },
+ {
+ .name = "asset",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data h5000_flash0_data = {
+ .width = 4,
+ .parts = h5000_flash0_partitions,
+ .nr_parts = ARRAY_SIZE(h5000_flash0_partitions),
+};
+
+static struct physmap_flash_data h5000_flash1_data = {
+ .width = 4,
+ .parts = h5000_flash1_partitions,
+ .nr_parts = ARRAY_SIZE(h5000_flash1_partitions),
+};
+
+static struct resource h5000_flash0_resources = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct resource h5000_flash1_resources = {
+ .start = PXA_CS0_PHYS + SZ_32M,
+ .end = PXA_CS0_PHYS + SZ_32M + SZ_16M - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
+};
+
+static struct platform_device h5000_flash[] = {
+ {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &h5000_flash0_resources,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &h5000_flash0_data,
+ },
+ },
+ {
+ .name = "physmap-flash",
+ .id = 1,
+ .resource = &h5000_flash1_resources,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &h5000_flash1_data,
+ },
+ },
+};
+
+/*
+ * USB Device Controller
+ */
+
+static struct pxa2xx_udc_mach_info h5000_udc_mach_info __initdata = {
+ .gpio_pullup = H5000_GPIO_USB_PULLUP,
+};
+
+/*
+ * GPIO setup
+ */
+
+static unsigned long h5000_pin_config[] __initdata = {
+ /* Crystal and Clock Signals */
+ GPIO12_32KHz,
+
+ /* SDRAM and Static Memory I/O Signals */
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO36_FFUART_DCD,
+ GPIO37_FFUART_DSR,
+ GPIO38_FFUART_RI,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO32_I2S_SYSCLK,
+};
+
+/*
+ * Localbus setup:
+ * CS0: Flash;
+ * CS1: MediaQ chip, select 16-bit bus and vlio;
+ * CS5: SAMCOP.
+ */
+
+static void fix_msc(void)
+{
+ __raw_writel(0x129c24f2, MSC0);
+ __raw_writel(0x7ff424fa, MSC1);
+ __raw_writel(0x7ff47ff4, MSC2);
+
+ __raw_writel(__raw_readl(MDREFR) | 0x02080000, MDREFR);
+}
+
+/*
+ * Platform devices
+ */
+
+static struct platform_device *devices[] __initdata = {
+ &h5000_flash[0],
+ &h5000_flash[1],
+};
+
+static void __init h5000_init(void)
+{
+ fix_msc();
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(h5000_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_udc_info(&h5000_udc_mach_info);
+ platform_add_devices(ARRAY_AND_SIZE(devices));
+}
+
+MACHINE_START(H5400, "HP iPAQ H5000")
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = h5000_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c
new file mode 100644
index 00000000..e8603eba
--- /dev/null
+++ b/arch/arm/mach-pxa/himalaya.c
@@ -0,0 +1,167 @@
+/*
+ * linux/arch/arm/mach-pxa/himalaya.c
+ *
+ * Hardware definitions for the HTC Himalaya
+ *
+ * Based on 2.6.21-hh20's himalaya.c and himalaya_lcd.c
+ *
+ * Copyright (c) 2008 Zbynek Michl <Zbynek.Michl@seznam.cz>
+ *
+ * This program is free software; you can 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/device.h>
+#include <linux/fb.h>
+#include <linux/platform_device.h>
+
+#include <video/w100fb.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
+#include "generic.h"
+
+/* ---------------------- Himalaya LCD definitions -------------------- */
+
+static struct w100_gen_regs himalaya_lcd_regs = {
+ .lcd_format = 0x00000003,
+ .lcdd_cntl1 = 0x00000000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x00fff003,
+ .genlcd_cntl2 = 0x00000003,
+ .genlcd_cntl3 = 0x000102aa,
+};
+
+static struct w100_mode himalaya4_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 0,
+ .right_margin = 31,
+ .upper_margin = 15,
+ .lower_margin = 0,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0xa0fb00f7,
+ .crtc_gs = 0xc0080007,
+ .crtc_vpos_gs = 0x00080007,
+ .crtc_rev = 0x0000000a,
+ .crtc_dclk = 0x81700030,
+ .crtc_gclk = 0x8015010f,
+ .crtc_goe = 0x00000000,
+ .pll_freq = 80,
+ .pixclk_divider = 15,
+ .pixclk_divider_rotated = 15,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+};
+
+static struct w100_mode himalaya6_lcd_mode = {
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 9,
+ .right_margin = 8,
+ .upper_margin = 5,
+ .lower_margin = 4,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0xa0fb00f7,
+ .crtc_gs = 0xc0080007,
+ .crtc_vpos_gs = 0x00080007,
+ .crtc_rev = 0x0000000a,
+ .crtc_dclk = 0xa1700030,
+ .crtc_gclk = 0x8015010f,
+ .crtc_goe = 0x00000000,
+ .pll_freq = 95,
+ .pixclk_divider = 0xb,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 1,
+ .sysclk_src = CLK_SRC_PLL,
+};
+
+static struct w100_gpio_regs himalaya_w100_gpio_info = {
+ .init_data1 = 0xffff0000, /* GPIO_DATA */
+ .gpio_dir1 = 0x00000000, /* GPIO_CNTL1 */
+ .gpio_oe1 = 0x003c0000, /* GPIO_CNTL2 */
+ .init_data2 = 0x00000000, /* GPIO_DATA2 */
+ .gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */
+ .gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */
+};
+
+static struct w100fb_mach_info himalaya_fb_info = {
+ .num_modes = 1,
+ .regs = &himalaya_lcd_regs,
+ .gpio = &himalaya_w100_gpio_info,
+ .xtal_freq = 16000000,
+};
+
+static struct resource himalaya_fb_resources[] = {
+ [0] = {
+ .start = 0x08000000,
+ .end = 0x08ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device himalaya_fb_device = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &himalaya_fb_info,
+ },
+ .num_resources = ARRAY_SIZE(himalaya_fb_resources),
+ .resource = himalaya_fb_resources,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static struct platform_device *devices[] __initdata = {
+ &himalaya_fb_device,
+};
+
+static void __init himalaya_lcd_init(void)
+{
+ int himalaya_boardid;
+
+ himalaya_boardid = 0x4; /* hardcoded (detection needs ASIC3 functions) */
+ printk(KERN_INFO "himalaya LCD Driver init. boardid=%d\n",
+ himalaya_boardid);
+
+ switch (himalaya_boardid) {
+ case 0x4:
+ himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+ break;
+ case 0x6:
+ himalaya_fb_info.modelist = &himalaya6_lcd_mode;
+ break;
+ default:
+ printk(KERN_INFO "himalaya lcd_init: unknown boardid=%d. Using 0x4\n",
+ himalaya_boardid);
+ himalaya_fb_info.modelist = &himalaya4_lcd_mode;
+ }
+}
+
+static void __init himalaya_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ himalaya_lcd_init();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+
+MACHINE_START(HIMALAYA, "HTC Himalaya")
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = himalaya_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
new file mode 100644
index 00000000..f941a495
--- /dev/null
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -0,0 +1,879 @@
+/*
+ * Support for HP iPAQ hx4700 PDAs.
+ *
+ * Copyright (c) 2008-2009 Philipp Zabel
+ *
+ * Based on code:
+ * Copyright (c) 2004 Hewlett-Packard Company.
+ * Copyright (c) 2005 SDG Systems, LLC
+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/lcd.h>
+#include <linux/mfd/htc-egpio.h>
+#include <linux/mfd/asic3.h>
+#include <linux/mtd/physmap.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/bq24022.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/max1586.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/hx4700.h>
+#include <mach/irda.h>
+
+#include <video/platform_lcd.h>
+#include <video/w100fb.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* Physical address space information */
+
+#define ATI_W3220_PHYS PXA_CS2_PHYS /* ATI Imageon 3220 Graphics */
+#define ASIC3_PHYS PXA_CS3_PHYS
+#define ASIC3_SD_PHYS (PXA_CS3_PHYS + 0x02000000)
+
+static unsigned long hx4700_pin_config[] __initdata = {
+
+ /* SDRAM and Static Memory I/O Signals */
+ GPIO20_nSDCS_2,
+ GPIO21_nSDCS_3,
+ GPIO15_nCS_1,
+ GPIO78_nCS_2, /* W3220 */
+ GPIO79_nCS_3, /* ASIC3 */
+ GPIO80_nCS_4,
+ GPIO33_nCS_5, /* EGPIO, WLAN */
+
+ /* PC CARD */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO85_nPCE_1,
+ GPIO104_PSKTSEL,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* FFUART (RS-232) */
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO36_FFUART_DCD,
+ GPIO37_FFUART_DSR,
+ GPIO38_FFUART_RI,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* PWM 1 (Backlight) */
+ GPIO17_PWM1_OUT,
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO113_I2S_SYSCLK,
+
+ /* SSP 1 (NavPoint) */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* SSP 2 (TSC2046) */
+ GPIO19_SSP2_SCLK,
+ GPIO86_SSP2_RXD,
+ GPIO87_SSP2_TXD,
+ GPIO88_GPIO,
+
+ /* HX4700 specific input GPIOs */
+ GPIO12_GPIO, /* ASIC3_IRQ */
+ GPIO13_GPIO, /* W3220_IRQ */
+ GPIO14_GPIO, /* nWLAN_IRQ */
+
+ GPIO10_GPIO, /* GSM_IRQ */
+ GPIO13_GPIO, /* CPLD_IRQ */
+ GPIO107_GPIO, /* DS1WM_IRQ */
+ GPIO108_GPIO, /* GSM_READY */
+ GPIO58_GPIO, /* TSC2046_nPENIRQ */
+ GPIO66_GPIO, /* nSDIO_IRQ */
+};
+
+#define HX4700_GPIO_IN(num, _desc) \
+ { .gpio = (num), .dir = 0, .desc = (_desc) }
+#define HX4700_GPIO_OUT(num, _init, _desc) \
+ { .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) }
+struct gpio_ress {
+ unsigned gpio : 8;
+ unsigned dir : 1;
+ unsigned init : 1;
+ char *desc;
+};
+
+static int hx4700_gpio_request(struct gpio_ress *gpios, int size)
+{
+ int i, rc = 0;
+ int gpio;
+ int dir;
+
+ for (i = 0; (!rc) && (i < size); i++) {
+ gpio = gpios[i].gpio;
+ dir = gpios[i].dir;
+ rc = gpio_request(gpio, gpios[i].desc);
+ if (rc) {
+ pr_err("Error requesting GPIO %d(%s) : %d\n",
+ gpio, gpios[i].desc, rc);
+ continue;
+ }
+ if (dir)
+ gpio_direction_output(gpio, gpios[i].init);
+ else
+ gpio_direction_input(gpio);
+ }
+ while ((rc) && (--i >= 0))
+ gpio_free(gpios[i].gpio);
+ return rc;
+}
+
+/*
+ * IRDA
+ */
+
+static struct pxaficp_platform_data ficp_info = {
+ .gpio_pwdown = GPIO105_HX4700_nIR_ON,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+/*
+ * GPIO Keys
+ */
+
+#define INIT_KEY(_code, _gpio, _active_low, _desc) \
+ { \
+ .code = KEY_##_code, \
+ .gpio = _gpio, \
+ .active_low = _active_low, \
+ .desc = _desc, \
+ .type = EV_KEY, \
+ .wakeup = 1, \
+ }
+
+static struct gpio_keys_button gpio_keys_buttons[] = {
+ INIT_KEY(POWER, GPIO0_HX4700_nKEY_POWER, 1, "Power button"),
+ INIT_KEY(MAIL, GPIO94_HX4700_KEY_MAIL, 0, "Mail button"),
+ INIT_KEY(ADDRESSBOOK, GPIO99_HX4700_KEY_CONTACTS,0, "Contacts button"),
+ INIT_KEY(RECORD, GPIOD6_nKEY_RECORD, 1, "Record button"),
+ INIT_KEY(CALENDAR, GPIOD1_nKEY_CALENDAR, 1, "Calendar button"),
+ INIT_KEY(HOMEPAGE, GPIOD3_nKEY_HOME, 1, "Home button"),
+};
+
+static struct gpio_keys_platform_data gpio_keys_data = {
+ .buttons = gpio_keys_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_keys_buttons),
+};
+
+static struct platform_device gpio_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &gpio_keys_data,
+ },
+ .id = -1,
+};
+
+/*
+ * ASIC3
+ */
+
+static u16 asic3_gpio_config[] = {
+ /* ASIC3 GPIO banks A and B along with some of C and D
+ implement the buffering for the CF slot. */
+ ASIC3_CONFIG_GPIO(0, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(1, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(2, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(3, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(4, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(5, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(6, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(7, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(8, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(9, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(10, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(11, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(12, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(13, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(14, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(15, 1, 1, 0),
+
+ ASIC3_CONFIG_GPIO(16, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(17, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(18, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(19, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(20, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(21, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(22, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(23, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(24, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(25, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(26, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(27, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(28, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(29, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(30, 1, 1, 0),
+ ASIC3_CONFIG_GPIO(31, 1, 1, 0),
+
+ /* GPIOC - CF, LEDs, SD */
+ ASIC3_GPIOC0_LED0, /* red */
+ ASIC3_GPIOC1_LED1, /* green */
+ ASIC3_GPIOC2_LED2, /* blue */
+ ASIC3_GPIOC4_CF_nCD,
+ ASIC3_GPIOC5_nCIOW,
+ ASIC3_GPIOC6_nCIOR,
+ ASIC3_GPIOC7_nPCE_1,
+ ASIC3_GPIOC8_nPCE_2,
+ ASIC3_GPIOC9_nPOE,
+ ASIC3_GPIOC10_nPWE,
+ ASIC3_GPIOC11_PSKTSEL,
+ ASIC3_GPIOC12_nPREG,
+ ASIC3_GPIOC13_nPWAIT,
+ ASIC3_GPIOC14_nPIOIS16,
+ ASIC3_GPIOC15_nPIOR,
+
+ /* GPIOD: input GPIOs, CF */
+ ASIC3_GPIOD11_nCIOIS16,
+ ASIC3_GPIOD12_nCWAIT,
+ ASIC3_GPIOD15_nPIOW,
+};
+
+static struct resource asic3_resources[] = {
+ /* GPIO part */
+ [0] = {
+ .start = ASIC3_PHYS,
+ .end = ASIC3_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ),
+ .end = gpio_to_irq(GPIO12_HX4700_ASIC3_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+ /* SD part */
+ [2] = {
+ .start = ASIC3_SD_PHYS,
+ .end = ASIC3_SD_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
+ .end = gpio_to_irq(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct asic3_platform_data asic3_platform_data = {
+ .gpio_config = asic3_gpio_config,
+ .gpio_config_num = ARRAY_SIZE(asic3_gpio_config),
+ .irq_base = IRQ_BOARD_START,
+ .gpio_base = HX4700_ASIC3_GPIO_BASE,
+};
+
+static struct platform_device asic3 = {
+ .name = "asic3",
+ .id = -1,
+ .resource = asic3_resources,
+ .num_resources = ARRAY_SIZE(asic3_resources),
+ .dev = {
+ .platform_data = &asic3_platform_data,
+ },
+};
+
+/*
+ * EGPIO
+ */
+
+static struct resource egpio_resources[] = {
+ [0] = {
+ .start = PXA_CS5_PHYS,
+ .end = PXA_CS5_PHYS + 0x4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct htc_egpio_chip egpio_chips[] = {
+ [0] = {
+ .reg_start = 0,
+ .gpio_base = HX4700_EGPIO_BASE,
+ .num_gpios = 8,
+ .direction = HTC_EGPIO_OUTPUT,
+ },
+};
+
+static struct htc_egpio_platform_data egpio_info = {
+ .reg_width = 16,
+ .bus_width = 16,
+ .chip = egpio_chips,
+ .num_chips = ARRAY_SIZE(egpio_chips),
+};
+
+static struct platform_device egpio = {
+ .name = "htc-egpio",
+ .id = -1,
+ .resource = egpio_resources,
+ .num_resources = ARRAY_SIZE(egpio_resources),
+ .dev = {
+ .platform_data = &egpio_info,
+ },
+};
+
+/*
+ * LCD - Sony display connected to ATI Imageon w3220
+ */
+
+static void sony_lcd_init(void)
+{
+ gpio_set_value(GPIO84_HX4700_LCD_SQN, 1);
+ gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
+ gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0);
+ gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 0);
+ gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0);
+ mdelay(10);
+ gpio_set_value(GPIO59_HX4700_LCD_PC1, 0);
+ gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
+ mdelay(20);
+
+ gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 1);
+ mdelay(5);
+ gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 1);
+
+ /* FIXME: init w3220 registers here */
+
+ mdelay(5);
+ gpio_set_value(GPIO70_HX4700_LCD_SLIN1, 1);
+ mdelay(10);
+ gpio_set_value(GPIO62_HX4700_LCD_nRESET, 1);
+ mdelay(10);
+ gpio_set_value(GPIO59_HX4700_LCD_PC1, 1);
+ mdelay(10);
+ gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 1);
+}
+
+static void sony_lcd_off(void)
+{
+ gpio_set_value(GPIO59_HX4700_LCD_PC1, 0);
+ gpio_set_value(GPIO62_HX4700_LCD_nRESET, 0);
+ mdelay(10);
+ gpio_set_value(GPIO112_HX4700_LCD_N2V7_7V3_ON, 0);
+ mdelay(10);
+ gpio_set_value(GPIO111_HX4700_LCD_AVDD_3V3_ON, 0);
+ mdelay(10);
+ gpio_set_value(GPIO110_HX4700_LCD_LVDD_3V3_ON, 0);
+}
+
+#ifdef CONFIG_PM
+static void w3220_lcd_suspend(struct w100fb_par *wfb)
+{
+ sony_lcd_off();
+}
+
+static void w3220_lcd_resume(struct w100fb_par *wfb)
+{
+ sony_lcd_init();
+}
+#else
+#define w3220_lcd_resume NULL
+#define w3220_lcd_suspend NULL
+#endif
+
+static struct w100_tg_info w3220_tg_info = {
+ .suspend = w3220_lcd_suspend,
+ .resume = w3220_lcd_resume,
+};
+
+/* W3220_VGA QVGA */
+static struct w100_gen_regs w3220_regs = {
+ .lcd_format = 0x00000003,
+ .lcdd_cntl1 = 0x00000000,
+ .lcdd_cntl2 = 0x0003ffff,
+ .genlcd_cntl1 = 0x00abf003, /* 0x00fff003 */
+ .genlcd_cntl2 = 0x00000003,
+ .genlcd_cntl3 = 0x000102aa,
+};
+
+static struct w100_mode w3220_modes[] = {
+{
+ .xres = 480,
+ .yres = 640,
+ .left_margin = 15,
+ .right_margin = 16,
+ .upper_margin = 8,
+ .lower_margin = 7,
+ .crtc_ss = 0x00000000,
+ .crtc_ls = 0xa1ff01f9, /* 0x21ff01f9 */
+ .crtc_gs = 0xc0000000, /* 0x40000000 */
+ .crtc_vpos_gs = 0x0000028f,
+ .crtc_ps1_active = 0x00000000, /* 0x41060010 */
+ .crtc_rev = 0,
+ .crtc_dclk = 0x80000000,
+ .crtc_gclk = 0x040a0104,
+ .crtc_goe = 0,
+ .pll_freq = 95,
+ .pixclk_divider = 4,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+},
+{
+ .xres = 240,
+ .yres = 320,
+ .left_margin = 9,
+ .right_margin = 8,
+ .upper_margin = 5,
+ .lower_margin = 4,
+ .crtc_ss = 0x80150014,
+ .crtc_ls = 0xa0fb00f7,
+ .crtc_gs = 0xc0080007,
+ .crtc_vpos_gs = 0x00080007,
+ .crtc_rev = 0x0000000a,
+ .crtc_dclk = 0x81700030,
+ .crtc_gclk = 0x8015010f,
+ .crtc_goe = 0x00000000,
+ .pll_freq = 95,
+ .pixclk_divider = 4,
+ .pixclk_divider_rotated = 4,
+ .pixclk_src = CLK_SRC_PLL,
+ .sysclk_divider = 0,
+ .sysclk_src = CLK_SRC_PLL,
+},
+};
+
+struct w100_mem_info w3220_mem_info = {
+ .ext_cntl = 0x09640011,
+ .sdram_mode_reg = 0x00600021,
+ .ext_timing_cntl = 0x1a001545, /* 0x15001545 */
+ .io_cntl = 0x7ddd7333,
+ .size = 0x1fffff,
+};
+
+struct w100_bm_mem_info w3220_bm_mem_info = {
+ .ext_mem_bw = 0x50413e01,
+ .offset = 0,
+ .ext_timing_ctl = 0x00043f7f,
+ .ext_cntl = 0x00000010,
+ .mode_reg = 0x00250000,
+ .io_cntl = 0x0fff0000,
+ .config = 0x08301480,
+};
+
+static struct w100_gpio_regs w3220_gpio_info = {
+ .init_data1 = 0xdfe00100, /* GPIO_DATA */
+ .gpio_dir1 = 0xffff0000, /* GPIO_CNTL1 */
+ .gpio_oe1 = 0x00000000, /* GPIO_CNTL2 */
+ .init_data2 = 0x00000000, /* GPIO_DATA2 */
+ .gpio_dir2 = 0x00000000, /* GPIO_CNTL3 */
+ .gpio_oe2 = 0x00000000, /* GPIO_CNTL4 */
+};
+
+static struct w100fb_mach_info w3220_info = {
+ .tg = &w3220_tg_info,
+ .mem = &w3220_mem_info,
+ .bm_mem = &w3220_bm_mem_info,
+ .gpio = &w3220_gpio_info,
+ .regs = &w3220_regs,
+ .modelist = w3220_modes,
+ .num_modes = 2,
+ .xtal_freq = 16000000,
+};
+
+static struct resource w3220_resources[] = {
+ [0] = {
+ .start = ATI_W3220_PHYS,
+ .end = ATI_W3220_PHYS + 0x00ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device w3220 = {
+ .name = "w100fb",
+ .id = -1,
+ .dev = {
+ .platform_data = &w3220_info,
+ },
+ .num_resources = ARRAY_SIZE(w3220_resources),
+ .resource = w3220_resources,
+};
+
+static void hx4700_lcd_set_power(struct plat_lcd_data *pd, unsigned int power)
+{
+ if (power)
+ sony_lcd_init();
+ else
+ sony_lcd_off();
+}
+
+static struct plat_lcd_data hx4700_lcd_data = {
+ .set_power = hx4700_lcd_set_power,
+};
+
+static struct platform_device hx4700_lcd = {
+ .name = "platform-lcd",
+ .id = -1,
+ .dev = {
+ .platform_data = &hx4700_lcd_data,
+ .parent = &w3220.dev,
+ },
+};
+
+/*
+ * Backlight
+ */
+
+static struct platform_pwm_backlight_data backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 200,
+ .dft_brightness = 100,
+ .pwm_period_ns = 30923,
+};
+
+static struct platform_device backlight = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &pxa27x_device_pwm1.dev,
+ .platform_data = &backlight_data,
+ },
+};
+
+/*
+ * USB "Transceiver"
+ */
+
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+ .gpio_pullup = GPIO76_HX4700_USBC_PUEN,
+ .gpio_vbus = GPIOD14_nUSBC_DETECT,
+ .gpio_vbus_inverted = 1,
+};
+
+static struct platform_device gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_vbus_info,
+ },
+};
+
+/*
+ * Touchscreen - TSC2046 connected to SSP2
+ */
+
+static const struct ads7846_platform_data tsc2046_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .pressure_max = 1024,
+ .debounce_max = 10,
+ .debounce_tol = 3,
+ .debounce_rep = 1,
+ .gpio_pendown = GPIO58_HX4700_TSC2046_nPENIRQ,
+};
+
+static struct pxa2xx_spi_chip tsc2046_chip = {
+ .tx_threshold = 1,
+ .rx_threshold = 2,
+ .timeout = 64,
+ .gpio_cs = GPIO88_HX4700_TSC2046_CS,
+};
+
+static struct spi_board_info tsc2046_board_info[] __initdata = {
+ {
+ .modalias = "ads7846",
+ .bus_num = 2,
+ .max_speed_hz = 2600000, /* 100 kHz sample rate */
+ .irq = gpio_to_irq(GPIO58_HX4700_TSC2046_nPENIRQ),
+ .platform_data = &tsc2046_info,
+ .controller_data = &tsc2046_chip,
+ },
+};
+
+static struct pxa2xx_spi_master pxa_ssp2_master_info = {
+ .num_chipselect = 1,
+ .clock_enable = CKEN_SSP2,
+ .enable_dma = 1,
+};
+
+/*
+ * External power
+ */
+
+static int power_supply_init(struct device *dev)
+{
+ return gpio_request(GPIOD9_nAC_IN, "AC charger detect");
+}
+
+static int hx4700_is_ac_online(void)
+{
+ return !gpio_get_value(GPIOD9_nAC_IN);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(GPIOD9_nAC_IN);
+}
+
+static char *hx4700_supplicants[] = {
+ "ds2760-battery.0", "backup-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = hx4700_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = hx4700_supplicants,
+ .num_supplicants = ARRAY_SIZE(hx4700_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+ [0] = {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = gpio_to_irq(GPIOD9_nAC_IN),
+ .end = gpio_to_irq(GPIOD9_nAC_IN),
+ },
+ [1] = {
+ .name = "usb",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = gpio_to_irq(GPIOD14_nUSBC_DETECT),
+ .end = gpio_to_irq(GPIOD14_nUSBC_DETECT),
+ },
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+/*
+ * Battery charger
+ */
+
+static struct regulator_consumer_supply bq24022_consumers[] = {
+ {
+ .dev = &gpio_vbus.dev,
+ .supply = "vbus_draw",
+ },
+ {
+ .dev = &power_supply.dev,
+ .supply = "ac_draw",
+ },
+};
+
+static struct regulator_init_data bq24022_init_data = {
+ .constraints = {
+ .max_uA = 500000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+ .consumer_supplies = bq24022_consumers,
+};
+
+static struct bq24022_mach_info bq24022_info = {
+ .gpio_nce = GPIO72_HX4700_BQ24022_nCHARGE_EN,
+ .gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2,
+ .init_data = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+ .name = "bq24022",
+ .id = -1,
+ .dev = {
+ .platform_data = &bq24022_info,
+ },
+};
+
+/*
+ * StrataFlash
+ */
+
+static void hx4700_set_vpp(struct platform_device *pdev, int vpp)
+{
+ gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp);
+}
+
+static struct resource strataflash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_128M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data strataflash_data = {
+ .width = 4,
+ .set_vpp = hx4700_set_vpp,
+};
+
+static struct platform_device strataflash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &strataflash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &strataflash_data,
+ },
+};
+
+/*
+ * Maxim MAX1587A on PI2C
+ */
+
+static struct regulator_consumer_supply max1587a_consumer = {
+ .supply = "vcc_core",
+};
+
+static struct regulator_init_data max1587a_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 900000,
+ .max_uV = 1705000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &max1587a_consumer,
+};
+
+static struct max1586_subdev_data max1587a_subdev = {
+ .name = "vcc_core",
+ .id = MAX1586_V3,
+ .platform_data = &max1587a_v3_info,
+};
+
+static struct max1586_platform_data max1587a_info = {
+ .num_subdevs = 1,
+ .subdevs = &max1587a_subdev,
+ .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
+};
+
+static struct i2c_board_info __initdata pi2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &max1587a_info,
+ },
+};
+
+/*
+ * PCMCIA
+ */
+
+static struct platform_device pcmcia = {
+ .name = "hx4700-pcmcia",
+ .dev = {
+ .parent = &asic3.dev,
+ },
+};
+
+/*
+ * Platform devices
+ */
+
+static struct platform_device *devices[] __initdata = {
+ &asic3,
+ &gpio_keys,
+ &backlight,
+ &w3220,
+ &hx4700_lcd,
+ &egpio,
+ &bq24022,
+ &gpio_vbus,
+ &power_supply,
+ &strataflash,
+ &pcmcia,
+};
+
+static struct gpio_ress global_gpios[] = {
+ HX4700_GPIO_IN(GPIO12_HX4700_ASIC3_IRQ, "ASIC3_IRQ"),
+ HX4700_GPIO_IN(GPIO13_HX4700_W3220_IRQ, "W3220_IRQ"),
+ HX4700_GPIO_IN(GPIO14_HX4700_nWLAN_IRQ, "WLAN_IRQ"),
+ HX4700_GPIO_OUT(GPIO59_HX4700_LCD_PC1, 1, "LCD_PC1"),
+ HX4700_GPIO_OUT(GPIO62_HX4700_LCD_nRESET, 1, "LCD_RESET"),
+ HX4700_GPIO_OUT(GPIO70_HX4700_LCD_SLIN1, 1, "LCD_SLIN1"),
+ HX4700_GPIO_OUT(GPIO84_HX4700_LCD_SQN, 1, "LCD_SQN"),
+ HX4700_GPIO_OUT(GPIO110_HX4700_LCD_LVDD_3V3_ON, 1, "LCD_LVDD"),
+ HX4700_GPIO_OUT(GPIO111_HX4700_LCD_AVDD_3V3_ON, 1, "LCD_AVDD"),
+ HX4700_GPIO_OUT(GPIO32_HX4700_RS232_ON, 1, "RS232_ON"),
+ HX4700_GPIO_OUT(GPIO71_HX4700_ASIC3_nRESET, 1, "ASIC3_nRESET"),
+ HX4700_GPIO_OUT(GPIO82_HX4700_EUART_RESET, 1, "EUART_RESET"),
+ HX4700_GPIO_OUT(GPIO105_HX4700_nIR_ON, 1, "nIR_EN"),
+};
+
+static void __init hx4700_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(hx4700_pin_config));
+ hx4700_gpio_request(ARRAY_AND_SIZE(global_gpios));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ pxa_set_ficp_info(&ficp_info);
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
+ pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
+ spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
+
+ gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 0);
+ mdelay(10);
+ gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
+ mdelay(10);
+}
+
+MACHINE_START(H4700, "HP iPAQ HX4700")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = HX4700_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = hx4700_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
new file mode 100644
index 00000000..6cedc81d
--- /dev/null
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -0,0 +1,199 @@
+/*
+ * linux/arch/arm/mach-pxa/icontrol.c
+ *
+ * Support for the iControl and SafeTcam platforms from TMT Services
+ * using the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za>
+ *
+ * This program is free software; you can 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/irq.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa320.h>
+#include <mach/mxm8x10.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include "generic.h"
+
+#define ICONTROL_MCP251x_nCS1 (15)
+#define ICONTROL_MCP251x_nCS2 (16)
+#define ICONTROL_MCP251x_nCS3 (17)
+#define ICONTROL_MCP251x_nCS4 (24)
+
+#define ICONTROL_MCP251x_nIRQ1 (74)
+#define ICONTROL_MCP251x_nIRQ2 (75)
+#define ICONTROL_MCP251x_nIRQ3 (76)
+#define ICONTROL_MCP251x_nIRQ4 (77)
+
+static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS1
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS2
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS3
+};
+
+static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
+ .tx_threshold = 8,
+ .rx_threshold = 128,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = ICONTROL_MCP251x_nCS4
+};
+
+static struct mcp251x_platform_data mcp251x_info = {
+ .oscillator_frequency = 16E6,
+ .board_specific_setup = NULL,
+ .power_enable = NULL,
+ .transceiver_enable = NULL
+};
+
+static struct spi_board_info mcp251x_board_info[] = {
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 6500000,
+ .bus_num = 3,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info1,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
+ },
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 6500000,
+ .bus_num = 3,
+ .chip_select = 1,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info2,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
+ },
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 6500000,
+ .bus_num = 4,
+ .chip_select = 0,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info3,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
+ },
+ {
+ .modalias = "mcp2515",
+ .max_speed_hz = 6500000,
+ .bus_num = 4,
+ .chip_select = 1,
+ .platform_data = &mcp251x_info,
+ .controller_data = &mcp251x_chip_info4,
+ .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ4)
+ }
+};
+
+static struct pxa2xx_spi_master pxa_ssp3_spi_master_info = {
+ .clock_enable = CKEN_SSP3,
+ .num_chipselect = 2,
+ .enable_dma = 1
+};
+
+static struct pxa2xx_spi_master pxa_ssp4_spi_master_info = {
+ .clock_enable = CKEN_SSP4,
+ .num_chipselect = 2,
+ .enable_dma = 1
+};
+
+struct platform_device pxa_spi_ssp3 = {
+ .name = "pxa2xx-spi",
+ .id = 3,
+ .dev = {
+ .platform_data = &pxa_ssp3_spi_master_info,
+ }
+};
+
+struct platform_device pxa_spi_ssp4 = {
+ .name = "pxa2xx-spi",
+ .id = 4,
+ .dev = {
+ .platform_data = &pxa_ssp4_spi_master_info,
+ }
+};
+
+static struct platform_device *icontrol_spi_devices[] __initdata = {
+ &pxa_spi_ssp3,
+ &pxa_spi_ssp4,
+};
+
+static mfp_cfg_t mfp_can_cfg[] __initdata = {
+ /* CAN CS lines */
+ GPIO15_GPIO,
+ GPIO16_GPIO,
+ GPIO17_GPIO,
+ GPIO24_GPIO,
+
+ /* SPI (SSP3) lines */
+ GPIO89_SSP3_SCLK,
+ GPIO91_SSP3_TXD,
+ GPIO92_SSP3_RXD,
+
+ /* SPI (SSP4) lines */
+ GPIO93_SSP4_SCLK,
+ GPIO95_SSP4_TXD,
+ GPIO96_SSP4_RXD,
+
+ /* CAN nIRQ lines */
+ GPIO74_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO75_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO76_GPIO | MFP_LPM_EDGE_RISE,
+ GPIO77_GPIO | MFP_LPM_EDGE_RISE
+};
+
+static void __init icontrol_can_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+ platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
+ spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
+}
+
+static void __init icontrol_init(void)
+{
+ mxm_8x10_barebones_init();
+ mxm_8x10_usb_host_init();
+ mxm_8x10_mmc_init();
+
+ icontrol_can_init();
+}
+
+MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = icontrol_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
new file mode 100644
index 00000000..f7fb64f1
--- /dev/null
+++ b/arch/arm/mach-pxa/idp.c
@@ -0,0 +1,201 @@
+/*
+ * linux/arch/arm/mach-pxa/idp.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.
+ *
+ * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
+ *
+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
+ * Initial code
+ *
+ * 2005-02-15: Cliff Brake <cliff.brake@gmail.com>
+ * <http://www.vibren.com> <http://bec-systems.com>
+ * Updated for 2.6 kernel
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa25x.h>
+#include <mach/idp.h>
+#include <mach/pxafb.h>
+#include <mach/bitfield.h>
+#include <mach/mmc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/* TODO:
+ * - add pxa2xx_audio_ops_t device structure
+ * - Ethernet interrupt
+ */
+
+static unsigned long idp_pin_config[] __initdata = {
+ /* LCD */
+ GPIOxx_LCD_DSTN_16BPP,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+
+ /* Ethernet */
+ GPIO33_nCS_5, /* Ethernet CS */
+ GPIO4_GPIO, /* Ethernet IRQ */
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = (IDP_ETH_PHYS + 0x300),
+ .end = (IDP_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO(4),
+ .end = IRQ_GPIO(4),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static void idp_backlight_power(int on)
+{
+ if (on) {
+ IDP_CPLD_LCD |= (1<<1);
+ } else {
+ IDP_CPLD_LCD &= ~(1<<1);
+ }
+}
+
+static void idp_vlcd(int on)
+{
+ if (on) {
+ IDP_CPLD_LCD |= (1<<2);
+ } else {
+ IDP_CPLD_LCD &= ~(1<<2);
+ }
+}
+
+static void idp_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+ if (on) {
+ IDP_CPLD_LCD |= (1<<0);
+ } else {
+ IDP_CPLD_LCD &= ~(1<<0);
+ }
+
+ /* call idp_vlcd for now as core driver does not support
+ * both power and vlcd hooks. Note, this is not technically
+ * the correct sequence, but seems to work. Disclaimer:
+ * this may eventually damage the display.
+ */
+
+ idp_vlcd(on);
+}
+
+static struct pxafb_mode_info sharp_lm8v31_mode = {
+ .pixclock = 270000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 1,
+ .left_margin = 3,
+ .right_margin = 3,
+ .vsync_len = 1,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+ .modes = &sharp_lm8v31_mode,
+ .num_modes = 1,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_AC_BIAS_FREQ(255),
+ .pxafb_backlight_power = &idp_backlight_power,
+ .pxafb_lcd_power = &idp_lcd_power
+};
+
+static struct pxamci_platform_data idp_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void __init idp_init(void)
+{
+ printk("idp_init()\n");
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(idp_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_device_register(&smc91x_device);
+ //platform_device_register(&mst_audio_device);
+ pxa_set_fb_info(NULL, &sharp_lm8v31);
+ pxa_set_mci_info(&idp_mci_platform_data);
+}
+
+static struct map_desc idp_io_desc[] __initdata = {
+ {
+ .virtual = IDP_COREVOLT_VIRT,
+ .pfn = __phys_to_pfn(IDP_COREVOLT_PHYS),
+ .length = IDP_COREVOLT_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IDP_CPLD_VIRT,
+ .pfn = __phys_to_pfn(IDP_CPLD_PHYS),
+ .length = IDP_CPLD_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init idp_map_io(void)
+{
+ pxa25x_map_io();
+ iotable_init(idp_io_desc, ARRAY_SIZE(idp_io_desc));
+}
+
+
+MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
+ /* Maintainer: Vibren Technologies */
+ .map_io = idp_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = idp_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/include/mach/addr-map.h b/arch/arm/mach-pxa/include/mach/addr-map.h
new file mode 100644
index 00000000..f4c03659
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/addr-map.h
@@ -0,0 +1,48 @@
+#ifndef __ASM_MACH_ADDR_MAP_H
+#define __ASM_MACH_ADDR_MAP_H
+
+/*
+ * Chip Selects
+ */
+#define PXA_CS0_PHYS 0x00000000
+#define PXA_CS1_PHYS 0x04000000
+#define PXA_CS2_PHYS 0x08000000
+#define PXA_CS3_PHYS 0x0C000000
+#define PXA_CS4_PHYS 0x10000000
+#define PXA_CS5_PHYS 0x14000000
+
+#define PXA300_CS0_PHYS 0x00000000 /* PXA300/PXA310 _only_ */
+#define PXA300_CS1_PHYS 0x30000000 /* PXA300/PXA310 _only_ */
+#define PXA3xx_CS2_PHYS 0x10000000
+#define PXA3xx_CS3_PHYS 0x14000000
+
+/*
+ * Peripheral Bus
+ */
+#define PERIPH_PHYS 0x40000000
+#define PERIPH_VIRT 0xf2000000
+#define PERIPH_SIZE 0x02000000
+
+/*
+ * Static Memory Controller (w/ SDRAM controls on PXA25x/PXA27x)
+ */
+#define PXA2XX_SMEMC_PHYS 0x48000000
+#define PXA3XX_SMEMC_PHYS 0x4a000000
+#define SMEMC_VIRT 0xf6000000
+#define SMEMC_SIZE 0x00100000
+
+/*
+ * Dynamic Memory Controller (only on PXA3xx)
+ */
+#define DMEMC_PHYS 0x48100000
+#define DMEMC_VIRT 0xf6100000
+#define DMEMC_SIZE 0x00100000
+
+/*
+ * Internal Memory Controller (PXA27x and later)
+ */
+#define IMEMC_PHYS 0x58000000
+#define IMEMC_VIRT 0xfe000000
+#define IMEMC_SIZE 0x00100000
+
+#endif /* __ASM_MACH_ADDR_MAP_H */
diff --git a/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h b/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h
new file mode 100644
index 00000000..d428be4d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/arcom-pcmcia.h
@@ -0,0 +1,11 @@
+#ifndef __ARCOM_PCMCIA_H
+#define __ARCOM_PCMCIA_H
+
+struct arcom_pcmcia_pdata {
+ int cd_gpio;
+ int rdy_gpio;
+ int pwr_gpio;
+ void (*reset)(int state);
+};
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h
new file mode 100644
index 00000000..a3449e35
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/audio.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_ARCH_AUDIO_H__
+#define __ASM_ARCH_AUDIO_H__
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/ac97_codec.h>
+
+/*
+ * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95)
+ * a -1 value means no gpio will be used for reset
+ * @codec_pdata: AC97 codec platform_data
+
+ * reset_gpio should only be specified for pxa27x CPUs where a silicon
+ * bug prevents correct operation of the reset line. If not specified,
+ * the default behaviour on these CPUs is to consider gpio 113 as the
+ * AC97 reset line, which is the default on most boards.
+ */
+typedef struct {
+ int (*startup)(struct snd_pcm_substream *, void *);
+ void (*shutdown)(struct snd_pcm_substream *, void *);
+ void (*suspend)(void *);
+ void (*resume)(void *);
+ void *priv;
+ int reset_gpio;
+ void *codec_pdata[AC97_BUS_MAX_DEVICES];
+} pxa2xx_audio_ops_t;
+
+extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops);
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/balloon3.h b/arch/arm/mach-pxa/include/mach/balloon3.h
new file mode 100644
index 00000000..7074e761
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/balloon3.h
@@ -0,0 +1,183 @@
+/*
+ * linux/include/asm-arm/arch-pxa/balloon3.h
+ *
+ * Authors: Nick Bane and Wookey
+ * Created: Oct, 2005
+ * Copyright: Toby Churchill Ltd
+ * Cribbed from mainstone.c, by Nicholas Pitre
+ *
+ * This program is free software; you can 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_BALLOON3_H
+#define ASM_ARCH_BALLOON3_H
+
+enum balloon3_features {
+ BALLOON3_FEATURE_OHCI,
+ BALLOON3_FEATURE_MMC,
+ BALLOON3_FEATURE_CF,
+ BALLOON3_FEATURE_AUDIO,
+ BALLOON3_FEATURE_TOPPOLY,
+};
+
+#define BALLOON3_FPGA_PHYS PXA_CS4_PHYS
+#define BALLOON3_FPGA_VIRT (0xf1000000) /* as per balloon2 */
+#define BALLOON3_FPGA_LENGTH 0x01000000
+
+#define BALLOON3_FPGA_SETnCLR (0x1000)
+
+/* FPGA / CPLD registers for CF socket */
+#define BALLOON3_CF_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00e00008)
+#define BALLOON3_CF_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00008)
+/* FPGA / CPLD version register */
+#define BALLOON3_FPGA_VER (BALLOON3_FPGA_VIRT + 0x00e0001c)
+/* FPGA / CPLD registers for NAND flash */
+#define BALLOON3_NAND_BASE (PXA_CS4_PHYS + 0x00e00000)
+#define BALLOON3_NAND_IO_REG (BALLOON3_FPGA_VIRT + 0x00e00000)
+#define BALLOON3_NAND_CONTROL2_REG (BALLOON3_FPGA_VIRT + 0x00e00010)
+#define BALLOON3_NAND_STAT_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
+#define BALLOON3_NAND_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e00014)
+
+/* fpga/cpld interrupt control register */
+#define BALLOON3_INT_CONTROL_REG (BALLOON3_FPGA_VIRT + 0x00e0000C)
+#define BALLOON3_VERSION_REG (BALLOON3_FPGA_VIRT + 0x00e0001c)
+
+#define BALLOON3_SAMOSA_ADDR_REG (BALLOON3_FPGA_VIRT + 0x00c00000)
+#define BALLOON3_SAMOSA_DATA_REG (BALLOON3_FPGA_VIRT + 0x00c00004)
+#define BALLOON3_SAMOSA_STATUS_REG (BALLOON3_FPGA_VIRT + 0x00c0001c)
+
+/* CF Status Register bits (read-only) bits */
+#define BALLOON3_CF_nIRQ (1 << 0)
+#define BALLOON3_CF_nSTSCHG_BVD1 (1 << 1)
+
+/* CF Control Set Register bits / CF Control Clear Register bits (write-only) */
+#define BALLOON3_CF_RESET (1 << 0)
+#define BALLOON3_CF_ENABLE (1 << 1)
+#define BALLOON3_CF_ADD_ENABLE (1 << 2)
+
+/* CF Interrupt sources */
+#define BALLOON3_BP_CF_NRDY_IRQ BALLOON3_IRQ(0)
+#define BALLOON3_BP_NSTSCHG_IRQ BALLOON3_IRQ(1)
+
+/* NAND Control register */
+#define BALLOON3_NAND_CONTROL_FLWP (1 << 7)
+#define BALLOON3_NAND_CONTROL_FLSE (1 << 6)
+#define BALLOON3_NAND_CONTROL_FLCE3 (1 << 5)
+#define BALLOON3_NAND_CONTROL_FLCE2 (1 << 4)
+#define BALLOON3_NAND_CONTROL_FLCE1 (1 << 3)
+#define BALLOON3_NAND_CONTROL_FLCE0 (1 << 2)
+#define BALLOON3_NAND_CONTROL_FLALE (1 << 1)
+#define BALLOON3_NAND_CONTROL_FLCLE (1 << 0)
+
+/* NAND Status register */
+#define BALLOON3_NAND_STAT_RNB (1 << 0)
+
+/* NAND Control2 register */
+#define BALLOON3_NAND_CONTROL2_16BIT (1 << 0)
+
+/* GPIOs for irqs */
+#define BALLOON3_GPIO_AUX_NIRQ (94)
+#define BALLOON3_GPIO_CODEC_IRQ (95)
+
+/* Timer and Idle LED locations */
+#define BALLOON3_GPIO_LED_NAND (9)
+#define BALLOON3_GPIO_LED_IDLE (10)
+
+/* backlight control */
+#define BALLOON3_GPIO_RUN_BACKLIGHT (99)
+
+#define BALLOON3_GPIO_S0_CD (105)
+
+/* NAND */
+#define BALLOON3_GPIO_RUN_NAND (102)
+
+/* PCF8574A Leds */
+#define BALLOON3_PCF_GPIO_BASE 160
+#define BALLOON3_PCF_GPIO_LED0 (BALLOON3_PCF_GPIO_BASE + 0)
+#define BALLOON3_PCF_GPIO_LED1 (BALLOON3_PCF_GPIO_BASE + 1)
+#define BALLOON3_PCF_GPIO_LED2 (BALLOON3_PCF_GPIO_BASE + 2)
+#define BALLOON3_PCF_GPIO_LED3 (BALLOON3_PCF_GPIO_BASE + 3)
+#define BALLOON3_PCF_GPIO_LED4 (BALLOON3_PCF_GPIO_BASE + 4)
+#define BALLOON3_PCF_GPIO_LED5 (BALLOON3_PCF_GPIO_BASE + 5)
+#define BALLOON3_PCF_GPIO_LED6 (BALLOON3_PCF_GPIO_BASE + 6)
+#define BALLOON3_PCF_GPIO_LED7 (BALLOON3_PCF_GPIO_BASE + 7)
+
+/* FPGA Interrupt Mask/Acknowledge Register */
+#define BALLOON3_INT_S0_IRQ (1 << 0) /* PCMCIA 0 IRQ */
+#define BALLOON3_INT_S0_STSCHG (1 << 1) /* PCMCIA 0 status changed */
+
+/* CPLD (and FPGA) interface definitions */
+#define CPLD_LCD0_DATA_SET 0x00
+#define CPLD_LCD0_DATA_CLR 0x10
+#define CPLD_LCD0_COMMAND_SET 0x01
+#define CPLD_LCD0_COMMAND_CLR 0x11
+#define CPLD_LCD1_DATA_SET 0x02
+#define CPLD_LCD1_DATA_CLR 0x12
+#define CPLD_LCD1_COMMAND_SET 0x03
+#define CPLD_LCD1_COMMAND_CLR 0x13
+
+#define CPLD_MISC_SET 0x07
+#define CPLD_MISC_CLR 0x17
+#define CPLD_MISC_LOON_NRESET_BIT 0
+#define CPLD_MISC_LOON_UNSUSP_BIT 1
+#define CPLD_MISC_RUN_5V_BIT 2
+#define CPLD_MISC_CHG_D0_BIT 3
+#define CPLD_MISC_CHG_D1_BIT 4
+#define CPLD_MISC_DAC_NCS_BIT 5
+
+#define CPLD_LCD_SET 0x08
+#define CPLD_LCD_CLR 0x18
+#define CPLD_LCD_BACKLIGHT_EN_0_BIT 0
+#define CPLD_LCD_BACKLIGHT_EN_1_BIT 1
+#define CPLD_LCD_LED_RED_BIT 4
+#define CPLD_LCD_LED_GREEN_BIT 5
+#define CPLD_LCD_NRESET_BIT 7
+
+#define CPLD_LCD_RO_SET 0x09
+#define CPLD_LCD_RO_CLR 0x19
+#define CPLD_LCD_RO_LCD0_nWAIT_BIT 0
+#define CPLD_LCD_RO_LCD1_nWAIT_BIT 1
+
+#define CPLD_SERIAL_SET 0x0a
+#define CPLD_SERIAL_CLR 0x1a
+#define CPLD_SERIAL_GSM_RI_BIT 0
+#define CPLD_SERIAL_GSM_CTS_BIT 1
+#define CPLD_SERIAL_GSM_DTR_BIT 2
+#define CPLD_SERIAL_LPR_CTS_BIT 3
+#define CPLD_SERIAL_TC232_CTS_BIT 4
+#define CPLD_SERIAL_TC232_DSR_BIT 5
+
+#define CPLD_SROUTING_SET 0x0b
+#define CPLD_SROUTING_CLR 0x1b
+#define CPLD_SROUTING_MSP430_LPR 0
+#define CPLD_SROUTING_MSP430_TC232 1
+#define CPLD_SROUTING_MSP430_GSM 2
+#define CPLD_SROUTING_LOON_LPR (0 << 4)
+#define CPLD_SROUTING_LOON_TC232 (1 << 4)
+#define CPLD_SROUTING_LOON_GSM (2 << 4)
+
+#define CPLD_AROUTING_SET 0x0c
+#define CPLD_AROUTING_CLR 0x1c
+#define CPLD_AROUTING_MIC2PHONE_BIT 0
+#define CPLD_AROUTING_PHONE2INT_BIT 1
+#define CPLD_AROUTING_PHONE2EXT_BIT 2
+#define CPLD_AROUTING_LOONL2INT_BIT 3
+#define CPLD_AROUTING_LOONL2EXT_BIT 4
+#define CPLD_AROUTING_LOONR2PHONE_BIT 5
+#define CPLD_AROUTING_LOONR2INT_BIT 6
+#define CPLD_AROUTING_LOONR2EXT_BIT 7
+
+/* Balloon3 Interrupts */
+#define BALLOON3_IRQ(x) (IRQ_BOARD_START + (x))
+
+#define BALLOON3_AUX_NIRQ IRQ_GPIO(BALLOON3_GPIO_AUX_NIRQ)
+#define BALLOON3_CODEC_IRQ IRQ_GPIO(BALLOON3_GPIO_CODEC_IRQ)
+#define BALLOON3_S0_CD_IRQ IRQ_GPIO(BALLOON3_GPIO_S0_CD)
+
+#define BALLOON3_NR_IRQS (IRQ_BOARD_START + 16)
+
+extern int balloon3_has(enum balloon3_features feature);
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/bitfield.h b/arch/arm/mach-pxa/include/mach/bitfield.h
new file mode 100644
index 00000000..f1f0e338
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/bitfield.h
@@ -0,0 +1,113 @@
+/*
+ * FILE bitfield.h
+ *
+ * Version 1.1
+ * Author Copyright (c) Marc A. Viredaz, 1998
+ * DEC Western Research Laboratory, Palo Alto, CA
+ * Date April 1998 (April 1997)
+ * System Advanced RISC Machine (ARM)
+ * Language C or ARM Assembly
+ * Purpose Definition of macros to operate on bit fields.
+ */
+
+
+
+#ifndef __BITFIELD_H
+#define __BITFIELD_H
+
+#ifndef __ASSEMBLY__
+#define UData(Data) ((unsigned long) (Data))
+#else
+#define UData(Data) (Data)
+#endif
+
+
+/*
+ * MACRO: Fld
+ *
+ * Purpose
+ * The macro "Fld" encodes a bit field, given its size and its shift value
+ * with respect to bit 0.
+ *
+ * Note
+ * A more intuitive way to encode bit fields would have been to use their
+ * mask. However, extracting size and shift value information from a bit
+ * field's mask is cumbersome and might break the assembler (255-character
+ * line-size limit).
+ *
+ * Input
+ * Size Size of the bit field, in number of bits.
+ * Shft Shift value of the bit field with respect to bit 0.
+ *
+ * Output
+ * Fld Encoded bit field.
+ */
+
+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
+
+
+/*
+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
+ *
+ * Purpose
+ * The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
+ * the size, shift value, mask, aligned mask, and first bit of a
+ * bit field.
+ *
+ * Input
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FSize Size of the bit field, in number of bits.
+ * FShft Shift value of the bit field with respect to bit 0.
+ * FMsk Mask for the bit field.
+ * FAlnMsk Mask for the bit field, aligned on bit 0.
+ * F1stBit First bit of the bit field.
+ */
+
+#define FSize(Field) ((Field) >> 16)
+#define FShft(Field) ((Field) & 0x0000FFFF)
+#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field) (UData (1) << FShft (Field))
+
+
+/*
+ * MACRO: FInsrt
+ *
+ * Purpose
+ * The macro "FInsrt" inserts a value into a bit field by shifting the
+ * former appropriately.
+ *
+ * Input
+ * Value Bit-field value.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FInsrt Bit-field value positioned appropriately.
+ */
+
+#define FInsrt(Value, Field) \
+ (UData (Value) << FShft (Field))
+
+
+/*
+ * MACRO: FExtr
+ *
+ * Purpose
+ * The macro "FExtr" extracts the value of a bit field by masking and
+ * shifting it appropriately.
+ *
+ * Input
+ * Data Data containing the bit-field to be extracted.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FExtr Bit-field value.
+ */
+
+#define FExtr(Data, Field) \
+ ((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+
+#endif /* __BITFIELD_H */
diff --git a/arch/arm/mach-pxa/include/mach/camera.h b/arch/arm/mach-pxa/include/mach/camera.h
new file mode 100644
index 00000000..6709b1cd
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/camera.h
@@ -0,0 +1,44 @@
+/*
+ camera.h - PXA camera driver header file
+
+ Copyright (C) 2003, Intel Corporation
+ Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#define PXA_CAMERA_MASTER 1
+#define PXA_CAMERA_DATAWIDTH_4 2
+#define PXA_CAMERA_DATAWIDTH_5 4
+#define PXA_CAMERA_DATAWIDTH_8 8
+#define PXA_CAMERA_DATAWIDTH_9 0x10
+#define PXA_CAMERA_DATAWIDTH_10 0x20
+#define PXA_CAMERA_PCLK_EN 0x40
+#define PXA_CAMERA_MCLK_EN 0x80
+#define PXA_CAMERA_PCP 0x100
+#define PXA_CAMERA_HSP 0x200
+#define PXA_CAMERA_VSP 0x400
+
+struct pxacamera_platform_data {
+ unsigned long flags;
+ unsigned long mclk_10khz;
+};
+
+extern void pxa_set_camera_info(struct pxacamera_platform_data *);
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/clkdev.h b/arch/arm/mach-pxa/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/colibri.h b/arch/arm/mach-pxa/include/mach/colibri.h
new file mode 100644
index 00000000..cb4236e9
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/colibri.h
@@ -0,0 +1,69 @@
+#ifndef _COLIBRI_H_
+#define _COLIBRI_H_
+
+#include <net/ax88796.h>
+#include <mach/mfp.h>
+
+/*
+ * base board glue for PXA270 module
+ */
+
+enum {
+ COLIBRI_EVALBOARD = 0,
+ COLIBRI_PXA270_INCOME,
+};
+
+#if defined(CONFIG_MACH_COLIBRI_EVALBOARD)
+extern void colibri_evalboard_init(void);
+#else
+static inline void colibri_evalboard_init(void) {}
+#endif
+
+#if defined(CONFIG_MACH_COLIBRI_PXA270_INCOME)
+extern void colibri_pxa270_income_boardinit(void);
+#else
+static inline void colibri_pxa270_income_boardinit(void) {}
+#endif
+
+/*
+ * common settings for all modules
+ */
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin);
+#else
+static inline void colibri_pxa3xx_init_mmc(mfp_cfg_t *pins, int len, int detect_pin) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern void colibri_pxa3xx_init_lcd(int bl_pin);
+#else
+static inline void colibri_pxa3xx_init_lcd(int bl_pin) {}
+#endif
+
+#if defined(CONFIG_AX88796)
+extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data);
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+extern void colibri_pxa3xx_init_nand(void);
+#else
+static inline void colibri_pxa3xx_init_nand(void) {}
+#endif
+
+/* physical memory regions */
+#define COLIBRI_SDRAM_BASE 0xa0000000 /* SDRAM region */
+
+/* GPIO definitions for Colibri PXA270 */
+#define GPIO114_COLIBRI_PXA270_ETH_IRQ 114
+#define GPIO0_COLIBRI_PXA270_SD_DETECT 0
+#define GPIO113_COLIBRI_PXA270_TS_IRQ 113
+
+/* GPIO definitions for Colibri PXA300/310 */
+#define GPIO13_COLIBRI_PXA300_SD_DETECT 13
+
+/* GPIO definitions for Colibri PXA320 */
+#define GPIO28_COLIBRI_PXA320_SD_DETECT 28
+
+#endif /* _COLIBRI_H_ */
+
diff --git a/arch/arm/mach-pxa/include/mach/corgi.h b/arch/arm/mach-pxa/include/mach/corgi.h
new file mode 100644
index 00000000..0011055b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/corgi.h
@@ -0,0 +1,113 @@
+/*
+ * Hardware specific definitions for SL-C7xx series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can 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_CORGI_H
+#define __ASM_ARCH_CORGI_H 1
+
+
+/*
+ * Corgi (Non Standard) GPIO Definitions
+ */
+#define CORGI_GPIO_KEY_INT (0) /* Keyboard Interrupt */
+#define CORGI_GPIO_AC_IN (1) /* Charger Detection */
+#define CORGI_GPIO_WAKEUP (3) /* System wakeup notification? */
+#define CORGI_GPIO_AK_INT (4) /* Headphone Jack Control Interrupt */
+#define CORGI_GPIO_TP_INT (5) /* Touch Panel Interrupt */
+#define CORGI_GPIO_nSD_WP (7) /* SD Write Protect? */
+#define CORGI_GPIO_nSD_DETECT (9) /* MMC/SD Card Detect */
+#define CORGI_GPIO_nSD_INT (10) /* SD Interrupt for SDIO? */
+#define CORGI_GPIO_MAIN_BAT_LOW (11) /* Main Battery Low Notification */
+#define CORGI_GPIO_BAT_COVER (11) /* Battery Cover Detect */
+#define CORGI_GPIO_LED_ORANGE (13) /* Orange LED Control */
+#define CORGI_GPIO_CF_CD (14) /* Compact Flash Card Detect */
+#define CORGI_GPIO_CHRG_FULL (16) /* Charging Complete Notification */
+#define CORGI_GPIO_CF_IRQ (17) /* Compact Flash Interrupt */
+#define CORGI_GPIO_LCDCON_CS (19) /* LCD Control Chip Select */
+#define CORGI_GPIO_MAX1111_CS (20) /* MAX1111 Chip Select */
+#define CORGI_GPIO_ADC_TEMP_ON (21) /* Select battery voltage or temperature */
+#define CORGI_GPIO_IR_ON (22) /* Enable IR Transciever */
+#define CORGI_GPIO_ADS7846_CS (24) /* ADS7846 Chip Select */
+#define CORGI_GPIO_SD_PWR (33) /* MMC/SD Power */
+#define CORGI_GPIO_CHRG_ON (38) /* Enable battery Charging */
+#define CORGI_GPIO_DISCHARGE_ON (42) /* Enable battery Discharge */
+#define CORGI_GPIO_CHRG_UKN (43) /* Unknown Charging (Bypass Control?) */
+#define CORGI_GPIO_HSYNC (44) /* LCD HSync Pulse */
+#define CORGI_GPIO_USB_PULLUP (45) /* USB show presence to host */
+
+
+/*
+ * Corgi Keyboard Definitions
+ */
+#define CORGI_KEY_STROBE_NUM (12)
+#define CORGI_KEY_SENSE_NUM (8)
+#define CORGI_GPIO_ALL_STROBE_BIT (0x00003ffc)
+#define CORGI_GPIO_HIGH_SENSE_BIT (0xfc000000)
+#define CORGI_GPIO_HIGH_SENSE_RSHIFT (26)
+#define CORGI_GPIO_LOW_SENSE_BIT (0x00000003)
+#define CORGI_GPIO_LOW_SENSE_LSHIFT (6)
+#define CORGI_GPIO_STROBE_BIT(a) GPIO_bit(66+(a))
+#define CORGI_GPIO_SENSE_BIT(a) GPIO_bit(58+(a))
+#define CORGI_GAFR_ALL_STROBE_BIT (0x0ffffff0)
+#define CORGI_GAFR_HIGH_SENSE_BIT (0xfff00000)
+#define CORGI_GAFR_LOW_SENSE_BIT (0x0000000f)
+#define CORGI_GPIO_KEY_SENSE(a) (58+(a))
+#define CORGI_GPIO_KEY_STROBE(a) (66+(a))
+
+
+/*
+ * Corgi Interrupts
+ */
+#define CORGI_IRQ_GPIO_KEY_INT IRQ_GPIO(0)
+#define CORGI_IRQ_GPIO_AC_IN IRQ_GPIO(1)
+#define CORGI_IRQ_GPIO_WAKEUP IRQ_GPIO(3)
+#define CORGI_IRQ_GPIO_AK_INT IRQ_GPIO(4)
+#define CORGI_IRQ_GPIO_TP_INT IRQ_GPIO(5)
+#define CORGI_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9)
+#define CORGI_IRQ_GPIO_nSD_INT IRQ_GPIO(10)
+#define CORGI_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(11)
+#define CORGI_IRQ_GPIO_CF_CD IRQ_GPIO(14)
+#define CORGI_IRQ_GPIO_CHRG_FULL IRQ_GPIO(16) /* Battery fully charged */
+#define CORGI_IRQ_GPIO_CF_IRQ IRQ_GPIO(17)
+#define CORGI_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(58+(a)) /* Keyboard Sense lines */
+
+
+/*
+ * Corgi SCOOP GPIOs and Config
+ */
+#define CORGI_SCP_LED_GREEN SCOOP_GPCR_PA11
+#define CORGI_SCP_SWA SCOOP_GPCR_PA12 /* Hinge Switch A */
+#define CORGI_SCP_SWB SCOOP_GPCR_PA13 /* Hinge Switch B */
+#define CORGI_SCP_MUTE_L SCOOP_GPCR_PA14
+#define CORGI_SCP_MUTE_R SCOOP_GPCR_PA15
+#define CORGI_SCP_AKIN_PULLUP SCOOP_GPCR_PA16
+#define CORGI_SCP_APM_ON SCOOP_GPCR_PA17
+#define CORGI_SCP_BACKLIGHT_CONT SCOOP_GPCR_PA18
+#define CORGI_SCP_MIC_BIAS SCOOP_GPCR_PA19
+
+#define CORGI_SCOOP_IO_DIR ( CORGI_SCP_LED_GREEN | CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R | \
+ CORGI_SCP_AKIN_PULLUP | CORGI_SCP_APM_ON | CORGI_SCP_BACKLIGHT_CONT | \
+ CORGI_SCP_MIC_BIAS )
+#define CORGI_SCOOP_IO_OUT ( CORGI_SCP_MUTE_L | CORGI_SCP_MUTE_R )
+
+#define CORGI_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO)
+#define CORGI_GPIO_LED_GREEN (CORGI_SCOOP_GPIO_BASE + 0)
+#define CORGI_GPIO_SWA (CORGI_SCOOP_GPIO_BASE + 1) /* Hinge Switch A */
+#define CORGI_GPIO_SWB (CORGI_SCOOP_GPIO_BASE + 2) /* Hinge Switch B */
+#define CORGI_GPIO_MUTE_L (CORGI_SCOOP_GPIO_BASE + 3)
+#define CORGI_GPIO_MUTE_R (CORGI_SCOOP_GPIO_BASE + 4)
+#define CORGI_GPIO_AKIN_PULLUP (CORGI_SCOOP_GPIO_BASE + 5)
+#define CORGI_GPIO_APM_ON (CORGI_SCOOP_GPIO_BASE + 6)
+#define CORGI_GPIO_BACKLIGHT_CONT (CORGI_SCOOP_GPIO_BASE + 7)
+#define CORGI_GPIO_MIC_BIAS (CORGI_SCOOP_GPIO_BASE + 8)
+
+#endif /* __ASM_ARCH_CORGI_H */
+
diff --git a/arch/arm/mach-pxa/include/mach/csb726.h b/arch/arm/mach-pxa/include/mach/csb726.h
new file mode 100644
index 00000000..747ab1a7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/csb726.h
@@ -0,0 +1,26 @@
+/*
+ * Support for Cogent CSB726
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can 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 CSB726_H
+#define CSB726_H
+
+#define CSB726_GPIO_IRQ_LAN 52
+#define CSB726_GPIO_IRQ_SM501 53
+#define CSB726_GPIO_MMC_DETECT 100
+#define CSB726_GPIO_MMC_RO 101
+
+#define CSB726_FLASH_SIZE (64 * 1024 * 1024)
+#define CSB726_FLASH_uMON (8 * 1024 * 1024)
+
+#define CSB726_IRQ_LAN gpio_to_irq(CSB726_GPIO_IRQ_LAN)
+#define CSB726_IRQ_SM501 gpio_to_irq(CSB726_GPIO_IRQ_SM501)
+
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/debug-macro.S b/arch/arm/mach-pxa/include/mach/debug-macro.S
new file mode 100644
index 00000000..7d5c7512
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/debug-macro.S
@@ -0,0 +1,23 @@
+/* arch/arm/mach-pxa/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include "hardware.h"
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00100000
+ orr \rv, \rp, #io_p2v(0x40000000) @ virtual
+ orr \rp, \rp, #0x40000000 @ physical
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-pxa/include/mach/dma.h b/arch/arm/mach-pxa/include/mach/dma.h
new file mode 100644
index 00000000..5bd55894
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/dma.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-pxa/include/mach/dma.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <mach/hardware.h>
+
+/* DMA Controller Registers Definitions */
+#define DMAC_REGS_VIRT io_p2v(0x40000000)
+
+#include <plat/dma.h>
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S b/arch/arm/mach-pxa/include/mach/entry-macro.S
new file mode 100644
index 00000000..a73bc86a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-pxa/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for PXA-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mrc p15, 0, \tmp, c0, c0, 0 @ CPUID
+ mov \tmp, \tmp, lsr #13
+ and \tmp, \tmp, #0x7 @ Core G
+ cmp \tmp, #1
+ bhi 1002f
+
+ @ Core Generation 1 (PXA25x)
+ mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000
+ add \base, \base, #0x00d00000
+ ldr \irqstat, [\base, #0] @ ICIP
+ ldr \irqnr, [\base, #4] @ ICMR
+
+ ands \irqnr, \irqstat, \irqnr
+ beq 1001f
+ rsb \irqstat, \irqnr, #0
+ and \irqstat, \irqstat, \irqnr
+ clz \irqnr, \irqstat
+ rsb \irqnr, \irqnr, #(31 + PXA_IRQ(0))
+ b 1001f
+1002:
+ @ Core Generation 2 (PXA27x) or Core Generation 3 (PXA3xx)
+ mrc p6, 0, \irqstat, c5, c0, 0 @ ICHP
+ tst \irqstat, #0x80000000
+ beq 1001f
+ bic \irqstat, \irqstat, #0x80000000
+ mov \irqnr, \irqstat, lsr #16
+ add \irqnr, \irqnr, #(PXA_IRQ(0))
+1001:
+ .endm
diff --git a/arch/arm/mach-pxa/include/mach/eseries-gpio.h b/arch/arm/mach-pxa/include/mach/eseries-gpio.h
new file mode 100644
index 00000000..f3e55098
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/eseries-gpio.h
@@ -0,0 +1,67 @@
+/*
+ * eseries-gpio.h
+ *
+ * Copyright (C) Ian Molton <spyro@f2s.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.
+ *
+ */
+
+/* e-series power button */
+#define GPIO_ESERIES_POWERBTN 0
+
+/* UDC GPIO definitions */
+#define GPIO_E7XX_USB_DISC 13
+#define GPIO_E7XX_USB_PULLUP 3
+
+#define GPIO_E800_USB_DISC 4
+#define GPIO_E800_USB_PULLUP 84
+
+/* e740 PCMCIA GPIO definitions */
+/* Note: PWR1 seems to be inverted */
+#define GPIO_E740_PCMCIA_CD0 8
+#define GPIO_E740_PCMCIA_CD1 44
+#define GPIO_E740_PCMCIA_RDY0 11
+#define GPIO_E740_PCMCIA_RDY1 6
+#define GPIO_E740_PCMCIA_RST0 27
+#define GPIO_E740_PCMCIA_RST1 24
+#define GPIO_E740_PCMCIA_PWR0 20
+#define GPIO_E740_PCMCIA_PWR1 23
+
+/* e750 PCMCIA GPIO definitions */
+#define GPIO_E750_PCMCIA_CD0 8
+#define GPIO_E750_PCMCIA_RDY0 12
+#define GPIO_E750_PCMCIA_RST0 27
+#define GPIO_E750_PCMCIA_PWR0 20
+
+/* e800 PCMCIA GPIO definitions */
+#define GPIO_E800_PCMCIA_RST0 69
+#define GPIO_E800_PCMCIA_RST1 72
+#define GPIO_E800_PCMCIA_PWR0 20
+#define GPIO_E800_PCMCIA_PWR1 73
+
+/* e7xx IrDA power control */
+#define GPIO_E7XX_IR_OFF 38
+
+/* e740 audio control GPIOs */
+#define GPIO_E740_WM9705_nAVDD2 16
+#define GPIO_E740_MIC_ON 40
+#define GPIO_E740_AMP_ON 41
+
+/* e750 audio control GPIOs */
+#define GPIO_E750_HP_AMP_OFF 4
+#define GPIO_E750_SPK_AMP_OFF 7
+#define GPIO_E750_HP_DETECT 37
+
+/* e800 audio control GPIOs */
+#define GPIO_E800_HP_DETECT 81
+#define GPIO_E800_HP_AMP_OFF 82
+#define GPIO_E800_SPK_AMP_ON 83
+
+/* ASIC related GPIOs */
+#define GPIO_ESERIES_TMIO_IRQ 5
+#define GPIO_ESERIES_TMIO_PCLR 19
+#define GPIO_ESERIES_TMIO_SUSPEND 45
+#define GPIO_E800_ANGELX_IRQ 8
diff --git a/arch/arm/mach-pxa/include/mach/eseries-irq.h b/arch/arm/mach-pxa/include/mach/eseries-irq.h
new file mode 100644
index 00000000..de292b26
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/eseries-irq.h
@@ -0,0 +1,28 @@
+/*
+ * eseries-irq.h
+ *
+ * Copyright (C) Ian Molton <spyro@f2s.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.
+ *
+ */
+
+#define ANGELX_IRQ_BASE (IRQ_BOARD_START+8)
+#define IRQ_ANGELX(n) (ANGELX_IRQ_BASE + (n))
+
+#define ANGELX_RDY0_IRQ IRQ_ANGELX(0)
+#define ANGELX_ST0_IRQ IRQ_ANGELX(1)
+#define ANGELX_CD0_IRQ IRQ_ANGELX(2)
+#define ANGELX_RDY1_IRQ IRQ_ANGELX(3)
+#define ANGELX_ST1_IRQ IRQ_ANGELX(4)
+#define ANGELX_CD1_IRQ IRQ_ANGELX(5)
+
+#define TMIO_IRQ_BASE (IRQ_BOARD_START+0)
+#define IRQ_TMIO(n) (TMIO_IRQ_BASE + (n))
+
+#define TMIO_SD_IRQ IRQ_TMIO(1)
+#define TMIO_USB_IRQ IRQ_TMIO(2)
+
+#define ESERIES_NR_IRQS (IRQ_BOARD_START + 16)
diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h
new file mode 100644
index 00000000..c4639502
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/gpio.h
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/mach-pxa/include/mach/gpio.h
+ *
+ * PXA GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.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 __ASM_ARCH_PXA_GPIO_H
+#define __ASM_ARCH_PXA_GPIO_H
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define GPIO_REGS_VIRT io_p2v(0x40E00000)
+
+#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
+
+/* GPIO Pin Level Registers */
+#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00)
+#define GPLR1 GPIO_REG(BANK_OFF(1) + 0x00)
+#define GPLR2 GPIO_REG(BANK_OFF(2) + 0x00)
+#define GPLR3 GPIO_REG(BANK_OFF(3) + 0x00)
+
+/* GPIO Pin Direction Registers */
+#define GPDR0 GPIO_REG(BANK_OFF(0) + 0x0c)
+#define GPDR1 GPIO_REG(BANK_OFF(1) + 0x0c)
+#define GPDR2 GPIO_REG(BANK_OFF(2) + 0x0c)
+#define GPDR3 GPIO_REG(BANK_OFF(3) + 0x0c)
+
+/* GPIO Pin Output Set Registers */
+#define GPSR0 GPIO_REG(BANK_OFF(0) + 0x18)
+#define GPSR1 GPIO_REG(BANK_OFF(1) + 0x18)
+#define GPSR2 GPIO_REG(BANK_OFF(2) + 0x18)
+#define GPSR3 GPIO_REG(BANK_OFF(3) + 0x18)
+
+/* GPIO Pin Output Clear Registers */
+#define GPCR0 GPIO_REG(BANK_OFF(0) + 0x24)
+#define GPCR1 GPIO_REG(BANK_OFF(1) + 0x24)
+#define GPCR2 GPIO_REG(BANK_OFF(2) + 0x24)
+#define GPCR3 GPIO_REG(BANK_OFF(3) + 0x24)
+
+/* GPIO Rising Edge Detect Registers */
+#define GRER0 GPIO_REG(BANK_OFF(0) + 0x30)
+#define GRER1 GPIO_REG(BANK_OFF(1) + 0x30)
+#define GRER2 GPIO_REG(BANK_OFF(2) + 0x30)
+#define GRER3 GPIO_REG(BANK_OFF(3) + 0x30)
+
+/* GPIO Falling Edge Detect Registers */
+#define GFER0 GPIO_REG(BANK_OFF(0) + 0x3c)
+#define GFER1 GPIO_REG(BANK_OFF(1) + 0x3c)
+#define GFER2 GPIO_REG(BANK_OFF(2) + 0x3c)
+#define GFER3 GPIO_REG(BANK_OFF(3) + 0x3c)
+
+/* GPIO Edge Detect Status Registers */
+#define GEDR0 GPIO_REG(BANK_OFF(0) + 0x48)
+#define GEDR1 GPIO_REG(BANK_OFF(1) + 0x48)
+#define GEDR2 GPIO_REG(BANK_OFF(2) + 0x48)
+#define GEDR3 GPIO_REG(BANK_OFF(3) + 0x48)
+
+/* GPIO Alternate Function Select Registers */
+#define GAFR0_L GPIO_REG(0x0054)
+#define GAFR0_U GPIO_REG(0x0058)
+#define GAFR1_L GPIO_REG(0x005C)
+#define GAFR1_U GPIO_REG(0x0060)
+#define GAFR2_L GPIO_REG(0x0064)
+#define GAFR2_U GPIO_REG(0x0068)
+#define GAFR3_L GPIO_REG(0x006C)
+#define GAFR3_U GPIO_REG(0x0070)
+
+/* More handy macros. The argument is a literal GPIO number. */
+
+#define GPIO_bit(x) (1 << ((x) & 0x1f))
+
+#define GPLR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x00)
+#define GPDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x0c)
+#define GPSR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x18)
+#define GPCR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x24)
+#define GRER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x30)
+#define GFER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x3c)
+#define GEDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x48)
+#define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2))
+
+
+#define NR_BUILTIN_GPIO PXA_GPIO_IRQ_NUM
+
+#define gpio_to_bank(gpio) ((gpio) >> 5)
+#define gpio_to_irq(gpio) IRQ_GPIO(gpio)
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ int gpio;
+
+ if (irq == IRQ_GPIO0 || irq == IRQ_GPIO1)
+ return irq - IRQ_GPIO0;
+
+ gpio = irq - PXA_GPIO_IRQ_BASE;
+ if (gpio >= 2 && gpio < NR_BUILTIN_GPIO)
+ return gpio;
+
+ return -1;
+}
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
+ * as well as their Alternate Function value being '1' for GPIO in GAFRx.
+ */
+static inline int __gpio_is_inverted(unsigned gpio)
+{
+ return cpu_is_pxa25x() && gpio > 85;
+}
+#else
+static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
+#endif
+
+/*
+ * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
+ * function of a GPIO, and GPDRx cannot be altered once configured. It
+ * is attributed as "occupied" here (I know this terminology isn't
+ * accurate, you are welcome to propose a better one :-)
+ */
+static inline int __gpio_is_occupied(unsigned gpio)
+{
+ if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
+ int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
+ int dir = GPDR(gpio) & GPIO_bit(gpio);
+
+ if (__gpio_is_inverted(gpio))
+ return af != 1 || dir == 0;
+ else
+ return af != 0 || dir != 0;
+ } else
+ return GPDR(gpio) & GPIO_bit(gpio);
+}
+
+#include <plat/gpio.h>
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/gumstix.h b/arch/arm/mach-pxa/include/mach/gumstix.h
new file mode 100644
index 00000000..9b898680
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/gumstix.h
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mach-pxa/include/mach/gumstix.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+/* BTRESET - Reset line to Bluetooth module, active low signal. */
+#define GPIO_GUMSTIX_BTRESET 7
+#define GPIO_GUMSTIX_BTRESET_MD (GPIO_GUMSTIX_BTRESET | GPIO_OUT)
+
+
+/*
+GPIOn - Input from MAX823 (or equiv), normalizing USB +5V into a clean
+interrupt signal for determining cable presence. On the gumstix F,
+this moves to GPIO17 and GPIO37. */
+
+/* GPIOx - Connects to USB D+ and used as a pull-up after GPIOn
+has detected a cable insertion; driven low otherwise. */
+
+#define GPIO_GUMSTIX_USB_GPIOn 35
+#define GPIO_GUMSTIX_USB_GPIOx 41
+
+/* usb state change */
+#define GUMSTIX_USB_INTR_IRQ IRQ_GPIO(GPIO_GUMSTIX_USB_GPIOn)
+
+#define GPIO_GUMSTIX_USB_GPIOn_MD (GPIO_GUMSTIX_USB_GPIOn | GPIO_IN)
+#define GPIO_GUMSTIX_USB_GPIOx_CON_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_OUT)
+#define GPIO_GUMSTIX_USB_GPIOx_DIS_MD (GPIO_GUMSTIX_USB_GPIOx | GPIO_IN)
+
+/*
+ * SD/MMC definitions
+ */
+#define GUMSTIX_GPIO_nSD_WP 22 /* SD Write Protect */
+#define GUMSTIX_GPIO_nSD_DETECT 11 /* MMC/SD Card Detect */
+#define GUMSTIX_IRQ_GPIO_nSD_DETECT IRQ_GPIO(GUMSTIX_GPIO_nSD_DETECT)
+
+/*
+ * SMC Ethernet definitions
+ * ETH_RST provides a hardware reset line to the ethernet chip
+ * ETH is the IRQ line in from the ethernet chip to the PXA
+ */
+#define GPIO_GUMSTIX_ETH0_RST 80
+#define GPIO_GUMSTIX_ETH0_RST_MD (GPIO_GUMSTIX_ETH0_RST | GPIO_OUT)
+#define GPIO_GUMSTIX_ETH1_RST 52
+#define GPIO_GUMSTIX_ETH1_RST_MD (GPIO_GUMSTIX_ETH1_RST | GPIO_OUT)
+
+#define GPIO_GUMSTIX_ETH0 36
+#define GPIO_GUMSTIX_ETH0_MD (GPIO_GUMSTIX_ETH0 | GPIO_IN)
+#define GUMSTIX_ETH0_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH0)
+#define GPIO_GUMSTIX_ETH1 27
+#define GPIO_GUMSTIX_ETH1_MD (GPIO_GUMSTIX_ETH1 | GPIO_IN)
+#define GUMSTIX_ETH1_IRQ IRQ_GPIO(GPIO_GUMSTIX_ETH1)
+
+
+/* CF reset line */
+#define GPIO8_RESET 8
+
+/* CF slot 0 */
+#define GPIO4_nBVD1 4
+#define GPIO4_nSTSCHG GPIO4_nBVD1
+#define GPIO11_nCD 11
+#define GPIO26_PRDY_nBSY 26
+#define GUMSTIX_S0_nSTSCHG_IRQ IRQ_GPIO(GPIO4_nSTSCHG)
+#define GUMSTIX_S0_nCD_IRQ IRQ_GPIO(GPIO11_nCD)
+#define GUMSTIX_S0_PRDY_nBSY_IRQ IRQ_GPIO(GPIO26_PRDY_nBSY)
+
+/* CF slot 1 */
+#define GPIO18_nBVD1 18
+#define GPIO18_nSTSCHG GPIO18_nBVD1
+#define GPIO36_nCD 36
+#define GPIO27_PRDY_nBSY 27
+#define GUMSTIX_S1_nSTSCHG_IRQ IRQ_GPIO(GPIO18_nSTSCHG)
+#define GUMSTIX_S1_nCD_IRQ IRQ_GPIO(GPIO36_nCD)
+#define GUMSTIX_S1_PRDY_nBSY_IRQ IRQ_GPIO(GPIO27_PRDY_nBSY)
+
+/* CF GPIO line modes */
+#define GPIO4_nSTSCHG_MD (GPIO4_nSTSCHG | GPIO_IN)
+#define GPIO8_RESET_MD (GPIO8_RESET | GPIO_OUT)
+#define GPIO11_nCD_MD (GPIO11_nCD | GPIO_IN)
+#define GPIO18_nSTSCHG_MD (GPIO18_nSTSCHG | GPIO_IN)
+#define GPIO26_PRDY_nBSY_MD (GPIO26_PRDY_nBSY | GPIO_IN)
+#define GPIO27_PRDY_nBSY_MD (GPIO27_PRDY_nBSY | GPIO_IN)
+#define GPIO36_nCD_MD (GPIO36_nCD | GPIO_IN)
+
+/* for expansion boards that can't be programatically detected */
+extern int am200_init(void);
+extern int am300_init(void);
+
diff --git a/arch/arm/mach-pxa/include/mach/h5000.h b/arch/arm/mach-pxa/include/mach/h5000.h
new file mode 100644
index 00000000..2a5ae380
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/h5000.h
@@ -0,0 +1,113 @@
+/*
+ * Hardware definitions for HP iPAQ h5xxx Handheld Computers
+ *
+ * Copyright(20)02 Hewlett-Packard Company.
+ *
+ * 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.
+ *
+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * Author: Jamey Hicks
+ */
+
+#ifndef __ASM_ARCH_H5000_H
+#define __ASM_ARCH_H5000_H
+
+#include <mach/mfp-pxa25x.h>
+
+/*
+ * CPU GPIOs
+ */
+
+#define H5000_GPIO_POWER_BUTTON (0)
+#define H5000_GPIO_RESET_BUTTON_N (1)
+#define H5000_GPIO_OPT_INT (2)
+#define H5000_GPIO_BACKUP_POWER (3)
+#define H5000_GPIO_ACTION_BUTTON (4)
+#define H5000_GPIO_COM_DCD_SOMETHING (5) /* what is this really ? */
+/* 6 not connected */
+#define H5000_GPIO_RESET_BUTTON_AGAIN_N (7) /* connected to gpio 1 as well */
+/* 8 not connected */
+#define H5000_GPIO_RSO_N (9) /* reset output from max1702 which regulates 3.3 and 2.5 */
+#define H5000_GPIO_ASIC_INT_N (10) /* from companion asic */
+#define H5000_GPIO_BT_ENV_0 (11) /* to LMX9814, set to 1 according to regdump */
+/*(12) not connected */
+#define H5000_GPIO_BT_ENV_1 (13) /* to LMX9814, set to 1 according to regdump */
+#define H5000_GPIO_BT_WU (14) /* from LMX9814, Defined as HOST_WAKEUP in the LMX9820 data sheet */
+/*(15) is CS1# */
+/*(16) not connected */
+/*(17) not connected */
+/*(18) is pcmcia ready */
+/*(19) is dreq1 */
+/*(20) is dreq0 */
+#define H5000_GPIO_OE_RD_NWR (21) /* output enable on rd/nwr signal to companion asic */
+/*(22) is not connected */
+#define H5000_GPIO_OPT_SPI_CLK (23) /* to extension pack */
+#define H5000_GPIO_OPT_SPI_CS_N (24) /* to extension pack */
+#define H5000_GPIO_OPT_SPI_DOUT (25) /* to extension pack */
+#define H5000_GPIO_OPT_SPI_DIN (26) /* to extension pack */
+/*(27) not connected */
+#define H5000_GPIO_I2S_BITCLK (28) /* connected to AC97 codec */
+#define H5000_GPIO_I2S_DATAOUT (29) /* connected to AC97 codec */
+#define H5000_GPIO_I2S_DATAIN (30) /* connected to AC97 codec */
+#define H5000_GPIO_I2S_LRCLK (31) /* connected to AC97 codec */
+#define H5000_GPIO_I2S_SYSCLK (32) /* connected to AC97 codec */
+/*(33) is CS5# */
+#define H5000_GPIO_COM_RXD (34) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_CTS (35) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DCD (36) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DSR (37) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_RI (38) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_TXD (39) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_DTR (40) /* connected to cradle/cable connector */
+#define H5000_GPIO_COM_RTS (41) /* connected to cradle/cable connector */
+
+#define H5000_GPIO_BT_RXD (42) /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_TXD (43) /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_CTS (44) /* connected to BT (LMX9814) */
+#define H5000_GPIO_BT_RTS (45) /* connected to BT (LMX9814) */
+
+#define H5000_GPIO_IRDA_RXD (46)
+#define H5000_GPIO_IRDA_TXD (47)
+
+#define H5000_GPIO_POE_N (48) /* used for pcmcia */
+#define H5000_GPIO_PWE_N (49) /* used for pcmcia */
+#define H5000_GPIO_PIOR_N (50) /* used for pcmcia */
+#define H5000_GPIO_PIOW_N (51) /* used for pcmcia */
+#define H5000_GPIO_PCE1_N (52) /* used for pcmcia */
+#define H5000_GPIO_PCE2_N (53) /* used for pcmcia */
+#define H5000_GPIO_PSKTSEL (54) /* used for pcmcia */
+#define H5000_GPIO_PREG_N (55) /* used for pcmcia */
+#define H5000_GPIO_PWAIT_N (56) /* used for pcmcia */
+#define H5000_GPIO_IOIS16_N (57) /* used for pcmcia */
+
+#define H5000_GPIO_IRDA_SD (58) /* to hsdl3002 sd */
+/*(59) not connected */
+#define H5000_GPIO_POWER_SD_N (60) /* controls power to SD */
+#define H5000_GPIO_POWER_RS232_N (61) /* inverted FORCEON to rs232 transceiver */
+#define H5000_GPIO_POWER_ACCEL_N (62) /* controls power to accel */
+/*(63) is not connected */
+#define H5000_GPIO_OPT_NVRAM (64) /* controls power to expansion pack */
+#define H5000_GPIO_CHG_EN (65) /* to sc801 en */
+#define H5000_GPIO_USB_PULLUP (66) /* USB d+ pullup via 1.5K resistor */
+#define H5000_GPIO_BT_2V8_N (67) /* 2.8V used by bluetooth */
+#define H5000_GPIO_EXT_CHG_RATE (68) /* enables external charging rate */
+/*(69) is not connected */
+#define H5000_GPIO_CIR_RESET (70) /* consumer IR reset */
+#define H5000_GPIO_POWER_LIGHT_SENSOR_N (71)
+#define H5000_GPIO_BT_M_RESET (72)
+#define H5000_GPIO_STD_CHG_RATE (73)
+#define H5000_GPIO_SD_WP_N (74)
+#define H5000_GPIO_MOTOR_ON_N (75) /* external pullup on this */
+#define H5000_GPIO_HEADPHONE_DETECT (76)
+#define H5000_GPIO_USB_CHG_RATE (77) /* select rate for charging via usb */
+/*(78) is CS2# */
+/*(79) is CS3# */
+/*(80) is CS4# */
+
+#endif /* __ASM_ARCH_H5000_H */
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
new file mode 100644
index 00000000..6957ba56
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -0,0 +1,346 @@
+/*
+ * arch/arm/mach-pxa/include/mach/hardware.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/addr-map.h>
+
+/*
+ * Workarounds for at least 2 errata so far require this.
+ * The mapping is set in mach-pxa/generic.c.
+ */
+#define UNCACHED_PHYS_0 0xff000000
+#define UNCACHED_ADDR UNCACHED_PHYS_0
+
+/*
+ * Intel PXA2xx internal register mapping:
+ *
+ * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff
+ * 0x44000000 - 0x45ffffff <--> 0xf4000000 - 0xf5ffffff
+ * 0x48000000 - 0x49ffffff <--> 0xf6000000 - 0xf7ffffff
+ * 0x4c000000 - 0x4dffffff <--> 0xf8000000 - 0xf9ffffff
+ * 0x50000000 - 0x51ffffff <--> 0xfa000000 - 0xfbffffff
+ * 0x54000000 - 0x55ffffff <--> 0xfc000000 - 0xfdffffff
+ * 0x58000000 - 0x59ffffff <--> 0xfe000000 - 0xffffffff
+ *
+ * Note that not all PXA2xx chips implement all those addresses, and the
+ * kernel only maps the minimum needed range of this mapping.
+ */
+#define io_p2v(x) (0xf2000000 + ((x) & 0x01ffffff) + (((x) & 0x1c000000) >> 1))
+#define io_v2p(x) (0x3c000000 + ((x) & 0x01ffffff) + (((x) & 0x0e000000) << 1))
+
+#ifndef __ASSEMBLY__
+
+# define __REG(x) (*((volatile u32 *)io_p2v(x)))
+
+/* With indexed regs we don't want to feed the index through io_p2v()
+ especially if it is a variable, otherwise horrible code will result. */
+# define __REG2(x,y) \
+ (*(volatile u32 *)((u32)&__REG(x) + (y)))
+
+# define __PREG(x) (io_v2p((u32)&(x)))
+
+#else
+
+# define __REG(x) io_p2v(x)
+# define __PREG(x) io_v2p(x)
+
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <asm/cputype.h>
+
+/*
+ * CPU Stepping CPU_ID JTAG_ID
+ *
+ * PXA210 B0 0x69052922 0x2926C013
+ * PXA210 B1 0x69052923 0x3926C013
+ * PXA210 B2 0x69052924 0x4926C013
+ * PXA210 C0 0x69052D25 0x5926C013
+ *
+ * PXA250 A0 0x69052100 0x09264013
+ * PXA250 A1 0x69052101 0x19264013
+ * PXA250 B0 0x69052902 0x29264013
+ * PXA250 B1 0x69052903 0x39264013
+ * PXA250 B2 0x69052904 0x49264013
+ * PXA250 C0 0x69052D05 0x59264013
+ *
+ * PXA255 A0 0x69052D06 0x69264013
+ *
+ * PXA26x A0 0x69052903 0x39264013
+ * PXA26x B0 0x69052D05 0x59264013
+ *
+ * PXA27x A0 0x69054110 0x09265013
+ * PXA27x A1 0x69054111 0x19265013
+ * PXA27x B0 0x69054112 0x29265013
+ * PXA27x B1 0x69054113 0x39265013
+ * PXA27x C0 0x69054114 0x49265013
+ * PXA27x C5 0x69054117 0x79265013
+ *
+ * PXA30x A0 0x69056880 0x0E648013
+ * PXA30x A1 0x69056881 0x1E648013
+ * PXA31x A0 0x69056890 0x0E649013
+ * PXA31x A1 0x69056891 0x1E649013
+ * PXA31x A2 0x69056892 0x2E649013
+ * PXA32x B1 0x69056825 0x5E642013
+ * PXA32x B2 0x69056826 0x6E642013
+ *
+ * PXA930 B0 0x69056835 0x5E643013
+ * PXA930 B1 0x69056837 0x7E643013
+ * PXA930 B2 0x69056838 0x8E643013
+ *
+ * PXA935 A0 0x56056931 0x1E653013
+ * PXA935 B0 0x56056936 0x6E653013
+ * PXA935 B1 0x56056938 0x8E653013
+ */
+#ifdef CONFIG_PXA25x
+#define __cpu_is_pxa210(id) \
+ ({ \
+ unsigned int _id = (id) & 0xf3f0; \
+ _id == 0x2120; \
+ })
+
+#define __cpu_is_pxa250(id) \
+ ({ \
+ unsigned int _id = (id) & 0xf3ff; \
+ _id <= 0x2105; \
+ })
+
+#define __cpu_is_pxa255(id) \
+ ({ \
+ unsigned int _id = (id) & 0xffff; \
+ _id == 0x2d06; \
+ })
+
+#define __cpu_is_pxa25x(id) \
+ ({ \
+ unsigned int _id = (id) & 0xf300; \
+ _id == 0x2100; \
+ })
+#else
+#define __cpu_is_pxa210(id) (0)
+#define __cpu_is_pxa250(id) (0)
+#define __cpu_is_pxa255(id) (0)
+#define __cpu_is_pxa25x(id) (0)
+#endif
+
+#ifdef CONFIG_PXA27x
+#define __cpu_is_pxa27x(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x411; \
+ })
+#else
+#define __cpu_is_pxa27x(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA300
+#define __cpu_is_pxa300(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x688; \
+ })
+#else
+#define __cpu_is_pxa300(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA310
+#define __cpu_is_pxa310(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x689; \
+ })
+#else
+#define __cpu_is_pxa310(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA320
+#define __cpu_is_pxa320(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x603 || _id == 0x682; \
+ })
+#else
+#define __cpu_is_pxa320(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA930
+#define __cpu_is_pxa930(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x683; \
+ })
+#else
+#define __cpu_is_pxa930(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA935
+#define __cpu_is_pxa935(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x693; \
+ })
+#else
+#define __cpu_is_pxa935(id) (0)
+#endif
+
+#ifdef CONFIG_CPU_PXA955
+#define __cpu_is_pxa955(id) \
+ ({ \
+ unsigned int _id = (id) >> 4 & 0xfff; \
+ _id == 0x581 || _id == 0xc08 \
+ || _id == 0xb76; \
+ })
+#else
+#define __cpu_is_pxa955(id) (0)
+#endif
+
+#define cpu_is_pxa210() \
+ ({ \
+ __cpu_is_pxa210(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa250() \
+ ({ \
+ __cpu_is_pxa250(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa255() \
+ ({ \
+ __cpu_is_pxa255(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa25x() \
+ ({ \
+ __cpu_is_pxa25x(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa27x() \
+ ({ \
+ __cpu_is_pxa27x(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa300() \
+ ({ \
+ __cpu_is_pxa300(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa310() \
+ ({ \
+ __cpu_is_pxa310(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa320() \
+ ({ \
+ __cpu_is_pxa320(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa930() \
+ ({ \
+ __cpu_is_pxa930(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa935() \
+ ({ \
+ __cpu_is_pxa935(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa955() \
+ ({ \
+ __cpu_is_pxa955(read_cpuid_id()); \
+ })
+
+
+/*
+ * CPUID Core Generation Bit
+ * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x
+ */
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
+#define __cpu_is_pxa2xx(id) \
+ ({ \
+ unsigned int _id = (id) >> 13 & 0x7; \
+ _id <= 0x2; \
+ })
+#else
+#define __cpu_is_pxa2xx(id) (0)
+#endif
+
+#ifdef CONFIG_PXA3xx
+#define __cpu_is_pxa3xx(id) \
+ ({ \
+ __cpu_is_pxa300(id) \
+ || __cpu_is_pxa310(id) \
+ || __cpu_is_pxa320(id) \
+ || __cpu_is_pxa93x(id); \
+ })
+#else
+#define __cpu_is_pxa3xx(id) (0)
+#endif
+
+#if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935)
+#define __cpu_is_pxa93x(id) \
+ ({ \
+ __cpu_is_pxa930(id) \
+ || __cpu_is_pxa935(id); \
+ })
+#else
+#define __cpu_is_pxa93x(id) (0)
+#endif
+
+#ifdef CONFIG_PXA95x
+#define __cpu_is_pxa95x(id) \
+ ({ \
+ __cpu_is_pxa955(id); \
+ })
+#else
+#define __cpu_is_pxa95x(id) (0)
+#endif
+
+#define cpu_is_pxa2xx() \
+ ({ \
+ __cpu_is_pxa2xx(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa3xx() \
+ ({ \
+ __cpu_is_pxa3xx(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa93x() \
+ ({ \
+ __cpu_is_pxa93x(read_cpuid_id()); \
+ })
+
+#define cpu_is_pxa95x() \
+ ({ \
+ __cpu_is_pxa95x(read_cpuid_id()); \
+ })
+
+/*
+ * return current memory and LCD clock frequency in units of 10kHz
+ */
+extern unsigned int get_memclk_frequency_10khz(void);
+
+/* return the clock tick rate of the OS timer */
+extern unsigned long get_clock_tick_rate(void);
+#endif
+
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define PCIBIOS_MIN_IO 0
+#define PCIBIOS_MIN_MEM 0
+#define pcibios_assign_all_busses() 1
+#define ARCH_HAS_DMA_SET_COHERENT_MASK
+#endif
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h
new file mode 100644
index 00000000..37408449
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/hx4700.h
@@ -0,0 +1,132 @@
+/*
+ * GPIO and IRQ definitions for HP iPAQ hx4700
+ *
+ * Copyright (c) 2008 Philipp Zabel
+ *
+ * This program is free software; you can 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 _HX4700_H_
+#define _HX4700_H_
+
+#include <linux/gpio.h>
+#include <linux/mfd/asic3.h>
+
+#define HX4700_ASIC3_GPIO_BASE NR_BUILTIN_GPIO
+#define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS)
+#define HX4700_NR_IRQS (IRQ_BOARD_START + 70)
+
+/*
+ * PXA GPIOs
+ */
+
+#define GPIO0_HX4700_nKEY_POWER 0
+#define GPIO12_HX4700_ASIC3_IRQ 12
+#define GPIO13_HX4700_W3220_IRQ 13
+#define GPIO14_HX4700_nWLAN_IRQ 14
+#define GPIO18_HX4700_RDY 18
+#define GPIO22_HX4700_LCD_RL 22
+#define GPIO27_HX4700_CODEC_ON 27
+#define GPIO32_HX4700_RS232_ON 32
+#define GPIO52_HX4700_CPU_nBATT_FAULT 52
+#define GPIO58_HX4700_TSC2046_nPENIRQ 58
+#define GPIO59_HX4700_LCD_PC1 59
+#define GPIO60_HX4700_CF_RNB 60
+#define GPIO61_HX4700_W3220_nRESET 61
+#define GPIO62_HX4700_LCD_nRESET 62
+#define GPIO63_HX4700_CPU_SS_nRESET 63
+#define GPIO65_HX4700_TSC2046_PEN_PU 65
+#define GPIO66_HX4700_ASIC3_nSDIO_IRQ 66
+#define GPIO67_HX4700_EUART_PS 67
+#define GPIO70_HX4700_LCD_SLIN1 70
+#define GPIO71_HX4700_ASIC3_nRESET 71
+#define GPIO72_HX4700_BQ24022_nCHARGE_EN 72
+#define GPIO73_HX4700_LCD_UD_1 73
+#define GPIO75_HX4700_EARPHONE_nDET 75
+#define GPIO76_HX4700_USBC_PUEN 76
+#define GPIO81_HX4700_CPU_GP_nRESET 81
+#define GPIO82_HX4700_EUART_RESET 82
+#define GPIO83_HX4700_WLAN_nRESET 83
+#define GPIO84_HX4700_LCD_SQN 84
+#define GPIO85_HX4700_nPCE1 85
+#define GPIO88_HX4700_TSC2046_CS 88
+#define GPIO91_HX4700_FLASH_VPEN 91
+#define GPIO92_HX4700_HP_DRIVER 92
+#define GPIO93_HX4700_EUART_INT 93
+#define GPIO94_HX4700_KEY_MAIL 94
+#define GPIO95_HX4700_BATT_OFF 95
+#define GPIO96_HX4700_BQ24022_ISET2 96
+#define GPIO97_HX4700_nBL_DETECT 97
+#define GPIO99_HX4700_KEY_CONTACTS 99
+#define GPIO100_HX4700_AUTO_SENSE 100 /* BL auto brightness */
+#define GPIO102_HX4700_SYNAPTICS_POWER_ON 102
+#define GPIO103_HX4700_SYNAPTICS_INT 103
+#define GPIO105_HX4700_nIR_ON 105
+#define GPIO106_HX4700_CPU_BT_nRESET 106
+#define GPIO107_HX4700_SPK_nSD 107
+#define GPIO109_HX4700_CODEC_nPDN 109
+#define GPIO110_HX4700_LCD_LVDD_3V3_ON 110
+#define GPIO111_HX4700_LCD_AVDD_3V3_ON 111
+#define GPIO112_HX4700_LCD_N2V7_7V3_ON 112
+#define GPIO114_HX4700_CF_RESET 114
+#define GPIO116_HX4700_CPU_HW_nRESET 116
+
+/*
+ * ASIC3 GPIOs
+ */
+
+#define GPIOC_BASE (HX4700_ASIC3_GPIO_BASE + 32)
+#define GPIOD_BASE (HX4700_ASIC3_GPIO_BASE + 48)
+
+#define GPIOC0_LED_RED (GPIOC_BASE + 0)
+#define GPIOC1_LED_GREEN (GPIOC_BASE + 1)
+#define GPIOC2_LED_BLUE (GPIOC_BASE + 2)
+#define GPIOC3_nSD_CS (GPIOC_BASE + 3)
+#define GPIOC4_CF_nCD (GPIOC_BASE + 4) /* Input */
+#define GPIOC5_nCIOW (GPIOC_BASE + 5) /* Output, to CF */
+#define GPIOC6_nCIOR (GPIOC_BASE + 6) /* Output, to CF */
+#define GPIOC7_nPCE1 (GPIOC_BASE + 7) /* Input, from CPU */
+#define GPIOC8_nPCE2 (GPIOC_BASE + 8) /* Input, from CPU */
+#define GPIOC9_nPOE (GPIOC_BASE + 9) /* Input, from CPU */
+#define GPIOC10_CF_nPWE (GPIOC_BASE + 10) /* Input */
+#define GPIOC11_PSKTSEL (GPIOC_BASE + 11) /* Input, from CPU */
+#define GPIOC12_nPREG (GPIOC_BASE + 12) /* Input, from CPU */
+#define GPIOC13_nPWAIT (GPIOC_BASE + 13) /* Output, to CPU */
+#define GPIOC14_nPIOIS16 (GPIOC_BASE + 14) /* Output, to CPU */
+#define GPIOC15_nPIOR (GPIOC_BASE + 15) /* Input, from CPU */
+
+#define GPIOD0_CPU_SS_INT (GPIOD_BASE + 0) /* Input */
+#define GPIOD1_nKEY_CALENDAR (GPIOD_BASE + 1)
+#define GPIOD2_BLUETOOTH_WAKEUP (GPIOD_BASE + 2)
+#define GPIOD3_nKEY_HOME (GPIOD_BASE + 3)
+#define GPIOD4_CF_nCD (GPIOD_BASE + 4) /* Input, from CF */
+#define GPIOD5_nPIO (GPIOD_BASE + 5) /* Input */
+#define GPIOD6_nKEY_RECORD (GPIOD_BASE + 6)
+#define GPIOD7_nSDIO_DETECT (GPIOD_BASE + 7)
+#define GPIOD8_COM_DCD (GPIOD_BASE + 8) /* Input */
+#define GPIOD9_nAC_IN (GPIOD_BASE + 9)
+#define GPIOD10_nSDIO_IRQ (GPIOD_BASE + 10) /* Input */
+#define GPIOD11_nCIOIS16 (GPIOD_BASE + 11) /* Input, from CF */
+#define GPIOD12_nCWAIT (GPIOD_BASE + 12) /* Input, from CF */
+#define GPIOD13_CF_RNB (GPIOD_BASE + 13) /* Input */
+#define GPIOD14_nUSBC_DETECT (GPIOD_BASE + 14)
+#define GPIOD15_nPIOW (GPIOD_BASE + 15) /* Input, from CPU */
+
+/*
+ * EGPIOs
+ */
+
+#define EGPIO0_VCC_3V3_EN (HX4700_EGPIO_BASE + 0) /* WLAN support chip */
+#define EGPIO1_WL_VREG_EN (HX4700_EGPIO_BASE + 1) /* WLAN power */
+#define EGPIO2_VCC_2V1_WL_EN (HX4700_EGPIO_BASE + 2) /* unused */
+#define EGPIO3_SS_PWR_ON (HX4700_EGPIO_BASE + 3) /* smart slot power */
+#define EGPIO4_CF_3V3_ON (HX4700_EGPIO_BASE + 4) /* CF 3.3V enable */
+#define EGPIO5_BT_3V3_ON (HX4700_EGPIO_BASE + 5) /* BT 3.3V enable */
+#define EGPIO6_WL1V8_EN (HX4700_EGPIO_BASE + 6) /* WLAN 1.8V enable */
+#define EGPIO7_VCC_3V3_WL_EN (HX4700_EGPIO_BASE + 7) /* WLAN 3.3V enable */
+#define EGPIO8_USB_3V3_ON (HX4700_EGPIO_BASE + 8) /* unused */
+
+#endif /* _HX4700_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/idp.h b/arch/arm/mach-pxa/include/mach/idp.h
new file mode 100644
index 00000000..5eff96fc
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/idp.h
@@ -0,0 +1,199 @@
+/*
+ * arch/arm/mach-pxa/include/mach/idp.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
+ *
+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
+ * Initial code
+ *
+ * 2005-02-15: Cliff Brake <cliff.brake@gmail.com>
+ * <http://www.vibren.com> <http://bec-systems.com>
+ * Changes for 2.6 kernel.
+ */
+
+
+/*
+ * Note: this file must be safe to include in assembly files
+ *
+ * Support for the Vibren PXA255 IDP requires rev04 or later
+ * IDP hardware.
+ */
+
+
+#define IDP_FLASH_PHYS (PXA_CS0_PHYS)
+#define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS)
+#define IDP_MEDIAQ_PHYS (PXA_CS3_PHYS)
+#define IDP_IDE_PHYS (PXA_CS5_PHYS + 0x03000000)
+#define IDP_ETH_PHYS (PXA_CS5_PHYS + 0x03400000)
+#define IDP_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000)
+#define IDP_CPLD_PHYS (PXA_CS5_PHYS + 0x03C00000)
+
+
+/*
+ * virtual memory map
+ */
+
+#define IDP_COREVOLT_VIRT (0xf0000000)
+#define IDP_COREVOLT_SIZE (1*1024*1024)
+
+#define IDP_CPLD_VIRT (IDP_COREVOLT_VIRT + IDP_COREVOLT_SIZE)
+#define IDP_CPLD_SIZE (1*1024*1024)
+
+#if (IDP_CPLD_VIRT + IDP_CPLD_SIZE) > 0xfc000000
+#error Your custom IO space is getting a bit large !!
+#endif
+
+#define CPLD_P2V(x) ((x) - IDP_CPLD_PHYS + IDP_CPLD_VIRT)
+#define CPLD_V2P(x) ((x) - IDP_CPLD_VIRT + IDP_CPLD_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __CPLD_REG(x) (*((volatile unsigned long *)CPLD_P2V(x)))
+#else
+# define __CPLD_REG(x) CPLD_P2V(x)
+#endif
+
+/* board level registers in the CPLD: (offsets from CPLD_VIRT) */
+
+#define _IDP_CPLD_REV (IDP_CPLD_PHYS + 0x00)
+#define _IDP_CPLD_PERIPH_PWR (IDP_CPLD_PHYS + 0x04)
+#define _IDP_CPLD_LED_CONTROL (IDP_CPLD_PHYS + 0x08)
+#define _IDP_CPLD_KB_COL_HIGH (IDP_CPLD_PHYS + 0x0C)
+#define _IDP_CPLD_KB_COL_LOW (IDP_CPLD_PHYS + 0x10)
+#define _IDP_CPLD_PCCARD_EN (IDP_CPLD_PHYS + 0x14)
+#define _IDP_CPLD_GPIOH_DIR (IDP_CPLD_PHYS + 0x18)
+#define _IDP_CPLD_GPIOH_VALUE (IDP_CPLD_PHYS + 0x1C)
+#define _IDP_CPLD_GPIOL_DIR (IDP_CPLD_PHYS + 0x20)
+#define _IDP_CPLD_GPIOL_VALUE (IDP_CPLD_PHYS + 0x24)
+#define _IDP_CPLD_PCCARD_PWR (IDP_CPLD_PHYS + 0x28)
+#define _IDP_CPLD_MISC_CTRL (IDP_CPLD_PHYS + 0x2C)
+#define _IDP_CPLD_LCD (IDP_CPLD_PHYS + 0x30)
+#define _IDP_CPLD_FLASH_WE (IDP_CPLD_PHYS + 0x34)
+
+#define _IDP_CPLD_KB_ROW (IDP_CPLD_PHYS + 0x50)
+#define _IDP_CPLD_PCCARD0_STATUS (IDP_CPLD_PHYS + 0x54)
+#define _IDP_CPLD_PCCARD1_STATUS (IDP_CPLD_PHYS + 0x58)
+#define _IDP_CPLD_MISC_STATUS (IDP_CPLD_PHYS + 0x5C)
+
+/* FPGA register virtual addresses */
+
+#define IDP_CPLD_REV __CPLD_REG(_IDP_CPLD_REV)
+#define IDP_CPLD_PERIPH_PWR __CPLD_REG(_IDP_CPLD_PERIPH_PWR)
+#define IDP_CPLD_LED_CONTROL __CPLD_REG(_IDP_CPLD_LED_CONTROL)
+#define IDP_CPLD_KB_COL_HIGH __CPLD_REG(_IDP_CPLD_KB_COL_HIGH)
+#define IDP_CPLD_KB_COL_LOW __CPLD_REG(_IDP_CPLD_KB_COL_LOW)
+#define IDP_CPLD_PCCARD_EN __CPLD_REG(_IDP_CPLD_PCCARD_EN)
+#define IDP_CPLD_GPIOH_DIR __CPLD_REG(_IDP_CPLD_GPIOH_DIR)
+#define IDP_CPLD_GPIOH_VALUE __CPLD_REG(_IDP_CPLD_GPIOH_VALUE)
+#define IDP_CPLD_GPIOL_DIR __CPLD_REG(_IDP_CPLD_GPIOL_DIR)
+#define IDP_CPLD_GPIOL_VALUE __CPLD_REG(_IDP_CPLD_GPIOL_VALUE)
+#define IDP_CPLD_PCCARD_PWR __CPLD_REG(_IDP_CPLD_PCCARD_PWR)
+#define IDP_CPLD_MISC_CTRL __CPLD_REG(_IDP_CPLD_MISC_CTRL)
+#define IDP_CPLD_LCD __CPLD_REG(_IDP_CPLD_LCD)
+#define IDP_CPLD_FLASH_WE __CPLD_REG(_IDP_CPLD_FLASH_WE)
+
+#define IDP_CPLD_KB_ROW __CPLD_REG(_IDP_CPLD_KB_ROW)
+#define IDP_CPLD_PCCARD0_STATUS __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS)
+#define IDP_CPLD_PCCARD1_STATUS __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS)
+#define IDP_CPLD_MISC_STATUS __CPLD_REG(_IDP_CPLD_MISC_STATUS)
+
+
+/*
+ * Bit masks for various registers
+ */
+
+// IDP_CPLD_PCCARD_PWR
+#define PCC0_PWR0 (1 << 0)
+#define PCC0_PWR1 (1 << 1)
+#define PCC0_PWR2 (1 << 2)
+#define PCC0_PWR3 (1 << 3)
+#define PCC1_PWR0 (1 << 4)
+#define PCC1_PWR1 (1 << 5)
+#define PCC1_PWR2 (1 << 6)
+#define PCC1_PWR3 (1 << 7)
+
+// IDP_CPLD_PCCARD_EN
+#define PCC0_RESET (1 << 6)
+#define PCC1_RESET (1 << 7)
+#define PCC0_ENABLE (1 << 0)
+#define PCC1_ENABLE (1 << 1)
+
+// IDP_CPLD_PCCARDx_STATUS
+#define _PCC_WRPROT (1 << 7) // 7-4 read as low true
+#define _PCC_RESET (1 << 6)
+#define _PCC_IRQ (1 << 5)
+#define _PCC_INPACK (1 << 4)
+#define PCC_BVD2 (1 << 3)
+#define PCC_BVD1 (1 << 2)
+#define PCC_VS2 (1 << 1)
+#define PCC_VS1 (1 << 0)
+
+#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x)))
+
+/* A listing of interrupts used by external hardware devices */
+
+#define TOUCH_PANEL_IRQ IRQ_GPIO(5)
+#define IDE_IRQ IRQ_GPIO(21)
+
+#define TOUCH_PANEL_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+
+#define ETHERNET_IRQ IRQ_GPIO(4)
+#define ETHERNET_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCMCIA_S0_CD_VALID IRQ_GPIO(7)
+#define PCMCIA_S0_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S1_CD_VALID IRQ_GPIO(8)
+#define PCMCIA_S1_CD_VALID_EDGE IRQ_TYPE_EDGE_BOTH
+
+#define PCMCIA_S0_RDYINT IRQ_GPIO(19)
+#define PCMCIA_S1_RDYINT IRQ_GPIO(22)
+
+
+/*
+ * Macros for LED Driver
+ */
+
+/* leds 0 = ON */
+#define IDP_HB_LED (1<<5)
+#define IDP_BUSY_LED (1<<6)
+
+#define IDP_LEDS_MASK (IDP_HB_LED | IDP_BUSY_LED)
+
+/*
+ * macros for MTD driver
+ */
+
+#define FLASH_WRITE_PROTECT_DISABLE() ((IDP_CPLD_FLASH_WE) &= ~(0x1))
+#define FLASH_WRITE_PROTECT_ENABLE() ((IDP_CPLD_FLASH_WE) |= (0x1))
+
+/*
+ * macros for matrix keyboard driver
+ */
+
+#define KEYBD_MATRIX_NUMBER_INPUTS 7
+#define KEYBD_MATRIX_NUMBER_OUTPUTS 14
+
+#define KEYBD_MATRIX_INVERT_OUTPUT_LOGIC FALSE
+#define KEYBD_MATRIX_INVERT_INPUT_LOGIC FALSE
+
+#define KEYBD_MATRIX_SETTLING_TIME_US 100
+#define KEYBD_MATRIX_KEYSTATE_DEBOUNCE_CONSTANT 2
+
+#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \
+{\
+ IDP_CPLD_KB_COL_LOW = outputs;\
+ IDP_CPLD_KB_COL_HIGH = outputs >> 7;\
+}
+
+#define KEYBD_MATRIX_GET_INPUTS(inputs) \
+{\
+ inputs = (IDP_CPLD_KB_ROW & 0x7f);\
+}
+
+
diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h
new file mode 100644
index 00000000..fdca3be4
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-pxa/include/mach/io.h
+ *
+ * Copied from asm/arch/sa1100/io.h
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/irda.h b/arch/arm/mach-pxa/include/mach/irda.h
new file mode 100644
index 00000000..3cd41f77
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/irda.h
@@ -0,0 +1,25 @@
+#ifndef ASMARM_ARCH_IRDA_H
+#define ASMARM_ARCH_IRDA_H
+
+/* board specific transceiver capabilities */
+
+#define IR_OFF 1
+#define IR_SIRMODE 2
+#define IR_FIRMODE 4
+
+struct pxaficp_platform_data {
+ int transceiver_cap;
+ void (*transceiver_mode)(struct device *dev, int mode);
+ int (*startup)(struct device *dev);
+ void (*shutdown)(struct device *dev);
+ int gpio_pwdown; /* powerdown GPIO for the IrDA chip */
+ bool gpio_pwdown_inverted; /* gpio_pwdown is inverted */
+};
+
+extern void pxa_set_ficp_info(struct pxaficp_platform_data *info);
+
+#if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x)
+void pxa2xx_transceiver_mode(struct device *dev, int mode);
+#endif
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
new file mode 100644
index 00000000..03840240
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -0,0 +1,107 @@
+/*
+ * arch/arm/mach-pxa/include/mach/irqs.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+#ifdef CONFIG_PXA_HAVE_ISA_IRQS
+#define PXA_ISA_IRQ(x) (x)
+#define PXA_ISA_IRQ_NUM (16)
+#else
+#define PXA_ISA_IRQ_NUM (0)
+#endif
+
+#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x))
+
+#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
+#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
+#define IRQ_USBH2 PXA_IRQ(2) /* USB Host interrupt 1 (OHCI,PXA27x) */
+#define IRQ_USBH1 PXA_IRQ(3) /* USB Host interrupt 2 (non-OHCI,PXA27x) */
+#define IRQ_KEYPAD PXA_IRQ(4) /* Key pad controller */
+#define IRQ_MEMSTK PXA_IRQ(5) /* Memory Stick interrupt (PXA27x) */
+#define IRQ_ACIPC0 PXA_IRQ(5) /* AP-CP Communication (PXA930) */
+#define IRQ_PWRI2C PXA_IRQ(6) /* Power I2C interrupt */
+#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error (PXA26x) */
+#define IRQ_OST_4_11 PXA_IRQ(7) /* OS timer 4-11 matches (PXA27x) */
+#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
+#define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */
+#define IRQ_GPIO_2_x PXA_IRQ(10) /* GPIO[2-x] Edge Detect */
+#define IRQ_USB PXA_IRQ(11) /* USB Service */
+#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */
+#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt (PXA27x) */
+#define IRQ_SSP4 PXA_IRQ(13) /* SSP4 service request (PXA3xx) */
+#define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */
+#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request (PXA25x) */
+#define IRQ_USIM PXA_IRQ(15) /* Smart Card interface interrupt (PXA27x) */
+#define IRQ_NSSP PXA_IRQ(16) /* Network SSP Service Request (PXA25x) */
+#define IRQ_SSP2 PXA_IRQ(16) /* SSP2 interrupt (PXA27x) */
+#define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */
+#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */
+#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */
+#define IRQ_ACIPC2 PXA_IRQ(19) /* AP-CP Communication (PXA930) */
+#define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */
+#define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */
+#define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/
+#define IRQ_MMC PXA_IRQ(23) /* MMC Status/Error Detection */
+#define IRQ_SSP PXA_IRQ(24) /* SSP Service Request */
+#define IRQ_DMA PXA_IRQ(25) /* DMA Channel Service Request */
+#define IRQ_OST0 PXA_IRQ(26) /* OS Timer match 0 */
+#define IRQ_OST1 PXA_IRQ(27) /* OS Timer match 1 */
+#define IRQ_OST2 PXA_IRQ(28) /* OS Timer match 2 */
+#define IRQ_OST3 PXA_IRQ(29) /* OS Timer match 3 */
+#define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */
+#define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */
+
+#define IRQ_TPM PXA_IRQ(32) /* TPM interrupt */
+#define IRQ_CAMERA PXA_IRQ(33) /* Camera Interface */
+#define IRQ_CIR PXA_IRQ(34) /* Consumer IR */
+#define IRQ_COMM_WDT PXA_IRQ(35) /* Comm WDT interrupt */
+#define IRQ_TSI PXA_IRQ(36) /* Touch Screen Interface (PXA320) */
+#define IRQ_ENHROT PXA_IRQ(37) /* Enhanced Rotary (PXA930) */
+#define IRQ_USIM2 PXA_IRQ(38) /* USIM2 Controller */
+#define IRQ_GCU PXA_IRQ(39) /* Graphics Controller (PXA3xx) */
+#define IRQ_ACIPC1 PXA_IRQ(40) /* AP-CP Communication (PXA930) */
+#define IRQ_MMC2 PXA_IRQ(41) /* MMC2 Controller */
+#define IRQ_TRKBALL PXA_IRQ(43) /* Track Ball (PXA930) */
+#define IRQ_1WIRE PXA_IRQ(44) /* 1-Wire Controller */
+#define IRQ_NAND PXA_IRQ(45) /* NAND Controller */
+#define IRQ_USB2 PXA_IRQ(46) /* USB 2.0 Device Controller */
+#define IRQ_WAKEUP0 PXA_IRQ(49) /* EXT_WAKEUP0 */
+#define IRQ_WAKEUP1 PXA_IRQ(50) /* EXT_WAKEUP1 */
+#define IRQ_DMEMC PXA_IRQ(51) /* Dynamic Memory Controller */
+#define IRQ_MMC3 PXA_IRQ(55) /* MMC3 Controller (PXA310) */
+
+#define IRQ_U2O PXA_IRQ(64) /* USB OTG 2.0 Controller (PXA935) */
+#define IRQ_U2H PXA_IRQ(65) /* USB Host 2.0 Controller (PXA935) */
+#define IRQ_PXA935_MMC0 PXA_IRQ(72) /* MMC0 Controller (PXA935) */
+#define IRQ_PXA935_MMC1 PXA_IRQ(73) /* MMC1 Controller (PXA935) */
+#define IRQ_PXA935_MMC2 PXA_IRQ(74) /* MMC2 Controller (PXA935) */
+#define IRQ_PXA955_MMC3 PXA_IRQ(75) /* MMC3 Controller (PXA955) */
+#define IRQ_U2P PXA_IRQ(93) /* USB PHY D+/D- Lines (PXA935) */
+
+#define PXA_GPIO_IRQ_BASE PXA_IRQ(96)
+#define PXA_GPIO_IRQ_NUM (192)
+
+#define GPIO_2_x_TO_IRQ(x) (PXA_GPIO_IRQ_BASE + (x))
+#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_x_TO_IRQ(x))
+
+/*
+ * The following interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.
+ * By default, no board IRQ is reserved. It should be finished in
+ * custom board since sparse IRQ is already enabled.
+ */
+#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_GPIO_IRQ_NUM)
+
+#define NR_IRQS (IRQ_BOARD_START)
+
+#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-pxa/include/mach/littleton.h b/arch/arm/mach-pxa/include/mach/littleton.h
new file mode 100644
index 00000000..2a5726c1
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/littleton.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_ARCH_LITTLETON_H
+#define __ASM_ARCH_LITTLETON_H
+
+#include <mach/gpio.h>
+
+#define LITTLETON_ETH_PHYS 0x30000000
+
+#define LITTLETON_GPIO_LCD_CS (17)
+
+#define EXT0_GPIO_BASE (NR_BUILTIN_GPIO)
+#define EXT0_GPIO(x) (EXT0_GPIO_BASE + (x))
+
+#define LITTLETON_NR_IRQS (IRQ_BOARD_START + 8)
+
+#endif /* __ASM_ARCH_LITTLETON_H */
diff --git a/arch/arm/mach-pxa/include/mach/lpd270.h b/arch/arm/mach-pxa/include/mach/lpd270.h
new file mode 100644
index 00000000..cd070092
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/lpd270.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/mach-pxa/include/mach/lpd270.h
+ *
+ * Author: Lennert Buytenhek
+ * Created: Feb 10, 2006
+ *
+ * This program is free software; you can 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_LPD270_H
+#define __ASM_ARCH_LPD270_H
+
+#define LPD270_CPLD_PHYS PXA_CS2_PHYS
+#define LPD270_CPLD_VIRT 0xf0000000
+#define LPD270_CPLD_SIZE 0x00100000
+
+#define LPD270_ETH_PHYS (PXA_CS2_PHYS + 0x01000000)
+
+/* CPLD registers */
+#define LPD270_CPLD_REG(x) ((unsigned long)(LPD270_CPLD_VIRT + (x)))
+#define LPD270_CONTROL LPD270_CPLD_REG(0x00)
+#define LPD270_PERIPHERAL0 LPD270_CPLD_REG(0x04)
+#define LPD270_PERIPHERAL1 LPD270_CPLD_REG(0x08)
+#define LPD270_CPLD_REVISION LPD270_CPLD_REG(0x14)
+#define LPD270_EEPROM_SPI_ITF LPD270_CPLD_REG(0x20)
+#define LPD270_MODE_PINS LPD270_CPLD_REG(0x24)
+#define LPD270_EGPIO LPD270_CPLD_REG(0x30)
+#define LPD270_INT_MASK LPD270_CPLD_REG(0x40)
+#define LPD270_INT_STATUS LPD270_CPLD_REG(0x50)
+
+#define LPD270_INT_AC97 (1 << 4) /* AC'97 CODEC IRQ */
+#define LPD270_INT_ETHERNET (1 << 3) /* Ethernet controller IRQ */
+#define LPD270_INT_USBC (1 << 2) /* USB client cable detection IRQ */
+
+#define LPD270_IRQ(x) (IRQ_BOARD_START + (x))
+#define LPD270_USBC_IRQ LPD270_IRQ(2)
+#define LPD270_ETHERNET_IRQ LPD270_IRQ(3)
+#define LPD270_AC97_IRQ LPD270_IRQ(4)
+#define LPD270_NR_IRQS (IRQ_BOARD_START + 5)
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/lubbock.h b/arch/arm/mach-pxa/include/mach/lubbock.h
new file mode 100644
index 00000000..2a086e83
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/lubbock.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-pxa/include/mach/lubbock.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define LUBBOCK_ETH_PHYS PXA_CS3_PHYS
+
+#define LUBBOCK_FPGA_PHYS PXA_CS2_PHYS
+#define LUBBOCK_FPGA_VIRT (0xf0000000)
+#define LUB_P2V(x) ((x) - LUBBOCK_FPGA_PHYS + LUBBOCK_FPGA_VIRT)
+#define LUB_V2P(x) ((x) - LUBBOCK_FPGA_VIRT + LUBBOCK_FPGA_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __LUB_REG(x) (*((volatile unsigned long *)LUB_P2V(x)))
+#else
+# define __LUB_REG(x) LUB_P2V(x)
+#endif
+
+/* FPGA register virtual addresses */
+#define LUB_WHOAMI __LUB_REG(LUBBOCK_FPGA_PHYS + 0x000)
+#define LUB_DISC_BLNK_LED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x040)
+#define LUB_CONF_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x050)
+#define LUB_USER_SWITCHES __LUB_REG(LUBBOCK_FPGA_PHYS + 0x060)
+#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
+#define LUB_MISC_RD __LUB_REG(LUBBOCK_FPGA_PHYS + 0x090)
+#define LUB_IRQ_MASK_EN __LUB_REG(LUBBOCK_FPGA_PHYS + 0x0c0)
+#define LUB_IRQ_SET_CLR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x0d0)
+#define LUB_GP __LUB_REG(LUBBOCK_FPGA_PHYS + 0x100)
+
+/* Board specific IRQs */
+#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x))
+#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0)
+#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1)
+#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */
+#define LUBBOCK_ETH_IRQ LUBBOCK_IRQ(3)
+#define LUBBOCK_UCB1400_IRQ LUBBOCK_IRQ(4)
+#define LUBBOCK_BB_IRQ LUBBOCK_IRQ(5)
+#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
+#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
+
+#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16)
+#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55)
+
+#ifndef __ASSEMBLY__
+extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h
new file mode 100644
index 00000000..0a2efcf7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/magician.h
@@ -0,0 +1,119 @@
+/*
+ * GPIO and IRQ definitions for HTC Magician PDA phones
+ *
+ * Copyright (c) 2007 Philipp Zabel
+ *
+ * This program is free software; you can 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 _MAGICIAN_H_
+#define _MAGICIAN_H_
+
+#include <mach/irqs.h>
+
+/*
+ * PXA GPIOs
+ */
+
+#define GPIO0_MAGICIAN_KEY_POWER 0
+#define GPIO9_MAGICIAN_UNKNOWN 9
+#define GPIO10_MAGICIAN_GSM_IRQ 10
+#define GPIO11_MAGICIAN_GSM_OUT1 11
+#define GPIO13_MAGICIAN_CPLD_IRQ 13
+#define GPIO18_MAGICIAN_UNKNOWN 18
+#define GPIO22_MAGICIAN_VIBRA_EN 22
+#define GPIO26_MAGICIAN_GSM_POWER 26
+#define GPIO27_MAGICIAN_USBC_PUEN 27
+#define GPIO30_MAGICIAN_BQ24022_nCHARGE_EN 30
+#define GPIO37_MAGICIAN_KEY_HANGUP 37
+#define GPIO38_MAGICIAN_KEY_CONTACTS 38
+#define GPIO40_MAGICIAN_GSM_OUT2 40
+#define GPIO48_MAGICIAN_UNKNOWN 48
+#define GPIO56_MAGICIAN_UNKNOWN 56
+#define GPIO57_MAGICIAN_CAM_RESET 57
+#define GPIO75_MAGICIAN_SAMSUNG_POWER 75
+#define GPIO83_MAGICIAN_nIR_EN 83
+#define GPIO86_MAGICIAN_GSM_RESET 86
+#define GPIO87_MAGICIAN_GSM_SELECT 87
+#define GPIO90_MAGICIAN_KEY_CALENDAR 90
+#define GPIO91_MAGICIAN_KEY_CAMERA 91
+#define GPIO93_MAGICIAN_KEY_UP 93
+#define GPIO94_MAGICIAN_KEY_DOWN 94
+#define GPIO95_MAGICIAN_KEY_LEFT 95
+#define GPIO96_MAGICIAN_KEY_RIGHT 96
+#define GPIO97_MAGICIAN_KEY_ENTER 97
+#define GPIO98_MAGICIAN_KEY_RECORD 98
+#define GPIO99_MAGICIAN_HEADPHONE_IN 99
+#define GPIO100_MAGICIAN_KEY_VOL_UP 100
+#define GPIO101_MAGICIAN_KEY_VOL_DOWN 101
+#define GPIO102_MAGICIAN_KEY_PHONE 102
+#define GPIO103_MAGICIAN_LED_KP 103
+#define GPIO104_MAGICIAN_LCD_POWER_1 104
+#define GPIO105_MAGICIAN_LCD_POWER_2 105
+#define GPIO106_MAGICIAN_LCD_POWER_3 106
+#define GPIO107_MAGICIAN_DS1WM_IRQ 107
+#define GPIO108_MAGICIAN_GSM_READY 108
+#define GPIO114_MAGICIAN_UNKNOWN 114
+#define GPIO115_MAGICIAN_nPEN_IRQ 115
+#define GPIO116_MAGICIAN_nCAM_EN 116
+#define GPIO119_MAGICIAN_UNKNOWN 119
+#define GPIO120_MAGICIAN_UNKNOWN 120
+
+/*
+ * CPLD IRQs
+ */
+
+#define IRQ_MAGICIAN_SD (IRQ_BOARD_START + 0)
+#define IRQ_MAGICIAN_EP (IRQ_BOARD_START + 1)
+#define IRQ_MAGICIAN_BT (IRQ_BOARD_START + 2)
+#define IRQ_MAGICIAN_VBUS (IRQ_BOARD_START + 3)
+
+#define MAGICIAN_NR_IRQS (IRQ_BOARD_START + 8)
+
+/*
+ * CPLD EGPIOs
+ */
+
+#define MAGICIAN_EGPIO_BASE 0x80 /* GPIO_BOARD_START */
+#define MAGICIAN_EGPIO(reg,bit) \
+ (MAGICIAN_EGPIO_BASE + 8*reg + bit)
+
+/* output */
+
+#define EGPIO_MAGICIAN_TOPPOLY_POWER MAGICIAN_EGPIO(0, 2)
+#define EGPIO_MAGICIAN_LED_POWER MAGICIAN_EGPIO(0, 5)
+#define EGPIO_MAGICIAN_GSM_RESET MAGICIAN_EGPIO(0, 6)
+#define EGPIO_MAGICIAN_LCD_POWER MAGICIAN_EGPIO(0, 7)
+#define EGPIO_MAGICIAN_SPK_POWER MAGICIAN_EGPIO(1, 0)
+#define EGPIO_MAGICIAN_EP_POWER MAGICIAN_EGPIO(1, 1)
+#define EGPIO_MAGICIAN_IN_SEL0 MAGICIAN_EGPIO(1, 2)
+#define EGPIO_MAGICIAN_IN_SEL1 MAGICIAN_EGPIO(1, 3)
+#define EGPIO_MAGICIAN_MIC_POWER MAGICIAN_EGPIO(1, 4)
+#define EGPIO_MAGICIAN_CODEC_RESET MAGICIAN_EGPIO(1, 5)
+#define EGPIO_MAGICIAN_CODEC_POWER MAGICIAN_EGPIO(1, 6)
+#define EGPIO_MAGICIAN_BL_POWER MAGICIAN_EGPIO(1, 7)
+#define EGPIO_MAGICIAN_SD_POWER MAGICIAN_EGPIO(2, 0)
+#define EGPIO_MAGICIAN_CARKIT_MIC MAGICIAN_EGPIO(2, 1)
+#define EGPIO_MAGICIAN_UNKNOWN_WAVEDEV_DLL MAGICIAN_EGPIO(2, 2)
+#define EGPIO_MAGICIAN_FLASH_VPP MAGICIAN_EGPIO(2, 3)
+#define EGPIO_MAGICIAN_BL_POWER2 MAGICIAN_EGPIO(2, 4)
+#define EGPIO_MAGICIAN_BQ24022_ISET2 MAGICIAN_EGPIO(2, 5)
+#define EGPIO_MAGICIAN_GSM_POWER MAGICIAN_EGPIO(2, 7)
+
+/* input */
+
+#define EGPIO_MAGICIAN_CABLE_STATE_AC MAGICIAN_EGPIO(4, 0)
+#define EGPIO_MAGICIAN_CABLE_STATE_USB MAGICIAN_EGPIO(4, 1)
+
+#define EGPIO_MAGICIAN_BOARD_ID0 MAGICIAN_EGPIO(5, 0)
+#define EGPIO_MAGICIAN_BOARD_ID1 MAGICIAN_EGPIO(5, 1)
+#define EGPIO_MAGICIAN_BOARD_ID2 MAGICIAN_EGPIO(5, 2)
+#define EGPIO_MAGICIAN_LCD_SELECT MAGICIAN_EGPIO(5, 3)
+#define EGPIO_MAGICIAN_nSD_READONLY MAGICIAN_EGPIO(5, 4)
+
+#define EGPIO_MAGICIAN_EP_INSERT MAGICIAN_EGPIO(6, 1)
+
+#endif /* _MAGICIAN_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h
new file mode 100644
index 00000000..4c2d11cd
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mainstone.h
@@ -0,0 +1,139 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mainstone.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 14, 2002
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ASM_ARCH_MAINSTONE_H
+#define ASM_ARCH_MAINSTONE_H
+
+#define MST_ETH_PHYS PXA_CS4_PHYS
+
+#define MST_FPGA_PHYS PXA_CS2_PHYS
+#define MST_FPGA_VIRT (0xf0000000)
+#define MST_P2V(x) ((x) - MST_FPGA_PHYS + MST_FPGA_VIRT)
+#define MST_V2P(x) ((x) - MST_FPGA_VIRT + MST_FPGA_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __MST_REG(x) (*((volatile unsigned long *)MST_P2V(x)))
+#else
+# define __MST_REG(x) MST_P2V(x)
+#endif
+
+/* board level registers in the FPGA */
+
+#define MST_LEDDAT1 __MST_REG(0x08000010)
+#define MST_LEDDAT2 __MST_REG(0x08000014)
+#define MST_LEDCTRL __MST_REG(0x08000040)
+#define MST_GPSWR __MST_REG(0x08000060)
+#define MST_MSCWR1 __MST_REG(0x08000080)
+#define MST_MSCWR2 __MST_REG(0x08000084)
+#define MST_MSCWR3 __MST_REG(0x08000088)
+#define MST_MSCRD __MST_REG(0x08000090)
+#define MST_INTMSKENA __MST_REG(0x080000c0)
+#define MST_INTSETCLR __MST_REG(0x080000d0)
+#define MST_PCMCIA0 __MST_REG(0x080000e0)
+#define MST_PCMCIA1 __MST_REG(0x080000e4)
+
+#define MST_MSCWR1_CAMERA_ON (1 << 15) /* Camera interface power control */
+#define MST_MSCWR1_CAMERA_SEL (1 << 14) /* Camera interface mux control */
+#define MST_MSCWR1_LCD_CTL (1 << 13) /* General-purpose LCD control */
+#define MST_MSCWR1_MS_ON (1 << 12) /* Memory Stick power control */
+#define MST_MSCWR1_MMC_ON (1 << 11) /* MultiMediaCard* power control */
+#define MST_MSCWR1_MS_SEL (1 << 10) /* SD/MS multiplexer control */
+#define MST_MSCWR1_BB_SEL (1 << 9) /* PCMCIA/Baseband multiplexer */
+#define MST_MSCWR1_BT_ON (1 << 8) /* Bluetooth UART transceiver */
+#define MST_MSCWR1_BTDTR (1 << 7) /* Bluetooth UART DTR */
+
+#define MST_MSCWR1_IRDA_MASK (3 << 5) /* IrDA transceiver mode */
+#define MST_MSCWR1_IRDA_FULL (0 << 5) /* full distance power */
+#define MST_MSCWR1_IRDA_OFF (1 << 5) /* shutdown */
+#define MST_MSCWR1_IRDA_MED (2 << 5) /* 2/3 distance power */
+#define MST_MSCWR1_IRDA_LOW (3 << 5) /* 1/3 distance power */
+
+#define MST_MSCWR1_IRDA_FIR (1 << 4) /* IrDA transceiver SIR/FIR */
+#define MST_MSCWR1_GREENLED (1 << 3) /* LED D1 control */
+#define MST_MSCWR1_PDC_CTL (1 << 2) /* reserved */
+#define MST_MSCWR1_MTR_ON (1 << 1) /* Silent alert motor */
+#define MST_MSCWR1_SYSRESET (1 << 0) /* System reset */
+
+#define MST_MSCWR2_USB_OTG_RST (1 << 6) /* USB On The Go reset */
+#define MST_MSCWR2_USB_OTG_SEL (1 << 5) /* USB On The Go control */
+#define MST_MSCWR2_nUSBC_SC (1 << 4) /* USB client soft connect control */
+#define MST_MSCWR2_I2S_SPKROFF (1 << 3) /* I2S CODEC amplifier control */
+#define MST_MSCWR2_AC97_SPKROFF (1 << 2) /* AC97 CODEC amplifier control */
+#define MST_MSCWR2_RADIO_PWR (1 << 1) /* Radio module power control */
+#define MST_MSCWR2_RADIO_WAKE (1 << 0) /* Radio module wake-up signal */
+
+#define MST_MSCWR3_GPIO_RESET_EN (1 << 2) /* Enable GPIO Reset */
+#define MST_MSCWR3_GPIO_RESET (1 << 1) /* Initiate a GPIO Reset */
+#define MST_MSCWR3_COMMS_SW_RESET (1 << 0) /* Communications Processor Reset Control */
+
+#define MST_MSCRD_nPENIRQ (1 << 9) /* ADI7873* nPENIRQ signal */
+#define MST_MSCRD_nMEMSTK_CD (1 << 8) /* Memory Stick detection signal */
+#define MST_MSCRD_nMMC_CD (1 << 7) /* SD/MMC card detection signal */
+#define MST_MSCRD_nUSIM_CD (1 << 6) /* USIM card detection signal */
+#define MST_MSCRD_USB_CBL (1 << 5) /* USB client cable status */
+#define MST_MSCRD_TS_BUSY (1 << 4) /* ADI7873 busy */
+#define MST_MSCRD_BTDSR (1 << 3) /* Bluetooth UART DSR */
+#define MST_MSCRD_BTRI (1 << 2) /* Bluetooth UART Ring Indicator */
+#define MST_MSCRD_BTDCD (1 << 1) /* Bluetooth UART DCD */
+#define MST_MSCRD_nMMC_WP (1 << 0) /* SD/MMC write-protect status */
+
+#define MST_INT_S1_IRQ (1 << 15) /* PCMCIA socket 1 IRQ */
+#define MST_INT_S1_STSCHG (1 << 14) /* PCMCIA socket 1 status changed */
+#define MST_INT_S1_CD (1 << 13) /* PCMCIA socket 1 card detection */
+#define MST_INT_S0_IRQ (1 << 11) /* PCMCIA socket 0 IRQ */
+#define MST_INT_S0_STSCHG (1 << 10) /* PCMCIA socket 0 status changed */
+#define MST_INT_S0_CD (1 << 9) /* PCMCIA socket 0 card detection */
+#define MST_INT_nEXBRD_INT (1 << 7) /* Expansion board IRQ */
+#define MST_INT_MSINS (1 << 6) /* Memory Stick* detection */
+#define MST_INT_PENIRQ (1 << 5) /* ADI7873* touch-screen IRQ */
+#define MST_INT_AC97 (1 << 4) /* AC'97 CODEC IRQ */
+#define MST_INT_ETHERNET (1 << 3) /* Ethernet controller IRQ */
+#define MST_INT_USBC (1 << 2) /* USB client cable detection IRQ */
+#define MST_INT_USIM (1 << 1) /* USIM card detection IRQ */
+#define MST_INT_MMC (1 << 0) /* MMC/SD card detection IRQ */
+
+#define MST_PCMCIA_nIRQ (1 << 10) /* IRQ / ready signal */
+#define MST_PCMCIA_nSPKR_BVD2 (1 << 9) /* VDD sense / digital speaker */
+#define MST_PCMCIA_nSTSCHG_BVD1 (1 << 8) /* VDD sense / card status changed */
+#define MST_PCMCIA_nVS2 (1 << 7) /* VSS voltage sense */
+#define MST_PCMCIA_nVS1 (1 << 6) /* VSS voltage sense */
+#define MST_PCMCIA_nCD (1 << 5) /* Card detection signal */
+#define MST_PCMCIA_RESET (1 << 4) /* Card reset signal */
+#define MST_PCMCIA_PWR_MASK (0x000f) /* MAX1602 power-supply controls */
+
+#define MST_PCMCIA_PWR_VPP_0 0x0 /* voltage VPP = 0V */
+#define MST_PCMCIA_PWR_VPP_120 0x2 /* voltage VPP = 12V*/
+#define MST_PCMCIA_PWR_VPP_VCC 0x1 /* voltage VPP = VCC */
+#define MST_PCMCIA_PWR_VCC_0 0x0 /* voltage VCC = 0V */
+#define MST_PCMCIA_PWR_VCC_33 0x8 /* voltage VCC = 3.3V */
+#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */
+
+/* board specific IRQs */
+#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x))
+#define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0)
+#define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1)
+#define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2)
+#define MAINSTONE_ETHERNET_IRQ MAINSTONE_IRQ(3)
+#define MAINSTONE_AC97_IRQ MAINSTONE_IRQ(4)
+#define MAINSTONE_PEN_IRQ MAINSTONE_IRQ(5)
+#define MAINSTONE_MSINS_IRQ MAINSTONE_IRQ(6)
+#define MAINSTONE_EXBRD_IRQ MAINSTONE_IRQ(7)
+#define MAINSTONE_S0_CD_IRQ MAINSTONE_IRQ(9)
+#define MAINSTONE_S0_STSCHG_IRQ MAINSTONE_IRQ(10)
+#define MAINSTONE_S0_IRQ MAINSTONE_IRQ(11)
+#define MAINSTONE_S1_CD_IRQ MAINSTONE_IRQ(13)
+#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
+#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
+
+#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16)
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h
new file mode 100644
index 00000000..07734f37
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-pxa/include/mach/memory.h
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0xa0000000)
+
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define ARM_DMA_ZONE_SIZE SZ_64M
+#endif
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
new file mode 100644
index 00000000..cafadc33
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h
@@ -0,0 +1,225 @@
+#ifndef __ASM_ARCH_MFP_PXA25X_H
+#define __ASM_ARCH_MFP_PXA25X_H
+
+#include <mach/mfp-pxa2xx.h>
+
+/* GPIO */
+#define GPIO2_GPIO MFP_CFG_IN(GPIO2, AF0)
+#define GPIO3_GPIO MFP_CFG_IN(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG_IN(GPIO4, AF0)
+#define GPIO5_GPIO MFP_CFG_IN(GPIO5, AF0)
+#define GPIO6_GPIO MFP_CFG_IN(GPIO6, AF0)
+#define GPIO7_GPIO MFP_CFG_IN(GPIO7, AF0)
+#define GPIO8_GPIO MFP_CFG_IN(GPIO8, AF0)
+
+#define GPIO1_RST MFP_CFG_IN(GPIO1, AF1)
+
+/* Crystal and Clock Signals */
+#define GPIO10_RTCCLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
+#define GPIO70_RTCCLK MFP_CFG_OUT(GPIO70, AF1, DRIVE_LOW)
+#define GPIO7_48MHz MFP_CFG_OUT(GPIO7, AF1, DRIVE_LOW)
+#define GPIO11_3_6MHz MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
+#define GPIO71_3_6MHz MFP_CFG_OUT(GPIO71, AF1, DRIVE_LOW)
+#define GPIO12_32KHz MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
+#define GPIO72_32kHz MFP_CFG_OUT(GPIO72, AF1, DRIVE_LOW)
+
+/* SDRAM and Static Memory I/O Signals */
+#define GPIO15_nCS_1 MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
+#define GPIO78_nCS_2 MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
+#define GPIO79_nCS_3 MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
+#define GPIO80_nCS_4 MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
+#define GPIO33_nCS_5 MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
+
+/* Miscellaneous I/O and DMA Signals */
+#define GPIO18_RDY MFP_CFG_IN(GPIO18, AF1)
+#define GPIO20_DREQ_0 MFP_CFG_IN(GPIO20, AF1)
+#define GPIO19_DREQ_1 MFP_CFG_IN(GPIO19, AF1)
+
+/* Alternate Bus Master Mode I/O Signals */
+#define GPIO13_MBGNT MFP_CFG_OUT(GPIO13, AF2, DRIVE_LOW)
+#define GPIO73_MBGNT MFP_CFG_OUT(GPIO73, AF1, DRIVE_LOW)
+#define GPIO14_MBREQ MFP_CFG_IN(GPIO14, AF1)
+#define GPIO66_MBREQ MFP_CFG_IN(GPIO66, AF1)
+
+/* PC CARD */
+#define GPIO52_nPCE_1 MFP_CFG_OUT(GPIO52, AF2, DRIVE_HIGH)
+#define GPIO53_nPCE_2 MFP_CFG_OUT(GPIO53, AF2, DRIVE_HIGH)
+#define GPIO55_nPREG MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
+#define GPIO50_nPIOR MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
+#define GPIO51_nPIOW MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
+#define GPIO49_nPWE MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
+#define GPIO48_nPOE MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
+#define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1)
+#define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1)
+#define GPIO54_nPSKTSEL MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
+
+/* FFUART */
+#define GPIO34_FFUART_RXD MFP_CFG_IN(GPIO34, AF1)
+#define GPIO35_FFUART_CTS MFP_CFG_IN(GPIO35, AF1)
+#define GPIO36_FFUART_DCD MFP_CFG_IN(GPIO36, AF1)
+#define GPIO37_FFUART_DSR MFP_CFG_IN(GPIO37, AF1)
+#define GPIO38_FFUART_RI MFP_CFG_IN(GPIO38, AF1)
+#define GPIO39_FFUART_TXD MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
+#define GPIO40_FFUART_DTR MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
+#define GPIO41_FFUART_RTS MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
+
+/* BTUART */
+#define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1)
+#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+#define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1)
+#define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+
+/* STUART */
+#define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2)
+#define GPIO47_STUART_TXD MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
+
+/* HWUART */
+#define GPIO42_HWUART_RXD MFP_CFG_IN(GPIO42, AF3)
+#define GPIO43_HWUART_TXD MFP_CFG_OUT(GPIO43, AF3, DRIVE_HIGH)
+#define GPIO44_HWUART_CTS MFP_CFG_IN(GPIO44, AF3)
+#define GPIO45_HWUART_RTS MFP_CFG_OUT(GPIO45, AF3, DRIVE_HIGH)
+#define GPIO48_HWUART_TXD MFP_CFG_OUT(GPIO48, AF1, DRIVE_HIGH)
+#define GPIO49_HWUART_RXD MFP_CFG_IN(GPIO49, AF1)
+#define GPIO50_HWUART_CTS MFP_CFG_IN(GPIO50, AF1)
+#define GPIO51_HWUART_RTS MFP_CFG_OUT(GPIO51, AF1, DRIVE_HIGH)
+
+/* FICP */
+#define GPIO46_FICP_RXD MFP_CFG_IN(GPIO46, AF1)
+#define GPIO47_FICP_TXD MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
+
+/* PWM 0/1 */
+#define GPIO16_PWM0_OUT MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
+#define GPIO17_PWM1_OUT MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO28_AC97_BITCLK MFP_CFG_IN(GPIO28, AF1)
+#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
+#define GPIO30_AC97_SDATA_OUT MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
+#define GPIO31_AC97_SYNC MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
+#define GPIO32_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO32, AF1)
+
+/* I2S */
+#define GPIO28_I2S_BITCLK_IN MFP_CFG_IN(GPIO28, AF2)
+#define GPIO28_I2S_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
+#define GPIO29_I2S_SDATA_IN MFP_CFG_IN(GPIO29, AF2)
+#define GPIO30_I2S_SDATA_OUT MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
+#define GPIO31_I2S_SYNC MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
+#define GPIO32_I2S_SYSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+
+/* SSP 1 */
+#define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
+#define GPIO24_SSP1_SFRM MFP_CFG_OUT(GPIO24, AF2, DRIVE_LOW)
+#define GPIO25_SSP1_TXD MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
+#define GPIO26_SSP1_RXD MFP_CFG_IN(GPIO26, AF1)
+#define GPIO27_SSP1_EXTCLK MFP_CFG_IN(GPIO27, AF1)
+
+/* SSP 2 - NSSP */
+#define GPIO81_SSP2_CLK_OUT MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
+#define GPIO81_SSP2_CLK_IN MFP_CFG_IN(GPIO81, AF1)
+#define GPIO82_SSP2_FRM_OUT MFP_CFG_OUT(GPIO82, AF1, DRIVE_LOW)
+#define GPIO82_SSP2_FRM_IN MFP_CFG_IN(GPIO82, AF1)
+#define GPIO83_SSP2_TXD MFP_CFG_OUT(GPIO83, AF1, DRIVE_LOW)
+#define GPIO83_SSP2_RXD MFP_CFG_IN(GPIO83, AF2)
+#define GPIO84_SSP2_TXD MFP_CFG_OUT(GPIO84, AF1, DRIVE_LOW)
+#define GPIO84_SSP2_RXD MFP_CFG_IN(GPIO84, AF2)
+
+/* MMC */
+#define GPIO6_MMC_CLK MFP_CFG_OUT(GPIO6, AF1, DRIVE_LOW)
+#define GPIO8_MMC_CS0 MFP_CFG_OUT(GPIO8, AF1, DRIVE_LOW)
+#define GPIO9_MMC_CS1 MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
+#define GPIO34_MMC_CS0 MFP_CFG_OUT(GPIO34, AF2, DRIVE_LOW)
+#define GPIO39_MMC_CS1 MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
+#define GPIO53_MMC_CLK MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
+#define GPIO54_MMC_CLK MFP_CFG_OUT(GPIO54, AF1, DRIVE_LOW)
+#define GPIO69_MMC_CLK MFP_CFG_OUT(GPIO69, AF1, DRIVE_LOW)
+#define GPIO67_MMC_CS0 MFP_CFG_OUT(GPIO67, AF1, DRIVE_LOW)
+#define GPIO68_MMC_CS1 MFP_CFG_OUT(GPIO68, AF1, DRIVE_LOW)
+
+/* LCD */
+#define GPIO58_LCD_LDD_0 MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
+#define GPIO59_LCD_LDD_1 MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
+#define GPIO60_LCD_LDD_2 MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
+#define GPIO61_LCD_LDD_3 MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
+#define GPIO62_LCD_LDD_4 MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
+#define GPIO63_LCD_LDD_5 MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
+#define GPIO64_LCD_LDD_6 MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
+#define GPIO65_LCD_LDD_7 MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
+#define GPIO66_LCD_LDD_8 MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
+#define GPIO67_LCD_LDD_9 MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
+#define GPIO68_LCD_LDD_10 MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
+#define GPIO69_LCD_LDD_11 MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
+#define GPIO70_LCD_LDD_12 MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
+#define GPIO71_LCD_LDD_13 MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
+#define GPIO72_LCD_LDD_14 MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
+#define GPIO73_LCD_LDD_15 MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
+#define GPIO74_LCD_FCLK MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
+#define GPIO75_LCD_LCLK MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
+#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO */
+#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF1)
+#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF1)
+#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF1)
+
+/* SDRAM */
+#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH)
+#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH)
+#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH)
+
+/* USB */
+#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1)
+#define GPIO32_USB_VP MFP_CFG_IN(GPIO32, AF2)
+#define GPIO34_USB_VM MFP_CFG_IN(GPIO34, AF2)
+#define GPIO39_USB_VPO MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW)
+#define GPIO56_USB_VMO MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO57_USB_nOE MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH)
+
+/* ASSP */
+#define GPIO28_ASSP_BITCLK_IN MFP_CFG_IN(GPIO28, AF3)
+#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW)
+#define GPIO29_ASSP_RXD MFP_CFG_IN(GPIO29, AF3)
+#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1)
+#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO89_AC97_nRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH)
+#endif /* CONFIG_CPU_PXA26x */
+
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP \
+ GPIO58_LCD_LDD_0, \
+ GPIO59_LCD_LDD_1, \
+ GPIO60_LCD_LDD_2, \
+ GPIO61_LCD_LDD_3, \
+ GPIO62_LCD_LDD_4, \
+ GPIO63_LCD_LDD_5, \
+ GPIO64_LCD_LDD_6, \
+ GPIO65_LCD_LDD_7, \
+ GPIO66_LCD_LDD_8, \
+ GPIO67_LCD_LDD_9, \
+ GPIO68_LCD_LDD_10, \
+ GPIO69_LCD_LDD_11, \
+ GPIO70_LCD_LDD_12, \
+ GPIO71_LCD_LDD_13, \
+ GPIO72_LCD_LDD_14, \
+ GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_DSTN_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK
+
+#define GPIOxx_LCD_TFT_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK, \
+ GPIO77_LCD_BIAS
+
+#endif /* __ASM_ARCH_MFP_PXA25X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
new file mode 100644
index 00000000..ec0f0b0b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
@@ -0,0 +1,465 @@
+#ifndef __ASM_ARCH_MFP_PXA27X_H
+#define __ASM_ARCH_MFP_PXA27X_H
+
+/*
+ * NOTE: for those special-function bidirectional GPIOs, as described
+ * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input
+ * alternative is preserved, the direction is actually selected by the
+ * specific controller, and this should work in most cases.
+ */
+
+#include <mach/mfp-pxa2xx.h>
+
+/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
+ * bit is set, regardless of the GPIO configuration
+ */
+#define GPIO3_GPIO MFP_CFG_IN(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG_IN(GPIO4, AF0)
+
+/* GPIO */
+#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG_IN(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG_IN(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG_IN(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG_IN(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG_IN(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG_IN(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG_IN(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG_IN(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG_IN(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG_IN(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG_IN(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG_IN(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG_IN(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG_IN(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG_IN(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG_IN(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG_IN(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG_IN(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG_IN(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG_IN(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG_IN(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG_IN(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG_IN(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG_IN(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG_IN(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG_IN(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG_IN(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG_IN(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG_IN(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG_IN(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG_IN(GPIO120, AF0)
+
+/* Crystal and Clock Signals */
+#define GPIO9_HZ_CLK MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
+#define GPIO10_HZ_CLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
+#define GPIO11_48_MHz MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW)
+#define GPIO12_48_MHz MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW)
+#define GPIO13_CLK_EXT MFP_CFG_IN(GPIO13, AF1)
+
+/* OS Timer Signals */
+#define GPIO11_EXT_SYNC_0 MFP_CFG_IN(GPIO11, AF1)
+#define GPIO12_EXT_SYNC_1 MFP_CFG_IN(GPIO12, AF1)
+#define GPIO9_CHOUT_0 MFP_CFG_OUT(GPIO9, AF3, DRIVE_LOW)
+#define GPIO10_CHOUT_1 MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW)
+#define GPIO11_CHOUT_0 MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
+#define GPIO12_CHOUT_1 MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
+
+/* SDRAM and Static Memory I/O Signals */
+#define GPIO20_nSDCS_2 MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH)
+#define GPIO21_nSDCS_3 MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH)
+#define GPIO15_nCS_1 MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
+#define GPIO78_nCS_2 MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
+#define GPIO79_nCS_3 MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
+#define GPIO80_nCS_4 MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
+#define GPIO33_nCS_5 MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
+
+/* Miscellaneous I/O and DMA Signals */
+#define GPIO21_DVAL_0 MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH)
+#define GPIO116_DVAL_0 MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH)
+#define GPIO33_DVAL_1 MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH)
+#define GPIO96_DVAL_1 MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH)
+#define GPIO18_RDY MFP_CFG_IN(GPIO18, AF1)
+#define GPIO20_DREQ_0 MFP_CFG_IN(GPIO20, AF1)
+#define GPIO115_DREQ_0 MFP_CFG_IN(GPIO115, AF1)
+#define GPIO80_DREQ_1 MFP_CFG_IN(GPIO80, AF1)
+#define GPIO97_DREQ_1 MFP_CFG_IN(GPIO97, AF2)
+#define GPIO85_DREQ_2 MFP_CFG_IN(GPIO85, AF2)
+#define GPIO100_DREQ_2 MFP_CFG_IN(GPIO100, AF2)
+
+/* Alternate Bus Master Mode I/O Signals */
+#define GPIO20_MBREQ MFP_CFG_IN(GPIO20, AF2)
+#define GPIO80_MBREQ MFP_CFG_IN(GPIO80, AF2)
+#define GPIO96_MBREQ MFP_CFG_IN(GPIO96, AF2)
+#define GPIO115_MBREQ MFP_CFG_IN(GPIO115, AF3)
+#define GPIO21_MBGNT MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW)
+#define GPIO33_MBGNT MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW)
+#define GPIO97_MBGNT MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW)
+#define GPIO116_MBGNT MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW)
+
+/* PC CARD */
+#define GPIO15_nPCE_1 MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO85_nPCE_1 MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH)
+#define GPIO86_nPCE_1 MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH)
+#define GPIO102_nPCE_1 MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH)
+#define GPIO54_nPCE_2 MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
+#define GPIO78_nPCE_2 MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH)
+#define GPIO87_nPCE_2 MFP_CFG_IN(GPIO87, AF1)
+#define GPIO55_nPREG MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
+#define GPIO50_nPIOR MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
+#define GPIO51_nPIOW MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
+#define GPIO49_nPWE MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
+#define GPIO48_nPOE MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
+#define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1)
+#define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1)
+#define GPIO79_PSKTSEL MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH)
+#define GPIO104_PSKTSEL MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH)
+
+/* I2C */
+#define GPIO117_I2C_SCL MFP_CFG_IN(GPIO117, AF1)
+#define GPIO118_I2C_SDA MFP_CFG_IN(GPIO118, AF1)
+
+/* FFUART */
+#define GPIO9_FFUART_CTS MFP_CFG_IN(GPIO9, AF3)
+#define GPIO26_FFUART_CTS MFP_CFG_IN(GPIO26, AF3)
+#define GPIO35_FFUART_CTS MFP_CFG_IN(GPIO35, AF1)
+#define GPIO100_FFUART_CTS MFP_CFG_IN(GPIO100, AF3)
+#define GPIO10_FFUART_DCD MFP_CFG_IN(GPIO10, AF1)
+#define GPIO36_FFUART_DCD MFP_CFG_IN(GPIO36, AF1)
+#define GPIO33_FFUART_DSR MFP_CFG_IN(GPIO33, AF2)
+#define GPIO37_FFUART_DSR MFP_CFG_IN(GPIO37, AF1)
+#define GPIO38_FFUART_RI MFP_CFG_IN(GPIO38, AF1)
+#define GPIO89_FFUART_RI MFP_CFG_IN(GPIO89, AF3)
+#define GPIO19_FFUART_RXD MFP_CFG_IN(GPIO19, AF3)
+#define GPIO33_FFUART_RXD MFP_CFG_IN(GPIO33, AF1)
+#define GPIO34_FFUART_RXD MFP_CFG_IN(GPIO34, AF1)
+#define GPIO41_FFUART_RXD MFP_CFG_IN(GPIO41, AF1)
+#define GPIO53_FFUART_RXD MFP_CFG_IN(GPIO53, AF1)
+#define GPIO85_FFUART_RXD MFP_CFG_IN(GPIO85, AF1)
+#define GPIO96_FFUART_RXD MFP_CFG_IN(GPIO96, AF3)
+#define GPIO102_FFUART_RXD MFP_CFG_IN(GPIO102, AF3)
+#define GPIO16_FFUART_TXD MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH)
+#define GPIO37_FFUART_TXD MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH)
+#define GPIO39_FFUART_TXD MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_TXD MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO99_FFUART_TXD MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH)
+#define GPIO27_FFUART_RTS MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH)
+#define GPIO41_FFUART_RTS MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_RTS MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH)
+#define GPIO98_FFUART_RTS MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH)
+#define GPIO40_FFUART_DTR MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
+#define GPIO82_FFUART_DTR MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH)
+
+/* BTUART */
+#define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1)
+#define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1)
+#define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+
+/* STUART */
+#define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2)
+#define GPIO47_STUART_TXD MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
+
+/* FICP */
+#define GPIO42_FICP_RXD MFP_CFG_IN(GPIO42, AF2)
+#define GPIO46_FICP_RXD MFP_CFG_IN(GPIO46, AF1)
+#define GPIO43_FICP_TXD MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH)
+#define GPIO47_FICP_TXD MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
+
+/* PWM 0/1/2/3 */
+#define GPIO11_PWM2_OUT MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW)
+#define GPIO12_PWM3_OUT MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW)
+#define GPIO16_PWM0_OUT MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
+#define GPIO17_PWM1_OUT MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
+#define GPIO38_PWM1_OUT MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW)
+#define GPIO46_PWM2_OUT MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW)
+#define GPIO47_PWM3_OUT MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW)
+#define GPIO79_PWM2_OUT MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW)
+#define GPIO80_PWM3_OUT MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW)
+#define GPIO115_PWM1_OUT MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO31_AC97_SYNC MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
+#define GPIO94_AC97_SYNC MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW)
+#define GPIO30_AC97_SDATA_OUT MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
+#define GPIO93_AC97_SDATA_OUT MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW)
+#define GPIO45_AC97_SYSCLK MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW)
+#define GPIO89_AC97_SYSCLK MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW)
+#define GPIO98_AC97_SYSCLK MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW)
+#define GPIO95_AC97_nRESET MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW)
+#define GPIO113_AC97_nRESET MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW)
+#define GPIO28_AC97_BITCLK MFP_CFG_IN(GPIO28, AF1)
+#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
+#define GPIO116_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO116, AF2)
+#define GPIO99_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO99, AF2)
+
+/* I2S */
+#define GPIO28_I2S_BITCLK_IN MFP_CFG_IN(GPIO28, AF2)
+#define GPIO28_I2S_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
+#define GPIO29_I2S_SDATA_IN MFP_CFG_IN(GPIO29, AF2)
+#define GPIO30_I2S_SDATA_OUT MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
+#define GPIO31_I2S_SYNC MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
+#define GPIO113_I2S_SYSCLK MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)
+
+/* SSP 1 */
+#define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
+#define GPIO29_SSP1_SCLK MFP_CFG_IN(GPIO29, AF3)
+#define GPIO27_SSP1_SYSCLK MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
+#define GPIO53_SSP1_SYSCLK MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW)
+#define GPIO24_SSP1_SFRM MFP_CFG_IN(GPIO24, AF2)
+#define GPIO28_SSP1_SFRM MFP_CFG_IN(GPIO28, AF3)
+#define GPIO25_SSP1_TXD MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
+#define GPIO57_SSP1_TXD MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW)
+#define GPIO26_SSP1_RXD MFP_CFG_IN(GPIO26, AF1)
+#define GPIO27_SSP1_SCLKEN MFP_CFG_IN(GPIO27, AF2)
+
+/* SSP 2 */
+#define GPIO19_SSP2_SCLK MFP_CFG_IN(GPIO19, AF1)
+#define GPIO22_SSP2_SCLK MFP_CFG_IN(GPIO22, AF3)
+#define GPIO29_SSP2_SCLK MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW)
+#define GPIO36_SSP2_SCLK MFP_CFG_IN(GPIO36, AF2)
+#define GPIO50_SSP2_SCLK MFP_CFG_IN(GPIO50, AF3)
+#define GPIO22_SSP2_SYSCLK MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW)
+#define GPIO14_SSP2_SFRM MFP_CFG_IN(GPIO14, AF2)
+#define GPIO37_SSP2_SFRM MFP_CFG_IN(GPIO37, AF2)
+#define GPIO87_SSP2_SFRM MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW)
+#define GPIO88_SSP2_SFRM MFP_CFG_IN(GPIO88, AF3)
+#define GPIO13_SSP2_TXD MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW)
+#define GPIO38_SSP2_TXD MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW)
+#define GPIO87_SSP2_TXD MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW)
+#define GPIO89_SSP2_TXD MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW)
+#define GPIO11_SSP2_RXD MFP_CFG_IN(GPIO11, AF2)
+#define GPIO29_SSP2_RXD MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW)
+#define GPIO40_SSP2_RXD MFP_CFG_IN(GPIO40, AF1)
+#define GPIO86_SSP2_RXD MFP_CFG_IN(GPIO86, AF1)
+#define GPIO88_SSP2_RXD MFP_CFG_IN(GPIO88, AF2)
+#define GPIO22_SSP2_EXTCLK MFP_CFG_IN(GPIO22, AF1)
+#define GPIO27_SSP2_EXTCLK MFP_CFG_IN(GPIO27, AF1)
+#define GPIO22_SSP2_SCLKEN MFP_CFG_IN(GPIO22, AF2)
+#define GPIO23_SSP2_SCLKEN MFP_CFG_IN(GPIO23, AF2)
+
+/* SSP 3 */
+#define GPIO34_SSP3_SCLK MFP_CFG_IN(GPIO34, AF3)
+#define GPIO40_SSP3_SCLK MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW)
+#define GPIO52_SSP3_SCLK MFP_CFG_IN(GPIO52, AF2)
+#define GPIO84_SSP3_SCLK MFP_CFG_IN(GPIO84, AF1)
+#define GPIO45_SSP3_SYSCLK MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW)
+#define GPIO35_SSP3_SFRM MFP_CFG_IN(GPIO35, AF3)
+#define GPIO39_SSP3_SFRM MFP_CFG_IN(GPIO39, AF3)
+#define GPIO83_SSP3_SFRM MFP_CFG_IN(GPIO83, AF1)
+#define GPIO35_SSP3_TXD MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW)
+#define GPIO38_SSP3_TXD MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW)
+#define GPIO81_SSP3_TXD MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
+#define GPIO41_SSP3_RXD MFP_CFG_IN(GPIO41, AF3)
+#define GPIO82_SSP3_RXD MFP_CFG_IN(GPIO82, AF1)
+#define GPIO89_SSP3_RXD MFP_CFG_IN(GPIO89, AF1)
+
+/* MMC */
+#define GPIO32_MMC_CLK MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW)
+#define GPIO92_MMC_DAT_0 MFP_CFG_IN(GPIO92, AF1)
+#define GPIO109_MMC_DAT_1 MFP_CFG_IN(GPIO109, AF1)
+#define GPIO110_MMC_DAT_2 MFP_CFG_IN(GPIO110, AF1)
+#define GPIO111_MMC_DAT_3 MFP_CFG_IN(GPIO111, AF1)
+#define GPIO112_MMC_CMD MFP_CFG_IN(GPIO112, AF1)
+
+/* LCD */
+#define GPIO58_LCD_LDD_0 MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
+#define GPIO59_LCD_LDD_1 MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
+#define GPIO60_LCD_LDD_2 MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
+#define GPIO61_LCD_LDD_3 MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
+#define GPIO62_LCD_LDD_4 MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
+#define GPIO63_LCD_LDD_5 MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
+#define GPIO64_LCD_LDD_6 MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
+#define GPIO65_LCD_LDD_7 MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
+#define GPIO66_LCD_LDD_8 MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
+#define GPIO67_LCD_LDD_9 MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
+#define GPIO68_LCD_LDD_10 MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
+#define GPIO69_LCD_LDD_11 MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
+#define GPIO70_LCD_LDD_12 MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
+#define GPIO71_LCD_LDD_13 MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
+#define GPIO72_LCD_LDD_14 MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
+#define GPIO73_LCD_LDD_15 MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
+#define GPIO86_LCD_LDD_16 MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW)
+#define GPIO87_LCD_LDD_17 MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW)
+#define GPIO74_LCD_FCLK MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
+#define GPIO75_LCD_LCLK MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
+#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+#define GPIO14_LCD_VSYNC MFP_CFG_IN(GPIO14, AF1)
+#define GPIO19_LCD_CS MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW)
+
+/* Keypad */
+#define GPIO93_KP_DKIN_0 MFP_CFG_IN(GPIO93, AF1)
+#define GPIO94_KP_DKIN_1 MFP_CFG_IN(GPIO94, AF1)
+#define GPIO95_KP_DKIN_2 MFP_CFG_IN(GPIO95, AF1)
+#define GPIO96_KP_DKIN_3 MFP_CFG_IN(GPIO96, AF1)
+#define GPIO97_KP_DKIN_4 MFP_CFG_IN(GPIO97, AF1)
+#define GPIO98_KP_DKIN_5 MFP_CFG_IN(GPIO98, AF1)
+#define GPIO99_KP_DKIN_6 MFP_CFG_IN(GPIO99, AF1)
+#define GPIO13_KP_KDIN_7 MFP_CFG_IN(GPIO13, AF2)
+#define GPIO100_KP_MKIN_0 MFP_CFG_IN(GPIO100, AF1)
+#define GPIO101_KP_MKIN_1 MFP_CFG_IN(GPIO101, AF1)
+#define GPIO102_KP_MKIN_2 MFP_CFG_IN(GPIO102, AF1)
+#define GPIO34_KP_MKIN_3 MFP_CFG_IN(GPIO34, AF2)
+#define GPIO37_KP_MKIN_3 MFP_CFG_IN(GPIO37, AF3)
+#define GPIO97_KP_MKIN_3 MFP_CFG_IN(GPIO97, AF3)
+#define GPIO98_KP_MKIN_4 MFP_CFG_IN(GPIO98, AF3)
+#define GPIO38_KP_MKIN_4 MFP_CFG_IN(GPIO38, AF2)
+#define GPIO39_KP_MKIN_4 MFP_CFG_IN(GPIO39, AF1)
+#define GPIO16_KP_MKIN_5 MFP_CFG_IN(GPIO16, AF1)
+#define GPIO90_KP_MKIN_5 MFP_CFG_IN(GPIO90, AF1)
+#define GPIO99_KP_MKIN_5 MFP_CFG_IN(GPIO99, AF3)
+#define GPIO17_KP_MKIN_6 MFP_CFG_IN(GPIO17, AF1)
+#define GPIO91_KP_MKIN_6 MFP_CFG_IN(GPIO91, AF1)
+#define GPIO95_KP_MKIN_6 MFP_CFG_IN(GPIO95, AF3)
+#define GPIO13_KP_MKIN_7 MFP_CFG_IN(GPIO13, AF3)
+#define GPIO36_KP_MKIN_7 MFP_CFG_IN(GPIO36, AF3)
+#define GPIO103_KP_MKOUT_0 MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_1 MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_2 MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH)
+#define GPIO106_KP_MKOUT_3 MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH)
+#define GPIO107_KP_MKOUT_4 MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH)
+#define GPIO108_KP_MKOUT_5 MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH)
+#define GPIO35_KP_MKOUT_6 MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH)
+#define GPIO22_KP_MKOUT_7 MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH)
+#define GPIO40_KP_MKOUT_6 MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH)
+#define GPIO41_KP_MKOUT_7 MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH)
+#define GPIO96_KP_MKOUT_6 MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH)
+
+/* USB P3 */
+#define GPIO10_USB_P3_5 MFP_CFG_IN(GPIO10, AF3)
+#define GPIO11_USB_P3_1 MFP_CFG_IN(GPIO11, AF3)
+#define GPIO30_USB_P3_2 MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_USB_P3_6 MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+#define GPIO56_USB_P3_4 MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO86_USB_P3_5 MFP_CFG_IN(GPIO86, AF3)
+#define GPIO87_USB_P3_1 MFP_CFG_IN(GPIO87, AF3)
+#define GPIO90_USB_P3_5 MFP_CFG_IN(GPIO90, AF2)
+#define GPIO91_USB_P3_1 MFP_CFG_IN(GPIO91, AF2)
+#define GPIO113_USB_P3_3 MFP_CFG_IN(GPIO113, AF3)
+
+/* USB P2 */
+#define GPIO34_USB_P2_2 MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW)
+#define GPIO35_USB_P2_1 MFP_CFG_IN(GPIO35, AF2)
+#define GPIO36_USB_P2_4 MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW)
+#define GPIO37_USB_P2_8 MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW)
+#define GPIO38_USB_P2_3 MFP_CFG_IN(GPIO38, AF3)
+#define GPIO39_USB_P2_6 MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
+#define GPIO40_USB_P2_5 MFP_CFG_IN(GPIO40, AF3)
+#define GPIO41_USB_P2_7 MFP_CFG_IN(GPIO41, AF2)
+#define GPIO53_USB_P2_3 MFP_CFG_IN(GPIO53, AF2)
+
+/* USB Host Port 1/2 */
+#define GPIO88_USBH1_PWR MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_USBH1_PEN MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW)
+#define GPIO119_USBH2_PWR MFP_CFG_IN(GPIO119, AF1)
+#define GPIO120_USBH2_PEN MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW)
+
+/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */
+#define GPIO115_CIF_DD_3 MFP_CFG_IN(GPIO115, AF2)
+#define GPIO116_CIF_DD_2 MFP_CFG_IN(GPIO116, AF1)
+#define GPIO12_CIF_DD_7 MFP_CFG_IN(GPIO12, AF2)
+#define GPIO17_CIF_DD_6 MFP_CFG_IN(GPIO17, AF2)
+#define GPIO23_CIF_MCLK MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW)
+#define GPIO24_CIF_FV MFP_CFG_IN(GPIO24, AF1)
+#define GPIO25_CIF_LV MFP_CFG_IN(GPIO25, AF1)
+#define GPIO26_CIF_PCLK MFP_CFG_IN(GPIO26, AF2)
+#define GPIO27_CIF_DD_0 MFP_CFG_IN(GPIO27, AF3)
+#define GPIO42_CIF_MCLK MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW)
+#define GPIO43_CIF_FV MFP_CFG_IN(GPIO43, AF3)
+#define GPIO44_CIF_LV MFP_CFG_IN(GPIO44, AF3)
+#define GPIO45_CIF_PCLK MFP_CFG_IN(GPIO45, AF3)
+#define GPIO47_CIF_DD_0 MFP_CFG_IN(GPIO47, AF1)
+#define GPIO48_CIF_DD_5 MFP_CFG_IN(GPIO48, AF1)
+#define GPIO50_CIF_DD_3 MFP_CFG_IN(GPIO50, AF1)
+#define GPIO51_CIF_DD_2 MFP_CFG_IN(GPIO51, AF1)
+#define GPIO52_CIF_DD_4 MFP_CFG_IN(GPIO52, AF1)
+#define GPIO53_CIF_MCLK MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW)
+#define GPIO54_CIF_PCLK MFP_CFG_IN(GPIO54, AF3)
+#define GPIO55_CIF_DD_1 MFP_CFG_IN(GPIO55, AF1)
+#define GPIO81_CIF_DD_0 MFP_CFG_IN(GPIO81, AF2)
+#define GPIO82_CIF_DD_5 MFP_CFG_IN(GPIO82, AF3)
+#define GPIO83_CIF_DD_4 MFP_CFG_IN(GPIO83, AF3)
+#define GPIO84_CIF_FV MFP_CFG_IN(GPIO84, AF3)
+#define GPIO85_CIF_LV MFP_CFG_IN(GPIO85, AF3)
+#define GPIO90_CIF_DD_4 MFP_CFG_IN(GPIO90, AF3)
+#define GPIO91_CIF_DD_5 MFP_CFG_IN(GPIO91, AF3)
+#define GPIO93_CIF_DD_6 MFP_CFG_IN(GPIO93, AF2)
+#define GPIO94_CIF_DD_5 MFP_CFG_IN(GPIO94, AF2)
+#define GPIO95_CIF_DD_4 MFP_CFG_IN(GPIO95, AF2)
+#define GPIO98_CIF_DD_0 MFP_CFG_IN(GPIO98, AF2)
+#define GPIO103_CIF_DD_3 MFP_CFG_IN(GPIO103, AF1)
+#define GPIO104_CIF_DD_2 MFP_CFG_IN(GPIO104, AF1)
+#define GPIO105_CIF_DD_1 MFP_CFG_IN(GPIO105, AF1)
+#define GPIO106_CIF_DD_9 MFP_CFG_IN(GPIO106, AF1)
+#define GPIO107_CIF_DD_8 MFP_CFG_IN(GPIO107, AF1)
+#define GPIO108_CIF_DD_7 MFP_CFG_IN(GPIO108, AF1)
+#define GPIO114_CIF_DD_1 MFP_CFG_IN(GPIO114, AF1)
+
+/* Universal Subscriber ID Interface */
+#define GPIO114_UVS0 MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW)
+#define GPIO115_nUVS1 MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW)
+#define GPIO116_nUVS2 MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW)
+#define GPIO14_UCLK MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW)
+#define GPIO91_UCLK MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW)
+#define GPIO19_nURST MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW)
+#define GPIO90_nURST MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW)
+#define GPIO116_UDET MFP_CFG_IN(GPIO116, AF3)
+#define GPIO114_UEN MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW)
+#define GPIO115_UEN MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW)
+
+/* Mobile Scalable Link (MSL) Interface */
+#define GPIO81_BB_OB_DAT_0 MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW)
+#define GPIO48_BB_OB_DAT_1 MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW)
+#define GPIO50_BB_OB_DAT_2 MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW)
+#define GPIO51_BB_OB_DAT_3 MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW)
+#define GPIO52_BB_OB_CLK MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW)
+#define GPIO53_BB_OB_STB MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
+#define GPIO54_BB_OB_WAIT MFP_CFG_IN(GPIO54, AF2)
+#define GPIO82_BB_IB_DAT_0 MFP_CFG_IN(GPIO82, AF2)
+#define GPIO55_BB_IB_DAT_1 MFP_CFG_IN(GPIO55, AF2)
+#define GPIO56_BB_IB_DAT_2 MFP_CFG_IN(GPIO56, AF2)
+#define GPIO57_BB_IB_DAT_3 MFP_CFG_IN(GPIO57, AF2)
+#define GPIO83_BB_IB_CLK MFP_CFG_IN(GPIO83, AF2)
+#define GPIO84_BB_IB_STB MFP_CFG_IN(GPIO84, AF2)
+#define GPIO85_BB_IB_WAIT MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW)
+
+/* Memory Stick Host Controller */
+#define GPIO92_MSBS MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW)
+#define GPIO109_MSSDIO MFP_CFG_IN(GPIO109, AF2)
+#define GPIO112_nMSINS MFP_CFG_IN(GPIO112, AF2)
+#define GPIO32_MSSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+
+/* commonly used pin configurations */
+#define GPIOxx_LCD_16BPP \
+ GPIO58_LCD_LDD_0, \
+ GPIO59_LCD_LDD_1, \
+ GPIO60_LCD_LDD_2, \
+ GPIO61_LCD_LDD_3, \
+ GPIO62_LCD_LDD_4, \
+ GPIO63_LCD_LDD_5, \
+ GPIO64_LCD_LDD_6, \
+ GPIO65_LCD_LDD_7, \
+ GPIO66_LCD_LDD_8, \
+ GPIO67_LCD_LDD_9, \
+ GPIO68_LCD_LDD_10, \
+ GPIO69_LCD_LDD_11, \
+ GPIO70_LCD_LDD_12, \
+ GPIO71_LCD_LDD_13, \
+ GPIO72_LCD_LDD_14, \
+ GPIO73_LCD_LDD_15
+
+#define GPIOxx_LCD_TFT_16BPP \
+ GPIOxx_LCD_16BPP, \
+ GPIO74_LCD_FCLK, \
+ GPIO75_LCD_LCLK, \
+ GPIO76_LCD_PCLK, \
+ GPIO77_LCD_BIAS
+
+
+extern int keypad_set_wake(unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA27X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
new file mode 100644
index 00000000..c54cef25
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -0,0 +1,135 @@
+#ifndef __ASM_ARCH_MFP_PXA2XX_H
+#define __ASM_ARCH_MFP_PXA2XX_H
+
+#include <plat/mfp.h>
+
+/*
+ * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
+ *
+ * MFP_PIN(x)
+ * MFP_AFx
+ * MFP_LPM_DRIVE_{LOW, HIGH}
+ * MFP_LPM_EDGE_x
+ *
+ * other MFP_x bit definitions will be ignored
+ *
+ * and adds the below two bits specifically for pxa2xx:
+ *
+ * bit 23 - Input/Output (PXA2xx specific)
+ * bit 24 - Wakeup Enable(PXA2xx specific)
+ */
+
+#define MFP_DIR_IN (0x0 << 23)
+#define MFP_DIR_OUT (0x1 << 23)
+#define MFP_DIR_MASK (0x1 << 23)
+#define MFP_DIR(x) (((x) >> 23) & 0x1)
+
+#define MFP_LPM_CAN_WAKEUP (0x1 << 24)
+#define MFP_LPM_KEEP_OUTPUT (0x1 << 25)
+
+#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
+#define WAKEUP_ON_EDGE_FALL (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
+#define WAKEUP_ON_EDGE_BOTH (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
+
+/* specifically for enabling wakeup on keypad GPIOs */
+#define WAKEUP_ON_LEVEL_HIGH (MFP_LPM_CAN_WAKEUP)
+
+#define MFP_CFG_IN(pin, af) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN))
+
+/* NOTE: pins configured as output _must_ provide a low power state,
+ * and this state should help to minimize the power dissipation.
+ */
+#define MFP_CFG_OUT(pin, af, state) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Common configurations for pxa25x and pxa27x
+ *
+ * Note: pins configured as GPIO are always initialized to input
+ * so not to cause any side effect
+ */
+#define GPIO0_GPIO MFP_CFG_IN(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG_IN(GPIO1, AF0)
+#define GPIO9_GPIO MFP_CFG_IN(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG_IN(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG_IN(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG_IN(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG_IN(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG_IN(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG_IN(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG_IN(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG_IN(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG_IN(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG_IN(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG_IN(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG_IN(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG_IN(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG_IN(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG_IN(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG_IN(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG_IN(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG_IN(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG_IN(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG_IN(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG_IN(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG_IN(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG_IN(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG_IN(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG_IN(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG_IN(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG_IN(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG_IN(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG_IN(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG_IN(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG_IN(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG_IN(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG_IN(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG_IN(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG_IN(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG_IN(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG_IN(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG_IN(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG_IN(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG_IN(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG_IN(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG_IN(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG_IN(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG_IN(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG_IN(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG_IN(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG_IN(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG_IN(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG_IN(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG_IN(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG_IN(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG_IN(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG_IN(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG_IN(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG_IN(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG_IN(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG_IN(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG_IN(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG_IN(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG_IN(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG_IN(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG_IN(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG_IN(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG_IN(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG_IN(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG_IN(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG_IN(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG_IN(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG_IN(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG_IN(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG_IN(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG_IN(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG_IN(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG_IN(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG_IN(GPIO84, AF0)
+
+extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm);
+extern int gpio_set_wake(unsigned int gpio, unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA2XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
new file mode 100644
index 00000000..4e128707
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h
@@ -0,0 +1,575 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa300.h
+ *
+ * PXA300/PXA310 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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_MFP_PXA300_H
+#define __ASM_ARCH_MFP_PXA300_H
+
+#include <mach/mfp-pxa3xx.h>
+
+/* GPIO */
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF1)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF3)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF2)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF3)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF3)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+
+#ifdef CONFIG_CPU_PXA310
+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
+#endif
+
+/* Chip Select */
+#define GPIO1_nCS2 MFP_CFG(GPIO1, AF1)
+#define GPIO2_nCS3 MFP_CFG(GPIO2, AF1)
+
+/* AC97 */
+#define GPIO23_AC97_nACRESET MFP_CFG(GPIO23, AF1)
+#define GPIO24_AC97_SYSCLK MFP_CFG(GPIO24, AF1)
+#define GPIO29_AC97_BITCLK MFP_CFG(GPIO29, AF1)
+#define GPIO25_AC97_SDATA_IN_0 MFP_CFG(GPIO25, AF1)
+#define GPIO26_AC97_SDATA_IN_1 MFP_CFG(GPIO26, AF1)
+#define GPIO17_AC97_SDATA_IN_2 MFP_CFG(GPIO17, AF3)
+#define GPIO21_AC97_SDATA_IN_2 MFP_CFG(GPIO21, AF2)
+#define GPIO18_AC97_SDATA_IN_3 MFP_CFG(GPIO18, AF3)
+#define GPIO22_AC97_SDATA_IN_3 MFP_CFG(GPIO22, AF2)
+#define GPIO27_AC97_SDATA_OUT MFP_CFG(GPIO27, AF1)
+#define GPIO28_AC97_SYNC MFP_CFG(GPIO28, AF1)
+
+/* I2C */
+#define GPIO21_I2C_SCL MFP_CFG_LPM(GPIO21, AF1, PULL_HIGH)
+#define GPIO22_I2C_SDA MFP_CFG_LPM(GPIO22, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO39_CI_DD_0 MFP_CFG_DRV(GPIO39, AF1, DS04X)
+#define GPIO40_CI_DD_1 MFP_CFG_DRV(GPIO40, AF1, DS04X)
+#define GPIO41_CI_DD_2 MFP_CFG_DRV(GPIO41, AF1, DS04X)
+#define GPIO42_CI_DD_3 MFP_CFG_DRV(GPIO42, AF1, DS04X)
+#define GPIO43_CI_DD_4 MFP_CFG_DRV(GPIO43, AF1, DS04X)
+#define GPIO44_CI_DD_5 MFP_CFG_DRV(GPIO44, AF1, DS04X)
+#define GPIO45_CI_DD_6 MFP_CFG_DRV(GPIO45, AF1, DS04X)
+#define GPIO46_CI_DD_7 MFP_CFG_DRV(GPIO46, AF0, DS04X)
+#define GPIO47_CI_DD_8 MFP_CFG_DRV(GPIO47, AF1, DS04X)
+#define GPIO48_CI_DD_9 MFP_CFG_DRV(GPIO48, AF1, DS04X)
+#define GPIO49_CI_MCLK MFP_CFG_DRV(GPIO49, AF0, DS04X)
+#define GPIO50_CI_PCLK MFP_CFG_DRV(GPIO50, AF0, DS04X)
+#define GPIO51_CI_HSYNC MFP_CFG_DRV(GPIO51, AF0, DS04X)
+#define GPIO52_CI_VSYNC MFP_CFG_DRV(GPIO52, AF0, DS04X)
+
+/* KEYPAD */
+#define GPIO3_KP_DKIN_6 MFP_CFG_LPM(GPIO3, AF2, FLOAT)
+#define GPIO4_KP_DKIN_7 MFP_CFG_LPM(GPIO4, AF2, FLOAT)
+#define GPIO16_KP_DKIN_6 MFP_CFG_LPM(GPIO16, AF6, FLOAT)
+#define GPIO83_KP_DKIN_2 MFP_CFG_LPM(GPIO83, AF5, FLOAT)
+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF5, FLOAT)
+#define GPIO85_KP_DKIN_0 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
+#define GPIO86_KP_DKIN_1 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
+#define GPIO87_KP_DKIN_2 MFP_CFG_LPM(GPIO87, AF3, FLOAT)
+#define GPIO88_KP_DKIN_3 MFP_CFG_LPM(GPIO88, AF3, FLOAT)
+#define GPIO89_KP_DKIN_3 MFP_CFG_LPM(GPIO89, AF3, FLOAT)
+#define GPIO107_KP_DKIN_0 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_1 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_2 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_3 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_4 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_5 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+#define GPIO113_KP_DKIN_6 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_7 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_0 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_1 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_2 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_3 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_4 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_5 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF5, FLOAT)
+#define GPIO0_2_KP_DKIN_0 MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+#define GPIO1_2_KP_DKIN_1 MFP_CFG_LPM(GPIO1_2, AF2, FLOAT)
+#define GPIO2_2_KP_DKIN_6 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_7 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_1 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+#define GPIO5_2_KP_DKIN_0 MFP_CFG_LPM(GPIO5_2, AF2, FLOAT)
+
+#define GPIO5_KP_MKIN_0 MFP_CFG_LPM(GPIO5, AF2, FLOAT)
+#define GPIO6_KP_MKIN_1 MFP_CFG_LPM(GPIO6, AF2, FLOAT)
+#define GPIO9_KP_MKIN_6 MFP_CFG_LPM(GPIO9, AF3, FLOAT)
+#define GPIO10_KP_MKIN_7 MFP_CFG_LPM(GPIO10, AF3, FLOAT)
+#define GPIO70_KP_MKIN_6 MFP_CFG_LPM(GPIO70, AF3, FLOAT)
+#define GPIO71_KP_MKIN_7 MFP_CFG_LPM(GPIO71, AF3, FLOAT)
+#define GPIO100_KP_MKIN_6 MFP_CFG_LPM(GPIO100, AF7, FLOAT)
+#define GPIO101_KP_MKIN_7 MFP_CFG_LPM(GPIO101, AF7, FLOAT)
+#define GPIO112_KP_MKIN_6 MFP_CFG_LPM(GPIO112, AF4, FLOAT)
+#define GPIO113_KP_MKIN_7 MFP_CFG_LPM(GPIO113, AF4, FLOAT)
+#define GPIO115_KP_MKIN_0 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_1 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_2 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_3 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_4 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_5 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+#define GPIO125_KP_MKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO2_2_KP_MKIN_6 MFP_CFG_LPM(GPIO2_2, AF1, FLOAT)
+#define GPIO3_2_KP_MKIN_7 MFP_CFG_LPM(GPIO3_2, AF1, FLOAT)
+
+#define GPIO7_KP_MKOUT_5 MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5 MFP_CFG_LPM(GPIO11, AF3, DRIVE_HIGH)
+#define GPIO12_KP_MKOUT_6 MFP_CFG_LPM(GPIO12, AF3, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_7 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
+#define GPIO19_KP_MKOUT_4 MFP_CFG_LPM(GPIO19, AF3, DRIVE_HIGH)
+#define GPIO20_KP_MKOUT_5 MFP_CFG_LPM(GPIO20, AF3, DRIVE_HIGH)
+#define GPIO38_KP_MKOUT_5 MFP_CFG_LPM(GPIO38, AF5, DRIVE_HIGH)
+#define GPIO53_KP_MKOUT_6 MFP_CFG_LPM(GPIO53, AF5, DRIVE_HIGH)
+#define GPIO78_KP_MKOUT_7 MFP_CFG_LPM(GPIO78, AF5, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_0 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_1 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
+#define GPIO87_KP_MKOUT_2 MFP_CFG_LPM(GPIO87, AF2, DRIVE_HIGH)
+#define GPIO88_KP_MKOUT_3 MFP_CFG_LPM(GPIO88, AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_6 MFP_CFG_LPM(GPIO104, AF5, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_7 MFP_CFG_LPM(GPIO105, AF5, DRIVE_HIGH)
+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_7 MFP_CFG_LPM(GPIO126, AF4, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_6 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+#define GPIO4_2_KP_MKOUT_5 MFP_CFG_LPM(GPIO4_2, AF1, DRIVE_HIGH)
+#define GPIO6_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO6_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO54_LCD_LDD_0 MFP_CFG_DRV(GPIO54, AF1, DS01X)
+#define GPIO55_LCD_LDD_1 MFP_CFG_DRV(GPIO55, AF1, DS01X)
+#define GPIO56_LCD_LDD_2 MFP_CFG_DRV(GPIO56, AF1, DS01X)
+#define GPIO57_LCD_LDD_3 MFP_CFG_DRV(GPIO57, AF1, DS01X)
+#define GPIO58_LCD_LDD_4 MFP_CFG_DRV(GPIO58, AF1, DS01X)
+#define GPIO59_LCD_LDD_5 MFP_CFG_DRV(GPIO59, AF1, DS01X)
+#define GPIO60_LCD_LDD_6 MFP_CFG_DRV(GPIO60, AF1, DS01X)
+#define GPIO61_LCD_LDD_7 MFP_CFG_DRV(GPIO61, AF1, DS01X)
+#define GPIO62_LCD_LDD_8 MFP_CFG_DRV(GPIO62, AF1, DS01X)
+#define GPIO63_LCD_LDD_9 MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_10 MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_11 MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_12 MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_13 MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_14 MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_15 MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_16 MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_17 MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO62_LCD_CS_N MFP_CFG_DRV(GPIO62, AF2, DS01X)
+#define GPIO72_LCD_FCLK MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_LCLK MFP_CFG_DRV(GPIO73, AF1, DS01X)
+#define GPIO74_LCD_PCLK MFP_CFG_DRV(GPIO74, AF1, DS02X)
+#define GPIO75_LCD_BIAS MFP_CFG_DRV(GPIO75, AF1, DS01X)
+#define GPIO76_LCD_VSYNC MFP_CFG_DRV(GPIO76, AF2, DS01X)
+
+#define GPIO15_LCD_CS_N MFP_CFG_DRV(GPIO15, AF2, DS01X)
+#define GPIO127_LCD_CS_N MFP_CFG_DRV(GPIO127, AF1, DS01X)
+#define GPIO63_LCD_VSYNC MFP_CFG_DRV(GPIO63, AF2, DS01X)
+
+/* Mini-LCD */
+#define GPIO72_MLCD_FCLK MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_LCLK MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO54_MLCD_LDD_0 MFP_CFG_DRV(GPIO54, AF7, DS08X)
+#define GPIO55_MLCD_LDD_1 MFP_CFG_DRV(GPIO55, AF7, DS08X)
+#define GPIO56_MLCD_LDD_2 MFP_CFG_DRV(GPIO56, AF7, DS08X)
+#define GPIO57_MLCD_LDD_3 MFP_CFG_DRV(GPIO57, AF7, DS08X)
+#define GPIO58_MLCD_LDD_4 MFP_CFG_DRV(GPIO58, AF7, DS08X)
+#define GPIO59_MLCD_LDD_5 MFP_CFG_DRV(GPIO59, AF7, DS08X)
+#define GPIO60_MLCD_LDD_6 MFP_CFG_DRV(GPIO60, AF7, DS08X)
+#define GPIO61_MLCD_LDD_7 MFP_CFG_DRV(GPIO61, AF7, DS08X)
+#define GPIO62_MLCD_LDD_8 MFP_CFG_DRV(GPIO62, AF7, DS08X)
+#define GPIO63_MLCD_LDD_9 MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_LDD_10 MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_LDD_11 MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_LDD_12 MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_LDD_13 MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_LDD_14 MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_LDD_15 MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO74_MLCD_PCLK MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO75_MLCD_BIAS MFP_CFG_DRV(GPIO75, AF2, DS08X)
+
+/* MMC1 */
+#define GPIO7_MMC1_CLK MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_CMD MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
+#define GPIO14_MMC1_CMD MFP_CFG_LPM(GPIO14, AF5, DRIVE_HIGH)
+#define GPIO15_MMC1_CMD MFP_CFG_LPM(GPIO15, AF5, DRIVE_HIGH)
+#define GPIO3_MMC1_DAT0 MFP_CFG_LPM(GPIO3, AF4, DRIVE_HIGH)
+#define GPIO4_MMC1_DAT1 MFP_CFG_LPM(GPIO4, AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT2 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT3 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
+
+/* MMC2 */
+#define GPIO9_MMC2_DAT0 MFP_CFG_LPM(GPIO9, AF4, PULL_HIGH)
+#define GPIO10_MMC2_DAT1 MFP_CFG_LPM(GPIO10, AF4, PULL_HIGH)
+#define GPIO11_MMC2_DAT2 MFP_CFG_LPM(GPIO11, AF4, PULL_HIGH)
+#define GPIO12_MMC2_DAT3 MFP_CFG_LPM(GPIO12, AF4, PULL_HIGH)
+#define GPIO13_MMC2_CLK MFP_CFG_LPM(GPIO13, AF4, PULL_HIGH)
+#define GPIO14_MMC2_CMD MFP_CFG_LPM(GPIO14, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT0 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT1 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+#define GPIO79_MMC2_DAT2 MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_DAT3 MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+#define GPIO81_MMC2_CLK MFP_CFG_LPM(GPIO81, AF4, PULL_HIGH)
+#define GPIO82_MMC2_CMD MFP_CFG_LPM(GPIO82, AF4, PULL_HIGH)
+
+/* SSP1 */
+#define GPIO89_SSP1_EXTCLK MFP_CFG(GPIO89, AF1)
+#define GPIO90_SSP1_SYSCLK MFP_CFG(GPIO90, AF1)
+#define GPIO15_SSP1_SCLK MFP_CFG(GPIO15, AF6)
+#define GPIO16_SSP1_FRM MFP_CFG(GPIO16, AF2)
+#define GPIO33_SSP1_SCLK MFP_CFG(GPIO33, AF5)
+#define GPIO34_SSP1_FRM MFP_CFG(GPIO34, AF5)
+#define GPIO85_SSP1_SCLK MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_FRM MFP_CFG(GPIO86, AF1)
+#define GPIO18_SSP1_TXD MFP_CFG(GPIO18, AF7)
+#define GPIO18_SSP1_RXD MFP_CFG(GPIO18, AF2)
+#define GPIO20_SSP1_TXD MFP_CFG(GPIO20, AF2)
+#define GPIO20_SSP1_RXD MFP_CFG(GPIO20, AF7)
+#define GPIO35_SSP1_TXD MFP_CFG(GPIO35, AF5)
+#define GPIO35_SSP1_RXD MFP_CFG(GPIO35, AF4)
+#define GPIO36_SSP1_TXD MFP_CFG(GPIO36, AF5)
+#define GPIO36_SSP1_RXD MFP_CFG(GPIO36, AF6)
+#define GPIO87_SSP1_TXD MFP_CFG(GPIO87, AF1)
+#define GPIO87_SSP1_RXD MFP_CFG(GPIO87, AF6)
+#define GPIO88_SSP1_TXD MFP_CFG(GPIO88, AF6)
+#define GPIO88_SSP1_RXD MFP_CFG(GPIO88, AF1)
+
+/* SSP2 */
+#define GPIO29_SSP2_EXTCLK MFP_CFG(GPIO29, AF2)
+#define GPIO23_SSP2_SCLK MFP_CFG(GPIO23, AF2)
+#define GPIO17_SSP2_FRM MFP_CFG(GPIO17, AF2)
+#define GPIO25_SSP2_SCLK MFP_CFG(GPIO25, AF2)
+#define GPIO26_SSP2_FRM MFP_CFG(GPIO26, AF2)
+#define GPIO33_SSP2_SCLK MFP_CFG(GPIO33, AF6)
+#define GPIO34_SSP2_FRM MFP_CFG(GPIO34, AF6)
+#define GPIO64_SSP2_SCLK MFP_CFG(GPIO64, AF2)
+#define GPIO65_SSP2_FRM MFP_CFG(GPIO65, AF2)
+#define GPIO19_SSP2_TXD MFP_CFG(GPIO19, AF2)
+#define GPIO19_SSP2_RXD MFP_CFG(GPIO19, AF7)
+#define GPIO24_SSP2_TXD MFP_CFG(GPIO24, AF5)
+#define GPIO24_SSP2_RXD MFP_CFG(GPIO24, AF4)
+#define GPIO27_SSP2_TXD MFP_CFG(GPIO27, AF2)
+#define GPIO27_SSP2_RXD MFP_CFG(GPIO27, AF5)
+#define GPIO28_SSP2_TXD MFP_CFG(GPIO28, AF5)
+#define GPIO28_SSP2_RXD MFP_CFG(GPIO28, AF2)
+#define GPIO35_SSP2_TXD MFP_CFG(GPIO35, AF7)
+#define GPIO35_SSP2_RXD MFP_CFG(GPIO35, AF6)
+#define GPIO66_SSP2_TXD MFP_CFG(GPIO66, AF4)
+#define GPIO66_SSP2_RXD MFP_CFG(GPIO66, AF2)
+#define GPIO67_SSP2_TXD MFP_CFG(GPIO67, AF2)
+#define GPIO67_SSP2_RXD MFP_CFG(GPIO67, AF4)
+#define GPIO36_SSP2_TXD MFP_CFG(GPIO36, AF7)
+
+/* SSP3 */
+#define GPIO69_SSP3_FRM MFP_CFG_X(GPIO69, AF2, DS08X, DRIVE_LOW)
+#define GPIO68_SSP3_SCLK MFP_CFG_X(GPIO68, AF2, DS08X, FLOAT)
+#define GPIO92_SSP3_FRM MFP_CFG_X(GPIO92, AF1, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_SCLK MFP_CFG_X(GPIO91, AF1, DS08X, FLOAT)
+#define GPIO70_SSP3_TXD MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO70_SSP3_RXD MFP_CFG_X(GPIO70, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF5, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF2, DS08X, FLOAT)
+#define GPIO93_SSP3_TXD MFP_CFG_X(GPIO93, AF1, DS08X, DRIVE_LOW)
+#define GPIO93_SSP3_RXD MFP_CFG_X(GPIO93, AF5, DS08X, FLOAT)
+#define GPIO94_SSP3_TXD MFP_CFG_X(GPIO94, AF5, DS08X, DRIVE_LOW)
+#define GPIO94_SSP3_RXD MFP_CFG_X(GPIO94, AF1, DS08X, FLOAT)
+
+/* SSP4 */
+#define GPIO95_SSP4_SCLK MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_FRM MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO97_SSP4_TXD MFP_CFG_LPM(GPIO97, AF1, PULL_HIGH)
+#define GPIO97_SSP4_RXD MFP_CFG_LPM(GPIO97, AF5, PULL_HIGH)
+#define GPIO98_SSP4_TXD MFP_CFG_LPM(GPIO98, AF5, PULL_HIGH)
+#define GPIO98_SSP4_RXD MFP_CFG_LPM(GPIO98, AF1, PULL_HIGH)
+
+/* UART1 */
+#define GPIO32_UART1_CTS MFP_CFG_LPM(GPIO32, AF2, FLOAT)
+#define GPIO37_UART1_CTS MFP_CFG_LPM(GPIO37, AF4, FLOAT)
+#define GPIO79_UART1_CTS MFP_CFG_LPM(GPIO79, AF1, FLOAT)
+#define GPIO84_UART1_CTS MFP_CFG_LPM(GPIO84, AF3, FLOAT)
+#define GPIO101_UART1_CTS MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO106_UART1_CTS MFP_CFG_LPM(GPIO106, AF6, FLOAT)
+
+#define GPIO32_UART1_RTS MFP_CFG_LPM(GPIO32, AF4, FLOAT)
+#define GPIO37_UART1_RTS MFP_CFG_LPM(GPIO37, AF2, FLOAT)
+#define GPIO79_UART1_RTS MFP_CFG_LPM(GPIO79, AF3, FLOAT)
+#define GPIO84_UART1_RTS MFP_CFG_LPM(GPIO84, AF1, FLOAT)
+#define GPIO101_UART1_RTS MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO106_UART1_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+
+#define GPIO34_UART1_DSR MFP_CFG_LPM(GPIO34, AF2, FLOAT)
+#define GPIO36_UART1_DSR MFP_CFG_LPM(GPIO36, AF4, FLOAT)
+#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF1, FLOAT)
+#define GPIO83_UART1_DSR MFP_CFG_LPM(GPIO83, AF3, FLOAT)
+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO105_UART1_DSR MFP_CFG_LPM(GPIO105, AF6, FLOAT)
+
+#define GPIO34_UART1_DTR MFP_CFG_LPM(GPIO34, AF4, FLOAT)
+#define GPIO36_UART1_DTR MFP_CFG_LPM(GPIO36, AF2, FLOAT)
+#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF3, FLOAT)
+#define GPIO83_UART1_DTR MFP_CFG_LPM(GPIO83, AF1, FLOAT)
+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO105_UART1_DTR MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+
+#define GPIO35_UART1_RI MFP_CFG_LPM(GPIO35, AF2, FLOAT)
+#define GPIO82_UART1_RI MFP_CFG_LPM(GPIO82, AF1, FLOAT)
+#define GPIO104_UART1_RI MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+
+#define GPIO33_UART1_DCD MFP_CFG_LPM(GPIO33, AF2, FLOAT)
+#define GPIO80_UART1_DCD MFP_CFG_LPM(GPIO80, AF1, FLOAT)
+#define GPIO102_UART1_DCD MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+#define GPIO30_UART1_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
+#define GPIO31_UART1_RXD MFP_CFG_LPM(GPIO31, AF4, FLOAT)
+#define GPIO77_UART1_RXD MFP_CFG_LPM(GPIO77, AF1, FLOAT)
+#define GPIO78_UART1_RXD MFP_CFG_LPM(GPIO78, AF3, FLOAT)
+#define GPIO99_UART1_RXD MFP_CFG_LPM(GPIO99, AF1, FLOAT)
+#define GPIO100_UART1_RXD MFP_CFG_LPM(GPIO100, AF6, FLOAT)
+#define GPIO102_UART1_RXD MFP_CFG_LPM(GPIO102, AF6, FLOAT)
+#define GPIO104_UART1_RXD MFP_CFG_LPM(GPIO104, AF4, FLOAT)
+
+#define GPIO30_UART1_TXD MFP_CFG_LPM(GPIO30, AF4, FLOAT)
+#define GPIO31_UART1_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
+#define GPIO77_UART1_TXD MFP_CFG_LPM(GPIO77, AF3, FLOAT)
+#define GPIO78_UART1_TXD MFP_CFG_LPM(GPIO78, AF1, FLOAT)
+#define GPIO99_UART1_TXD MFP_CFG_LPM(GPIO99, AF6, FLOAT)
+#define GPIO100_UART1_TXD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO102_UART1_TXD MFP_CFG_LPM(GPIO102, AF4, FLOAT)
+
+/* UART2 */
+#define GPIO15_UART2_CTS MFP_CFG_LPM(GPIO15, AF3, FLOAT)
+#define GPIO16_UART2_CTS MFP_CFG_LPM(GPIO16, AF5, FLOAT)
+#define GPIO111_UART2_CTS MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO114_UART2_CTS MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+
+#define GPIO15_UART2_RTS MFP_CFG_LPM(GPIO15, AF4, FLOAT)
+#define GPIO16_UART2_RTS MFP_CFG_LPM(GPIO16, AF4, FLOAT)
+#define GPIO114_UART2_RTS MFP_CFG_LPM(GPIO114, AF3, FLOAT)
+#define GPIO111_UART2_RTS MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+#define GPIO18_UART2_RXD MFP_CFG_LPM(GPIO18, AF5, FLOAT)
+#define GPIO19_UART2_RXD MFP_CFG_LPM(GPIO19, AF4, FLOAT)
+#define GPIO112_UART2_RXD MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO113_UART2_RXD MFP_CFG_LPM(GPIO113, AF3, FLOAT)
+
+#define GPIO18_UART2_TXD MFP_CFG_LPM(GPIO18, AF4, FLOAT)
+#define GPIO19_UART2_TXD MFP_CFG_LPM(GPIO19, AF5, FLOAT)
+#define GPIO112_UART2_TXD MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO113_UART2_TXD MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO91_UART3_CTS MFP_CFG_LPM(GPIO91, AF2, FLOAT)
+#define GPIO92_UART3_CTS MFP_CFG_LPM(GPIO92, AF4, FLOAT)
+#define GPIO107_UART3_CTS MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_CTS MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+#define GPIO91_UART3_RTS MFP_CFG_LPM(GPIO91, AF4, FLOAT)
+#define GPIO92_UART3_RTS MFP_CFG_LPM(GPIO92, AF2, FLOAT)
+#define GPIO107_UART3_RTS MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO108_UART3_RTS MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+
+#define GPIO7_UART3_RXD MFP_CFG_LPM(GPIO7, AF2, FLOAT)
+#define GPIO8_UART3_RXD MFP_CFG_LPM(GPIO8, AF6, FLOAT)
+#define GPIO93_UART3_RXD MFP_CFG_LPM(GPIO93, AF4, FLOAT)
+#define GPIO94_UART3_RXD MFP_CFG_LPM(GPIO94, AF2, FLOAT)
+#define GPIO109_UART3_RXD MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO110_UART3_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+
+#define GPIO7_UART3_TXD MFP_CFG_LPM(GPIO7, AF6, FLOAT)
+#define GPIO8_UART3_TXD MFP_CFG_LPM(GPIO8, AF2, FLOAT)
+#define GPIO93_UART3_TXD MFP_CFG_LPM(GPIO93, AF2, FLOAT)
+#define GPIO94_UART3_TXD MFP_CFG_LPM(GPIO94, AF4, FLOAT)
+#define GPIO109_UART3_TXD MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO110_UART3_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+
+/* USB Host */
+#define GPIO0_2_USBH_PEN MFP_CFG(GPIO0_2, AF1)
+#define GPIO1_2_USBH_PWR MFP_CFG(GPIO1_2, AF1)
+
+/* USB P3 */
+#define GPIO77_USB_P3_1 MFP_CFG(GPIO77, AF2)
+#define GPIO78_USB_P3_2 MFP_CFG(GPIO78, AF2)
+#define GPIO79_USB_P3_3 MFP_CFG(GPIO79, AF2)
+#define GPIO80_USB_P3_4 MFP_CFG(GPIO80, AF2)
+#define GPIO81_USB_P3_5 MFP_CFG(GPIO81, AF2)
+#define GPIO82_USB_P3_6 MFP_CFG(GPIO82, AF2)
+
+/* PWM */
+#define GPIO17_PWM0_OUT MFP_CFG(GPIO17, AF1)
+#define GPIO18_PWM1_OUT MFP_CFG(GPIO18, AF1)
+#define GPIO19_PWM2_OUT MFP_CFG(GPIO19, AF1)
+#define GPIO20_PWM3_OUT MFP_CFG(GPIO20, AF1)
+
+/* CIR */
+#define GPIO8_CIR_OUT MFP_CFG(GPIO8, AF5)
+#define GPIO16_CIR_OUT MFP_CFG(GPIO16, AF3)
+
+#define GPIO20_OW_DQ_IN MFP_CFG(GPIO20, AF5)
+#define GPIO126_OW_DQ MFP_CFG(GPIO126, AF2)
+
+#define GPIO0_DF_RDY MFP_CFG(GPIO0, AF1)
+#define GPIO7_CLK_BYPASS_XSC MFP_CFG(GPIO7, AF7)
+#define GPIO17_EXT_SYNC_MVT_0 MFP_CFG(GPIO17, AF6)
+#define GPIO18_EXT_SYNC_MVT_1 MFP_CFG(GPIO18, AF6)
+#define GPIO19_OST_CHOUT_MVT_0 MFP_CFG(GPIO19, AF6)
+#define GPIO20_OST_CHOUT_MVT_1 MFP_CFG(GPIO20, AF6)
+#define GPIO49_48M_CLK MFP_CFG(GPIO49, AF2)
+#define GPIO126_EXT_CLK MFP_CFG(GPIO126, AF3)
+#define GPIO127_CLK_BYPASS_GB MFP_CFG(GPIO127, AF7)
+#define GPIO71_EXT_MATCH_MVT MFP_CFG(GPIO71, AF6)
+
+#define GPIO3_uIO_IN MFP_CFG(GPIO3, AF1)
+
+#define GPIO4_uSIM_CARD_STATE MFP_CFG(GPIO4, AF1)
+#define GPIO5_uSIM_uCLK MFP_CFG(GPIO5, AF1)
+#define GPIO6_uSIM_uRST MFP_CFG(GPIO6, AF1)
+#define GPIO16_uSIM_UVS_0 MFP_CFG(GPIO16, AF1)
+
+#define GPIO9_SCIO MFP_CFG(GPIO9, AF1)
+#define GPIO20_RTC_MVT MFP_CFG(GPIO20, AF4)
+#define GPIO126_RTC_MVT MFP_CFG(GPIO126, AF1)
+
+/*
+ * PXA300 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA300
+#define GPIO99_USB_P2_2 MFP_CFG(GPIO99, AF2)
+#define GPIO99_USB_P2_5 MFP_CFG(GPIO99, AF3)
+#define GPIO99_USB_P2_6 MFP_CFG(GPIO99, AF4)
+#define GPIO100_USB_P2_2 MFP_CFG(GPIO100, AF4)
+#define GPIO100_USB_P2_5 MFP_CFG(GPIO100, AF5)
+#define GPIO101_USB_P2_1 MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_4 MFP_CFG(GPIO102, AF2)
+#define GPIO104_USB_P2_3 MFP_CFG(GPIO104, AF2)
+#define GPIO105_USB_P2_5 MFP_CFG(GPIO105, AF2)
+#define GPIO100_USB_P2_6 MFP_CFG(GPIO100, AF2)
+#define GPIO106_USB_P2_7 MFP_CFG(GPIO106, AF2)
+#define GPIO103_USB_P2_8 MFP_CFG(GPIO103, AF2)
+
+/* U2D UTMI */
+#define GPIO38_UTM_CLK MFP_CFG(GPIO38, AF1)
+#define GPIO26_U2D_RXERROR MFP_CFG(GPIO26, AF3)
+#define GPIO50_U2D_RXERROR MFP_CFG(GPIO50, AF1)
+#define GPIO89_U2D_RXERROR MFP_CFG(GPIO89, AF5)
+#define GPIO24_UTM_RXVALID MFP_CFG(GPIO24, AF3)
+#define GPIO48_UTM_RXVALID MFP_CFG(GPIO48, AF2)
+#define GPIO87_UTM_RXVALID MFP_CFG(GPIO87, AF5)
+#define GPIO25_UTM_RXACTIVE MFP_CFG(GPIO25, AF3)
+#define GPIO47_UTM_RXACTIVE MFP_CFG(GPIO47, AF2)
+#define GPIO49_UTM_RXACTIVE MFP_CFG(GPIO49, AF1)
+#define GPIO88_UTM_RXACTIVE MFP_CFG(GPIO88, AF5)
+#define GPIO53_UTM_TXREADY MFP_CFG(GPIO53, AF1)
+#define GPIO67_UTM_LINESTATE_0 MFP_CFG(GPIO67, AF3)
+#define GPIO92_UTM_LINESTATE_0 MFP_CFG(GPIO92, AF3)
+#define GPIO104_UTM_LINESTATE_0 MFP_CFG(GPIO104, AF3)
+#define GPIO109_UTM_LINESTATE_0 MFP_CFG(GPIO109, AF4)
+#define GPIO68_UTM_LINESTATE_1 MFP_CFG(GPIO68, AF3)
+#define GPIO93_UTM_LINESTATE_1 MFP_CFG(GPIO93, AF3)
+#define GPIO105_UTM_LINESTATE_1 MFP_CFG(GPIO105, AF3)
+#define GPIO27_U2D_OPMODE_0 MFP_CFG(GPIO27, AF4)
+#define GPIO51_U2D_OPMODE_0 MFP_CFG(GPIO51, AF2)
+#define GPIO90_U2D_OPMODE_0 MFP_CFG(GPIO90, AF7)
+#define GPIO28_U2D_OPMODE_1 MFP_CFG(GPIO28, AF4)
+#define GPIO52_U2D_OPMODE_1 MFP_CFG(GPIO52, AF2)
+#define GPIO106_U2D_OPMODE_1 MFP_CFG(GPIO106, AF3)
+#define GPIO110_U2D_OPMODE_1 MFP_CFG(GPIO110, AF5)
+#define GPIO76_U2D_RESET MFP_CFG(GPIO76, AF1)
+#define GPIO95_U2D_RESET MFP_CFG(GPIO95, AF2)
+#define GPIO100_U2D_RESET MFP_CFG(GPIO100, AF3)
+#define GPIO66_U2D_SUSPEND MFP_CFG(GPIO66, AF3)
+#define GPIO98_U2D_SUSPEND MFP_CFG(GPIO98, AF2)
+#define GPIO103_U2D_SUSPEND MFP_CFG(GPIO103, AF3)
+#define GPIO65_U2D_TERM_SEL MFP_CFG(GPIO65, AF5)
+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF3)
+#define GPIO102_U2D_TERM_SEL MFP_CFG(GPIO102, AF5)
+#define GPIO29_U2D_TXVALID MFP_CFG(GPIO29, AF3)
+#define GPIO52_U2D_TXVALID MFP_CFG(GPIO52, AF4)
+#define GPIO69_U2D_TXVALID MFP_CFG(GPIO69, AF3)
+#define GPIO85_U2D_TXVALID MFP_CFG(GPIO85, AF7)
+#define GPIO64_U2D_XCVR_SEL MFP_CFG(GPIO64, AF5)
+#define GPIO96_U2D_XCVR_SEL MFP_CFG(GPIO96, AF3)
+#define GPIO101_U2D_XCVR_SEL MFP_CFG(GPIO101, AF5)
+#define GPIO30_UTM_PHYDATA_0 MFP_CFG(GPIO30, AF3)
+#define GPIO31_UTM_PHYDATA_1 MFP_CFG(GPIO31, AF3)
+#define GPIO32_UTM_PHYDATA_2 MFP_CFG(GPIO32, AF3)
+#define GPIO33_UTM_PHYDATA_3 MFP_CFG(GPIO33, AF3)
+#define GPIO34_UTM_PHYDATA_4 MFP_CFG(GPIO34, AF3)
+#define GPIO35_UTM_PHYDATA_5 MFP_CFG(GPIO35, AF3)
+#define GPIO36_UTM_PHYDATA_6 MFP_CFG(GPIO36, AF3)
+#define GPIO37_UTM_PHYDATA_7 MFP_CFG(GPIO37, AF3)
+#define GPIO39_UTM_PHYDATA_0 MFP_CFG(GPIO39, AF3)
+#define GPIO40_UTM_PHYDATA_1 MFP_CFG(GPIO40, AF3)
+#define GPIO41_UTM_PHYDATA_2 MFP_CFG(GPIO41, AF3)
+#define GPIO42_UTM_PHYDATA_3 MFP_CFG(GPIO42, AF3)
+#define GPIO43_UTM_PHYDATA_4 MFP_CFG(GPIO43, AF3)
+#define GPIO44_UTM_PHYDATA_5 MFP_CFG(GPIO44, AF3)
+#define GPIO45_UTM_PHYDATA_6 MFP_CFG(GPIO45, AF3)
+#define GPIO46_UTM_PHYDATA_7 MFP_CFG(GPIO46, AF3)
+#endif /* CONFIG_CPU_PXA300 */
+
+/*
+ * PXA310 specific MFP configurations
+ */
+#ifdef CONFIG_CPU_PXA310
+/* USB P2 */
+#define GPIO36_USB_P2_1 MFP_CFG(GPIO36, AF1)
+#define GPIO30_USB_P2_2 MFP_CFG(GPIO30, AF1)
+#define GPIO35_USB_P2_3 MFP_CFG(GPIO35, AF1)
+#define GPIO32_USB_P2_4 MFP_CFG(GPIO32, AF1)
+#define GPIO34_USB_P2_5 MFP_CFG(GPIO34, AF1)
+#define GPIO31_USB_P2_6 MFP_CFG(GPIO31, AF1)
+
+/* MMC1 */
+#define GPIO24_MMC1_CMD MFP_CFG(GPIO24, AF3)
+#define GPIO29_MMC1_DAT0 MFP_CFG(GPIO29, AF3)
+
+/* MMC3 */
+#define GPIO103_MMC3_CLK MFP_CFG(GPIO103, AF2)
+#define GPIO105_MMC3_CMD MFP_CFG(GPIO105, AF2)
+#define GPIO11_2_MMC3_CLK MFP_CFG(GPIO11_2, AF1)
+#define GPIO12_2_MMC3_CMD MFP_CFG(GPIO12_2, AF1)
+#define GPIO7_2_MMC3_DAT0 MFP_CFG(GPIO7_2, AF1)
+#define GPIO8_2_MMC3_DAT1 MFP_CFG(GPIO8_2, AF1)
+#define GPIO9_2_MMC3_DAT2 MFP_CFG(GPIO9_2, AF1)
+#define GPIO10_2_MMC3_DAT3 MFP_CFG(GPIO10_2, AF1)
+
+/* ULPI */
+#define GPIO38_ULPI_CLK MFP_CFG(GPIO38, AF1)
+#define GPIO30_ULPI_DATA_OUT_0 MFP_CFG(GPIO30, AF3)
+#define GPIO31_ULPI_DATA_OUT_1 MFP_CFG(GPIO31, AF3)
+#define GPIO32_ULPI_DATA_OUT_2 MFP_CFG(GPIO32, AF3)
+#define GPIO33_ULPI_DATA_OUT_3 MFP_CFG(GPIO33, AF3)
+#define GPIO34_ULPI_DATA_OUT_4 MFP_CFG(GPIO34, AF3)
+#define GPIO35_ULPI_DATA_OUT_5 MFP_CFG(GPIO35, AF3)
+#define GPIO36_ULPI_DATA_OUT_6 MFP_CFG(GPIO36, AF3)
+#define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3)
+#define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1)
+
+#define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, AF0, DS01X)
+#define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, AF0, DS01X)
+#define ULPI_STP MFP_CFG_DRV(ULPI_STP, AF0, DS01X)
+#endif /* CONFIG_CPU_PXA310 */
+
+#endif /* __ASM_ARCH_MFP_PXA300_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa320.h b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
new file mode 100644
index 00000000..3ce4682e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa320.h
@@ -0,0 +1,461 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa320.h
+ *
+ * PXA320 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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_MFP_PXA320_H
+#define __ASM_ARCH_MFP_PXA320_H
+
+#include <mach/mfp-pxa3xx.h>
+
+/* GPIO */
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+
+#define GPIO7_2_GPIO MFP_CFG(GPIO7_2, AF0)
+#define GPIO8_2_GPIO MFP_CFG(GPIO8_2, AF0)
+#define GPIO9_2_GPIO MFP_CFG(GPIO9_2, AF0)
+#define GPIO10_2_GPIO MFP_CFG(GPIO10_2, AF0)
+#define GPIO11_2_GPIO MFP_CFG(GPIO11_2, AF0)
+#define GPIO12_2_GPIO MFP_CFG(GPIO12_2, AF0)
+#define GPIO13_2_GPIO MFP_CFG(GPIO13_2, AF0)
+#define GPIO14_2_GPIO MFP_CFG(GPIO14_2, AF0)
+#define GPIO15_2_GPIO MFP_CFG(GPIO15_2, AF0)
+#define GPIO16_2_GPIO MFP_CFG(GPIO16_2, AF0)
+#define GPIO17_2_GPIO MFP_CFG(GPIO17_2, AF0)
+
+/* Chip Select */
+#define GPIO3_nCS2 MFP_CFG(GPIO3, AF1)
+#define GPIO4_nCS3 MFP_CFG(GPIO4, AF1)
+
+/* AC97 */
+#define GPIO34_AC97_SYSCLK MFP_CFG(GPIO34, AF1)
+#define GPIO39_AC97_BITCLK MFP_CFG(GPIO39, AF1)
+#define GPIO40_AC97_nACRESET MFP_CFG(GPIO40, AF1)
+#define GPIO35_AC97_SDATA_IN_0 MFP_CFG(GPIO35, AF1)
+#define GPIO36_AC97_SDATA_IN_1 MFP_CFG(GPIO36, AF1)
+#define GPIO32_AC97_SDATA_IN_2 MFP_CFG(GPIO32, AF2)
+#define GPIO33_AC97_SDATA_IN_3 MFP_CFG(GPIO33, AF2)
+#define GPIO11_AC97_SDATA_IN_2 MFP_CFG(GPIO11, AF3)
+#define GPIO12_AC97_SDATA_IN_3 MFP_CFG(GPIO12, AF3)
+#define GPIO37_AC97_SDATA_OUT MFP_CFG(GPIO37, AF1)
+#define GPIO38_AC97_SYNC MFP_CFG(GPIO38, AF1)
+
+/* I2C */
+#define GPIO32_I2C_SCL MFP_CFG_LPM(GPIO32, AF1, PULL_HIGH)
+#define GPIO33_I2C_SDA MFP_CFG_LPM(GPIO33, AF1, PULL_HIGH)
+
+/* QCI */
+#define GPIO49_CI_DD_0 MFP_CFG_DRV(GPIO49, AF1, DS04X)
+#define GPIO50_CI_DD_1 MFP_CFG_DRV(GPIO50, AF1, DS04X)
+#define GPIO51_CI_DD_2 MFP_CFG_DRV(GPIO51, AF1, DS04X)
+#define GPIO52_CI_DD_3 MFP_CFG_DRV(GPIO52, AF1, DS04X)
+#define GPIO53_CI_DD_4 MFP_CFG_DRV(GPIO53, AF1, DS04X)
+#define GPIO54_CI_DD_5 MFP_CFG_DRV(GPIO54, AF1, DS04X)
+#define GPIO55_CI_DD_6 MFP_CFG_DRV(GPIO55, AF1, DS04X)
+#define GPIO56_CI_DD_7 MFP_CFG_DRV(GPIO56, AF0, DS04X)
+#define GPIO57_CI_DD_8 MFP_CFG_DRV(GPIO57, AF1, DS04X)
+#define GPIO58_CI_DD_9 MFP_CFG_DRV(GPIO58, AF1, DS04X)
+#define GPIO59_CI_MCLK MFP_CFG_DRV(GPIO59, AF0, DS04X)
+#define GPIO60_CI_PCLK MFP_CFG_DRV(GPIO60, AF0, DS04X)
+#define GPIO61_CI_HSYNC MFP_CFG_DRV(GPIO61, AF0, DS04X)
+#define GPIO62_CI_VSYNC MFP_CFG_DRV(GPIO62, AF0, DS04X)
+
+#define GPIO31_CIR_OUT MFP_CFG(GPIO31, AF5)
+
+#define GPIO0_2_CLK_EXT MFP_CFG(GPIO0_2, AF3)
+#define GPIO0_DRQ MFP_CFG(GPIO0, AF2)
+#define GPIO11_EXT_SYNC0 MFP_CFG(GPIO11, AF5)
+#define GPIO12_EXT_SYNC1 MFP_CFG(GPIO12, AF6)
+#define GPIO0_2_HZ_CLK MFP_CFG(GPIO0_2, AF1)
+#define GPIO14_HZ_CLK MFP_CFG(GPIO14, AF4)
+#define GPIO30_ICP_RXD MFP_CFG(GPIO30, AF1)
+#define GPIO31_ICP_TXD MFP_CFG(GPIO31, AF1)
+
+#define GPIO83_KP_DKIN_0 MFP_CFG_LPM(GPIO83, AF3, FLOAT)
+#define GPIO84_KP_DKIN_1 MFP_CFG_LPM(GPIO84, AF3, FLOAT)
+#define GPIO85_KP_DKIN_2 MFP_CFG_LPM(GPIO85, AF3, FLOAT)
+#define GPIO86_KP_DKIN_3 MFP_CFG_LPM(GPIO86, AF3, FLOAT)
+
+#define GPIO105_KP_DKIN_0 MFP_CFG_LPM(GPIO105, AF2, FLOAT)
+#define GPIO106_KP_DKIN_1 MFP_CFG_LPM(GPIO106, AF2, FLOAT)
+#define GPIO107_KP_DKIN_2 MFP_CFG_LPM(GPIO107, AF2, FLOAT)
+#define GPIO108_KP_DKIN_3 MFP_CFG_LPM(GPIO108, AF2, FLOAT)
+#define GPIO109_KP_DKIN_4 MFP_CFG_LPM(GPIO109, AF2, FLOAT)
+#define GPIO110_KP_DKIN_5 MFP_CFG_LPM(GPIO110, AF2, FLOAT)
+#define GPIO111_KP_DKIN_6 MFP_CFG_LPM(GPIO111, AF2, FLOAT)
+#define GPIO112_KP_DKIN_7 MFP_CFG_LPM(GPIO112, AF2, FLOAT)
+
+#define GPIO113_KP_DKIN_0 MFP_CFG_LPM(GPIO113, AF2, FLOAT)
+#define GPIO114_KP_DKIN_1 MFP_CFG_LPM(GPIO114, AF2, FLOAT)
+#define GPIO115_KP_DKIN_2 MFP_CFG_LPM(GPIO115, AF2, FLOAT)
+#define GPIO116_KP_DKIN_3 MFP_CFG_LPM(GPIO116, AF2, FLOAT)
+#define GPIO117_KP_DKIN_4 MFP_CFG_LPM(GPIO117, AF2, FLOAT)
+#define GPIO118_KP_DKIN_5 MFP_CFG_LPM(GPIO118, AF2, FLOAT)
+#define GPIO119_KP_DKIN_6 MFP_CFG_LPM(GPIO119, AF2, FLOAT)
+#define GPIO120_KP_DKIN_7 MFP_CFG_LPM(GPIO120, AF2, FLOAT)
+
+#define GPIO127_KP_DKIN_0 MFP_CFG_LPM(GPIO127, AF2, FLOAT)
+#define GPIO126_KP_DKIN_1 MFP_CFG_LPM(GPIO126, AF2, FLOAT)
+
+#define GPIO2_2_KP_DKIN_0 MFP_CFG_LPM(GPIO2_2, AF2, FLOAT)
+#define GPIO3_2_KP_DKIN_1 MFP_CFG_LPM(GPIO3_2, AF2, FLOAT)
+#define GPIO125_KP_DKIN_2 MFP_CFG_LPM(GPIO125, AF2, FLOAT)
+#define GPIO124_KP_DKIN_3 MFP_CFG_LPM(GPIO124, AF2, FLOAT)
+#define GPIO123_KP_DKIN_4 MFP_CFG_LPM(GPIO123, AF2, FLOAT)
+#define GPIO122_KP_DKIN_5 MFP_CFG_LPM(GPIO122, AF2, FLOAT)
+#define GPIO121_KP_DKIN_6 MFP_CFG_LPM(GPIO121, AF2, FLOAT)
+#define GPIO4_2_KP_DKIN_7 MFP_CFG_LPM(GPIO4_2, AF2, FLOAT)
+
+#define GPIO113_KP_MKIN_0 MFP_CFG_LPM(GPIO113, AF1, FLOAT)
+#define GPIO114_KP_MKIN_1 MFP_CFG_LPM(GPIO114, AF1, FLOAT)
+#define GPIO115_KP_MKIN_2 MFP_CFG_LPM(GPIO115, AF1, FLOAT)
+#define GPIO116_KP_MKIN_3 MFP_CFG_LPM(GPIO116, AF1, FLOAT)
+#define GPIO117_KP_MKIN_4 MFP_CFG_LPM(GPIO117, AF1, FLOAT)
+#define GPIO118_KP_MKIN_5 MFP_CFG_LPM(GPIO118, AF1, FLOAT)
+#define GPIO119_KP_MKIN_6 MFP_CFG_LPM(GPIO119, AF1, FLOAT)
+#define GPIO120_KP_MKIN_7 MFP_CFG_LPM(GPIO120, AF1, FLOAT)
+
+#define GPIO83_KP_MKOUT_0 MFP_CFG_LPM(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO84_KP_MKOUT_1 MFP_CFG_LPM(GPIO84, AF2, DRIVE_HIGH)
+#define GPIO85_KP_MKOUT_2 MFP_CFG_LPM(GPIO85, AF2, DRIVE_HIGH)
+#define GPIO86_KP_MKOUT_3 MFP_CFG_LPM(GPIO86, AF2, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_4 MFP_CFG_LPM(GPIO13, AF3, DRIVE_HIGH)
+#define GPIO14_KP_MKOUT_5 MFP_CFG_LPM(GPIO14, AF3, DRIVE_HIGH)
+
+#define GPIO121_KP_MKOUT_0 MFP_CFG_LPM(GPIO121, AF1, DRIVE_HIGH)
+#define GPIO122_KP_MKOUT_1 MFP_CFG_LPM(GPIO122, AF1, DRIVE_HIGH)
+#define GPIO123_KP_MKOUT_2 MFP_CFG_LPM(GPIO123, AF1, DRIVE_HIGH)
+#define GPIO124_KP_MKOUT_3 MFP_CFG_LPM(GPIO124, AF1, DRIVE_HIGH)
+#define GPIO125_KP_MKOUT_4 MFP_CFG_LPM(GPIO125, AF1, DRIVE_HIGH)
+#define GPIO126_KP_MKOUT_5 MFP_CFG_LPM(GPIO126, AF1, DRIVE_HIGH)
+#define GPIO127_KP_MKOUT_6 MFP_CFG_LPM(GPIO127, AF1, DRIVE_HIGH)
+#define GPIO5_2_KP_MKOUT_7 MFP_CFG_LPM(GPIO5_2, AF1, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO6_2_LCD_LDD_0 MFP_CFG_DRV(GPIO6_2, AF1, DS01X)
+#define GPIO7_2_LCD_LDD_1 MFP_CFG_DRV(GPIO7_2, AF1, DS01X)
+#define GPIO8_2_LCD_LDD_2 MFP_CFG_DRV(GPIO8_2, AF1, DS01X)
+#define GPIO9_2_LCD_LDD_3 MFP_CFG_DRV(GPIO9_2, AF1, DS01X)
+#define GPIO10_2_LCD_LDD_4 MFP_CFG_DRV(GPIO10_2, AF1, DS01X)
+#define GPIO11_2_LCD_LDD_5 MFP_CFG_DRV(GPIO11_2, AF1, DS01X)
+#define GPIO12_2_LCD_LDD_6 MFP_CFG_DRV(GPIO12_2, AF1, DS01X)
+#define GPIO13_2_LCD_LDD_7 MFP_CFG_DRV(GPIO13_2, AF1, DS01X)
+#define GPIO63_LCD_LDD_8 MFP_CFG_DRV(GPIO63, AF1, DS01X)
+#define GPIO64_LCD_LDD_9 MFP_CFG_DRV(GPIO64, AF1, DS01X)
+#define GPIO65_LCD_LDD_10 MFP_CFG_DRV(GPIO65, AF1, DS01X)
+#define GPIO66_LCD_LDD_11 MFP_CFG_DRV(GPIO66, AF1, DS01X)
+#define GPIO67_LCD_LDD_12 MFP_CFG_DRV(GPIO67, AF1, DS01X)
+#define GPIO68_LCD_LDD_13 MFP_CFG_DRV(GPIO68, AF1, DS01X)
+#define GPIO69_LCD_LDD_14 MFP_CFG_DRV(GPIO69, AF1, DS01X)
+#define GPIO70_LCD_LDD_15 MFP_CFG_DRV(GPIO70, AF1, DS01X)
+#define GPIO71_LCD_LDD_16 MFP_CFG_DRV(GPIO71, AF1, DS01X)
+#define GPIO72_LCD_LDD_17 MFP_CFG_DRV(GPIO72, AF1, DS01X)
+#define GPIO73_LCD_CS_N MFP_CFG_DRV(GPIO73, AF2, DS01X)
+#define GPIO74_LCD_VSYNC MFP_CFG_DRV(GPIO74, AF2, DS01X)
+#define GPIO14_2_LCD_FCLK MFP_CFG_DRV(GPIO14_2, AF1, DS01X)
+#define GPIO15_2_LCD_LCLK MFP_CFG_DRV(GPIO15_2, AF1, DS01X)
+#define GPIO16_2_LCD_PCLK MFP_CFG_DRV(GPIO16_2, AF1, DS01X)
+#define GPIO17_2_LCD_BIAS MFP_CFG_DRV(GPIO17_2, AF1, DS01X)
+#define GPIO64_LCD_VSYNC MFP_CFG_DRV(GPIO64, AF2, DS01X)
+#define GPIO63_LCD_CS_N MFP_CFG_DRV(GPIO63, AF2, DS01X)
+
+#define GPIO6_2_MLCD_DD_0 MFP_CFG_DRV(GPIO6_2, AF7, DS08X)
+#define GPIO7_2_MLCD_DD_1 MFP_CFG_DRV(GPIO7_2, AF7, DS08X)
+#define GPIO8_2_MLCD_DD_2 MFP_CFG_DRV(GPIO8_2, AF7, DS08X)
+#define GPIO9_2_MLCD_DD_3 MFP_CFG_DRV(GPIO9_2, AF7, DS08X)
+#define GPIO10_2_MLCD_DD_4 MFP_CFG_DRV(GPIO10_2, AF7, DS08X)
+#define GPIO11_2_MLCD_DD_5 MFP_CFG_DRV(GPIO11_2, AF7, DS08X)
+#define GPIO12_2_MLCD_DD_6 MFP_CFG_DRV(GPIO12_2, AF7, DS08X)
+#define GPIO13_2_MLCD_DD_7 MFP_CFG_DRV(GPIO13_2, AF7, DS08X)
+#define GPIO63_MLCD_DD_8 MFP_CFG_DRV(GPIO63, AF7, DS08X)
+#define GPIO64_MLCD_DD_9 MFP_CFG_DRV(GPIO64, AF7, DS08X)
+#define GPIO65_MLCD_DD_10 MFP_CFG_DRV(GPIO65, AF7, DS08X)
+#define GPIO66_MLCD_DD_11 MFP_CFG_DRV(GPIO66, AF7, DS08X)
+#define GPIO67_MLCD_DD_12 MFP_CFG_DRV(GPIO67, AF7, DS08X)
+#define GPIO68_MLCD_DD_13 MFP_CFG_DRV(GPIO68, AF7, DS08X)
+#define GPIO69_MLCD_DD_14 MFP_CFG_DRV(GPIO69, AF7, DS08X)
+#define GPIO70_MLCD_DD_15 MFP_CFG_DRV(GPIO70, AF7, DS08X)
+#define GPIO71_MLCD_DD_16 MFP_CFG_DRV(GPIO71, AF7, DS08X)
+#define GPIO72_MLCD_DD_17 MFP_CFG_DRV(GPIO72, AF7, DS08X)
+#define GPIO73_MLCD_CS MFP_CFG_DRV(GPIO73, AF7, DS08X)
+#define GPIO74_MLCD_VSYNC MFP_CFG_DRV(GPIO74, AF7, DS08X)
+#define GPIO14_2_MLCD_FCLK MFP_CFG_DRV(GPIO14_2, AF7, DS08X)
+#define GPIO15_2_MLCD_LCLK MFP_CFG_DRV(GPIO15_2, AF7, DS08X)
+#define GPIO16_2_MLCD_PCLK MFP_CFG_DRV(GPIO16_2, AF7, DS08X)
+#define GPIO17_2_MLCD_BIAS MFP_CFG_DRV(GPIO17_2, AF7, DS08X)
+
+/* MMC1 */
+#define GPIO9_MMC1_CMD MFP_CFG_LPM(GPIO9, AF4, DRIVE_HIGH)
+#define GPIO22_MMC1_CLK MFP_CFG_LPM(GPIO22, AF4, DRIVE_HIGH)
+#define GPIO23_MMC1_CMD MFP_CFG_LPM(GPIO23, AF4, DRIVE_HIGH)
+#define GPIO30_MMC1_CLK MFP_CFG_LPM(GPIO30, AF4, DRIVE_HIGH)
+#define GPIO31_MMC1_CMD MFP_CFG_LPM(GPIO31, AF4, DRIVE_HIGH)
+#define GPIO5_MMC1_DAT0 MFP_CFG_LPM(GPIO5, AF4, DRIVE_HIGH)
+#define GPIO6_MMC1_DAT1 MFP_CFG_LPM(GPIO6, AF4, DRIVE_HIGH)
+#define GPIO7_MMC1_DAT2 MFP_CFG_LPM(GPIO7, AF4, DRIVE_HIGH)
+#define GPIO8_MMC1_DAT3 MFP_CFG_LPM(GPIO8, AF4, DRIVE_HIGH)
+#define GPIO18_MMC1_DAT0 MFP_CFG_LPM(GPIO18, AF4, DRIVE_HIGH)
+#define GPIO19_MMC1_DAT1 MFP_CFG_LPM(GPIO19, AF4, DRIVE_HIGH)
+#define GPIO20_MMC1_DAT2 MFP_CFG_LPM(GPIO20, AF4, DRIVE_HIGH)
+#define GPIO21_MMC1_DAT3 MFP_CFG_LPM(GPIO21, AF4, DRIVE_HIGH)
+
+#define GPIO28_MMC2_CLK MFP_CFG_LPM(GPIO28, AF4, PULL_HIGH)
+#define GPIO29_MMC2_CMD MFP_CFG_LPM(GPIO29, AF4, PULL_HIGH)
+#define GPIO30_MMC2_CLK MFP_CFG_LPM(GPIO30, AF3, PULL_HIGH)
+#define GPIO31_MMC2_CMD MFP_CFG_LPM(GPIO31, AF3, PULL_HIGH)
+#define GPIO79_MMC2_CLK MFP_CFG_LPM(GPIO79, AF4, PULL_HIGH)
+#define GPIO80_MMC2_CMD MFP_CFG_LPM(GPIO80, AF4, PULL_HIGH)
+
+#define GPIO5_MMC2_DAT0 MFP_CFG_LPM(GPIO5, AF2, PULL_HIGH)
+#define GPIO6_MMC2_DAT1 MFP_CFG_LPM(GPIO6, AF2, PULL_HIGH)
+#define GPIO7_MMC2_DAT2 MFP_CFG_LPM(GPIO7, AF2, PULL_HIGH)
+#define GPIO8_MMC2_DAT3 MFP_CFG_LPM(GPIO8, AF2, PULL_HIGH)
+#define GPIO24_MMC2_DAT0 MFP_CFG_LPM(GPIO24, AF4, PULL_HIGH)
+#define GPIO75_MMC2_DAT0 MFP_CFG_LPM(GPIO75, AF4, PULL_HIGH)
+#define GPIO25_MMC2_DAT1 MFP_CFG_LPM(GPIO25, AF4, PULL_HIGH)
+#define GPIO76_MMC2_DAT1 MFP_CFG_LPM(GPIO76, AF4, PULL_HIGH)
+#define GPIO26_MMC2_DAT2 MFP_CFG_LPM(GPIO26, AF4, PULL_HIGH)
+#define GPIO77_MMC2_DAT2 MFP_CFG_LPM(GPIO77, AF4, PULL_HIGH)
+#define GPIO27_MMC2_DAT3 MFP_CFG_LPM(GPIO27, AF4, PULL_HIGH)
+#define GPIO78_MMC2_DAT3 MFP_CFG_LPM(GPIO78, AF4, PULL_HIGH)
+
+/* 1-Wire */
+#define GPIO14_ONE_WIRE MFP_CFG_LPM(GPIO14, AF5, FLOAT)
+#define GPIO0_2_ONE_WIRE MFP_CFG_LPM(GPIO0_2, AF2, FLOAT)
+
+/* SSP1 */
+#define GPIO87_SSP1_EXTCLK MFP_CFG(GPIO87, AF1)
+#define GPIO88_SSP1_SYSCLK MFP_CFG(GPIO88, AF1)
+#define GPIO83_SSP1_SCLK MFP_CFG(GPIO83, AF1)
+#define GPIO84_SSP1_SFRM MFP_CFG(GPIO84, AF1)
+#define GPIO85_SSP1_RXD MFP_CFG(GPIO85, AF6)
+#define GPIO85_SSP1_TXD MFP_CFG(GPIO85, AF1)
+#define GPIO86_SSP1_RXD MFP_CFG(GPIO86, AF1)
+#define GPIO86_SSP1_TXD MFP_CFG(GPIO86, AF6)
+
+/* SSP2 */
+#define GPIO39_SSP2_EXTCLK MFP_CFG(GPIO39, AF2)
+#define GPIO40_SSP2_SYSCLK MFP_CFG(GPIO40, AF2)
+#define GPIO12_SSP2_SCLK MFP_CFG(GPIO12, AF2)
+#define GPIO35_SSP2_SCLK MFP_CFG(GPIO35, AF2)
+#define GPIO36_SSP2_SFRM MFP_CFG(GPIO36, AF2)
+#define GPIO37_SSP2_RXD MFP_CFG(GPIO37, AF5)
+#define GPIO37_SSP2_TXD MFP_CFG(GPIO37, AF2)
+#define GPIO38_SSP2_RXD MFP_CFG(GPIO38, AF2)
+#define GPIO38_SSP2_TXD MFP_CFG(GPIO38, AF5)
+
+#define GPIO69_SSP3_SCLK MFP_CFG_X(GPIO69, AF2, DS08X, FLOAT)
+#define GPIO70_SSP3_FRM MFP_CFG_X(GPIO70, AF2, DS08X, DRIVE_LOW)
+#define GPIO89_SSP3_SCLK MFP_CFG_X(GPIO89, AF1, DS08X, FLOAT)
+#define GPIO90_SSP3_FRM MFP_CFG_X(GPIO90, AF1, DS08X, DRIVE_LOW)
+#define GPIO71_SSP3_RXD MFP_CFG_X(GPIO71, AF5, DS08X, FLOAT)
+#define GPIO71_SSP3_TXD MFP_CFG_X(GPIO71, AF2, DS08X, DRIVE_LOW)
+#define GPIO72_SSP3_RXD MFP_CFG_X(GPIO72, AF2, DS08X, FLOAT)
+#define GPIO72_SSP3_TXD MFP_CFG_X(GPIO72, AF5, DS08X, DRIVE_LOW)
+#define GPIO91_SSP3_RXD MFP_CFG_X(GPIO91, AF5, DS08X, FLOAT)
+#define GPIO91_SSP3_TXD MFP_CFG_X(GPIO91, AF1, DS08X, DRIVE_LOW)
+#define GPIO92_SSP3_RXD MFP_CFG_X(GPIO92, AF1, DS08X, FLOAT)
+#define GPIO92_SSP3_TXD MFP_CFG_X(GPIO92, AF5, DS08X, DRIVE_LOW)
+
+#define GPIO93_SSP4_SCLK MFP_CFG_LPM(GPIO93, AF1, PULL_HIGH)
+#define GPIO94_SSP4_FRM MFP_CFG_LPM(GPIO94, AF1, PULL_HIGH)
+#define GPIO94_SSP4_RXD MFP_CFG_LPM(GPIO94, AF5, PULL_HIGH)
+#define GPIO95_SSP4_RXD MFP_CFG_LPM(GPIO95, AF5, PULL_HIGH)
+#define GPIO95_SSP4_TXD MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_SSP4_RXD MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+#define GPIO96_SSP4_TXD MFP_CFG_LPM(GPIO96, AF5, PULL_HIGH)
+
+/* UART1 */
+#define GPIO41_UART1_RXD MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO41_UART1_TXD MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_UART1_RXD MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+#define GPIO42_UART1_TXD MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO75_UART1_RXD MFP_CFG_LPM(GPIO75, AF1, FLOAT)
+#define GPIO76_UART1_RXD MFP_CFG_LPM(GPIO76, AF3, FLOAT)
+#define GPIO76_UART1_TXD MFP_CFG_LPM(GPIO76, AF1, FLOAT)
+#define GPIO97_UART1_RXD MFP_CFG_LPM(GPIO97, AF1, FLOAT)
+#define GPIO97_UART1_TXD MFP_CFG_LPM(GPIO97, AF6, FLOAT)
+#define GPIO98_UART1_RXD MFP_CFG_LPM(GPIO98, AF6, FLOAT)
+#define GPIO98_UART1_TXD MFP_CFG_LPM(GPIO98, AF1, FLOAT)
+#define GPIO43_UART1_CTS MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO43_UART1_RTS MFP_CFG_LPM(GPIO43, AF4, FLOAT)
+#define GPIO48_UART1_CTS MFP_CFG_LPM(GPIO48, AF4, FLOAT)
+#define GPIO48_UART1_RTS MFP_CFG_LPM(GPIO48, AF2, FLOAT)
+#define GPIO77_UART1_CTS MFP_CFG_LPM(GPIO77, AF1, FLOAT)
+#define GPIO82_UART1_RTS MFP_CFG_LPM(GPIO82, AF1, FLOAT)
+#define GPIO82_UART1_CTS MFP_CFG_LPM(GPIO82, AF3, FLOAT)
+#define GPIO99_UART1_CTS MFP_CFG_LPM(GPIO99, AF1, FLOAT)
+#define GPIO99_UART1_RTS MFP_CFG_LPM(GPIO99, AF6, FLOAT)
+#define GPIO104_UART1_CTS MFP_CFG_LPM(GPIO104, AF6, FLOAT)
+#define GPIO104_UART1_RTS MFP_CFG_LPM(GPIO104, AF1, FLOAT)
+#define GPIO45_UART1_DTR MFP_CFG_LPM(GPIO45, AF4, FLOAT)
+#define GPIO45_UART1_DSR MFP_CFG_LPM(GPIO45, AF2, FLOAT)
+#define GPIO47_UART1_DTR MFP_CFG_LPM(GPIO47, AF2, FLOAT)
+#define GPIO47_UART1_DSR MFP_CFG_LPM(GPIO47, AF4, FLOAT)
+#define GPIO79_UART1_DSR MFP_CFG_LPM(GPIO79, AF1, FLOAT)
+#define GPIO81_UART1_DTR MFP_CFG_LPM(GPIO81, AF1, FLOAT)
+#define GPIO81_UART1_DSR MFP_CFG_LPM(GPIO81, AF3, FLOAT)
+#define GPIO101_UART1_DTR MFP_CFG_LPM(GPIO101, AF6, FLOAT)
+#define GPIO101_UART1_DSR MFP_CFG_LPM(GPIO101, AF1, FLOAT)
+#define GPIO103_UART1_DTR MFP_CFG_LPM(GPIO103, AF1, FLOAT)
+#define GPIO103_UART1_DSR MFP_CFG_LPM(GPIO103, AF6, FLOAT)
+#define GPIO44_UART1_DCD MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO78_UART1_DCD MFP_CFG_LPM(GPIO78, AF1, FLOAT)
+#define GPIO100_UART1_DCD MFP_CFG_LPM(GPIO100, AF1, FLOAT)
+#define GPIO46_UART1_RI MFP_CFG_LPM(GPIO46, AF2, FLOAT)
+#define GPIO80_UART1_RI MFP_CFG_LPM(GPIO80, AF1, FLOAT)
+#define GPIO102_UART1_RI MFP_CFG_LPM(GPIO102, AF1, FLOAT)
+
+/* UART2 */
+#define GPIO109_UART2_CTS MFP_CFG_LPM(GPIO109, AF3, FLOAT)
+#define GPIO109_UART2_RTS MFP_CFG_LPM(GPIO109, AF1, FLOAT)
+#define GPIO112_UART2_CTS MFP_CFG_LPM(GPIO112, AF1, FLOAT)
+#define GPIO112_UART2_RTS MFP_CFG_LPM(GPIO112, AF3, FLOAT)
+#define GPIO110_UART2_RXD MFP_CFG_LPM(GPIO110, AF1, FLOAT)
+#define GPIO110_UART2_TXD MFP_CFG_LPM(GPIO110, AF3, FLOAT)
+#define GPIO111_UART2_RXD MFP_CFG_LPM(GPIO111, AF3, FLOAT)
+#define GPIO111_UART2_TXD MFP_CFG_LPM(GPIO111, AF1, FLOAT)
+
+/* UART3 */
+#define GPIO89_UART3_CTS MFP_CFG_LPM(GPIO89, AF2, FLOAT)
+#define GPIO89_UART3_RTS MFP_CFG_LPM(GPIO89, AF4, FLOAT)
+#define GPIO90_UART3_CTS MFP_CFG_LPM(GPIO90, AF4, FLOAT)
+#define GPIO90_UART3_RTS MFP_CFG_LPM(GPIO90, AF2, FLOAT)
+#define GPIO105_UART3_CTS MFP_CFG_LPM(GPIO105, AF1, FLOAT)
+#define GPIO105_UART3_RTS MFP_CFG_LPM(GPIO105, AF3, FLOAT)
+#define GPIO106_UART3_CTS MFP_CFG_LPM(GPIO106, AF3, FLOAT)
+#define GPIO106_UART3_RTS MFP_CFG_LPM(GPIO106, AF1, FLOAT)
+#define GPIO30_UART3_RXD MFP_CFG_LPM(GPIO30, AF2, FLOAT)
+#define GPIO30_UART3_TXD MFP_CFG_LPM(GPIO30, AF6, FLOAT)
+#define GPIO31_UART3_RXD MFP_CFG_LPM(GPIO31, AF6, FLOAT)
+#define GPIO31_UART3_TXD MFP_CFG_LPM(GPIO31, AF2, FLOAT)
+#define GPIO91_UART3_RXD MFP_CFG_LPM(GPIO91, AF4, FLOAT)
+#define GPIO91_UART3_TXD MFP_CFG_LPM(GPIO91, AF2, FLOAT)
+#define GPIO92_UART3_RXD MFP_CFG_LPM(GPIO92, AF2, FLOAT)
+#define GPIO92_UART3_TXD MFP_CFG_LPM(GPIO92, AF4, FLOAT)
+#define GPIO107_UART3_RXD MFP_CFG_LPM(GPIO107, AF3, FLOAT)
+#define GPIO107_UART3_TXD MFP_CFG_LPM(GPIO107, AF1, FLOAT)
+#define GPIO108_UART3_RXD MFP_CFG_LPM(GPIO108, AF1, FLOAT)
+#define GPIO108_UART3_TXD MFP_CFG_LPM(GPIO108, AF3, FLOAT)
+
+
+/* USB 2.0 UTMI */
+#define GPIO10_UTM_CLK MFP_CFG(GPIO10, AF1)
+#define GPIO36_U2D_RXERROR MFP_CFG(GPIO36, AF3)
+#define GPIO60_U2D_RXERROR MFP_CFG(GPIO60, AF1)
+#define GPIO87_U2D_RXERROR MFP_CFG(GPIO87, AF5)
+#define GPIO34_UTM_RXVALID MFP_CFG(GPIO34, AF3)
+#define GPIO58_UTM_RXVALID MFP_CFG(GPIO58, AF2)
+#define GPIO85_UTM_RXVALID MFP_CFG(GPIO85, AF5)
+#define GPIO35_UTM_RXACTIVE MFP_CFG(GPIO35, AF3)
+#define GPIO59_UTM_RXACTIVE MFP_CFG(GPIO59, AF1)
+#define GPIO86_UTM_RXACTIVE MFP_CFG(GPIO86, AF5)
+#define GPIO73_UTM_TXREADY MFP_CFG(GPIO73, AF1)
+#define GPIO68_UTM_LINESTATE_0 MFP_CFG(GPIO68, AF3)
+#define GPIO90_UTM_LINESTATE_0 MFP_CFG(GPIO90, AF3)
+#define GPIO102_UTM_LINESTATE_0 MFP_CFG(GPIO102, AF3)
+#define GPIO107_UTM_LINESTATE_0 MFP_CFG(GPIO107, AF4)
+#define GPIO69_UTM_LINESTATE_1 MFP_CFG(GPIO69, AF3)
+#define GPIO91_UTM_LINESTATE_1 MFP_CFG(GPIO91, AF3)
+#define GPIO103_UTM_LINESTATE_1 MFP_CFG(GPIO103, AF3)
+
+#define GPIO41_U2D_PHYDATA_0 MFP_CFG(GPIO41, AF3)
+#define GPIO42_U2D_PHYDATA_1 MFP_CFG(GPIO42, AF3)
+#define GPIO43_U2D_PHYDATA_2 MFP_CFG(GPIO43, AF3)
+#define GPIO44_U2D_PHYDATA_3 MFP_CFG(GPIO44, AF3)
+#define GPIO45_U2D_PHYDATA_4 MFP_CFG(GPIO45, AF3)
+#define GPIO46_U2D_PHYDATA_5 MFP_CFG(GPIO46, AF3)
+#define GPIO47_U2D_PHYDATA_6 MFP_CFG(GPIO47, AF3)
+#define GPIO48_U2D_PHYDATA_7 MFP_CFG(GPIO48, AF3)
+
+#define GPIO49_U2D_PHYDATA_0 MFP_CFG(GPIO49, AF3)
+#define GPIO50_U2D_PHYDATA_1 MFP_CFG(GPIO50, AF3)
+#define GPIO51_U2D_PHYDATA_2 MFP_CFG(GPIO51, AF3)
+#define GPIO52_U2D_PHYDATA_3 MFP_CFG(GPIO52, AF3)
+#define GPIO53_U2D_PHYDATA_4 MFP_CFG(GPIO53, AF3)
+#define GPIO54_U2D_PHYDATA_5 MFP_CFG(GPIO54, AF3)
+#define GPIO55_U2D_PHYDATA_6 MFP_CFG(GPIO55, AF3)
+#define GPIO56_U2D_PHYDATA_7 MFP_CFG(GPIO56, AF3)
+
+#define GPIO37_U2D_OPMODE0 MFP_CFG(GPIO37, AF4)
+#define GPIO61_U2D_OPMODE0 MFP_CFG(GPIO61, AF2)
+#define GPIO88_U2D_OPMODE0 MFP_CFG(GPIO88, AF7)
+
+#define GPIO38_U2D_OPMODE1 MFP_CFG(GPIO38, AF4)
+#define GPIO62_U2D_OPMODE1 MFP_CFG(GPIO62, AF2)
+#define GPIO104_U2D_OPMODE1 MFP_CFG(GPIO104, AF4)
+#define GPIO108_U2D_OPMODE1 MFP_CFG(GPIO108, AF5)
+
+#define GPIO74_U2D_RESET MFP_CFG(GPIO74, AF1)
+#define GPIO93_U2D_RESET MFP_CFG(GPIO93, AF2)
+#define GPIO98_U2D_RESET MFP_CFG(GPIO98, AF3)
+
+#define GPIO67_U2D_SUSPEND MFP_CFG(GPIO67, AF3)
+#define GPIO96_U2D_SUSPEND MFP_CFG(GPIO96, AF2)
+#define GPIO101_U2D_SUSPEND MFP_CFG(GPIO101, AF3)
+
+#define GPIO66_U2D_TERM_SEL MFP_CFG(GPIO66, AF5)
+#define GPIO95_U2D_TERM_SEL MFP_CFG(GPIO95, AF3)
+#define GPIO97_U2D_TERM_SEL MFP_CFG(GPIO97, AF7)
+#define GPIO100_U2D_TERM_SEL MFP_CFG(GPIO100, AF5)
+
+#define GPIO39_U2D_TXVALID MFP_CFG(GPIO39, AF4)
+#define GPIO70_U2D_TXVALID MFP_CFG(GPIO70, AF5)
+#define GPIO83_U2D_TXVALID MFP_CFG(GPIO83, AF7)
+
+#define GPIO65_U2D_XCVR_SEL MFP_CFG(GPIO65, AF5)
+#define GPIO94_U2D_XCVR_SEL MFP_CFG(GPIO94, AF3)
+#define GPIO99_U2D_XCVR_SEL MFP_CFG(GPIO99, AF5)
+
+/* USB Host 1.1 */
+#define GPIO2_2_USBH_PEN MFP_CFG(GPIO2_2, AF1)
+#define GPIO3_2_USBH_PWR MFP_CFG(GPIO3_2, AF1)
+
+/* USB P2 */
+#define GPIO97_USB_P2_2 MFP_CFG(GPIO97, AF2)
+#define GPIO97_USB_P2_6 MFP_CFG(GPIO97, AF4)
+#define GPIO98_USB_P2_2 MFP_CFG(GPIO98, AF4)
+#define GPIO98_USB_P2_6 MFP_CFG(GPIO98, AF2)
+#define GPIO99_USB_P2_1 MFP_CFG(GPIO99, AF2)
+#define GPIO100_USB_P2_4 MFP_CFG(GPIO100, AF2)
+#define GPIO101_USB_P2_8 MFP_CFG(GPIO101, AF2)
+#define GPIO102_USB_P2_3 MFP_CFG(GPIO102, AF2)
+#define GPIO103_USB_P2_5 MFP_CFG(GPIO103, AF2)
+#define GPIO104_USB_P2_7 MFP_CFG(GPIO104, AF2)
+
+/* USB P3 */
+#define GPIO75_USB_P3_1 MFP_CFG(GPIO75, AF2)
+#define GPIO76_USB_P3_2 MFP_CFG(GPIO76, AF2)
+#define GPIO77_USB_P3_3 MFP_CFG(GPIO77, AF2)
+#define GPIO78_USB_P3_4 MFP_CFG(GPIO78, AF2)
+#define GPIO79_USB_P3_5 MFP_CFG(GPIO79, AF2)
+#define GPIO80_USB_P3_6 MFP_CFG(GPIO80, AF2)
+
+#define GPIO13_CHOUT0 MFP_CFG(GPIO13, AF6)
+#define GPIO14_CHOUT1 MFP_CFG(GPIO14, AF6)
+
+#define GPIO2_RDY MFP_CFG(GPIO2, AF1)
+#define GPIO5_NPIOR MFP_CFG(GPIO5, AF3)
+#define GPIO6_NPIOW MFP_CFG(GPIO6, AF3)
+#define GPIO7_NPIOS16 MFP_CFG(GPIO7, AF3)
+#define GPIO8_NPWAIT MFP_CFG(GPIO8, AF3)
+
+#define GPIO11_PWM0_OUT MFP_CFG(GPIO11, AF1)
+#define GPIO12_PWM1_OUT MFP_CFG(GPIO12, AF1)
+#define GPIO13_PWM2_OUT MFP_CFG(GPIO13, AF1)
+#define GPIO14_PWM3_OUT MFP_CFG(GPIO14, AF1)
+
+#endif /* __ASM_ARCH_MFP_PXA320_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
new file mode 100644
index 00000000..d375195d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa3xx.h
@@ -0,0 +1,158 @@
+#ifndef __ASM_ARCH_MFP_PXA3XX_H
+#define __ASM_ARCH_MFP_PXA3XX_H
+
+#include <plat/mfp.h>
+
+#define MFPR_BASE (0x40e10000)
+
+/* PXA3xx common MFP configurations - processor specific ones defined
+ * in mfp-pxa300.h and mfp-pxa320.h
+ */
+#define GPIO0_GPIO MFP_CFG(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG(GPIO1, AF0)
+#define GPIO2_GPIO MFP_CFG(GPIO2, AF0)
+#define GPIO3_GPIO MFP_CFG(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG(GPIO4, AF0)
+#define GPIO5_GPIO MFP_CFG(GPIO5, AF0)
+#define GPIO6_GPIO MFP_CFG(GPIO6, AF0)
+#define GPIO7_GPIO MFP_CFG(GPIO7, AF0)
+#define GPIO8_GPIO MFP_CFG(GPIO8, AF0)
+#define GPIO9_GPIO MFP_CFG(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG(GPIO45, AF0)
+
+#define GPIO47_GPIO MFP_CFG(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG(GPIO48, AF0)
+
+#define GPIO53_GPIO MFP_CFG(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG(GPIO55, AF0)
+
+#define GPIO57_GPIO MFP_CFG(GPIO57, AF0)
+
+#define GPIO63_GPIO MFP_CFG(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG(GPIO84, AF0)
+#define GPIO85_GPIO MFP_CFG(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG(GPIO120, AF0)
+#define GPIO121_GPIO MFP_CFG(GPIO121, AF0)
+#define GPIO122_GPIO MFP_CFG(GPIO122, AF0)
+#define GPIO123_GPIO MFP_CFG(GPIO123, AF0)
+#define GPIO124_GPIO MFP_CFG(GPIO124, AF0)
+#define GPIO125_GPIO MFP_CFG(GPIO125, AF0)
+#define GPIO126_GPIO MFP_CFG(GPIO126, AF0)
+#define GPIO127_GPIO MFP_CFG(GPIO127, AF0)
+
+#define GPIO0_2_GPIO MFP_CFG(GPIO0_2, AF0)
+#define GPIO1_2_GPIO MFP_CFG(GPIO1_2, AF0)
+#define GPIO2_2_GPIO MFP_CFG(GPIO2_2, AF0)
+#define GPIO3_2_GPIO MFP_CFG(GPIO3_2, AF0)
+#define GPIO4_2_GPIO MFP_CFG(GPIO4_2, AF0)
+#define GPIO5_2_GPIO MFP_CFG(GPIO5_2, AF0)
+#define GPIO6_2_GPIO MFP_CFG(GPIO6_2, AF0)
+
+/* NOTE: usage of these two functions is not recommended,
+ * use pxa3xx_mfp_config() instead.
+ */
+static inline unsigned long pxa3xx_mfp_read(int mfp)
+{
+ return mfp_read(mfp);
+}
+
+static inline void pxa3xx_mfp_write(int mfp, unsigned long val)
+{
+ mfp_write(mfp, val);
+}
+
+static inline void pxa3xx_mfp_config(unsigned long *mfp_cfg, int num)
+{
+ mfp_config(mfp_cfg, num);
+}
+#endif /* __ASM_ARCH_MFP_PXA3XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa930.h b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
new file mode 100644
index 00000000..04f7c970
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa930.h
@@ -0,0 +1,498 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp-pxa930.h
+ *
+ * PXA930 specific MFP configuration definitions
+ *
+ * Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MFP_PXA9xx_H
+#define __ASM_ARCH_MFP_PXA9xx_H
+
+#include <mach/mfp-pxa3xx.h>
+
+/* GPIO */
+#define GPIO46_GPIO MFP_CFG(GPIO46, AF0)
+#define GPIO49_GPIO MFP_CFG(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG(GPIO52, AF0)
+#define GPIO56_GPIO MFP_CFG(GPIO56, AF0)
+#define GPIO58_GPIO MFP_CFG(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG(GPIO62, AF0)
+
+#define GSIM_UCLK_GPIO_79 MFP_CFG(GSIM_UCLK, AF0)
+#define GSIM_UIO_GPIO_80 MFP_CFG(GSIM_UIO, AF0)
+#define GSIM_nURST_GPIO_81 MFP_CFG(GSIM_nURST, AF0)
+#define GSIM_UDET_GPIO_82 MFP_CFG(GSIM_UDET, AF0)
+
+#define DF_IO15_GPIO_28 MFP_CFG(DF_IO15, AF0)
+#define DF_IO14_GPIO_29 MFP_CFG(DF_IO14, AF0)
+#define DF_IO13_GPIO_30 MFP_CFG(DF_IO13, AF0)
+#define DF_IO12_GPIO_31 MFP_CFG(DF_IO12, AF0)
+#define DF_IO11_GPIO_32 MFP_CFG(DF_IO11, AF0)
+#define DF_IO10_GPIO_33 MFP_CFG(DF_IO10, AF0)
+#define DF_IO9_GPIO_34 MFP_CFG(DF_IO9, AF0)
+#define DF_IO8_GPIO_35 MFP_CFG(DF_IO8, AF0)
+#define DF_IO7_GPIO_36 MFP_CFG(DF_IO7, AF0)
+#define DF_IO6_GPIO_37 MFP_CFG(DF_IO6, AF0)
+#define DF_IO5_GPIO_38 MFP_CFG(DF_IO5, AF0)
+#define DF_IO4_GPIO_39 MFP_CFG(DF_IO4, AF0)
+#define DF_IO3_GPIO_40 MFP_CFG(DF_IO3, AF0)
+#define DF_IO2_GPIO_41 MFP_CFG(DF_IO2, AF0)
+#define DF_IO1_GPIO_42 MFP_CFG(DF_IO1, AF0)
+#define DF_IO0_GPIO_43 MFP_CFG(DF_IO0, AF0)
+#define DF_nCS0_GPIO_44 MFP_CFG(DF_nCS0, AF0)
+#define DF_nCS1_GPIO_45 MFP_CFG(DF_nCS1, AF0)
+#define DF_nWE_GPIO_46 MFP_CFG(DF_nWE, AF0)
+#define DF_nRE_nOE_GPIO_47 MFP_CFG(DF_nRE_nOE, AF0)
+#define DF_CLE_nOE_GPIO_48 MFP_CFG(DF_CLE_nOE, AF0)
+#define DF_nADV1_ALE_GPIO_49 MFP_CFG(DF_nADV1_ALE, AF0)
+#define DF_nADV2_ALE_GPIO_50 MFP_CFG(DF_nADV2_ALE, AF0)
+#define DF_INT_RnB_GPIO_51 MFP_CFG(DF_INT_RnB, AF0)
+#define DF_SCLK_E_GPIO_52 MFP_CFG(DF_SCLK_E, AF0)
+
+#define DF_ADDR0_GPIO_53 MFP_CFG(DF_ADDR0, AF0)
+#define DF_ADDR1_GPIO_54 MFP_CFG(DF_ADDR1, AF0)
+#define DF_ADDR2_GPIO_55 MFP_CFG(DF_ADDR2, AF0)
+#define DF_ADDR3_GPIO_56 MFP_CFG(DF_ADDR3, AF0)
+#define nXCVREN_GPIO_57 MFP_CFG(nXCVREN, AF0)
+#define nLUA_GPIO_58 MFP_CFG(nLUA, AF0)
+#define nLLA_GPIO_59 MFP_CFG(nLLA, AF0)
+#define nBE0_GPIO_60 MFP_CFG(nBE0, AF0)
+#define nBE1_GPIO_61 MFP_CFG(nBE1, AF0)
+#define RDY_GPIO_62 MFP_CFG(RDY, AF0)
+#define PMIC_INT_GPIO83 MFP_CFG_LPM(PMIC_INT, AF0, PULL_HIGH)
+
+/* Chip Select */
+#define DF_nCS0_nCS2 MFP_CFG_LPM(DF_nCS0, AF3, PULL_HIGH)
+#define DF_nCS1_nCS3 MFP_CFG_LPM(DF_nCS1, AF3, PULL_HIGH)
+
+/* AC97 */
+#define GPIO83_BAC97_SYSCLK MFP_CFG(GPIO83, AF3)
+#define GPIO84_BAC97_SDATA_IN0 MFP_CFG(GPIO84, AF3)
+#define GPIO85_BAC97_BITCLK MFP_CFG(GPIO85, AF3)
+#define GPIO86_BAC97_nRESET MFP_CFG(GPIO86, AF3)
+#define GPIO87_BAC97_SYNC MFP_CFG(GPIO87, AF3)
+#define GPIO88_BAC97_SDATA_OUT MFP_CFG(GPIO88, AF3)
+
+/* I2C */
+#define GPIO39_CI2C_SCL MFP_CFG_LPM(GPIO39, AF3, PULL_HIGH)
+#define GPIO40_CI2C_SDA MFP_CFG_LPM(GPIO40, AF3, PULL_HIGH)
+
+#define GPIO51_CI2C_SCL MFP_CFG_LPM(GPIO51, AF3, PULL_HIGH)
+#define GPIO52_CI2C_SDA MFP_CFG_LPM(GPIO52, AF3, PULL_HIGH)
+
+#define GPIO63_CI2C_SCL MFP_CFG_LPM(GPIO63, AF4, PULL_HIGH)
+#define GPIO64_CI2C_SDA MFP_CFG_LPM(GPIO64, AF4, PULL_HIGH)
+
+#define GPIO73_CI2C_SCL MFP_CFG_LPM(GPIO73, AF1, PULL_HIGH)
+#define GPIO74_CI2C_SDA MFP_CFG_LPM(GPIO74, AF1, PULL_HIGH)
+
+#define GPIO77_CI2C_SCL MFP_CFG_LPM(GPIO77, AF2, PULL_HIGH)
+#define GPIO78_CI2C_SDA MFP_CFG_LPM(GPIO78, AF2, PULL_HIGH)
+
+#define GPIO89_CI2C_SCL MFP_CFG_LPM(GPIO89, AF1, PULL_HIGH)
+#define GPIO90_CI2C_SDA MFP_CFG_LPM(GPIO90, AF1, PULL_HIGH)
+
+#define GPIO95_CI2C_SCL MFP_CFG_LPM(GPIO95, AF1, PULL_HIGH)
+#define GPIO96_CI2C_SDA MFP_CFG_LPM(GPIO96, AF1, PULL_HIGH)
+
+#define GPIO97_CI2C_SCL MFP_CFG_LPM(GPIO97, AF3, PULL_HIGH)
+#define GPIO98_CI2C_SDA MFP_CFG_LPM(GPIO98, AF3, PULL_HIGH)
+
+/* QCI */
+#define GPIO63_CI_DD_9 MFP_CFG_LPM(GPIO63, AF1, PULL_LOW)
+#define GPIO64_CI_DD_8 MFP_CFG_LPM(GPIO64, AF1, PULL_LOW)
+#define GPIO65_CI_DD_7 MFP_CFG_LPM(GPIO65, AF1, PULL_LOW)
+#define GPIO66_CI_DD_6 MFP_CFG_LPM(GPIO66, AF1, PULL_LOW)
+#define GPIO67_CI_DD_5 MFP_CFG_LPM(GPIO67, AF1, PULL_LOW)
+#define GPIO68_CI_DD_4 MFP_CFG_LPM(GPIO68, AF1, PULL_LOW)
+#define GPIO69_CI_DD_3 MFP_CFG_LPM(GPIO69, AF1, PULL_LOW)
+#define GPIO70_CI_DD_2 MFP_CFG_LPM(GPIO70, AF1, PULL_LOW)
+#define GPIO71_CI_DD_1 MFP_CFG_LPM(GPIO71, AF1, PULL_LOW)
+#define GPIO72_CI_DD_0 MFP_CFG_LPM(GPIO72, AF1, PULL_LOW)
+#define GPIO73_CI_HSYNC MFP_CFG_LPM(GPIO73, AF1, PULL_LOW)
+#define GPIO74_CI_VSYNC MFP_CFG_LPM(GPIO74, AF1, PULL_LOW)
+#define GPIO75_CI_MCLK MFP_CFG_LPM(GPIO75, AF1, PULL_LOW)
+#define GPIO76_CI_PCLK MFP_CFG_LPM(GPIO76, AF1, PULL_LOW)
+
+/* KEYPAD */
+#define GPIO4_KP_DKIN_4 MFP_CFG_LPM(GPIO4, AF3, FLOAT)
+#define GPIO5_KP_DKIN_5 MFP_CFG_LPM(GPIO5, AF3, FLOAT)
+#define GPIO6_KP_DKIN_6 MFP_CFG_LPM(GPIO6, AF3, FLOAT)
+#define GPIO7_KP_DKIN_7 MFP_CFG_LPM(GPIO7, AF3, FLOAT)
+#define GPIO8_KP_DKIN_4 MFP_CFG_LPM(GPIO8, AF3, FLOAT)
+#define GPIO9_KP_DKIN_5 MFP_CFG_LPM(GPIO9, AF3, FLOAT)
+#define GPIO10_KP_DKIN_6 MFP_CFG_LPM(GPIO10, AF3, FLOAT)
+#define GPIO11_KP_DKIN_7 MFP_CFG_LPM(GPIO11, AF3, FLOAT)
+
+#define GPIO12_KP_DKIN_0 MFP_CFG_LPM(GPIO12, AF2, FLOAT)
+#define GPIO13_KP_DKIN_1 MFP_CFG_LPM(GPIO13, AF2, FLOAT)
+#define GPIO14_KP_DKIN_2 MFP_CFG_LPM(GPIO14, AF2, FLOAT)
+#define GPIO15_KP_DKIN_3 MFP_CFG_LPM(GPIO15, AF2, FLOAT)
+
+#define GPIO41_KP_DKIN_0 MFP_CFG_LPM(GPIO41, AF2, FLOAT)
+#define GPIO42_KP_DKIN_1 MFP_CFG_LPM(GPIO42, AF2, FLOAT)
+#define GPIO43_KP_DKIN_2 MFP_CFG_LPM(GPIO43, AF2, FLOAT)
+#define GPIO44_KP_DKIN_3 MFP_CFG_LPM(GPIO44, AF2, FLOAT)
+#define GPIO41_KP_DKIN_4 MFP_CFG_LPM(GPIO41, AF4, FLOAT)
+#define GPIO42_KP_DKIN_5 MFP_CFG_LPM(GPIO42, AF4, FLOAT)
+
+#define GPIO0_KP_MKIN_0 MFP_CFG_LPM(GPIO0, AF1, FLOAT)
+#define GPIO2_KP_MKIN_1 MFP_CFG_LPM(GPIO2, AF1, FLOAT)
+#define GPIO4_KP_MKIN_2 MFP_CFG_LPM(GPIO4, AF1, FLOAT)
+#define GPIO6_KP_MKIN_3 MFP_CFG_LPM(GPIO6, AF1, FLOAT)
+#define GPIO8_KP_MKIN_4 MFP_CFG_LPM(GPIO8, AF1, FLOAT)
+#define GPIO10_KP_MKIN_5 MFP_CFG_LPM(GPIO10, AF1, FLOAT)
+#define GPIO12_KP_MKIN_6 MFP_CFG_LPM(GPIO12, AF1, FLOAT)
+#define GPIO14_KP_MKIN_7 MFP_CFG(GPIO14, AF1)
+#define GPIO35_KP_MKIN_5 MFP_CFG(GPIO35, AF4)
+
+#define GPIO1_KP_MKOUT_0 MFP_CFG_LPM(GPIO1, AF1, DRIVE_HIGH)
+#define GPIO3_KP_MKOUT_1 MFP_CFG_LPM(GPIO3, AF1, DRIVE_HIGH)
+#define GPIO5_KP_MKOUT_2 MFP_CFG_LPM(GPIO5, AF1, DRIVE_HIGH)
+#define GPIO7_KP_MKOUT_3 MFP_CFG_LPM(GPIO7, AF1, DRIVE_HIGH)
+#define GPIO9_KP_MKOUT_4 MFP_CFG_LPM(GPIO9, AF1, DRIVE_HIGH)
+#define GPIO11_KP_MKOUT_5 MFP_CFG_LPM(GPIO11, AF1, DRIVE_HIGH)
+#define GPIO13_KP_MKOUT_6 MFP_CFG_LPM(GPIO13, AF1, DRIVE_HIGH)
+#define GPIO15_KP_MKOUT_7 MFP_CFG_LPM(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO36_KP_MKOUT_5 MFP_CFG_LPM(GPIO36, AF4, DRIVE_HIGH)
+
+/* LCD */
+#define GPIO17_LCD_FCLK_RD MFP_CFG(GPIO17, AF1)
+#define GPIO18_LCD_LCLK_A0 MFP_CFG(GPIO18, AF1)
+#define GPIO19_LCD_PCLK_WR MFP_CFG(GPIO19, AF1)
+#define GPIO20_LCD_BIAS MFP_CFG(GPIO20, AF1)
+#define GPIO21_LCD_CS MFP_CFG(GPIO21, AF1)
+#define GPIO22_LCD_CS2 MFP_CFG(GPIO22, AF2)
+#define GPIO22_LCD_VSYNC MFP_CFG(GPIO22, AF1)
+#define GPIO23_LCD_DD0 MFP_CFG(GPIO23, AF1)
+#define GPIO24_LCD_DD1 MFP_CFG(GPIO24, AF1)
+#define GPIO25_LCD_DD2 MFP_CFG(GPIO25, AF1)
+#define GPIO26_LCD_DD3 MFP_CFG(GPIO26, AF1)
+#define GPIO27_LCD_DD4 MFP_CFG(GPIO27, AF1)
+#define GPIO28_LCD_DD5 MFP_CFG(GPIO28, AF1)
+#define GPIO29_LCD_DD6 MFP_CFG(GPIO29, AF1)
+#define GPIO30_LCD_DD7 MFP_CFG(GPIO30, AF1)
+#define GPIO31_LCD_DD8 MFP_CFG(GPIO31, AF1)
+#define GPIO32_LCD_DD9 MFP_CFG(GPIO32, AF1)
+#define GPIO33_LCD_DD10 MFP_CFG(GPIO33, AF1)
+#define GPIO34_LCD_DD11 MFP_CFG(GPIO34, AF1)
+#define GPIO35_LCD_DD12 MFP_CFG(GPIO35, AF1)
+#define GPIO36_LCD_DD13 MFP_CFG(GPIO36, AF1)
+#define GPIO37_LCD_DD14 MFP_CFG(GPIO37, AF1)
+#define GPIO38_LCD_DD15 MFP_CFG(GPIO38, AF1)
+#define GPIO39_LCD_DD16 MFP_CFG(GPIO39, AF1)
+#define GPIO40_LCD_DD17 MFP_CFG(GPIO40, AF1)
+#define GPIO41_LCD_CS2 MFP_CFG(GPIO41, AF3)
+#define GPIO42_LCD_VSYNC2 MFP_CFG(GPIO42, AF3)
+#define GPIO44_LCD_DD7 MFP_CFG(GPIO44, AF1)
+
+/* Mini-LCD */
+#define GPIO17_MLCD_FCLK MFP_CFG(GPIO17, AF3)
+#define GPIO18_MLCD_LCLK MFP_CFG(GPIO18, AF3)
+#define GPIO19_MLCD_PCLK MFP_CFG(GPIO19, AF3)
+#define GPIO20_MLCD_BIAS MFP_CFG(GPIO20, AF3)
+#define GPIO23_MLCD_DD0 MFP_CFG(GPIO23, AF3)
+#define GPIO24_MLCD_DD1 MFP_CFG(GPIO24, AF3)
+#define GPIO25_MLCD_DD2 MFP_CFG(GPIO25, AF3)
+#define GPIO26_MLCD_DD3 MFP_CFG(GPIO26, AF3)
+#define GPIO27_MLCD_DD4 MFP_CFG(GPIO27, AF3)
+#define GPIO28_MLCD_DD5 MFP_CFG(GPIO28, AF3)
+#define GPIO29_MLCD_DD6 MFP_CFG(GPIO29, AF3)
+#define GPIO30_MLCD_DD7 MFP_CFG(GPIO30, AF3)
+#define GPIO31_MLCD_DD8 MFP_CFG(GPIO31, AF3)
+#define GPIO32_MLCD_DD9 MFP_CFG(GPIO32, AF3)
+#define GPIO33_MLCD_DD10 MFP_CFG(GPIO33, AF3)
+#define GPIO34_MLCD_DD11 MFP_CFG(GPIO34, AF3)
+#define GPIO35_MLCD_DD12 MFP_CFG(GPIO35, AF3)
+#define GPIO36_MLCD_DD13 MFP_CFG(GPIO36, AF3)
+#define GPIO37_MLCD_DD14 MFP_CFG(GPIO37, AF3)
+#define GPIO38_MLCD_DD15 MFP_CFG(GPIO38, AF3)
+#define GPIO44_MLCD_DD7 MFP_CFG(GPIO44, AF5)
+
+/* MMC1 */
+#define GPIO10_MMC1_DAT3 MFP_CFG(GPIO10, AF4)
+#define GPIO11_MMC1_DAT2 MFP_CFG(GPIO11, AF4)
+#define GPIO12_MMC1_DAT1 MFP_CFG(GPIO12, AF4)
+#define GPIO13_MMC1_DAT0 MFP_CFG(GPIO13, AF4)
+#define GPIO14_MMC1_CMD MFP_CFG(GPIO14, AF4)
+#define GPIO15_MMC1_CLK MFP_CFG(GPIO15, AF4)
+#define GPIO55_MMC1_CMD MFP_CFG(GPIO55, AF3)
+#define GPIO56_MMC1_CLK MFP_CFG(GPIO56, AF3)
+#define GPIO57_MMC1_DAT0 MFP_CFG(GPIO57, AF3)
+#define GPIO58_MMC1_DAT1 MFP_CFG(GPIO58, AF3)
+#define GPIO59_MMC1_DAT2 MFP_CFG(GPIO59, AF3)
+#define GPIO60_MMC1_DAT3 MFP_CFG(GPIO60, AF3)
+
+#define DF_ADDR0_MMC1_CLK MFP_CFG(DF_ADDR0, AF2)
+#define DF_ADDR1_MMC1_CMD MFP_CFG(DF_ADDR1, AF2)
+#define DF_ADDR2_MMC1_DAT0 MFP_CFG(DF_ADDR2, AF2)
+#define DF_ADDR3_MMC1_DAT1 MFP_CFG(DF_ADDR3, AF3)
+#define nXCVREN_MMC1_DAT2 MFP_CFG(nXCVREN, AF2)
+
+/* MMC2 */
+#define GPIO31_MMC2_CMD MFP_CFG(GPIO31, AF7)
+#define GPIO32_MMC2_CLK MFP_CFG(GPIO32, AF7)
+#define GPIO33_MMC2_DAT0 MFP_CFG(GPIO33, AF7)
+#define GPIO34_MMC2_DAT1 MFP_CFG(GPIO34, AF7)
+#define GPIO35_MMC2_DAT2 MFP_CFG(GPIO35, AF7)
+#define GPIO36_MMC2_DAT3 MFP_CFG(GPIO36, AF7)
+
+#define GPIO101_MMC2_DAT3 MFP_CFG(GPIO101, AF1)
+#define GPIO102_MMC2_DAT2 MFP_CFG(GPIO102, AF1)
+#define GPIO103_MMC2_DAT1 MFP_CFG(GPIO103, AF1)
+#define GPIO104_MMC2_DAT0 MFP_CFG(GPIO104, AF1)
+#define GPIO105_MMC2_CMD MFP_CFG(GPIO105, AF1)
+#define GPIO106_MMC2_CLK MFP_CFG(GPIO106, AF1)
+
+#define DF_IO10_MMC2_DAT3 MFP_CFG(DF_IO10, AF3)
+#define DF_IO11_MMC2_DAT2 MFP_CFG(DF_IO11, AF3)
+#define DF_IO12_MMC2_DAT1 MFP_CFG(DF_IO12, AF3)
+#define DF_IO13_MMC2_DAT0 MFP_CFG(DF_IO13, AF3)
+#define DF_IO14_MMC2_CLK MFP_CFG(DF_IO14, AF3)
+#define DF_IO15_MMC2_CMD MFP_CFG(DF_IO15, AF3)
+
+/* BSSP1 */
+#define GPIO12_BSSP1_CLK MFP_CFG(GPIO12, AF3)
+#define GPIO13_BSSP1_FRM MFP_CFG(GPIO13, AF3)
+#define GPIO14_BSSP1_RXD MFP_CFG(GPIO14, AF3)
+#define GPIO15_BSSP1_TXD MFP_CFG(GPIO15, AF3)
+#define GPIO97_BSSP1_CLK MFP_CFG(GPIO97, AF5)
+#define GPIO98_BSSP1_FRM MFP_CFG(GPIO98, AF5)
+
+/* BSSP2 */
+#define GPIO84_BSSP2_SDATA_IN MFP_CFG(GPIO84, AF1)
+#define GPIO85_BSSP2_BITCLK MFP_CFG(GPIO85, AF1)
+#define GPIO86_BSSP2_SYSCLK MFP_CFG(GPIO86, AF1)
+#define GPIO87_BSSP2_SYNC MFP_CFG(GPIO87, AF1)
+#define GPIO88_BSSP2_DATA_OUT MFP_CFG(GPIO88, AF1)
+#define GPIO86_BSSP2_SDATA_IN MFP_CFG(GPIO86, AF4)
+
+/* BSSP3 */
+#define GPIO79_BSSP3_CLK MFP_CFG(GPIO79, AF1)
+#define GPIO80_BSSP3_FRM MFP_CFG(GPIO80, AF1)
+#define GPIO81_BSSP3_TXD MFP_CFG(GPIO81, AF1)
+#define GPIO82_BSSP3_RXD MFP_CFG(GPIO82, AF1)
+#define GPIO83_BSSP3_SYSCLK MFP_CFG(GPIO83, AF1)
+
+/* BSSP4 */
+#define GPIO43_BSSP4_CLK MFP_CFG(GPIO43, AF4)
+#define GPIO44_BSSP4_FRM MFP_CFG(GPIO44, AF4)
+#define GPIO45_BSSP4_TXD MFP_CFG(GPIO45, AF4)
+#define GPIO46_BSSP4_RXD MFP_CFG(GPIO46, AF4)
+
+#define GPIO51_BSSP4_CLK MFP_CFG(GPIO51, AF4)
+#define GPIO52_BSSP4_FRM MFP_CFG(GPIO52, AF4)
+#define GPIO53_BSSP4_TXD MFP_CFG(GPIO53, AF4)
+#define GPIO54_BSSP4_RXD MFP_CFG(GPIO54, AF4)
+
+/* GSSP1 */
+#define GPIO79_GSSP1_CLK MFP_CFG(GPIO79, AF2)
+#define GPIO80_GSSP1_FRM MFP_CFG(GPIO80, AF2)
+#define GPIO81_GSSP1_TXD MFP_CFG(GPIO81, AF2)
+#define GPIO82_GSSP1_RXD MFP_CFG(GPIO82, AF2)
+#define GPIO83_GSSP1_SYSCLK MFP_CFG(GPIO83, AF2)
+
+#define GPIO93_GSSP1_CLK MFP_CFG(GPIO93, AF4)
+#define GPIO94_GSSP1_FRM MFP_CFG(GPIO94, AF4)
+#define GPIO95_GSSP1_TXD MFP_CFG(GPIO95, AF4)
+#define GPIO96_GSSP1_RXD MFP_CFG(GPIO96, AF4)
+
+/* GSSP2 */
+#define GPIO47_GSSP2_CLK MFP_CFG(GPIO47, AF4)
+#define GPIO48_GSSP2_FRM MFP_CFG(GPIO48, AF4)
+#define GPIO49_GSSP2_RXD MFP_CFG(GPIO49, AF4)
+#define GPIO50_GSSP2_TXD MFP_CFG(GPIO50, AF4)
+
+#define GPIO69_GSSP2_CLK MFP_CFG(GPIO69, AF4)
+#define GPIO70_GSSP2_FRM MFP_CFG(GPIO70, AF4)
+#define GPIO71_GSSP2_RXD MFP_CFG(GPIO71, AF4)
+#define GPIO72_GSSP2_TXD MFP_CFG(GPIO72, AF4)
+
+#define GPIO84_GSSP2_RXD MFP_CFG(GPIO84, AF2)
+#define GPIO85_GSSP2_CLK MFP_CFG(GPIO85, AF2)
+#define GPIO86_GSSP2_SYSCLK MFP_CFG(GPIO86, AF2)
+#define GPIO87_GSSP2_FRM MFP_CFG(GPIO87, AF2)
+#define GPIO88_GSSP2_TXD MFP_CFG(GPIO88, AF2)
+#define GPIO86_GSSP2_RXD MFP_CFG(GPIO86, AF5)
+
+#define GPIO103_GSSP2_CLK MFP_CFG(GPIO103, AF2)
+#define GPIO104_GSSP2_FRM MFP_CFG(GPIO104, AF2)
+#define GPIO105_GSSP2_RXD MFP_CFG(GPIO105, AF2)
+#define GPIO106_GSSP2_TXD MFP_CFG(GPIO106, AF2)
+
+/* UART1 - FFUART */
+#define GPIO47_UART1_DSR_N MFP_CFG(GPIO47, AF1)
+#define GPIO48_UART1_DTR_N MFP_CFG(GPIO48, AF1)
+#define GPIO49_UART1_RI MFP_CFG(GPIO49, AF1)
+#define GPIO50_UART1_DCD MFP_CFG(GPIO50, AF1)
+#define GPIO51_UART1_CTS MFP_CFG(GPIO51, AF1)
+#define GPIO52_UART1_RTS MFP_CFG(GPIO52, AF1)
+#define GPIO53_UART1_RXD MFP_CFG(GPIO53, AF1)
+#define GPIO54_UART1_TXD MFP_CFG(GPIO54, AF1)
+
+#define GPIO63_UART1_TXD MFP_CFG(GPIO63, AF2)
+#define GPIO64_UART1_RXD MFP_CFG(GPIO64, AF2)
+#define GPIO65_UART1_DSR MFP_CFG(GPIO65, AF2)
+#define GPIO66_UART1_DTR MFP_CFG(GPIO66, AF2)
+#define GPIO67_UART1_RI MFP_CFG(GPIO67, AF2)
+#define GPIO68_UART1_DCD MFP_CFG(GPIO68, AF2)
+#define GPIO69_UART1_CTS MFP_CFG(GPIO69, AF2)
+#define GPIO70_UART1_RTS MFP_CFG(GPIO70, AF2)
+
+#define GPIO53_UART1_TXD MFP_CFG(GPIO53, AF2)
+#define GPIO54_UART1_RXD MFP_CFG(GPIO54, AF2)
+
+/* UART2 - BTUART */
+#define GPIO91_UART2_RXD MFP_CFG(GPIO91, AF1)
+#define GPIO92_UART2_TXD MFP_CFG(GPIO92, AF1)
+#define GPIO93_UART2_CTS MFP_CFG(GPIO93, AF1)
+#define GPIO94_UART2_RTS MFP_CFG(GPIO94, AF1)
+
+/* UART3 - STUART */
+#define GPIO43_UART3_RTS MFP_CFG(GPIO43, AF3)
+#define GPIO44_UART3_CTS MFP_CFG(GPIO44, AF3)
+#define GPIO45_UART3_RXD MFP_CFG(GPIO45, AF3)
+#define GPIO46_UART3_TXD MFP_CFG(GPIO46, AF3)
+
+#define GPIO75_UART3_RTS MFP_CFG(GPIO75, AF5)
+#define GPIO76_UART3_CTS MFP_CFG(GPIO76, AF5)
+#define GPIO77_UART3_TXD MFP_CFG(GPIO77, AF5)
+#define GPIO78_UART3_RXD MFP_CFG(GPIO78, AF5)
+
+/* DFI */
+#define DF_IO0_DF_IO0 MFP_CFG(DF_IO0, AF2)
+#define DF_IO1_DF_IO1 MFP_CFG(DF_IO1, AF2)
+#define DF_IO2_DF_IO2 MFP_CFG(DF_IO2, AF2)
+#define DF_IO3_DF_IO3 MFP_CFG(DF_IO3, AF2)
+#define DF_IO4_DF_IO4 MFP_CFG(DF_IO4, AF2)
+#define DF_IO5_DF_IO5 MFP_CFG(DF_IO5, AF2)
+#define DF_IO6_DF_IO6 MFP_CFG(DF_IO6, AF2)
+#define DF_IO7_DF_IO7 MFP_CFG(DF_IO7, AF2)
+#define DF_IO8_DF_IO8 MFP_CFG(DF_IO8, AF2)
+#define DF_IO9_DF_IO9 MFP_CFG(DF_IO9, AF2)
+#define DF_IO10_DF_IO10 MFP_CFG(DF_IO10, AF2)
+#define DF_IO11_DF_IO11 MFP_CFG(DF_IO11, AF2)
+#define DF_IO12_DF_IO12 MFP_CFG(DF_IO12, AF2)
+#define DF_IO13_DF_IO13 MFP_CFG(DF_IO13, AF2)
+#define DF_IO14_DF_IO14 MFP_CFG(DF_IO14, AF2)
+#define DF_IO15_DF_IO15 MFP_CFG(DF_IO15, AF2)
+#define DF_nADV1_ALE_DF_nADV1 MFP_CFG(DF_nADV1_ALE, AF2)
+#define DF_nADV2_ALE_DF_nADV2 MFP_CFG(DF_nADV2_ALE, AF2)
+#define DF_nCS0_DF_nCS0 MFP_CFG(DF_nCS0, AF2)
+#define DF_nCS1_DF_nCS1 MFP_CFG(DF_nCS1, AF2)
+#define DF_nRE_nOE_DF_nOE MFP_CFG(DF_nRE_nOE, AF2)
+#define DF_nWE_DF_nWE MFP_CFG(DF_nWE, AF2)
+
+/* DFI - NAND */
+#define DF_CLE_nOE_ND_CLE MFP_CFG_LPM(DF_CLE_nOE, AF1, PULL_HIGH)
+#define DF_INT_RnB_ND_INT_RnB MFP_CFG_LPM(DF_INT_RnB, AF1, PULL_LOW)
+#define DF_IO0_ND_IO0 MFP_CFG_LPM(DF_IO0, AF1, PULL_LOW)
+#define DF_IO1_ND_IO1 MFP_CFG_LPM(DF_IO1, AF1, PULL_LOW)
+#define DF_IO2_ND_IO2 MFP_CFG_LPM(DF_IO2, AF1, PULL_LOW)
+#define DF_IO3_ND_IO3 MFP_CFG_LPM(DF_IO3, AF1, PULL_LOW)
+#define DF_IO4_ND_IO4 MFP_CFG_LPM(DF_IO4, AF1, PULL_LOW)
+#define DF_IO5_ND_IO5 MFP_CFG_LPM(DF_IO5, AF1, PULL_LOW)
+#define DF_IO6_ND_IO6 MFP_CFG_LPM(DF_IO6, AF1, PULL_LOW)
+#define DF_IO7_ND_IO7 MFP_CFG_LPM(DF_IO7, AF1, PULL_LOW)
+#define DF_IO8_ND_IO8 MFP_CFG_LPM(DF_IO8, AF1, PULL_LOW)
+#define DF_IO9_ND_IO9 MFP_CFG_LPM(DF_IO9, AF1, PULL_LOW)
+#define DF_IO10_ND_IO10 MFP_CFG_LPM(DF_IO10, AF1, PULL_LOW)
+#define DF_IO11_ND_IO11 MFP_CFG_LPM(DF_IO11, AF1, PULL_LOW)
+#define DF_IO12_ND_IO12 MFP_CFG_LPM(DF_IO12, AF1, PULL_LOW)
+#define DF_IO13_ND_IO13 MFP_CFG_LPM(DF_IO13, AF1, PULL_LOW)
+#define DF_IO14_ND_IO14 MFP_CFG_LPM(DF_IO14, AF1, PULL_LOW)
+#define DF_IO15_ND_IO15 MFP_CFG_LPM(DF_IO15, AF1, PULL_LOW)
+#define DF_nADV1_ALE_ND_ALE MFP_CFG_LPM(DF_nADV1_ALE, AF1, PULL_HIGH)
+#define DF_nADV2_ALE_ND_ALE MFP_CFG_LPM(DF_nADV2_ALE, AF1, PULL_HIGH)
+#define DF_nADV2_ALE_nCS3 MFP_CFG_LPM(DF_nADV2_ALE, AF3, PULL_HIGH)
+#define DF_nCS0_ND_nCS0 MFP_CFG_LPM(DF_nCS0, AF1, PULL_HIGH)
+#define DF_nCS1_ND_nCS1 MFP_CFG_LPM(DF_nCS1, AF1, PULL_HIGH)
+#define DF_nRE_nOE_ND_nRE MFP_CFG_LPM(DF_nRE_nOE, AF1, PULL_HIGH)
+#define DF_nWE_ND_nWE MFP_CFG_LPM(DF_nWE, AF1, PULL_HIGH)
+
+/* PWM */
+#define GPIO41_PWM0 MFP_CFG_LPM(GPIO41, AF1, PULL_LOW)
+#define GPIO42_PWM1 MFP_CFG_LPM(GPIO42, AF1, PULL_LOW)
+#define GPIO43_PWM3 MFP_CFG_LPM(GPIO43, AF1, PULL_LOW)
+#define GPIO20_PWM0 MFP_CFG_LPM(GPIO20, AF2, PULL_LOW)
+#define GPIO21_PWM2 MFP_CFG_LPM(GPIO21, AF3, PULL_LOW)
+#define GPIO22_PWM3 MFP_CFG_LPM(GPIO22, AF3, PULL_LOW)
+#define GPIO32_PWM0 MFP_CFG_LPM(GPIO32, AF4, PULL_LOW)
+
+/* CIR */
+#define GPIO46_CIR_OUT MFP_CFG(GPIO46, AF1)
+#define GPIO77_CIR_OUT MFP_CFG(GPIO77, AF3)
+
+/* USB P2 */
+#define GPIO0_USB_P2_7 MFP_CFG(GPIO0, AF3)
+#define GPIO15_USB_P2_7 MFP_CFG(GPIO15, AF5)
+#define GPIO16_USB_P2_7 MFP_CFG(GPIO16, AF2)
+#define GPIO48_USB_P2_7 MFP_CFG(GPIO48, AF7)
+#define GPIO49_USB_P2_7 MFP_CFG(GPIO49, AF6)
+#define DF_IO9_USB_P2_7 MFP_CFG(DF_IO9, AF3)
+
+#define GPIO48_USB_P2_8 MFP_CFG(GPIO48, AF2)
+#define GPIO50_USB_P2_7 MFP_CFG_X(GPIO50, AF2, DS02X, FLOAT)
+#define GPIO51_USB_P2_5 MFP_CFG(GPIO51, AF2)
+#define GPIO47_USB_P2_4 MFP_CFG(GPIO47, AF2)
+#define GPIO53_USB_P2_3 MFP_CFG(GPIO53, AF2)
+#define GPIO54_USB_P2_6 MFP_CFG(GPIO54, AF2)
+#define GPIO49_USB_P2_2 MFP_CFG(GPIO49, AF2)
+#define GPIO52_USB_P2_1 MFP_CFG(GPIO52, AF2)
+
+#define GPIO63_USB_P2_8 MFP_CFG(GPIO63, AF3)
+#define GPIO64_USB_P2_7 MFP_CFG(GPIO64, AF3)
+#define GPIO65_USB_P2_6 MFP_CFG(GPIO65, AF3)
+#define GPIO66_USG_P2_5 MFP_CFG(GPIO66, AF3)
+#define GPIO67_USB_P2_4 MFP_CFG(GPIO67, AF3)
+#define GPIO68_USB_P2_3 MFP_CFG(GPIO68, AF3)
+#define GPIO69_USB_P2_2 MFP_CFG(GPIO69, AF3)
+#define GPIO70_USB_P2_1 MFP_CFG(GPIO70, AF3)
+
+/* ULPI */
+#define GPIO31_USB_ULPI_D0 MFP_CFG(GPIO31, AF4)
+#define GPIO30_USB_ULPI_D1 MFP_CFG(GPIO30, AF7)
+#define GPIO33_USB_ULPI_D2 MFP_CFG(GPIO33, AF5)
+#define GPIO34_USB_ULPI_D3 MFP_CFG(GPIO34, AF5)
+#define GPIO35_USB_ULPI_D4 MFP_CFG(GPIO35, AF5)
+#define GPIO36_USB_ULPI_D5 MFP_CFG(GPIO36, AF5)
+#define GPIO41_USB_ULPI_D6 MFP_CFG(GPIO41, AF5)
+#define GPIO42_USB_ULPI_D7 MFP_CFG(GPIO42, AF5)
+#define GPIO37_USB_ULPI_DIR MFP_CFG(GPIO37, AF4)
+#define GPIO38_USB_ULPI_CLK MFP_CFG(GPIO38, AF4)
+#define GPIO39_USB_ULPI_STP MFP_CFG(GPIO39, AF4)
+#define GPIO40_USB_ULPI_NXT MFP_CFG(GPIO40, AF4)
+
+#define GPIO3_CLK26MOUTDMD MFP_CFG(GPIO3, AF3)
+#define GPIO40_CLK26MOUTDMD MFP_CFG(GPIO40, AF7)
+#define GPIO94_CLK26MOUTDMD MFP_CFG(GPIO94, AF5)
+#define GPIO104_CLK26MOUTDMD MFP_CFG(GPIO104, AF4)
+#define DF_ADDR1_CLK26MOUTDMD MFP_CFG(DF_ADDR2, AF3)
+#define DF_ADDR3_CLK26MOUTDMD MFP_CFG(DF_ADDR3, AF3)
+
+#define GPIO14_CLK26MOUT MFP_CFG(GPIO14, AF5)
+#define GPIO38_CLK26MOUT MFP_CFG(GPIO38, AF7)
+#define GPIO92_CLK26MOUT MFP_CFG(GPIO92, AF5)
+#define GPIO105_CLK26MOUT MFP_CFG(GPIO105, AF4)
+
+#define GPIO2_CLK13MOUTDMD MFP_CFG(GPIO2, AF3)
+#define GPIO39_CLK13MOUTDMD MFP_CFG(GPIO39, AF7)
+#define GPIO50_CLK13MOUTDMD MFP_CFG(GPIO50, AF3)
+#define GPIO93_CLK13MOUTDMD MFP_CFG(GPIO93, AF5)
+#define GPIO103_CLK13MOUTDMD MFP_CFG(GPIO103, AF4)
+#define DF_ADDR2_CLK13MOUTDMD MFP_CFG(DF_ADDR2, AF3)
+
+/* 1 wire */
+#define GPIO95_OW_DQ_IN MFP_CFG(GPIO95, AF5)
+
+#endif /* __ASM_ARCH_MFP_PXA9xx_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp.h b/arch/arm/mach-pxa/include/mach/mfp.h
new file mode 100644
index 00000000..271e249a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp.h
+ *
+ * Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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_MFP_H
+#define __ASM_ARCH_MFP_H
+
+#include <plat/mfp.h>
+
+#endif /* __ASM_ARCH_MFP_H */
diff --git a/arch/arm/mach-pxa/include/mach/mioa701.h b/arch/arm/mach-pxa/include/mach/mioa701.h
new file mode 100644
index 00000000..02868447
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mioa701.h
@@ -0,0 +1,72 @@
+#ifndef _MIOA701_H_
+#define _MIOA701_H_
+
+#define MIO_CFG_IN(pin, af) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+ (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN))
+
+#define MIO_CFG_OUT(pin, af, state) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Global GPIOs */
+#define GPIO9_CHARGE_EN 9
+#define GPIO18_POWEROFF 18
+#define GPIO87_LCD_POWER 87
+#define GPIO96_AC_DETECT 96
+#define GPIO80_MAYBE_CHARGE_VDROP 80 /* Drop of 88mV */
+
+/* USB */
+#define GPIO13_nUSB_DETECT 13
+#define GPIO22_USB_ENABLE 22
+
+/* SDIO bits */
+#define GPIO78_SDIO_RO 78
+#define GPIO15_SDIO_INSERT 15
+#define GPIO91_SDIO_EN 91
+
+/* Bluetooth */
+#define GPIO14_BT_nACTIVITY 14
+#define GPIO83_BT_ON 83
+#define GPIO77_BT_UNKNOWN1 77
+#define GPIO86_BT_MAYBE_nRESET 86
+
+/* GPS */
+#define GPIO23_GPS_UNKNOWN1 23
+#define GPIO26_GPS_ON 26
+#define GPIO27_GPS_RESET 27
+#define GPIO106_GPS_UNKNOWN2 106
+#define GPIO107_GPS_UNKNOWN3 107
+
+/* GSM */
+#define GPIO24_GSM_MOD_RESET_CMD 24
+#define GPIO88_GSM_nMOD_ON_CMD 88
+#define GPIO90_GSM_nMOD_OFF_CMD 90
+#define GPIO114_GSM_nMOD_DTE_UART_STATE 114
+#define GPIO25_GSM_MOD_ON_STATE 25
+#define GPIO113_GSM_EVENT 113
+
+/* SOUND */
+#define GPIO12_HPJACK_INSERT 12
+
+/* LEDS */
+#define GPIO10_LED_nCharging 10
+#define GPIO97_LED_nBlue 97
+#define GPIO98_LED_nOrange 98
+#define GPIO82_LED_nVibra 82
+#define GPIO115_LED_nKeyboard 115
+
+/* Keyboard */
+#define GPIO0_KEY_POWER 0
+#define GPIO93_KEY_VOLUME_UP 93
+#define GPIO94_KEY_VOLUME_DOWN 94
+
+extern struct input_dev *mioa701_evdev;
+extern void mioa701_gpio_lpm_set(unsigned long mfp_pin);
+
+/* Assembler externals mioa701_bootresume.S */
+extern u32 mioa701_bootstrap;
+extern u32 mioa701_jumpaddr;
+extern u32 mioa701_bootstrap_lg;
+
+#endif /* _MIOA701_H */
diff --git a/arch/arm/mach-pxa/include/mach/mmc.h b/arch/arm/mach-pxa/include/mach/mmc.h
new file mode 100644
index 00000000..9eb515bb
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mmc.h
@@ -0,0 +1,28 @@
+#ifndef ASMARM_ARCH_MMC_H
+#define ASMARM_ARCH_MMC_H
+
+#include <linux/mmc/host.h>
+#include <linux/interrupt.h>
+
+struct device;
+struct mmc_host;
+
+struct pxamci_platform_data {
+ unsigned int ocr_mask; /* available voltages */
+ unsigned long detect_delay_ms; /* delay in millisecond before detecting cards after interrupt */
+ int (*init)(struct device *, irq_handler_t , void *);
+ int (*get_ro)(struct device *);
+ void (*setpower)(struct device *, unsigned int);
+ void (*exit)(struct device *, void *);
+ int gpio_card_detect; /* gpio detecting card insertion */
+ int gpio_card_ro; /* gpio detecting read only toggle */
+ bool gpio_card_ro_invert; /* gpio ro is inverted */
+ int gpio_power; /* gpio powering up MMC bus */
+ bool gpio_power_invert; /* gpio power is inverted */
+};
+
+extern void pxa_set_mci_info(struct pxamci_platform_data *info);
+extern void pxa3xx_set_mci2_info(struct pxamci_platform_data *info);
+extern void pxa3xx_set_mci3_info(struct pxamci_platform_data *info);
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h
new file mode 100644
index 00000000..297387ec
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mtd-xip.h
@@ -0,0 +1,36 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 2, 2004
+ * Copyright: (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_PXA_MTD_XIP_H__
+#define __ARCH_PXA_MTD_XIP_H__
+
+#include <mach/regs-ost.h>
+#include <mach/regs-intc.h>
+
+#define xip_irqpending() (ICIP & ICMR)
+
+/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
+#define xip_currtime() (OSCR)
+#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4)
+
+/*
+ * xip_cpu_idle() is used when waiting for a delay equal or larger than
+ * the system timer tick period. This should put the CPU into idle mode
+ * to save power and to be woken up only when some interrupts are pending.
+ * As above, this should not rely upon standard kernel code.
+ */
+
+#define xip_cpu_idle() asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1))
+
+#endif /* __ARCH_PXA_MTD_XIP_H__ */
diff --git a/arch/arm/mach-pxa/include/mach/mxm8x10.h b/arch/arm/mach-pxa/include/mach/mxm8x10.h
new file mode 100644
index 00000000..ffa15665
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mxm8x10.h
@@ -0,0 +1,21 @@
+#ifndef __MACH_MXM_8X10_H
+#define __MACH_MXM_8X10_H
+
+#define MXM_8X10_ETH_PHYS 0x13000000
+
+#if defined(CONFIG_MMC)
+
+#define MXM_8X10_SD_nCD (72)
+#define MXM_8X10_SD_WP (84)
+
+extern void mxm_8x10_mmc_init(void);
+#else
+static inline void mxm_8x10_mmc_init(void) {}
+#endif
+
+extern void mxm_8x10_usb_host_init(void);
+extern void mxm_8x10_ac97_init(void);
+
+extern void mxm_8x10_barebones_init(void);
+
+#endif /* __MACH_MXM_8X10_H */
diff --git a/arch/arm/mach-pxa/include/mach/ohci.h b/arch/arm/mach-pxa/include/mach/ohci.h
new file mode 100644
index 00000000..95b6e2a6
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/ohci.h
@@ -0,0 +1,36 @@
+#ifndef ASMARM_ARCH_OHCI_H
+#define ASMARM_ARCH_OHCI_H
+
+struct device;
+
+struct pxaohci_platform_data {
+ int (*init)(struct device *);
+ void (*exit)(struct device *);
+
+ unsigned long flags;
+#define ENABLE_PORT1 (1 << 0)
+#define ENABLE_PORT2 (1 << 1)
+#define ENABLE_PORT3 (1 << 2)
+#define ENABLE_PORT_ALL (ENABLE_PORT1 | ENABLE_PORT2 | ENABLE_PORT3)
+
+#define POWER_SENSE_LOW (1 << 3)
+#define POWER_CONTROL_LOW (1 << 4)
+#define NO_OC_PROTECTION (1 << 5)
+#define OC_MODE_GLOBAL (0 << 6)
+#define OC_MODE_PERPORT (1 << 6)
+
+ int power_on_delay; /* Power On to Power Good time - in ms
+ * HCD must wait for this duration before
+ * accessing a powered on port
+ */
+ int port_mode;
+#define PMM_NPS_MODE 1
+#define PMM_GLOBAL_MODE 2
+#define PMM_PERPORT_MODE 3
+
+ int power_budget;
+};
+
+extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palm27x.h b/arch/arm/mach-pxa/include/mach/palm27x.h
new file mode 100644
index 00000000..8d560437
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palm27x.h
@@ -0,0 +1,81 @@
+/*
+ * Common functions for Palm LD, T5, TX, Z72
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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 __INCLUDE_MACH_PALM27X__
+#define __INCLUDE_MACH_PALM27X__
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+extern void __init palm27x_mmc_init(int detect, int ro, int power,
+ int power_inverted);
+#else
+static inline void palm27x_mmc_init(int detect, int ro, int power,
+ int power_inverted)
+{}
+#endif
+
+#if defined(CONFIG_SUSPEND)
+extern void __init palm27x_pm_init(unsigned long str_base);
+#else
+static inline void palm27x_pm_init(unsigned long str_base) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+extern struct pxafb_mode_info palm_320x480_lcd_mode;
+extern struct pxafb_mode_info palm_320x320_lcd_mode;
+extern struct pxafb_mode_info palm_320x320_new_lcd_mode;
+extern void __init palm27x_lcd_init(int power,
+ struct pxafb_mode_info *mode);
+#else
+static inline void palm27x_lcd_init(int power, struct pxafb_mode_info *mode) {}
+#endif
+
+#if defined(CONFIG_USB_PXA27X) || \
+ defined(CONFIG_USB_PXA27X_MODULE)
+extern void __init palm27x_udc_init(int vbus, int pullup,
+ int vbus_inverted);
+#else
+static inline void palm27x_udc_init(int vbus, int pullup, int vbus_inverted) {}
+#endif
+
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
+extern void __init palm27x_irda_init(int pwdn);
+#else
+static inline void palm27x_irda_init(int pwdn) {}
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_WM97XX) || \
+ defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
+extern void __init palm27x_ac97_init(int minv, int maxv, int jack,
+ int reset);
+#else
+static inline void palm27x_ac97_init(int minv, int maxv, int jack, int reset) {}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+extern void __init palm27x_pwm_init(int bl, int lcd);
+#else
+static inline void palm27x_pwm_init(int bl, int lcd) {}
+#endif
+
+#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
+extern void __init palm27x_power_init(int ac, int usb);
+#else
+static inline void palm27x_power_init(int ac, int usb) {}
+#endif
+
+#if defined(CONFIG_REGULATOR_MAX1586) || \
+ defined(CONFIG_REGULATOR_MAX1586_MODULE)
+extern void __init palm27x_pmic_init(void);
+#else
+static inline void palm27x_pmic_init(void) {}
+#endif
+
+#endif /* __INCLUDE_MACH_PALM27X__ */
diff --git a/arch/arm/mach-pxa/include/mach/palmasoc.h b/arch/arm/mach-pxa/include/mach/palmasoc.h
new file mode 100644
index 00000000..58afb30d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmasoc.h
@@ -0,0 +1,8 @@
+#ifndef _INCLUDE_PALMASOC_H_
+#define _INCLUDE_PALMASOC_H_
+
+struct palm27x_asoc_info {
+ int jack_gpio;
+};
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmld.h b/arch/arm/mach-pxa/include/mach/palmld.h
new file mode 100644
index 00000000..ae536e86
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmld.h
@@ -0,0 +1,109 @@
+/*
+ * GPIOs and interrupts for Palm LifeDrive Handheld Computer
+ *
+ * Authors: Alex Osborne <ato@meshy.org>
+ * Marek Vasut <marek.vasut@gmail.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 _INCLUDE_PALMLD_H_
+#define _INCLUDE_PALMLD_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMLD_GPIO_RESET 1
+#define GPIO_NR_PALMLD_POWER_DETECT 4
+#define GPIO_NR_PALMLD_HOTSYNC_BUTTON_N 10
+#define GPIO_NR_PALMLD_POWER_SWITCH 12
+#define GPIO_NR_PALMLD_EARPHONE_DETECT 13
+#define GPIO_NR_PALMLD_LOCK_SWITCH 15
+
+/* SD/MMC */
+#define GPIO_NR_PALMLD_SD_DETECT_N 14
+#define GPIO_NR_PALMLD_SD_POWER 114
+#define GPIO_NR_PALMLD_SD_READONLY 116
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMLD_WM9712_IRQ 27
+
+/* IRDA */
+#define GPIO_NR_PALMLD_IR_DISABLE 108
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMLD_BL_POWER 19
+#define GPIO_NR_PALMLD_LCD_POWER 96
+
+/* LCD BORDER */
+#define GPIO_NR_PALMLD_BORDER_SWITCH 21
+#define GPIO_NR_PALMLD_BORDER_SELECT 22
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMLD_BT_POWER 17
+#define GPIO_NR_PALMLD_BT_RESET 83
+
+/* PCMCIA (WiFi) */
+#define GPIO_NR_PALMLD_PCMCIA_READY 38
+#define GPIO_NR_PALMLD_PCMCIA_POWER 36
+#define GPIO_NR_PALMLD_PCMCIA_RESET 81
+
+/* LEDs */
+#define GPIO_NR_PALMLD_LED_GREEN 52
+#define GPIO_NR_PALMLD_LED_AMBER 94
+
+/* IDE */
+#define GPIO_NR_PALMLD_IDE_RESET 98
+#define GPIO_NR_PALMLD_IDE_PWEN 115
+
+/* USB */
+#define GPIO_NR_PALMLD_USB_DETECT_N 3
+#define GPIO_NR_PALMLD_USB_READY 86
+#define GPIO_NR_PALMLD_USB_RESET 88
+#define GPIO_NR_PALMLD_USB_INT 106
+#define GPIO_NR_PALMLD_USB_POWER 118
+/* 20, 53 and 86 are usb related too */
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMLD_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMLD_GPIO_RESET)
+#define IRQ_GPIO_PALMLD_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMLD_SD_DETECT_N)
+#define IRQ_GPIO_PALMLD_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMLD_WM9712_IRQ)
+#define IRQ_GPIO_PALMLD_IDE_IRQ IRQ_GPIO(GPIO_NR_PALMLD_IDE_IRQ)
+
+
+/** HERE ARE INIT VALUES **/
+
+/* IO mappings */
+#define PALMLD_USB_PHYS PXA_CS2_PHYS
+#define PALMLD_USB_VIRT 0xf0000000
+#define PALMLD_USB_SIZE 0x00100000
+
+#define PALMLD_IDE_PHYS 0x20000000
+#define PALMLD_IDE_VIRT 0xf1000000
+#define PALMLD_IDE_SIZE 0x00100000
+
+#define PALMLD_PHYS_IO_START 0x40000000
+#define PALMLD_STR_BASE 0xa0200000
+
+/* BATTERY */
+#define PALMLD_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */
+#define PALMLD_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */
+#define PALMLD_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMLD_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMLD_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMLD_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMLD_MAX_LIFE_MINS 240 /* on-life in minutes */
+
+#define PALMLD_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMLD_MAX_INTENSITY 0xFE
+#define PALMLD_DEFAULT_INTENSITY 0x7E
+#define PALMLD_LIMIT_MASK 0x7F
+#define PALMLD_PRESCALER 0x3F
+#define PALMLD_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmt5.h b/arch/arm/mach-pxa/include/mach/palmt5.h
new file mode 100644
index 00000000..6baf7469
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmt5.h
@@ -0,0 +1,84 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|T5 Handheld Computer
+ *
+ * Authors: Ales Snuparek <snuparek@atlas.cz>
+ * Marek Vasut <marek.vasut@gmail.com>
+ * Justin Kendrick <twilightsentry@gmail.com>
+ * RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can 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 _INCLUDE_PALMT5_H_
+#define _INCLUDE_PALMT5_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMT5_GPIO_RESET 1
+
+#define GPIO_NR_PALMT5_POWER_DETECT 90
+#define GPIO_NR_PALMT5_HOTSYNC_BUTTON_N 10
+#define GPIO_NR_PALMT5_EARPHONE_DETECT 107
+
+/* SD/MMC */
+#define GPIO_NR_PALMT5_SD_DETECT_N 14
+#define GPIO_NR_PALMT5_SD_POWER 114
+#define GPIO_NR_PALMT5_SD_READONLY 115
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMT5_WM9712_IRQ 27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMT5_IR_DISABLE 40
+
+/* USB */
+#define GPIO_NR_PALMT5_USB_DETECT_N 15
+#define GPIO_NR_PALMT5_USB_PULLUP 93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMT5_BL_POWER 84
+#define GPIO_NR_PALMT5_LCD_POWER 96
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMT5_BT_POWER 17
+#define GPIO_NR_PALMT5_BT_RESET 83
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMT5_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMT5_SD_DETECT_N)
+#define IRQ_GPIO_PALMT5_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMT5_WM9712_IRQ)
+#define IRQ_GPIO_PALMT5_USB_DETECT IRQ_GPIO(GPIO_NR_PALMT5_USB_DETECT)
+#define IRQ_GPIO_PALMT5_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMT5_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses */
+#define PALMT5_PHYS_RAM_START 0xa0000000
+#define PALMT5_PHYS_IO_START 0x40000000
+#define PALMT5_STR_BASE 0xa0200000
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME 21
+
+/* BATTERY */
+#define PALMT5_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMT5_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMT5_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMT5_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMT5_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMT5_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMT5_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+#define PALMT5_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMT5_MAX_INTENSITY 0xFE
+#define PALMT5_DEFAULT_INTENSITY 0x7E
+#define PALMT5_LIMIT_MASK 0x7F
+#define PALMT5_PRESCALER 0x3F
+#define PALMT5_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmtc.h b/arch/arm/mach-pxa/include/mach/palmtc.h
new file mode 100644
index 00000000..3f9dd3fd
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtc.h
@@ -0,0 +1,86 @@
+/*
+ * linux/include/asm-arm/arch-pxa/palmtc-gpio.h
+ *
+ * GPIOs and interrupts for Palm Tungsten|C Handheld Computer
+ *
+ * Authors: Alex Osborne <bobofdoom@gmail.com>
+ * Marek Vasut <marek.vasut@gmail.com>
+ * Holger Bocklet <bitz.email@gmx.net>
+ *
+ * This program is free software; you can 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 _INCLUDE_PALMTC_H_
+#define _INCLUDE_PALMTC_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTC_EARPHONE_DETECT 2
+#define GPIO_NR_PALMTC_CRADLE_DETECT 5
+#define GPIO_NR_PALMTC_HOTSYNC_BUTTON 7
+
+/* SD/MMC */
+#define GPIO_NR_PALMTC_SD_DETECT_N 12
+#define GPIO_NR_PALMTC_SD_POWER 32
+#define GPIO_NR_PALMTC_SD_READONLY 54
+
+/* WLAN */
+#define GPIO_NR_PALMTC_PCMCIA_READY 13
+#define GPIO_NR_PALMTC_PCMCIA_PWRREADY 14
+#define GPIO_NR_PALMTC_PCMCIA_POWER1 15
+#define GPIO_NR_PALMTC_PCMCIA_POWER2 33
+#define GPIO_NR_PALMTC_PCMCIA_POWER3 55
+#define GPIO_NR_PALMTC_PCMCIA_RESET 78
+
+/* UDC */
+#define GPIO_NR_PALMTC_USB_DETECT_N 4
+#define GPIO_NR_PALMTC_USB_POWER 36
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTC_BL_POWER 16
+#define GPIO_NR_PALMTC_LCD_POWER 44
+#define GPIO_NR_PALMTC_LCD_BLANK 38
+
+/* UART */
+#define GPIO_NR_PALMTC_RS232_POWER 37
+
+/* IRDA */
+#define GPIO_NR_PALMTC_IR_DISABLE 45
+
+/* IRQs */
+#define IRQ_GPIO_PALMTC_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTC_SD_DETECT_N)
+#define IRQ_GPIO_PALMTC_WLAN_READY IRQ_GPIO(GPIO_NR_PALMTC_WLAN_READY)
+
+/* UCB1400 GPIOs */
+#define GPIO_NR_PALMTC_POWER_DETECT (0x80 | 0x00)
+#define GPIO_NR_PALMTC_HEADPHONE_DETECT (0x80 | 0x01)
+#define GPIO_NR_PALMTC_SPEAKER_ENABLE (0x80 | 0x03)
+#define GPIO_NR_PALMTC_VIBRA_POWER (0x80 | 0x05)
+#define GPIO_NR_PALMTC_LED_POWER (0x80 | 0x07)
+
+/** HERE ARE INIT VALUES **/
+#define PALMTC_UCB1400_GPIO_OFFSET 0x80
+
+/* BATTERY */
+#define PALMTC_BAT_MAX_VOLTAGE 4000 /* 4.00V maximum voltage */
+#define PALMTC_BAT_MIN_VOLTAGE 3550 /* 3.55V critical voltage */
+#define PALMTC_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMTC_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMTC_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMTC_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMTC_MAX_LIFE_MINS 240 /* on-life in minutes */
+
+#define PALMTC_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMTC_MAX_INTENSITY 0xFE
+#define PALMTC_DEFAULT_INTENSITY 0x7E
+#define PALMTC_LIMIT_MASK 0x7F
+#define PALMTC_PRESCALER 0x3F
+#define PALMTC_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmte2.h b/arch/arm/mach-pxa/include/mach/palmte2.h
new file mode 100644
index 00000000..f89e989a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmte2.h
@@ -0,0 +1,68 @@
+/*
+ * GPIOs and interrupts for Palm Tungsten|E2 Handheld Computer
+ *
+ * Author:
+ * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.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 _INCLUDE_PALMTE2_H_
+#define _INCLUDE_PALMTE2_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTE2_POWER_DETECT 9
+#define GPIO_NR_PALMTE2_HOTSYNC_BUTTON_N 4
+#define GPIO_NR_PALMTE2_EARPHONE_DETECT 15
+
+/* SD/MMC */
+#define GPIO_NR_PALMTE2_SD_DETECT_N 10
+#define GPIO_NR_PALMTE2_SD_POWER 55
+#define GPIO_NR_PALMTE2_SD_READONLY 51
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTE2_IR_DISABLE 48
+
+/* USB */
+#define GPIO_NR_PALMTE2_USB_DETECT_N 35
+#define GPIO_NR_PALMTE2_USB_PULLUP 53
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTE2_BL_POWER 56
+#define GPIO_NR_PALMTE2_LCD_POWER 37
+
+/* KEYS */
+#define GPIO_NR_PALMTE2_KEY_NOTES 5
+#define GPIO_NR_PALMTE2_KEY_TASKS 7
+#define GPIO_NR_PALMTE2_KEY_CALENDAR 11
+#define GPIO_NR_PALMTE2_KEY_CONTACTS 13
+#define GPIO_NR_PALMTE2_KEY_CENTER 14
+#define GPIO_NR_PALMTE2_KEY_LEFT 19
+#define GPIO_NR_PALMTE2_KEY_RIGHT 20
+#define GPIO_NR_PALMTE2_KEY_DOWN 21
+#define GPIO_NR_PALMTE2_KEY_UP 22
+
+/** HERE ARE INIT VALUES **/
+
+/* BACKLIGHT */
+#define PALMTE2_MAX_INTENSITY 0xFE
+#define PALMTE2_DEFAULT_INTENSITY 0x7E
+#define PALMTE2_LIMIT_MASK 0x7F
+#define PALMTE2_PRESCALER 0x3F
+#define PALMTE2_PERIOD_NS 3500
+
+/* BATTERY */
+#define PALMTE2_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMTE2_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMTE2_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMTE2_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMTE2_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMTE2_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMTE2_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmtreo.h b/arch/arm/mach-pxa/include/mach/palmtreo.h
new file mode 100644
index 00000000..2d3f14e3
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtreo.h
@@ -0,0 +1,67 @@
+/*
+ * GPIOs and interrupts for Palm Treo smartphones
+ *
+ * currently supported:
+ * Palm Treo 680 (GSM)
+ * Palm Centro 685 (GSM)
+ *
+ * Author: Tomas Cech <sleep_walker@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * find more info at www.hackndev.com
+ *
+ */
+
+#ifndef _INCLUDE_TREO_H_
+#define _INCLUDE_TREO_H_
+
+/* GPIOs */
+#define GPIO_NR_TREO_POWER_DETECT 0
+#define GPIO_NR_TREO_AMP_EN 27
+#define GPIO_NR_TREO_GREEN_LED 20
+#define GPIO_NR_TREO_RED_LED 79
+#define GPIO_NR_TREO_SD_DETECT_N 113
+#define GPIO_NR_TREO_EP_DETECT_N 116
+#define GPIO_NR_TREO_USB_DETECT 1
+#define GPIO_NR_TREO_USB_PULLUP 114
+#define GPIO_NR_TREO_GSM_POWER 40
+#define GPIO_NR_TREO_GSM_RESET 87
+#define GPIO_NR_TREO_GSM_WAKE 57
+#define GPIO_NR_TREO_GSM_HOST_WAKE 14
+#define GPIO_NR_TREO_GSM_TRIGGER 10
+#define GPIO_NR_TREO_IR_EN 115
+#define GPIO_NR_TREO_IR_TXD 47
+#define GPIO_NR_TREO_BL_POWER 38
+#define GPIO_NR_TREO_LCD_POWER 25
+
+/* Treo680 specific GPIOs */
+#ifdef CONFIG_MACH_TREO680
+#define GPIO_NR_TREO680_SD_READONLY 33
+#define GPIO_NR_TREO680_SD_POWER 42
+#define GPIO_NR_TREO680_VIBRATE_EN 44
+#define GPIO_NR_TREO680_KEYB_BL 24
+#define GPIO_NR_TREO680_BT_EN 43
+#endif /* CONFIG_MACH_TREO680 */
+
+/* Centro685 specific GPIOs */
+#define GPIO_NR_CENTRO_SD_POWER 21
+#define GPIO_NR_CENTRO_VIBRATE_EN 22
+#define GPIO_NR_CENTRO_KEYB_BL 33
+#define GPIO_NR_CENTRO_BT_EN 80
+
+/* Various addresses */
+#define TREO_PHYS_RAM_START 0xa0000000
+#define TREO_PHYS_IO_START 0x40000000
+#define TREO_STR_BASE 0xa2000000
+
+/* BACKLIGHT */
+#define TREO_MAX_INTENSITY 254
+#define TREO_DEFAULT_INTENSITY 160
+#define TREO_LIMIT_MASK 0x7F
+#define TREO_PRESCALER 63
+#define TREO_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmtx.h b/arch/arm/mach-pxa/include/mach/palmtx.h
new file mode 100644
index 00000000..10abc4f2
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmtx.h
@@ -0,0 +1,112 @@
+/*
+ * GPIOs and interrupts for Palm T|X Handheld Computer
+ *
+ * Based on palmld-gpio.h by Alex Osborne
+ *
+ * Authors: Marek Vasut <marek.vasut@gmail.com>
+ * Cristiano P. <cristianop@users.sourceforge.net>
+ * Jan Herman <2hp@seznam.cz>
+ *
+ * This program is free software; you can 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 _INCLUDE_PALMTX_H_
+#define _INCLUDE_PALMTX_H_
+
+/** HERE ARE GPIOs **/
+
+/* GPIOs */
+#define GPIO_NR_PALMTX_GPIO_RESET 1
+
+#define GPIO_NR_PALMTX_POWER_DETECT 12 /* 90 */
+#define GPIO_NR_PALMTX_HOTSYNC_BUTTON_N 10
+#define GPIO_NR_PALMTX_EARPHONE_DETECT 107
+
+/* SD/MMC */
+#define GPIO_NR_PALMTX_SD_DETECT_N 14
+#define GPIO_NR_PALMTX_SD_POWER 114 /* probably */
+#define GPIO_NR_PALMTX_SD_READONLY 115 /* probably */
+
+/* TOUCHSCREEN */
+#define GPIO_NR_PALMTX_WM9712_IRQ 27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMTX_IR_DISABLE 40
+
+/* USB */
+#define GPIO_NR_PALMTX_USB_DETECT_N 13
+#define GPIO_NR_PALMTX_USB_PULLUP 93
+
+/* LCD/BACKLIGHT */
+#define GPIO_NR_PALMTX_BL_POWER 84
+#define GPIO_NR_PALMTX_LCD_POWER 96
+
+/* LCD BORDER */
+#define GPIO_NR_PALMTX_BORDER_SWITCH 98
+#define GPIO_NR_PALMTX_BORDER_SELECT 22
+
+/* BLUETOOTH */
+#define GPIO_NR_PALMTX_BT_POWER 17
+#define GPIO_NR_PALMTX_BT_RESET 83
+
+/* PCMCIA (WiFi) */
+#define GPIO_NR_PALMTX_PCMCIA_POWER1 94
+#define GPIO_NR_PALMTX_PCMCIA_POWER2 108
+#define GPIO_NR_PALMTX_PCMCIA_RESET 79
+#define GPIO_NR_PALMTX_PCMCIA_READY 116
+
+/* NAND Flash ... this GPIO may be incorrect! */
+#define GPIO_NR_PALMTX_NAND_BUFFER_DIR 79
+
+/* INTERRUPTS */
+#define IRQ_GPIO_PALMTX_SD_DETECT_N IRQ_GPIO(GPIO_NR_PALMTX_SD_DETECT_N)
+#define IRQ_GPIO_PALMTX_WM9712_IRQ IRQ_GPIO(GPIO_NR_PALMTX_WM9712_IRQ)
+#define IRQ_GPIO_PALMTX_USB_DETECT IRQ_GPIO(GPIO_NR_PALMTX_USB_DETECT)
+#define IRQ_GPIO_PALMTX_GPIO_RESET IRQ_GPIO(GPIO_NR_PALMTX_GPIO_RESET)
+
+/** HERE ARE INIT VALUES **/
+
+/* Various addresses */
+#define PALMTX_PCMCIA_PHYS 0x28000000
+#define PALMTX_PCMCIA_VIRT 0xf0000000
+#define PALMTX_PCMCIA_SIZE 0x100000
+
+#define PALMTX_PHYS_RAM_START 0xa0000000
+#define PALMTX_PHYS_IO_START 0x40000000
+
+#define PALMTX_STR_BASE 0xa0200000
+
+#define PALMTX_PHYS_FLASH_START PXA_CS0_PHYS /* ChipSelect 0 */
+#define PALMTX_PHYS_NAND_START PXA_CS1_PHYS /* ChipSelect 1 */
+
+#define PALMTX_NAND_ALE_PHYS (PALMTX_PHYS_NAND_START | (1 << 24))
+#define PALMTX_NAND_CLE_PHYS (PALMTX_PHYS_NAND_START | (1 << 25))
+#define PALMTX_NAND_ALE_VIRT 0xff100000
+#define PALMTX_NAND_CLE_VIRT 0xff200000
+
+/* TOUCHSCREEN */
+#define AC97_LINK_FRAME 21
+
+
+/* BATTERY */
+#define PALMTX_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMTX_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMTX_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMTX_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMTX_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMTX_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMTX_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+#define PALMTX_BAT_MEASURE_DELAY (HZ * 1)
+
+/* BACKLIGHT */
+#define PALMTX_MAX_INTENSITY 0xFE
+#define PALMTX_DEFAULT_INTENSITY 0x7E
+#define PALMTX_LIMIT_MASK 0x7F
+#define PALMTX_PRESCALER 0x3F
+#define PALMTX_PERIOD_NS 3500
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
new file mode 100644
index 00000000..0d4700a7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/palmz72.h
@@ -0,0 +1,84 @@
+/*
+ * GPIOs and interrupts for Palm Zire72 Handheld Computer
+ *
+ * Authors: Alex Osborne <bobofdoom@gmail.com>
+ * Jan Herman <2hp@seznam.cz>
+ * Sergey Lapin <slapin@ossfans.org>
+ *
+ * This program is free software; you can 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 _INCLUDE_PALMZ72_H_
+#define _INCLUDE_PALMZ72_H_
+
+/* Power and control */
+#define GPIO_NR_PALMZ72_GPIO_RESET 1
+#define GPIO_NR_PALMZ72_POWER_DETECT 0
+
+/* SD/MMC */
+#define GPIO_NR_PALMZ72_SD_DETECT_N 14
+#define GPIO_NR_PALMZ72_SD_POWER_N 98
+#define GPIO_NR_PALMZ72_SD_RO 115
+
+/* Touchscreen */
+#define GPIO_NR_PALMZ72_WM9712_IRQ 27
+
+/* IRDA - disable GPIO connected to SD pin of tranceiver (TFBS4710?) ? */
+#define GPIO_NR_PALMZ72_IR_DISABLE 49
+
+/* USB */
+#define GPIO_NR_PALMZ72_USB_DETECT_N 15
+#define GPIO_NR_PALMZ72_USB_PULLUP 95
+
+/* LCD/Backlight */
+#define GPIO_NR_PALMZ72_BL_POWER 20
+#define GPIO_NR_PALMZ72_LCD_POWER 96
+
+/* LED */
+#define GPIO_NR_PALMZ72_LED_GREEN 88
+
+/* Bluetooth */
+#define GPIO_NR_PALMZ72_BT_POWER 17
+#define GPIO_NR_PALMZ72_BT_RESET 83
+
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN 56
+#define GPIO_NR_PALMZ72_CAM_RESET 57
+#define GPIO_NR_PALMZ72_CAM_POWER 91
+
+/** Initial values **/
+
+/* Battery */
+#define PALMZ72_BAT_MAX_VOLTAGE 4000 /* 4.00v current voltage */
+#define PALMZ72_BAT_MIN_VOLTAGE 3550 /* 3.55v critical voltage */
+#define PALMZ72_BAT_MAX_CURRENT 0 /* unknown */
+#define PALMZ72_BAT_MIN_CURRENT 0 /* unknown */
+#define PALMZ72_BAT_MAX_CHARGE 1 /* unknown */
+#define PALMZ72_BAT_MIN_CHARGE 1 /* unknown */
+#define PALMZ72_MAX_LIFE_MINS 360 /* on-life in minutes */
+
+/* Backlight */
+#define PALMZ72_MAX_INTENSITY 0xFE
+#define PALMZ72_DEFAULT_INTENSITY 0x7E
+#define PALMZ72_LIMIT_MASK 0x7F
+#define PALMZ72_PRESCALER 0x3F
+#define PALMZ72_PERIOD_NS 3500
+
+#ifdef CONFIG_PM
+struct palmz72_resume_info {
+ u32 magic0; /* 0x0 */
+ u32 magic1; /* 0x4 */
+ u32 resume_addr; /* 0x8 */
+ u32 pad[11]; /* 0xc..0x37 */
+ u32 arm_control; /* 0x38 */
+ u32 aux_control; /* 0x3c */
+ u32 ttb; /* 0x40 */
+ u32 domain_access; /* 0x44 */
+ u32 process_id; /* 0x48 */
+};
+#endif
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/pata_pxa.h b/arch/arm/mach-pxa/include/mach/pata_pxa.h
new file mode 100644
index 00000000..6cf7df1d
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pata_pxa.h
@@ -0,0 +1,33 @@
+/*
+ * Generic PXA PATA driver
+ *
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.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, 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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_PATA_PXA_H__
+#define __MACH_PATA_PXA_H__
+
+struct pata_pxa_pdata {
+ /* PXA DMA DREQ<0:2> pin */
+ uint32_t dma_dreq;
+ /* Register shift */
+ uint32_t reg_shift;
+ /* IRQ flags */
+ uint32_t irq_flags;
+};
+
+#endif /* __MACH_PATA_PXA_H__ */
diff --git a/arch/arm/mach-pxa/include/mach/pcm027.h b/arch/arm/mach-pxa/include/mach/pcm027.h
new file mode 100644
index 00000000..4bac5884
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pcm027.h
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pcm027.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Definitions of CPU card resources only
+ */
+
+/* phyCORE-PXA270 (PCM027) Interrupts */
+#define PCM027_IRQ(x) (IRQ_BOARD_START + (x))
+#define PCM027_BTDET_IRQ PCM027_IRQ(0)
+#define PCM027_FF_RI_IRQ PCM027_IRQ(1)
+#define PCM027_MMCDET_IRQ PCM027_IRQ(2)
+#define PCM027_PM_5V_IRQ PCM027_IRQ(3)
+
+#define PCM027_NR_IRQS (IRQ_BOARD_START + 32)
+
+/* I2C RTC */
+#define PCM027_RTC_IRQ_GPIO 0
+#define PCM027_RTC_IRQ IRQ_GPIO(PCM027_RTC_IRQ_GPIO)
+#define PCM027_RTC_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+#define ADR_PCM027_RTC 0x51 /* I2C address */
+
+/* I2C EEPROM */
+#define ADR_PCM027_EEPROM 0x54 /* I2C address */
+
+/* Ethernet chip (SMSC91C111) */
+#define PCM027_ETH_IRQ_GPIO 52
+#define PCM027_ETH_IRQ IRQ_GPIO(PCM027_ETH_IRQ_GPIO)
+#define PCM027_ETH_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+#define PCM027_ETH_PHYS PXA_CS5_PHYS
+#define PCM027_ETH_SIZE (1*1024*1024)
+
+/* CAN controller SJA1000 (unsupported yet) */
+#define PCM027_CAN_IRQ_GPIO 114
+#define PCM027_CAN_IRQ IRQ_GPIO(PCM027_CAN_IRQ_GPIO)
+#define PCM027_CAN_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+#define PCM027_CAN_PHYS 0x22000000
+#define PCM027_CAN_SIZE 0x100
+
+/* SPI GPIO expander (unsupported yet) */
+#define PCM027_EGPIO_IRQ_GPIO 27
+#define PCM027_EGPIO_IRQ IRQ_GPIO(PCM027_EGPIO_IRQ_GPIO)
+#define PCM027_EGPIO_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+#define PCM027_EGPIO_CS 24
+/*
+ * TODO: Switch this pin from dedicated usage to GPIO if
+ * more than the MAX7301 device is connected to this SPI bus
+ */
+#define PCM027_EGPIO_CS_MODE GPIO24_SFRM_MD
+
+/* Flash memory */
+#define PCM027_FLASH_PHYS 0x00000000
+#define PCM027_FLASH_SIZE 0x02000000
+
+/* onboard LEDs connected to GPIO */
+#define PCM027_LED_CPU 90
+#define PCM027_LED_HEARD_BEAT 91
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own basebaord init function and call it from
+ * inside pcm027_init(). This example here is for the developmen board.
+ * Refer pcm990-baseboard.c
+ */
+extern void pcm990_baseboard_init(void);
diff --git a/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
new file mode 100644
index 00000000..8a4383b7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
@@ -0,0 +1,275 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pcm990_baseboard.h
+ *
+ * (c) 2003 Phytec Messtechnik GmbH <armlinux@phytec.de>
+ * (c) 2007 Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <mach/pcm027.h>
+
+/*
+ * definitions relevant only when the PCM-990
+ * development base board is in use
+ */
+
+/* CPLD's interrupt controller is connected to PCM-027 GPIO 9 */
+#define PCM990_CTRL_INT_IRQ_GPIO 9
+#define PCM990_CTRL_INT_IRQ IRQ_GPIO(PCM990_CTRL_INT_IRQ_GPIO)
+#define PCM990_CTRL_INT_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+#define PCM990_CTRL_PHYS PXA_CS1_PHYS /* 16-Bit */
+#define PCM990_CTRL_BASE 0xea000000
+#define PCM990_CTRL_SIZE (1*1024*1024)
+
+#define PCM990_CTRL_PWR_IRQ_GPIO 14
+#define PCM990_CTRL_PWR_IRQ IRQ_GPIO(PCM990_CTRL_PWR_IRQ_GPIO)
+#define PCM990_CTRL_PWR_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+/* visible CPLD (U7) registers */
+#define PCM990_CTRL_REG0 0x0000 /* RESET REGISTER */
+#define PCM990_CTRL_SYSRES 0x0001 /* System RESET REGISTER */
+#define PCM990_CTRL_RESOUT 0x0002 /* RESETOUT Enable REGISTER */
+#define PCM990_CTRL_RESGPIO 0x0004 /* RESETGPIO Enable REGISTER */
+
+#define PCM990_CTRL_REG1 0x0002 /* Power REGISTER */
+#define PCM990_CTRL_5VOFF 0x0001 /* Disable 5V Regulators */
+#define PCM990_CTRL_CANPWR 0x0004 /* Enable CANPWR ADUM */
+#define PCM990_CTRL_PM_5V 0x0008 /* Read 5V OK */
+
+#define PCM990_CTRL_REG2 0x0004 /* LED REGISTER */
+#define PCM990_CTRL_LEDPWR 0x0001 /* POWER LED enable */
+#define PCM990_CTRL_LEDBAS 0x0002 /* BASIS LED enable */
+#define PCM990_CTRL_LEDUSR 0x0004 /* USER LED enable */
+
+#define PCM990_CTRL_REG3 0x0006 /* LCD CTRL REGISTER 3 */
+#define PCM990_CTRL_LCDPWR 0x0001 /* RW LCD Power on */
+#define PCM990_CTRL_LCDON 0x0002 /* RW LCD Latch on */
+#define PCM990_CTRL_LCDPOS1 0x0004 /* RW POS 1 */
+#define PCM990_CTRL_LCDPOS2 0x0008 /* RW POS 2 */
+
+#define PCM990_CTRL_REG4 0x0008 /* MMC1 CTRL REGISTER 4 */
+#define PCM990_CTRL_MMC1PWR 0x0001 /* RW MMC1 Power on */
+
+#define PCM990_CTRL_REG5 0x000A /* MMC2 CTRL REGISTER 5 */
+#define PCM990_CTRL_MMC2PWR 0x0001 /* RW MMC2 Power on */
+#define PCM990_CTRL_MMC2LED 0x0002 /* RW MMC2 LED */
+#define PCM990_CTRL_MMC2DE 0x0004 /* R MMC2 Card detect */
+#define PCM990_CTRL_MMC2WP 0x0008 /* R MMC2 Card write protect */
+
+#define PCM990_CTRL_REG6 0x000C /* Interrupt Clear REGISTER */
+#define PCM990_CTRL_INTC0 0x0001 /* Clear Reg BT Detect */
+#define PCM990_CTRL_INTC1 0x0002 /* Clear Reg FR RI */
+#define PCM990_CTRL_INTC2 0x0004 /* Clear Reg MMC1 Detect */
+#define PCM990_CTRL_INTC3 0x0008 /* Clear Reg PM_5V off */
+
+#define PCM990_CTRL_REG7 0x000E /* Interrupt Enable REGISTER */
+#define PCM990_CTRL_ENAINT0 0x0001 /* Enable Int BT Detect */
+#define PCM990_CTRL_ENAINT1 0x0002 /* Enable Int FR RI */
+#define PCM990_CTRL_ENAINT2 0x0004 /* Enable Int MMC1 Detect */
+#define PCM990_CTRL_ENAINT3 0x0008 /* Enable Int PM_5V off */
+
+#define PCM990_CTRL_REG8 0x0014 /* Uart REGISTER */
+#define PCM990_CTRL_FFSD 0x0001 /* BT Uart Enable */
+#define PCM990_CTRL_BTSD 0x0002 /* FF Uart Enable */
+#define PCM990_CTRL_FFRI 0x0004 /* FF Uart RI detect */
+#define PCM990_CTRL_BTRX 0x0008 /* BT Uart Rx detect */
+
+#define PCM990_CTRL_REG9 0x0010 /* AC97 Flash REGISTER */
+#define PCM990_CTRL_FLWP 0x0001 /* pC Flash Write Protect */
+#define PCM990_CTRL_FLDIS 0x0002 /* pC Flash Disable */
+#define PCM990_CTRL_AC97ENA 0x0004 /* Enable AC97 Expansion */
+
+#define PCM990_CTRL_REG10 0x0012 /* GPS-REGISTER */
+#define PCM990_CTRL_GPSPWR 0x0004 /* GPS-Modul Power on */
+#define PCM990_CTRL_GPSENA 0x0008 /* GPS-Modul Enable */
+
+#define PCM990_CTRL_REG11 0x0014 /* Accu REGISTER */
+#define PCM990_CTRL_ACENA 0x0001 /* Charge Enable */
+#define PCM990_CTRL_ACSEL 0x0002 /* Charge Akku -> DC Enable */
+#define PCM990_CTRL_ACPRES 0x0004 /* DC Present */
+#define PCM990_CTRL_ACALARM 0x0008 /* Error Akku */
+
+#define PCM990_CTRL_P2V(x) ((x) - PCM990_CTRL_PHYS + PCM990_CTRL_BASE)
+#define PCM990_CTRL_V2P(x) ((x) - PCM990_CTRL_BASE + PCM990_CTRL_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __PCM990_CTRL_REG(x) \
+ (*((volatile unsigned char *)PCM990_CTRL_P2V(x)))
+#else
+# define __PCM990_CTRL_REG(x) PCM990_CTRL_P2V(x)
+#endif
+
+#define PCM990_INTMSKENA __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_INTSETCLR __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL0 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG0)
+#define PCM990_CTRL1 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG1)
+#define PCM990_CTRL2 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG2)
+#define PCM990_CTRL3 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3)
+#define PCM990_CTRL4 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG4)
+#define PCM990_CTRL5 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5)
+#define PCM990_CTRL6 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG6)
+#define PCM990_CTRL7 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG7)
+#define PCM990_CTRL8 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG8)
+#define PCM990_CTRL9 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG9)
+#define PCM990_CTRL10 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG10)
+#define PCM990_CTRL11 __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG11)
+
+
+/*
+ * IDE
+ */
+#define PCM990_IDE_IRQ_GPIO 13
+#define PCM990_IDE_IRQ IRQ_GPIO(PCM990_IDE_IRQ_GPIO)
+#define PCM990_IDE_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+#define PCM990_IDE_PLD_PHYS 0x20000000 /* 16 bit wide */
+#define PCM990_IDE_PLD_BASE 0xee000000
+#define PCM990_IDE_PLD_SIZE (1*1024*1024)
+
+/* visible CPLD (U6) registers */
+#define PCM990_IDE_PLD_REG0 0x1000 /* OFFSET IDE REGISTER 0 */
+#define PCM990_IDE_PM5V 0x0004 /* R System VCC_5V */
+#define PCM990_IDE_STBY 0x0008 /* R System StandBy */
+
+#define PCM990_IDE_PLD_REG1 0x1002 /* OFFSET IDE REGISTER 1 */
+#define PCM990_IDE_IDEMODE 0x0001 /* R TrueIDE Mode */
+#define PCM990_IDE_DMAENA 0x0004 /* RW DMA Enable */
+#define PCM990_IDE_DMA1_0 0x0008 /* RW 1=DREQ1 0=DREQ0 */
+
+#define PCM990_IDE_PLD_REG2 0x1004 /* OFFSET IDE REGISTER 2 */
+#define PCM990_IDE_RESENA 0x0001 /* RW IDE Reset Bit enable */
+#define PCM990_IDE_RES 0x0002 /* RW IDE Reset Bit */
+#define PCM990_IDE_RDY 0x0008 /* RDY */
+
+#define PCM990_IDE_PLD_REG3 0x1006 /* OFFSET IDE REGISTER 3 */
+#define PCM990_IDE_IDEOE 0x0001 /* RW Latch on Databus */
+#define PCM990_IDE_IDEON 0x0002 /* RW Latch on Control Address */
+#define PCM990_IDE_IDEIN 0x0004 /* RW Latch on Interrupt usw. */
+
+#define PCM990_IDE_PLD_REG4 0x1008 /* OFFSET IDE REGISTER 4 */
+#define PCM990_IDE_PWRENA 0x0001 /* RW IDE Power enable */
+#define PCM990_IDE_5V 0x0002 /* R IDE Power 5V */
+#define PCM990_IDE_PWG 0x0008 /* R IDE Power is on */
+
+#define PCM990_IDE_PLD_P2V(x) ((x) - PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_BASE)
+#define PCM990_IDE_PLD_V2P(x) ((x) - PCM990_IDE_PLD_BASE + PCM990_IDE_PLD_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __PCM990_IDE_PLD_REG(x) \
+ (*((volatile unsigned char *)PCM990_IDE_PLD_P2V(x)))
+#else
+# define __PCM990_IDE_PLD_REG(x) PCM990_IDE_PLD_P2V(x)
+#endif
+
+#define PCM990_IDE0 \
+ __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG0)
+#define PCM990_IDE1 \
+ __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG1)
+#define PCM990_IDE2 \
+ __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG2)
+#define PCM990_IDE3 \
+ __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG3)
+#define PCM990_IDE4 \
+ __PCM990_IDE_PLD_REG(PCM990_IDE_PLD_PHYS + PCM990_IDE_PLD_REG4)
+
+/*
+ * Compact Flash
+ */
+#define PCM990_CF_IRQ_GPIO 11
+#define PCM990_CF_IRQ IRQ_GPIO(PCM990_CF_IRQ_GPIO)
+#define PCM990_CF_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_CD_GPIO 12
+#define PCM990_CF_CD IRQ_GPIO(PCM990_CF_CD_GPIO)
+#define PCM990_CF_CD_EDGE IRQ_TYPE_EDGE_RISING
+
+#define PCM990_CF_PLD_PHYS 0x30000000 /* 16 bit wide */
+#define PCM990_CF_PLD_BASE 0xef000000
+#define PCM990_CF_PLD_SIZE (1*1024*1024)
+#define PCM990_CF_PLD_P2V(x) ((x) - PCM990_CF_PLD_PHYS + PCM990_CF_PLD_BASE)
+#define PCM990_CF_PLD_V2P(x) ((x) - PCM990_CF_PLD_BASE + PCM990_CF_PLD_PHYS)
+
+/* visible CPLD (U6) registers */
+#define PCM990_CF_PLD_REG0 0x1000 /* OFFSET CF REGISTER 0 */
+#define PCM990_CF_REG0_LED 0x0001 /* RW LED on */
+#define PCM990_CF_REG0_BLK 0x0002 /* RW LED flash when access */
+#define PCM990_CF_REG0_PM5V 0x0004 /* R System VCC_5V enable */
+#define PCM990_CF_REG0_STBY 0x0008 /* R System StandBy */
+
+#define PCM990_CF_PLD_REG1 0x1002 /* OFFSET CF REGISTER 1 */
+#define PCM990_CF_REG1_IDEMODE 0x0001 /* RW CF card run as TrueIDE */
+#define PCM990_CF_REG1_CF0 0x0002 /* RW CF card at ADDR 0x28000000 */
+
+#define PCM990_CF_PLD_REG2 0x1004 /* OFFSET CF REGISTER 2 */
+#define PCM990_CF_REG2_RES 0x0002 /* RW CF RESET BIT */
+#define PCM990_CF_REG2_RDYENA 0x0004 /* RW Enable CF_RDY */
+#define PCM990_CF_REG2_RDY 0x0008 /* R CF_RDY auf PWAIT */
+
+#define PCM990_CF_PLD_REG3 0x1006 /* OFFSET CF REGISTER 3 */
+#define PCM990_CF_REG3_CFOE 0x0001 /* RW Latch on Databus */
+#define PCM990_CF_REG3_CFON 0x0002 /* RW Latch on Control Address */
+#define PCM990_CF_REG3_CFIN 0x0004 /* RW Latch on Interrupt usw. */
+#define PCM990_CF_REG3_CFCD 0x0008 /* RW Latch on CD1/2 VS1/2 usw */
+
+#define PCM990_CF_PLD_REG4 0x1008 /* OFFSET CF REGISTER 4 */
+#define PCM990_CF_REG4_PWRENA 0x0001 /* RW CF Power on (CD1/2 = "00") */
+#define PCM990_CF_REG4_5_3V 0x0002 /* RW 1 = 5V CF_VCC 0 = 3 V CF_VCC */
+#define PCM990_CF_REG4_3B 0x0004 /* RW 3.0V Backup from VCC (5_3V=0) */
+#define PCM990_CF_REG4_PWG 0x0008 /* R CF-Power is on */
+
+#define PCM990_CF_PLD_REG5 0x100A /* OFFSET CF REGISTER 5 */
+#define PCM990_CF_REG5_BVD1 0x0001 /* R CF /BVD1 */
+#define PCM990_CF_REG5_BVD2 0x0002 /* R CF /BVD2 */
+#define PCM990_CF_REG5_VS1 0x0004 /* R CF /VS1 */
+#define PCM990_CF_REG5_VS2 0x0008 /* R CF /VS2 */
+
+#define PCM990_CF_PLD_REG6 0x100C /* OFFSET CF REGISTER 6 */
+#define PCM990_CF_REG6_CD1 0x0001 /* R CF Card_Detect1 */
+#define PCM990_CF_REG6_CD2 0x0002 /* R CF Card_Detect2 */
+
+#ifndef __ASSEMBLY__
+# define __PCM990_CF_PLD_REG(x) \
+ (*((volatile unsigned char *)PCM990_CF_PLD_P2V(x)))
+#else
+# define __PCM990_CF_PLD_REG(x) PCM990_CF_PLD_P2V(x)
+#endif
+
+#define PCM990_CF0 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG0)
+#define PCM990_CF1 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG1)
+#define PCM990_CF2 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG2)
+#define PCM990_CF3 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG3)
+#define PCM990_CF4 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG4)
+#define PCM990_CF5 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG5)
+#define PCM990_CF6 __PCM990_CF_PLD_REG(PCM990_CF_PLD_PHYS + PCM990_CF_PLD_REG6)
+
+/*
+ * Wolfson AC97 Touch
+ */
+#define PCM990_AC97_IRQ_GPIO 10
+#define PCM990_AC97_IRQ IRQ_GPIO(PCM990_AC97_IRQ_GPIO)
+#define PCM990_AC97_IRQ_EDGE IRQ_TYPE_EDGE_RISING
+
+/*
+ * MMC phyCORE
+ */
+#define PCM990_MMC0_IRQ_GPIO 9
+#define PCM990_MMC0_IRQ IRQ_GPIO(PCM990_MMC0_IRQ_GPIO)
+#define PCM990_MMC0_IRQ_EDGE IRQ_TYPE_EDGE_FALLING
+
+/*
+ * USB phyCore
+ */
+#define PCM990_USB_OVERCURRENT (88 | GPIO_ALT_FN_1_IN)
+#define PCM990_USB_PWR_EN (89 | GPIO_ALT_FN_2_OUT)
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h
new file mode 100644
index 00000000..f15afe01
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pm.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/suspend.h>
+
+struct pxa_cpu_pm_fns {
+ int save_count;
+ void (*save)(unsigned long *);
+ void (*restore)(unsigned long *);
+ int (*valid)(suspend_state_t state);
+ void (*enter)(suspend_state_t state);
+ int (*prepare)(void);
+ void (*finish)(void);
+};
+
+extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
+
+/* sleep.S */
+extern void pxa25x_cpu_suspend(unsigned int, long);
+extern void pxa27x_cpu_suspend(unsigned int, long);
+
+extern int pxa_pm_enter(suspend_state_t state);
+extern int pxa_pm_prepare(void);
+extern void pxa_pm_finish(void);
+
+/* NOTE: this is for PM debugging on Lubbock, it's really a big
+ * ugly, but let's keep the crap minimum here, instead of direct
+ * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c
+ */
+#ifdef CONFIG_ARCH_LUBBOCK
+extern void lubbock_set_hexled(uint32_t value);
+#else
+#define lubbock_set_hexled(x)
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
new file mode 100644
index 00000000..83d1cfd0
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-pxa/include/mach/poodle.h
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * Based on:
+ * arch/arm/mach-sa1100/include/mach/collie.h
+ *
+ * ChangeLog:
+ * 04-06-2001 Lineo Japan, Inc.
+ * 04-16-2001 SHARP Corporation
+ * Update to 2.6 John Lenz
+ */
+#ifndef __ASM_ARCH_POODLE_H
+#define __ASM_ARCH_POODLE_H 1
+
+/*
+ * GPIOs
+ */
+/* PXA GPIOs */
+#define POODLE_GPIO_ON_KEY (0)
+#define POODLE_GPIO_AC_IN (1)
+#define POODLE_GPIO_CO 16
+#define POODLE_GPIO_TP_INT (5)
+#define POODLE_GPIO_TP_CS (24)
+#define POODLE_GPIO_WAKEUP (11) /* change battery */
+#define POODLE_GPIO_GA_INT (10)
+#define POODLE_GPIO_IR_ON (22)
+#define POODLE_GPIO_HP_IN (4)
+#define POODLE_GPIO_CF_IRQ (17)
+#define POODLE_GPIO_CF_CD (14)
+#define POODLE_GPIO_CF_STSCHG (14)
+#define POODLE_GPIO_SD_PWR (33)
+#define POODLE_GPIO_SD_PWR1 (3)
+#define POODLE_GPIO_nSD_CLK (6)
+#define POODLE_GPIO_nSD_WP (7)
+#define POODLE_GPIO_nSD_INT (8)
+#define POODLE_GPIO_nSD_DETECT (9)
+#define POODLE_GPIO_MAIN_BAT_LOW (13)
+#define POODLE_GPIO_BAT_COVER (13)
+#define POODLE_GPIO_USB_PULLUP (20)
+#define POODLE_GPIO_ADC_TEMP_ON (21)
+#define POODLE_GPIO_BYPASS_ON (36)
+#define POODLE_GPIO_CHRG_ON (38)
+#define POODLE_GPIO_CHRG_FULL (16)
+#define POODLE_GPIO_DISCHARGE_ON (42) /* Enable battery discharge */
+
+/* PXA GPIOs */
+#define POODLE_IRQ_GPIO_ON_KEY IRQ_GPIO(0)
+#define POODLE_IRQ_GPIO_AC_IN IRQ_GPIO(1)
+#define POODLE_IRQ_GPIO_HP_IN IRQ_GPIO(4)
+#define POODLE_IRQ_GPIO_CO IRQ_GPIO(16)
+#define POODLE_IRQ_GPIO_TP_INT IRQ_GPIO(5)
+#define POODLE_IRQ_GPIO_WAKEUP IRQ_GPIO(11)
+#define POODLE_IRQ_GPIO_GA_INT IRQ_GPIO(10)
+#define POODLE_IRQ_GPIO_CF_IRQ IRQ_GPIO(17)
+#define POODLE_IRQ_GPIO_CF_CD IRQ_GPIO(14)
+#define POODLE_IRQ_GPIO_nSD_INT IRQ_GPIO(8)
+#define POODLE_IRQ_GPIO_nSD_DETECT IRQ_GPIO(9)
+#define POODLE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(13)
+
+/* SCOOP GPIOs */
+#define POODLE_SCOOP_CHARGE_ON SCOOP_GPCR_PA11
+#define POODLE_SCOOP_CP401 SCOOP_GPCR_PA13
+#define POODLE_SCOOP_VPEN SCOOP_GPCR_PA18
+#define POODLE_SCOOP_L_PCLK SCOOP_GPCR_PA20
+#define POODLE_SCOOP_L_LCLK SCOOP_GPCR_PA21
+#define POODLE_SCOOP_HS_OUT SCOOP_GPCR_PA22
+
+#define POODLE_SCOOP_IO_DIR ( POODLE_SCOOP_VPEN | POODLE_SCOOP_HS_OUT )
+#define POODLE_SCOOP_IO_OUT ( 0 )
+
+#define POODLE_SCOOP_GPIO_BASE (NR_BUILTIN_GPIO)
+#define POODLE_GPIO_CHARGE_ON (POODLE_SCOOP_GPIO_BASE + 0)
+#define POODLE_GPIO_CP401 (POODLE_SCOOP_GPIO_BASE + 2)
+#define POODLE_GPIO_VPEN (POODLE_SCOOP_GPIO_BASE + 7)
+#define POODLE_GPIO_L_PCLK (POODLE_SCOOP_GPIO_BASE + 9)
+#define POODLE_GPIO_L_LCLK (POODLE_SCOOP_GPIO_BASE + 10)
+#define POODLE_GPIO_HS_OUT (POODLE_SCOOP_GPIO_BASE + 11)
+
+#define POODLE_LOCOMO_GPIO_AMP_ON LOCOMO_GPIO(8)
+#define POODLE_LOCOMO_GPIO_MUTE_L LOCOMO_GPIO(10)
+#define POODLE_LOCOMO_GPIO_MUTE_R LOCOMO_GPIO(11)
+#define POODLE_LOCOMO_GPIO_232VCC_ON LOCOMO_GPIO(12)
+#define POODLE_LOCOMO_GPIO_JK_B LOCOMO_GPIO(13)
+
+#define POODLE_NR_IRQS (IRQ_BOARD_START + 4) /* 4 for LoCoMo */
+
+extern struct platform_device poodle_locomo_device;
+
+#endif /* __ASM_ARCH_POODLE_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x-udc.h b/arch/arm/mach-pxa/include/mach/pxa25x-udc.h
new file mode 100644
index 00000000..1b80a480
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa25x-udc.h
@@ -0,0 +1,163 @@
+#ifndef _ASM_ARCH_PXA25X_UDC_H
+#define _ASM_ARCH_PXA25X_UDC_H
+
+#ifdef _ASM_ARCH_PXA27X_UDC_H
+#error "You can't include both PXA25x and PXA27x UDC support"
+#endif
+
+#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */
+#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */
+#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */
+
+#define UDCCR __REG(0x40600000) /* UDC Control Register */
+#define UDCCR_UDE (1 << 0) /* UDC enable */
+#define UDCCR_UDA (1 << 1) /* UDC active */
+#define UDCCR_RSM (1 << 2) /* Device resume */
+#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
+#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
+#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
+#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
+#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
+
+#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */
+#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
+#define UDCCS0_IPR (1 << 1) /* IN packet ready */
+#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
+#define UDCCS0_SST (1 << 4) /* Sent stall */
+#define UDCCS0_FST (1 << 5) /* Force stall */
+#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
+#define UDCCS0_SA (1 << 7) /* Setup active */
+
+/* Bulk IN - Endpoint 1,6,11 */
+#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */
+#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */
+#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */
+
+#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_BI_SST (1 << 4) /* Sent stall */
+#define UDCCS_BI_FST (1 << 5) /* Force stall */
+#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
+
+/* Bulk OUT - Endpoint 2,7,12 */
+#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
+#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
+#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */
+
+#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_BO_DME (1 << 3) /* DMA enable */
+#define UDCCS_BO_SST (1 << 4) /* Sent stall */
+#define UDCCS_BO_FST (1 << 5) /* Force stall */
+#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
+
+/* Isochronous IN - Endpoint 3,8,13 */
+#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */
+#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */
+#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */
+
+#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
+
+/* Isochronous OUT - Endpoint 4,9,14 */
+#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */
+#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */
+#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */
+
+#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_IO_ROF (1 << 2) /* Receive overflow */
+#define UDCCS_IO_DME (1 << 3) /* DMA enable */
+#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
+
+/* Interrupt IN - Endpoint 5,10,15 */
+#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */
+#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */
+#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */
+
+#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_INT_SST (1 << 4) /* Sent stall */
+#define UDCCS_INT_FST (1 << 5) /* Force stall */
+#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
+
+#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */
+#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */
+#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */
+#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */
+#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */
+#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */
+#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */
+#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */
+#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */
+#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */
+#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */
+#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */
+#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */
+#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */
+#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */
+#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */
+#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */
+#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */
+#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */
+#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */
+#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */
+#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */
+#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */
+#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */
+
+#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */
+
+#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
+#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
+#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
+#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
+#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
+#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
+#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
+#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
+
+#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */
+
+#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
+#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
+#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
+#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
+#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
+#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
+#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
+#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
+
+#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */
+
+#define USIR0_IR0 (1 << 0) /* Interrupt request ep 0 */
+#define USIR0_IR1 (1 << 1) /* Interrupt request ep 1 */
+#define USIR0_IR2 (1 << 2) /* Interrupt request ep 2 */
+#define USIR0_IR3 (1 << 3) /* Interrupt request ep 3 */
+#define USIR0_IR4 (1 << 4) /* Interrupt request ep 4 */
+#define USIR0_IR5 (1 << 5) /* Interrupt request ep 5 */
+#define USIR0_IR6 (1 << 6) /* Interrupt request ep 6 */
+#define USIR0_IR7 (1 << 7) /* Interrupt request ep 7 */
+
+#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */
+
+#define USIR1_IR8 (1 << 0) /* Interrupt request ep 8 */
+#define USIR1_IR9 (1 << 1) /* Interrupt request ep 9 */
+#define USIR1_IR10 (1 << 2) /* Interrupt request ep 10 */
+#define USIR1_IR11 (1 << 3) /* Interrupt request ep 11 */
+#define USIR1_IR12 (1 << 4) /* Interrupt request ep 12 */
+#define USIR1_IR13 (1 << 5) /* Interrupt request ep 13 */
+#define USIR1_IR14 (1 << 6) /* Interrupt request ep 14 */
+#define USIR1_IR15 (1 << 7) /* Interrupt request ep 15 */
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa25x.h b/arch/arm/mach-pxa/include/mach/pxa25x.h
new file mode 100644
index 00000000..508c3ba1
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa25x.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA25x_H
+#define __MACH_PXA25x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+
+#endif /* __MACH_PXA25x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x-udc.h b/arch/arm/mach-pxa/include/mach/pxa27x-udc.h
new file mode 100644
index 00000000..ab1443f8
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa27x-udc.h
@@ -0,0 +1,257 @@
+#ifndef _ASM_ARCH_PXA27X_UDC_H
+#define _ASM_ARCH_PXA27X_UDC_H
+
+#ifdef _ASM_ARCH_PXA25X_UDC_H
+#error You cannot include both PXA25x and PXA27x UDC support
+#endif
+
+#define UDCCR __REG(0x40600000) /* UDC Control Register */
+#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
+#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation
+ Protocol Port Support */
+#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol
+ Support */
+#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol
+ Enable */
+#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */
+#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */
+#define UDCCR_ACN_S 11
+#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */
+#define UDCCR_AIN_S 8
+#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface
+ Setting Number */
+#define UDCCR_AAISN_S 5
+#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active
+ Configuration */
+#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration
+ Error */
+#define UDCCR_UDR (1 << 2) /* UDC Resume */
+#define UDCCR_UDA (1 << 1) /* UDC Active */
+#define UDCCR_UDE (1 << 0) /* UDC Enable */
+
+#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control Register0 */
+#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control Register1 */
+#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */
+#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */
+
+#define UDC_INT_FIFOERROR (0x2)
+#define UDC_INT_PACKETCMP (0x1)
+
+#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */
+#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */
+#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */
+#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */
+#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */
+
+#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status Register 0 */
+#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status Register 1 */
+#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */
+#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */
+#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */
+#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */
+#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */
+
+#define UDCFNR __REG(0x40600014) /* UDC Frame Number Register */
+#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go interrupt control */
+#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */
+#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever Interrupt
+ Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever Interrupt
+ Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising
+ Edge Interrupt Enable */
+#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling
+ Edge Interrupt Enable */
+#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge
+ Interrupt Enable */
+
+#define UP2OCR __REG(0x40600020) /* USB Port 2 Output Control register */
+#define UP3OCR __REG(0x40600024) /* USB Port 2 Output Control register */
+
+#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */
+#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */
+#define UP2OCR_DPPDE (1 << 2) /* Host Port 2 Transceiver D+ Pull Down Enable */
+#define UP2OCR_DMPDE (1 << 3) /* Host Port 2 Transceiver D- Pull Down Enable */
+#define UP2OCR_DPPUE (1 << 4) /* Host Port 2 Transceiver D+ Pull Up Enable */
+#define UP2OCR_DMPUE (1 << 5) /* Host Port 2 Transceiver D- Pull Up Enable */
+#define UP2OCR_DPPUBE (1 << 6) /* Host Port 2 Transceiver D+ Pull Up Bypass Enable */
+#define UP2OCR_DMPUBE (1 << 7) /* Host Port 2 Transceiver D- Pull Up Bypass Enable */
+#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */
+#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */
+#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */
+#define UP2OCR_HXS (1 << 16) /* Host Port 2 Transceiver Output Select */
+#define UP2OCR_HXOE (1 << 17) /* Host Port 2 Transceiver Output Enable */
+#define UP2OCR_SEOS(x) ((x & 7) << 24) /* Single-Ended Output Select */
+
+#define UDCCSN(x) __REG2(0x40600100, (x) << 2)
+#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status register - Endpoint 0 */
+#define UDCCSR0_SA (1 << 7) /* Setup Active */
+#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */
+#define UDCCSR0_FST (1 << 5) /* Force Stall */
+#define UDCCSR0_SST (1 << 4) /* Sent Stall */
+#define UDCCSR0_DME (1 << 3) /* DMA Enable */
+#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */
+#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */
+#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */
+
+#define UDCCSRA __REG(0x40600104) /* UDC Control/Status register - Endpoint A */
+#define UDCCSRB __REG(0x40600108) /* UDC Control/Status register - Endpoint B */
+#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status register - Endpoint C */
+#define UDCCSRD __REG(0x40600110) /* UDC Control/Status register - Endpoint D */
+#define UDCCSRE __REG(0x40600114) /* UDC Control/Status register - Endpoint E */
+#define UDCCSRF __REG(0x40600118) /* UDC Control/Status register - Endpoint F */
+#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status register - Endpoint G */
+#define UDCCSRH __REG(0x40600120) /* UDC Control/Status register - Endpoint H */
+#define UDCCSRI __REG(0x40600124) /* UDC Control/Status register - Endpoint I */
+#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status register - Endpoint J */
+#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status register - Endpoint K */
+#define UDCCSRL __REG(0x40600130) /* UDC Control/Status register - Endpoint L */
+#define UDCCSRM __REG(0x40600134) /* UDC Control/Status register - Endpoint M */
+#define UDCCSRN __REG(0x40600138) /* UDC Control/Status register - Endpoint N */
+#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status register - Endpoint P */
+#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status register - Endpoint Q */
+#define UDCCSRR __REG(0x40600144) /* UDC Control/Status register - Endpoint R */
+#define UDCCSRS __REG(0x40600148) /* UDC Control/Status register - Endpoint S */
+#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status register - Endpoint T */
+#define UDCCSRU __REG(0x40600150) /* UDC Control/Status register - Endpoint U */
+#define UDCCSRV __REG(0x40600154) /* UDC Control/Status register - Endpoint V */
+#define UDCCSRW __REG(0x40600158) /* UDC Control/Status register - Endpoint W */
+#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status register - Endpoint X */
+
+#define UDCCSR_DPE (1 << 9) /* Data Packet Error */
+#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */
+#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */
+#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */
+#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */
+#define UDCCSR_FST (1 << 5) /* Force STALL */
+#define UDCCSR_SST (1 << 4) /* Sent STALL */
+#define UDCCSR_DME (1 << 3) /* DMA Enable */
+#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */
+#define UDCCSR_PC (1 << 1) /* Packet Complete */
+#define UDCCSR_FS (1 << 0) /* FIFO needs service */
+
+#define UDCBCN(x) __REG2(0x40600200, (x)<<2)
+#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */
+#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */
+#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */
+#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */
+#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */
+#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */
+#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */
+#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */
+#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */
+#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */
+#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */
+#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */
+#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */
+#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */
+#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */
+#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */
+#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */
+#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */
+#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */
+#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */
+#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */
+#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */
+#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */
+#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */
+
+#define UDCDN(x) __REG2(0x40600300, (x)<<2)
+#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2))
+#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x))))
+#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */
+#define UDCDRA __REG(0x40600304) /* Data Register - EPA */
+#define UDCDRB __REG(0x40600308) /* Data Register - EPB */
+#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */
+#define UDCDRD __REG(0x40600310) /* Data Register - EPD */
+#define UDCDRE __REG(0x40600314) /* Data Register - EPE */
+#define UDCDRF __REG(0x40600318) /* Data Register - EPF */
+#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */
+#define UDCDRH __REG(0x40600320) /* Data Register - EPH */
+#define UDCDRI __REG(0x40600324) /* Data Register - EPI */
+#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */
+#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */
+#define UDCDRL __REG(0x40600330) /* Data Register - EPL */
+#define UDCDRM __REG(0x40600334) /* Data Register - EPM */
+#define UDCDRN __REG(0x40600338) /* Data Register - EPN */
+#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */
+#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */
+#define UDCDRR __REG(0x40600344) /* Data Register - EPR */
+#define UDCDRS __REG(0x40600348) /* Data Register - EPS */
+#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */
+#define UDCDRU __REG(0x40600350) /* Data Register - EPU */
+#define UDCDRV __REG(0x40600354) /* Data Register - EPV */
+#define UDCDRW __REG(0x40600358) /* Data Register - EPW */
+#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */
+
+#define UDCCN(x) __REG2(0x40600400, (x)<<2)
+#define UDCCRA __REG(0x40600404) /* Configuration register EPA */
+#define UDCCRB __REG(0x40600408) /* Configuration register EPB */
+#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */
+#define UDCCRD __REG(0x40600410) /* Configuration register EPD */
+#define UDCCRE __REG(0x40600414) /* Configuration register EPE */
+#define UDCCRF __REG(0x40600418) /* Configuration register EPF */
+#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */
+#define UDCCRH __REG(0x40600420) /* Configuration register EPH */
+#define UDCCRI __REG(0x40600424) /* Configuration register EPI */
+#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */
+#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */
+#define UDCCRL __REG(0x40600430) /* Configuration register EPL */
+#define UDCCRM __REG(0x40600434) /* Configuration register EPM */
+#define UDCCRN __REG(0x40600438) /* Configuration register EPN */
+#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */
+#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */
+#define UDCCRR __REG(0x40600444) /* Configuration register EPR */
+#define UDCCRS __REG(0x40600448) /* Configuration register EPS */
+#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */
+#define UDCCRU __REG(0x40600450) /* Configuration register EPU */
+#define UDCCRV __REG(0x40600454) /* Configuration register EPV */
+#define UDCCRW __REG(0x40600458) /* Configuration register EPW */
+#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */
+
+#define UDCCONR_CN (0x03 << 25) /* Configuration Number */
+#define UDCCONR_CN_S (25)
+#define UDCCONR_IN (0x07 << 22) /* Interface Number */
+#define UDCCONR_IN_S (22)
+#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */
+#define UDCCONR_AISN_S (19)
+#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */
+#define UDCCONR_EN_S (15)
+#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */
+#define UDCCONR_ET_S (13)
+#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */
+#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */
+#define UDCCONR_ET_NU (0x00 << 13) /* Not used */
+#define UDCCONR_ED (1 << 12) /* Endpoint Direction */
+#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */
+#define UDCCONR_MPS_S (2)
+#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */
+#define UDCCONR_EE (1 << 0) /* Endpoint Enable */
+
+
+#define UDC_INT_FIFOERROR (0x2)
+#define UDC_INT_PACKETCMP (0x1)
+
+#define UDC_FNR_MASK (0x7ff)
+
+#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST)
+#define UDC_BCR_MASK (0x3ff)
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x.h b/arch/arm/mach-pxa/include/mach/pxa27x.h
new file mode 100644
index 00000000..0b702693
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa27x.h
@@ -0,0 +1,22 @@
+#ifndef __MACH_PXA27x_H
+#define __MACH_PXA27x_H
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa27x.h>
+
+#define ARB_CNTRL __REG(0x48000048) /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK (1<<31) /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK (1<<30) /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK (1<<29) /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK (1<<28) /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK (1<<27) /* Be parked with USB when idle */
+#define ARB_LCD_PARK (1<<26) /* Be parked with LCD when idle */
+#define ARB_DMA_PARK (1<<25) /* Be parked with DMA when idle */
+#define ARB_CORE_PARK (1<<24) /* Be parked with core when idle */
+#define ARB_LOCK_FLAG (1<<23) /* Only Locking masters gain access to the bus */
+
+extern int __init pxa27x_set_pwrmode(unsigned int mode);
+
+#endif /* __MACH_PXA27x_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
new file mode 100644
index 00000000..ee6ced1c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
@@ -0,0 +1,187 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
+ *
+ * Taken from pxa-regs.h by Russell King
+ *
+ * Author: Nicolas Pitre
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PXA2XX_REGS_H
+#define __PXA2XX_REGS_H
+
+#include <mach/hardware.h>
+
+/*
+ * Power Manager
+ */
+
+#define PMCR __REG(0x40F00000) /* Power Manager Control Register */
+#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */
+#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */
+#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */
+#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */
+#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */
+#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */
+#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */
+#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */
+#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */
+#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
+#define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */
+#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
+
+#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */
+#define PSTR __REG(0x40F00038) /* Power Manager Standby Config Register */
+#define PSNR __REG(0x40F0003C) /* Power Manager Sense Config Register */
+#define PVCR __REG(0x40F00040) /* Power Manager VoltageControl Register */
+#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */
+#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */
+#define PCMD(x) __REG2(0x40F00080, (x)<<2)
+#define PCMD0 __REG(0x40F00080 + 0 * 4)
+#define PCMD1 __REG(0x40F00080 + 1 * 4)
+#define PCMD2 __REG(0x40F00080 + 2 * 4)
+#define PCMD3 __REG(0x40F00080 + 3 * 4)
+#define PCMD4 __REG(0x40F00080 + 4 * 4)
+#define PCMD5 __REG(0x40F00080 + 5 * 4)
+#define PCMD6 __REG(0x40F00080 + 6 * 4)
+#define PCMD7 __REG(0x40F00080 + 7 * 4)
+#define PCMD8 __REG(0x40F00080 + 8 * 4)
+#define PCMD9 __REG(0x40F00080 + 9 * 4)
+#define PCMD10 __REG(0x40F00080 + 10 * 4)
+#define PCMD11 __REG(0x40F00080 + 11 * 4)
+#define PCMD12 __REG(0x40F00080 + 12 * 4)
+#define PCMD13 __REG(0x40F00080 + 13 * 4)
+#define PCMD14 __REG(0x40F00080 + 14 * 4)
+#define PCMD15 __REG(0x40F00080 + 15 * 4)
+#define PCMD16 __REG(0x40F00080 + 16 * 4)
+#define PCMD17 __REG(0x40F00080 + 17 * 4)
+#define PCMD18 __REG(0x40F00080 + 18 * 4)
+#define PCMD19 __REG(0x40F00080 + 19 * 4)
+#define PCMD20 __REG(0x40F00080 + 20 * 4)
+#define PCMD21 __REG(0x40F00080 + 21 * 4)
+#define PCMD22 __REG(0x40F00080 + 22 * 4)
+#define PCMD23 __REG(0x40F00080 + 23 * 4)
+#define PCMD24 __REG(0x40F00080 + 24 * 4)
+#define PCMD25 __REG(0x40F00080 + 25 * 4)
+#define PCMD26 __REG(0x40F00080 + 26 * 4)
+#define PCMD27 __REG(0x40F00080 + 27 * 4)
+#define PCMD28 __REG(0x40F00080 + 28 * 4)
+#define PCMD29 __REG(0x40F00080 + 29 * 4)
+#define PCMD30 __REG(0x40F00080 + 30 * 4)
+#define PCMD31 __REG(0x40F00080 + 31 * 4)
+
+#define PCMD_MBC (1<<12)
+#define PCMD_DCE (1<<11)
+#define PCMD_LC (1<<10)
+/* FIXME: PCMD_SQC need be checked. */
+#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable,
+ bit 9 should be 0 all day. */
+#define PVCR_VCSA (0x1<<14)
+#define PVCR_CommandDelay (0xf80)
+#define PCFR_PI2C_EN (0x1 << 6)
+
+#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */
+#define PSSR_RDH (1 << 5) /* Read Disable Hold */
+#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
+#define PSSR_STS (1 << 3) /* Standby Mode Status */
+#define PSSR_VFS (1 << 2) /* VDD Fault Status */
+#define PSSR_BFS (1 << 1) /* Battery Fault Status */
+#define PSSR_SSS (1 << 0) /* Software Sleep Status */
+
+#define PSLR_SL_ROD (1 << 20) /* Sleep-Mode/Depp-Sleep Mode nRESET_OUT Disable */
+
+#define PCFR_RO (1 << 15) /* RDH Override */
+#define PCFR_PO (1 << 14) /* PH Override */
+#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */
+#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */
+#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */
+#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */
+#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */
+#define PCFR_GPR_EN (1 << 4) /* nRESET_GPIO Pin Enable */
+#define PCFR_DS (1 << 3) /* Deep Sleep Mode */
+#define PCFR_FS (1 << 2) /* Float Static Chip Selects */
+#define PCFR_FP (1 << 1) /* Float PCMCIA controls */
+#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */
+
+#define RCSR_GPR (1 << 3) /* GPIO Reset */
+#define RCSR_SMR (1 << 2) /* Sleep Mode */
+#define RCSR_WDR (1 << 1) /* Watchdog Reset */
+#define RCSR_HWR (1 << 0) /* Hardware Reset */
+
+#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */
+#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */
+#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */
+#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */
+#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */
+#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */
+#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */
+#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */
+#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */
+#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */
+#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */
+#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */
+#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */
+#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */
+#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */
+#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */
+#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */
+#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
+
+/*
+ * PXA2xx specific Core clock definitions
+ */
+#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */
+#define CCSR __REG(0x4130000C) /* Core Clock Status Register */
+#define CKEN __REG(0x41300004) /* Clock Enable Register */
+#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */
+
+#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */
+#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
+#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
+
+#define CKEN_AC97CONF (31) /* AC97 Controller Configuration */
+#define CKEN_CAMERA (24) /* Camera Interface Clock Enable */
+#define CKEN_SSP1 (23) /* SSP1 Unit Clock Enable */
+#define CKEN_MEMC (22) /* Memory Controller Clock Enable */
+#define CKEN_MEMSTK (21) /* Memory Stick Host Controller */
+#define CKEN_IM (20) /* Internal Memory Clock Enable */
+#define CKEN_KEYPAD (19) /* Keypad Interface Clock Enable */
+#define CKEN_USIM (18) /* USIM Unit Clock Enable */
+#define CKEN_MSL (17) /* MSL Unit Clock Enable */
+#define CKEN_LCD (16) /* LCD Unit Clock Enable */
+#define CKEN_PWRI2C (15) /* PWR I2C Unit Clock Enable */
+#define CKEN_I2C (14) /* I2C Unit Clock Enable */
+#define CKEN_FICP (13) /* FICP Unit Clock Enable */
+#define CKEN_MMC (12) /* MMC Unit Clock Enable */
+#define CKEN_USB (11) /* USB Unit Clock Enable */
+#define CKEN_ASSP (10) /* ASSP (SSP3) Clock Enable */
+#define CKEN_USBHOST (10) /* USB Host Unit Clock Enable */
+#define CKEN_OSTIMER (9) /* OS Timer Unit Clock Enable */
+#define CKEN_NSSP (9) /* NSSP (SSP2) Clock Enable */
+#define CKEN_I2S (8) /* I2S Unit Clock Enable */
+#define CKEN_BTUART (7) /* BTUART Unit Clock Enable */
+#define CKEN_FFUART (6) /* FFUART Unit Clock Enable */
+#define CKEN_STUART (5) /* STUART Unit Clock Enable */
+#define CKEN_HWUART (4) /* HWUART Unit Clock Enable */
+#define CKEN_SSP3 (4) /* SSP3 Unit Clock Enable */
+#define CKEN_SSP (3) /* SSP Unit Clock Enable */
+#define CKEN_SSP2 (3) /* SSP2 Unit Clock Enable */
+#define CKEN_AC97 (2) /* AC97 Unit Clock Enable */
+#define CKEN_PWM1 (1) /* PWM1 Clock Enable */
+#define CKEN_PWM0 (0) /* PWM0 Clock Enable */
+
+#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */
+#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */
+
+/* PWRMODE register M field values */
+
+#define PWRMODE_IDLE 0x1
+#define PWRMODE_STANDBY 0x2
+#define PWRMODE_SLEEP 0x3
+#define PWRMODE_DEEPSLEEP 0x7
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/pxa300.h b/arch/arm/mach-pxa/include/mach/pxa300.h
new file mode 100644
index 00000000..2f33076c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa300.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA300_H
+#define __MACH_PXA300_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa300.h>
+
+#endif /* __MACH_PXA300_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa320.h b/arch/arm/mach-pxa/include/mach/pxa320.h
new file mode 100644
index 00000000..cab78e90
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa320.h
@@ -0,0 +1,9 @@
+#ifndef __MACH_PXA320_H
+#define __MACH_PXA320_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa320.h>
+
+#endif /* __MACH_PXA320_H */
+
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
new file mode 100644
index 00000000..207ecb49
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
@@ -0,0 +1,205 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pxa3xx-regs.h
+ *
+ * PXA3xx specific register definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_PXA3XX_REGS_H
+#define __ASM_ARCH_PXA3XX_REGS_H
+
+#include <mach/hardware.h>
+
+/*
+ * Oscillator Configuration Register (OSCC)
+ */
+#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */
+
+#define OSCC_PEN (1 << 11) /* 13MHz POUT */
+
+
+/*
+ * Service Power Management Unit (MPMU)
+ */
+#define PMCR __REG(0x40F50000) /* Power Manager Control Register */
+#define PSR __REG(0x40F50004) /* Power Manager S2 Status Register */
+#define PSPR __REG(0x40F50008) /* Power Manager Scratch Pad Register */
+#define PCFR __REG(0x40F5000C) /* Power Manager General Configuration Register */
+#define PWER __REG(0x40F50010) /* Power Manager Wake-up Enable Register */
+#define PWSR __REG(0x40F50014) /* Power Manager Wake-up Status Register */
+#define PECR __REG(0x40F50018) /* Power Manager EXT_WAKEUP[1:0] Control Register */
+#define DCDCSR __REG(0x40F50080) /* DC-DC Controller Status Register */
+#define PVCR __REG(0x40F50100) /* Power Manager Voltage Change Control Register */
+#define PCMD(x) __REG(0x40F50110 + ((x) << 2))
+
+/*
+ * Slave Power Management Unit
+ */
+#define ASCR __REG(0x40f40000) /* Application Subsystem Power Status/Configuration */
+#define ARSR __REG(0x40f40004) /* Application Subsystem Reset Status */
+#define AD3ER __REG(0x40f40008) /* Application Subsystem Wake-Up from D3 Enable */
+#define AD3SR __REG(0x40f4000c) /* Application Subsystem Wake-Up from D3 Status */
+#define AD2D0ER __REG(0x40f40010) /* Application Subsystem Wake-Up from D2 to D0 Enable */
+#define AD2D0SR __REG(0x40f40014) /* Application Subsystem Wake-Up from D2 to D0 Status */
+#define AD2D1ER __REG(0x40f40018) /* Application Subsystem Wake-Up from D2 to D1 Enable */
+#define AD2D1SR __REG(0x40f4001c) /* Application Subsystem Wake-Up from D2 to D1 Status */
+#define AD1D0ER __REG(0x40f40020) /* Application Subsystem Wake-Up from D1 to D0 Enable */
+#define AD1D0SR __REG(0x40f40024) /* Application Subsystem Wake-Up from D1 to D0 Status */
+#define AGENP __REG(0x40f4002c) /* Application Subsystem General Purpose */
+#define AD3R __REG(0x40f40030) /* Application Subsystem D3 Configuration */
+#define AD2R __REG(0x40f40034) /* Application Subsystem D2 Configuration */
+#define AD1R __REG(0x40f40038) /* Application Subsystem D1 Configuration */
+
+/*
+ * Application Subsystem Configuration bits.
+ */
+#define ASCR_RDH (1 << 31)
+#define ASCR_D1S (1 << 2)
+#define ASCR_D2S (1 << 1)
+#define ASCR_D3S (1 << 0)
+
+/*
+ * Application Reset Status bits.
+ */
+#define ARSR_GPR (1 << 3)
+#define ARSR_LPMR (1 << 2)
+#define ARSR_WDT (1 << 1)
+#define ARSR_HWR (1 << 0)
+
+/*
+ * Application Subsystem Wake-Up bits.
+ */
+#define ADXER_WRTC (1 << 31) /* RTC */
+#define ADXER_WOST (1 << 30) /* OS Timer */
+#define ADXER_WTSI (1 << 29) /* Touchscreen */
+#define ADXER_WUSBH (1 << 28) /* USB host */
+#define ADXER_WUSB2 (1 << 26) /* USB client 2.0 */
+#define ADXER_WMSL0 (1 << 24) /* MSL port 0*/
+#define ADXER_WDMUX3 (1 << 23) /* USB EDMUX3 */
+#define ADXER_WDMUX2 (1 << 22) /* USB EDMUX2 */
+#define ADXER_WKP (1 << 21) /* Keypad */
+#define ADXER_WUSIM1 (1 << 20) /* USIM Port 1 */
+#define ADXER_WUSIM0 (1 << 19) /* USIM Port 0 */
+#define ADXER_WOTG (1 << 16) /* USBOTG input */
+#define ADXER_MFP_WFLASH (1 << 15) /* MFP: Data flash busy */
+#define ADXER_MFP_GEN12 (1 << 14) /* MFP: MMC3/GPIO/OST inputs */
+#define ADXER_MFP_WMMC2 (1 << 13) /* MFP: MMC2 */
+#define ADXER_MFP_WMMC1 (1 << 12) /* MFP: MMC1 */
+#define ADXER_MFP_WI2C (1 << 11) /* MFP: I2C */
+#define ADXER_MFP_WSSP4 (1 << 10) /* MFP: SSP4 */
+#define ADXER_MFP_WSSP3 (1 << 9) /* MFP: SSP3 */
+#define ADXER_MFP_WMAXTRIX (1 << 8) /* MFP: matrix keypad */
+#define ADXER_MFP_WUART3 (1 << 7) /* MFP: UART3 */
+#define ADXER_MFP_WUART2 (1 << 6) /* MFP: UART2 */
+#define ADXER_MFP_WUART1 (1 << 5) /* MFP: UART1 */
+#define ADXER_MFP_WSSP2 (1 << 4) /* MFP: SSP2 */
+#define ADXER_MFP_WSSP1 (1 << 3) /* MFP: SSP1 */
+#define ADXER_MFP_WAC97 (1 << 2) /* MFP: AC97 */
+#define ADXER_WEXTWAKE1 (1 << 1) /* External Wake 1 */
+#define ADXER_WEXTWAKE0 (1 << 0) /* External Wake 0 */
+
+/*
+ * AD3R/AD2R/AD1R bits. R2-R5 are only defined for PXA320.
+ */
+#define ADXR_L2 (1 << 8)
+#define ADXR_R5 (1 << 5)
+#define ADXR_R4 (1 << 4)
+#define ADXR_R3 (1 << 3)
+#define ADXR_R2 (1 << 2)
+#define ADXR_R1 (1 << 1)
+#define ADXR_R0 (1 << 0)
+
+/*
+ * Values for PWRMODE CP15 register
+ */
+#define PXA3xx_PM_S3D4C4 0x07 /* aka deep sleep */
+#define PXA3xx_PM_S2D3C4 0x06 /* aka sleep */
+#define PXA3xx_PM_S0D2C2 0x03 /* aka standby */
+#define PXA3xx_PM_S0D1C2 0x02 /* aka LCD refresh */
+#define PXA3xx_PM_S0D0C1 0x01
+
+/*
+ * Application Subsystem Clock
+ */
+#define ACCR __REG(0x41340000) /* Application Subsystem Clock Configuration Register */
+#define ACSR __REG(0x41340004) /* Application Subsystem Clock Status Register */
+#define AICSR __REG(0x41340008) /* Application Subsystem Interrupt Control/Status Register */
+#define CKENA __REG(0x4134000C) /* A Clock Enable Register */
+#define CKENB __REG(0x41340010) /* B Clock Enable Register */
+#define AC97_DIV __REG(0x41340014) /* AC97 clock divisor value register */
+
+#define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */
+#define ACCR_SPDIS (1 << 30) /* System PLL Output Disable */
+#define ACCR_D0CS (1 << 26) /* D0 Mode Clock Select */
+#define ACCR_PCCE (1 << 11) /* Power Mode Change Clock Enable */
+#define ACCR_DDR_D0CS (1 << 7) /* DDR SDRAM clock frequency in D0CS (PXA31x only) */
+
+#define ACCR_SMCFS_MASK (0x7 << 23) /* Static Memory Controller Frequency Select */
+#define ACCR_SFLFS_MASK (0x3 << 18) /* Frequency Select for Internal Memory Controller */
+#define ACCR_XSPCLK_MASK (0x3 << 16) /* Core Frequency during Frequency Change */
+#define ACCR_HSS_MASK (0x3 << 14) /* System Bus-Clock Frequency Select */
+#define ACCR_DMCFS_MASK (0x3 << 12) /* Dynamic Memory Controller Clock Frequency Select */
+#define ACCR_XN_MASK (0x7 << 8) /* Core PLL Turbo-Mode-to-Run-Mode Ratio */
+#define ACCR_XL_MASK (0x1f) /* Core PLL Run-Mode-to-Oscillator Ratio */
+
+#define ACCR_SMCFS(x) (((x) & 0x7) << 23)
+#define ACCR_SFLFS(x) (((x) & 0x3) << 18)
+#define ACCR_XSPCLK(x) (((x) & 0x3) << 16)
+#define ACCR_HSS(x) (((x) & 0x3) << 14)
+#define ACCR_DMCFS(x) (((x) & 0x3) << 12)
+#define ACCR_XN(x) (((x) & 0x7) << 8)
+#define ACCR_XL(x) ((x) & 0x1f)
+
+/*
+ * Clock Enable Bit
+ */
+#define CKEN_LCD 1 /* < LCD Clock Enable */
+#define CKEN_USBH 2 /* < USB host clock enable */
+#define CKEN_CAMERA 3 /* < Camera interface clock enable */
+#define CKEN_NAND 4 /* < NAND Flash Controller Clock Enable */
+#define CKEN_USB2 6 /* < USB 2.0 client clock enable. */
+#define CKEN_DMC 8 /* < Dynamic Memory Controller clock enable */
+#define CKEN_SMC 9 /* < Static Memory Controller clock enable */
+#define CKEN_ISC 10 /* < Internal SRAM Controller clock enable */
+#define CKEN_BOOT 11 /* < Boot rom clock enable */
+#define CKEN_MMC1 12 /* < MMC1 Clock enable */
+#define CKEN_MMC2 13 /* < MMC2 clock enable */
+#define CKEN_KEYPAD 14 /* < Keypand Controller Clock Enable */
+#define CKEN_CIR 15 /* < Consumer IR Clock Enable */
+#define CKEN_USIM0 17 /* < USIM[0] Clock Enable */
+#define CKEN_USIM1 18 /* < USIM[1] Clock Enable */
+#define CKEN_TPM 19 /* < TPM clock enable */
+#define CKEN_UDC 20 /* < UDC clock enable */
+#define CKEN_BTUART 21 /* < BTUART clock enable */
+#define CKEN_FFUART 22 /* < FFUART clock enable */
+#define CKEN_STUART 23 /* < STUART clock enable */
+#define CKEN_AC97 24 /* < AC97 clock enable */
+#define CKEN_TOUCH 25 /* < Touch screen Interface Clock Enable */
+#define CKEN_SSP1 26 /* < SSP1 clock enable */
+#define CKEN_SSP2 27 /* < SSP2 clock enable */
+#define CKEN_SSP3 28 /* < SSP3 clock enable */
+#define CKEN_SSP4 29 /* < SSP4 clock enable */
+#define CKEN_MSL0 30 /* < MSL0 clock enable */
+#define CKEN_PWM0 32 /* < PWM[0] clock enable */
+#define CKEN_PWM1 33 /* < PWM[1] clock enable */
+#define CKEN_I2C 36 /* < I2C clock enable */
+#define CKEN_INTC 38 /* < Interrupt controller clock enable */
+#define CKEN_GPIO 39 /* < GPIO clock enable */
+#define CKEN_1WIRE 40 /* < 1-wire clock enable */
+#define CKEN_HSIO2 41 /* < HSIO2 clock enable */
+#define CKEN_MINI_IM 48 /* < Mini-IM */
+#define CKEN_MINI_LCD 49 /* < Mini LCD */
+
+#define CKEN_MMC3 5 /* < MMC3 Clock Enable */
+#define CKEN_MVED 43 /* < MVED clock enable */
+
+/* Note: GCU clock enable bit differs on PXA300/PXA310 and PXA320 */
+#define CKEN_PXA300_GCU 42 /* Graphics controller clock enable */
+#define CKEN_PXA320_GCU 7 /* Graphics controller clock enable */
+
+#endif /* __ASM_ARCH_PXA3XX_REGS_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
new file mode 100644
index 00000000..9d82cb65
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx-u2d.h
@@ -0,0 +1,35 @@
+/*
+ * PXA3xx U2D header
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __PXA310_U2D__
+#define __PXA310_U2D__
+
+#include <linux/usb/ulpi.h>
+
+struct pxa3xx_u2d_platform_data {
+
+#define ULPI_SER_6PIN (1 << 0)
+#define ULPI_SER_3PIN (1 << 1)
+ unsigned int ulpi_mode;
+
+ int (*init)(struct device *);
+ void (*exit)(struct device *);
+};
+
+
+/* Start PXA3xx U2D host */
+int pxa3xx_u2d_start_hc(struct usb_bus *host);
+/* Stop PXA3xx U2D host */
+void pxa3xx_u2d_stop_hc(struct usb_bus *host);
+
+extern void pxa3xx_set_u2d_info(struct pxa3xx_u2d_platform_data *info);
+
+#endif /* __PXA310_U2D__ */
diff --git a/arch/arm/mach-pxa/include/mach/pxa930.h b/arch/arm/mach-pxa/include/mach/pxa930.h
new file mode 100644
index 00000000..d45f76a9
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa930.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_PXA930_H
+#define __MACH_PXA930_H
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa930.h>
+
+#endif /* __MACH_PXA930_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa930_rotary.h b/arch/arm/mach-pxa/include/mach/pxa930_rotary.h
new file mode 100644
index 00000000..053587ca
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa930_rotary.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_ARCH_PXA930_ROTARY_H
+#define __ASM_ARCH_PXA930_ROTARY_H
+
+/* NOTE:
+ *
+ * rotary can be either interpreted as a ralative input event (e.g.
+ * REL_WHEEL or REL_HWHEEL) or a specific key event (e.g. UP/DOWN
+ * or LEFT/RIGHT), depending on if up_key & down_key are assigned
+ * or rel_code is assigned a non-zero value. When all are non-zero,
+ * up_key and down_key will be preferred.
+ */
+struct pxa930_rotary_platform_data {
+ int up_key;
+ int down_key;
+ int rel_code;
+};
+
+void __init pxa930_set_rotarykey_info(struct pxa930_rotary_platform_data *info);
+
+#endif /* __ASM_ARCH_PXA930_ROTARY_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa930_trkball.h b/arch/arm/mach-pxa/include/mach/pxa930_trkball.h
new file mode 100644
index 00000000..5e0789bc
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa930_trkball.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_ARCH_PXA930_TRKBALL_H
+#define __ASM_ARCH_PXA930_TRKBALL_H
+
+struct pxa930_trkball_platform_data {
+ int x_filter;
+ int y_filter;
+};
+
+#endif /* __ASM_ARCH_PXA930_TRKBALL_H */
+
diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h
new file mode 100644
index 00000000..01a45ac4
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxafb.h
@@ -0,0 +1,162 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pxafb.h
+ *
+ * Support for the xscale frame buffer.
+ *
+ * Author: Jean-Frederic Clere
+ * Created: Sep 22, 2003
+ * Copyright: jfclere@sinix.net
+ *
+ * This program is free software; you can 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/fb.h>
+#include <mach/regs-lcd.h>
+
+/*
+ * Supported LCD connections
+ *
+ * bits 0 - 3: for LCD panel type:
+ *
+ * STN - for passive matrix
+ * DSTN - for dual scan passive matrix
+ * TFT - for active matrix
+ *
+ * bits 4 - 9 : for bus width
+ * bits 10-17 : for AC Bias Pin Frequency
+ * bit 18 : for output enable polarity
+ * bit 19 : for pixel clock edge
+ * bit 20 : for output pixel format when base is RGBT16
+ */
+#define LCD_CONN_TYPE(_x) ((_x) & 0x0f)
+#define LCD_CONN_WIDTH(_x) (((_x) >> 4) & 0x1f)
+
+#define LCD_TYPE_MASK 0xf
+#define LCD_TYPE_UNKNOWN 0
+#define LCD_TYPE_MONO_STN 1
+#define LCD_TYPE_MONO_DSTN 2
+#define LCD_TYPE_COLOR_STN 3
+#define LCD_TYPE_COLOR_DSTN 4
+#define LCD_TYPE_COLOR_TFT 5
+#define LCD_TYPE_SMART_PANEL 6
+#define LCD_TYPE_MAX 7
+
+#define LCD_MONO_STN_4BPP ((4 << 4) | LCD_TYPE_MONO_STN)
+#define LCD_MONO_STN_8BPP ((8 << 4) | LCD_TYPE_MONO_STN)
+#define LCD_MONO_DSTN_8BPP ((8 << 4) | LCD_TYPE_MONO_DSTN)
+#define LCD_COLOR_STN_8BPP ((8 << 4) | LCD_TYPE_COLOR_STN)
+#define LCD_COLOR_DSTN_16BPP ((16 << 4) | LCD_TYPE_COLOR_DSTN)
+#define LCD_COLOR_TFT_8BPP ((8 << 4) | LCD_TYPE_COLOR_TFT)
+#define LCD_COLOR_TFT_16BPP ((16 << 4) | LCD_TYPE_COLOR_TFT)
+#define LCD_COLOR_TFT_18BPP ((18 << 4) | LCD_TYPE_COLOR_TFT)
+#define LCD_SMART_PANEL_8BPP ((8 << 4) | LCD_TYPE_SMART_PANEL)
+#define LCD_SMART_PANEL_16BPP ((16 << 4) | LCD_TYPE_SMART_PANEL)
+#define LCD_SMART_PANEL_18BPP ((18 << 4) | LCD_TYPE_SMART_PANEL)
+
+#define LCD_AC_BIAS_FREQ(x) (((x) & 0xff) << 10)
+#define LCD_BIAS_ACTIVE_HIGH (0 << 18)
+#define LCD_BIAS_ACTIVE_LOW (1 << 18)
+#define LCD_PCLK_EDGE_RISE (0 << 19)
+#define LCD_PCLK_EDGE_FALL (1 << 19)
+#define LCD_ALTERNATE_MAPPING (1 << 20)
+
+/*
+ * This structure describes the machine which we are running on.
+ * It is set in linux/arch/arm/mach-pxa/machine_name.c and used in the probe routine
+ * of linux/drivers/video/pxafb.c
+ */
+struct pxafb_mode_info {
+ u_long pixclock;
+
+ u_short xres;
+ u_short yres;
+
+ u_char bpp;
+ u_int cmap_greyscale:1,
+ depth:8,
+ transparency:1,
+ unused:22;
+
+ /* Parallel Mode Timing */
+ u_char hsync_len;
+ u_char left_margin;
+ u_char right_margin;
+
+ u_char vsync_len;
+ u_char upper_margin;
+ u_char lower_margin;
+ u_char sync;
+
+ /* Smart Panel Mode Timing - see PXA27x DM 7.4.15.0.3 for details
+ * Note:
+ * 1. all parameters in nanosecond (ns)
+ * 2. a0cs{rd,wr}_set_hld are controlled by the same register bits
+ * in pxa27x and pxa3xx, initialize them to the same value or
+ * the larger one will be used
+ * 3. same to {rd,wr}_pulse_width
+ *
+ * 4. LCD_PCLK_EDGE_{RISE,FALL} controls the L_PCLK_WR polarity
+ * 5. sync & FB_SYNC_HOR_HIGH_ACT controls the L_LCLK_A0
+ * 6. sync & FB_SYNC_VERT_HIGH_ACT controls the L_LCLK_RD
+ */
+ unsigned a0csrd_set_hld; /* A0 and CS Setup/Hold Time before/after L_FCLK_RD */
+ unsigned a0cswr_set_hld; /* A0 and CS Setup/Hold Time before/after L_PCLK_WR */
+ unsigned wr_pulse_width; /* L_PCLK_WR pulse width */
+ unsigned rd_pulse_width; /* L_FCLK_RD pulse width */
+ unsigned cmd_inh_time; /* Command Inhibit time between two writes */
+ unsigned op_hold_time; /* Output Hold time from L_FCLK_RD negation */
+};
+
+struct pxafb_mach_info {
+ struct pxafb_mode_info *modes;
+ unsigned int num_modes;
+
+ unsigned int lcd_conn;
+ unsigned long video_mem_size;
+
+ u_int fixed_modes:1,
+ cmap_inverse:1,
+ cmap_static:1,
+ acceleration_enabled:1,
+ unused:28;
+
+ /* The following should be defined in LCCR0
+ * LCCR0_Act or LCCR0_Pas Active or Passive
+ * LCCR0_Sngl or LCCR0_Dual Single/Dual panel
+ * LCCR0_Mono or LCCR0_Color Mono/Color
+ * LCCR0_4PixMono or LCCR0_8PixMono (in mono single mode)
+ * LCCR0_DMADel(Tcpu) (optional) DMA request delay
+ *
+ * The following should not be defined in LCCR0:
+ * LCCR0_OUM, LCCR0_BM, LCCR0_QDM, LCCR0_DIS, LCCR0_EFM
+ * LCCR0_IUM, LCCR0_SFM, LCCR0_LDM, LCCR0_ENB
+ */
+ u_int lccr0;
+ /* The following should be defined in LCCR3
+ * LCCR3_OutEnH or LCCR3_OutEnL Output enable polarity
+ * LCCR3_PixRsEdg or LCCR3_PixFlEdg Pixel clock edge type
+ * LCCR3_Acb(X) AB Bias pin frequency
+ * LCCR3_DPC (optional) Double Pixel Clock mode (untested)
+ *
+ * The following should not be defined in LCCR3
+ * LCCR3_HSP, LCCR3_VSP, LCCR0_Pcd(x), LCCR3_Bpp
+ */
+ u_int lccr3;
+ /* The following should be defined in LCCR4
+ * LCCR4_PAL_FOR_0 or LCCR4_PAL_FOR_1 or LCCR4_PAL_FOR_2
+ *
+ * All other bits in LCCR4 should be left alone.
+ */
+ u_int lccr4;
+ void (*pxafb_backlight_power)(int);
+ void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
+ void (*smart_update)(struct fb_info *);
+};
+
+void pxa_set_fb_info(struct device *, struct pxafb_mach_info *);
+unsigned long pxafb_get_hsync_time(struct device *dev);
+
+extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);
+extern int pxafb_smart_flush(struct fb_info *info);
diff --git a/arch/arm/mach-pxa/include/mach/regs-ac97.h b/arch/arm/mach-pxa/include/mach/regs-ac97.h
new file mode 100644
index 00000000..b8d14bd9
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-ac97.h
@@ -0,0 +1,101 @@
+#ifndef __ASM_ARCH_REGS_AC97_H
+#define __ASM_ARCH_REGS_AC97_H
+
+#include <mach/hardware.h>
+
+/*
+ * AC97 Controller registers
+ */
+
+#define POCR __REG(0x40500000) /* PCM Out Control Register */
+#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+#define POCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
+
+#define PICR __REG(0x40500004) /* PCM In Control Register */
+#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+#define PICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
+
+#define MCCR __REG(0x40500008) /* Mic In Control Register */
+#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
+#define MCCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
+
+#define GCR __REG(0x4050000C) /* Global Control Register */
+#ifdef CONFIG_PXA3xx
+#define GCR_CLKBPB (1 << 31) /* Internal clock enable */
+#endif
+#define GCR_nDMAEN (1 << 24) /* non DMA Enable */
+#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */
+#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */
+#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */
+#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */
+#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */
+#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */
+#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */
+#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */
+#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */
+#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */
+
+#define POSR __REG(0x40500010) /* PCM Out Status Register */
+#define POSR_FIFOE (1 << 4) /* FIFO error */
+#define POSR_FSR (1 << 2) /* FIFO Service Request */
+
+#define PISR __REG(0x40500014) /* PCM In Status Register */
+#define PISR_FIFOE (1 << 4) /* FIFO error */
+#define PISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */
+#define PISR_FSR (1 << 2) /* FIFO Service Request */
+
+#define MCSR __REG(0x40500018) /* Mic In Status Register */
+#define MCSR_FIFOE (1 << 4) /* FIFO error */
+#define MCSR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */
+#define MCSR_FSR (1 << 2) /* FIFO Service Request */
+
+#define GSR __REG(0x4050001C) /* Global Status Register */
+#define GSR_CDONE (1 << 19) /* Command Done */
+#define GSR_SDONE (1 << 18) /* Status Done */
+#define GSR_RDCS (1 << 15) /* Read Completion Status */
+#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */
+#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */
+#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */
+#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */
+#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */
+#define GSR_SCR (1 << 9) /* Secondary Codec Ready */
+#define GSR_PCR (1 << 8) /* Primary Codec Ready */
+#define GSR_MCINT (1 << 7) /* Mic In Interrupt */
+#define GSR_POINT (1 << 6) /* PCM Out Interrupt */
+#define GSR_PIINT (1 << 5) /* PCM In Interrupt */
+#define GSR_ACOFFD (1 << 3) /* AC-link Shut Off Done */
+#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */
+#define GSR_MIINT (1 << 1) /* Modem In Interrupt */
+#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */
+
+#define CAR __REG(0x40500020) /* CODEC Access Register */
+#define CAR_CAIP (1 << 0) /* Codec Access In Progress */
+
+#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */
+#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */
+
+#define MOCR __REG(0x40500100) /* Modem Out Control Register */
+#define MOCR_FEIE (1 << 3) /* FIFO Error */
+#define MOCR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
+
+#define MICR __REG(0x40500108) /* Modem In Control Register */
+#define MICR_FEIE (1 << 3) /* FIFO Error */
+#define MICR_FSRIE (1 << 1) /* FIFO Service Request Interrupt Enable */
+
+#define MOSR __REG(0x40500110) /* Modem Out Status Register */
+#define MOSR_FIFOE (1 << 4) /* FIFO error */
+#define MOSR_FSR (1 << 2) /* FIFO Service Request */
+
+#define MISR __REG(0x40500118) /* Modem In Status Register */
+#define MISR_FIFOE (1 << 4) /* FIFO error */
+#define MISR_EOC (1 << 3) /* DMA End-of-Chain (exclusive clear) */
+#define MISR_FSR (1 << 2) /* FIFO Service Request */
+
+#define MODR __REG(0x40500140) /* Modem FIFO Data Register */
+
+#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */
+#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */
+#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */
+#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */
+
+#endif /* __ASM_ARCH_REGS_AC97_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h
new file mode 100644
index 00000000..662288eb
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
@@ -0,0 +1,30 @@
+#ifndef __ASM_MACH_REGS_INTC_H
+#define __ASM_MACH_REGS_INTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Interrupt Controller
+ */
+
+#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
+#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
+#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
+#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
+#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
+#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
+#define ICHP __REG(0x40D00018) /* Interrupt Controller Highest Priority Register */
+
+#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
+#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
+#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
+#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
+#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
+
+#define ICIP3 __REG(0x40D00130) /* Interrupt Controller IRQ Pending Register 3 */
+#define ICMR3 __REG(0x40D00134) /* Interrupt Controller Mask Register 3 */
+#define ICLR3 __REG(0x40D00138) /* Interrupt Controller Level Register 3 */
+#define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */
+#define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */
+
+#endif /* __ASM_MACH_REGS_INTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-lcd.h b/arch/arm/mach-pxa/include/mach/regs-lcd.h
new file mode 100644
index 00000000..f82dcea7
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-lcd.h
@@ -0,0 +1,197 @@
+#ifndef __ASM_ARCH_REGS_LCD_H
+#define __ASM_ARCH_REGS_LCD_H
+
+#include <mach/bitfield.h>
+
+/*
+ * LCD Controller Registers and Bits Definitions
+ */
+#define LCCR0 (0x000) /* LCD Controller Control Register 0 */
+#define LCCR1 (0x004) /* LCD Controller Control Register 1 */
+#define LCCR2 (0x008) /* LCD Controller Control Register 2 */
+#define LCCR3 (0x00C) /* LCD Controller Control Register 3 */
+#define LCCR4 (0x010) /* LCD Controller Control Register 4 */
+#define LCCR5 (0x014) /* LCD Controller Control Register 5 */
+#define LCSR (0x038) /* LCD Controller Status Register 0 */
+#define LCSR1 (0x034) /* LCD Controller Status Register 1 */
+#define LIIDR (0x03C) /* LCD Controller Interrupt ID Register */
+#define TMEDRGBR (0x040) /* TMED RGB Seed Register */
+#define TMEDCR (0x044) /* TMED Control Register */
+
+#define FBR0 (0x020) /* DMA Channel 0 Frame Branch Register */
+#define FBR1 (0x024) /* DMA Channel 1 Frame Branch Register */
+#define FBR2 (0x028) /* DMA Channel 2 Frame Branch Register */
+#define FBR3 (0x02C) /* DMA Channel 2 Frame Branch Register */
+#define FBR4 (0x030) /* DMA Channel 2 Frame Branch Register */
+#define FBR5 (0x110) /* DMA Channel 2 Frame Branch Register */
+#define FBR6 (0x114) /* DMA Channel 2 Frame Branch Register */
+
+#define OVL1C1 (0x050) /* Overlay 1 Control Register 1 */
+#define OVL1C2 (0x060) /* Overlay 1 Control Register 2 */
+#define OVL2C1 (0x070) /* Overlay 2 Control Register 1 */
+#define OVL2C2 (0x080) /* Overlay 2 Control Register 2 */
+
+#define CMDCR (0x100) /* Command Control Register */
+#define PRSR (0x104) /* Panel Read Status Register */
+
+#define LCCR3_BPP(x) ((((x) & 0x7) << 24) | (((x) & 0x8) ? (1 << 29) : 0))
+
+#define LCCR3_PDFOR_0 (0 << 30)
+#define LCCR3_PDFOR_1 (1 << 30)
+#define LCCR3_PDFOR_2 (2 << 30)
+#define LCCR3_PDFOR_3 (3 << 30)
+
+#define LCCR4_PAL_FOR_0 (0 << 15)
+#define LCCR4_PAL_FOR_1 (1 << 15)
+#define LCCR4_PAL_FOR_2 (2 << 15)
+#define LCCR4_PAL_FOR_3 (3 << 15)
+#define LCCR4_PAL_FOR_MASK (3 << 15)
+
+#define FDADR0 (0x200) /* DMA Channel 0 Frame Descriptor Address Register */
+#define FDADR1 (0x210) /* DMA Channel 1 Frame Descriptor Address Register */
+#define FDADR2 (0x220) /* DMA Channel 2 Frame Descriptor Address Register */
+#define FDADR3 (0x230) /* DMA Channel 3 Frame Descriptor Address Register */
+#define FDADR4 (0x240) /* DMA Channel 4 Frame Descriptor Address Register */
+#define FDADR5 (0x250) /* DMA Channel 5 Frame Descriptor Address Register */
+#define FDADR6 (0x260) /* DMA Channel 6 Frame Descriptor Address Register */
+
+#define LCCR0_ENB (1 << 0) /* LCD Controller enable */
+#define LCCR0_CMS (1 << 1) /* Color/Monochrome Display Select */
+#define LCCR0_Color (LCCR0_CMS*0) /* Color display */
+#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */
+#define LCCR0_SDS (1 << 2) /* Single/Dual Panel Display Select */
+#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */
+#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */
+
+#define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */
+#define LCCR0_SFM (1 << 4) /* Start of frame mask */
+#define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */
+#define LCCR0_EFM (1 << 6) /* End of Frame mask */
+#define LCCR0_PAS (1 << 7) /* Passive/Active display Select */
+#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */
+#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */
+#define LCCR0_DPD (1 << 9) /* Double Pixel Data (monochrome) */
+#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome display */
+#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome display */
+#define LCCR0_DIS (1 << 10) /* LCD Disable */
+#define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */
+#define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */
+#define LCCR0_PDD_S 12
+#define LCCR0_BM (1 << 20) /* Branch mask */
+#define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */
+#define LCCR0_LCDT (1 << 22) /* LCD panel type */
+#define LCCR0_RDSTM (1 << 23) /* Read status interrupt mask */
+#define LCCR0_CMDIM (1 << 24) /* Command interrupt mask */
+#define LCCR0_OUC (1 << 25) /* Overlay Underlay control bit */
+#define LCCR0_LDDALT (1 << 26) /* LDD alternate mapping control */
+
+#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */
+#define LCCR1_DisWdth(Pixel) (((Pixel) - 1) << FShft (LCCR1_PPL))
+
+#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */
+#define LCCR1_HorSnchWdth(Tpix) (((Tpix) - 1) << FShft (LCCR1_HSW))
+
+#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait - 1 */
+#define LCCR1_EndLnDel(Tpix) (((Tpix) - 1) << FShft (LCCR1_ELW))
+
+#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */
+#define LCCR1_BegLnDel(Tpix) (((Tpix) - 1) << FShft (LCCR1_BLW))
+
+#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */
+#define LCCR2_DisHght(Line) (((Line) - 1) << FShft (LCCR2_LPP))
+
+#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse - 1 */
+#define LCCR2_VrtSnchWdth(Tln) (((Tln) - 1) << FShft (LCCR2_VSW))
+
+#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */
+#define LCCR2_EndFrmDel(Tln) ((Tln) << FShft (LCCR2_EFW))
+
+#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */
+#define LCCR2_BegFrmDel(Tln) ((Tln) << FShft (LCCR2_BFW))
+
+#define LCCR3_API (0xf << 16) /* AC Bias pin trasitions per interrupt */
+#define LCCR3_API_S 16
+#define LCCR3_VSP (1 << 20) /* vertical sync polarity */
+#define LCCR3_HSP (1 << 21) /* horizontal sync polarity */
+#define LCCR3_PCP (1 << 22) /* Pixel Clock Polarity (L_PCLK) */
+#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */
+#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */
+
+#define LCCR3_OEP (1 << 23) /* Output Enable Polarity */
+#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */
+#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */
+
+#define LCCR3_DPC (1 << 27) /* double pixel clock mode */
+#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */
+#define LCCR3_PixClkDiv(Div) (((Div) << FShft (LCCR3_PCD)))
+
+#define LCCR3_ACB Fld (8, 8) /* AC Bias */
+#define LCCR3_Acb(Acb) (((Acb) << FShft (LCCR3_ACB)))
+
+#define LCCR3_HorSnchH (LCCR3_HSP*0) /* HSP Active High */
+#define LCCR3_HorSnchL (LCCR3_HSP*1) /* HSP Active Low */
+
+#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* VSP Active High */
+#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* VSP Active Low */
+
+#define LCCR5_IUM(x) (1 << ((x) + 23)) /* input underrun mask */
+#define LCCR5_BSM(x) (1 << ((x) + 15)) /* branch mask */
+#define LCCR5_EOFM(x) (1 << ((x) + 7)) /* end of frame mask */
+#define LCCR5_SOFM(x) (1 << ((x) + 0)) /* start of frame mask */
+
+#define LCSR_LDD (1 << 0) /* LCD Disable Done */
+#define LCSR_SOF (1 << 1) /* Start of frame */
+#define LCSR_BER (1 << 2) /* Bus error */
+#define LCSR_ABC (1 << 3) /* AC Bias count */
+#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */
+#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */
+#define LCSR_OU (1 << 6) /* output FIFO underrun */
+#define LCSR_QD (1 << 7) /* quick disable */
+#define LCSR_EOF (1 << 8) /* end of frame */
+#define LCSR_BS (1 << 9) /* branch status */
+#define LCSR_SINT (1 << 10) /* subsequent interrupt */
+#define LCSR_RD_ST (1 << 11) /* read status */
+#define LCSR_CMD_INT (1 << 12) /* command interrupt */
+
+#define LCSR1_IU(x) (1 << ((x) + 23)) /* Input FIFO underrun */
+#define LCSR1_BS(x) (1 << ((x) + 15)) /* Branch Status */
+#define LCSR1_EOF(x) (1 << ((x) + 7)) /* End of Frame Status */
+#define LCSR1_SOF(x) (1 << ((x) - 1)) /* Start of Frame Status */
+
+#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */
+
+/* overlay control registers */
+#define OVLxC1_PPL(x) ((((x) - 1) & 0x3ff) << 0) /* Pixels Per Line */
+#define OVLxC1_LPO(x) ((((x) - 1) & 0x3ff) << 10) /* Number of Lines */
+#define OVLxC1_BPP(x) (((x) & 0xf) << 20) /* Bits Per Pixel */
+#define OVLxC1_OEN (1 << 31) /* Enable bit for Overlay */
+#define OVLxC2_XPOS(x) (((x) & 0x3ff) << 0) /* Horizontal Position */
+#define OVLxC2_YPOS(x) (((x) & 0x3ff) << 10) /* Vertical Position */
+#define OVL2C2_PFOR(x) (((x) & 0x7) << 20) /* Pixel Format */
+
+/* smartpanel related */
+#define PRSR_DATA(x) ((x) & 0xff) /* Panel Data */
+#define PRSR_A0 (1 << 8) /* Read Data Source */
+#define PRSR_ST_OK (1 << 9) /* Status OK */
+#define PRSR_CON_NT (1 << 10) /* Continue to Next Command */
+
+#define SMART_CMD_A0 (0x1 << 8)
+#define SMART_CMD_READ_STATUS_REG (0x0 << 9)
+#define SMART_CMD_READ_FRAME_BUFFER ((0x0 << 9) | SMART_CMD_A0)
+#define SMART_CMD_WRITE_COMMAND (0x1 << 9)
+#define SMART_CMD_WRITE_DATA ((0x1 << 9) | SMART_CMD_A0)
+#define SMART_CMD_WRITE_FRAME ((0x2 << 9) | SMART_CMD_A0)
+#define SMART_CMD_WAIT_FOR_VSYNC (0x3 << 9)
+#define SMART_CMD_NOOP (0x4 << 9)
+#define SMART_CMD_INTERRUPT (0x5 << 9)
+
+#define SMART_CMD(x) (SMART_CMD_WRITE_COMMAND | ((x) & 0xff))
+#define SMART_DAT(x) (SMART_CMD_WRITE_DATA | ((x) & 0xff))
+
+/* SMART_DELAY() is introduced for software controlled delay primitive which
+ * can be inserted between command sequences, unused command 0x6 is used here
+ * and delay ranges from 0ms ~ 255ms
+ */
+#define SMART_CMD_DELAY (0x6 << 9)
+#define SMART_DELAY(ms) (SMART_CMD_DELAY | ((ms) & 0xff))
+#endif /* __ASM_ARCH_REGS_LCD_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h
new file mode 100644
index 00000000..a3e5f86e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-ost.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_REGS_OST_H
+#define __ASM_MACH_REGS_OST_H
+
+#include <mach/hardware.h>
+
+/*
+ * OS Timer & Match Registers
+ */
+
+#define OSMR0 __REG(0x40A00000) /* */
+#define OSMR1 __REG(0x40A00004) /* */
+#define OSMR2 __REG(0x40A00008) /* */
+#define OSMR3 __REG(0x40A0000C) /* */
+#define OSMR4 __REG(0x40A00080) /* */
+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
+#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */
+#define OMCR4 __REG(0x40A000C0) /* */
+#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
+#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
+#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
+
+#define OWER_WME (1 << 0) /* Watchdog Match Enable */
+
+#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
+#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
+#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
+
+#endif /* __ASM_MACH_REGS_OST_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-rtc.h b/arch/arm/mach-pxa/include/mach/regs-rtc.h
new file mode 100644
index 00000000..f0e4a589
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-rtc.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR __REG(0x40900000) /* RTC Count Register */
+#define RTAR __REG(0x40900004) /* RTC Alarm Register */
+#define RTSR __REG(0x40900008) /* RTC Status Register */
+#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */
+#define PIAR __REG(0x40900038) /* Periodic Interrupt Alarm Register */
+
+#define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */
+#define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */
+#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
+#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
+#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
+#define RTSR_AL (1 << 0) /* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-u2d.h b/arch/arm/mach-pxa/include/mach/regs-u2d.h
new file mode 100644
index 00000000..c15c0c57
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-u2d.h
@@ -0,0 +1,200 @@
+#ifndef __ASM_ARCH_PXA3xx_U2D_H
+#define __ASM_ARCH_PXA3xx_U2D_H
+
+#include <mach/bitfield.h>
+
+/*
+ * USB2 device controller registers and bits definitions
+ */
+#define U2DCR (0x0000) /* U2D Control Register */
+#define U2DCR_NDC (1 << 31) /* NAK During Config */
+#define U2DCR_HSTC (0x7 << 28) /* High Speed Timeout Calibration */
+#define U2DCR_SPEOREN (1 << 27) /* Short Packet EOR INTR generation Enable */
+#define U2DCR_FSTC (0x7 << 24) /* Full Speed Timeout Calibration */
+#define U2DCR_UCLKOVR (1 << 22) /* UTM Clock Override */
+#define U2DCR_ABP (1 << 21) /* Application Bus Power */
+#define U2DCR_ADD (1 << 20) /* Application Device Disconnect */
+#define U2DCR_CC (1 << 19) /* Configuration Change */
+#define U2DCR_HS (1 << 18) /* High Speed USB Detection */
+#define U2DCR_SMAC (1 << 17) /* Switch Endpoint Memory to Active Configuration */
+#define U2DCR_DWRE (1 << 16) /* Device Remote Wake-up Feature */
+#define U2DCR_ACN (0xf << 12) /* Active U2D Configuration Number */
+#define U2DCR_AIN (0xf << 8) /* Active U2D Interface Number */
+#define U2DCR_AAISN (0xf << 4) /* Active U2D Alternate Interface Setting Number */
+#define U2DCR_EMCE (1 << 3) /* Endpoint Memory Configuration Error */
+#define U2DCR_UDR (1 << 2) /* U2D Resume */
+#define U2DCR_UDA (1 << 1) /* U2D Active */
+#define U2DCR_UDE (1 << 0) /* U2D Enable */
+
+#define U2DICR (0x0004) /* U2D Interrupt Control Register */
+#define U2DISR (0x000C) /* U2D Interrupt Status Register */
+#define U2DINT_CC (1 << 31) /* Interrupt - Configuration Change */
+#define U2DINT_SOF (1 << 30) /* Interrupt - SOF */
+#define U2DINT_USOF (1 << 29) /* Interrupt - micro SOF */
+#define U2DINT_RU (1 << 28) /* Interrupt - Resume */
+#define U2DINT_SU (1 << 27) /* Interrupt - Suspend */
+#define U2DINT_RS (1 << 26) /* Interrupt - Reset */
+#define U2DINT_DPE (1 << 25) /* Interrupt - Data Packet Error */
+#define U2DINT_FIFOERR (0x4) /* Interrupt - endpoint FIFO error */
+#define U2DINT_PACKETCMP (0x2) /* Interrupt - endpoint packet complete */
+#define U2DINT_SPACKETCMP (0x1) /* Interrupt - endpoint short packet complete */
+
+#define U2DFNR (0x0014) /* U2D Frame Number Register */
+
+#define U2DINT(n, intr) (((intr) & 0x07) << (((n) & 0x07) * 3))
+#define U2DICR2 (0x0008) /* U2D Interrupt Control Register 2 */
+#define U2DISR2 (0x0010) /* U2D Interrupt Status Register 2 */
+
+#define U2DOTGCR (0x0020) /* U2D OTG Control Register */
+#define U2DOTGCR_OTGEN (1 << 31) /* On-The-Go Enable */
+#define U2DOTGCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation Protocal Port Support */
+#define U2DOTGCR_AHNP (1 << 29) /* A-device Host Negotiation Protocal Support */
+#define U2DOTGCR_BHNP (1 << 28) /* B-device Host Negotiation Protocal Enable */
+
+#ifdef CONFIG_CPU_PXA930
+#define U2DOTGCR_LPA (1 << 15) /* ULPI low power mode active */
+#define U2DOTGCR_IESI (1 << 13) /* OTG interrupt Enable */
+#define U2DOTGCR_ISSI (1 << 12) /* OTG interrupt status */
+#endif
+
+#define U2DOTGCR_CKAF (1 << 5) /* Carkit Mode Alternate Function Select */
+#define U2DOTGCR_UTMID (1 << 4) /* UTMI Interface Disable */
+#define U2DOTGCR_ULAF (1 << 3) /* ULPI Mode Alternate Function Select */
+#define U2DOTGCR_SMAF (1 << 2) /* Serial Mode Alternate Function Select */
+#define U2DOTGCR_RTSM (1 << 1) /* Return to Synchronous Mode (ULPI Mode) */
+#define U2DOTGCR_ULE (1 << 0) /* ULPI Wrapper Enable */
+
+#define U2DOTGICR (0x0024) /* U2D OTG Interrupt Control Register */
+#define U2DOTGISR (0x0028) /* U2D OTG Interrupt Status Register */
+
+#define U2DOTGINT_SF (1 << 17) /* OTG Set Feature Command Received */
+#define U2DOTGINT_SI (1 << 16) /* OTG Interrupt */
+#define U2DOTGINT_RLS1 (1 << 14) /* RXCMD Linestate[1] Change Interrupt Rise */
+#define U2DOTGINT_RLS0 (1 << 13) /* RXCMD Linestate[0] Change Interrupt Rise */
+#define U2DOTGINT_RID (1 << 12) /* RXCMD OTG ID Change Interrupt Rise */
+#define U2DOTGINT_RSE (1 << 11) /* RXCMD OTG Session End Interrupt Rise */
+#define U2DOTGINT_RSV (1 << 10) /* RXCMD OTG Session Valid Interrupt Rise */
+#define U2DOTGINT_RVV (1 << 9) /* RXCMD OTG Vbus Valid Interrupt Rise */
+#define U2DOTGINT_RCK (1 << 8) /* RXCMD Carkit Interrupt Rise */
+#define U2DOTGINT_FLS1 (1 << 6) /* RXCMD Linestate[1] Change Interrupt Fall */
+#define U2DOTGINT_FLS0 (1 << 5) /* RXCMD Linestate[0] Change Interrupt Fall */
+#define U2DOTGINT_FID (1 << 4) /* RXCMD OTG ID Change Interrupt Fall */
+#define U2DOTGINT_FSE (1 << 3) /* RXCMD OTG Session End Interrupt Fall */
+#define U2DOTGINT_FSV (1 << 2) /* RXCMD OTG Session Valid Interrupt Fall */
+#define U2DOTGINT_FVV (1 << 1) /* RXCMD OTG Vbus Valid Interrupt Fall */
+#define U2DOTGINT_FCK (1 << 0) /* RXCMD Carkit Interrupt Fall */
+
+#define U2DOTGUSR (0x002C) /* U2D OTG ULPI Status Register */
+#define U2DOTGUSR_LPA (1 << 31) /* ULPI Low Power Mode Active */
+#define U2DOTGUSR_S6A (1 << 30) /* ULPI Serial Mode (6-pin) Active */
+#define U2DOTGUSR_S3A (1 << 29) /* ULPI Serial Mode (3-pin) Active */
+#define U2DOTGUSR_CKA (1 << 28) /* ULPI Car Kit Mode Active */
+#define U2DOTGUSR_LS1 (1 << 6) /* RXCMD Linestate 1 Status */
+#define U2DOTGUSR_LS0 (1 << 5) /* RXCMD Linestate 0 Status */
+#define U2DOTGUSR_ID (1 << 4) /* OTG IDGnd Status */
+#define U2DOTGUSR_SE (1 << 3) /* OTG Session End Status */
+#define U2DOTGUSR_SV (1 << 2) /* OTG Session Valid Status */
+#define U2DOTGUSR_VV (1 << 1) /* OTG Vbus Valid Status */
+#define U2DOTGUSR_CK (1 << 0) /* Carkit Interrupt Status */
+
+#define U2DOTGUCR (0x0030) /* U2D OTG ULPI Control Register */
+#define U2DOTGUCR_RUN (1 << 25) /* RUN */
+#define U2DOTGUCR_RNW (1 << 24) /* Read or Write operation */
+#define U2DOTGUCR_ADDR (0x3f << 16) /* Address of the ULPI PHY register */
+#define U2DOTGUCR_WDATA (0xff << 8) /* The data for a WRITE command */
+#define U2DOTGUCR_RDATA (0xff << 0) /* The data for a READ command */
+
+#define U2DP3CR (0x0034) /* U2D Port 3 Control Register */
+#define U2DP3CR_P2SS (0x3 << 8) /* Host Port 2 Serial Mode Select */
+#define U2DP3CR_P3SS (0x7 << 4) /* Host Port 3 Serial Mode Select */
+#define U2DP3CR_VPVMBEN (0x1 << 2) /* Host Port 3 Vp/Vm Block Enable */
+#define U2DP3CR_CFG (0x3 << 0) /* Host Port 3 Configuration */
+
+#define U2DCSR0 (0x0100) /* U2D Control/Status Register - Endpoint 0 */
+#define U2DCSR0_IPA (1 << 8) /* IN Packet Adjusted */
+#define U2DCSR0_SA (1 << 7) /* SETUP Active */
+#define U2DCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */
+#define U2DCSR0_FST (1 << 5) /* Force Stall */
+#define U2DCSR0_SST (1 << 4) /* Send Stall */
+#define U2DCSR0_DME (1 << 3) /* DMA Enable */
+#define U2DCSR0_FTF (1 << 2) /* Flush Transmit FIFO */
+#define U2DCSR0_IPR (1 << 1) /* IN Packet Ready */
+#define U2DCSR0_OPC (1 << 0) /* OUT Packet Complete */
+
+#define U2DCSR(x) (0x0100 + ((x) << 2)) /* U2D Control/Status Register - Endpoint x */
+#define U2DCSR_BF (1 << 10) /* Buffer Full, for OUT eps */
+#define U2DCSR_BE (1 << 10) /* Buffer Empty, for IN eps */
+#define U2DCSR_DPE (1 << 9) /* Data Packet Error, for ISO eps only */
+#define U2DCSR_FEF (1 << 8) /* Flush Endpoint FIFO */
+#define U2DCSR_SP (1 << 7) /* Short Packet Control/Status, for OUT eps only, readonly */
+#define U2DCSR_BNE (1 << 6) /* Buffer Not Empty, for OUT eps */
+#define U2DCSR_BNF (1 << 6) /* Buffer Not Full, for IN eps */
+#define U2DCSR_FST (1 << 5) /* Force STALL, write 1 set */
+#define U2DCSR_SST (1 << 4) /* Sent STALL, write 1 clear */
+#define U2DCSR_DME (1 << 3) /* DMA Enable */
+#define U2DCSR_TRN (1 << 2) /* Tx/Rx NAK, write 1 clear */
+#define U2DCSR_PC (1 << 1) /* Packet Complete, write 1 clear */
+#define U2DCSR_FS (1 << 0) /* FIFO needs Service */
+
+#define U2DBCR0 (0x0200) /* U2D Byte Count Register - Endpoint 0 */
+#define U2DBCR(x) (0x0200 + ((x) << 2)) /* U2D Byte Count Register - Endpoint x */
+
+#define U2DDR0 (0x0300) /* U2D Data Register - Endpoint 0 */
+
+#define U2DEPCR(x) (0x0400 + ((x) << 2)) /* U2D Configuration Register - Endpoint x */
+#define U2DEPCR_EE (1 << 0) /* Endpoint Enable */
+#define U2DEPCR_BS_MASK (0x3FE) /* Buffer Size, BS*8=FIFO size, max 8184B = 8KB */
+
+#define U2DSCA (0x0500) /* U2D Setup Command Address */
+#define U2DSCA_VALUE (0x0120)
+
+#define U2DEN0 (0x0504) /* U2D Endpoint Information Register - Endpoint 0 */
+#define U2DEN(x) (0x0504 + ((x) << 2)) /* U2D Endpoint Information Register - Endpoint x */
+
+/* U2DMA registers */
+#define U2DMACSR0 (0x1000) /* U2DMA Control/Status Register - Channel 0 */
+#define U2DMACSR(x) (0x1000 + ((x) << 2)) /* U2DMA Control/Status Register - Channel x */
+#define U2DMACSR_RUN (1 << 31) /* Run Bit (read / write) */
+#define U2DMACSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
+#define U2DMACSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
+#define U2DMACSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
+#define U2DMACSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
+#define U2DMACSR_RASIRQEN (1 << 23) /* Request After Cnannel Stopped Interrupt Enable */
+#define U2DMACSR_MASKRUN (1 << 22) /* Mask Run */
+#define U2DMACSR_SCEMC (3 << 18) /* System Bus Split Completion Error Message Class */
+#define U2DMACSR_SCEMI (0x1f << 13) /* System Bus Split Completion Error Message Index */
+#define U2DMACSR_BUSERRTYPE (7 << 10) /* PX Bus Error Type */
+#define U2DMACSR_EORINTR (1 << 9) /* End Of Receive */
+#define U2DMACSR_REQPEND (1 << 8) /* Request Pending */
+#define U2DMACSR_RASINTR (1 << 4) /* Request After Channel Stopped (read / write 1 clear) */
+#define U2DMACSR_STOPINTR (1 << 3) /* Stop Interrupt (read only) */
+#define U2DMACSR_ENDINTR (1 << 2) /* End Interrupt (read / write 1 clear) */
+#define U2DMACSR_STARTINTR (1 << 1) /* Start Interrupt (read / write 1 clear) */
+#define U2DMACSR_BUSERRINTR (1 << 0) /* Bus Error Interrupt (read / write 1 clear) */
+
+#define U2DMACR (0x1080) /* U2DMA Control Register */
+#define U2DMAINT (0x10F0) /* U2DMA Interrupt Register */
+
+#define U2DMABR0 (0x1100) /* U2DMA Branch Register - Channel 0 */
+#define U2DMABR(x) (0x1100 + (x) << 2) /* U2DMA Branch Register - Channel x */
+
+#define U2DMADADR0 (0x1200) /* U2DMA Descriptor Address Register - Channel 0 */
+#define U2DMADADR(x) (0x1200 + (x) * 0x10) /* U2DMA Descriptor Address Register - Channel x */
+
+#define U2DMADADR_STOP (1U << 0)
+
+#define U2DMASADR0 (0x1204) /* U2DMA Source Address Register - Channel 0 */
+#define U2DMASADR(x) (0x1204 + (x) * 0x10) /* U2DMA Source Address Register - Channel x */
+#define U2DMATADR0 (0x1208) /* U2DMA Target Address Register - Channel 0 */
+#define U2DMATADR(x) (0x1208 + (x) * 0x10) /* U2DMA Target Address Register - Channel x */
+
+#define U2DMACMDR0 (0x120C) /* U2DMA Command Address Register - Channel 0 */
+#define U2DMACMDR(x) (0x120C + (x) * 0x10) /* U2DMA Command Address Register - Channel x */
+
+#define U2DMACMDR_XFRDIS (1 << 31) /* Transfer Direction */
+#define U2DMACMDR_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
+#define U2DMACMDR_ENDIRQEN (1 << 21) /* End Interrupt Enable */
+#define U2DMACMDR_PACKCOMP (1 << 13) /* Packet Complete */
+#define U2DMACMDR_LEN (0x07ff) /* length mask (max = 2K - 1) */
+
+#endif /* __ASM_ARCH_PXA3xx_U2D_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-uart.h b/arch/arm/mach-pxa/include/mach/regs-uart.h
new file mode 100644
index 00000000..55aeb7fb
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-uart.h
@@ -0,0 +1,143 @@
+#ifndef __ASM_ARCH_REGS_UART_H
+#define __ASM_ARCH_REGS_UART_H
+
+/*
+ * UARTs
+ */
+
+/* Full Function UART (FFUART) */
+#define FFUART FFRBR
+#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */
+#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */
+#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */
+#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */
+#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */
+#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */
+#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */
+#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */
+#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */
+#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */
+#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */
+#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+/* Bluetooth UART (BTUART) */
+#define BTUART BTRBR
+#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */
+#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */
+#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */
+#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */
+#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */
+#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */
+#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */
+#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */
+#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */
+#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */
+#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */
+#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+/* Standard UART (STUART) */
+#define STUART STRBR
+#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */
+#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */
+#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */
+#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */
+#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */
+#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */
+#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */
+#define STLSR __REG(0x40700014) /* Line Status Register (read only) */
+#define STMSR __REG(0x40700018) /* Reserved */
+#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */
+#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */
+#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+/* Hardware UART (HWUART) */
+#define HWUART HWRBR
+#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */
+#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */
+#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */
+#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */
+#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */
+#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */
+#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */
+#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */
+#define HWMSR __REG(0x41600018) /* Modem Status Register (read only) */
+#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */
+#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */
+#define HWFOR __REG(0x41600024) /* Receive FIFO Occupancy Register (read only) */
+#define HWABR __REG(0x41600028) /* Auto-Baud Control Register (read/write) */
+#define HWACR __REG(0x4160002C) /* Auto-Baud Count Register (read only) */
+#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+#define IER_DMAE (1 << 7) /* DMA Requests Enable */
+#define IER_UUE (1 << 6) /* UART Unit Enable */
+#define IER_NRZE (1 << 5) /* NRZ coding Enable */
+#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
+#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
+#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
+#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
+#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
+
+#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
+#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
+#define IIR_TOD (1 << 3) /* Time Out Detected */
+#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
+#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
+#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
+
+#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
+#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
+#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
+#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
+#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
+#define FCR_ITL_1 (0)
+#define FCR_ITL_8 (FCR_ITL1)
+#define FCR_ITL_16 (FCR_ITL2)
+#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1)
+
+#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
+#define LCR_SB (1 << 6) /* Set Break */
+#define LCR_STKYP (1 << 5) /* Sticky Parity */
+#define LCR_EPS (1 << 4) /* Even Parity Select */
+#define LCR_PEN (1 << 3) /* Parity Enable */
+#define LCR_STB (1 << 2) /* Stop Bit */
+#define LCR_WLS1 (1 << 1) /* Word Length Select */
+#define LCR_WLS0 (1 << 0) /* Word Length Select */
+
+#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
+#define LSR_TEMT (1 << 6) /* Transmitter Empty */
+#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
+#define LSR_BI (1 << 4) /* Break Interrupt */
+#define LSR_FE (1 << 3) /* Framing Error */
+#define LSR_PE (1 << 2) /* Parity Error */
+#define LSR_OE (1 << 1) /* Overrun Error */
+#define LSR_DR (1 << 0) /* Data Ready */
+
+#define MCR_LOOP (1 << 4)
+#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
+#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
+#define MCR_RTS (1 << 1) /* Request to Send */
+#define MCR_DTR (1 << 0) /* Data Terminal Ready */
+
+#define MSR_DCD (1 << 7) /* Data Carrier Detect */
+#define MSR_RI (1 << 6) /* Ring Indicator */
+#define MSR_DSR (1 << 5) /* Data Set Ready */
+#define MSR_CTS (1 << 4) /* Clear To Send */
+#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
+#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
+#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
+#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
+
+/*
+ * IrSR (Infrared Selection Register)
+ */
+#define STISR_RXPL (1 << 4) /* Receive Data Polarity */
+#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */
+#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */
+#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */
+#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */
+
+#endif /* __ASM_ARCH_REGS_UART_H */
diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h
new file mode 100644
index 00000000..b6c10556
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/reset.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H
+
+#define RESET_STATUS_HARDWARE (1 << 0) /* Hardware Reset */
+#define RESET_STATUS_WATCHDOG (1 << 1) /* Watchdog Reset */
+#define RESET_STATUS_LOWPOWER (1 << 2) /* Low Power/Sleep Exit */
+#define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */
+#define RESET_STATUS_ALL (0xf)
+
+extern unsigned int reset_status;
+extern void clear_reset_status(unsigned int mask);
+
+/**
+ * init_gpio_reset() - register GPIO as reset generator
+ * @gpio: gpio nr
+ * @output: set gpio as output instead of input during normal work
+ * @level: output level
+ */
+extern int init_gpio_reset(int gpio, int output, int level);
+
+#endif /* __ASM_ARCH_RESET_H */
diff --git a/arch/arm/mach-pxa/include/mach/sharpsl_pm.h b/arch/arm/mach-pxa/include/mach/sharpsl_pm.h
new file mode 100644
index 00000000..905be675
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/sharpsl_pm.h
@@ -0,0 +1,113 @@
+/*
+ * SharpSL Battery/PM Driver
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * This program is free software; you can 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_SHARPSL_PM
+#define _MACH_SHARPSL_PM
+
+struct sharpsl_charger_machinfo {
+ void (*init)(void);
+ void (*exit)(void);
+ int gpio_acin;
+ int gpio_batfull;
+ int batfull_irq;
+ int gpio_batlock;
+ int gpio_fatal;
+ void (*discharge)(int);
+ void (*discharge1)(int);
+ void (*charge)(int);
+ void (*measure_temp)(int);
+ void (*presuspend)(void);
+ void (*postsuspend)(void);
+ void (*earlyresume)(void);
+ unsigned long (*read_devdata)(int);
+#define SHARPSL_BATT_VOLT 1
+#define SHARPSL_BATT_TEMP 2
+#define SHARPSL_ACIN_VOLT 3
+#define SHARPSL_STATUS_ACIN 4
+#define SHARPSL_STATUS_LOCK 5
+#define SHARPSL_STATUS_CHRGFULL 6
+#define SHARPSL_STATUS_FATAL 7
+ unsigned long (*charger_wakeup)(void);
+ int (*should_wakeup)(unsigned int resume_on_alarm);
+ void (*backlight_limit)(int);
+ int (*backlight_get_status) (void);
+ int charge_on_volt;
+ int charge_on_temp;
+ int charge_acin_high;
+ int charge_acin_low;
+ int fatal_acin_volt;
+ int fatal_noacin_volt;
+ int bat_levels;
+ struct battery_thresh *bat_levels_noac;
+ struct battery_thresh *bat_levels_acin;
+ struct battery_thresh *bat_levels_noac_bl;
+ struct battery_thresh *bat_levels_acin_bl;
+ int status_high_acin;
+ int status_low_acin;
+ int status_high_noac;
+ int status_low_noac;
+};
+
+struct battery_thresh {
+ int voltage;
+ int percentage;
+};
+
+struct battery_stat {
+ int ac_status; /* APM AC Present/Not Present */
+ int mainbat_status; /* APM Main Battery Status */
+ int mainbat_percent; /* Main Battery Percentage Charge */
+ int mainbat_voltage; /* Main Battery Voltage */
+};
+
+struct sharpsl_pm_status {
+ struct device *dev;
+ struct timer_list ac_timer;
+ struct timer_list chrg_full_timer;
+
+ int charge_mode;
+#define CHRG_ERROR (-1)
+#define CHRG_OFF (0)
+#define CHRG_ON (1)
+#define CHRG_DONE (2)
+
+ unsigned int flags;
+#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */
+#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */
+#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */
+#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */
+#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */
+
+ int full_count;
+ unsigned long charge_start_time;
+ struct sharpsl_charger_machinfo *machinfo;
+ struct battery_stat battstat;
+};
+
+extern struct sharpsl_pm_status sharpsl_pm;
+
+extern struct battery_thresh sharpsl_battery_levels_acin[];
+extern struct battery_thresh sharpsl_battery_levels_noac[];
+
+#define SHARPSL_LED_ERROR 2
+#define SHARPSL_LED_ON 1
+#define SHARPSL_LED_OFF 0
+
+void sharpsl_battery_kick(void);
+void sharpsl_pm_led(int val);
+
+/* MAX1111 Channel Definitions */
+#define MAX1111_BATT_VOLT 4u
+#define MAX1111_BATT_TEMP 2u
+#define MAX1111_ACIN_VOLT 6u
+int sharpsl_pm_pxa_read_max1111(int channel);
+
+void corgi_lcd_limit_intensity(int limit);
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/smemc.h b/arch/arm/mach-pxa/include/mach/smemc.h
new file mode 100644
index 00000000..654adc90
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/smemc.h
@@ -0,0 +1,74 @@
+/*
+ * Static memory controller register definitions for PXA CPUs
+ *
+ * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.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 __SMEMC_REGS_H
+#define __SMEMC_REGS_H
+
+#define PXA2XX_SMEMC_BASE 0x48000000
+#define PXA3XX_SMEMC_BASE 0x4a000000
+#define SMEMC_VIRT 0xf6000000
+
+#define MDCNFG (SMEMC_VIRT + 0x00) /* SDRAM Configuration Register 0 */
+#define MDREFR (SMEMC_VIRT + 0x04) /* SDRAM Refresh Control Register */
+#define MSC0 (SMEMC_VIRT + 0x08) /* Static Memory Control Register 0 */
+#define MSC1 (SMEMC_VIRT + 0x0C) /* Static Memory Control Register 1 */
+#define MSC2 (SMEMC_VIRT + 0x10) /* Static Memory Control Register 2 */
+#define MECR (SMEMC_VIRT + 0x14) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
+#define SXLCR (SMEMC_VIRT + 0x18) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
+#define SXCNFG (SMEMC_VIRT + 0x1C) /* Synchronous Static Memory Control Register */
+#define SXMRS (SMEMC_VIRT + 0x24) /* MRS value to be written to Synchronous Flash or SMROM */
+#define MCMEM0 (SMEMC_VIRT + 0x28) /* Card interface Common Memory Space Socket 0 Timing */
+#define MCMEM1 (SMEMC_VIRT + 0x2C) /* Card interface Common Memory Space Socket 1 Timing */
+#define MCATT0 (SMEMC_VIRT + 0x30) /* Card interface Attribute Space Socket 0 Timing Configuration */
+#define MCATT1 (SMEMC_VIRT + 0x34) /* Card interface Attribute Space Socket 1 Timing Configuration */
+#define MCIO0 (SMEMC_VIRT + 0x38) /* Card interface I/O Space Socket 0 Timing Configuration */
+#define MCIO1 (SMEMC_VIRT + 0x3C) /* Card interface I/O Space Socket 1 Timing Configuration */
+#define MDMRS (SMEMC_VIRT + 0x40) /* MRS value to be written to SDRAM */
+#define BOOT_DEF (SMEMC_VIRT + 0x44) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+#define MEMCLKCFG (SMEMC_VIRT + 0x68) /* Clock Configuration */
+#define CSADRCFG0 (SMEMC_VIRT + 0x80) /* Address Configuration Register for CS0 */
+#define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */
+#define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */
+#define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */
+
+/*
+ * More handy macros for PCMCIA
+ *
+ * Arg is socket number
+ */
+#define MCMEM(s) (SMEMC_VIRT + 0x28 + ((s)<<2)) /* Card interface Common Memory Space Socket s Timing */
+#define MCATT(s) (SMEMC_VIRT + 0x30 + ((s)<<2)) /* Card interface Attribute Space Socket s Timing Configuration */
+#define MCIO(s) (SMEMC_VIRT + 0x38 + ((s)<<2)) /* Card interface I/O Space Socket s Timing Configuration */
+
+/* MECR register defines */
+#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
+#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
+
+#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
+#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
+#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
+#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */
+
+#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
+#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
+#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
+#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
+#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
+#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
+#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
+#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
+#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
+#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
+#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
+#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
+#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
+#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/spitz.h b/arch/arm/mach-pxa/include/mach/spitz.h
new file mode 100644
index 00000000..685749a5
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/spitz.h
@@ -0,0 +1,189 @@
+/*
+ * Hardware specific definitions for SL-Cx000 series of PDAs
+ *
+ * Copyright (c) 2005 Alexander Wykes
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can 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_SPITZ_H
+#define __ASM_ARCH_SPITZ_H 1
+#endif
+
+#include <linux/fb.h>
+#include <linux/gpio.h>
+
+/* Spitz/Akita GPIOs */
+
+#define SPITZ_GPIO_KEY_INT (0) /* Key Interrupt */
+#define SPITZ_GPIO_RESET (1)
+#define SPITZ_GPIO_nSD_DETECT (9)
+#define SPITZ_GPIO_TP_INT (11) /* Touch Panel interrupt */
+#define SPITZ_GPIO_AK_INT (13) /* Remote Control */
+#define SPITZ_GPIO_ADS7846_CS (14)
+#define SPITZ_GPIO_SYNC (16)
+#define SPITZ_GPIO_MAX1111_CS (20)
+#define SPITZ_GPIO_FATAL_BAT (21)
+#define SPITZ_GPIO_HSYNC (22)
+#define SPITZ_GPIO_nSD_CLK (32)
+#define SPITZ_GPIO_USB_DEVICE (35)
+#define SPITZ_GPIO_USB_HOST (37)
+#define SPITZ_GPIO_USB_CONNECT (41)
+#define SPITZ_GPIO_LCDCON_CS (53)
+#define SPITZ_GPIO_nPCE (54)
+#define SPITZ_GPIO_nSD_WP (81)
+#define SPITZ_GPIO_ON_RESET (89)
+#define SPITZ_GPIO_BAT_COVER (90)
+#define SPITZ_GPIO_CF_CD (94)
+#define SPITZ_GPIO_ON_KEY (95)
+#define SPITZ_GPIO_SWA (97)
+#define SPITZ_GPIO_SWB (96)
+#define SPITZ_GPIO_CHRG_FULL (101)
+#define SPITZ_GPIO_CO (101)
+#define SPITZ_GPIO_CF_IRQ (105)
+#define SPITZ_GPIO_AC_IN (115)
+#define SPITZ_GPIO_HP_IN (116)
+
+/* Spitz Only GPIOs */
+
+#define SPITZ_GPIO_CF2_IRQ (106) /* CF slot1 Ready */
+#define SPITZ_GPIO_CF2_CD (93)
+
+
+/* Spitz/Akita Keyboard Definitions */
+
+#define SPITZ_KEY_STROBE_NUM (11)
+#define SPITZ_KEY_SENSE_NUM (7)
+#define SPITZ_GPIO_G0_STROBE_BIT 0x0f800000
+#define SPITZ_GPIO_G1_STROBE_BIT 0x00100000
+#define SPITZ_GPIO_G2_STROBE_BIT 0x01000000
+#define SPITZ_GPIO_G3_STROBE_BIT 0x00041880
+#define SPITZ_GPIO_G0_SENSE_BIT 0x00021000
+#define SPITZ_GPIO_G1_SENSE_BIT 0x000000d4
+#define SPITZ_GPIO_G2_SENSE_BIT 0x08000000
+#define SPITZ_GPIO_G3_SENSE_BIT 0x00000000
+
+#define SPITZ_GPIO_KEY_STROBE0 88
+#define SPITZ_GPIO_KEY_STROBE1 23
+#define SPITZ_GPIO_KEY_STROBE2 24
+#define SPITZ_GPIO_KEY_STROBE3 25
+#define SPITZ_GPIO_KEY_STROBE4 26
+#define SPITZ_GPIO_KEY_STROBE5 27
+#define SPITZ_GPIO_KEY_STROBE6 52
+#define SPITZ_GPIO_KEY_STROBE7 103
+#define SPITZ_GPIO_KEY_STROBE8 107
+#define SPITZ_GPIO_KEY_STROBE9 108
+#define SPITZ_GPIO_KEY_STROBE10 114
+
+#define SPITZ_GPIO_KEY_SENSE0 12
+#define SPITZ_GPIO_KEY_SENSE1 17
+#define SPITZ_GPIO_KEY_SENSE2 91
+#define SPITZ_GPIO_KEY_SENSE3 34
+#define SPITZ_GPIO_KEY_SENSE4 36
+#define SPITZ_GPIO_KEY_SENSE5 38
+#define SPITZ_GPIO_KEY_SENSE6 39
+
+
+/* Spitz Scoop Device (No. 1) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP_LED_GREEN SCOOP_GPCR_PA11 /* Keep */
+#define SPITZ_SCP_JK_B SCOOP_GPCR_PA12 /* Keep */
+#define SPITZ_SCP_CHRG_ON SCOOP_GPCR_PA13 /* Keep */
+#define SPITZ_SCP_MUTE_L SCOOP_GPCR_PA14 /* Low */
+#define SPITZ_SCP_MUTE_R SCOOP_GPCR_PA15 /* Low */
+#define SPITZ_SCP_CF_POWER SCOOP_GPCR_PA16 /* Keep */
+#define SPITZ_SCP_LED_ORANGE SCOOP_GPCR_PA17 /* Keep */
+#define SPITZ_SCP_JK_A SCOOP_GPCR_PA18 /* Low */
+#define SPITZ_SCP_ADC_TEMP_ON SCOOP_GPCR_PA19 /* Low */
+
+#define SPITZ_SCP_IO_DIR (SPITZ_SCP_JK_B | SPITZ_SCP_CHRG_ON | \
+ SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | \
+ SPITZ_SCP_CF_POWER | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_IO_OUT (SPITZ_SCP_CHRG_ON | SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R)
+#define SPITZ_SCP_SUS_CLR (SPITZ_SCP_MUTE_L | SPITZ_SCP_MUTE_R | SPITZ_SCP_JK_A | SPITZ_SCP_ADC_TEMP_ON)
+#define SPITZ_SCP_SUS_SET 0
+
+#define SPITZ_SCP_GPIO_BASE (NR_BUILTIN_GPIO)
+#define SPITZ_GPIO_LED_GREEN (SPITZ_SCP_GPIO_BASE + 0)
+#define SPITZ_GPIO_JK_B (SPITZ_SCP_GPIO_BASE + 1)
+#define SPITZ_GPIO_CHRG_ON (SPITZ_SCP_GPIO_BASE + 2)
+#define SPITZ_GPIO_MUTE_L (SPITZ_SCP_GPIO_BASE + 3)
+#define SPITZ_GPIO_MUTE_R (SPITZ_SCP_GPIO_BASE + 4)
+#define SPITZ_GPIO_CF_POWER (SPITZ_SCP_GPIO_BASE + 5)
+#define SPITZ_GPIO_LED_ORANGE (SPITZ_SCP_GPIO_BASE + 6)
+#define SPITZ_GPIO_JK_A (SPITZ_SCP_GPIO_BASE + 7)
+#define SPITZ_GPIO_ADC_TEMP_ON (SPITZ_SCP_GPIO_BASE + 8)
+
+/* Spitz Scoop Device (No. 2) GPIOs */
+/* Suspend States in comments */
+#define SPITZ_SCP2_IR_ON SCOOP_GPCR_PA11 /* High */
+#define SPITZ_SCP2_AKIN_PULLUP SCOOP_GPCR_PA12 /* Keep */
+#define SPITZ_SCP2_RESERVED_1 SCOOP_GPCR_PA13 /* High */
+#define SPITZ_SCP2_RESERVED_2 SCOOP_GPCR_PA14 /* Low */
+#define SPITZ_SCP2_RESERVED_3 SCOOP_GPCR_PA15 /* Low */
+#define SPITZ_SCP2_RESERVED_4 SCOOP_GPCR_PA16 /* Low */
+#define SPITZ_SCP2_BACKLIGHT_CONT SCOOP_GPCR_PA17 /* Low */
+#define SPITZ_SCP2_BACKLIGHT_ON SCOOP_GPCR_PA18 /* Low */
+#define SPITZ_SCP2_MIC_BIAS SCOOP_GPCR_PA19 /* Low */
+
+#define SPITZ_SCP2_IO_DIR (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1 | \
+ SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+
+#define SPITZ_SCP2_IO_OUT (SPITZ_SCP2_AKIN_PULLUP | SPITZ_SCP2_RESERVED_1)
+#define SPITZ_SCP2_SUS_CLR (SPITZ_SCP2_RESERVED_2 | SPITZ_SCP2_RESERVED_3 | SPITZ_SCP2_RESERVED_4 | \
+ SPITZ_SCP2_BACKLIGHT_CONT | SPITZ_SCP2_BACKLIGHT_ON | SPITZ_SCP2_MIC_BIAS)
+#define SPITZ_SCP2_SUS_SET (SPITZ_SCP2_IR_ON | SPITZ_SCP2_RESERVED_1)
+
+#define SPITZ_SCP2_GPIO_BASE (NR_BUILTIN_GPIO + 12)
+#define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0)
+#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1)
+#define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2)
+#define SPITZ_GPIO_RESERVED_2 (SPITZ_SCP2_GPIO_BASE + 3)
+#define SPITZ_GPIO_RESERVED_3 (SPITZ_SCP2_GPIO_BASE + 4)
+#define SPITZ_GPIO_RESERVED_4 (SPITZ_SCP2_GPIO_BASE + 5)
+#define SPITZ_GPIO_BACKLIGHT_CONT (SPITZ_SCP2_GPIO_BASE + 6)
+#define SPITZ_GPIO_BACKLIGHT_ON (SPITZ_SCP2_GPIO_BASE + 7)
+#define SPITZ_GPIO_MIC_BIAS (SPITZ_SCP2_GPIO_BASE + 8)
+
+/* Akita IO Expander GPIOs */
+#define AKITA_IOEXP_GPIO_BASE (NR_BUILTIN_GPIO + 12)
+#define AKITA_GPIO_RESERVED_0 (AKITA_IOEXP_GPIO_BASE + 0)
+#define AKITA_GPIO_RESERVED_1 (AKITA_IOEXP_GPIO_BASE + 1)
+#define AKITA_GPIO_MIC_BIAS (AKITA_IOEXP_GPIO_BASE + 2)
+#define AKITA_GPIO_BACKLIGHT_ON (AKITA_IOEXP_GPIO_BASE + 3)
+#define AKITA_GPIO_BACKLIGHT_CONT (AKITA_IOEXP_GPIO_BASE + 4)
+#define AKITA_GPIO_AKIN_PULLUP (AKITA_IOEXP_GPIO_BASE + 5)
+#define AKITA_GPIO_IR_ON (AKITA_IOEXP_GPIO_BASE + 6)
+#define AKITA_GPIO_RESERVED_7 (AKITA_IOEXP_GPIO_BASE + 7)
+
+/* Spitz IRQ Definitions */
+
+#define SPITZ_IRQ_GPIO_KEY_INT IRQ_GPIO(SPITZ_GPIO_KEY_INT)
+#define SPITZ_IRQ_GPIO_AC_IN IRQ_GPIO(SPITZ_GPIO_AC_IN)
+#define SPITZ_IRQ_GPIO_AK_INT IRQ_GPIO(SPITZ_GPIO_AK_INT)
+#define SPITZ_IRQ_GPIO_HP_IN IRQ_GPIO(SPITZ_GPIO_HP_IN)
+#define SPITZ_IRQ_GPIO_TP_INT IRQ_GPIO(SPITZ_GPIO_TP_INT)
+#define SPITZ_IRQ_GPIO_SYNC IRQ_GPIO(SPITZ_GPIO_SYNC)
+#define SPITZ_IRQ_GPIO_ON_KEY IRQ_GPIO(SPITZ_GPIO_ON_KEY)
+#define SPITZ_IRQ_GPIO_SWA IRQ_GPIO(SPITZ_GPIO_SWA)
+#define SPITZ_IRQ_GPIO_SWB IRQ_GPIO(SPITZ_GPIO_SWB)
+#define SPITZ_IRQ_GPIO_BAT_COVER IRQ_GPIO(SPITZ_GPIO_BAT_COVER)
+#define SPITZ_IRQ_GPIO_FATAL_BAT IRQ_GPIO(SPITZ_GPIO_FATAL_BAT)
+#define SPITZ_IRQ_GPIO_CO IRQ_GPIO(SPITZ_GPIO_CO)
+#define SPITZ_IRQ_GPIO_CF_IRQ IRQ_GPIO(SPITZ_GPIO_CF_IRQ)
+#define SPITZ_IRQ_GPIO_CF_CD IRQ_GPIO(SPITZ_GPIO_CF_CD)
+#define SPITZ_IRQ_GPIO_CF2_IRQ IRQ_GPIO(SPITZ_GPIO_CF2_IRQ)
+#define SPITZ_IRQ_GPIO_nSD_INT IRQ_GPIO(SPITZ_GPIO_nSD_INT)
+#define SPITZ_IRQ_GPIO_nSD_DETECT IRQ_GPIO(SPITZ_GPIO_nSD_DETECT)
+
+/*
+ * Shared data structures
+ */
+extern struct platform_device spitzssp_device;
+extern struct sharpsl_charger_machinfo spitz_pm_machinfo;
diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h
new file mode 100644
index 00000000..d1fce8b6
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/system.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-pxa/include/mach/system.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <asm/proc-fns.h>
+#include "hardware.h"
+#include "pxa2xx-regs.h"
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+
+void arch_reset(char mode, const char *cmd);
diff --git a/arch/arm/mach-pxa/include/mach/timex.h b/arch/arm/mach-pxa/include/mach/timex.h
new file mode 100644
index 00000000..af6760a5
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/timex.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-pxa/include/mach/timex.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Various drivers are still using the constant of CLOCK_TICK_RATE, for
+ * those drivers to at least work, the definition is provided here.
+ *
+ * NOTE: this is no longer accurate when multiple processors and boards
+ * are selected, newer drivers should not depend on this any more. Use
+ * either the clocksource/clockevent or get this at run-time by calling
+ * get_clock_tick_rate() (as defined in generic.c).
+ */
+
+#if defined(CONFIG_PXA25x)
+/* PXA250/210 timer base */
+#define CLOCK_TICK_RATE 3686400
+#elif defined(CONFIG_PXA27x)
+/* PXA27x timer base */
+#ifdef CONFIG_MACH_MAINSTONE
+#define CLOCK_TICK_RATE 3249600
+#else
+#define CLOCK_TICK_RATE 3250000
+#endif
+#else
+#define CLOCK_TICK_RATE 3250000
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
new file mode 100644
index 00000000..1272c4b5
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -0,0 +1,200 @@
+/*
+ * Hardware specific definitions for Sharp SL-C6000x series of PDAs
+ *
+ * Copyright (c) 2005 Dirk Opfer
+ *
+ * Based on Sharp's 2.4 kernel patches
+ *
+ * This program is free software; you can 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_TOSA_H_
+#define _ASM_ARCH_TOSA_H_ 1
+
+/* TOSA Chip selects */
+#define TOSA_LCDC_PHYS PXA_CS4_PHYS
+/* Internel Scoop */
+#define TOSA_CF_PHYS (PXA_CS2_PHYS + 0x00800000)
+/* Jacket Scoop */
+#define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+
+#define TOSA_NR_IRQS (IRQ_BOARD_START + TC6393XB_NR_IRQS)
+/*
+ * SCOOP2 internal GPIOs
+ */
+#define TOSA_SCOOP_GPIO_BASE NR_BUILTIN_GPIO
+#define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
+#define TOSA_GPIO_TC6393XB_REST_IN (TOSA_SCOOP_GPIO_BASE + 1)
+#define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2)
+#define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3)
+#define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4)
+#define TOSA_SCOOP_AUD_PWR_ON SCOOP_GPCR_PA16
+#define TOSA_GPIO_BT_RESET (TOSA_SCOOP_GPIO_BASE + 6)
+#define TOSA_GPIO_BT_PWR_EN (TOSA_SCOOP_GPIO_BASE + 7)
+#define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19
+
+/* GPIO Direction 1 : output mode / 0:input mode */
+#define TOSA_SCOOP_IO_DIR (TOSA_SCOOP_PXA_VCORE1 | \
+ TOSA_SCOOP_AUD_PWR_ON)
+
+/*
+ * SCOOP2 jacket GPIOs
+ */
+#define TOSA_SCOOP_JC_GPIO_BASE (NR_BUILTIN_GPIO + 12)
+#define TOSA_GPIO_BT_LED (TOSA_SCOOP_JC_GPIO_BASE + 0)
+#define TOSA_GPIO_NOTE_LED (TOSA_SCOOP_JC_GPIO_BASE + 1)
+#define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2)
+#define TOSA_GPIO_USB_PULLUP (TOSA_SCOOP_JC_GPIO_BASE + 3)
+#define TOSA_GPIO_TC6393XB_SUSPEND (TOSA_SCOOP_JC_GPIO_BASE + 4)
+#define TOSA_GPIO_TC6393XB_L3V_ON (TOSA_SCOOP_JC_GPIO_BASE + 5)
+#define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17
+#define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7)
+#define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19
+
+/* GPIO Direction 1 : output mode / 0:input mode */
+#define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)
+
+/*
+ * TC6393XB GPIOs
+ */
+#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12)
+
+#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0)
+#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1)
+#define TOSA_GPIO_BL_C20MA (TOSA_TC6393XB_GPIO_BASE + 3)
+#define TOSA_GPIO_CARD_VCC_ON (TOSA_TC6393XB_GPIO_BASE + 4)
+#define TOSA_GPIO_CHARGE_OFF (TOSA_TC6393XB_GPIO_BASE + 6)
+#define TOSA_GPIO_CHARGE_OFF_JC (TOSA_TC6393XB_GPIO_BASE + 7)
+#define TOSA_GPIO_BAT0_V_ON (TOSA_TC6393XB_GPIO_BASE + 9)
+#define TOSA_GPIO_BAT1_V_ON (TOSA_TC6393XB_GPIO_BASE + 10)
+#define TOSA_GPIO_BU_CHRG_ON (TOSA_TC6393XB_GPIO_BASE + 11)
+#define TOSA_GPIO_BAT_SW_ON (TOSA_TC6393XB_GPIO_BASE + 12)
+#define TOSA_GPIO_BAT0_TH_ON (TOSA_TC6393XB_GPIO_BASE + 14)
+#define TOSA_GPIO_BAT1_TH_ON (TOSA_TC6393XB_GPIO_BASE + 15)
+
+/*
+ * Timing Generator
+ */
+#define TG_PNLCTL 0x00
+#define TG_TPOSCTL 0x01
+#define TG_DUTYCTL 0x02
+#define TG_GPOSR 0x03
+#define TG_GPODR1 0x04
+#define TG_GPODR2 0x05
+#define TG_PINICTL 0x06
+#define TG_HPOSCTL 0x07
+
+/*
+ * PXA GPIOs
+ */
+#define TOSA_GPIO_POWERON (0)
+#define TOSA_GPIO_RESET (1)
+#define TOSA_GPIO_AC_IN (2)
+#define TOSA_GPIO_RECORD_BTN (3)
+#define TOSA_GPIO_SYNC (4) /* Cradle SYNC Button */
+#define TOSA_GPIO_USB_IN (5)
+#define TOSA_GPIO_JACKET_DETECT (7)
+#define TOSA_GPIO_nSD_DETECT (9)
+#define TOSA_GPIO_nSD_INT (10)
+#define TOSA_GPIO_TC6393XB_CLK (11)
+#define TOSA_GPIO_BAT1_CRG (12)
+#define TOSA_GPIO_CF_CD (13)
+#define TOSA_GPIO_BAT0_CRG (14)
+#define TOSA_GPIO_TC6393XB_INT (15)
+#define TOSA_GPIO_BAT0_LOW (17)
+#define TOSA_GPIO_TC6393XB_RDY (18)
+#define TOSA_GPIO_ON_RESET (19)
+#define TOSA_GPIO_EAR_IN (20)
+#define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
+#define TOSA_GPIO_ON_KEY (22)
+#define TOSA_GPIO_VGA_LINE (27)
+#define TOSA_GPIO_TP_INT (32) /* Touch Panel pen down interrupt */
+#define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
+#define TOSA_GPIO_BAT_LOCKED (38) /* Battery locked */
+#define TOSA_GPIO_IRDA_TX (47)
+#define TOSA_GPIO_TG_SPI_SCLK (81)
+#define TOSA_GPIO_TG_SPI_CS (82)
+#define TOSA_GPIO_TG_SPI_MOSI (83)
+#define TOSA_GPIO_BAT1_LOW (84)
+
+#define TOSA_GPIO_HP_IN GPIO_EAR_IN
+
+#define TOSA_GPIO_MAIN_BAT_LOW GPIO_BAT0_LOW
+
+#define TOSA_KEY_STROBE_NUM (11)
+#define TOSA_KEY_SENSE_NUM (7)
+
+#define TOSA_GPIO_HIGH_STROBE_BIT (0xfc000000)
+#define TOSA_GPIO_LOW_STROBE_BIT (0x0000001f)
+#define TOSA_GPIO_ALL_SENSE_BIT (0x00000fe0)
+#define TOSA_GPIO_ALL_SENSE_RSHIFT (5)
+#define TOSA_GPIO_STROBE_BIT(a) GPIO_bit(58+(a))
+#define TOSA_GPIO_SENSE_BIT(a) GPIO_bit(69+(a))
+#define TOSA_GAFR_HIGH_STROBE_BIT (0xfff00000)
+#define TOSA_GAFR_LOW_STROBE_BIT (0x000003ff)
+#define TOSA_GAFR_ALL_SENSE_BIT (0x00fffc00)
+#define TOSA_GPIO_KEY_SENSE(a) (69+(a))
+#define TOSA_GPIO_KEY_STROBE(a) (58+(a))
+
+/*
+ * Interrupts
+ */
+#define TOSA_IRQ_GPIO_WAKEUP IRQ_GPIO(TOSA_GPIO_WAKEUP)
+#define TOSA_IRQ_GPIO_AC_IN IRQ_GPIO(TOSA_GPIO_AC_IN)
+#define TOSA_IRQ_GPIO_RECORD_BTN IRQ_GPIO(TOSA_GPIO_RECORD_BTN)
+#define TOSA_IRQ_GPIO_SYNC IRQ_GPIO(TOSA_GPIO_SYNC)
+#define TOSA_IRQ_GPIO_USB_IN IRQ_GPIO(TOSA_GPIO_USB_IN)
+#define TOSA_IRQ_GPIO_JACKET_DETECT IRQ_GPIO(TOSA_GPIO_JACKET_DETECT)
+#define TOSA_IRQ_GPIO_nSD_INT IRQ_GPIO(TOSA_GPIO_nSD_INT)
+#define TOSA_IRQ_GPIO_nSD_DETECT IRQ_GPIO(TOSA_GPIO_nSD_DETECT)
+#define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
+#define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD)
+#define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
+#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT)
+#define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
+#define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN)
+#define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
+#define TOSA_IRQ_GPIO_ON_KEY IRQ_GPIO(TOSA_GPIO_ON_KEY)
+#define TOSA_IRQ_GPIO_VGA_LINE IRQ_GPIO(TOSA_GPIO_VGA_LINE)
+#define TOSA_IRQ_GPIO_TP_INT IRQ_GPIO(TOSA_GPIO_TP_INT)
+#define TOSA_IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(TOSA_GPIO_JC_CF_IRQ)
+#define TOSA_IRQ_GPIO_BAT_LOCKED IRQ_GPIO(TOSA_GPIO_BAT_LOCKED)
+#define TOSA_IRQ_GPIO_BAT1_LOW IRQ_GPIO(TOSA_GPIO_BAT1_LOW)
+#define TOSA_IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a))
+
+#define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW)
+
+#define TOSA_KEY_SYNC KEY_102ND /* ??? */
+
+#ifndef CONFIG_TOSA_USE_EXT_KEYCODES
+#define TOSA_KEY_RECORD KEY_YEN
+#define TOSA_KEY_ADDRESSBOOK KEY_KATAKANA
+#define TOSA_KEY_CANCEL KEY_ESC
+#define TOSA_KEY_CENTER KEY_HIRAGANA
+#define TOSA_KEY_OK KEY_HENKAN
+#define TOSA_KEY_CALENDAR KEY_KATAKANAHIRAGANA
+#define TOSA_KEY_HOMEPAGE KEY_HANGEUL
+#define TOSA_KEY_LIGHT KEY_MUHENKAN
+#define TOSA_KEY_MENU KEY_HANJA
+#define TOSA_KEY_FN KEY_RIGHTALT
+#define TOSA_KEY_MAIL KEY_ZENKAKUHANKAKU
+#else
+#define TOSA_KEY_RECORD KEY_RECORD
+#define TOSA_KEY_ADDRESSBOOK KEY_ADDRESSBOOK
+#define TOSA_KEY_CANCEL KEY_CANCEL
+#define TOSA_KEY_CENTER KEY_SELECT /* ??? */
+#define TOSA_KEY_OK KEY_OK
+#define TOSA_KEY_CALENDAR KEY_CALENDAR
+#define TOSA_KEY_HOMEPAGE KEY_HOMEPAGE
+#define TOSA_KEY_LIGHT KEY_KBDILLUMTOGGLE
+#define TOSA_KEY_MENU KEY_MENU
+#define TOSA_KEY_FN KEY_FN
+#define TOSA_KEY_MAIL KEY_MAIL
+#endif
+
+struct spi_device;
+extern int tosa_bl_enable(struct spi_device *spi, int enable);
+
+#endif /* _ASM_ARCH_TOSA_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/tosa_bt.h b/arch/arm/mach-pxa/include/mach/tosa_bt.h
new file mode 100644
index 00000000..efc3c3d3
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/tosa_bt.h
@@ -0,0 +1,22 @@
+/*
+ * Tosa bluetooth built-in chip control.
+ *
+ * Later it may be shared with some other platforms.
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can 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 TOSA_BT_H
+#define TOSA_BT_H
+
+struct tosa_bt_data {
+ int gpio_pwr;
+ int gpio_reset;
+};
+
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/trizeps4.h b/arch/arm/mach-pxa/include/mach/trizeps4.h
new file mode 100644
index 00000000..903e1a2e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/trizeps4.h
@@ -0,0 +1,162 @@
+/************************************************************************
+ * Include file for TRIZEPS4 SoM and ConXS eval-board
+ * Copyright (c) Jürgen Schindele
+ * 2006
+ ************************************************************************/
+
+/*
+ * Includes/Defines
+ */
+#ifndef _TRIPEPS4_H_
+#define _TRIPEPS4_H_
+
+/* physical memory regions */
+#define TRIZEPS4_FLASH_PHYS (PXA_CS0_PHYS) /* Flash region */
+#define TRIZEPS4_DISK_PHYS (PXA_CS1_PHYS) /* Disk On Chip region */
+#define TRIZEPS4_ETH_PHYS (PXA_CS2_PHYS) /* Ethernet DM9000 region */
+#define TRIZEPS4_PIC_PHYS (PXA_CS3_PHYS) /* Logic chip on ConXS-Board */
+#define TRIZEPS4_SDRAM_BASE 0xa0000000 /* SDRAM region */
+
+ /* Logic on ConXS-board CSFR register*/
+#define TRIZEPS4_CFSR_PHYS (PXA_CS3_PHYS)
+ /* Logic on ConXS-board BOCR register*/
+#define TRIZEPS4_BOCR_PHYS (PXA_CS3_PHYS+0x02000000)
+ /* Logic on ConXS-board IRCR register*/
+#define TRIZEPS4_IRCR_PHYS (PXA_CS3_PHYS+0x02400000)
+ /* Logic on ConXS-board UPSR register*/
+#define TRIZEPS4_UPSR_PHYS (PXA_CS3_PHYS+0x02800000)
+ /* Logic on ConXS-board DICR register*/
+#define TRIZEPS4_DICR_PHYS (PXA_CS3_PHYS+0x03800000)
+
+/* virtual memory regions */
+#define TRIZEPS4_DISK_VIRT 0xF0000000 /* Disk On Chip region */
+
+#define TRIZEPS4_PIC_VIRT 0xF0100000 /* not used */
+#define TRIZEPS4_CFSR_VIRT 0xF0100000
+#define TRIZEPS4_BOCR_VIRT 0xF0200000
+#define TRIZEPS4_DICR_VIRT 0xF0300000
+#define TRIZEPS4_IRCR_VIRT 0xF0400000
+#define TRIZEPS4_UPSR_VIRT 0xF0500000
+
+/* size of flash */
+#define TRIZEPS4_FLASH_SIZE 0x02000000 /* Flash size 32 MB */
+
+/* Ethernet Controller Davicom DM9000 */
+#define GPIO_DM9000 101
+#define TRIZEPS4_ETH_IRQ IRQ_GPIO(GPIO_DM9000)
+
+/* UCB1400 audio / TS-controller */
+#define GPIO_UCB1400 1
+#define TRIZEPS4_UCB1400_IRQ IRQ_GPIO(GPIO_UCB1400)
+
+/* PCMCIA socket Compact Flash */
+#define GPIO_PCD 11 /* PCMCIA Card Detect */
+#define TRIZEPS4_CD_IRQ IRQ_GPIO(GPIO_PCD)
+#define GPIO_PRDY 13 /* READY / nINT */
+#define TRIZEPS4_READY_NINT IRQ_GPIO(GPIO_PRDY)
+
+/* MMC socket */
+#define GPIO_MMC_DET 12
+#define TRIZEPS4_MMC_IRQ IRQ_GPIO(GPIO_MMC_DET)
+
+/* DOC NAND chip */
+#define GPIO_DOC_LOCK 94
+#define GPIO_DOC_IRQ 93
+#define TRIZEPS4_DOC_IRQ IRQ_GPIO(GPIO_DOC_IRQ)
+
+/* SPI interface */
+#define GPIO_SPI 53
+#define TRIZEPS4_SPI_IRQ IRQ_GPIO(GPIO_SPI)
+
+/* LEDS using tx2 / rx2 */
+#define GPIO_SYS_BUSY_LED 46
+#define GPIO_HEARTBEAT_LED 47
+
+/* Off-module PIC on ConXS board */
+#define GPIO_PIC 0
+#define TRIZEPS4_PIC_IRQ IRQ_GPIO(GPIO_PIC)
+
+#ifdef CONFIG_MACH_TRIZEPS_CONXS
+/* for CONXS base board define these registers */
+#define CFSR_P2V(x) ((x) - TRIZEPS4_CFSR_PHYS + TRIZEPS4_CFSR_VIRT)
+#define CFSR_V2P(x) ((x) - TRIZEPS4_CFSR_VIRT + TRIZEPS4_CFSR_PHYS)
+
+#define BCR_P2V(x) ((x) - TRIZEPS4_BOCR_PHYS + TRIZEPS4_BOCR_VIRT)
+#define BCR_V2P(x) ((x) - TRIZEPS4_BOCR_VIRT + TRIZEPS4_BOCR_PHYS)
+
+#define DCR_P2V(x) ((x) - TRIZEPS4_DICR_PHYS + TRIZEPS4_DICR_VIRT)
+#define DCR_V2P(x) ((x) - TRIZEPS4_DICR_VIRT + TRIZEPS4_DICR_PHYS)
+
+#define IRCR_P2V(x) ((x) - TRIZEPS4_IRCR_PHYS + TRIZEPS4_IRCR_VIRT)
+#define IRCR_V2P(x) ((x) - TRIZEPS4_IRCR_VIRT + TRIZEPS4_IRCR_PHYS)
+
+#ifndef __ASSEMBLY__
+static inline unsigned short CFSR_readw(void)
+{
+ /* [Compact Flash Status Register] is read only */
+ return *((unsigned short *)CFSR_P2V(0x0C000000));
+}
+static inline void BCR_writew(unsigned short value)
+{
+ /* [Board Control Regsiter] is write only */
+ *((unsigned short *)BCR_P2V(0x0E000000)) = value;
+}
+static inline void DCR_writew(unsigned short value)
+{
+ /* [Display Control Register] is write only */
+ *((unsigned short *)DCR_P2V(0x0E000000)) = value;
+}
+static inline void IRCR_writew(unsigned short value)
+{
+ /* [InfraRed data Control Register] is write only */
+ *((unsigned short *)IRCR_P2V(0x0E000000)) = value;
+}
+#else
+#define ConXS_CFSR CFSR_P2V(0x0C000000)
+#define ConXS_BCR BCR_P2V(0x0E000000)
+#define ConXS_DCR DCR_P2V(0x0F800000)
+#define ConXS_IRCR IRCR_P2V(0x0F800000)
+#endif
+#else
+/* for whatever baseboard define function registers */
+static inline unsigned short CFSR_readw(void)
+{
+ return 0;
+}
+static inline void BCR_writew(unsigned short value)
+{
+ ;
+}
+static inline void DCR_writew(unsigned short value)
+{
+ ;
+}
+static inline void IRCR_writew(unsigned short value)
+{
+ ;
+}
+#endif /* CONFIG_MACH_TRIZEPS_CONXS */
+
+#define ConXS_CFSR_BVD_MASK 0x0003
+#define ConXS_CFSR_BVD1 (1 << 0)
+#define ConXS_CFSR_BVD2 (1 << 1)
+#define ConXS_CFSR_VS_MASK 0x000C
+#define ConXS_CFSR_VS1 (1 << 2)
+#define ConXS_CFSR_VS2 (1 << 3)
+#define ConXS_CFSR_VS_5V (0x3 << 2)
+#define ConXS_CFSR_VS_3V3 0x0
+
+#define ConXS_BCR_S0_POW_EN0 (1 << 0)
+#define ConXS_BCR_S0_POW_EN1 (1 << 1)
+#define ConXS_BCR_L_DISP (1 << 4)
+#define ConXS_BCR_CF_BUF_EN (1 << 5)
+#define ConXS_BCR_CF_RESET (1 << 7)
+#define ConXS_BCR_S0_VCC_3V3 0x1
+#define ConXS_BCR_S0_VCC_5V0 0x2
+#define ConXS_BCR_S0_VPP_12V 0x4
+#define ConXS_BCR_S0_VPP_3V3 0x8
+
+#define ConXS_IRCR_MODE (1 << 0)
+#define ConXS_IRCR_SD (1 << 1)
+
+#endif /* _TRIPEPS4_H_ */
diff --git a/arch/arm/mach-pxa/include/mach/udc.h b/arch/arm/mach-pxa/include/mach/udc.h
new file mode 100644
index 00000000..2f82332e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/udc.h
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/mach-pxa/include/mach/udc.h
+ *
+ */
+#include <asm/mach/udc_pxa2xx.h>
+
+extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
+
diff --git a/arch/arm/mach-pxa/include/mach/uncompress.h b/arch/arm/mach-pxa/include/mach/uncompress.h
new file mode 100644
index 00000000..5519a34b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/uncompress.h
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/mach-pxa/include/mach/uncompress.h
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+
+#define FFUART_BASE (0x40100000)
+#define BTUART_BASE (0x40200000)
+#define STUART_BASE (0x40700000)
+
+unsigned long uart_base;
+unsigned int uart_shift;
+unsigned int uart_is_pxa;
+
+static inline unsigned char uart_read(int offset)
+{
+ return *(volatile unsigned char *)(uart_base + (offset << uart_shift));
+}
+
+static inline void uart_write(unsigned char val, int offset)
+{
+ *(volatile unsigned char *)(uart_base + (offset << uart_shift)) = val;
+}
+
+static inline int uart_is_enabled(void)
+{
+ /* assume enabled by default for non-PXA uarts */
+ return uart_is_pxa ? uart_read(UART_IER) & UART_IER_UUE : 1;
+}
+
+static inline void putc(char c)
+{
+ if (!uart_is_enabled())
+ return;
+
+ while (!(uart_read(UART_LSR) & UART_LSR_THRE))
+ barrier();
+
+ uart_write(c, UART_TX);
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+ /* initialize to default */
+ uart_base = FFUART_BASE;
+ uart_shift = 2;
+ uart_is_pxa = 1;
+
+ if (machine_is_littleton() || machine_is_intelmote2()
+ || machine_is_csb726() || machine_is_stargate2()
+ || machine_is_cm_x300() || machine_is_balloon3())
+ uart_base = STUART_BASE;
+
+ if (machine_is_arcom_zeus()) {
+ uart_base = 0x10000000; /* nCS4 */
+ uart_shift = 1;
+ uart_is_pxa = 0;
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-pxa/include/mach/viper.h b/arch/arm/mach-pxa/include/mach/viper.h
new file mode 100644
index 00000000..5f5fbf1f
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/viper.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-pxa/include/mach/viper.h
+ *
+ * Author: Ian Campbell
+ * Created: Feb 03, 2003
+ * Copyright: Arcom Control Systems.
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ * <marc.zyngier@altran.com>
+ *
+ * Created based on lubbock.h:
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_VIPER_H
+#define ARCH_VIPER_H
+
+#define VIPER_BOOT_PHYS PXA_CS0_PHYS
+#define VIPER_FLASH_PHYS PXA_CS1_PHYS
+#define VIPER_ETH_PHYS PXA_CS2_PHYS
+#define VIPER_USB_PHYS PXA_CS3_PHYS
+#define VIPER_ETH_DATA_PHYS PXA_CS4_PHYS
+#define VIPER_CPLD_PHYS PXA_CS5_PHYS
+
+#define VIPER_CPLD_BASE (0xf0000000)
+#define VIPER_PC104IO_BASE (0xf1000000)
+#define VIPER_USB_BASE (0xf1800000)
+
+#define VIPER_ETH_GPIO (0)
+#define VIPER_CPLD_GPIO (1)
+#define VIPER_USB_GPIO (2)
+#define VIPER_UARTA_GPIO (4)
+#define VIPER_UARTB_GPIO (3)
+#define VIPER_CF_CD_GPIO (32)
+#define VIPER_CF_RDY_GPIO (8)
+#define VIPER_BCKLIGHT_EN_GPIO (9)
+#define VIPER_LCD_EN_GPIO (10)
+#define VIPER_PSU_DATA_GPIO (6)
+#define VIPER_PSU_CLK_GPIO (11)
+#define VIPER_UART_SHDN_GPIO (12)
+#define VIPER_BRIGHTNESS_GPIO (16)
+#define VIPER_PSU_nCS_LD_GPIO (19)
+#define VIPER_UPS_GPIO (20)
+#define VIPER_CF_POWER_GPIO (82)
+#define VIPER_TPM_I2C_SDA_GPIO (26)
+#define VIPER_TPM_I2C_SCL_GPIO (27)
+#define VIPER_RTC_I2C_SDA_GPIO (83)
+#define VIPER_RTC_I2C_SCL_GPIO (84)
+
+#define VIPER_CPLD_P2V(x) ((x) - VIPER_CPLD_PHYS + VIPER_CPLD_BASE)
+#define VIPER_CPLD_V2P(x) ((x) - VIPER_CPLD_BASE + VIPER_CPLD_PHYS)
+
+#ifndef __ASSEMBLY__
+# define __VIPER_CPLD_REG(x) (*((volatile u16 *)VIPER_CPLD_P2V(x)))
+#endif
+
+/* board level registers in the CPLD: (offsets from CPLD_BASE) ... */
+
+/* ... Physical addresses */
+#define _VIPER_LO_IRQ_STATUS (VIPER_CPLD_PHYS + 0x100000)
+#define _VIPER_ICR_PHYS (VIPER_CPLD_PHYS + 0x100002)
+#define _VIPER_HI_IRQ_STATUS (VIPER_CPLD_PHYS + 0x100004)
+#define _VIPER_VERSION_PHYS (VIPER_CPLD_PHYS + 0x100006)
+#define VIPER_UARTA_PHYS (VIPER_CPLD_PHYS + 0x300010)
+#define VIPER_UARTB_PHYS (VIPER_CPLD_PHYS + 0x300000)
+#define _VIPER_SRAM_BASE (VIPER_CPLD_PHYS + 0x800000)
+
+/* ... Virtual addresses */
+#define VIPER_LO_IRQ_STATUS __VIPER_CPLD_REG(_VIPER_LO_IRQ_STATUS)
+#define VIPER_HI_IRQ_STATUS __VIPER_CPLD_REG(_VIPER_HI_IRQ_STATUS)
+#define VIPER_VERSION __VIPER_CPLD_REG(_VIPER_VERSION_PHYS)
+#define VIPER_ICR __VIPER_CPLD_REG(_VIPER_ICR_PHYS)
+
+/* Decode VIPER_VERSION register */
+#define VIPER_CPLD_REVISION(x) (((x) >> 5) & 0x7)
+#define VIPER_BOARD_VERSION(x) (((x) >> 3) & 0x3)
+#define VIPER_BOARD_ISSUE(x) (((x) >> 0) & 0x7)
+
+/* Interrupt and Configuration Register (VIPER_ICR) */
+/* This is a write only register. Only CF_RST is used under Linux */
+
+#define VIPER_ICR_RETRIG (1 << 0)
+#define VIPER_ICR_AUTO_CLR (1 << 1)
+#define VIPER_ICR_R_DIS (1 << 2)
+#define VIPER_ICR_CF_RST (1 << 3)
+
+#endif
+
diff --git a/arch/arm/mach-pxa/include/mach/vmalloc.h b/arch/arm/mach-pxa/include/mach/vmalloc.h
new file mode 100644
index 00000000..bfecfbf5
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/vmalloc.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/mach-pxa/include/mach/vmalloc.h
+ *
+ * Author: Nicolas Pitre
+ * Copyright: (C) 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VMALLOC_END (0xe8000000UL)
diff --git a/arch/arm/mach-pxa/include/mach/vpac270.h b/arch/arm/mach-pxa/include/mach/vpac270.h
new file mode 100644
index 00000000..7bfa3dd0
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/vpac270.h
@@ -0,0 +1,42 @@
+/*
+ * GPIOs and interrupts for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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 _INCLUDE_VPAC270_H_
+#define _INCLUDE_VPAC270_H_
+
+#define GPIO1_VPAC270_USER_BTN 1
+
+#define GPIO15_VPAC270_LED_ORANGE 15
+
+#define GPIO81_VPAC270_BKL_ON 81
+#define GPIO83_VPAC270_NL_ON 83
+
+#define GPIO52_VPAC270_SD_READONLY 52
+#define GPIO53_VPAC270_SD_DETECT_N 53
+
+#define GPIO84_VPAC270_PCMCIA_CD 84
+#define GPIO35_VPAC270_PCMCIA_RDY 35
+#define GPIO107_VPAC270_PCMCIA_PPEN 107
+#define GPIO11_VPAC270_PCMCIA_RESET 11
+#define GPIO17_VPAC270_CF_CD 17
+#define GPIO12_VPAC270_CF_RDY 12
+#define GPIO16_VPAC270_CF_RESET 16
+
+#define GPIO41_VPAC270_UDC_DETECT 41
+
+#define GPIO114_VPAC270_ETH_IRQ 114
+
+#define GPIO36_VPAC270_IDE_IRQ 36
+
+#define GPIO113_VPAC270_TS_IRQ 113
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h
new file mode 100644
index 00000000..7b0f71ef
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/z2.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-pxa/include/mach/z2.h
+ *
+ * Author: Ken McGuire
+ * Created: Feb 6, 2009
+ *
+ * This program is free software; you can 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_ZIPIT2_H
+#define ASM_ARCH_ZIPIT2_H
+
+/* LEDs */
+#define GPIO10_ZIPITZ2_LED_WIFI 10
+#define GPIO85_ZIPITZ2_LED_CHARGED 85
+#define GPIO83_ZIPITZ2_LED_CHARGING 83
+
+/* SD/MMC */
+#define GPIO96_ZIPITZ2_SD_DETECT 96
+
+/* GPIO Buttons */
+#define GPIO1_ZIPITZ2_POWER_BUTTON 1
+#define GPIO98_ZIPITZ2_LID_BUTTON 98
+
+/* Libertas GSPI8686 WiFi */
+#define GPIO14_ZIPITZ2_WIFI_POWER 14
+#define GPIO24_ZIPITZ2_WIFI_CS 24
+#define GPIO36_ZIPITZ2_WIFI_IRQ 36
+
+/* LCD */
+#define GPIO19_ZIPITZ2_LCD_RESET 19
+#define GPIO88_ZIPITZ2_LCD_CS 88
+
+/* MISC GPIOs */
+#define GPIO0_ZIPITZ2_AC_DETECT 0
+#define GPIO37_ZIPITZ2_HEADSET_DETECT 37
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/zeus.h b/arch/arm/mach-pxa/include/mach/zeus.h
new file mode 100644
index 00000000..0641f31a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/zeus.h
@@ -0,0 +1,85 @@
+/*
+ * arch/arm/mach-pxa/include/mach/zeus.h
+ *
+ * Author: David Vrabel
+ * Created: Sept 28, 2005
+ * Copyright: Arcom Control Systems Ltd.
+ *
+ * Maintained by: Marc Zyngier <maz@misterjones.org>
+ *
+ * This program is free software; you can 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_ZEUS_H
+#define _MACH_ZEUS_H
+
+#define ZEUS_NR_IRQS (IRQ_BOARD_START + 48)
+
+/* Physical addresses */
+#define ZEUS_FLASH_PHYS PXA_CS0_PHYS
+#define ZEUS_ETH0_PHYS PXA_CS1_PHYS
+#define ZEUS_ETH1_PHYS PXA_CS2_PHYS
+#define ZEUS_CPLD_PHYS (PXA_CS4_PHYS+0x2000000)
+#define ZEUS_SRAM_PHYS PXA_CS5_PHYS
+#define ZEUS_PC104IO_PHYS (0x30000000)
+
+#define ZEUS_CPLD_VERSION_PHYS (ZEUS_CPLD_PHYS + 0x00000000)
+#define ZEUS_CPLD_ISA_IRQ_PHYS (ZEUS_CPLD_PHYS + 0x00800000)
+#define ZEUS_CPLD_CONTROL_PHYS (ZEUS_CPLD_PHYS + 0x01000000)
+#define ZEUS_CPLD_EXTWDOG_PHYS (ZEUS_CPLD_PHYS + 0x01800000)
+
+/* GPIOs */
+#define ZEUS_AC97_GPIO 0
+#define ZEUS_WAKEUP_GPIO 1
+#define ZEUS_UARTA_GPIO 9
+#define ZEUS_UARTB_GPIO 10
+#define ZEUS_UARTC_GPIO 12
+#define ZEUS_UARTD_GPIO 11
+#define ZEUS_ETH0_GPIO 14
+#define ZEUS_ISA_GPIO 17
+#define ZEUS_BKLEN_GPIO 19
+#define ZEUS_USB2_PWREN_GPIO 22
+#define ZEUS_PTT_GPIO 27
+#define ZEUS_CF_CD_GPIO 35
+#define ZEUS_MMC_WP_GPIO 52
+#define ZEUS_MMC_CD_GPIO 53
+#define ZEUS_EXTGPIO_GPIO 91
+#define ZEUS_CF_PWEN_GPIO 97
+#define ZEUS_CF_RDY_GPIO 99
+#define ZEUS_LCD_EN_GPIO 101
+#define ZEUS_ETH1_GPIO 113
+#define ZEUS_CAN_GPIO 116
+
+#define ZEUS_EXT0_GPIO_BASE 128
+#define ZEUS_EXT1_GPIO_BASE 160
+#define ZEUS_USER_GPIO_BASE 192
+
+#define ZEUS_EXT0_GPIO(x) (ZEUS_EXT0_GPIO_BASE + (x))
+#define ZEUS_EXT1_GPIO(x) (ZEUS_EXT1_GPIO_BASE + (x))
+#define ZEUS_USER_GPIO(x) (ZEUS_USER_GPIO_BASE + (x))
+
+#define ZEUS_CAN_SHDN_GPIO ZEUS_EXT1_GPIO(2)
+
+/*
+ * CPLD registers:
+ * Only 4 registers, but spread over a 32MB address space.
+ * Be gentle, and remap that over 32kB...
+ */
+
+#define ZEUS_CPLD (0xf0000000)
+#define ZEUS_CPLD_VERSION (ZEUS_CPLD + 0x0000)
+#define ZEUS_CPLD_ISA_IRQ (ZEUS_CPLD + 0x1000)
+#define ZEUS_CPLD_CONTROL (ZEUS_CPLD + 0x2000)
+
+/* CPLD register bits */
+#define ZEUS_CPLD_CONTROL_CF_RST 0x01
+
+#define ZEUS_PC104IO (0xf1000000)
+
+#define ZEUS_SRAM_SIZE (256 * 1024)
+
+#endif
+
+
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
new file mode 100644
index 00000000..ea24998b
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/zylonite.h
@@ -0,0 +1,42 @@
+#ifndef __ASM_ARCH_ZYLONITE_H
+#define __ASM_ARCH_ZYLONITE_H
+
+#define ZYLONITE_ETH_PHYS 0x14000000
+
+#define EXT_GPIO(x) (128 + (x))
+
+#define ZYLONITE_NR_IRQS (IRQ_BOARD_START + 32)
+
+/* the following variables are processor specific and initialized
+ * by the corresponding zylonite_pxa3xx_init()
+ */
+extern int gpio_eth_irq;
+extern int gpio_debug_led1;
+extern int gpio_debug_led2;
+
+extern int wm9713_irq;
+
+extern int lcd_id;
+extern int lcd_orientation;
+
+#ifdef CONFIG_CPU_PXA300
+extern void zylonite_pxa300_init(void);
+#else
+static inline void zylonite_pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310())
+ panic("%s: PXA300/PXA310 not supported\n", __func__);
+}
+#endif
+
+#ifdef CONFIG_CPU_PXA320
+extern void zylonite_pxa320_init(void);
+#else
+static inline void zylonite_pxa320_init(void)
+{
+ if (cpu_is_pxa320())
+ panic("%s: PXA320 not supported\n", __func__);
+}
+#endif
+
+#endif /* __ASM_ARCH_ZYLONITE_H */
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
new file mode 100644
index 00000000..32ed551b
--- /dev/null
+++ b/arch/arm/mach-pxa/irq.c
@@ -0,0 +1,230 @@
+/*
+ * linux/arch/arm/mach-pxa/irq.c
+ *
+ * Generic PXA IRQ handling
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+#define IRQ_BASE (void __iomem *)io_p2v(0x40d00000)
+
+#define ICIP (0x000)
+#define ICMR (0x004)
+#define ICLR (0x008)
+#define ICFR (0x00c)
+#define ICPR (0x010)
+#define ICCR (0x014)
+#define ICHP (0x018)
+#define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \
+ ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \
+ (0x144 + (((i) - 64) << 2)))
+#define IPR_VALID (1 << 31)
+#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
+
+#define MAX_INTERNAL_IRQS 128
+
+/*
+ * This is for peripheral IRQs internal to the PXA chip.
+ */
+
+static int pxa_internal_irq_nr;
+
+static inline int cpu_has_ipr(void)
+{
+ return !cpu_is_pxa25x();
+}
+
+static inline void __iomem *irq_base(int i)
+{
+ static unsigned long phys_base[] = {
+ 0x40d00000,
+ 0x40d0009c,
+ 0x40d00130,
+ };
+
+ return (void __iomem *)io_p2v(phys_base[i]);
+}
+
+static void pxa_mask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr &= ~(1 << IRQ_BIT(d->irq));
+ __raw_writel(icmr, base + ICMR);
+}
+
+static void pxa_unmask_irq(struct irq_data *d)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(d);
+ uint32_t icmr = __raw_readl(base + ICMR);
+
+ icmr |= 1 << IRQ_BIT(d->irq);
+ __raw_writel(icmr, base + ICMR);
+}
+
+static struct irq_chip pxa_internal_irq_chip = {
+ .name = "SC",
+ .irq_ack = pxa_mask_irq,
+ .irq_mask = pxa_mask_irq,
+ .irq_unmask = pxa_unmask_irq,
+};
+
+/*
+ * GPIO IRQs for GPIO 0 and 1
+ */
+static int pxa_set_low_gpio_type(struct irq_data *d, unsigned int type)
+{
+ int gpio = d->irq - IRQ_GPIO0;
+
+ if (__gpio_is_occupied(gpio)) {
+ pr_err("%s failed: GPIO is configured\n", __func__);
+ return -EINVAL;
+ }
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ GRER0 |= GPIO_bit(gpio);
+ else
+ GRER0 &= ~GPIO_bit(gpio);
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ GFER0 |= GPIO_bit(gpio);
+ else
+ GFER0 &= ~GPIO_bit(gpio);
+
+ return 0;
+}
+
+static void pxa_ack_low_gpio(struct irq_data *d)
+{
+ GEDR0 = (1 << (d->irq - IRQ_GPIO0));
+}
+
+static struct irq_chip pxa_low_gpio_chip = {
+ .name = "GPIO-l",
+ .irq_ack = pxa_ack_low_gpio,
+ .irq_mask = pxa_mask_irq,
+ .irq_unmask = pxa_unmask_irq,
+ .irq_set_type = pxa_set_low_gpio_type,
+};
+
+static void __init pxa_init_low_gpio_irq(set_wake_t fn)
+{
+ int irq;
+
+ /* clear edge detection on GPIO 0 and 1 */
+ GFER0 &= ~0x3;
+ GRER0 &= ~0x3;
+ GEDR0 = 0x3;
+
+ for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
+ irq_set_chip_and_handler(irq, &pxa_low_gpio_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, irq_base(0));
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ pxa_low_gpio_chip.irq_set_wake = fn;
+}
+
+void __init pxa_init_irq(int irq_nr, set_wake_t fn)
+{
+ int irq, i, n;
+
+ BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
+
+ pxa_internal_irq_nr = irq_nr;
+
+ for (n = 0; n < irq_nr; n += 32) {
+ void __iomem *base = irq_base(n >> 5);
+
+ __raw_writel(0, base + ICMR); /* disable all IRQs */
+ __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */
+ for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
+ /* initialize interrupt priority */
+ if (cpu_has_ipr())
+ __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
+
+ irq = PXA_IRQ(i);
+ irq_set_chip_and_handler(irq, &pxa_internal_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, base);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+ }
+
+ /* only unmasked interrupts kick us out of idle */
+ __raw_writel(1, irq_base(0) + ICCR);
+
+ pxa_internal_irq_chip.irq_set_wake = fn;
+ pxa_init_low_gpio_irq(fn);
+}
+
+#ifdef CONFIG_PM
+static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
+static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
+
+static int pxa_irq_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
+ void __iomem *base = irq_base(i);
+
+ saved_icmr[i] = __raw_readl(base + ICMR);
+ __raw_writel(0, base + ICMR);
+ }
+
+ if (cpu_has_ipr()) {
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
+ }
+
+ return 0;
+}
+
+static void pxa_irq_resume(void)
+{
+ int i;
+
+ for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
+ void __iomem *base = irq_base(i);
+
+ __raw_writel(saved_icmr[i], base + ICMR);
+ __raw_writel(0, base + ICLR);
+ }
+
+ if (cpu_has_ipr())
+ for (i = 0; i < pxa_internal_irq_nr; i++)
+ __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
+
+ __raw_writel(1, IRQ_BASE + ICCR);
+}
+#else
+#define pxa_irq_suspend NULL
+#define pxa_irq_resume NULL
+#endif
+
+struct syscore_ops pxa_irq_syscore_ops = {
+ .suspend = pxa_irq_suspend,
+ .resume = pxa_irq_resume,
+};
diff --git a/arch/arm/mach-pxa/leds-idp.c b/arch/arm/mach-pxa/leds-idp.c
new file mode 100644
index 00000000..8b9c1714
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-idp.c
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-idp.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Macros for actual LED manipulation should be in machine specific
+ * files in this 'mach' directory.
+ */
+
+
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <mach/pxa25x.h>
+#include <mach/idp.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void idp_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= IDP_HB_LED;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~IDP_BUSY_LED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= IDP_BUSY_LED;
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= IDP_HB_LED;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~IDP_HB_LED;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= IDP_BUSY_LED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~IDP_BUSY_LED;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ IDP_CPLD_LED_CONTROL = ( (IDP_CPLD_LED_CONTROL | IDP_LEDS_MASK) & ~hw_led_state);
+ else
+ IDP_CPLD_LED_CONTROL |= IDP_LEDS_MASK;
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds-lubbock.c b/arch/arm/mach-pxa/leds-lubbock.c
new file mode 100644
index 00000000..e26d5efe
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-lubbock.c
@@ -0,0 +1,125 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-lubbock.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Major surgery on April 2004 by Nicolas Pitre for less global
+ * namespace collision. Mostly adapted the Mainstone version.
+ */
+
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <mach/pxa25x.h>
+#include <mach/lubbock.h>
+
+#include "leds.h"
+
+/*
+ * 8 discrete leds available for general use:
+ *
+ * Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays
+ * so be sure to not monkey with them here.
+ */
+
+#define D28 (1 << 0)
+#define D27 (1 << 1)
+#define D26 (1 << 2)
+#define D25 (1 << 3)
+#define D24 (1 << 4)
+#define D23 (1 << 5)
+#define D22 (1 << 6)
+#define D21 (1 << 7)
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void lubbock_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = 0;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ hw_led_state ^= D26;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ hw_led_state &= ~D27;
+ break;
+
+ case led_idle_end:
+ hw_led_state |= D27;
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ hw_led_state |= D21;
+ break;
+
+ case led_green_off:
+ hw_led_state &= ~D21;
+ break;
+
+ case led_amber_on:
+ hw_led_state |= D22;
+ break;
+
+ case led_amber_off:
+ hw_led_state &= ~D22;
+ break;
+
+ case led_red_on:
+ hw_led_state |= D23;
+ break;
+
+ case led_red_off:
+ hw_led_state &= ~D23;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ LUB_DISC_BLNK_LED = (LUB_DISC_BLNK_LED | 0xff) & ~hw_led_state;
+ else
+ LUB_DISC_BLNK_LED |= 0xff;
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds-mainstone.c b/arch/arm/mach-pxa/leds-mainstone.c
new file mode 100644
index 00000000..db4af5ee
--- /dev/null
+++ b/arch/arm/mach-pxa/leds-mainstone.c
@@ -0,0 +1,120 @@
+/*
+ * linux/arch/arm/mach-pxa/leds-mainstone.c
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 05, 2002
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include <mach/pxa27x.h>
+#include <mach/mainstone.h>
+
+#include "leds.h"
+
+
+/* 8 discrete leds available for general use: */
+#define D28 (1 << 0)
+#define D27 (1 << 1)
+#define D26 (1 << 2)
+#define D25 (1 << 3)
+#define D24 (1 << 4)
+#define D23 (1 << 5)
+#define D22 (1 << 6)
+#define D21 (1 << 7)
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void mainstone_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = 0;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ hw_led_state ^= D26;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ hw_led_state &= ~D27;
+ break;
+
+ case led_idle_end:
+ hw_led_state |= D27;
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ hw_led_state |= D21;
+ break;
+
+ case led_green_off:
+ hw_led_state &= ~D21;
+ break;
+
+ case led_amber_on:
+ hw_led_state |= D22;
+ break;
+
+ case led_amber_off:
+ hw_led_state &= ~D22;
+ break;
+
+ case led_red_on:
+ hw_led_state |= D23;
+ break;
+
+ case led_red_off:
+ hw_led_state &= ~D23;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ MST_LEDCTRL = (MST_LEDCTRL | 0xff) & ~hw_led_state;
+ else
+ MST_LEDCTRL |= 0xff;
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-pxa/leds.c b/arch/arm/mach-pxa/leds.c
new file mode 100644
index 00000000..bbe4d5f6
--- /dev/null
+++ b/arch/arm/mach-pxa/leds.c
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/arm/mach-pxa/leds.c
+ *
+ * xscale LEDs dispatcher
+ *
+ * Copyright (C) 2001 Nicolas Pitre
+ *
+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include "leds.h"
+
+static int __init
+pxa_leds_init(void)
+{
+ if (machine_is_lubbock())
+ leds_event = lubbock_leds_event;
+ if (machine_is_mainstone())
+ leds_event = mainstone_leds_event;
+ if (machine_is_pxa_idp())
+ leds_event = idp_leds_event;
+
+ leds_event(led_start);
+ return 0;
+}
+
+core_initcall(pxa_leds_init);
diff --git a/arch/arm/mach-pxa/leds.h b/arch/arm/mach-pxa/leds.h
new file mode 100644
index 00000000..7f0dfe01
--- /dev/null
+++ b/arch/arm/mach-pxa/leds.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-pxa/leds.h
+ *
+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
+ *
+ * blinky lights for various PXA-based systems:
+ *
+ */
+
+extern void idp_leds_event(led_event_t evt);
+extern void lubbock_leds_event(led_event_t evt);
+extern void mainstone_leds_event(led_event_t evt);
+extern void trizeps4_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
new file mode 100644
index 00000000..e5e326d2
--- /dev/null
+++ b/arch/arm/mach-pxa/littleton.c
@@ -0,0 +1,446 @@
+/*
+ * linux/arch/arm/mach-pxa/littleton.c
+ *
+ * Support for the Marvell Littleton Development Platform.
+ *
+ * Author: Jason Chagas (largely modified code)
+ * Created: Nov 20, 2006
+ * Copyright: (C) Copyright 2006 Marvell International Ltd.
+ *
+ * 2007-11-22 modified to align with latest kernel
+ * eric miao <eric.miao@marvell.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
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/smc91x.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/mfd/da903x.h>
+#include <linux/i2c/max732x.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa300.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/littleton.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "generic.h"
+
+#define GPIO_MMC1_CARD_DETECT mfp_to_gpio(MFP_PIN_GPIO15)
+
+/* Littleton MFP configurations */
+static mfp_cfg_t littleton_mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+
+ /* SSP2 */
+ GPIO25_SSP2_SCLK,
+ GPIO27_SSP2_TXD,
+ GPIO17_GPIO, /* SFRM as chip-select */
+
+ /* Debug Ethernet */
+ GPIO90_GPIO,
+
+ /* Keypad */
+ GPIO107_KP_DKIN_0,
+ GPIO108_KP_DKIN_1,
+ GPIO115_KP_MKIN_0,
+ GPIO116_KP_MKIN_1,
+ GPIO117_KP_MKIN_2,
+ GPIO118_KP_MKIN_3,
+ GPIO119_KP_MKIN_4,
+ GPIO120_KP_MKIN_5,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+
+ /* MMC1 */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+ GPIO15_GPIO, /* card detect */
+
+ /* UART3 */
+ GPIO107_UART3_CTS,
+ GPIO108_UART3_RTS,
+ GPIO109_UART3_TXD,
+ GPIO110_UART3_RXD,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = (LITTLETON_ETH_PHYS + 0x300),
+ .end = (LITTLETON_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
+ .end = IRQ_GPIO(mfp_to_gpio(MFP_PIN_GPIO90)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ }
+};
+
+static struct smc91x_platdata littleton_smc91x_info = {
+ .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT |
+ SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &littleton_smc91x_info,
+ },
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info tpo_tdo24mtea1_modes[] = {
+ [0] = {
+ /* VGA */
+ .pixclock = 38250,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 8,
+ .left_margin = 8,
+ .right_margin = 24,
+ .vsync_len = 2,
+ .upper_margin = 2,
+ .lower_margin = 4,
+ .sync = 0,
+ },
+ [1] = {
+ /* QVGA */
+ .pixclock = 153000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 8,
+ .left_margin = 8,
+ .right_margin = 88,
+ .vsync_len = 2,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info littleton_lcd_info = {
+ .modes = tpo_tdo24mtea1_modes,
+ .num_modes = 2,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+};
+
+static void littleton_init_lcd(void)
+{
+ pxa_set_fb_info(NULL, &littleton_lcd_info);
+}
+#else
+static inline void littleton_init_lcd(void) {};
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
+
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master littleton_spi_info = {
+ .num_chipselect = 1,
+};
+
+static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .gpio_cs = LITTLETON_GPIO_LCD_CS,
+};
+
+static struct spi_board_info littleton_spi_devices[] __initdata = {
+ {
+ .modalias = "tdo24m",
+ .max_speed_hz = 1000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .controller_data= &littleton_tdo24m_chip,
+ },
+};
+
+static void __init littleton_init_spi(void)
+{
+ pxa2xx_set_spi_info(2, &littleton_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
+}
+#else
+static inline void littleton_init_spi(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int littleton_matrix_key_map[] = {
+ /* KEY(row, col, key_code) */
+ KEY(1, 3, KEY_0), KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), KEY(2, 0, KEY_3),
+ KEY(0, 1, KEY_4), KEY(1, 1, KEY_5), KEY(2, 1, KEY_6), KEY(0, 2, KEY_7),
+ KEY(1, 2, KEY_8), KEY(2, 2, KEY_9),
+
+ KEY(0, 3, KEY_KPASTERISK), /* * */
+ KEY(2, 3, KEY_KPDOT), /* # */
+
+ KEY(5, 4, KEY_ENTER),
+
+ KEY(5, 0, KEY_UP),
+ KEY(5, 1, KEY_DOWN),
+ KEY(5, 2, KEY_LEFT),
+ KEY(5, 3, KEY_RIGHT),
+ KEY(3, 2, KEY_HOME),
+ KEY(4, 1, KEY_END),
+ KEY(3, 3, KEY_BACK),
+
+ KEY(4, 0, KEY_SEND),
+ KEY(4, 2, KEY_VOLUMEUP),
+ KEY(4, 3, KEY_VOLUMEDOWN),
+
+ KEY(3, 0, KEY_F22), /* soft1 */
+ KEY(3, 1, KEY_F23), /* soft2 */
+};
+
+static struct pxa27x_keypad_platform_data littleton_keypad_info = {
+ .matrix_key_rows = 6,
+ .matrix_key_cols = 5,
+ .matrix_key_map = littleton_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(littleton_matrix_key_map),
+
+ .enable_rotary0 = 1,
+ .rotary0_up_key = KEY_UP,
+ .rotary0_down_key = KEY_DOWN,
+
+ .debounce_interval = 30,
+};
+static void __init littleton_init_keypad(void)
+{
+ pxa_set_keypad_info(&littleton_keypad_info);
+}
+#else
+static inline void littleton_init_keypad(void) {}
+#endif
+
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data littleton_mci_platform_data = {
+ .detect_delay_ms = 200,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_card_detect = GPIO_MMC1_CARD_DETECT,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void __init littleton_init_mmc(void)
+{
+ pxa_set_mci_info(&littleton_mci_platform_data);
+}
+#else
+static inline void littleton_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition littleton_nand_partitions[] = {
+ [0] = {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = 0x060000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [1] = {
+ .name = "Kernel",
+ .offset = 0x060000,
+ .size = 0x200000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [2] = {
+ .name = "Filesystem",
+ .offset = 0x0260000,
+ .size = 0x3000000, /* 48M - rootfs */
+ },
+ [3] = {
+ .name = "MassStorage",
+ .offset = 0x3260000,
+ .size = 0x3d40000,
+ },
+ [4] = {
+ .name = "BBT",
+ .offset = 0x6FA0000,
+ .size = 0x80000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* NOTE: we reserve some blocks at the end of the NAND flash for
+ * bad block management, and the max number of relocation blocks
+ * differs on different platforms. Please take care with it when
+ * defining the partition table.
+ */
+};
+
+static struct pxa3xx_nand_platform_data littleton_nand_info = {
+ .enable_arbiter = 1,
+ .parts = littleton_nand_partitions,
+ .nr_parts = ARRAY_SIZE(littleton_nand_partitions),
+};
+
+static void __init littleton_init_nand(void)
+{
+ pxa3xx_set_nand_info(&littleton_nand_info);
+}
+#else
+static inline void littleton_init_nand(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct led_info littleton_da9034_leds[] = {
+ [0] = {
+ .name = "littleton:keypad1",
+ .flags = DA9034_LED_RAMP,
+ },
+ [1] = {
+ .name = "littleton:keypad2",
+ .flags = DA9034_LED_RAMP,
+ },
+ [2] = {
+ .name = "littleton:vibra",
+ .flags = 0,
+ },
+};
+
+static struct da9034_touch_pdata littleton_da9034_touch = {
+ .x_inverted = 1,
+ .interval_ms = 20,
+};
+
+static struct da903x_subdev_info littleton_da9034_subdevs[] = {
+ {
+ .name = "da903x-led",
+ .id = DA9034_ID_LED_1,
+ .platform_data = &littleton_da9034_leds[0],
+ }, {
+ .name = "da903x-led",
+ .id = DA9034_ID_LED_2,
+ .platform_data = &littleton_da9034_leds[1],
+ }, {
+ .name = "da903x-led",
+ .id = DA9034_ID_VIBRA,
+ .platform_data = &littleton_da9034_leds[2],
+ }, {
+ .name = "da903x-backlight",
+ .id = DA9034_ID_WLED,
+ }, {
+ .name = "da9034-touch",
+ .id = DA9034_ID_TOUCH,
+ .platform_data = &littleton_da9034_touch,
+ },
+};
+
+static struct da903x_platform_data littleton_da9034_info = {
+ .num_subdevs = ARRAY_SIZE(littleton_da9034_subdevs),
+ .subdevs = littleton_da9034_subdevs,
+};
+
+static struct max732x_platform_data littleton_max7320_info = {
+ .gpio_base = EXT0_GPIO_BASE,
+};
+
+static struct i2c_board_info littleton_i2c_info[] = {
+ [0] = {
+ .type = "da9034",
+ .addr = 0x34,
+ .platform_data = &littleton_da9034_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO18)),
+ },
+ [1] = {
+ .type = "max7320",
+ .addr = 0x50,
+ .platform_data = &littleton_max7320_info,
+ },
+};
+
+static void __init littleton_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(littleton_i2c_info));
+}
+#else
+static inline void littleton_init_i2c(void) {}
+#endif /* CONFIG_I2C_PXA || CONFIG_I2C_PXA_MODULE */
+
+static void __init littleton_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(littleton_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ /*
+ * Note: we depend bootloader set the correct
+ * value to MSC register for SMC91x.
+ */
+ platform_device_register(&smc91x_device);
+
+ littleton_init_spi();
+ littleton_init_i2c();
+ littleton_init_mmc();
+ littleton_init_lcd();
+ littleton_init_keypad();
+ littleton_init_nand();
+}
+
+MACHINE_START(LITTLETON, "Marvell Form Factor Development Platform (aka Littleton)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = LITTLETON_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = littleton_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
new file mode 100644
index 00000000..6cf8180b
--- /dev/null
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -0,0 +1,508 @@
+/*
+ * linux/arch/arm/mach-pxa/lpd270.c
+ *
+ * Support for the LogicPD PXA270 Card Engine.
+ * Derived from the mainstone code, which carries these notices:
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 05, 2002
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
+#include <mach/lpd270.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long lpd270_pin_config[] __initdata = {
+ /* Chip Selects */
+ GPIO15_nCS_1, /* Mainboard Flash */
+ GPIO78_nCS_2, /* CPLD + Ethernet */
+
+ /* LCD - 16bpp Active TFT */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+ GPIO16_PWM0_OUT, /* Backlight */
+
+ /* USB Host */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO45_AC97_SYSCLK,
+
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+};
+
+static unsigned int lpd270_irq_enabled;
+
+static void lpd270_mask_irq(struct irq_data *d)
+{
+ int lpd270_irq = d->irq - LPD270_IRQ(0);
+
+ __raw_writew(~(1 << lpd270_irq), LPD270_INT_STATUS);
+
+ lpd270_irq_enabled &= ~(1 << lpd270_irq);
+ __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+}
+
+static void lpd270_unmask_irq(struct irq_data *d)
+{
+ int lpd270_irq = d->irq - LPD270_IRQ(0);
+
+ lpd270_irq_enabled |= 1 << lpd270_irq;
+ __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+}
+
+static struct irq_chip lpd270_irq_chip = {
+ .name = "CPLD",
+ .irq_ack = lpd270_mask_irq,
+ .irq_mask = lpd270_mask_irq,
+ .irq_unmask = lpd270_unmask_irq,
+};
+
+static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending;
+
+ pending = __raw_readw(LPD270_INT_STATUS) & lpd270_irq_enabled;
+ do {
+ /* clear useless edge notification */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ if (likely(pending)) {
+ irq = LPD270_IRQ(0) + __ffs(pending);
+ generic_handle_irq(irq);
+
+ pending = __raw_readw(LPD270_INT_STATUS) &
+ lpd270_irq_enabled;
+ }
+ } while (pending);
+}
+
+static void __init lpd270_init_irq(void)
+{
+ int irq;
+
+ pxa27x_init_irq();
+
+ __raw_writew(0, LPD270_INT_MASK);
+ __raw_writew(0, LPD270_INT_STATUS);
+
+ /* setup extra LogicPD PXA270 irqs */
+ for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) {
+ irq_set_chip_and_handler(irq, &lpd270_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ irq_set_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+}
+
+
+#ifdef CONFIG_PM
+static void lpd270_irq_resume(void)
+{
+ __raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
+}
+
+static struct syscore_ops lpd270_irq_syscore_ops = {
+ .resume = lpd270_irq_resume,
+};
+
+static int __init lpd270_irq_device_init(void)
+{
+ if (machine_is_logicpd_pxa270()) {
+ register_syscore_ops(&lpd270_irq_syscore_ops);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+device_initcall(lpd270_irq_device_init);
+#endif
+
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = LPD270_ETH_PHYS,
+ .end = (LPD270_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = LPD270_ETHERNET_IRQ,
+ .end = LPD270_ETHERNET_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource lpd270_flash_resources[] = {
+ [0] = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition lpd270_flash0_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Kernel",
+ .size = 0x00400000,
+ .offset = 0x00040000,
+ }, {
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00440000
+ },
+};
+
+static struct flash_platform_data lpd270_flash_data[2] = {
+ {
+ .name = "processor-flash",
+ .map_name = "cfi_probe",
+ .parts = lpd270_flash0_partitions,
+ .nr_parts = ARRAY_SIZE(lpd270_flash0_partitions),
+ }, {
+ .name = "mainboard-flash",
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ }
+};
+
+static struct platform_device lpd270_flash_device[2] = {
+ {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lpd270_flash_data[0],
+ },
+ .resource = &lpd270_flash_resources[0],
+ .num_resources = 1,
+ }, {
+ .name = "pxa2xx-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &lpd270_flash_data[1],
+ },
+ .resource = &lpd270_flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
+static struct platform_pwm_backlight_data lpd270_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1,
+ .dft_brightness = 1,
+ .pwm_period_ns = 78770,
+};
+
+static struct platform_device lpd270_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &lpd270_backlight_data,
+ },
+};
+
+/* 5.7" TFT QVGA (LoLo display number 1) */
+static struct pxafb_mode_info sharp_lq057q3dc02_mode = {
+ .pixclock = 150000,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .hsync_len = 0x14,
+ .left_margin = 0x28,
+ .right_margin = 0x0a,
+ .vsync_len = 0x02,
+ .upper_margin = 0x08,
+ .lower_margin = 0x14,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq057q3dc02 = {
+ .modes = &sharp_lq057q3dc02_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+/* 12.1" TFT SVGA (LoLo display number 2) */
+static struct pxafb_mode_info sharp_lq121s1dg31_mode = {
+ .pixclock = 50000,
+ .xres = 800,
+ .yres = 600,
+ .bpp = 16,
+ .hsync_len = 0x05,
+ .left_margin = 0x52,
+ .right_margin = 0x05,
+ .vsync_len = 0x04,
+ .upper_margin = 0x14,
+ .lower_margin = 0x0a,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq121s1dg31 = {
+ .modes = &sharp_lq121s1dg31_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+/* 3.6" TFT QVGA (LoLo display number 3) */
+static struct pxafb_mode_info sharp_lq036q1da01_mode = {
+ .pixclock = 150000,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .hsync_len = 0x0e,
+ .left_margin = 0x04,
+ .right_margin = 0x0a,
+ .vsync_len = 0x03,
+ .upper_margin = 0x03,
+ .lower_margin = 0x03,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq036q1da01 = {
+ .modes = &sharp_lq036q1da01_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+/* 6.4" TFT VGA (LoLo display number 5) */
+static struct pxafb_mode_info sharp_lq64d343_mode = {
+ .pixclock = 25000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 0x31,
+ .left_margin = 0x89,
+ .right_margin = 0x19,
+ .vsync_len = 0x12,
+ .upper_margin = 0x22,
+ .lower_margin = 0x00,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq64d343 = {
+ .modes = &sharp_lq64d343_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+/* 10.4" TFT VGA (LoLo display number 7) */
+static struct pxafb_mode_info sharp_lq10d368_mode = {
+ .pixclock = 25000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 0x31,
+ .left_margin = 0x89,
+ .right_margin = 0x19,
+ .vsync_len = 0x12,
+ .upper_margin = 0x22,
+ .lower_margin = 0x00,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq10d368 = {
+ .modes = &sharp_lq10d368_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+/* 3.5" TFT QVGA (LoLo display number 8) */
+static struct pxafb_mode_info sharp_lq035q7db02_20_mode = {
+ .pixclock = 150000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 0x0e,
+ .left_margin = 0x0a,
+ .right_margin = 0x0a,
+ .vsync_len = 0x03,
+ .upper_margin = 0x05,
+ .lower_margin = 0x14,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info sharp_lq035q7db02_20 = {
+ .modes = &sharp_lq035q7db02_20_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_ALTERNATE_MAPPING,
+};
+
+static struct pxafb_mach_info *lpd270_lcd_to_use;
+
+static int __init lpd270_set_lcd(char *str)
+{
+ if (!strnicmp(str, "lq057q3dc02", 11)) {
+ lpd270_lcd_to_use = &sharp_lq057q3dc02;
+ } else if (!strnicmp(str, "lq121s1dg31", 11)) {
+ lpd270_lcd_to_use = &sharp_lq121s1dg31;
+ } else if (!strnicmp(str, "lq036q1da01", 11)) {
+ lpd270_lcd_to_use = &sharp_lq036q1da01;
+ } else if (!strnicmp(str, "lq64d343", 8)) {
+ lpd270_lcd_to_use = &sharp_lq64d343;
+ } else if (!strnicmp(str, "lq10d368", 8)) {
+ lpd270_lcd_to_use = &sharp_lq10d368;
+ } else if (!strnicmp(str, "lq035q7db02-20", 14)) {
+ lpd270_lcd_to_use = &sharp_lq035q7db02_20;
+ } else {
+ printk(KERN_INFO "lpd270: unknown lcd panel [%s]\n", str);
+ }
+
+ return 1;
+}
+
+__setup("lcd=", lpd270_set_lcd);
+
+static struct platform_device *platform_devices[] __initdata = {
+ &smc91x_device,
+ &lpd270_backlight_device,
+ &lpd270_flash_device[0],
+ &lpd270_flash_device[1],
+};
+
+static struct pxaohci_platform_data lpd270_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static void __init lpd270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(lpd270_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ lpd270_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
+ lpd270_flash_data[1].width = 4;
+
+ /*
+ * System bus arbiter setting:
+ * - Core_Park
+ * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+ */
+ ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ pxa_set_ac97_info(NULL);
+
+ if (lpd270_lcd_to_use != NULL)
+ pxa_set_fb_info(NULL, lpd270_lcd_to_use);
+
+ pxa_set_ohci_info(&lpd270_ohci_platform_data);
+}
+
+
+static struct map_desc lpd270_io_desc[] __initdata = {
+ {
+ .virtual = LPD270_CPLD_VIRT,
+ .pfn = __phys_to_pfn(LPD270_CPLD_PHYS),
+ .length = LPD270_CPLD_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init lpd270_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(lpd270_io_desc, ARRAY_SIZE(lpd270_io_desc));
+
+ /* for use I SRAM as framebuffer. */
+ PSLR |= 0x00000F04;
+ PCFR = 0x00000066;
+}
+
+MACHINE_START(LOGICPD_PXA270, "LogicPD PXA270 Card Engine")
+ /* Maintainer: Peter Barada */
+ .boot_params = 0xa0000100,
+ .map_io = lpd270_map_io,
+ .nr_irqs = LPD270_NR_IRQS,
+ .init_irq = lpd270_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = lpd270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
new file mode 100644
index 00000000..e10ddb82
--- /dev/null
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -0,0 +1,558 @@
+/*
+ * linux/arch/arm/mach-pxa/lubbock.c
+ *
+ * Support for the Intel DBPXA250 Development Platform.
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/major.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/smc91x.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/pxa2xx_spi.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <asm/hardware/sa1111.h>
+
+#include <mach/pxa25x.h>
+#include <mach/gpio.h>
+#include <mach/audio.h>
+#include <mach/lubbock.h>
+#include <mach/udc.h>
+#include <mach/irda.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/pm.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "clock.h"
+#include "devices.h"
+
+static unsigned long lubbock_pin_config[] __initdata = {
+ GPIO15_nCS_1, /* CS1 - Flash */
+ GPIO78_nCS_2, /* CS2 - Baseboard FGPA */
+ GPIO79_nCS_3, /* CS3 - SMC ethernet */
+ GPIO80_nCS_4, /* CS4 - SA1111 */
+
+ /* SSP data pins */
+ GPIO23_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* LCD - 16bpp DSTN */
+ GPIOxx_LCD_DSTN_16BPP,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+
+ /* wakeup */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+#define LUB_HEXLED __LUB_REG(LUBBOCK_FPGA_PHYS + 0x010)
+#define LUB_MISC_WR __LUB_REG(LUBBOCK_FPGA_PHYS + 0x080)
+
+void lubbock_set_hexled(uint32_t value)
+{
+ LUB_HEXLED = value;
+}
+
+void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ LUB_MISC_WR = (LUB_MISC_WR & ~mask) | (set & mask);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(lubbock_set_misc_wr);
+
+static unsigned long lubbock_irq_enabled;
+
+static void lubbock_mask_irq(struct irq_data *d)
+{
+ int lubbock_irq = (d->irq - LUBBOCK_IRQ(0));
+ LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
+}
+
+static void lubbock_unmask_irq(struct irq_data *d)
+{
+ int lubbock_irq = (d->irq - LUBBOCK_IRQ(0));
+ /* the irq can be acknowledged only if deasserted, so it's done here */
+ LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
+ LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
+}
+
+static struct irq_chip lubbock_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = lubbock_mask_irq,
+ .irq_mask = lubbock_mask_irq,
+ .irq_unmask = lubbock_unmask_irq,
+};
+
+static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
+ do {
+ /* clear our parent irq */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ if (likely(pending)) {
+ irq = LUBBOCK_IRQ(0) + __ffs(pending);
+ generic_handle_irq(irq);
+ }
+ pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
+ } while (pending);
+}
+
+static void __init lubbock_init_irq(void)
+{
+ int irq;
+
+ pxa25x_init_irq();
+
+ /* setup extra lubbock irqs */
+ for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
+ irq_set_chip_and_handler(irq, &lubbock_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ irq_set_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+}
+
+#ifdef CONFIG_PM
+
+static void lubbock_irq_resume(void)
+{
+ LUB_IRQ_MASK_EN = lubbock_irq_enabled;
+}
+
+static struct syscore_ops lubbock_irq_syscore_ops = {
+ .resume = lubbock_irq_resume,
+};
+
+static int __init lubbock_irq_device_init(void)
+{
+ if (machine_is_lubbock()) {
+ register_syscore_ops(&lubbock_irq_syscore_ops);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+device_initcall(lubbock_irq_device_init);
+
+#endif
+
+static int lubbock_udc_is_connected(void)
+{
+ return (LUB_MISC_RD & (1 << 9)) == 0;
+}
+
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ .udc_is_connected = lubbock_udc_is_connected,
+ // no D+ pullup; lubbock can't connect/disconnect in software
+};
+
+static struct resource sa1111_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x10001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = LUBBOCK_SA1111_IRQ,
+ .end = LUBBOCK_SA1111_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = LUBBOCK_SA1111_IRQ_BASE,
+};
+
+static struct platform_device sa1111_device = {
+ .name = "sa1111",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa1111_resources),
+ .resource = sa1111_resources,
+ .dev = {
+ .platform_data = &sa1111_info,
+ },
+};
+
+/* ADS7846 is connected through SSP ... and if your board has J5 populated,
+ * you can select it to replace the ucb1400 by switching the touchscreen cable
+ * (to J5) and poking board registers (as done below). Else it's only useful
+ * for the temperature sensors.
+ */
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+ .num_chipselect = 1,
+};
+
+static int lubbock_ads7846_pendown_state(void)
+{
+ /* TS_BUSY is bit 8 in LUB_MISC_RD, but pendown is irq-only */
+ return 0;
+}
+
+static struct ads7846_platform_data ads_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100, /* internal, no cap */
+ .get_pendown_state = lubbock_ads7846_pendown_state,
+ // .x_plate_ohms = 500, /* GUESS! */
+ // .y_plate_ohms = 500, /* GUESS! */
+};
+
+static void ads7846_cs(u32 command)
+{
+ static const unsigned TS_nCS = 1 << 11;
+ lubbock_set_misc_wr(TS_nCS, (command == PXA2XX_CS_ASSERT) ? 0 : TS_nCS);
+}
+
+static struct pxa2xx_spi_chip ads_hw = {
+ .tx_threshold = 1,
+ .rx_threshold = 2,
+ .cs_control = ads7846_cs,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = { {
+ .modalias = "ads7846",
+ .platform_data = &ads_info,
+ .controller_data = &ads_hw,
+ .irq = LUBBOCK_BB_IRQ,
+ .max_speed_hz = 120000 /* max sample rate at 3V */
+ * 26 /* command + data + overhead */,
+ .bus_num = 1,
+ .chip_select = 0,
+},
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = 0x0c000c00,
+ .end = 0x0c0fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = LUBBOCK_ETH_IRQ,
+ .end = LUBBOCK_ETH_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+ [2] = {
+ .name = "smc91x-attrib",
+ .start = 0x0e000000,
+ .end = 0x0e0fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct smc91x_platdata lubbock_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_IO_SHIFT_2,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &lubbock_smc91x_info,
+ },
+};
+
+static struct resource flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x04000000,
+ .end = 0x04000000 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition lubbock_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x00100000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00140000
+ }
+};
+
+static struct flash_platform_data lubbock_flash_data[2] = {
+ {
+ .map_name = "cfi_probe",
+ .parts = lubbock_partitions,
+ .nr_parts = ARRAY_SIZE(lubbock_partitions),
+ }, {
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ }
+};
+
+static struct platform_device lubbock_flash_device[2] = {
+ {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lubbock_flash_data[0],
+ },
+ .resource = &flash_resources[0],
+ .num_resources = 1,
+ },
+ {
+ .name = "pxa2xx-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &lubbock_flash_data[1],
+ },
+ .resource = &flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+ &smc91x_device,
+ &lubbock_flash_device[0],
+ &lubbock_flash_device[1],
+};
+
+static struct pxafb_mode_info sharp_lm8v31_mode = {
+ .pixclock = 270000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 1,
+ .left_margin = 3,
+ .right_margin = 3,
+ .vsync_len = 1,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lm8v31 = {
+ .modes = &sharp_lm8v31_mode,
+ .num_modes = 1,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL |
+ LCD_AC_BIAS_FREQ(255),
+};
+
+#define MMC_POLL_RATE msecs_to_jiffies(1000)
+
+static void lubbock_mmc_poll(unsigned long);
+static irq_handler_t mmc_detect_int;
+
+static struct timer_list mmc_timer = {
+ .function = lubbock_mmc_poll,
+};
+
+static void lubbock_mmc_poll(unsigned long data)
+{
+ unsigned long flags;
+
+ /* clear any previous irq state, then ... */
+ local_irq_save(flags);
+ LUB_IRQ_SET_CLR &= ~(1 << 0);
+ local_irq_restore(flags);
+
+ /* poll until mmc/sd card is removed */
+ if (LUB_IRQ_SET_CLR & (1 << 0))
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+ else {
+ (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data);
+ enable_irq(LUBBOCK_SD_IRQ);
+ }
+}
+
+static irqreturn_t lubbock_detect_int(int irq, void *data)
+{
+ /* IRQ is level triggered; disable, and poll for removal */
+ disable_irq(irq);
+ mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE);
+
+ return mmc_detect_int(irq, data);
+}
+
+static int lubbock_mci_init(struct device *dev,
+ irq_handler_t detect_int,
+ void *data)
+{
+ /* detect card insert/eject */
+ mmc_detect_int = detect_int;
+ init_timer(&mmc_timer);
+ mmc_timer.data = (unsigned long) data;
+ return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
+ IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
+}
+
+static int lubbock_mci_get_ro(struct device *dev)
+{
+ return (LUB_MISC_RD & (1 << 2)) != 0;
+}
+
+static void lubbock_mci_exit(struct device *dev, void *data)
+{
+ free_irq(LUBBOCK_SD_IRQ, data);
+ del_timer_sync(&mmc_timer);
+}
+
+static struct pxamci_platform_data lubbock_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .detect_delay_ms = 10,
+ .init = lubbock_mci_init,
+ .get_ro = lubbock_mci_get_ro,
+ .exit = lubbock_mci_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void lubbock_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ LUB_MISC_WR &= ~(1 << 4);
+ } else if (mode & IR_FIRMODE) {
+ LUB_MISC_WR |= 1 << 4;
+ }
+ pxa2xx_transceiver_mode(dev, mode);
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data lubbock_ficp_platform_data = {
+ .gpio_pwdown = -1,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
+ .transceiver_mode = lubbock_irda_transceiver_mode,
+};
+
+static void __init lubbock_init(void)
+{
+ int flashboot = (LUB_CONF_SWITCHES & 1);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
+ pxa_set_udc_info(&udc_info);
+ pxa_set_fb_info(NULL, &sharp_lm8v31);
+ pxa_set_mci_info(&lubbock_mci_platform_data);
+ pxa_set_ficp_info(&lubbock_ficp_platform_data);
+ pxa_set_ac97_info(NULL);
+
+ lubbock_flash_data[0].width = lubbock_flash_data[1].width =
+ (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
+ /* Compensate for the nROMBT switch which swaps the flash banks */
+ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
+ flashboot?"Flash":"ROM", flashboot);
+
+ lubbock_flash_data[flashboot^1].name = "application-flash";
+ lubbock_flash_data[flashboot].name = "boot-rom";
+ (void) platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
+static struct map_desc lubbock_io_desc[] __initdata = {
+ { /* CPLD */
+ .virtual = LUBBOCK_FPGA_VIRT,
+ .pfn = __phys_to_pfn(LUBBOCK_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init lubbock_map_io(void)
+{
+ pxa25x_map_io();
+ iotable_init(lubbock_io_desc, ARRAY_SIZE(lubbock_io_desc));
+
+ PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
+ /* Maintainer: MontaVista Software Inc. */
+ .map_io = lubbock_map_io,
+ .nr_irqs = LUBBOCK_NR_IRQS,
+ .init_irq = lubbock_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = lubbock_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
new file mode 100644
index 00000000..e1920572
--- /dev/null
+++ b/arch/arm/mach-pxa/magician.c
@@ -0,0 +1,773 @@
+/*
+ * Support for HTC Magician PDA phones:
+ * i-mate JAM, O2 Xda mini, Orange SPV M500, Qtek s100, Qtek s110
+ * and T-Mobile MDA Compact.
+ *
+ * Copyright (c) 2006-2007 Philipp Zabel
+ *
+ * Based on hx4700.c, spitz.c and others.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mfd/htc-egpio.h>
+#include <linux/mfd/htc-pasic3.h>
+#include <linux/mtd/physmap.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/bq24022.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/magician.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+
+#include "devices.h"
+#include "generic.h"
+
+static unsigned long magician_pin_config[] __initdata = {
+
+ /* SDRAM and Static Memory I/O Signals */
+ GPIO20_nSDCS_2,
+ GPIO21_nSDCS_3,
+ GPIO15_nCS_1,
+ GPIO78_nCS_2, /* PASIC3 */
+ GPIO79_nCS_3, /* EGPIO CPLD */
+ GPIO80_nCS_4,
+ GPIO33_nCS_5,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* PWM 0 */
+ GPIO16_PWM0_OUT,
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO31_I2S_SYNC,
+ GPIO113_I2S_SYSCLK,
+
+ /* SSP 1 */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+
+ /* SSP 2 */
+ GPIO19_SSP2_SCLK,
+ GPIO14_SSP2_SFRM,
+ GPIO89_SSP2_TXD,
+ GPIO88_SSP2_RXD,
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* QCI */
+ GPIO12_CIF_DD_7,
+ GPIO17_CIF_DD_6,
+ GPIO50_CIF_DD_3,
+ GPIO51_CIF_DD_2,
+ GPIO52_CIF_DD_4,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO55_CIF_DD_1,
+ GPIO81_CIF_DD_0,
+ GPIO82_CIF_DD_5,
+ GPIO84_CIF_FV,
+ GPIO85_CIF_LV,
+
+ /* Magician specific input GPIOs */
+ GPIO9_GPIO, /* unknown */
+ GPIO10_GPIO, /* GSM_IRQ */
+ GPIO13_GPIO, /* CPLD_IRQ */
+ GPIO107_GPIO, /* DS1WM_IRQ */
+ GPIO108_GPIO, /* GSM_READY */
+ GPIO115_GPIO, /* nPEN_IRQ */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+
+/*
+ * IRDA
+ */
+
+static struct pxaficp_platform_data magician_ficp_info = {
+ .gpio_pwdown = GPIO83_MAGICIAN_nIR_EN,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+/*
+ * GPIO Keys
+ */
+
+#define INIT_KEY(_code, _gpio, _desc) \
+ { \
+ .code = KEY_##_code, \
+ .gpio = _gpio, \
+ .desc = _desc, \
+ .type = EV_KEY, \
+ .wakeup = 1, \
+ }
+
+static struct gpio_keys_button magician_button_table[] = {
+ INIT_KEY(POWER, GPIO0_MAGICIAN_KEY_POWER, "Power button"),
+ INIT_KEY(ESC, GPIO37_MAGICIAN_KEY_HANGUP, "Hangup button"),
+ INIT_KEY(F10, GPIO38_MAGICIAN_KEY_CONTACTS, "Contacts button"),
+ INIT_KEY(CALENDAR, GPIO90_MAGICIAN_KEY_CALENDAR, "Calendar button"),
+ INIT_KEY(CAMERA, GPIO91_MAGICIAN_KEY_CAMERA, "Camera button"),
+ INIT_KEY(UP, GPIO93_MAGICIAN_KEY_UP, "Up button"),
+ INIT_KEY(DOWN, GPIO94_MAGICIAN_KEY_DOWN, "Down button"),
+ INIT_KEY(LEFT, GPIO95_MAGICIAN_KEY_LEFT, "Left button"),
+ INIT_KEY(RIGHT, GPIO96_MAGICIAN_KEY_RIGHT, "Right button"),
+ INIT_KEY(KPENTER, GPIO97_MAGICIAN_KEY_ENTER, "Action button"),
+ INIT_KEY(RECORD, GPIO98_MAGICIAN_KEY_RECORD, "Record button"),
+ INIT_KEY(VOLUMEUP, GPIO100_MAGICIAN_KEY_VOL_UP, "Volume up"),
+ INIT_KEY(VOLUMEDOWN, GPIO101_MAGICIAN_KEY_VOL_DOWN, "Volume down"),
+ INIT_KEY(PHONE, GPIO102_MAGICIAN_KEY_PHONE, "Phone button"),
+ INIT_KEY(PLAY, GPIO99_MAGICIAN_HEADPHONE_IN, "Headset button"),
+};
+
+static struct gpio_keys_platform_data gpio_keys_data = {
+ .buttons = magician_button_table,
+ .nbuttons = ARRAY_SIZE(magician_button_table),
+};
+
+static struct platform_device gpio_keys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &gpio_keys_data,
+ },
+ .id = -1,
+};
+
+
+/*
+ * EGPIO (Xilinx CPLD)
+ *
+ * 7 32-bit aligned 8-bit registers: 3x output, 1x irq, 3x input
+ */
+
+static struct resource egpio_resources[] = {
+ [0] = {
+ .start = PXA_CS3_PHYS,
+ .end = PXA_CS3_PHYS + 0x20 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
+ .end = gpio_to_irq(GPIO13_MAGICIAN_CPLD_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct htc_egpio_chip egpio_chips[] = {
+ [0] = {
+ .reg_start = 0,
+ .gpio_base = MAGICIAN_EGPIO(0, 0),
+ .num_gpios = 24,
+ .direction = HTC_EGPIO_OUTPUT,
+ .initial_values = 0x40, /* EGPIO_MAGICIAN_GSM_RESET */
+ },
+ [1] = {
+ .reg_start = 4,
+ .gpio_base = MAGICIAN_EGPIO(4, 0),
+ .num_gpios = 24,
+ .direction = HTC_EGPIO_INPUT,
+ },
+};
+
+static struct htc_egpio_platform_data egpio_info = {
+ .reg_width = 8,
+ .bus_width = 32,
+ .irq_base = IRQ_BOARD_START,
+ .num_irqs = 4,
+ .ack_register = 3,
+ .chip = egpio_chips,
+ .num_chips = ARRAY_SIZE(egpio_chips),
+};
+
+static struct platform_device egpio = {
+ .name = "htc-egpio",
+ .id = -1,
+ .resource = egpio_resources,
+ .num_resources = ARRAY_SIZE(egpio_resources),
+ .dev = {
+ .platform_data = &egpio_info,
+ },
+};
+
+/*
+ * LCD - Toppoly TD028STEB1 or Samsung LTP280QV
+ */
+
+static struct pxafb_mode_info toppoly_modes[] = {
+ {
+ .pixclock = 96153,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+ .hsync_len = 11,
+ .vsync_len = 3,
+ .left_margin = 19,
+ .upper_margin = 2,
+ .right_margin = 10,
+ .lower_margin = 2,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mode_info samsung_modes[] = {
+ {
+ .pixclock = 96153,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+ .hsync_len = 8,
+ .vsync_len = 4,
+ .left_margin = 9,
+ .upper_margin = 4,
+ .right_margin = 9,
+ .lower_margin = 4,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
+static void toppoly_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+ pr_debug("Toppoly LCD power\n");
+
+ if (on) {
+ pr_debug("on\n");
+ gpio_set_value(EGPIO_MAGICIAN_TOPPOLY_POWER, 1);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+ udelay(2000);
+ gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
+ udelay(2000);
+ /* FIXME: enable LCDC here */
+ udelay(2000);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+ udelay(2000);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+ } else {
+ pr_debug("off\n");
+ msleep(15);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+ udelay(500);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+ udelay(1000);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+ gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
+ }
+}
+
+static void samsung_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+ pr_debug("Samsung LCD power\n");
+
+ if (on) {
+ pr_debug("on\n");
+ if (system_rev < 3)
+ gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 1);
+ else
+ gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 1);
+ mdelay(10);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 1);
+ mdelay(10);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 1);
+ mdelay(30);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 1);
+ mdelay(10);
+ } else {
+ pr_debug("off\n");
+ mdelay(10);
+ gpio_set_value(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+ mdelay(30);
+ gpio_set_value(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+ mdelay(10);
+ gpio_set_value(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+ mdelay(10);
+ if (system_rev < 3)
+ gpio_set_value(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
+ else
+ gpio_set_value(EGPIO_MAGICIAN_LCD_POWER, 0);
+ }
+}
+
+static struct pxafb_mach_info toppoly_info = {
+ .modes = toppoly_modes,
+ .num_modes = 1,
+ .fixed_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+ .pxafb_lcd_power = toppoly_lcd_power,
+};
+
+static struct pxafb_mach_info samsung_info = {
+ .modes = samsung_modes,
+ .num_modes = 1,
+ .fixed_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL |\
+ LCD_ALTERNATE_MAPPING,
+ .pxafb_lcd_power = samsung_lcd_power,
+};
+
+/*
+ * Backlight
+ */
+
+static int magician_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER");
+ if (ret)
+ goto err;
+ ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2");
+ if (ret)
+ goto err2;
+ return 0;
+
+err2:
+ gpio_free(EGPIO_MAGICIAN_BL_POWER);
+err:
+ return ret;
+}
+
+static int magician_backlight_notify(struct device *dev, int brightness)
+{
+ gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness);
+ if (brightness >= 200) {
+ gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1);
+ return brightness - 72;
+ } else {
+ gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0);
+ return brightness;
+ }
+}
+
+static void magician_backlight_exit(struct device *dev)
+{
+ gpio_free(EGPIO_MAGICIAN_BL_POWER);
+ gpio_free(EGPIO_MAGICIAN_BL_POWER2);
+}
+
+static struct platform_pwm_backlight_data backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 272,
+ .dft_brightness = 100,
+ .pwm_period_ns = 30923,
+ .init = magician_backlight_init,
+ .notify = magician_backlight_notify,
+ .exit = magician_backlight_exit,
+};
+
+static struct platform_device backlight = {
+ .name = "pwm-backlight",
+ .id = -1,
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &backlight_data,
+ },
+};
+
+/*
+ * LEDs
+ */
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "magician::vibra",
+ .default_trigger = "none",
+ .gpio = GPIO22_MAGICIAN_VIBRA_EN,
+ },
+ {
+ .name = "magician::phone_bl",
+ .default_trigger = "backlight",
+ .gpio = GPIO103_MAGICIAN_LED_KP,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct pasic3_led pasic3_leds[] = {
+ {
+ .led = {
+ .name = "magician:red",
+ .default_trigger = "ds2760-battery.0-charging",
+ },
+ .hw_num = 0,
+ .bit2 = PASIC3_BIT2_LED0,
+ .mask = PASIC3_MASK_LED0,
+ },
+ {
+ .led = {
+ .name = "magician:green",
+ .default_trigger = "ds2760-battery.0-charging-or-full",
+ },
+ .hw_num = 1,
+ .bit2 = PASIC3_BIT2_LED1,
+ .mask = PASIC3_MASK_LED1,
+ },
+ {
+ .led = {
+ .name = "magician:blue",
+ .default_trigger = "bluetooth",
+ },
+ .hw_num = 2,
+ .bit2 = PASIC3_BIT2_LED2,
+ .mask = PASIC3_MASK_LED2,
+ },
+};
+
+static struct pasic3_leds_machinfo pasic3_leds_info = {
+ .num_leds = ARRAY_SIZE(pasic3_leds),
+ .power_gpio = EGPIO_MAGICIAN_LED_POWER,
+ .leds = pasic3_leds,
+};
+
+/*
+ * PASIC3 with DS1WM
+ */
+
+static struct resource pasic3_resources[] = {
+ [0] = {
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 0x1b,
+ .flags = IORESOURCE_MEM,
+ },
+ /* No IRQ handler in the PASIC3, DS1WM needs an external IRQ */
+ [1] = {
+ .start = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
+ .end = gpio_to_irq(GPIO107_MAGICIAN_DS1WM_IRQ),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct pasic3_platform_data pasic3_platform_data = {
+ .led_pdata = &pasic3_leds_info,
+ .clock_rate = 4000000,
+};
+
+static struct platform_device pasic3 = {
+ .name = "pasic3",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pasic3_resources),
+ .resource = pasic3_resources,
+ .dev = {
+ .platform_data = &pasic3_platform_data,
+ },
+};
+
+/*
+ * USB "Transceiver"
+ */
+
+static struct resource gpio_vbus_resource = {
+ .flags = IORESOURCE_IRQ,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
+};
+
+static struct gpio_vbus_mach_info gpio_vbus_info = {
+ .gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
+ .gpio_vbus = EGPIO_MAGICIAN_CABLE_STATE_USB,
+};
+
+static struct platform_device gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .num_resources = 1,
+ .resource = &gpio_vbus_resource,
+ .dev = {
+ .platform_data = &gpio_vbus_info,
+ },
+};
+
+/*
+ * External power
+ */
+
+static int power_supply_init(struct device *dev)
+{
+ return gpio_request(EGPIO_MAGICIAN_CABLE_STATE_AC, "CABLE_STATE_AC");
+}
+
+static int magician_is_ac_online(void)
+{
+ return gpio_get_value(EGPIO_MAGICIAN_CABLE_STATE_AC);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(EGPIO_MAGICIAN_CABLE_STATE_AC);
+}
+
+static char *magician_supplicants[] = {
+ "ds2760-battery.0", "backup-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = magician_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = magician_supplicants,
+ .num_supplicants = ARRAY_SIZE(magician_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+ [0] = {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
+ },
+ [1] = {
+ .name = "usb",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ .start = IRQ_MAGICIAN_VBUS,
+ .end = IRQ_MAGICIAN_VBUS,
+ },
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+/*
+ * Battery charger
+ */
+
+static struct regulator_consumer_supply bq24022_consumers[] = {
+ {
+ .dev = &gpio_vbus.dev,
+ .supply = "vbus_draw",
+ },
+ {
+ .dev = &power_supply.dev,
+ .supply = "ac_draw",
+ },
+};
+
+static struct regulator_init_data bq24022_init_data = {
+ .constraints = {
+ .max_uA = 500000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers),
+ .consumer_supplies = bq24022_consumers,
+};
+
+static struct bq24022_mach_info bq24022_info = {
+ .gpio_nce = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+ .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
+ .init_data = &bq24022_init_data,
+};
+
+static struct platform_device bq24022 = {
+ .name = "bq24022",
+ .id = -1,
+ .dev = {
+ .platform_data = &bq24022_info,
+ },
+};
+
+/*
+ * MMC/SD
+ */
+
+static int magician_mci_init(struct device *dev,
+ irq_handler_t detect_irq, void *data)
+{
+ return request_irq(IRQ_MAGICIAN_SD, detect_irq,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+ "mmc card detect", data);
+}
+
+static void magician_mci_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_MAGICIAN_SD, data);
+}
+
+static struct pxamci_platform_data magician_mci_info = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = magician_mci_init,
+ .exit = magician_mci_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = EGPIO_MAGICIAN_nSD_READONLY,
+ .gpio_card_ro_invert = 1,
+ .gpio_power = EGPIO_MAGICIAN_SD_POWER,
+};
+
+
+/*
+ * USB OHCI
+ */
+
+static struct pxaohci_platform_data magician_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT3 | POWER_CONTROL_LOW,
+ .power_budget = 0,
+};
+
+
+/*
+ * StrataFlash
+ */
+
+static void magician_set_vpp(struct platform_device *pdev, int vpp)
+{
+ gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
+}
+
+static struct resource strataflash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data strataflash_data = {
+ .width = 4,
+ .set_vpp = magician_set_vpp,
+};
+
+static struct platform_device strataflash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &strataflash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &strataflash_data,
+ },
+};
+
+/*
+ * I2C
+ */
+
+static struct i2c_pxa_platform_data i2c_info = {
+ .fast_mode = 1,
+};
+
+/*
+ * Platform devices
+ */
+
+static struct platform_device *devices[] __initdata = {
+ &gpio_keys,
+ &egpio,
+ &backlight,
+ &pasic3,
+ &bq24022,
+ &gpio_vbus,
+ &power_supply,
+ &strataflash,
+ &leds_gpio,
+};
+
+static void __init magician_init(void)
+{
+ void __iomem *cpld;
+ int lcd_select;
+ int err;
+
+ gpio_request(GPIO13_MAGICIAN_CPLD_IRQ, "CPLD_IRQ");
+ gpio_request(GPIO107_MAGICIAN_DS1WM_IRQ, "DS1WM_IRQ");
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(magician_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_add_devices(ARRAY_AND_SIZE(devices));
+
+ err = gpio_request(GPIO83_MAGICIAN_nIR_EN, "nIR_EN");
+ if (!err) {
+ gpio_direction_output(GPIO83_MAGICIAN_nIR_EN, 1);
+ pxa_set_ficp_info(&magician_ficp_info);
+ }
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_i2c_info(&i2c_info);
+ pxa_set_mci_info(&magician_mci_info);
+ pxa_set_ohci_info(&magician_ohci_info);
+
+ /* Check LCD type we have */
+ cpld = ioremap_nocache(PXA_CS3_PHYS, 0x1000);
+ if (cpld) {
+ u8 board_id = __raw_readb(cpld+0x14);
+ iounmap(cpld);
+ system_rev = board_id & 0x7;
+ lcd_select = board_id & 0x8;
+ pr_info("LCD type: %s\n", lcd_select ? "Samsung" : "Toppoly");
+ if (lcd_select && (system_rev < 3)) {
+ gpio_request(GPIO75_MAGICIAN_SAMSUNG_POWER, "SAMSUNG_POWER");
+ gpio_direction_output(GPIO75_MAGICIAN_SAMSUNG_POWER, 0);
+ }
+ gpio_request(GPIO104_MAGICIAN_LCD_POWER_1, "LCD_POWER_1");
+ gpio_request(GPIO105_MAGICIAN_LCD_POWER_2, "LCD_POWER_2");
+ gpio_request(GPIO106_MAGICIAN_LCD_POWER_3, "LCD_POWER_3");
+ gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
+ gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
+ gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
+ pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
+ } else
+ pr_err("LCD detection: CPLD mapping failed\n");
+}
+
+
+MACHINE_START(MAGICIAN, "HTC Magician")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .nr_irqs = MAGICIAN_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = magician_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
new file mode 100644
index 00000000..3479e2b3
--- /dev/null
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -0,0 +1,625 @@
+/*
+ * linux/arch/arm/mach-pxa/mainstone.c
+ *
+ * Support for the Intel HCDDBBVA0 Development Platform.
+ * (go figure how they came up with such name...)
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 05, 2002
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/pwm_backlight.h>
+#include <linux/smc91x.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/gpio.h>
+#include <mach/mainstone.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long mainstone_pin_config[] = {
+ /* Chip Select */
+ GPIO15_nCS_1,
+
+ /* LCD - 16bpp Active TFT */
+ GPIOxx_LCD_TFT_16BPP,
+ GPIO16_PWM0_OUT, /* Backlight */
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+
+ /* USB Host Port 1 */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO45_AC97_SYSCLK,
+
+ /* Keypad */
+ GPIO93_KP_DKIN_0,
+ GPIO94_KP_DKIN_1,
+ GPIO95_KP_DKIN_2,
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO98_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+ GPIO96_KP_MKOUT_6,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* GPIO */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
+};
+
+static unsigned long mainstone_irq_enabled;
+
+static void mainstone_mask_irq(struct irq_data *d)
+{
+ int mainstone_irq = (d->irq - MAINSTONE_IRQ(0));
+ MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
+}
+
+static void mainstone_unmask_irq(struct irq_data *d)
+{
+ int mainstone_irq = (d->irq - MAINSTONE_IRQ(0));
+ /* the irq can be acknowledged only if deasserted, so it's done here */
+ MST_INTSETCLR &= ~(1 << mainstone_irq);
+ MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq));
+}
+
+static struct irq_chip mainstone_irq_chip = {
+ .name = "FPGA",
+ .irq_ack = mainstone_mask_irq,
+ .irq_mask = mainstone_mask_irq,
+ .irq_unmask = mainstone_unmask_irq,
+};
+
+static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
+ do {
+ /* clear useless edge notification */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ if (likely(pending)) {
+ irq = MAINSTONE_IRQ(0) + __ffs(pending);
+ generic_handle_irq(irq);
+ }
+ pending = MST_INTSETCLR & mainstone_irq_enabled;
+ } while (pending);
+}
+
+static void __init mainstone_init_irq(void)
+{
+ int irq;
+
+ pxa27x_init_irq();
+
+ /* setup extra Mainstone irqs */
+ for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
+ irq_set_chip_and_handler(irq, &mainstone_irq_chip,
+ handle_level_irq);
+ if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
+ else
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ set_irq_flags(MAINSTONE_IRQ(8), 0);
+ set_irq_flags(MAINSTONE_IRQ(12), 0);
+
+ MST_INTMSKENA = 0;
+ MST_INTSETCLR = 0;
+
+ irq_set_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+}
+
+#ifdef CONFIG_PM
+
+static void mainstone_irq_resume(void)
+{
+ MST_INTMSKENA = mainstone_irq_enabled;
+}
+
+static struct syscore_ops mainstone_irq_syscore_ops = {
+ .resume = mainstone_irq_resume,
+};
+
+static int __init mainstone_irq_device_init(void)
+{
+ if (machine_is_mainstone())
+ register_syscore_ops(&mainstone_irq_syscore_ops);
+
+ return 0;
+}
+
+device_initcall(mainstone_irq_device_init);
+
+#endif
+
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = (MST_ETH_PHYS + 0x300),
+ .end = (MST_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MAINSTONE_IRQ(3),
+ .end = MAINSTONE_IRQ(3),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata mainstone_smc91x_info = {
+ .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT |
+ SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &mainstone_smc91x_info,
+ },
+};
+
+static int mst_audio_startup(struct snd_pcm_substream *substream, void *priv)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ MST_MSCWR2 &= ~MST_MSCWR2_AC97_SPKROFF;
+ return 0;
+}
+
+static void mst_audio_shutdown(struct snd_pcm_substream *substream, void *priv)
+{
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static long mst_audio_suspend_mask;
+
+static void mst_audio_suspend(void *priv)
+{
+ mst_audio_suspend_mask = MST_MSCWR2;
+ MST_MSCWR2 |= MST_MSCWR2_AC97_SPKROFF;
+}
+
+static void mst_audio_resume(void *priv)
+{
+ MST_MSCWR2 &= mst_audio_suspend_mask | ~MST_MSCWR2_AC97_SPKROFF;
+}
+
+static pxa2xx_audio_ops_t mst_audio_ops = {
+ .startup = mst_audio_startup,
+ .shutdown = mst_audio_shutdown,
+ .suspend = mst_audio_suspend,
+ .resume = mst_audio_resume,
+};
+
+static struct resource flash_resources[] = {
+ [0] = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition mainstoneflash0_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },{
+ .name = "Kernel",
+ .size = 0x00400000,
+ .offset = 0x00040000,
+ },{
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00440000
+ }
+};
+
+static struct flash_platform_data mst_flash_data[2] = {
+ {
+ .map_name = "cfi_probe",
+ .parts = mainstoneflash0_partitions,
+ .nr_parts = ARRAY_SIZE(mainstoneflash0_partitions),
+ }, {
+ .map_name = "cfi_probe",
+ .parts = NULL,
+ .nr_parts = 0,
+ }
+};
+
+static struct platform_device mst_flash_device[2] = {
+ {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mst_flash_data[0],
+ },
+ .resource = &flash_resources[0],
+ .num_resources = 1,
+ },
+ {
+ .name = "pxa2xx-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &mst_flash_data[1],
+ },
+ .resource = &flash_resources[1],
+ .num_resources = 1,
+ },
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct platform_pwm_backlight_data mainstone_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1023,
+ .dft_brightness = 1023,
+ .pwm_period_ns = 78770,
+};
+
+static struct platform_device mainstone_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &mainstone_backlight_data,
+ },
+};
+
+static void __init mainstone_backlight_register(void)
+{
+ int ret = platform_device_register(&mainstone_backlight_device);
+ if (ret)
+ printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret);
+}
+#else
+#define mainstone_backlight_register() do { } while (0)
+#endif
+
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
+ .pixclock = 50000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 1,
+ .left_margin = 0x9f,
+ .right_margin = 1,
+ .vsync_len = 44,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
+ .pixclock = 110000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 8,
+ .right_margin = 20,
+ .vsync_len = 3,
+ .upper_margin = 1,
+ .lower_margin = 10,
+ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info mainstone_pxafb_info = {
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static int mainstone_mci_init(struct device *dev, irq_handler_t mstone_detect_int, void *data)
+{
+ int err;
+
+ /* make sure SD/Memory Stick multiplexer's signals
+ * are routed to MMC controller
+ */
+ MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+
+ err = request_irq(MAINSTONE_MMC_IRQ, mstone_detect_int, IRQF_DISABLED,
+ "MMC card detect", data);
+ if (err)
+ printk(KERN_ERR "mainstone_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+
+ return err;
+}
+
+static void mainstone_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if (( 1 << vdd) & p_d->ocr_mask) {
+ printk(KERN_DEBUG "%s: on\n", __func__);
+ MST_MSCWR1 |= MST_MSCWR1_MMC_ON;
+ MST_MSCWR1 &= ~MST_MSCWR1_MS_SEL;
+ } else {
+ printk(KERN_DEBUG "%s: off\n", __func__);
+ MST_MSCWR1 &= ~MST_MSCWR1_MMC_ON;
+ }
+}
+
+static void mainstone_mci_exit(struct device *dev, void *data)
+{
+ free_irq(MAINSTONE_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data mainstone_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = mainstone_mci_init,
+ .setpower = mainstone_mci_setpower,
+ .exit = mainstone_mci_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static void mainstone_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (mode & IR_SIRMODE) {
+ MST_MSCWR1 &= ~MST_MSCWR1_IRDA_FIR;
+ } else if (mode & IR_FIRMODE) {
+ MST_MSCWR1 |= MST_MSCWR1_IRDA_FIR;
+ }
+ pxa2xx_transceiver_mode(dev, mode);
+ if (mode & IR_OFF) {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_OFF;
+ } else {
+ MST_MSCWR1 = (MST_MSCWR1 & ~MST_MSCWR1_IRDA_MASK) | MST_MSCWR1_IRDA_FULL;
+ }
+ local_irq_restore(flags);
+}
+
+static struct pxaficp_platform_data mainstone_ficp_platform_data = {
+ .gpio_pwdown = -1,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = mainstone_irda_transceiver_mode,
+};
+
+static struct gpio_keys_button gpio_keys_button[] = {
+ [0] = {
+ .desc = "wakeup",
+ .code = KEY_SUSPEND,
+ .type = EV_KEY,
+ .gpio = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mainstone_gpio_keys = {
+ .buttons = gpio_keys_button,
+ .nbuttons = 1,
+};
+
+static struct platform_device mst_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &mainstone_gpio_keys,
+ },
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &smc91x_device,
+ &mst_flash_device[0],
+ &mst_flash_device[1],
+ &mst_gpio_keys_device,
+};
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int mainstone_matrix_keys[] = {
+ KEY(0, 0, KEY_A), KEY(1, 0, KEY_B), KEY(2, 0, KEY_C),
+ KEY(3, 0, KEY_D), KEY(4, 0, KEY_E), KEY(5, 0, KEY_F),
+ KEY(0, 1, KEY_G), KEY(1, 1, KEY_H), KEY(2, 1, KEY_I),
+ KEY(3, 1, KEY_J), KEY(4, 1, KEY_K), KEY(5, 1, KEY_L),
+ KEY(0, 2, KEY_M), KEY(1, 2, KEY_N), KEY(2, 2, KEY_O),
+ KEY(3, 2, KEY_P), KEY(4, 2, KEY_Q), KEY(5, 2, KEY_R),
+ KEY(0, 3, KEY_S), KEY(1, 3, KEY_T), KEY(2, 3, KEY_U),
+ KEY(3, 3, KEY_V), KEY(4, 3, KEY_W), KEY(5, 3, KEY_X),
+ KEY(2, 4, KEY_Y), KEY(3, 4, KEY_Z),
+
+ KEY(0, 4, KEY_DOT), /* . */
+ KEY(1, 4, KEY_CLOSE), /* @ */
+ KEY(4, 4, KEY_SLASH),
+ KEY(5, 4, KEY_BACKSLASH),
+ KEY(0, 5, KEY_HOME),
+ KEY(1, 5, KEY_LEFTSHIFT),
+ KEY(2, 5, KEY_SPACE),
+ KEY(3, 5, KEY_SPACE),
+ KEY(4, 5, KEY_ENTER),
+ KEY(5, 5, KEY_BACKSPACE),
+
+ KEY(0, 6, KEY_UP),
+ KEY(1, 6, KEY_DOWN),
+ KEY(2, 6, KEY_LEFT),
+ KEY(3, 6, KEY_RIGHT),
+ KEY(4, 6, KEY_SELECT),
+};
+
+struct pxa27x_keypad_platform_data mainstone_keypad_info = {
+ .matrix_key_rows = 6,
+ .matrix_key_cols = 7,
+ .matrix_key_map = mainstone_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(mainstone_matrix_keys),
+
+ .enable_rotary0 = 1,
+ .rotary0_up_key = KEY_UP,
+ .rotary0_down_key = KEY_DOWN,
+
+ .debounce_interval = 30,
+};
+
+static void __init mainstone_init_keypad(void)
+{
+ pxa_set_keypad_info(&mainstone_keypad_info);
+}
+#else
+static inline void mainstone_init_keypad(void) {}
+#endif
+
+static void __init mainstone_init(void)
+{
+ int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(mainstone_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ mst_flash_data[0].width = (__raw_readl(BOOT_DEF) & 1) ? 2 : 4;
+ mst_flash_data[1].width = 4;
+
+ /* Compensate for SW7 which swaps the flash banks */
+ mst_flash_data[SW7].name = "processor-flash";
+ mst_flash_data[SW7 ^ 1].name = "mainboard-flash";
+
+ printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
+ mst_flash_data[0].name);
+
+ /* system bus arbiter setting
+ * - Core_Park
+ * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+ */
+ ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ /* reading Mainstone's "Virtual Configuration Register"
+ might be handy to select LCD type here */
+ if (0)
+ mainstone_pxafb_info.modes = &toshiba_ltm04c380k_mode;
+ else
+ mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
+
+ pxa_set_fb_info(NULL, &mainstone_pxafb_info);
+ mainstone_backlight_register();
+
+ pxa_set_mci_info(&mainstone_mci_platform_data);
+ pxa_set_ficp_info(&mainstone_ficp_platform_data);
+ pxa_set_ohci_info(&mainstone_ohci_platform_data);
+ pxa_set_i2c_info(NULL);
+ pxa_set_ac97_info(&mst_audio_ops);
+
+ mainstone_init_keypad();
+}
+
+
+static struct map_desc mainstone_io_desc[] __initdata = {
+ { /* CPLD */
+ .virtual = MST_FPGA_VIRT,
+ .pfn = __phys_to_pfn(MST_FPGA_PHYS),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init mainstone_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(mainstone_io_desc, ARRAY_SIZE(mainstone_io_desc));
+
+ /* for use I SRAM as framebuffer. */
+ PSLR |= 0xF04;
+ PCFR = 0x66;
+}
+
+MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
+ /* Maintainer: MontaVista Software Inc. */
+ .boot_params = 0xa0000100, /* BLOB boot parameter setting */
+ .map_io = mainstone_map_io,
+ .nr_irqs = MAINSTONE_NR_IRQS,
+ .init_irq = mainstone_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = mainstone_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
new file mode 100644
index 00000000..b27544bc
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -0,0 +1,412 @@
+/*
+ * linux/arch/arm/mach-pxa/mfp-pxa2xx.c
+ *
+ * PXA2xx pin mux configuration support
+ *
+ * The GPIOs on PXA2xx can be configured as one of many alternate
+ * functions, this is by concept samilar to the MFP configuration
+ * on PXA3xx, what's more important, the low power pin state and
+ * wakeup detection are also supported by the same framework.
+ *
+ * This program is free software; you can 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/syscore_ops.h>
+
+#include <mach/gpio.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa2xx.h>
+
+#include "generic.h"
+
+#define PGSR(x) __REG2(0x40F00020, (x) << 2)
+#define __GAFR(u, x) __REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
+#define GAFR_L(x) __GAFR(0, x)
+#define GAFR_U(x) __GAFR(1, x)
+
+#define PWER_WE35 (1 << 24)
+
+struct gpio_desc {
+ unsigned valid : 1;
+ unsigned can_wakeup : 1;
+ unsigned keypad_gpio : 1;
+ unsigned dir_inverted : 1;
+ unsigned int mask; /* bit mask in PWER or PKWR */
+ unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */
+ unsigned long config;
+};
+
+static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
+
+static unsigned long gpdr_lpm[4];
+
+static int __mfp_config_gpio(unsigned gpio, unsigned long c)
+{
+ unsigned long gafr, mask = GPIO_bit(gpio);
+ int bank = gpio_to_bank(gpio);
+ int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
+ int shft = (gpio & 0xf) << 1;
+ int fn = MFP_AF(c);
+ int is_out = (c & MFP_DIR_OUT) ? 1 : 0;
+
+ if (fn > 3)
+ return -EINVAL;
+
+ /* alternate function and direction at run-time */
+ gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
+ gafr = (gafr & ~(0x3 << shft)) | (fn << shft);
+
+ if (uorl == 0)
+ GAFR_L(bank) = gafr;
+ else
+ GAFR_U(bank) = gafr;
+
+ if (is_out ^ gpio_desc[gpio].dir_inverted)
+ GPDR(gpio) |= mask;
+ else
+ GPDR(gpio) &= ~mask;
+
+ /* alternate function and direction at low power mode */
+ switch (c & MFP_LPM_STATE_MASK) {
+ case MFP_LPM_DRIVE_HIGH:
+ PGSR(bank) |= mask;
+ is_out = 1;
+ break;
+ case MFP_LPM_DRIVE_LOW:
+ PGSR(bank) &= ~mask;
+ is_out = 1;
+ break;
+ case MFP_LPM_INPUT:
+ case MFP_LPM_DEFAULT:
+ break;
+ default:
+ /* warning and fall through, treat as MFP_LPM_DEFAULT */
+ pr_warning("%s: GPIO%d: unsupported low power mode\n",
+ __func__, gpio);
+ break;
+ }
+
+ if (is_out ^ gpio_desc[gpio].dir_inverted)
+ gpdr_lpm[bank] |= mask;
+ else
+ gpdr_lpm[bank] &= ~mask;
+
+ /* give early warning if MFP_LPM_CAN_WAKEUP is set on the
+ * configurations of those pins not able to wakeup
+ */
+ if ((c & MFP_LPM_CAN_WAKEUP) && !gpio_desc[gpio].can_wakeup) {
+ pr_warning("%s: GPIO%d unable to wakeup\n",
+ __func__, gpio);
+ return -EINVAL;
+ }
+
+ if ((c & MFP_LPM_CAN_WAKEUP) && is_out) {
+ pr_warning("%s: output GPIO%d unable to wakeup\n",
+ __func__, gpio);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int __mfp_validate(int mfp)
+{
+ int gpio = mfp_to_gpio(mfp);
+
+ if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
+ pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+ return -1;
+ }
+
+ return gpio;
+}
+
+void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+ unsigned long flags;
+ unsigned long *c;
+ int i, gpio;
+
+ for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
+
+ gpio = __mfp_validate(MFP_PIN(*c));
+ if (gpio < 0)
+ continue;
+
+ local_irq_save(flags);
+
+ gpio_desc[gpio].config = *c;
+ __mfp_config_gpio(gpio, *c);
+
+ local_irq_restore(flags);
+ }
+}
+
+void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
+{
+ unsigned long flags, c;
+ int gpio;
+
+ gpio = __mfp_validate(mfp);
+ if (gpio < 0)
+ return;
+
+ local_irq_save(flags);
+
+ c = gpio_desc[gpio].config;
+ c = (c & ~MFP_LPM_STATE_MASK) | lpm;
+ __mfp_config_gpio(gpio, c);
+
+ local_irq_restore(flags);
+}
+
+int gpio_set_wake(unsigned int gpio, unsigned int on)
+{
+ struct gpio_desc *d;
+ unsigned long c, mux_taken;
+
+ if (gpio > mfp_to_gpio(MFP_PIN_GPIO127))
+ return -EINVAL;
+
+ d = &gpio_desc[gpio];
+ c = d->config;
+
+ if (!d->valid)
+ return -EINVAL;
+
+ /* Allow keypad GPIOs to wakeup system when
+ * configured as generic GPIOs.
+ */
+ if (d->keypad_gpio && (MFP_AF(d->config) == 0) &&
+ (d->config & MFP_LPM_CAN_WAKEUP)) {
+ if (on)
+ PKWR |= d->mask;
+ else
+ PKWR &= ~d->mask;
+ return 0;
+ }
+
+ mux_taken = (PWER & d->mux_mask) & (~d->mask);
+ if (on && mux_taken)
+ return -EBUSY;
+
+ if (d->can_wakeup && (c & MFP_LPM_CAN_WAKEUP)) {
+ if (on) {
+ PWER = (PWER & ~d->mux_mask) | d->mask;
+
+ if (c & MFP_LPM_EDGE_RISE)
+ PRER |= d->mask;
+ else
+ PRER &= ~d->mask;
+
+ if (c & MFP_LPM_EDGE_FALL)
+ PFER |= d->mask;
+ else
+ PFER &= ~d->mask;
+ } else {
+ PWER &= ~d->mask;
+ PRER &= ~d->mask;
+ PFER &= ~d->mask;
+ }
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PXA25x
+static void __init pxa25x_mfp_init(void)
+{
+ int i;
+
+ for (i = 0; i <= pxa_last_gpio; i++)
+ gpio_desc[i].valid = 1;
+
+ for (i = 0; i <= 15; i++) {
+ gpio_desc[i].can_wakeup = 1;
+ gpio_desc[i].mask = GPIO_bit(i);
+ }
+
+ /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
+ * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
+ */
+ for (i = 86; i <= pxa_last_gpio; i++)
+ gpio_desc[i].dir_inverted = 1;
+}
+#else
+static inline void pxa25x_mfp_init(void) {}
+#endif /* CONFIG_PXA25x */
+
+#ifdef CONFIG_PXA27x
+static int pxa27x_pkwr_gpio[] = {
+ 13, 16, 17, 34, 36, 37, 38, 39, 90, 91, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102
+};
+
+int keypad_set_wake(unsigned int on)
+{
+ unsigned int i, gpio, mask = 0;
+ struct gpio_desc *d;
+
+ for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
+
+ gpio = pxa27x_pkwr_gpio[i];
+ d = &gpio_desc[gpio];
+
+ /* skip if configured as generic GPIO */
+ if (MFP_AF(d->config) == 0)
+ continue;
+
+ if (d->config & MFP_LPM_CAN_WAKEUP)
+ mask |= gpio_desc[gpio].mask;
+ }
+
+ if (on)
+ PKWR |= mask;
+ else
+ PKWR &= ~mask;
+ return 0;
+}
+
+#define PWER_WEMUX2_GPIO38 (1 << 16)
+#define PWER_WEMUX2_GPIO53 (2 << 16)
+#define PWER_WEMUX2_GPIO40 (3 << 16)
+#define PWER_WEMUX2_GPIO36 (4 << 16)
+#define PWER_WEMUX2_MASK (7 << 16)
+#define PWER_WEMUX3_GPIO31 (1 << 19)
+#define PWER_WEMUX3_GPIO113 (2 << 19)
+#define PWER_WEMUX3_MASK (3 << 19)
+
+#define INIT_GPIO_DESC_MUXED(mux, gpio) \
+do { \
+ gpio_desc[(gpio)].can_wakeup = 1; \
+ gpio_desc[(gpio)].mask = PWER_ ## mux ## _GPIO ##gpio; \
+ gpio_desc[(gpio)].mux_mask = PWER_ ## mux ## _MASK; \
+} while (0)
+
+static void __init pxa27x_mfp_init(void)
+{
+ int i, gpio;
+
+ for (i = 0; i <= pxa_last_gpio; i++) {
+ /* skip GPIO2, 5, 6, 7, 8, they are not
+ * valid pins allow configuration
+ */
+ if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8)
+ continue;
+
+ gpio_desc[i].valid = 1;
+ }
+
+ /* Keypad GPIOs */
+ for (i = 0; i < ARRAY_SIZE(pxa27x_pkwr_gpio); i++) {
+ gpio = pxa27x_pkwr_gpio[i];
+ gpio_desc[gpio].can_wakeup = 1;
+ gpio_desc[gpio].keypad_gpio = 1;
+ gpio_desc[gpio].mask = 1 << i;
+ }
+
+ /* Overwrite GPIO13 as a PWER wakeup source */
+ for (i = 0; i <= 15; i++) {
+ /* skip GPIO2, 5, 6, 7, 8 */
+ if (GPIO_bit(i) & 0x1e4)
+ continue;
+
+ gpio_desc[i].can_wakeup = 1;
+ gpio_desc[i].mask = GPIO_bit(i);
+ }
+
+ gpio_desc[35].can_wakeup = 1;
+ gpio_desc[35].mask = PWER_WE35;
+
+ INIT_GPIO_DESC_MUXED(WEMUX3, 31);
+ INIT_GPIO_DESC_MUXED(WEMUX3, 113);
+ INIT_GPIO_DESC_MUXED(WEMUX2, 38);
+ INIT_GPIO_DESC_MUXED(WEMUX2, 53);
+ INIT_GPIO_DESC_MUXED(WEMUX2, 40);
+ INIT_GPIO_DESC_MUXED(WEMUX2, 36);
+}
+#else
+static inline void pxa27x_mfp_init(void) {}
+#endif /* CONFIG_PXA27x */
+
+#ifdef CONFIG_PM
+static unsigned long saved_gafr[2][4];
+static unsigned long saved_gpdr[4];
+static unsigned long saved_pgsr[4];
+
+static int pxa2xx_mfp_suspend(void)
+{
+ int i;
+
+ /* set corresponding PGSR bit of those marked MFP_LPM_KEEP_OUTPUT */
+ for (i = 0; i < pxa_last_gpio; i++) {
+ if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
+ (GPDR(i) & GPIO_bit(i))) {
+ if (GPLR(i) & GPIO_bit(i))
+ PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
+ else
+ PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
+ }
+ }
+
+ for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
+
+ saved_gafr[0][i] = GAFR_L(i);
+ saved_gafr[1][i] = GAFR_U(i);
+ saved_gpdr[i] = GPDR(i * 32);
+ saved_pgsr[i] = PGSR(i);
+
+ GPDR(i * 32) = gpdr_lpm[i];
+ }
+ return 0;
+}
+
+static void pxa2xx_mfp_resume(void)
+{
+ int i;
+
+ for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) {
+ GAFR_L(i) = saved_gafr[0][i];
+ GAFR_U(i) = saved_gafr[1][i];
+ GPDR(i * 32) = saved_gpdr[i];
+ PGSR(i) = saved_pgsr[i];
+ }
+ PSSR = PSSR_RDH | PSSR_PH;
+}
+#else
+#define pxa2xx_mfp_suspend NULL
+#define pxa2xx_mfp_resume NULL
+#endif
+
+struct syscore_ops pxa2xx_mfp_syscore_ops = {
+ .suspend = pxa2xx_mfp_suspend,
+ .resume = pxa2xx_mfp_resume,
+};
+
+static int __init pxa2xx_mfp_init(void)
+{
+ int i;
+
+ if (!cpu_is_pxa2xx())
+ return 0;
+
+ if (cpu_is_pxa25x())
+ pxa25x_mfp_init();
+
+ if (cpu_is_pxa27x())
+ pxa27x_mfp_init();
+
+ /* clear RDH bit to enable GPIO receivers after reset/sleep exit */
+ PSSR = PSSR_RDH;
+
+ /* initialize gafr_run[], pgsr_lpm[] from existing values */
+ for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
+ gpdr_lpm[i] = GPDR(i * 32);
+
+ return 0;
+}
+postcore_initcall(pxa2xx_mfp_init);
diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c
new file mode 100644
index 00000000..89863a01
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp-pxa3xx.c
@@ -0,0 +1,59 @@
+/*
+ * linux/arch/arm/mach-pxa/mfp.c
+ *
+ * PXA3xx Multi-Function Pin Support
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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 <linux/syscore_ops.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp-pxa3xx.h>
+#include <mach/pxa3xx-regs.h>
+
+#ifdef CONFIG_PM
+/*
+ * Configure the MFPs appropriately for suspend/resume.
+ * FIXME: this should probably depend on which system state we're
+ * entering - for instance, we might not want to place MFP pins in
+ * a pull-down mode if they're an active low chip select, and we're
+ * just entering standby.
+ */
+static int pxa3xx_mfp_suspend(void)
+{
+ mfp_config_lpm();
+ return 0;
+}
+
+static void pxa3xx_mfp_resume(void)
+{
+ mfp_config_run();
+
+ /* clear RDH bit when MFP settings are restored
+ *
+ * NOTE: the last 3 bits DxS are write-1-to-clear so carefully
+ * preserve them here in case they will be referenced later
+ */
+ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+}
+#else
+#define pxa3xx_mfp_suspend NULL
+#define pxa3xx_mfp_resume NULL
+#endif
+
+struct syscore_ops pxa3xx_mfp_syscore_ops = {
+ .suspend = pxa3xx_mfp_suspend,
+ .resume = pxa3xx_mfp_resume,
+};
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
new file mode 100644
index 00000000..e3470137
--- /dev/null
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -0,0 +1,799 @@
+/*
+ * Handles the Mitac Mio A701 Board
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/gpio_keys.h>
+#include <linux/pwm_backlight.h>
+#include <linux/rtc.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pda_power.h>
+#include <linux/power_supply.h>
+#include <linux/wm97xx.h>
+#include <linux/mtd/physmap.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/regulator/max1586.h>
+#include <linux/slab.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/regs-rtc.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/camera.h>
+#include <mach/audio.h>
+#include <media/soc_camera.h>
+
+#include <mach/mioa701.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long mioa701_pin_config[] = {
+ /* Mio global */
+ MIO_CFG_OUT(GPIO9_CHARGE_EN, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO18_POWEROFF, AF0, DRIVE_LOW),
+ MFP_CFG_OUT(GPIO3, AF0, DRIVE_HIGH),
+ MFP_CFG_OUT(GPIO4, AF0, DRIVE_HIGH),
+ MIO_CFG_IN(GPIO80_MAYBE_CHARGE_VDROP, AF0),
+
+ /* Backlight PWM 0 */
+ GPIO16_PWM0_OUT,
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ MIO_CFG_IN(GPIO78_SDIO_RO, AF0),
+ MIO_CFG_IN(GPIO15_SDIO_INSERT, AF0),
+ MIO_CFG_OUT(GPIO91_SDIO_EN, AF0, DRIVE_LOW),
+
+ /* USB */
+ MIO_CFG_IN(GPIO13_nUSB_DETECT, AF0),
+ MIO_CFG_OUT(GPIO22_USB_ENABLE, AF0, DRIVE_LOW),
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* QCI */
+ GPIO12_CIF_DD_7,
+ GPIO17_CIF_DD_6,
+ GPIO50_CIF_DD_3,
+ GPIO51_CIF_DD_2,
+ GPIO52_CIF_DD_4,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO55_CIF_DD_1,
+ GPIO81_CIF_DD_0,
+ GPIO82_CIF_DD_5,
+ GPIO84_CIF_FV,
+ GPIO85_CIF_LV,
+
+ /* Bluetooth */
+ MIO_CFG_IN(GPIO14_BT_nACTIVITY, AF0),
+ GPIO44_BTUART_CTS,
+ GPIO42_BTUART_RXD,
+ GPIO45_BTUART_RTS,
+ GPIO43_BTUART_TXD,
+ MIO_CFG_OUT(GPIO83_BT_ON, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO77_BT_UNKNOWN1, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO86_BT_MAYBE_nRESET, AF0, DRIVE_HIGH),
+
+ /* GPS */
+ MIO_CFG_OUT(GPIO23_GPS_UNKNOWN1, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO26_GPS_ON, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO27_GPS_RESET, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO106_GPS_UNKNOWN2, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO107_GPS_UNKNOWN3, AF0, DRIVE_LOW),
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* GSM */
+ MIO_CFG_OUT(GPIO24_GSM_MOD_RESET_CMD, AF0, DRIVE_LOW),
+ MIO_CFG_OUT(GPIO88_GSM_nMOD_ON_CMD, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO90_GSM_nMOD_OFF_CMD, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO114_GSM_nMOD_DTE_UART_STATE, AF0, DRIVE_HIGH),
+ MIO_CFG_IN(GPIO25_GSM_MOD_ON_STATE, AF0),
+ MIO_CFG_IN(GPIO113_GSM_EVENT, AF0) | WAKEUP_ON_EDGE_BOTH,
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO36_FFUART_DCD,
+ GPIO37_FFUART_DSR,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ /* Sound */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ MIO_CFG_IN(GPIO12_HPJACK_INSERT, AF0),
+
+ /* Leds */
+ MIO_CFG_OUT(GPIO10_LED_nCharging, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO97_LED_nBlue, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO98_LED_nOrange, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO82_LED_nVibra, AF0, DRIVE_HIGH),
+ MIO_CFG_OUT(GPIO115_LED_nKeyboard, AF0, DRIVE_HIGH),
+
+ /* Keyboard */
+ MIO_CFG_IN(GPIO0_KEY_POWER, AF0) | WAKEUP_ON_EDGE_BOTH,
+ MIO_CFG_IN(GPIO93_KEY_VOLUME_UP, AF0),
+ MIO_CFG_IN(GPIO94_KEY_VOLUME_DOWN, AF0),
+ GPIO100_KP_MKIN_0,
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* Unknown */
+ MFP_CFG_IN(GPIO20, AF0),
+ MFP_CFG_IN(GPIO21, AF0),
+ MFP_CFG_IN(GPIO33, AF0),
+ MFP_CFG_OUT(GPIO49, AF0, DRIVE_HIGH),
+ MFP_CFG_OUT(GPIO57, AF0, DRIVE_HIGH),
+ MFP_CFG_IN(GPIO96, AF0),
+ MFP_CFG_OUT(GPIO116, AF0, DRIVE_HIGH),
+};
+
+#define MIO_GPIO_IN(num, _desc) \
+ { .gpio = (num), .dir = 0, .desc = (_desc) }
+#define MIO_GPIO_OUT(num, _init, _desc) \
+ { .gpio = (num), .dir = 1, .init = (_init), .desc = (_desc) }
+struct gpio_ress {
+ unsigned gpio : 8;
+ unsigned dir : 1;
+ unsigned init : 1;
+ char *desc;
+};
+
+static int mio_gpio_request(struct gpio_ress *gpios, int size)
+{
+ int i, rc = 0;
+ int gpio;
+ int dir;
+
+ for (i = 0; (!rc) && (i < size); i++) {
+ gpio = gpios[i].gpio;
+ dir = gpios[i].dir;
+ rc = gpio_request(gpio, gpios[i].desc);
+ if (rc) {
+ printk(KERN_ERR "Error requesting GPIO %d(%s) : %d\n",
+ gpio, gpios[i].desc, rc);
+ continue;
+ }
+ if (dir)
+ gpio_direction_output(gpio, gpios[i].init);
+ else
+ gpio_direction_input(gpio);
+ }
+ while ((rc) && (--i >= 0))
+ gpio_free(gpios[i].gpio);
+ return rc;
+}
+
+static void mio_gpio_free(struct gpio_ress *gpios, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ gpio_free(gpios[i].gpio);
+}
+
+/* LCD Screen and Backlight */
+static struct platform_pwm_backlight_data mioa701_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 50,
+ .pwm_period_ns = 4000 * 1024, /* Fl = 250kHz */
+};
+
+/*
+ * LTM0305A776C LCD panel timings
+ *
+ * see:
+ * - the LTM0305A776C datasheet,
+ * - and the PXA27x Programmers' manual
+ */
+static struct pxafb_mode_info mioa701_ltm0305a776c = {
+ .pixclock = 220000, /* CLK=4.545 MHz */
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .vsync_len = 2,
+ .left_margin = 6,
+ .right_margin = 4,
+ .upper_margin = 5,
+ .lower_margin = 3,
+};
+
+static void mioa701_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+ gpio_set_value(GPIO87_LCD_POWER, on);
+}
+
+static struct pxafb_mach_info mioa701_pxafb_info = {
+ .modes = &mioa701_ltm0305a776c,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = mioa701_lcd_power,
+};
+
+/*
+ * Keyboard configuration
+ */
+static unsigned int mioa701_matrix_keys[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_RIGHT),
+ KEY(0, 2, KEY_MEDIA),
+ KEY(1, 0, KEY_DOWN),
+ KEY(1, 1, KEY_ENTER),
+ KEY(1, 2, KEY_CONNECT), /* GPS key */
+ KEY(2, 0, KEY_LEFT),
+ KEY(2, 1, KEY_PHONE), /* Phone Green key */
+ KEY(2, 2, KEY_CAMERA) /* Camera key */
+};
+static struct pxa27x_keypad_platform_data mioa701_keypad_info = {
+ .matrix_key_rows = 3,
+ .matrix_key_cols = 3,
+ .matrix_key_map = mioa701_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(mioa701_matrix_keys),
+};
+
+/*
+ * GPIO Key Configuration
+ */
+#define MIO_KEY(key, _gpio, _desc, _wakeup) \
+ { .code = (key), .gpio = (_gpio), .active_low = 0, \
+ .desc = (_desc), .type = EV_KEY, .wakeup = (_wakeup) }
+static struct gpio_keys_button mioa701_button_table[] = {
+ MIO_KEY(KEY_EXIT, GPIO0_KEY_POWER, "Power button", 1),
+ MIO_KEY(KEY_VOLUMEUP, GPIO93_KEY_VOLUME_UP, "Volume up", 0),
+ MIO_KEY(KEY_VOLUMEDOWN, GPIO94_KEY_VOLUME_DOWN, "Volume down", 0),
+ MIO_KEY(KEY_HP, GPIO12_HPJACK_INSERT, "HP jack detect", 0)
+};
+
+static struct gpio_keys_platform_data mioa701_gpio_keys_data = {
+ .buttons = mioa701_button_table,
+ .nbuttons = ARRAY_SIZE(mioa701_button_table),
+};
+
+/*
+ * Leds and vibrator
+ */
+#define ONE_LED(_gpio, _name) \
+{ .gpio = (_gpio), .name = (_name), .active_low = true }
+static struct gpio_led gpio_leds[] = {
+ ONE_LED(GPIO10_LED_nCharging, "mioa701:charging"),
+ ONE_LED(GPIO97_LED_nBlue, "mioa701:blue"),
+ ONE_LED(GPIO98_LED_nOrange, "mioa701:orange"),
+ ONE_LED(GPIO82_LED_nVibra, "mioa701:vibra"),
+ ONE_LED(GPIO115_LED_nKeyboard, "mioa701:keyboard")
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+/*
+ * GSM Sagem XS200 chip
+ *
+ * GSM handling was purged from kernel. For history, this is the way to go :
+ * - init : GPIO24_GSM_MOD_RESET_CMD = 0, GPIO114_GSM_nMOD_DTE_UART_STATE = 1
+ * GPIO88_GSM_nMOD_ON_CMD = 1, GPIO90_GSM_nMOD_OFF_CMD = 1
+ * - reset : GPIO24_GSM_MOD_RESET_CMD = 1, msleep(100),
+ * GPIO24_GSM_MOD_RESET_CMD = 0
+ * - turn on : GPIO88_GSM_nMOD_ON_CMD = 0, msleep(1000),
+ * GPIO88_GSM_nMOD_ON_CMD = 1
+ * - turn off : GPIO90_GSM_nMOD_OFF_CMD = 0, msleep(1000),
+ * GPIO90_GSM_nMOD_OFF_CMD = 1
+ */
+static int is_gsm_on(void)
+{
+ int is_on;
+
+ is_on = !!gpio_get_value(GPIO25_GSM_MOD_ON_STATE);
+ return is_on;
+}
+
+irqreturn_t gsm_on_irq(int irq, void *p)
+{
+ printk(KERN_DEBUG "Mioa701: GSM status changed to %s\n",
+ is_gsm_on() ? "on" : "off");
+ return IRQ_HANDLED;
+}
+
+struct gpio_ress gsm_gpios[] = {
+ MIO_GPIO_IN(GPIO25_GSM_MOD_ON_STATE, "GSM state"),
+ MIO_GPIO_IN(GPIO113_GSM_EVENT, "GSM event"),
+};
+
+static int __init gsm_init(void)
+{
+ int rc;
+
+ rc = mio_gpio_request(ARRAY_AND_SIZE(gsm_gpios));
+ if (rc)
+ goto err_gpio;
+ rc = request_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), gsm_on_irq,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "GSM XS200 Power Irq", NULL);
+ if (rc)
+ goto err_irq;
+
+ gpio_set_wake(GPIO113_GSM_EVENT, 1);
+ return 0;
+
+err_irq:
+ printk(KERN_ERR "Mioa701: Can't request GSM_ON irq\n");
+ mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
+err_gpio:
+ printk(KERN_ERR "Mioa701: gsm not available\n");
+ return rc;
+}
+
+static void gsm_exit(void)
+{
+ free_irq(gpio_to_irq(GPIO25_GSM_MOD_ON_STATE), NULL);
+ mio_gpio_free(ARRAY_AND_SIZE(gsm_gpios));
+}
+
+/*
+ * Bluetooth BRF6150 chip
+ *
+ * BT handling was purged from kernel. For history, this is the way to go :
+ * - turn on : GPIO83_BT_ON = 1
+ * - turn off : GPIO83_BT_ON = 0
+ */
+
+/*
+ * GPS Sirf Star III chip
+ *
+ * GPS handling was purged from kernel. For history, this is the way to go :
+ * - init : GPIO23_GPS_UNKNOWN1 = 1, GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
+ * GPIO106_GPS_UNKNOWN2 = 0, GPIO107_GPS_UNKNOWN3 = 0
+ * - turn on : GPIO27_GPS_RESET = 1, GPIO26_GPS_ON = 1
+ * - turn off : GPIO26_GPS_ON = 0, GPIO27_GPS_RESET = 0
+ */
+
+/*
+ * USB UDC
+ */
+static int is_usb_connected(void)
+{
+ return !gpio_get_value(GPIO13_nUSB_DETECT);
+}
+
+static struct pxa2xx_udc_mach_info mioa701_udc_info = {
+ .udc_is_connected = is_usb_connected,
+ .gpio_pullup = GPIO22_USB_ENABLE,
+};
+
+struct gpio_vbus_mach_info gpio_vbus_data = {
+ .gpio_vbus = GPIO13_nUSB_DETECT,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = -1,
+};
+
+/*
+ * SDIO/MMC Card controller
+ */
+/**
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static struct pxamci_platform_data mioa701_mci_info = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_card_detect = GPIO15_SDIO_INSERT,
+ .gpio_card_ro = GPIO78_SDIO_RO,
+ .gpio_power = GPIO91_SDIO_EN,
+};
+
+/* FlashRAM */
+static struct resource strataflash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data strataflash_data = {
+ .width = 2,
+ /* .set_vpp = mioa701_set_vpp, */
+};
+
+static struct platform_device strataflash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &strataflash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &strataflash_data,
+ },
+};
+
+/*
+ * Suspend/Resume bootstrap management
+ *
+ * MIO A701 reboot sequence is highly ROM dependent. From the one dissassembled,
+ * this sequence is as follows :
+ * - disables interrupts
+ * - initialize SDRAM (self refresh RAM into active RAM)
+ * - initialize GPIOs (depends on value at 0xa020b020)
+ * - initialize coprossessors
+ * - if edge detect on PWR_SCL(GPIO3), then proceed to cold start
+ * - or if value at 0xa020b000 not equal to 0x0f0f0f0f, proceed to cold start
+ * - else do a resume, ie. jump to addr 0xa0100000
+ */
+#define RESUME_ENABLE_ADDR 0xa020b000
+#define RESUME_ENABLE_VAL 0x0f0f0f0f
+#define RESUME_BT_ADDR 0xa020b020
+#define RESUME_UNKNOWN_ADDR 0xa020b024
+#define RESUME_VECTOR_ADDR 0xa0100000
+#define BOOTSTRAP_WORDS mioa701_bootstrap_lg/4
+
+static u32 *save_buffer;
+
+static void install_bootstrap(void)
+{
+ int i;
+ u32 *rom_bootstrap = phys_to_virt(RESUME_VECTOR_ADDR);
+ u32 *src = &mioa701_bootstrap;
+
+ for (i = 0; i < BOOTSTRAP_WORDS; i++)
+ rom_bootstrap[i] = src[i];
+}
+
+
+static int mioa701_sys_suspend(void)
+{
+ int i = 0, is_bt_on;
+ u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR);
+ u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
+ u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR);
+ u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR);
+
+ /* Devices prepare suspend */
+ is_bt_on = !!gpio_get_value(GPIO83_BT_ON);
+ pxa2xx_mfp_set_lpm(GPIO83_BT_ON,
+ is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW);
+
+ for (i = 0; i < BOOTSTRAP_WORDS; i++)
+ save_buffer[i] = mem_resume_vector[i];
+ save_buffer[i++] = *mem_resume_enabler;
+ save_buffer[i++] = *mem_resume_bt;
+ save_buffer[i++] = *mem_resume_unknown;
+
+ *mem_resume_enabler = RESUME_ENABLE_VAL;
+ *mem_resume_bt = is_bt_on;
+
+ install_bootstrap();
+ return 0;
+}
+
+static void mioa701_sys_resume(void)
+{
+ int i = 0;
+ u32 *mem_resume_vector = phys_to_virt(RESUME_VECTOR_ADDR);
+ u32 *mem_resume_enabler = phys_to_virt(RESUME_ENABLE_ADDR);
+ u32 *mem_resume_bt = phys_to_virt(RESUME_BT_ADDR);
+ u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR);
+
+ for (i = 0; i < BOOTSTRAP_WORDS; i++)
+ mem_resume_vector[i] = save_buffer[i];
+ *mem_resume_enabler = save_buffer[i++];
+ *mem_resume_bt = save_buffer[i++];
+ *mem_resume_unknown = save_buffer[i++];
+}
+
+static struct syscore_ops mioa701_syscore_ops = {
+ .suspend = mioa701_sys_suspend,
+ .resume = mioa701_sys_resume,
+};
+
+static int __init bootstrap_init(void)
+{
+ int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);
+
+ register_syscore_ops(&mioa701_syscore_ops);
+
+ save_buffer = kmalloc(save_size, GFP_KERNEL);
+ if (!save_buffer)
+ return -ENOMEM;
+ printk(KERN_INFO "MioA701: allocated %d bytes for bootstrap\n",
+ save_size);
+ return 0;
+}
+
+static void bootstrap_exit(void)
+{
+ kfree(save_buffer);
+ unregister_syscore_ops(&mioa701_syscore_ops);
+
+ printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
+ "resume !!!\n");
+}
+
+/*
+ * Power Supply
+ */
+static char *supplicants[] = {
+ "mioa701_battery"
+};
+
+static int is_ac_connected(void)
+{
+ return gpio_get_value(GPIO96_AC_DETECT);
+}
+
+static void mioa701_set_charge(int flags)
+{
+ gpio_set_value(GPIO9_CHARGE_EN, (flags == PDA_POWER_CHARGE_USB));
+}
+
+static struct pda_power_pdata power_pdata = {
+ .is_ac_online = is_ac_connected,
+ .is_usb_online = is_usb_connected,
+ .set_charge = mioa701_set_charge,
+ .supplied_to = supplicants,
+ .num_supplicants = ARRAY_SIZE(supplicants),
+};
+
+static struct resource power_resources[] = {
+ [0] = {
+ .name = "ac",
+ .start = gpio_to_irq(GPIO96_AC_DETECT),
+ .end = gpio_to_irq(GPIO96_AC_DETECT),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+ [1] = {
+ .name = "usb",
+ .start = gpio_to_irq(GPIO13_nUSB_DETECT),
+ .end = gpio_to_irq(GPIO13_nUSB_DETECT),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device power_dev = {
+ .name = "pda-power",
+ .id = -1,
+ .resource = power_resources,
+ .num_resources = ARRAY_SIZE(power_resources),
+ .dev = {
+ .platform_data = &power_pdata,
+ },
+};
+
+static struct wm97xx_batt_pdata mioa701_battery_data = {
+ .batt_aux = WM97XX_AUX_ID1,
+ .temp_aux = -1,
+ .charge_gpio = -1,
+ .min_voltage = 0xc00,
+ .max_voltage = 0xfc0,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION,
+ .batt_div = 1,
+ .batt_mult = 1,
+ .batt_name = "mioa701_battery",
+};
+
+static struct wm97xx_pdata mioa701_wm97xx_pdata = {
+ .batt_pdata = &mioa701_battery_data,
+};
+
+/*
+ * Voltage regulation
+ */
+static struct regulator_consumer_supply max1586_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data max1586_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 1000000,
+ .max_uV = 1705000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(max1586_consumers),
+ .consumer_supplies = max1586_consumers,
+};
+
+static struct max1586_subdev_data max1586_subdevs[] = {
+ { .name = "vcc_core", .id = MAX1586_V3,
+ .platform_data = &max1586_v3_info },
+};
+
+static struct max1586_platform_data max1586_info = {
+ .subdevs = max1586_subdevs,
+ .num_subdevs = ARRAY_SIZE(max1586_subdevs),
+ .v3_gain = MAX1586_GAIN_NO_R24, /* 700..1475 mV */
+};
+
+/*
+ * Camera interface
+ */
+struct pxacamera_platform_data mioa701_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 5000,
+};
+
+static struct i2c_board_info __initdata mioa701_pi2c_devices[] = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &max1586_info,
+ },
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info mioa701_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("mt9m111", 0x5d),
+ },
+};
+
+static struct soc_camera_link iclink = {
+ .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
+ .board_info = &mioa701_i2c_devices[0],
+ .i2c_adapter_id = 0,
+};
+
+struct i2c_pxa_platform_data i2c_pdata = {
+ .fast_mode = 1,
+};
+
+static pxa2xx_audio_ops_t mioa701_ac97_info = {
+ .reset_gpio = 95,
+ .codec_pdata = { &mioa701_wm97xx_pdata, },
+};
+
+/*
+ * Mio global
+ */
+
+/* Devices */
+#define MIO_PARENT_DEV(var, strname, tparent, pdata) \
+static struct platform_device var = { \
+ .name = strname, \
+ .id = -1, \
+ .dev = { \
+ .platform_data = pdata, \
+ .parent = tparent, \
+ }, \
+};
+#define MIO_SIMPLE_DEV(var, strname, pdata) \
+ MIO_PARENT_DEV(var, strname, NULL, pdata)
+
+MIO_SIMPLE_DEV(mioa701_gpio_keys, "gpio-keys", &mioa701_gpio_keys_data)
+MIO_PARENT_DEV(mioa701_backlight, "pwm-backlight", &pxa27x_device_pwm0.dev,
+ &mioa701_backlight_data);
+MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info)
+MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL)
+MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
+MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
+MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
+MIO_SIMPLE_DEV(mioa701_camera, "soc-camera-pdrv",&iclink);
+
+static struct platform_device *devices[] __initdata = {
+ &mioa701_gpio_keys,
+ &mioa701_backlight,
+ &mioa701_led,
+ &pxa2xx_pcm,
+ &mioa701_sound,
+ &power_dev,
+ &strataflash,
+ &gpio_vbus,
+ &mioa701_camera,
+ &mioa701_board,
+};
+
+static void mioa701_machine_exit(void);
+
+static void mioa701_poweroff(void)
+{
+ mioa701_machine_exit();
+ arm_machine_restart('s', NULL);
+}
+
+static void mioa701_restart(char c, const char *cmd)
+{
+ mioa701_machine_exit();
+ arm_machine_restart('s', cmd);
+}
+
+static struct gpio_ress global_gpios[] = {
+ MIO_GPIO_OUT(GPIO9_CHARGE_EN, 1, "Charger enable"),
+ MIO_GPIO_OUT(GPIO18_POWEROFF, 0, "Power Off"),
+ MIO_GPIO_OUT(GPIO87_LCD_POWER, 0, "LCD Power"),
+};
+
+static void __init mioa701_machine_init(void)
+{
+ PSLR = 0xff100000; /* SYSDEL=125ms, PWRDEL=125ms, PSLR_SL_ROD=1 */
+ PCFR = PCFR_DC_EN | PCFR_GPR_EN | PCFR_OPDE;
+ RTTR = 32768 - 1; /* Reset crazy WinCE value */
+ UP2OCR = UP2OCR_HXOE;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(mioa701_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
+ bootstrap_init();
+ pxa_set_fb_info(NULL, &mioa701_pxafb_info);
+ pxa_set_mci_info(&mioa701_mci_info);
+ pxa_set_keypad_info(&mioa701_keypad_info);
+ pxa_set_udc_info(&mioa701_udc_info);
+ pxa_set_ac97_info(&mioa701_ac97_info);
+ pm_power_off = mioa701_poweroff;
+ arm_pm_restart = mioa701_restart;
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ gsm_init();
+
+ i2c_register_board_info(1, ARRAY_AND_SIZE(mioa701_pi2c_devices));
+ pxa_set_i2c_info(&i2c_pdata);
+ pxa27x_set_i2c_power_info(NULL);
+ pxa_set_camera_info(&mioa701_pxacamera_platform_data);
+}
+
+static void mioa701_machine_exit(void)
+{
+ bootstrap_exit();
+ gsm_exit();
+}
+
+MACHINE_START(MIOA701, "MIO A701")
+ .boot_params = 0xa0000100,
+ .map_io = &pxa27x_map_io,
+ .init_irq = &pxa27x_init_irq,
+ .init_machine = mioa701_machine_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/mioa701_bootresume.S b/arch/arm/mach-pxa/mioa701_bootresume.S
new file mode 100644
index 00000000..324d25a4
--- /dev/null
+++ b/arch/arm/mach-pxa/mioa701_bootresume.S
@@ -0,0 +1,37 @@
+/* Bootloader to resume MIO A701
+ *
+ * 2007-1-12 Robert Jarzmik
+ *
+ * This code is licenced under the GPLv2.
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Note: Yes, part of the following code is located into the .data section.
+ * This is to allow jumpaddr to be accessed with a relative load
+ * while we can't rely on any MMU translation. We could have put
+ * sleep_save_sp in the .text section as well, but some setups might
+ * insist on it to be truly read-only.
+ */
+ .data
+ENTRY(mioa701_bootstrap)
+0:
+ b 1f
+ENTRY(mioa701_jumpaddr)
+ .word 0x40f00008 @ PSPR in no-MMU mode
+1:
+ mov r0, #0xa0000000 @ Don't suppose memory access works
+ orr r0, r0, #0x00200000 @ even if it's supposed to
+ orr r0, r0, #0x0000b000
+ mov r1, #0
+ str r1, [r0] @ Early disable resume for next boot
+ ldr r0, mioa701_jumpaddr @ (Murphy's Law)
+ ldr r0, [r0]
+ mov pc, r0
+2:
+
+ENTRY(mioa701_bootstrap_lg)
+ .data
+ .word 2b-0b
diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c
new file mode 100644
index 00000000..59cce78a
--- /dev/null
+++ b/arch/arm/mach-pxa/mp900.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/mach-pxa/mp900.c
+ *
+ * Support for the NEC MobilePro900/C platform
+ *
+ * Based on mach-pxa/gumstix.c
+ *
+ * 2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com>
+ * 2007, 2008 Michael Petchkovsky <mkpetch@internode.on.net>
+ *
+ * This program is free software; you can 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/device.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/usb/isp116x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa25x.h>
+#include "generic.h"
+
+static void isp116x_pfm_delay(struct device *dev, int delay)
+{
+
+ /* 400Mhz PXA2 = 2.5ns / instruction */
+
+ int cyc = delay / 10;
+
+ /* 4 Instructions = 4 x 2.5ns = 10ns */
+ __asm__ volatile ("0:\n"
+ "subs %0, %1, #1\n"
+ "bge 0b\n"
+ :"=r" (cyc)
+ :"0"(cyc)
+ );
+}
+
+static struct isp116x_platform_data isp116x_pfm_data = {
+ .remote_wakeup_enable = 1,
+ .delay = isp116x_pfm_delay,
+};
+
+static struct resource isp116x_pfm_resources[] = {
+ [0] = {
+ .start = 0x0d000000,
+ .end = 0x0d000000 + 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x0d000000 + 4,
+ .end = 0x0d000000 + 5,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 61,
+ .end = 61,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mp900c_dummy_device = {
+ .name = "mp900c_dummy",
+ .id = -1,
+};
+
+static struct platform_device mp900c_usb = {
+ .name = "isp116x-hcd",
+ .num_resources = ARRAY_SIZE(isp116x_pfm_resources),
+ .resource = isp116x_pfm_resources,
+ .dev.platform_data = &isp116x_pfm_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mp900c_dummy_device,
+ &mp900c_usb,
+};
+
+static void __init mp900c_init(void)
+{
+ printk(KERN_INFO "MobilePro 900/C machine init\n");
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */
+MACHINE_START(NEC_MP900, "MobilePro900/C")
+ .boot_params = 0xa0220100,
+ .timer = &pxa_timer,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = mp900c_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c
new file mode 100644
index 00000000..b5a8fd3f
--- /dev/null
+++ b/arch/arm/mach-pxa/mxm8x10.c
@@ -0,0 +1,474 @@
+/*
+ * linux/arch/arm/mach-pxa/mxm8x10.c
+ *
+ * Support for the Embedian MXM-8x10 Computer on Module
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ * Copyright (C) 2009 Embedian Inc.
+ * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
+ *
+ * 2007-09-04: eric miao <eric.y.miao@gmail.com>
+ * rewrite to align with latest kernel
+ *
+ * 2010-01-09: Edwin Peer <epeer@tmtservices.co.za>
+ * Hennie van der Merwe <hvdmerwe@tmtservices.co.za>
+ * rework for upstream merge
+ *
+ * This program is free software; you can 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_8250.h>
+#include <linux/dm9000.h>
+#include <linux/gpio.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <plat/pxa3xx_nand.h>
+
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxa320.h>
+
+#include <mach/mxm8x10.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* GPIO pin definition
+
+External device stuff - Leave unconfigured for now...
+---------------------
+GPIO0 - DREQ (External DMA Request)
+GPIO3 - nGCS2 (External Chip Select) Where is nGCS0; nGCS1; nGCS4; nGCS5 ?
+GPIO4 - nGCS3
+GPIO15 - EXT_GPIO1
+GPIO16 - EXT_GPIO2
+GPIO17 - EXT_GPIO3
+GPIO24 - EXT_GPIO4
+GPIO25 - EXT_GPIO5
+GPIO26 - EXT_GPIO6
+GPIO27 - EXT_GPIO7
+GPIO28 - EXT_GPIO8
+GPIO29 - EXT_GPIO9
+GPIO30 - EXT_GPIO10
+GPIO31 - EXT_GPIO11
+GPIO57 - EXT_GPIO12
+GPIO74 - EXT_IRQ1
+GPIO75 - EXT_IRQ2
+GPIO76 - EXT_IRQ3
+GPIO77 - EXT_IRQ4
+GPIO78 - EXT_IRQ5
+GPIO79 - EXT_IRQ6
+GPIO80 - EXT_IRQ7
+GPIO81 - EXT_IRQ8
+GPIO87 - VCCIO_PWREN (External Device PWREN)
+
+Dallas 1-Wire - Leave unconfigured for now...
+-------------
+GPIO0_2 - DS - 1Wire
+
+Ethernet
+--------
+GPIO1 - DM9000 PWR
+GPIO9 - DM9K_nIRQ
+GPIO36 - DM9K_RESET
+
+Keypad - Leave unconfigured by for now...
+------
+GPIO1_2 - KP_DKIN0
+GPIO5_2 - KP_MKOUT7
+GPIO82 - KP_DKIN1
+GPIO85 - KP_DKIN2
+GPIO86 - KP_DKIN3
+GPIO113 - KP_MKIN0
+GPIO114 - KP_MKIN1
+GPIO115 - KP_MKIN2
+GPIO116 - KP_MKIN3
+GPIO117 - KP_MKIN4
+GPIO118 - KP_MKIN5
+GPIO119 - KP_MKIN6
+GPIO120 - KP_MKIN7
+GPIO121 - KP_MKOUT0
+GPIO122 - KP_MKOUT1
+GPIO122 - KP_MKOUT2
+GPIO123 - KP_MKOUT3
+GPIO124 - KP_MKOUT4
+GPIO125 - KP_MKOUT5
+GPIO127 - KP_MKOUT6
+
+Data Bus - Leave unconfigured for now...
+--------
+GPIO2 - nWait (Data Bus)
+
+USB Device
+----------
+GPIO4_2 - USBD_PULLUP
+GPIO10 - UTM_CLK (USB Device UTM Clk)
+GPIO49 - USB 2.0 Device UTM_DATA0
+GPIO50 - USB 2.0 Device UTM_DATA1
+GPIO51 - USB 2.0 Device UTM_DATA2
+GPIO52 - USB 2.0 Device UTM_DATA3
+GPIO53 - USB 2.0 Device UTM_DATA4
+GPIO54 - USB 2.0 Device UTM_DATA5
+GPIO55 - USB 2.0 Device UTM_DATA6
+GPIO56 - USB 2.0 Device UTM_DATA7
+GPIO58 - UTM_RXVALID (USB 2.0 Device)
+GPIO59 - UTM_RXACTIVE (USB 2.0 Device)
+GPIO60 - UTM_RXERROR
+GPIO61 - UTM_OPMODE0
+GPIO62 - UTM_OPMODE1
+GPIO71 - USBD_INT (USB Device?)
+GPIO73 - UTM_TXREADY (USB 2.0 Device)
+GPIO83 - UTM_TXVALID (USB 2.0 Device)
+GPIO98 - UTM_RESET (USB 2.0 device)
+GPIO99 - UTM_XCVR_SELECT
+GPIO100 - UTM_TERM_SELECT
+GPIO101 - UTM_SUSPENDM_X
+GPIO102 - UTM_LINESTATE0
+GPIO103 - UTM_LINESTATE1
+
+Card-Bus Interface - Leave unconfigured for now...
+------------------
+GPIO5 - nPIOR (I/O space output enable)
+GPIO6 - nPIOW (I/O space write enable)
+GPIO7 - nIOS16 (Input from I/O space telling size of data bus)
+GPIO8 - nPWAIT (Input for inserting wait states)
+
+LCD
+---
+GPIO6_2 - LDD0
+GPIO7_2 - LDD1
+GPIO8_2 - LDD2
+GPIO9_2 - LDD3
+GPIO11_2 - LDD5
+GPIO12_2 - LDD6
+GPIO13_2 - LDD7
+GPIO14_2 - VSYNC
+GPIO15_2 - HSYNC
+GPIO16_2 - VCLK
+GPIO17_2 - HCLK
+GPIO18_2 - VDEN
+GPIO63 - LDD8 (CPU LCD)
+GPIO64 - LDD9 (CPU LCD)
+GPIO65 - LDD10 (CPU LCD)
+GPIO66 - LDD11 (CPU LCD)
+GPIO67 - LDD12 (CPU LCD)
+GPIO68 - LDD13 (CPU LCD)
+GPIO69 - LDD14 (CPU LCD)
+GPIO70 - LDD15 (CPU LCD)
+GPIO88 - VCCLCD_PWREN (LCD Panel PWREN)
+GPIO97 - BACKLIGHT_EN
+GPIO104 - LCD_PWREN
+
+PWM - Leave unconfigured for now...
+---
+GPIO11 - PWM0
+GPIO12 - PWM1
+GPIO13 - PWM2
+GPIO14 - PWM3
+
+SD-CARD
+-------
+GPIO18 - SDDATA0
+GPIO19 - SDDATA1
+GPIO20 - SDDATA2
+GPIO21 - SDDATA3
+GPIO22 - SDCLK
+GPIO23 - SDCMD
+GPIO72 - SD_WP
+GPIO84 - SD_nIRQ_CD (SD-Card)
+
+I2C
+---
+GPIO32 - I2CSCL
+GPIO33 - I2CSDA
+
+AC97
+----
+GPIO35 - AC97_SDATA_IN
+GPIO37 - AC97_SDATA_OUT
+GPIO38 - AC97_SYNC
+GPIO39 - AC97_BITCLK
+GPIO40 - AC97_nRESET
+
+UART1
+-----
+GPIO41 - UART_RXD1
+GPIO42 - UART_TXD1
+GPIO43 - UART_CTS1
+GPIO44 - UART_DCD1
+GPIO45 - UART_DSR1
+GPIO46 - UART_nRI1
+GPIO47 - UART_DTR1
+GPIO48 - UART_RTS1
+
+UART2
+-----
+GPIO109 - RTS2
+GPIO110 - RXD2
+GPIO111 - TXD2
+GPIO112 - nCTS2
+
+UART3
+-----
+GPIO105 - nCTS3
+GPIO106 - nRTS3
+GPIO107 - TXD3
+GPIO108 - RXD3
+
+SSP3 - Leave unconfigured for now...
+----
+GPIO89 - SSP3_CLK
+GPIO90 - SSP3_SFRM
+GPIO91 - SSP3_TXD
+GPIO92 - SSP3_RXD
+
+SSP4
+GPIO93 - SSP4_CLK
+GPIO94 - SSP4_SFRM
+GPIO95 - SSP4_TXD
+GPIO96 - SSP4_RXD
+*/
+
+static mfp_cfg_t mfp_cfg[] __initdata = {
+ /* USB */
+ GPIO10_UTM_CLK,
+ GPIO49_U2D_PHYDATA_0,
+ GPIO50_U2D_PHYDATA_1,
+ GPIO51_U2D_PHYDATA_2,
+ GPIO52_U2D_PHYDATA_3,
+ GPIO53_U2D_PHYDATA_4,
+ GPIO54_U2D_PHYDATA_5,
+ GPIO55_U2D_PHYDATA_6,
+ GPIO56_U2D_PHYDATA_7,
+ GPIO58_UTM_RXVALID,
+ GPIO59_UTM_RXACTIVE,
+ GPIO60_U2D_RXERROR,
+ GPIO61_U2D_OPMODE0,
+ GPIO62_U2D_OPMODE1,
+ GPIO71_GPIO, /* USBD_INT */
+ GPIO73_UTM_TXREADY,
+ GPIO83_U2D_TXVALID,
+ GPIO98_U2D_RESET,
+ GPIO99_U2D_XCVR_SEL,
+ GPIO100_U2D_TERM_SEL,
+ GPIO101_U2D_SUSPEND,
+ GPIO102_UTM_LINESTATE_0,
+ GPIO103_UTM_LINESTATE_1,
+ GPIO4_2_GPIO | MFP_PULL_HIGH, /* UTM_PULLUP */
+
+ /* DM9000 */
+ GPIO1_GPIO,
+ GPIO9_GPIO,
+ GPIO36_GPIO,
+
+ /* AC97 */
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET,
+
+ /* UARTS */
+ GPIO41_UART1_RXD,
+ GPIO42_UART1_TXD,
+ GPIO43_UART1_CTS,
+ GPIO44_UART1_DCD,
+ GPIO45_UART1_DSR,
+ GPIO46_UART1_RI,
+ GPIO47_UART1_DTR,
+ GPIO48_UART1_RTS,
+
+ GPIO109_UART2_RTS,
+ GPIO110_UART2_RXD,
+ GPIO111_UART2_TXD,
+ GPIO112_UART2_CTS,
+
+ GPIO105_UART3_CTS,
+ GPIO106_UART3_RTS,
+ GPIO107_UART3_TXD,
+ GPIO108_UART3_RXD,
+
+ GPIO78_GPIO,
+ GPIO79_GPIO,
+ GPIO80_GPIO,
+ GPIO81_GPIO,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* MMC */
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,
+ GPIO72_GPIO | MFP_PULL_HIGH, /* Card Detect */
+ GPIO84_GPIO | MFP_PULL_LOW, /* Write Protect */
+
+ /* IRQ */
+ GPIO74_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ1 */
+ GPIO75_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ2 */
+ GPIO76_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ3 */
+ GPIO77_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ4 */
+ GPIO78_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ5 */
+ GPIO79_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ6 */
+ GPIO80_GPIO | MFP_LPM_EDGE_RISE, /* EXT_IRQ7 */
+ GPIO81_GPIO | MFP_LPM_EDGE_RISE /* EXT_IRQ8 */
+};
+
+/* MMC/MCI Support */
+#if defined(CONFIG_MMC)
+static struct pxamci_platform_data mxm_8x10_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .detect_delay_ms = 10,
+ .gpio_card_detect = MXM_8X10_SD_nCD,
+ .gpio_card_ro = MXM_8X10_SD_WP,
+ .gpio_power = -1
+};
+
+void __init mxm_8x10_mmc_init(void)
+{
+ pxa_set_mci_info(&mxm_8x10_mci_platform_data);
+}
+#endif
+
+/* USB Open Host Controller Interface */
+static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ .flags = ENABLE_PORT_ALL
+};
+
+void __init mxm_8x10_usb_host_init(void)
+{
+ pxa_set_ohci_info(&mxm_8x10_ohci_platform_data);
+}
+
+/* AC97 Sound Support */
+static struct platform_device mxm_8x10_ac97_device = {
+ .name = "pxa2xx-ac97"
+};
+
+void __init mxm_8x10_ac97_init(void)
+{
+ platform_device_register(&mxm_8x10_ac97_device);
+}
+
+/* NAND flash Support */
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+#define NAND_BLOCK_SIZE SZ_128K
+#define NB(x) (NAND_BLOCK_SIZE * (x))
+static struct mtd_partition mxm_8x10_nand_partitions[] = {
+ [0] = {
+ .name = "boot",
+ .size = NB(0x002),
+ .offset = NB(0x000),
+ .mask_flags = MTD_WRITEABLE
+ },
+ [1] = {
+ .name = "kernel",
+ .size = NB(0x010),
+ .offset = NB(0x002),
+ .mask_flags = MTD_WRITEABLE
+ },
+ [2] = {
+ .name = "root",
+ .size = NB(0x36c),
+ .offset = NB(0x012)
+ },
+ [3] = {
+ .name = "bbt",
+ .size = NB(0x082),
+ .offset = NB(0x37e),
+ .mask_flags = MTD_WRITEABLE
+ }
+};
+
+static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = mxm_8x10_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions)
+};
+
+static void __init mxm_8x10_nand_init(void)
+{
+ pxa3xx_set_nand_info(&mxm_8x10_nand_info);
+}
+#else
+static inline void mxm_8x10_nand_init(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
+/* Ethernet support: Davicom DM9000 */
+static struct resource dm9k_resources[] = {
+ [0] = {
+ .start = MXM_8X10_ETH_PHYS + 0x300,
+ .end = MXM_8X10_ETH_PHYS + 0x300,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MXM_8X10_ETH_PHYS + 0x308,
+ .end = MXM_8X10_ETH_PHYS + 0x308,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO9)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
+ }
+};
+
+static struct dm9000_plat_data dm9k_plat_data = {
+ .flags = DM9000_PLATF_16BITONLY
+};
+
+static struct platform_device dm9k_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9k_resources),
+ .resource = dm9k_resources,
+ .dev = {
+ .platform_data = &dm9k_plat_data
+ }
+};
+
+static void __init mxm_8x10_ethernet_init(void)
+{
+ platform_device_register(&dm9k_device);
+}
+
+/* PXA UARTs */
+static void __init mxm_8x10_uarts_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+}
+
+/* I2C and Real Time Clock */
+static struct i2c_board_info __initdata mxm_8x10_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1337", 0x68)
+ }
+};
+
+static void __init mxm_8x10_i2c_init(void)
+{
+ i2c_register_board_info(0, mxm_8x10_i2c_devices,
+ ARRAY_SIZE(mxm_8x10_i2c_devices));
+ pxa_set_i2c_info(NULL);
+}
+
+void __init mxm_8x10_barebones_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+
+ mxm_8x10_uarts_init();
+ mxm_8x10_nand_init();
+ mxm_8x10_i2c_init();
+ mxm_8x10_ethernet_init();
+}
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c
new file mode 100644
index 00000000..fbc10d7b
--- /dev/null
+++ b/arch/arm/mach-pxa/palm27x.c
@@ -0,0 +1,479 @@
+/*
+ * Common code for Palm LD, T5, TX, Z72
+ *
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.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/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/regulator/max1586.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+#include <mach/palm27x.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data palm27x_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .detect_delay_ms = 200,
+};
+
+void __init palm27x_mmc_init(int detect, int ro, int power,
+ int power_inverted)
+{
+ palm27x_mci_platform_data.gpio_card_detect = detect;
+ palm27x_mci_platform_data.gpio_card_ro = ro;
+ palm27x_mci_platform_data.gpio_power = power;
+ palm27x_mci_platform_data.gpio_power_invert = power_inverted;
+
+ pxa_set_mci_info(&palm27x_mci_platform_data);
+}
+#endif
+
+/******************************************************************************
+ * Power management - standby
+ ******************************************************************************/
+#if defined(CONFIG_SUSPEND)
+void __init palm27x_pm_init(unsigned long str_base)
+{
+ static const unsigned long resume[] = {
+ 0xe3a00101, /* mov r0, #0x40000000 */
+ 0xe380060f, /* orr r0, r0, #0x00f00000 */
+ 0xe590f008, /* ldr pc, [r0, #0x08] */
+ };
+
+ /*
+ * Copy the bootloader.
+ * NOTE: PalmZ72 uses a different wakeup method!
+ */
+ memcpy(phys_to_virt(str_base), resume, sizeof(resume));
+}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+struct pxafb_mode_info palm_320x480_lcd_mode = {
+ .pixclock = 57692,
+ .xres = 320,
+ .yres = 480,
+ .bpp = 16,
+
+ .left_margin = 32,
+ .right_margin = 1,
+ .upper_margin = 7,
+ .lower_margin = 1,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+};
+
+struct pxafb_mode_info palm_320x320_lcd_mode = {
+ .pixclock = 115384,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 27,
+ .right_margin = 7,
+ .upper_margin = 7,
+ .lower_margin = 8,
+
+ .hsync_len = 6,
+ .vsync_len = 1,
+};
+
+struct pxafb_mode_info palm_320x320_new_lcd_mode = {
+ .pixclock = 86538,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 20,
+ .right_margin = 8,
+ .upper_margin = 8,
+ .lower_margin = 5,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+};
+
+static struct pxafb_mach_info palm27x_lcd_screen = {
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static int palm27x_lcd_power;
+static void palm27x_lcd_ctl(int on, struct fb_var_screeninfo *info)
+{
+ gpio_set_value(palm27x_lcd_power, on);
+}
+
+void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
+{
+ palm27x_lcd_screen.modes = mode;
+
+ if (gpio_is_valid(power)) {
+ if (!gpio_request(power, "LCD power")) {
+ pr_err("Palm27x: failed to claim lcd power gpio!\n");
+ return;
+ }
+ if (!gpio_direction_output(power, 1)) {
+ pr_err("Palm27x: lcd power configuration failed!\n");
+ return;
+ }
+ palm27x_lcd_power = power;
+ palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
+ }
+
+ pxa_set_fb_info(NULL, &palm27x_lcd_screen);
+}
+#endif
+
+/******************************************************************************
+ * USB Gadget
+ ******************************************************************************/
+#if defined(CONFIG_USB_PXA27X) || \
+ defined(CONFIG_USB_PXA27X_MODULE)
+static struct gpio_vbus_mach_info palm27x_udc_info = {
+ .gpio_vbus_inverted = 1,
+};
+
+static struct platform_device palm27x_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palm27x_udc_info,
+ },
+};
+
+void __init palm27x_udc_init(int vbus, int pullup, int vbus_inverted)
+{
+ palm27x_udc_info.gpio_vbus = vbus;
+ palm27x_udc_info.gpio_pullup = pullup;
+
+ palm27x_udc_info.gpio_vbus_inverted = vbus_inverted;
+
+ if (!gpio_request(pullup, "USB Pullup")) {
+ gpio_direction_output(pullup,
+ palm27x_udc_info.gpio_vbus_inverted);
+ gpio_free(pullup);
+ } else
+ return;
+
+ platform_device_register(&palm27x_gpio_vbus);
+}
+#endif
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
+static struct pxaficp_platform_data palm27x_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+void __init palm27x_irda_init(int pwdn)
+{
+ palm27x_ficp_platform_data.gpio_pwdown = pwdn;
+ pxa_set_ficp_info(&palm27x_ficp_platform_data);
+}
+#endif
+
+/******************************************************************************
+ * WM97xx audio, battery
+ ******************************************************************************/
+#if defined(CONFIG_TOUCHSCREEN_WM97XX) || \
+ defined(CONFIG_TOUCHSCREEN_WM97XX_MODULE)
+static struct wm97xx_batt_pdata palm27x_batt_pdata = {
+ .batt_aux = WM97XX_AUX_ID3,
+ .temp_aux = WM97XX_AUX_ID2,
+ .charge_gpio = -1,
+ .batt_mult = 1000,
+ .batt_div = 414,
+ .temp_mult = 1,
+ .temp_div = 1,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .batt_name = "main-batt",
+};
+
+static struct wm97xx_pdata palm27x_wm97xx_pdata = {
+ .batt_pdata = &palm27x_batt_pdata,
+};
+
+static pxa2xx_audio_ops_t palm27x_ac97_pdata = {
+ .codec_pdata = { &palm27x_wm97xx_pdata, },
+};
+
+static struct palm27x_asoc_info palm27x_asoc_pdata = {
+ .jack_gpio = -1,
+};
+
+static struct platform_device palm27x_asoc = {
+ .name = "palm27x-asoc",
+ .id = -1,
+ .dev = {
+ .platform_data = &palm27x_asoc_pdata,
+ },
+};
+
+void __init palm27x_ac97_init(int minv, int maxv, int jack, int reset)
+{
+ palm27x_ac97_pdata.reset_gpio = reset;
+ palm27x_asoc_pdata.jack_gpio = jack;
+
+ if (minv < 0 || maxv < 0) {
+ palm27x_ac97_pdata.codec_pdata[0] = NULL;
+ pxa_set_ac97_info(&palm27x_ac97_pdata);
+ } else {
+ palm27x_batt_pdata.min_voltage = minv,
+ palm27x_batt_pdata.max_voltage = maxv,
+
+ pxa_set_ac97_info(&palm27x_ac97_pdata);
+ platform_device_register(&palm27x_asoc);
+ }
+}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static int palm_bl_power;
+static int palm_lcd_power;
+
+static int palm27x_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(palm_bl_power, "BL POWER");
+ if (ret)
+ goto err;
+ ret = gpio_direction_output(palm_bl_power, 0);
+ if (ret)
+ goto err2;
+
+ if (gpio_is_valid(palm_lcd_power)) {
+ ret = gpio_request(palm_lcd_power, "LCD POWER");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_output(palm_lcd_power, 0);
+ if (ret)
+ goto err3;
+ }
+
+ return 0;
+err3:
+ gpio_free(palm_lcd_power);
+err2:
+ gpio_free(palm_bl_power);
+err:
+ return ret;
+}
+
+static int palm27x_backlight_notify(struct device *dev, int brightness)
+{
+ gpio_set_value(palm_bl_power, brightness);
+ if (gpio_is_valid(palm_lcd_power))
+ gpio_set_value(palm_lcd_power, brightness);
+ return brightness;
+}
+
+static void palm27x_backlight_exit(struct device *dev)
+{
+ gpio_free(palm_bl_power);
+ if (gpio_is_valid(palm_lcd_power))
+ gpio_free(palm_lcd_power);
+}
+
+static struct platform_pwm_backlight_data palm27x_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 0xfe,
+ .dft_brightness = 0x7e,
+ .pwm_period_ns = 3500 * 1024,
+ .init = palm27x_backlight_init,
+ .notify = palm27x_backlight_notify,
+ .exit = palm27x_backlight_exit,
+};
+
+static struct platform_device palm27x_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &palm27x_backlight_data,
+ },
+};
+
+void __init palm27x_pwm_init(int bl, int lcd)
+{
+ palm_bl_power = bl;
+ palm_lcd_power = lcd;
+ platform_device_register(&palm27x_backlight);
+}
+#endif
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+#if defined(CONFIG_PDA_POWER) || defined(CONFIG_PDA_POWER_MODULE)
+static int palm_ac_state;
+static int palm_usb_state;
+
+static int palm27x_power_supply_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(palm_ac_state, "AC state");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(palm_ac_state);
+ if (ret)
+ goto err2;
+
+ if (gpio_is_valid(palm_usb_state)) {
+ ret = gpio_request(palm_usb_state, "USB state");
+ if (ret)
+ goto err2;
+ ret = gpio_direction_input(palm_usb_state);
+ if (ret)
+ goto err3;
+ }
+
+ return 0;
+err3:
+ gpio_free(palm_usb_state);
+err2:
+ gpio_free(palm_ac_state);
+err1:
+ return ret;
+}
+
+static void palm27x_power_supply_exit(struct device *dev)
+{
+ gpio_free(palm_usb_state);
+ gpio_free(palm_ac_state);
+}
+
+static int palm27x_is_ac_online(void)
+{
+ return gpio_get_value(palm_ac_state);
+}
+
+static int palm27x_is_usb_online(void)
+{
+ return !gpio_get_value(palm_usb_state);
+}
+static char *palm27x_supplicants[] = {
+ "main-battery",
+};
+
+static struct pda_power_pdata palm27x_ps_info = {
+ .init = palm27x_power_supply_init,
+ .exit = palm27x_power_supply_exit,
+ .is_ac_online = palm27x_is_ac_online,
+ .is_usb_online = palm27x_is_usb_online,
+ .supplied_to = palm27x_supplicants,
+ .num_supplicants = ARRAY_SIZE(palm27x_supplicants),
+};
+
+static struct platform_device palm27x_power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &palm27x_ps_info,
+ },
+};
+
+void __init palm27x_power_init(int ac, int usb)
+{
+ palm_ac_state = ac;
+ palm_usb_state = usb;
+ platform_device_register(&palm27x_power_supply);
+}
+#endif
+
+/******************************************************************************
+ * Core power regulator
+ ******************************************************************************/
+#if defined(CONFIG_REGULATOR_MAX1586) || \
+ defined(CONFIG_REGULATOR_MAX1586_MODULE)
+static struct regulator_consumer_supply palm27x_max1587a_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data palm27x_max1587a_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 900000,
+ .max_uV = 1705000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = palm27x_max1587a_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(palm27x_max1587a_consumers),
+};
+
+static struct max1586_subdev_data palm27x_max1587a_subdevs[] = {
+ {
+ .name = "vcc_core",
+ .id = MAX1586_V3,
+ .platform_data = &palm27x_max1587a_v3_info,
+ }
+};
+
+static struct max1586_platform_data palm27x_max1587a_info = {
+ .subdevs = palm27x_max1587a_subdevs,
+ .num_subdevs = ARRAY_SIZE(palm27x_max1587a_subdevs),
+ .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
+};
+
+static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &palm27x_max1587a_info,
+ },
+};
+
+static struct i2c_pxa_platform_data palm27x_i2c_power_info = {
+ .use_pio = 1,
+};
+
+void __init palm27x_pmic_init(void)
+{
+ i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info));
+ pxa27x_set_i2c_power_info(&palm27x_i2c_power_info);
+}
+#endif
diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c
new file mode 100644
index 00000000..4061ecdd
--- /dev/null
+++ b/arch/arm/mach-pxa/palmld.c
@@ -0,0 +1,350 @@
+/*
+ * Hardware definitions for Palm LifeDrive
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Alex Osborne <ato@meshy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmld.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/palmasoc.h>
+#include <mach/palm27x.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmld_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO114_GPIO, /* SD power */
+ GPIO116_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO95_AC97_nRESET,
+
+ /* IrDA */
+ GPIO108_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* MATRIX KEYPAD */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* GPIO KEYS */
+ GPIO10_GPIO, /* hotsync button */
+ GPIO12_GPIO, /* power switch */
+ GPIO15_GPIO, /* lock switch */
+
+ /* LEDs */
+ GPIO52_GPIO, /* green led */
+ GPIO94_GPIO, /* orange led */
+
+ /* PCMCIA */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO36_GPIO, /* wifi power */
+ GPIO38_GPIO, /* wifi ready */
+ GPIO81_GPIO, /* wifi reset */
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO39_FFUART_TXD,
+
+ /* HDD */
+ GPIO98_GPIO, /* HDD reset */
+ GPIO115_GPIO, /* HDD power */
+
+ /* MISC */
+ GPIO13_GPIO, /* earphone detect */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition palmld_partitions[] = {
+ {
+ .name = "Flash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data palmld_flash_data[] = {
+ {
+ .width = 2, /* bankwidth in bytes */
+ .parts = palmld_partitions,
+ .nr_parts = ARRAY_SIZE(palmld_partitions)
+ }
+};
+
+static struct resource palmld_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_4M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmld_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &palmld_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = palmld_flash_data,
+ },
+};
+
+static void __init palmld_nor_init(void)
+{
+ platform_device_register(&palmld_flash);
+}
+#else
+static inline void palmld_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int palmld_matrix_keys[] = {
+ KEY(0, 1, KEY_F2),
+ KEY(0, 2, KEY_UP),
+
+ KEY(1, 0, KEY_F3),
+ KEY(1, 1, KEY_F4),
+ KEY(1, 2, KEY_RIGHT),
+
+ KEY(2, 0, KEY_F1),
+ KEY(2, 1, KEY_F5),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_F6),
+ KEY(3, 1, KEY_ENTER),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmld_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmld_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmld_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+static void __init palmld_kpc_init(void)
+{
+ pxa_set_keypad_info(&palmld_keypad_platform_data);
+}
+#else
+static inline void palmld_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button palmld_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMLD_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+ {KEY_F9, GPIO_NR_PALMLD_LOCK_SWITCH, 0, "Lock Switch" },
+ {KEY_POWER, GPIO_NR_PALMLD_POWER_SWITCH, 0, "Power Switch" },
+};
+
+static struct gpio_keys_platform_data palmld_pxa_keys_data = {
+ .buttons = palmld_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmld_pxa_buttons),
+};
+
+static struct platform_device palmld_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmld_pxa_keys_data,
+ },
+};
+
+static void __init palmld_keys_init(void)
+{
+ platform_device_register(&palmld_pxa_keys);
+}
+#else
+static inline void palmld_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led gpio_leds[] = {
+{
+ .name = "palmld:green:led",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMLD_LED_GREEN,
+}, {
+ .name = "palmld:amber:led",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMLD_LED_AMBER,
+},
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device palmld_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ }
+};
+
+static void __init palmld_leds_init(void)
+{
+ platform_device_register(&palmld_leds);
+}
+#else
+static inline void palmld_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * HDD
+ ******************************************************************************/
+#if defined(CONFIG_PATA_PALMLD) || defined(CONFIG_PATA_PALMLD_MODULE)
+static struct platform_device palmld_ide_device = {
+ .name = "pata_palmld",
+ .id = -1,
+};
+
+static void __init palmld_ide_init(void)
+{
+ platform_device_register(&palmld_ide_device);
+}
+#else
+static inline void palmld_ide_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct map_desc palmld_io_desc[] __initdata = {
+{
+ .virtual = PALMLD_IDE_VIRT,
+ .pfn = __phys_to_pfn(PALMLD_IDE_PHYS),
+ .length = PALMLD_IDE_SIZE,
+ .type = MT_DEVICE
+},
+{
+ .virtual = PALMLD_USB_VIRT,
+ .pfn = __phys_to_pfn(PALMLD_USB_PHYS),
+ .length = PALMLD_USB_SIZE,
+ .type = MT_DEVICE
+},
+};
+
+static void __init palmld_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(palmld_io_desc, ARRAY_SIZE(palmld_io_desc));
+}
+
+static void __init palmld_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmld_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ palm27x_mmc_init(GPIO_NR_PALMLD_SD_DETECT_N, GPIO_NR_PALMLD_SD_READONLY,
+ GPIO_NR_PALMLD_SD_POWER, 0);
+ palm27x_pm_init(PALMLD_STR_BASE);
+ palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
+ palm27x_irda_init(GPIO_NR_PALMLD_IR_DISABLE);
+ palm27x_ac97_init(PALMLD_BAT_MIN_VOLTAGE, PALMLD_BAT_MAX_VOLTAGE,
+ GPIO_NR_PALMLD_EARPHONE_DETECT, 95);
+ palm27x_pwm_init(GPIO_NR_PALMLD_BL_POWER, GPIO_NR_PALMLD_LCD_POWER);
+ palm27x_power_init(GPIO_NR_PALMLD_POWER_DETECT,
+ GPIO_NR_PALMLD_USB_DETECT_N);
+ palm27x_pmic_init();
+ palmld_kpc_init();
+ palmld_keys_init();
+ palmld_nor_init();
+ palmld_leds_init();
+ palmld_ide_init();
+}
+
+MACHINE_START(PALMLD, "Palm LifeDrive")
+ .boot_params = 0xa0000100,
+ .map_io = palmld_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmld_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
new file mode 100644
index 00000000..df4d7d00
--- /dev/null
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -0,0 +1,211 @@
+/*
+ * Hardware definitions for Palm Tungsten|T5
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Ales Snuparek <snuparek@atlas.cz>
+ * Justin Kendrick <twilightsentry@gmail.com>
+ * RichardT5 <richard_t5@users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/memblock.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmt5.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+#include <mach/palm27x.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmt5_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO114_GPIO, /* SD power */
+ GPIO115_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO95_AC97_nRESET,
+
+ /* IrDA */
+ GPIO40_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* USB */
+ GPIO15_GPIO, /* usb detect */
+ GPIO93_GPIO, /* usb power */
+
+ /* MATRIX KEYPAD */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO39_FFUART_TXD,
+
+ /* MISC */
+ GPIO10_GPIO, /* hotsync button */
+ GPIO90_GPIO, /* power detect */
+ GPIO107_GPIO, /* earphone detect */
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int palmt5_matrix_keys[] = {
+ KEY(0, 0, KEY_POWER),
+ KEY(0, 1, KEY_F1),
+ KEY(0, 2, KEY_ENTER),
+
+ KEY(1, 0, KEY_F2),
+ KEY(1, 1, KEY_F3),
+ KEY(1, 2, KEY_F4),
+
+ KEY(2, 0, KEY_UP),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_RIGHT),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmt5_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmt5_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmt5_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+static void __init palmt5_kpc_init(void)
+{
+ pxa_set_keypad_info(&palmt5_keypad_platform_data);
+}
+#else
+static inline void palmt5_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button palmt5_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMT5_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+};
+
+static struct gpio_keys_platform_data palmt5_pxa_keys_data = {
+ .buttons = palmt5_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmt5_pxa_buttons),
+};
+
+static struct platform_device palmt5_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmt5_pxa_keys_data,
+ },
+};
+
+static void __init palmt5_keys_init(void)
+{
+ platform_device_register(&palmt5_pxa_keys);
+}
+#else
+static inline void palmt5_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init palmt5_reserve(void)
+{
+ memblock_reserve(0xa0200000, 0x1000);
+}
+
+static void __init palmt5_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ palm27x_mmc_init(GPIO_NR_PALMT5_SD_DETECT_N, GPIO_NR_PALMT5_SD_READONLY,
+ GPIO_NR_PALMT5_SD_POWER, 0);
+ palm27x_pm_init(PALMT5_STR_BASE);
+ palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
+ palm27x_udc_init(GPIO_NR_PALMT5_USB_DETECT_N,
+ GPIO_NR_PALMT5_USB_PULLUP, 1);
+ palm27x_irda_init(GPIO_NR_PALMT5_IR_DISABLE);
+ palm27x_ac97_init(PALMT5_BAT_MIN_VOLTAGE, PALMT5_BAT_MAX_VOLTAGE,
+ GPIO_NR_PALMT5_EARPHONE_DETECT, 95);
+ palm27x_pwm_init(GPIO_NR_PALMT5_BL_POWER, GPIO_NR_PALMT5_LCD_POWER);
+ palm27x_power_init(GPIO_NR_PALMT5_POWER_DETECT, -1);
+ palm27x_pmic_init();
+ palmt5_kpc_init();
+ palmt5_keys_init();
+}
+
+MACHINE_START(PALMT5, "Palm Tungsten|T5")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .reserve = palmt5_reserve,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmt5_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
new file mode 100644
index 00000000..5193ce27
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -0,0 +1,546 @@
+/*
+ * linux/arch/arm/mach-pxa/palmtc.c
+ *
+ * Support for the Palm Tungsten|C
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Petr Blaha <p3t3@centrum.cz>
+ * Chetan S. Kumar <shivakumar.chetan@gmail.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/delay.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/ucb1400.h>
+#include <linux/power_supply.h>
+#include <linux/gpio_keys.h>
+#include <linux/mtd/physmap.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/audio.h>
+#include <mach/palmtc.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/irda.h>
+#include <mach/udc.h>
+#include <mach/pxa2xx-regs.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmtc_pin_config[] __initdata = {
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+ GPIO12_GPIO, /* detect */
+ GPIO32_GPIO, /* power */
+ GPIO54_GPIO, /* r/o switch */
+
+ /* PCMCIA */
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO49_nPWE,
+ GPIO48_nPOE,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO57_nIOIS16,
+ GPIO56_nPWAIT,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* IrDA */
+ GPIO45_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* PWM */
+ GPIO17_PWM1_OUT,
+
+ /* USB */
+ GPIO4_GPIO, /* detect */
+ GPIO36_GPIO, /* pullup */
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* MATRIX KEYPAD */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 0 */
+ GPIO9_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 1 */
+ GPIO10_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 2 */
+ GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* in 3 */
+ GPIO18_GPIO | MFP_LPM_DRIVE_LOW, /* out 0 */
+ GPIO19_GPIO | MFP_LPM_DRIVE_LOW, /* out 1 */
+ GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* out 2 */
+ GPIO21_GPIO | MFP_LPM_DRIVE_LOW, /* out 3 */
+ GPIO22_GPIO | MFP_LPM_DRIVE_LOW, /* out 4 */
+ GPIO23_GPIO | MFP_LPM_DRIVE_LOW, /* out 5 */
+ GPIO24_GPIO | MFP_LPM_DRIVE_LOW, /* out 6 */
+ GPIO25_GPIO | MFP_LPM_DRIVE_LOW, /* out 7 */
+ GPIO26_GPIO | MFP_LPM_DRIVE_LOW, /* out 8 */
+ GPIO27_GPIO | MFP_LPM_DRIVE_LOW, /* out 9 */
+ GPIO79_GPIO | MFP_LPM_DRIVE_LOW, /* out 10 */
+ GPIO80_GPIO | MFP_LPM_DRIVE_LOW, /* out 11 */
+
+ /* PXA GPIO KEYS */
+ GPIO7_GPIO | WAKEUP_ON_EDGE_BOTH, /* hotsync button on cradle */
+
+ /* MISC */
+ GPIO1_RST, /* reset */
+ GPIO2_GPIO, /* earphone detect */
+ GPIO16_GPIO, /* backlight switch */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data palmtc_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_power = GPIO_NR_PALMTC_SD_POWER,
+ .gpio_card_ro = GPIO_NR_PALMTC_SD_READONLY,
+ .gpio_card_detect = GPIO_NR_PALMTC_SD_DETECT_N,
+ .detect_delay_ms = 200,
+};
+
+static void __init palmtc_mmc_init(void)
+{
+ pxa_set_mci_info(&palmtc_mci_platform_data);
+}
+#else
+static inline void palmtc_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button palmtc_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMTC_HOTSYNC_BUTTON, 1, "HotSync Button", EV_KEY, 1},
+};
+
+static struct gpio_keys_platform_data palmtc_pxa_keys_data = {
+ .buttons = palmtc_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmtc_pxa_buttons),
+};
+
+static struct platform_device palmtc_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_pxa_keys_data,
+ },
+};
+
+static void __init palmtc_keys_init(void)
+{
+ platform_device_register(&palmtc_pxa_keys);
+}
+#else
+static inline void palmtc_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static int palmtc_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMTC_BL_POWER, "BL POWER");
+ if (ret)
+ goto err;
+ ret = gpio_direction_output(GPIO_NR_PALMTC_BL_POWER, 1);
+ if (ret)
+ goto err2;
+
+ return 0;
+
+err2:
+ gpio_free(GPIO_NR_PALMTC_BL_POWER);
+err:
+ return ret;
+}
+
+static int palmtc_backlight_notify(struct device *dev, int brightness)
+{
+ /* backlight is on when GPIO16 AF0 is high */
+ gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness);
+ return brightness;
+}
+
+static void palmtc_backlight_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMTC_BL_POWER);
+}
+
+static struct platform_pwm_backlight_data palmtc_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = PALMTC_MAX_INTENSITY,
+ .dft_brightness = PALMTC_MAX_INTENSITY,
+ .pwm_period_ns = PALMTC_PERIOD_NS,
+ .init = palmtc_backlight_init,
+ .notify = palmtc_backlight_notify,
+ .exit = palmtc_backlight_exit,
+};
+
+static struct platform_device palmtc_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa25x_device_pwm1.dev,
+ .platform_data = &palmtc_backlight_data,
+ },
+};
+
+static void __init palmtc_pwm_init(void)
+{
+ platform_device_register(&palmtc_backlight);
+}
+#else
+static inline void palmtc_pwm_init(void) {}
+#endif
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+#if defined(CONFIG_IRDA) || defined(CONFIG_IRDA_MODULE)
+static struct pxaficp_platform_data palmtc_ficp_platform_data = {
+ .gpio_pwdown = GPIO_NR_PALMTC_IR_DISABLE,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+static void __init palmtc_irda_init(void)
+{
+ pxa_set_ficp_info(&palmtc_ficp_platform_data);
+}
+#else
+static inline void palmtc_irda_init(void) {}
+#endif
+
+/******************************************************************************
+ * Keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
+static const uint32_t palmtc_matrix_keys[] = {
+ KEY(0, 0, KEY_F1),
+ KEY(0, 1, KEY_X),
+ KEY(0, 2, KEY_POWER),
+ KEY(0, 3, KEY_TAB),
+ KEY(0, 4, KEY_A),
+ KEY(0, 5, KEY_Q),
+ KEY(0, 6, KEY_LEFTSHIFT),
+ KEY(0, 7, KEY_Z),
+ KEY(0, 8, KEY_S),
+ KEY(0, 9, KEY_W),
+ KEY(0, 10, KEY_E),
+ KEY(0, 11, KEY_UP),
+
+ KEY(1, 0, KEY_F2),
+ KEY(1, 1, KEY_DOWN),
+ KEY(1, 3, KEY_D),
+ KEY(1, 4, KEY_C),
+ KEY(1, 5, KEY_F),
+ KEY(1, 6, KEY_R),
+ KEY(1, 7, KEY_SPACE),
+ KEY(1, 8, KEY_V),
+ KEY(1, 9, KEY_G),
+ KEY(1, 10, KEY_T),
+ KEY(1, 11, KEY_LEFT),
+
+ KEY(2, 0, KEY_F3),
+ KEY(2, 1, KEY_LEFTCTRL),
+ KEY(2, 3, KEY_H),
+ KEY(2, 4, KEY_Y),
+ KEY(2, 5, KEY_N),
+ KEY(2, 6, KEY_J),
+ KEY(2, 7, KEY_U),
+ KEY(2, 8, KEY_M),
+ KEY(2, 9, KEY_K),
+ KEY(2, 10, KEY_I),
+ KEY(2, 11, KEY_RIGHT),
+
+ KEY(3, 0, KEY_F4),
+ KEY(3, 1, KEY_ENTER),
+ KEY(3, 3, KEY_DOT),
+ KEY(3, 4, KEY_L),
+ KEY(3, 5, KEY_O),
+ KEY(3, 6, KEY_LEFTALT),
+ KEY(3, 7, KEY_ENTER),
+ KEY(3, 8, KEY_BACKSPACE),
+ KEY(3, 9, KEY_P),
+ KEY(3, 10, KEY_B),
+ KEY(3, 11, KEY_FN),
+};
+
+const struct matrix_keymap_data palmtc_keymap_data = {
+ .keymap = palmtc_matrix_keys,
+ .keymap_size = ARRAY_SIZE(palmtc_matrix_keys),
+};
+
+static const unsigned int palmtc_keypad_row_gpios[] = {
+ 0, 9, 10, 11
+};
+
+static const unsigned int palmtc_keypad_col_gpios[] = {
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 79, 80
+};
+
+static struct matrix_keypad_platform_data palmtc_keypad_platform_data = {
+ .keymap_data = &palmtc_keymap_data,
+ .row_gpios = palmtc_keypad_row_gpios,
+ .num_row_gpios = ARRAY_SIZE(palmtc_keypad_row_gpios),
+ .col_gpios = palmtc_keypad_col_gpios,
+ .num_col_gpios = ARRAY_SIZE(palmtc_keypad_col_gpios),
+ .active_low = 1,
+
+ .debounce_ms = 20,
+ .col_scan_delay_us = 5,
+};
+
+static struct platform_device palmtc_keyboard = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_keypad_platform_data,
+ },
+};
+static void __init palmtc_mkp_init(void)
+{
+ platform_device_register(&palmtc_keyboard);
+}
+#else
+static inline void palmtc_mkp_init(void) {}
+#endif
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
+static struct gpio_vbus_mach_info palmtc_udc_info = {
+ .gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = GPIO_NR_PALMTC_USB_POWER,
+};
+
+static struct platform_device palmtc_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_udc_info,
+ },
+};
+
+static void __init palmtc_udc_init(void)
+{
+ platform_device_register(&palmtc_gpio_vbus);
+};
+#else
+static inline void palmtc_udc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Touchscreen / Battery / GPIO-extender
+ ******************************************************************************/
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static struct platform_device palmtc_ucb1400_device = {
+ .name = "ucb1400_core",
+ .id = -1,
+};
+
+static void __init palmtc_ts_init(void)
+{
+ pxa_set_ac97_info(NULL);
+ platform_device_register(&palmtc_ucb1400_device);
+}
+#else
+static inline void palmtc_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led palmtc_gpio_leds[] = {
+{
+ .name = "palmtc:green:user",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMTC_LED_POWER,
+ .active_low = 1,
+}, {
+ .name = "palmtc:vibra:vibra",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMTC_VIBRA_POWER,
+ .active_low = 1,
+}
+
+};
+
+static struct gpio_led_platform_data palmtc_gpio_led_info = {
+ .leds = palmtc_gpio_leds,
+ .num_leds = ARRAY_SIZE(palmtc_gpio_leds),
+};
+
+static struct platform_device palmtc_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtc_gpio_led_info,
+ }
+};
+
+static void __init palmtc_leds_init(void)
+{
+ platform_device_register(&palmtc_leds);
+}
+#else
+static inline void palmtc_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct resource palmtc_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_16M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition palmtc_flash_parts[] = {
+ {
+ .name = "U-Boot Bootloader",
+ .offset = 0x0,
+ .size = 0x40000,
+ },
+ {
+ .name = "Linux Kernel",
+ .offset = 0x40000,
+ .size = 0x2c0000,
+ },
+ {
+ .name = "Filesystem",
+ .offset = 0x300000,
+ .size = 0xcc0000,
+ },
+ {
+ .name = "U-Boot Environment",
+ .offset = 0xfc0000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data palmtc_flash_data = {
+ .width = 4,
+ .parts = palmtc_flash_parts,
+ .nr_parts = ARRAY_SIZE(palmtc_flash_parts),
+};
+
+static struct platform_device palmtc_flash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &palmtc_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &palmtc_flash_data,
+ },
+};
+
+static void __init palmtc_nor_init(void)
+{
+ platform_device_register(&palmtc_flash);
+}
+#else
+static inline void palmtc_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info palmtc_lcd_modes[] = {
+ {
+ .pixclock = 115384,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 27,
+ .right_margin = 7,
+ .upper_margin = 7,
+ .lower_margin = 8,
+
+ .hsync_len = 6,
+ .vsync_len = 1,
+ },
+};
+
+static struct pxafb_mach_info palmtc_lcd_screen = {
+ .modes = palmtc_lcd_modes,
+ .num_modes = ARRAY_SIZE(palmtc_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init palmtc_lcd_init(void)
+{
+ pxa_set_fb_info(NULL, &palmtc_lcd_screen);
+}
+#else
+static inline void palmtc_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init palmtc_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtc_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_hwuart_info(NULL);
+
+ palmtc_mmc_init();
+ palmtc_keys_init();
+ palmtc_pwm_init();
+ palmtc_irda_init();
+ palmtc_mkp_init();
+ palmtc_udc_init();
+ palmtc_ts_init();
+ palmtc_nor_init();
+ palmtc_lcd_init();
+ palmtc_leds_init();
+};
+
+MACHINE_START(PALMTC, "Palm Tungsten|C")
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmtc_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
new file mode 100644
index 00000000..726f5b98
--- /dev/null
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -0,0 +1,364 @@
+/*
+ * Hardware definitions for Palm Tungsten|E2
+ *
+ * Author:
+ * Carlos Eduardo Medaglia Dyonisio <cadu@nerdfeliz.com>
+ *
+ * Rewrite for mainline:
+ * Marek Vasut <marek.vasut@gmail.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.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/audio.h>
+#include <mach/palmte2.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/irda.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmte2_pin_config[] __initdata = {
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+ GPIO10_GPIO, /* SD detect */
+ GPIO55_GPIO, /* SD power */
+ GPIO51_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* USB */
+ GPIO15_GPIO, /* usb detect */
+ GPIO53_GPIO, /* usb power */
+
+ /* IrDA */
+ GPIO48_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* GPIO KEYS */
+ GPIO5_GPIO, /* notes */
+ GPIO7_GPIO, /* tasks */
+ GPIO11_GPIO, /* calendar */
+ GPIO13_GPIO, /* contacts */
+ GPIO14_GPIO, /* center */
+ GPIO19_GPIO, /* left */
+ GPIO20_GPIO, /* right */
+ GPIO21_GPIO, /* down */
+ GPIO22_GPIO, /* up */
+
+ /* MISC */
+ GPIO1_RST, /* reset */
+ GPIO4_GPIO, /* Hotsync button */
+ GPIO9_GPIO, /* power detect */
+ GPIO15_GPIO, /* earphone detect */
+ GPIO37_GPIO, /* LCD power */
+ GPIO56_GPIO, /* Backlight power */
+};
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+static struct pxamci_platform_data palmte2_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_card_detect = GPIO_NR_PALMTE2_SD_DETECT_N,
+ .gpio_card_ro = GPIO_NR_PALMTE2_SD_READONLY,
+ .gpio_power = GPIO_NR_PALMTE2_SD_POWER,
+};
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+static struct gpio_keys_button palmte2_pxa_buttons[] = {
+ {KEY_F1, GPIO_NR_PALMTE2_KEY_CONTACTS, 1, "Contacts" },
+ {KEY_F2, GPIO_NR_PALMTE2_KEY_CALENDAR, 1, "Calendar" },
+ {KEY_F3, GPIO_NR_PALMTE2_KEY_TASKS, 1, "Tasks" },
+ {KEY_F4, GPIO_NR_PALMTE2_KEY_NOTES, 1, "Notes" },
+ {KEY_ENTER, GPIO_NR_PALMTE2_KEY_CENTER, 1, "Center" },
+ {KEY_LEFT, GPIO_NR_PALMTE2_KEY_LEFT, 1, "Left" },
+ {KEY_RIGHT, GPIO_NR_PALMTE2_KEY_RIGHT, 1, "Right" },
+ {KEY_DOWN, GPIO_NR_PALMTE2_KEY_DOWN, 1, "Down" },
+ {KEY_UP, GPIO_NR_PALMTE2_KEY_UP, 1, "Up" },
+};
+
+static struct gpio_keys_platform_data palmte2_pxa_keys_data = {
+ .buttons = palmte2_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmte2_pxa_buttons),
+};
+
+static struct platform_device palmte2_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_pxa_keys_data,
+ },
+};
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+static struct gpio palmte_bl_gpios[] = {
+ { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
+ { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
+};
+
+static int palmte2_backlight_init(struct device *dev)
+{
+ return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
+}
+
+static int palmte2_backlight_notify(struct device *dev, int brightness)
+{
+ gpio_set_value(GPIO_NR_PALMTE2_BL_POWER, brightness);
+ gpio_set_value(GPIO_NR_PALMTE2_LCD_POWER, brightness);
+ return brightness;
+}
+
+static void palmte2_backlight_exit(struct device *dev)
+{
+ gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
+}
+
+static struct platform_pwm_backlight_data palmte2_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = PALMTE2_MAX_INTENSITY,
+ .dft_brightness = PALMTE2_MAX_INTENSITY,
+ .pwm_period_ns = PALMTE2_PERIOD_NS,
+ .init = palmte2_backlight_init,
+ .notify = palmte2_backlight_notify,
+ .exit = palmte2_backlight_exit,
+};
+
+static struct platform_device palmte2_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa25x_device_pwm0.dev,
+ .platform_data = &palmte2_backlight_data,
+ },
+};
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+static struct pxaficp_platform_data palmte2_ficp_platform_data = {
+ .gpio_pwdown = GPIO_NR_PALMTE2_IR_DISABLE,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+/******************************************************************************
+ * UDC
+ ******************************************************************************/
+static struct gpio_vbus_mach_info palmte2_udc_info = {
+ .gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N,
+ .gpio_vbus_inverted = 1,
+ .gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP,
+};
+
+static struct platform_device palmte2_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_udc_info,
+ },
+};
+
+/******************************************************************************
+ * Power supply
+ ******************************************************************************/
+static int power_supply_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_NR_PALMTE2_POWER_DETECT, "CABLE_STATE_AC");
+ if (ret)
+ goto err1;
+ ret = gpio_direction_input(GPIO_NR_PALMTE2_POWER_DETECT);
+ if (ret)
+ goto err2;
+
+ return 0;
+
+err2:
+ gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+err1:
+ return ret;
+}
+
+static int palmte2_is_ac_online(void)
+{
+ return gpio_get_value(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(GPIO_NR_PALMTE2_POWER_DETECT);
+}
+
+static char *palmte2_supplicants[] = {
+ "main-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = palmte2_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = palmte2_supplicants,
+ .num_supplicants = ARRAY_SIZE(palmte2_supplicants),
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+};
+
+/******************************************************************************
+ * WM97xx audio, battery
+ ******************************************************************************/
+static struct wm97xx_batt_pdata palmte2_batt_pdata = {
+ .batt_aux = WM97XX_AUX_ID3,
+ .temp_aux = WM97XX_AUX_ID2,
+ .charge_gpio = -1,
+ .max_voltage = PALMTE2_BAT_MAX_VOLTAGE,
+ .min_voltage = PALMTE2_BAT_MIN_VOLTAGE,
+ .batt_mult = 1000,
+ .batt_div = 414,
+ .temp_mult = 1,
+ .temp_div = 1,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO,
+ .batt_name = "main-batt",
+};
+
+static struct wm97xx_pdata palmte2_wm97xx_pdata = {
+ .batt_pdata = &palmte2_batt_pdata,
+};
+
+static pxa2xx_audio_ops_t palmte2_ac97_pdata = {
+ .codec_pdata = { &palmte2_wm97xx_pdata, },
+};
+
+static struct palm27x_asoc_info palmte2_asoc_pdata = {
+ .jack_gpio = GPIO_NR_PALMTE2_EARPHONE_DETECT,
+};
+
+static struct platform_device palmte2_asoc = {
+ .name = "palm27x-asoc",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmte2_asoc_pdata,
+ },
+};
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+static struct pxafb_mode_info palmte2_lcd_modes[] = {
+{
+ .pixclock = 77757,
+ .xres = 320,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 28,
+ .right_margin = 7,
+ .upper_margin = 7,
+ .lower_margin = 5,
+
+ .hsync_len = 4,
+ .vsync_len = 1,
+},
+};
+
+static struct pxafb_mach_info palmte2_lcd_screen = {
+ .modes = palmte2_lcd_modes,
+ .num_modes = ARRAY_SIZE(palmte2_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+ &palmte2_pxa_keys,
+#endif
+ &palmte2_backlight,
+ &power_supply,
+ &palmte2_asoc,
+ &palmte2_gpio_vbus,
+};
+
+/* setup udc GPIOs initial state */
+static void __init palmte2_udc_init(void)
+{
+ if (!gpio_request(GPIO_NR_PALMTE2_USB_PULLUP, "UDC Vbus")) {
+ gpio_direction_output(GPIO_NR_PALMTE2_USB_PULLUP, 1);
+ gpio_free(GPIO_NR_PALMTE2_USB_PULLUP);
+ }
+}
+
+static void __init palmte2_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmte2_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa_set_fb_info(NULL, &palmte2_lcd_screen);
+ pxa_set_mci_info(&palmte2_mci_platform_data);
+ palmte2_udc_init();
+ pxa_set_ac97_info(&palmte2_ac97_pdata);
+ pxa_set_ficp_info(&palmte2_ficp_platform_data);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+MACHINE_START(PALMTE2, "Palm Tungsten|E2")
+ .boot_params = 0xa0000100,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmte2_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
new file mode 100644
index 00000000..20d1b18b
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -0,0 +1,458 @@
+/*
+ * Hardware definitions for Palm Treo smartphones
+ *
+ * currently supported:
+ * Palm Treo 680 (GSM)
+ * Palm Centro 685 (GSM)
+ *
+ * Author: Tomas Cech <sleep_walker@suse.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/memblock.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/power_supply.h>
+#include <linux/w1-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/audio.h>
+#include <mach/palmtreo.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/ohci.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/palmasoc.h>
+#include <mach/camera.h>
+#include <mach/palm27x.h>
+
+#include <sound/pxa2xx-lib.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long treo_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO113_GPIO, /* SD detect */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO95_AC97_nRESET,
+
+ /* IrDA */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* USB */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* usb detect */
+
+ /* MATRIX KEYPAD */
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO97_KP_MKIN_3,
+ GPIO98_KP_MKIN_4,
+ GPIO91_KP_MKIN_6,
+ GPIO13_KP_MKIN_7,
+ GPIO103_KP_MKOUT_0 | MFP_LPM_DRIVE_HIGH,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+ GPIO96_KP_MKOUT_6,
+ GPIO93_KP_DKIN_0 | WAKEUP_ON_LEVEL_HIGH, /* Hotsync button */
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* Quick Capture Interface */
+ GPIO84_CIF_FV,
+ GPIO85_CIF_LV,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO81_CIF_DD_0,
+ GPIO55_CIF_DD_1,
+ GPIO51_CIF_DD_2,
+ GPIO50_CIF_DD_3,
+ GPIO52_CIF_DD_4,
+ GPIO48_CIF_DD_5,
+ GPIO17_CIF_DD_6,
+ GPIO12_CIF_DD_7,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* GSM */
+ GPIO14_GPIO | WAKEUP_ON_EDGE_BOTH, /* GSM host wake up */
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO39_FFUART_TXD,
+ GPIO41_FFUART_RTS,
+
+ /* MISC. */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, /* external power detect */
+ GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH, /* silent switch */
+ GPIO116_GPIO, /* headphone detect */
+ GPIO11_GPIO | WAKEUP_ON_EDGE_BOTH, /* bluetooth host wake up */
+};
+
+#ifdef CONFIG_MACH_TREO680
+static unsigned long treo680_pin_config[] __initdata = {
+ GPIO33_GPIO, /* SD read only */
+
+ /* MATRIX KEYPAD - different wake up source */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO99_KP_MKIN_5,
+};
+#endif /* CONFIG_MACH_TREO680 */
+
+#ifdef CONFIG_MACH_CENTRO
+static unsigned long centro685_pin_config[] __initdata = {
+ /* Bluetooth attached to BT UART*/
+ MFP_CFG_OUT(GPIO80, AF0, DRIVE_LOW), /* power: LOW = off */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* MATRIX KEYPAD - different wake up source */
+ GPIO100_KP_MKIN_0,
+ GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
+};
+#endif /* CONFIG_MACH_CENTRO */
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int treo680_matrix_keys[] = {
+ KEY(0, 0, KEY_F8), /* Red/Off/Power */
+ KEY(0, 1, KEY_LEFT),
+ KEY(0, 2, KEY_LEFTCTRL), /* Alternate */
+ KEY(0, 3, KEY_L),
+ KEY(0, 4, KEY_A),
+ KEY(0, 5, KEY_Q),
+ KEY(0, 6, KEY_P),
+
+ KEY(1, 0, KEY_RIGHTCTRL), /* Menu */
+ KEY(1, 1, KEY_RIGHT),
+ KEY(1, 2, KEY_LEFTSHIFT), /* Left shift */
+ KEY(1, 3, KEY_Z),
+ KEY(1, 4, KEY_S),
+ KEY(1, 5, KEY_W),
+
+ KEY(2, 0, KEY_F1), /* Phone */
+ KEY(2, 1, KEY_UP),
+ KEY(2, 2, KEY_0),
+ KEY(2, 3, KEY_X),
+ KEY(2, 4, KEY_D),
+ KEY(2, 5, KEY_E),
+
+ KEY(3, 0, KEY_F10), /* Calendar */
+ KEY(3, 1, KEY_DOWN),
+ KEY(3, 2, KEY_SPACE),
+ KEY(3, 3, KEY_C),
+ KEY(3, 4, KEY_F),
+ KEY(3, 5, KEY_R),
+
+ KEY(4, 0, KEY_F12), /* Mail */
+ KEY(4, 1, KEY_KPENTER),
+ KEY(4, 2, KEY_RIGHTALT), /* Alt */
+ KEY(4, 3, KEY_V),
+ KEY(4, 4, KEY_G),
+ KEY(4, 5, KEY_T),
+
+ KEY(5, 0, KEY_F9), /* Home */
+ KEY(5, 1, KEY_PAGEUP), /* Side up */
+ KEY(5, 2, KEY_DOT),
+ KEY(5, 3, KEY_B),
+ KEY(5, 4, KEY_H),
+ KEY(5, 5, KEY_Y),
+
+ KEY(6, 0, KEY_TAB), /* Side Activate */
+ KEY(6, 1, KEY_PAGEDOWN), /* Side down */
+ KEY(6, 2, KEY_ENTER),
+ KEY(6, 3, KEY_N),
+ KEY(6, 4, KEY_J),
+ KEY(6, 5, KEY_U),
+
+ KEY(7, 0, KEY_F6), /* Green/Call */
+ KEY(7, 1, KEY_O),
+ KEY(7, 2, KEY_BACKSPACE),
+ KEY(7, 3, KEY_M),
+ KEY(7, 4, KEY_K),
+ KEY(7, 5, KEY_I),
+};
+
+static unsigned int centro_matrix_keys[] = {
+ KEY(0, 0, KEY_F9), /* Home */
+ KEY(0, 1, KEY_LEFT),
+ KEY(0, 2, KEY_LEFTCTRL), /* Alternate */
+ KEY(0, 3, KEY_L),
+ KEY(0, 4, KEY_A),
+ KEY(0, 5, KEY_Q),
+ KEY(0, 6, KEY_P),
+
+ KEY(1, 0, KEY_RIGHTCTRL), /* Menu */
+ KEY(1, 1, KEY_RIGHT),
+ KEY(1, 2, KEY_LEFTSHIFT), /* Left shift */
+ KEY(1, 3, KEY_Z),
+ KEY(1, 4, KEY_S),
+ KEY(1, 5, KEY_W),
+
+ KEY(2, 0, KEY_F1), /* Phone */
+ KEY(2, 1, KEY_UP),
+ KEY(2, 2, KEY_0),
+ KEY(2, 3, KEY_X),
+ KEY(2, 4, KEY_D),
+ KEY(2, 5, KEY_E),
+
+ KEY(3, 0, KEY_F10), /* Calendar */
+ KEY(3, 1, KEY_DOWN),
+ KEY(3, 2, KEY_SPACE),
+ KEY(3, 3, KEY_C),
+ KEY(3, 4, KEY_F),
+ KEY(3, 5, KEY_R),
+
+ KEY(4, 0, KEY_F12), /* Mail */
+ KEY(4, 1, KEY_KPENTER),
+ KEY(4, 2, KEY_RIGHTALT), /* Alt */
+ KEY(4, 3, KEY_V),
+ KEY(4, 4, KEY_G),
+ KEY(4, 5, KEY_T),
+
+ KEY(5, 0, KEY_F8), /* Red/Off/Power */
+ KEY(5, 1, KEY_PAGEUP), /* Side up */
+ KEY(5, 2, KEY_DOT),
+ KEY(5, 3, KEY_B),
+ KEY(5, 4, KEY_H),
+ KEY(5, 5, KEY_Y),
+
+ KEY(6, 0, KEY_TAB), /* Side Activate */
+ KEY(6, 1, KEY_PAGEDOWN), /* Side down */
+ KEY(6, 2, KEY_ENTER),
+ KEY(6, 3, KEY_N),
+ KEY(6, 4, KEY_J),
+ KEY(6, 5, KEY_U),
+
+ KEY(7, 0, KEY_F6), /* Green/Call */
+ KEY(7, 1, KEY_O),
+ KEY(7, 2, KEY_BACKSPACE),
+ KEY(7, 3, KEY_M),
+ KEY(7, 4, KEY_K),
+ KEY(7, 5, KEY_I),
+};
+
+static struct pxa27x_keypad_platform_data treo680_keypad_pdata = {
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 7,
+ .matrix_key_map = treo680_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(treo680_matrix_keys),
+ .direct_key_map = { KEY_CONNECT },
+ .direct_key_num = 1,
+
+ .debounce_interval = 30,
+};
+
+static void __init palmtreo_kpc_init(void)
+{
+ static struct pxa27x_keypad_platform_data *data = &treo680_keypad_pdata;
+
+ if (machine_is_centro()) {
+ data->matrix_key_map = centro_matrix_keys;
+ data->matrix_key_map_size = ARRAY_SIZE(centro_matrix_keys);
+ }
+
+ pxa_set_keypad_info(&treo680_keypad_pdata);
+}
+#else
+static inline void palmtreo_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data treo680_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT3,
+ .power_budget = 0,
+};
+
+static void __init palmtreo_uhc_init(void)
+{
+ if (machine_is_treo680())
+ pxa_set_ohci_info(&treo680_ohci_info);
+}
+#else
+static inline void palmtreo_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Vibra and LEDs
+ ******************************************************************************/
+#ifdef CONFIG_MACH_TREO680
+static struct gpio_led treo680_gpio_leds[] = {
+ {
+ .name = "treo680:vibra:vibra",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_TREO680_VIBRATE_EN,
+ },
+ {
+ .name = "treo680:green:led",
+ .default_trigger = "mmc0",
+ .gpio = GPIO_NR_TREO_GREEN_LED,
+ },
+ {
+ .name = "treo680:white:keybbl",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_TREO680_KEYB_BL,
+ },
+};
+
+static struct gpio_led_platform_data treo680_gpio_led_info = {
+ .leds = treo680_gpio_leds,
+ .num_leds = ARRAY_SIZE(treo680_gpio_leds),
+};
+
+static struct gpio_led centro_gpio_leds[] = {
+ {
+ .name = "centro:vibra:vibra",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_CENTRO_VIBRATE_EN,
+ },
+ {
+ .name = "centro:green:led",
+ .default_trigger = "mmc0",
+ .gpio = GPIO_NR_TREO_GREEN_LED,
+ },
+ {
+ .name = "centro:white:keybbl",
+ .default_trigger = "none",
+ .active_low = 1,
+ .gpio = GPIO_NR_CENTRO_KEYB_BL,
+ },
+};
+
+static struct gpio_led_platform_data centro_gpio_led_info = {
+ .leds = centro_gpio_leds,
+ .num_leds = ARRAY_SIZE(centro_gpio_leds),
+};
+
+static struct platform_device palmtreo_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &treo680_gpio_led_info,
+ }
+};
+
+static void __init palmtreo_leds_init(void)
+{
+ if (machine_is_centro())
+ palmtreo_leds.dev.platform_data = &centro_gpio_led_info;
+
+ platform_device_register(&palmtreo_leds);
+}
+#else
+static inline void palmtreo_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init treo_reserve(void)
+{
+ memblock_reserve(0xa0000000, 0x1000);
+ memblock_reserve(0xa2000000, 0x1000);
+}
+
+static void __init palmphone_common_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(treo_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ palm27x_pm_init(TREO_STR_BASE);
+ palm27x_lcd_init(GPIO_NR_TREO_BL_POWER, &palm_320x320_new_lcd_mode);
+ palm27x_udc_init(GPIO_NR_TREO_USB_DETECT, GPIO_NR_TREO_USB_PULLUP, 1);
+ palm27x_irda_init(GPIO_NR_TREO_IR_EN);
+ palm27x_ac97_init(-1, -1, -1, 95);
+ palm27x_pwm_init(GPIO_NR_TREO_BL_POWER, -1);
+ palm27x_power_init(GPIO_NR_TREO_POWER_DETECT, -1);
+ palm27x_pmic_init();
+ palmtreo_kpc_init();
+ palmtreo_uhc_init();
+ palmtreo_leds_init();
+}
+
+static void __init treo680_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(treo680_pin_config));
+ palmphone_common_init();
+ palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
+ GPIO_NR_TREO680_SD_POWER, 0);
+}
+
+static void __init centro_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(centro685_pin_config));
+ palmphone_common_init();
+ palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, -1,
+ GPIO_NR_CENTRO_SD_POWER, 1);
+}
+
+MACHINE_START(TREO680, "Palm Treo 680")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .reserve = treo_reserve,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = treo680_init,
+MACHINE_END
+
+MACHINE_START(CENTRO, "Palm Centro 685")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .reserve = treo_reserve,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = centro_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c
new file mode 100644
index 00000000..595f0020
--- /dev/null
+++ b/arch/arm/mach-pxa/palmtx.c
@@ -0,0 +1,372 @@
+/*
+ * Hardware definitions for PalmTX
+ *
+ * Author: Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on work of:
+ * Alex Osborne <ato@meshy.org>
+ * Cristiano P. <cristianop@users.sourceforge.net>
+ * Jan Herman <2hp@seznam.cz>
+ * Michal Hrusecky
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmtx.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+#include <mach/palm27x.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmtx_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO114_GPIO, /* SD power */
+ GPIO115_GPIO, /* SD r/o switch */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO95_AC97_nRESET,
+
+ /* IrDA */
+ GPIO40_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* USB */
+ GPIO13_GPIO, /* usb detect */
+ GPIO93_GPIO, /* usb power */
+
+ /* PCMCIA */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO94_GPIO, /* wifi power 1 */
+ GPIO108_GPIO, /* wifi power 2 */
+ GPIO116_GPIO, /* wifi ready */
+
+ /* MATRIX KEYPAD */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO39_FFUART_TXD,
+
+ /* NAND */
+ GPIO15_nCS_1,
+ GPIO18_RDY,
+
+ /* MISC. */
+ GPIO10_GPIO, /* hotsync button */
+ GPIO12_GPIO, /* power detect */
+ GPIO107_GPIO, /* earphone detect */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition palmtx_partitions[] = {
+ {
+ .name = "Flash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0
+ }
+};
+
+static struct physmap_flash_data palmtx_flash_data[] = {
+ {
+ .width = 2, /* bankwidth in bytes */
+ .parts = palmtx_partitions,
+ .nr_parts = ARRAY_SIZE(palmtx_partitions)
+ }
+};
+
+static struct resource palmtx_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device palmtx_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &palmtx_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = palmtx_flash_data,
+ },
+};
+
+static void __init palmtx_nor_init(void)
+{
+ platform_device_register(&palmtx_flash);
+}
+#else
+static inline void palmtx_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int palmtx_matrix_keys[] = {
+ KEY(0, 0, KEY_POWER),
+ KEY(0, 1, KEY_F1),
+ KEY(0, 2, KEY_ENTER),
+
+ KEY(1, 0, KEY_F2),
+ KEY(1, 1, KEY_F3),
+ KEY(1, 2, KEY_F4),
+
+ KEY(2, 0, KEY_UP),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_RIGHT),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmtx_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmtx_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+static void __init palmtx_kpc_init(void)
+{
+ pxa_set_keypad_info(&palmtx_keypad_platform_data);
+}
+#else
+static inline void palmtx_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button palmtx_pxa_buttons[] = {
+ {KEY_F8, GPIO_NR_PALMTX_HOTSYNC_BUTTON_N, 1, "HotSync Button" },
+};
+
+static struct gpio_keys_platform_data palmtx_pxa_keys_data = {
+ .buttons = palmtx_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(palmtx_pxa_buttons),
+};
+
+static struct platform_device palmtx_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtx_pxa_keys_data,
+ },
+};
+
+static void __init palmtx_keys_init(void)
+{
+ platform_device_register(&palmtx_pxa_keys);
+}
+#else
+static inline void palmtx_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * NAND Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_NAND_PLATFORM) || \
+ defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ writeb(cmd, PALMTX_NAND_CLE_VIRT);
+ else if (ctrl & NAND_ALE)
+ writeb(cmd, PALMTX_NAND_ALE_VIRT);
+ else
+ writeb(cmd, nandaddr);
+}
+
+static struct mtd_partition palmtx_partition_info[] = {
+ [0] = {
+ .name = "palmtx-0",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static const char *palmtx_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data palmtx_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(palmtx_partition_info),
+ .partitions = palmtx_partition_info,
+ .chip_delay = 20,
+ .part_probe_types = palmtx_part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = palmtx_nand_cmd_ctl,
+ },
+};
+
+static struct resource palmtx_nand_resource[] = {
+ [0] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device palmtx_nand = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(palmtx_nand_resource),
+ .resource = palmtx_nand_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &palmtx_nand_platdata,
+ }
+};
+
+static void __init palmtx_nand_init(void)
+{
+ platform_device_register(&palmtx_nand);
+}
+#else
+static inline void palmtx_nand_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static struct map_desc palmtx_io_desc[] __initdata = {
+{
+ .virtual = PALMTX_PCMCIA_VIRT,
+ .pfn = __phys_to_pfn(PALMTX_PCMCIA_PHYS),
+ .length = PALMTX_PCMCIA_SIZE,
+ .type = MT_DEVICE,
+}, {
+ .virtual = PALMTX_NAND_ALE_VIRT,
+ .pfn = __phys_to_pfn(PALMTX_NAND_ALE_PHYS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+}, {
+ .virtual = PALMTX_NAND_CLE_VIRT,
+ .pfn = __phys_to_pfn(PALMTX_NAND_CLE_PHYS),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+}
+};
+
+static void __init palmtx_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
+}
+
+static void __init palmtx_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ palm27x_mmc_init(GPIO_NR_PALMTX_SD_DETECT_N, GPIO_NR_PALMTX_SD_READONLY,
+ GPIO_NR_PALMTX_SD_POWER, 0);
+ palm27x_pm_init(PALMTX_STR_BASE);
+ palm27x_lcd_init(-1, &palm_320x480_lcd_mode);
+ palm27x_udc_init(GPIO_NR_PALMTX_USB_DETECT_N,
+ GPIO_NR_PALMTX_USB_PULLUP, 1);
+ palm27x_irda_init(GPIO_NR_PALMTX_IR_DISABLE);
+ palm27x_ac97_init(PALMTX_BAT_MIN_VOLTAGE, PALMTX_BAT_MAX_VOLTAGE,
+ GPIO_NR_PALMTX_EARPHONE_DETECT, 95);
+ palm27x_pwm_init(GPIO_NR_PALMTX_BL_POWER, GPIO_NR_PALMTX_LCD_POWER);
+ palm27x_power_init(GPIO_NR_PALMTX_POWER_DETECT, -1);
+ palm27x_pmic_init();
+ palmtx_kpc_init();
+ palmtx_keys_init();
+ palmtx_nor_init();
+ palmtx_nand_init();
+}
+
+MACHINE_START(PALMTX, "Palm T|X")
+ .boot_params = 0xa0000100,
+ .map_io = palmtx_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmtx_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
new file mode 100644
index 00000000..65f24f0b
--- /dev/null
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -0,0 +1,406 @@
+/*
+ * Hardware definitions for Palm Zire72
+ *
+ * Authors:
+ * Vladimir "Farcaller" Pouzanov <farcaller@gmail.com>
+ * Sergey Lapin <slapin@ossfans.org>
+ * Alex Osborne <bobofdoom@gmail.com>
+ * Jan Herman <2hp@seznam.cz>
+ *
+ * Rewrite for mainline:
+ * Marek Vasut <marek.vasut@gmail.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.
+ *
+ * (find more info at www.hackndev.com)
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/gpio.h>
+#include <linux/wm97xx.h>
+#include <linux/power_supply.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/palmz72.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/irda.h>
+#include <plat/pxa27x_keypad.h>
+#include <mach/udc.h>
+#include <mach/palmasoc.h>
+#include <mach/palm27x.h>
+
+#include <mach/pm.h>
+#include <mach/camera.h>
+
+#include <media/soc_camera.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long palmz72_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO14_GPIO, /* SD detect */
+ GPIO115_GPIO, /* SD RO */
+ GPIO98_GPIO, /* SD power */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO89_AC97_SYSCLK,
+ GPIO113_AC97_nRESET,
+
+ /* IrDA */
+ GPIO49_GPIO, /* ir disable */
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+
+ /* PWM */
+ GPIO16_PWM0_OUT,
+
+ /* USB */
+ GPIO15_GPIO, /* usb detect */
+ GPIO95_GPIO, /* usb pullup */
+
+ /* Matrix keypad */
+ GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO97_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ GPIO20_GPIO, /* bl power */
+ GPIO21_GPIO, /* LCD border switch */
+ GPIO22_GPIO, /* LCD border color */
+ GPIO96_GPIO, /* lcd power */
+
+ /* PXA Camera */
+ GPIO81_CIF_DD_0,
+ GPIO48_CIF_DD_5,
+ GPIO50_CIF_DD_3,
+ GPIO51_CIF_DD_2,
+ GPIO52_CIF_DD_4,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO55_CIF_DD_1,
+ GPIO84_CIF_FV,
+ GPIO85_CIF_LV,
+ GPIO93_CIF_DD_6,
+ GPIO108_CIF_DD_7,
+
+ GPIO56_GPIO, /* OV9640 Powerdown */
+ GPIO57_GPIO, /* OV9640 Reset */
+ GPIO91_GPIO, /* OV9640 Power */
+
+ /* I2C */
+ GPIO117_GPIO, /* I2C_SCL */
+ GPIO118_GPIO, /* I2C_SDA */
+
+ /* Misc. */
+ GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */
+ GPIO88_GPIO, /* green led */
+ GPIO27_GPIO, /* WM9712 IRQ */
+};
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int palmz72_matrix_keys[] = {
+ KEY(0, 0, KEY_POWER),
+ KEY(0, 1, KEY_F1),
+ KEY(0, 2, KEY_ENTER),
+
+ KEY(1, 0, KEY_F2),
+ KEY(1, 1, KEY_F3),
+ KEY(1, 2, KEY_F4),
+
+ KEY(2, 0, KEY_UP),
+ KEY(2, 2, KEY_DOWN),
+
+ KEY(3, 0, KEY_RIGHT),
+ KEY(3, 2, KEY_LEFT),
+};
+
+static struct pxa27x_keypad_platform_data palmz72_keypad_platform_data = {
+ .matrix_key_rows = 4,
+ .matrix_key_cols = 3,
+ .matrix_key_map = palmz72_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(palmz72_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+static void __init palmz72_kpc_init(void)
+{
+ pxa_set_keypad_info(&palmz72_keypad_platform_data);
+}
+#else
+static inline void palmz72_kpc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "palmz72:green:led",
+ .default_trigger = "none",
+ .gpio = GPIO_NR_PALMZ72_LED_GREEN,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device palmz72_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ }
+};
+
+static void __init palmz72_leds_init(void)
+{
+ platform_device_register(&palmz72_leds);
+}
+#else
+static inline void palmz72_leds_init(void) {}
+#endif
+
+#ifdef CONFIG_PM
+
+/* We have some black magic here
+ * PalmOS ROM on recover expects special struct physical address
+ * to be transferred via PSPR. Using this struct PalmOS restores
+ * its state after sleep. As for Linux, we need to setup it the
+ * same way. More than that, PalmOS ROM changes some values in memory.
+ * For now only one location is found, which needs special treatment.
+ * Thanks to Alex Osborne, Andrzej Zaborowski, and lots of other people
+ * for reading backtraces for me :)
+ */
+
+#define PALMZ72_SAVE_DWORD ((unsigned long *)0xc0000050)
+
+static struct palmz72_resume_info palmz72_resume_info = {
+ .magic0 = 0xb4e6,
+ .magic1 = 1,
+
+ /* reset state, MMU off etc */
+ .arm_control = 0,
+ .aux_control = 0,
+ .ttb = 0,
+ .domain_access = 0,
+ .process_id = 0,
+};
+
+static unsigned long store_ptr;
+
+/* syscore_ops for Palm Zire 72 PM */
+
+static int palmz72_pm_suspend(void)
+{
+ /* setup the resume_info struct for the original bootloader */
+ palmz72_resume_info.resume_addr = (u32) cpu_resume;
+
+ /* Storing memory touched by ROM */
+ store_ptr = *PALMZ72_SAVE_DWORD;
+
+ /* Setting PSPR to a proper value */
+ PSPR = virt_to_phys(&palmz72_resume_info);
+
+ return 0;
+}
+
+static void palmz72_pm_resume(void)
+{
+ *PALMZ72_SAVE_DWORD = store_ptr;
+}
+
+static struct syscore_ops palmz72_pm_syscore_ops = {
+ .suspend = palmz72_pm_suspend,
+ .resume = palmz72_pm_resume,
+};
+
+static int __init palmz72_pm_init(void)
+{
+ if (machine_is_palmz72()) {
+ register_syscore_ops(&palmz72_pm_syscore_ops);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+device_initcall(palmz72_pm_init);
+#endif
+
+/******************************************************************************
+ * SoC Camera
+ ******************************************************************************/
+#if defined(CONFIG_SOC_CAMERA_OV9640) || \
+ defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
+static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 2600,
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info palmz72_i2c_device[] = {
+ {
+ I2C_BOARD_INFO("ov9640", 0x30),
+ }
+};
+
+static int palmz72_camera_power(struct device *dev, int power)
+{
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
+ mdelay(50);
+ return 0;
+}
+
+static int palmz72_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
+ mdelay(50);
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
+ mdelay(50);
+ return 0;
+}
+
+static struct soc_camera_link palmz72_iclink = {
+ .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
+ .board_info = &palmz72_i2c_device[0],
+ .i2c_adapter_id = 0,
+ .module_name = "ov96xx",
+ .power = &palmz72_camera_power,
+ .reset = &palmz72_camera_reset,
+ .flags = SOCAM_DATAWIDTH_8,
+};
+
+static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
+ .sda_pin = 118,
+ .scl_pin = 117,
+ .udelay = 10,
+ .timeout = 100,
+};
+
+static struct platform_device palmz72_i2c_bus_device = {
+ .name = "i2c-gpio",
+ .id = 0, /* we use this as a replacement for i2c-pxa */
+ .dev = {
+ .platform_data = &palmz72_i2c_bus_data,
+ }
+};
+
+static struct platform_device palmz72_camera = {
+ .name = "soc-camera-pdrv",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz72_iclink,
+ },
+};
+
+/* Here we request the camera GPIOs and configure them. We power up the camera
+ * module, deassert the reset pin, but put it into powerdown (low to no power
+ * consumption) mode. This allows us to later bring the module up fast. */
+static struct gpio palmz72_camera_gpios[] = {
+ { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" },
+ { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" },
+ { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" },
+};
+
+static inline void __init palmz72_cam_gpio_init(void)
+{
+ int ret;
+
+ ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+ if (!ret)
+ gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+ else
+ printk(KERN_ERR "Camera GPIO init failed!\n");
+
+ return;
+}
+
+static void __init palmz72_camera_init(void)
+{
+ palmz72_cam_gpio_init();
+ pxa_set_camera_info(&palmz72_pxacamera_platform_data);
+ platform_device_register(&palmz72_i2c_bus_device);
+ platform_device_register(&palmz72_camera);
+}
+#else
+static inline void palmz72_camera_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init palmz72_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(palmz72_pin_config));
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ palm27x_mmc_init(GPIO_NR_PALMZ72_SD_DETECT_N, GPIO_NR_PALMZ72_SD_RO,
+ GPIO_NR_PALMZ72_SD_POWER_N, 1);
+ palm27x_lcd_init(-1, &palm_320x320_lcd_mode);
+ palm27x_udc_init(GPIO_NR_PALMZ72_USB_DETECT_N,
+ GPIO_NR_PALMZ72_USB_PULLUP, 0);
+ palm27x_irda_init(GPIO_NR_PALMZ72_IR_DISABLE);
+ palm27x_ac97_init(PALMZ72_BAT_MIN_VOLTAGE, PALMZ72_BAT_MAX_VOLTAGE,
+ -1, 113);
+ palm27x_pwm_init(-1, -1);
+ palm27x_power_init(-1, -1);
+ palm27x_pmic_init();
+ palmz72_kpc_init();
+ palmz72_leds_init();
+ palmz72_camera_init();
+}
+
+MACHINE_START(PALMZ72, "Palm Zire72")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = palmz72_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm027.c b/arch/arm/mach-pxa/pcm027.c
new file mode 100644
index 00000000..1fc8a664
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm027.c
@@ -0,0 +1,267 @@
+/*
+ * linux/arch/arm/mach-pxa/pcm027.c
+ * Support for the Phytec phyCORE-PXA270 CPU card (aka PCM-027).
+ *
+ * Refer
+ * http://www.phytec.com/products/sbc/ARM-XScale/phyCORE-XScale-PXA270.html
+ * for additional hardware info
+ *
+ * Author: Juergen Kilb
+ * Created: April 05, 2005
+ * Copyright: Phytec Messtechnik GmbH
+ * e-Mail: armlinux@phytec.de
+ *
+ * based on Intel Mainstone Board
+ *
+ * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/max7301.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/leds.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/pxa27x.h>
+#include <mach/pcm027.h>
+#include "generic.h"
+
+/*
+ * ABSTRACT:
+ *
+ * The PXA270 processor comes with a bunch of hardware on its silicon.
+ * Not all of this hardware can be used at the same time and not all
+ * is routed to module's connectors. Also it depends on the baseboard, what
+ * kind of hardware can be used in which way.
+ * -> So this file supports the main devices on the CPU card only!
+ * Refer pcm990-baseboard.c how to extend this features to get a full
+ * blown system with many common interfaces.
+ *
+ * The PCM-027 supports the following interfaces through its connectors and
+ * will be used in pcm990-baseboard.c:
+ *
+ * - LCD support
+ * - MMC support
+ * - IDE/CF card
+ * - FFUART
+ * - BTUART
+ * - IRUART
+ * - AC97
+ * - SSP
+ * - SSP3
+ *
+ * Claimed GPIOs:
+ * GPIO0 -> IRQ input from RTC
+ * GPIO2 -> SYS_ENA*)
+ * GPIO3 -> PWR_SCL
+ * GPIO4 -> PWR_SDA
+ * GPIO5 -> PowerCap0*)
+ * GPIO6 -> PowerCap1*)
+ * GPIO7 -> PowerCap2*)
+ * GPIO8 -> PowerCap3*)
+ * GPIO15 -> /CS1
+ * GPIO20 -> /CS2
+ * GPIO21 -> /CS3
+ * GPIO33 -> /CS5 network controller select
+ * GPIO52 -> IRQ from network controller
+ * GPIO78 -> /CS2
+ * GPIO80 -> /CS4
+ * GPIO90 -> LED0
+ * GPIO91 -> LED1
+ * GPIO114 -> IRQ from CAN controller
+ * GPIO117 -> SCL
+ * GPIO118 -> SDA
+ *
+ * *) CPU internal use only
+ */
+
+static unsigned long pcm027_pin_config[] __initdata = {
+ /* Chip Selects */
+ GPIO20_nSDCS_2,
+ GPIO21_nSDCS_3,
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO80_nCS_4,
+ GPIO33_nCS_5, /* Ethernet */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* GPIO */
+ GPIO52_GPIO, /* IRQ from network controller */
+#ifdef CONFIG_LEDS_GPIO
+ GPIO90_GPIO, /* PCM027_LED_CPU */
+ GPIO91_GPIO, /* PCM027_LED_HEART_BEAT */
+#endif
+ GPIO114_GPIO, /* IRQ from CAN controller */
+};
+
+/*
+ * SMC91x network controller specific stuff
+ */
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = PCM027_ETH_PHYS + 0x300,
+ .end = PCM027_ETH_PHYS + PCM027_ETH_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PCM027_ETH_IRQ,
+ .end = PCM027_ETH_IRQ,
+ /* note: smc91x's driver doesn't use the trigger bits yet */
+ .flags = IORESOURCE_IRQ | PCM027_ETH_IRQ_EDGE,
+ }
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+/*
+ * SPI host and devices
+ */
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+ .num_chipselect = 1,
+};
+
+static struct max7301_platform_data max7301_info = {
+ .base = -1,
+};
+
+/* bus_num must match id in pxa2xx_set_spi_info() call */
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "max7301",
+ .platform_data = &max7301_info,
+ .max_speed_hz = 13000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+/*
+ * NOR flash
+ */
+static struct physmap_flash_data pcm027_flash_data = {
+ .width = 4,
+};
+
+static struct resource pcm027_flash_resource = {
+ .start = PCM027_FLASH_PHYS,
+ .end = PCM027_FLASH_PHYS + PCM027_FLASH_SIZE - 1 ,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device pcm027_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm027_flash_data,
+ },
+ .resource = &pcm027_flash_resource,
+ .num_resources = 1,
+};
+
+#ifdef CONFIG_LEDS_GPIO
+
+static struct gpio_led pcm027_led[] = {
+ {
+ .name = "led0:red", /* FIXME */
+ .gpio = PCM027_LED_CPU
+ },
+ {
+ .name = "led1:green", /* FIXME */
+ .gpio = PCM027_LED_HEARD_BEAT
+ },
+};
+
+static struct gpio_led_platform_data pcm027_led_data = {
+ .num_leds = ARRAY_SIZE(pcm027_led),
+ .leds = pcm027_led
+};
+
+static struct platform_device pcm027_led_dev = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &pcm027_led_data,
+ },
+};
+
+#endif /* CONFIG_LEDS_GPIO */
+
+/*
+ * declare the available device resources on this board
+ */
+static struct platform_device *devices[] __initdata = {
+ &smc91x_device,
+ &pcm027_flash,
+#ifdef CONFIG_LEDS_GPIO
+ &pcm027_led_dev
+#endif
+};
+
+/*
+ * pcm027_init - breath some life into the board
+ */
+static void __init pcm027_init(void)
+{
+ /* system bus arbiter setting
+ * - Core_Park
+ * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+ */
+ ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
+ pxa2xx_mfp_config(pcm027_pin_config, ARRAY_SIZE(pcm027_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ /* at last call the baseboard to initialize itself */
+#ifdef CONFIG_MACH_PCM990_BASEBOARD
+ pcm990_baseboard_init();
+#endif
+
+ pxa2xx_set_spi_info(1, &pxa_ssp_master_info);
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
+static void __init pcm027_map_io(void)
+{
+ pxa27x_map_io();
+
+ /* initialize sleep mode regs (wake-up sources, etc) */
+ PGSR0 = 0x01308000;
+ PGSR1 = 0x00CF0002;
+ PGSR2 = 0x0E294000;
+ PGSR3 = 0x0000C000;
+ PWER = 0x40000000 | PWER_GPIO0 | PWER_GPIO1;
+ PRER = 0x00000000;
+ PFER = 0x00000003;
+}
+
+MACHINE_START(PCM027, "Phytec Messtechnik GmbH phyCORE-PXA270")
+ /* Maintainer: Pengutronix */
+ .boot_params = 0xa0000100,
+ .map_io = pcm027_map_io,
+ .nr_irqs = PCM027_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = pcm027_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
new file mode 100644
index 00000000..6d5b7e06
--- /dev/null
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -0,0 +1,542 @@
+/*
+ * arch/arm/mach-pxa/pcm990-baseboard.c
+ * Support for the Phytec phyCORE-PXA270 Development Platform (PCM-990).
+ *
+ * Refer
+ * http://www.phytec.com/products/rdk/ARM-XScale/phyCORE-XScale-PXA270.html
+ * for additional hardware info
+ *
+ * Author: Juergen Kilb
+ * Created: April 05, 2005
+ * Copyright: Phytec Messtechnik GmbH
+ * e-Mail: armlinux@phytec.de
+ *
+ * based on Intel Mainstone Board
+ *
+ * Copyright 2007 Juergen Beisert @ Pengutronix (j.beisert@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/pwm_backlight.h>
+
+#include <media/soc_camera.h>
+
+#include <asm/gpio.h>
+#include <mach/camera.h>
+#include <asm/mach/map.h>
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pcm990_baseboard.h>
+#include <mach/pxafb.h>
+
+#include "devices.h"
+#include "generic.h"
+
+static unsigned long pcm990_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ /* USB */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+ /* PWM0 */
+ GPIO16_PWM0_OUT,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+};
+
+/*
+ * pcm990_lcd_power - control power supply to the LCD
+ * @on: 0 = switch off, 1 = switch on
+ *
+ * Called by the pxafb driver
+ */
+#ifndef CONFIG_PCM990_DISPLAY_NONE
+static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+ if (on) {
+ /* enable LCD-Latches
+ * power on LCD
+ */
+ __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) =
+ PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON;
+ } else {
+ /* disable LCD-Latches
+ * power off LCD
+ */
+ __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = 0x00;
+ }
+}
+#endif
+
+#if defined(CONFIG_PCM990_DISPLAY_SHARP)
+static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = {
+ .pixclock = 28000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 20,
+ .left_margin = 103,
+ .right_margin = 47,
+ .vsync_len = 6,
+ .upper_margin = 28,
+ .lower_margin = 5,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info pcm990_fbinfo __initdata = {
+ .modes = &fb_info_sharp_lq084v1dg21,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = pcm990_lcd_power,
+};
+#elif defined(CONFIG_PCM990_DISPLAY_NEC)
+struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = {
+ .pixclock = 39720,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 32,
+ .left_margin = 16,
+ .right_margin = 48,
+ .vsync_len = 2,
+ .upper_margin = 12,
+ .lower_margin = 17,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info pcm990_fbinfo __initdata = {
+ .modes = &fb_info_nec_nl6448bc20_18d,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = pcm990_lcd_power,
+};
+#endif
+
+static struct platform_pwm_backlight_data pcm990_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 1023,
+ .dft_brightness = 1023,
+ .pwm_period_ns = 78770,
+};
+
+static struct platform_device pcm990_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &pcm990_backlight_data,
+ },
+};
+
+/*
+ * The PCM-990 development baseboard uses PCM-027's hardware in the
+ * following way:
+ *
+ * - LCD support is in use
+ * - GPIO16 is output for back light on/off with PWM
+ * - GPIO58 ... GPIO73 are outputs for display data
+ * - GPIO74 is output output for LCDFCLK
+ * - GPIO75 is output for LCDLCLK
+ * - GPIO76 is output for LCDPCLK
+ * - GPIO77 is output for LCDBIAS
+ * - MMC support is in use
+ * - GPIO32 is output for MMCCLK
+ * - GPIO92 is MMDAT0
+ * - GPIO109 is MMDAT1
+ * - GPIO110 is MMCS0
+ * - GPIO111 is MMCS1
+ * - GPIO112 is MMCMD
+ * - IDE/CF card is in use
+ * - GPIO48 is output /POE
+ * - GPIO49 is output /PWE
+ * - GPIO50 is output /PIOR
+ * - GPIO51 is output /PIOW
+ * - GPIO54 is output /PCE2
+ * - GPIO55 is output /PREG
+ * - GPIO56 is input /PWAIT
+ * - GPIO57 is output /PIOS16
+ * - GPIO79 is output PSKTSEL
+ * - GPIO85 is output /PCE1
+ * - FFUART is in use
+ * - GPIO34 is input FFRXD
+ * - GPIO35 is input FFCTS
+ * - GPIO36 is input FFDCD
+ * - GPIO37 is input FFDSR
+ * - GPIO38 is input FFRI
+ * - GPIO39 is output FFTXD
+ * - GPIO40 is output FFDTR
+ * - GPIO41 is output FFRTS
+ * - BTUART is in use
+ * - GPIO42 is input BTRXD
+ * - GPIO43 is output BTTXD
+ * - GPIO44 is input BTCTS
+ * - GPIO45 is output BTRTS
+ * - IRUART is in use
+ * - GPIO46 is input STDRXD
+ * - GPIO47 is output STDTXD
+ * - AC97 is in use*)
+ * - GPIO28 is input AC97CLK
+ * - GPIO29 is input AC97DatIn
+ * - GPIO30 is output AC97DatO
+ * - GPIO31 is output AC97SYNC
+ * - GPIO113 is output AC97_RESET
+ * - SSP is in use
+ * - GPIO23 is output SSPSCLK
+ * - GPIO24 is output chip select to Max7301
+ * - GPIO25 is output SSPTXD
+ * - GPIO26 is input SSPRXD
+ * - GPIO27 is input for Max7301 IRQ
+ * - GPIO53 is input SSPSYSCLK
+ * - SSP3 is in use
+ * - GPIO81 is output SSPTXD3
+ * - GPIO82 is input SSPRXD3
+ * - GPIO83 is output SSPSFRM
+ * - GPIO84 is output SSPCLK3
+ *
+ * Otherwise claimed GPIOs:
+ * GPIO1 -> IRQ from user switch
+ * GPIO9 -> IRQ from power management
+ * GPIO10 -> IRQ from WML9712 AC97 controller
+ * GPIO11 -> IRQ from IDE controller
+ * GPIO12 -> IRQ from CF controller
+ * GPIO13 -> IRQ from CF controller
+ * GPIO14 -> GPIO free
+ * GPIO15 -> /CS1 selects baseboard's Control CPLD (U7, 16 bit wide data path)
+ * GPIO19 -> GPIO free
+ * GPIO20 -> /SDCS2
+ * GPIO21 -> /CS3 PC card socket select
+ * GPIO33 -> /CS5 network controller select
+ * GPIO78 -> /CS2 (16 bit wide data path)
+ * GPIO80 -> /CS4 (16 bit wide data path)
+ * GPIO86 -> GPIO free
+ * GPIO87 -> GPIO free
+ * GPIO90 -> LED0 on CPU module
+ * GPIO91 -> LED1 on CPI module
+ * GPIO117 -> SCL
+ * GPIO118 -> SDA
+ */
+
+static unsigned long pcm990_irq_enabled;
+
+static void pcm990_mask_ack_irq(struct irq_data *d)
+{
+ int pcm990_irq = (d->irq - PCM027_IRQ(0));
+ PCM990_INTMSKENA = (pcm990_irq_enabled &= ~(1 << pcm990_irq));
+}
+
+static void pcm990_unmask_irq(struct irq_data *d)
+{
+ int pcm990_irq = (d->irq - PCM027_IRQ(0));
+ /* the irq can be acknowledged only if deasserted, so it's done here */
+ PCM990_INTSETCLR |= 1 << pcm990_irq;
+ PCM990_INTMSKENA = (pcm990_irq_enabled |= (1 << pcm990_irq));
+}
+
+static struct irq_chip pcm990_irq_chip = {
+ .irq_mask_ack = pcm990_mask_ack_irq,
+ .irq_unmask = pcm990_unmask_irq,
+};
+
+static void pcm990_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+
+ do {
+ /* clear our parent IRQ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ if (likely(pending)) {
+ irq = PCM027_IRQ(0) + __ffs(pending);
+ generic_handle_irq(irq);
+ }
+ pending = (~PCM990_INTSETCLR) & pcm990_irq_enabled;
+ } while (pending);
+}
+
+static void __init pcm990_init_irq(void)
+{
+ int irq;
+
+ /* setup extra PCM990 irqs */
+ for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
+ irq_set_chip_and_handler(irq, &pcm990_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ PCM990_INTMSKENA = 0x00; /* disable all Interrupts */
+ PCM990_INTSETCLR = 0xFF;
+
+ irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
+ irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
+}
+
+static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
+ void *data)
+{
+ int err;
+
+ err = request_irq(PCM027_MMCDET_IRQ, mci_detect_int, IRQF_DISABLED,
+ "MMC card detect", data);
+ if (err)
+ printk(KERN_ERR "pcm990_mci_init: MMC/SD: can't request MMC "
+ "card detect IRQ\n");
+
+ return err;
+}
+
+static void pcm990_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data *p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask)
+ __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+ PCM990_CTRL_MMC2PWR;
+ else
+ __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG5) =
+ ~PCM990_CTRL_MMC2PWR;
+}
+
+static void pcm990_mci_exit(struct device *dev, void *data)
+{
+ free_irq(PCM027_MMCDET_IRQ, data);
+}
+
+#define MSECS_PER_JIFFY (1000/HZ)
+
+static struct pxamci_platform_data pcm990_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .init = pcm990_mci_init,
+ .setpower = pcm990_mci_setpower,
+ .exit = pcm990_mci_exit,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static struct pxaohci_platform_data pcm990_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+ .power_on_delay = 10,
+};
+
+/*
+ * PXA27x Camera specific stuff
+ */
+#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+static unsigned long pcm990_camera_pin_config[] = {
+ /* CIF */
+ GPIO98_CIF_DD_0,
+ GPIO105_CIF_DD_1,
+ GPIO104_CIF_DD_2,
+ GPIO103_CIF_DD_3,
+ GPIO95_CIF_DD_4,
+ GPIO94_CIF_DD_5,
+ GPIO93_CIF_DD_6,
+ GPIO108_CIF_DD_7,
+ GPIO107_CIF_DD_8,
+ GPIO106_CIF_DD_9,
+ GPIO42_CIF_MCLK,
+ GPIO45_CIF_PCLK,
+ GPIO43_CIF_FV,
+ GPIO44_CIF_LV,
+};
+
+/*
+ * CICR4: PCLK_EN: Pixel clock is supplied by the sensor
+ * MCLK_EN: Master clock is generated by PXA
+ * PCP: Data sampled on the falling edge of pixel clock
+ */
+struct pxacamera_platform_data pcm990_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | PXA_CAMERA_DATAWIDTH_10 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN/* | PXA_CAMERA_PCP*/,
+ .mclk_10khz = 1000,
+};
+
+#include <linux/i2c/pca953x.h>
+
+static struct pca953x_platform_data pca9536_data = {
+ .gpio_base = NR_BUILTIN_GPIO,
+};
+
+static int gpio_bus_switch = -EINVAL;
+
+static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
+ unsigned long flags)
+{
+ if (gpio_bus_switch < 0) {
+ if (flags == SOCAM_DATAWIDTH_10)
+ return 0;
+ else
+ return -EINVAL;
+ }
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ gpio_set_value(gpio_bus_switch, 1);
+ else
+ gpio_set_value(gpio_bus_switch, 0);
+
+ return 0;
+}
+
+static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link)
+{
+ int ret;
+
+ if (gpio_bus_switch < 0) {
+ ret = gpio_request(NR_BUILTIN_GPIO, "camera");
+ if (!ret) {
+ gpio_bus_switch = NR_BUILTIN_GPIO;
+ gpio_direction_output(gpio_bus_switch, 0);
+ }
+ }
+
+ if (gpio_bus_switch >= 0)
+ return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10;
+ else
+ return SOCAM_DATAWIDTH_10;
+}
+
+static void pcm990_camera_free_bus(struct soc_camera_link *link)
+{
+ if (gpio_bus_switch < 0)
+ return;
+
+ gpio_free(gpio_bus_switch);
+ gpio_bus_switch = -EINVAL;
+}
+
+/* Board I2C devices. */
+static struct i2c_board_info __initdata pcm990_i2c_devices[] = {
+ {
+ /* Must initialize before the camera(s) */
+ I2C_BOARD_INFO("pca9536", 0x41),
+ .platform_data = &pca9536_data,
+ },
+};
+
+static struct i2c_board_info pcm990_camera_i2c[] = {
+ {
+ I2C_BOARD_INFO("mt9v022", 0x48),
+ }, {
+ I2C_BOARD_INFO("mt9m001", 0x5d),
+ },
+};
+
+static struct soc_camera_link iclink[] = {
+ {
+ .bus_id = 0, /* Must match with the camera ID */
+ .board_info = &pcm990_camera_i2c[0],
+ .i2c_adapter_id = 0,
+ .query_bus_param = pcm990_camera_query_bus_param,
+ .set_bus_param = pcm990_camera_set_bus_param,
+ .free_bus = pcm990_camera_free_bus,
+ }, {
+ .bus_id = 0, /* Must match with the camera ID */
+ .board_info = &pcm990_camera_i2c[1],
+ .i2c_adapter_id = 0,
+ .query_bus_param = pcm990_camera_query_bus_param,
+ .set_bus_param = pcm990_camera_set_bus_param,
+ .free_bus = pcm990_camera_free_bus,
+ },
+};
+
+static struct platform_device pcm990_camera[] = {
+ {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink[0],
+ },
+ }, {
+ .name = "soc-camera-pdrv",
+ .id = 1,
+ .dev = {
+ .platform_data = &iclink[1],
+ },
+ },
+};
+#endif /* CONFIG_VIDEO_PXA27x ||CONFIG_VIDEO_PXA27x_MODULE */
+
+/*
+ * enable generic access to the base board control CPLDs U6 and U7
+ */
+static struct map_desc pcm990_io_desc[] __initdata = {
+ {
+ .virtual = PCM990_CTRL_BASE,
+ .pfn = __phys_to_pfn(PCM990_CTRL_PHYS),
+ .length = PCM990_CTRL_SIZE,
+ .type = MT_DEVICE /* CPLD */
+ }, {
+ .virtual = PCM990_CF_PLD_BASE,
+ .pfn = __phys_to_pfn(PCM990_CF_PLD_PHYS),
+ .length = PCM990_CF_PLD_SIZE,
+ .type = MT_DEVICE /* CPLD */
+ }
+};
+
+/*
+ * system init for baseboard usage. Will be called by pcm027 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init pcm990_baseboard_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_pin_config));
+
+ /* register CPLD access */
+ iotable_init(ARRAY_AND_SIZE(pcm990_io_desc));
+
+ /* register CPLD's IRQ controller */
+ pcm990_init_irq();
+
+#ifndef CONFIG_PCM990_DISPLAY_NONE
+ pxa_set_fb_info(NULL, &pcm990_fbinfo);
+#endif
+ platform_device_register(&pcm990_backlight_device);
+
+ /* MMC */
+ pxa_set_mci_info(&pcm990_mci_platform_data);
+
+ /* USB host */
+ pxa_set_ohci_info(&pcm990_ohci_platform_data);
+
+ pxa_set_i2c_info(NULL);
+ pxa_set_ac97_info(NULL);
+
+#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(pcm990_camera_pin_config));
+ pxa_set_camera_info(&pcm990_pxacamera_platform_data);
+
+ i2c_register_board_info(0, ARRAY_AND_SIZE(pcm990_i2c_devices));
+
+ platform_device_register(&pcm990_camera[0]);
+ platform_device_register(&pcm990_camera[1]);
+#endif
+
+ printk(KERN_INFO "PCM-990 Evaluation baseboard initialized\n");
+}
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
new file mode 100644
index 00000000..51e15832
--- /dev/null
+++ b/arch/arm/mach-pxa/pm.c
@@ -0,0 +1,119 @@
+/*
+ * PXA250/210 Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <mach/pm.h>
+
+struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
+static unsigned long *sleep_save;
+
+int pxa_pm_enter(suspend_state_t state)
+{
+ unsigned long sleep_save_checksum = 0, checksum = 0;
+ int i;
+
+#ifdef CONFIG_IWMMXT
+ /* force any iWMMXt context to ram **/
+ if (elf_hwcap & HWCAP_IWMMXT)
+ iwmmxt_task_disable(NULL);
+#endif
+
+ /* skip registers saving for standby */
+ if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->save) {
+ pxa_cpu_pm_fns->save(sleep_save);
+ /* before sleeping, calculate and save a checksum */
+ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
+ sleep_save_checksum += sleep_save[i];
+ }
+
+ /* *** go zzz *** */
+ pxa_cpu_pm_fns->enter(state);
+ cpu_init();
+
+ if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) {
+ /* after sleeping, validate the checksum */
+ for (i = 0; i < pxa_cpu_pm_fns->save_count - 1; i++)
+ checksum += sleep_save[i];
+
+ /* if invalid, display message and wait for a hardware reset */
+ if (checksum != sleep_save_checksum) {
+
+ lubbock_set_hexled(0xbadbadc5);
+
+ while (1)
+ pxa_cpu_pm_fns->enter(state);
+ }
+ pxa_cpu_pm_fns->restore(sleep_save);
+ }
+
+ pr_debug("*** made it back from resume\n");
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(pxa_pm_enter);
+
+static int pxa_pm_valid(suspend_state_t state)
+{
+ if (pxa_cpu_pm_fns)
+ return pxa_cpu_pm_fns->valid(state);
+
+ return -EINVAL;
+}
+
+int pxa_pm_prepare(void)
+{
+ int ret = 0;
+
+ if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->prepare)
+ ret = pxa_cpu_pm_fns->prepare();
+
+ return ret;
+}
+
+void pxa_pm_finish(void)
+{
+ if (pxa_cpu_pm_fns && pxa_cpu_pm_fns->finish)
+ pxa_cpu_pm_fns->finish();
+}
+
+static const struct platform_suspend_ops pxa_pm_ops = {
+ .valid = pxa_pm_valid,
+ .enter = pxa_pm_enter,
+ .prepare = pxa_pm_prepare,
+ .finish = pxa_pm_finish,
+};
+
+static int __init pxa_pm_init(void)
+{
+ if (!pxa_cpu_pm_fns) {
+ printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n");
+ return -EINVAL;
+ }
+
+ sleep_save = kmalloc(pxa_cpu_pm_fns->save_count * sizeof(unsigned long),
+ GFP_KERNEL);
+ if (!sleep_save) {
+ printk(KERN_ERR "failed to alloc memory for pm save\n");
+ return -ENOMEM;
+ }
+
+ suspend_set_ops(&pxa_pm_ops);
+ return 0;
+}
+
+device_initcall(pxa_pm_init);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
new file mode 100644
index 00000000..16d14fd7
--- /dev/null
+++ b/arch/arm/mach-pxa/poodle.c
@@ -0,0 +1,473 @@
+/*
+ * linux/arch/arm/mach-pxa/poodle.c
+ *
+ * Support for the SHARP Poodle Board.
+ *
+ * Based on:
+ * linux/arch/arm/mach-pxa/lubbock.c Author: Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Change Log
+ * 12-Dec-2002 Sharp Corporation for Poodle
+ * John Lenz <lenz@cs.wisc.edu> updates to 2.6
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/pm.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mtd/sharpsl.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/pxa25x.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/irda.h>
+#include <mach/poodle.h>
+#include <mach/pxafb.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/hardware/locomo.h>
+#include <asm/mach/sharpsl_param.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned long poodle_pin_config[] __initdata = {
+ /* I/O */
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+ GPIO18_RDY,
+
+ /* Clock */
+ GPIO12_32KHz,
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+ GPIO24_GPIO, /* POODLE_GPIO_TP_CS - SFRM as chip select */
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO32_I2S_SYSCLK,
+
+ /* Infra-Red */
+ GPIO47_FICP_TXD,
+ GPIO46_FICP_RXD,
+
+ /* FFUART */
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+ GPIO39_FFUART_TXD,
+ GPIO37_FFUART_DSR,
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+
+ /* LCD */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+
+ /* GPIO */
+ GPIO9_GPIO, /* POODLE_GPIO_nSD_DETECT */
+ GPIO7_GPIO, /* POODLE_GPIO_nSD_WP */
+ GPIO3_GPIO, /* POODLE_GPIO_SD_PWR */
+ GPIO33_GPIO, /* POODLE_GPIO_SD_PWR1 */
+
+ GPIO20_GPIO, /* POODLE_GPIO_USB_PULLUP */
+ GPIO22_GPIO, /* POODLE_GPIO_IR_ON */
+};
+
+static struct resource poodle_scoop_resources[] = {
+ [0] = {
+ .start = 0x10800000,
+ .end = 0x10800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config poodle_scoop_setup = {
+ .io_dir = POODLE_SCOOP_IO_DIR,
+ .io_out = POODLE_SCOOP_IO_OUT,
+ .gpio_base = POODLE_SCOOP_GPIO_BASE,
+};
+
+struct platform_device poodle_scoop_device = {
+ .name = "sharp-scoop",
+ .id = -1,
+ .dev = {
+ .platform_data = &poodle_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(poodle_scoop_resources),
+ .resource = poodle_scoop_resources,
+};
+
+static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
+{
+ .dev = &poodle_scoop_device.dev,
+ .irq = POODLE_IRQ_GPIO_CF_IRQ,
+ .cd_irq = POODLE_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+},
+};
+
+static struct scoop_pcmcia_config poodle_pcmcia_config = {
+ .devs = &poodle_pcmcia_scoop[0],
+ .num_devs = 1,
+};
+
+EXPORT_SYMBOL(poodle_scoop_device);
+
+
+/* LoCoMo device */
+static struct resource locomo_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x10001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO(10),
+ .end = IRQ_GPIO(10),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct locomo_platform_data locomo_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+struct platform_device poodle_locomo_device = {
+ .name = "locomo",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(locomo_resources),
+ .resource = locomo_resources,
+ .dev = {
+ .platform_data = &locomo_info,
+ },
+};
+
+EXPORT_SYMBOL(poodle_locomo_device);
+
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static struct pxa2xx_spi_master poodle_spi_info = {
+ .num_chipselect = 1,
+};
+
+static struct ads7846_platform_data poodle_ads7846_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .gpio_pendown = POODLE_GPIO_TP_INT,
+};
+
+static struct pxa2xx_spi_chip poodle_ads7846_chip = {
+ .gpio_cs = POODLE_GPIO_TP_CS,
+};
+
+static struct spi_board_info poodle_spi_devices[] = {
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 10000,
+ .bus_num = 1,
+ .platform_data = &poodle_ads7846_info,
+ .controller_data= &poodle_ads7846_chip,
+ .irq = gpio_to_irq(POODLE_GPIO_TP_INT),
+ },
+};
+
+static void __init poodle_init_spi(void)
+{
+ pxa2xx_set_spi_info(1, &poodle_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
+}
+#else
+static inline void poodle_init_spi(void) {}
+#endif
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
+{
+ int err;
+
+ err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
+ if (err)
+ goto err_free_2;
+
+ err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1");
+ if (err)
+ goto err_free_3;
+
+ gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
+ gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);
+
+ return 0;
+
+err_free_3:
+ gpio_free(POODLE_GPIO_SD_PWR);
+err_free_2:
+ return err;
+}
+
+static void poodle_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask) {
+ gpio_set_value(POODLE_GPIO_SD_PWR, 1);
+ mdelay(2);
+ gpio_set_value(POODLE_GPIO_SD_PWR1, 1);
+ } else {
+ gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
+ gpio_set_value(POODLE_GPIO_SD_PWR, 0);
+ }
+}
+
+static void poodle_mci_exit(struct device *dev, void *data)
+{
+ gpio_free(POODLE_GPIO_SD_PWR1);
+ gpio_free(POODLE_GPIO_SD_PWR);
+}
+
+static struct pxamci_platform_data poodle_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = poodle_mci_init,
+ .setpower = poodle_mci_setpower,
+ .exit = poodle_mci_exit,
+ .gpio_card_detect = POODLE_GPIO_nSD_DETECT,
+ .gpio_card_ro = POODLE_GPIO_nSD_WP,
+ .gpio_power = -1,
+};
+
+
+/*
+ * Irda
+ */
+static struct pxaficp_platform_data poodle_ficp_platform_data = {
+ .gpio_pwdown = POODLE_GPIO_IR_ON,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+
+/*
+ * USB Device Controller
+ */
+static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ /* no connect GPIO; poodle can't tell connection status */
+ .gpio_pullup = POODLE_GPIO_USB_PULLUP,
+};
+
+
+/* PXAFB device */
+static struct pxafb_mode_info poodle_fb_mode = {
+ .pixclock = 144700,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .hsync_len = 7,
+ .left_margin = 11,
+ .right_margin = 30,
+ .vsync_len = 2,
+ .upper_margin = 2,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info poodle_fb_info = {
+ .modes = &poodle_fb_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP,
+};
+
+static struct mtd_partition sharpsl_nand_partitions[] = {
+ {
+ .name = "System Area",
+ .offset = 0,
+ .size = 7 * 1024 * 1024,
+ },
+ {
+ .name = "Root Filesystem",
+ .offset = 7 * 1024 * 1024,
+ .size = 22 * 1024 * 1024,
+ },
+ {
+ .name = "Home Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr sharpsl_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 2,
+ .pattern = scan_ff_pattern
+};
+
+static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
+ .badblock_pattern = &sharpsl_bbt,
+ .partitions = sharpsl_nand_partitions,
+ .nr_partitions = ARRAY_SIZE(sharpsl_nand_partitions),
+};
+
+static struct resource sharpsl_nand_resources[] = {
+ {
+ .start = 0x0C000000,
+ .end = 0x0C000FFF,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sharpsl_nand_device = {
+ .name = "sharpsl-nand",
+ .id = -1,
+ .resource = sharpsl_nand_resources,
+ .num_resources = ARRAY_SIZE(sharpsl_nand_resources),
+ .dev.platform_data = &sharpsl_nand_platform_data,
+};
+
+static struct mtd_partition sharpsl_rom_parts[] = {
+ {
+ .name ="Boot PROM Filesystem",
+ .offset = 0x00120000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data sharpsl_rom_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(sharpsl_rom_parts),
+ .parts = sharpsl_rom_parts,
+};
+
+static struct resource sharpsl_rom_resources[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x007fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sharpsl_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = sharpsl_rom_resources,
+ .num_resources = ARRAY_SIZE(sharpsl_rom_resources),
+ .dev.platform_data = &sharpsl_rom_data,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &poodle_locomo_device,
+ &poodle_scoop_device,
+ &sharpsl_nand_device,
+ &sharpsl_rom_device,
+};
+
+static struct i2c_board_info __initdata poodle_i2c_devices[] = {
+ { I2C_BOARD_INFO("wm8731", 0x1b) },
+};
+
+static void poodle_poweroff(void)
+{
+ arm_machine_restart('h', NULL);
+}
+
+static void poodle_restart(char mode, const char *cmd)
+{
+ arm_machine_restart('h', cmd);
+}
+
+static void __init poodle_init(void)
+{
+ int ret = 0;
+
+ pm_power_off = poodle_poweroff;
+ arm_pm_restart = poodle_restart;
+
+ PCFR |= PCFR_OPDE;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_scoop_config = &poodle_pcmcia_config;
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret)
+ pr_warning("poodle: Unable to register LoCoMo device\n");
+
+ pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
+ pxa_set_udc_info(&udc_info);
+ pxa_set_mci_info(&poodle_mci_platform_data);
+ pxa_set_ficp_info(&poodle_ficp_platform_data);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
+ poodle_init_spi();
+}
+
+static void __init fixup_poodle(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].size = (32*1024*1024);
+}
+
+MACHINE_START(POODLE, "SHARP Poodle")
+ .fixup = fixup_poodle,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = POODLE_NR_IRQS, /* 4 for LoCoMo */
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = poodle_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
new file mode 100644
index 00000000..fed363ce
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -0,0 +1,386 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa25x.c
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * Code specific to PXA21x/25x/26x variants.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Since this file should be linked before any other machine specific file,
+ * the __initcall() here will be executed first. This serves as default
+ * initialization stuff for PXA machines which can be overridden later if
+ * need be.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/irq.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/pxa25x.h>
+#include <mach/reset.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/*
+ * Various clock factors driven by the CCCR register.
+ */
+
+/* Crystal Frequency to Memory Frequency Multiplier (L) */
+static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
+
+/* Memory Frequency to Run Mode Frequency Multiplier (M) */
+static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
+
+/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
+/* Note: we store the value N * 2 here. */
+static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
+
+/* Crystal clock */
+#define BASE_CLK 3686400
+
+/*
+ * Get the clock frequency as reflected by CCCR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa25x_get_clk_frequency_khz(int info)
+{
+ unsigned long cccr, turbo;
+ unsigned int l, L, m, M, n2, N;
+
+ cccr = CCCR;
+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
+
+ l = L_clk_mult[(cccr >> 0) & 0x1f];
+ m = M_clk_mult[(cccr >> 5) & 0x03];
+ n2 = N2_clk_mult[(cccr >> 7) & 0x07];
+
+ L = l * BASE_CLK;
+ M = m * L;
+ N = n2 * M / 2;
+
+ if(info)
+ {
+ L += 5000;
+ printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
+ L / 1000000, (L % 1000000) / 10000, l );
+ M += 5000;
+ printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+ M / 1000000, (M % 1000000) / 10000, m );
+ N += 5000;
+ printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+ N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
+ (turbo & 1) ? "" : "in" );
+ }
+
+ return (turbo & 1) ? (N/1000) : (M/1000);
+}
+
+static unsigned long clk_pxa25x_mem_getrate(struct clk *clk)
+{
+ return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK;
+}
+
+static const struct clkops clk_pxa25x_mem_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+ .getrate = clk_pxa25x_mem_getrate,
+};
+
+static const struct clkops clk_pxa25x_lcd_ops = {
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
+ .getrate = clk_pxa25x_mem_getrate,
+};
+
+static unsigned long gpio12_config_32k[] = {
+ GPIO12_32KHz,
+};
+
+static unsigned long gpio12_config_gpio[] = {
+ GPIO12_GPIO,
+};
+
+static void clk_gpio12_enable(struct clk *clk)
+{
+ pxa2xx_mfp_config(gpio12_config_32k, 1);
+}
+
+static void clk_gpio12_disable(struct clk *clk)
+{
+ pxa2xx_mfp_config(gpio12_config_gpio, 1);
+}
+
+static const struct clkops clk_pxa25x_gpio12_ops = {
+ .enable = clk_gpio12_enable,
+ .disable = clk_gpio12_disable,
+};
+
+static unsigned long gpio11_config_3m6[] = {
+ GPIO11_3_6MHz,
+};
+
+static unsigned long gpio11_config_gpio[] = {
+ GPIO11_GPIO,
+};
+
+static void clk_gpio11_enable(struct clk *clk)
+{
+ pxa2xx_mfp_config(gpio11_config_3m6, 1);
+}
+
+static void clk_gpio11_disable(struct clk *clk)
+{
+ pxa2xx_mfp_config(gpio11_config_gpio, 1);
+}
+
+static const struct clkops clk_pxa25x_gpio11_ops = {
+ .enable = clk_gpio11_enable,
+ .disable = clk_gpio11_disable,
+};
+
+/*
+ * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
+ * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
+ * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
+ */
+
+/*
+ * PXA 2xx clock declarations.
+ */
+static DEFINE_PXA2_CKEN(pxa25x_hwuart, HWUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_ffuart, FFUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_btuart, BTUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_stuart, STUART, 14745600, 1);
+static DEFINE_PXA2_CKEN(pxa25x_usb, USB, 47923000, 5);
+static DEFINE_PXA2_CKEN(pxa25x_mmc, MMC, 19169000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_i2c, I2C, 31949000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ssp, SSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_nssp, NSSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_assp, ASSP, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_pwm0, PWM0, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_pwm1, PWM1, 3686400, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ac97, AC97, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa25x_i2s, I2S, 14745600, 0);
+static DEFINE_PXA2_CKEN(pxa25x_ficp, FICP, 47923000, 0);
+
+static DEFINE_CK(pxa25x_lcd, LCD, &clk_pxa25x_lcd_ops);
+static DEFINE_CLK(pxa25x_gpio11, &clk_pxa25x_gpio11_ops, 3686400, 0);
+static DEFINE_CLK(pxa25x_gpio12, &clk_pxa25x_gpio12_ops, 32768, 0);
+static DEFINE_CLK(pxa25x_mem, &clk_pxa25x_mem_ops, 0, 0);
+
+static struct clk_lookup pxa25x_clkregs[] = {
+ INIT_CLKREG(&clk_pxa25x_lcd, "pxa2xx-fb", NULL),
+ INIT_CLKREG(&clk_pxa25x_ffuart, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_pxa25x_btuart, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_pxa25x_usb, "pxa25x-udc", NULL),
+ INIT_CLKREG(&clk_pxa25x_mmc, "pxa2xx-mci.0", NULL),
+ INIT_CLKREG(&clk_pxa25x_i2c, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_pxa25x_ssp, "pxa25x-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa25x_nssp, "pxa25x-nssp.1", NULL),
+ INIT_CLKREG(&clk_pxa25x_assp, "pxa25x-nssp.2", NULL),
+ INIT_CLKREG(&clk_pxa25x_pwm0, "pxa25x-pwm.0", NULL),
+ INIT_CLKREG(&clk_pxa25x_pwm1, "pxa25x-pwm.1", NULL),
+ INIT_CLKREG(&clk_pxa25x_i2s, "pxa2xx-i2s", NULL),
+ INIT_CLKREG(&clk_pxa25x_stuart, "pxa2xx-ir", "UARTCLK"),
+ INIT_CLKREG(&clk_pxa25x_ficp, "pxa2xx-ir", "FICPCLK"),
+ INIT_CLKREG(&clk_pxa25x_ac97, NULL, "AC97CLK"),
+ INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
+ INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
+ INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
+};
+
+static struct clk_lookup pxa25x_hwuart_clkreg =
+ INIT_CLKREG(&clk_pxa25x_hwuart, "pxa2xx-uart.3", NULL);
+
+#ifdef CONFIG_PM
+
+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum {
+ SLEEP_SAVE_PSTR,
+ SLEEP_SAVE_COUNT
+};
+
+
+static void pxa25x_cpu_pm_save(unsigned long *sleep_save)
+{
+ SAVE(PSTR);
+}
+
+static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
+{
+ RESTORE(PSTR);
+}
+
+static void pxa25x_cpu_pm_enter(suspend_state_t state)
+{
+ /* Clear reset status */
+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
+ break;
+ }
+}
+
+static int pxa25x_cpu_pm_prepare(void)
+{
+ /* set resume return address */
+ PSPR = virt_to_phys(cpu_resume);
+ return 0;
+}
+
+static void pxa25x_cpu_pm_finish(void)
+{
+ /* ensure not to come back here if it wasn't intended */
+ PSPR = 0;
+}
+
+static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = {
+ .save_count = SLEEP_SAVE_COUNT,
+ .valid = suspend_valid_only_mem,
+ .save = pxa25x_cpu_pm_save,
+ .restore = pxa25x_cpu_pm_restore,
+ .enter = pxa25x_cpu_pm_enter,
+ .prepare = pxa25x_cpu_pm_prepare,
+ .finish = pxa25x_cpu_pm_finish,
+};
+
+static void __init pxa25x_init_pm(void)
+{
+ pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
+}
+#else
+static inline void pxa25x_init_pm(void) {}
+#endif
+
+/* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
+ */
+
+static int pxa25x_set_wake(struct irq_data *d, unsigned int on)
+{
+ int gpio = irq_to_gpio(d->irq);
+ uint32_t mask = 0;
+
+ if (gpio >= 0 && gpio < 85)
+ return gpio_set_wake(gpio, on);
+
+ if (d->irq == IRQ_RTCAlrm) {
+ mask = PWER_RTC;
+ goto set_pwer;
+ }
+
+ return -EINVAL;
+
+set_pwer:
+ if (on)
+ PWER |= mask;
+ else
+ PWER &=~mask;
+
+ return 0;
+}
+
+void __init pxa25x_init_irq(void)
+{
+ pxa_init_irq(32, pxa25x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 84, pxa25x_set_wake);
+}
+
+#ifdef CONFIG_CPU_PXA26x
+void __init pxa26x_init_irq(void)
+{
+ pxa_init_irq(32, pxa25x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 89, pxa25x_set_wake);
+}
+#endif
+
+static struct map_desc pxa25x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init pxa25x_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa25x_io_desc));
+ pxa25x_get_clk_frequency_khz(1);
+}
+
+static struct platform_device *pxa25x_devices[] __initdata = {
+ &pxa25x_device_udc,
+ &pxa_device_pmu,
+ &pxa_device_i2s,
+ &sa1100_device_rtc,
+ &pxa25x_device_ssp,
+ &pxa25x_device_nssp,
+ &pxa25x_device_assp,
+ &pxa25x_device_pwm0,
+ &pxa25x_device_pwm1,
+ &pxa_device_asoc_platform,
+};
+
+static int __init pxa25x_init(void)
+{
+ int ret = 0;
+
+ if (cpu_is_pxa25x()) {
+
+ reset_status = RCSR;
+
+ clkdev_add_table(pxa25x_clkregs, ARRAY_SIZE(pxa25x_clkregs));
+
+ if ((ret = pxa_init_dma(IRQ_DMA, 16)))
+ return ret;
+
+ pxa25x_init_pm();
+
+ register_syscore_ops(&pxa_irq_syscore_ops);
+ register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+ register_syscore_ops(&pxa_gpio_syscore_ops);
+ register_syscore_ops(&pxa2xx_clock_syscore_ops);
+
+ ret = platform_add_devices(pxa25x_devices,
+ ARRAY_SIZE(pxa25x_devices));
+ if (ret)
+ return ret;
+ }
+
+ /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */
+ if (cpu_is_pxa255())
+ clkdev_add(&pxa25x_hwuart_clkreg);
+
+ return ret;
+}
+
+postcore_initcall(pxa25x_init);
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
new file mode 100644
index 00000000..2fecbec5
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -0,0 +1,457 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa27x.c
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 05, 2002
+ * Copyright: MontaVista Software Inc.
+ *
+ * Code specific to PXA27x aka Bulverde.
+ *
+ * This program is free software; you can 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/suspend.h>
+#include <linux/platform_device.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/pxa27x.h>
+#include <mach/reset.h>
+#include <mach/ohci.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+void pxa27x_clear_otgph(void)
+{
+ if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH))
+ PSSR |= PSSR_OTGPH;
+}
+EXPORT_SYMBOL(pxa27x_clear_otgph);
+
+static unsigned long ac97_reset_config[] = {
+ GPIO113_GPIO,
+ GPIO113_AC97_nRESET,
+ GPIO95_GPIO,
+ GPIO95_AC97_nRESET,
+};
+
+void pxa27x_assert_ac97reset(int reset_gpio, int on)
+{
+ if (reset_gpio == 113)
+ pxa2xx_mfp_config(on ? &ac97_reset_config[0] :
+ &ac97_reset_config[1], 1);
+
+ if (reset_gpio == 95)
+ pxa2xx_mfp_config(on ? &ac97_reset_config[2] :
+ &ac97_reset_config[3], 1);
+}
+EXPORT_SYMBOL_GPL(pxa27x_assert_ac97reset);
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK 13000000
+
+/*
+ * Get the clock frequency as reflected by CCSR and the turbo flag.
+ * We assume these values have been applied via a fcs.
+ * If info is not 0 we also display the current settings.
+ */
+unsigned int pxa27x_get_clk_frequency_khz(int info)
+{
+ unsigned long ccsr, clkcfg;
+ unsigned int l, L, m, M, n2, N, S;
+ int cccr_a, t, ht, b;
+
+ ccsr = CCSR;
+ cccr_a = CCCR & (1 << 25);
+
+ /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
+ t = clkcfg & (1 << 0);
+ ht = clkcfg & (1 << 2);
+ b = clkcfg & (1 << 3);
+
+ l = ccsr & 0x1f;
+ n2 = (ccsr>>7) & 0xf;
+ m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
+
+ L = l * BASE_CLK;
+ N = (L * n2) / 2;
+ M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
+ S = (b) ? L : (L/2);
+
+ if (info) {
+ printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
+ L / 1000000, (L % 1000000) / 10000, l );
+ printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
+ N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5,
+ (t) ? "" : "in" );
+ printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
+ M / 1000000, (M % 1000000) / 10000, m );
+ printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
+ S / 1000000, (S % 1000000) / 10000 );
+ }
+
+ return (t) ? (N/1000) : (L/1000);
+}
+
+/*
+ * Return the current mem clock frequency as reflected by CCCR[A], B, and L
+ */
+static unsigned long clk_pxa27x_mem_getrate(struct clk *clk)
+{
+ unsigned long ccsr, clkcfg;
+ unsigned int l, L, m, M;
+ int cccr_a, b;
+
+ ccsr = CCSR;
+ cccr_a = CCCR & (1 << 25);
+
+ /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
+ b = clkcfg & (1 << 3);
+
+ l = ccsr & 0x1f;
+ m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
+
+ L = l * BASE_CLK;
+ M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
+
+ return M;
+}
+
+static const struct clkops clk_pxa27x_mem_ops = {
+ .enable = clk_dummy_enable,
+ .disable = clk_dummy_disable,
+ .getrate = clk_pxa27x_mem_getrate,
+};
+
+/*
+ * Return the current LCD clock frequency in units of 10kHz as
+ */
+static unsigned int pxa27x_get_lcdclk_frequency_10khz(void)
+{
+ unsigned long ccsr;
+ unsigned int l, L, k, K;
+
+ ccsr = CCSR;
+
+ l = ccsr & 0x1f;
+ k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4;
+
+ L = l * BASE_CLK;
+ K = L / k;
+
+ return (K / 10000);
+}
+
+static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
+{
+ return pxa27x_get_lcdclk_frequency_10khz() * 10000;
+}
+
+static const struct clkops clk_pxa27x_lcd_ops = {
+ .enable = clk_pxa2xx_cken_enable,
+ .disable = clk_pxa2xx_cken_disable,
+ .getrate = clk_pxa27x_lcd_getrate,
+};
+
+static DEFINE_PXA2_CKEN(pxa27x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA2_CKEN(pxa27x_i2s, I2S, 14682000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usb, USB, 48000000, 5);
+static DEFINE_PXA2_CKEN(pxa27x_mmc, MMC, 19500000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ficp, FICP, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usbhost, USBHOST, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwri2c, PWRI2C, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_pwm1, PWM1, 13000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ac97, AC97, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_ac97conf, AC97CONF, 24576000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_msl, MSL, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_usim, USIM, 48000000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_memstk, MEMSTK, 19500000, 0);
+static DEFINE_PXA2_CKEN(pxa27x_im, IM, 0, 0);
+static DEFINE_PXA2_CKEN(pxa27x_memc, MEMC, 0, 0);
+
+static DEFINE_CK(pxa27x_lcd, LCD, &clk_pxa27x_lcd_ops);
+static DEFINE_CK(pxa27x_camera, CAMERA, &clk_pxa27x_lcd_ops);
+static DEFINE_CLK(pxa27x_mem, &clk_pxa27x_mem_ops, 0, 0);
+
+static struct clk_lookup pxa27x_clkregs[] = {
+ INIT_CLKREG(&clk_pxa27x_lcd, "pxa2xx-fb", NULL),
+ INIT_CLKREG(&clk_pxa27x_camera, "pxa27x-camera.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_ffuart, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_btuart, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_pxa27x_i2s, "pxa2xx-i2s", NULL),
+ INIT_CLKREG(&clk_pxa27x_i2c, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_usb, "pxa27x-udc", NULL),
+ INIT_CLKREG(&clk_pxa27x_mmc, "pxa2xx-mci.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_stuart, "pxa2xx-ir", "UARTCLK"),
+ INIT_CLKREG(&clk_pxa27x_ficp, "pxa2xx-ir", "FICPCLK"),
+ INIT_CLKREG(&clk_pxa27x_usbhost, "pxa27x-ohci", NULL),
+ INIT_CLKREG(&clk_pxa27x_pwri2c, "pxa2xx-i2c.1", NULL),
+ INIT_CLKREG(&clk_pxa27x_keypad, "pxa27x-keypad", NULL),
+ INIT_CLKREG(&clk_pxa27x_ssp1, "pxa27x-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_ssp2, "pxa27x-ssp.1", NULL),
+ INIT_CLKREG(&clk_pxa27x_ssp3, "pxa27x-ssp.2", NULL),
+ INIT_CLKREG(&clk_pxa27x_pwm0, "pxa27x-pwm.0", NULL),
+ INIT_CLKREG(&clk_pxa27x_pwm1, "pxa27x-pwm.1", NULL),
+ INIT_CLKREG(&clk_pxa27x_ac97, NULL, "AC97CLK"),
+ INIT_CLKREG(&clk_pxa27x_ac97conf, NULL, "AC97CONFCLK"),
+ INIT_CLKREG(&clk_pxa27x_msl, NULL, "MSLCLK"),
+ INIT_CLKREG(&clk_pxa27x_usim, NULL, "USIMCLK"),
+ INIT_CLKREG(&clk_pxa27x_memstk, NULL, "MSTKCLK"),
+ INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
+ INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
+ INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
+};
+
+#ifdef CONFIG_PM
+
+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
+
+/*
+ * allow platforms to override default PWRMODE setting used for PM_SUSPEND_MEM
+ */
+static unsigned int pwrmode = PWRMODE_SLEEP;
+
+int __init pxa27x_set_pwrmode(unsigned int mode)
+{
+ switch (mode) {
+ case PWRMODE_SLEEP:
+ case PWRMODE_DEEPSLEEP:
+ pwrmode = mode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum {
+ SLEEP_SAVE_PSTR,
+ SLEEP_SAVE_MDREFR,
+ SLEEP_SAVE_PCFR,
+ SLEEP_SAVE_COUNT
+};
+
+void pxa27x_cpu_pm_save(unsigned long *sleep_save)
+{
+ sleep_save[SLEEP_SAVE_MDREFR] = __raw_readl(MDREFR);
+ SAVE(PCFR);
+
+ SAVE(PSTR);
+}
+
+void pxa27x_cpu_pm_restore(unsigned long *sleep_save)
+{
+ __raw_writel(sleep_save[SLEEP_SAVE_MDREFR], MDREFR);
+ RESTORE(PCFR);
+
+ PSSR = PSSR_RDH | PSSR_PH;
+
+ RESTORE(PSTR);
+}
+
+void pxa27x_cpu_pm_enter(suspend_state_t state)
+{
+ extern void pxa_cpu_standby(void);
+
+ /* ensure voltage-change sequencer not initiated, which hangs */
+ PCFR &= ~PCFR_FVC;
+
+ /* Clear edge-detect status register. */
+ PEDR = 0xDF12FE1B;
+
+ /* Clear reset status */
+ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ pxa_cpu_standby();
+ break;
+ case PM_SUSPEND_MEM:
+ pxa27x_cpu_suspend(pwrmode, PLAT_PHYS_OFFSET - PAGE_OFFSET);
+ break;
+ }
+}
+
+static int pxa27x_cpu_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static int pxa27x_cpu_pm_prepare(void)
+{
+ /* set resume return address */
+ PSPR = virt_to_phys(cpu_resume);
+ return 0;
+}
+
+static void pxa27x_cpu_pm_finish(void)
+{
+ /* ensure not to come back here if it wasn't intended */
+ PSPR = 0;
+}
+
+static struct pxa_cpu_pm_fns pxa27x_cpu_pm_fns = {
+ .save_count = SLEEP_SAVE_COUNT,
+ .save = pxa27x_cpu_pm_save,
+ .restore = pxa27x_cpu_pm_restore,
+ .valid = pxa27x_cpu_pm_valid,
+ .enter = pxa27x_cpu_pm_enter,
+ .prepare = pxa27x_cpu_pm_prepare,
+ .finish = pxa27x_cpu_pm_finish,
+};
+
+static void __init pxa27x_init_pm(void)
+{
+ pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
+}
+#else
+static inline void pxa27x_init_pm(void) {}
+#endif
+
+/* PXA27x: Various gpios can issue wakeup events. This logic only
+ * handles the simple cases, not the WEMUX2 and WEMUX3 options
+ */
+static int pxa27x_set_wake(struct irq_data *d, unsigned int on)
+{
+ int gpio = irq_to_gpio(d->irq);
+ uint32_t mask;
+
+ if (gpio >= 0 && gpio < 128)
+ return gpio_set_wake(gpio, on);
+
+ if (d->irq == IRQ_KEYPAD)
+ return keypad_set_wake(on);
+
+ switch (d->irq) {
+ case IRQ_RTCAlrm:
+ mask = PWER_RTC;
+ break;
+ case IRQ_USB:
+ mask = 1u << 26;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (on)
+ PWER |= mask;
+ else
+ PWER &=~mask;
+
+ return 0;
+}
+
+void __init pxa27x_init_irq(void)
+{
+ pxa_init_irq(34, pxa27x_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 120, pxa27x_set_wake);
+}
+
+static struct map_desc pxa27x_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA2XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ }, { /* IMem ctl */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0x58000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init pxa27x_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa27x_io_desc));
+ pxa27x_get_clk_frequency_khz(1);
+}
+
+/*
+ * device registration specific to PXA27x.
+ */
+void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+ local_irq_disable();
+ PCFR |= PCFR_PI2CEN;
+ local_irq_enable();
+ pxa_register_device(&pxa27x_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+ &pxa27x_device_udc,
+ &pxa_device_pmu,
+ &pxa_device_i2s,
+ &pxa_device_asoc_ssp1,
+ &pxa_device_asoc_ssp2,
+ &pxa_device_asoc_ssp3,
+ &pxa_device_asoc_platform,
+ &sa1100_device_rtc,
+ &pxa_device_rtc,
+ &pxa27x_device_ssp1,
+ &pxa27x_device_ssp2,
+ &pxa27x_device_ssp3,
+ &pxa27x_device_pwm0,
+ &pxa27x_device_pwm1,
+};
+
+static int __init pxa27x_init(void)
+{
+ int ret = 0;
+
+ if (cpu_is_pxa27x()) {
+
+ reset_status = RCSR;
+
+ clkdev_add_table(pxa27x_clkregs, ARRAY_SIZE(pxa27x_clkregs));
+
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+ return ret;
+
+ pxa27x_init_pm();
+
+ register_syscore_ops(&pxa_irq_syscore_ops);
+ register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+ register_syscore_ops(&pxa_gpio_syscore_ops);
+ register_syscore_ops(&pxa2xx_clock_syscore_ops);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+postcore_initcall(pxa27x_init);
diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c
new file mode 100644
index 00000000..86827042
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa2xx.c
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa2xx.c
+ *
+ * code specific to pxa2xx
+ *
+ * Copyright (C) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can 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/device.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/reset.h>
+#include <mach/irda.h>
+
+void pxa2xx_clear_reset_status(unsigned int mask)
+{
+ /* RESET_STATUS_* has a 1:1 mapping with RCSR */
+ RCSR = mask;
+}
+
+static unsigned long pxa2xx_mfp_fir[] = {
+ GPIO46_FICP_RXD,
+ GPIO47_FICP_TXD,
+};
+
+static unsigned long pxa2xx_mfp_sir[] = {
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+};
+
+static unsigned long pxa2xx_mfp_off[] = {
+ GPIO46_GPIO | MFP_LPM_DRIVE_LOW,
+ GPIO47_GPIO | MFP_LPM_DRIVE_LOW,
+};
+
+void pxa2xx_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF) {
+ pxa2xx_mfp_config(pxa2xx_mfp_off, ARRAY_SIZE(pxa2xx_mfp_off));
+ } else if (mode & IR_SIRMODE) {
+ pxa2xx_mfp_config(pxa2xx_mfp_sir, ARRAY_SIZE(pxa2xx_mfp_sir));
+ } else if (mode & IR_FIRMODE) {
+ pxa2xx_mfp_config(pxa2xx_mfp_fir, ARRAY_SIZE(pxa2xx_mfp_fir));
+ } else
+ BUG();
+}
+EXPORT_SYMBOL_GPL(pxa2xx_transceiver_mode);
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
new file mode 100644
index 00000000..40bb1650
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -0,0 +1,116 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa300.c
+ *
+ * Code specific to PXA300/PXA310
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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/platform_device.h>
+
+#include <mach/pxa300.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+static struct mfp_addr_map pxa300_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR_X(GPIO0, GPIO2, 0x00b4),
+ MFP_ADDR_X(GPIO3, GPIO26, 0x027c),
+ MFP_ADDR_X(GPIO27, GPIO98, 0x0400),
+ MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
+ MFP_ADDR_X(GPIO0_2, GPIO1_2, 0x0674),
+ MFP_ADDR_X(GPIO2_2, GPIO6_2, 0x02dc),
+
+ MFP_ADDR(nBE0, 0x0204),
+ MFP_ADDR(nBE1, 0x0208),
+
+ MFP_ADDR(nLUA, 0x0244),
+ MFP_ADDR(nLLA, 0x0254),
+
+ MFP_ADDR(DF_CLE_nOE, 0x0240),
+ MFP_ADDR(DF_nRE_nOE, 0x0200),
+ MFP_ADDR(DF_ALE_nWE, 0x020C),
+ MFP_ADDR(DF_INT_RnB, 0x00C8),
+ MFP_ADDR(DF_nCS0, 0x0248),
+ MFP_ADDR(DF_nCS1, 0x0278),
+ MFP_ADDR(DF_nWE, 0x00CC),
+
+ MFP_ADDR(DF_ADDR0, 0x0210),
+ MFP_ADDR(DF_ADDR1, 0x0214),
+ MFP_ADDR(DF_ADDR2, 0x0218),
+ MFP_ADDR(DF_ADDR3, 0x021C),
+
+ MFP_ADDR(DF_IO0, 0x0220),
+ MFP_ADDR(DF_IO1, 0x0228),
+ MFP_ADDR(DF_IO2, 0x0230),
+ MFP_ADDR(DF_IO3, 0x0238),
+ MFP_ADDR(DF_IO4, 0x0258),
+ MFP_ADDR(DF_IO5, 0x0260),
+ MFP_ADDR(DF_IO6, 0x0268),
+ MFP_ADDR(DF_IO7, 0x0270),
+ MFP_ADDR(DF_IO8, 0x0224),
+ MFP_ADDR(DF_IO9, 0x022C),
+ MFP_ADDR(DF_IO10, 0x0234),
+ MFP_ADDR(DF_IO11, 0x023C),
+ MFP_ADDR(DF_IO12, 0x025C),
+ MFP_ADDR(DF_IO13, 0x0264),
+ MFP_ADDR(DF_IO14, 0x026C),
+ MFP_ADDR(DF_IO15, 0x0274),
+
+ MFP_ADDR_END,
+};
+
+/* override pxa300 MFP register addresses */
+static struct mfp_addr_map pxa310_mfp_addr_map[] __initdata = {
+ MFP_ADDR_X(GPIO30, GPIO98, 0x0418),
+ MFP_ADDR_X(GPIO7_2, GPIO12_2, 0x052C),
+
+ MFP_ADDR(ULPI_STP, 0x040C),
+ MFP_ADDR(ULPI_NXT, 0x0410),
+ MFP_ADDR(ULPI_DIR, 0x0414),
+
+ MFP_ADDR_END,
+};
+
+static DEFINE_PXA3_CKEN(common_nand, NAND, 156000000, 0);
+static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0);
+
+static struct clk_lookup common_clkregs[] = {
+ INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
+};
+
+static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0);
+
+static struct clk_lookup pxa310_clkregs[] = {
+ INIT_CLKREG(&clk_pxa310_mmc3, "pxa2xx-mci.2", NULL),
+};
+
+static int __init pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa300_mfp_addr_map);
+ clkdev_add_table(ARRAY_AND_SIZE(common_clkregs));
+ }
+
+ if (cpu_is_pxa310()) {
+ mfp_init_addr(pxa310_mfp_addr_map);
+ clkdev_add_table(ARRAY_AND_SIZE(pxa310_clkregs));
+ }
+
+ return 0;
+}
+
+core_initcall(pxa300_init);
diff --git a/arch/arm/mach-pxa/pxa320.c b/arch/arm/mach-pxa/pxa320.c
new file mode 100644
index 00000000..8d614ecd
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa320.c
@@ -0,0 +1,99 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa320.c
+ *
+ * Code specific to PXA320
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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/platform_device.h>
+
+#include <mach/pxa320.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+static struct mfp_addr_map pxa320_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR_X(GPIO0, GPIO4, 0x0124),
+ MFP_ADDR_X(GPIO5, GPIO9, 0x028C),
+ MFP_ADDR(GPIO10, 0x0458),
+ MFP_ADDR_X(GPIO11, GPIO26, 0x02A0),
+ MFP_ADDR_X(GPIO27, GPIO48, 0x0400),
+ MFP_ADDR_X(GPIO49, GPIO62, 0x045C),
+ MFP_ADDR_X(GPIO63, GPIO73, 0x04B4),
+ MFP_ADDR_X(GPIO74, GPIO98, 0x04F0),
+ MFP_ADDR_X(GPIO99, GPIO127, 0x0600),
+ MFP_ADDR_X(GPIO0_2, GPIO5_2, 0x0674),
+ MFP_ADDR_X(GPIO6_2, GPIO13_2, 0x0494),
+ MFP_ADDR_X(GPIO14_2, GPIO17_2, 0x04E0),
+
+ MFP_ADDR(nXCVREN, 0x0138),
+ MFP_ADDR(DF_CLE_nOE, 0x0204),
+ MFP_ADDR(DF_nADV1_ALE, 0x0208),
+ MFP_ADDR(DF_SCLK_S, 0x020C),
+ MFP_ADDR(DF_SCLK_E, 0x0210),
+ MFP_ADDR(nBE0, 0x0214),
+ MFP_ADDR(nBE1, 0x0218),
+ MFP_ADDR(DF_nADV2_ALE, 0x021C),
+ MFP_ADDR(DF_INT_RnB, 0x0220),
+ MFP_ADDR(DF_nCS0, 0x0224),
+ MFP_ADDR(DF_nCS1, 0x0228),
+ MFP_ADDR(DF_nWE, 0x022C),
+ MFP_ADDR(DF_nRE_nOE, 0x0230),
+ MFP_ADDR(nLUA, 0x0234),
+ MFP_ADDR(nLLA, 0x0238),
+ MFP_ADDR(DF_ADDR0, 0x023C),
+ MFP_ADDR(DF_ADDR1, 0x0240),
+ MFP_ADDR(DF_ADDR2, 0x0244),
+ MFP_ADDR(DF_ADDR3, 0x0248),
+ MFP_ADDR(DF_IO0, 0x024C),
+ MFP_ADDR(DF_IO8, 0x0250),
+ MFP_ADDR(DF_IO1, 0x0254),
+ MFP_ADDR(DF_IO9, 0x0258),
+ MFP_ADDR(DF_IO2, 0x025C),
+ MFP_ADDR(DF_IO10, 0x0260),
+ MFP_ADDR(DF_IO3, 0x0264),
+ MFP_ADDR(DF_IO11, 0x0268),
+ MFP_ADDR(DF_IO4, 0x026C),
+ MFP_ADDR(DF_IO12, 0x0270),
+ MFP_ADDR(DF_IO5, 0x0274),
+ MFP_ADDR(DF_IO13, 0x0278),
+ MFP_ADDR(DF_IO6, 0x027C),
+ MFP_ADDR(DF_IO14, 0x0280),
+ MFP_ADDR(DF_IO7, 0x0284),
+ MFP_ADDR(DF_IO15, 0x0288),
+
+ MFP_ADDR_END,
+};
+
+static DEFINE_PXA3_CKEN(pxa320_nand, NAND, 104000000, 0);
+static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0);
+
+static struct clk_lookup pxa320_clkregs[] = {
+ INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL),
+ INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL),
+};
+
+static int __init pxa320_init(void)
+{
+ if (cpu_is_pxa320()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa320_mfp_addr_map);
+ clkdev_add_table(ARRAY_AND_SIZE(pxa320_clkregs));
+ }
+
+ return 0;
+}
+
+core_initcall(pxa320_init);
diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c
new file mode 100644
index 00000000..ce7168b2
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c
@@ -0,0 +1,400 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx-ulpi.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2010 CompuLab Ltd.
+ *
+ * 2010-13-07: Igor Grinberg <grinberg@compulab.co.il>
+ * initial version: pxa310 USB Host mode support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/usb.h>
+#include <linux/usb/otg.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-u2d.h>
+#include <mach/pxa3xx-u2d.h>
+
+struct pxa3xx_u2d_ulpi {
+ struct clk *clk;
+ void __iomem *mmio_base;
+
+ struct otg_transceiver *otg;
+ unsigned int ulpi_mode;
+};
+
+static struct pxa3xx_u2d_ulpi *u2d;
+
+static inline u32 u2d_readl(u32 reg)
+{
+ return __raw_readl(u2d->mmio_base + reg);
+}
+
+static inline void u2d_writel(u32 reg, u32 val)
+{
+ __raw_writel(val, u2d->mmio_base + reg);
+}
+
+#if defined(CONFIG_PXA310_ULPI)
+enum u2d_ulpi_phy_mode {
+ SYNCH = 0,
+ CARKIT = (1 << 0),
+ SER_3PIN = (1 << 1),
+ SER_6PIN = (1 << 2),
+ LOWPOWER = (1 << 3),
+};
+
+static inline enum u2d_ulpi_phy_mode pxa310_ulpi_get_phymode(void)
+{
+ return (u2d_readl(U2DOTGUSR) >> 28) & 0xF;
+}
+
+static int pxa310_ulpi_poll(void)
+{
+ int timeout = 50000;
+
+ while (timeout--) {
+ if (!(u2d_readl(U2DOTGUCR) & U2DOTGUCR_RUN))
+ return 0;
+
+ cpu_relax();
+ }
+
+ pr_warning("%s: ULPI access timed out!\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static int pxa310_ulpi_read(struct otg_transceiver *otg, u32 reg)
+{
+ int err;
+
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | U2DOTGUCR_RNW | (reg << 16));
+ msleep(5);
+
+ err = pxa310_ulpi_poll();
+ if (err)
+ return err;
+
+ return u2d_readl(U2DOTGUCR) & U2DOTGUCR_RDATA;
+}
+
+static int pxa310_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+{
+ if (pxa310_ulpi_get_phymode() != SYNCH) {
+ pr_warning("%s: PHY is not in SYNCH mode!\n", __func__);
+ return -EBUSY;
+ }
+
+ u2d_writel(U2DOTGUCR, U2DOTGUCR_RUN | (reg << 16) | (val << 8));
+ msleep(5);
+
+ return pxa310_ulpi_poll();
+}
+
+struct otg_io_access_ops pxa310_ulpi_access_ops = {
+ .read = pxa310_ulpi_read,
+ .write = pxa310_ulpi_write,
+};
+
+static void pxa310_otg_transceiver_rtsm(void)
+{
+ u32 u2dotgcr;
+
+ /* put PHY to sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_RTSM | U2DOTGCR_UTMID;
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(10);
+
+ /* setup OTG sync mode */
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+}
+
+static int pxa310_start_otg_host_transcvr(struct usb_bus *host)
+{
+ int err;
+
+ pxa310_otg_transceiver_rtsm();
+
+ err = otg_init(u2d->otg);
+ if (err) {
+ pr_err("OTG transceiver init failed");
+ return err;
+ }
+
+ err = otg_set_vbus(u2d->otg, 1);
+ if (err) {
+ pr_err("OTG transceiver VBUS set failed");
+ return err;
+ }
+
+ err = otg_set_host(u2d->otg, host);
+ if (err)
+ pr_err("OTG transceiver Host mode set failed");
+
+ return err;
+}
+
+static int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ u32 u2dotgcr;
+ int err;
+
+ /* disable USB device controller */
+ u2d_writel(U2DCR, u2d_readl(U2DCR) & ~U2DCR_UDE);
+ u2d_writel(U2DOTGCR, u2d_readl(U2DOTGCR) | U2DOTGCR_UTMID);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+
+ err = pxa310_start_otg_host_transcvr(host);
+ if (err)
+ return err;
+
+ /* set xceiver mode */
+ if (u2d->ulpi_mode & ULPI_IC_6PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) & ~U2DP3CR_P2SS);
+ else if (u2d->ulpi_mode & ULPI_IC_3PIN_SERIAL)
+ u2d_writel(U2DP3CR, u2d_readl(U2DP3CR) | U2DP3CR_P2SS);
+
+ /* start OTG host controller */
+ u2dotgcr = u2d_readl(U2DOTGCR) | U2DOTGCR_SMAF;
+ u2d_writel(U2DOTGCR, u2dotgcr & ~(U2DOTGCR_ULAF | U2DOTGCR_CKAF));
+
+ return 0;
+}
+
+static void pxa310_stop_otg_hc(void)
+{
+ pxa310_otg_transceiver_rtsm();
+
+ otg_set_host(u2d->otg, NULL);
+ otg_set_vbus(u2d->otg, 0);
+ otg_shutdown(u2d->otg);
+}
+
+static void pxa310_u2d_setup_otg_hc(void)
+{
+ u32 u2dotgcr;
+
+ u2dotgcr = u2d_readl(U2DOTGCR);
+ u2dotgcr |= U2DOTGCR_ULAF | U2DOTGCR_UTMID;
+ u2dotgcr &= ~(U2DOTGCR_SMAF | U2DOTGCR_CKAF);
+ u2d_writel(U2DOTGCR, u2dotgcr);
+ msleep(5);
+ u2d_writel(U2DOTGCR, u2dotgcr | U2DOTGCR_ULE);
+ msleep(5);
+ u2d_writel(U2DOTGICR, u2d_readl(U2DOTGICR) & ~0x37F7F);
+}
+
+static int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ unsigned int ulpi_mode = ULPI_OTG_DRVVBUS;
+
+ if (pdata) {
+ if (pdata->ulpi_mode & ULPI_SER_6PIN)
+ ulpi_mode |= ULPI_IC_6PIN_SERIAL;
+ else if (pdata->ulpi_mode & ULPI_SER_3PIN)
+ ulpi_mode |= ULPI_IC_3PIN_SERIAL;
+ }
+
+ u2d->ulpi_mode = ulpi_mode;
+
+ u2d->otg = otg_ulpi_create(&pxa310_ulpi_access_ops, ulpi_mode);
+ if (!u2d->otg)
+ return -ENOMEM;
+
+ u2d->otg->io_priv = u2d->mmio_base;
+
+ return 0;
+}
+
+static void pxa310_otg_exit(void)
+{
+ kfree(u2d->otg);
+}
+#else
+static inline void pxa310_u2d_setup_otg_hc(void) {}
+static inline int pxa310_start_otg_hc(struct usb_bus *host)
+{
+ return 0;
+}
+static inline void pxa310_stop_otg_hc(void) {}
+static inline int pxa310_otg_init(struct pxa3xx_u2d_platform_data *pdata)
+{
+ return 0;
+}
+static inline void pxa310_otg_exit(void) {}
+#endif /* CONFIG_PXA310_ULPI */
+
+int pxa3xx_u2d_start_hc(struct usb_bus *host)
+{
+ int err = 0;
+
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return 0;
+
+ clk_enable(u2d->clk);
+
+ if (cpu_is_pxa310()) {
+ pxa310_u2d_setup_otg_hc();
+ err = pxa310_start_otg_hc(host);
+ }
+
+ return err;
+}
+
+void pxa3xx_u2d_stop_hc(struct usb_bus *host)
+{
+ /* In case the PXA3xx ULPI isn't used, do nothing. */
+ if (!u2d)
+ return;
+
+ if (cpu_is_pxa310())
+ pxa310_stop_otg_hc();
+
+ clk_disable(u2d->clk);
+}
+
+static int pxa3xx_u2d_probe(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+ int err;
+
+ u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
+ if (!u2d) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ u2d->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(u2d->clk)) {
+ dev_err(&pdev->dev, "failed to get u2d clock\n");
+ err = PTR_ERR(u2d->clk);
+ goto err_free_mem;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no IO memory resource defined\n");
+ err = -ENODEV;
+ goto err_put_clk;
+ }
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (!r) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ err = -EBUSY;
+ goto err_put_clk;
+ }
+
+ u2d->mmio_base = ioremap(r->start, resource_size(r));
+ if (!u2d->mmio_base) {
+ dev_err(&pdev->dev, "ioremap() failed\n");
+ err = -ENODEV;
+ goto err_free_res;
+ }
+
+ if (pdata->init) {
+ err = pdata->init(&pdev->dev);
+ if (err)
+ goto err_free_io;
+ }
+
+ /* Only PXA310 U2D has OTG functionality */
+ if (cpu_is_pxa310()) {
+ err = pxa310_otg_init(pdata);
+ if (err)
+ goto err_free_plat;
+ }
+
+ platform_set_drvdata(pdev, &u2d);
+
+ return 0;
+
+err_free_plat:
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+err_free_io:
+ iounmap(u2d->mmio_base);
+err_free_res:
+ release_mem_region(r->start, resource_size(r));
+err_put_clk:
+ clk_put(u2d->clk);
+err_free_mem:
+ kfree(u2d);
+ return err;
+}
+
+static int pxa3xx_u2d_remove(struct platform_device *pdev)
+{
+ struct pxa3xx_u2d_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *r;
+
+ if (cpu_is_pxa310()) {
+ pxa310_stop_otg_hc();
+ pxa310_otg_exit();
+ }
+
+ if (pdata->exit)
+ pdata->exit(&pdev->dev);
+
+ platform_set_drvdata(pdev, NULL);
+ iounmap(u2d->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_put(u2d->clk);
+
+ kfree(u2d);
+
+ return 0;
+}
+
+static struct platform_driver pxa3xx_u2d_ulpi_driver = {
+ .driver = {
+ .name = "pxa3xx-u2d",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa3xx_u2d_probe,
+ .remove = pxa3xx_u2d_remove,
+};
+
+static int pxa3xx_u2d_ulpi_init(void)
+{
+ return platform_driver_register(&pxa3xx_u2d_ulpi_driver);
+}
+module_init(pxa3xx_u2d_ulpi_init);
+
+static void __exit pxa3xx_u2d_ulpi_exit(void)
+{
+ platform_driver_unregister(&pxa3xx_u2d_ulpi_driver);
+}
+module_exit(pxa3xx_u2d_ulpi_exit);
+
+MODULE_DESCRIPTION("PXA3xx U2D ULPI driver");
+MODULE_AUTHOR("Igor Grinberg");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
new file mode 100644
index 00000000..8521d7d6
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -0,0 +1,464 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa3xx.c
+ *
+ * code specific to pxa3xx aka Monahans
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ *
+ * 2007-09-02: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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/pm.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/reset.h>
+#include <mach/ohci.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/regs-intc.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+#define PECR_IE(n) ((1 << ((n) * 2)) << 28)
+#define PECR_IS(n) ((1 << ((n) * 2)) << 29)
+
+static DEFINE_PXA3_CKEN(pxa3xx_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa3xx_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa3xx_stuart, STUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa3xx_i2c, I2C, 32842000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_udc, UDC, 48000000, 5);
+static DEFINE_PXA3_CKEN(pxa3xx_usbh, USBH, 48000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_u2d, USB2, 48000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_ssp4, SSP4, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_pwm1, PWM1, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_mmc1, MMC1, 19500000, 0);
+static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0);
+
+static DEFINE_CK(pxa3xx_lcd, LCD, &clk_pxa3xx_hsio_ops);
+static DEFINE_CK(pxa3xx_smemc, SMC, &clk_pxa3xx_smemc_ops);
+static DEFINE_CK(pxa3xx_camera, CAMERA, &clk_pxa3xx_hsio_ops);
+static DEFINE_CK(pxa3xx_ac97, AC97, &clk_pxa3xx_ac97_ops);
+static DEFINE_CLK(pxa3xx_pout, &clk_pxa3xx_pout_ops, 13000000, 70);
+
+static struct clk_lookup pxa3xx_clkregs[] = {
+ INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"),
+ /* Power I2C clock is always on */
+ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL),
+ INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"),
+ INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"),
+ INIT_CLKREG(&clk_pxa3xx_ffuart, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_btuart, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_pxa3xx_stuart, "pxa2xx-ir", "UARTCLK"),
+ INIT_CLKREG(&clk_pxa3xx_i2c, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_udc, "pxa27x-udc", NULL),
+ INIT_CLKREG(&clk_pxa3xx_usbh, "pxa27x-ohci", NULL),
+ INIT_CLKREG(&clk_pxa3xx_u2d, "pxa3xx-u2d", NULL),
+ INIT_CLKREG(&clk_pxa3xx_keypad, "pxa27x-keypad", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp1, "pxa27x-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp2, "pxa27x-ssp.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp3, "pxa27x-ssp.2", NULL),
+ INIT_CLKREG(&clk_pxa3xx_ssp4, "pxa27x-ssp.3", NULL),
+ INIT_CLKREG(&clk_pxa3xx_pwm0, "pxa27x-pwm.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_pwm1, "pxa27x-pwm.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_mmc1, "pxa2xx-mci.0", NULL),
+ INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
+ INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
+};
+
+#ifdef CONFIG_PM
+
+#define ISRAM_START 0x5c000000
+#define ISRAM_SIZE SZ_256K
+
+static void __iomem *sram;
+static unsigned long wakeup_src;
+
+/*
+ * Enter a standby mode (S0D1C2 or S0D2C2). Upon wakeup, the dynamic
+ * memory controller has to be reinitialised, so we place some code
+ * in the SRAM to perform this function.
+ *
+ * We disable FIQs across the standby - otherwise, we might receive a
+ * FIQ while the SDRAM is unavailable.
+ */
+static void pxa3xx_cpu_standby(unsigned int pwrmode)
+{
+ extern const char pm_enter_standby_start[], pm_enter_standby_end[];
+ void (*fn)(unsigned int) = (void __force *)(sram + 0x8000);
+
+ memcpy_toio(sram + 0x8000, pm_enter_standby_start,
+ pm_enter_standby_end - pm_enter_standby_start);
+
+ AD2D0SR = ~0;
+ AD2D1SR = ~0;
+ AD2D0ER = wakeup_src;
+ AD2D1ER = 0;
+ ASCR = ASCR;
+ ARSR = ARSR;
+
+ local_fiq_disable();
+ fn(pwrmode);
+ local_fiq_enable();
+
+ AD2D0ER = 0;
+ AD2D1ER = 0;
+}
+
+/*
+ * NOTE: currently, the OBM (OEM Boot Module) binary comes along with
+ * PXA3xx development kits assumes that the resuming process continues
+ * with the address stored within the first 4 bytes of SDRAM. The PSPR
+ * register is used privately by BootROM and OBM, and _must_ be set to
+ * 0x5c014000 for the moment.
+ */
+static void pxa3xx_cpu_pm_suspend(void)
+{
+ volatile unsigned long *p = (volatile void *)0xc0000000;
+ unsigned long saved_data = *p;
+
+ extern void pxa3xx_cpu_suspend(long);
+
+ /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */
+ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM);
+ CKENB |= 1 << (CKEN_HSIO2 & 0x1f);
+
+ /* clear and setup wakeup source */
+ AD3SR = ~0;
+ AD3ER = wakeup_src;
+ ASCR = ASCR;
+ ARSR = ARSR;
+
+ PCFR |= (1u << 13); /* L1_DIS */
+ PCFR &= ~((1u << 12) | (1u << 1)); /* L0_EN | SL_ROD */
+
+ PSPR = 0x5c014000;
+
+ /* overwrite with the resume address */
+ *p = virt_to_phys(cpu_resume);
+
+ pxa3xx_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
+
+ *p = saved_data;
+
+ AD3ER = 0;
+}
+
+static void pxa3xx_cpu_pm_enter(suspend_state_t state)
+{
+ /*
+ * Don't sleep if no wakeup sources are defined
+ */
+ if (wakeup_src == 0) {
+ printk(KERN_ERR "Not suspending: no wakeup sources\n");
+ return;
+ }
+
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ pxa3xx_cpu_standby(PXA3xx_PM_S0D2C2);
+ break;
+
+ case PM_SUSPEND_MEM:
+ pxa3xx_cpu_pm_suspend();
+ break;
+ }
+}
+
+static int pxa3xx_cpu_pm_valid(suspend_state_t state)
+{
+ return state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY;
+}
+
+static struct pxa_cpu_pm_fns pxa3xx_cpu_pm_fns = {
+ .valid = pxa3xx_cpu_pm_valid,
+ .enter = pxa3xx_cpu_pm_enter,
+};
+
+static void __init pxa3xx_init_pm(void)
+{
+ sram = ioremap(ISRAM_START, ISRAM_SIZE);
+ if (!sram) {
+ printk(KERN_ERR "Unable to map ISRAM: disabling standby/suspend\n");
+ return;
+ }
+
+ /*
+ * Since we copy wakeup code into the SRAM, we need to ensure
+ * that it is preserved over the low power modes. Note: bit 8
+ * is undocumented in the developer manual, but must be set.
+ */
+ AD1R |= ADXR_L2 | ADXR_R0;
+ AD2R |= ADXR_L2 | ADXR_R0;
+ AD3R |= ADXR_L2 | ADXR_R0;
+
+ /*
+ * Clear the resume enable registers.
+ */
+ AD1D0ER = 0;
+ AD2D0ER = 0;
+ AD2D1ER = 0;
+ AD3ER = 0;
+
+ pxa_cpu_pm_fns = &pxa3xx_cpu_pm_fns;
+}
+
+static int pxa3xx_set_wake(struct irq_data *d, unsigned int on)
+{
+ unsigned long flags, mask = 0;
+
+ switch (d->irq) {
+ case IRQ_SSP3:
+ mask = ADXER_MFP_WSSP3;
+ break;
+ case IRQ_MSL:
+ mask = ADXER_WMSL0;
+ break;
+ case IRQ_USBH2:
+ case IRQ_USBH1:
+ mask = ADXER_WUSBH;
+ break;
+ case IRQ_KEYPAD:
+ mask = ADXER_WKP;
+ break;
+ case IRQ_AC97:
+ mask = ADXER_MFP_WAC97;
+ break;
+ case IRQ_USIM:
+ mask = ADXER_WUSIM0;
+ break;
+ case IRQ_SSP2:
+ mask = ADXER_MFP_WSSP2;
+ break;
+ case IRQ_I2C:
+ mask = ADXER_MFP_WI2C;
+ break;
+ case IRQ_STUART:
+ mask = ADXER_MFP_WUART3;
+ break;
+ case IRQ_BTUART:
+ mask = ADXER_MFP_WUART2;
+ break;
+ case IRQ_FFUART:
+ mask = ADXER_MFP_WUART1;
+ break;
+ case IRQ_MMC:
+ mask = ADXER_MFP_WMMC1;
+ break;
+ case IRQ_SSP:
+ mask = ADXER_MFP_WSSP1;
+ break;
+ case IRQ_RTCAlrm:
+ mask = ADXER_WRTC;
+ break;
+ case IRQ_SSP4:
+ mask = ADXER_MFP_WSSP4;
+ break;
+ case IRQ_TSI:
+ mask = ADXER_WTSI;
+ break;
+ case IRQ_USIM2:
+ mask = ADXER_WUSIM1;
+ break;
+ case IRQ_MMC2:
+ mask = ADXER_MFP_WMMC2;
+ break;
+ case IRQ_NAND:
+ mask = ADXER_MFP_WFLASH;
+ break;
+ case IRQ_USB2:
+ mask = ADXER_WUSB2;
+ break;
+ case IRQ_WAKEUP0:
+ mask = ADXER_WEXTWAKE0;
+ break;
+ case IRQ_WAKEUP1:
+ mask = ADXER_WEXTWAKE1;
+ break;
+ case IRQ_MMC3:
+ mask = ADXER_MFP_GEN12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ local_irq_save(flags);
+ if (on)
+ wakeup_src |= mask;
+ else
+ wakeup_src &= ~mask;
+ local_irq_restore(flags);
+
+ return 0;
+}
+#else
+static inline void pxa3xx_init_pm(void) {}
+#define pxa3xx_set_wake NULL
+#endif
+
+static void pxa_ack_ext_wakeup(struct irq_data *d)
+{
+ PECR |= PECR_IS(d->irq - IRQ_WAKEUP0);
+}
+
+static void pxa_mask_ext_wakeup(struct irq_data *d)
+{
+ ICMR2 &= ~(1 << ((d->irq - PXA_IRQ(0)) & 0x1f));
+ PECR &= ~PECR_IE(d->irq - IRQ_WAKEUP0);
+}
+
+static void pxa_unmask_ext_wakeup(struct irq_data *d)
+{
+ ICMR2 |= 1 << ((d->irq - PXA_IRQ(0)) & 0x1f);
+ PECR |= PECR_IE(d->irq - IRQ_WAKEUP0);
+}
+
+static int pxa_set_ext_wakeup_type(struct irq_data *d, unsigned int flow_type)
+{
+ if (flow_type & IRQ_TYPE_EDGE_RISING)
+ PWER |= 1 << (d->irq - IRQ_WAKEUP0);
+
+ if (flow_type & IRQ_TYPE_EDGE_FALLING)
+ PWER |= 1 << (d->irq - IRQ_WAKEUP0 + 2);
+
+ return 0;
+}
+
+static struct irq_chip pxa_ext_wakeup_chip = {
+ .name = "WAKEUP",
+ .irq_ack = pxa_ack_ext_wakeup,
+ .irq_mask = pxa_mask_ext_wakeup,
+ .irq_unmask = pxa_unmask_ext_wakeup,
+ .irq_set_type = pxa_set_ext_wakeup_type,
+};
+
+static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
+{
+ int irq;
+
+ for (irq = IRQ_WAKEUP0; irq <= IRQ_WAKEUP1; irq++) {
+ irq_set_chip_and_handler(irq, &pxa_ext_wakeup_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ pxa_ext_wakeup_chip.irq_set_wake = fn;
+}
+
+void __init pxa3xx_init_irq(void)
+{
+ /* enable CP6 access */
+ u32 value;
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c1, 0\n": "=r"(value));
+ value |= (1 << 6);
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c1, 0\n": :"r"(value));
+
+ pxa_init_irq(56, pxa3xx_set_wake);
+ pxa_init_ext_wakeup_irq(pxa3xx_set_wake);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
+}
+
+static struct map_desc pxa3xx_io_desc[] __initdata = {
+ { /* Mem Ctl */
+ .virtual = SMEMC_VIRT,
+ .pfn = __phys_to_pfn(PXA3XX_SMEMC_BASE),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ }
+};
+
+void __init pxa3xx_map_io(void)
+{
+ pxa_map_io();
+ iotable_init(ARRAY_AND_SIZE(pxa3xx_io_desc));
+ pxa3xx_get_clk_frequency_khz(1);
+}
+
+/*
+ * device registration specific to PXA3xx.
+ */
+
+void __init pxa3xx_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+ &pxa27x_device_udc,
+ &pxa_device_pmu,
+ &pxa_device_i2s,
+ &pxa_device_asoc_ssp1,
+ &pxa_device_asoc_ssp2,
+ &pxa_device_asoc_ssp3,
+ &pxa_device_asoc_ssp4,
+ &pxa_device_asoc_platform,
+ &sa1100_device_rtc,
+ &pxa_device_rtc,
+ &pxa27x_device_ssp1,
+ &pxa27x_device_ssp2,
+ &pxa27x_device_ssp3,
+ &pxa3xx_device_ssp4,
+ &pxa27x_device_pwm0,
+ &pxa27x_device_pwm1,
+};
+
+static int __init pxa3xx_init(void)
+{
+ int ret = 0;
+
+ if (cpu_is_pxa3xx()) {
+
+ reset_status = ARSR;
+
+ /*
+ * clear RDH bit every time after reset
+ *
+ * Note: the last 3 bits DxS are write-1-to-clear so carefully
+ * preserve them here in case they will be referenced later
+ */
+ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+
+ clkdev_add_table(pxa3xx_clkregs, ARRAY_SIZE(pxa3xx_clkregs));
+
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+ return ret;
+
+ pxa3xx_init_pm();
+
+ register_syscore_ops(&pxa_irq_syscore_ops);
+ register_syscore_ops(&pxa3xx_mfp_syscore_ops);
+ register_syscore_ops(&pxa_gpio_syscore_ops);
+ register_syscore_ops(&pxa3xx_clock_syscore_ops);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+postcore_initcall(pxa3xx_init);
diff --git a/arch/arm/mach-pxa/pxa930.c b/arch/arm/mach-pxa/pxa930.c
new file mode 100644
index 00000000..8aeacf90
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa930.c
@@ -0,0 +1,206 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa930.c
+ *
+ * Code specific to PXA930
+ *
+ * Copyright (C) 2007-2008 Marvell Internation 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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+
+#include <mach/pxa930.h>
+
+static struct mfp_addr_map pxa930_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR(GPIO0, 0x02e0),
+ MFP_ADDR(GPIO1, 0x02dc),
+ MFP_ADDR(GPIO2, 0x02e8),
+ MFP_ADDR(GPIO3, 0x02d8),
+ MFP_ADDR(GPIO4, 0x02e4),
+ MFP_ADDR(GPIO5, 0x02ec),
+ MFP_ADDR(GPIO6, 0x02f8),
+ MFP_ADDR(GPIO7, 0x02fc),
+ MFP_ADDR(GPIO8, 0x0300),
+ MFP_ADDR(GPIO9, 0x02d4),
+ MFP_ADDR(GPIO10, 0x02f4),
+ MFP_ADDR(GPIO11, 0x02f0),
+ MFP_ADDR(GPIO12, 0x0304),
+ MFP_ADDR(GPIO13, 0x0310),
+ MFP_ADDR(GPIO14, 0x0308),
+ MFP_ADDR(GPIO15, 0x030c),
+ MFP_ADDR(GPIO16, 0x04e8),
+ MFP_ADDR(GPIO17, 0x04f4),
+ MFP_ADDR(GPIO18, 0x04f8),
+ MFP_ADDR(GPIO19, 0x04fc),
+ MFP_ADDR(GPIO20, 0x0518),
+ MFP_ADDR(GPIO21, 0x051c),
+ MFP_ADDR(GPIO22, 0x04ec),
+ MFP_ADDR(GPIO23, 0x0500),
+ MFP_ADDR(GPIO24, 0x04f0),
+ MFP_ADDR(GPIO25, 0x0504),
+ MFP_ADDR(GPIO26, 0x0510),
+ MFP_ADDR(GPIO27, 0x0514),
+ MFP_ADDR(GPIO28, 0x0520),
+ MFP_ADDR(GPIO29, 0x0600),
+ MFP_ADDR(GPIO30, 0x0618),
+ MFP_ADDR(GPIO31, 0x0610),
+ MFP_ADDR(GPIO32, 0x060c),
+ MFP_ADDR(GPIO33, 0x061c),
+ MFP_ADDR(GPIO34, 0x0620),
+ MFP_ADDR(GPIO35, 0x0628),
+ MFP_ADDR(GPIO36, 0x062c),
+ MFP_ADDR(GPIO37, 0x0630),
+ MFP_ADDR(GPIO38, 0x0634),
+ MFP_ADDR(GPIO39, 0x0638),
+ MFP_ADDR(GPIO40, 0x063c),
+ MFP_ADDR(GPIO41, 0x0614),
+ MFP_ADDR(GPIO42, 0x0624),
+ MFP_ADDR(GPIO43, 0x0608),
+ MFP_ADDR(GPIO44, 0x0604),
+ MFP_ADDR(GPIO45, 0x050c),
+ MFP_ADDR(GPIO46, 0x0508),
+ MFP_ADDR(GPIO47, 0x02bc),
+ MFP_ADDR(GPIO48, 0x02b4),
+ MFP_ADDR(GPIO49, 0x02b8),
+ MFP_ADDR(GPIO50, 0x02c8),
+ MFP_ADDR(GPIO51, 0x02c0),
+ MFP_ADDR(GPIO52, 0x02c4),
+ MFP_ADDR(GPIO53, 0x02d0),
+ MFP_ADDR(GPIO54, 0x02cc),
+ MFP_ADDR(GPIO55, 0x029c),
+ MFP_ADDR(GPIO56, 0x02a0),
+ MFP_ADDR(GPIO57, 0x0294),
+ MFP_ADDR(GPIO58, 0x0298),
+ MFP_ADDR(GPIO59, 0x02a4),
+ MFP_ADDR(GPIO60, 0x02a8),
+ MFP_ADDR(GPIO61, 0x02b0),
+ MFP_ADDR(GPIO62, 0x02ac),
+ MFP_ADDR(GPIO63, 0x0640),
+ MFP_ADDR(GPIO64, 0x065c),
+ MFP_ADDR(GPIO65, 0x0648),
+ MFP_ADDR(GPIO66, 0x0644),
+ MFP_ADDR(GPIO67, 0x0674),
+ MFP_ADDR(GPIO68, 0x0658),
+ MFP_ADDR(GPIO69, 0x0654),
+ MFP_ADDR(GPIO70, 0x0660),
+ MFP_ADDR(GPIO71, 0x0668),
+ MFP_ADDR(GPIO72, 0x0664),
+ MFP_ADDR(GPIO73, 0x0650),
+ MFP_ADDR(GPIO74, 0x066c),
+ MFP_ADDR(GPIO75, 0x064c),
+ MFP_ADDR(GPIO76, 0x0670),
+ MFP_ADDR(GPIO77, 0x0678),
+ MFP_ADDR(GPIO78, 0x067c),
+ MFP_ADDR(GPIO79, 0x0694),
+ MFP_ADDR(GPIO80, 0x069c),
+ MFP_ADDR(GPIO81, 0x06a0),
+ MFP_ADDR(GPIO82, 0x06a4),
+ MFP_ADDR(GPIO83, 0x0698),
+ MFP_ADDR(GPIO84, 0x06bc),
+ MFP_ADDR(GPIO85, 0x06b4),
+ MFP_ADDR(GPIO86, 0x06b0),
+ MFP_ADDR(GPIO87, 0x06c0),
+ MFP_ADDR(GPIO88, 0x06c4),
+ MFP_ADDR(GPIO89, 0x06ac),
+ MFP_ADDR(GPIO90, 0x0680),
+ MFP_ADDR(GPIO91, 0x0684),
+ MFP_ADDR(GPIO92, 0x0688),
+ MFP_ADDR(GPIO93, 0x0690),
+ MFP_ADDR(GPIO94, 0x068c),
+ MFP_ADDR(GPIO95, 0x06a8),
+ MFP_ADDR(GPIO96, 0x06b8),
+ MFP_ADDR(GPIO97, 0x0410),
+ MFP_ADDR(GPIO98, 0x0418),
+ MFP_ADDR(GPIO99, 0x041c),
+ MFP_ADDR(GPIO100, 0x0414),
+ MFP_ADDR(GPIO101, 0x0408),
+ MFP_ADDR(GPIO102, 0x0324),
+ MFP_ADDR(GPIO103, 0x040c),
+ MFP_ADDR(GPIO104, 0x0400),
+ MFP_ADDR(GPIO105, 0x0328),
+ MFP_ADDR(GPIO106, 0x0404),
+
+ MFP_ADDR(nXCVREN, 0x0204),
+ MFP_ADDR(DF_CLE_nOE, 0x020c),
+ MFP_ADDR(DF_nADV1_ALE, 0x0218),
+ MFP_ADDR(DF_SCLK_E, 0x0214),
+ MFP_ADDR(DF_SCLK_S, 0x0210),
+ MFP_ADDR(nBE0, 0x021c),
+ MFP_ADDR(nBE1, 0x0220),
+ MFP_ADDR(DF_nADV2_ALE, 0x0224),
+ MFP_ADDR(DF_INT_RnB, 0x0228),
+ MFP_ADDR(DF_nCS0, 0x022c),
+ MFP_ADDR(DF_nCS1, 0x0230),
+ MFP_ADDR(nLUA, 0x0254),
+ MFP_ADDR(nLLA, 0x0258),
+ MFP_ADDR(DF_nWE, 0x0234),
+ MFP_ADDR(DF_nRE_nOE, 0x0238),
+ MFP_ADDR(DF_ADDR0, 0x024c),
+ MFP_ADDR(DF_ADDR1, 0x0250),
+ MFP_ADDR(DF_ADDR2, 0x025c),
+ MFP_ADDR(DF_ADDR3, 0x0260),
+ MFP_ADDR(DF_IO0, 0x023c),
+ MFP_ADDR(DF_IO1, 0x0240),
+ MFP_ADDR(DF_IO2, 0x0244),
+ MFP_ADDR(DF_IO3, 0x0248),
+ MFP_ADDR(DF_IO4, 0x0264),
+ MFP_ADDR(DF_IO5, 0x0268),
+ MFP_ADDR(DF_IO6, 0x026c),
+ MFP_ADDR(DF_IO7, 0x0270),
+ MFP_ADDR(DF_IO8, 0x0274),
+ MFP_ADDR(DF_IO9, 0x0278),
+ MFP_ADDR(DF_IO10, 0x027c),
+ MFP_ADDR(DF_IO11, 0x0280),
+ MFP_ADDR(DF_IO12, 0x0284),
+ MFP_ADDR(DF_IO13, 0x0288),
+ MFP_ADDR(DF_IO14, 0x028c),
+ MFP_ADDR(DF_IO15, 0x0290),
+
+ MFP_ADDR(GSIM_UIO, 0x0314),
+ MFP_ADDR(GSIM_UCLK, 0x0318),
+ MFP_ADDR(GSIM_UDET, 0x031c),
+ MFP_ADDR(GSIM_nURST, 0x0320),
+
+ MFP_ADDR(PMIC_INT, 0x06c8),
+
+ MFP_ADDR(RDY, 0x0200),
+
+ MFP_ADDR_END,
+};
+
+static struct mfp_addr_map pxa935_mfp_addr_map[] __initdata = {
+ MFP_ADDR(GPIO159, 0x0524),
+ MFP_ADDR(GPIO163, 0x0534),
+ MFP_ADDR(GPIO167, 0x0544),
+ MFP_ADDR(GPIO168, 0x0548),
+ MFP_ADDR(GPIO169, 0x054c),
+ MFP_ADDR(GPIO170, 0x0550),
+ MFP_ADDR(GPIO171, 0x0554),
+ MFP_ADDR(GPIO172, 0x0558),
+ MFP_ADDR(GPIO173, 0x055c),
+
+ MFP_ADDR_END,
+};
+
+static int __init pxa930_init(void)
+{
+ if (cpu_is_pxa93x()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa930_mfp_addr_map);
+ }
+
+ if (cpu_is_pxa935())
+ mfp_init_addr(pxa935_mfp_addr_map);
+
+ return 0;
+}
+
+core_initcall(pxa930_init);
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
new file mode 100644
index 00000000..ecc82a33
--- /dev/null
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -0,0 +1,296 @@
+/*
+ * linux/arch/arm/mach-pxa/pxa95x.c
+ *
+ * code specific to PXA95x aka MGx
+ *
+ * Copyright (C) 2009-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/pxa930.h>
+#include <mach/reset.h>
+#include <mach/pm.h>
+#include <mach/dma.h>
+#include <mach/regs-intc.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+static struct mfp_addr_map pxa95x_mfp_addr_map[] __initdata = {
+
+ MFP_ADDR(GPIO0, 0x02e0),
+ MFP_ADDR(GPIO1, 0x02dc),
+ MFP_ADDR(GPIO2, 0x02e8),
+ MFP_ADDR(GPIO3, 0x02d8),
+ MFP_ADDR(GPIO4, 0x02e4),
+ MFP_ADDR(GPIO5, 0x02ec),
+ MFP_ADDR(GPIO6, 0x02f8),
+ MFP_ADDR(GPIO7, 0x02fc),
+ MFP_ADDR(GPIO8, 0x0300),
+ MFP_ADDR(GPIO9, 0x02d4),
+ MFP_ADDR(GPIO10, 0x02f4),
+ MFP_ADDR(GPIO11, 0x02f0),
+ MFP_ADDR(GPIO12, 0x0304),
+ MFP_ADDR(GPIO13, 0x0310),
+ MFP_ADDR(GPIO14, 0x0308),
+ MFP_ADDR(GPIO15, 0x030c),
+ MFP_ADDR(GPIO16, 0x04e8),
+ MFP_ADDR(GPIO17, 0x04f4),
+ MFP_ADDR(GPIO18, 0x04f8),
+ MFP_ADDR(GPIO19, 0x04fc),
+ MFP_ADDR(GPIO20, 0x0518),
+ MFP_ADDR(GPIO21, 0x051c),
+ MFP_ADDR(GPIO22, 0x04ec),
+ MFP_ADDR(GPIO23, 0x0500),
+ MFP_ADDR(GPIO24, 0x04f0),
+ MFP_ADDR(GPIO25, 0x0504),
+ MFP_ADDR(GPIO26, 0x0510),
+ MFP_ADDR(GPIO27, 0x0514),
+ MFP_ADDR(GPIO28, 0x0520),
+ MFP_ADDR(GPIO29, 0x0600),
+ MFP_ADDR(GPIO30, 0x0618),
+ MFP_ADDR(GPIO31, 0x0610),
+ MFP_ADDR(GPIO32, 0x060c),
+ MFP_ADDR(GPIO33, 0x061c),
+ MFP_ADDR(GPIO34, 0x0620),
+ MFP_ADDR(GPIO35, 0x0628),
+ MFP_ADDR(GPIO36, 0x062c),
+ MFP_ADDR(GPIO37, 0x0630),
+ MFP_ADDR(GPIO38, 0x0634),
+ MFP_ADDR(GPIO39, 0x0638),
+ MFP_ADDR(GPIO40, 0x063c),
+ MFP_ADDR(GPIO41, 0x0614),
+ MFP_ADDR(GPIO42, 0x0624),
+ MFP_ADDR(GPIO43, 0x0608),
+ MFP_ADDR(GPIO44, 0x0604),
+ MFP_ADDR(GPIO45, 0x050c),
+ MFP_ADDR(GPIO46, 0x0508),
+ MFP_ADDR(GPIO47, 0x02bc),
+ MFP_ADDR(GPIO48, 0x02b4),
+ MFP_ADDR(GPIO49, 0x02b8),
+ MFP_ADDR(GPIO50, 0x02c8),
+ MFP_ADDR(GPIO51, 0x02c0),
+ MFP_ADDR(GPIO52, 0x02c4),
+ MFP_ADDR(GPIO53, 0x02d0),
+ MFP_ADDR(GPIO54, 0x02cc),
+ MFP_ADDR(GPIO55, 0x029c),
+ MFP_ADDR(GPIO56, 0x02a0),
+ MFP_ADDR(GPIO57, 0x0294),
+ MFP_ADDR(GPIO58, 0x0298),
+ MFP_ADDR(GPIO59, 0x02a4),
+ MFP_ADDR(GPIO60, 0x02a8),
+ MFP_ADDR(GPIO61, 0x02b0),
+ MFP_ADDR(GPIO62, 0x02ac),
+ MFP_ADDR(GPIO63, 0x0640),
+ MFP_ADDR(GPIO64, 0x065c),
+ MFP_ADDR(GPIO65, 0x0648),
+ MFP_ADDR(GPIO66, 0x0644),
+ MFP_ADDR(GPIO67, 0x0674),
+ MFP_ADDR(GPIO68, 0x0658),
+ MFP_ADDR(GPIO69, 0x0654),
+ MFP_ADDR(GPIO70, 0x0660),
+ MFP_ADDR(GPIO71, 0x0668),
+ MFP_ADDR(GPIO72, 0x0664),
+ MFP_ADDR(GPIO73, 0x0650),
+ MFP_ADDR(GPIO74, 0x066c),
+ MFP_ADDR(GPIO75, 0x064c),
+ MFP_ADDR(GPIO76, 0x0670),
+ MFP_ADDR(GPIO77, 0x0678),
+ MFP_ADDR(GPIO78, 0x067c),
+ MFP_ADDR(GPIO79, 0x0694),
+ MFP_ADDR(GPIO80, 0x069c),
+ MFP_ADDR(GPIO81, 0x06a0),
+ MFP_ADDR(GPIO82, 0x06a4),
+ MFP_ADDR(GPIO83, 0x0698),
+ MFP_ADDR(GPIO84, 0x06bc),
+ MFP_ADDR(GPIO85, 0x06b4),
+ MFP_ADDR(GPIO86, 0x06b0),
+ MFP_ADDR(GPIO87, 0x06c0),
+ MFP_ADDR(GPIO88, 0x06c4),
+ MFP_ADDR(GPIO89, 0x06ac),
+ MFP_ADDR(GPIO90, 0x0680),
+ MFP_ADDR(GPIO91, 0x0684),
+ MFP_ADDR(GPIO92, 0x0688),
+ MFP_ADDR(GPIO93, 0x0690),
+ MFP_ADDR(GPIO94, 0x068c),
+ MFP_ADDR(GPIO95, 0x06a8),
+ MFP_ADDR(GPIO96, 0x06b8),
+ MFP_ADDR(GPIO97, 0x0410),
+ MFP_ADDR(GPIO98, 0x0418),
+ MFP_ADDR(GPIO99, 0x041c),
+ MFP_ADDR(GPIO100, 0x0414),
+ MFP_ADDR(GPIO101, 0x0408),
+ MFP_ADDR(GPIO102, 0x0324),
+ MFP_ADDR(GPIO103, 0x040c),
+ MFP_ADDR(GPIO104, 0x0400),
+ MFP_ADDR(GPIO105, 0x0328),
+ MFP_ADDR(GPIO106, 0x0404),
+
+ MFP_ADDR(GPIO159, 0x0524),
+ MFP_ADDR(GPIO163, 0x0534),
+ MFP_ADDR(GPIO167, 0x0544),
+ MFP_ADDR(GPIO168, 0x0548),
+ MFP_ADDR(GPIO169, 0x054c),
+ MFP_ADDR(GPIO170, 0x0550),
+ MFP_ADDR(GPIO171, 0x0554),
+ MFP_ADDR(GPIO172, 0x0558),
+ MFP_ADDR(GPIO173, 0x055c),
+
+ MFP_ADDR(nXCVREN, 0x0204),
+ MFP_ADDR(DF_CLE_nOE, 0x020c),
+ MFP_ADDR(DF_nADV1_ALE, 0x0218),
+ MFP_ADDR(DF_SCLK_E, 0x0214),
+ MFP_ADDR(DF_SCLK_S, 0x0210),
+ MFP_ADDR(nBE0, 0x021c),
+ MFP_ADDR(nBE1, 0x0220),
+ MFP_ADDR(DF_nADV2_ALE, 0x0224),
+ MFP_ADDR(DF_INT_RnB, 0x0228),
+ MFP_ADDR(DF_nCS0, 0x022c),
+ MFP_ADDR(DF_nCS1, 0x0230),
+ MFP_ADDR(nLUA, 0x0254),
+ MFP_ADDR(nLLA, 0x0258),
+ MFP_ADDR(DF_nWE, 0x0234),
+ MFP_ADDR(DF_nRE_nOE, 0x0238),
+ MFP_ADDR(DF_ADDR0, 0x024c),
+ MFP_ADDR(DF_ADDR1, 0x0250),
+ MFP_ADDR(DF_ADDR2, 0x025c),
+ MFP_ADDR(DF_ADDR3, 0x0260),
+ MFP_ADDR(DF_IO0, 0x023c),
+ MFP_ADDR(DF_IO1, 0x0240),
+ MFP_ADDR(DF_IO2, 0x0244),
+ MFP_ADDR(DF_IO3, 0x0248),
+ MFP_ADDR(DF_IO4, 0x0264),
+ MFP_ADDR(DF_IO5, 0x0268),
+ MFP_ADDR(DF_IO6, 0x026c),
+ MFP_ADDR(DF_IO7, 0x0270),
+ MFP_ADDR(DF_IO8, 0x0274),
+ MFP_ADDR(DF_IO9, 0x0278),
+ MFP_ADDR(DF_IO10, 0x027c),
+ MFP_ADDR(DF_IO11, 0x0280),
+ MFP_ADDR(DF_IO12, 0x0284),
+ MFP_ADDR(DF_IO13, 0x0288),
+ MFP_ADDR(DF_IO14, 0x028c),
+ MFP_ADDR(DF_IO15, 0x0290),
+
+ MFP_ADDR(GSIM_UIO, 0x0314),
+ MFP_ADDR(GSIM_UCLK, 0x0318),
+ MFP_ADDR(GSIM_UDET, 0x031c),
+ MFP_ADDR(GSIM_nURST, 0x0320),
+
+ MFP_ADDR(PMIC_INT, 0x06c8),
+
+ MFP_ADDR(RDY, 0x0200),
+
+ MFP_ADDR_END,
+};
+
+static DEFINE_CK(pxa95x_lcd, LCD, &clk_pxa3xx_hsio_ops);
+static DEFINE_CLK(pxa95x_pout, &clk_pxa3xx_pout_ops, 13000000, 70);
+static DEFINE_PXA3_CKEN(pxa95x_ffuart, FFUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_btuart, BTUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_stuart, STUART, 14857000, 1);
+static DEFINE_PXA3_CKEN(pxa95x_i2c, I2C, 32842000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_keypad, KEYPAD, 32768, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp1, SSP1, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp2, SSP2, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp3, SSP3, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_ssp4, SSP4, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_pwm0, PWM0, 13000000, 0);
+static DEFINE_PXA3_CKEN(pxa95x_pwm1, PWM1, 13000000, 0);
+
+static struct clk_lookup pxa95x_clkregs[] = {
+ INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"),
+ /* Power I2C clock is always on */
+ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL),
+ INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-uart.2", NULL),
+ INIT_CLKREG(&clk_pxa95x_stuart, "pxa2xx-ir", "UARTCLK"),
+ INIT_CLKREG(&clk_pxa95x_i2c, "pxa2xx-i2c.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_keypad, "pxa27x-keypad", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp1, "pxa27x-ssp.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp2, "pxa27x-ssp.1", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp3, "pxa27x-ssp.2", NULL),
+ INIT_CLKREG(&clk_pxa95x_ssp4, "pxa27x-ssp.3", NULL),
+ INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
+ INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
+};
+
+void __init pxa95x_init_irq(void)
+{
+ pxa_init_irq(96, NULL);
+ pxa_init_gpio(IRQ_GPIO_2_x, 2, 127, NULL);
+}
+
+/*
+ * device registration specific to PXA93x.
+ */
+
+void __init pxa95x_set_i2c_power_info(struct i2c_pxa_platform_data *info)
+{
+ pxa_register_device(&pxa3xx_device_i2c_power, info);
+}
+
+static struct platform_device *devices[] __initdata = {
+ &sa1100_device_rtc,
+ &pxa_device_rtc,
+ &pxa27x_device_ssp1,
+ &pxa27x_device_ssp2,
+ &pxa27x_device_ssp3,
+ &pxa3xx_device_ssp4,
+ &pxa27x_device_pwm0,
+ &pxa27x_device_pwm1,
+};
+
+static int __init pxa95x_init(void)
+{
+ int ret = 0, i;
+
+ if (cpu_is_pxa95x()) {
+ mfp_init_base(io_p2v(MFPR_BASE));
+ mfp_init_addr(pxa95x_mfp_addr_map);
+
+ reset_status = ARSR;
+
+ /*
+ * clear RDH bit every time after reset
+ *
+ * Note: the last 3 bits DxS are write-1-to-clear so carefully
+ * preserve them here in case they will be referenced later
+ */
+ ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
+
+ clkdev_add_table(pxa95x_clkregs, ARRAY_SIZE(pxa95x_clkregs));
+
+ if ((ret = pxa_init_dma(IRQ_DMA, 32)))
+ return ret;
+
+ register_syscore_ops(&pxa_irq_syscore_ops);
+ register_syscore_ops(&pxa_gpio_syscore_ops);
+ register_syscore_ops(&pxa3xx_clock_syscore_ops);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+postcore_initcall(pxa95x_init);
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
new file mode 100644
index 00000000..2f37d43f
--- /dev/null
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -0,0 +1,1118 @@
+/*
+ * arch/arm/mach-pxa/raumfeld.c
+ *
+ * Support for the following Raumfeld devices:
+ *
+ * * Controller
+ * * Connector
+ * * Speaker S/M
+ *
+ * See http://www.raumfeld.com for details.
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+#include <linux/input.h>
+#include <linux/rotary_encoder.h>
+#include <linux/gpio_keys.h>
+#include <linux/input/eeti_ts.h>
+#include <linux/leds.h>
+#include <linux/w1-gpio.h>
+#include <linux/sched.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lis3lv02d.h>
+#include <linux/pda_power.h>
+#include <linux/power_supply.h>
+#include <linux/regulator/max8660.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa3xx-regs.h>
+#include <mach/mfp-pxa3xx.h>
+#include <mach/mfp-pxa300.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "generic.h"
+#include "devices.h"
+#include "clock.h"
+
+/* common GPIO definitions */
+
+/* inputs */
+#define GPIO_ON_OFF (14)
+#define GPIO_VOLENC_A (19)
+#define GPIO_VOLENC_B (20)
+#define GPIO_CHARGE_DONE (23)
+#define GPIO_CHARGE_IND (27)
+#define GPIO_TOUCH_IRQ (32)
+#define GPIO_ETH_IRQ (40)
+#define GPIO_SPI_MISO (98)
+#define GPIO_ACCEL_IRQ (104)
+#define GPIO_RESCUE_BOOT (115)
+#define GPIO_DOCK_DETECT (116)
+#define GPIO_KEY1 (117)
+#define GPIO_KEY2 (118)
+#define GPIO_KEY3 (119)
+#define GPIO_CHARGE_USB_OK (112)
+#define GPIO_CHARGE_DC_OK (101)
+#define GPIO_CHARGE_USB_SUSP (102)
+
+/* outputs */
+#define GPIO_SHUTDOWN_SUPPLY (16)
+#define GPIO_SHUTDOWN_BATT (18)
+#define GPIO_CHRG_PEN2 (31)
+#define GPIO_TFT_VA_EN (33)
+#define GPIO_SPDIF_CS (34)
+#define GPIO_LED2 (35)
+#define GPIO_LED1 (36)
+#define GPIO_SPDIF_RESET (38)
+#define GPIO_SPI_CLK (95)
+#define GPIO_MCLK_DAC_CS (96)
+#define GPIO_SPI_MOSI (97)
+#define GPIO_W1_PULLUP_ENABLE (105)
+#define GPIO_DISPLAY_ENABLE (106)
+#define GPIO_MCLK_RESET (111)
+#define GPIO_W2W_RESET (113)
+#define GPIO_W2W_PDN (114)
+#define GPIO_CODEC_RESET (120)
+#define GPIO_AUDIO_VA_ENABLE (124)
+#define GPIO_ACCEL_CS (125)
+#define GPIO_ONE_WIRE (126)
+
+/*
+ * GPIO configurations
+ */
+static mfp_cfg_t raumfeld_controller_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* One-wire */
+ GPIO126_GPIO | MFP_LPM_FLOAT,
+ GPIO105_GPIO | MFP_PULL_LOW | MFP_LPM_PULL_LOW,
+
+ /* CHRG_USB_OK */
+ GPIO101_GPIO | MFP_PULL_HIGH,
+ /* CHRG_USB_OK */
+ GPIO112_GPIO | MFP_PULL_HIGH,
+ /* CHRG_USB_SUSP */
+ GPIO102_GPIO,
+ /* DISPLAY_ENABLE */
+ GPIO106_GPIO,
+ /* DOCK_DETECT */
+ GPIO116_GPIO | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+};
+
+static mfp_cfg_t raumfeld_connector_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* Ethernet */
+ GPIO1_nCS2, /* CS */
+ GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */
+
+ /* SSP for I2S */
+ GPIO85_SSP1_SCLK,
+ GPIO89_SSP1_EXTCLK,
+ GPIO86_SSP1_FRM,
+ GPIO87_SSP1_TXD,
+ GPIO88_SSP1_RXD,
+ GPIO90_SSP1_SYSCLK,
+
+ /* SSP2 for S/PDIF */
+ GPIO25_SSP2_SCLK,
+ GPIO26_SSP2_FRM,
+ GPIO27_SSP2_TXD,
+ GPIO29_SSP2_EXTCLK,
+
+ /* LEDs */
+ GPIO35_GPIO | MFP_LPM_PULL_LOW,
+ GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+static mfp_cfg_t raumfeld_speaker_pin_config[] __initdata = {
+ /* UART1 */
+ GPIO77_UART1_RXD,
+ GPIO78_UART1_TXD,
+ GPIO79_UART1_CTS,
+ GPIO81_UART1_DSR,
+ GPIO83_UART1_DTR,
+ GPIO84_UART1_RTS,
+
+ /* UART3 */
+ GPIO110_UART3_RXD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* I2C */
+ GPIO21_I2C_SCL | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+ GPIO22_I2C_SDA | MFP_LPM_FLOAT | MFP_PULL_FLOAT,
+
+ /* SPI */
+ GPIO34_GPIO, /* SPDIF_CS */
+ GPIO96_GPIO, /* MCLK_CS */
+ GPIO125_GPIO, /* ACCEL_CS */
+
+ /* MMC */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD,
+
+ /* Ethernet */
+ GPIO1_nCS2, /* CS */
+ GPIO40_GPIO | MFP_PULL_HIGH, /* IRQ */
+
+ /* SSP for I2S */
+ GPIO85_SSP1_SCLK,
+ GPIO89_SSP1_EXTCLK,
+ GPIO86_SSP1_FRM,
+ GPIO87_SSP1_TXD,
+ GPIO88_SSP1_RXD,
+ GPIO90_SSP1_SYSCLK,
+
+ /* LEDs */
+ GPIO35_GPIO | MFP_LPM_PULL_LOW,
+ GPIO36_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+/*
+ * SMSC LAN9220 Ethernet
+ */
+
+static struct resource smc91x_resources[] = {
+ {
+ .start = PXA3xx_CS2_PHYS,
+ .end = PXA3xx_CS2_PHYS + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = gpio_to_irq(GPIO_ETH_IRQ),
+ .end = gpio_to_irq(GPIO_ETH_IRQ),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING,
+ }
+};
+
+static struct smsc911x_platform_config raumfeld_smsc911x_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &raumfeld_smsc911x_config,
+ }
+};
+
+/**
+ * NAND
+ */
+
+static struct mtd_partition raumfeld_nand_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = 0xa0000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "BootloaderEnvironment",
+ .offset = 0xa0000,
+ .size = 0x20000,
+ },
+ {
+ .name = "BootloaderSplashScreen",
+ .offset = 0xc0000,
+ .size = 0x60000,
+ },
+ {
+ .name = "UBI",
+ .offset = 0x120000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct pxa3xx_nand_platform_data raumfeld_nand_info = {
+ .enable_arbiter = 1,
+ .keep_config = 1,
+ .parts = raumfeld_nand_partitions,
+ .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions),
+};
+
+/**
+ * USB (OHCI) support
+ */
+
+static struct pxaohci_platform_data raumfeld_ohci_info = {
+ .port_mode = PMM_GLOBAL_MODE,
+ .flags = ENABLE_PORT1,
+};
+
+/**
+ * Rotary encoder input device
+ */
+
+static struct rotary_encoder_platform_data raumfeld_rotary_encoder_info = {
+ .steps = 24,
+ .axis = REL_X,
+ .relative_axis = 1,
+ .gpio_a = GPIO_VOLENC_A,
+ .gpio_b = GPIO_VOLENC_B,
+ .inverted_a = 1,
+ .inverted_b = 0,
+};
+
+static struct platform_device rotary_encoder_device = {
+ .name = "rotary-encoder",
+ .id = 0,
+ .dev = {
+ .platform_data = &raumfeld_rotary_encoder_info,
+ }
+};
+
+/**
+ * GPIO buttons
+ */
+
+static struct gpio_keys_button gpio_keys_button[] = {
+ {
+ .code = KEY_F1,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY1,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 1",
+ },
+ {
+ .code = KEY_F2,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY2,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 2",
+ },
+ {
+ .code = KEY_F3,
+ .type = EV_KEY,
+ .gpio = GPIO_KEY3,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "Button 3",
+ },
+ {
+ .code = KEY_F4,
+ .type = EV_KEY,
+ .gpio = GPIO_RESCUE_BOOT,
+ .active_low = 0,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "rescue boot button",
+ },
+ {
+ .code = KEY_F5,
+ .type = EV_KEY,
+ .gpio = GPIO_DOCK_DETECT,
+ .active_low = 1,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "dock detect",
+ },
+ {
+ .code = KEY_F6,
+ .type = EV_KEY,
+ .gpio = GPIO_ON_OFF,
+ .active_low = 0,
+ .wakeup = 0,
+ .debounce_interval = 5, /* ms */
+ .desc = "on_off button",
+ },
+};
+
+static struct gpio_keys_platform_data gpio_keys_platform_data = {
+ .buttons = gpio_keys_button,
+ .nbuttons = ARRAY_SIZE(gpio_keys_button),
+ .rep = 0,
+};
+
+static struct platform_device raumfeld_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_keys_platform_data,
+ }
+};
+
+/**
+ * GPIO LEDs
+ */
+
+static struct gpio_led raumfeld_leds[] = {
+ {
+ .name = "raumfeld:1",
+ .gpio = GPIO_LED1,
+ .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "raumfeld:2",
+ .gpio = GPIO_LED2,
+ .active_low = 0,
+ .default_state = LEDS_GPIO_DEFSTATE_OFF,
+ }
+};
+
+static struct gpio_led_platform_data raumfeld_led_platform_data = {
+ .leds = raumfeld_leds,
+ .num_leds = ARRAY_SIZE(raumfeld_leds),
+};
+
+static struct platform_device raumfeld_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &raumfeld_led_platform_data,
+ },
+};
+
+/**
+ * One-wire (W1 bus) support
+ */
+
+static void w1_enable_external_pullup(int enable)
+{
+ gpio_set_value(GPIO_W1_PULLUP_ENABLE, enable);
+ msleep(100);
+}
+
+static struct w1_gpio_platform_data w1_gpio_platform_data = {
+ .pin = GPIO_ONE_WIRE,
+ .is_open_drain = 0,
+ .enable_external_pullup = w1_enable_external_pullup,
+};
+
+struct platform_device raumfeld_w1_gpio_device = {
+ .name = "w1-gpio",
+ .dev = {
+ .platform_data = &w1_gpio_platform_data
+ }
+};
+
+static void __init raumfeld_w1_init(void)
+{
+ int ret = gpio_request(GPIO_W1_PULLUP_ENABLE,
+ "W1 external pullup enable");
+
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W1_PULLUP_ENABLE\n");
+ else
+ gpio_direction_output(GPIO_W1_PULLUP_ENABLE, 0);
+
+ platform_device_register(&raumfeld_w1_gpio_device);
+}
+
+/**
+ * Framebuffer device
+ */
+
+/* PWM controlled backlight */
+static struct platform_pwm_backlight_data raumfeld_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ /* 10000 ns = 10 ms ^= 100 kHz */
+ .pwm_period_ns = 10000,
+};
+
+static struct platform_device raumfeld_pwm_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm0.dev,
+ .platform_data = &raumfeld_pwm_backlight_data,
+ }
+};
+
+/* LT3593 controlled backlight */
+static struct gpio_led raumfeld_lt3593_led = {
+ .name = "backlight",
+ .gpio = mfp_to_gpio(MFP_PIN_GPIO17),
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+};
+
+static struct gpio_led_platform_data raumfeld_lt3593_platform_data = {
+ .leds = &raumfeld_lt3593_led,
+ .num_leds = 1,
+};
+
+static struct platform_device raumfeld_lt3593_device = {
+ .name = "leds-lt3593",
+ .id = -1,
+ .dev = {
+ .platform_data = &raumfeld_lt3593_platform_data,
+ },
+};
+
+static struct pxafb_mode_info sharp_lq043t3dx02_mode = {
+ .pixclock = 111000,
+ .xres = 480,
+ .yres = 272,
+ .bpp = 16,
+ .hsync_len = 41,
+ .left_margin = 2,
+ .right_margin = 1,
+ .vsync_len = 10,
+ .upper_margin = 3,
+ .lower_margin = 1,
+ .sync = 0,
+};
+
+static struct pxafb_mach_info raumfeld_sharp_lcd_info = {
+ .modes = &sharp_lq043t3dx02_mode,
+ .num_modes = 1,
+ .video_mem_size = 0x400000,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+#ifdef CONFIG_PXA3XX_GCU
+ .acceleration_enabled = 1,
+#endif
+};
+
+static void __init raumfeld_lcd_init(void)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_TFT_VA_EN\n");
+ else
+ gpio_direction_output(GPIO_TFT_VA_EN, 1);
+
+ msleep(100);
+
+ ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n");
+ else
+ gpio_direction_output(GPIO_DISPLAY_ENABLE, 1);
+
+ /* Hardware revision 2 has the backlight regulator controlled
+ * by an LT3593, earlier and later devices use PWM for that. */
+ if ((system_rev & 0xff) == 2) {
+ platform_device_register(&raumfeld_lt3593_device);
+ } else {
+ mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT;
+ pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1);
+ platform_device_register(&raumfeld_pwm_backlight_device);
+ }
+
+ pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
+ platform_device_register(&pxa3xx_device_gcu);
+}
+
+/**
+ * SPI devices
+ */
+
+struct spi_gpio_platform_data raumfeld_spi_platform_data = {
+ .sck = GPIO_SPI_CLK,
+ .mosi = GPIO_SPI_MOSI,
+ .miso = GPIO_SPI_MISO,
+ .num_chipselect = 3,
+};
+
+static struct platform_device raumfeld_spi_device = {
+ .name = "spi_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &raumfeld_spi_platform_data,
+ }
+};
+
+static struct lis3lv02d_platform_data lis3_pdata = {
+ .click_flags = LIS3_CLICK_SINGLE_X |
+ LIS3_CLICK_SINGLE_Y |
+ LIS3_CLICK_SINGLE_Z,
+ .irq_cfg = LIS3_IRQ1_CLICK | LIS3_IRQ2_CLICK,
+ .wakeup_flags = LIS3_WAKEUP_X_LO | LIS3_WAKEUP_X_HI |
+ LIS3_WAKEUP_Y_LO | LIS3_WAKEUP_Y_HI |
+ LIS3_WAKEUP_Z_LO | LIS3_WAKEUP_Z_HI,
+ .wakeup_thresh = 10,
+ .click_thresh_x = 10,
+ .click_thresh_y = 10,
+ .click_thresh_z = 10,
+};
+
+#define SPI_AK4104 \
+{ \
+ .modalias = "ak4104-codec", \
+ .max_speed_hz = 10000, \
+ .bus_num = 0, \
+ .chip_select = 0, \
+ .controller_data = (void *) GPIO_SPDIF_CS, \
+}
+
+#define SPI_LIS3 \
+{ \
+ .modalias = "lis3lv02d_spi", \
+ .max_speed_hz = 1000000, \
+ .bus_num = 0, \
+ .chip_select = 1, \
+ .controller_data = (void *) GPIO_ACCEL_CS, \
+ .platform_data = &lis3_pdata, \
+ .irq = gpio_to_irq(GPIO_ACCEL_IRQ), \
+}
+
+#define SPI_DAC7512 \
+{ \
+ .modalias = "dac7512", \
+ .max_speed_hz = 1000000, \
+ .bus_num = 0, \
+ .chip_select = 2, \
+ .controller_data = (void *) GPIO_MCLK_DAC_CS, \
+}
+
+static struct spi_board_info connector_spi_devices[] __initdata = {
+ SPI_AK4104,
+ SPI_DAC7512,
+};
+
+static struct spi_board_info speaker_spi_devices[] __initdata = {
+ SPI_DAC7512,
+};
+
+static struct spi_board_info controller_spi_devices[] __initdata = {
+ SPI_LIS3,
+};
+
+/**
+ * MMC for Marvell Libertas 8688 via SDIO
+ */
+
+static int raumfeld_mci_init(struct device *dev, irq_handler_t isr, void *data)
+{
+ gpio_set_value(GPIO_W2W_RESET, 1);
+ gpio_set_value(GPIO_W2W_PDN, 1);
+
+ return 0;
+}
+
+static void raumfeld_mci_exit(struct device *dev, void *data)
+{
+ gpio_set_value(GPIO_W2W_RESET, 0);
+ gpio_set_value(GPIO_W2W_PDN, 0);
+}
+
+static struct pxamci_platform_data raumfeld_mci_platform_data = {
+ .init = raumfeld_mci_init,
+ .exit = raumfeld_mci_exit,
+ .detect_delay_ms = 200,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+/*
+ * External power / charge logic
+ */
+
+static int power_supply_init(struct device *dev)
+{
+ return 0;
+}
+
+static void power_supply_exit(struct device *dev)
+{
+}
+
+static int raumfeld_is_ac_online(void)
+{
+ return !gpio_get_value(GPIO_CHARGE_DC_OK);
+}
+
+static int raumfeld_is_usb_online(void)
+{
+ return 0;
+}
+
+static char *raumfeld_power_supplicants[] = { "ds2760-battery.0" };
+
+static void raumfeld_power_signal_charged(void)
+{
+ struct power_supply *psy =
+ power_supply_get_by_name(raumfeld_power_supplicants[0]);
+
+ if (psy)
+ power_supply_set_battery_charged(psy);
+}
+
+static int raumfeld_power_resume(void)
+{
+ /* check if GPIO_CHARGE_DONE went low while we were sleeping */
+ if (!gpio_get_value(GPIO_CHARGE_DONE))
+ raumfeld_power_signal_charged();
+
+ return 0;
+}
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = raumfeld_is_ac_online,
+ .is_usb_online = raumfeld_is_usb_online,
+ .exit = power_supply_exit,
+ .supplied_to = raumfeld_power_supplicants,
+ .num_supplicants = ARRAY_SIZE(raumfeld_power_supplicants),
+ .resume = raumfeld_power_resume,
+};
+
+static struct resource power_supply_resources[] = {
+ {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
+ .start = GPIO_CHARGE_DC_OK,
+ .end = GPIO_CHARGE_DC_OK,
+ },
+};
+
+static irqreturn_t charge_done_irq(int irq, void *dev_id)
+{
+ raumfeld_power_signal_charged();
+ return IRQ_HANDLED;
+}
+
+static struct platform_device raumfeld_power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data = &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static void __init raumfeld_power_init(void)
+{
+ int ret;
+
+ /* Set PEN2 high to enable maximum charge current */
+ ret = gpio_request(GPIO_CHRG_PEN2, "CHRG_PEN2");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHRG_PEN2\n");
+ else
+ gpio_direction_output(GPIO_CHRG_PEN2, 1);
+
+ ret = gpio_request(GPIO_CHARGE_DC_OK, "CABLE_DC_OK");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHARGE_DC_OK\n");
+
+ ret = gpio_request(GPIO_CHARGE_USB_SUSP, "CHARGE_USB_SUSP");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_CHARGE_USB_SUSP\n");
+ else
+ gpio_direction_output(GPIO_CHARGE_USB_SUSP, 0);
+
+ power_supply_resources[0].start = gpio_to_irq(GPIO_CHARGE_DC_OK);
+ power_supply_resources[0].end = gpio_to_irq(GPIO_CHARGE_DC_OK);
+
+ ret = request_irq(gpio_to_irq(GPIO_CHARGE_DONE),
+ &charge_done_irq, IORESOURCE_IRQ_LOWEDGE,
+ "charge_done", NULL);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: unable to register irq %d\n", __func__,
+ GPIO_CHARGE_DONE);
+ else
+ platform_device_register(&raumfeld_power_supply);
+}
+
+/* Fixed regulator for AUDIO_VA, 0-0048 maps to the cs4270 codec device */
+
+static struct regulator_consumer_supply audio_va_consumer_supply =
+ REGULATOR_SUPPLY("va", "0-0048");
+
+struct regulator_init_data audio_va_initdata = {
+ .consumer_supplies = &audio_va_consumer_supply,
+ .num_consumer_supplies = 1,
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config audio_va_config = {
+ .supply_name = "audio_va",
+ .microvolts = 5000000,
+ .gpio = GPIO_AUDIO_VA_ENABLE,
+ .enable_high = 1,
+ .enabled_at_boot = 0,
+ .init_data = &audio_va_initdata,
+};
+
+static struct platform_device audio_va_device = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &audio_va_config,
+ },
+};
+
+/* Dummy supplies for Codec's VD/VLC */
+
+static struct regulator_consumer_supply audio_dummy_supplies[] = {
+ REGULATOR_SUPPLY("vd", "0-0048"),
+ REGULATOR_SUPPLY("vlc", "0-0048"),
+};
+
+struct regulator_init_data audio_dummy_initdata = {
+ .consumer_supplies = audio_dummy_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(audio_dummy_supplies),
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct fixed_voltage_config audio_dummy_config = {
+ .supply_name = "audio_vd",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &audio_dummy_initdata,
+};
+
+static struct platform_device audio_supply_dummy_device = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &audio_dummy_config,
+ },
+};
+
+static struct platform_device *audio_regulator_devices[] = {
+ &audio_va_device,
+ &audio_supply_dummy_device,
+};
+
+/**
+ * Regulator support via MAX8660
+ */
+
+static struct regulator_consumer_supply vcc_mmc_supply =
+ REGULATOR_SUPPLY("vmmc", "pxa2xx-mci.0");
+
+static struct regulator_init_data vcc_mmc_init_data = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_MODE,
+ },
+ .consumer_supplies = &vcc_mmc_supply,
+ .num_consumer_supplies = 1,
+};
+
+struct max8660_subdev_data max8660_v6_subdev_data = {
+ .id = MAX8660_V6,
+ .name = "vmmc",
+ .platform_data = &vcc_mmc_init_data,
+};
+
+static struct max8660_platform_data max8660_pdata = {
+ .subdevs = &max8660_v6_subdev_data,
+ .num_subdevs = 1,
+};
+
+/**
+ * I2C devices
+ */
+
+static struct i2c_board_info raumfeld_pwri2c_board_info = {
+ .type = "max8660",
+ .addr = 0x34,
+ .platform_data = &max8660_pdata,
+};
+
+static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = {
+ .type = "cs4270",
+ .addr = 0x48,
+};
+
+static struct eeti_ts_platform_data eeti_ts_pdata = {
+ .irq_active_high = 1,
+};
+
+static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = {
+ .type = "eeti_ts",
+ .addr = 0x0a,
+ .irq = gpio_to_irq(GPIO_TOUCH_IRQ),
+ .platform_data = &eeti_ts_pdata,
+};
+
+static struct platform_device *raumfeld_common_devices[] = {
+ &raumfeld_gpio_keys_device,
+ &raumfeld_led_device,
+ &raumfeld_spi_device,
+};
+
+static void __init raumfeld_audio_init(void)
+{
+ int ret;
+
+ ret = gpio_request(GPIO_CODEC_RESET, "cs4270 reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_CODEC_RESET\n");
+ else
+ gpio_direction_output(GPIO_CODEC_RESET, 1);
+
+ ret = gpio_request(GPIO_SPDIF_RESET, "ak4104 s/pdif reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_SPDIF_RESET\n");
+ else
+ gpio_direction_output(GPIO_SPDIF_RESET, 1);
+
+ ret = gpio_request(GPIO_MCLK_RESET, "MCLK reset");
+ if (ret < 0)
+ pr_warning("unable to request GPIO_MCLK_RESET\n");
+ else
+ gpio_direction_output(GPIO_MCLK_RESET, 1);
+
+ platform_add_devices(ARRAY_AND_SIZE(audio_regulator_devices));
+}
+
+static void __init raumfeld_common_init(void)
+{
+ int ret;
+
+ /* The on/off button polarity has changed after revision 1 */
+ if ((system_rev & 0xff) > 1) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(gpio_keys_button); i++)
+ if (!strcmp(gpio_keys_button[i].desc, "on_off button"))
+ gpio_keys_button[i].active_low = 1;
+ }
+
+ enable_irq_wake(IRQ_WAKEUP0);
+
+ pxa3xx_set_nand_info(&raumfeld_nand_info);
+ pxa3xx_set_i2c_power_info(NULL);
+ pxa_set_ohci_info(&raumfeld_ohci_info);
+ pxa_set_mci_info(&raumfeld_mci_platform_data);
+ pxa_set_i2c_info(NULL);
+ pxa_set_ffuart_info(NULL);
+
+ ret = gpio_request(GPIO_W2W_RESET, "Wi2Wi reset");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W2W_RESET\n");
+ else
+ gpio_direction_output(GPIO_W2W_RESET, 0);
+
+ ret = gpio_request(GPIO_W2W_PDN, "Wi2Wi powerup");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_W2W_PDN\n");
+ else
+ gpio_direction_output(GPIO_W2W_PDN, 0);
+
+ /* this can be used to switch off the device */
+ ret = gpio_request(GPIO_SHUTDOWN_SUPPLY, "supply shutdown");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_SHUTDOWN_SUPPLY\n");
+ else
+ gpio_direction_output(GPIO_SHUTDOWN_SUPPLY, 0);
+
+ platform_add_devices(ARRAY_AND_SIZE(raumfeld_common_devices));
+ i2c_register_board_info(1, &raumfeld_pwri2c_board_info, 1);
+}
+
+static void __init raumfeld_controller_init(void)
+{
+ int ret;
+
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config));
+ platform_device_register(&rotary_encoder_device);
+ spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices));
+ i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1);
+
+ ret = gpio_request(GPIO_SHUTDOWN_BATT, "battery shutdown");
+ if (ret < 0)
+ pr_warning("Unable to request GPIO_SHUTDOWN_BATT\n");
+ else
+ gpio_direction_output(GPIO_SHUTDOWN_BATT, 0);
+
+ raumfeld_common_init();
+ raumfeld_power_init();
+ raumfeld_lcd_init();
+ raumfeld_w1_init();
+}
+
+static void __init raumfeld_connector_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_connector_pin_config));
+ spi_register_board_info(ARRAY_AND_SIZE(connector_spi_devices));
+ i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+ platform_device_register(&smc91x_device);
+
+ raumfeld_audio_init();
+ raumfeld_common_init();
+}
+
+static void __init raumfeld_speaker_init(void)
+{
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_speaker_pin_config));
+ spi_register_board_info(ARRAY_AND_SIZE(speaker_spi_devices));
+ i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1);
+
+ platform_device_register(&smc91x_device);
+ platform_device_register(&rotary_encoder_device);
+
+ raumfeld_audio_init();
+ raumfeld_common_init();
+}
+
+/* physical memory regions */
+#define RAUMFELD_SDRAM_BASE 0xa0000000 /* SDRAM region */
+
+#ifdef CONFIG_MACH_RAUMFELD_RC
+MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_controller_init,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_CONNECTOR
+MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_connector_init,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_RAUMFELD_SPEAKER
+MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
+ .boot_params = RAUMFELD_SDRAM_BASE + 0x100,
+ .init_machine = raumfeld_speaker_init,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c
new file mode 100644
index 00000000..01e9d643
--- /dev/null
+++ b/arch/arm/mach-pxa/reset.c
@@ -0,0 +1,102 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <asm/proc-fns.h>
+
+#include <mach/regs-ost.h>
+#include <mach/reset.h>
+
+unsigned int reset_status;
+EXPORT_SYMBOL(reset_status);
+
+static void do_hw_reset(void);
+
+static int reset_gpio = -1;
+
+int init_gpio_reset(int gpio, int output, int level)
+{
+ int rc;
+
+ rc = gpio_request(gpio, "reset generator");
+ if (rc) {
+ printk(KERN_ERR "Can't request reset_gpio\n");
+ goto out;
+ }
+
+ if (output)
+ rc = gpio_direction_output(gpio, level);
+ else
+ rc = gpio_direction_input(gpio);
+ if (rc) {
+ printk(KERN_ERR "Can't configure reset_gpio\n");
+ gpio_free(gpio);
+ goto out;
+ }
+
+out:
+ if (!rc)
+ reset_gpio = gpio;
+
+ return rc;
+}
+
+/*
+ * Trigger GPIO reset.
+ * This covers various types of logic connecting gpio pin
+ * to RESET pins (nRESET or GPIO_RESET):
+ */
+static void do_gpio_reset(void)
+{
+ BUG_ON(reset_gpio == -1);
+
+ /* drive it low */
+ gpio_direction_output(reset_gpio, 0);
+ mdelay(2);
+ /* rising edge or drive high */
+ gpio_set_value(reset_gpio, 1);
+ mdelay(2);
+ /* falling edge */
+ gpio_set_value(reset_gpio, 0);
+
+ /* give it some time */
+ mdelay(10);
+
+ WARN_ON(1);
+ /* fallback */
+ do_hw_reset();
+}
+
+static void do_hw_reset(void)
+{
+ /* Initialize the watchdog and let it fire */
+ OWER = OWER_WME;
+ OSSR = OSSR_M3;
+ OSMR3 = OSCR + 368640; /* ... in 100 ms */
+}
+
+void arch_reset(char mode, const char *cmd)
+{
+ clear_reset_status(RESET_STATUS_ALL);
+
+ switch (mode) {
+ case 's':
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+ break;
+ case 'g':
+ do_gpio_reset();
+ break;
+ case 'h':
+ default:
+ do_hw_reset();
+ break;
+ }
+}
+
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
new file mode 100644
index 00000000..fee97a93
--- /dev/null
+++ b/arch/arm/mach-pxa/saar.c
@@ -0,0 +1,604 @@
+/*
+ * linux/arch/arm/mach-pxa/saar.c
+ *
+ * Support for the Marvell PXA930 Handheld Platform (aka SAAR)
+ *
+ * Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/smc91x.h>
+#include <linux/mfd/da903x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/onenand.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa930.h>
+#include <mach/pxafb.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define GPIO_LCD_RESET (16)
+
+/* SAAR MFP configurations */
+static mfp_cfg_t saar_mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO23_LCD_DD0,
+ GPIO24_LCD_DD1,
+ GPIO25_LCD_DD2,
+ GPIO26_LCD_DD3,
+ GPIO27_LCD_DD4,
+ GPIO28_LCD_DD5,
+ GPIO29_LCD_DD6,
+ GPIO44_LCD_DD7,
+ GPIO21_LCD_CS,
+ GPIO22_LCD_VSYNC,
+ GPIO17_LCD_FCLK_RD,
+ GPIO18_LCD_LCLK_A0,
+ GPIO19_LCD_PCLK_WR,
+ GPIO16_GPIO, /* LCD reset */
+
+ /* Ethernet */
+ DF_nCS1_nCS3,
+ GPIO97_GPIO,
+
+ /* DFI */
+ DF_INT_RnB_ND_INT_RnB,
+ DF_nRE_nOE_ND_nRE,
+ DF_nWE_ND_nWE,
+ DF_CLE_nOE_ND_CLE,
+ DF_nADV1_ALE_ND_ALE,
+ DF_nADV2_ALE_nCS3,
+ DF_nCS0_ND_nCS0,
+ DF_IO0_ND_IO0,
+ DF_IO1_ND_IO1,
+ DF_IO2_ND_IO2,
+ DF_IO3_ND_IO3,
+ DF_IO4_ND_IO4,
+ DF_IO5_ND_IO5,
+ DF_IO6_ND_IO6,
+ DF_IO7_ND_IO7,
+ DF_IO8_ND_IO8,
+ DF_IO9_ND_IO9,
+ DF_IO10_ND_IO10,
+ DF_IO11_ND_IO11,
+ DF_IO12_ND_IO12,
+ DF_IO13_ND_IO13,
+ DF_IO14_ND_IO14,
+ DF_IO15_ND_IO15,
+};
+
+#define SAAR_ETH_PHYS (0x14000000)
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = (SAAR_ETH_PHYS + 0x300),
+ .end = (SAAR_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO97)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata saar_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &saar_smc91x_info,
+ },
+};
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static uint16_t lcd_power_on[] = {
+ /* single frame */
+ SMART_CMD_NOOP,
+ SMART_CMD(0x00),
+ SMART_DELAY(0),
+
+ SMART_CMD_NOOP,
+ SMART_CMD(0x00),
+ SMART_DELAY(0),
+
+ SMART_CMD_NOOP,
+ SMART_CMD(0x00),
+ SMART_DELAY(0),
+
+ SMART_CMD_NOOP,
+ SMART_CMD(0x00),
+ SMART_DELAY(10),
+
+ /* calibration control */
+ SMART_CMD(0x00),
+ SMART_CMD(0xA4),
+ SMART_DAT(0x80),
+ SMART_DAT(0x01),
+ SMART_DELAY(150),
+
+ /*Power-On Init sequence*/
+ SMART_CMD(0x00), /* output ctrl */
+ SMART_CMD(0x01),
+ SMART_DAT(0x01),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* wave ctrl */
+ SMART_CMD(0x02),
+ SMART_DAT(0x07),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x03), /* entry mode */
+ SMART_DAT(0xD0),
+ SMART_DAT(0x30),
+ SMART_CMD(0x00),
+ SMART_CMD(0x08), /* display ctrl 2 */
+ SMART_DAT(0x08),
+ SMART_DAT(0x08),
+ SMART_CMD(0x00),
+ SMART_CMD(0x09), /* display ctrl 3 */
+ SMART_DAT(0x04),
+ SMART_DAT(0x2F),
+ SMART_CMD(0x00),
+ SMART_CMD(0x0A), /* display ctrl 4 */
+ SMART_DAT(0x00),
+ SMART_DAT(0x08),
+ SMART_CMD(0x00),
+ SMART_CMD(0x0D), /* Frame Marker position */
+ SMART_DAT(0x00),
+ SMART_DAT(0x08),
+ SMART_CMD(0x00),
+ SMART_CMD(0x60), /* Driver output control */
+ SMART_DAT(0x27),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x61), /* Base image display control */
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_CMD(0x00),
+ SMART_CMD(0x30), /* Y settings 30h-3Dh */
+ SMART_DAT(0x07),
+ SMART_DAT(0x07),
+ SMART_CMD(0x00),
+ SMART_CMD(0x31),
+ SMART_DAT(0x00),
+ SMART_DAT(0x07),
+ SMART_CMD(0x00),
+ SMART_CMD(0x32), /* Timing(3), ASW HOLD=0.5CLK */
+ SMART_DAT(0x04),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x33), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */
+ SMART_DAT(0x03),
+ SMART_DAT(0x03),
+ SMART_CMD(0x00),
+ SMART_CMD(0x34),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x35),
+ SMART_DAT(0x02),
+ SMART_DAT(0x05),
+ SMART_CMD(0x00),
+ SMART_CMD(0x36),
+ SMART_DAT(0x1F),
+ SMART_DAT(0x1F),
+ SMART_CMD(0x00),
+ SMART_CMD(0x37),
+ SMART_DAT(0x07),
+ SMART_DAT(0x07),
+ SMART_CMD(0x00),
+ SMART_CMD(0x38),
+ SMART_DAT(0x00),
+ SMART_DAT(0x07),
+ SMART_CMD(0x00),
+ SMART_CMD(0x39),
+ SMART_DAT(0x04),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x3A),
+ SMART_DAT(0x03),
+ SMART_DAT(0x03),
+ SMART_CMD(0x00),
+ SMART_CMD(0x3B),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x3C),
+ SMART_DAT(0x02),
+ SMART_DAT(0x05),
+ SMART_CMD(0x00),
+ SMART_CMD(0x3D),
+ SMART_DAT(0x1F),
+ SMART_DAT(0x1F),
+ SMART_CMD(0x00), /* Display control 1 */
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_CMD(0x00), /* Power control 5 */
+ SMART_CMD(0x17),
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_CMD(0x00), /* Power control 1 */
+ SMART_CMD(0x10),
+ SMART_DAT(0x10),
+ SMART_DAT(0xB0),
+ SMART_CMD(0x00), /* Power control 2 */
+ SMART_CMD(0x11),
+ SMART_DAT(0x01),
+ SMART_DAT(0x30),
+ SMART_CMD(0x00), /* Power control 3 */
+ SMART_CMD(0x12),
+ SMART_DAT(0x01),
+ SMART_DAT(0x9E),
+ SMART_CMD(0x00), /* Power control 4 */
+ SMART_CMD(0x13),
+ SMART_DAT(0x17),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* Power control 3 */
+ SMART_CMD(0x12),
+ SMART_DAT(0x01),
+ SMART_DAT(0xBE),
+ SMART_DELAY(100),
+
+ /* display mode : 240*320 */
+ SMART_CMD(0x00), /* RAM address set(H) 0*/
+ SMART_CMD(0x20),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* RAM address set(V) 4*/
+ SMART_CMD(0x21),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* Start of Window RAM address set(H) 8*/
+ SMART_CMD(0x50),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* End of Window RAM address set(H) 12*/
+ SMART_CMD(0x51),
+ SMART_DAT(0x00),
+ SMART_DAT(0xEF),
+ SMART_CMD(0x00), /* Start of Window RAM address set(V) 16*/
+ SMART_CMD(0x52),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* End of Window RAM address set(V) 20*/
+ SMART_CMD(0x53),
+ SMART_DAT(0x01),
+ SMART_DAT(0x3F),
+ SMART_CMD(0x00), /* Panel interface control 1 */
+ SMART_CMD(0x90),
+ SMART_DAT(0x00),
+ SMART_DAT(0x1A),
+ SMART_CMD(0x00), /* Panel interface control 2 */
+ SMART_CMD(0x92),
+ SMART_DAT(0x04),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* Panel interface control 3 */
+ SMART_CMD(0x93),
+ SMART_DAT(0x00),
+ SMART_DAT(0x05),
+ SMART_DELAY(20),
+};
+
+static uint16_t lcd_panel_on[] = {
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x21),
+ SMART_DELAY(1),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x61),
+ SMART_DELAY(100),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x01),
+ SMART_DAT(0x73),
+ SMART_DELAY(1),
+};
+
+static uint16_t lcd_panel_off[] = {
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x72),
+ SMART_DELAY(40),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_DELAY(1),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_DELAY(1),
+};
+
+static uint16_t lcd_power_off[] = {
+ SMART_CMD(0x00),
+ SMART_CMD(0x10),
+ SMART_DAT(0x00),
+ SMART_DAT(0x80),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x11),
+ SMART_DAT(0x01),
+ SMART_DAT(0x60),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x12),
+ SMART_DAT(0x01),
+ SMART_DAT(0xAE),
+ SMART_DELAY(40),
+
+ SMART_CMD(0x00),
+ SMART_CMD(0x10),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+};
+
+static uint16_t update_framedata[] = {
+ /* set display ram: 240*320 */
+ SMART_CMD(0x00), /* RAM address set(H) 0*/
+ SMART_CMD(0x20),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* RAM address set(V) 4*/
+ SMART_CMD(0x21),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* Start of Window RAM address set(H) 8 */
+ SMART_CMD(0x50),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* End of Window RAM address set(H) 12 */
+ SMART_CMD(0x51),
+ SMART_DAT(0x00),
+ SMART_DAT(0xEF),
+ SMART_CMD(0x00), /* Start of Window RAM address set(V) 16 */
+ SMART_CMD(0x52),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00), /* End of Window RAM address set(V) 20 */
+ SMART_CMD(0x53),
+ SMART_DAT(0x01),
+ SMART_DAT(0x3F),
+
+ /* wait for vsync cmd before transferring frame data */
+ SMART_CMD_WAIT_FOR_VSYNC,
+
+ /* write ram */
+ SMART_CMD(0x00),
+ SMART_CMD(0x22),
+
+ /* write frame data */
+ SMART_CMD_WRITE_FRAME,
+};
+
+static void ltm022a97a_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+ static int pin_requested = 0;
+ struct fb_info *info = container_of(var, struct fb_info, var);
+ int err;
+
+ if (!pin_requested) {
+ err = gpio_request(GPIO_LCD_RESET, "lcd reset");
+ if (err) {
+ pr_err("failed to request gpio for LCD reset\n");
+ return;
+ }
+
+ gpio_direction_output(GPIO_LCD_RESET, 0);
+ pin_requested = 1;
+ }
+
+ if (on) {
+ gpio_set_value(GPIO_LCD_RESET, 0); msleep(100);
+ gpio_set_value(GPIO_LCD_RESET, 1); msleep(10);
+
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_on));
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_on));
+ } else {
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_panel_off));
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(lcd_power_off));
+ }
+
+ err = pxafb_smart_flush(info);
+ if (err)
+ pr_err("%s: timed out\n", __func__);
+}
+
+static void ltm022a97a_update(struct fb_info *info)
+{
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata));
+ pxafb_smart_flush(info);
+}
+
+static struct pxafb_mode_info toshiba_ltm022a97a_modes[] = {
+ [0] = {
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .a0csrd_set_hld = 30,
+ .a0cswr_set_hld = 30,
+ .wr_pulse_width = 30,
+ .rd_pulse_width = 30,
+ .op_hold_time = 30,
+ .cmd_inh_time = 60,
+
+ /* L_LCLK_A0 and L_LCLK_RD active low */
+ .sync = FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
+static struct pxafb_mach_info saar_lcd_info = {
+ .modes = toshiba_ltm022a97a_modes,
+ .num_modes = 1,
+ .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = ltm022a97a_lcd_power,
+ .smart_update = ltm022a97a_update,
+};
+
+static void __init saar_init_lcd(void)
+{
+ pxa_set_fb_info(NULL, &saar_lcd_info);
+}
+#else
+static inline void saar_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct da9034_backlight_pdata saar_da9034_backlight = {
+ .output_current = 4, /* 4mA */
+};
+
+static struct da903x_subdev_info saar_da9034_subdevs[] = {
+ [0] = {
+ .name = "da903x-backlight",
+ .id = DA9034_ID_WLED,
+ .platform_data = &saar_da9034_backlight,
+ },
+};
+
+static struct da903x_platform_data saar_da9034_info = {
+ .num_subdevs = ARRAY_SIZE(saar_da9034_subdevs),
+ .subdevs = saar_da9034_subdevs,
+};
+
+static struct i2c_board_info saar_i2c_info[] = {
+ [0] = {
+ .type = "da9034",
+ .addr = 0x34,
+ .platform_data = &saar_da9034_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+ },
+};
+
+static void __init saar_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(saar_i2c_info));
+}
+#else
+static inline void saar_init_i2c(void) {}
+#endif
+
+#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
+static struct mtd_partition saar_onenand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_1M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "reserved",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_8M,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (SZ_2M + SZ_1M),
+ .mask_flags = 0,
+ }, {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_48M,
+ .mask_flags = 0,
+ }
+};
+
+static struct onenand_platform_data saar_onenand_info = {
+ .parts = saar_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(saar_onenand_partitions),
+};
+
+#define SMC_CS0_PHYS_BASE (0x10000000)
+
+static struct resource saar_resource_onenand[] = {
+ [0] = {
+ .start = SMC_CS0_PHYS_BASE,
+ .end = SMC_CS0_PHYS_BASE + SZ_1M,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device saar_device_onenand = {
+ .name = "onenand-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &saar_onenand_info,
+ },
+ .resource = saar_resource_onenand,
+ .num_resources = ARRAY_SIZE(saar_resource_onenand),
+};
+
+static void __init saar_init_onenand(void)
+{
+ platform_device_register(&saar_device_onenand);
+}
+#else
+static void __init saar_init_onenand(void) {}
+#endif
+
+static void __init saar_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(saar_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_device_register(&smc91x_device);
+ saar_init_onenand();
+
+ saar_init_i2c();
+ saar_init_lcd();
+}
+
+MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
+ /* Maintainer: Eric Miao <eric.miao@marvell.com> */
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = saar_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
new file mode 100644
index 00000000..9322fe52
--- /dev/null
+++ b/arch/arm/mach-pxa/saarb.c
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-pxa/saarb.c
+ *
+ * Support for the Marvell Handheld Platform (aka SAARB)
+ *
+ * Copyright (C) 2007-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/irqs.h>
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+#include <mach/mfp-pxa930.h>
+#include <mach/gpio.h>
+
+#include "generic.h"
+
+#define SAARB_NR_IRQS (IRQ_BOARD_START + 40)
+
+static struct pm860x_touch_pdata saarb_touch = {
+ .gpadc_prebias = 1,
+ .slot_cycle = 1,
+ .tsi_prebias = 6,
+ .pen_prebias = 16,
+ .pen_prechg = 2,
+ .res_x = 300,
+};
+
+static struct pm860x_backlight_pdata saarb_backlight[] = {
+ {
+ .id = PM8606_ID_BACKLIGHT,
+ .iset = PM8606_WLED_CURRENT(24),
+ .flags = PM8606_BACKLIGHT1,
+ },
+ {},
+};
+
+static struct pm860x_led_pdata saarb_led[] = {
+ {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_BLUE,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_BLUE,
+ },
+};
+
+static struct pm860x_platform_data saarb_pm8607_info = {
+ .touch = &saarb_touch,
+ .backlight = &saarb_backlight[0],
+ .led = &saarb_led[0],
+ .companion_addr = 0x10,
+ .irq_mode = 0,
+ .irq_base = IRQ_BOARD_START,
+
+ .i2c_port = GI2C_PORT,
+};
+
+static struct i2c_board_info saarb_i2c_info[] = {
+ {
+ .type = "88PM860x",
+ .addr = 0x34,
+ .platform_data = &saarb_pm8607_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+ },
+};
+
+static void __init saarb_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(saarb_i2c_info));
+}
+
+MACHINE_START(SAARB, "PXA955 Handheld Platform (aka SAARB)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa_map_io,
+ .nr_irqs = SAARB_NR_IRQS,
+ .init_irq = pxa95x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = saarb_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
new file mode 100644
index 00000000..785880f6
--- /dev/null
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -0,0 +1,999 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
+ * series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on code written by Sharp for 2.4 kernels
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/suspend.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <mach/pm.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/regs-rtc.h>
+#include <mach/sharpsl_pm.h>
+
+/*
+ * Constants
+ */
+#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */
+#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */
+#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */
+#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */
+
+#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */
+#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */
+#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */
+#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */
+#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */
+
+/*
+ * Prototypes
+ */
+#ifdef CONFIG_PM
+static int sharpsl_off_charge_battery(void);
+static int sharpsl_check_battery_voltage(void);
+static int sharpsl_fatal_check(void);
+#endif
+static int sharpsl_check_battery_temp(void);
+static int sharpsl_ac_check(void);
+static int sharpsl_average_value(int ad);
+static void sharpsl_average_clear(void);
+static void sharpsl_charge_toggle(struct work_struct *private_);
+static void sharpsl_battery_thread(struct work_struct *private_);
+
+
+/*
+ * Variables
+ */
+struct sharpsl_pm_status sharpsl_pm;
+static DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle);
+static DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread);
+DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger);
+
+
+
+struct battery_thresh sharpsl_battery_levels_acin[] = {
+ { 213, 100},
+ { 212, 98},
+ { 211, 95},
+ { 210, 93},
+ { 209, 90},
+ { 208, 88},
+ { 207, 85},
+ { 206, 83},
+ { 205, 80},
+ { 204, 78},
+ { 203, 75},
+ { 202, 73},
+ { 201, 70},
+ { 200, 68},
+ { 199, 65},
+ { 198, 63},
+ { 197, 60},
+ { 196, 58},
+ { 195, 55},
+ { 194, 53},
+ { 193, 50},
+ { 192, 48},
+ { 192, 45},
+ { 191, 43},
+ { 191, 40},
+ { 190, 38},
+ { 190, 35},
+ { 189, 33},
+ { 188, 30},
+ { 187, 28},
+ { 186, 25},
+ { 185, 23},
+ { 184, 20},
+ { 183, 18},
+ { 182, 15},
+ { 181, 13},
+ { 180, 10},
+ { 179, 8},
+ { 178, 5},
+ { 0, 0},
+};
+
+struct battery_thresh sharpsl_battery_levels_noac[] = {
+ { 213, 100},
+ { 212, 98},
+ { 211, 95},
+ { 210, 93},
+ { 209, 90},
+ { 208, 88},
+ { 207, 85},
+ { 206, 83},
+ { 205, 80},
+ { 204, 78},
+ { 203, 75},
+ { 202, 73},
+ { 201, 70},
+ { 200, 68},
+ { 199, 65},
+ { 198, 63},
+ { 197, 60},
+ { 196, 58},
+ { 195, 55},
+ { 194, 53},
+ { 193, 50},
+ { 192, 48},
+ { 191, 45},
+ { 190, 43},
+ { 189, 40},
+ { 188, 38},
+ { 187, 35},
+ { 186, 33},
+ { 185, 30},
+ { 184, 28},
+ { 183, 25},
+ { 182, 23},
+ { 181, 20},
+ { 180, 18},
+ { 179, 15},
+ { 178, 13},
+ { 177, 10},
+ { 176, 8},
+ { 175, 5},
+ { 0, 0},
+};
+
+/* MAX1111 Commands */
+#define MAXCTRL_PD0 (1u << 0)
+#define MAXCTRL_PD1 (1u << 1)
+#define MAXCTRL_SGL (1u << 2)
+#define MAXCTRL_UNI (1u << 3)
+#define MAXCTRL_SEL_SH 4
+#define MAXCTRL_STR (1u << 7)
+
+/*
+ * Read MAX1111 ADC
+ */
+int sharpsl_pm_pxa_read_max1111(int channel)
+{
+ /* Ugly, better move this function into another module */
+ if (machine_is_tosa())
+ return 0;
+
+ extern int max1111_read_channel(int);
+
+ /* max1111 accepts channels from 0-3, however,
+ * it is encoded from 0-7 here in the code.
+ */
+ return max1111_read_channel(channel >> 1);
+}
+
+static int get_percentage(int voltage)
+{
+ int i = sharpsl_pm.machinfo->bat_levels - 1;
+ int bl_status = sharpsl_pm.machinfo->backlight_get_status ? sharpsl_pm.machinfo->backlight_get_status() : 0;
+ struct battery_thresh *thresh;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_acin_bl : sharpsl_pm.machinfo->bat_levels_acin;
+ else
+ thresh = bl_status ? sharpsl_pm.machinfo->bat_levels_noac_bl : sharpsl_pm.machinfo->bat_levels_noac;
+
+ while (i > 0 && (voltage > thresh[i].voltage))
+ i--;
+
+ return thresh[i].percentage;
+}
+
+static int get_apm_status(int voltage)
+{
+ int low_thresh, high_thresh;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON) {
+ high_thresh = sharpsl_pm.machinfo->status_high_acin;
+ low_thresh = sharpsl_pm.machinfo->status_low_acin;
+ } else {
+ high_thresh = sharpsl_pm.machinfo->status_high_noac;
+ low_thresh = sharpsl_pm.machinfo->status_low_noac;
+ }
+
+ if (voltage >= high_thresh)
+ return APM_BATTERY_STATUS_HIGH;
+ if (voltage >= low_thresh)
+ return APM_BATTERY_STATUS_LOW;
+ return APM_BATTERY_STATUS_CRITICAL;
+}
+
+void sharpsl_battery_kick(void)
+{
+ schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
+}
+EXPORT_SYMBOL(sharpsl_battery_kick);
+
+
+static void sharpsl_battery_thread(struct work_struct *private_)
+{
+ int voltage, percent, apm_status, i;
+
+ if (!sharpsl_pm.machinfo)
+ return;
+
+ sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
+
+ /* Corgi cannot confirm when battery fully charged so periodically kick! */
+ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON)
+ && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL))
+ schedule_delayed_work(&toggle_charger, 0);
+
+ for (i = 0; i < 5; i++) {
+ voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+ if (voltage > 0)
+ break;
+ }
+ if (voltage <= 0) {
+ voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+ dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+ }
+
+ voltage = sharpsl_average_value(voltage);
+ apm_status = get_apm_status(voltage);
+ percent = get_percentage(voltage);
+
+ /* At low battery voltages, the voltage has a tendency to start
+ creeping back up so we try to avoid this here */
+ if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE)
+ || (apm_status == APM_BATTERY_STATUS_HIGH)
+ || percent <= sharpsl_pm.battstat.mainbat_percent) {
+ sharpsl_pm.battstat.mainbat_voltage = voltage;
+ sharpsl_pm.battstat.mainbat_status = apm_status;
+ sharpsl_pm.battstat.mainbat_percent = percent;
+ }
+
+ dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage,
+ sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
+
+ /* Suspend if critical battery level */
+ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+ && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+ && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+ sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+ dev_err(sharpsl_pm.dev, "Fatal Off\n");
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+ }
+
+ schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
+}
+
+void sharpsl_pm_led(int val)
+{
+ if (val == SHARPSL_LED_ERROR) {
+ dev_err(sharpsl_pm.dev, "Charging Error!\n");
+ } else if (val == SHARPSL_LED_ON) {
+ dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+ led_trigger_event(sharpsl_charge_led_trigger, LED_FULL);
+ } else {
+ dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+ led_trigger_event(sharpsl_charge_led_trigger, LED_OFF);
+ }
+}
+
+static void sharpsl_charge_on(void)
+{
+ dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
+
+ sharpsl_pm.full_count = 0;
+ sharpsl_pm.charge_mode = CHRG_ON;
+ schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
+ schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
+}
+
+static void sharpsl_charge_off(void)
+{
+ dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
+
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm_led(SHARPSL_LED_OFF);
+ sharpsl_pm.charge_mode = CHRG_OFF;
+
+ schedule_delayed_work(&sharpsl_bat, 0);
+}
+
+static void sharpsl_charge_error(void)
+{
+ sharpsl_pm_led(SHARPSL_LED_ERROR);
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm.charge_mode = CHRG_ERROR;
+}
+
+static void sharpsl_charge_toggle(struct work_struct *private_)
+{
+ dev_dbg(sharpsl_pm.dev, "Toggling Charger at time: %lx\n", jiffies);
+
+ if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+ sharpsl_charge_off();
+ return;
+ } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
+ sharpsl_charge_error();
+ return;
+ }
+
+ sharpsl_pm_led(SHARPSL_LED_ON);
+ sharpsl_pm.machinfo->charge(0);
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ sharpsl_pm.machinfo->charge(1);
+
+ sharpsl_pm.charge_start_time = jiffies;
+}
+
+static void sharpsl_ac_timer(unsigned long data)
+{
+ int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+ dev_dbg(sharpsl_pm.dev, "AC Status: %d\n", acin);
+
+ sharpsl_average_clear();
+ if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
+ sharpsl_charge_on();
+ else if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_charge_off();
+
+ schedule_delayed_work(&sharpsl_bat, 0);
+}
+
+
+static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id)
+{
+ /* Delay the event slightly to debounce */
+ /* Must be a smaller delay than the chrg_full_isr below */
+ mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+ return IRQ_HANDLED;
+}
+
+static void sharpsl_chrg_full_timer(unsigned long data)
+{
+ dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
+
+ sharpsl_pm.full_count++;
+
+ if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_charge_off();
+ } else if (sharpsl_pm.full_count < 2) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
+ schedule_delayed_work(&toggle_charger, 0);
+ } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
+ schedule_delayed_work(&toggle_charger, 0);
+ } else {
+ sharpsl_charge_off();
+ sharpsl_pm.charge_mode = CHRG_DONE;
+ dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
+ }
+}
+
+/* Charging Finished Interrupt (Not present on Corgi) */
+/* Can trigger at the same time as an AC status change so
+ delay until after that has been processed */
+static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id)
+{
+ if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
+ return IRQ_HANDLED;
+
+ /* delay until after any ac interrupt */
+ mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id)
+{
+ int is_fatal = 0;
+
+ if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) {
+ dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
+ is_fatal = 1;
+ }
+
+ if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) {
+ dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
+ is_fatal = 1;
+ }
+
+ if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
+ sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+ apm_queue_event(APM_CRITICAL_SUSPEND);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Maintain an average of the last 10 readings
+ */
+#define SHARPSL_CNV_VALUE_NUM 10
+static int sharpsl_ad_index;
+
+static void sharpsl_average_clear(void)
+{
+ sharpsl_ad_index = 0;
+}
+
+static int sharpsl_average_value(int ad)
+{
+ int i, ad_val = 0;
+ static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+
+ if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
+ sharpsl_ad_index = 0;
+ return ad;
+ }
+
+ sharpsl_ad[sharpsl_ad_index] = ad;
+ sharpsl_ad_index++;
+ if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
+ for (i = 0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+ sharpsl_ad[i] = sharpsl_ad[i+1];
+ sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
+ }
+ for (i = 0; i < sharpsl_ad_index; i++)
+ ad_val += sharpsl_ad[i];
+
+ return ad_val / sharpsl_ad_index;
+}
+
+/*
+ * Take an array of 5 integers, remove the maximum and minimum values
+ * and return the average.
+ */
+static int get_select_val(int *val)
+{
+ int i, j, k, temp, sum = 0;
+
+ /* Find MAX val */
+ temp = val[0];
+ j = 0;
+ for (i = 1; i < 5; i++) {
+ if (temp < val[i]) {
+ temp = val[i];
+ j = i;
+ }
+ }
+
+ /* Find MIN val */
+ temp = val[4];
+ k = 4;
+ for (i = 3; i >= 0; i--) {
+ if (temp > val[i]) {
+ temp = val[i];
+ k = i;
+ }
+ }
+
+ for (i = 0; i < 5; i++)
+ if (i != j && i != k)
+ sum += val[i];
+
+ dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
+
+ return sum/3;
+}
+
+static int sharpsl_check_battery_temp(void)
+{
+ int val, i, buff[5];
+
+ /* Check battery temperature */
+ for (i = 0; i < 5; i++) {
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+ sharpsl_pm.machinfo->measure_temp(1);
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+ buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP);
+ sharpsl_pm.machinfo->measure_temp(0);
+ }
+
+ val = get_select_val(buff);
+
+ dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
+ if (val > sharpsl_pm.machinfo->charge_on_temp) {
+ printk(KERN_WARNING "Not charging: temperature out of limits.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_check_battery_voltage(void)
+{
+ int val, i, buff[5];
+
+ /* disable charge, enable discharge */
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm.machinfo->discharge(1);
+ mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(1);
+
+ /* Check battery voltage */
+ for (i = 0; i < 5; i++) {
+ buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(0);
+
+ sharpsl_pm.machinfo->discharge(0);
+
+ val = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
+
+ if (val < sharpsl_pm.machinfo->charge_on_volt)
+ return -1;
+
+ return 0;
+}
+#endif
+
+static int sharpsl_ac_check(void)
+{
+ int temp, i, buff[5];
+
+ for (i = 0; i < 5; i++) {
+ buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
+ }
+
+ temp = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n", temp);
+
+ if ((temp > sharpsl_pm.machinfo->charge_acin_high) || (temp < sharpsl_pm.machinfo->charge_acin_low)) {
+ dev_err(sharpsl_pm.dev, "Error: AC check failed: voltage %d.\n", temp);
+ return -1;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ sharpsl_pm.flags |= SHARPSL_SUSPENDED;
+ flush_delayed_work_sync(&toggle_charger);
+ flush_delayed_work_sync(&sharpsl_bat);
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+ else
+ sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+
+ return 0;
+}
+
+static int sharpsl_pm_resume(struct platform_device *pdev)
+{
+ /* Clear the reset source indicators as they break the bootloader upon reboot */
+ RCSR = 0x0f;
+ sharpsl_average_clear();
+ sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
+ sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
+
+ return 0;
+}
+
+static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+ dev_dbg(sharpsl_pm.dev, "Time is: %08x\n", RCNR);
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n", sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+ /* not charging and AC-IN! */
+
+ if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
+ dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+ sharpsl_off_charge_battery();
+ }
+
+ sharpsl_pm.machinfo->presuspend();
+
+ PEDR = 0xffffffff; /* clear it */
+
+ sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
+ if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
+ RTSR &= RTSR_ALE;
+ RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
+ dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n", RTAR);
+ sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
+ } else if (alarm_enable) {
+ RTSR &= RTSR_ALE;
+ RTAR = alarm_time;
+ dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n", RTAR);
+ } else {
+ dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
+ }
+
+ pxa_pm_enter(state);
+
+ sharpsl_pm.machinfo->postsuspend();
+
+ dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n", PEDR);
+}
+
+static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+ if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable)) {
+ if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
+ dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+ if (sharpsl_off_charge_battery()) {
+ dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+ dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
+ }
+
+ if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) ||
+ (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL))) {
+ dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
+ corgi_goto_sleep(alarm_time, alarm_enable, state);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int corgi_pxa_pm_enter(suspend_state_t state)
+{
+ unsigned long alarm_time = RTAR;
+ unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
+
+ dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
+
+ corgi_goto_sleep(alarm_time, alarm_status, state);
+
+ while (corgi_enter_suspend(alarm_time, alarm_status, state))
+ {}
+
+ if (sharpsl_pm.machinfo->earlyresume)
+ sharpsl_pm.machinfo->earlyresume();
+
+ dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
+
+ return 0;
+}
+
+/*
+ * Check for fatal battery errors
+ * Fatal returns -1
+ */
+static int sharpsl_fatal_check(void)
+{
+ int buff[5], temp, i, acin;
+
+ dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
+
+ /* Check AC-Adapter */
+ acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+ if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+ sharpsl_pm.machinfo->charge(0);
+ udelay(100);
+ sharpsl_pm.machinfo->discharge(1); /* enable discharge */
+ mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(1);
+
+ /* Check battery : check inserting battery ? */
+ for (i = 0; i < 5; i++) {
+ buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+ mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+ }
+
+ if (sharpsl_pm.machinfo->discharge1)
+ sharpsl_pm.machinfo->discharge1(0);
+
+ if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+ udelay(100);
+ sharpsl_pm.machinfo->charge(1);
+ sharpsl_pm.machinfo->discharge(0);
+ }
+
+ temp = get_select_val(buff);
+ dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %ld\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
+
+ if ((acin && (temp < sharpsl_pm.machinfo->fatal_acin_volt)) ||
+ (!acin && (temp < sharpsl_pm.machinfo->fatal_noacin_volt)))
+ return -1;
+ return 0;
+}
+
+static int sharpsl_off_charge_error(void)
+{
+ dev_err(sharpsl_pm.dev, "Offline Charger: Error occurred.\n");
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm_led(SHARPSL_LED_ERROR);
+ sharpsl_pm.charge_mode = CHRG_ERROR;
+ return 1;
+}
+
+/*
+ * Charging Control while suspended
+ * Return 1 - go straight to sleep
+ * Return 0 - sleep or wakeup depending on other factors
+ */
+static int sharpsl_off_charge_battery(void)
+{
+ int time;
+
+ dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
+
+ if (sharpsl_pm.charge_mode == CHRG_OFF) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
+
+ /* AC Check */
+ if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
+ return sharpsl_off_charge_error();
+
+ /* Start Charging */
+ sharpsl_pm_led(SHARPSL_LED_ON);
+ sharpsl_pm.machinfo->charge(0);
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ sharpsl_pm.machinfo->charge(1);
+
+ sharpsl_pm.charge_mode = CHRG_ON;
+ sharpsl_pm.full_count = 0;
+
+ return 1;
+ } else if (sharpsl_pm.charge_mode != CHRG_ON) {
+ return 1;
+ }
+
+ if (sharpsl_pm.full_count == 0) {
+ int time;
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
+
+ if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
+ return sharpsl_off_charge_error();
+
+ sharpsl_pm.machinfo->charge(0);
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ sharpsl_pm.machinfo->charge(1);
+ sharpsl_pm.charge_mode = CHRG_ON;
+
+ mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+ time = RCNR;
+ while (1) {
+ /* Check if any wakeup event had occurred */
+ if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+ return 0;
+ /* Check for timeout */
+ if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
+ return 1;
+ if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n");
+ sharpsl_pm.full_count++;
+ sharpsl_pm.machinfo->charge(0);
+ mdelay(SHARPSL_CHARGE_WAIT_TIME);
+ sharpsl_pm.machinfo->charge(1);
+ return 1;
+ }
+ }
+ }
+
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
+
+ mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+ time = RCNR;
+ while (1) {
+ /* Check if any wakeup event had occurred */
+ if (sharpsl_pm.machinfo->charger_wakeup())
+ return 0;
+ /* Check for timeout */
+ if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
+ if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
+ sharpsl_pm.full_count = 0;
+ }
+ sharpsl_pm.full_count++;
+ return 1;
+ }
+ if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
+ dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
+ sharpsl_pm_led(SHARPSL_LED_OFF);
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm.charge_mode = CHRG_DONE;
+ return 1;
+ }
+ }
+}
+#else
+#define sharpsl_pm_suspend NULL
+#define sharpsl_pm_resume NULL
+#endif
+
+static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_percent);
+}
+
+static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", sharpsl_pm.battstat.mainbat_voltage);
+}
+
+static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
+static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static void sharpsl_apm_get_power_status(struct apm_power_info *info)
+{
+ info->ac_line_status = sharpsl_pm.battstat.ac_status;
+
+ if (sharpsl_pm.charge_mode == CHRG_ON)
+ info->battery_status = APM_BATTERY_STATUS_CHARGING;
+ else
+ info->battery_status = sharpsl_pm.battstat.mainbat_status;
+
+ info->battery_flag = (1 << info->battery_status);
+ info->battery_life = sharpsl_pm.battstat.mainbat_percent;
+}
+
+#ifdef CONFIG_PM
+static const struct platform_suspend_ops sharpsl_pm_ops = {
+ .prepare = pxa_pm_prepare,
+ .finish = pxa_pm_finish,
+ .enter = corgi_pxa_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+#endif
+
+static int __devinit sharpsl_pm_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ if (!pdev->dev.platform_data)
+ return -EINVAL;
+
+ sharpsl_pm.dev = &pdev->dev;
+ sharpsl_pm.machinfo = pdev->dev.platform_data;
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ sharpsl_pm.flags = 0;
+
+ init_timer(&sharpsl_pm.ac_timer);
+ sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
+
+ init_timer(&sharpsl_pm.chrg_full_timer);
+ sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
+
+ led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger);
+
+ sharpsl_pm.machinfo->init();
+
+ gpio_request(sharpsl_pm.machinfo->gpio_acin, "AC IN");
+ gpio_direction_input(sharpsl_pm.machinfo->gpio_acin);
+ gpio_request(sharpsl_pm.machinfo->gpio_batfull, "Battery Full");
+ gpio_direction_input(sharpsl_pm.machinfo->gpio_batfull);
+ gpio_request(sharpsl_pm.machinfo->gpio_batlock, "Battery Lock");
+ gpio_direction_input(sharpsl_pm.machinfo->gpio_batlock);
+
+ /* Register interrupt handlers */
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "AC Input Detect", sharpsl_ac_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin));
+ }
+
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Battery Cover", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock));
+ }
+
+ if (sharpsl_pm.machinfo->gpio_fatal) {
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "Fatal Battery", sharpsl_fatal_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal));
+ }
+ }
+
+ if (sharpsl_pm.machinfo->batfull_irq) {
+ /* Register interrupt handler. */
+ if (request_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr, IRQF_DISABLED | IRQF_TRIGGER_RISING, "CO", sharpsl_chrg_full_isr)) {
+ dev_err(sharpsl_pm.dev, "Could not get irq %d.\n", IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull));
+ }
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_battery_percentage);
+ ret |= device_create_file(&pdev->dev, &dev_attr_battery_voltage);
+ if (ret != 0)
+ dev_warn(&pdev->dev, "Failed to register attributes (%d)\n", ret);
+
+ apm_get_power_status = sharpsl_apm_get_power_status;
+
+#ifdef CONFIG_PM
+ suspend_set_ops(&sharpsl_pm_ops);
+#endif
+
+ mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+ return 0;
+}
+
+static int sharpsl_pm_remove(struct platform_device *pdev)
+{
+ suspend_set_ops(NULL);
+
+ device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
+ device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
+
+ led_trigger_unregister_simple(sharpsl_charge_led_trigger);
+
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
+
+ if (sharpsl_pm.machinfo->gpio_fatal)
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_fatal), sharpsl_fatal_isr);
+
+ if (sharpsl_pm.machinfo->batfull_irq)
+ free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
+
+ gpio_free(sharpsl_pm.machinfo->gpio_batlock);
+ gpio_free(sharpsl_pm.machinfo->gpio_batfull);
+ gpio_free(sharpsl_pm.machinfo->gpio_acin);
+
+ if (sharpsl_pm.machinfo->exit)
+ sharpsl_pm.machinfo->exit();
+
+ del_timer_sync(&sharpsl_pm.chrg_full_timer);
+ del_timer_sync(&sharpsl_pm.ac_timer);
+
+ return 0;
+}
+
+static struct platform_driver sharpsl_pm_driver = {
+ .probe = sharpsl_pm_probe,
+ .remove = sharpsl_pm_remove,
+ .suspend = sharpsl_pm_suspend,
+ .resume = sharpsl_pm_resume,
+ .driver = {
+ .name = "sharpsl-pm",
+ },
+};
+
+static int __devinit sharpsl_pm_init(void)
+{
+ return platform_driver_register(&sharpsl_pm_driver);
+}
+
+static void sharpsl_pm_exit(void)
+{
+ platform_driver_unregister(&sharpsl_pm_driver);
+}
+
+late_initcall(sharpsl_pm_init);
+module_exit(sharpsl_pm_exit);
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
new file mode 100644
index 00000000..6f536889
--- /dev/null
+++ b/arch/arm/mach-pxa/sleep.S
@@ -0,0 +1,210 @@
+/*
+ * Low-level PXA250/210 sleep/wakeUp support
+ *
+ * Initial SA1110 code:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Adapted for PXA by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <mach/smemc.h>
+#include <mach/pxa2xx-regs.h>
+
+#define MDREFR_KDIV 0x200a4000 // all banks
+#define CCCR_SLEEP 0x00000107 // L=7 2N=2 A=0 PPDIS=0 CPDIS=0
+
+ .text
+
+#ifdef CONFIG_PXA3xx
+/*
+ * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4)
+ *
+ * r0 = v:p offset
+ */
+ENTRY(pxa3xx_cpu_suspend)
+
+#ifndef CONFIG_IWMMXT
+ mra r2, r3, acc0
+#endif
+ stmfd sp!, {r2 - r12, lr} @ save registers on stack
+ mov r1, r0
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
+
+ mov r0, #0x06 @ S2D3C4 mode
+ mcr p14, 0, r0, c7, c0, 0 @ enter sleep
+
+20: b 20b @ waiting for sleep
+#endif /* CONFIG_PXA3xx */
+
+#ifdef CONFIG_PXA27x
+/*
+ * pxa27x_cpu_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
+ */
+ENTRY(pxa27x_cpu_suspend)
+
+#ifndef CONFIG_IWMMXT
+ mra r2, r3, acc0
+#endif
+ stmfd sp!, {r2 - r12, lr} @ save registers on stack
+ mov r4, r0 @ save sleep mode
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
+
+ @ Put the processor to sleep
+ @ (also workaround for sighting 28071)
+
+ @ prepare value for sleep mode
+ mov r1, r4 @ sleep mode
+
+ @ prepare pointer to physical address 0 (virtual mapping in generic.c)
+ mov r2, #UNCACHED_PHYS_0
+
+ @ prepare SDRAM refresh settings
+ ldr r4, =MDREFR
+ ldr r5, [r4]
+
+ @ enable SDRAM self-refresh mode
+ orr r5, r5, #MDREFR_SLFRSH
+
+ @ set SDCLKx divide-by-2 bits (this is part of a workaround for Errata 50)
+ ldr r6, =MDREFR_KDIV
+ orr r5, r5, r6
+
+ @ Intel PXA270 Specification Update notes problems sleeping
+ @ with core operating above 91 MHz
+ @ (see Errata 50, ...processor does not exit from sleep...)
+
+ ldr r6, =CCCR
+ ldr r8, [r6] @ keep original value for resume
+
+ ldr r7, =CCCR_SLEEP @ prepare CCCR sleep value
+ mov r0, #0x2 @ prepare value for CLKCFG
+
+ @ align execution to a cache line
+ b pxa_cpu_do_suspend
+#endif
+
+#ifdef CONFIG_PXA25x
+/*
+ * pxa25x_cpu_suspend()
+ *
+ * Forces CPU into sleep state.
+ *
+ * r0 = value for PWRMODE M field for desired sleep state
+ * r1 = v:p offset
+ */
+
+ENTRY(pxa25x_cpu_suspend)
+ stmfd sp!, {r2 - r12, lr} @ save registers on stack
+ mov r4, r0 @ save sleep mode
+ ldr r3, =pxa_cpu_resume @ resume function
+ bl cpu_suspend
+ @ prepare value for sleep mode
+ mov r1, r4 @ sleep mode
+
+ @ prepare pointer to physical address 0 (virtual mapping in generic.c)
+ mov r2, #UNCACHED_PHYS_0
+
+ @ prepare SDRAM refresh settings
+ ldr r4, =MDREFR
+ ldr r5, [r4]
+
+ @ enable SDRAM self-refresh mode
+ orr r5, r5, #MDREFR_SLFRSH
+
+ @ Intel PXA255 Specification Update notes problems
+ @ about suspending with PXBus operating above 133MHz
+ @ (see Errata 31, GPIO output signals, ... unpredictable in sleep
+ @
+ @ We keep the change-down close to the actual suspend on SDRAM
+ @ as possible to eliminate messing about with the refresh clock
+ @ as the system will restore with the original speed settings
+ @
+ @ Ben Dooks, 13-Sep-2004
+
+ ldr r6, =CCCR
+ ldr r8, [r6] @ keep original value for resume
+
+ @ ensure x1 for run and turbo mode with memory clock
+ bic r7, r8, #CCCR_M_MASK | CCCR_N_MASK
+ orr r7, r7, #(1<<5) | (2<<7)
+
+ @ check that the memory frequency is within limits
+ and r14, r7, #CCCR_L_MASK
+ teq r14, #1
+ bicne r7, r7, #CCCR_L_MASK
+ orrne r7, r7, #1 @@ 99.53MHz
+
+ @ get ready for the change
+
+ @ note, turbo is not preserved over sleep so there is no
+ @ point in preserving it here. we save it on the stack with the
+ @ other CP registers instead.
+ mov r0, #0
+ mcr p14, 0, r0, c6, c0, 0
+ orr r0, r0, #2 @ initiate change bit
+ b pxa_cpu_do_suspend
+#endif
+
+ .ltorg
+ .align 5
+pxa_cpu_do_suspend:
+
+ @ All needed values are now in registers.
+ @ These last instructions should be in cache
+
+ @ initiate the frequency change...
+ str r7, [r6]
+ mcr p14, 0, r0, c6, c0, 0
+
+ @ restore the original cpu speed value for resume
+ str r8, [r6]
+
+ @ need 6 13-MHz cycles before changing PWRMODE
+ @ just set frequency to 91-MHz... 6*91/13 = 42
+
+ mov r0, #42
+10: subs r0, r0, #1
+ bne 10b
+
+ @ Do not reorder...
+ @ Intel PXA270 Specification Update notes problems performing
+ @ external accesses after SDRAM is put in self-refresh mode
+ @ (see Errata 39 ...hangs when entering self-refresh mode)
+
+ @ force address lines low by reading at physical address 0
+ ldr r3, [r2]
+
+ @ put SDRAM into self-refresh
+ str r5, [r4]
+
+ @ enter sleep mode
+ mcr p14, 0, r1, c7, c0, 0 @ PWRMODE
+
+20: b 20b @ loop waiting for sleep
+
+/*
+ * pxa_cpu_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ */
+ .align 5
+pxa_cpu_resume:
+ ldmfd sp!, {r2, r3}
+#ifndef CONFIG_IWMMXT
+ mar acc0, r2, r3
+#endif
+ ldmfd sp!, {r4 - r12, pc} @ return to caller
diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c
new file mode 100644
index 00000000..79923058
--- /dev/null
+++ b/arch/arm/mach-pxa/smemc.c
@@ -0,0 +1,58 @@
+/*
+ * Static Memory Controller
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/hardware.h>
+#include <mach/smemc.h>
+
+#ifdef CONFIG_PM
+static unsigned long msc[2];
+static unsigned long sxcnfg, memclkcfg;
+static unsigned long csadrcfg[4];
+
+static int pxa3xx_smemc_suspend(void)
+{
+ msc[0] = __raw_readl(MSC0);
+ msc[1] = __raw_readl(MSC1);
+ sxcnfg = __raw_readl(SXCNFG);
+ memclkcfg = __raw_readl(MEMCLKCFG);
+ csadrcfg[0] = __raw_readl(CSADRCFG0);
+ csadrcfg[1] = __raw_readl(CSADRCFG1);
+ csadrcfg[2] = __raw_readl(CSADRCFG2);
+ csadrcfg[3] = __raw_readl(CSADRCFG3);
+
+ return 0;
+}
+
+static void pxa3xx_smemc_resume(void)
+{
+ __raw_writel(msc[0], MSC0);
+ __raw_writel(msc[1], MSC1);
+ __raw_writel(sxcnfg, SXCNFG);
+ __raw_writel(memclkcfg, MEMCLKCFG);
+ __raw_writel(csadrcfg[0], CSADRCFG0);
+ __raw_writel(csadrcfg[1], CSADRCFG1);
+ __raw_writel(csadrcfg[2], CSADRCFG2);
+ __raw_writel(csadrcfg[3], CSADRCFG3);
+}
+
+static struct syscore_ops smemc_syscore_ops = {
+ .suspend = pxa3xx_smemc_suspend,
+ .resume = pxa3xx_smemc_resume,
+};
+
+static int __init smemc_init(void)
+{
+ if (cpu_is_pxa3xx())
+ register_syscore_ops(&smemc_syscore_ops);
+
+ return 0;
+}
+subsys_initcall(smemc_init);
+#endif
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
new file mode 100644
index 00000000..01c57696
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz.c
@@ -0,0 +1,1010 @@
+/*
+ * Support for Sharp SL-Cxx00 Series of PDAs
+ * Models: SL-C3000 (Spitz), SL-C1000 (Akita) and SL-C3100 (Borzoi)
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * Based on Sharp's 2.4 kernel patches/lubbock.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio_keys.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/corgi_lcd.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mtd/sharpsl.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/regulator/machine.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/scoop.h>
+
+#include <mach/pxa27x.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/reset.h>
+#include <mach/irda.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <mach/pxafb.h>
+#include <mach/spitz.h>
+#include <mach/sharpsl_pm.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long spitz_pin_config[] __initdata = {
+ /* Chip Selects */
+ GPIO78_nCS_2, /* SCOOP #2 */
+ GPIO79_nCS_3, /* NAND */
+ GPIO80_nCS_4, /* SCOOP #1 */
+
+ /* LCD - 16bpp Active TFT */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* PC Card */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO104_PSKTSEL,
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+
+ /* GPIOs */
+ GPIO9_GPIO, /* SPITZ_GPIO_nSD_DETECT */
+ GPIO16_GPIO, /* SPITZ_GPIO_SYNC */
+ GPIO81_GPIO, /* SPITZ_GPIO_nSD_WP */
+ GPIO41_GPIO, /* SPITZ_GPIO_USB_CONNECT */
+ GPIO37_GPIO, /* SPITZ_GPIO_USB_HOST */
+ GPIO35_GPIO, /* SPITZ_GPIO_USB_DEVICE */
+ GPIO22_GPIO, /* SPITZ_GPIO_HSYNC */
+ GPIO94_GPIO, /* SPITZ_GPIO_CF_CD */
+ GPIO105_GPIO, /* SPITZ_GPIO_CF_IRQ */
+ GPIO106_GPIO, /* SPITZ_GPIO_CF2_IRQ */
+
+ /* GPIO matrix keypad */
+ GPIO88_GPIO, /* column 0 */
+ GPIO23_GPIO, /* column 1 */
+ GPIO24_GPIO, /* column 2 */
+ GPIO25_GPIO, /* column 3 */
+ GPIO26_GPIO, /* column 4 */
+ GPIO27_GPIO, /* column 5 */
+ GPIO52_GPIO, /* column 6 */
+ GPIO103_GPIO, /* column 7 */
+ GPIO107_GPIO, /* column 8 */
+ GPIO108_GPIO, /* column 9 */
+ GPIO114_GPIO, /* column 10 */
+ GPIO12_GPIO, /* row 0 */
+ GPIO17_GPIO, /* row 1 */
+ GPIO91_GPIO, /* row 2 */
+ GPIO34_GPIO, /* row 3 */
+ GPIO36_GPIO, /* row 4 */
+ GPIO38_GPIO, /* row 5 */
+ GPIO39_GPIO, /* row 6 */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* SPITZ_GPIO_KEY_INT */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_FALL, /* SPITZ_GPIO_RESET */
+};
+
+
+/******************************************************************************
+ * Scoop GPIO expander
+ ******************************************************************************/
+#if defined(CONFIG_SHARP_SCOOP) || defined(CONFIG_SHARP_SCOOP_MODULE)
+/* SCOOP Device #1 */
+static struct resource spitz_scoop_1_resources[] = {
+ [0] = {
+ .start = 0x10800000,
+ .end = 0x10800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config spitz_scoop_1_setup = {
+ .io_dir = SPITZ_SCP_IO_DIR,
+ .io_out = SPITZ_SCP_IO_OUT,
+ .suspend_clr = SPITZ_SCP_SUS_CLR,
+ .suspend_set = SPITZ_SCP_SUS_SET,
+ .gpio_base = SPITZ_SCP_GPIO_BASE,
+};
+
+struct platform_device spitz_scoop_1_device = {
+ .name = "sharp-scoop",
+ .id = 0,
+ .dev = {
+ .platform_data = &spitz_scoop_1_setup,
+ },
+ .num_resources = ARRAY_SIZE(spitz_scoop_1_resources),
+ .resource = spitz_scoop_1_resources,
+};
+
+/* SCOOP Device #2 */
+static struct resource spitz_scoop_2_resources[] = {
+ [0] = {
+ .start = 0x08800040,
+ .end = 0x08800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config spitz_scoop_2_setup = {
+ .io_dir = SPITZ_SCP2_IO_DIR,
+ .io_out = SPITZ_SCP2_IO_OUT,
+ .suspend_clr = SPITZ_SCP2_SUS_CLR,
+ .suspend_set = SPITZ_SCP2_SUS_SET,
+ .gpio_base = SPITZ_SCP2_GPIO_BASE,
+};
+
+struct platform_device spitz_scoop_2_device = {
+ .name = "sharp-scoop",
+ .id = 1,
+ .dev = {
+ .platform_data = &spitz_scoop_2_setup,
+ },
+ .num_resources = ARRAY_SIZE(spitz_scoop_2_resources),
+ .resource = spitz_scoop_2_resources,
+};
+
+static void __init spitz_scoop_init(void)
+{
+ platform_device_register(&spitz_scoop_1_device);
+
+ /* Akita doesn't have the second SCOOP chip */
+ if (!machine_is_akita())
+ platform_device_register(&spitz_scoop_2_device);
+}
+
+/* Power control is shared with between one of the CF slots and SD */
+static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr)
+{
+ unsigned short cpr;
+ unsigned long flags;
+
+ if (new_cpr & 0x7) {
+ gpio_set_value(SPITZ_GPIO_CF_POWER, 1);
+ mdelay(5);
+ }
+
+ local_irq_save(flags);
+
+ cpr = read_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR);
+
+ if (enable & new_cpr)
+ cpr |= new_cpr;
+ else
+ cpr &= ~enable;
+
+ write_scoop_reg(&spitz_scoop_1_device.dev, SCOOP_CPR, cpr);
+
+ local_irq_restore(flags);
+
+ if (!(cpr & 0x7)) {
+ mdelay(1);
+ gpio_set_value(SPITZ_GPIO_CF_POWER, 0);
+ }
+}
+
+#else
+static inline void spitz_scoop_init(void) {}
+static inline void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) {}
+#endif
+
+/******************************************************************************
+ * PCMCIA
+ ******************************************************************************/
+#if defined(CONFIG_PCMCIA_PXA2XX) || defined(CONFIG_PCMCIA_PXA2XX_MODULE)
+static void spitz_pcmcia_pwr(struct device *scoop, uint16_t cpr, int nr)
+{
+ /* Only need to override behaviour for slot 0 */
+ if (nr == 0)
+ spitz_card_pwr_ctrl(
+ cpr & (SCOOP_CPR_CF_3V | SCOOP_CPR_CF_XV), cpr);
+ else
+ write_scoop_reg(scoop, SCOOP_CPR, cpr);
+}
+
+static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = {
+ {
+ .dev = &spitz_scoop_1_device.dev,
+ .irq = SPITZ_IRQ_GPIO_CF_IRQ,
+ .cd_irq = SPITZ_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+ }, {
+ .dev = &spitz_scoop_2_device.dev,
+ .irq = SPITZ_IRQ_GPIO_CF2_IRQ,
+ .cd_irq = -1,
+ },
+};
+
+static struct scoop_pcmcia_config spitz_pcmcia_config = {
+ .devs = &spitz_pcmcia_scoop[0],
+ .num_devs = 2,
+ .power_ctrl = spitz_pcmcia_pwr,
+};
+
+static void __init spitz_pcmcia_init(void)
+{
+ /* Akita has only one PCMCIA slot used */
+ if (machine_is_akita())
+ spitz_pcmcia_config.num_devs = 1;
+
+ platform_scoop_config = &spitz_pcmcia_config;
+}
+#else
+static inline void spitz_pcmcia_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_MATRIX) || defined(CONFIG_KEYBOARD_MATRIX_MODULE)
+
+#define SPITZ_KEY_CALENDAR KEY_F1
+#define SPITZ_KEY_ADDRESS KEY_F2
+#define SPITZ_KEY_FN KEY_F3
+#define SPITZ_KEY_CANCEL KEY_F4
+#define SPITZ_KEY_EXOK KEY_F5
+#define SPITZ_KEY_EXCANCEL KEY_F6
+#define SPITZ_KEY_EXJOGDOWN KEY_F7
+#define SPITZ_KEY_EXJOGUP KEY_F8
+#define SPITZ_KEY_JAP1 KEY_LEFTALT
+#define SPITZ_KEY_JAP2 KEY_RIGHTCTRL
+#define SPITZ_KEY_SYNC KEY_F9
+#define SPITZ_KEY_MAIL KEY_F10
+#define SPITZ_KEY_OK KEY_F11
+#define SPITZ_KEY_MENU KEY_F12
+
+static const uint32_t spitz_keymap[] = {
+ KEY(0, 0, KEY_LEFTCTRL),
+ KEY(0, 1, KEY_1),
+ KEY(0, 2, KEY_3),
+ KEY(0, 3, KEY_5),
+ KEY(0, 4, KEY_6),
+ KEY(0, 5, KEY_7),
+ KEY(0, 6, KEY_9),
+ KEY(0, 7, KEY_0),
+ KEY(0, 8, KEY_BACKSPACE),
+ KEY(0, 9, SPITZ_KEY_EXOK), /* EXOK */
+ KEY(0, 10, SPITZ_KEY_EXCANCEL), /* EXCANCEL */
+ KEY(1, 1, KEY_2),
+ KEY(1, 2, KEY_4),
+ KEY(1, 3, KEY_R),
+ KEY(1, 4, KEY_Y),
+ KEY(1, 5, KEY_8),
+ KEY(1, 6, KEY_I),
+ KEY(1, 7, KEY_O),
+ KEY(1, 8, KEY_P),
+ KEY(1, 9, SPITZ_KEY_EXJOGDOWN), /* EXJOGDOWN */
+ KEY(1, 10, SPITZ_KEY_EXJOGUP), /* EXJOGUP */
+ KEY(2, 0, KEY_TAB),
+ KEY(2, 1, KEY_Q),
+ KEY(2, 2, KEY_E),
+ KEY(2, 3, KEY_T),
+ KEY(2, 4, KEY_G),
+ KEY(2, 5, KEY_U),
+ KEY(2, 6, KEY_J),
+ KEY(2, 7, KEY_K),
+ KEY(3, 0, SPITZ_KEY_ADDRESS), /* ADDRESS */
+ KEY(3, 1, KEY_W),
+ KEY(3, 2, KEY_S),
+ KEY(3, 3, KEY_F),
+ KEY(3, 4, KEY_V),
+ KEY(3, 5, KEY_H),
+ KEY(3, 6, KEY_M),
+ KEY(3, 7, KEY_L),
+ KEY(3, 9, KEY_RIGHTSHIFT),
+ KEY(4, 0, SPITZ_KEY_CALENDAR), /* CALENDAR */
+ KEY(4, 1, KEY_A),
+ KEY(4, 2, KEY_D),
+ KEY(4, 3, KEY_C),
+ KEY(4, 4, KEY_B),
+ KEY(4, 5, KEY_N),
+ KEY(4, 6, KEY_DOT),
+ KEY(4, 8, KEY_ENTER),
+ KEY(4, 9, KEY_LEFTSHIFT),
+ KEY(5, 0, SPITZ_KEY_MAIL), /* MAIL */
+ KEY(5, 1, KEY_Z),
+ KEY(5, 2, KEY_X),
+ KEY(5, 3, KEY_MINUS),
+ KEY(5, 4, KEY_SPACE),
+ KEY(5, 5, KEY_COMMA),
+ KEY(5, 7, KEY_UP),
+ KEY(5, 10, SPITZ_KEY_FN), /* FN */
+ KEY(6, 0, KEY_SYSRQ),
+ KEY(6, 1, SPITZ_KEY_JAP1), /* JAP1 */
+ KEY(6, 2, SPITZ_KEY_JAP2), /* JAP2 */
+ KEY(6, 3, SPITZ_KEY_CANCEL), /* CANCEL */
+ KEY(6, 4, SPITZ_KEY_OK), /* OK */
+ KEY(6, 5, SPITZ_KEY_MENU), /* MENU */
+ KEY(6, 6, KEY_LEFT),
+ KEY(6, 7, KEY_DOWN),
+ KEY(6, 8, KEY_RIGHT),
+};
+
+static const struct matrix_keymap_data spitz_keymap_data = {
+ .keymap = spitz_keymap,
+ .keymap_size = ARRAY_SIZE(spitz_keymap),
+};
+
+static const uint32_t spitz_row_gpios[] =
+ { 12, 17, 91, 34, 36, 38, 39 };
+static const uint32_t spitz_col_gpios[] =
+ { 88, 23, 24, 25, 26, 27, 52, 103, 107, 108, 114 };
+
+static struct matrix_keypad_platform_data spitz_mkp_pdata = {
+ .keymap_data = &spitz_keymap_data,
+ .row_gpios = spitz_row_gpios,
+ .col_gpios = spitz_col_gpios,
+ .num_row_gpios = ARRAY_SIZE(spitz_row_gpios),
+ .num_col_gpios = ARRAY_SIZE(spitz_col_gpios),
+ .col_scan_delay_us = 10,
+ .debounce_ms = 10,
+ .wakeup = 1,
+};
+
+static struct platform_device spitz_mkp_device = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &spitz_mkp_pdata,
+ },
+};
+
+static void __init spitz_mkp_init(void)
+{
+ platform_device_register(&spitz_mkp_device);
+}
+#else
+static inline void spitz_mkp_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button spitz_gpio_keys[] = {
+ {
+ .type = EV_PWR,
+ .code = KEY_SUSPEND,
+ .gpio = SPITZ_GPIO_ON_KEY,
+ .desc = "On Off",
+ .wakeup = 1,
+ },
+ /* Two buttons detecting the lid state */
+ {
+ .type = EV_SW,
+ .code = 0,
+ .gpio = SPITZ_GPIO_SWA,
+ .desc = "Display Down",
+ },
+ {
+ .type = EV_SW,
+ .code = 1,
+ .gpio = SPITZ_GPIO_SWB,
+ .desc = "Lid Closed",
+ },
+};
+
+static struct gpio_keys_platform_data spitz_gpio_keys_platform_data = {
+ .buttons = spitz_gpio_keys,
+ .nbuttons = ARRAY_SIZE(spitz_gpio_keys),
+};
+
+static struct platform_device spitz_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &spitz_gpio_keys_platform_data,
+ },
+};
+
+static void __init spitz_keys_init(void)
+{
+ platform_device_register(&spitz_gpio_keys_device);
+}
+#else
+static inline void spitz_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led spitz_gpio_leds[] = {
+ {
+ .name = "spitz:amber:charge",
+ .default_trigger = "sharpsl-charge",
+ .gpio = SPITZ_GPIO_LED_ORANGE,
+ },
+ {
+ .name = "spitz:green:hddactivity",
+ .default_trigger = "ide-disk",
+ .gpio = SPITZ_GPIO_LED_GREEN,
+ },
+};
+
+static struct gpio_led_platform_data spitz_gpio_leds_info = {
+ .leds = spitz_gpio_leds,
+ .num_leds = ARRAY_SIZE(spitz_gpio_leds),
+};
+
+static struct platform_device spitz_led_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &spitz_gpio_leds_info,
+ },
+};
+
+static void __init spitz_leds_init(void)
+{
+ platform_device_register(&spitz_led_device);
+}
+#else
+static inline void spitz_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * SSP Devices
+ ******************************************************************************/
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+static void spitz_ads7846_wait_for_hsync(void)
+{
+ while (gpio_get_value(SPITZ_GPIO_HSYNC))
+ cpu_relax();
+
+ while (!gpio_get_value(SPITZ_GPIO_HSYNC))
+ cpu_relax();
+}
+
+static struct ads7846_platform_data spitz_ads7846_info = {
+ .model = 7846,
+ .vref_delay_usecs = 100,
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1024,
+ .gpio_pendown = SPITZ_GPIO_TP_INT,
+ .wait_for_sync = spitz_ads7846_wait_for_hsync,
+};
+
+static struct pxa2xx_spi_chip spitz_ads7846_chip = {
+ .gpio_cs = SPITZ_GPIO_ADS7846_CS,
+};
+
+static void spitz_bl_kick_battery(void)
+{
+ void (*kick_batt)(void);
+
+ kick_batt = symbol_get(sharpsl_battery_kick);
+ if (kick_batt) {
+ kick_batt();
+ symbol_put(sharpsl_battery_kick);
+ }
+}
+
+static struct corgi_lcd_platform_data spitz_lcdcon_info = {
+ .init_mode = CORGI_LCD_MODE_VGA,
+ .max_intensity = 0x2f,
+ .default_intensity = 0x1f,
+ .limit_mask = 0x0b,
+ .gpio_backlight_cont = SPITZ_GPIO_BACKLIGHT_CONT,
+ .gpio_backlight_on = SPITZ_GPIO_BACKLIGHT_ON,
+ .kick_battery = spitz_bl_kick_battery,
+};
+
+static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
+ .gpio_cs = SPITZ_GPIO_LCDCON_CS,
+};
+
+static struct pxa2xx_spi_chip spitz_max1111_chip = {
+ .gpio_cs = SPITZ_GPIO_MAX1111_CS,
+};
+
+static struct spi_board_info spitz_spi_devices[] = {
+ {
+ .modalias = "ads7846",
+ .max_speed_hz = 1200000,
+ .bus_num = 2,
+ .chip_select = 0,
+ .platform_data = &spitz_ads7846_info,
+ .controller_data = &spitz_ads7846_chip,
+ .irq = gpio_to_irq(SPITZ_GPIO_TP_INT),
+ }, {
+ .modalias = "corgi-lcd",
+ .max_speed_hz = 50000,
+ .bus_num = 2,
+ .chip_select = 1,
+ .platform_data = &spitz_lcdcon_info,
+ .controller_data = &spitz_lcdcon_chip,
+ }, {
+ .modalias = "max1111",
+ .max_speed_hz = 450000,
+ .bus_num = 2,
+ .chip_select = 2,
+ .controller_data = &spitz_max1111_chip,
+ },
+};
+
+static struct pxa2xx_spi_master spitz_spi_info = {
+ .num_chipselect = 3,
+};
+
+static void __init spitz_spi_init(void)
+{
+ struct corgi_lcd_platform_data *lcd_data = &spitz_lcdcon_info;
+
+ if (machine_is_akita()) {
+ lcd_data->gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
+ lcd_data->gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
+ }
+
+ pxa2xx_set_spi_info(2, &spitz_spi_info);
+ spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
+}
+#else
+static inline void spitz_spi_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+/*
+ * NOTE: The card detect interrupt isn't debounced so we delay it by 250ms to
+ * give the card a chance to fully insert/eject.
+ */
+static void spitz_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ struct pxamci_platform_data* p_d = dev->platform_data;
+
+ if ((1 << vdd) & p_d->ocr_mask)
+ spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, SCOOP_CPR_SD_3V);
+ else
+ spitz_card_pwr_ctrl(SCOOP_CPR_SD_3V, 0x0);
+}
+
+static struct pxamci_platform_data spitz_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .setpower = spitz_mci_setpower,
+ .gpio_card_detect = SPITZ_GPIO_nSD_DETECT,
+ .gpio_card_ro = SPITZ_GPIO_nSD_WP,
+ .gpio_power = -1,
+};
+
+static void __init spitz_mmc_init(void)
+{
+ pxa_set_mci_info(&spitz_mci_platform_data);
+}
+#else
+static inline void spitz_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int spitz_ohci_init(struct device *dev)
+{
+ int err;
+
+ err = gpio_request(SPITZ_GPIO_USB_HOST, "USB_HOST");
+ if (err)
+ return err;
+
+ /* Only Port 2 is connected, setup USB Port 2 Output Control Register */
+ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+
+ return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1);
+}
+
+static void spitz_ohci_exit(struct device *dev)
+{
+ gpio_free(SPITZ_GPIO_USB_HOST);
+}
+
+static struct pxaohci_platform_data spitz_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ .init = spitz_ohci_init,
+ .exit = spitz_ohci_exit,
+ .flags = ENABLE_PORT_ALL | NO_OC_PROTECTION,
+ .power_budget = 150,
+};
+
+static void __init spitz_uhc_init(void)
+{
+ pxa_set_ohci_info(&spitz_ohci_platform_data);
+}
+#else
+static inline void spitz_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * IrDA
+ ******************************************************************************/
+#if defined(CONFIG_PXA_FICP) || defined(CONFIG_PXA_FICP_MODULE)
+static struct pxaficp_platform_data spitz_ficp_platform_data = {
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+};
+
+static void __init spitz_irda_init(void)
+{
+ if (machine_is_akita())
+ spitz_ficp_platform_data.gpio_pwdown = AKITA_GPIO_IR_ON;
+ else
+ spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
+
+ pxa_set_ficp_info(&spitz_ficp_platform_data);
+}
+#else
+static inline void spitz_irda_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info spitz_pxafb_modes[] = {
+ {
+ .pixclock = 19231,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 40,
+ .left_margin = 46,
+ .right_margin = 125,
+ .vsync_len = 3,
+ .upper_margin = 1,
+ .lower_margin = 0,
+ .sync = 0,
+ }, {
+ .pixclock = 134617,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 20,
+ .left_margin = 20,
+ .right_margin = 46,
+ .vsync_len = 2,
+ .upper_margin = 1,
+ .lower_margin = 0,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info spitz_pxafb_info = {
+ .modes = spitz_pxafb_modes,
+ .num_modes = ARRAY_SIZE(spitz_pxafb_modes),
+ .fixed_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_ALTERNATE_MAPPING,
+};
+
+static void __init spitz_lcd_init(void)
+{
+ pxa_set_fb_info(NULL, &spitz_pxafb_info);
+}
+#else
+static inline void spitz_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_MTD_NAND_SHARPSL) || defined(CONFIG_MTD_NAND_SHARPSL_MODULE)
+static struct mtd_partition spitz_nand_partitions[] = {
+ {
+ .name = "System Area",
+ .offset = 0,
+ .size = 7 * 1024 * 1024,
+ }, {
+ .name = "Root Filesystem",
+ .offset = 7 * 1024 * 1024,
+ }, {
+ .name = "Home Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr spitz_nand_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 2,
+ .pattern = scan_ff_pattern
+};
+
+static struct nand_ecclayout akita_oobinfo = {
+ .oobfree = { {0x08, 0x09} },
+ .eccbytes = 24,
+ .eccpos = {
+ 0x05, 0x01, 0x02, 0x03, 0x06, 0x07, 0x15, 0x11,
+ 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
+ 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37,
+ },
+};
+
+static struct sharpsl_nand_platform_data spitz_nand_pdata = {
+ .badblock_pattern = &spitz_nand_bbt,
+ .partitions = spitz_nand_partitions,
+ .nr_partitions = ARRAY_SIZE(spitz_nand_partitions),
+};
+
+static struct resource spitz_nand_resources[] = {
+ {
+ .start = PXA_CS3_PHYS,
+ .end = PXA_CS3_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spitz_nand_device = {
+ .name = "sharpsl-nand",
+ .id = -1,
+ .resource = spitz_nand_resources,
+ .num_resources = ARRAY_SIZE(spitz_nand_resources),
+ .dev = {
+ .platform_data = &spitz_nand_pdata,
+ }
+};
+
+static void __init spitz_nand_init(void)
+{
+ if (machine_is_spitz()) {
+ spitz_nand_partitions[1].size = 5 * 1024 * 1024;
+ } else if (machine_is_akita()) {
+ spitz_nand_partitions[1].size = 58 * 1024 * 1024;
+ spitz_nand_bbt.len = 1;
+ spitz_nand_pdata.ecc_layout = &akita_oobinfo;
+ } else if (machine_is_borzoi()) {
+ spitz_nand_partitions[1].size = 32 * 1024 * 1024;
+ spitz_nand_bbt.len = 1;
+ spitz_nand_pdata.ecc_layout = &akita_oobinfo;
+ }
+
+ platform_device_register(&spitz_nand_device);
+}
+#else
+static inline void spitz_nand_init(void) {}
+#endif
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition spitz_rom_parts[] = {
+ {
+ .name ="Boot PROM Filesystem",
+ .offset = 0x00140000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data spitz_rom_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(spitz_rom_parts),
+ .parts = spitz_rom_parts,
+};
+
+static struct resource spitz_rom_resources[] = {
+ {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spitz_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = spitz_rom_resources,
+ .num_resources = ARRAY_SIZE(spitz_rom_resources),
+ .dev = {
+ .platform_data = &spitz_rom_data,
+ },
+};
+
+static void __init spitz_nor_init(void)
+{
+ platform_device_register(&spitz_rom_device);
+}
+#else
+static inline void spitz_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO expander
+ ******************************************************************************/
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct pca953x_platform_data akita_pca953x_pdata = {
+ .gpio_base = AKITA_IOEXP_GPIO_BASE,
+};
+
+static struct i2c_board_info spitz_i2c_devs[] = {
+ {
+ .type = "wm8750",
+ .addr = 0x1b,
+ }, {
+ .type = "max7310",
+ .addr = 0x18,
+ .platform_data = &akita_pca953x_pdata,
+ },
+};
+
+static struct regulator_consumer_supply isl6271a_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data isl6271a_info[] = {
+ {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 850000,
+ .max_uV = 1600000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = isl6271a_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(isl6271a_consumers),
+ }
+};
+
+static struct i2c_board_info spitz_pi2c_devs[] = {
+ {
+ .type = "isl6271a",
+ .addr = 0x0c,
+ .platform_data = &isl6271a_info,
+ },
+};
+
+static void __init spitz_i2c_init(void)
+{
+ int size = ARRAY_SIZE(spitz_i2c_devs);
+
+ /* Only Akita has the max7310 chip */
+ if (!machine_is_akita())
+ size--;
+
+ pxa_set_i2c_info(NULL);
+ pxa27x_set_i2c_power_info(NULL);
+ i2c_register_board_info(0, spitz_i2c_devs, size);
+ i2c_register_board_info(1, ARRAY_AND_SIZE(spitz_pi2c_devs));
+}
+#else
+static inline void spitz_i2c_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void spitz_poweroff(void)
+{
+ arm_machine_restart('g', NULL);
+}
+
+static void spitz_restart(char mode, const char *cmd)
+{
+ uint32_t msc0 = __raw_readl(MSC0);
+ /* Bootloader magic for a reboot */
+ if ((msc0 & 0xffff0000) == 0x7ff00000)
+ __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);
+
+ spitz_poweroff();
+}
+
+static void __init spitz_init(void)
+{
+ init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0);
+ pm_power_off = spitz_poweroff;
+ arm_pm_restart = spitz_restart;
+
+ PMCR = 0x00;
+
+ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+ PCFR |= PCFR_OPDE;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(spitz_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ spitz_spi_init();
+ spitz_scoop_init();
+ spitz_mkp_init();
+ spitz_keys_init();
+ spitz_leds_init();
+ spitz_mmc_init();
+ spitz_pcmcia_init();
+ spitz_irda_init();
+ spitz_uhc_init();
+ spitz_lcd_init();
+ spitz_nor_init();
+ spitz_nand_init();
+ spitz_i2c_init();
+}
+
+static void __init spitz_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks = 1;
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].size = (64*1024*1024);
+}
+
+#ifdef CONFIG_MACH_SPITZ
+MACHINE_START(SPITZ, "SHARP Spitz")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = spitz_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_BORZOI
+MACHINE_START(BORZOI, "SHARP Borzoi")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = spitz_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_AKITA
+MACHINE_START(AKITA, "SHARP Akita")
+ .fixup = spitz_fixup,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .init_machine = spitz_init,
+ .timer = &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
new file mode 100644
index 00000000..094279ae
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -0,0 +1,260 @@
+/*
+ * Battery and Power Management code for the Sharp SL-Cxx00
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can 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/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+#include <mach/spitz.h>
+#include <mach/pxa27x.h>
+#include <mach/sharpsl_pm.h>
+
+#include "generic.h"
+
+#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */
+
+static int spitz_last_ac_status;
+
+static struct gpio spitz_charger_gpios[] = {
+ { SPITZ_GPIO_KEY_INT, GPIOF_IN, "Keyboard Interrupt" },
+ { SPITZ_GPIO_SYNC, GPIOF_IN, "Sync" },
+ { SPITZ_GPIO_ADC_TEMP_ON, GPIOF_OUT_INIT_LOW, "ADC Temp On" },
+ { SPITZ_GPIO_JK_B, GPIOF_OUT_INIT_LOW, "JK B" },
+ { SPITZ_GPIO_CHRG_ON, GPIOF_OUT_INIT_LOW, "Charger On" },
+};
+
+static void spitz_charger_init(void)
+{
+ gpio_request_array(ARRAY_AND_SIZE(spitz_charger_gpios));
+}
+
+static void spitz_measure_temp(int on)
+{
+ gpio_set_value(SPITZ_GPIO_ADC_TEMP_ON, on);
+}
+
+static void spitz_charge(int on)
+{
+ if (on) {
+ if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
+ gpio_set_value(SPITZ_GPIO_JK_B, 1);
+ gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
+ } else {
+ gpio_set_value(SPITZ_GPIO_JK_B, 0);
+ gpio_set_value(SPITZ_GPIO_CHRG_ON, 0);
+ }
+ } else {
+ gpio_set_value(SPITZ_GPIO_JK_B, 0);
+ gpio_set_value(SPITZ_GPIO_CHRG_ON, 1);
+ }
+}
+
+static void spitz_discharge(int on)
+{
+ gpio_set_value(SPITZ_GPIO_JK_A, on);
+}
+
+/* HACK - For unknown reasons, accurate voltage readings are only made with a load
+ on the power bus which the green led on spitz provides */
+static void spitz_discharge1(int on)
+{
+ gpio_set_value(SPITZ_GPIO_LED_GREEN, on);
+}
+
+static unsigned long gpio18_config[] = {
+ GPIO18_RDY,
+ GPIO18_GPIO,
+};
+
+static void spitz_presuspend(void)
+{
+ spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+ /* GPIO Sleep Register */
+ PGSR0 = 0x00144018;
+ PGSR1 = 0x00EF0000;
+ if (machine_is_akita()) {
+ PGSR2 = 0x2121C000;
+ PGSR3 = 0x00600400;
+ } else {
+ PGSR2 = 0x0121C000;
+ PGSR3 = 0x00600000;
+ }
+
+ PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+ PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+ PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+ PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+ PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
+
+ pxa2xx_mfp_config(&gpio18_config[0], 1);
+ gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown");
+ gpio_free(18);
+
+ PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
+ PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+ PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
+ PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+ PKSR = 0xffffffff; /* clear */
+
+ /* nRESET_OUT Disable */
+ PSLR |= PSLR_SL_ROD;
+
+ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+ PCFR = PCFR_GPR_EN | PCFR_OPDE;
+}
+
+static void spitz_postsuspend(void)
+{
+ pxa2xx_mfp_config(&gpio18_config[1], 1);
+}
+
+static int spitz_should_wakeup(unsigned int resume_on_alarm)
+{
+ int is_resume = 0;
+ int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+ if (spitz_last_ac_status != acin) {
+ if (acin) {
+ /* charge on */
+ sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+ dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
+ } else {
+ /* charge off */
+ dev_dbg(sharpsl_pm.dev, "AC Removed\n");
+ sharpsl_pm_led(SHARPSL_LED_OFF);
+ sharpsl_pm.machinfo->charge(0);
+ sharpsl_pm.charge_mode = CHRG_OFF;
+ }
+ spitz_last_ac_status = acin;
+ /* Return to suspend as this must be what we were woken for */
+ return 0;
+ }
+
+ if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
+ is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
+
+ if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
+ is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
+
+ if (resume_on_alarm && (PEDR & PWER_RTC))
+ is_resume |= PWER_RTC;
+
+ dev_dbg(sharpsl_pm.dev, "is_resume: %x\n", is_resume);
+ return is_resume;
+}
+
+static unsigned long spitz_charger_wakeup(void)
+{
+ return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
+}
+
+unsigned long spitzpm_read_devdata(int type)
+{
+ switch (type) {
+ case SHARPSL_STATUS_ACIN:
+ return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
+ case SHARPSL_STATUS_LOCK:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_batlock);
+ case SHARPSL_STATUS_CHRGFULL:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_batfull);
+ case SHARPSL_STATUS_FATAL:
+ return gpio_get_value(sharpsl_pm.machinfo->gpio_fatal);
+ case SHARPSL_ACIN_VOLT:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
+ case SHARPSL_BATT_TEMP:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
+ case SHARPSL_BATT_VOLT:
+ default:
+ return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
+ }
+}
+
+struct sharpsl_charger_machinfo spitz_pm_machinfo = {
+ .init = spitz_charger_init,
+ .exit = NULL,
+ .gpio_batlock = SPITZ_GPIO_BAT_COVER,
+ .gpio_acin = SPITZ_GPIO_AC_IN,
+ .gpio_batfull = SPITZ_GPIO_CHRG_FULL,
+ .batfull_irq = 1,
+ .gpio_fatal = SPITZ_GPIO_FATAL_BAT,
+ .discharge = spitz_discharge,
+ .discharge1 = spitz_discharge1,
+ .charge = spitz_charge,
+ .measure_temp = spitz_measure_temp,
+ .presuspend = spitz_presuspend,
+ .postsuspend = spitz_postsuspend,
+ .read_devdata = spitzpm_read_devdata,
+ .charger_wakeup = spitz_charger_wakeup,
+ .should_wakeup = spitz_should_wakeup,
+#if defined(CONFIG_LCD_CORGI)
+ .backlight_limit = corgi_lcd_limit_intensity,
+#endif
+ .charge_on_volt = SHARPSL_CHARGE_ON_VOLT,
+ .charge_on_temp = SHARPSL_CHARGE_ON_TEMP,
+ .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH,
+ .charge_acin_low = SHARPSL_CHARGE_ON_ACIN_LOW,
+ .fatal_acin_volt = SHARPSL_FATAL_ACIN_VOLT,
+ .fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
+ .bat_levels = 40,
+ .bat_levels_noac = sharpsl_battery_levels_noac,
+ .bat_levels_acin = sharpsl_battery_levels_acin,
+ .status_high_acin = 188,
+ .status_low_acin = 178,
+ .status_high_noac = 185,
+ .status_low_noac = 175,
+};
+
+static struct platform_device *spitzpm_device;
+
+static int __devinit spitzpm_init(void)
+{
+ int ret;
+
+ if (!machine_is_spitz() && !machine_is_akita()
+ && !machine_is_borzoi())
+ return -ENODEV;
+
+ spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
+ if (!spitzpm_device)
+ return -ENOMEM;
+
+ spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
+ ret = platform_device_add(spitzpm_device);
+
+ if (ret)
+ platform_device_put(spitzpm_device);
+
+ return ret;
+}
+
+static void spitzpm_exit(void)
+{
+ platform_device_unregister(spitzpm_device);
+}
+
+module_init(spitzpm_init);
+module_exit(spitzpm_exit);
diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S
new file mode 100644
index 00000000..29f5f5c1
--- /dev/null
+++ b/arch/arm/mach-pxa/standby.S
@@ -0,0 +1,114 @@
+/*
+ * PXA27x standby mode
+ *
+ * Author: David Burrage
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+#include <mach/pxa2xx-regs.h>
+
+ .text
+
+#ifdef CONFIG_PXA27x
+ENTRY(pxa_cpu_standby)
+ ldr r0, =PSSR
+ mov r1, #(PSSR_PH | PSSR_STS)
+ mov r2, #PWRMODE_STANDBY
+ mov r3, #UNCACHED_PHYS_0 @ Read mem context in.
+ ldr ip, [r3]
+ b 1f
+
+ .align 5
+1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby
+ str r1, [r0] @ make sure PSSR_PH/STS are clear
+ mov pc, lr
+
+#endif
+
+#ifdef CONFIG_PXA3xx
+
+#define PXA3_MDCNFG 0x0000
+#define PXA3_MDCNFG_DMCEN (1 << 30)
+#define PXA3_DDR_HCAL 0x0060
+#define PXA3_DDR_HCAL_HCRNG 0x1f
+#define PXA3_DDR_HCAL_HCPROG (1 << 28)
+#define PXA3_DDR_HCAL_HCEN (1 << 31)
+#define PXA3_DMCIER 0x0070
+#define PXA3_DMCIER_EDLP (1 << 29)
+#define PXA3_DMCISR 0x0078
+#define PXA3_RCOMP 0x0100
+#define PXA3_RCOMP_SWEVAL (1 << 31)
+
+ENTRY(pm_enter_standby_start)
+ mov r1, #0xf6000000 @ DMEMC_REG_BASE (PXA3_MDCNFG)
+ add r1, r1, #0x00100000
+
+ /*
+ * Preload the TLB entry for accessing the dynamic memory
+ * controller registers. Note that page table lookups will
+ * fail until the dynamic memory controller has been
+ * reinitialised - and that includes MMU page table walks.
+ * This also means that only the dynamic memory controller
+ * can be reliably accessed in the code following standby.
+ */
+ ldr r2, [r1] @ Dummy read PXA3_MDCNFG
+
+ mcr p14, 0, r0, c7, c0, 0
+ .rept 8
+ nop
+ .endr
+
+ ldr r0, [r1, #PXA3_DDR_HCAL] @ Clear (and wait for) HCEN
+ bic r0, r0, #PXA3_DDR_HCAL_HCEN
+ str r0, [r1, #PXA3_DDR_HCAL]
+1: ldr r0, [r1, #PXA3_DDR_HCAL]
+ tst r0, #PXA3_DDR_HCAL_HCEN
+ bne 1b
+
+ ldr r0, [r1, #PXA3_RCOMP] @ Initiate RCOMP
+ orr r0, r0, #PXA3_RCOMP_SWEVAL
+ str r0, [r1, #PXA3_RCOMP]
+
+ mov r0, #~0 @ Clear interrupts
+ str r0, [r1, #PXA3_DMCISR]
+
+ ldr r0, [r1, #PXA3_DMCIER] @ set DMIER[EDLP]
+ orr r0, r0, #PXA3_DMCIER_EDLP
+ str r0, [r1, #PXA3_DMCIER]
+
+ ldr r0, [r1, #PXA3_DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN
+ bic r0, r0, #PXA3_DDR_HCAL_HCRNG
+ orr r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG
+ str r0, [r1, #PXA3_DDR_HCAL]
+
+1: ldr r0, [r1, #PXA3_DMCISR]
+ tst r0, #PXA3_DMCIER_EDLP
+ beq 1b
+
+ ldr r0, [r1, #PXA3_MDCNFG] @ set PXA3_MDCNFG[DMCEN]
+ orr r0, r0, #PXA3_MDCNFG_DMCEN
+ str r0, [r1, #PXA3_MDCNFG]
+1: ldr r0, [r1, #PXA3_MDCNFG]
+ tst r0, #PXA3_MDCNFG_DMCEN
+ beq 1b
+
+ ldr r0, [r1, #PXA3_DDR_HCAL] @ set PXA3_DDR_HCAL[HCRNG]
+ orr r0, r0, #2 @ HCRNG
+ str r0, [r1, #PXA3_DDR_HCAL]
+
+ ldr r0, [r1, #PXA3_DMCIER] @ Clear the interrupt
+ bic r0, r0, #0x20000000
+ str r0, [r1, #PXA3_DMCIER]
+
+ mov pc, lr
+ENTRY(pm_enter_standby_end)
+
+#endif
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
new file mode 100644
index 00000000..cb5611da
--- /dev/null
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -0,0 +1,1019 @@
+/*
+ * linux/arch/arm/mach-pxa/stargate2.c
+ *
+ * Author: Ed C. Epp
+ * Created: Nov 05, 2002
+ * Copyright: Intel Corp.
+ *
+ * Modified 2009: Jonathan Cameron <jic23@cam.ac.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/device.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/at24.h>
+#include <linux/smc91x.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/smemc.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mfd/da903x.h>
+#include <linux/sht15.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define STARGATE_NR_IRQS (IRQ_BOARD_START + 8)
+
+/* Bluetooth */
+#define SG2_BT_RESET 81
+
+/* SD */
+#define SG2_GPIO_nSD_DETECT 90
+#define SG2_SD_POWER_ENABLE 89
+
+static unsigned long sg2_im2_unified_pin_config[] __initdata = {
+ /* Device Identification for wakeup*/
+ GPIO102_GPIO,
+ /* DA9030 */
+ GPIO1_GPIO,
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+
+ /* 802.15.4 radio - driver out of mainline */
+ GPIO22_GPIO, /* CC_RSTN */
+ GPIO114_GPIO, /* CC_FIFO */
+ GPIO116_GPIO, /* CC_CCA */
+ GPIO0_GPIO, /* CC_FIFOP */
+ GPIO16_GPIO, /* CCSFD */
+ GPIO115_GPIO, /* Power enable */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* SSP 3 - 802.15.4 radio */
+ GPIO39_GPIO, /* Chip Select */
+ GPIO34_SSP3_SCLK,
+ GPIO35_SSP3_TXD,
+ GPIO41_SSP3_RXD,
+
+ /* SSP 2 to daughter boards */
+ GPIO11_SSP2_RXD,
+ GPIO38_SSP2_TXD,
+ GPIO36_SSP2_SCLK,
+ GPIO37_GPIO, /* chip select */
+
+ /* SSP 1 - to daughter boards */
+ GPIO24_GPIO, /* Chip Select */
+ GPIO23_SSP1_SCLK,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+
+ /* BTUART Basic Connector*/
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* STUART - IM2 via debug board not sure on SG2*/
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* Basic sensor board */
+ GPIO96_GPIO, /* accelerometer interrupt */
+ GPIO99_GPIO, /* ADC interrupt */
+
+ /* SHT15 */
+ GPIO100_GPIO,
+ GPIO98_GPIO,
+
+ /* Basic sensor board */
+ GPIO96_GPIO, /* accelerometer interrupt */
+ GPIO99_GPIO, /* ADC interrupt */
+
+ /* Connector pins specified as gpios */
+ GPIO94_GPIO, /* large basic connector pin 14 */
+ GPIO10_GPIO, /* large basic connector pin 23 */
+};
+
+static struct sht15_platform_data platform_data_sht15 = {
+ .gpio_data = 100,
+ .gpio_sck = 98,
+};
+
+static struct platform_device sht15 = {
+ .name = "sht15",
+ .id = -1,
+ .dev = {
+ .platform_data = &platform_data_sht15,
+ },
+};
+
+static struct regulator_consumer_supply stargate2_sensor_3_con[] = {
+ {
+ .dev = &sht15.dev,
+ .supply = "vcc",
+ },
+};
+
+enum stargate2_ldos{
+ vcc_vref,
+ vcc_cc2420,
+ /* a mote connector? */
+ vcc_mica,
+ /* the CSR bluecore chip */
+ vcc_bt,
+ /* The two voltages available to sensor boards */
+ vcc_sensor_1_8,
+ vcc_sensor_3,
+ /* directly connected to the pxa27x */
+ vcc_sram_ext,
+ vcc_pxa_pll,
+ vcc_pxa_usim, /* Reference voltage for certain gpios */
+ vcc_pxa_mem,
+ vcc_pxa_flash,
+ vcc_pxa_core, /*Dc-Dc buck not yet supported */
+ vcc_lcd,
+ vcc_bb,
+ vcc_bbio, /*not sure!*/
+ vcc_io, /* cc2420 802.15.4 radio and pxa vcc_io ?*/
+};
+
+/* The values of the various regulator constraints are obviously dependent
+ * on exactly what is wired to each ldo. Unfortunately this information is
+ * not generally available. More information has been requested from Xbow.
+ */
+static struct regulator_init_data stargate2_ldo_init_data[] = {
+ [vcc_bbio] = {
+ .constraints = { /* board default 1.8V */
+ .name = "vcc_bbio",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+ },
+ [vcc_bb] = {
+ .constraints = { /* board default 2.8V */
+ .name = "vcc_bb",
+ .min_uV = 2700000,
+ .max_uV = 3000000,
+ },
+ },
+ [vcc_pxa_flash] = {
+ .constraints = {/* default is 1.8V */
+ .name = "vcc_pxa_flash",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+ },
+ [vcc_cc2420] = { /* also vcc_io */
+ .constraints = {
+ /* board default is 2.8V */
+ .name = "vcc_cc2420",
+ .min_uV = 2700000,
+ .max_uV = 3300000,
+ },
+ },
+ [vcc_vref] = { /* Reference for what? */
+ .constraints = { /* default 1.8V */
+ .name = "vcc_vref",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+ },
+ [vcc_sram_ext] = {
+ .constraints = { /* default 2.8V */
+ .name = "vcc_sram_ext",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+ },
+ [vcc_mica] = {
+ .constraints = { /* default 2.8V */
+ .name = "vcc_mica",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+ },
+ [vcc_bt] = {
+ .constraints = { /* default 2.8V */
+ .name = "vcc_bt",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ },
+ },
+ [vcc_lcd] = {
+ .constraints = { /* default 2.8V */
+ .name = "vcc_lcd",
+ .min_uV = 2700000,
+ .max_uV = 3300000,
+ },
+ },
+ [vcc_io] = { /* Same or higher than everything
+ * bar vccbat and vccusb */
+ .constraints = { /* default 2.8V */
+ .name = "vcc_io",
+ .min_uV = 2692000,
+ .max_uV = 3300000,
+ },
+ },
+ [vcc_sensor_1_8] = {
+ .constraints = { /* default 1.8V */
+ .name = "vcc_sensor_1_8",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+ },
+ [vcc_sensor_3] = { /* curiously default 2.8V */
+ .constraints = {
+ .name = "vcc_sensor_3",
+ .min_uV = 2800000,
+ .max_uV = 3000000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(stargate2_sensor_3_con),
+ .consumer_supplies = stargate2_sensor_3_con,
+ },
+ [vcc_pxa_pll] = { /* 1.17V - 1.43V, default 1.3V*/
+ .constraints = {
+ .name = "vcc_pxa_pll",
+ .min_uV = 1170000,
+ .max_uV = 1430000,
+ },
+ },
+ [vcc_pxa_usim] = {
+ .constraints = { /* default 1.8V */
+ .name = "vcc_pxa_usim",
+ .min_uV = 1710000,
+ .max_uV = 2160000,
+ },
+ },
+ [vcc_pxa_mem] = {
+ .constraints = { /* default 1.8V */
+ .name = "vcc_pxa_mem",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ },
+ },
+};
+
+static struct mtd_partition stargate2flash_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = 0,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0x00040000,
+ .mask_flags = 0
+ }, {
+ .name = "Filesystem",
+ .size = 0x01DC0000,
+ .offset = 0x00240000,
+ .mask_flags = 0
+ },
+};
+
+static struct resource flash_resources = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct flash_platform_data stargate2_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = stargate2flash_partitions,
+ .nr_parts = ARRAY_SIZE(stargate2flash_partitions),
+ .name = "PXA27xOnChipROM",
+ .width = 2,
+};
+
+static struct platform_device stargate2_flash_device = {
+ .name = "pxa2xx-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &stargate2_flash_data,
+ },
+ .resource = &flash_resources,
+ .num_resources = 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp_master_0_info = {
+ .num_chipselect = 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp_master_1_info = {
+ .num_chipselect = 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp_master_2_info = {
+ .num_chipselect = 1,
+};
+
+/* An upcoming kernel change will scrap SFRM usage so these
+ * drivers have been moved to use gpio's via cs_control */
+static struct pxa2xx_spi_chip staccel_chip_info = {
+ .tx_threshold = 8,
+ .rx_threshold = 8,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = 24,
+};
+
+static struct pxa2xx_spi_chip cc2420_info = {
+ .tx_threshold = 8,
+ .rx_threshold = 8,
+ .dma_burst_size = 8,
+ .timeout = 235,
+ .gpio_cs = 39,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "lis3l02dq",
+ .max_speed_hz = 8000000,/* 8MHz max spi frequency at 3V */
+ .bus_num = 1,
+ .chip_select = 0,
+ .controller_data = &staccel_chip_info,
+ .irq = IRQ_GPIO(96),
+ }, {
+ .modalias = "cc2420",
+ .max_speed_hz = 6500000,
+ .bus_num = 3,
+ .chip_select = 0,
+ .controller_data = &cc2420_info,
+ },
+};
+
+static void sg2_udc_command(int cmd)
+{
+ switch (cmd) {
+ case PXA2XX_UDC_CMD_CONNECT:
+ UP2OCR |= UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE;
+ break;
+ case PXA2XX_UDC_CMD_DISCONNECT:
+ UP2OCR &= ~(UP2OCR_HXOE | UP2OCR_DPPUE | UP2OCR_DPPUBE);
+ break;
+ }
+}
+
+static struct i2c_pxa_platform_data i2c_pwr_pdata = {
+ .fast_mode = 1,
+};
+
+static struct i2c_pxa_platform_data i2c_pdata = {
+ .fast_mode = 1,
+};
+
+static void __init imote2_stargate2_init(void)
+{
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(sg2_im2_unified_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
+ pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
+ pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+
+ pxa27x_set_i2c_power_info(&i2c_pwr_pdata);
+ pxa_set_i2c_info(&i2c_pdata);
+}
+
+#ifdef CONFIG_MACH_INTELMOTE2
+/* As the the imote2 doesn't currently have a conventional SD slot
+ * there is no option to hotplug cards, making all this rather simple
+ */
+static int imote2_mci_get_ro(struct device *dev)
+{
+ return 0;
+}
+
+/* Rather simple case as hotplugging not possible */
+static struct pxamci_platform_data imote2_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, /* default anyway */
+ .get_ro = imote2_mci_get_ro,
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+static struct gpio_led imote2_led_pins[] = {
+ {
+ .name = "imote2:red",
+ .gpio = 103,
+ .active_low = 1,
+ }, {
+ .name = "imote2:green",
+ .gpio = 104,
+ .active_low = 1,
+ }, {
+ .name = "imote2:blue",
+ .gpio = 105,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data imote2_led_data = {
+ .num_leds = ARRAY_SIZE(imote2_led_pins),
+ .leds = imote2_led_pins,
+};
+
+static struct platform_device imote2_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &imote2_led_data,
+ },
+};
+
+static struct da903x_subdev_info imote2_da9030_subdevs[] = {
+ {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO2,
+ .platform_data = &stargate2_ldo_init_data[vcc_bbio],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO3,
+ .platform_data = &stargate2_ldo_init_data[vcc_bb],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO4,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO5,
+ .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO6,
+ .platform_data = &stargate2_ldo_init_data[vcc_vref],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO7,
+ .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO8,
+ .platform_data = &stargate2_ldo_init_data[vcc_mica],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO9,
+ .platform_data = &stargate2_ldo_init_data[vcc_bt],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO10,
+ .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO11,
+ .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO12,
+ .platform_data = &stargate2_ldo_init_data[vcc_lcd],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO15,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO17,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
+ }, {
+ .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
+ .id = DA9030_ID_LDO18,
+ .platform_data = &stargate2_ldo_init_data[vcc_io],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO19,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
+ },
+};
+
+static struct da903x_platform_data imote2_da9030_pdata = {
+ .num_subdevs = ARRAY_SIZE(imote2_da9030_subdevs),
+ .subdevs = imote2_da9030_subdevs,
+};
+
+static struct i2c_board_info __initdata imote2_pwr_i2c_board_info[] = {
+ {
+ .type = "da9030",
+ .addr = 0x49,
+ .platform_data = &imote2_da9030_pdata,
+ .irq = gpio_to_irq(1),
+ },
+};
+
+static struct i2c_board_info __initdata imote2_i2c_board_info[] = {
+ { /* UCAM sensor board */
+ .type = "max1239",
+ .addr = 0x35,
+ }, { /* ITS400 Sensor board only */
+ .type = "max1363",
+ .addr = 0x34,
+ /* Through a nand gate - Also beware, on V2 sensor board the
+ * pull up resistors are missing.
+ */
+ .irq = IRQ_GPIO(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tsl2561",
+ .addr = 0x49,
+ /* Through a nand gate - Also beware, on V2 sensor board the
+ * pull up resistors are missing.
+ */
+ .irq = IRQ_GPIO(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tmp175",
+ .addr = 0x4A,
+ .irq = IRQ_GPIO(96),
+ }, { /* IMB400 Multimedia board */
+ .type = "wm8940",
+ .addr = 0x1A,
+ },
+};
+
+static unsigned long imote2_pin_config[] __initdata = {
+
+ /* Button */
+ GPIO91_GPIO,
+
+ /* LEDS */
+ GPIO103_GPIO, /* red led */
+ GPIO104_GPIO, /* green led */
+ GPIO105_GPIO, /* blue led */
+};
+
+static struct pxa2xx_udc_mach_info imote2_udc_info __initdata = {
+ .udc_command = sg2_udc_command,
+};
+
+static struct platform_device *imote2_devices[] = {
+ &stargate2_flash_device,
+ &imote2_leds,
+ &sht15,
+};
+
+static void __init imote2_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(imote2_pin_config));
+
+ imote2_stargate2_init();
+
+ platform_add_devices(imote2_devices, ARRAY_SIZE(imote2_devices));
+
+ i2c_register_board_info(0, imote2_i2c_board_info,
+ ARRAY_SIZE(imote2_i2c_board_info));
+ i2c_register_board_info(1, imote2_pwr_i2c_board_info,
+ ARRAY_SIZE(imote2_pwr_i2c_board_info));
+
+ pxa_set_mci_info(&imote2_mci_platform_data);
+ pxa_set_udc_info(&imote2_udc_info);
+}
+#endif
+
+#ifdef CONFIG_MACH_STARGATE2
+
+static unsigned long stargate2_pin_config[] __initdata = {
+
+ GPIO15_nCS_1, /* SRAM */
+ /* SMC91x */
+ GPIO80_nCS_4,
+ GPIO40_GPIO, /*cable detect?*/
+
+ /* Button */
+ GPIO91_GPIO | WAKEUP_ON_LEVEL_HIGH,
+
+ /* Compact Flash */
+ GPIO79_PSKTSEL,
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO120_GPIO, /* Buff ctrl */
+ GPIO108_GPIO, /* Power ctrl */
+ GPIO82_GPIO, /* Reset */
+ GPIO53_GPIO, /* SG2_S0_GPIO_DETECT */
+
+ /* MMC not shared with imote2 */
+ GPIO90_GPIO, /* nSD detect */
+ GPIO89_GPIO, /* SD_POWER_ENABLE */
+
+ /* Bluetooth */
+ GPIO81_GPIO, /* reset */
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = (PXA_CS4_PHYS + 0x300),
+ .end = (PXA_CS4_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO(40),
+ .end = IRQ_GPIO(40),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata stargate2_smc91x_info = {
+ .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT | SMC91X_USE_32BIT
+ | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &stargate2_smc91x_info,
+ },
+};
+
+
+/*
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert / eject.
+ */
+static int stargate2_mci_init(struct device *dev,
+ irq_handler_t stargate2_detect_int,
+ void *data)
+{
+ int err;
+
+ err = gpio_request(SG2_SD_POWER_ENABLE, "SG2_sd_power_enable");
+ if (err) {
+ printk(KERN_ERR "Can't get the gpio for SD power control");
+ goto return_err;
+ }
+ gpio_direction_output(SG2_SD_POWER_ENABLE, 0);
+
+ err = gpio_request(SG2_GPIO_nSD_DETECT, "SG2_sd_detect");
+ if (err) {
+ printk(KERN_ERR "Can't get the sd detect gpio");
+ goto free_power_en;
+ }
+ gpio_direction_input(SG2_GPIO_nSD_DETECT);
+
+ err = request_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT),
+ stargate2_detect_int,
+ IRQ_TYPE_EDGE_BOTH,
+ "MMC card detect",
+ data);
+ if (err) {
+ printk(KERN_ERR "can't request MMC card detect IRQ\n");
+ goto free_nsd_detect;
+ }
+ return 0;
+
+ free_nsd_detect:
+ gpio_free(SG2_GPIO_nSD_DETECT);
+ free_power_en:
+ gpio_free(SG2_SD_POWER_ENABLE);
+ return_err:
+ return err;
+}
+
+/**
+ * stargate2_mci_setpower() - set state of mmc power supply
+ *
+ * Very simple control. Either it is on or off and is controlled by
+ * a gpio pin */
+static void stargate2_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ gpio_set_value(SG2_SD_POWER_ENABLE, !!vdd);
+}
+
+static void stargate2_mci_exit(struct device *dev, void *data)
+{
+ free_irq(IRQ_GPIO(SG2_GPIO_nSD_DETECT), data);
+ gpio_free(SG2_SD_POWER_ENABLE);
+ gpio_free(SG2_GPIO_nSD_DETECT);
+}
+
+static struct pxamci_platform_data stargate2_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .init = stargate2_mci_init,
+ .setpower = stargate2_mci_setpower,
+ .exit = stargate2_mci_exit,
+};
+
+
+/*
+ * SRAM - The Stargate 2 has 32MB of SRAM.
+ *
+ * Here it is made available as an MTD. This will then
+ * typically have a cifs filesystem created on it to provide
+ * fast temporary storage.
+ */
+static struct resource sram_resources = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + SZ_32M-1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platdata_mtd_ram stargate2_sram_pdata = {
+ .mapname = "Stargate2 SRAM",
+ .bankwidth = 2,
+};
+
+static struct platform_device stargate2_sram = {
+ .name = "mtd-ram",
+ .id = 0,
+ .resource = &sram_resources,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &stargate2_sram_pdata,
+ },
+};
+
+static struct pcf857x_platform_data platform_data_pcf857x = {
+ .gpio_base = 128,
+ .n_latch = 0,
+ .setup = NULL,
+ .teardown = NULL,
+ .context = NULL,
+};
+
+static struct at24_platform_data pca9500_eeprom_pdata = {
+ .byte_len = 256,
+ .page_size = 4,
+};
+
+/**
+ * stargate2_reset_bluetooth() reset the bluecore to ensure consistent state
+ **/
+static int stargate2_reset_bluetooth(void)
+{
+ int err;
+ err = gpio_request(SG2_BT_RESET, "SG2_BT_RESET");
+ if (err) {
+ printk(KERN_ERR "Could not get gpio for bluetooth reset\n");
+ return err;
+ }
+ gpio_direction_output(SG2_BT_RESET, 1);
+ mdelay(5);
+ /* now reset it - 5 msec minimum */
+ gpio_set_value(SG2_BT_RESET, 0);
+ mdelay(10);
+ gpio_set_value(SG2_BT_RESET, 1);
+ gpio_free(SG2_BT_RESET);
+ return 0;
+}
+
+static struct led_info stargate2_leds[] = {
+ {
+ .name = "sg2:red",
+ .flags = DA9030_LED_RATE_ON,
+ }, {
+ .name = "sg2:blue",
+ .flags = DA9030_LED_RATE_ON,
+ }, {
+ .name = "sg2:green",
+ .flags = DA9030_LED_RATE_ON,
+ },
+};
+
+static struct da903x_subdev_info stargate2_da9030_subdevs[] = {
+ {
+ .name = "da903x-led",
+ .id = DA9030_ID_LED_2,
+ .platform_data = &stargate2_leds[0],
+ }, {
+ .name = "da903x-led",
+ .id = DA9030_ID_LED_3,
+ .platform_data = &stargate2_leds[2],
+ }, {
+ .name = "da903x-led",
+ .id = DA9030_ID_LED_4,
+ .platform_data = &stargate2_leds[1],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO2,
+ .platform_data = &stargate2_ldo_init_data[vcc_bbio],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO3,
+ .platform_data = &stargate2_ldo_init_data[vcc_bb],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO4,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_flash],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO5,
+ .platform_data = &stargate2_ldo_init_data[vcc_cc2420],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO6,
+ .platform_data = &stargate2_ldo_init_data[vcc_vref],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO7,
+ .platform_data = &stargate2_ldo_init_data[vcc_sram_ext],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO8,
+ .platform_data = &stargate2_ldo_init_data[vcc_mica],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO9,
+ .platform_data = &stargate2_ldo_init_data[vcc_bt],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO10,
+ .platform_data = &stargate2_ldo_init_data[vcc_sensor_1_8],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO11,
+ .platform_data = &stargate2_ldo_init_data[vcc_sensor_3],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO12,
+ .platform_data = &stargate2_ldo_init_data[vcc_lcd],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO15,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_pll],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO17,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_usim],
+ }, {
+ .name = "da903x-regulator", /*pxa vcc i/o and cc2420 vcc i/o */
+ .id = DA9030_ID_LDO18,
+ .platform_data = &stargate2_ldo_init_data[vcc_io],
+ }, {
+ .name = "da903x-regulator",
+ .id = DA9030_ID_LDO19,
+ .platform_data = &stargate2_ldo_init_data[vcc_pxa_mem],
+ },
+};
+
+static struct da903x_platform_data stargate2_da9030_pdata = {
+ .num_subdevs = ARRAY_SIZE(stargate2_da9030_subdevs),
+ .subdevs = stargate2_da9030_subdevs,
+};
+
+static struct i2c_board_info __initdata stargate2_pwr_i2c_board_info[] = {
+ {
+ .type = "da9030",
+ .addr = 0x49,
+ .platform_data = &stargate2_da9030_pdata,
+ .irq = gpio_to_irq(1),
+ },
+};
+
+static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
+ /* Techically this a pca9500 - but it's compatible with the 8574
+ * for gpio expansion and the 24c02 for eeprom access.
+ */
+ {
+ .type = "pcf8574",
+ .addr = 0x27,
+ .platform_data = &platform_data_pcf857x,
+ }, {
+ .type = "24c02",
+ .addr = 0x57,
+ .platform_data = &pca9500_eeprom_pdata,
+ }, {
+ .type = "max1238",
+ .addr = 0x35,
+ }, { /* ITS400 Sensor board only */
+ .type = "max1363",
+ .addr = 0x34,
+ /* Through a nand gate - Also beware, on V2 sensor board the
+ * pull up resistors are missing.
+ */
+ .irq = IRQ_GPIO(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tsl2561",
+ .addr = 0x49,
+ /* Through a nand gate - Also beware, on V2 sensor board the
+ * pull up resistors are missing.
+ */
+ .irq = IRQ_GPIO(99),
+ }, { /* ITS400 Sensor board only */
+ .type = "tmp175",
+ .addr = 0x4A,
+ .irq = IRQ_GPIO(96),
+ },
+};
+
+/* Board doesn't support cable detection - so always lie and say
+ * something is there.
+ */
+static int sg2_udc_detect(void)
+{
+ return 1;
+}
+
+static struct pxa2xx_udc_mach_info stargate2_udc_info __initdata = {
+ .udc_is_connected = sg2_udc_detect,
+ .udc_command = sg2_udc_command,
+};
+
+static struct platform_device *stargate2_devices[] = {
+ &stargate2_flash_device,
+ &stargate2_sram,
+ &smc91x_device,
+ &sht15,
+};
+
+static void __init stargate2_init(void)
+{
+ /* This is probably a board specific hack as this must be set
+ prior to connecting the MFP stuff up. */
+ __raw_writel(__raw_readl(MECR) & ~MECR_NOS, MECR);
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(stargate2_pin_config));
+
+ imote2_stargate2_init();
+
+ platform_add_devices(ARRAY_AND_SIZE(stargate2_devices));
+
+ i2c_register_board_info(0, ARRAY_AND_SIZE(stargate2_i2c_board_info));
+ i2c_register_board_info(1, stargate2_pwr_i2c_board_info,
+ ARRAY_SIZE(stargate2_pwr_i2c_board_info));
+
+ pxa_set_mci_info(&stargate2_mci_platform_data);
+
+ pxa_set_udc_info(&stargate2_udc_info);
+
+ stargate2_reset_bluetooth();
+}
+#endif
+
+#ifdef CONFIG_MACH_INTELMOTE2
+MACHINE_START(INTELMOTE2, "IMOTE 2")
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = imote2_init,
+ .boot_params = 0xA0000100,
+MACHINE_END
+#endif
+
+#ifdef CONFIG_MACH_STARGATE2
+MACHINE_START(STARGATE2, "Stargate 2")
+ .map_io = pxa27x_map_io,
+ .nr_irqs = STARGATE_NR_IRQS,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = stargate2_init,
+ .boot_params = 0xA0000100,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
new file mode 100644
index 00000000..53d4a472
--- /dev/null
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -0,0 +1,497 @@
+/*
+ * linux/arch/arm/mach-pxa/tavorevb.c
+ *
+ * Support for the Marvell PXA930 Evaluation Board
+ *
+ * Copyright (C) 2007-2008 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/smc91x.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa930.h>
+#include <mach/pxafb.h>
+#include <plat/pxa27x_keypad.h>
+
+#include "devices.h"
+#include "generic.h"
+
+/* Tavor EVB MFP configurations */
+static mfp_cfg_t tavorevb_mfp_cfg[] __initdata = {
+ /* Ethernet */
+ DF_nCS1_nCS3,
+ GPIO47_GPIO,
+
+ /* LCD */
+ GPIO23_LCD_DD0,
+ GPIO24_LCD_DD1,
+ GPIO25_LCD_DD2,
+ GPIO26_LCD_DD3,
+ GPIO27_LCD_DD4,
+ GPIO28_LCD_DD5,
+ GPIO29_LCD_DD6,
+ GPIO44_LCD_DD7,
+ GPIO21_LCD_CS,
+ GPIO22_LCD_CS2,
+
+ GPIO17_LCD_FCLK_RD,
+ GPIO18_LCD_LCLK_A0,
+ GPIO19_LCD_PCLK_WR,
+
+ /* LCD Backlight */
+ GPIO43_PWM3, /* primary backlight */
+ GPIO32_PWM0, /* secondary backlight */
+
+ /* Keypad */
+ GPIO0_KP_MKIN_0,
+ GPIO2_KP_MKIN_1,
+ GPIO4_KP_MKIN_2,
+ GPIO6_KP_MKIN_3,
+ GPIO8_KP_MKIN_4,
+ GPIO10_KP_MKIN_5,
+ GPIO12_KP_MKIN_6,
+ GPIO1_KP_MKOUT_0,
+ GPIO3_KP_MKOUT_1,
+ GPIO5_KP_MKOUT_2,
+ GPIO7_KP_MKOUT_3,
+ GPIO9_KP_MKOUT_4,
+ GPIO11_KP_MKOUT_5,
+ GPIO13_KP_MKOUT_6,
+
+ GPIO14_KP_DKIN_2,
+ GPIO15_KP_DKIN_3,
+};
+
+#define TAVOREVB_ETH_PHYS (0x14000000)
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = (TAVOREVB_ETH_PHYS + 0x300),
+ .end = (TAVOREVB_ETH_PHYS + 0xfffff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)),
+ .end = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO47)),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata tavorevb_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &tavorevb_smc91x_info,
+ },
+};
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int tavorevb_matrix_key_map[] = {
+ /* KEY(row, col, key_code) */
+ KEY(0, 4, KEY_A), KEY(0, 5, KEY_B), KEY(0, 6, KEY_C),
+ KEY(1, 4, KEY_E), KEY(1, 5, KEY_F), KEY(1, 6, KEY_G),
+ KEY(2, 4, KEY_I), KEY(2, 5, KEY_J), KEY(2, 6, KEY_K),
+ KEY(3, 4, KEY_M), KEY(3, 5, KEY_N), KEY(3, 6, KEY_O),
+ KEY(4, 5, KEY_R), KEY(4, 6, KEY_S),
+ KEY(5, 4, KEY_U), KEY(5, 4, KEY_V), KEY(5, 6, KEY_W),
+
+ KEY(6, 4, KEY_Y), KEY(6, 5, KEY_Z),
+
+ KEY(0, 3, KEY_0), KEY(2, 0, KEY_1), KEY(2, 1, KEY_2), KEY(2, 2, KEY_3),
+ KEY(2, 3, KEY_4), KEY(1, 0, KEY_5), KEY(1, 1, KEY_6), KEY(1, 2, KEY_7),
+ KEY(1, 3, KEY_8), KEY(0, 2, KEY_9),
+
+ KEY(6, 6, KEY_SPACE),
+ KEY(0, 0, KEY_KPASTERISK), /* * */
+ KEY(0, 1, KEY_KPDOT), /* # */
+
+ KEY(4, 1, KEY_UP),
+ KEY(4, 3, KEY_DOWN),
+ KEY(4, 0, KEY_LEFT),
+ KEY(4, 2, KEY_RIGHT),
+ KEY(6, 0, KEY_HOME),
+ KEY(3, 2, KEY_END),
+ KEY(6, 1, KEY_DELETE),
+ KEY(5, 2, KEY_BACK),
+ KEY(6, 3, KEY_CAPSLOCK), /* KEY_LEFTSHIFT), */
+
+ KEY(4, 4, KEY_ENTER), /* scroll push */
+ KEY(6, 2, KEY_ENTER), /* keypad action */
+
+ KEY(3, 1, KEY_SEND),
+ KEY(5, 3, KEY_RECORD),
+ KEY(5, 0, KEY_VOLUMEUP),
+ KEY(5, 1, KEY_VOLUMEDOWN),
+
+ KEY(3, 0, KEY_F22), /* soft1 */
+ KEY(3, 3, KEY_F23), /* soft2 */
+};
+
+static struct pxa27x_keypad_platform_data tavorevb_keypad_info = {
+ .matrix_key_rows = 7,
+ .matrix_key_cols = 7,
+ .matrix_key_map = tavorevb_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(tavorevb_matrix_key_map),
+ .debounce_interval = 30,
+};
+
+static void __init tavorevb_init_keypad(void)
+{
+ pxa_set_keypad_info(&tavorevb_keypad_info);
+}
+#else
+static inline void tavorevb_init_keypad(void) {}
+#endif /* CONFIG_KEYBOARD_PXA27x || CONFIG_KEYBOARD_PXA27x_MODULE */
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct platform_pwm_backlight_data tavorevb_backlight_data[] = {
+ [0] = {
+ /* primary backlight */
+ .pwm_id = 2,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 100000,
+ },
+ [1] = {
+ /* secondary backlight */
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 100000,
+ },
+};
+
+static struct platform_device tavorevb_backlight_devices[] = {
+ [0] = {
+ .name = "pwm-backlight",
+ .id = 0,
+ .dev = {
+ .platform_data = &tavorevb_backlight_data[0],
+ },
+ },
+ [1] = {
+ .name = "pwm-backlight",
+ .id = 1,
+ .dev = {
+ .platform_data = &tavorevb_backlight_data[1],
+ },
+ },
+};
+
+static uint16_t panel_init[] = {
+ /* DSTB OUT */
+ SMART_CMD(0x00),
+ SMART_CMD_NOOP,
+ SMART_DELAY(1),
+
+ SMART_CMD(0x00),
+ SMART_CMD_NOOP,
+ SMART_DELAY(1),
+
+ SMART_CMD(0x00),
+ SMART_CMD_NOOP,
+ SMART_DELAY(1),
+
+ /* STB OUT */
+ SMART_CMD(0x00),
+ SMART_CMD(0x1D),
+ SMART_DAT(0x00),
+ SMART_DAT(0x05),
+ SMART_DELAY(1),
+
+ /* P-ON Init sequence */
+ SMART_CMD(0x00), /* OSC ON */
+ SMART_CMD(0x00),
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_CMD(0x00),
+ SMART_CMD(0x01), /* SOURCE DRIVER SHIFT DIRECTION and display RAM setting */
+ SMART_DAT(0x01),
+ SMART_DAT(0x27),
+ SMART_CMD(0x00),
+ SMART_CMD(0x02), /* LINE INV */
+ SMART_DAT(0x02),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x03), /* IF mode(1) */
+ SMART_DAT(0x01), /* 8bit smart mode(8-8),high speed write mode */
+ SMART_DAT(0x30),
+ SMART_CMD(0x07),
+ SMART_CMD(0x00), /* RAM Write Mode */
+ SMART_DAT(0x00),
+ SMART_DAT(0x03),
+ SMART_CMD(0x00),
+
+ /* DISPLAY Setting, 262K, fixed(NO scroll), no split screen */
+ SMART_CMD(0x07),
+ SMART_DAT(0x40), /* 16/18/19 BPP */
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x08), /* BP, FP Seting, BP=2H, FP=3H */
+ SMART_DAT(0x03),
+ SMART_DAT(0x02),
+ SMART_CMD(0x00),
+ SMART_CMD(0x0C), /* IF mode(2), using internal clock & MPU */
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x0D), /* Frame setting, 1Min. Frequence, 16CLK */
+ SMART_DAT(0x00),
+ SMART_DAT(0x10),
+ SMART_CMD(0x00),
+ SMART_CMD(0x12), /* Timing(1),ASW W=4CLK, ASW ST=1CLK */
+ SMART_DAT(0x03),
+ SMART_DAT(0x02),
+ SMART_CMD(0x00),
+ SMART_CMD(0x13), /* Timing(2),OEV ST=0.5CLK, OEV ED=1CLK */
+ SMART_DAT(0x01),
+ SMART_DAT(0x02),
+ SMART_CMD(0x00),
+ SMART_CMD(0x14), /* Timing(3), ASW HOLD=0.5CLK */
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x15), /* Timing(4), CKV ST=0CLK, CKV ED=1CLK */
+ SMART_DAT(0x20),
+ SMART_DAT(0x00),
+ SMART_CMD(0x00),
+ SMART_CMD(0x1C),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x03),
+ SMART_CMD(0x00),
+ SMART_DAT(0x04),
+ SMART_DAT(0x03),
+ SMART_CMD(0x03),
+ SMART_CMD(0x01),
+ SMART_DAT(0x03),
+ SMART_DAT(0x04),
+ SMART_CMD(0x03),
+ SMART_CMD(0x02),
+ SMART_DAT(0x04),
+ SMART_DAT(0x03),
+ SMART_CMD(0x03),
+ SMART_CMD(0x03),
+ SMART_DAT(0x03),
+ SMART_DAT(0x03),
+ SMART_CMD(0x03),
+ SMART_CMD(0x04),
+ SMART_DAT(0x01),
+ SMART_DAT(0x01),
+ SMART_CMD(0x03),
+ SMART_CMD(0x05),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x04),
+ SMART_CMD(0x02),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x04),
+ SMART_CMD(0x03),
+ SMART_DAT(0x01),
+ SMART_DAT(0x3F),
+ SMART_DELAY(0),
+
+ /* DISP RAM setting: 240*320 */
+ SMART_CMD(0x04), /* HADDR, START 0 */
+ SMART_CMD(0x06),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00), /* x1,3 */
+ SMART_CMD(0x04), /* HADDR, END 4 */
+ SMART_CMD(0x07),
+ SMART_DAT(0x00),
+ SMART_DAT(0xEF), /* x2, 7 */
+ SMART_CMD(0x04), /* VADDR, START 8 */
+ SMART_CMD(0x08),
+ SMART_DAT(0x00), /* y1, 10 */
+ SMART_DAT(0x00), /* y1, 11 */
+ SMART_CMD(0x04), /* VADDR, END 12 */
+ SMART_CMD(0x09),
+ SMART_DAT(0x01), /* y2, 14 */
+ SMART_DAT(0x3F), /* y2, 15 */
+ SMART_CMD(0x02), /* RAM ADDR SETTING 16 */
+ SMART_CMD(0x00),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00), /* x1, 19 */
+ SMART_CMD(0x02), /* RAM ADDR SETTING 20 */
+ SMART_CMD(0x01),
+ SMART_DAT(0x00), /* y1, 22 */
+ SMART_DAT(0x00), /* y1, 23 */
+};
+
+static uint16_t panel_on[] = {
+ /* Power-IC ON */
+ SMART_CMD(0x01),
+ SMART_CMD(0x02),
+ SMART_DAT(0x07),
+ SMART_DAT(0x7D),
+ SMART_CMD(0x01),
+ SMART_CMD(0x03),
+ SMART_DAT(0x00),
+ SMART_DAT(0x05),
+ SMART_CMD(0x01),
+ SMART_CMD(0x04),
+ SMART_DAT(0x00),
+ SMART_DAT(0x00),
+ SMART_CMD(0x01),
+ SMART_CMD(0x05),
+ SMART_DAT(0x00),
+ SMART_DAT(0x15),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xC0),
+ SMART_DAT(0x10),
+ SMART_DELAY(30),
+
+ /* DISP ON */
+ SMART_CMD(0x01),
+ SMART_CMD(0x01),
+ SMART_DAT(0x00),
+ SMART_DAT(0x01),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xFF),
+ SMART_DAT(0xFE),
+ SMART_DELAY(150),
+};
+
+static uint16_t panel_off[] = {
+ SMART_CMD(0x00),
+ SMART_CMD(0x1E),
+ SMART_DAT(0x00),
+ SMART_DAT(0x0A),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xFF),
+ SMART_DAT(0xEE),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xF8),
+ SMART_DAT(0x12),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xE8),
+ SMART_DAT(0x11),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0xC0),
+ SMART_DAT(0x11),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0x40),
+ SMART_DAT(0x11),
+ SMART_CMD(0x01),
+ SMART_CMD(0x00),
+ SMART_DAT(0x00),
+ SMART_DAT(0x10),
+};
+
+static uint16_t update_framedata[] = {
+ /* write ram */
+ SMART_CMD(0x02),
+ SMART_CMD(0x02),
+
+ /* write frame data */
+ SMART_CMD_WRITE_FRAME,
+};
+
+static void ltm020d550_lcd_power(int on, struct fb_var_screeninfo *var)
+{
+ struct fb_info *info = container_of(var, struct fb_info, var);
+
+ if (on) {
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_init));
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_on));
+ } else {
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(panel_off));
+ }
+
+ if (pxafb_smart_flush(info))
+ pr_err("%s: timed out\n", __func__);
+}
+
+static void ltm020d550_update(struct fb_info *info)
+{
+ pxafb_smart_queue(info, ARRAY_AND_SIZE(update_framedata));
+ pxafb_smart_flush(info);
+}
+
+static struct pxafb_mode_info toshiba_ltm020d550_modes[] = {
+ [0] = {
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .a0csrd_set_hld = 30,
+ .a0cswr_set_hld = 30,
+ .wr_pulse_width = 30,
+ .rd_pulse_width = 170,
+ .op_hold_time = 30,
+ .cmd_inh_time = 60,
+
+ /* L_LCLK_A0 and L_LCLK_RD active low */
+ .sync = FB_SYNC_HOR_HIGH_ACT |
+ FB_SYNC_VERT_HIGH_ACT,
+ },
+};
+
+static struct pxafb_mach_info tavorevb_lcd_info = {
+ .modes = toshiba_ltm020d550_modes,
+ .num_modes = 1,
+ .lcd_conn = LCD_SMART_PANEL_8BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = ltm020d550_lcd_power,
+ .smart_update = ltm020d550_update,
+};
+
+static void __init tavorevb_init_lcd(void)
+{
+ platform_device_register(&tavorevb_backlight_devices[0]);
+ platform_device_register(&tavorevb_backlight_devices[1]);
+ pxa_set_fb_info(NULL, &tavorevb_lcd_info);
+}
+#else
+static inline void tavorevb_init_lcd(void) {}
+#endif /* CONFIG_FB_PXA || CONFIG_FB_PXA_MODULE */
+
+static void __init tavorevb_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(tavorevb_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ platform_device_register(&smc91x_device);
+
+ tavorevb_init_lcd();
+ tavorevb_init_keypad();
+}
+
+MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
+ /* Maintainer: Eric Miao <eric.miao@marvell.com> */
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = tavorevb_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/tavorevb3.c b/arch/arm/mach-pxa/tavorevb3.c
new file mode 100644
index 00000000..79f4422f
--- /dev/null
+++ b/arch/arm/mach-pxa/tavorevb3.c
@@ -0,0 +1,134 @@
+/*
+ * linux/arch/arm/mach-pxa/tavorevb3.c
+ *
+ * Support for the Marvell EVB3 Development Platform.
+ *
+ * Copyright: (C) Copyright 2008-2010 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/gpio.h>
+#include <linux/mfd/88pm860x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa930.h>
+
+#include "devices.h"
+#include "generic.h"
+
+#define TAVOREVB3_NR_IRQS (IRQ_BOARD_START + 24)
+
+static mfp_cfg_t evb3_mfp_cfg[] __initdata = {
+ /* UART */
+ GPIO53_UART1_TXD,
+ GPIO54_UART1_RXD,
+
+ /* PMIC */
+ PMIC_INT_GPIO83,
+};
+
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct pm860x_touch_pdata evb3_touch = {
+ .gpadc_prebias = 1,
+ .slot_cycle = 1,
+ .tsi_prebias = 6,
+ .pen_prebias = 16,
+ .pen_prechg = 2,
+ .res_x = 300,
+};
+
+static struct pm860x_backlight_pdata evb3_backlight[] = {
+ {
+ .id = PM8606_ID_BACKLIGHT,
+ .iset = PM8606_WLED_CURRENT(24),
+ .flags = PM8606_BACKLIGHT1,
+ },
+ {},
+};
+
+static struct pm860x_led_pdata evb3_led[] = {
+ {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED1_BLUE,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_RED,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_GREEN,
+ }, {
+ .id = PM8606_ID_LED,
+ .iset = PM8606_LED_CURRENT(12),
+ .flags = PM8606_LED2_BLUE,
+ },
+};
+
+static struct pm860x_platform_data evb3_pm8607_info = {
+ .touch = &evb3_touch,
+ .backlight = &evb3_backlight[0],
+ .led = &evb3_led[0],
+ .companion_addr = 0x10,
+ .irq_mode = 0,
+ .irq_base = IRQ_BOARD_START,
+
+ .i2c_port = GI2C_PORT,
+};
+
+static struct i2c_board_info evb3_i2c_info[] = {
+ {
+ .type = "88PM860x",
+ .addr = 0x34,
+ .platform_data = &evb3_pm8607_info,
+ .irq = gpio_to_irq(mfp_to_gpio(MFP_PIN_GPIO83)),
+ },
+};
+
+static void __init evb3_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(evb3_i2c_info));
+}
+#else
+static inline void evb3_init_i2c(void) {}
+#endif
+
+static void __init evb3_init(void)
+{
+ /* initialize MFP configurations */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(evb3_mfp_cfg));
+
+ pxa_set_ffuart_info(NULL);
+
+ evb3_init_i2c();
+}
+
+MACHINE_START(TAVOREVB3, "PXA950 Evaluation Board (aka TavorEVB3)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = TAVOREVB3_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = evb3_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
new file mode 100644
index 00000000..de684701
--- /dev/null
+++ b/arch/arm/mach-pxa/time.c
@@ -0,0 +1,178 @@
+/*
+ * arch/arm/mach-pxa/time.c
+ *
+ * PXA clocksource, clockevents, and OST interrupt handlers.
+ * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>.
+ *
+ * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
+ * by MontaVista Software, Inc. (Nico, your code rocks!)
+ *
+ * This program is free software; you can 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/interrupt.h>
+#include <linux/clockchips.h>
+#include <linux/sched.h>
+
+#include <asm/div64.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
+#include <mach/regs-ost.h>
+
+/*
+ * This is PXA's sched_clock implementation. This has a resolution
+ * of at least 308 ns and a maximum value of 208 days.
+ *
+ * The return value is guaranteed to be monotonic in that range as
+ * long as there is always less than 582 seconds between successive
+ * calls to sched_clock() which should always be the case in practice.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = OSCR;
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace pxa_update_sched_clock(void)
+{
+ u32 cyc = OSCR;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+
+#define MIN_OSCR_DELTA 16
+
+static irqreturn_t
+pxa_ost0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* Disarm the compare/match, signal the event. */
+ OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
+ c->event_handler(c);
+
+ return IRQ_HANDLED;
+}
+
+static int
+pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+ unsigned long next, oscr;
+
+ OIER |= OIER_E0;
+ next = OSCR + delta;
+ OSMR0 = next;
+ oscr = OSCR;
+
+ return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+}
+
+static void
+pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* initializing, released, or preparing for suspend */
+ OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+}
+
+static struct clock_event_device ckevt_pxa_osmr0 = {
+ .name = "osmr0",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = pxa_osmr0_set_next_event,
+ .set_mode = pxa_osmr0_set_mode,
+};
+
+static struct irqaction pxa_ost0_irq = {
+ .name = "ost0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = pxa_ost0_interrupt,
+ .dev_id = &ckevt_pxa_osmr0,
+};
+
+static void __init pxa_timer_init(void)
+{
+ unsigned long clock_tick_rate = get_clock_tick_rate();
+
+ OIER = 0;
+ OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
+
+ init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
+
+ clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
+ ckevt_pxa_osmr0.max_delta_ns =
+ clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
+ ckevt_pxa_osmr0.min_delta_ns =
+ clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_pxa_osmr0) + 1;
+ ckevt_pxa_osmr0.cpumask = cpumask_of(0);
+
+ setup_irq(IRQ_OST0, &pxa_ost0_irq);
+
+ clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32,
+ clocksource_mmio_readl_up);
+ clockevents_register_device(&ckevt_pxa_osmr0);
+}
+
+#ifdef CONFIG_PM
+static unsigned long osmr[4], oier, oscr;
+
+static void pxa_timer_suspend(void)
+{
+ osmr[0] = OSMR0;
+ osmr[1] = OSMR1;
+ osmr[2] = OSMR2;
+ osmr[3] = OSMR3;
+ oier = OIER;
+ oscr = OSCR;
+}
+
+static void pxa_timer_resume(void)
+{
+ /*
+ * Ensure that we have at least MIN_OSCR_DELTA between match
+ * register 0 and the OSCR, to guarantee that we will receive
+ * the one-shot timer interrupt. We adjust OSMR0 in preference
+ * to OSCR to guarantee that OSCR is monotonically incrementing.
+ */
+ if (osmr[0] - oscr < MIN_OSCR_DELTA)
+ osmr[0] += MIN_OSCR_DELTA;
+
+ OSMR0 = osmr[0];
+ OSMR1 = osmr[1];
+ OSMR2 = osmr[2];
+ OSMR3 = osmr[3];
+ OIER = oier;
+ OSCR = oscr;
+}
+#else
+#define pxa_timer_suspend NULL
+#define pxa_timer_resume NULL
+#endif
+
+struct sys_timer pxa_timer = {
+ .init = pxa_timer_init,
+ .suspend = pxa_timer_suspend,
+ .resume = pxa_timer_resume,
+};
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
new file mode 100644
index 00000000..b9b1e5c2
--- /dev/null
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -0,0 +1,148 @@
+/*
+ * Bluetooth built-in chip control
+ *
+ * Copyright (c) 2008 Dmitry Baryshkov
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/rfkill.h>
+
+#include <mach/tosa_bt.h>
+
+static void tosa_bt_on(struct tosa_bt_data *data)
+{
+ gpio_set_value(data->gpio_reset, 0);
+ gpio_set_value(data->gpio_pwr, 1);
+ gpio_set_value(data->gpio_reset, 1);
+ mdelay(20);
+ gpio_set_value(data->gpio_reset, 0);
+}
+
+static void tosa_bt_off(struct tosa_bt_data *data)
+{
+ gpio_set_value(data->gpio_reset, 1);
+ mdelay(10);
+ gpio_set_value(data->gpio_pwr, 0);
+ gpio_set_value(data->gpio_reset, 0);
+}
+
+static int tosa_bt_set_block(void *data, bool blocked)
+{
+ pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");
+
+ if (!blocked) {
+ pr_info("TOSA_BT: going ON\n");
+ tosa_bt_on(data);
+ } else {
+ pr_info("TOSA_BT: going OFF\n");
+ tosa_bt_off(data);
+ }
+
+ return 0;
+}
+
+static const struct rfkill_ops tosa_bt_rfkill_ops = {
+ .set_block = tosa_bt_set_block,
+};
+
+static int tosa_bt_probe(struct platform_device *dev)
+{
+ int rc;
+ struct rfkill *rfk;
+
+ struct tosa_bt_data *data = dev->dev.platform_data;
+
+ rc = gpio_request(data->gpio_reset, "Bluetooth reset");
+ if (rc)
+ goto err_reset;
+ rc = gpio_direction_output(data->gpio_reset, 0);
+ if (rc)
+ goto err_reset_dir;
+ rc = gpio_request(data->gpio_pwr, "Bluetooth power");
+ if (rc)
+ goto err_pwr;
+ rc = gpio_direction_output(data->gpio_pwr, 0);
+ if (rc)
+ goto err_pwr_dir;
+
+ rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
+ &tosa_bt_rfkill_ops, data);
+ if (!rfk) {
+ rc = -ENOMEM;
+ goto err_rfk_alloc;
+ }
+
+ rc = rfkill_register(rfk);
+ if (rc)
+ goto err_rfkill;
+
+ platform_set_drvdata(dev, rfk);
+
+ return 0;
+
+err_rfkill:
+ rfkill_destroy(rfk);
+err_rfk_alloc:
+ tosa_bt_off(data);
+err_pwr_dir:
+ gpio_free(data->gpio_pwr);
+err_pwr:
+err_reset_dir:
+ gpio_free(data->gpio_reset);
+err_reset:
+ return rc;
+}
+
+static int __devexit tosa_bt_remove(struct platform_device *dev)
+{
+ struct tosa_bt_data *data = dev->dev.platform_data;
+ struct rfkill *rfk = platform_get_drvdata(dev);
+
+ platform_set_drvdata(dev, NULL);
+
+ if (rfk) {
+ rfkill_unregister(rfk);
+ rfkill_destroy(rfk);
+ }
+ rfk = NULL;
+
+ tosa_bt_off(data);
+
+ gpio_free(data->gpio_pwr);
+ gpio_free(data->gpio_reset);
+
+ return 0;
+}
+
+static struct platform_driver tosa_bt_driver = {
+ .probe = tosa_bt_probe,
+ .remove = __devexit_p(tosa_bt_remove),
+
+ .driver = {
+ .name = "tosa-bt",
+ .owner = THIS_MODULE,
+ },
+};
+
+
+static int __init tosa_bt_init(void)
+{
+ return platform_driver_register(&tosa_bt_driver);
+}
+
+static void __exit tosa_bt_exit(void)
+{
+ platform_driver_unregister(&tosa_bt_driver);
+}
+
+module_init(tosa_bt_init);
+module_exit(tosa_bt_exit);
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
new file mode 100644
index 00000000..5fa14577
--- /dev/null
+++ b/arch/arm/mach-pxa/tosa.c
@@ -0,0 +1,979 @@
+/*
+ * Support for Sharp SL-C6000x PDAs
+ * Model: (Tosa)
+ *
+ * Copyright (c) 2005 Dirk Opfer
+ *
+ * Based on code written by Sharp/Lineo for 2.4 kernels
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/mmc/host.h>
+#include <linux/mfd/tc6393xb.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/pm.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/pda_power.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/pxa25x.h>
+#include <mach/reset.h>
+#include <mach/irda.h>
+#include <mach/mmc.h>
+#include <mach/udc.h>
+#include <mach/tosa_bt.h>
+#include <mach/audio.h>
+#include <mach/smemc.h>
+
+#include <asm/mach/arch.h>
+#include <mach/tosa.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+
+#include "generic.h"
+#include "clock.h"
+#include "devices.h"
+
+static unsigned long tosa_pin_config[] = {
+ GPIO78_nCS_2, /* Scoop */
+ GPIO80_nCS_4, /* tg6393xb */
+ GPIO33_nCS_5, /* Scoop */
+
+ // GPIO76 CARD_VCC_ON1
+
+ GPIO19_GPIO, /* Reset out */
+ GPIO1_RST | WAKEUP_ON_EDGE_FALL,
+
+ GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* WAKE_UP */
+ GPIO2_GPIO | WAKEUP_ON_EDGE_BOTH, /* AC_IN */
+ GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* RECORD */
+ GPIO4_GPIO | WAKEUP_ON_EDGE_FALL, /* SYNC */
+ GPIO20_GPIO, /* EAR_IN */
+ GPIO22_GPIO, /* On */
+
+ GPIO5_GPIO, /* USB_IN */
+ GPIO32_GPIO, /* Pen IRQ */
+
+ GPIO7_GPIO, /* Jacket Detect */
+ GPIO14_GPIO, /* BAT0_CRG */
+ GPIO12_GPIO, /* BAT1_CRG */
+ GPIO17_GPIO, /* BAT0_LOW */
+ GPIO84_GPIO, /* BAT1_LOW */
+ GPIO38_GPIO, /* BAT_LOCK */
+
+ GPIO11_3_6MHz,
+ GPIO15_GPIO, /* TC6393XB IRQ */
+ GPIO18_RDY,
+ GPIO27_GPIO, /* LCD Sync */
+
+ /* MMC */
+ GPIO6_MMC_CLK,
+ GPIO8_MMC_CS0,
+ GPIO9_GPIO, /* Detect */
+ GPIO10_GPIO, /* nSD_INT */
+
+ /* CF */
+ GPIO13_GPIO, /* CD_IRQ */
+ GPIO21_GPIO, /* Main Slot IRQ */
+ GPIO36_GPIO, /* Jacket Slot IRQ */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+
+ /* AC97 */
+ GPIO31_AC97_SYNC,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ // GPIO79 nAUD_IRQ
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO35_FFUART_CTS,
+ GPIO37_FFUART_DSR,
+ GPIO39_FFUART_TXD,
+ GPIO40_FFUART_DTR,
+ GPIO41_FFUART_RTS,
+
+ /* BTUART */
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+
+ /* Keybd */
+ GPIO58_GPIO | MFP_LPM_DRIVE_LOW, /* Column 0 */
+ GPIO59_GPIO | MFP_LPM_DRIVE_LOW, /* Column 1 */
+ GPIO60_GPIO | MFP_LPM_DRIVE_LOW, /* Column 2 */
+ GPIO61_GPIO | MFP_LPM_DRIVE_LOW, /* Column 3 */
+ GPIO62_GPIO | MFP_LPM_DRIVE_LOW, /* Column 4 */
+ GPIO63_GPIO | MFP_LPM_DRIVE_LOW, /* Column 5 */
+ GPIO64_GPIO | MFP_LPM_DRIVE_LOW, /* Column 6 */
+ GPIO65_GPIO | MFP_LPM_DRIVE_LOW, /* Column 7 */
+ GPIO66_GPIO | MFP_LPM_DRIVE_LOW, /* Column 8 */
+ GPIO67_GPIO | MFP_LPM_DRIVE_LOW, /* Column 9 */
+ GPIO68_GPIO | MFP_LPM_DRIVE_LOW, /* Column 10 */
+ GPIO69_GPIO | MFP_LPM_DRIVE_LOW, /* Row 0 */
+ GPIO70_GPIO | MFP_LPM_DRIVE_LOW, /* Row 1 */
+ GPIO71_GPIO | MFP_LPM_DRIVE_LOW, /* Row 2 */
+ GPIO72_GPIO | MFP_LPM_DRIVE_LOW, /* Row 3 */
+ GPIO73_GPIO | MFP_LPM_DRIVE_LOW, /* Row 4 */
+ GPIO74_GPIO | MFP_LPM_DRIVE_LOW, /* Row 5 */
+ GPIO75_GPIO | MFP_LPM_DRIVE_LOW, /* Row 6 */
+
+ /* SPI */
+ GPIO81_SSP2_CLK_OUT,
+ GPIO82_SSP2_FRM_OUT,
+ GPIO83_SSP2_TXD,
+
+ /* IrDA is managed in other way */
+ GPIO46_GPIO,
+ GPIO47_GPIO,
+};
+
+/*
+ * SCOOP Device
+ */
+static struct resource tosa_scoop_resources[] = {
+ [0] = {
+ .start = TOSA_CF_PHYS,
+ .end = TOSA_CF_PHYS + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config tosa_scoop_setup = {
+ .io_dir = TOSA_SCOOP_IO_DIR,
+ .gpio_base = TOSA_SCOOP_GPIO_BASE,
+};
+
+static struct platform_device tosascoop_device = {
+ .name = "sharp-scoop",
+ .id = 0,
+ .dev = {
+ .platform_data = &tosa_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(tosa_scoop_resources),
+ .resource = tosa_scoop_resources,
+};
+
+
+/*
+ * SCOOP Device Jacket
+ */
+static struct resource tosa_scoop_jc_resources[] = {
+ [0] = {
+ .start = TOSA_SCOOP_PHYS + 0x40,
+ .end = TOSA_SCOOP_PHYS + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config tosa_scoop_jc_setup = {
+ .io_dir = TOSA_SCOOP_JC_IO_DIR,
+ .gpio_base = TOSA_SCOOP_JC_GPIO_BASE,
+};
+
+static struct platform_device tosascoop_jc_device = {
+ .name = "sharp-scoop",
+ .id = 1,
+ .dev = {
+ .platform_data = &tosa_scoop_jc_setup,
+ .parent = &tosascoop_device.dev,
+ },
+ .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources),
+ .resource = tosa_scoop_jc_resources,
+};
+
+/*
+ * PCMCIA
+ */
+static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = {
+{
+ .dev = &tosascoop_device.dev,
+ .irq = TOSA_IRQ_GPIO_CF_IRQ,
+ .cd_irq = TOSA_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+},{
+ .dev = &tosascoop_jc_device.dev,
+ .irq = TOSA_IRQ_GPIO_JC_CF_IRQ,
+ .cd_irq = -1,
+},
+};
+
+static struct scoop_pcmcia_config tosa_pcmcia_config = {
+ .devs = &tosa_pcmcia_scoop[0],
+ .num_devs = 2,
+};
+
+/*
+ * USB Device Controller
+ */
+static struct gpio_vbus_mach_info tosa_udc_info = {
+ .gpio_pullup = TOSA_GPIO_USB_PULLUP,
+ .gpio_vbus = TOSA_GPIO_USB_IN,
+ .gpio_vbus_inverted = 1,
+};
+
+static struct platform_device tosa_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosa_udc_info,
+ },
+};
+
+/*
+ * MMC/SD Device
+ */
+static int tosa_mci_init(struct device *dev, irq_handler_t tosa_detect_int, void *data)
+{
+ int err;
+
+ err = gpio_request(TOSA_GPIO_nSD_INT, "SD Int");
+ if (err) {
+ printk(KERN_ERR "tosa_mci_init: can't request SD_PWR gpio\n");
+ goto err_gpio_int;
+ }
+ err = gpio_direction_input(TOSA_GPIO_nSD_INT);
+ if (err)
+ goto err_gpio_int_dir;
+
+ return 0;
+
+err_gpio_int_dir:
+ gpio_free(TOSA_GPIO_nSD_INT);
+err_gpio_int:
+ return err;
+}
+
+static void tosa_mci_exit(struct device *dev, void *data)
+{
+ gpio_free(TOSA_GPIO_nSD_INT);
+}
+
+static struct pxamci_platform_data tosa_mci_platform_data = {
+ .detect_delay_ms = 250,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = tosa_mci_init,
+ .exit = tosa_mci_exit,
+ .gpio_card_detect = TOSA_GPIO_nSD_DETECT,
+ .gpio_card_ro = TOSA_GPIO_SD_WP,
+ .gpio_power = TOSA_GPIO_PWR_ON,
+};
+
+/*
+ * Irda
+ */
+static void tosa_irda_transceiver_mode(struct device *dev, int mode)
+{
+ if (mode & IR_OFF) {
+ gpio_set_value(TOSA_GPIO_IR_POWERDWN, 0);
+ pxa2xx_transceiver_mode(dev, mode);
+ gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+ } else {
+ pxa2xx_transceiver_mode(dev, mode);
+ gpio_set_value(TOSA_GPIO_IR_POWERDWN, 1);
+ }
+}
+
+static int tosa_irda_startup(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(TOSA_GPIO_IRDA_TX, "IrDA TX");
+ if (ret)
+ goto err_tx;
+ ret = gpio_direction_output(TOSA_GPIO_IRDA_TX, 0);
+ if (ret)
+ goto err_tx_dir;
+
+ ret = gpio_request(TOSA_GPIO_IR_POWERDWN, "IrDA powerdown");
+ if (ret)
+ goto err_pwr;
+
+ ret = gpio_direction_output(TOSA_GPIO_IR_POWERDWN, 0);
+ if (ret)
+ goto err_pwr_dir;
+
+ tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
+
+ return 0;
+
+err_pwr_dir:
+ gpio_free(TOSA_GPIO_IR_POWERDWN);
+err_pwr:
+err_tx_dir:
+ gpio_free(TOSA_GPIO_IRDA_TX);
+err_tx:
+ return ret;
+}
+
+static void tosa_irda_shutdown(struct device *dev)
+{
+ tosa_irda_transceiver_mode(dev, IR_SIRMODE | IR_OFF);
+ gpio_free(TOSA_GPIO_IR_POWERDWN);
+ gpio_free(TOSA_GPIO_IRDA_TX);
+}
+
+static struct pxaficp_platform_data tosa_ficp_platform_data = {
+ .gpio_pwdown = -1,
+ .transceiver_cap = IR_SIRMODE | IR_OFF,
+ .transceiver_mode = tosa_irda_transceiver_mode,
+ .startup = tosa_irda_startup,
+ .shutdown = tosa_irda_shutdown,
+};
+
+/*
+ * Tosa AC IN
+ */
+static int tosa_power_init(struct device *dev)
+{
+ int ret = gpio_request(TOSA_GPIO_AC_IN, "ac in");
+ if (ret)
+ goto err_gpio_req;
+
+ ret = gpio_direction_input(TOSA_GPIO_AC_IN);
+ if (ret)
+ goto err_gpio_in;
+
+ return 0;
+
+err_gpio_in:
+ gpio_free(TOSA_GPIO_AC_IN);
+err_gpio_req:
+ return ret;
+}
+
+static void tosa_power_exit(struct device *dev)
+{
+ gpio_free(TOSA_GPIO_AC_IN);
+}
+
+static int tosa_power_ac_online(void)
+{
+ return gpio_get_value(TOSA_GPIO_AC_IN) == 0;
+}
+
+static char *tosa_ac_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+ "jacket-battery",
+};
+
+static struct pda_power_pdata tosa_power_data = {
+ .init = tosa_power_init,
+ .is_ac_online = tosa_power_ac_online,
+ .exit = tosa_power_exit,
+ .supplied_to = tosa_ac_supplied_to,
+ .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to),
+};
+
+static struct resource tosa_power_resource[] = {
+ {
+ .name = "ac",
+ .start = gpio_to_irq(TOSA_GPIO_AC_IN),
+ .end = gpio_to_irq(TOSA_GPIO_AC_IN),
+ .flags = IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device tosa_power_device = {
+ .name = "pda-power",
+ .id = -1,
+ .dev.platform_data = &tosa_power_data,
+ .resource = tosa_power_resource,
+ .num_resources = ARRAY_SIZE(tosa_power_resource),
+};
+
+/*
+ * Tosa Keyboard
+ */
+static const uint32_t tosakbd_keymap[] = {
+ KEY(0, 2, KEY_W),
+ KEY(0, 6, KEY_K),
+ KEY(0, 7, KEY_BACKSPACE),
+ KEY(0, 8, KEY_P),
+ KEY(1, 1, KEY_Q),
+ KEY(1, 2, KEY_E),
+ KEY(1, 3, KEY_T),
+ KEY(1, 4, KEY_Y),
+ KEY(1, 6, KEY_O),
+ KEY(1, 7, KEY_I),
+ KEY(1, 8, KEY_COMMA),
+ KEY(2, 1, KEY_A),
+ KEY(2, 2, KEY_D),
+ KEY(2, 3, KEY_G),
+ KEY(2, 4, KEY_U),
+ KEY(2, 6, KEY_L),
+ KEY(2, 7, KEY_ENTER),
+ KEY(2, 8, KEY_DOT),
+ KEY(3, 1, KEY_Z),
+ KEY(3, 2, KEY_C),
+ KEY(3, 3, KEY_V),
+ KEY(3, 4, KEY_J),
+ KEY(3, 5, TOSA_KEY_ADDRESSBOOK),
+ KEY(3, 6, TOSA_KEY_CANCEL),
+ KEY(3, 7, TOSA_KEY_CENTER),
+ KEY(3, 8, TOSA_KEY_OK),
+ KEY(3, 9, KEY_LEFTSHIFT),
+ KEY(4, 1, KEY_S),
+ KEY(4, 2, KEY_R),
+ KEY(4, 3, KEY_B),
+ KEY(4, 4, KEY_N),
+ KEY(4, 5, TOSA_KEY_CALENDAR),
+ KEY(4, 6, TOSA_KEY_HOMEPAGE),
+ KEY(4, 7, KEY_LEFTCTRL),
+ KEY(4, 8, TOSA_KEY_LIGHT),
+ KEY(4, 10, KEY_RIGHTSHIFT),
+ KEY(5, 1, KEY_TAB),
+ KEY(5, 2, KEY_SLASH),
+ KEY(5, 3, KEY_H),
+ KEY(5, 4, KEY_M),
+ KEY(5, 5, TOSA_KEY_MENU),
+ KEY(5, 7, KEY_UP),
+ KEY(5, 11, TOSA_KEY_FN),
+ KEY(6, 1, KEY_X),
+ KEY(6, 2, KEY_F),
+ KEY(6, 3, KEY_SPACE),
+ KEY(6, 4, KEY_APOSTROPHE),
+ KEY(6, 5, TOSA_KEY_MAIL),
+ KEY(6, 6, KEY_LEFT),
+ KEY(6, 7, KEY_DOWN),
+ KEY(6, 8, KEY_RIGHT),
+};
+
+static struct matrix_keymap_data tosakbd_keymap_data = {
+ .keymap = tosakbd_keymap,
+ .keymap_size = ARRAY_SIZE(tosakbd_keymap),
+};
+
+static const int tosakbd_col_gpios[] =
+ { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68 };
+static const int tosakbd_row_gpios[] =
+ { 69, 70, 71, 72, 73, 74, 75 };
+
+static struct matrix_keypad_platform_data tosakbd_pdata = {
+ .keymap_data = &tosakbd_keymap_data,
+ .row_gpios = tosakbd_row_gpios,
+ .col_gpios = tosakbd_col_gpios,
+ .num_row_gpios = ARRAY_SIZE(tosakbd_row_gpios),
+ .num_col_gpios = ARRAY_SIZE(tosakbd_col_gpios),
+ .col_scan_delay_us = 10,
+ .debounce_ms = 10,
+ .wakeup = 1,
+};
+
+static struct platform_device tosakbd_device = {
+ .name = "matrix-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosakbd_pdata,
+ },
+};
+
+static struct gpio_keys_button tosa_gpio_keys[] = {
+ /*
+ * Two following keys are directly tied to "ON" button of tosa. Why?
+ * The first one can be used as a wakeup source, the second can't;
+ * also the first one is OR of ac_powered and on_button.
+ */
+ {
+ .type = EV_PWR,
+ .code = KEY_RESERVED,
+ .gpio = TOSA_GPIO_POWERON,
+ .desc = "Poweron",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ {
+ .type = EV_PWR,
+ .code = KEY_SUSPEND,
+ .gpio = TOSA_GPIO_ON_KEY,
+ .desc = "On key",
+ /*
+ * can't be used as wakeup
+ * .wakeup = 1,
+ */
+ .active_low = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = TOSA_KEY_RECORD,
+ .gpio = TOSA_GPIO_RECORD_BTN,
+ .desc = "Record Button",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ {
+ .type = EV_KEY,
+ .code = TOSA_KEY_SYNC,
+ .gpio = TOSA_GPIO_SYNC,
+ .desc = "Sync Button",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ {
+ .type = EV_SW,
+ .code = SW_HEADPHONE_INSERT,
+ .gpio = TOSA_GPIO_EAR_IN,
+ .desc = "HeadPhone insert",
+ .active_low = 1,
+ .debounce_interval = 300,
+ },
+};
+
+static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
+ .buttons = tosa_gpio_keys,
+ .nbuttons = ARRAY_SIZE(tosa_gpio_keys),
+};
+
+static struct platform_device tosa_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosa_gpio_keys_platform_data,
+ },
+};
+
+/*
+ * Tosa LEDs
+ */
+static struct gpio_led tosa_gpio_leds[] = {
+ {
+ .name = "tosa:amber:charge",
+ .default_trigger = "main-battery-charging",
+ .gpio = TOSA_GPIO_CHRG_ERR_LED,
+ },
+ {
+ .name = "tosa:green:mail",
+ .default_trigger = "nand-disk",
+ .gpio = TOSA_GPIO_NOTE_LED,
+ },
+ {
+ .name = "tosa:dual:wlan",
+ .default_trigger = "none",
+ .gpio = TOSA_GPIO_WLAN_LED,
+ },
+ {
+ .name = "tosa:blue:bluetooth",
+ .default_trigger = "tosa-bt",
+ .gpio = TOSA_GPIO_BT_LED,
+ },
+};
+
+static struct gpio_led_platform_data tosa_gpio_leds_platform_data = {
+ .leds = tosa_gpio_leds,
+ .num_leds = ARRAY_SIZE(tosa_gpio_leds),
+};
+
+static struct platform_device tosaled_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosa_gpio_leds_platform_data,
+ },
+};
+
+/*
+ * Toshiba Mobile IO Controller
+ */
+static struct resource tc6393xb_resources[] = {
+ [0] = {
+ .start = TOSA_LCDC_PHYS,
+ .end = TOSA_LCDC_PHYS + 0x3ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+
+ [1] = {
+ .start = TOSA_IRQ_GPIO_TC6393XB_INT,
+ .end = TOSA_IRQ_GPIO_TC6393XB_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static int tosa_tc6393xb_enable(struct platform_device *dev)
+{
+ int rc;
+
+ rc = gpio_request(TOSA_GPIO_TC6393XB_REST_IN, "tc6393xb #pclr");
+ if (rc)
+ goto err_req_pclr;
+ rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
+ if (rc)
+ goto err_req_suspend;
+ rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v");
+ if (rc)
+ goto err_req_l3v;
+ rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
+ if (rc)
+ goto err_dir_l3v;
+ rc = gpio_direction_output(TOSA_GPIO_TC6393XB_SUSPEND, 0);
+ if (rc)
+ goto err_dir_suspend;
+ rc = gpio_direction_output(TOSA_GPIO_TC6393XB_REST_IN, 0);
+ if (rc)
+ goto err_dir_pclr;
+
+ mdelay(1);
+
+ gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
+
+ mdelay(10);
+
+ gpio_set_value(TOSA_GPIO_TC6393XB_REST_IN, 1);
+ gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
+
+ return 0;
+err_dir_pclr:
+err_dir_suspend:
+err_dir_l3v:
+ gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
+err_req_l3v:
+ gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
+err_req_suspend:
+ gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
+err_req_pclr:
+ return rc;
+}
+
+static int tosa_tc6393xb_disable(struct platform_device *dev)
+{
+ gpio_free(TOSA_GPIO_TC6393XB_L3V_ON);
+ gpio_free(TOSA_GPIO_TC6393XB_SUSPEND);
+ gpio_free(TOSA_GPIO_TC6393XB_REST_IN);
+
+ return 0;
+}
+
+static int tosa_tc6393xb_resume(struct platform_device *dev)
+{
+ gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 1);
+ mdelay(10);
+ gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 1);
+ mdelay(10);
+
+ return 0;
+}
+
+static int tosa_tc6393xb_suspend(struct platform_device *dev)
+{
+ gpio_set_value(TOSA_GPIO_TC6393XB_L3V_ON, 0);
+ gpio_set_value(TOSA_GPIO_TC6393XB_SUSPEND, 0);
+ return 0;
+}
+
+static struct mtd_partition tosa_nand_partition[] = {
+ {
+ .name = "smf",
+ .offset = 0,
+ .size = 7 * 1024 * 1024,
+ },
+ {
+ .name = "root",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 28 * 1024 * 1024,
+ },
+ {
+ .name = "home",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = {
+ .options = 0,
+ .offs = 4,
+ .len = 2,
+ .pattern = scan_ff_pattern
+};
+
+static struct tmio_nand_data tosa_tc6393xb_nand_config = {
+ .num_partitions = ARRAY_SIZE(tosa_nand_partition),
+ .partition = tosa_nand_partition,
+ .badblock_pattern = &tosa_tc6393xb_nand_bbt,
+};
+
+static int tosa_tc6393xb_setup(struct platform_device *dev)
+{
+ int rc;
+
+ rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
+ if (rc)
+ goto err_req;
+
+ rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
+ if (rc)
+ goto err_dir;
+
+ return rc;
+
+err_dir:
+ gpio_free(TOSA_GPIO_CARD_VCC_ON);
+err_req:
+ return rc;
+}
+
+static void tosa_tc6393xb_teardown(struct platform_device *dev)
+{
+ gpio_free(TOSA_GPIO_CARD_VCC_ON);
+}
+
+#ifdef CONFIG_MFD_TC6393XB
+static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
+ {
+ .xres = 480,
+ .yres = 640,
+ .pixclock = 0x002cdf00,/* PLL divisor */
+ .left_margin = 0x004c,
+ .right_margin = 0x005b,
+ .upper_margin = 0x0001,
+ .lower_margin = 0x000d,
+ .hsync_len = 0x0002,
+ .vsync_len = 0x0001,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },{
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 0x00e7f203,/* PLL divisor */
+ .left_margin = 0x0024,
+ .right_margin = 0x002f,
+ .upper_margin = 0x0001,
+ .lower_margin = 0x000d,
+ .hsync_len = 0x0002,
+ .vsync_len = 0x0001,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ }
+};
+
+static struct tmio_fb_data tosa_tc6393xb_fb_config = {
+ .lcd_set_power = tc6393xb_lcd_set_power,
+ .lcd_mode = tc6393xb_lcd_mode,
+ .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode),
+ .modes = &tosa_tc6393xb_lcd_mode[0],
+ .height = 82,
+ .width = 60,
+};
+#endif
+
+static struct tc6393xb_platform_data tosa_tc6393xb_data = {
+ .scr_pll2cr = 0x0cc1,
+ .scr_gper = 0x3300,
+
+ .irq_base = IRQ_BOARD_START,
+ .gpio_base = TOSA_TC6393XB_GPIO_BASE,
+ .setup = tosa_tc6393xb_setup,
+ .teardown = tosa_tc6393xb_teardown,
+
+ .enable = tosa_tc6393xb_enable,
+ .disable = tosa_tc6393xb_disable,
+ .suspend = tosa_tc6393xb_suspend,
+ .resume = tosa_tc6393xb_resume,
+
+ .nand_data = &tosa_tc6393xb_nand_config,
+#ifdef CONFIG_MFD_TC6393XB
+ .fb_data = &tosa_tc6393xb_fb_config,
+#endif
+
+ .resume_restore = 1,
+};
+
+
+static struct platform_device tc6393xb_device = {
+ .name = "tc6393xb",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosa_tc6393xb_data,
+ },
+ .num_resources = ARRAY_SIZE(tc6393xb_resources),
+ .resource = tc6393xb_resources,
+};
+
+static struct tosa_bt_data tosa_bt_data = {
+ .gpio_pwr = TOSA_GPIO_BT_PWR_EN,
+ .gpio_reset = TOSA_GPIO_BT_RESET,
+};
+
+static struct platform_device tosa_bt_device = {
+ .name = "tosa-bt",
+ .id = -1,
+ .dev.platform_data = &tosa_bt_data,
+};
+
+static struct pxa2xx_spi_master pxa_ssp_master_info = {
+ .num_chipselect = 1,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "tosa-lcd",
+ // .platform_data
+ .max_speed_hz = 28750,
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+};
+
+static struct mtd_partition sharpsl_rom_parts[] = {
+ {
+ .name ="Boot PROM Filesystem",
+ .offset = 0x00160000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data sharpsl_rom_data = {
+ .width = 2,
+ .nr_parts = ARRAY_SIZE(sharpsl_rom_parts),
+ .parts = sharpsl_rom_parts,
+};
+
+static struct resource sharpsl_rom_resources[] = {
+ {
+ .start = 0x00000000,
+ .end = 0x007fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device sharpsl_rom_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = sharpsl_rom_resources,
+ .num_resources = ARRAY_SIZE(sharpsl_rom_resources),
+ .dev.platform_data = &sharpsl_rom_data,
+};
+
+static struct platform_device wm9712_device = {
+ .name = "wm9712-codec",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &tosascoop_device,
+ &tosascoop_jc_device,
+ &tc6393xb_device,
+ &tosa_power_device,
+ &tosakbd_device,
+ &tosa_gpio_keys_device,
+ &tosaled_device,
+ &tosa_bt_device,
+ &sharpsl_rom_device,
+ &wm9712_device,
+ &tosa_gpio_vbus,
+};
+
+static void tosa_poweroff(void)
+{
+ arm_machine_restart('g', NULL);
+}
+
+static void tosa_restart(char mode, const char *cmd)
+{
+ uint32_t msc0 = __raw_readl(MSC0);
+
+ /* Bootloader magic for a reboot */
+ if((msc0 & 0xffff0000) == 0x7ff00000)
+ __raw_writel((msc0 & 0xffff) | 0x7ee00000, MSC0);
+
+ tosa_poweroff();
+}
+
+static void __init tosa_init(void)
+{
+ int dummy;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(tosa_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ gpio_set_wake(MFP_PIN_GPIO1, 1);
+ /* We can't pass to gpio-keys since it will drop the Reset altfunc */
+
+ init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0);
+
+ pm_power_off = tosa_poweroff;
+ arm_pm_restart = tosa_restart;
+
+ PCFR |= PCFR_OPDE;
+
+ /* enable batt_fault */
+ PMCR = 0x01;
+
+ dummy = gpiochip_reserve(TOSA_SCOOP_GPIO_BASE, 12);
+ dummy = gpiochip_reserve(TOSA_SCOOP_JC_GPIO_BASE, 12);
+ dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
+
+ pxa_set_mci_info(&tosa_mci_platform_data);
+ pxa_set_ficp_info(&tosa_ficp_platform_data);
+ pxa_set_i2c_info(NULL);
+ pxa_set_ac97_info(NULL);
+ platform_scoop_config = &tosa_pcmcia_config;
+
+ pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init fixup_tosa(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ sharpsl_save_param();
+ mi->nr_banks=1;
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].size = (64*1024*1024);
+}
+
+MACHINE_START(TOSA, "SHARP Tosa")
+ .fixup = fixup_tosa,
+ .map_io = pxa25x_map_io,
+ .nr_irqs = TOSA_NR_IRQS,
+ .init_irq = pxa25x_init_irq,
+ .init_machine = tosa_init,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
new file mode 100644
index 00000000..687417a9
--- /dev/null
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -0,0 +1,571 @@
+/*
+ * linux/arch/arm/mach-pxa/trizeps4.c
+ *
+ * Support for the Keith und Koep Trizeps4 Module Platform.
+ *
+ * Author: Jürgen Schindele
+ * Created: 20 02, 2006
+ * Copyright: Jürgen Schindele
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/bitops.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/pxa27x.h>
+#include <mach/trizeps4.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <mach/irda.h>
+#include <mach/ohci.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/* comment out the following line if you want to use the
+ * Standard UART from PXA for serial / irda transmission
+ * and acivate it if you have status leds connected */
+#define STATUS_LEDS_ON_STUART_PINS 1
+
+/*****************************************************************************
+ * MultiFunctionPins of CPU
+ *****************************************************************************/
+static unsigned long trizeps4_pin_config[] __initdata = {
+ /* Chip Selects */
+ GPIO15_nCS_1, /* DiskOnChip CS */
+ GPIO93_GPIO, /* TRIZEPS4_DOC_IRQ */
+ GPIO94_GPIO, /* DOC lock */
+
+ GPIO78_nCS_2, /* DM9000 CS */
+ GPIO101_GPIO, /* TRIZEPS4_ETH_IRQ */
+
+ GPIO79_nCS_3, /* Logic CS */
+ GPIO0_GPIO | WAKEUP_ON_EDGE_RISE, /* Logic irq */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* LCD - 16bpp Active TFT */
+ GPIOxx_LCD_TFT_16BPP,
+
+ /* UART */
+ GPIO9_FFUART_CTS,
+ GPIO10_FFUART_DCD,
+ GPIO16_FFUART_TXD,
+ GPIO33_FFUART_DSR,
+ GPIO38_FFUART_RI,
+ GPIO82_FFUART_DTR,
+ GPIO83_FFUART_RTS,
+ GPIO96_FFUART_RXD,
+
+ GPIO42_BTUART_RXD,
+ GPIO43_BTUART_TXD,
+ GPIO44_BTUART_CTS,
+ GPIO45_BTUART_RTS,
+#ifdef STATUS_LEDS_ON_STUART_PINS
+ GPIO46_GPIO,
+ GPIO47_GPIO,
+#else
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+#endif
+ /* PCMCIA */
+ GPIO11_GPIO, /* TRIZEPS4_CD_IRQ */
+ GPIO13_GPIO, /* TRIZEPS4_READY_NINT */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO102_nPCE_1,
+ GPIO104_PSKTSEL,
+
+ /* MultiMediaCard */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO12_GPIO, /* TRIZEPS4_MMC_IRQ */
+
+ /* USB OHCI */
+ GPIO88_USBH1_PWR, /* USBHPWR1 */
+ GPIO89_USBH1_PEN, /* USBHPEN1 */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+};
+
+static unsigned long trizeps4wl_pin_config[] __initdata = {
+ /* SSP 2 */
+ GPIO14_SSP2_SFRM,
+ GPIO19_SSP2_SCLK,
+ GPIO53_GPIO, /* TRIZEPS4_SPI_IRQ */
+ GPIO86_SSP2_RXD,
+ GPIO87_SSP2_TXD,
+};
+
+/****************************************************************************
+ * ONBOARD FLASH
+ ****************************************************************************/
+static struct mtd_partition trizeps4_partitions[] = {
+ {
+ .name = "Bootloader",
+ .offset = 0x00000000,
+ .size = 0x00040000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ }, {
+ .name = "Backup",
+ .offset = 0x00040000,
+ .size = 0x00040000,
+ }, {
+ .name = "Image",
+ .offset = 0x00080000,
+ .size = 0x01080000,
+ }, {
+ .name = "IPSM",
+ .offset = 0x01100000,
+ .size = 0x00e00000,
+ }, {
+ .name = "Registry",
+ .offset = 0x01f00000,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data trizeps4_flash_data[] = {
+ {
+ .width = 4, /* bankwidth in bytes */
+ .parts = trizeps4_partitions,
+ .nr_parts = ARRAY_SIZE(trizeps4_partitions)
+ }
+};
+
+static struct resource flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = trizeps4_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+/****************************************************************************
+ * DAVICOM DM9000 Ethernet
+ ****************************************************************************/
+static struct resource dm9000_resources[] = {
+ [0] = {
+ .start = TRIZEPS4_ETH_PHYS+0x300,
+ .end = TRIZEPS4_ETH_PHYS+0x400-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = TRIZEPS4_ETH_PHYS+0x8300,
+ .end = TRIZEPS4_ETH_PHYS+0x8400-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = TRIZEPS4_ETH_IRQ,
+ .end = TRIZEPS4_ETH_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct dm9000_plat_data tri_dm9000_platdata = {
+ .flags = DM9000_PLATF_32BITONLY,
+};
+
+static struct platform_device dm9000_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm9000_resources),
+ .resource = dm9000_resources,
+ .dev = {
+ .platform_data = &tri_dm9000_platdata,
+ }
+};
+
+/****************************************************************************
+ * LED's on GPIO pins of PXA
+ ****************************************************************************/
+static struct gpio_led trizeps4_led[] = {
+#ifdef STATUS_LEDS_ON_STUART_PINS
+ {
+ .name = "led0:orange:heartbeat", /* */
+ .default_trigger = "heartbeat",
+ .gpio = GPIO_HEARTBEAT_LED,
+ .active_low = 1,
+ },
+ {
+ .name = "led1:yellow:cpubusy", /* */
+ .default_trigger = "cpu-busy",
+ .gpio = GPIO_SYS_BUSY_LED,
+ .active_low = 1,
+ },
+#endif
+};
+
+static struct gpio_led_platform_data trizeps4_led_data = {
+ .leds = trizeps4_led,
+ .num_leds = ARRAY_SIZE(trizeps4_led),
+};
+
+static struct platform_device leds_devices = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &trizeps4_led_data,
+ },
+};
+
+static struct platform_device *trizeps4_devices[] __initdata = {
+ &flash_device,
+ &dm9000_device,
+ &leds_devices,
+};
+
+static struct platform_device *trizeps4wl_devices[] __initdata = {
+ &flash_device,
+ &leds_devices,
+};
+
+static short trizeps_conxs_bcr;
+
+/* PCCARD power switching supports only 3,3V */
+void board_pcmcia_power(int power)
+{
+ if (power) {
+ /* switch power on, put in reset and enable buffers */
+ trizeps_conxs_bcr |= power;
+ trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
+ trizeps_conxs_bcr &= ~ConXS_BCR_CF_BUF_EN;
+ BCR_writew(trizeps_conxs_bcr);
+ /* wait a little */
+ udelay(2000);
+ /* take reset away */
+ trizeps_conxs_bcr &= ~ConXS_BCR_CF_RESET;
+ BCR_writew(trizeps_conxs_bcr);
+ udelay(2000);
+ } else {
+ /* put in reset */
+ trizeps_conxs_bcr |= ConXS_BCR_CF_RESET;
+ BCR_writew(trizeps_conxs_bcr);
+ udelay(1000);
+ /* switch power off */
+ trizeps_conxs_bcr &= ~0xf;
+ BCR_writew(trizeps_conxs_bcr);
+ }
+ pr_debug("%s: o%s 0x%x\n", __func__, power ? "n" : "ff",
+ trizeps_conxs_bcr);
+}
+EXPORT_SYMBOL(board_pcmcia_power);
+
+/* backlight power switching for LCD panel */
+static void board_backlight_power(int on)
+{
+ if (on)
+ trizeps_conxs_bcr |= ConXS_BCR_L_DISP;
+ else
+ trizeps_conxs_bcr &= ~ConXS_BCR_L_DISP;
+
+ pr_debug("%s: o%s 0x%x\n", __func__, on ? "n" : "ff",
+ trizeps_conxs_bcr);
+ BCR_writew(trizeps_conxs_bcr);
+}
+
+/* a I2C based RTC is known on CONXS board */
+static struct i2c_board_info trizeps4_i2c_devices[] __initdata = {
+ { I2C_BOARD_INFO("rtc-pcf8593", 0x51) }
+};
+
+/****************************************************************************
+ * MMC card slot external to module
+ ****************************************************************************/
+static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int,
+ void *data)
+{
+ int err;
+
+ err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request"
+ "MMC card detect IRQ\n");
+ return -1;
+ }
+ return 0;
+}
+
+static void trizeps4_mci_exit(struct device *dev, void *data)
+{
+ free_irq(TRIZEPS4_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data trizeps4_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .detect_delay_ms= 10,
+ .init = trizeps4_mci_init,
+ .exit = trizeps4_mci_exit,
+ .get_ro = NULL, /* write-protection not supported */
+ .setpower = NULL, /* power-switching not supported */
+ .gpio_card_detect = -1,
+ .gpio_card_ro = -1,
+ .gpio_power = -1,
+};
+
+/****************************************************************************
+ * IRDA mode switching on stuart
+ ****************************************************************************/
+#ifndef STATUS_LEDS_ON_STUART_PINS
+static short trizeps_conxs_ircr;
+
+static int trizeps4_irda_startup(struct device *dev)
+{
+ trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
+ IRCR_writew(trizeps_conxs_ircr);
+ return 0;
+}
+
+static void trizeps4_irda_shutdown(struct device *dev)
+{
+ trizeps_conxs_ircr |= ConXS_IRCR_SD;
+ IRCR_writew(trizeps_conxs_ircr);
+}
+
+static void trizeps4_irda_transceiver_mode(struct device *dev, int mode)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ /* Switch mode */
+ if (mode & IR_SIRMODE)
+ trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; /* Slow mode */
+ else if (mode & IR_FIRMODE)
+ trizeps_conxs_ircr |= ConXS_IRCR_MODE; /* Fast mode */
+
+ /* Switch power */
+ if (mode & IR_OFF)
+ trizeps_conxs_ircr |= ConXS_IRCR_SD;
+ else
+ trizeps_conxs_ircr &= ~ConXS_IRCR_SD;
+
+ IRCR_writew(trizeps_conxs_ircr);
+ local_irq_restore(flags);
+
+ pxa2xx_transceiver_mode(dev, mode);
+}
+
+static struct pxaficp_platform_data trizeps4_ficp_platform_data = {
+ .gpio_pwdown = -1,
+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE | IR_OFF,
+ .transceiver_mode = trizeps4_irda_transceiver_mode,
+ .startup = trizeps4_irda_startup,
+ .shutdown = trizeps4_irda_shutdown,
+};
+#endif
+
+/****************************************************************************
+ * OHCI USB port
+ ****************************************************************************/
+static struct pxaohci_platform_data trizeps4_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static struct map_desc trizeps4_io_desc[] __initdata = {
+ { /* ConXS CFSR */
+ .virtual = TRIZEPS4_CFSR_VIRT,
+ .pfn = __phys_to_pfn(TRIZEPS4_CFSR_PHYS),
+ .length = 0x00001000,
+ .type = MT_DEVICE
+ },
+ { /* ConXS BCR */
+ .virtual = TRIZEPS4_BOCR_VIRT,
+ .pfn = __phys_to_pfn(TRIZEPS4_BOCR_PHYS),
+ .length = 0x00001000,
+ .type = MT_DEVICE
+ },
+ { /* ConXS IRCR */
+ .virtual = TRIZEPS4_IRCR_VIRT,
+ .pfn = __phys_to_pfn(TRIZEPS4_IRCR_PHYS),
+ .length = 0x00001000,
+ .type = MT_DEVICE
+ },
+ { /* ConXS DCR */
+ .virtual = TRIZEPS4_DICR_VIRT,
+ .pfn = __phys_to_pfn(TRIZEPS4_DICR_PHYS),
+ .length = 0x00001000,
+ .type = MT_DEVICE
+ },
+ { /* ConXS UPSR */
+ .virtual = TRIZEPS4_UPSR_VIRT,
+ .pfn = __phys_to_pfn(TRIZEPS4_UPSR_PHYS),
+ .length = 0x00001000,
+ .type = MT_DEVICE
+ }
+};
+
+static struct pxafb_mode_info sharp_lcd_mode = {
+ .pixclock = 78000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 8,
+ .hsync_len = 4,
+ .left_margin = 4,
+ .right_margin = 4,
+ .vsync_len = 2,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info sharp_lcd = {
+ .modes = &sharp_lcd_mode,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_DSTN_16BPP | LCD_PCLK_EDGE_FALL,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .pxafb_backlight_power = board_backlight_power,
+};
+
+static struct pxafb_mode_info toshiba_lcd_mode = {
+ .pixclock = 39720,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 8,
+ .hsync_len = 63,
+ .left_margin = 12,
+ .right_margin = 12,
+ .vsync_len = 4,
+ .upper_margin = 32,
+ .lower_margin = 10,
+ .sync = 0,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info toshiba_lcd = {
+ .modes = &toshiba_lcd_mode,
+ .num_modes = 1,
+ .lcd_conn = (LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL),
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .pxafb_backlight_power = board_backlight_power,
+};
+
+static void __init trizeps4_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4_pin_config));
+ if (machine_is_trizeps4wl()) {
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(trizeps4wl_pin_config));
+ platform_add_devices(trizeps4wl_devices,
+ ARRAY_SIZE(trizeps4wl_devices));
+ } else {
+ platform_add_devices(trizeps4_devices,
+ ARRAY_SIZE(trizeps4_devices));
+ }
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ if (0) /* dont know how to determine LCD */
+ pxa_set_fb_info(NULL, &sharp_lcd);
+ else
+ pxa_set_fb_info(NULL, &toshiba_lcd);
+
+ pxa_set_mci_info(&trizeps4_mci_platform_data);
+#ifndef STATUS_LEDS_ON_STUART_PINS
+ pxa_set_ficp_info(&trizeps4_ficp_platform_data);
+#endif
+ pxa_set_ohci_info(&trizeps4_ohci_platform_data);
+ pxa_set_ac97_info(NULL);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, trizeps4_i2c_devices,
+ ARRAY_SIZE(trizeps4_i2c_devices));
+
+ /* this is the reset value */
+ trizeps_conxs_bcr = 0x00A0;
+
+ BCR_writew(trizeps_conxs_bcr);
+ board_backlight_power(1);
+}
+
+static void __init trizeps4_map_io(void)
+{
+ pxa27x_map_io();
+ iotable_init(trizeps4_io_desc, ARRAY_SIZE(trizeps4_io_desc));
+
+ if ((__raw_readl(MSC0) & 0x8) && (__raw_readl(BOOT_DEF) & 0x1)) {
+ /* if flash is 16 bit wide its a Trizeps4 WL */
+ __machine_arch_type = MACH_TYPE_TRIZEPS4WL;
+ trizeps4_flash_data[0].width = 2;
+ } else {
+ /* if flash is 32 bit wide its a Trizeps4 */
+ __machine_arch_type = MACH_TYPE_TRIZEPS4;
+ trizeps4_flash_data[0].width = 4;
+ }
+}
+
+MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
+ /* MAINTAINER("Jürgen Schindele") */
+ .boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
+ .init_machine = trizeps4_init,
+ .map_io = trizeps4_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
+MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module")
+ /* MAINTAINER("Jürgen Schindele") */
+ .boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
+ .init_machine = trizeps4_init,
+ .map_io = trizeps4_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
new file mode 100644
index 00000000..903218ea
--- /dev/null
+++ b/arch/arm/mach-pxa/viper.c
@@ -0,0 +1,1000 @@
+/*
+ * linux/arch/arm/mach-pxa/viper.c
+ *
+ * Support for the Arcom VIPER SBC.
+ *
+ * Author: Ian Campbell
+ * Created: Feb 03, 2003
+ * Copyright: Arcom Control Systems
+ *
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ * <marc.zyngier@altran.com>
+ *
+ * Based on lubbock.c:
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/types.h>
+#include <linux/memory.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/major.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+#include <linux/jiffies.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/serial_8250.h>
+#include <linux/smc91x.h>
+#include <linux/pwm_backlight.h>
+#include <linux/usb/isp116x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/pxa25x.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/regs-uart.h>
+#include <mach/arcom-pcmcia.h>
+#include <mach/viper.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+#include "devices.h"
+
+static unsigned int icr;
+
+static void viper_icr_set_bit(unsigned int bit)
+{
+ icr |= bit;
+ VIPER_ICR = icr;
+}
+
+static void viper_icr_clear_bit(unsigned int bit)
+{
+ icr &= ~bit;
+ VIPER_ICR = icr;
+}
+
+/* This function is used from the pcmcia module to reset the CF */
+static void viper_cf_reset(int state)
+{
+ if (state)
+ viper_icr_set_bit(VIPER_ICR_CF_RST);
+ else
+ viper_icr_clear_bit(VIPER_ICR_CF_RST);
+}
+
+static struct arcom_pcmcia_pdata viper_pcmcia_info = {
+ .cd_gpio = VIPER_CF_CD_GPIO,
+ .rdy_gpio = VIPER_CF_RDY_GPIO,
+ .pwr_gpio = VIPER_CF_POWER_GPIO,
+ .reset = viper_cf_reset,
+};
+
+static struct platform_device viper_pcmcia_device = {
+ .name = "viper-pcmcia",
+ .id = -1,
+ .dev = {
+ .platform_data = &viper_pcmcia_info,
+ },
+};
+
+/*
+ * The CPLD version register was not present on VIPER boards prior to
+ * v2i1. On v1 boards where the version register is not present we
+ * will just read back the previous value from the databus.
+ *
+ * Therefore we do two reads. The first time we write 0 to the
+ * (read-only) register before reading and the second time we write
+ * 0xff first. If the two reads do not match or they read back as 0xff
+ * or 0x00 then we have version 1 hardware.
+ */
+static u8 viper_hw_version(void)
+{
+ u8 v1, v2;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ VIPER_VERSION = 0;
+ v1 = VIPER_VERSION;
+ VIPER_VERSION = 0xff;
+ v2 = VIPER_VERSION;
+
+ v1 = (v1 != v2 || v1 == 0xff) ? 0 : v1;
+
+ local_irq_restore(flags);
+ return v1;
+}
+
+/* CPU system core operations. */
+static int viper_cpu_suspend(void)
+{
+ viper_icr_set_bit(VIPER_ICR_R_DIS);
+ return 0;
+}
+
+static void viper_cpu_resume(void)
+{
+ viper_icr_clear_bit(VIPER_ICR_R_DIS);
+}
+
+static struct syscore_ops viper_cpu_syscore_ops = {
+ .suspend = viper_cpu_suspend,
+ .resume = viper_cpu_resume,
+};
+
+static unsigned int current_voltage_divisor;
+
+/*
+ * If force is not true then step from existing to new divisor. If
+ * force is true then jump straight to the new divisor. Stepping is
+ * used because if the jump in voltage is too large, the VCC can dip
+ * too low and the regulator cuts out.
+ *
+ * force can be used to initialize the divisor to a know state by
+ * setting the value for the current clock speed, since we are already
+ * running at that speed we know the voltage should be pretty close so
+ * the jump won't be too large
+ */
+static void viper_set_core_cpu_voltage(unsigned long khz, int force)
+{
+ int i = 0;
+ unsigned int divisor = 0;
+ const char *v;
+
+ if (khz < 200000) {
+ v = "1.0"; divisor = 0xfff;
+ } else if (khz < 300000) {
+ v = "1.1"; divisor = 0xde5;
+ } else {
+ v = "1.3"; divisor = 0x325;
+ }
+
+ pr_debug("viper: setting CPU core voltage to %sV at %d.%03dMHz\n",
+ v, (int)khz / 1000, (int)khz % 1000);
+
+#define STEP 0x100
+ do {
+ int step;
+
+ if (force)
+ step = divisor;
+ else if (current_voltage_divisor < divisor - STEP)
+ step = current_voltage_divisor + STEP;
+ else if (current_voltage_divisor > divisor + STEP)
+ step = current_voltage_divisor - STEP;
+ else
+ step = divisor;
+ force = 0;
+
+ gpio_set_value(VIPER_PSU_CLK_GPIO, 0);
+ gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0);
+
+ for (i = 1 << 11 ; i > 0 ; i >>= 1) {
+ udelay(1);
+
+ gpio_set_value(VIPER_PSU_DATA_GPIO, step & i);
+ udelay(1);
+
+ gpio_set_value(VIPER_PSU_CLK_GPIO, 1);
+ udelay(1);
+
+ gpio_set_value(VIPER_PSU_CLK_GPIO, 0);
+ }
+ udelay(1);
+
+ gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 1);
+ udelay(1);
+
+ gpio_set_value(VIPER_PSU_nCS_LD_GPIO, 0);
+
+ current_voltage_divisor = step;
+ } while (current_voltage_divisor != divisor);
+}
+
+/* Interrupt handling */
+static unsigned long viper_irq_enabled_mask;
+static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
+static const int viper_isa_irq_map[] = {
+ 0, /* ISA irq #0, invalid */
+ 0, /* ISA irq #1, invalid */
+ 0, /* ISA irq #2, invalid */
+ 1 << 0, /* ISA irq #3 */
+ 1 << 1, /* ISA irq #4 */
+ 1 << 2, /* ISA irq #5 */
+ 1 << 3, /* ISA irq #6 */
+ 1 << 4, /* ISA irq #7 */
+ 0, /* ISA irq #8, invalid */
+ 1 << 8, /* ISA irq #9 */
+ 1 << 5, /* ISA irq #10 */
+ 1 << 6, /* ISA irq #11 */
+ 1 << 7, /* ISA irq #12 */
+ 0, /* ISA irq #13, invalid */
+ 1 << 9, /* ISA irq #14 */
+ 1 << 10, /* ISA irq #15 */
+};
+
+static inline int viper_irq_to_bitmask(unsigned int irq)
+{
+ return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)];
+}
+
+static inline int viper_bit_to_irq(int bit)
+{
+ return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
+}
+
+static void viper_ack_irq(struct irq_data *d)
+{
+ int viper_irq = viper_irq_to_bitmask(d->irq);
+
+ if (viper_irq & 0xff)
+ VIPER_LO_IRQ_STATUS = viper_irq;
+ else
+ VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
+}
+
+static void viper_mask_irq(struct irq_data *d)
+{
+ viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(d->irq));
+}
+
+static void viper_unmask_irq(struct irq_data *d)
+{
+ viper_irq_enabled_mask |= viper_irq_to_bitmask(d->irq);
+}
+
+static inline unsigned long viper_irq_pending(void)
+{
+ return (VIPER_HI_IRQ_STATUS << 8 | VIPER_LO_IRQ_STATUS) &
+ viper_irq_enabled_mask;
+}
+
+static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending;
+
+ pending = viper_irq_pending();
+ do {
+ /* we're in a chained irq handler,
+ * so ack the interrupt by hand */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ if (likely(pending)) {
+ irq = viper_bit_to_irq(__ffs(pending));
+ generic_handle_irq(irq);
+ }
+ pending = viper_irq_pending();
+ } while (pending);
+}
+
+static struct irq_chip viper_irq_chip = {
+ .name = "ISA",
+ .irq_ack = viper_ack_irq,
+ .irq_mask = viper_mask_irq,
+ .irq_unmask = viper_unmask_irq
+};
+
+static void __init viper_init_irq(void)
+{
+ int level;
+ int isa_irq;
+
+ pxa25x_init_irq();
+
+ /* setup ISA IRQs */
+ for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) {
+ isa_irq = viper_bit_to_irq(level);
+ irq_set_chip_and_handler(isa_irq, &viper_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ irq_set_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO),
+ viper_irq_handler);
+ irq_set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH);
+}
+
+/* Flat Panel */
+static struct pxafb_mode_info fb_mode_info[] = {
+ {
+ .pixclock = 157500,
+
+ .xres = 320,
+ .yres = 240,
+
+ .bpp = 16,
+
+ .hsync_len = 63,
+ .left_margin = 7,
+ .right_margin = 13,
+
+ .vsync_len = 20,
+ .upper_margin = 0,
+ .lower_margin = 0,
+
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info fb_info = {
+ .modes = fb_mode_info,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static int viper_backlight_init(struct device *dev)
+{
+ int ret;
+
+ /* GPIO9 and 10 control FB backlight. Initialise to off */
+ ret = gpio_request(VIPER_BCKLIGHT_EN_GPIO, "Backlight");
+ if (ret)
+ goto err_request_bckl;
+
+ ret = gpio_request(VIPER_LCD_EN_GPIO, "LCD");
+ if (ret)
+ goto err_request_lcd;
+
+ ret = gpio_direction_output(VIPER_BCKLIGHT_EN_GPIO, 0);
+ if (ret)
+ goto err_dir;
+
+ ret = gpio_direction_output(VIPER_LCD_EN_GPIO, 0);
+ if (ret)
+ goto err_dir;
+
+ return 0;
+
+err_dir:
+ gpio_free(VIPER_LCD_EN_GPIO);
+err_request_lcd:
+ gpio_free(VIPER_BCKLIGHT_EN_GPIO);
+err_request_bckl:
+ dev_err(dev, "Failed to setup LCD GPIOs\n");
+
+ return ret;
+}
+
+static int viper_backlight_notify(struct device *dev, int brightness)
+{
+ gpio_set_value(VIPER_LCD_EN_GPIO, !!brightness);
+ gpio_set_value(VIPER_BCKLIGHT_EN_GPIO, !!brightness);
+
+ return brightness;
+}
+
+static void viper_backlight_exit(struct device *dev)
+{
+ gpio_free(VIPER_LCD_EN_GPIO);
+ gpio_free(VIPER_BCKLIGHT_EN_GPIO);
+}
+
+static struct platform_pwm_backlight_data viper_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 1000000,
+ .init = viper_backlight_init,
+ .notify = viper_backlight_notify,
+ .exit = viper_backlight_exit,
+};
+
+static struct platform_device viper_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa25x_device_pwm0.dev,
+ .platform_data = &viper_backlight_data,
+ },
+};
+
+/* Ethernet */
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = VIPER_ETH_PHYS + 0x300,
+ .end = VIPER_ETH_PHYS + 0x30f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gpio_to_irq(VIPER_ETH_GPIO),
+ .end = gpio_to_irq(VIPER_ETH_GPIO),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+ [2] = {
+ .name = "smc91x-data32",
+ .start = VIPER_ETH_DATA_PHYS,
+ .end = VIPER_ETH_DATA_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct smc91x_platdata viper_smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &viper_smc91x_info,
+ },
+};
+
+/* i2c */
+static struct i2c_gpio_platform_data i2c_bus_data = {
+ .sda_pin = VIPER_RTC_I2C_SDA_GPIO,
+ .scl_pin = VIPER_RTC_I2C_SCL_GPIO,
+ .udelay = 10,
+ .timeout = HZ,
+};
+
+static struct platform_device i2c_bus_device = {
+ .name = "i2c-gpio",
+ .id = 1, /* pxa2xx-i2c is bus 0, so start at 1 */
+ .dev = {
+ .platform_data = &i2c_bus_data,
+ }
+};
+
+static struct i2c_board_info __initdata viper_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1338", 0x68),
+ },
+};
+
+/*
+ * Serial configuration:
+ * You can either have the standard PXA ports driven by the PXA driver,
+ * or all the ports (PXA + 16850) driven by the 8250 driver.
+ * Choose your poison.
+ */
+
+static struct resource viper_serial_resources[] = {
+#ifndef CONFIG_SERIAL_PXA
+ {
+ .start = 0x40100000,
+ .end = 0x4010001f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x40200000,
+ .end = 0x4020001f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x40700000,
+ .end = 0x4070001f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = VIPER_UARTA_PHYS,
+ .end = VIPER_UARTA_PHYS + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = VIPER_UARTB_PHYS,
+ .end = VIPER_UARTB_PHYS + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+#else
+ {
+ 0,
+ },
+#endif
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+#ifndef CONFIG_SERIAL_PXA
+ /* Internal UARTs */
+ {
+ .membase = (void *)&FFUART,
+ .mapbase = __PREG(FFUART),
+ .irq = IRQ_FFUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ {
+ .membase = (void *)&BTUART,
+ .mapbase = __PREG(BTUART),
+ .irq = IRQ_BTUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ {
+ .membase = (void *)&STUART,
+ .mapbase = __PREG(STUART),
+ .irq = IRQ_STUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ /* External UARTs */
+ {
+ .mapbase = VIPER_UARTA_PHYS,
+ .irq = gpio_to_irq(VIPER_UARTA_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 1843200,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+ UPF_SKIP_TEST,
+ },
+ {
+ .mapbase = VIPER_UARTB_PHYS,
+ .irq = gpio_to_irq(VIPER_UARTB_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 1843200,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+ UPF_SKIP_TEST,
+ },
+#endif
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(viper_serial_resources),
+ .resource = viper_serial_resources,
+};
+
+/* USB */
+static void isp116x_delay(struct device *dev, int delay)
+{
+ ndelay(delay);
+}
+
+static struct resource isp116x_resources[] = {
+ [0] = { /* DATA */
+ .start = VIPER_USB_PHYS + 0,
+ .end = VIPER_USB_PHYS + 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* ADDR */
+ .start = VIPER_USB_PHYS + 2,
+ .end = VIPER_USB_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = gpio_to_irq(VIPER_USB_GPIO),
+ .end = gpio_to_irq(VIPER_USB_GPIO),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data isp116x_platform_data = {
+ /* Enable internal resistors on downstream ports */
+ .sel15Kres = 1,
+ /* On-chip overcurrent protection */
+ .oc_enable = 1,
+ /* INT output polarity */
+ .int_act_high = 1,
+ /* INT edge or level triggered */
+ .int_edge_triggered = 0,
+
+ /* WAKEUP pin connected - NOT SUPPORTED */
+ /* .remote_wakeup_connected = 0, */
+ /* Wakeup by devices on usb bus enabled */
+ .remote_wakeup_enable = 0,
+ .delay = isp116x_delay,
+};
+
+static struct platform_device isp116x_device = {
+ .name = "isp116x-hcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(isp116x_resources),
+ .resource = isp116x_resources,
+ .dev = {
+ .platform_data = &isp116x_platform_data,
+ },
+
+};
+
+/* MTD */
+static struct resource mtd_resources[] = {
+ [0] = { /* RedBoot config + filesystem flash */
+ .start = VIPER_FLASH_PHYS,
+ .end = VIPER_FLASH_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* Boot flash */
+ .start = VIPER_BOOT_PHYS,
+ .end = VIPER_BOOT_PHYS + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /*
+ * SRAM size is actually 256KB, 8bits, with a sparse mapping
+ * (each byte is on a 16bit boundary).
+ */
+ .start = _VIPER_SRAM_BASE,
+ .end = _VIPER_SRAM_BASE + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mtd_partition viper_boot_flash_partition = {
+ .name = "RedBoot",
+ .size = SZ_1M,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force R/O */
+};
+
+static struct physmap_flash_data viper_flash_data[] = {
+ [0] = {
+ .width = 2,
+ .parts = NULL,
+ .nr_parts = 0,
+ },
+ [1] = {
+ .width = 2,
+ .parts = &viper_boot_flash_partition,
+ .nr_parts = 1,
+ },
+};
+
+static struct platform_device viper_mtd_devices[] = {
+ [0] = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &viper_flash_data[0],
+ },
+ .resource = &mtd_resources[0],
+ .num_resources = 1,
+ },
+ [1] = {
+ .name = "physmap-flash",
+ .id = 1,
+ .dev = {
+ .platform_data = &viper_flash_data[1],
+ },
+ .resource = &mtd_resources[1],
+ .num_resources = 1,
+ },
+};
+
+static struct platform_device *viper_devs[] __initdata = {
+ &smc91x_device,
+ &i2c_bus_device,
+ &serial_device,
+ &isp116x_device,
+ &viper_mtd_devices[0],
+ &viper_mtd_devices[1],
+ &viper_backlight_device,
+ &viper_pcmcia_device,
+};
+
+static mfp_cfg_t viper_pin_config[] __initdata = {
+ /* Chip selects */
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO79_nCS_3,
+ GPIO80_nCS_4,
+ GPIO33_nCS_5,
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ /* FP Backlight */
+ GPIO9_GPIO, /* VIPER_BCKLIGHT_EN_GPIO */
+ GPIO10_GPIO, /* VIPER_LCD_EN_GPIO */
+ GPIO16_PWM0_OUT,
+
+ /* Ethernet PHY Ready */
+ GPIO18_RDY,
+
+ /* Serial shutdown */
+ GPIO12_GPIO | MFP_LPM_DRIVE_HIGH, /* VIPER_UART_SHDN_GPIO */
+
+ /* Compact-Flash / PC104 */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO52_nPCE_1,
+ GPIO53_nPCE_2,
+ GPIO54_nPSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO8_GPIO, /* VIPER_CF_RDY_GPIO */
+ GPIO32_GPIO, /* VIPER_CF_CD_GPIO */
+ GPIO82_GPIO, /* VIPER_CF_POWER_GPIO */
+
+ /* Integrated UPS control */
+ GPIO20_GPIO, /* VIPER_UPS_GPIO */
+
+ /* Vcc regulator control */
+ GPIO6_GPIO, /* VIPER_PSU_DATA_GPIO */
+ GPIO11_GPIO, /* VIPER_PSU_CLK_GPIO */
+ GPIO19_GPIO, /* VIPER_PSU_nCS_LD_GPIO */
+
+ /* i2c busses */
+ GPIO26_GPIO, /* VIPER_TPM_I2C_SDA_GPIO */
+ GPIO27_GPIO, /* VIPER_TPM_I2C_SCL_GPIO */
+ GPIO83_GPIO, /* VIPER_RTC_I2C_SDA_GPIO */
+ GPIO84_GPIO, /* VIPER_RTC_I2C_SCL_GPIO */
+
+ /* PC/104 Interrupt */
+ GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* VIPER_CPLD_GPIO */
+};
+
+static unsigned long viper_tpm;
+
+static int __init viper_tpm_setup(char *str)
+{
+ strict_strtoul(str, 10, &viper_tpm);
+ return 1;
+}
+
+__setup("tpm=", viper_tpm_setup);
+
+static void __init viper_tpm_init(void)
+{
+ struct platform_device *tpm_device;
+ struct i2c_gpio_platform_data i2c_tpm_data = {
+ .sda_pin = VIPER_TPM_I2C_SDA_GPIO,
+ .scl_pin = VIPER_TPM_I2C_SCL_GPIO,
+ .udelay = 10,
+ .timeout = HZ,
+ };
+ char *errstr;
+
+ /* Allocate TPM i2c bus if requested */
+ if (!viper_tpm)
+ return;
+
+ tpm_device = platform_device_alloc("i2c-gpio", 2);
+ if (tpm_device) {
+ if (!platform_device_add_data(tpm_device,
+ &i2c_tpm_data,
+ sizeof(i2c_tpm_data))) {
+ if (platform_device_add(tpm_device)) {
+ errstr = "register TPM i2c bus";
+ goto error_free_tpm;
+ }
+ } else {
+ errstr = "allocate TPM i2c bus data";
+ goto error_free_tpm;
+ }
+ } else {
+ errstr = "allocate TPM i2c device";
+ goto error_tpm;
+ }
+
+ return;
+
+error_free_tpm:
+ kfree(tpm_device);
+error_tpm:
+ pr_err("viper: Couldn't %s, giving up\n", errstr);
+}
+
+static void __init viper_init_vcore_gpios(void)
+{
+ if (gpio_request(VIPER_PSU_DATA_GPIO, "PSU data"))
+ goto err_request_data;
+
+ if (gpio_request(VIPER_PSU_CLK_GPIO, "PSU clock"))
+ goto err_request_clk;
+
+ if (gpio_request(VIPER_PSU_nCS_LD_GPIO, "PSU cs"))
+ goto err_request_cs;
+
+ if (gpio_direction_output(VIPER_PSU_DATA_GPIO, 0) ||
+ gpio_direction_output(VIPER_PSU_CLK_GPIO, 0) ||
+ gpio_direction_output(VIPER_PSU_nCS_LD_GPIO, 0))
+ goto err_dir;
+
+ /* c/should assume redboot set the correct level ??? */
+ viper_set_core_cpu_voltage(get_clk_frequency_khz(0), 1);
+
+ return;
+
+err_dir:
+ gpio_free(VIPER_PSU_nCS_LD_GPIO);
+err_request_cs:
+ gpio_free(VIPER_PSU_CLK_GPIO);
+err_request_clk:
+ gpio_free(VIPER_PSU_DATA_GPIO);
+err_request_data:
+ pr_err("viper: Failed to setup vcore control GPIOs\n");
+}
+
+static void __init viper_init_serial_gpio(void)
+{
+ if (gpio_request(VIPER_UART_SHDN_GPIO, "UARTs shutdown"))
+ goto err_request;
+
+ if (gpio_direction_output(VIPER_UART_SHDN_GPIO, 0))
+ goto err_dir;
+
+ return;
+
+err_dir:
+ gpio_free(VIPER_UART_SHDN_GPIO);
+err_request:
+ pr_err("viper: Failed to setup UART shutdown GPIO\n");
+}
+
+#ifdef CONFIG_CPU_FREQ
+static int viper_cpufreq_notifier(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *freq = data;
+
+ /* TODO: Adjust timings??? */
+
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+ if (freq->old < freq->new) {
+ /* we are getting faster so raise the voltage
+ * before we change freq */
+ viper_set_core_cpu_voltage(freq->new, 0);
+ }
+ break;
+ case CPUFREQ_POSTCHANGE:
+ if (freq->old > freq->new) {
+ /* we are slowing down so drop the power
+ * after we change freq */
+ viper_set_core_cpu_voltage(freq->new, 0);
+ }
+ break;
+ case CPUFREQ_RESUMECHANGE:
+ viper_set_core_cpu_voltage(freq->new, 0);
+ break;
+ default:
+ /* ignore */
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block viper_cpufreq_notifier_block = {
+ .notifier_call = viper_cpufreq_notifier
+};
+
+static void __init viper_init_cpufreq(void)
+{
+ if (cpufreq_register_notifier(&viper_cpufreq_notifier_block,
+ CPUFREQ_TRANSITION_NOTIFIER))
+ pr_err("viper: Failed to setup cpufreq notifier\n");
+}
+#else
+static inline void viper_init_cpufreq(void) {}
+#endif
+
+static void viper_power_off(void)
+{
+ pr_notice("Shutting off UPS\n");
+ gpio_set_value(VIPER_UPS_GPIO, 1);
+ /* Spin to death... */
+ while (1);
+}
+
+static void __init viper_init(void)
+{
+ u8 version;
+
+ pm_power_off = viper_power_off;
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(viper_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ /* Wake-up serial console */
+ viper_init_serial_gpio();
+
+ pxa_set_fb_info(NULL, &fb_info);
+
+ /* v1 hardware cannot use the datacs line */
+ version = viper_hw_version();
+ if (version == 0)
+ smc91x_device.num_resources--;
+
+ pxa_set_i2c_info(NULL);
+ platform_add_devices(viper_devs, ARRAY_SIZE(viper_devs));
+
+ viper_init_vcore_gpios();
+ viper_init_cpufreq();
+
+ register_syscore_ops(&viper_cpu_syscore_ops);
+
+ if (version) {
+ pr_info("viper: hardware v%di%d detected. "
+ "CPLD revision %d.\n",
+ VIPER_BOARD_VERSION(version),
+ VIPER_BOARD_ISSUE(version),
+ VIPER_CPLD_REVISION(version));
+ system_rev = (VIPER_BOARD_VERSION(version) << 8) |
+ (VIPER_BOARD_ISSUE(version) << 4) |
+ VIPER_CPLD_REVISION(version);
+ } else {
+ pr_info("viper: No version register.\n");
+ }
+
+ i2c_register_board_info(1, ARRAY_AND_SIZE(viper_i2c_devices));
+
+ viper_tpm_init();
+ pxa_set_ac97_info(NULL);
+}
+
+static struct map_desc viper_io_desc[] __initdata = {
+ {
+ .virtual = VIPER_CPLD_BASE,
+ .pfn = __phys_to_pfn(VIPER_CPLD_PHYS),
+ .length = 0x00300000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = VIPER_PC104IO_BASE,
+ .pfn = __phys_to_pfn(0x30000000),
+ .length = 0x00800000,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init viper_map_io(void)
+{
+ pxa25x_map_io();
+
+ iotable_init(viper_io_desc, ARRAY_SIZE(viper_io_desc));
+
+ PCFR |= PCFR_OPDE;
+}
+
+MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC")
+ /* Maintainer: Marc Zyngier <maz@misterjones.org> */
+ .boot_params = 0xa0000100,
+ .map_io = viper_map_io,
+ .init_irq = viper_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = viper_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
new file mode 100644
index 00000000..10b80d47
--- /dev/null
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -0,0 +1,724 @@
+/*
+ * Hardware definitions for Voipac PXA270
+ *
+ * Copyright (C) 2010
+ * Marek Vasut <marek.vasut@gmail.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/delay.h>
+#include <linux/irq.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/usb/gpio_vbus.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/onenand.h>
+#include <linux/dm9000.h>
+#include <linux/ucb1400.h>
+#include <linux/ata_platform.h>
+#include <linux/regulator/max1586.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/audio.h>
+#include <mach/vpac270.h>
+#include <mach/mmc.h>
+#include <mach/pxafb.h>
+#include <mach/ohci.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+#include <mach/pata_pxa.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long vpac270_pin_config[] __initdata = {
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+ GPIO53_GPIO, /* SD detect */
+ GPIO52_GPIO, /* SD r/o switch */
+
+ /* GPIO KEYS */
+ GPIO1_GPIO, /* USER BTN */
+
+ /* LEDs */
+ GPIO15_GPIO, /* orange led */
+
+ /* FFUART */
+ GPIO34_FFUART_RXD,
+ GPIO39_FFUART_TXD,
+ GPIO27_FFUART_RTS,
+ GPIO100_FFUART_CTS,
+ GPIO33_FFUART_DSR,
+ GPIO40_FFUART_DTR,
+ GPIO10_FFUART_DCD,
+ GPIO38_FFUART_RI,
+
+ /* LCD */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO86_LCD_LDD_16,
+ GPIO87_LCD_LDD_17,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+
+ /* PCMCIA */
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO55_nPREG,
+ GPIO57_nIOIS16,
+ GPIO56_nPWAIT,
+ GPIO104_PSKTSEL,
+ GPIO84_GPIO, /* PCMCIA CD */
+ GPIO35_GPIO, /* PCMCIA RDY */
+ GPIO107_GPIO, /* PCMCIA PPEN */
+ GPIO11_GPIO, /* PCMCIA RESET */
+ GPIO17_GPIO, /* CF CD */
+ GPIO12_GPIO, /* CF RDY */
+ GPIO16_GPIO, /* CF RESET */
+
+ /* UHC */
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+ GPIO119_USBH2_PWR,
+ GPIO120_USBH2_PEN,
+
+ /* UDC */
+ GPIO41_GPIO,
+
+ /* Ethernet */
+ GPIO114_GPIO, /* IRQ */
+
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+ GPIO95_AC97_nRESET,
+ GPIO98_AC97_SYSCLK,
+ GPIO113_GPIO, /* TS IRQ */
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* IDE */
+ GPIO36_GPIO, /* IDE IRQ */
+ GPIO80_DREQ_1,
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct mtd_partition vpac270_nor_partitions[] = {
+ {
+ .name = "Flash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct physmap_flash_data vpac270_flash_data[] = {
+ {
+ .width = 2, /* bankwidth in bytes */
+ .parts = vpac270_nor_partitions,
+ .nr_parts = ARRAY_SIZE(vpac270_nor_partitions)
+ }
+};
+
+static struct resource vpac270_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device vpac270_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .resource = &vpac270_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = vpac270_flash_data,
+ },
+};
+static void __init vpac270_nor_init(void)
+{
+ platform_device_register(&vpac270_flash);
+}
+#else
+static inline void vpac270_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * OneNAND Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_ONENAND) || defined(CONFIG_MTD_ONENAND_MODULE)
+static struct mtd_partition vpac270_onenand_partitions[] = {
+ {
+ .name = "Flash",
+ .offset = 0x00000000,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct onenand_platform_data vpac270_onenand_info = {
+ .parts = vpac270_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(vpac270_onenand_partitions),
+};
+
+static struct resource vpac270_onenand_resources[] = {
+ [0] = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_1M,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device vpac270_onenand = {
+ .name = "onenand-flash",
+ .id = -1,
+ .resource = vpac270_onenand_resources,
+ .num_resources = ARRAY_SIZE(vpac270_onenand_resources),
+ .dev = {
+ .platform_data = &vpac270_onenand_info,
+ },
+};
+
+static void __init vpac270_onenand_init(void)
+{
+ platform_device_register(&vpac270_onenand);
+}
+#else
+static void __init vpac270_onenand_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data vpac270_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_power = -1,
+ .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N,
+ .gpio_card_ro = GPIO52_VPAC270_SD_READONLY,
+ .detect_delay_ms = 200,
+};
+
+static void __init vpac270_mmc_init(void)
+{
+ pxa_set_mci_info(&vpac270_mci_platform_data);
+}
+#else
+static inline void vpac270_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button vpac270_pxa_buttons[] = {
+ {KEY_POWER, GPIO1_VPAC270_USER_BTN, 0, "USER BTN"},
+};
+
+static struct gpio_keys_platform_data vpac270_pxa_keys_data = {
+ .buttons = vpac270_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(vpac270_pxa_buttons),
+};
+
+static struct platform_device vpac270_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &vpac270_pxa_keys_data,
+ },
+};
+
+static void __init vpac270_keys_init(void)
+{
+ platform_device_register(&vpac270_pxa_keys);
+}
+#else
+static inline void vpac270_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * LED
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led vpac270_gpio_leds[] = {
+{
+ .name = "vpac270:orange:user",
+ .default_trigger = "none",
+ .gpio = GPIO15_VPAC270_LED_ORANGE,
+ .active_low = 1,
+}
+};
+
+static struct gpio_led_platform_data vpac270_gpio_led_info = {
+ .leds = vpac270_gpio_leds,
+ .num_leds = ARRAY_SIZE(vpac270_gpio_leds),
+};
+
+static struct platform_device vpac270_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &vpac270_gpio_led_info,
+ }
+};
+
+static void __init vpac270_leds_init(void)
+{
+ platform_device_register(&vpac270_leds);
+}
+#else
+static inline void vpac270_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Host
+ ******************************************************************************/
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static int vpac270_ohci_init(struct device *dev)
+{
+ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+ return 0;
+}
+
+static struct pxaohci_platform_data vpac270_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT2 |
+ POWER_CONTROL_LOW | POWER_SENSE_LOW,
+ .init = vpac270_ohci_init,
+};
+
+static void __init vpac270_uhc_init(void)
+{
+ pxa_set_ohci_info(&vpac270_ohci_info);
+}
+#else
+static inline void vpac270_uhc_init(void) {}
+#endif
+
+/******************************************************************************
+ * USB Gadget
+ ******************************************************************************/
+#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
+static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
+ .gpio_vbus = GPIO41_VPAC270_UDC_DETECT,
+ .gpio_pullup = -1,
+};
+
+static struct platform_device vpac270_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &vpac270_gpio_vbus_info,
+ },
+};
+
+static void vpac270_udc_command(int cmd)
+{
+ if (cmd == PXA2XX_UDC_CMD_CONNECT)
+ UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+ else if (cmd == PXA2XX_UDC_CMD_DISCONNECT)
+ UP2OCR = UP2OCR_HXOE;
+}
+
+static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = {
+ .udc_command = vpac270_udc_command,
+ .gpio_pullup = -1,
+};
+
+static void __init vpac270_udc_init(void)
+{
+ pxa_set_udc_info(&vpac270_udc_info);
+ platform_device_register(&vpac270_gpio_vbus);
+}
+#else
+static inline void vpac270_udc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Ethernet
+ ******************************************************************************/
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource vpac270_dm9000_resources[] = {
+ [0] = {
+ .start = PXA_CS2_PHYS + 0x300,
+ .end = PXA_CS2_PHYS + 0x303,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS2_PHYS + 0x304,
+ .end = PXA_CS2_PHYS + 0x343,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+ .end = IRQ_GPIO(GPIO114_VPAC270_ETH_IRQ),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ },
+};
+
+static struct dm9000_plat_data vpac270_dm9000_platdata = {
+ .flags = DM9000_PLATF_32BITONLY,
+};
+
+static struct platform_device vpac270_dm9000_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(vpac270_dm9000_resources),
+ .resource = vpac270_dm9000_resources,
+ .dev = {
+ .platform_data = &vpac270_dm9000_platdata,
+ }
+};
+
+static void __init vpac270_eth_init(void)
+{
+ platform_device_register(&vpac270_dm9000_device);
+}
+#else
+static inline void vpac270_eth_init(void) {}
+#endif
+
+/******************************************************************************
+ * Audio and Touchscreen
+ ******************************************************************************/
+#if defined(CONFIG_TOUCHSCREEN_UCB1400) || \
+ defined(CONFIG_TOUCHSCREEN_UCB1400_MODULE)
+static pxa2xx_audio_ops_t vpac270_ac97_pdata = {
+ .reset_gpio = 95,
+};
+
+static struct ucb1400_pdata vpac270_ucb1400_pdata = {
+ .irq = IRQ_GPIO(GPIO113_VPAC270_TS_IRQ),
+};
+
+static struct platform_device vpac270_ucb1400_device = {
+ .name = "ucb1400_core",
+ .id = -1,
+ .dev = {
+ .platform_data = &vpac270_ucb1400_pdata,
+ },
+};
+
+static void __init vpac270_ts_init(void)
+{
+ pxa_set_ac97_info(&vpac270_ac97_pdata);
+ platform_device_register(&vpac270_ucb1400_device);
+}
+#else
+static inline void vpac270_ts_init(void) {}
+#endif
+
+/******************************************************************************
+ * RTC
+ ******************************************************************************/
+#if defined(CONFIG_RTC_DRV_DS1307) || defined(CONFIG_RTC_DRV_DS1307_MODULE)
+static struct i2c_board_info __initdata vpac270_i2c_devs[] = {
+ {
+ I2C_BOARD_INFO("ds1339", 0x68),
+ },
+};
+
+static void __init vpac270_rtc_init(void)
+{
+ i2c_register_board_info(0, ARRAY_AND_SIZE(vpac270_i2c_devs));
+}
+#else
+static inline void vpac270_rtc_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info vpac270_lcd_modes[] = {
+{
+ .pixclock = 57692,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 32,
+ .depth = 18,
+
+ .left_margin = 144,
+ .right_margin = 32,
+ .upper_margin = 13,
+ .lower_margin = 30,
+
+ .hsync_len = 32,
+ .vsync_len = 2,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+}, { /* CRT 640x480 */
+ .pixclock = 35000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .depth = 16,
+
+ .left_margin = 96,
+ .right_margin = 48,
+ .upper_margin = 33,
+ .lower_margin = 10,
+
+ .hsync_len = 48,
+ .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+}, { /* CRT 800x600 H=30kHz V=48HZ */
+ .pixclock = 25000,
+ .xres = 800,
+ .yres = 600,
+ .bpp = 16,
+ .depth = 16,
+
+ .left_margin = 50,
+ .right_margin = 1,
+ .upper_margin = 21,
+ .lower_margin = 12,
+
+ .hsync_len = 8,
+ .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+}, { /* CRT 1024x768 H=40kHz V=50Hz */
+ .pixclock = 15000,
+ .xres = 1024,
+ .yres = 768,
+ .bpp = 16,
+ .depth = 16,
+
+ .left_margin = 220,
+ .right_margin = 8,
+ .upper_margin = 33,
+ .lower_margin = 2,
+
+ .hsync_len = 48,
+ .vsync_len = 1,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+}
+};
+
+static struct pxafb_mach_info vpac270_lcd_screen = {
+ .modes = vpac270_lcd_modes,
+ .num_modes = ARRAY_SIZE(vpac270_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_18BPP,
+};
+
+static void vpac270_lcd_power(int on, struct fb_var_screeninfo *info)
+{
+ gpio_set_value(GPIO81_VPAC270_BKL_ON, on);
+}
+
+static void __init vpac270_lcd_init(void)
+{
+ int ret;
+
+ ret = gpio_request(GPIO81_VPAC270_BKL_ON, "BKL-ON");
+ if (ret) {
+ pr_err("Requesting BKL-ON GPIO failed!\n");
+ goto err;
+ }
+
+ ret = gpio_direction_output(GPIO81_VPAC270_BKL_ON, 1);
+ if (ret) {
+ pr_err("Setting BKL-ON GPIO direction failed!\n");
+ goto err2;
+ }
+
+ vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
+ pxa_set_fb_info(NULL, &vpac270_lcd_screen);
+ return;
+
+err2:
+ gpio_free(GPIO81_VPAC270_BKL_ON);
+err:
+ return;
+}
+#else
+static inline void vpac270_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * PATA IDE
+ ******************************************************************************/
+#if defined(CONFIG_PATA_PXA) || defined(CONFIG_PATA_PXA_MODULE)
+static struct pata_pxa_pdata vpac270_pata_pdata = {
+ .reg_shift = 1,
+ .dma_dreq = 1,
+ .irq_flags = IRQF_TRIGGER_RISING,
+};
+
+static struct resource vpac270_ide_resources[] = {
+ [0] = { /* I/O Base address */
+ .start = PXA_CS3_PHYS + 0x120,
+ .end = PXA_CS3_PHYS + 0x13f,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = { /* CTL Base address */
+ .start = PXA_CS3_PHYS + 0x15c,
+ .end = PXA_CS3_PHYS + 0x15f,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = { /* DMA Base address */
+ .start = PXA_CS3_PHYS + 0x20,
+ .end = PXA_CS3_PHYS + 0x2f,
+ .flags = IORESOURCE_DMA
+ },
+ [3] = { /* IDE IRQ pin */
+ .start = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+ .end = gpio_to_irq(GPIO36_VPAC270_IDE_IRQ),
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device vpac270_ide_device = {
+ .name = "pata_pxa",
+ .num_resources = ARRAY_SIZE(vpac270_ide_resources),
+ .resource = vpac270_ide_resources,
+ .dev = {
+ .platform_data = &vpac270_pata_pdata,
+ .coherent_dma_mask = 0xffffffff,
+ }
+};
+
+static void __init vpac270_ide_init(void)
+{
+ platform_device_register(&vpac270_ide_device);
+}
+#else
+static inline void vpac270_ide_init(void) {}
+#endif
+
+/******************************************************************************
+ * Core power regulator
+ ******************************************************************************/
+#if defined(CONFIG_REGULATOR_MAX1586) || \
+ defined(CONFIG_REGULATOR_MAX1586_MODULE)
+static struct regulator_consumer_supply vpac270_max1587a_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data vpac270_max1587a_v3_info = {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 900000,
+ .max_uV = 1705000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = vpac270_max1587a_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(vpac270_max1587a_consumers),
+};
+
+static struct max1586_subdev_data vpac270_max1587a_subdevs[] = {
+ {
+ .name = "vcc_core",
+ .id = MAX1586_V3,
+ .platform_data = &vpac270_max1587a_v3_info,
+ }
+};
+
+static struct max1586_platform_data vpac270_max1587a_info = {
+ .subdevs = vpac270_max1587a_subdevs,
+ .num_subdevs = ARRAY_SIZE(vpac270_max1587a_subdevs),
+ .v3_gain = MAX1586_GAIN_R24_3k32, /* 730..1550 mV */
+};
+
+static struct i2c_board_info __initdata vpac270_pi2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("max1586", 0x14),
+ .platform_data = &vpac270_max1587a_info,
+ },
+};
+
+static void __init vpac270_pmic_init(void)
+{
+ i2c_register_board_info(1, ARRAY_AND_SIZE(vpac270_pi2c_board_info));
+}
+#else
+static inline void vpac270_pmic_init(void) {}
+#endif
+
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init vpac270_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(vpac270_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_i2c_info(NULL);
+ pxa27x_set_i2c_power_info(NULL);
+
+ vpac270_pmic_init();
+ vpac270_lcd_init();
+ vpac270_mmc_init();
+ vpac270_nor_init();
+ vpac270_onenand_init();
+ vpac270_leds_init();
+ vpac270_keys_init();
+ vpac270_uhc_init();
+ vpac270_udc_init();
+ vpac270_eth_init();
+ vpac270_ts_init();
+ vpac270_rtc_init();
+ vpac270_ide_init();
+}
+
+MACHINE_START(VPAC270, "Voipac PXA270")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = vpac270_init
+MACHINE_END
diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c
new file mode 100644
index 00000000..f55f8f2e
--- /dev/null
+++ b/arch/arm/mach-pxa/xcep.c
@@ -0,0 +1,190 @@
+/* linux/arch/arm/mach-pxa/xcep.c
+ *
+ * Support for the Iskratel Electronics XCEP platform as used in
+ * the Libera instruments from Instrumentation Technologies.
+ *
+ * Author: Ales Bardorfer <ales@i-tech.si>
+ * Contributions by: Abbott, MG (Michael) <michael.abbott@diamond.ac.uk>
+ * Contributions by: Matej Kenda <matej.kenda@i-tech.si>
+ * Created: June 2006
+ * Copyright: (C) 2006-2009 Instrumentation Technologies
+ *
+ * This program is free software; you can 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/i2c/pxa-i2c.h>
+#include <linux/smc91x.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa2xx-regs.h>
+#include <mach/mfp-pxa25x.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+
+#define XCEP_ETH_PHYS (PXA_CS3_PHYS + 0x00000300)
+#define XCEP_ETH_PHYS_END (PXA_CS3_PHYS + 0x000fffff)
+#define XCEP_ETH_ATTR (PXA_CS3_PHYS + 0x02000000)
+#define XCEP_ETH_ATTR_END (PXA_CS3_PHYS + 0x020fffff)
+#define XCEP_ETH_IRQ IRQ_GPIO0
+
+/* XCEP CPLD base */
+#define XCEP_CPLD_BASE 0xf0000000
+
+
+/* Flash partitions. */
+
+static struct mtd_partition xcep_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "Bootloader ENV",
+ .size = 0x00040000,
+ .offset = 0x00040000,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "Kernel",
+ .size = 0x00100000,
+ .offset = 0x00080000,
+ }, {
+ .name = "Rescue fs",
+ .size = 0x00280000,
+ .offset = 0x00180000,
+ }, {
+ .name = "Filesystem",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00400000
+ }
+};
+
+static struct physmap_flash_data xcep_flash_data[] = {
+ {
+ .width = 4, /* bankwidth in bytes */
+ .parts = xcep_partitions,
+ .nr_parts = ARRAY_SIZE(xcep_partitions)
+ }
+};
+
+static struct resource flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = xcep_flash_data,
+ },
+ .resource = &flash_resource,
+ .num_resources = 1,
+};
+
+
+
+/* SMC LAN91C111 network controller. */
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = XCEP_ETH_PHYS,
+ .end = XCEP_ETH_PHYS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = XCEP_ETH_IRQ,
+ .end = XCEP_ETH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "smc91x-attrib",
+ .start = XCEP_ETH_ATTR,
+ .end = XCEP_ETH_ATTR_END,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct smc91x_platdata xcep_smc91x_info = {
+ .flags = SMC91X_USE_32BIT | SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &xcep_smc91x_info,
+ },
+};
+
+
+static struct platform_device *devices[] __initdata = {
+ &flash_device,
+ &smc91x_device,
+};
+
+
+/* We have to state that there are HWMON devices on the I2C bus on XCEP.
+ * Drivers for HWMON verify capabilities of the adapter when loading and
+ * refuse to attach if the adapter doesn't support HWMON class of devices.
+ * See also Documentation/i2c/porting-clients. */
+static struct i2c_pxa_platform_data xcep_i2c_platform_data = {
+ .class = I2C_CLASS_HWMON
+};
+
+
+static mfp_cfg_t xcep_pin_config[] __initdata = {
+ GPIO79_nCS_3, /* SMC 91C111 chip select. */
+ GPIO80_nCS_4, /* CPLD chip select. */
+ /* SSP communication to MSP430 */
+ GPIO23_SSP1_SCLK,
+ GPIO24_SSP1_SFRM,
+ GPIO25_SSP1_TXD,
+ GPIO26_SSP1_RXD,
+ GPIO27_SSP1_EXTCLK
+};
+
+static void __init xcep_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(xcep_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+ pxa_set_hwuart_info(NULL);
+
+ /* See Intel XScale Developer's Guide for details */
+ /* Set RDF and RDN to appropriate values (chip select 3 (smc91x)) */
+ __raw_writel((__raw_readl(MSC1) & 0xffff) | 0xD5540000, MSC1);
+ /* Set RDF and RDN to appropriate values (chip select 5 (fpga)) */
+ __raw_writel((__raw_readl(MSC2) & 0xffff) | 0x72A00000, MSC2);
+
+ platform_add_devices(ARRAY_AND_SIZE(devices));
+ pxa_set_i2c_info(&xcep_i2c_platform_data);
+}
+
+MACHINE_START(XCEP, "Iskratel XCEP")
+ .boot_params = 0xa0000100,
+ .init_machine = xcep_init,
+ .map_io = pxa25x_map_io,
+ .init_irq = pxa25x_init_irq,
+ .timer = &pxa_timer,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
new file mode 100644
index 00000000..fbe9e02e
--- /dev/null
+++ b/arch/arm/mach-pxa/z2.c
@@ -0,0 +1,709 @@
+/*
+ * linux/arch/arm/mach-pxa/z2.c
+ *
+ * Support for the Zipit Z2 Handheld device.
+ *
+ * Copyright (C) 2009-2010 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on research and code by: Ken McGuire
+ * Based on mainstone.c as modified for the Zipit Z2.
+ *
+ * This program is free software; you can 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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/pwm_backlight.h>
+#include <linux/z2_battery.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/spi/libertas_spi.h>
+#include <linux/spi/lms283gf05.h>
+#include <linux/power_supply.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/delay.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/pxa-i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/pxa27x.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/z2.h>
+#include <mach/pxafb.h>
+#include <mach/mmc.h>
+#include <plat/pxa27x_keypad.h>
+
+#include "generic.h"
+#include "devices.h"
+
+/******************************************************************************
+ * Pin configuration
+ ******************************************************************************/
+static unsigned long z2_pin_config[] = {
+
+ /* LCD - 16bpp Active TFT */
+ GPIO58_LCD_LDD_0,
+ GPIO59_LCD_LDD_1,
+ GPIO60_LCD_LDD_2,
+ GPIO61_LCD_LDD_3,
+ GPIO62_LCD_LDD_4,
+ GPIO63_LCD_LDD_5,
+ GPIO64_LCD_LDD_6,
+ GPIO65_LCD_LDD_7,
+ GPIO66_LCD_LDD_8,
+ GPIO67_LCD_LDD_9,
+ GPIO68_LCD_LDD_10,
+ GPIO69_LCD_LDD_11,
+ GPIO70_LCD_LDD_12,
+ GPIO71_LCD_LDD_13,
+ GPIO72_LCD_LDD_14,
+ GPIO73_LCD_LDD_15,
+ GPIO74_LCD_FCLK,
+ GPIO75_LCD_LCLK,
+ GPIO76_LCD_PCLK,
+ GPIO77_LCD_BIAS,
+ GPIO19_GPIO, /* LCD reset */
+ GPIO88_GPIO, /* LCD chipselect */
+
+ /* PWM */
+ GPIO115_PWM1_OUT, /* Keypad Backlight */
+ GPIO11_PWM2_OUT, /* LCD Backlight */
+
+ /* MMC */
+ GPIO32_MMC_CLK,
+ GPIO112_MMC_CMD,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO96_GPIO, /* SD detect */
+
+ /* STUART */
+ GPIO46_STUART_RXD,
+ GPIO47_STUART_TXD,
+
+ /* Keypad */
+ GPIO100_KP_MKIN_0,
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO34_KP_MKIN_3,
+ GPIO38_KP_MKIN_4,
+ GPIO16_KP_MKIN_5,
+ GPIO17_KP_MKIN_6,
+ GPIO103_KP_MKOUT_0,
+ GPIO104_KP_MKOUT_1,
+ GPIO105_KP_MKOUT_2,
+ GPIO106_KP_MKOUT_3,
+ GPIO107_KP_MKOUT_4,
+ GPIO108_KP_MKOUT_5,
+ GPIO35_KP_MKOUT_6,
+ GPIO41_KP_MKOUT_7,
+
+ /* I2C */
+ GPIO117_I2C_SCL,
+ GPIO118_I2C_SDA,
+
+ /* SSP1 */
+ GPIO23_SSP1_SCLK, /* SSP1_SCK */
+ GPIO25_SSP1_TXD, /* SSP1_TXD */
+ GPIO26_SSP1_RXD, /* SSP1_RXD */
+
+ /* SSP2 */
+ GPIO22_SSP2_SCLK, /* SSP2_SCK */
+ GPIO13_SSP2_TXD, /* SSP2_TXD */
+ GPIO40_SSP2_RXD, /* SSP2_RXD */
+
+ /* LEDs */
+ GPIO10_GPIO, /* WiFi LED */
+ GPIO83_GPIO, /* Charging LED */
+ GPIO85_GPIO, /* Charged LED */
+
+ /* I2S */
+ GPIO28_I2S_BITCLK_OUT,
+ GPIO29_I2S_SDATA_IN,
+ GPIO30_I2S_SDATA_OUT,
+ GPIO31_I2S_SYNC,
+ GPIO113_I2S_SYSCLK,
+
+ /* MISC */
+ GPIO0_GPIO, /* AC power detect */
+ GPIO1_GPIO, /* Power button */
+ GPIO37_GPIO, /* Headphone detect */
+ GPIO98_GPIO, /* Lid switch */
+ GPIO14_GPIO, /* WiFi Power */
+ GPIO24_GPIO, /* WiFi CS */
+ GPIO36_GPIO, /* WiFi IRQ */
+ GPIO88_GPIO, /* LCD CS */
+};
+
+/******************************************************************************
+ * NOR Flash
+ ******************************************************************************/
+#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+static struct resource z2_flash_resource = {
+ .start = PXA_CS0_PHYS,
+ .end = PXA_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition z2_flash_parts[] = {
+ {
+ .name = "U-Boot Bootloader",
+ .offset = 0x0,
+ .size = 0x40000,
+ }, {
+ .name = "U-Boot Environment",
+ .offset = 0x40000,
+ .size = 0x20000,
+ }, {
+ .name = "Flash",
+ .offset = 0x60000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data z2_flash_data = {
+ .width = 2,
+ .parts = z2_flash_parts,
+ .nr_parts = ARRAY_SIZE(z2_flash_parts),
+};
+
+static struct platform_device z2_flash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = &z2_flash_resource,
+ .num_resources = 1,
+ .dev = {
+ .platform_data = &z2_flash_data,
+ },
+};
+
+static void __init z2_nor_init(void)
+{
+ platform_device_register(&z2_flash);
+}
+#else
+static inline void z2_nor_init(void) {}
+#endif
+
+/******************************************************************************
+ * Backlight
+ ******************************************************************************/
+#if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE)
+static struct platform_pwm_backlight_data z2_backlight_data[] = {
+ [0] = {
+ /* Keypad Backlight */
+ .pwm_id = 1,
+ .max_brightness = 1023,
+ .dft_brightness = 0,
+ .pwm_period_ns = 1260320,
+ },
+ [1] = {
+ /* LCD Backlight */
+ .pwm_id = 2,
+ .max_brightness = 1023,
+ .dft_brightness = 512,
+ .pwm_period_ns = 1260320,
+ },
+};
+
+static struct platform_device z2_backlight_devices[2] = {
+ {
+ .name = "pwm-backlight",
+ .id = 0,
+ .dev = {
+ .platform_data = &z2_backlight_data[1],
+ },
+ },
+ {
+ .name = "pwm-backlight",
+ .id = 1,
+ .dev = {
+ .platform_data = &z2_backlight_data[0],
+ },
+ },
+};
+static void __init z2_pwm_init(void)
+{
+ platform_device_register(&z2_backlight_devices[0]);
+ platform_device_register(&z2_backlight_devices[1]);
+}
+#else
+static inline void z2_pwm_init(void) {}
+#endif
+
+/******************************************************************************
+ * Framebuffer
+ ******************************************************************************/
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct pxafb_mode_info z2_lcd_modes[] = {
+{
+ .pixclock = 192000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+
+ .left_margin = 4,
+ .right_margin = 8,
+ .upper_margin = 4,
+ .lower_margin = 8,
+
+ .hsync_len = 4,
+ .vsync_len = 4,
+},
+};
+
+static struct pxafb_mach_info z2_lcd_screen = {
+ .modes = z2_lcd_modes,
+ .num_modes = ARRAY_SIZE(z2_lcd_modes),
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_BIAS_ACTIVE_LOW |
+ LCD_ALTERNATE_MAPPING,
+};
+
+static void __init z2_lcd_init(void)
+{
+ pxa_set_fb_info(NULL, &z2_lcd_screen);
+}
+#else
+static inline void z2_lcd_init(void) {}
+#endif
+
+/******************************************************************************
+ * SD/MMC card controller
+ ******************************************************************************/
+#if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE)
+static struct pxamci_platform_data z2_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .gpio_card_detect = GPIO96_ZIPITZ2_SD_DETECT,
+ .gpio_power = -1,
+ .gpio_card_ro = -1,
+ .detect_delay_ms = 200,
+};
+
+static void __init z2_mmc_init(void)
+{
+ pxa_set_mci_info(&z2_mci_platform_data);
+}
+#else
+static inline void z2_mmc_init(void) {}
+#endif
+
+/******************************************************************************
+ * LEDs
+ ******************************************************************************/
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+struct gpio_led z2_gpio_leds[] = {
+{
+ .name = "z2:green:wifi",
+ .default_trigger = "none",
+ .gpio = GPIO10_ZIPITZ2_LED_WIFI,
+ .active_low = 1,
+}, {
+ .name = "z2:green:charged",
+ .default_trigger = "mmc0",
+ .gpio = GPIO85_ZIPITZ2_LED_CHARGED,
+ .active_low = 1,
+}, {
+ .name = "z2:amber:charging",
+ .default_trigger = "Z2-charging-or-full",
+ .gpio = GPIO83_ZIPITZ2_LED_CHARGING,
+ .active_low = 1,
+},
+};
+
+static struct gpio_led_platform_data z2_gpio_led_info = {
+ .leds = z2_gpio_leds,
+ .num_leds = ARRAY_SIZE(z2_gpio_leds),
+};
+
+static struct platform_device z2_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &z2_gpio_led_info,
+ }
+};
+
+static void __init z2_leds_init(void)
+{
+ platform_device_register(&z2_leds);
+}
+#else
+static inline void z2_leds_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keyboard
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int z2_matrix_keys[] = {
+ KEY(0, 0, KEY_OPTION),
+ KEY(1, 0, KEY_UP),
+ KEY(2, 0, KEY_DOWN),
+ KEY(3, 0, KEY_LEFT),
+ KEY(4, 0, KEY_RIGHT),
+ KEY(5, 0, KEY_END),
+ KEY(6, 0, KEY_KPPLUS),
+
+ KEY(0, 1, KEY_HOME),
+ KEY(1, 1, KEY_Q),
+ KEY(2, 1, KEY_I),
+ KEY(3, 1, KEY_G),
+ KEY(4, 1, KEY_X),
+ KEY(5, 1, KEY_ENTER),
+ KEY(6, 1, KEY_KPMINUS),
+
+ KEY(0, 2, KEY_PAGEUP),
+ KEY(1, 2, KEY_W),
+ KEY(2, 2, KEY_O),
+ KEY(3, 2, KEY_H),
+ KEY(4, 2, KEY_C),
+ KEY(5, 2, KEY_LEFTALT),
+
+ KEY(0, 3, KEY_PAGEDOWN),
+ KEY(1, 3, KEY_E),
+ KEY(2, 3, KEY_P),
+ KEY(3, 3, KEY_J),
+ KEY(4, 3, KEY_V),
+ KEY(5, 3, KEY_LEFTSHIFT),
+
+ KEY(0, 4, KEY_ESC),
+ KEY(1, 4, KEY_R),
+ KEY(2, 4, KEY_A),
+ KEY(3, 4, KEY_K),
+ KEY(4, 4, KEY_B),
+ KEY(5, 4, KEY_LEFTCTRL),
+
+ KEY(0, 5, KEY_TAB),
+ KEY(1, 5, KEY_T),
+ KEY(2, 5, KEY_S),
+ KEY(3, 5, KEY_L),
+ KEY(4, 5, KEY_N),
+ KEY(5, 5, KEY_SPACE),
+
+ KEY(0, 6, KEY_STOPCD),
+ KEY(1, 6, KEY_Y),
+ KEY(2, 6, KEY_D),
+ KEY(3, 6, KEY_BACKSPACE),
+ KEY(4, 6, KEY_M),
+ KEY(5, 6, KEY_COMMA),
+
+ KEY(0, 7, KEY_PLAYCD),
+ KEY(1, 7, KEY_U),
+ KEY(2, 7, KEY_F),
+ KEY(3, 7, KEY_Z),
+ KEY(4, 7, KEY_SEMICOLON),
+ KEY(5, 7, KEY_DOT),
+};
+
+static struct pxa27x_keypad_platform_data z2_keypad_platform_data = {
+ .matrix_key_rows = 7,
+ .matrix_key_cols = 8,
+ .matrix_key_map = z2_matrix_keys,
+ .matrix_key_map_size = ARRAY_SIZE(z2_matrix_keys),
+
+ .debounce_interval = 30,
+};
+
+static void __init z2_mkp_init(void)
+{
+ pxa_set_keypad_info(&z2_keypad_platform_data);
+}
+#else
+static inline void z2_mkp_init(void) {}
+#endif
+
+/******************************************************************************
+ * GPIO keys
+ ******************************************************************************/
+#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
+static struct gpio_keys_button z2_pxa_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = GPIO1_ZIPITZ2_POWER_BUTTON,
+ .active_low = 0,
+ .desc = "Power Button",
+ .wakeup = 1,
+ .type = EV_KEY,
+ },
+ {
+ .code = SW_LID,
+ .gpio = GPIO98_ZIPITZ2_LID_BUTTON,
+ .active_low = 1,
+ .desc = "Lid Switch",
+ .wakeup = 0,
+ .type = EV_SW,
+ },
+};
+
+static struct gpio_keys_platform_data z2_pxa_keys_data = {
+ .buttons = z2_pxa_buttons,
+ .nbuttons = ARRAY_SIZE(z2_pxa_buttons),
+};
+
+static struct platform_device z2_pxa_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &z2_pxa_keys_data,
+ },
+};
+
+static void __init z2_keys_init(void)
+{
+ platform_device_register(&z2_pxa_keys);
+}
+#else
+static inline void z2_keys_init(void) {}
+#endif
+
+/******************************************************************************
+ * Battery
+ ******************************************************************************/
+#if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE)
+static struct z2_battery_info batt_chip_info = {
+ .batt_I2C_bus = 0,
+ .batt_I2C_addr = 0x55,
+ .batt_I2C_reg = 2,
+ .charge_gpio = GPIO0_ZIPITZ2_AC_DETECT,
+ .min_voltage = 3475000,
+ .max_voltage = 4190000,
+ .batt_div = 59,
+ .batt_mult = 1000000,
+ .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION,
+ .batt_name = "Z2",
+};
+
+static struct i2c_board_info __initdata z2_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("aer915", 0x55),
+ .platform_data = &batt_chip_info,
+ }, {
+ I2C_BOARD_INFO("wm8750", 0x1b),
+ },
+
+};
+
+static void __init z2_i2c_init(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(z2_i2c_board_info));
+}
+#else
+static inline void z2_i2c_init(void) {}
+#endif
+
+/******************************************************************************
+ * SSP Devices - WiFi and LCD control
+ ******************************************************************************/
+#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
+/* WiFi */
+static int z2_lbs_spi_setup(struct spi_device *spi)
+{
+ int ret = 0;
+
+ ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power");
+ if (ret)
+ goto err;
+
+ ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1);
+ if (ret)
+ goto err2;
+
+ /* Wait until card is powered on */
+ mdelay(180);
+
+ spi->bits_per_word = 16;
+ spi->mode = SPI_MODE_2,
+
+ spi_setup(spi);
+
+ return 0;
+
+err2:
+ gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
+err:
+ return ret;
+};
+
+static int z2_lbs_spi_teardown(struct spi_device *spi)
+{
+ gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0);
+ gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
+
+ return 0;
+};
+
+static struct pxa2xx_spi_chip z2_lbs_chip_info = {
+ .rx_threshold = 8,
+ .tx_threshold = 8,
+ .timeout = 1000,
+ .gpio_cs = GPIO24_ZIPITZ2_WIFI_CS,
+};
+
+static struct libertas_spi_platform_data z2_lbs_pdata = {
+ .use_dummy_writes = 1,
+ .setup = z2_lbs_spi_setup,
+ .teardown = z2_lbs_spi_teardown,
+};
+
+/* LCD */
+static struct pxa2xx_spi_chip lms283_chip_info = {
+ .rx_threshold = 1,
+ .tx_threshold = 1,
+ .timeout = 64,
+ .gpio_cs = GPIO88_ZIPITZ2_LCD_CS,
+};
+
+static const struct lms283gf05_pdata lms283_pdata = {
+ .reset_gpio = GPIO19_ZIPITZ2_LCD_RESET,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+{
+ .modalias = "libertas_spi",
+ .platform_data = &z2_lbs_pdata,
+ .controller_data = &z2_lbs_chip_info,
+ .irq = gpio_to_irq(GPIO36_ZIPITZ2_WIFI_IRQ),
+ .max_speed_hz = 13000000,
+ .bus_num = 1,
+ .chip_select = 0,
+},
+{
+ .modalias = "lms283gf05",
+ .controller_data = &lms283_chip_info,
+ .platform_data = &lms283_pdata,
+ .max_speed_hz = 400000,
+ .bus_num = 2,
+ .chip_select = 0,
+},
+};
+
+static struct pxa2xx_spi_master pxa_ssp1_master_info = {
+ .clock_enable = CKEN_SSP,
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+static struct pxa2xx_spi_master pxa_ssp2_master_info = {
+ .clock_enable = CKEN_SSP2,
+ .num_chipselect = 1,
+};
+
+static void __init z2_spi_init(void)
+{
+ pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
+ pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+#else
+static inline void z2_spi_init(void) {}
+#endif
+
+/******************************************************************************
+ * Core power regulator
+ ******************************************************************************/
+#if defined(CONFIG_REGULATOR_TPS65023) || \
+ defined(CONFIG_REGULATOR_TPS65023_MODULE)
+static struct regulator_consumer_supply z2_tps65021_consumers[] = {
+ {
+ .supply = "vcc_core",
+ }
+};
+
+static struct regulator_init_data z2_tps65021_info[] = {
+ {
+ .constraints = {
+ .name = "vcc_core range",
+ .min_uV = 800000,
+ .max_uV = 1600000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .consumer_supplies = z2_tps65021_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(z2_tps65021_consumers),
+ }, {
+ .constraints = {
+ .name = "DCDC2",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .always_on = 1,
+ },
+ }, {
+ .constraints = {
+ .name = "DCDC3",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ },
+ }, {
+ .constraints = {
+ .name = "LDO1",
+ .min_uV = 1000000,
+ .max_uV = 3150000,
+ .always_on = 1,
+ },
+ }, {
+ .constraints = {
+ .name = "LDO2",
+ .min_uV = 1050000,
+ .max_uV = 3300000,
+ .always_on = 1,
+ },
+ }
+};
+
+static struct i2c_board_info __initdata z2_pi2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("tps65021", 0x48),
+ .platform_data = &z2_tps65021_info,
+ },
+};
+
+static void __init z2_pmic_init(void)
+{
+ pxa27x_set_i2c_power_info(NULL);
+ i2c_register_board_info(1, ARRAY_AND_SIZE(z2_pi2c_board_info));
+}
+#else
+static inline void z2_pmic_init(void) {}
+#endif
+
+/******************************************************************************
+ * Machine init
+ ******************************************************************************/
+static void __init z2_init(void)
+{
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(z2_pin_config));
+
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ z2_lcd_init();
+ z2_mmc_init();
+ z2_mkp_init();
+ z2_i2c_init();
+ z2_spi_init();
+ z2_nor_init();
+ z2_pwm_init();
+ z2_leds_init();
+ z2_keys_init();
+ z2_pmic_init();
+}
+
+MACHINE_START(ZIPIT2, "Zipit Z2")
+ .boot_params = 0xa0000100,
+ .map_io = pxa27x_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = z2_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
new file mode 100644
index 00000000..00363c7a
--- /dev/null
+++ b/arch/arm/mach-pxa/zeus.c
@@ -0,0 +1,914 @@
+/*
+ * Support for the Arcom ZEUS.
+ *
+ * Copyright (C) 2006 Arcom Control Systems Ltd.
+ *
+ * Loosely based on Arcom's 2.6.16.28.
+ * Maintained by Marc Zyngier <maz@misterjones.org>
+ *
+ * This program is free software; you can 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/cpufreq.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/gpio.h>
+#include <linux/serial_8250.h>
+#include <linux/dm9000.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/apm-emulation.h>
+#include <linux/can/platform/mcp251x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/pxa2xx-regs.h>
+#include <mach/regs-uart.h>
+#include <mach/ohci.h>
+#include <mach/mmc.h>
+#include <mach/pxa27x-udc.h>
+#include <mach/udc.h>
+#include <mach/pxafb.h>
+#include <mach/mfp-pxa27x.h>
+#include <mach/pm.h>
+#include <mach/audio.h>
+#include <mach/arcom-pcmcia.h>
+#include <mach/zeus.h>
+#include <mach/smemc.h>
+
+#include "generic.h"
+
+/*
+ * Interrupt handling
+ */
+
+static unsigned long zeus_irq_enabled_mask;
+static const int zeus_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, };
+static const int zeus_isa_irq_map[] = {
+ 0, /* ISA irq #0, invalid */
+ 0, /* ISA irq #1, invalid */
+ 0, /* ISA irq #2, invalid */
+ 1 << 0, /* ISA irq #3 */
+ 1 << 1, /* ISA irq #4 */
+ 1 << 2, /* ISA irq #5 */
+ 1 << 3, /* ISA irq #6 */
+ 1 << 4, /* ISA irq #7 */
+ 0, /* ISA irq #8, invalid */
+ 0, /* ISA irq #9, invalid */
+ 1 << 5, /* ISA irq #10 */
+ 1 << 6, /* ISA irq #11 */
+ 1 << 7, /* ISA irq #12 */
+};
+
+static inline int zeus_irq_to_bitmask(unsigned int irq)
+{
+ return zeus_isa_irq_map[irq - PXA_ISA_IRQ(0)];
+}
+
+static inline int zeus_bit_to_irq(int bit)
+{
+ return zeus_isa_irqs[bit] + PXA_ISA_IRQ(0);
+}
+
+static void zeus_ack_irq(struct irq_data *d)
+{
+ __raw_writew(zeus_irq_to_bitmask(d->irq), ZEUS_CPLD_ISA_IRQ);
+}
+
+static void zeus_mask_irq(struct irq_data *d)
+{
+ zeus_irq_enabled_mask &= ~(zeus_irq_to_bitmask(d->irq));
+}
+
+static void zeus_unmask_irq(struct irq_data *d)
+{
+ zeus_irq_enabled_mask |= zeus_irq_to_bitmask(d->irq);
+}
+
+static inline unsigned long zeus_irq_pending(void)
+{
+ return __raw_readw(ZEUS_CPLD_ISA_IRQ) & zeus_irq_enabled_mask;
+}
+
+static void zeus_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned long pending;
+
+ pending = zeus_irq_pending();
+ do {
+ /* we're in a chained irq handler,
+ * so ack the interrupt by hand */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ if (likely(pending)) {
+ irq = zeus_bit_to_irq(__ffs(pending));
+ generic_handle_irq(irq);
+ }
+ pending = zeus_irq_pending();
+ } while (pending);
+}
+
+static struct irq_chip zeus_irq_chip = {
+ .name = "ISA",
+ .irq_ack = zeus_ack_irq,
+ .irq_mask = zeus_mask_irq,
+ .irq_unmask = zeus_unmask_irq,
+};
+
+static void __init zeus_init_irq(void)
+{
+ int level;
+ int isa_irq;
+
+ pxa27x_init_irq();
+
+ /* Peripheral IRQs. It would be nice to move those inside driver
+ configuration, but it is not supported at the moment. */
+ irq_set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO),
+ IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING);
+
+ /* Setup ISA IRQs */
+ for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) {
+ isa_irq = zeus_bit_to_irq(level);
+ irq_set_chip_and_handler(isa_irq, &zeus_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ irq_set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler);
+}
+
+
+/*
+ * Platform devices
+ */
+
+/* Flash */
+static struct resource zeus_mtd_resources[] = {
+ [0] = { /* NOR Flash (up to 64MB) */
+ .start = ZEUS_FLASH_PHYS,
+ .end = ZEUS_FLASH_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* SRAM */
+ .start = ZEUS_SRAM_PHYS,
+ .end = ZEUS_SRAM_PHYS + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct physmap_flash_data zeus_flash_data[] = {
+ [0] = {
+ .width = 2,
+ .parts = NULL,
+ .nr_parts = 0,
+ },
+};
+
+static struct platform_device zeus_mtd_devices[] = {
+ [0] = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &zeus_flash_data[0],
+ },
+ .resource = &zeus_mtd_resources[0],
+ .num_resources = 1,
+ },
+};
+
+/* Serial */
+static struct resource zeus_serial_resources[] = {
+ {
+ .start = 0x10000000,
+ .end = 0x1000000f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x10800000,
+ .end = 0x1080000f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x11000000,
+ .end = 0x1100000f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x40100000,
+ .end = 0x4010001f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x40200000,
+ .end = 0x4020001f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x40700000,
+ .end = 0x4070001f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ /* External UARTs */
+ /* FIXME: Shared IRQs on COM1-COM4 will not work properly on v1i1 hardware. */
+ { /* COM1 */
+ .mapbase = 0x10000000,
+ .irq = gpio_to_irq(ZEUS_UARTA_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 14745600,
+ .regshift = 1,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { /* COM2 */
+ .mapbase = 0x10800000,
+ .irq = gpio_to_irq(ZEUS_UARTB_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 14745600,
+ .regshift = 1,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { /* COM3 */
+ .mapbase = 0x11000000,
+ .irq = gpio_to_irq(ZEUS_UARTC_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 14745600,
+ .regshift = 1,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { /* COM4 */
+ .mapbase = 0x11800000,
+ .irq = gpio_to_irq(ZEUS_UARTD_GPIO),
+ .irqflags = IRQF_TRIGGER_RISING,
+ .uartclk = 14745600,
+ .regshift = 1,
+ .flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ /* Internal UARTs */
+ { /* FFUART */
+ .membase = (void *)&FFUART,
+ .mapbase = __PREG(FFUART),
+ .irq = IRQ_FFUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { /* BTUART */
+ .membase = (void *)&BTUART,
+ .mapbase = __PREG(BTUART),
+ .irq = IRQ_BTUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { /* STUART */
+ .membase = (void *)&STUART,
+ .mapbase = __PREG(STUART),
+ .irq = IRQ_STUART,
+ .uartclk = 921600 * 16,
+ .regshift = 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ .iotype = UPIO_MEM,
+ },
+ { },
+};
+
+static struct platform_device zeus_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(zeus_serial_resources),
+ .resource = zeus_serial_resources,
+};
+
+/* Ethernet */
+static struct resource zeus_dm9k0_resource[] = {
+ [0] = {
+ .start = ZEUS_ETH0_PHYS,
+ .end = ZEUS_ETH0_PHYS + 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = ZEUS_ETH0_PHYS + 2,
+ .end = ZEUS_ETH0_PHYS + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = gpio_to_irq(ZEUS_ETH0_GPIO),
+ .end = gpio_to_irq(ZEUS_ETH0_GPIO),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct resource zeus_dm9k1_resource[] = {
+ [0] = {
+ .start = ZEUS_ETH1_PHYS,
+ .end = ZEUS_ETH1_PHYS + 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = ZEUS_ETH1_PHYS + 2,
+ .end = ZEUS_ETH1_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = gpio_to_irq(ZEUS_ETH1_GPIO),
+ .end = gpio_to_irq(ZEUS_ETH1_GPIO),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct dm9000_plat_data zeus_dm9k_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device zeus_dm9k0_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(zeus_dm9k0_resource),
+ .resource = zeus_dm9k0_resource,
+ .dev = {
+ .platform_data = &zeus_dm9k_platdata,
+ }
+};
+
+static struct platform_device zeus_dm9k1_device = {
+ .name = "dm9000",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(zeus_dm9k1_resource),
+ .resource = zeus_dm9k1_resource,
+ .dev = {
+ .platform_data = &zeus_dm9k_platdata,
+ }
+};
+
+/* External SRAM */
+static struct resource zeus_sram_resource = {
+ .start = ZEUS_SRAM_PHYS,
+ .end = ZEUS_SRAM_PHYS + ZEUS_SRAM_SIZE * 2 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device zeus_sram_device = {
+ .name = "pxa2xx-8bit-sram",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &zeus_sram_resource,
+};
+
+/* SPI interface on SSP3 */
+static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
+ .num_chipselect = 1,
+ .enable_dma = 1,
+};
+
+/* CAN bus on SPI */
+static int zeus_mcp2515_setup(struct spi_device *sdev)
+{
+ int err;
+
+ err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
+ if (err)
+ return err;
+
+ err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1);
+ if (err) {
+ gpio_free(ZEUS_CAN_SHDN_GPIO);
+ return err;
+ }
+
+ return 0;
+}
+
+static int zeus_mcp2515_transceiver_enable(int enable)
+{
+ gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable);
+ return 0;
+}
+
+static struct mcp251x_platform_data zeus_mcp2515_pdata = {
+ .oscillator_frequency = 16*1000*1000,
+ .board_specific_setup = zeus_mcp2515_setup,
+ .power_enable = zeus_mcp2515_transceiver_enable,
+};
+
+static struct spi_board_info zeus_spi_board_info[] = {
+ [0] = {
+ .modalias = "mcp2515",
+ .platform_data = &zeus_mcp2515_pdata,
+ .irq = gpio_to_irq(ZEUS_CAN_GPIO),
+ .max_speed_hz = 1*1000*1000,
+ .bus_num = 3,
+ .mode = SPI_MODE_0,
+ .chip_select = 0,
+ },
+};
+
+/* Leds */
+static struct gpio_led zeus_leds[] = {
+ [0] = {
+ .name = "zeus:yellow:1",
+ .default_trigger = "heartbeat",
+ .gpio = ZEUS_EXT0_GPIO(3),
+ .active_low = 1,
+ },
+ [1] = {
+ .name = "zeus:yellow:2",
+ .default_trigger = "default-on",
+ .gpio = ZEUS_EXT0_GPIO(4),
+ .active_low = 1,
+ },
+ [2] = {
+ .name = "zeus:yellow:3",
+ .default_trigger = "default-on",
+ .gpio = ZEUS_EXT0_GPIO(5),
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data zeus_leds_info = {
+ .leds = zeus_leds,
+ .num_leds = ARRAY_SIZE(zeus_leds),
+};
+
+static struct platform_device zeus_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &zeus_leds_info,
+ },
+};
+
+static void zeus_cf_reset(int state)
+{
+ u16 cpld_state = __raw_readw(ZEUS_CPLD_CONTROL);
+
+ if (state)
+ cpld_state |= ZEUS_CPLD_CONTROL_CF_RST;
+ else
+ cpld_state &= ~ZEUS_CPLD_CONTROL_CF_RST;
+
+ __raw_writew(cpld_state, ZEUS_CPLD_CONTROL);
+}
+
+static struct arcom_pcmcia_pdata zeus_pcmcia_info = {
+ .cd_gpio = ZEUS_CF_CD_GPIO,
+ .rdy_gpio = ZEUS_CF_RDY_GPIO,
+ .pwr_gpio = ZEUS_CF_PWEN_GPIO,
+ .reset = zeus_cf_reset,
+};
+
+static struct platform_device zeus_pcmcia_device = {
+ .name = "zeus-pcmcia",
+ .id = -1,
+ .dev = {
+ .platform_data = &zeus_pcmcia_info,
+ },
+};
+
+static struct resource zeus_max6369_resource = {
+ .start = ZEUS_CPLD_EXTWDOG_PHYS,
+ .end = ZEUS_CPLD_EXTWDOG_PHYS,
+ .flags = IORESOURCE_MEM,
+};
+
+struct platform_device zeus_max6369_device = {
+ .name = "max6369_wdt",
+ .id = -1,
+ .resource = &zeus_max6369_resource,
+ .num_resources = 1,
+};
+
+static struct platform_device *zeus_devices[] __initdata = {
+ &zeus_serial_device,
+ &zeus_mtd_devices[0],
+ &zeus_dm9k0_device,
+ &zeus_dm9k1_device,
+ &zeus_sram_device,
+ &zeus_leds_device,
+ &zeus_pcmcia_device,
+ &zeus_max6369_device,
+};
+
+/* AC'97 */
+static pxa2xx_audio_ops_t zeus_ac97_info = {
+ .reset_gpio = 95,
+};
+
+
+/*
+ * USB host
+ */
+
+static int zeus_ohci_init(struct device *dev)
+{
+ int err;
+
+ /* Switch on port 2. */
+ if ((err = gpio_request(ZEUS_USB2_PWREN_GPIO, "USB2_PWREN"))) {
+ dev_err(dev, "Can't request USB2_PWREN\n");
+ return err;
+ }
+
+ if ((err = gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 1))) {
+ gpio_free(ZEUS_USB2_PWREN_GPIO);
+ dev_err(dev, "Can't enable USB2_PWREN\n");
+ return err;
+ }
+
+ /* Port 2 is shared between host and client interface. */
+ UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+
+ return 0;
+}
+
+static void zeus_ohci_exit(struct device *dev)
+{
+ /* Power-off port 2 */
+ gpio_direction_output(ZEUS_USB2_PWREN_GPIO, 0);
+ gpio_free(ZEUS_USB2_PWREN_GPIO);
+}
+
+static struct pxaohci_platform_data zeus_ohci_platform_data = {
+ .port_mode = PMM_NPS_MODE,
+ /* Clear Power Control Polarity Low and set Power Sense
+ * Polarity Low. Supply power to USB ports. */
+ .flags = ENABLE_PORT_ALL | POWER_SENSE_LOW,
+ .init = zeus_ohci_init,
+ .exit = zeus_ohci_exit,
+};
+
+/*
+ * Flat Panel
+ */
+
+static void zeus_lcd_power(int on, struct fb_var_screeninfo *si)
+{
+ gpio_set_value(ZEUS_LCD_EN_GPIO, on);
+}
+
+static void zeus_backlight_power(int on)
+{
+ gpio_set_value(ZEUS_BKLEN_GPIO, on);
+}
+
+static int zeus_setup_fb_gpios(void)
+{
+ int err;
+
+ if ((err = gpio_request(ZEUS_LCD_EN_GPIO, "LCD_EN")))
+ goto out_err;
+
+ if ((err = gpio_direction_output(ZEUS_LCD_EN_GPIO, 0)))
+ goto out_err_lcd;
+
+ if ((err = gpio_request(ZEUS_BKLEN_GPIO, "BKLEN")))
+ goto out_err_lcd;
+
+ if ((err = gpio_direction_output(ZEUS_BKLEN_GPIO, 0)))
+ goto out_err_bkl;
+
+ return 0;
+
+out_err_bkl:
+ gpio_free(ZEUS_BKLEN_GPIO);
+out_err_lcd:
+ gpio_free(ZEUS_LCD_EN_GPIO);
+out_err:
+ return err;
+}
+
+static struct pxafb_mode_info zeus_fb_mode_info[] = {
+ {
+ .pixclock = 39722,
+
+ .xres = 640,
+ .yres = 480,
+
+ .bpp = 16,
+
+ .hsync_len = 63,
+ .left_margin = 16,
+ .right_margin = 81,
+
+ .vsync_len = 2,
+ .upper_margin = 12,
+ .lower_margin = 31,
+
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info zeus_fb_info = {
+ .modes = zeus_fb_mode_info,
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+ .pxafb_lcd_power = zeus_lcd_power,
+ .pxafb_backlight_power = zeus_backlight_power,
+};
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+
+static struct pxamci_platform_data zeus_mci_platform_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .detect_delay_ms = 250,
+ .gpio_card_detect = ZEUS_MMC_CD_GPIO,
+ .gpio_card_ro = ZEUS_MMC_WP_GPIO,
+ .gpio_card_ro_invert = 1,
+ .gpio_power = -1
+};
+
+/*
+ * USB Device Controller
+ */
+static void zeus_udc_command(int cmd)
+{
+ switch (cmd) {
+ case PXA2XX_UDC_CMD_DISCONNECT:
+ pr_info("zeus: disconnecting USB client\n");
+ UP2OCR = UP2OCR_HXOE | UP2OCR_HXS | UP2OCR_DMPDE | UP2OCR_DPPDE;
+ break;
+
+ case PXA2XX_UDC_CMD_CONNECT:
+ pr_info("zeus: connecting USB client\n");
+ UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE;
+ break;
+ }
+}
+
+static struct pxa2xx_udc_mach_info zeus_udc_info = {
+ .udc_command = zeus_udc_command,
+};
+
+#ifdef CONFIG_PM
+static void zeus_power_off(void)
+{
+ local_irq_disable();
+ pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET);
+}
+#else
+#define zeus_power_off NULL
+#endif
+
+#ifdef CONFIG_APM_EMULATION
+static void zeus_get_power_status(struct apm_power_info *info)
+{
+ /* Power supply is always present */
+ info->ac_line_status = APM_AC_ONLINE;
+ info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
+ info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT;
+}
+
+static inline void zeus_setup_apm(void)
+{
+ apm_get_power_status = zeus_get_power_status;
+}
+#else
+static inline void zeus_setup_apm(void)
+{
+}
+#endif
+
+static int zeus_get_pcb_info(struct i2c_client *client, unsigned gpio,
+ unsigned ngpio, void *context)
+{
+ int i;
+ u8 pcb_info = 0;
+
+ for (i = 0; i < 8; i++) {
+ int pcb_bit = gpio + i + 8;
+
+ if (gpio_request(pcb_bit, "pcb info")) {
+ dev_err(&client->dev, "Can't request pcb info %d\n", i);
+ continue;
+ }
+
+ if (gpio_direction_input(pcb_bit)) {
+ dev_err(&client->dev, "Can't read pcb info %d\n", i);
+ gpio_free(pcb_bit);
+ continue;
+ }
+
+ pcb_info |= !!gpio_get_value(pcb_bit) << i;
+
+ gpio_free(pcb_bit);
+ }
+
+ dev_info(&client->dev, "Zeus PCB version %d issue %d\n",
+ pcb_info >> 4, pcb_info & 0xf);
+
+ return 0;
+}
+
+static struct pca953x_platform_data zeus_pca953x_pdata[] = {
+ [0] = { .gpio_base = ZEUS_EXT0_GPIO_BASE, },
+ [1] = {
+ .gpio_base = ZEUS_EXT1_GPIO_BASE,
+ .setup = zeus_get_pcb_info,
+ },
+ [2] = { .gpio_base = ZEUS_USER_GPIO_BASE, },
+};
+
+static struct i2c_board_info __initdata zeus_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pca9535", 0x21),
+ .platform_data = &zeus_pca953x_pdata[0],
+ },
+ {
+ I2C_BOARD_INFO("pca9535", 0x22),
+ .platform_data = &zeus_pca953x_pdata[1],
+ },
+ {
+ I2C_BOARD_INFO("pca9535", 0x20),
+ .platform_data = &zeus_pca953x_pdata[2],
+ .irq = gpio_to_irq(ZEUS_EXTGPIO_GPIO),
+ },
+ { I2C_BOARD_INFO("lm75a", 0x48) },
+ { I2C_BOARD_INFO("24c01", 0x50) },
+ { I2C_BOARD_INFO("isl1208", 0x6f) },
+};
+
+static mfp_cfg_t zeus_pin_config[] __initdata = {
+ /* AC97 */
+ GPIO28_AC97_BITCLK,
+ GPIO29_AC97_SDATA_IN_0,
+ GPIO30_AC97_SDATA_OUT,
+ GPIO31_AC97_SYNC,
+
+ GPIO15_nCS_1,
+ GPIO78_nCS_2,
+ GPIO80_nCS_4,
+ GPIO33_nCS_5,
+
+ GPIO22_GPIO,
+ GPIO32_MMC_CLK,
+ GPIO92_MMC_DAT_0,
+ GPIO109_MMC_DAT_1,
+ GPIO110_MMC_DAT_2,
+ GPIO111_MMC_DAT_3,
+ GPIO112_MMC_CMD,
+
+ GPIO88_USBH1_PWR,
+ GPIO89_USBH1_PEN,
+ GPIO119_USBH2_PWR,
+ GPIO120_USBH2_PEN,
+
+ GPIO86_LCD_LDD_16,
+ GPIO87_LCD_LDD_17,
+
+ GPIO102_GPIO,
+ GPIO104_CIF_DD_2,
+ GPIO105_CIF_DD_1,
+
+ GPIO81_SSP3_TXD,
+ GPIO82_SSP3_RXD,
+ GPIO83_SSP3_SFRM,
+ GPIO84_SSP3_SCLK,
+
+ GPIO48_nPOE,
+ GPIO49_nPWE,
+ GPIO50_nPIOR,
+ GPIO51_nPIOW,
+ GPIO85_nPCE_1,
+ GPIO54_nPCE_2,
+ GPIO79_PSKTSEL,
+ GPIO55_nPREG,
+ GPIO56_nPWAIT,
+ GPIO57_nIOIS16,
+ GPIO36_GPIO, /* CF CD */
+ GPIO97_GPIO, /* CF PWREN */
+ GPIO99_GPIO, /* CF RDY */
+};
+
+/*
+ * DM9k MSCx settings: SRAM, 16 bits
+ * 17 cycles delay first access
+ * 5 cycles delay next access
+ * 13 cycles recovery time
+ * faster device
+ */
+#define DM9K_MSC_VALUE 0xe4c9
+
+static void __init zeus_init(void)
+{
+ u16 dm9000_msc = DM9K_MSC_VALUE;
+ u32 msc0, msc1;
+
+ system_rev = __raw_readw(ZEUS_CPLD_VERSION);
+ pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f));
+
+ /* Fix timings for dm9000s (CS1/CS2)*/
+ msc0 = (__raw_readl(MSC0) & 0x0000ffff) | (dm9000_msc << 16);
+ msc1 = (__raw_readl(MSC1) & 0xffff0000) | dm9000_msc;
+ __raw_writel(msc0, MSC0);
+ __raw_writel(msc1, MSC1);
+
+ pm_power_off = zeus_power_off;
+ zeus_setup_apm();
+
+ pxa2xx_mfp_config(ARRAY_AND_SIZE(zeus_pin_config));
+
+ platform_add_devices(zeus_devices, ARRAY_SIZE(zeus_devices));
+
+ pxa_set_ohci_info(&zeus_ohci_platform_data);
+
+ if (zeus_setup_fb_gpios())
+ pr_err("Failed to setup fb gpios\n");
+ else
+ pxa_set_fb_info(NULL, &zeus_fb_info);
+
+ pxa_set_mci_info(&zeus_mci_platform_data);
+ pxa_set_udc_info(&zeus_udc_info);
+ pxa_set_ac97_info(&zeus_ac97_info);
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(zeus_i2c_devices));
+ pxa2xx_set_spi_info(3, &pxa2xx_spi_ssp3_master_info);
+ spi_register_board_info(zeus_spi_board_info, ARRAY_SIZE(zeus_spi_board_info));
+}
+
+static struct map_desc zeus_io_desc[] __initdata = {
+ {
+ .virtual = ZEUS_CPLD_VERSION,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_VERSION_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = ZEUS_CPLD_ISA_IRQ,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_ISA_IRQ_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = ZEUS_CPLD_CONTROL,
+ .pfn = __phys_to_pfn(ZEUS_CPLD_CONTROL_PHYS),
+ .length = 0x1000,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = ZEUS_PC104IO,
+ .pfn = __phys_to_pfn(ZEUS_PC104IO_PHYS),
+ .length = 0x00800000,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init zeus_map_io(void)
+{
+ pxa27x_map_io();
+
+ iotable_init(zeus_io_desc, ARRAY_SIZE(zeus_io_desc));
+
+ /* Clear PSPR to ensure a full restart on wake-up. */
+ PMCR = PSPR = 0;
+
+ /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */
+ OSCC |= OSCC_OON;
+
+ /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...).
+ * float chip selects and PCMCIA */
+ PCFR = PCFR_OPDE | PCFR_DC_EN | PCFR_FS | PCFR_FP;
+}
+
+MACHINE_START(ARCOM_ZEUS, "Arcom/Eurotech ZEUS")
+ /* Maintainer: Marc Zyngier <maz@misterjones.org> */
+ .boot_params = 0xa0000100,
+ .map_io = zeus_map_io,
+ .nr_irqs = ZEUS_NR_IRQS,
+ .init_irq = zeus_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = zeus_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
new file mode 100644
index 00000000..5821185f
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -0,0 +1,431 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite.c
+ *
+ * Support for the PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2006 Marvell International Ltd.
+ *
+ * 2007-09-04: eric miao <eric.miao@marvell.com>
+ * rewrite to align with latest kernel
+ *
+ * This program is free software; you can 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/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/hardware.h>
+#include <mach/audio.h>
+#include <mach/pxafb.h>
+#include <mach/zylonite.h>
+#include <mach/mmc.h>
+#include <mach/ohci.h>
+#include <plat/pxa27x_keypad.h>
+#include <plat/pxa3xx_nand.h>
+
+#include "devices.h"
+#include "generic.h"
+
+int gpio_eth_irq;
+int gpio_debug_led1;
+int gpio_debug_led2;
+
+int wm9713_irq;
+
+int lcd_id;
+int lcd_orientation;
+
+struct platform_device pxa_device_wm9713_audio = {
+ .name = "wm9713-codec",
+ .id = -1,
+};
+
+static void __init zylonite_init_wm9713_audio(void)
+{
+ platform_device_register(&pxa_device_wm9713_audio);
+}
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = ZYLONITE_ETH_PHYS + 0x300,
+ .end = ZYLONITE_ETH_PHYS + 0xfffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = -1, /* for run-time assignment */
+ .end = -1,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct smc91x_platdata zylonite_smc91x_info = {
+ .flags = SMC91X_USE_8BIT | SMC91X_USE_16BIT |
+ SMC91X_NOWAIT | SMC91X_USE_DMA,
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+ .dev = {
+ .platform_data = &zylonite_smc91x_info,
+ },
+};
+
+#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+static struct gpio_led zylonite_debug_leds[] = {
+ [0] = {
+ .name = "zylonite:yellow:1",
+ .default_trigger = "heartbeat",
+ },
+ [1] = {
+ .name = "zylonite:yellow:2",
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data zylonite_debug_leds_info = {
+ .leds = zylonite_debug_leds,
+ .num_leds = ARRAY_SIZE(zylonite_debug_leds),
+};
+
+static struct platform_device zylonite_device_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &zylonite_debug_leds_info,
+ }
+};
+
+static void __init zylonite_init_leds(void)
+{
+ zylonite_debug_leds[0].gpio = gpio_debug_led1;
+ zylonite_debug_leds[1].gpio = gpio_debug_led2;
+
+ platform_device_register(&zylonite_device_leds);
+}
+#else
+static inline void zylonite_init_leds(void) {}
+#endif
+
+#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
+static struct platform_pwm_backlight_data zylonite_backlight_data = {
+ .pwm_id = 3,
+ .max_brightness = 100,
+ .dft_brightness = 100,
+ .pwm_period_ns = 10000,
+};
+
+static struct platform_device zylonite_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &pxa27x_device_pwm1.dev,
+ .platform_data = &zylonite_backlight_data,
+ },
+};
+
+static struct pxafb_mode_info toshiba_ltm035a776c_mode = {
+ .pixclock = 110000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 6,
+ .right_margin = 4,
+ .vsync_len = 2,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .sync = FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mode_info toshiba_ltm04c380k_mode = {
+ .pixclock = 50000,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .hsync_len = 1,
+ .left_margin = 0x9f,
+ .right_margin = 1,
+ .vsync_len = 44,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .sync = FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
+};
+
+static struct pxafb_mach_info zylonite_toshiba_lcd_info = {
+ .num_modes = 1,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static struct pxafb_mode_info sharp_ls037_modes[] = {
+ [0] = {
+ .pixclock = 158000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .hsync_len = 4,
+ .left_margin = 39,
+ .right_margin = 39,
+ .vsync_len = 1,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .sync = 0,
+ },
+ [1] = {
+ .pixclock = 39700,
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .hsync_len = 8,
+ .left_margin = 81,
+ .right_margin = 81,
+ .vsync_len = 1,
+ .upper_margin = 2,
+ .lower_margin = 7,
+ .sync = 0,
+ },
+};
+
+static struct pxafb_mach_info zylonite_sharp_lcd_info = {
+ .modes = sharp_ls037_modes,
+ .num_modes = 2,
+ .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL,
+};
+
+static void __init zylonite_init_lcd(void)
+{
+ platform_device_register(&zylonite_backlight_device);
+
+ if (lcd_id & 0x20) {
+ pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info);
+ return;
+ }
+
+ /* legacy LCD panels, it would be handy here if LCD panel type can
+ * be decided at run-time
+ */
+ if (1)
+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm035a776c_mode;
+ else
+ zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
+
+ pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info);
+}
+#else
+static inline void zylonite_init_lcd(void) {}
+#endif
+
+#if defined(CONFIG_MMC)
+static struct pxamci_platform_data zylonite_mci_platform_data = {
+ .detect_delay_ms= 200,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = EXT_GPIO(0),
+ .gpio_card_ro = EXT_GPIO(2),
+ .gpio_power = -1,
+};
+
+static struct pxamci_platform_data zylonite_mci2_platform_data = {
+ .detect_delay_ms= 200,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = EXT_GPIO(1),
+ .gpio_card_ro = EXT_GPIO(3),
+ .gpio_power = -1,
+};
+
+static struct pxamci_platform_data zylonite_mci3_platform_data = {
+ .detect_delay_ms= 200,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .gpio_card_detect = EXT_GPIO(30),
+ .gpio_card_ro = EXT_GPIO(31),
+ .gpio_power = -1,
+};
+
+static void __init zylonite_init_mmc(void)
+{
+ pxa_set_mci_info(&zylonite_mci_platform_data);
+ pxa3xx_set_mci2_info(&zylonite_mci2_platform_data);
+ if (cpu_is_pxa310())
+ pxa3xx_set_mci3_info(&zylonite_mci3_platform_data);
+}
+#else
+static inline void zylonite_init_mmc(void) {}
+#endif
+
+#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
+static unsigned int zylonite_matrix_key_map[] = {
+ /* KEY(row, col, key_code) */
+ KEY(0, 0, KEY_A), KEY(0, 1, KEY_B), KEY(0, 2, KEY_C), KEY(0, 5, KEY_D),
+ KEY(1, 0, KEY_E), KEY(1, 1, KEY_F), KEY(1, 2, KEY_G), KEY(1, 5, KEY_H),
+ KEY(2, 0, KEY_I), KEY(2, 1, KEY_J), KEY(2, 2, KEY_K), KEY(2, 5, KEY_L),
+ KEY(3, 0, KEY_M), KEY(3, 1, KEY_N), KEY(3, 2, KEY_O), KEY(3, 5, KEY_P),
+ KEY(5, 0, KEY_Q), KEY(5, 1, KEY_R), KEY(5, 2, KEY_S), KEY(5, 5, KEY_T),
+ KEY(6, 0, KEY_U), KEY(6, 1, KEY_V), KEY(6, 2, KEY_W), KEY(6, 5, KEY_X),
+ KEY(7, 1, KEY_Y), KEY(7, 2, KEY_Z),
+
+ KEY(4, 4, KEY_0), KEY(1, 3, KEY_1), KEY(4, 1, KEY_2), KEY(1, 4, KEY_3),
+ KEY(2, 3, KEY_4), KEY(4, 2, KEY_5), KEY(2, 4, KEY_6), KEY(3, 3, KEY_7),
+ KEY(4, 3, KEY_8), KEY(3, 4, KEY_9),
+
+ KEY(4, 5, KEY_SPACE),
+ KEY(5, 3, KEY_KPASTERISK), /* * */
+ KEY(5, 4, KEY_KPDOT), /* #" */
+
+ KEY(0, 7, KEY_UP),
+ KEY(1, 7, KEY_DOWN),
+ KEY(2, 7, KEY_LEFT),
+ KEY(3, 7, KEY_RIGHT),
+ KEY(2, 6, KEY_HOME),
+ KEY(3, 6, KEY_END),
+ KEY(6, 4, KEY_DELETE),
+ KEY(6, 6, KEY_BACK),
+ KEY(6, 3, KEY_CAPSLOCK), /* KEY_LEFTSHIFT), */
+
+ KEY(4, 6, KEY_ENTER), /* scroll push */
+ KEY(5, 7, KEY_ENTER), /* keypad action */
+
+ KEY(0, 4, KEY_EMAIL),
+ KEY(5, 6, KEY_SEND),
+ KEY(4, 0, KEY_CALENDAR),
+ KEY(7, 6, KEY_RECORD),
+ KEY(6, 7, KEY_VOLUMEUP),
+ KEY(7, 7, KEY_VOLUMEDOWN),
+
+ KEY(0, 6, KEY_F22), /* soft1 */
+ KEY(1, 6, KEY_F23), /* soft2 */
+ KEY(0, 3, KEY_AUX), /* contact */
+};
+
+static struct pxa27x_keypad_platform_data zylonite_keypad_info = {
+ .matrix_key_rows = 8,
+ .matrix_key_cols = 8,
+ .matrix_key_map = zylonite_matrix_key_map,
+ .matrix_key_map_size = ARRAY_SIZE(zylonite_matrix_key_map),
+
+ .enable_rotary0 = 1,
+ .rotary0_up_key = KEY_UP,
+ .rotary0_down_key = KEY_DOWN,
+
+ .debounce_interval = 30,
+};
+
+static void __init zylonite_init_keypad(void)
+{
+ pxa_set_keypad_info(&zylonite_keypad_info);
+}
+#else
+static inline void zylonite_init_keypad(void) {}
+#endif
+
+#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE)
+static struct mtd_partition zylonite_nand_partitions[] = {
+ [0] = {
+ .name = "Bootloader",
+ .offset = 0,
+ .size = 0x060000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [1] = {
+ .name = "Kernel",
+ .offset = 0x060000,
+ .size = 0x200000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ [2] = {
+ .name = "Filesystem",
+ .offset = 0x0260000,
+ .size = 0x3000000, /* 48M - rootfs */
+ },
+ [3] = {
+ .name = "MassStorage",
+ .offset = 0x3260000,
+ .size = 0x3d40000,
+ },
+ [4] = {
+ .name = "BBT",
+ .offset = 0x6FA0000,
+ .size = 0x80000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* NOTE: we reserve some blocks at the end of the NAND flash for
+ * bad block management, and the max number of relocation blocks
+ * differs on different platforms. Please take care with it when
+ * defining the partition table.
+ */
+};
+
+static struct pxa3xx_nand_platform_data zylonite_nand_info = {
+ .enable_arbiter = 1,
+ .parts = zylonite_nand_partitions,
+ .nr_parts = ARRAY_SIZE(zylonite_nand_partitions),
+};
+
+static void __init zylonite_init_nand(void)
+{
+ pxa3xx_set_nand_info(&zylonite_nand_info);
+}
+#else
+static inline void zylonite_init_nand(void) {}
+#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+static struct pxaohci_platform_data zylonite_ohci_info = {
+ .port_mode = PMM_PERPORT_MODE,
+ .flags = ENABLE_PORT1 | ENABLE_PORT2 |
+ POWER_CONTROL_LOW | POWER_SENSE_LOW,
+};
+
+static void __init zylonite_init_ohci(void)
+{
+ pxa_set_ohci_info(&zylonite_ohci_info);
+}
+#else
+static inline void zylonite_init_ohci(void) {}
+#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */
+
+static void __init zylonite_init(void)
+{
+ pxa_set_ffuart_info(NULL);
+ pxa_set_btuart_info(NULL);
+ pxa_set_stuart_info(NULL);
+
+ /* board-processor specific initialization */
+ zylonite_pxa300_init();
+ zylonite_pxa320_init();
+
+ /*
+ * Note: We depend that the bootloader set
+ * the correct value to MSC register for SMC91x.
+ */
+ smc91x_resources[1].start = gpio_to_irq(gpio_eth_irq);
+ smc91x_resources[1].end = gpio_to_irq(gpio_eth_irq);
+ platform_device_register(&smc91x_device);
+
+ pxa_set_ac97_info(NULL);
+ zylonite_init_lcd();
+ zylonite_init_mmc();
+ zylonite_init_keypad();
+ zylonite_init_nand();
+ zylonite_init_leds();
+ zylonite_init_ohci();
+ zylonite_init_wm9713_audio();
+}
+
+MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
+ .boot_params = 0xa0000100,
+ .map_io = pxa3xx_map_io,
+ .nr_irqs = ZYLONITE_NR_IRQS,
+ .init_irq = pxa3xx_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = zylonite_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
new file mode 100644
index 00000000..93c64d8d
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -0,0 +1,280 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite_pxa300.c
+ *
+ * PXA300/PXA310 specific support code for the
+ * PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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/i2c.h>
+#include <linux/i2c/pxa-i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/gpio.h>
+
+#include <mach/pxa300.h>
+#include <mach/zylonite.h>
+
+#include "generic.h"
+
+/* PXA300/PXA310 common configurations */
+static mfp_cfg_t common_mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO54_LCD_LDD_0,
+ GPIO55_LCD_LDD_1,
+ GPIO56_LCD_LDD_2,
+ GPIO57_LCD_LDD_3,
+ GPIO58_LCD_LDD_4,
+ GPIO59_LCD_LDD_5,
+ GPIO60_LCD_LDD_6,
+ GPIO61_LCD_LDD_7,
+ GPIO62_LCD_LDD_8,
+ GPIO63_LCD_LDD_9,
+ GPIO64_LCD_LDD_10,
+ GPIO65_LCD_LDD_11,
+ GPIO66_LCD_LDD_12,
+ GPIO67_LCD_LDD_13,
+ GPIO68_LCD_LDD_14,
+ GPIO69_LCD_LDD_15,
+ GPIO70_LCD_LDD_16,
+ GPIO71_LCD_LDD_17,
+ GPIO72_LCD_FCLK,
+ GPIO73_LCD_LCLK,
+ GPIO74_LCD_PCLK,
+ GPIO75_LCD_BIAS,
+ GPIO76_LCD_VSYNC,
+ GPIO127_LCD_CS_N,
+ GPIO20_PWM3_OUT, /* backlight */
+
+ /* BTUART */
+ GPIO111_UART2_RTS,
+ GPIO112_UART2_RXD | MFP_LPM_EDGE_FALL,
+ GPIO113_UART2_TXD,
+ GPIO114_UART2_CTS | MFP_LPM_EDGE_BOTH,
+
+ /* STUART */
+ GPIO109_UART3_TXD,
+ GPIO110_UART3_RXD | MFP_LPM_EDGE_FALL,
+
+ /* AC97 */
+ GPIO23_AC97_nACRESET,
+ GPIO24_AC97_SYSCLK,
+ GPIO29_AC97_BITCLK,
+ GPIO25_AC97_SDATA_IN_0,
+ GPIO27_AC97_SDATA_OUT,
+ GPIO28_AC97_SYNC,
+ GPIO17_GPIO, /* SDATA_IN_1 but unused - configure to GPIO */
+
+ /* SSP3 */
+ GPIO91_SSP3_SCLK,
+ GPIO92_SSP3_FRM,
+ GPIO93_SSP3_TXD,
+ GPIO94_SSP3_RXD,
+
+ /* WM9713 IRQ */
+ GPIO26_GPIO,
+
+ /* Keypad */
+ GPIO107_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
+ GPIO108_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
+ GPIO115_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+ GPIO116_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+ GPIO117_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+ GPIO118_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+ GPIO119_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+ GPIO120_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+ GPIO2_2_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+ GPIO3_2_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+ GPIO4_2_KP_MKOUT_5,
+ GPIO5_2_KP_MKOUT_6,
+ GPIO6_2_KP_MKOUT_7,
+
+ /* MMC1 */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD, /* CMD0 for slot 0 */
+ GPIO15_GPIO, /* CMD1 default as GPIO for slot 0 */
+
+ /* MMC2 */
+ GPIO9_MMC2_DAT0,
+ GPIO10_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO11_MMC2_DAT2,
+ GPIO12_MMC2_DAT3,
+ GPIO13_MMC2_CLK,
+ GPIO14_MMC2_CMD,
+
+ /* USB Host */
+ GPIO0_2_USBH_PEN,
+ GPIO1_2_USBH_PWR,
+
+ /* Standard I2C */
+ GPIO21_I2C_SCL,
+ GPIO22_I2C_SDA,
+
+ /* GPIO */
+ GPIO18_GPIO | MFP_PULL_HIGH, /* GPIO Expander #0 INT_N */
+ GPIO19_GPIO | MFP_PULL_HIGH, /* GPIO Expander #1 INT_N */
+};
+
+static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
+ /* FFUART */
+ GPIO30_UART1_RXD | MFP_LPM_EDGE_FALL,
+ GPIO31_UART1_TXD,
+ GPIO32_UART1_CTS,
+ GPIO37_UART1_RTS,
+ GPIO33_UART1_DCD,
+ GPIO34_UART1_DSR | MFP_LPM_EDGE_FALL,
+ GPIO35_UART1_RI,
+ GPIO36_UART1_DTR,
+
+ /* Ethernet */
+ GPIO2_nCS3,
+ GPIO99_GPIO,
+};
+
+static mfp_cfg_t pxa310_mfp_cfg[] __initdata = {
+ /* FFUART */
+ GPIO99_UART1_RXD | MFP_LPM_EDGE_FALL,
+ GPIO100_UART1_TXD,
+ GPIO101_UART1_CTS,
+ GPIO106_UART1_RTS,
+
+ /* Ethernet */
+ GPIO2_nCS3,
+ GPIO102_GPIO,
+
+ /* MMC3 */
+ GPIO7_2_MMC3_DAT0,
+ GPIO8_2_MMC3_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO9_2_MMC3_DAT2,
+ GPIO10_2_MMC3_DAT3,
+ GPIO103_MMC3_CLK,
+ GPIO105_MMC3_CMD,
+};
+
+#define NUM_LCD_DETECT_PINS 7
+
+static int lcd_detect_pins[] __initdata = {
+ MFP_PIN_GPIO71, /* LCD_LDD_17 - ORIENT */
+ MFP_PIN_GPIO70, /* LCD_LDD_16 - LCDID[5] */
+ MFP_PIN_GPIO75, /* LCD_BIAS - LCDID[4] */
+ MFP_PIN_GPIO73, /* LCD_LCLK - LCDID[3] */
+ MFP_PIN_GPIO72, /* LCD_FCLK - LCDID[2] */
+ MFP_PIN_GPIO127,/* LCD_CS_N - LCDID[1] */
+ MFP_PIN_GPIO76, /* LCD_VSYNC - LCDID[0] */
+};
+
+static void __init zylonite_detect_lcd_panel(void)
+{
+ unsigned long mfpr_save[NUM_LCD_DETECT_PINS];
+ int i, gpio, id = 0;
+
+ /* save the original MFP settings of these pins and configure
+ * them as GPIO Input, DS01X, Pull Neither, Edge Clear
+ */
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
+ pxa3xx_mfp_write(lcd_detect_pins[i], 0x8440);
+ }
+
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ id = id << 1;
+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
+ gpio_request(gpio, "LCD_ID_PINS");
+ gpio_direction_input(gpio);
+
+ if (gpio_get_value(gpio))
+ id = id | 0x1;
+ gpio_free(gpio);
+ }
+
+ /* lcd id, flush out bit 1 */
+ lcd_id = id & 0x3d;
+
+ /* lcd orientation, portrait or landscape */
+ lcd_orientation = (id >> 6) & 0x1;
+
+ /* restore the original MFP settings */
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++)
+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+}
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+static struct pca953x_platform_data gpio_exp[] = {
+ [0] = {
+ .gpio_base = 128,
+ },
+ [1] = {
+ .gpio_base = 144,
+ },
+};
+
+static struct i2c_board_info zylonite_i2c_board_info[] = {
+ {
+ .type = "pca9539",
+ .addr = 0x74,
+ .platform_data = &gpio_exp[0],
+ .irq = IRQ_GPIO(18),
+ }, {
+ .type = "pca9539",
+ .addr = 0x75,
+ .platform_data = &gpio_exp[1],
+ .irq = IRQ_GPIO(19),
+ },
+};
+
+static void __init zylonite_init_i2c(void)
+{
+ pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(zylonite_i2c_board_info));
+}
+#else
+static inline void zylonite_init_i2c(void) {}
+#endif
+
+void __init zylonite_pxa300_init(void)
+{
+ if (cpu_is_pxa300() || cpu_is_pxa310()) {
+ /* initialize MFP */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(common_mfp_cfg));
+
+ /* detect LCD panel */
+ zylonite_detect_lcd_panel();
+
+ /* WM9713 IRQ */
+ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO26);
+
+ zylonite_init_i2c();
+ }
+
+ if (cpu_is_pxa300()) {
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa300_mfp_cfg));
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO99);
+ }
+
+ if (cpu_is_pxa310()) {
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(pxa310_mfp_cfg));
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO102);
+ }
+
+ /* GPIOs for Debug LEDs */
+ gpio_debug_led1 = EXT_GPIO(25);
+ gpio_debug_led2 = EXT_GPIO(26);
+}
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
new file mode 100644
index 00000000..9942bac4
--- /dev/null
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -0,0 +1,215 @@
+/*
+ * linux/arch/arm/mach-pxa/zylonite_pxa320.c
+ *
+ * PXA320 specific support code for the
+ * PXA3xx Development Platform (aka Zylonite)
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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/gpio.h>
+
+#include <mach/pxa320.h>
+#include <mach/zylonite.h>
+
+#include "generic.h"
+
+static mfp_cfg_t mfp_cfg[] __initdata = {
+ /* LCD */
+ GPIO6_2_LCD_LDD_0,
+ GPIO7_2_LCD_LDD_1,
+ GPIO8_2_LCD_LDD_2,
+ GPIO9_2_LCD_LDD_3,
+ GPIO10_2_LCD_LDD_4,
+ GPIO11_2_LCD_LDD_5,
+ GPIO12_2_LCD_LDD_6,
+ GPIO13_2_LCD_LDD_7,
+ GPIO63_LCD_LDD_8,
+ GPIO64_LCD_LDD_9,
+ GPIO65_LCD_LDD_10,
+ GPIO66_LCD_LDD_11,
+ GPIO67_LCD_LDD_12,
+ GPIO68_LCD_LDD_13,
+ GPIO69_LCD_LDD_14,
+ GPIO70_LCD_LDD_15,
+ GPIO71_LCD_LDD_16,
+ GPIO72_LCD_LDD_17,
+ GPIO73_LCD_CS_N,
+ GPIO74_LCD_VSYNC,
+ GPIO14_2_LCD_FCLK,
+ GPIO15_2_LCD_LCLK,
+ GPIO16_2_LCD_PCLK,
+ GPIO17_2_LCD_BIAS,
+ GPIO14_PWM3_OUT, /* backlight */
+
+ /* FFUART */
+ GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL,
+ GPIO42_UART1_TXD,
+ GPIO43_UART1_CTS,
+ GPIO44_UART1_DCD,
+ GPIO45_UART1_DSR | MFP_LPM_EDGE_FALL,
+ GPIO46_UART1_RI,
+ GPIO47_UART1_DTR,
+ GPIO48_UART1_RTS,
+
+ /* AC97 */
+ GPIO34_AC97_SYSCLK,
+ GPIO35_AC97_SDATA_IN_0,
+ GPIO37_AC97_SDATA_OUT,
+ GPIO38_AC97_SYNC,
+ GPIO39_AC97_BITCLK,
+ GPIO40_AC97_nACRESET,
+ GPIO36_GPIO, /* SDATA_IN_1 but unused - configure to GPIO */
+
+ /* SSP3 */
+ GPIO89_SSP3_SCLK,
+ GPIO90_SSP3_FRM,
+ GPIO91_SSP3_TXD,
+ GPIO92_SSP3_RXD,
+
+ /* WM9713 IRQ */
+ GPIO15_GPIO,
+
+ /* I2C */
+ GPIO32_I2C_SCL,
+ GPIO33_I2C_SDA,
+
+ /* Keypad */
+ GPIO105_KP_DKIN_0 | MFP_LPM_EDGE_BOTH,
+ GPIO106_KP_DKIN_1 | MFP_LPM_EDGE_BOTH,
+ GPIO113_KP_MKIN_0 | MFP_LPM_EDGE_BOTH,
+ GPIO114_KP_MKIN_1 | MFP_LPM_EDGE_BOTH,
+ GPIO115_KP_MKIN_2 | MFP_LPM_EDGE_BOTH,
+ GPIO116_KP_MKIN_3 | MFP_LPM_EDGE_BOTH,
+ GPIO117_KP_MKIN_4 | MFP_LPM_EDGE_BOTH,
+ GPIO118_KP_MKIN_5 | MFP_LPM_EDGE_BOTH,
+ GPIO119_KP_MKIN_6 | MFP_LPM_EDGE_BOTH,
+ GPIO120_KP_MKIN_7 | MFP_LPM_EDGE_BOTH,
+ GPIO121_KP_MKOUT_0,
+ GPIO122_KP_MKOUT_1,
+ GPIO123_KP_MKOUT_2,
+ GPIO124_KP_MKOUT_3,
+ GPIO125_KP_MKOUT_4,
+ GPIO126_KP_MKOUT_5,
+ GPIO127_KP_MKOUT_6,
+ GPIO5_2_KP_MKOUT_7,
+
+ /* Ethernet */
+ GPIO4_nCS3,
+ GPIO90_GPIO,
+
+ /* MMC1 */
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
+ GPIO31_GPIO, /* CMD1 default as GPIO for slot 0 */
+
+ /* MMC2 */
+ GPIO24_MMC2_DAT0,
+ GPIO25_MMC2_DAT1 | MFP_LPM_EDGE_BOTH,
+ GPIO26_MMC2_DAT2,
+ GPIO27_MMC2_DAT3,
+ GPIO28_MMC2_CLK,
+ GPIO29_MMC2_CMD,
+
+ /* USB Host */
+ GPIO2_2_USBH_PEN,
+ GPIO3_2_USBH_PWR,
+
+ /* Debug LEDs */
+ GPIO1_2_GPIO | MFP_LPM_DRIVE_HIGH,
+ GPIO4_2_GPIO | MFP_LPM_DRIVE_HIGH,
+};
+
+#define NUM_LCD_DETECT_PINS 7
+
+static int lcd_detect_pins[] __initdata = {
+ MFP_PIN_GPIO72, /* LCD_LDD_17 - ORIENT */
+ MFP_PIN_GPIO71, /* LCD_LDD_16 - LCDID[5] */
+ MFP_PIN_GPIO17_2, /* LCD_BIAS - LCDID[4] */
+ MFP_PIN_GPIO15_2, /* LCD_LCLK - LCDID[3] */
+ MFP_PIN_GPIO14_2, /* LCD_FCLK - LCDID[2] */
+ MFP_PIN_GPIO73, /* LCD_CS_N - LCDID[1] */
+ MFP_PIN_GPIO74, /* LCD_VSYNC - LCDID[0] */
+ /*
+ * set the MFP_PIN_GPIO 14/15/17 to alternate function other than
+ * GPIO to avoid input level confliction with 14_2, 15_2, 17_2
+ */
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO17,
+};
+
+static int lcd_detect_mfpr[] __initdata = {
+ /* AF0, DS 1X, Pull Neither, Edge Clear */
+ 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440, 0x8440,
+ 0xc442, /* Backlight, Pull-Up, AF2 */
+ 0x8445, /* AF5 */
+ 0x8445, /* AF5 */
+};
+
+static void __init zylonite_detect_lcd_panel(void)
+{
+ unsigned long mfpr_save[ARRAY_SIZE(lcd_detect_pins)];
+ int i, gpio, id = 0;
+
+ /* save the original MFP settings of these pins and configure them
+ * as GPIO Input, DS01X, Pull Neither, Edge Clear
+ */
+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++) {
+ mfpr_save[i] = pxa3xx_mfp_read(lcd_detect_pins[i]);
+ pxa3xx_mfp_write(lcd_detect_pins[i], lcd_detect_mfpr[i]);
+ }
+
+ for (i = 0; i < NUM_LCD_DETECT_PINS; i++) {
+ id = id << 1;
+ gpio = mfp_to_gpio(lcd_detect_pins[i]);
+ gpio_request(gpio, "LCD_ID_PINS");
+ gpio_direction_input(gpio);
+
+ if (gpio_get_value(gpio))
+ id = id | 0x1;
+ gpio_free(gpio);
+ }
+
+ /* lcd id, flush out bit 1 */
+ lcd_id = id & 0x3d;
+
+ /* lcd orientation, portrait or landscape */
+ lcd_orientation = (id >> 6) & 0x1;
+
+ /* restore the original MFP settings */
+ for (i = 0; i < ARRAY_SIZE(lcd_detect_pins); i++)
+ pxa3xx_mfp_write(lcd_detect_pins[i], mfpr_save[i]);
+}
+
+void __init zylonite_pxa320_init(void)
+{
+ if (cpu_is_pxa320()) {
+ /* initialize MFP */
+ pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_cfg));
+
+ /* detect LCD panel */
+ zylonite_detect_lcd_panel();
+
+ /* GPIO pin assignment */
+ gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
+ gpio_debug_led1 = mfp_to_gpio(MFP_PIN_GPIO1_2);
+ gpio_debug_led2 = mfp_to_gpio(MFP_PIN_GPIO4_2);
+
+ /* WM9713 IRQ */
+ wm9713_irq = mfp_to_gpio(MFP_PIN_GPIO15);
+ }
+}
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
new file mode 100644
index 00000000..b9a9805e
--- /dev/null
+++ b/arch/arm/mach-realview/Kconfig
@@ -0,0 +1,98 @@
+menu "RealView platform type"
+ depends on ARCH_REALVIEW
+
+config MACH_REALVIEW_EB
+ bool "Support RealView(R) Emulation Baseboard"
+ select ARM_GIC
+ help
+ Include support for the ARM(R) RealView(R) Emulation Baseboard
+ platform.
+
+config REALVIEW_EB_A9MP
+ bool "Support Multicore Cortex-A9 Tile"
+ depends on MACH_REALVIEW_EB
+ select CPU_V7
+ help
+ Enable support for the Cortex-A9MPCore tile fitted to the
+ Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM11MP
+ bool "Support ARM11MPCore Tile"
+ depends on MACH_REALVIEW_EB
+ select CPU_V6K
+ select ARCH_HAS_BARRIERS if SMP
+ help
+ Enable support for the ARM11MPCore tile fitted to the Realview(R)
+ Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM11MP_REVB
+ bool "Support ARM11MPCore RevB Tile"
+ depends on REALVIEW_EB_ARM11MP
+ help
+ Enable support for the ARM11MPCore Revision B tile on the
+ Realview(R) Emulation Baseboard platform. Since there are device
+ address differences, a kernel built with this option enabled is
+ not compatible with other revisions of the ARM11MPCore tile.
+
+config MACH_REALVIEW_PB11MP
+ bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
+ select CPU_V6K
+ select ARM_GIC
+ select HAVE_PATA_PLATFORM
+ select ARCH_HAS_BARRIERS if SMP
+ help
+ Include support for the ARM(R) RealView(R) Platform Baseboard for
+ the ARM11MPCore. This platform has an on-board ARM11MPCore and has
+ support for PCI-E and Compact Flash.
+
+# ARMv6 CPU without K extensions, but does have the new exclusive ops
+config MACH_REALVIEW_PB1176
+ bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
+ select CPU_V6
+ select ARM_GIC
+ help
+ Include support for the ARM(R) RealView(R) Platform Baseboard for
+ ARM1176JZF-S.
+
+config REALVIEW_PB1176_SECURE_FLASH
+ bool "Allow access to the secure flash memory block"
+ depends on MACH_REALVIEW_PB1176
+ default n
+ help
+ Select this option if Linux will only run in secure mode on the
+ RealView PB1176 platform and access to the secure flash memory
+ block (64MB @ 0x3c000000) is required.
+
+config MACH_REALVIEW_PBA8
+ bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
+ select CPU_V7
+ select ARM_GIC
+ select HAVE_PATA_PLATFORM
+ help
+ Include support for the ARM(R) RealView Platform Baseboard for
+ Cortex(tm)-A8. This platform has an on-board Cortex-A8 and has
+ support for PCI-E and Compact Flash.
+
+config MACH_REALVIEW_PBX
+ bool "Support RealView(R) Platform Baseboard Explore"
+ select ARM_GIC
+ select HAVE_PATA_PLATFORM
+ select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
+ select ZONE_DMA if SPARSEMEM
+ help
+ Include support for the ARM(R) RealView(R) Platform Baseboard
+ Explore.
+
+config REALVIEW_HIGH_PHYS_OFFSET
+ bool "High physical base address for the RealView platform"
+ depends on MMU && !MACH_REALVIEW_PB1176
+ default y
+ help
+ RealView boards other than PB1176 have the RAM available at
+ 0x70000000, 256MB of which being mirrored at 0x00000000. If
+ the board supports 512MB of RAM, this option allows the
+ memory to be accessed contiguously at the high physical
+ offset. On the PBX board, disabling this option allows 1GB of
+ RAM to be used with SPARSEMEM.
+
+endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
new file mode 100644
index 00000000..541fa4c1
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o
+obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
+obj-$(CONFIG_MACH_REALVIEW_PB11MP) += realview_pb11mp.o
+obj-$(CONFIG_MACH_REALVIEW_PB1176) += realview_pb1176.o
+obj-$(CONFIG_MACH_REALVIEW_PBA8) += realview_pba8.o
+obj-$(CONFIG_MACH_REALVIEW_PBX) += realview_pbx.o
+obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot
new file mode 100644
index 00000000..d97e003d
--- /dev/null
+++ b/arch/arm/mach-realview/Makefile.boot
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y)
+ zreladdr-y := 0x70008000
+params_phys-y := 0x70000100
+initrd_phys-y := 0x70800000
+else
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+endif
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
new file mode 100644
index 00000000..5c23450d
--- /dev/null
+++ b/arch/arm/mach-realview/core.c
@@ -0,0 +1,536 @@
+/*
+ * linux/arch/arm/mach-realview/core.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/ata_platform.h>
+#include <linux/amba/mmci.h>
+#include <linux/gfp.h>
+#include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware/gic.h>
+
+#include <mach/platform.h>
+#include <mach/irqs.h>
+#include <asm/hardware/timer-sp.h>
+
+#include <plat/clcd.h>
+#include <plat/sched_clock.h>
+
+#include "core.h"
+
+#define REALVIEW_FLASHCTRL (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
+
+static void realview_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ u32 val;
+
+ val = __raw_readl(REALVIEW_FLASHCTRL);
+ if (on)
+ val |= REALVIEW_FLASHPROG_FLVPPEN;
+ else
+ val &= ~REALVIEW_FLASHPROG_FLVPPEN;
+ __raw_writel(val, REALVIEW_FLASHCTRL);
+}
+
+static struct physmap_flash_data realview_flash_data = {
+ .width = 4,
+ .set_vpp = realview_flash_set_vpp,
+};
+
+struct platform_device realview_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &realview_flash_data,
+ },
+};
+
+int realview_flash_register(struct resource *res, u32 num)
+{
+ realview_flash_device.resource = res;
+ realview_flash_device.num_resources = num;
+ return platform_device_register(&realview_flash_device);
+}
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device realview_eth_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = 2,
+};
+
+int realview_eth_register(const char *name, struct resource *res)
+{
+ if (name)
+ realview_eth_device.name = name;
+ realview_eth_device.resource = res;
+ if (strcmp(realview_eth_device.name, "smsc911x") == 0)
+ realview_eth_device.dev.platform_data = &smsc911x_config;
+
+ return platform_device_register(&realview_eth_device);
+}
+
+struct platform_device realview_usb_device = {
+ .name = "isp1760",
+ .num_resources = 2,
+};
+
+int realview_usb_register(struct resource *res)
+{
+ realview_usb_device.resource = res;
+ return platform_device_register(&realview_usb_device);
+}
+
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 1,
+};
+
+static struct resource pata_resources[] = {
+ [0] = {
+ .start = REALVIEW_CF_BASE,
+ .end = REALVIEW_CF_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_CF_BASE + 0x100,
+ .end = REALVIEW_CF_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device realview_cf_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_resources),
+ .resource = pata_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ },
+};
+
+static struct resource realview_i2c_resource = {
+ .start = REALVIEW_I2C_BASE,
+ .end = REALVIEW_I2C_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+struct platform_device realview_i2c_device = {
+ .name = "versatile-i2c",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &realview_i2c_resource,
+};
+
+static struct i2c_board_info realview_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
+ },
+};
+
+static int __init realview_i2c_init(void)
+{
+ return i2c_register_board_info(0, realview_i2c_board_info,
+ ARRAY_SIZE(realview_i2c_board_info));
+}
+arch_initcall(realview_i2c_init);
+
+#define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET)
+
+/*
+ * This is only used if GPIOLIB support is disabled
+ */
+static unsigned int realview_mmc_status(struct device *dev)
+{
+ struct amba_device *adev = container_of(dev, struct amba_device, dev);
+ u32 mask;
+
+ if (machine_is_realview_pb1176()) {
+ static bool inserted = false;
+
+ /*
+ * The PB1176 does not have the status register,
+ * assume it is inserted at startup, then invert
+ * for each call so card insertion/removal will
+ * be detected anyway. This will not be called if
+ * GPIO on PL061 is active, which is the proper
+ * way to do this on the PB1176.
+ */
+ inserted = !inserted;
+ return inserted ? 0 : 1;
+ }
+
+ if (adev->res.start == REALVIEW_MMCI0_BASE)
+ mask = 1;
+ else
+ mask = 2;
+
+ return readl(REALVIEW_SYSMCI) & mask;
+}
+
+struct mmci_platform_data realview_mmc0_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = realview_mmc_status,
+ .gpio_wp = 17,
+ .gpio_cd = 16,
+ .cd_invert = true,
+};
+
+struct mmci_platform_data realview_mmc1_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = realview_mmc_status,
+ .gpio_wp = 19,
+ .gpio_cd = 18,
+ .cd_invert = true,
+};
+
+/*
+ * Clock handling
+ */
+static const struct icst_params realview_oscvco_params = {
+ .ref = 24000000,
+ .vco_max = ICST307_VCO_MAX,
+ .vco_min = ICST307_VCO_MIN,
+ .vd_min = 4 + 8,
+ .vd_max = 511 + 8,
+ .rd_min = 1 + 2,
+ .rd_max = 127 + 2,
+ .s2div = icst307_s2div,
+ .idx2s = icst307_idx2s,
+};
+
+static void realview_oscvco_set(struct clk *clk, struct icst_vco vco)
+{
+ void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET;
+ u32 val;
+
+ val = readl(clk->vcoreg) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, sys_lock);
+ writel(val, clk->vcoreg);
+ writel(0, sys_lock);
+}
+
+static const struct clk_ops oscvco_clk_ops = {
+ .round = icst_clk_round,
+ .set = icst_clk_set,
+ .setvco = realview_oscvco_set,
+};
+
+static struct clk oscvco_clk = {
+ .ops = &oscvco_clk_ops,
+ .params = &realview_oscvco_params,
+};
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk ref24_clk = {
+ .rate = 24000000,
+};
+
+static struct clk sp804_clk = {
+ .rate = 1000000,
+};
+
+static struct clk dummy_apb_pclk;
+
+static struct clk_lookup lookups[] = {
+ { /* Bus clock */
+ .con_id = "apb_pclk",
+ .clk = &dummy_apb_pclk,
+ }, { /* UART0 */
+ .dev_id = "dev:uart0",
+ .clk = &ref24_clk,
+ }, { /* UART1 */
+ .dev_id = "dev:uart1",
+ .clk = &ref24_clk,
+ }, { /* UART2 */
+ .dev_id = "dev:uart2",
+ .clk = &ref24_clk,
+ }, { /* UART3 */
+ .dev_id = "fpga:uart3",
+ .clk = &ref24_clk,
+ }, { /* UART3 is on the dev chip in PB1176 */
+ .dev_id = "dev:uart3",
+ .clk = &ref24_clk,
+ }, { /* UART4 only exists in PB1176 */
+ .dev_id = "fpga:uart4",
+ .clk = &ref24_clk,
+ }, { /* KMI0 */
+ .dev_id = "fpga:kmi0",
+ .clk = &ref24_clk,
+ }, { /* KMI1 */
+ .dev_id = "fpga:kmi1",
+ .clk = &ref24_clk,
+ }, { /* MMC0 */
+ .dev_id = "fpga:mmc0",
+ .clk = &ref24_clk,
+ }, { /* CLCD is in the PB1176 and EB DevChip */
+ .dev_id = "dev:clcd",
+ .clk = &oscvco_clk,
+ }, { /* PB:CLCD */
+ .dev_id = "issp:clcd",
+ .clk = &oscvco_clk,
+ }, { /* SSP */
+ .dev_id = "dev:ssp0",
+ .clk = &ref24_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .clk = &sp804_clk,
+ },
+};
+
+void __init realview_init_early(void)
+{
+ void __iomem *sys = __io_address(REALVIEW_SYS_BASE);
+
+ if (machine_is_realview_pb1176())
+ oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC0_OFFSET;
+ else
+ oscvco_clk.vcoreg = sys + REALVIEW_SYS_OSC4_OFFSET;
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ versatile_sched_clock_init(sys + REALVIEW_SYS_24MHz_OFFSET, 24000000);
+}
+
+/*
+ * CLCD support.
+ */
+#define SYS_CLCD_NLCDIOON (1 << 2)
+#define SYS_CLCD_VDDPOSSWITCH (1 << 3)
+#define SYS_CLCD_PWR3V5SWITCH (1 << 4)
+#define SYS_CLCD_ID_MASK (0x1f << 8)
+#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
+#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
+#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
+#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
+#define SYS_CLCD_ID_VGA (0x1f << 8)
+
+/*
+ * Disable all display connectors on the interface module.
+ */
+static void realview_clcd_disable(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+}
+
+/*
+ * Enable the relevant connector on the interface module.
+ */
+static void realview_clcd_enable(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ u32 val;
+
+ /*
+ * Enable the PSUs
+ */
+ val = readl(sys_clcd);
+ val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+}
+
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure. Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
+static int realview_clcd_setup(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_CLCD_OFFSET;
+ const char *panel_name, *vga_panel_name;
+ unsigned long framesize;
+ u32 val;
+
+ if (machine_is_realview_eb()) {
+ /* VGA, 16bpp */
+ framesize = 640 * 480 * 2;
+ vga_panel_name = "VGA";
+ } else {
+ /* XVGA, 16bpp */
+ framesize = 1024 * 768 * 2;
+ vga_panel_name = "XVGA";
+ }
+
+ val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+ if (val == SYS_CLCD_ID_SANYO_3_8)
+ panel_name = "Sanyo TM38QV67A02A";
+ else if (val == SYS_CLCD_ID_SANYO_2_5)
+ panel_name = "Sanyo QVGA Portrait";
+ else if (val == SYS_CLCD_ID_EPSON_2_2)
+ panel_name = "Epson L2F50113T00";
+ else if (val == SYS_CLCD_ID_VGA)
+ panel_name = vga_panel_name;
+ else {
+ pr_err("CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val);
+ panel_name = vga_panel_name;
+ }
+
+ fb->panel = versatile_clcd_get_panel(panel_name);
+ if (!fb->panel)
+ return -EINVAL;
+
+ return versatile_clcd_setup_dma(fb, framesize);
+}
+
+struct clcd_board clcd_plat_data = {
+ .name = "RealView",
+ .caps = CLCD_CAP_ALL,
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .disable = realview_clcd_disable,
+ .enable = realview_clcd_enable,
+ .setup = realview_clcd_setup,
+ .mmap = versatile_clcd_mmap_dma,
+ .remove = versatile_clcd_remove_dma,
+};
+
+#ifdef CONFIG_LEDS
+#define VA_LEDS_BASE (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
+
+void realview_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ u32 val;
+ u32 led = 1 << smp_processor_id();
+
+ local_irq_save(flags);
+ val = readl(VA_LEDS_BASE);
+
+ switch (ledevt) {
+ case led_idle_start:
+ val = val & ~led;
+ break;
+
+ case led_idle_end:
+ val = val | led;
+ break;
+
+ case led_timer:
+ val = val ^ REALVIEW_SYS_LED7;
+ break;
+
+ case led_halted:
+ val = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ writel(val, VA_LEDS_BASE);
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_LEDS */
+
+/*
+ * Where is the timer (VA)?
+ */
+void __iomem *timer0_va_base;
+void __iomem *timer1_va_base;
+void __iomem *timer2_va_base;
+void __iomem *timer3_va_base;
+
+/*
+ * Set up the clock source and clock events devices
+ */
+void __init realview_timer_init(unsigned int timer_irq)
+{
+ u32 val;
+
+ /*
+ * set clock frequency:
+ * REALVIEW_REFCLK is 32KHz
+ * REALVIEW_TIMCLK is 1MHz
+ */
+ val = readl(__io_address(REALVIEW_SCTL_BASE));
+ writel((REALVIEW_TIMCLK << REALVIEW_TIMER1_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER2_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER3_EnSel) |
+ (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
+ __io_address(REALVIEW_SCTL_BASE));
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ writel(0, timer0_va_base + TIMER_CTRL);
+ writel(0, timer1_va_base + TIMER_CTRL);
+ writel(0, timer2_va_base + TIMER_CTRL);
+ writel(0, timer3_va_base + TIMER_CTRL);
+
+ sp804_clocksource_init(timer3_va_base, "timer3");
+ sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
+}
+
+/*
+ * Setup the memory banks.
+ */
+void realview_fixup(struct machine_desc *mdesc, struct tag *tags, char **from,
+ struct meminfo *meminfo)
+{
+ /*
+ * Most RealView platforms have 512MB contiguous RAM at 0x70000000.
+ * Half of this is mirrored at 0.
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+ meminfo->bank[0].start = 0x70000000;
+ meminfo->bank[0].size = SZ_512M;
+ meminfo->nr_banks = 1;
+#else
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_256M;
+ meminfo->nr_banks = 1;
+#endif
+}
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
new file mode 100644
index 00000000..5c83d1e8
--- /dev/null
+++ b/arch/arm/mach-realview/core.h
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/arm/mach-realview/core.h
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_REALVIEW_H
+#define __ASM_ARCH_REALVIEW_H
+
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/leds.h>
+
+#define AMBA_DEVICE(name,busid,base,plat) \
+static struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0, \
+ .init_name = busid, \
+ .platform_data = plat, \
+ }, \
+ .res = { \
+ .start = REALVIEW_##base##_BASE, \
+ .end = (REALVIEW_##base##_BASE) + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .dma_mask = ~0, \
+ .irq = base##_IRQ, \
+}
+
+struct machine_desc;
+
+extern struct platform_device realview_flash_device;
+extern struct platform_device realview_cf_device;
+extern struct platform_device realview_i2c_device;
+extern struct mmci_platform_data realview_mmc0_plat_data;
+extern struct mmci_platform_data realview_mmc1_plat_data;
+extern struct clcd_board clcd_plat_data;
+extern void __iomem *timer0_va_base;
+extern void __iomem *timer1_va_base;
+extern void __iomem *timer2_va_base;
+extern void __iomem *timer3_va_base;
+
+extern void realview_leds_event(led_event_t ledevt);
+extern void realview_timer_init(unsigned int timer_irq);
+extern int realview_flash_register(struct resource *res, u32 num);
+extern int realview_eth_register(const char *name, struct resource *res);
+extern int realview_usb_register(struct resource *res);
+extern void realview_init_early(void);
+extern void realview_fixup(struct machine_desc *mdesc, struct tag *tags,
+ char **from, struct meminfo *meminfo);
+extern void (*realview_reset)(char);
+
+#endif
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c
new file mode 100644
index 00000000..a87523d0
--- /dev/null
+++ b/arch/arm/mach-realview/hotplug.c
@@ -0,0 +1,127 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile( "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+}
+
+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 (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-realview/include/mach/barriers.h b/arch/arm/mach-realview/include/mach/barriers.h
new file mode 100644
index 00000000..9a732195
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/barriers.h
@@ -0,0 +1,8 @@
+/*
+ * Barriers redefined for RealView ARM11MPCore platforms with L220 cache
+ * controller to work around hardware errata causing the outer_sync()
+ * operation to deadlock the system.
+ */
+#define mb() dsb()
+#define rmb() dsb()
+#define wmb() mb()
diff --git a/arch/arm/mach-realview/include/mach/board-eb.h b/arch/arm/mach-realview/include/mach/board-eb.h
new file mode 100644
index 00000000..794a8d91
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-eb.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-realview/include/mach/board-eb.h
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_EB_H
+#define __ASM_ARCH_BOARD_EB_H
+
+#include <mach/platform.h>
+
+/*
+ * RealView EB + ARM11MPCore peripheral addresses
+ */
+#define REALVIEW_EB_UART0_BASE 0x10009000 /* UART 0 */
+#define REALVIEW_EB_UART1_BASE 0x1000A000 /* UART 1 */
+#define REALVIEW_EB_UART2_BASE 0x1000B000 /* UART 2 */
+#define REALVIEW_EB_UART3_BASE 0x1000C000 /* UART 3 */
+#define REALVIEW_EB_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
+#define REALVIEW_EB_WATCHDOG_BASE 0x10010000 /* watchdog interface */
+#define REALVIEW_EB_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
+#define REALVIEW_EB_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
+#define REALVIEW_EB_GPIO0_BASE 0x10013000 /* GPIO port 0 */
+#define REALVIEW_EB_RTC_BASE 0x10017000 /* Real Time Clock */
+#define REALVIEW_EB_CLCD_BASE 0x10020000 /* CLCD */
+#define REALVIEW_EB_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
+#define REALVIEW_EB_SMC_BASE 0x10080000 /* Static memory controller */
+
+#define REALVIEW_EB_FLASH_BASE 0x40000000
+#define REALVIEW_EB_FLASH_SIZE SZ_64M
+#define REALVIEW_EB_ETH_BASE 0x4E000000 /* Ethernet */
+#define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */
+
+#ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB
+#define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE 0x10100600
+#define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */
+#else
+#define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */
+#define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */
+#define REALVIEW_EB11MP_TWD_BASE 0x1F000600
+#define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */
+#define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */
+#define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */
+#endif
+
+/*
+ * Core tile identification (REALVIEW_SYS_PROCID)
+ */
+#define REALVIEW_EB_PROC_MASK 0xFF000000
+#define REALVIEW_EB_PROC_ARM7TDMI 0x00000000
+#define REALVIEW_EB_PROC_ARM9 0x02000000
+#define REALVIEW_EB_PROC_ARM11 0x04000000
+#define REALVIEW_EB_PROC_ARM11MP 0x06000000
+#define REALVIEW_EB_PROC_A9MP 0x0C000000
+
+#define check_eb_proc(proc_type) \
+ ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_EB_PROC_MASK) \
+ == proc_type)
+
+#ifdef CONFIG_REALVIEW_EB_ARM11MP
+#define core_tile_eb11mp() check_eb_proc(REALVIEW_EB_PROC_ARM11MP)
+#else
+#define core_tile_eb11mp() 0
+#endif
+
+#ifdef CONFIG_REALVIEW_EB_A9MP
+#define core_tile_a9mp() check_eb_proc(REALVIEW_EB_PROC_A9MP)
+#else
+#define core_tile_a9mp() 0
+#endif
+
+#define machine_is_realview_eb_mp() \
+ (machine_is_realview_eb() && (core_tile_eb11mp() || core_tile_a9mp()))
+
+#endif /* __ASM_ARCH_BOARD_EB_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
new file mode 100644
index 00000000..002ab5d8
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/mach-realview/include/mach/board-pb1176.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PB1176_H
+#define __ASM_ARCH_BOARD_PB1176_H
+
+#include <mach/platform.h>
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PB1176_UART4_BASE 0x10009000 /* UART 4 */
+#define REALVIEW_PB1176_SCTL_BASE 0x10100000 /* System controller */
+#define REALVIEW_PB1176_SMC_BASE 0x10111000 /* SMC */
+#define REALVIEW_PB1176_DMC_BASE 0x10109000 /* DMC configuration */
+#define REALVIEW_PB1176_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
+#define REALVIEW_PB1176_FLASH_BASE 0x30000000
+#define REALVIEW_PB1176_FLASH_SIZE SZ_64M
+#define REALVIEW_PB1176_SEC_FLASH_BASE 0x3C000000 /* Secure flash */
+#define REALVIEW_PB1176_SEC_FLASH_SIZE SZ_64M
+
+#define REALVIEW_PB1176_TIMER0_1_BASE 0x10104000 /* Timer 0 and 1 */
+#define REALVIEW_PB1176_TIMER2_3_BASE 0x10105000 /* Timer 2 and 3 */
+#define REALVIEW_PB1176_TIMER4_5_BASE 0x10106000 /* Timer 4 and 5 */
+#define REALVIEW_PB1176_WATCHDOG_BASE 0x10107000 /* watchdog interface */
+#define REALVIEW_PB1176_RTC_BASE 0x10108000 /* Real Time Clock */
+#define REALVIEW_PB1176_GPIO0_BASE 0x1010A000 /* GPIO port 0 */
+#define REALVIEW_PB1176_SSP_BASE 0x1010B000 /* Synchronous Serial Port */
+#define REALVIEW_PB1176_UART0_BASE 0x1010C000 /* UART 0 */
+#define REALVIEW_PB1176_UART1_BASE 0x1010D000 /* UART 1 */
+#define REALVIEW_PB1176_UART2_BASE 0x1010E000 /* UART 2 */
+#define REALVIEW_PB1176_UART3_BASE 0x1010F000 /* UART 3 */
+#define REALVIEW_PB1176_CLCD_BASE 0x10112000 /* CLCD */
+#define REALVIEW_PB1176_ETH_BASE 0x3A000000 /* Ethernet */
+#define REALVIEW_PB1176_USB_BASE 0x3B000000 /* USB */
+
+/*
+ * PCI regions
+ */
+#define REALVIEW_PB1176_PCI_BASE 0x60000000 /* PCI self config */
+#define REALVIEW_PB1176_PCI_CFG_BASE 0x61000000 /* PCI config */
+#define REALVIEW_PB1176_PCI_IO_BASE0 0x62000000 /* PCI IO region */
+#define REALVIEW_PB1176_PCI_MEM_BASE0 0x63000000 /* Memory region 1 */
+#define REALVIEW_PB1176_PCI_MEM_BASE1 0x64000000 /* Memory region 2 */
+#define REALVIEW_PB1176_PCI_MEM_BASE2 0x68000000 /* Memory region 3 */
+
+#define REALVIEW_PB1176_PCI_BASE_SIZE 0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_CFG_BASE_SIZE 0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_IO_BASE0_SIZE 0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE0_SIZE 0x01000000 /* 16MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE1_SIZE 0x04000000 /* 64MB */
+#define REALVIEW_PB1176_PCI_MEM_BASE2_SIZE 0x08000000 /* 128MB */
+
+#define REALVIEW_DC1176_GIC_CPU_BASE 0x10120000 /* GIC CPU interface, on devchip */
+#define REALVIEW_DC1176_GIC_DIST_BASE 0x10121000 /* GIC distributor, on devchip */
+#define REALVIEW_PB1176_GIC_CPU_BASE 0x10040000 /* GIC CPU interface, on FPGA */
+#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
+#define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */
+
+/*
+ * Control register SYS_RESETCTL Bit 8 is set to 1 to force a soft reset
+ */
+#define REALVIEW_PB1176_SYS_SOFT_RESET 0x0100
+
+#endif /* __ASM_ARCH_BOARD_PB1176_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pb11mp.h b/arch/arm/mach-realview/include/mach/board-pb11mp.h
new file mode 100644
index 00000000..7abf918b
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pb11mp.h
@@ -0,0 +1,96 @@
+/*
+ * arch/arm/mach-realview/include/mach/board-pb11mp.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PB11MP_H
+#define __ASM_ARCH_BOARD_PB11MP_H
+
+#include <mach/platform.h>
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PB11MP_UART0_BASE 0x10009000 /* UART 0 */
+#define REALVIEW_PB11MP_UART1_BASE 0x1000A000 /* UART 1 */
+#define REALVIEW_PB11MP_UART2_BASE 0x1000B000 /* UART 2 */
+#define REALVIEW_PB11MP_UART3_BASE 0x1000C000 /* UART 3 */
+#define REALVIEW_PB11MP_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
+#define REALVIEW_PB11MP_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */
+#define REALVIEW_PB11MP_WATCHDOG_BASE 0x10010000 /* watchdog interface */
+#define REALVIEW_PB11MP_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
+#define REALVIEW_PB11MP_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
+#define REALVIEW_PB11MP_GPIO0_BASE 0x10013000 /* GPIO port 0 */
+#define REALVIEW_PB11MP_RTC_BASE 0x10017000 /* Real Time Clock */
+#define REALVIEW_PB11MP_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */
+#define REALVIEW_PB11MP_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */
+#define REALVIEW_PB11MP_SCTL_BASE 0x1001A000 /* System Controller */
+#define REALVIEW_PB11MP_CLCD_BASE 0x10020000 /* CLCD */
+#define REALVIEW_PB11MP_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */
+#define REALVIEW_PB11MP_DMC_BASE 0x100E0000 /* DMC configuration */
+#define REALVIEW_PB11MP_SMC_BASE 0x100E1000 /* SMC configuration */
+#define REALVIEW_PB11MP_CAN_BASE 0x100E2000 /* CAN bus */
+#define REALVIEW_PB11MP_CF_BASE 0x18000000 /* Compact flash */
+#define REALVIEW_PB11MP_CF_MEM_BASE 0x18003000 /* SMC for Compact flash */
+#define REALVIEW_PB11MP_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */
+#define REALVIEW_PB11MP_FLASH0_BASE 0x40000000
+#define REALVIEW_PB11MP_FLASH0_SIZE SZ_64M
+#define REALVIEW_PB11MP_FLASH1_BASE 0x44000000
+#define REALVIEW_PB11MP_FLASH1_SIZE SZ_64M
+#define REALVIEW_PB11MP_ETH_BASE 0x4E000000 /* Ethernet */
+#define REALVIEW_PB11MP_USB_BASE 0x4F000000 /* USB */
+#define REALVIEW_PB11MP_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */
+#define REALVIEW_PB11MP_LT_BASE 0xC0000000 /* Logic Tile expansion */
+#define REALVIEW_PB11MP_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */
+#define REALVIEW_PB11MP_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */
+
+#define REALVIEW_PB11MP_SYS_PLD_CTRL1 0x74
+
+/*
+ * PB11MPCore PCI regions
+ */
+#define REALVIEW_PB11MP_PCI_BASE 0x90040000 /* PCI-X Unit base */
+#define REALVIEW_PB11MP_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
+#define REALVIEW_PB11MP_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
+
+#define REALVIEW_PB11MP_PCI_BASE_SIZE 0x10000 /* 16 Kb */
+#define REALVIEW_PB11MP_PCI_IO_SIZE 0x1000 /* 4 Kb */
+#define REALVIEW_PB11MP_PCI_MEM_SIZE 0x20000000 /* 512 MB */
+
+/*
+ * Testchip peripheral and fpga gic regions
+ */
+#define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */
+#define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */
+#define REALVIEW_TC11MP_TWD_BASE 0x1F000600
+#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
+#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */
+
+ /*
+ * Values for REALVIEW_SYS_RESET_CTRL
+ */
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR 0x01
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT 0x02
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET 0x03
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET 0x04
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR 0x05
+#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC 0x06
+
+#define REALVIEW_PB11MP_SYS_CTRL_LED (1 << 0)
+
+#endif /* __ASM_ARCH_BOARD_PB11MP_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pba8.h b/arch/arm/mach-realview/include/mach/board-pba8.h
new file mode 100644
index 00000000..4dfc67a4
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pba8.h
@@ -0,0 +1,73 @@
+/*
+ * include/asm-arm/arch-realview/board-pba8.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_BOARD_PBA8_H
+#define __ASM_ARCH_BOARD_PBA8_H
+
+#include <mach/platform.h>
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PBA8_UART0_BASE 0x10009000 /* UART 0 */
+#define REALVIEW_PBA8_UART1_BASE 0x1000A000 /* UART 1 */
+#define REALVIEW_PBA8_UART2_BASE 0x1000B000 /* UART 2 */
+#define REALVIEW_PBA8_UART3_BASE 0x1000C000 /* UART 3 */
+#define REALVIEW_PBA8_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
+#define REALVIEW_PBA8_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */
+#define REALVIEW_PBA8_WATCHDOG_BASE 0x10010000 /* watchdog interface */
+#define REALVIEW_PBA8_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
+#define REALVIEW_PBA8_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
+#define REALVIEW_PBA8_GPIO0_BASE 0x10013000 /* GPIO port 0 */
+#define REALVIEW_PBA8_RTC_BASE 0x10017000 /* Real Time Clock */
+#define REALVIEW_PBA8_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */
+#define REALVIEW_PBA8_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */
+#define REALVIEW_PBA8_SCTL_BASE 0x1001A000 /* System Controller */
+#define REALVIEW_PBA8_CLCD_BASE 0x10020000 /* CLCD */
+#define REALVIEW_PBA8_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */
+#define REALVIEW_PBA8_DMC_BASE 0x100E0000 /* DMC configuration */
+#define REALVIEW_PBA8_SMC_BASE 0x100E1000 /* SMC configuration */
+#define REALVIEW_PBA8_CAN_BASE 0x100E2000 /* CAN bus */
+#define REALVIEW_PBA8_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */
+#define REALVIEW_PBA8_FLASH0_BASE 0x40000000
+#define REALVIEW_PBA8_FLASH0_SIZE SZ_64M
+#define REALVIEW_PBA8_FLASH1_BASE 0x44000000
+#define REALVIEW_PBA8_FLASH1_SIZE SZ_64M
+#define REALVIEW_PBA8_ETH_BASE 0x4E000000 /* Ethernet */
+#define REALVIEW_PBA8_USB_BASE 0x4F000000 /* USB */
+#define REALVIEW_PBA8_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */
+#define REALVIEW_PBA8_LT_BASE 0xC0000000 /* Logic Tile expansion */
+#define REALVIEW_PBA8_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */
+#define REALVIEW_PBA8_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */
+
+#define REALVIEW_PBA8_SYS_PLD_CTRL1 0x74
+
+/*
+ * PBA8 PCI regions
+ */
+#define REALVIEW_PBA8_PCI_BASE 0x90040000 /* PCI-X Unit base */
+#define REALVIEW_PBA8_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
+#define REALVIEW_PBA8_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
+
+#define REALVIEW_PBA8_PCI_BASE_SIZE 0x10000 /* 16 Kb */
+#define REALVIEW_PBA8_PCI_IO_SIZE 0x1000 /* 4 Kb */
+#define REALVIEW_PBA8_PCI_MEM_SIZE 0x20000000 /* 512 MB */
+
+#endif /* __ASM_ARCH_BOARD_PBA8_H */
diff --git a/arch/arm/mach-realview/include/mach/board-pbx.h b/arch/arm/mach-realview/include/mach/board-pbx.h
new file mode 100644
index 00000000..848bfff6
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/board-pbx.h
@@ -0,0 +1,108 @@
+/*
+ * arch/arm/mach-realview/include/mach/board-pbx.h
+ *
+ * Copyright (C) 2009 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_BOARD_PBX_H
+#define __ASM_ARCH_BOARD_PBX_H
+
+#include <mach/platform.h>
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_PBX_UART0_BASE 0x10009000 /* UART 0 */
+#define REALVIEW_PBX_UART1_BASE 0x1000A000 /* UART 1 */
+#define REALVIEW_PBX_UART2_BASE 0x1000B000 /* UART 2 */
+#define REALVIEW_PBX_UART3_BASE 0x1000C000 /* UART 3 */
+#define REALVIEW_PBX_SSP_BASE 0x1000D000 /* Synchronous Serial Port */
+#define REALVIEW_PBX_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */
+#define REALVIEW_PBX_WATCHDOG_BASE 0x10010000 /* watchdog interface */
+#define REALVIEW_PBX_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */
+#define REALVIEW_PBX_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */
+#define REALVIEW_PBX_GPIO0_BASE 0x10013000 /* GPIO port 0 */
+#define REALVIEW_PBX_RTC_BASE 0x10017000 /* Real Time Clock */
+#define REALVIEW_PBX_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */
+#define REALVIEW_PBX_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */
+#define REALVIEW_PBX_SCTL_BASE 0x1001A000 /* System Controller */
+#define REALVIEW_PBX_CLCD_BASE 0x10020000 /* CLCD */
+#define REALVIEW_PBX_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */
+#define REALVIEW_PBX_DMC_BASE 0x100E0000 /* DMC configuration */
+#define REALVIEW_PBX_SMC_BASE 0x100E1000 /* SMC configuration */
+#define REALVIEW_PBX_CAN_BASE 0x100E2000 /* CAN bus */
+#define REALVIEW_PBX_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */
+#define REALVIEW_PBX_FLASH0_BASE 0x40000000
+#define REALVIEW_PBX_FLASH0_SIZE SZ_64M
+#define REALVIEW_PBX_FLASH1_BASE 0x44000000
+#define REALVIEW_PBX_FLASH1_SIZE SZ_64M
+#define REALVIEW_PBX_ETH_BASE 0x4E000000 /* Ethernet */
+#define REALVIEW_PBX_USB_BASE 0x4F000000 /* USB */
+#define REALVIEW_PBX_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */
+#define REALVIEW_PBX_LT_BASE 0xC0000000 /* Logic Tile expansion */
+#define REALVIEW_PBX_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */
+#define REALVIEW_PBX_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */
+
+/*
+ * Tile-specific addresses
+ */
+#define REALVIEW_PBX_TILE_SCU_BASE 0x1F000000 /* SCU registers */
+#define REALVIEW_PBX_TILE_GIC_CPU_BASE 0x1F000100 /* Private Generic interrupt controller CPU interface */
+#define REALVIEW_PBX_TILE_TWD_BASE 0x1F000600
+#define REALVIEW_PBX_TILE_TWD_PERCPU_BASE 0x1F000700
+#define REALVIEW_PBX_TILE_TWD_SIZE 0x00000100
+#define REALVIEW_PBX_TILE_GIC_DIST_BASE 0x1F001000 /* Private Generic interrupt controller distributor */
+#define REALVIEW_PBX_TILE_L220_BASE 0x1F002000 /* L220 registers */
+
+#define REALVIEW_PBX_SYS_PLD_CTRL1 0x74
+
+/*
+ * PBX PCI regions
+ */
+#define REALVIEW_PBX_PCI_BASE 0x90040000 /* PCI-X Unit base */
+#define REALVIEW_PBX_PCI_IO_BASE 0x90050000 /* IO Region on AHB */
+#define REALVIEW_PBX_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */
+
+#define REALVIEW_PBX_PCI_BASE_SIZE 0x10000 /* 16 Kb */
+#define REALVIEW_PBX_PCI_IO_SIZE 0x1000 /* 4 Kb */
+#define REALVIEW_PBX_PCI_MEM_SIZE 0x20000000 /* 512 MB */
+
+/*
+ * Core tile identification (REALVIEW_SYS_PROCID)
+ */
+#define REALVIEW_PBX_PROC_MASK 0xFF000000
+#define REALVIEW_PBX_PROC_ARM7TDMI 0x00000000
+#define REALVIEW_PBX_PROC_ARM9 0x02000000
+#define REALVIEW_PBX_PROC_ARM11 0x04000000
+#define REALVIEW_PBX_PROC_ARM11MP 0x06000000
+#define REALVIEW_PBX_PROC_A9MP 0x0C000000
+#define REALVIEW_PBX_PROC_A8 0x0E000000
+
+#define check_pbx_proc(proc_type) \
+ ((readl(__io_address(REALVIEW_SYS_PROCID)) & REALVIEW_PBX_PROC_MASK) \
+ == proc_type)
+
+#ifdef CONFIG_MACH_REALVIEW_PBX
+#define core_tile_pbx11mp() check_pbx_proc(REALVIEW_PBX_PROC_ARM11MP)
+#define core_tile_pbxa9mp() check_pbx_proc(REALVIEW_PBX_PROC_A9MP)
+#define core_tile_pbxa8() check_pbx_proc(REALVIEW_PBX_PROC_A8)
+#else
+#define core_tile_pbx11mp() 0
+#define core_tile_pbxa9mp() 0
+#define core_tile_pbxa8() 0
+#endif
+
+#endif /* __ASM_ARCH_BOARD_PBX_H */
diff --git a/arch/arm/mach-realview/include/mach/clkdev.h b/arch/arm/mach-realview/include/mach/clkdev.h
new file mode 100644
index 00000000..e58d0771
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/clkdev.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <plat/clock.h>
+
+struct clk {
+ unsigned long rate;
+ const struct clk_ops *ops;
+ const struct icst_params *params;
+ void __iomem *vcoreg;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/debug-macro.S b/arch/arm/mach-realview/include/mach/debug-macro.S
new file mode 100644
index 00000000..90b687cb
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/debug-macro.S
@@ -0,0 +1,42 @@
+/* arch/arm/mach-realview/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#if defined(CONFIG_MACH_REALVIEW_EB) || \
+ defined(CONFIG_MACH_REALVIEW_PB11MP) || \
+ defined(CONFIG_MACH_REALVIEW_PBA8) || \
+ defined(CONFIG_MACH_REALVIEW_PBX)
+#ifndef DEBUG_LL_UART_OFFSET
+#define DEBUG_LL_UART_OFFSET 0x00009000
+#elif DEBUG_LL_UART_OFFSET != 0x00009000
+#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
+#endif
+#endif
+
+#ifdef CONFIG_MACH_REALVIEW_PB1176
+#ifndef DEBUG_LL_UART_OFFSET
+#define DEBUG_LL_UART_OFFSET 0x0010c000
+#elif DEBUG_LL_UART_OFFSET != 0x0010c000
+#warning "DEBUG_LL_UART_OFFSET already defined to a different value"
+#endif
+#endif
+
+#ifndef DEBUG_LL_UART_OFFSET
+#error "Unknown RealView platform"
+#endif
+
+ .macro addruart, rp, rv
+ mov \rp, #DEBUG_LL_UART_OFFSET
+ orr \rv, \rp, #0xfb000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-realview/include/mach/entry-macro.S b/arch/arm/mach-realview/include/mach/entry-macro.S
new file mode 100644
index 00000000..4071164a
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/entry-macro.S
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-realview/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for RealView platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
diff --git a/arch/arm/mach-realview/include/mach/gpio.h b/arch/arm/mach-realview/include/mach/gpio.h
new file mode 100644
index 00000000..94ff2767
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#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
diff --git a/arch/arm/mach-realview/include/mach/hardware.h b/arch/arm/mach-realview/include/mach/hardware.h
new file mode 100644
index 00000000..8a638d15
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/hardware.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-realview/include/mach/hardware.h
+ *
+ * This file contains the hardware definitions of the RealView boards.
+ *
+ * Copyright (C) 2003 ARM Limited.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/* macro to get at IO space when running virtually */
+#ifdef CONFIG_MMU
+/*
+ * Statically mapped addresses:
+ *
+ * 10xx xxxx -> fbxx xxxx
+ * 1exx xxxx -> fdxx xxxx
+ * 1fxx xxxx -> fexx xxxx
+ */
+#define IO_ADDRESS(x) (((x) & 0x03ffffff) + 0xfb000000)
+#else
+#define IO_ADDRESS(x) (x)
+#endif
+#define __io_address(n) __io(IO_ADDRESS(n))
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/io.h b/arch/arm/mach-realview/include/mach/io.h
new file mode 100644
index 00000000..f05bcdf6
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-realview/include/mach/io.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/irqs-eb.h b/arch/arm/mach-realview/include/mach/irqs-eb.h
new file mode 100644
index 00000000..204d5378
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-eb.h
@@ -0,0 +1,129 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs-eb.h
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_EB_H
+#define __MACH_IRQS_EB_H
+
+#define IRQ_EB_GIC_START 32
+
+/*
+ * RealView EB interrupt sources
+ */
+#define IRQ_EB_WDOG (IRQ_EB_GIC_START + 0) /* Watchdog timer */
+#define IRQ_EB_SOFT (IRQ_EB_GIC_START + 1) /* Software interrupt */
+#define IRQ_EB_COMMRx (IRQ_EB_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_EB_COMMTx (IRQ_EB_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_EB_TIMER0_1 (IRQ_EB_GIC_START + 4) /* Timer 0 and 1 */
+#define IRQ_EB_TIMER2_3 (IRQ_EB_GIC_START + 5) /* Timer 2 and 3 */
+#define IRQ_EB_GPIO0 (IRQ_EB_GIC_START + 6) /* GPIO 0 */
+#define IRQ_EB_GPIO1 (IRQ_EB_GIC_START + 7) /* GPIO 1 */
+#define IRQ_EB_GPIO2 (IRQ_EB_GIC_START + 8) /* GPIO 2 */
+ /* 9 reserved */
+#define IRQ_EB_RTC (IRQ_EB_GIC_START + 10) /* Real Time Clock */
+#define IRQ_EB_SSP (IRQ_EB_GIC_START + 11) /* Synchronous Serial Port */
+#define IRQ_EB_UART0 (IRQ_EB_GIC_START + 12) /* UART 0 on development chip */
+#define IRQ_EB_UART1 (IRQ_EB_GIC_START + 13) /* UART 1 on development chip */
+#define IRQ_EB_UART2 (IRQ_EB_GIC_START + 14) /* UART 2 on development chip */
+#define IRQ_EB_UART3 (IRQ_EB_GIC_START + 15) /* UART 3 on development chip */
+#define IRQ_EB_SCI (IRQ_EB_GIC_START + 16) /* Smart Card Interface */
+#define IRQ_EB_MMCI0A (IRQ_EB_GIC_START + 17) /* Multimedia Card 0A */
+#define IRQ_EB_MMCI0B (IRQ_EB_GIC_START + 18) /* Multimedia Card 0B */
+#define IRQ_EB_AACI (IRQ_EB_GIC_START + 19) /* Audio Codec */
+#define IRQ_EB_KMI0 (IRQ_EB_GIC_START + 20) /* Keyboard/Mouse port 0 */
+#define IRQ_EB_KMI1 (IRQ_EB_GIC_START + 21) /* Keyboard/Mouse port 1 */
+#define IRQ_EB_CHARLCD (IRQ_EB_GIC_START + 22) /* Character LCD */
+#define IRQ_EB_CLCD (IRQ_EB_GIC_START + 23) /* CLCD controller */
+#define IRQ_EB_DMA (IRQ_EB_GIC_START + 24) /* DMA controller */
+#define IRQ_EB_PWRFAIL (IRQ_EB_GIC_START + 25) /* Power failure */
+#define IRQ_EB_PISMO (IRQ_EB_GIC_START + 26) /* PISMO interface */
+#define IRQ_EB_DoC (IRQ_EB_GIC_START + 27) /* Disk on Chip memory controller */
+#define IRQ_EB_ETH (IRQ_EB_GIC_START + 28) /* Ethernet controller */
+#define IRQ_EB_USB (IRQ_EB_GIC_START + 29) /* USB controller */
+#define IRQ_EB_TSPEN (IRQ_EB_GIC_START + 30) /* Touchscreen pen */
+#define IRQ_EB_TSKPAD (IRQ_EB_GIC_START + 31) /* Touchscreen keypad */
+
+/*
+ * RealView EB + ARM11MPCore interrupt sources (primary GIC on the core tile)
+ */
+#define IRQ_EB11MP_AACI (IRQ_EB_GIC_START + 0)
+#define IRQ_EB11MP_TIMER0_1 (IRQ_EB_GIC_START + 1)
+#define IRQ_EB11MP_TIMER2_3 (IRQ_EB_GIC_START + 2)
+#define IRQ_EB11MP_USB (IRQ_EB_GIC_START + 3)
+#define IRQ_EB11MP_UART0 (IRQ_EB_GIC_START + 4)
+#define IRQ_EB11MP_UART1 (IRQ_EB_GIC_START + 5)
+#define IRQ_EB11MP_RTC (IRQ_EB_GIC_START + 6)
+#define IRQ_EB11MP_KMI0 (IRQ_EB_GIC_START + 7)
+#define IRQ_EB11MP_KMI1 (IRQ_EB_GIC_START + 8)
+#define IRQ_EB11MP_ETH (IRQ_EB_GIC_START + 9)
+#define IRQ_EB11MP_EB_IRQ1 (IRQ_EB_GIC_START + 10) /* main GIC */
+#define IRQ_EB11MP_EB_IRQ2 (IRQ_EB_GIC_START + 11) /* tile GIC */
+#define IRQ_EB11MP_EB_FIQ1 (IRQ_EB_GIC_START + 12) /* main GIC */
+#define IRQ_EB11MP_EB_FIQ2 (IRQ_EB_GIC_START + 13) /* tile GIC */
+#define IRQ_EB11MP_MMCI0A (IRQ_EB_GIC_START + 14)
+#define IRQ_EB11MP_MMCI0B (IRQ_EB_GIC_START + 15)
+
+#define IRQ_EB11MP_PMU_CPU0 (IRQ_EB_GIC_START + 17)
+#define IRQ_EB11MP_PMU_CPU1 (IRQ_EB_GIC_START + 18)
+#define IRQ_EB11MP_PMU_CPU2 (IRQ_EB_GIC_START + 19)
+#define IRQ_EB11MP_PMU_CPU3 (IRQ_EB_GIC_START + 20)
+#define IRQ_EB11MP_PMU_SCU0 (IRQ_EB_GIC_START + 21)
+#define IRQ_EB11MP_PMU_SCU1 (IRQ_EB_GIC_START + 22)
+#define IRQ_EB11MP_PMU_SCU2 (IRQ_EB_GIC_START + 23)
+#define IRQ_EB11MP_PMU_SCU3 (IRQ_EB_GIC_START + 24)
+#define IRQ_EB11MP_PMU_SCU4 (IRQ_EB_GIC_START + 25)
+#define IRQ_EB11MP_PMU_SCU5 (IRQ_EB_GIC_START + 26)
+#define IRQ_EB11MP_PMU_SCU6 (IRQ_EB_GIC_START + 27)
+#define IRQ_EB11MP_PMU_SCU7 (IRQ_EB_GIC_START + 28)
+
+#define IRQ_EB11MP_L220_EVENT (IRQ_EB_GIC_START + 29)
+#define IRQ_EB11MP_L220_SLAVE (IRQ_EB_GIC_START + 30)
+#define IRQ_EB11MP_L220_DECODE (IRQ_EB_GIC_START + 31)
+
+#define IRQ_EB11MP_UART2 -1
+#define IRQ_EB11MP_UART3 -1
+#define IRQ_EB11MP_CLCD -1
+#define IRQ_EB11MP_DMA -1
+#define IRQ_EB11MP_WDOG -1
+#define IRQ_EB11MP_GPIO0 -1
+#define IRQ_EB11MP_GPIO1 -1
+#define IRQ_EB11MP_GPIO2 -1
+#define IRQ_EB11MP_SCI -1
+#define IRQ_EB11MP_SSP -1
+
+#define NR_GIC_EB11MP 2
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_EB
+ */
+#define NR_IRQS_EB (IRQ_EB_GIC_START + 96)
+
+#if defined(CONFIG_MACH_REALVIEW_EB) \
+ && (!defined(NR_IRQS) || (NR_IRQS < NR_IRQS_EB))
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_EB
+#endif
+
+#if defined(CONFIG_REALVIEW_EB_ARM11MP) || defined(CONFIG_REALVIEW_EB_A9MP) \
+ && (!defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_EB11MP))
+#undef MAX_GIC_NR
+#define MAX_GIC_NR NR_GIC_EB11MP
+#endif
+
+#endif /* __MACH_IRQS_EB_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
new file mode 100644
index 00000000..5c3c625e
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -0,0 +1,100 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs-pb1176.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PB1176_H
+#define __MACH_IRQS_PB1176_H
+
+#define IRQ_DC1176_GIC_START 32
+#define IRQ_PB1176_GIC_START 64
+
+/*
+ * ARM1176 DevChip interrupt sources (primary GIC)
+ */
+#define IRQ_DC1176_WATCHDOG (IRQ_DC1176_GIC_START + 0) /* Watchdog timer */
+#define IRQ_DC1176_SOFTINT (IRQ_DC1176_GIC_START + 1) /* Software interrupt */
+#define IRQ_DC1176_COMMRx (IRQ_DC1176_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_DC1176_COMMTx (IRQ_DC1176_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_DC1176_CORE_PMU (IRQ_DC1176_GIC_START + 7) /* Core PMU interrupt */
+#define IRQ_DC1176_TIMER0 (IRQ_DC1176_GIC_START + 8) /* Timer 0 */
+#define IRQ_DC1176_TIMER1 (IRQ_DC1176_GIC_START + 9) /* Timer 1 */
+#define IRQ_DC1176_TIMER2 (IRQ_DC1176_GIC_START + 10) /* Timer 2 */
+#define IRQ_DC1176_APC (IRQ_DC1176_GIC_START + 11)
+#define IRQ_DC1176_IEC (IRQ_DC1176_GIC_START + 12)
+#define IRQ_DC1176_L2CC (IRQ_DC1176_GIC_START + 13)
+#define IRQ_DC1176_RTC (IRQ_DC1176_GIC_START + 14)
+#define IRQ_DC1176_CLCD (IRQ_DC1176_GIC_START + 15) /* CLCD controller */
+#define IRQ_DC1176_SSP (IRQ_DC1176_GIC_START + 17) /* SSP port */
+#define IRQ_DC1176_UART0 (IRQ_DC1176_GIC_START + 18) /* UART 0 on development chip */
+#define IRQ_DC1176_UART1 (IRQ_DC1176_GIC_START + 19) /* UART 1 on development chip */
+#define IRQ_DC1176_UART2 (IRQ_DC1176_GIC_START + 20) /* UART 2 on development chip */
+#define IRQ_DC1176_UART3 (IRQ_DC1176_GIC_START + 21) /* UART 3 on development chip */
+
+#define IRQ_DC1176_PB_IRQ2 (IRQ_DC1176_GIC_START + 30) /* tile GIC */
+#define IRQ_DC1176_PB_IRQ1 (IRQ_DC1176_GIC_START + 31) /* main GIC */
+
+/*
+ * RealView PB1176 interrupt sources (secondary GIC)
+ */
+#define IRQ_PB1176_MMCI0A (IRQ_PB1176_GIC_START + 1) /* Multimedia Card 0A */
+#define IRQ_PB1176_MMCI0B (IRQ_PB1176_GIC_START + 2) /* Multimedia Card 0A */
+#define IRQ_PB1176_KMI0 (IRQ_PB1176_GIC_START + 3) /* Keyboard/Mouse port 0 */
+#define IRQ_PB1176_KMI1 (IRQ_PB1176_GIC_START + 4) /* Keyboard/Mouse port 1 */
+#define IRQ_PB1176_SCI (IRQ_PB1176_GIC_START + 5)
+#define IRQ_PB1176_UART4 (IRQ_PB1176_GIC_START + 6) /* UART 4 on baseboard */
+#define IRQ_PB1176_CHARLCD (IRQ_PB1176_GIC_START + 7) /* Character LCD */
+#define IRQ_PB1176_GPIO1 (IRQ_PB1176_GIC_START + 8)
+#define IRQ_PB1176_GPIO2 (IRQ_PB1176_GIC_START + 9)
+#define IRQ_PB1176_ETH (IRQ_PB1176_GIC_START + 10) /* Ethernet controller */
+#define IRQ_PB1176_USB (IRQ_PB1176_GIC_START + 11) /* USB controller */
+
+#define IRQ_PB1176_PISMO (IRQ_PB1176_GIC_START + 16)
+
+#define IRQ_PB1176_AACI (IRQ_PB1176_GIC_START + 19) /* Audio Codec */
+
+#define IRQ_PB1176_TIMER0_1 (IRQ_PB1176_GIC_START + 22)
+#define IRQ_PB1176_TIMER2_3 (IRQ_PB1176_GIC_START + 23)
+#define IRQ_PB1176_DMAC (IRQ_PB1176_GIC_START + 24) /* DMA controller */
+#define IRQ_PB1176_RTC (IRQ_PB1176_GIC_START + 25) /* Real Time Clock */
+
+#define IRQ_PB1176_GPIO0 -1
+#define IRQ_PB1176_SCTL -1
+
+#define NR_GIC_PB1176 2
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_PB1176
+ */
+#define NR_IRQS_PB1176 (IRQ_DC1176_GIC_START + 96)
+
+#if defined(CONFIG_MACH_REALVIEW_PB1176)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PB1176)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_PB1176
+#endif
+
+#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PB1176)
+#undef MAX_GIC_NR
+#define MAX_GIC_NR NR_GIC_PB1176
+#endif
+
+#endif /* CONFIG_MACH_REALVIEW_PB1176 */
+
+#endif /* __MACH_IRQS_PB1176_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb11mp.h b/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
new file mode 100644
index 00000000..34e255ad
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-pb11mp.h
@@ -0,0 +1,122 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs-pb11mp.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PB11MP_H
+#define __MACH_IRQS_PB11MP_H
+
+#define IRQ_TC11MP_GIC_START 32
+#define IRQ_PB11MP_GIC_START 64
+
+/*
+ * ARM11MPCore test chip interrupt sources (primary GIC on the test chip)
+ */
+#define IRQ_TC11MP_AACI (IRQ_TC11MP_GIC_START + 0)
+#define IRQ_TC11MP_TIMER0_1 (IRQ_TC11MP_GIC_START + 1)
+#define IRQ_TC11MP_TIMER2_3 (IRQ_TC11MP_GIC_START + 2)
+#define IRQ_TC11MP_USB (IRQ_TC11MP_GIC_START + 3)
+#define IRQ_TC11MP_UART0 (IRQ_TC11MP_GIC_START + 4)
+#define IRQ_TC11MP_UART1 (IRQ_TC11MP_GIC_START + 5)
+#define IRQ_TC11MP_RTC (IRQ_TC11MP_GIC_START + 6)
+#define IRQ_TC11MP_KMI0 (IRQ_TC11MP_GIC_START + 7)
+#define IRQ_TC11MP_KMI1 (IRQ_TC11MP_GIC_START + 8)
+#define IRQ_TC11MP_ETH (IRQ_TC11MP_GIC_START + 9)
+#define IRQ_TC11MP_PB_IRQ1 (IRQ_TC11MP_GIC_START + 10) /* main GIC */
+#define IRQ_TC11MP_PB_IRQ2 (IRQ_TC11MP_GIC_START + 11) /* tile GIC */
+#define IRQ_TC11MP_PB_FIQ1 (IRQ_TC11MP_GIC_START + 12) /* main GIC */
+#define IRQ_TC11MP_PB_FIQ2 (IRQ_TC11MP_GIC_START + 13) /* tile GIC */
+#define IRQ_TC11MP_MMCI0A (IRQ_TC11MP_GIC_START + 14)
+#define IRQ_TC11MP_MMCI0B (IRQ_TC11MP_GIC_START + 15)
+
+#define IRQ_TC11MP_PMU_CPU0 (IRQ_TC11MP_GIC_START + 17)
+#define IRQ_TC11MP_PMU_CPU1 (IRQ_TC11MP_GIC_START + 18)
+#define IRQ_TC11MP_PMU_CPU2 (IRQ_TC11MP_GIC_START + 19)
+#define IRQ_TC11MP_PMU_CPU3 (IRQ_TC11MP_GIC_START + 20)
+#define IRQ_TC11MP_PMU_SCU0 (IRQ_TC11MP_GIC_START + 21)
+#define IRQ_TC11MP_PMU_SCU1 (IRQ_TC11MP_GIC_START + 22)
+#define IRQ_TC11MP_PMU_SCU2 (IRQ_TC11MP_GIC_START + 23)
+#define IRQ_TC11MP_PMU_SCU3 (IRQ_TC11MP_GIC_START + 24)
+#define IRQ_TC11MP_PMU_SCU4 (IRQ_TC11MP_GIC_START + 25)
+#define IRQ_TC11MP_PMU_SCU5 (IRQ_TC11MP_GIC_START + 26)
+#define IRQ_TC11MP_PMU_SCU6 (IRQ_TC11MP_GIC_START + 27)
+#define IRQ_TC11MP_PMU_SCU7 (IRQ_TC11MP_GIC_START + 28)
+
+#define IRQ_TC11MP_L220_EVENT (IRQ_TC11MP_GIC_START + 29)
+#define IRQ_TC11MP_L220_SLAVE (IRQ_TC11MP_GIC_START + 30)
+#define IRQ_TC11MP_L220_DECODE (IRQ_TC11MP_GIC_START + 31)
+
+/*
+ * RealView PB11MPCore GIC interrupt sources (secondary GIC on the board)
+ */
+#define IRQ_PB11MP_WATCHDOG (IRQ_PB11MP_GIC_START + 0) /* Watchdog timer */
+#define IRQ_PB11MP_SOFT (IRQ_PB11MP_GIC_START + 1) /* Software interrupt */
+#define IRQ_PB11MP_COMMRx (IRQ_PB11MP_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_PB11MP_COMMTx (IRQ_PB11MP_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_PB11MP_GPIO0 (IRQ_PB11MP_GIC_START + 6) /* GPIO 0 */
+#define IRQ_PB11MP_GPIO1 (IRQ_PB11MP_GIC_START + 7) /* GPIO 1 */
+#define IRQ_PB11MP_GPIO2 (IRQ_PB11MP_GIC_START + 8) /* GPIO 2 */
+ /* 9 reserved */
+#define IRQ_PB11MP_RTC_GIC1 (IRQ_PB11MP_GIC_START + 10) /* Real Time Clock */
+#define IRQ_PB11MP_SSP (IRQ_PB11MP_GIC_START + 11) /* Synchronous Serial Port */
+#define IRQ_PB11MP_UART0_GIC1 (IRQ_PB11MP_GIC_START + 12) /* UART 0 on development chip */
+#define IRQ_PB11MP_UART1_GIC1 (IRQ_PB11MP_GIC_START + 13) /* UART 1 on development chip */
+#define IRQ_PB11MP_UART2 (IRQ_PB11MP_GIC_START + 14) /* UART 2 on development chip */
+#define IRQ_PB11MP_UART3 (IRQ_PB11MP_GIC_START + 15) /* UART 3 on development chip */
+#define IRQ_PB11MP_SCI (IRQ_PB11MP_GIC_START + 16) /* Smart Card Interface */
+#define IRQ_PB11MP_MMCI0A_GIC1 (IRQ_PB11MP_GIC_START + 17) /* Multimedia Card 0A */
+#define IRQ_PB11MP_MMCI0B_GIC1 (IRQ_PB11MP_GIC_START + 18) /* Multimedia Card 0B */
+#define IRQ_PB11MP_AACI_GIC1 (IRQ_PB11MP_GIC_START + 19) /* Audio Codec */
+#define IRQ_PB11MP_KMI0_GIC1 (IRQ_PB11MP_GIC_START + 20) /* Keyboard/Mouse port 0 */
+#define IRQ_PB11MP_KMI1_GIC1 (IRQ_PB11MP_GIC_START + 21) /* Keyboard/Mouse port 1 */
+#define IRQ_PB11MP_CHARLCD (IRQ_PB11MP_GIC_START + 22) /* Character LCD */
+#define IRQ_PB11MP_CLCD (IRQ_PB11MP_GIC_START + 23) /* CLCD controller */
+#define IRQ_PB11MP_DMAC (IRQ_PB11MP_GIC_START + 24) /* DMA controller */
+#define IRQ_PB11MP_PWRFAIL (IRQ_PB11MP_GIC_START + 25) /* Power failure */
+#define IRQ_PB11MP_PISMO (IRQ_PB11MP_GIC_START + 26) /* PISMO interface */
+#define IRQ_PB11MP_DoC (IRQ_PB11MP_GIC_START + 27) /* Disk on Chip memory controller */
+#define IRQ_PB11MP_ETH_GIC1 (IRQ_PB11MP_GIC_START + 28) /* Ethernet controller */
+#define IRQ_PB11MP_USB_GIC1 (IRQ_PB11MP_GIC_START + 29) /* USB controller */
+#define IRQ_PB11MP_TSPEN (IRQ_PB11MP_GIC_START + 30) /* Touchscreen pen */
+#define IRQ_PB11MP_TSKPAD (IRQ_PB11MP_GIC_START + 31) /* Touchscreen keypad */
+
+#define IRQ_PB11MP_SMC -1
+#define IRQ_PB11MP_SCTL -1
+
+#define NR_GIC_PB11MP 2
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_PB11MP
+ */
+#define NR_IRQS_PB11MP (IRQ_TC11MP_GIC_START + 96)
+
+#if defined(CONFIG_MACH_REALVIEW_PB11MP)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PB11MP)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_PB11MP
+#endif
+
+#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PB11MP)
+#undef MAX_GIC_NR
+#define MAX_GIC_NR NR_GIC_PB11MP
+#endif
+
+#endif /* CONFIG_MACH_REALVIEW_PB11MP */
+
+#endif /* __MACH_IRQS_PB11MP_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pba8.h b/arch/arm/mach-realview/include/mach/irqs-pba8.h
new file mode 100644
index 00000000..4a88a4ed
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-pba8.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs-pba8.h
+ *
+ * Copyright (C) 2008 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IRQS_PBA8_H
+#define __MACH_IRQS_PBA8_H
+
+#define IRQ_PBA8_GIC_START 32
+
+/*
+ * PB-A8 on-board gic irq sources
+ */
+#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */
+#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */
+#define IRQ_PBA8_COMMRx (IRQ_PBA8_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_PBA8_COMMTx (IRQ_PBA8_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 4) /* Timer 0/1 (default timer) */
+#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 5) /* Timer 2/3 */
+#define IRQ_PBA8_GPIO0 (IRQ_PBA8_GIC_START + 6) /* GPIO 0 */
+#define IRQ_PBA8_GPIO1 (IRQ_PBA8_GIC_START + 7) /* GPIO 1 */
+#define IRQ_PBA8_GPIO2 (IRQ_PBA8_GIC_START + 8) /* GPIO 2 */
+ /* 9 reserved */
+#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 10) /* Real Time Clock */
+#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */
+#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 12) /* UART 0 on development chip */
+#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 13) /* UART 1 on development chip */
+#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 14) /* UART 2 on development chip */
+#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 15) /* UART 3 on development chip */
+#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */
+#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */
+#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */
+#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */
+#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */
+#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */
+#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */
+#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */
+#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */
+#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */
+#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */
+#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */
+#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */
+#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */
+#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */
+#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */
+
+#define IRQ_PBA8_PMU (IRQ_PBA8_GIC_START + 47) /* Cortex-A8 PMU */
+
+/* ... */
+#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50)
+#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51)
+#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52)
+#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53)
+
+#define IRQ_PBA8_SMC -1
+#define IRQ_PBA8_SCTL -1
+
+#define NR_GIC_PBA8 1
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_PBA8
+ */
+#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64)
+
+#if defined(CONFIG_MACH_REALVIEW_PBA8)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PBA8)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_PBA8
+#endif
+
+#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PBA8)
+#undef MAX_GIC_NR
+#define MAX_GIC_NR NR_GIC_PBA8
+#endif
+
+#endif /* CONFIG_MACH_REALVIEW_PBA8 */
+
+#endif /* __MACH_IRQS_PBA8_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs-pbx.h b/arch/arm/mach-realview/include/mach/irqs-pbx.h
new file mode 100644
index 00000000..206a3001
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs-pbx.h
@@ -0,0 +1,109 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs-pbx.h
+ *
+ * Copyright (C) 2009 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_IRQS_PBX_H
+#define __MACH_IRQS_PBX_H
+
+#define IRQ_PBX_GIC_START 32
+
+/*
+ * PBX on-board gic irq sources
+ */
+#define IRQ_PBX_WATCHDOG (IRQ_PBX_GIC_START + 0) /* Watchdog timer */
+#define IRQ_PBX_SOFT (IRQ_PBX_GIC_START + 1) /* Software interrupt */
+#define IRQ_PBX_COMMRx (IRQ_PBX_GIC_START + 2) /* Debug Comm Rx interrupt */
+#define IRQ_PBX_COMMTx (IRQ_PBX_GIC_START + 3) /* Debug Comm Tx interrupt */
+#define IRQ_PBX_TIMER0_1 (IRQ_PBX_GIC_START + 4) /* Timer 0/1 (default timer) */
+#define IRQ_PBX_TIMER2_3 (IRQ_PBX_GIC_START + 5) /* Timer 2/3 */
+#define IRQ_PBX_GPIO0 (IRQ_PBX_GIC_START + 6) /* GPIO 0 */
+#define IRQ_PBX_GPIO1 (IRQ_PBX_GIC_START + 7) /* GPIO 1 */
+#define IRQ_PBX_GPIO2 (IRQ_PBX_GIC_START + 8) /* GPIO 2 */
+ /* 9 reserved */
+#define IRQ_PBX_RTC (IRQ_PBX_GIC_START + 10) /* Real Time Clock */
+#define IRQ_PBX_SSP (IRQ_PBX_GIC_START + 11) /* Synchronous Serial Port */
+#define IRQ_PBX_UART0 (IRQ_PBX_GIC_START + 12) /* UART 0 on development chip */
+#define IRQ_PBX_UART1 (IRQ_PBX_GIC_START + 13) /* UART 1 on development chip */
+#define IRQ_PBX_UART2 (IRQ_PBX_GIC_START + 14) /* UART 2 on development chip */
+#define IRQ_PBX_UART3 (IRQ_PBX_GIC_START + 15) /* UART 3 on development chip */
+#define IRQ_PBX_SCI (IRQ_PBX_GIC_START + 16) /* Smart Card Interface */
+#define IRQ_PBX_MMCI0A (IRQ_PBX_GIC_START + 17) /* Multimedia Card 0A */
+#define IRQ_PBX_MMCI0B (IRQ_PBX_GIC_START + 18) /* Multimedia Card 0B */
+#define IRQ_PBX_AACI (IRQ_PBX_GIC_START + 19) /* Audio Codec */
+#define IRQ_PBX_KMI0 (IRQ_PBX_GIC_START + 20) /* Keyboard/Mouse port 0 */
+#define IRQ_PBX_KMI1 (IRQ_PBX_GIC_START + 21) /* Keyboard/Mouse port 1 */
+#define IRQ_PBX_CHARLCD (IRQ_PBX_GIC_START + 22) /* Character LCD */
+#define IRQ_PBX_CLCD (IRQ_PBX_GIC_START + 23) /* CLCD controller */
+#define IRQ_PBX_DMAC (IRQ_PBX_GIC_START + 24) /* DMA controller */
+#define IRQ_PBX_PWRFAIL (IRQ_PBX_GIC_START + 25) /* Power failure */
+#define IRQ_PBX_PISMO (IRQ_PBX_GIC_START + 26) /* PISMO interface */
+#define IRQ_PBX_DoC (IRQ_PBX_GIC_START + 27) /* Disk on Chip memory controller */
+#define IRQ_PBX_ETH (IRQ_PBX_GIC_START + 28) /* Ethernet controller */
+#define IRQ_PBX_USB (IRQ_PBX_GIC_START + 29) /* USB controller */
+#define IRQ_PBX_TSPEN (IRQ_PBX_GIC_START + 30) /* Touchscreen pen */
+#define IRQ_PBX_TSKPAD (IRQ_PBX_GIC_START + 31) /* Touchscreen keypad */
+
+#define IRQ_PBX_PMU_SCU0 (IRQ_PBX_GIC_START + 32) /* SCU PMU Interrupts (11mp) */
+#define IRQ_PBX_PMU_SCU1 (IRQ_PBX_GIC_START + 33)
+#define IRQ_PBX_PMU_SCU2 (IRQ_PBX_GIC_START + 34)
+#define IRQ_PBX_PMU_SCU3 (IRQ_PBX_GIC_START + 35)
+#define IRQ_PBX_PMU_SCU4 (IRQ_PBX_GIC_START + 36)
+#define IRQ_PBX_PMU_SCU5 (IRQ_PBX_GIC_START + 37)
+#define IRQ_PBX_PMU_SCU6 (IRQ_PBX_GIC_START + 38)
+#define IRQ_PBX_PMU_SCU7 (IRQ_PBX_GIC_START + 39)
+
+#define IRQ_PBX_WATCHDOG1 (IRQ_PBX_GIC_START + 40) /* Watchdog1 timer */
+#define IRQ_PBX_TIMER4_5 (IRQ_PBX_GIC_START + 41) /* Timer 0/1 (default timer) */
+#define IRQ_PBX_TIMER6_7 (IRQ_PBX_GIC_START + 42) /* Timer 2/3 */
+/* ... */
+#define IRQ_PBX_PMU_CPU0 (IRQ_PBX_GIC_START + 44) /* CPU PMU Interrupts */
+#define IRQ_PBX_PMU_CPU1 (IRQ_PBX_GIC_START + 45)
+#define IRQ_PBX_PMU_CPU2 (IRQ_PBX_GIC_START + 46)
+#define IRQ_PBX_PMU_CPU3 (IRQ_PBX_GIC_START + 47)
+
+/* ... */
+#define IRQ_PBX_PCI0 (IRQ_PBX_GIC_START + 50)
+#define IRQ_PBX_PCI1 (IRQ_PBX_GIC_START + 51)
+#define IRQ_PBX_PCI2 (IRQ_PBX_GIC_START + 52)
+#define IRQ_PBX_PCI3 (IRQ_PBX_GIC_START + 53)
+
+#define IRQ_PBX_SMC -1
+#define IRQ_PBX_SCTL -1
+
+#define NR_GIC_PBX 1
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_PBX
+ */
+#define NR_IRQS_PBX (IRQ_PBX_GIC_START + 96)
+
+#if defined(CONFIG_MACH_REALVIEW_PBX)
+
+#if !defined(NR_IRQS) || (NR_IRQS < NR_IRQS_PBX)
+#undef NR_IRQS
+#define NR_IRQS NR_IRQS_PBX
+#endif
+
+#if !defined(MAX_GIC_NR) || (MAX_GIC_NR < NR_GIC_PBX)
+#undef MAX_GIC_NR
+#define MAX_GIC_NR NR_GIC_PBX
+#endif
+
+#endif /* CONFIG_MACH_REALVIEW_PBX */
+
+#endif /* __MACH_IRQS_PBX_H */
diff --git a/arch/arm/mach-realview/include/mach/irqs.h b/arch/arm/mach-realview/include/mach/irqs.h
new file mode 100644
index 00000000..78854f2f
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/irqs.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-realview/include/mach/irqs.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include <mach/irqs-eb.h>
+#include <mach/irqs-pb11mp.h>
+#include <mach/irqs-pb1176.h>
+#include <mach/irqs-pba8.h>
+#include <mach/irqs-pbx.h>
+
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+
+#define IRQ_GIC_START 32
+
+#ifndef NR_IRQS
+#error "NR_IRQS not defined by the board-specific files"
+#endif
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
new file mode 100644
index 00000000..1759fa67
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/mach-realview/include/mach/memory.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+#define PLAT_PHYS_OFFSET UL(0x70000000)
+#else
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+#endif
+
+#ifdef CONFIG_ZONE_DMA
+#define ARM_DMA_ZONE_SIZE SZ_256M
+#endif
+
+#ifdef CONFIG_SPARSEMEM
+
+/*
+ * Sparsemem definitions for RealView PBX.
+ *
+ * The RealView PBX board has another block of 512MB of RAM at 0x20000000,
+ * however only the block at 0x70000000 (or the 256MB mirror at 0x00000000)
+ * may be used for DMA.
+ *
+ * The macros below define a section size of 256MB and a non-linear virtual to
+ * physical mapping:
+ *
+ * 256MB @ 0x00000000 -> PAGE_OFFSET
+ * 512MB @ 0x20000000 -> PAGE_OFFSET + 0x10000000
+ * 256MB @ 0x80000000 -> PAGE_OFFSET + 0x30000000
+ */
+#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
+#error "SPARSEMEM not available with REALVIEW_HIGH_PHYS_OFFSET"
+#endif
+
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 28
+
+/* bank page offsets */
+#define PAGE_OFFSET1 (PAGE_OFFSET + 0x10000000)
+#define PAGE_OFFSET2 (PAGE_OFFSET + 0x30000000)
+
+#define __phys_to_virt(phys) \
+ ((phys) >= 0x80000000 ? (phys) - 0x80000000 + PAGE_OFFSET2 : \
+ (phys) >= 0x20000000 ? (phys) - 0x20000000 + PAGE_OFFSET1 : \
+ (phys) + PAGE_OFFSET)
+
+#define __virt_to_phys(virt) \
+ ((virt) >= PAGE_OFFSET2 ? (virt) - PAGE_OFFSET2 + 0x80000000 : \
+ (virt) >= PAGE_OFFSET1 ? (virt) - PAGE_OFFSET1 + 0x20000000 : \
+ (virt) - PAGE_OFFSET)
+
+#endif /* CONFIG_SPARSEMEM */
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/platform.h b/arch/arm/mach-realview/include/mach/platform.h
new file mode 100644
index 00000000..1b77a27b
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/platform.h
@@ -0,0 +1,249 @@
+/*
+ * arch/arm/mach-realview/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_PLATFORM_H
+#define __ASM_ARCH_PLATFORM_H
+
+/*
+ * Memory definitions
+ */
+#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)...*/
+#define REALVIEW_BOOT_ROM_HI 0x30000000
+#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */
+#define REALVIEW_BOOT_ROM_SIZE SZ_64M
+
+#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */
+#define REALVIEW_SSRAM_SIZE SZ_2M
+
+/*
+ * SDRAM
+ */
+#define REALVIEW_SDRAM_BASE 0x00000000
+
+/*
+ * Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ * RealView Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define REALVIEW_SYS_ID_OFFSET 0x00
+#define REALVIEW_SYS_SW_OFFSET 0x04
+#define REALVIEW_SYS_LED_OFFSET 0x08
+#define REALVIEW_SYS_OSC0_OFFSET 0x0C
+
+#define REALVIEW_SYS_OSC1_OFFSET 0x10
+#define REALVIEW_SYS_OSC2_OFFSET 0x14
+#define REALVIEW_SYS_OSC3_OFFSET 0x18
+#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */
+
+#define REALVIEW_SYS_LOCK_OFFSET 0x20
+#define REALVIEW_SYS_100HZ_OFFSET 0x24
+#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28
+#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C
+#define REALVIEW_SYS_FLAGS_OFFSET 0x30
+#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30
+#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34
+#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38
+#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38
+#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C
+#define REALVIEW_SYS_RESETCTL_OFFSET 0x40
+#define REALVIEW_SYS_PCICTL_OFFSET 0x44
+#define REALVIEW_SYS_MCI_OFFSET 0x48
+#define REALVIEW_SYS_FLASH_OFFSET 0x4C
+#define REALVIEW_SYS_CLCD_OFFSET 0x50
+#define REALVIEW_SYS_CLCDSER_OFFSET 0x54
+#define REALVIEW_SYS_BOOTCS_OFFSET 0x58
+#define REALVIEW_SYS_24MHz_OFFSET 0x5C
+#define REALVIEW_SYS_MISC_OFFSET 0x60
+#define REALVIEW_SYS_IOSEL_OFFSET 0x70
+#define REALVIEW_SYS_PROCID_OFFSET 0x84
+#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0
+#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4
+#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8
+#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC
+#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0
+
+#define REALVIEW_SYS_BASE 0x10000000
+#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
+#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
+#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
+#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
+#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
+
+#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
+#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
+#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
+#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
+#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
+#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
+#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
+#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
+#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
+#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
+#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
+#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
+#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
+#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
+#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
+#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
+#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
+#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
+#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
+#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
+#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET)
+#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
+#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
+#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
+#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
+#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
+
+/* ------------------------------------------------------------------------
+ * RealView control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * REALVIEW_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4 = build value
+ * 3:0 = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * REALVIEW_SYS_LOCK
+ * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ * SYS_CLD, SYS_BOOTCS
+ */
+#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
+#define REALVIEW_SYS_LOCK_VAL 0xA05F /* Enable write access */
+
+/*
+ * REALVIEW_SYS_FLASH
+ */
+#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
+
+/*
+ * REALVIEW_INTREG
+ * - used to acknowledge and control MMCI and UART interrupts
+ */
+#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */
+#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */
+#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */
+ /* write 1 to acknowledge and clear */
+#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */
+#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */
+
+/*
+ * RealView common peripheral addresses
+ */
+#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */
+#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */
+#define REALVIEW_AACI_BASE 0x10004000 /* Audio */
+#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */
+#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */
+#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */
+#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */
+#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */
+#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */
+#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */
+#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */
+#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
+
+/* PCI space */
+#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */
+#define REALVIEW_PCI_CFG_BASE 0x42000000
+#define REALVIEW_PCI_MEM_BASE0 0x44000000
+#define REALVIEW_PCI_MEM_BASE1 0x50000000
+#define REALVIEW_PCI_MEM_BASE2 0x60000000
+/* Sizes of above maps */
+#define REALVIEW_PCI_BASE_SIZE 0x01000000
+#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000
+#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
+#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
+#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
+
+#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
+#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */
+
+/*
+ * CompactFlash
+ */
+#define REALVIEW_CF_BASE 0x18000000 /* CompactFlash */
+#define REALVIEW_CF_MEM_BASE 0x18003000 /* SMC for CompactFlash */
+
+/*
+ * Disk on Chip
+ */
+#define REALVIEW_DOC_BASE 0x2C000000
+#define REALVIEW_DOC_SIZE (16 << 20)
+#define REALVIEW_DOC_PAGE_SIZE 512
+#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES 32
+#define START_PAGE 0x80
+
+/*
+ * LED settings, bits [7:0]
+ */
+#define REALVIEW_SYS_LED0 (1 << 0)
+#define REALVIEW_SYS_LED1 (1 << 1)
+#define REALVIEW_SYS_LED2 (1 << 2)
+#define REALVIEW_SYS_LED3 (1 << 3)
+#define REALVIEW_SYS_LED4 (1 << 4)
+#define REALVIEW_SYS_LED5 (1 << 5)
+#define REALVIEW_SYS_LED6 (1 << 6)
+#define REALVIEW_SYS_LED7 (1 << 7)
+
+#define ALL_LEDS 0xFF
+
+#define LED_BANK REALVIEW_SYS_LED
+
+/*
+ * Control registers
+ */
+#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */
+#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */
+#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */
+#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */
+
+/*
+ * System controller bit assignment
+ */
+#define REALVIEW_REFCLK 0
+#define REALVIEW_TIMCLK 1
+
+#define REALVIEW_TIMER1_EnSel 15
+#define REALVIEW_TIMER2_EnSel 17
+#define REALVIEW_TIMER3_EnSel 19
+#define REALVIEW_TIMER4_EnSel 21
+
+
+#define REALVIEW_CSR_BASE 0x10000000
+#define REALVIEW_CSR_SIZE 0x10000000
+
+#endif /* __ASM_ARCH_PLATFORM_H */
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
new file mode 100644
index 00000000..a30f2e3e
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/system.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-realview/include/mach/system.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+void (*realview_reset)(char mode);
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ if (realview_reset)
+ realview_reset(mode);
+}
+
+#endif
diff --git a/arch/arm/mach-realview/include/mach/timex.h b/arch/arm/mach-realview/include/mach/timex.h
new file mode 100644
index 00000000..4eeb0693
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-realview/include/mach/timex.h
+ *
+ * RealView architecture timex specifications
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-realview/include/mach/uncompress.h b/arch/arm/mach-realview/include/mach/uncompress.h
new file mode 100644
index 00000000..83050378
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/uncompress.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-realview/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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/hardware.h>
+#include <asm/mach-types.h>
+
+#include <mach/board-eb.h>
+#include <mach/board-pb11mp.h>
+#include <mach/board-pb1176.h>
+#include <mach/board-pba8.h>
+#include <mach/board-pbx.h>
+
+#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18))
+
+/*
+ * Return the UART base address
+ */
+static inline unsigned long get_uart_base(void)
+{
+ if (machine_is_realview_eb())
+ return REALVIEW_EB_UART0_BASE;
+ else if (machine_is_realview_pb11mp())
+ return REALVIEW_PB11MP_UART0_BASE;
+ else if (machine_is_realview_pb1176())
+ return REALVIEW_PB1176_UART0_BASE;
+ else if (machine_is_realview_pba8())
+ return REALVIEW_PBA8_UART0_BASE;
+ else if (machine_is_realview_pbx())
+ return REALVIEW_PBX_UART0_BASE;
+ else
+ return 0;
+}
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-realview/include/mach/vmalloc.h b/arch/arm/mach-realview/include/mach/vmalloc.h
new file mode 100644
index 00000000..a2a4c686
--- /dev/null
+++ b/arch/arm/mach-realview/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-realview/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xf8000000UL
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
new file mode 100644
index 00000000..963bf0d8
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/mach-realview/platsmp.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/init.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+
+#include <mach/board-eb.h>
+#include <mach/board-pb11mp.h>
+#include <mach/board-pbx.h>
+
+#include "core.h"
+
+extern void versatile_secondary_startup(void);
+
+static void __iomem *scu_base_addr(void)
+{
+ if (machine_is_realview_eb_mp())
+ return __io_address(REALVIEW_EB11MP_SCU_BASE);
+ else if (machine_is_realview_pb11mp())
+ return __io_address(REALVIEW_TC11MP_SCU_BASE);
+ else if (machine_is_realview_pbx() &&
+ (core_tile_pbx11mp() || core_tile_pbxa9mp()))
+ return __io_address(REALVIEW_PBX_TILE_SCU_BASE);
+ else
+ return (void __iomem *)0;
+}
+
+/*
+ * 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;
+
+ /* sanity check */
+ if (ncores > NR_CPUS) {
+ printk(KERN_WARNING
+ "Realview: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base_addr());
+
+ /*
+ * Write the address of secondary startup into the
+ * system-wide flags register. The BootMonitor waits
+ * until it receives a soft interrupt, and then the
+ * secondary CPU branches to this address.
+ */
+ __raw_writel(BSYM(virt_to_phys(versatile_secondary_startup)),
+ __io_address(REALVIEW_SYS_FLAGSSET));
+}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
new file mode 100644
index 00000000..10e75fab
--- /dev/null
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -0,0 +1,473 @@
+/*
+ * linux/arch/arm/mach-realview/realview_eb.c
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/localtimer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-eb.h>
+#include <mach/irqs.h>
+
+#include "core.h"
+
+static struct map_desc realview_eb_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_EB_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }
+#endif
+};
+
+static struct map_desc realview_eb11mp_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_EB11MP_L220_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void __init realview_eb_map_io(void)
+{
+ iotable_init(realview_eb_io_desc, ARRAY_SIZE(realview_eb_io_desc));
+ if (core_tile_eb11mp() || core_tile_a9mp())
+ iotable_init(realview_eb11mp_io_desc, ARRAY_SIZE(realview_eb11mp_io_desc));
+}
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = -1,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+/*
+ * RealView EB AMBA devices
+ */
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
+
+#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
+#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
+
+/*
+ * These devices are connected directly to the multi-layer AHB switch
+ */
+#define EB_SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ }
+#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ }
+#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ }
+#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ }
+#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ }
+#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ }
+#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ }
+#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ }
+#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:smc", EB_SMC, NULL);
+AMBA_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "dev:dmac", DMAC, NULL);
+AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(rtc, "dev:rtc", EB_RTC, NULL);
+AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
+AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
+AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * RealView EB platform devices
+ */
+static struct resource realview_eb_flash_resource = {
+ .start = REALVIEW_EB_FLASH_BASE,
+ .end = REALVIEW_EB_FLASH_BASE + REALVIEW_EB_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource realview_eb_eth_resources[] = {
+ [0] = {
+ .start = REALVIEW_EB_ETH_BASE,
+ .end = REALVIEW_EB_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EB_ETH,
+ .end = IRQ_EB_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * Detect and register the correct Ethernet device. RealView/EB rev D
+ * platforms use the newer SMSC LAN9118 Ethernet chip
+ */
+static int eth_device_register(void)
+{
+ void __iomem *eth_addr = ioremap(REALVIEW_EB_ETH_BASE, SZ_4K);
+ const char *name = NULL;
+ u32 idrev;
+
+ if (!eth_addr)
+ return -ENOMEM;
+
+ idrev = readl(eth_addr + 0x50);
+ if ((idrev & 0xFFFF0000) != 0x01180000)
+ /* SMSC LAN9118 not present, use LAN91C111 instead */
+ name = "smc91x";
+
+ iounmap(eth_addr);
+ return realview_eth_register(name, realview_eb_eth_resources);
+}
+
+static struct resource realview_eb_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_EB_USB_BASE,
+ .end = REALVIEW_EB_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EB_USB,
+ .end = IRQ_EB_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pmu_resources[] = {
+ [0] = {
+ .start = IRQ_EB11MP_PMU_CPU0,
+ .end = IRQ_EB11MP_PMU_CPU0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_EB11MP_PMU_CPU1,
+ .end = IRQ_EB11MP_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_EB11MP_PMU_CPU2,
+ .end = IRQ_EB11MP_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_EB11MP_PMU_CPU3,
+ .end = IRQ_EB11MP_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+static struct resource char_lcd_resources[] = {
+ {
+ .start = REALVIEW_CHAR_LCD_BASE,
+ .end = (REALVIEW_CHAR_LCD_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_EB_CHARLCD,
+ .end = IRQ_EB_CHARLCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device char_lcd_device = {
+ .name = "arm-charlcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(char_lcd_resources),
+ .resource = char_lcd_resources,
+};
+
+static void __init gic_init_irq(void)
+{
+ if (core_tile_eb11mp() || core_tile_a9mp()) {
+ unsigned int pldctrl;
+
+ /* new irq mode */
+ writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
+ pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_EB11MP_SYS_PLD_CTRL1);
+ pldctrl |= 0x00800000;
+ writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_EB11MP_SYS_PLD_CTRL1);
+ writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
+
+ /* core tile GIC, primary */
+ gic_init(0, 29, __io_address(REALVIEW_EB11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB11MP_GIC_CPU_BASE));
+
+#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
+ /* board GIC, secondary */
+ gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB_GIC_CPU_BASE));
+ gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
+#endif
+ } else {
+ /* board GIC, primary */
+ gic_init(0, 29, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+ __io_address(REALVIEW_EB_GIC_CPU_BASE));
+ }
+}
+
+/*
+ * Fix up the IRQ numbers for the RealView EB/ARM11MPCore tile
+ */
+static void realview_eb11mp_fixup(void)
+{
+ /* AMBA devices */
+ dmac_device.irq[0] = IRQ_EB11MP_DMA;
+ uart0_device.irq[0] = IRQ_EB11MP_UART0;
+ uart1_device.irq[0] = IRQ_EB11MP_UART1;
+ uart2_device.irq[0] = IRQ_EB11MP_UART2;
+ uart3_device.irq[0] = IRQ_EB11MP_UART3;
+ clcd_device.irq[0] = IRQ_EB11MP_CLCD;
+ wdog_device.irq[0] = IRQ_EB11MP_WDOG;
+ gpio0_device.irq[0] = IRQ_EB11MP_GPIO0;
+ gpio1_device.irq[0] = IRQ_EB11MP_GPIO1;
+ gpio2_device.irq[0] = IRQ_EB11MP_GPIO2;
+ rtc_device.irq[0] = IRQ_EB11MP_RTC;
+ sci0_device.irq[0] = IRQ_EB11MP_SCI;
+ ssp0_device.irq[0] = IRQ_EB11MP_SSP;
+ aaci_device.irq[0] = IRQ_EB11MP_AACI;
+ mmc0_device.irq[0] = IRQ_EB11MP_MMCI0A;
+ mmc0_device.irq[1] = IRQ_EB11MP_MMCI0B;
+ kmi0_device.irq[0] = IRQ_EB11MP_KMI0;
+ kmi1_device.irq[0] = IRQ_EB11MP_KMI1;
+
+ /* platform devices */
+ realview_eb_eth_resources[1].start = IRQ_EB11MP_ETH;
+ realview_eb_eth_resources[1].end = IRQ_EB11MP_ETH;
+ realview_eb_isp1761_resources[1].start = IRQ_EB11MP_USB;
+ realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB;
+}
+
+static void __init realview_eb_timer_init(void)
+{
+ unsigned int timer_irq;
+
+ timer0_va_base = __io_address(REALVIEW_EB_TIMER0_1_BASE);
+ timer1_va_base = __io_address(REALVIEW_EB_TIMER0_1_BASE) + 0x20;
+ timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
+ timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
+
+ if (core_tile_eb11mp() || core_tile_a9mp()) {
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
+#endif
+ timer_irq = IRQ_EB11MP_TIMER0_1;
+ } else
+ timer_irq = IRQ_EB_TIMER0_1;
+
+ realview_timer_init(timer_irq);
+}
+
+static struct sys_timer realview_eb_timer = {
+ .init = realview_eb_timer_init,
+};
+
+static void realview_eb_reset(char mode)
+{
+ void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+ void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+ if (core_tile_eb11mp())
+ __raw_writel(0x0008, reset_ctrl);
+}
+
+static void __init realview_eb_init(void)
+{
+ int i;
+
+ if (core_tile_eb11mp() || core_tile_a9mp()) {
+ realview_eb11mp_fixup();
+
+#ifdef CONFIG_CACHE_L2X0
+ /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
+ * Bits: .... ...0 0111 1001 0000 .... .... .... */
+ l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
+#endif
+ platform_device_register(&pmu_device);
+ }
+
+ realview_flash_register(&realview_eb_flash_resource, 1);
+ platform_device_register(&realview_i2c_device);
+ platform_device_register(&char_lcd_device);
+ eth_device_register();
+ realview_usb_register(realview_eb_isp1761_resources);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+ realview_reset = realview_eb_reset;
+}
+
+MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
+ .map_io = realview_eb_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .timer = &realview_eb_timer,
+ .init_machine = realview_eb_init,
+MACHINE_END
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
new file mode 100644
index 00000000..eab6070f
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -0,0 +1,368 @@
+/*
+ * linux/arch/arm/mach-realview/realview_pb1176.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-pb1176.h>
+#include <mach/irqs.h>
+
+#include "core.h"
+
+static struct map_desc realview_pb1176_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_DC1176_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_DC1176_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_DC1176_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_DC1176_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_L220_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_L220_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_PB1176_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB1176_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
+};
+
+static void __init realview_pb1176_map_io(void)
+{
+ iotable_init(realview_pb1176_io_desc, ARRAY_SIZE(realview_pb1176_io_desc));
+}
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = -1,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+/*
+ * RealView PB1176 AMBA devices
+ */
+#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ }
+#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
+#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ }
+#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ }
+#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ }
+#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ }
+#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ }
+#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ }
+#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ }
+#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ }
+#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ }
+#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ }
+#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+AMBA_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:smc", PB1176_SMC, NULL);
+AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL);
+AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL);
+AMBA_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL);
+AMBA_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL);
+AMBA_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL);
+AMBA_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data);
+AMBA_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &uart4_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * RealView PB1176 platform devices
+ */
+static struct resource realview_pb1176_flash_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB1176_FLASH_BASE,
+ .end = REALVIEW_PB1176_FLASH_BASE + REALVIEW_PB1176_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_PB1176_SEC_FLASH_BASE,
+ .end = REALVIEW_PB1176_SEC_FLASH_BASE + REALVIEW_PB1176_SEC_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+#ifdef CONFIG_REALVIEW_PB1176_SECURE_FLASH
+#define PB1176_FLASH_BLOCKS 2
+#else
+#define PB1176_FLASH_BLOCKS 1
+#endif
+
+static struct resource realview_pb1176_smsc911x_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB1176_ETH_BASE,
+ .end = REALVIEW_PB1176_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PB1176_ETH,
+ .end = IRQ_PB1176_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource realview_pb1176_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB1176_USB_BASE,
+ .end = REALVIEW_PB1176_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PB1176_USB,
+ .end = IRQ_PB1176_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pmu_resource = {
+ .start = IRQ_DC1176_CORE_PMU,
+ .end = IRQ_DC1176_CORE_PMU,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = 1,
+ .resource = &pmu_resource,
+};
+
+static struct resource char_lcd_resources[] = {
+ {
+ .start = REALVIEW_CHAR_LCD_BASE,
+ .end = (REALVIEW_CHAR_LCD_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_PB1176_CHARLCD,
+ .end = IRQ_PB1176_CHARLCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device char_lcd_device = {
+ .name = "arm-charlcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(char_lcd_resources),
+ .resource = char_lcd_resources,
+};
+
+static void __init gic_init_irq(void)
+{
+ /* ARM1176 DevChip GIC, primary */
+ gic_init(0, IRQ_DC1176_GIC_START,
+ __io_address(REALVIEW_DC1176_GIC_DIST_BASE),
+ __io_address(REALVIEW_DC1176_GIC_CPU_BASE));
+
+ /* board GIC, secondary */
+ gic_init(1, IRQ_PB1176_GIC_START,
+ __io_address(REALVIEW_PB1176_GIC_DIST_BASE),
+ __io_address(REALVIEW_PB1176_GIC_CPU_BASE));
+ gic_cascade_irq(1, IRQ_DC1176_PB_IRQ1);
+}
+
+static void __init realview_pb1176_timer_init(void)
+{
+ timer0_va_base = __io_address(REALVIEW_PB1176_TIMER0_1_BASE);
+ timer1_va_base = __io_address(REALVIEW_PB1176_TIMER0_1_BASE) + 0x20;
+ timer2_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE);
+ timer3_va_base = __io_address(REALVIEW_PB1176_TIMER2_3_BASE) + 0x20;
+
+ realview_timer_init(IRQ_DC1176_TIMER0);
+}
+
+static struct sys_timer realview_pb1176_timer = {
+ .init = realview_pb1176_timer_init,
+};
+
+static void realview_pb1176_reset(char mode)
+{
+ void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+ void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+ __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+ __raw_writel(REALVIEW_PB1176_SYS_SOFT_RESET, reset_ctrl);
+}
+
+static void realview_pb1176_fixup(struct machine_desc *mdesc,
+ struct tag *tags, char **from,
+ struct meminfo *meminfo)
+{
+ /*
+ * RealView PB1176 only has 128MB of RAM mapped at 0.
+ */
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_128M;
+ meminfo->nr_banks = 1;
+}
+
+static void __init realview_pb1176_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ /* 128Kb (16Kb/way) 8-way associativity. evmon/parity/share enabled. */
+ l2x0_init(__io_address(REALVIEW_PB1176_L220_BASE), 0x00730000, 0xfe000fff);
+#endif
+
+ realview_flash_register(realview_pb1176_flash_resources,
+ PB1176_FLASH_BLOCKS);
+ realview_eth_register(NULL, realview_pb1176_smsc911x_resources);
+ platform_device_register(&realview_i2c_device);
+ realview_usb_register(realview_pb1176_isp1761_resources);
+ platform_device_register(&pmu_device);
+ platform_device_register(&char_lcd_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+ realview_reset = realview_pb1176_reset;
+}
+
+MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .fixup = realview_pb1176_fixup,
+ .map_io = realview_pb1176_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .timer = &realview_pb1176_timer,
+ .init_machine = realview_pb1176_init,
+MACHINE_END
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
new file mode 100644
index 00000000..b2985fc7
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -0,0 +1,370 @@
+/*
+ * linux/arch/arm/mach-realview/realview_pb11mp.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/localtimer.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/board-pb11mp.h>
+#include <mach/irqs.h>
+
+#include "core.h"
+
+static struct map_desc realview_pb11mp_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB11MP_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB11MP_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB11MP_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB11MP_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB11MP_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB11MP_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PB11MP_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB11MP_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_TC11MP_L220_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_TC11MP_L220_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_PB11MP_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PB11MP_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
+};
+
+static void __init realview_pb11mp_map_io(void)
+{
+ iotable_init(realview_pb11mp_io_desc, ARRAY_SIZE(realview_pb11mp_io_desc));
+}
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = -1,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+/*
+ * RealView PB11MPCore AMBA devices
+ */
+
+#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ }
+#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
+#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ }
+#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ }
+#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ }
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ }
+#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ }
+#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ }
+#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ }
+#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ }
+#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ }
+#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ }
+#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ }
+#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+AMBA_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL);
+AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL);
+AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL);
+AMBA_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL);
+AMBA_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AMBA_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * RealView PB11MPCore platform devices
+ */
+static struct resource realview_pb11mp_flash_resource[] = {
+ [0] = {
+ .start = REALVIEW_PB11MP_FLASH0_BASE,
+ .end = REALVIEW_PB11MP_FLASH0_BASE + REALVIEW_PB11MP_FLASH0_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_PB11MP_FLASH1_BASE,
+ .end = REALVIEW_PB11MP_FLASH1_BASE + REALVIEW_PB11MP_FLASH1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource realview_pb11mp_smsc911x_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB11MP_ETH_BASE,
+ .end = REALVIEW_PB11MP_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC11MP_ETH,
+ .end = IRQ_TC11MP_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource realview_pb11mp_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_PB11MP_USB_BASE,
+ .end = REALVIEW_PB11MP_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC11MP_USB,
+ .end = IRQ_TC11MP_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pmu_resources[] = {
+ [0] = {
+ .start = IRQ_TC11MP_PMU_CPU0,
+ .end = IRQ_TC11MP_PMU_CPU0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_TC11MP_PMU_CPU1,
+ .end = IRQ_TC11MP_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_TC11MP_PMU_CPU2,
+ .end = IRQ_TC11MP_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_TC11MP_PMU_CPU3,
+ .end = IRQ_TC11MP_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+static void __init gic_init_irq(void)
+{
+ unsigned int pldctrl;
+
+ /* new irq mode with no DCC */
+ writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
+ pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_PB11MP_SYS_PLD_CTRL1);
+ pldctrl |= 2 << 22;
+ writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_PB11MP_SYS_PLD_CTRL1);
+ writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
+
+ /* ARM11MPCore test chip GIC, primary */
+ gic_init(0, 29, __io_address(REALVIEW_TC11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_TC11MP_GIC_CPU_BASE));
+
+ /* board GIC, secondary */
+ gic_init(1, IRQ_PB11MP_GIC_START,
+ __io_address(REALVIEW_PB11MP_GIC_DIST_BASE),
+ __io_address(REALVIEW_PB11MP_GIC_CPU_BASE));
+ gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
+}
+
+static void __init realview_pb11mp_timer_init(void)
+{
+ timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
+ timer1_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE) + 0x20;
+ timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
+ timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
+
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
+#endif
+ realview_timer_init(IRQ_TC11MP_TIMER0_1);
+}
+
+static struct sys_timer realview_pb11mp_timer = {
+ .init = realview_pb11mp_timer_init,
+};
+
+static void realview_pb11mp_reset(char mode)
+{
+ void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+ void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+ __raw_writel(0x0000, reset_ctrl);
+ __raw_writel(0x0004, reset_ctrl);
+}
+
+static void __init realview_pb11mp_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
+ * Bits: .... ...0 0111 1001 0000 .... .... .... */
+ l2x0_init(__io_address(REALVIEW_TC11MP_L220_BASE), 0x00790000, 0xfe000fff);
+#endif
+
+ realview_flash_register(realview_pb11mp_flash_resource,
+ ARRAY_SIZE(realview_pb11mp_flash_resource));
+ realview_eth_register(NULL, realview_pb11mp_smsc911x_resources);
+ platform_device_register(&realview_i2c_device);
+ platform_device_register(&realview_cf_device);
+ realview_usb_register(realview_pb11mp_isp1761_resources);
+ platform_device_register(&pmu_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+ realview_reset = realview_pb11mp_reset;
+}
+
+MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
+ .map_io = realview_pb11mp_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .timer = &realview_pb11mp_timer,
+ .init_machine = realview_pb11mp_init,
+MACHINE_END
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
new file mode 100644
index 00000000..fb686655
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -0,0 +1,320 @@
+/*
+ * linux/arch/arm/mach-realview/realview_pba8.c
+ *
+ * Copyright (C) 2008 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/gic.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/board-pba8.h>
+#include <mach/irqs.h>
+
+#include "core.h"
+
+static struct map_desc realview_pba8_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBA8_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBA8_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBA8_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBA8_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_PCI
+ {
+ .virtual = PCIX_UNIT_BASE,
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_PCI_BASE),
+ .length = REALVIEW_PBA8_PCI_BASE_SIZE,
+ .type = MT_DEVICE
+ },
+#endif
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_PBA8_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBA8_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
+};
+
+static void __init realview_pba8_map_io(void)
+{
+ iotable_init(realview_pba8_io_desc, ARRAY_SIZE(realview_pba8_io_desc));
+}
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = -1,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+/*
+ * RealView PBA8Core AMBA devices
+ */
+
+#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ }
+#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
+#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ }
+#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ }
+#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ }
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ }
+#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ }
+#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ }
+#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ }
+#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ }
+#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ }
+#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ }
+#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ }
+#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+AMBA_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:smc", PBA8_SMC, NULL);
+AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL);
+AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL);
+AMBA_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL);
+AMBA_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AMBA_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * RealView PB-A8 platform devices
+ */
+static struct resource realview_pba8_flash_resource[] = {
+ [0] = {
+ .start = REALVIEW_PBA8_FLASH0_BASE,
+ .end = REALVIEW_PBA8_FLASH0_BASE + REALVIEW_PBA8_FLASH0_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_PBA8_FLASH1_BASE,
+ .end = REALVIEW_PBA8_FLASH1_BASE + REALVIEW_PBA8_FLASH1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource realview_pba8_smsc911x_resources[] = {
+ [0] = {
+ .start = REALVIEW_PBA8_ETH_BASE,
+ .end = REALVIEW_PBA8_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PBA8_ETH,
+ .end = IRQ_PBA8_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource realview_pba8_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_PBA8_USB_BASE,
+ .end = REALVIEW_PBA8_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PBA8_USB,
+ .end = IRQ_PBA8_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pmu_resource = {
+ .start = IRQ_PBA8_PMU,
+ .end = IRQ_PBA8_PMU,
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = 1,
+ .resource = &pmu_resource,
+};
+
+static void __init gic_init_irq(void)
+{
+ /* ARM PB-A8 on-board GIC */
+ gic_init(0, IRQ_PBA8_GIC_START,
+ __io_address(REALVIEW_PBA8_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBA8_GIC_CPU_BASE));
+}
+
+static void __init realview_pba8_timer_init(void)
+{
+ timer0_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE);
+ timer1_va_base = __io_address(REALVIEW_PBA8_TIMER0_1_BASE) + 0x20;
+ timer2_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE);
+ timer3_va_base = __io_address(REALVIEW_PBA8_TIMER2_3_BASE) + 0x20;
+
+ realview_timer_init(IRQ_PBA8_TIMER0_1);
+}
+
+static struct sys_timer realview_pba8_timer = {
+ .init = realview_pba8_timer_init,
+};
+
+static void realview_pba8_reset(char mode)
+{
+ void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+ void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+ __raw_writel(0x0000, reset_ctrl);
+ __raw_writel(0x0004, reset_ctrl);
+}
+
+static void __init realview_pba8_init(void)
+{
+ int i;
+
+ realview_flash_register(realview_pba8_flash_resource,
+ ARRAY_SIZE(realview_pba8_flash_resource));
+ realview_eth_register(NULL, realview_pba8_smsc911x_resources);
+ platform_device_register(&realview_i2c_device);
+ platform_device_register(&realview_cf_device);
+ realview_usb_register(realview_pba8_isp1761_resources);
+ platform_device_register(&pmu_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+ realview_reset = realview_pba8_reset;
+}
+
+MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .fixup = realview_fixup,
+ .map_io = realview_pba8_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .timer = &realview_pba8_timer,
+ .init_machine = realview_pba8_init,
+MACHINE_END
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
new file mode 100644
index 00000000..92ace2cf
--- /dev/null
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -0,0 +1,403 @@
+/*
+ * arch/arm/mach-realview/realview_pbx.c
+ *
+ * Copyright (C) 2009 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/pmu.h>
+#include <asm/smp_twd.h>
+#include <asm/pgtable.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/board-pbx.h>
+#include <mach/irqs.h>
+
+#include "core.h"
+
+static struct map_desc realview_pbx_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_SYS_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_TIMER0_1_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TIMER0_1_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_TIMER2_3_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TIMER2_3_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#ifdef CONFIG_PCI
+ {
+ .virtual = PCIX_UNIT_BASE,
+ .pfn = __phys_to_pfn(REALVIEW_PBX_PCI_BASE),
+ .length = REALVIEW_PBX_PCI_BASE_SIZE,
+ .type = MT_DEVICE,
+ },
+#endif
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_UART0_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+#endif
+};
+
+static struct map_desc realview_local_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_GIC_CPU_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_GIC_CPU_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_GIC_DIST_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_GIC_DIST_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = IO_ADDRESS(REALVIEW_PBX_TILE_L220_BASE),
+ .pfn = __phys_to_pfn(REALVIEW_PBX_TILE_L220_BASE),
+ .length = SZ_8K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void __init realview_pbx_map_io(void)
+{
+ iotable_init(realview_pbx_io_desc, ARRAY_SIZE(realview_pbx_io_desc));
+ if (core_tile_pbx11mp() || core_tile_pbxa9mp())
+ iotable_init(realview_local_io_desc, ARRAY_SIZE(realview_local_io_desc));
+}
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = -1,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+/*
+ * RealView PBXCore AMBA devices
+ */
+
+#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
+#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
+#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
+#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ }
+#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ }
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ }
+#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ }
+#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ }
+#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ }
+#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ }
+#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ }
+#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ }
+#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ }
+#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+AMBA_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:smc", PBX_SMC, NULL);
+AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL);
+AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL);
+AMBA_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL);
+AMBA_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data);
+
+/* Primecells on the NEC ISSP chip */
+AMBA_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &smc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &gpio2_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+/*
+ * RealView PB-X platform devices
+ */
+static struct resource realview_pbx_flash_resources[] = {
+ [0] = {
+ .start = REALVIEW_PBX_FLASH0_BASE,
+ .end = REALVIEW_PBX_FLASH0_BASE + REALVIEW_PBX_FLASH0_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = REALVIEW_PBX_FLASH1_BASE,
+ .end = REALVIEW_PBX_FLASH1_BASE + REALVIEW_PBX_FLASH1_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource realview_pbx_smsc911x_resources[] = {
+ [0] = {
+ .start = REALVIEW_PBX_ETH_BASE,
+ .end = REALVIEW_PBX_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PBX_ETH,
+ .end = IRQ_PBX_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource realview_pbx_isp1761_resources[] = {
+ [0] = {
+ .start = REALVIEW_PBX_USB_BASE,
+ .end = REALVIEW_PBX_USB_BASE + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PBX_USB,
+ .end = IRQ_PBX_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource pmu_resources[] = {
+ [0] = {
+ .start = IRQ_PBX_PMU_CPU0,
+ .end = IRQ_PBX_PMU_CPU0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_PBX_PMU_CPU1,
+ .end = IRQ_PBX_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_PBX_PMU_CPU2,
+ .end = IRQ_PBX_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_PBX_PMU_CPU3,
+ .end = IRQ_PBX_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+static void __init gic_init_irq(void)
+{
+ /* ARM PBX on-board GIC */
+ if (core_tile_pbx11mp() || core_tile_pbxa9mp()) {
+ gic_init(0, 29, __io_address(REALVIEW_PBX_TILE_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBX_TILE_GIC_CPU_BASE));
+ } else {
+ gic_init(0, IRQ_PBX_GIC_START,
+ __io_address(REALVIEW_PBX_GIC_DIST_BASE),
+ __io_address(REALVIEW_PBX_GIC_CPU_BASE));
+ }
+}
+
+static void __init realview_pbx_timer_init(void)
+{
+ timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
+ timer1_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE) + 0x20;
+ timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
+ timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
+
+#ifdef CONFIG_LOCAL_TIMERS
+ if (core_tile_pbx11mp() || core_tile_pbxa9mp())
+ twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
+#endif
+ realview_timer_init(IRQ_PBX_TIMER0_1);
+}
+
+static struct sys_timer realview_pbx_timer = {
+ .init = realview_pbx_timer_init,
+};
+
+static void realview_pbx_fixup(struct machine_desc *mdesc, struct tag *tags,
+ char **from, struct meminfo *meminfo)
+{
+#ifdef CONFIG_SPARSEMEM
+ /*
+ * Memory configuration with SPARSEMEM enabled on RealView PBX (see
+ * asm/mach/memory.h for more information).
+ */
+ meminfo->bank[0].start = 0;
+ meminfo->bank[0].size = SZ_256M;
+ meminfo->bank[1].start = 0x20000000;
+ meminfo->bank[1].size = SZ_512M;
+ meminfo->bank[2].start = 0x80000000;
+ meminfo->bank[2].size = SZ_256M;
+ meminfo->nr_banks = 3;
+#else
+ realview_fixup(mdesc, tags, from, meminfo);
+#endif
+}
+
+static void realview_pbx_reset(char mode)
+{
+ void __iomem *reset_ctrl = __io_address(REALVIEW_SYS_RESETCTL);
+ void __iomem *lock_ctrl = __io_address(REALVIEW_SYS_LOCK);
+
+ /*
+ * To reset, we hit the on-board reset register
+ * in the system FPGA
+ */
+ __raw_writel(REALVIEW_SYS_LOCK_VAL, lock_ctrl);
+ __raw_writel(0x00F0, reset_ctrl);
+ __raw_writel(0x00F4, reset_ctrl);
+}
+
+static void __init realview_pbx_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ if (core_tile_pbxa9mp()) {
+ void __iomem *l2x0_base =
+ __io_address(REALVIEW_PBX_TILE_L220_BASE);
+
+ /* set RAM latencies to 1 cycle for eASIC */
+ writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
+ writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+ /* 16KB way size, 8-way associativity, parity disabled
+ * Bits: .. 0 0 0 0 1 00 1 0 1 001 0 000 0 .... .... .... */
+ l2x0_init(l2x0_base, 0x02520000, 0xc0000fff);
+ platform_device_register(&pmu_device);
+ }
+#endif
+
+ realview_flash_register(realview_pbx_flash_resources,
+ ARRAY_SIZE(realview_pbx_flash_resources));
+ realview_eth_register(NULL, realview_pbx_smsc911x_resources);
+ platform_device_register(&realview_i2c_device);
+ platform_device_register(&realview_cf_device);
+ realview_usb_register(realview_pbx_isp1761_resources);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = realview_leds_event;
+#endif
+ realview_reset = realview_pbx_reset;
+}
+
+MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .fixup = realview_pbx_fixup,
+ .map_io = realview_pbx_map_io,
+ .init_early = realview_init_early,
+ .init_irq = gic_init_irq,
+ .timer = &realview_pbx_timer,
+ .init_machine = realview_pbx_init,
+MACHINE_END
diff --git a/arch/arm/mach-rpc/Makefile b/arch/arm/mach-rpc/Makefile
new file mode 100644
index 00000000..aa77bc9e
--- /dev/null
+++ b/arch/arm/mach-rpc/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := dma.o irq.o riscpc.o
+obj-m :=
+obj-n :=
+obj- :=
+
diff --git a/arch/arm/mach-rpc/Makefile.boot b/arch/arm/mach-rpc/Makefile.boot
new file mode 100644
index 00000000..9c9e7685
--- /dev/null
+++ b/arch/arm/mach-rpc/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x10008000
+params_phys-y := 0x10000100
+initrd_phys-y := 0x18000000
+
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
new file mode 100644
index 00000000..85883b2e
--- /dev/null
+++ b/arch/arm/mach-rpc/dma.c
@@ -0,0 +1,389 @@
+/*
+ * linux/arch/arm/mach-rpc/dma.c
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DMA functions specific to RiscPC architecture
+ */
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/fiq.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/uaccess.h>
+
+#include <asm/mach/dma.h>
+#include <asm/hardware/iomd.h>
+
+struct iomd_dma {
+ struct dma_struct dma;
+ unsigned int state;
+ unsigned long base; /* Controller base address */
+ int irq; /* Controller IRQ */
+ struct scatterlist cur_sg; /* Current controller buffer */
+ dma_addr_t dma_addr;
+ unsigned int dma_len;
+};
+
+#if 0
+typedef enum {
+ dma_size_8 = 1,
+ dma_size_16 = 2,
+ dma_size_32 = 4,
+ dma_size_128 = 16
+} dma_size_t;
+#endif
+
+#define TRANSFER_SIZE 2
+
+#define CURA (0)
+#define ENDA (IOMD_IO0ENDA - IOMD_IO0CURA)
+#define CURB (IOMD_IO0CURB - IOMD_IO0CURA)
+#define ENDB (IOMD_IO0ENDB - IOMD_IO0CURA)
+#define CR (IOMD_IO0CR - IOMD_IO0CURA)
+#define ST (IOMD_IO0ST - IOMD_IO0CURA)
+
+static void iomd_get_next_sg(struct scatterlist *sg, struct iomd_dma *idma)
+{
+ unsigned long end, offset, flags = 0;
+
+ if (idma->dma.sg) {
+ sg->dma_address = idma->dma_addr;
+ offset = sg->dma_address & ~PAGE_MASK;
+
+ end = offset + idma->dma_len;
+
+ if (end > PAGE_SIZE)
+ end = PAGE_SIZE;
+
+ if (offset + TRANSFER_SIZE >= end)
+ flags |= DMA_END_L;
+
+ sg->length = end - TRANSFER_SIZE;
+
+ idma->dma_len -= end - offset;
+ idma->dma_addr += end - offset;
+
+ if (idma->dma_len == 0) {
+ if (idma->dma.sgcount > 1) {
+ idma->dma.sg = sg_next(idma->dma.sg);
+ idma->dma_addr = idma->dma.sg->dma_address;
+ idma->dma_len = idma->dma.sg->length;
+ idma->dma.sgcount--;
+ } else {
+ idma->dma.sg = NULL;
+ flags |= DMA_END_S;
+ }
+ }
+ } else {
+ flags = DMA_END_S | DMA_END_L;
+ sg->dma_address = 0;
+ sg->length = 0;
+ }
+
+ sg->length |= flags;
+}
+
+static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
+{
+ struct iomd_dma *idma = dev_id;
+ unsigned long base = idma->base;
+
+ do {
+ unsigned int status;
+
+ status = iomd_readb(base + ST);
+ if (!(status & DMA_ST_INT))
+ return IRQ_HANDLED;
+
+ if ((idma->state ^ status) & DMA_ST_AB)
+ iomd_get_next_sg(&idma->cur_sg, idma);
+
+ switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
+ case DMA_ST_OFL: /* OIA */
+ case DMA_ST_AB: /* .IB */
+ iomd_writel(idma->cur_sg.dma_address, base + CURA);
+ iomd_writel(idma->cur_sg.length, base + ENDA);
+ idma->state = DMA_ST_AB;
+ break;
+
+ case DMA_ST_OFL | DMA_ST_AB: /* OIB */
+ case 0: /* .IA */
+ iomd_writel(idma->cur_sg.dma_address, base + CURB);
+ iomd_writel(idma->cur_sg.length, base + ENDB);
+ idma->state = 0;
+ break;
+ }
+
+ if (status & DMA_ST_OFL &&
+ idma->cur_sg.length == (DMA_END_S|DMA_END_L))
+ break;
+ } while (1);
+
+ idma->state = ~DMA_ST_AB;
+ disable_irq(irq);
+
+ return IRQ_HANDLED;
+}
+
+static int iomd_request_dma(unsigned int chan, dma_t *dma)
+{
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+ return request_irq(idma->irq, iomd_dma_handle,
+ IRQF_DISABLED, idma->dma.device_id, idma);
+}
+
+static void iomd_free_dma(unsigned int chan, dma_t *dma)
+{
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+
+ free_irq(idma->irq, idma);
+}
+
+static void iomd_enable_dma(unsigned int chan, dma_t *dma)
+{
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+ unsigned long dma_base = idma->base;
+ unsigned int ctrl = TRANSFER_SIZE | DMA_CR_E;
+
+ if (idma->dma.invalid) {
+ idma->dma.invalid = 0;
+
+ /*
+ * Cope with ISA-style drivers which expect cache
+ * coherence.
+ */
+ if (!idma->dma.sg) {
+ idma->dma.sg = &idma->dma.buf;
+ idma->dma.sgcount = 1;
+ idma->dma.buf.length = idma->dma.count;
+ idma->dma.buf.dma_address = dma_map_single(NULL,
+ idma->dma.addr, idma->dma.count,
+ idma->dma.dma_mode == DMA_MODE_READ ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+
+ iomd_writeb(DMA_CR_C, dma_base + CR);
+ idma->state = DMA_ST_AB;
+ }
+
+ if (idma->dma.dma_mode == DMA_MODE_READ)
+ ctrl |= DMA_CR_D;
+
+ iomd_writeb(ctrl, dma_base + CR);
+ enable_irq(idma->irq);
+}
+
+static void iomd_disable_dma(unsigned int chan, dma_t *dma)
+{
+ struct iomd_dma *idma = container_of(dma, struct iomd_dma, dma);
+ unsigned long dma_base = idma->base;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (idma->state != ~DMA_ST_AB)
+ disable_irq(idma->irq);
+ iomd_writeb(0, dma_base + CR);
+ local_irq_restore(flags);
+}
+
+static int iomd_set_dma_speed(unsigned int chan, dma_t *dma, int cycle)
+{
+ int tcr, speed;
+
+ if (cycle < 188)
+ speed = 3;
+ else if (cycle <= 250)
+ speed = 2;
+ else if (cycle < 438)
+ speed = 1;
+ else
+ speed = 0;
+
+ tcr = iomd_readb(IOMD_DMATCR);
+ speed &= 3;
+
+ switch (chan) {
+ case DMA_0:
+ tcr = (tcr & ~0x03) | speed;
+ break;
+
+ case DMA_1:
+ tcr = (tcr & ~0x0c) | (speed << 2);
+ break;
+
+ case DMA_2:
+ tcr = (tcr & ~0x30) | (speed << 4);
+ break;
+
+ case DMA_3:
+ tcr = (tcr & ~0xc0) | (speed << 6);
+ break;
+
+ default:
+ break;
+ }
+
+ iomd_writeb(tcr, IOMD_DMATCR);
+
+ return speed;
+}
+
+static struct dma_ops iomd_dma_ops = {
+ .type = "IOMD",
+ .request = iomd_request_dma,
+ .free = iomd_free_dma,
+ .enable = iomd_enable_dma,
+ .disable = iomd_disable_dma,
+ .setspeed = iomd_set_dma_speed,
+};
+
+static struct fiq_handler fh = {
+ .name = "floppydma"
+};
+
+struct floppy_dma {
+ struct dma_struct dma;
+ unsigned int fiq;
+};
+
+static void floppy_enable_dma(unsigned int chan, dma_t *dma)
+{
+ struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
+ void *fiqhandler_start;
+ unsigned int fiqhandler_length;
+ struct pt_regs regs;
+
+ if (fdma->dma.sg)
+ BUG();
+
+ if (fdma->dma.dma_mode == DMA_MODE_READ) {
+ extern unsigned char floppy_fiqin_start, floppy_fiqin_end;
+ fiqhandler_start = &floppy_fiqin_start;
+ fiqhandler_length = &floppy_fiqin_end - &floppy_fiqin_start;
+ } else {
+ extern unsigned char floppy_fiqout_start, floppy_fiqout_end;
+ fiqhandler_start = &floppy_fiqout_start;
+ fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
+ }
+
+ regs.ARM_r9 = fdma->dma.count;
+ regs.ARM_r10 = (unsigned long)fdma->dma.addr;
+ regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE;
+
+ if (claim_fiq(&fh)) {
+ printk("floppydma: couldn't claim FIQ.\n");
+ return;
+ }
+
+ set_fiq_handler(fiqhandler_start, fiqhandler_length);
+ set_fiq_regs(&regs);
+ enable_fiq(fdma->fiq);
+}
+
+static void floppy_disable_dma(unsigned int chan, dma_t *dma)
+{
+ struct floppy_dma *fdma = container_of(dma, struct floppy_dma, dma);
+ disable_fiq(fdma->fiq);
+ release_fiq(&fh);
+}
+
+static int floppy_get_residue(unsigned int chan, dma_t *dma)
+{
+ struct pt_regs regs;
+ get_fiq_regs(&regs);
+ return regs.ARM_r9;
+}
+
+static struct dma_ops floppy_dma_ops = {
+ .type = "FIQDMA",
+ .enable = floppy_enable_dma,
+ .disable = floppy_disable_dma,
+ .residue = floppy_get_residue,
+};
+
+/*
+ * This is virtual DMA - we don't need anything here.
+ */
+static void sound_enable_disable_dma(unsigned int chan, dma_t *dma)
+{
+}
+
+static struct dma_ops sound_dma_ops = {
+ .type = "VIRTUAL",
+ .enable = sound_enable_disable_dma,
+ .disable = sound_enable_disable_dma,
+};
+
+static struct iomd_dma iomd_dma[6];
+
+static struct floppy_dma floppy_dma = {
+ .dma = {
+ .d_ops = &floppy_dma_ops,
+ },
+ .fiq = FIQ_FLOPPYDATA,
+};
+
+static dma_t sound_dma = {
+ .d_ops = &sound_dma_ops,
+};
+
+static int __init rpc_dma_init(void)
+{
+ unsigned int i;
+ int ret;
+
+ iomd_writeb(0, IOMD_IO0CR);
+ iomd_writeb(0, IOMD_IO1CR);
+ iomd_writeb(0, IOMD_IO2CR);
+ iomd_writeb(0, IOMD_IO3CR);
+
+ iomd_writeb(0xa0, IOMD_DMATCR);
+
+ /*
+ * Setup DMA channels 2,3 to be for podules
+ * and channels 0,1 for internal devices
+ */
+ iomd_writeb(DMA_EXT_IO3|DMA_EXT_IO2, IOMD_DMAEXT);
+
+ iomd_dma[DMA_0].base = IOMD_IO0CURA;
+ iomd_dma[DMA_0].irq = IRQ_DMA0;
+ iomd_dma[DMA_1].base = IOMD_IO1CURA;
+ iomd_dma[DMA_1].irq = IRQ_DMA1;
+ iomd_dma[DMA_2].base = IOMD_IO2CURA;
+ iomd_dma[DMA_2].irq = IRQ_DMA2;
+ iomd_dma[DMA_3].base = IOMD_IO3CURA;
+ iomd_dma[DMA_3].irq = IRQ_DMA3;
+ iomd_dma[DMA_S0].base = IOMD_SD0CURA;
+ iomd_dma[DMA_S0].irq = IRQ_DMAS0;
+ iomd_dma[DMA_S1].base = IOMD_SD1CURA;
+ iomd_dma[DMA_S1].irq = IRQ_DMAS1;
+
+ for (i = DMA_0; i <= DMA_S1; i++) {
+ iomd_dma[i].dma.d_ops = &iomd_dma_ops;
+
+ ret = isa_dma_add(i, &iomd_dma[i].dma);
+ if (ret)
+ printk("IOMDDMA%u: unable to register: %d\n", i, ret);
+ }
+
+ ret = isa_dma_add(DMA_VIRTUAL_FLOPPY, &floppy_dma.dma);
+ if (ret)
+ printk("IOMDFLOPPY: unable to register: %d\n", ret);
+ ret = isa_dma_add(DMA_VIRTUAL_SOUND, &sound_dma);
+ if (ret)
+ printk("IOMDSOUND: unable to register: %d\n", ret);
+ return 0;
+}
+core_initcall(rpc_dma_init);
diff --git a/arch/arm/mach-rpc/include/mach/acornfb.h b/arch/arm/mach-rpc/include/mach/acornfb.h
new file mode 100644
index 00000000..395d7628
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/acornfb.h
@@ -0,0 +1,140 @@
+/*
+ * arch/arm/mach-rpc/include/mach/acornfb.h
+ *
+ * Copyright (C) 1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * AcornFB architecture specific code
+ */
+
+#define acornfb_bandwidth(var) ((var)->pixclock * 8 / (var)->bits_per_pixel)
+
+static inline int
+acornfb_valid_pixrate(struct fb_var_screeninfo *var)
+{
+ u_long limit;
+
+ if (!var->pixclock)
+ return 0;
+
+ /*
+ * Limits below are taken from RISC OS bandwidthlimit file
+ */
+ if (current_par.using_vram) {
+ if (current_par.vram_half_sam == 2048)
+ limit = 6578;
+ else
+ limit = 13157;
+ } else {
+ limit = 26315;
+ }
+
+ return acornfb_bandwidth(var) >= limit;
+}
+
+/*
+ * Try to find the best PLL parameters for the pixel clock.
+ * This algorithm seems to give best predictable results,
+ * and produces the same values as detailed in the VIDC20
+ * data sheet.
+ */
+static inline u_int
+acornfb_vidc20_find_pll(u_int pixclk)
+{
+ u_int r, best_r = 2, best_v = 2;
+ int best_d = 0x7fffffff;
+
+ for (r = 2; r <= 32; r++) {
+ u_int rr, v, p;
+ int d;
+
+ rr = 41667 * r;
+
+ v = (rr + pixclk / 2) / pixclk;
+
+ if (v > 32 || v < 2)
+ continue;
+
+ p = (rr + v / 2) / v;
+
+ d = pixclk - p;
+
+ if (d < 0)
+ d = -d;
+
+ if (d < best_d) {
+ best_d = d;
+ best_v = v - 1;
+ best_r = r - 1;
+ }
+
+ if (d == 0)
+ break;
+ }
+
+ return best_v << 8 | best_r;
+}
+
+static inline void
+acornfb_vidc20_find_rates(struct vidc_timing *vidc,
+ struct fb_var_screeninfo *var)
+{
+ u_int div;
+
+ /* Select pixel-clock divisor to keep PLL in range */
+ div = var->pixclock / 9090; /*9921*/
+
+ /* Limit divisor */
+ if (div == 0)
+ div = 1;
+ if (div > 8)
+ div = 8;
+
+ /* Encode divisor to VIDC20 setting */
+ switch (div) {
+ case 1: vidc->control |= VIDC20_CTRL_PIX_CK; break;
+ case 2: vidc->control |= VIDC20_CTRL_PIX_CK2; break;
+ case 3: vidc->control |= VIDC20_CTRL_PIX_CK3; break;
+ case 4: vidc->control |= VIDC20_CTRL_PIX_CK4; break;
+ case 5: vidc->control |= VIDC20_CTRL_PIX_CK5; break;
+ case 6: vidc->control |= VIDC20_CTRL_PIX_CK6; break;
+ case 7: vidc->control |= VIDC20_CTRL_PIX_CK7; break;
+ case 8: vidc->control |= VIDC20_CTRL_PIX_CK8; break;
+ }
+
+ /*
+ * With VRAM, the FIFO can be set to the highest possible setting
+ * because there are no latency considerations for other memory
+ * accesses. However, in 64 bit bus mode the FIFO preload value
+ * must not be set to VIDC20_CTRL_FIFO_28 because this will let
+ * the FIFO overflow. See VIDC20 manual page 33 (6.0 Setting the
+ * FIFO preload value).
+ */
+ if (current_par.using_vram) {
+ if (current_par.vram_half_sam == 2048)
+ vidc->control |= VIDC20_CTRL_FIFO_24;
+ else
+ vidc->control |= VIDC20_CTRL_FIFO_28;
+ } else {
+ unsigned long bandwidth = acornfb_bandwidth(var);
+
+ /* Encode bandwidth as VIDC20 setting */
+ if (bandwidth > 33334) /* < 30.0MB/s */
+ vidc->control |= VIDC20_CTRL_FIFO_16;
+ else if (bandwidth > 26666) /* < 37.5MB/s */
+ vidc->control |= VIDC20_CTRL_FIFO_20;
+ else if (bandwidth > 22222) /* < 45.0MB/s */
+ vidc->control |= VIDC20_CTRL_FIFO_24;
+ else /* > 45.0MB/s */
+ vidc->control |= VIDC20_CTRL_FIFO_28;
+ }
+
+ /* Find the PLL values */
+ vidc->pll_ctl = acornfb_vidc20_find_pll(var->pixclock / div);
+}
+
+#define acornfb_default_control() (VIDC20_CTRL_PIX_VCLK)
+#define acornfb_default_econtrol() (VIDC20_ECTL_DAC | VIDC20_ECTL_REG(3))
diff --git a/arch/arm/mach-rpc/include/mach/debug-macro.S b/arch/arm/mach-rpc/include/mach/debug-macro.S
new file mode 100644
index 00000000..85effffd
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/debug-macro.S
@@ -0,0 +1,23 @@
+/* arch/arm/mach-rpc/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00010000
+ orr \rp, \rp, #0x00000fe0
+ orr \rv, \rp, #0xe0000000 @ virtual
+ orr \rp, \rp, #0x03000000 @ physical
+ .endm
+
+#define UART_SHIFT 2
+#define FLOW_CONTROL
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
new file mode 100644
index 00000000..4e7e5414
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/entry-macro.S
@@ -0,0 +1,16 @@
+#include <mach/hardware.h>
+#include <asm/hardware/entry-macro-iomd.S>
+
+ .equ ioc_base_high, IOC_BASE & 0xff000000
+ .equ ioc_base_low, IOC_BASE & 0x00ff0000
+
+ .macro get_irqnr_preamble, base, tmp
+ mov \base, #ioc_base_high @ point at IOC
+ .if ioc_base_low
+ orr \base, \base, #ioc_base_low
+ .endif
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h
new file mode 100644
index 00000000..dde6b3c0
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/hardware.h
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-rpc/include/mach/hardware.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the hardware definitions of the RiscPC series machines.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <mach/memory.h>
+
+#ifndef __ASSEMBLY__
+#define IOMEM(x) ((void __iomem *)(unsigned long)(x))
+#else
+#define IOMEM(x) x
+#endif /* __ASSEMBLY__ */
+
+/*
+ * What hardware must be present
+ */
+#define HAS_IOMD
+#define HAS_VIDC20
+
+/* Hardware addresses of major areas.
+ * *_START is the physical address
+ * *_SIZE is the size of the region
+ * *_BASE is the virtual address
+ */
+#define RAM_SIZE 0x10000000
+#define RAM_START 0x10000000
+
+#define EASI_SIZE 0x08000000 /* EASI I/O */
+#define EASI_START 0x08000000
+#define EASI_BASE 0xe5000000
+
+#define IO_START 0x03000000 /* I/O */
+#define IO_SIZE 0x01000000
+#define IO_BASE IOMEM(0xe0000000)
+
+#define SCREEN_START 0x02000000 /* VRAM */
+#define SCREEN_END 0xdfc00000
+#define SCREEN_BASE 0xdf800000
+
+#define UNCACHEABLE_ADDR 0xdf010000
+
+/*
+ * IO Addresses
+ */
+#define VIDC_BASE IOMEM(0xe0400000)
+#define EXPMASK_BASE 0xe0360000
+#define IOMD_BASE IOMEM(0xe0200000)
+#define IOC_BASE IOMEM(0xe0200000)
+#define PCIO_BASE IOMEM(0xe0010000)
+#define FLOPPYDMA_BASE IOMEM(0xe002a000)
+
+#define vidc_writel(val) __raw_writel(val, VIDC_BASE)
+
+#define IO_EC_EASI_BASE 0x81400000
+#define IO_EC_IOC4_BASE 0x8009c000
+#define IO_EC_IOC_BASE 0x80090000
+#define IO_EC_MEMC8_BASE 0x8000ac00
+#define IO_EC_MEMC_BASE 0x80000000
+
+#define NETSLOT_BASE 0x0302b000
+#define NETSLOT_SIZE 0x00001000
+
+#define PODSLOT_IOC0_BASE 0x03240000
+#define PODSLOT_IOC4_BASE 0x03270000
+#define PODSLOT_IOC_SIZE (1 << 14)
+#define PODSLOT_MEMC_BASE 0x03000000
+#define PODSLOT_MEMC_SIZE (1 << 14)
+#define PODSLOT_EASI_BASE 0x08000000
+#define PODSLOT_EASI_SIZE (1 << 24)
+
+#define EXPMASK_STATUS (EXPMASK_BASE + 0x00)
+#define EXPMASK_ENABLE (EXPMASK_BASE + 0x04)
+
+#endif
diff --git a/arch/arm/mach-rpc/include/mach/io.h b/arch/arm/mach-rpc/include/mach/io.h
new file mode 100644
index 00000000..20da7f48
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/io.h
@@ -0,0 +1,213 @@
+/*
+ * arch/arm/mach-rpc/include/mach/io.h
+ *
+ * Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 06-Dec-1997 RMK Created.
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We use two different types of addressing - PC style addresses, and ARM
+ * addresses. PC style accesses the PC hardware with the normal PC IO
+ * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+
+ * and are translated to the start of IO. Note that all addresses are
+ * shifted left!
+ */
+#define __PORT_PCIO(x) (!((x) & 0x80000000))
+
+/*
+ * Dynamic IO functions.
+ */
+static inline void __outb (unsigned int value, unsigned int port)
+{
+ unsigned long temp;
+ __asm__ __volatile__(
+ "tst %2, #0x80000000\n\t"
+ "mov %0, %4\n\t"
+ "addeq %0, %0, %3\n\t"
+ "strb %1, [%0, %2, lsl #2] @ outb"
+ : "=&r" (temp)
+ : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
+ : "cc");
+}
+
+static inline void __outw (unsigned int value, unsigned int port)
+{
+ unsigned long temp;
+ __asm__ __volatile__(
+ "tst %2, #0x80000000\n\t"
+ "mov %0, %4\n\t"
+ "addeq %0, %0, %3\n\t"
+ "str %1, [%0, %2, lsl #2] @ outw"
+ : "=&r" (temp)
+ : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
+ : "cc");
+}
+
+static inline void __outl (unsigned int value, unsigned int port)
+{
+ unsigned long temp;
+ __asm__ __volatile__(
+ "tst %2, #0x80000000\n\t"
+ "mov %0, %4\n\t"
+ "addeq %0, %0, %3\n\t"
+ "str %1, [%0, %2, lsl #2] @ outl"
+ : "=&r" (temp)
+ : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE)
+ : "cc");
+}
+
+#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
+static inline unsigned sz __in##fnsuffix (unsigned int port) \
+{ \
+ unsigned long temp, value; \
+ __asm__ __volatile__( \
+ "tst %2, #0x80000000\n\t" \
+ "mov %0, %4\n\t" \
+ "addeq %0, %0, %3\n\t" \
+ "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \
+ : "=&r" (temp), "=r" (value) \
+ : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \
+ : "cc"); \
+ return (unsigned sz)value; \
+}
+
+static inline void __iomem *__deprecated __ioaddr(unsigned int port)
+{
+ void __iomem *ret;
+ if (__PORT_PCIO(port))
+ ret = PCIO_BASE;
+ else
+ ret = IO_BASE;
+ return ret + (port << 2);
+}
+
+#define DECLARE_IO(sz,fnsuffix,instr) \
+ DECLARE_DYN_IN(sz,fnsuffix,instr)
+
+DECLARE_IO(char,b,"b")
+DECLARE_IO(short,w,"")
+DECLARE_IO(int,l,"")
+
+#undef DECLARE_IO
+#undef DECLARE_DYN_IN
+
+/*
+ * Constant address IO functions
+ *
+ * These have to be macros for the 'J' constraint to work -
+ * +/-4096 immediate operand.
+ */
+#define __outbc(value,port) \
+({ \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "strb %0, [%1, %2] @ outbc" \
+ : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "strb %0, [%1, %2] @ outbc" \
+ : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \
+})
+
+#define __inbc(port) \
+({ \
+ unsigned char result; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "ldrb %0, [%1, %2] @ inbc" \
+ : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "ldrb %0, [%1, %2] @ inbc" \
+ : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
+ result; \
+})
+
+#define __outwc(value,port) \
+({ \
+ unsigned long __v = value; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "str %0, [%1, %2] @ outwc" \
+ : : "r" (__v|__v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "str %0, [%1, %2] @ outwc" \
+ : : "r" (__v|__v<<16), "r" (IO_BASE), "r" ((port) << 2)); \
+})
+
+#define __inwc(port) \
+({ \
+ unsigned short result; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, %2] @ inwc" \
+ : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, %2] @ inwc" \
+ : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
+ result & 0xffff; \
+})
+
+#define __outlc(value,port) \
+({ \
+ unsigned long __v = value; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "str %0, [%1, %2] @ outlc" \
+ : : "r" (__v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "str %0, [%1, %2] @ outlc" \
+ : : "r" (__v), "r" (IO_BASE), "r" ((port) << 2)); \
+})
+
+#define __inlc(port) \
+({ \
+ unsigned long result; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, %2] @ inlc" \
+ : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \
+ else \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, %2] @ inlc" \
+ : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \
+ result; \
+})
+
+#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
+#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
+#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
+#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
+#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
+#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
+
+/* the following macro is deprecated */
+#define ioaddr(port) ((unsigned long)__ioaddr((port)))
+
+#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
+#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
+
+#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)
+#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x) (x)
+
+#endif
diff --git a/arch/arm/mach-rpc/include/mach/irqs.h b/arch/arm/mach-rpc/include/mach/irqs.h
new file mode 100644
index 00000000..3d203749
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/irqs.h
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-rpc/include/mach/irqs.h
+ *
+ * Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define IRQ_PRINTER 0
+#define IRQ_BATLOW 1
+#define IRQ_FLOPPYINDEX 2
+#define IRQ_VSYNCPULSE 3
+#define IRQ_POWERON 4
+#define IRQ_TIMER0 5
+#define IRQ_TIMER1 6
+#define IRQ_IMMEDIATE 7
+#define IRQ_EXPCARDFIQ 8
+#define IRQ_HARDDISK 9
+#define IRQ_SERIALPORT 10
+#define IRQ_FLOPPYDISK 12
+#define IRQ_EXPANSIONCARD 13
+#define IRQ_KEYBOARDTX 14
+#define IRQ_KEYBOARDRX 15
+
+#define IRQ_DMA0 16
+#define IRQ_DMA1 17
+#define IRQ_DMA2 18
+#define IRQ_DMA3 19
+#define IRQ_DMAS0 20
+#define IRQ_DMAS1 21
+
+#define FIQ_FLOPPYDATA 0
+#define FIQ_ECONET 2
+#define FIQ_SERIALPORT 4
+#define FIQ_EXPANSIONCARD 6
+#define FIQ_FORCE 7
+
+/*
+ * This is the offset of the FIQ "IRQ" numbers
+ */
+#define FIQ_START 64
+
+#define IRQ_TIMER IRQ_TIMER0
+
+#define NR_IRQS 128
diff --git a/arch/arm/mach-rpc/include/mach/isa-dma.h b/arch/arm/mach-rpc/include/mach/isa-dma.h
new file mode 100644
index 00000000..67bfc671
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/isa-dma.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-rpc/include/mach/isa-dma.h
+ *
+ * Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can 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_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_CHANNELS 8
+
+#define DMA_0 0
+#define DMA_1 1
+#define DMA_2 2
+#define DMA_3 3
+#define DMA_S0 4
+#define DMA_S1 5
+#define DMA_VIRTUAL_FLOPPY 6
+#define DMA_VIRTUAL_SOUND 7
+
+#define DMA_FLOPPY DMA_VIRTUAL_FLOPPY
+
+#define IOMD_DMA_BOUNDARY (PAGE_SIZE - 1)
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff --git a/arch/arm/mach-rpc/include/mach/memory.h b/arch/arm/mach-rpc/include/mach/memory.h
new file mode 100644
index 00000000..18a22109
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/memory.h
@@ -0,0 +1,40 @@
+/*
+ * arch/arm/mach-rpc/include/mach/memory.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 20-Oct-1996 RMK Created
+ * 31-Dec-1997 RMK Fixed definitions to reduce warnings
+ * 11-Jan-1998 RMK Uninlined to reduce hits on cache
+ * 08-Feb-1998 RMK Added __virt_to_bus and __bus_to_virt
+ * 21-Mar-1999 RMK Renamed to memory.h
+ * RMK Added TASK_SIZE and PAGE_OFFSET
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x10000000)
+
+/*
+ * Cache flushing area - ROM
+ */
+#define FLUSH_BASE_PHYS 0x00000000
+#define FLUSH_BASE 0xdf000000
+
+/*
+ * Sparsemem support. Each section is a maximum of 64MB. The sections
+ * are offset by 128MB and can cover 128MB, so that gives us a maximum
+ * of 29 physmem bits.
+ */
+#define MAX_PHYSMEM_BITS 29
+#define SECTION_SIZE_BITS 26
+
+#endif
diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h
new file mode 100644
index 00000000..45c7b935
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/mach-rpc/include/mach/system.h
+ *
+ * Copyright (C) 1996-1999 Russell King.
+ *
+ * This program is free software; you can 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/hardware.h>
+#include <asm/hardware/iomd.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ iomd_writeb(0, IOMD_ROMCR0);
+
+ /*
+ * Jump into the ROM
+ */
+ cpu_reset(0);
+}
diff --git a/arch/arm/mach-rpc/include/mach/timex.h b/arch/arm/mach-rpc/include/mach/timex.h
new file mode 100644
index 00000000..dd75e738
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/timex.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/mach-rpc/include/mach/timex.h
+ *
+ * Copyright (C) 1997, 1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * RiscPC architecture timex specifications
+ */
+
+/*
+ * On the RiscPC, the clock ticks at 2MHz.
+ */
+#define CLOCK_TICK_RATE 2000000
+
diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h
new file mode 100644
index 00000000..9cd9bcda
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/uncompress.h
@@ -0,0 +1,196 @@
+/*
+ * arch/arm/mach-rpc/include/mach/uncompress.h
+ *
+ * Copyright (C) 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VIDMEM ((char *)SCREEN_START)
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+int video_size_row;
+unsigned char bytes_per_char_h;
+extern unsigned long con_charconvtable[256];
+
+struct param_struct {
+ unsigned long page_size;
+ unsigned long nr_pages;
+ unsigned long ramdisk_size;
+ unsigned long mountrootrdonly;
+ unsigned long rootdev;
+ unsigned long video_num_cols;
+ unsigned long video_num_rows;
+ unsigned long video_x;
+ unsigned long video_y;
+ unsigned long memc_control_reg;
+ unsigned char sounddefault;
+ unsigned char adfsdrives;
+ unsigned char bytes_per_char_h;
+ unsigned char bytes_per_char_v;
+ unsigned long unused[256/4-11];
+};
+
+static const unsigned long palette_4[16] = {
+ 0x00000000,
+ 0x000000cc,
+ 0x0000cc00, /* Green */
+ 0x0000cccc, /* Yellow */
+ 0x00cc0000, /* Blue */
+ 0x00cc00cc, /* Magenta */
+ 0x00cccc00, /* Cyan */
+ 0x00cccccc, /* White */
+ 0x00000000,
+ 0x000000ff,
+ 0x0000ff00,
+ 0x0000ffff,
+ 0x00ff0000,
+ 0x00ff00ff,
+ 0x00ffff00,
+ 0x00ffffff
+};
+
+#define palette_setpixel(p) *(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
+#define palette_write(v) *(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)
+
+/*
+ * params_phys is a linker defined symbol - see
+ * arch/arm/boot/compressed/Makefile
+ */
+extern __attribute__((pure)) struct param_struct *params(void);
+#define params (params())
+
+#ifndef STANDALONE_DEBUG
+unsigned long video_num_cols;
+unsigned long video_num_rows;
+unsigned long video_x;
+unsigned long video_y;
+unsigned char bytes_per_char_v;
+int white;
+
+/*
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+ extern void ll_write_char(char *, char c, char white);
+ int x,y;
+ char *ptr;
+
+ x = video_x;
+ y = video_y;
+
+ if (c == '\n') {
+ if (++y >= video_num_rows)
+ y--;
+ } else if (c == '\r') {
+ x = 0;
+ } else {
+ ptr = VIDMEM + ((y*video_num_cols*bytes_per_char_v+x)*bytes_per_char_h);
+ ll_write_char(ptr, c, white);
+ if (++x >= video_num_cols) {
+ x = 0;
+ if ( ++y >= video_num_rows ) {
+ y--;
+ }
+ }
+ }
+
+ video_x = x;
+ video_y = y;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * Setup for decompression
+ */
+static void arch_decomp_setup(void)
+{
+ int i;
+ struct tag *t = (struct tag *)params;
+ unsigned int nr_pages = 0, page_size = PAGE_SIZE;
+
+ if (t->hdr.tag == ATAG_CORE)
+ {
+ for (; t->hdr.size; t = tag_next(t))
+ {
+ if (t->hdr.tag == ATAG_VIDEOTEXT)
+ {
+ video_num_rows = t->u.videotext.video_lines;
+ video_num_cols = t->u.videotext.video_cols;
+ bytes_per_char_h = t->u.videotext.video_points;
+ bytes_per_char_v = t->u.videotext.video_points;
+ video_x = t->u.videotext.x;
+ video_y = t->u.videotext.y;
+ }
+
+ if (t->hdr.tag == ATAG_MEM)
+ {
+ page_size = PAGE_SIZE;
+ nr_pages += (t->u.mem.size / PAGE_SIZE);
+ }
+ }
+ }
+ else
+ {
+ nr_pages = params->nr_pages;
+ page_size = params->page_size;
+ video_num_rows = params->video_num_rows;
+ video_num_cols = params->video_num_cols;
+ video_x = params->video_x;
+ video_y = params->video_y;
+ bytes_per_char_h = params->bytes_per_char_h;
+ bytes_per_char_v = params->bytes_per_char_v;
+ }
+
+ video_size_row = video_num_cols * bytes_per_char_h;
+
+ if (bytes_per_char_h == 4)
+ for (i = 0; i < 256; i++)
+ con_charconvtable[i] =
+ (i & 128 ? 1 << 0 : 0) |
+ (i & 64 ? 1 << 4 : 0) |
+ (i & 32 ? 1 << 8 : 0) |
+ (i & 16 ? 1 << 12 : 0) |
+ (i & 8 ? 1 << 16 : 0) |
+ (i & 4 ? 1 << 20 : 0) |
+ (i & 2 ? 1 << 24 : 0) |
+ (i & 1 ? 1 << 28 : 0);
+ else
+ for (i = 0; i < 16; i++)
+ con_charconvtable[i] =
+ (i & 8 ? 1 << 0 : 0) |
+ (i & 4 ? 1 << 8 : 0) |
+ (i & 2 ? 1 << 16 : 0) |
+ (i & 1 ? 1 << 24 : 0);
+
+
+ palette_setpixel(0);
+ if (bytes_per_char_h == 1) {
+ palette_write (0);
+ palette_write (0x00ffffff);
+ for (i = 2; i < 256; i++)
+ palette_write (0);
+ white = 1;
+ } else {
+ for (i = 0; i < 256; i++)
+ palette_write (i < 16 ? palette_4[i] : 0);
+ white = 7;
+ }
+
+ if (nr_pages * page_size < 4096*1024) error("<4M of mem\n");
+}
+#endif
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-rpc/include/mach/vmalloc.h b/arch/arm/mach-rpc/include/mach/vmalloc.h
new file mode 100644
index 00000000..fb700228
--- /dev/null
+++ b/arch/arm/mach-rpc/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * arch/arm/mach-rpc/include/mach/vmalloc.h
+ *
+ * Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define VMALLOC_END 0xdc000000UL
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
new file mode 100644
index 00000000..2e1b5309
--- /dev/null
+++ b/arch/arm/mach-rpc/irq.c
@@ -0,0 +1,162 @@
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware/iomd.h>
+#include <asm/irq.h>
+
+static void iomd_ack_irq_a(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << d->irq;
+ val = iomd_readb(IOMD_IRQMASKA);
+ iomd_writeb(val & ~mask, IOMD_IRQMASKA);
+ iomd_writeb(mask, IOMD_IRQCLRA);
+}
+
+static void iomd_mask_irq_a(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << d->irq;
+ val = iomd_readb(IOMD_IRQMASKA);
+ iomd_writeb(val & ~mask, IOMD_IRQMASKA);
+}
+
+static void iomd_unmask_irq_a(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << d->irq;
+ val = iomd_readb(IOMD_IRQMASKA);
+ iomd_writeb(val | mask, IOMD_IRQMASKA);
+}
+
+static struct irq_chip iomd_a_chip = {
+ .irq_ack = iomd_ack_irq_a,
+ .irq_mask = iomd_mask_irq_a,
+ .irq_unmask = iomd_unmask_irq_a,
+};
+
+static void iomd_mask_irq_b(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_IRQMASKB);
+ iomd_writeb(val & ~mask, IOMD_IRQMASKB);
+}
+
+static void iomd_unmask_irq_b(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_IRQMASKB);
+ iomd_writeb(val | mask, IOMD_IRQMASKB);
+}
+
+static struct irq_chip iomd_b_chip = {
+ .irq_ack = iomd_mask_irq_b,
+ .irq_mask = iomd_mask_irq_b,
+ .irq_unmask = iomd_unmask_irq_b,
+};
+
+static void iomd_mask_irq_dma(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_DMAMASK);
+ iomd_writeb(val & ~mask, IOMD_DMAMASK);
+}
+
+static void iomd_unmask_irq_dma(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_DMAMASK);
+ iomd_writeb(val | mask, IOMD_DMAMASK);
+}
+
+static struct irq_chip iomd_dma_chip = {
+ .irq_ack = iomd_mask_irq_dma,
+ .irq_mask = iomd_mask_irq_dma,
+ .irq_unmask = iomd_unmask_irq_dma,
+};
+
+static void iomd_mask_irq_fiq(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_FIQMASK);
+ iomd_writeb(val & ~mask, IOMD_FIQMASK);
+}
+
+static void iomd_unmask_irq_fiq(struct irq_data *d)
+{
+ unsigned int val, mask;
+
+ mask = 1 << (d->irq & 7);
+ val = iomd_readb(IOMD_FIQMASK);
+ iomd_writeb(val | mask, IOMD_FIQMASK);
+}
+
+static struct irq_chip iomd_fiq_chip = {
+ .irq_ack = iomd_mask_irq_fiq,
+ .irq_mask = iomd_mask_irq_fiq,
+ .irq_unmask = iomd_unmask_irq_fiq,
+};
+
+void __init rpc_init_irq(void)
+{
+ unsigned int irq, flags;
+
+ iomd_writeb(0, IOMD_IRQMASKA);
+ iomd_writeb(0, IOMD_IRQMASKB);
+ iomd_writeb(0, IOMD_FIQMASK);
+ iomd_writeb(0, IOMD_DMAMASK);
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ flags = IRQF_VALID;
+
+ if (irq <= 6 || (irq >= 9 && irq <= 15))
+ flags |= IRQF_PROBE;
+
+ if (irq == 21 || (irq >= 16 && irq <= 19) ||
+ irq == IRQ_KEYBOARDTX)
+ flags |= IRQF_NOAUTOEN;
+
+ switch (irq) {
+ case 0 ... 7:
+ irq_set_chip_and_handler(irq, &iomd_a_chip,
+ handle_level_irq);
+ set_irq_flags(irq, flags);
+ break;
+
+ case 8 ... 15:
+ irq_set_chip_and_handler(irq, &iomd_b_chip,
+ handle_level_irq);
+ set_irq_flags(irq, flags);
+ break;
+
+ case 16 ... 21:
+ irq_set_chip_and_handler(irq, &iomd_dma_chip,
+ handle_level_irq);
+ set_irq_flags(irq, flags);
+ break;
+
+ case 64 ... 71:
+ irq_set_chip(irq, &iomd_fiq_chip);
+ set_irq_flags(irq, IRQF_VALID);
+ break;
+ }
+ }
+
+ init_FIQ();
+}
+
diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c
new file mode 100644
index 00000000..580b3c73
--- /dev/null
+++ b/arch/arm/mach-rpc/riscpc.c
@@ -0,0 +1,227 @@
+/*
+ * linux/arch/arm/mach-rpc/riscpc.c
+ *
+ * Copyright (C) 1998-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Architecture specific fixups.
+ */
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include <linux/ata_platform.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+
+#include <asm/elf.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/domain.h>
+#include <asm/setup.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+extern void rpc_init_irq(void);
+
+unsigned int vram_size;
+unsigned int memc_ctrl_reg;
+unsigned int number_mfm_drives;
+
+static int __init parse_tag_acorn(const struct tag *tag)
+{
+ memc_ctrl_reg = tag->u.acorn.memc_control_reg;
+ number_mfm_drives = tag->u.acorn.adfsdrives;
+
+ switch (tag->u.acorn.vram_pages) {
+ case 512:
+ vram_size += PAGE_SIZE * 256;
+ case 256:
+ vram_size += PAGE_SIZE * 256;
+ default:
+ break;
+ }
+#if 0
+ if (vram_size) {
+ desc->video_start = 0x02000000;
+ desc->video_end = 0x02000000 + vram_size;
+ }
+#endif
+ return 0;
+}
+
+__tagtable(ATAG_ACORN, parse_tag_acorn);
+
+static struct map_desc rpc_io_desc[] __initdata = {
+ { /* VRAM */
+ .virtual = SCREEN_BASE,
+ .pfn = __phys_to_pfn(SCREEN_START),
+ .length = 2*1048576,
+ .type = MT_DEVICE
+ }, { /* IO space */
+ .virtual = (u32)IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE ,
+ .type = MT_DEVICE
+ }, { /* EASI space */
+ .virtual = EASI_BASE,
+ .pfn = __phys_to_pfn(EASI_START),
+ .length = EASI_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init rpc_map_io(void)
+{
+ iotable_init(rpc_io_desc, ARRAY_SIZE(rpc_io_desc));
+
+ /*
+ * Turn off floppy.
+ */
+ writeb(0xc, PCIO_BASE + (0x3f2 << 2));
+
+ /*
+ * RiscPC can't handle half-word loads and stores
+ */
+ elf_hwcap &= ~HWCAP_HALF;
+}
+
+static struct resource acornfb_resources[] = {
+ { /* VIDC */
+ .start = 0x03400000,
+ .end = 0x035fffff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_VSYNCPULSE,
+ .end = IRQ_VSYNCPULSE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device acornfb_device = {
+ .name = "acornfb",
+ .id = -1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(acornfb_resources),
+ .resource = acornfb_resources,
+};
+
+static struct resource iomd_resources[] = {
+ {
+ .start = 0x03200000,
+ .end = 0x0320ffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device iomd_device = {
+ .name = "iomd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(iomd_resources),
+ .resource = iomd_resources,
+};
+
+static struct platform_device kbd_device = {
+ .name = "kart",
+ .id = -1,
+ .dev = {
+ .parent = &iomd_device.dev,
+ },
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .mapbase = 0x03010fe0,
+ .irq = 10,
+ .uartclk = 1843200,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static struct pata_platform_info pata_platform_data = {
+ .ioport_shift = 2,
+};
+
+static struct resource pata_resources[] = {
+ [0] = {
+ .start = 0x030107c0,
+ .end = 0x030107df,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x03010fd8,
+ .end = 0x03010fdb,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_HARDDISK,
+ .end = IRQ_HARDDISK,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_resources),
+ .resource = pata_resources,
+ .dev = {
+ .platform_data = &pata_platform_data,
+ .coherent_dma_mask = ~0, /* grumble */
+ },
+};
+
+static struct platform_device *devs[] __initdata = {
+ &iomd_device,
+ &kbd_device,
+ &serial_device,
+ &acornfb_device,
+ &pata_device,
+};
+
+static struct i2c_board_info i2c_rtc = {
+ I2C_BOARD_INFO("pcf8583", 0x50)
+};
+
+static int __init rpc_init(void)
+{
+ i2c_register_board_info(0, &i2c_rtc, 1);
+ return platform_add_devices(devs, ARRAY_SIZE(devs));
+}
+
+arch_initcall(rpc_init);
+
+extern struct sys_timer ioc_timer;
+
+MACHINE_START(RISCPC, "Acorn-RiscPC")
+ /* Maintainer: Russell King */
+ .boot_params = 0x10000100,
+ .reserve_lp0 = 1,
+ .reserve_lp1 = 1,
+ .map_io = rpc_map_io,
+ .init_irq = rpc_init_irq,
+ .timer = &ioc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2400/Kconfig b/arch/arm/mach-s3c2400/Kconfig
new file mode 100644
index 00000000..fdd8f5e9
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Kconfig
@@ -0,0 +1,7 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+menu "S3C2400 Machines"
+
+endmenu
diff --git a/arch/arm/mach-s3c2400/Makefile b/arch/arm/mach-s3c2400/Makefile
new file mode 100644
index 00000000..7e23f4e1
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Makefile
@@ -0,0 +1,15 @@
+# arch/arm/mach-s3c2400/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2400) += gpio.o
+
+# Machine support
+
diff --git a/arch/arm/mach-s3c2400/gpio.c b/arch/arm/mach-s3c2400/gpio.c
new file mode 100644
index 00000000..6c68e78f
--- /dev/null
+++ b/arch/arm/mach-s3c2400/gpio.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/mach-s3c2400/gpio.c
+ *
+ * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
+ *
+ * S3C2400 GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+
+int s3c2400_gpio_getirq(unsigned int pin)
+{
+ if (pin < S3C2410_GPE(0) || pin > S3C2400_GPE(7))
+ return -EINVAL; /* not valid interrupts */
+
+ return (pin - S3C2410_GPE(0)) + IRQ_EINT0;
+}
+
+EXPORT_SYMBOL(s3c2400_gpio_getirq);
diff --git a/arch/arm/mach-s3c2400/include/mach/map.h b/arch/arm/mach-s3c2400/include/mach/map.h
new file mode 100644
index 00000000..3fd88920
--- /dev/null
+++ b/arch/arm/mach-s3c2400/include/mach/map.h
@@ -0,0 +1,66 @@
+/* arch/arm/mach-s3c2400/include/mach/map.h
+ *
+ * Copyright 2003-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright 2003, Lucas Correia Villa Real
+ *
+ * S3C2400 - 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.
+*/
+
+#define S3C2400_PA_MEMCTRL (0x14000000)
+#define S3C2400_PA_USBHOST (0x14200000)
+#define S3C2400_PA_IRQ (0x14400000)
+#define S3C2400_PA_DMA (0x14600000)
+#define S3C2400_PA_CLKPWR (0x14800000)
+#define S3C2400_PA_LCD (0x14A00000)
+#define S3C2400_PA_UART (0x15000000)
+#define S3C2400_PA_TIMER (0x15100000)
+#define S3C2400_PA_USBDEV (0x15200140)
+#define S3C2400_PA_WATCHDOG (0x15300000)
+#define S3C2400_PA_IIC (0x15400000)
+#define S3C2400_PA_IIS (0x15508000)
+#define S3C2400_PA_GPIO (0x15600000)
+#define S3C2400_PA_RTC (0x15700040)
+#define S3C2400_PA_ADC (0x15800000)
+#define S3C2400_PA_SPI (0x15900000)
+
+#define S3C2400_PA_MMC (0x15A00000)
+#define S3C2400_SZ_MMC SZ_1M
+
+/* physical addresses of all the chip-select areas */
+
+#define S3C2400_CS0 (0x00000000)
+#define S3C2400_CS1 (0x02000000)
+#define S3C2400_CS2 (0x04000000)
+#define S3C2400_CS3 (0x06000000)
+#define S3C2400_CS4 (0x08000000)
+#define S3C2400_CS5 (0x0A000000)
+#define S3C2400_CS6 (0x0C000000)
+#define S3C2400_CS7 (0x0E000000)
+
+#define S3C2400_SDRAM_PA (S3C2400_CS6)
+
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#define S3C24XX_PA_IRQ S3C2400_PA_IRQ
+#define S3C24XX_PA_MEMCTRL S3C2400_PA_MEMCTRL
+#define S3C24XX_PA_USBHOST S3C2400_PA_USBHOST
+#define S3C24XX_PA_DMA S3C2400_PA_DMA
+#define S3C24XX_PA_CLKPWR S3C2400_PA_CLKPWR
+#define S3C24XX_PA_LCD S3C2400_PA_LCD
+#define S3C24XX_PA_UART S3C2400_PA_UART
+#define S3C24XX_PA_TIMER S3C2400_PA_TIMER
+#define S3C24XX_PA_USBDEV S3C2400_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C2400_PA_WATCHDOG
+#define S3C24XX_PA_IIC S3C2400_PA_IIC
+#define S3C24XX_PA_IIS S3C2400_PA_IIS
+#define S3C24XX_PA_GPIO S3C2400_PA_GPIO
+#define S3C24XX_PA_RTC S3C2400_PA_RTC
+#define S3C24XX_PA_ADC S3C2400_PA_ADC
+#define S3C24XX_PA_SPI S3C2400_PA_SPI
diff --git a/arch/arm/mach-s3c2400/include/mach/memory.h b/arch/arm/mach-s3c2400/include/mach/memory.h
new file mode 100644
index 00000000..3f33670d
--- /dev/null
+++ b/arch/arm/mach-s3c2400/include/mach/memory.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c2400/include/mach/memory.h
+ * from arch/arm/mach-rpc/include/mach/memory.h
+ *
+ * Copyright 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (C) 1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can 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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x0C000000)
+
+#endif
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
new file mode 100644
index 00000000..7245a557
--- /dev/null
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -0,0 +1,181 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2410
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM920T
+ select S3C_GPIO_PULL_UP
+ select S3C2410_CLOCK
+ select S3C2410_GPIO
+ select CPU_LLSERIAL_S3C2410
+ select S3C2410_PM if PM
+ select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
+ help
+ Support for S3C2410 and S3C2410A family from the S3C24XX line
+ of Samsung Mobile CPUs.
+
+config CPU_S3C2410_DMA
+ bool
+ depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
+ default y if CPU_S3C2410 || CPU_S3C2442
+ help
+ DMA device selection for S3C2410 and compatible CPUs
+
+config S3C2410_PM
+ bool
+ help
+ Power Management code common to S3C2410 and better
+
+config S3C2410_GPIO
+ bool
+ help
+ GPIO code for S3C2410 and similar processors
+
+config SIMTEC_NOR
+ bool
+ help
+ Internal node to specify machine has simtec NOR mapping
+
+config MACH_BAST_IDE
+ bool
+ select HAVE_PATA_PLATFORM
+ help
+ Internal node for machines with an BAST style IDE
+ interface
+
+# cpu frequency scaling support
+
+config S3C2410_CPUFREQ
+ bool
+ depends on CPU_FREQ_S3C24XX && CPU_S3C2410
+ select S3C2410_CPUFREQ_UTILS
+ help
+ CPU Frequency scaling support for S3C2410
+
+config S3C2410_PLLTABLE
+ bool
+ depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL
+ default y
+ help
+ Select the PLL table for the S3C2410
+
+menu "S3C2410 Machines"
+
+config ARCH_SMDK2410
+ bool "SMDK2410/A9M2410"
+ select CPU_S3C2410
+ select MACH_SMDK
+ help
+ Say Y here if you are using the SMDK2410 or the derived module A9M2410
+ <http://www.fsforth.de>
+
+config ARCH_H1940
+ bool "IPAQ H1940"
+ select CPU_S3C2410
+ select PM_H1940 if PM
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ select S3C2410_SETUP_TS
+ help
+ Say Y here if you are using the HP IPAQ H1940
+
+config H1940BT
+ tristate "Control the state of H1940 bluetooth chip"
+ depends on ARCH_H1940
+ select RFKILL
+ help
+ This is a simple driver that is able to control
+ the state of built in bluetooth chip on h1940.
+
+config PM_H1940
+ bool
+ help
+ Internal node for H1940 and related PM
+
+config MACH_N30
+ bool "Acer N30 family"
+ select CPU_S3C2410
+ select MACH_N35
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you want suppt for the Acer N30, Acer N35,
+ Navman PiN570, Yakumo AlphaX or Airis NC05 PDAs.
+
+config MACH_N35
+ bool
+ help
+ Internal node in order to enable support for Acer N35 if Acer N30 is
+ selected.
+
+config ARCH_BAST
+ bool "Simtec Electronics BAST (EB2410ITX)"
+ select CPU_S3C2410
+ select S3C2410_IOTIMING if S3C2410_CPUFREQ
+ select PM_SIMTEC if PM
+ select SIMTEC_NOR
+ select MACH_BAST_IDE
+ select S3C24XX_DCLK
+ select ISA
+ select S3C_DEV_HWMON
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Simtec Electronics EB2410ITX
+ development board (also known as BAST)
+
+config MACH_OTOM
+ bool "NexVision OTOM Board"
+ select CPU_S3C2410
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Nex Vision OTOM board
+
+config MACH_AML_M5900
+ bool "AML M5900 Series"
+ select CPU_S3C2410
+ select PM_SIMTEC if PM
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the American Microsystems M5900 Series
+ <http://www.amltd.com>
+
+config BAST_PC104_IRQ
+ bool "BAST PC104 IRQ support"
+ depends on ARCH_BAST
+ default y
+ help
+ Say Y here to enable the PC104 IRQ routing on the
+ Simtec BAST (EB2410ITX)
+
+config MACH_TCT_HAMMER
+ bool "TCT Hammer Board"
+ select CPU_S3C2410
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the TinCanTools Hammer Board
+ <http://www.tincantools.com>
+
+config MACH_VR1000
+ bool "Thorcom VR1000"
+ select PM_SIMTEC if PM
+ select S3C24XX_DCLK
+ select SIMTEC_NOR
+ select MACH_BAST_IDE
+ select CPU_S3C2410
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Thorcom VR1000 board.
+
+config MACH_QT2410
+ bool "QT2410"
+ select CPU_S3C2410
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Armzone QT2410
+
+endmenu
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
new file mode 100644
index 00000000..81695353
--- /dev/null
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -0,0 +1,41 @@
+# arch/arm/mach-s3c2410/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
+obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
+obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
+obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
+obj-$(CONFIG_S3C2410_GPIO) += gpio.o
+obj-$(CONFIG_S3C2410_CPUFREQ) += cpu-freq.o
+obj-$(CONFIG_S3C2410_PLLTABLE) += pll.o
+
+# Machine support
+
+obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
+obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
+obj-$(CONFIG_H1940BT) += h1940-bluetooth.o
+obj-$(CONFIG_PM_H1940) += pm-h1940.o
+obj-$(CONFIG_MACH_N30) += mach-n30.o
+obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
+obj-$(CONFIG_MACH_OTOM) += mach-otom.o
+obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
+obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
+obj-$(CONFIG_MACH_TCT_HAMMER) += mach-tct_hammer.o
+obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
+obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
+
+# Common bits of machine support
+
+obj-$(CONFIG_SIMTEC_NOR) += nor-simtec.o
+
+# machine additions
+
+obj-$(CONFIG_MACH_BAST_IDE) += bast-ide.o
diff --git a/arch/arm/mach-s3c2410/Makefile.boot b/arch/arm/mach-s3c2410/Makefile.boot
new file mode 100644
index 00000000..58c1dd7f
--- /dev/null
+++ b/arch/arm/mach-s3c2410/Makefile.boot
@@ -0,0 +1,7 @@
+ifeq ($(CONFIG_PM_H1940),y)
+ zreladdr-y := 0x30108000
+ params_phys-y := 0x30100100
+else
+ zreladdr-y := 0x30008000
+ params_phys-y := 0x30000100
+endif
diff --git a/arch/arm/mach-s3c2410/bast-ide.c b/arch/arm/mach-s3c2410/bast-ide.c
new file mode 100644
index 00000000..298ececf
--- /dev/null
+++ b/arch/arm/mach-s3c2410/bast-ide.c
@@ -0,0 +1,112 @@
+/* linux/arch/arm/mach-s3c2410/bast-ide.c
+ *
+ * Copyright 2007 Simtec Electronics
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ * http://armlinux.simtec.co.uk/
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/map.h>
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+/* IDE ports */
+
+static struct pata_platform_info bast_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+#define IDE_CS S3C2410_CS5
+
+static struct resource bast_ide0_resource[] = {
+ [0] = {
+ .start = IDE_CS + BAST_PA_IDEPRI,
+ .end = IDE_CS + BAST_PA_IDEPRI + (8 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IDE_CS + BAST_PA_IDEPRIAUX + (6 * 0x20) ,
+ .end = IDE_CS + BAST_PA_IDEPRIAUX + (7 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_IDE0,
+ .end = IRQ_IDE0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bast_device_ide0 = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_ide0_resource),
+ .resource = bast_ide0_resource,
+ .dev = {
+ .platform_data = &bast_ide_platdata,
+ .coherent_dma_mask = ~0,
+ }
+
+};
+
+static struct resource bast_ide1_resource[] = {
+ [0] = {
+ .start = IDE_CS + BAST_PA_IDESEC,
+ .end = IDE_CS + BAST_PA_IDESEC + (8 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IDE_CS + BAST_PA_IDESECAUX + (6 * 0x20),
+ .end = IDE_CS + BAST_PA_IDESECAUX + (7 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_IDE1,
+ .end = IRQ_IDE1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bast_device_ide1 = {
+ .name = "pata_platform",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bast_ide1_resource),
+ .resource = bast_ide1_resource,
+ .dev = {
+ .platform_data = &bast_ide_platdata,
+ .coherent_dma_mask = ~0,
+ }
+};
+
+static struct platform_device *bast_ide_devices[] __initdata = {
+ &bast_device_ide0,
+ &bast_device_ide1,
+};
+
+static __init int bast_ide_init(void)
+{
+ if (machine_is_bast() || machine_is_vr1000())
+ return platform_add_devices(bast_ide_devices,
+ ARRAY_SIZE(bast_ide_devices));
+
+ return 0;
+}
+
+fs_initcall(bast_ide_init);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
new file mode 100644
index 00000000..bc53d2d1
--- /dev/null
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s3c2410/bast-irq.c
+ *
+ * Copyright 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+#include <plat/irq.h>
+
+#if 0
+#include <asm/debug-ll.h>
+#endif
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+
+/* handle PC104 ISA interrupts from the system CPLD */
+
+/* table of ISA irq nos to the relevant mask... zero means
+ * the irq is not implemented
+*/
+static unsigned char bast_pc104_irqmasks[] = {
+ 0, /* 0 */
+ 0, /* 1 */
+ 0, /* 2 */
+ 1, /* 3 */
+ 0, /* 4 */
+ 2, /* 5 */
+ 0, /* 6 */
+ 4, /* 7 */
+ 0, /* 8 */
+ 0, /* 9 */
+ 8, /* 10 */
+ 0, /* 11 */
+ 0, /* 12 */
+ 0, /* 13 */
+ 0, /* 14 */
+ 0, /* 15 */
+};
+
+static unsigned char bast_pc104_irqs[] = { 3, 5, 7, 10 };
+
+static void
+bast_pc104_mask(struct irq_data *data)
+{
+ unsigned long temp;
+
+ temp = __raw_readb(BAST_VA_PC104_IRQMASK);
+ temp &= ~bast_pc104_irqmasks[data->irq];
+ __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
+}
+
+static void
+bast_pc104_maskack(struct irq_data *data)
+{
+ struct irq_desc *desc = irq_desc + IRQ_ISA;
+
+ bast_pc104_mask(data);
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+}
+
+static void
+bast_pc104_unmask(struct irq_data *data)
+{
+ unsigned long temp;
+
+ temp = __raw_readb(BAST_VA_PC104_IRQMASK);
+ temp |= bast_pc104_irqmasks[data->irq];
+ __raw_writeb(temp, BAST_VA_PC104_IRQMASK);
+}
+
+static struct irq_chip bast_pc104_chip = {
+ .irq_mask = bast_pc104_mask,
+ .irq_unmask = bast_pc104_unmask,
+ .irq_ack = bast_pc104_maskack
+};
+
+static void
+bast_irq_pc104_demux(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned int stat;
+ unsigned int irqno;
+ int i;
+
+ stat = __raw_readb(BAST_VA_PC104_IRQREQ) & 0xf;
+
+ if (unlikely(stat == 0)) {
+ /* ack if we get an irq with nothing (ie, startup) */
+
+ desc = irq_desc + IRQ_ISA;
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ } else {
+ /* handle the IRQ */
+
+ for (i = 0; stat != 0; i++, stat >>= 1) {
+ if (stat & 1) {
+ irqno = bast_pc104_irqs[i];
+ generic_handle_irq(irqno);
+ }
+ }
+ }
+}
+
+static __init int bast_irq_init(void)
+{
+ unsigned int i;
+
+ if (machine_is_bast()) {
+ printk(KERN_INFO "BAST PC104 IRQ routing, Copyright 2005 Simtec Electronics\n");
+
+ /* zap all the IRQs */
+
+ __raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
+
+ irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
+
+ /* register our IRQs */
+
+ for (i = 0; i < 4; i++) {
+ unsigned int irqno = bast_pc104_irqs[i];
+
+ irq_set_chip_and_handler(irqno, &bast_pc104_chip,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+ }
+
+ return 0;
+}
+
+arch_initcall(bast_irq_init);
diff --git a/arch/arm/mach-s3c2410/cpu-freq.c b/arch/arm/mach-s3c2410/cpu-freq.c
new file mode 100644
index 00000000..75189df9
--- /dev/null
+++ b/arch/arm/mach-s3c2410/cpu-freq.c
@@ -0,0 +1,159 @@
+/* linux/arch/arm/mach-s3c2410/cpu-freq.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
+
+static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+ u32 clkdiv = 0;
+
+ if (cfg->divs.h_divisor == 2)
+ clkdiv |= S3C2410_CLKDIVN_HDIVN;
+
+ if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+ clkdiv |= S3C2410_CLKDIVN_PDIVN;
+
+ __raw_writel(clkdiv, S3C2410_CLKDIVN);
+}
+
+static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+ unsigned long hclk, fclk, pclk;
+ unsigned int hdiv, pdiv;
+ unsigned long hclk_max;
+
+ fclk = cfg->freq.fclk;
+ hclk_max = cfg->max.hclk;
+
+ cfg->freq.armclk = fclk;
+
+ s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
+ __func__, fclk, hclk_max);
+
+ hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
+ hclk = fclk / hdiv;
+
+ if (hclk > cfg->max.hclk) {
+ s3c_freq_dbg("%s: hclk too big\n", __func__);
+ return -EINVAL;
+ }
+
+ pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+ pclk = hclk / pdiv;
+
+ if (pclk > cfg->max.pclk) {
+ s3c_freq_dbg("%s: pclk too big\n", __func__);
+ return -EINVAL;
+ }
+
+ pdiv *= hdiv;
+
+ /* record the result */
+ cfg->divs.p_divisor = pdiv;
+ cfg->divs.h_divisor = hdiv;
+
+ return 0 ;
+}
+
+static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
+ .max = {
+ .fclk = 200000000,
+ .hclk = 100000000,
+ .pclk = 50000000,
+ },
+
+ /* transition latency is about 5ms worst-case, so
+ * set 10ms to be sure */
+ .latency = 10000000,
+
+ .locktime_m = 150,
+ .locktime_u = 150,
+ .locktime_bits = 12,
+
+ .need_pll = 1,
+
+ .name = "s3c2410",
+ .calc_iotiming = s3c2410_iotiming_calc,
+ .set_iotiming = s3c2410_iotiming_set,
+ .get_iotiming = s3c2410_iotiming_get,
+ .resume_clocks = s3c2410_setup_clocks,
+
+ .set_fvco = s3c2410_set_fvco,
+ .set_refresh = s3c2410_cpufreq_setrefresh,
+ .set_divs = s3c2410_cpufreq_setdivs,
+ .calc_divs = s3c2410_cpufreq_calcdivs,
+
+ .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2410_cpufreq_add(struct sys_device *sysdev)
+{
+ return s3c_cpufreq_register(&s3c2410_cpufreq_info);
+}
+
+static struct sysdev_driver s3c2410_cpufreq_driver = {
+ .add = s3c2410_cpufreq_add,
+};
+
+static int __init s3c2410_cpufreq_init(void)
+{
+ return sysdev_driver_register(&s3c2410_sysclass,
+ &s3c2410_cpufreq_driver);
+}
+
+arch_initcall(s3c2410_cpufreq_init);
+
+static int s3c2410a_cpufreq_add(struct sys_device *sysdev)
+{
+ /* alter the maximum freq settings for S3C2410A. If a board knows
+ * it only has a maximum of 200, then it should register its own
+ * limits. */
+
+ s3c2410_cpufreq_info.max.fclk = 266000000;
+ s3c2410_cpufreq_info.max.hclk = 133000000;
+ s3c2410_cpufreq_info.max.pclk = 66500000;
+ s3c2410_cpufreq_info.name = "s3c2410a";
+
+ return s3c2410_cpufreq_add(sysdev);
+}
+
+static struct sysdev_driver s3c2410a_cpufreq_driver = {
+ .add = s3c2410a_cpufreq_add,
+};
+
+static int __init s3c2410a_cpufreq_init(void)
+{
+ return sysdev_driver_register(&s3c2410a_sysclass,
+ &s3c2410a_cpufreq_driver);
+}
+
+arch_initcall(s3c2410a_cpufreq_init);
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
new file mode 100644
index 00000000..0d8e0438
--- /dev/null
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -0,0 +1,193 @@
+/* linux/arch/arm/mach-s3c2410/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/cpu.h>
+#include <plat/dma-s3c24xx.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
+ [DMACH_XD0] = {
+ .name = "xdreq0",
+ .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+ },
+ [DMACH_XD1] = {
+ .name = "xdreq1",
+ .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+ },
+ [DMACH_SDI] = {
+ .name = "sdi",
+ .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+ .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_SPI0] = {
+ .name = "spi0",
+ .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
+ },
+ [DMACH_SPI1] = {
+ .name = "spi1",
+ .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+ },
+ [DMACH_UART0] = {
+ .name = "uart0",
+ .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1] = {
+ .name = "uart1",
+ .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2] = {
+ .name = "uart2",
+ .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_TIMER] = {
+ .name = "timer",
+ .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+ .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+ },
+ [DMACH_I2S_IN] = {
+ .name = "i2s-sdi",
+ .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_I2S_OUT] = {
+ .name = "i2s-sdo",
+ .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_USB_EP1] = {
+ .name = "usb-ep1",
+ .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP2] = {
+ .name = "usb-ep2",
+ .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP3] = {
+ .name = "usb-ep3",
+ .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP4] = {
+ .name = "usb-ep4",
+ .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+ },
+};
+
+static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map)
+{
+ chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
+ .select = s3c2410_dma_select,
+ .dcon_mask = 7 << 24,
+ .map = s3c2410_dma_mappings,
+ .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
+};
+
+static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
+ .channels = {
+ [DMACH_SDI] = {
+ .list = {
+ [0] = 3 | DMA_CH_VALID,
+ [1] = 2 | DMA_CH_VALID,
+ [2] = 0 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_I2S_IN] = {
+ .list = {
+ [0] = 1 | DMA_CH_VALID,
+ [1] = 2 | DMA_CH_VALID,
+ },
+ },
+ },
+};
+
+static int __init s3c2410_dma_add(struct sys_device *sysdev)
+{
+ s3c2410_dma_init();
+ s3c24xx_dma_order_set(&s3c2410_dma_order);
+ return s3c24xx_dma_init_map(&s3c2410_dma_sel);
+}
+
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_dma_driver = {
+ .add = s3c2410_dma_add,
+};
+
+static int __init s3c2410_dma_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
+}
+
+arch_initcall(s3c2410_dma_drvinit);
+
+static struct sysdev_driver s3c2410a_dma_driver = {
+ .add = s3c2410_dma_add,
+};
+
+static int __init s3c2410a_dma_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_dma_driver);
+}
+
+arch_initcall(s3c2410a_dma_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+/* S3C2442 DMA contains the same selection table as the S3C2410 */
+static struct sysdev_driver s3c2442_dma_driver = {
+ .add = s3c2410_dma_add,
+};
+
+static int __init s3c2442_dma_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
+}
+
+arch_initcall(s3c2442_dma_drvinit);
+#endif
+
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
new file mode 100644
index 00000000..9664e011
--- /dev/null
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/mach-s3c2410/gpio.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-fns.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+
+int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+ unsigned int config)
+{
+ void __iomem *reg = S3C24XX_EINFLT0;
+ unsigned long flags;
+ unsigned long val;
+
+ if (pin < S3C2410_GPG(8) || pin > S3C2410_GPG(15))
+ return -EINVAL;
+
+ config &= 0xff;
+
+ pin -= S3C2410_GPG(8);
+ reg += pin & ~3;
+
+ local_irq_save(flags);
+
+ /* update filter width and clock source */
+
+ val = __raw_readl(reg);
+ val &= ~(0xff << ((pin & 3) * 8));
+ val |= config << ((pin & 3) * 8);
+ __raw_writel(val, reg);
+
+ /* update filter enable */
+
+ val = __raw_readl(S3C24XX_EXTINT2);
+ val &= ~(1 << ((pin * 4) + 3));
+ val |= on << ((pin * 4) + 3);
+ __raw_writel(val, S3C24XX_EXTINT2);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/h1940-bluetooth.c b/arch/arm/mach-s3c2410/h1940-bluetooth.c
new file mode 100644
index 00000000..2c126bbc
--- /dev/null
+++ b/arch/arm/mach-s3c2410/h1940-bluetooth.c
@@ -0,0 +1,158 @@
+/*
+ * arch/arm/mach-s3c2410/h1940-bluetooth.c
+ * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * S3C2410 bluetooth "driver"
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/rfkill.h>
+#include <linux/leds.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/hardware.h>
+#include <mach/h1940-latch.h>
+#include <mach/h1940.h>
+
+#define DRV_NAME "h1940-bt"
+
+/* Bluetooth control */
+static void h1940bt_enable(int on)
+{
+ if (on) {
+ /* Power on the chip */
+ gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 1);
+ /* Reset the chip */
+ mdelay(10);
+
+ gpio_set_value(S3C2410_GPH(1), 1);
+ mdelay(10);
+ gpio_set_value(S3C2410_GPH(1), 0);
+
+ h1940_led_blink_set(-EINVAL, GPIO_LED_BLINK, NULL, NULL);
+ }
+ else {
+ gpio_set_value(S3C2410_GPH(1), 1);
+ mdelay(10);
+ gpio_set_value(S3C2410_GPH(1), 0);
+ mdelay(10);
+ gpio_set_value(H1940_LATCH_BLUETOOTH_POWER, 0);
+
+ h1940_led_blink_set(-EINVAL, GPIO_LED_NO_BLINK_LOW, NULL, NULL);
+ }
+}
+
+static int h1940bt_set_block(void *data, bool blocked)
+{
+ h1940bt_enable(!blocked);
+ return 0;
+}
+
+static const struct rfkill_ops h1940bt_rfkill_ops = {
+ .set_block = h1940bt_set_block,
+};
+
+static int __devinit h1940bt_probe(struct platform_device *pdev)
+{
+ struct rfkill *rfk;
+ int ret = 0;
+
+ ret = gpio_request(S3C2410_GPH(1), dev_name(&pdev->dev));
+ if (ret) {
+ dev_err(&pdev->dev, "could not get GPH1\n");
+ return ret;
+ }
+
+ ret = gpio_request(H1940_LATCH_BLUETOOTH_POWER, dev_name(&pdev->dev));
+ if (ret) {
+ gpio_free(S3C2410_GPH(1));
+ dev_err(&pdev->dev, "could not get BT_POWER\n");
+ return ret;
+ }
+
+ /* Configures BT serial port GPIOs */
+ s3c_gpio_cfgpin(S3C2410_GPH(0), S3C2410_GPH0_nCTS0);
+ s3c_gpio_setpull(S3C2410_GPH(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(1), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_setpull(S3C2410_GPH(1), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(2), S3C2410_GPH2_TXD0);
+ s3c_gpio_setpull(S3C2410_GPH(2), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(3), S3C2410_GPH3_RXD0);
+ s3c_gpio_setpull(S3C2410_GPH(3), S3C_GPIO_PULL_NONE);
+
+ rfk = rfkill_alloc(DRV_NAME, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
+ &h1940bt_rfkill_ops, NULL);
+ if (!rfk) {
+ ret = -ENOMEM;
+ goto err_rfk_alloc;
+ }
+
+ ret = rfkill_register(rfk);
+ if (ret)
+ goto err_rfkill;
+
+ platform_set_drvdata(pdev, rfk);
+
+ return 0;
+
+err_rfkill:
+ rfkill_destroy(rfk);
+err_rfk_alloc:
+ return ret;
+}
+
+static int h1940bt_remove(struct platform_device *pdev)
+{
+ struct rfkill *rfk = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ gpio_free(S3C2410_GPH(1));
+
+ if (rfk) {
+ rfkill_unregister(rfk);
+ rfkill_destroy(rfk);
+ }
+ rfk = NULL;
+
+ h1940bt_enable(0);
+
+ return 0;
+}
+
+
+static struct platform_driver h1940bt_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ },
+ .probe = h1940bt_probe,
+ .remove = h1940bt_remove,
+};
+
+
+static int __init h1940bt_init(void)
+{
+ return platform_driver_register(&h1940bt_driver);
+}
+
+static void __exit h1940bt_exit(void)
+{
+ platform_driver_unregister(&h1940bt_driver);
+}
+
+module_init(h1940bt_init);
+module_exit(h1940bt_exit);
+
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_DESCRIPTION("Driver for the iPAQ H1940 bluetooth chip");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h b/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
new file mode 100644
index 00000000..1b614d5a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
@@ -0,0 +1,25 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-cpld.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - CPLD control constants
+ *
+ * This program is free software; you can 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_ANUBISCPLD_H
+#define __ASM_ARCH_ANUBISCPLD_H
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define ANUBIS_CTRL1_NANDSEL (0x3)
+
+/* IDREG - revision */
+
+#define ANUBIS_IDREG_REVMASK (0x7)
+
+#endif /* __ASM_ARCH_ANUBISCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-irq.h b/arch/arm/mach-s3c2410/include/mach/anubis-irq.h
new file mode 100644
index 00000000..a2a32813
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/anubis-irq.h
@@ -0,0 +1,21 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-irq.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - IRQ Number 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_ANUBISIRQ_H
+#define __ASM_ARCH_ANUBISIRQ_H
+
+#define IRQ_IDE0 IRQ_EINT2
+#define IRQ_IDE1 IRQ_EINT3
+#define IRQ_ASIX IRQ_EINT1
+
+#endif /* __ASM_ARCH_ANUBISIRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/anubis-map.h b/arch/arm/mach-s3c2410/include/mach/anubis-map.h
new file mode 100644
index 00000000..c9deb3a5
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/anubis-map.h
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s3c2410/include/mach/anubis-map.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * ANUBIS - 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.
+*/
+
+/* needs arch/map.h including with this */
+
+#ifndef __ASM_ARCH_ANUBISMAP_H
+#define __ASM_ARCH_ANUBISMAP_H
+
+/* start peripherals off after the S3C2410 */
+
+#define ANUBIS_IOADDR(x) (S3C2410_ADDR((x) + 0x01800000))
+
+#define ANUBIS_PA_CPLD (S3C2410_CS1 | (1<<26))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define ANUBIS_VA_CTRL1 ANUBIS_IOADDR(0x00000000) /* 0x01800000 */
+#define ANUBIS_PA_CTRL1 (ANUBIS_PA_CPLD)
+
+#define ANUBIS_VA_IDREG ANUBIS_IOADDR(0x00300000) /* 0x01B00000 */
+#define ANUBIS_PA_IDREG (ANUBIS_PA_CPLD + (3<<23))
+
+#define ANUBIS_IDEPRI ANUBIS_IOADDR(0x01000000)
+#define ANUBIS_IDEPRIAUX ANUBIS_IOADDR(0x01100000)
+#define ANUBIS_IDESEC ANUBIS_IOADDR(0x01200000)
+#define ANUBIS_IDESECAUX ANUBIS_IOADDR(0x01300000)
+
+#endif /* __ASM_ARCH_ANUBISMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-cpld.h b/arch/arm/mach-s3c2410/include/mach/bast-cpld.h
new file mode 100644
index 00000000..bee2a7a9
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/bast-cpld.h
@@ -0,0 +1,53 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-cpld.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * BAST - CPLD control constants
+ *
+ * This program is free software; you can 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_BASTCPLD_H
+#define __ASM_ARCH_BASTCPLD_H
+
+/* CTRL1 - Audio LR routing */
+
+#define BAST_CPLD_CTRL1_LRCOFF (0x00)
+#define BAST_CPLD_CTRL1_LRCADC (0x01)
+#define BAST_CPLD_CTRL1_LRCDAC (0x02)
+#define BAST_CPLD_CTRL1_LRCARM (0x03)
+#define BAST_CPLD_CTRL1_LRMASK (0x03)
+
+/* CTRL2 - NAND WP control, IDE Reset assert/check */
+
+#define BAST_CPLD_CTRL2_WNAND (0x04)
+#define BAST_CPLD_CTLR2_IDERST (0x08)
+
+/* CTRL3 - rom write control, CPLD identity */
+
+#define BAST_CPLD_CTRL3_IDMASK (0x0e)
+#define BAST_CPLD_CTRL3_ROMWEN (0x01)
+
+/* CTRL4 - 8bit LCD interface control/status */
+
+#define BAST_CPLD_CTRL4_LLAT (0x01)
+#define BAST_CPLD_CTRL4_LCDRW (0x02)
+#define BAST_CPLD_CTRL4_LCDCMD (0x04)
+#define BAST_CPLD_CTRL4_LCDE2 (0x01)
+
+/* CTRL5 - DMA routing */
+
+#define BAST_CPLD_DMA0_PRIIDE (0<<0)
+#define BAST_CPLD_DMA0_SECIDE (1<<0)
+#define BAST_CPLD_DMA0_ISA15 (2<<0)
+#define BAST_CPLD_DMA0_ISA36 (3<<0)
+
+#define BAST_CPLD_DMA1_PRIIDE (0<<2)
+#define BAST_CPLD_DMA1_SECIDE (1<<2)
+#define BAST_CPLD_DMA1_ISA15 (2<<2)
+#define BAST_CPLD_DMA1_ISA36 (3<<2)
+
+#endif /* __ASM_ARCH_BASTCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-irq.h b/arch/arm/mach-s3c2410/include/mach/bast-irq.h
new file mode 100644
index 00000000..cac428c4
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/bast-irq.h
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-irq.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine BAST - IRQ Number 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_BASTIRQ_H
+#define __ASM_ARCH_BASTIRQ_H
+
+/* irq numbers to onboard peripherals */
+
+#define IRQ_USBOC IRQ_EINT18
+#define IRQ_IDE0 IRQ_EINT16
+#define IRQ_IDE1 IRQ_EINT17
+#define IRQ_PCSERIAL1 IRQ_EINT15
+#define IRQ_PCSERIAL2 IRQ_EINT14
+#define IRQ_PCPARALLEL IRQ_EINT13
+#define IRQ_ASIX IRQ_EINT11
+#define IRQ_DM9000 IRQ_EINT10
+#define IRQ_ISA IRQ_EINT9
+#define IRQ_SMALERT IRQ_EINT8
+
+#endif /* __ASM_ARCH_BASTIRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-map.h b/arch/arm/mach-s3c2410/include/mach/bast-map.h
new file mode 100644
index 00000000..6e7dc9d0
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/bast-map.h
@@ -0,0 +1,146 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-map.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine BAST - 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.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x13000000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space. We also have the board's CPLD to find register space
+ * for.
+ */
+
+#ifndef __ASM_ARCH_BASTMAP_H
+#define __ASM_ARCH_BASTMAP_H
+
+#define BAST_IOADDR(x) (S3C2410_ADDR((x) + 0x01300000))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define BAST_VA_CTRL1 BAST_IOADDR(0x00000000) /* 0x01300000 */
+#define BAST_PA_CTRL1 (S3C2410_CS5 | 0x7800000)
+
+#define BAST_VA_CTRL2 BAST_IOADDR(0x00100000) /* 0x01400000 */
+#define BAST_PA_CTRL2 (S3C2410_CS1 | 0x6000000)
+
+#define BAST_VA_CTRL3 BAST_IOADDR(0x00200000) /* 0x01500000 */
+#define BAST_PA_CTRL3 (S3C2410_CS1 | 0x6800000)
+
+#define BAST_VA_CTRL4 BAST_IOADDR(0x00300000) /* 0x01600000 */
+#define BAST_PA_CTRL4 (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define BAST_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
+#define BAST_VA_PC104_IRQREQ BAST_IOADDR(0x00400000)
+
+#define BAST_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
+#define BAST_VA_PC104_IRQRAW BAST_IOADDR(0x00500000)
+
+#define BAST_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
+#define BAST_VA_PC104_IRQMASK BAST_IOADDR(0x00600000)
+
+#define BAST_PA_LCD_RCMD1 (0x8800000)
+#define BAST_VA_LCD_RCMD1 BAST_IOADDR(0x00700000)
+
+#define BAST_PA_LCD_WCMD1 (0x8000000)
+#define BAST_VA_LCD_WCMD1 BAST_IOADDR(0x00800000)
+
+#define BAST_PA_LCD_RDATA1 (0x9800000)
+#define BAST_VA_LCD_RDATA1 BAST_IOADDR(0x00900000)
+
+#define BAST_PA_LCD_WDATA1 (0x9000000)
+#define BAST_VA_LCD_WDATA1 BAST_IOADDR(0x00A00000)
+
+#define BAST_PA_LCD_RCMD2 (0xA800000)
+#define BAST_VA_LCD_RCMD2 BAST_IOADDR(0x00B00000)
+
+#define BAST_PA_LCD_WCMD2 (0xA000000)
+#define BAST_VA_LCD_WCMD2 BAST_IOADDR(0x00C00000)
+
+#define BAST_PA_LCD_RDATA2 (0xB800000)
+#define BAST_VA_LCD_RDATA2 BAST_IOADDR(0x00D00000)
+
+#define BAST_PA_LCD_WDATA2 (0xB000000)
+#define BAST_VA_LCD_WDATA2 BAST_IOADDR(0x00E00000)
+
+
+/* 0xE0000000 contains the IO space that is split by speed and
+ * wether the access is for 8 or 16bit IO... this ensures that
+ * the correct access is made
+ *
+ * 0x10000000 of space, partitioned as so:
+ *
+ * 0x00000000 to 0x04000000 8bit, slow
+ * 0x04000000 to 0x08000000 16bit, slow
+ * 0x08000000 to 0x0C000000 16bit, net
+ * 0x0C000000 to 0x10000000 16bit, fast
+ *
+ * each of these spaces has the following in:
+ *
+ * 0x00000000 to 0x01000000 16MB ISA IO space
+ * 0x01000000 to 0x02000000 16MB ISA memory space
+ * 0x02000000 to 0x02100000 1MB IDE primary channel
+ * 0x02100000 to 0x02200000 1MB IDE primary channel aux
+ * 0x02200000 to 0x02400000 1MB IDE secondary channel
+ * 0x02300000 to 0x02400000 1MB IDE secondary channel aux
+ * 0x02400000 to 0x02500000 1MB ASIX ethernet controller
+ * 0x02500000 to 0x02600000 1MB Davicom DM9000 ethernet controller
+ * 0x02600000 to 0x02700000 1MB PC SuperIO controller
+ *
+ * the phyiscal layout of the zones are:
+ * nGCS2 - 8bit, slow
+ * nGCS3 - 16bit, slow
+ * nGCS4 - 16bit, net
+ * nGCS5 - 16bit, fast
+ */
+
+#define BAST_VA_MULTISPACE (0xE0000000)
+
+#define BAST_VA_ISAIO (BAST_VA_MULTISPACE + 0x00000000)
+#define BAST_VA_ISAMEM (BAST_VA_MULTISPACE + 0x01000000)
+#define BAST_VA_IDEPRI (BAST_VA_MULTISPACE + 0x02000000)
+#define BAST_VA_IDEPRIAUX (BAST_VA_MULTISPACE + 0x02100000)
+#define BAST_VA_IDESEC (BAST_VA_MULTISPACE + 0x02200000)
+#define BAST_VA_IDESECAUX (BAST_VA_MULTISPACE + 0x02300000)
+#define BAST_VA_ASIXNET (BAST_VA_MULTISPACE + 0x02400000)
+#define BAST_VA_DM9000 (BAST_VA_MULTISPACE + 0x02500000)
+#define BAST_VA_SUPERIO (BAST_VA_MULTISPACE + 0x02600000)
+
+#define BAST_VA_MULTISPACE (0xE0000000)
+
+#define BAST_VAM_CS2 (0x00000000)
+#define BAST_VAM_CS3 (0x04000000)
+#define BAST_VAM_CS4 (0x08000000)
+#define BAST_VAM_CS5 (0x0C000000)
+
+/* physical offset addresses for the peripherals */
+
+#define BAST_PA_ISAIO (0x00000000)
+#define BAST_PA_ASIXNET (0x01000000)
+#define BAST_PA_SUPERIO (0x01800000)
+#define BAST_PA_IDEPRI (0x02000000)
+#define BAST_PA_IDEPRIAUX (0x02800000)
+#define BAST_PA_IDESEC (0x03000000)
+#define BAST_PA_IDESECAUX (0x03800000)
+#define BAST_PA_ISAMEM (0x04000000)
+#define BAST_PA_DM9000 (0x05000000)
+
+/* some configurations for the peripherals */
+
+#define BAST_PCSIO (BAST_VA_SUPERIO + BAST_VAM_CS2)
+/* */
+
+#define BAST_ASIXNET_CS BAST_VAM_CS5
+#define BAST_IDE_CS BAST_VAM_CS5
+#define BAST_DM9000_CS BAST_VAM_CS4
+
+#endif /* __ASM_ARCH_BASTMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/bast-pmu.h b/arch/arm/mach-s3c2410/include/mach/bast-pmu.h
new file mode 100644
index 00000000..4c38b39b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/bast-pmu.h
@@ -0,0 +1,40 @@
+/* arch/arm/mach-s3c2410/include/mach/bast-pmu.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@simtec.co.uk>
+ *
+ * Machine BAST - Power Management chip
+ *
+ * This program is free software; you can 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_BASTPMU_H
+#define __ASM_ARCH_BASTPMU_H "08_OCT_2004"
+
+#define BASTPMU_REG_IDENT (0x00)
+#define BASTPMU_REG_VERSION (0x01)
+#define BASTPMU_REG_DDCCTRL (0x02)
+#define BASTPMU_REG_POWER (0x03)
+#define BASTPMU_REG_RESET (0x04)
+#define BASTPMU_REG_GWO (0x05)
+#define BASTPMU_REG_WOL (0x06)
+#define BASTPMU_REG_WOR (0x07)
+#define BASTPMU_REG_UID (0x09)
+
+#define BASTPMU_EEPROM (0xC0)
+
+#define BASTPMU_EEP_UID (BASTPMU_EEPROM + 0)
+#define BASTPMU_EEP_WOL (BASTPMU_EEPROM + 8)
+#define BASTPMU_EEP_WOR (BASTPMU_EEPROM + 9)
+
+#define BASTPMU_IDENT_0 0x53
+#define BASTPMU_IDENT_1 0x42
+#define BASTPMU_IDENT_2 0x50
+#define BASTPMU_IDENT_3 0x4d
+
+#define BASTPMU_RESET_GUARD (0x55)
+
+#endif /* __ASM_ARCH_BASTPMU_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
new file mode 100644
index 00000000..5882deaa
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
@@ -0,0 +1,101 @@
+/* arch/arm/mach-s3c2410/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2005 Simtec Electronics
+ *
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-serial.h>
+
+#define S3C2410_UART1_OFF (0x4000)
+#define SHIFT_2440TXF (14-9)
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C24XX_PA_UART
+ ldr \rv, = S3C24XX_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+ .macro fifo_full_s3c24xx rd, rx
+ @ check for arm920 vs arm926. currently assume all arm926
+ @ devices have an 64 byte FIFO identical to the s3c2440
+ mrc p15, 0, \rd, c0, c0
+ and \rd, \rd, #0xff0
+ teq \rd, #0x260
+ beq 1004f
+ mrc p15, 0, \rd, c1, c0
+ tst \rd, #1
+ addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
+ addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
+ bic \rd, \rd, #0xff000
+ ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+ and \rd, \rd, #0x00ff0000
+ teq \rd, #0x00440000 @ is it 2440?
+1004:
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ moveq \rd, \rd, lsr #SHIFT_2440TXF
+ tst \rd, #S3C2410_UFSTAT_TXFULL
+ .endm
+
+ .macro fifo_full_s3c2410 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ tst \rd, #S3C2410_UFSTAT_TXFULL
+ .endm
+
+/* fifo level reading */
+
+ .macro fifo_level_s3c24xx rd, rx
+ @ check for arm920 vs arm926. currently assume all arm926
+ @ devices have an 64 byte FIFO identical to the s3c2440
+ mrc p15, 0, \rd, c0, c0
+ and \rd, \rd, #0xff0
+ teq \rd, #0x260
+ beq 10000f
+ mrc p15, 0, \rd, c1, c0
+ tst \rd, #1
+ addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
+ addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART)
+ bic \rd, \rd, #0xff000
+ ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
+ and \rd, \rd, #0x00ff0000
+ teq \rd, #0x00440000 @ is it 2440?
+
+10000:
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ andne \rd, \rd, #S3C2410_UFSTAT_TXMASK
+ andeq \rd, \rd, #S3C2440_UFSTAT_TXMASK
+ .endm
+
+ .macro fifo_level_s3c2410 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ and \rd, \rd, #S3C2410_UFSTAT_TXMASK
+ .endm
+
+/* Select the correct implementation depending on the configuration. The
+ * S3C2440 will get selected by default, as these are the most widely
+ * used variants of these
+*/
+
+#if defined(CONFIG_CPU_LLSERIAL_S3C2410_ONLY)
+#define fifo_full fifo_full_s3c2410
+#define fifo_level fifo_level_s3c2410
+#elif !defined(CONFIG_CPU_LLSERIAL_S3C2440_ONLY)
+#define fifo_full fifo_full_s3c24xx
+#define fifo_level fifo_level_s3c24xx
+#endif
+
+/* include the reset of the code which will do the work */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h
new file mode 100644
index 00000000..b2b2a5bb
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/dma.h
@@ -0,0 +1,204 @@
+/* arch/arm/mach-s3c2410/include/mach/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA 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_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#include <plat/dma.h>
+#include <linux/sysdev.h>
+
+#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
+
+/* We use `virtual` dma channels to hide the fact we have only a limited
+ * number of DMA channels, and not of all of them (dependent on the device)
+ * can be attached to any DMA source. We therefore let the DMA core handle
+ * the allocation of hardware channels to clients.
+*/
+
+enum dma_ch {
+ DMACH_XD0,
+ DMACH_XD1,
+ DMACH_SDI,
+ DMACH_SPI0,
+ DMACH_SPI1,
+ DMACH_UART0,
+ DMACH_UART1,
+ DMACH_UART2,
+ DMACH_TIMER,
+ DMACH_I2S_IN,
+ DMACH_I2S_OUT,
+ DMACH_PCM_IN,
+ DMACH_PCM_OUT,
+ DMACH_MIC_IN,
+ DMACH_USB_EP1,
+ DMACH_USB_EP2,
+ DMACH_USB_EP3,
+ DMACH_USB_EP4,
+ DMACH_UART0_SRC2, /* s3c2412 second uart sources */
+ DMACH_UART1_SRC2,
+ DMACH_UART2_SRC2,
+ DMACH_UART3, /* s3c2443 has extra uart */
+ DMACH_UART3_SRC2,
+ DMACH_MAX, /* the end entry */
+};
+
+#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
+
+/* we have 4 dma channels */
+#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
+#define S3C_DMA_CHANNELS (4)
+#else
+#define S3C_DMA_CHANNELS (6)
+#endif
+
+/* types */
+
+enum s3c2410_dma_state {
+ S3C2410_DMA_IDLE,
+ S3C2410_DMA_RUNNING,
+ S3C2410_DMA_PAUSED
+};
+
+/* enum s3c2410_dma_loadst
+ *
+ * This represents the state of the DMA engine, wrt to the loaded / running
+ * transfers. Since we don't have any way of knowing exactly the state of
+ * the DMA transfers, we need to know the state to make decisions on wether
+ * we can
+ *
+ * S3C2410_DMA_NONE
+ *
+ * There are no buffers loaded (the channel should be inactive)
+ *
+ * S3C2410_DMA_1LOADED
+ *
+ * There is one buffer loaded, however it has not been confirmed to be
+ * loaded by the DMA engine. This may be because the channel is not
+ * yet running, or the DMA driver decided that it was too costly to
+ * sit and wait for it to happen.
+ *
+ * S3C2410_DMA_1RUNNING
+ *
+ * The buffer has been confirmed running, and not finisged
+ *
+ * S3C2410_DMA_1LOADED_1RUNNING
+ *
+ * There is a buffer waiting to be loaded by the DMA engine, and one
+ * currently running.
+*/
+
+enum s3c2410_dma_loadst {
+ S3C2410_DMALOAD_NONE,
+ S3C2410_DMALOAD_1LOADED,
+ S3C2410_DMALOAD_1RUNNING,
+ S3C2410_DMALOAD_1LOADED_1RUNNING,
+};
+
+
+/* flags */
+
+#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about
+ * waiting for reloads */
+#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
+
+#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
+
+/* dma buffer */
+
+struct s3c2410_dma_buf;
+
+/* s3c2410_dma_buf
+ *
+ * internally used buffer structure to describe a queued or running
+ * buffer.
+*/
+
+struct s3c2410_dma_buf {
+ struct s3c2410_dma_buf *next;
+ int magic; /* magic */
+ int size; /* buffer size in bytes */
+ dma_addr_t data; /* start of DMA data */
+ dma_addr_t ptr; /* where the DMA got to [1] */
+ void *id; /* client's id */
+};
+
+/* [1] is this updated for both recv/send modes? */
+
+struct s3c2410_dma_stats {
+ unsigned long loads;
+ unsigned long timeout_longest;
+ unsigned long timeout_shortest;
+ unsigned long timeout_avg;
+ unsigned long timeout_failed;
+};
+
+struct s3c2410_dma_map;
+
+/* struct s3c2410_dma_chan
+ *
+ * full state information for each DMA channel
+*/
+
+struct s3c2410_dma_chan {
+ /* channel state flags and information */
+ unsigned char number; /* number of this dma channel */
+ unsigned char in_use; /* channel allocated */
+ unsigned char irq_claimed; /* irq claimed for channel */
+ unsigned char irq_enabled; /* irq enabled for channel */
+ unsigned char xfer_unit; /* size of an transfer */
+
+ /* channel state */
+
+ enum s3c2410_dma_state state;
+ enum s3c2410_dma_loadst load_state;
+ struct s3c2410_dma_client *client;
+
+ /* channel configuration */
+ enum s3c2410_dmasrc source;
+ enum dma_ch req_ch;
+ unsigned long dev_addr;
+ unsigned long load_timeout;
+ unsigned int flags; /* channel flags */
+
+ struct s3c24xx_dma_map *map; /* channel hw maps */
+
+ /* channel's hardware position and configuration */
+ void __iomem *regs; /* channels registers */
+ void __iomem *addr_reg; /* data address register */
+ unsigned int irq; /* channel irq */
+ unsigned long dcon; /* default value of DCON */
+
+ /* driver handles */
+ s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
+ s3c2410_dma_opfn_t op_fn; /* channel op callback */
+
+ /* stats gathering */
+ struct s3c2410_dma_stats *stats;
+ struct s3c2410_dma_stats stats_store;
+
+ /* buffer list and information */
+ struct s3c2410_dma_buf *curr; /* current dma buffer */
+ struct s3c2410_dma_buf *next; /* next buffer to load */
+ struct s3c2410_dma_buf *end; /* end of queue */
+
+ /* system device */
+ struct sys_device dev;
+};
+
+typedef unsigned long dma_device_t;
+
+static inline bool s3c_dma_has_circular(void)
+{
+ return false;
+}
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/entry-macro.S b/arch/arm/mach-s3c2410/include/mach/entry-macro.S
new file mode 100644
index 00000000..473b3cd3
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/entry-macro.S
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-s3c2410/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for S3C2410-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+/* We have a problem that the INTOFFSET register does not always
+ * show one interrupt. Occasionally we get two interrupts through
+ * the prioritiser, and this causes the INTOFFSET register to show
+ * what looks like the logical-or of the two interrupt numbers.
+ *
+ * Thanks to Klaus, Shannon, et al for helping to debug this problem
+*/
+
+#define INTPND (0x10)
+#define INTOFFSET (0x14)
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \base, #S3C24XX_VA_IRQ
+
+ @@ try the interrupt offset register, since it is there
+
+ ldr \irqstat, [ \base, #INTPND ]
+ teq \irqstat, #0
+ beq 1002f
+ ldr \irqnr, [ \base, #INTOFFSET ]
+ mov \tmp, #1
+ tst \irqstat, \tmp, lsl \irqnr
+ bne 1001f
+
+ @@ the number specified is not a valid irq, so try
+ @@ and work it out for ourselves
+
+ mov \irqnr, #0 @@ start here
+
+ @@ work out which irq (if any) we got
+
+ movs \tmp, \irqstat, lsl#16
+ addeq \irqnr, \irqnr, #16
+ moveq \irqstat, \irqstat, lsr#16
+ tst \irqstat, #0xff
+ addeq \irqnr, \irqnr, #8
+ moveq \irqstat, \irqstat, lsr#8
+ tst \irqstat, #0xf
+ addeq \irqnr, \irqnr, #4
+ moveq \irqstat, \irqstat, lsr#4
+ tst \irqstat, #0x3
+ addeq \irqnr, \irqnr, #2
+ moveq \irqstat, \irqstat, lsr#2
+ tst \irqstat, #0x1
+ addeq \irqnr, \irqnr, #1
+
+ @@ we have the value
+1001:
+ adds \irqnr, \irqnr, #IRQ_EINT0
+1002:
+ @@ exit here, Z flag unset if IRQ
+
+ .endm
+
+ /* currently don't need an disable_fiq macro */
+
+ .macro disable_fiq
+ .endm
diff --git a/arch/arm/mach-s3c2410/include/mach/fb.h b/arch/arm/mach-s3c2410/include/mach/fb.h
new file mode 100644
index 00000000..eee0654e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/fb.h
@@ -0,0 +1,74 @@
+/* arch/arm/mach-s3c2410/include/mach/fb.h
+ *
+ * Copyright (c) 2004 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * Inspired by pxafb.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_FB_H
+#define __ASM_ARM_FB_H
+
+#include <mach/regs-lcd.h>
+
+struct s3c2410fb_hw {
+ unsigned long lcdcon1;
+ unsigned long lcdcon2;
+ unsigned long lcdcon3;
+ unsigned long lcdcon4;
+ unsigned long lcdcon5;
+};
+
+/* LCD description */
+struct s3c2410fb_display {
+ /* LCD type */
+ unsigned type;
+
+ /* Screen size */
+ unsigned short width;
+ unsigned short height;
+
+ /* Screen info */
+ unsigned short xres;
+ unsigned short yres;
+ unsigned short bpp;
+
+ unsigned pixclock; /* pixclock in picoseconds */
+ unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
+ unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
+ unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
+ unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
+
+ /* lcd configuration registers */
+ unsigned long lcdcon5;
+};
+
+struct s3c2410fb_mach_info {
+
+ struct s3c2410fb_display *displays; /* attached diplays info */
+ unsigned num_displays; /* number of defined displays */
+ unsigned default_display;
+
+ /* GPIOs */
+
+ unsigned long gpcup;
+ unsigned long gpcup_mask;
+ unsigned long gpccon;
+ unsigned long gpccon_mask;
+ unsigned long gpdup;
+ unsigned long gpdup_mask;
+ unsigned long gpdcon;
+ unsigned long gpdcon_mask;
+
+ /* lpc3600 control register */
+ unsigned long lpcsel;
+};
+
+extern void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *);
+
+#endif /* __ASM_ARM_FB_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-fns.h b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
new file mode 100644
index 00000000..f453c4f2
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-fns.h
@@ -0,0 +1,104 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-fns.h
+ *
+ * Copyright (c) 2003-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - 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 __MACH_GPIO_FNS_H
+#define __MACH_GPIO_FNS_H __FILE__
+
+/* These functions are in the to-be-removed category and it is strongly
+ * encouraged not to use these in new code. They will be marked deprecated
+ * very soon.
+ *
+ * Most of the functionality can be either replaced by the gpiocfg calls
+ * for the s3c platform or by the generic GPIOlib API.
+ *
+ * As of 2.6.35-rc, these will be removed, with the few drivers using them
+ * either replaced or given a wrapper until the calls can be removed.
+*/
+
+#include <plat/gpio-cfg.h>
+
+static inline void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int cfg)
+{
+ /* 1:1 mapping between cfgpin and setcfg calls at the moment */
+ s3c_gpio_cfgpin(pin, cfg);
+}
+
+/* external functions for GPIO support
+ *
+ * These allow various different clients to access the same GPIO
+ * registers without conflicting. If your driver only owns the entire
+ * GPIO register, then it is safe to ioremap/__raw_{read|write} to it.
+*/
+
+extern unsigned int s3c2410_gpio_getcfg(unsigned int pin);
+
+/* s3c2410_gpio_getirq
+ *
+ * turn the given pin number into the corresponding IRQ number
+ *
+ * returns:
+ * < 0 = no interrupt for this pin
+ * >=0 = interrupt number for the pin
+*/
+
+extern int s3c2410_gpio_getirq(unsigned int pin);
+
+#ifdef CONFIG_CPU_S3C2400
+
+extern int s3c2400_gpio_getirq(unsigned int pin);
+
+#endif /* CONFIG_CPU_S3C2400 */
+
+/* s3c2410_gpio_irqfilter
+ *
+ * set the irq filtering on the given pin
+ *
+ * on = 0 => disable filtering
+ * 1 => enable filtering
+ *
+ * config = S3C2410_EINTFLT_PCLK or S3C2410_EINTFLT_EXTCLK orred with
+ * width of filter (0 through 63)
+ *
+ *
+*/
+
+extern int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
+ unsigned int config);
+
+/* s3c2410_gpio_pullup
+ *
+ * This call should be replaced with s3c_gpio_setpull().
+ *
+ * As a note, there is currently no distinction between pull-up and pull-down
+ * in the s3c24xx series devices with only an on/off configuration.
+ */
+
+/* s3c2410_gpio_pullup
+ *
+ * configure the pull-up control on the given pin
+ *
+ * to = 1 => disable the pull-up
+ * 0 => enable the pull-up
+ *
+ * eg;
+ *
+ * s3c2410_gpio_pullup(S3C2410_GPB(0), 0);
+ * s3c2410_gpio_pullup(S3C2410_GPE(8), 0);
+*/
+
+extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);
+
+extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
+
+extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
+
+#endif /* __MACH_GPIO_FNS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
new file mode 100644
index 00000000..4f7bf327
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
@@ -0,0 +1,118 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio-nrs.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - GPIO bank numbering
+ *
+ * This program is free software; you can 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_GPIONRS_H
+#define __MACH_GPIONRS_H
+
+#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
+
+#define S3C2410_GPIO_BANKG (32*6)
+#define S3C2410_GPIO_BANKH (32*7)
+
+/* GPIO sizes for various SoCs:
+ *
+ * 2442
+ * 2410 2412 2440 2443 2416
+ * ---- ---- ---- ---- ----
+ * A 23 22 25 16 25
+ * B 11 11 11 11 9
+ * C 16 15 16 16 16
+ * D 16 16 16 16 16
+ * E 16 16 16 16 16
+ * F 8 8 8 8 8
+ * G 16 16 16 16 8
+ * H 11 11 9 15 15
+ * J -- -- 13 16 --
+ * K -- -- -- -- 16
+ * L -- -- -- 15 7
+ * M -- -- -- 2 2
+ */
+
+/* GPIO bank sizes */
+#define S3C2410_GPIO_A_NR (32)
+#define S3C2410_GPIO_B_NR (32)
+#define S3C2410_GPIO_C_NR (32)
+#define S3C2410_GPIO_D_NR (32)
+#define S3C2410_GPIO_E_NR (32)
+#define S3C2410_GPIO_F_NR (32)
+#define S3C2410_GPIO_G_NR (32)
+#define S3C2410_GPIO_H_NR (32)
+#define S3C2410_GPIO_J_NR (32) /* technically 16. */
+#define S3C2410_GPIO_K_NR (32) /* technically 16. */
+#define S3C2410_GPIO_L_NR (32) /* technically 15. */
+#define S3C2410_GPIO_M_NR (32) /* technically 2. */
+
+#if CONFIG_S3C_GPIO_SPACE != 0
+#error CONFIG_S3C_GPIO_SPACE cannot be zero at the moment
+#endif
+
+#define S3C2410_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 0)
+
+#ifndef __ASSEMBLY__
+
+enum s3c_gpio_number {
+ S3C2410_GPIO_A_START = 0,
+ S3C2410_GPIO_B_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_A),
+ S3C2410_GPIO_C_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_B),
+ S3C2410_GPIO_D_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_C),
+ S3C2410_GPIO_E_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_D),
+ S3C2410_GPIO_F_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_E),
+ S3C2410_GPIO_G_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_F),
+ S3C2410_GPIO_H_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_G),
+ S3C2410_GPIO_J_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_H),
+ S3C2410_GPIO_K_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_J),
+ S3C2410_GPIO_L_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_K),
+ S3C2410_GPIO_M_START = S3C2410_GPIO_NEXT(S3C2410_GPIO_L),
+};
+
+#endif /* __ASSEMBLY__ */
+
+/* S3C2410 GPIO number definitions. */
+
+#define S3C2410_GPA(_nr) (S3C2410_GPIO_A_START + (_nr))
+#define S3C2410_GPB(_nr) (S3C2410_GPIO_B_START + (_nr))
+#define S3C2410_GPC(_nr) (S3C2410_GPIO_C_START + (_nr))
+#define S3C2410_GPD(_nr) (S3C2410_GPIO_D_START + (_nr))
+#define S3C2410_GPE(_nr) (S3C2410_GPIO_E_START + (_nr))
+#define S3C2410_GPF(_nr) (S3C2410_GPIO_F_START + (_nr))
+#define S3C2410_GPG(_nr) (S3C2410_GPIO_G_START + (_nr))
+#define S3C2410_GPH(_nr) (S3C2410_GPIO_H_START + (_nr))
+#define S3C2410_GPJ(_nr) (S3C2410_GPIO_J_START + (_nr))
+#define S3C2410_GPK(_nr) (S3C2410_GPIO_K_START + (_nr))
+#define S3C2410_GPL(_nr) (S3C2410_GPIO_L_START + (_nr))
+#define S3C2410_GPM(_nr) (S3C2410_GPIO_M_START + (_nr))
+
+/* compatibility until drivers can be modified */
+
+#define S3C2410_GPA0 S3C2410_GPA(0)
+#define S3C2410_GPA1 S3C2410_GPA(1)
+#define S3C2410_GPA3 S3C2410_GPA(3)
+#define S3C2410_GPA7 S3C2410_GPA(7)
+
+#define S3C2410_GPE0 S3C2410_GPE(0)
+#define S3C2410_GPE1 S3C2410_GPE(1)
+#define S3C2410_GPE2 S3C2410_GPE(2)
+#define S3C2410_GPE3 S3C2410_GPE(3)
+#define S3C2410_GPE4 S3C2410_GPE(4)
+#define S3C2410_GPE5 S3C2410_GPE(5)
+#define S3C2410_GPE6 S3C2410_GPE(6)
+#define S3C2410_GPE7 S3C2410_GPE(7)
+#define S3C2410_GPE8 S3C2410_GPE(8)
+#define S3C2410_GPE9 S3C2410_GPE(9)
+#define S3C2410_GPE10 S3C2410_GPE(10)
+
+#define S3C2410_GPH10 S3C2410_GPH(10)
+
+#endif /* __MACH_GPIONRS_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio-track.h b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
new file mode 100644
index 00000000..d67819dd
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio-track.h
@@ -0,0 +1,33 @@
+/* arch/arm/mach-s3c24100/include/mach/gpio-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - GPIO core 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_CORE_H
+#define __ASM_ARCH_GPIO_CORE_H __FILE__
+
+#include <mach/regs-gpio.h>
+
+extern struct s3c_gpio_chip s3c24xx_gpios[];
+
+static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip;
+
+ if (pin > S3C_GPIO_END)
+ return NULL;
+
+ chip = &s3c24xx_gpios[pin/32];
+ return ((pin - chip->chip.base) < chip->chip.ngpio) ? chip : NULL;
+}
+
+#endif /* __ASM_ARCH_GPIO_CORE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/gpio.h b/arch/arm/mach-s3c2410/include/mach/gpio.h
new file mode 100644
index 00000000..f7f6b07d
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/gpio.h
@@ -0,0 +1,41 @@
+/* arch/arm/mach-s3c2410/include/mach/gpio.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - 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.
+*/
+
+#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
+
+/* some boards require extra gpio capacity to support external
+ * devices that need GPIO.
+ */
+
+#ifdef CONFIG_CPU_S3C244X
+#define ARCH_NR_GPIOS (32 * 9 + CONFIG_S3C24XX_GPIO_EXTRA)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define ARCH_NR_GPIOS (32 * 12 + CONFIG_S3C24XX_GPIO_EXTRA)
+#else
+#define ARCH_NR_GPIOS (256 + CONFIG_S3C24XX_GPIO_EXTRA)
+#endif
+
+#include <asm-generic/gpio.h>
+#include <mach/gpio-nrs.h>
+#include <mach/gpio-fns.h>
+
+#ifdef CONFIG_CPU_S3C244X
+#define S3C_GPIO_END (S3C2410_GPJ(0) + 32)
+#elif defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define S3C_GPIO_END (S3C2410_GPM(0) + 32)
+#else
+#define S3C_GPIO_END (S3C2410_GPH(0) + 32)
+#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/h1940-latch.h b/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
new file mode 100644
index 00000000..97e42bfc
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/h1940-latch.h
@@ -0,0 +1,43 @@
+/* arch/arm/mach-s3c2410/include/mach/h1940-latch.h
+ *
+ * Copyright (c) 2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * iPAQ H1940 series - latch 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_H1940_LATCH_H
+#define __ASM_ARCH_H1940_LATCH_H
+
+#include <mach/gpio.h>
+
+#define H1940_LATCH_GPIO(x) (S3C_GPIO_END + (x))
+
+/* SD layer latch */
+
+#define H1940_LATCH_LCD_P0 H1940_LATCH_GPIO(0)
+#define H1940_LATCH_LCD_P1 H1940_LATCH_GPIO(1)
+#define H1940_LATCH_LCD_P2 H1940_LATCH_GPIO(2)
+#define H1940_LATCH_LCD_P3 H1940_LATCH_GPIO(3)
+#define H1940_LATCH_MAX1698_nSHUTDOWN H1940_LATCH_GPIO(4)
+#define H1940_LATCH_LED_RED H1940_LATCH_GPIO(5)
+#define H1940_LATCH_SDQ7 H1940_LATCH_GPIO(6)
+#define H1940_LATCH_USB_DP H1940_LATCH_GPIO(7)
+
+/* CPU layer latch */
+
+#define H1940_LATCH_UDA_POWER H1940_LATCH_GPIO(8)
+#define H1940_LATCH_AUDIO_POWER H1940_LATCH_GPIO(9)
+#define H1940_LATCH_SM803_ENABLE H1940_LATCH_GPIO(10)
+#define H1940_LATCH_LCD_P4 H1940_LATCH_GPIO(11)
+#define H1940_LATCH_SD_POWER H1940_LATCH_GPIO(12)
+#define H1940_LATCH_BLUETOOTH_POWER H1940_LATCH_GPIO(13)
+#define H1940_LATCH_LED_GREEN H1940_LATCH_GPIO(14)
+#define H1940_LATCH_LED_FLASH H1940_LATCH_GPIO(15)
+
+#endif /* __ASM_ARCH_H1940_LATCH_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/h1940.h b/arch/arm/mach-s3c2410/include/mach/h1940.h
new file mode 100644
index 00000000..2aa683c8
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/h1940.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/h1940.h
+ *
+ * Copyright 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * H1940 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_H1940_H
+#define __ASM_ARCH_H1940_H
+
+#define H1940_SUSPEND_CHECKSUM (0x30003ff8)
+#define H1940_SUSPEND_RESUMEAT (0x30081000)
+#define H1940_SUSPEND_CHECK (0x30080000)
+
+extern void h1940_pm_return(void);
+extern int h1940_led_blink_set(unsigned gpio, int state,
+ unsigned long *delay_on, unsigned long *delay_off);
+
+
+#endif /* __ASM_ARCH_H1940_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/hardware.h b/arch/arm/mach-s3c2410/include/mach/hardware.h
new file mode 100644
index 00000000..aef5631e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/hardware.h
@@ -0,0 +1,42 @@
+/* arch/arm/mach-s3c2410/include/mach/hardware.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - 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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#ifndef __ASSEMBLY__
+
+extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+#ifdef CONFIG_CPU_S3C2412
+
+extern int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state);
+
+#endif /* CONFIG_CPU_S3C2412 */
+
+#endif /* __ASSEMBLY__ */
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+/* machine specific hardware definitions should go after this */
+
+/* currently here until moved into config (todo) */
+#define CONFIG_NO_MULTIWORD_IO
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/idle.h b/arch/arm/mach-s3c2410/include/mach/idle.h
new file mode 100644
index 00000000..e9ddd706
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/idle.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/idle.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 CPU Idle controls
+*/
+
+#ifndef __ASM_ARCH_IDLE_H
+#define __ASM_ARCH_IDLE_H __FILE__
+
+/* This allows the over-ride of the default idle code, in case there
+ * is any other things to be done over idle (like DVS)
+*/
+
+extern void (*s3c24xx_idle)(void);
+
+extern void s3c24xx_default_idle(void);
+
+#endif /* __ASM_ARCH_IDLE_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/io.h b/arch/arm/mach-s3c2410/include/mach/io.h
new file mode 100644
index 00000000..9813dbf2
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/io.h
@@ -0,0 +1,218 @@
+/*
+ * arch/arm/mach-s3c2410/include/mach/io.h
+ * from arch/arm/mach-rpc/include/mach/io.h
+ *
+ * Copyright (C) 1997 Russell King
+ * (C) 2003 Simtec Electronics
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We use two different types of addressing - PC style addresses, and ARM
+ * addresses. PC style accesses the PC hardware with the normal PC IO
+ * addresses, eg 0x3f8 for serial#1. ARM addresses are above A28
+ * and are translated to the start of IO. Note that all addresses are
+ * not shifted left!
+ */
+
+#define __PORT_PCIO(x) ((x) < (1<<28))
+
+#define PCIO_BASE (S3C24XX_VA_ISA_WORD)
+#define PCIO_BASE_b (S3C24XX_VA_ISA_BYTE)
+#define PCIO_BASE_w (S3C24XX_VA_ISA_WORD)
+#define PCIO_BASE_l (S3C24XX_VA_ISA_WORD)
+/*
+ * Dynamic IO functions - let the compiler
+ * optimize the expressions
+ */
+
+#define DECLARE_DYN_OUT(sz,fnsuffix,instr) \
+static inline void __out##fnsuffix (unsigned int val, unsigned int port) \
+{ \
+ unsigned long temp; \
+ __asm__ __volatile__( \
+ "cmp %2, #(1<<28)\n\t" \
+ "mov %0, %2\n\t" \
+ "addcc %0, %0, %3\n\t" \
+ "str" instr " %1, [%0, #0 ] @ out" #fnsuffix \
+ : "=&r" (temp) \
+ : "r" (val), "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \
+ : "cc"); \
+}
+
+
+#define DECLARE_DYN_IN(sz,fnsuffix,instr) \
+static inline unsigned sz __in##fnsuffix (unsigned int port) \
+{ \
+ unsigned long temp, value; \
+ __asm__ __volatile__( \
+ "cmp %2, #(1<<28)\n\t" \
+ "mov %0, %2\n\t" \
+ "addcc %0, %0, %3\n\t" \
+ "ldr" instr " %1, [%0, #0 ] @ in" #fnsuffix \
+ : "=&r" (temp), "=r" (value) \
+ : "r" (port), "Ir" (PCIO_BASE_##fnsuffix) \
+ : "cc"); \
+ return (unsigned sz)value; \
+}
+
+static inline void __iomem *__ioaddr (unsigned long port)
+{
+ return __PORT_PCIO(port) ? (PCIO_BASE + port) : (void __iomem *)port;
+}
+
+#define DECLARE_IO(sz,fnsuffix,instr) \
+ DECLARE_DYN_IN(sz,fnsuffix,instr) \
+ DECLARE_DYN_OUT(sz,fnsuffix,instr)
+
+DECLARE_IO(char,b,"b")
+DECLARE_IO(short,w,"h")
+DECLARE_IO(int,l,"")
+
+#undef DECLARE_IO
+#undef DECLARE_DYN_IN
+
+/*
+ * Constant address IO functions
+ *
+ * These have to be macros for the 'J' constraint to work -
+ * +/-4096 immediate operand.
+ */
+#define __outbc(value,port) \
+({ \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "strb %0, [%1, %2] @ outbc" \
+ : : "r" (value), "r" (PCIO_BASE), "Jr" ((port))); \
+ else \
+ __asm__ __volatile__( \
+ "strb %0, [%1, #0] @ outbc" \
+ : : "r" (value), "r" ((port))); \
+})
+
+#define __inbc(port) \
+({ \
+ unsigned char result; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "ldrb %0, [%1, %2] @ inbc" \
+ : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \
+ else \
+ __asm__ __volatile__( \
+ "ldrb %0, [%1, #0] @ inbc" \
+ : "=r" (result) : "r" ((port))); \
+ result; \
+})
+
+#define __outwc(value,port) \
+({ \
+ unsigned long v = value; \
+ if (__PORT_PCIO((port))) { \
+ if ((port) < 256 && (port) > -256) \
+ __asm__ __volatile__( \
+ "strh %0, [%1, %2] @ outwc" \
+ : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \
+ else if ((port) > 0) \
+ __asm__ __volatile__( \
+ "strh %0, [%1, %2] @ outwc" \
+ : : "r" (v), \
+ "r" (PCIO_BASE + ((port) & ~0xff)), \
+ "Jr" (((port) & 0xff))); \
+ else \
+ __asm__ __volatile__( \
+ "strh %0, [%1, #0] @ outwc" \
+ : : "r" (v), \
+ "r" (PCIO_BASE + (port))); \
+ } else \
+ __asm__ __volatile__( \
+ "strh %0, [%1, #0] @ outwc" \
+ : : "r" (v), "r" ((port))); \
+})
+
+#define __inwc(port) \
+({ \
+ unsigned short result; \
+ if (__PORT_PCIO((port))) { \
+ if ((port) < 256 && (port) > -256 ) \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, %2] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE), \
+ "Jr" ((port))); \
+ else if ((port) > 0) \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, %2] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE + ((port) & ~0xff)), \
+ "Jr" (((port) & 0xff))); \
+ else \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, #0] @ inwc" \
+ : "=r" (result) \
+ : "r" (PCIO_BASE + ((port)))); \
+ } else \
+ __asm__ __volatile__( \
+ "ldrh %0, [%1, #0] @ inwc" \
+ : "=r" (result) : "r" ((port))); \
+ result; \
+})
+
+#define __outlc(value,port) \
+({ \
+ unsigned long v = value; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "str %0, [%1, %2] @ outlc" \
+ : : "r" (v), "r" (PCIO_BASE), "Jr" ((port))); \
+ else \
+ __asm__ __volatile__( \
+ "str %0, [%1, #0] @ outlc" \
+ : : "r" (v), "r" ((port))); \
+})
+
+#define __inlc(port) \
+({ \
+ unsigned long result; \
+ if (__PORT_PCIO((port))) \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, %2] @ inlc" \
+ : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port))); \
+ else \
+ __asm__ __volatile__( \
+ "ldr %0, [%1, #0] @ inlc" \
+ : "=r" (result) : "r" ((port))); \
+ result; \
+})
+
+#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port)))
+
+#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p))
+#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p))
+#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p))
+#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p))
+#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p))
+#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p))
+#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p))
+/* the following macro is deprecated */
+#define ioaddr(port) __ioaddr((port))
+
+#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l)
+#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l)
+#define insl(p,d,l) __raw_readsl(__ioaddr(p),d,l)
+
+#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l)
+#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l)
+#define outsl(p,d,l) __raw_writesl(__ioaddr(p),d,l)
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+#define __mem_pci(x) (x)
+
+#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/irqs.h b/arch/arm/mach-s3c2410/include/mach/irqs.h
new file mode 100644
index 00000000..e5a68ea1
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/irqs.h
@@ -0,0 +1,202 @@
+/* arch/arm/mach-s3c2410/include/mach/irqs.h
+ *
+ * Copyright (c) 2003-2005 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.
+*/
+
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ */
+
+#define S3C2410_CPUIRQ_OFFSET (16)
+
+#define S3C2410_IRQ(x) ((x) + S3C2410_CPUIRQ_OFFSET)
+
+/* main cpu interrupts */
+#define IRQ_EINT0 S3C2410_IRQ(0) /* 16 */
+#define IRQ_EINT1 S3C2410_IRQ(1)
+#define IRQ_EINT2 S3C2410_IRQ(2)
+#define IRQ_EINT3 S3C2410_IRQ(3)
+#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */
+#define IRQ_EINT8t23 S3C2410_IRQ(5)
+#define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */
+#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440,s3c2443 */
+#define IRQ_BATT_FLT S3C2410_IRQ(7)
+#define IRQ_TICK S3C2410_IRQ(8) /* 24 */
+#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */
+#define IRQ_TIMER0 S3C2410_IRQ(10)
+#define IRQ_TIMER1 S3C2410_IRQ(11)
+#define IRQ_TIMER2 S3C2410_IRQ(12)
+#define IRQ_TIMER3 S3C2410_IRQ(13)
+#define IRQ_TIMER4 S3C2410_IRQ(14)
+#define IRQ_UART2 S3C2410_IRQ(15)
+#define IRQ_LCD S3C2410_IRQ(16) /* 32 */
+#define IRQ_DMA0 S3C2410_IRQ(17) /* IRQ_DMA for s3c2443 */
+#define IRQ_DMA1 S3C2410_IRQ(18)
+#define IRQ_DMA2 S3C2410_IRQ(19)
+#define IRQ_DMA3 S3C2410_IRQ(20)
+#define IRQ_SDI S3C2410_IRQ(21)
+#define IRQ_SPI0 S3C2410_IRQ(22)
+#define IRQ_UART1 S3C2410_IRQ(23)
+#define IRQ_RESERVED24 S3C2410_IRQ(24) /* 40 */
+#define IRQ_NFCON S3C2410_IRQ(24) /* for s3c2440 */
+#define IRQ_USBD S3C2410_IRQ(25)
+#define IRQ_USBH S3C2410_IRQ(26)
+#define IRQ_IIC S3C2410_IRQ(27)
+#define IRQ_UART0 S3C2410_IRQ(28) /* 44 */
+#define IRQ_SPI1 S3C2410_IRQ(29)
+#define IRQ_RTC S3C2410_IRQ(30)
+#define IRQ_ADCPARENT S3C2410_IRQ(31)
+
+/* interrupts generated from the external interrupts sources */
+#define IRQ_EINT4 S3C2410_IRQ(32) /* 48 */
+#define IRQ_EINT5 S3C2410_IRQ(33)
+#define IRQ_EINT6 S3C2410_IRQ(34)
+#define IRQ_EINT7 S3C2410_IRQ(35)
+#define IRQ_EINT8 S3C2410_IRQ(36)
+#define IRQ_EINT9 S3C2410_IRQ(37)
+#define IRQ_EINT10 S3C2410_IRQ(38)
+#define IRQ_EINT11 S3C2410_IRQ(39)
+#define IRQ_EINT12 S3C2410_IRQ(40)
+#define IRQ_EINT13 S3C2410_IRQ(41)
+#define IRQ_EINT14 S3C2410_IRQ(42)
+#define IRQ_EINT15 S3C2410_IRQ(43)
+#define IRQ_EINT16 S3C2410_IRQ(44)
+#define IRQ_EINT17 S3C2410_IRQ(45)
+#define IRQ_EINT18 S3C2410_IRQ(46)
+#define IRQ_EINT19 S3C2410_IRQ(47)
+#define IRQ_EINT20 S3C2410_IRQ(48) /* 64 */
+#define IRQ_EINT21 S3C2410_IRQ(49)
+#define IRQ_EINT22 S3C2410_IRQ(50)
+#define IRQ_EINT23 S3C2410_IRQ(51)
+
+#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT4 + 4)
+#define IRQ_EINT(x) (((x) >= 4) ? (IRQ_EINT4 + (x) - 4) : (IRQ_EINT0 + (x)))
+
+#define IRQ_LCD_FIFO S3C2410_IRQ(52)
+#define IRQ_LCD_FRAME S3C2410_IRQ(53)
+
+/* IRQs for the interal UARTs, and ADC
+ * these need to be ordered in number of appearance in the
+ * SUBSRC mask register
+*/
+
+#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+54)
+
+#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 70 */
+#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1)
+#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2)
+
+#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 73 */
+#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4)
+#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5)
+
+#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 76 */
+#define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7)
+#define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8)
+
+#define IRQ_TC S3C2410_IRQSUB(9)
+#define IRQ_ADC S3C2410_IRQSUB(10)
+
+/* extra irqs for s3c2412 */
+
+#define IRQ_S3C2412_CFSDI S3C2410_IRQ(21)
+
+#define IRQ_S3C2412_SDI S3C2410_IRQSUB(13)
+#define IRQ_S3C2412_CF S3C2410_IRQSUB(14)
+
+
+#define IRQ_S3C2416_EINT8t15 S3C2410_IRQ(5)
+#define IRQ_S3C2416_DMA S3C2410_IRQ(17)
+#define IRQ_S3C2416_UART3 S3C2410_IRQ(18)
+#define IRQ_S3C2416_SDI1 S3C2410_IRQ(20)
+#define IRQ_S3C2416_SDI0 S3C2410_IRQ(21)
+
+#define IRQ_S3C2416_LCD2 S3C2410_IRQSUB(15)
+#define IRQ_S3C2416_LCD3 S3C2410_IRQSUB(16)
+#define IRQ_S3C2416_LCD4 S3C2410_IRQSUB(17)
+#define IRQ_S3C2416_DMA0 S3C2410_IRQSUB(18)
+#define IRQ_S3C2416_DMA1 S3C2410_IRQSUB(19)
+#define IRQ_S3C2416_DMA2 S3C2410_IRQSUB(20)
+#define IRQ_S3C2416_DMA3 S3C2410_IRQSUB(21)
+#define IRQ_S3C2416_DMA4 S3C2410_IRQSUB(22)
+#define IRQ_S3C2416_DMA5 S3C2410_IRQSUB(23)
+#define IRQ_S32416_WDT S3C2410_IRQSUB(27)
+#define IRQ_S32416_AC97 S3C2410_IRQSUB(28)
+
+
+/* extra irqs for s3c2440 */
+
+#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
+#define IRQ_S3C2440_CAM_P S3C2410_IRQSUB(12) /* S3C2443 too */
+#define IRQ_S3C2440_WDT S3C2410_IRQSUB(13)
+#define IRQ_S3C2440_AC97 S3C2410_IRQSUB(14)
+
+/* irqs for s3c2443 */
+
+#define IRQ_S3C2443_DMA S3C2410_IRQ(17) /* IRQ_DMA1 */
+#define IRQ_S3C2443_UART3 S3C2410_IRQ(18) /* IRQ_DMA2 */
+#define IRQ_S3C2443_CFCON S3C2410_IRQ(19) /* IRQ_DMA3 */
+#define IRQ_S3C2443_HSMMC S3C2410_IRQ(20) /* IRQ_SDI */
+#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */
+
+#define IRQ_S3C2416_HSMMC0 S3C2410_IRQ(21) /* S3C2416/S3C2450 */
+
+#define IRQ_HSMMC0 IRQ_S3C2416_HSMMC0
+#define IRQ_HSMMC1 IRQ_S3C2443_HSMMC
+
+#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
+#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
+#define IRQ_S3C2443_LCD3 S3C2410_IRQSUB(16)
+#define IRQ_S3C2443_LCD4 S3C2410_IRQSUB(17)
+
+#define IRQ_S3C2443_DMA0 S3C2410_IRQSUB(18)
+#define IRQ_S3C2443_DMA1 S3C2410_IRQSUB(19)
+#define IRQ_S3C2443_DMA2 S3C2410_IRQSUB(20)
+#define IRQ_S3C2443_DMA3 S3C2410_IRQSUB(21)
+#define IRQ_S3C2443_DMA4 S3C2410_IRQSUB(22)
+#define IRQ_S3C2443_DMA5 S3C2410_IRQSUB(23)
+
+/* UART3 */
+#define IRQ_S3C2443_RX3 S3C2410_IRQSUB(24)
+#define IRQ_S3C2443_TX3 S3C2410_IRQSUB(25)
+#define IRQ_S3C2443_ERR3 S3C2410_IRQSUB(26)
+
+#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27)
+#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
+
+#if defined(CONFIG_CPU_S3C2443) || defined(CONFIG_CPU_S3C2416)
+#define NR_IRQS (IRQ_S3C2443_AC97+1)
+#else
+#define NR_IRQS (IRQ_S3C2440_AC97+1)
+#endif
+
+/* compatibility define. */
+#define IRQ_UART3 IRQ_S3C2443_UART3
+#define IRQ_S3CUART_RX3 IRQ_S3C2443_RX3
+#define IRQ_S3CUART_TX3 IRQ_S3C2443_TX3
+#define IRQ_S3CUART_ERR3 IRQ_S3C2443_ERR3
+
+#define IRQ_LCD_VSYNC IRQ_S3C2443_LCD3
+#define IRQ_LCD_SYSTEM IRQ_S3C2443_LCD2
+
+#ifdef CONFIG_CPU_S3C2440
+#define IRQ_S3C244x_AC97 IRQ_S3C2440_AC97
+#else
+#define IRQ_S3C244x_AC97 IRQ_S3C2443_AC97
+#endif
+
+/* Our FIQs are routable from IRQ_EINT0 to IRQ_ADCPARENT */
+#define FIQ_START IRQ_EINT0
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/leds-gpio.h b/arch/arm/mach-s3c2410/include/mach/leds-gpio.h
new file mode 100644
index 00000000..d8a76725
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/leds-gpio.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s3c2410/include/mach/leds-gpio.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - LEDs GPIO connector
+ *
+ * This program is free software; you can 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_LEDSGPIO_H
+#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h"
+
+#define S3C24XX_LEDF_ACTLOW (1<<0) /* LED is on when GPIO low */
+#define S3C24XX_LEDF_TRISTATE (1<<1) /* tristate to turn off */
+
+struct s3c24xx_led_platdata {
+ unsigned int gpio;
+ unsigned int flags;
+
+ char *name;
+ char *def_trigger;
+};
+
+#endif /* __ASM_ARCH_LEDSGPIO_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
new file mode 100644
index 00000000..425552d8
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -0,0 +1,124 @@
+/* arch/arm/mach-s3c2410/include/mach/map.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - 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
+
+#include <plat/map-base.h>
+#include <plat/map.h>
+
+#define S3C2410_ADDR(x) S3C_ADDR(x)
+
+/* USB host controller */
+#define S3C2410_PA_USBHOST (0x49000000)
+
+/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
+#define S3C2416_PA_HSUDC (0x49800000)
+#define S3C2416_SZ_HSUDC (SZ_4K)
+
+/* DMA controller */
+#define S3C2410_PA_DMA (0x4B000000)
+#define S3C24XX_SZ_DMA SZ_1M
+
+/* Clock and Power management */
+#define S3C2410_PA_CLKPWR (0x4C000000)
+
+/* LCD controller */
+#define S3C2410_PA_LCD (0x4D000000)
+#define S3C24XX_SZ_LCD SZ_1M
+
+/* NAND flash controller */
+#define S3C2410_PA_NAND (0x4E000000)
+
+/* IIC hardware controller */
+#define S3C2410_PA_IIC (0x54000000)
+
+/* IIS controller */
+#define S3C2410_PA_IIS (0x55000000)
+
+/* RTC */
+#define S3C2410_PA_RTC (0x57000000)
+#define S3C24XX_SZ_RTC SZ_1M
+
+/* ADC */
+#define S3C2410_PA_ADC (0x58000000)
+
+/* SPI */
+#define S3C2410_PA_SPI (0x59000000)
+
+/* SDI */
+#define S3C2410_PA_SDI (0x5A000000)
+
+/* CAMIF */
+#define S3C2440_PA_CAMIF (0x4F000000)
+#define S3C2440_SZ_CAMIF SZ_1M
+
+/* AC97 */
+
+#define S3C2440_PA_AC97 (0x5B000000)
+#define S3C2440_SZ_AC97 SZ_1M
+
+/* S3C2443/S3C2416 High-speed SD/MMC */
+#define S3C2443_PA_HSMMC (0x4A800000)
+#define S3C2416_PA_HSMMC0 (0x4AC00000)
+
+#define S3C2443_PA_FB (0x4C800000)
+
+/* S3C2412 memory and IO controls */
+#define S3C2412_PA_SSMC (0x4F000000)
+#define S3C2412_VA_SSMC S3C_ADDR_CPU(0x00000000)
+
+#define S3C2412_PA_EBI (0x48800000)
+#define S3C2412_VA_EBI S3C_ADDR_CPU(0x00010000)
+
+/* physical addresses of all the chip-select areas */
+
+#define S3C2410_CS0 (0x00000000)
+#define S3C2410_CS1 (0x08000000)
+#define S3C2410_CS2 (0x10000000)
+#define S3C2410_CS3 (0x18000000)
+#define S3C2410_CS4 (0x20000000)
+#define S3C2410_CS5 (0x28000000)
+#define S3C2410_CS6 (0x30000000)
+#define S3C2410_CS7 (0x38000000)
+
+#define S3C2410_SDRAM_PA (S3C2410_CS6)
+
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#define S3C24XX_PA_IRQ S3C2410_PA_IRQ
+#define S3C24XX_PA_MEMCTRL S3C2410_PA_MEMCTRL
+#define S3C24XX_PA_DMA S3C2410_PA_DMA
+#define S3C24XX_PA_CLKPWR S3C2410_PA_CLKPWR
+#define S3C24XX_PA_LCD S3C2410_PA_LCD
+#define S3C24XX_PA_UART S3C2410_PA_UART
+#define S3C24XX_PA_TIMER S3C2410_PA_TIMER
+#define S3C24XX_PA_USBDEV S3C2410_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C2410_PA_WATCHDOG
+#define S3C24XX_PA_IIS S3C2410_PA_IIS
+#define S3C24XX_PA_GPIO S3C2410_PA_GPIO
+#define S3C24XX_PA_RTC S3C2410_PA_RTC
+#define S3C24XX_PA_ADC S3C2410_PA_ADC
+#define S3C24XX_PA_SPI S3C2410_PA_SPI
+#define S3C24XX_PA_SDI S3C2410_PA_SDI
+#define S3C24XX_PA_NAND S3C2410_PA_NAND
+
+#define S3C_PA_FB S3C2443_PA_FB
+#define S3C_PA_IIC S3C2410_PA_IIC
+#define S3C_PA_UART S3C24XX_PA_UART
+#define S3C_PA_USBHOST S3C2410_PA_USBHOST
+#define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0
+#define S3C_PA_HSMMC1 S3C2443_PA_HSMMC
+#define S3C_PA_WDT S3C2410_PA_WATCHDOG
+#define S3C_PA_NAND S3C24XX_PA_NAND
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/memory.h b/arch/arm/mach-s3c2410/include/mach/memory.h
new file mode 100644
index 00000000..f92b97b8
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/memory.h
@@ -0,0 +1,16 @@
+/* arch/arm/mach-s3c2410/include/mach/memory.h
+ * from arch/arm/mach-rpc/include/mach/memory.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can 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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x30000000)
+
+#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h b/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
new file mode 100644
index 00000000..e9e36b0a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/osiris-cpld.h
+ *
+ * Copyright 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - CPLD control constants
+ *
+ * This program is free software; you can 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_OSIRISCPLD_H
+#define __ASM_ARCH_OSIRISCPLD_H
+
+/* CTRL0 - NAND WP control */
+
+#define OSIRIS_CTRL0_NANDSEL (0x3)
+#define OSIRIS_CTRL0_BOOT_INT (1<<3)
+#define OSIRIS_CTRL0_PCMCIA (1<<4)
+#define OSIRIS_CTRL0_FIX8 (1<<5)
+#define OSIRIS_CTRL0_PCMCIA_nWAIT (1<<6)
+#define OSIRIS_CTRL0_PCMCIA_nIOIS16 (1<<7)
+
+#define OSIRIS_CTRL1_FIX8 (1<<0)
+
+#define OSIRIS_ID_REVMASK (0x7)
+
+#endif /* __ASM_ARCH_OSIRISCPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/osiris-map.h b/arch/arm/mach-s3c2410/include/mach/osiris-map.h
new file mode 100644
index 00000000..17380f84
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/osiris-map.h
@@ -0,0 +1,42 @@
+/* arch/arm/mach-s3c2410/include/mach/osiris-map.h
+ *
+ * Copyright 2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * OSIRIS - 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.
+*/
+
+/* needs arch/map.h including with this */
+
+#ifndef __ASM_ARCH_OSIRISMAP_H
+#define __ASM_ARCH_OSIRISMAP_H
+
+/* start peripherals off after the S3C2410 */
+
+#define OSIRIS_IOADDR(x) (S3C2410_ADDR((x) + 0x04000000))
+
+#define OSIRIS_PA_CPLD (S3C2410_CS1 | (1<<26))
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define OSIRIS_VA_CTRL0 OSIRIS_IOADDR(0x00000000)
+#define OSIRIS_PA_CTRL0 (OSIRIS_PA_CPLD)
+
+#define OSIRIS_VA_CTRL1 OSIRIS_IOADDR(0x00100000)
+#define OSIRIS_PA_CTRL1 (OSIRIS_PA_CPLD + (1<<23))
+
+#define OSIRIS_VA_CTRL2 OSIRIS_IOADDR(0x00200000)
+#define OSIRIS_PA_CTRL2 (OSIRIS_PA_CPLD + (2<<23))
+
+#define OSIRIS_VA_CTRL3 OSIRIS_IOADDR(0x00300000)
+#define OSIRIS_PA_CTRL3 (OSIRIS_PA_CPLD + (2<<23))
+
+#define OSIRIS_VA_IDREG OSIRIS_IOADDR(0x00700000)
+#define OSIRIS_PA_IDREG (OSIRIS_PA_CPLD + (7<<23))
+
+#endif /* __ASM_ARCH_OSIRISMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/otom-map.h b/arch/arm/mach-s3c2410/include/mach/otom-map.h
new file mode 100644
index 00000000..f9277a52
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/otom-map.h
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/otom-map.h
+ *
+ * (c) 2005 Guillaume GOURAT / NexVision
+ * guillaume.gourat@nexvision.fr
+ *
+ * NexVision OTOM board 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.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x01300000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space.
+ */
+
+#ifndef __ASM_ARCH_OTOMMAP_H
+#define __ASM_ARCH_OTOMMAP_H
+
+#define OTOM_PA_CS8900A_BASE (S3C2410_CS3 + 0x01000000) /* nGCS3 +0x01000000 */
+#define OTOM_VA_CS8900A_BASE S3C2410_ADDR(0x04000000) /* 0xF4000000 */
+
+/* physical offset addresses for the peripherals */
+
+#define OTOM_PA_FLASH0_BASE (S3C2410_CS0) /* Bank 0 */
+
+#endif /* __ASM_ARCH_OTOMMAP_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/pm-core.h b/arch/arm/mach-s3c2410/include/mach/pm-core.h
new file mode 100644
index 00000000..70a83b20
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/pm-core.h
@@ -0,0 +1,64 @@
+/* linux/arch/arm/mach-s3c2410/include/pm-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ unsigned long tmp = __raw_readl(S3C2410_CLKCON);
+
+ /* re-start uart clocks */
+ tmp |= S3C2410_CLKCON_UART0;
+ tmp |= S3C2410_CLKCON_UART1;
+ tmp |= S3C2410_CLKCON_UART2;
+
+ __raw_writel(tmp, S3C2410_CLKCON);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
+ __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
+
+ /* ack any outstanding external interrupts before we go to sleep */
+
+ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
+ __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
+ __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
+
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
+}
+
+static void s3c_pm_show_resume_irqs(int start, unsigned long which,
+ unsigned long mask);
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ S3C_PMDBG("post sleep: IRQs 0x%08x, 0x%08x\n",
+ __raw_readl(S3C2410_SRCPND),
+ __raw_readl(S3C2410_EINTPEND));
+
+ s3c_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
+ s3c_irqwake_intmask);
+
+ s3c_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
+ s3c_irqwake_eintmask);
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+}
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
new file mode 100644
index 00000000..3415b600
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-clock.h
@@ -0,0 +1,166 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_CLOCK
+#define __ASM_ARM_REGS_CLOCK
+
+#define S3C2410_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s)))
+
+#define S3C2410_LOCKTIME S3C2410_CLKREG(0x00)
+#define S3C2410_MPLLCON S3C2410_CLKREG(0x04)
+#define S3C2410_UPLLCON S3C2410_CLKREG(0x08)
+#define S3C2410_CLKCON S3C2410_CLKREG(0x0C)
+#define S3C2410_CLKSLOW S3C2410_CLKREG(0x10)
+#define S3C2410_CLKDIVN S3C2410_CLKREG(0x14)
+
+#define S3C2410_CLKCON_IDLE (1<<2)
+#define S3C2410_CLKCON_POWER (1<<3)
+#define S3C2410_CLKCON_NAND (1<<4)
+#define S3C2410_CLKCON_LCDC (1<<5)
+#define S3C2410_CLKCON_USBH (1<<6)
+#define S3C2410_CLKCON_USBD (1<<7)
+#define S3C2410_CLKCON_PWMT (1<<8)
+#define S3C2410_CLKCON_SDI (1<<9)
+#define S3C2410_CLKCON_UART0 (1<<10)
+#define S3C2410_CLKCON_UART1 (1<<11)
+#define S3C2410_CLKCON_UART2 (1<<12)
+#define S3C2410_CLKCON_GPIO (1<<13)
+#define S3C2410_CLKCON_RTC (1<<14)
+#define S3C2410_CLKCON_ADC (1<<15)
+#define S3C2410_CLKCON_IIC (1<<16)
+#define S3C2410_CLKCON_IIS (1<<17)
+#define S3C2410_CLKCON_SPI (1<<18)
+
+/* DCLKCON register addresses in gpio.h */
+
+#define S3C2410_DCLKCON_DCLK0EN (1<<0)
+#define S3C2410_DCLKCON_DCLK0_PCLK (0<<1)
+#define S3C2410_DCLKCON_DCLK0_UCLK (1<<1)
+#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
+#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
+#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
+#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
+
+#define S3C2410_DCLKCON_DCLK1EN (1<<16)
+#define S3C2410_DCLKCON_DCLK1_PCLK (0<<17)
+#define S3C2410_DCLKCON_DCLK1_UCLK (1<<17)
+#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
+#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
+#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
+
+#define S3C2410_CLKDIVN_PDIVN (1<<0)
+#define S3C2410_CLKDIVN_HDIVN (1<<1)
+
+#define S3C2410_CLKSLOW_UCLK_OFF (1<<7)
+#define S3C2410_CLKSLOW_MPLL_OFF (1<<5)
+#define S3C2410_CLKSLOW_SLOW (1<<4)
+#define S3C2410_CLKSLOW_SLOWVAL(x) (x)
+#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7)
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+/* extra registers */
+#define S3C2440_CAMDIVN S3C2410_CLKREG(0x18)
+
+#define S3C2440_CLKCON_CAMERA (1<<19)
+#define S3C2440_CLKCON_AC97 (1<<20)
+
+#define S3C2440_CLKDIVN_PDIVN (1<<0)
+#define S3C2440_CLKDIVN_HDIVN_MASK (3<<1)
+#define S3C2440_CLKDIVN_HDIVN_1 (0<<1)
+#define S3C2440_CLKDIVN_HDIVN_2 (1<<1)
+#define S3C2440_CLKDIVN_HDIVN_4_8 (2<<1)
+#define S3C2440_CLKDIVN_HDIVN_3_6 (3<<1)
+#define S3C2440_CLKDIVN_UCLK (1<<3)
+
+#define S3C2440_CAMDIVN_CAMCLK_MASK (0xf<<0)
+#define S3C2440_CAMDIVN_CAMCLK_SEL (1<<4)
+#define S3C2440_CAMDIVN_HCLK3_HALF (1<<8)
+#define S3C2440_CAMDIVN_HCLK4_HALF (1<<9)
+#define S3C2440_CAMDIVN_DVSEN (1<<12)
+
+#define S3C2442_CAMDIVN_CAMCLK_DIV3 (1<<5)
+
+#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
+
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+
+#define S3C2412_OSCSET S3C2410_CLKREG(0x18)
+#define S3C2412_CLKSRC S3C2410_CLKREG(0x1C)
+
+#define S3C2412_PLLCON_OFF (1<<20)
+
+#define S3C2412_CLKDIVN_PDIVN (1<<2)
+#define S3C2412_CLKDIVN_HDIVN_MASK (3<<0)
+#define S3C2412_CLKDIVN_ARMDIVN (1<<3)
+#define S3C2412_CLKDIVN_DVSEN (1<<4)
+#define S3C2412_CLKDIVN_HALFHCLK (1<<5)
+#define S3C2412_CLKDIVN_USB48DIV (1<<6)
+#define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8)
+#define S3C2412_CLKDIVN_UARTDIV_SHIFT (8)
+#define S3C2412_CLKDIVN_I2SDIV_MASK (15<<12)
+#define S3C2412_CLKDIVN_I2SDIV_SHIFT (12)
+#define S3C2412_CLKDIVN_CAMDIV_MASK (15<<16)
+#define S3C2412_CLKDIVN_CAMDIV_SHIFT (16)
+
+#define S3C2412_CLKCON_WDT (1<<28)
+#define S3C2412_CLKCON_SPI (1<<27)
+#define S3C2412_CLKCON_IIS (1<<26)
+#define S3C2412_CLKCON_IIC (1<<25)
+#define S3C2412_CLKCON_ADC (1<<24)
+#define S3C2412_CLKCON_RTC (1<<23)
+#define S3C2412_CLKCON_GPIO (1<<22)
+#define S3C2412_CLKCON_UART2 (1<<21)
+#define S3C2412_CLKCON_UART1 (1<<20)
+#define S3C2412_CLKCON_UART0 (1<<19)
+#define S3C2412_CLKCON_SDI (1<<18)
+#define S3C2412_CLKCON_PWMT (1<<17)
+#define S3C2412_CLKCON_USBD (1<<16)
+#define S3C2412_CLKCON_CAMCLK (1<<15)
+#define S3C2412_CLKCON_UARTCLK (1<<14)
+/* missing 13 */
+#define S3C2412_CLKCON_USB_HOST48 (1<<12)
+#define S3C2412_CLKCON_USB_DEV48 (1<<11)
+#define S3C2412_CLKCON_HCLKdiv2 (1<<10)
+#define S3C2412_CLKCON_HCLKx2 (1<<9)
+#define S3C2412_CLKCON_SDRAM (1<<8)
+/* missing 7 */
+#define S3C2412_CLKCON_USBH S3C2410_CLKCON_USBH
+#define S3C2412_CLKCON_LCDC S3C2410_CLKCON_LCDC
+#define S3C2412_CLKCON_NAND S3C2410_CLKCON_NAND
+#define S3C2412_CLKCON_DMA3 (1<<3)
+#define S3C2412_CLKCON_DMA2 (1<<2)
+#define S3C2412_CLKCON_DMA1 (1<<1)
+#define S3C2412_CLKCON_DMA0 (1<<0)
+
+/* clock sourec controls */
+
+#define S3C2412_CLKSRC_EXTCLKDIV_MASK (7 << 0)
+#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT (0)
+#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV (1<<3)
+#define S3C2412_CLKSRC_MSYSCLK_MPLL (1<<4)
+#define S3C2412_CLKSRC_USYSCLK_UPLL (1<<5)
+#define S3C2412_CLKSRC_UARTCLK_MPLL (1<<8)
+#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9)
+#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10)
+#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11)
+#define S3C2412_CLKSRC_UREFCLK_EXTCLK (1<<12)
+#define S3C2412_CLKSRC_EREFCLK_EXTCLK (1<<14)
+
+#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
+
+#define S3C2416_CLKDIV2 S3C2410_CLKREG(0x28)
+
+#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-dsc.h b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
new file mode 100644
index 00000000..98fd4a05
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-dsc.h
@@ -0,0 +1,220 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-dsc.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440/S3C2412 Signal Drive Strength Control
+*/
+
+
+#ifndef __ASM_ARCH_REGS_DSC_H
+#define __ASM_ARCH_REGS_DSC_H "2440-dsc"
+
+#if defined(CONFIG_CPU_S3C2412)
+#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
+#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
+#endif
+
+#if defined(CONFIG_CPU_S3C2416)
+#define S3C2416_DSC0 S3C2410_GPIOREG(0xc0)
+#define S3C2416_DSC1 S3C2410_GPIOREG(0xc4)
+#define S3C2416_DSC2 S3C2410_GPIOREG(0xc8)
+#define S3C2416_DSC3 S3C2410_GPIOREG(0x110)
+
+#define S3C2416_SELECT_DSC0 (0 << 30)
+#define S3C2416_SELECT_DSC1 (1 << 30)
+#define S3C2416_SELECT_DSC2 (2 << 30)
+#define S3C2416_SELECT_DSC3 (3 << 30)
+
+#define S3C2416_DSC_GETSHIFT(x) (x & 30)
+
+#define S3C2416_DSC0_CF (S3C2416_SELECT_DSC0 | 28)
+#define S3C2416_DSC0_CF_5mA (0 << 28)
+#define S3C2416_DSC0_CF_10mA (1 << 28)
+#define S3C2416_DSC0_CF_15mA (2 << 28)
+#define S3C2416_DSC0_CF_21mA (3 << 28)
+#define S3C2416_DSC0_CF_MASK (3 << 28)
+
+#define S3C2416_DSC0_nRBE (S3C2416_SELECT_DSC0 | 26)
+#define S3C2416_DSC0_nRBE_5mA (0 << 26)
+#define S3C2416_DSC0_nRBE_10mA (1 << 26)
+#define S3C2416_DSC0_nRBE_15mA (2 << 26)
+#define S3C2416_DSC0_nRBE_21mA (3 << 26)
+#define S3C2416_DSC0_nRBE_MASK (3 << 26)
+
+#define S3C2416_DSC0_nROE (S3C2416_SELECT_DSC0 | 24)
+#define S3C2416_DSC0_nROE_5mA (0 << 24)
+#define S3C2416_DSC0_nROE_10mA (1 << 24)
+#define S3C2416_DSC0_nROE_15mA (2 << 24)
+#define S3C2416_DSC0_nROE_21mA (3 << 24)
+#define S3C2416_DSC0_nROE_MASK (3 << 24)
+
+#endif
+
+#if defined(CONFIG_CPU_S3C244X)
+
+#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
+#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
+
+#define S3C2440_SELECT_DSC0 (0)
+#define S3C2440_SELECT_DSC1 (1<<31)
+
+#define S3C2440_DSC_GETSHIFT(x) ((x) & 31)
+
+#define S3C2440_DSC0_DISABLE (1<<31)
+
+#define S3C2440_DSC0_ADDR (S3C2440_SELECT_DSC0 | 8)
+#define S3C2440_DSC0_ADDR_12mA (0<<8)
+#define S3C2440_DSC0_ADDR_10mA (1<<8)
+#define S3C2440_DSC0_ADDR_8mA (2<<8)
+#define S3C2440_DSC0_ADDR_6mA (3<<8)
+#define S3C2440_DSC0_ADDR_MASK (3<<8)
+
+/* D24..D31 */
+#define S3C2440_DSC0_DATA3 (S3C2440_SELECT_DSC0 | 6)
+#define S3C2440_DSC0_DATA3_12mA (0<<6)
+#define S3C2440_DSC0_DATA3_10mA (1<<6)
+#define S3C2440_DSC0_DATA3_8mA (2<<6)
+#define S3C2440_DSC0_DATA3_6mA (3<<6)
+#define S3C2440_DSC0_DATA3_MASK (3<<6)
+
+/* D16..D23 */
+#define S3C2440_DSC0_DATA2 (S3C2440_SELECT_DSC0 | 4)
+#define S3C2440_DSC0_DATA2_12mA (0<<4)
+#define S3C2440_DSC0_DATA2_10mA (1<<4)
+#define S3C2440_DSC0_DATA2_8mA (2<<4)
+#define S3C2440_DSC0_DATA2_6mA (3<<4)
+#define S3C2440_DSC0_DATA2_MASK (3<<4)
+
+/* D8..D15 */
+#define S3C2440_DSC0_DATA1 (S3C2440_SELECT_DSC0 | 2)
+#define S3C2440_DSC0_DATA1_12mA (0<<2)
+#define S3C2440_DSC0_DATA1_10mA (1<<2)
+#define S3C2440_DSC0_DATA1_8mA (2<<2)
+#define S3C2440_DSC0_DATA1_6mA (3<<2)
+#define S3C2440_DSC0_DATA1_MASK (3<<2)
+
+/* D0..D7 */
+#define S3C2440_DSC0_DATA0 (S3C2440_SELECT_DSC0 | 0)
+#define S3C2440_DSC0_DATA0_12mA (0<<0)
+#define S3C2440_DSC0_DATA0_10mA (1<<0)
+#define S3C2440_DSC0_DATA0_8mA (2<<0)
+#define S3C2440_DSC0_DATA0_6mA (3<<0)
+#define S3C2440_DSC0_DATA0_MASK (3<<0)
+
+#define S3C2440_DSC1_SCK1 (S3C2440_SELECT_DSC1 | 28)
+#define S3C2440_DSC1_SCK1_12mA (0<<28)
+#define S3C2440_DSC1_SCK1_10mA (1<<28)
+#define S3C2440_DSC1_SCK1_8mA (2<<28)
+#define S3C2440_DSC1_SCK1_6mA (3<<28)
+#define S3C2440_DSC1_SCK1_MASK (3<<28)
+
+#define S3C2440_DSC1_SCK0 (S3C2440_SELECT_DSC1 | 26)
+#define S3C2440_DSC1_SCK0_12mA (0<<26)
+#define S3C2440_DSC1_SCK0_10mA (1<<26)
+#define S3C2440_DSC1_SCK0_8mA (2<<26)
+#define S3C2440_DSC1_SCK0_6mA (3<<26)
+#define S3C2440_DSC1_SCK0_MASK (3<<26)
+
+#define S3C2440_DSC1_SCKE (S3C2440_SELECT_DSC1 | 24)
+#define S3C2440_DSC1_SCKE_10mA (0<<24)
+#define S3C2440_DSC1_SCKE_8mA (1<<24)
+#define S3C2440_DSC1_SCKE_6mA (2<<24)
+#define S3C2440_DSC1_SCKE_4mA (3<<24)
+#define S3C2440_DSC1_SCKE_MASK (3<<24)
+
+/* SDRAM nRAS/nCAS */
+#define S3C2440_DSC1_SDR (S3C2440_SELECT_DSC1 | 22)
+#define S3C2440_DSC1_SDR_10mA (0<<22)
+#define S3C2440_DSC1_SDR_8mA (1<<22)
+#define S3C2440_DSC1_SDR_6mA (2<<22)
+#define S3C2440_DSC1_SDR_4mA (3<<22)
+#define S3C2440_DSC1_SDR_MASK (3<<22)
+
+/* NAND Flash Controller */
+#define S3C2440_DSC1_NFC (S3C2440_SELECT_DSC1 | 20)
+#define S3C2440_DSC1_NFC_10mA (0<<20)
+#define S3C2440_DSC1_NFC_8mA (1<<20)
+#define S3C2440_DSC1_NFC_6mA (2<<20)
+#define S3C2440_DSC1_NFC_4mA (3<<20)
+#define S3C2440_DSC1_NFC_MASK (3<<20)
+
+/* nBE[0..3] */
+#define S3C2440_DSC1_nBE (S3C2440_SELECT_DSC1 | 18)
+#define S3C2440_DSC1_nBE_10mA (0<<18)
+#define S3C2440_DSC1_nBE_8mA (1<<18)
+#define S3C2440_DSC1_nBE_6mA (2<<18)
+#define S3C2440_DSC1_nBE_4mA (3<<18)
+#define S3C2440_DSC1_nBE_MASK (3<<18)
+
+#define S3C2440_DSC1_WOE (S3C2440_SELECT_DSC1 | 16)
+#define S3C2440_DSC1_WOE_10mA (0<<16)
+#define S3C2440_DSC1_WOE_8mA (1<<16)
+#define S3C2440_DSC1_WOE_6mA (2<<16)
+#define S3C2440_DSC1_WOE_4mA (3<<16)
+#define S3C2440_DSC1_WOE_MASK (3<<16)
+
+#define S3C2440_DSC1_CS7 (S3C2440_SELECT_DSC1 | 14)
+#define S3C2440_DSC1_CS7_10mA (0<<14)
+#define S3C2440_DSC1_CS7_8mA (1<<14)
+#define S3C2440_DSC1_CS7_6mA (2<<14)
+#define S3C2440_DSC1_CS7_4mA (3<<14)
+#define S3C2440_DSC1_CS7_MASK (3<<14)
+
+#define S3C2440_DSC1_CS6 (S3C2440_SELECT_DSC1 | 12)
+#define S3C2440_DSC1_CS6_10mA (0<<12)
+#define S3C2440_DSC1_CS6_8mA (1<<12)
+#define S3C2440_DSC1_CS6_6mA (2<<12)
+#define S3C2440_DSC1_CS6_4mA (3<<12)
+#define S3C2440_DSC1_CS6_MASK (3<<12)
+
+#define S3C2440_DSC1_CS5 (S3C2440_SELECT_DSC1 | 10)
+#define S3C2440_DSC1_CS5_10mA (0<<10)
+#define S3C2440_DSC1_CS5_8mA (1<<10)
+#define S3C2440_DSC1_CS5_6mA (2<<10)
+#define S3C2440_DSC1_CS5_4mA (3<<10)
+#define S3C2440_DSC1_CS5_MASK (3<<10)
+
+#define S3C2440_DSC1_CS4 (S3C2440_SELECT_DSC1 | 8)
+#define S3C2440_DSC1_CS4_10mA (0<<8)
+#define S3C2440_DSC1_CS4_8mA (1<<8)
+#define S3C2440_DSC1_CS4_6mA (2<<8)
+#define S3C2440_DSC1_CS4_4mA (3<<8)
+#define S3C2440_DSC1_CS4_MASK (3<<8)
+
+#define S3C2440_DSC1_CS3 (S3C2440_SELECT_DSC1 | 6)
+#define S3C2440_DSC1_CS3_10mA (0<<6)
+#define S3C2440_DSC1_CS3_8mA (1<<6)
+#define S3C2440_DSC1_CS3_6mA (2<<6)
+#define S3C2440_DSC1_CS3_4mA (3<<6)
+#define S3C2440_DSC1_CS3_MASK (3<<6)
+
+#define S3C2440_DSC1_CS2 (S3C2440_SELECT_DSC1 | 4)
+#define S3C2440_DSC1_CS2_10mA (0<<4)
+#define S3C2440_DSC1_CS2_8mA (1<<4)
+#define S3C2440_DSC1_CS2_6mA (2<<4)
+#define S3C2440_DSC1_CS2_4mA (3<<4)
+#define S3C2440_DSC1_CS2_MASK (3<<4)
+
+#define S3C2440_DSC1_CS1 (S3C2440_SELECT_DSC1 | 2)
+#define S3C2440_DSC1_CS1_10mA (0<<2)
+#define S3C2440_DSC1_CS1_8mA (1<<2)
+#define S3C2440_DSC1_CS1_6mA (2<<2)
+#define S3C2440_DSC1_CS1_4mA (3<<2)
+#define S3C2440_DSC1_CS1_MASK (3<<2)
+
+#define S3C2440_DSC1_CS0 (S3C2440_SELECT_DSC1 | 0)
+#define S3C2440_DSC1_CS0_10mA (0<<0)
+#define S3C2440_DSC1_CS0_8mA (1<<0)
+#define S3C2440_DSC1_CS0_6mA (2<<0)
+#define S3C2440_DSC1_CS0_4mA (3<<0)
+#define S3C2440_DSC1_CS0_MASK (3<<0)
+
+#endif /* CONFIG_CPU_S3C2440 */
+
+#endif /* __ASM_ARCH_REGS_DSC_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpio.h b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
new file mode 100644
index 00000000..a0a89d42
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
@@ -0,0 +1,843 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 GPIO register definitions
+*/
+
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H
+
+#include <mach/gpio-nrs.h>
+
+#ifdef CONFIG_CPU_S3C2400
+#define S3C24XX_MISCCR S3C2400_MISCCR
+#else
+#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
+#endif /* CONFIG_CPU_S3C2400 */
+
+/* general configuration options */
+
+#define S3C2410_GPIO_LEAVE (0xFFFFFFFF)
+#define S3C2410_GPIO_INPUT (0xFFFFFFF0) /* not available on A */
+#define S3C2410_GPIO_OUTPUT (0xFFFFFFF1)
+#define S3C2410_GPIO_IRQ (0xFFFFFFF2) /* not available for all */
+#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* bank A => addr/cs/nand */
+#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
+
+/* register address for the GPIO registers.
+ * S3C24XX_GPIOREG2 is for the second set of registers in the
+ * GPIO which move between s3c2410 and s3c2412 type systems */
+
+#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
+#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2)
+
+
+/* configure GPIO ports A..G */
+
+/* port A - S3C2410: 22bits, zero in bit X makes pin X output
+ * S3C2400: 18bits, zero in bit X makes pin X output
+ * 1 makes port special function, this is default
+*/
+#define S3C2410_GPACON S3C2410_GPIOREG(0x00)
+#define S3C2410_GPADAT S3C2410_GPIOREG(0x04)
+
+#define S3C2400_GPACON S3C2410_GPIOREG(0x00)
+#define S3C2400_GPADAT S3C2410_GPIOREG(0x04)
+
+#define S3C2410_GPA0_ADDR0 (1<<0)
+
+#define S3C2410_GPA1_ADDR16 (1<<1)
+
+#define S3C2410_GPA2_ADDR17 (1<<2)
+
+#define S3C2410_GPA3_ADDR18 (1<<3)
+
+#define S3C2410_GPA4_ADDR19 (1<<4)
+
+#define S3C2410_GPA5_ADDR20 (1<<5)
+
+#define S3C2410_GPA6_ADDR21 (1<<6)
+
+#define S3C2410_GPA7_ADDR22 (1<<7)
+
+#define S3C2410_GPA8_ADDR23 (1<<8)
+
+#define S3C2410_GPA9_ADDR24 (1<<9)
+
+#define S3C2410_GPA10_ADDR25 (1<<10)
+#define S3C2400_GPA10_SCKE (1<<10)
+
+#define S3C2410_GPA11_ADDR26 (1<<11)
+#define S3C2400_GPA11_nCAS0 (1<<11)
+
+#define S3C2410_GPA12_nGCS1 (1<<12)
+#define S3C2400_GPA12_nCAS1 (1<<12)
+
+#define S3C2410_GPA13_nGCS2 (1<<13)
+#define S3C2400_GPA13_nGCS1 (1<<13)
+
+#define S3C2410_GPA14_nGCS3 (1<<14)
+#define S3C2400_GPA14_nGCS2 (1<<14)
+
+#define S3C2410_GPA15_nGCS4 (1<<15)
+#define S3C2400_GPA15_nGCS3 (1<<15)
+
+#define S3C2410_GPA16_nGCS5 (1<<16)
+#define S3C2400_GPA16_nGCS4 (1<<16)
+
+#define S3C2410_GPA17_CLE (1<<17)
+#define S3C2400_GPA17_nGCS5 (1<<17)
+
+#define S3C2410_GPA18_ALE (1<<18)
+
+#define S3C2410_GPA19_nFWE (1<<19)
+
+#define S3C2410_GPA20_nFRE (1<<20)
+
+#define S3C2410_GPA21_nRSTOUT (1<<21)
+
+#define S3C2410_GPA22_nFCE (1<<22)
+
+/* 0x08 and 0x0c are reserved on S3C2410 */
+
+/* S3C2410:
+ * GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
+ * 00 = input, 01 = output, 10=special function, 11=reserved
+
+ * S3C2400:
+ * GPB is 16 IO pins, each configured by 2 bits each in GPBCON.
+ * 00 = input, 01 = output, 10=data, 11=special function
+
+ * bit 0,1 = pin 0, 2,3= pin 1...
+ *
+ * CPBUP = pull up resistor control, 1=disabled, 0=enabled
+*/
+
+#define S3C2410_GPBCON S3C2410_GPIOREG(0x10)
+#define S3C2410_GPBDAT S3C2410_GPIOREG(0x14)
+#define S3C2410_GPBUP S3C2410_GPIOREG(0x18)
+
+#define S3C2400_GPBCON S3C2410_GPIOREG(0x08)
+#define S3C2400_GPBDAT S3C2410_GPIOREG(0x0C)
+#define S3C2400_GPBUP S3C2410_GPIOREG(0x10)
+
+/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
+
+#define S3C2410_GPB0_TOUT0 (0x02 << 0)
+#define S3C2400_GPB0_DATA16 (0x02 << 0)
+
+#define S3C2410_GPB1_TOUT1 (0x02 << 2)
+#define S3C2400_GPB1_DATA17 (0x02 << 2)
+
+#define S3C2410_GPB2_TOUT2 (0x02 << 4)
+#define S3C2400_GPB2_DATA18 (0x02 << 4)
+#define S3C2400_GPB2_TCLK1 (0x03 << 4)
+
+#define S3C2410_GPB3_TOUT3 (0x02 << 6)
+#define S3C2400_GPB3_DATA19 (0x02 << 6)
+#define S3C2400_GPB3_TXD1 (0x03 << 6)
+
+#define S3C2410_GPB4_TCLK0 (0x02 << 8)
+#define S3C2400_GPB4_DATA20 (0x02 << 8)
+#define S3C2410_GPB4_MASK (0x03 << 8)
+#define S3C2400_GPB4_RXD1 (0x03 << 8)
+#define S3C2400_GPB4_MASK (0x03 << 8)
+
+#define S3C2410_GPB5_nXBACK (0x02 << 10)
+#define S3C2443_GPB5_XBACK (0x03 << 10)
+#define S3C2400_GPB5_DATA21 (0x02 << 10)
+#define S3C2400_GPB5_nCTS1 (0x03 << 10)
+
+#define S3C2410_GPB6_nXBREQ (0x02 << 12)
+#define S3C2443_GPB6_XBREQ (0x03 << 12)
+#define S3C2400_GPB6_DATA22 (0x02 << 12)
+#define S3C2400_GPB6_nRTS1 (0x03 << 12)
+
+#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2443_GPB7_XDACK1 (0x03 << 14)
+#define S3C2400_GPB7_DATA23 (0x02 << 14)
+
+#define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
+#define S3C2400_GPB8_DATA24 (0x02 << 16)
+
+#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2443_GPB9_XDACK0 (0x03 << 18)
+#define S3C2400_GPB9_DATA25 (0x02 << 18)
+#define S3C2400_GPB9_I2SSDI (0x03 << 18)
+
+#define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
+#define S3C2400_GPB10_DATA26 (0x02 << 20)
+#define S3C2400_GPB10_nSS (0x03 << 20)
+
+#define S3C2400_GPB11_INP (0x00 << 22)
+#define S3C2400_GPB11_OUTP (0x01 << 22)
+#define S3C2400_GPB11_DATA27 (0x02 << 22)
+
+#define S3C2400_GPB12_INP (0x00 << 24)
+#define S3C2400_GPB12_OUTP (0x01 << 24)
+#define S3C2400_GPB12_DATA28 (0x02 << 24)
+
+#define S3C2400_GPB13_INP (0x00 << 26)
+#define S3C2400_GPB13_OUTP (0x01 << 26)
+#define S3C2400_GPB13_DATA29 (0x02 << 26)
+
+#define S3C2400_GPB14_INP (0x00 << 28)
+#define S3C2400_GPB14_OUTP (0x01 << 28)
+#define S3C2400_GPB14_DATA30 (0x02 << 28)
+
+#define S3C2400_GPB15_INP (0x00 << 30)
+#define S3C2400_GPB15_OUTP (0x01 << 30)
+#define S3C2400_GPB15_DATA31 (0x02 << 30)
+
+#define S3C2410_GPB_PUPDIS(x) (1<<(x))
+
+/* Port C consits of 16 GPIO/Special function
+ *
+ * almost identical setup to port b, but the special functions are mostly
+ * to do with the video system's sync/etc.
+*/
+
+#define S3C2410_GPCCON S3C2410_GPIOREG(0x20)
+#define S3C2410_GPCDAT S3C2410_GPIOREG(0x24)
+#define S3C2410_GPCUP S3C2410_GPIOREG(0x28)
+
+#define S3C2400_GPCCON S3C2410_GPIOREG(0x14)
+#define S3C2400_GPCDAT S3C2410_GPIOREG(0x18)
+#define S3C2400_GPCUP S3C2410_GPIOREG(0x1C)
+
+#define S3C2410_GPC0_LEND (0x02 << 0)
+#define S3C2400_GPC0_VD0 (0x02 << 0)
+
+#define S3C2410_GPC1_VCLK (0x02 << 2)
+#define S3C2400_GPC1_VD1 (0x02 << 2)
+
+#define S3C2410_GPC2_VLINE (0x02 << 4)
+#define S3C2400_GPC2_VD2 (0x02 << 4)
+
+#define S3C2410_GPC3_VFRAME (0x02 << 6)
+#define S3C2400_GPC3_VD3 (0x02 << 6)
+
+#define S3C2410_GPC4_VM (0x02 << 8)
+#define S3C2400_GPC4_VD4 (0x02 << 8)
+
+#define S3C2410_GPC5_LCDVF0 (0x02 << 10)
+#define S3C2400_GPC5_VD5 (0x02 << 10)
+
+#define S3C2410_GPC6_LCDVF1 (0x02 << 12)
+#define S3C2400_GPC6_VD6 (0x02 << 12)
+
+#define S3C2410_GPC7_LCDVF2 (0x02 << 14)
+#define S3C2400_GPC7_VD7 (0x02 << 14)
+
+#define S3C2410_GPC8_VD0 (0x02 << 16)
+#define S3C2400_GPC8_VD8 (0x02 << 16)
+
+#define S3C2410_GPC9_VD1 (0x02 << 18)
+#define S3C2400_GPC9_VD9 (0x02 << 18)
+
+#define S3C2410_GPC10_VD2 (0x02 << 20)
+#define S3C2400_GPC10_VD10 (0x02 << 20)
+
+#define S3C2410_GPC11_VD3 (0x02 << 22)
+#define S3C2400_GPC11_VD11 (0x02 << 22)
+
+#define S3C2410_GPC12_VD4 (0x02 << 24)
+#define S3C2400_GPC12_VD12 (0x02 << 24)
+
+#define S3C2410_GPC13_VD5 (0x02 << 26)
+#define S3C2400_GPC13_VD13 (0x02 << 26)
+
+#define S3C2410_GPC14_VD6 (0x02 << 28)
+#define S3C2400_GPC14_VD14 (0x02 << 28)
+
+#define S3C2410_GPC15_VD7 (0x02 << 30)
+#define S3C2400_GPC15_VD15 (0x02 << 30)
+
+#define S3C2410_GPC_PUPDIS(x) (1<<(x))
+
+/*
+ * S3C2410: Port D consists of 16 GPIO/Special function
+ *
+ * almost identical setup to port b, but the special functions are mostly
+ * to do with the video system's data.
+ *
+ * S3C2400: Port D consists of 11 GPIO/Special function
+ *
+ * almost identical setup to port c
+*/
+
+#define S3C2410_GPDCON S3C2410_GPIOREG(0x30)
+#define S3C2410_GPDDAT S3C2410_GPIOREG(0x34)
+#define S3C2410_GPDUP S3C2410_GPIOREG(0x38)
+
+#define S3C2400_GPDCON S3C2410_GPIOREG(0x20)
+#define S3C2400_GPDDAT S3C2410_GPIOREG(0x24)
+#define S3C2400_GPDUP S3C2410_GPIOREG(0x28)
+
+#define S3C2410_GPD0_VD8 (0x02 << 0)
+#define S3C2400_GPD0_VFRAME (0x02 << 0)
+#define S3C2442_GPD0_nSPICS1 (0x03 << 0)
+
+#define S3C2410_GPD1_VD9 (0x02 << 2)
+#define S3C2400_GPD1_VM (0x02 << 2)
+#define S3C2442_GPD1_SPICLK1 (0x03 << 2)
+
+#define S3C2410_GPD2_VD10 (0x02 << 4)
+#define S3C2400_GPD2_VLINE (0x02 << 4)
+
+#define S3C2410_GPD3_VD11 (0x02 << 6)
+#define S3C2400_GPD3_VCLK (0x02 << 6)
+
+#define S3C2410_GPD4_VD12 (0x02 << 8)
+#define S3C2400_GPD4_LEND (0x02 << 8)
+
+#define S3C2410_GPD5_VD13 (0x02 << 10)
+#define S3C2400_GPD5_TOUT0 (0x02 << 10)
+
+#define S3C2410_GPD6_VD14 (0x02 << 12)
+#define S3C2400_GPD6_TOUT1 (0x02 << 12)
+
+#define S3C2410_GPD7_VD15 (0x02 << 14)
+#define S3C2400_GPD7_TOUT2 (0x02 << 14)
+
+#define S3C2410_GPD8_VD16 (0x02 << 16)
+#define S3C2400_GPD8_TOUT3 (0x02 << 16)
+#define S3C2440_GPD8_SPIMISO1 (0x03 << 16)
+
+#define S3C2410_GPD9_VD17 (0x02 << 18)
+#define S3C2400_GPD9_TCLK0 (0x02 << 18)
+#define S3C2440_GPD9_SPIMOSI1 (0x03 << 18)
+
+#define S3C2410_GPD10_VD18 (0x02 << 20)
+#define S3C2400_GPD10_nWAIT (0x02 << 20)
+#define S3C2440_GPD10_SPICLK1 (0x03 << 20)
+
+#define S3C2410_GPD11_VD19 (0x02 << 22)
+
+#define S3C2410_GPD12_VD20 (0x02 << 24)
+
+#define S3C2410_GPD13_VD21 (0x02 << 26)
+
+#define S3C2410_GPD14_VD22 (0x02 << 28)
+#define S3C2410_GPD14_nSS1 (0x03 << 28)
+
+#define S3C2410_GPD15_VD23 (0x02 << 30)
+#define S3C2410_GPD15_nSS0 (0x03 << 30)
+
+#define S3C2410_GPD_PUPDIS(x) (1<<(x))
+
+/* S3C2410:
+ * Port E consists of 16 GPIO/Special function
+ *
+ * again, the same as port B, but dealing with I2S, SDI, and
+ * more miscellaneous functions
+ *
+ * S3C2400:
+ * Port E consists of 12 GPIO/Special function
+ *
+ * GPIO / interrupt inputs
+*/
+
+#define S3C2410_GPECON S3C2410_GPIOREG(0x40)
+#define S3C2410_GPEDAT S3C2410_GPIOREG(0x44)
+#define S3C2410_GPEUP S3C2410_GPIOREG(0x48)
+
+#define S3C2400_GPECON S3C2410_GPIOREG(0x2C)
+#define S3C2400_GPEDAT S3C2410_GPIOREG(0x30)
+#define S3C2400_GPEUP S3C2410_GPIOREG(0x34)
+
+#define S3C2410_GPE0_I2SLRCK (0x02 << 0)
+#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
+#define S3C2400_GPE0_EINT0 (0x02 << 0)
+#define S3C2410_GPE0_MASK (0x03 << 0)
+
+#define S3C2410_GPE1_I2SSCLK (0x02 << 2)
+#define S3C2443_GPE1_AC_SYNC (0x03 << 2)
+#define S3C2400_GPE1_EINT1 (0x02 << 2)
+#define S3C2400_GPE1_nSS (0x03 << 2)
+#define S3C2410_GPE1_MASK (0x03 << 2)
+
+#define S3C2410_GPE2_CDCLK (0x02 << 4)
+#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
+#define S3C2400_GPE2_EINT2 (0x02 << 4)
+#define S3C2400_GPE2_I2SSDI (0x03 << 4)
+
+#define S3C2410_GPE3_I2SSDI (0x02 << 6)
+#define S3C2443_GPE3_AC_SDI (0x03 << 6)
+#define S3C2400_GPE3_EINT3 (0x02 << 6)
+#define S3C2400_GPE3_nCTS1 (0x03 << 6)
+#define S3C2410_GPE3_nSS0 (0x03 << 6)
+#define S3C2410_GPE3_MASK (0x03 << 6)
+
+#define S3C2410_GPE4_I2SSDO (0x02 << 8)
+#define S3C2443_GPE4_AC_SDO (0x03 << 8)
+#define S3C2400_GPE4_EINT4 (0x02 << 8)
+#define S3C2400_GPE4_nRTS1 (0x03 << 8)
+#define S3C2410_GPE4_I2SSDI (0x03 << 8)
+#define S3C2410_GPE4_MASK (0x03 << 8)
+
+#define S3C2410_GPE5_SDCLK (0x02 << 10)
+#define S3C2443_GPE5_SD1_CLK (0x02 << 10)
+#define S3C2400_GPE5_EINT5 (0x02 << 10)
+#define S3C2400_GPE5_TCLK1 (0x03 << 10)
+#define S3C2443_GPE5_AC_BITCLK (0x03 << 10)
+
+#define S3C2410_GPE6_SDCMD (0x02 << 12)
+#define S3C2443_GPE6_SD1_CMD (0x02 << 12)
+#define S3C2443_GPE6_AC_SDI (0x03 << 12)
+#define S3C2400_GPE6_EINT6 (0x02 << 12)
+
+#define S3C2410_GPE7_SDDAT0 (0x02 << 14)
+#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14)
+#define S3C2443_GPE7_AC_SDO (0x03 << 14)
+#define S3C2400_GPE7_EINT7 (0x02 << 14)
+
+#define S3C2410_GPE8_SDDAT1 (0x02 << 16)
+#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16)
+#define S3C2443_GPE8_AC_SYNC (0x03 << 16)
+#define S3C2400_GPE8_nXDACK0 (0x02 << 16)
+
+#define S3C2410_GPE9_SDDAT2 (0x02 << 18)
+#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18)
+#define S3C2443_GPE9_AC_nRESET (0x03 << 18)
+#define S3C2400_GPE9_nXDACK1 (0x02 << 18)
+#define S3C2400_GPE9_nXBACK (0x03 << 18)
+
+#define S3C2410_GPE10_SDDAT3 (0x02 << 20)
+#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
+#define S3C2400_GPE10_nXDREQ0 (0x02 << 20)
+
+#define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
+#define S3C2400_GPE11_nXDREQ1 (0x02 << 22)
+#define S3C2400_GPE11_nXBREQ (0x03 << 22)
+
+#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24)
+
+#define S3C2410_GPE13_SPICLK0 (0x02 << 26)
+
+#define S3C2410_GPE14_IICSCL (0x02 << 28)
+#define S3C2410_GPE14_MASK (0x03 << 28)
+
+#define S3C2410_GPE15_IICSDA (0x02 << 30)
+#define S3C2410_GPE15_MASK (0x03 << 30)
+
+#define S3C2440_GPE0_ACSYNC (0x03 << 0)
+#define S3C2440_GPE1_ACBITCLK (0x03 << 2)
+#define S3C2440_GPE2_ACRESET (0x03 << 4)
+#define S3C2440_GPE3_ACIN (0x03 << 6)
+#define S3C2440_GPE4_ACOUT (0x03 << 8)
+
+#define S3C2410_GPE_PUPDIS(x) (1<<(x))
+
+/* S3C2410:
+ * Port F consists of 8 GPIO/Special function
+ *
+ * GPIO / interrupt inputs
+ *
+ * GPFCON has 2 bits for each of the input pins on port F
+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined
+ *
+ * pull up works like all other ports.
+ *
+ * S3C2400:
+ * Port F consists of 7 GPIO/Special function
+ *
+ * GPIO/serial/misc pins
+*/
+
+#define S3C2410_GPFCON S3C2410_GPIOREG(0x50)
+#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54)
+#define S3C2410_GPFUP S3C2410_GPIOREG(0x58)
+
+#define S3C2400_GPFCON S3C2410_GPIOREG(0x38)
+#define S3C2400_GPFDAT S3C2410_GPIOREG(0x3C)
+#define S3C2400_GPFUP S3C2410_GPIOREG(0x40)
+
+#define S3C2410_GPF0_EINT0 (0x02 << 0)
+#define S3C2400_GPF0_RXD0 (0x02 << 0)
+
+#define S3C2410_GPF1_EINT1 (0x02 << 2)
+#define S3C2400_GPF1_RXD1 (0x02 << 2)
+#define S3C2400_GPF1_IICSDA (0x03 << 2)
+
+#define S3C2410_GPF2_EINT2 (0x02 << 4)
+#define S3C2400_GPF2_TXD0 (0x02 << 4)
+
+#define S3C2410_GPF3_EINT3 (0x02 << 6)
+#define S3C2400_GPF3_TXD1 (0x02 << 6)
+#define S3C2400_GPF3_IICSCL (0x03 << 6)
+
+#define S3C2410_GPF4_EINT4 (0x02 << 8)
+#define S3C2400_GPF4_nRTS0 (0x02 << 8)
+#define S3C2400_GPF4_nXBACK (0x03 << 8)
+
+#define S3C2410_GPF5_EINT5 (0x02 << 10)
+#define S3C2400_GPF5_nCTS0 (0x02 << 10)
+#define S3C2400_GPF5_nXBREQ (0x03 << 10)
+
+#define S3C2410_GPF6_EINT6 (0x02 << 12)
+#define S3C2400_GPF6_CLKOUT (0x02 << 12)
+
+#define S3C2410_GPF7_EINT7 (0x02 << 14)
+
+#define S3C2410_GPF_PUPDIS(x) (1<<(x))
+
+/* S3C2410:
+ * Port G consists of 8 GPIO/IRQ/Special function
+ *
+ * GPGCON has 2 bits for each of the input pins on port F
+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
+ *
+ * pull up works like all other ports.
+ *
+ * S3C2400:
+ * Port G consists of 10 GPIO/Special function
+*/
+
+#define S3C2410_GPGCON S3C2410_GPIOREG(0x60)
+#define S3C2410_GPGDAT S3C2410_GPIOREG(0x64)
+#define S3C2410_GPGUP S3C2410_GPIOREG(0x68)
+
+#define S3C2400_GPGCON S3C2410_GPIOREG(0x44)
+#define S3C2400_GPGDAT S3C2410_GPIOREG(0x48)
+#define S3C2400_GPGUP S3C2410_GPIOREG(0x4C)
+
+#define S3C2410_GPG0_EINT8 (0x02 << 0)
+#define S3C2400_GPG0_I2SLRCK (0x02 << 0)
+
+#define S3C2410_GPG1_EINT9 (0x02 << 2)
+#define S3C2400_GPG1_I2SSCLK (0x02 << 2)
+
+#define S3C2410_GPG2_EINT10 (0x02 << 4)
+#define S3C2410_GPG2_nSS0 (0x03 << 4)
+#define S3C2400_GPG2_CDCLK (0x02 << 4)
+
+#define S3C2410_GPG3_EINT11 (0x02 << 6)
+#define S3C2410_GPG3_nSS1 (0x03 << 6)
+#define S3C2400_GPG3_I2SSDO (0x02 << 6)
+#define S3C2400_GPG3_I2SSDI (0x03 << 6)
+
+#define S3C2410_GPG4_EINT12 (0x02 << 8)
+#define S3C2400_GPG4_MMCCLK (0x02 << 8)
+#define S3C2400_GPG4_I2SSDI (0x03 << 8)
+#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
+#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
+
+#define S3C2410_GPG5_EINT13 (0x02 << 10)
+#define S3C2400_GPG5_MMCCMD (0x02 << 10)
+#define S3C2400_GPG5_IICSDA (0x03 << 10)
+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */
+
+#define S3C2410_GPG6_EINT14 (0x02 << 12)
+#define S3C2400_GPG6_MMCDAT (0x02 << 12)
+#define S3C2400_GPG6_IICSCL (0x03 << 12)
+#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
+
+#define S3C2410_GPG7_EINT15 (0x02 << 14)
+#define S3C2410_GPG7_SPICLK1 (0x03 << 14)
+#define S3C2400_GPG7_SPIMISO (0x02 << 14)
+#define S3C2400_GPG7_IICSDA (0x03 << 14)
+
+#define S3C2410_GPG8_EINT16 (0x02 << 16)
+#define S3C2400_GPG8_SPIMOSI (0x02 << 16)
+#define S3C2400_GPG8_IICSCL (0x03 << 16)
+
+#define S3C2410_GPG9_EINT17 (0x02 << 18)
+#define S3C2400_GPG9_SPICLK (0x02 << 18)
+#define S3C2400_GPG9_MMCCLK (0x03 << 18)
+
+#define S3C2410_GPG10_EINT18 (0x02 << 20)
+
+#define S3C2410_GPG11_EINT19 (0x02 << 22)
+#define S3C2410_GPG11_TCLK1 (0x03 << 22)
+#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
+
+#define S3C2410_GPG12_EINT20 (0x02 << 24)
+#define S3C2410_GPG12_XMON (0x03 << 24)
+#define S3C2442_GPG12_nSPICS0 (0x03 << 24)
+#define S3C2443_GPG12_nINPACK (0x03 << 24)
+
+#define S3C2410_GPG13_EINT21 (0x02 << 26)
+#define S3C2410_GPG13_nXPON (0x03 << 26)
+#define S3C2443_GPG13_CF_nREG (0x03 << 26)
+
+#define S3C2410_GPG14_EINT22 (0x02 << 28)
+#define S3C2410_GPG14_YMON (0x03 << 28)
+#define S3C2443_GPG14_CF_RESET (0x03 << 28)
+
+#define S3C2410_GPG15_EINT23 (0x02 << 30)
+#define S3C2410_GPG15_nYPON (0x03 << 30)
+#define S3C2443_GPG15_CF_PWR (0x03 << 30)
+
+#define S3C2410_GPG_PUPDIS(x) (1<<(x))
+
+/* Port H consists of11 GPIO/serial/Misc pins
+ *
+ * GPGCON has 2 bits for each of the input pins on port F
+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2410_GPHCON S3C2410_GPIOREG(0x70)
+#define S3C2410_GPHDAT S3C2410_GPIOREG(0x74)
+#define S3C2410_GPHUP S3C2410_GPIOREG(0x78)
+
+#define S3C2410_GPH0_nCTS0 (0x02 << 0)
+#define S3C2416_GPH0_TXD0 (0x02 << 0)
+
+#define S3C2410_GPH1_nRTS0 (0x02 << 2)
+#define S3C2416_GPH1_RXD0 (0x02 << 2)
+
+#define S3C2410_GPH2_TXD0 (0x02 << 4)
+#define S3C2416_GPH2_TXD1 (0x02 << 4)
+
+#define S3C2410_GPH3_RXD0 (0x02 << 6)
+#define S3C2416_GPH3_RXD1 (0x02 << 6)
+
+#define S3C2410_GPH4_TXD1 (0x02 << 8)
+#define S3C2416_GPH4_TXD2 (0x02 << 8)
+
+#define S3C2410_GPH5_RXD1 (0x02 << 10)
+#define S3C2416_GPH5_RXD2 (0x02 << 10)
+
+#define S3C2410_GPH6_TXD2 (0x02 << 12)
+#define S3C2416_GPH6_TXD3 (0x02 << 12)
+#define S3C2410_GPH6_nRTS1 (0x03 << 12)
+#define S3C2416_GPH6_nRTS2 (0x03 << 12)
+
+#define S3C2410_GPH7_RXD2 (0x02 << 14)
+#define S3C2416_GPH7_RXD3 (0x02 << 14)
+#define S3C2410_GPH7_nCTS1 (0x03 << 14)
+#define S3C2416_GPH7_nCTS2 (0x03 << 14)
+
+#define S3C2410_GPH8_UCLK (0x02 << 16)
+#define S3C2416_GPH8_nCTS0 (0x02 << 16)
+
+#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
+#define S3C2442_GPH9_nSPICS0 (0x03 << 18)
+#define S3C2416_GPH9_nRTS0 (0x02 << 18)
+
+#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
+#define S3C2416_GPH10_nCTS1 (0x02 << 20)
+
+#define S3C2416_GPH11_nRTS1 (0x02 << 22)
+
+#define S3C2416_GPH12_EXTUARTCLK (0x02 << 24)
+
+#define S3C2416_GPH13_CLKOUT0 (0x02 << 26)
+
+#define S3C2416_GPH14_CLKOUT1 (0x02 << 28)
+
+/* The S3C2412 and S3C2413 move the GPJ register set to after
+ * GPH, which means all registers after 0x80 are now offset by 0x10
+ * for the 2412/2413 from the 2410/2440/2442
+*/
+
+/* S3C2443 and above */
+#define S3C2440_GPJCON S3C2410_GPIOREG(0xD0)
+#define S3C2440_GPJDAT S3C2410_GPIOREG(0xD4)
+#define S3C2440_GPJUP S3C2410_GPIOREG(0xD8)
+
+#define S3C2443_GPKCON S3C2410_GPIOREG(0xE0)
+#define S3C2443_GPKDAT S3C2410_GPIOREG(0xE4)
+#define S3C2443_GPKUP S3C2410_GPIOREG(0xE8)
+
+#define S3C2443_GPLCON S3C2410_GPIOREG(0xF0)
+#define S3C2443_GPLDAT S3C2410_GPIOREG(0xF4)
+#define S3C2443_GPLUP S3C2410_GPIOREG(0xF8)
+
+#define S3C2443_GPMCON S3C2410_GPIOREG(0x100)
+#define S3C2443_GPMDAT S3C2410_GPIOREG(0x104)
+#define S3C2443_GPMUP S3C2410_GPIOREG(0x108)
+
+/* miscellaneous control */
+#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
+#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
+#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84)
+
+#define S3C24XX_DCLKCON S3C24XX_GPIOREG2(0x84)
+
+/* see clock.h for dclk definitions */
+
+/* pullup control on databus */
+#define S3C2410_MISCCR_SPUCR_HEN (0<<0)
+#define S3C2410_MISCCR_SPUCR_HDIS (1<<0)
+#define S3C2410_MISCCR_SPUCR_LEN (0<<1)
+#define S3C2410_MISCCR_SPUCR_LDIS (1<<1)
+
+#define S3C2400_MISCCR_SPUCR_LEN (0<<0)
+#define S3C2400_MISCCR_SPUCR_LDIS (1<<0)
+#define S3C2400_MISCCR_SPUCR_HEN (0<<1)
+#define S3C2400_MISCCR_SPUCR_HDIS (1<<1)
+
+#define S3C2400_MISCCR_HZ_STOPEN (0<<2)
+#define S3C2400_MISCCR_HZ_STOPPREV (1<<2)
+
+#define S3C2410_MISCCR_USBDEV (0<<3)
+#define S3C2410_MISCCR_USBHOST (1<<3)
+
+#define S3C2410_MISCCR_CLK0_MPLL (0<<4)
+#define S3C2410_MISCCR_CLK0_UPLL (1<<4)
+#define S3C2410_MISCCR_CLK0_FCLK (2<<4)
+#define S3C2410_MISCCR_CLK0_HCLK (3<<4)
+#define S3C2410_MISCCR_CLK0_PCLK (4<<4)
+#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
+#define S3C2410_MISCCR_CLK0_MASK (7<<4)
+
+#define S3C2412_MISCCR_CLK0_RTC (2<<4)
+
+#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
+#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
+#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
+#define S3C2410_MISCCR_CLK1_HCLK (3<<8)
+#define S3C2410_MISCCR_CLK1_PCLK (4<<8)
+#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
+#define S3C2410_MISCCR_CLK1_MASK (7<<8)
+
+#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
+
+#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
+#define S3C2416_MISCCR_SEL_SUSPND (1<<12)
+#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
+
+#define S3C2410_MISCCR_nRSTCON (1<<16)
+
+#define S3C2410_MISCCR_nEN_SCLK0 (1<<17)
+#define S3C2410_MISCCR_nEN_SCLK1 (1<<18)
+#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */
+#define S3C2410_MISCCR_SDSLEEP (7<<17)
+
+#define S3C2416_MISCCR_FLT_I2C (1<<24)
+#define S3C2416_MISCCR_HSSPI_EN2 (1<<31)
+
+/* external interrupt control... */
+/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
+ * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
+ * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
+ *
+ * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23
+ *
+ * Samsung datasheet p9-25
+*/
+#define S3C2400_EXTINT0 S3C2410_GPIOREG(0x58)
+#define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88)
+#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C)
+#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90)
+
+#define S3C24XX_EXTINT0 S3C24XX_GPIOREG2(0x88)
+#define S3C24XX_EXTINT1 S3C24XX_GPIOREG2(0x8C)
+#define S3C24XX_EXTINT2 S3C24XX_GPIOREG2(0x90)
+
+/* interrupt filtering conrrol for EINT16..EINT23 */
+#define S3C2410_EINFLT0 S3C2410_GPIOREG(0x94)
+#define S3C2410_EINFLT1 S3C2410_GPIOREG(0x98)
+#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C)
+#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0)
+
+#define S3C24XX_EINFLT0 S3C24XX_GPIOREG2(0x94)
+#define S3C24XX_EINFLT1 S3C24XX_GPIOREG2(0x98)
+#define S3C24XX_EINFLT2 S3C24XX_GPIOREG2(0x9C)
+#define S3C24XX_EINFLT3 S3C24XX_GPIOREG2(0xA0)
+
+/* values for interrupt filtering */
+#define S3C2410_EINTFLT_PCLK (0x00)
+#define S3C2410_EINTFLT_EXTCLK (1<<7)
+#define S3C2410_EINTFLT_WIDTHMSK(x) ((x) & 0x3f)
+
+/* removed EINTxxxx defs from here, not meant for this */
+
+/* GSTATUS have miscellaneous information in them
+ *
+ * These move between s3c2410 and s3c2412 style systems.
+ */
+
+#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC)
+#define S3C2410_GSTATUS1 S3C2410_GPIOREG(0x0B0)
+#define S3C2410_GSTATUS2 S3C2410_GPIOREG(0x0B4)
+#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8)
+#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC)
+
+#define S3C2412_GSTATUS0 S3C2410_GPIOREG(0x0BC)
+#define S3C2412_GSTATUS1 S3C2410_GPIOREG(0x0C0)
+#define S3C2412_GSTATUS2 S3C2410_GPIOREG(0x0C4)
+#define S3C2412_GSTATUS3 S3C2410_GPIOREG(0x0C8)
+#define S3C2412_GSTATUS4 S3C2410_GPIOREG(0x0CC)
+
+#define S3C24XX_GSTATUS0 S3C24XX_GPIOREG2(0x0AC)
+#define S3C24XX_GSTATUS1 S3C24XX_GPIOREG2(0x0B0)
+#define S3C24XX_GSTATUS2 S3C24XX_GPIOREG2(0x0B4)
+#define S3C24XX_GSTATUS3 S3C24XX_GPIOREG2(0x0B8)
+#define S3C24XX_GSTATUS4 S3C24XX_GPIOREG2(0x0BC)
+
+#define S3C2410_GSTATUS0_nWAIT (1<<3)
+#define S3C2410_GSTATUS0_NCON (1<<2)
+#define S3C2410_GSTATUS0_RnB (1<<1)
+#define S3C2410_GSTATUS0_nBATTFLT (1<<0)
+
+#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
+#define S3C2410_GSTATUS1_2410 (0x32410000)
+#define S3C2410_GSTATUS1_2412 (0x32412001)
+#define S3C2410_GSTATUS1_2416 (0x32416003)
+#define S3C2410_GSTATUS1_2440 (0x32440000)
+#define S3C2410_GSTATUS1_2442 (0x32440aaa)
+/* some 2416 CPUs report this value also */
+#define S3C2410_GSTATUS1_2450 (0x32450003)
+
+#define S3C2410_GSTATUS2_WTRESET (1<<2)
+#define S3C2410_GSTATUS2_OFFRESET (1<<1)
+#define S3C2410_GSTATUS2_PONRESET (1<<0)
+
+/* open drain control register */
+#define S3C2400_OPENCR S3C2410_GPIOREG(0x50)
+
+#define S3C2400_OPENCR_OPC_RXD1DIS (0<<0)
+#define S3C2400_OPENCR_OPC_RXD1EN (1<<0)
+#define S3C2400_OPENCR_OPC_TXD1DIS (0<<1)
+#define S3C2400_OPENCR_OPC_TXD1EN (1<<1)
+#define S3C2400_OPENCR_OPC_CMDDIS (0<<2)
+#define S3C2400_OPENCR_OPC_CMDEN (1<<2)
+#define S3C2400_OPENCR_OPC_DATDIS (0<<3)
+#define S3C2400_OPENCR_OPC_DATEN (1<<3)
+#define S3C2400_OPENCR_OPC_MISODIS (0<<4)
+#define S3C2400_OPENCR_OPC_MISOEN (1<<4)
+#define S3C2400_OPENCR_OPC_MOSIDIS (0<<5)
+#define S3C2400_OPENCR_OPC_MOSIEN (1<<5)
+
+/* 2412/2413 sleep configuration registers */
+
+#define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C)
+#define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C)
+#define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C)
+#define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C)
+#define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C)
+#define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C)
+
+/* definitions for each pin bit */
+#define S3C2412_GPIO_SLPCON_LOW ( 0x00 )
+#define S3C2412_GPIO_SLPCON_HIGH ( 0x01 )
+#define S3C2412_GPIO_SLPCON_IN ( 0x02 )
+#define S3C2412_GPIO_SLPCON_PULL ( 0x03 )
+
+#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2))
+#define S3C2412_SLPCON_HIGH(x) ( 0x01 << ((x) * 2))
+#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2))
+#define S3C2412_SLPCON_PULL(x) ( 0x03 << ((x) * 2))
+#define S3C2412_SLPCON_EINT(x) ( 0x02 << ((x) * 2)) /* only IRQ pins */
+#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
+
+#define S3C2412_SLPCON_ALL_LOW (0x0)
+#define S3C2412_SLPCON_ALL_HIGH (0x11111111 | 0x44444444)
+#define S3C2412_SLPCON_ALL_IN (0x22222222 | 0x88888888)
+#define S3C2412_SLPCON_ALL_PULL (0x33333333)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
new file mode 100644
index 00000000..19575e06
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
@@ -0,0 +1,70 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-gpioj.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440 GPIO J register definitions
+*/
+
+
+#ifndef __ASM_ARCH_REGS_GPIOJ_H
+#define __ASM_ARCH_REGS_GPIOJ_H "gpioj"
+
+/* Port J consists of 13 GPIO/Camera pins
+ *
+ * GPJCON has 2 bits for each of the input pins on port F
+ * 00 = 0 input, 1 output, 2 Camera
+ *
+ * pull up works like all other ports.
+*/
+
+#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
+#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
+#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
+#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
+
+#define S3C2440_GPJ0_OUTP (0x01 << 0)
+#define S3C2440_GPJ0_CAMDATA0 (0x02 << 0)
+
+#define S3C2440_GPJ1_OUTP (0x01 << 2)
+#define S3C2440_GPJ1_CAMDATA1 (0x02 << 2)
+
+#define S3C2440_GPJ2_OUTP (0x01 << 4)
+#define S3C2440_GPJ2_CAMDATA2 (0x02 << 4)
+
+#define S3C2440_GPJ3_OUTP (0x01 << 6)
+#define S3C2440_GPJ3_CAMDATA3 (0x02 << 6)
+
+#define S3C2440_GPJ4_OUTP (0x01 << 8)
+#define S3C2440_GPJ4_CAMDATA4 (0x02 << 8)
+
+#define S3C2440_GPJ5_OUTP (0x01 << 10)
+#define S3C2440_GPJ5_CAMDATA5 (0x02 << 10)
+
+#define S3C2440_GPJ6_OUTP (0x01 << 12)
+#define S3C2440_GPJ6_CAMDATA6 (0x02 << 12)
+
+#define S3C2440_GPJ7_OUTP (0x01 << 14)
+#define S3C2440_GPJ7_CAMDATA7 (0x02 << 14)
+
+#define S3C2440_GPJ8_OUTP (0x01 << 16)
+#define S3C2440_GPJ8_CAMPCLK (0x02 << 16)
+
+#define S3C2440_GPJ9_OUTP (0x01 << 18)
+#define S3C2440_GPJ9_CAMVSYNC (0x02 << 18)
+
+#define S3C2440_GPJ10_OUTP (0x01 << 20)
+#define S3C2440_GPJ10_CAMHREF (0x02 << 20)
+
+#define S3C2440_GPJ11_OUTP (0x01 << 22)
+#define S3C2440_GPJ11_CAMCLKOUT (0x02 << 22)
+
+#define S3C2440_GPJ12_OUTP (0x01 << 24)
+#define S3C2440_GPJ12_CAMRESET (0x02 << 24)
+
+#endif /* __ASM_ARCH_REGS_GPIOJ_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-irq.h b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
new file mode 100644
index 00000000..0f07ba30
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-irq.h
@@ -0,0 +1,53 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can 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_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* interrupt controller */
+
+#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ)
+#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO)
+#define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2)
+
+#define S3C2410_SRCPND S3C2410_IRQREG(0x000)
+#define S3C2410_INTMOD S3C2410_IRQREG(0x004)
+#define S3C2410_INTMSK S3C2410_IRQREG(0x008)
+#define S3C2410_PRIORITY S3C2410_IRQREG(0x00C)
+#define S3C2410_INTPND S3C2410_IRQREG(0x010)
+#define S3C2410_INTOFFSET S3C2410_IRQREG(0x014)
+#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
+#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
+
+#define S3C2416_PRIORITY_MODE1 S3C2410_IRQREG(0x030)
+#define S3C2416_PRIORITY_UPDATE1 S3C2410_IRQREG(0x034)
+#define S3C2416_SRCPND2 S3C2410_IRQREG(0x040)
+#define S3C2416_INTMOD2 S3C2410_IRQREG(0x044)
+#define S3C2416_INTMSK2 S3C2410_IRQREG(0x048)
+#define S3C2416_INTPND2 S3C2410_IRQREG(0x050)
+#define S3C2416_INTOFFSET2 S3C2410_IRQREG(0x054)
+#define S3C2416_PRIORITY_MODE2 S3C2410_IRQREG(0x070)
+#define S3C2416_PRIORITY_UPDATE2 S3C2410_IRQREG(0x074)
+
+/* mask: 0=enable, 1=disable
+ * 1 bit EINT, 4=EINT4, 23=EINT23
+ * EINT0,1,2,3 are not handled here.
+*/
+
+#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4)
+#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8)
+#define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4)
+#define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8)
+
+#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4)
+#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-lcd.h b/arch/arm/mach-s3c2410/include/mach/regs-lcd.h
new file mode 100644
index 00000000..ee8f040a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-lcd.h
@@ -0,0 +1,162 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-lcd.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can 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_LCD_H
+#define ___ASM_ARCH_REGS_LCD_H
+
+#define S3C2410_LCDREG(x) (x)
+
+/* LCD control registers */
+#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00)
+#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04)
+#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08)
+#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C)
+#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10)
+
+#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8)
+#define S3C2410_LCDCON1_MMODE (1<<7)
+#define S3C2410_LCDCON1_DSCAN4 (0<<5)
+#define S3C2410_LCDCON1_STN4 (1<<5)
+#define S3C2410_LCDCON1_STN8 (2<<5)
+#define S3C2410_LCDCON1_TFT (3<<5)
+
+#define S3C2410_LCDCON1_STN1BPP (0<<1)
+#define S3C2410_LCDCON1_STN2GREY (1<<1)
+#define S3C2410_LCDCON1_STN4GREY (2<<1)
+#define S3C2410_LCDCON1_STN8BPP (3<<1)
+#define S3C2410_LCDCON1_STN12BPP (4<<1)
+
+#define S3C2410_LCDCON1_TFT1BPP (8<<1)
+#define S3C2410_LCDCON1_TFT2BPP (9<<1)
+#define S3C2410_LCDCON1_TFT4BPP (10<<1)
+#define S3C2410_LCDCON1_TFT8BPP (11<<1)
+#define S3C2410_LCDCON1_TFT16BPP (12<<1)
+#define S3C2410_LCDCON1_TFT24BPP (13<<1)
+
+#define S3C2410_LCDCON1_ENVID (1)
+
+#define S3C2410_LCDCON1_MODEMASK 0x1E
+
+#define S3C2410_LCDCON2_VBPD(x) ((x) << 24)
+#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14)
+#define S3C2410_LCDCON2_VFPD(x) ((x) << 6)
+#define S3C2410_LCDCON2_VSPW(x) ((x) << 0)
+
+#define S3C2410_LCDCON2_GET_VBPD(x) ( ((x) >> 24) & 0xFF)
+#define S3C2410_LCDCON2_GET_VFPD(x) ( ((x) >> 6) & 0xFF)
+#define S3C2410_LCDCON2_GET_VSPW(x) ( ((x) >> 0) & 0x3F)
+
+#define S3C2410_LCDCON3_HBPD(x) ((x) << 19)
+#define S3C2410_LCDCON3_WDLY(x) ((x) << 19)
+#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8)
+#define S3C2410_LCDCON3_HFPD(x) ((x) << 0)
+#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
+
+#define S3C2410_LCDCON3_GET_HBPD(x) ( ((x) >> 19) & 0x7F)
+#define S3C2410_LCDCON3_GET_HFPD(x) ( ((x) >> 0) & 0xFF)
+
+/* LDCCON4 changes for STN mode on the S3C2412 */
+
+#define S3C2410_LCDCON4_MVAL(x) ((x) << 8)
+#define S3C2410_LCDCON4_HSPW(x) ((x) << 0)
+#define S3C2410_LCDCON4_WLH(x) ((x) << 0)
+
+#define S3C2410_LCDCON4_GET_HSPW(x) ( ((x) >> 0) & 0xFF)
+
+#define S3C2410_LCDCON5_BPP24BL (1<<12)
+#define S3C2410_LCDCON5_FRM565 (1<<11)
+#define S3C2410_LCDCON5_INVVCLK (1<<10)
+#define S3C2410_LCDCON5_INVVLINE (1<<9)
+#define S3C2410_LCDCON5_INVVFRAME (1<<8)
+#define S3C2410_LCDCON5_INVVD (1<<7)
+#define S3C2410_LCDCON5_INVVDEN (1<<6)
+#define S3C2410_LCDCON5_INVPWREN (1<<5)
+#define S3C2410_LCDCON5_INVLEND (1<<4)
+#define S3C2410_LCDCON5_PWREN (1<<3)
+#define S3C2410_LCDCON5_ENLEND (1<<2)
+#define S3C2410_LCDCON5_BSWP (1<<1)
+#define S3C2410_LCDCON5_HWSWP (1<<0)
+
+/* framebuffer start addressed */
+#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14)
+#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18)
+#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C)
+
+#define S3C2410_LCDBANK(x) ((x) << 21)
+#define S3C2410_LCDBASEU(x) (x)
+
+#define S3C2410_OFFSIZE(x) ((x) << 11)
+#define S3C2410_PAGEWIDTH(x) (x)
+
+/* colour lookup and miscellaneous controls */
+
+#define S3C2410_REDLUT S3C2410_LCDREG(0x20)
+#define S3C2410_GREENLUT S3C2410_LCDREG(0x24)
+#define S3C2410_BLUELUT S3C2410_LCDREG(0x28)
+
+#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C)
+#define S3C2410_TPAL S3C2410_LCDREG(0x50)
+
+#define S3C2410_TPAL_EN (1<<24)
+
+/* interrupt info */
+#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54)
+#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58)
+#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C)
+#define S3C2410_LCDINT_FIWSEL (1<<2)
+#define S3C2410_LCDINT_FRSYNC (1<<1)
+#define S3C2410_LCDINT_FICNT (1<<0)
+
+/* s3c2442 extra stn registers */
+
+#define S3C2442_REDLUT S3C2410_LCDREG(0x20)
+#define S3C2442_GREENLUT S3C2410_LCDREG(0x24)
+#define S3C2442_BLUELUT S3C2410_LCDREG(0x28)
+#define S3C2442_DITHMODE S3C2410_LCDREG(0x20)
+
+#define S3C2410_LPCSEL S3C2410_LCDREG(0x60)
+
+#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4))
+
+/* S3C2412 registers */
+
+#define S3C2412_TPAL S3C2410_LCDREG(0x20)
+
+#define S3C2412_LCDINTPND S3C2410_LCDREG(0x24)
+#define S3C2412_LCDSRCPND S3C2410_LCDREG(0x28)
+#define S3C2412_LCDINTMSK S3C2410_LCDREG(0x2C)
+
+#define S3C2412_TCONSEL S3C2410_LCDREG(0x30)
+
+#define S3C2412_LCDCON6 S3C2410_LCDREG(0x34)
+#define S3C2412_LCDCON7 S3C2410_LCDREG(0x38)
+#define S3C2412_LCDCON8 S3C2410_LCDREG(0x3C)
+#define S3C2412_LCDCON9 S3C2410_LCDREG(0x40)
+
+#define S3C2412_REDLUT(x) S3C2410_LCDREG(0x44 + ((x)*4))
+#define S3C2412_GREENLUT(x) S3C2410_LCDREG(0x60 + ((x)*4))
+#define S3C2412_BLUELUT(x) S3C2410_LCDREG(0x98 + ((x)*4))
+
+#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4))
+
+/* general registers */
+
+/* base of the LCD registers, where INTPND, INTSRC and then INTMSK
+ * are available. */
+
+#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54)
+#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24)
+
+#define S3C24XX_LCDINTPND (0x00)
+#define S3C24XX_LCDSRCPND (0x04)
+#define S3C24XX_LCDINTMSK (0x08)
+
+#endif /* ___ASM_ARCH_REGS_LCD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
new file mode 100644
index 00000000..988a6863
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-mem.h
@@ -0,0 +1,230 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-mem.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Memory Control register definitions
+*/
+
+#ifndef __ASM_ARM_MEMREGS_H
+#define __ASM_ARM_MEMREGS_H
+
+#ifndef S3C2410_MEMREG
+#define S3C2410_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+/* bus width, and wait state control */
+#define S3C2410_BWSCON S3C2410_MEMREG(0x0000)
+
+/* bank zero config - note, pinstrapped from OM pins! */
+#define S3C2410_BWSCON_DW0_16 (1<<1)
+#define S3C2410_BWSCON_DW0_32 (2<<1)
+
+/* bank one configs */
+#define S3C2410_BWSCON_DW1_8 (0<<4)
+#define S3C2410_BWSCON_DW1_16 (1<<4)
+#define S3C2410_BWSCON_DW1_32 (2<<4)
+#define S3C2410_BWSCON_WS1 (1<<6)
+#define S3C2410_BWSCON_ST1 (1<<7)
+
+/* bank 2 configurations */
+#define S3C2410_BWSCON_DW2_8 (0<<8)
+#define S3C2410_BWSCON_DW2_16 (1<<8)
+#define S3C2410_BWSCON_DW2_32 (2<<8)
+#define S3C2410_BWSCON_WS2 (1<<10)
+#define S3C2410_BWSCON_ST2 (1<<11)
+
+/* bank 3 configurations */
+#define S3C2410_BWSCON_DW3_8 (0<<12)
+#define S3C2410_BWSCON_DW3_16 (1<<12)
+#define S3C2410_BWSCON_DW3_32 (2<<12)
+#define S3C2410_BWSCON_WS3 (1<<14)
+#define S3C2410_BWSCON_ST3 (1<<15)
+
+/* bank 4 configurations */
+#define S3C2410_BWSCON_DW4_8 (0<<16)
+#define S3C2410_BWSCON_DW4_16 (1<<16)
+#define S3C2410_BWSCON_DW4_32 (2<<16)
+#define S3C2410_BWSCON_WS4 (1<<18)
+#define S3C2410_BWSCON_ST4 (1<<19)
+
+/* bank 5 configurations */
+#define S3C2410_BWSCON_DW5_8 (0<<20)
+#define S3C2410_BWSCON_DW5_16 (1<<20)
+#define S3C2410_BWSCON_DW5_32 (2<<20)
+#define S3C2410_BWSCON_WS5 (1<<22)
+#define S3C2410_BWSCON_ST5 (1<<23)
+
+/* bank 6 configurations */
+#define S3C2410_BWSCON_DW6_8 (0<<24)
+#define S3C2410_BWSCON_DW6_16 (1<<24)
+#define S3C2410_BWSCON_DW6_32 (2<<24)
+#define S3C2410_BWSCON_WS6 (1<<26)
+#define S3C2410_BWSCON_ST6 (1<<27)
+
+/* bank 7 configurations */
+#define S3C2410_BWSCON_DW7_8 (0<<28)
+#define S3C2410_BWSCON_DW7_16 (1<<28)
+#define S3C2410_BWSCON_DW7_32 (2<<28)
+#define S3C2410_BWSCON_WS7 (1<<30)
+#define S3C2410_BWSCON_ST7 (1<<31)
+
+/* accesor functions for getting BANK(n) configuration. (n != 0) */
+
+#define S3C2410_BWSCON_GET(_bwscon, _bank) (((_bwscon) >> ((_bank) * 4)) & 0xf)
+
+#define S3C2410_BWSCON_DW8 (0)
+#define S3C2410_BWSCON_DW16 (1)
+#define S3C2410_BWSCON_DW32 (2)
+#define S3C2410_BWSCON_WS (1 << 2)
+#define S3C2410_BWSCON_ST (1 << 3)
+
+/* memory set (rom, ram) */
+#define S3C2410_BANKCON0 S3C2410_MEMREG(0x0004)
+#define S3C2410_BANKCON1 S3C2410_MEMREG(0x0008)
+#define S3C2410_BANKCON2 S3C2410_MEMREG(0x000C)
+#define S3C2410_BANKCON3 S3C2410_MEMREG(0x0010)
+#define S3C2410_BANKCON4 S3C2410_MEMREG(0x0014)
+#define S3C2410_BANKCON5 S3C2410_MEMREG(0x0018)
+#define S3C2410_BANKCON6 S3C2410_MEMREG(0x001C)
+#define S3C2410_BANKCON7 S3C2410_MEMREG(0x0020)
+
+/* bank configuration registers */
+
+#define S3C2410_BANKCON_PMCnorm (0x00)
+#define S3C2410_BANKCON_PMC4 (0x01)
+#define S3C2410_BANKCON_PMC8 (0x02)
+#define S3C2410_BANKCON_PMC16 (0x03)
+
+/* bank configurations for banks 0..7, note banks
+ * 6 and 7 have different configurations depending on
+ * the memory type bits */
+
+#define S3C2410_BANKCON_Tacp2 (0x0 << 2)
+#define S3C2410_BANKCON_Tacp3 (0x1 << 2)
+#define S3C2410_BANKCON_Tacp4 (0x2 << 2)
+#define S3C2410_BANKCON_Tacp6 (0x3 << 2)
+#define S3C2410_BANKCON_Tacp_SHIFT (2)
+
+#define S3C2410_BANKCON_Tcah0 (0x0 << 4)
+#define S3C2410_BANKCON_Tcah1 (0x1 << 4)
+#define S3C2410_BANKCON_Tcah2 (0x2 << 4)
+#define S3C2410_BANKCON_Tcah4 (0x3 << 4)
+#define S3C2410_BANKCON_Tcah_SHIFT (4)
+
+#define S3C2410_BANKCON_Tcoh0 (0x0 << 6)
+#define S3C2410_BANKCON_Tcoh1 (0x1 << 6)
+#define S3C2410_BANKCON_Tcoh2 (0x2 << 6)
+#define S3C2410_BANKCON_Tcoh4 (0x3 << 6)
+#define S3C2410_BANKCON_Tcoh_SHIFT (6)
+
+#define S3C2410_BANKCON_Tacc1 (0x0 << 8)
+#define S3C2410_BANKCON_Tacc2 (0x1 << 8)
+#define S3C2410_BANKCON_Tacc3 (0x2 << 8)
+#define S3C2410_BANKCON_Tacc4 (0x3 << 8)
+#define S3C2410_BANKCON_Tacc6 (0x4 << 8)
+#define S3C2410_BANKCON_Tacc8 (0x5 << 8)
+#define S3C2410_BANKCON_Tacc10 (0x6 << 8)
+#define S3C2410_BANKCON_Tacc14 (0x7 << 8)
+#define S3C2410_BANKCON_Tacc_SHIFT (8)
+
+#define S3C2410_BANKCON_Tcos0 (0x0 << 11)
+#define S3C2410_BANKCON_Tcos1 (0x1 << 11)
+#define S3C2410_BANKCON_Tcos2 (0x2 << 11)
+#define S3C2410_BANKCON_Tcos4 (0x3 << 11)
+#define S3C2410_BANKCON_Tcos_SHIFT (11)
+
+#define S3C2410_BANKCON_Tacs0 (0x0 << 13)
+#define S3C2410_BANKCON_Tacs1 (0x1 << 13)
+#define S3C2410_BANKCON_Tacs2 (0x2 << 13)
+#define S3C2410_BANKCON_Tacs4 (0x3 << 13)
+#define S3C2410_BANKCON_Tacs_SHIFT (13)
+
+#define S3C2410_BANKCON_SRAM (0x0 << 15)
+#define S3C2400_BANKCON_EDODRAM (0x2 << 15)
+#define S3C2410_BANKCON_SDRAM (0x3 << 15)
+
+/* next bits only for EDO DRAM in 6,7 */
+#define S3C2400_BANKCON_EDO_Trcd1 (0x00 << 4)
+#define S3C2400_BANKCON_EDO_Trcd2 (0x01 << 4)
+#define S3C2400_BANKCON_EDO_Trcd3 (0x02 << 4)
+#define S3C2400_BANKCON_EDO_Trcd4 (0x03 << 4)
+
+/* CAS pulse width */
+#define S3C2400_BANKCON_EDO_PULSE1 (0x00 << 3)
+#define S3C2400_BANKCON_EDO_PULSE2 (0x01 << 3)
+
+/* CAS pre-charge */
+#define S3C2400_BANKCON_EDO_TCP1 (0x00 << 2)
+#define S3C2400_BANKCON_EDO_TCP2 (0x01 << 2)
+
+/* control column address select */
+#define S3C2400_BANKCON_EDO_SCANb8 (0x00 << 0)
+#define S3C2400_BANKCON_EDO_SCANb9 (0x01 << 0)
+#define S3C2400_BANKCON_EDO_SCANb10 (0x02 << 0)
+#define S3C2400_BANKCON_EDO_SCANb11 (0x03 << 0)
+
+/* next bits only for SDRAM in 6,7 */
+#define S3C2410_BANKCON_Trcd2 (0x00 << 2)
+#define S3C2410_BANKCON_Trcd3 (0x01 << 2)
+#define S3C2410_BANKCON_Trcd4 (0x02 << 2)
+
+/* control column address select */
+#define S3C2410_BANKCON_SCANb8 (0x00 << 0)
+#define S3C2410_BANKCON_SCANb9 (0x01 << 0)
+#define S3C2410_BANKCON_SCANb10 (0x02 << 0)
+
+#define S3C2410_REFRESH S3C2410_MEMREG(0x0024)
+#define S3C2410_BANKSIZE S3C2410_MEMREG(0x0028)
+#define S3C2410_MRSRB6 S3C2410_MEMREG(0x002C)
+#define S3C2410_MRSRB7 S3C2410_MEMREG(0x0030)
+
+/* refresh control */
+
+#define S3C2410_REFRESH_REFEN (1<<23)
+#define S3C2410_REFRESH_SELF (1<<22)
+#define S3C2410_REFRESH_REFCOUNTER ((1<<11)-1)
+
+#define S3C2410_REFRESH_TRP_MASK (3<<20)
+#define S3C2410_REFRESH_TRP_2clk (0<<20)
+#define S3C2410_REFRESH_TRP_3clk (1<<20)
+#define S3C2410_REFRESH_TRP_4clk (2<<20)
+
+#define S3C2400_REFRESH_DRAM_TRP_MASK (3<<20)
+#define S3C2400_REFRESH_DRAM_TRP_1_5clk (0<<20)
+#define S3C2400_REFRESH_DRAM_TRP_2_5clk (1<<20)
+#define S3C2400_REFRESH_DRAM_TRP_3_5clk (2<<20)
+#define S3C2400_REFRESH_DRAM_TRP_4_5clk (3<<20)
+
+#define S3C2410_REFRESH_TSRC_MASK (3<<18)
+#define S3C2410_REFRESH_TSRC_4clk (0<<18)
+#define S3C2410_REFRESH_TSRC_5clk (1<<18)
+#define S3C2410_REFRESH_TSRC_6clk (2<<18)
+#define S3C2410_REFRESH_TSRC_7clk (3<<18)
+
+
+/* mode select register(s) */
+
+#define S3C2410_MRSRB_CL1 (0x00 << 4)
+#define S3C2410_MRSRB_CL2 (0x02 << 4)
+#define S3C2410_MRSRB_CL3 (0x03 << 4)
+
+/* bank size register */
+#define S3C2410_BANKSIZE_128M (0x2 << 0)
+#define S3C2410_BANKSIZE_64M (0x1 << 0)
+#define S3C2410_BANKSIZE_32M (0x0 << 0)
+#define S3C2410_BANKSIZE_16M (0x7 << 0)
+#define S3C2410_BANKSIZE_8M (0x6 << 0)
+#define S3C2410_BANKSIZE_4M (0x5 << 0)
+#define S3C2410_BANKSIZE_2M (0x4 << 0)
+#define S3C2410_BANKSIZE_MASK (0x7 << 0)
+#define S3C2400_BANKSIZE_MASK (0x4 << 0)
+#define S3C2410_BANKSIZE_SCLK_EN (1<<4)
+#define S3C2410_BANKSIZE_SCKE_EN (1<<5)
+#define S3C2410_BANKSIZE_BURST (1<<7)
+
+#endif /* __ASM_ARM_MEMREGS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-power.h b/arch/arm/mach-s3c2410/include/mach/regs-power.h
new file mode 100644
index 00000000..4932b87b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-power.h
@@ -0,0 +1,40 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-power.h
+ *
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C24XX power control register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_PWR
+#define __ASM_ARM_REGS_PWR __FILE__
+
+#define S3C24XX_PWRREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2412_PWRMODECON S3C24XX_PWRREG(0x20)
+#define S3C2412_PWRCFG S3C24XX_PWRREG(0x24)
+
+#define S3C2412_INFORM0 S3C24XX_PWRREG(0x70)
+#define S3C2412_INFORM1 S3C24XX_PWRREG(0x74)
+#define S3C2412_INFORM2 S3C24XX_PWRREG(0x78)
+#define S3C2412_INFORM3 S3C24XX_PWRREG(0x7C)
+
+#define S3C2412_PWRCFG_BATF_IRQ (1<<0)
+#define S3C2412_PWRCFG_BATF_IGNORE (2<<0)
+#define S3C2412_PWRCFG_BATF_SLEEP (3<<0)
+#define S3C2412_PWRCFG_BATF_MASK (3<<0)
+
+#define S3C2412_PWRCFG_STANDBYWFI_IGNORE (0<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_IDLE (1<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_STOP (2<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_SLEEP (3<<6)
+#define S3C2412_PWRCFG_STANDBYWFI_MASK (3<<6)
+
+#define S3C2412_PWRCFG_RTC_MASKIRQ (1<<8)
+#define S3C2412_PWRCFG_NAND_NORST (1<<9)
+
+#endif /* __ASM_ARM_REGS_PWR */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
new file mode 100644
index 00000000..fb635251
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
@@ -0,0 +1,48 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412-mem.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2412_MEM
+#define __ASM_ARM_REGS_S3C2412_MEM
+
+#define S3C2412_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#define S3C2412_EBIREG(x) (S3C2412_VA_EBI + (x))
+
+#define S3C2412_SSMCREG(x) (S3C2412_VA_SSMC + (x))
+#define S3C2412_SSMC(x, o) (S3C2412_SSMCREG((x * 0x20) + (o)))
+
+#define S3C2412_BANKCFG S3C2412_MEMREG(0x00)
+#define S3C2412_BANKCON1 S3C2412_MEMREG(0x04)
+#define S3C2412_BANKCON2 S3C2412_MEMREG(0x08)
+#define S3C2412_BANKCON3 S3C2412_MEMREG(0x0C)
+
+#define S3C2412_REFRESH S3C2412_MEMREG(0x10)
+#define S3C2412_TIMEOUT S3C2412_MEMREG(0x14)
+
+/* EBI control registers */
+
+#define S3C2412_EBI_PR S3C2412_EBIREG(0x00)
+#define S3C2412_EBI_BANKCFG S3C2412_EBIREG(0x04)
+
+/* SSMC control registers */
+
+#define S3C2412_SSMC_BANK(x) S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMIDCYR(x) S3C2412_SSMC(x, 0x00)
+#define S3C2412_SMBWSTRD(x) S3C2412_SSMC(x, 0x04)
+#define S3C2412_SMBWSTWRR(x) S3C2412_SSMC(x, 0x08)
+#define S3C2412_SMBWSTOENR(x) S3C2412_SSMC(x, 0x0C)
+#define S3C2412_SMBWSTWENR(x) S3C2412_SSMC(x, 0x10)
+#define S3C2412_SMBCR(x) S3C2412_SSMC(x, 0x14)
+#define S3C2412_SMBSR(x) S3C2412_SSMC(x, 0x18)
+#define S3C2412_SMBWSTBRDR(x) S3C2412_SSMC(x, 0x1C)
+
+#endif /* __ASM_ARM_REGS_S3C2412_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
new file mode 100644
index 00000000..aa69dc79
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
@@ -0,0 +1,23 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2412.h
+ *
+ * Copyright 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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.
+ *
+ * S3C2412 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_H
+#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
+
+#define S3C2412_SWRST (S3C24XX_VA_CLKPWR + 0x30)
+#define S3C2412_SWRST_RESET (0x533C2412)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2412_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
new file mode 100644
index 00000000..2f31b749
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
@@ -0,0 +1,30 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416-mem.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 memory register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2416_MEM
+#define __ASM_ARM_REGS_S3C2416_MEM
+
+#ifndef S3C2416_MEMREG
+#define S3C2416_MEMREG(x) (S3C24XX_VA_MEMCTRL + (x))
+#endif
+
+#define S3C2416_BANKCFG S3C2416_MEMREG(0x00)
+#define S3C2416_BANKCON1 S3C2416_MEMREG(0x04)
+#define S3C2416_BANKCON2 S3C2416_MEMREG(0x08)
+#define S3C2416_BANKCON3 S3C2416_MEMREG(0x0C)
+
+#define S3C2416_REFRESH S3C2416_MEMREG(0x10)
+#define S3C2416_TIMEOUT S3C2416_MEMREG(0x14)
+
+#endif /* __ASM_ARM_REGS_S3C2416_MEM */
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
new file mode 100644
index 00000000..e443167e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2416.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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.
+ *
+ * S3C2416 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2416_H
+#define __ASM_ARCH_REGS_S3C2416_H "s3c2416"
+
+#define S3C2416_SWRST (S3C24XX_VA_CLKPWR + 0x44)
+#define S3C2416_SWRST_RESET (0x533C2416)
+
+/* see regs-power.h for the other registers in the power block. */
+
+#endif /* __ASM_ARCH_REGS_S3C2416_H */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
new file mode 100644
index 00000000..5e06c726
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
@@ -0,0 +1,192 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2443 clock register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
+#define __ASM_ARM_REGS_S3C2443_CLOCK
+
+#define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
+
+#define S3C2443_PLLCON_MDIVSHIFT 16
+#define S3C2443_PLLCON_PDIVSHIFT 8
+#define S3C2443_PLLCON_SDIVSHIFT 0
+#define S3C2443_PLLCON_MDIVMASK ((1<<(1+(23-16)))-1)
+#define S3C2443_PLLCON_PDIVMASK ((1<<(1+(9-8)))-1)
+#define S3C2443_PLLCON_SDIVMASK (3)
+
+#define S3C2443_MPLLCON S3C2443_CLKREG(0x10)
+#define S3C2443_EPLLCON S3C2443_CLKREG(0x18)
+#define S3C2443_CLKSRC S3C2443_CLKREG(0x20)
+#define S3C2443_CLKDIV0 S3C2443_CLKREG(0x24)
+#define S3C2443_CLKDIV1 S3C2443_CLKREG(0x28)
+#define S3C2443_HCLKCON S3C2443_CLKREG(0x30)
+#define S3C2443_PCLKCON S3C2443_CLKREG(0x34)
+#define S3C2443_SCLKCON S3C2443_CLKREG(0x38)
+#define S3C2443_PWRMODE S3C2443_CLKREG(0x40)
+#define S3C2443_SWRST S3C2443_CLKREG(0x44)
+#define S3C2443_BUSPRI0 S3C2443_CLKREG(0x50)
+#define S3C2443_SYSID S3C2443_CLKREG(0x5C)
+#define S3C2443_PWRCFG S3C2443_CLKREG(0x60)
+#define S3C2443_RSTCON S3C2443_CLKREG(0x64)
+#define S3C2443_PHYCTRL S3C2443_CLKREG(0x80)
+#define S3C2443_PHYPWR S3C2443_CLKREG(0x84)
+#define S3C2443_URSTCON S3C2443_CLKREG(0x88)
+#define S3C2443_UCLKCON S3C2443_CLKREG(0x8C)
+
+#define S3C2443_SWRST_RESET (0x533c2443)
+
+#define S3C2443_PLLCON_OFF (1<<24)
+
+#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<7)
+#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<7)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<7)
+#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<7)
+#define S3C2443_CLKSRC_EPLLREF_MASK (3<<7)
+
+#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3)
+
+#define S3C2443_CLKDIV0_HALF_HCLK (1<<3)
+#define S3C2443_CLKDIV0_HALF_PCLK (1<<2)
+
+#define S3C2443_CLKDIV0_HCLKDIV_MASK (3<<0)
+
+#define S3C2443_CLKDIV0_EXTDIV_MASK (3<<6)
+#define S3C2443_CLKDIV0_EXTDIV_SHIFT (6)
+
+#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4)
+#define S3C2443_CLKDIV0_PREDIV_SHIFT (4)
+
+#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9)
+#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9)
+#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9)
+#define S3C2443_CLKDIV0_ARMDIV_2 (8<<9)
+#define S3C2443_CLKDIV0_ARMDIV_3 (2<<9)
+#define S3C2443_CLKDIV0_ARMDIV_4 (9<<9)
+#define S3C2443_CLKDIV0_ARMDIV_6 (10<<9)
+#define S3C2443_CLKDIV0_ARMDIV_8 (11<<9)
+#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9)
+#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9)
+
+/* S3C2443_CLKDIV1 removed, only used in clock.c code */
+
+#define S3C2443_CLKCON_NAND
+
+#define S3C2443_HCLKCON_DMA0 (1<<0)
+#define S3C2443_HCLKCON_DMA1 (1<<1)
+#define S3C2443_HCLKCON_DMA2 (1<<2)
+#define S3C2443_HCLKCON_DMA3 (1<<3)
+#define S3C2443_HCLKCON_DMA4 (1<<4)
+#define S3C2443_HCLKCON_DMA5 (1<<5)
+#define S3C2443_HCLKCON_CAMIF (1<<8)
+#define S3C2443_HCLKCON_LCDC (1<<9)
+#define S3C2443_HCLKCON_USBH (1<<11)
+#define S3C2443_HCLKCON_USBD (1<<12)
+#define S3C2416_HCLKCON_HSMMC0 (1<<15)
+#define S3C2443_HCLKCON_HSMMC (1<<16)
+#define S3C2443_HCLKCON_CFC (1<<17)
+#define S3C2443_HCLKCON_SSMC (1<<18)
+#define S3C2443_HCLKCON_DRAMC (1<<19)
+
+#define S3C2443_PCLKCON_UART0 (1<<0)
+#define S3C2443_PCLKCON_UART1 (1<<1)
+#define S3C2443_PCLKCON_UART2 (1<<2)
+#define S3C2443_PCLKCON_UART3 (1<<3)
+#define S3C2443_PCLKCON_IIC (1<<4)
+#define S3C2443_PCLKCON_SDI (1<<5)
+#define S3C2443_PCLKCON_ADC (1<<7)
+#define S3C2443_PCLKCON_AC97 (1<<8)
+#define S3C2443_PCLKCON_IIS (1<<9)
+#define S3C2443_PCLKCON_PWMT (1<<10)
+#define S3C2443_PCLKCON_WDT (1<<11)
+#define S3C2443_PCLKCON_RTC (1<<12)
+#define S3C2443_PCLKCON_GPIO (1<<13)
+#define S3C2443_PCLKCON_SPI0 (1<<14)
+#define S3C2443_PCLKCON_SPI1 (1<<15)
+
+#define S3C2443_SCLKCON_DDRCLK (1<<16)
+#define S3C2443_SCLKCON_SSMCCLK (1<<15)
+#define S3C2443_SCLKCON_HSSPICLK (1<<14)
+#define S3C2443_SCLKCON_HSMMCCLK_EXT (1<<13)
+#define S3C2443_SCLKCON_HSMMCCLK_EPLL (1<<12)
+#define S3C2443_SCLKCON_CAMCLK (1<<11)
+#define S3C2443_SCLKCON_DISPCLK (1<<10)
+#define S3C2443_SCLKCON_I2SCLK (1<<9)
+#define S3C2443_SCLKCON_UARTCLK (1<<8)
+#define S3C2443_SCLKCON_USBHOST (1<<1)
+
+#define S3C2443_PWRCFG_SLEEP (1<<15)
+
+#define S3C2443_PWRCFG_USBPHY (1 << 4)
+
+#define S3C2443_URSTCON_FUNCRST (1 << 2)
+#define S3C2443_URSTCON_PHYRST (1 << 0)
+
+#define S3C2443_PHYCTRL_CLKSEL (1 << 3)
+#define S3C2443_PHYCTRL_EXTCLK (1 << 2)
+#define S3C2443_PHYCTRL_PLLSEL (1 << 1)
+#define S3C2443_PHYCTRL_DSPORT (1 << 0)
+
+#define S3C2443_PHYPWR_COMMON_ON (1 << 31)
+#define S3C2443_PHYPWR_ANALOG_PD (1 << 4)
+#define S3C2443_PHYPWR_PLL_REFCLK (1 << 3)
+#define S3C2443_PHYPWR_XO_ON (1 << 2)
+#define S3C2443_PHYPWR_PLL_PWRDN (1 << 1)
+#define S3C2443_PHYPWR_FSUSPEND (1 << 0)
+
+#define S3C2443_UCLKCON_DETECT_VBUS (1 << 31)
+#define S3C2443_UCLKCON_FUNC_CLKEN (1 << 2)
+#define S3C2443_UCLKCON_TCLKEN (1 << 0)
+
+#include <asm/div64.h>
+
+static inline unsigned int
+s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
+{
+ unsigned int mdiv, pdiv, sdiv;
+ uint64_t fvco;
+
+ mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+ pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+ sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+ mdiv &= S3C2443_PLLCON_MDIVMASK;
+ pdiv &= S3C2443_PLLCON_PDIVMASK;
+ sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+ fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
+ do_div(fvco, pdiv << sdiv);
+
+ return (unsigned int)fvco;
+}
+
+static inline unsigned int
+s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
+{
+ unsigned int mdiv, pdiv, sdiv;
+ uint64_t fvco;
+
+ mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
+ pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
+ sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
+
+ mdiv &= S3C2443_PLLCON_MDIVMASK;
+ pdiv &= S3C2443_PLLCON_PDIVMASK;
+ sdiv &= S3C2443_PLLCON_SDIVMASK;
+
+ fvco = (uint64_t)baseclk * (mdiv + 8);
+ do_div(fvco, (pdiv + 2) << sdiv);
+
+ return (unsigned int)fvco;
+}
+
+#endif /* __ASM_ARM_REGS_S3C2443_CLOCK */
+
diff --git a/arch/arm/mach-s3c2410/include/mach/regs-sdi.h b/arch/arm/mach-s3c2410/include/mach/regs-sdi.h
new file mode 100644
index 00000000..cbf2d888
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/regs-sdi.h
@@ -0,0 +1,127 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 MMC/SDIO register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_SDI
+#define __ASM_ARM_REGS_SDI "regs-sdi.h"
+
+#define S3C2410_SDICON (0x00)
+#define S3C2410_SDIPRE (0x04)
+#define S3C2410_SDICMDARG (0x08)
+#define S3C2410_SDICMDCON (0x0C)
+#define S3C2410_SDICMDSTAT (0x10)
+#define S3C2410_SDIRSP0 (0x14)
+#define S3C2410_SDIRSP1 (0x18)
+#define S3C2410_SDIRSP2 (0x1C)
+#define S3C2410_SDIRSP3 (0x20)
+#define S3C2410_SDITIMER (0x24)
+#define S3C2410_SDIBSIZE (0x28)
+#define S3C2410_SDIDCON (0x2C)
+#define S3C2410_SDIDCNT (0x30)
+#define S3C2410_SDIDSTA (0x34)
+#define S3C2410_SDIFSTA (0x38)
+
+#define S3C2410_SDIDATA (0x3C)
+#define S3C2410_SDIIMSK (0x40)
+
+#define S3C2440_SDIDATA (0x40)
+#define S3C2440_SDIIMSK (0x3C)
+
+#define S3C2440_SDICON_SDRESET (1<<8)
+#define S3C2440_SDICON_MMCCLOCK (1<<5)
+#define S3C2410_SDICON_BYTEORDER (1<<4)
+#define S3C2410_SDICON_SDIOIRQ (1<<3)
+#define S3C2410_SDICON_RWAITEN (1<<2)
+#define S3C2410_SDICON_FIFORESET (1<<1)
+#define S3C2410_SDICON_CLOCKTYPE (1<<0)
+
+#define S3C2410_SDICMDCON_ABORT (1<<12)
+#define S3C2410_SDICMDCON_WITHDATA (1<<11)
+#define S3C2410_SDICMDCON_LONGRSP (1<<10)
+#define S3C2410_SDICMDCON_WAITRSP (1<<9)
+#define S3C2410_SDICMDCON_CMDSTART (1<<8)
+#define S3C2410_SDICMDCON_SENDERHOST (1<<6)
+#define S3C2410_SDICMDCON_INDEX (0x3f)
+
+#define S3C2410_SDICMDSTAT_CRCFAIL (1<<12)
+#define S3C2410_SDICMDSTAT_CMDSENT (1<<11)
+#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
+#define S3C2410_SDICMDSTAT_RSPFIN (1<<9)
+#define S3C2410_SDICMDSTAT_XFERING (1<<8)
+#define S3C2410_SDICMDSTAT_INDEX (0xff)
+
+#define S3C2440_SDIDCON_DS_BYTE (0<<22)
+#define S3C2440_SDIDCON_DS_HALFWORD (1<<22)
+#define S3C2440_SDIDCON_DS_WORD (2<<22)
+#define S3C2410_SDIDCON_IRQPERIOD (1<<21)
+#define S3C2410_SDIDCON_TXAFTERRESP (1<<20)
+#define S3C2410_SDIDCON_RXAFTERCMD (1<<19)
+#define S3C2410_SDIDCON_BUSYAFTERCMD (1<<18)
+#define S3C2410_SDIDCON_BLOCKMODE (1<<17)
+#define S3C2410_SDIDCON_WIDEBUS (1<<16)
+#define S3C2410_SDIDCON_DMAEN (1<<15)
+#define S3C2410_SDIDCON_STOP (1<<14)
+#define S3C2440_SDIDCON_DATSTART (1<<14)
+#define S3C2410_SDIDCON_DATMODE (3<<12)
+#define S3C2410_SDIDCON_BLKNUM (0x7ff)
+
+/* constants for S3C2410_SDIDCON_DATMODE */
+#define S3C2410_SDIDCON_XFER_READY (0<<12)
+#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
+#define S3C2410_SDIDCON_XFER_RXSTART (2<<12)
+#define S3C2410_SDIDCON_XFER_TXSTART (3<<12)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF)
+#define S3C2410_SDIDCNT_BLKNUM_SHIFT (12)
+
+#define S3C2410_SDIDSTA_RDYWAITREQ (1<<10)
+#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
+#define S3C2410_SDIDSTA_FIFOFAIL (1<<8) /* reserved on 2440 */
+#define S3C2410_SDIDSTA_CRCFAIL (1<<7)
+#define S3C2410_SDIDSTA_RXCRCFAIL (1<<6)
+#define S3C2410_SDIDSTA_DATATIMEOUT (1<<5)
+#define S3C2410_SDIDSTA_XFERFINISH (1<<4)
+#define S3C2410_SDIDSTA_BUSYFINISH (1<<3)
+#define S3C2410_SDIDSTA_SBITERR (1<<2) /* reserved on 2410a/2440 */
+#define S3C2410_SDIDSTA_TXDATAON (1<<1)
+#define S3C2410_SDIDSTA_RXDATAON (1<<0)
+
+#define S3C2440_SDIFSTA_FIFORESET (1<<16)
+#define S3C2440_SDIFSTA_FIFOFAIL (3<<14) /* 3 is correct (2 bits) */
+#define S3C2410_SDIFSTA_TFDET (1<<13)
+#define S3C2410_SDIFSTA_RFDET (1<<12)
+#define S3C2410_SDIFSTA_TFHALF (1<<11)
+#define S3C2410_SDIFSTA_TFEMPTY (1<<10)
+#define S3C2410_SDIFSTA_RFLAST (1<<9)
+#define S3C2410_SDIFSTA_RFFULL (1<<8)
+#define S3C2410_SDIFSTA_RFHALF (1<<7)
+#define S3C2410_SDIFSTA_COUNTMASK (0x7f)
+
+#define S3C2410_SDIIMSK_RESPONSECRC (1<<17)
+#define S3C2410_SDIIMSK_CMDSENT (1<<16)
+#define S3C2410_SDIIMSK_CMDTIMEOUT (1<<15)
+#define S3C2410_SDIIMSK_RESPONSEND (1<<14)
+#define S3C2410_SDIIMSK_READWAIT (1<<13)
+#define S3C2410_SDIIMSK_SDIOIRQ (1<<12)
+#define S3C2410_SDIIMSK_FIFOFAIL (1<<11)
+#define S3C2410_SDIIMSK_CRCSTATUS (1<<10)
+#define S3C2410_SDIIMSK_DATACRC (1<<9)
+#define S3C2410_SDIIMSK_DATATIMEOUT (1<<8)
+#define S3C2410_SDIIMSK_DATAFINISH (1<<7)
+#define S3C2410_SDIIMSK_BUSYFINISH (1<<6)
+#define S3C2410_SDIIMSK_SBITERR (1<<5) /* reserved 2440/2410a */
+#define S3C2410_SDIIMSK_TXFIFOHALF (1<<4)
+#define S3C2410_SDIIMSK_TXFIFOEMPTY (1<<3)
+#define S3C2410_SDIIMSK_RXFIFOLAST (1<<2)
+#define S3C2410_SDIIMSK_RXFIFOFULL (1<<1)
+#define S3C2410_SDIIMSK_RXFIFOHALF (1<<0)
+
+#endif /* __ASM_ARM_REGS_SDI */
diff --git a/arch/arm/mach-s3c2410/include/mach/reset.h b/arch/arm/mach-s3c2410/include/mach/reset.h
new file mode 100644
index 00000000..f8c9387b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/reset.h
@@ -0,0 +1,22 @@
+/* arch/arm/mach-s3c2410/include/mach/reset.h
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 CPU reset controls
+*/
+
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H __FILE__
+
+/* This allows the over-ride of the default reset code
+*/
+
+extern void (*s3c24xx_reset_hook)(void);
+
+#endif /* __ASM_ARCH_RESET_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/spi-gpio.h b/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
new file mode 100644
index 00000000..dcef2287
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/spi-gpio.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s3c2410/include/mach/spi-gpio.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - SPI Controller platform_device info
+ *
+ * This program is free software; you can 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_SPIGPIO_H
+#define __ASM_ARCH_SPIGPIO_H __FILE__
+
+struct s3c2410_spigpio_info {
+ unsigned long pin_clk;
+ unsigned long pin_mosi;
+ unsigned long pin_miso;
+
+ int num_chipselect;
+ int bus_num;
+
+ void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs);
+};
+
+
+#endif /* __ASM_ARCH_SPIGPIO_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h
new file mode 100644
index 00000000..4d958837
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/spi.h
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s3c2410/include/mach/spi.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - SPI Controller platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPI_H
+#define __ASM_ARCH_SPI_H __FILE__
+
+struct s3c2410_spi_info {
+ int pin_cs; /* simple gpio cs */
+ unsigned int num_cs; /* total chipselects */
+ int bus_num; /* bus number to use. */
+
+ unsigned int use_fiq:1; /* use fiq */
+
+ void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
+ void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
+};
+
+/* Standard setup / suspend routines for SPI GPIO pins. */
+
+extern void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
+ int enable);
+
+extern void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
+ int enable);
+
+extern void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
+ int enable);
+
+#endif /* __ASM_ARCH_SPI_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/system-reset.h b/arch/arm/mach-s3c2410/include/mach/system-reset.h
new file mode 100644
index 00000000..6faadcee
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/system-reset.h
@@ -0,0 +1,32 @@
+/* arch/arm/mach-s3c2410/include/mach/system-reset.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - System define for arch_reset() 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.
+*/
+
+#include <mach/hardware.h>
+#include <plat/watchdog-reset.h>
+
+extern void (*s3c24xx_reset_hook)(void);
+
+static void
+arch_reset(char mode, const char *cmd)
+{
+ if (mode == 's') {
+ cpu_reset(0);
+ }
+
+ if (s3c24xx_reset_hook)
+ s3c24xx_reset_hook();
+
+ arch_wdt_reset();
+
+ /* we'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h
new file mode 100644
index 00000000..a8cbca67
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/system.h
@@ -0,0 +1,58 @@
+/* arch/arm/mach-s3c2410/include/mach/system.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - System function defines and includes
+ *
+ * This program is free software; you can 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/hardware.h>
+
+#include <mach/map.h>
+#include <mach/idle.h>
+#include <mach/reset.h>
+
+#include <mach/regs-clock.h>
+
+void (*s3c24xx_idle)(void);
+void (*s3c24xx_reset_hook)(void);
+
+void s3c24xx_default_idle(void)
+{
+ unsigned long tmp;
+ int i;
+
+ /* idle the system by using the idle mode which will wait for an
+ * interrupt to happen before restarting the system.
+ */
+
+ /* Warning: going into idle state upsets jtag scanning */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+
+ /* the samsung port seems to do a loop and then unset idle.. */
+ for (i = 0; i < 50; i++) {
+ tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
+ }
+
+ /* this bit is not cleared on re-start... */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+}
+
+static void arch_idle(void)
+{
+ if (s3c24xx_idle != NULL)
+ (s3c24xx_idle)();
+ else
+ s3c24xx_default_idle();
+}
+
+#include <mach/system-reset.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/tick.h b/arch/arm/mach-s3c2410/include/mach/tick.h
new file mode 100644
index 00000000..544da419
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/tick.h
@@ -0,0 +1,15 @@
+/* linux/arch/arm/mach-s3c2410/include/mach/tick.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C2410 - timer tick support
+ */
+
+#define SRCPND_TIMER4 (1<<(IRQ_TIMER4 - IRQ_EINT0))
+
+static inline int s3c24xx_ostimer_pending(void)
+{
+ return __raw_readl(S3C2410_SRCPND) & SRCPND_TIMER4;
+}
diff --git a/arch/arm/mach-s3c2410/include/mach/timex.h b/arch/arm/mach-s3c2410/include/mach/timex.h
new file mode 100644
index 00000000..fe9ca1ff
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
new file mode 100644
index 00000000..8b283f84
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -0,0 +1,54 @@
+/* arch/arm/mach-s3c2410/include/mach/uncompress.h
+ *
+ * Copyright (c) 2003-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/regs-gpio.h>
+#include <mach/map.h>
+
+/* working in physical space... */
+#undef S3C2410_GPIOREG
+#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
+
+#include <plat/uncompress.h>
+
+static inline int is_arm926(void)
+{
+ unsigned int cpuid;
+
+ asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (cpuid));
+
+ return ((cpuid & 0xff0) == 0x260);
+}
+
+static void arch_detect_cpu(void)
+{
+ unsigned int cpuid;
+
+ cpuid = *((volatile unsigned int *)S3C2410_GSTATUS1);
+ cpuid &= S3C2410_GSTATUS1_IDMASK;
+
+ if (is_arm926() || cpuid == S3C2410_GSTATUS1_2440 ||
+ cpuid == S3C2410_GSTATUS1_2442 ||
+ cpuid == S3C2410_GSTATUS1_2416 ||
+ cpuid == S3C2410_GSTATUS1_2450) {
+ fifo_mask = S3C2440_UFSTAT_TXMASK;
+ fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+ } else {
+ fifo_mask = S3C2410_UFSTAT_TXMASK;
+ fifo_max = 15 << S3C2410_UFSTAT_TXSHIFT;
+ }
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vmalloc.h b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
new file mode 100644
index 00000000..7a311e8d
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h b/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
new file mode 100644
index 00000000..e4119913
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-cpld.h
+ *
+ * Copyright (c) 2003 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * VR1000 - CPLD control constants
+ *
+ * This program is free software; you can 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_VR1000CPLD_H
+#define __ASM_ARCH_VR1000CPLD_H
+
+#define VR1000_CPLD_CTRL2_RAMWEN (0x04) /* SRAM Write Enable */
+
+#endif /* __ASM_ARCH_VR1000CPLD_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h b/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
new file mode 100644
index 00000000..47add133
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
@@ -0,0 +1,26 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-irq.h
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine VR1000 - IRQ Number 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_VR1000IRQ_H
+#define __ASM_ARCH_VR1000IRQ_H
+
+/* irq numbers to onboard peripherals */
+
+#define IRQ_USBOC IRQ_EINT19
+#define IRQ_IDE0 IRQ_EINT16
+#define IRQ_IDE1 IRQ_EINT17
+#define IRQ_VR1000_SERIAL IRQ_EINT12
+#define IRQ_VR1000_DM9000A IRQ_EINT10
+#define IRQ_VR1000_DM9000N IRQ_EINT9
+#define IRQ_SMALERT IRQ_EINT8
+
+#endif /* __ASM_ARCH_VR1000IRQ_H */
diff --git a/arch/arm/mach-s3c2410/include/mach/vr1000-map.h b/arch/arm/mach-s3c2410/include/mach/vr1000-map.h
new file mode 100644
index 00000000..99612fcc
--- /dev/null
+++ b/arch/arm/mach-s3c2410/include/mach/vr1000-map.h
@@ -0,0 +1,110 @@
+/* arch/arm/mach-s3c2410/include/mach/vr1000-map.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine VR1000 - 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.
+*/
+
+/* needs arch/map.h including with this */
+
+/* ok, we've used up to 0x13000000, now we need to find space for the
+ * peripherals that live in the nGCS[x] areas, which are quite numerous
+ * in their space. We also have the board's CPLD to find register space
+ * for.
+ */
+
+#ifndef __ASM_ARCH_VR1000MAP_H
+#define __ASM_ARCH_VR1000MAP_H
+
+#include <mach/bast-map.h>
+
+#define VR1000_IOADDR(x) BAST_IOADDR(x)
+
+/* we put the CPLD registers next, to get them out of the way */
+
+#define VR1000_VA_CTRL1 VR1000_IOADDR(0x00000000) /* 0x01300000 */
+#define VR1000_PA_CTRL1 (S3C2410_CS5 | 0x7800000)
+
+#define VR1000_VA_CTRL2 VR1000_IOADDR(0x00100000) /* 0x01400000 */
+#define VR1000_PA_CTRL2 (S3C2410_CS1 | 0x6000000)
+
+#define VR1000_VA_CTRL3 VR1000_IOADDR(0x00200000) /* 0x01500000 */
+#define VR1000_PA_CTRL3 (S3C2410_CS1 | 0x6800000)
+
+#define VR1000_VA_CTRL4 VR1000_IOADDR(0x00300000) /* 0x01600000 */
+#define VR1000_PA_CTRL4 (S3C2410_CS1 | 0x7000000)
+
+/* next, we have the PC104 ISA interrupt registers */
+
+#define VR1000_PA_PC104_IRQREQ (S3C2410_CS5 | 0x6000000) /* 0x01700000 */
+#define VR1000_VA_PC104_IRQREQ VR1000_IOADDR(0x00400000)
+
+#define VR1000_PA_PC104_IRQRAW (S3C2410_CS5 | 0x6800000) /* 0x01800000 */
+#define VR1000_VA_PC104_IRQRAW VR1000_IOADDR(0x00500000)
+
+#define VR1000_PA_PC104_IRQMASK (S3C2410_CS5 | 0x7000000) /* 0x01900000 */
+#define VR1000_VA_PC104_IRQMASK VR1000_IOADDR(0x00600000)
+
+/* 0xE0000000 contains the IO space that is split by speed and
+ * wether the access is for 8 or 16bit IO... this ensures that
+ * the correct access is made
+ *
+ * 0x10000000 of space, partitioned as so:
+ *
+ * 0x00000000 to 0x04000000 8bit, slow
+ * 0x04000000 to 0x08000000 16bit, slow
+ * 0x08000000 to 0x0C000000 16bit, net
+ * 0x0C000000 to 0x10000000 16bit, fast
+ *
+ * each of these spaces has the following in:
+ *
+ * 0x02000000 to 0x02100000 1MB IDE primary channel
+ * 0x02100000 to 0x02200000 1MB IDE primary channel aux
+ * 0x02200000 to 0x02400000 1MB IDE secondary channel
+ * 0x02300000 to 0x02400000 1MB IDE secondary channel aux
+ * 0x02500000 to 0x02600000 1MB Davicom DM9000 ethernet controllers
+ * 0x02600000 to 0x02700000 1MB
+ *
+ * the phyiscal layout of the zones are:
+ * nGCS2 - 8bit, slow
+ * nGCS3 - 16bit, slow
+ * nGCS4 - 16bit, net
+ * nGCS5 - 16bit, fast
+ */
+
+#define VR1000_VA_MULTISPACE (0xE0000000)
+
+#define VR1000_VA_ISAIO (VR1000_VA_MULTISPACE + 0x00000000)
+#define VR1000_VA_ISAMEM (VR1000_VA_MULTISPACE + 0x01000000)
+#define VR1000_VA_IDEPRI (VR1000_VA_MULTISPACE + 0x02000000)
+#define VR1000_VA_IDEPRIAUX (VR1000_VA_MULTISPACE + 0x02100000)
+#define VR1000_VA_IDESEC (VR1000_VA_MULTISPACE + 0x02200000)
+#define VR1000_VA_IDESECAUX (VR1000_VA_MULTISPACE + 0x02300000)
+#define VR1000_VA_ASIXNET (VR1000_VA_MULTISPACE + 0x02400000)
+#define VR1000_VA_DM9000 (VR1000_VA_MULTISPACE + 0x02500000)
+#define VR1000_VA_SUPERIO (VR1000_VA_MULTISPACE + 0x02600000)
+
+/* physical offset addresses for the peripherals */
+
+#define VR1000_PA_IDEPRI (0x02000000)
+#define VR1000_PA_IDEPRIAUX (0x02800000)
+#define VR1000_PA_IDESEC (0x03000000)
+#define VR1000_PA_IDESECAUX (0x03800000)
+#define VR1000_PA_DM9000 (0x05000000)
+
+#define VR1000_PA_SERIAL (0x11800000)
+#define VR1000_VA_SERIAL (VR1000_IOADDR(0x00700000))
+
+/* VR1000 ram is in CS1, with A26..A24 = 2_101 */
+#define VR1000_PA_SRAM (S3C2410_CS1 | 0x05000000)
+
+/* some configurations for the peripherals */
+
+#define VR1000_DM9000_CS VR1000_VAM_CS4
+
+#endif /* __ASM_ARCH_VR1000MAP_H */
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
new file mode 100644
index 00000000..dabc1412
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -0,0 +1,244 @@
+/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+ *
+ * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
+ *
+ * Copyright (c) 2006 American Microsystems Limited
+ * David Anders <danders@amltd.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
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <mach/fb.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/gpio-cfg.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+static struct resource amlm5900_nor_resource = {
+ .start = 0x00000000,
+ .end = 0x01000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+
+
+static struct mtd_partition amlm5900_mtd_partitions[] = {
+ {
+ .name = "System",
+ .size = 0x240000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "Kernel",
+ .size = 0x100000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "Ramdisk",
+ .size = 0x300000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "JFFS2",
+ .size = 0x9A0000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "Settings",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct physmap_flash_data amlm5900_flash_data = {
+ .width = 2,
+ .parts = amlm5900_mtd_partitions,
+ .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions),
+};
+
+static struct platform_device amlm5900_device_nor = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &amlm5900_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &amlm5900_nor_resource,
+};
+
+static struct map_desc amlm5900_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg amlm5900_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+
+static struct platform_device *amlm5900_devices[] __initdata = {
+#ifdef CONFIG_FB_S3C2410
+ &s3c_device_lcd,
+#endif
+ &s3c_device_adc,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &amlm5900_device_nor,
+};
+
+static void __init amlm5900_map_io(void)
+{
+ s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+}
+
+#ifdef CONFIG_FB_S3C2410
+static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
+ .width = 160,
+ .height = 160,
+
+ .type = S3C2410_LCDCON1_STN4,
+
+ .pixclock = 680000, /* HCLK = 100MHz */
+ .xres = 160,
+ .yres = 160,
+ .bpp = 4,
+ .left_margin = 1 << (4 + 3),
+ .right_margin = 8 << 3,
+ .hsync_len = 48,
+ .upper_margin = 0,
+ .lower_margin = 0,
+
+ .lcdcon5 = 0x00000001,
+};
+
+static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
+
+ .displays = &amlm5900_lcd_info,
+ .num_displays = 1,
+ .default_display = 0,
+
+ .gpccon = 0xaaaaaaaa,
+ .gpccon_mask = 0xffffffff,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+
+ .gpdcon = 0xaaaaaaaa,
+ .gpdcon_mask = 0xffffffff,
+ .gpdup = 0x0000ffff,
+ .gpdup_mask = 0xffffffff,
+};
+#endif
+
+static irqreturn_t
+amlm5900_wake_interrupt(int irq, void *ignored)
+{
+ return IRQ_HANDLED;
+}
+
+static void amlm5900_init_pm(void)
+{
+ int ret = 0;
+
+ ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt,
+ IRQF_TRIGGER_RISING | IRQF_SHARED,
+ "amlm5900_wakeup", &amlm5900_wake_interrupt);
+ if (ret != 0) {
+ printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret);
+ } else {
+ enable_irq_wake(IRQ_EINT9);
+ /* configure the suspend/resume status pin */
+ s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_UP);
+ }
+}
+static void __init amlm5900_init(void)
+{
+ amlm5900_init_pm();
+#ifdef CONFIG_FB_S3C2410
+ s3c24xx_fb_set_platdata(&amlm5900_fb_info);
+#endif
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
+}
+
+MACHINE_START(AML_M5900, "AML_M5900")
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = amlm5900_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = amlm5900_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
new file mode 100644
index 00000000..1e2d536a
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -0,0 +1,665 @@
+/* linux/arch/arm/mach-s3c2410/mach-bast.c
+ *
+ * Copyright 2003-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/dm9000.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <net/ax88796.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+#include <mach/bast-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+
+#include <plat/hwmon.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <mach/fb.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/serial_8250.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/cpu-freq.h>
+#include <plat/gpio-cfg.h>
+#include <plat/audio-simtec.h>
+
+#include "usb-simtec.h"
+#include "nor-simtec.h"
+
+#define COPYRIGHT ", Copyright 2004-2008 Simtec Electronics"
+
+/* macros for virtual address mods for the io space entries */
+#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
+#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
+#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
+#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
+
+/* macros to modify the physical addresses for io space */
+
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
+
+static struct map_desc bast_iodesc[] __initdata = {
+ /* ISA IO areas */
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = PA_CS2(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = PA_CS3(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+ /* bast CPLD control registers, and external interrupt controls */
+ {
+ .virtual = (u32)BAST_VA_CTRL1,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL1),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL2,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL2),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL3,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_CTRL4,
+ .pfn = __phys_to_pfn(BAST_PA_CTRL4),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+ /* PC104 IRQ mux */
+ {
+ .virtual = (u32)BAST_VA_PC104_IRQREQ,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_PC104_IRQRAW,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)BAST_VA_PC104_IRQMASK,
+ .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+
+ /* peripheral space... one for each of fast/slow/byte/16bit */
+ /* note, ide is only decoded in word space, even though some registers
+ * are only 8bit */
+
+ /* slow, byte */
+ { VA_C2(BAST_VA_ISAIO), PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
+ { VA_C2(BAST_VA_ISAMEM), PA_CS2(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
+ { VA_C2(BAST_VA_SUPERIO), PA_CS2(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
+
+ /* slow, word */
+ { VA_C3(BAST_VA_ISAIO), PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
+ { VA_C3(BAST_VA_ISAMEM), PA_CS3(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
+ { VA_C3(BAST_VA_SUPERIO), PA_CS3(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
+
+ /* fast, byte */
+ { VA_C4(BAST_VA_ISAIO), PA_CS4(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
+ { VA_C4(BAST_VA_ISAMEM), PA_CS4(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
+ { VA_C4(BAST_VA_SUPERIO), PA_CS4(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
+
+ /* fast, word */
+ { VA_C5(BAST_VA_ISAIO), PA_CS5(BAST_PA_ISAIO), SZ_16M, MT_DEVICE },
+ { VA_C5(BAST_VA_ISAMEM), PA_CS5(BAST_PA_ISAMEM), SZ_16M, MT_DEVICE },
+ { VA_C5(BAST_VA_SUPERIO), PA_CS5(BAST_PA_SUPERIO), SZ_1M, MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+
+static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = bast_serial_clocks,
+ .clocks_size = ARRAY_SIZE(bast_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = bast_serial_clocks,
+ .clocks_size = ARRAY_SIZE(bast_serial_clocks),
+ },
+ /* port 2 is not actually used */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = bast_serial_clocks,
+ .clocks_size = ARRAY_SIZE(bast_serial_clocks),
+ }
+};
+
+/* NAND Flash on BAST board */
+
+#ifdef CONFIG_PM
+static int bast_pm_suspend(void)
+{
+ /* ensure that an nRESET is not generated on resume. */
+ gpio_direction_output(S3C2410_GPA(21), 1);
+ return 0;
+}
+
+static void bast_pm_resume(void)
+{
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+}
+
+#else
+#define bast_pm_suspend NULL
+#define bast_pm_resume NULL
+#endif
+
+static struct syscore_ops bast_pm_syscore_ops = {
+ .suspend = bast_pm_suspend,
+ .resume = bast_pm_resume,
+};
+
+static int smartmedia_map[] = { 0 };
+static int chip0_map[] = { 1 };
+static int chip1_map[] = { 2 };
+static int chip2_map[] = { 3 };
+
+static struct mtd_partition __initdata bast_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_16K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "/boot",
+ .size = SZ_4M - SZ_16K,
+ .offset = SZ_16K,
+ },
+ [2] = {
+ .name = "user",
+ .offset = SZ_4M,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+/* the bast has 4 selectable slots for nand-flash, the three
+ * on-board chip areas, as well as the external SmartMedia
+ * slot.
+ *
+ * Note, there is no current hot-plug support for the SmartMedia
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata bast_nand_sets[] = {
+ [0] = {
+ .name = "SmartMedia",
+ .nr_chips = 1,
+ .nr_map = smartmedia_map,
+ .options = NAND_SCAN_SILENT_NODEV,
+ .nr_partitions = ARRAY_SIZE(bast_default_nand_part),
+ .partitions = bast_default_nand_part,
+ },
+ [1] = {
+ .name = "chip0",
+ .nr_chips = 1,
+ .nr_map = chip0_map,
+ .nr_partitions = ARRAY_SIZE(bast_default_nand_part),
+ .partitions = bast_default_nand_part,
+ },
+ [2] = {
+ .name = "chip1",
+ .nr_chips = 1,
+ .nr_map = chip1_map,
+ .options = NAND_SCAN_SILENT_NODEV,
+ .nr_partitions = ARRAY_SIZE(bast_default_nand_part),
+ .partitions = bast_default_nand_part,
+ },
+ [3] = {
+ .name = "chip2",
+ .nr_chips = 1,
+ .nr_map = chip2_map,
+ .options = NAND_SCAN_SILENT_NODEV,
+ .nr_partitions = ARRAY_SIZE(bast_default_nand_part),
+ .partitions = bast_default_nand_part,
+ }
+};
+
+static void bast_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+ unsigned int tmp;
+
+ slot = set->nr_map[slot] & 3;
+
+ pr_debug("bast_nand: selecting slot %d (set %p,%p)\n",
+ slot, set, set->nr_map);
+
+ tmp = __raw_readb(BAST_VA_CTRL2);
+ tmp &= BAST_CPLD_CTLR2_IDERST;
+ tmp |= slot;
+ tmp |= BAST_CPLD_CTRL2_WNAND;
+
+ pr_debug("bast_nand: ctrl2 now %02x\n", tmp);
+
+ __raw_writeb(tmp, BAST_VA_CTRL2);
+}
+
+static struct s3c2410_platform_nand __initdata bast_nand_info = {
+ .tacls = 30,
+ .twrph0 = 60,
+ .twrph1 = 60,
+ .nr_sets = ARRAY_SIZE(bast_nand_sets),
+ .sets = bast_nand_sets,
+ .select_chip = bast_nand_select,
+};
+
+/* DM9000 */
+
+static struct resource bast_dm9k_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + BAST_PA_DM9000,
+ .end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
+ .end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_DM9000,
+ .end = IRQ_DM9000,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ }
+
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+static struct dm9000_plat_data bast_dm9k_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device bast_device_dm9k = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_dm9k_resource),
+ .resource = bast_dm9k_resource,
+ .dev = {
+ .platform_data = &bast_dm9k_platdata,
+ }
+};
+
+/* serial devices */
+
+#define SERIAL_BASE (S3C2410_CS2 + BAST_PA_SUPERIO)
+#define SERIAL_FLAGS (UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SHARE_IRQ)
+#define SERIAL_CLK (1843200)
+
+static struct plat_serial8250_port bast_sio_data[] = {
+ [0] = {
+ .mapbase = SERIAL_BASE + 0x2f8,
+ .irq = IRQ_PCSERIAL1,
+ .flags = SERIAL_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = SERIAL_CLK,
+ },
+ [1] = {
+ .mapbase = SERIAL_BASE + 0x3f8,
+ .irq = IRQ_PCSERIAL2,
+ .flags = SERIAL_FLAGS,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = SERIAL_CLK,
+ },
+ { }
+};
+
+static struct platform_device bast_sio = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = &bast_sio_data,
+ },
+};
+
+/* we have devices on the bus which cannot work much over the
+ * standard 100KHz i2c bus frequency
+*/
+
+static struct s3c2410_platform_i2c __initdata bast_i2c_info = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+};
+
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data bast_asix_platdata = {
+ .flags = AXFLG_MAC_FROMDEV,
+ .wordlength = 2,
+ .dcr_val = 0x48,
+ .rcr_val = 0x40,
+};
+
+static struct resource bast_asix_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + BAST_PA_ASIXNET,
+ .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+ .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1f * 0x20),
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_ASIX,
+ .end = IRQ_ASIX,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device bast_device_asix = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_asix_resource),
+ .resource = bast_asix_resource,
+ .dev = {
+ .platform_data = &bast_asix_platdata
+ }
+};
+
+/* Asix AX88796 10/100 ethernet controller parallel port */
+
+static struct resource bast_asixpp_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + BAST_PA_ASIXNET + (0x18 * 0x20),
+ .end = S3C2410_CS5 + BAST_PA_ASIXNET + (0x1b * 0x20) - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device bast_device_axpp = {
+ .name = "ax88796-pp",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bast_asixpp_resource),
+ .resource = bast_asixpp_resource,
+};
+
+/* LCD/VGA controller */
+
+static struct s3c2410fb_display __initdata bast_lcd_info[] = {
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 4,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
+
+ .lcdcon5 = 0x00014b02,
+ },
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 8,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
+
+ .lcdcon5 = 0x00014b02,
+ },
+ {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 33333,
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .left_margin = 40,
+ .right_margin = 20,
+ .hsync_len = 88,
+ .upper_margin = 30,
+ .lower_margin = 32,
+ .vsync_len = 3,
+
+ .lcdcon5 = 0x00014b02,
+ },
+};
+
+/* LCD/VGA controller */
+
+static struct s3c2410fb_mach_info __initdata bast_fb_info = {
+
+ .displays = bast_lcd_info,
+ .num_displays = ARRAY_SIZE(bast_lcd_info),
+ .default_display = 1,
+};
+
+/* I2C devices fitted. */
+
+static struct i2c_board_info bast_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ }, {
+ I2C_BOARD_INFO("simtec-pmu", 0x6b),
+ }, {
+ I2C_BOARD_INFO("ch7013", 0x75),
+ },
+};
+
+static struct s3c_hwmon_pdata bast_hwmon_info = {
+ /* LCD contrast (0-6.6V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "lcd-contrast",
+ .mult = 3300,
+ .div = 512,
+ },
+ /* LED current feedback */
+ .in[1] = &(struct s3c_hwmon_chcfg) {
+ .name = "led-feedback",
+ .mult = 3300,
+ .div = 1024,
+ },
+ /* LCD feedback (0-6.6V) */
+ .in[2] = &(struct s3c_hwmon_chcfg) {
+ .name = "lcd-feedback",
+ .mult = 3300,
+ .div = 512,
+ },
+ /* Vcore (1.8-2.0V), Vref 3.3V */
+ .in[3] = &(struct s3c_hwmon_chcfg) {
+ .name = "vcore",
+ .mult = 3300,
+ .div = 1024,
+ },
+};
+
+/* Standard BAST devices */
+// cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
+
+static struct platform_device *bast_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &s3c_device_adc,
+ &s3c_device_hwmon,
+ &bast_device_dm9k,
+ &bast_device_asix,
+ &bast_device_axpp,
+ &bast_sio,
+};
+
+static struct clk *bast_clocks[] __initdata = {
+ &s3c24xx_dclk0,
+ &s3c24xx_dclk1,
+ &s3c24xx_clkout0,
+ &s3c24xx_clkout1,
+ &s3c24xx_uclk,
+};
+
+static struct s3c_cpufreq_board __initdata bast_cpufreq = {
+ .refresh = 7800, /* 7.8usec */
+ .auto_io = 1,
+ .need_io = 1,
+};
+
+static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
+ .have_mic = 1,
+ .have_lout = 1,
+};
+
+static void __init bast_map_io(void)
+{
+ /* initialise the clocks */
+
+ s3c24xx_dclk0.parent = &clk_upll;
+ s3c24xx_dclk0.rate = 12*1000*1000;
+
+ s3c24xx_dclk1.parent = &clk_upll;
+ s3c24xx_dclk1.rate = 24*1000*1000;
+
+ s3c24xx_clkout0.parent = &s3c24xx_dclk0;
+ s3c24xx_clkout1.parent = &s3c24xx_dclk1;
+
+ s3c24xx_uclk.parent = &s3c24xx_clkout1;
+
+ s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+
+ s3c_hwmon_set_platdata(&bast_hwmon_info);
+
+ s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+}
+
+static void __init bast_init(void)
+{
+ register_syscore_ops(&bast_pm_syscore_ops);
+
+ s3c_i2c0_set_platdata(&bast_i2c_info);
+ s3c_nand_set_platdata(&bast_nand_info);
+ s3c24xx_fb_set_platdata(&bast_fb_info);
+ platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
+
+ i2c_register_board_info(0, bast_i2c_devs,
+ ARRAY_SIZE(bast_i2c_devs));
+
+ usb_simtec_init();
+ nor_simtec_init();
+ simtec_audio_add(NULL, true, &bast_audio);
+
+ WARN_ON(gpio_request(S3C2410_GPA(21), "bast nreset"));
+
+ s3c_cpufreq_setboard(&bast_cpufreq);
+}
+
+MACHINE_START(BAST, "Simtec-BAST")
+ /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = bast_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = bast_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
new file mode 100644
index 00000000..2a2fa062
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -0,0 +1,753 @@
+/* linux/arch/arm/mach-s3c2410/mach-h1940.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.handhelds.org/projects/h1940.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/pwm_backlight.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/pda_power.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-clock.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/gpio-fns.h>
+#include <mach/gpio-nrs.h>
+
+#include <mach/h1940.h>
+#include <mach/h1940-latch.h>
+#include <mach/fb.h>
+#include <plat/udc.h>
+#include <plat/iic.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/pm.h>
+#include <plat/mci.h>
+#include <plat/ts.h>
+
+#include <sound/uda1380.h>
+
+#define H1940_LATCH ((void __force __iomem *)0xF8000000)
+
+#define H1940_PA_LATCH S3C2410_CS2
+
+#define H1940_LATCH_BIT(x) (1 << ((x) + 16 - S3C_GPIO_END))
+
+static struct map_desc h1940_iodesc[] __initdata = {
+ [0] = {
+ .virtual = (unsigned long)H1940_LATCH,
+ .pfn = __phys_to_pfn(H1940_PA_LATCH),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg h1940_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x245,
+ .ulcon = 0x03,
+ .ufcon = 0x00,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .uart_flags = UPF_CONS_FLOW,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ }
+};
+
+/* Board control latch control */
+
+static unsigned int latch_state;
+
+static void h1940_latch_control(unsigned int clear, unsigned int set)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ latch_state &= ~clear;
+ latch_state |= set;
+
+ __raw_writel(latch_state, H1940_LATCH);
+
+ local_irq_restore(flags);
+}
+
+static inline int h1940_gpiolib_to_latch(int offset)
+{
+ return 1 << (offset + 16);
+}
+
+static void h1940_gpiolib_latch_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ int latch_bit = h1940_gpiolib_to_latch(offset);
+
+ h1940_latch_control(value ? 0 : latch_bit,
+ value ? latch_bit : 0);
+}
+
+static int h1940_gpiolib_latch_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ h1940_gpiolib_latch_set(chip, offset, value);
+ return 0;
+}
+
+static int h1940_gpiolib_latch_get(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return (latch_state >> (offset + 16)) & 1;
+}
+
+struct gpio_chip h1940_latch_gpiochip = {
+ .base = H1940_LATCH_GPIO(0),
+ .owner = THIS_MODULE,
+ .label = "H1940_LATCH",
+ .ngpio = 16,
+ .direction_output = h1940_gpiolib_latch_output,
+ .set = h1940_gpiolib_latch_set,
+ .get = h1940_gpiolib_latch_get,
+};
+
+static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
+ .vbus_pin = S3C2410_GPG(5),
+ .vbus_pin_inverted = 1,
+ .pullup_pin = H1940_LATCH_USB_DP,
+};
+
+static struct s3c2410_ts_mach_info h1940_ts_cfg __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+ .cfg_gpio = s3c24xx_ts_cfg_gpio,
+};
+
+/**
+ * Set lcd on or off
+ **/
+static struct s3c2410fb_display h1940_lcd __initdata = {
+ .lcdcon5= S3C2410_LCDCON5_FRM565 | \
+ S3C2410_LCDCON5_INVVLINE | \
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 260000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 8,
+ .right_margin = 20,
+ .hsync_len = 4,
+ .upper_margin = 8,
+ .lower_margin = 7,
+ .vsync_len = 1,
+};
+
+static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
+ .displays = &h1940_lcd,
+ .num_displays = 1,
+ .default_display = 0,
+
+ .lpcsel = 0x02,
+ .gpccon = 0xaa940659,
+ .gpccon_mask = 0xffffc0f0,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+ .gpdcon = 0xaa84aaa0,
+ .gpdcon_mask = 0xffffffff,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+};
+
+static int power_supply_init(struct device *dev)
+{
+ return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int h1940_is_ac_online(void)
+{
+ return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(S3C2410_GPF(2));
+}
+
+static char *h1940_supplicants[] = {
+ "main-battery",
+ "backup-battery",
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = h1940_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = h1940_supplicants,
+ .num_supplicants = ARRAY_SIZE(h1940_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+ [0] = {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+ IORESOURCE_IRQ_HIGHEDGE,
+ .start = IRQ_EINT2,
+ .end = IRQ_EINT2,
+ },
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data =
+ &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+ { .volt = 4070, .cur = 162, .level = 100},
+ { .volt = 4040, .cur = 165, .level = 95},
+ { .volt = 4016, .cur = 164, .level = 90},
+ { .volt = 3996, .cur = 166, .level = 85},
+ { .volt = 3971, .cur = 168, .level = 80},
+ { .volt = 3951, .cur = 168, .level = 75},
+ { .volt = 3931, .cur = 170, .level = 70},
+ { .volt = 3903, .cur = 172, .level = 65},
+ { .volt = 3886, .cur = 172, .level = 60},
+ { .volt = 3858, .cur = 176, .level = 55},
+ { .volt = 3842, .cur = 176, .level = 50},
+ { .volt = 3818, .cur = 176, .level = 45},
+ { .volt = 3789, .cur = 180, .level = 40},
+ { .volt = 3769, .cur = 180, .level = 35},
+ { .volt = 3749, .cur = 184, .level = 30},
+ { .volt = 3732, .cur = 184, .level = 25},
+ { .volt = 3716, .cur = 184, .level = 20},
+ { .volt = 3708, .cur = 184, .level = 15},
+ { .volt = 3716, .cur = 96, .level = 10},
+ { .volt = 3700, .cur = 96, .level = 5},
+ { .volt = 3684, .cur = 96, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+ { .volt = 4130, .cur = 0, .level = 100},
+ { .volt = 3982, .cur = 0, .level = 50},
+ { .volt = 3854, .cur = 0, .level = 10},
+ { .volt = 3841, .cur = 0, .level = 0},
+};
+
+int h1940_bat_init(void)
+{
+ int ret;
+
+ ret = gpio_request(H1940_LATCH_SM803_ENABLE, "h1940-charger-enable");
+ if (ret)
+ return ret;
+ gpio_direction_output(H1940_LATCH_SM803_ENABLE, 0);
+
+ return 0;
+
+}
+
+void h1940_bat_exit(void)
+{
+ gpio_free(H1940_LATCH_SM803_ENABLE);
+}
+
+void h1940_enable_charger(void)
+{
+ gpio_set_value(H1940_LATCH_SM803_ENABLE, 1);
+}
+
+void h1940_disable_charger(void)
+{
+ gpio_set_value(H1940_LATCH_SM803_ENABLE, 0);
+}
+
+static struct s3c_adc_bat_pdata h1940_bat_cfg = {
+ .init = h1940_bat_init,
+ .exit = h1940_bat_exit,
+ .enable_charger = h1940_enable_charger,
+ .disable_charger = h1940_disable_charger,
+ .gpio_charge_finished = S3C2410_GPF(3),
+ .gpio_inverted = 1,
+ .lut_noac = bat_lut_noac,
+ .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+ .lut_acin = bat_lut_acin,
+ .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+ .volt_channel = 0,
+ .current_channel = 1,
+ .volt_mult = 4056,
+ .current_mult = 1893,
+ .internal_impedance = 200,
+ .backup_volt_channel = 3,
+ /* TODO Check backup volt multiplier */
+ .backup_volt_mult = 4056,
+ .backup_volt_min = 0,
+ .backup_volt_max = 4149288
+};
+
+static struct platform_device h1940_battery = {
+ .name = "s3c-adc-battery",
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_adc.dev,
+ .platform_data = &h1940_bat_cfg,
+ },
+};
+
+DEFINE_SPINLOCK(h1940_blink_spin);
+
+int h1940_led_blink_set(unsigned gpio, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int blink_gpio, check_gpio1, check_gpio2;
+
+ switch (gpio) {
+ case H1940_LATCH_LED_GREEN:
+ blink_gpio = S3C2410_GPA(7);
+ check_gpio1 = S3C2410_GPA(1);
+ check_gpio2 = S3C2410_GPA(3);
+ break;
+ case H1940_LATCH_LED_RED:
+ blink_gpio = S3C2410_GPA(1);
+ check_gpio1 = S3C2410_GPA(7);
+ check_gpio2 = S3C2410_GPA(3);
+ break;
+ default:
+ blink_gpio = S3C2410_GPA(3);
+ check_gpio1 = S3C2410_GPA(1);
+ check_gpio1 = S3C2410_GPA(7);
+ break;
+ }
+
+ if (delay_on && delay_off && !*delay_on && !*delay_off)
+ *delay_on = *delay_off = 500;
+
+ spin_lock(&h1940_blink_spin);
+
+ switch (state) {
+ case GPIO_LED_NO_BLINK_LOW:
+ case GPIO_LED_NO_BLINK_HIGH:
+ if (!gpio_get_value(check_gpio1) &&
+ !gpio_get_value(check_gpio2))
+ gpio_set_value(H1940_LATCH_LED_FLASH, 0);
+ gpio_set_value(blink_gpio, 0);
+ if (gpio_is_valid(gpio))
+ gpio_set_value(gpio, state);
+ break;
+ case GPIO_LED_BLINK:
+ if (gpio_is_valid(gpio))
+ gpio_set_value(gpio, 0);
+ gpio_set_value(H1940_LATCH_LED_FLASH, 1);
+ gpio_set_value(blink_gpio, 1);
+ break;
+ }
+
+ spin_unlock(&h1940_blink_spin);
+
+ return 0;
+}
+EXPORT_SYMBOL(h1940_led_blink_set);
+
+static struct gpio_led h1940_leds_desc[] = {
+ {
+ .name = "Green",
+ .default_trigger = "main-battery-full",
+ .gpio = H1940_LATCH_LED_GREEN,
+ .retain_state_suspended = 1,
+ },
+ {
+ .name = "Red",
+ .default_trigger
+ = "main-battery-charging-blink-full-solid",
+ .gpio = H1940_LATCH_LED_RED,
+ .retain_state_suspended = 1,
+ },
+};
+
+static struct gpio_led_platform_data h1940_leds_pdata = {
+ .num_leds = ARRAY_SIZE(h1940_leds_desc),
+ .leds = h1940_leds_desc,
+ .gpio_blink_set = h1940_led_blink_set,
+};
+
+static struct platform_device h1940_device_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &h1940_leds_pdata,
+ },
+};
+
+static struct platform_device h1940_device_bluetooth = {
+ .name = "h1940-bt",
+ .id = -1,
+};
+
+static void h1940_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+ switch (power_mode) {
+ case MMC_POWER_OFF:
+ gpio_set_value(H1940_LATCH_SD_POWER, 0);
+ break;
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ gpio_set_value(H1940_LATCH_SD_POWER, 1);
+ break;
+ default:
+ break;
+ };
+}
+
+static struct s3c24xx_mci_pdata h1940_mmc_cfg __initdata = {
+ .gpio_detect = S3C2410_GPF(5),
+ .gpio_wprotect = S3C2410_GPH(8),
+ .set_power = h1940_set_mmc_power,
+ .ocr_avail = MMC_VDD_32_33,
+};
+
+static int h1940_backlight_init(struct device *dev)
+{
+ gpio_request(S3C2410_GPB(0), "Backlight");
+
+ gpio_direction_output(S3C2410_GPB(0), 0);
+ s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+
+ return 0;
+}
+
+static int h1940_backlight_notify(struct device *dev, int brightness)
+{
+ if (!brightness) {
+ gpio_direction_output(S3C2410_GPB(0), 1);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+ } else {
+ gpio_direction_output(S3C2410_GPB(0), 0);
+ s3c_gpio_setpull(S3C2410_GPB(0), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 1);
+ }
+ return brightness;
+}
+
+static void h1940_backlight_exit(struct device *dev)
+{
+ gpio_direction_output(S3C2410_GPB(0), 1);
+ gpio_set_value(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+}
+
+
+static struct platform_pwm_backlight_data backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 100,
+ .dft_brightness = 50,
+ /* tcnt = 0x31 */
+ .pwm_period_ns = 36296,
+ .init = h1940_backlight_init,
+ .notify = h1940_backlight_notify,
+ .exit = h1940_backlight_exit,
+};
+
+static struct platform_device h1940_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[0].dev,
+ .platform_data = &backlight_data,
+ },
+ .id = -1,
+};
+
+static void h1940_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ int value, retries = 100;
+
+ if (!power) {
+ gpio_set_value(S3C2410_GPC(0), 0);
+ /* wait for 3ac */
+ do {
+ value = gpio_get_value(S3C2410_GPC(6));
+ } while (value && retries--);
+
+ gpio_set_value(H1940_LATCH_LCD_P2, 0);
+ gpio_set_value(H1940_LATCH_LCD_P3, 0);
+ gpio_set_value(H1940_LATCH_LCD_P4, 0);
+
+ gpio_direction_output(S3C2410_GPC(1), 0);
+ gpio_direction_output(S3C2410_GPC(4), 0);
+
+ gpio_set_value(H1940_LATCH_LCD_P1, 0);
+ gpio_set_value(H1940_LATCH_LCD_P0, 0);
+
+ gpio_set_value(S3C2410_GPC(5), 0);
+
+ } else {
+ gpio_set_value(H1940_LATCH_LCD_P0, 1);
+ gpio_set_value(H1940_LATCH_LCD_P1, 1);
+
+ gpio_direction_input(S3C2410_GPC(1));
+ gpio_direction_input(S3C2410_GPC(4));
+ mdelay(10);
+ s3c_gpio_cfgpin(S3C2410_GPC(1), S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin(S3C2410_GPC(4), S3C_GPIO_SFN(2));
+
+ gpio_set_value(S3C2410_GPC(5), 1);
+ gpio_set_value(S3C2410_GPC(0), 1);
+
+ gpio_set_value(H1940_LATCH_LCD_P3, 1);
+ gpio_set_value(H1940_LATCH_LCD_P2, 1);
+ gpio_set_value(H1940_LATCH_LCD_P4, 1);
+ }
+}
+
+static struct plat_lcd_data h1940_lcd_power_data = {
+ .set_power = h1940_lcd_power_set,
+};
+
+static struct platform_device h1940_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_lcd.dev,
+ .dev.platform_data = &h1940_lcd_power_data,
+};
+
+static struct uda1380_platform_data uda1380_info = {
+ .gpio_power = H1940_LATCH_UDA_POWER,
+ .gpio_reset = S3C2410_GPA(12),
+ .dac_clk = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info h1940_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("uda1380", 0x1a),
+ .platform_data = &uda1380_info,
+ },
+};
+
+#define DECLARE_BUTTON(p, k, n, w) \
+ { \
+ .gpio = p, \
+ .code = k, \
+ .desc = n, \
+ .wakeup = w, \
+ .active_low = 1, \
+ }
+
+static struct gpio_keys_button h1940_buttons[] = {
+ DECLARE_BUTTON(S3C2410_GPF(0), KEY_POWER, "Power", 1),
+ DECLARE_BUTTON(S3C2410_GPF(6), KEY_ENTER, "Select", 1),
+ DECLARE_BUTTON(S3C2410_GPF(7), KEY_RECORD, "Record", 0),
+ DECLARE_BUTTON(S3C2410_GPG(0), KEY_F11, "Calendar", 0),
+ DECLARE_BUTTON(S3C2410_GPG(2), KEY_F12, "Contacts", 0),
+ DECLARE_BUTTON(S3C2410_GPG(3), KEY_MAIL, "Mail", 0),
+ DECLARE_BUTTON(S3C2410_GPG(6), KEY_LEFT, "Left_arrow", 0),
+ DECLARE_BUTTON(S3C2410_GPG(7), KEY_HOMEPAGE, "Home", 0),
+ DECLARE_BUTTON(S3C2410_GPG(8), KEY_RIGHT, "Right_arrow", 0),
+ DECLARE_BUTTON(S3C2410_GPG(9), KEY_UP, "Up_arrow", 0),
+ DECLARE_BUTTON(S3C2410_GPG(10), KEY_DOWN, "Down_arrow", 0),
+};
+
+static struct gpio_keys_platform_data h1940_buttons_data = {
+ .buttons = h1940_buttons,
+ .nbuttons = ARRAY_SIZE(h1940_buttons),
+};
+
+static struct platform_device h1940_dev_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &h1940_buttons_data,
+ }
+};
+
+static struct platform_device *h1940_devices[] __initdata = {
+ &h1940_dev_buttons,
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &samsung_asoc_dma,
+ &s3c_device_usbgadget,
+ &h1940_device_leds,
+ &h1940_device_bluetooth,
+ &s3c_device_sdi,
+ &s3c_device_rtc,
+ &s3c_device_timer[0],
+ &h1940_backlight,
+ &h1940_lcd_powerdev,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &power_supply,
+ &h1940_battery,
+};
+
+static void __init h1940_map_io(void)
+{
+ s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+
+ /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+ memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
+ s3c_pm_init();
+
+ /* Add latch gpio chip, set latch initial value */
+ h1940_latch_control(0, 0);
+ WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+ memblock_reserve(0x30003000, 0x1000);
+ memblock_reserve(0x30081000, 0x1000);
+}
+
+static void __init h1940_init_irq(void)
+{
+ s3c24xx_init_irq();
+}
+
+static void __init h1940_init(void)
+{
+ u32 tmp;
+
+ s3c24xx_fb_set_platdata(&h1940_fb_info);
+ s3c24xx_mci_set_platdata(&h1940_mmc_cfg);
+ s3c24xx_udc_set_platdata(&h1940_udc_cfg);
+ s3c24xx_ts_set_platdata(&h1940_ts_cfg);
+ s3c_i2c0_set_platdata(NULL);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ tmp = (0x78 << S3C24XX_PLLCON_MDIVSHIFT)
+ | (0x02 << S3C24XX_PLLCON_PDIVSHIFT)
+ | (0x03 << S3C24XX_PLLCON_SDIVSHIFT);
+ writel(tmp, S3C2410_UPLLCON);
+
+ gpio_request(S3C2410_GPC(0), "LCD power");
+ gpio_request(S3C2410_GPC(1), "LCD power");
+ gpio_request(S3C2410_GPC(4), "LCD power");
+ gpio_request(S3C2410_GPC(5), "LCD power");
+ gpio_request(S3C2410_GPC(6), "LCD power");
+ gpio_request(H1940_LATCH_LCD_P0, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P1, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P2, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P3, "LCD power");
+ gpio_request(H1940_LATCH_LCD_P4, "LCD power");
+ gpio_request(H1940_LATCH_MAX1698_nSHUTDOWN, "LCD power");
+ gpio_direction_output(S3C2410_GPC(0), 0);
+ gpio_direction_output(S3C2410_GPC(1), 0);
+ gpio_direction_output(S3C2410_GPC(4), 0);
+ gpio_direction_output(S3C2410_GPC(5), 0);
+ gpio_direction_input(S3C2410_GPC(6));
+ gpio_direction_output(H1940_LATCH_LCD_P0, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P1, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P2, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P3, 0);
+ gpio_direction_output(H1940_LATCH_LCD_P4, 0);
+ gpio_direction_output(H1940_LATCH_MAX1698_nSHUTDOWN, 0);
+
+ gpio_request(H1940_LATCH_SD_POWER, "SD power");
+ gpio_direction_output(H1940_LATCH_SD_POWER, 0);
+
+ platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
+
+ gpio_request(S3C2410_GPA(1), "Red LED blink");
+ gpio_request(S3C2410_GPA(3), "Blue LED blink");
+ gpio_request(S3C2410_GPA(7), "Green LED blink");
+ gpio_request(H1940_LATCH_LED_FLASH, "LED blink");
+ gpio_direction_output(S3C2410_GPA(1), 0);
+ gpio_direction_output(S3C2410_GPA(3), 0);
+ gpio_direction_output(S3C2410_GPA(7), 0);
+ gpio_direction_output(H1940_LATCH_LED_FLASH, 0);
+
+ i2c_register_board_info(0, h1940_i2c_devices,
+ ARRAY_SIZE(h1940_i2c_devices));
+}
+
+MACHINE_START(H1940, "IPAQ-H1940")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = h1940_map_io,
+ .reserve = h1940_reserve,
+ .init_irq = h1940_init_irq,
+ .init_machine = h1940_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
new file mode 100644
index 00000000..079dcaa6
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -0,0 +1,604 @@
+/* Machine specific code for the Acer n30, Acer N35, Navman PiN 570,
+ * Yakumo AlphaX and Airis NC05 PDAs.
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (c) 2005-2008 Christer Weinigel <christer@weinigel.se>
+ *
+ * There is a wiki with more information about the n30 port at
+ * http://handhelds.org/moin/moin.cgi/AcerN30Documentation .
+ *
+ * This program is free software; you can 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_keys.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/fb.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/map.h>
+
+#include <plat/iic.h>
+#include <plat/regs-serial.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/mci.h>
+#include <plat/s3c2410.h>
+#include <plat/udc.h>
+
+static struct map_desc n30_iodesc[] __initdata = {
+ /* nothing here yet */
+};
+
+static struct s3c2410_uartcfg n30_uartcfgs[] = {
+ /* Normal serial port */
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x2c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ /* IR port */
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .uart_flags = UPF_CONS_FLOW,
+ .ucon = 0x2c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ },
+ /* On the N30 the bluetooth controller is connected here.
+ * On the N35 and variants the GPS receiver is connected here. */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x2c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+static struct s3c2410_udc_mach_info n30_udc_cfg __initdata = {
+ .vbus_pin = S3C2410_GPG(1),
+ .vbus_pin_inverted = 0,
+ .pullup_pin = S3C2410_GPB(3),
+};
+
+static struct gpio_keys_button n30_buttons[] = {
+ {
+ .gpio = S3C2410_GPF(0),
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(9),
+ .code = KEY_UP,
+ .desc = "Thumbwheel Up",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(8),
+ .code = KEY_DOWN,
+ .desc = "Thumbwheel Down",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(7),
+ .code = KEY_ENTER,
+ .desc = "Thumbwheel Press",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(7),
+ .code = KEY_HOMEPAGE,
+ .desc = "Home",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(6),
+ .code = KEY_CALENDAR,
+ .desc = "Calendar",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(5),
+ .code = KEY_ADDRESSBOOK,
+ .desc = "Contacts",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(4),
+ .code = KEY_MAIL,
+ .desc = "Mail",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data n30_button_data = {
+ .buttons = n30_buttons,
+ .nbuttons = ARRAY_SIZE(n30_buttons),
+};
+
+static struct platform_device n30_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &n30_button_data,
+ }
+};
+
+static struct gpio_keys_button n35_buttons[] = {
+ {
+ .gpio = S3C2410_GPF(0),
+ .code = KEY_POWER,
+ .type = EV_PWR,
+ .desc = "Power",
+ .active_low = 0,
+ .wakeup = 1,
+ },
+ {
+ .gpio = S3C2410_GPG(9),
+ .code = KEY_UP,
+ .desc = "Joystick Up",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(8),
+ .code = KEY_DOWN,
+ .desc = "Joystick Down",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(6),
+ .code = KEY_DOWN,
+ .desc = "Joystick Left",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(5),
+ .code = KEY_DOWN,
+ .desc = "Joystick Right",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(7),
+ .code = KEY_ENTER,
+ .desc = "Joystick Press",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(7),
+ .code = KEY_HOMEPAGE,
+ .desc = "Home",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(6),
+ .code = KEY_CALENDAR,
+ .desc = "Calendar",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(5),
+ .code = KEY_ADDRESSBOOK,
+ .desc = "Contacts",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(4),
+ .code = KEY_MAIL,
+ .desc = "Mail",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPF(3),
+ .code = SW_RADIO,
+ .desc = "GPS Antenna",
+ .active_low = 0,
+ },
+ {
+ .gpio = S3C2410_GPG(2),
+ .code = SW_HEADPHONE_INSERT,
+ .desc = "Headphone",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data n35_button_data = {
+ .buttons = n35_buttons,
+ .nbuttons = ARRAY_SIZE(n35_buttons),
+};
+
+static struct platform_device n35_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &n35_button_data,
+ }
+};
+
+/* This is the bluetooth LED on the device. */
+static struct s3c24xx_led_platdata n30_blue_led_pdata = {
+ .name = "blue_led",
+ .gpio = S3C2410_GPG(6),
+ .def_trigger = "",
+};
+
+/* This is the blue LED on the device. Originally used to indicate GPS activity
+ * by flashing. */
+static struct s3c24xx_led_platdata n35_blue_led_pdata = {
+ .name = "blue_led",
+ .gpio = S3C2410_GPD(8),
+ .def_trigger = "",
+};
+
+/* This LED is driven by the battery microcontroller, and is blinking
+ * red, blinking green or solid green when the battery is low,
+ * charging or full respectively. By driving GPD9 low, it's possible
+ * to force the LED to blink red, so call that warning LED. */
+static struct s3c24xx_led_platdata n30_warning_led_pdata = {
+ .name = "warning_led",
+ .flags = S3C24XX_LEDF_ACTLOW,
+ .gpio = S3C2410_GPD(9),
+ .def_trigger = "",
+};
+
+static struct s3c24xx_led_platdata n35_warning_led_pdata = {
+ .name = "warning_led",
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .gpio = S3C2410_GPD(9),
+ .def_trigger = "",
+};
+
+static struct platform_device n30_blue_led = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &n30_blue_led_pdata,
+ },
+};
+
+static struct platform_device n35_blue_led = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &n35_blue_led_pdata,
+ },
+};
+
+static struct platform_device n30_warning_led = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &n30_warning_led_pdata,
+ },
+};
+
+static struct platform_device n35_warning_led = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &n35_warning_led_pdata,
+ },
+};
+
+static struct s3c2410fb_display n30_display __initdata = {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 170000,
+
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 3,
+ .right_margin = 40,
+ .hsync_len = 40,
+ .upper_margin = 2,
+ .lower_margin = 3,
+ .vsync_len = 2,
+
+ .lcdcon5 = S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
+};
+
+static struct s3c2410fb_mach_info n30_fb_info __initdata = {
+ .displays = &n30_display,
+ .num_displays = 1,
+ .default_display = 0,
+ .lpcsel = 0x06,
+};
+
+static void n30_sdi_set_power(unsigned char power_mode, unsigned short vdd)
+{
+ switch (power_mode) {
+ case MMC_POWER_ON:
+ case MMC_POWER_UP:
+ gpio_set_value(S3C2410_GPG(4), 1);
+ break;
+ case MMC_POWER_OFF:
+ default:
+ gpio_set_value(S3C2410_GPG(4), 0);
+ break;
+ }
+}
+
+static struct s3c24xx_mci_pdata n30_mci_cfg __initdata = {
+ .gpio_detect = S3C2410_GPF(1),
+ .gpio_wprotect = S3C2410_GPG(10),
+ .ocr_avail = MMC_VDD_32_33,
+ .set_power = n30_sdi_set_power,
+};
+
+static struct platform_device *n30_devices[] __initdata = {
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &n30_button_device,
+ &n30_blue_led,
+ &n30_warning_led,
+};
+
+static struct platform_device *n35_devices[] __initdata = {
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_rtc,
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &n35_button_device,
+ &n35_blue_led,
+ &n35_warning_led,
+};
+
+static struct s3c2410_platform_i2c __initdata n30_i2ccfg = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 10*1000,
+};
+
+/* Lots of hardcoded stuff, but it sets up the hardware in a useful
+ * state so that we can boot Linux directly from flash. */
+static void __init n30_hwinit(void)
+{
+ /* GPA0-11 special functions -- unknown what they do
+ * GPA12 N30 special function -- unknown what it does
+ * N35/PiN output -- unknown what it does
+ *
+ * A12 is nGCS1 on the N30 and an output on the N35/PiN. I
+ * don't think it does anything useful on the N30, so I ought
+ * to make it an output there too since it always driven to 0
+ * as far as I can tell. */
+ if (machine_is_n30())
+ __raw_writel(0x007fffff, S3C2410_GPACON);
+ if (machine_is_n35())
+ __raw_writel(0x007fefff, S3C2410_GPACON);
+ __raw_writel(0x00000000, S3C2410_GPADAT);
+
+ /* GPB0 TOUT0 backlight level
+ * GPB1 output 1=backlight on
+ * GPB2 output IrDA enable 0=transceiver enabled, 1=disabled
+ * GPB3 output USB D+ pull up 0=disabled, 1=enabled
+ * GPB4 N30 output -- unknown function
+ * N30/PiN GPS control 0=GPS enabled, 1=GPS disabled
+ * GPB5 output -- unknown function
+ * GPB6 input -- unknown function
+ * GPB7 output -- unknown function
+ * GPB8 output -- probably LCD driver enable
+ * GPB9 output -- probably LCD VSYNC driver enable
+ * GPB10 output -- probably LCD HSYNC driver enable
+ */
+ __raw_writel(0x00154556, S3C2410_GPBCON);
+ __raw_writel(0x00000750, S3C2410_GPBDAT);
+ __raw_writel(0x00000073, S3C2410_GPBUP);
+
+ /* GPC0 input RS232 DCD/DSR/RI
+ * GPC1 LCD
+ * GPC2 output RS232 DTR?
+ * GPC3 input RS232 DCD/DSR/RI
+ * GPC4 LCD
+ * GPC5 output 0=NAND write enabled, 1=NAND write protect
+ * GPC6 input -- unknown function
+ * GPC7 input charger status 0=charger connected
+ * this input can be triggered by power on the USB device
+ * port too, but will go back to disconnected soon after.
+ * GPC8 N30/N35 output -- unknown function, always driven to 1
+ * PiN input -- unknown function, always read as 1
+ * Make it an input with a pull up for all models.
+ * GPC9-15 LCD
+ */
+ __raw_writel(0xaaa80618, S3C2410_GPCCON);
+ __raw_writel(0x0000014c, S3C2410_GPCDAT);
+ __raw_writel(0x0000fef2, S3C2410_GPCUP);
+
+ /* GPD0 input -- unknown function
+ * GPD1-D7 LCD
+ * GPD8 N30 output -- unknown function
+ * N35/PiN output 1=GPS LED on
+ * GPD9 output 0=power led blinks red, 1=normal power led function
+ * GPD10 output -- unknown function
+ * GPD11-15 LCD drivers
+ */
+ __raw_writel(0xaa95aaa4, S3C2410_GPDCON);
+ __raw_writel(0x00000601, S3C2410_GPDDAT);
+ __raw_writel(0x0000fbfe, S3C2410_GPDUP);
+
+ /* GPE0-4 I2S audio bus
+ * GPE5-10 SD/MMC bus
+ * E11-13 outputs -- unknown function, probably power management
+ * E14-15 I2C bus connected to the battery controller
+ */
+ __raw_writel(0xa56aaaaa, S3C2410_GPECON);
+ __raw_writel(0x0000efc5, S3C2410_GPEDAT);
+ __raw_writel(0x0000f81f, S3C2410_GPEUP);
+
+ /* GPF0 input 0=power button pressed
+ * GPF1 input SD/MMC switch 0=card present
+ * GPF2 N30 1=reset button pressed (inverted compared to the rest)
+ * N35/PiN 0=reset button pressed
+ * GPF3 N30/PiN input -- unknown function
+ * N35 input GPS antenna position, 0=antenna closed, 1=open
+ * GPF4 input 0=button 4 pressed
+ * GPF5 input 0=button 3 pressed
+ * GPF6 input 0=button 2 pressed
+ * GPF7 input 0=button 1 pressed
+ */
+ __raw_writel(0x0000aaaa, S3C2410_GPFCON);
+ __raw_writel(0x00000000, S3C2410_GPFDAT);
+ __raw_writel(0x000000ff, S3C2410_GPFUP);
+
+ /* GPG0 input RS232 DCD/DSR/RI
+ * GPG1 input 1=USB gadget port has power from a host
+ * GPG2 N30 input -- unknown function
+ * N35/PiN input 0=headphones plugged in, 1=not plugged in
+ * GPG3 N30 output -- unknown function
+ * N35/PiN input with unknown function
+ * GPG4 N30 output 0=MMC enabled, 1=MMC disabled
+ * GPG5 N30 output 0=BlueTooth chip disabled, 1=enabled
+ * N35/PiN input joystick right
+ * GPG6 N30 output 0=blue led on, 1=off
+ * N35/PiN input joystick left
+ * GPG7 input 0=thumbwheel pressed
+ * GPG8 input 0=thumbwheel down
+ * GPG9 input 0=thumbwheel up
+ * GPG10 input SD/MMC write protect switch
+ * GPG11 N30 input -- unknown function
+ * N35 output 0=GPS antenna powered, 1=not powered
+ * PiN output -- unknown function
+ * GPG12-15 touch screen functions
+ *
+ * The pullups differ between the models, so enable all
+ * pullups that are enabled on any of the models.
+ */
+ if (machine_is_n30())
+ __raw_writel(0xff0a956a, S3C2410_GPGCON);
+ if (machine_is_n35())
+ __raw_writel(0xff4aa92a, S3C2410_GPGCON);
+ __raw_writel(0x0000e800, S3C2410_GPGDAT);
+ __raw_writel(0x0000f86f, S3C2410_GPGUP);
+
+ /* GPH0/1/2/3 RS232 serial port
+ * GPH4/5 IrDA serial port
+ * GPH6/7 N30 BlueTooth serial port
+ * N35/PiN GPS receiver
+ * GPH8 input -- unknown function
+ * GPH9 CLKOUT0 HCLK -- unknown use
+ * GPH10 CLKOUT1 FCLK -- unknown use
+ *
+ * The pull ups for H6/H7 are enabled on N30 but not on the
+ * N35/PiN. I suppose is useful for a budget model of the N30
+ * with no bluetooh. It doesn't hurt to have the pull ups
+ * enabled on the N35, so leave them enabled for all models.
+ */
+ __raw_writel(0x0028aaaa, S3C2410_GPHCON);
+ __raw_writel(0x000005ef, S3C2410_GPHDAT);
+ __raw_writel(0x0000063f, S3C2410_GPHUP);
+}
+
+static void __init n30_map_io(void)
+{
+ s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
+ n30_hwinit();
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+}
+
+/* GPB3 is the line that controls the pull-up for the USB D+ line */
+
+static void __init n30_init(void)
+{
+ WARN_ON(gpio_request(S3C2410_GPG(4), "mmc power"));
+
+ s3c24xx_fb_set_platdata(&n30_fb_info);
+ s3c24xx_udc_set_platdata(&n30_udc_cfg);
+ s3c24xx_mci_set_platdata(&n30_mci_cfg);
+ s3c_i2c0_set_platdata(&n30_i2ccfg);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ if (machine_is_n30()) {
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
+ }
+
+ if (machine_is_n35()) {
+ /* Turn off suspend and switch the selectable USB port
+ * to USB device mode. Turn on suspend for the host
+ * port since it is not connected on the N35.
+ *
+ * Actually, the host port is available at some pads
+ * on the back of the device, so it would actually be
+ * possible to add a USB device inside the N35 if you
+ * are willing to do some hardware modifications. */
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1,
+ S3C2410_MISCCR_USBSUSPND0);
+
+ platform_add_devices(n35_devices, ARRAY_SIZE(n35_devices));
+ }
+}
+
+MACHINE_START(N30, "Acer-N30")
+ /* Maintainer: Christer Weinigel <christer@weinigel.se>,
+ Ben Dooks <ben-linux@fluff.org>
+ */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .timer = &s3c24xx_timer,
+ .init_machine = n30_init,
+ .init_irq = s3c24xx_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
+
+MACHINE_START(N35, "Acer-N35")
+ /* Maintainer: Christer Weinigel <christer@weinigel.se>
+ */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .timer = &s3c24xx_timer,
+ .init_machine = n30_init,
+ .init_irq = s3c24xx_init_irq,
+ .map_io = n30_map_io,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
new file mode 100644
index 00000000..0aa16cd5
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -0,0 +1,124 @@
+/* linux/arch/arm/mach-s3c2410/mach-otom.c
+ *
+ * Copyright (c) 2004 Nex Vision
+ * Guillaume GOURAT <guillaume.gourat@nexvision.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/otom-map.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+#include <plat/cpu.h>
+
+static struct map_desc otom11_iodesc[] __initdata = {
+ /* Device area */
+ { (u32)OTOM_VA_CS8900A_BASE, OTOM_PA_CS8900A_BASE, SZ_16M, MT_DEVICE },
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg otom11_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ /* port 2 is not actually used */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+/* NOR Flash on NexVision OTOM board */
+
+static struct resource otom_nor_resource[] = {
+ [0] = {
+ .start = S3C2410_CS0,
+ .end = S3C2410_CS0 + (4*1024*1024) - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device otom_device_nor = {
+ .name = "mtd-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(otom_nor_resource),
+ .resource = otom_nor_resource,
+};
+
+/* Standard OTOM devices */
+
+static struct platform_device *otom11_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_rtc,
+ &otom_device_nor,
+};
+
+static void __init otom11_map_io(void)
+{
+ s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
+}
+
+static void __init otom11_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
+}
+
+MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
+ /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = otom11_map_io,
+ .init_machine = otom11_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
new file mode 100644
index 00000000..e8f49fee
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -0,0 +1,372 @@
+/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
+ *
+ * Copyright (C) 2006 by OpenMoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <plat/regs-serial.h>
+#include <mach/fb.h>
+#include <plat/nand.h>
+#include <plat/udc.h>
+#include <mach/spi.h>
+#include <mach/spi-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+static struct map_desc qt2410_iodesc[] __initdata = {
+ { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
+ {
+ /* Configuration for 640x480 SHARP LQ080V3DG01 */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 640,
+ .height = 480,
+
+ .pixclock = 40000, /* HCLK/4 */
+ .xres = 640,
+ .yres = 480,
+ .bpp = 16,
+ .left_margin = 44,
+ .right_margin = 116,
+ .hsync_len = 96,
+ .upper_margin = 19,
+ .lower_margin = 11,
+ .vsync_len = 15,
+ },
+ {
+ /* Configuration for 480x640 toppoly TD028TTEC1 */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 480,
+ .height = 640,
+ .pixclock = 40000, /* HCLK/4 */
+ .xres = 480,
+ .yres = 640,
+ .bpp = 16,
+ .left_margin = 8,
+ .right_margin = 24,
+ .hsync_len = 8,
+ .upper_margin = 2,
+ .lower_margin = 4,
+ .vsync_len = 2,
+ },
+ {
+ /* Config for 240x320 LCD */
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .pixclock = 100000, /* HCLK/10 */
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 13,
+ .right_margin = 8,
+ .hsync_len = 4,
+ .upper_margin = 2,
+ .lower_margin = 7,
+ .vsync_len = 4,
+ },
+};
+
+
+static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
+ .displays = qt2410_lcd_cfg,
+ .num_displays = ARRAY_SIZE(qt2410_lcd_cfg),
+ .default_display = 0,
+
+ .lpcsel = ((0xCE6) & ~7) | 1<<4,
+};
+
+/* CS8900 */
+
+static struct resource qt2410_cs89x0_resources[] = {
+ [0] = {
+ .start = 0x19000000,
+ .end = 0x19000000 + 16,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EINT9,
+ .end = IRQ_EINT9,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device qt2410_cs89x0 = {
+ .name = "cirrus-cs89x0",
+ .num_resources = ARRAY_SIZE(qt2410_cs89x0_resources),
+ .resource = qt2410_cs89x0_resources,
+};
+
+/* LED */
+
+static struct s3c24xx_led_platdata qt2410_pdata_led = {
+ .gpio = S3C2410_GPB(0),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led",
+ .def_trigger = "timer",
+};
+
+static struct platform_device qt2410_led = {
+ .name = "s3c24xx_led",
+ .id = 0,
+ .dev = {
+ .platform_data = &qt2410_pdata_led,
+ },
+};
+
+/* SPI */
+
+static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
+{
+ switch (cs) {
+ case BITBANG_CS_ACTIVE:
+ gpio_set_value(S3C2410_GPB(5), 0);
+ break;
+ case BITBANG_CS_INACTIVE:
+ gpio_set_value(S3C2410_GPB(5), 1);
+ break;
+ }
+}
+
+static struct s3c2410_spigpio_info spi_gpio_cfg = {
+ .pin_clk = S3C2410_GPG(7),
+ .pin_mosi = S3C2410_GPG(6),
+ .pin_miso = S3C2410_GPG(5),
+ .chip_select = &spi_gpio_cs,
+};
+
+
+static struct platform_device qt2410_spi = {
+ .name = "s3c24xx-spi-gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &spi_gpio_cfg,
+ },
+};
+
+/* Board devices */
+
+static struct platform_device *qt2410_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_sdi,
+ &s3c_device_usbgadget,
+ &qt2410_spi,
+ &qt2410_cs89x0,
+ &qt2410_led,
+};
+
+static struct mtd_partition __initdata qt2410_nand_part[] = {
+ [0] = {
+ .name = "U-Boot",
+ .size = 0x30000,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "U-Boot environment",
+ .offset = 0x30000,
+ .size = 0x4000,
+ },
+ [2] = {
+ .name = "kernel",
+ .offset = 0x34000,
+ .size = SZ_2M,
+ },
+ [3] = {
+ .name = "initrd",
+ .offset = 0x234000,
+ .size = SZ_4M,
+ },
+ [4] = {
+ .name = "jffs2",
+ .offset = 0x634000,
+ .size = 0x39cc000,
+ },
+};
+
+static struct s3c2410_nand_set __initdata qt2410_nand_sets[] = {
+ [0] = {
+ .name = "NAND",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(qt2410_nand_part),
+ .partitions = qt2410_nand_part,
+ },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+ */
+
+static struct s3c2410_platform_nand __initdata qt2410_nand_info = {
+ .tacls = 20,
+ .twrph0 = 60,
+ .twrph1 = 20,
+ .nr_sets = ARRAY_SIZE(qt2410_nand_sets),
+ .sets = qt2410_nand_sets,
+};
+
+/* UDC */
+
+static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
+};
+
+static char tft_type = 's';
+
+static int __init qt2410_tft_setup(char *str)
+{
+ tft_type = str[0];
+ return 1;
+}
+
+__setup("tft=", qt2410_tft_setup);
+
+static void __init qt2410_map_io(void)
+{
+ s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
+ s3c24xx_init_clocks(12*1000*1000);
+ s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+}
+
+static void __init qt2410_machine_init(void)
+{
+ s3c_nand_set_platdata(&qt2410_nand_info);
+
+ switch (tft_type) {
+ case 'p': /* production */
+ qt2410_fb_info.default_display = 1;
+ break;
+ case 'b': /* big */
+ qt2410_fb_info.default_display = 0;
+ break;
+ case 's': /* small */
+ default:
+ qt2410_fb_info.default_display = 2;
+ break;
+ }
+ s3c24xx_fb_set_platdata(&qt2410_fb_info);
+
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
+ s3c2410_gpio_setpin(S3C2410_GPB(0), 1);
+
+ s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
+ s3c_i2c0_set_platdata(NULL);
+
+ WARN_ON(gpio_request(S3C2410_GPB(5), "spi cs"));
+ gpio_direction_output(S3C2410_GPB(5), 1);
+
+ platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
+ s3c_pm_init();
+}
+
+MACHINE_START(QT2410, "QT2410")
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = qt2410_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = qt2410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
new file mode 100644
index 00000000..e17f0338
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -0,0 +1,121 @@
+/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
+ *
+ * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
+ *
+ * Copyright (C) 2004 by FS Forth-Systeme GmbH
+ * All rights reserved.
+ *
+ * @Author: Jonas Dietsche
+ *
+ * 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
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2410_iodesc[] __initdata = {
+ /* nothing here yet */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+static struct platform_device *smdk2410_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+};
+
+static void __init smdk2410_map_io(void)
+{
+ s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+}
+
+static void __init smdk2410_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
+ * to SMDK2410 */
+ /* Maintainer: Jonas Dietsche */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = smdk2410_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = smdk2410_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
new file mode 100644
index 00000000..43c2b831
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c
@@ -0,0 +1,154 @@
+/* linux/arch/arm/mach-s3c2410/mach-tct_hammer.c
+ *
+ * Copyright (c) 2007 TinCanTools
+ * David Anders <danders@amltd.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
+ *
+ * @History:
+ * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ ***********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/flash.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+
+static struct resource tct_hammer_nor_resource = {
+ .start = 0x00000000,
+ .end = 0x01000000 - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mtd_partition tct_hammer_mtd_partitions[] = {
+ {
+ .name = "System",
+ .size = 0x240000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "JFFS2",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct physmap_flash_data tct_hammer_flash_data = {
+ .width = 2,
+ .parts = tct_hammer_mtd_partitions,
+ .nr_parts = ARRAY_SIZE(tct_hammer_mtd_partitions),
+};
+
+static struct platform_device tct_hammer_device_nor = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &tct_hammer_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &tct_hammer_nor_resource,
+};
+
+static struct map_desc tct_hammer_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg tct_hammer_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+
+static struct platform_device *tct_hammer_devices[] __initdata = {
+ &s3c_device_adc,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &s3c_device_usbgadget,
+ &s3c_device_sdi,
+ &tct_hammer_device_nor,
+};
+
+static void __init tct_hammer_map_io(void)
+{
+ s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
+}
+
+static void __init tct_hammer_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(tct_hammer_devices, ARRAY_SIZE(tct_hammer_devices));
+}
+
+MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = tct_hammer_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = tct_hammer_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
new file mode 100644
index 00000000..6ccce5a7
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -0,0 +1,408 @@
+/* linux/arch/arm/mach-s3c2410/mach-vr1000.c
+ *
+ * Copyright (c) 2003-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Machine support for Thorcom VR1000 board. Designed for Thorcom by
+ * Simtec Electronics, http://www.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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/dm9000.h>
+#include <linux/i2c.h>
+
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/vr1000-map.h>
+#include <mach/vr1000-irq.h>
+#include <mach/vr1000-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/audio-simtec.h>
+
+#include "usb-simtec.h"
+#include "nor-simtec.h"
+
+/* macros for virtual address mods for the io space entries */
+#define VA_C5(item) ((unsigned long)(item) + BAST_VAM_CS5)
+#define VA_C4(item) ((unsigned long)(item) + BAST_VAM_CS4)
+#define VA_C3(item) ((unsigned long)(item) + BAST_VAM_CS3)
+#define VA_C2(item) ((unsigned long)(item) + BAST_VAM_CS2)
+
+/* macros to modify the physical addresses for io space */
+
+#define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2))
+#define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3))
+#define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4))
+#define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5))
+
+static struct map_desc vr1000_iodesc[] __initdata = {
+ /* ISA IO areas */
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = PA_CS2(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = PA_CS3(BAST_PA_ISAIO),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+
+ /* CPLD control registers, and external interrupt controls */
+ {
+ .virtual = (u32)VR1000_VA_CTRL1,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL1),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL2,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL2),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL3,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)VR1000_VA_CTRL4,
+ .pfn = __phys_to_pfn(VR1000_PA_CTRL4),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+/* uart clock source(s) */
+
+static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0.
+ }
+};
+
+static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = vr1000_serial_clocks,
+ .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = vr1000_serial_clocks,
+ .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
+ },
+ /* port 2 is not actually used */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = vr1000_serial_clocks,
+ .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
+
+ }
+};
+
+/* definitions for the vr1000 extra 16550 serial ports */
+
+#define VR1000_BAUDBASE (3692307)
+
+#define VR1000_SERIAL_MAPBASE(x) (VR1000_PA_SERIAL + 0x80 + ((x) << 5))
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ [0] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(0),
+ .irq = IRQ_VR1000_SERIAL + 0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [1] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(1),
+ .irq = IRQ_VR1000_SERIAL + 1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [2] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(2),
+ .irq = IRQ_VR1000_SERIAL + 2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ [3] = {
+ .mapbase = VR1000_SERIAL_MAPBASE(3),
+ .irq = IRQ_VR1000_SERIAL + 3,
+ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+ .iotype = UPIO_MEM,
+ .regshift = 0,
+ .uartclk = VR1000_BAUDBASE,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+/* DM9000 ethernet devices */
+
+static struct resource vr1000_dm9k0_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + VR1000_PA_DM9000,
+ .end = S3C2410_CS5 + VR1000_PA_DM9000 + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x40,
+ .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x7f,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = IRQ_VR1000_DM9000A,
+ .end = IRQ_VR1000_DM9000A,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ }
+
+};
+
+static struct resource vr1000_dm9k1_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0x80,
+ .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0x83,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C2410_CS5 + VR1000_PA_DM9000 + 0xC0,
+ .end = S3C2410_CS5 + VR1000_PA_DM9000 + 0xFF,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = IRQ_VR1000_DM9000N,
+ .end = IRQ_VR1000_DM9000N,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ }
+};
+
+/* for the moment we limit ourselves to 16bit IO until some
+ * better IO routines can be written and tested
+*/
+
+static struct dm9000_plat_data vr1000_dm9k_platdata = {
+ .flags = DM9000_PLATF_16BITONLY,
+};
+
+static struct platform_device vr1000_dm9k0 = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(vr1000_dm9k0_resource),
+ .resource = vr1000_dm9k0_resource,
+ .dev = {
+ .platform_data = &vr1000_dm9k_platdata,
+ }
+};
+
+static struct platform_device vr1000_dm9k1 = {
+ .name = "dm9000",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(vr1000_dm9k1_resource),
+ .resource = vr1000_dm9k1_resource,
+ .dev = {
+ .platform_data = &vr1000_dm9k_platdata,
+ }
+};
+
+/* LEDS */
+
+static struct s3c24xx_led_platdata vr1000_led1_pdata = {
+ .name = "led1",
+ .gpio = S3C2410_GPB(0),
+ .def_trigger = "",
+};
+
+static struct s3c24xx_led_platdata vr1000_led2_pdata = {
+ .name = "led2",
+ .gpio = S3C2410_GPB(1),
+ .def_trigger = "",
+};
+
+static struct s3c24xx_led_platdata vr1000_led3_pdata = {
+ .name = "led3",
+ .gpio = S3C2410_GPB(2),
+ .def_trigger = "",
+};
+
+static struct platform_device vr1000_led1 = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &vr1000_led1_pdata,
+ },
+};
+
+static struct platform_device vr1000_led2 = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &vr1000_led2_pdata,
+ },
+};
+
+static struct platform_device vr1000_led3 = {
+ .name = "s3c24xx_led",
+ .id = 3,
+ .dev = {
+ .platform_data = &vr1000_led3_pdata,
+ },
+};
+
+/* I2C devices. */
+
+static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ }, {
+ I2C_BOARD_INFO("tmp101", 0x48),
+ }, {
+ I2C_BOARD_INFO("m41st87", 0x68),
+ },
+};
+
+/* devices for this board */
+
+static struct platform_device *vr1000_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_adc,
+ &serial_device,
+ &vr1000_dm9k0,
+ &vr1000_dm9k1,
+ &vr1000_led1,
+ &vr1000_led2,
+ &vr1000_led3,
+};
+
+static struct clk *vr1000_clocks[] __initdata = {
+ &s3c24xx_dclk0,
+ &s3c24xx_dclk1,
+ &s3c24xx_clkout0,
+ &s3c24xx_clkout1,
+ &s3c24xx_uclk,
+};
+
+static void vr1000_power_off(void)
+{
+ gpio_direction_output(S3C2410_GPB(9), 1);
+}
+
+static void __init vr1000_map_io(void)
+{
+ /* initialise clock sources */
+
+ s3c24xx_dclk0.parent = &clk_upll;
+ s3c24xx_dclk0.rate = 12*1000*1000;
+
+ s3c24xx_dclk1.parent = NULL;
+ s3c24xx_dclk1.rate = 3692307;
+
+ s3c24xx_clkout0.parent = &s3c24xx_dclk0;
+ s3c24xx_clkout1.parent = &s3c24xx_dclk1;
+
+ s3c24xx_uclk.parent = &s3c24xx_clkout1;
+
+ s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+
+ pm_power_off = vr1000_power_off;
+
+ s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+}
+
+static void __init vr1000_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
+
+ i2c_register_board_info(0, vr1000_i2c_devs,
+ ARRAY_SIZE(vr1000_i2c_devs));
+
+ nor_simtec_init();
+ simtec_audio_add(NULL, true, NULL);
+
+ WARN_ON(gpio_request(S3C2410_GPB(9), "power off"));
+}
+
+MACHINE_START(VR1000, "Thorcom-VR1000")
+ /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = vr1000_map_io,
+ .init_machine = vr1000_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2410/nor-simtec.c b/arch/arm/mach-s3c2410/nor-simtec.c
new file mode 100644
index 00000000..ad9f750f
--- /dev/null
+++ b/arch/arm/mach-s3c2410/nor-simtec.c
@@ -0,0 +1,87 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec NOR mapping
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/map.h>
+#include <mach/bast-map.h>
+#include <mach/bast-cpld.h>
+
+#include "nor-simtec.h"
+
+static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
+{
+ unsigned int val;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ val = __raw_readb(BAST_VA_CTRL3);
+
+ printk(KERN_DEBUG "%s(%d)\n", __func__, vpp);
+
+ if (vpp)
+ val |= BAST_CPLD_CTRL3_ROMWEN;
+ else
+ val &= ~BAST_CPLD_CTRL3_ROMWEN;
+
+ __raw_writeb(val, BAST_VA_CTRL3);
+ local_irq_restore(flags);
+}
+
+static struct physmap_flash_data simtec_nor_pdata = {
+ .width = 2,
+ .set_vpp = simtec_nor_vpp,
+ .nr_parts = 0,
+};
+
+static struct resource simtec_nor_resource[] = {
+ [0] = {
+ .start = S3C2410_CS1 + 0x4000000,
+ .end = S3C2410_CS1 + 0x4000000 + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device simtec_device_nor = {
+ .name = "physmap-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(simtec_nor_resource),
+ .resource = simtec_nor_resource,
+ .dev = {
+ .platform_data = &simtec_nor_pdata,
+ },
+};
+
+void __init nor_simtec_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&simtec_device_nor);
+ if (ret < 0)
+ printk(KERN_ERR "failed to register physmap-flash device\n");
+ else
+ simtec_nor_vpp(NULL, 1);
+}
diff --git a/arch/arm/mach-s3c2410/nor-simtec.h b/arch/arm/mach-s3c2410/nor-simtec.h
new file mode 100644
index 00000000..f619c1e0
--- /dev/null
+++ b/arch/arm/mach-s3c2410/nor-simtec.h
@@ -0,0 +1,14 @@
+/* linux/arch/arm/mach-s3c2410/nor-simtec.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec NOR mapping
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void nor_simtec_init(void);
diff --git a/arch/arm/mach-s3c2410/pll.c b/arch/arm/mach-s3c2410/pll.c
new file mode 100644
index 00000000..8338865e
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pll.c
@@ -0,0 +1,95 @@
+/* arch/arm/mach-s3c2410/pll.c
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2410 CPU PLL tables
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table pll_vals_12MHz[] = {
+ { .frequency = 34000000, .index = PLLVAL(82, 2, 3), },
+ { .frequency = 45000000, .index = PLLVAL(82, 1, 3), },
+ { .frequency = 51000000, .index = PLLVAL(161, 3, 3), },
+ { .frequency = 48000000, .index = PLLVAL(120, 2, 3), },
+ { .frequency = 56000000, .index = PLLVAL(142, 2, 3), },
+ { .frequency = 68000000, .index = PLLVAL(82, 2, 2), },
+ { .frequency = 79000000, .index = PLLVAL(71, 1, 2), },
+ { .frequency = 85000000, .index = PLLVAL(105, 2, 2), },
+ { .frequency = 90000000, .index = PLLVAL(112, 2, 2), },
+ { .frequency = 101000000, .index = PLLVAL(127, 2, 2), },
+ { .frequency = 113000000, .index = PLLVAL(105, 1, 2), },
+ { .frequency = 118000000, .index = PLLVAL(150, 2, 2), },
+ { .frequency = 124000000, .index = PLLVAL(116, 1, 2), },
+ { .frequency = 135000000, .index = PLLVAL(82, 2, 1), },
+ { .frequency = 147000000, .index = PLLVAL(90, 2, 1), },
+ { .frequency = 152000000, .index = PLLVAL(68, 1, 1), },
+ { .frequency = 158000000, .index = PLLVAL(71, 1, 1), },
+ { .frequency = 170000000, .index = PLLVAL(77, 1, 1), },
+ { .frequency = 180000000, .index = PLLVAL(82, 1, 1), },
+ { .frequency = 186000000, .index = PLLVAL(85, 1, 1), },
+ { .frequency = 192000000, .index = PLLVAL(88, 1, 1), },
+ { .frequency = 203000000, .index = PLLVAL(161, 3, 1), },
+
+ /* 2410A extras */
+
+ { .frequency = 210000000, .index = PLLVAL(132, 2, 1), },
+ { .frequency = 226000000, .index = PLLVAL(105, 1, 1), },
+ { .frequency = 266000000, .index = PLLVAL(125, 1, 1), },
+ { .frequency = 268000000, .index = PLLVAL(126, 1, 1), },
+ { .frequency = 270000000, .index = PLLVAL(127, 1, 1), },
+};
+
+static int s3c2410_plls_add(struct sys_device *dev)
+{
+ return s3c_plltab_register(pll_vals_12MHz, ARRAY_SIZE(pll_vals_12MHz));
+}
+
+static struct sysdev_driver s3c2410_plls_drv = {
+ .add = s3c2410_plls_add,
+};
+
+static int __init s3c2410_pll_init(void)
+{
+ return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_plls_drv);
+
+}
+
+arch_initcall(s3c2410_pll_init);
+
+static struct sysdev_driver s3c2410a_plls_drv = {
+ .add = s3c2410_plls_add,
+};
+
+static int __init s3c2410a_pll_init(void)
+{
+ return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_plls_drv);
+}
+
+arch_initcall(s3c2410a_pll_init);
diff --git a/arch/arm/mach-s3c2410/pm-h1940.S b/arch/arm/mach-s3c2410/pm-h1940.S
new file mode 100644
index 00000000..c93bf2db
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pm-h1940.S
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-s3c2410/pm-h1940.S
+ *
+ * Copyright (c) 2006 Ben Dooks <ben-linux@fluff.org>
+ *
+ * H1940 Suspend to RAM
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+
+ .text
+ .global h1940_pm_return
+
+h1940_pm_return:
+ mov r0, #S3C2410_PA_GPIO
+ ldr pc, [ r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO ]
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
new file mode 100644
index 00000000..4728f9aa
--- /dev/null
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -0,0 +1,172 @@
+/* linux/arch/arm/mach-s3c2410/pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/h1940.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+static void s3c2410_pm_prepare(void)
+{
+ /* ensure at least GSTATUS3 has the resume address */
+
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2410_GSTATUS3);
+
+ S3C_PMDBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
+ S3C_PMDBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
+
+ if (machine_is_h1940()) {
+ void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+ unsigned long ptr;
+ unsigned long calc = 0;
+
+ /* generate check for the bootloader to check on resume */
+
+ for (ptr = 0; ptr < 0x40000; ptr += 0x400)
+ calc += __raw_readl(base+ptr);
+
+ __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+ }
+
+ /* RX3715 and RX1950 use similar to H1940 code and the
+ * same offsets for resume and checksum pointers */
+
+ if (machine_is_rx3715() || machine_is_rx1950()) {
+ void *base = phys_to_virt(H1940_SUSPEND_CHECK);
+ unsigned long ptr;
+ unsigned long calc = 0;
+
+ /* generate check for the bootloader to check on resume */
+
+ for (ptr = 0; ptr < 0x40000; ptr += 0x4)
+ calc += __raw_readl(base+ptr);
+
+ __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
+ }
+
+ if ( machine_is_aml_m5900() )
+ s3c2410_gpio_setpin(S3C2410_GPF(2), 1);
+
+ if (machine_is_rx1950()) {
+ /* According to S3C2442 user's manual, page 7-17,
+ * when the system is operating in NAND boot mode,
+ * the hardware pin configuration - EINT[23:21] –
+ * must be set as input for starting up after
+ * wakeup from sleep mode
+ */
+ s3c_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPIO_INPUT);
+ }
+}
+
+static void s3c2410_pm_resume(void)
+{
+ unsigned long tmp;
+
+ /* unset the return-from-sleep flag, to ensure reset */
+
+ tmp = __raw_readl(S3C2410_GSTATUS2);
+ tmp &= S3C2410_GSTATUS2_OFFRESET;
+ __raw_writel(tmp, S3C2410_GSTATUS2);
+
+ if ( machine_is_aml_m5900() )
+ s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+}
+
+struct syscore_ops s3c2410_pm_syscore_ops = {
+ .resume = s3c2410_pm_resume,
+};
+
+static int s3c2410_pm_add(struct sys_device *dev)
+{
+ pm_cpu_prep = s3c2410_pm_prepare;
+ pm_cpu_sleep = s3c2410_cpu_suspend;
+
+ return 0;
+}
+
+#if defined(CONFIG_CPU_S3C2410)
+static struct sysdev_driver s3c2410_pm_driver = {
+ .add = s3c2410_pm_add,
+};
+
+/* register ourselves */
+
+static int __init s3c2410_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
+}
+
+arch_initcall(s3c2410_pm_drvinit);
+
+static struct sysdev_driver s3c2410a_pm_driver = {
+ .add = s3c2410_pm_add,
+};
+
+static int __init s3c2410a_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_pm_driver);
+}
+
+arch_initcall(s3c2410a_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2440)
+static struct sysdev_driver s3c2440_pm_driver = {
+ .add = s3c2410_pm_add,
+};
+
+static int __init s3c2440_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
+}
+
+arch_initcall(s3c2440_pm_drvinit);
+#endif
+
+#if defined(CONFIG_CPU_S3C2442)
+static struct sysdev_driver s3c2442_pm_driver = {
+ .add = s3c2410_pm_add,
+};
+
+static int __init s3c2442_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
+}
+
+arch_initcall(s3c2442_pm_drvinit);
+#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
new file mode 100644
index 00000000..f1d3bd8f
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -0,0 +1,183 @@
+/* linux/arch/arm/mach-s3c2410/s3c2410.c
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+
+#include <plat/s3c2410.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pll.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2410_iodesc[] __initdata = {
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(WATCHDOG),
+};
+
+/* our uart devices */
+
+/* uart registration process */
+
+void __init s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2410-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2410_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2410_map_io(void)
+{
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+
+ iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
+}
+
+void __init_or_cpufreq s3c2410_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long tmp;
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long pclk;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ /* now we've got our machine bits initialised, work out what
+ * clocks we've got */
+
+ fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
+
+ tmp = __raw_readl(S3C2410_CLKDIVN);
+
+ /* work out clock scalings */
+
+ hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
+ pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
+
+ /* print brieft summary of clocks, etc */
+
+ printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+ print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+ /* initialise the clocks here, to allow other things like the
+ * console to use them
+ */
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+/* fake ARMCLK for use with cpufreq, etc. */
+
+static struct clk s3c2410_armclk = {
+ .name = "armclk",
+ .parent = &clk_f,
+ .id = -1,
+};
+
+void __init s3c2410_init_clocks(int xtal)
+{
+ s3c24xx_register_baseclocks(xtal);
+ s3c2410_setup_clocks();
+ s3c2410_baseclk_add();
+ s3c24xx_register_clock(&s3c2410_armclk);
+}
+
+struct sysdev_class s3c2410_sysclass = {
+ .name = "s3c2410-core",
+};
+
+/* Note, we would have liked to name this s3c2410-core, but we cannot
+ * register two sysdev_class with the same name.
+ */
+struct sysdev_class s3c2410a_sysclass = {
+ .name = "s3c2410a-core",
+};
+
+static struct sys_device s3c2410_sysdev = {
+ .cls = &s3c2410_sysclass,
+};
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2410 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2410_core_init(void)
+{
+ return sysdev_class_register(&s3c2410_sysclass);
+}
+
+core_initcall(s3c2410_core_init);
+
+static int __init s3c2410a_core_init(void)
+{
+ return sysdev_class_register(&s3c2410a_sysclass);
+}
+
+core_initcall(s3c2410a_core_init);
+
+int __init s3c2410_init(void)
+{
+ printk("S3C2410: Initialising architecture\n");
+
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+ return sysdev_register(&s3c2410_sysdev);
+}
+
+int __init s3c2410a_init(void)
+{
+ s3c2410_sysdev.cls = &s3c2410a_sysclass;
+ return s3c2410_init();
+}
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
new file mode 100644
index 00000000..dd5b6388
--- /dev/null
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2410/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * 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 <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-serial.h>
+
+ /* s3c2410_cpu_suspend
+ *
+ * put the cpu into sleep mode
+ */
+
+ENTRY(s3c2410_cpu_suspend)
+ @@ prepare cpu to sleep
+
+ ldr r4, =S3C2410_REFRESH
+ ldr r5, =S3C24XX_MISCCR
+ ldr r6, =S3C2410_CLKCON
+ ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
+ ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
+ ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
+
+ orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
+ orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
+ orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
+
+ teq pc, #0 @ first as a trial-run to load cache
+ bl s3c2410_do_sleep
+ teq r0, r0 @ now do it for real
+ b s3c2410_do_sleep @
+
+ @@ align next bit of code to cache line
+ .align 5
+s3c2410_do_sleep:
+ streq r7, [ r4 ] @ SDRAM sleep command
+ streq r8, [ r5 ] @ SDRAM power-down config
+ streq r9, [ r6 ] @ CPU sleep
+1: beq 1b
+ mov pc, r14
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
new file mode 100644
index 00000000..29bd3d98
--- /dev/null
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -0,0 +1,132 @@
+/* linux/arch/arm/mach-s3c2410/usb-simtec.c
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * Simtec BAST and Thorcom VR1000 USB port support 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.
+*/
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/gpio.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/usb-control.h>
+#include <plat/devs.h>
+
+#include "usb-simtec.h"
+
+/* control power and monitor over-current events on various Simtec
+ * designed boards.
+*/
+
+static unsigned int power_state[2];
+
+static void
+usb_simtec_powercontrol(int port, int to)
+{
+ pr_debug("usb_simtec_powercontrol(%d,%d)\n", port, to);
+
+ power_state[port] = to;
+
+ if (power_state[0] && power_state[1])
+ gpio_set_value(S3C2410_GPB(4), 0);
+ else
+ gpio_set_value(S3C2410_GPB(4), 1);
+}
+
+static irqreturn_t
+usb_simtec_ocirq(int irq, void *pw)
+{
+ struct s3c2410_hcd_info *info = pw;
+
+ if (gpio_get_value(S3C2410_GPG(10)) == 0) {
+ pr_debug("usb_simtec: over-current irq (oc detected)\n");
+ s3c2410_usb_report_oc(info, 3);
+ } else {
+ pr_debug("usb_simtec: over-current irq (oc cleared)\n");
+ s3c2410_usb_report_oc(info, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on)
+{
+ int ret;
+
+ if (on) {
+ ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING,
+ "USB Over-current", info);
+ if (ret != 0) {
+ printk(KERN_ERR "failed to request usb oc irq\n");
+ }
+ } else {
+ free_irq(IRQ_USBOC, info);
+ }
+}
+
+static struct s3c2410_hcd_info usb_simtec_info __initdata = {
+ .port[0] = {
+ .flags = S3C_HCDFLG_USED
+ },
+ .port[1] = {
+ .flags = S3C_HCDFLG_USED
+ },
+
+ .power_control = usb_simtec_powercontrol,
+ .enable_oc = usb_simtec_enableoc,
+};
+
+
+int usb_simtec_init(void)
+{
+ int ret;
+
+ printk("USB Power Control, Copyright 2004 Simtec Electronics\n");
+
+ ret = gpio_request(S3C2410_GPB(4), "USB power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPB4\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_request(S3C2410_GPG(10), "USB overcurrent");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPG10\n", __func__);
+ gpio_free(S3C2410_GPB(4));
+ return ret;
+ }
+
+ /* turn power on */
+ gpio_direction_output(S3C2410_GPB(4), 1);
+ gpio_direction_input(S3C2410_GPG(10));
+
+ s3c_ohci_set_platdata(&usb_simtec_info);
+ return 0;
+}
diff --git a/arch/arm/mach-s3c2410/usb-simtec.h b/arch/arm/mach-s3c2410/usb-simtec.h
new file mode 100644
index 00000000..03842ede
--- /dev/null
+++ b/arch/arm/mach-s3c2410/usb-simtec.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s3c2410/usb-simtec.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.simtec.co.uk/products/EB2410ITX/
+ *
+ * Simtec BAST and Thorcom VR1000 USB port support 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.
+*/
+
+extern int usb_simtec_init(void);
+
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
new file mode 100644
index 00000000..e82ab4aa
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -0,0 +1,99 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2412
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM926T
+ select CPU_LLSERIAL_S3C2440
+ select S3C2412_PM if PM
+ select S3C2412_DMA if S3C2410_DMA
+ select S3C2410_GPIO
+ help
+ Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
+
+config CPU_S3C2412_ONLY
+ bool
+ depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
+ !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \
+ !CPU_S3C2443 && CPU_S3C2412
+ default y if CPU_S3C2412
+
+config S3C2412_DMA
+ bool
+ depends on CPU_S3C2412
+ help
+ Internal config node for S3C2412 DMA support
+
+config S3C2412_PM
+ bool
+ select S3C2412_PM_SLEEP
+ help
+ Internal config node to apply S3C2412 power management
+
+config S3C2412_PM_SLEEP
+ bool
+ help
+ Internal config node to apply sleep for S3C2412 power management.
+ Can be selected by another SoCs with similar sleep procedure.
+
+# Note, the S3C2412 IOtiming support is in plat-s3c24xx
+
+config S3C2412_CPUFREQ
+ bool
+ depends on CPU_FREQ_S3C24XX && CPU_S3C2412
+ select S3C2412_IOTIMING
+ default y
+ help
+ CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
+
+menu "S3C2412 Machines"
+
+config MACH_JIVE
+ bool "Logitech Jive"
+ select CPU_S3C2412
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Logitech Jive.
+
+config MACH_JIVE_SHOW_BOOTLOADER
+ bool "Allow access to bootloader partitions in MTD (EXPERIMENTAL)"
+ depends on MACH_JIVE && EXPERIMENTAL
+
+config MACH_SMDK2413
+ bool "SMDK2413"
+ select CPU_S3C2412
+ select MACH_S3C2413
+ select MACH_SMDK
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using an SMDK2413
+
+config MACH_S3C2413
+ bool
+ help
+ Internal node for S3C2413 version of SMDK2413, so that
+ machine_is_s3c2413() will work when MACH_SMDK2413 is
+ selected
+
+config MACH_SMDK2412
+ bool "SMDK2412"
+ select MACH_SMDK2413
+ help
+ Say Y here if you are using an SMDK2412
+
+ Note, this shares support with SMDK2413, so will automatically
+ select MACH_SMDK2413.
+
+config MACH_VSTMS
+ bool "VMSTMS"
+ select CPU_S3C2412
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using an VSTMS board
+
+endmenu
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
new file mode 100644
index 00000000..6c48a91e
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -0,0 +1,25 @@
+# arch/arm/mach-s3c2412/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
+obj-$(CONFIG_CPU_S3C2412) += irq.o
+obj-$(CONFIG_CPU_S3C2412) += clock.o
+obj-$(CONFIG_CPU_S3C2412) += gpio.o
+obj-$(CONFIG_S3C2412_DMA) += dma.o
+obj-$(CONFIG_S3C2412_PM) += pm.o
+obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
+obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_JIVE) += mach-jive.o
+obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
+obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
new file mode 100644
index 00000000..0c0505b0
--- /dev/null
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -0,0 +1,786 @@
+/* linux/arch/arm/mach-s3c2412/clock.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412,S3C2413 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+static int s3c2412_clkcon_enable(struct clk *clk, int enable)
+{
+ unsigned int clocks = clk->ctrlbit;
+ unsigned long clkcon;
+
+ clkcon = __raw_readl(S3C2410_CLKCON);
+
+ if (enable)
+ clkcon |= clocks;
+ else
+ clkcon &= ~clocks;
+
+ __raw_writel(clkcon, S3C2410_CLKCON);
+
+ return 0;
+}
+
+static int s3c2412_upll_enable(struct clk *clk, int enable)
+{
+ unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
+ unsigned long orig = upllcon;
+
+ if (!enable)
+ upllcon |= S3C2412_PLLCON_OFF;
+ else
+ upllcon &= ~S3C2412_PLLCON_OFF;
+
+ __raw_writel(upllcon, S3C2410_UPLLCON);
+
+ /* allow ~150uS for the PLL to settle and lock */
+
+ if (enable && (orig & S3C2412_PLLCON_OFF))
+ udelay(150);
+
+ return 0;
+}
+
+/* clock selections */
+
+static struct clk clk_erefclk = {
+ .name = "erefclk",
+ .id = -1,
+};
+
+static struct clk clk_urefclk = {
+ .name = "urefclk",
+ .id = -1,
+};
+
+static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_urefclk)
+ clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
+ else if (parent == &clk_upll)
+ clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+
+static struct clk clk_usysclk = {
+ .name = "usysclk",
+ .id = -1,
+ .parent = &clk_xtal,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_usysclk,
+ },
+};
+
+static struct clk clk_mrefclk = {
+ .name = "mrefclk",
+ .parent = &clk_xtal,
+ .id = -1,
+};
+
+static struct clk clk_mdivclk = {
+ .name = "mdivclk",
+ .parent = &clk_xtal,
+ .id = -1,
+};
+
+static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_usysclk)
+ clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
+ else if (parent == &clk_h)
+ clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+
+static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ div = parent_rate / rate;
+ if (div > 2)
+ div = 2;
+
+ return parent_rate / div;
+}
+
+static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+ return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
+}
+
+static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+ rate = s3c2412_roundrate_usbsrc(clk, rate);
+
+ if ((parent_rate / rate) == 2)
+ clkdivn |= S3C2412_CLKDIVN_USB48DIV;
+ else
+ clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
+
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+ return 0;
+}
+
+static struct clk clk_usbsrc = {
+ .name = "usbsrc",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_usbsrc,
+ .set_rate = s3c2412_setrate_usbsrc,
+ .round_rate = s3c2412_roundrate_usbsrc,
+ .set_parent = s3c2412_setparent_usbsrc,
+ },
+};
+
+static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_mdivclk)
+ clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
+ else if (parent == &clk_mpll)
+ clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+
+static struct clk clk_msysclk = {
+ .name = "msysclk",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_msysclk,
+ },
+};
+
+static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+ unsigned long clkdiv;
+ unsigned long dvs;
+
+ /* Note, we current equate fclk andf msysclk for S3C2412 */
+
+ if (parent == &clk_msysclk || parent == &clk_f)
+ dvs = 0;
+ else if (parent == &clk_h)
+ dvs = S3C2412_CLKDIVN_DVSEN;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ /* update this under irq lockdown, clkdivn is not protected
+ * by the clock system. */
+
+ local_irq_save(flags);
+
+ clkdiv = __raw_readl(S3C2410_CLKDIVN);
+ clkdiv &= ~S3C2412_CLKDIVN_DVSEN;
+ clkdiv |= dvs;
+ __raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk clk_armclk = {
+ .name = "armclk",
+ .id = -1,
+ .parent = &clk_msysclk,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2412_setparent_armclk,
+ },
+};
+
+/* these next clocks have an divider immediately after them,
+ * so we can register them with their divider and leave out the
+ * intermediate clock stage
+*/
+static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ /* note, we remove the +/- 1 calculations as they cancel out */
+
+ div = (rate / parent_rate);
+
+ if (div < 1)
+ div = 1;
+ else if (div > 16)
+ div = 16;
+
+ return parent_rate / div;
+}
+
+static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_erefclk)
+ clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
+ else if (parent == &clk_mpll)
+ clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+
+static unsigned long s3c2412_getrate_uart(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+ div &= S3C2412_CLKDIVN_UARTDIV_MASK;
+ div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+ return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+ rate = s3c2412_roundrate_clksrc(clk, rate);
+
+ clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
+ clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
+
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+ return 0;
+}
+
+static struct clk clk_uart = {
+ .name = "uartclk",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_uart,
+ .set_rate = s3c2412_setrate_uart,
+ .set_parent = s3c2412_setparent_uart,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
+};
+
+static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_erefclk)
+ clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
+ else if (parent == &clk_mpll)
+ clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+
+static unsigned long s3c2412_getrate_i2s(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+ div &= S3C2412_CLKDIVN_I2SDIV_MASK;
+ div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+ return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+ rate = s3c2412_roundrate_clksrc(clk, rate);
+
+ clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
+ clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
+
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+ return 0;
+}
+
+static struct clk clk_i2s = {
+ .name = "i2sclk",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_i2s,
+ .set_rate = s3c2412_setrate_i2s,
+ .set_parent = s3c2412_setparent_i2s,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
+};
+
+static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+
+ if (parent == &clk_usysclk)
+ clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
+ else if (parent == &clk_h)
+ clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ __raw_writel(clksrc, S3C2412_CLKSRC);
+ return 0;
+}
+static unsigned long s3c2412_getrate_cam(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2410_CLKDIVN);
+
+ div &= S3C2412_CLKDIVN_CAMDIV_MASK;
+ div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+ return parent_rate / (div + 1);
+}
+
+static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
+
+ rate = s3c2412_roundrate_clksrc(clk, rate);
+
+ clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
+ clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
+
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+ return 0;
+}
+
+static struct clk clk_cam = {
+ .name = "camif-upll", /* same as 2440 name */
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2412_getrate_cam,
+ .set_rate = s3c2412_setrate_cam,
+ .set_parent = s3c2412_setparent_cam,
+ .round_rate = s3c2412_roundrate_clksrc,
+ },
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_disable[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_NAND,
+ }, {
+ .name = "sdi",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_SDI,
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_ADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_IIC,
+ }, {
+ .name = "iis",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_IIS,
+ }, {
+ .name = "spi",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_SPI,
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "dma",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_DMA0,
+ }, {
+ .name = "dma",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_DMA1,
+ }, {
+ .name = "dma",
+ .id = 2,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_DMA2,
+ }, {
+ .name = "dma",
+ .id = 3,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_DMA3,
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_LCDC,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_USBH,
+ }, {
+ .name = "usb-device",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_USBD,
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_PWMT,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_UART2,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = 0,
+ }, {
+ .name = "usb-bus-gadget",
+ .id = -1,
+ .parent = &clk_usb_bus,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_USB_DEV48,
+ }, {
+ .name = "usb-bus-host",
+ .id = -1,
+ .parent = &clk_usb_bus,
+ .enable = s3c2412_clkcon_enable,
+ .ctrlbit = S3C2412_CLKCON_USB_HOST48,
+ }
+};
+
+/* clocks to add where we need to check their parentage */
+
+struct clk_init {
+ struct clk *clk;
+ unsigned int bit;
+ struct clk *src_0;
+ struct clk *src_1;
+};
+
+static struct clk_init clks_src[] __initdata = {
+ {
+ .clk = &clk_usysclk,
+ .bit = S3C2412_CLKSRC_USBCLK_HCLK,
+ .src_0 = &clk_urefclk,
+ .src_1 = &clk_upll,
+ }, {
+ .clk = &clk_i2s,
+ .bit = S3C2412_CLKSRC_I2SCLK_MPLL,
+ .src_0 = &clk_erefclk,
+ .src_1 = &clk_mpll,
+ }, {
+ .clk = &clk_cam,
+ .bit = S3C2412_CLKSRC_CAMCLK_HCLK,
+ .src_0 = &clk_usysclk,
+ .src_1 = &clk_h,
+ }, {
+ .clk = &clk_msysclk,
+ .bit = S3C2412_CLKSRC_MSYSCLK_MPLL,
+ .src_0 = &clk_mdivclk,
+ .src_1 = &clk_mpll,
+ }, {
+ .clk = &clk_uart,
+ .bit = S3C2412_CLKSRC_UARTCLK_MPLL,
+ .src_0 = &clk_erefclk,
+ .src_1 = &clk_mpll,
+ }, {
+ .clk = &clk_usbsrc,
+ .bit = S3C2412_CLKSRC_USBCLK_HCLK,
+ .src_0 = &clk_usysclk,
+ .src_1 = &clk_h,
+ /* here we assume OM[4] select xtal */
+ }, {
+ .clk = &clk_erefclk,
+ .bit = S3C2412_CLKSRC_EREFCLK_EXTCLK,
+ .src_0 = &clk_xtal,
+ .src_1 = &clk_ext,
+ }, {
+ .clk = &clk_urefclk,
+ .bit = S3C2412_CLKSRC_UREFCLK_EXTCLK,
+ .src_0 = &clk_xtal,
+ .src_1 = &clk_ext,
+ },
+};
+
+/* s3c2412_clk_initparents
+ *
+ * Initialise the parents for the clocks that we get at start-time
+*/
+
+static void __init s3c2412_clk_initparents(void)
+{
+ unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
+ struct clk_init *cip = clks_src;
+ struct clk *src;
+ int ptr;
+ int ret;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
+ ret = s3c24xx_register_clock(cip->clk);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ cip->clk->name, ret);
+ }
+
+ src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
+
+ printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
+ clk_set_parent(cip->clk, src);
+ }
+}
+
+/* clocks to add straight away */
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_usb_bus,
+ &clk_mrefclk,
+ &clk_armclk,
+};
+
+int __init s3c2412_baseclk_add(void)
+{
+ unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
+ unsigned int dvs;
+ struct clk *clkp;
+ int ret;
+ int ptr;
+
+ clk_upll.enable = s3c2412_upll_enable;
+ clk_usb_bus.parent = &clk_usbsrc;
+ clk_usb_bus.rate = 0x0;
+
+ clk_f.parent = &clk_msysclk;
+
+ s3c2412_clk_initparents();
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
+ clkp = clks[ptr];
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+
+ /* set the dvs state according to what we got at boot time */
+
+ dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN;
+
+ if (dvs)
+ clk_armclk.parent = &clk_h;
+
+ printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off");
+
+ /* ensure usb bus clock is within correct rate of 48MHz */
+
+ if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
+ printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
+
+ /* for the moment, let's use the UPLL, and see if we can
+ * get 48MHz */
+
+ clk_set_parent(&clk_usysclk, &clk_upll);
+ clk_set_parent(&clk_usbsrc, &clk_usysclk);
+ clk_set_rate(&clk_usbsrc, 48*1000*1000);
+ }
+
+ printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+ (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
+ print_mhz(clk_get_rate(&clk_upll)),
+ print_mhz(clk_get_rate(&clk_usb_bus)));
+
+ /* register clocks from clock array */
+
+ clkp = init_clocks;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+ /* ensure that we note the clock state */
+
+ clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+
+ /* We must be careful disabling the clocks we are not intending to
+ * be using at boot time, as subsystems such as the LCD which do
+ * their own DMA requests to the bus can cause the system to lockup
+ * if they where in the middle of requesting bus access.
+ *
+ * Disabling the LCD clock if the LCD is active is very dangerous,
+ * and therefore the bootloader should be careful to not enable
+ * the LCD clock if it is not needed.
+ */
+
+ /* install (and disable) the clocks we do not need immediately */
+
+ clkp = init_clocks_disable;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+
+ s3c2412_clkcon_enable(clkp, 0);
+ }
+
+ s3c_pwmclk_init();
+ return 0;
+}
diff --git a/arch/arm/mach-s3c2412/cpu-freq.c b/arch/arm/mach-s3c2412/cpu-freq.c
new file mode 100644
index 00000000..eb3ea172
--- /dev/null
+++ b/arch/arm/mach-s3c2412/cpu-freq.c
@@ -0,0 +1,257 @@
+/* linux/arch/arm/mach-s3c2412/cpu-freq.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 CPU Frequency scalling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2412-mem.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+/* our clock resources. */
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+ unsigned int hdiv, pdiv, armdiv, dvs;
+ unsigned long hclk, fclk, armclk, armdiv_clk;
+ unsigned long hclk_max;
+
+ fclk = cfg->freq.fclk;
+ armclk = cfg->freq.armclk;
+ hclk_max = cfg->max.hclk;
+
+ /* We can't run hclk above armclk as at the best we have to
+ * have armclk and hclk in dvs mode. */
+
+ if (hclk_max > armclk)
+ hclk_max = armclk;
+
+ s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
+ __func__, fclk, armclk, hclk_max);
+ s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
+ __func__, cfg->freq.fclk, cfg->freq.armclk,
+ cfg->freq.hclk, cfg->freq.pclk);
+
+ armdiv = fclk / armclk;
+
+ if (armdiv < 1)
+ armdiv = 1;
+ if (armdiv > 2)
+ armdiv = 2;
+
+ cfg->divs.arm_divisor = armdiv;
+ armdiv_clk = fclk / armdiv;
+
+ hdiv = armdiv_clk / hclk_max;
+ if (hdiv < 1)
+ hdiv = 1;
+
+ cfg->freq.hclk = hclk = armdiv_clk / hdiv;
+
+ /* set dvs depending on whether we reached armclk or not. */
+ cfg->divs.dvs = dvs = armclk < armdiv_clk;
+
+ /* update the actual armclk we achieved. */
+ cfg->freq.armclk = dvs ? hclk : armdiv_clk;
+
+ s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
+ __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
+
+ if (hdiv > 4)
+ goto invalid;
+
+ pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+ if ((hclk / pdiv) > cfg->max.pclk)
+ pdiv++;
+
+ cfg->freq.pclk = hclk / pdiv;
+
+ s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+ if (pdiv > 2)
+ goto invalid;
+
+ pdiv *= hdiv;
+
+ /* store the result, and then return */
+
+ cfg->divs.h_divisor = hdiv * armdiv;
+ cfg->divs.p_divisor = pdiv * armdiv;
+
+ return 0;
+
+ invalid:
+ return -EINVAL;
+}
+
+static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+ unsigned long clkdiv;
+ unsigned long olddiv;
+
+ olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
+
+ /* clear off current clock info */
+
+ clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
+ clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
+ clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
+
+ if (cfg->divs.arm_divisor == 2)
+ clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
+
+ clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
+
+ if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+ clkdiv |= S3C2412_CLKDIVN_PDIVN;
+
+ s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
+ __raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+ clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ struct s3c_cpufreq_board *board = cfg->board;
+ unsigned long refresh;
+
+ s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
+ board->refresh, cfg->freq.hclk);
+
+ /* Reduce both the refresh time (in ns) and the frequency (in MHz)
+ * by 10 each to ensure that we do not overflow 32 bit numbers. This
+ * should work for HCLK up to 133MHz and refresh period up to 30usec.
+ */
+
+ refresh = (board->refresh / 10);
+ refresh *= (cfg->freq.hclk / 100);
+ refresh /= (1 * 1000 * 1000); /* 10^6 */
+
+ s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
+ __raw_writel(refresh, S3C2412_REFRESH);
+}
+
+/* set the default cpu frequency information, based on an 200MHz part
+ * as we have no other way of detecting the speed rating in software.
+ */
+
+static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
+ .max = {
+ .fclk = 200000000,
+ .hclk = 100000000,
+ .pclk = 50000000,
+ },
+
+ .latency = 5000000, /* 5ms */
+
+ .locktime_m = 150,
+ .locktime_u = 150,
+ .locktime_bits = 16,
+
+ .name = "s3c2412",
+ .set_refresh = s3c2412_cpufreq_setrefresh,
+ .set_divs = s3c2412_cpufreq_setdivs,
+ .calc_divs = s3c2412_cpufreq_calcdivs,
+
+ .calc_iotiming = s3c2412_iotiming_calc,
+ .set_iotiming = s3c2412_iotiming_set,
+ .get_iotiming = s3c2412_iotiming_get,
+
+ .resume_clocks = s3c2412_setup_clocks,
+
+ .debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
+};
+
+static int s3c2412_cpufreq_add(struct sys_device *sysdev)
+{
+ unsigned long fclk_rate;
+
+ hclk = clk_get(NULL, "hclk");
+ if (IS_ERR(hclk)) {
+ printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
+ return -ENOENT;
+ }
+
+ fclk = clk_get(NULL, "fclk");
+ if (IS_ERR(fclk)) {
+ printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
+ goto err_fclk;
+ }
+
+ fclk_rate = clk_get_rate(fclk);
+ if (fclk_rate > 200000000) {
+ printk(KERN_INFO
+ "%s: fclk %ld MHz, assuming 266MHz capable part\n",
+ __func__, fclk_rate / 1000000);
+ s3c2412_cpufreq_info.max.fclk = 266000000;
+ s3c2412_cpufreq_info.max.hclk = 133000000;
+ s3c2412_cpufreq_info.max.pclk = 66000000;
+ }
+
+ armclk = clk_get(NULL, "armclk");
+ if (IS_ERR(armclk)) {
+ printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
+ goto err_armclk;
+ }
+
+ xtal = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal)) {
+ printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
+ goto err_xtal;
+ }
+
+ return s3c_cpufreq_register(&s3c2412_cpufreq_info);
+
+err_xtal:
+ clk_put(armclk);
+err_armclk:
+ clk_put(fclk);
+err_fclk:
+ clk_put(hclk);
+
+ return -ENOENT;
+}
+
+static struct sysdev_driver s3c2412_cpufreq_driver = {
+ .add = s3c2412_cpufreq_add,
+};
+
+static int s3c2412_cpufreq_init(void)
+{
+ return sysdev_driver_register(&s3c2412_sysclass,
+ &s3c2412_cpufreq_driver);
+}
+
+arch_initcall(s3c2412_cpufreq_init);
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
new file mode 100644
index 00000000..7abecfca
--- /dev/null
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -0,0 +1,195 @@
+/* linux/arch/arm/mach-s3c2412/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
+
+static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
+ [DMACH_XD0] = {
+ .name = "xdreq0",
+ .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ0),
+ },
+ [DMACH_XD1] = {
+ .name = "xdreq1",
+ .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_XDREQ1),
+ },
+ [DMACH_SDI] = {
+ .name = "sdi",
+ .channels = MAP(S3C2412_DMAREQSEL_SDI),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_SDI),
+ .hw_addr.to = S3C2410_PA_SDI + S3C2410_SDIDATA,
+ .hw_addr.from = S3C2410_PA_SDI + S3C2410_SDIDATA,
+ },
+ [DMACH_SPI0] = {
+ .name = "spi0",
+ .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_SPI0RX),
+ .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
+ },
+ [DMACH_SPI1] = {
+ .name = "spi1",
+ .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_SPI1RX),
+ .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT,
+ },
+ [DMACH_UART0] = {
+ .name = "uart0",
+ .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_0),
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1] = {
+ .name = "uart1",
+ .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_0),
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2] = {
+ .name = "uart2",
+ .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_0),
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_UART0_SRC2] = {
+ .name = "uart0",
+ .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART0_1),
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1_SRC2] = {
+ .name = "uart1",
+ .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART1_1),
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2_SRC2] = {
+ .name = "uart2",
+ .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_UART2_1),
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_TIMER] = {
+ .name = "timer",
+ .channels = MAP(S3C2412_DMAREQSEL_TIMER),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_TIMER),
+ },
+ [DMACH_I2S_IN] = {
+ .name = "i2s-sdi",
+ .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_I2SRX),
+ },
+ [DMACH_I2S_OUT] = {
+ .name = "i2s-sdo",
+ .channels = MAP(S3C2412_DMAREQSEL_I2STX),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_I2STX),
+ },
+ [DMACH_USB_EP1] = {
+ .name = "usb-ep1",
+ .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP1),
+ },
+ [DMACH_USB_EP2] = {
+ .name = "usb-ep2",
+ .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP2),
+ },
+ [DMACH_USB_EP3] = {
+ .name = "usb-ep3",
+ .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP3),
+ },
+ [DMACH_USB_EP4] = {
+ .name = "usb-ep4",
+ .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
+ .channels_rx = MAP(S3C2412_DMAREQSEL_USBEP4),
+ },
+};
+
+static void s3c2412_dma_direction(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map,
+ enum s3c2410_dmasrc dir)
+{
+ unsigned long chsel;
+
+ if (dir == S3C2410_DMASRC_HW)
+ chsel = map->channels_rx[0];
+ else
+ chsel = map->channels[0];
+
+ chsel &= ~DMA_CH_VALID;
+ chsel |= S3C2412_DMAREQSEL_HW;
+
+ writel(chsel, chan->regs + S3C2412_DMA_DMAREQSEL);
+}
+
+static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map)
+{
+ s3c2412_dma_direction(chan, map, chan->source);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
+ .select = s3c2412_dma_select,
+ .direction = s3c2412_dma_direction,
+ .dcon_mask = 0,
+ .map = s3c2412_dma_mappings,
+ .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
+};
+
+static int __init s3c2412_dma_add(struct sys_device *sysdev)
+{
+ s3c2410_dma_init();
+ return s3c24xx_dma_init_map(&s3c2412_dma_sel);
+}
+
+static struct sysdev_driver s3c2412_dma_driver = {
+ .add = s3c2412_dma_add,
+};
+
+static int __init s3c2412_dma_init(void)
+{
+ return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver);
+}
+
+arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c2412/gpio.c b/arch/arm/mach-s3c2412/gpio.c
new file mode 100644
index 00000000..3404a876
--- /dev/null
+++ b/arch/arm/mach-s3c2412/gpio.c
@@ -0,0 +1,62 @@
+/* linux/arch/arm/mach-s3c2412/gpio.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * S3C2412/S3C2413 specific GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/hardware.h>
+
+#include <plat/gpio-core.h>
+
+int s3c2412_gpio_set_sleepcfg(unsigned int pin, unsigned int state)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long offs = pin - chip->chip.base;
+ unsigned long flags;
+ unsigned long slpcon;
+
+ offs *= 2;
+
+ if (pin < S3C2410_GPB(0))
+ return -EINVAL;
+
+ if (pin >= S3C2410_GPF(0) &&
+ pin <= S3C2410_GPG(16))
+ return -EINVAL;
+
+ if (pin > S3C2410_GPH(16))
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ slpcon = __raw_readl(chip->base + 0x0C);
+
+ slpcon &= ~(3 << offs);
+ slpcon |= state << offs;
+
+ __raw_writel(slpcon, chip->base + 0x0C);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2412_gpio_set_sleepcfg);
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
new file mode 100644
index 00000000..1a1aa220
--- /dev/null
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -0,0 +1,212 @@
+/* linux/arch/arm/mach-s3c2412/irq.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-power.h>
+
+#include <plat/cpu.h>
+#include <plat/irq.h>
+#include <plat/pm.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
+
+/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
+ * having them turn up in both the INT* and the EINT* registers. Whilst
+ * both show the status, they both now need to be acked when the IRQs
+ * go off.
+*/
+
+static void
+s3c2412_irq_mask(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ __raw_writel(mask | bitval, S3C2410_INTMSK);
+
+ mask = __raw_readl(S3C2412_EINTMASK);
+ __raw_writel(mask | bitval, S3C2412_EINTMASK);
+}
+
+static inline void
+s3c2412_irq_ack(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+
+ __raw_writel(bitval, S3C2412_EINTPEND);
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c2412_irq_maskack(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+ mask = __raw_readl(S3C2412_EINTMASK);
+ __raw_writel(mask | bitval, S3C2412_EINTMASK);
+
+ __raw_writel(bitval, S3C2412_EINTPEND);
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static void
+s3c2412_irq_unmask(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2412_EINTMASK);
+ __raw_writel(mask & ~bitval, S3C2412_EINTMASK);
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ __raw_writel(mask & ~bitval, S3C2410_INTMSK);
+}
+
+static struct irq_chip s3c2412_irq_eint0t4 = {
+ .irq_ack = s3c2412_irq_ack,
+ .irq_mask = s3c2412_irq_mask,
+ .irq_unmask = s3c2412_irq_unmask,
+ .irq_set_wake = s3c_irq_wake,
+ .irq_set_type = s3c_irqext_type,
+};
+
+#define INTBIT(x) (1 << ((x) - S3C2410_IRQSUB(0)))
+
+/* CF and SDI sub interrupts */
+
+static void s3c2412_irq_demux_cfsdi(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+
+ if (subsrc & INTBIT(IRQ_S3C2412_SDI))
+ generic_handle_irq(IRQ_S3C2412_SDI);
+
+ if (subsrc & INTBIT(IRQ_S3C2412_CF))
+ generic_handle_irq(IRQ_S3C2412_CF);
+}
+
+#define INTMSK_CFSDI (1UL << (IRQ_S3C2412_CFSDI - IRQ_EINT0))
+#define SUBMSK_CFSDI INTMSK_SUB(IRQ_S3C2412_SDI, IRQ_S3C2412_CF)
+
+static void s3c2412_irq_cfsdi_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_CFSDI);
+}
+
+static void s3c2412_irq_cfsdi_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_CFSDI, SUBMSK_CFSDI);
+}
+
+static struct irq_chip s3c2412_irq_cfsdi = {
+ .name = "s3c2412-cfsdi",
+ .irq_ack = s3c2412_irq_cfsdi_ack,
+ .irq_mask = s3c2412_irq_cfsdi_mask,
+ .irq_unmask = s3c2412_irq_cfsdi_unmask,
+};
+
+static int s3c2412_irq_rtc_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long pwrcfg;
+
+ pwrcfg = __raw_readl(S3C2412_PWRCFG);
+ if (state)
+ pwrcfg &= ~S3C2412_PWRCFG_RTC_MASKIRQ;
+ else
+ pwrcfg |= S3C2412_PWRCFG_RTC_MASKIRQ;
+ __raw_writel(pwrcfg, S3C2412_PWRCFG);
+
+ return s3c_irq_chip.irq_set_wake(data, state);
+}
+
+static struct irq_chip s3c2412_irq_rtc_chip;
+
+static int s3c2412_irq_add(struct sys_device *sysdev)
+{
+ unsigned int irqno;
+
+ for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+ irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4,
+ handle_edge_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ /* add demux support for CF/SDI */
+
+ irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
+
+ for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
+ irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ /* change RTC IRQ's set wake method */
+
+ s3c2412_irq_rtc_chip = s3c_irq_chip;
+ s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
+
+ irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2412_irq_driver = {
+ .add = s3c2412_irq_add,
+};
+
+static int s3c2412_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_irq_driver);
+}
+
+arch_initcall(s3c2412_irq_init);
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
new file mode 100644
index 00000000..85dcaeb9
--- /dev/null
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -0,0 +1,677 @@
+/* linux/arch/arm/mach-s3c2410/mach-jive.c
+ *
+ * Copyright 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+
+#include <video/ili9320.h>
+
+#include <linux/spi/spi.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/spi-gpio.h>
+#include <mach/fb.h>
+
+#include <asm/mach-types.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+
+static struct map_desc jive_iodesc[] __initdata = {
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg jive_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+/* Jive flash assignment
+ *
+ * 0x00000000-0x00028000 : uboot
+ * 0x00028000-0x0002c000 : uboot env
+ * 0x0002c000-0x00030000 : spare
+ * 0x00030000-0x00200000 : zimage A
+ * 0x00200000-0x01600000 : cramfs A
+ * 0x01600000-0x017d0000 : zimage B
+ * 0x017d0000-0x02bd0000 : cramfs B
+ * 0x02bd0000-0x03fd0000 : yaffs
+ */
+static struct mtd_partition __initdata jive_imageA_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+ /* Don't allow access to the bootloader from linux */
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (160 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* spare */
+ {
+ .name = "spare",
+ .offset = (176 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+#endif
+
+ /* booted images */
+ {
+ .name = "kernel (ro)",
+ .offset = (192 * SZ_1K),
+ .size = (SZ_2M) - (192 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "root (ro)",
+ .offset = (SZ_2M),
+ .size = (20 * SZ_1M),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* yaffs */
+ {
+ .name = "yaffs",
+ .offset = (44 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+
+ /* bootloader environment */
+ {
+ .name = "env",
+ .offset = (160 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+
+ /* upgrade images */
+ {
+ .name = "zimage",
+ .offset = (22 * SZ_1M),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ }, {
+ .name = "cramfs",
+ .offset = (24 * SZ_1M) - (192*SZ_1K),
+ .size = (20 * SZ_1M),
+ },
+};
+
+static struct mtd_partition __initdata jive_imageB_nand_part[] = {
+
+#ifdef CONFIG_MACH_JIVE_SHOW_BOOTLOADER
+ /* Don't allow access to the bootloader from linux */
+ {
+ .name = "uboot",
+ .offset = 0,
+ .size = (160 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* spare */
+ {
+ .name = "spare",
+ .offset = (176 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+#endif
+
+ /* booted images */
+ {
+ .name = "kernel (ro)",
+ .offset = (22 * SZ_1M),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "root (ro)",
+ .offset = (24 * SZ_1M) - (192 * SZ_1K),
+ .size = (20 * SZ_1M),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+
+ /* yaffs */
+ {
+ .name = "yaffs",
+ .offset = (44 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+
+ /* bootloader environment */
+ {
+ .name = "env",
+ .offset = (160 * SZ_1K),
+ .size = (16 * SZ_1K),
+ },
+
+ /* upgrade images */
+ {
+ .name = "zimage",
+ .offset = (192 * SZ_1K),
+ .size = (2 * SZ_1M) - (192 * SZ_1K),
+ }, {
+ .name = "cramfs",
+ .offset = (2 * SZ_1M),
+ .size = (20 * SZ_1M),
+ },
+};
+
+static struct s3c2410_nand_set __initdata jive_nand_sets[] = {
+ [0] = {
+ .name = "flash",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(jive_imageA_nand_part),
+ .partitions = jive_imageA_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand __initdata jive_nand_info = {
+ /* set taken from osiris nand timings, possibly still conservative */
+ .tacls = 30,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .sets = jive_nand_sets,
+ .nr_sets = ARRAY_SIZE(jive_nand_sets),
+};
+
+static int __init jive_mtdset(char *options)
+{
+ struct s3c2410_nand_set *nand = &jive_nand_sets[0];
+ unsigned long set;
+
+ if (options == NULL || options[0] == '\0')
+ return 0;
+
+ if (strict_strtoul(options, 10, &set)) {
+ printk(KERN_ERR "failed to parse mtdset=%s\n", options);
+ return 0;
+ }
+
+ switch (set) {
+ case 1:
+ nand->nr_partitions = ARRAY_SIZE(jive_imageB_nand_part);
+ nand->partitions = jive_imageB_nand_part;
+ case 0:
+ /* this is already setup in the nand info */
+ break;
+ default:
+ printk(KERN_ERR "Unknown mtd set %ld specified,"
+ "using default.", set);
+ }
+
+ return 0;
+}
+
+/* parse the mtdset= option given to the kernel command line */
+__setup("mtdset=", jive_mtdset);
+
+/* LCD timing and setup */
+
+#define LCD_XRES (240)
+#define LCD_YRES (320)
+#define LCD_LEFT_MARGIN (12)
+#define LCD_RIGHT_MARGIN (12)
+#define LCD_LOWER_MARGIN (12)
+#define LCD_UPPER_MARGIN (12)
+#define LCD_VSYNC (2)
+#define LCD_HSYNC (2)
+
+#define LCD_REFRESH (60)
+
+#define LCD_HTOT (LCD_HSYNC + LCD_LEFT_MARGIN + LCD_XRES + LCD_RIGHT_MARGIN)
+#define LCD_VTOT (LCD_VSYNC + LCD_LOWER_MARGIN + LCD_YRES + LCD_UPPER_MARGIN)
+
+static struct s3c2410fb_display jive_vgg2432a4_display[] = {
+ [0] = {
+ .width = LCD_XRES,
+ .height = LCD_YRES,
+ .xres = LCD_XRES,
+ .yres = LCD_YRES,
+ .left_margin = LCD_LEFT_MARGIN,
+ .right_margin = LCD_RIGHT_MARGIN,
+ .upper_margin = LCD_UPPER_MARGIN,
+ .lower_margin = LCD_LOWER_MARGIN,
+ .hsync_len = LCD_HSYNC,
+ .vsync_len = LCD_VSYNC,
+
+ .pixclock = (1000000000000LL /
+ (LCD_REFRESH * LCD_HTOT * LCD_VTOT)),
+
+ .bpp = 16,
+ .type = (S3C2410_LCDCON1_TFT16BPP |
+ S3C2410_LCDCON1_TFT),
+
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_INVVDEN |
+ S3C2410_LCDCON5_PWREN),
+ },
+};
+
+/* todo - put into gpio header */
+
+#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
+#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
+
+static struct s3c2410fb_mach_info jive_lcd_config = {
+ .displays = jive_vgg2432a4_display,
+ .num_displays = ARRAY_SIZE(jive_vgg2432a4_display),
+ .default_display = 0,
+
+ /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
+ * and disable the pull down resistors on pins we are using for LCD
+ * data. */
+
+ .gpcup = (0xf << 1) | (0x3f << 10),
+
+ .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE |
+ S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
+ S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 |
+ S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 |
+ S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7),
+
+ .gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) |
+ S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) |
+ S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
+ S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
+ S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
+
+ .gpdup = (0x3f << 2) | (0x3f << 10),
+
+ .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 |
+ S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 |
+ S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 |
+ S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
+ S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
+ S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
+
+ .gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) |
+ S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) |
+ S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) |
+ S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
+ S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
+ S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
+};
+
+/* ILI9320 support. */
+
+static void jive_lcm_reset(unsigned int set)
+{
+ printk(KERN_DEBUG "%s(%d)\n", __func__, set);
+
+ gpio_set_value(S3C2410_GPG(13), set);
+}
+
+#undef LCD_UPPER_MARGIN
+#define LCD_UPPER_MARGIN 2
+
+static struct ili9320_platdata jive_lcm_config = {
+ .hsize = LCD_XRES,
+ .vsize = LCD_YRES,
+
+ .reset = jive_lcm_reset,
+ .suspend = ILI9320_SUSPEND_DEEP,
+
+ .entry_mode = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
+ .display2 = (ILI9320_DISPLAY2_FP(LCD_UPPER_MARGIN) |
+ ILI9320_DISPLAY2_BP(LCD_LOWER_MARGIN)),
+ .display3 = 0x0,
+ .display4 = 0x0,
+ .rgb_if1 = (ILI9320_RGBIF1_RIM_RGB18 |
+ ILI9320_RGBIF1_RM | ILI9320_RGBIF1_CLK_RGBIF),
+ .rgb_if2 = ILI9320_RGBIF2_DPL,
+ .interface2 = 0x0,
+ .interface3 = 0x3,
+ .interface4 = (ILI9320_INTERFACE4_RTNE(16) |
+ ILI9320_INTERFACE4_DIVE(1)),
+ .interface5 = 0x0,
+ .interface6 = 0x0,
+};
+
+/* LCD SPI support */
+
+static void jive_lcd_spi_chipselect(struct s3c2410_spigpio_info *spi, int cs)
+{
+ gpio_set_value(S3C2410_GPB(7), cs ? 0 : 1);
+}
+
+static struct s3c2410_spigpio_info jive_lcd_spi = {
+ .bus_num = 1,
+ .pin_clk = S3C2410_GPG(8),
+ .pin_mosi = S3C2410_GPB(8),
+ .num_chipselect = 1,
+ .chip_select = jive_lcd_spi_chipselect,
+};
+
+static struct platform_device jive_device_lcdspi = {
+ .name = "spi_s3c24xx_gpio",
+ .id = 1,
+ .num_resources = 0,
+ .dev.platform_data = &jive_lcd_spi,
+};
+
+/* WM8750 audio code SPI definition */
+
+static void jive_wm8750_chipselect(struct s3c2410_spigpio_info *spi, int cs)
+{
+ gpio_set_value(S3C2410_GPH(10), cs ? 0 : 1);
+}
+
+static struct s3c2410_spigpio_info jive_wm8750_spi = {
+ .bus_num = 2,
+ .pin_clk = S3C2410_GPB(4),
+ .pin_mosi = S3C2410_GPB(9),
+ .num_chipselect = 1,
+ .chip_select = jive_wm8750_chipselect,
+};
+
+static struct platform_device jive_device_wm8750 = {
+ .name = "spi_s3c24xx_gpio",
+ .id = 2,
+ .num_resources = 0,
+ .dev.platform_data = &jive_wm8750_spi,
+};
+
+/* JIVE SPI devices. */
+
+static struct spi_board_info __initdata jive_spi_devs[] = {
+ [0] = {
+ .modalias = "VGG2432A4",
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_3, /* CPOL=1, CPHA=1 */
+ .max_speed_hz = 100000,
+ .platform_data = &jive_lcm_config,
+ }, {
+ .modalias = "WM8750",
+ .bus_num = 2,
+ .chip_select = 0,
+ .mode = SPI_MODE_0, /* CPOL=0, CPHA=0 */
+ .max_speed_hz = 100000,
+ },
+};
+
+/* I2C bus and device configuration. */
+
+static struct s3c2410_platform_i2c jive_i2c_cfg __initdata = {
+ .frequency = 80 * 1000,
+ .flags = S3C_IICFLG_FILTER,
+ .sda_delay = 2,
+};
+
+static struct i2c_board_info jive_i2c_devs[] __initdata = {
+ [0] = {
+ I2C_BOARD_INFO("lis302dl", 0x1c),
+ .irq = IRQ_EINT14,
+ },
+};
+
+/* The platform devices being used. */
+
+static struct platform_device *jive_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_lcd,
+ &jive_device_lcdspi,
+ &jive_device_wm8750,
+ &s3c_device_nand,
+ &s3c_device_usbgadget,
+};
+
+static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
+ .vbus_pin = S3C2410_GPG(1), /* detect is on GPG1 */
+};
+
+/* Jive power management device */
+
+#ifdef CONFIG_PM
+static int jive_pm_suspend(void)
+{
+ /* Write the magic value u-boot uses to check for resume into
+ * the INFORM0 register, and ensure INFORM1 is set to the
+ * correct address to resume from. */
+
+ __raw_writel(0x2BED, S3C2412_INFORM0);
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+
+ return 0;
+}
+
+static void jive_pm_resume(void)
+{
+ __raw_writel(0x0, S3C2412_INFORM0);
+}
+
+#else
+#define jive_pm_suspend NULL
+#define jive_pm_resume NULL
+#endif
+
+static struct syscore_ops jive_pm_syscore_ops = {
+ .suspend = jive_pm_suspend,
+ .resume = jive_pm_resume,
+};
+
+static void __init jive_map_io(void)
+{
+ s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+}
+
+static void jive_power_off(void)
+{
+ printk(KERN_INFO "powering system down...\n");
+
+ s3c2410_gpio_setpin(S3C2410_GPC(5), 1);
+ s3c_gpio_cfgpin(S3C2410_GPC(5), S3C2410_GPIO_OUTPUT);
+}
+
+static void __init jive_machine_init(void)
+{
+ /* register system core operations for managing low level suspend */
+
+ register_syscore_ops(&jive_pm_syscore_ops);
+
+ /* write our sleep configurations for the IO. Pull down all unused
+ * IO, ensure that we have turned off all peripherals we do not
+ * need, and configure the ones we do need. */
+
+ /* Port B sleep */
+
+ __raw_writel(S3C2412_SLPCON_IN(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_HIGH(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_HIGH(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_PULL(10), S3C2412_GPBSLPCON);
+
+ /* Port C sleep */
+
+ __raw_writel(S3C2412_SLPCON_PULL(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_PULL(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_LOW(6) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_PULL(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_PULL(10) |
+ S3C2412_SLPCON_PULL(11) |
+ S3C2412_SLPCON_PULL(12) |
+ S3C2412_SLPCON_PULL(13) |
+ S3C2412_SLPCON_PULL(14) |
+ S3C2412_SLPCON_PULL(15), S3C2412_GPCSLPCON);
+
+ /* Port D sleep */
+
+ __raw_writel(S3C2412_SLPCON_ALL_PULL, S3C2412_GPDSLPCON);
+
+ /* Port F sleep */
+
+ __raw_writel(S3C2412_SLPCON_LOW(0) |
+ S3C2412_SLPCON_LOW(1) |
+ S3C2412_SLPCON_LOW(2) |
+ S3C2412_SLPCON_EINT(3) |
+ S3C2412_SLPCON_EINT(4) |
+ S3C2412_SLPCON_EINT(5) |
+ S3C2412_SLPCON_EINT(6) |
+ S3C2412_SLPCON_EINT(7), S3C2412_GPFSLPCON);
+
+ /* Port G sleep */
+
+ __raw_writel(S3C2412_SLPCON_IN(0) |
+ S3C2412_SLPCON_IN(1) |
+ S3C2412_SLPCON_IN(2) |
+ S3C2412_SLPCON_IN(3) |
+ S3C2412_SLPCON_IN(4) |
+ S3C2412_SLPCON_IN(5) |
+ S3C2412_SLPCON_IN(6) |
+ S3C2412_SLPCON_IN(7) |
+ S3C2412_SLPCON_PULL(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_IN(10) |
+ S3C2412_SLPCON_PULL(11) |
+ S3C2412_SLPCON_PULL(12) |
+ S3C2412_SLPCON_PULL(13) |
+ S3C2412_SLPCON_IN(14) |
+ S3C2412_SLPCON_PULL(15), S3C2412_GPGSLPCON);
+
+ /* Port H sleep */
+
+ __raw_writel(S3C2412_SLPCON_PULL(0) |
+ S3C2412_SLPCON_PULL(1) |
+ S3C2412_SLPCON_PULL(2) |
+ S3C2412_SLPCON_PULL(3) |
+ S3C2412_SLPCON_PULL(4) |
+ S3C2412_SLPCON_PULL(5) |
+ S3C2412_SLPCON_PULL(6) |
+ S3C2412_SLPCON_IN(7) |
+ S3C2412_SLPCON_IN(8) |
+ S3C2412_SLPCON_PULL(9) |
+ S3C2412_SLPCON_IN(10), S3C2412_GPHSLPCON);
+
+ /* initialise the power management now we've setup everything. */
+
+ s3c_pm_init();
+
+ /** TODO - check that this is after the cmdline option! */
+ s3c_nand_set_platdata(&jive_nand_info);
+
+ /* initialise the spi */
+
+ gpio_request(S3C2410_GPG(13), "lcm reset");
+ gpio_direction_output(S3C2410_GPG(13), 0);
+
+ gpio_request(S3C2410_GPB(7), "jive spi");
+ gpio_direction_output(S3C2410_GPB(7), 1);
+
+ s3c2410_gpio_setpin(S3C2410_GPB(6), 0);
+ s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
+
+ s3c2410_gpio_setpin(S3C2410_GPG(8), 1);
+ s3c_gpio_cfgpin(S3C2410_GPG(8), S3C2410_GPIO_OUTPUT);
+
+ /* initialise the WM8750 spi */
+
+ gpio_request(S3C2410_GPH(10), "jive wm8750 spi");
+ gpio_direction_output(S3C2410_GPH(10), 1);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ s3c24xx_udc_set_platdata(&jive_udc_cfg);
+ s3c24xx_fb_set_platdata(&jive_lcd_config);
+
+ spi_register_board_info(jive_spi_devs, ARRAY_SIZE(jive_spi_devs));
+
+ s3c_i2c0_set_platdata(&jive_i2c_cfg);
+ i2c_register_board_info(0, jive_i2c_devs, ARRAY_SIZE(jive_i2c_devs));
+
+ pm_power_off = jive_power_off;
+
+ platform_add_devices(jive_devices, ARRAY_SIZE(jive_devices));
+}
+
+MACHINE_START(JIVE, "JIVE")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = jive_map_io,
+ .init_machine = jive_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
new file mode 100644
index 00000000..834cfb61
--- /dev/null
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -0,0 +1,160 @@
+/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
+ * loans of SMDK2413 to work with.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/iomd.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <plat/udc.h>
+#include <plat/iic.h>
+#include <mach/fb.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2413_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ }
+};
+
+
+static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
+ .pullup_pin = S3C2410_GPF(2),
+};
+
+
+static struct platform_device *smdk2413_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_usbgadget,
+};
+
+static void __init smdk2413_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline,
+ struct meminfo *mi)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ mi->nr_banks=1;
+ mi->bank[0].start = 0x30000000;
+ mi->bank[0].size = SZ_64M;
+ }
+}
+
+static void __init smdk2413_map_io(void)
+{
+ s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+}
+
+static void __init smdk2413_machine_init(void)
+{ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+
+ s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(S3C2413, "S3C2413")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
+
+MACHINE_START(SMDK2412, "SMDK2412")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
+
+MACHINE_START(SMDK2413, "SMDK2413")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .fixup = smdk2413_fixup,
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2413_map_io,
+ .init_machine = smdk2413_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
new file mode 100644
index 00000000..83544ebe
--- /dev/null
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -0,0 +1,166 @@
+/* linux/arch/arm/mach-s3c2412/mach-vstms.c
+ *
+ * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ *
+ * Derived from mach-smdk2413.c - (C) 2006 Simtec 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/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+
+#include <plat/iic.h>
+#include <plat/nand.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+
+static struct map_desc vstms_iodesc[] __initdata = {
+};
+
+static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ }
+};
+
+static struct mtd_partition __initdata vstms_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = 0x7C000,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "UBoot Config",
+ .offset = 0x7C000,
+ .size = 0x4000,
+ },
+ [2] = {
+ .name = "Kernel",
+ .offset = 0x80000,
+ .size = 0x200000,
+ },
+ [3] = {
+ .name = "RFS",
+ .offset = 0x280000,
+ .size = 0x3d80000,
+ },
+};
+
+static struct s3c2410_nand_set __initdata vstms_nand_sets[] = {
+ [0] = {
+ .name = "NAND",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(vstms_nand_part),
+ .partitions = vstms_nand_part,
+ },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand __initdata vstms_nand_info = {
+ .tacls = 20,
+ .twrph0 = 60,
+ .twrph1 = 20,
+ .nr_sets = ARRAY_SIZE(vstms_nand_sets),
+ .sets = vstms_nand_sets,
+};
+
+static struct platform_device *vstms_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+};
+
+static void __init vstms_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline,
+ struct meminfo *mi)
+{
+ if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
+ mi->nr_banks=1;
+ mi->bank[0].start = 0x30000000;
+ mi->bank[0].size = SZ_64M;
+ }
+}
+
+static void __init vstms_map_io(void)
+{
+ s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+}
+
+static void __init vstms_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_nand_set_platdata(&vstms_nand_info);
+
+ platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
+}
+
+MACHINE_START(VSTMS, "VSTMS")
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .fixup = vstms_fixup,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = vstms_init,
+ .map_io = vstms_map_io,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
new file mode 100644
index 00000000..752b13a7
--- /dev/null
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -0,0 +1,122 @@
+/* linux/arch/arm/mach-s3c2412/pm.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/s3c2412.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static void s3c2412_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ flush_cache_all();
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C2412_PWRCFG);
+ tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP;
+ __raw_writel(tmp, S3C2412_PWRCFG);
+
+ s3c2412_sleep_enter();
+}
+
+static void s3c2412_pm_prepare(void)
+{
+}
+
+static int s3c2412_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s3c2412_pm_prepare;
+ pm_cpu_sleep = s3c2412_cpu_suspend;
+
+ return 0;
+}
+
+static struct sleep_save s3c2412_sleep[] = {
+ SAVE_ITEM(S3C2412_DSC0),
+ SAVE_ITEM(S3C2412_DSC1),
+ SAVE_ITEM(S3C2413_GPJDAT),
+ SAVE_ITEM(S3C2413_GPJCON),
+ SAVE_ITEM(S3C2413_GPJUP),
+
+ /* save the PWRCFG to get back to original sleep method */
+
+ SAVE_ITEM(S3C2412_PWRCFG),
+
+ /* save the sleep configuration anyway, just in case these
+ * get damaged during wakeup */
+
+ SAVE_ITEM(S3C2412_GPBSLPCON),
+ SAVE_ITEM(S3C2412_GPCSLPCON),
+ SAVE_ITEM(S3C2412_GPDSLPCON),
+ SAVE_ITEM(S3C2412_GPFSLPCON),
+ SAVE_ITEM(S3C2412_GPGSLPCON),
+ SAVE_ITEM(S3C2412_GPHSLPCON),
+ SAVE_ITEM(S3C2413_GPJSLPCON),
+};
+
+static struct sysdev_driver s3c2412_pm_driver = {
+ .add = s3c2412_pm_add,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+ return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
+}
+
+arch_initcall(s3c2412_pm_init);
+
+static int s3c2412_pm_suspend(void)
+{
+ s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+ return 0;
+}
+
+static void s3c2412_pm_resume(void)
+{
+ unsigned long tmp;
+
+ tmp = __raw_readl(S3C2412_PWRCFG);
+ tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+ tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+ __raw_writel(tmp, S3C2412_PWRCFG);
+
+ s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
+}
+
+struct syscore_ops s3c2412_pm_syscore_ops = {
+ .suspend = s3c2412_pm_suspend,
+ .resume = s3c2412_pm_resume,
+};
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
new file mode 100644
index 00000000..ef0958d3
--- /dev/null
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -0,0 +1,252 @@
+/* linux/arch/arm/mach-s3c2412/s3c2412.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/reset.h>
+#include <mach/idle.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-power.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+#include <plat/regs-spi.h>
+#include <mach/regs-s3c2412.h>
+
+#include <plat/s3c2412.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+#include <plat/nand-core.h>
+
+#ifndef CONFIG_CPU_S3C2412_ONLY
+void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
+
+static inline void s3c2412_init_gpio2(void)
+{
+ s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
+}
+#else
+#define s3c2412_init_gpio2() do { } while(0)
+#endif
+
+/* Initial IO mappings */
+
+static struct map_desc s3c2412_iodesc[] __initdata = {
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(WATCHDOG),
+ {
+ .virtual = (unsigned long)S3C2412_VA_SSMC,
+ .pfn = __phys_to_pfn(S3C2412_PA_SSMC),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)S3C2412_VA_EBI,
+ .pfn = __phys_to_pfn(S3C2412_PA_EBI),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+/* uart registration process */
+
+void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
+
+ /* rename devices that are s3c2412/s3c2413 specific */
+ s3c_device_sdi.name = "s3c2412-sdi";
+ s3c_device_lcd.name = "s3c2412-lcd";
+ s3c_nand_setname("s3c2412-nand");
+
+ /* alter IRQ of SDI controller */
+
+ s3c_device_sdi.resource[1].start = IRQ_S3C2412_SDI;
+ s3c_device_sdi.resource[1].end = IRQ_S3C2412_SDI;
+
+ /* spi channel related changes, s3c2412/13 specific */
+ s3c_device_spi0.name = "s3c2412-spi";
+ s3c_device_spi0.resource[0].end = S3C24XX_PA_SPI + 0x24;
+ s3c_device_spi1.name = "s3c2412-spi";
+ s3c_device_spi1.resource[0].start = S3C24XX_PA_SPI + S3C2412_SPI1;
+ s3c_device_spi1.resource[0].end = S3C24XX_PA_SPI + S3C2412_SPI1 + 0x24;
+
+}
+
+/* s3c2412_idle
+ *
+ * use the standard idle call by ensuring the idle mode
+ * in power config, then issuing the idle co-processor
+ * instruction
+*/
+
+static void s3c2412_idle(void)
+{
+ unsigned long tmp;
+
+ /* ensure our idle mode is to go to idle */
+
+ tmp = __raw_readl(S3C2412_PWRCFG);
+ tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK;
+ tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE;
+ __raw_writel(tmp, S3C2412_PWRCFG);
+
+ cpu_do_idle();
+}
+
+static void s3c2412_hard_reset(void)
+{
+ /* errata "Watch-dog/Software Reset Problem" specifies that
+ * this reset must be done with the SYSCLK sourced from
+ * EXTCLK instead of FOUT to avoid a glitch in the reset
+ * mechanism.
+ *
+ * See the watchdog section of the S3C2412 manual for more
+ * information on this fix.
+ */
+
+ __raw_writel(0x00, S3C2412_CLKSRC);
+ __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
+
+ mdelay(1);
+}
+
+/* s3c2412_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+*/
+
+void __init s3c2412_map_io(void)
+{
+ /* move base of IO */
+
+ s3c2412_init_gpio2();
+
+ /* set our idle function */
+
+ s3c24xx_idle = s3c2412_idle;
+
+ /* set custom reset hook */
+
+ s3c24xx_reset_hook = s3c2412_hard_reset;
+
+ /* register our io-tables */
+
+ iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
+}
+
+void __init_or_cpufreq s3c2412_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long tmp;
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long pclk;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ /* now we've got our machine bits initialised, work out what
+ * clocks we've got */
+
+ fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal * 2);
+
+ clk_mpll.rate = fclk;
+
+ tmp = __raw_readl(S3C2410_CLKDIVN);
+
+ /* work out clock scalings */
+
+ hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
+ hclk /= ((tmp & S3C2412_CLKDIVN_ARMDIVN) ? 2 : 1);
+ pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
+
+ /* print brieft summary of clocks, etc */
+
+ printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+ print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c2412_init_clocks(int xtal)
+{
+ /* initialise the clocks here, to allow other things like the
+ * console to use them
+ */
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c2412_setup_clocks();
+ s3c2412_baseclk_add();
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2412 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+struct sysdev_class s3c2412_sysclass = {
+ .name = "s3c2412-core",
+};
+
+static int __init s3c2412_core_init(void)
+{
+ return sysdev_class_register(&s3c2412_sysclass);
+}
+
+core_initcall(s3c2412_core_init);
+
+static struct sys_device s3c2412_sysdev = {
+ .cls = &s3c2412_sysclass,
+};
+
+int __init s3c2412_init(void)
+{
+ printk("S3C2412: Initialising architecture\n");
+
+ register_syscore_ops(&s3c2412_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+ return sysdev_register(&s3c2412_sysdev);
+}
diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S
new file mode 100644
index 00000000..c82418ed
--- /dev/null
+++ b/arch/arm/mach-s3c2412/sleep.S
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s3c2412/sleep.S
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412 Power Manager low-level sleep support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-irq.h>
+
+ .text
+
+ .global s3c2412_sleep_enter
+
+s3c2412_sleep_enter:
+ mov r0, #0 /* argument for coprocessors */
+ ldr r1, =S3C2410_INTPND
+ ldr r2, =S3C2410_SRCPND
+ ldr r3, =S3C2410_EINTPEND
+
+ teq r0, r0
+ bl s3c2412_sleep_enter1
+ teq pc, r0
+ bl s3c2412_sleep_enter1
+
+ .align 5
+
+ /* this is called twice, first with the Z flag to ensure that the
+ * instructions have been loaded into the cache, and the second
+ * time to try and suspend the system.
+ */
+s3c2412_sleep_enter1:
+ mcr p15, 0, r0, c7, c10, 4
+ mcrne p15, 0, r0, c7, c0, 4
+
+ /* if we return from here, it is because an interrupt was
+ * active when we tried to shutdown. Try and ack the IRQ and
+ * retry, as simply returning causes the system to lock.
+ */
+
+ ldrne r9, [ r1 ]
+ strne r9, [ r1 ]
+ ldrne r9, [ r2 ]
+ strne r9, [ r2 ]
+ ldrne r9, [ r3 ]
+ strne r9, [ r3 ]
+ bne s3c2412_sleep_enter1
+
+ mov pc, r14
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig
new file mode 100644
index 00000000..69b48a7d
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Kconfig
@@ -0,0 +1,61 @@
+# arch/arm/mach-s3c2416/Kconfig
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+# note, this also supports the S3C2450 which is so similar it has the same
+# ID code as the S3C2416.
+
+config CPU_S3C2416
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM926T
+ select S3C2416_DMA if S3C2410_DMA
+ select CPU_LLSERIAL_S3C2440
+ select S3C_GPIO_PULL_UPDOWN
+ select SAMSUNG_CLKSRC
+ select S3C2443_CLOCK
+ help
+ Support for the S3C2416 SoC from the S3C24XX line
+
+config S3C2416_DMA
+ bool
+ depends on CPU_S3C2416
+ help
+ Internal config node for S3C2416 DMA support
+
+config S3C2416_PM
+ bool
+ select S3C2412_PM_SLEEP
+ help
+ Internal config node to apply S3C2416 power management
+
+config S3C2416_SETUP_SDHCI
+ bool
+ select S3C2416_SETUP_SDHCI_GPIO
+ help
+ Internal helper functions for S3C2416 based SDHCI systems
+
+config S3C2416_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
+menu "S3C2416 Machines"
+
+config MACH_SMDK2416
+ bool "SMDK2416"
+ select CPU_S3C2416
+ select MACH_SMDK
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select S3C2416_SETUP_SDHCI
+ select S3C2416_PM if PM
+ help
+ Say Y here if you are using an SMDK2416
+
+endmenu
diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile
new file mode 100644
index 00000000..7b805b27
--- /dev/null
+++ b/arch/arm/mach-s3c2416/Makefile
@@ -0,0 +1,23 @@
+# arch/arm/mach-s3c2416/Makefile
+#
+# Copyright 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2416) += s3c2416.o clock.o
+obj-$(CONFIG_CPU_S3C2416) += irq.o
+obj-$(CONFIG_S3C2416_PM) += pm.o
+#obj-$(CONFIG_S3C2416_DMA) += dma.o
+
+# Device setup
+obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o
diff --git a/arch/arm/mach-s3c2416/clock.c b/arch/arm/mach-s3c2416/clock.c
new file mode 100644
index 00000000..3b02d850
--- /dev/null
+++ b/arch/arm/mach-s3c2416/clock.c
@@ -0,0 +1,143 @@
+/* linux/arch/arm/mach-s3c2416/clock.c
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * S3C2416 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <plat/s3c2416.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/pll6553x.h>
+#include <plat/pll.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-s3c2443-clock.h>
+
+static unsigned int armdiv[8] = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 3,
+ [3] = 4,
+ [5] = 6,
+ [7] = 8,
+};
+
+static struct clksrc_clk hsmmc_div[] = {
+ [0] = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = 0,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2416_CLKDIV2, .size = 2, .shift = 6 },
+ },
+ [1] = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = 1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+ },
+};
+
+static struct clksrc_clk hsmmc_mux[] = {
+ [0] = {
+ .clk = {
+ .id = 0,
+ .name = "hsmmc-if",
+ .ctrlbit = (1 << 6),
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .sources = &(struct clksrc_sources) {
+ .nr_sources = 2,
+ .sources = (struct clk *[]) {
+ [0] = &hsmmc_div[0].clk,
+ [1] = NULL, /* to fix */
+ },
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 16 },
+ },
+ [1] = {
+ .clk = {
+ .id = 1,
+ .name = "hsmmc-if",
+ .ctrlbit = (1 << 12),
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .sources = &(struct clksrc_sources) {
+ .nr_sources = 2,
+ .sources = (struct clk *[]) {
+ [0] = &hsmmc_div[1].clk,
+ [1] = NULL, /* to fix */
+ },
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 17 },
+ },
+};
+
+static struct clk hsmmc0_clk = {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2416_HCLKCON_HSMMC0,
+};
+
+static inline unsigned int s3c2416_fclk_div(unsigned long clkcon0)
+{
+ clkcon0 &= 7 << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+
+ return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+void __init_or_cpufreq s3c2416_setup_clocks(void)
+{
+ s3c2443_common_setup_clocks(s3c2416_get_pll, s3c2416_fclk_div);
+}
+
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+ &hsmmc_div[0],
+ &hsmmc_div[1],
+ &hsmmc_mux[0],
+ &hsmmc_mux[1],
+};
+
+void __init s3c2416_init_clocks(int xtal)
+{
+ u32 epllcon = __raw_readl(S3C2443_EPLLCON);
+ u32 epllcon1 = __raw_readl(S3C2443_EPLLCON+4);
+ int ptr;
+
+ /* s3c2416 EPLL compatible with s3c64xx */
+ clk_epll.rate = s3c_get_pll6553x(xtal, epllcon, epllcon1);
+
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c2443_common_init_clocks(xtal, s3c2416_get_pll, s3c2416_fclk_div);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
+ s3c24xx_register_clock(&hsmmc0_clk);
+
+ s3c_pwmclk_init();
+
+}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
new file mode 100644
index 00000000..28ad20d4
--- /dev/null
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -0,0 +1,247 @@
+/* linux/arch/arm/mach-s3c2416/irq.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2416_irq_demux(unsigned int irq, unsigned int len)
+{
+ unsigned int subsrc, submsk;
+ unsigned int end;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= (irq - S3C2410_IRQSUB(0));
+ subsrc &= (1 << len)-1;
+
+ end = len + irq;
+
+ for (; irq < end && subsrc; irq++) {
+ if (subsrc & 1)
+ generic_handle_irq(irq);
+
+ subsrc >>= 1;
+ }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2416_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2416_irq_wdtac97_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2416_irq_wdtac97_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2416_irq_wdtac97 = {
+ .irq_mask = s3c2416_irq_wdtac97_mask,
+ .irq_unmask = s3c2416_irq_wdtac97_unmask,
+ .irq_ack = s3c2416_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2416_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2416_irq_lcd_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2416_irq_lcd_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2416_irq_lcd = {
+ .irq_mask = s3c2416_irq_lcd_mask,
+ .irq_unmask = s3c2416_irq_lcd_unmask,
+ .irq_ack = s3c2416_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2416_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+
+static void s3c2416_irq_dma_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2416_irq_dma_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2416_irq_dma_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2416_irq_dma = {
+ .irq_mask = s3c2416_irq_dma_mask,
+ .irq_unmask = s3c2416_irq_dma_unmask,
+ .irq_ack = s3c2416_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2416_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2416_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2416_irq_uart3_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2416_irq_uart3_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2416_irq_uart3 = {
+ .irq_mask = s3c2416_irq_uart3_mask,
+ .irq_unmask = s3c2416_irq_uart3_unmask,
+ .irq_ack = s3c2416_irq_uart3_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2416_add_sub(unsigned int base,
+ void (*demux)(unsigned int,
+ struct irq_desc *),
+ struct irq_chip *chip,
+ unsigned int start, unsigned int end)
+{
+ unsigned int irqno;
+
+ irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+ irq_set_chained_handler(base, demux);
+
+ for (irqno = start; irqno <= end; irqno++) {
+ irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static int __init s3c2416_irq_add(struct sys_device *sysdev)
+{
+ printk(KERN_INFO "S3C2416: IRQ Support\n");
+
+ s3c2416_add_sub(IRQ_LCD, s3c2416_irq_demux_lcd, &s3c2416_irq_lcd,
+ IRQ_S3C2443_LCD2, IRQ_S3C2443_LCD4);
+
+ s3c2416_add_sub(IRQ_S3C2443_DMA, s3c2416_irq_demux_dma,
+ &s3c2416_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+ s3c2416_add_sub(IRQ_S3C2443_UART3, s3c2416_irq_demux_uart3,
+ &s3c2416_irq_uart3,
+ IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+ s3c2416_add_sub(IRQ_WDT, s3c2416_irq_demux_wdtac97,
+ &s3c2416_irq_wdtac97,
+ IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2416_irq_driver = {
+ .add = s3c2416_irq_add,
+};
+
+static int __init s3c2416_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_irq_driver);
+}
+
+arch_initcall(s3c2416_irq_init);
+
diff --git a/arch/arm/mach-s3c2416/mach-smdk2416.c b/arch/arm/mach-s3c2416/mach-smdk2416.c
new file mode 100644
index 00000000..ac27ebb3
--- /dev/null
+++ b/arch/arm/mach-s3c2416/mach-smdk2416.c
@@ -0,0 +1,254 @@
+/* linux/arch/arm/mach-s3c2416/mach-hanlin_v3c.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+#include <linux/gpio.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <mach/idle.h>
+#include <mach/leds-gpio.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2416.h>
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/nand.h>
+#include <plat/sdhci.h>
+#include <plat/udc.h>
+
+#include <plat/regs-fb-v4.h>
+#include <plat/fb.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2416_iodesc[] __initdata = {
+ /* ISA IO Space map (memory space selected by A24) */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | \
+ S3C2440_UCON_PCLK | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+
+#define UFCON (S3C2410_UFCON_RXTRIG8 | \
+ S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdk2416_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON | 0x50,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+void smdk2416_hsudc_gpio_init(void)
+{
+ s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
+ s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
+ s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
+}
+
+void smdk2416_hsudc_gpio_uninit(void)
+{
+ s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
+ s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
+}
+
+struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+ .epnum = 9,
+ .gpio_init = smdk2416_hsudc_gpio_init,
+ .gpio_uninit = smdk2416_hsudc_gpio_uninit,
+};
+
+struct s3c_fb_pd_win smdk2416_fb_win[] = {
+ [0] = {
+ /* think this is the same as the smdk6410 */
+ .win_mode = {
+ .pixclock = 41094,
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .default_bpp = 16,
+ .max_bpp = 32,
+ },
+};
+
+static void s3c2416_fb_gpio_setup_24bpp(void)
+{
+ unsigned int gpio;
+
+ for (gpio = S3C2410_GPC(1); gpio <= S3C2410_GPC(4); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ for (gpio = S3C2410_GPC(8); gpio <= S3C2410_GPC(15); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ for (gpio = S3C2410_GPD(0); gpio <= S3C2410_GPD(15); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+}
+
+static struct s3c_fb_platdata smdk2416_fb_platdata = {
+ .win[0] = &smdk2416_fb_win[0],
+ .setup_gpio = s3c2416_fb_gpio_setup_24bpp,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct s3c_sdhci_platdata smdk2416_hsmmc0_pdata __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = S3C2410_GPF(1),
+ .ext_cd_gpio_invert = 1,
+};
+
+static struct s3c_sdhci_platdata smdk2416_hsmmc1_pdata __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_NONE,
+};
+
+static struct platform_device *smdk2416_devices[] __initdata = {
+ &s3c_device_fb,
+ &s3c_device_wdt,
+ &s3c_device_ohci,
+ &s3c_device_i2c0,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_usb_hsudc,
+};
+
+static void __init smdk2416_map_io(void)
+{
+ s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+}
+
+static void __init smdk2416_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_fb_set_platdata(&smdk2416_fb_platdata);
+
+ s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
+ s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
+
+ s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
+
+ gpio_request(S3C2410_GPB(4), "USBHost Power");
+ gpio_direction_output(S3C2410_GPB(4), 1);
+
+ gpio_request(S3C2410_GPB(3), "Display Power");
+ gpio_direction_output(S3C2410_GPB(3), 1);
+
+ gpio_request(S3C2410_GPB(1), "Display Reset");
+ gpio_direction_output(S3C2410_GPB(1), 1);
+
+ platform_add_devices(smdk2416_devices, ARRAY_SIZE(smdk2416_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(SMDK2416, "SMDK2416")
+ /* Maintainer: Yauhen Kharuzhy <jekhor@gmail.com> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2416_map_io,
+ .init_machine = smdk2416_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c
new file mode 100644
index 00000000..41db2b21
--- /dev/null
+++ b/arch/arm/mach-s3c2416/pm.c
@@ -0,0 +1,81 @@
+/* linux/arch/arm/mach-s3c2416/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S3C2416 - PM support (Based on Ben Dooks' S3C2412 PM support)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+
+#include <mach/regs-power.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+extern void s3c2412_sleep_enter(void);
+
+static void s3c2416_cpu_suspend(void)
+{
+ flush_cache_all();
+
+ /* enable wakeup sources regardless of battery state */
+ __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG);
+
+ /* set the mode as sleep, 2BED represents "Go to BED" */
+ __raw_writel(0x2BED, S3C2443_PWRMODE);
+
+ s3c2412_sleep_enter();
+}
+
+static void s3c2416_pm_prepare(void)
+{
+ /*
+ * write the magic value u-boot uses to check for resume into
+ * the INFORM0 register, and ensure INFORM1 is set to the
+ * correct address to resume from.
+ */
+ __raw_writel(0x2BED, S3C2412_INFORM0);
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C2412_INFORM1);
+}
+
+static int s3c2416_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s3c2416_pm_prepare;
+ pm_cpu_sleep = s3c2416_cpu_suspend;
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2416_pm_driver = {
+ .add = s3c2416_pm_add,
+};
+
+static __init int s3c2416_pm_init(void)
+{
+ return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
+}
+
+arch_initcall(s3c2416_pm_init);
+
+
+static void s3c2416_pm_resume(void)
+{
+ /* unset the return-from-sleep amd inform flags */
+ __raw_writel(0x0, S3C2443_PWRMODE);
+ __raw_writel(0x0, S3C2412_INFORM0);
+ __raw_writel(0x0, S3C2412_INFORM1);
+}
+
+struct syscore_ops s3c2416_pm_syscore_ops = {
+ .resume = s3c2416_pm_resume,
+};
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
new file mode 100644
index 00000000..494ce913
--- /dev/null
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -0,0 +1,142 @@
+/* linux/arch/arm/mach-s3c2416/s3c2416.c
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>,
+ * as part of OpenInkpot project
+ * Copyright (c) 2009 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * Samsung S3C2416 Mobile CPU support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/reset.h>
+#include <mach/idle.h>
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2416.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/sdhci.h>
+#include <plat/pm.h>
+
+#include <plat/iic-core.h>
+#include <plat/fb-core.h>
+#include <plat/nand-core.h>
+
+static struct map_desc s3c2416_iodesc[] __initdata = {
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2416_sysclass = {
+ .name = "s3c2416-core",
+};
+
+static struct sys_device s3c2416_sysdev = {
+ .cls = &s3c2416_sysclass,
+};
+
+static void s3c2416_hard_reset(void)
+{
+ __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2416_init(void)
+{
+ printk(KERN_INFO "S3C2416: Initializing architecture\n");
+
+ s3c24xx_reset_hook = s3c2416_hard_reset;
+ /* s3c24xx_idle = s3c2416_idle; */
+
+ /* change WDT IRQ number */
+ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+ s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ s3c_fb_setname("s3c2443-fb");
+
+ register_syscore_ops(&s3c2416_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+ return sysdev_register(&s3c2416_sysdev);
+}
+
+void __init s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+
+ s3c_nand_setname("s3c2412-nand");
+}
+
+/* s3c2416_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2416_map_io(void)
+{
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown;
+
+ /* initialize device information early */
+ s3c2416_default_sdhci0();
+ s3c2416_default_sdhci1();
+
+ iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc));
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2416 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2416_core_init(void)
+{
+ return sysdev_class_register(&s3c2416_sysclass);
+}
+
+core_initcall(s3c2416_core_init);
diff --git a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c
new file mode 100644
index 00000000..f65cb3ef
--- /dev/null
+++ b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c
+ *
+ * Copyright 2010 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC)
+ *
+ * Based on mach-s3c64xx/setup-sdhci-gpio.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2));
+}
+
+void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2));
+}
diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c
new file mode 100644
index 00000000..ed34fad8
--- /dev/null
+++ b/arch/arm/mach-s3c2416/setup-sdhci.c
@@ -0,0 +1,61 @@
+/* linux/arch/arm/mach-s3c2416/setup-sdhci.c
+ *
+ * Copyright 2010 Promwad Innovation Company
+ * Yauhen Kharuzhy <yauhen.kharuzhy@promwad.com>
+ *
+ * S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * Based on mach-s3c64xx/setup-sdhci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s3c2416_hsmmc_clksrcs[4] = {
+ [0] = "hsmmc",
+ [1] = "hsmmc",
+ [2] = "hsmmc-if",
+ /* [3] = "48m", - note not successfully used yet */
+};
+
+void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2);
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ __raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ __raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
new file mode 100644
index 00000000..50825a3f
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -0,0 +1,206 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2440
+ bool
+ select CPU_ARM920T
+ select S3C_GPIO_PULL_UP
+ select S3C2410_CLOCK
+ select S3C2410_PM if PM
+ select S3C2410_GPIO
+ select S3C2440_DMA if S3C2410_DMA
+ select CPU_S3C244X
+ select CPU_LLSERIAL_S3C2440
+ help
+ Support for S3C2440 Samsung Mobile CPU based systems.
+
+config CPU_S3C2442
+ bool
+ select CPU_ARM920T
+ select S3C_GPIO_PULL_DOWN
+ select S3C2410_CLOCK
+ select S3C2410_GPIO
+ select S3C2410_PM if PM
+ select CPU_S3C244X
+ select CPU_LLSERIAL_S3C2440
+ help
+ Support for S3C2442 Samsung Mobile CPU based systems.
+
+config CPU_S3C244X
+ bool
+ depends on CPU_S3C2440 || CPU_S3C2442
+ help
+ Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
+
+
+
+config S3C2440_CPUFREQ
+ bool "S3C2440/S3C2442 CPU Frequency scaling support"
+ depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
+ select S3C2410_CPUFREQ_UTILS
+ default y
+ help
+ CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
+
+config S3C2440_XTAL_12000000
+ bool
+ help
+ Indicate that the build needs to support 12MHz system
+ crystal.
+
+config S3C2440_XTAL_16934400
+ bool
+ help
+ Indicate that the build needs to support 16.9344MHz system
+ crystal.
+
+config S3C2440_PLL_12000000
+ bool
+ depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000
+ default y if CPU_FREQ_S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
+
+config S3C2440_PLL_16934400
+ bool
+ depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400
+ default y if CPU_FREQ_S3C24XX_PLL
+ help
+ PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
+
+config S3C2440_DMA
+ bool
+ depends on CPU_S3C2440
+ help
+ Support for S3C2440 specific DMA code5A
+
+menu "S3C2440 and S3C2442 Machines"
+
+config MACH_ANUBIS
+ bool "Simtec Electronics ANUBIS"
+ select CPU_S3C2440
+ select S3C24XX_DCLK
+ select PM_SIMTEC if PM
+ select HAVE_PATA_PLATFORM
+ select S3C24XX_GPIO_EXTRA64
+ select S3C2440_XTAL_12000000
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Simtec Electronics ANUBIS
+ development system
+
+config MACH_NEO1973_GTA02
+ bool "Openmoko GTA02 / Freerunner phone"
+ select CPU_S3C2442
+ select MFD_PCF50633
+ select PCF50633_GPIO
+ select I2C
+ select POWER_SUPPLY
+ select MACH_NEO1973
+ select S3C2410_PWM
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone
+
+config MACH_OSIRIS
+ bool "Simtec IM2440D20 (OSIRIS) module"
+ select CPU_S3C2440
+ select S3C24XX_DCLK
+ select PM_SIMTEC if PM
+ select S3C24XX_GPIO_EXTRA128
+ select S3C2440_XTAL_12000000
+ select S3C2410_IOTIMING if S3C2440_CPUFREQ
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Simtec IM2440D20 module, also
+ known as the Osiris.
+
+config MACH_OSIRIS_DVS
+ tristate "Simtec IM2440D20 (OSIRIS) Dynamic Voltage Scaling driver"
+ depends on MACH_OSIRIS
+ select TPS65010
+ help
+ Say Y/M here if you want to have dynamic voltage scaling support
+ on the Simtec IM2440D20 (OSIRIS) module via the TPS65011.
+
+ The DVS driver alters the voltage supplied to the ARM core
+ depending on the frequency it is running at. The driver itself
+ does not do any of the frequency alteration, which is left up
+ to the cpufreq driver.
+
+config MACH_RX3715
+ bool "HP iPAQ rx3715"
+ select CPU_S3C2440
+ select S3C2440_XTAL_16934400
+ select PM_H1940 if PM
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the HP iPAQ rx3715.
+
+config ARCH_S3C2440
+ bool "SMDK2440"
+ select CPU_S3C2440
+ select S3C2440_XTAL_16934400
+ select MACH_SMDK
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the SMDK2440.
+
+config MACH_NEXCODER_2440
+ bool "NexVision NEXCODER 2440 Light Board"
+ select CPU_S3C2440
+ select S3C2440_XTAL_12000000
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
+
+config SMDK2440_CPU2440
+ bool "SMDK2440 with S3C2440 CPU module"
+ default y if ARCH_S3C2440
+ select S3C2440_XTAL_16934400
+ select CPU_S3C2440
+
+config SMDK2440_CPU2442
+ bool "SMDM2440 with S3C2442 CPU module"
+ select CPU_S3C2442
+
+config MACH_AT2440EVB
+ bool "Avantech AT2440EVB development board"
+ select CPU_S3C2440
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ help
+ Say Y here if you are using the AT2440EVB development board
+
+config MACH_MINI2440
+ bool "MINI2440 development board"
+ select CPU_S3C2440
+ select EEPROM_AT24
+ select NEW_LEDS
+ select LEDS_CLASS
+ select LEDS_TRIGGER
+ select LEDS_TRIGGER_BACKLIGHT
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ help
+ Say Y here to select support for the MINI2440. Is a 10cm x 10cm board
+ available via various sources. It can come with a 3.5" or 7" touch LCD.
+
+config MACH_RX1950
+ bool "HP iPAQ rx1950"
+ select CPU_S3C2442
+ select S3C24XX_DCLK
+ select PM_H1940 if PM
+ select I2C
+ select S3C2410_PWM
+ select S3C_DEV_NAND
+ select S3C2410_IOTIMING if S3C2440_CPUFREQ
+ select S3C2440_XTAL_16934400
+ help
+ Say Y here if you're using HP iPAQ rx1950
+
+endmenu
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
new file mode 100644
index 00000000..d5440fa3
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -0,0 +1,41 @@
+# arch/arm/mach-s3c2440/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+
+obj-$(CONFIG_CPU_S3C2440) += irq.o
+obj-$(CONFIG_CPU_S3C2440) += clock.o
+obj-$(CONFIG_S3C2440_DMA) += dma.o
+
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-clock.o
+obj-$(CONFIG_S3C2440_CPUFREQ) += s3c2440-cpufreq.o
+
+obj-$(CONFIG_S3C2440_PLL_12000000) += s3c2440-pll-12000000.o
+obj-$(CONFIG_S3C2440_PLL_16934400) += s3c2440-pll-16934400.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
+obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
+obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
+obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
+obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
+obj-$(CONFIG_MACH_AT2440EVB) += mach-at2440evb.o
+obj-$(CONFIG_MACH_MINI2440) += mach-mini2440.o
+obj-$(CONFIG_MACH_NEO1973_GTA02) += mach-gta02.o
+obj-$(CONFIG_MACH_RX1950) += mach-rx1950.o
+
+# extra machine support
+
+obj-$(CONFIG_MACH_OSIRIS_DVS) += mach-osiris-dvs.o
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
new file mode 100644
index 00000000..3dc2426e
--- /dev/null
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -0,0 +1,152 @@
+/* linux/arch/arm/mach-s3c2440/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* S3C2440 extended clock support */
+
+static unsigned long s3c2440_camif_upll_round(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ /* note, we remove the +/- 1 calculations for the divisor */
+
+ div = (parent_rate / rate) / 2;
+
+ if (div < 1)
+ div = 1;
+ else if (div > 16)
+ div = 16;
+
+ return parent_rate / (div * 2);
+}
+
+static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+
+ rate = s3c2440_camif_upll_round(clk, rate);
+
+ camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
+
+ if (rate != parent_rate) {
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= (((parent_rate / rate) / 2) - 1);
+ }
+
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+/* Extra S3C2440 clocks */
+
+static struct clk s3c2440_clk_cam = {
+ .name = "camif",
+ .id = -1,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2440_clk_cam_upll = {
+ .name = "camif-upll",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_rate = s3c2440_camif_upll_setrate,
+ .round_rate = s3c2440_camif_upll_round,
+ },
+};
+
+static struct clk s3c2440_clk_ac97 = {
+ .name = "ac97",
+ .id = -1,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2440_CLKCON_CAMERA,
+};
+
+static int s3c2440_clk_add(struct sys_device *sysdev)
+{
+ struct clk *clock_upll;
+ struct clk *clock_h;
+ struct clk *clock_p;
+
+ clock_p = clk_get(NULL, "pclk");
+ clock_h = clk_get(NULL, "hclk");
+ clock_upll = clk_get(NULL, "upll");
+
+ if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+ printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
+ return -EINVAL;
+ }
+
+ s3c2440_clk_cam.parent = clock_h;
+ s3c2440_clk_ac97.parent = clock_p;
+ s3c2440_clk_cam_upll.parent = clock_upll;
+
+ s3c24xx_register_clock(&s3c2440_clk_ac97);
+ s3c24xx_register_clock(&s3c2440_clk_cam);
+ s3c24xx_register_clock(&s3c2440_clk_cam_upll);
+
+ clk_disable(&s3c2440_clk_ac97);
+ clk_disable(&s3c2440_clk_cam);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+ .add = s3c2440_clk_add,
+};
+
+static __init int s3c24xx_clk_driver(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c24xx_clk_driver);
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
new file mode 100644
index 00000000..3b0529f5
--- /dev/null
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -0,0 +1,211 @@
+/* linux/arch/arm/mach-s3c2440/dma.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
+ [DMACH_XD0] = {
+ .name = "xdreq0",
+ .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
+ },
+ [DMACH_XD1] = {
+ .name = "xdreq1",
+ .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
+ },
+ [DMACH_SDI] = {
+ .name = "sdi",
+ .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
+ .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
+ .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_SPI0] = {
+ .name = "spi0",
+ .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
+ },
+ [DMACH_SPI1] = {
+ .name = "spi1",
+ .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+ },
+ [DMACH_UART0] = {
+ .name = "uart0",
+ .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1] = {
+ .name = "uart1",
+ .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2] = {
+ .name = "uart2",
+ .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_TIMER] = {
+ .name = "timer",
+ .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
+ .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
+ },
+ [DMACH_I2S_IN] = {
+ .name = "i2s-sdi",
+ .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_I2S_OUT] = {
+ .name = "i2s-sdo",
+ .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
+ .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_PCM_IN] = {
+ .name = "pcm-in",
+ .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
+ .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
+ .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+ },
+ [DMACH_PCM_OUT] = {
+ .name = "pcm-out",
+ .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
+ .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
+ .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+ },
+ [DMACH_MIC_IN] = {
+ .name = "mic-in",
+ .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
+ .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
+ .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+ },
+ [DMACH_USB_EP1] = {
+ .name = "usb-ep1",
+ .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP2] = {
+ .name = "usb-ep2",
+ .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP3] = {
+ .name = "usb-ep3",
+ .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
+ },
+ [DMACH_USB_EP4] = {
+ .name = "usb-ep4",
+ .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
+ },
+};
+
+static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map)
+{
+ chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
+ .select = s3c2440_dma_select,
+ .dcon_mask = 7 << 24,
+ .map = s3c2440_dma_mappings,
+ .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
+};
+
+static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
+ .channels = {
+ [DMACH_SDI] = {
+ .list = {
+ [0] = 3 | DMA_CH_VALID,
+ [1] = 2 | DMA_CH_VALID,
+ [2] = 1 | DMA_CH_VALID,
+ [3] = 0 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_I2S_IN] = {
+ .list = {
+ [0] = 1 | DMA_CH_VALID,
+ [1] = 2 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_I2S_OUT] = {
+ .list = {
+ [0] = 2 | DMA_CH_VALID,
+ [1] = 1 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_PCM_IN] = {
+ .list = {
+ [0] = 2 | DMA_CH_VALID,
+ [1] = 1 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_PCM_OUT] = {
+ .list = {
+ [0] = 1 | DMA_CH_VALID,
+ [1] = 3 | DMA_CH_VALID,
+ },
+ },
+ [DMACH_MIC_IN] = {
+ .list = {
+ [0] = 3 | DMA_CH_VALID,
+ [1] = 2 | DMA_CH_VALID,
+ },
+ },
+ },
+};
+
+static int __init s3c2440_dma_add(struct sys_device *sysdev)
+{
+ s3c2410_dma_init();
+ s3c24xx_dma_order_set(&s3c2440_dma_order);
+ return s3c24xx_dma_init_map(&s3c2440_dma_sel);
+}
+
+static struct sysdev_driver s3c2440_dma_driver = {
+ .add = s3c2440_dma_add,
+};
+
+static int __init s3c2440_dma_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver);
+}
+
+arch_initcall(s3c2440_dma_init);
+
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c
new file mode 100644
index 00000000..9ea66e31
--- /dev/null
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s3c2440/dsc.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 Drive Strength Control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+
+int s3c2440_set_dsc(unsigned int pin, unsigned int value)
+{
+ void __iomem *base;
+ unsigned long val;
+ unsigned long flags;
+ unsigned long mask;
+
+ base = (pin & S3C2440_SELECT_DSC1) ? S3C2440_DSC1 : S3C2440_DSC0;
+ mask = 3 << S3C2440_DSC_GETSHIFT(pin);
+
+ local_irq_save(flags);
+
+ val = __raw_readl(base);
+ val &= ~mask;
+ val |= value & mask;
+ __raw_writel(val, base);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2440_set_dsc);
diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-s3c2440/include/mach/gta02.h
new file mode 100644
index 00000000..3a56a229
--- /dev/null
+++ b/arch/arm/mach-s3c2440/include/mach/gta02.h
@@ -0,0 +1,84 @@
+#ifndef _GTA02_H
+#define _GTA02_H
+
+#include <mach/regs-gpio.h>
+
+/* Different hardware revisions, passed in ATAG_REVISION by u-boot */
+#define GTA02v1_SYSTEM_REV 0x00000310
+#define GTA02v2_SYSTEM_REV 0x00000320
+#define GTA02v3_SYSTEM_REV 0x00000330
+#define GTA02v4_SYSTEM_REV 0x00000340
+#define GTA02v5_SYSTEM_REV 0x00000350
+/* since A7 is basically same as A6, we use A6 PCB ID */
+#define GTA02v6_SYSTEM_REV 0x00000360
+
+#define GTA02_GPIO_n3DL_GSM S3C2410_GPA(13) /* v1 + v2 + v3 only */
+
+#define GTA02_GPIO_PWR_LED1 S3C2410_GPB(0)
+#define GTA02_GPIO_PWR_LED2 S3C2410_GPB(1)
+#define GTA02_GPIO_AUX_LED S3C2410_GPB(2)
+#define GTA02_GPIO_VIBRATOR_ON S3C2410_GPB(3)
+#define GTA02_GPIO_MODEM_RST S3C2410_GPB(5)
+#define GTA02_GPIO_BT_EN S3C2410_GPB(6)
+#define GTA02_GPIO_MODEM_ON S3C2410_GPB(7)
+#define GTA02_GPIO_EXTINT8 S3C2410_GPB(8)
+#define GTA02_GPIO_USB_PULLUP S3C2410_GPB(9)
+
+#define GTA02_GPIO_PIO5 S3C2410_GPC(5) /* v3 + v4 only */
+
+#define GTA02v3_GPIO_nG1_CS S3C2410_GPD(12) /* v3 + v4 only */
+#define GTA02v3_GPIO_nG2_CS S3C2410_GPD(13) /* v3 + v4 only */
+#define GTA02v5_GPIO_HDQ S3C2410_GPD(14) /* v5 + */
+
+#define GTA02_GPIO_nG1_INT S3C2410_GPF(0)
+#define GTA02_GPIO_IO1 S3C2410_GPF(1)
+#define GTA02_GPIO_PIO_2 S3C2410_GPF(2) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_JACK_INSERT S3C2410_GPF(4)
+#define GTA02_GPIO_WLAN_GPIO1 S3C2410_GPF(5) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_AUX_KEY S3C2410_GPF(6)
+#define GTA02_GPIO_HOLD_KEY S3C2410_GPF(7)
+
+#define GTA02_GPIO_3D_IRQ S3C2410_GPG(4)
+#define GTA02v2_GPIO_nG2_INT S3C2410_GPG(8) /* v2 + v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_OC S3C2410_GPG(9) /* v3 + v4 only */
+#define GTA02v3_GPIO_nUSB_FLT S3C2410_GPG(10) /* v3 + v4 only */
+#define GTA02v3_GPIO_nGSM_OC S3C2410_GPG(11) /* v3 + v4 only */
+
+#define GTA02_GPIO_AMP_SHUT S3C2410_GPJ(1) /* v2 + v3 + v4 only */
+#define GTA02v1_GPIO_WLAN_GPIO10 S3C2410_GPJ(2)
+#define GTA02_GPIO_HP_IN S3C2410_GPJ(2) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_INT0 S3C2410_GPJ(3) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_nGSM_EN S3C2410_GPJ(4)
+#define GTA02_GPIO_3D_RESET S3C2410_GPJ(5)
+#define GTA02_GPIO_nDL_GSM S3C2410_GPJ(6) /* v4 + v5 only */
+#define GTA02_GPIO_WLAN_GPIO0 S3C2410_GPJ(7)
+#define GTA02v1_GPIO_BAT_ID S3C2410_GPJ(8)
+#define GTA02_GPIO_KEEPACT S3C2410_GPJ(8)
+#define GTA02v1_GPIO_HP_IN S3C2410_GPJ(10)
+#define GTA02_CHIP_PWD S3C2410_GPJ(11) /* v2 + v3 + v4 only */
+#define GTA02_GPIO_nWLAN_RESET S3C2410_GPJ(12) /* v2 + v3 + v4 only */
+
+#define GTA02_IRQ_GSENSOR_1 IRQ_EINT0
+#define GTA02_IRQ_MODEM IRQ_EINT1
+#define GTA02_IRQ_PIO_2 IRQ_EINT2 /* v2 + v3 + v4 only */
+#define GTA02_IRQ_nJACK_INSERT IRQ_EINT4
+#define GTA02_IRQ_WLAN_GPIO1 IRQ_EINT5
+#define GTA02_IRQ_AUX IRQ_EINT6
+#define GTA02_IRQ_nHOLD IRQ_EINT7
+#define GTA02_IRQ_PCF50633 IRQ_EINT9
+#define GTA02_IRQ_3D IRQ_EINT12
+#define GTA02_IRQ_GSENSOR_2 IRQ_EINT16 /* v2 + v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_OC IRQ_EINT17 /* v3 + v4 only */
+#define GTA02v3_IRQ_nUSB_FLT IRQ_EINT18 /* v3 + v4 only */
+#define GTA02v3_IRQ_nGSM_OC IRQ_EINT19 /* v3 + v4 only */
+
+/* returns 00 000 on GTA02 A5 and earlier, A6 returns 01 001 */
+#define GTA02_PCB_ID1_0 S3C2410_GPC(13)
+#define GTA02_PCB_ID1_1 S3C2410_GPC(15)
+#define GTA02_PCB_ID1_2 S3C2410_GPD(0)
+#define GTA02_PCB_ID2_0 S3C2410_GPD(3)
+#define GTA02_PCB_ID2_1 S3C2410_GPD(4)
+
+int gta02_get_pcb_revision(void);
+
+#endif /* _GTA02_H */
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
new file mode 100644
index 00000000..eb1cc0f0
--- /dev/null
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -0,0 +1,126 @@
+/* linux/arch/arm/mach-s3c2440/irq.c
+ *
+ * Copyright (c) 2003-2004 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* WDT/AC97 */
+
+static void s3c_irq_demux_wdtac97(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= 13;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ generic_handle_irq(IRQ_S3C2440_WDT);
+ }
+ if (subsrc & 2) {
+ generic_handle_irq(IRQ_S3C2440_AC97);
+ }
+ }
+}
+
+
+#define INTMSK_WDT (1UL << (IRQ_WDT - IRQ_EINT0))
+
+static void
+s3c_irq_wdtac97_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_WDT, 3 << 13);
+}
+
+static void
+s3c_irq_wdtac97_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_WDT);
+}
+
+static void
+s3c_irq_wdtac97_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_WDT, 3 << 13);
+}
+
+static struct irq_chip s3c_irq_wdtac97 = {
+ .irq_mask = s3c_irq_wdtac97_mask,
+ .irq_unmask = s3c_irq_wdtac97_unmask,
+ .irq_ack = s3c_irq_wdtac97_ack,
+};
+
+static int s3c2440_irq_add(struct sys_device *sysdev)
+{
+ unsigned int irqno;
+
+ printk("S3C2440: IRQ Support\n");
+
+ /* add new chained handler for wdt, ac7 */
+
+ irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
+ handle_level_irq);
+ irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+
+ for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
+ irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+ .add = s3c2440_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
new file mode 100644
index 00000000..d7086788
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -0,0 +1,506 @@
+/* linux/arch/arm/mach-s3c2440/mach-anubis.c
+ *
+ * Copyright 2003-2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/sm501.h>
+#include <linux/sm501-regs.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/anubis-map.h>
+#include <mach/anubis-irq.h>
+#include <mach/anubis-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <net/ax88796.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/audio-simtec.h>
+
+#define COPYRIGHT ", Copyright 2005-2009 Simtec Electronics"
+
+static struct map_desc anubis_iodesc[] __initdata = {
+ /* ISA IO areas */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(0x0),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(0x0),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ },
+
+ /* we could possibly compress the next set down into a set of smaller tables
+ * pagetables, but that would mean using an L2 section, and it still means
+ * we cannot actually feed the same register to an LDR due to 16K spacing
+ */
+
+ /* CPLD control registers */
+
+ {
+ .virtual = (u32)ANUBIS_VA_CTRL1,
+ .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)ANUBIS_VA_IDREG,
+ .pfn = __phys_to_pfn(ANUBIS_PA_IDREG),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+
+static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = anubis_serial_clocks,
+ .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+ },
+ [1] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = anubis_serial_clocks,
+ .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
+ },
+};
+
+/* NAND Flash on Anubis board */
+
+static int external_map[] = { 2 };
+static int chip0_map[] = { 0 };
+static int chip1_map[] = { 1 };
+
+static struct mtd_partition __initdata anubis_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_16K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "/boot",
+ .size = SZ_4M - SZ_16K,
+ .offset = SZ_16K,
+ },
+ [2] = {
+ .name = "user1",
+ .offset = SZ_4M,
+ .size = SZ_32M - SZ_4M,
+ },
+ [3] = {
+ .name = "user2",
+ .offset = SZ_32M,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct mtd_partition __initdata anubis_default_nand_part_large[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_128K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "/boot",
+ .size = SZ_4M - SZ_128K,
+ .offset = SZ_128K,
+ },
+ [2] = {
+ .name = "user1",
+ .offset = SZ_4M,
+ .size = SZ_32M - SZ_4M,
+ },
+ [3] = {
+ .name = "user2",
+ .offset = SZ_32M,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+/* the Anubis has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata anubis_nand_sets[] = {
+ [1] = {
+ .name = "External",
+ .nr_chips = 1,
+ .nr_map = external_map,
+ .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
+ .partitions = anubis_default_nand_part,
+ },
+ [0] = {
+ .name = "chip0",
+ .nr_chips = 1,
+ .nr_map = chip0_map,
+ .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
+ .partitions = anubis_default_nand_part,
+ },
+ [2] = {
+ .name = "chip1",
+ .nr_chips = 1,
+ .nr_map = chip1_map,
+ .nr_partitions = ARRAY_SIZE(anubis_default_nand_part),
+ .partitions = anubis_default_nand_part,
+ },
+};
+
+static void anubis_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+ unsigned int tmp;
+
+ slot = set->nr_map[slot] & 3;
+
+ pr_debug("anubis_nand: selecting slot %d (set %p,%p)\n",
+ slot, set, set->nr_map);
+
+ tmp = __raw_readb(ANUBIS_VA_CTRL1);
+ tmp &= ~ANUBIS_CTRL1_NANDSEL;
+ tmp |= slot;
+
+ pr_debug("anubis_nand: ctrl1 now %02x\n", tmp);
+
+ __raw_writeb(tmp, ANUBIS_VA_CTRL1);
+}
+
+static struct s3c2410_platform_nand __initdata anubis_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(anubis_nand_sets),
+ .sets = anubis_nand_sets,
+ .select_chip = anubis_nand_select,
+};
+
+/* IDE channels */
+
+static struct pata_platform_info anubis_ide_platdata = {
+ .ioport_shift = 5,
+};
+
+static struct resource anubis_ide0_resource[] = {
+ {
+ .start = S3C2410_CS3,
+ .end = S3C2410_CS3 + (8*32) - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = S3C2410_CS3 + (1<<26) + (6*32),
+ .end = S3C2410_CS3 + (1<<26) + (7*32) - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_IDE0,
+ .end = IRQ_IDE0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device anubis_device_ide0 = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(anubis_ide0_resource),
+ .resource = anubis_ide0_resource,
+ .dev = {
+ .platform_data = &anubis_ide_platdata,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static struct resource anubis_ide1_resource[] = {
+ {
+ .start = S3C2410_CS4,
+ .end = S3C2410_CS4 + (8*32) - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = S3C2410_CS4 + (1<<26) + (6*32),
+ .end = S3C2410_CS4 + (1<<26) + (7*32) - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_IDE0,
+ .end = IRQ_IDE0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device anubis_device_ide1 = {
+ .name = "pata_platform",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(anubis_ide1_resource),
+ .resource = anubis_ide1_resource,
+ .dev = {
+ .platform_data = &anubis_ide_platdata,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/* Asix AX88796 10/100 ethernet controller */
+
+static struct ax_plat_data anubis_asix_platdata = {
+ .flags = AXFLG_MAC_FROMDEV,
+ .wordlength = 2,
+ .dcr_val = 0x48,
+ .rcr_val = 0x40,
+};
+
+static struct resource anubis_asix_resource[] = {
+ [0] = {
+ .start = S3C2410_CS5,
+ .end = S3C2410_CS5 + (0x20 * 0x20) -1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = IRQ_ASIX,
+ .end = IRQ_ASIX,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct platform_device anubis_device_asix = {
+ .name = "ax88796",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(anubis_asix_resource),
+ .resource = anubis_asix_resource,
+ .dev = {
+ .platform_data = &anubis_asix_platdata,
+ }
+};
+
+/* SM501 */
+
+static struct resource anubis_sm501_resource[] = {
+ [0] = {
+ .start = S3C2410_CS2,
+ .end = S3C2410_CS2 + SZ_8M,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C2410_CS2 + SZ_64M - SZ_2M,
+ .end = S3C2410_CS2 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT0,
+ .end = IRQ_EINT0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sm501_initdata anubis_sm501_initdata = {
+ .gpio_high = {
+ .set = 0x3F000000, /* 24bit panel */
+ .mask = 0x0,
+ },
+ .misc_timing = {
+ .set = 0x010100, /* SDRAM timing */
+ .mask = 0x1F1F00,
+ },
+ .misc_control = {
+ .set = SM501_MISC_PNL_24BIT,
+ .mask = 0,
+ },
+
+ .devices = SM501_USE_GPIO,
+
+ /* set the SDRAM and bus clocks */
+ .mclk = 72 * MHZ,
+ .m1xclk = 144 * MHZ,
+};
+
+static struct sm501_platdata_gpio_i2c anubis_sm501_gpio_i2c[] = {
+ [0] = {
+ .bus_num = 1,
+ .pin_scl = 44,
+ .pin_sda = 45,
+ },
+ [1] = {
+ .bus_num = 2,
+ .pin_scl = 40,
+ .pin_sda = 41,
+ },
+};
+
+static struct sm501_platdata anubis_sm501_platdata = {
+ .init = &anubis_sm501_initdata,
+ .gpio_base = -1,
+ .gpio_i2c = anubis_sm501_gpio_i2c,
+ .gpio_i2c_nr = ARRAY_SIZE(anubis_sm501_gpio_i2c),
+};
+
+static struct platform_device anubis_device_sm501 = {
+ .name = "sm501",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(anubis_sm501_resource),
+ .resource = anubis_sm501_resource,
+ .dev = {
+ .platform_data = &anubis_sm501_platdata,
+ },
+};
+
+/* Standard Anubis devices */
+
+static struct platform_device *anubis_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_adc,
+ &s3c_device_i2c0,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &anubis_device_ide0,
+ &anubis_device_ide1,
+ &anubis_device_asix,
+ &anubis_device_sm501,
+};
+
+static struct clk *anubis_clocks[] __initdata = {
+ &s3c24xx_dclk0,
+ &s3c24xx_dclk1,
+ &s3c24xx_clkout0,
+ &s3c24xx_clkout1,
+ &s3c24xx_uclk,
+};
+
+/* I2C devices. */
+
+static struct i2c_board_info anubis_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tps65011", 0x48),
+ .irq = IRQ_EINT20,
+ }
+};
+
+/* Audio setup */
+static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
+ .have_mic = 1,
+ .have_lout = 1,
+ .output_cdclk = 1,
+ .use_mpllin = 1,
+ .amp_gpio = S3C2410_GPB(2),
+ .amp_gain[0] = S3C2410_GPD(10),
+ .amp_gain[1] = S3C2410_GPD(11),
+};
+
+static void __init anubis_map_io(void)
+{
+ /* initialise the clocks */
+
+ s3c24xx_dclk0.parent = &clk_upll;
+ s3c24xx_dclk0.rate = 12*1000*1000;
+
+ s3c24xx_dclk1.parent = &clk_upll;
+ s3c24xx_dclk1.rate = 24*1000*1000;
+
+ s3c24xx_clkout0.parent = &s3c24xx_dclk0;
+ s3c24xx_clkout1.parent = &s3c24xx_dclk1;
+
+ s3c24xx_uclk.parent = &s3c24xx_clkout1;
+
+ s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+
+ s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+
+ /* check for the newer revision boards with large page nand */
+
+ if ((__raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK) >= 4) {
+ printk(KERN_INFO "ANUBIS-B detected (revision %d)\n",
+ __raw_readb(ANUBIS_VA_IDREG) & ANUBIS_IDREG_REVMASK);
+ anubis_nand_sets[0].partitions = anubis_default_nand_part_large;
+ anubis_nand_sets[0].nr_partitions = ARRAY_SIZE(anubis_default_nand_part_large);
+ } else {
+ /* ensure that the GPIO is setup */
+ s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
+ }
+}
+
+static void __init anubis_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_nand_set_platdata(&anubis_nand_info);
+ simtec_audio_add(NULL, false, &anubis_audio);
+
+ platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
+
+ i2c_register_board_info(0, anubis_i2c_devs,
+ ARRAY_SIZE(anubis_i2c_devs));
+}
+
+
+MACHINE_START(ANUBIS, "Simtec-Anubis")
+ /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = anubis_map_io,
+ .init_machine = anubis_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
new file mode 100644
index 00000000..6c98b789
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -0,0 +1,241 @@
+/* linux/arch/arm/mach-s3c2440/mach-at2440evb.c
+ *
+ * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
+ * Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
+ * and modifications by SBZ <sbz@spgui.org> and
+ * Weibing <http://weibing.blogbus.com>
+ *
+ * For product information, visit http://www.arm.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/dm9000.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/mci.h>
+
+static struct map_desc at2440evb_iodesc[] __initdata = {
+ /* Nothing here */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+
+static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = at2440evb_serial_clocks,
+ .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = at2440evb_serial_clocks,
+ .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
+ },
+};
+
+/* NAND Flash on AT2440EVB board */
+
+static struct mtd_partition __initdata at2440evb_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_256K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "Kernel",
+ .size = SZ_2M,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "Root",
+ .offset = SZ_256K + SZ_2M,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct s3c2410_nand_set __initdata at2440evb_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(at2440evb_default_nand_part),
+ .partitions = at2440evb_default_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand __initdata at2440evb_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(at2440evb_nand_sets),
+ .sets = at2440evb_nand_sets,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource at2440evb_dm9k_resource[] = {
+ [0] = {
+ .start = S3C2410_CS3,
+ .end = S3C2410_CS3 + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C2410_CS3 + 4,
+ .end = S3C2410_CS3 + 7,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = IRQ_EINT7,
+ .end = IRQ_EINT7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+static struct dm9000_plat_data at2440evb_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device at2440evb_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(at2440evb_dm9k_resource),
+ .resource = at2440evb_dm9k_resource,
+ .dev = {
+ .platform_data = &at2440evb_dm9k_pdata,
+ },
+};
+
+static struct s3c24xx_mci_pdata at2440evb_mci_pdata __initdata = {
+ .gpio_detect = S3C2410_GPG(10),
+};
+
+/* 7" LCD panel */
+
+static struct s3c2410fb_display at2440evb_lcd_cfg __initdata = {
+
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+
+ .width = 800,
+ .height = 480,
+
+ .pixclock = 33333, /* HCLK 60 MHz, divisor 2 */
+ .xres = 800,
+ .yres = 480,
+ .bpp = 16,
+ .left_margin = 88,
+ .right_margin = 40,
+ .hsync_len = 128,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .vsync_len = 2,
+};
+
+static struct s3c2410fb_mach_info at2440evb_fb_info __initdata = {
+ .displays = &at2440evb_lcd_cfg,
+ .num_displays = 1,
+ .default_display = 0,
+};
+
+static struct platform_device *at2440evb_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_adc,
+ &s3c_device_i2c0,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &s3c_device_sdi,
+ &s3c_device_lcd,
+ &at2440evb_device_eth,
+};
+
+static void __init at2440evb_map_io(void)
+{
+ s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
+ s3c24xx_init_clocks(16934400);
+ s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+}
+
+static void __init at2440evb_init(void)
+{
+ s3c24xx_fb_set_platdata(&at2440evb_fb_info);
+ s3c24xx_mci_set_platdata(&at2440evb_mci_pdata);
+ s3c_nand_set_platdata(&at2440evb_nand_info);
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(at2440evb_devices, ARRAY_SIZE(at2440evb_devices));
+}
+
+
+MACHINE_START(AT2440EVB, "AT2440EVB")
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = at2440evb_map_io,
+ .init_machine = at2440evb_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
new file mode 100644
index 00000000..71666200
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -0,0 +1,604 @@
+/*
+ * linux/arch/arm/mach-s3c2442/mach-gta02.c
+ *
+ * S3C2442 Machine Support for Openmoko GTA02 / FreeRunner.
+ *
+ * Copyright (C) 2006-2009 by Openmoko, Inc.
+ * Authors: Harald Welte <laforge@openmoko.org>
+ * Andy Green <andy@openmoko.org>
+ * Werner Almesberger <werner@openmoko.org>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mmc/host.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/io.h>
+
+#include <linux/i2c.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+#include <linux/mfd/pcf50633/adc.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
+#include <linux/mfd/pcf50633/backlight.h>
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/fb.h>
+
+#include <mach/spi.h>
+#include <mach/spi-gpio.h>
+#include <plat/usb-control.h>
+#include <mach/regs-mem.h>
+#include <mach/hardware.h>
+
+#include <mach/gta02.h>
+
+#include <plat/regs-serial.h>
+#include <plat/nand.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/udc.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <plat/ts.h>
+
+
+static struct pcf50633 *gta02_pcf;
+
+/*
+ * This gets called frequently when we paniced.
+ */
+
+static long gta02_panic_blink(int state)
+{
+ long delay = 0;
+ char led;
+
+ led = (state) ? 1 : 0;
+ gpio_direction_output(GTA02_GPIO_AUX_LED, led);
+
+ return delay;
+}
+
+
+static struct map_desc gta02_iodesc[] __initdata = {
+ {
+ .virtual = 0xe0000000,
+ .pfn = __phys_to_pfn(S3C2410_CS3 + 0x01000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ },
+};
+
+#define UCON (S3C2410_UCON_DEFAULT | S3C2443_UCON_RXERR_IRQEN)
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg gta02_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+#ifdef CONFIG_CHARGER_PCF50633
+/*
+ * On GTA02 the 1A charger features a 48K resistor to 0V on the ID pin.
+ * We use this to recognize that we can pull 1A from the USB socket.
+ *
+ * These constants are the measured pcf50633 ADC levels with the 1A
+ * charger / 48K resistor, and with no pulldown resistor.
+ */
+
+#define ADC_NOM_CHG_DETECT_1A 6
+#define ADC_NOM_CHG_DETECT_USB 43
+
+static void
+gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
+{
+ int ma;
+
+ /* Interpret charger type */
+ if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
+
+ /*
+ * Sanity - stop GPO driving out now that we have a 1A charger
+ * GPO controls USB Host power generation on GTA02
+ */
+ pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
+
+ ma = 1000;
+ } else
+ ma = 100;
+
+ pcf50633_mbc_usb_curlim_set(pcf, ma);
+}
+
+static struct delayed_work gta02_charger_work;
+static int gta02_usb_vbus_draw;
+
+static void gta02_charger_worker(struct work_struct *work)
+{
+ if (gta02_usb_vbus_draw) {
+ pcf50633_mbc_usb_curlim_set(gta02_pcf, gta02_usb_vbus_draw);
+ return;
+ }
+
+#ifdef CONFIG_PCF50633_ADC
+ pcf50633_adc_async_read(gta02_pcf,
+ PCF50633_ADCC1_MUX_ADCIN1,
+ PCF50633_ADCC1_AVERAGE_16,
+ gta02_configure_pmu_for_charger,
+ NULL);
+#else
+ /*
+ * If the PCF50633 ADC is disabled we fallback to a
+ * 100mA limit for safety.
+ */
+ pcf50633_mbc_usb_curlim_set(pcf, 100);
+#endif
+}
+
+#define GTA02_CHARGER_CONFIGURE_TIMEOUT ((3000 * HZ) / 1000)
+
+static void gta02_pmu_event_callback(struct pcf50633 *pcf, int irq)
+{
+ if (irq == PCF50633_IRQ_USBINS) {
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+
+ return;
+ }
+
+ if (irq == PCF50633_IRQ_USBREM) {
+ cancel_delayed_work_sync(&gta02_charger_work);
+ gta02_usb_vbus_draw = 0;
+ }
+}
+
+static void gta02_udc_vbus_draw(unsigned int ma)
+{
+ if (!gta02_pcf)
+ return;
+
+ gta02_usb_vbus_draw = ma;
+
+ schedule_delayed_work(&gta02_charger_work,
+ GTA02_CHARGER_CONFIGURE_TIMEOUT);
+}
+#else /* !CONFIG_CHARGER_PCF50633 */
+#define gta02_pmu_event_callback NULL
+#define gta02_udc_vbus_draw NULL
+#endif
+
+/*
+ * This is called when pc50633 is probed, unfortunately quite late in the
+ * day since it is an I2C bus device. Here we can belatedly define some
+ * platform devices with the advantage that we can mark the pcf50633 as the
+ * parent. This makes them get suspended and resumed with their parent
+ * the pcf50633 still around.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf);
+
+
+static char *gta02_batteries[] = {
+ "battery",
+};
+
+static struct pcf50633_bl_platform_data gta02_backlight_data = {
+ .default_brightness = 0x3f,
+ .default_brightness_limit = 0,
+ .ramp_time = 5,
+};
+
+struct pcf50633_platform_data gta02_pcf_pdata = {
+ .resumers = {
+ [0] = PCF50633_INT1_USBINS |
+ PCF50633_INT1_USBREM |
+ PCF50633_INT1_ALARM,
+ [1] = PCF50633_INT2_ONKEYF,
+ [2] = PCF50633_INT3_ONKEY1S,
+ [3] = PCF50633_INT4_LOWSYS |
+ PCF50633_INT4_LOWBAT |
+ PCF50633_INT4_HIGHTMP,
+ },
+
+ .batteries = gta02_batteries,
+ .num_batteries = ARRAY_SIZE(gta02_batteries),
+
+ .charger_reference_current_ma = 1000,
+
+ .backlight_data = &gta02_backlight_data,
+
+ .reg_init_data = {
+ [PCF50633_REGULATOR_AUTO] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_DOWN1] = {
+ .constraints = {
+ .min_uV = 1300000,
+ .max_uV = 1600000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_DOWN2] = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+ },
+ [PCF50633_REGULATOR_HCLDO] = {
+ .constraints = {
+ .min_uV = 2000000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ },
+ [PCF50633_REGULATOR_LDO1] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO2] = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO3] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO4] = {
+ .constraints = {
+ .min_uV = 3200000,
+ .max_uV = 3200000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO5] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ .apply_uV = 1,
+ },
+ },
+ [PCF50633_REGULATOR_LDO6] = {
+ .constraints = {
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ },
+ },
+ [PCF50633_REGULATOR_MEMLDO] = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ },
+ },
+
+ },
+ .probe_done = gta02_pmu_attach_child_devices,
+ .mbc_event_callback = gta02_pmu_event_callback,
+};
+
+
+/* NOR Flash. */
+
+#define GTA02_FLASH_BASE 0x18000000 /* GCS3 */
+#define GTA02_FLASH_SIZE 0x200000 /* 2MBytes */
+
+static struct physmap_flash_data gta02_nor_flash_data = {
+ .width = 2,
+};
+
+static struct resource gta02_nor_flash_resource = {
+ .start = GTA02_FLASH_BASE,
+ .end = GTA02_FLASH_BASE + GTA02_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device gta02_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &gta02_nor_flash_data,
+ },
+ .resource = &gta02_nor_flash_resource,
+ .num_resources = 1,
+};
+
+
+struct platform_device s3c24xx_pwm_device = {
+ .name = "s3c24xx_pwm",
+ .num_resources = 0,
+};
+
+static struct platform_device gta02_dfbmcs320_device = {
+ .name = "dfbmcs320",
+};
+
+static struct i2c_board_info gta02_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf50633", 0x73),
+ .irq = GTA02_IRQ_PCF50633,
+ .platform_data = &gta02_pcf_pdata,
+ },
+ {
+ I2C_BOARD_INFO("wm8753", 0x1a),
+ },
+};
+
+static struct s3c2410_nand_set __initdata gta02_nand_sets[] = {
+ [0] = {
+ /*
+ * This name is also hard-coded in the boot loaders, so
+ * changing it would would require all users to upgrade
+ * their boot loaders, some of which are stored in a NOR
+ * that is considered to be immutable.
+ */
+ .name = "neo1973-nand",
+ .nr_chips = 1,
+ .flash_bbt = 1,
+ },
+};
+
+/*
+ * Choose a set of timings derived from S3C@2442B MCP54
+ * data sheet (K5D2G13ACM-D075 MCP Memory).
+ */
+
+static struct s3c2410_platform_nand __initdata gta02_nand_info = {
+ .tacls = 0,
+ .twrph0 = 25,
+ .twrph1 = 15,
+ .nr_sets = ARRAY_SIZE(gta02_nand_sets),
+ .sets = gta02_nand_sets,
+};
+
+
+/* Get PMU to set USB current limit accordingly. */
+static struct s3c2410_udc_mach_info gta02_udc_cfg __initdata = {
+ .vbus_draw = gta02_udc_vbus_draw,
+ .pullup_pin = GTA02_GPIO_USB_PULLUP,
+};
+
+/* USB */
+static struct s3c2410_hcd_info gta02_usb_info __initdata = {
+ .port[0] = {
+ .flags = S3C_HCDFLG_USED,
+ },
+ .port[1] = {
+ .flags = 0,
+ },
+};
+
+/* Touchscreen */
+static struct s3c2410_ts_mach_info gta02_ts_info = {
+ .delay = 10000,
+ .presc = 0xff, /* slow as we can go */
+ .oversampling_shift = 2,
+};
+
+/* Buttons */
+static struct gpio_keys_button gta02_buttons[] = {
+ {
+ .gpio = GTA02_GPIO_AUX_KEY,
+ .code = KEY_PHONE,
+ .desc = "Aux",
+ .type = EV_KEY,
+ .debounce_interval = 100,
+ },
+ {
+ .gpio = GTA02_GPIO_HOLD_KEY,
+ .code = KEY_PAUSE,
+ .desc = "Hold",
+ .type = EV_KEY,
+ .debounce_interval = 100,
+ },
+};
+
+static struct gpio_keys_platform_data gta02_buttons_pdata = {
+ .buttons = gta02_buttons,
+ .nbuttons = ARRAY_SIZE(gta02_buttons),
+};
+
+static struct platform_device gta02_buttons_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gta02_buttons_pdata,
+ },
+};
+
+static void __init gta02_map_io(void)
+{
+ s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+}
+
+
+/* These are the guys that don't need to be children of PMU. */
+
+static struct platform_device *gta02_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_sdi,
+ &s3c_device_usbgadget,
+ &s3c_device_nand,
+ &gta02_nor_flash,
+ &s3c24xx_pwm_device,
+ &s3c_device_iis,
+ &samsung_asoc_dma,
+ &s3c_device_i2c0,
+ &gta02_dfbmcs320_device,
+ &gta02_buttons_device,
+ &s3c_device_adc,
+ &s3c_device_ts,
+};
+
+/* These guys DO need to be children of PMU. */
+
+static struct platform_device *gta02_devices_pmu_children[] = {
+};
+
+
+/*
+ * This is called when pc50633 is probed, quite late in the day since it is an
+ * I2C bus device. Here we can define platform devices with the advantage that
+ * we can mark the pcf50633 as the parent. This makes them get suspended and
+ * resumed with their parent the pcf50633 still around. All devices whose
+ * operation depends on something from pcf50633 must have this relationship
+ * made explicit like this, or suspend and resume will become an unreliable
+ * hellworld.
+ */
+
+static void gta02_pmu_attach_child_devices(struct pcf50633 *pcf)
+{
+ int n;
+
+ /* Grab a copy of the now probed PMU pointer. */
+ gta02_pcf = pcf;
+
+ for (n = 0; n < ARRAY_SIZE(gta02_devices_pmu_children); n++)
+ gta02_devices_pmu_children[n]->dev.parent = pcf->dev;
+
+ platform_add_devices(gta02_devices_pmu_children,
+ ARRAY_SIZE(gta02_devices_pmu_children));
+}
+
+static void gta02_poweroff(void)
+{
+ pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
+}
+
+static void __init gta02_machine_init(void)
+{
+ /* Set the panic callback to turn AUX LED on or off. */
+ panic_blink = gta02_panic_blink;
+
+ s3c_pm_init();
+
+#ifdef CONFIG_CHARGER_PCF50633
+ INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
+#endif
+
+ s3c24xx_udc_set_platdata(&gta02_udc_cfg);
+ s3c24xx_ts_set_platdata(&gta02_ts_info);
+ s3c_ohci_set_platdata(&gta02_usb_info);
+ s3c_nand_set_platdata(&gta02_nand_info);
+ s3c_i2c0_set_platdata(NULL);
+
+ i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
+
+ platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
+ pm_power_off = gta02_poweroff;
+
+ regulator_has_full_constraints();
+}
+
+
+MACHINE_START(NEO1973_GTA02, "GTA02")
+ /* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = gta02_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = gta02_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c
new file mode 100644
index 00000000..fc2dc0b3
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-mini2440.c
@@ -0,0 +1,684 @@
+/* linux/arch/arm/mach-s3c2440/mach-mini2440.c
+ *
+ * Copyright (c) 2008 Ramax Lo <ramaxlo@gmail.com>
+ * Based on mach-anubis.c by Ben Dooks <ben@simtec.co.uk>
+ * and modifications by SBZ <sbz@spgui.org> and
+ * Weibing <http://weibing.blogbus.com> and
+ * Michel Pollet <buserror@gmail.com>
+ *
+ * For product information, visit http://code.google.com/p/mini2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_core.h>
+#include <linux/dm9000.h>
+#include <linux/i2c/at24.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/fb.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/irqs.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <sound/s3c24xx_uda134x.h>
+
+#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
+
+static struct map_desc mini2440_iodesc[] __initdata = {
+ /* nothing to declare, move along */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+
+static struct s3c2410_uartcfg mini2440_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* USB device UDC support */
+
+static struct s3c2410_udc_mach_info mini2440_udc_cfg __initdata = {
+ .pullup_pin = S3C2410_GPC(5),
+};
+
+
+/* LCD timing and setup */
+
+/*
+ * This macro simplifies the table bellow
+ */
+#define _LCD_DECLARE(_clock,_xres,margin_left,margin_right,hsync, \
+ _yres,margin_top,margin_bottom,vsync, refresh) \
+ .width = _xres, \
+ .xres = _xres, \
+ .height = _yres, \
+ .yres = _yres, \
+ .left_margin = margin_left, \
+ .right_margin = margin_right, \
+ .upper_margin = margin_top, \
+ .lower_margin = margin_bottom, \
+ .hsync_len = hsync, \
+ .vsync_len = vsync, \
+ .pixclock = ((_clock*100000000000LL) / \
+ ((refresh) * \
+ (hsync + margin_left + _xres + margin_right) * \
+ (vsync + margin_top + _yres + margin_bottom))), \
+ .bpp = 16,\
+ .type = (S3C2410_LCDCON1_TFT16BPP |\
+ S3C2410_LCDCON1_TFT)
+
+static struct s3c2410fb_display mini2440_lcd_cfg[] __initdata = {
+ [0] = { /* mini2440 + 3.5" TFT + touchscreen */
+ _LCD_DECLARE(
+ 7, /* The 3.5 is quite fast */
+ 240, 21, 38, 6, /* x timing */
+ 320, 4, 4, 2, /* y timing */
+ 60), /* refresh rate */
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_INVVDEN |
+ S3C2410_LCDCON5_PWREN),
+ },
+ [1] = { /* mini2440 + 7" TFT + touchscreen */
+ _LCD_DECLARE(
+ 10, /* the 7" runs slower */
+ 800, 40, 40, 48, /* x timing */
+ 480, 29, 3, 3, /* y timing */
+ 50), /* refresh rate */
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN),
+ },
+ /* The VGA shield can outout at several resolutions. All share
+ * the same timings, however, anything smaller than 1024x768
+ * will only be displayed in the top left corner of a 1024x768
+ * XGA output unless you add optional dip switches to the shield.
+ * Therefore timings for other resolutions have been omitted here.
+ */
+ [2] = {
+ _LCD_DECLARE(
+ 10,
+ 1024, 1, 2, 2, /* y timing */
+ 768, 200, 16, 16, /* x timing */
+ 24), /* refresh rate, maximum stable,
+ tested with the FPGA shield */
+ .lcdcon5 = (S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_HWSWP),
+ },
+};
+
+/* todo - put into gpio header */
+
+#define S3C2410_GPCCON_MASK(x) (3 << ((x) * 2))
+#define S3C2410_GPDCON_MASK(x) (3 << ((x) * 2))
+
+static struct s3c2410fb_mach_info mini2440_fb_info __initdata = {
+ .displays = &mini2440_lcd_cfg[0], /* not constant! see init */
+ .num_displays = 1,
+ .default_display = 0,
+
+ /* Enable VD[2..7], VD[10..15], VD[18..23] and VCLK, syncs, VDEN
+ * and disable the pull down resistors on pins we are using for LCD
+ * data. */
+
+ .gpcup = (0xf << 1) | (0x3f << 10),
+
+ .gpccon = (S3C2410_GPC1_VCLK | S3C2410_GPC2_VLINE |
+ S3C2410_GPC3_VFRAME | S3C2410_GPC4_VM |
+ S3C2410_GPC10_VD2 | S3C2410_GPC11_VD3 |
+ S3C2410_GPC12_VD4 | S3C2410_GPC13_VD5 |
+ S3C2410_GPC14_VD6 | S3C2410_GPC15_VD7),
+
+ .gpccon_mask = (S3C2410_GPCCON_MASK(1) | S3C2410_GPCCON_MASK(2) |
+ S3C2410_GPCCON_MASK(3) | S3C2410_GPCCON_MASK(4) |
+ S3C2410_GPCCON_MASK(10) | S3C2410_GPCCON_MASK(11) |
+ S3C2410_GPCCON_MASK(12) | S3C2410_GPCCON_MASK(13) |
+ S3C2410_GPCCON_MASK(14) | S3C2410_GPCCON_MASK(15)),
+
+ .gpdup = (0x3f << 2) | (0x3f << 10),
+
+ .gpdcon = (S3C2410_GPD2_VD10 | S3C2410_GPD3_VD11 |
+ S3C2410_GPD4_VD12 | S3C2410_GPD5_VD13 |
+ S3C2410_GPD6_VD14 | S3C2410_GPD7_VD15 |
+ S3C2410_GPD10_VD18 | S3C2410_GPD11_VD19 |
+ S3C2410_GPD12_VD20 | S3C2410_GPD13_VD21 |
+ S3C2410_GPD14_VD22 | S3C2410_GPD15_VD23),
+
+ .gpdcon_mask = (S3C2410_GPDCON_MASK(2) | S3C2410_GPDCON_MASK(3) |
+ S3C2410_GPDCON_MASK(4) | S3C2410_GPDCON_MASK(5) |
+ S3C2410_GPDCON_MASK(6) | S3C2410_GPDCON_MASK(7) |
+ S3C2410_GPDCON_MASK(10) | S3C2410_GPDCON_MASK(11)|
+ S3C2410_GPDCON_MASK(12) | S3C2410_GPDCON_MASK(13)|
+ S3C2410_GPDCON_MASK(14) | S3C2410_GPDCON_MASK(15)),
+};
+
+/* MMC/SD */
+
+static struct s3c24xx_mci_pdata mini2440_mmc_cfg __initdata = {
+ .gpio_detect = S3C2410_GPG(8),
+ .gpio_wprotect = S3C2410_GPH(8),
+ .set_power = NULL,
+ .ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34,
+};
+
+/* NAND Flash on MINI2440 board */
+
+static struct mtd_partition mini2440_default_nand_part[] __initdata = {
+ [0] = {
+ .name = "u-boot",
+ .size = SZ_256K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "u-boot-env",
+ .size = SZ_128K,
+ .offset = SZ_256K,
+ },
+ [2] = {
+ .name = "kernel",
+ /* 5 megabytes, for a kernel with no modules
+ * or a uImage with a ramdisk attached */
+ .size = 0x00500000,
+ .offset = SZ_256K + SZ_128K,
+ },
+ [3] = {
+ .name = "root",
+ .offset = SZ_256K + SZ_128K + 0x00500000,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct s3c2410_nand_set mini2440_nand_sets[] __initdata = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(mini2440_default_nand_part),
+ .partitions = mini2440_default_nand_part,
+ .flash_bbt = 1, /* we use u-boot to create a BBT */
+ },
+};
+
+static struct s3c2410_platform_nand mini2440_nand_info __initdata = {
+ .tacls = 0,
+ .twrph0 = 25,
+ .twrph1 = 15,
+ .nr_sets = ARRAY_SIZE(mini2440_nand_sets),
+ .sets = mini2440_nand_sets,
+ .ignore_unset_ecc = 1,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini2440_dm9k_resource[] = {
+ [0] = {
+ .start = MACH_MINI2440_DM9K_BASE,
+ .end = MACH_MINI2440_DM9K_BASE + 3,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = MACH_MINI2440_DM9K_BASE + 4,
+ .end = MACH_MINI2440_DM9K_BASE + 7,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = IRQ_EINT7,
+ .end = IRQ_EINT7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
+ }
+};
+
+/*
+ * The DM9000 has no eeprom, and it's MAC address is set by
+ * the bootloader before starting the kernel.
+ */
+static struct dm9000_plat_data mini2440_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini2440_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mini2440_dm9k_resource),
+ .resource = mini2440_dm9k_resource,
+ .dev = {
+ .platform_data = &mini2440_dm9k_pdata,
+ },
+};
+
+/* CON5
+ * +--+ /-----\
+ * | | | |
+ * | | | BAT |
+ * | | \_____/
+ * | |
+ * | | +----+ +----+
+ * | | | K5 | | K1 |
+ * | | +----+ +----+
+ * | | +----+ +----+
+ * | | | K4 | | K2 |
+ * | | +----+ +----+
+ * | | +----+ +----+
+ * | | | K6 | | K3 |
+ * | | +----+ +----+
+ * .....
+ */
+static struct gpio_keys_button mini2440_buttons[] = {
+ {
+ .gpio = S3C2410_GPG(0), /* K1 */
+ .code = KEY_F1,
+ .desc = "Button 1",
+ .active_low = 1,
+ },
+ {
+ .gpio = S3C2410_GPG(3), /* K2 */
+ .code = KEY_F2,
+ .desc = "Button 2",
+ .active_low = 1,
+ },
+ {
+ .gpio = S3C2410_GPG(5), /* K3 */
+ .code = KEY_F3,
+ .desc = "Button 3",
+ .active_low = 1,
+ },
+ {
+ .gpio = S3C2410_GPG(6), /* K4 */
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ },
+ {
+ .gpio = S3C2410_GPG(7), /* K5 */
+ .code = KEY_F5,
+ .desc = "Button 5",
+ .active_low = 1,
+ },
+#if 0
+ /* this pin is also known as TCLK1 and seems to already
+ * marked as "in use" somehow in the kernel -- possibly wrongly */
+ {
+ .gpio = S3C2410_GPG(11), /* K6 */
+ .code = KEY_F6,
+ .desc = "Button 6",
+ .active_low = 1,
+ },
+#endif
+};
+
+static struct gpio_keys_platform_data mini2440_button_data = {
+ .buttons = mini2440_buttons,
+ .nbuttons = ARRAY_SIZE(mini2440_buttons),
+};
+
+static struct platform_device mini2440_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &mini2440_button_data,
+ }
+};
+
+/* LEDS */
+
+static struct s3c24xx_led_platdata mini2440_led1_pdata = {
+ .name = "led1",
+ .gpio = S3C2410_GPB(5),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .def_trigger = "heartbeat",
+};
+
+static struct s3c24xx_led_platdata mini2440_led2_pdata = {
+ .name = "led2",
+ .gpio = S3C2410_GPB(6),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .def_trigger = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata mini2440_led3_pdata = {
+ .name = "led3",
+ .gpio = S3C2410_GPB(7),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .def_trigger = "mmc0",
+};
+
+static struct s3c24xx_led_platdata mini2440_led4_pdata = {
+ .name = "led4",
+ .gpio = S3C2410_GPB(8),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .def_trigger = "",
+};
+
+static struct s3c24xx_led_platdata mini2440_led_backlight_pdata = {
+ .name = "backlight",
+ .gpio = S3C2410_GPG(4),
+ .def_trigger = "backlight",
+};
+
+static struct platform_device mini2440_led1 = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &mini2440_led1_pdata,
+ },
+};
+
+static struct platform_device mini2440_led2 = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &mini2440_led2_pdata,
+ },
+};
+
+static struct platform_device mini2440_led3 = {
+ .name = "s3c24xx_led",
+ .id = 3,
+ .dev = {
+ .platform_data = &mini2440_led3_pdata,
+ },
+};
+
+static struct platform_device mini2440_led4 = {
+ .name = "s3c24xx_led",
+ .id = 4,
+ .dev = {
+ .platform_data = &mini2440_led4_pdata,
+ },
+};
+
+static struct platform_device mini2440_led_backlight = {
+ .name = "s3c24xx_led",
+ .id = 5,
+ .dev = {
+ .platform_data = &mini2440_led_backlight_pdata,
+ },
+};
+
+/* AUDIO */
+
+static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = {
+ .l3_clk = S3C2410_GPB(4),
+ .l3_mode = S3C2410_GPB(2),
+ .l3_data = S3C2410_GPB(3),
+ .model = UDA134X_UDA1341
+};
+
+static struct platform_device mini2440_audio = {
+ .name = "s3c24xx_uda134x",
+ .id = 0,
+ .dev = {
+ .platform_data = &mini2440_audio_pins,
+ },
+};
+
+/*
+ * I2C devices
+ */
+static struct at24_platform_data at24c08 = {
+ .byte_len = SZ_8K / 8,
+ .page_size = 16,
+};
+
+static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("24c08", 0x50),
+ .platform_data = &at24c08,
+ },
+};
+
+static struct platform_device uda1340_codec = {
+ .name = "uda134x-codec",
+ .id = -1,
+};
+
+static struct platform_device *mini2440_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_rtc,
+ &s3c_device_usbgadget,
+ &mini2440_device_eth,
+ &mini2440_led1,
+ &mini2440_led2,
+ &mini2440_led3,
+ &mini2440_led4,
+ &mini2440_button_device,
+ &s3c_device_nand,
+ &s3c_device_sdi,
+ &s3c_device_iis,
+ &uda1340_codec,
+ &mini2440_audio,
+ &samsung_asoc_dma,
+};
+
+static void __init mini2440_map_io(void)
+{
+ s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
+}
+
+/*
+ * mini2440_features string
+ *
+ * t = Touchscreen present
+ * b = backlight control
+ * c = camera [TODO]
+ * 0-9 LCD configuration
+ *
+ */
+static char mini2440_features_str[12] __initdata = "0tb";
+
+static int __init mini2440_features_setup(char *str)
+{
+ if (str)
+ strlcpy(mini2440_features_str, str, sizeof(mini2440_features_str));
+ return 1;
+}
+
+__setup("mini2440=", mini2440_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+#define FEATURE_BACKLIGHT (1 << 1)
+#define FEATURE_TOUCH (1 << 2)
+#define FEATURE_CAMERA (1 << 3)
+
+struct mini2440_features_t {
+ int count;
+ int done;
+ int lcd_index;
+ struct platform_device *optional[8];
+};
+
+static void __init mini2440_parse_features(
+ struct mini2440_features_t * features,
+ const char * features_str )
+{
+ const char * fp = features_str;
+
+ features->count = 0;
+ features->done = 0;
+ features->lcd_index = -1;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "MINI2440: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(mini2440_lcd_cfg))
+ printk(KERN_INFO "MINI2440: "
+ "'%c' out of range LCD mode\n", f);
+ else {
+ features->optional[features->count++] =
+ &s3c_device_lcd;
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ case 'b':
+ if (features->done & FEATURE_BACKLIGHT)
+ printk(KERN_INFO "MINI2440: '%c' ignored, "
+ "backlight already set\n", f);
+ else {
+ features->optional[features->count++] =
+ &mini2440_led_backlight;
+ }
+ features->done |= FEATURE_BACKLIGHT;
+ break;
+ case 't':
+ printk(KERN_INFO "MINI2440: '%c' ignored, "
+ "touchscreen not compiled in\n", f);
+ break;
+ case 'c':
+ if (features->done & FEATURE_CAMERA)
+ printk(KERN_INFO "MINI2440: '%c' ignored, "
+ "camera already registered\n", f);
+ else
+ features->optional[features->count++] =
+ &s3c_device_camif;
+ features->done |= FEATURE_CAMERA;
+ break;
+ }
+ }
+}
+
+static void __init mini2440_init(void)
+{
+ struct mini2440_features_t features = { 0 };
+ int i;
+
+ printk(KERN_INFO "MINI2440: Option string mini2440=%s\n",
+ mini2440_features_str);
+
+ /* Parse the feature string */
+ mini2440_parse_features(&features, mini2440_features_str);
+
+ /* turn LCD on */
+ s3c_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
+
+ /* Turn the backlight early on */
+ WARN_ON(gpio_request(S3C2410_GPG(4), "backlight"));
+ gpio_direction_output(S3C2410_GPG(4), 1);
+
+ /* remove pullup on optional PWM backlight -- unused on 3.5 and 7"s */
+ s3c_gpio_setpull(S3C2410_GPB(1), S3C_GPIO_PULL_UP);
+ s3c2410_gpio_setpin(S3C2410_GPB(1), 0);
+ s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPIO_INPUT);
+
+ /* mark the key as input, without pullups (there is one on the board) */
+ for (i = 0; i < ARRAY_SIZE(mini2440_buttons); i++) {
+ s3c_gpio_setpull(mini2440_buttons[i].gpio, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(mini2440_buttons[i].gpio, S3C2410_GPIO_INPUT);
+ }
+ if (features.lcd_index != -1) {
+ int li;
+
+ mini2440_fb_info.displays =
+ &mini2440_lcd_cfg[features.lcd_index];
+
+ printk(KERN_INFO "MINI2440: LCD");
+ for (li = 0; li < ARRAY_SIZE(mini2440_lcd_cfg); li++)
+ if (li == features.lcd_index)
+ printk(" [%d:%dx%d]", li,
+ mini2440_lcd_cfg[li].width,
+ mini2440_lcd_cfg[li].height);
+ else
+ printk(" %d:%dx%d", li,
+ mini2440_lcd_cfg[li].width,
+ mini2440_lcd_cfg[li].height);
+ printk("\n");
+ s3c24xx_fb_set_platdata(&mini2440_fb_info);
+ }
+
+ s3c24xx_udc_set_platdata(&mini2440_udc_cfg);
+ s3c24xx_mci_set_platdata(&mini2440_mmc_cfg);
+ s3c_nand_set_platdata(&mini2440_nand_info);
+ s3c_i2c0_set_platdata(NULL);
+
+ i2c_register_board_info(0, mini2440_i2c_devs,
+ ARRAY_SIZE(mini2440_i2c_devs));
+
+ platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
+
+ if (features.count) /* the optional features */
+ platform_add_devices(features.optional, features.count);
+
+}
+
+
+MACHINE_START(MINI2440, "MINI2440")
+ /* Maintainer: Michel Pollet <buserror@gmail.com> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = mini2440_map_io,
+ .init_machine = mini2440_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
new file mode 100644
index 00000000..37dd306f
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -0,0 +1,159 @@
+/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
+ *
+ * Copyright (c) 2004 Nex Vision
+ * Guillaume GOURAT <guillaume.gourat@nexvision.tv>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Modifications:
+ * 15-10-2004 GG Created initial version
+ * 12-03-2005 BJD Updated for release
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/string.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mtd/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/setup.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+//#include <asm/debug-ll.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct map_desc nexcoder_iodesc[] __initdata = {
+ /* nothing here yet */
+};
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG12 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg nexcoder_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ }
+};
+
+/* NOR Flash on NexVision NexCoder 2440 board */
+
+static struct resource nexcoder_nor_resource[] = {
+ [0] = {
+ .start = S3C2410_CS0,
+ .end = S3C2410_CS0 + (8*1024*1024) - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct map_info nexcoder_nor_map = {
+ .bankwidth = 2,
+};
+
+static struct platform_device nexcoder_device_nor = {
+ .name = "mtd-flash",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nexcoder_nor_resource),
+ .resource = nexcoder_nor_resource,
+ .dev =
+ {
+ .platform_data = &nexcoder_nor_map,
+ }
+};
+
+/* Standard Nexcoder devices */
+
+static struct platform_device *nexcoder_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_rtc,
+ &s3c_device_camif,
+ &s3c_device_spi0,
+ &s3c_device_spi1,
+ &nexcoder_device_nor,
+};
+
+static void __init nexcoder_sensorboard_init(void)
+{
+ // Initialize SCCB bus
+ s3c2410_gpio_setpin(S3C2410_GPE(14), 1); // IICSCL
+ s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPIO_OUTPUT);
+ s3c2410_gpio_setpin(S3C2410_GPE(15), 1); // IICSDA
+ s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPIO_OUTPUT);
+
+ // Power up the sensor board
+ s3c2410_gpio_setpin(S3C2410_GPF(1), 1);
+ s3c_gpio_cfgpin(S3C2410_GPF(1), S3C2410_GPIO_OUTPUT); // CAM_GPIO7 => nLDO_PWRDN
+ s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
+ s3c_gpio_cfgpin(S3C2410_GPF(2), S3C2410_GPIO_OUTPUT); // CAM_GPIO6 => CAM_PWRDN
+}
+
+static void __init nexcoder_map_io(void)
+{
+ s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+
+ nexcoder_sensorboard_init();
+}
+
+static void __init nexcoder_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
+};
+
+MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
+ /* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = nexcoder_map_io,
+ .init_machine = nexcoder_init,
+ .init_irq = s3c24xx_init_irq,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-osiris-dvs.c b/arch/arm/mach-s3c2440/mach-osiris-dvs.c
new file mode 100644
index 00000000..ad2792df
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-osiris-dvs.c
@@ -0,0 +1,194 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris-dvs.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Simtec Osiris Dynamic Voltage 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/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/gpio.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <plat/cpu-freq.h>
+
+#define OSIRIS_GPIO_DVS S3C2410_GPB(5)
+
+static bool dvs_en;
+
+static void osiris_dvs_tps_setdvs(bool on)
+{
+ unsigned vregs1 = 0, vdcdc2 = 0;
+
+ if (!on) {
+ vdcdc2 = TPS_VCORE_DISCH | TPS_LP_COREOFF;
+ vregs1 = TPS_LDO1_OFF; /* turn off in low-power mode */
+ }
+
+ dvs_en = on;
+ vdcdc2 |= TPS_VCORE_1_3V | TPS_VCORE_LP_1_0V;
+ vregs1 |= TPS_LDO2_ENABLE | TPS_LDO1_ENABLE;
+
+ tps65010_config_vregs1(vregs1);
+ tps65010_config_vdcdc2(vdcdc2);
+}
+
+static bool is_dvs(struct s3c_freq *f)
+{
+ /* at the moment, we assume ARMCLK = HCLK => DVS */
+ return f->armclk == f->hclk;
+}
+
+/* keep track of current state */
+static bool cur_dvs = false;
+
+static int osiris_dvs_notify(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct cpufreq_freqs *cf = data;
+ struct s3c_cpufreq_freqs *freqs = to_s3c_cpufreq(cf);
+ bool old_dvs = is_dvs(&freqs->old);
+ bool new_dvs = is_dvs(&freqs->new);
+ int ret = 0;
+
+ if (!dvs_en)
+ return 0;
+
+ printk(KERN_DEBUG "%s: old %ld,%ld new %ld,%ld\n", __func__,
+ freqs->old.armclk, freqs->old.hclk,
+ freqs->new.armclk, freqs->new.hclk);
+
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+ if (old_dvs & !new_dvs ||
+ cur_dvs & !new_dvs) {
+ pr_debug("%s: exiting dvs\n", __func__);
+ cur_dvs = false;
+ gpio_set_value(OSIRIS_GPIO_DVS, 1);
+ }
+ break;
+ case CPUFREQ_POSTCHANGE:
+ if (!old_dvs & new_dvs ||
+ !cur_dvs & new_dvs) {
+ pr_debug("entering dvs\n");
+ cur_dvs = true;
+ gpio_set_value(OSIRIS_GPIO_DVS, 0);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+static struct notifier_block osiris_dvs_nb = {
+ .notifier_call = osiris_dvs_notify,
+};
+
+static int __devinit osiris_dvs_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ dev_info(&pdev->dev, "initialising\n");
+
+ ret = gpio_request(OSIRIS_GPIO_DVS, "osiris-dvs");
+ if (ret) {
+ dev_err(&pdev->dev, "cannot claim gpio\n");
+ goto err_nogpio;
+ }
+
+ /* start with dvs disabled */
+ gpio_direction_output(OSIRIS_GPIO_DVS, 1);
+
+ ret = cpufreq_register_notifier(&osiris_dvs_nb,
+ CPUFREQ_TRANSITION_NOTIFIER);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register with cpufreq\n");
+ goto err_nofreq;
+ }
+
+ osiris_dvs_tps_setdvs(true);
+
+ return 0;
+
+err_nofreq:
+ gpio_free(OSIRIS_GPIO_DVS);
+
+err_nogpio:
+ return ret;
+}
+
+static int __devexit osiris_dvs_remove(struct platform_device *pdev)
+{
+ dev_info(&pdev->dev, "exiting\n");
+
+ /* disable any current dvs */
+ gpio_set_value(OSIRIS_GPIO_DVS, 1);
+ osiris_dvs_tps_setdvs(false);
+
+ cpufreq_unregister_notifier(&osiris_dvs_nb,
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ gpio_free(OSIRIS_GPIO_DVS);
+
+ return 0;
+}
+
+/* the CONFIG_PM block is so small, it isn't worth actaully compiling it
+ * out if the configuration isn't set. */
+
+static int osiris_dvs_suspend(struct device *dev)
+{
+ gpio_set_value(OSIRIS_GPIO_DVS, 1);
+ osiris_dvs_tps_setdvs(false);
+ cur_dvs = false;
+
+ return 0;
+}
+
+static int osiris_dvs_resume(struct device *dev)
+{
+ osiris_dvs_tps_setdvs(true);
+ return 0;
+}
+
+static const struct dev_pm_ops osiris_dvs_pm = {
+ .suspend = osiris_dvs_suspend,
+ .resume = osiris_dvs_resume,
+};
+
+static struct platform_driver osiris_dvs_driver = {
+ .probe = osiris_dvs_probe,
+ .remove = __devexit_p(osiris_dvs_remove),
+ .driver = {
+ .name = "osiris-dvs",
+ .owner = THIS_MODULE,
+ .pm = &osiris_dvs_pm,
+ },
+};
+
+static int __init osiris_dvs_init(void)
+{
+ return platform_driver_register(&osiris_dvs_driver);
+}
+
+static void __exit osiris_dvs_exit(void)
+{
+ platform_driver_unregister(&osiris_dvs_driver);
+}
+
+module_init(osiris_dvs_init);
+module_exit(osiris_dvs_exit);
+
+MODULE_DESCRIPTION("Simtec OSIRIS DVS support");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:osiris-dvs");
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
new file mode 100644
index 00000000..d8853639
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -0,0 +1,455 @@
+/* linux/arch/arm/mach-s3c2440/mach-osiris.c
+ *
+ * Copyright (c) 2005-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/syscore_ops.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <linux/i2c/tps65010.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/osiris-map.h>
+#include <mach/osiris-cpld.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+/* onboard perihperal map */
+
+static struct map_desc osiris_iodesc[] __initdata = {
+ /* ISA IO areas (may be over-written later) */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS5),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS5),
+ .length = SZ_16M,
+ .type = MT_DEVICE,
+ },
+
+ /* CPLD control registers */
+
+ {
+ .virtual = (u32)OSIRIS_VA_CTRL0,
+ .pfn = __phys_to_pfn(OSIRIS_PA_CTRL0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)OSIRIS_VA_CTRL1,
+ .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)OSIRIS_VA_CTRL2,
+ .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)OSIRIS_VA_IDREG,
+ .pfn = __phys_to_pfn(OSIRIS_PA_IDREG),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
+ [0] = {
+ .name = "uclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = osiris_serial_clocks,
+ .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = osiris_serial_clocks,
+ .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ .clocks = osiris_serial_clocks,
+ .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
+ }
+};
+
+/* NAND Flash on Osiris board */
+
+static int external_map[] = { 2 };
+static int chip0_map[] = { 0 };
+static int chip1_map[] = { 1 };
+
+static struct mtd_partition __initdata osiris_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_16K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "/boot",
+ .size = SZ_4M - SZ_16K,
+ .offset = SZ_16K,
+ },
+ [2] = {
+ .name = "user1",
+ .offset = SZ_4M,
+ .size = SZ_32M - SZ_4M,
+ },
+ [3] = {
+ .name = "user2",
+ .offset = SZ_32M,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct mtd_partition __initdata osiris_default_nand_part_large[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_128K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "/boot",
+ .size = SZ_4M - SZ_128K,
+ .offset = SZ_128K,
+ },
+ [2] = {
+ .name = "user1",
+ .offset = SZ_4M,
+ .size = SZ_32M - SZ_4M,
+ },
+ [3] = {
+ .name = "user2",
+ .offset = SZ_32M,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+/* the Osiris has 3 selectable slots for nand-flash, the two
+ * on-board chip areas, as well as the external slot.
+ *
+ * Note, there is no current hot-plug support for the External
+ * socket.
+*/
+
+static struct s3c2410_nand_set __initdata osiris_nand_sets[] = {
+ [1] = {
+ .name = "External",
+ .nr_chips = 1,
+ .nr_map = external_map,
+ .options = NAND_SCAN_SILENT_NODEV,
+ .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
+ .partitions = osiris_default_nand_part,
+ },
+ [0] = {
+ .name = "chip0",
+ .nr_chips = 1,
+ .nr_map = chip0_map,
+ .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
+ .partitions = osiris_default_nand_part,
+ },
+ [2] = {
+ .name = "chip1",
+ .nr_chips = 1,
+ .nr_map = chip1_map,
+ .options = NAND_SCAN_SILENT_NODEV,
+ .nr_partitions = ARRAY_SIZE(osiris_default_nand_part),
+ .partitions = osiris_default_nand_part,
+ },
+};
+
+static void osiris_nand_select(struct s3c2410_nand_set *set, int slot)
+{
+ unsigned int tmp;
+
+ slot = set->nr_map[slot] & 3;
+
+ pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n",
+ slot, set, set->nr_map);
+
+ tmp = __raw_readb(OSIRIS_VA_CTRL0);
+ tmp &= ~OSIRIS_CTRL0_NANDSEL;
+ tmp |= slot;
+
+ pr_debug("osiris_nand: ctrl0 now %02x\n", tmp);
+
+ __raw_writeb(tmp, OSIRIS_VA_CTRL0);
+}
+
+static struct s3c2410_platform_nand __initdata osiris_nand_info = {
+ .tacls = 25,
+ .twrph0 = 60,
+ .twrph1 = 60,
+ .nr_sets = ARRAY_SIZE(osiris_nand_sets),
+ .sets = osiris_nand_sets,
+ .select_chip = osiris_nand_select,
+};
+
+/* PCMCIA control and configuration */
+
+static struct resource osiris_pcmcia_resource[] = {
+ [0] = {
+ .start = 0x0f000000,
+ .end = 0x0f100000,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0x0c000000,
+ .end = 0x0c100000,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device osiris_pcmcia = {
+ .name = "osiris-pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(osiris_pcmcia_resource),
+ .resource = osiris_pcmcia_resource,
+};
+
+/* Osiris power management device */
+
+#ifdef CONFIG_PM
+static unsigned char pm_osiris_ctrl0;
+
+static int osiris_pm_suspend(void)
+{
+ unsigned int tmp;
+
+ pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0);
+ tmp = pm_osiris_ctrl0 & ~OSIRIS_CTRL0_NANDSEL;
+
+ /* ensure correct NAND slot is selected on resume */
+ if ((pm_osiris_ctrl0 & OSIRIS_CTRL0_BOOT_INT) == 0)
+ tmp |= 2;
+
+ __raw_writeb(tmp, OSIRIS_VA_CTRL0);
+
+ /* ensure that an nRESET is not generated on resume. */
+ s3c2410_gpio_setpin(S3C2410_GPA(21), 1);
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPIO_OUTPUT);
+
+ return 0;
+}
+
+static void osiris_pm_resume(void)
+{
+ if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
+ __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
+
+ __raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
+
+ s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
+}
+
+#else
+#define osiris_pm_suspend NULL
+#define osiris_pm_resume NULL
+#endif
+
+static struct syscore_ops osiris_pm_syscore_ops = {
+ .suspend = osiris_pm_suspend,
+ .resume = osiris_pm_resume,
+};
+
+/* Link for DVS driver to TPS65011 */
+
+static void osiris_tps_release(struct device *dev)
+{
+ /* static device, do not need to release anything */
+}
+
+static struct platform_device osiris_tps_device = {
+ .name = "osiris-dvs",
+ .id = -1,
+ .dev.release = osiris_tps_release,
+};
+
+static int osiris_tps_setup(struct i2c_client *client, void *context)
+{
+ osiris_tps_device.dev.parent = &client->dev;
+ return platform_device_register(&osiris_tps_device);
+}
+
+static int osiris_tps_remove(struct i2c_client *client, void *context)
+{
+ platform_device_unregister(&osiris_tps_device);
+ return 0;
+}
+
+static struct tps65010_board osiris_tps_board = {
+ .base = -1, /* GPIO can go anywhere at the moment */
+ .setup = osiris_tps_setup,
+ .teardown = osiris_tps_remove,
+};
+
+/* I2C devices fitted. */
+
+static struct i2c_board_info osiris_i2c_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("tps65011", 0x48),
+ .irq = IRQ_EINT20,
+ .platform_data = &osiris_tps_board,
+ },
+};
+
+/* Standard Osiris devices */
+
+static struct platform_device *osiris_devices[] __initdata = {
+ &s3c_device_i2c0,
+ &s3c_device_wdt,
+ &s3c_device_nand,
+ &osiris_pcmcia,
+};
+
+static struct clk *osiris_clocks[] __initdata = {
+ &s3c24xx_dclk0,
+ &s3c24xx_dclk1,
+ &s3c24xx_clkout0,
+ &s3c24xx_clkout1,
+ &s3c24xx_uclk,
+};
+
+static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
+ .refresh = 7800, /* refresh period is 7.8usec */
+ .auto_io = 1,
+ .need_io = 1,
+};
+
+static void __init osiris_map_io(void)
+{
+ unsigned long flags;
+
+ /* initialise the clocks */
+
+ s3c24xx_dclk0.parent = &clk_upll;
+ s3c24xx_dclk0.rate = 12*1000*1000;
+
+ s3c24xx_dclk1.parent = &clk_upll;
+ s3c24xx_dclk1.rate = 24*1000*1000;
+
+ s3c24xx_clkout0.parent = &s3c24xx_dclk0;
+ s3c24xx_clkout1.parent = &s3c24xx_dclk1;
+
+ s3c24xx_uclk.parent = &s3c24xx_clkout1;
+
+ s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+
+ s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
+ s3c24xx_init_clocks(0);
+ s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+
+ /* check for the newer revision boards with large page nand */
+
+ if ((__raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK) >= 4) {
+ printk(KERN_INFO "OSIRIS-B detected (revision %d)\n",
+ __raw_readb(OSIRIS_VA_IDREG) & OSIRIS_ID_REVMASK);
+ osiris_nand_sets[0].partitions = osiris_default_nand_part_large;
+ osiris_nand_sets[0].nr_partitions = ARRAY_SIZE(osiris_default_nand_part_large);
+ } else {
+ /* write-protect line to the NAND */
+ s3c2410_gpio_setpin(S3C2410_GPA(0), 1);
+ }
+
+ /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
+
+ local_irq_save(flags);
+ __raw_writel(__raw_readl(S3C2410_BWSCON) | S3C2410_BWSCON_ST1 | S3C2410_BWSCON_ST2 | S3C2410_BWSCON_ST3 | S3C2410_BWSCON_ST4 | S3C2410_BWSCON_ST5, S3C2410_BWSCON);
+ local_irq_restore(flags);
+}
+
+static void __init osiris_init(void)
+{
+ register_syscore_ops(&osiris_pm_syscore_ops);
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_nand_set_platdata(&osiris_nand_info);
+
+ s3c_cpufreq_setboard(&osiris_cpufreq);
+
+ i2c_register_board_info(0, osiris_i2c_devs,
+ ARRAY_SIZE(osiris_i2c_devs));
+
+ platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
+};
+
+MACHINE_START(OSIRIS, "Simtec-OSIRIS")
+ /* Maintainer: Ben Dooks <ben@simtec.co.uk> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = osiris_map_io,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = osiris_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
new file mode 100644
index 00000000..27ea9509
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -0,0 +1,834 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx1950.c
+ *
+ * Copyright (c) 2006-2009 Victor Chukhantsev, Denis Grigoriev,
+ * Copyright (c) 2007-2010 Vasily Khoruzhick
+ *
+ * based on smdk2440 written by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/sysdev.h>
+#include <linux/pda_power.h>
+#include <linux/pwm_backlight.h>
+#include <linux/pwm.h>
+#include <linux/s3c_adc_battery.h>
+#include <linux/leds.h>
+#include <linux/i2c.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/mmc/host.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/h1940.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/regs-serial.h>
+#include <plat/regs-iic.h>
+#include <plat/mci.h>
+#include <plat/udc.h>
+#include <plat/nand.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+#include <plat/ts.h>
+
+#include <sound/uda1380.h>
+
+#define LCD_PWM_PERIOD 192960
+#define LCD_PWM_DUTY 127353
+
+static struct map_desc rx1950_iodesc[] __initdata = {
+};
+
+static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
+ [0] = {
+ .name = "fclk",
+ .divisor = 0x0a,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clocks = rx1950_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clocks = rx1950_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0xf1,
+ .clocks = rx1950_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
+ },
+};
+
+static struct s3c2410fb_display rx1950_display = {
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+
+ .pixclock = 260000,
+ .left_margin = 10,
+ .right_margin = 20,
+ .hsync_len = 10,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .vsync_len = 2,
+
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVCLK |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_HWSWP |
+ (0x02 << 13) |
+ (0x02 << 15),
+
+};
+
+static int power_supply_init(struct device *dev)
+{
+ return gpio_request(S3C2410_GPF(2), "cable plugged");
+}
+
+static int rx1950_is_ac_online(void)
+{
+ return !gpio_get_value(S3C2410_GPF(2));
+}
+
+static void power_supply_exit(struct device *dev)
+{
+ gpio_free(S3C2410_GPF(2));
+}
+
+static char *rx1950_supplicants[] = {
+ "main-battery"
+};
+
+static struct pda_power_pdata power_supply_info = {
+ .init = power_supply_init,
+ .is_ac_online = rx1950_is_ac_online,
+ .exit = power_supply_exit,
+ .supplied_to = rx1950_supplicants,
+ .num_supplicants = ARRAY_SIZE(rx1950_supplicants),
+};
+
+static struct resource power_supply_resources[] = {
+ [0] = {
+ .name = "ac",
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE |
+ IORESOURCE_IRQ_HIGHEDGE,
+ .start = IRQ_EINT2,
+ .end = IRQ_EINT2,
+ },
+};
+
+static struct platform_device power_supply = {
+ .name = "pda-power",
+ .id = -1,
+ .dev = {
+ .platform_data =
+ &power_supply_info,
+ },
+ .resource = power_supply_resources,
+ .num_resources = ARRAY_SIZE(power_supply_resources),
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_noac[] = {
+ { .volt = 4100, .cur = 156, .level = 100},
+ { .volt = 4050, .cur = 156, .level = 95},
+ { .volt = 4025, .cur = 141, .level = 90},
+ { .volt = 3995, .cur = 144, .level = 85},
+ { .volt = 3957, .cur = 162, .level = 80},
+ { .volt = 3931, .cur = 147, .level = 75},
+ { .volt = 3902, .cur = 147, .level = 70},
+ { .volt = 3863, .cur = 153, .level = 65},
+ { .volt = 3838, .cur = 150, .level = 60},
+ { .volt = 3800, .cur = 153, .level = 55},
+ { .volt = 3765, .cur = 153, .level = 50},
+ { .volt = 3748, .cur = 172, .level = 45},
+ { .volt = 3740, .cur = 153, .level = 40},
+ { .volt = 3714, .cur = 175, .level = 35},
+ { .volt = 3710, .cur = 156, .level = 30},
+ { .volt = 3963, .cur = 156, .level = 25},
+ { .volt = 3672, .cur = 178, .level = 20},
+ { .volt = 3651, .cur = 178, .level = 15},
+ { .volt = 3629, .cur = 178, .level = 10},
+ { .volt = 3612, .cur = 162, .level = 5},
+ { .volt = 3605, .cur = 162, .level = 0},
+};
+
+static const struct s3c_adc_bat_thresh bat_lut_acin[] = {
+ { .volt = 4200, .cur = 0, .level = 100},
+ { .volt = 4190, .cur = 0, .level = 99},
+ { .volt = 4178, .cur = 0, .level = 95},
+ { .volt = 4110, .cur = 0, .level = 70},
+ { .volt = 4076, .cur = 0, .level = 65},
+ { .volt = 4046, .cur = 0, .level = 60},
+ { .volt = 4021, .cur = 0, .level = 55},
+ { .volt = 3999, .cur = 0, .level = 50},
+ { .volt = 3982, .cur = 0, .level = 45},
+ { .volt = 3965, .cur = 0, .level = 40},
+ { .volt = 3957, .cur = 0, .level = 35},
+ { .volt = 3948, .cur = 0, .level = 30},
+ { .volt = 3936, .cur = 0, .level = 25},
+ { .volt = 3927, .cur = 0, .level = 20},
+ { .volt = 3906, .cur = 0, .level = 15},
+ { .volt = 3880, .cur = 0, .level = 10},
+ { .volt = 3829, .cur = 0, .level = 5},
+ { .volt = 3820, .cur = 0, .level = 0},
+};
+
+int rx1950_bat_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C2410_GPJ(2), "rx1950-charger-enable-1");
+ if (ret)
+ goto err_gpio1;
+ ret = gpio_request(S3C2410_GPJ(3), "rx1950-charger-enable-2");
+ if (ret)
+ goto err_gpio2;
+
+ return 0;
+
+err_gpio2:
+ gpio_free(S3C2410_GPJ(2));
+err_gpio1:
+ return ret;
+}
+
+void rx1950_bat_exit(void)
+{
+ gpio_free(S3C2410_GPJ(2));
+ gpio_free(S3C2410_GPJ(3));
+}
+
+void rx1950_enable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 1);
+ gpio_direction_output(S3C2410_GPJ(3), 1);
+}
+
+void rx1950_disable_charger(void)
+{
+ gpio_direction_output(S3C2410_GPJ(2), 0);
+ gpio_direction_output(S3C2410_GPJ(3), 0);
+}
+
+DEFINE_SPINLOCK(rx1950_blink_spin);
+
+static int rx1950_led_blink_set(unsigned gpio, int state,
+ unsigned long *delay_on, unsigned long *delay_off)
+{
+ int blink_gpio, check_gpio;
+
+ switch (gpio) {
+ case S3C2410_GPA(6):
+ blink_gpio = S3C2410_GPA(4);
+ check_gpio = S3C2410_GPA(3);
+ break;
+ case S3C2410_GPA(7):
+ blink_gpio = S3C2410_GPA(3);
+ check_gpio = S3C2410_GPA(4);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ if (delay_on && delay_off && !*delay_on && !*delay_off)
+ *delay_on = *delay_off = 500;
+
+ spin_lock(&rx1950_blink_spin);
+
+ switch (state) {
+ case GPIO_LED_NO_BLINK_LOW:
+ case GPIO_LED_NO_BLINK_HIGH:
+ if (!gpio_get_value(check_gpio))
+ gpio_set_value(S3C2410_GPJ(6), 0);
+ gpio_set_value(blink_gpio, 0);
+ gpio_set_value(gpio, state);
+ break;
+ case GPIO_LED_BLINK:
+ gpio_set_value(gpio, 0);
+ gpio_set_value(S3C2410_GPJ(6), 1);
+ gpio_set_value(blink_gpio, 1);
+ break;
+ }
+
+ spin_unlock(&rx1950_blink_spin);
+
+ return 0;
+}
+
+static struct gpio_led rx1950_leds_desc[] = {
+ {
+ .name = "Green",
+ .default_trigger = "main-battery-full",
+ .gpio = S3C2410_GPA(6),
+ .retain_state_suspended = 1,
+ },
+ {
+ .name = "Red",
+ .default_trigger
+ = "main-battery-charging-blink-full-solid",
+ .gpio = S3C2410_GPA(7),
+ .retain_state_suspended = 1,
+ },
+ {
+ .name = "Blue",
+ .default_trigger = "rx1950-acx-mem",
+ .gpio = S3C2410_GPA(11),
+ .retain_state_suspended = 1,
+ },
+};
+
+static struct gpio_led_platform_data rx1950_leds_pdata = {
+ .num_leds = ARRAY_SIZE(rx1950_leds_desc),
+ .leds = rx1950_leds_desc,
+ .gpio_blink_set = rx1950_led_blink_set,
+};
+
+static struct platform_device rx1950_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &rx1950_leds_pdata,
+ },
+};
+
+static struct s3c_adc_bat_pdata rx1950_bat_cfg = {
+ .init = rx1950_bat_init,
+ .exit = rx1950_bat_exit,
+ .enable_charger = rx1950_enable_charger,
+ .disable_charger = rx1950_disable_charger,
+ .gpio_charge_finished = S3C2410_GPF(3),
+ .lut_noac = bat_lut_noac,
+ .lut_noac_cnt = ARRAY_SIZE(bat_lut_noac),
+ .lut_acin = bat_lut_acin,
+ .lut_acin_cnt = ARRAY_SIZE(bat_lut_acin),
+ .volt_channel = 0,
+ .current_channel = 1,
+ .volt_mult = 4235,
+ .current_mult = 2900,
+ .internal_impedance = 200,
+};
+
+static struct platform_device rx1950_battery = {
+ .name = "s3c-adc-battery",
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_adc.dev,
+ .platform_data = &rx1950_bat_cfg,
+ },
+};
+
+static struct s3c2410fb_mach_info rx1950_lcd_cfg = {
+ .displays = &rx1950_display,
+ .num_displays = 1,
+ .default_display = 0,
+
+ .lpcsel = 0x02,
+ .gpccon = 0xaa9556a9,
+ .gpccon_mask = 0xffc003fc,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+
+ .gpdcon = 0xaa90aaa1,
+ .gpdcon_mask = 0xffc0fff0,
+ .gpdup = 0x0000fcfd,
+ .gpdup_mask = 0xffffffff,
+
+};
+
+static struct pwm_device *lcd_pwm;
+
+void rx1950_lcd_power(int enable)
+{
+ int i;
+ static int enabled;
+ if (enabled == enable)
+ return;
+ if (!enable) {
+
+ /* GPC11-GPC15->OUTPUT */
+ for (i = 11; i < 16; i++)
+ gpio_direction_output(S3C2410_GPC(i), 1);
+
+ /* Wait a bit here... */
+ mdelay(100);
+
+ /* GPD2-GPD7->OUTPUT */
+ /* GPD11-GPD15->OUTPUT */
+ /* GPD2-GPD7->1, GPD11-GPD15->1 */
+ for (i = 2; i < 8; i++)
+ gpio_direction_output(S3C2410_GPD(i), 1);
+ for (i = 11; i < 16; i++)
+ gpio_direction_output(S3C2410_GPD(i), 1);
+
+ /* Wait a bit here...*/
+ mdelay(100);
+
+ /* GPB0->OUTPUT, GPB0->0 */
+ gpio_direction_output(S3C2410_GPB(0), 0);
+
+ /* GPC1-GPC4->OUTPUT, GPC1-4->0 */
+ for (i = 1; i < 5; i++)
+ gpio_direction_output(S3C2410_GPC(i), 0);
+
+ /* GPC15-GPC11->0 */
+ for (i = 11; i < 16; i++)
+ gpio_direction_output(S3C2410_GPC(i), 0);
+
+ /* GPD15-GPD11->0, GPD2->GPD7->0 */
+ for (i = 11; i < 16; i++)
+ gpio_direction_output(S3C2410_GPD(i), 0);
+
+ for (i = 2; i < 8; i++)
+ gpio_direction_output(S3C2410_GPD(i), 0);
+
+ /* GPC6->0, GPC7->0, GPC5->0 */
+ gpio_direction_output(S3C2410_GPC(6), 0);
+ gpio_direction_output(S3C2410_GPC(7), 0);
+ gpio_direction_output(S3C2410_GPC(5), 0);
+
+ /* GPB1->OUTPUT, GPB1->0 */
+ gpio_direction_output(S3C2410_GPB(1), 0);
+ pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
+ pwm_disable(lcd_pwm);
+
+ /* GPC0->0, GPC10->0 */
+ gpio_direction_output(S3C2410_GPC(0), 0);
+ gpio_direction_output(S3C2410_GPC(10), 0);
+ } else {
+ pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
+ pwm_enable(lcd_pwm);
+
+ gpio_direction_output(S3C2410_GPC(0), 1);
+ gpio_direction_output(S3C2410_GPC(5), 1);
+
+ s3c_gpio_cfgpin(S3C2410_GPB(1), S3C2410_GPB1_TOUT1);
+ gpio_direction_output(S3C2410_GPC(7), 1);
+
+ for (i = 1; i < 5; i++)
+ s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+ for (i = 11; i < 16; i++)
+ s3c_gpio_cfgpin(S3C2410_GPC(i), S3C_GPIO_SFN(2));
+
+ for (i = 2; i < 8; i++)
+ s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+ for (i = 11; i < 16; i++)
+ s3c_gpio_cfgpin(S3C2410_GPD(i), S3C_GPIO_SFN(2));
+
+ gpio_direction_output(S3C2410_GPC(10), 1);
+ gpio_direction_output(S3C2410_GPC(6), 1);
+ }
+ enabled = enable;
+}
+
+static void rx1950_bl_power(int enable)
+{
+ static int enabled;
+ if (enabled == enable)
+ return;
+ if (!enable) {
+ gpio_direction_output(S3C2410_GPB(0), 0);
+ } else {
+ /* LED driver need a "push" to power on */
+ gpio_direction_output(S3C2410_GPB(0), 1);
+ /* Warm up backlight for one period of PWM.
+ * Without this trick its almost impossible to
+ * enable backlight with low brightness value
+ */
+ ndelay(48000);
+ s3c_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPB0_TOUT0);
+ }
+ enabled = enable;
+}
+
+static int rx1950_backlight_init(struct device *dev)
+{
+ WARN_ON(gpio_request(S3C2410_GPB(0), "Backlight"));
+ lcd_pwm = pwm_request(1, "RX1950 LCD");
+ if (IS_ERR(lcd_pwm)) {
+ dev_err(dev, "Unable to request PWM for LCD power!\n");
+ return PTR_ERR(lcd_pwm);
+ }
+
+ rx1950_lcd_power(1);
+ rx1950_bl_power(1);
+
+ return 0;
+}
+
+static void rx1950_backlight_exit(struct device *dev)
+{
+ rx1950_bl_power(0);
+ rx1950_lcd_power(0);
+
+ pwm_free(lcd_pwm);
+ gpio_free(S3C2410_GPB(0));
+}
+
+
+static int rx1950_backlight_notify(struct device *dev, int brightness)
+{
+ if (!brightness) {
+ rx1950_bl_power(0);
+ rx1950_lcd_power(0);
+ } else {
+ rx1950_lcd_power(1);
+ rx1950_bl_power(1);
+ }
+ return brightness;
+}
+
+static struct platform_pwm_backlight_data rx1950_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 24,
+ .dft_brightness = 4,
+ .pwm_period_ns = 48000,
+ .init = rx1950_backlight_init,
+ .notify = rx1950_backlight_notify,
+ .exit = rx1950_backlight_exit,
+};
+
+static struct platform_device rx1950_backlight = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[0].dev,
+ .platform_data = &rx1950_backlight_data,
+ },
+};
+
+static void rx1950_set_mmc_power(unsigned char power_mode, unsigned short vdd)
+{
+ switch (power_mode) {
+ case MMC_POWER_OFF:
+ gpio_direction_output(S3C2410_GPJ(1), 0);
+ break;
+ case MMC_POWER_UP:
+ case MMC_POWER_ON:
+ gpio_direction_output(S3C2410_GPJ(1), 1);
+ break;
+ default:
+ break;
+ }
+}
+
+static struct s3c24xx_mci_pdata rx1950_mmc_cfg __initdata = {
+ .gpio_detect = S3C2410_GPF(5),
+ .gpio_wprotect = S3C2410_GPH(8),
+ .set_power = rx1950_set_mmc_power,
+ .ocr_avail = MMC_VDD_32_33,
+};
+
+static struct mtd_partition rx1950_nand_part[] = {
+ [0] = {
+ .name = "Boot0",
+ .offset = 0,
+ .size = 0x4000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [1] = {
+ .name = "Boot1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x40000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ [2] = {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x300000,
+ .mask_flags = 0,
+ },
+ [3] = {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ },
+};
+
+static struct s3c2410_nand_set rx1950_nand_sets[] = {
+ [0] = {
+ .name = "Internal",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(rx1950_nand_part),
+ .partitions = rx1950_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand rx1950_nand_info = {
+ .tacls = 25,
+ .twrph0 = 50,
+ .twrph1 = 15,
+ .nr_sets = ARRAY_SIZE(rx1950_nand_sets),
+ .sets = rx1950_nand_sets,
+};
+
+static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = {
+ .vbus_pin = S3C2410_GPG(5),
+ .vbus_pin_inverted = 1,
+ .pullup_pin = S3C2410_GPJ(5),
+};
+
+static struct s3c2410_ts_mach_info rx1950_ts_cfg __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 3,
+};
+
+static struct gpio_keys_button rx1950_gpio_keys_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = S3C2410_GPF(0),
+ .active_low = 1,
+ .desc = "Power button",
+ .wakeup = 1,
+ },
+ {
+ .code = KEY_F5,
+ .gpio = S3C2410_GPF(7),
+ .active_low = 1,
+ .desc = "Record button",
+ },
+ {
+ .code = KEY_F1,
+ .gpio = S3C2410_GPG(0),
+ .active_low = 1,
+ .desc = "Calendar button",
+ },
+ {
+ .code = KEY_F2,
+ .gpio = S3C2410_GPG(2),
+ .active_low = 1,
+ .desc = "Contacts button",
+ },
+ {
+ .code = KEY_F3,
+ .gpio = S3C2410_GPG(3),
+ .active_low = 1,
+ .desc = "Mail button",
+ },
+ {
+ .code = KEY_F4,
+ .gpio = S3C2410_GPG(7),
+ .active_low = 1,
+ .desc = "WLAN button",
+ },
+ {
+ .code = KEY_LEFT,
+ .gpio = S3C2410_GPG(10),
+ .active_low = 1,
+ .desc = "Left button",
+ },
+ {
+ .code = KEY_RIGHT,
+ .gpio = S3C2410_GPG(11),
+ .active_low = 1,
+ .desc = "Right button",
+ },
+ {
+ .code = KEY_UP,
+ .gpio = S3C2410_GPG(4),
+ .active_low = 1,
+ .desc = "Up button",
+ },
+ {
+ .code = KEY_DOWN,
+ .gpio = S3C2410_GPG(6),
+ .active_low = 1,
+ .desc = "Down button",
+ },
+ {
+ .code = KEY_ENTER,
+ .gpio = S3C2410_GPG(9),
+ .active_low = 1,
+ .desc = "Ok button"
+ },
+};
+
+static struct gpio_keys_platform_data rx1950_gpio_keys_data = {
+ .buttons = rx1950_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(rx1950_gpio_keys_table),
+};
+
+static struct platform_device rx1950_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev.platform_data = &rx1950_gpio_keys_data,
+};
+
+static struct uda1380_platform_data uda1380_info = {
+ .gpio_power = S3C2410_GPJ(0),
+ .gpio_reset = S3C2410_GPD(0),
+ .dac_clk = UDA1380_DAC_CLK_SYSCLK,
+};
+
+static struct i2c_board_info rx1950_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("uda1380", 0x1a),
+ .platform_data = &uda1380_info,
+ },
+};
+
+static struct platform_device *rx1950_devices[] __initdata = {
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &samsung_asoc_dma,
+ &s3c_device_usbgadget,
+ &s3c_device_rtc,
+ &s3c_device_nand,
+ &s3c_device_sdi,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &s3c_device_timer[0],
+ &s3c_device_timer[1],
+ &rx1950_backlight,
+ &rx1950_device_gpiokeys,
+ &power_supply,
+ &rx1950_battery,
+ &rx1950_leds,
+};
+
+static struct clk *rx1950_clocks[] __initdata = {
+ &s3c24xx_clkout0,
+ &s3c24xx_clkout1,
+};
+
+static void __init rx1950_map_io(void)
+{
+ s3c24xx_clkout0.parent = &clk_h;
+ s3c24xx_clkout1.parent = &clk_f;
+
+ s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+
+ s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
+ s3c24xx_init_clocks(16934000);
+ s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+
+ /* setup PM */
+
+#ifdef CONFIG_PM_H1940
+ memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 8);
+#endif
+
+ s3c_pm_init();
+}
+
+static void __init rx1950_init_machine(void)
+{
+ int i;
+
+ s3c24xx_fb_set_platdata(&rx1950_lcd_cfg);
+ s3c24xx_udc_set_platdata(&rx1950_udc_cfg);
+ s3c24xx_ts_set_platdata(&rx1950_ts_cfg);
+ s3c24xx_mci_set_platdata(&rx1950_mmc_cfg);
+ s3c_i2c0_set_platdata(NULL);
+ s3c_nand_set_platdata(&rx1950_nand_info);
+
+ /* Turn off suspend on both USB ports, and switch the
+ * selectable USB port to USB device mode. */
+ s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
+ S3C2410_MISCCR_USBSUSPND0 |
+ S3C2410_MISCCR_USBSUSPND1, 0x0);
+
+ /* mmc power is disabled by default */
+ WARN_ON(gpio_request(S3C2410_GPJ(1), "MMC power"));
+ gpio_direction_output(S3C2410_GPJ(1), 0);
+
+ for (i = 0; i < 8; i++)
+ WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+ for (i = 10; i < 16; i++)
+ WARN_ON(gpio_request(S3C2410_GPC(i), "LCD power"));
+
+ for (i = 2; i < 8; i++)
+ WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+ for (i = 11; i < 16; i++)
+ WARN_ON(gpio_request(S3C2410_GPD(i), "LCD power"));
+
+ WARN_ON(gpio_request(S3C2410_GPB(1), "LCD power"));
+
+ WARN_ON(gpio_request(S3C2410_GPA(3), "Red blink"));
+ WARN_ON(gpio_request(S3C2410_GPA(4), "Green blink"));
+ WARN_ON(gpio_request(S3C2410_GPJ(6), "LED blink"));
+ gpio_direction_output(S3C2410_GPA(3), 0);
+ gpio_direction_output(S3C2410_GPA(4), 0);
+ gpio_direction_output(S3C2410_GPJ(6), 0);
+
+ platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
+
+ i2c_register_board_info(0, rx1950_i2c_devices,
+ ARRAY_SIZE(rx1950_i2c_devices));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx1950_reserve(void)
+{
+ memblock_reserve(0x30003000, 0x1000);
+ memblock_reserve(0x30081000, 0x1000);
+}
+
+MACHINE_START(RX1950, "HP iPAQ RX1950")
+ /* Maintainers: Vasily Khoruzhick */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = rx1950_map_io,
+ .reserve = rx1950_reserve,
+ .init_irq = s3c24xx_init_irq,
+ .init_machine = rx1950_init_machine,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
new file mode 100644
index 00000000..1472b1a5
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -0,0 +1,227 @@
+/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.handhelds.org/projects/rx3715.html
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/memblock.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/h1940.h>
+#include <plat/nand.h>
+#include <mach/fb.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+static struct map_desc rx3715_iodesc[] __initdata = {
+ /* dump ISA space somewhere unused */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS3),
+ .length = SZ_1M,
+ .type = MT_DEVICE,
+ },
+};
+
+
+static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
+ [0] = {
+ .name = "fclk",
+ .divisor = 0,
+ .min_baud = 0,
+ .max_baud = 0,
+ }
+};
+
+static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ .clocks = rx3715_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x00,
+ .clocks = rx3715_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .uart_flags = UPF_CONS_FLOW,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ .clocks = rx3715_serial_clocks,
+ .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
+ }
+};
+
+/* framebuffer lcd controller information */
+
+static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
+ .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+ .width = 240,
+ .height = 320,
+
+ .pixclock = 260000,
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 36,
+ .right_margin = 36,
+ .hsync_len = 8,
+ .upper_margin = 6,
+ .lower_margin = 7,
+ .vsync_len = 3,
+};
+
+static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
+
+ .displays = &rx3715_lcdcfg,
+ .num_displays = 1,
+ .default_display = 0,
+
+ .lpcsel = 0xf82,
+
+ .gpccon = 0xaa955699,
+ .gpccon_mask = 0xffc003cc,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+
+ .gpdcon = 0xaa95aaa1,
+ .gpdcon_mask = 0xffc0fff0,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+};
+
+static struct mtd_partition __initdata rx3715_nand_part[] = {
+ [0] = {
+ .name = "Whole Flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = MTD_WRITEABLE,
+ }
+};
+
+static struct s3c2410_nand_set __initdata rx3715_nand_sets[] = {
+ [0] = {
+ .name = "Internal",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(rx3715_nand_part),
+ .partitions = rx3715_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand __initdata rx3715_nand_info = {
+ .tacls = 25,
+ .twrph0 = 50,
+ .twrph1 = 15,
+ .nr_sets = ARRAY_SIZE(rx3715_nand_sets),
+ .sets = rx3715_nand_sets,
+};
+
+static struct platform_device *rx3715_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+ &s3c_device_nand,
+};
+
+static void __init rx3715_map_io(void)
+{
+ s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
+ s3c24xx_init_clocks(16934000);
+ s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+}
+
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+ memblock_reserve(0x30003000, 0x1000);
+ memblock_reserve(0x30081000, 0x1000);
+}
+
+static void __init rx3715_init_irq(void)
+{
+ s3c24xx_init_irq();
+}
+
+static void __init rx3715_init_machine(void)
+{
+#ifdef CONFIG_PM_H1940
+ memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024);
+#endif
+ s3c_pm_init();
+
+ s3c_nand_set_platdata(&rx3715_nand_info);
+ s3c24xx_fb_set_platdata(&rx3715_fb_info);
+ platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
+}
+
+MACHINE_START(RX3715, "IPAQ-RX3715")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+ .map_io = rx3715_map_io,
+ .reserve = rx3715_reserve,
+ .init_irq = rx3715_init_irq,
+ .init_machine = rx3715_init_machine,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
new file mode 100644
index 00000000..eedfe0f1
--- /dev/null
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -0,0 +1,184 @@
+/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * Thanks to Dimity Andric and TomTom for the loan of an SMDK2440.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2440_iodesc[] __initdata = {
+ /* ISA IO Space map (memory space selected by A24) */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ }
+};
+
+/* LCD driver info */
+
+static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
+
+ .lcdcon5 = S3C2410_LCDCON5_FRM565 |
+ S3C2410_LCDCON5_INVVLINE |
+ S3C2410_LCDCON5_INVVFRAME |
+ S3C2410_LCDCON5_PWREN |
+ S3C2410_LCDCON5_HWSWP,
+
+ .type = S3C2410_LCDCON1_TFT,
+
+ .width = 240,
+ .height = 320,
+
+ .pixclock = 166667, /* HCLK 60 MHz, divisor 10 */
+ .xres = 240,
+ .yres = 320,
+ .bpp = 16,
+ .left_margin = 20,
+ .right_margin = 8,
+ .hsync_len = 4,
+ .upper_margin = 8,
+ .lower_margin = 7,
+ .vsync_len = 4,
+};
+
+static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
+ .displays = &smdk2440_lcd_cfg,
+ .num_displays = 1,
+ .default_display = 0,
+
+#if 0
+ /* currently setup by downloader */
+ .gpccon = 0xaa940659,
+ .gpccon_mask = 0xffffffff,
+ .gpcup = 0x0000ffff,
+ .gpcup_mask = 0xffffffff,
+ .gpdcon = 0xaa84aaa0,
+ .gpdcon_mask = 0xffffffff,
+ .gpdup = 0x0000faff,
+ .gpdup_mask = 0xffffffff,
+#endif
+
+ .lpcsel = ((0xCE6) & ~7) | 1<<4,
+};
+
+static struct platform_device *smdk2440_devices[] __initdata = {
+ &s3c_device_ohci,
+ &s3c_device_lcd,
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_iis,
+};
+
+static void __init smdk2440_map_io(void)
+{
+ s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
+ s3c24xx_init_clocks(16934400);
+ s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+}
+
+static void __init smdk2440_machine_init(void)
+{
+ s3c24xx_fb_set_platdata(&smdk2440_fb_info);
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(S3C2440, "SMDK2440")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2440_map_io,
+ .init_machine = smdk2440_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2440/s3c2440-cpufreq.c b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
new file mode 100644
index 00000000..976002fb
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440-cpufreq.c
@@ -0,0 +1,311 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2440-cpufreq.c
+ *
+ * Copyright (c) 2006-2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+static struct clk *xtal;
+static struct clk *fclk;
+static struct clk *hclk;
+static struct clk *armclk;
+
+/* HDIV: 1, 2, 3, 4, 6, 8 */
+
+static inline int within_khz(unsigned long a, unsigned long b)
+{
+ long diff = a - b;
+
+ return (diff >= -1000 && diff <= 1000);
+}
+
+/**
+ * s3c2440_cpufreq_calcdivs - calculate divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Calcualte the divider values for the given frequency settings
+ * specified in @cfg. The values are stored in @cfg for later use
+ * by the relevant set routine if the request settings can be reached.
+ */
+int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+ unsigned int hdiv, pdiv;
+ unsigned long hclk, fclk, armclk;
+ unsigned long hclk_max;
+
+ fclk = cfg->freq.fclk;
+ armclk = cfg->freq.armclk;
+ hclk_max = cfg->max.hclk;
+
+ s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
+ __func__, fclk, armclk, hclk_max);
+
+ if (armclk > fclk) {
+ printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
+ armclk = fclk;
+ }
+
+ /* if we are in DVS, we need HCLK to be <= ARMCLK */
+ if (armclk < fclk && armclk < hclk_max)
+ hclk_max = armclk;
+
+ for (hdiv = 1; hdiv < 9; hdiv++) {
+ if (hdiv == 5 || hdiv == 7)
+ hdiv++;
+
+ hclk = (fclk / hdiv);
+ if (hclk <= hclk_max || within_khz(hclk, hclk_max))
+ break;
+ }
+
+ s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
+
+ if (hdiv > 8)
+ goto invalid;
+
+ pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
+
+ if ((hclk / pdiv) > cfg->max.pclk)
+ pdiv++;
+
+ s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
+
+ if (pdiv > 2)
+ goto invalid;
+
+ pdiv *= hdiv;
+
+ /* calculate a valid armclk */
+
+ if (armclk < hclk)
+ armclk = hclk;
+
+ /* if we're running armclk lower than fclk, this really means
+ * that the system should go into dvs mode, which means that
+ * armclk is connected to hclk. */
+ if (armclk < fclk) {
+ cfg->divs.dvs = 1;
+ armclk = hclk;
+ } else
+ cfg->divs.dvs = 0;
+
+ cfg->freq.armclk = armclk;
+
+ /* store the result, and then return */
+
+ cfg->divs.h_divisor = hdiv;
+ cfg->divs.p_divisor = pdiv;
+
+ return 0;
+
+ invalid:
+ return -EINVAL;
+}
+
+#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
+ S3C2440_CAMDIVN_HCLK4_HALF)
+
+/**
+ * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
+ * @cfg: The cpu frequency settings.
+ *
+ * Set the divisors from the settings in @cfg, which where generated
+ * during the calculation phase by s3c2440_cpufreq_calcdivs().
+ */
+static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+ unsigned long clkdiv, camdiv;
+
+ s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
+ cfg->divs.h_divisor, cfg->divs.p_divisor);
+
+ clkdiv = __raw_readl(S3C2410_CLKDIVN);
+ camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+ clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
+ camdiv &= ~CAMDIVN_HCLK_HALF;
+
+ switch (cfg->divs.h_divisor) {
+ case 1:
+ clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
+ break;
+
+ case 2:
+ clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
+ break;
+
+ case 6:
+ camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
+ case 3:
+ clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
+ break;
+
+ case 8:
+ camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
+ case 4:
+ clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
+ break;
+
+ default:
+ BUG(); /* we don't expect to get here. */
+ }
+
+ if (cfg->divs.p_divisor != cfg->divs.h_divisor)
+ clkdiv |= S3C2440_CLKDIVN_PDIVN;
+
+ /* todo - set pclk. */
+
+ /* Write the divisors first with hclk intentionally halved so that
+ * when we write clkdiv we will under-frequency instead of over. We
+ * then make a short delay and remove the hclk halving if necessary.
+ */
+
+ __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
+ __raw_writel(clkdiv, S3C2410_CLKDIVN);
+
+ ndelay(20);
+ __raw_writel(camdiv, S3C2440_CAMDIVN);
+
+ clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
+}
+
+static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
+ int *divs,
+ struct cpufreq_frequency_table *table,
+ size_t table_size)
+{
+ unsigned long freq;
+ int index = 0;
+ int div;
+
+ for (div = *divs; div > 0; div = *divs++) {
+ freq = fclk / div;
+
+ if (freq > max_hclk && div != 1)
+ continue;
+
+ freq /= 1000; /* table is in kHz */
+ index = s3c_cpufreq_addfreq(table, index, table_size, freq);
+ if (index < 0)
+ break;
+ }
+
+ return index;
+}
+
+static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
+
+static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
+ struct cpufreq_frequency_table *table,
+ size_t table_size)
+{
+ int ret;
+
+ WARN_ON(cfg->info == NULL);
+ WARN_ON(cfg->board == NULL);
+
+ ret = run_freq_for(cfg->info->max.hclk,
+ cfg->info->max.fclk,
+ hclk_divs,
+ table, table_size);
+
+ s3c_freq_dbg("%s: returning %d\n", __func__, ret);
+
+ return ret;
+}
+
+struct s3c_cpufreq_info s3c2440_cpufreq_info = {
+ .max = {
+ .fclk = 400000000,
+ .hclk = 133333333,
+ .pclk = 66666666,
+ },
+
+ .locktime_m = 300,
+ .locktime_u = 300,
+ .locktime_bits = 16,
+
+ .name = "s3c244x",
+ .calc_iotiming = s3c2410_iotiming_calc,
+ .set_iotiming = s3c2410_iotiming_set,
+ .get_iotiming = s3c2410_iotiming_get,
+ .set_fvco = s3c2410_set_fvco,
+
+ .set_refresh = s3c2410_cpufreq_setrefresh,
+ .set_divs = s3c2440_cpufreq_setdivs,
+ .calc_divs = s3c2440_cpufreq_calcdivs,
+ .calc_freqtable = s3c2440_cpufreq_calctable,
+
+ .resume_clocks = s3c244x_setup_clocks,
+
+ .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
+};
+
+static int s3c2440_cpufreq_add(struct sys_device *sysdev)
+{
+ xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+ hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+ fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+ armclk = s3c_cpufreq_clk_get(NULL, "armclk");
+
+ if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
+ printk(KERN_ERR "%s: failed to get clocks\n", __func__);
+ return -ENOENT;
+ }
+
+ return s3c_cpufreq_register(&s3c2440_cpufreq_info);
+}
+
+static struct sysdev_driver s3c2440_cpufreq_driver = {
+ .add = s3c2440_cpufreq_add,
+};
+
+static int s3c2440_cpufreq_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass,
+ &s3c2440_cpufreq_driver);
+}
+
+/* arch_initcall adds the clocks we need, so use subsys_initcall. */
+subsys_initcall(s3c2440_cpufreq_init);
+
+static struct sysdev_driver s3c2442_cpufreq_driver = {
+ .add = s3c2440_cpufreq_add,
+};
+
+static int s3c2442_cpufreq_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass,
+ &s3c2442_cpufreq_driver);
+}
+
+subsys_initcall(s3c2442_cpufreq_init);
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
new file mode 100644
index 00000000..f105d5e8
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
@@ -0,0 +1,97 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-12000000.c
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (12MHz Crystal)
+ *
+ * This program is free software; you can 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/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
+ { .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
+ { .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
+ { .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
+ { .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
+ { .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
+ { .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
+ { .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
+ { .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
+ { .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
+ { .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
+ { .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
+ { .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
+ { .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
+ { .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
+ { .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
+ { .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
+ { .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
+ { .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
+ { .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
+ { .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
+ { .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
+ { .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
+ { .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
+ { .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
+ { .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
+ { .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
+ { .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
+};
+
+static int s3c2440_plls12_add(struct sys_device *dev)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 12000000) {
+ printk(KERN_INFO "Using PLL table for 12MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_12,
+ ARRAY_SIZE(s3c2440_plls_12));
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_plls12_drv = {
+ .add = s3c2440_plls12_add,
+};
+
+static int __init s3c2440_pll_12mhz(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_plls12_drv);
+
+}
+
+arch_initcall(s3c2440_pll_12mhz);
+
+static struct sysdev_driver s3c2442_plls12_drv = {
+ .add = s3c2440_plls12_add,
+};
+
+static int __init s3c2442_pll_12mhz(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_plls12_drv);
+
+}
+
+arch_initcall(s3c2442_pll_12mhz);
diff --git a/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
new file mode 100644
index 00000000..c8a8f90e
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
@@ -0,0 +1,127 @@
+/* arch/arm/mach-s3c2440/s3c2440-pll-16934400.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ * Vincent Sanders <vince@arm.linux.org.uk>
+ *
+ * S3C2440/S3C2442 CPU PLL tables (16.93444MHz Crystal)
+ *
+ * This program is free software; you can 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/sysdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+
+static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
+ { .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
+ { .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
+ { .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
+ { .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
+ { .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
+ { .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
+ { .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
+ { .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
+ { .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
+ { .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
+ { .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
+ { .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
+ { .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
+ { .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
+ { .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
+ { .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
+ { .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
+ { .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
+ { .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
+ { .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
+ { .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
+ { .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
+ { .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
+ { .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
+ { .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
+ { .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
+ { .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
+ { .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
+ { .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
+ { .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
+ { .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
+ { .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
+ { .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
+ { .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
+ { .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
+ { .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
+ { .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
+ { .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
+ { .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
+ { .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
+ { .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
+ { .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
+ { .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
+ { .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
+ { .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
+ { .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
+ { .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
+ { .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
+ { .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
+ { .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
+ { .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
+ { .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
+ { .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
+ { .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
+ { .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
+};
+
+static int s3c2440_plls169344_add(struct sys_device *dev)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ if (IS_ERR(xtal_clk))
+ return PTR_ERR(xtal_clk);
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ if (xtal == 169344000) {
+ printk(KERN_INFO "Using PLL table for 16.9344MHz crystal\n");
+ return s3c_plltab_register(s3c2440_plls_169344,
+ ARRAY_SIZE(s3c2440_plls_169344));
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_plls169344_drv = {
+ .add = s3c2440_plls169344_add,
+};
+
+static int __init s3c2440_pll_16934400(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass,
+ &s3c2440_plls169344_drv);
+
+}
+
+arch_initcall(s3c2440_pll_16934400);
+
+static struct sysdev_driver s3c2442_plls169344_drv = {
+ .add = s3c2440_plls169344_add,
+};
+
+static int __init s3c2442_pll_16934400(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass,
+ &s3c2442_plls169344_drv);
+
+}
+
+arch_initcall(s3c2442_pll_16934400);
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
new file mode 100644
index 00000000..ce99ff72
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-s3c2440/s3c2440.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 Mobile 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+static struct sys_device s3c2440_sysdev = {
+ .cls = &s3c2440_sysclass,
+};
+
+int __init s3c2440_init(void)
+{
+ printk("S3C2440: Initialising architecture\n");
+
+ /* change irq for watchdog */
+
+ s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
+ s3c_device_wdt.resource[1].end = IRQ_S3C2440_WDT;
+
+ /* register suspend/resume handlers */
+
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+ /* register our system device for everything else */
+
+ return sysdev_register(&s3c2440_sysdev);
+}
+
+void __init s3c2440_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up;
+}
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
new file mode 100644
index 00000000..6224bad4
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -0,0 +1,185 @@
+/* linux/arch/arm/mach-s3c2442/s3c2442.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2442 core and lock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/s3c244x.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* S3C2442 extended clock support */
+
+static unsigned long s3c2442_camif_upll_round(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int div;
+
+ if (rate > parent_rate)
+ return parent_rate;
+
+ div = parent_rate / rate;
+
+ if (div == 3)
+ return parent_rate / 3;
+
+ /* note, we remove the +/- 1 calculations for the divisor */
+
+ div /= 2;
+
+ if (div < 1)
+ div = 1;
+ else if (div > 16)
+ div = 16;
+
+ return parent_rate / (div * 2);
+}
+
+static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+
+ rate = s3c2442_camif_upll_round(clk, rate);
+
+ camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
+
+ if (rate == parent_rate) {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
+ } else if ((parent_rate / rate) == 3) {
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
+ } else {
+ camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
+ camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
+ camdivn |= (((parent_rate / rate) / 2) - 1);
+ }
+
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+/* Extra S3C2442 clocks */
+
+static struct clk s3c2442_clk_cam = {
+ .name = "camif",
+ .id = -1,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2440_CLKCON_CAMERA,
+};
+
+static struct clk s3c2442_clk_cam_upll = {
+ .name = "camif-upll",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_rate = s3c2442_camif_upll_setrate,
+ .round_rate = s3c2442_camif_upll_round,
+ },
+};
+
+static int s3c2442_clk_add(struct sys_device *sysdev)
+{
+ struct clk *clock_upll;
+ struct clk *clock_h;
+ struct clk *clock_p;
+
+ clock_p = clk_get(NULL, "pclk");
+ clock_h = clk_get(NULL, "hclk");
+ clock_upll = clk_get(NULL, "upll");
+
+ if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
+ printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
+ return -EINVAL;
+ }
+
+ s3c2442_clk_cam.parent = clock_h;
+ s3c2442_clk_cam_upll.parent = clock_upll;
+
+ s3c24xx_register_clock(&s3c2442_clk_cam);
+ s3c24xx_register_clock(&s3c2442_clk_cam_upll);
+
+ clk_disable(&s3c2442_clk_cam);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2442_clk_driver = {
+ .add = s3c2442_clk_add,
+};
+
+static __init int s3c2442_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
+
+
+static struct sys_device s3c2442_sysdev = {
+ .cls = &s3c2442_sysclass,
+};
+
+int __init s3c2442_init(void)
+{
+ printk("S3C2442: Initialising architecture\n");
+
+ register_syscore_ops(&s3c2410_pm_syscore_ops);
+ register_syscore_ops(&s3c244x_pm_syscore_ops);
+ register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
+ return sysdev_register(&s3c2442_sysdev);
+}
+
+void __init s3c2442_map_io(void)
+{
+ s3c244x_map_io();
+
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down;
+}
diff --git a/arch/arm/mach-s3c2440/s3c244x-clock.c b/arch/arm/mach-s3c2440/s3c244x-clock.c
new file mode 100644
index 00000000..f8d96130
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c244x-clock.c
@@ -0,0 +1,138 @@
+/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2440/S3C2442 Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/atomic.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long camdivn;
+ unsigned long dvs;
+
+ if (parent == &clk_f)
+ dvs = 0;
+ else if (parent == &clk_h)
+ dvs = S3C2440_CAMDIVN_DVSEN;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ camdivn = __raw_readl(S3C2440_CAMDIVN);
+ camdivn &= ~S3C2440_CAMDIVN_DVSEN;
+ camdivn |= dvs;
+ __raw_writel(camdivn, S3C2440_CAMDIVN);
+
+ return 0;
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2440_setparent_armclk,
+ },
+};
+
+static int s3c244x_clk_add(struct sys_device *sysdev)
+{
+ unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
+ unsigned long clkdivn;
+ struct clk *clock_upll;
+ int ret;
+
+ printk("S3C244X: Clock Support, DVS %s\n",
+ (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
+
+ clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
+
+ ret = s3c24xx_register_clock(&clk_arm);
+ if (ret < 0) {
+ printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
+ return ret;
+ }
+
+ clock_upll = clk_get(NULL, "upll");
+ if (IS_ERR(clock_upll)) {
+ printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
+ return -ENOENT;
+ }
+
+ /* check rate of UPLL, and if it is near 96MHz, then change
+ * to using half the UPLL rate for the system */
+
+ if (clk_get_rate(clock_upll) > (94 * MHZ)) {
+ clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
+
+ spin_lock(&clocks_lock);
+
+ clkdivn = __raw_readl(S3C2410_CLKDIVN);
+ clkdivn |= S3C2440_CLKDIVN_UCLK;
+ __raw_writel(clkdivn, S3C2410_CLKDIVN);
+
+ spin_unlock(&clocks_lock);
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_clk_driver = {
+ .add = s3c244x_clk_add,
+};
+
+static int s3c2440_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_clk_driver);
+}
+
+arch_initcall(s3c2440_clk_init);
+
+static struct sysdev_driver s3c2442_clk_driver = {
+ .add = s3c244x_clk_add,
+};
+
+static int s3c2442_clk_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_clk_driver);
+}
+
+arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
new file mode 100644
index 00000000..c63e8f26
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
@@ -0,0 +1,138 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
+ *
+ * Copyright (c) 2003-2004 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+/* camera irq */
+
+static void s3c_irq_demux_cam(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= 11;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ generic_handle_irq(IRQ_S3C2440_CAM_C);
+ }
+ if (subsrc & 2) {
+ generic_handle_irq(IRQ_S3C2440_CAM_P);
+ }
+ }
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+
+static void
+s3c_irq_cam_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_CAM, 3 << 11);
+}
+
+static void
+s3c_irq_cam_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void
+s3c_irq_cam_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_CAM, 3 << 11);
+}
+
+static struct irq_chip s3c_irq_cam = {
+ .irq_mask = s3c_irq_cam_mask,
+ .irq_unmask = s3c_irq_cam_unmask,
+ .irq_ack = s3c_irq_cam_ack,
+};
+
+static int s3c244x_irq_add(struct sys_device *sysdev)
+{
+ unsigned int irqno;
+
+ irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
+ handle_level_irq);
+ set_irq_flags(IRQ_NFCON, IRQF_VALID);
+
+ /* add chained handler for camera */
+
+ irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
+ handle_level_irq);
+ irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+
+ for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
+ irq_set_chip_and_handler(irqno, &s3c_irq_cam,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2440_irq_driver = {
+ .add = s3c244x_irq_add,
+};
+
+static int s3c2440_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_irq_driver);
+}
+
+arch_initcall(s3c2440_irq_init);
+
+static struct sysdev_driver s3c2442_irq_driver = {
+ .add = s3c244x_irq_add,
+};
+
+
+static int s3c2442_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver);
+}
+
+arch_initcall(s3c2442_irq_init);
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
new file mode 100644
index 00000000..7e8a23d2
--- /dev/null
+++ b/arch/arm/mach-s3c2440/s3c244x.c
@@ -0,0 +1,196 @@
+/* linux/arch/arm/plat-s3c24xx/s3c244x.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <mach/regs-clock.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-gpioj.h>
+#include <mach/regs-dsc.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c244x.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/pll.h>
+#include <plat/nand-core.h>
+
+static struct map_desc s3c244x_iodesc[] __initdata = {
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(WATCHDOG),
+};
+
+/* uart initialisation */
+
+void __init s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+void __init s3c244x_map_io(void)
+{
+ /* register our io-tables */
+
+ iotable_init(s3c244x_iodesc, ARRAY_SIZE(s3c244x_iodesc));
+
+ /* rename any peripherals used differing from the s3c2410 */
+
+ s3c_device_sdi.name = "s3c2440-sdi";
+ s3c_device_i2c0.name = "s3c2440-i2c";
+ s3c_nand_setname("s3c2440-nand");
+ s3c_device_ts.name = "s3c2440-ts";
+ s3c_device_usbgadget.name = "s3c2440-usbgadget";
+}
+
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long clkdiv;
+ unsigned long camdiv;
+ unsigned long xtal;
+ unsigned long hclk, fclk, pclk;
+ int hdiv = 1;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
+
+ clkdiv = __raw_readl(S3C2410_CLKDIVN);
+ camdiv = __raw_readl(S3C2440_CAMDIVN);
+
+ /* work out clock scalings */
+
+ switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
+ case S3C2440_CLKDIVN_HDIVN_1:
+ hdiv = 1;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_2:
+ hdiv = 2;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_4_8:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
+ break;
+
+ case S3C2440_CLKDIVN_HDIVN_3_6:
+ hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
+ break;
+ }
+
+ hclk = fclk / hdiv;
+ pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
+
+ /* print brief summary of clocks, etc */
+
+ printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
+ print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+}
+
+void __init s3c244x_init_clocks(int xtal)
+{
+ /* initialise the clocks here, to allow other things like the
+ * console to use them, and to add new ones after the initialisation
+ */
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c244x_setup_clocks();
+ s3c2410_baseclk_add();
+}
+
+/* Since the S3C2442 and S3C2440 share items, put both sysclasses here */
+
+struct sysdev_class s3c2440_sysclass = {
+ .name = "s3c2440-core",
+};
+
+struct sysdev_class s3c2442_sysclass = {
+ .name = "s3c2442-core",
+};
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2440 based system)
+ * as a driver which may support both 2410 and 2440 may try and use it.
+*/
+
+static int __init s3c2440_core_init(void)
+{
+ return sysdev_class_register(&s3c2440_sysclass);
+}
+
+core_initcall(s3c2440_core_init);
+
+static int __init s3c2442_core_init(void)
+{
+ return sysdev_class_register(&s3c2442_sysclass);
+}
+
+core_initcall(s3c2442_core_init);
+
+
+#ifdef CONFIG_PM
+static struct sleep_save s3c244x_sleep[] = {
+ SAVE_ITEM(S3C2440_DSC0),
+ SAVE_ITEM(S3C2440_DSC1),
+ SAVE_ITEM(S3C2440_GPJDAT),
+ SAVE_ITEM(S3C2440_GPJCON),
+ SAVE_ITEM(S3C2440_GPJUP)
+};
+
+static int s3c244x_suspend(void)
+{
+ s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+ return 0;
+}
+
+static void s3c244x_resume(void)
+{
+ s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+}
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume NULL
+#endif
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+ .suspend = s3c244x_suspend,
+ .resume = s3c244x_resume,
+};
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
new file mode 100644
index 00000000..d8eb8682
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -0,0 +1,33 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config CPU_S3C2443
+ bool
+ depends on ARCH_S3C2410
+ select CPU_ARM920T
+ select S3C2443_DMA if S3C2410_DMA
+ select CPU_LLSERIAL_S3C2440
+ select SAMSUNG_CLKSRC
+ select S3C2443_CLOCK
+ select S3C_GPIO_PULL_S3C2443
+ help
+ Support for the S3C2443 SoC from the S3C24XX line
+
+config S3C2443_DMA
+ bool
+ depends on CPU_S3C2443
+ help
+ Internal config node for S3C2443 DMA support
+
+menu "S3C2443 Machines"
+
+config MACH_SMDK2443
+ bool "SMDK2443"
+ select CPU_S3C2443
+ select MACH_SMDK
+ select S3C_DEV_HSMMC1
+ help
+ Say Y here if you are using an SMDK2443
+
+endmenu
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
new file mode 100644
index 00000000..d1843c9e
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Makefile
@@ -0,0 +1,20 @@
+# arch/arm/mach-s3c2443/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_CPU_S3C2443) += s3c2443.o
+obj-$(CONFIG_CPU_S3C2443) += irq.o
+obj-$(CONFIG_CPU_S3C2443) += clock.o
+
+obj-$(CONFIG_S3C2443_DMA) += dma.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
new file mode 100644
index 00000000..f4ec6d57
--- /dev/null
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -0,0 +1,376 @@
+/* linux/arch/arm/mach-s3c2443/clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+/* We currently have to assume that the system is running
+ * from the XTPll input, and that all ***REFCLKs are being
+ * fed from it, as we cannot read the state of OM[4] from
+ * software.
+ *
+ * It would be possible for each board initialisation to
+ * set the correct muxing at initialisation
+*/
+
+/* clock selections */
+
+static struct clk clk_i2s_ext = {
+ .name = "i2s-ext",
+ .id = -1,
+};
+
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
+/* armdiv divisor table */
+
+static unsigned int armdiv[16] = {
+ [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
+ [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
+ [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
+ [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
+ [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
+ [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
+ [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
+ [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
+};
+
+static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
+{
+ clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+
+ return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
+}
+
+static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned best = 256; /* bigger than any value */
+ unsigned div;
+ int ptr;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best)
+ best = div;
+ }
+
+ return parent / best;
+}
+
+static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ unsigned long calc;
+ unsigned div;
+ unsigned best = 256; /* bigger than any value */
+ int ptr;
+ int val = -1;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(armdiv); ptr++) {
+ div = armdiv[ptr];
+ calc = parent / div;
+ if (calc <= rate && div < best) {
+ best = div;
+ val = ptr;
+ }
+ }
+
+ if (val >= 0) {
+ unsigned long clkcon0;
+
+ clkcon0 = __raw_readl(S3C2443_CLKDIV0);
+ clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
+ clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
+ __raw_writel(clkcon0, S3C2443_CLKDIV0);
+ }
+
+ return (val == -1) ? -EINVAL : 0;
+}
+
+static struct clk clk_armdiv = {
+ .name = "armdiv",
+ .id = -1,
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .round_rate = s3c2443_armclk_roundrate,
+ .set_rate = s3c2443_armclk_setrate,
+ },
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, from armdiv or from hclk.
+ */
+
+static struct clk *clk_arm_sources[] = {
+ [0] = &clk_armdiv,
+ [1] = &clk_h,
+};
+
+static struct clksrc_clk clk_arm = {
+ .clk = {
+ .name = "armclk",
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_arm_sources,
+ .nr_sources = ARRAY_SIZE(clk_arm_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
+};
+
+/* hsspi
+ *
+ * high-speed spi clock, sourced from esysclk
+*/
+
+static struct clksrc_clk clk_hsspi = {
+ .clk = {
+ .name = "hsspi",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+
+/* clk_hsmcc_div
+ *
+ * this clock is sourced from epll, and is fed through a divider,
+ * to a mux controlled by sclkcon where either it or a extclk can
+ * be fed to the hsmmc block
+*/
+
+static struct clksrc_clk clk_hsmmc_div = {
+ .clk = {
+ .name = "hsmmc-div",
+ .id = 1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
+};
+
+static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
+{
+ unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
+
+ clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
+ S3C2443_SCLKCON_HSMMCCLK_EPLL);
+
+ if (parent == &clk_epll)
+ clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
+ else if (parent == &clk_ext)
+ clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
+ else
+ return -EINVAL;
+
+ if (clk->usage > 0) {
+ __raw_writel(clksrc, S3C2443_SCLKCON);
+ }
+
+ clk->parent = parent;
+ return 0;
+}
+
+static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
+{
+ return s3c2443_setparent_hsmmc(clk, clk->parent);
+}
+
+static struct clk clk_hsmmc = {
+ .name = "hsmmc-if",
+ .id = 1,
+ .parent = &clk_hsmmc_div.clk,
+ .enable = s3c2443_enable_hsmmc,
+ .ops = &(struct clk_ops) {
+ .set_parent = s3c2443_setparent_hsmmc,
+ },
+};
+
+/* i2s_eplldiv
+ *
+ * This clock is the output from the I2S divisor of ESYSCLK, and is separate
+ * from the mux that comes after it (cannot merge into one single clock)
+*/
+
+static struct clksrc_clk clk_i2s_eplldiv = {
+ .clk = {
+ .name = "i2s-eplldiv",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
+};
+
+/* i2s-ref
+ *
+ * i2s bus reference clock, selectable from external, esysclk or epllref
+ *
+ * Note, this used to be two clocks, but was compressed into one.
+*/
+
+struct clk *clk_i2s_srclist[] = {
+ [0] = &clk_i2s_eplldiv.clk,
+ [1] = &clk_i2s_ext,
+ [2] = &clk_epllref.clk,
+ [3] = &clk_epllref.clk,
+};
+
+static struct clksrc_clk clk_i2s = {
+ .clk = {
+ .name = "i2s-if",
+ .id = -1,
+ .ctrlbit = S3C2443_SCLKCON_I2SCLK,
+ .enable = s3c2443_clkcon_enable_s,
+
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_i2s_srclist,
+ .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
+};
+
+/* standard clock definitions */
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "sdi",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_SDI,
+ }, {
+ .name = "iis",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_IIS,
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_SPI0,
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_SPI1,
+ }
+};
+
+static struct clk init_clocks[] = {
+};
+
+/* clocks to add straight away */
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+ &clk_arm,
+ &clk_i2s_eplldiv,
+ &clk_i2s,
+ &clk_hsspi,
+ &clk_hsmmc_div,
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_hsmmc,
+ &clk_armdiv,
+};
+
+void __init_or_cpufreq s3c2443_setup_clocks(void)
+{
+ s3c2443_common_setup_clocks(s3c2443_get_mpll, s3c2443_fclk_div);
+}
+
+void __init s3c2443_init_clocks(int xtal)
+{
+ unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+ int ptr;
+
+ clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c2443_common_init_clocks(xtal, s3c2443_get_mpll, s3c2443_fclk_div);
+
+ s3c2443_setup_clocks();
+
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
+ /* register clocks from clock array */
+
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ /* We must be careful disabling the clocks we are not intending to
+ * be using at boot time, as subsystems such as the LCD which do
+ * their own DMA requests to the bus can cause the system to lockup
+ * if they where in the middle of requesting bus access.
+ *
+ * Disabling the LCD clock if the LCD is active is very dangerous,
+ * and therefore the bootloader should be careful to not enable
+ * the LCD clock if it is not needed.
+ */
+
+ /* install (and disable) the clocks we do not need immediately */
+
+ 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-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
new file mode 100644
index 00000000..3f658685
--- /dev/null
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -0,0 +1,180 @@
+/* linux/arch/arm/mach-s3c2443/dma.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 DMA selection
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <plat/regs-ac97.h>
+#include <plat/regs-dma.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-lcd.h>
+#include <mach/regs-sdi.h>
+#include <plat/regs-iis.h>
+#include <plat/regs-spi.h>
+
+#define MAP(x) { \
+ [0] = (x) | DMA_CH_VALID, \
+ [1] = (x) | DMA_CH_VALID, \
+ [2] = (x) | DMA_CH_VALID, \
+ [3] = (x) | DMA_CH_VALID, \
+ [4] = (x) | DMA_CH_VALID, \
+ [5] = (x) | DMA_CH_VALID, \
+ }
+
+static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
+ [DMACH_XD0] = {
+ .name = "xdreq0",
+ .channels = MAP(S3C2443_DMAREQSEL_XDREQ0),
+ },
+ [DMACH_XD1] = {
+ .name = "xdreq1",
+ .channels = MAP(S3C2443_DMAREQSEL_XDREQ1),
+ },
+ [DMACH_SDI] = {
+ .name = "sdi",
+ .channels = MAP(S3C2443_DMAREQSEL_SDI),
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_SPI0] = {
+ .name = "spi0",
+ .channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
+ .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
+ },
+ [DMACH_SPI1] = {
+ .name = "spi1",
+ .channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
+ .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
+ .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
+ },
+ [DMACH_UART0] = {
+ .name = "uart0",
+ .channels = MAP(S3C2443_DMAREQSEL_UART0_0),
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1] = {
+ .name = "uart1",
+ .channels = MAP(S3C2443_DMAREQSEL_UART1_0),
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2] = {
+ .name = "uart2",
+ .channels = MAP(S3C2443_DMAREQSEL_UART2_0),
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_UART3] = {
+ .name = "uart3",
+ .channels = MAP(S3C2443_DMAREQSEL_UART3_0),
+ .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH,
+ .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH,
+ },
+ [DMACH_UART0_SRC2] = {
+ .name = "uart0",
+ .channels = MAP(S3C2443_DMAREQSEL_UART0_1),
+ .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
+ },
+ [DMACH_UART1_SRC2] = {
+ .name = "uart1",
+ .channels = MAP(S3C2443_DMAREQSEL_UART1_1),
+ .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
+ },
+ [DMACH_UART2_SRC2] = {
+ .name = "uart2",
+ .channels = MAP(S3C2443_DMAREQSEL_UART2_1),
+ .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
+ .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
+ },
+ [DMACH_UART3_SRC2] = {
+ .name = "uart3",
+ .channels = MAP(S3C2443_DMAREQSEL_UART3_1),
+ .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH,
+ .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH,
+ },
+ [DMACH_TIMER] = {
+ .name = "timer",
+ .channels = MAP(S3C2443_DMAREQSEL_TIMER),
+ },
+ [DMACH_I2S_IN] = {
+ .name = "i2s-sdi",
+ .channels = MAP(S3C2443_DMAREQSEL_I2SRX),
+ .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_I2S_OUT] = {
+ .name = "i2s-sdo",
+ .channels = MAP(S3C2443_DMAREQSEL_I2STX),
+ .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
+ },
+ [DMACH_PCM_IN] = {
+ .name = "pcm-in",
+ .channels = MAP(S3C2443_DMAREQSEL_PCMIN),
+ .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+ },
+ [DMACH_PCM_OUT] = {
+ .name = "pcm-out",
+ .channels = MAP(S3C2443_DMAREQSEL_PCMOUT),
+ .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
+ },
+ [DMACH_MIC_IN] = {
+ .name = "mic-in",
+ .channels = MAP(S3C2443_DMAREQSEL_MICIN),
+ .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
+ },
+};
+
+static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map)
+{
+ writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
+ chan->regs + S3C2443_DMA_DMAREQSEL);
+}
+
+static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
+ .select = s3c2443_dma_select,
+ .dcon_mask = 0,
+ .map = s3c2443_dma_mappings,
+ .map_size = ARRAY_SIZE(s3c2443_dma_mappings),
+};
+
+static int __init s3c2443_dma_add(struct sys_device *sysdev)
+{
+ s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
+ return s3c24xx_dma_init_map(&s3c2443_dma_sel);
+}
+
+static struct sysdev_driver s3c2443_dma_driver = {
+ .add = s3c2443_dma_add,
+};
+
+static int __init s3c2443_dma_init(void)
+{
+ return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver);
+}
+
+arch_initcall(s3c2443_dma_init);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
new file mode 100644
index 00000000..83ecb117
--- /dev/null
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -0,0 +1,278 @@
+/* linux/arch/arm/mach-s3c2443/irq.c
+ *
+ * Copyright (c) 2007 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
+
+static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
+{
+ unsigned int subsrc, submsk;
+ unsigned int end;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= (irq - S3C2410_IRQSUB(0));
+ subsrc &= (1 << len)-1;
+
+ end = len + irq;
+
+ for (; irq < end && subsrc; irq++) {
+ if (subsrc & 1)
+ generic_handle_irq(irq);
+
+ subsrc >>= 1;
+ }
+}
+
+/* WDT/AC97 sub interrupts */
+
+static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
+}
+
+#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
+#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
+
+static void s3c2443_irq_wdtac97_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_WDTAC97);
+}
+
+static void s3c2443_irq_wdtac97_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_WDTAC97, SUBMSK_WDTAC97);
+}
+
+static struct irq_chip s3c2443_irq_wdtac97 = {
+ .irq_mask = s3c2443_irq_wdtac97_mask,
+ .irq_unmask = s3c2443_irq_wdtac97_unmask,
+ .irq_ack = s3c2443_irq_wdtac97_ack,
+};
+
+/* LCD sub interrupts */
+
+static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
+}
+
+#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
+#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
+
+static void s3c2443_irq_lcd_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_LCD);
+}
+
+static void s3c2443_irq_lcd_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_LCD, SUBMSK_LCD);
+}
+
+static struct irq_chip s3c2443_irq_lcd = {
+ .irq_mask = s3c2443_irq_lcd_mask,
+ .irq_unmask = s3c2443_irq_lcd_unmask,
+ .irq_ack = s3c2443_irq_lcd_ack,
+};
+
+/* DMA sub interrupts */
+
+static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6);
+}
+
+#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
+#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
+
+static void s3c2443_irq_dma_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static void s3c2443_irq_dma_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_DMA);
+}
+
+static void s3c2443_irq_dma_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_DMA, SUBMSK_DMA);
+}
+
+static struct irq_chip s3c2443_irq_dma = {
+ .irq_mask = s3c2443_irq_dma_mask,
+ .irq_unmask = s3c2443_irq_dma_unmask,
+ .irq_ack = s3c2443_irq_dma_ack,
+};
+
+/* UART3 sub interrupts */
+
+static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2443_irq_demux(IRQ_S3C2443_RX3, 3);
+}
+
+#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
+#define SUBMSK_UART3 (0x7 << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
+
+static void s3c2443_irq_uart3_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_UART3);
+}
+
+static void s3c2443_irq_uart3_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_UART3, SUBMSK_UART3);
+}
+
+static struct irq_chip s3c2443_irq_uart3 = {
+ .irq_mask = s3c2443_irq_uart3_mask,
+ .irq_unmask = s3c2443_irq_uart3_unmask,
+ .irq_ack = s3c2443_irq_uart3_ack,
+};
+
+/* CAM sub interrupts */
+
+static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
+{
+ s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
+}
+
+#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
+#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
+
+static void s3c2443_irq_cam_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static void s3c2443_irq_cam_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_CAM);
+}
+
+static void s3c2443_irq_cam_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_CAM, SUBMSK_CAM);
+}
+
+static struct irq_chip s3c2443_irq_cam = {
+ .irq_mask = s3c2443_irq_cam_mask,
+ .irq_unmask = s3c2443_irq_cam_unmask,
+ .irq_ack = s3c2443_irq_cam_ack,
+};
+
+/* IRQ initialisation code */
+
+static int __init s3c2443_add_sub(unsigned int base,
+ void (*demux)(unsigned int,
+ struct irq_desc *),
+ struct irq_chip *chip,
+ unsigned int start, unsigned int end)
+{
+ unsigned int irqno;
+
+ irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+ irq_set_chained_handler(base, demux);
+
+ for (irqno = start; irqno <= end; irqno++) {
+ irq_set_chip_and_handler(irqno, chip, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ return 0;
+}
+
+static int __init s3c2443_irq_add(struct sys_device *sysdev)
+{
+ printk("S3C2443: IRQ Support\n");
+
+ s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
+ IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
+
+ s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
+ IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
+
+ s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
+ &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
+
+ s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
+ &s3c2443_irq_uart3,
+ IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
+
+ s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
+ &s3c2443_irq_wdtac97,
+ IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
+
+ return 0;
+}
+
+static struct sysdev_driver s3c2443_irq_driver = {
+ .add = s3c2443_irq_add,
+};
+
+static int __init s3c2443_irq_init(void)
+{
+ return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
+}
+
+arch_initcall(s3c2443_irq_init);
+
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
new file mode 100644
index 00000000..514275e4
--- /dev/null
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -0,0 +1,148 @@
+/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://www.fluff.org/ben/smdk2443/
+ *
+ * Thanks to Samsung for the loan of an SMDK2443
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-lcd.h>
+
+#include <mach/idle.h>
+#include <mach/fb.h>
+#include <plat/iic.h>
+
+#include <plat/s3c2410.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#include <plat/common-smdk.h>
+
+static struct map_desc smdk2443_iodesc[] __initdata = {
+ /* ISA IO Space map (memory space selected by A24) */
+
+ {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE,
+ .pfn = __phys_to_pfn(S3C2410_CS2),
+ .length = 0x10000,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
+ .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
+ .length = SZ_4M,
+ .type = MT_DEVICE,
+ }
+};
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ /* IR port */
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x43,
+ .ufcon = 0x51,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ }
+};
+
+static struct platform_device *smdk2443_devices[] __initdata = {
+ &s3c_device_wdt,
+ &s3c_device_i2c0,
+ &s3c_device_hsmmc1,
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+ &s3c_device_ac97,
+#endif
+};
+
+static void __init smdk2443_map_io(void)
+{
+ s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+}
+
+static void __init smdk2443_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+
+#ifdef CONFIG_SND_SOC_SMDK2443_WM9710
+ s3c24xx_ac97_setup_gpio(S3C24XX_AC97_GPE0);
+#endif
+
+ platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
+ smdk_machine_init();
+}
+
+MACHINE_START(SMDK2443, "SMDK2443")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C2410_SDRAM_PA + 0x100,
+
+ .init_irq = s3c24xx_init_irq,
+ .map_io = smdk2443_map_io,
+ .init_machine = smdk2443_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
new file mode 100644
index 00000000..e6a28ba5
--- /dev/null
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -0,0 +1,110 @@
+/* linux/arch/arm/mach-s3c2443/s3c2443.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C2443 Mobile 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-s3c2443-clock.h>
+#include <mach/reset.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <plat/s3c2443.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb-core.h>
+#include <plat/nand-core.h>
+
+static struct map_desc s3c2443_iodesc[] __initdata = {
+ IODESC_ENT(WATCHDOG),
+ IODESC_ENT(CLKPWR),
+ IODESC_ENT(TIMER),
+};
+
+struct sysdev_class s3c2443_sysclass = {
+ .name = "s3c2443-core",
+};
+
+static struct sys_device s3c2443_sysdev = {
+ .cls = &s3c2443_sysclass,
+};
+
+static void s3c2443_hard_reset(void)
+{
+ __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
+}
+
+int __init s3c2443_init(void)
+{
+ printk("S3C2443: Initialising architecture\n");
+
+ s3c24xx_reset_hook = s3c2443_hard_reset;
+
+ s3c_nand_setname("s3c2412-nand");
+ s3c_fb_setname("s3c2443-fb");
+
+ /* change WDT IRQ number */
+ s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
+ s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
+
+ return sysdev_register(&s3c2443_sysdev);
+}
+
+void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
+}
+
+/* s3c2443_map_io
+ *
+ * register the standard cpu IO areas, and any passed in from the
+ * machine specific initialisation.
+ */
+
+void __init s3c2443_map_io(void)
+{
+ s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_s3c2443;
+ s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_s3c2443;
+
+ iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
+}
+
+/* need to register class before we actually register the device, and
+ * we also need to ensure that it has been initialised before any of the
+ * drivers even try to use it (even if not on an s3c2443 based system)
+ * as a driver which may support both 2443 and 2440 may try and use it.
+*/
+
+static int __init s3c2443_core_init(void)
+{
+ return sysdev_class_register(&s3c2443_sysclass);
+}
+
+core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mach-s3c24a0/include/mach/debug-macro.S b/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
new file mode 100644
index 00000000..0c5a7380
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/debug-macro.S
@@ -0,0 +1,27 @@
+/* arch/arm/mach-s3c2410/include/mach/debug-macro.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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C24XX_PA_UART
+ ldr \rv, = S3C24XX_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(S3C2410_UART1_OFF * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c24a0/include/mach/io.h b/arch/arm/mach-s3c24a0/include/mach/io.h
new file mode 100644
index 00000000..4326c30f
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c24a0/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C24A0
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s3c24a0/include/mach/irqs.h b/arch/arm/mach-s3c24a0/include/mach/irqs.h
new file mode 100644
index 00000000..83ce2a7a
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/irqs.h
@@ -0,0 +1,117 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/irqs.h
+ *
+ * Copyright (c) 2003-2005 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.
+*/
+
+
+#ifndef __ASM_ARCH_24A0_IRQS_H
+#define __ASM_ARCH_24A0_IRQS_H __FILE__
+
+#define IRQ_EINT0t2 S3C2410_IRQ(0) /* 16 */
+/* for generic entry-macro.S */
+#define IRQ_EINT0 IRQ_EINT0t2
+
+#define IRQ_EINT3t6 S3C2410_IRQ(1)
+#define IRQ_EINT7t10 S3C2410_IRQ(2)
+#define IRQ_EINT11t14 S3C2410_IRQ(3)
+#define IRQ_EINT15t18 S3C2410_IRQ(4) /* 20 */
+#define IRQ_TICK S3C2410_IRQ(5)
+#define IRQ_DCTQ S3C2410_IRQ(6)
+#define IRQ_MC S3C2410_IRQ(7)
+#define IRQ_ME S3C2410_IRQ(8) /* 24 */
+#define IRQ_KEYPAD S3C2410_IRQ(9)
+#define IRQ_TIMER0 S3C2410_IRQ(10)
+#define IRQ_TIMER1 S3C2410_IRQ(11)
+#define IRQ_TIMER2 S3C2410_IRQ(12)
+#define IRQ_TIMER3_4 S3C2410_IRQ(13)
+#define IRQ_OS_TIMER IRQ_TIMER3_4
+#define IRQ_LCD S3C2410_IRQ(14)
+#define IRQ_CAM_C S3C2410_IRQ(15)
+#define IRQ_WDT_BATFLT S3C2410_IRQ(16) /* 32 */
+#define IRQ_UART0 S3C2410_IRQ(17)
+#define IRQ_CAM_P S3C2410_IRQ(18)
+#define IRQ_MODEM S3C2410_IRQ(19)
+#define IRQ_DMA S3C2410_IRQ(20)
+#define IRQ_SDI S3C2410_IRQ(21)
+#define IRQ_SPI0 S3C2410_IRQ(22)
+#define IRQ_UART1 S3C2410_IRQ(23)
+#define IRQ_AC97_NFLASH S3C2410_IRQ(24) /* 40 */
+#define IRQ_USBD S3C2410_IRQ(25)
+#define IRQ_USBH S3C2410_IRQ(26)
+#define IRQ_IIC S3C2410_IRQ(27)
+#define IRQ_IRDA_MSTICK S3C2410_IRQ(28) /* 44 */
+#define IRQ_VLX_SPI1 S3C2410_IRQ(29)
+#define IRQ_RTC S3C2410_IRQ(30) /* 46 */
+#define IRQ_ADC_PEN S3C2410_IRQ(31)
+
+/* interrupts generated from the external interrupts sources */
+#define IRQ_EINT00 S3C2410_IRQ(32) /* 48 */
+#define IRQ_EINT1 S3C2410_IRQ(33)
+#define IRQ_EINT2 S3C2410_IRQ(34)
+#define IRQ_EINT3 S3C2410_IRQ(35)
+#define IRQ_EINT4 S3C2410_IRQ(36)
+#define IRQ_EINT5 S3C2410_IRQ(37)
+#define IRQ_EINT6 S3C2410_IRQ(38)
+#define IRQ_EINT7 S3C2410_IRQ(39)
+#define IRQ_EINT8 S3C2410_IRQ(40)
+#define IRQ_EINT9 S3C2410_IRQ(41)
+#define IRQ_EINT10 S3C2410_IRQ(42)
+#define IRQ_EINT11 S3C2410_IRQ(43)
+#define IRQ_EINT12 S3C2410_IRQ(44)
+#define IRQ_EINT13 S3C2410_IRQ(45)
+#define IRQ_EINT14 S3C2410_IRQ(46)
+#define IRQ_EINT15 S3C2410_IRQ(47)
+#define IRQ_EINT16 S3C2410_IRQ(48)
+#define IRQ_EINT17 S3C2410_IRQ(49)
+#define IRQ_EINT18 S3C2410_IRQ(50)
+
+#define IRQ_EINT_BIT(x) ((x) - IRQ_EINT00)
+
+/* SUB IRQS */
+#define IRQ_S3CUART_RX0 S3C2410_IRQ(51) /* 67 */
+#define IRQ_S3CUART_TX0 S3C2410_IRQ(52)
+#define IRQ_S3CUART_ERR0 S3C2410_IRQ(53)
+
+#define IRQ_S3CUART_RX1 S3C2410_IRQ(54)
+#define IRQ_S3CUART_TX1 S3C2410_IRQ(55)
+#define IRQ_S3CUART_ERR1 S3C2410_IRQ(56)
+
+#define IRQ_S3CUART_RX2 (0x0)
+#define IRQ_S3CUART_TX2 (0x0)
+#define IRQ_S3CUART_ERR2 (0x0)
+
+
+#define IRQ_IRDA S3C2410_IRQ(57)
+#define IRQ_MSTICK S3C2410_IRQ(58)
+#define IRQ_RESERVED0 S3C2410_IRQ(59)
+#define IRQ_RESERVED1 S3C2410_IRQ(60)
+#define IRQ_RESERVED2 S3C2410_IRQ(61)
+#define IRQ_TIMER3 S3C2410_IRQ(62)
+#define IRQ_TIMER4 S3C2410_IRQ(63)
+#define IRQ_WDT S3C2410_IRQ(64)
+#define IRQ_BATFLT S3C2410_IRQ(65)
+#define IRQ_POST S3C2410_IRQ(66)
+#define IRQ_DISP_FIFO S3C2410_IRQ(67)
+#define IRQ_PENUP S3C2410_IRQ(68)
+#define IRQ_PENDN S3C2410_IRQ(69)
+#define IRQ_ADC S3C2410_IRQ(70)
+#define IRQ_DISP_FRAME S3C2410_IRQ(71)
+#define IRQ_NFLASH S3C2410_IRQ(72)
+#define IRQ_AC97 S3C2410_IRQ(73)
+#define IRQ_SPI1 S3C2410_IRQ(74)
+#define IRQ_VLX S3C2410_IRQ(75)
+#define IRQ_DMA0 S3C2410_IRQ(76)
+#define IRQ_DMA1 S3C2410_IRQ(77)
+#define IRQ_DMA2 S3C2410_IRQ(78)
+#define IRQ_DMA3 S3C2410_IRQ(79)
+
+#define IRQ_TC (0x0)
+
+#define NR_IRQS (IRQ_DMA3+1)
+
+#endif /* __ASM_ARCH_24A0_IRQS_H */
diff --git a/arch/arm/mach-s3c24a0/include/mach/map.h b/arch/arm/mach-s3c24a0/include/mach/map.h
new file mode 100644
index 00000000..d88c8b24
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/map.h
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/map.h
+ *
+ * Copyright 2003-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24A0 - 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_24A0_MAP_H
+#define __ASM_ARCH_24A0_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map.h>
+
+#define S3C24A0_PA_IO_BASE (0x40000000)
+#define S3C24A0_PA_CLKPWR (0x40000000)
+#define S3C24A0_PA_IRQ (0x40200000)
+#define S3C24A0_PA_DMA (0x40400000)
+#define S3C24A0_PA_MEMCTRL (0x40C00000)
+#define S3C24A0_PA_NAND (0x40C00000)
+#define S3C24A0_PA_SROM (0x40C20000)
+#define S3C24A0_PA_SDRAM (0x40C40000)
+#define S3C24A0_PA_BUSM (0x40CE0000)
+#define S3C24A0_PA_USBHOST (0x41000000)
+#define S3C24A0_PA_MODEMIF (0x41180000)
+#define S3C24A0_PA_IRDA (0x41800000)
+#define S3C24A0_PA_TIMER (0x44000000)
+#define S3C24A0_PA_WATCHDOG (0x44100000)
+#define S3C24A0_PA_RTC (0x44200000)
+#define S3C24A0_PA_UART (0x44400000)
+#define S3C24A0_PA_UART0 (S3C24A0_PA_UART)
+#define S3C24A0_PA_UART1 (S3C24A0_PA_UART + 0x4000)
+#define S3C24A0_PA_SPI (0x44500000)
+#define S3C24A0_PA_IIC (0x44600000)
+#define S3C24A0_PA_IIS (0x44700000)
+#define S3C24A0_PA_GPIO (0x44800000)
+#define S3C24A0_PA_KEYIF (0x44900000)
+#define S3C24A0_PA_USBDEV (0x44A00000)
+#define S3C24A0_PA_AC97 (0x45000000)
+#define S3C24A0_PA_ADC (0x45800000)
+#define S3C24A0_PA_SDI (0x46000000)
+#define S3C24A0_PA_MS (0x46100000)
+#define S3C24A0_PA_LCD (0x4A000000)
+#define S3C24A0_PA_VPOST (0x4A100000)
+
+/* physical addresses of all the chip-select areas */
+
+#define S3C24A0_CS0 (0x00000000)
+#define S3C24A0_CS1 (0x04000000)
+#define S3C24A0_CS2 (0x08000000)
+#define S3C24A0_CS3 (0x0C000000)
+#define S3C24A0_CS4 (0x10000000)
+#define S3C24A0_CS5 (0x40000000)
+
+#define S3C24A0_SDRAM_PA (S3C24A0_CS4)
+
+/* Use a single interface for common resources between S3C24XX cpus */
+
+#define S3C24XX_PA_IRQ S3C24A0_PA_IRQ
+#define S3C24XX_PA_MEMCTRL S3C24A0_PA_MEMCTRL
+#define S3C24XX_PA_USBHOST S3C24A0_PA_USBHOST
+#define S3C24XX_PA_DMA S3C24A0_PA_DMA
+#define S3C24XX_PA_CLKPWR S3C24A0_PA_CLKPWR
+#define S3C24XX_PA_LCD S3C24A0_PA_LCD
+#define S3C24XX_PA_UART S3C24A0_PA_UART
+#define S3C24XX_PA_TIMER S3C24A0_PA_TIMER
+#define S3C24XX_PA_USBDEV S3C24A0_PA_USBDEV
+#define S3C24XX_PA_WATCHDOG S3C24A0_PA_WATCHDOG
+#define S3C24XX_PA_IIS S3C24A0_PA_IIS
+#define S3C24XX_PA_GPIO S3C24A0_PA_GPIO
+#define S3C24XX_PA_RTC S3C24A0_PA_RTC
+#define S3C24XX_PA_ADC S3C24A0_PA_ADC
+#define S3C24XX_PA_SPI S3C24A0_PA_SPI
+#define S3C24XX_PA_SDI S3C24A0_PA_SDI
+#define S3C24XX_PA_NAND S3C24A0_PA_NAND
+
+#define S3C_PA_UART S3C24A0_PA_UART
+#define S3C_PA_IIC S3C24A0_PA_IIC
+#define S3C_PA_NAND S3C24XX_PA_NAND
+
+#endif /* __ASM_ARCH_24A0_MAP_H */
diff --git a/arch/arm/mach-s3c24a0/include/mach/memory.h b/arch/arm/mach-s3c24a0/include/mach/memory.h
new file mode 100644
index 00000000..7d208a71
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/memory.h
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/memory.h
+ * from linux/include/asm-arm/arch-rpc/memory.h
+ *
+ * Copyright (C) 1996,1997,1998 Russell King.
+ *
+ * This program is free software; you can 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_24A0_MEMORY_H
+#define __ASM_ARCH_24A0_MEMORY_H __FILE__
+
+#define PLAT_PHYS_OFFSET UL(0x10000000)
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+#define __pfn_to_bus(x) __pfn_to_phys(x)
+#define __bus_to_pfn(x) __phys_to_pfn(x)
+
+#endif
diff --git a/arch/arm/mach-s3c24a0/include/mach/regs-clock.h b/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
new file mode 100644
index 00000000..be0af518
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
@@ -0,0 +1,88 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2003-2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C24A0 clock register definitions
+*/
+
+#ifndef __ASM_ARCH_24A0_REGS_CLOCK_H
+#define __ASM_ARCH_24A0_REGS_CLOCK_H __FILE__
+
+#define S3C24A0_MPLLCON S3C2410_CLKREG(0x10)
+#define S3C24A0_UPLLCON S3C2410_CLKREG(0x14)
+#define S3C24A0_CLKCON S3C2410_CLKREG(0x20)
+#define S3C24A0_CLKSRC S3C2410_CLKREG(0x24)
+#define S3C24A0_CLKDIVN S3C2410_CLKREG(0x28)
+
+/* CLKCON register bits */
+
+#define S3C24A0_CLKCON_VLX (1<<29)
+#define S3C24A0_CLKCON_VPOST (1<<28)
+#define S3C24A0_CLKCON_WDT (1<<27) /* reserved */
+#define S3C24A0_CLKCON_MPEGDCTQ (1<<26)
+#define S3C24A0_CLKCON_VPOSTIF (1<<25)
+#define S3C24A0_CLKCON_MPEG4IF (1<<24)
+#define S3C24A0_CLKCON_CAM_UPLL (1<<23)
+#define S3C24A0_CLKCON_LCDC (1<<22)
+#define S3C24A0_CLKCON_CAM_HCLK (1<<21)
+#define S3C24A0_CLKCON_MPEG4 (1<<20)
+#define S3C24A0_CLKCON_KEYPAD (1<<19)
+#define S3C24A0_CLKCON_ADC (1<<18)
+#define S3C24A0_CLKCON_SDI (1<<17)
+#define S3C24A0_CLKCON_MS (1<<16) /* memory stick */
+#define S3C24A0_CLKCON_USBD (1<<15)
+#define S3C24A0_CLKCON_GPIO (1<<14)
+#define S3C24A0_CLKCON_IIS (1<<13)
+#define S3C24A0_CLKCON_IIC (1<<12)
+#define S3C24A0_CLKCON_SPI (1<<11)
+#define S3C24A0_CLKCON_UART1 (1<<10)
+#define S3C24A0_CLKCON_UART0 (1<<9)
+#define S3C24A0_CLKCON_PWMT (1<<8)
+#define S3C24A0_CLKCON_USBH (1<<7)
+#define S3C24A0_CLKCON_AC97 (1<<6)
+#define S3C24A0_CLKCON_IrDA (1<<4)
+#define S3C24A0_CLKCON_IDLE (1<<2)
+#define S3C24A0_CLKCON_MON (1<<1)
+#define S3C24A0_CLKCON_STOP (1<<0)
+
+/* CLKSRC register bits */
+
+#define S3C24A0_CLKSRC_OSC (1<<8) /* CLKSRC */
+#define S3C24A0_CLKSRC_UPLL (1<<7)
+#define S3C24A0_CLKSRC_MPLL (1<<5)
+#define S3C24A0_CLKSRC_EXT (1<<4)
+
+/* Use a single interface with the common code, for s3c24xx */
+
+#define S3C2410_MPLLCON S3C24A0_MPLLCON
+#define S3C2410_UPLLCON S3C24A0_UPLLCON
+#define S3C2410_CLKCON S3C24A0_CLKCON
+#define S3C2410_CLKSLOW S3C24A0_CLKSRC
+#define S3C2410_CLKDIVN S3C24A0_CLKDIVN
+
+#define S3C2410_CLKCON_IDLE S3C24A0_CLKCON_IDLE
+#define S3C2410_CLKCON_POWER S3C24A0_CLKCON_STOP
+#define S3C2410_CLKCON_LCDC S3C24A0_CLKCON_LCDC
+#define S3C2410_CLKCON_USBH S3C24A0_CLKCON_USBH
+#define S3C2410_CLKCON_USBD S3C24A0_CLKCON_USBD
+#define S3C2410_CLKCON_PWMT S3C24A0_CLKCON_PWMT
+#define S3C2410_CLKCON_SDI S3C24A0_CLKCON_SDI
+#define S3C2410_CLKCON_UART0 S3C24A0_CLKCON_UART0
+#define S3C2410_CLKCON_UART1 S3C24A0_CLKCON_UART1
+#define S3C2410_CLKCON_GPIO S3C24A0_CLKCON_GPIO
+#define S3C2410_CLKCON_ADC S3C24A0_CLKCON_ADC
+#define S3C2410_CLKCON_IIC S3C24A0_CLKCON_IIC
+#define S3C2410_CLKCON_IIS S3C24A0_CLKCON_IIS
+#define S3C2410_CLKCON_SPI S3C24A0_CLKCON_SPI
+
+#define S3C2410_CLKSLOW_UCLK_OFF S3C24A0_CLKSRC_UPLL
+#define S3C2410_CLKSLOW_MPLL_OFF S3C24A0_CLKSRC_MPLL
+#define S3C2410_CLKSLOW_SLOW (0xFF)
+#define S3C2410_CLKSLOW_GET_SLOWVAL(x) (0x1)
+
+#endif /* __ASM_ARCH_24A0_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c24a0/include/mach/regs-irq.h b/arch/arm/mach-s3c24a0/include/mach/regs-irq.h
new file mode 100644
index 00000000..6086f6f1
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/regs-irq.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can 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_24A0_REGS_IRQ_H
+#define ___ASM_ARCH_24A0_REGS_IRQ_H __FILE__
+
+
+#define S3C2410_EINTMASK S3C2410_EINTREG(0x034)
+#define S3C2410_EINTPEND S3C2410_EINTREG(0X038)
+
+#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x034)
+#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X038)
+
+#endif /* __ASM_ARCH_24A0_REGS_IRQ_H */
+
+
+
diff --git a/arch/arm/mach-s3c24a0/include/mach/system.h b/arch/arm/mach-s3c24a0/include/mach/system.h
new file mode 100644
index 00000000..bd1bd195
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/system.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/system.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24A0 - System function defines and includes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+#include <mach/map.h>
+
+static void arch_idle(void)
+{
+ /* currently no specific idle support. */
+}
+
+void (*s3c24xx_reset_hook)(void);
+
+#include <asm/plat-s3c24xx/system-reset.h>
diff --git a/arch/arm/mach-s3c24a0/include/mach/tick.h b/arch/arm/mach-s3c24a0/include/mach/tick.h
new file mode 100644
index 00000000..9dea8ba6
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/tick.h
@@ -0,0 +1,15 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/tick.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24A0 - timer tick support
+ */
+
+#define SUBSRC_TIMER4 (1 << (IRQ_TIMER4 - IRQ_S3CUART_RX0))
+
+static inline int s3c24xx_ostimer_pending(void)
+{
+ return __raw_readl(S3C2410_SUBSRCPND) & SUBSRC_TIMER4;
+}
diff --git a/arch/arm/mach-s3c24a0/include/mach/timex.h b/arch/arm/mach-s3c24a0/include/mach/timex.h
new file mode 100644
index 00000000..98573424
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/timex.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s3c24a0/include/mach/timex.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c24a0/include/mach/vmalloc.h b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
new file mode 100644
index 00000000..6480b152
--- /dev/null
+++ b/arch/arm/mach-s3c24a0/include/mach/vmalloc.h
@@ -0,0 +1,17 @@
+/* linux/include/asm-arm/arch-s3c24ao/vmalloc.h
+ *
+ * Copyright 2008 Simtec Electronics <linux@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.
+ *
+ * S3C24A0 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
new file mode 100644
index 00000000..e4177e22
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -0,0 +1,268 @@
+# Copyright 2008 Openmoko, Inc.
+# Simtec Electronics, Ben Dooks <ben@simtec.co.uk>
+#
+# Licensed under GPLv2
+
+# temporary until we can eliminate all drivers using it.
+config PLAT_S3C64XX
+ bool
+ depends on ARCH_S3C64XX
+ select SAMSUNG_WAKEMASK
+ default y
+ help
+ Base platform code for any Samsung S3C64XX device
+
+
+# Configuration options for the S3C6410 CPU
+
+config CPU_S3C6400
+ bool
+ help
+ Enable S3C6400 CPU support
+
+config CPU_S3C6410
+ bool
+ help
+ Enable S3C6410 CPU support
+
+config S3C64XX_DMA
+ bool "S3C64XX DMA"
+ select S3C_DMA
+
+config S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_SDHCI_GPIO
+ bool
+ help
+ Internal configuration for default SDHCI setup for S3C6400 and
+ S3C6410 SoCs.
+
+config S3C64XX_DEV_ONENAND1
+ bool
+ help
+ Compile in platform device definition for OneNAND1 controller
+
+# platform specific device setup
+
+config S3C64XX_SETUP_I2C0
+ bool
+ default y
+ help
+ Common setup code for i2c bus 0.
+
+ Note, currently since i2c0 is always compiled, this setup helper
+ is always compiled with it.
+
+config S3C64XX_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config S3C64XX_SETUP_IDE
+ bool
+ help
+ Common setup code for S3C64XX IDE.
+
+config S3C64XX_SETUP_FB_24BPP
+ bool
+ help
+ Common setup code for S3C64XX with an 24bpp RGB display helper.
+
+config S3C64XX_SETUP_KEYPAD
+ bool
+ help
+ Common setup code for S3C64XX KEYPAD GPIO configurations
+
+config S3C64XX_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for S3C64XX SDHCI GPIO configurations
+
+# S36400 Macchine support
+
+config MACH_SMDK6400
+ bool "SMDK6400"
+ select CPU_S3C6400
+ select S3C_DEV_HSMMC
+ select S3C_DEV_NAND
+ select S3C64XX_SETUP_SDHCI
+ help
+ Machine support for the Samsung SMDK6400
+
+# S3C6410 machine support
+
+config MACH_ANW6410
+ bool "A&W6410"
+ select CPU_S3C6410
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ help
+ Machine support for the A&W6410
+
+config MACH_MINI6410
+ bool "MINI6410"
+ select CPU_S3C6410
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_NAND
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ help
+ Machine support for the FriendlyARM MINI6410
+
+config MACH_REAL6410
+ bool "REAL6410"
+ select CPU_S3C6410
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_SDHCI
+ select S3C_DEV_FB
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C_DEV_NAND
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_TS
+ select S3C_DEV_USB_HOST
+ help
+ Machine support for the CoreWind REAL6410
+
+config MACH_SMDK6410
+ bool "SMDK6410"
+ select CPU_S3C6410
+ select SAMSUNG_DEV_ADC
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_I2C1
+ select SAMSUNG_DEV_IDE
+ select S3C_DEV_FB
+ select S3C_DEV_RTC
+ select SAMSUNG_DEV_TS
+ select S3C_DEV_USB_HOST
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select HAVE_S3C2410_WATCHDOG if WATCHDOG
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
+ select S3C64XX_SETUP_FB_24BPP
+ select S3C64XX_SETUP_KEYPAD
+ help
+ Machine support for the Samsung SMDK6410
+
+# At least some of the SMDK6410s were shipped with the card detect
+# for the MMC/SD slots connected to the same input. This means that
+# either the boards need to be altered to have channel0 to an alternate
+# configuration or that only one slot can be used.
+
+choice
+ prompt "SMDK6410 MMC/SD slot setup"
+ depends on MACH_SMDK6410
+
+config SMDK6410_SD_CH0
+ bool "Use channel 0 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON7 (channel 0) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+config SMDK6410_SD_CH1
+ bool "Use channel 1 only"
+ depends on MACH_SMDK6410
+ help
+ Select CON6 (channel 1) as the MMC/SD slot, as
+ at least some SMDK6410 boards come with the
+ resistors fitted so that the card detects for
+ channels 0 and 1 are the same.
+
+endchoice
+
+config SMDK6410_WM1190_EV1
+ bool "Support Wolfson Microelectronics 1190-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ select REGULATOR
+ select REGULATOR_WM8350
+ select S3C24XX_GPIO_EXTRA64
+ select MFD_WM8350_I2C
+ select MFD_WM8350_CONFIG_MODE_0
+ select MFD_WM8350_CONFIG_MODE_3
+ select MFD_WM8352_CONFIG_MODE_0
+ help
+ The Wolfson Microelectronics 1190-EV1 is a WM835x based PMIC
+ and audio daughtercard for the Samsung SMDK6410 reference
+ platform. Enabling this option will build support for this
+ module into the kernel. The presence of the module will be
+ detected at runtime so the the resulting kernel can be used
+ with or without the 1190-EV1 fitted.
+
+config SMDK6410_WM1192_EV1
+ bool "Support Wolfson Microelectronics 1192-EV1 PMIC card"
+ depends on MACH_SMDK6410
+ select REGULATOR
+ select REGULATOR_WM831X
+ select S3C24XX_GPIO_EXTRA64
+ select MFD_WM831X
+ select MFD_WM831X_I2C
+ help
+ The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
+ daughtercard for the Samsung SMDK6410 reference platform.
+ Enabling this option will build support for this module into
+ the kernel. The presence of the daughtercard will be
+ detected at runtime so the the resulting kernel can be used
+ with or without the 1192-EV1 fitted.
+
+config MACH_NCP
+ bool "NCP"
+ select CPU_S3C6410
+ select S3C_DEV_I2C1
+ select S3C_DEV_HSMMC1
+ select S3C64XX_SETUP_I2C1
+ help
+ Machine support for the Samsung NCP
+
+config MACH_HMT
+ bool "Airgoo HMT"
+ select CPU_S3C6410
+ select S3C_DEV_FB
+ select S3C_DEV_NAND
+ select S3C_DEV_USB_HOST
+ select S3C64XX_SETUP_FB_24BPP
+ select SAMSUNG_DEV_PWM
+ help
+ Machine support for the Airgoo HMT
+
+config MACH_SMARTQ
+ bool
+ select CPU_S3C6410
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_FB
+ select S3C_DEV_HWMON
+ select S3C_DEV_RTC
+ select S3C_DEV_USB_HSOTG
+ select S3C_DEV_USB_HOST
+ select S3C64XX_SETUP_SDHCI
+ select S3C64XX_SETUP_FB_24BPP
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ help
+ Shared machine support for SmartQ 5/7
+
+config MACH_SMARTQ5
+ bool "SmartQ 5"
+ select MACH_SMARTQ
+ help
+ Machine support for the SmartQ 5
+
+config MACH_SMARTQ7
+ bool "SmartQ 7"
+ select MACH_SMARTQ
+ help
+ Machine support for the SmartQ 7
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
new file mode 100644
index 00000000..4657363f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -0,0 +1,69 @@
+# arch/arm/mach-s3c64xx/Makefile
+#
+# Copyright 2008 Openmoko, Inc.
+# Copyright 2008 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core files
+obj-y += cpu.o
+obj-y += clock.o
+obj-y += gpiolib.o
+
+# Core support for S3C6400 system
+
+obj-$(CONFIG_CPU_S3C6400) += s3c6400.o
+obj-$(CONFIG_CPU_S3C6410) += s3c6410.o
+
+obj-y += irq.o
+obj-y += irq-eint.o
+
+# CPU frequency scaling
+
+obj-$(CONFIG_CPU_FREQ_S3C64XX) += cpufreq.o
+
+# DMA support
+
+obj-$(CONFIG_S3C64XX_DMA) += dma.o
+
+# Device setup
+
+obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
+obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
+obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad.o
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+
+# PM
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_PM) += irq-pm.o
+
+# Machine support
+
+obj-$(CONFIG_MACH_ANW6410) += mach-anw6410.o
+obj-$(CONFIG_MACH_SMDK6400) += mach-smdk6400.o
+obj-$(CONFIG_MACH_SMDK6410) += mach-smdk6410.o
+obj-$(CONFIG_MACH_REAL6410) += mach-real6410.o
+obj-$(CONFIG_MACH_MINI6410) += mach-mini6410.o
+obj-$(CONFIG_MACH_NCP) += mach-ncp.o
+obj-$(CONFIG_MACH_HMT) += mach-hmt.o
+obj-$(CONFIG_MACH_SMARTQ) += mach-smartq.o
+obj-$(CONFIG_MACH_SMARTQ5) += mach-smartq5.o
+obj-$(CONFIG_MACH_SMARTQ7) += mach-smartq7.o
+
+# device support
+
+obj-y += dev-uart.o
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+obj-$(CONFIG_S3C64XX_DEV_TS) += dev-ts.o
+obj-$(CONFIG_S3C64XX_DEV_ONENAND1) += dev-onenand1.o
diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot
new file mode 100644
index 00000000..ba41fdc0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x50008000
+params_phys-y := 0x50000100
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
new file mode 100644
index 00000000..fdfc4d5e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -0,0 +1,856 @@
+/* linux/arch/arm/plat-s3c64xx/clock.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX Base clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-clock.h>
+#include <mach/pll.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * ext_xtal_mux for want of an actual name from the manual.
+*/
+
+static struct clk clk_ext_xtal_mux = {
+ .name = "ext_xtal",
+ .id = -1,
+};
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+
+#define clk_fout_mpll clk_mpll
+#define clk_fout_epll clk_epll
+
+struct clk clk_h2 = {
+ .name = "hclk2",
+ .id = -1,
+ .rate = 0,
+};
+
+struct clk clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+ .rate = 27000000,
+};
+
+static int clk_48m_ctrl(struct clk *clk, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ /* can't rely on clock lock, this register has other usages */
+ local_irq_save(flags);
+
+ val = __raw_readl(S3C64XX_OTHERS);
+ if (enable)
+ val |= S3C64XX_OTHERS_USBMASK;
+ else
+ val &= ~S3C64XX_OTHERS_USBMASK;
+
+ __raw_writel(val, S3C64XX_OTHERS);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+struct clk clk_48m = {
+ .name = "clk_48m",
+ .id = -1,
+ .rate = 48000000,
+ .enable = clk_48m_ctrl,
+};
+
+struct clk clk_xusbxti = {
+ .name = "xusbxti",
+ .id = -1,
+ .rate = 48000000,
+};
+
+static int inline s3c64xx_gate(void __iomem *reg,
+ struct clk *clk,
+ int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ u32 con;
+
+ con = __raw_readl(reg);
+
+ if (enable)
+ con |= ctrlbit;
+ else
+ con &= ~ctrlbit;
+
+ __raw_writel(con, reg);
+ return 0;
+}
+
+static int s3c64xx_pclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_PCLK_GATE, clk, enable);
+}
+
+static int s3c64xx_hclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_HCLK_GATE, clk, enable);
+}
+
+int s3c64xx_sclk_ctrl(struct clk *clk, int enable)
+{
+ return s3c64xx_gate(S3C_SCLK_GATE, clk, enable);
+}
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_RTC,
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_TSADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIC,
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C6410_CLKCON_PCLK_I2C1,
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIS0,
+ }, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_IIS1,
+ }, {
+#ifdef CONFIG_CPU_S3C6410
+ .name = "iis",
+ .id = -1, /* There's only one IISv4 port */
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C6410_CLKCON_PCLK_IIS2,
+ }, {
+#endif
+ .name = "keypad",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_KEYPAD,
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_SPI0,
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_SPI1,
+ }, {
+ .name = "spi_48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI0_48,
+ }, {
+ .name = "spi_48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI1_48,
+ }, {
+ .name = "48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC0_48,
+ }, {
+ .name = "48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC1_48,
+ }, {
+ .name = "48m",
+ .id = 2,
+ .parent = &clk_48m,
+ .enable = s3c64xx_sclk_ctrl,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC2_48,
+ }, {
+ .name = "dma0",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_DMA0,
+ }, {
+ .name = "dma1",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_DMA1,
+ },
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_LCD,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_UHOST,
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC0,
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC1,
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_HSMMC2,
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_USB,
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_PWM,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART2,
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p,
+ .enable = s3c64xx_pclk_ctrl,
+ .ctrlbit = S3C_CLKCON_PCLK_UART3,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C_CLKCON_PCLK_WDT,
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C_CLKCON_PCLK_AC97,
+ }, {
+ .name = "cfcon",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_IHOST,
+ }
+};
+
+
+static struct clk clk_fout_apll = {
+ .name = "fout_apll",
+ .id = -1,
+};
+
+static struct clk *clk_src_apll_list[] = {
+ [0] = &clk_fin_apll,
+ [1] = &clk_fout_apll,
+};
+
+static struct clksrc_sources clk_src_apll = {
+ .sources = clk_src_apll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_apll_list),
+};
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 },
+ .sources = &clk_src_apll,
+};
+
+static struct clk *clk_src_epll_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_fout_epll,
+};
+
+static struct clksrc_sources clk_src_epll = {
+ .sources = clk_src_epll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_epll_list),
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 },
+ .sources = &clk_src_epll,
+};
+
+static struct clk *clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &clk_fout_mpll,
+};
+
+static struct clksrc_sources clk_src_mpll = {
+ .sources = clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 },
+ .sources = &clk_src_mpll,
+};
+
+static unsigned int armclk_mask;
+
+static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv;
+
+ /* divisor mask starts at bit0, so no need to shift */
+ clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask;
+
+ return rate / (clkdiv + 1);
+}
+
+static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ u32 div;
+
+ if (parent < rate)
+ return parent;
+
+ div = (parent / rate) - 1;
+ if (div > armclk_mask)
+ div = armclk_mask;
+
+ return parent / (div + 1);
+}
+
+static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long parent = clk_get_rate(clk->parent);
+ u32 div;
+ u32 val;
+
+ if (rate < parent / (armclk_mask + 1))
+ return -EINVAL;
+
+ rate = clk_round_rate(clk, rate);
+ div = clk_get_rate(clk->parent) / rate;
+
+ val = __raw_readl(S3C_CLK_DIV0);
+ val &= ~armclk_mask;
+ val |= (div - 1);
+ __raw_writel(val, S3C_CLK_DIV0);
+
+ return 0;
+
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c64xx_clk_arm_get_rate,
+ .set_rate = s3c64xx_clk_arm_set_rate,
+ .round_rate = s3c64xx_clk_arm_round_rate,
+ },
+};
+
+static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+
+ printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
+
+ if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK)
+ rate /= 2;
+
+ return rate;
+}
+
+static struct clk_ops clk_dout_ops = {
+ .get_rate = s3c64xx_clk_doutmpll_get_rate,
+};
+
+static struct clk clk_dout_mpll = {
+ .name = "dout_mpll",
+ .id = -1,
+ .parent = &clk_mout_mpll.clk,
+ .ops = &clk_dout_ops,
+};
+
+static struct clk *clkset_spi_mmc_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ &clk_fin_epll,
+ &clk_27m,
+};
+
+static struct clksrc_sources clkset_spi_mmc = {
+ .sources = clkset_spi_mmc_list,
+ .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list),
+};
+
+static struct clk *clkset_irda_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ NULL,
+ &clk_27m,
+};
+
+static struct clksrc_sources clkset_irda = {
+ .sources = clkset_irda_list,
+ .nr_sources = ARRAY_SIZE(clkset_irda_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ NULL,
+ NULL
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_uhost_list[] = {
+ &clk_48m,
+ &clk_mout_epll.clk,
+ &clk_dout_mpll,
+ &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_uhost = {
+ .sources = clkset_uhost_list,
+ .nr_sources = ARRAY_SIZE(clkset_uhost_list),
+};
+
+/* The peripheral clocks are all controlled via clocksource followed
+ * by an optional divider and gate stage. We currently roll this into
+ * one clock which hides the intermediate clock from the mux.
+ *
+ * Note, the JPEG clock can only be an even divider...
+ *
+ * The scaler and LCD clocks depend on the S3C64XX version, and also
+ * have a common parent divisor so are not included here.
+ */
+
+/* clocks that feed other parts of the clock source tree */
+
+static struct clk clk_iis_cd0 = {
+ .name = "iis_cdclk0",
+ .id = -1,
+};
+
+static struct clk clk_iis_cd1 = {
+ .name = "iis_cdclk1",
+ .id = -1,
+};
+
+static struct clk clk_iisv4_cd = {
+ .name = "iis_cdclk_v4",
+ .id = -1,
+};
+
+static struct clk clk_pcm_cd = {
+ .name = "pcm_cdclk",
+ .id = -1,
+};
+
+static struct clk *clkset_audio0_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_dout_mpll,
+ [2] = &clk_fin_epll,
+ [3] = &clk_iis_cd0,
+ [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio0 = {
+ .sources = clkset_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio0_list),
+};
+
+static struct clk *clkset_audio1_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_dout_mpll,
+ [2] = &clk_fin_epll,
+ [3] = &clk_iis_cd1,
+ [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio1 = {
+ .sources = clkset_audio1_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio1_list),
+};
+
+static struct clk *clkset_audio2_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_dout_mpll,
+ [2] = &clk_fin_epll,
+ [3] = &clk_iisv4_cd,
+ [4] = &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio2 = {
+ .sources = clkset_audio2_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio2_list),
+};
+
+static struct clk *clkset_camif_list[] = {
+ &clk_h2,
+};
+
+static struct clksrc_sources clkset_camif = {
+ .sources = clkset_camif_list,
+ .nr_sources = ARRAY_SIZE(clkset_camif_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "mmc_bus",
+ .id = 2,
+ .ctrlbit = S3C_CLKCON_SCLK_MMC2,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "usb-bus-host",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_UHOST,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 },
+ .sources = &clkset_uhost,
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_UART,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
+ .sources = &clkset_uart,
+ }, {
+/* Where does UCLK0 come from? */
+ .clk = {
+ .name = "spi-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "spi-bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_SPI1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 },
+ .sources = &clkset_spi_mmc,
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_AUDIO0,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 },
+ .sources = &clkset_audio0,
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 1,
+ .ctrlbit = S3C_CLKCON_SCLK_AUDIO1,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 },
+ .sources = &clkset_audio1,
+ }, {
+ .clk = {
+ .name = "audio-bus",
+ .id = 2,
+ .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 },
+ .sources = &clkset_audio2,
+ }, {
+ .clk = {
+ .name = "irda-bus",
+ .id = 0,
+ .ctrlbit = S3C_CLKCON_SCLK_IRDA,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 },
+ .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 },
+ .sources = &clkset_irda,
+ }, {
+ .clk = {
+ .name = "camera",
+ .id = -1,
+ .ctrlbit = S3C_CLKCON_SCLK_CAM,
+ .enable = s3c64xx_sclk_ctrl,
+ },
+ .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 },
+ .reg_src = { .reg = NULL, .shift = 0, .size = 0 },
+ .sources = &clkset_camif,
+ },
+};
+
+/* Clock initialisation code */
+
+static struct clksrc_clk *init_parents[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+};
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+void __init_or_cpufreq s3c6400_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk2;
+ unsigned long pclk;
+ unsigned long epll;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned int ptr;
+ u32 clkdiv0;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ clkdiv0 = __raw_readl(S3C_CLK_DIV0);
+ printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ /* For now assume the mux always selects the crystal */
+ clk_ext_xtal_mux.parent = xtal_clk;
+
+ epll = s3c6400_get_epll(xtal);
+ mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON));
+ apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON));
+
+ fclk = mpll;
+
+ printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n",
+ apll, mpll, epll);
+
+ hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2);
+ hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK);
+ pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK);
+
+ printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n",
+ hclk2, hclk, pclk);
+
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_apll.rate = apll;
+
+ clk_h2.rate = hclk2;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
+ s3c_set_clksrc(init_parents[ptr], true);
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks1[] __initdata = {
+ &clk_ext_xtal_mux,
+ &clk_iis_cd0,
+ &clk_iis_cd1,
+ &clk_iisv4_cd,
+ &clk_pcm_cd,
+ &clk_mout_epll.clk,
+ &clk_mout_mpll.clk,
+ &clk_dout_mpll,
+ &clk_arm,
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_epll,
+ &clk_27m,
+ &clk_48m,
+ &clk_h2,
+ &clk_xusbxti,
+};
+
+/**
+ * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410
+ * @xtal: The rate for the clock crystal feeding the PLLs.
+ * @armclk_divlimit: Divisor mask for ARMCLK.
+ *
+ * Register the clocks for the S3C6400 and S3C6410 SoC range, such
+ * as ARMCLK as well as the necessary parent clocks.
+ *
+ * This call does not setup the clocks, which is left to the
+ * s3c6400_setup_clocks() call which may be needed by the cpufreq
+ * or resume code to re-set the clocks if the bootloader has changed
+ * them.
+ */
+void __init s3c64xx_register_clocks(unsigned long xtal,
+ unsigned armclk_divlimit)
+{
+ armclk_mask = armclk_divlimit;
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ 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));
+
+ s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_pwmclk_init();
+}
diff --git a/arch/arm/mach-s3c64xx/cpu.c b/arch/arm/mach-s3c64xx/cpu.c
new file mode 100644
index 00000000..374e45e5
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpu.c
@@ -0,0 +1,167 @@
+/* linux/arch/arm/plat-s3c64xx/cpu.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX 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/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+/* table of supported CPUs */
+
+static const char name_s3c6400[] = "S3C6400";
+static const char name_s3c6410[] = "S3C6410";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x36400000,
+ .idmask = 0xfffff000,
+ .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,
+ .map_io = s3c6410_map_io,
+ .init_clocks = s3c6410_init_clocks,
+ .init_uarts = s3c6410_init_uarts,
+ .init = s3c6410_init,
+ .name = name_s3c6410,
+ },
+};
+
+/* minimal IO mapping */
+
+/* see notes on uart map in arch/arm/mach-s3c6400/include/mach/debug-macro.S */
+#define UART_OFFS (S3C_PA_UART & 0xfffff)
+
+static struct map_desc s3c_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SYSCON),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_MEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_SROM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)(S3C_VA_UART + UART_OFFS),
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S3C64XX_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S3C_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_GPIO,
+ .pfn = __phys_to_pfn(S3C64XX_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C64XX_VA_MODEM,
+ .pfn = __phys_to_pfn(S3C64XX_PA_MODEM),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(S3C64XX_PA_WATCHDOG),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn = __phys_to_pfn(S3C64XX_PA_USB_HSPHY),
+ .length = SZ_1K,
+ .type = MT_DEVICE,
+ },
+};
+
+
+struct sysdev_class s3c64xx_sysclass = {
+ .name = "s3c64xx-core",
+};
+
+static struct sys_device s3c64xx_sysdev = {
+ .cls = &s3c64xx_sysclass,
+};
+
+/* uart registration process */
+
+void __init s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s3c64xx_uart_resources, cfg, no);
+}
+
+/* read cpu identification code */
+
+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);
+ }
+
+ s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
+
+static __init int s3c64xx_sysdev_init(void)
+{
+ sysdev_class_register(&s3c64xx_sysclass);
+ return sysdev_register(&s3c64xx_sysdev);
+}
+
+core_initcall(s3c64xx_sysdev_init);
diff --git a/arch/arm/mach-s3c64xx/cpufreq.c b/arch/arm/mach-s3c64xx/cpufreq.c
new file mode 100644
index 00000000..4375b975
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/cpufreq.c
@@ -0,0 +1,270 @@
+/* linux/arch/arm/plat-s3c64xx/cpufreq.c
+ *
+ * Copyright 2009 Wolfson Microelectronics plc
+ *
+ * S3C64xx 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+
+static struct clk *armclk;
+static struct regulator *vddarm;
+static unsigned long regulator_latency;
+
+#ifdef CONFIG_CPU_S3C6410
+struct s3c64xx_dvfs {
+ unsigned int vddarm_min;
+ unsigned int vddarm_max;
+};
+
+static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
+ [0] = { 1000000, 1150000 },
+ [1] = { 1050000, 1150000 },
+ [2] = { 1100000, 1150000 },
+ [3] = { 1200000, 1350000 },
+};
+
+static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
+ { 0, 66000 },
+ { 0, 133000 },
+ { 1, 222000 },
+ { 1, 266000 },
+ { 2, 333000 },
+ { 2, 400000 },
+ { 2, 532000 },
+ { 2, 533000 },
+ { 3, 667000 },
+ { 0, CPUFREQ_TABLE_END },
+};
+#endif
+
+static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
+}
+
+static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
+{
+ if (cpu != 0)
+ return 0;
+
+ return clk_get_rate(armclk) / 1000;
+}
+
+static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ int ret;
+ unsigned int i;
+ struct cpufreq_freqs freqs;
+ struct s3c64xx_dvfs *dvfs;
+
+ ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
+ target_freq, relation, &i);
+ if (ret != 0)
+ return ret;
+
+ freqs.cpu = 0;
+ freqs.old = clk_get_rate(armclk) / 1000;
+ freqs.new = s3c64xx_freq_table[i].frequency;
+ freqs.flags = 0;
+ dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].index];
+
+ if (freqs.old == freqs.new)
+ return 0;
+
+ pr_debug("cpufreq: Transition %d-%dkHz\n", freqs.old, freqs.new);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_REGULATOR
+ if (vddarm && freqs.new > freqs.old) {
+ ret = regulator_set_voltage(vddarm,
+ dvfs->vddarm_min,
+ dvfs->vddarm_max);
+ if (ret != 0) {
+ pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+ freqs.new, ret);
+ goto err;
+ }
+ }
+#endif
+
+ ret = clk_set_rate(armclk, freqs.new * 1000);
+ if (ret < 0) {
+ pr_err("cpufreq: Failed to set rate %dkHz: %d\n",
+ freqs.new, ret);
+ goto err;
+ }
+
+#ifdef CONFIG_REGULATOR
+ if (vddarm && freqs.new < freqs.old) {
+ ret = regulator_set_voltage(vddarm,
+ dvfs->vddarm_min,
+ dvfs->vddarm_max);
+ if (ret != 0) {
+ pr_err("cpufreq: Failed to set VDDARM for %dkHz: %d\n",
+ freqs.new, ret);
+ goto err_clk;
+ }
+ }
+#endif
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ pr_debug("cpufreq: Set actual frequency %lukHz\n",
+ clk_get_rate(armclk) / 1000);
+
+ return 0;
+
+err_clk:
+ if (clk_set_rate(armclk, freqs.old * 1000) < 0)
+ pr_err("Failed to restore original clock rate\n");
+err:
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+#ifdef CONFIG_REGULATOR
+static void __init s3c64xx_cpufreq_config_regulator(void)
+{
+ int count, v, i, found;
+ struct cpufreq_frequency_table *freq;
+ struct s3c64xx_dvfs *dvfs;
+
+ count = regulator_count_voltages(vddarm);
+ if (count < 0) {
+ pr_err("cpufreq: Unable to check supported voltages\n");
+ }
+
+ freq = s3c64xx_freq_table;
+ while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
+ if (freq->frequency == CPUFREQ_ENTRY_INVALID)
+ continue;
+
+ dvfs = &s3c64xx_dvfs_table[freq->index];
+ found = 0;
+
+ for (i = 0; i < count; i++) {
+ v = regulator_list_voltage(vddarm, i);
+ if (v >= dvfs->vddarm_min && v <= dvfs->vddarm_max)
+ found = 1;
+ }
+
+ if (!found) {
+ pr_debug("cpufreq: %dkHz unsupported by regulator\n",
+ freq->frequency);
+ freq->frequency = CPUFREQ_ENTRY_INVALID;
+ }
+
+ freq++;
+ }
+
+ /* Guess based on having to do an I2C/SPI write; in future we
+ * will be able to query the regulator performance here. */
+ regulator_latency = 1 * 1000 * 1000;
+}
+#endif
+
+static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ struct cpufreq_frequency_table *freq;
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ if (s3c64xx_freq_table == NULL) {
+ pr_err("cpufreq: No frequency information for this CPU\n");
+ return -ENODEV;
+ }
+
+ armclk = clk_get(NULL, "armclk");
+ if (IS_ERR(armclk)) {
+ pr_err("cpufreq: Unable to obtain ARMCLK: %ld\n",
+ PTR_ERR(armclk));
+ return PTR_ERR(armclk);
+ }
+
+#ifdef CONFIG_REGULATOR
+ vddarm = regulator_get(NULL, "vddarm");
+ if (IS_ERR(vddarm)) {
+ ret = PTR_ERR(vddarm);
+ pr_err("cpufreq: Failed to obtain VDDARM: %d\n", ret);
+ pr_err("cpufreq: Only frequency scaling available\n");
+ vddarm = NULL;
+ } else {
+ s3c64xx_cpufreq_config_regulator();
+ }
+#endif
+
+ freq = s3c64xx_freq_table;
+ while (freq->frequency != CPUFREQ_TABLE_END) {
+ unsigned long r;
+
+ /* Check for frequencies we can generate */
+ r = clk_round_rate(armclk, freq->frequency * 1000);
+ r /= 1000;
+ if (r != freq->frequency) {
+ pr_debug("cpufreq: %dkHz unsupported by clock\n",
+ freq->frequency);
+ freq->frequency = CPUFREQ_ENTRY_INVALID;
+ }
+
+ /* If we have no regulator then assume startup
+ * frequency is the maximum we can support. */
+ if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0))
+ freq->frequency = CPUFREQ_ENTRY_INVALID;
+
+ freq++;
+ }
+
+ policy->cur = clk_get_rate(armclk) / 1000;
+
+ /* Datasheet says PLL stabalisation time (if we were to use
+ * the PLLs, which we don't currently) is ~300us worst case,
+ * but add some fudge.
+ */
+ policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
+ if (ret != 0) {
+ pr_err("cpufreq: Failed to configure frequency table: %d\n",
+ ret);
+ regulator_put(vddarm);
+ clk_put(armclk);
+ }
+
+ return ret;
+}
+
+static struct cpufreq_driver s3c64xx_cpufreq_driver = {
+ .owner = THIS_MODULE,
+ .flags = 0,
+ .verify = s3c64xx_cpufreq_verify_speed,
+ .target = s3c64xx_cpufreq_set_target,
+ .get = s3c64xx_cpufreq_get_speed,
+ .init = s3c64xx_cpufreq_driver_init,
+ .name = "s3c",
+};
+
+static int __init s3c64xx_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&s3c64xx_cpufreq_driver);
+}
+module_init(s3c64xx_cpufreq_init);
diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c
new file mode 100644
index 00000000..cad67022
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-audio.c
@@ -0,0 +1,317 @@
+/* linux/arch/arm/plat-s3c/dev-audio.c
+ *
+ * Copyright 2009 Wolfson Microelectronics
+ * Mark Brown <broonie@opensource.wolfsonmicro.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/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <mach/dma.h>
+
+#include <plat/devs.h>
+#include <plat/audio.h>
+#include <plat/gpio-cfg.h>
+
+static const char *rclksrc[] = {
+ [0] = "iis",
+ [1] = "audio-bus",
+};
+
+static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S3C64XX_GPD(0);
+ break;
+ case 1:
+ base = S3C64XX_GPE(0);
+ break;
+ case 2:
+ s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
+ return 0;
+ default:
+ printk(KERN_DEBUG "Invalid I2S Controller number: %d\n",
+ pdev->id);
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s3c64xx_iis0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IIS0,
+ .end = S3C64XX_PA_IIS0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_OUT,
+ .end = DMACH_I2S0_OUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_IN,
+ .end = DMACH_I2S0_IN,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+struct platform_device s3c64xx_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
+ .resource = s3c64xx_iis0_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis0);
+
+static struct resource s3c64xx_iis1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IIS1,
+ .end = S3C64XX_PA_IIS1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S1_OUT,
+ .end = DMACH_I2S1_OUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S1_IN,
+ .end = DMACH_I2S1_IN,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s3c64xx_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
+ .resource = s3c64xx_iis1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iis1);
+
+static struct resource s3c64xx_iisv4_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_IISV4,
+ .end = S3C64XX_PA_IISV4 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_HSI_I2SV40_TX,
+ .end = DMACH_HSI_I2SV40_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_HSI_I2SV40_RX,
+ .end = DMACH_HSI_I2SV40_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata i2sv4_pdata = {
+ .cfg_gpio = s3c64xx_i2s_cfg_gpio,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+struct platform_device s3c64xx_device_iisv4 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource),
+ .resource = s3c64xx_iisv4_resource,
+ .dev = {
+ .platform_data = &i2sv4_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_iisv4);
+
+
+/* PCM Controller platform_devices */
+
+static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S3C64XX_GPD(0);
+ break;
+ case 1:
+ base = S3C64XX_GPE(0);
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
+ pdev->id);
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
+ return 0;
+}
+
+static struct resource s3c64xx_pcm0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_PCM0,
+ .end = S3C64XX_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,
+ },
+};
+
+static struct s3c_audio_pdata s3c_pcm0_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm0_resource),
+ .resource = s3c64xx_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm0);
+
+static struct resource s3c64xx_pcm1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_PCM1,
+ .end = S3C64XX_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,
+ },
+};
+
+static struct s3c_audio_pdata s3c_pcm1_pdata = {
+ .cfg_gpio = s3c64xx_pcm_cfg_gpio,
+};
+
+struct platform_device s3c64xx_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_pcm1_resource),
+ .resource = s3c64xx_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_pcm1);
+
+/* AC97 Controller platform devices */
+
+static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
+}
+
+static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource s3c64xx_ac97_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_AC97,
+ .end = S3C64XX_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;
+
+static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource),
+ .resource = s3c64xx_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s3c64xx_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_ac97);
+
+void __init s3c64xx_ac97_setup_gpio(int num)
+{
+ if (num == S3C64XX_AC97_GPD)
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
+ else
+ s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
+}
diff --git a/arch/arm/mach-s3c64xx/dev-onenand1.c b/arch/arm/mach-s3c64xx/dev-onenand1.c
new file mode 100644
index 00000000..92ffd5ba
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-onenand1.c
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/dev-onenand1.c
+ *
+ * Copyright (c) 2008-2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S3C64XX series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s3c64xx_onenand1_resources[] = {
+ [0] = {
+ .start = S3C64XX_PA_ONENAND1,
+ .end = S3C64XX_PA_ONENAND1 + 0x400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C64XX_PA_ONENAND1_BUF,
+ .end = S3C64XX_PA_ONENAND1_BUF + S3C64XX_SZ_ONENAND1_BUF - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_ONENAND1,
+ .end = IRQ_ONENAND1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c64xx_device_onenand1 = {
+ .name = "samsung-onenand",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_onenand1_resources),
+ .resource = s3c64xx_onenand1_resources,
+};
+
+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;
+}
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c
new file mode 100644
index 00000000..5e6b4208
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-spi.c
@@ -0,0 +1,179 @@
+/* linux/arch/arm/plat-s3c64xx/dev-spi.c
+ *
+ * Copyright (C) 2009 Samsung Electronics 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/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/spi-clocks.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+
+static char *spi_src_clks[] = {
+ [S3C64XX_SPI_SRCCLK_PCLK] = "pclk",
+ [S3C64XX_SPI_SRCCLK_SPIBUS] = "spi-bus",
+ [S3C64XX_SPI_SRCCLK_48M] = "spi_48m",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the GPC-3,7.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S3C64XX_GPC(0);
+ break;
+
+ case 1:
+ base = S3C64XX_GPC(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+
+static struct resource s3c64xx_spi0_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_SPI0,
+ .end = S3C64XX_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 s3c64xx_spi0_pdata = {
+ .cfg_gpio = s3c64xx_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .tx_st_done = 21,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c64xx_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource),
+ .resource = s3c64xx_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c64xx_spi0_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_spi0);
+
+static struct resource s3c64xx_spi1_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_SPI1,
+ .end = S3C64XX_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 s3c64xx_spi1_pdata = {
+ .cfg_gpio = s3c64xx_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .tx_st_done = 21,
+};
+
+struct platform_device s3c64xx_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c64xx_spi1_resource),
+ .resource = s3c64xx_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s3c64xx_spi1_pdata,
+ },
+};
+EXPORT_SYMBOL(s3c64xx_device_spi1);
+
+void __init s3c64xx_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 > S3C64XX_SPI_SRCCLK_48M) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ pd = &s3c64xx_spi0_pdata;
+ break;
+ case 1:
+ pd = &s3c64xx_spi1_pdata;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-s3c64xx/dev-uart.c b/arch/arm/mach-s3c64xx/dev-uart.c
new file mode 100644
index 00000000..f797f748
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dev-uart.c
@@ -0,0 +1,147 @@
+/* linux/arch/arm/plat-s3c64xx/dev-uart.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX UART 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/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+/* Serial port registrations */
+
+/* 64xx uarts are closer together */
+
+static struct resource s3c64xx_uart0_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART0,
+ .end = S3C_PA_UART0 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX0,
+ .end = IRQ_S3CUART_RX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX0,
+ .end = IRQ_S3CUART_TX0,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR0,
+ .end = IRQ_S3CUART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c64xx_uart1_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART1,
+ .end = S3C_PA_UART1 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX1,
+ .end = IRQ_S3CUART_RX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX1,
+ .end = IRQ_S3CUART_TX1,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR1,
+ .end = IRQ_S3CUART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s3c6xx_uart2_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART2,
+ .end = S3C_PA_UART2 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX2,
+ .end = IRQ_S3CUART_RX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX2,
+ .end = IRQ_S3CUART_TX2,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR2,
+ .end = IRQ_S3CUART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s3c64xx_uart3_resource[] = {
+ [0] = {
+ .start = S3C_PA_UART3,
+ .end = S3C_PA_UART3 + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX3,
+ .end = IRQ_S3CUART_RX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S3CUART_TX3,
+ .end = IRQ_S3CUART_TX3,
+ .flags = IORESOURCE_IRQ,
+
+ },
+ [3] = {
+ .start = IRQ_S3CUART_ERR3,
+ .end = IRQ_S3CUART_ERR3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+struct s3c24xx_uart_resources s3c64xx_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c64xx_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c64xx_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c6xx_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c6xx_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c64xx_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c64xx_uart3_resource),
+ },
+};
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c
new file mode 100644
index 00000000..204bfafe
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/dma.c
@@ -0,0 +1,752 @@
+/* linux/arch/arm/plat-s3c64xx/dma.c
+ *
+ * Copyright 2009 Openmoko, Inc.
+ * Copyright 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX DMA core
+ *
+ * This program is free software; you can 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/interrupt.h>
+#include <linux/dmapool.h>
+#include <linux/sysdev.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <mach/regs-sys.h>
+
+#include <asm/hardware/pl080.h>
+
+/* dma channel state information */
+
+struct s3c64xx_dmac {
+ struct sys_device sysdev;
+ struct clk *clk;
+ void __iomem *regs;
+ struct s3c2410_dma_chan *channels;
+ enum dma_ch chanbase;
+};
+
+/* pool to provide LLI buffers */
+static struct dma_pool *dma_pool;
+
+/* Debug configuration and code */
+
+static unsigned char debug_show_buffs = 0;
+
+static void dbg_showchan(struct s3c2410_dma_chan *chan)
+{
+ pr_debug("DMA%d: %08x->%08x L %08x C %08x,%08x S %08x\n",
+ chan->number,
+ readl(chan->regs + PL080_CH_SRC_ADDR),
+ readl(chan->regs + PL080_CH_DST_ADDR),
+ readl(chan->regs + PL080_CH_LLI),
+ readl(chan->regs + PL080_CH_CONTROL),
+ readl(chan->regs + PL080S_CH_CONTROL2),
+ readl(chan->regs + PL080S_CH_CONFIG));
+}
+
+static void show_lli(struct pl080s_lli *lli)
+{
+ pr_debug("LLI[%p] %08x->%08x, NL %08x C %08x,%08x\n",
+ lli, lli->src_addr, lli->dst_addr, lli->next_lli,
+ lli->control0, lli->control1);
+}
+
+static void dbg_showbuffs(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dma_buff *ptr;
+ struct s3c64xx_dma_buff *end;
+
+ pr_debug("DMA%d: buffs next %p, curr %p, end %p\n",
+ chan->number, chan->next, chan->curr, chan->end);
+
+ ptr = chan->next;
+ end = chan->end;
+
+ if (debug_show_buffs) {
+ for (; ptr != NULL; ptr = ptr->next) {
+ pr_debug("DMA%d: %08x ",
+ chan->number, ptr->lli_dma);
+ show_lli(ptr->lli);
+ }
+ }
+}
+
+/* End of Debug */
+
+static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned int start, offs;
+
+ start = 0;
+
+ if (channel >= DMACH_PCM1_TX)
+ start = 8;
+
+ for (offs = 0; offs < 8; offs++) {
+ chan = &s3c2410_chans[start + offs];
+ if (!chan->in_use)
+ goto found;
+ }
+
+ return NULL;
+
+found:
+ s3c_dma_chan_map[channel] = chan;
+ return chan;
+}
+
+int s3c2410_dma_config(enum dma_ch channel, int xferunit)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ switch (xferunit) {
+ case 1:
+ chan->hw_width = 0;
+ break;
+ case 2:
+ chan->hw_width = 1;
+ break;
+ case 4:
+ chan->hw_width = 2;
+ break;
+ default:
+ printk(KERN_ERR "%s: illegal width %d\n", __func__, xferunit);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
+ struct pl080s_lli *lli,
+ dma_addr_t data, int size)
+{
+ dma_addr_t src, dst;
+ u32 control0, control1;
+
+ switch (chan->source) {
+ case S3C2410_DMASRC_HW:
+ src = chan->dev_addr;
+ dst = data;
+ control0 = PL080_CONTROL_SRC_AHB2;
+ control0 |= PL080_CONTROL_DST_INCR;
+ break;
+
+ case S3C2410_DMASRC_MEM:
+ src = data;
+ dst = chan->dev_addr;
+ control0 = PL080_CONTROL_DST_AHB2;
+ control0 |= PL080_CONTROL_SRC_INCR;
+ break;
+ default:
+ BUG();
+ }
+
+ /* note, we do not currently setup any of the burst controls */
+
+ control1 = size >> chan->hw_width; /* size in no of xfers */
+ control0 |= PL080_CONTROL_PROT_SYS; /* always in priv. mode */
+ control0 |= PL080_CONTROL_TC_IRQ_EN; /* always fire IRQ */
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_DWIDTH_SHIFT;
+ control0 |= (u32)chan->hw_width << PL080_CONTROL_SWIDTH_SHIFT;
+
+ lli->src_addr = src;
+ lli->dst_addr = dst;
+ lli->next_lli = 0;
+ lli->control0 = control0;
+ lli->control1 = control1;
+}
+
+static void s3c64xx_lli_to_regs(struct s3c2410_dma_chan *chan,
+ struct pl080s_lli *lli)
+{
+ void __iomem *regs = chan->regs;
+
+ pr_debug("%s: LLI %p => regs\n", __func__, lli);
+ show_lli(lli);
+
+ writel(lli->src_addr, regs + PL080_CH_SRC_ADDR);
+ writel(lli->dst_addr, regs + PL080_CH_DST_ADDR);
+ writel(lli->next_lli, regs + PL080_CH_LLI);
+ writel(lli->control0, regs + PL080_CH_CONTROL);
+ writel(lli->control1, regs + PL080S_CH_CONTROL2);
+}
+
+static int s3c64xx_dma_start(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dmac *dmac = chan->dmac;
+ u32 config;
+ u32 bit = chan->bit;
+
+ dbg_showchan(chan);
+
+ pr_debug("%s: clearing interrupts\n", __func__);
+
+ /* clear interrupts */
+ writel(bit, dmac->regs + PL080_TC_CLEAR);
+ writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+ pr_debug("%s: starting channel\n", __func__);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config |= PL080_CONFIG_ENABLE;
+ config &= ~PL080_CONFIG_HALT;
+
+ pr_debug("%s: writing config %08x\n", __func__, config);
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+
+static int s3c64xx_dma_stop(struct s3c2410_dma_chan *chan)
+{
+ u32 config;
+ int timeout;
+
+ pr_debug("%s: stopping channel\n", __func__);
+
+ dbg_showchan(chan);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config |= PL080_CONFIG_HALT;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ timeout = 1000;
+ do {
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ pr_debug("%s: %d - config %08x\n", __func__, timeout, config);
+ if (config & PL080_CONFIG_ACTIVE)
+ udelay(10);
+ else
+ break;
+ } while (--timeout > 0);
+
+ if (config & PL080_CONFIG_ACTIVE) {
+ printk(KERN_ERR "%s: channel still active\n", __func__);
+ return -EFAULT;
+ }
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config &= ~PL080_CONFIG_ENABLE;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+
+static inline void s3c64xx_dma_bufffdone(struct s3c2410_dma_chan *chan,
+ struct s3c64xx_dma_buff *buf,
+ enum s3c2410_dma_buffresult result)
+{
+ if (chan->callback_fn != NULL)
+ (chan->callback_fn)(chan, buf->pw, 0, result);
+}
+
+static void s3c64xx_dma_freebuff(struct s3c64xx_dma_buff *buff)
+{
+ dma_pool_free(dma_pool, buff->lli, buff->lli_dma);
+ kfree(buff);
+}
+
+static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan)
+{
+ struct s3c64xx_dma_buff *buff, *next;
+ u32 config;
+
+ dbg_showchan(chan);
+
+ pr_debug("%s: flushing channel\n", __func__);
+
+ config = readl(chan->regs + PL080S_CH_CONFIG);
+ config &= ~PL080_CONFIG_ENABLE;
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ /* dump all the buffers associated with this channel */
+
+ for (buff = chan->curr; buff != NULL; buff = next) {
+ next = buff->next;
+ pr_debug("%s: buff %p (next %p)\n", __func__, buff, buff->next);
+
+ s3c64xx_dma_bufffdone(chan, buff, S3C2410_RES_ABORT);
+ s3c64xx_dma_freebuff(buff);
+ }
+
+ chan->curr = chan->next = chan->end = NULL;
+
+ return 0;
+}
+
+int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ return s3c64xx_dma_start(chan);
+
+ case S3C2410_DMAOP_STOP:
+ return s3c64xx_dma_stop(chan);
+
+ case S3C2410_DMAOP_FLUSH:
+ return s3c64xx_dma_flush(chan);
+
+ /* believe PAUSE/RESUME are no-ops */
+ case S3C2410_DMAOP_PAUSE:
+ case S3C2410_DMAOP_RESUME:
+ case S3C2410_DMAOP_STARTED:
+ case S3C2410_DMAOP_TIMEOUT:
+ return 0;
+ }
+
+ return -ENOENT;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* s3c2410_dma_enque
+ *
+ */
+
+int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
+ dma_addr_t data, int size)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ struct s3c64xx_dma_buff *next;
+ struct s3c64xx_dma_buff *buff;
+ struct pl080s_lli *lli;
+ unsigned long flags;
+ int ret;
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ buff = kzalloc(sizeof(struct s3c64xx_dma_buff), GFP_ATOMIC);
+ if (!buff) {
+ printk(KERN_ERR "%s: no memory for buffer\n", __func__);
+ return -ENOMEM;
+ }
+
+ lli = dma_pool_alloc(dma_pool, GFP_ATOMIC, &buff->lli_dma);
+ if (!lli) {
+ printk(KERN_ERR "%s: no memory for lli\n", __func__);
+ ret = -ENOMEM;
+ goto err_buff;
+ }
+
+ pr_debug("%s: buff %p, dp %08x lli (%p, %08x) %d\n",
+ __func__, buff, data, lli, (u32)buff->lli_dma, size);
+
+ buff->lli = lli;
+ buff->pw = id;
+
+ s3c64xx_dma_fill_lli(chan, lli, data, size);
+
+ local_irq_save(flags);
+
+ if ((next = chan->next) != NULL) {
+ struct s3c64xx_dma_buff *end = chan->end;
+ struct pl080s_lli *endlli = end->lli;
+
+ pr_debug("enquing onto channel\n");
+
+ end->next = buff;
+ endlli->next_lli = buff->lli_dma;
+
+ if (chan->flags & S3C2410_DMAF_CIRCULAR) {
+ struct s3c64xx_dma_buff *curr = chan->curr;
+ lli->next_lli = curr->lli_dma;
+ }
+
+ if (next == chan->curr) {
+ writel(buff->lli_dma, chan->regs + PL080_CH_LLI);
+ chan->next = buff;
+ }
+
+ show_lli(endlli);
+ chan->end = buff;
+ } else {
+ pr_debug("enquing onto empty channel\n");
+
+ chan->curr = buff;
+ chan->next = buff;
+ chan->end = buff;
+
+ s3c64xx_lli_to_regs(chan, lli);
+ }
+
+ local_irq_restore(flags);
+
+ show_lli(lli);
+
+ dbg_showchan(chan);
+ dbg_showbuffs(chan);
+ return 0;
+
+err_buff:
+ kfree(buff);
+ return ret;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+
+int s3c2410_dma_devconfig(enum dma_ch channel,
+ enum s3c2410_dmasrc source,
+ unsigned long devaddr)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ u32 peripheral;
+ u32 config = 0;
+
+ pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n",
+ __func__, channel, source, devaddr, chan);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ peripheral = (chan->peripheral & 0xf);
+ chan->source = source;
+ chan->dev_addr = devaddr;
+
+ pr_debug("%s: peripheral %d\n", __func__, peripheral);
+
+ switch (source) {
+ case S3C2410_DMASRC_HW:
+ config = 2 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ config |= peripheral << PL080_CONFIG_SRC_SEL_SHIFT;
+ break;
+ case S3C2410_DMASRC_MEM:
+ config = 1 << PL080_CONFIG_FLOW_CONTROL_SHIFT;
+ config |= peripheral << PL080_CONFIG_DST_SEL_SHIFT;
+ break;
+ default:
+ printk(KERN_ERR "%s: bad source\n", __func__);
+ return -EINVAL;
+ }
+
+ /* allow TC and ERR interrupts */
+ config |= PL080_CONFIG_TC_IRQ_MASK;
+ config |= PL080_CONFIG_ERR_IRQ_MASK;
+
+ pr_debug("%s: config %08x\n", __func__, config);
+
+ writel(config, chan->regs + PL080S_CH_CONFIG);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+
+int s3c2410_dma_getposition(enum dma_ch channel,
+ dma_addr_t *src, dma_addr_t *dst)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ WARN_ON(!chan);
+ if (!chan)
+ return -EINVAL;
+
+ if (src != NULL)
+ *src = readl(chan->regs + PL080_CH_SRC_ADDR);
+
+ if (dst != NULL)
+ *dst = readl(chan->regs + PL080_CH_DST_ADDR);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(enum dma_ch channel,
+ struct s3c2410_dma_client *client,
+ void *dev)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned long flags;
+
+ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+ channel, client->name, dev);
+
+ local_irq_save(flags);
+
+ chan = s3c64xx_dma_map_channel(channel);
+ if (chan == NULL) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+
+ dbg_showchan(chan);
+
+ chan->client = client;
+ chan->in_use = 1;
+ chan->peripheral = channel;
+
+ local_irq_restore(flags);
+
+ /* need to setup */
+
+ pr_debug("%s: channel initialised, %p\n", __func__, chan);
+
+ return chan->number | DMACH_LOW_LEVEL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (chan->client != client) {
+ printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+ channel, chan->client, client);
+ }
+
+ /* sort out stopping and freeing the channel */
+
+
+ chan->client = NULL;
+ chan->in_use = 0;
+
+ if (!(channel & DMACH_LOW_LEVEL))
+ s3c_dma_chan_map[channel] = NULL;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
+{
+ struct s3c64xx_dmac *dmac = pw;
+ struct s3c2410_dma_chan *chan;
+ enum s3c2410_dma_buffresult res;
+ u32 tcstat, errstat;
+ u32 bit;
+ int offs;
+
+ tcstat = readl(dmac->regs + PL080_TC_STATUS);
+ errstat = readl(dmac->regs + PL080_ERR_STATUS);
+
+ for (offs = 0, bit = 1; offs < 8; offs++, bit <<= 1) {
+ struct s3c64xx_dma_buff *buff;
+
+ if (!(errstat & bit) && !(tcstat & bit))
+ continue;
+
+ chan = dmac->channels + offs;
+ res = S3C2410_RES_ERR;
+
+ if (tcstat & bit) {
+ writel(bit, dmac->regs + PL080_TC_CLEAR);
+ res = S3C2410_RES_OK;
+ }
+
+ if (errstat & bit)
+ writel(bit, dmac->regs + PL080_ERR_CLEAR);
+
+ /* 'next' points to the buffer that is next to the
+ * currently active buffer.
+ * For CIRCULAR queues, 'next' will be same as 'curr'
+ * when 'end' is the active buffer.
+ */
+ buff = chan->curr;
+ while (buff && buff != chan->next
+ && buff->next != chan->next)
+ buff = buff->next;
+
+ if (!buff)
+ BUG();
+
+ if (buff == chan->next)
+ buff = chan->end;
+
+ s3c64xx_dma_bufffdone(chan, buff, res);
+
+ /* Free the node and update curr, if non-circular queue */
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR)) {
+ chan->curr = buff->next;
+ s3c64xx_dma_freebuff(buff);
+ }
+
+ /* Update 'next' */
+ buff = chan->next;
+ if (chan->next == chan->end) {
+ chan->next = chan->curr;
+ if (!(chan->flags & S3C2410_DMAF_CIRCULAR))
+ chan->end = NULL;
+ } else {
+ chan->next = buff->next;
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct sysdev_class dma_sysclass = {
+ .name = "s3c64xx-dma",
+};
+
+static int s3c64xx_dma_init1(int chno, enum dma_ch chbase,
+ int irq, unsigned int base)
+{
+ struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno];
+ struct s3c64xx_dmac *dmac;
+ char clkname[16];
+ void __iomem *regs;
+ void __iomem *regptr;
+ int err, ch;
+
+ dmac = kzalloc(sizeof(struct s3c64xx_dmac), GFP_KERNEL);
+ if (!dmac) {
+ printk(KERN_ERR "%s: failed to alloc mem\n", __func__);
+ return -ENOMEM;
+ }
+
+ dmac->sysdev.id = chno / 8;
+ dmac->sysdev.cls = &dma_sysclass;
+
+ err = sysdev_register(&dmac->sysdev);
+ if (err) {
+ printk(KERN_ERR "%s: failed to register sysdevice\n", __func__);
+ goto err_alloc;
+ }
+
+ regs = ioremap(base, 0x200);
+ if (!regs) {
+ printk(KERN_ERR "%s: failed to ioremap()\n", __func__);
+ err = -ENXIO;
+ goto err_dev;
+ }
+
+ snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id);
+
+ dmac->clk = clk_get(NULL, clkname);
+ if (IS_ERR(dmac->clk)) {
+ printk(KERN_ERR "%s: failed to get clock %s\n", __func__, clkname);
+ err = PTR_ERR(dmac->clk);
+ goto err_map;
+ }
+
+ clk_enable(dmac->clk);
+
+ dmac->regs = regs;
+ dmac->chanbase = chbase;
+ dmac->channels = chptr;
+
+ err = request_irq(irq, s3c64xx_dma_irq, 0, "DMA", dmac);
+ if (err < 0) {
+ printk(KERN_ERR "%s: failed to get irq\n", __func__);
+ goto err_clk;
+ }
+
+ regptr = regs + PL080_Cx_BASE(0);
+
+ for (ch = 0; ch < 8; ch++, chptr++) {
+ pr_debug("%s: registering DMA %d (%p)\n",
+ __func__, chno + ch, regptr);
+
+ chptr->bit = 1 << ch;
+ chptr->number = chno + ch;
+ chptr->dmac = dmac;
+ chptr->regs = regptr;
+ regptr += PL080_Cx_STRIDE;
+ }
+
+ /* for the moment, permanently enable the controller */
+ writel(PL080_CONFIG_ENABLE, regs + PL080_CONFIG);
+
+ printk(KERN_INFO "PL080: IRQ %d, at %p, channels %d..%d\n",
+ irq, regs, chno, chno+8);
+
+ return 0;
+
+err_clk:
+ clk_disable(dmac->clk);
+ clk_put(dmac->clk);
+err_map:
+ iounmap(regs);
+err_dev:
+ sysdev_unregister(&dmac->sysdev);
+err_alloc:
+ kfree(dmac);
+ return err;
+}
+
+static int __init s3c64xx_dma_init(void)
+{
+ int ret;
+
+ printk(KERN_INFO "%s: Registering DMA channels\n", __func__);
+
+ dma_pool = dma_pool_create("DMA-LLI", NULL, sizeof(struct pl080s_lli), 16, 0);
+ if (!dma_pool) {
+ printk(KERN_ERR "%s: failed to create pool\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = sysdev_class_register(&dma_sysclass);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to create sysclass\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Set all DMA configuration to be DMA, not SDMA */
+ writel(0xffffff, S3C_SYSREG(0x110));
+
+ /* Register standard DMA controllers */
+ s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000);
+ s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000);
+
+ return 0;
+}
+
+arch_initcall(s3c64xx_dma_init);
diff --git a/arch/arm/mach-s3c64xx/gpiolib.c b/arch/arm/mach-s3c64xx/gpiolib.c
new file mode 100644
index 00000000..92b09085
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/gpiolib.c
@@ -0,0 +1,290 @@
+/* arch/arm/plat-s3c64xx/gpiolib.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/regs-gpio.h>
+
+/* GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 8 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * D 5 4Bit Yes 3
+ * E 5 4Bit Yes None
+ * F 16 2Bit Yes 4 [1]
+ * G 7 4Bit Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * K 16 4Bit[2] No None
+ * L 15 4Bit[2] No None
+ * M 6 4Bit No IRQ_EINT
+ * N 16 2Bit No IRQ_EINT
+ * O 16 2Bit Yes 7
+ * P 15 2Bit Yes 8
+ * Q 9 2Bit Yes 9
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_noint = {
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0111 = {
+ .cfg_eint = 7,
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_4bit_cfg_eint0011 = {
+ .cfg_eint = 3,
+ .get_config = s3c_gpio_getcfg_s3c64xx_4bit,
+ .set_config = s3c_gpio_setcfg_s3c64xx_4bit,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static int s3c64xx_gpio2int_gpm(struct gpio_chip *chip, unsigned pin)
+{
+ return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit[] = {
+ {
+ .base = S3C64XX_GPA_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPA(0),
+ .ngpio = S3C64XX_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S3C64XX_GPB_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPB(0),
+ .ngpio = S3C64XX_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S3C64XX_GPC_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPC(0),
+ .ngpio = S3C64XX_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S3C64XX_GPD_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPD(0),
+ .ngpio = S3C64XX_GPIO_D_NR,
+ .label = "GPD",
+ },
+ }, {
+ .base = S3C64XX_GPE_BASE,
+ .config = &gpio_4bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPE(0),
+ .ngpio = S3C64XX_GPIO_E_NR,
+ .label = "GPE",
+ },
+ }, {
+ .base = S3C64XX_GPG_BASE,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPG(0),
+ .ngpio = S3C64XX_GPIO_G_NR,
+ .label = "GPG",
+ },
+ }, {
+ .base = S3C64XX_GPM_BASE,
+ .config = &gpio_4bit_cfg_eint0011,
+ .chip = {
+ .base = S3C64XX_GPM(0),
+ .ngpio = S3C64XX_GPIO_M_NR,
+ .label = "GPM",
+ .to_irq = s3c64xx_gpio2int_gpm,
+ },
+ },
+};
+
+static int s3c64xx_gpio2int_gpl(struct gpio_chip *chip, unsigned pin)
+{
+ return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
+}
+
+static struct s3c_gpio_chip gpio_4bit2[] = {
+ {
+ .base = S3C64XX_GPH_BASE + 0x4,
+ .config = &gpio_4bit_cfg_eint0111,
+ .chip = {
+ .base = S3C64XX_GPH(0),
+ .ngpio = S3C64XX_GPIO_H_NR,
+ .label = "GPH",
+ },
+ }, {
+ .base = S3C64XX_GPK_BASE + 0x4,
+ .config = &gpio_4bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPK(0),
+ .ngpio = S3C64XX_GPIO_K_NR,
+ .label = "GPK",
+ },
+ }, {
+ .base = S3C64XX_GPL_BASE + 0x4,
+ .config = &gpio_4bit_cfg_eint0011,
+ .chip = {
+ .base = S3C64XX_GPL(0),
+ .ngpio = S3C64XX_GPIO_L_NR,
+ .label = "GPL",
+ .to_irq = s3c64xx_gpio2int_gpl,
+ },
+ },
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_noint = {
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint10 = {
+ .cfg_eint = 2,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_2bit_cfg_eint11 = {
+ .cfg_eint = 3,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ .set_pull = s3c_gpio_setpull_updown,
+ .get_pull = s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_chip gpio_2bit[] = {
+ {
+ .base = S3C64XX_GPF_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPF(0),
+ .ngpio = S3C64XX_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S3C64XX_GPI_BASE,
+ .config = &gpio_2bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPI(0),
+ .ngpio = S3C64XX_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S3C64XX_GPJ_BASE,
+ .config = &gpio_2bit_cfg_noint,
+ .chip = {
+ .base = S3C64XX_GPJ(0),
+ .ngpio = S3C64XX_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S3C64XX_GPN_BASE,
+ .irq_base = IRQ_EINT(0),
+ .config = &gpio_2bit_cfg_eint10,
+ .chip = {
+ .base = S3C64XX_GPN(0),
+ .ngpio = S3C64XX_GPIO_N_NR,
+ .label = "GPN",
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = S3C64XX_GPO_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPO(0),
+ .ngpio = S3C64XX_GPIO_O_NR,
+ .label = "GPO",
+ },
+ }, {
+ .base = S3C64XX_GPP_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPP(0),
+ .ngpio = S3C64XX_GPIO_P_NR,
+ .label = "GPP",
+ },
+ }, {
+ .base = S3C64XX_GPQ_BASE,
+ .config = &gpio_2bit_cfg_eint11,
+ .chip = {
+ .base = S3C64XX_GPQ(0),
+ .ngpio = S3C64XX_GPIO_Q_NR,
+ .label = "GPQ",
+ },
+ },
+};
+
+static __init void s3c64xx_gpiolib_add_2bit(struct s3c_gpio_chip *chip)
+{
+ chip->pm = __gpio_pm(&s3c_gpio_pm_2bit);
+}
+
+static __init void s3c64xx_gpiolib_add(struct s3c_gpio_chip *chips,
+ int nr_chips,
+ void (*fn)(struct s3c_gpio_chip *))
+{
+ for (; nr_chips > 0; nr_chips--, chips++) {
+ if (fn)
+ (fn)(chips);
+ s3c_gpiolib_add(chips);
+ }
+}
+
+static __init int s3c64xx_gpiolib_init(void)
+{
+ s3c64xx_gpiolib_add(gpio_4bit, ARRAY_SIZE(gpio_4bit),
+ samsung_gpiolib_add_4bit);
+
+ s3c64xx_gpiolib_add(gpio_4bit2, ARRAY_SIZE(gpio_4bit2),
+ samsung_gpiolib_add_4bit2);
+
+ s3c64xx_gpiolib_add(gpio_2bit, ARRAY_SIZE(gpio_2bit),
+ s3c64xx_gpiolib_add_2bit);
+
+ return 0;
+}
+
+core_initcall(s3c64xx_gpiolib_init);
diff --git a/arch/arm/mach-s3c64xx/include/mach/debug-macro.S b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..a29e7055
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/debug-macro.S
@@ -0,0 +1,38 @@
+/* arch/arm/mach-s3c6400/include/mach/debug-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = (S3C_VA_UART + S3C_PA_UART & 0xfffff)
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
new file mode 100644
index 00000000..0a5d9268
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -0,0 +1,127 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - DMA support
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H __FILE__
+
+#define S3C_DMA_CHANNELS (16)
+
+/* see mach-s3c2410/dma.h for notes on dma channel numbers */
+
+/* Note, for the S3C64XX architecture we keep the DMACH_
+ * defines in the order they are allocated to [S]DMA0/[S]DMA1
+ * so that is easy to do DHACH_ -> DMA controller conversion
+ */
+enum dma_ch {
+ /* DMA0/SDMA0 */
+ DMACH_UART0 = 0,
+ DMACH_UART0_SRC2,
+ DMACH_UART1,
+ DMACH_UART1_SRC2,
+ DMACH_UART2,
+ DMACH_UART2_SRC2,
+ DMACH_UART3,
+ DMACH_UART3_SRC2,
+ DMACH_PCM0_TX,
+ DMACH_PCM0_RX,
+ DMACH_I2S0_OUT,
+ DMACH_I2S0_IN,
+ DMACH_SPI0_TX,
+ DMACH_SPI0_RX,
+ DMACH_HSI_I2SV40_TX,
+ DMACH_HSI_I2SV40_RX,
+
+ /* DMA1/SDMA1 */
+ DMACH_PCM1_TX = 16,
+ DMACH_PCM1_RX,
+ DMACH_I2S1_OUT,
+ DMACH_I2S1_IN,
+ DMACH_SPI1_TX,
+ DMACH_SPI1_RX,
+ DMACH_AC97_PCMOUT,
+ DMACH_AC97_PCMIN,
+ DMACH_AC97_MICIN,
+ DMACH_PWM,
+ DMACH_IRDA,
+ DMACH_EXTERNAL,
+ DMACH_RES1,
+ DMACH_RES2,
+ DMACH_SECURITY_RX, /* SDMA1 only */
+ DMACH_SECURITY_TX, /* SDMA1 only */
+ DMACH_MAX /* the end */
+};
+
+static __inline__ bool s3c_dma_has_circular(void)
+{
+ return true;
+}
+
+#define S3C2410_DMAF_CIRCULAR (1 << 0)
+
+#include <plat/dma.h>
+
+#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
+
+struct s3c64xx_dma_buff;
+
+/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
+ * @next: Pointer to next buffer in queue or ring.
+ * @pw: Client provided identifier
+ * @lli: Pointer to hardware descriptor this buffer is associated with.
+ * @lli_dma: Hardare address of the descriptor.
+ */
+struct s3c64xx_dma_buff {
+ struct s3c64xx_dma_buff *next;
+
+ void *pw;
+ struct pl080s_lli *lli;
+ dma_addr_t lli_dma;
+};
+
+struct s3c64xx_dmac;
+
+struct s3c2410_dma_chan {
+ unsigned char number; /* number of this dma channel */
+ unsigned char in_use; /* channel allocated */
+ unsigned char bit; /* bit for enable/disable/etc */
+ unsigned char hw_width;
+ unsigned char peripheral;
+
+ unsigned int flags;
+ enum s3c2410_dmasrc source;
+
+
+ dma_addr_t dev_addr;
+
+ struct s3c2410_dma_client *client;
+ struct s3c64xx_dmac *dmac; /* pointer to controller */
+
+ void __iomem *regs;
+
+ /* cdriver callbacks */
+ s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
+ s3c2410_dma_opfn_t op_fn; /* channel op callback */
+
+ /* buffer list and information */
+ struct s3c64xx_dma_buff *curr; /* current dma buffer */
+ struct s3c64xx_dma_buff *next; /* next buffer to load */
+ struct s3c64xx_dma_buff *end; /* end of queue */
+
+ /* note, when channel is running in circular mode, curr is the
+ * first buffer enqueued, end is the last and curr is where the
+ * last buffer-done event is set-at. The buffers are not freed
+ * and the last buffer hardware descriptor points back to the
+ * first.
+ */
+};
+
+#include <plat/dma-core.h>
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/entry-macro.S b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..dd362604
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/entry-macro.S
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Low-level IRQ helper macros for the Samsung S3C64XX series
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff --git a/arch/arm/mach-s3c64xx/include/mach/gpio.h b/arch/arm/mach-s3c64xx/include/mach/gpio.h
new file mode 100644
index 00000000..0d46e994
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/gpio.h
@@ -0,0 +1,100 @@
+/* arch/arm/mach-s3c6400/include/mach/gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - 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.
+*/
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* GPIO bank sizes */
+#define S3C64XX_GPIO_A_NR (8)
+#define S3C64XX_GPIO_B_NR (7)
+#define S3C64XX_GPIO_C_NR (8)
+#define S3C64XX_GPIO_D_NR (5)
+#define S3C64XX_GPIO_E_NR (5)
+#define S3C64XX_GPIO_F_NR (16)
+#define S3C64XX_GPIO_G_NR (7)
+#define S3C64XX_GPIO_H_NR (10)
+#define S3C64XX_GPIO_I_NR (16)
+#define S3C64XX_GPIO_J_NR (12)
+#define S3C64XX_GPIO_K_NR (16)
+#define S3C64XX_GPIO_L_NR (15)
+#define S3C64XX_GPIO_M_NR (6)
+#define S3C64XX_GPIO_N_NR (16)
+#define S3C64XX_GPIO_O_NR (16)
+#define S3C64XX_GPIO_P_NR (15)
+#define S3C64XX_GPIO_Q_NR (9)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S3C64XX_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s3c_gpio_number {
+ S3C64XX_GPIO_A_START = 0,
+ S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
+ S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
+ S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
+ S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
+ S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
+ S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
+ S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
+ S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
+ S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
+ S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
+ S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
+ S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
+ S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
+ S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
+ S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
+ S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
+};
+
+/* S3C64XX GPIO number definitions. */
+
+#define S3C64XX_GPA(_nr) (S3C64XX_GPIO_A_START + (_nr))
+#define S3C64XX_GPB(_nr) (S3C64XX_GPIO_B_START + (_nr))
+#define S3C64XX_GPC(_nr) (S3C64XX_GPIO_C_START + (_nr))
+#define S3C64XX_GPD(_nr) (S3C64XX_GPIO_D_START + (_nr))
+#define S3C64XX_GPE(_nr) (S3C64XX_GPIO_E_START + (_nr))
+#define S3C64XX_GPF(_nr) (S3C64XX_GPIO_F_START + (_nr))
+#define S3C64XX_GPG(_nr) (S3C64XX_GPIO_G_START + (_nr))
+#define S3C64XX_GPH(_nr) (S3C64XX_GPIO_H_START + (_nr))
+#define S3C64XX_GPI(_nr) (S3C64XX_GPIO_I_START + (_nr))
+#define S3C64XX_GPJ(_nr) (S3C64XX_GPIO_J_START + (_nr))
+#define S3C64XX_GPK(_nr) (S3C64XX_GPIO_K_START + (_nr))
+#define S3C64XX_GPL(_nr) (S3C64XX_GPIO_L_START + (_nr))
+#define S3C64XX_GPM(_nr) (S3C64XX_GPIO_M_START + (_nr))
+#define S3C64XX_GPN(_nr) (S3C64XX_GPIO_N_START + (_nr))
+#define S3C64XX_GPO(_nr) (S3C64XX_GPIO_O_START + (_nr))
+#define S3C64XX_GPP(_nr) (S3C64XX_GPIO_P_START + (_nr))
+#define S3C64XX_GPQ(_nr) (S3C64XX_GPIO_Q_START + (_nr))
+
+/* the end of the S3C64XX specific gpios */
+#define S3C64XX_GPIO_END (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+#define S3C_GPIO_END S3C64XX_GPIO_END
+
+/* define the number of gpios we need to the one after the GPQ() range */
+#define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
+
+#define BOARD_NR_GPIOS 16
+
+#define ARCH_NR_GPIOS (GPIO_BOARD_START + BOARD_NR_GPIOS)
+
+#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s3c64xx/include/mach/hardware.h b/arch/arm/mach-s3c64xx/include/mach/hardware.h
new file mode 100644
index 00000000..862d033e
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/hardware.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/hardware.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - Hardware support
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/io.h b/arch/arm/mach-s3c64xx/include/mach/io.h
new file mode 100644
index 00000000..de5716db
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s3c64xxinclude/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S3C64XX based
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/irqs.h b/arch/arm/mach-s3c64xx/include/mach/irqs.h
new file mode 100644
index 00000000..8e2df26c
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/irqs.h
@@ -0,0 +1,220 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/irqs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - IRQ support
+ */
+
+#ifndef __ASM_MACH_S3C64XX_IRQS_H
+#define __ASM_MACH_S3C64XX_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S3C_IRQ_OFFSET (32)
+
+#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
+
+#define IRQ_VIC0_BASE S3C_IRQ(0)
+#define IRQ_VIC1_BASE S3C_IRQ(32)
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S3CUART_BASE0 (16)
+#define IRQ_S3CUART_BASE1 (20)
+#define IRQ_S3CUART_BASE2 (24)
+#define IRQ_S3CUART_BASE3 (28)
+
+#define UART_IRQ_RXD (0)
+#define UART_IRQ_ERR (1)
+#define UART_IRQ_TXD (2)
+#define UART_IRQ_MODEM (3)
+
+#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
+
+/* VIC based IRQs */
+
+#define S3C64XX_IRQ_VIC0(x) (IRQ_VIC0_BASE + (x))
+#define S3C64XX_IRQ_VIC1(x) (IRQ_VIC1_BASE + (x))
+
+/* VIC0 */
+
+#define IRQ_EINT0_3 S3C64XX_IRQ_VIC0(0)
+#define IRQ_EINT4_11 S3C64XX_IRQ_VIC0(1)
+#define IRQ_RTC_TIC S3C64XX_IRQ_VIC0(2)
+#define IRQ_CAMIF_C S3C64XX_IRQ_VIC0(3)
+#define IRQ_CAMIF_P S3C64XX_IRQ_VIC0(4)
+#define IRQ_CAMIF_MC S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIC1 S3C64XX_IRQ_VIC0(5)
+#define IRQ_S3C6410_IIS S3C64XX_IRQ_VIC0(6)
+#define IRQ_S3C6400_CAMIF_MP S3C64XX_IRQ_VIC0(6)
+#define IRQ_CAMIF_WE_C S3C64XX_IRQ_VIC0(7)
+#define IRQ_S3C6410_G3D S3C64XX_IRQ_VIC0(8)
+#define IRQ_S3C6400_CAMIF_WE_P S3C64XX_IRQ_VIC0(8)
+#define IRQ_POST0 S3C64XX_IRQ_VIC0(9)
+#define IRQ_ROTATOR S3C64XX_IRQ_VIC0(10)
+#define IRQ_2D S3C64XX_IRQ_VIC0(11)
+#define IRQ_TVENC S3C64XX_IRQ_VIC0(12)
+#define IRQ_SCALER S3C64XX_IRQ_VIC0(13)
+#define IRQ_BATF S3C64XX_IRQ_VIC0(14)
+#define IRQ_JPEG S3C64XX_IRQ_VIC0(15)
+#define IRQ_MFC S3C64XX_IRQ_VIC0(16)
+#define IRQ_SDMA0 S3C64XX_IRQ_VIC0(17)
+#define IRQ_SDMA1 S3C64XX_IRQ_VIC0(18)
+#define IRQ_ARM_DMAERR S3C64XX_IRQ_VIC0(19)
+#define IRQ_ARM_DMA S3C64XX_IRQ_VIC0(20)
+#define IRQ_ARM_DMAS S3C64XX_IRQ_VIC0(21)
+#define IRQ_KEYPAD S3C64XX_IRQ_VIC0(22)
+#define IRQ_TIMER0_VIC S3C64XX_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC S3C64XX_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC S3C64XX_IRQ_VIC0(25)
+#define IRQ_WDT S3C64XX_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC S3C64XX_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC S3C64XX_IRQ_VIC0(28)
+#define IRQ_LCD_FIFO S3C64XX_IRQ_VIC0(29)
+#define IRQ_LCD_VSYNC S3C64XX_IRQ_VIC0(30)
+#define IRQ_LCD_SYSTEM S3C64XX_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_19 S3C64XX_IRQ_VIC1(0)
+#define IRQ_EINT20_27 S3C64XX_IRQ_VIC1(1)
+#define IRQ_PCM0 S3C64XX_IRQ_VIC1(2)
+#define IRQ_PCM1 S3C64XX_IRQ_VIC1(3)
+#define IRQ_AC97 S3C64XX_IRQ_VIC1(4)
+#define IRQ_UART0 S3C64XX_IRQ_VIC1(5)
+#define IRQ_UART1 S3C64XX_IRQ_VIC1(6)
+#define IRQ_UART2 S3C64XX_IRQ_VIC1(7)
+#define IRQ_UART3 S3C64XX_IRQ_VIC1(8)
+#define IRQ_DMA0 S3C64XX_IRQ_VIC1(9)
+#define IRQ_DMA1 S3C64XX_IRQ_VIC1(10)
+#define IRQ_ONENAND0 S3C64XX_IRQ_VIC1(11)
+#define IRQ_ONENAND1 S3C64XX_IRQ_VIC1(12)
+#define IRQ_NFC S3C64XX_IRQ_VIC1(13)
+#define IRQ_CFCON S3C64XX_IRQ_VIC1(14)
+#define IRQ_USBH S3C64XX_IRQ_VIC1(15)
+#define IRQ_SPI0 S3C64XX_IRQ_VIC1(16)
+#define IRQ_SPI1 S3C64XX_IRQ_VIC1(17)
+#define IRQ_IIC S3C64XX_IRQ_VIC1(18)
+#define IRQ_HSItx S3C64XX_IRQ_VIC1(19)
+#define IRQ_HSIrx S3C64XX_IRQ_VIC1(20)
+#define IRQ_RESERVED S3C64XX_IRQ_VIC1(21)
+#define IRQ_MSM S3C64XX_IRQ_VIC1(22)
+#define IRQ_HOSTIF S3C64XX_IRQ_VIC1(23)
+#define IRQ_HSMMC0 S3C64XX_IRQ_VIC1(24)
+#define IRQ_HSMMC1 S3C64XX_IRQ_VIC1(25)
+#define IRQ_HSMMC2 IRQ_SPI1 /* shared with SPI1 */
+#define IRQ_OTG S3C64XX_IRQ_VIC1(26)
+#define IRQ_IRDA S3C64XX_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM S3C64XX_IRQ_VIC1(28)
+#define IRQ_SEC S3C64XX_IRQ_VIC1(29)
+#define IRQ_PENDN S3C64XX_IRQ_VIC1(30)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_ADC S3C64XX_IRQ_VIC1(31)
+
+#define S3C64XX_TIMER_IRQ(x) S3C_IRQ(64 + (x))
+
+#define IRQ_TIMER0 S3C64XX_TIMER_IRQ(0)
+#define IRQ_TIMER1 S3C64XX_TIMER_IRQ(1)
+#define IRQ_TIMER2 S3C64XX_TIMER_IRQ(2)
+#define IRQ_TIMER3 S3C64XX_TIMER_IRQ(3)
+#define IRQ_TIMER4 S3C64XX_TIMER_IRQ(4)
+
+/* compatibility for device defines */
+
+#define IRQ_IIC1 IRQ_S3C6410_IIC1
+
+/* Since the IRQ_EINT(x) are a linear mapping on current s3c64xx series
+ * we just defined them as an IRQ_EINT(x) macro from S3C_IRQ_EINT_BASE
+ * which we place after the pair of VICs. */
+
+#define S3C_IRQ_EINT_BASE S3C_IRQ(64+5)
+
+#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
+#define IRQ_EINT(x) S3C_EINT(x)
+#define IRQ_EINT_BIT(x) ((x) - S3C_EINT(0))
+
+/* Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+#define IRQ_EINT_GROUP1_NR (15)
+#define IRQ_EINT_GROUP2_NR (8)
+#define IRQ_EINT_GROUP3_NR (5)
+#define IRQ_EINT_GROUP4_NR (14)
+#define IRQ_EINT_GROUP5_NR (7)
+#define IRQ_EINT_GROUP6_NR (10)
+#define IRQ_EINT_GROUP7_NR (16)
+#define IRQ_EINT_GROUP8_NR (15)
+#define IRQ_EINT_GROUP9_NR (9)
+
+#define IRQ_EINT_GROUP_BASE S3C_EINT(28)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0x00)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP3_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP4_BASE (IRQ_EINT_GROUP3_BASE + IRQ_EINT_GROUP3_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP4_BASE + IRQ_EINT_GROUP4_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP7_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP7_BASE + IRQ_EINT_GROUP7_NR)
+#define IRQ_EINT_GROUP9_BASE (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR)
+
+#define IRQ_EINT_GROUP(group, no) (IRQ_EINT_GROUP##group##_BASE + (no))
+
+/* Define a group of interrupts for board-specific use (eg, for MFD
+ * interrupt controllers). */
+#define IRQ_BOARD_START (IRQ_EINT_GROUP9_BASE + IRQ_EINT_GROUP9_NR + 1)
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#define IRQ_BOARD_NR 64
+#elif defined(CONFIG_SMDK6410_WM1192_EV1)
+#define IRQ_BOARD_NR 64
+#else
+#define IRQ_BOARD_NR 16
+#endif
+
+#define IRQ_BOARD_END (IRQ_BOARD_START + IRQ_BOARD_NR)
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_BOARD_END + 1)
+
+/* Compatibility */
+
+#define IRQ_ONENAND IRQ_ONENAND0
+
+#endif /* __ASM_MACH_S3C64XX_IRQS_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
new file mode 100644
index 00000000..a1f13f02
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -0,0 +1,130 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/map.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - 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>
+
+/*
+ * Post-mux Chip Select Regions Xm0CSn_
+ * These may be used by SROM, NAND or CF depending on settings
+ */
+
+#define S3C64XX_PA_XM0CSN0 (0x10000000)
+#define S3C64XX_PA_XM0CSN1 (0x18000000)
+#define S3C64XX_PA_XM0CSN2 (0x20000000)
+#define S3C64XX_PA_XM0CSN3 (0x28000000)
+#define S3C64XX_PA_XM0CSN4 (0x30000000)
+#define S3C64XX_PA_XM0CSN5 (0x38000000)
+
+/* HSMMC units */
+#define S3C64XX_PA_HSMMC(x) (0x7C200000 + ((x) * 0x100000))
+#define S3C64XX_PA_HSMMC0 S3C64XX_PA_HSMMC(0)
+#define S3C64XX_PA_HSMMC1 S3C64XX_PA_HSMMC(1)
+#define S3C64XX_PA_HSMMC2 S3C64XX_PA_HSMMC(2)
+
+#define S3C_PA_UART (0x7F005000)
+#define S3C_PA_UART0 (S3C_PA_UART + 0x00)
+#define S3C_PA_UART1 (S3C_PA_UART + 0x400)
+#define S3C_PA_UART2 (S3C_PA_UART + 0x800)
+#define S3C_PA_UART3 (S3C_PA_UART + 0xC00)
+#define S3C_UART_OFFSET (0x400)
+
+/* See notes on UART VA mapping in debug-macro.S */
+#define S3C_VA_UARTx(x) (S3C_VA_UART + (S3C_PA_UART & 0xfffff) + ((x) * S3C_UART_OFFSET))
+
+#define S3C_VA_UART0 S3C_VA_UARTx(0)
+#define S3C_VA_UART1 S3C_VA_UARTx(1)
+#define S3C_VA_UART2 S3C_VA_UARTx(2)
+#define S3C_VA_UART3 S3C_VA_UARTx(3)
+
+#define S3C64XX_PA_SROM (0x70000000)
+
+#define S3C64XX_PA_ONENAND0 (0x70100000)
+#define S3C64XX_PA_ONENAND0_BUF (0x20000000)
+#define S3C64XX_SZ_ONENAND0_BUF (SZ_64M)
+
+/* NAND and OneNAND1 controllers occupy the same register region
+ (depending on SoC POP version) */
+#define S3C64XX_PA_ONENAND1 (0x70200000)
+#define S3C64XX_PA_ONENAND1_BUF (0x28000000)
+#define S3C64XX_SZ_ONENAND1_BUF (SZ_64M)
+
+#define S3C64XX_PA_NAND (0x70200000)
+#define S3C64XX_PA_FB (0x77100000)
+#define S3C64XX_PA_USB_HSOTG (0x7C000000)
+#define S3C64XX_PA_WATCHDOG (0x7E004000)
+#define S3C64XX_PA_RTC (0x7E005000)
+#define S3C64XX_PA_KEYPAD (0x7E00A000)
+#define S3C64XX_PA_ADC (0x7E00B000)
+#define S3C64XX_PA_SYSCON (0x7E00F000)
+#define S3C64XX_PA_AC97 (0x7F001000)
+#define S3C64XX_PA_IIS0 (0x7F002000)
+#define S3C64XX_PA_IIS1 (0x7F003000)
+#define S3C64XX_PA_TIMER (0x7F006000)
+#define S3C64XX_PA_IIC0 (0x7F004000)
+#define S3C64XX_PA_SPI0 (0x7F00B000)
+#define S3C64XX_PA_SPI1 (0x7F00C000)
+#define S3C64XX_PA_PCM0 (0x7F009000)
+#define S3C64XX_PA_PCM1 (0x7F00A000)
+#define S3C64XX_PA_IISV4 (0x7F00D000)
+#define S3C64XX_PA_IIC1 (0x7F00F000)
+
+#define S3C64XX_PA_GPIO (0x7F008000)
+#define S3C64XX_VA_GPIO S3C_ADDR_CPU(0x00000000)
+#define S3C64XX_SZ_GPIO SZ_4K
+
+#define S3C64XX_PA_SDRAM (0x50000000)
+
+#define S3C64XX_PA_CFCON (0x70300000)
+
+#define S3C64XX_PA_VIC0 (0x71200000)
+#define S3C64XX_PA_VIC1 (0x71300000)
+
+#define S3C64XX_PA_MODEM (0x74108000)
+#define S3C64XX_VA_MODEM S3C_ADDR_CPU(0x00100000)
+
+#define S3C64XX_PA_USBHOST (0x74300000)
+
+#define S3C64XX_PA_USB_HSPHY (0x7C100000)
+#define S3C64XX_VA_USB_HSPHY S3C_ADDR_CPU(0x00200000)
+
+/* place VICs close together */
+#define VA_VIC0 (S3C_VA_IRQ + 0x00)
+#define VA_VIC1 (S3C_VA_IRQ + 0x10000)
+
+/* compatibiltiy defines. */
+#define S3C_PA_TIMER S3C64XX_PA_TIMER
+#define S3C_PA_HSMMC0 S3C64XX_PA_HSMMC0
+#define S3C_PA_HSMMC1 S3C64XX_PA_HSMMC1
+#define S3C_PA_HSMMC2 S3C64XX_PA_HSMMC2
+#define S3C_PA_IIC S3C64XX_PA_IIC0
+#define S3C_PA_IIC1 S3C64XX_PA_IIC1
+#define S3C_PA_NAND S3C64XX_PA_NAND
+#define S3C_PA_ONENAND S3C64XX_PA_ONENAND0
+#define S3C_PA_ONENAND_BUF S3C64XX_PA_ONENAND0_BUF
+#define S3C_SZ_ONENAND_BUF S3C64XX_SZ_ONENAND0_BUF
+#define S3C_PA_FB S3C64XX_PA_FB
+#define S3C_PA_USBHOST S3C64XX_PA_USBHOST
+#define S3C_PA_USB_HSOTG S3C64XX_PA_USB_HSOTG
+#define S3C_VA_USB_HSPHY S3C64XX_VA_USB_HSPHY
+#define S3C_PA_RTC S3C64XX_PA_RTC
+#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
+
+#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
+#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
+#define SAMSUNG_PA_KEYPAD S3C64XX_PA_KEYPAD
+
+#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/memory.h b/arch/arm/mach-s3c64xx/include/mach/memory.h
new file mode 100644
index 00000000..4760cdae
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/memory.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c6400/include/mach/memory.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x50000000)
+
+#define CONSISTENT_DMA_SIZE SZ_8M
+
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/pll.h b/arch/arm/mach-s3c64xx/include/mach/pll.h
new file mode 100644
index 00000000..5ef0bb69
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pll.h
@@ -0,0 +1,45 @@
+/* arch/arm/plat-s3c64xx/include/plat/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX PLL code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S3C6400_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
+#define S3C6400_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
+#define S3C6400_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
+#define S3C6400_PLL_MDIV_SHIFT (16)
+#define S3C6400_PLL_PDIV_SHIFT (8)
+#define S3C6400_PLL_SDIV_SHIFT (0)
+
+#include <asm/div64.h>
+#include <plat/pll6553x.h>
+
+static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
+ u32 pllcon)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
+ pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
+ sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+static inline unsigned long s3c6400_get_epll(unsigned long baseclk)
+{
+ return s3c_get_pll6553x(baseclk, __raw_readl(S3C_EPLL_CON0),
+ __raw_readl(S3C_EPLL_CON1));
+}
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
new file mode 100644
index 00000000..1e9f20f0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/regs-gpio.h>
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ u32 tmp = __raw_readl(S3C_PCLK_GATE);
+
+ /* As a note, since the S3C64XX UARTs generally have multiple
+ * clock sources, we simply enable PCLK at the moment and hope
+ * that the resume settings for the UART are suitable for the
+ * use with PCLK.
+ */
+
+ tmp |= S3C_CLKCON_PCLK_UART0;
+ tmp |= S3C_CLKCON_PCLK_UART1;
+ tmp |= S3C_CLKCON_PCLK_UART2;
+ tmp |= S3C_CLKCON_PCLK_UART3;
+
+ __raw_writel(tmp, S3C_PCLK_GATE);
+ udelay(10);
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ /* VIC should have already been taken care of */
+
+ /* clear any pending EINT0 interrupts */
+ __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+}
+
+/* make these defines, we currently do not have any need to change
+ * the IRQ wake controls depending on the CPU we are running on */
+
+#define s3c_irqwake_eintallow ((1 << 28) - 1)
+#define s3c_irqwake_intallow (0)
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ u32 ucon = __raw_readl(regs + S3C2410_UCON);
+ u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK;
+ u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK;
+ u32 new_ucon;
+ u32 delta;
+
+ /* S3C64XX UART blocks only support level interrupts, so ensure that
+ * when we restore unused UART blocks we force the level interrupt
+ * settigs. */
+ save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL;
+
+ /* We have a constraint on changing the clock type of the UART
+ * between UCLKx and PCLK, so ensure that when we restore UCON
+ * that the CLK field is correctly modified if the bootloader
+ * has changed anything.
+ */
+ if (ucon_clk != save_clk) {
+ new_ucon = save->ucon;
+ delta = ucon_clk ^ save_clk;
+
+ /* change from UCLKx => wrong PCLK,
+ * either UCLK can be tested for by a bit-test
+ * with UCLK0 */
+ if (ucon_clk & S3C6400_UCON_UCLK0 &&
+ !(save_clk & S3C6400_UCON_UCLK0) &&
+ delta & S3C6400_UCON_PCLK2) {
+ new_ucon &= ~S3C6400_UCON_UCLK0;
+ } else if (delta == S3C6400_UCON_PCLK2) {
+ /* as an precaution, don't change from
+ * PCLK2 => PCLK or vice-versa */
+ new_ucon ^= S3C6400_UCON_PCLK2;
+ }
+
+ S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n",
+ ucon, new_ucon, save->ucon);
+ save->ucon = new_ucon;
+ }
+}
diff --git a/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h b/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
new file mode 100644
index 00000000..b25bedee
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64xx - pwm clock and timer support
+ */
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
new file mode 100644
index 00000000..05332b99
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -0,0 +1,162 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX 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_CLOCK_H
+#define __PLAT_REGS_CLOCK_H __FILE__
+
+#define S3C_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S3C_APLL_LOCK S3C_CLKREG(0x00)
+#define S3C_MPLL_LOCK S3C_CLKREG(0x04)
+#define S3C_EPLL_LOCK S3C_CLKREG(0x08)
+#define S3C_APLL_CON S3C_CLKREG(0x0C)
+#define S3C_MPLL_CON S3C_CLKREG(0x10)
+#define S3C_EPLL_CON0 S3C_CLKREG(0x14)
+#define S3C_EPLL_CON1 S3C_CLKREG(0x18)
+#define S3C_CLK_SRC S3C_CLKREG(0x1C)
+#define S3C_CLK_DIV0 S3C_CLKREG(0x20)
+#define S3C_CLK_DIV1 S3C_CLKREG(0x24)
+#define S3C_CLK_DIV2 S3C_CLKREG(0x28)
+#define S3C_CLK_OUT S3C_CLKREG(0x2C)
+#define S3C_HCLK_GATE S3C_CLKREG(0x30)
+#define S3C_PCLK_GATE S3C_CLKREG(0x34)
+#define S3C_SCLK_GATE S3C_CLKREG(0x38)
+#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
+#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
+#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
+
+/* CLKDIV0 */
+#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
+#define S3C6400_CLKDIV0_PCLK_SHIFT (12)
+#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9)
+#define S3C6400_CLKDIV0_HCLK2_SHIFT (9)
+#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8)
+#define S3C6400_CLKDIV0_HCLK_SHIFT (8)
+#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4)
+#define S3C6400_CLKDIV0_MPLL_SHIFT (4)
+
+#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0)
+#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0)
+#define S3C6400_CLKDIV0_ARM_SHIFT (0)
+
+/* HCLK GATE Registers */
+#define S3C_CLKCON_HCLK_3DSE (1<<31)
+#define S3C_CLKCON_HCLK_UHOST (1<<29)
+#define S3C_CLKCON_HCLK_SECUR (1<<28)
+#define S3C_CLKCON_HCLK_SDMA1 (1<<27)
+#define S3C_CLKCON_HCLK_SDMA0 (1<<26)
+#define S3C_CLKCON_HCLK_IROM (1<<25)
+#define S3C_CLKCON_HCLK_DDR1 (1<<24)
+#define S3C_CLKCON_HCLK_DDR0 (1<<23)
+#define S3C_CLKCON_HCLK_MEM1 (1<<22)
+#define S3C_CLKCON_HCLK_MEM0 (1<<21)
+#define S3C_CLKCON_HCLK_USB (1<<20)
+#define S3C_CLKCON_HCLK_HSMMC2 (1<<19)
+#define S3C_CLKCON_HCLK_HSMMC1 (1<<18)
+#define S3C_CLKCON_HCLK_HSMMC0 (1<<17)
+#define S3C_CLKCON_HCLK_MDP (1<<16)
+#define S3C_CLKCON_HCLK_DHOST (1<<15)
+#define S3C_CLKCON_HCLK_IHOST (1<<14)
+#define S3C_CLKCON_HCLK_DMA1 (1<<13)
+#define S3C_CLKCON_HCLK_DMA0 (1<<12)
+#define S3C_CLKCON_HCLK_JPEG (1<<11)
+#define S3C_CLKCON_HCLK_CAMIF (1<<10)
+#define S3C_CLKCON_HCLK_SCALER (1<<9)
+#define S3C_CLKCON_HCLK_2D (1<<8)
+#define S3C_CLKCON_HCLK_TV (1<<7)
+#define S3C_CLKCON_HCLK_POST0 (1<<5)
+#define S3C_CLKCON_HCLK_ROT (1<<4)
+#define S3C_CLKCON_HCLK_LCD (1<<3)
+#define S3C_CLKCON_HCLK_TZIC (1<<2)
+#define S3C_CLKCON_HCLK_INTC (1<<1)
+#define S3C_CLKCON_HCLK_MFC (1<<0)
+
+/* PCLK GATE Registers */
+#define S3C6410_CLKCON_PCLK_I2C1 (1<<27)
+#define S3C6410_CLKCON_PCLK_IIS2 (1<<26)
+#define S3C_CLKCON_PCLK_SKEY (1<<24)
+#define S3C_CLKCON_PCLK_CHIPID (1<<23)
+#define S3C_CLKCON_PCLK_SPI1 (1<<22)
+#define S3C_CLKCON_PCLK_SPI0 (1<<21)
+#define S3C_CLKCON_PCLK_HSIRX (1<<20)
+#define S3C_CLKCON_PCLK_HSITX (1<<19)
+#define S3C_CLKCON_PCLK_GPIO (1<<18)
+#define S3C_CLKCON_PCLK_IIC (1<<17)
+#define S3C_CLKCON_PCLK_IIS1 (1<<16)
+#define S3C_CLKCON_PCLK_IIS0 (1<<15)
+#define S3C_CLKCON_PCLK_AC97 (1<<14)
+#define S3C_CLKCON_PCLK_TZPC (1<<13)
+#define S3C_CLKCON_PCLK_TSADC (1<<12)
+#define S3C_CLKCON_PCLK_KEYPAD (1<<11)
+#define S3C_CLKCON_PCLK_IRDA (1<<10)
+#define S3C_CLKCON_PCLK_PCM1 (1<<9)
+#define S3C_CLKCON_PCLK_PCM0 (1<<8)
+#define S3C_CLKCON_PCLK_PWM (1<<7)
+#define S3C_CLKCON_PCLK_RTC (1<<6)
+#define S3C_CLKCON_PCLK_WDT (1<<5)
+#define S3C_CLKCON_PCLK_UART3 (1<<4)
+#define S3C_CLKCON_PCLK_UART2 (1<<3)
+#define S3C_CLKCON_PCLK_UART1 (1<<2)
+#define S3C_CLKCON_PCLK_UART0 (1<<1)
+#define S3C_CLKCON_PCLK_MFC (1<<0)
+
+/* SCLK GATE Registers */
+#define S3C_CLKCON_SCLK_UHOST (1<<30)
+#define S3C_CLKCON_SCLK_MMC2_48 (1<<29)
+#define S3C_CLKCON_SCLK_MMC1_48 (1<<28)
+#define S3C_CLKCON_SCLK_MMC0_48 (1<<27)
+#define S3C_CLKCON_SCLK_MMC2 (1<<26)
+#define S3C_CLKCON_SCLK_MMC1 (1<<25)
+#define S3C_CLKCON_SCLK_MMC0 (1<<24)
+#define S3C_CLKCON_SCLK_SPI1_48 (1<<23)
+#define S3C_CLKCON_SCLK_SPI0_48 (1<<22)
+#define S3C_CLKCON_SCLK_SPI1 (1<<21)
+#define S3C_CLKCON_SCLK_SPI0 (1<<20)
+#define S3C_CLKCON_SCLK_DAC27 (1<<19)
+#define S3C_CLKCON_SCLK_TV27 (1<<18)
+#define S3C_CLKCON_SCLK_SCALER27 (1<<17)
+#define S3C_CLKCON_SCLK_SCALER (1<<16)
+#define S3C_CLKCON_SCLK_LCD27 (1<<15)
+#define S3C_CLKCON_SCLK_LCD (1<<14)
+#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13)
+#define S3C6410_CLKCON_FIMC (1<<13)
+#define S3C_CLKCON_SCLK_POST0_27 (1<<12)
+#define S3C6400_CLKCON_SCLK_POST1 (1<<11)
+#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11)
+#define S3C_CLKCON_SCLK_POST0 (1<<10)
+#define S3C_CLKCON_SCLK_AUDIO1 (1<<9)
+#define S3C_CLKCON_SCLK_AUDIO0 (1<<8)
+#define S3C_CLKCON_SCLK_SECUR (1<<7)
+#define S3C_CLKCON_SCLK_IRDA (1<<6)
+#define S3C_CLKCON_SCLK_UART (1<<5)
+#define S3C_CLKCON_SCLK_ONENAND (1<<4)
+#define S3C_CLKCON_SCLK_MFC (1<<3)
+#define S3C_CLKCON_SCLK_CAM (1<<2)
+#define S3C_CLKCON_SCLK_JPEG (1<<1)
+
+/* CLKSRC */
+
+#define S3C6400_CLKSRC_APLL_MOUT (1 << 0)
+#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1)
+#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2)
+#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0)
+#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1)
+#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
+#define S3C6400_CLKSRC_MFC (1 << 4)
+
+/* MEM_SYS_CFG */
+#define MEM_SYS_CFG_INDEP_CF 0x4000
+#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
+
+#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-fb.h b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
new file mode 100644
index 00000000..a06ee0af
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * 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/include/mach/regs-gpio-memport.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h
new file mode 100644
index 00000000..82342f6f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio-memport.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio-memport.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO memory port register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H __FILE__
+
+#define S3C64XX_MEM0CONSTOP S3C64XX_GPIOREG(0x1B0)
+#define S3C64XX_MEM1CONSTOP S3C64XX_GPIOREG(0x1B4)
+
+#define S3C64XX_MEM0CONSLP0 S3C64XX_GPIOREG(0x1C0)
+#define S3C64XX_MEM0CONSLP1 S3C64XX_GPIOREG(0x1C4)
+#define S3C64XX_MEM1CONSLP S3C64XX_GPIOREG(0x1C8)
+
+#define S3C64XX_MEM0DRVCON S3C64XX_GPIOREG(0x1D0)
+#define S3C64XX_MEM1DRVCON S3C64XX_GPIOREG(0x1D4)
+
+#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_MEMPORT_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
new file mode 100644
index 00000000..81f7f6e6
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-gpio.h
@@ -0,0 +1,187 @@
+/* linux/arch/arm/plat-s3c64xx/include/mach/regs-gpio.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - GPIO register definitions
+ */
+
+#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H
+#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__
+
+/* Base addresses for each of the banks */
+
+#define S3C64XX_GPIOREG(reg) (S3C64XX_VA_GPIO + (reg))
+
+#define S3C64XX_GPA_BASE S3C64XX_GPIOREG(0x0000)
+#define S3C64XX_GPB_BASE S3C64XX_GPIOREG(0x0020)
+#define S3C64XX_GPC_BASE S3C64XX_GPIOREG(0x0040)
+#define S3C64XX_GPD_BASE S3C64XX_GPIOREG(0x0060)
+#define S3C64XX_GPE_BASE S3C64XX_GPIOREG(0x0080)
+#define S3C64XX_GPF_BASE S3C64XX_GPIOREG(0x00A0)
+#define S3C64XX_GPG_BASE S3C64XX_GPIOREG(0x00C0)
+#define S3C64XX_GPH_BASE S3C64XX_GPIOREG(0x00E0)
+#define S3C64XX_GPI_BASE S3C64XX_GPIOREG(0x0100)
+#define S3C64XX_GPJ_BASE S3C64XX_GPIOREG(0x0120)
+#define S3C64XX_GPK_BASE S3C64XX_GPIOREG(0x0800)
+#define S3C64XX_GPL_BASE S3C64XX_GPIOREG(0x0810)
+#define S3C64XX_GPM_BASE S3C64XX_GPIOREG(0x0820)
+#define S3C64XX_GPN_BASE S3C64XX_GPIOREG(0x0830)
+#define S3C64XX_GPO_BASE S3C64XX_GPIOREG(0x0140)
+#define S3C64XX_GPP_BASE S3C64XX_GPIOREG(0x0160)
+#define S3C64XX_GPQ_BASE S3C64XX_GPIOREG(0x0180)
+
+/* SPCON */
+
+#define S3C64XX_SPCON S3C64XX_GPIOREG(0x1A0)
+
+#define S3C64XX_SPCON_DRVCON_CAM_MASK (0x3 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_SHIFT (30)
+#define S3C64XX_SPCON_DRVCON_CAM_2mA (0x0 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_4mA (0x1 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_7mA (0x2 << 30)
+#define S3C64XX_SPCON_DRVCON_CAM_9mA (0x3 << 30)
+
+#define S3C64XX_SPCON_DRVCON_HSSPI_MASK (0x3 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_SHIFT (28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_2mA (0x0 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_4mA (0x1 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_7mA (0x2 << 28)
+#define S3C64XX_SPCON_DRVCON_HSSPI_9mA (0x3 << 28)
+
+#define S3C64XX_SPCON_DRVCON_HSMMC_MASK (0x3 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_SHIFT (26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_2mA (0x0 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_4mA (0x1 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_7mA (0x2 << 26)
+#define S3C64XX_SPCON_DRVCON_HSMMC_9mA (0x3 << 26)
+
+#define S3C64XX_SPCON_DRVCON_LCD_MASK (0x3 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_SHIFT (24)
+#define S3C64XX_SPCON_DRVCON_LCD_2mA (0x0 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_4mA (0x1 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_7mA (0x2 << 24)
+#define S3C64XX_SPCON_DRVCON_LCD_9mA (0x3 << 24)
+
+#define S3C64XX_SPCON_DRVCON_MODEM_MASK (0x3 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_SHIFT (22)
+#define S3C64XX_SPCON_DRVCON_MODEM_2mA (0x0 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_4mA (0x1 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_7mA (0x2 << 22)
+#define S3C64XX_SPCON_DRVCON_MODEM_9mA (0x3 << 22)
+
+#define S3C64XX_SPCON_nRSTOUT_OEN (1 << 21)
+
+#define S3C64XX_SPCON_DRVCON_SPICLK1_MASK (0x3 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_SHIFT (18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_2mA (0x0 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_4mA (0x1 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_7mA (0x2 << 18)
+#define S3C64XX_SPCON_DRVCON_SPICLK1_9mA (0x3 << 18)
+
+#define S3C64XX_SPCON_MEM1_DQS_PUD_MASK (0x3 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_SHIFT (16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DISABLED (0x0 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_DOWN (0x1 << 16)
+#define S3C64XX_SPCON_MEM1_DQS_PUD_UP (0x2 << 16)
+
+#define S3C64XX_SPCON_MEM1_D_PUD1_MASK (0x3 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_SHIFT (14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DISABLED (0x0 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_DOWN (0x1 << 14)
+#define S3C64XX_SPCON_MEM1_D_PUD1_UP (0x2 << 14)
+
+#define S3C64XX_SPCON_MEM1_D_PUD0_MASK (0x3 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_SHIFT (12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DISABLED (0x0 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_DOWN (0x1 << 12)
+#define S3C64XX_SPCON_MEM1_D_PUD0_UP (0x2 << 12)
+
+#define S3C64XX_SPCON_MEM0_D_PUD_MASK (0x3 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_SHIFT (8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DISABLED (0x0 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_DOWN (0x1 << 8)
+#define S3C64XX_SPCON_MEM0_D_PUD_UP (0x2 << 8)
+
+#define S3C64XX_SPCON_USBH_DMPD (1 << 7)
+#define S3C64XX_SPCON_USBH_DPPD (1 << 6)
+#define S3C64XX_SPCON_USBH_PUSW2 (1 << 5)
+#define S3C64XX_SPCON_USBH_PUSW1 (1 << 4)
+#define S3C64XX_SPCON_USBH_SUSPND (1 << 3)
+
+#define S3C64XX_SPCON_LCD_SEL_MASK (0x3 << 0)
+#define S3C64XX_SPCON_LCD_SEL_SHIFT (0)
+#define S3C64XX_SPCON_LCD_SEL_HOST (0x0 << 0)
+#define S3C64XX_SPCON_LCD_SEL_RGB (0x1 << 0)
+#define S3C64XX_SPCON_LCD_SEL_606_656 (0x2 << 0)
+
+
+/* External interrupt registers */
+
+#define S3C64XX_EINT12CON S3C64XX_GPIOREG(0x200)
+#define S3C64XX_EINT34CON S3C64XX_GPIOREG(0x204)
+#define S3C64XX_EINT56CON S3C64XX_GPIOREG(0x208)
+#define S3C64XX_EINT78CON S3C64XX_GPIOREG(0x20C)
+#define S3C64XX_EINT9CON S3C64XX_GPIOREG(0x210)
+
+#define S3C64XX_EINT12FLTCON S3C64XX_GPIOREG(0x220)
+#define S3C64XX_EINT34FLTCON S3C64XX_GPIOREG(0x224)
+#define S3C64XX_EINT56FLTCON S3C64XX_GPIOREG(0x228)
+#define S3C64XX_EINT78FLTCON S3C64XX_GPIOREG(0x22C)
+#define S3C64XX_EINT9FLTCON S3C64XX_GPIOREG(0x230)
+
+#define S3C64XX_EINT12MASK S3C64XX_GPIOREG(0x240)
+#define S3C64XX_EINT34MASK S3C64XX_GPIOREG(0x244)
+#define S3C64XX_EINT56MASK S3C64XX_GPIOREG(0x248)
+#define S3C64XX_EINT78MASK S3C64XX_GPIOREG(0x24C)
+#define S3C64XX_EINT9MASK S3C64XX_GPIOREG(0x250)
+
+#define S3C64XX_EINT12PEND S3C64XX_GPIOREG(0x260)
+#define S3C64XX_EINT34PEND S3C64XX_GPIOREG(0x264)
+#define S3C64XX_EINT56PEND S3C64XX_GPIOREG(0x268)
+#define S3C64XX_EINT78PEND S3C64XX_GPIOREG(0x26C)
+#define S3C64XX_EINT9PEND S3C64XX_GPIOREG(0x270)
+
+#define S3C64XX_PRIORITY S3C64XX_GPIOREG(0x280)
+#define S3C64XX_PRIORITY_ARB(x) (1 << (x))
+
+#define S3C64XX_SERVICE S3C64XX_GPIOREG(0x284)
+#define S3C64XX_SERVICEPEND S3C64XX_GPIOREG(0x288)
+
+#define S3C64XX_EINT0CON0 S3C64XX_GPIOREG(0x900)
+#define S3C64XX_EINT0CON1 S3C64XX_GPIOREG(0x904)
+#define S3C64XX_EINT0FLTCON0 S3C64XX_GPIOREG(0x910)
+#define S3C64XX_EINT0FLTCON1 S3C64XX_GPIOREG(0x914)
+#define S3C64XX_EINT0FLTCON2 S3C64XX_GPIOREG(0x918)
+#define S3C64XX_EINT0FLTCON3 S3C64XX_GPIOREG(0x91C)
+
+#define S3C64XX_EINT0MASK S3C64XX_GPIOREG(0x920)
+#define S3C64XX_EINT0PEND S3C64XX_GPIOREG(0x924)
+
+/* GPIO sleep configuration */
+
+#define S3C64XX_SPCONSLP S3C64XX_GPIOREG(0x880)
+
+#define S3C64XX_SPCONSLP_TDO_PULLDOWN (1 << 14)
+#define S3C64XX_SPCONSLP_CKE1INIT (1 << 5)
+
+#define S3C64XX_SPCONSLP_RSTOUT_MASK (0x3 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT0 (0x0 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_OUT1 (0x1 << 12)
+#define S3C64XX_SPCONSLP_RSTOUT_HIZ (0x2 << 12)
+
+#define S3C64XX_SPCONSLP_KPCOL_MASK (0x3 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT0 (0x0 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_OUT1 (0x1 << 0)
+#define S3C64XX_SPCONSLP_KPCOL_INP (0x2 << 0)
+
+
+#define S3C64XX_SLPEN S3C64XX_GPIOREG(0x930)
+
+#define S3C64XX_SLPEN_USE_xSLP (1 << 0)
+#define S3C64XX_SLPEN_CFG_BYSLPEN (1 << 1)
+
+#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */
+
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-irq.h b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
new file mode 100644
index 00000000..bcce68a0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-irq.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/regs-irq.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+
+#endif /* __ASM_ARCH_6400_REGS_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-modem.h b/arch/arm/mach-s3c64xx/include/mach/regs-modem.h
new file mode 100644
index 00000000..49f7759d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-modem.h
@@ -0,0 +1,31 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-modem.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - modem block 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_S3C64XX_REGS_MODEM_H
+#define __PLAT_S3C64XX_REGS_MODEM_H __FILE__
+
+#define S3C64XX_MODEMREG(x) (S3C64XX_VA_MODEM + (x))
+
+#define S3C64XX_MODEM_INT2AP S3C64XX_MODEMREG(0x0)
+#define S3C64XX_MODEM_INT2MODEM S3C64XX_MODEMREG(0x4)
+#define S3C64XX_MODEM_MIFCON S3C64XX_MODEMREG(0x8)
+#define S3C64XX_MODEM_MIFPCON S3C64XX_MODEMREG(0xC)
+#define S3C64XX_MODEM_INTCLR S3C64XX_MODEMREG(0x10)
+#define S3C64XX_MODEM_DMA_TXADDR S3C64XX_MODEMREG(0x14)
+#define S3C64XX_MODEM_DMA_RXADDR S3C64XX_MODEMREG(0x18)
+
+#define MIFPCON_INT2M_LEVEL (1 << 4)
+#define MIFPCON_LCD_BYPASS (1 << 3)
+
+#endif /* __PLAT_S3C64XX_REGS_MODEM_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-srom.h b/arch/arm/mach-s3c64xx/include/mach/regs-srom.h
new file mode 100644
index 00000000..756731b3
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-srom.h
@@ -0,0 +1,59 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-srom.h
+ *
+ * Copyright 2009 Andy Green <andy@warmcat.com>
+ *
+ * S3C64XX SROM 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_SROM_H
+#define __PLAT_REGS_SROM_H __FILE__
+
+#define S3C64XX_SROMREG(x) (S3C_VA_MEM + (x))
+
+#define S3C64XX_SROM_BW S3C64XX_SROMREG(0)
+#define S3C64XX_SROM_BC0 S3C64XX_SROMREG(4)
+#define S3C64XX_SROM_BC1 S3C64XX_SROMREG(8)
+#define S3C64XX_SROM_BC2 S3C64XX_SROMREG(0xc)
+#define S3C64XX_SROM_BC3 S3C64XX_SROMREG(0x10)
+#define S3C64XX_SROM_BC4 S3C64XX_SROMREG(0x14)
+#define S3C64XX_SROM_BC5 S3C64XX_SROMREG(0x18)
+
+/*
+ * one register BW holds 5 x 4-bit packed settings for NCS0 - NCS4
+ */
+
+#define S3C64XX_SROM_BW__DATAWIDTH__SHIFT 0
+#define S3C64XX_SROM_BW__WAITENABLE__SHIFT 2
+#define S3C64XX_SROM_BW__BYTEENABLE__SHIFT 3
+#define S3C64XX_SROM_BW__CS_MASK 0xf
+
+#define S3C64XX_SROM_BW__NCS0__SHIFT 0
+#define S3C64XX_SROM_BW__NCS1__SHIFT 4
+#define S3C64XX_SROM_BW__NCS2__SHIFT 8
+#define S3C64XX_SROM_BW__NCS3__SHIFT 0xc
+#define S3C64XX_SROM_BW__NCS4__SHIFT 0x10
+
+/*
+ * applies to same to BCS0 - BCS4
+ */
+
+#define S3C64XX_SROM_BCX__PMC__SHIFT 0
+#define S3C64XX_SROM_BCX__PMC__MASK 3
+#define S3C64XX_SROM_BCX__TACP__SHIFT 4
+#define S3C64XX_SROM_BCX__TACP__MASK 0xf
+#define S3C64XX_SROM_BCX__TCAH__SHIFT 8
+#define S3C64XX_SROM_BCX__TCAH__MASK 0xf
+#define S3C64XX_SROM_BCX__TCOH__SHIFT 12
+#define S3C64XX_SROM_BCX__TCOH__MASK 0xf
+#define S3C64XX_SROM_BCX__TACC__SHIFT 16
+#define S3C64XX_SROM_BCX__TACC__MASK 0x1f
+#define S3C64XX_SROM_BCX__TCOS__SHIFT 24
+#define S3C64XX_SROM_BCX__TCOS__MASK 0xf
+#define S3C64XX_SROM_BCX__TACS__SHIFT 28
+#define S3C64XX_SROM_BCX__TACS__MASK 0xf
+
+#endif /* _PLAT_REGS_SROM_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-sys.h b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
new file mode 100644
index 00000000..69b78d9f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-sys.h
@@ -0,0 +1,28 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-sys.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX system 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_SYS_H
+#define __PLAT_REGS_SYS_H __FILE__
+
+#define S3C_SYSREG(x) (S3C_VA_SYS + (x))
+
+#define S3C64XX_AHB_CON0 S3C_SYSREG(0x100)
+#define S3C64XX_AHB_CON1 S3C_SYSREG(0x104)
+#define S3C64XX_AHB_CON2 S3C_SYSREG(0x108)
+
+#define S3C64XX_OTHERS S3C_SYSREG(0x900)
+
+#define S3C64XX_OTHERS_USBMASK (1 << 16)
+
+#endif /* _PLAT_REGS_SYS_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h b/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h
new file mode 100644
index 00000000..270d96ac
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-syscon-power.h
@@ -0,0 +1,116 @@
+/* arch/arm/plat-s3c64xx/include/plat/regs-syscon-power.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - syscon power and sleep control 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_S3C64XX_REGS_SYSCON_POWER_H
+#define __PLAT_S3C64XX_REGS_SYSCON_POWER_H __FILE__
+
+#define S3C64XX_PWR_CFG S3C_SYSREG(0x804)
+
+#define S3C64XX_PWRCFG_OSC_OTG_DISABLE (1 << 17)
+#define S3C64XX_PWRCFG_MMC2_DISABLE (1 << 16)
+#define S3C64XX_PWRCFG_MMC1_DISABLE (1 << 15)
+#define S3C64XX_PWRCFG_MMC0_DISABLE (1 << 14)
+#define S3C64XX_PWRCFG_HSI_DISABLE (1 << 13)
+#define S3C64XX_PWRCFG_TS_DISABLE (1 << 12)
+#define S3C64XX_PWRCFG_RTC_TICK_DISABLE (1 << 11)
+#define S3C64XX_PWRCFG_RTC_ALARM_DISABLE (1 << 10)
+#define S3C64XX_PWRCFG_MSM_DISABLE (1 << 9)
+#define S3C64XX_PWRCFG_KEY_DISABLE (1 << 8)
+#define S3C64XX_PWRCFG_BATF_DISABLE (1 << 7)
+
+#define S3C64XX_PWRCFG_CFG_WFI_MASK (0x3 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SHIFT (5)
+#define S3C64XX_PWRCFG_CFG_WFI_IGNORE (0x0 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_IDLE (0x1 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_STOP (0x2 << 5)
+#define S3C64XX_PWRCFG_CFG_WFI_SLEEP (0x3 << 5)
+
+#define S3C64XX_PWRCFG_CFG_BATFLT_MASK (0x3 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SHIFT (3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IGNORE (0x0 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_IRQ (0x1 << 3)
+#define S3C64XX_PWRCFG_CFG_BATFLT_SLEEP (0x3 << 3)
+
+#define S3C64XX_PWRCFG_CFG_BAT_WAKE (1 << 2)
+#define S3C64XX_PWRCFG_OSC27_EN (1 << 0)
+
+#define S3C64XX_EINT_MASK S3C_SYSREG(0x808)
+
+#define S3C64XX_NORMAL_CFG S3C_SYSREG(0x810)
+
+#define S3C64XX_NORMALCFG_IROM_ON (1 << 30)
+#define S3C64XX_NORMALCFG_DOMAIN_ETM_ON (1 << 16)
+#define S3C64XX_NORMALCFG_DOMAIN_S_ON (1 << 15)
+#define S3C64XX_NORMALCFG_DOMAIN_F_ON (1 << 14)
+#define S3C64XX_NORMALCFG_DOMAIN_P_ON (1 << 13)
+#define S3C64XX_NORMALCFG_DOMAIN_I_ON (1 << 12)
+#define S3C64XX_NORMALCFG_DOMAIN_G_ON (1 << 10)
+#define S3C64XX_NORMALCFG_DOMAIN_V_ON (1 << 9)
+
+#define S3C64XX_STOP_CFG S3C_SYSREG(0x814)
+
+#define S3C64XX_STOPCFG_MEMORY_ARM_ON (1 << 29)
+#define S3C64XX_STOPCFG_TOP_MEMORY_ON (1 << 20)
+#define S3C64XX_STOPCFG_ARM_LOGIC_ON (1 << 17)
+#define S3C64XX_STOPCFG_TOP_LOGIC_ON (1 << 8)
+#define S3C64XX_STOPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_SLEEP_CFG S3C_SYSREG(0x818)
+
+#define S3C64XX_SLEEPCFG_OSC_EN (1 << 0)
+
+#define S3C64XX_STOP_MEM_CFG S3C_SYSREG(0x81c)
+
+#define S3C64XX_STOPMEMCFG_MODEMIF_RETAIN (1 << 6)
+#define S3C64XX_STOPMEMCFG_HOSTIF_RETAIN (1 << 5)
+#define S3C64XX_STOPMEMCFG_OTG_RETAIN (1 << 4)
+#define S3C64XX_STOPMEMCFG_HSMCC_RETAIN (1 << 3)
+#define S3C64XX_STOPMEMCFG_IROM_RETAIN (1 << 2)
+#define S3C64XX_STOPMEMCFG_IRDA_RETAIN (1 << 1)
+#define S3C64XX_STOPMEMCFG_NFCON_RETAIN (1 << 0)
+
+#define S3C64XX_OSC_STABLE S3C_SYSREG(0x824)
+#define S3C64XX_PWR_STABLE S3C_SYSREG(0x828)
+
+#define S3C64XX_WAKEUP_STAT S3C_SYSREG(0x908)
+
+#define S3C64XX_WAKEUPSTAT_MMC2 (1 << 11)
+#define S3C64XX_WAKEUPSTAT_MMC1 (1 << 10)
+#define S3C64XX_WAKEUPSTAT_MMC0 (1 << 9)
+#define S3C64XX_WAKEUPSTAT_HSI (1 << 8)
+#define S3C64XX_WAKEUPSTAT_BATFLT (1 << 6)
+#define S3C64XX_WAKEUPSTAT_MSM (1 << 5)
+#define S3C64XX_WAKEUPSTAT_KEY (1 << 4)
+#define S3C64XX_WAKEUPSTAT_TS (1 << 3)
+#define S3C64XX_WAKEUPSTAT_RTC_TICK (1 << 2)
+#define S3C64XX_WAKEUPSTAT_RTC_ALARM (1 << 1)
+#define S3C64XX_WAKEUPSTAT_EINT (1 << 0)
+
+#define S3C64XX_BLK_PWR_STAT S3C_SYSREG(0x90c)
+
+#define S3C64XX_BLKPWRSTAT_G (1 << 7)
+#define S3C64XX_BLKPWRSTAT_ETM (1 << 6)
+#define S3C64XX_BLKPWRSTAT_S (1 << 5)
+#define S3C64XX_BLKPWRSTAT_F (1 << 4)
+#define S3C64XX_BLKPWRSTAT_P (1 << 3)
+#define S3C64XX_BLKPWRSTAT_I (1 << 2)
+#define S3C64XX_BLKPWRSTAT_V (1 << 1)
+#define S3C64XX_BLKPWRSTAT_TOP (1 << 0)
+
+#define S3C64XX_INFORM0 S3C_SYSREG(0xA00)
+#define S3C64XX_INFORM1 S3C_SYSREG(0xA04)
+#define S3C64XX_INFORM2 S3C_SYSREG(0xA08)
+#define S3C64XX_INFORM3 S3C_SYSREG(0xA0C)
+
+#endif /* __PLAT_S3C64XX_REGS_SYSCON_POWER_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6400.h b/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
new file mode 100644
index 00000000..f86958d0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/s3c6400.h
@@ -0,0 +1,36 @@
+/* arch/arm/mach-s3c64xx/include/macht/s3c6400.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6400 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 S3C6400 related SoCs */
+
+extern void s3c6400_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c6400_setup_clocks(void);
+
+extern void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit);
+
+#ifdef CONFIG_CPU_S3C6400
+
+extern int s3c6400_init(void);
+extern void s3c6400_init_irq(void);
+extern void s3c6400_map_io(void);
+extern void s3c6400_init_clocks(int xtal);
+
+#define s3c6400_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6400_init_clocks NULL
+#define s3c6400_init_uarts NULL
+#define s3c6400_map_io NULL
+#define s3c6400_init NULL
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/s3c6410.h b/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
new file mode 100644
index 00000000..24f1141f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/s3c6410.h
@@ -0,0 +1,29 @@
+/* arch/arm/mach-s3c64xx/include/mach/s3c6410.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Header file for s3c6410 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.
+*/
+
+#ifdef CONFIG_CPU_S3C6410
+
+extern int s3c6410_init(void);
+extern void s3c6410_init_irq(void);
+extern void s3c6410_map_io(void);
+extern void s3c6410_init_clocks(int xtal);
+
+#define s3c6410_init_uarts s3c6400_common_init_uarts
+
+#else
+#define s3c6410_init_clocks NULL
+#define s3c6410_init_uarts NULL
+#define s3c6410_map_io NULL
+#define s3c6410_init NULL
+#endif
diff --git a/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
new file mode 100644
index 00000000..9d0c43b4
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s3c64xx/include/mach/spi-clocks.h
+ *
+ * Copyright (C) 2009 Samsung Electronics 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 __S3C64XX_PLAT_SPI_CLKS_H
+#define __S3C64XX_PLAT_SPI_CLKS_H __FILE__
+
+#define S3C64XX_SPI_SRCCLK_PCLK 0
+#define S3C64XX_SPI_SRCCLK_SPIBUS 1
+#define S3C64XX_SPI_SRCCLK_48M 2
+
+#endif /* __S3C64XX_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h
new file mode 100644
index 00000000..2e58cb7a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/system.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/system.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400 - system implementation
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/watchdog-reset.h>
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ if (mode != 's')
+ arch_wdt_reset();
+
+ /* if all else fails, or mode was for soft, jump to 0 */
+ cpu_reset(0);
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/tick.h b/arch/arm/mach-s3c64xx/include/mach/tick.h
new file mode 100644
index 00000000..ebe18a94
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/tick.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+/* note, the timer interrutps turn up in 2 places, the vic and then
+ * the timer block. We take the VIC as the base at the moment.
+ */
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & 1 << (IRQ_TIMER4_VIC - S3C64XX_IRQ_VIC0(0));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_6400_TICK_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/timex.h b/arch/arm/mach-s3c64xx/include/mach/timex.h
new file mode 100644
index 00000000..fb2e8cd4
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s3c64xx/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/uncompress.h b/arch/arm/mach-s3c64xx/include/mach/uncompress.h
new file mode 100644
index 00000000..c6a82a20
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/uncompress.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s3c6400/include/mach/uncompress.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+ fifo_mask = S3C2440_UFSTAT_TXMASK;
+ fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/vmalloc.h b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..23f75e55
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/* arch/arm/mach-s3c64xx/include/mach/vmalloc.h
+ *
+ * from arch/arm/mach-iop3xx/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
new file mode 100644
index 00000000..4d203be1
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -0,0 +1,213 @@
+/* arch/arm/plat-s3c64xx/irq-eint.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling for IRQ_EINT(x)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <plat/regs-irqtype.h>
+#include <mach/regs-gpio.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#define eint_offset(irq) ((irq) - IRQ_EINT(0))
+#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq)))
+
+static inline void s3c_irq_eint_mask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask |= (u32)data->chip_data;
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static void s3c_irq_eint_unmask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S3C64XX_EINT0MASK);
+ mask &= ~((u32)data->chip_data);
+ __raw_writel(mask, S3C64XX_EINT0MASK);
+}
+
+static inline void s3c_irq_eint_ack(struct irq_data *data)
+{
+ __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND);
+}
+
+static void s3c_irq_eint_maskack(struct irq_data *data)
+{
+ /* compiler should in-line these */
+ s3c_irq_eint_mask(data);
+ s3c_irq_eint_ack(data);
+}
+
+static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type)
+{
+ int offs = eint_offset(data->irq);
+ int pin, pin_val;
+ int shift;
+ u32 ctrl, mask;
+ u32 newvalue = 0;
+ void __iomem *reg;
+
+ if (offs > 27)
+ return -EINVAL;
+
+ if (offs <= 15)
+ reg = S3C64XX_EINT0CON0;
+ else
+ reg = S3C64XX_EINT0CON1;
+
+ switch (type) {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ if (offs <= 15)
+ shift = (offs / 2) * 4;
+ else
+ shift = ((offs - 16) / 2) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(reg);
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, reg);
+
+ /* set the GPIO pin appropriately */
+
+ if (offs < 16) {
+ pin = S3C64XX_GPN(offs);
+ pin_val = S3C_GPIO_SFN(2);
+ } else if (offs < 23) {
+ pin = S3C64XX_GPL(offs + 8 - 16);
+ pin_val = S3C_GPIO_SFN(3);
+ } else {
+ pin = S3C64XX_GPM(offs - 23);
+ pin_val = S3C_GPIO_SFN(3);
+ }
+
+ s3c_gpio_cfgpin(pin, pin_val);
+
+ return 0;
+}
+
+static struct irq_chip s3c_irq_eint = {
+ .name = "s3c-eint",
+ .irq_mask = s3c_irq_eint_mask,
+ .irq_unmask = s3c_irq_eint_unmask,
+ .irq_mask_ack = s3c_irq_eint_maskack,
+ .irq_ack = s3c_irq_eint_ack,
+ .irq_set_type = s3c_irq_eint_set_type,
+ .irq_set_wake = s3c_irqext_wake,
+};
+
+/* s3c_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from IRQ_EINT(0) to IRQ_EINT(27). It is designed to be inlined into
+ * the specific handlers s3c_irq_demux_eintX_Y.
+ */
+static inline void s3c_irq_demux_eint(unsigned int start, unsigned int end)
+{
+ u32 status = __raw_readl(S3C64XX_EINT0PEND);
+ u32 mask = __raw_readl(S3C64XX_EINT0MASK);
+ unsigned int irq;
+
+ status &= ~mask;
+ status >>= start;
+ status &= (1 << (end - start + 1)) - 1;
+
+ for (irq = IRQ_EINT(start); irq <= IRQ_EINT(end); irq++) {
+ if (status & 1)
+ generic_handle_irq(irq);
+
+ status >>= 1;
+ }
+}
+
+static void s3c_irq_demux_eint0_3(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(0, 3);
+}
+
+static void s3c_irq_demux_eint4_11(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(4, 11);
+}
+
+static void s3c_irq_demux_eint12_19(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(12, 19);
+}
+
+static void s3c_irq_demux_eint20_27(unsigned int irq, struct irq_desc *desc)
+{
+ s3c_irq_demux_eint(20, 27);
+}
+
+static int __init s3c64xx_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
+ irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
+ irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
+ irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
+ irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
+ irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
+
+ return 0;
+}
+
+arch_initcall(s3c64xx_init_irq_eint);
diff --git a/arch/arm/mach-s3c64xx/irq-pm.c b/arch/arm/mach-s3c64xx/irq-pm.c
new file mode 100644
index 00000000..8bec61e2
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq-pm.c
@@ -0,0 +1,111 @@
+/* arch/arm/plat-s3c64xx/irq-pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling Power Management
+ *
+ * This program is free software; you can 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/syscore_ops.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-gpio.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+/* We handled all the IRQ types in this code, to save having to make several
+ * small files to handle each different type separately. Having the EINT_GRP
+ * code here shouldn't be as much bloat as the IRQ table space needed when
+ * they are enabled. The added benefit is we ensure that these registers are
+ * in the same state as we suspended.
+ */
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C64XX_PRIORITY),
+ SAVE_ITEM(S3C64XX_EINT0CON0),
+ SAVE_ITEM(S3C64XX_EINT0CON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON0),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON1),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON2),
+ SAVE_ITEM(S3C64XX_EINT0FLTCON3),
+ SAVE_ITEM(S3C64XX_EINT0MASK),
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+};
+
+static struct irq_grp_save {
+ u32 fltcon;
+ u32 con;
+ u32 mask;
+} eint_grp_save[5];
+
+static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static int s3c64xx_irq_pm_suspend(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: suspending IRQs\n", __func__);
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ irq_uart_mask[i] = __raw_readl(S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ grp->con = __raw_readl(S3C64XX_EINT12CON + (i * 4));
+ grp->mask = __raw_readl(S3C64XX_EINT12MASK + (i * 4));
+ grp->fltcon = __raw_readl(S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ return 0;
+}
+
+static void s3c64xx_irq_pm_resume(void)
+{
+ struct irq_grp_save *grp = eint_grp_save;
+ int i;
+
+ S3C_PMDBG("%s: resuming IRQs\n", __func__);
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+
+ for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++)
+ __raw_writel(irq_uart_mask[i], S3C_VA_UARTx(i) + S3C64XX_UINTM);
+
+ for (i = 0; i < ARRAY_SIZE(eint_grp_save); i++, grp++) {
+ __raw_writel(grp->con, S3C64XX_EINT12CON + (i * 4));
+ __raw_writel(grp->mask, S3C64XX_EINT12MASK + (i * 4));
+ __raw_writel(grp->fltcon, S3C64XX_EINT12FLTCON + (i * 4));
+ }
+
+ S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
+}
+
+struct syscore_ops s3c64xx_irq_syscore_ops = {
+ .suspend = s3c64xx_irq_pm_suspend,
+ .resume = s3c64xx_irq_pm_resume,
+};
+
+static __init int s3c64xx_syscore_init(void)
+{
+ register_syscore_ops(&s3c64xx_irq_syscore_ops);
+
+ return 0;
+}
+
+core_initcall(s3c64xx_syscore_init);
diff --git a/arch/arm/mach-s3c64xx/irq.c b/arch/arm/mach-s3c64xx/irq.c
new file mode 100644
index 00000000..97660c81
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/irq.c
@@ -0,0 +1,64 @@
+/* arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/vic.h>
+
+#include <mach/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.h>
+#include <plat/cpu.h>
+
+static struct s3c_uart_irq uart_irqs[] = {
+ [0] = {
+ .regs = S3C_VA_UART0,
+ .base_irq = IRQ_S3CUART_BASE0,
+ .parent_irq = IRQ_UART0,
+ },
+ [1] = {
+ .regs = S3C_VA_UART1,
+ .base_irq = IRQ_S3CUART_BASE1,
+ .parent_irq = IRQ_UART1,
+ },
+ [2] = {
+ .regs = S3C_VA_UART2,
+ .base_irq = IRQ_S3CUART_BASE2,
+ .parent_irq = IRQ_UART2,
+ },
+ [3] = {
+ .regs = S3C_VA_UART3,
+ .base_irq = IRQ_S3CUART_BASE3,
+ .parent_irq = IRQ_UART3,
+ },
+};
+
+
+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);
+
+ /* add the timer sub-irqs */
+ s3c_init_vic_timer_irq(5, IRQ_TIMER0);
+
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
new file mode 100644
index 00000000..a53cf149
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -0,0 +1,242 @@
+/* linux/arch/arm/mach-s3c64xx/mach-anw6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ * Copyright 2009 Kwangwoo Lee
+ * Kwangwoo Lee <kwangwoo.lee@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/dm9000.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+
+/* DM9000 */
+#define ANW6410_PA_DM9000 (0x18000000)
+
+/* A hardware buffer to control external devices is mapped at 0x30000000.
+ * It can not be read. So current status must be kept in anw6410_extdev_status.
+ */
+#define ANW6410_VA_EXTDEV S3C_ADDR(0x02000000)
+#define ANW6410_PA_EXTDEV (0x30000000)
+
+#define ANW6410_EN_DM9000 (1<<11)
+#define ANW6410_EN_LCD (1<<14)
+
+static __u32 anw6410_extdev_status;
+
+static struct s3c2410_uartcfg anw6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+/* framebuffer and LCD setup. */
+static void __init anw6410_lcd_mode_set(void)
+{
+ u32 tmp;
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/* GPF1 = LCD panel power
+ * GPF4 = LCD backlight control
+ */
+static void anw6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ anw6410_extdev_status |= (ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 1);
+ gpio_direction_output(S3C64XX_GPF(4), 1);
+ } else {
+ anw6410_extdev_status &= ~(ANW6410_EN_LCD << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+
+ gpio_direction_output(S3C64XX_GPF(1), 0);
+ gpio_direction_output(S3C64XX_GPF(4), 0);
+ }
+}
+
+static struct plat_lcd_data anw6410_lcd_power_data = {
+ .set_power = anw6410_lcd_power_set,
+};
+
+static struct platform_device anw6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &anw6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win anw6410_fb_win0 = {
+ /* this is to ensure we use win0 */
+ .win_mode = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata anw6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &anw6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+static void __init anw6410_dm9000_enable(void)
+{
+ anw6410_extdev_status |= (ANW6410_EN_DM9000 << 16);
+ __raw_writel(anw6410_extdev_status, ANW6410_VA_EXTDEV);
+}
+
+static struct resource anw6410_dm9000_resource[] = {
+ [0] = {
+ .start = ANW6410_PA_DM9000,
+ .end = ANW6410_PA_DM9000 + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ANW6410_PA_DM9000 + 4,
+ .end = ANW6410_PA_DM9000 + 4 + 500,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_EINT(15),
+ .end = IRQ_EINT(15),
+ .flags = IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
+ },
+};
+
+static struct dm9000_plat_data anw6410_dm9000_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+ /* dev_addr can be set to provide hwaddr. */
+};
+
+static struct platform_device anw6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(anw6410_dm9000_resource),
+ .resource = anw6410_dm9000_resource,
+ .dev = {
+ .platform_data = &anw6410_dm9000_pdata,
+ },
+};
+
+static struct map_desc anw6410_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)ANW6410_VA_EXTDEV,
+ .pfn = __phys_to_pfn(ANW6410_PA_EXTDEV),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct platform_device *anw6410_devices[] __initdata = {
+ &s3c_device_fb,
+ &anw6410_lcd_powerdev,
+ &anw6410_device_eth,
+};
+
+static void __init anw6410_map_io(void)
+{
+ s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+
+ anw6410_lcd_mode_set();
+}
+
+static void __init anw6410_machine_init(void)
+{
+ s3c_fb_set_platdata(&anw6410_lcd_pdata);
+
+ gpio_request(S3C64XX_GPF(1), "panel power");
+ gpio_request(S3C64XX_GPF(4), "LCD backlight");
+
+ anw6410_dm9000_enable();
+
+ platform_add_devices(anw6410_devices, ARRAY_SIZE(anw6410_devices));
+}
+
+MACHINE_START(ANW6410, "A&W6410")
+ /* Maintainer: Kwangwoo Lee <kwangwoo.lee@gmail.com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = anw6410_map_io,
+ .init_machine = anw6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
new file mode 100644
index 00000000..b2639582
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -0,0 +1,273 @@
+/* mach-hmt.c - Platform code for Airgoo HMT
+ *
+ * Copyright 2009 Peter Korsgaard <jacmet@sunsite.dk>
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/pwm_backlight.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg hmt_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static int hmt_bl_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPB(4), "lcd backlight enable");
+ if (!ret)
+ ret = gpio_direction_output(S3C64XX_GPB(4), 0);
+
+ return ret;
+}
+
+static int hmt_bl_notify(struct device *dev, int brightness)
+{
+ /*
+ * translate from CIELUV/CIELAB L*->brightness, E.G. from
+ * perceived luminance to light output. Assumes range 0..25600
+ */
+ if (brightness < 0x800) {
+ /* Y = Yn * L / 903.3 */
+ brightness = (100*256 * brightness + 231245/2) / 231245;
+ } else {
+ /* Y = Yn * ((L + 16) / 116 )^3 */
+ int t = (brightness*4 + 16*1024 + 58)/116;
+ brightness = 25 * ((t * t * t + 0x100000/2) / 0x100000);
+ }
+
+ gpio_set_value(S3C64XX_GPB(4), brightness);
+
+ return brightness;
+}
+
+static void hmt_bl_exit(struct device *dev)
+{
+ gpio_free(S3C64XX_GPB(4));
+}
+
+static struct platform_pwm_backlight_data hmt_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 100 * 256,
+ .dft_brightness = 40 * 256,
+ .pwm_period_ns = 1000000000 / (100 * 256 * 20),
+ .init = hmt_bl_init,
+ .notify = hmt_bl_notify,
+ .exit = hmt_bl_exit,
+
+};
+
+static struct platform_device hmt_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[1].dev,
+ .platform_data = &hmt_backlight_data,
+ },
+};
+
+static struct s3c_fb_pd_win hmt_fb_win0 = {
+ .win_mode = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata hmt_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &hmt_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition hmt_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_512K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "uboot-env1",
+ .size = SZ_256K,
+ .offset = SZ_512K,
+ },
+ [2] = {
+ .name = "uboot-env2",
+ .size = SZ_256K,
+ .offset = SZ_512K + SZ_256K,
+ },
+ [3] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [4] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set hmt_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(hmt_nand_part),
+ .partitions = hmt_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand hmt_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(hmt_nand_sets),
+ .sets = hmt_nand_sets,
+};
+
+static struct gpio_led hmt_leds[] = {
+ { /* left function keys */
+ .name = "left:blue",
+ .gpio = S3C64XX_GPO(12),
+ .default_trigger = "default-on",
+ },
+ { /* right function keys - red */
+ .name = "right:red",
+ .gpio = S3C64XX_GPO(13),
+ },
+ { /* right function keys - green */
+ .name = "right:green",
+ .gpio = S3C64XX_GPO(14),
+ },
+ { /* right function keys - blue */
+ .name = "right:blue",
+ .gpio = S3C64XX_GPO(15),
+ .default_trigger = "default-on",
+ },
+};
+
+static struct gpio_led_platform_data hmt_led_data = {
+ .num_leds = ARRAY_SIZE(hmt_leds),
+ .leds = hmt_leds,
+};
+
+static struct platform_device hmt_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &hmt_led_data,
+};
+
+static struct map_desc hmt_iodesc[] = {};
+
+static struct platform_device *hmt_devices[] __initdata = {
+ &s3c_device_i2c0,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_timer[1],
+ &hmt_backlight_device,
+ &hmt_leds_device,
+};
+
+static void __init hmt_map_io(void)
+{
+ s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+}
+
+static void __init hmt_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_fb_set_platdata(&hmt_lcd_pdata);
+ s3c_nand_set_platdata(&hmt_nand_info);
+
+ gpio_request(S3C64XX_GPC(7), "usb power");
+ gpio_direction_output(S3C64XX_GPC(7), 0);
+ gpio_request(S3C64XX_GPM(0), "usb power");
+ gpio_direction_output(S3C64XX_GPM(0), 1);
+ gpio_request(S3C64XX_GPK(7), "usb power");
+ gpio_direction_output(S3C64XX_GPK(7), 1);
+ gpio_request(S3C64XX_GPF(13), "usb power");
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+
+ platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices));
+}
+
+MACHINE_START(HMT, "Airgoo-HMT")
+ /* Maintainer: Peter Korsgaard <jacmet@sunsite.dk> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = hmt_map_io,
+ .init_machine = hmt_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
new file mode 100644
index 00000000..89f35e02
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -0,0 +1,357 @@
+/* linux/arch/arm/mach-s3c64xx/mach-mini6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+#include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg mini6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource mini6410_dm9k_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_XM0CSN1,
+ .end = S3C64XX_PA_XM0CSN1 + 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C64XX_PA_XM0CSN1 + 4,
+ .end = S3C64XX_PA_XM0CSN1 + 5,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = S3C_EINT(7),
+ .end = S3C_EINT(7),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+ }
+};
+
+static struct dm9000_plat_data mini6410_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device mini6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mini6410_dm9k_resource),
+ .resource = mini6410_dm9k_resource,
+ .dev = {
+ .platform_data = &mini6410_dm9k_pdata,
+ },
+};
+
+static struct mtd_partition mini6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set mini6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(mini6410_nand_part),
+ .partitions = mini6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand mini6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(mini6410_nand_sets),
+ .sets = mini6410_nand_sets,
+};
+
+static struct s3c_fb_pd_win mini6410_fb_win[] = {
+ {
+ .win_mode = { /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 272,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ }, {
+ .win_mode = { /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ },
+};
+
+static struct s3c_fb_platdata mini6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &mini6410_fb_win[0],
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static void mini6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(S3C64XX_GPE(0), 1);
+ else
+ gpio_direction_output(S3C64XX_GPE(0), 0);
+}
+
+static struct plat_lcd_data mini6410_lcd_power_data = {
+ .set_power = mini6410_lcd_power_set,
+};
+
+static struct platform_device mini6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &mini6410_lcd_power_data,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static struct platform_device *mini6410_devices[] __initdata = {
+ &mini6410_device_eth,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_ohci,
+ &s3c_device_nand,
+ &s3c_device_fb,
+ &mini6410_lcd_powerdev,
+ &s3c_device_adc,
+ &s3c_device_ts,
+};
+
+static void __init mini6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(NULL, 0);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * mini6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char mini6410_features_str[12] __initdata = "0";
+
+static int __init mini6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(mini6410_features_str, str,
+ sizeof(mini6410_features_str));
+ return 1;
+}
+
+__setup("mini6410=", mini6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct mini6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void mini6410_parse_features(
+ struct mini6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "MINI6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(mini6410_fb_win))
+ printk(KERN_INFO "MINI6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
+}
+
+static void __init mini6410_machine_init(void)
+{
+ u32 cs1;
+ struct mini6410_features_t features = { 0 };
+
+ printk(KERN_INFO "MINI6410: Option string mini6410=%s\n",
+ mini6410_features_str);
+
+ /* Parse the feature string */
+ mini6410_parse_features(&features, mini6410_features_str);
+
+ mini6410_lcd_pdata.win[0] = &mini6410_fb_win[features.lcd_index];
+
+ printk(KERN_INFO "MINI6410: selected LCD display is %dx%d\n",
+ mini6410_lcd_pdata.win[0]->win_mode.xres,
+ mini6410_lcd_pdata.win[0]->win_mode.yres);
+
+ s3c_nand_set_platdata(&mini6410_nand_info);
+ s3c_fb_set_platdata(&mini6410_lcd_pdata);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+ gpio_request(S3C64XX_GPE(0), "LCD power");
+
+ platform_add_devices(mini6410_devices, ARRAY_SIZE(mini6410_devices));
+}
+
+MACHINE_START(MINI6410, "MINI6410")
+ /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = mini6410_map_io,
+ .init_machine = mini6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
new file mode 100644
index 00000000..c4986498
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -0,0 +1,105 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-ncp.c
+ *
+ * Copyright (C) 2008-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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg ncp_uartcfgs[] __initdata = {
+ /* REVISIT: NCP uses only serial 1, 2 */
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static struct platform_device *ncp_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct map_desc ncp_iodesc[] __initdata = {};
+
+static void __init ncp_map_io(void)
+{
+ s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+}
+
+static void __init ncp_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+
+ platform_add_devices(ncp_devices, ARRAY_SIZE(ncp_devices));
+}
+
+MACHINE_START(NCP, "NCP")
+ /* Maintainer: Samsung Electronics */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = ncp_map_io,
+ .init_machine = ncp_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
new file mode 100644
index 00000000..4957ab0a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -0,0 +1,338 @@
+/* linux/arch/arm/mach-s3c64xx/mach-real6410.c
+ *
+ * Copyright 2010 Darius Augulis <augulis.darius@gmail.com>
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/dm9000.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/types.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-srom.h>
+#include <mach/s3c6410.h>
+
+#include <plat/adc.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/nand.h>
+#include <plat/regs-serial.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* DM9000AEP 10/100 ethernet controller */
+
+static struct resource real6410_dm9k_resource[] = {
+ [0] = {
+ .start = S3C64XX_PA_XM0CSN1,
+ .end = S3C64XX_PA_XM0CSN1 + 1,
+ .flags = IORESOURCE_MEM
+ },
+ [1] = {
+ .start = S3C64XX_PA_XM0CSN1 + 4,
+ .end = S3C64XX_PA_XM0CSN1 + 5,
+ .flags = IORESOURCE_MEM
+ },
+ [2] = {
+ .start = S3C_EINT(7),
+ .end = S3C_EINT(7),
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL
+ }
+};
+
+static struct dm9000_plat_data real6410_dm9k_pdata = {
+ .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
+};
+
+static struct platform_device real6410_device_eth = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(real6410_dm9k_resource),
+ .resource = real6410_dm9k_resource,
+ .dev = {
+ .platform_data = &real6410_dm9k_pdata,
+ },
+};
+
+static struct s3c_fb_pd_win real6410_fb_win[] = {
+ {
+ .win_mode = { /* 4.3" 480x272 */
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 1,
+ .hsync_len = 40,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 272,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ }, {
+ .win_mode = { /* 7.0" 800x480 */
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ },
+};
+
+static struct s3c_fb_platdata real6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &real6410_fb_win[0],
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+static struct mtd_partition real6410_nand_part[] = {
+ [0] = {
+ .name = "uboot",
+ .size = SZ_1M,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "kernel",
+ .size = SZ_2M,
+ .offset = SZ_1M,
+ },
+ [2] = {
+ .name = "rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = SZ_1M + SZ_2M,
+ },
+};
+
+static struct s3c2410_nand_set real6410_nand_sets[] = {
+ [0] = {
+ .name = "nand",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(real6410_nand_part),
+ .partitions = real6410_nand_part,
+ },
+};
+
+static struct s3c2410_platform_nand real6410_nand_info = {
+ .tacls = 25,
+ .twrph0 = 55,
+ .twrph1 = 40,
+ .nr_sets = ARRAY_SIZE(real6410_nand_sets),
+ .sets = real6410_nand_sets,
+};
+
+static struct platform_device *real6410_devices[] __initdata = {
+ &real6410_device_eth,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_fb,
+ &s3c_device_nand,
+ &s3c_device_adc,
+ &s3c_device_ts,
+ &s3c_device_ohci,
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init real6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(NULL, 0);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+/*
+ * real6410_features string
+ *
+ * 0-9 LCD configuration
+ *
+ */
+static char real6410_features_str[12] __initdata = "0";
+
+static int __init real6410_features_setup(char *str)
+{
+ if (str)
+ strlcpy(real6410_features_str, str,
+ sizeof(real6410_features_str));
+ return 1;
+}
+
+__setup("real6410=", real6410_features_setup);
+
+#define FEATURE_SCREEN (1 << 0)
+
+struct real6410_features_t {
+ int done;
+ int lcd_index;
+};
+
+static void real6410_parse_features(
+ struct real6410_features_t *features,
+ const char *features_str)
+{
+ const char *fp = features_str;
+
+ features->done = 0;
+ features->lcd_index = 0;
+
+ while (*fp) {
+ char f = *fp++;
+
+ switch (f) {
+ case '0'...'9': /* tft screen */
+ if (features->done & FEATURE_SCREEN) {
+ printk(KERN_INFO "REAL6410: '%c' ignored, "
+ "screen type already set\n", f);
+ } else {
+ int li = f - '0';
+ if (li >= ARRAY_SIZE(real6410_fb_win))
+ printk(KERN_INFO "REAL6410: '%c' out "
+ "of range LCD mode\n", f);
+ else {
+ features->lcd_index = li;
+ }
+ }
+ features->done |= FEATURE_SCREEN;
+ break;
+ }
+ }
+}
+
+static void __init real6410_machine_init(void)
+{
+ u32 cs1;
+ struct real6410_features_t features = { 0 };
+
+ printk(KERN_INFO "REAL6410: Option string real6410=%s\n",
+ real6410_features_str);
+
+ /* Parse the feature string */
+ real6410_parse_features(&features, real6410_features_str);
+
+ real6410_lcd_pdata.win[0] = &real6410_fb_win[features.lcd_index];
+
+ printk(KERN_INFO "REAL6410: selected LCD display is %dx%d\n",
+ real6410_lcd_pdata.win[0]->win_mode.xres,
+ real6410_lcd_pdata.win[0]->win_mode.yres);
+
+ s3c_fb_set_platdata(&real6410_lcd_pdata);
+ s3c_nand_set_platdata(&real6410_nand_info);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (13 << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPF(15), "LCD power");
+
+ platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices));
+}
+
+MACHINE_START(REAL6410, "REAL6410")
+ /* Maintainer: Darius Augulis <augulis.darius@gmail.com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = real6410_map_io,
+ .init_machine = real6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c
new file mode 100644
index 00000000..cb1ebeb0
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq.c
@@ -0,0 +1,399 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/serial_core.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/usb/gpio_vbus.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-modem.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+#include <plat/hwmon.h>
+#include <plat/regs-serial.h>
+#include <plat/udc-hs.h>
+#include <plat/usb-control.h>
+#include <plat/sdhci.h>
+#include <plat/ts.h>
+
+#include <video/platform_lcd.h>
+
+#define UCON S3C2410_UCON_DEFAULT
+#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
+#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
+
+static struct s3c2410_uartcfg smartq_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+static void smartq_usb_host_powercontrol(int port, int to)
+{
+ pr_debug("%s(%d, %d)\n", __func__, port, to);
+
+ if (port == 0) {
+ gpio_set_value(S3C64XX_GPL(0), to);
+ gpio_set_value(S3C64XX_GPL(1), to);
+ }
+}
+
+static irqreturn_t smartq_usb_host_ocirq(int irq, void *pw)
+{
+ struct s3c2410_hcd_info *info = pw;
+
+ if (gpio_get_value(S3C64XX_GPL(10)) == 0) {
+ pr_debug("%s: over-current irq (oc detected)\n", __func__);
+ s3c2410_usb_report_oc(info, 3);
+ } else {
+ pr_debug("%s: over-current irq (oc cleared)\n", __func__);
+ s3c2410_usb_report_oc(info, 0);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void smartq_usb_host_enableoc(struct s3c2410_hcd_info *info, int on)
+{
+ int ret;
+
+ /* This isn't present on a SmartQ 5 board */
+ if (machine_is_smartq5())
+ return;
+
+ if (on) {
+ ret = request_irq(gpio_to_irq(S3C64XX_GPL(10)),
+ smartq_usb_host_ocirq, IRQF_DISABLED |
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "USB host overcurrent", info);
+ if (ret != 0)
+ pr_err("failed to request usb oc irq: %d\n", ret);
+ } else {
+ free_irq(gpio_to_irq(S3C64XX_GPL(10)), info);
+ }
+}
+
+static struct s3c2410_hcd_info smartq_usb_host_info = {
+ .port[0] = {
+ .flags = S3C_HCDFLG_USED
+ },
+ .port[1] = {
+ .flags = 0
+ },
+
+ .power_control = smartq_usb_host_powercontrol,
+ .enable_oc = smartq_usb_host_enableoc,
+};
+
+static struct gpio_vbus_mach_info smartq_usb_otg_vbus_pdata = {
+ .gpio_vbus = S3C64XX_GPL(9),
+ .gpio_pullup = -1,
+ .gpio_vbus_inverted = true,
+};
+
+static struct platform_device smartq_usb_otg_vbus_dev = {
+ .name = "gpio-vbus",
+ .dev.platform_data = &smartq_usb_otg_vbus_pdata,
+};
+
+static int smartq_bl_init(struct device *dev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
+
+ return 0;
+}
+
+static struct platform_pwm_backlight_data smartq_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 1000,
+ .dft_brightness = 600,
+ .pwm_period_ns = 1000000000 / (1000 * 20),
+ .init = smartq_bl_init,
+};
+
+static struct platform_device smartq_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[1].dev,
+ .platform_data = &smartq_backlight_data,
+ },
+};
+
+static struct s3c2410_ts_mach_info smartq_touchscreen_pdata __initdata = {
+ .delay = 65535,
+ .presc = 99,
+ .oversampling_shift = 4,
+};
+
+static struct s3c_sdhci_platdata smartq_internal_hsmmc_pdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+};
+
+static struct s3c_hwmon_pdata smartq_hwmon_pdata __initdata = {
+ /* Battery voltage (?-4.2V) */
+ .in[0] = &(struct s3c_hwmon_chcfg) {
+ .name = "smartq:battery-voltage",
+ .mult = 3300,
+ .div = 2048,
+ },
+ /* Reference voltage (1.2V) */
+ .in[1] = &(struct s3c_hwmon_chcfg) {
+ .name = "smartq:reference-voltage",
+ .mult = 3300,
+ .div = 4096,
+ },
+};
+
+static int __init smartq_lcd_setup_gpio(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPM(3), "LCD power");
+ if (ret < 0)
+ return ret;
+
+ /* turn power off */
+ gpio_direction_output(S3C64XX_GPM(3), 0);
+
+ return 0;
+}
+
+/* GPM0 -> CS */
+static struct spi_gpio_platform_data smartq_lcd_control = {
+ .sck = S3C64XX_GPM(1),
+ .mosi = S3C64XX_GPM(2),
+ .miso = S3C64XX_GPM(2),
+};
+
+static struct platform_device smartq_lcd_control_device = {
+ .name = "spi-gpio",
+ .id = 1,
+ .dev.platform_data = &smartq_lcd_control,
+};
+
+static void smartq_lcd_power_set(struct plat_lcd_data *pd, unsigned int power)
+{
+ gpio_direction_output(S3C64XX_GPM(3), power);
+}
+
+static struct plat_lcd_data smartq_lcd_power_data = {
+ .set_power = smartq_lcd_power_set,
+};
+
+static struct platform_device smartq_lcd_power_device = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smartq_lcd_power_data,
+};
+
+static struct i2c_board_info smartq_i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8987", 0x1a), },
+};
+
+static struct platform_device *smartq_devices[] __initdata = {
+ &s3c_device_hsmmc1, /* Init iNAND first, ... */
+ &s3c_device_hsmmc0, /* ... then the external SD card */
+ &s3c_device_hsmmc2,
+ &s3c_device_adc,
+ &s3c_device_fb,
+ &s3c_device_hwmon,
+ &s3c_device_i2c0,
+ &s3c_device_ohci,
+ &s3c_device_rtc,
+ &s3c_device_timer[1],
+ &s3c_device_ts,
+ &s3c_device_usb_hsotg,
+ &s3c64xx_device_iis0,
+ &smartq_backlight_device,
+ &smartq_lcd_control_device,
+ &smartq_lcd_power_device,
+ &smartq_usb_otg_vbus_dev,
+};
+
+static void __init smartq_lcd_mode_set(void)
+{
+ u32 tmp;
+
+ /* set the LCD type */
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the LCD bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void smartq_power_off(void)
+{
+ gpio_direction_output(S3C64XX_GPK(15), 1);
+}
+
+static int __init smartq_power_off_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPK(15), "Power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK15\n", __func__);
+ return ret;
+ }
+
+ /* leave power on */
+ gpio_direction_output(S3C64XX_GPK(15), 0);
+
+ pm_power_off = smartq_power_off;
+
+ return ret;
+}
+
+static int __init smartq_usb_host_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPL(0), "USB power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL0\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_request(S3C64XX_GPL(1), "USB host power control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL1\n", __func__);
+ goto err;
+ }
+
+ if (!machine_is_smartq5()) {
+ /* This isn't present on a SmartQ 5 board */
+ ret = gpio_request(S3C64XX_GPL(10), "USB host overcurrent");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPL10\n", __func__);
+ goto err2;
+ }
+ }
+
+ /* turn power off */
+ gpio_direction_output(S3C64XX_GPL(0), 0);
+ gpio_direction_output(S3C64XX_GPL(1), 0);
+ if (!machine_is_smartq5())
+ gpio_direction_input(S3C64XX_GPL(10));
+
+ s3c_device_ohci.dev.platform_data = &smartq_usb_host_info;
+
+ return 0;
+
+err2:
+ gpio_free(S3C64XX_GPL(1));
+err:
+ gpio_free(S3C64XX_GPL(0));
+ return ret;
+}
+
+static int __init smartq_usb_otg_init(void)
+{
+ clk_xusbxti.rate = 12000000;
+
+ return 0;
+}
+
+static int __init smartq_wifi_init(void)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPK(1), "wifi control");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK1\n", __func__);
+ return ret;
+ }
+
+ ret = gpio_request(S3C64XX_GPK(2), "wifi reset");
+ if (ret < 0) {
+ pr_err("%s: failed to get GPK2\n", __func__);
+ gpio_free(S3C64XX_GPK(1));
+ return ret;
+ }
+
+ /* turn power on */
+ gpio_direction_output(S3C64XX_GPK(1), 1);
+
+ /* reset device */
+ gpio_direction_output(S3C64XX_GPK(2), 0);
+ mdelay(100);
+ gpio_set_value(S3C64XX_GPK(2), 1);
+ gpio_direction_input(S3C64XX_GPK(2));
+
+ return 0;
+}
+
+static struct map_desc smartq_iodesc[] __initdata = {};
+void __init smartq_map_io(void)
+{
+ s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
+
+ smartq_lcd_mode_set();
+}
+
+void __init smartq_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_hwmon_set_platdata(&smartq_hwmon_pdata);
+ s3c_sdhci1_set_platdata(&smartq_internal_hsmmc_pdata);
+ s3c_sdhci2_set_platdata(&smartq_internal_hsmmc_pdata);
+ s3c24xx_ts_set_platdata(&smartq_touchscreen_pdata);
+
+ i2c_register_board_info(0, smartq_i2c_devs,
+ ARRAY_SIZE(smartq_i2c_devs));
+
+ WARN_ON(smartq_lcd_setup_gpio());
+ WARN_ON(smartq_power_off_init());
+ WARN_ON(smartq_usb_host_init());
+ WARN_ON(smartq_usb_otg_init());
+ WARN_ON(smartq_wifi_init());
+
+ platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
+}
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.h b/arch/arm/mach-s3c64xx/mach-smartq.h
new file mode 100644
index 00000000..8e8b693d
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq.h
@@ -0,0 +1,20 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq.h
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can 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_SMARTQ_H
+#define __MACH_SMARTQ_H __FILE__
+
+#include <linux/init.h>
+
+extern void __init smartq_map_io(void);
+extern void __init smartq_machine_init(void);
+
+#endif /* __MACH_SMARTQ_H */
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
new file mode 100644
index 00000000..3a3e5acd
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -0,0 +1,154 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq5.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can 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/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/s3c6410.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include "mach-smartq.h"
+
+static struct gpio_led smartq5_leds[] = {
+ {
+ .name = "smartq5:green",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(8),
+ },
+ {
+ .name = "smartq5:red",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(9),
+ },
+};
+
+static struct gpio_led_platform_data smartq5_led_data = {
+ .num_leds = ARRAY_SIZE(smartq5_leds),
+ .leds = smartq5_leds,
+};
+
+static struct platform_device smartq5_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &smartq5_led_data,
+};
+
+/* Labels according to the SmartQ manual */
+static struct gpio_keys_button smartq5_buttons[] = {
+ {
+ .gpio = S3C64XX_GPL(14),
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(2),
+ .code = KEY_KPMINUS,
+ .desc = "Minus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(12),
+ .code = KEY_KPPLUS,
+ .desc = "Plus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(15),
+ .code = KEY_ENTER,
+ .desc = "Move",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data smartq5_buttons_data = {
+ .buttons = smartq5_buttons,
+ .nbuttons = ARRAY_SIZE(smartq5_buttons),
+};
+
+static struct platform_device smartq5_buttons_device = {
+ .name = "gpio-keys",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &smartq5_buttons_data,
+ }
+};
+
+static struct s3c_fb_pd_win smartq5_fb_win0 = {
+ .win_mode = {
+ .left_margin = 216,
+ .right_margin = 40,
+ .upper_margin = 35,
+ .lower_margin = 10,
+ .hsync_len = 1,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_platdata smartq5_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &smartq5_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+ VIDCON1_INV_VDEN,
+};
+
+static struct platform_device *smartq5_devices[] __initdata = {
+ &smartq5_leds_device,
+ &smartq5_buttons_device,
+};
+
+static void __init smartq5_machine_init(void)
+{
+ s3c_fb_set_platdata(&smartq5_lcd_pdata);
+
+ smartq_machine_init();
+
+ platform_add_devices(smartq5_devices, ARRAY_SIZE(smartq5_devices));
+}
+
+MACHINE_START(SMARTQ5, "SmartQ 5")
+ /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq5_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
new file mode 100644
index 00000000..e6537587
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mach-s3c64xx/mach-smartq7.c
+ *
+ * Copyright (C) 2010 Maurus Cuelenaere
+ *
+ * This program is free software; you can 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/fb.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+#include <mach/s3c6410.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include "mach-smartq.h"
+
+static struct gpio_led smartq7_leds[] = {
+ {
+ .name = "smartq7:red",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(8),
+ },
+ {
+ .name = "smartq7:green",
+ .active_low = 1,
+ .gpio = S3C64XX_GPN(9),
+ },
+};
+
+static struct gpio_led_platform_data smartq7_led_data = {
+ .num_leds = ARRAY_SIZE(smartq7_leds),
+ .leds = smartq7_leds,
+};
+
+static struct platform_device smartq7_leds_device = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev.platform_data = &smartq7_led_data,
+};
+
+/* Labels according to the SmartQ manual */
+static struct gpio_keys_button smartq7_buttons[] = {
+ {
+ .gpio = S3C64XX_GPL(14),
+ .code = KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(2),
+ .code = KEY_FN,
+ .desc = "Function",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(3),
+ .code = KEY_KPMINUS,
+ .desc = "Minus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(4),
+ .code = KEY_KPPLUS,
+ .desc = "Plus",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(12),
+ .code = KEY_ENTER,
+ .desc = "Enter",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+ {
+ .gpio = S3C64XX_GPN(15),
+ .code = KEY_ESC,
+ .desc = "Cancel",
+ .active_low = 1,
+ .debounce_interval = 5,
+ .type = EV_KEY,
+ },
+};
+
+static struct gpio_keys_platform_data smartq7_buttons_data = {
+ .buttons = smartq7_buttons,
+ .nbuttons = ARRAY_SIZE(smartq7_buttons),
+};
+
+static struct platform_device smartq7_buttons_device = {
+ .name = "gpio-keys",
+ .id = 0,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &smartq7_buttons_data,
+ }
+};
+
+static struct s3c_fb_pd_win smartq7_fb_win0 = {
+ .win_mode = {
+ .left_margin = 3,
+ .right_margin = 5,
+ .upper_margin = 1,
+ .lower_margin = 20,
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_platdata smartq7_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &smartq7_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+ VIDCON1_INV_VCLK,
+};
+
+static struct platform_device *smartq7_devices[] __initdata = {
+ &smartq7_leds_device,
+ &smartq7_buttons_device,
+};
+
+static void __init smartq7_machine_init(void)
+{
+ s3c_fb_set_platdata(&smartq7_lcd_pdata);
+
+ smartq_machine_init();
+
+ platform_add_devices(smartq7_devices, ARRAY_SIZE(smartq7_devices));
+}
+
+MACHINE_START(SMARTQ7, "SmartQ 7")
+ /* Maintainer: Maurus Cuelenaere <mcuelenaere AT gmail DOT com> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+ .init_irq = s3c6410_init_irq,
+ .map_io = smartq_map_io,
+ .init_machine = smartq7_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c
new file mode 100644
index 00000000..3cca642f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c
@@ -0,0 +1,94 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6400.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+
+#include <mach/s3c6400.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6400_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = 0x3c5,
+ .ulcon = 0x03,
+ .ufcon = 0x51,
+ },
+};
+
+static struct map_desc smdk6400_iodesc[] = {};
+
+static void __init smdk6400_map_io(void)
+{
+ s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+}
+
+static struct platform_device *smdk6400_devices[] __initdata = {
+ &s3c_device_hsmmc1,
+ &s3c_device_i2c0,
+};
+
+static struct i2c_board_info i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8753", 0x1A), },
+ { I2C_BOARD_INFO("24c08", 0x50), },
+};
+
+static void __init smdk6400_machine_init(void)
+{
+ i2c_register_board_info(0, i2c_devs, ARRAY_SIZE(i2c_devs));
+ platform_add_devices(smdk6400_devices, ARRAY_SIZE(smdk6400_devices));
+}
+
+MACHINE_START(SMDK6400, "SMDK6400")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6400_init_irq,
+ .map_io = smdk6400_map_io,
+ .init_machine = smdk6400_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
new file mode 100644
index 00000000..2c0353a8
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -0,0 +1,754 @@
+/* linux/arch/arm/mach-s3c64xx/mach-smdk6410.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/pwm_backlight.h>
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+#include <linux/mfd/wm8350/core.h>
+#include <linux/mfd/wm8350/pmic.h>
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+#endif
+
+#include <video/platform_lcd.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-fb.h>
+#include <mach/map.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-modem.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-sys.h>
+#include <mach/regs-srom.h>
+#include <plat/ata.h>
+#include <plat/iic.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#include <mach/s3c6410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/keypad.h>
+
+#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
+#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
+#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg smdk6410_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = UCON,
+ .ulcon = ULCON,
+ .ufcon = UFCON,
+ },
+};
+
+/* framebuffer and LCD setup. */
+
+/* GPF15 = LCD backlight control
+ * GPF13 => Panel power
+ * GPN5 = LCD nRESET signal
+ * PWM_TOUT1 => backlight brightness
+ */
+
+static void smdk6410_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ gpio_direction_output(S3C64XX_GPF(13), 1);
+
+ /* fire nRESET on power up */
+ gpio_direction_output(S3C64XX_GPN(5), 0);
+ msleep(10);
+ gpio_direction_output(S3C64XX_GPN(5), 1);
+ msleep(1);
+ } else {
+ gpio_direction_output(S3C64XX_GPF(13), 0);
+ }
+}
+
+static struct plat_lcd_data smdk6410_lcd_power_data = {
+ .set_power = smdk6410_lcd_power_set,
+};
+
+static struct platform_device smdk6410_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdk6410_lcd_power_data,
+};
+
+static struct s3c_fb_pd_win smdk6410_fb_win0 = {
+ /* this is to ensure we use win0 */
+ .win_mode = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .virtual_y = 480 * 2,
+ .virtual_x = 800,
+};
+
+/* 405566 clocks per frame => 60Hz refresh requires 24333960Hz clock */
+static struct s3c_fb_platdata smdk6410_lcd_pdata __initdata = {
+ .setup_gpio = s3c64xx_fb_gpio_setup_24bpp,
+ .win[0] = &smdk6410_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+};
+
+/*
+ * Configuring Ethernet on SMDK6410
+ *
+ * Both CS8900A and LAN9115 chips share one chip select mediated by CFG6.
+ * The constant address below corresponds to nCS1
+ *
+ * 1) Set CFGB2 p3 ON others off, no other CFGB selects "ethernet"
+ * 2) CFG6 needs to be switched to "LAN9115" side
+ */
+
+static struct resource smdk6410_smsc911x_resources[] = {
+ [0] = {
+ .start = S3C64XX_PA_XM0CSN1,
+ .end = S3C64XX_PA_XM0CSN1 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C_EINT(10),
+ .end = S3C_EINT(10),
+ .flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
+ },
+};
+
+static struct smsc911x_platform_config smdk6410_smsc911x_pdata = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+
+static struct platform_device smdk6410_smsc911x = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdk6410_smsc911x_resources),
+ .resource = &smdk6410_smsc911x_resources[0],
+ .dev = {
+ .platform_data = &smdk6410_smsc911x_pdata,
+ },
+};
+
+#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_init_data smdk6410_b_pwr_5v_data = {
+ .constraints = {
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_b_pwr_5v_consumers),
+ .consumer_supplies = smdk6410_b_pwr_5v_consumers,
+};
+
+static struct fixed_voltage_config smdk6410_b_pwr_5v_pdata = {
+ .supply_name = "B_PWR_5V",
+ .microvolts = 5000000,
+ .init_data = &smdk6410_b_pwr_5v_data,
+ .gpio = -EINVAL,
+};
+
+static struct platform_device smdk6410_b_pwr_5v = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .dev = {
+ .platform_data = &smdk6410_b_pwr_5v_pdata,
+ },
+};
+#endif
+
+static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
+ .setup_gpio = s3c64xx_ide_setup_gpio,
+};
+
+static uint32_t smdk6410_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 smdk6410_keymap_data __initdata = {
+ .keymap = smdk6410_keymap,
+ .keymap_size = ARRAY_SIZE(smdk6410_keymap),
+};
+
+static struct samsung_keypad_platdata smdk6410_keypad_data __initdata = {
+ .keymap_data = &smdk6410_keymap_data,
+ .rows = 2,
+ .cols = 8,
+};
+
+static int smdk6410_backlight_init(struct device *dev)
+{
+ int ret;
+
+ ret = gpio_request(S3C64XX_GPF(15), "Backlight");
+ if (ret) {
+ printk(KERN_ERR "failed to request GPF for PWM-OUT1\n");
+ return ret;
+ }
+
+ /* Configure GPIO pin with S3C64XX_GPF15_PWM_TOUT1 */
+ s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2));
+
+ return 0;
+}
+
+static void smdk6410_backlight_exit(struct device *dev)
+{
+ s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_OUTPUT);
+ gpio_free(S3C64XX_GPF(15));
+}
+
+static struct platform_pwm_backlight_data smdk6410_backlight_data = {
+ .pwm_id = 1,
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .pwm_period_ns = 78770,
+ .init = smdk6410_backlight_init,
+ .exit = smdk6410_backlight_exit,
+};
+
+static struct platform_device smdk6410_backlight_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .parent = &s3c_device_timer[1].dev,
+ .platform_data = &smdk6410_backlight_data,
+ },
+};
+
+static struct map_desc smdk6410_iodesc[] = {};
+
+static struct platform_device *smdk6410_devices[] __initdata = {
+#ifdef CONFIG_SMDK6410_SD_CH0
+ &s3c_device_hsmmc0,
+#endif
+#ifdef CONFIG_SMDK6410_SD_CH1
+ &s3c_device_hsmmc1,
+#endif
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_ohci,
+ &s3c_device_usb_hsotg,
+ &samsung_asoc_dma,
+ &s3c64xx_device_iisv4,
+ &samsung_device_keypad,
+
+#ifdef CONFIG_REGULATOR
+ &smdk6410_b_pwr_5v,
+#endif
+ &smdk6410_lcd_powerdev,
+
+ &smdk6410_smsc911x,
+ &s3c_device_adc,
+ &s3c_device_cfcon,
+ &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",
+ }
+};
+
+/* VDDARM, BUCK1 on J5 */
+static struct regulator_init_data smdk6410_vddarm = {
+ .constraints = {
+ .name = "PVDD_ARM",
+ .min_uV = 1000000,
+ .max_uV = 1300000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(smdk6410_vddarm_consumers),
+ .consumer_supplies = smdk6410_vddarm_consumers,
+};
+
+/* VDD_INT, BUCK2 on J5 */
+static struct regulator_init_data smdk6410_vddint = {
+ .constraints = {
+ .name = "PVDD_INT",
+ .min_uV = 1000000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
+ },
+};
+
+/* VDD_HI, LDO3 on J5 */
+static struct regulator_init_data smdk6410_vddhi = {
+ .constraints = {
+ .name = "PVDD_HI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_PLL, LDO2 on J5 */
+static struct regulator_init_data smdk6410_vddpll = {
+ .constraints = {
+ .name = "PVDD_PLL",
+ .always_on = 1,
+ },
+};
+
+/* VDD_UH_MMC, LDO5 on J5 */
+static struct regulator_init_data smdk6410_vdduh_mmc = {
+ .constraints = {
+ .name = "PVDD_UH+PVDD_MMC",
+ .always_on = 1,
+ },
+};
+
+/* VCCM3BT, LDO8 on J5 */
+static struct regulator_init_data smdk6410_vccmc3bt = {
+ .constraints = {
+ .name = "PVCCM3BT",
+ .always_on = 1,
+ },
+};
+
+/* VCCM2MTV, LDO11 on J5 */
+static struct regulator_init_data smdk6410_vccm2mtv = {
+ .constraints = {
+ .name = "PVCCM2MTV",
+ .always_on = 1,
+ },
+};
+
+/* VDD_LCD, LDO12 on J5 */
+static struct regulator_init_data smdk6410_vddlcd = {
+ .constraints = {
+ .name = "PVDD_LCD",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTGI, LDO9 on J5 */
+static struct regulator_init_data smdk6410_vddotgi = {
+ .constraints = {
+ .name = "PVDD_OTGI",
+ .always_on = 1,
+ },
+};
+
+/* VDD_OTG, LDO14 on J5 */
+static struct regulator_init_data smdk6410_vddotg = {
+ .constraints = {
+ .name = "PVDD_OTG",
+ .always_on = 1,
+ },
+};
+
+/* VDD_ALIVE, LDO15 on J5 */
+static struct regulator_init_data smdk6410_vddalive = {
+ .constraints = {
+ .name = "PVDD_ALIVE",
+ .always_on = 1,
+ },
+};
+
+/* VDD_AUDIO, VLDO_AUDIO on J5 */
+static struct regulator_init_data smdk6410_vddaudio = {
+ .constraints = {
+ .name = "PVDD_AUDIO",
+ .always_on = 1,
+ },
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+/* S3C64xx internal logic & PLL */
+static struct regulator_init_data wm8350_dcdc1_data = {
+ .constraints = {
+ .name = "PVDD_INT+PVDD_PLL",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .always_on = 1,
+ .apply_uV = 1,
+ },
+};
+
+/* Memory */
+static struct regulator_init_data wm8350_dcdc3_data = {
+ .constraints = {
+ .name = "PVDD_MEM",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .always_on = 1,
+ .state_mem = {
+ .uV = 1800000,
+ .mode = REGULATOR_MODE_NORMAL,
+ .enabled = 1,
+ },
+ .initial_state = PM_SUSPEND_MEM,
+ },
+};
+
+/* USB, EXT, PCM, ADC/DAC, USB, MMC */
+static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = {
+ {
+ /* WM8580 */
+ .supply = "DVDD",
+ .dev_name = "0-001b",
+ },
+};
+
+static struct regulator_init_data wm8350_dcdc4_data = {
+ .constraints = {
+ .name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .always_on = 1,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(wm8350_dcdc4_consumers),
+ .consumer_supplies = wm8350_dcdc4_consumers,
+};
+
+/* OTGi/1190-EV1 HPVDD & AVDD */
+static struct regulator_init_data wm8350_ldo4_data = {
+ .constraints = {
+ .name = "PVDD_OTGI+HPVDD+AVDD",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct {
+ int regulator;
+ struct regulator_init_data *initdata;
+} wm1190_regulators[] = {
+ { WM8350_DCDC_1, &wm8350_dcdc1_data },
+ { WM8350_DCDC_3, &wm8350_dcdc3_data },
+ { WM8350_DCDC_4, &wm8350_dcdc4_data },
+ { WM8350_DCDC_6, &smdk6410_vddarm },
+ { WM8350_LDO_1, &smdk6410_vddalive },
+ { WM8350_LDO_2, &smdk6410_vddotg },
+ { WM8350_LDO_3, &smdk6410_vddlcd },
+ { WM8350_LDO_4, &wm8350_ldo4_data },
+};
+
+static int __init smdk6410_wm8350_init(struct wm8350 *wm8350)
+{
+ int i;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ /* Instantiate the regulators */
+ for (i = 0; i < ARRAY_SIZE(wm1190_regulators); i++)
+ wm8350_register_regulator(wm8350,
+ wm1190_regulators[i].regulator,
+ wm1190_regulators[i].initdata);
+
+ return 0;
+}
+
+static struct wm8350_platform_data __initdata smdk6410_wm8350_pdata = {
+ .init = smdk6410_wm8350_init,
+ .irq_high = 1,
+ .irq_base = IRQ_BOARD_START,
+};
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+static struct gpio_led wm1192_pmic_leds[] = {
+ {
+ .name = "PMIC:red:power",
+ .gpio = GPIO_BOARD_START + 3,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+};
+
+static struct gpio_led_platform_data wm1192_pmic_led = {
+ .num_leds = ARRAY_SIZE(wm1192_pmic_leds),
+ .leds = wm1192_pmic_leds,
+};
+
+static struct platform_device wm1192_pmic_led_dev = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &wm1192_pmic_led,
+ },
+};
+
+static int wm1192_pre_init(struct wm831x *wm831x)
+{
+ int ret;
+
+ /* Configure the IRQ line */
+ s3c_gpio_setpull(S3C64XX_GPN(12), S3C_GPIO_PULL_UP);
+
+ ret = platform_device_register(&wm1192_pmic_led_dev);
+ if (ret != 0)
+ dev_err(wm831x->dev, "Failed to add PMIC LED: %d\n", ret);
+
+ return 0;
+}
+
+static struct wm831x_backlight_pdata wm1192_backlight_pdata = {
+ .isink = 1,
+ .max_uA = 27554,
+};
+
+static struct regulator_init_data wm1192_dcdc3 = {
+ .constraints = {
+ .name = "PVDD_MEM+PVDD_GPS",
+ .always_on = 1,
+ },
+};
+
+static struct regulator_consumer_supply wm1192_ldo1_consumers[] = {
+ { .supply = "DVDD", .dev_name = "0-001b", }, /* WM8580 */
+};
+
+static struct regulator_init_data wm1192_ldo1 = {
+ .constraints = {
+ .name = "PVDD_LCD+PVDD_EXT",
+ .always_on = 1,
+ },
+ .consumer_supplies = wm1192_ldo1_consumers,
+ .num_consumer_supplies = ARRAY_SIZE(wm1192_ldo1_consumers),
+};
+
+static struct wm831x_status_pdata wm1192_led7_pdata = {
+ .name = "LED7:green:",
+};
+
+static struct wm831x_status_pdata wm1192_led8_pdata = {
+ .name = "LED8:green:",
+};
+
+static struct wm831x_pdata smdk6410_wm1192_pdata = {
+ .pre_init = wm1192_pre_init,
+ .irq_base = IRQ_BOARD_START,
+
+ .backlight = &wm1192_backlight_pdata,
+ .dcdc = {
+ &smdk6410_vddarm, /* DCDC1 */
+ &smdk6410_vddint, /* DCDC2 */
+ &wm1192_dcdc3,
+ },
+ .gpio_base = GPIO_BOARD_START,
+ .ldo = {
+ &wm1192_ldo1, /* LDO1 */
+ &smdk6410_vdduh_mmc, /* LDO2 */
+ NULL, /* LDO3 NC */
+ &smdk6410_vddotgi, /* LDO4 */
+ &smdk6410_vddotg, /* LDO5 */
+ &smdk6410_vddhi, /* LDO6 */
+ &smdk6410_vddaudio, /* LDO7 */
+ &smdk6410_vccm2mtv, /* LDO8 */
+ &smdk6410_vddpll, /* LDO9 */
+ &smdk6410_vccmc3bt, /* LDO10 */
+ &smdk6410_vddalive, /* LDO11 */
+ },
+ .status = {
+ &wm1192_led7_pdata,
+ &wm1192_led8_pdata,
+ },
+};
+#endif
+
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+
+#ifdef CONFIG_SMDK6410_WM1192_EV1
+ { I2C_BOARD_INFO("wm8312", 0x34),
+ .platform_data = &smdk6410_wm1192_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+
+#ifdef CONFIG_SMDK6410_WM1190_EV1
+ { I2C_BOARD_INFO("wm8350", 0x1a),
+ .platform_data = &smdk6410_wm8350_pdata,
+ .irq = S3C_EINT(12),
+ },
+#endif
+};
+
+static struct i2c_board_info i2c_devs1[] __initdata = {
+ { I2C_BOARD_INFO("24c128", 0x57), }, /* Samsung S524AD0XD1 */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdk6410_map_io(void)
+{
+ u32 tmp;
+
+ s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+
+ /* set the LCD type */
+
+ tmp = __raw_readl(S3C64XX_SPCON);
+ tmp &= ~S3C64XX_SPCON_LCD_SEL_MASK;
+ tmp |= S3C64XX_SPCON_LCD_SEL_RGB;
+ __raw_writel(tmp, S3C64XX_SPCON);
+
+ /* remove the lcd bypass */
+ tmp = __raw_readl(S3C64XX_MODEM_MIFPCON);
+ tmp &= ~MIFPCON_LCD_BYPASS;
+ __raw_writel(tmp, S3C64XX_MODEM_MIFPCON);
+}
+
+static void __init smdk6410_machine_init(void)
+{
+ u32 cs1;
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_fb_set_platdata(&smdk6410_lcd_pdata);
+
+ samsung_keypad_set_platdata(&smdk6410_keypad_data);
+
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ /* configure nCS1 width to 16 bits */
+
+ cs1 = __raw_readl(S3C64XX_SROM_BW) &
+ ~(S3C64XX_SROM_BW__CS_MASK << S3C64XX_SROM_BW__NCS1__SHIFT);
+ cs1 |= ((1 << S3C64XX_SROM_BW__DATAWIDTH__SHIFT) |
+ (1 << S3C64XX_SROM_BW__WAITENABLE__SHIFT) |
+ (1 << S3C64XX_SROM_BW__BYTEENABLE__SHIFT)) <<
+ S3C64XX_SROM_BW__NCS1__SHIFT;
+ __raw_writel(cs1, S3C64XX_SROM_BW);
+
+ /* set timing for nCS1 suitable for ethernet chip */
+
+ __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) |
+ (6 << S3C64XX_SROM_BCX__TACP__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) |
+ (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) |
+ (0xe << S3C64XX_SROM_BCX__TACC__SHIFT) |
+ (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) |
+ (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1);
+
+ gpio_request(S3C64XX_GPN(5), "LCD power");
+ gpio_request(S3C64XX_GPF(13), "LCD power");
+
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ s3c_ide_set_platdata(&smdk6410_ide_pdata);
+
+ platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
+}
+
+MACHINE_START(SMDK6410, "SMDK6410")
+ /* Maintainer: Ben Dooks <ben-linux@fluff.org> */
+ .boot_params = S3C64XX_PA_SDRAM + 0x100,
+
+ .init_irq = s3c6410_init_irq,
+ .map_io = smdk6410_map_io,
+ .init_machine = smdk6410_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c
new file mode 100644
index 00000000..bc1c470b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/pm.c
@@ -0,0 +1,197 @@
+/* linux/arch/arm/plat-s3c64xx/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU PM support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/pm.h>
+#include <plat/wakeup-mask.h>
+
+#include <mach/regs-sys.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-syscon-power.h>
+#include <mach/regs-gpio-memport.h>
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+void s3c_pm_debug_smdkled(u32 set, u32 clear)
+{
+ unsigned long flags;
+ int i;
+
+ local_irq_save(flags);
+ for (i = 0; i < 4; i++) {
+ if (clear & (1 << i))
+ gpio_set_value(S3C64XX_GPN(12 + i), 0);
+ if (set & (1 << i))
+ gpio_set_value(S3C64XX_GPN(12 + i), 1);
+ }
+ local_irq_restore(flags);
+}
+#endif
+
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C_APLL_LOCK),
+ SAVE_ITEM(S3C_MPLL_LOCK),
+ SAVE_ITEM(S3C_EPLL_LOCK),
+ SAVE_ITEM(S3C_CLK_SRC),
+ SAVE_ITEM(S3C_CLK_DIV0),
+ SAVE_ITEM(S3C_CLK_DIV1),
+ SAVE_ITEM(S3C_CLK_DIV2),
+ SAVE_ITEM(S3C_CLK_OUT),
+ SAVE_ITEM(S3C_HCLK_GATE),
+ SAVE_ITEM(S3C_PCLK_GATE),
+ SAVE_ITEM(S3C_SCLK_GATE),
+ SAVE_ITEM(S3C_MEM0_GATE),
+
+ SAVE_ITEM(S3C_EPLL_CON1),
+ SAVE_ITEM(S3C_EPLL_CON0),
+
+ SAVE_ITEM(S3C64XX_MEM0DRVCON),
+ SAVE_ITEM(S3C64XX_MEM1DRVCON),
+
+#ifndef CONFIG_CPU_FREQ
+ SAVE_ITEM(S3C_APLL_CON),
+ SAVE_ITEM(S3C_MPLL_CON),
+#endif
+};
+
+static struct sleep_save misc_save[] = {
+ SAVE_ITEM(S3C64XX_AHB_CON0),
+ SAVE_ITEM(S3C64XX_AHB_CON1),
+ SAVE_ITEM(S3C64XX_AHB_CON2),
+
+ SAVE_ITEM(S3C64XX_SPCON),
+
+ SAVE_ITEM(S3C64XX_MEM0CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM1CONSTOP),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP0),
+ SAVE_ITEM(S3C64XX_MEM0CONSLP1),
+ SAVE_ITEM(S3C64XX_MEM1CONSLP),
+};
+
+void s3c_pm_configure_extint(void)
+{
+ __raw_writel(s3c_irqwake_eintmask, S3C64XX_EINT_MASK);
+}
+
+void s3c_pm_restore_core(void)
+{
+ __raw_writel(0, S3C64XX_EINT_MASK);
+
+ s3c_pm_debug_smdkled(1 << 2, 0);
+
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+
+/* since both s3c6400 and s3c6410 share the same sleep pm calls, we
+ * put the per-cpu code in here until any new cpu comes along and changes
+ * this.
+ */
+
+static void s3c64xx_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ /* set our standby method to sleep */
+
+ tmp = __raw_readl(S3C64XX_PWR_CFG);
+ tmp &= ~S3C64XX_PWRCFG_CFG_WFI_MASK;
+ tmp |= S3C64XX_PWRCFG_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S3C64XX_PWR_CFG);
+
+ /* clear any old wakeup */
+
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT),
+ S3C64XX_WAKEUP_STAT);
+
+ /* set the LED state to 0110 over sleep */
+ s3c_pm_debug_smdkled(3 << 1, 0xf);
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp));
+
+ /* we should never get past here */
+
+ panic("sleep resumed to originator?");
+}
+
+/* mapping of interrupts to parts of the wakeup mask */
+static struct samsung_wakeup_mask wake_irqs[] = {
+ { .irq = IRQ_RTC_ALARM, .bit = S3C64XX_PWRCFG_RTC_ALARM_DISABLE, },
+ { .irq = IRQ_RTC_TIC, .bit = S3C64XX_PWRCFG_RTC_TICK_DISABLE, },
+ { .irq = IRQ_PENDN, .bit = S3C64XX_PWRCFG_TS_DISABLE, },
+ { .irq = IRQ_HSMMC0, .bit = S3C64XX_PWRCFG_MMC0_DISABLE, },
+ { .irq = IRQ_HSMMC1, .bit = S3C64XX_PWRCFG_MMC1_DISABLE, },
+ { .irq = IRQ_HSMMC2, .bit = S3C64XX_PWRCFG_MMC2_DISABLE, },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_BATF_DISABLE},
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_MSM_DISABLE },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_HSI_DISABLE },
+ { .irq = NO_WAKEUP_IRQ, .bit = S3C64XX_PWRCFG_MSM_DISABLE },
+};
+
+static void s3c64xx_pm_prepare(void)
+{
+ samsung_sync_wakemask(S3C64XX_PWR_CFG,
+ wake_irqs, ARRAY_SIZE(wake_irqs));
+
+ /* store address of resume. */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+
+ /* ensure previous wakeup state is cleared before sleeping */
+ __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
+}
+
+static int s3c64xx_pm_init(void)
+{
+ pm_cpu_prep = s3c64xx_pm_prepare;
+ pm_cpu_sleep = s3c64xx_cpu_suspend;
+ pm_uart_udivslot = 1;
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+ gpio_request(S3C64XX_GPN(12), "DEBUG_LED0");
+ gpio_request(S3C64XX_GPN(13), "DEBUG_LED1");
+ gpio_request(S3C64XX_GPN(14), "DEBUG_LED2");
+ gpio_request(S3C64XX_GPN(15), "DEBUG_LED3");
+ gpio_direction_output(S3C64XX_GPN(12), 0);
+ gpio_direction_output(S3C64XX_GPN(13), 0);
+ gpio_direction_output(S3C64XX_GPN(14), 0);
+ gpio_direction_output(S3C64XX_GPN(15), 0);
+#endif
+
+ return 0;
+}
+
+arch_initcall(s3c64xx_pm_init);
diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c
new file mode 100644
index 00000000..5e93fe3f
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6400.c
@@ -0,0 +1,93 @@
+/* linux/arch/arm/mach-s3c64xx/cpu.c
+ *
+ * Copyright 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+#include <mach/s3c6400.h>
+
+void __init s3c6400_map_io(void)
+{
+ /* setup SDHCI */
+
+ s3c6400_default_sdhci0();
+ s3c6400_default_sdhci1();
+ s3c6400_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+
+ s3c_device_nand.name = "s3c6400-nand";
+
+ s3c_onenand_setname("s3c6400-onenand");
+ s3c64xx_onenand1_setname("s3c6400-onenand");
+}
+
+void __init s3c6400_init_clocks(int xtal)
+{
+ s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK);
+ s3c6400_setup_clocks();
+}
+
+void __init s3c6400_init_irq(void)
+{
+ /* VIC0 does not have IRQS 5..7,
+ * VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(0xf << 5), ~0);
+}
+
+struct sysdev_class s3c6400_sysclass = {
+ .name = "s3c6400-core",
+};
+
+static struct sys_device s3c6400_sysdev = {
+ .cls = &s3c6400_sysclass,
+};
+
+static int __init s3c6400_core_init(void)
+{
+ return sysdev_class_register(&s3c6400_sysclass);
+}
+
+core_initcall(s3c6400_core_init);
+
+int __init s3c6400_init(void)
+{
+ printk("S3C6400: Initialising architecture\n");
+
+ return sysdev_register(&s3c6400_sysdev);
+}
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
new file mode 100644
index 00000000..312aa6b1
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -0,0 +1,98 @@
+/* linux/arch/arm/mach-s3c64xx/s3c6410.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/sdhci.h>
+#include <plat/ata-core.h>
+#include <plat/adc-core.h>
+#include <plat/iic-core.h>
+#include <plat/onenand-core.h>
+#include <mach/s3c6400.h>
+#include <mach/s3c6410.h>
+
+void __init s3c6410_map_io(void)
+{
+ /* initialise device information early */
+ s3c6410_default_sdhci0();
+ s3c6410_default_sdhci1();
+ s3c6410_default_sdhci2();
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ s3c_adc_setname("s3c64xx-adc");
+ s3c_device_nand.name = "s3c6400-nand";
+ s3c_onenand_setname("s3c6410-onenand");
+ s3c64xx_onenand1_setname("s3c6410-onenand");
+ s3c_cfcon_setname("s3c64xx-pata");
+}
+
+void __init s3c6410_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initialising clocks\n", __func__);
+ s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK);
+ s3c6400_setup_clocks();
+}
+
+void __init s3c6410_init_irq(void)
+{
+ /* VIC0 is missing IRQ7, VIC1 is fully populated. */
+ s3c64xx_init_irq(~0 & ~(1 << 7), ~0);
+}
+
+struct sysdev_class s3c6410_sysclass = {
+ .name = "s3c6410-core",
+};
+
+static struct sys_device s3c6410_sysdev = {
+ .cls = &s3c6410_sysclass,
+};
+
+static int __init s3c6410_core_init(void)
+{
+ return sysdev_class_register(&s3c6410_sysclass);
+}
+
+core_initcall(s3c6410_core_init);
+
+int __init s3c6410_init(void)
+{
+ printk("S3C6410: Initialising architecture\n");
+
+ return sysdev_register(&s3c6410_sysdev);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-fb-24bpp.c b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
new file mode 100644
index 00000000..8f309118
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-fb-24bpp.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-s3c64xx/setup-fb-24bpp.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can 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 <mach/regs-fb.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+extern void s3c64xx_fb_gpio_setup_24bpp(void)
+{
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPI(0), 16, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPJ(0), 12, S3C_GPIO_SFN(2));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-i2c0.c b/arch/arm/mach-s3c64xx/setup-i2c0.c
new file mode 100644
index 00000000..241af94a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c0.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c0.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 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>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-i2c1.c b/arch/arm/mach-s3c64xx/setup-i2c1.c
new file mode 100644
index 00000000..3d13a961
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-i2c1.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Base S3C64XX I2C bus 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>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S3C64XX_GPB(2), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
new file mode 100644
index 00000000..41b42560
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-s3c64xx/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C64XX setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/ata.h>
+
+void s3c64xx_ide_setup_gpio(void)
+{
+ u32 reg;
+
+ reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
+
+ /* Independent CF interface, CF chip select configuration */
+ writel(reg | MEM_SYS_CFG_INDEP_CF |
+ MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S3C_MEM_SYS_CFG);
+
+ s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
+
+ /* Set XhiDATA[15:0] pins as CF Data[15:0] */
+ s3c_gpio_cfgpin_range(S3C64XX_GPK(0), 16, S3C_GPIO_SFN(5));
+
+ /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
+ s3c_gpio_cfgpin_range(S3C64XX_GPL(0), 3, S3C_GPIO_SFN(6));
+
+ /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
+ s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
+ s3c_gpio_cfgpin_range(S3C64XX_GPM(0), 5, S3C_GPIO_SFN(6));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-keypad.c b/arch/arm/mach-s3c64xx/setup-keypad.c
new file mode 100644
index 00000000..1d4d0ee9
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-keypad.c
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s3c64xx/setup-keypad.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * GPIO configuration for S3C64XX KeyPad 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/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/keypad.h>
+
+void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols)
+{
+ /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), rows, S3C_GPIO_SFN(3));
+
+ /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
new file mode 100644
index 00000000..6eac071a
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -0,0 +1,57 @@
+/* linux/arch/arm/plat-s3c64xx/setup-sdhci-gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - 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 <plat/gpio-cfg.h>
+#include <plat/sdhci.h>
+
+void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPG(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
+ }
+}
+
+void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPH pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
+ }
+}
+
+void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ /* Set all the necessary GPH pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPH(6), width, S3C_GPIO_SFN(3));
+
+ /* Set all the necessary GPC pins to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S3C64XX_GPC(4), 2, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci.c b/arch/arm/mach-s3c64xx/setup-sdhci.c
new file mode 100644
index 00000000..f344a222
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-sdhci.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/mach-s3c64xx/setup-sdhci.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C6400/S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s3c64xx_hsmmc_clksrcs[4] = {
+ [0] = "hsmmc",
+ [1] = "hsmmc",
+ [2] = "mmc_bus",
+ /* [3] = "48m", - note not successfully used yet */
+};
+
+void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ pr_debug("%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3);
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
+
+void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+ s3c6400_setup_sdhci_cfg_card(dev, r, ios, card);
+}
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S
new file mode 100644
index 00000000..1f87732b
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/sleep.S
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-s3c64xx/sleep.S
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX CPU sleep code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/map.h>
+
+#undef S3C64XX_VA_GPIO
+#define S3C64XX_VA_GPIO (0x0)
+
+#include <mach/regs-gpio.h>
+
+#define LL_UART (S3C_PA_UART + (0x400 * CONFIG_S3C_LOWLEVEL_UART_PORT))
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * Save enough processor state to allow the restart of the pm.c
+ * code after resume.
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(s3c_cpu_save)
+ stmfd sp!, { r4 - r12, lr }
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ @@ call final suspend code
+ ldr r0, =pm_cpu_sleep
+ ldr pc, [r0]
+
+ @@ return to the caller, after the MMU is turned on.
+ @@ restore the last bits of the stack and return.
+resume_with_mmu:
+ ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save
+
+ /* Sleep magic, the word before the resume entry point so that the
+ * bootloader can check for a resumeable image. */
+
+ .word 0x2bedf00d
+
+ /* s3c_cpu_reusme
+ *
+ * This is the entry point, stored by whatever method the bootloader
+ * requires to get the kernel runnign again. This code expects to be
+ * entered with no caches live and the MMU disabled. It will then
+ * restore the MMU and other basic CP registers saved and restart
+ * the kernel C code to finish the resume code.
+ */
+
+ENTRY(s3c_cpu_resume)
+ msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ ldr r2, =LL_UART /* for debug */
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+
+#define S3C64XX_GPNCON (S3C64XX_GPN_BASE + 0x00)
+#define S3C64XX_GPNDAT (S3C64XX_GPN_BASE + 0x04)
+
+#define S3C64XX_GPN_CONMASK(__gpio) (0x3 << ((__gpio) * 2))
+#define S3C64XX_GPN_OUTPUT(__gpio) (0x1 << ((__gpio) * 2))
+
+ /* Initialise the GPIO state if we are debugging via the SMDK LEDs,
+ * as the uboot version supplied resets these to inputs during the
+ * resume checks.
+ */
+
+ ldr r3, =S3C64XX_PA_GPIO
+ ldr r0, [ r3, #S3C64XX_GPNCON ]
+ bic r0, r0, #(S3C64XX_GPN_CONMASK(12) | S3C64XX_GPN_CONMASK(13) | \
+ S3C64XX_GPN_CONMASK(14) | S3C64XX_GPN_CONMASK(15))
+ orr r0, r0, #(S3C64XX_GPN_OUTPUT(12) | S3C64XX_GPN_OUTPUT(13) | \
+ S3C64XX_GPN_OUTPUT(14) | S3C64XX_GPN_OUTPUT(15))
+ str r0, [ r3, #S3C64XX_GPNCON ]
+
+ ldr r0, [ r3, #S3C64XX_GPNDAT ]
+ bic r0, r0, #0xf << 12 @ GPN12..15
+ orr r0, r0, #1 << 15 @ GPN15
+ str r0, [ r3, #S3C64XX_GPNDAT ]
+#endif
+ b cpu_resume
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
new file mode 100644
index 00000000..017af4c4
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -0,0 +1,59 @@
+# arch/arm/mach-s5p64x0/Kconfig
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+if ARCH_S5P64X0
+
+config CPU_S5P6440
+ bool
+ select S3C_PL330_DMA
+ select S5P_HRT
+ help
+ Enable S5P6440 CPU support
+
+config CPU_S5P6450
+ bool
+ select S3C_PL330_DMA
+ select S5P_HRT
+ help
+ Enable S5P6450 CPU support
+
+config S5P64X0_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+# machine support
+
+config MACH_SMDK6440
+ bool "SMDK6440"
+ select CPU_S5P6440
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C64XX_DEV_SPI
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ select S5P64X0_SETUP_I2C1
+ help
+ Machine support for the Samsung SMDK6440
+
+config MACH_SMDK6450
+ bool "SMDK6450"
+ select CPU_S5P6450
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S3C64XX_DEV_SPI
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ select S5P64X0_SETUP_I2C1
+ help
+ Machine support for the Samsung SMDK6450
+
+endif
diff --git a/arch/arm/mach-s5p64x0/Makefile b/arch/arm/mach-s5p64x0/Makefile
new file mode 100644
index 00000000..ae6bf6fe
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Makefile
@@ -0,0 +1,30 @@
+# arch/arm/mach-s5p64x0/Makefile
+#
+# Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5P64X0 system
+
+obj-$(CONFIG_ARCH_S5P64X0) += cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_ARCH_S5P64X0) += setup-i2c0.o
+obj-$(CONFIG_CPU_S5P6440) += clock-s5p6440.o
+obj-$(CONFIG_CPU_S5P6450) += clock-s5p6450.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDK6440) += mach-smdk6440.o
+obj-$(CONFIG_MACH_SMDK6450) += mach-smdk6450.o
+
+# device support
+
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+
+obj-$(CONFIG_S5P64X0_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/mach-s5p64x0/Makefile.boot b/arch/arm/mach-s5p64x0/Makefile.boot
new file mode 100644
index 00000000..ff90aa13
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
new file mode 100644
index 00000000..9f12c2eb
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -0,0 +1,619 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6440.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P6440 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+
+static u32 epll_div[][5] = {
+ { 36000000, 0, 48, 1, 4 },
+ { 48000000, 0, 32, 1, 3 },
+ { 60000000, 0, 40, 1, 3 },
+ { 72000000, 0, 48, 1, 3 },
+ { 84000000, 0, 28, 1, 2 },
+ { 96000000, 0, 32, 1, 2 },
+ { 32768000, 45264, 43, 1, 4 },
+ { 45158000, 6903, 30, 1, 3 },
+ { 49152000, 50332, 32, 1, 3 },
+ { 67738000, 10398, 45, 1, 3 },
+ { 73728000, 9961, 49, 1, 3 }
+};
+
+static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P64X0_EPLL_CON);
+ epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+ epll_con_k &= ~(PLL90XX_KDIV_MASK);
+ epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+ epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+ (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+ (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P64X0_EPLL_CON);
+ __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6440_epll_ops = {
+ .get_rate = s5p_epll_get_rate,
+ .set_rate = s5p6440_epll_set_rate,
+};
+
+static struct clksrc_clk clk_hclk = {
+ .clk = {
+ .name = "clk_hclk",
+ .id = -1,
+ .parent = &clk_armclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+ .clk = {
+ .name = "clk_pclk",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_hclk_low = {
+ .clk = {
+ .name = "clk_hclk_low",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_SYS_OTHERS, .shift = 6, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+ .clk = {
+ .name = "clk_pclk_low",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_off[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_mem_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "post",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 5)
+ }, {
+ .name = "2d",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "pdma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 20)
+ }, {
+ .name = "irom",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "hclk_fimgvg",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "tsi",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "pcm",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "gps",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "dsim",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "etm",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 29),
+ }, {
+ .name = "dmc0",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 30),
+ }, {
+ .name = "pclk_fimgvg",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 31),
+ }, {
+ .name = "sclk_spi_48",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "sclk_spi_48",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 23),
+ }, {
+ .name = "mmc_48m",
+ .id = 0,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "mmc_48m",
+ .id = 1,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 28),
+ }, {
+ .name = "mmc_48m",
+ .id = 2,
+ .parent = &clk_48m,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 29),
+ },
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "intc",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mem",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 18),
+ },
+};
+
+static struct clk clk_iis_cd_v40 = {
+ .name = "iis_cdclk_v40",
+ .id = -1,
+};
+
+static struct clk clk_pcm_cd = {
+ .name = "pcm_cdclk",
+ .id = -1,
+};
+
+static struct clk *clkset_group1_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_fin_epll,
+};
+
+static struct clksrc_sources clkset_group1 = {
+ .sources = clkset_group1_list,
+ .nr_sources = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_audio_list[] = {
+ &clk_mout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_fin_epll,
+ &clk_iis_cd_v40,
+ &clk_pcm_cd,
+};
+
+static struct clksrc_sources clkset_audio = {
+ .sources = clkset_audio_list,
+ .nr_sources = ARRAY_SIZE(clkset_audio_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_post",
+ .id = -1,
+ .ctrlbit = (1 << 10),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_dispcon",
+ .id = -1,
+ .ctrlbit = (1 << 1),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimgvg",
+ .id = -1,
+ .ctrlbit = (1 << 2),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_audio2",
+ .id = -1,
+ .ctrlbit = (1 << 11),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_audio,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 0, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 24, .size = 4 },
+ },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+ &clk_dout_mpll,
+ &clk_armclk,
+ &clk_hclk,
+ &clk_pclk,
+ &clk_hclk_low,
+ &clk_pclk_low,
+};
+
+void __init_or_cpufreq s5p6440_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk_low;
+ unsigned long pclk;
+ unsigned long pclk_low;
+
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned int ptr;
+
+ /* Set S5P6440 functions for clk_fout_epll */
+
+ clk_fout_epll.enable = s5p_epll_enable;
+ clk_fout_epll.ops = &s5p6440_epll_ops;
+
+ clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+ xtal_clk = clk_get(NULL, "ext_xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+ epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+ __raw_readl(S5P64X0_EPLL_CON_K));
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+
+ printk(KERN_INFO "S5P6440: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+ " E=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll));
+
+ fclk = clk_get_rate(&clk_armclk.clk);
+ hclk = clk_get_rate(&clk_hclk.clk);
+ pclk = clk_get_rate(&clk_pclk.clk);
+ hclk_low = clk_get_rate(&clk_hclk_low.clk);
+ pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+ printk(KERN_INFO "S5P6440: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+ print_mhz(hclk), print_mhz(hclk_low),
+ print_mhz(pclk), print_mhz(pclk_low));
+
+ clk_f.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_iis_cd_v40,
+ &clk_pcm_cd,
+};
+
+void __init s5p6440_register_clocks(void)
+{
+ 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-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
new file mode 100644
index 00000000..4eec457d
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -0,0 +1,666 @@
+/* linux/arch/arm/mach-s5p64x0/clock-s5p6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P6450 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/s5p64x0-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6450.h>
+
+static struct clksrc_clk clk_mout_dpll = {
+ .clk = {
+ .name = "mout_dpll",
+ .id = -1,
+ },
+ .sources = &clk_src_dpll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
+};
+
+static u32 epll_div[][5] = {
+ { 133000000, 27307, 55, 2, 2 },
+ { 100000000, 43691, 41, 2, 2 },
+ { 480000000, 0, 80, 2, 0 },
+};
+
+static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P64X0_EPLL_CON);
+ epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
+
+ epll_con_k &= ~(PLL90XX_KDIV_MASK);
+ epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+ epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+ (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+ (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P64X0_EPLL_CON);
+ __raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5p6450_epll_ops = {
+ .get_rate = s5p_epll_get_rate,
+ .set_rate = s5p6450_epll_set_rate,
+};
+
+static struct clksrc_clk clk_dout_epll = {
+ .clk = {
+ .name = "dout_epll",
+ .id = -1,
+ .parent = &clk_mout_epll.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_mout_hclk_sel = {
+ .clk = {
+ .name = "mout_hclk_sel",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 15, .size = 1 },
+};
+
+static struct clk *clkset_hclk_list[] = {
+ &clk_mout_hclk_sel.clk,
+ &clk_armclk.clk,
+};
+
+static struct clksrc_sources clkset_hclk = {
+ .sources = clkset_hclk_list,
+ .nr_sources = ARRAY_SIZE(clkset_hclk_list),
+};
+
+static struct clksrc_clk clk_hclk = {
+ .clk = {
+ .name = "clk_hclk",
+ .id = -1,
+ },
+ .sources = &clkset_hclk,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 14, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk = {
+ .clk = {
+ .name = "clk_pclk",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 12, .size = 4 },
+};
+static struct clksrc_clk clk_dout_pwm_ratio0 = {
+ .clk = {
+ .name = "clk_dout_pwm_ratio0",
+ .id = -1,
+ .parent = &clk_mout_hclk_sel.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_to_wdt_pwm = {
+ .clk = {
+ .name = "clk_pclk_to_wdt_pwm",
+ .id = -1,
+ .parent = &clk_dout_pwm_ratio0.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 20, .size = 4 },
+};
+
+static struct clksrc_clk clk_hclk_low = {
+ .clk = {
+ .name = "clk_hclk_low",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_low,
+ .reg_src = { .reg = S5P64X0_OTHERS, .shift = 6, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_low = {
+ .clk = {
+ .name = "clk_pclk_low",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 12, .size = 4 },
+};
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_off[] = {
+ {
+ .name = "usbhost",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "pdma",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "usbotg",
+ .id = -1,
+ .parent = &clk_hclk_low.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s5p64x0_hclk1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 22),
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "iis",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 27),
+ }, {
+ .name = "dmc0",
+ .id = -1,
+ .parent = &clk_pclk.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 30),
+ }
+};
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "intc",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mem",
+ .id = -1,
+ .parent = &clk_hclk.clk,
+ .enable = s5p64x0_hclk0_ctrl,
+ .ctrlbit = (1 << 21),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclk_to_wdt_pwm.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_pclk_low.clk,
+ .enable = s5p64x0_pclk_ctrl,
+ .ctrlbit = (1 << 18),
+ },
+};
+
+static struct clk *clkset_uart_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_mali_list[] = {
+ &clk_mout_epll.clk,
+ &clk_mout_apll.clk,
+ &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_mali = {
+ .sources = clkset_mali_list,
+ .nr_sources = ARRAY_SIZE(clkset_mali_list),
+};
+
+static struct clk *clkset_group2_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+};
+
+static struct clksrc_sources clkset_group2 = {
+ .sources = clkset_group2_list,
+ .nr_sources = ARRAY_SIZE(clkset_group2_list),
+};
+
+static struct clk *clkset_dispcon_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+ &clk_mout_dpll.clk,
+};
+
+static struct clksrc_sources clkset_dispcon = {
+ .sources = clkset_dispcon_list,
+ .nr_sources = ARRAY_SIZE(clkset_dispcon_list),
+};
+
+static struct clk *clkset_hsmmc44_list[] = {
+ &clk_dout_epll.clk,
+ &clk_dout_mpll.clk,
+ &clk_ext_xtal_mux,
+ &s5p_clk_27m,
+ &clk_48m,
+};
+
+static struct clksrc_sources clkset_hsmmc44 = {
+ .sources = clkset_hsmmc44_list,
+ .nr_sources = ARRAY_SIZE(clkset_hsmmc44_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+ [0] = &clk_dout_epll.clk,
+ [1] = &clk_dout_mpll.clk,
+ [2] = &clk_ext_xtal_mux,
+ [3] = NULL,
+ [4] = NULL,
+};
+
+static struct clksrc_sources clkset_sclk_audio0 = {
+ .sources = clkset_sclk_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+ .clk = {
+ .name = "audio-bus",
+ .id = -1,
+ .enable = s5p64x0_sclk_ctrl,
+ .ctrlbit = (1 << 8),
+ .parent = &clk_dout_epll.clk,
+ },
+ .sources = &clkset_sclk_audio0,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 10, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 8, .size = 4 },
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .ctrlbit = (1 << 24),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 18, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .ctrlbit = (1 << 25),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .ctrlbit = (1 << 26),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 22, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1 << 5),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .ctrlbit = (1 << 20),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 14, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .ctrlbit = (1 << 21),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = -1,
+ .ctrlbit = (1 << 10),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 26, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "aclk_mali",
+ .id = -1,
+ .ctrlbit = (1 << 2),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_mali,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_2d",
+ .id = -1,
+ .ctrlbit = (1 << 12),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_mali,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 30, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_usi",
+ .id = -1,
+ .ctrlbit = (1 << 7),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 10, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_camif",
+ .id = -1,
+ .ctrlbit = (1 << 6),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 28, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_dispcon",
+ .id = -1,
+ .ctrlbit = (1 << 1),
+ .enable = s5p64x0_sclk1_ctrl,
+ },
+ .sources = &clkset_dispcon,
+ .reg_src = { .reg = S5P64X0_CLK_SRC1, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_hsmmc44",
+ .id = -1,
+ .ctrlbit = (1 << 30),
+ .enable = s5p64x0_sclk_ctrl,
+ },
+ .sources = &clkset_hsmmc44,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 6, .size = 3 },
+ .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 28, .size = 4 },
+ },
+};
+
+/* Clock initialization code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_dout_epll,
+ &clk_mout_mpll,
+ &clk_dout_mpll,
+ &clk_armclk,
+ &clk_mout_hclk_sel,
+ &clk_dout_pwm_ratio0,
+ &clk_pclk_to_wdt_pwm,
+ &clk_hclk,
+ &clk_pclk,
+ &clk_hclk_low,
+ &clk_pclk_low,
+ &clk_sclk_audio0,
+};
+
+void __init_or_cpufreq s5p6450_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+
+ unsigned long xtal;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long hclk_low;
+ unsigned long pclk;
+ unsigned long pclk_low;
+
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long dpll;
+ unsigned int ptr;
+
+ /* Set S5P6450 functions for clk_fout_epll */
+
+ clk_fout_epll.enable = s5p_epll_enable;
+ clk_fout_epll.ops = &s5p6450_epll_ops;
+
+ clk_48m.enable = s5p64x0_clk48m_ctrl;
+
+ xtal_clk = clk_get(NULL, "ext_xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_APLL_CON), pll_4502);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P64X0_MPLL_CON), pll_4502);
+ epll = s5p_get_pll90xx(xtal, __raw_readl(S5P64X0_EPLL_CON),
+ __raw_readl(S5P64X0_EPLL_CON_K));
+ dpll = s5p_get_pll46xx(xtal, __raw_readl(S5P6450_DPLL_CON),
+ __raw_readl(S5P6450_DPLL_CON_K), pll_4650c);
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_dpll.rate = dpll;
+
+ printk(KERN_INFO "S5P6450: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz," \
+ " E=%ld.%ldMHz, D=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll),
+ print_mhz(dpll));
+
+ fclk = clk_get_rate(&clk_armclk.clk);
+ hclk = clk_get_rate(&clk_hclk.clk);
+ pclk = clk_get_rate(&clk_pclk.clk);
+ hclk_low = clk_get_rate(&clk_hclk_low.clk);
+ pclk_low = clk_get_rate(&clk_pclk_low.clk);
+
+ printk(KERN_INFO "S5P6450: HCLK=%ld.%ldMHz, HCLK_LOW=%ld.%ldMHz," \
+ " PCLK=%ld.%ldMHz, PCLK_LOW=%ld.%ldMHz\n",
+ print_mhz(hclk), print_mhz(hclk_low),
+ print_mhz(pclk), print_mhz(pclk_low));
+
+ clk_f.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+void __init s5p6450_register_clocks(void)
+{
+ int ptr;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
+ s3c_register_clksrc(sysclks[ptr], 1);
+
+ s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ 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-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
new file mode 100644
index 00000000..b52c6e2f
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -0,0 +1,235 @@
+/* linux/arch/arm/mach-s5p64x0/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+
+struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 1, .size = 1 },
+};
+
+struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 2, .size = 1 },
+};
+
+enum perf_level {
+ L0 = 532*1000,
+ L1 = 266*1000,
+ L2 = 133*1000,
+};
+
+static const u32 clock_table[][3] = {
+ /*{ARM_CLK, DIVarm, DIVhclk}*/
+ {L0 * 1000, (0 << ARM_DIV_RATIO_SHIFT), (3 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+ {L1 * 1000, (1 << ARM_DIV_RATIO_SHIFT), (1 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+ {L2 * 1000, (3 << ARM_DIV_RATIO_SHIFT), (0 << S5P64X0_CLKDIV0_HCLK_SHIFT)},
+};
+
+unsigned long s5p64x0_armclk_get_rate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv;
+
+ /* divisor mask starts at bit0, so no need to shift */
+ clkdiv = __raw_readl(ARM_CLK_DIV) & ARM_DIV_MASK;
+
+ return rate / (clkdiv + 1);
+}
+
+unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 iter;
+
+ for (iter = 1 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (rate > clock_table[iter][0])
+ return clock_table[iter-1][0];
+ }
+
+ return clock_table[ARRAY_SIZE(clock_table) - 1][0];
+}
+
+int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 round_tmp;
+ u32 iter;
+ u32 clk_div0_tmp;
+ u32 cur_rate = clk->ops->get_rate(clk);
+ unsigned long flags;
+
+ round_tmp = clk->ops->round_rate(clk, rate);
+ if (round_tmp == cur_rate)
+ return 0;
+
+
+ for (iter = 0 ; iter < ARRAY_SIZE(clock_table) ; iter++) {
+ if (round_tmp == clock_table[iter][0])
+ break;
+ }
+
+ if (iter >= ARRAY_SIZE(clock_table))
+ iter = ARRAY_SIZE(clock_table) - 1;
+
+ local_irq_save(flags);
+ if (cur_rate > round_tmp) {
+ /* Frequency Down */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P64X0_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+
+ } else {
+ /* Frequency Up */
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) &
+ ~(S5P64X0_CLKDIV0_HCLK_MASK);
+ clk_div0_tmp |= clock_table[iter][2];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+
+ clk_div0_tmp = __raw_readl(ARM_CLK_DIV) & ~(ARM_DIV_MASK);
+ clk_div0_tmp |= clock_table[iter][1];
+ __raw_writel(clk_div0_tmp, ARM_CLK_DIV);
+ }
+ local_irq_restore(flags);
+
+ clk->rate = clock_table[iter][0];
+
+ return 0;
+}
+
+struct clk_ops s5p64x0_clkarm_ops = {
+ .get_rate = s5p64x0_armclk_get_rate,
+ .set_rate = s5p64x0_armclk_set_rate,
+ .round_rate = s5p64x0_armclk_round_rate,
+};
+
+struct clksrc_clk clk_armclk = {
+ .clk = {
+ .name = "armclk",
+ .id = 1,
+ .parent = &clk_mout_apll.clk,
+ .ops = &s5p64x0_clkarm_ops,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 0, .size = 4 },
+};
+
+struct clksrc_clk clk_dout_mpll = {
+ .clk = {
+ .name = "dout_mpll",
+ .id = -1,
+ .parent = &clk_mout_mpll.clk,
+ },
+ .reg_div = { .reg = S5P64X0_CLK_DIV0, .shift = 4, .size = 1 },
+};
+
+struct clk *clkset_hclk_low_list[] = {
+ &clk_mout_apll.clk,
+ &clk_mout_mpll.clk,
+};
+
+struct clksrc_sources clkset_hclk_low = {
+ .sources = clkset_hclk_low_list,
+ .nr_sources = ARRAY_SIZE(clkset_hclk_low_list),
+};
+
+int s5p64x0_pclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_PCLK, clk, enable);
+}
+
+int s5p64x0_hclk0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK0, clk, enable);
+}
+
+int s5p64x0_hclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_HCLK1, clk, enable);
+}
+
+int s5p64x0_sclk_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK0, clk, enable);
+}
+
+int s5p64x0_sclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_SCLK1, clk, enable);
+}
+
+int s5p64x0_mem_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P64X0_CLK_GATE_MEM0, clk, enable);
+}
+
+int s5p64x0_clk48m_ctrl(struct clk *clk, int enable)
+{
+ unsigned long flags;
+ u32 val;
+
+ /* can't rely on clock lock, this register has other usages */
+ local_irq_save(flags);
+
+ val = __raw_readl(S5P64X0_OTHERS);
+ if (enable)
+ val |= S5P64X0_OTHERS_USB_SIG_MASK;
+ else
+ val &= ~S5P64X0_OTHERS_USB_SIG_MASK;
+
+ __raw_writel(val, S5P64X0_OTHERS);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
new file mode 100644
index 00000000..a5c00952
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/cpu.c
@@ -0,0 +1,209 @@
+/* linux/arch/arm/mach-s5p64x0/cpu.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/proc-fns.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/adc-core.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5p64x0_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5P64X0_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5P64X0_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6440_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6440_PA_UART(0)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static struct map_desc s5p6450_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(0)),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART + SZ_512K,
+ .pfn = __phys_to_pfn(S5P6450_PA_UART(5)),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void s5p64x0_idle(void)
+{
+ unsigned long val;
+
+ if (!need_resched()) {
+ val = __raw_readl(S5P64X0_PWR_CFG);
+ val &= ~(0x3 << 5);
+ val |= (0x1 << 5);
+ __raw_writel(val, S5P64X0_PWR_CFG);
+
+ cpu_do_idle();
+ }
+ local_irq_enable();
+}
+
+/*
+ * s5p64x0_map_io
+ *
+ * register the standard CPU IO areas
+ */
+
+void __init s5p6440_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+
+ iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+ iotable_init(s5p6440_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+}
+
+void __init s5p6450_map_io(void)
+{
+ /* initialize any device information early */
+ s3c_adc_setname("s3c64xx-adc");
+
+ iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
+ iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
+}
+
+/*
+ * s5p64x0_init_clocks
+ *
+ * register and setup the CPU clocks
+ */
+
+void __init s5p6440_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6440_register_clocks();
+ s5p6440_setup_clocks();
+}
+
+void __init s5p6450_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5p6450_register_clocks();
+ s5p6450_setup_clocks();
+}
+
+/*
+ * s5p64x0_init_irq
+ *
+ * register the CPU interrupts
+ */
+
+void __init s5p6440_init_irq(void)
+{
+ /* S5P6440 supports 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[3, 4, 8, 10, (12-22)]
+ * VIC1 is missing IRQ VIC1[1, 3, 4, 10, 11, 12, 14, 15, 22]
+ */
+ vic[0] = 0xff800ae7;
+ vic[1] = 0xffbf23e5;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+void __init s5p6450_init_irq(void)
+{
+ /* S5P6450 supports only 2 VIC */
+ u32 vic[2];
+
+ /*
+ * VIC0 is missing IRQ_VIC0[(13-15), (21-22)]
+ * VIC1 is missing IRQ VIC1[12, 14, 23]
+ */
+ vic[0] = 0xff9f1fff;
+ vic[1] = 0xff7fafff;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+struct sysdev_class s5p64x0_sysclass = {
+ .name = "s5p64x0-core",
+};
+
+static struct sys_device s5p64x0_sysdev = {
+ .cls = &s5p64x0_sysclass,
+};
+
+static int __init s5p64x0_core_init(void)
+{
+ return sysdev_class_register(&s5p64x0_sysclass);
+}
+core_initcall(s5p64x0_core_init);
+
+int __init s5p64x0_init(void)
+{
+ printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5p64x0_idle;
+
+ return sysdev_register(&s5p64x0_sysdev);
+}
diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c
new file mode 100644
index 00000000..35f1f226
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-audio.c
@@ -0,0 +1,236 @@
+/* linux/arch/arm/mach-s5p64x0/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static const char *rclksrc[] = {
+ [0] = "iis",
+ [1] = "sclk_audio2",
+};
+
+static int s5p6440_cfg_i2s(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5));
+ break;
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_i2s_pdata = {
+ .cfg_gpio = s5p6440_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource s5p64x0_i2s0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_I2S,
+ .end = S5P64X0_PA_I2S + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_I2S0_TX,
+ .end = DMACH_I2S0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_I2S0_RX,
+ .end = DMACH_I2S0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6440_device_iis = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
+ .resource = s5p64x0_i2s0_resource,
+ .dev = {
+ .platform_data = &s5p6440_i2s_pdata,
+ },
+};
+
+static int s5p6450_cfg_i2s(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5));
+ break;
+ case 1:
+ s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5));
+ s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5));
+ break;
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s5p6450_i2s0_pdata = {
+ .cfg_gpio = s5p6450_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+struct platform_device s5p6450_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource),
+ .resource = s5p64x0_i2s0_resource,
+ .dev = {
+ .platform_data = &s5p6450_i2s0_pdata,
+ },
+};
+
+static struct s3c_audio_pdata s5p6450_i2s_pdata = {
+ .cfg_gpio = s5p6450_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource s5p6450_i2s1_resource[] = {
+ [0] = {
+ .start = S5P6450_PA_I2S1,
+ .end = S5P6450_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 s5p6450_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p6450_i2s1_resource),
+ .resource = s5p6450_i2s1_resource,
+ .dev = {
+ .platform_data = &s5p6450_i2s_pdata,
+ },
+};
+
+static struct resource s5p6450_i2s2_resource[] = {
+ [0] = {
+ .start = S5P6450_PA_I2S2,
+ .end = S5P6450_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 s5p6450_device_iis2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5p6450_i2s2_resource),
+ .resource = s5p6450_i2s2_resource,
+ .dev = {
+ .platform_data = &s5p6450_i2s_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5p6440_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5P6440_GPR(6), 3, S3C_GPIO_SFN(2));
+ s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(2));
+ break;
+
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s5p6440_pcm_pdata = {
+ .cfg_gpio = s5p6440_pcm_cfg_gpio,
+};
+
+static struct resource s5p6440_pcm0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_PCM,
+ .end = S5P64X0_PA_PCM + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_PCM0_TX,
+ .end = DMACH_PCM0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_PCM0_RX,
+ .end = DMACH_PCM0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+struct platform_device s5p6440_device_pcm = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p6440_pcm0_resource),
+ .resource = s5p6440_pcm0_resource,
+ .dev = {
+ .platform_data = &s5p6440_pcm_pdata,
+ },
+};
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c
new file mode 100644
index 00000000..ac825e82
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dev-spi.c
@@ -0,0 +1,226 @@
+/* linux/arch/arm/mach-s5p64x0/dev-spi.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+
+static char *s5p64x0_spi_src_clks[] = {
+ [S5P64X0_SPI_SRCCLK_PCLK] = "pclk",
+ [S5P64X0_SPI_SRCCLK_SCLK] = "sclk_spi",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s5p6440_spi_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S5P6440_GPC(0);
+ break;
+
+ case 1:
+ base = S5P6440_GPC(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+
+static int s5p6450_spi_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S5P6450_GPC(0);
+ break;
+
+ case 1:
+ base = S5P6450_GPC(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+
+static struct resource s5p64x0_spi0_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_SPI0,
+ .end = S5P64X0_PA_SPI0 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI0_TX,
+ .end = DMACH_SPI0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI0_RX,
+ .end = DMACH_SPI0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi0_pdata = {
+ .cfg_gpio = s5p6440_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
+ .cfg_gpio = s5p6450_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5p64x0_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p64x0_spi0_resource),
+ .resource = s5p64x0_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource s5p64x0_spi1_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_SPI1,
+ .end = S5P64X0_PA_SPI1 + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPI1_TX,
+ .end = DMACH_SPI1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMACH_SPI1_RX,
+ .end = DMACH_SPI1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c64xx_spi_info s5p6440_spi1_pdata = {
+ .cfg_gpio = s5p6440_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
+ .cfg_gpio = s5p6450_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .tx_st_done = 25,
+};
+
+struct platform_device s5p64x0_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p64x0_spi1_resource),
+ .resource = s5p64x0_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs)
+{
+ unsigned int id;
+ struct s3c64xx_spi_info *pd;
+
+ id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+ /* Reject invalid configuration */
+ if (!num_cs || src_clk_nr < 0
+ || src_clk_nr > S5P64X0_SPI_SRCCLK_SCLK) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ if (id == 0x50000)
+ pd = &s5p6450_spi0_pdata;
+ else
+ pd = &s5p6440_spi0_pdata;
+
+ s5p64x0_device_spi0.dev.platform_data = pd;
+ break;
+ case 1:
+ if (id == 0x50000)
+ pd = &s5p6450_spi1_pdata;
+ else
+ pd = &s5p6440_spi1_pdata;
+
+ s5p64x0_device_spi1.dev.platform_data = pd;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = s5p64x0_spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
new file mode 100644
index 00000000..d7ad944b
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -0,0 +1,149 @@
+/* linux/arch/arm/mach-s5p64x0/dma.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * 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 <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/regs-clock.h>
+
+#include <plat/devs.h>
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5p64x0_pdma_resource[] = {
+ [0] = {
+ .start = S5P64X0_PA_PDMA,
+ .end = S5P64X0_PA_PDMA + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DMA0,
+ .end = IRQ_DMA0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5p6440_pdma_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_MAX,
+ [9] = DMACH_MAX,
+ [10] = DMACH_PCM0_TX,
+ [11] = DMACH_PCM0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S0_RX,
+ [14] = DMACH_SPI0_TX,
+ [15] = DMACH_SPI0_RX,
+ [16] = DMACH_MAX,
+ [17] = DMACH_MAX,
+ [18] = DMACH_MAX,
+ [19] = DMACH_MAX,
+ [20] = DMACH_SPI1_TX,
+ [21] = DMACH_SPI1_RX,
+ [22] = DMACH_MAX,
+ [23] = DMACH_MAX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_MAX,
+ [26] = DMACH_MAX,
+ [27] = DMACH_MAX,
+ [28] = DMACH_MAX,
+ [29] = DMACH_PWM,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct s3c_pl330_platdata s5p6450_pdma_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_UART4_RX,
+ [9] = DMACH_UART4_TX,
+ [10] = DMACH_PCM0_TX,
+ [11] = DMACH_PCM0_RX,
+ [12] = DMACH_I2S0_TX,
+ [13] = DMACH_I2S0_RX,
+ [14] = DMACH_SPI0_TX,
+ [15] = DMACH_SPI0_RX,
+ [16] = DMACH_PCM1_TX,
+ [17] = DMACH_PCM1_RX,
+ [18] = DMACH_PCM2_TX,
+ [19] = DMACH_PCM2_RX,
+ [20] = DMACH_SPI1_TX,
+ [21] = DMACH_SPI1_RX,
+ [22] = DMACH_USI_TX,
+ [23] = DMACH_USI_RX,
+ [24] = DMACH_MAX,
+ [25] = DMACH_I2S1_TX,
+ [26] = DMACH_I2S1_RX,
+ [27] = DMACH_I2S2_TX,
+ [28] = DMACH_I2S2_RX,
+ [29] = DMACH_PWM,
+ [30] = DMACH_UART5_RX,
+ [31] = DMACH_UART5_TX,
+ },
+};
+
+static struct platform_device s5p64x0_device_pdma = {
+ .name = "s3c-pl330",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p64x0_pdma_resource),
+ .resource = s5p64x0_pdma_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static int __init s5p64x0_dma_init(void)
+{
+ unsigned int id;
+
+ id = __raw_readl(S5P64X0_SYS_ID) & 0xFF000;
+
+ if (id == 0x50000)
+ s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
+ else
+ s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+
+ platform_device_register(&s5p64x0_device_pdma);
+
+ return 0;
+}
+arch_initcall(s5p64x0_dma_init);
diff --git a/arch/arm/mach-s5p64x0/gpiolib.c b/arch/arm/mach-s5p64x0/gpiolib.c
new file mode 100644
index 00000000..e7fb3b00
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/gpiolib.c
@@ -0,0 +1,511 @@
+/* linux/arch/arm/mach-s5p64x0/gpiolib.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/*
+ * S5P6440 GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 6 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * F 2 2Bit Yes 4 [1]
+ * G 7 4Bit Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * N 16 2Bit No IRQ_EINT
+ * P 8 2Bit Yes 8
+ * R 15 4Bit[2] Yes 8
+ *
+ * S5P6450 GPIO bank summary:
+ *
+ * Bank GPIOs Style SlpCon ExtInt Group
+ * A 6 4Bit Yes 1
+ * B 7 4Bit Yes 1
+ * C 8 4Bit Yes 2
+ * D 8 4Bit Yes None
+ * F 2 2Bit Yes None
+ * G 14 4Bit[2] Yes 5
+ * H 10 4Bit[2] Yes 6
+ * I 16 2Bit Yes None
+ * J 12 2Bit Yes None
+ * K 5 4Bit Yes None
+ * N 16 2Bit No IRQ_EINT
+ * P 11 2Bit Yes 8
+ * Q 14 2Bit Yes None
+ * R 15 4Bit[2] Yes None
+ * S 8 2Bit Yes None
+ *
+ * [1] BANKF pins 14,15 do not form part of the external interrupt sources
+ * [2] BANK has two control registers, GPxCON0 and GPxCON1
+ */
+
+static int s5p64x0_gpiolib_rbank_4bit2_input(struct gpio_chip *chip,
+ unsigned int offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+ unsigned long flags;
+
+ switch (offset) {
+ case 6:
+ offset += 1;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ regcon -= 4;
+ break;
+ default:
+ offset -= 7;
+ break;
+ }
+
+ s3c_gpio_lock(ourchip, flags);
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(offset));
+ __raw_writel(con, regcon);
+
+ s3c_gpio_unlock(ourchip, flags);
+
+ return 0;
+}
+
+static int s5p64x0_gpiolib_rbank_4bit2_output(struct gpio_chip *chip,
+ unsigned int offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ void __iomem *regcon = base;
+ unsigned long con;
+ unsigned long dat;
+ unsigned long flags;
+ unsigned con_offset = offset;
+
+ switch (con_offset) {
+ case 6:
+ con_offset += 1;
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ regcon -= 4;
+ break;
+ default:
+ con_offset -= 7;
+ break;
+ }
+
+ s3c_gpio_lock(ourchip, flags);
+
+ con = __raw_readl(regcon);
+ con &= ~(0xf << con_4bit_shift(con_offset));
+ con |= 0x1 << con_4bit_shift(con_offset);
+
+ dat = __raw_readl(base + GPIODAT_OFF);
+ if (value)
+ dat |= 1 << offset;
+ else
+ dat &= ~(1 << offset);
+
+ __raw_writel(con, regcon);
+ __raw_writel(dat, base + GPIODAT_OFF);
+
+ s3c_gpio_unlock(ourchip, flags);
+
+ return 0;
+}
+
+int s5p64x0_gpio_setcfg_4bit_rbank(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift;
+ u32 con;
+
+ switch (off) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ shift = (off & 7) * 4;
+ reg -= 4;
+ break;
+ case 6:
+ shift = ((off + 1) & 7) * 4;
+ reg -= 4;
+ default:
+ shift = ((off + 1) & 7) * 4;
+ break;
+ }
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0xf << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+static struct s3c_gpio_cfg s5p64x0_gpio_cfgs[] = {
+ {
+ .cfg_eint = 0,
+ }, {
+ .cfg_eint = 7,
+ }, {
+ .cfg_eint = 3,
+ .set_config = s5p64x0_gpio_setcfg_4bit_rbank,
+ }, {
+ .cfg_eint = 0,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ }, {
+ .cfg_eint = 2,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ }, {
+ .cfg_eint = 3,
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit[] = {
+ {
+ .base = S5P64X0_GPA_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPA(0),
+ .ngpio = S5P6440_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S5P64X0_GPB_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPB(0),
+ .ngpio = S5P6440_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S5P64X0_GPC_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPC(0),
+ .ngpio = S5P6440_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S5P64X0_GPG_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPG(0),
+ .ngpio = S5P6440_GPIO_G_NR,
+ .label = "GPG",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_4bit2[] = {
+ {
+ .base = S5P64X0_GPH_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6440_GPH(0),
+ .ngpio = S5P6440_GPIO_H_NR,
+ .label = "GPH",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_rbank_4bit2[] = {
+ {
+ .base = S5P64X0_GPR_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[2],
+ .chip = {
+ .base = S5P6440_GPR(0),
+ .ngpio = S5P6440_GPIO_R_NR,
+ .label = "GPR",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6440_gpio_2bit[] = {
+ {
+ .base = S5P64X0_GPF_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6440_GPF(0),
+ .ngpio = S5P6440_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S5P64X0_GPI_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6440_GPI(0),
+ .ngpio = S5P6440_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S5P64X0_GPJ_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6440_GPJ(0),
+ .ngpio = S5P6440_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S5P64X0_GPN_BASE,
+ .config = &s5p64x0_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6440_GPN(0),
+ .ngpio = S5P6440_GPIO_N_NR,
+ .label = "GPN",
+ },
+ }, {
+ .base = S5P64X0_GPP_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6440_GPP(0),
+ .ngpio = S5P6440_GPIO_P_NR,
+ .label = "GPP",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_4bit[] = {
+ {
+ .base = S5P64X0_GPA_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPA(0),
+ .ngpio = S5P6450_GPIO_A_NR,
+ .label = "GPA",
+ },
+ }, {
+ .base = S5P64X0_GPB_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPB(0),
+ .ngpio = S5P6450_GPIO_B_NR,
+ .label = "GPB",
+ },
+ }, {
+ .base = S5P64X0_GPC_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPC(0),
+ .ngpio = S5P6450_GPIO_C_NR,
+ .label = "GPC",
+ },
+ }, {
+ .base = S5P6450_GPD_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPD(0),
+ .ngpio = S5P6450_GPIO_D_NR,
+ .label = "GPD",
+ },
+ }, {
+ .base = S5P6450_GPK_BASE,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPK(0),
+ .ngpio = S5P6450_GPIO_K_NR,
+ .label = "GPK",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_4bit2[] = {
+ {
+ .base = S5P64X0_GPG_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPG(0),
+ .ngpio = S5P6450_GPIO_G_NR,
+ .label = "GPG",
+ },
+ }, {
+ .base = S5P64X0_GPH_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[1],
+ .chip = {
+ .base = S5P6450_GPH(0),
+ .ngpio = S5P6450_GPIO_H_NR,
+ .label = "GPH",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_rbank_4bit2[] = {
+ {
+ .base = S5P64X0_GPR_BASE + 0x4,
+ .config = &s5p64x0_gpio_cfgs[2],
+ .chip = {
+ .base = S5P6450_GPR(0),
+ .ngpio = S5P6450_GPIO_R_NR,
+ .label = "GPR",
+ },
+ },
+};
+
+static struct s3c_gpio_chip s5p6450_gpio_2bit[] = {
+ {
+ .base = S5P64X0_GPF_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPF(0),
+ .ngpio = S5P6450_GPIO_F_NR,
+ .label = "GPF",
+ },
+ }, {
+ .base = S5P64X0_GPI_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6450_GPI(0),
+ .ngpio = S5P6450_GPIO_I_NR,
+ .label = "GPI",
+ },
+ }, {
+ .base = S5P64X0_GPJ_BASE,
+ .config = &s5p64x0_gpio_cfgs[3],
+ .chip = {
+ .base = S5P6450_GPJ(0),
+ .ngpio = S5P6450_GPIO_J_NR,
+ .label = "GPJ",
+ },
+ }, {
+ .base = S5P64X0_GPN_BASE,
+ .config = &s5p64x0_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6450_GPN(0),
+ .ngpio = S5P6450_GPIO_N_NR,
+ .label = "GPN",
+ },
+ }, {
+ .base = S5P64X0_GPP_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPP(0),
+ .ngpio = S5P6450_GPIO_P_NR,
+ .label = "GPP",
+ },
+ }, {
+ .base = S5P6450_GPQ_BASE,
+ .config = &s5p64x0_gpio_cfgs[4],
+ .chip = {
+ .base = S5P6450_GPQ(0),
+ .ngpio = S5P6450_GPIO_Q_NR,
+ .label = "GPQ",
+ },
+ }, {
+ .base = S5P6450_GPS_BASE,
+ .config = &s5p64x0_gpio_cfgs[5],
+ .chip = {
+ .base = S5P6450_GPS(0),
+ .ngpio = S5P6450_GPIO_S_NR,
+ .label = "GPS",
+ },
+ },
+};
+
+void __init s5p64x0_gpiolib_set_cfg(struct s3c_gpio_cfg *chipcfg, int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chipcfg++) {
+ if (!chipcfg->set_config)
+ chipcfg->set_config = s3c_gpio_setcfg_s3c64xx_4bit;
+ if (!chipcfg->get_config)
+ chipcfg->get_config = s3c_gpio_getcfg_s3c64xx_4bit;
+ if (!chipcfg->set_pull)
+ chipcfg->set_pull = s3c_gpio_setpull_updown;
+ if (!chipcfg->get_pull)
+ chipcfg->get_pull = s3c_gpio_getpull_updown;
+ }
+}
+
+static void __init s5p64x0_gpio_add_rbank_4bit2(struct s3c_gpio_chip *chip,
+ int nr_chips)
+{
+ for (; nr_chips > 0; nr_chips--, chip++) {
+ chip->chip.direction_input = s5p64x0_gpiolib_rbank_4bit2_input;
+ chip->chip.direction_output =
+ s5p64x0_gpiolib_rbank_4bit2_output;
+ s3c_gpiolib_add(chip);
+ }
+}
+
+static int __init s5p64x0_gpiolib_init(void)
+{
+ unsigned int chipid;
+
+ chipid = __raw_readl(S5P64X0_SYS_ID);
+
+ s5p64x0_gpiolib_set_cfg(s5p64x0_gpio_cfgs,
+ ARRAY_SIZE(s5p64x0_gpio_cfgs));
+
+ if ((chipid & 0xff000) == 0x50000) {
+ samsung_gpiolib_add_2bit_chips(s5p6450_gpio_2bit,
+ ARRAY_SIZE(s5p6450_gpio_2bit));
+
+ samsung_gpiolib_add_4bit_chips(s5p6450_gpio_4bit,
+ ARRAY_SIZE(s5p6450_gpio_4bit));
+
+ samsung_gpiolib_add_4bit2_chips(s5p6450_gpio_4bit2,
+ ARRAY_SIZE(s5p6450_gpio_4bit2));
+
+ s5p64x0_gpio_add_rbank_4bit2(s5p6450_gpio_rbank_4bit2,
+ ARRAY_SIZE(s5p6450_gpio_rbank_4bit2));
+ } else {
+ samsung_gpiolib_add_2bit_chips(s5p6440_gpio_2bit,
+ ARRAY_SIZE(s5p6440_gpio_2bit));
+
+ samsung_gpiolib_add_4bit_chips(s5p6440_gpio_4bit,
+ ARRAY_SIZE(s5p6440_gpio_4bit));
+
+ samsung_gpiolib_add_4bit2_chips(s5p6440_gpio_4bit2,
+ ARRAY_SIZE(s5p6440_gpio_4bit2));
+
+ s5p64x0_gpio_add_rbank_4bit2(s5p6440_gpio_rbank_4bit2,
+ ARRAY_SIZE(s5p6440_gpio_rbank_4bit2));
+ }
+
+ return 0;
+}
+core_initcall(s5p64x0_gpiolib_init);
diff --git a/arch/arm/mach-s5p64x0/include/mach/debug-macro.S b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
new file mode 100644
index 00000000..79b04e6a
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
@@ -0,0 +1,33 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#include <plat/regs-serial.h>
+
+ .macro addruart, rp, rv
+ mov \rp, #0xE0000000
+ orr \rp, \rp, #0x00100000
+ ldr \rp, [\rp, #0x118 ]
+ and \rp, \rp, #0xff000
+ teq \rp, #0x50000 @@ S5P6450
+ ldreq \rp, =0xEC800000
+ movne \rp, #0xEC000000 @@ S5P6440
+ ldrne \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5p64x0/include/mach/dma.h b/arch/arm/mach-s5p64x0/include/mach/dma.h
new file mode 100644
index 00000000..81209eb1
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/dma.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/entry-macro.S b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
new file mode 100644
index 00000000..10b62b4f
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
@@ -0,0 +1,16 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Low-level IRQ helper macros for the Samsung S5P64X0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+#include <asm/entry-macro-vic2.S>
diff --git a/arch/arm/mach-s5p64x0/include/mach/gpio.h b/arch/arm/mach-s5p64x0/include/mach/gpio.h
new file mode 100644
index 00000000..adb5f298
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/gpio.h
@@ -0,0 +1,139 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/gpio.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - GPIO lib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* GPIO bank sizes */
+
+#define S5P6440_GPIO_A_NR (6)
+#define S5P6440_GPIO_B_NR (7)
+#define S5P6440_GPIO_C_NR (8)
+#define S5P6440_GPIO_F_NR (16)
+#define S5P6440_GPIO_G_NR (7)
+#define S5P6440_GPIO_H_NR (10)
+#define S5P6440_GPIO_I_NR (16)
+#define S5P6440_GPIO_J_NR (12)
+#define S5P6440_GPIO_N_NR (16)
+#define S5P6440_GPIO_P_NR (8)
+#define S5P6440_GPIO_R_NR (15)
+
+#define S5P6450_GPIO_A_NR (6)
+#define S5P6450_GPIO_B_NR (7)
+#define S5P6450_GPIO_C_NR (8)
+#define S5P6450_GPIO_D_NR (8)
+#define S5P6450_GPIO_F_NR (16)
+#define S5P6450_GPIO_G_NR (14)
+#define S5P6450_GPIO_H_NR (10)
+#define S5P6450_GPIO_I_NR (16)
+#define S5P6450_GPIO_J_NR (12)
+#define S5P6450_GPIO_K_NR (5)
+#define S5P6450_GPIO_N_NR (16)
+#define S5P6450_GPIO_P_NR (11)
+#define S5P6450_GPIO_Q_NR (14)
+#define S5P6450_GPIO_R_NR (15)
+#define S5P6450_GPIO_S_NR (8)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5P64X0_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p6440_gpio_number {
+ S5P6440_GPIO_A_START = 0,
+ S5P6440_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_A),
+ S5P6440_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_B),
+ S5P6440_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_C),
+ S5P6440_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_F),
+ S5P6440_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_G),
+ S5P6440_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_H),
+ S5P6440_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_I),
+ S5P6440_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_J),
+ S5P6440_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_N),
+ S5P6440_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6440_GPIO_P),
+};
+
+enum s5p6450_gpio_number {
+ S5P6450_GPIO_A_START = 0,
+ S5P6450_GPIO_B_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_A),
+ S5P6450_GPIO_C_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_B),
+ S5P6450_GPIO_D_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_C),
+ S5P6450_GPIO_F_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_D),
+ S5P6450_GPIO_G_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_F),
+ S5P6450_GPIO_H_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_G),
+ S5P6450_GPIO_I_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_H),
+ S5P6450_GPIO_J_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_I),
+ S5P6450_GPIO_K_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_J),
+ S5P6450_GPIO_N_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_K),
+ S5P6450_GPIO_P_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_N),
+ S5P6450_GPIO_Q_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_P),
+ S5P6450_GPIO_R_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_Q),
+ S5P6450_GPIO_S_START = S5P64X0_GPIO_NEXT(S5P6450_GPIO_R),
+};
+
+/* GPIO number definitions */
+
+#define S5P6440_GPA(_nr) (S5P6440_GPIO_A_START + (_nr))
+#define S5P6440_GPB(_nr) (S5P6440_GPIO_B_START + (_nr))
+#define S5P6440_GPC(_nr) (S5P6440_GPIO_C_START + (_nr))
+#define S5P6440_GPF(_nr) (S5P6440_GPIO_F_START + (_nr))
+#define S5P6440_GPG(_nr) (S5P6440_GPIO_G_START + (_nr))
+#define S5P6440_GPH(_nr) (S5P6440_GPIO_H_START + (_nr))
+#define S5P6440_GPI(_nr) (S5P6440_GPIO_I_START + (_nr))
+#define S5P6440_GPJ(_nr) (S5P6440_GPIO_J_START + (_nr))
+#define S5P6440_GPN(_nr) (S5P6440_GPIO_N_START + (_nr))
+#define S5P6440_GPP(_nr) (S5P6440_GPIO_P_START + (_nr))
+#define S5P6440_GPR(_nr) (S5P6440_GPIO_R_START + (_nr))
+
+#define S5P6450_GPA(_nr) (S5P6450_GPIO_A_START + (_nr))
+#define S5P6450_GPB(_nr) (S5P6450_GPIO_B_START + (_nr))
+#define S5P6450_GPC(_nr) (S5P6450_GPIO_C_START + (_nr))
+#define S5P6450_GPD(_nr) (S5P6450_GPIO_D_START + (_nr))
+#define S5P6450_GPF(_nr) (S5P6450_GPIO_F_START + (_nr))
+#define S5P6450_GPG(_nr) (S5P6450_GPIO_G_START + (_nr))
+#define S5P6450_GPH(_nr) (S5P6450_GPIO_H_START + (_nr))
+#define S5P6450_GPI(_nr) (S5P6450_GPIO_I_START + (_nr))
+#define S5P6450_GPJ(_nr) (S5P6450_GPIO_J_START + (_nr))
+#define S5P6450_GPK(_nr) (S5P6450_GPIO_K_START + (_nr))
+#define S5P6450_GPN(_nr) (S5P6450_GPIO_N_START + (_nr))
+#define S5P6450_GPP(_nr) (S5P6450_GPIO_P_START + (_nr))
+#define S5P6450_GPQ(_nr) (S5P6450_GPIO_Q_START + (_nr))
+#define S5P6450_GPR(_nr) (S5P6450_GPIO_R_START + (_nr))
+#define S5P6450_GPS(_nr) (S5P6450_GPIO_S_START + (_nr))
+
+/* the end of the S5P64X0 specific gpios */
+
+#define S5P6440_GPIO_END (S5P6440_GPR(S5P6440_GPIO_R_NR) + 1)
+#define S5P6450_GPIO_END (S5P6450_GPS(S5P6450_GPIO_S_NR) + 1)
+
+#define S5P64X0_GPIO_END (S5P6440_GPIO_END > S5P6450_GPIO_END ? \
+ S5P6440_GPIO_END : S5P6450_GPIO_END)
+
+#define S3C_GPIO_END S5P64X0_GPIO_END
+
+/* define the number of gpios we need to the one after the last GPIO range */
+
+#define ARCH_NR_GPIOS (S5P64X0_GPIO_END + CONFIG_SAMSUNG_GPIO_EXTRA)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/hardware.h b/arch/arm/mach-s5p64x0/include/mach/hardware.h
new file mode 100644
index 00000000..d3e87996
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/hardware.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/i2c.h b/arch/arm/mach-s5p64x0/include/mach/i2c.h
new file mode 100644
index 00000000..887d2520
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/i2c.h
@@ -0,0 +1,17 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/i2c.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 I2C configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s5p6440_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6440_i2c1_cfg_gpio(struct platform_device *dev);
+
+extern void s5p6450_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s5p6450_i2c1_cfg_gpio(struct platform_device *dev);
diff --git a/arch/arm/mach-s5p64x0/include/mach/io.h b/arch/arm/mach-s5p64x0/include/mach/io.h
new file mode 100644
index 00000000..a3e095c0
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/io.h
@@ -0,0 +1,25 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/io.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5P64X0 based
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
new file mode 100644
index 00000000..513abffc
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -0,0 +1,142 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/irqs.h
+ *
+ * Copyright 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - IRQ definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0 */
+
+#define IRQ_EINT0_3 S5P_IRQ_VIC0(0)
+#define IRQ_EINT4_11 S5P_IRQ_VIC0(1)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(2)
+#define IRQ_IIS1 S5P_IRQ_VIC0(3) /* for only S5P6450 */
+#define IRQ_IIS2 S5P_IRQ_VIC0(4) /* for only S5P6450 */
+#define IRQ_IIC1 S5P_IRQ_VIC0(5)
+#define IRQ_I2SV40 S5P_IRQ_VIC0(6)
+#define IRQ_GPS S5P_IRQ_VIC0(7) /* for only S5P6450 */
+
+#define IRQ_2D S5P_IRQ_VIC0(11)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(25)
+#define IRQ_WDT S5P_IRQ_VIC0(26)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(27)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(28)
+#define IRQ_DISPCON0 S5P_IRQ_VIC0(29)
+#define IRQ_DISPCON1 S5P_IRQ_VIC0(30)
+#define IRQ_DISPCON2 S5P_IRQ_VIC0(31)
+
+/* VIC1 */
+
+#define IRQ_EINT12_15 S5P_IRQ_VIC1(0)
+#define IRQ_PCM0 S5P_IRQ_VIC1(2)
+#define IRQ_PCM1 S5P_IRQ_VIC1(3) /* for only S5P6450 */
+#define IRQ_PCM2 S5P_IRQ_VIC1(4) /* for only S5P6450 */
+#define IRQ_UART0 S5P_IRQ_VIC1(5)
+#define IRQ_UART1 S5P_IRQ_VIC1(6)
+#define IRQ_UART2 S5P_IRQ_VIC1(7)
+#define IRQ_UART3 S5P_IRQ_VIC1(8)
+#define IRQ_DMA0 S5P_IRQ_VIC1(9)
+#define IRQ_UART4 S5P_IRQ_VIC1(10) /* S5P6450 */
+#define IRQ_UART5 S5P_IRQ_VIC1(11) /* S5P6450 */
+#define IRQ_NFC S5P_IRQ_VIC1(13)
+#define IRQ_USI S5P_IRQ_VIC1(15) /* S5P6450 */
+#define IRQ_SPI0 S5P_IRQ_VIC1(16)
+#define IRQ_SPI1 S5P_IRQ_VIC1(17)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(17) /* Shared */
+#define IRQ_IIC S5P_IRQ_VIC1(18)
+#define IRQ_DISPCON3 S5P_IRQ_VIC1(19)
+#define IRQ_EINT_GROUPS S5P_IRQ_VIC1(21)
+#define IRQ_PMU S5P_IRQ_VIC1(23) /* S5P6440 */
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(24)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(25)
+#define IRQ_OTG S5P_IRQ_VIC1(26)
+#define IRQ_DSI S5P_IRQ_VIC1(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC1(28)
+#define IRQ_TSI S5P_IRQ_VIC1(29)
+#define IRQ_PENDN S5P_IRQ_VIC1(30)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_ADC S5P_IRQ_VIC1(31)
+
+/* UART interrupts, S5P6450 has 5 UARTs */
+#define IRQ_S5P_UART_BASE4 (96)
+#define IRQ_S5P_UART_BASE5 (100)
+
+#define IRQ_S5P_UART_RX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX4 (IRQ_S5P_UART_BASE4 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR4 (IRQ_S5P_UART_BASE4 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX5 (IRQ_S5P_UART_BASE5 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR5 (IRQ_S5P_UART_BASE5 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX4 IRQ_S5P_UART_RX4
+#define IRQ_S3CUART_RX5 IRQ_S5P_UART_RX5
+
+/* S5P6450 EINT feature will be added */
+
+/*
+ * Since the IRQ_EINT(x) are a linear mapping on s5p6440 we just defined
+ * them as an IRQ_EINT(x) macro from S5P_IRQ_EINT_BASE which we place
+ * after the pair of VICs.
+ */
+
+#define S5P_IRQ_EINT_BASE (S5P_IRQ_VIC1(31) + 6)
+
+#define S5P_EINT(x) ((x) + S5P_IRQ_EINT_BASE)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_EINT_BASE)
+/*
+ * S5P6440 has 0-15 external interrupts in group 0. Only these can be used
+ * to wake up from sleep. If request is beyond this range, by mistake, a large
+ * return value for an irq number should be indication of something amiss.
+ */
+#define S5P_EINT_BASE2 (0xf0000000)
+
+/*
+ * Next the external interrupt groups. These are similar to the IRQ_EINT(x)
+ * that they are sourced from the GPIO pins but with a different scheme for
+ * priority and source indication.
+ *
+ * The IRQ_EINT(x) can be thought of as 'group 0' of the available GPIO
+ * interrupts, but for historical reasons they are kept apart from these
+ * next interrupts.
+ *
+ * Use IRQ_EINT_GROUP(group, offset) to get the number for use in the
+ * machine specific support files.
+ */
+
+/* Actually, #6 and #7 are missing in the EINT_GROUP1 */
+#define IRQ_EINT_GROUP1_NR (15)
+#define IRQ_EINT_GROUP2_NR (8)
+#define IRQ_EINT_GROUP5_NR (7)
+#define IRQ_EINT_GROUP6_NR (10)
+/* Actually, #0, #1 and #2 are missing in the EINT_GROUP8 */
+#define IRQ_EINT_GROUP8_NR (11)
+
+#define IRQ_EINT_GROUP_BASE S5P_EINT(16)
+#define IRQ_EINT_GROUP1_BASE (IRQ_EINT_GROUP_BASE + 0)
+#define IRQ_EINT_GROUP2_BASE (IRQ_EINT_GROUP1_BASE + IRQ_EINT_GROUP1_NR)
+#define IRQ_EINT_GROUP5_BASE (IRQ_EINT_GROUP2_BASE + IRQ_EINT_GROUP2_NR)
+#define IRQ_EINT_GROUP6_BASE (IRQ_EINT_GROUP5_BASE + IRQ_EINT_GROUP5_NR)
+#define IRQ_EINT_GROUP8_BASE (IRQ_EINT_GROUP6_BASE + IRQ_EINT_GROUP6_NR)
+
+#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
+
+/* Set the default NR_IRQS */
+
+#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h
new file mode 100644
index 00000000..95c91257
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/map.h
@@ -0,0 +1,89 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/map.h
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5P64X0_PA_SDRAM 0x20000000
+
+#define S5P64X0_PA_CHIPID 0xE0000000
+
+#define S5P64X0_PA_SYSCON 0xE0100000
+
+#define S5P64X0_PA_GPIO 0xE0308000
+
+#define S5P64X0_PA_VIC0 0xE4000000
+#define S5P64X0_PA_VIC1 0xE4100000
+
+#define S5P64X0_PA_SROMC 0xE7000000
+
+#define S5P64X0_PA_PDMA 0xE9000000
+
+#define S5P64X0_PA_TIMER 0xEA000000
+#define S5P64X0_PA_RTC 0xEA100000
+#define S5P64X0_PA_WDT 0xEA200000
+
+#define S5P6440_PA_IIC0 0xEC104000
+#define S5P6440_PA_IIC1 0xEC20F000
+#define S5P6450_PA_IIC0 0xEC100000
+#define S5P6450_PA_IIC1 0xEC200000
+
+#define S5P64X0_PA_SPI0 0xEC400000
+#define S5P64X0_PA_SPI1 0xEC500000
+
+#define S5P64X0_PA_HSOTG 0xED100000
+
+#define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
+
+#define S5P64X0_PA_I2S 0xF2000000
+#define S5P6450_PA_I2S1 0xF2800000
+#define S5P6450_PA_I2S2 0xF2900000
+
+#define S5P64X0_PA_PCM 0xF2100000
+
+#define S5P64X0_PA_ADC 0xF3000000
+
+/* Compatibiltiy Defines */
+
+#define S3C_PA_HSMMC0 S5P64X0_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 S5P64X0_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 S5P64X0_PA_HSMMC(2)
+#define S3C_PA_IIC S5P6440_PA_IIC0
+#define S3C_PA_IIC1 S5P6440_PA_IIC1
+#define S3C_PA_RTC S5P64X0_PA_RTC
+#define S3C_PA_WDT S5P64X0_PA_WDT
+
+#define S5P_PA_CHIPID S5P64X0_PA_CHIPID
+#define S5P_PA_SROMC S5P64X0_PA_SROMC
+#define S5P_PA_SYSCON S5P64X0_PA_SYSCON
+#define S5P_PA_TIMER S5P64X0_PA_TIMER
+
+#define SAMSUNG_PA_ADC S5P64X0_PA_ADC
+
+/* UART */
+
+#define S5P6440_PA_UART(x) (0xEC000000 + ((x) * S3C_UART_OFFSET))
+#define S5P6450_PA_UART(x) ((x < 5) ? (0xEC800000 + ((x) * S3C_UART_OFFSET)) : (0xEC000000))
+
+#define S5P_PA_UART0 S5P6450_PA_UART(0)
+#define S5P_PA_UART1 S5P6450_PA_UART(1)
+#define S5P_PA_UART2 S5P6450_PA_UART(2)
+#define S5P_PA_UART3 S5P6450_PA_UART(3)
+#define S5P_PA_UART4 S5P6450_PA_UART(4)
+#define S5P_PA_UART5 S5P6450_PA_UART(5)
+
+#define S5P_SZ_UART SZ_256
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h
new file mode 100644
index 00000000..365a6eb4
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/memory.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/memory.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H __FILE__
+
+#define PLAT_PHYS_OFFSET UL(0x20000000)
+#define CONSISTENT_DMA_SIZE SZ_8M
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
new file mode 100644
index 00000000..19fff8b7
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
@@ -0,0 +1,68 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/pwm-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S5P64X0 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return 0;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK 0
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
new file mode 100644
index 00000000..a133f22f
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P64X0_APLL_CON S5P_CLKREG(0x0C)
+#define S5P64X0_MPLL_CON S5P_CLKREG(0x10)
+#define S5P64X0_EPLL_CON S5P_CLKREG(0x14)
+#define S5P64X0_EPLL_CON_K S5P_CLKREG(0x18)
+
+#define S5P64X0_CLK_SRC0 S5P_CLKREG(0x1C)
+
+#define S5P64X0_CLK_DIV0 S5P_CLKREG(0x20)
+#define S5P64X0_CLK_DIV1 S5P_CLKREG(0x24)
+#define S5P64X0_CLK_DIV2 S5P_CLKREG(0x28)
+
+#define S5P64X0_CLK_GATE_HCLK0 S5P_CLKREG(0x30)
+#define S5P64X0_CLK_GATE_PCLK S5P_CLKREG(0x34)
+#define S5P64X0_CLK_GATE_SCLK0 S5P_CLKREG(0x38)
+#define S5P64X0_CLK_GATE_MEM0 S5P_CLKREG(0x3C)
+
+#define S5P64X0_CLK_DIV3 S5P_CLKREG(0x40)
+
+#define S5P64X0_CLK_GATE_HCLK1 S5P_CLKREG(0x44)
+#define S5P64X0_CLK_GATE_SCLK1 S5P_CLKREG(0x48)
+
+#define S5P6450_DPLL_CON S5P_CLKREG(0x50)
+#define S5P6450_DPLL_CON_K S5P_CLKREG(0x54)
+
+#define S5P64X0_CLK_SRC1 S5P_CLKREG(0x10C)
+
+#define S5P64X0_SYS_ID S5P_CLKREG(0x118)
+#define S5P64X0_SYS_OTHERS S5P_CLKREG(0x11C)
+
+#define S5P64X0_PWR_CFG S5P_CLKREG(0x804)
+#define S5P64X0_OTHERS S5P_CLKREG(0x900)
+
+#define S5P64X0_CLKDIV0_HCLK_SHIFT (8)
+#define S5P64X0_CLKDIV0_HCLK_MASK (0xF << S5P64X0_CLKDIV0_HCLK_SHIFT)
+
+#define S5P64X0_OTHERS_USB_SIG_MASK (1 << 16)
+
+/* Compatibility defines */
+
+#define ARM_CLK_DIV S5P64X0_CLK_DIV0
+#define ARM_DIV_RATIO_SHIFT 0
+#define ARM_DIV_MASK (0xF << ARM_DIV_RATIO_SHIFT)
+
+#define S5P_EPLL_CON S5P64X0_EPLL_CON
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
new file mode 100644
index 00000000..0953ef6b
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
@@ -0,0 +1,37 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - GPIO register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_GPIO_H
+#define __ASM_ARCH_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+/* Base addresses for each of the banks */
+
+#define S5P64X0_GPA_BASE (S5P_VA_GPIO + 0x0000)
+#define S5P64X0_GPB_BASE (S5P_VA_GPIO + 0x0020)
+#define S5P64X0_GPC_BASE (S5P_VA_GPIO + 0x0040)
+#define S5P64X0_GPF_BASE (S5P_VA_GPIO + 0x00A0)
+#define S5P64X0_GPG_BASE (S5P_VA_GPIO + 0x00C0)
+#define S5P64X0_GPH_BASE (S5P_VA_GPIO + 0x00E0)
+#define S5P64X0_GPI_BASE (S5P_VA_GPIO + 0x0100)
+#define S5P64X0_GPJ_BASE (S5P_VA_GPIO + 0x0120)
+#define S5P64X0_GPN_BASE (S5P_VA_GPIO + 0x0830)
+#define S5P64X0_GPP_BASE (S5P_VA_GPIO + 0x0160)
+#define S5P64X0_GPR_BASE (S5P_VA_GPIO + 0x0290)
+
+#define S5P6450_GPD_BASE (S5P_VA_GPIO + 0x0060)
+#define S5P6450_GPK_BASE (S5P_VA_GPIO + 0x0140)
+#define S5P6450_GPQ_BASE (S5P_VA_GPIO + 0x0180)
+#define S5P6450_GPS_BASE (S5P_VA_GPIO + 0x0300)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-irq.h b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
new file mode 100644
index 00000000..4aaebdac
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
new file mode 100644
index 00000000..ff85b4b6
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/s5p64x0-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for s5p64x0 clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_CLOCK_H
+#define __ASM_ARCH_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+extern struct clksrc_clk clk_mout_apll;
+extern struct clksrc_clk clk_mout_mpll;
+extern struct clksrc_clk clk_mout_epll;
+
+extern int s5p64x0_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p64x0_epll_get_rate(struct clk *clk);
+
+extern unsigned long s5p64x0_armclk_get_rate(struct clk *clk);
+extern unsigned long s5p64x0_armclk_round_rate(struct clk *clk, unsigned long rate);
+extern int s5p64x0_armclk_set_rate(struct clk *clk, unsigned long rate);
+
+extern struct clk_ops s5p64x0_clkarm_ops;
+
+extern struct clksrc_clk clk_armclk;
+extern struct clksrc_clk clk_dout_mpll;
+
+extern struct clk *clkset_hclk_low_list[];
+extern struct clksrc_sources clkset_hclk_low;
+
+extern int s5p64x0_pclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk0_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_hclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_sclk1_ctrl(struct clk *clk, int enable);
+extern int s5p64x0_mem_ctrl(struct clk *clk, int enable);
+
+extern int s5p64x0_clk48m_ctrl(struct clk *clk, int enable);
+
+#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
new file mode 100644
index 00000000..170a20a9
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/spi-clocks.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPI_CLKS_H
+#define __ASM_ARCH_SPI_CLKS_H __FILE__
+
+#define S5P64X0_SPI_SRCCLK_PCLK 0
+#define S5P64X0_SPI_SRCCLK_SCLK 1
+
+#endif /* __ASM_ARCH_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h
new file mode 100644
index 00000000..60f57532
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/system.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/system.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/system-reset.h>
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/tick.h b/arch/arm/mach-s5p64x0/include/mach/tick.h
new file mode 100644
index 00000000..00aa7f1d
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/tick.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/tick.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P64X0 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/timex.h b/arch/arm/mach-s5p64x0/include/mach/timex.h
new file mode 100644
index 00000000..4b91faa1
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/timex.h
@@ -0,0 +1,27 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/timex.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S5P64X0 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/uncompress.h b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
new file mode 100644
index 00000000..1608faf8
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/uncompress.h
@@ -0,0 +1,212 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/uncompress.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+
+/*
+ * cannot use commonly <plat/uncompress.h>
+ * because uart base of S5P6440 and S5P6450 is different
+ */
+
+typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+unsigned int fifo_mask;
+unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX (14)
+
+unsigned long uart_base;
+
+static __inline__ void get_uart_base(void)
+{
+ unsigned int chipid;
+
+ chipid = *(const volatile unsigned int __force *) 0xE0100118;
+
+ uart_base = S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT;
+
+ if ((chipid & 0xff000) == 0x50000)
+ uart_base += 0xEC800000;
+ else
+ uart_base += 0xEC000000;
+}
+
+static __inline__ void uart_wr(unsigned int reg, unsigned int val)
+{
+ volatile unsigned int *ptr;
+
+ get_uart_base();
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ *ptr = val;
+}
+
+static __inline__ unsigned int uart_rd(unsigned int reg)
+{
+ volatile unsigned int *ptr;
+
+ get_uart_base();
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ return *ptr;
+}
+
+/*
+ * we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+ */
+
+static void putc(int ch)
+{
+ if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+ int level;
+
+ while (1) {
+ level = uart_rd(S3C2410_UFSTAT);
+ level &= fifo_mask;
+
+ if (level < fifo_max)
+ break;
+ }
+
+ } else {
+ /* not using fifos */
+
+ while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+ barrier();
+ }
+
+ /* write byte to transmission register */
+ uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad) \
+ do { \
+ *((volatile unsigned int __force *)(ad)) = (d); \
+ } while (0)
+
+/*
+ * CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+ */
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System resetting\n");
+
+ __raw_writel(0x4000, S3C2410_WTDAT);
+ __raw_writel(0x4000, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+ while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+ u32 fifocon = uart_rd(S3C2410_UFCON);
+
+ if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+ fifocon |= S3C2410_UFCON_RESETBOTH;
+ uart_wr(S3C2410_UFCON, fifocon);
+
+ /* wait for fifo reset to complete */
+ while (1) {
+ fifocon = uart_rd(S3C2410_UFCON);
+ if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+ break;
+ }
+ }
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+static void arch_decomp_setup(void)
+{
+ /*
+ * we may need to setup the uart(s) here if we are not running
+ * on an BAST... the BAST will have left the uarts configured
+ * after calling linux.
+ */
+
+ arch_detect_cpu();
+ arch_decomp_wdog_start();
+
+ /*
+ * Enable the UART FIFOs if they where not enabled and our
+ * configuration says we should turn them on.
+ */
+
+ arch_enable_uart_fifo();
+}
+
+
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/vmalloc.h b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
new file mode 100644
index 00000000..38dcc71a
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/* linux/arch/arm/mach-s5p64x0/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
new file mode 100644
index 00000000..79833caf
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/init.c
@@ -0,0 +1,73 @@
+/* linux/arch/arm/mach-s5p64x0/init.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P64X0 - Init support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
+ [0] = {
+ .name = "pclk_low",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+ [1] = {
+ .name = "uclk1",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+
+void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5p64x0_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
+ }
+ }
+}
+
+void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ int uart;
+
+ for (uart = 0; uart < no; uart++) {
+ s5p_uart_resources[uart].resources->start = S5P6440_PA_UART(uart);
+ s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
+ }
+
+ s5p64x0_common_init_uarts(cfg, no);
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
+
+void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s5p64x0_common_init_uarts(cfg, no);
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
new file mode 100644
index 00000000..2d559f10
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -0,0 +1,208 @@
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6440.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s5p6440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/pll.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/s5p-time.h>
+
+#define SMDK6440_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK6440_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK6440_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16 | \
+ S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6440_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK6440_UCON_DEFAULT,
+ .ulcon = SMDK6440_ULCON_DEFAULT,
+ .ufcon = SMDK6440_UFCON_DEFAULT,
+ },
+};
+
+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,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_ts,
+ &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 = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6440_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6440_i2c1_cfg_gpio,
+};
+
+static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), },
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+};
+
+static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = {
+ /* To be populated */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdk6440_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+}
+
+static void __init smdk6440_machine_init(void)
+{
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ s3c_i2c0_set_platdata(&s5p6440_i2c0_data);
+ s3c_i2c1_set_platdata(&s5p6440_i2c1_data);
+ i2c_register_board_info(0, smdk6440_i2c_devs0,
+ ARRAY_SIZE(smdk6440_i2c_devs0));
+ i2c_register_board_info(1, smdk6440_i2c_devs1,
+ ARRAY_SIZE(smdk6440_i2c_devs1));
+
+ platform_add_devices(smdk6440_devices, ARRAY_SIZE(smdk6440_devices));
+}
+
+MACHINE_START(SMDK6440, "SMDK6440")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P64X0_PA_SDRAM + 0x100,
+
+ .init_irq = s5p6440_init_irq,
+ .map_io = smdk6440_map_io,
+ .init_machine = smdk6440_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
new file mode 100644
index 00000000..d19c4690
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -0,0 +1,227 @@
+/* linux/arch/arm/mach-s5p64x0/mach-smdk6450.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/i2c.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s5p6450.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/pll.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
+#include <plat/s5p-time.h>
+
+#define SMDK6450_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDK6450_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDK6450_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_TXTRIG16 | \
+ S3C2410_UFCON_RXTRIG8)
+
+static struct s3c2410_uartcfg smdk6450_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+ [4] = {
+ .hwport = 4,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#endif
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+ [5] = {
+ .hwport = 5,
+ .flags = 0,
+ .ucon = SMDK6450_UCON_DEFAULT,
+ .ulcon = SMDK6450_ULCON_DEFAULT,
+ .ufcon = SMDK6450_UFCON_DEFAULT,
+ },
+#endif
+};
+
+static 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,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_ts,
+ &s3c_device_wdt,
+ &samsung_asoc_dma,
+ &s5p6450_device_iis0,
+ &s3c_device_timer[1],
+ &smdk6450_backlight_device,
+ /* s5p6450_device_spi0 will be added */
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c0_data __initdata = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6450_i2c0_cfg_gpio,
+};
+
+static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = {
+ .flags = 0,
+ .bus_num = 1,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+ .cfg_gpio = s5p6450_i2c1_cfg_gpio,
+};
+
+static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+ { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */
+};
+
+static struct i2c_board_info smdk6450_i2c_devs1[] __initdata = {
+ { I2C_BOARD_INFO("24c128", 0x57), },/* Samsung S524AD0XD1 EEPROM */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdk6450_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
+ s3c24xx_init_clocks(19200000);
+ s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+}
+
+static void __init smdk6450_machine_init(void)
+{
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ s3c_i2c0_set_platdata(&s5p6450_i2c0_data);
+ s3c_i2c1_set_platdata(&s5p6450_i2c1_data);
+ i2c_register_board_info(0, smdk6450_i2c_devs0,
+ ARRAY_SIZE(smdk6450_i2c_devs0));
+ i2c_register_board_info(1, smdk6450_i2c_devs1,
+ ARRAY_SIZE(smdk6450_i2c_devs1));
+
+ platform_add_devices(smdk6450_devices, ARRAY_SIZE(smdk6450_devices));
+}
+
+MACHINE_START(SMDK6450, "SMDK6450")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P64X0_PA_SDRAM + 0x100,
+
+ .init_irq = s5p6450_init_irq,
+ .map_io = smdk6450_map_io,
+ .init_machine = smdk6450_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/setup-i2c0.c b/arch/arm/mach-s5p64x0/setup-i2c0.c
new file mode 100644
index 00000000..46b46391
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-i2c0.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/mach-s5p64x0/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64x0/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#include <mach/i2c.h>
+
+void s5p6440_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6440_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
+
+void s5p6450_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6450_GPB(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5p64x0/setup-i2c1.c b/arch/arm/mach-s5p64x0/setup-i2c1.c
new file mode 100644
index 00000000..6ad3b986
--- /dev/null
+++ b/arch/arm/mach-s5p64x0/setup-i2c1.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/mach-s5p64xx/setup-i2c1.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * I2C1 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+
+#include <mach/i2c.h>
+
+void s5p6440_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6440_GPR(9), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
+
+void s5p6450_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5P6450_GPR(9), 2,
+ S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
+}
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev) { }
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
new file mode 100644
index 00000000..608722ff
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -0,0 +1,74 @@
+# Copyright 2009 Samsung Electronics Co.
+# Byungho Min <bhmin@samsung.com>
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5PC100 CPU
+
+if ARCH_S5PC100
+
+config CPU_S5PC100
+ bool
+ select S5P_EXT_INT
+ select S3C_PL330_DMA
+ help
+ Enable S5PC100 CPU support
+
+config S5PC100_SETUP_FB_24BPP
+ bool
+ help
+ Common setup code for S5PC1XX with an 24bpp RGB display helper.
+
+config S5PC100_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config S5PC100_SETUP_IDE
+ bool
+ help
+ Common setup code for S5PC100 IDE GPIO configurations
+
+config S5PC100_SETUP_KEYPAD
+ bool
+ help
+ Common setup code for KEYPAD GPIO configurations.
+
+config S5PC100_SETUP_SDHCI
+ bool
+ select S5PC100_SETUP_SDHCI_GPIO
+ help
+ Internal helper functions for S5PC100 based SDHCI systems
+
+config S5PC100_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
+config MACH_SMDKC100
+ bool "SMDKC100"
+ select CPU_S5PC100
+ select S3C_DEV_FB
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_IDE
+ select SAMSUNG_DEV_KEYPAD
+ select SAMSUNG_DEV_PWM
+ select SAMSUNG_DEV_TS
+ select S5PC100_SETUP_FB_24BPP
+ select S5PC100_SETUP_I2C1
+ select S5PC100_SETUP_IDE
+ select S5PC100_SETUP_KEYPAD
+ select S5PC100_SETUP_SDHCI
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ help
+ Machine support for the Samsung SMDKC100
+
+endif
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
new file mode 100644
index 00000000..a5e6e608
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -0,0 +1,36 @@
+# arch/arm/mach-s5pc100/Makefile
+#
+# Copyright 2009 Samsung Electronics Co.
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5PC100 system
+
+obj-$(CONFIG_CPU_S5PC100) += cpu.o init.o clock.o
+obj-$(CONFIG_CPU_S5PC100) += setup-i2c0.o
+obj-$(CONFIG_CPU_S5PC100) += dma.o
+
+# Helper and device support
+
+obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o
+obj-$(CONFIG_S5PC100_SETUP_KEYPAD) += setup-keypad.o
+obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
+
+# device support
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+
+# machine support
+
+obj-$(CONFIG_MACH_SMDKC100) += mach-smdkc100.o
+
+# device support
+obj-y += dev-audio.o
diff --git a/arch/arm/mach-s5pc100/Makefile.boot b/arch/arm/mach-s5pc100/Makefile.boot
new file mode 100644
index 00000000..ff90aa13
--- /dev/null
+++ b/arch/arm/mach-s5pc100/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
new file mode 100644
index 00000000..0305e9b8
--- /dev/null
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -0,0 +1,1398 @@
+/* linux/arch/arm/mach-s5pc100/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PC100 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+#include <plat/s5p-clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5pc100.h>
+
+static struct clk s5p_clk_otgphy = {
+ .name = "otg_phy",
+ .id = -1,
+};
+
+static struct clk *clk_src_mout_href_list[] = {
+ [0] = &s5p_clk_27m,
+ [1] = &clk_fin_hpll,
+};
+
+static struct clksrc_sources clk_src_mout_href = {
+ .sources = clk_src_mout_href_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mout_href_list),
+};
+
+static struct clksrc_clk clk_mout_href = {
+ .clk = {
+ .name = "mout_href",
+ .id = -1,
+ },
+ .sources = &clk_src_mout_href,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+};
+
+static struct clk *clk_src_mout_48m_list[] = {
+ [0] = &clk_xusbxti,
+ [1] = &s5p_clk_otgphy,
+};
+
+static struct clksrc_sources clk_src_mout_48m = {
+ .sources = clk_src_mout_48m_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mout_48m_list),
+};
+
+static struct clksrc_clk clk_mout_48m = {
+ .clk = {
+ .name = "mout_48m",
+ .id = -1,
+ },
+ .sources = &clk_src_mout_48m,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clk *clk_src_mout_hpll_list[] = {
+ [0] = &s5p_clk_27m,
+};
+
+static struct clksrc_sources clk_src_mout_hpll = {
+ .sources = clk_src_mout_hpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mout_hpll_list),
+};
+
+static struct clksrc_clk clk_mout_hpll = {
+ .clk = {
+ .name = "mout_hpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mout_hpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_apll = {
+ .clk = {
+ .name = "div_apll",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_arm = {
+ .clk = {
+ .name = "div_arm",
+ .id = -1,
+ .parent = &clk_div_apll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_d0_bus = {
+ .clk = {
+ .name = "div_d0_bus",
+ .id = -1,
+ .parent = &clk_div_arm.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_pclkd0 = {
+ .clk = {
+ .name = "div_pclkd0",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_secss = {
+ .clk = {
+ .name = "div_secss",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_apll2 = {
+ .clk = {
+ .name = "div_apll2",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 3 },
+};
+
+static struct clk *clk_src_mout_am_list[] = {
+ [0] = &clk_mout_mpll.clk,
+ [1] = &clk_div_apll2.clk,
+};
+
+struct clksrc_sources clk_src_mout_am = {
+ .sources = clk_src_mout_am_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mout_am_list),
+};
+
+static struct clksrc_clk clk_mout_am = {
+ .clk = {
+ .name = "mout_am",
+ .id = -1,
+ },
+ .sources = &clk_src_mout_am,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_d1_bus = {
+ .clk = {
+ .name = "div_d1_bus",
+ .id = -1,
+ .parent = &clk_mout_am.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_mpll2 = {
+ .clk = {
+ .name = "div_mpll2",
+ .id = -1,
+ .parent = &clk_mout_am.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_mpll = {
+ .clk = {
+ .name = "div_mpll",
+ .id = -1,
+ .parent = &clk_mout_am.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 4, .size = 2 },
+};
+
+static struct clk *clk_src_mout_onenand_list[] = {
+ [0] = &clk_div_d0_bus.clk,
+ [1] = &clk_div_d1_bus.clk,
+};
+
+struct clksrc_sources clk_src_mout_onenand = {
+ .sources = clk_src_mout_onenand_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mout_onenand_list),
+};
+
+static struct clksrc_clk clk_mout_onenand = {
+ .clk = {
+ .name = "mout_onenand",
+ .id = -1,
+ },
+ .sources = &clk_src_mout_onenand,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+};
+
+static struct clksrc_clk clk_div_onenand = {
+ .clk = {
+ .name = "div_onenand",
+ .id = -1,
+ .parent = &clk_mout_onenand.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 2 },
+};
+
+static struct clksrc_clk clk_div_pclkd1 = {
+ .clk = {
+ .name = "div_pclkd1",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 3 },
+};
+
+static struct clksrc_clk clk_div_cam = {
+ .clk = {
+ .name = "div_cam",
+ .id = -1,
+ .parent = &clk_div_mpll2.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 24, .size = 5 },
+};
+
+static struct clksrc_clk clk_div_hdmi = {
+ .clk = {
+ .name = "div_hdmi",
+ .id = -1,
+ .parent = &clk_mout_hpll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
+};
+
+static u32 epll_div[][4] = {
+ { 32750000, 131, 3, 4 },
+ { 32768000, 131, 3, 4 },
+ { 36000000, 72, 3, 3 },
+ { 45000000, 90, 3, 3 },
+ { 45158000, 90, 3, 3 },
+ { 45158400, 90, 3, 3 },
+ { 48000000, 96, 3, 3 },
+ { 49125000, 131, 4, 3 },
+ { 49152000, 131, 4, 3 },
+ { 60000000, 120, 3, 3 },
+ { 67737600, 226, 5, 3 },
+ { 67738000, 226, 5, 3 },
+ { 73800000, 246, 5, 3 },
+ { 73728000, 246, 5, 3 },
+ { 72000000, 144, 3, 3 },
+ { 84000000, 168, 3, 3 },
+ { 96000000, 96, 3, 2 },
+ { 144000000, 144, 3, 2 },
+ { 192000000, 96, 3, 1 }
+};
+
+static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con;
+ unsigned int i;
+
+ if (clk->rate == rate) /* Return if nothing changed */
+ return 0;
+
+ epll_con = __raw_readl(S5P_EPLL_CON);
+
+ epll_con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) |
+ (epll_div[i][2] << PLL65XX_PDIV_SHIFT) |
+ (epll_div[i][3] << PLL65XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P_EPLL_CON);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5pc100_epll_ops = {
+ .get_rate = s5p_epll_get_rate,
+ .set_rate = s5pc100_epll_set_rate,
+};
+
+static int s5pc100_d0_0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D00, clk, enable);
+}
+
+static int s5pc100_d0_1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D01, clk, enable);
+}
+
+static int s5pc100_d0_2_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D02, clk, enable);
+}
+
+static int s5pc100_d1_0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D10, clk, enable);
+}
+
+static int s5pc100_d1_1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D11, clk, enable);
+}
+
+static int s5pc100_d1_2_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D12, clk, enable);
+}
+
+static int s5pc100_d1_3_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D13, clk, enable);
+}
+
+static int s5pc100_d1_4_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D14, clk, enable);
+}
+
+static int s5pc100_d1_5_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_D15, clk, enable);
+}
+
+static int s5pc100_sclk0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_SCLK0, clk, enable);
+}
+
+static int s5pc100_sclk1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_SCLK1, clk, enable);
+}
+
+/*
+ * The following clocks will be disabled during clock initialization. It is
+ * recommended to keep the following clocks disabled until the driver requests
+ * for enabling the clock.
+ */
+static struct clk init_clocks_off[] = {
+ {
+ .name = "cssys",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "secss",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "g2d",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "mdma",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "cfcon",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "nfcon",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "onenandc",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "sdm",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_2_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "seckey",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_2_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "modemif",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "usbhost",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "pdma",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "pdma",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "rotator",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "fimc",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "fimc",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "fimc",
+ .id = 2,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "jpeg",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "mipi-dsim",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "mipi-csis",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_1_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "g3d",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "tv",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_2_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "vp",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_2_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "mixer",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_2_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "hdmi",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_2_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "mfc",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_2_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "apc",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "iec",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "systimer",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "spi",
+ .id = 2,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "irda",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "ccan",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "ccan",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 11),
+ }, {
+ .name = "hsitx",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 12),
+ }, {
+ .name = "hsirx",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 13),
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "iis",
+ .id = 2,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "pcm",
+ .id = 0,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "pcm",
+ .id = 1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "spdif",
+ .id = -1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "keypad",
+ .id = -1,
+ .parent = &clk_div_pclkd1.clk,
+ .enable = s5pc100_d1_5_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "spi_48m",
+ .id = 0,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 7),
+ }, {
+ .name = "spi_48m",
+ .id = 1,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 8),
+ }, {
+ .name = "spi_48m",
+ .id = 2,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 9),
+ }, {
+ .name = "mmc_48m",
+ .id = 0,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 15),
+ }, {
+ .name = "mmc_48m",
+ .id = 1,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 16),
+ }, {
+ .name = "mmc_48m",
+ .id = 2,
+ .parent = &clk_mout_48m.clk,
+ .enable = s5pc100_sclk0_ctrl,
+ .ctrlbit = (1 << 17),
+ },
+};
+
+static struct clk clk_vclk54m = {
+ .name = "vclk_54m",
+ .id = -1,
+ .rate = 54000000,
+};
+
+static struct clk clk_i2scdclk0 = {
+ .name = "i2s_cdclk0",
+ .id = -1,
+};
+
+static struct clk clk_i2scdclk1 = {
+ .name = "i2s_cdclk1",
+ .id = -1,
+};
+
+static struct clk clk_i2scdclk2 = {
+ .name = "i2s_cdclk2",
+ .id = -1,
+};
+
+static struct clk clk_pcmcdclk0 = {
+ .name = "pcm_cdclk0",
+ .id = -1,
+};
+
+static struct clk clk_pcmcdclk1 = {
+ .name = "pcm_cdclk1",
+ .id = -1,
+};
+
+static struct clk *clk_src_group1_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll2.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group1 = {
+ .sources = clk_src_group1_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group1_list),
+};
+
+static struct clk *clk_src_group2_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_group2 = {
+ .sources = clk_src_group2_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group2_list),
+};
+
+static struct clk *clk_src_group3_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_i2scdclk0,
+ [4] = &clk_pcmcdclk0,
+ [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group3 = {
+ .sources = clk_src_group3_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group3_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 0,
+ .ctrlbit = (1 << 8),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group3,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+};
+
+static struct clk *clk_src_group4_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_i2scdclk1,
+ [4] = &clk_pcmcdclk1,
+ [5] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group4 = {
+ .sources = clk_src_group4_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group4_list),
+};
+
+static struct clksrc_clk clk_sclk_audio1 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 1,
+ .ctrlbit = (1 << 9),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group4,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+};
+
+static struct clk *clk_src_group5_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_i2scdclk2,
+ [4] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_group5 = {
+ .sources = clk_src_group5_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group5_list),
+};
+
+static struct clksrc_clk clk_sclk_audio2 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 2,
+ .ctrlbit = (1 << 10),
+ .enable = s5pc100_sclk1_ctrl,
+ },
+ .sources = &clk_src_group5,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+};
+
+static struct clk *clk_src_group6_list[] = {
+ [0] = &s5p_clk_27m,
+ [1] = &clk_vclk54m,
+ [2] = &clk_div_hdmi.clk,
+};
+
+struct clksrc_sources clk_src_group6 = {
+ .sources = clk_src_group6_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group6_list),
+};
+
+static struct clk *clk_src_group7_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_mout_hpll.clk,
+ [3] = &clk_vclk54m,
+};
+
+struct clksrc_sources clk_src_group7 = {
+ .sources = clk_src_group7_list,
+ .nr_sources = ARRAY_SIZE(clk_src_group7_list),
+};
+
+static struct clk *clk_src_mmc0_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+};
+
+struct clksrc_sources clk_src_mmc0 = {
+ .sources = clk_src_mmc0_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mmc0_list),
+};
+
+static struct clk *clk_src_mmc12_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_mmc12 = {
+ .sources = clk_src_mmc12_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mmc12_list),
+};
+
+static struct clk *clk_src_irda_usb_list[] = {
+ [0] = &clk_mout_epll.clk,
+ [1] = &clk_div_mpll.clk,
+ [2] = &clk_fin_epll,
+ [3] = &clk_mout_hpll.clk,
+};
+
+struct clksrc_sources clk_src_irda_usb = {
+ .sources = clk_src_irda_usb_list,
+ .nr_sources = ARRAY_SIZE(clk_src_irda_usb_list),
+};
+
+static struct clk *clk_src_pwi_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_mout_epll.clk,
+ [2] = &clk_div_mpll.clk,
+};
+
+struct clksrc_sources clk_src_pwi = {
+ .sources = clk_src_pwi_list,
+ .nr_sources = ARRAY_SIZE(clk_src_pwi_list),
+};
+
+static struct clk *clk_sclk_spdif_list[] = {
+ [0] = &clk_sclk_audio0.clk,
+ [1] = &clk_sclk_audio1.clk,
+ [2] = &clk_sclk_audio2.clk,
+};
+
+struct clksrc_sources clk_src_sclk_spdif = {
+ .sources = clk_sclk_spdif_list,
+ .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list),
+};
+
+static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+static unsigned long s5pc100_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(clk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+static struct clk_ops s5pc100_sclk_spdif_ops = {
+ .set_rate = s5pc100_spdif_set_rate,
+ .get_rate = s5pc100_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .id = -1,
+ .ctrlbit = (1 << 11),
+ .enable = s5pc100_sclk1_ctrl,
+ .ops = &s5pc100_sclk_spdif_ops,
+ },
+ .sources = &clk_src_sclk_spdif,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 },
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .ctrlbit = (1 << 4),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_group1,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .ctrlbit = (1 << 5),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_group1,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 2,
+ .ctrlbit = (1 << 6),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_group1,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = -1,
+ .ctrlbit = (1 << 3),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mixer",
+ .id = -1,
+ .ctrlbit = (1 << 6),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_group6,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 },
+ }, {
+ .clk = {
+ .name = "sclk_lcd",
+ .id = -1,
+ .ctrlbit = (1 << 0),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_group7,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 12, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 0,
+ .ctrlbit = (1 << 1),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_group7,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 1,
+ .ctrlbit = (1 << 2),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_group7,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 2,
+ .ctrlbit = (1 << 3),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_group7,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 24, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .ctrlbit = (1 << 12),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_mmc0,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .ctrlbit = (1 << 13),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_mmc12,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .ctrlbit = (1 << 14),
+ .enable = s5pc100_sclk1_ctrl,
+
+ },
+ .sources = &clk_src_mmc12,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_irda",
+ .id = 2,
+ .ctrlbit = (1 << 10),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_irda_usb,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_irda",
+ .id = -1,
+ .ctrlbit = (1 << 10),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_mmc12,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_pwi",
+ .id = -1,
+ .ctrlbit = (1 << 1),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_pwi,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 0, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 3 },
+ }, {
+ .clk = {
+ .name = "sclk_uhost",
+ .id = -1,
+ .ctrlbit = (1 << 11),
+ .enable = s5pc100_sclk0_ctrl,
+
+ },
+ .sources = &clk_src_irda_usb,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 20, .size = 4 },
+ },
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+ &clk_mout_hpll,
+ &clk_mout_href,
+ &clk_mout_48m,
+ &clk_div_apll,
+ &clk_div_arm,
+ &clk_div_d0_bus,
+ &clk_div_pclkd0,
+ &clk_div_secss,
+ &clk_div_apll2,
+ &clk_mout_am,
+ &clk_div_d1_bus,
+ &clk_div_mpll2,
+ &clk_div_mpll,
+ &clk_mout_onenand,
+ &clk_div_onenand,
+ &clk_div_pclkd1,
+ &clk_div_cam,
+ &clk_div_hdmi,
+ &clk_sclk_audio0,
+ &clk_sclk_audio1,
+ &clk_sclk_audio2,
+ &clk_sclk_spdif,
+};
+
+void __init_or_cpufreq s5pc100_setup_clocks(void)
+{
+ unsigned long xtal;
+ unsigned long arm;
+ unsigned long hclkd0;
+ unsigned long hclkd1;
+ unsigned long pclkd0;
+ unsigned long pclkd1;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long hpll;
+ unsigned int ptr;
+
+ /* Set S5PC100 functions for clk_fout_epll */
+ clk_fout_epll.enable = s5p_epll_enable;
+ clk_fout_epll.ops = &s5pc100_epll_ops;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ xtal = clk_get_rate(&clk_xtal);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ apll = s5p_get_pll65xx(xtal, __raw_readl(S5P_APLL_CON));
+ mpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_MPLL_CON));
+ epll = s5p_get_pll65xx(xtal, __raw_readl(S5P_EPLL_CON));
+ hpll = s5p_get_pll65xx(xtal, __raw_readl(S5P_HPLL_CON));
+
+ printk(KERN_INFO "S5PC100: PLL settings, A=%ld.%ldMHz, M=%ld.%ldMHz, E=%ld.%ldMHz, H=%ld.%ldMHz\n",
+ print_mhz(apll), print_mhz(mpll), print_mhz(epll), print_mhz(hpll));
+
+ clk_fout_apll.rate = apll;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_mout_hpll.clk.rate = hpll;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+
+ arm = clk_get_rate(&clk_div_arm.clk);
+ hclkd0 = clk_get_rate(&clk_div_d0_bus.clk);
+ pclkd0 = clk_get_rate(&clk_div_pclkd0.clk);
+ hclkd1 = clk_get_rate(&clk_div_d1_bus.clk);
+ pclkd1 = clk_get_rate(&clk_div_pclkd1.clk);
+
+ printk(KERN_INFO "S5PC100: HCLKD0=%ld.%ldMHz, HCLKD1=%ld.%ldMHz, PCLKD0=%ld.%ldMHz, PCLKD1=%ld.%ldMHz\n",
+ print_mhz(hclkd0), print_mhz(hclkd1), print_mhz(pclkd0), print_mhz(pclkd1));
+
+ clk_f.rate = arm;
+ clk_h.rate = hclkd1;
+ clk_p.rate = pclkd1;
+}
+
+/*
+ * The following clocks will be enabled during clock initialization.
+ */
+static struct clk init_clocks[] = {
+ {
+ .name = "tzic",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "intc",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_0_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "ebi",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "intmem",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 4),
+ }, {
+ .name = "sromc",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "dmc",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "chipid",
+ .id = -1,
+ .parent = &clk_div_d0_bus.clk,
+ .enable = s5pc100_d0_1_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 0),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 1),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 2),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_4_ctrl,
+ .ctrlbit = (1 << 3),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_div_d1_bus.clk,
+ .enable = s5pc100_d1_3_ctrl,
+ .ctrlbit = (1 << 6),
+ },
+};
+
+static struct clk *clks[] __initdata = {
+ &clk_ext,
+ &clk_i2scdclk0,
+ &clk_i2scdclk1,
+ &clk_i2scdclk2,
+ &clk_pcmcdclk0,
+ &clk_pcmcdclk1,
+};
+
+void __init s5pc100_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-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
new file mode 100644
index 00000000..fd2708e7
--- /dev/null
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -0,0 +1,169 @@
+/* linux/arch/arm/mach-s5pc100/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6410/cpu.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/ata-core.h>
+#include <plat/iic-core.h>
+#include <plat/sdhci.h>
+#include <plat/adc-core.h>
+#include <plat/onenand-core.h>
+#include <plat/fb-core.h>
+
+#include <plat/s5pc100.h>
+
+/* Initial IO mappings */
+
+static struct map_desc s5pc100_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(S5PC100_PA_SYSTIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5PC100_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC2,
+ .pfn = __phys_to_pfn(S5PC100_PA_VIC2),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5PC100_VA_OTHERS,
+ .pfn = __phys_to_pfn(S5PC100_PA_OTHERS),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void s5pc100_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+/* s5pc100_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5pc100_map_io(void)
+{
+ iotable_init(s5pc100_iodesc, ARRAY_SIZE(s5pc100_iodesc));
+
+ /* initialise device information early */
+ s5pc100_default_sdhci0();
+ s5pc100_default_sdhci1();
+ s5pc100_default_sdhci2();
+
+ s3c_adc_setname("s3c64xx-adc");
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+
+ s3c_onenand_setname("s5pc100-onenand");
+ s3c_fb_setname("s5pc100-fb");
+ s3c_cfcon_setname("s5pc100-pata");
+}
+
+void __init s5pc100_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5pc100_register_clocks();
+ s5pc100_setup_clocks();
+}
+
+void __init s5pc100_init_irq(void)
+{
+ u32 vic[] = {~0, ~0, ~0};
+
+ /* VIC0, VIC1, and VIC2 are fully populated. */
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+static struct sysdev_class s5pc100_sysclass = {
+ .name = "s5pc100-core",
+};
+
+static struct sys_device s5pc100_sysdev = {
+ .cls = &s5pc100_sysclass,
+};
+
+static int __init s5pc100_core_init(void)
+{
+ return sysdev_class_register(&s5pc100_sysclass);
+}
+
+core_initcall(s5pc100_core_init);
+
+int __init s5pc100_init(void)
+{
+ printk(KERN_INFO "S5PC100: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5pc100_idle;
+
+ return sysdev_register(&s5pc100_sysdev);
+}
diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c
new file mode 100644
index 00000000..ab2d2717
--- /dev/null
+++ b/arch/arm/mach-s5pc100/dev-audio.c
@@ -0,0 +1,347 @@
+/* linux/arch/arm/mach-s5pc100/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static int s5pc100_cfg_i2s(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ switch (pdev->id) {
+ case 0: /* Dedicated pins */
+ break;
+ case 1:
+ s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4));
+ break;
+ default:
+ printk(KERN_ERR "Invalid Device %d\n", pdev->id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const char *rclksrc_v5[] = {
+ [0] = "iis",
+ [1] = "i2sclkd2",
+};
+
+static struct s3c_audio_pdata i2sv5_pdata = {
+ .cfg_gpio = s5pc100_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc_v5,
+ },
+ },
+};
+
+static struct resource s5pc100_iis0_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_I2S0,
+ .end = S5PC100_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 s5pc100_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pc100_iis0_resource),
+ .resource = s5pc100_iis0_resource,
+ .dev = {
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "iis",
+ [1] = "sclk_audio",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5pc100_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc_v3,
+ },
+ },
+};
+
+static struct resource s5pc100_iis1_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_I2S1,
+ .end = S5PC100_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 s5pc100_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pc100_iis1_resource),
+ .resource = s5pc100_iis1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+static struct resource s5pc100_iis2_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_I2S2,
+ .end = S5PC100_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 s5pc100_device_iis2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pc100_iis2_resource),
+ .resource = s5pc100_iis2_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5pc100_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(5));
+ break;
+
+ case 1:
+ s3c_gpio_cfgpin_range(S5PC100_GPC(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 = s5pc100_pcm_cfg_gpio,
+};
+
+static struct resource s5pc100_pcm0_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_PCM0,
+ .end = S5PC100_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 s5pc100_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pc100_pcm0_resource),
+ .resource = s5pc100_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource s5pc100_pcm1_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_PCM1,
+ .end = S5PC100_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 s5pc100_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pc100_pcm1_resource),
+ .resource = s5pc100_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+/* AC97 Controller platform devices */
+
+static int s5pc100_ac97_cfg_gpio(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource s5pc100_ac97_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_AC97,
+ .end = S5PC100_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 = s5pc100_ac97_cfg_gpio,
+};
+
+static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pc100_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pc100_ac97_resource),
+ .resource = s5pc100_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s5pc100_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* S/PDIF Controller platform_device */
+static int s5pc100_spdif_cfg_gpd(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PC100_GPD(5), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static int s5pc100_spdif_cfg_gpg3(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PC100_GPG3(5), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s5pc100_spdif_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_SPDIF,
+ .end = S5PC100_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata s5p_spdif_pdata = {
+ .cfg_gpio = s5pc100_spdif_cfg_gpd,
+};
+
+static u64 s5pc100_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pc100_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pc100_spdif_resource),
+ .resource = s5pc100_spdif_resource,
+ .dev = {
+ .platform_data = &s5p_spdif_pdata,
+ .dma_mask = &s5pc100_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init s5pc100_spdif_setup_gpio(int gpio)
+{
+ if (gpio == S5PC100_SPDIF_GPD)
+ s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpd;
+ else
+ s5p_spdif_pdata.cfg_gpio = s5pc100_spdif_cfg_gpg3;
+}
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c
new file mode 100644
index 00000000..e5d6c4dc
--- /dev/null
+++ b/arch/arm/mach-s5pc100/dev-spi.c
@@ -0,0 +1,227 @@
+/* linux/arch/arm/mach-s5pc100/dev-spi.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/spi-clocks.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+#include <plat/irqs.h>
+
+static char *spi_src_clks[] = {
+ [S5PC100_SPI_SRCCLK_PCLK] = "pclk",
+ [S5PC100_SPI_SRCCLK_48M] = "spi_48m",
+ [S5PC100_SPI_SRCCLK_SPIBUS] = "spi_bus",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s5pc100_spi_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgall_range(S5PC100_GPB(0), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ break;
+
+ case 1:
+ s3c_gpio_cfgall_range(S5PC100_GPB(4), 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+ break;
+
+ case 2:
+ s3c_gpio_cfgpin(S5PC100_GPG3(0), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(S5PC100_GPG3(0), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgall_range(S5PC100_GPB(2), 2,
+ S3C_GPIO_SFN(3), S3C_GPIO_PULL_UP);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct resource s5pc100_spi0_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_SPI0,
+ .end = S5PC100_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 s5pc100_spi0_pdata = {
+ .cfg_gpio = s5pc100_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .high_speed = 1,
+ .tx_st_done = 21,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pc100_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pc100_spi0_resource),
+ .resource = s5pc100_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pc100_spi0_pdata,
+ },
+};
+
+static struct resource s5pc100_spi1_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_SPI1,
+ .end = S5PC100_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 s5pc100_spi1_pdata = {
+ .cfg_gpio = s5pc100_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .high_speed = 1,
+ .tx_st_done = 21,
+};
+
+struct platform_device s5pc100_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pc100_spi1_resource),
+ .resource = s5pc100_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pc100_spi1_pdata,
+ },
+};
+
+static struct resource s5pc100_spi2_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_SPI2,
+ .end = S5PC100_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 s5pc100_spi2_pdata = {
+ .cfg_gpio = s5pc100_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 13,
+ .high_speed = 1,
+ .tx_st_done = 21,
+};
+
+struct platform_device s5pc100_device_spi2 = {
+ .name = "s3c64xx-spi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pc100_spi2_resource),
+ .resource = s5pc100_spi2_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pc100_spi2_pdata,
+ },
+};
+
+void __init s5pc100_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 > S5PC100_SPI_SRCCLK_SPIBUS) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ pd = &s5pc100_spi0_pdata;
+ break;
+ case 1:
+ pd = &s5pc100_spi1_pdata;
+ break;
+ case 2:
+ pd = &s5pc100_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-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
new file mode 100644
index 00000000..bf4cd0fb
--- /dev/null
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -0,0 +1,167 @@
+/*
+ * 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 <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+static u64 dma_dmamask = DMA_BIT_MASK(32);
+
+static struct resource s5pc100_pdma0_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_PDMA0,
+ .end = S5PC100_PA_PDMA0 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA0,
+ .end = IRQ_PDMA0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pc100_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_IRDA,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S0S_TX,
+ [12] = DMACH_I2S1_RX,
+ [13] = DMACH_I2S1_TX,
+ [14] = DMACH_I2S2_RX,
+ [15] = DMACH_I2S2_TX,
+ [16] = DMACH_SPI0_RX,
+ [17] = DMACH_SPI0_TX,
+ [18] = DMACH_SPI1_RX,
+ [19] = DMACH_SPI1_TX,
+ [20] = DMACH_SPI2_RX,
+ [21] = DMACH_SPI2_TX,
+ [22] = DMACH_AC97_MICIN,
+ [23] = DMACH_AC97_PCMIN,
+ [24] = DMACH_AC97_PCMOUT,
+ [25] = DMACH_EXTERNAL,
+ [26] = DMACH_PWM,
+ [27] = DMACH_SPDIF,
+ [28] = DMACH_HSI_RX,
+ [29] = DMACH_HSI_TX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct platform_device s5pc100_device_pdma0 = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pc100_pdma0_resource),
+ .resource = s5pc100_pdma0_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pc100_pdma0_pdata,
+ },
+};
+
+static struct resource s5pc100_pdma1_resource[] = {
+ [0] = {
+ .start = S5PC100_PA_PDMA1,
+ .end = S5PC100_PA_PDMA1 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA1,
+ .end = IRQ_PDMA1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pc100_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_IRDA,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S0S_TX,
+ [12] = DMACH_I2S1_RX,
+ [13] = DMACH_I2S1_TX,
+ [14] = DMACH_I2S2_RX,
+ [15] = DMACH_I2S2_TX,
+ [16] = DMACH_SPI0_RX,
+ [17] = DMACH_SPI0_TX,
+ [18] = DMACH_SPI1_RX,
+ [19] = DMACH_SPI1_TX,
+ [20] = DMACH_SPI2_RX,
+ [21] = DMACH_SPI2_TX,
+ [22] = DMACH_PCM0_RX,
+ [23] = DMACH_PCM0_TX,
+ [24] = DMACH_PCM1_RX,
+ [25] = DMACH_PCM1_TX,
+ [26] = DMACH_MSM_REQ0,
+ [27] = DMACH_MSM_REQ1,
+ [28] = DMACH_MSM_REQ2,
+ [29] = DMACH_MSM_REQ3,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct platform_device s5pc100_device_pdma1 = {
+ .name = "s3c-pl330",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pc100_pdma1_resource),
+ .resource = s5pc100_pdma1_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pc100_pdma1_pdata,
+ },
+};
+
+static struct platform_device *s5pc100_dmacs[] __initdata = {
+ &s5pc100_device_pdma0,
+ &s5pc100_device_pdma1,
+};
+
+static int __init s5pc100_dma_init(void)
+{
+ platform_add_devices(s5pc100_dmacs, ARRAY_SIZE(s5pc100_dmacs));
+
+ return 0;
+}
+arch_initcall(s5pc100_dma_init);
diff --git a/arch/arm/mach-s5pc100/include/mach/debug-macro.S b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
new file mode 100644
index 00000000..b2ba95dd
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/debug-macro.S
@@ -0,0 +1,39 @@
+/* arch/arm/mach-s5pc100/include/mach/debug-macro.S
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ *
+ * Based on mach-s3c6400/include/mach/debug-macro.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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pc100/include/mach/dma.h b/arch/arm/mach-s5pc100/include/mach/dma.h
new file mode 100644
index 00000000..81209eb1
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/dma.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/entry-macro.S b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
new file mode 100644
index 00000000..ba76af05
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/entry-macro.S
@@ -0,0 +1,50 @@
+/* arch/arm/mach-s5pc100/include/mach/entry-macro.S
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6400/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for the Samsung S5PC1XX series
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+*/
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, # S5P_IRQ_OFFSET + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic2
+ addeq \tmp, \base, #(VA_VIC2 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-s5pc100/include/mach/gpio.h b/arch/arm/mach-s5pc100/include/mach/gpio.h
new file mode 100644
index 00000000..29a8a12d
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/gpio.h
@@ -0,0 +1,151 @@
+/* arch/arm/mach-s5pc100/include/mach/gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - GPIO lib support
+ *
+ * Base on mach-s3c6400/include/mach/gpio.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H __FILE__
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
+/* GPIO bank sizes */
+#define S5PC100_GPIO_A0_NR (8)
+#define S5PC100_GPIO_A1_NR (5)
+#define S5PC100_GPIO_B_NR (8)
+#define S5PC100_GPIO_C_NR (5)
+#define S5PC100_GPIO_D_NR (7)
+#define S5PC100_GPIO_E0_NR (8)
+#define S5PC100_GPIO_E1_NR (6)
+#define S5PC100_GPIO_F0_NR (8)
+#define S5PC100_GPIO_F1_NR (8)
+#define S5PC100_GPIO_F2_NR (8)
+#define S5PC100_GPIO_F3_NR (4)
+#define S5PC100_GPIO_G0_NR (8)
+#define S5PC100_GPIO_G1_NR (3)
+#define S5PC100_GPIO_G2_NR (7)
+#define S5PC100_GPIO_G3_NR (7)
+#define S5PC100_GPIO_H0_NR (8)
+#define S5PC100_GPIO_H1_NR (8)
+#define S5PC100_GPIO_H2_NR (8)
+#define S5PC100_GPIO_H3_NR (8)
+#define S5PC100_GPIO_I_NR (8)
+#define S5PC100_GPIO_J0_NR (8)
+#define S5PC100_GPIO_J1_NR (5)
+#define S5PC100_GPIO_J2_NR (8)
+#define S5PC100_GPIO_J3_NR (8)
+#define S5PC100_GPIO_J4_NR (4)
+#define S5PC100_GPIO_K0_NR (8)
+#define S5PC100_GPIO_K1_NR (6)
+#define S5PC100_GPIO_K2_NR (8)
+#define S5PC100_GPIO_K3_NR (8)
+#define S5PC100_GPIO_L0_NR (8)
+#define S5PC100_GPIO_L1_NR (8)
+#define S5PC100_GPIO_L2_NR (8)
+#define S5PC100_GPIO_L3_NR (8)
+#define S5PC100_GPIO_L4_NR (8)
+
+/* GPIO bank numbes */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5PC100_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+ S5PC100_GPIO_A0_START = 0,
+ S5PC100_GPIO_A1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_A0),
+ S5PC100_GPIO_B_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_A1),
+ S5PC100_GPIO_C_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_B),
+ S5PC100_GPIO_D_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_C),
+ S5PC100_GPIO_E0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_D),
+ S5PC100_GPIO_E1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_E0),
+ S5PC100_GPIO_F0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_E1),
+ S5PC100_GPIO_F1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F0),
+ S5PC100_GPIO_F2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F1),
+ S5PC100_GPIO_F3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F2),
+ S5PC100_GPIO_G0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_F3),
+ S5PC100_GPIO_G1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G0),
+ S5PC100_GPIO_G2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G1),
+ S5PC100_GPIO_G3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G2),
+ S5PC100_GPIO_H0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_G3),
+ S5PC100_GPIO_H1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H0),
+ S5PC100_GPIO_H2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H1),
+ S5PC100_GPIO_H3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H2),
+ S5PC100_GPIO_I_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_H3),
+ S5PC100_GPIO_J0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_I),
+ S5PC100_GPIO_J1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J0),
+ S5PC100_GPIO_J2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J1),
+ S5PC100_GPIO_J3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J2),
+ S5PC100_GPIO_J4_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J3),
+ S5PC100_GPIO_K0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_J4),
+ S5PC100_GPIO_K1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K0),
+ S5PC100_GPIO_K2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K1),
+ S5PC100_GPIO_K3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K2),
+ S5PC100_GPIO_L0_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_K3),
+ S5PC100_GPIO_L1_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L0),
+ S5PC100_GPIO_L2_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L1),
+ S5PC100_GPIO_L3_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L2),
+ S5PC100_GPIO_L4_START = S5PC100_GPIO_NEXT(S5PC100_GPIO_L3),
+ S5PC100_GPIO_END = S5PC100_GPIO_NEXT(S5PC100_GPIO_L4),
+};
+
+/* S5PC100 GPIO number definitions. */
+#define S5PC100_GPA0(_nr) (S5PC100_GPIO_A0_START + (_nr))
+#define S5PC100_GPA1(_nr) (S5PC100_GPIO_A1_START + (_nr))
+#define S5PC100_GPB(_nr) (S5PC100_GPIO_B_START + (_nr))
+#define S5PC100_GPC(_nr) (S5PC100_GPIO_C_START + (_nr))
+#define S5PC100_GPD(_nr) (S5PC100_GPIO_D_START + (_nr))
+#define S5PC100_GPE0(_nr) (S5PC100_GPIO_E0_START + (_nr))
+#define S5PC100_GPE1(_nr) (S5PC100_GPIO_E1_START + (_nr))
+#define S5PC100_GPF0(_nr) (S5PC100_GPIO_F0_START + (_nr))
+#define S5PC100_GPF1(_nr) (S5PC100_GPIO_F1_START + (_nr))
+#define S5PC100_GPF2(_nr) (S5PC100_GPIO_F2_START + (_nr))
+#define S5PC100_GPF3(_nr) (S5PC100_GPIO_F3_START + (_nr))
+#define S5PC100_GPG0(_nr) (S5PC100_GPIO_G0_START + (_nr))
+#define S5PC100_GPG1(_nr) (S5PC100_GPIO_G1_START + (_nr))
+#define S5PC100_GPG2(_nr) (S5PC100_GPIO_G2_START + (_nr))
+#define S5PC100_GPG3(_nr) (S5PC100_GPIO_G3_START + (_nr))
+#define S5PC100_GPH0(_nr) (S5PC100_GPIO_H0_START + (_nr))
+#define S5PC100_GPH1(_nr) (S5PC100_GPIO_H1_START + (_nr))
+#define S5PC100_GPH2(_nr) (S5PC100_GPIO_H2_START + (_nr))
+#define S5PC100_GPH3(_nr) (S5PC100_GPIO_H3_START + (_nr))
+#define S5PC100_GPI(_nr) (S5PC100_GPIO_I_START + (_nr))
+#define S5PC100_GPJ0(_nr) (S5PC100_GPIO_J0_START + (_nr))
+#define S5PC100_GPJ1(_nr) (S5PC100_GPIO_J1_START + (_nr))
+#define S5PC100_GPJ2(_nr) (S5PC100_GPIO_J2_START + (_nr))
+#define S5PC100_GPJ3(_nr) (S5PC100_GPIO_J3_START + (_nr))
+#define S5PC100_GPJ4(_nr) (S5PC100_GPIO_J4_START + (_nr))
+#define S5PC100_GPK0(_nr) (S5PC100_GPIO_K0_START + (_nr))
+#define S5PC100_GPK1(_nr) (S5PC100_GPIO_K1_START + (_nr))
+#define S5PC100_GPK2(_nr) (S5PC100_GPIO_K2_START + (_nr))
+#define S5PC100_GPK3(_nr) (S5PC100_GPIO_K3_START + (_nr))
+#define S5PC100_GPL0(_nr) (S5PC100_GPIO_L0_START + (_nr))
+#define S5PC100_GPL1(_nr) (S5PC100_GPIO_L1_START + (_nr))
+#define S5PC100_GPL2(_nr) (S5PC100_GPIO_L2_START + (_nr))
+#define S5PC100_GPL3(_nr) (S5PC100_GPIO_L3_START + (_nr))
+#define S5PC100_GPL4(_nr) (S5PC100_GPIO_L4_START + (_nr))
+
+/* It used the end of the S5PC100 gpios */
+#define S3C_GPIO_END S5PC100_GPIO_END
+
+/* define the number of gpios we need to the one after the MP04() range */
+#define ARCH_NR_GPIOS (S5PC100_GPIO_END + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/hardware.h b/arch/arm/mach-s5pc100/include/mach/hardware.h
new file mode 100644
index 00000000..6b38618c
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/hardware.h
@@ -0,0 +1,14 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/hardware.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - Hardware support
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/io.h b/arch/arm/mach-s5pc100/include/mach/io.h
new file mode 100644
index 00000000..819acf5e
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/io.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5pc100/include/mach/io.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * Default IO routines for S5PC100 systems
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
new file mode 100644
index 00000000..d2eb4757
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -0,0 +1,115 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/irqs.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - IRQ definitions
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H __FILE__
+
+#include <plat/irqs.h>
+
+/* VIC0: system, DMA, timer */
+#define IRQ_EINT16_31 S5P_IRQ_VIC0(16)
+#define IRQ_BATF S5P_IRQ_VIC0(17)
+#define IRQ_MDMA S5P_IRQ_VIC0(18)
+#define IRQ_PDMA0 S5P_IRQ_VIC0(19)
+#define IRQ_PDMA1 S5P_IRQ_VIC0(20)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER S5P_IRQ_VIC0(26)
+#define IRQ_WDT S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT S5P_IRQ_VIC0(30)
+
+/* VIC1: ARM, power, memory, connectivity */
+#define IRQ_PMU S5P_IRQ_VIC1(0)
+#define IRQ_CORTEX1 S5P_IRQ_VIC1(1)
+#define IRQ_CORTEX2 S5P_IRQ_VIC1(2)
+#define IRQ_CORTEX3 S5P_IRQ_VIC1(3)
+#define IRQ_CORTEX4 S5P_IRQ_VIC1(4)
+#define IRQ_IEMAPC S5P_IRQ_VIC1(5)
+#define IRQ_IEMIEC S5P_IRQ_VIC1(6)
+#define IRQ_ONENAND S5P_IRQ_VIC1(7)
+#define IRQ_NFC S5P_IRQ_VIC1(8)
+#define IRQ_CFCON S5P_IRQ_VIC1(9)
+#define IRQ_UART0 S5P_IRQ_VIC1(10)
+#define IRQ_UART1 S5P_IRQ_VIC1(11)
+#define IRQ_UART2 S5P_IRQ_VIC1(12)
+#define IRQ_UART3 S5P_IRQ_VIC1(13)
+#define IRQ_IIC S5P_IRQ_VIC1(14)
+#define IRQ_SPI0 S5P_IRQ_VIC1(15)
+#define IRQ_SPI1 S5P_IRQ_VIC1(16)
+#define IRQ_SPI2 S5P_IRQ_VIC1(17)
+#define IRQ_IRDA S5P_IRQ_VIC1(18)
+#define IRQ_IIC2 S5P_IRQ_VIC1(19)
+#define IRQ_IIC3 S5P_IRQ_VIC1(20)
+#define IRQ_HSIRX S5P_IRQ_VIC1(21)
+#define IRQ_HSITX S5P_IRQ_VIC1(22)
+#define IRQ_UHOST S5P_IRQ_VIC1(23)
+#define IRQ_OTG S5P_IRQ_VIC1(24)
+#define IRQ_MSM S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
+#define IRQ_MIPICSI S5P_IRQ_VIC1(29)
+#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
+
+/* VIC2: multimedia, audio, security */
+#define IRQ_LCD0 S5P_IRQ_VIC2(0)
+#define IRQ_LCD1 S5P_IRQ_VIC2(1)
+#define IRQ_LCD2 S5P_IRQ_VIC2(2)
+#define IRQ_LCD3 S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0 S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1 S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2 S5P_IRQ_VIC2(7)
+#define IRQ_JPEG S5P_IRQ_VIC2(8)
+#define IRQ_2D S5P_IRQ_VIC2(9)
+#define IRQ_3D S5P_IRQ_VIC2(10)
+#define IRQ_MIXER S5P_IRQ_VIC2(11)
+#define IRQ_HDMI S5P_IRQ_VIC2(12)
+#define IRQ_IIC1 S5P_IRQ_VIC2(13)
+#define IRQ_MFC S5P_IRQ_VIC2(14)
+#define IRQ_TVENC S5P_IRQ_VIC2(15)
+#define IRQ_I2S0 S5P_IRQ_VIC2(16)
+#define IRQ_I2S1 S5P_IRQ_VIC2(17)
+#define IRQ_I2S2 S5P_IRQ_VIC2(18)
+#define IRQ_AC97 S5P_IRQ_VIC2(19)
+#define IRQ_PCM0 S5P_IRQ_VIC2(20)
+#define IRQ_PCM1 S5P_IRQ_VIC2(21)
+#define IRQ_SPDIF S5P_IRQ_VIC2(22)
+#define IRQ_ADC S5P_IRQ_VIC2(23)
+#define IRQ_PENDN S5P_IRQ_VIC2(24)
+#define IRQ_TC IRQ_PENDN
+#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
+#define IRQ_CG S5P_IRQ_VIC2(26)
+#define IRQ_SEC S5P_IRQ_VIC2(27)
+#define IRQ_SECRX S5P_IRQ_VIC2(28)
+#define IRQ_SECTX S5P_IRQ_VIC2(29)
+#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
+#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
+#define IRQ_VIC_END S5P_IRQ_VIC2(31)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
+#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
+
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR 21
+
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
+
+/* Compatibility */
+#define IRQ_LCD_FIFO IRQ_LCD0
+#define IRQ_LCD_VSYNC IRQ_LCD1
+#define IRQ_LCD_SYSTEM IRQ_LCD2
+
+#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
new file mode 100644
index 00000000..ccbe6b76
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -0,0 +1,133 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/map.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5PC100_PA_SDRAM 0x20000000
+
+#define S5PC100_PA_ONENAND 0xE7100000
+#define S5PC100_PA_ONENAND_BUF 0xB0000000
+
+#define S5PC100_PA_CHIPID 0xE0000000
+
+#define S5PC100_PA_SYSCON 0xE0100000
+
+#define S5PC100_PA_OTHERS 0xE0200000
+
+#define S5PC100_PA_GPIO 0xE0300000
+
+#define S5PC100_PA_VIC0 0xE4000000
+#define S5PC100_PA_VIC1 0xE4100000
+#define S5PC100_PA_VIC2 0xE4200000
+
+#define S5PC100_PA_SROMC 0xE7000000
+
+#define S5PC100_PA_CFCON 0xE7800000
+
+#define S5PC100_PA_MDMA 0xE8100000
+#define S5PC100_PA_PDMA0 0xE9000000
+#define S5PC100_PA_PDMA1 0xE9200000
+
+#define S5PC100_PA_TIMER 0xEA000000
+#define S5PC100_PA_SYSTIMER 0xEA100000
+#define S5PC100_PA_WATCHDOG 0xEA200000
+#define S5PC100_PA_RTC 0xEA300000
+
+#define S5PC100_PA_UART 0xEC000000
+
+#define S5PC100_PA_IIC0 0xEC100000
+#define S5PC100_PA_IIC1 0xEC200000
+
+#define S5PC100_PA_SPI0 0xEC300000
+#define S5PC100_PA_SPI1 0xEC400000
+#define S5PC100_PA_SPI2 0xEC500000
+
+#define S5PC100_PA_USB_HSOTG 0xED200000
+#define S5PC100_PA_USB_HSPHY 0xED300000
+
+#define S5PC100_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000))
+
+#define S5PC100_PA_FB 0xEE000000
+
+#define S5PC100_PA_FIMC0 0xEE200000
+#define S5PC100_PA_FIMC1 0xEE300000
+#define S5PC100_PA_FIMC2 0xEE400000
+
+#define S5PC100_PA_I2S0 0xF2000000
+#define S5PC100_PA_I2S1 0xF2100000
+#define S5PC100_PA_I2S2 0xF2200000
+
+#define S5PC100_PA_AC97 0xF2300000
+
+#define S5PC100_PA_PCM0 0xF2400000
+#define S5PC100_PA_PCM1 0xF2500000
+
+#define S5PC100_PA_SPDIF 0xF2600000
+
+#define S5PC100_PA_TSADC 0xF3000000
+
+#define S5PC100_PA_KEYPAD 0xF3100000
+
+/* Compatibiltiy Defines */
+
+#define S3C_PA_FB S5PC100_PA_FB
+#define S3C_PA_HSMMC0 S5PC100_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 S5PC100_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 S5PC100_PA_HSMMC(2)
+#define S3C_PA_IIC S5PC100_PA_IIC0
+#define S3C_PA_IIC1 S5PC100_PA_IIC1
+#define S3C_PA_KEYPAD S5PC100_PA_KEYPAD
+#define S3C_PA_ONENAND S5PC100_PA_ONENAND
+#define S3C_PA_ONENAND_BUF S5PC100_PA_ONENAND_BUF
+#define S3C_PA_RTC S5PC100_PA_RTC
+#define S3C_PA_TSADC S5PC100_PA_TSADC
+#define S3C_PA_USB_HSOTG S5PC100_PA_USB_HSOTG
+#define S3C_PA_USB_HSPHY S5PC100_PA_USB_HSPHY
+#define S3C_PA_WDT S5PC100_PA_WATCHDOG
+
+#define S5P_PA_CHIPID S5PC100_PA_CHIPID
+#define S5P_PA_FIMC0 S5PC100_PA_FIMC0
+#define S5P_PA_FIMC1 S5PC100_PA_FIMC1
+#define S5P_PA_FIMC2 S5PC100_PA_FIMC2
+#define S5P_PA_SDRAM S5PC100_PA_SDRAM
+#define S5P_PA_SROMC S5PC100_PA_SROMC
+#define S5P_PA_SYSCON S5PC100_PA_SYSCON
+#define S5P_PA_TIMER S5PC100_PA_TIMER
+
+#define SAMSUNG_PA_ADC S5PC100_PA_TSADC
+#define SAMSUNG_PA_CFCON S5PC100_PA_CFCON
+#define SAMSUNG_PA_KEYPAD S5PC100_PA_KEYPAD
+
+#define S5PC100_VA_OTHERS (S3C_VA_SYS + 0x10000)
+
+#define S3C_SZ_ONENAND_BUF (SZ_256M - SZ_32M)
+
+/* UART */
+
+#define S3C_PA_UART S5PC100_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_SZ_UART SZ_256
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h
new file mode 100644
index 00000000..bda4e79f
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/memory.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-s5pc100/include/mach/memory.h
+ *
+ * Copyright 2008 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * Based on mach-s3c6400/include/mach/memory.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x20000000)
+
+#endif
diff --git a/arch/arm/mach-s5pc100/include/mach/pwm-clock.h b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
new file mode 100644
index 00000000..b34d2f7a
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/pwm-clock.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - pwm clock and timer support
+ *
+ * Based on mach-s3c6400/include/mach/pwm-clock.h
+ */
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg >= S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-clock.h b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
new file mode 100644
index 00000000..bc92da2e
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
@@ -0,0 +1,80 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PC100 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5PC100_REG_OTHERS(x) (S5PC100_VA_OTHERS + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK S5P_CLKREG(0x04)
+#define S5P_EPLL_LOCK S5P_CLKREG(0x08)
+#define S5P_HPLL_LOCK S5P_CLKREG(0x0C)
+
+#define S5P_APLL_CON S5P_CLKREG(0x100)
+#define S5P_MPLL_CON S5P_CLKREG(0x104)
+#define S5P_EPLL_CON S5P_CLKREG(0x108)
+#define S5P_HPLL_CON S5P_CLKREG(0x10C)
+
+#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1 S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3 S5P_CLKREG(0x20C)
+
+#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1 S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3 S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4 S5P_CLKREG(0x310)
+
+#define S5P_CLK_OUT S5P_CLKREG(0x400)
+
+#define S5P_CLKGATE_D00 S5P_CLKREG(0x500)
+#define S5P_CLKGATE_D01 S5P_CLKREG(0x504)
+#define S5P_CLKGATE_D02 S5P_CLKREG(0x508)
+
+#define S5P_CLKGATE_D10 S5P_CLKREG(0x520)
+#define S5P_CLKGATE_D11 S5P_CLKREG(0x524)
+#define S5P_CLKGATE_D12 S5P_CLKREG(0x528)
+#define S5P_CLKGATE_D13 S5P_CLKREG(0x52C)
+#define S5P_CLKGATE_D14 S5P_CLKREG(0x530)
+#define S5P_CLKGATE_D15 S5P_CLKREG(0x534)
+
+#define S5P_CLKGATE_D20 S5P_CLKREG(0x540)
+
+#define S5P_CLKGATE_SCLK0 S5P_CLKREG(0x560)
+#define S5P_CLKGATE_SCLK1 S5P_CLKREG(0x564)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_D0_MASK (0x7<<8)
+#define S5P_CLKDIV0_D0_SHIFT (8)
+#define S5P_CLKDIV0_PCLKD0_MASK (0x7<<12)
+#define S5P_CLKDIV0_PCLKD0_SHIFT (12)
+
+/* CLKDIV1 */
+#define S5P_CLKDIV1_D1_MASK (0x7<<12)
+#define S5P_CLKDIV1_D1_SHIFT (12)
+#define S5P_CLKDIV1_PCLKD1_MASK (0x7<<16)
+#define S5P_CLKDIV1_PCLKD1_SHIFT (16)
+
+#define S5PC100_SWRESET S5PC100_REG_OTHERS(0x000)
+#define S5PC100_MEM_SYS_CFG S5PC100_REG_OTHERS(0x200)
+
+#define S5PC100_SWRESET_RESETVAL 0xc100
+
+#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-fb.h b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
new file mode 100644
index 00000000..07aa4d60
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-fb.h
@@ -0,0 +1,105 @@
+/* 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/include/mach/regs-gpio.h b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
new file mode 100644
index 00000000..0bf73209
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-gpio.h
@@ -0,0 +1,38 @@
+/* linux/arch/arm/plat-s5pc100/include/plat/regs-gpio.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - GPIO register definitions
+ */
+
+#ifndef __ASM_MACH_S5PC100_REGS_GPIO_H
+#define __ASM_MACH_S5PC100_REGS_GPIO_H __FILE__
+
+#include <mach/map.h>
+
+#define S5PC100EINT30CON (S5P_VA_GPIO + 0xE00)
+#define S5P_EINT_CON(x) (S5PC100EINT30CON + ((x) * 0x4))
+
+#define S5PC100EINT30FLTCON0 (S5P_VA_GPIO + 0xE80)
+#define S5P_EINT_FLTCON(x) (S5PC100EINT30FLTCON0 + ((x) * 0x4))
+
+#define S5PC100EINT30MASK (S5P_VA_GPIO + 0xF00)
+#define S5P_EINT_MASK(x) (S5PC100EINT30MASK + ((x) * 0x4))
+
+#define S5PC100EINT30PEND (S5P_VA_GPIO + 0xF40)
+#define S5P_EINT_PEND(x) (S5PC100EINT30PEND + ((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(0x2)
+
+#define EINT_GPIO_0(x) S5PC100_GPH0(x)
+#define EINT_GPIO_1(x) S5PC100_GPH1(x)
+#define EINT_GPIO_2(x) S5PC100_GPH2(x)
+#define EINT_GPIO_3(x) S5PC100_GPH3(x)
+
+#endif /* __ASM_MACH_S5PC100_REGS_GPIO_H */
+
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-irq.h b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
new file mode 100644
index 00000000..4d9036d0
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/regs-irq.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <mach/map.h>
+#include <asm/hardware/vic.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/spi-clocks.h b/arch/arm/mach-s5pc100/include/mach/spi-clocks.h
new file mode 100644
index 00000000..65e42637
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/spi-clocks.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5pc100/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 __S5PC100_PLAT_SPI_CLKS_H
+#define __S5PC100_PLAT_SPI_CLKS_H __FILE__
+
+#define S5PC100_SPI_SRCCLK_PCLK 0
+#define S5PC100_SPI_SRCCLK_48M 1
+#define S5PC100_SPI_SRCCLK_SPIBUS 2
+
+#endif /* __S5PC100_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
new file mode 100644
index 00000000..a9ea57c0
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/system.h
@@ -0,0 +1,21 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/system.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - system implementation
+ *
+ * Based on mach-s3c6400/include/mach/system.h
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/system-reset.h>
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/tick.h b/arch/arm/mach-s5pc100/include/mach/tick.h
new file mode 100644
index 00000000..20f68730
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/tick.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5pc100/include/mach/tick.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S3C64XX - Timer tick support definitions
+ *
+ * Based on mach-s3c6400/include/mach/tick.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+/* note, the timer interrutps turn up in 2 places, the vic and then
+ * the timer block. We take the VIC as the base at the moment.
+ */
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/timex.h b/arch/arm/mach-s5pc100/include/mach/timex.h
new file mode 100644
index 00000000..47ffb17a
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/timex.h
@@ -0,0 +1,24 @@
+/* arch/arm/mach-s5pc100/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C6400 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/uncompress.h b/arch/arm/mach-s5pc100/include/mach/uncompress.h
new file mode 100644
index 00000000..01ccf535
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/uncompress.h
@@ -0,0 +1,28 @@
+/* arch/arm/mach-s5pc100/include/mach/uncompress.h
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * S5PC100 - uncompress code
+ *
+ * Based on mach-s3c6400/include/mach/uncompress.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+ fifo_mask = S3C2440_UFSTAT_TXMASK;
+ fifo_max = 63 << S3C2440_UFSTAT_TXSHIFT;
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/vmalloc.h b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
new file mode 100644
index 00000000..44c8e572
--- /dev/null
+++ b/arch/arm/mach-s5pc100/include/mach/vmalloc.h
@@ -0,0 +1,17 @@
+/* arch/arm/mach-s5pc100/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C6400 vmalloc definition
+*/
+
+#ifndef __ASM_ARCH_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pc100/init.c b/arch/arm/mach-s5pc100/init.c
new file mode 100644
index 00000000..19d7b523
--- /dev/null
+++ b/arch/arm/mach-s5pc100/init.c
@@ -0,0 +1,24 @@
+/* linux/arch/arm/plat-s5pc100/s5pc100-init.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5pc100.h>
+
+/* uart registration process */
+void __init s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
new file mode 100644
index 00000000..0525cb3e
--- /dev/null
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -0,0 +1,289 @@
+/* linux/arch/arm/mach-s5pc100/mach-smdkc100.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Author: Byungho Min <bhmin@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/pwm_backlight.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <mach/regs-gpio.h>
+
+#include <video/platform_lcd.h>
+
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <plat/regs-serial.h>
+#include <plat/gpio-cfg.h>
+
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/s5pc100.h>
+#include <plat/fb.h>
+#include <plat/iic.h>
+#include <plat/ata.h>
+#include <plat/adc.h>
+#include <plat/keypad.h>
+#include <plat/ts.h>
+#include <plat/audio.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC100_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC100_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2440_UFCON_RXTRIG8 | \
+ S3C2440_UFCON_TXTRIG16)
+
+static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC100_UCON_DEFAULT,
+ .ulcon = SMDKC100_ULCON_DEFAULT,
+ .ufcon = SMDKC100_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC100_UCON_DEFAULT,
+ .ulcon = SMDKC100_ULCON_DEFAULT,
+ .ufcon = SMDKC100_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC100_UCON_DEFAULT,
+ .ulcon = SMDKC100_ULCON_DEFAULT,
+ .ufcon = SMDKC100_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC100_UCON_DEFAULT,
+ .ulcon = SMDKC100_ULCON_DEFAULT,
+ .ufcon = SMDKC100_UFCON_DEFAULT,
+ },
+};
+
+/* I2C0 */
+static struct i2c_board_info i2c_devs0[] __initdata = {
+ {I2C_BOARD_INFO("wm8580", 0x1b),},
+};
+
+/* I2C1 */
+static struct i2c_board_info i2c_devs1[] __initdata = {
+};
+
+/* LCD power controller */
+static void smdkc100_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power) {
+ /* module reset */
+ gpio_direction_output(S5PC100_GPH0(6), 1);
+ mdelay(100);
+ gpio_direction_output(S5PC100_GPH0(6), 0);
+ mdelay(10);
+ gpio_direction_output(S5PC100_GPH0(6), 1);
+ mdelay(10);
+ }
+}
+
+static struct plat_lcd_data smdkc100_lcd_power_data = {
+ .set_power = smdkc100_lcd_power_set,
+};
+
+static struct platform_device smdkc100_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdkc100_lcd_power_data,
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win smdkc100_fb_win0 = {
+ /* this is to ensure we use win0 */
+ .win_mode = {
+ .left_margin = 8,
+ .right_margin = 13,
+ .upper_margin = 7,
+ .lower_margin = 5,
+ .hsync_len = 3,
+ .vsync_len = 1,
+ .xres = 800,
+ .yres = 480,
+ .refresh = 80,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
+ .win[0] = &smdkc100_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pc100_fb_gpio_setup_24bpp,
+};
+
+static struct s3c_ide_platdata smdkc100_ide_pdata __initdata = {
+ .setup_gpio = s5pc100_ide_setup_gpio,
+};
+
+static uint32_t smdkc100_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 smdkc100_keymap_data __initdata = {
+ .keymap = smdkc100_keymap,
+ .keymap_size = ARRAY_SIZE(smdkc100_keymap),
+};
+
+static struct samsung_keypad_platdata smdkc100_keypad_data __initdata = {
+ .keymap_data = &smdkc100_keymap_data,
+ .rows = 2,
+ .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,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_fb,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_ts,
+ &s3c_device_wdt,
+ &smdkc100_lcd_powerdev,
+ &samsung_asoc_dma,
+ &s5pc100_device_iis0,
+ &samsung_device_keypad,
+ &s5pc100_device_ac97,
+ &s3c_device_rtc,
+ &s5p_device_fimc0,
+ &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 = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdkc100_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(12000000);
+ s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs));
+}
+
+static void __init smdkc100_machine_init(void)
+{
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ /* I2C */
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
+ i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+
+ s3c_fb_set_platdata(&smdkc100_lcd_pdata);
+ s3c_ide_set_platdata(&smdkc100_ide_pdata);
+
+ samsung_keypad_set_platdata(&smdkc100_keypad_data);
+
+ s5pc100_spdif_setup_gpio(S5PC100_SPDIF_GPD);
+
+ /* LCD init */
+ gpio_request(S5PC100_GPH0(6), "GPH0");
+ smdkc100_lcd_power_set(&smdkc100_lcd_power_data, 0);
+ platform_add_devices(smdkc100_devices, ARRAY_SIZE(smdkc100_devices));
+}
+
+MACHINE_START(SMDKC100, "SMDKC100")
+ /* Maintainer: Byungho Min <bhmin@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pc100_init_irq,
+ .map_io = smdkc100_map_io,
+ .init_machine = smdkc100_machine_init,
+ .timer = &s3c24xx_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pc100/setup-fb-24bpp.c b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
new file mode 100644
index 00000000..d31c0f3f
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-fb-24bpp.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/mach-s5pc100/setup-fb-24bpp.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *
+ * Base S5PC100 setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can 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 <mach/regs-fb.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <plat/gpio-cfg.h>
+
+#define DISR_OFFSET 0x7008
+
+static void s5pc100_fb_setgpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
+}
+
+void s5pc100_fb_gpio_setup_24bpp(void)
+{
+ s5pc100_fb_setgpios(S5PC100_GPF0(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF1(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF2(0), 8);
+ s5pc100_fb_setgpios(S5PC100_GPF3(0), 4);
+}
diff --git a/arch/arm/mach-s5pc100/setup-i2c0.c b/arch/arm/mach-s5pc100/setup-i2c0.c
new file mode 100644
index 00000000..eaef7a3b
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-i2c0.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pc100/setup-i2c0.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC100 I2C bus 0 gpio configuration
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PC100_GPD(3), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pc100/setup-i2c1.c b/arch/arm/mach-s5pc100/setup-i2c1.c
new file mode 100644
index 00000000..aaff74a9
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-i2c1.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pc100/setup-i2c1.c
+ *
+ * Copyright 2009 Samsung Electronics Co.
+ * Byungho Min <bhmin@samsung.com>
+ *
+ * Base S5PC100 I2C bus 1 gpio configuration
+ *
+ * Based on plat-s3c64xx/setup-i2c1.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <linux/gpio.h>
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PC100_GPD(5), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pc100/setup-ide.c b/arch/arm/mach-s5pc100/setup-ide.c
new file mode 100644
index 00000000..223aae04
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-ide.c
@@ -0,0 +1,57 @@
+/* linux/arch/arm/mach-s5pc100/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PC100 setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+
+static void s5pc100_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
+void s5pc100_ide_setup_gpio(void)
+{
+ u32 reg;
+
+ /* Independent CF interface, CF chip select configuration */
+ reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
+ writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
+
+ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ0(0), 8);
+
+ /*CF_Data[0 - 7] */
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ2(0), 8);
+
+ /* CF_Data[8 - 15] */
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ3(0), 8);
+
+ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+ s5pc100_ide_cfg_gpios(S5PC100_GPJ4(0), 4);
+
+ /* EBI_OE, EBI_WE */
+ s3c_gpio_cfgpin_range(S5PC100_GPK0(6), 2, S3C_GPIO_SFN(0));
+
+ /* CF_OE, CF_WE */
+ s3c_gpio_cfgrange_nopull(S5PC100_GPK1(6), 8, S3C_GPIO_SFN(2));
+
+ /* CF_CD */
+ s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PC100_GPK3(5), S3C_GPIO_PULL_NONE);
+}
diff --git a/arch/arm/mach-s5pc100/setup-keypad.c b/arch/arm/mach-s5pc100/setup-keypad.c
new file mode 100644
index 00000000..ada377f0
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-keypad.c
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5pc100/setup-keypad.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * GPIO configuration for S5PC100 KeyPad 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/gpio.h>
+#include <plat/gpio-cfg.h>
+
+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(S5PC100_GPH3(0), rows, S3C_GPIO_SFN(3));
+
+ /* Set all the necessary GPH2 pins to special-function 3: KP_COL[x] */
+ s3c_gpio_cfgrange_nopull(S5PC100_GPH2(0), cols, S3C_GPIO_SFN(3));
+}
diff --git a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
new file mode 100644
index 00000000..03c02d04
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
@@ -0,0 +1,71 @@
+/* linux/arch/arm/plat-s5pc100/setup-sdhci-gpio.c
+ *
+ * Copyright 2009 Samsung Eletronics
+ *
+ * S5PC100 - 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 s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+ unsigned int num;
+
+ num = width;
+ /* In case of 8 width, we should decrease the 2 */
+ if (width == 8)
+ num = width - 2;
+
+ /* Set all the necessary GPG0/GPG1 pins to special-function 0 */
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG0(0), 2 + num, S3C_GPIO_SFN(2));
+
+ if (width == 8)
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG1(0), 2, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+ }
+}
+
+void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG2 pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG2(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+ }
+}
+
+void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG3 pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PC100_GPG3(0), 2 + width, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+ }
+}
diff --git a/arch/arm/mach-s5pc100/setup-sdhci.c b/arch/arm/mach-s5pc100/setup-sdhci.c
new file mode 100644
index 00000000..be25879b
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-sdhci.c
@@ -0,0 +1,65 @@
+/* linux/arch/arm/mach-s5pc100/setup-sdhci.c
+ *
+ * Copyright 2008 Samsung Electronics
+ *
+ * S5PC100 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * Based on mach-s3c6410/setup-sdhci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pc100_hsmmc_clksrcs[4] = {
+ [0] = "hsmmc", /* HCLK */
+ /* [1] = "hsmmc", - duplicate HCLK entry */
+ [2] = "sclk_mmc", /* mmc_bus */
+ /* [3] = "48m", - note not successfully used yet */
+};
+
+
+void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ /* don't need to alter anything according to card-type */
+
+ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
new file mode 100644
index 00000000..37b5a975
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -0,0 +1,175 @@
+# arch/arm/mach-s5pv210/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+# Configuration options for the S5PV210/S5PC110
+
+if ARCH_S5PV210
+
+config CPU_S5PV210
+ bool
+ select S3C_PL330_DMA
+ select S5P_EXT_INT
+ select S5P_HRT
+ select S5PV210_PM if PM
+ help
+ Enable S5PV210 CPU support
+
+config S5PV210_SETUP_I2C1
+ bool
+ help
+ Common setup code for i2c bus 1.
+
+config S5PV210_SETUP_I2C2
+ bool
+ help
+ Common setup code for i2c bus 2.
+
+config S5PV210_SETUP_IDE
+ bool
+ help
+ Common setup code for S5PV210 IDE GPIO configurations
+
+config S5PV210_SETUP_FB_24BPP
+ bool
+ help
+ Common setup code for S5PV210 with an 24bpp RGB display helper.
+
+config S5PV210_SETUP_KEYPAD
+ bool
+ help
+ Common setup code for keypad.
+
+config S5PV210_SETUP_SDHCI
+ bool
+ select S5PV210_SETUP_SDHCI_GPIO
+ help
+ Internal helper functions for S5PV210 based SDHCI systems
+
+config S5PV210_SETUP_SDHCI_GPIO
+ bool
+ help
+ Common setup code for SDHCI gpio.
+
+config S5PV210_SETUP_FIMC
+ bool
+ help
+ Common setup code for the camera interfaces.
+
+menu "S5PC110 Machines"
+
+config MACH_AQUILA
+ bool "Aquila"
+ select CPU_S5PV210
+ select S3C_DEV_FB
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S5P_DEV_ONENAND
+ select S5PV210_SETUP_FB_24BPP
+ select S5PV210_SETUP_SDHCI
+ help
+ Machine support for the Samsung Aquila target based on S5PC110 SoC
+
+config MACH_GONI
+ bool "GONI"
+ select CPU_S5PV210
+ select S5P_GPIO_INT
+ select S3C_DEV_FB
+ select S5P_DEV_FIMC0
+ select S5P_DEV_FIMC1
+ select S5P_DEV_FIMC2
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_USB_HSOTG
+ select S5P_DEV_ONENAND
+ select SAMSUNG_DEV_KEYPAD
+ select S5PV210_SETUP_FB_24BPP
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_KEYPAD
+ select S5PV210_SETUP_SDHCI
+ help
+ Machine support for Samsung GONI board
+ S5PC110(MCP) is one of package option of S5PV210
+
+config MACH_SMDKC110
+ bool "SMDKC110"
+ select CPU_S5PV210
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select SAMSUNG_DEV_IDE
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_IDE
+ help
+ Machine support for Samsung SMDKC110
+ S5PC110(MCP) is one of package option of S5PV210
+
+endmenu
+
+menu "S5PV210 Machines"
+
+config MACH_SMDKV210
+ bool "SMDKV210"
+ select CPU_S5PV210
+ 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_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
+ help
+ Machine support for Samsung SMDKV210
+
+config MACH_TORBRECK
+ bool "Torbreck"
+ select CPU_S5PV210
+ select ARCH_SPARSEMEM_ENABLE
+ select S3C_DEV_HSMMC
+ select S3C_DEV_HSMMC1
+ select S3C_DEV_HSMMC2
+ select S3C_DEV_HSMMC3
+ select S3C_DEV_I2C1
+ select S3C_DEV_I2C2
+ select S3C_DEV_RTC
+ select S3C_DEV_WDT
+ select S5PV210_SETUP_I2C1
+ select S5PV210_SETUP_I2C2
+ select S5PV210_SETUP_SDHCI
+ help
+ Machine support for aESOP Torbreck
+
+endmenu
+
+config S5PV210_PM
+ bool
+ help
+ Power Management code common to S5PV210
+
+endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
new file mode 100644
index 00000000..50907aca
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -0,0 +1,40 @@
+# arch/arm/mach-s5pv210/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+# Core support for S5PV210 system
+
+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
+
+# machine support
+
+obj-$(CONFIG_MACH_AQUILA) += mach-aquila.o
+obj-$(CONFIG_MACH_SMDKV210) += mach-smdkv210.o
+obj-$(CONFIG_MACH_SMDKC110) += mach-smdkc110.o
+obj-$(CONFIG_MACH_GONI) += mach-goni.o
+obj-$(CONFIG_MACH_TORBRECK) += mach-torbreck.o
+
+# device support
+
+obj-y += dev-audio.o
+obj-$(CONFIG_S3C64XX_DEV_SPI) += dev-spi.o
+
+obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
+obj-$(CONFIG_S5PV210_SETUP_FIMC) += setup-fimc.o
+obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o
+obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
+obj-$(CONFIG_S5PV210_SETUP_KEYPAD) += setup-keypad.o
+obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o
+obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5pv210/Makefile.boot b/arch/arm/mach-s5pv210/Makefile.boot
new file mode 100644
index 00000000..ff90aa13
--- /dev/null
+++ b/arch/arm/mach-s5pv210/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
new file mode 100644
index 00000000..2d599499
--- /dev/null
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -0,0 +1,1243 @@
+/* linux/arch/arm/mach-s5pv210/clock.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+
+#include <plat/cpu-freq.h>
+#include <mach/regs-clock.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>
+
+static unsigned long xtal;
+
+static struct clksrc_clk clk_mout_apll = {
+ .clk = {
+ .name = "mout_apll",
+ .id = -1,
+ },
+ .sources = &clk_src_apll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_epll = {
+ .clk = {
+ .name = "mout_epll",
+ .id = -1,
+ },
+ .sources = &clk_src_epll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_mout_mpll = {
+ .clk = {
+ .name = "mout_mpll",
+ .id = -1,
+ },
+ .sources = &clk_src_mpll,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
+};
+
+static struct clk *clkset_armclk_list[] = {
+ [0] = &clk_mout_apll.clk,
+ [1] = &clk_mout_mpll.clk,
+};
+
+static struct clksrc_sources clkset_armclk = {
+ .sources = clkset_armclk_list,
+ .nr_sources = ARRAY_SIZE(clkset_armclk_list),
+};
+
+static struct clksrc_clk clk_armclk = {
+ .clk = {
+ .name = "armclk",
+ .id = -1,
+ },
+ .sources = &clkset_armclk,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_msys = {
+ .clk = {
+ .name = "hclk_msys",
+ .id = -1,
+ .parent = &clk_armclk.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
+};
+
+static struct clksrc_clk clk_pclk_msys = {
+ .clk = {
+ .name = "pclk_msys",
+ .id = -1,
+ .parent = &clk_hclk_msys.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
+};
+
+static struct clksrc_clk clk_sclk_a2m = {
+ .clk = {
+ .name = "sclk_a2m",
+ .id = -1,
+ .parent = &clk_mout_apll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
+};
+
+static struct clk *clkset_hclk_sys_list[] = {
+ [0] = &clk_mout_mpll.clk,
+ [1] = &clk_sclk_a2m.clk,
+};
+
+static struct clksrc_sources clkset_hclk_sys = {
+ .sources = clkset_hclk_sys_list,
+ .nr_sources = ARRAY_SIZE(clkset_hclk_sys_list),
+};
+
+static struct clksrc_clk clk_hclk_dsys = {
+ .clk = {
+ .name = "hclk_dsys",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_sys,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_dsys = {
+ .clk = {
+ .name = "pclk_dsys",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
+};
+
+static struct clksrc_clk clk_hclk_psys = {
+ .clk = {
+ .name = "hclk_psys",
+ .id = -1,
+ },
+ .sources = &clkset_hclk_sys,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
+};
+
+static struct clksrc_clk clk_pclk_psys = {
+ .clk = {
+ .name = "pclk_psys",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
+};
+
+static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
+}
+
+static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
+}
+
+static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
+}
+
+static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
+}
+
+static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
+}
+
+static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
+{
+ return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
+}
+
+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,
+};
+
+static struct clk clk_sclk_usbphy1 = {
+ .name = "sclk_usbphy1",
+ .id = -1,
+};
+
+static struct clk clk_pcmcdclk0 = {
+ .name = "pcmcdclk",
+ .id = -1,
+};
+
+static struct clk clk_pcmcdclk1 = {
+ .name = "pcmcdclk",
+ .id = -1,
+};
+
+static struct clk clk_pcmcdclk2 = {
+ .name = "pcmcdclk",
+ .id = -1,
+};
+
+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 = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 7),
+ },
+ .sources = &clkset_vpllsrc,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 28, .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_CLK_SRC0, .shift = 12, .size = 1 },
+};
+
+static struct clk *clkset_moutdmc0src_list[] = {
+ [0] = &clk_sclk_a2m.clk,
+ [1] = &clk_mout_mpll.clk,
+ [2] = NULL,
+ [3] = NULL,
+};
+
+static struct clksrc_sources clkset_moutdmc0src = {
+ .sources = clkset_moutdmc0src_list,
+ .nr_sources = ARRAY_SIZE(clkset_moutdmc0src_list),
+};
+
+static struct clksrc_clk clk_mout_dmc0 = {
+ .clk = {
+ .name = "mout_dmc0",
+ .id = -1,
+ },
+ .sources = &clkset_moutdmc0src,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+};
+
+static struct clksrc_clk clk_sclk_dmc0 = {
+ .clk = {
+ .name = "sclk_dmc0",
+ .id = -1,
+ .parent = &clk_mout_dmc0.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+};
+
+static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
+{
+ return clk_get_rate(clk->parent) / 2;
+}
+
+static struct clk_ops clk_hclk_imem_ops = {
+ .get_rate = s5pv210_clk_imem_get_rate,
+};
+
+static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
+{
+ return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+}
+
+static struct clk_ops clk_fout_apll_ops = {
+ .get_rate = s5pv210_clk_fout_apll_get_rate,
+};
+
+static struct clk init_clocks_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,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1<<29),
+ }, {
+ .name = "fimc",
+ .id = 0,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 24),
+ }, {
+ .name = "fimc",
+ .id = 1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 25),
+ }, {
+ .name = "fimc",
+ .id = 2,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 26),
+ }, {
+ .name = "otg",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<17),
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_hclk_dsys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<0),
+ }, {
+ .name = "cfcon",
+ .id = 0,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1<<25),
+ }, {
+ .name = "hsmmc",
+ .id = 0,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<17),
+ }, {
+ .name = "hsmmc",
+ .id = 2,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<18),
+ }, {
+ .name = "hsmmc",
+ .id = 3,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip2_ctrl,
+ .ctrlbit = (1<<19),
+ }, {
+ .name = "systimer",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<16),
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<22),
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<15),
+ }, {
+ .name = "i2c",
+ .id = 0,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<7),
+ }, {
+ .name = "i2c",
+ .id = 1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 10),
+ }, {
+ .name = "i2c",
+ .id = 2,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<9),
+ }, {
+ .name = "spi",
+ .id = 0,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<12),
+ }, {
+ .name = "spi",
+ .id = 1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<13),
+ }, {
+ .name = "spi",
+ .id = 2,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<14),
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<23),
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<24),
+ }, {
+ .name = "keypad",
+ .id = -1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<21),
+ }, {
+ .name = "iis",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1<<4),
+ }, {
+ .name = "iis",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 5),
+ }, {
+ .name = "iis",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 6),
+ }, {
+ .name = "spdif",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "hclk_imem",
+ .id = -1,
+ .parent = &clk_hclk_msys.clk,
+ .ctrlbit = (1 << 5),
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ops = &clk_hclk_imem_ops,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 17),
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 18),
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 19),
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_pclk_psys.clk,
+ .enable = s5pv210_clk_ip3_ctrl,
+ .ctrlbit = (1 << 20),
+ }, {
+ .name = "sromc",
+ .id = -1,
+ .parent = &clk_hclk_psys.clk,
+ .enable = s5pv210_clk_ip1_ctrl,
+ .ctrlbit = (1 << 26),
+ },
+};
+
+static struct clk *clkset_uart_list[] = {
+ [6] = &clk_mout_mpll.clk,
+ [7] = &clk_mout_epll.clk,
+};
+
+static struct clksrc_sources clkset_uart = {
+ .sources = clkset_uart_list,
+ .nr_sources = ARRAY_SIZE(clkset_uart_list),
+};
+
+static struct clk *clkset_group1_list[] = {
+ [0] = &clk_sclk_a2m.clk,
+ [1] = &clk_mout_mpll.clk,
+ [2] = &clk_mout_epll.clk,
+ [3] = &clk_sclk_vpll.clk,
+};
+
+static struct clksrc_sources clkset_group1 = {
+ .sources = clkset_group1_list,
+ .nr_sources = ARRAY_SIZE(clkset_group1_list),
+};
+
+static struct clk *clkset_sclk_onenand_list[] = {
+ [0] = &clk_hclk_psys.clk,
+ [1] = &clk_hclk_dsys.clk,
+};
+
+static struct clksrc_sources clkset_sclk_onenand = {
+ .sources = clkset_sclk_onenand_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_onenand_list),
+};
+
+static struct clk *clkset_sclk_dac_list[] = {
+ [0] = &clk_sclk_vpll.clk,
+ [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_dac = {
+ .sources = clkset_sclk_dac_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_dac_list),
+};
+
+static struct clksrc_clk clk_sclk_dac = {
+ .clk = {
+ .name = "sclk_dac",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 2),
+ },
+ .sources = &clkset_sclk_dac,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
+};
+
+static struct clksrc_clk clk_sclk_pixel = {
+ .clk = {
+ .name = "sclk_pixel",
+ .id = -1,
+ .parent = &clk_sclk_vpll.clk,
+ },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
+};
+
+static struct clk *clkset_sclk_hdmi_list[] = {
+ [0] = &clk_sclk_pixel.clk,
+ [1] = &clk_sclk_hdmiphy,
+};
+
+static struct clksrc_sources clkset_sclk_hdmi = {
+ .sources = clkset_sclk_hdmi_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_hdmi_list),
+};
+
+static struct clksrc_clk clk_sclk_hdmi = {
+ .clk = {
+ .name = "sclk_hdmi",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 0),
+ },
+ .sources = &clkset_sclk_hdmi,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
+};
+
+static struct clk *clkset_sclk_mixer_list[] = {
+ [0] = &clk_sclk_dac.clk,
+ [1] = &clk_sclk_hdmi.clk,
+};
+
+static struct clksrc_sources clkset_sclk_mixer = {
+ .sources = clkset_sclk_mixer_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list),
+};
+
+static struct clk *clkset_sclk_audio0_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_pcmcdclk0,
+ [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_sclk_audio0 = {
+ .sources = clkset_sclk_audio0_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio0_list),
+};
+
+static struct clksrc_clk clk_sclk_audio0 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 24),
+ },
+ .sources = &clkset_sclk_audio0,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio1_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_pcmcdclk1,
+ [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_sclk_audio1 = {
+ .sources = clkset_sclk_audio1_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio1_list),
+};
+
+static struct clksrc_clk clk_sclk_audio1 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 25),
+ },
+ .sources = &clkset_sclk_audio1,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
+};
+
+static struct clk *clkset_sclk_audio2_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_pcmcdclk0,
+ [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_sclk_audio2 = {
+ .sources = clkset_sclk_audio2_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_audio2_list),
+};
+
+static struct clksrc_clk clk_sclk_audio2 = {
+ .clk = {
+ .name = "sclk_audio",
+ .id = 2,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 26),
+ },
+ .sources = &clkset_sclk_audio2,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
+};
+
+static struct clk *clkset_sclk_spdif_list[] = {
+ [0] = &clk_sclk_audio0.clk,
+ [1] = &clk_sclk_audio1.clk,
+ [2] = &clk_sclk_audio2.clk,
+};
+
+static struct clksrc_sources clkset_sclk_spdif = {
+ .sources = clkset_sclk_spdif_list,
+ .nr_sources = ARRAY_SIZE(clkset_sclk_spdif_list),
+};
+
+static int s5pv210_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct clk *pclk;
+ int ret;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ ret = pclk->ops->set_rate(pclk, rate);
+ clk_put(pclk);
+
+ return ret;
+}
+
+static unsigned long s5pv210_spdif_get_rate(struct clk *clk)
+{
+ struct clk *pclk;
+ int rate;
+
+ pclk = clk_get_parent(clk);
+ if (IS_ERR(pclk))
+ return -EINVAL;
+
+ rate = pclk->ops->get_rate(clk);
+ clk_put(pclk);
+
+ return rate;
+}
+
+static struct clk_ops s5pv210_sclk_spdif_ops = {
+ .set_rate = s5pv210_spdif_set_rate,
+ .get_rate = s5pv210_spdif_get_rate,
+};
+
+static struct clksrc_clk clk_sclk_spdif = {
+ .clk = {
+ .name = "sclk_spdif",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 27),
+ .ops = &s5pv210_sclk_spdif_ops,
+ },
+ .sources = &clkset_sclk_spdif,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
+};
+
+static struct clk *clkset_group2_list[] = {
+ [0] = &clk_ext_xtal_mux,
+ [1] = &clk_xusbxti,
+ [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_group2 = {
+ .sources = clkset_group2_list,
+ .nr_sources = ARRAY_SIZE(clkset_group2_list),
+};
+
+static struct clksrc_clk clksrcs[] = {
+ {
+ .clk = {
+ .name = "sclk_dmc",
+ .id = -1,
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_onenand",
+ .id = -1,
+ },
+ .sources = &clkset_sclk_onenand,
+ .reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 13),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = 2,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 14),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "uclk1",
+ .id = 3,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 15),
+ },
+ .sources = &clkset_uart,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mixer",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 1),
+ },
+ .sources = &clkset_sclk_mixer,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 0,
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 2),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 1,
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 3),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimc",
+ .id = 2,
+ .enable = s5pv210_clk_mask1_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam",
+ .id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 3),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_cam",
+ .id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 4),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimd",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 5),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 9),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 2,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 10),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mmc",
+ .id = 3,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 11),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_mfc",
+ .id = -1,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_g2d",
+ .id = -1,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 12),
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_g3d",
+ .id = -1,
+ .enable = s5pv210_clk_ip0_ctrl,
+ .ctrlbit = (1 << 8),
+ },
+ .sources = &clkset_group1,
+ .reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
+ .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_csis",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 6),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 0,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 16),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_spi",
+ .id = 1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 17),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_pwi",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 29),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_pwm",
+ .id = -1,
+ .enable = s5pv210_clk_mask0_ctrl,
+ .ctrlbit = (1 << 19),
+ },
+ .sources = &clkset_group2,
+ .reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
+ .reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
+ },
+};
+
+/* Clock initialisation code */
+static struct clksrc_clk *sysclks[] = {
+ &clk_mout_apll,
+ &clk_mout_epll,
+ &clk_mout_mpll,
+ &clk_armclk,
+ &clk_hclk_msys,
+ &clk_sclk_a2m,
+ &clk_hclk_dsys,
+ &clk_hclk_psys,
+ &clk_pclk_msys,
+ &clk_pclk_dsys,
+ &clk_pclk_psys,
+ &clk_vpllsrc,
+ &clk_sclk_vpll,
+ &clk_sclk_dac,
+ &clk_sclk_pixel,
+ &clk_sclk_hdmi,
+ &clk_mout_dmc0,
+ &clk_sclk_dmc0,
+ &clk_sclk_audio0,
+ &clk_sclk_audio1,
+ &clk_sclk_audio2,
+ &clk_sclk_spdif,
+};
+
+static u32 epll_div[][6] = {
+ { 48000000, 0, 48, 3, 3, 0 },
+ { 96000000, 0, 48, 3, 2, 0 },
+ { 144000000, 1, 72, 3, 2, 0 },
+ { 192000000, 0, 48, 3, 1, 0 },
+ { 288000000, 1, 72, 3, 1, 0 },
+ { 32750000, 1, 65, 3, 4, 35127 },
+ { 32768000, 1, 65, 3, 4, 35127 },
+ { 45158400, 0, 45, 3, 3, 10355 },
+ { 45000000, 0, 45, 3, 3, 10355 },
+ { 45158000, 0, 45, 3, 3, 10355 },
+ { 49125000, 0, 49, 3, 3, 9961 },
+ { 49152000, 0, 49, 3, 3, 9961 },
+ { 67737600, 1, 67, 3, 3, 48366 },
+ { 67738000, 1, 67, 3, 3, 48366 },
+ { 73800000, 1, 73, 3, 3, 47710 },
+ { 73728000, 1, 73, 3, 3, 47710 },
+ { 36000000, 1, 32, 3, 4, 0 },
+ { 60000000, 1, 60, 3, 3, 0 },
+ { 72000000, 1, 72, 3, 3, 0 },
+ { 80000000, 1, 80, 3, 3, 0 },
+ { 84000000, 0, 42, 3, 2, 0 },
+ { 50000000, 0, 50, 3, 3, 0 },
+};
+
+static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int epll_con, epll_con_k;
+ unsigned int i;
+
+ /* Return if nothing changed */
+ if (clk->rate == rate)
+ return 0;
+
+ epll_con = __raw_readl(S5P_EPLL_CON);
+ epll_con_k = __raw_readl(S5P_EPLL_CON1);
+
+ epll_con_k &= ~PLL46XX_KDIV_MASK;
+ epll_con &= ~(1 << 27 |
+ PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
+ PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
+ PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+
+ for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+ if (epll_div[i][0] == rate) {
+ epll_con_k |= epll_div[i][5] << 0;
+ epll_con |= (epll_div[i][1] << 27 |
+ epll_div[i][2] << PLL46XX_MDIV_SHIFT |
+ epll_div[i][3] << PLL46XX_PDIV_SHIFT |
+ epll_div[i][4] << PLL46XX_SDIV_SHIFT);
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(epll_div)) {
+ printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ __raw_writel(epll_con, S5P_EPLL_CON);
+ __raw_writel(epll_con_k, S5P_EPLL_CON1);
+
+ printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+ clk->rate, rate);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static struct clk_ops s5pv210_epll_ops = {
+ .set_rate = s5pv210_epll_set_rate,
+ .get_rate = s5p_epll_get_rate,
+};
+
+void __init_or_cpufreq s5pv210_setup_clocks(void)
+{
+ struct clk *xtal_clk;
+ unsigned long vpllsrc;
+ unsigned long armclk;
+ unsigned long hclk_msys;
+ unsigned long hclk_dsys;
+ unsigned long hclk_psys;
+ unsigned long pclk_msys;
+ unsigned long pclk_dsys;
+ unsigned long pclk_psys;
+ unsigned long apll;
+ unsigned long mpll;
+ unsigned long epll;
+ unsigned long vpll;
+ unsigned int ptr;
+ u32 clkdiv0, clkdiv1;
+
+ /* Set functions for clk_fout_epll */
+ clk_fout_epll.enable = s5p_epll_enable;
+ clk_fout_epll.ops = &s5pv210_epll_ops;
+
+ printk(KERN_DEBUG "%s: registering clocks\n", __func__);
+
+ clkdiv0 = __raw_readl(S5P_CLK_DIV0);
+ clkdiv1 = __raw_readl(S5P_CLK_DIV1);
+
+ printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
+ __func__, clkdiv0, clkdiv1);
+
+ xtal_clk = clk_get(NULL, "xtal");
+ BUG_ON(IS_ERR(xtal_clk));
+
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
+
+ apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
+ mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
+ epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
+ __raw_readl(S5P_EPLL_CON1), pll_4600);
+ vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
+ vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
+
+ clk_fout_apll.ops = &clk_fout_apll_ops;
+ clk_fout_mpll.rate = mpll;
+ clk_fout_epll.rate = epll;
+ clk_fout_vpll.rate = vpll;
+
+ printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
+ apll, mpll, epll, vpll);
+
+ armclk = clk_get_rate(&clk_armclk.clk);
+ hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
+ hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
+ hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
+ pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
+ pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
+ pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
+
+ printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
+ "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
+ armclk, hclk_msys, hclk_dsys, hclk_psys,
+ pclk_msys, pclk_dsys, pclk_psys);
+
+ clk_f.rate = armclk;
+ clk_h.rate = hclk_psys;
+ clk_p.rate = pclk_psys;
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_set_clksrc(&clksrcs[ptr], true);
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_sclk_hdmi27m,
+ &clk_sclk_hdmiphy,
+ &clk_sclk_usbphy0,
+ &clk_sclk_usbphy1,
+ &clk_pcmcdclk0,
+ &clk_pcmcdclk1,
+ &clk_pcmcdclk2,
+};
+
+void __init s5pv210_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-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
new file mode 100644
index 00000000..61e6c24b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -0,0 +1,197 @@
+/* linux/arch/arm/mach-s5pv210/cpu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/proc-fns.h>
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/fb-core.h>
+#include <plat/s5pv210.h>
+#include <plat/adc-core.h>
+#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>
+
+/* Initial IO mappings */
+
+static struct map_desc s5pv210_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_SYSTIMER,
+ .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_GPIO,
+ .pfn = __phys_to_pfn(S5PV210_PA_GPIO),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC0,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC0),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC1,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC1),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC2,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC2),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)VA_VIC3,
+ .pfn = __phys_to_pfn(S5PV210_PA_VIC3),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_UART,
+ .pfn = __phys_to_pfn(S3C_PA_UART),
+ .length = SZ_512K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC0,
+ .pfn = __phys_to_pfn(S5PV210_PA_DMC0),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_DMC1,
+ .pfn = __phys_to_pfn(S5PV210_PA_DMC1),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_USB_HSPHY,
+ .pfn =__phys_to_pfn(S5PV210_PA_HSPHY),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }
+};
+
+static void s5pv210_idle(void)
+{
+ if (!need_resched())
+ cpu_do_idle();
+
+ local_irq_enable();
+}
+
+static void s5pv210_sw_reset(void)
+{
+ __raw_writel(0x1, S5P_SWRESET);
+}
+
+/* s5pv210_map_io
+ *
+ * register the standard cpu IO areas
+*/
+
+void __init s5pv210_map_io(void)
+{
+ iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
+
+ /* initialise device information early */
+ s5pv210_default_sdhci0();
+ s5pv210_default_sdhci1();
+ s5pv210_default_sdhci2();
+ s5pv210_default_sdhci3();
+
+ s3c_adc_setname("s3c64xx-adc");
+
+ s3c_cfcon_setname("s5pv210-pata");
+
+ s3c_fimc_setname(0, "s5pv210-fimc");
+ s3c_fimc_setname(1, "s5pv210-fimc");
+ s3c_fimc_setname(2, "s5pv210-fimc");
+
+ /* the i2c devices are directly compatible with s3c2440 */
+ s3c_i2c0_setname("s3c2440-i2c");
+ s3c_i2c1_setname("s3c2440-i2c");
+ s3c_i2c2_setname("s3c2440-i2c");
+
+ s3c_fb_setname("s5pv210-fb");
+
+ /* Use s5pv210-keypad instead of samsung-keypad */
+ samsung_keypad_setname("s5pv210-keypad");
+}
+
+void __init s5pv210_init_clocks(int xtal)
+{
+ printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
+
+ s3c24xx_register_baseclocks(xtal);
+ s5p_register_clocks(xtal);
+ s5pv210_register_clocks();
+ s5pv210_setup_clocks();
+}
+
+void __init s5pv210_init_irq(void)
+{
+ u32 vic[4]; /* S5PV210 supports 4 VIC */
+
+ /* All the VICs are fully populated. */
+ vic[0] = ~0;
+ vic[1] = ~0;
+ vic[2] = ~0;
+ vic[3] = ~0;
+
+ s5p_init_irq(vic, ARRAY_SIZE(vic));
+}
+
+struct sysdev_class s5pv210_sysclass = {
+ .name = "s5pv210-core",
+};
+
+static struct sys_device s5pv210_sysdev = {
+ .cls = &s5pv210_sysclass,
+};
+
+static int __init s5pv210_core_init(void)
+{
+ return sysdev_class_register(&s5pv210_sysclass);
+}
+
+core_initcall(s5pv210_core_init);
+
+int __init s5pv210_init(void)
+{
+ printk(KERN_INFO "S5PV210: Initializing architecture\n");
+
+ /* set idle function */
+ pm_idle = s5pv210_idle;
+
+ /* set sw_reset function */
+ s5p_reset_hook = s5pv210_sw_reset;
+
+ return sysdev_register(&s5pv210_sysdev);
+}
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
new file mode 100644
index 00000000..153af8b3
--- /dev/null
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -0,0 +1,485 @@
+/* linux/arch/arm/mach-s5pv210/cpufreq.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * CPU frequency scaling for S5PC110/S5PV210
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cpufreq.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+static struct clk *cpu_clk;
+static struct clk *dmc0_clk;
+static struct clk *dmc1_clk;
+static struct cpufreq_freqs freqs;
+
+/* APLL M,P,S values for 1G/800Mhz */
+#define APLL_VAL_1000 ((1 << 31) | (125 << 16) | (3 << 8) | 1)
+#define APLL_VAL_800 ((1 << 31) | (100 << 16) | (3 << 8) | 1)
+
+/*
+ * DRAM configurations to calculate refresh counter for changing
+ * frequency of memory.
+ */
+struct dram_conf {
+ unsigned long freq; /* HZ */
+ unsigned long refresh; /* DRAM refresh counter * 1000 */
+};
+
+/* DRAM configuration (DMC0 and DMC1) */
+static struct dram_conf s5pv210_dram_conf[2];
+
+enum perf_level {
+ L0, L1, L2, L3, L4,
+};
+
+enum s5pv210_mem_type {
+ LPDDR = 0x1,
+ LPDDR2 = 0x2,
+ DDR2 = 0x4,
+};
+
+enum s5pv210_dmc_port {
+ DMC0 = 0,
+ DMC1,
+};
+
+static struct cpufreq_frequency_table s5pv210_freq_table[] = {
+ {L0, 1000*1000},
+ {L1, 800*1000},
+ {L2, 400*1000},
+ {L3, 200*1000},
+ {L4, 100*1000},
+ {0, CPUFREQ_TABLE_END},
+};
+
+static u32 clkdiv_val[5][11] = {
+ /*
+ * Clock divider value for following
+ * { APLL, A2M, HCLK_MSYS, PCLK_MSYS,
+ * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS,
+ * ONEDRAM, MFC, G3D }
+ */
+
+ /* L0 : [1000/200/100][166/83][133/66][200/200] */
+ {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L1 : [800/200/100][166/83][133/66][200/200] */
+ {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L2 : [400/200/100][166/83][133/66][200/200] */
+ {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L3 : [200/200/100][166/83][133/66][200/200] */
+ {3, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
+
+ /* L4 : [100/100/100][83/83][66/66][100/100] */
+ {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
+};
+
+/*
+ * This function set DRAM refresh counter
+ * accoriding to operating frequency of DRAM
+ * ch: DMC port number 0 or 1
+ * freq: Operating frequency of DRAM(KHz)
+ */
+static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
+{
+ unsigned long tmp, tmp1;
+ void __iomem *reg = NULL;
+
+ if (ch == DMC0) {
+ reg = (S5P_VA_DMC0 + 0x30);
+ } else if (ch == DMC1) {
+ reg = (S5P_VA_DMC1 + 0x30);
+ } else {
+ printk(KERN_ERR "Cannot find DMC port\n");
+ return;
+ }
+
+ /* Find current DRAM frequency */
+ tmp = s5pv210_dram_conf[ch].freq;
+
+ do_div(tmp, freq);
+
+ tmp1 = s5pv210_dram_conf[ch].refresh;
+
+ do_div(tmp1, tmp);
+
+ __raw_writel(tmp1, reg);
+}
+
+int s5pv210_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, s5pv210_freq_table);
+}
+
+unsigned int s5pv210_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int s5pv210_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned long reg;
+ unsigned int index, priv_index;
+ unsigned int pll_changing = 0;
+ unsigned int bus_speed_changing = 0;
+
+ freqs.old = s5pv210_getspeed(0);
+
+ if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+ target_freq, relation, &index))
+ return -EINVAL;
+
+ freqs.new = s5pv210_freq_table[index].frequency;
+ freqs.cpu = 0;
+
+ if (freqs.new == freqs.old)
+ return 0;
+
+ /* Finding current running level index */
+ if (cpufreq_frequency_table_target(policy, s5pv210_freq_table,
+ freqs.old, relation, &priv_index))
+ return -EINVAL;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ if (freqs.new > freqs.old) {
+ /* Voltage up: will be implemented */
+ }
+
+ /* Check if there need to change PLL */
+ if ((index == L0) || (priv_index == L0))
+ pll_changing = 1;
+
+ /* Check if there need to change System bus clock */
+ if ((index == L4) || (priv_index == L4))
+ bus_speed_changing = 1;
+
+ if (bus_speed_changing) {
+ /*
+ * Reconfigure DRAM refresh counter value for minimum
+ * temporary clock while changing divider.
+ * expected clock is 83Mhz : 7.8usec/(1/83Mhz) = 0x287
+ */
+ if (pll_changing)
+ s5pv210_set_refresh(DMC1, 83000);
+ else
+ s5pv210_set_refresh(DMC1, 100000);
+
+ s5pv210_set_refresh(DMC0, 83000);
+ }
+
+ /*
+ * APLL should be changed in this level
+ * APLL -> MPLL(for stable transition) -> APLL
+ * Some clock source's clock API are not prepared.
+ * Do not use clock API in below code.
+ */
+ if (pll_changing) {
+ /*
+ * 1. Temporary Change divider for MFC and G3D
+ * SCLKA2M(200/1=200)->(200/4=50)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_DIV2);
+ reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+ reg |= (3 << S5P_CLKDIV2_G3D_SHIFT) |
+ (3 << S5P_CLKDIV2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV2);
+
+ /* For MFC, G3D dividing */
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & ((1 << 16) | (1 << 17)));
+
+ /*
+ * 2. Change SCLKA2M(200Mhz)to SCLKMPLL in MFC_MUX, G3D MUX
+ * (200/4=50)->(667/4=166)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_SRC2);
+ reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+ reg |= (1 << S5P_CLKSRC2_G3D_SHIFT) |
+ (1 << S5P_CLKSRC2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC2);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT1);
+ } while (reg & ((1 << 7) | (1 << 3)));
+
+ /*
+ * 3. DMC1 refresh count for 133Mhz if (index == L4) is
+ * true refresh counter is already programed in upper
+ * code. 0x287@83Mhz
+ */
+ if (!bus_speed_changing)
+ s5pv210_set_refresh(DMC1, 133000);
+
+ /* 4. SCLKAPLL -> SCLKMPLL */
+ reg = __raw_readl(S5P_CLK_SRC0);
+ reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+ reg |= (0x1 << S5P_CLKSRC0_MUX200_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC0);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT0);
+ } while (reg & (0x1 << 18));
+
+ }
+
+ /* Change divider */
+ reg = __raw_readl(S5P_CLK_DIV0);
+
+ reg &= ~(S5P_CLKDIV0_APLL_MASK | S5P_CLKDIV0_A2M_MASK |
+ S5P_CLKDIV0_HCLK200_MASK | S5P_CLKDIV0_PCLK100_MASK |
+ S5P_CLKDIV0_HCLK166_MASK | S5P_CLKDIV0_PCLK83_MASK |
+ S5P_CLKDIV0_HCLK133_MASK | S5P_CLKDIV0_PCLK66_MASK);
+
+ reg |= ((clkdiv_val[index][0] << S5P_CLKDIV0_APLL_SHIFT) |
+ (clkdiv_val[index][1] << S5P_CLKDIV0_A2M_SHIFT) |
+ (clkdiv_val[index][2] << S5P_CLKDIV0_HCLK200_SHIFT) |
+ (clkdiv_val[index][3] << S5P_CLKDIV0_PCLK100_SHIFT) |
+ (clkdiv_val[index][4] << S5P_CLKDIV0_HCLK166_SHIFT) |
+ (clkdiv_val[index][5] << S5P_CLKDIV0_PCLK83_SHIFT) |
+ (clkdiv_val[index][6] << S5P_CLKDIV0_HCLK133_SHIFT) |
+ (clkdiv_val[index][7] << S5P_CLKDIV0_PCLK66_SHIFT));
+
+ __raw_writel(reg, S5P_CLK_DIV0);
+
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & 0xff);
+
+ /* ARM MCS value changed */
+ reg = __raw_readl(S5P_ARM_MCS_CON);
+ reg &= ~0x3;
+ if (index >= L3)
+ reg |= 0x3;
+ else
+ reg |= 0x1;
+
+ __raw_writel(reg, S5P_ARM_MCS_CON);
+
+ if (pll_changing) {
+ /* 5. Set Lock time = 30us*24Mhz = 0x2cf */
+ __raw_writel(0x2cf, S5P_APLL_LOCK);
+
+ /*
+ * 6. Turn on APLL
+ * 6-1. Set PMS values
+ * 6-2. Wait untile the PLL is locked
+ */
+ if (index == L0)
+ __raw_writel(APLL_VAL_1000, S5P_APLL_CON);
+ else
+ __raw_writel(APLL_VAL_800, S5P_APLL_CON);
+
+ do {
+ reg = __raw_readl(S5P_APLL_CON);
+ } while (!(reg & (0x1 << 29)));
+
+ /*
+ * 7. Change souce clock from SCLKMPLL(667Mhz)
+ * to SCLKA2M(200Mhz) in MFC_MUX and G3D MUX
+ * (667/4=166)->(200/4=50)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_SRC2);
+ reg &= ~(S5P_CLKSRC2_G3D_MASK | S5P_CLKSRC2_MFC_MASK);
+ reg |= (0 << S5P_CLKSRC2_G3D_SHIFT) |
+ (0 << S5P_CLKSRC2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC2);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT1);
+ } while (reg & ((1 << 7) | (1 << 3)));
+
+ /*
+ * 8. Change divider for MFC and G3D
+ * (200/4=50)->(200/1=200)Mhz
+ */
+ reg = __raw_readl(S5P_CLK_DIV2);
+ reg &= ~(S5P_CLKDIV2_G3D_MASK | S5P_CLKDIV2_MFC_MASK);
+ reg |= (clkdiv_val[index][10] << S5P_CLKDIV2_G3D_SHIFT) |
+ (clkdiv_val[index][9] << S5P_CLKDIV2_MFC_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV2);
+
+ /* For MFC, G3D dividing */
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT0);
+ } while (reg & ((1 << 16) | (1 << 17)));
+
+ /* 9. Change MPLL to APLL in MSYS_MUX */
+ reg = __raw_readl(S5P_CLK_SRC0);
+ reg &= ~(S5P_CLKSRC0_MUX200_MASK);
+ reg |= (0x0 << S5P_CLKSRC0_MUX200_SHIFT);
+ __raw_writel(reg, S5P_CLK_SRC0);
+
+ do {
+ reg = __raw_readl(S5P_CLKMUX_STAT0);
+ } while (reg & (0x1 << 18));
+
+ /*
+ * 10. DMC1 refresh counter
+ * L4 : DMC1 = 100Mhz 7.8us/(1/100) = 0x30c
+ * Others : DMC1 = 200Mhz 7.8us/(1/200) = 0x618
+ */
+ if (!bus_speed_changing)
+ s5pv210_set_refresh(DMC1, 200000);
+ }
+
+ /*
+ * L4 level need to change memory bus speed, hence onedram clock divier
+ * and memory refresh parameter should be changed
+ */
+ if (bus_speed_changing) {
+ reg = __raw_readl(S5P_CLK_DIV6);
+ reg &= ~S5P_CLKDIV6_ONEDRAM_MASK;
+ reg |= (clkdiv_val[index][8] << S5P_CLKDIV6_ONEDRAM_SHIFT);
+ __raw_writel(reg, S5P_CLK_DIV6);
+
+ do {
+ reg = __raw_readl(S5P_CLKDIV_STAT1);
+ } while (reg & (1 << 15));
+
+ /* Reconfigure DRAM refresh counter value */
+ if (index != L4) {
+ /*
+ * DMC0 : 166Mhz
+ * DMC1 : 200Mhz
+ */
+ s5pv210_set_refresh(DMC0, 166000);
+ s5pv210_set_refresh(DMC1, 200000);
+ } else {
+ /*
+ * DMC0 : 83Mhz
+ * DMC1 : 100Mhz
+ */
+ s5pv210_set_refresh(DMC0, 83000);
+ s5pv210_set_refresh(DMC1, 100000);
+ }
+ }
+
+ if (freqs.new < freqs.old) {
+ /* Voltage down: will be implemented */
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ printk(KERN_DEBUG "Perf changed[L%d]\n", index);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+
+static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ return 0;
+}
+#endif
+
+static int check_mem_type(void __iomem *dmc_reg)
+{
+ unsigned long val;
+
+ val = __raw_readl(dmc_reg + 0x4);
+ val = (val & (0xf << 8));
+
+ return val >> 8;
+}
+
+static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
+{
+ unsigned long mem_type;
+
+ cpu_clk = clk_get(NULL, "armclk");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ dmc0_clk = clk_get(NULL, "sclk_dmc0");
+ if (IS_ERR(dmc0_clk)) {
+ clk_put(cpu_clk);
+ return PTR_ERR(dmc0_clk);
+ }
+
+ dmc1_clk = clk_get(NULL, "hclk_msys");
+ if (IS_ERR(dmc1_clk)) {
+ clk_put(dmc0_clk);
+ clk_put(cpu_clk);
+ return PTR_ERR(dmc1_clk);
+ }
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ /*
+ * check_mem_type : This driver only support LPDDR & LPDDR2.
+ * other memory type is not supported.
+ */
+ mem_type = check_mem_type(S5P_VA_DMC0);
+
+ if ((mem_type != LPDDR) && (mem_type != LPDDR2)) {
+ printk(KERN_ERR "CPUFreq doesn't support this memory type\n");
+ return -EINVAL;
+ }
+
+ /* Find current refresh counter and frequency each DMC */
+ s5pv210_dram_conf[0].refresh = (__raw_readl(S5P_VA_DMC0 + 0x30) * 1000);
+ s5pv210_dram_conf[0].freq = clk_get_rate(dmc0_clk);
+
+ s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000);
+ s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk);
+
+ policy->cur = policy->min = policy->max = s5pv210_getspeed(0);
+
+ cpufreq_frequency_table_get_attr(s5pv210_freq_table, policy->cpu);
+
+ policy->cpuinfo.transition_latency = 40000;
+
+ return cpufreq_frequency_table_cpuinfo(policy, s5pv210_freq_table);
+}
+
+static struct cpufreq_driver s5pv210_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = s5pv210_verify_speed,
+ .target = s5pv210_target,
+ .get = s5pv210_getspeed,
+ .init = s5pv210_cpu_init,
+ .name = "s5pv210",
+#ifdef CONFIG_PM
+ .suspend = s5pv210_cpufreq_suspend,
+ .resume = s5pv210_cpufreq_resume,
+#endif
+};
+
+static int __init s5pv210_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&s5pv210_driver);
+}
+
+late_initcall(s5pv210_cpufreq_init);
diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c
new file mode 100644
index 00000000..8d58f192
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-audio.c
@@ -0,0 +1,363 @@
+/* linux/arch/arm/mach-s5pv210/dev-audio.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co. Ltd
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/audio.h>
+
+#include <mach/map.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+static const char *rclksrc[] = {
+ [0] = "busclk",
+ [1] = "i2sclk",
+};
+
+static int s5pv210_cfg_i2s(struct platform_device *pdev)
+{
+ /* configure GPIO for i2s port */
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2));
+ break;
+ case 1:
+ s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5PV210_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 = s5pv210_cfg_i2s,
+ .type = {
+ .i2s = {
+ .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
+ | QUIRK_NEED_RSTCLR,
+ .src_clk = rclksrc,
+ },
+ },
+};
+
+static struct resource s5pv210_iis0_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_IIS0,
+ .end = S5PV210_PA_IIS0 + 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 s5pv210_device_iis0 = {
+ .name = "samsung-i2s",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_iis0_resource),
+ .resource = s5pv210_iis0_resource,
+ .dev = {
+ .platform_data = &i2sv5_pdata,
+ },
+};
+
+static const char *rclksrc_v3[] = {
+ [0] = "iis",
+ [1] = "audio-bus",
+};
+
+static struct s3c_audio_pdata i2sv3_pdata = {
+ .cfg_gpio = s5pv210_cfg_i2s,
+ .type = {
+ .i2s = {
+ .src_clk = rclksrc_v3,
+ },
+ },
+};
+
+static struct resource s5pv210_iis1_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_IIS1,
+ .end = S5PV210_PA_IIS1 + 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 s5pv210_device_iis1 = {
+ .name = "samsung-i2s",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv210_iis1_resource),
+ .resource = s5pv210_iis1_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+static struct resource s5pv210_iis2_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_IIS2,
+ .end = S5PV210_PA_IIS2 + 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 s5pv210_device_iis2 = {
+ .name = "samsung-i2s",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pv210_iis2_resource),
+ .resource = s5pv210_iis2_resource,
+ .dev = {
+ .platform_data = &i2sv3_pdata,
+ },
+};
+
+/* PCM Controller platform_devices */
+
+static int s5pv210_pcm_cfg_gpio(struct platform_device *pdev)
+{
+ switch (pdev->id) {
+ case 0:
+ s3c_gpio_cfgpin_range(S5PV210_GPI(0), 5, S3C_GPIO_SFN(3));
+ break;
+ case 1:
+ s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(3));
+ break;
+ case 2:
+ s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(2));
+ break;
+ default:
+ printk(KERN_DEBUG "Invalid PCM Controller number!");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct s3c_audio_pdata s3c_pcm_pdata = {
+ .cfg_gpio = s5pv210_pcm_cfg_gpio,
+};
+
+static struct resource s5pv210_pcm0_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_PCM0,
+ .end = S5PV210_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 s5pv210_device_pcm0 = {
+ .name = "samsung-pcm",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_pcm0_resource),
+ .resource = s5pv210_pcm0_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource s5pv210_pcm1_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_PCM1,
+ .end = S5PV210_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 s5pv210_device_pcm1 = {
+ .name = "samsung-pcm",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv210_pcm1_resource),
+ .resource = s5pv210_pcm1_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+static struct resource s5pv210_pcm2_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_PCM2,
+ .end = S5PV210_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 s5pv210_device_pcm2 = {
+ .name = "samsung-pcm",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5pv210_pcm2_resource),
+ .resource = s5pv210_pcm2_resource,
+ .dev = {
+ .platform_data = &s3c_pcm_pdata,
+ },
+};
+
+/* AC97 Controller platform devices */
+
+static int s5pv210_ac97_cfg_gpio(struct platform_device *pdev)
+{
+ return s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(4));
+}
+
+static struct resource s5pv210_ac97_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_AC97,
+ .end = S5PV210_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 = s5pv210_ac97_cfg_gpio,
+};
+
+static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pv210_ac97_resource),
+ .resource = s5pv210_ac97_resource,
+ .dev = {
+ .platform_data = &s3c_ac97_pdata,
+ .dma_mask = &s5pv210_ac97_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+/* S/PDIF Controller platform_device */
+
+static int s5pv210_spdif_cfg_gpio(struct platform_device *pdev)
+{
+ s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 2, S3C_GPIO_SFN(3));
+
+ return 0;
+}
+
+static struct resource s5pv210_spdif_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_SPDIF,
+ .end = S5PV210_PA_SPDIF + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMACH_SPDIF,
+ .end = DMACH_SPDIF,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct s3c_audio_pdata samsung_spdif_pdata = {
+ .cfg_gpio = s5pv210_spdif_cfg_gpio,
+};
+
+static u64 s5pv210_spdif_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_spdif = {
+ .name = "samsung-spdif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5pv210_spdif_resource),
+ .resource = s5pv210_spdif_resource,
+ .dev = {
+ .platform_data = &samsung_spdif_pdata,
+ .dma_mask = &s5pv210_spdif_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c
new file mode 100644
index 00000000..eaf9a7bf
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-spi.c
@@ -0,0 +1,175 @@
+/* linux/arch/arm/mach-s5pv210/dev-spi.c
+ *
+ * Copyright (C) 2010 Samsung Electronics Co. Ltd.
+ * Jaswinder Singh <jassi.brar@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+
+#include <mach/dma.h>
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <mach/spi-clocks.h>
+
+#include <plat/s3c64xx-spi.h>
+#include <plat/gpio-cfg.h>
+
+static char *spi_src_clks[] = {
+ [S5PV210_SPI_SRCCLK_PCLK] = "pclk",
+ [S5PV210_SPI_SRCCLK_SCLK] = "sclk_spi",
+};
+
+/* SPI Controller platform_devices */
+
+/* Since we emulate multi-cs capability, we do not touch the CS.
+ * The emulated CS is toggled by board specific mechanism, as it can
+ * be either some immediate GPIO or some signal out of some other
+ * chip in between ... or some yet another way.
+ * We simply do not assume anything about CS.
+ */
+static int s5pv210_spi_cfg_gpio(struct platform_device *pdev)
+{
+ unsigned int base;
+
+ switch (pdev->id) {
+ case 0:
+ base = S5PV210_GPB(0);
+ break;
+
+ case 1:
+ base = S5PV210_GPB(4);
+ break;
+
+ default:
+ dev_err(&pdev->dev, "Invalid SPI Controller number!");
+ return -EINVAL;
+ }
+
+ s3c_gpio_cfgall_range(base, 3,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
+ return 0;
+}
+
+static struct resource s5pv210_spi0_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_SPI0,
+ .end = S5PV210_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 s5pv210_spi0_pdata = {
+ .cfg_gpio = s5pv210_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x1ff,
+ .rx_lvl_offset = 15,
+ .high_speed = 1,
+ .tx_st_done = 25,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s5pv210_device_spi0 = {
+ .name = "s3c64xx-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_spi0_resource),
+ .resource = s5pv210_spi0_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_spi0_pdata,
+ },
+};
+
+static struct resource s5pv210_spi1_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_SPI1,
+ .end = S5PV210_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 s5pv210_spi1_pdata = {
+ .cfg_gpio = s5pv210_spi_cfg_gpio,
+ .fifo_lvl_mask = 0x7f,
+ .rx_lvl_offset = 15,
+ .high_speed = 1,
+ .tx_st_done = 25,
+};
+
+struct platform_device s5pv210_device_spi1 = {
+ .name = "s3c64xx-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv210_spi1_resource),
+ .resource = s5pv210_spi1_resource,
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_spi1_pdata,
+ },
+};
+
+void __init s5pv210_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 > S5PV210_SPI_SRCCLK_SCLK) {
+ printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
+ return;
+ }
+
+ switch (cntrlr) {
+ case 0:
+ pd = &s5pv210_spi0_pdata;
+ break;
+ case 1:
+ pd = &s5pv210_spi1_pdata;
+ break;
+ default:
+ printk(KERN_ERR "%s: Invalid SPI controller(%d)\n",
+ __func__, cntrlr);
+ return;
+ }
+
+ pd->num_cs = num_cs;
+ pd->src_clk_nr = src_clk_nr;
+ pd->src_clk_name = spi_src_clks[src_clk_nr];
+}
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
new file mode 100644
index 00000000..497d3439
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -0,0 +1,168 @@
+/*
+ * 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 s5pv210_pdma0_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_PDMA0,
+ .end = S5PV210_PA_PDMA0 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA0,
+ .end = IRQ_PDMA0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma0_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_MAX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S0S_TX,
+ [12] = DMACH_I2S1_RX,
+ [13] = DMACH_I2S1_TX,
+ [14] = DMACH_MAX,
+ [15] = DMACH_MAX,
+ [16] = DMACH_SPI0_RX,
+ [17] = DMACH_SPI0_TX,
+ [18] = DMACH_SPI1_RX,
+ [19] = DMACH_SPI1_TX,
+ [20] = DMACH_MAX,
+ [21] = DMACH_MAX,
+ [22] = DMACH_AC97_MICIN,
+ [23] = DMACH_AC97_PCMIN,
+ [24] = DMACH_AC97_PCMOUT,
+ [25] = DMACH_MAX,
+ [26] = DMACH_PWM,
+ [27] = DMACH_SPDIF,
+ [28] = DMACH_MAX,
+ [29] = DMACH_MAX,
+ [30] = DMACH_MAX,
+ [31] = DMACH_MAX,
+ },
+};
+
+static struct platform_device s5pv210_device_pdma0 = {
+ .name = "s3c-pl330",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5pv210_pdma0_resource),
+ .resource = s5pv210_pdma0_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_pdma0_pdata,
+ },
+};
+
+static struct resource s5pv210_pdma1_resource[] = {
+ [0] = {
+ .start = S5PV210_PA_PDMA1,
+ .end = S5PV210_PA_PDMA1 + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PDMA1,
+ .end = IRQ_PDMA1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct s3c_pl330_platdata s5pv210_pdma1_pdata = {
+ .peri = {
+ [0] = DMACH_UART0_RX,
+ [1] = DMACH_UART0_TX,
+ [2] = DMACH_UART1_RX,
+ [3] = DMACH_UART1_TX,
+ [4] = DMACH_UART2_RX,
+ [5] = DMACH_UART2_TX,
+ [6] = DMACH_UART3_RX,
+ [7] = DMACH_UART3_TX,
+ [8] = DMACH_MAX,
+ [9] = DMACH_I2S0_RX,
+ [10] = DMACH_I2S0_TX,
+ [11] = DMACH_I2S0S_TX,
+ [12] = DMACH_I2S1_RX,
+ [13] = DMACH_I2S1_TX,
+ [14] = DMACH_I2S2_RX,
+ [15] = DMACH_I2S2_TX,
+ [16] = DMACH_SPI0_RX,
+ [17] = DMACH_SPI0_TX,
+ [18] = DMACH_SPI1_RX,
+ [19] = DMACH_SPI1_TX,
+ [20] = DMACH_MAX,
+ [21] = DMACH_MAX,
+ [22] = DMACH_PCM0_RX,
+ [23] = DMACH_PCM0_TX,
+ [24] = DMACH_PCM1_RX,
+ [25] = DMACH_PCM1_TX,
+ [26] = DMACH_MSM_REQ0,
+ [27] = DMACH_MSM_REQ1,
+ [28] = DMACH_MSM_REQ2,
+ [29] = DMACH_MSM_REQ3,
+ [30] = DMACH_PCM2_RX,
+ [31] = DMACH_PCM2_TX,
+ },
+};
+
+static struct platform_device s5pv210_device_pdma1 = {
+ .name = "s3c-pl330",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5pv210_pdma1_resource),
+ .resource = s5pv210_pdma1_resource,
+ .dev = {
+ .dma_mask = &dma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &s5pv210_pdma1_pdata,
+ },
+};
+
+static struct platform_device *s5pv210_dmacs[] __initdata = {
+ &s5pv210_device_pdma0,
+ &s5pv210_device_pdma1,
+};
+
+static int __init s5pv210_dma_init(void)
+{
+ platform_add_devices(s5pv210_dmacs, ARRAY_SIZE(s5pv210_dmacs));
+
+ return 0;
+}
+arch_initcall(s5pv210_dma_init);
diff --git a/arch/arm/mach-s5pv210/include/mach/debug-macro.S b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
new file mode 100644
index 00000000..169fe654
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/debug-macro.S
@@ -0,0 +1,41 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/debug-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/debug-macro.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.
+*/
+
+/* pull in the relevant register and map files. */
+
+#include <mach/map.h>
+#include <plat/regs-serial.h>
+
+ /* note, for the boot process to work we have to keep the UART
+ * virtual address aligned to an 1MiB boundary for the L1
+ * mapping the head code makes. We keep the UART virtual address
+ * aligned and add in the offset when we load the value here.
+ */
+
+ .macro addruart, rp, rv
+ ldr \rp, = S3C_PA_UART
+ ldr \rv, = S3C_VA_UART
+#if CONFIG_DEBUG_S3C_UART != 0
+ add \rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
+ add \rv, \rv, #(0x400 * CONFIG_DEBUG_S3C_UART)
+#endif
+ .endm
+
+#define fifo_full fifo_full_s5pv210
+#define fifo_level fifo_level_s5pv210
+
+/* include the reset of the code which will do the work, we're only
+ * compiling for a single cpu processor type so the default of s3c2440
+ * will be fine with us.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s5pv210/include/mach/dma.h b/arch/arm/mach-s5pv210/include/mach/dma.h
new file mode 100644
index 00000000..81209eb1
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/dma.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef __MACH_DMA_H
+#define __MACH_DMA_H
+
+/* This platform uses the common S3C DMA API driver for PL330 */
+#include <plat/s3c-dma-pl330.h>
+
+#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/entry-macro.S b/arch/arm/mach-s5pv210/include/mach/entry-macro.S
new file mode 100644
index 00000000..3aa41ac5
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/entry-macro.S
@@ -0,0 +1,54 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/entry-macro.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Low-level IRQ helper macros for the Samsung 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 <asm/hardware/vic.h>
+#include <mach/map.h>
+#include <plat/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =VA_VIC0
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ @ check the vic0
+ mov \irqnr, # S5P_IRQ_OFFSET + 31
+ ldr \irqstat, [ \base, # VIC_IRQ_STATUS ]
+ teq \irqstat, #0
+
+ @ otherwise try vic1
+ addeq \tmp, \base, #(VA_VIC1 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic2
+ addeq \tmp, \base, #(VA_VIC2 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ @ otherwise try vic3
+ addeq \tmp, \base, #(VA_VIC3 - VA_VIC0)
+ addeq \irqnr, \irqnr, #32
+ ldreq \irqstat, [ \tmp, # VIC_IRQ_STATUS ]
+ teqeq \irqstat, #0
+
+ clzne \irqstat, \irqstat
+ subne \irqnr, \irqnr, \irqstat
+ .endm
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h
new file mode 100644
index 00000000..a5a1e331
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/gpio.h
@@ -0,0 +1,147 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - 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 MP03 are the configurable gpio banks */
+
+/* GPIO bank sizes */
+#define S5PV210_GPIO_A0_NR (8)
+#define S5PV210_GPIO_A1_NR (4)
+#define S5PV210_GPIO_B_NR (8)
+#define S5PV210_GPIO_C0_NR (5)
+#define S5PV210_GPIO_C1_NR (5)
+#define S5PV210_GPIO_D0_NR (4)
+#define S5PV210_GPIO_D1_NR (6)
+#define S5PV210_GPIO_E0_NR (8)
+#define S5PV210_GPIO_E1_NR (5)
+#define S5PV210_GPIO_F0_NR (8)
+#define S5PV210_GPIO_F1_NR (8)
+#define S5PV210_GPIO_F2_NR (8)
+#define S5PV210_GPIO_F3_NR (6)
+#define S5PV210_GPIO_G0_NR (7)
+#define S5PV210_GPIO_G1_NR (7)
+#define S5PV210_GPIO_G2_NR (7)
+#define S5PV210_GPIO_G3_NR (7)
+#define S5PV210_GPIO_H0_NR (8)
+#define S5PV210_GPIO_H1_NR (8)
+#define S5PV210_GPIO_H2_NR (8)
+#define S5PV210_GPIO_H3_NR (8)
+#define S5PV210_GPIO_I_NR (7)
+#define S5PV210_GPIO_J0_NR (8)
+#define S5PV210_GPIO_J1_NR (6)
+#define S5PV210_GPIO_J2_NR (8)
+#define S5PV210_GPIO_J3_NR (8)
+#define S5PV210_GPIO_J4_NR (5)
+
+#define S5PV210_GPIO_MP01_NR (8)
+#define S5PV210_GPIO_MP02_NR (4)
+#define S5PV210_GPIO_MP03_NR (8)
+#define S5PV210_GPIO_MP04_NR (8)
+#define S5PV210_GPIO_MP05_NR (8)
+
+/* GPIO bank numbers */
+
+/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
+ * space for debugging purposes so that any accidental
+ * change from one gpio bank to another can be caught.
+*/
+
+#define S5PV210_GPIO_NEXT(__gpio) \
+ ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)
+
+enum s5p_gpio_number {
+ S5PV210_GPIO_A0_START = 0,
+ S5PV210_GPIO_A1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A0),
+ S5PV210_GPIO_B_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_A1),
+ S5PV210_GPIO_C0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_B),
+ S5PV210_GPIO_C1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_C0),
+ S5PV210_GPIO_D0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_C1),
+ S5PV210_GPIO_D1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_D0),
+ S5PV210_GPIO_E0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_D1),
+ S5PV210_GPIO_E1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_E0),
+ S5PV210_GPIO_F0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_E1),
+ S5PV210_GPIO_F1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F0),
+ S5PV210_GPIO_F2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F1),
+ S5PV210_GPIO_F3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F2),
+ S5PV210_GPIO_G0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_F3),
+ S5PV210_GPIO_G1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G0),
+ S5PV210_GPIO_G2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G1),
+ S5PV210_GPIO_G3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G2),
+ S5PV210_GPIO_H0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_G3),
+ S5PV210_GPIO_H1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H0),
+ S5PV210_GPIO_H2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H1),
+ S5PV210_GPIO_H3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H2),
+ S5PV210_GPIO_I_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_H3),
+ S5PV210_GPIO_J0_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_I),
+ S5PV210_GPIO_J1_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J0),
+ S5PV210_GPIO_J2_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J1),
+ S5PV210_GPIO_J3_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J2),
+ S5PV210_GPIO_J4_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J3),
+ S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4),
+ S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01),
+ S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
+ S5PV210_GPIO_MP04_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP03),
+ S5PV210_GPIO_MP05_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP04),
+};
+
+/* S5PV210 GPIO number definitions */
+#define S5PV210_GPA0(_nr) (S5PV210_GPIO_A0_START + (_nr))
+#define S5PV210_GPA1(_nr) (S5PV210_GPIO_A1_START + (_nr))
+#define S5PV210_GPB(_nr) (S5PV210_GPIO_B_START + (_nr))
+#define S5PV210_GPC0(_nr) (S5PV210_GPIO_C0_START + (_nr))
+#define S5PV210_GPC1(_nr) (S5PV210_GPIO_C1_START + (_nr))
+#define S5PV210_GPD0(_nr) (S5PV210_GPIO_D0_START + (_nr))
+#define S5PV210_GPD1(_nr) (S5PV210_GPIO_D1_START + (_nr))
+#define S5PV210_GPE0(_nr) (S5PV210_GPIO_E0_START + (_nr))
+#define S5PV210_GPE1(_nr) (S5PV210_GPIO_E1_START + (_nr))
+#define S5PV210_GPF0(_nr) (S5PV210_GPIO_F0_START + (_nr))
+#define S5PV210_GPF1(_nr) (S5PV210_GPIO_F1_START + (_nr))
+#define S5PV210_GPF2(_nr) (S5PV210_GPIO_F2_START + (_nr))
+#define S5PV210_GPF3(_nr) (S5PV210_GPIO_F3_START + (_nr))
+#define S5PV210_GPG0(_nr) (S5PV210_GPIO_G0_START + (_nr))
+#define S5PV210_GPG1(_nr) (S5PV210_GPIO_G1_START + (_nr))
+#define S5PV210_GPG2(_nr) (S5PV210_GPIO_G2_START + (_nr))
+#define S5PV210_GPG3(_nr) (S5PV210_GPIO_G3_START + (_nr))
+#define S5PV210_GPH0(_nr) (S5PV210_GPIO_H0_START + (_nr))
+#define S5PV210_GPH1(_nr) (S5PV210_GPIO_H1_START + (_nr))
+#define S5PV210_GPH2(_nr) (S5PV210_GPIO_H2_START + (_nr))
+#define S5PV210_GPH3(_nr) (S5PV210_GPIO_H3_START + (_nr))
+#define S5PV210_GPI(_nr) (S5PV210_GPIO_I_START + (_nr))
+#define S5PV210_GPJ0(_nr) (S5PV210_GPIO_J0_START + (_nr))
+#define S5PV210_GPJ1(_nr) (S5PV210_GPIO_J1_START + (_nr))
+#define S5PV210_GPJ2(_nr) (S5PV210_GPIO_J2_START + (_nr))
+#define S5PV210_GPJ3(_nr) (S5PV210_GPIO_J3_START + (_nr))
+#define S5PV210_GPJ4(_nr) (S5PV210_GPIO_J4_START + (_nr))
+#define S5PV210_MP01(_nr) (S5PV210_GPIO_MP01_START + (_nr))
+#define S5PV210_MP02(_nr) (S5PV210_GPIO_MP02_START + (_nr))
+#define S5PV210_MP03(_nr) (S5PV210_GPIO_MP03_START + (_nr))
+#define S5PV210_MP04(_nr) (S5PV210_GPIO_MP04_START + (_nr))
+#define S5PV210_MP05(_nr) (S5PV210_GPIO_MP05_START + (_nr))
+
+/* the end of the S5PV210 specific gpios */
+#define S5PV210_GPIO_END (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + 1)
+#define S3C_GPIO_END S5PV210_GPIO_END
+
+/* define the number of gpios we need to the one after the MP05() range */
+#define ARCH_NR_GPIOS (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + \
+ CONFIG_SAMSUNG_GPIO_EXTRA + 1)
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/hardware.h b/arch/arm/mach-s5pv210/include/mach/hardware.h
new file mode 100644
index 00000000..fada7a39
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/hardware.h
@@ -0,0 +1,18 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/hardware.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Hardware support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H __FILE__
+
+/* currently nothing here, placeholder */
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/io.h b/arch/arm/mach-s5pv210/include/mach/io.h
new file mode 100644
index 00000000..5ab9d560
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/io.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/io.h
+ *
+ * Copyright 2008-2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/io.h
+ *
+ * Default IO routines 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H __FILE__
+
+/* No current ISA/PCI bus support. */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#define IO_SPACE_LIMIT (0xFFFFFFFF)
+
+#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
new file mode 100644
index 00000000..b9f9ec33
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -0,0 +1,137 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/irqs.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - 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>
+
+/* VIC0: System, DMA, Timer */
+
+#define IRQ_EINT16_31 S5P_IRQ_VIC0(16)
+#define IRQ_BATF S5P_IRQ_VIC0(17)
+#define IRQ_MDMA S5P_IRQ_VIC0(18)
+#define IRQ_PDMA0 S5P_IRQ_VIC0(19)
+#define IRQ_PDMA1 S5P_IRQ_VIC0(20)
+#define IRQ_TIMER0_VIC S5P_IRQ_VIC0(21)
+#define IRQ_TIMER1_VIC S5P_IRQ_VIC0(22)
+#define IRQ_TIMER2_VIC S5P_IRQ_VIC0(23)
+#define IRQ_TIMER3_VIC S5P_IRQ_VIC0(24)
+#define IRQ_TIMER4_VIC S5P_IRQ_VIC0(25)
+#define IRQ_SYSTIMER S5P_IRQ_VIC0(26)
+#define IRQ_WDT S5P_IRQ_VIC0(27)
+#define IRQ_RTC_ALARM S5P_IRQ_VIC0(28)
+#define IRQ_RTC_TIC S5P_IRQ_VIC0(29)
+#define IRQ_GPIOINT S5P_IRQ_VIC0(30)
+#define IRQ_FIMC3 S5P_IRQ_VIC0(31)
+
+/* VIC1: ARM, Power, Memory, Connectivity, Storage */
+
+#define IRQ_PMU S5P_IRQ_VIC1(0)
+#define IRQ_CORTEX1 S5P_IRQ_VIC1(1)
+#define IRQ_CORTEX2 S5P_IRQ_VIC1(2)
+#define IRQ_CORTEX3 S5P_IRQ_VIC1(3)
+#define IRQ_CORTEX4 S5P_IRQ_VIC1(4)
+#define IRQ_IEMAPC S5P_IRQ_VIC1(5)
+#define IRQ_IEMIEC S5P_IRQ_VIC1(6)
+#define IRQ_ONENAND S5P_IRQ_VIC1(7)
+#define IRQ_NFC S5P_IRQ_VIC1(8)
+#define IRQ_CFCON S5P_IRQ_VIC1(9)
+#define IRQ_UART0 S5P_IRQ_VIC1(10)
+#define IRQ_UART1 S5P_IRQ_VIC1(11)
+#define IRQ_UART2 S5P_IRQ_VIC1(12)
+#define IRQ_UART3 S5P_IRQ_VIC1(13)
+#define IRQ_IIC S5P_IRQ_VIC1(14)
+#define IRQ_SPI0 S5P_IRQ_VIC1(15)
+#define IRQ_SPI1 S5P_IRQ_VIC1(16)
+#define IRQ_SPI2 S5P_IRQ_VIC1(17)
+#define IRQ_IRDA S5P_IRQ_VIC1(18)
+#define IRQ_IIC2 S5P_IRQ_VIC1(19)
+#define IRQ_IIC3 S5P_IRQ_VIC1(20)
+#define IRQ_HSIRX S5P_IRQ_VIC1(21)
+#define IRQ_HSITX S5P_IRQ_VIC1(22)
+#define IRQ_UHOST S5P_IRQ_VIC1(23)
+#define IRQ_OTG S5P_IRQ_VIC1(24)
+#define IRQ_MSM S5P_IRQ_VIC1(25)
+#define IRQ_HSMMC0 S5P_IRQ_VIC1(26)
+#define IRQ_HSMMC1 S5P_IRQ_VIC1(27)
+#define IRQ_HSMMC2 S5P_IRQ_VIC1(28)
+#define IRQ_MIPI_CSIS S5P_IRQ_VIC1(29)
+#define IRQ_MIPIDSI S5P_IRQ_VIC1(30)
+#define IRQ_ONENAND_AUDI S5P_IRQ_VIC1(31)
+
+/* VIC2: Multimedia, Audio, Security */
+
+#define IRQ_LCD0 S5P_IRQ_VIC2(0)
+#define IRQ_LCD1 S5P_IRQ_VIC2(1)
+#define IRQ_LCD2 S5P_IRQ_VIC2(2)
+#define IRQ_LCD3 S5P_IRQ_VIC2(3)
+#define IRQ_ROTATOR S5P_IRQ_VIC2(4)
+#define IRQ_FIMC0 S5P_IRQ_VIC2(5)
+#define IRQ_FIMC1 S5P_IRQ_VIC2(6)
+#define IRQ_FIMC2 S5P_IRQ_VIC2(7)
+#define IRQ_JPEG S5P_IRQ_VIC2(8)
+#define IRQ_2D S5P_IRQ_VIC2(9)
+#define IRQ_3D S5P_IRQ_VIC2(10)
+#define IRQ_MIXER S5P_IRQ_VIC2(11)
+#define IRQ_HDMI S5P_IRQ_VIC2(12)
+#define IRQ_IIC1 S5P_IRQ_VIC2(13)
+#define IRQ_MFC S5P_IRQ_VIC2(14)
+#define IRQ_TVENC S5P_IRQ_VIC2(15)
+#define IRQ_I2S0 S5P_IRQ_VIC2(16)
+#define IRQ_I2S1 S5P_IRQ_VIC2(17)
+#define IRQ_I2S2 S5P_IRQ_VIC2(18)
+#define IRQ_AC97 S5P_IRQ_VIC2(19)
+#define IRQ_PCM0 S5P_IRQ_VIC2(20)
+#define IRQ_PCM1 S5P_IRQ_VIC2(21)
+#define IRQ_SPDIF S5P_IRQ_VIC2(22)
+#define IRQ_ADC S5P_IRQ_VIC2(23)
+#define IRQ_PENDN S5P_IRQ_VIC2(24)
+#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_PCM2 S5P_IRQ_VIC2(29)
+#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
+#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
+
+/* VIC3: Etc */
+
+#define IRQ_IPC S5P_IRQ_VIC3(0)
+#define IRQ_HOSTIF S5P_IRQ_VIC3(1)
+#define IRQ_HSMMC3 S5P_IRQ_VIC3(2)
+#define IRQ_CEC S5P_IRQ_VIC3(3)
+#define IRQ_TSI S5P_IRQ_VIC3(4)
+#define IRQ_MDNIE0 S5P_IRQ_VIC3(5)
+#define IRQ_MDNIE1 S5P_IRQ_VIC3(6)
+#define IRQ_MDNIE2 S5P_IRQ_VIC3(7)
+#define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
+#define IRQ_VIC_END S5P_IRQ_VIC3(31)
+
+#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
+#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
+
+/* GPIO interrupt */
+#define S5P_GPIOINT_BASE (IRQ_EINT(31) + 1)
+#define S5P_GPIOINT_GROUP_MAXNR 22
+
+/* Set the default NR_IRQS */
+#define NR_IRQS (IRQ_EINT(31) + S5P_GPIOINT_COUNT + 1)
+
+/* Compatibility */
+#define IRQ_LCD_FIFO IRQ_LCD0
+#define IRQ_LCD_VSYNC IRQ_LCD1
+#define IRQ_LCD_SYSTEM IRQ_LCD2
+#define IRQ_MIPI_CSIS0 IRQ_MIPI_CSIS
+
+#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
new file mode 100644
index 00000000..1dd58836
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -0,0 +1,135 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/map.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory map definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H __FILE__
+
+#include <plat/map-base.h>
+#include <plat/map-s5p.h>
+
+#define S5PV210_PA_SDRAM 0x20000000
+
+#define S5PV210_PA_SROM_BANK5 0xA8000000
+
+#define S5PC110_PA_ONENAND 0xB0000000
+#define S5PC110_PA_ONENAND_DMA 0xB0600000
+
+#define S5PV210_PA_CHIPID 0xE0000000
+
+#define S5PV210_PA_SYSCON 0xE0100000
+
+#define S5PV210_PA_GPIO 0xE0200000
+
+#define S5PV210_PA_SPDIF 0xE1100000
+
+#define S5PV210_PA_SPI0 0xE1300000
+#define S5PV210_PA_SPI1 0xE1400000
+
+#define S5PV210_PA_KEYPAD 0xE1600000
+
+#define S5PV210_PA_ADC 0xE1700000
+
+#define S5PV210_PA_IIC0 0xE1800000
+#define S5PV210_PA_IIC1 0xFAB00000
+#define S5PV210_PA_IIC2 0xE1A00000
+
+#define S5PV210_PA_AC97 0xE2200000
+
+#define S5PV210_PA_PCM0 0xE2300000
+#define S5PV210_PA_PCM1 0xE1200000
+#define S5PV210_PA_PCM2 0xE2B00000
+
+#define S5PV210_PA_TIMER 0xE2500000
+#define S5PV210_PA_SYSTIMER 0xE2600000
+#define S5PV210_PA_WATCHDOG 0xE2700000
+#define S5PV210_PA_RTC 0xE2800000
+
+#define S5PV210_PA_UART 0xE2900000
+
+#define S5PV210_PA_SROMC 0xE8000000
+
+#define S5PV210_PA_CFCON 0xE8200000
+
+#define S5PV210_PA_HSMMC(x) (0xEB000000 + ((x) * 0x100000))
+
+#define S5PV210_PA_HSOTG 0xEC000000
+#define S5PV210_PA_HSPHY 0xEC100000
+
+#define S5PV210_PA_IIS0 0xEEE30000
+#define S5PV210_PA_IIS1 0xE2100000
+#define S5PV210_PA_IIS2 0xE2A00000
+
+#define S5PV210_PA_DMC0 0xF0000000
+#define S5PV210_PA_DMC1 0xF1400000
+
+#define S5PV210_PA_VIC0 0xF2000000
+#define S5PV210_PA_VIC1 0xF2100000
+#define S5PV210_PA_VIC2 0xF2200000
+#define S5PV210_PA_VIC3 0xF2300000
+
+#define S5PV210_PA_FB 0xF8000000
+
+#define S5PV210_PA_MDMA 0xFA200000
+#define S5PV210_PA_PDMA0 0xE0900000
+#define S5PV210_PA_PDMA1 0xE0A00000
+
+#define S5PV210_PA_MIPI_CSIS 0xFA600000
+
+#define S5PV210_PA_FIMC0 0xFB200000
+#define S5PV210_PA_FIMC1 0xFB300000
+#define S5PV210_PA_FIMC2 0xFB400000
+
+/* Compatibiltiy Defines */
+
+#define S3C_PA_FB S5PV210_PA_FB
+#define S3C_PA_HSMMC0 S5PV210_PA_HSMMC(0)
+#define S3C_PA_HSMMC1 S5PV210_PA_HSMMC(1)
+#define S3C_PA_HSMMC2 S5PV210_PA_HSMMC(2)
+#define S3C_PA_HSMMC3 S5PV210_PA_HSMMC(3)
+#define S3C_PA_IIC S5PV210_PA_IIC0
+#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 S5P_PA_CHIPID S5PV210_PA_CHIPID
+#define S5P_PA_FIMC0 S5PV210_PA_FIMC0
+#define S5P_PA_FIMC1 S5PV210_PA_FIMC1
+#define S5P_PA_FIMC2 S5PV210_PA_FIMC2
+#define S5P_PA_MIPI_CSIS0 S5PV210_PA_MIPI_CSIS
+#define S5P_PA_ONENAND S5PC110_PA_ONENAND
+#define S5P_PA_ONENAND_DMA S5PC110_PA_ONENAND_DMA
+#define S5P_PA_SDRAM S5PV210_PA_SDRAM
+#define S5P_PA_SROMC S5PV210_PA_SROMC
+#define S5P_PA_SYSCON S5PV210_PA_SYSCON
+#define S5P_PA_TIMER S5PV210_PA_TIMER
+
+#define SAMSUNG_PA_ADC S5PV210_PA_ADC
+#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
+#define SAMSUNG_PA_KEYPAD S5PV210_PA_KEYPAD
+
+/* UART */
+
+#define S3C_VA_UARTx(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+
+#define S3C_PA_UART S5PV210_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_SZ_UART SZ_256
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h
new file mode 100644
index 00000000..7b5fcf0d
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/memory.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Memory definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x20000000)
+#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
+
+/*
+ * Sparsemem support
+ * Physical memory can be located from 0x20000000 to 0x7fffffff,
+ * so MAX_PHYSMEM_BITS is 31.
+ */
+
+#define MAX_PHYSMEM_BITS 31
+#define SECTION_SIZE_BITS 28
+
+#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/pm-core.h b/arch/arm/mach-s5pv210/include/mach/pm-core.h
new file mode 100644
index 00000000..e8d394f8
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pm-core.h
@@ -0,0 +1,43 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pm-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/pm-core.h,
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S5PV210 - PM core support for arch/arm/plat-s5p/pm.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+static inline void s3c_pm_debug_init_uart(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_prepare_irqs(void)
+{
+ __raw_writel(s3c_irqwake_intmask, S5P_WAKEUP_MASK);
+ __raw_writel(s3c_irqwake_eintmask, S5P_EINT_WAKEUP_MASK);
+}
+
+static inline void s3c_pm_arch_stop_clocks(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_show_resume_irqs(void)
+{
+ /* nothing here yet */
+}
+
+static inline void s3c_pm_arch_update_uart(void __iomem *regs,
+ struct pm_uart_save *save)
+{
+ /* nothing here yet */
+}
diff --git a/arch/arm/mach-s5pv210/include/mach/pwm-clock.h b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
new file mode 100644
index 00000000..f8a9f1b3
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/pwm-clock.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Based on arch/arm/mach-s3c64xx/include/mach/pwm-clock.h
+ *
+ * S5PV210 - pwm clock and timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_PWMCLK_H
+#define __ASM_ARCH_PWMCLK_H __FILE__
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @tcfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C64XX_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << tcfg1;
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 1;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div);
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C64XX_TCFG1_MUX_TCLK
+
+#endif /* __ASM_ARCH_PWMCLK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
new file mode 100644
index 00000000..78925c51
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -0,0 +1,205 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Clock register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_CLKREG(x) (S3C_VA_SYS + (x))
+
+#define S5P_APLL_LOCK S5P_CLKREG(0x00)
+#define S5P_MPLL_LOCK S5P_CLKREG(0x08)
+#define S5P_EPLL_LOCK S5P_CLKREG(0x10)
+#define S5P_VPLL_LOCK S5P_CLKREG(0x20)
+
+#define S5P_APLL_CON S5P_CLKREG(0x100)
+#define S5P_MPLL_CON S5P_CLKREG(0x108)
+#define S5P_EPLL_CON S5P_CLKREG(0x110)
+#define S5P_EPLL_CON1 S5P_CLKREG(0x114)
+#define S5P_VPLL_CON S5P_CLKREG(0x120)
+
+#define S5P_CLK_SRC0 S5P_CLKREG(0x200)
+#define S5P_CLK_SRC1 S5P_CLKREG(0x204)
+#define S5P_CLK_SRC2 S5P_CLKREG(0x208)
+#define S5P_CLK_SRC3 S5P_CLKREG(0x20C)
+#define S5P_CLK_SRC4 S5P_CLKREG(0x210)
+#define S5P_CLK_SRC5 S5P_CLKREG(0x214)
+#define S5P_CLK_SRC6 S5P_CLKREG(0x218)
+
+#define S5P_CLK_SRC_MASK0 S5P_CLKREG(0x280)
+#define S5P_CLK_SRC_MASK1 S5P_CLKREG(0x284)
+
+#define S5P_CLK_DIV0 S5P_CLKREG(0x300)
+#define S5P_CLK_DIV1 S5P_CLKREG(0x304)
+#define S5P_CLK_DIV2 S5P_CLKREG(0x308)
+#define S5P_CLK_DIV3 S5P_CLKREG(0x30C)
+#define S5P_CLK_DIV4 S5P_CLKREG(0x310)
+#define S5P_CLK_DIV5 S5P_CLKREG(0x314)
+#define S5P_CLK_DIV6 S5P_CLKREG(0x318)
+#define S5P_CLK_DIV7 S5P_CLKREG(0x31C)
+
+#define S5P_CLKGATE_MAIN0 S5P_CLKREG(0x400)
+#define S5P_CLKGATE_MAIN1 S5P_CLKREG(0x404)
+#define S5P_CLKGATE_MAIN2 S5P_CLKREG(0x408)
+
+#define S5P_CLKGATE_PERI0 S5P_CLKREG(0x420)
+#define S5P_CLKGATE_PERI1 S5P_CLKREG(0x424)
+
+#define S5P_CLKGATE_SCLK0 S5P_CLKREG(0x440)
+#define S5P_CLKGATE_SCLK1 S5P_CLKREG(0x444)
+#define S5P_CLKGATE_IP0 S5P_CLKREG(0x460)
+#define S5P_CLKGATE_IP1 S5P_CLKREG(0x464)
+#define S5P_CLKGATE_IP2 S5P_CLKREG(0x468)
+#define S5P_CLKGATE_IP3 S5P_CLKREG(0x46C)
+#define S5P_CLKGATE_IP4 S5P_CLKREG(0x470)
+
+#define S5P_CLKGATE_BLOCK S5P_CLKREG(0x480)
+#define S5P_CLKGATE_BUS0 S5P_CLKREG(0x484)
+#define S5P_CLKGATE_BUS1 S5P_CLKREG(0x488)
+#define S5P_CLK_OUT S5P_CLKREG(0x500)
+
+/* DIV/MUX STATUS */
+#define S5P_CLKDIV_STAT0 S5P_CLKREG(0x1000)
+#define S5P_CLKDIV_STAT1 S5P_CLKREG(0x1004)
+#define S5P_CLKMUX_STAT0 S5P_CLKREG(0x1100)
+#define S5P_CLKMUX_STAT1 S5P_CLKREG(0x1104)
+
+/* CLKSRC0 */
+#define S5P_CLKSRC0_MUX200_SHIFT (16)
+#define S5P_CLKSRC0_MUX200_MASK (0x1 << S5P_CLKSRC0_MUX200_SHIFT)
+#define S5P_CLKSRC0_MUX166_MASK (0x1<<20)
+#define S5P_CLKSRC0_MUX133_MASK (0x1<<24)
+
+/* CLKSRC2 */
+#define S5P_CLKSRC2_G3D_SHIFT (0)
+#define S5P_CLKSRC2_G3D_MASK (0x3 << S5P_CLKSRC2_G3D_SHIFT)
+#define S5P_CLKSRC2_MFC_SHIFT (4)
+#define S5P_CLKSRC2_MFC_MASK (0x3 << S5P_CLKSRC2_MFC_SHIFT)
+
+/* CLKSRC6*/
+#define S5P_CLKSRC6_ONEDRAM_SHIFT (24)
+#define S5P_CLKSRC6_ONEDRAM_MASK (0x3 << S5P_CLKSRC6_ONEDRAM_SHIFT)
+
+/* CLKDIV0 */
+#define S5P_CLKDIV0_APLL_SHIFT (0)
+#define S5P_CLKDIV0_APLL_MASK (0x7 << S5P_CLKDIV0_APLL_SHIFT)
+#define S5P_CLKDIV0_A2M_SHIFT (4)
+#define S5P_CLKDIV0_A2M_MASK (0x7 << S5P_CLKDIV0_A2M_SHIFT)
+#define S5P_CLKDIV0_HCLK200_SHIFT (8)
+#define S5P_CLKDIV0_HCLK200_MASK (0x7 << S5P_CLKDIV0_HCLK200_SHIFT)
+#define S5P_CLKDIV0_PCLK100_SHIFT (12)
+#define S5P_CLKDIV0_PCLK100_MASK (0x7 << S5P_CLKDIV0_PCLK100_SHIFT)
+#define S5P_CLKDIV0_HCLK166_SHIFT (16)
+#define S5P_CLKDIV0_HCLK166_MASK (0xF << S5P_CLKDIV0_HCLK166_SHIFT)
+#define S5P_CLKDIV0_PCLK83_SHIFT (20)
+#define S5P_CLKDIV0_PCLK83_MASK (0x7 << S5P_CLKDIV0_PCLK83_SHIFT)
+#define S5P_CLKDIV0_HCLK133_SHIFT (24)
+#define S5P_CLKDIV0_HCLK133_MASK (0xF << S5P_CLKDIV0_HCLK133_SHIFT)
+#define S5P_CLKDIV0_PCLK66_SHIFT (28)
+#define S5P_CLKDIV0_PCLK66_MASK (0x7 << S5P_CLKDIV0_PCLK66_SHIFT)
+
+/* CLKDIV2 */
+#define S5P_CLKDIV2_G3D_SHIFT (0)
+#define S5P_CLKDIV2_G3D_MASK (0xF << S5P_CLKDIV2_G3D_SHIFT)
+#define S5P_CLKDIV2_MFC_SHIFT (4)
+#define S5P_CLKDIV2_MFC_MASK (0xF << S5P_CLKDIV2_MFC_SHIFT)
+
+/* CLKDIV6 */
+#define S5P_CLKDIV6_ONEDRAM_SHIFT (28)
+#define S5P_CLKDIV6_ONEDRAM_MASK (0xF << S5P_CLKDIV6_ONEDRAM_SHIFT)
+
+#define S5P_SWRESET S5P_CLKREG(0x2000)
+
+#define S5P_ARM_MCS_CON S5P_CLKREG(0x6100)
+
+/* Registers related to power management */
+#define S5P_PWR_CFG S5P_CLKREG(0xC000)
+#define S5P_EINT_WAKEUP_MASK S5P_CLKREG(0xC004)
+#define S5P_WAKEUP_MASK S5P_CLKREG(0xC008)
+#define S5P_PWR_MODE S5P_CLKREG(0xC00C)
+#define S5P_NORMAL_CFG S5P_CLKREG(0xC010)
+#define S5P_IDLE_CFG S5P_CLKREG(0xC020)
+#define S5P_STOP_CFG S5P_CLKREG(0xC030)
+#define S5P_STOP_MEM_CFG S5P_CLKREG(0xC034)
+#define S5P_SLEEP_CFG S5P_CLKREG(0xC040)
+
+#define S5P_OSC_FREQ S5P_CLKREG(0xC100)
+#define S5P_OSC_STABLE S5P_CLKREG(0xC104)
+#define S5P_PWR_STABLE S5P_CLKREG(0xC108)
+#define S5P_MTC_STABLE S5P_CLKREG(0xC110)
+#define S5P_CLAMP_STABLE S5P_CLKREG(0xC114)
+
+#define S5P_WAKEUP_STAT S5P_CLKREG(0xC200)
+#define S5P_BLK_PWR_STAT S5P_CLKREG(0xC204)
+
+#define S5P_OTHERS S5P_CLKREG(0xE000)
+#define S5P_OM_STAT S5P_CLKREG(0xE100)
+#define S5P_USB_PHY_CONTROL S5P_CLKREG(0xE80C)
+#define S5P_DAC_CONTROL S5P_CLKREG(0xE810)
+#define S5P_MIPI_DPHY_CONTROL(x) S5P_CLKREG(0xE814)
+#define S5P_MIPI_DPHY_ENABLE (1 << 0)
+#define S5P_MIPI_DPHY_SRESETN (1 << 1)
+#define S5P_MIPI_DPHY_MRESETN (1 << 2)
+
+#define S5P_INFORM0 S5P_CLKREG(0xF000)
+#define S5P_INFORM1 S5P_CLKREG(0xF004)
+#define S5P_INFORM2 S5P_CLKREG(0xF008)
+#define S5P_INFORM3 S5P_CLKREG(0xF00C)
+#define S5P_INFORM4 S5P_CLKREG(0xF010)
+#define S5P_INFORM5 S5P_CLKREG(0xF014)
+#define S5P_INFORM6 S5P_CLKREG(0xF018)
+#define S5P_INFORM7 S5P_CLKREG(0xF01C)
+
+#define S5P_RST_STAT S5P_CLKREG(0xA000)
+#define S5P_OSC_CON S5P_CLKREG(0x8000)
+#define S5P_MDNIE_SEL S5P_CLKREG(0x7008)
+#define S5P_MIPI_PHY_CON0 S5P_CLKREG(0x7200)
+#define S5P_MIPI_PHY_CON1 S5P_CLKREG(0x7204)
+
+#define S5P_IDLE_CFG_TL_MASK (3 << 30)
+#define S5P_IDLE_CFG_TM_MASK (3 << 28)
+#define S5P_IDLE_CFG_TL_ON (2 << 30)
+#define S5P_IDLE_CFG_TM_ON (2 << 28)
+#define S5P_IDLE_CFG_DIDLE (1 << 0)
+
+#define S5P_CFG_WFI_CLEAN (~(3 << 8))
+#define S5P_CFG_WFI_IDLE (1 << 8)
+#define S5P_CFG_WFI_STOP (2 << 8)
+#define S5P_CFG_WFI_SLEEP (3 << 8)
+
+#define S5P_OTHER_SYS_INT 24
+#define S5P_OTHER_STA_TYPE 23
+#define S5P_OTHER_SYSC_INTOFF (1 << 0)
+#define STA_TYPE_EXPON 0
+#define STA_TYPE_SFR 1
+
+#define S5P_PWR_STA_EXP_SCALE 0
+#define S5P_PWR_STA_CNT 4
+
+#define S5P_PWR_STABLE_COUNT 85500
+
+#define S5P_SLEEP_CFG_OSC_EN (1 << 0)
+#define S5P_SLEEP_CFG_USBOSC_EN (1 << 1)
+
+/* OTHERS Resgister */
+#define S5P_OTHERS_RET_IO (1 << 31)
+#define S5P_OTHERS_RET_CF (1 << 30)
+#define S5P_OTHERS_RET_MMC (1 << 29)
+#define S5P_OTHERS_RET_UART (1 << 28)
+#define S5P_OTHERS_USB_SIG_MASK (1 << 16)
+
+/* S5P_DAC_CONTROL */
+#define S5P_DAC_ENABLE (1)
+#define S5P_DAC_DISABLE (0)
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-fb.h b/arch/arm/mach-s5pv210/include/mach/regs-fb.h
new file mode 100644
index 00000000..60d99298
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-fb.h
@@ -0,0 +1,21 @@
+/*
+ * 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/include/mach/regs-gpio.h b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
new file mode 100644
index 00000000..de0c8997
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
@@ -0,0 +1,41 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-gpio.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 - 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>
+
+#define S5PV210_EINT30CON (S5P_VA_GPIO + 0xE00)
+#define S5P_EINT_CON(x) (S5PV210_EINT30CON + ((x) * 0x4))
+
+#define S5PV210_EINT30FLTCON0 (S5P_VA_GPIO + 0xE80)
+#define S5P_EINT_FLTCON(x) (S5PV210_EINT30FLTCON0 + ((x) * 0x4))
+
+#define S5PV210_EINT30MASK (S5P_VA_GPIO + 0xF00)
+#define S5P_EINT_MASK(x) (S5PV210_EINT30MASK + ((x) * 0x4))
+
+#define S5PV210_EINT30PEND (S5P_VA_GPIO + 0xF40)
+#define S5P_EINT_PEND(x) (S5PV210_EINT30PEND + ((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) S5PV210_GPH0(x)
+#define EINT_GPIO_1(x) S5PV210_GPH1(x)
+#define EINT_GPIO_2(x) S5PV210_GPH2(x)
+#define EINT_GPIO_3(x) S5PV210_GPH3(x)
+
+#endif /* __ASM_ARCH_REGS_GPIO_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-irq.h b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
new file mode 100644
index 00000000..5c3b104a
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-irq.h
@@ -0,0 +1,19 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - IRQ register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_IRQ_H
+#define __ASM_ARCH_REGS_IRQ_H __FILE__
+
+#include <asm/hardware/vic.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-sys.h b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
new file mode 100644
index 00000000..26691d39
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/regs-sys.h
@@ -0,0 +1,19 @@
+/* arch/arm/mach-s5pv210/include/mach/regs-sys.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - System registers definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define S5PV210_USB_PHY_CON (S3C_VA_SYS + 0xE80C)
+#define S5PV210_USB_PHY0_EN (1 << 0)
+#define S5PV210_USB_PHY1_EN (1 << 1)
+
+/* compatibility defines for s3c-hsotg driver */
+#define S3C64XX_OTHERS S5PV210_USB_PHY_CON
+#define S3C64XX_OTHERS_USBMASK S5PV210_USB_PHY0_EN
diff --git a/arch/arm/mach-s5pv210/include/mach/spi-clocks.h b/arch/arm/mach-s5pv210/include/mach/spi-clocks.h
new file mode 100644
index 00000000..02acded5
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/spi-clocks.h
@@ -0,0 +1,17 @@
+/* linux/arch/arm/mach-s5pv210/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 __S5PV210_PLAT_SPI_CLKS_H
+#define __S5PV210_PLAT_SPI_CLKS_H __FILE__
+
+#define S5PV210_SPI_SRCCLK_PCLK 0
+#define S5PV210_SPI_SRCCLK_SCLK 1
+
+#endif /* __S5PV210_PLAT_SPI_CLKS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h
new file mode 100644
index 00000000..af8a200b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/system.h
@@ -0,0 +1,23 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/system.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - system support header
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H __FILE__
+
+#include <plat/system-reset.h>
+
+static void arch_idle(void)
+{
+ /* nothing here yet */
+}
+
+#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/tick.h b/arch/arm/mach-s5pv210/include/mach/tick.h
new file mode 100644
index 00000000..7993b360
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/tick.h
@@ -0,0 +1,26 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/tick.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s3c6400/include/mach/tick.h
+ *
+ * S5PV210 - Timer tick support definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TICK_H
+#define __ASM_ARCH_TICK_H __FILE__
+
+static inline u32 s3c24xx_ostimer_pending(void)
+{
+ u32 pend = __raw_readl(VA_VIC0 + VIC_RAW_STATUS);
+ return pend & (1 << (IRQ_TIMER4_VIC - S5P_IRQ_VIC0(0)));
+}
+
+#define TICK_MAX (0xffffffff)
+
+#endif /* __ASM_ARCH_TICK_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/timex.h b/arch/arm/mach-s5pv210/include/mach/timex.h
new file mode 100644
index 00000000..73dc8549
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/timex.h
@@ -0,0 +1,29 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/timex.h
+ *
+ * Copyright (c) 2003-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/timex.h
+ *
+ * S5PV210 - time parameters
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H __FILE__
+
+/* CLOCK_TICK_RATE needs to be evaluatable by the cpp, so making it
+ * a variable is useless. It seems as long as we make our timers an
+ * exact multiple of HZ, any value that makes a 1->1 correspondence
+ * for the time conversion functions to/from jiffies is acceptable.
+*/
+
+#define CLOCK_TICK_RATE 12000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/uncompress.h b/arch/arm/mach-s5pv210/include/mach/uncompress.h
new file mode 100644
index 00000000..08ff2fda
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/uncompress.h
@@ -0,0 +1,24 @@
+/* linux/arch/arm/mach-s5pv210/include/mach/uncompress.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <mach/map.h>
+#include <plat/uncompress.h>
+
+static void arch_detect_cpu(void)
+{
+ /* we do not need to do any cpu detection here at the moment. */
+}
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/vmalloc.h b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
new file mode 100644
index 00000000..a6c659d6
--- /dev/null
+++ b/arch/arm/mach-s5pv210/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/* linux/arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on arch/arm/mach-s5p6442/include/mach/vmalloc.h
+ *
+ * S5PV210 vmalloc 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_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H __FILE__
+
+#define VMALLOC_END 0xF6000000UL
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
new file mode 100644
index 00000000..4865ae2c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/init.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/mach-s5pv210/init.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s5pv210.h>
+#include <plat/regs-serial.h>
+
+static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
+ [0] = {
+ .name = "pclk",
+ .divisor = 1,
+ .min_baud = 0,
+ .max_baud = 0,
+ },
+};
+
+/* uart registration process */
+void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ struct s3c2410_uartcfg *tcfg = cfg;
+ u32 ucnt;
+
+ for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
+ if (!tcfg->clocks) {
+ tcfg->clocks = s5pv210_serial_clocks;
+ tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
+ }
+ }
+
+ s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
+}
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
new file mode 100644
index 00000000..4e1d8ff5
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -0,0 +1,686 @@
+/* linux/arch/arm/mach-s5pv210/mach-aquila.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+#include <plat/fimc-core.h>
+#include <plat/sdhci.h>
+#include <plat/s5p-time.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define AQUILA_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define AQUILA_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define AQUILA_UFCON_DEFAULT S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg aquila_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = AQUILA_UCON_DEFAULT,
+ .ulcon = AQUILA_ULCON_DEFAULT,
+ /*
+ * Actually UART0 can support 256 bytes fifo, but aquila board
+ * supports 128 bytes fifo because of initial chip bug
+ */
+ .ufcon = AQUILA_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG128 | S5PV210_UFCON_RXTRIG128,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = AQUILA_UCON_DEFAULT,
+ .ulcon = AQUILA_ULCON_DEFAULT,
+ .ufcon = AQUILA_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG64 | S5PV210_UFCON_RXTRIG64,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = AQUILA_UCON_DEFAULT,
+ .ulcon = AQUILA_ULCON_DEFAULT,
+ .ufcon = AQUILA_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = AQUILA_UCON_DEFAULT,
+ .ulcon = AQUILA_ULCON_DEFAULT,
+ .ufcon = AQUILA_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
+ },
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win aquila_fb_win0 = {
+ .win_mode = {
+ .left_margin = 16,
+ .right_margin = 16,
+ .upper_margin = 3,
+ .lower_margin = 28,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_pd_win aquila_fb_win1 = {
+ .win_mode = {
+ .left_margin = 16,
+ .right_margin = 16,
+ .upper_margin = 3,
+ .lower_margin = 28,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_platdata aquila_lcd_pdata __initdata = {
+ .win[0] = &aquila_fb_win0,
+ .win[1] = &aquila_fb_win1,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC |
+ VIDCON1_INV_VCLK | VIDCON1_INV_VDEN,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_init_data aquila_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 aquila_ldo3_data = {
+ .constraints = {
+ .name = "VUSB+MIPI_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo4_data = {
+ .constraints = {
+ .name = "VDAC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo5_data = {
+ .constraints = {
+ .name = "VTF_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo6_data = {
+ .constraints = {
+ .name = "VCC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo7_data = {
+ .constraints = {
+ .name = "VCC_3.0V",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo8_data = {
+ .constraints = {
+ .name = "VUSB+VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo9_data = {
+ .constraints = {
+ .name = "VCC+VCAM_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo10_data = {
+ .constraints = {
+ .name = "VPLL_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo11_data = {
+ .constraints = {
+ .name = "CAM_IO_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo12_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo13_data = {
+ .constraints = {
+ .name = "CAM_A_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo14_data = {
+ .constraints = {
+ .name = "CAM_CIF_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo15_data = {
+ .constraints = {
+ .name = "CAM_AF_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo16_data = {
+ .constraints = {
+ .name = "VMIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo17_data = {
+ .constraints = {
+ .name = "CAM_8M_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data aquila_buck1_data = {
+ .constraints = {
+ .name = "VARM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck1_consumer,
+};
+
+static struct regulator_init_data aquila_buck2_data = {
+ .constraints = {
+ .name = "VINT_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck2_consumer,
+};
+
+static struct regulator_init_data aquila_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data aquila_buck4_data = {
+ .constraints = {
+ .name = "CAM_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct max8998_regulator_data aquila_regulators[] = {
+ { MAX8998_LDO2, &aquila_ldo2_data },
+ { MAX8998_LDO3, &aquila_ldo3_data },
+ { MAX8998_LDO4, &aquila_ldo4_data },
+ { MAX8998_LDO5, &aquila_ldo5_data },
+ { MAX8998_LDO6, &aquila_ldo6_data },
+ { MAX8998_LDO7, &aquila_ldo7_data },
+ { MAX8998_LDO8, &aquila_ldo8_data },
+ { MAX8998_LDO9, &aquila_ldo9_data },
+ { MAX8998_LDO10, &aquila_ldo10_data },
+ { MAX8998_LDO11, &aquila_ldo11_data },
+ { MAX8998_LDO12, &aquila_ldo12_data },
+ { MAX8998_LDO13, &aquila_ldo13_data },
+ { MAX8998_LDO14, &aquila_ldo14_data },
+ { MAX8998_LDO15, &aquila_ldo15_data },
+ { MAX8998_LDO16, &aquila_ldo16_data },
+ { MAX8998_LDO17, &aquila_ldo17_data },
+ { MAX8998_BUCK1, &aquila_buck1_data },
+ { MAX8998_BUCK2, &aquila_buck2_data },
+ { MAX8998_BUCK3, &aquila_buck3_data },
+ { MAX8998_BUCK4, &aquila_buck4_data },
+};
+
+static struct max8998_platform_data aquila_max8998_pdata = {
+ .num_regulators = ARRAY_SIZE(aquila_regulators),
+ .regulators = aquila_regulators,
+ .buck1_set1 = S5PV210_GPH0(3),
+ .buck1_set2 = S5PV210_GPH0(4),
+ .buck2_set3 = S5PV210_GPH0(5),
+ .buck1_voltage1 = 1200000,
+ .buck1_voltage2 = 1200000,
+ .buck1_voltage3 = 1200000,
+ .buck1_voltage4 = 1200000,
+ .buck2_voltage1 = 1200000,
+ .buck2_voltage2 = 1200000,
+};
+#endif
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("DBVDD", "5-001a"),
+ REGULATOR_SUPPLY("AVDD2", "5-001a"),
+ REGULATOR_SUPPLY("CPVDD", "5-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "5-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "5-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 fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VCC_1.8V_PDA",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "V_BAT",
+ .microvolts = 3700000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "5-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "5-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1_3.0V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD_1.0V",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* configure gpio3/4/5/7 function for AIF2 voice */
+ .gpio_defaults[2] = 0x8100,
+ .gpio_defaults[3] = 0x8100,
+ .gpio_defaults[4] = 0x8100,
+ .gpio_defaults[6] = 0x0100,
+ /* configure gpio8/9/10/11 function for AIF3 BT */
+ .gpio_defaults[7] = 0x8100,
+ .gpio_defaults[8] = 0x0100,
+ .gpio_defaults[9] = 0x0100,
+ .gpio_defaults[10] = 0x0100,
+ .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4 4
+static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
+ .sda_pin = S5PV210_GPJ4(0), /* XMSMCSN */
+ .scl_pin = S5PV210_GPJ4(3), /* XMSMIRQN */
+};
+
+static struct platform_device aquila_i2c_gpio_pmic = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_PMIC_BUS_4,
+ .dev = {
+ .platform_data = &aquila_i2c_gpio_pmic_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+ {
+ /* 0xCC when SRAD = 0 */
+ I2C_BOARD_INFO("max8998", 0xCC >> 1),
+ .platform_data = &aquila_max8998_pdata,
+ },
+#endif
+};
+
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5 5
+static struct i2c_gpio_platform_data aquila_i2c_gpio5_data = {
+ .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
+ .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
+};
+
+static struct platform_device aquila_i2c_gpio5 = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_BUS_5,
+ .dev = {
+ .platform_data = &aquila_i2c_gpio5_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+ {
+ /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button aquila_gpio_keys_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = S5PV210_GPH2(6),
+ .desc = "gpio-keys: KEY_POWER",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data aquila_gpio_keys_data = {
+ .buttons = aquila_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(aquila_gpio_keys_table),
+};
+
+static struct platform_device aquila_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &aquila_gpio_keys_data,
+ },
+};
+
+static void __init aquila_pmic_init(void)
+{
+ /* AP_PMIC_IRQ: EINT7 */
+ s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+ /* nPower: EINT22 */
+ s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
+/* MoviNAND */
+static struct s3c_sdhci_platdata aquila_hsmmc0_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+};
+
+/* Wireless LAN */
+static struct s3c_sdhci_platdata aquila_hsmmc1_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ /* ext_cd_{init,cleanup} callbacks will be added later */
+};
+
+/* External Flash */
+#define AQUILA_EXT_FLASH_EN S5PV210_MP05(4)
+#define AQUILA_EXT_FLASH_CD S5PV210_GPH3(4)
+static struct s3c_sdhci_platdata aquila_hsmmc2_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = AQUILA_EXT_FLASH_CD,
+ .ext_cd_gpio_invert = 1,
+};
+
+static void aquila_setup_sdhci(void)
+{
+ gpio_request(AQUILA_EXT_FLASH_EN, "FLASH_EN");
+ gpio_direction_output(AQUILA_EXT_FLASH_EN, 1);
+
+ s3c_sdhci0_set_platdata(&aquila_hsmmc0_data);
+ s3c_sdhci1_set_platdata(&aquila_hsmmc1_data);
+ s3c_sdhci2_set_platdata(&aquila_hsmmc2_data);
+};
+
+static struct platform_device *aquila_devices[] __initdata = {
+ &aquila_i2c_gpio_pmic,
+ &aquila_i2c_gpio5,
+ &aquila_device_gpiokeys,
+ &s3c_device_fb,
+ &s5p_device_onenand,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s5pv210_device_iis0,
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+};
+
+static void __init aquila_sound_init(void)
+{
+ unsigned int gpio;
+
+ /* CODEC_XTAL_EN
+ *
+ * The Aquila board have a oscillator which provide main clock
+ * to WM8994 codec. The oscillator provide 24MHz clock to WM8994
+ * clock. Set gpio setting of "CODEC_XTAL_EN" to enable a oscillator.
+ * */
+ gpio = S5PV210_GPH3(2); /* XEINT_26 */
+ gpio_request(gpio, "CODEC_XTAL_EN");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+
+ /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+ * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+ * because it needs 24MHz clock to operate WM8994 codec.
+ */
+ __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
+static void __init aquila_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+}
+
+static void __init aquila_machine_init(void)
+{
+ /* PMIC */
+ aquila_pmic_init();
+ i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+ ARRAY_SIZE(i2c_gpio_pmic_devs));
+ /* SDHCI */
+ aquila_setup_sdhci();
+
+ s3c_fimc_setname(0, "s5p-fimc");
+ s3c_fimc_setname(1, "s5p-fimc");
+ s3c_fimc_setname(2, "s5p-fimc");
+
+ /* SOUND */
+ aquila_sound_init();
+ i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+ ARRAY_SIZE(i2c_gpio5_devs));
+
+ /* FB */
+ s3c_fb_set_platdata(&aquila_lcd_pdata);
+
+ platform_add_devices(aquila_devices, ARRAY_SIZE(aquila_devices));
+}
+
+MACHINE_START(AQUILA, "Aquila")
+ /* Maintainers:
+ Marek Szyprowski <m.szyprowski@samsung.com>
+ Kyungmin Park <kyungmin.park@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = aquila_map_io,
+ .init_machine = aquila_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
new file mode 100644
index 00000000..31d5aa76
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -0,0 +1,896 @@
+/* linux/arch/arm/mach-s5pv210/mach-goni.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/atmel_mxt_ts.h>
+#include <linux/mfd/max8998.h>
+#include <linux/mfd/wm8994/pdata.h>
+#include <linux/regulator/fixed.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/lcd.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+#include <plat/iic.h>
+#include <plat/keypad.h>
+#include <plat/sdhci.h>
+#include <plat/clock.h>
+#include <plat/s5p-time.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define GONI_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define GONI_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define GONI_UFCON_DEFAULT S3C2410_UFCON_FIFOMODE
+
+static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = GONI_UCON_DEFAULT,
+ .ulcon = GONI_ULCON_DEFAULT,
+ .ufcon = GONI_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG256 | S5PV210_UFCON_RXTRIG256,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = GONI_UCON_DEFAULT,
+ .ulcon = GONI_ULCON_DEFAULT,
+ .ufcon = GONI_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG64 | S5PV210_UFCON_RXTRIG64,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = GONI_UCON_DEFAULT,
+ .ulcon = GONI_ULCON_DEFAULT,
+ .ufcon = GONI_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = GONI_UCON_DEFAULT,
+ .ulcon = GONI_ULCON_DEFAULT,
+ .ufcon = GONI_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
+ },
+};
+
+/* Frame Buffer */
+static struct s3c_fb_pd_win goni_fb_win0 = {
+ .win_mode = {
+ .left_margin = 16,
+ .right_margin = 16,
+ .upper_margin = 2,
+ .lower_margin = 28,
+ .hsync_len = 2,
+ .vsync_len = 1,
+ .xres = 480,
+ .yres = 800,
+ .refresh = 55,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+ .virtual_x = 480,
+ .virtual_y = 2 * 800,
+};
+
+static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
+ .win[0] = &goni_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+ VIDCON0_CLKSEL_LCD,
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+ | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
+static int lcd_power_on(struct lcd_device *ld, int enable)
+{
+ return 1;
+}
+
+static int reset_lcd(struct lcd_device *ld)
+{
+ static unsigned int first = 1;
+ int reset_gpio = -1;
+
+ reset_gpio = S5PV210_MP05(5);
+
+ if (first) {
+ gpio_request(reset_gpio, "MLCD_RST");
+ first = 0;
+ }
+
+ gpio_direction_output(reset_gpio, 1);
+ return 1;
+}
+
+static struct lcd_platform_data goni_lcd_platform_data = {
+ .reset = reset_lcd,
+ .power_on = lcd_power_on,
+ .lcd_enabled = 0,
+ .reset_delay = 120, /* 120ms */
+ .power_on_delay = 25, /* 25ms */
+ .power_off_delay = 200, /* 200ms */
+};
+
+#define LCD_BUS_NUM 3
+static struct spi_board_info spi_board_info[] __initdata = {
+ {
+ .modalias = "s6e63m0",
+ .platform_data = &goni_lcd_platform_data,
+ .max_speed_hz = 1200000,
+ .bus_num = LCD_BUS_NUM,
+ .chip_select = 0,
+ .mode = SPI_MODE_3,
+ .controller_data = (void *)S5PV210_MP01(1), /* DISPLAY_CS */
+ },
+};
+
+static struct spi_gpio_platform_data lcd_spi_gpio_data = {
+ .sck = S5PV210_MP04(1), /* DISPLAY_CLK */
+ .mosi = S5PV210_MP04(3), /* DISPLAY_SI */
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+static struct platform_device goni_spi_gpio = {
+ .name = "spi_gpio",
+ .id = LCD_BUS_NUM,
+ .dev = {
+ .parent = &s3c_device_fb.dev,
+ .platform_data = &lcd_spi_gpio_data,
+ },
+};
+
+/* KEYPAD */
+static uint32_t keymap[] __initdata = {
+ /* KEY(row, col, keycode) */
+ KEY(0, 1, KEY_MENU), /* Send */
+ KEY(0, 2, KEY_BACK), /* End */
+ KEY(1, 1, KEY_CONFIG), /* Half shot */
+ KEY(1, 2, KEY_VOLUMEUP),
+ KEY(2, 1, KEY_CAMERA), /* Full shot */
+ KEY(2, 2, KEY_VOLUMEDOWN),
+};
+
+static struct matrix_keymap_data keymap_data __initdata = {
+ .keymap = keymap,
+ .keymap_size = ARRAY_SIZE(keymap),
+};
+
+static struct samsung_keypad_platdata keypad_data __initdata = {
+ .keymap_data = &keymap_data,
+ .rows = 3,
+ .cols = 3,
+};
+
+/* Radio */
+static struct i2c_board_info i2c1_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("si470x", 0x10),
+ },
+};
+
+static void __init goni_radio_init(void)
+{
+ int gpio;
+
+ gpio = S5PV210_GPJ2(4); /* XMSMDATA_4 */
+ gpio_request(gpio, "FM_INT");
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ i2c1_devs[0].irq = gpio_to_irq(gpio);
+
+ gpio = S5PV210_GPJ2(5); /* XMSMDATA_5 */
+ gpio_request(gpio, "FM_RST");
+ gpio_direction_output(gpio, 1);
+}
+
+/* TSP */
+static struct mxt_platform_data qt602240_platform_data = {
+ .x_line = 17,
+ .y_line = 11,
+ .x_size = 800,
+ .y_size = 480,
+ .blen = 0x21,
+ .threshold = 0x28,
+ .voltage = 2800000, /* 2.8V */
+ .orient = MXT_DIAGONAL,
+ .irqflags = IRQF_TRIGGER_FALLING,
+};
+
+static struct s3c2410_platform_i2c i2c2_data __initdata = {
+ .flags = 0,
+ .bus_num = 2,
+ .slave_addr = 0x10,
+ .frequency = 400 * 1000,
+ .sda_delay = 100,
+};
+
+static struct i2c_board_info i2c2_devs[] __initdata = {
+ {
+ I2C_BOARD_INFO("qt602240_ts", 0x4a),
+ .platform_data = &qt602240_platform_data,
+ },
+};
+
+static void __init goni_tsp_init(void)
+{
+ int gpio;
+
+ gpio = S5PV210_GPJ1(3); /* XMSMADDR_11 */
+ gpio_request(gpio, "TSP_LDO_ON");
+ gpio_direction_output(gpio, 1);
+ gpio_export(gpio, 0);
+
+ gpio = S5PV210_GPJ0(5); /* XMSMADDR_5 */
+ gpio_request(gpio, "TSP_INT");
+
+ s5p_register_gpio_interrupt(gpio);
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+ i2c2_devs[0].irq = gpio_to_irq(gpio);
+}
+
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_consumer_supply goni_ldo3_consumers[] = {
+ REGULATOR_SUPPLY("vusb_a", "s3c-hsotg"),
+};
+
+static struct regulator_consumer_supply goni_ldo5_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
+};
+
+static struct regulator_consumer_supply goni_ldo8_consumers[] = {
+ REGULATOR_SUPPLY("vusb_d", "s3c-hsotg"),
+};
+
+static struct regulator_consumer_supply goni_ldo11_consumers[] = {
+ REGULATOR_SUPPLY("vddio", "0-0030"), /* "CAM_IO_2.8V" */
+};
+
+static struct regulator_consumer_supply goni_ldo13_consumers[] = {
+ REGULATOR_SUPPLY("vdda", "0-0030"), /* "CAM_A_2.8V" */
+};
+
+static struct regulator_consumer_supply goni_ldo14_consumers[] = {
+ REGULATOR_SUPPLY("vdd_core", "0-0030"), /* "CAM_CIF_1.8V" */
+};
+
+static struct regulator_init_data goni_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 goni_ldo3_data = {
+ .constraints = {
+ .name = "VUSB+MIPI_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo3_consumers),
+ .consumer_supplies = goni_ldo3_consumers,
+};
+
+static struct regulator_init_data goni_ldo4_data = {
+ .constraints = {
+ .name = "VDAC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo5_data = {
+ .constraints = {
+ .name = "VTF_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo5_consumers),
+ .consumer_supplies = goni_ldo5_consumers,
+};
+
+static struct regulator_init_data goni_ldo6_data = {
+ .constraints = {
+ .name = "VCC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo7_data = {
+ .constraints = {
+ .name = "VLCD_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo8_data = {
+ .constraints = {
+ .name = "VUSB+VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo8_consumers),
+ .consumer_supplies = goni_ldo8_consumers,
+};
+
+static struct regulator_init_data goni_ldo9_data = {
+ .constraints = {
+ .name = "VCC+VCAM_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo10_data = {
+ .constraints = {
+ .name = "VPLL_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo11_data = {
+ .constraints = {
+ .name = "CAM_IO_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo11_consumers),
+ .consumer_supplies = goni_ldo11_consumers,
+};
+
+static struct regulator_init_data goni_ldo12_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo13_data = {
+ .constraints = {
+ .name = "CAM_A_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo13_consumers),
+ .consumer_supplies = goni_ldo13_consumers,
+};
+
+static struct regulator_init_data goni_ldo14_data = {
+ .constraints = {
+ .name = "CAM_CIF_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(goni_ldo14_consumers),
+ .consumer_supplies = goni_ldo14_consumers,
+};
+
+static struct regulator_init_data goni_ldo15_data = {
+ .constraints = {
+ .name = "CAM_AF_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo16_data = {
+ .constraints = {
+ .name = "VMIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo17_data = {
+ .constraints = {
+ .name = "VCC_3.0V_LCD",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer =
+ REGULATOR_SUPPLY("vddarm", NULL);
+
+static struct regulator_consumer_supply buck2_consumer =
+ REGULATOR_SUPPLY("vddint", NULL);
+
+static struct regulator_init_data goni_buck1_data = {
+ .constraints = {
+ .name = "VARM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck1_consumer,
+};
+
+static struct regulator_init_data goni_buck2_data = {
+ .constraints = {
+ .name = "VINT_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &buck2_consumer,
+};
+
+static struct regulator_init_data goni_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data goni_buck4_data = {
+ .constraints = {
+ .name = "CAM_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct max8998_regulator_data goni_regulators[] = {
+ { MAX8998_LDO2, &goni_ldo2_data },
+ { MAX8998_LDO3, &goni_ldo3_data },
+ { MAX8998_LDO4, &goni_ldo4_data },
+ { MAX8998_LDO5, &goni_ldo5_data },
+ { MAX8998_LDO6, &goni_ldo6_data },
+ { MAX8998_LDO7, &goni_ldo7_data },
+ { MAX8998_LDO8, &goni_ldo8_data },
+ { MAX8998_LDO9, &goni_ldo9_data },
+ { MAX8998_LDO10, &goni_ldo10_data },
+ { MAX8998_LDO11, &goni_ldo11_data },
+ { MAX8998_LDO12, &goni_ldo12_data },
+ { MAX8998_LDO13, &goni_ldo13_data },
+ { MAX8998_LDO14, &goni_ldo14_data },
+ { MAX8998_LDO15, &goni_ldo15_data },
+ { MAX8998_LDO16, &goni_ldo16_data },
+ { MAX8998_LDO17, &goni_ldo17_data },
+ { MAX8998_BUCK1, &goni_buck1_data },
+ { MAX8998_BUCK2, &goni_buck2_data },
+ { MAX8998_BUCK3, &goni_buck3_data },
+ { MAX8998_BUCK4, &goni_buck4_data },
+};
+
+static struct max8998_platform_data goni_max8998_pdata = {
+ .num_regulators = ARRAY_SIZE(goni_regulators),
+ .regulators = goni_regulators,
+ .buck1_set1 = S5PV210_GPH0(3),
+ .buck1_set2 = S5PV210_GPH0(4),
+ .buck2_set3 = S5PV210_GPH0(5),
+ .buck1_voltage1 = 1200000,
+ .buck1_voltage2 = 1200000,
+ .buck1_voltage3 = 1200000,
+ .buck1_voltage4 = 1200000,
+ .buck2_voltage1 = 1200000,
+ .buck2_voltage2 = 1200000,
+};
+#endif
+
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+ REGULATOR_SUPPLY("DBVDD", "5-001a"),
+ REGULATOR_SUPPLY("AVDD2", "5-001a"),
+ REGULATOR_SUPPLY("CPVDD", "5-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+ REGULATOR_SUPPLY("SPKVDD1", "5-001a"),
+ REGULATOR_SUPPLY("SPKVDD2", "5-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 fixed_voltage_config wm8994_fixed_voltage0_config = {
+ .supply_name = "VCC_1.8V_PDA",
+ .microvolts = 1800000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+ .supply_name = "V_BAT",
+ .microvolts = 3700000,
+ .gpio = -EINVAL,
+ .init_data = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage0_config,
+ },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+ .name = "reg-fixed-voltage",
+ .id = 1,
+ .dev = {
+ .platform_data = &wm8994_fixed_voltage1_config,
+ },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+ REGULATOR_SUPPLY("AVDD1", "5-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+ REGULATOR_SUPPLY("DCVDD", "5-001a");
+
+static struct regulator_init_data wm8994_ldo1_data = {
+ .constraints = {
+ .name = "AVDD1_3.0V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+ .constraints = {
+ .name = "DCVDD_1.0V",
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+ /* configure gpio1 function: 0x0001(Logic level input/output) */
+ .gpio_defaults[0] = 0x0001,
+ /* configure gpio3/4/5/7 function for AIF2 voice */
+ .gpio_defaults[2] = 0x8100,
+ .gpio_defaults[3] = 0x8100,
+ .gpio_defaults[4] = 0x8100,
+ .gpio_defaults[6] = 0x0100,
+ /* configure gpio8/9/10/11 function for AIF3 BT */
+ .gpio_defaults[7] = 0x8100,
+ .gpio_defaults[8] = 0x0100,
+ .gpio_defaults[9] = 0x0100,
+ .gpio_defaults[10] = 0x0100,
+ .ldo[0] = { S5PV210_MP03(6), NULL, &wm8994_ldo1_data }, /* XM0FRNB_2 */
+ .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+};
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4 4
+static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
+ .sda_pin = S5PV210_GPJ4(0), /* XMSMCSN */
+ .scl_pin = S5PV210_GPJ4(3), /* XMSMIRQN */
+};
+
+static struct platform_device goni_i2c_gpio_pmic = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_PMIC_BUS_4,
+ .dev = {
+ .platform_data = &goni_i2c_gpio_pmic_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+ {
+ /* 0xCC when SRAD = 0 */
+ I2C_BOARD_INFO("max8998", 0xCC >> 1),
+ .platform_data = &goni_max8998_pdata,
+ },
+#endif
+};
+
+/* GPIO I2C AP 1.8V */
+#define AP_I2C_GPIO_BUS_5 5
+static struct i2c_gpio_platform_data goni_i2c_gpio5_data = {
+ .sda_pin = S5PV210_MP05(3), /* XM0ADDR_11 */
+ .scl_pin = S5PV210_MP05(2), /* XM0ADDR_10 */
+};
+
+static struct platform_device goni_i2c_gpio5 = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_BUS_5,
+ .dev = {
+ .platform_data = &goni_i2c_gpio5_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio5_devs[] __initdata = {
+ {
+ /* CS/ADDR = low 0x34 (FYI: high = 0x36) */
+ I2C_BOARD_INFO("wm8994", 0x1a),
+ .platform_data = &wm8994_platform_data,
+ },
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button goni_gpio_keys_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = S5PV210_GPH2(6),
+ .desc = "gpio-keys: KEY_POWER",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data goni_gpio_keys_data = {
+ .buttons = goni_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(goni_gpio_keys_table),
+};
+
+static struct platform_device goni_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &goni_gpio_keys_data,
+ },
+};
+
+static void __init goni_pmic_init(void)
+{
+ /* AP_PMIC_IRQ: EINT7 */
+ s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+ /* nPower: EINT22 */
+ s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
+/* MoviNAND */
+static struct s3c_sdhci_platdata goni_hsmmc0_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_PERMANENT,
+};
+
+/* Wireless LAN */
+static struct s3c_sdhci_platdata goni_hsmmc1_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_EXTERNAL,
+ /* ext_cd_{init,cleanup} callbacks will be added later */
+};
+
+/* External Flash */
+#define GONI_EXT_FLASH_EN S5PV210_MP05(4)
+#define GONI_EXT_FLASH_CD S5PV210_GPH3(4)
+static struct s3c_sdhci_platdata goni_hsmmc2_data __initdata = {
+ .max_width = 4,
+ .cd_type = S3C_SDHCI_CD_GPIO,
+ .ext_cd_gpio = GONI_EXT_FLASH_CD,
+ .ext_cd_gpio_invert = 1,
+};
+
+static struct regulator_consumer_supply mmc2_supplies[] = {
+ REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"),
+};
+
+static struct regulator_init_data mmc2_fixed_voltage_init_data = {
+ .constraints = {
+ .name = "V_TF_2.8V",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(mmc2_supplies),
+ .consumer_supplies = mmc2_supplies,
+};
+
+static struct fixed_voltage_config mmc2_fixed_voltage_config = {
+ .supply_name = "EXT_FLASH_EN",
+ .microvolts = 2800000,
+ .gpio = GONI_EXT_FLASH_EN,
+ .enable_high = true,
+ .init_data = &mmc2_fixed_voltage_init_data,
+};
+
+static struct platform_device mmc2_fixed_voltage = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &mmc2_fixed_voltage_config,
+ },
+};
+
+static void goni_setup_sdhci(void)
+{
+ s3c_sdhci0_set_platdata(&goni_hsmmc0_data);
+ s3c_sdhci1_set_platdata(&goni_hsmmc1_data);
+ s3c_sdhci2_set_platdata(&goni_hsmmc2_data);
+};
+
+static struct platform_device *goni_devices[] __initdata = {
+ &s3c_device_fb,
+ &s5p_device_onenand,
+ &goni_spi_gpio,
+ &goni_i2c_gpio_pmic,
+ &goni_i2c_gpio5,
+ &mmc2_fixed_voltage,
+ &goni_device_gpiokeys,
+ &s3c_device_i2c0,
+ &s5p_device_fimc0,
+ &s5p_device_fimc1,
+ &s5p_device_fimc2,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s5pv210_device_iis0,
+ &s3c_device_usb_hsotg,
+ &samsung_device_keypad,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &wm8994_fixed_voltage0,
+ &wm8994_fixed_voltage1,
+};
+
+static void __init goni_sound_init(void)
+{
+ /* Ths main clock of WM8994 codec uses the output of CLKOUT pin.
+ * The CLKOUT[9:8] set to 0x3(XUSBXTI) of 0xE010E000(OTHERS)
+ * because it needs 24MHz clock to operate WM8994 codec.
+ */
+ __raw_writel(__raw_readl(S5P_OTHERS) | (0x3 << 8), S5P_OTHERS);
+}
+
+static void __init goni_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+}
+
+static void __init goni_machine_init(void)
+{
+ /* Radio: call before I2C 1 registeration */
+ goni_radio_init();
+
+ /* I2C0 */
+ s3c_i2c0_set_platdata(NULL);
+
+ /* I2C1 */
+ s3c_i2c1_set_platdata(NULL);
+ i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+
+ /* TSP: call before I2C 2 registeration */
+ goni_tsp_init();
+
+ /* I2C2 */
+ s3c_i2c2_set_platdata(&i2c2_data);
+ i2c_register_board_info(2, i2c2_devs, ARRAY_SIZE(i2c2_devs));
+
+ /* PMIC */
+ goni_pmic_init();
+ i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+ ARRAY_SIZE(i2c_gpio_pmic_devs));
+ /* SDHCI */
+ goni_setup_sdhci();
+
+ /* SOUND */
+ goni_sound_init();
+ i2c_register_board_info(AP_I2C_GPIO_BUS_5, i2c_gpio5_devs,
+ ARRAY_SIZE(i2c_gpio5_devs));
+
+ /* FB */
+ s3c_fb_set_platdata(&goni_lcd_pdata);
+
+ /* SPI */
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+
+ /* KEYPAD */
+ samsung_keypad_set_platdata(&keypad_data);
+
+ clk_xusbxti.rate = 24000000;
+
+ platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
+}
+
+MACHINE_START(GONI, "GONI")
+ /* Maintainers: Kyungmin Park <kyungmin.park@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = goni_map_io,
+ .init_machine = goni_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
new file mode 100644
index 00000000..6c412c8c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -0,0 +1,144 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkc110.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/i2c.h>
+#include <linux/sysdev.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/ata.h>
+#include <plat/iic.h>
+#include <plat/pm.h>
+#include <plat/s5p-time.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKC110_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKC110_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKC110_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKC110_UCON_DEFAULT,
+ .ulcon = SMDKC110_ULCON_DEFAULT,
+ .ufcon = SMDKC110_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKC110_UCON_DEFAULT,
+ .ulcon = SMDKC110_ULCON_DEFAULT,
+ .ufcon = SMDKC110_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKC110_UCON_DEFAULT,
+ .ulcon = SMDKC110_ULCON_DEFAULT,
+ .ufcon = SMDKC110_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKC110_UCON_DEFAULT,
+ .ulcon = SMDKC110_ULCON_DEFAULT,
+ .ufcon = SMDKC110_UFCON_DEFAULT,
+ },
+};
+
+static struct s3c_ide_platdata smdkc110_ide_pdata __initdata = {
+ .setup_gpio = s5pv210_ide_setup_gpio,
+};
+
+static struct platform_device *smdkc110_devices[] __initdata = {
+ &samsung_asoc_dma,
+ &s5pv210_device_iis0,
+ &s5pv210_device_ac97,
+ &s5pv210_device_spdif,
+ &s3c_device_cfcon,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+};
+
+static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+};
+
+static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info smdkc110_i2c_devs2[] __initdata = {
+ /* To Be Updated */
+};
+
+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);
+}
+
+static void __init smdkc110_machine_init(void)
+{
+ s3c_pm_init();
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(0, smdkc110_i2c_devs0,
+ ARRAY_SIZE(smdkc110_i2c_devs0));
+ i2c_register_board_info(1, smdkc110_i2c_devs1,
+ ARRAY_SIZE(smdkc110_i2c_devs1));
+ i2c_register_board_info(2, smdkc110_i2c_devs2,
+ ARRAY_SIZE(smdkc110_i2c_devs2));
+
+ s3c_ide_set_platdata(&smdkc110_ide_pdata);
+
+ platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
+}
+
+MACHINE_START(SMDKC110, "SMDKC110")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = smdkc110_map_io,
+ .init_machine = smdkc110_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
new file mode 100644
index 00000000..c6a9e86c
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -0,0 +1,354 @@
+/* linux/arch/arm/mach-s5pv210/mach-smdkv210.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/i2c.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/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/regs-clock.h>
+#include <mach/regs-fb.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>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define SMDKV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define SMDKV210_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define SMDKV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = SMDKV210_UCON_DEFAULT,
+ .ulcon = SMDKV210_ULCON_DEFAULT,
+ .ufcon = SMDKV210_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = SMDKV210_UCON_DEFAULT,
+ .ulcon = SMDKV210_ULCON_DEFAULT,
+ .ufcon = SMDKV210_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = SMDKV210_UCON_DEFAULT,
+ .ulcon = SMDKV210_ULCON_DEFAULT,
+ .ufcon = SMDKV210_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = SMDKV210_UCON_DEFAULT,
+ .ulcon = SMDKV210_ULCON_DEFAULT,
+ .ufcon = SMDKV210_UFCON_DEFAULT,
+ },
+};
+
+static struct s3c_ide_platdata smdkv210_ide_pdata __initdata = {
+ .setup_gpio = s5pv210_ide_setup_gpio,
+};
+
+static uint32_t smdkv210_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 smdkv210_keymap_data __initdata = {
+ .keymap = smdkv210_keymap,
+ .keymap_size = ARRAY_SIZE(smdkv210_keymap),
+};
+
+static struct samsung_keypad_platdata smdkv210_keypad_data __initdata = {
+ .keymap_data = &smdkv210_keymap_data,
+ .rows = 8,
+ .cols = 8,
+};
+
+static struct resource smdkv210_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 smdkv210_dm9000_platdata = {
+ .flags = DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM,
+ .dev_addr = { 0x00, 0x09, 0xc0, 0xff, 0xec, 0x48 },
+};
+
+struct platform_device smdkv210_dm9000 = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smdkv210_dm9000_resources),
+ .resource = smdkv210_dm9000_resources,
+ .dev = {
+ .platform_data = &smdkv210_dm9000_platdata,
+ },
+};
+
+static void smdkv210_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 smdkv210_lcd_lte480wv_data = {
+ .set_power = smdkv210_lte480wv_set_power,
+};
+
+static struct platform_device smdkv210_lcd_lte480wv = {
+ .name = "platform-lcd",
+ .dev.parent = &s3c_device_fb.dev,
+ .dev.platform_data = &smdkv210_lcd_lte480wv_data,
+};
+
+static struct s3c_fb_pd_win smdkv210_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 smdkv210_lcd0_pdata __initdata = {
+ .win[0] = &smdkv210_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB,
+ .vidcon1 = VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .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;
+ }
+
+ /* Configure GPIO pin with S5PV210_GPD_0_3_TOUT_3 */
+ s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_SFN(2));
+
+ return 0;
+}
+
+static void smdkv210_backlight_exit(struct device *dev)
+{
+ s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_OUTPUT);
+ gpio_free(S5PV210_GPD0(3));
+}
+
+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 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_devices[] __initdata = {
+ &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,
+ &samsung_asoc_dma,
+ &samsung_device_keypad,
+ &smdkv210_dm9000,
+ &smdkv210_lcd_lte480wv,
+ &s3c_device_timer[3],
+ &smdkv210_backlight_device,
+};
+
+static void __init smdkv210_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 smdkv210_i2c_devs0[] __initdata = {
+ { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */
+ { I2C_BOARD_INFO("wm8580", 0x1b), },
+};
+
+static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info smdkv210_i2c_devs2[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
+static void __init smdkv210_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_PWM2, S5P_PWM4);
+}
+
+static void __init smdkv210_machine_init(void)
+{
+ s3c_pm_init();
+
+ smdkv210_dm9000_init();
+
+ samsung_keypad_set_platdata(&smdkv210_keypad_data);
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(0, smdkv210_i2c_devs0,
+ ARRAY_SIZE(smdkv210_i2c_devs0));
+ i2c_register_board_info(1, smdkv210_i2c_devs1,
+ ARRAY_SIZE(smdkv210_i2c_devs1));
+ i2c_register_board_info(2, smdkv210_i2c_devs2,
+ ARRAY_SIZE(smdkv210_i2c_devs2));
+
+ s3c_ide_set_platdata(&smdkv210_ide_pdata);
+
+ s3c_fb_set_platdata(&smdkv210_lcd0_pdata);
+
+ platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
+}
+
+MACHINE_START(SMDKV210, "SMDKV210")
+ /* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = smdkv210_map_io,
+ .init_machine = smdkv210_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
new file mode 100644
index 00000000..925fc0dc
--- /dev/null
+++ b/arch/arm/mach-s5pv210/mach-torbreck.c
@@ -0,0 +1,133 @@
+/* linux/arch/arm/mach-s5pv210/mach-torbreck.c
+ *
+ * Copyright (c) 2010 aESOP Community
+ * http://www.aesop.or.kr/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/regs-serial.h>
+#include <plat/s5pv210.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/iic.h>
+#include <plat/s5p-time.h>
+
+/* Following are default values for UCON, ULCON and UFCON UART registers */
+#define TORBRECK_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI | \
+ S3C2443_UCON_RXERR_IRQEN)
+
+#define TORBRECK_ULCON_DEFAULT S3C2410_LCON_CS8
+
+#define TORBRECK_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S5PV210_UFCON_TXTRIG4 | \
+ S5PV210_UFCON_RXTRIG4)
+
+static struct s3c2410_uartcfg torbreck_uartcfgs[] __initdata = {
+ [0] = {
+ .hwport = 0,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [1] = {
+ .hwport = 1,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [2] = {
+ .hwport = 2,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+ [3] = {
+ .hwport = 3,
+ .flags = 0,
+ .ucon = TORBRECK_UCON_DEFAULT,
+ .ulcon = TORBRECK_ULCON_DEFAULT,
+ .ufcon = TORBRECK_UFCON_DEFAULT,
+ },
+};
+
+static struct platform_device *torbreck_devices[] __initdata = {
+ &s5pv210_device_iis0,
+ &s3c_device_cfcon,
+ &s3c_device_hsmmc0,
+ &s3c_device_hsmmc1,
+ &s3c_device_hsmmc2,
+ &s3c_device_hsmmc3,
+ &s3c_device_i2c0,
+ &s3c_device_i2c1,
+ &s3c_device_i2c2,
+ &s3c_device_rtc,
+ &s3c_device_wdt,
+};
+
+static struct i2c_board_info torbreck_i2c_devs0[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs1[] __initdata = {
+ /* To Be Updated */
+};
+
+static struct i2c_board_info torbreck_i2c_devs2[] __initdata = {
+ /* To Be Updated */
+};
+
+static void __init torbreck_map_io(void)
+{
+ s5p_init_io(NULL, 0, S5P_VA_CHIPID);
+ s3c24xx_init_clocks(24000000);
+ s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
+ s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+}
+
+static void __init torbreck_machine_init(void)
+{
+ s3c_i2c0_set_platdata(NULL);
+ s3c_i2c1_set_platdata(NULL);
+ s3c_i2c2_set_platdata(NULL);
+ i2c_register_board_info(0, torbreck_i2c_devs0,
+ ARRAY_SIZE(torbreck_i2c_devs0));
+ i2c_register_board_info(1, torbreck_i2c_devs1,
+ ARRAY_SIZE(torbreck_i2c_devs1));
+ i2c_register_board_info(2, torbreck_i2c_devs2,
+ ARRAY_SIZE(torbreck_i2c_devs2));
+
+ platform_add_devices(torbreck_devices, ARRAY_SIZE(torbreck_devices));
+}
+
+MACHINE_START(TORBRECK, "TORBRECK")
+ /* Maintainer: Hyunchul Ko <ghcstop@gmail.com> */
+ .boot_params = S5P_PA_SDRAM + 0x100,
+ .init_irq = s5pv210_init_irq,
+ .map_io = torbreck_map_io,
+ .init_machine = torbreck_machine_init,
+ .timer = &s5p_timer,
+MACHINE_END
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c
new file mode 100644
index 00000000..24febae3
--- /dev/null
+++ b/arch/arm/mach-s5pv210/pm.c
@@ -0,0 +1,175 @@
+/* linux/arch/arm/mach-s5pv210/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 - Power Management support
+ *
+ * Based on arch/arm/mach-s3c2410/pm.c
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/regs-timer.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-clock.h>
+
+static struct sleep_save s5pv210_core_save[] = {
+ /* Clock source */
+ SAVE_ITEM(S5P_CLK_SRC0),
+ SAVE_ITEM(S5P_CLK_SRC1),
+ SAVE_ITEM(S5P_CLK_SRC2),
+ SAVE_ITEM(S5P_CLK_SRC3),
+ SAVE_ITEM(S5P_CLK_SRC4),
+ SAVE_ITEM(S5P_CLK_SRC5),
+ SAVE_ITEM(S5P_CLK_SRC6),
+
+ /* Clock source Mask */
+ SAVE_ITEM(S5P_CLK_SRC_MASK0),
+ SAVE_ITEM(S5P_CLK_SRC_MASK1),
+
+ /* Clock Divider */
+ SAVE_ITEM(S5P_CLK_DIV0),
+ SAVE_ITEM(S5P_CLK_DIV1),
+ SAVE_ITEM(S5P_CLK_DIV2),
+ SAVE_ITEM(S5P_CLK_DIV3),
+ SAVE_ITEM(S5P_CLK_DIV4),
+ SAVE_ITEM(S5P_CLK_DIV5),
+ SAVE_ITEM(S5P_CLK_DIV6),
+ SAVE_ITEM(S5P_CLK_DIV7),
+
+ /* Clock Main Gate */
+ SAVE_ITEM(S5P_CLKGATE_MAIN0),
+ SAVE_ITEM(S5P_CLKGATE_MAIN1),
+ SAVE_ITEM(S5P_CLKGATE_MAIN2),
+
+ /* Clock source Peri Gate */
+ SAVE_ITEM(S5P_CLKGATE_PERI0),
+ SAVE_ITEM(S5P_CLKGATE_PERI1),
+
+ /* Clock source SCLK Gate */
+ SAVE_ITEM(S5P_CLKGATE_SCLK0),
+ SAVE_ITEM(S5P_CLKGATE_SCLK1),
+
+ /* Clock IP Clock gate */
+ SAVE_ITEM(S5P_CLKGATE_IP0),
+ SAVE_ITEM(S5P_CLKGATE_IP1),
+ SAVE_ITEM(S5P_CLKGATE_IP2),
+ SAVE_ITEM(S5P_CLKGATE_IP3),
+ SAVE_ITEM(S5P_CLKGATE_IP4),
+
+ /* Clock Blcok and Bus gate */
+ SAVE_ITEM(S5P_CLKGATE_BLOCK),
+ SAVE_ITEM(S5P_CLKGATE_BUS0),
+
+ /* Clock ETC */
+ SAVE_ITEM(S5P_CLK_OUT),
+ SAVE_ITEM(S5P_MDNIE_SEL),
+
+ /* PWM Register */
+ SAVE_ITEM(S3C2410_TCFG0),
+ SAVE_ITEM(S3C2410_TCFG1),
+ SAVE_ITEM(S3C64XX_TINT_CSTAT),
+ SAVE_ITEM(S3C2410_TCON),
+ SAVE_ITEM(S3C2410_TCNTB(0)),
+ SAVE_ITEM(S3C2410_TCMPB(0)),
+ SAVE_ITEM(S3C2410_TCNTO(0)),
+};
+
+void s5pv210_cpu_suspend(void)
+{
+ unsigned long tmp;
+
+ /* issue the standby signal into the pm unit. Note, we
+ * issue a write-buffer drain just in case */
+
+ tmp = 0;
+
+ asm("b 1f\n\t"
+ ".align 5\n\t"
+ "1:\n\t"
+ "mcr p15, 0, %0, c7, c10, 5\n\t"
+ "mcr p15, 0, %0, c7, c10, 4\n\t"
+ "wfi" : : "r" (tmp));
+
+ /* we should never get past here */
+ panic("sleep resumed to originator?");
+}
+
+static void s5pv210_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* ensure at least INFORM0 has the resume address */
+ __raw_writel(virt_to_phys(s3c_cpu_resume), S5P_INFORM0);
+
+ tmp = __raw_readl(S5P_SLEEP_CFG);
+ tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
+ __raw_writel(tmp, S5P_SLEEP_CFG);
+
+ /* WFI for SLEEP mode configuration by SYSCON */
+ tmp = __raw_readl(S5P_PWR_CFG);
+ tmp &= S5P_CFG_WFI_CLEAN;
+ tmp |= S5P_CFG_WFI_SLEEP;
+ __raw_writel(tmp, S5P_PWR_CFG);
+
+ /* SYSCON interrupt handling disable */
+ tmp = __raw_readl(S5P_OTHERS);
+ tmp |= S5P_OTHER_SYSC_INTOFF;
+ __raw_writel(tmp, S5P_OTHERS);
+
+ s3c_pm_do_save(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+}
+
+static int s5pv210_pm_add(struct sys_device *sysdev)
+{
+ pm_cpu_prep = s5pv210_pm_prepare;
+ pm_cpu_sleep = s5pv210_cpu_suspend;
+
+ return 0;
+}
+
+static struct sysdev_driver s5pv210_pm_driver = {
+ .add = s5pv210_pm_add,
+};
+
+static __init int s5pv210_pm_drvinit(void)
+{
+ return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+}
+arch_initcall(s5pv210_pm_drvinit);
+
+static void s5pv210_pm_resume(void)
+{
+ u32 tmp;
+
+ tmp = __raw_readl(S5P_OTHERS);
+ tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
+ S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
+ __raw_writel(tmp , S5P_OTHERS);
+
+ s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
+}
+
+static struct syscore_ops s5pv210_pm_syscore_ops = {
+ .resume = s5pv210_pm_resume,
+};
+
+static __init int s5pv210_pm_syscore_init(void)
+{
+ register_syscore_ops(&s5pv210_pm_syscore_ops);
+ return 0;
+}
+arch_initcall(s5pv210_pm_syscore_init);
diff --git a/arch/arm/mach-s5pv210/setup-fb-24bpp.c b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
new file mode 100644
index 00000000..e932ebfa
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fb-24bpp.c
@@ -0,0 +1,50 @@
+/* linux/arch/arm/plat-s5pv210/setup-fb-24bpp.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base s5pv210 setup information for 24bpp LCD framebuffer
+ *
+ * This program is free software; you can 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 <mach/regs-fb.h>
+#include <mach/map.h>
+#include <plat/fb.h>
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+
+static void s5pv210_fb_cfg_gpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(2));
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
+
+void s5pv210_fb_gpio_setup_24bpp(void)
+{
+ s5pv210_fb_cfg_gpios(S5PV210_GPF0(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF1(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF2(0), 8);
+ s5pv210_fb_cfg_gpios(S5PV210_GPF3(0), 4);
+
+ /* Set DISPLAY_CONTROL register for Display path selection.
+ *
+ * ouput | RGB | I80 | ITU
+ * -----------------------------------
+ * 00 | MIE | FIMD | FIMD
+ * 01 | MDNIE | MDNIE | FIMD
+ * 10 | FIMD | FIMD | FIMD
+ * 11 | FIMD | FIMD | FIMD
+ */
+ writel(0x2, S5P_MDNIE_SEL);
+}
diff --git a/arch/arm/mach-s5pv210/setup-fimc.c b/arch/arm/mach-s5pv210/setup-fimc.c
new file mode 100644
index 00000000..54cc5b11
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-fimc.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5PV210 camera interface 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/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/camport.h>
+
+int s5pv210_fimc_setup_gpio(enum s5p_camport_id id)
+{
+ u32 gpio8, gpio5;
+ int ret;
+
+ switch (id) {
+ case S5P_CAMPORT_A:
+ gpio8 = S5PV210_GPE0(0);
+ gpio5 = S5PV210_GPE1(0);
+ break;
+
+ case S5P_CAMPORT_B:
+ gpio8 = S5PV210_GPJ0(0);
+ gpio5 = S5PV210_GPJ1(0);
+ break;
+
+ default:
+ WARN(1, "Wrong camport id: %d\n", id);
+ return -EINVAL;
+ }
+
+ ret = s3c_gpio_cfgall_range(gpio8, 8, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_UP);
+ if (ret)
+ return ret;
+
+ return s3c_gpio_cfgall_range(gpio5, 5, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv210/setup-i2c0.c b/arch/arm/mach-s5pv210/setup-i2c0.c
new file mode 100644
index 00000000..0f1cc3a1
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-i2c0.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c0.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * I2C0 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV210_GPD1(0), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv210/setup-i2c1.c b/arch/arm/mach-s5pv210/setup-i2c1.c
new file mode 100644
index 00000000..f61365a3
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-i2c1.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c1.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * I2C1 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c1.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c1_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV210_GPD1(2), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv210/setup-i2c2.c b/arch/arm/mach-s5pv210/setup-i2c2.c
new file mode 100644
index 00000000..2f91b5ce
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-i2c2.c
@@ -0,0 +1,28 @@
+/* linux/arch/arm/mach-s5pv210/setup-i2c2.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * I2C2 GPIO configuration.
+ *
+ * Based on plat-s3c64xx/setup-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <plat/iic.h>
+#include <plat/gpio-cfg.h>
+
+void s3c_i2c2_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgall_range(S5PV210_GPD1(4), 2,
+ S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+}
diff --git a/arch/arm/mach-s5pv210/setup-ide.c b/arch/arm/mach-s5pv210/setup-ide.c
new file mode 100644
index 00000000..ea123d54
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-ide.c
@@ -0,0 +1,39 @@
+/* linux/arch/arm/mach-s5pv210/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+
+#include <plat/gpio-cfg.h>
+
+static void s5pv210_ide_cfg_gpios(unsigned int base, unsigned int nr)
+{
+ s3c_gpio_cfgrange_nopull(base, nr, S3C_GPIO_SFN(4));
+
+ for (; nr > 0; nr--, base++)
+ s5p_gpio_set_drvstr(base, S5P_GPIO_DRVSTR_LV4);
+}
+
+void s5pv210_ide_setup_gpio(void)
+{
+ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ0(0), 8);
+
+ /* CF_Data[0 - 7] */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ2(0), 8);
+
+ /* CF_Data[8 - 15] */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ3(0), 8);
+
+ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+ s5pv210_ide_cfg_gpios(S5PV210_GPJ4(0), 4);
+}
diff --git a/arch/arm/mach-s5pv210/setup-keypad.c b/arch/arm/mach-s5pv210/setup-keypad.c
new file mode 100644
index 00000000..c56420a5
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-keypad.c
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/arm/mach-s5pv210/setup-keypad.c
+ *
+ * Copyright (C) 2010 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/gpio.h>
+#include <plat/gpio-cfg.h>
+
+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));
+
+ /* 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/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
new file mode 100644
index 00000000..3e3ac05b
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -0,0 +1,104 @@
+/* linux/arch/arm/plat-s5pc1xx/setup-sdhci-gpio.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - 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 s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG0/GPG1 pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG0(0), 2, S3C_GPIO_SFN(2));
+
+ switch (width) {
+ case 8:
+ /* GPG1[3:6] special-function 3 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(3));
+ case 4:
+ /* GPG0[3:6] special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG0(3), 4, S3C_GPIO_SFN(2));
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+ }
+}
+
+void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG1[0:1] pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(0), 2, S3C_GPIO_SFN(2));
+
+ /* Data pin GPG1[3:6] to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG1(3), 4, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+ }
+}
+
+void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG2[0:1] pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG2(0), 2, S3C_GPIO_SFN(2));
+
+ switch (width) {
+ case 8:
+ /* Data pin GPG3[3:6] to special-function 3 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(3));
+ case 4:
+ /* Data pin GPG2[3:6] to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG2(3), 4, S3C_GPIO_SFN(2));
+ default:
+ break;
+ }
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+ }
+}
+
+void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width)
+{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
+
+ /* Set all the necessary GPG3[0:1] pins to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(0), 2, S3C_GPIO_SFN(2));
+
+ /* Data pin GPG3[3:6] to special-function 2 */
+ s3c_gpio_cfgrange_nopull(S5PV210_GPG3(3), 4, S3C_GPIO_SFN(2));
+
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG3(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG3(2), S3C_GPIO_SFN(2));
+ }
+}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci.c b/arch/arm/mach-s5pv210/setup-sdhci.c
new file mode 100644
index 00000000..a83b6c90
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-sdhci.c
@@ -0,0 +1,63 @@
+/* linux/arch/arm/mach-s5pv210/setup-sdhci.c
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5PV210 - Helper functions for settign up SDHCI device(s) (HSMMC)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+
+#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
+
+/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */
+
+char *s5pv210_hsmmc_clksrcs[4] = {
+ [0] = "hsmmc", /* HCLK */
+ /* [1] = "hsmmc", - duplicate HCLK entry */
+ [2] = "sclk_mmc", /* mmc_bus */
+ /* [3] = NULL, - reserved */
+};
+
+void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card)
+{
+ u32 ctrl2, ctrl3;
+
+ /* don't need to alter anything according to card-type */
+
+ writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4);
+
+ ctrl2 = readl(r + S3C_SDHCI_CONTROL2);
+ ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK;
+ ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR |
+ S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK |
+ S3C_SDHCI_CTRL2_ENFBCLKRX |
+ S3C_SDHCI_CTRL2_DFCNT_NONE |
+ S3C_SDHCI_CTRL2_ENCLKOUTHOLD);
+
+ if (ios->clock < 25 * 1000000)
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 |
+ S3C_SDHCI_CTRL3_FCSEL2 |
+ S3C_SDHCI_CTRL3_FCSEL1 |
+ S3C_SDHCI_CTRL3_FCSEL0);
+ else
+ ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0);
+
+ writel(ctrl2, r + S3C_SDHCI_CONTROL2);
+ writel(ctrl3, r + S3C_SDHCI_CONTROL3);
+}
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
new file mode 100644
index 00000000..a3d64946
--- /dev/null
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -0,0 +1,73 @@
+/* linux/arch/arm/plat-s5p/sleep.S
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 power Manager (Suspend-To-RAM) support
+ * Based on S3C2410 sleep code by:
+ * Ben Dooks, (c) 2004 Simtec Electronics
+ *
+ * Based on PXA/SA1100 sleep code by:
+ * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
+ * Cliff Brake, (c) 2001
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(s3c_cpu_save)
+
+ stmfd sp!, { r3 - r12, lr }
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ ldr r0, =pm_cpu_sleep
+ ldr r0, [ r0 ]
+ mov pc, r0
+
+resume_with_mmu:
+ 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
+
+ /* 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)
+ b cpu_resume
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
new file mode 100644
index 00000000..42625e4d
--- /dev/null
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -0,0 +1,170 @@
+if ARCH_SA1100
+
+menu "SA11x0 Implementations"
+
+config SA1100_ASSABET
+ bool "Assabet"
+ select CPU_FREQ_SA1110
+ help
+ Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
+ Microprocessor Development Board (also known as the Assabet).
+
+config ASSABET_NEPONSET
+ bool "Include support for Neponset"
+ depends on SA1100_ASSABET
+ select SA1111
+ help
+ Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
+ Microprocessor Development Board (Assabet) with the SA-1111
+ Development Board (Nepon).
+
+config SA1100_CERF
+ bool "CerfBoard"
+ select CPU_FREQ_SA1110
+ help
+ The Intrinsyc CerfBoard is based on the StrongARM 1110 (Discontinued).
+ More information is available at:
+ <http://www.intrinsyc.com/products/cerfboard/>.
+
+ Say Y if configuring for an Intrinsyc CerfBoard.
+ Say N otherwise.
+
+choice
+ prompt "Cerf Flash available"
+ depends on SA1100_CERF
+ default SA1100_CERF_FLASH_8MB
+
+config SA1100_CERF_FLASH_8MB
+ bool "8MB"
+
+config SA1100_CERF_FLASH_16MB
+ bool "16MB"
+
+config SA1100_CERF_FLASH_32MB
+ bool "32MB"
+
+endchoice
+
+config SA1100_COLLIE
+ bool "Sharp Zaurus SL5500"
+ # FIXME: select CPU_FREQ_SA11x0
+ select SHARP_LOCOMO
+ select SHARP_SCOOP
+ select SHARP_PARAM
+ help
+ Say Y here to support the Sharp Zaurus SL5500 PDAs.
+
+config SA1100_H3100
+ bool "Compaq iPAQ H3100"
+ select HTC_EGPIO
+ select CPU_FREQ_SA1110
+ help
+ Say Y here if you intend to run this kernel on the Compaq iPAQ
+ H3100 handheld computer. Information about this machine and the
+ Linux port to this machine can be found at:
+
+ <http://www.handhelds.org/Compaq/index.html#iPAQ_H3100>
+
+config SA1100_H3600
+ bool "Compaq iPAQ H3600/H3700"
+ select HTC_EGPIO
+ select CPU_FREQ_SA1110
+ help
+ Say Y here if you intend to run this kernel on the Compaq iPAQ
+ H3600 handheld computer. Information about this machine and the
+ Linux port to this machine can be found at:
+
+ <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
+
+config SA1100_BADGE4
+ bool "HP Labs BadgePAD 4"
+ select SA1111
+ select CPU_FREQ_SA1100
+ help
+ Say Y here if you want to build a kernel for the HP Laboratories
+ BadgePAD 4.
+
+config SA1100_JORNADA720
+ bool "HP Jornada 720"
+ select SA1111
+ # FIXME: select CPU_FREQ_SA11x0
+ help
+ Say Y here if you want to build a kernel for the HP Jornada 720
+ handheld computer. See
+ <http://h10025.www1.hp.com/ewfrf/wc/product?product=61677&cc=us&lc=en&dlc=en&product=61677#>
+
+config SA1100_JORNADA720_SSP
+ bool "HP Jornada 720 Extended SSP driver"
+ select SA1100_SSP
+ depends on SA1100_JORNADA720
+ help
+ Say Y here if you have a HP Jornada 7xx handheld computer and you
+ want to access devices connected to the MCU. Those include the
+ keyboard, touchscreen, backlight and battery. This driver also activates
+ the generic SSP which it extends.
+
+config SA1100_HACKKIT
+ bool "HackKit Core CPU Board"
+ select CPU_FREQ_SA1100
+ help
+ Say Y here to support the HackKit Core CPU Board
+ <http://hackkit.eletztrick.de>;
+
+config SA1100_LART
+ bool "LART"
+ select CPU_FREQ_SA1100
+ help
+ Say Y here if you are using the Linux Advanced Radio Terminal
+ (also known as the LART). See <http://www.lartmaker.nl/> for
+ information on the LART.
+
+config SA1100_NANOENGINE
+ bool "nanoEngine"
+ select CPU_FREQ_SA1110
+ select PCI
+ select PCI_NANOENGINE
+ help
+ Say Y here if you are using the Bright Star Engineering nanoEngine.
+ See <http://www.brightstareng.com/arm/nanoeng.htm> for information
+ on the BSE nanoEngine.
+
+config SA1100_PLEB
+ bool "PLEB"
+ select CPU_FREQ_SA1100
+ help
+ Say Y here if you are using version 1 of the Portable Linux
+ Embedded Board (also known as PLEB).
+ See <http://www.disy.cse.unsw.edu.au/Hardware/PLEB/>
+ for more information.
+
+config SA1100_SHANNON
+ bool "Shannon"
+ select CPU_FREQ_SA1100
+ help
+ The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
+ limited edition webphone produced by Philips. The Shannon is a SA1100
+ platform with a 640x480 LCD, touchscreen, CIR keyboard, PCMCIA slots,
+ and a telco interface.
+
+config SA1100_SIMPAD
+ bool "Simpad"
+ select CPU_FREQ_SA1110
+ help
+ The SIEMENS webpad SIMpad is based on the StrongARM 1110. There
+ are two different versions CL4 and SL4. CL4 has 32MB RAM and 16MB
+ FLASH. The SL4 version got 64 MB RAM and 32 MB FLASH and a
+ PCMCIA-Slot. The version for the Germany Telecom (DTAG) is the same
+ like CL4 in additional it has a PCMCIA-Slot. For more information
+ visit <http://www.usa.siemens.com/> or <http://www.siemens.ch/>.
+
+config SA1100_SSP
+ tristate "Generic PIO SSP"
+ help
+ Say Y here to enable support for the generic PIO SSP driver.
+ This isn't for audio support, but for attached sensors and
+ other devices, eg for BadgePAD 4 sensor support.
+
+endmenu
+
+endif
+
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
new file mode 100644
index 00000000..41252d22
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile
@@ -0,0 +1,56 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o generic.o gpio.o irq.o dma.o time.o #nmi-oopser.o
+obj-m :=
+obj-n :=
+obj- :=
+led-y := leds.o
+
+obj-$(CONFIG_CPU_FREQ_SA1100) += cpu-sa1100.o
+obj-$(CONFIG_CPU_FREQ_SA1110) += cpu-sa1110.o
+
+# Specific board support
+obj-$(CONFIG_SA1100_ASSABET) += assabet.o
+led-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
+obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
+
+obj-$(CONFIG_SA1100_BADGE4) += badge4.o
+led-$(CONFIG_SA1100_BADGE4) += leds-badge4.o
+
+obj-$(CONFIG_SA1100_CERF) += cerf.o
+led-$(CONFIG_SA1100_CERF) += leds-cerf.o
+
+obj-$(CONFIG_SA1100_COLLIE) += collie.o
+
+obj-$(CONFIG_SA1100_H3100) += h3100.o h3xxx.o
+obj-$(CONFIG_SA1100_H3600) += h3600.o h3xxx.o
+
+obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
+led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
+
+obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
+obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
+
+obj-$(CONFIG_SA1100_LART) += lart.o
+led-$(CONFIG_SA1100_LART) += leds-lart.o
+
+obj-$(CONFIG_SA1100_NANOENGINE) += nanoengine.o
+obj-$(CONFIG_PCI_NANOENGINE) += pci-nanoengine.o
+
+obj-$(CONFIG_SA1100_PLEB) += pleb.o
+
+obj-$(CONFIG_SA1100_SHANNON) += shannon.o
+
+obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
+led-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o
+
+# LEDs support
+obj-$(CONFIG_LEDS) += $(led-y)
+
+# Miscellaneous functions
+obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_SA1100_SSP) += ssp.o
+
diff --git a/arch/arm/mach-sa1100/Makefile.boot b/arch/arm/mach-sa1100/Makefile.boot
new file mode 100644
index 00000000..a56ad041
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile.boot
@@ -0,0 +1,7 @@
+ zreladdr-y := 0xc0008000
+ifeq ($(CONFIG_ARCH_SA1100),y)
+ zreladdr-$(CONFIG_SA1111) := 0xc0208000
+endif
+params_phys-y := 0xc0000100
+initrd_phys-y := 0xc0800000
+
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
new file mode 100644
index 00000000..5778274a
--- /dev/null
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -0,0 +1,456 @@
+/*
+ * linux/arch/arm/mach-sa1100/assabet.c
+ *
+ * Author: Nicolas Pitre
+ *
+ * This file contains all Assabet-specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/irda.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/assabet.h>
+#include <mach/mcp.h>
+
+#include "generic.h"
+
+#define ASSABET_BCR_DB1110 \
+ (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \
+ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
+ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
+ ASSABET_BCR_IRDA_MD0)
+
+#define ASSABET_BCR_DB1111 \
+ (ASSABET_BCR_SPK_OFF | ASSABET_BCR_QMUTE | \
+ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
+ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
+ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
+ ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST)
+
+unsigned long SCR_value = ASSABET_SCR_INIT;
+EXPORT_SYMBOL(SCR_value);
+
+static unsigned long BCR_value = ASSABET_BCR_DB1110;
+
+void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ BCR_value = (BCR_value & ~mask) | val;
+ ASSABET_BCR = BCR_value;
+ local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(ASSABET_BCR_frob);
+
+static void assabet_backlight_power(int on)
+{
+#ifndef ASSABET_PAL_VIDEO
+ if (on)
+ ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
+ else
+#endif
+ ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+/*
+ * Turn on/off the backlight. When turning the backlight on,
+ * we wait 500us after turning it on so we don't cause the
+ * supplies to droop when we enable the LCD controller (and
+ * cause a hard reset.)
+ */
+static void assabet_lcd_power(int on)
+{
+#ifndef ASSABET_PAL_VIDEO
+ if (on) {
+ ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
+ udelay(500);
+ } else
+#endif
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+
+/*
+ * Assabet flash support code.
+ */
+
+#ifdef ASSABET_REV_4
+/*
+ * Phase 4 Assabet has two 28F160B3 flash parts in bank 0:
+ */
+static struct mtd_partition assabet_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "bootloader params",
+ .size = 0x00020000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "jffs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+#else
+/*
+ * Phase 5 Assabet has two 28F128J3A flash parts in bank 0:
+ */
+static struct mtd_partition assabet_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "bootloader params",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "jffs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+#endif
+
+static struct flash_platform_data assabet_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = assabet_partitions,
+ .nr_parts = ARRAY_SIZE(assabet_partitions),
+};
+
+static struct resource assabet_flash_resources[] = {
+ {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SA1100_CS1_PHYS,
+ .end = SA1100_CS1_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+
+/*
+ * Assabet IrDA support code.
+ */
+
+static int assabet_irda_set_power(struct device *dev, unsigned int state)
+{
+ static unsigned int bcr_state[4] = {
+ ASSABET_BCR_IRDA_MD0,
+ ASSABET_BCR_IRDA_MD1|ASSABET_BCR_IRDA_MD0,
+ ASSABET_BCR_IRDA_MD1,
+ 0
+ };
+
+ if (state < 4) {
+ state = bcr_state[state];
+ ASSABET_BCR_clear(state ^ (ASSABET_BCR_IRDA_MD1|
+ ASSABET_BCR_IRDA_MD0));
+ ASSABET_BCR_set(state);
+ }
+ return 0;
+}
+
+static void assabet_irda_set_speed(struct device *dev, unsigned int speed)
+{
+ if (speed < 4000000)
+ ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
+ else
+ ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
+}
+
+static struct irda_platform_data assabet_irda_data = {
+ .set_power = assabet_irda_set_power,
+ .set_speed = assabet_irda_set_speed,
+};
+
+static struct mcp_plat_data assabet_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+static void __init assabet_init(void)
+{
+ /*
+ * Ensure that the power supply is in "high power" mode.
+ */
+ GPDR |= GPIO_GPIO16;
+ GPSR = GPIO_GPIO16;
+
+ /*
+ * Ensure that these pins are set as outputs and are driving
+ * logic 0. This ensures that we won't inadvertently toggle
+ * the WS latch in the CPLD, and we don't float causing
+ * excessive power drain. --rmk
+ */
+ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+ GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+ /*
+ * Set up registers for sleep mode.
+ */
+ PWER = PWER_GPIO0;
+ PGSR = 0;
+ PCFR = 0;
+ PSDR = 0;
+ PPDR |= PPC_TXD3 | PPC_TXD1;
+ PPSR |= PPC_TXD3 | PPC_TXD1;
+
+ sa1100fb_lcd_power = assabet_lcd_power;
+ sa1100fb_backlight_power = assabet_backlight_power;
+
+ if (machine_has_neponset()) {
+ /*
+ * Angel sets this, but other bootloaders may not.
+ *
+ * This must precede any driver calls to BCR_set()
+ * or BCR_clear().
+ */
+ ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111;
+
+#ifndef CONFIG_ASSABET_NEPONSET
+ printk( "Warning: Neponset detected but full support "
+ "hasn't been configured in the kernel\n" );
+#endif
+ }
+
+ sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
+ ARRAY_SIZE(assabet_flash_resources));
+ sa11x0_register_irda(&assabet_irda_data);
+ sa11x0_register_mcp(&assabet_mcp_data);
+}
+
+/*
+ * On Assabet, we must probe for the Neponset board _before_
+ * paging_init() has occurred to actually determine the amount
+ * of RAM available. To do so, we map the appropriate IO section
+ * in the page table here in order to access GPIO registers.
+ */
+static void __init map_sa1100_gpio_regs( void )
+{
+ unsigned long phys = __PREG(GPLR) & PMD_MASK;
+ unsigned long virt = io_p2v(phys);
+ int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
+ pmd_t *pmd;
+
+ pmd = pmd_offset(pgd_offset_k(virt), virt);
+ *pmd = __pmd(phys | prot);
+ flush_pmd_entry(pmd);
+}
+
+/*
+ * Read System Configuration "Register"
+ * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
+ * User's Guide", section 4.4.1)
+ *
+ * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S
+ * to set up the serial port for decompression status messages. We
+ * repeat it here because the kernel may not be loaded as a zImage, and
+ * also because it's a hassle to communicate the SCR value to the kernel
+ * from the decompressor.
+ *
+ * Note that IRQs are guaranteed to be disabled.
+ */
+static void __init get_assabet_scr(void)
+{
+ unsigned long scr, i;
+
+ GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
+ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
+ GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
+ for(i = 100; i--; ) /* Read GPIO 9:2 */
+ scr = GPLR;
+ GPDR |= 0x3fc; /* restore correct pin direction */
+ scr &= 0x3fc; /* save as system configuration byte. */
+ SCR_value = scr;
+}
+
+static void __init
+fixup_assabet(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ /* This must be done before any call to machine_has_neponset() */
+ map_sa1100_gpio_regs();
+ get_assabet_scr();
+
+ if (machine_has_neponset())
+ printk("Neponset expansion board detected\n");
+}
+
+
+static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == _Ser1UTCR0) {
+ if (state)
+ ASSABET_BCR_clear(ASSABET_BCR_RS232EN |
+ ASSABET_BCR_COM_RTS |
+ ASSABET_BCR_COM_DTR);
+ else
+ ASSABET_BCR_set(ASSABET_BCR_RS232EN |
+ ASSABET_BCR_COM_RTS |
+ ASSABET_BCR_COM_DTR);
+ }
+}
+
+/*
+ * Assabet uses COM_RTS and COM_DTR for both UART1 (com port)
+ * and UART3 (radio module). We only handle them for UART1 here.
+ */
+static void assabet_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (port->mapbase == _Ser1UTCR0) {
+ u_int set = 0, clear = 0;
+
+ if (mctrl & TIOCM_RTS)
+ clear |= ASSABET_BCR_COM_RTS;
+ else
+ set |= ASSABET_BCR_COM_RTS;
+
+ if (mctrl & TIOCM_DTR)
+ clear |= ASSABET_BCR_COM_DTR;
+ else
+ set |= ASSABET_BCR_COM_DTR;
+
+ ASSABET_BCR_clear(clear);
+ ASSABET_BCR_set(set);
+ }
+}
+
+static u_int assabet_get_mctrl(struct uart_port *port)
+{
+ u_int ret = 0;
+ u_int bsr = ASSABET_BSR;
+
+ /* need 2 reads to read current value */
+ bsr = ASSABET_BSR;
+
+ if (port->mapbase == _Ser1UTCR0) {
+ if (bsr & ASSABET_BSR_COM_DCD)
+ ret |= TIOCM_CD;
+ if (bsr & ASSABET_BSR_COM_CTS)
+ ret |= TIOCM_CTS;
+ if (bsr & ASSABET_BSR_COM_DSR)
+ ret |= TIOCM_DSR;
+ } else if (port->mapbase == _Ser3UTCR0) {
+ if (bsr & ASSABET_BSR_RAD_DCD)
+ ret |= TIOCM_CD;
+ if (bsr & ASSABET_BSR_RAD_CTS)
+ ret |= TIOCM_CTS;
+ if (bsr & ASSABET_BSR_RAD_DSR)
+ ret |= TIOCM_DSR;
+ if (bsr & ASSABET_BSR_RAD_RI)
+ ret |= TIOCM_RI;
+ } else {
+ ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+ }
+
+ return ret;
+}
+
+static struct sa1100_port_fns assabet_port_fns __initdata = {
+ .set_mctrl = assabet_set_mctrl,
+ .get_mctrl = assabet_get_mctrl,
+ .pm = assabet_uart_pm,
+};
+
+static struct map_desc assabet_io_desc[] __initdata = {
+ { /* Board Control Register */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x12000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init assabet_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc));
+
+ /*
+ * Set SUS bit in SDCR0 so serial port 1 functions.
+ * Its called GPCLKR0 in my SA1110 manual.
+ */
+ Ser1SDCR0 |= SDCR0_SUS;
+
+ if (machine_has_neponset()) {
+#ifdef CONFIG_ASSABET_NEPONSET
+ extern void neponset_map_io(void);
+
+ /*
+ * We map Neponset registers even if it isn't present since
+ * many drivers will try to probe their stuff (and fail).
+ * This is still more friendly than a kernel paging request
+ * crash.
+ */
+ neponset_map_io();
+#endif
+ } else {
+ sa1100_register_uart_fns(&assabet_port_fns);
+ }
+
+ /*
+ * When Neponset is attached, the first UART should be
+ * UART3. That's what Angel is doing and many documents
+ * are stating this.
+ *
+ * We do the Neponset mapping even if Neponset support
+ * isn't compiled in so the user will still get something on
+ * the expected physical serial port.
+ *
+ * We no longer do this; not all boot loaders support it,
+ * and UART3 appears to be somewhat unreliable with blob.
+ */
+ sa1100_register_uart(0, 1);
+ sa1100_register_uart(2, 3);
+}
+
+
+MACHINE_START(ASSABET, "Intel-Assabet")
+ .boot_params = 0xc0000100,
+ .fixup = fixup_assabet,
+ .map_io = assabet_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = assabet_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c
new file mode 100644
index 00000000..4f19ff86
--- /dev/null
+++ b/arch/arm/mach-sa1100/badge4.c
@@ -0,0 +1,309 @@
+/*
+ * linux/arch/arm/mach-sa1100/badge4.c
+ *
+ * BadgePAD 4 specific initialization
+ *
+ * Tim Connors <connors@hpl.hp.com>
+ * Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/errno.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <mach/irqs.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/badge4.h>
+
+#include "generic.h"
+
+static struct resource sa1111_resources[] = {
+ [0] = {
+ .start = BADGE4_SA1111_BASE,
+ .end = BADGE4_SA1111_BASE + 0x00001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = BADGE4_IRQ_GPIO_SA1111,
+ .end = BADGE4_IRQ_GPIO_SA1111,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+ .name = "sa1111",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sa1111_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
+ },
+ .num_resources = ARRAY_SIZE(sa1111_resources),
+ .resource = sa1111_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+};
+
+static int __init badge4_sa1111_init(void)
+{
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state
+ */
+ sa1110_mb_disable();
+
+ /*
+ * Probe for SA1111.
+ */
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+
+/*
+ * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit)
+ * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
+ * Sixty-three 32 KiW Main Blocks (4032 Ki b)
+ *
+ * <or>
+ *
+ * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit)
+ * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
+ * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b)
+ */
+static struct mtd_partition badge4_partitions[] = {
+ {
+ .name = "BLOB boot loader",
+ .offset = 0,
+ .size = 0x0000A000
+ }, {
+ .name = "params",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00006000
+ }, {
+ .name = "root",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ }
+};
+
+static struct flash_platform_data badge4_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = badge4_partitions,
+ .nr_parts = ARRAY_SIZE(badge4_partitions),
+};
+
+static struct resource badge4_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static int five_v_on __initdata = 0;
+
+static int __init five_v_on_setup(char *ignore)
+{
+ five_v_on = 1;
+ return 1;
+}
+__setup("five_v_on", five_v_on_setup);
+
+
+static int __init badge4_init(void)
+{
+ int ret;
+
+ if (!machine_is_badge4())
+ return -ENODEV;
+
+ /* LCD */
+ GPCR = (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+ BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 |
+ BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 |
+ BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+ BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
+ BADGE4_GPIO_GPC_VID);
+ GPDR &= ~BADGE4_GPIO_INT_VID;
+ GPDR |= (BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+ BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 |
+ BADGE4_GPIO_LGP6 | BADGE4_GPIO_LGP7 |
+ BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+ BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
+ BADGE4_GPIO_GPC_VID);
+
+ /* SDRAM SPD i2c */
+ GPCR = (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL);
+ GPDR |= (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL);
+
+ /* uart */
+ GPCR = (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
+ GPDR |= (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
+
+ /* CPLD muxsel0 input for mux/adc chip select */
+ GPCR = BADGE4_GPIO_MUXSEL0;
+ GPDR |= BADGE4_GPIO_MUXSEL0;
+
+ /* test points: J5, J6 as inputs, J7 outputs */
+ GPDR &= ~(BADGE4_GPIO_TESTPT_J5 | BADGE4_GPIO_TESTPT_J6);
+ GPCR = BADGE4_GPIO_TESTPT_J7;
+ GPDR |= BADGE4_GPIO_TESTPT_J7;
+
+ /* 5V supply rail. */
+ GPCR = BADGE4_GPIO_PCMEN5V; /* initially off */
+ GPDR |= BADGE4_GPIO_PCMEN5V;
+
+ /* CPLD sdram type inputs; set up by blob */
+ //GPDR |= (BADGE4_GPIO_SDTYP1 | BADGE4_GPIO_SDTYP0);
+ printk(KERN_DEBUG __FILE__ ": SDRAM CPLD typ1=%d typ0=%d\n",
+ !!(GPLR & BADGE4_GPIO_SDTYP1),
+ !!(GPLR & BADGE4_GPIO_SDTYP0));
+
+ /* SA1111 reset pin; set up by blob */
+ //GPSR = BADGE4_GPIO_SA1111_NRST;
+ //GPDR |= BADGE4_GPIO_SA1111_NRST;
+
+
+ /* power management cruft */
+ PGSR = 0;
+ PWER = 0;
+ PCFR = 0;
+ PSDR = 0;
+
+ PWER |= PWER_GPIO26; /* wake up on an edge from TESTPT_J5 */
+ PWER |= PWER_RTC; /* wake up if rtc fires */
+
+ /* drive sa1111_nrst during sleep */
+ PGSR |= BADGE4_GPIO_SA1111_NRST;
+ /* drive CPLD as is during sleep */
+ PGSR |= (GPLR & (BADGE4_GPIO_SDTYP0|BADGE4_GPIO_SDTYP1));
+
+
+ /* Now bring up the SA-1111. */
+ ret = badge4_sa1111_init();
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: SA-1111 initialization failed (%d)\n",
+ __func__, ret);
+
+
+ /* maybe turn on 5v0 from the start */
+ badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on);
+
+ sa11x0_register_mtd(&badge4_flash_data, &badge4_flash_resource, 1);
+
+ return 0;
+}
+
+arch_initcall(badge4_init);
+
+
+static unsigned badge4_5V_bitmap = 0;
+
+void badge4_set_5V(unsigned subsystem, int on)
+{
+ unsigned long flags;
+ unsigned old_5V_bitmap;
+
+ local_irq_save(flags);
+
+ old_5V_bitmap = badge4_5V_bitmap;
+
+ if (on) {
+ badge4_5V_bitmap |= subsystem;
+ } else {
+ badge4_5V_bitmap &= ~subsystem;
+ }
+
+ /* detect on->off and off->on transitions */
+ if ((!old_5V_bitmap) && (badge4_5V_bitmap)) {
+ /* was off, now on */
+ printk(KERN_INFO "%s: enabling 5V supply rail\n", __func__);
+ GPSR = BADGE4_GPIO_PCMEN5V;
+ } else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) {
+ /* was on, now off */
+ printk(KERN_INFO "%s: disabling 5V supply rail\n", __func__);
+ GPCR = BADGE4_GPIO_PCMEN5V;
+ }
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(badge4_set_5V);
+
+
+static struct map_desc badge4_io_desc[] __initdata = {
+ { /* SRAM bank 1 */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SRAM bank 2 */
+ .virtual = 0xf2000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x48000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
+};
+
+static void
+badge4_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (!state) {
+ Ser1SDCR0 |= SDCR0_UART;
+ }
+}
+
+static struct sa1100_port_fns badge4_port_fns __initdata = {
+ //.get_mctrl = badge4_get_mctrl,
+ //.set_mctrl = badge4_set_mctrl,
+ .pm = badge4_uart_pm,
+};
+
+static void __init badge4_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(badge4_io_desc, ARRAY_SIZE(badge4_io_desc));
+
+ sa1100_register_uart_fns(&badge4_port_fns);
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+}
+
+MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
+ .boot_params = 0xc0000100,
+ .map_io = badge4_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
new file mode 100644
index 00000000..7f3da4b1
--- /dev/null
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/arm/mach-sa1100/cerf.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.
+ *
+ * Apr-2003 : Removed some old PDA crud [FB]
+ * Oct-2003 : Added uart2 resource [FB]
+ * Jan-2004 : Removed io map for flash [FB]
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/cerf.h>
+#include <mach/mcp.h>
+#include "generic.h"
+
+static struct resource cerfuart2_resources[] = {
+ [0] = {
+ .start = 0x80030000,
+ .end = 0x8003ffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device cerfuart2_device = {
+ .name = "sa11x0-uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(cerfuart2_resources),
+ .resource = cerfuart2_resources,
+};
+
+static struct platform_device *cerf_devices[] __initdata = {
+ &cerfuart2_device,
+};
+
+#ifdef CONFIG_SA1100_CERF_FLASH_32MB
+# define CERF_FLASH_SIZE 0x02000000
+#elif defined CONFIG_SA1100_CERF_FLASH_16MB
+# define CERF_FLASH_SIZE 0x01000000
+#elif defined CONFIG_SA1100_CERF_FLASH_8MB
+# define CERF_FLASH_SIZE 0x00800000
+#else
+# error "Undefined flash size for CERF"
+#endif
+
+static struct mtd_partition cerf_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 0x00020000,
+ .offset = 0x00000000,
+ }, {
+ .name = "Params",
+ .size = 0x00040000,
+ .offset = 0x00020000,
+ }, {
+ .name = "Kernel",
+ .size = 0x00100000,
+ .offset = 0x00060000,
+ }, {
+ .name = "Filesystem",
+ .size = CERF_FLASH_SIZE-0x00160000,
+ .offset = 0x00160000,
+ }
+};
+
+static struct flash_platform_data cerf_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = cerf_partitions,
+ .nr_parts = ARRAY_SIZE(cerf_partitions),
+};
+
+static struct resource cerf_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __init cerf_init_irq(void)
+{
+ sa1100_init_irq();
+ irq_set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING);
+}
+
+static struct map_desc cerf_io_desc[] __initdata = {
+ { /* Crystal Ethernet Chip */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init cerf_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(cerf_io_desc, ARRAY_SIZE(cerf_io_desc));
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 2); /* disable this and the uart2 device for sa1100_fir */
+ sa1100_register_uart(2, 1);
+
+ /* set some GPDR bits here while it's safe */
+ GPDR |= CERF_GPIO_CF_RESET;
+}
+
+static struct mcp_plat_data cerf_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+static void __init cerf_init(void)
+{
+ platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
+ sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
+ sa11x0_register_mcp(&cerf_mcp_data);
+}
+
+MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
+ /* Maintainer: support@intrinsyc.com */
+ .map_io = cerf_map_io,
+ .init_irq = cerf_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = cerf_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
new file mode 100644
index 00000000..dab3c634
--- /dev/null
+++ b/arch/arm/mach-sa1100/clock.c
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/mach-sa1100/clock.c
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+
+#include <mach/hardware.h>
+
+/*
+ * Very simple clock implementation - we only have one clock to deal with.
+ */
+struct clk {
+ unsigned int enabled;
+};
+
+static void clk_gpio27_enable(void)
+{
+ /*
+ * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+ * (SA-1110 Developer's Manual, section 9.1.2.1)
+ */
+ GAFR |= GPIO_32_768kHz;
+ GPDR |= GPIO_32_768kHz;
+ TUCR = TUCR_3_6864MHz;
+}
+
+static void clk_gpio27_disable(void)
+{
+ TUCR = 0;
+ GPDR &= ~GPIO_32_768kHz;
+ GAFR &= ~GPIO_32_768kHz;
+}
+
+static struct clk clk_gpio27;
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ const char *devname = dev_name(dev);
+
+ return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ clk_gpio27_enable();
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ clk_gpio27_disable();
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return 3686400;
+}
+EXPORT_SYMBOL(clk_get_rate);
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
new file mode 100644
index 00000000..bd3e1bfd
--- /dev/null
+++ b/arch/arm/mach-sa1100/collie.c
@@ -0,0 +1,389 @@
+/*
+ * linux/arch/arm/mach-sa1100/collie.c
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains all Collie-specific tweaks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ChangeLog:
+ * 2006 Pavel Machek <pavel@ucw.cz>
+ * 03-06-2004 John Lenz <lenz@cs.wisc.edu>
+ * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
+ * 04-16-2001 Lineo Japan,Inc. ...
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/timer.h>
+#include <linux/gpio.h>
+#include <linux/pda_power.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <mach/collie.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/locomo.h>
+#include <mach/mcp.h>
+
+#include "generic.h"
+
+static struct resource collie_scoop_resources[] = {
+ [0] = {
+ .start = 0x40800000,
+ .end = 0x40800fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct scoop_config collie_scoop_setup = {
+ .io_dir = COLLIE_SCOOP_IO_DIR,
+ .io_out = COLLIE_SCOOP_IO_OUT,
+ .gpio_base = COLLIE_SCOOP_GPIO_BASE,
+};
+
+struct platform_device colliescoop_device = {
+ .name = "sharp-scoop",
+ .id = -1,
+ .dev = {
+ .platform_data = &collie_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(collie_scoop_resources),
+ .resource = collie_scoop_resources,
+};
+
+static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = {
+ {
+ .dev = &colliescoop_device.dev,
+ .irq = COLLIE_IRQ_GPIO_CF_IRQ,
+ .cd_irq = COLLIE_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+ },
+};
+
+static struct scoop_pcmcia_config collie_pcmcia_config = {
+ .devs = &collie_pcmcia_scoop[0],
+ .num_devs = 1,
+};
+
+static struct mcp_plat_data collie_mcp_data = {
+ .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
+ .sclk_rate = 9216000,
+ .gpio_base = COLLIE_TC35143_GPIO_BASE,
+};
+
+/*
+ * Collie AC IN
+ */
+static int collie_power_init(struct device *dev)
+{
+ int ret = gpio_request(COLLIE_GPIO_AC_IN, "ac in");
+ if (ret)
+ goto err_gpio_req;
+
+ ret = gpio_direction_input(COLLIE_GPIO_AC_IN);
+ if (ret)
+ goto err_gpio_in;
+
+ return 0;
+
+err_gpio_in:
+ gpio_free(COLLIE_GPIO_AC_IN);
+err_gpio_req:
+ return ret;
+}
+
+static void collie_power_exit(struct device *dev)
+{
+ gpio_free(COLLIE_GPIO_AC_IN);
+}
+
+static int collie_power_ac_online(void)
+{
+ return gpio_get_value(COLLIE_GPIO_AC_IN) == 2;
+}
+
+static char *collie_ac_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+};
+
+static struct pda_power_pdata collie_power_data = {
+ .init = collie_power_init,
+ .is_ac_online = collie_power_ac_online,
+ .exit = collie_power_exit,
+ .supplied_to = collie_ac_supplied_to,
+ .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
+};
+
+static struct resource collie_power_resource[] = {
+ {
+ .name = "ac",
+ .start = gpio_to_irq(COLLIE_GPIO_AC_IN),
+ .end = gpio_to_irq(COLLIE_GPIO_AC_IN),
+ .flags = IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE |
+ IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device collie_power_device = {
+ .name = "pda-power",
+ .id = -1,
+ .dev.platform_data = &collie_power_data,
+ .resource = collie_power_resource,
+ .num_resources = ARRAY_SIZE(collie_power_resource),
+};
+
+#ifdef CONFIG_SHARP_LOCOMO
+/*
+ * low-level UART features.
+ */
+struct platform_device collie_locomo_device;
+
+static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (mctrl & TIOCM_RTS)
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
+ else
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
+
+ if (mctrl & TIOCM_DTR)
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
+ else
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+}
+
+static u_int collie_uart_get_mctrl(struct uart_port *port)
+{
+ int ret = TIOCM_CD;
+ unsigned int r;
+
+ r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
+ if (r == -ENODEV)
+ return ret;
+ if (r & LOCOMO_GPIO_CTS)
+ ret |= TIOCM_CTS;
+ if (r & LOCOMO_GPIO_DSR)
+ ret |= TIOCM_DSR;
+
+ return ret;
+}
+
+static struct sa1100_port_fns collie_port_fns __initdata = {
+ .set_mctrl = collie_uart_set_mctrl,
+ .get_mctrl = collie_uart_get_mctrl,
+};
+
+static int collie_uart_probe(struct locomo_dev *dev)
+{
+ return 0;
+}
+
+static int collie_uart_remove(struct locomo_dev *dev)
+{
+ return 0;
+}
+
+static struct locomo_driver collie_uart_driver = {
+ .drv = {
+ .name = "collie_uart",
+ },
+ .devid = LOCOMO_DEVID_UART,
+ .probe = collie_uart_probe,
+ .remove = collie_uart_remove,
+};
+
+static int __init collie_uart_init(void)
+{
+ return locomo_driver_register(&collie_uart_driver);
+}
+device_initcall(collie_uart_init);
+
+#endif
+
+
+static struct resource locomo_resources[] = {
+ [0] = {
+ .start = 0x40000000,
+ .end = 0x40001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO25,
+ .end = IRQ_GPIO25,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct locomo_platform_data locomo_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+struct platform_device collie_locomo_device = {
+ .name = "locomo",
+ .id = 0,
+ .dev = {
+ .platform_data = &locomo_info,
+ },
+ .num_resources = ARRAY_SIZE(locomo_resources),
+ .resource = locomo_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &collie_locomo_device,
+ &colliescoop_device,
+ &collie_power_device,
+};
+
+static struct mtd_partition collie_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x000C0000,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00100000,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00e20000,
+ }
+};
+
+static int collie_flash_init(void)
+{
+ int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
+ if (rc)
+ return rc;
+
+ rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
+ if (rc)
+ gpio_free(COLLIE_GPIO_VPEN);
+
+ return rc;
+}
+
+static void collie_set_vpp(int vpp)
+{
+ gpio_set_value(COLLIE_GPIO_VPEN, vpp);
+}
+
+static void collie_flash_exit(void)
+{
+ gpio_free(COLLIE_GPIO_VPEN);
+}
+
+static struct flash_platform_data collie_flash_data = {
+ .map_name = "cfi_probe",
+ .init = collie_flash_init,
+ .set_vpp = collie_set_vpp,
+ .exit = collie_flash_exit,
+ .parts = collie_partitions,
+ .nr_parts = ARRAY_SIZE(collie_partitions),
+};
+
+static struct resource collie_flash_resources[] = {
+ {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static void __init collie_init(void)
+{
+ int ret = 0;
+
+ /* cpu initialize */
+ GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
+ GPIO_MCP_CLK | GPIO_32_768kHz;
+
+ GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
+ GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
+ GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
+ _COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
+ _COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
+
+ PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
+ PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
+ PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+
+ PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY |
+ _COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
+
+ PGSR = _COLLIE_GPIO_nREMOCON_ON;
+
+ PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
+
+ PCFR = PCFR_OPDE;
+
+ GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
+
+
+ platform_scoop_config = &collie_pcmcia_config;
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret) {
+ printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
+ }
+
+ sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
+ ARRAY_SIZE(collie_flash_resources));
+ sa11x0_register_mcp(&collie_mcp_data);
+
+ sharpsl_save_param();
+}
+
+static struct map_desc collie_io_desc[] __initdata = {
+ { /* 32M main flash (cs0) */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* 32M boot flash (cs1) */
+ .virtual = 0xea000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init collie_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
+
+#ifdef CONFIG_SHARP_LOCOMO
+ sa1100_register_uart_fns(&collie_port_fns);
+#endif
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+}
+
+MACHINE_START(COLLIE, "Sharp-Collie")
+ .map_io = collie_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = collie_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
new file mode 100644
index 00000000..aaa8acf7
--- /dev/null
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -0,0 +1,248 @@
+/*
+ * cpu-sa1100.c: clock scaling for the SA1100
+ *
+ * Copyright (C) 2000 2001, The Delft University of Technology
+ *
+ * Authors:
+ * - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
+ * - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ * - major rewrite for linux-2.3.99
+ * - rewritten for the more generic power management scheme in
+ * linux-2.4.5-rmk1
+ *
+ * This software has been developed while working on the LART
+ * computing board (http://www.lartmaker.nl/), which is
+ * sponsored by the Mobile Multi-media Communications
+ * (http://www.mobimedia.org/) and Ubiquitous Communications
+ * (http://www.ubicom.tudelft.nl/) projects.
+ *
+ * The authors can be reached at:
+ *
+ * Erik Mouw
+ * Information and Communication Theory Group
+ * Faculty of Information Technology and Systems
+ * Delft University of Technology
+ * P.O. Box 5031
+ * 2600 GA Delft
+ * The Netherlands
+ *
+ *
+ * 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
+ *
+ *
+ * Theory of operations
+ * ====================
+ *
+ * Clock scaling can be used to lower the power consumption of the CPU
+ * core. This will give you a somewhat longer running time.
+ *
+ * The SA-1100 has a single register to change the core clock speed:
+ *
+ * PPCR 0x90020014 PLL config
+ *
+ * However, the DRAM timings are closely related to the core clock
+ * speed, so we need to change these, too. The used registers are:
+ *
+ * MDCNFG 0xA0000000 DRAM config
+ * MDCAS0 0xA0000004 Access waveform
+ * MDCAS1 0xA0000008 Access waveform
+ * MDCAS2 0xA000000C Access waveform
+ *
+ * Care must be taken to change the DRAM parameters the correct way,
+ * because otherwise the DRAM becomes unusable and the kernel will
+ * crash.
+ *
+ * The simple solution to avoid a kernel crash is to put the actual
+ * clock change in ROM and jump to that code from the kernel. The main
+ * disadvantage is that the ROM has to be modified, which is not
+ * possible on all SA-1100 platforms. Another disadvantage is that
+ * jumping to ROM makes clock switching unnecessary complicated.
+ *
+ * The idea behind this driver is that the memory configuration can be
+ * changed while running from DRAM (even with interrupts turned on!)
+ * as long as all re-configuration steps yield a valid DRAM
+ * configuration. The advantages are clear: it will run on all SA-1100
+ * platforms, and the code is very simple.
+ *
+ * If you really want to understand what is going on in
+ * sa1100_update_dram_timings(), you'll have to read sections 8.2,
+ * 9.5.7.3, and 10.2 from the "Intel StrongARM SA-1100 Microprocessor
+ * Developers Manual" (available for free from Intel).
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/cputype.h>
+
+#include <mach/hardware.h>
+
+#include "generic.h"
+
+struct sa1100_dram_regs {
+ int speed;
+ u32 mdcnfg;
+ u32 mdcas0;
+ u32 mdcas1;
+ u32 mdcas2;
+};
+
+
+static struct cpufreq_driver sa1100_driver;
+
+static struct sa1100_dram_regs sa1100_dram_settings[] = {
+ /*speed, mdcnfg, mdcas0, mdcas1, mdcas2, clock freq */
+ { 59000, 0x00dc88a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 59.0 MHz */
+ { 73700, 0x011490a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 73.7 MHz */
+ { 88500, 0x014e90a3, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 88.5 MHz */
+ {103200, 0x01889923, 0xcccccccf, 0xfffffffc, 0xffffffff},/* 103.2 MHz */
+ {118000, 0x01c29923, 0x9999998f, 0xfffffff9, 0xffffffff},/* 118.0 MHz */
+ {132700, 0x01fb2123, 0x9999998f, 0xfffffff9, 0xffffffff},/* 132.7 MHz */
+ {147500, 0x02352123, 0x3333330f, 0xfffffff3, 0xffffffff},/* 147.5 MHz */
+ {162200, 0x026b29a3, 0x38e38e1f, 0xfff8e38e, 0xffffffff},/* 162.2 MHz */
+ {176900, 0x02a329a3, 0x71c71c1f, 0xfff1c71c, 0xffffffff},/* 176.9 MHz */
+ {191700, 0x02dd31a3, 0xe38e383f, 0xffe38e38, 0xffffffff},/* 191.7 MHz */
+ {206400, 0x03153223, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 206.4 MHz */
+ {221200, 0x034fba23, 0xc71c703f, 0xffc71c71, 0xffffffff},/* 221.2 MHz */
+ {235900, 0x03853a23, 0xe1e1e07f, 0xe1e1e1e1, 0xffffffe1},/* 235.9 MHz */
+ {250700, 0x03bf3aa3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 250.7 MHz */
+ {265400, 0x03f7c2a3, 0xc3c3c07f, 0xc3c3c3c3, 0xffffffc3},/* 265.4 MHz */
+ {280200, 0x0431c2a3, 0x878780ff, 0x87878787, 0xffffff87},/* 280.2 MHz */
+ { 0, 0, 0, 0, 0 } /* last entry */
+};
+
+static void sa1100_update_dram_timings(int current_speed, int new_speed)
+{
+ struct sa1100_dram_regs *settings = sa1100_dram_settings;
+
+ /* find speed */
+ while (settings->speed != 0) {
+ if (new_speed == settings->speed)
+ break;
+
+ settings++;
+ }
+
+ if (settings->speed == 0) {
+ panic("%s: couldn't find dram setting for speed %d\n",
+ __func__, new_speed);
+ }
+
+ /* No risk, no fun: run with interrupts on! */
+ if (new_speed > current_speed) {
+ /* We're going FASTER, so first relax the memory
+ * timings before changing the core frequency
+ */
+
+ /* Half the memory access clock */
+ MDCNFG |= MDCNFG_CDB2;
+
+ /* The order of these statements IS important, keep 8
+ * pulses!!
+ */
+ MDCAS2 = settings->mdcas2;
+ MDCAS1 = settings->mdcas1;
+ MDCAS0 = settings->mdcas0;
+ MDCNFG = settings->mdcnfg;
+ } else {
+ /* We're going SLOWER: first decrease the core
+ * frequency and then tighten the memory settings.
+ */
+
+ /* Half the memory access clock */
+ MDCNFG |= MDCNFG_CDB2;
+
+ /* The order of these statements IS important, keep 8
+ * pulses!!
+ */
+ MDCAS0 = settings->mdcas0;
+ MDCAS1 = settings->mdcas1;
+ MDCAS2 = settings->mdcas2;
+ MDCNFG = settings->mdcnfg;
+ }
+}
+
+static int sa1100_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ unsigned int cur = sa11x0_getspeed(0);
+ unsigned int new_ppcr;
+ struct cpufreq_freqs freqs;
+
+ new_ppcr = sa11x0_freq_to_ppcr(target_freq);
+ switch (relation) {
+ case CPUFREQ_RELATION_L:
+ if (sa11x0_ppcr_to_freq(new_ppcr) > policy->max)
+ new_ppcr--;
+ break;
+ case CPUFREQ_RELATION_H:
+ if ((sa11x0_ppcr_to_freq(new_ppcr) > target_freq) &&
+ (sa11x0_ppcr_to_freq(new_ppcr - 1) >= policy->min))
+ new_ppcr--;
+ break;
+ }
+
+ freqs.old = cur;
+ freqs.new = sa11x0_ppcr_to_freq(new_ppcr);
+ freqs.cpu = 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ if (freqs.new > cur)
+ sa1100_update_dram_timings(cur, freqs.new);
+
+ PPCR = new_ppcr;
+
+ if (freqs.new < cur)
+ sa1100_update_dram_timings(cur, freqs.new);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+ policy->cur = policy->min = policy->max = sa11x0_getspeed(0);
+ policy->cpuinfo.min_freq = 59000;
+ policy->cpuinfo.max_freq = 287000;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ return 0;
+}
+
+static struct cpufreq_driver sa1100_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = sa11x0_verify_speed,
+ .target = sa1100_target,
+ .get = sa11x0_getspeed,
+ .init = sa1100_cpu_init,
+ .name = "sa1100",
+};
+
+static int __init sa1100_dram_init(void)
+{
+ if (cpu_is_sa1100())
+ return cpufreq_register_driver(&sa1100_driver);
+ else
+ return -ENODEV;
+}
+
+arch_initcall(sa1100_dram_init);
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
new file mode 100644
index 00000000..675bf8ef
--- /dev/null
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -0,0 +1,407 @@
+/*
+ * linux/arch/arm/mach-sa1100/cpu-sa1110.c
+ *
+ * Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Note: there are two erratas that apply to the SA1110 here:
+ * 7 - SDRAM auto-power-up failure (rev A0)
+ * 13 - Corruption of internal register reads/writes following
+ * SDRAM reads (rev A0, B0, B1)
+ *
+ * We ignore rev. A0 and B0 devices; I don't think they're worth supporting.
+ *
+ * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
+ */
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+
+#include <asm/cputype.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+
+#include "generic.h"
+
+#undef DEBUG
+
+struct sdram_params {
+ const char name[20];
+ u_char rows; /* bits */
+ u_char cas_latency; /* cycles */
+ u_char tck; /* clock cycle time (ns) */
+ u_char trcd; /* activate to r/w (ns) */
+ u_char trp; /* precharge to activate (ns) */
+ u_char twr; /* write recovery time (ns) */
+ u_short refresh; /* refresh time for array (us) */
+};
+
+struct sdram_info {
+ u_int mdcnfg;
+ u_int mdrefr;
+ u_int mdcas[3];
+};
+
+static struct sdram_params sdram_tbl[] __initdata = {
+ { /* Toshiba TC59SM716 CL2 */
+ .name = "TC59SM716-CL2",
+ .rows = 12,
+ .tck = 10,
+ .trcd = 20,
+ .trp = 20,
+ .twr = 10,
+ .refresh = 64000,
+ .cas_latency = 2,
+ }, { /* Toshiba TC59SM716 CL3 */
+ .name = "TC59SM716-CL3",
+ .rows = 12,
+ .tck = 8,
+ .trcd = 20,
+ .trp = 20,
+ .twr = 8,
+ .refresh = 64000,
+ .cas_latency = 3,
+ }, { /* Samsung K4S641632D TC75 */
+ .name = "K4S641632D",
+ .rows = 14,
+ .tck = 9,
+ .trcd = 27,
+ .trp = 20,
+ .twr = 9,
+ .refresh = 64000,
+ .cas_latency = 3,
+ }, { /* Samsung K4S281632B-1H */
+ .name = "K4S281632B-1H",
+ .rows = 12,
+ .tck = 10,
+ .trp = 20,
+ .twr = 10,
+ .refresh = 64000,
+ .cas_latency = 3,
+ }, { /* Samsung KM416S4030CT */
+ .name = "KM416S4030CT",
+ .rows = 13,
+ .tck = 8,
+ .trcd = 24, /* 3 CLKs */
+ .trp = 24, /* 3 CLKs */
+ .twr = 16, /* Trdl: 2 CLKs */
+ .refresh = 64000,
+ .cas_latency = 3,
+ }, { /* Winbond W982516AH75L CL3 */
+ .name = "W982516AH75L",
+ .rows = 16,
+ .tck = 8,
+ .trcd = 20,
+ .trp = 20,
+ .twr = 8,
+ .refresh = 64000,
+ .cas_latency = 3,
+ }, { /* Micron MT48LC8M16A2TG-75 */
+ .name = "MT48LC8M16A2TG-75",
+ .rows = 12,
+ .tck = 8,
+ .trcd = 20,
+ .trp = 20,
+ .twr = 8,
+ .refresh = 64000,
+ .cas_latency = 3,
+ },
+};
+
+static struct sdram_params sdram_params;
+
+/*
+ * Given a period in ns and frequency in khz, calculate the number of
+ * cycles of frequency in period. Note that we round up to the next
+ * cycle, even if we are only slightly over.
+ */
+static inline u_int ns_to_cycles(u_int ns, u_int khz)
+{
+ return (ns * khz + 999999) / 1000000;
+}
+
+/*
+ * Create the MDCAS register bit pattern.
+ */
+static inline void set_mdcas(u_int *mdcas, int delayed, u_int rcd)
+{
+ u_int shift;
+
+ rcd = 2 * rcd - 1;
+ shift = delayed + 1 + rcd;
+
+ mdcas[0] = (1 << rcd) - 1;
+ mdcas[0] |= 0x55555555 << shift;
+ mdcas[1] = mdcas[2] = 0x55555555 << (shift & 1);
+}
+
+static void
+sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
+ struct sdram_params *sdram)
+{
+ u_int mem_khz, sd_khz, trp, twr;
+
+ mem_khz = cpu_khz / 2;
+ sd_khz = mem_khz;
+
+ /*
+ * If SDCLK would invalidate the SDRAM timings,
+ * run SDCLK at half speed.
+ *
+ * CPU steppings prior to B2 must either run the memory at
+ * half speed or use delayed read latching (errata 13).
+ */
+ if ((ns_to_cycles(sdram->tck, sd_khz) > 1) ||
+ (CPU_REVISION < CPU_SA1110_B2 && sd_khz < 62000))
+ sd_khz /= 2;
+
+ sd->mdcnfg = MDCNFG & 0x007f007f;
+
+ twr = ns_to_cycles(sdram->twr, mem_khz);
+
+ /* trp should always be >1 */
+ trp = ns_to_cycles(sdram->trp, mem_khz) - 1;
+ if (trp < 1)
+ trp = 1;
+
+ sd->mdcnfg |= trp << 8;
+ sd->mdcnfg |= trp << 24;
+ sd->mdcnfg |= sdram->cas_latency << 12;
+ sd->mdcnfg |= sdram->cas_latency << 28;
+ sd->mdcnfg |= twr << 14;
+ sd->mdcnfg |= twr << 30;
+
+ sd->mdrefr = MDREFR & 0xffbffff0;
+ sd->mdrefr |= 7;
+
+ if (sd_khz != mem_khz)
+ sd->mdrefr |= MDREFR_K1DB2;
+
+ /* initial number of '1's in MDCAS + 1 */
+ set_mdcas(sd->mdcas, sd_khz >= 62000,
+ ns_to_cycles(sdram->trcd, mem_khz));
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
+ sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
+ sd->mdcas[2]);
+#endif
+}
+
+/*
+ * Set the SDRAM refresh rate.
+ */
+static inline void sdram_set_refresh(u_int dri)
+{
+ MDREFR = (MDREFR & 0xffff000f) | (dri << 4);
+ (void) MDREFR;
+}
+
+/*
+ * Update the refresh period. We do this such that we always refresh
+ * the SDRAMs within their permissible period. The refresh period is
+ * always a multiple of the memory clock (fixed at cpu_clock / 2).
+ *
+ * FIXME: we don't currently take account of burst accesses here,
+ * but neither do Intels DM nor Angel.
+ */
+static void
+sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
+{
+ u_int ns_row = (sdram->refresh * 1000) >> sdram->rows;
+ u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32;
+
+#ifdef DEBUG
+ mdelay(250);
+ printk(KERN_DEBUG "new dri value = %d\n", dri);
+#endif
+
+ sdram_set_refresh(dri);
+}
+
+/*
+ * Ok, set the CPU frequency.
+ */
+static int sa1110_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct sdram_params *sdram = &sdram_params;
+ struct cpufreq_freqs freqs;
+ struct sdram_info sd;
+ unsigned long flags;
+ unsigned int ppcr, unused;
+
+ switch (relation) {
+ case CPUFREQ_RELATION_L:
+ ppcr = sa11x0_freq_to_ppcr(target_freq);
+ if (sa11x0_ppcr_to_freq(ppcr) > policy->max)
+ ppcr--;
+ break;
+ case CPUFREQ_RELATION_H:
+ ppcr = sa11x0_freq_to_ppcr(target_freq);
+ if (ppcr && (sa11x0_ppcr_to_freq(ppcr) > target_freq) &&
+ (sa11x0_ppcr_to_freq(ppcr-1) >= policy->min))
+ ppcr--;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ freqs.old = sa11x0_getspeed(0);
+ freqs.new = sa11x0_ppcr_to_freq(ppcr);
+ freqs.cpu = 0;
+
+ sdram_calculate_timing(&sd, freqs.new, sdram);
+
+#if 0
+ /*
+ * These values are wrong according to the SA1110 documentation
+ * and errata, but they seem to work. Need to get a storage
+ * scope on to the SDRAM signals to work out why.
+ */
+ if (policy->max < 147500) {
+ sd.mdrefr |= MDREFR_K1DB2;
+ sd.mdcas[0] = 0xaaaaaa7f;
+ } else {
+ sd.mdrefr &= ~MDREFR_K1DB2;
+ sd.mdcas[0] = 0xaaaaaa9f;
+ }
+ sd.mdcas[1] = 0xaaaaaaaa;
+ sd.mdcas[2] = 0xaaaaaaaa;
+#endif
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ /*
+ * The clock could be going away for some time. Set the SDRAMs
+ * to refresh rapidly (every 64 memory clock cycles). To get
+ * through the whole array, we need to wait 262144 mclk cycles.
+ * We wait 20ms to be safe.
+ */
+ sdram_set_refresh(2);
+ if (!irqs_disabled())
+ msleep(20);
+ else
+ mdelay(20);
+
+ /*
+ * Reprogram the DRAM timings with interrupts disabled, and
+ * ensure that we are doing this within a complete cache line.
+ * This means that we won't access SDRAM for the duration of
+ * the programming.
+ */
+ local_irq_save(flags);
+ asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+ udelay(10);
+ __asm__ __volatile__("\n\
+ b 2f \n\
+ .align 5 \n\
+1: str %3, [%1, #0] @ MDCNFG \n\
+ str %4, [%1, #28] @ MDREFR \n\
+ str %5, [%1, #4] @ MDCAS0 \n\
+ str %6, [%1, #8] @ MDCAS1 \n\
+ str %7, [%1, #12] @ MDCAS2 \n\
+ str %8, [%2, #0] @ PPCR \n\
+ ldr %0, [%1, #0] \n\
+ b 3f \n\
+2: b 1b \n\
+3: nop \n\
+ nop"
+ : "=&r" (unused)
+ : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
+ "r" (sd.mdrefr), "r" (sd.mdcas[0]),
+ "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
+ local_irq_restore(flags);
+
+ /*
+ * Now, return the SDRAM refresh back to normal.
+ */
+ sdram_update_refresh(freqs.new, sdram);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+ policy->cur = policy->min = policy->max = sa11x0_getspeed(0);
+ policy->cpuinfo.min_freq = 59000;
+ policy->cpuinfo.max_freq = 287000;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ return 0;
+}
+
+/* sa1110_driver needs __refdata because it must remain after init registers
+ * it with cpufreq_register_driver() */
+static struct cpufreq_driver sa1110_driver __refdata = {
+ .flags = CPUFREQ_STICKY,
+ .verify = sa11x0_verify_speed,
+ .target = sa1110_target,
+ .get = sa11x0_getspeed,
+ .init = sa1110_cpu_init,
+ .name = "sa1110",
+};
+
+static struct sdram_params *sa1110_find_sdram(const char *name)
+{
+ struct sdram_params *sdram;
+
+ for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
+ sdram++)
+ if (strcmp(name, sdram->name) == 0)
+ return sdram;
+
+ return NULL;
+}
+
+static char sdram_name[16];
+
+static int __init sa1110_clk_init(void)
+{
+ struct sdram_params *sdram;
+ const char *name = sdram_name;
+
+ if (!cpu_is_sa1110())
+ return -ENODEV;
+
+ if (!name[0]) {
+ if (machine_is_assabet())
+ name = "TC59SM716-CL3";
+ if (machine_is_pt_system3())
+ name = "K4S641632D";
+ if (machine_is_h3100())
+ name = "KM416S4030CT";
+ if (machine_is_jornada720())
+ name = "K4S281632B-1H";
+ if (machine_is_nanoengine())
+ name = "MT48LC8M16A2TG-75";
+ }
+
+ sdram = sa1110_find_sdram(name);
+ if (sdram) {
+ printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
+ " twr: %d refresh: %d cas_latency: %d\n",
+ sdram->tck, sdram->trcd, sdram->trp,
+ sdram->twr, sdram->refresh, sdram->cas_latency);
+
+ memcpy(&sdram_params, sdram, sizeof(sdram_params));
+
+ return cpufreq_register_driver(&sa1110_driver);
+ }
+
+ return 0;
+}
+
+module_param_string(sdram, sdram_name, sizeof(sdram_name), 0);
+arch_initcall(sa1110_clk_init);
diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
new file mode 100644
index 00000000..ad660350
--- /dev/null
+++ b/arch/arm/mach-sa1100/dma.c
@@ -0,0 +1,348 @@
+/*
+ * arch/arm/mach-sa1100/dma.c
+ *
+ * Support functions for the SA11x0 internal DMA channels.
+ *
+ * Copyright (C) 2000, 2001 by Nicolas Pitre
+ *
+ * This program is free software; you can 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/interrupt.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK( s, arg... ) printk( "dma<%p>: " s, regs , ##arg )
+#else
+#define DPRINTK( x... )
+#endif
+
+
+typedef struct {
+ const char *device_id; /* device name */
+ u_long device; /* this channel device, 0 if unused*/
+ dma_callback_t callback; /* to call when DMA completes */
+ void *data; /* ... with private data ptr */
+} sa1100_dma_t;
+
+static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
+
+static DEFINE_SPINLOCK(dma_list_lock);
+
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+ dma_regs_t *dma_regs = dev_id;
+ sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
+ int status = dma_regs->RdDCSR;
+
+ if (status & (DCSR_ERROR)) {
+ printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id);
+ dma_regs->ClrDCSR = DCSR_ERROR;
+ }
+
+ dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
+ if (dma->callback) {
+ if (status & DCSR_DONEA)
+ dma->callback(dma->data);
+ if (status & DCSR_DONEB)
+ dma->callback(dma->data);
+ }
+ return IRQ_HANDLED;
+}
+
+
+/**
+ * sa1100_request_dma - allocate one of the SA11x0's DMA channels
+ * @device: The SA11x0 peripheral targeted by this request
+ * @device_id: An ascii name for the claiming device
+ * @callback: Function to be called when the DMA completes
+ * @data: A cookie passed back to the callback function
+ * @dma_regs: Pointer to the location of the allocated channel's identifier
+ *
+ * This function will search for a free DMA channel and returns the
+ * address of the hardware registers for that channel as the channel
+ * identifier. This identifier is written to the location pointed by
+ * @dma_regs. The list of possible values for @device are listed into
+ * arch/arm/mach-sa1100/include/mach/dma.h as a dma_device_t enum.
+ *
+ * Note that reading from a port and writing to the same port are
+ * actually considered as two different streams requiring separate
+ * DMA registrations.
+ *
+ * The @callback function is called from interrupt context when one
+ * of the two possible DMA buffers in flight has terminated. That
+ * function has to be small and efficient while posponing more complex
+ * processing to a lower priority execution context.
+ *
+ * If no channels are available, or if the desired @device is already in
+ * use by another DMA channel, then an error code is returned. This
+ * function must be called before any other DMA calls.
+ **/
+
+int sa1100_request_dma (dma_device_t device, const char *device_id,
+ dma_callback_t callback, void *data,
+ dma_regs_t **dma_regs)
+{
+ sa1100_dma_t *dma = NULL;
+ dma_regs_t *regs;
+ int i, err;
+
+ *dma_regs = NULL;
+
+ err = 0;
+ spin_lock(&dma_list_lock);
+ for (i = 0; i < SA1100_DMA_CHANNELS; i++) {
+ if (dma_chan[i].device == device) {
+ err = -EBUSY;
+ break;
+ } else if (!dma_chan[i].device && !dma) {
+ dma = &dma_chan[i];
+ }
+ }
+ if (!err) {
+ if (dma)
+ dma->device = device;
+ else
+ err = -ENOSR;
+ }
+ spin_unlock(&dma_list_lock);
+ if (err)
+ return err;
+
+ i = dma - dma_chan;
+ regs = (dma_regs_t *)&DDAR(i);
+ err = request_irq(IRQ_DMA0 + i, dma_irq_handler, IRQF_DISABLED,
+ device_id, regs);
+ if (err) {
+ printk(KERN_ERR
+ "%s: unable to request IRQ %d for %s\n",
+ __func__, IRQ_DMA0 + i, device_id);
+ dma->device = 0;
+ return err;
+ }
+
+ *dma_regs = regs;
+ dma->device_id = device_id;
+ dma->callback = callback;
+ dma->data = data;
+
+ regs->ClrDCSR =
+ (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
+ DCSR_IE | DCSR_ERROR | DCSR_RUN);
+ regs->DDAR = device;
+
+ return 0;
+}
+
+
+/**
+ * sa1100_free_dma - free a SA11x0 DMA channel
+ * @regs: identifier for the channel to free
+ *
+ * This clears all activities on a given DMA channel and releases it
+ * for future requests. The @regs identifier is provided by a
+ * successful call to sa1100_request_dma().
+ **/
+
+void sa1100_free_dma(dma_regs_t *regs)
+{
+ int i;
+
+ for (i = 0; i < SA1100_DMA_CHANNELS; i++)
+ if (regs == (dma_regs_t *)&DDAR(i))
+ break;
+ if (i >= SA1100_DMA_CHANNELS) {
+ printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
+ return;
+ }
+
+ if (!dma_chan[i].device) {
+ printk(KERN_ERR "%s: Trying to free free DMA\n", __func__);
+ return;
+ }
+
+ regs->ClrDCSR =
+ (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
+ DCSR_IE | DCSR_ERROR | DCSR_RUN);
+ free_irq(IRQ_DMA0 + i, regs);
+ dma_chan[i].device = 0;
+}
+
+
+/**
+ * sa1100_start_dma - submit a data buffer for DMA
+ * @regs: identifier for the channel to use
+ * @dma_ptr: buffer physical (or bus) start address
+ * @size: buffer size
+ *
+ * This function hands the given data buffer to the hardware for DMA
+ * access. If another buffer is already in flight then this buffer
+ * will be queued so the DMA engine will switch to it automatically
+ * when the previous one is done. The DMA engine is actually toggling
+ * between two buffers so at most 2 successful calls can be made before
+ * one of them terminates and the callback function is called.
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ *
+ * The @size must not be larger than %MAX_DMA_SIZE. If a given buffer
+ * is larger than that then it's the caller's responsibility to split
+ * it into smaller chunks and submit them separately. If this is the
+ * case then a @size of %CUT_DMA_SIZE is recommended to avoid ending
+ * up with too small chunks. The callback function can be used to chain
+ * submissions of buffer chunks.
+ *
+ * Error return values:
+ * %-EOVERFLOW: Given buffer size is too big.
+ * %-EBUSY: Both DMA buffers are already in use.
+ * %-EAGAIN: Both buffers were busy but one of them just completed
+ * but the interrupt handler has to execute first.
+ *
+ * This function returs 0 on success.
+ **/
+
+int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size)
+{
+ unsigned long flags;
+ u_long status;
+ int ret;
+
+ if (dma_ptr & 3)
+ printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n",
+ (unsigned long)dma_ptr);
+
+ if (size > MAX_DMA_SIZE)
+ return -EOVERFLOW;
+
+ local_irq_save(flags);
+ status = regs->RdDCSR;
+
+ /* If both DMA buffers are started, there's nothing else we can do. */
+ if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
+ DPRINTK("start: st %#x busy\n", status);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
+ (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
+ if (status & DCSR_DONEA) {
+ /* give a chance for the interrupt to be processed */
+ ret = -EAGAIN;
+ goto out;
+ }
+ regs->DBSA = dma_ptr;
+ regs->DBTA = size;
+ regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
+ DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
+ } else {
+ if (status & DCSR_DONEB) {
+ /* give a chance for the interrupt to be processed */
+ ret = -EAGAIN;
+ goto out;
+ }
+ regs->DBSB = dma_ptr;
+ regs->DBTB = size;
+ regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
+ DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size);
+ }
+ ret = 0;
+
+out:
+ local_irq_restore(flags);
+ return ret;
+}
+
+
+/**
+ * sa1100_get_dma_pos - return current DMA position
+ * @regs: identifier for the channel to use
+ *
+ * This function returns the current physical (or bus) address for the
+ * given DMA channel. If the channel is running i.e. not in a stopped
+ * state then the caller must disable interrupts prior calling this
+ * function and process the returned value before re-enabling them to
+ * prevent races with the completion interrupt handler and the callback
+ * function. The validation of the returned value is the caller's
+ * responsibility as well -- the hardware seems to return out of range
+ * values when the DMA engine completes a buffer.
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ **/
+
+dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs)
+{
+ int status;
+
+ /*
+ * We must determine whether buffer A or B is active.
+ * Two possibilities: either we are in the middle of
+ * a buffer, or the DMA controller just switched to the
+ * next toggle but the interrupt hasn't been serviced yet.
+ * The former case is straight forward. In the later case,
+ * we'll do like if DMA is just at the end of the previous
+ * toggle since all registers haven't been reset yet.
+ * This goes around the edge case and since we're always
+ * a little behind anyways it shouldn't make a big difference.
+ * If DMA has been stopped prior calling this then the
+ * position is exact.
+ */
+ status = regs->RdDCSR;
+ if ((!(status & DCSR_BIU) && (status & DCSR_STRTA)) ||
+ ( (status & DCSR_BIU) && !(status & DCSR_STRTB)))
+ return regs->DBSA;
+ else
+ return regs->DBSB;
+}
+
+
+/**
+ * sa1100_reset_dma - reset a DMA channel
+ * @regs: identifier for the channel to use
+ *
+ * This function resets and reconfigure the given DMA channel. This is
+ * particularly useful after a sleep/wakeup event.
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ **/
+
+void sa1100_reset_dma(dma_regs_t *regs)
+{
+ int i;
+
+ for (i = 0; i < SA1100_DMA_CHANNELS; i++)
+ if (regs == (dma_regs_t *)&DDAR(i))
+ break;
+ if (i >= SA1100_DMA_CHANNELS) {
+ printk(KERN_ERR "%s: bad DMA identifier\n", __func__);
+ return;
+ }
+
+ regs->ClrDCSR =
+ (DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
+ DCSR_IE | DCSR_ERROR | DCSR_RUN);
+ regs->DDAR = dma_chan[i].device;
+}
+
+
+EXPORT_SYMBOL(sa1100_request_dma);
+EXPORT_SYMBOL(sa1100_free_dma);
+EXPORT_SYMBOL(sa1100_start_dma);
+EXPORT_SYMBOL(sa1100_get_dma_pos);
+EXPORT_SYMBOL(sa1100_reset_dma);
+
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
new file mode 100644
index 00000000..e21f3470
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.c
@@ -0,0 +1,454 @@
+/*
+ * linux/arch/arm/mach-sa1100/generic.c
+ *
+ * Author: Nicolas Pitre
+ *
+ * Code common to all SA11x0 machines.
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <asm/system.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/irq.h>
+#include <asm/gpio.h>
+
+#include "generic.h"
+
+unsigned int reset_status;
+EXPORT_SYMBOL(reset_status);
+
+#define NR_FREQS 16
+
+/*
+ * This table is setup for a 3.6864MHz Crystal.
+ */
+static const unsigned short cclk_frequency_100khz[NR_FREQS] = {
+ 590, /* 59.0 MHz */
+ 737, /* 73.7 MHz */
+ 885, /* 88.5 MHz */
+ 1032, /* 103.2 MHz */
+ 1180, /* 118.0 MHz */
+ 1327, /* 132.7 MHz */
+ 1475, /* 147.5 MHz */
+ 1622, /* 162.2 MHz */
+ 1769, /* 176.9 MHz */
+ 1917, /* 191.7 MHz */
+ 2064, /* 206.4 MHz */
+ 2212, /* 221.2 MHz */
+ 2359, /* 235.9 MHz */
+ 2507, /* 250.7 MHz */
+ 2654, /* 265.4 MHz */
+ 2802 /* 280.2 MHz */
+};
+
+/* rounds up(!) */
+unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
+{
+ int i;
+
+ khz /= 100;
+
+ for (i = 0; i < NR_FREQS; i++)
+ if (cclk_frequency_100khz[i] >= khz)
+ break;
+
+ return i;
+}
+
+unsigned int sa11x0_ppcr_to_freq(unsigned int idx)
+{
+ unsigned int freq = 0;
+ if (idx < NR_FREQS)
+ freq = cclk_frequency_100khz[idx] * 100;
+ return freq;
+}
+
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+int sa11x0_verify_speed(struct cpufreq_policy *policy)
+{
+ unsigned int tmp;
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+
+ /* make sure that at least one frequency is within the policy */
+ tmp = cclk_frequency_100khz[sa11x0_freq_to_ppcr(policy->min)] * 100;
+ if (tmp > policy->max)
+ policy->max = tmp;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+
+ return 0;
+}
+
+unsigned int sa11x0_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+ return cclk_frequency_100khz[PPCR & 0xf] * 100;
+}
+
+/*
+ * Default power-off for SA1100
+ */
+static void sa1100_power_off(void)
+{
+ mdelay(100);
+ local_irq_disable();
+ /* disable internal oscillator, float CS lines */
+ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
+ /* enable wake-up on GPIO0 (Assabet...) */
+ PWER = GFER = GRER = 1;
+ /*
+ * set scratchpad to zero, just in case it is used as a
+ * restart address by the bootloader.
+ */
+ PSPR = 0;
+ /* enter sleep mode */
+ PMCR = PMCR_SF;
+}
+
+static void sa11x0_register_device(struct platform_device *dev, void *data)
+{
+ int err;
+ dev->dev.platform_data = data;
+ err = platform_device_register(dev);
+ if (err)
+ printk(KERN_ERR "Unable to register device %s: %d\n",
+ dev->name, err);
+}
+
+
+static struct resource sa11x0udc_resources[] = {
+ [0] = {
+ .start = __PREG(Ser0UDCCR),
+ .end = __PREG(Ser0UDCCR) + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_Ser0UDC,
+ .end = IRQ_Ser0UDC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 sa11x0udc_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0udc_device = {
+ .name = "sa11x0-udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0udc_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0udc_resources),
+ .resource = sa11x0udc_resources,
+};
+
+static struct resource sa11x0uart1_resources[] = {
+ [0] = {
+ .start = __PREG(Ser1UTCR0),
+ .end = __PREG(Ser1UTCR0) + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_Ser1UART,
+ .end = IRQ_Ser1UART,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sa11x0uart1_device = {
+ .name = "sa11x0-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sa11x0uart1_resources),
+ .resource = sa11x0uart1_resources,
+};
+
+static struct resource sa11x0uart3_resources[] = {
+ [0] = {
+ .start = __PREG(Ser3UTCR0),
+ .end = __PREG(Ser3UTCR0) + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_Ser3UART,
+ .end = IRQ_Ser3UART,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sa11x0uart3_device = {
+ .name = "sa11x0-uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(sa11x0uart3_resources),
+ .resource = sa11x0uart3_resources,
+};
+
+static struct resource sa11x0mcp_resources[] = {
+ [0] = {
+ .start = __PREG(Ser4MCCR0),
+ .end = __PREG(Ser4MCCR0) + 0xffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_Ser4MCP,
+ .end = IRQ_Ser4MCP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0mcp_device = {
+ .name = "sa11x0-mcp",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0mcp_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0mcp_resources),
+ .resource = sa11x0mcp_resources,
+};
+
+void sa11x0_register_mcp(struct mcp_plat_data *data)
+{
+ sa11x0_register_device(&sa11x0mcp_device, data);
+}
+
+static struct resource sa11x0ssp_resources[] = {
+ [0] = {
+ .start = 0x80070000,
+ .end = 0x8007ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_Ser4SSP,
+ .end = IRQ_Ser4SSP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0ssp_device = {
+ .name = "sa11x0-ssp",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0ssp_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0ssp_resources),
+ .resource = sa11x0ssp_resources,
+};
+
+static struct resource sa11x0fb_resources[] = {
+ [0] = {
+ .start = 0xb0100000,
+ .end = 0xb010ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sa11x0fb_device = {
+ .name = "sa11x0-fb",
+ .id = -1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0fb_resources),
+ .resource = sa11x0fb_resources,
+};
+
+static struct platform_device sa11x0pcmcia_device = {
+ .name = "sa11x0-pcmcia",
+ .id = -1,
+};
+
+static struct platform_device sa11x0mtd_device = {
+ .name = "sa1100-mtd",
+ .id = -1,
+};
+
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+ struct resource *res, int nr)
+{
+ flash->name = "sa1100";
+ sa11x0mtd_device.resource = res;
+ sa11x0mtd_device.num_resources = nr;
+ sa11x0_register_device(&sa11x0mtd_device, flash);
+}
+
+static struct resource sa11x0ir_resources[] = {
+ {
+ .start = __PREG(Ser2UTCR0),
+ .end = __PREG(Ser2UTCR0) + 0x24 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = __PREG(Ser2HSCR0),
+ .end = __PREG(Ser2HSCR0) + 0x1c - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = __PREG(Ser2HSCR2),
+ .end = __PREG(Ser2HSCR2) + 0x04 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_Ser2ICP,
+ .end = IRQ_Ser2ICP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device sa11x0ir_device = {
+ .name = "sa11x0-ir",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa11x0ir_resources),
+ .resource = sa11x0ir_resources,
+};
+
+void sa11x0_register_irda(struct irda_platform_data *irda)
+{
+ sa11x0_register_device(&sa11x0ir_device, irda);
+}
+
+static struct platform_device sa11x0rtc_device = {
+ .name = "sa1100-rtc",
+ .id = -1,
+};
+
+static struct platform_device *sa11x0_devices[] __initdata = {
+ &sa11x0udc_device,
+ &sa11x0uart1_device,
+ &sa11x0uart3_device,
+ &sa11x0ssp_device,
+ &sa11x0pcmcia_device,
+ &sa11x0fb_device,
+ &sa11x0rtc_device,
+};
+
+static int __init sa1100_init(void)
+{
+ pm_power_off = sa1100_power_off;
+ return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
+}
+
+arch_initcall(sa1100_init);
+
+void (*sa1100fb_backlight_power)(int on);
+void (*sa1100fb_lcd_power)(int on);
+
+EXPORT_SYMBOL(sa1100fb_backlight_power);
+EXPORT_SYMBOL(sa1100fb_lcd_power);
+
+
+/*
+ * Common I/O mapping:
+ *
+ * Typically, static virtual address mappings are as follow:
+ *
+ * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.)
+ * 0xf4000000-0xf4ffffff: SA-1111
+ * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area)
+ * 0xf6000000-0xfffeffff: reserved (internal SA1100 IO defined above)
+ * 0xffff0000-0xffff0fff: SA1100 exception vectors
+ * 0xffff2000-0xffff2fff: Minicache copy_user_page area
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ *
+ * The machine specific code must provide the extra mapping beside the
+ * default mapping provided here.
+ */
+
+static struct map_desc standard_io_desc[] __initdata = {
+ { /* PCM */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x80000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SCM */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x90000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MER */
+ .virtual = 0xfc000000,
+ .pfn = __phys_to_pfn(0xa0000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* LCD + DMA */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xb0000000),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init sa1100_map_io(void)
+{
+ iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+/*
+ * Disable the memory bus request/grant signals on the SA1110 to
+ * ensure that we don't receive spurious memory requests. We set
+ * the MBGNT signal false to ensure the SA1111 doesn't own the
+ * SDRAM bus.
+ */
+void __init sa1110_mb_disable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+
+ GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
+
+ local_irq_restore(flags);
+}
+
+/*
+ * If the system is going to use the SA-1111 DMA engines, set up
+ * the memory bus request/grant pins.
+ */
+void __devinit sa1110_mb_enable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+
+ GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+ TUCR |= TUCR_MR;
+
+ local_irq_restore(flags);
+}
+
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
new file mode 100644
index 00000000..b7a9a601
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.h
@@ -0,0 +1,41 @@
+/*
+ * linux/arch/arm/mach-sa1100/generic.h
+ *
+ * Author: Nicolas Pitre
+ */
+
+struct sys_timer;
+
+extern struct sys_timer sa1100_timer;
+extern void __init sa1100_map_io(void);
+extern void __init sa1100_init_irq(void);
+extern void __init sa1100_init_gpio(void);
+
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size)
+
+extern void (*sa1100fb_backlight_power)(int on);
+extern void (*sa1100fb_lcd_power)(int on);
+
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+struct cpufreq_policy;
+
+extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
+extern int sa11x0_verify_speed(struct cpufreq_policy *policy);
+extern unsigned int sa11x0_getspeed(unsigned int cpu);
+extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
+
+struct flash_platform_data;
+struct resource;
+
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+ struct resource *res, int nr);
+
+struct irda_platform_data;
+void sa11x0_register_irda(struct irda_platform_data *irda);
+
+struct mcp_plat_data;
+void sa11x0_register_mcp(struct mcp_plat_data *data);
diff --git a/arch/arm/mach-sa1100/gpio.c b/arch/arm/mach-sa1100/gpio.c
new file mode 100644
index 00000000..0d3829a8
--- /dev/null
+++ b/arch/arm/mach-sa1100/gpio.c
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-sa1100/gpio.c
+ *
+ * Generic SA-1100 GPIO handling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#include <asm/gpio.h>
+#include <mach/hardware.h>
+#include "generic.h"
+
+static int sa1100_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return GPLR & GPIO_GPIO(offset);
+}
+
+static void sa1100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ if (value)
+ GPSR = GPIO_GPIO(offset);
+ else
+ GPCR = GPIO_GPIO(offset);
+}
+
+static int sa1100_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ GPDR &= ~GPIO_GPIO(offset);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ sa1100_gpio_set(chip, offset, value);
+ GPDR |= GPIO_GPIO(offset);
+ local_irq_restore(flags);
+ return 0;
+}
+
+static struct gpio_chip sa1100_gpio_chip = {
+ .label = "gpio",
+ .direction_input = sa1100_direction_input,
+ .direction_output = sa1100_direction_output,
+ .set = sa1100_gpio_set,
+ .get = sa1100_gpio_get,
+ .base = 0,
+ .ngpio = GPIO_MAX + 1,
+};
+
+void __init sa1100_init_gpio(void)
+{
+ gpiochip_add(&sa1100_gpio_chip);
+}
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
new file mode 100644
index 00000000..03d7376c
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -0,0 +1,93 @@
+/*
+ * Support for Compaq iPAQ H3100 handheld computer
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irda.h>
+
+#include <mach/h3xxx.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static void h3100_lcd_power(int enable)
+{
+ if (!gpio_request(H3XXX_EGPIO_LCD_ON, "LCD ON")) {
+ gpio_set_value(H3100_GPIO_LCD_3V_ON, enable);
+ gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
+ gpio_free(H3XXX_EGPIO_LCD_ON);
+ } else {
+ pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
+ }
+}
+
+
+static void __init h3100_map_io(void)
+{
+ h3xxx_map_io();
+
+ sa1100fb_lcd_power = h3100_lcd_power;
+
+ /* Older bootldrs put GPIO2-9 in alternate mode on the
+ assumption that they are used for video */
+ GAFR &= ~0x000001fb;
+}
+
+/*
+ * This turns the IRDA power on or off on the Compaq H3100
+ */
+static int h3100_irda_set_power(struct device *dev, unsigned int state)
+{
+ gpio_set_value(H3100_GPIO_IR_ON, state);
+ return 0;
+}
+
+static void h3100_irda_set_speed(struct device *dev, unsigned int speed)
+{
+ gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000));
+}
+
+static struct irda_platform_data h3100_irda_data = {
+ .set_power = h3100_irda_set_power,
+ .set_speed = h3100_irda_set_speed,
+};
+
+static struct gpio_default_state h3100_default_gpio[] = {
+ { H3100_GPIO_IR_ON, GPIO_MODE_OUT0, "IrDA power" },
+ { H3100_GPIO_IR_FSEL, GPIO_MODE_OUT0, "IrDA fsel" },
+ { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
+ { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
+ { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
+ { H3100_GPIO_LCD_3V_ON, GPIO_MODE_OUT0, "LCD 3v" },
+};
+
+static void __init h3100_mach_init(void)
+{
+ h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
+ h3xxx_mach_init();
+ sa11x0_register_irda(&h3100_irda_data);
+}
+
+MACHINE_START(H3100, "Compaq iPAQ H3100")
+ .boot_params = 0xc0000100,
+ .map_io = h3100_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = h3100_mach_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
new file mode 100644
index 00000000..965f64a8
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -0,0 +1,134 @@
+/*
+ * Support for Compaq iPAQ H3600 handheld computer
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irda.h>
+
+#include <mach/h3xxx.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static void h3600_lcd_power(int enable)
+{
+ if (gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power")) {
+ pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
+ goto err1;
+ }
+ if (gpio_request(H3600_EGPIO_LCD_PCI, "LCD control")) {
+ pr_err("%s: can't request H3XXX_EGPIO_LCD_PCI\n", __func__);
+ goto err2;
+ }
+ if (gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v")) {
+ pr_err("%s: can't request H3XXX_EGPIO_LCD_5V_ON\n", __func__);
+ goto err3;
+ }
+ if (gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v")) {
+ pr_err("%s: can't request H3600_EGPIO_LVDD_ON\n", __func__);
+ goto err4;
+ }
+
+ gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
+ gpio_direction_output(H3600_EGPIO_LCD_PCI, enable);
+ gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable);
+ gpio_direction_output(H3600_EGPIO_LVDD_ON, enable);
+
+ gpio_free(H3600_EGPIO_LVDD_ON);
+err4: gpio_free(H3600_EGPIO_LCD_5V_ON);
+err3: gpio_free(H3600_EGPIO_LCD_PCI);
+err2: gpio_free(H3XXX_EGPIO_LCD_ON);
+err1: return;
+}
+
+static void __init h3600_map_io(void)
+{
+ h3xxx_map_io();
+
+ sa1100fb_lcd_power = h3600_lcd_power;
+}
+
+/*
+ * This turns the IRDA power on or off on the Compaq H3600
+ */
+static int h3600_irda_set_power(struct device *dev, unsigned int state)
+{
+ gpio_set_value(H3600_EGPIO_IR_ON, state);
+ return 0;
+}
+
+static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
+{
+ gpio_set_value(H3600_EGPIO_IR_FSEL, !(speed < 4000000));
+}
+
+static int h3600_irda_startup(struct device *dev)
+{
+ int err = gpio_request(H3600_EGPIO_IR_ON, "IrDA power");
+ if (err)
+ goto err1;
+ err = gpio_direction_output(H3600_EGPIO_IR_ON, 0);
+ if (err)
+ goto err2;
+ err = gpio_request(H3600_EGPIO_IR_FSEL, "IrDA fsel");
+ if (err)
+ goto err2;
+ err = gpio_direction_output(H3600_EGPIO_IR_FSEL, 0);
+ if (err)
+ goto err3;
+ return 0;
+
+err3: gpio_free(H3600_EGPIO_IR_FSEL);
+err2: gpio_free(H3600_EGPIO_IR_ON);
+err1: return err;
+}
+
+static void h3600_irda_shutdown(struct device *dev)
+{
+ gpio_free(H3600_EGPIO_IR_ON);
+ gpio_free(H3600_EGPIO_IR_FSEL);
+}
+
+static struct irda_platform_data h3600_irda_data = {
+ .set_power = h3600_irda_set_power,
+ .set_speed = h3600_irda_set_speed,
+ .startup = h3600_irda_startup,
+ .shutdown = h3600_irda_shutdown,
+};
+
+static struct gpio_default_state h3600_default_gpio[] = {
+ { H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
+ { H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
+ { H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
+};
+
+static void __init h3600_mach_init(void)
+{
+ h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
+ h3xxx_mach_init();
+ sa11x0_register_irda(&h3600_irda_data);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ H3600")
+ .boot_params = 0xc0000100,
+ .map_io = h3600_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = h3600_mach_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
new file mode 100644
index 00000000..b0784c97
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -0,0 +1,313 @@
+/*
+ * Support for Compaq iPAQ H3100 and H3600 handheld computers (common code)
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mfd/htc-egpio.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/h3xxx.h>
+
+#include "generic.h"
+
+void h3xxx_init_gpio(struct gpio_default_state *s, size_t n)
+{
+ while (n--) {
+ const char *name = s->name;
+ int err;
+
+ if (!name)
+ name = "[init]";
+ err = gpio_request(s->gpio, name);
+ if (err) {
+ printk(KERN_ERR "gpio%u: unable to request: %d\n",
+ s->gpio, err);
+ continue;
+ }
+ if (s->mode >= 0) {
+ err = gpio_direction_output(s->gpio, s->mode);
+ } else {
+ err = gpio_direction_input(s->gpio);
+ }
+ if (err) {
+ printk(KERN_ERR "gpio%u: unable to set direction: %d\n",
+ s->gpio, err);
+ continue;
+ }
+ if (!s->name)
+ gpio_free(s->gpio);
+ s++;
+ }
+}
+
+
+/*
+ * H3xxx flash support
+ */
+static struct mtd_partition h3xxx_partitions[] = {
+ {
+ .name = "H3XXX boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "H3XXX rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00040000,
+ }
+};
+
+static void h3xxx_set_vpp(int vpp)
+{
+ gpio_set_value(H3XXX_EGPIO_VPP_ON, vpp);
+}
+
+static int h3xxx_flash_init(void)
+{
+ int err = gpio_request(H3XXX_EGPIO_VPP_ON, "Flash Vpp");
+ if (err) {
+ pr_err("%s: can't request H3XXX_EGPIO_VPP_ON\n", __func__);
+ return err;
+ }
+
+ err = gpio_direction_output(H3XXX_EGPIO_VPP_ON, 0);
+ if (err)
+ gpio_free(H3XXX_EGPIO_VPP_ON);
+
+ return err;
+}
+
+static void h3xxx_flash_exit(void)
+{
+ gpio_free(H3XXX_EGPIO_VPP_ON);
+}
+
+static struct flash_platform_data h3xxx_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = h3xxx_set_vpp,
+ .init = h3xxx_flash_init,
+ .exit = h3xxx_flash_exit,
+ .parts = h3xxx_partitions,
+ .nr_parts = ARRAY_SIZE(h3xxx_partitions),
+};
+
+static struct resource h3xxx_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+
+/*
+ * H3xxx uart support
+ */
+static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
+ }
+}
+
+static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
+{
+ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+ if (port->mapbase == _Ser3UTCR0) {
+ /*
+ * DCD and CTS bits are inverted in GPLR by RS232 transceiver
+ */
+ if (gpio_get_value(H3XXX_GPIO_COM_DCD))
+ ret &= ~TIOCM_CD;
+ if (gpio_get_value(H3XXX_GPIO_COM_CTS))
+ ret &= ~TIOCM_CTS;
+ }
+
+ return ret;
+}
+
+static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ if (!gpio_request(H3XXX_EGPIO_RS232_ON, "RS232 transceiver")) {
+ gpio_direction_output(H3XXX_EGPIO_RS232_ON, !state);
+ gpio_free(H3XXX_EGPIO_RS232_ON);
+ } else {
+ pr_err("%s: can't request H3XXX_EGPIO_RS232_ON\n",
+ __func__);
+ }
+ }
+}
+
+/*
+ * Enable/Disable wake up events for this serial port.
+ * Obviously, we only support this on the normal COM port.
+ */
+static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
+{
+ int err = -EINVAL;
+
+ if (port->mapbase == _Ser3UTCR0) {
+ if (enable)
+ PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
+ else
+ PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
+ err = 0;
+ }
+ return err;
+}
+
+static struct sa1100_port_fns h3xxx_port_fns __initdata = {
+ .set_mctrl = h3xxx_uart_set_mctrl,
+ .get_mctrl = h3xxx_uart_get_mctrl,
+ .pm = h3xxx_uart_pm,
+ .set_wake = h3xxx_uart_set_wake,
+};
+
+/*
+ * EGPIO
+ */
+
+static struct resource egpio_resources[] = {
+ [0] = {
+ .start = H3600_EGPIO_PHYS,
+ .end = H3600_EGPIO_PHYS + 0x4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct htc_egpio_chip egpio_chips[] = {
+ [0] = {
+ .reg_start = 0,
+ .gpio_base = H3XXX_EGPIO_BASE,
+ .num_gpios = 16,
+ .direction = HTC_EGPIO_OUTPUT,
+ .initial_values = 0x0080, /* H3XXX_EGPIO_RS232_ON */
+ },
+};
+
+static struct htc_egpio_platform_data egpio_info = {
+ .reg_width = 16,
+ .bus_width = 16,
+ .chip = egpio_chips,
+ .num_chips = ARRAY_SIZE(egpio_chips),
+};
+
+static struct platform_device h3xxx_egpio = {
+ .name = "htc-egpio",
+ .id = -1,
+ .resource = egpio_resources,
+ .num_resources = ARRAY_SIZE(egpio_resources),
+ .dev = {
+ .platform_data = &egpio_info,
+ },
+};
+
+/*
+ * GPIO keys
+ */
+
+static struct gpio_keys_button h3xxx_button_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = H3XXX_GPIO_PWR_BUTTON,
+ .desc = "Power Button",
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ }, {
+ .code = KEY_ENTER,
+ .gpio = H3XXX_GPIO_ACTION_BUTTON,
+ .active_low = 1,
+ .desc = "Action button",
+ .type = EV_KEY,
+ .wakeup = 0,
+ },
+};
+
+static struct gpio_keys_platform_data h3xxx_keys_data = {
+ .buttons = h3xxx_button_table,
+ .nbuttons = ARRAY_SIZE(h3xxx_button_table),
+};
+
+static struct platform_device h3xxx_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &h3xxx_keys_data,
+ },
+};
+
+static struct platform_device *h3xxx_devices[] = {
+ &h3xxx_egpio,
+ &h3xxx_keys,
+};
+
+void __init h3xxx_mach_init(void)
+{
+ sa1100_register_uart_fns(&h3xxx_port_fns);
+ sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
+ platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
+}
+
+static struct map_desc h3600_io_desc[] __initdata = {
+ { /* static memory bank 2 CS#2 */
+ .virtual = H3600_BANK_2_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS2_PHYS),
+ .length = 0x02800000,
+ .type = MT_DEVICE
+ }, { /* static memory bank 4 CS#4 */
+ .virtual = H3600_BANK_4_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS4_PHYS),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* EGPIO 0 CS#5 */
+ .virtual = H3600_EGPIO_VIRT,
+ .pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
+};
+
+/*
+ * Common map_io initialization
+ */
+
+void __init h3xxx_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
+
+ sa1100_register_uart(0, 3); /* Common serial port */
+// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
+
+ /* Ensure those pins are outputs and driving low */
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
+ /* Configure suspend conditions */
+ PGSR = 0;
+ PCFR = PCFR_OPDE;
+ PSDR = 0;
+
+ GPCR = 0x0fffffff; /* All outputs are set low by default */
+ GPDR = 0; /* Configure all GPIOs as input */
+}
+
diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c
new file mode 100644
index 00000000..db5e434a
--- /dev/null
+++ b/arch/arm/mach-sa1100/hackkit.c
@@ -0,0 +1,203 @@
+/*
+ * linux/arch/arm/mach-sa1100/hackkit.c
+ *
+ * Copyright (C) 2002 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * This file contains all HackKit tweaks. Based on original work from
+ * Nicolas Pitre's assabet fixes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/serial_core.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+/**********************************************************************
+ * prototypes
+ */
+
+/* init funcs */
+static void __init hackkit_map_io(void);
+
+static u_int hackkit_get_mctrl(struct uart_port *port);
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl);
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
+
+/**********************************************************************
+ * global data
+ */
+
+/**********************************************************************
+ * static data
+ */
+
+static struct map_desc hackkit_io_desc[] __initdata = {
+ { /* Flash bank 0 */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ },
+};
+
+static struct sa1100_port_fns hackkit_port_fns __initdata = {
+ .set_mctrl = hackkit_set_mctrl,
+ .get_mctrl = hackkit_get_mctrl,
+ .pm = hackkit_uart_pm,
+};
+
+/**********************************************************************
+ * Static functions
+ */
+
+static void __init hackkit_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(hackkit_io_desc, ARRAY_SIZE(hackkit_io_desc));
+
+ sa1100_register_uart_fns(&hackkit_port_fns);
+ sa1100_register_uart(0, 1); /* com port */
+ sa1100_register_uart(1, 2);
+ sa1100_register_uart(2, 3); /* radio module */
+
+ Ser1SDCR0 |= SDCR0_SUS;
+}
+
+/**
+ * hackkit_uart_pm - powermgmt callback function for system 3 UART
+ * @port: uart port structure
+ * @state: pm state
+ * @oldstate: old pm state
+ *
+ */
+static void hackkit_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ /* TODO: switch on/off uart in powersave mode */
+}
+
+/*
+ * Note! this can be called from IRQ context.
+ * FIXME: No modem ctrl lines yet.
+ */
+static void hackkit_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+#if 0
+ if (port->mapbase == _Ser1UTCR0) {
+ u_int set = 0, clear = 0;
+
+ if (mctrl & TIOCM_RTS)
+ set |= PT_CTRL2_RS1_RTS;
+ else
+ clear |= PT_CTRL2_RS1_RTS;
+
+ if (mctrl & TIOCM_DTR)
+ set |= PT_CTRL2_RS1_DTR;
+ else
+ clear |= PT_CTRL2_RS1_DTR;
+
+ PTCTRL2_clear(clear);
+ PTCTRL2_set(set);
+ }
+#endif
+}
+
+static u_int hackkit_get_mctrl(struct uart_port *port)
+{
+ u_int ret = 0;
+#if 0
+ u_int irqsr = PT_IRQSR;
+
+ /* need 2 reads to read current value */
+ irqsr = PT_IRQSR;
+
+ /* TODO: check IRQ source register for modem/com
+ status lines and set them correctly. */
+#endif
+
+ ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+ return ret;
+}
+
+static struct mtd_partition hackkit_partitions[] = {
+ {
+ .name = "BLOB",
+ .size = 0x00040000,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "config",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "kernel",
+ .size = 0x00100000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "initrd",
+ .size = 0x00180000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "rootfs",
+ .size = 0x700000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "data",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct flash_platform_data hackkit_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = hackkit_partitions,
+ .nr_parts = ARRAY_SIZE(hackkit_partitions),
+};
+
+static struct resource hackkit_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __init hackkit_init(void)
+{
+ sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
+}
+
+/**********************************************************************
+ * Exported Functions
+ */
+
+MACHINE_START(HACKKIT, "HackKit Cpu Board")
+ .boot_params = 0xc0000100,
+ .map_io = hackkit_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = hackkit_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h
new file mode 100644
index 00000000..bae8296f
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h
@@ -0,0 +1,2056 @@
+/*
+ * FILE SA-1100.h
+ *
+ * Version 1.2
+ * Author Copyright (c) Marc A. Viredaz, 1998
+ * DEC Western Research Laboratory, Palo Alto, CA
+ * Date January 1998 (April 1997)
+ * System StrongARM SA-1100
+ * Language C or ARM Assembly
+ * Purpose Definition of constants related to the StrongARM
+ * SA-1100 microprocessor (Advanced RISC Machine (ARM)
+ * architecture version 4). This file is based on the
+ * StrongARM SA-1100 data sheet version 2.2.
+ *
+ */
+
+
+/* Be sure that virtual mapping is defined right */
+#ifndef __ASM_ARCH_HARDWARE_H
+#error You must include hardware.h not SA-1100.h
+#endif
+
+#include "bitfield.h"
+
+/*
+ * SA1100 CS line to physical address
+ */
+
+#define SA1100_CS0_PHYS 0x00000000
+#define SA1100_CS1_PHYS 0x08000000
+#define SA1100_CS2_PHYS 0x10000000
+#define SA1100_CS3_PHYS 0x18000000
+#define SA1100_CS4_PHYS 0x40000000
+#define SA1100_CS5_PHYS 0x48000000
+
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (0x20000000 + (Nb)*PCMCIASp)
+#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA (Nb) + 2*PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA (Nb) + 3*PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
+
+#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */
+#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */
+#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */
+#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */
+
+
+/*
+ * Universal Serial Bus (USB) Device Controller (UDC) control registers
+ *
+ * Registers
+ * Ser0UDCCR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control Register (read/write).
+ * Ser0UDCAR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Address Register (read/write).
+ * Ser0UDCOMP Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Output Maximum Packet size register
+ * (read/write).
+ * Ser0UDCIMP Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Input Maximum Packet size register
+ * (read/write).
+ * Ser0UDCCS0 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 0
+ * (read/write).
+ * Ser0UDCCS1 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 1
+ * (output, read/write).
+ * Ser0UDCCS2 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 2
+ * (input, read/write).
+ * Ser0UDCD0 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Data register end-point 0
+ * (read/write).
+ * Ser0UDCWC Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Write Count register end-point 0
+ * (read).
+ * Ser0UDCDR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Data Register (read/write).
+ * Ser0UDCSR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Status Register (read/write).
+ */
+
+#define Ser0UDCCR __REG(0x80000000) /* Ser. port 0 UDC Control Reg. */
+#define Ser0UDCAR __REG(0x80000004) /* Ser. port 0 UDC Address Reg. */
+#define Ser0UDCOMP __REG(0x80000008) /* Ser. port 0 UDC Output Maximum Packet size reg. */
+#define Ser0UDCIMP __REG(0x8000000C) /* Ser. port 0 UDC Input Maximum Packet size reg. */
+#define Ser0UDCCS0 __REG(0x80000010) /* Ser. port 0 UDC Control/Status reg. end-point 0 */
+#define Ser0UDCCS1 __REG(0x80000014) /* Ser. port 0 UDC Control/Status reg. end-point 1 (output) */
+#define Ser0UDCCS2 __REG(0x80000018) /* Ser. port 0 UDC Control/Status reg. end-point 2 (input) */
+#define Ser0UDCD0 __REG(0x8000001C) /* Ser. port 0 UDC Data reg. end-point 0 */
+#define Ser0UDCWC __REG(0x80000020) /* Ser. port 0 UDC Write Count reg. end-point 0 */
+#define Ser0UDCDR __REG(0x80000028) /* Ser. port 0 UDC Data Reg. */
+#define Ser0UDCSR __REG(0x80000030) /* Ser. port 0 UDC Status Reg. */
+
+#define UDCCR_UDD 0x00000001 /* UDC Disable */
+#define UDCCR_UDA 0x00000002 /* UDC Active (read) */
+#define UDCCR_RESIM 0x00000004 /* Resume Interrupt Mask, per errata */
+#define UDCCR_EIM 0x00000008 /* End-point 0 Interrupt Mask */
+ /* (disable) */
+#define UDCCR_RIM 0x00000010 /* Receive Interrupt Mask */
+ /* (disable) */
+#define UDCCR_TIM 0x00000020 /* Transmit Interrupt Mask */
+ /* (disable) */
+#define UDCCR_SRM 0x00000040 /* Suspend/Resume interrupt Mask */
+ /* (disable) */
+#define UDCCR_SUSIM UDCCR_SRM /* Per errata, SRM just masks suspend */
+#define UDCCR_REM 0x00000080 /* REset interrupt Mask (disable) */
+
+#define UDCAR_ADD Fld (7, 0) /* function ADDress */
+
+#define UDCOMP_OUTMAXP Fld (8, 0) /* OUTput MAXimum Packet size - 1 */
+ /* [byte] */
+#define UDCOMP_OutMaxPkt(Size) /* Output Maximum Packet size */ \
+ /* [1..256 byte] */ \
+ (((Size) - 1) << FShft (UDCOMP_OUTMAXP))
+
+#define UDCIMP_INMAXP Fld (8, 0) /* INput MAXimum Packet size - 1 */
+ /* [byte] */
+#define UDCIMP_InMaxPkt(Size) /* Input Maximum Packet size */ \
+ /* [1..256 byte] */ \
+ (((Size) - 1) << FShft (UDCIMP_INMAXP))
+
+#define UDCCS0_OPR 0x00000001 /* Output Packet Ready (read) */
+#define UDCCS0_IPR 0x00000002 /* Input Packet Ready */
+#define UDCCS0_SST 0x00000004 /* Sent STall */
+#define UDCCS0_FST 0x00000008 /* Force STall */
+#define UDCCS0_DE 0x00000010 /* Data End */
+#define UDCCS0_SE 0x00000020 /* Setup End (read) */
+#define UDCCS0_SO 0x00000040 /* Serviced Output packet ready */
+ /* (write) */
+#define UDCCS0_SSE 0x00000080 /* Serviced Setup End (write) */
+
+#define UDCCS1_RFS 0x00000001 /* Receive FIFO 12-bytes or more */
+ /* Service request (read) */
+#define UDCCS1_RPC 0x00000002 /* Receive Packet Complete */
+#define UDCCS1_RPE 0x00000004 /* Receive Packet Error (read) */
+#define UDCCS1_SST 0x00000008 /* Sent STall */
+#define UDCCS1_FST 0x00000010 /* Force STall */
+#define UDCCS1_RNE 0x00000020 /* Receive FIFO Not Empty (read) */
+
+#define UDCCS2_TFS 0x00000001 /* Transmit FIFO 8-bytes or less */
+ /* Service request (read) */
+#define UDCCS2_TPC 0x00000002 /* Transmit Packet Complete */
+#define UDCCS2_TPE 0x00000004 /* Transmit Packet Error (read) */
+#define UDCCS2_TUR 0x00000008 /* Transmit FIFO Under-Run */
+#define UDCCS2_SST 0x00000010 /* Sent STall */
+#define UDCCS2_FST 0x00000020 /* Force STall */
+
+#define UDCD0_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+
+#define UDCWC_WC Fld (4, 0) /* Write Count */
+
+#define UDCDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+
+#define UDCSR_EIR 0x00000001 /* End-point 0 Interrupt Request */
+#define UDCSR_RIR 0x00000002 /* Receive Interrupt Request */
+#define UDCSR_TIR 0x00000004 /* Transmit Interrupt Request */
+#define UDCSR_SUSIR 0x00000008 /* SUSpend Interrupt Request */
+#define UDCSR_RESIR 0x00000010 /* RESume Interrupt Request */
+#define UDCSR_RSTIR 0x00000020 /* ReSeT Interrupt Request */
+
+
+/*
+ * Universal Asynchronous Receiver/Transmitter (UART) control registers
+ *
+ * Registers
+ * Ser1UTCR0 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser1UTCR1 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser1UTCR2 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser1UTCR3 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser1UTDR Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser1UTSR0 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser1UTSR1 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Ser2UTCR0 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser2UTCR1 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser2UTCR2 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser2UTCR3 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser2UTCR4 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 4
+ * (read/write).
+ * Ser2UTDR Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser2UTSR0 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser2UTSR1 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Ser3UTCR0 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser3UTCR1 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser3UTCR2 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser3UTCR3 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser3UTDR Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser3UTSR0 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser3UTSR1 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fua, Tua Frequency, period of the UART communication.
+ */
+
+#define _UTCR0(Nb) __REG(0x80010000 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 0 [1..3] */
+#define _UTCR1(Nb) __REG(0x80010004 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 1 [1..3] */
+#define _UTCR2(Nb) __REG(0x80010008 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 2 [1..3] */
+#define _UTCR3(Nb) __REG(0x8001000C + ((Nb) - 1)*0x00020000) /* UART Control Reg. 3 [1..3] */
+#define _UTCR4(Nb) __REG(0x80010010 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 4 [2] */
+#define _UTDR(Nb) __REG(0x80010014 + ((Nb) - 1)*0x00020000) /* UART Data Reg. [1..3] */
+#define _UTSR0(Nb) __REG(0x8001001C + ((Nb) - 1)*0x00020000) /* UART Status Reg. 0 [1..3] */
+#define _UTSR1(Nb) __REG(0x80010020 + ((Nb) - 1)*0x00020000) /* UART Status Reg. 1 [1..3] */
+
+#define Ser1UTCR0 _UTCR0 (1) /* Ser. port 1 UART Control Reg. 0 */
+#define Ser1UTCR1 _UTCR1 (1) /* Ser. port 1 UART Control Reg. 1 */
+#define Ser1UTCR2 _UTCR2 (1) /* Ser. port 1 UART Control Reg. 2 */
+#define Ser1UTCR3 _UTCR3 (1) /* Ser. port 1 UART Control Reg. 3 */
+#define Ser1UTDR _UTDR (1) /* Ser. port 1 UART Data Reg. */
+#define Ser1UTSR0 _UTSR0 (1) /* Ser. port 1 UART Status Reg. 0 */
+#define Ser1UTSR1 _UTSR1 (1) /* Ser. port 1 UART Status Reg. 1 */
+
+#define Ser2UTCR0 _UTCR0 (2) /* Ser. port 2 UART Control Reg. 0 */
+#define Ser2UTCR1 _UTCR1 (2) /* Ser. port 2 UART Control Reg. 1 */
+#define Ser2UTCR2 _UTCR2 (2) /* Ser. port 2 UART Control Reg. 2 */
+#define Ser2UTCR3 _UTCR3 (2) /* Ser. port 2 UART Control Reg. 3 */
+#define Ser2UTCR4 _UTCR4 (2) /* Ser. port 2 UART Control Reg. 4 */
+#define Ser2UTDR _UTDR (2) /* Ser. port 2 UART Data Reg. */
+#define Ser2UTSR0 _UTSR0 (2) /* Ser. port 2 UART Status Reg. 0 */
+#define Ser2UTSR1 _UTSR1 (2) /* Ser. port 2 UART Status Reg. 1 */
+
+#define Ser3UTCR0 _UTCR0 (3) /* Ser. port 3 UART Control Reg. 0 */
+#define Ser3UTCR1 _UTCR1 (3) /* Ser. port 3 UART Control Reg. 1 */
+#define Ser3UTCR2 _UTCR2 (3) /* Ser. port 3 UART Control Reg. 2 */
+#define Ser3UTCR3 _UTCR3 (3) /* Ser. port 3 UART Control Reg. 3 */
+#define Ser3UTDR _UTDR (3) /* Ser. port 3 UART Data Reg. */
+#define Ser3UTSR0 _UTSR0 (3) /* Ser. port 3 UART Status Reg. 0 */
+#define Ser3UTSR1 _UTSR1 (3) /* Ser. port 3 UART Status Reg. 1 */
+
+/* Those are still used in some places */
+#define _Ser1UTCR0 __PREG(Ser1UTCR0)
+#define _Ser2UTCR0 __PREG(Ser2UTCR0)
+#define _Ser3UTCR0 __PREG(Ser3UTCR0)
+
+/* Register offsets */
+#define UTCR0 0x00
+#define UTCR1 0x04
+#define UTCR2 0x08
+#define UTCR3 0x0c
+#define UTDR 0x14
+#define UTSR0 0x1c
+#define UTSR1 0x20
+
+#define UTCR0_PE 0x00000001 /* Parity Enable */
+#define UTCR0_OES 0x00000002 /* Odd/Even parity Select */
+#define UTCR0_OddPar (UTCR0_OES*0) /* Odd Parity */
+#define UTCR0_EvenPar (UTCR0_OES*1) /* Even Parity */
+#define UTCR0_SBS 0x00000004 /* Stop Bit Select */
+#define UTCR0_1StpBit (UTCR0_SBS*0) /* 1 Stop Bit per frame */
+#define UTCR0_2StpBit (UTCR0_SBS*1) /* 2 Stop Bits per frame */
+#define UTCR0_DSS 0x00000008 /* Data Size Select */
+#define UTCR0_7BitData (UTCR0_DSS*0) /* 7-Bit Data */
+#define UTCR0_8BitData (UTCR0_DSS*1) /* 8-Bit Data */
+#define UTCR0_SCE 0x00000010 /* Sample Clock Enable */
+ /* (ser. port 1: GPIO [18], */
+ /* ser. port 3: GPIO [20]) */
+#define UTCR0_RCE 0x00000020 /* Receive Clock Edge select */
+#define UTCR0_RcRsEdg (UTCR0_RCE*0) /* Receive clock Rising-Edge */
+#define UTCR0_RcFlEdg (UTCR0_RCE*1) /* Receive clock Falling-Edge */
+#define UTCR0_TCE 0x00000040 /* Transmit Clock Edge select */
+#define UTCR0_TrRsEdg (UTCR0_TCE*0) /* Transmit clock Rising-Edge */
+#define UTCR0_TrFlEdg (UTCR0_TCE*1) /* Transmit clock Falling-Edge */
+#define UTCR0_Ser2IrDA /* Ser. port 2 IrDA settings */ \
+ (UTCR0_1StpBit + UTCR0_8BitData)
+
+#define UTCR1_BRD Fld (4, 0) /* Baud Rate Divisor/16 - 1 [11:8] */
+#define UTCR2_BRD Fld (8, 0) /* Baud Rate Divisor/16 - 1 [7:0] */
+ /* fua = fxtl/(16*(BRD[11:0] + 1)) */
+ /* Tua = 16*(BRD [11:0] + 1)*Txtl */
+#define UTCR1_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 >> FSize (UTCR2_BRD) << \
+ FShft (UTCR1_BRD))
+#define UTCR2_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 & FAlnMsk (UTCR2_BRD) << \
+ FShft (UTCR2_BRD))
+ /* fua = fxtl/(16*Floor (Div/16)) */
+ /* Tua = 16*Floor (Div/16)*Txtl */
+#define UTCR1_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 >> FSize (UTCR2_BRD) << \
+ FShft (UTCR1_BRD))
+#define UTCR2_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 & FAlnMsk (UTCR2_BRD) << \
+ FShft (UTCR2_BRD))
+ /* fua = fxtl/(16*Ceil (Div/16)) */
+ /* Tua = 16*Ceil (Div/16)*Txtl */
+
+#define UTCR3_RXE 0x00000001 /* Receive Enable */
+#define UTCR3_TXE 0x00000002 /* Transmit Enable */
+#define UTCR3_BRK 0x00000004 /* BReaK mode */
+#define UTCR3_RIE 0x00000008 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Interrupt Enable */
+#define UTCR3_TIE 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define UTCR3_LBM 0x00000020 /* Look-Back Mode */
+#define UTCR3_Ser2IrDA /* Ser. port 2 IrDA settings (RIE, */ \
+ /* TIE, LBM can be set or cleared) */ \
+ (UTCR3_RXE + UTCR3_TXE)
+
+#define UTCR4_HSE 0x00000001 /* Hewlett-Packard Serial InfraRed */
+ /* (HP-SIR) modulation Enable */
+#define UTCR4_NRZ (UTCR4_HSE*0) /* Non-Return to Zero modulation */
+#define UTCR4_HPSIR (UTCR4_HSE*1) /* HP-SIR modulation */
+#define UTCR4_LPM 0x00000002 /* Low-Power Mode */
+#define UTCR4_Z3_16Bit (UTCR4_LPM*0) /* Zero pulse = 3/16 Bit time */
+#define UTCR4_Z1_6us (UTCR4_LPM*1) /* Zero pulse = 1.6 us */
+
+#define UTDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define UTDR_PRE 0x00000100 /* receive PaRity Error (read) */
+#define UTDR_FRE 0x00000200 /* receive FRaming Error (read) */
+#define UTDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define UTSR0_TFS 0x00000001 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define UTSR0_RFS 0x00000002 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Service request (read) */
+#define UTSR0_RID 0x00000004 /* Receiver IDle */
+#define UTSR0_RBB 0x00000008 /* Receive Beginning of Break */
+#define UTSR0_REB 0x00000010 /* Receive End of Break */
+#define UTSR0_EIF 0x00000020 /* Error In FIFO (read) */
+
+#define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */
+#define UTSR1_RNE 0x00000002 /* Receive FIFO Not Empty (read) */
+#define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */
+#define UTSR1_PRE 0x00000008 /* receive PaRity Error (read) */
+#define UTSR1_FRE 0x00000010 /* receive FRaming Error (read) */
+#define UTSR1_ROR 0x00000020 /* Receive FIFO Over-Run (read) */
+
+
+/*
+ * Synchronous Data Link Controller (SDLC) control registers
+ *
+ * Registers
+ * Ser1SDCR0 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 0 (read/write).
+ * Ser1SDCR1 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 1 (read/write).
+ * Ser1SDCR2 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 2 (read/write).
+ * Ser1SDCR3 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 3 (read/write).
+ * Ser1SDCR4 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 4 (read/write).
+ * Ser1SDDR Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Data Register (read/write).
+ * Ser1SDSR0 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Status Register 0 (read/write).
+ * Ser1SDSR1 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Status Register 1 (read/write).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fsd, Tsd Frequency, period of the SDLC communication.
+ */
+
+#define Ser1SDCR0 __REG(0x80020060) /* Ser. port 1 SDLC Control Reg. 0 */
+#define Ser1SDCR1 __REG(0x80020064) /* Ser. port 1 SDLC Control Reg. 1 */
+#define Ser1SDCR2 __REG(0x80020068) /* Ser. port 1 SDLC Control Reg. 2 */
+#define Ser1SDCR3 __REG(0x8002006C) /* Ser. port 1 SDLC Control Reg. 3 */
+#define Ser1SDCR4 __REG(0x80020070) /* Ser. port 1 SDLC Control Reg. 4 */
+#define Ser1SDDR __REG(0x80020078) /* Ser. port 1 SDLC Data Reg. */
+#define Ser1SDSR0 __REG(0x80020080) /* Ser. port 1 SDLC Status Reg. 0 */
+#define Ser1SDSR1 __REG(0x80020084) /* Ser. port 1 SDLC Status Reg. 1 */
+
+#define SDCR0_SUS 0x00000001 /* SDLC/UART Select */
+#define SDCR0_SDLC (SDCR0_SUS*0) /* SDLC mode (TXD1 & RXD1) */
+#define SDCR0_UART (SDCR0_SUS*1) /* UART mode (TXD1 & RXD1) */
+#define SDCR0_SDF 0x00000002 /* Single/Double start Flag select */
+#define SDCR0_SglFlg (SDCR0_SDF*0) /* Single start Flag */
+#define SDCR0_DblFlg (SDCR0_SDF*1) /* Double start Flag */
+#define SDCR0_LBM 0x00000004 /* Look-Back Mode */
+#define SDCR0_BMS 0x00000008 /* Bit Modulation Select */
+#define SDCR0_FM0 (SDCR0_BMS*0) /* Freq. Modulation zero (0) */
+#define SDCR0_NRZ (SDCR0_BMS*1) /* Non-Return to Zero modulation */
+#define SDCR0_SCE 0x00000010 /* Sample Clock Enable (GPIO [16]) */
+#define SDCR0_SCD 0x00000020 /* Sample Clock Direction select */
+ /* (GPIO [16]) */
+#define SDCR0_SClkIn (SDCR0_SCD*0) /* Sample Clock Input */
+#define SDCR0_SClkOut (SDCR0_SCD*1) /* Sample Clock Output */
+#define SDCR0_RCE 0x00000040 /* Receive Clock Edge select */
+#define SDCR0_RcRsEdg (SDCR0_RCE*0) /* Receive clock Rising-Edge */
+#define SDCR0_RcFlEdg (SDCR0_RCE*1) /* Receive clock Falling-Edge */
+#define SDCR0_TCE 0x00000080 /* Transmit Clock Edge select */
+#define SDCR0_TrRsEdg (SDCR0_TCE*0) /* Transmit clock Rising-Edge */
+#define SDCR0_TrFlEdg (SDCR0_TCE*1) /* Transmit clock Falling-Edge */
+
+#define SDCR1_AAF 0x00000001 /* Abort After Frame enable */
+ /* (GPIO [17]) */
+#define SDCR1_TXE 0x00000002 /* Transmit Enable */
+#define SDCR1_RXE 0x00000004 /* Receive Enable */
+#define SDCR1_RIE 0x00000008 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Interrupt Enable */
+#define SDCR1_TIE 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define SDCR1_AME 0x00000020 /* Address Match Enable */
+#define SDCR1_TUS 0x00000040 /* Transmit FIFO Under-run Select */
+#define SDCR1_EFrmURn (SDCR1_TUS*0) /* End Frame on Under-Run */
+#define SDCR1_AbortURn (SDCR1_TUS*1) /* Abort on Under-Run */
+#define SDCR1_RAE 0x00000080 /* Receive Abort interrupt Enable */
+
+#define SDCR2_AMV Fld (8, 0) /* Address Match Value */
+
+#define SDCR3_BRD Fld (4, 0) /* Baud Rate Divisor/16 - 1 [11:8] */
+#define SDCR4_BRD Fld (8, 0) /* Baud Rate Divisor/16 - 1 [7:0] */
+ /* fsd = fxtl/(16*(BRD[11:0] + 1)) */
+ /* Tsd = 16*(BRD[11:0] + 1)*Txtl */
+#define SDCR3_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 >> FSize (SDCR4_BRD) << \
+ FShft (SDCR3_BRD))
+#define SDCR4_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 & FAlnMsk (SDCR4_BRD) << \
+ FShft (SDCR4_BRD))
+ /* fsd = fxtl/(16*Floor (Div/16)) */
+ /* Tsd = 16*Floor (Div/16)*Txtl */
+#define SDCR3_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 >> FSize (SDCR4_BRD) << \
+ FShft (SDCR3_BRD))
+#define SDCR4_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 & FAlnMsk (SDCR4_BRD) << \
+ FShft (SDCR4_BRD))
+ /* fsd = fxtl/(16*Ceil (Div/16)) */
+ /* Tsd = 16*Ceil (Div/16)*Txtl */
+
+#define SDDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define SDDR_EOF 0x00000100 /* receive End-Of-Frame (read) */
+#define SDDR_CRE 0x00000200 /* receive CRC Error (read) */
+#define SDDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define SDSR0_EIF 0x00000001 /* Error In FIFO (read) */
+#define SDSR0_TUR 0x00000002 /* Transmit FIFO Under-Run */
+#define SDSR0_RAB 0x00000004 /* Receive ABort */
+#define SDSR0_TFS 0x00000008 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define SDSR0_RFS 0x00000010 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Service request (read) */
+
+#define SDSR1_RSY 0x00000001 /* Receiver SYnchronized (read) */
+#define SDSR1_TBY 0x00000002 /* Transmitter BusY (read) */
+#define SDSR1_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define SDSR1_TNF 0x00000008 /* Transmit FIFO Not Full (read) */
+#define SDSR1_RTD 0x00000010 /* Receive Transition Detected */
+#define SDSR1_EOF 0x00000020 /* receive End-Of-Frame (read) */
+#define SDSR1_CRE 0x00000040 /* receive CRC Error (read) */
+#define SDSR1_ROR 0x00000080 /* Receive FIFO Over-Run (read) */
+
+
+/*
+ * High-Speed Serial to Parallel controller (HSSP) control registers
+ *
+ * Registers
+ * Ser2HSCR0 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 0 (read/write).
+ * Ser2HSCR1 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 1 (read/write).
+ * Ser2HSDR Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Data Register (read/write).
+ * Ser2HSSR0 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Status Register 0 (read/write).
+ * Ser2HSSR1 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Status Register 1 (read).
+ * Ser2HSCR2 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 2 (read/write).
+ * [The HSCR2 register is only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ */
+
+#define Ser2HSCR0 __REG(0x80040060) /* Ser. port 2 HSSP Control Reg. 0 */
+#define Ser2HSCR1 __REG(0x80040064) /* Ser. port 2 HSSP Control Reg. 1 */
+#define Ser2HSDR __REG(0x8004006C) /* Ser. port 2 HSSP Data Reg. */
+#define Ser2HSSR0 __REG(0x80040074) /* Ser. port 2 HSSP Status Reg. 0 */
+#define Ser2HSSR1 __REG(0x80040078) /* Ser. port 2 HSSP Status Reg. 1 */
+#define Ser2HSCR2 __REG(0x90060028) /* Ser. port 2 HSSP Control Reg. 2 */
+
+#define HSCR0_ITR 0x00000001 /* IrDA Transmission Rate */
+#define HSCR0_UART (HSCR0_ITR*0) /* UART mode (115.2 kb/s if IrDA) */
+#define HSCR0_HSSP (HSCR0_ITR*1) /* HSSP mode (4 Mb/s) */
+#define HSCR0_LBM 0x00000002 /* Look-Back Mode */
+#define HSCR0_TUS 0x00000004 /* Transmit FIFO Under-run Select */
+#define HSCR0_EFrmURn (HSCR0_TUS*0) /* End Frame on Under-Run */
+#define HSCR0_AbortURn (HSCR0_TUS*1) /* Abort on Under-Run */
+#define HSCR0_TXE 0x00000008 /* Transmit Enable */
+#define HSCR0_RXE 0x00000010 /* Receive Enable */
+#define HSCR0_RIE 0x00000020 /* Receive FIFO 2/5-to-3/5-full or */
+ /* more Interrupt Enable */
+#define HSCR0_TIE 0x00000040 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define HSCR0_AME 0x00000080 /* Address Match Enable */
+
+#define HSCR1_AMV Fld (8, 0) /* Address Match Value */
+
+#define HSDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define HSDR_EOF 0x00000100 /* receive End-Of-Frame (read) */
+#define HSDR_CRE 0x00000200 /* receive CRC Error (read) */
+#define HSDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define HSSR0_EIF 0x00000001 /* Error In FIFO (read) */
+#define HSSR0_TUR 0x00000002 /* Transmit FIFO Under-Run */
+#define HSSR0_RAB 0x00000004 /* Receive ABort */
+#define HSSR0_TFS 0x00000008 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define HSSR0_RFS 0x00000010 /* Receive FIFO 2/5-to-3/5-full or */
+ /* more Service request (read) */
+#define HSSR0_FRE 0x00000020 /* receive FRaming Error */
+
+#define HSSR1_RSY 0x00000001 /* Receiver SYnchronized (read) */
+#define HSSR1_TBY 0x00000002 /* Transmitter BusY (read) */
+#define HSSR1_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define HSSR1_TNF 0x00000008 /* Transmit FIFO Not Full (read) */
+#define HSSR1_EOF 0x00000010 /* receive End-Of-Frame (read) */
+#define HSSR1_CRE 0x00000020 /* receive CRC Error (read) */
+#define HSSR1_ROR 0x00000040 /* Receive FIFO Over-Run (read) */
+
+#define HSCR2_TXP 0x00040000 /* Transmit data Polarity (TXD_2) */
+#define HSCR2_TrDataL (HSCR2_TXP*0) /* Transmit Data active Low */
+ /* (inverted) */
+#define HSCR2_TrDataH (HSCR2_TXP*1) /* Transmit Data active High */
+ /* (non-inverted) */
+#define HSCR2_RXP 0x00080000 /* Receive data Polarity (RXD_2) */
+#define HSCR2_RcDataL (HSCR2_RXP*0) /* Receive Data active Low */
+ /* (inverted) */
+#define HSCR2_RcDataH (HSCR2_RXP*1) /* Receive Data active High */
+ /* (non-inverted) */
+
+
+/*
+ * Multi-media Communications Port (MCP) control registers
+ *
+ * Registers
+ * Ser4MCCR0 Serial port 4 Multi-media Communications Port (MCP)
+ * Control Register 0 (read/write).
+ * Ser4MCDR0 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 0 (audio, read/write).
+ * Ser4MCDR1 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 1 (telecom, read/write).
+ * Ser4MCDR2 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 2 (CODEC registers, read/write).
+ * Ser4MCSR Serial port 4 Multi-media Communications Port (MCP)
+ * Status Register (read/write).
+ * Ser4MCCR1 Serial port 4 Multi-media Communications Port (MCP)
+ * Control Register 1 (read/write).
+ * [The MCCR1 register is only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ *
+ * Clocks
+ * fmc, Tmc Frequency, period of the MCP communication (10 MHz,
+ * 12 MHz, or GPIO [21]).
+ * faud, Taud Frequency, period of the audio sampling.
+ * ftcm, Ttcm Frequency, period of the telecom sampling.
+ */
+
+#define Ser4MCCR0 __REG(0x80060000) /* Ser. port 4 MCP Control Reg. 0 */
+#define Ser4MCDR0 __REG(0x80060008) /* Ser. port 4 MCP Data Reg. 0 (audio) */
+#define Ser4MCDR1 __REG(0x8006000C) /* Ser. port 4 MCP Data Reg. 1 (telecom) */
+#define Ser4MCDR2 __REG(0x80060010) /* Ser. port 4 MCP Data Reg. 2 (CODEC reg.) */
+#define Ser4MCSR __REG(0x80060018) /* Ser. port 4 MCP Status Reg. */
+#define Ser4MCCR1 __REG(0x90060030) /* Ser. port 4 MCP Control Reg. 1 */
+
+#define MCCR0_ASD Fld (7, 0) /* Audio Sampling rate Divisor/32 */
+ /* [6..127] */
+ /* faud = fmc/(32*ASD) */
+ /* Taud = 32*ASD*Tmc */
+#define MCCR0_AudSmpDiv(Div) /* Audio Sampling rate Divisor */ \
+ /* [192..4064] */ \
+ ((Div)/32 << FShft (MCCR0_ASD))
+ /* faud = fmc/(32*Floor (Div/32)) */
+ /* Taud = 32*Floor (Div/32)*Tmc */
+#define MCCR0_CeilAudSmpDiv(Div) /* Ceil. of AudSmpDiv [192..4064] */ \
+ (((Div) + 31)/32 << FShft (MCCR0_ASD))
+ /* faud = fmc/(32*Ceil (Div/32)) */
+ /* Taud = 32*Ceil (Div/32)*Tmc */
+#define MCCR0_TSD Fld (7, 8) /* Telecom Sampling rate */
+ /* Divisor/32 [16..127] */
+ /* ftcm = fmc/(32*TSD) */
+ /* Ttcm = 32*TSD*Tmc */
+#define MCCR0_TcmSmpDiv(Div) /* Telecom Sampling rate Divisor */ \
+ /* [512..4064] */ \
+ ((Div)/32 << FShft (MCCR0_TSD))
+ /* ftcm = fmc/(32*Floor (Div/32)) */
+ /* Ttcm = 32*Floor (Div/32)*Tmc */
+#define MCCR0_CeilTcmSmpDiv(Div) /* Ceil. of TcmSmpDiv [512..4064] */ \
+ (((Div) + 31)/32 << FShft (MCCR0_TSD))
+ /* ftcm = fmc/(32*Ceil (Div/32)) */
+ /* Ttcm = 32*Ceil (Div/32)*Tmc */
+#define MCCR0_MCE 0x00010000 /* MCP Enable */
+#define MCCR0_ECS 0x00020000 /* External Clock Select */
+#define MCCR0_IntClk (MCCR0_ECS*0) /* Internal Clock (10 or 12 MHz) */
+#define MCCR0_ExtClk (MCCR0_ECS*1) /* External Clock (GPIO [21]) */
+#define MCCR0_ADM 0x00040000 /* A/D (audio/telecom) data */
+ /* sampling/storing Mode */
+#define MCCR0_VldBit (MCCR0_ADM*0) /* Valid Bit storing mode */
+#define MCCR0_SmpCnt (MCCR0_ADM*1) /* Sampling Counter storing mode */
+#define MCCR0_TTE 0x00080000 /* Telecom Transmit FIFO 1/2-full */
+ /* or less interrupt Enable */
+#define MCCR0_TRE 0x00100000 /* Telecom Receive FIFO 1/2-full */
+ /* or more interrupt Enable */
+#define MCCR0_ATE 0x00200000 /* Audio Transmit FIFO 1/2-full */
+ /* or less interrupt Enable */
+#define MCCR0_ARE 0x00400000 /* Audio Receive FIFO 1/2-full or */
+ /* more interrupt Enable */
+#define MCCR0_LBM 0x00800000 /* Look-Back Mode */
+#define MCCR0_ECP Fld (2, 24) /* External Clock Prescaler - 1 */
+#define MCCR0_ExtClkDiv(Div) /* External Clock Divisor [1..4] */ \
+ (((Div) - 1) << FShft (MCCR0_ECP))
+
+#define MCDR0_DATA Fld (12, 4) /* receive/transmit audio DATA */
+ /* FIFOs */
+
+#define MCDR1_DATA Fld (14, 2) /* receive/transmit telecom DATA */
+ /* FIFOs */
+
+ /* receive/transmit CODEC reg. */
+ /* FIFOs: */
+#define MCDR2_DATA Fld (16, 0) /* reg. DATA */
+#define MCDR2_RW 0x00010000 /* reg. Read/Write (transmit) */
+#define MCDR2_Rd (MCDR2_RW*0) /* reg. Read */
+#define MCDR2_Wr (MCDR2_RW*1) /* reg. Write */
+#define MCDR2_ADD Fld (4, 17) /* reg. ADDress */
+
+#define MCSR_ATS 0x00000001 /* Audio Transmit FIFO 1/2-full */
+ /* or less Service request (read) */
+#define MCSR_ARS 0x00000002 /* Audio Receive FIFO 1/2-full or */
+ /* more Service request (read) */
+#define MCSR_TTS 0x00000004 /* Telecom Transmit FIFO 1/2-full */
+ /* or less Service request (read) */
+#define MCSR_TRS 0x00000008 /* Telecom Receive FIFO 1/2-full */
+ /* or more Service request (read) */
+#define MCSR_ATU 0x00000010 /* Audio Transmit FIFO Under-run */
+#define MCSR_ARO 0x00000020 /* Audio Receive FIFO Over-run */
+#define MCSR_TTU 0x00000040 /* Telecom Transmit FIFO Under-run */
+#define MCSR_TRO 0x00000080 /* Telecom Receive FIFO Over-run */
+#define MCSR_ANF 0x00000100 /* Audio transmit FIFO Not Full */
+ /* (read) */
+#define MCSR_ANE 0x00000200 /* Audio receive FIFO Not Empty */
+ /* (read) */
+#define MCSR_TNF 0x00000400 /* Telecom transmit FIFO Not Full */
+ /* (read) */
+#define MCSR_TNE 0x00000800 /* Telecom receive FIFO Not Empty */
+ /* (read) */
+#define MCSR_CWC 0x00001000 /* CODEC register Write Completed */
+ /* (read) */
+#define MCSR_CRC 0x00002000 /* CODEC register Read Completed */
+ /* (read) */
+#define MCSR_ACE 0x00004000 /* Audio CODEC Enabled (read) */
+#define MCSR_TCE 0x00008000 /* Telecom CODEC Enabled (read) */
+
+#define MCCR1_CFS 0x00100000 /* Clock Freq. Select */
+#define MCCR1_F12MHz (MCCR1_CFS*0) /* Freq. (fmc) = ~ 12 MHz */
+ /* (11.981 MHz) */
+#define MCCR1_F10MHz (MCCR1_CFS*1) /* Freq. (fmc) = ~ 10 MHz */
+ /* (9.585 MHz) */
+
+
+/*
+ * Synchronous Serial Port (SSP) control registers
+ *
+ * Registers
+ * Ser4SSCR0 Serial port 4 Synchronous Serial Port (SSP) Control
+ * Register 0 (read/write).
+ * Ser4SSCR1 Serial port 4 Synchronous Serial Port (SSP) Control
+ * Register 1 (read/write).
+ * [Bits SPO and SP are only implemented in versions 2.0
+ * (rev. = 8) and higher of the StrongARM SA-1100.]
+ * Ser4SSDR Serial port 4 Synchronous Serial Port (SSP) Data
+ * Register (read/write).
+ * Ser4SSSR Serial port 4 Synchronous Serial Port (SSP) Status
+ * Register (read/write).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fss, Tss Frequency, period of the SSP communication.
+ */
+
+#define Ser4SSCR0 __REG(0x80070060) /* Ser. port 4 SSP Control Reg. 0 */
+#define Ser4SSCR1 __REG(0x80070064) /* Ser. port 4 SSP Control Reg. 1 */
+#define Ser4SSDR __REG(0x8007006C) /* Ser. port 4 SSP Data Reg. */
+#define Ser4SSSR __REG(0x80070074) /* Ser. port 4 SSP Status Reg. */
+
+#define SSCR0_DSS Fld (4, 0) /* Data Size - 1 Select [3..15] */
+#define SSCR0_DataSize(Size) /* Data Size Select [4..16] */ \
+ (((Size) - 1) << FShft (SSCR0_DSS))
+#define SSCR0_FRF Fld (2, 4) /* FRame Format */
+#define SSCR0_Motorola /* Motorola Serial Peripheral */ \
+ /* Interface (SPI) format */ \
+ (0 << FShft (SSCR0_FRF))
+#define SSCR0_TI /* Texas Instruments Synchronous */ \
+ /* Serial format */ \
+ (1 << FShft (SSCR0_FRF))
+#define SSCR0_National /* National Microwire format */ \
+ (2 << FShft (SSCR0_FRF))
+#define SSCR0_SSE 0x00000080 /* SSP Enable */
+#define SSCR0_SCR Fld (8, 8) /* Serial Clock Rate divisor/2 - 1 */
+ /* fss = fxtl/(2*(SCR + 1)) */
+ /* Tss = 2*(SCR + 1)*Txtl */
+#define SSCR0_SerClkDiv(Div) /* Serial Clock Divisor [2..512] */ \
+ (((Div) - 2)/2 << FShft (SSCR0_SCR))
+ /* fss = fxtl/(2*Floor (Div/2)) */
+ /* Tss = 2*Floor (Div/2)*Txtl */
+#define SSCR0_CeilSerClkDiv(Div) /* Ceil. of SerClkDiv [2..512] */ \
+ (((Div) - 1)/2 << FShft (SSCR0_SCR))
+ /* fss = fxtl/(2*Ceil (Div/2)) */
+ /* Tss = 2*Ceil (Div/2)*Txtl */
+
+#define SSCR1_RIE 0x00000001 /* Receive FIFO 1/2-full or more */
+ /* Interrupt Enable */
+#define SSCR1_TIE 0x00000002 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define SSCR1_LBM 0x00000004 /* Look-Back Mode */
+#define SSCR1_SPO 0x00000008 /* Sample clock (SCLK) POlarity */
+#define SSCR1_SClkIactL (SSCR1_SPO*0) /* Sample Clock Inactive Low */
+#define SSCR1_SClkIactH (SSCR1_SPO*1) /* Sample Clock Inactive High */
+#define SSCR1_SP 0x00000010 /* Sample clock (SCLK) Phase */
+#define SSCR1_SClk1P (SSCR1_SP*0) /* Sample Clock active 1 Period */
+ /* after frame (SFRM, 1st edge) */
+#define SSCR1_SClk1_2P (SSCR1_SP*1) /* Sample Clock active 1/2 Period */
+ /* after frame (SFRM, 1st edge) */
+#define SSCR1_ECS 0x00000020 /* External Clock Select */
+#define SSCR1_IntClk (SSCR1_ECS*0) /* Internal Clock */
+#define SSCR1_ExtClk (SSCR1_ECS*1) /* External Clock (GPIO [19]) */
+
+#define SSDR_DATA Fld (16, 0) /* receive/transmit DATA FIFOs */
+
+#define SSSR_TNF 0x00000002 /* Transmit FIFO Not Full (read) */
+#define SSSR_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define SSSR_BSY 0x00000008 /* SSP BuSY (read) */
+#define SSSR_TFS 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define SSSR_RFS 0x00000020 /* Receive FIFO 1/2-full or more */
+ /* Service request (read) */
+#define SSSR_ROR 0x00000040 /* Receive FIFO Over-Run */
+
+
+/*
+ * Operating System (OS) timer control registers
+ *
+ * Registers
+ * OSMR0 Operating System (OS) timer Match Register 0
+ * (read/write).
+ * OSMR1 Operating System (OS) timer Match Register 1
+ * (read/write).
+ * OSMR2 Operating System (OS) timer Match Register 2
+ * (read/write).
+ * OSMR3 Operating System (OS) timer Match Register 3
+ * (read/write).
+ * OSCR Operating System (OS) timer Counter Register
+ * (read/write).
+ * OSSR Operating System (OS) timer Status Register
+ * (read/write).
+ * OWER Operating System (OS) timer Watch-dog Enable Register
+ * (read/write).
+ * OIER Operating System (OS) timer Interrupt Enable Register
+ * (read/write).
+ */
+
+#define OSMR0 __REG(0x90000000) /* OS timer Match Reg. 0 */
+#define OSMR1 __REG(0x90000004) /* OS timer Match Reg. 1 */
+#define OSMR2 __REG(0x90000008) /* OS timer Match Reg. 2 */
+#define OSMR3 __REG(0x9000000c) /* OS timer Match Reg. 3 */
+#define OSCR __REG(0x90000010) /* OS timer Counter Reg. */
+#define OSSR __REG(0x90000014 ) /* OS timer Status Reg. */
+#define OWER __REG(0x90000018 ) /* OS timer Watch-dog Enable Reg. */
+#define OIER __REG(0x9000001C ) /* OS timer Interrupt Enable Reg. */
+
+#define OSSR_M(Nb) /* Match detected [0..3] */ \
+ (0x00000001 << (Nb))
+#define OSSR_M0 OSSR_M (0) /* Match detected 0 */
+#define OSSR_M1 OSSR_M (1) /* Match detected 1 */
+#define OSSR_M2 OSSR_M (2) /* Match detected 2 */
+#define OSSR_M3 OSSR_M (3) /* Match detected 3 */
+
+#define OWER_WME 0x00000001 /* Watch-dog Match Enable */
+ /* (set only) */
+
+#define OIER_E(Nb) /* match interrupt Enable [0..3] */ \
+ (0x00000001 << (Nb))
+#define OIER_E0 OIER_E (0) /* match interrupt Enable 0 */
+#define OIER_E1 OIER_E (1) /* match interrupt Enable 1 */
+#define OIER_E2 OIER_E (2) /* match interrupt Enable 2 */
+#define OIER_E3 OIER_E (3) /* match interrupt Enable 3 */
+
+
+/*
+ * Real-Time Clock (RTC) control registers
+ *
+ * Registers
+ * RTAR Real-Time Clock (RTC) Alarm Register (read/write).
+ * RCNR Real-Time Clock (RTC) CouNt Register (read/write).
+ * RTTR Real-Time Clock (RTC) Trim Register (read/write).
+ * RTSR Real-Time Clock (RTC) Status Register (read/write).
+ *
+ * Clocks
+ * frtx, Trtx Frequency, period of the real-time clock crystal
+ * (32.768 kHz nominal).
+ * frtc, Trtc Frequency, period of the real-time clock counter
+ * (1 Hz nominal).
+ */
+
+#define RTAR __REG(0x90010000) /* RTC Alarm Reg. */
+#define RCNR __REG(0x90010004) /* RTC CouNt Reg. */
+#define RTTR __REG(0x90010008) /* RTC Trim Reg. */
+#define RTSR __REG(0x90010010) /* RTC Status Reg. */
+
+#define RTTR_C Fld (16, 0) /* clock divider Count - 1 */
+#define RTTR_D Fld (10, 16) /* trim Delete count */
+ /* frtc = (1023*(C + 1) - D)*frtx/ */
+ /* (1023*(C + 1)^2) */
+ /* Trtc = (1023*(C + 1)^2)*Trtx/ */
+ /* (1023*(C + 1) - D) */
+
+#define RTSR_AL 0x00000001 /* ALarm detected */
+#define RTSR_HZ 0x00000002 /* 1 Hz clock detected */
+#define RTSR_ALE 0x00000004 /* ALarm interrupt Enable */
+#define RTSR_HZE 0x00000008 /* 1 Hz clock interrupt Enable */
+
+
+/*
+ * Power Manager (PM) control registers
+ *
+ * Registers
+ * PMCR Power Manager (PM) Control Register (read/write).
+ * PSSR Power Manager (PM) Sleep Status Register (read/write).
+ * PSPR Power Manager (PM) Scratch-Pad Register (read/write).
+ * PWER Power Manager (PM) Wake-up Enable Register
+ * (read/write).
+ * PCFR Power Manager (PM) general ConFiguration Register
+ * (read/write).
+ * PPCR Power Manager (PM) Phase-Locked Loop (PLL)
+ * Configuration Register (read/write).
+ * PGSR Power Manager (PM) General-Purpose Input/Output (GPIO)
+ * Sleep state Register (read/write, see GPIO pins).
+ * POSR Power Manager (PM) Oscillator Status Register (read).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ */
+
+#define PMCR __REG(0x90020000) /* PM Control Reg. */
+#define PSSR __REG(0x90020004) /* PM Sleep Status Reg. */
+#define PSPR __REG(0x90020008) /* PM Scratch-Pad Reg. */
+#define PWER __REG(0x9002000C) /* PM Wake-up Enable Reg. */
+#define PCFR __REG(0x90020010) /* PM general ConFiguration Reg. */
+#define PPCR __REG(0x90020014) /* PM PLL Configuration Reg. */
+#define PGSR __REG(0x90020018) /* PM GPIO Sleep state Reg. */
+#define POSR __REG(0x9002001C) /* PM Oscillator Status Reg. */
+
+#define PMCR_SF 0x00000001 /* Sleep Force (set only) */
+
+#define PSSR_SS 0x00000001 /* Software Sleep */
+#define PSSR_BFS 0x00000002 /* Battery Fault Status */
+ /* (BATT_FAULT) */
+#define PSSR_VFS 0x00000004 /* Vdd Fault Status (VDD_FAULT) */
+#define PSSR_DH 0x00000008 /* DRAM control Hold */
+#define PSSR_PH 0x00000010 /* Peripheral control Hold */
+
+#define PWER_GPIO(Nb) GPIO_GPIO (Nb) /* GPIO [0..27] wake-up enable */
+#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */
+#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */
+#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */
+#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */
+#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */
+#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */
+#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */
+#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */
+#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */
+#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */
+#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */
+#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */
+#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */
+#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */
+#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */
+#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */
+#define PWER_GPIO16 PWER_GPIO (16) /* GPIO [16] wake-up enable */
+#define PWER_GPIO17 PWER_GPIO (17) /* GPIO [17] wake-up enable */
+#define PWER_GPIO18 PWER_GPIO (18) /* GPIO [18] wake-up enable */
+#define PWER_GPIO19 PWER_GPIO (19) /* GPIO [19] wake-up enable */
+#define PWER_GPIO20 PWER_GPIO (20) /* GPIO [20] wake-up enable */
+#define PWER_GPIO21 PWER_GPIO (21) /* GPIO [21] wake-up enable */
+#define PWER_GPIO22 PWER_GPIO (22) /* GPIO [22] wake-up enable */
+#define PWER_GPIO23 PWER_GPIO (23) /* GPIO [23] wake-up enable */
+#define PWER_GPIO24 PWER_GPIO (24) /* GPIO [24] wake-up enable */
+#define PWER_GPIO25 PWER_GPIO (25) /* GPIO [25] wake-up enable */
+#define PWER_GPIO26 PWER_GPIO (26) /* GPIO [26] wake-up enable */
+#define PWER_GPIO27 PWER_GPIO (27) /* GPIO [27] wake-up enable */
+#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
+
+#define PCFR_OPDE 0x00000001 /* Oscillator Power-Down Enable */
+#define PCFR_ClkRun (PCFR_OPDE*0) /* Clock Running in sleep mode */
+#define PCFR_ClkStp (PCFR_OPDE*1) /* Clock Stopped in sleep mode */
+#define PCFR_FP 0x00000002 /* Float PCMCIA pins */
+#define PCFR_PCMCIANeg (PCFR_FP*0) /* PCMCIA pins Negated (1) */
+#define PCFR_PCMCIAFlt (PCFR_FP*1) /* PCMCIA pins Floating */
+#define PCFR_FS 0x00000004 /* Float Static memory pins */
+#define PCFR_StMemNeg (PCFR_FS*0) /* Static Memory pins Negated (1) */
+#define PCFR_StMemFlt (PCFR_FS*1) /* Static Memory pins Floating */
+#define PCFR_FO 0x00000008 /* Force RTC oscillator */
+ /* (32.768 kHz) enable On */
+
+#define PPCR_CCF Fld (5, 0) /* CPU core Clock (CCLK) Freq. */
+#define PPCR_Fx16 /* Freq. x 16 (fcpu = 16*fxtl) */ \
+ (0x00 << FShft (PPCR_CCF))
+#define PPCR_Fx20 /* Freq. x 20 (fcpu = 20*fxtl) */ \
+ (0x01 << FShft (PPCR_CCF))
+#define PPCR_Fx24 /* Freq. x 24 (fcpu = 24*fxtl) */ \
+ (0x02 << FShft (PPCR_CCF))
+#define PPCR_Fx28 /* Freq. x 28 (fcpu = 28*fxtl) */ \
+ (0x03 << FShft (PPCR_CCF))
+#define PPCR_Fx32 /* Freq. x 32 (fcpu = 32*fxtl) */ \
+ (0x04 << FShft (PPCR_CCF))
+#define PPCR_Fx36 /* Freq. x 36 (fcpu = 36*fxtl) */ \
+ (0x05 << FShft (PPCR_CCF))
+#define PPCR_Fx40 /* Freq. x 40 (fcpu = 40*fxtl) */ \
+ (0x06 << FShft (PPCR_CCF))
+#define PPCR_Fx44 /* Freq. x 44 (fcpu = 44*fxtl) */ \
+ (0x07 << FShft (PPCR_CCF))
+#define PPCR_Fx48 /* Freq. x 48 (fcpu = 48*fxtl) */ \
+ (0x08 << FShft (PPCR_CCF))
+#define PPCR_Fx52 /* Freq. x 52 (fcpu = 52*fxtl) */ \
+ (0x09 << FShft (PPCR_CCF))
+#define PPCR_Fx56 /* Freq. x 56 (fcpu = 56*fxtl) */ \
+ (0x0A << FShft (PPCR_CCF))
+#define PPCR_Fx60 /* Freq. x 60 (fcpu = 60*fxtl) */ \
+ (0x0B << FShft (PPCR_CCF))
+#define PPCR_Fx64 /* Freq. x 64 (fcpu = 64*fxtl) */ \
+ (0x0C << FShft (PPCR_CCF))
+#define PPCR_Fx68 /* Freq. x 68 (fcpu = 68*fxtl) */ \
+ (0x0D << FShft (PPCR_CCF))
+#define PPCR_Fx72 /* Freq. x 72 (fcpu = 72*fxtl) */ \
+ (0x0E << FShft (PPCR_CCF))
+#define PPCR_Fx76 /* Freq. x 76 (fcpu = 76*fxtl) */ \
+ (0x0F << FShft (PPCR_CCF))
+ /* 3.6864 MHz crystal (fxtl): */
+#define PPCR_F59_0MHz PPCR_Fx16 /* Freq. (fcpu) = 59.0 MHz */
+#define PPCR_F73_7MHz PPCR_Fx20 /* Freq. (fcpu) = 73.7 MHz */
+#define PPCR_F88_5MHz PPCR_Fx24 /* Freq. (fcpu) = 88.5 MHz */
+#define PPCR_F103_2MHz PPCR_Fx28 /* Freq. (fcpu) = 103.2 MHz */
+#define PPCR_F118_0MHz PPCR_Fx32 /* Freq. (fcpu) = 118.0 MHz */
+#define PPCR_F132_7MHz PPCR_Fx36 /* Freq. (fcpu) = 132.7 MHz */
+#define PPCR_F147_5MHz PPCR_Fx40 /* Freq. (fcpu) = 147.5 MHz */
+#define PPCR_F162_2MHz PPCR_Fx44 /* Freq. (fcpu) = 162.2 MHz */
+#define PPCR_F176_9MHz PPCR_Fx48 /* Freq. (fcpu) = 176.9 MHz */
+#define PPCR_F191_7MHz PPCR_Fx52 /* Freq. (fcpu) = 191.7 MHz */
+#define PPCR_F206_4MHz PPCR_Fx56 /* Freq. (fcpu) = 206.4 MHz */
+#define PPCR_F221_2MHz PPCR_Fx60 /* Freq. (fcpu) = 221.2 MHz */
+#define PPCR_F239_6MHz PPCR_Fx64 /* Freq. (fcpu) = 239.6 MHz */
+#define PPCR_F250_7MHz PPCR_Fx68 /* Freq. (fcpu) = 250.7 MHz */
+#define PPCR_F265_4MHz PPCR_Fx72 /* Freq. (fcpu) = 265.4 MHz */
+#define PPCR_F280_2MHz PPCR_Fx76 /* Freq. (fcpu) = 280.2 MHz */
+ /* 3.5795 MHz crystal (fxtl): */
+#define PPCR_F57_3MHz PPCR_Fx16 /* Freq. (fcpu) = 57.3 MHz */
+#define PPCR_F71_6MHz PPCR_Fx20 /* Freq. (fcpu) = 71.6 MHz */
+#define PPCR_F85_9MHz PPCR_Fx24 /* Freq. (fcpu) = 85.9 MHz */
+#define PPCR_F100_2MHz PPCR_Fx28 /* Freq. (fcpu) = 100.2 MHz */
+#define PPCR_F114_5MHz PPCR_Fx32 /* Freq. (fcpu) = 114.5 MHz */
+#define PPCR_F128_9MHz PPCR_Fx36 /* Freq. (fcpu) = 128.9 MHz */
+#define PPCR_F143_2MHz PPCR_Fx40 /* Freq. (fcpu) = 143.2 MHz */
+#define PPCR_F157_5MHz PPCR_Fx44 /* Freq. (fcpu) = 157.5 MHz */
+#define PPCR_F171_8MHz PPCR_Fx48 /* Freq. (fcpu) = 171.8 MHz */
+#define PPCR_F186_1MHz PPCR_Fx52 /* Freq. (fcpu) = 186.1 MHz */
+#define PPCR_F200_5MHz PPCR_Fx56 /* Freq. (fcpu) = 200.5 MHz */
+#define PPCR_F214_8MHz PPCR_Fx60 /* Freq. (fcpu) = 214.8 MHz */
+#define PPCR_F229_1MHz PPCR_Fx64 /* Freq. (fcpu) = 229.1 MHz */
+#define PPCR_F243_4MHz PPCR_Fx68 /* Freq. (fcpu) = 243.4 MHz */
+#define PPCR_F257_7MHz PPCR_Fx72 /* Freq. (fcpu) = 257.7 MHz */
+#define PPCR_F272_0MHz PPCR_Fx76 /* Freq. (fcpu) = 272.0 MHz */
+
+#define POSR_OOK 0x00000001 /* RTC Oscillator (32.768 kHz) OK */
+
+
+/*
+ * Reset Controller (RC) control registers
+ *
+ * Registers
+ * RSRR Reset Controller (RC) Software Reset Register
+ * (read/write).
+ * RCSR Reset Controller (RC) Status Register (read/write).
+ */
+
+#define RSRR __REG(0x90030000) /* RC Software Reset Reg. */
+#define RCSR __REG(0x90030004) /* RC Status Reg. */
+
+#define RSRR_SWR 0x00000001 /* SoftWare Reset (set only) */
+
+#define RCSR_HWR 0x00000001 /* HardWare Reset */
+#define RCSR_SWR 0x00000002 /* SoftWare Reset */
+#define RCSR_WDR 0x00000004 /* Watch-Dog Reset */
+#define RCSR_SMR 0x00000008 /* Sleep-Mode Reset */
+
+
+/*
+ * Test unit control registers
+ *
+ * Registers
+ * TUCR Test Unit Control Register (read/write).
+ */
+
+#define TUCR __REG(0x90030008) /* Test Unit Control Reg. */
+
+#define TUCR_TIC 0x00000040 /* TIC mode */
+#define TUCR_TTST 0x00000080 /* Trim TeST mode */
+#define TUCR_RCRC 0x00000100 /* Richard's Cyclic Redundancy */
+ /* Check */
+#define TUCR_PMD 0x00000200 /* Power Management Disable */
+#define TUCR_MR 0x00000400 /* Memory Request mode */
+#define TUCR_NoMB (TUCR_MR*0) /* No Memory Bus request & grant */
+#define TUCR_MBGPIO (TUCR_MR*1) /* Memory Bus request (MBREQ) & */
+ /* grant (MBGNT) on GPIO [22:21] */
+#define TUCR_CTB Fld (3, 20) /* Clock Test Bits */
+#define TUCR_FDC 0x00800000 /* RTC Force Delete Count */
+#define TUCR_FMC 0x01000000 /* Force Michelle's Control mode */
+#define TUCR_TMC 0x02000000 /* RTC Trimmer Multiplexer Control */
+#define TUCR_DPS 0x04000000 /* Disallow Pad Sleep */
+#define TUCR_TSEL Fld (3, 29) /* clock Test SELect on GPIO [27] */
+#define TUCR_32_768kHz /* 32.768 kHz osc. on GPIO [27] */ \
+ (0 << FShft (TUCR_TSEL))
+#define TUCR_3_6864MHz /* 3.6864 MHz osc. on GPIO [27] */ \
+ (1 << FShft (TUCR_TSEL))
+#define TUCR_VDD /* VDD ring osc./16 on GPIO [27] */ \
+ (2 << FShft (TUCR_TSEL))
+#define TUCR_96MHzPLL /* 96 MHz PLL/4 on GPIO [27] */ \
+ (3 << FShft (TUCR_TSEL))
+#define TUCR_Clock /* internal (fcpu/2) & 32.768 kHz */ \
+ /* Clocks on GPIO [26:27] */ \
+ (4 << FShft (TUCR_TSEL))
+#define TUCR_3_6864MHzA /* 3.6864 MHz osc. on GPIO [27] */ \
+ /* (Alternative) */ \
+ (5 << FShft (TUCR_TSEL))
+#define TUCR_MainPLL /* Main PLL/16 on GPIO [27] */ \
+ (6 << FShft (TUCR_TSEL))
+#define TUCR_VDDL /* VDDL ring osc./4 on GPIO [27] */ \
+ (7 << FShft (TUCR_TSEL))
+
+
+/*
+ * General-Purpose Input/Output (GPIO) control registers
+ *
+ * Registers
+ * GPLR General-Purpose Input/Output (GPIO) Pin Level
+ * Register (read).
+ * GPDR General-Purpose Input/Output (GPIO) Pin Direction
+ * Register (read/write).
+ * GPSR General-Purpose Input/Output (GPIO) Pin output Set
+ * Register (write).
+ * GPCR General-Purpose Input/Output (GPIO) Pin output Clear
+ * Register (write).
+ * GRER General-Purpose Input/Output (GPIO) Rising-Edge
+ * detect Register (read/write).
+ * GFER General-Purpose Input/Output (GPIO) Falling-Edge
+ * detect Register (read/write).
+ * GEDR General-Purpose Input/Output (GPIO) Edge Detect
+ * status Register (read/write).
+ * GAFR General-Purpose Input/Output (GPIO) Alternate
+ * Function Register (read/write).
+ *
+ * Clock
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ */
+
+#define GPLR __REG(0x90040000) /* GPIO Pin Level Reg. */
+#define GPDR __REG(0x90040004) /* GPIO Pin Direction Reg. */
+#define GPSR __REG(0x90040008) /* GPIO Pin output Set Reg. */
+#define GPCR __REG(0x9004000C) /* GPIO Pin output Clear Reg. */
+#define GRER __REG(0x90040010) /* GPIO Rising-Edge detect Reg. */
+#define GFER __REG(0x90040014) /* GPIO Falling-Edge detect Reg. */
+#define GEDR __REG(0x90040018) /* GPIO Edge Detect status Reg. */
+#define GAFR __REG(0x9004001C) /* GPIO Alternate Function Reg. */
+
+#define GPIO_MIN (0)
+#define GPIO_MAX (27)
+
+#define GPIO_GPIO(Nb) /* GPIO [0..27] */ \
+ (0x00000001 << (Nb))
+#define GPIO_GPIO0 GPIO_GPIO (0) /* GPIO [0] */
+#define GPIO_GPIO1 GPIO_GPIO (1) /* GPIO [1] */
+#define GPIO_GPIO2 GPIO_GPIO (2) /* GPIO [2] */
+#define GPIO_GPIO3 GPIO_GPIO (3) /* GPIO [3] */
+#define GPIO_GPIO4 GPIO_GPIO (4) /* GPIO [4] */
+#define GPIO_GPIO5 GPIO_GPIO (5) /* GPIO [5] */
+#define GPIO_GPIO6 GPIO_GPIO (6) /* GPIO [6] */
+#define GPIO_GPIO7 GPIO_GPIO (7) /* GPIO [7] */
+#define GPIO_GPIO8 GPIO_GPIO (8) /* GPIO [8] */
+#define GPIO_GPIO9 GPIO_GPIO (9) /* GPIO [9] */
+#define GPIO_GPIO10 GPIO_GPIO (10) /* GPIO [10] */
+#define GPIO_GPIO11 GPIO_GPIO (11) /* GPIO [11] */
+#define GPIO_GPIO12 GPIO_GPIO (12) /* GPIO [12] */
+#define GPIO_GPIO13 GPIO_GPIO (13) /* GPIO [13] */
+#define GPIO_GPIO14 GPIO_GPIO (14) /* GPIO [14] */
+#define GPIO_GPIO15 GPIO_GPIO (15) /* GPIO [15] */
+#define GPIO_GPIO16 GPIO_GPIO (16) /* GPIO [16] */
+#define GPIO_GPIO17 GPIO_GPIO (17) /* GPIO [17] */
+#define GPIO_GPIO18 GPIO_GPIO (18) /* GPIO [18] */
+#define GPIO_GPIO19 GPIO_GPIO (19) /* GPIO [19] */
+#define GPIO_GPIO20 GPIO_GPIO (20) /* GPIO [20] */
+#define GPIO_GPIO21 GPIO_GPIO (21) /* GPIO [21] */
+#define GPIO_GPIO22 GPIO_GPIO (22) /* GPIO [22] */
+#define GPIO_GPIO23 GPIO_GPIO (23) /* GPIO [23] */
+#define GPIO_GPIO24 GPIO_GPIO (24) /* GPIO [24] */
+#define GPIO_GPIO25 GPIO_GPIO (25) /* GPIO [25] */
+#define GPIO_GPIO26 GPIO_GPIO (26) /* GPIO [26] */
+#define GPIO_GPIO27 GPIO_GPIO (27) /* GPIO [27] */
+
+#define GPIO_LDD(Nb) /* LCD Data [8..15] (O) */ \
+ GPIO_GPIO ((Nb) - 6)
+#define GPIO_LDD8 GPIO_LDD (8) /* LCD Data [8] (O) */
+#define GPIO_LDD9 GPIO_LDD (9) /* LCD Data [9] (O) */
+#define GPIO_LDD10 GPIO_LDD (10) /* LCD Data [10] (O) */
+#define GPIO_LDD11 GPIO_LDD (11) /* LCD Data [11] (O) */
+#define GPIO_LDD12 GPIO_LDD (12) /* LCD Data [12] (O) */
+#define GPIO_LDD13 GPIO_LDD (13) /* LCD Data [13] (O) */
+#define GPIO_LDD14 GPIO_LDD (14) /* LCD Data [14] (O) */
+#define GPIO_LDD15 GPIO_LDD (15) /* LCD Data [15] (O) */
+ /* ser. port 4: */
+#define GPIO_SSP_TXD GPIO_GPIO (10) /* SSP Transmit Data (O) */
+#define GPIO_SSP_RXD GPIO_GPIO (11) /* SSP Receive Data (I) */
+#define GPIO_SSP_SCLK GPIO_GPIO (12) /* SSP Sample CLocK (O) */
+#define GPIO_SSP_SFRM GPIO_GPIO (13) /* SSP Sample FRaMe (O) */
+ /* ser. port 1: */
+#define GPIO_UART_TXD GPIO_GPIO (14) /* UART Transmit Data (O) */
+#define GPIO_UART_RXD GPIO_GPIO (15) /* UART Receive Data (I) */
+#define GPIO_SDLC_SCLK GPIO_GPIO (16) /* SDLC Sample CLocK (I/O) */
+#define GPIO_SDLC_AAF GPIO_GPIO (17) /* SDLC Abort After Frame (O) */
+#define GPIO_UART_SCLK1 GPIO_GPIO (18) /* UART Sample CLocK 1 (I) */
+ /* ser. port 4: */
+#define GPIO_SSP_CLK GPIO_GPIO (19) /* SSP external CLocK (I) */
+ /* ser. port 3: */
+#define GPIO_UART_SCLK3 GPIO_GPIO (20) /* UART Sample CLocK 3 (I) */
+ /* ser. port 4: */
+#define GPIO_MCP_CLK GPIO_GPIO (21) /* MCP CLocK (I) */
+ /* test controller: */
+#define GPIO_TIC_ACK GPIO_GPIO (21) /* TIC ACKnowledge (O) */
+#define GPIO_MBGNT GPIO_GPIO (21) /* Memory Bus GraNT (O) */
+#define GPIO_TREQA GPIO_GPIO (22) /* TIC REQuest A (I) */
+#define GPIO_MBREQ GPIO_GPIO (22) /* Memory Bus REQuest (I) */
+#define GPIO_TREQB GPIO_GPIO (23) /* TIC REQuest B (I) */
+#define GPIO_1Hz GPIO_GPIO (25) /* 1 Hz clock (O) */
+#define GPIO_RCLK GPIO_GPIO (26) /* internal (R) CLocK (O, fcpu/2) */
+#define GPIO_32_768kHz GPIO_GPIO (27) /* 32.768 kHz clock (O, RTC) */
+
+#define GPDR_In 0 /* Input */
+#define GPDR_Out 1 /* Output */
+
+
+/*
+ * Interrupt Controller (IC) control registers
+ *
+ * Registers
+ * ICIP Interrupt Controller (IC) Interrupt ReQuest (IRQ)
+ * Pending register (read).
+ * ICMR Interrupt Controller (IC) Mask Register (read/write).
+ * ICLR Interrupt Controller (IC) Level Register (read/write).
+ * ICCR Interrupt Controller (IC) Control Register
+ * (read/write).
+ * [The ICCR register is only implemented in versions 2.0
+ * (rev. = 8) and higher of the StrongARM SA-1100.]
+ * ICFP Interrupt Controller (IC) Fast Interrupt reQuest
+ * (FIQ) Pending register (read).
+ * ICPR Interrupt Controller (IC) Pending Register (read).
+ * [The ICPR register is active low (inverted) in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it is active high (non-inverted) in
+ * versions 2.0 (rev. = 8) and higher.]
+ */
+
+#define ICIP __REG(0x90050000) /* IC IRQ Pending reg. */
+#define ICMR __REG(0x90050004) /* IC Mask Reg. */
+#define ICLR __REG(0x90050008) /* IC Level Reg. */
+#define ICCR __REG(0x9005000C) /* IC Control Reg. */
+#define ICFP __REG(0x90050010) /* IC FIQ Pending reg. */
+#define ICPR __REG(0x90050020) /* IC Pending Reg. */
+
+#define IC_GPIO(Nb) /* GPIO [0..10] */ \
+ (0x00000001 << (Nb))
+#define IC_GPIO0 IC_GPIO (0) /* GPIO [0] */
+#define IC_GPIO1 IC_GPIO (1) /* GPIO [1] */
+#define IC_GPIO2 IC_GPIO (2) /* GPIO [2] */
+#define IC_GPIO3 IC_GPIO (3) /* GPIO [3] */
+#define IC_GPIO4 IC_GPIO (4) /* GPIO [4] */
+#define IC_GPIO5 IC_GPIO (5) /* GPIO [5] */
+#define IC_GPIO6 IC_GPIO (6) /* GPIO [6] */
+#define IC_GPIO7 IC_GPIO (7) /* GPIO [7] */
+#define IC_GPIO8 IC_GPIO (8) /* GPIO [8] */
+#define IC_GPIO9 IC_GPIO (9) /* GPIO [9] */
+#define IC_GPIO10 IC_GPIO (10) /* GPIO [10] */
+#define IC_GPIO11_27 0x00000800 /* GPIO [11:27] (ORed) */
+#define IC_LCD 0x00001000 /* LCD controller */
+#define IC_Ser0UDC 0x00002000 /* Ser. port 0 UDC */
+#define IC_Ser1SDLC 0x00004000 /* Ser. port 1 SDLC */
+#define IC_Ser1UART 0x00008000 /* Ser. port 1 UART */
+#define IC_Ser2ICP 0x00010000 /* Ser. port 2 ICP */
+#define IC_Ser3UART 0x00020000 /* Ser. port 3 UART */
+#define IC_Ser4MCP 0x00040000 /* Ser. port 4 MCP */
+#define IC_Ser4SSP 0x00080000 /* Ser. port 4 SSP */
+#define IC_DMA(Nb) /* DMA controller channel [0..5] */ \
+ (0x00100000 << (Nb))
+#define IC_DMA0 IC_DMA (0) /* DMA controller channel 0 */
+#define IC_DMA1 IC_DMA (1) /* DMA controller channel 1 */
+#define IC_DMA2 IC_DMA (2) /* DMA controller channel 2 */
+#define IC_DMA3 IC_DMA (3) /* DMA controller channel 3 */
+#define IC_DMA4 IC_DMA (4) /* DMA controller channel 4 */
+#define IC_DMA5 IC_DMA (5) /* DMA controller channel 5 */
+#define IC_OST(Nb) /* OS Timer match [0..3] */ \
+ (0x04000000 << (Nb))
+#define IC_OST0 IC_OST (0) /* OS Timer match 0 */
+#define IC_OST1 IC_OST (1) /* OS Timer match 1 */
+#define IC_OST2 IC_OST (2) /* OS Timer match 2 */
+#define IC_OST3 IC_OST (3) /* OS Timer match 3 */
+#define IC_RTC1Hz 0x40000000 /* RTC 1 Hz clock */
+#define IC_RTCAlrm 0x80000000 /* RTC Alarm */
+
+#define ICLR_IRQ 0 /* Interrupt ReQuest */
+#define ICLR_FIQ 1 /* Fast Interrupt reQuest */
+
+#define ICCR_DIM 0x00000001 /* Disable Idle-mode interrupt */
+ /* Mask */
+#define ICCR_IdleAllInt (ICCR_DIM*0) /* Idle-mode All Interrupt enable */
+ /* (ICMR ignored) */
+#define ICCR_IdleMskInt (ICCR_DIM*1) /* Idle-mode non-Masked Interrupt */
+ /* enable (ICMR used) */
+
+
+/*
+ * Peripheral Pin Controller (PPC) control registers
+ *
+ * Registers
+ * PPDR Peripheral Pin Controller (PPC) Pin Direction
+ * Register (read/write).
+ * PPSR Peripheral Pin Controller (PPC) Pin State Register
+ * (read/write).
+ * PPAR Peripheral Pin Controller (PPC) Pin Assignment
+ * Register (read/write).
+ * PSDR Peripheral Pin Controller (PPC) Sleep-mode pin
+ * Direction Register (read/write).
+ * PPFR Peripheral Pin Controller (PPC) Pin Flag Register
+ * (read).
+ */
+
+#define PPDR __REG(0x90060000) /* PPC Pin Direction Reg. */
+#define PPSR __REG(0x90060004) /* PPC Pin State Reg. */
+#define PPAR __REG(0x90060008) /* PPC Pin Assignment Reg. */
+#define PSDR __REG(0x9006000C) /* PPC Sleep-mode pin Direction Reg. */
+#define PPFR __REG(0x90060010) /* PPC Pin Flag Reg. */
+
+#define PPC_LDD(Nb) /* LCD Data [0..7] */ \
+ (0x00000001 << (Nb))
+#define PPC_LDD0 PPC_LDD (0) /* LCD Data [0] */
+#define PPC_LDD1 PPC_LDD (1) /* LCD Data [1] */
+#define PPC_LDD2 PPC_LDD (2) /* LCD Data [2] */
+#define PPC_LDD3 PPC_LDD (3) /* LCD Data [3] */
+#define PPC_LDD4 PPC_LDD (4) /* LCD Data [4] */
+#define PPC_LDD5 PPC_LDD (5) /* LCD Data [5] */
+#define PPC_LDD6 PPC_LDD (6) /* LCD Data [6] */
+#define PPC_LDD7 PPC_LDD (7) /* LCD Data [7] */
+#define PPC_L_PCLK 0x00000100 /* LCD Pixel CLocK */
+#define PPC_L_LCLK 0x00000200 /* LCD Line CLocK */
+#define PPC_L_FCLK 0x00000400 /* LCD Frame CLocK */
+#define PPC_L_BIAS 0x00000800 /* LCD AC BIAS */
+ /* ser. port 1: */
+#define PPC_TXD1 0x00001000 /* SDLC/UART Transmit Data 1 */
+#define PPC_RXD1 0x00002000 /* SDLC/UART Receive Data 1 */
+ /* ser. port 2: */
+#define PPC_TXD2 0x00004000 /* IPC Transmit Data 2 */
+#define PPC_RXD2 0x00008000 /* IPC Receive Data 2 */
+ /* ser. port 3: */
+#define PPC_TXD3 0x00010000 /* UART Transmit Data 3 */
+#define PPC_RXD3 0x00020000 /* UART Receive Data 3 */
+ /* ser. port 4: */
+#define PPC_TXD4 0x00040000 /* MCP/SSP Transmit Data 4 */
+#define PPC_RXD4 0x00080000 /* MCP/SSP Receive Data 4 */
+#define PPC_SCLK 0x00100000 /* MCP/SSP Sample CLocK */
+#define PPC_SFRM 0x00200000 /* MCP/SSP Sample FRaMe */
+
+#define PPDR_In 0 /* Input */
+#define PPDR_Out 1 /* Output */
+
+ /* ser. port 1: */
+#define PPAR_UPR 0x00001000 /* UART Pin Reassignment */
+#define PPAR_UARTTR (PPAR_UPR*0) /* UART on TXD_1 & RXD_1 */
+#define PPAR_UARTGPIO (PPAR_UPR*1) /* UART on GPIO [14:15] */
+ /* ser. port 4: */
+#define PPAR_SPR 0x00040000 /* SSP Pin Reassignment */
+#define PPAR_SSPTRSS (PPAR_SPR*0) /* SSP on TXD_C, RXD_C, SCLK_C, */
+ /* & SFRM_C */
+#define PPAR_SSPGPIO (PPAR_SPR*1) /* SSP on GPIO [10:13] */
+
+#define PSDR_OutL 0 /* Output Low in sleep mode */
+#define PSDR_Flt 1 /* Floating (input) in sleep mode */
+
+#define PPFR_LCD 0x00000001 /* LCD controller */
+#define PPFR_SP1TX 0x00001000 /* Ser. Port 1 SDLC/UART Transmit */
+#define PPFR_SP1RX 0x00002000 /* Ser. Port 1 SDLC/UART Receive */
+#define PPFR_SP2TX 0x00004000 /* Ser. Port 2 ICP Transmit */
+#define PPFR_SP2RX 0x00008000 /* Ser. Port 2 ICP Receive */
+#define PPFR_SP3TX 0x00010000 /* Ser. Port 3 UART Transmit */
+#define PPFR_SP3RX 0x00020000 /* Ser. Port 3 UART Receive */
+#define PPFR_SP4 0x00040000 /* Ser. Port 4 MCP/SSP */
+#define PPFR_PerEn 0 /* Peripheral Enabled */
+#define PPFR_PPCEn 1 /* PPC Enabled */
+
+
+/*
+ * Dynamic Random-Access Memory (DRAM) control registers
+ *
+ * Registers
+ * MDCNFG Memory system: Dynamic Random-Access Memory (DRAM)
+ * CoNFiGuration register (read/write).
+ * MDCAS0 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 0
+ * (read/write).
+ * MDCAS1 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 1
+ * (read/write).
+ * MDCAS2 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 2
+ * (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fcas, Tcas Frequency, period of the DRAM CAS shift registers.
+ */
+
+#define MDCNFG __REG(0xA0000000) /* DRAM CoNFiGuration reg. */
+#define MDCAS0 __REG(0xA0000004) /* DRAM CAS shift reg. 0 */
+#define MDCAS1 __REG(0xA0000008) /* DRAM CAS shift reg. 1 */
+#define MDCAS2 __REG(0xA000000c) /* DRAM CAS shift reg. 2 */
+
+/* SA1100 MDCNFG values */
+#define MDCNFG_DE(Nb) /* DRAM Enable bank [0..3] */ \
+ (0x00000001 << (Nb))
+#define MDCNFG_DE0 MDCNFG_DE (0) /* DRAM Enable bank 0 */
+#define MDCNFG_DE1 MDCNFG_DE (1) /* DRAM Enable bank 1 */
+#define MDCNFG_DE2 MDCNFG_DE (2) /* DRAM Enable bank 2 */
+#define MDCNFG_DE3 MDCNFG_DE (3) /* DRAM Enable bank 3 */
+#define MDCNFG_DRAC Fld (2, 4) /* DRAM Row Address Count - 9 */
+#define MDCNFG_RowAdd(Add) /* Row Address count [9..12] */ \
+ (((Add) - 9) << FShft (MDCNFG_DRAC))
+#define MDCNFG_CDB2 0x00000040 /* shift reg. Clock Divide By 2 */
+ /* (fcas = fcpu/2) */
+#define MDCNFG_TRP Fld (4, 7) /* Time RAS Pre-charge - 1 [Tmem] */
+#define MDCNFG_PrChrg(Tcpu) /* Pre-Charge time [2..32 Tcpu] */ \
+ (((Tcpu) - 2)/2 << FShft (MDCNFG_TRP))
+#define MDCNFG_CeilPrChrg(Tcpu) /* Ceil. of PrChrg [2..32 Tcpu] */ \
+ (((Tcpu) - 1)/2 << FShft (MDCNFG_TRP))
+#define MDCNFG_TRASR Fld (4, 11) /* Time RAS Refresh - 1 [Tmem] */
+#define MDCNFG_Ref(Tcpu) /* Refresh time [2..32 Tcpu] */ \
+ (((Tcpu) - 2)/2 << FShft (MDCNFG_TRASR))
+#define MDCNFG_CeilRef(Tcpu) /* Ceil. of Ref [2..32 Tcpu] */ \
+ (((Tcpu) - 1)/2 << FShft (MDCNFG_TRASR))
+#define MDCNFG_TDL Fld (2, 15) /* Time Data Latch [Tcpu] */
+#define MDCNFG_DataLtch(Tcpu) /* Data Latch delay [0..3 Tcpu] */ \
+ ((Tcpu) << FShft (MDCNFG_TDL))
+#define MDCNFG_DRI Fld (15, 17) /* min. DRAM Refresh Interval/4 */
+ /* [Tmem] */
+#define MDCNFG_RefInt(Tcpu) /* min. Refresh Interval */ \
+ /* [0..262136 Tcpu] */ \
+ ((Tcpu)/8 << FShft (MDCNFG_DRI))
+
+/* SA1110 MDCNFG values */
+#define MDCNFG_SA1110_DE0 0x00000001 /* DRAM Enable bank 0 */
+#define MDCNFG_SA1110_DE1 0x00000002 /* DRAM Enable bank 1 */
+#define MDCNFG_SA1110_DTIM0 0x00000004 /* DRAM timing type 0/1 */
+#define MDCNFG_SA1110_DWID0 0x00000008 /* DRAM bus width 0/1 */
+#define MDCNFG_SA1110_DRAC0 Fld(3, 4) /* DRAM row addr bit count */
+ /* bank 0/1 */
+#define MDCNFG_SA1110_CDB20 0x00000080 /* Mem Clock divide by 2 0/1 */
+#define MDCNFG_SA1110_TRP0 Fld(3, 8) /* RAS precharge 0/1 */
+#define MDCNFG_SA1110_TDL0 Fld(2, 12) /* Data input latch after CAS*/
+ /* deassertion 0/1 */
+#define MDCNFG_SA1110_TWR0 Fld(2, 14) /* SDRAM write recovery 0/1 */
+#define MDCNFG_SA1110_DE2 0x00010000 /* DRAM Enable bank 0 */
+#define MDCNFG_SA1110_DE3 0x00020000 /* DRAM Enable bank 1 */
+#define MDCNFG_SA1110_DTIM2 0x00040000 /* DRAM timing type 0/1 */
+#define MDCNFG_SA1110_DWID2 0x00080000 /* DRAM bus width 0/1 */
+#define MDCNFG_SA1110_DRAC2 Fld(3, 20) /* DRAM row addr bit count */
+ /* bank 0/1 */
+#define MDCNFG_SA1110_CDB22 0x00800000 /* Mem Clock divide by 2 0/1 */
+#define MDCNFG_SA1110_TRP2 Fld(3, 24) /* RAS precharge 0/1 */
+#define MDCNFG_SA1110_TDL2 Fld(2, 28) /* Data input latch after CAS*/
+ /* deassertion 0/1 */
+#define MDCNFG_SA1110_TWR2 Fld(2, 30) /* SDRAM write recovery 0/1 */
+
+
+/*
+ * Static memory control registers
+ *
+ * Registers
+ * MSC0 Memory system: Static memory Control register 0
+ * (read/write).
+ * MSC1 Memory system: Static memory Control register 1
+ * (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ */
+
+#define MSC0 __REG(0xa0000010) /* Static memory Control reg. 0 */
+#define MSC1 __REG(0xa0000014) /* Static memory Control reg. 1 */
+#define MSC2 __REG(0xa000002c) /* Static memory Control reg. 2, not contiguous */
+
+#define MSC_Bnk(Nb) /* static memory Bank [0..3] */ \
+ Fld (16, ((Nb) Modulo 2)*16)
+#define MSC0_Bnk0 MSC_Bnk (0) /* static memory Bank 0 */
+#define MSC0_Bnk1 MSC_Bnk (1) /* static memory Bank 1 */
+#define MSC1_Bnk2 MSC_Bnk (2) /* static memory Bank 2 */
+#define MSC1_Bnk3 MSC_Bnk (3) /* static memory Bank 3 */
+
+#define MSC_RT Fld (2, 0) /* ROM/static memory Type */
+#define MSC_NonBrst /* Non-Burst static memory */ \
+ (0 << FShft (MSC_RT))
+#define MSC_SRAM /* 32-bit byte-writable SRAM */ \
+ (1 << FShft (MSC_RT))
+#define MSC_Brst4 /* Burst-of-4 static memory */ \
+ (2 << FShft (MSC_RT))
+#define MSC_Brst8 /* Burst-of-8 static memory */ \
+ (3 << FShft (MSC_RT))
+#define MSC_RBW 0x0004 /* ROM/static memory Bus Width */
+#define MSC_32BitStMem (MSC_RBW*0) /* 32-Bit Static Memory */
+#define MSC_16BitStMem (MSC_RBW*1) /* 16-Bit Static Memory */
+#define MSC_RDF Fld (5, 3) /* ROM/static memory read Delay */
+ /* First access - 1(.5) [Tmem] */
+#define MSC_1stRdAcc(Tcpu) /* 1st Read Access time (burst */ \
+ /* static memory) [3..65 Tcpu] */ \
+ ((((Tcpu) - 3)/2) << FShft (MSC_RDF))
+#define MSC_Ceil1stRdAcc(Tcpu) /* Ceil. of 1stRdAcc [3..65 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDF))
+#define MSC_RdAcc(Tcpu) /* Read Access time (non-burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDF))
+#define MSC_CeilRdAcc(Tcpu) /* Ceil. of RdAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDF))
+#define MSC_RDN Fld (5, 8) /* ROM/static memory read Delay */
+ /* Next access - 1 [Tmem] */
+#define MSC_NxtRdAcc(Tcpu) /* Next Read Access time (burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDN))
+#define MSC_CeilNxtRdAcc(Tcpu) /* Ceil. of NxtRdAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDN))
+#define MSC_WrAcc(Tcpu) /* Write Access time (non-burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDN))
+#define MSC_CeilWrAcc(Tcpu) /* Ceil. of WrAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDN))
+#define MSC_RRR Fld (3, 13) /* ROM/static memory RecoveRy */
+ /* time/2 [Tmem] */
+#define MSC_Rec(Tcpu) /* Recovery time [0..28 Tcpu] */ \
+ (((Tcpu)/4) << FShft (MSC_RRR))
+#define MSC_CeilRec(Tcpu) /* Ceil. of Rec [0..28 Tcpu] */ \
+ ((((Tcpu) + 3)/4) << FShft (MSC_RRR))
+
+
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) control
+ * register
+ *
+ * Register
+ * MECR Memory system: Expansion memory bus (PCMCIA)
+ * Configuration Register (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fbclk, Tbclk Frequency, period of the PCMCIA clock (BCLK).
+ */
+
+ /* Memory system: */
+#define MECR __REG(0xA0000018) /* Expansion memory bus (PCMCIA) Configuration Reg. */
+
+#define MECR_PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ Fld (15, (Nb)*16)
+#define MECR_PCMCIA0 MECR_PCMCIA (0) /* PCMCIA 0 */
+#define MECR_PCMCIA1 MECR_PCMCIA (1) /* PCMCIA 1 */
+
+#define MECR_BSIO Fld (5, 0) /* BCLK Select I/O - 1 [Tmem] */
+#define MECR_IOClk(Tcpu) /* I/O Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSIO))
+#define MECR_CeilIOClk(Tcpu) /* Ceil. of IOClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSIO))
+#define MECR_BSA Fld (5, 5) /* BCLK Select Attribute - 1 */
+ /* [Tmem] */
+#define MECR_AttrClk(Tcpu) /* Attribute Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSA))
+#define MECR_CeilAttrClk(Tcpu) /* Ceil. of AttrClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSA))
+#define MECR_BSM Fld (5, 10) /* BCLK Select Memory - 1 [Tmem] */
+#define MECR_MemClk(Tcpu) /* Memory Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSM))
+#define MECR_CeilMemClk(Tcpu) /* Ceil. of MemClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSM))
+
+/*
+ * On SA1110 only
+ */
+
+#define MDREFR __REG(0xA000001C)
+
+#define MDREFR_TRASR Fld (4, 0)
+#define MDREFR_DRI Fld (12, 4)
+#define MDREFR_E0PIN (1 << 16)
+#define MDREFR_K0RUN (1 << 17)
+#define MDREFR_K0DB2 (1 << 18)
+#define MDREFR_E1PIN (1 << 20)
+#define MDREFR_K1RUN (1 << 21)
+#define MDREFR_K1DB2 (1 << 22)
+#define MDREFR_K2RUN (1 << 25)
+#define MDREFR_K2DB2 (1 << 26)
+#define MDREFR_EAPD (1 << 28)
+#define MDREFR_KAPD (1 << 29)
+#define MDREFR_SLFRSH (1 << 31)
+
+
+/*
+ * Direct Memory Access (DMA) control registers
+ *
+ * Registers
+ * DDAR0 Direct Memory Access (DMA) Device Address Register
+ * channel 0 (read/write).
+ * DCSR0 Direct Memory Access (DMA) Control and Status
+ * Register channel 0 (read/write).
+ * DBSA0 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 0 (read/write).
+ * DBTA0 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 0 (read/write).
+ * DBSB0 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 0 (read/write).
+ * DBTB0 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 0 (read/write).
+ *
+ * DDAR1 Direct Memory Access (DMA) Device Address Register
+ * channel 1 (read/write).
+ * DCSR1 Direct Memory Access (DMA) Control and Status
+ * Register channel 1 (read/write).
+ * DBSA1 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 1 (read/write).
+ * DBTA1 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 1 (read/write).
+ * DBSB1 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 1 (read/write).
+ * DBTB1 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 1 (read/write).
+ *
+ * DDAR2 Direct Memory Access (DMA) Device Address Register
+ * channel 2 (read/write).
+ * DCSR2 Direct Memory Access (DMA) Control and Status
+ * Register channel 2 (read/write).
+ * DBSA2 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 2 (read/write).
+ * DBTA2 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 2 (read/write).
+ * DBSB2 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 2 (read/write).
+ * DBTB2 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 2 (read/write).
+ *
+ * DDAR3 Direct Memory Access (DMA) Device Address Register
+ * channel 3 (read/write).
+ * DCSR3 Direct Memory Access (DMA) Control and Status
+ * Register channel 3 (read/write).
+ * DBSA3 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 3 (read/write).
+ * DBTA3 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 3 (read/write).
+ * DBSB3 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 3 (read/write).
+ * DBTB3 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 3 (read/write).
+ *
+ * DDAR4 Direct Memory Access (DMA) Device Address Register
+ * channel 4 (read/write).
+ * DCSR4 Direct Memory Access (DMA) Control and Status
+ * Register channel 4 (read/write).
+ * DBSA4 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 4 (read/write).
+ * DBTA4 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 4 (read/write).
+ * DBSB4 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 4 (read/write).
+ * DBTB4 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 4 (read/write).
+ *
+ * DDAR5 Direct Memory Access (DMA) Device Address Register
+ * channel 5 (read/write).
+ * DCSR5 Direct Memory Access (DMA) Control and Status
+ * Register channel 5 (read/write).
+ * DBSA5 Direct Memory Access (DMA) Buffer Start address
+ * register A channel 5 (read/write).
+ * DBTA5 Direct Memory Access (DMA) Buffer Transfer count
+ * register A channel 5 (read/write).
+ * DBSB5 Direct Memory Access (DMA) Buffer Start address
+ * register B channel 5 (read/write).
+ * DBTB5 Direct Memory Access (DMA) Buffer Transfer count
+ * register B channel 5 (read/write).
+ */
+
+#define DMASp 0x00000020 /* DMA control reg. Space [byte] */
+
+#define DDAR(Nb) __REG(0xB0000000 + (Nb)*DMASp) /* DMA Device Address Reg. channel [0..5] */
+#define SetDCSR(Nb) __REG(0xB0000004 + (Nb)*DMASp) /* Set DMA Control & Status Reg. channel [0..5] (write) */
+#define ClrDCSR(Nb) __REG(0xB0000008 + (Nb)*DMASp) /* Clear DMA Control & Status Reg. channel [0..5] (write) */
+#define RdDCSR(Nb) __REG(0xB000000C + (Nb)*DMASp) /* Read DMA Control & Status Reg. channel [0..5] (read) */
+#define DBSA(Nb) __REG(0xB0000010 + (Nb)*DMASp) /* DMA Buffer Start address reg. A channel [0..5] */
+#define DBTA(Nb) __REG(0xB0000014 + (Nb)*DMASp) /* DMA Buffer Transfer count reg. A channel [0..5] */
+#define DBSB(Nb) __REG(0xB0000018 + (Nb)*DMASp) /* DMA Buffer Start address reg. B channel [0..5] */
+#define DBTB(Nb) __REG(0xB000001C + (Nb)*DMASp) /* DMA Buffer Transfer count reg. B channel [0..5] */
+
+#define DDAR_RW 0x00000001 /* device data Read/Write */
+#define DDAR_DevWr (DDAR_RW*0) /* Device data Write */
+ /* (memory -> device) */
+#define DDAR_DevRd (DDAR_RW*1) /* Device data Read */
+ /* (device -> memory) */
+#define DDAR_E 0x00000002 /* big/little Endian device */
+#define DDAR_LtlEnd (DDAR_E*0) /* Little Endian device */
+#define DDAR_BigEnd (DDAR_E*1) /* Big Endian device */
+#define DDAR_BS 0x00000004 /* device Burst Size */
+#define DDAR_Brst4 (DDAR_BS*0) /* Burst-of-4 device */
+#define DDAR_Brst8 (DDAR_BS*1) /* Burst-of-8 device */
+#define DDAR_DW 0x00000008 /* device Data Width */
+#define DDAR_8BitDev (DDAR_DW*0) /* 8-Bit Device */
+#define DDAR_16BitDev (DDAR_DW*1) /* 16-Bit Device */
+#define DDAR_DS Fld (4, 4) /* Device Select */
+#define DDAR_Ser0UDCTr /* Ser. port 0 UDC Transmit */ \
+ (0x0 << FShft (DDAR_DS))
+#define DDAR_Ser0UDCRc /* Ser. port 0 UDC Receive */ \
+ (0x1 << FShft (DDAR_DS))
+#define DDAR_Ser1SDLCTr /* Ser. port 1 SDLC Transmit */ \
+ (0x2 << FShft (DDAR_DS))
+#define DDAR_Ser1SDLCRc /* Ser. port 1 SDLC Receive */ \
+ (0x3 << FShft (DDAR_DS))
+#define DDAR_Ser1UARTTr /* Ser. port 1 UART Transmit */ \
+ (0x4 << FShft (DDAR_DS))
+#define DDAR_Ser1UARTRc /* Ser. port 1 UART Receive */ \
+ (0x5 << FShft (DDAR_DS))
+#define DDAR_Ser2ICPTr /* Ser. port 2 ICP Transmit */ \
+ (0x6 << FShft (DDAR_DS))
+#define DDAR_Ser2ICPRc /* Ser. port 2 ICP Receive */ \
+ (0x7 << FShft (DDAR_DS))
+#define DDAR_Ser3UARTTr /* Ser. port 3 UART Transmit */ \
+ (0x8 << FShft (DDAR_DS))
+#define DDAR_Ser3UARTRc /* Ser. port 3 UART Receive */ \
+ (0x9 << FShft (DDAR_DS))
+#define DDAR_Ser4MCP0Tr /* Ser. port 4 MCP 0 Transmit */ \
+ /* (audio) */ \
+ (0xA << FShft (DDAR_DS))
+#define DDAR_Ser4MCP0Rc /* Ser. port 4 MCP 0 Receive */ \
+ /* (audio) */ \
+ (0xB << FShft (DDAR_DS))
+#define DDAR_Ser4MCP1Tr /* Ser. port 4 MCP 1 Transmit */ \
+ /* (telecom) */ \
+ (0xC << FShft (DDAR_DS))
+#define DDAR_Ser4MCP1Rc /* Ser. port 4 MCP 1 Receive */ \
+ /* (telecom) */ \
+ (0xD << FShft (DDAR_DS))
+#define DDAR_Ser4SSPTr /* Ser. port 4 SSP Transmit */ \
+ (0xE << FShft (DDAR_DS))
+#define DDAR_Ser4SSPRc /* Ser. port 4 SSP Receive */ \
+ (0xF << FShft (DDAR_DS))
+#define DDAR_DA Fld (24, 8) /* Device Address */
+#define DDAR_DevAdd(Add) /* Device Address */ \
+ (((Add) & 0xF0000000) | \
+ (((Add) & 0X003FFFFC) << (FShft (DDAR_DA) - 2)))
+#define DDAR_Ser0UDCWr /* Ser. port 0 UDC Write */ \
+ (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
+ DDAR_Ser0UDCTr + DDAR_DevAdd (__PREG(Ser0UDCDR)))
+#define DDAR_Ser0UDCRd /* Ser. port 0 UDC Read */ \
+ (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
+ DDAR_Ser0UDCRc + DDAR_DevAdd (__PREG(Ser0UDCDR)))
+#define DDAR_Ser1UARTWr /* Ser. port 1 UART Write */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser1UARTTr + DDAR_DevAdd (__PREG(Ser1UTDR)))
+#define DDAR_Ser1UARTRd /* Ser. port 1 UART Read */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser1UARTRc + DDAR_DevAdd (__PREG(Ser1UTDR)))
+#define DDAR_Ser1SDLCWr /* Ser. port 1 SDLC Write */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser1SDLCTr + DDAR_DevAdd (__PREG(Ser1SDDR)))
+#define DDAR_Ser1SDLCRd /* Ser. port 1 SDLC Read */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser1SDLCRc + DDAR_DevAdd (__PREG(Ser1SDDR)))
+#define DDAR_Ser2UARTWr /* Ser. port 2 UART Write */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2UTDR)))
+#define DDAR_Ser2UARTRd /* Ser. port 2 UART Read */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2UTDR)))
+#define DDAR_Ser2HSSPWr /* Ser. port 2 HSSP Write */ \
+ (DDAR_DevWr + DDAR_Brst8 + DDAR_8BitDev + \
+ DDAR_Ser2ICPTr + DDAR_DevAdd (__PREG(Ser2HSDR)))
+#define DDAR_Ser2HSSPRd /* Ser. port 2 HSSP Read */ \
+ (DDAR_DevRd + DDAR_Brst8 + DDAR_8BitDev + \
+ DDAR_Ser2ICPRc + DDAR_DevAdd (__PREG(Ser2HSDR)))
+#define DDAR_Ser3UARTWr /* Ser. port 3 UART Write */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser3UARTTr + DDAR_DevAdd (__PREG(Ser3UTDR)))
+#define DDAR_Ser3UARTRd /* Ser. port 3 UART Read */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev + \
+ DDAR_Ser3UARTRc + DDAR_DevAdd (__PREG(Ser3UTDR)))
+#define DDAR_Ser4MCP0Wr /* Ser. port 4 MCP 0 Write (audio) */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4MCP0Tr + DDAR_DevAdd (__PREG(Ser4MCDR0)))
+#define DDAR_Ser4MCP0Rd /* Ser. port 4 MCP 0 Read (audio) */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4MCP0Rc + DDAR_DevAdd (__PREG(Ser4MCDR0)))
+#define DDAR_Ser4MCP1Wr /* Ser. port 4 MCP 1 Write */ \
+ /* (telecom) */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4MCP1Tr + DDAR_DevAdd (__PREG(Ser4MCDR1)))
+#define DDAR_Ser4MCP1Rd /* Ser. port 4 MCP 1 Read */ \
+ /* (telecom) */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4MCP1Rc + DDAR_DevAdd (__PREG(Ser4MCDR1)))
+#define DDAR_Ser4SSPWr /* Ser. port 4 SSP Write (16 bits) */ \
+ (DDAR_DevWr + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4SSPTr + DDAR_DevAdd (__PREG(Ser4SSDR)))
+#define DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */ \
+ (DDAR_DevRd + DDAR_Brst4 + DDAR_16BitDev + \
+ DDAR_Ser4SSPRc + DDAR_DevAdd (__PREG(Ser4SSDR)))
+
+#define DCSR_RUN 0x00000001 /* DMA running */
+#define DCSR_IE 0x00000002 /* DMA Interrupt Enable */
+#define DCSR_ERROR 0x00000004 /* DMA ERROR */
+#define DCSR_DONEA 0x00000008 /* DONE DMA transfer buffer A */
+#define DCSR_STRTA 0x00000010 /* STaRTed DMA transfer buffer A */
+#define DCSR_DONEB 0x00000020 /* DONE DMA transfer buffer B */
+#define DCSR_STRTB 0x00000040 /* STaRTed DMA transfer buffer B */
+#define DCSR_BIU 0x00000080 /* DMA Buffer In Use */
+#define DCSR_BufA (DCSR_BIU*0) /* DMA Buffer A in use */
+#define DCSR_BufB (DCSR_BIU*1) /* DMA Buffer B in use */
+
+#define DBT_TC Fld (13, 0) /* Transfer Count */
+#define DBTA_TCA DBT_TC /* Transfer Count buffer A */
+#define DBTB_TCB DBT_TC /* Transfer Count buffer B */
+
+
+/*
+ * Liquid Crystal Display (LCD) control registers
+ *
+ * Registers
+ * LCCR0 Liquid Crystal Display (LCD) Control Register 0
+ * (read/write).
+ * [Bits LDM, BAM, and ERM are only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ * LCSR Liquid Crystal Display (LCD) Status Register
+ * (read/write).
+ * [Bit LDD can be only read in versions 1.0 (rev. = 1)
+ * and 1.1 (rev. = 2) of the StrongARM SA-1100, it can be
+ * read and written (cleared) in versions 2.0 (rev. = 8)
+ * and higher.]
+ * DBAR1 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Base Address Register channel 1 (read/write).
+ * DCAR1 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Current Address Register channel 1 (read).
+ * DBAR2 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Base Address Register channel 2 (read/write).
+ * DCAR2 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Current Address Register channel 2 (read).
+ * LCCR1 Liquid Crystal Display (LCD) Control Register 1
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher.]
+ * LCCR2 Liquid Crystal Display (LCD) Control Register 2
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher.]
+ * LCCR3 Liquid Crystal Display (LCD) Control Register 3
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher. Bit PCP is only
+ * implemented in versions 2.0 (rev. = 8) and higher of
+ * the StrongARM SA-1100.]
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fpix, Tpix Frequency, period of the pixel clock.
+ * fln, Tln Frequency, period of the line clock.
+ * fac, Tac Frequency, period of the AC bias clock.
+ */
+
+#define LCD_PEntrySp 2 /* LCD Palette Entry Space [byte] */
+#define LCD_4BitPSp /* LCD 4-Bit pixel Palette Space */ \
+ /* [byte] */ \
+ (16*LCD_PEntrySp)
+#define LCD_8BitPSp /* LCD 8-Bit pixel Palette Space */ \
+ /* [byte] */ \
+ (256*LCD_PEntrySp)
+#define LCD_12_16BitPSp /* LCD 12/16-Bit pixel */ \
+ /* dummy-Palette Space [byte] */ \
+ (16*LCD_PEntrySp)
+
+#define LCD_PGrey Fld (4, 0) /* LCD Palette entry Grey value */
+#define LCD_PBlue Fld (4, 0) /* LCD Palette entry Blue value */
+#define LCD_PGreen Fld (4, 4) /* LCD Palette entry Green value */
+#define LCD_PRed Fld (4, 8) /* LCD Palette entry Red value */
+#define LCD_PBS Fld (2, 12) /* LCD Pixel Bit Size */
+#define LCD_4Bit /* LCD 4-Bit pixel mode */ \
+ (0 << FShft (LCD_PBS))
+#define LCD_8Bit /* LCD 8-Bit pixel mode */ \
+ (1 << FShft (LCD_PBS))
+#define LCD_12_16Bit /* LCD 12/16-Bit pixel mode */ \
+ (2 << FShft (LCD_PBS))
+
+#define LCD_Int0_0 0x0 /* LCD Intensity = 0.0% = 0 */
+#define LCD_Int11_1 0x1 /* LCD Intensity = 11.1% = 1/9 */
+#define LCD_Int20_0 0x2 /* LCD Intensity = 20.0% = 1/5 */
+#define LCD_Int26_7 0x3 /* LCD Intensity = 26.7% = 4/15 */
+#define LCD_Int33_3 0x4 /* LCD Intensity = 33.3% = 3/9 */
+#define LCD_Int40_0 0x5 /* LCD Intensity = 40.0% = 2/5 */
+#define LCD_Int44_4 0x6 /* LCD Intensity = 44.4% = 4/9 */
+#define LCD_Int50_0 0x7 /* LCD Intensity = 50.0% = 1/2 */
+#define LCD_Int55_6 0x8 /* LCD Intensity = 55.6% = 5/9 */
+#define LCD_Int60_0 0x9 /* LCD Intensity = 60.0% = 3/5 */
+#define LCD_Int66_7 0xA /* LCD Intensity = 66.7% = 6/9 */
+#define LCD_Int73_3 0xB /* LCD Intensity = 73.3% = 11/15 */
+#define LCD_Int80_0 0xC /* LCD Intensity = 80.0% = 4/5 */
+#define LCD_Int88_9 0xD /* LCD Intensity = 88.9% = 8/9 */
+#define LCD_Int100_0 0xE /* LCD Intensity = 100.0% = 1 */
+#define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */
+ /* (Alternative) */
+
+#define LCCR0 __REG(0xB0100000) /* LCD Control Reg. 0 */
+#define LCSR __REG(0xB0100004) /* LCD Status Reg. */
+#define DBAR1 __REG(0xB0100010) /* LCD DMA Base Address Reg. channel 1 */
+#define DCAR1 __REG(0xB0100014) /* LCD DMA Current Address Reg. channel 1 */
+#define DBAR2 __REG(0xB0100018) /* LCD DMA Base Address Reg. channel 2 */
+#define DCAR2 __REG(0xB010001C) /* LCD DMA Current Address Reg. channel 2 */
+#define LCCR1 __REG(0xB0100020) /* LCD Control Reg. 1 */
+#define LCCR2 __REG(0xB0100024) /* LCD Control Reg. 2 */
+#define LCCR3 __REG(0xB0100028) /* LCD Control Reg. 3 */
+
+#define LCCR0_LEN 0x00000001 /* LCD ENable */
+#define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */
+#define LCCR0_Color (LCCR0_CMS*0) /* Color display */
+#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */
+#define LCCR0_SDS 0x00000004 /* Single/Dual panel display */
+ /* Select */
+#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */
+#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */
+#define LCCR0_LDM 0x00000008 /* LCD Disable done (LDD) */
+ /* interrupt Mask (disable) */
+#define LCCR0_BAM 0x00000010 /* Base Address update (BAU) */
+ /* interrupt Mask (disable) */
+#define LCCR0_ERM 0x00000020 /* LCD ERror (BER, IOL, IUL, IOU, */
+ /* IUU, OOL, OUL, OOU, and OUU) */
+ /* interrupt Mask (disable) */
+#define LCCR0_PAS 0x00000080 /* Passive/Active display Select */
+#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */
+#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */
+#define LCCR0_BLE 0x00000100 /* Big/Little Endian select */
+#define LCCR0_LtlEnd (LCCR0_BLE*0) /* Little Endian frame buffer */
+#define LCCR0_BigEnd (LCCR0_BLE*1) /* Big Endian frame buffer */
+#define LCCR0_DPD 0x00000200 /* Double Pixel Data (monochrome */
+ /* display mode) */
+#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */
+ /* display */
+#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */
+ /* display */
+#define LCCR0_PDD Fld (8, 12) /* Palette DMA request Delay */
+ /* [Tmem] */
+#define LCCR0_DMADel(Tcpu) /* palette DMA request Delay */ \
+ /* [0..510 Tcpu] */ \
+ ((Tcpu)/2 << FShft (LCCR0_PDD))
+
+#define LCSR_LDD 0x00000001 /* LCD Disable Done */
+#define LCSR_BAU 0x00000002 /* Base Address Update (read) */
+#define LCSR_BER 0x00000004 /* Bus ERror */
+#define LCSR_ABC 0x00000008 /* AC Bias clock Count */
+#define LCSR_IOL 0x00000010 /* Input FIFO Over-run Lower */
+ /* panel */
+#define LCSR_IUL 0x00000020 /* Input FIFO Under-run Lower */
+ /* panel */
+#define LCSR_IOU 0x00000040 /* Input FIFO Over-run Upper */
+ /* panel */
+#define LCSR_IUU 0x00000080 /* Input FIFO Under-run Upper */
+ /* panel */
+#define LCSR_OOL 0x00000100 /* Output FIFO Over-run Lower */
+ /* panel */
+#define LCSR_OUL 0x00000200 /* Output FIFO Under-run Lower */
+ /* panel */
+#define LCSR_OOU 0x00000400 /* Output FIFO Over-run Upper */
+ /* panel */
+#define LCSR_OUU 0x00000800 /* Output FIFO Under-run Upper */
+ /* panel */
+
+#define LCCR1_PPL Fld (6, 4) /* Pixels Per Line/16 - 1 */
+#define LCCR1_DisWdth(Pixel) /* Display Width [16..1024 pix.] */ \
+ (((Pixel) - 16)/16 << FShft (LCCR1_PPL))
+#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */
+ /* pulse Width - 1 [Tpix] (L_LCLK) */
+#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \
+ /* pulse Width [1..64 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_HSW))
+#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */
+ /* count - 1 [Tpix] */
+#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \
+ /* [1..256 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_ELW))
+#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */
+ /* Wait count - 1 [Tpix] */
+#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \
+ /* [1..256 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_BLW))
+
+#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */
+#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \
+ (((Line) - 1) << FShft (LCCR2_LPP))
+#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */
+ /* Width - 1 [Tln] (L_FCLK) */
+#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \
+ /* Width [1..64 Tln] */ \
+ (((Tln) - 1) << FShft (LCCR2_VSW))
+#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */
+ /* count [Tln] */
+#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \
+ /* [0..255 Tln] */ \
+ ((Tln) << FShft (LCCR2_EFW))
+#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */
+ /* Wait count [Tln] */
+#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \
+ /* [0..255 Tln] */ \
+ ((Tln) << FShft (LCCR2_BFW))
+
+#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor/2 - 2 */
+ /* [1..255] (L_PCLK) */
+ /* fpix = fcpu/(2*(PCD + 2)) */
+ /* Tpix = 2*(PCD + 2)*Tcpu */
+#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor [6..514] */ \
+ (((Div) - 4)/2 << FShft (LCCR3_PCD))
+ /* fpix = fcpu/(2*Floor (Div/2)) */
+ /* Tpix = 2*Floor (Div/2)*Tcpu */
+#define LCCR3_CeilPixClkDiv(Div) /* Ceil. of PixClkDiv [6..514] */ \
+ (((Div) - 3)/2 << FShft (LCCR3_PCD))
+ /* fpix = fcpu/(2*Ceil (Div/2)) */
+ /* Tpix = 2*Ceil (Div/2)*Tcpu */
+#define LCCR3_ACB Fld (8, 8) /* AC Bias clock half period - 1 */
+ /* [Tln] (L_BIAS) */
+#define LCCR3_ACBsDiv(Div) /* AC Bias clock Divisor [2..512] */ \
+ (((Div) - 2)/2 << FShft (LCCR3_ACB))
+ /* fac = fln/(2*Floor (Div/2)) */
+ /* Tac = 2*Floor (Div/2)*Tln */
+#define LCCR3_CeilACBsDiv(Div) /* Ceil. of ACBsDiv [2..512] */ \
+ (((Div) - 1)/2 << FShft (LCCR3_ACB))
+ /* fac = fln/(2*Ceil (Div/2)) */
+ /* Tac = 2*Ceil (Div/2)*Tln */
+#define LCCR3_API Fld (4, 16) /* AC bias Pin transitions per */
+ /* Interrupt */
+#define LCCR3_ACBsCntOff /* AC Bias clock transition Count */ \
+ /* Off */ \
+ (0 << FShft (LCCR3_API))
+#define LCCR3_ACBsCnt(Trans) /* AC Bias clock transition Count */ \
+ /* [1..15] */ \
+ ((Trans) << FShft (LCCR3_API))
+#define LCCR3_VSP 0x00100000 /* Vertical Synchronization pulse */
+ /* Polarity (L_FCLK) */
+#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */
+ /* active High */
+#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */
+ /* active Low */
+#define LCCR3_HSP 0x00200000 /* Horizontal Synchronization */
+ /* pulse Polarity (L_LCLK) */
+#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */
+ /* pulse active High */
+#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */
+ /* pulse active Low */
+#define LCCR3_PCP 0x00400000 /* Pixel Clock Polarity (L_PCLK) */
+#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */
+#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */
+#define LCCR3_OEP 0x00800000 /* Output Enable Polarity (L_BIAS, */
+ /* active display mode) */
+#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */
+#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1101.h b/arch/arm/mach-sa1100/include/mach/SA-1101.h
new file mode 100644
index 00000000..5d2ad7db
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/SA-1101.h
@@ -0,0 +1,925 @@
+/*
+ * SA-1101.h
+ *
+ * Copyright (c) Peter Danielsson 1999
+ *
+ * Definition of constants related to the sa1101
+ * support chip for the sa1100
+ *
+ */
+
+
+/* Be sure that virtual mapping is defined right */
+#ifndef __ASM_ARCH_HARDWARE_H
+#error You must include hardware.h not SA-1101.h
+#endif
+
+#ifndef SA1101_BASE
+#error You must define SA-1101 physical base address
+#endif
+
+#ifndef LANGUAGE
+# ifdef __ASSEMBLY__
+# define LANGUAGE Assembly
+# else
+# define LANGUAGE C
+# endif
+#endif
+
+/*
+ * We have mapped the sa1101 depending on the value of SA1101_BASE.
+ * It then appears from 0xf4000000.
+ */
+
+#define SA1101_p2v( x ) ((x) - SA1101_BASE + 0xf4000000)
+#define SA1101_v2p( x ) ((x) - 0xf4000000 + SA1101_BASE)
+
+#ifndef SA1101_p2v
+#define SA1101_p2v(PhAdd) (PhAdd)
+#endif
+
+#include <mach/bitfield.h>
+
+#define C 0
+#define Assembly 1
+
+
+/*
+ * Memory map
+ */
+
+#define __SHMEM_CONTROL0 0x00000000
+#define __SYSTEM_CONTROL1 0x00000400
+#define __ARBITER 0x00020000
+#define __SYSTEM_CONTROL2 0x00040000
+#define __SYSTEM_CONTROL3 0x00060000
+#define __PARALLEL_PORT 0x00080000
+#define __VIDMEM_CONTROL 0x00100000
+#define __UPDATE_FIFO 0x00120000
+#define __SHMEM_CONTROL1 0x00140000
+#define __INTERRUPT_CONTROL 0x00160000
+#define __USB_CONTROL 0x00180000
+#define __TRACK_INTERFACE 0x001a0000
+#define __MOUSE_INTERFACE 0x001b0000
+#define __KEYPAD_INTERFACE 0x001c0000
+#define __PCMCIA_INTERFACE 0x001e0000
+#define __VGA_CONTROL 0x00200000
+#define __GPIO_INTERFACE 0x00300000
+
+/*
+ * Macro that calculates real address for registers in the SA-1101
+ */
+
+#define _SA1101( x ) ((x) + SA1101_BASE)
+
+/*
+ * Interface and shared memory controller registers
+ *
+ * Registers
+ * SKCR SA-1101 control register (read/write)
+ * SMCR Shared Memory Controller Register
+ * SNPR Snoop Register
+ */
+
+#define _SKCR _SA1101( 0x00000000 ) /* SA-1101 Control Reg. */
+#define _SMCR _SA1101( 0x00140000 ) /* Shared Mem. Control Reg. */
+#define _SNPR _SA1101( 0x00140400 ) /* Snoop Reg. */
+
+#if LANGUAGE == C
+#define SKCR (*((volatile Word *) SA1101_p2v (_SKCR)))
+#define SMCR (*((volatile Word *) SA1101_p2v (_SMCR)))
+#define SNPR (*((volatile Word *) SA1101_p2v (_SNPR)))
+
+#define SKCR_PLLEn 0x0001 /* Enable On-Chip PLL */
+#define SKCR_BCLKEn 0x0002 /* Enables BCLK */
+#define SKCR_Sleep 0x0004 /* Sleep Mode */
+#define SKCR_IRefEn 0x0008 /* DAC Iref input enable */
+#define SKCR_VCOON 0x0010 /* VCO bias */
+#define SKCR_ScanTestEn 0x0020 /* Enables scan test */
+#define SKCR_ClockTestEn 0x0040 /* Enables clock test */
+
+#define SMCR_DCAC Fld(2,0) /* Number of column address bits */
+#define SMCR_DRAC Fld(2,2) /* Number of row address bits */
+#define SMCR_ArbiterBias 0x0008 /* favor video or USB */
+#define SMCR_TopVidMem Fld(4,5) /* Top 4 bits of vidmem addr. */
+
+#define SMCR_ColAdrBits( x ) /* col. addr bits 8..11 */ \
+ (( (x) - 8 ) << FShft (SMCR_DCAC))
+#define SMCR_RowAdrBits( x ) /* row addr bits 9..12 */\
+ (( (x) - 9 ) << FShft (SMCR_DRAC))
+
+#define SNPR_VFBstart Fld(12,0) /* Video frame buffer addr */
+#define SNPR_VFBsize Fld(11,12) /* Video frame buffer size */
+#define SNPR_WholeBank (1 << 23) /* Whole bank bit */
+#define SNPR_BankSelect Fld(2,27) /* Bank select */
+#define SNPR_SnoopEn (1 << 31) /* Enable snoop operation */
+
+#define SNPR_Set_VFBsize( x ) /* set frame buffer size (in kb) */ \
+ ( (x) << FShft (SNPR_VFBsize))
+#define SNPR_Select_Bank(x) /* select bank 0 or 1 */ \
+ (( (x) + 1 ) << FShft (SNPR_BankSelect ))
+
+#endif /* LANGUAGE == C */
+
+/*
+ * Video Memory Controller
+ *
+ * Registers
+ * VMCCR Configuration register
+ * VMCAR VMC address register
+ * VMCDR VMC data register
+ *
+ */
+
+#define _VMCCR _SA1101( 0x00100000 ) /* Configuration register */
+#define _VMCAR _SA1101( 0x00101000 ) /* VMC address register */
+#define _VMCDR _SA1101( 0x00101400 ) /* VMC data register */
+
+#if LANGUAGE == C
+#define VMCCR (*((volatile Word *) SA1101_p2v (_VMCCR)))
+#define VMCAR (*((volatile Word *) SA1101_p2v (_VMCAR)))
+#define VMCDR (*((volatile Word *) SA1101_p2v (_VMCDR)))
+
+#define VMCCR_RefreshEn 0x0000 /* Enable memory refresh */
+#define VMCCR_Config 0x0001 /* DRAM size */
+#define VMCCR_RefPeriod Fld(2,3) /* Refresh period */
+#define VMCCR_StaleDataWait Fld(4,5) /* Stale FIFO data timeout counter */
+#define VMCCR_SleepState (1<<9) /* State of interface pins in sleep*/
+#define VMCCR_RefTest (1<<10) /* refresh test */
+#define VMCCR_RefLow Fld(6,11) /* refresh low counter */
+#define VMCCR_RefHigh Fld(7,17) /* refresh high counter */
+#define VMCCR_SDTCTest Fld(7,24) /* stale data timeout counter */
+#define VMCCR_ForceSelfRef (1<<31) /* Force self refresh */
+
+#endif LANGUAGE == C
+
+
+/* Update FIFO
+ *
+ * Registers
+ * UFCR Update FIFO Control Register
+ * UFSR Update FIFO Status Register
+ * UFLVLR update FIFO level register
+ * UFDR update FIFO data register
+ */
+
+#define _UFCR _SA1101(0x00120000) /* Update FIFO Control Reg. */
+#define _UFSR _SA1101(0x00120400) /* Update FIFO Status Reg. */
+#define _UFLVLR _SA1101(0x00120800) /* Update FIFO level reg. */
+#define _UFDR _SA1101(0x00120c00) /* Update FIFO data reg. */
+
+#if LANGUAGE == C
+
+#define UFCR (*((volatile Word *) SA1101_p2v (_UFCR)))
+#define UFSR (*((volatile Word *) SA1101_p2v (_UFSR)))
+#define UFLVLR (*((volatile Word *) SA1101_p2v (_UFLVLR)))
+#define UFDR (*((volatile Word *) SA1101_p2v (_UFDR)))
+
+
+#define UFCR_FifoThreshhold Fld(7,0) /* Level for FifoGTn flag */
+
+#define UFSR_FifoGTnFlag 0x01 /* FifoGTn flag */#define UFSR_FifoEmpty 0x80 /* FIFO is empty */
+
+#endif /* LANGUAGE == C */
+
+/* System Controller
+ *
+ * Registers
+ * SKPCR Power Control Register
+ * SKCDR Clock Divider Register
+ * DACDR1 DAC1 Data register
+ * DACDR2 DAC2 Data register
+ */
+
+#define _SKPCR _SA1101(0x00000400)
+#define _SKCDR _SA1101(0x00040000)
+#define _DACDR1 _SA1101(0x00060000)
+#define _DACDR2 _SA1101(0x00060400)
+
+#if LANGUAGE == C
+#define SKPCR (*((volatile Word *) SA1101_p2v (_SKPCR)))
+#define SKCDR (*((volatile Word *) SA1101_p2v (_SKCDR)))
+#define DACDR1 (*((volatile Word *) SA1101_p2v (_DACDR1)))
+#define DACDR2 (*((volatile Word *) SA1101_p2v (_DACDR2)))
+
+#define SKPCR_UCLKEn 0x01 /* USB Enable */
+#define SKPCR_PCLKEn 0x02 /* PS/2 Enable */
+#define SKPCR_ICLKEn 0x04 /* Interrupt Controller Enable */
+#define SKPCR_VCLKEn 0x08 /* Video Controller Enable */
+#define SKPCR_PICLKEn 0x10 /* parallel port Enable */
+#define SKPCR_DCLKEn 0x20 /* DACs Enable */
+#define SKPCR_nKPADEn 0x40 /* Multiplexer */
+
+#define SKCDR_PLLMul Fld(7,0) /* PLL Multiplier */
+#define SKCDR_VCLKEn Fld(2,7) /* Video controller clock divider */
+#define SKDCR_BCLKEn (1<<9) /* BCLK Divider */
+#define SKDCR_UTESTCLKEn (1<<10) /* Route USB clock during test mode */
+#define SKDCR_DivRValue Fld(6,11) /* Input clock divider for PLL */
+#define SKDCR_DivNValue Fld(5,17) /* Output clock divider for PLL */
+#define SKDCR_PLLRSH Fld(3,22) /* PLL bandwidth control */
+#define SKDCR_ChargePump (1<<25) /* Charge pump control */
+#define SKDCR_ClkTestMode (1<<26) /* Clock output test mode */
+#define SKDCR_ClkTestEn (1<<27) /* Test clock generator */
+#define SKDCR_ClkJitterCntl Fld(3,28) /* video clock jitter compensation */
+
+#define DACDR_DACCount Fld(8,0) /* Count value */
+#define DACDR1_DACCount DACDR_DACCount
+#define DACDR2_DACCount DACDR_DACCount
+
+#endif /* LANGUAGE == C */
+
+/*
+ * Parallel Port Interface
+ *
+ * Registers
+ * IEEE_Config IEEE mode selection and programmable attributes
+ * IEEE_Control Controls the states of IEEE port control outputs
+ * IEEE_Data Forward transfer data register
+ * IEEE_Addr Forward transfer address register
+ * IEEE_Status Port IO signal status register
+ * IEEE_IntStatus Port interrupts status register
+ * IEEE_FifoLevels Rx and Tx FIFO interrupt generation levels
+ * IEEE_InitTime Forward timeout counter initial value
+ * IEEE_TimerStatus Forward timeout counter current value
+ * IEEE_FifoReset Reset forward transfer FIFO
+ * IEEE_ReloadValue Counter reload value
+ * IEEE_TestControl Control testmode
+ * IEEE_TestDataIn Test data register
+ * IEEE_TestDataInEn Enable test data
+ * IEEE_TestCtrlIn Test control signals
+ * IEEE_TestCtrlInEn Enable test control signals
+ * IEEE_TestDataStat Current data bus value
+ *
+ */
+
+/*
+ * The control registers are defined as offsets from a base address
+ */
+
+#define _IEEE( x ) _SA1101( (x) + __PARALLEL_PORT )
+
+#define _IEEE_Config _IEEE( 0x0000 )
+#define _IEEE_Control _IEEE( 0x0400 )
+#define _IEEE_Data _IEEE( 0x4000 )
+#define _IEEE_Addr _IEEE( 0x0800 )
+#define _IEEE_Status _IEEE( 0x0c00 )
+#define _IEEE_IntStatus _IEEE( 0x1000 )
+#define _IEEE_FifoLevels _IEEE( 0x1400 )
+#define _IEEE_InitTime _IEEE( 0x1800 )
+#define _IEEE_TimerStatus _IEEE( 0x1c00 )
+#define _IEEE_FifoReset _IEEE( 0x2000 )
+#define _IEEE_ReloadValue _IEEE( 0x3c00 )
+#define _IEEE_TestControl _IEEE( 0x2400 )
+#define _IEEE_TestDataIn _IEEE( 0x2800 )
+#define _IEEE_TestDataInEn _IEEE( 0x2c00 )
+#define _IEEE_TestCtrlIn _IEEE( 0x3000 )
+#define _IEEE_TestCtrlInEn _IEEE( 0x3400 )
+#define _IEEE_TestDataStat _IEEE( 0x3800 )
+
+
+#if LANGUAGE == C
+#define IEEE_Config (*((volatile Word *) SA1101_p2v (_IEEE_Config)))
+#define IEEE_Control (*((volatile Word *) SA1101_p2v (_IEEE_Control)))
+#define IEEE_Data (*((volatile Word *) SA1101_p2v (_IEEE_Data)))
+#define IEEE_Addr (*((volatile Word *) SA1101_p2v (_IEEE_Addr)))
+#define IEEE_Status (*((volatile Word *) SA1101_p2v (_IEEE_Status)))
+#define IEEE_IntStatus (*((volatile Word *) SA1101_p2v (_IEEE_IntStatus)))
+#define IEEE_FifoLevels (*((volatile Word *) SA1101_p2v (_IEEE_FifoLevels)))
+#define IEEE_InitTime (*((volatile Word *) SA1101_p2v (_IEEE_InitTime)))
+#define IEEE_TimerStatus (*((volatile Word *) SA1101_p2v (_IEEE_TimerStatus)))
+#define IEEE_FifoReset (*((volatile Word *) SA1101_p2v (_IEEE_FifoReset)))
+#define IEEE_ReloadValue (*((volatile Word *) SA1101_p2v (_IEEE_ReloadValue)))
+#define IEEE_TestControl (*((volatile Word *) SA1101_p2v (_IEEE_TestControl)))
+#define IEEE_TestDataIn (*((volatile Word *) SA1101_p2v (_IEEE_TestDataIn)))
+#define IEEE_TestDataInEn (*((volatile Word *) SA1101_p2v (_IEEE_TestDataInEn)))
+#define IEEE_TestCtrlIn (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlIn)))
+#define IEEE_TestCtrlInEn (*((volatile Word *) SA1101_p2v (_IEEE_TestCtrlInEn)))
+#define IEEE_TestDataStat (*((volatile Word *) SA1101_p2v (_IEEE_TestDataStat)))
+
+
+#define IEEE_Config_M Fld(3,0) /* Mode select */
+#define IEEE_Config_D 0x04 /* FIFO access enable */
+#define IEEE_Config_B 0x08 /* 9-bit word enable */
+#define IEEE_Config_T 0x10 /* Data transfer enable */
+#define IEEE_Config_A 0x20 /* Data transfer direction */
+#define IEEE_Config_E 0x40 /* Timer enable */
+#define IEEE_Control_A 0x08 /* AutoFd output */
+#define IEEE_Control_E 0x04 /* Selectin output */
+#define IEEE_Control_T 0x02 /* Strobe output */
+#define IEEE_Control_I 0x01 /* Port init output */
+#define IEEE_Data_C (1<<31) /* Byte count */
+#define IEEE_Data_Db Fld(9,16) /* Data byte 2 */
+#define IEEE_Data_Da Fld(9,0) /* Data byte 1 */
+#define IEEE_Addr_A Fld(8,0) /* forward address transfer byte */
+#define IEEE_Status_A 0x0100 /* nAutoFd port output status */
+#define IEEE_Status_E 0x0080 /* nSelectIn port output status */
+#define IEEE_Status_T 0x0040 /* nStrobe port output status */
+#define IEEE_Status_I 0x0020 /* nInit port output status */
+#define IEEE_Status_B 0x0010 /* Busy port inout status */
+#define IEEE_Status_S 0x0008 /* Select port input status */
+#define IEEE_Status_K 0x0004 /* nAck port input status */
+#define IEEE_Status_F 0x0002 /* nFault port input status */
+#define IEEE_Status_R 0x0001 /* pError port input status */
+
+#define IEEE_IntStatus_IntReqDat 0x0100
+#define IEEE_IntStatus_IntReqEmp 0x0080
+#define IEEE_IntStatus_IntReqInt 0x0040
+#define IEEE_IntStatus_IntReqRav 0x0020
+#define IEEE_IntStatus_IntReqTim 0x0010
+#define IEEE_IntStatus_RevAddrComp 0x0008
+#define IEEE_IntStatus_RevDataComp 0x0004
+#define IEEE_IntStatus_FwdAddrComp 0x0002
+#define IEEE_IntStatus_FwdDataComp 0x0001
+#define IEEE_FifoLevels_RevFifoLevel 2
+#define IEEE_FifoLevels_FwdFifoLevel 1
+#define IEEE_InitTime_TimValInit Fld(22,0)
+#define IEEE_TimerStatus_TimValStat Fld(22,0)
+#define IEEE_ReloadValue_Reload Fld(4,0)
+
+#define IEEE_TestControl_RegClk 0x04
+#define IEEE_TestControl_ClockSelect Fld(2,1)
+#define IEEE_TestControl_TimerTestModeEn 0x01
+#define IEEE_TestCtrlIn_PError 0x10
+#define IEEE_TestCtrlIn_nFault 0x08
+#define IEEE_TestCtrlIn_nAck 0x04
+#define IEEE_TestCtrlIn_PSel 0x02
+#define IEEE_TestCtrlIn_Busy 0x01
+
+#endif /* LANGUAGE == C */
+
+/*
+ * VGA Controller
+ *
+ * Registers
+ * VideoControl Video Control Register
+ * VgaTiming0 VGA Timing Register 0
+ * VgaTiming1 VGA Timing Register 1
+ * VgaTiming2 VGA Timing Register 2
+ * VgaTiming3 VGA Timing Register 3
+ * VgaBorder VGA Border Color Register
+ * VgaDBAR VGADMA Base Address Register
+ * VgaDCAR VGADMA Channel Current Address Register
+ * VgaStatus VGA Status Register
+ * VgaInterruptMask VGA Interrupt Mask Register
+ * VgaPalette VGA Palette Registers
+ * DacControl DAC Control Register
+ * VgaTest VGA Controller Test Register
+ */
+
+#define _VGA( x ) _SA1101( ( x ) + __VGA_CONTROL )
+
+#define _VideoControl _VGA( 0x0000 )
+#define _VgaTiming0 _VGA( 0x0400 )
+#define _VgaTiming1 _VGA( 0x0800 )
+#define _VgaTiming2 _VGA( 0x0c00 )
+#define _VgaTiming3 _VGA( 0x1000 )
+#define _VgaBorder _VGA( 0x1400 )
+#define _VgaDBAR _VGA( 0x1800 )
+#define _VgaDCAR _VGA( 0x1c00 )
+#define _VgaStatus _VGA( 0x2000 )
+#define _VgaInterruptMask _VGA( 0x2400 )
+#define _VgaPalette _VGA( 0x40000 )
+#define _DacControl _VGA( 0x3000 )
+#define _VgaTest _VGA( 0x2c00 )
+
+#if (LANGUAGE == C)
+#define VideoControl (*((volatile Word *) SA1101_p2v (_VideoControl)))
+#define VgaTiming0 (*((volatile Word *) SA1101_p2v (_VgaTiming0)))
+#define VgaTiming1 (*((volatile Word *) SA1101_p2v (_VgaTiming1)))
+#define VgaTiming2 (*((volatile Word *) SA1101_p2v (_VgaTiming2)))
+#define VgaTiming3 (*((volatile Word *) SA1101_p2v (_VgaTiming3)))
+#define VgaBorder (*((volatile Word *) SA1101_p2v (_VgaBorder)))
+#define VgaDBAR (*((volatile Word *) SA1101_p2v (_VgaDBAR)))
+#define VgaDCAR (*((volatile Word *) SA1101_p2v (_VgaDCAR)))
+#define VgaStatus (*((volatile Word *) SA1101_p2v (_VgaStatus)))
+#define VgaInterruptMask (*((volatile Word *) SA1101_p2v (_VgaInterruptMask)))
+#define VgaPalette (*((volatile Word *) SA1101_p2v (_VgaPalette)))
+#define DacControl (*((volatile Word *) SA1101_p2v (_DacControl)))
+#define VgaTest (*((volatile Word *) SA1101_p2v (_VgaTest)))
+
+#define VideoControl_VgaEn 0x00000000
+#define VideoControl_BGR 0x00000001
+#define VideoControl_VCompVal Fld(2,2)
+#define VideoControl_VgaReq Fld(4,4)
+#define VideoControl_VBurstL Fld(4,8)
+#define VideoControl_VMode (1<<12)
+#define VideoControl_PalRead (1<<13)
+
+#define VgaTiming0_PPL Fld(6,2)
+#define VgaTiming0_HSW Fld(8,8)
+#define VgaTiming0_HFP Fld(8,16)
+#define VgaTiming0_HBP Fld(8,24)
+
+#define VgaTiming1_LPS Fld(10,0)
+#define VgaTiming1_VSW Fld(6,10)
+#define VgaTiming1_VFP Fld(8,16)
+#define VgaTiming1_VBP Fld(8,24)
+
+#define VgaTiming2_IVS 0x01
+#define VgaTiming2_IHS 0x02
+#define VgaTiming2_CVS 0x04
+#define VgaTiming2_CHS 0x08
+
+#define VgaTiming3_HBS Fld(8,0)
+#define VgaTiming3_HBE Fld(8,8)
+#define VgaTiming3_VBS Fld(8,16)
+#define VgaTiming3_VBE Fld(8,24)
+
+#define VgaBorder_BCOL Fld(24,0)
+
+#define VgaStatus_VFUF 0x01
+#define VgaStatus_VNext 0x02
+#define VgaStatus_VComp 0x04
+
+#define VgaInterruptMask_VFUFMask 0x00
+#define VgaInterruptMask_VNextMask 0x01
+#define VgaInterruptMask_VCompMask 0x02
+
+#define VgaPalette_R Fld(8,0)
+#define VgaPalette_G Fld(8,8)
+#define VgaPalette_B Fld(8,16)
+
+#define DacControl_DACON 0x0001
+#define DacControl_COMPON 0x0002
+#define DacControl_PEDON 0x0004
+#define DacControl_RTrim Fld(5,4)
+#define DacControl_GTrim Fld(5,9)
+#define DacControl_BTrim Fld(5,14)
+
+#define VgaTest_TDAC 0x00
+#define VgaTest_Datatest Fld(4,1)
+#define VgaTest_DACTESTDAC 0x10
+#define VgaTest_DACTESTOUT Fld(3,5)
+
+#endif /* LANGUAGE == C */
+
+/*
+ * USB Host Interface Controller
+ *
+ * Registers
+ * Revision
+ * Control
+ * CommandStatus
+ * InterruptStatus
+ * InterruptEnable
+ * HCCA
+ * PeriodCurrentED
+ * ControlHeadED
+ * BulkHeadED
+ * BulkCurrentED
+ * DoneHead
+ * FmInterval
+ * FmRemaining
+ * FmNumber
+ * PeriodicStart
+ * LSThreshold
+ * RhDescriptorA
+ * RhDescriptorB
+ * RhStatus
+ * RhPortStatus
+ * USBStatus
+ * USBReset
+ * USTAR
+ * USWER
+ * USRFR
+ * USNFR
+ * USTCSR
+ * USSR
+ *
+ */
+
+#define _USB( x ) _SA1101( ( x ) + __USB_CONTROL )
+
+
+#define _Revision _USB( 0x0000 )
+#define _Control _USB( 0x0888 )
+#define _CommandStatus _USB( 0x0c00 )
+#define _InterruptStatus _USB( 0x1000 )
+#define _InterruptEnable _USB( 0x1400 )
+#define _HCCA _USB( 0x1800 )
+#define _PeriodCurrentED _USB( 0x1c00 )
+#define _ControlHeadED _USB( 0x2000 )
+#define _BulkHeadED _USB( 0x2800 )
+#define _BulkCurrentED _USB( 0x2c00 )
+#define _DoneHead _USB( 0x3000 )
+#define _FmInterval _USB( 0x3400 )
+#define _FmRemaining _USB( 0x3800 )
+#define _FmNumber _USB( 0x3c00 )
+#define _PeriodicStart _USB( 0x4000 )
+#define _LSThreshold _USB( 0x4400 )
+#define _RhDescriptorA _USB( 0x4800 )
+#define _RhDescriptorB _USB( 0x4c00 )
+#define _RhStatus _USB( 0x5000 )
+#define _RhPortStatus _USB( 0x5400 )
+#define _USBStatus _USB( 0x11800 )
+#define _USBReset _USB( 0x11c00 )
+
+#define _USTAR _USB( 0x10400 )
+#define _USWER _USB( 0x10800 )
+#define _USRFR _USB( 0x10c00 )
+#define _USNFR _USB( 0x11000 )
+#define _USTCSR _USB( 0x11400 )
+#define _USSR _USB( 0x11800 )
+
+
+#if (LANGUAGE == C)
+
+#define Revision (*((volatile Word *) SA1101_p2v (_Revision)))
+#define Control (*((volatile Word *) SA1101_p2v (_Control)))
+#define CommandStatus (*((volatile Word *) SA1101_p2v (_CommandStatus)))
+#define InterruptStatus (*((volatile Word *) SA1101_p2v (_InterruptStatus)))
+#define InterruptEnable (*((volatile Word *) SA1101_p2v (_InterruptEnable)))
+#define HCCA (*((volatile Word *) SA1101_p2v (_HCCA)))
+#define PeriodCurrentED (*((volatile Word *) SA1101_p2v (_PeriodCurrentED)))
+#define ControlHeadED (*((volatile Word *) SA1101_p2v (_ControlHeadED)))
+#define BulkHeadED (*((volatile Word *) SA1101_p2v (_BulkHeadED)))
+#define BulkCurrentED (*((volatile Word *) SA1101_p2v (_BulkCurrentED)))
+#define DoneHead (*((volatile Word *) SA1101_p2v (_DoneHead)))
+#define FmInterval (*((volatile Word *) SA1101_p2v (_FmInterval)))
+#define FmRemaining (*((volatile Word *) SA1101_p2v (_FmRemaining)))
+#define FmNumber (*((volatile Word *) SA1101_p2v (_FmNumber)))
+#define PeriodicStart (*((volatile Word *) SA1101_p2v (_PeriodicStart)))
+#define LSThreshold (*((volatile Word *) SA1101_p2v (_LSThreshold)))
+#define RhDescriptorA (*((volatile Word *) SA1101_p2v (_RhDescriptorA)))
+#define RhDescriptorB (*((volatile Word *) SA1101_p2v (_RhDescriptorB)))
+#define RhStatus (*((volatile Word *) SA1101_p2v (_RhStatus)))
+#define RhPortStatus (*((volatile Word *) SA1101_p2v (_RhPortStatus)))
+#define USBStatus (*((volatile Word *) SA1101_p2v (_USBStatus)))
+#define USBReset (*((volatile Word *) SA1101_p2v (_USBReset)))
+#define USTAR (*((volatile Word *) SA1101_p2v (_USTAR)))
+#define USWER (*((volatile Word *) SA1101_p2v (_USWER)))
+#define USRFR (*((volatile Word *) SA1101_p2v (_USRFR)))
+#define USNFR (*((volatile Word *) SA1101_p2v (_USNFR)))
+#define USTCSR (*((volatile Word *) SA1101_p2v (_USTCSR)))
+#define USSR (*((volatile Word *) SA1101_p2v (_USSR)))
+
+
+#define USBStatus_IrqHciRmtWkp (1<<7)
+#define USBStatus_IrqHciBuffAcc (1<<8)
+#define USBStatus_nIrqHciM (1<<9)
+#define USBStatus_nHciMFClr (1<<10)
+
+#define USBReset_ForceIfReset 0x01
+#define USBReset_ForceHcReset 0x02
+#define USBReset_ClkGenReset 0x04
+
+#define USTCR_RdBstCntrl Fld(3,0)
+#define USTCR_ByteEnable Fld(4,3)
+#define USTCR_WriteEn (1<<7)
+#define USTCR_FifoCir (1<<8)
+#define USTCR_TestXferSel (1<<9)
+#define USTCR_FifoCirAtEnd (1<<10)
+#define USTCR_nSimScaleDownClk (1<<11)
+
+#define USSR_nAppMDEmpty 0x01
+#define USSR_nAppMDFirst 0x02
+#define USSR_nAppMDLast 0x04
+#define USSR_nAppMDFull 0x08
+#define USSR_nAppMAFull 0x10
+#define USSR_XferReq 0x20
+#define USSR_XferEnd 0x40
+
+#endif /* LANGUAGE == C */
+
+
+/*
+ * Interrupt Controller
+ *
+ * Registers
+ * INTTEST0 Test register 0
+ * INTTEST1 Test register 1
+ * INTENABLE0 Interrupt Enable register 0
+ * INTENABLE1 Interrupt Enable register 1
+ * INTPOL0 Interrupt Polarity selection 0
+ * INTPOL1 Interrupt Polarity selection 1
+ * INTTSTSEL Interrupt source selection
+ * INTSTATCLR0 Interrupt Status 0
+ * INTSTATCLR1 Interrupt Status 1
+ * INTSET0 Interrupt Set 0
+ * INTSET1 Interrupt Set 1
+ */
+
+#define _INT( x ) _SA1101( ( x ) + __INTERRUPT_CONTROL)
+
+#define _INTTEST0 _INT( 0x1000 )
+#define _INTTEST1 _INT( 0x1400 )
+#define _INTENABLE0 _INT( 0x2000 )
+#define _INTENABLE1 _INT( 0x2400 )
+#define _INTPOL0 _INT( 0x3000 )
+#define _INTPOL1 _INT( 0x3400 )
+#define _INTTSTSEL _INT( 0x5000 )
+#define _INTSTATCLR0 _INT( 0x6000 )
+#define _INTSTATCLR1 _INT( 0x6400 )
+#define _INTSET0 _INT( 0x7000 )
+#define _INTSET1 _INT( 0x7400 )
+
+#if ( LANGUAGE == C )
+#define INTTEST0 (*((volatile Word *) SA1101_p2v (_INTTEST0)))
+#define INTTEST1 (*((volatile Word *) SA1101_p2v (_INTTEST1)))
+#define INTENABLE0 (*((volatile Word *) SA1101_p2v (_INTENABLE0)))
+#define INTENABLE1 (*((volatile Word *) SA1101_p2v (_INTENABLE1)))
+#define INTPOL0 (*((volatile Word *) SA1101_p2v (_INTPOL0)))
+#define INTPOL1 (*((volatile Word *) SA1101_p2v (_INTPOL1)))
+#define INTTSTSEL (*((volatile Word *) SA1101_p2v (_INTTSTSEL)))
+#define INTSTATCLR0 (*((volatile Word *) SA1101_p2v (_INTSTATCLR0)))
+#define INTSTATCLR1 (*((volatile Word *) SA1101_p2v (_INTSTATCLR1)))
+#define INTSET0 (*((volatile Word *) SA1101_p2v (_INTSET0)))
+#define INTSET1 (*((volatile Word *) SA1101_p2v (_INTSET1)))
+
+#endif /* LANGUAGE == C */
+
+/*
+ * PS/2 Trackpad and Mouse Interfaces
+ *
+ * Registers (prefix kbd applies to trackpad interface, mse to mouse)
+ * KBDCR Control Register
+ * KBDSTAT Status Register
+ * KBDDATA Transmit/Receive Data register
+ * KBDCLKDIV Clock Division Register
+ * KBDPRECNT Clock Precount Register
+ * KBDTEST1 Test register 1
+ * KBDTEST2 Test register 2
+ * KBDTEST3 Test register 3
+ * KBDTEST4 Test register 4
+ * MSECR
+ * MSESTAT
+ * MSEDATA
+ * MSECLKDIV
+ * MSEPRECNT
+ * MSETEST1
+ * MSETEST2
+ * MSETEST3
+ * MSETEST4
+ *
+ */
+
+#define _KBD( x ) _SA1101( ( x ) + __TRACK_INTERFACE )
+#define _MSE( x ) _SA1101( ( x ) + __MOUSE_INTERFACE )
+
+#define _KBDCR _KBD( 0x0000 )
+#define _KBDSTAT _KBD( 0x0400 )
+#define _KBDDATA _KBD( 0x0800 )
+#define _KBDCLKDIV _KBD( 0x0c00 )
+#define _KBDPRECNT _KBD( 0x1000 )
+#define _KBDTEST1 _KBD( 0x2000 )
+#define _KBDTEST2 _KBD( 0x2400 )
+#define _KBDTEST3 _KBD( 0x2800 )
+#define _KBDTEST4 _KBD( 0x2c00 )
+#define _MSECR _MSE( 0x0000 )
+#define _MSESTAT _MSE( 0x0400 )
+#define _MSEDATA _MSE( 0x0800 )
+#define _MSECLKDIV _MSE( 0x0c00 )
+#define _MSEPRECNT _MSE( 0x1000 )
+#define _MSETEST1 _MSE( 0x2000 )
+#define _MSETEST2 _MSE( 0x2400 )
+#define _MSETEST3 _MSE( 0x2800 )
+#define _MSETEST4 _MSE( 0x2c00 )
+
+#if ( LANGUAGE == C )
+
+#define KBDCR (*((volatile Word *) SA1101_p2v (_KBDCR)))
+#define KBDSTAT (*((volatile Word *) SA1101_p2v (_KBDSTAT)))
+#define KBDDATA (*((volatile Word *) SA1101_p2v (_KBDDATA)))
+#define KBDCLKDIV (*((volatile Word *) SA1101_p2v (_KBDCLKDIV)))
+#define KBDPRECNT (*((volatile Word *) SA1101_p2v (_KBDPRECNT)))
+#define KBDTEST1 (*((volatile Word *) SA1101_p2v (_KBDTEST1)))
+#define KBDTEST2 (*((volatile Word *) SA1101_p2v (_KBDTEST2)))
+#define KBDTEST3 (*((volatile Word *) SA1101_p2v (_KBDTEST3)))
+#define KBDTEST4 (*((volatile Word *) SA1101_p2v (_KBDTEST4)))
+#define MSECR (*((volatile Word *) SA1101_p2v (_MSECR)))
+#define MSESTAT (*((volatile Word *) SA1101_p2v (_MSESTAT)))
+#define MSEDATA (*((volatile Word *) SA1101_p2v (_MSEDATA)))
+#define MSECLKDIV (*((volatile Word *) SA1101_p2v (_MSECLKDIV)))
+#define MSEPRECNT (*((volatile Word *) SA1101_p2v (_MSEPRECNT)))
+#define MSETEST1 (*((volatile Word *) SA1101_p2v (_MSETEST1)))
+#define MSETEST2 (*((volatile Word *) SA1101_p2v (_MSETEST2)))
+#define MSETEST3 (*((volatile Word *) SA1101_p2v (_MSETEST3)))
+#define MSETEST4 (*((volatile Word *) SA1101_p2v (_MSETEST4)))
+
+
+#define KBDCR_ENA 0x08
+#define KBDCR_FKD 0x02
+#define KBDCR_FKC 0x01
+
+#define KBDSTAT_TXE 0x80
+#define KBDSTAT_TXB 0x40
+#define KBDSTAT_RXF 0x20
+#define KBDSTAT_RXB 0x10
+#define KBDSTAT_ENA 0x08
+#define KBDSTAT_RXP 0x04
+#define KBDSTAT_KBD 0x02
+#define KBDSTAT_KBC 0x01
+
+#define KBDCLKDIV_DivVal Fld(4,0)
+
+#define MSECR_ENA 0x08
+#define MSECR_FKD 0x02
+#define MSECR_FKC 0x01
+
+#define MSESTAT_TXE 0x80
+#define MSESTAT_TXB 0x40
+#define MSESTAT_RXF 0x20
+#define MSESTAT_RXB 0x10
+#define MSESTAT_ENA 0x08
+#define MSESTAT_RXP 0x04
+#define MSESTAT_MSD 0x02
+#define MSESTAT_MSC 0x01
+
+#define MSECLKDIV_DivVal Fld(4,0)
+
+#define KBDTEST1_CD 0x80
+#define KBDTEST1_RC1 0x40
+#define KBDTEST1_MC 0x20
+#define KBDTEST1_C Fld(2,3)
+#define KBDTEST1_T2 0x40
+#define KBDTEST1_T1 0x20
+#define KBDTEST1_T0 0x10
+#define KBDTEST2_TICBnRES 0x08
+#define KBDTEST2_RKC 0x04
+#define KBDTEST2_RKD 0x02
+#define KBDTEST2_SEL 0x01
+#define KBDTEST3_ms_16 0x80
+#define KBDTEST3_us_64 0x40
+#define KBDTEST3_us_16 0x20
+#define KBDTEST3_DIV8 0x10
+#define KBDTEST3_DIn 0x08
+#define KBDTEST3_CIn 0x04
+#define KBDTEST3_KD 0x02
+#define KBDTEST3_KC 0x01
+#define KBDTEST4_BC12 0x80
+#define KBDTEST4_BC11 0x40
+#define KBDTEST4_TRES 0x20
+#define KBDTEST4_CLKOE 0x10
+#define KBDTEST4_CRES 0x08
+#define KBDTEST4_RXB 0x04
+#define KBDTEST4_TXB 0x02
+#define KBDTEST4_SRX 0x01
+
+#define MSETEST1_CD 0x80
+#define MSETEST1_RC1 0x40
+#define MSETEST1_MC 0x20
+#define MSETEST1_C Fld(2,3)
+#define MSETEST1_T2 0x40
+#define MSETEST1_T1 0x20
+#define MSETEST1_T0 0x10
+#define MSETEST2_TICBnRES 0x08
+#define MSETEST2_RKC 0x04
+#define MSETEST2_RKD 0x02
+#define MSETEST2_SEL 0x01
+#define MSETEST3_ms_16 0x80
+#define MSETEST3_us_64 0x40
+#define MSETEST3_us_16 0x20
+#define MSETEST3_DIV8 0x10
+#define MSETEST3_DIn 0x08
+#define MSETEST3_CIn 0x04
+#define MSETEST3_KD 0x02
+#define MSETEST3_KC 0x01
+#define MSETEST4_BC12 0x80
+#define MSETEST4_BC11 0x40
+#define MSETEST4_TRES 0x20
+#define MSETEST4_CLKOE 0x10
+#define MSETEST4_CRES 0x08
+#define MSETEST4_RXB 0x04
+#define MSETEST4_TXB 0x02
+#define MSETEST4_SRX 0x01
+
+#endif /* LANGUAGE == C */
+
+
+/*
+ * General-Purpose I/O Interface
+ *
+ * Registers
+ * PADWR Port A Data Write Register
+ * PBDWR Port B Data Write Register
+ * PADRR Port A Data Read Register
+ * PBDRR Port B Data Read Register
+ * PADDR Port A Data Direction Register
+ * PBDDR Port B Data Direction Register
+ * PASSR Port A Sleep State Register
+ * PBSSR Port B Sleep State Register
+ *
+ */
+
+#define _PIO( x ) _SA1101( ( x ) + __GPIO_INTERFACE )
+
+#define _PADWR _PIO( 0x0000 )
+#define _PBDWR _PIO( 0x0400 )
+#define _PADRR _PIO( 0x0000 )
+#define _PBDRR _PIO( 0x0400 )
+#define _PADDR _PIO( 0x0800 )
+#define _PBDDR _PIO( 0x0c00 )
+#define _PASSR _PIO( 0x1000 )
+#define _PBSSR _PIO( 0x1400 )
+
+
+#if ( LANGUAGE == C )
+
+
+#define PADWR (*((volatile Word *) SA1101_p2v (_PADWR)))
+#define PBDWR (*((volatile Word *) SA1101_p2v (_PBDWR)))
+#define PADRR (*((volatile Word *) SA1101_p2v (_PADRR)))
+#define PBDRR (*((volatile Word *) SA1101_p2v (_PBDRR)))
+#define PADDR (*((volatile Word *) SA1101_p2v (_PADDR)))
+#define PBDDR (*((volatile Word *) SA1101_p2v (_PBDDR)))
+#define PASSR (*((volatile Word *) SA1101_p2v (_PASSR)))
+#define PBSSR (*((volatile Word *) SA1101_p2v (_PBSSR)))
+
+#endif
+
+
+
+/*
+ * Keypad Interface
+ *
+ * Registers
+ * PXDWR
+ * PXDRR
+ * PYDWR
+ * PYDRR
+ *
+ */
+
+#define _KEYPAD( x ) _SA1101( ( x ) + __KEYPAD_INTERFACE )
+
+#define _PXDWR _KEYPAD( 0x0000 )
+#define _PXDRR _KEYPAD( 0x0000 )
+#define _PYDWR _KEYPAD( 0x0400 )
+#define _PYDRR _KEYPAD( 0x0400 )
+
+#if ( LANGUAGE == C )
+
+
+#define PXDWR (*((volatile Word *) SA1101_p2v (_PXDWR)))
+#define PXDRR (*((volatile Word *) SA1101_p2v (_PXDRR)))
+#define PYDWR (*((volatile Word *) SA1101_p2v (_PYDWR)))
+#define PYDRR (*((volatile Word *) SA1101_p2v (_PYDRR)))
+
+#endif
+
+
+
+/*
+ * PCMCIA Interface
+ *
+ * Registers
+ * PCSR Status Register
+ * PCCR Control Register
+ * PCSSR Sleep State Register
+ *
+ */
+
+#define _CARD( x ) _SA1101( ( x ) + __PCMCIA_INTERFACE )
+
+#define _PCSR _CARD( 0x0000 )
+#define _PCCR _CARD( 0x0400 )
+#define _PCSSR _CARD( 0x0800 )
+
+#if ( LANGUAGE == C )
+#define PCSR (*((volatile Word *) SA1101_p2v (_PCSR)))
+#define PCCR (*((volatile Word *) SA1101_p2v (_PCCR)))
+#define PCSSR (*((volatile Word *) SA1101_p2v (_PCSSR)))
+
+#define PCSR_S0_ready 0x0001
+#define PCSR_S1_ready 0x0002
+#define PCSR_S0_detected 0x0004
+#define PCSR_S1_detected 0x0008
+#define PCSR_S0_VS1 0x0010
+#define PCSR_S0_VS2 0x0020
+#define PCSR_S1_VS1 0x0040
+#define PCSR_S1_VS2 0x0080
+#define PCSR_S0_WP 0x0100
+#define PCSR_S1_WP 0x0200
+#define PCSR_S0_BVD1_nSTSCHG 0x0400
+#define PCSR_S0_BVD2_nSPKR 0x0800
+#define PCSR_S1_BVD1_nSTSCHG 0x1000
+#define PCSR_S1_BVD2_nSPKR 0x2000
+
+#define PCCR_S0_VPP0 0x0001
+#define PCCR_S0_VPP1 0x0002
+#define PCCR_S0_VCC0 0x0004
+#define PCCR_S0_VCC1 0x0008
+#define PCCR_S1_VPP0 0x0010
+#define PCCR_S1_VPP1 0x0020
+#define PCCR_S1_VCC0 0x0040
+#define PCCR_S1_VCC1 0x0080
+#define PCCR_S0_reset 0x0100
+#define PCCR_S1_reset 0x0200
+#define PCCR_S0_float 0x0400
+#define PCCR_S1_float 0x0800
+
+#define PCSSR_S0_VCC0 0x0001
+#define PCSSR_S0_VCC1 0x0002
+#define PCSSR_S0_VPP0 0x0004
+#define PCSSR_S0_VPP1 0x0008
+#define PCSSR_S0_control 0x0010
+#define PCSSR_S1_VCC0 0x0020
+#define PCSSR_S1_VCC1 0x0040
+#define PCSSR_S1_VPP0 0x0080
+#define PCSSR_S1_VPP1 0x0100
+#define PCSSR_S1_control 0x0200
+
+#endif
+
+#undef C
+#undef Assembly
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1111.h b/arch/arm/mach-sa1100/include/mach/SA-1111.h
new file mode 100644
index 00000000..c38f6091
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/SA-1111.h
@@ -0,0 +1,5 @@
+/*
+ * Moved to new location
+ */
+#warning using old SA-1111.h - update to <asm/hardware/sa1111.h>
+#include <asm/hardware/sa1111.h>
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
new file mode 100644
index 00000000..28c2cf50
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -0,0 +1,105 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/assabet.h
+ *
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware specific definitions for Assabet
+ * Only include this file from SA1100-specific files.
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for Neponset added.
+ */
+#ifndef __ASM_ARCH_ASSABET_H
+#define __ASM_ARCH_ASSABET_H
+
+
+/* System Configuration Register flags */
+
+#define ASSABET_SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */
+#define ASSABET_SCR_SDRAM_HIGH (1<<3) /* SDRAM size (high bit) */
+#define ASSABET_SCR_FLASH_LOW (1<<4) /* Flash size (low bit) */
+#define ASSABET_SCR_FLASH_HIGH (1<<5) /* Flash size (high bit) */
+#define ASSABET_SCR_GFX (1<<8) /* Graphics Accelerator (0 = present) */
+#define ASSABET_SCR_SA1111 (1<<9) /* Neponset (0 = present) */
+
+#define ASSABET_SCR_INIT -1
+
+extern unsigned long SCR_value;
+
+#ifdef CONFIG_ASSABET_NEPONSET
+#define machine_has_neponset() ((SCR_value & ASSABET_SCR_SA1111) == 0)
+#else
+#define machine_has_neponset() (0)
+#endif
+
+/* Board Control Register */
+
+#define ASSABET_BCR_BASE 0xf1000000
+#define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE))
+
+#define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */
+#define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */
+#define ASSABET_BCR_GFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */
+#define ASSABET_BCR_CODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */
+#define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */
+#define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */
+#define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */
+#define ASSABET_BCR_STEREO_LB (1<<6) /* Stereo Loopback */
+#define ASSABET_BCR_CF_BUS_OFF (1<<7) /* Compact Flash bus (0 = on, 1 = off (float)) */
+#define ASSABET_BCR_AUDIO_ON (1<<8) /* Audio power on */
+#define ASSABET_BCR_LIGHT_ON (1<<9) /* Backlight */
+#define ASSABET_BCR_LCD_12RGB (1<<10) /* 0 = 16RGB, 1 = 12RGB */
+#define ASSABET_BCR_LCD_ON (1<<11) /* LCD power on */
+#define ASSABET_BCR_RS232EN (1<<12) /* RS232 transceiver enable */
+#define ASSABET_BCR_LED_RED (1<<13) /* D9 (0 = on, 1 = off) */
+#define ASSABET_BCR_LED_GREEN (1<<14) /* D8 (0 = on, 1 = off) */
+#define ASSABET_BCR_VIB_ON (1<<15) /* Vibration motor (quiet alert) */
+#define ASSABET_BCR_COM_DTR (1<<16) /* COMport Data Terminal Ready */
+#define ASSABET_BCR_COM_RTS (1<<17) /* COMport Request To Send */
+#define ASSABET_BCR_RAD_WU (1<<18) /* Radio wake up interrupt */
+#define ASSABET_BCR_SMB_EN (1<<19) /* System management bus enable */
+#define ASSABET_BCR_TV_IR_DEC (1<<20) /* TV IR Decode Enable (not implemented) */
+#define ASSABET_BCR_QMUTE (1<<21) /* Quick Mute */
+#define ASSABET_BCR_RAD_ON (1<<22) /* Radio Power On */
+#define ASSABET_BCR_SPK_OFF (1<<23) /* 1 = Speaker amplifier power off */
+
+#ifdef CONFIG_SA1100_ASSABET
+extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
+#else
+#define ASSABET_BCR_frob(x,y) do { } while (0)
+#endif
+
+#define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x))
+#define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0)
+
+#define ASSABET_BSR_BASE 0xf1000000
+#define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE))
+
+#define ASSABET_BSR_RS232_VALID (1 << 24)
+#define ASSABET_BSR_COM_DCD (1 << 25)
+#define ASSABET_BSR_COM_CTS (1 << 26)
+#define ASSABET_BSR_COM_DSR (1 << 27)
+#define ASSABET_BSR_RAD_CTS (1 << 28)
+#define ASSABET_BSR_RAD_DSR (1 << 29)
+#define ASSABET_BSR_RAD_DCD (1 << 30)
+#define ASSABET_BSR_RAD_RI (1 << 31)
+
+
+/* GPIOs for which the generic definition doesn't say much */
+#define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */
+#define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */
+#define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */
+#define ASSABET_GPIO_CF_IRQ GPIO_GPIO (21) /* CF IRQ */
+#define ASSABET_GPIO_CF_CD GPIO_GPIO (22) /* CF CD */
+#define ASSABET_GPIO_CF_BVD2 GPIO_GPIO (24) /* CF BVD */
+#define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */
+#define ASSABET_GPIO_CF_BVD1 GPIO_GPIO (25) /* CF BVD */
+#define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */
+#define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */
+
+#define ASSABET_IRQ_GPIO_CF_IRQ IRQ_GPIO21
+#define ASSABET_IRQ_GPIO_CF_CD IRQ_GPIO22
+#define ASSABET_IRQ_GPIO_CF_BVD2 IRQ_GPIO24
+#define ASSABET_IRQ_GPIO_CF_BVD1 IRQ_GPIO25
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/badge4.h b/arch/arm/mach-sa1100/include/mach/badge4.h
new file mode 100644
index 00000000..44d2e1bf
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/badge4.h
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/badge4.h
+ *
+ * Tim Connors <connors@hpl.hp.com>
+ * Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can 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_HARDWARE_H
+#error "include <mach/hardware.h> instead"
+#endif
+
+#define BADGE4_SA1111_BASE (0x48000000)
+
+/* GPIOs on the BadgePAD 4 */
+#define BADGE4_GPIO_INT_1111 GPIO_GPIO0 /* SA-1111 IRQ */
+
+#define BADGE4_GPIO_INT_VID GPIO_GPIO1 /* Video expansion */
+#define BADGE4_GPIO_LGP2 GPIO_GPIO2 /* GPIO_LDD8 */
+#define BADGE4_GPIO_LGP3 GPIO_GPIO3 /* GPIO_LDD9 */
+#define BADGE4_GPIO_LGP4 GPIO_GPIO4 /* GPIO_LDD10 */
+#define BADGE4_GPIO_LGP5 GPIO_GPIO5 /* GPIO_LDD11 */
+#define BADGE4_GPIO_LGP6 GPIO_GPIO6 /* GPIO_LDD12 */
+#define BADGE4_GPIO_LGP7 GPIO_GPIO7 /* GPIO_LDD13 */
+#define BADGE4_GPIO_LGP8 GPIO_GPIO8 /* GPIO_LDD14 */
+#define BADGE4_GPIO_LGP9 GPIO_GPIO9 /* GPIO_LDD15 */
+#define BADGE4_GPIO_GPA_VID GPIO_GPIO10 /* Video expansion */
+#define BADGE4_GPIO_GPB_VID GPIO_GPIO11 /* Video expansion */
+#define BADGE4_GPIO_GPC_VID GPIO_GPIO12 /* Video expansion */
+
+#define BADGE4_GPIO_UART_HS1 GPIO_GPIO13
+#define BADGE4_GPIO_UART_HS2 GPIO_GPIO14
+
+#define BADGE4_GPIO_MUXSEL0 GPIO_GPIO15
+#define BADGE4_GPIO_TESTPT_J7 GPIO_GPIO16
+
+#define BADGE4_GPIO_SDSDA GPIO_GPIO17 /* SDRAM SPD Data */
+#define BADGE4_GPIO_SDSCL GPIO_GPIO18 /* SDRAM SPD Clock */
+#define BADGE4_GPIO_SDTYP0 GPIO_GPIO19 /* SDRAM Type Control */
+#define BADGE4_GPIO_SDTYP1 GPIO_GPIO20 /* SDRAM Type Control */
+
+#define BADGE4_GPIO_BGNT_1111 GPIO_GPIO21 /* GPIO_MBGNT */
+#define BADGE4_GPIO_BREQ_1111 GPIO_GPIO22 /* GPIO_TREQA */
+
+#define BADGE4_GPIO_TESTPT_J6 GPIO_GPIO23
+
+#define BADGE4_GPIO_PCMEN5V GPIO_GPIO24 /* 5V power */
+
+#define BADGE4_GPIO_SA1111_NRST GPIO_GPIO25 /* SA-1111 nRESET */
+
+#define BADGE4_GPIO_TESTPT_J5 GPIO_GPIO26
+
+#define BADGE4_GPIO_CLK_1111 GPIO_GPIO27 /* GPIO_32_768kHz */
+
+/* Interrupts on the BadgePAD 4 */
+#define BADGE4_IRQ_GPIO_SA1111 IRQ_GPIO0 /* SA-1111 interrupt */
+
+
+/* PCM5ENV Usage tracking */
+
+#define BADGE4_5V_PCMCIA_SOCK0 (1<<0)
+#define BADGE4_5V_PCMCIA_SOCK1 (1<<1)
+#define BADGE4_5V_PCMCIA_SOCK(n) (1<<(n))
+#define BADGE4_5V_USB (1<<2)
+#define BADGE4_5V_INITIALLY (1<<3)
+
+#ifndef __ASSEMBLY__
+extern void badge4_set_5V(unsigned subsystem, int on);
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/bitfield.h b/arch/arm/mach-sa1100/include/mach/bitfield.h
new file mode 100644
index 00000000..f1f0e338
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/bitfield.h
@@ -0,0 +1,113 @@
+/*
+ * FILE bitfield.h
+ *
+ * Version 1.1
+ * Author Copyright (c) Marc A. Viredaz, 1998
+ * DEC Western Research Laboratory, Palo Alto, CA
+ * Date April 1998 (April 1997)
+ * System Advanced RISC Machine (ARM)
+ * Language C or ARM Assembly
+ * Purpose Definition of macros to operate on bit fields.
+ */
+
+
+
+#ifndef __BITFIELD_H
+#define __BITFIELD_H
+
+#ifndef __ASSEMBLY__
+#define UData(Data) ((unsigned long) (Data))
+#else
+#define UData(Data) (Data)
+#endif
+
+
+/*
+ * MACRO: Fld
+ *
+ * Purpose
+ * The macro "Fld" encodes a bit field, given its size and its shift value
+ * with respect to bit 0.
+ *
+ * Note
+ * A more intuitive way to encode bit fields would have been to use their
+ * mask. However, extracting size and shift value information from a bit
+ * field's mask is cumbersome and might break the assembler (255-character
+ * line-size limit).
+ *
+ * Input
+ * Size Size of the bit field, in number of bits.
+ * Shft Shift value of the bit field with respect to bit 0.
+ *
+ * Output
+ * Fld Encoded bit field.
+ */
+
+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
+
+
+/*
+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
+ *
+ * Purpose
+ * The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
+ * the size, shift value, mask, aligned mask, and first bit of a
+ * bit field.
+ *
+ * Input
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FSize Size of the bit field, in number of bits.
+ * FShft Shift value of the bit field with respect to bit 0.
+ * FMsk Mask for the bit field.
+ * FAlnMsk Mask for the bit field, aligned on bit 0.
+ * F1stBit First bit of the bit field.
+ */
+
+#define FSize(Field) ((Field) >> 16)
+#define FShft(Field) ((Field) & 0x0000FFFF)
+#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field) (UData (1) << FShft (Field))
+
+
+/*
+ * MACRO: FInsrt
+ *
+ * Purpose
+ * The macro "FInsrt" inserts a value into a bit field by shifting the
+ * former appropriately.
+ *
+ * Input
+ * Value Bit-field value.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FInsrt Bit-field value positioned appropriately.
+ */
+
+#define FInsrt(Value, Field) \
+ (UData (Value) << FShft (Field))
+
+
+/*
+ * MACRO: FExtr
+ *
+ * Purpose
+ * The macro "FExtr" extracts the value of a bit field by masking and
+ * shifting it appropriately.
+ *
+ * Input
+ * Data Data containing the bit-field to be extracted.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FExtr Bit-field value.
+ */
+
+#define FExtr(Data, Field) \
+ ((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+
+#endif /* __BITFIELD_H */
diff --git a/arch/arm/mach-sa1100/include/mach/cerf.h b/arch/arm/mach-sa1100/include/mach/cerf.h
new file mode 100644
index 00000000..c3ac3d0f
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/cerf.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/cerf.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Apr-2003 : Removed some old PDA crud [FB]
+ */
+#ifndef _INCLUDE_CERF_H_
+#define _INCLUDE_CERF_H_
+
+
+#define CERF_ETH_IO 0xf0000000
+#define CERF_ETH_IRQ IRQ_GPIO26
+
+#define CERF_GPIO_CF_BVD2 GPIO_GPIO (19)
+#define CERF_GPIO_CF_BVD1 GPIO_GPIO (20)
+#define CERF_GPIO_CF_RESET GPIO_GPIO (21)
+#define CERF_GPIO_CF_IRQ GPIO_GPIO (22)
+#define CERF_GPIO_CF_CD GPIO_GPIO (23)
+
+#define CERF_IRQ_GPIO_CF_BVD2 IRQ_GPIO19
+#define CERF_IRQ_GPIO_CF_BVD1 IRQ_GPIO20
+#define CERF_IRQ_GPIO_CF_IRQ IRQ_GPIO22
+#define CERF_IRQ_GPIO_CF_CD IRQ_GPIO23
+
+#endif // _INCLUDE_CERF_H_
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
new file mode 100644
index 00000000..52acda70
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/collie.h
+ *
+ * This file contains the hardware specific definitions for Assabet
+ * Only include this file from SA1100-specific files.
+ *
+ * ChangeLog:
+ * 04-06-2001 Lineo Japan, Inc.
+ * 04-16-2001 SHARP Corporation
+ * 07-07-2002 Chris Larson <clarson@digi.com>
+ *
+ */
+#ifndef __ASM_ARCH_COLLIE_H
+#define __ASM_ARCH_COLLIE_H
+
+
+#define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1)
+#define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0)
+#define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12
+#define COLLIE_SCP_DIAG_BOOT2 SCOOP_GPCR_PA13
+#define COLLIE_SCP_MUTE_L SCOOP_GPCR_PA14
+#define COLLIE_SCP_MUTE_R SCOOP_GPCR_PA15
+#define COLLIE_SCP_5VON SCOOP_GPCR_PA16
+#define COLLIE_SCP_AMP_ON SCOOP_GPCR_PA17
+#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
+#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
+
+#define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
+ COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+ COLLIE_SCP_LB_VOL_CHG)
+#define COLLIE_SCOOP_IO_OUT (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
+
+/* GPIOs for gpiolib */
+
+#define COLLIE_GPIO_ON_KEY (0)
+#define COLLIE_GPIO_AC_IN (1)
+#define COLLIE_GPIO_SDIO_INT (11)
+#define COLLIE_GPIO_CF_IRQ (14)
+#define COLLIE_GPIO_nREMOCON_INT (15)
+#define COLLIE_GPIO_UCB1x00_RESET (16)
+#define COLLIE_GPIO_nMIC_ON (17)
+#define COLLIE_GPIO_nREMOCON_ON (18)
+#define COLLIE_GPIO_CO (20)
+#define COLLIE_GPIO_MCP_CLK (21)
+#define COLLIE_GPIO_CF_CD (22)
+#define COLLIE_GPIO_UCB1x00_IRQ (23)
+#define COLLIE_GPIO_WAKEUP (24)
+#define COLLIE_GPIO_GA_INT (25)
+#define COLLIE_GPIO_MAIN_BAT_LOW (26)
+
+/* GPIO definitions for direct register access */
+
+#define _COLLIE_GPIO_ON_KEY GPIO_GPIO(0)
+#define _COLLIE_GPIO_AC_IN GPIO_GPIO(1)
+#define _COLLIE_GPIO_nREMOCON_INT GPIO_GPIO(15)
+#define _COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO(16)
+#define _COLLIE_GPIO_nMIC_ON GPIO_GPIO(17)
+#define _COLLIE_GPIO_nREMOCON_ON GPIO_GPIO(18)
+#define _COLLIE_GPIO_CO GPIO_GPIO(20)
+#define _COLLIE_GPIO_WAKEUP GPIO_GPIO(24)
+/* Interrupts */
+
+#define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0
+#define COLLIE_IRQ_GPIO_AC_IN IRQ_GPIO1
+#define COLLIE_IRQ_GPIO_SDIO_IRQ IRQ_GPIO11
+#define COLLIE_IRQ_GPIO_CF_IRQ IRQ_GPIO14
+#define COLLIE_IRQ_GPIO_nREMOCON_INT IRQ_GPIO15
+#define COLLIE_IRQ_GPIO_CO IRQ_GPIO20
+#define COLLIE_IRQ_GPIO_CF_CD IRQ_GPIO22
+#define COLLIE_IRQ_GPIO_UCB1x00_IRQ IRQ_GPIO23
+#define COLLIE_IRQ_GPIO_WAKEUP IRQ_GPIO24
+#define COLLIE_IRQ_GPIO_GA_INT IRQ_GPIO25
+#define COLLIE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO26
+
+/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
+#define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13)
+#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
+#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
+#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
+#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3
+#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
+#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
+#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
+#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
+#define COLLIE_GPIO_MBAT_ON (COLLIE_TC35143_GPIO_BASE + 7)
+#define COLLIE_GPIO_BBAT_ON (COLLIE_TC35143_GPIO_BASE + 8)
+#define COLLIE_GPIO_TMP_ON (COLLIE_TC35143_GPIO_BASE + 9)
+#define COLLIE_TC35143_GPIO_IN (UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
+#define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
+ | UCB_IO_6)
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/debug-macro.S b/arch/arm/mach-sa1100/include/mach/debug-macro.S
new file mode 100644
index 00000000..0cd0fc96
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/debug-macro.S
@@ -0,0 +1,62 @@
+/* arch/arm/mach-sa1100/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+#include <mach/hardware.h>
+
+ .macro addruart, rp, rv
+ mrc p15, 0, \rp, c1, c0
+ tst \rp, #1 @ MMU enabled?
+ moveq \rp, #0x80000000 @ physical base address
+ movne \rp, #0xf8000000 @ virtual address
+
+ @ We probe for the active serial port here, coherently with
+ @ the comment in arch/arm/mach-sa1100/include/mach/uncompress.h.
+ @ We assume r1 can be clobbered.
+
+ @ see if Ser3 is active
+ add \rp, \rp, #0x00050000
+ ldr \rv, [\rp, #UTCR3]
+ tst \rv, #UTCR3_TXE
+
+ @ if Ser3 is inactive, then try Ser1
+ addeq \rp, \rp, #(0x00010000 - 0x00050000)
+ ldreq \rv, [\rp, #UTCR3]
+ tsteq \rv, #UTCR3_TXE
+
+ @ if Ser1 is inactive, then try Ser2
+ addeq \rp, \rp, #(0x00030000 - 0x00010000)
+ ldreq \rv, [\rp, #UTCR3]
+ tsteq \rv, #UTCR3_TXE
+
+ @ clear top bits, and generate both phys and virt addresses
+ lsl \rp, \rp, #8
+ lsr \rp, \rp, #8
+ orr \rv, \rp, #0xf8000000 @ virtual
+ orr \rp, \rp, #0x80000000 @ physical
+
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #UTDR]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #UTSR1]
+ tst \rd, #UTSR1_TNF
+ beq 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #UTSR1]
+ tst \rd, #UTSR1_TBY
+ bne 1001b
+ .endm
diff --git a/arch/arm/mach-sa1100/include/mach/dma.h b/arch/arm/mach-sa1100/include/mach/dma.h
new file mode 100644
index 00000000..dda1b351
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/dma.h
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/dma.h
+ *
+ * Generic SA1100 DMA support
+ *
+ * Copyright (C) 2000 Nicolas Pitre
+ *
+ */
+
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include "hardware.h"
+
+
+/*
+ * The SA1100 has six internal DMA channels.
+ */
+#define SA1100_DMA_CHANNELS 6
+
+/*
+ * Maximum physical DMA buffer size
+ */
+#define MAX_DMA_SIZE 0x1fff
+#define CUT_DMA_SIZE 0x1000
+
+/*
+ * All possible SA1100 devices a DMA channel can be attached to.
+ */
+typedef enum {
+ DMA_Ser0UDCWr = DDAR_Ser0UDCWr, /* Ser. port 0 UDC Write */
+ DMA_Ser0UDCRd = DDAR_Ser0UDCRd, /* Ser. port 0 UDC Read */
+ DMA_Ser1UARTWr = DDAR_Ser1UARTWr, /* Ser. port 1 UART Write */
+ DMA_Ser1UARTRd = DDAR_Ser1UARTRd, /* Ser. port 1 UART Read */
+ DMA_Ser1SDLCWr = DDAR_Ser1SDLCWr, /* Ser. port 1 SDLC Write */
+ DMA_Ser1SDLCRd = DDAR_Ser1SDLCRd, /* Ser. port 1 SDLC Read */
+ DMA_Ser2UARTWr = DDAR_Ser2UARTWr, /* Ser. port 2 UART Write */
+ DMA_Ser2UARTRd = DDAR_Ser2UARTRd, /* Ser. port 2 UART Read */
+ DMA_Ser2HSSPWr = DDAR_Ser2HSSPWr, /* Ser. port 2 HSSP Write */
+ DMA_Ser2HSSPRd = DDAR_Ser2HSSPRd, /* Ser. port 2 HSSP Read */
+ DMA_Ser3UARTWr = DDAR_Ser3UARTWr, /* Ser. port 3 UART Write */
+ DMA_Ser3UARTRd = DDAR_Ser3UARTRd, /* Ser. port 3 UART Read */
+ DMA_Ser4MCP0Wr = DDAR_Ser4MCP0Wr, /* Ser. port 4 MCP 0 Write (audio) */
+ DMA_Ser4MCP0Rd = DDAR_Ser4MCP0Rd, /* Ser. port 4 MCP 0 Read (audio) */
+ DMA_Ser4MCP1Wr = DDAR_Ser4MCP1Wr, /* Ser. port 4 MCP 1 Write */
+ DMA_Ser4MCP1Rd = DDAR_Ser4MCP1Rd, /* Ser. port 4 MCP 1 Read */
+ DMA_Ser4SSPWr = DDAR_Ser4SSPWr, /* Ser. port 4 SSP Write (16 bits) */
+ DMA_Ser4SSPRd = DDAR_Ser4SSPRd /* Ser. port 4 SSP Read (16 bits) */
+} dma_device_t;
+
+typedef struct {
+ volatile u_long DDAR;
+ volatile u_long SetDCSR;
+ volatile u_long ClrDCSR;
+ volatile u_long RdDCSR;
+ volatile dma_addr_t DBSA;
+ volatile u_long DBTA;
+ volatile dma_addr_t DBSB;
+ volatile u_long DBTB;
+} dma_regs_t;
+
+typedef void (*dma_callback_t)(void *data);
+
+/*
+ * DMA function prototypes
+ */
+
+extern int sa1100_request_dma( dma_device_t device, const char *device_id,
+ dma_callback_t callback, void *data,
+ dma_regs_t **regs );
+extern void sa1100_free_dma( dma_regs_t *regs );
+extern int sa1100_start_dma( dma_regs_t *regs, dma_addr_t dma_ptr, u_int size );
+extern dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs);
+extern void sa1100_reset_dma(dma_regs_t *regs);
+
+/**
+ * sa1100_stop_dma - stop DMA in progress
+ * @regs: identifier for the channel to use
+ *
+ * This stops DMA without clearing buffer pointers. Unlike
+ * sa1100_clear_dma() this allows subsequent use of sa1100_resume_dma()
+ * or sa1100_get_dma_pos().
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ **/
+
+#define sa1100_stop_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN)
+
+/**
+ * sa1100_resume_dma - resume DMA on a stopped channel
+ * @regs: identifier for the channel to use
+ *
+ * This resumes DMA on a channel previously stopped with
+ * sa1100_stop_dma().
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ **/
+
+#define sa1100_resume_dma(regs) ((regs)->SetDCSR = DCSR_IE|DCSR_RUN)
+
+/**
+ * sa1100_clear_dma - clear DMA pointers
+ * @regs: identifier for the channel to use
+ *
+ * This clear any DMA state so the DMA engine is ready to restart
+ * with new buffers through sa1100_start_dma(). Any buffers in flight
+ * are discarded.
+ *
+ * The @regs identifier is provided by a successful call to
+ * sa1100_request_dma().
+ **/
+
+#define sa1100_clear_dma(regs) ((regs)->ClrDCSR = DCSR_IE|DCSR_RUN|DCSR_STRTA|DCSR_STRTB)
+
+#endif /* _ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-sa1100/include/mach/entry-macro.S b/arch/arm/mach-sa1100/include/mach/entry-macro.S
new file mode 100644
index 00000000..6aa13c46
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/entry-macro.S
@@ -0,0 +1,47 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SA1100-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ mov \base, #0xfa000000 @ ICIP = 0xfa050000
+ add \base, \base, #0x00050000
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base] @ get irqs
+ ldr \irqnr, [\base, #4] @ ICMR = 0xfa050004
+ ands \irqstat, \irqstat, \irqnr
+ mov \irqnr, #0
+ beq 1001f
+ tst \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tsteq \irqstat, #0xff
+ moveq \irqstat, \irqstat, lsr #8
+ addeq \irqnr, \irqnr, #8
+ tst \irqstat, #0x0f
+ moveq \irqstat, \irqstat, lsr #4
+ addeq \irqnr, \irqnr, #4
+ tst \irqstat, #0x03
+ moveq \irqstat, \irqstat, lsr #2
+ addeq \irqnr, \irqnr, #2
+ tst \irqstat, #0x01
+ addeqs \irqnr, \irqnr, #1
+1001:
+ .endm
+
diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h
new file mode 100644
index 00000000..7befc104
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/gpio.h
@@ -0,0 +1,57 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/gpio.h
+ *
+ * SA1100 GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.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 __ASM_ARCH_SA1100_GPIO_H
+#define __ASM_ARCH_SA1100_GPIO_H
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm-generic/gpio.h>
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
+ return GPLR & GPIO_GPIO(gpio);
+ else
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (__builtin_constant_p(gpio) && (gpio <= GPIO_MAX))
+ if (value)
+ GPSR = GPIO_GPIO(gpio);
+ else
+ GPCR = GPIO_GPIO(gpio);
+ else
+ __gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
+ (IRQ_GPIO11 - 11 + gpio))
+#define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
+ (irq - IRQ_GPIO11 + 11))
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/h3xxx.h b/arch/arm/mach-sa1100/include/mach/h3xxx.h
new file mode 100644
index 00000000..7d9df16f
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/h3xxx.h
@@ -0,0 +1,94 @@
+/*
+ * Definitions for Compaq iPAQ H3100 and H3600 handheld computers
+ *
+ * (c) 2000 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ *
+ * This program is free software; you can 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 _INCLUDE_H3XXX_H_
+#define _INCLUDE_H3XXX_H_
+
+/* Physical memory regions corresponding to chip selects */
+#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
+#define H3600_BANK_2_PHYS SA1100_CS2_PHYS
+#define H3600_BANK_4_PHYS SA1100_CS4_PHYS
+
+/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
+#define H3600_EGPIO_VIRT 0xf0000000
+#define H3600_BANK_2_VIRT 0xf1000000
+#define H3600_BANK_4_VIRT 0xf3800000
+
+/*
+ * gpiolib numbers for all iPAQs
+ */
+#define H3XXX_GPIO_PWR_BUTTON 0
+#define H3XXX_GPIO_PCMCIA_CD1 10
+#define H3XXX_GPIO_PCMCIA_IRQ1 11
+#define H3XXX_GPIO_PCMCIA_CD0 17
+#define H3XXX_GPIO_ACTION_BUTTON 18
+#define H3XXX_GPIO_SYS_CLK 19
+#define H3XXX_GPIO_PCMCIA_IRQ0 21
+#define H3XXX_GPIO_COM_DCD 23
+#define H3XXX_GPIO_OPTION 24
+#define H3XXX_GPIO_COM_CTS 25
+#define H3XXX_GPIO_COM_RTS 26
+
+/* machine-specific gpios */
+
+#define H3100_GPIO_BT_ON 2
+#define H3100_GPIO_QMUTE 4
+#define H3100_GPIO_LCD_3V_ON 5
+#define H3100_GPIO_AUD_ON 6
+#define H3100_GPIO_AUD_PWR_ON 7
+#define H3100_GPIO_IR_ON 8
+#define H3100_GPIO_IR_FSEL 9
+
+#define H3600_GPIO_CLK_SET0 12 /* audio sample rate clock generator */
+#define H3600_GPIO_CLK_SET1 13
+#define H3600_GPIO_SOFT_RESET 20 /* also known as BATT_FAULT */
+#define H3600_GPIO_OPT_LOCK 22
+#define H3600_GPIO_OPT_DET 27
+
+
+/* H3100 / 3600 EGPIO pins */
+#define H3XXX_EGPIO_BASE (GPIO_MAX + 1)
+
+#define H3XXX_EGPIO_VPP_ON (H3XXX_EGPIO_BASE + 0)
+#define H3XXX_EGPIO_CARD_RESET (H3XXX_EGPIO_BASE + 1) /* reset the attached pcmcia/compactflash card. active high. */
+#define H3XXX_EGPIO_OPT_RESET (H3XXX_EGPIO_BASE + 2) /* reset the attached option pack. active high. */
+#define H3XXX_EGPIO_CODEC_NRESET (H3XXX_EGPIO_BASE + 3) /* reset the onboard UDA1341. active low. */
+#define H3XXX_EGPIO_OPT_NVRAM_ON (H3XXX_EGPIO_BASE + 4) /* apply power to optionpack nvram, active high. */
+#define H3XXX_EGPIO_OPT_ON (H3XXX_EGPIO_BASE + 5) /* full power to option pack. active high. */
+#define H3XXX_EGPIO_LCD_ON (H3XXX_EGPIO_BASE + 6) /* enable 3.3V to LCD. active high. */
+#define H3XXX_EGPIO_RS232_ON (H3XXX_EGPIO_BASE + 7) /* UART3 transceiver force on. Active high. */
+
+/* H3600 only EGPIO pins */
+#define H3600_EGPIO_LCD_PCI (H3XXX_EGPIO_BASE + 8) /* LCD control IC enable. active high. */
+#define H3600_EGPIO_IR_ON (H3XXX_EGPIO_BASE + 9) /* apply power to IR module. active high. */
+#define H3600_EGPIO_AUD_AMP_ON (H3XXX_EGPIO_BASE + 10) /* apply power to audio power amp. active high. */
+#define H3600_EGPIO_AUD_PWR_ON (H3XXX_EGPIO_BASE + 11) /* apply power to reset of audio circuit. active high. */
+#define H3600_EGPIO_QMUTE (H3XXX_EGPIO_BASE + 12) /* mute control for onboard UDA1341. active high. */
+#define H3600_EGPIO_IR_FSEL (H3XXX_EGPIO_BASE + 13) /* IR speed select: 1->fast, 0->slow */
+#define H3600_EGPIO_LCD_5V_ON (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
+#define H3600_EGPIO_LVDD_ON (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
+
+struct gpio_default_state {
+ int gpio;
+ int mode;
+ const char *name;
+};
+
+#define GPIO_MODE_IN -1
+#define GPIO_MODE_OUT0 0
+#define GPIO_MODE_OUT1 1
+
+void h3xxx_init_gpio(struct gpio_default_state *s, size_t n);
+void __init h3xxx_map_io(void);
+void __init h3xxx_mach_init(void);
+
+#endif /* _INCLUDE_H3XXX_H_ */
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
new file mode 100644
index 00000000..967ae768
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -0,0 +1,87 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/hardware.h
+ *
+ * Copyright (C) 1998 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware definitions for SA1100 architecture
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for SA1111 added.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+
+#define UNCACHEABLE_ADDR 0xfa050000
+
+
+/*
+ * SA1100 internal I/O mappings
+ *
+ * We have the following mapping:
+ * phys virt
+ * 80000000 f8000000
+ * 90000000 fa000000
+ * a0000000 fc000000
+ * b0000000 fe000000
+ */
+
+#define VIO_BASE 0xf8000000 /* virtual start of IO space */
+#define VIO_SHIFT 3 /* x = IO space shrink power */
+#define PIO_START 0x80000000 /* physical start of IO space */
+
+#define io_p2v( x ) \
+ ( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE )
+#define io_v2p( x ) \
+ ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
+
+#define CPU_SA1110_A0 (0)
+#define CPU_SA1110_B0 (4)
+#define CPU_SA1110_B1 (5)
+#define CPU_SA1110_B2 (6)
+#define CPU_SA1110_B4 (8)
+
+#define CPU_SA1100_ID (0x4401a110)
+#define CPU_SA1100_MASK (0xfffffff0)
+#define CPU_SA1110_ID (0x6901b110)
+#define CPU_SA1110_MASK (0xfffffff0)
+
+#ifndef __ASSEMBLY__
+
+#include <asm/cputype.h>
+
+#define CPU_REVISION (read_cpuid_id() & 15)
+
+#define cpu_is_sa1100() ((read_cpuid_id() & CPU_SA1100_MASK) == CPU_SA1100_ID)
+#define cpu_is_sa1110() ((read_cpuid_id() & CPU_SA1110_MASK) == CPU_SA1110_ID)
+
+# define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
+# define __PREG(x) (io_v2p((unsigned long)&(x)))
+
+static inline unsigned long get_clock_tick_rate(void)
+{
+ return 3686400;
+}
+#else
+
+# define __REG(x) io_p2v(x)
+# define __PREG(x) io_v2p(x)
+
+#endif
+
+#include "SA-1100.h"
+
+#ifdef CONFIG_SA1101
+#include "SA-1101.h"
+#endif
+
+#if defined(CONFIG_ARCH_SA1100) && defined(CONFIG_PCI)
+#define PCIBIOS_MIN_IO 0
+#define PCIBIOS_MIN_MEM 0
+#define pcibios_assign_all_busses() 1
+#define HAVE_ARCH_PCI_SET_DMA_MASK 1
+#endif
+
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-sa1100/include/mach/io.h b/arch/arm/mach-sa1100/include/mach/io.h
new file mode 100644
index 00000000..d8b43f3d
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
new file mode 100644
index 00000000..d18f21ab
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/irqs.h
+ *
+ * Copyright (C) 1996 Russell King
+ * Copyright (C) 1998 Deborah Wallach (updates for SA1100/Brutus).
+ * Copyright (C) 1999 Nicolas Pitre (full GPIO irq isolation)
+ *
+ * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
+ */
+
+#define IRQ_GPIO0 0
+#define IRQ_GPIO1 1
+#define IRQ_GPIO2 2
+#define IRQ_GPIO3 3
+#define IRQ_GPIO4 4
+#define IRQ_GPIO5 5
+#define IRQ_GPIO6 6
+#define IRQ_GPIO7 7
+#define IRQ_GPIO8 8
+#define IRQ_GPIO9 9
+#define IRQ_GPIO10 10
+#define IRQ_GPIO11_27 11
+#define IRQ_LCD 12 /* LCD controller */
+#define IRQ_Ser0UDC 13 /* Ser. port 0 UDC */
+#define IRQ_Ser1SDLC 14 /* Ser. port 1 SDLC */
+#define IRQ_Ser1UART 15 /* Ser. port 1 UART */
+#define IRQ_Ser2ICP 16 /* Ser. port 2 ICP */
+#define IRQ_Ser3UART 17 /* Ser. port 3 UART */
+#define IRQ_Ser4MCP 18 /* Ser. port 4 MCP */
+#define IRQ_Ser4SSP 19 /* Ser. port 4 SSP */
+#define IRQ_DMA0 20 /* DMA controller channel 0 */
+#define IRQ_DMA1 21 /* DMA controller channel 1 */
+#define IRQ_DMA2 22 /* DMA controller channel 2 */
+#define IRQ_DMA3 23 /* DMA controller channel 3 */
+#define IRQ_DMA4 24 /* DMA controller channel 4 */
+#define IRQ_DMA5 25 /* DMA controller channel 5 */
+#define IRQ_OST0 26 /* OS Timer match 0 */
+#define IRQ_OST1 27 /* OS Timer match 1 */
+#define IRQ_OST2 28 /* OS Timer match 2 */
+#define IRQ_OST3 29 /* OS Timer match 3 */
+#define IRQ_RTC1Hz 30 /* RTC 1 Hz clock */
+#define IRQ_RTCAlrm 31 /* RTC Alarm */
+
+#define IRQ_GPIO11 32
+#define IRQ_GPIO12 33
+#define IRQ_GPIO13 34
+#define IRQ_GPIO14 35
+#define IRQ_GPIO15 36
+#define IRQ_GPIO16 37
+#define IRQ_GPIO17 38
+#define IRQ_GPIO18 39
+#define IRQ_GPIO19 40
+#define IRQ_GPIO20 41
+#define IRQ_GPIO21 42
+#define IRQ_GPIO22 43
+#define IRQ_GPIO23 44
+#define IRQ_GPIO24 45
+#define IRQ_GPIO25 46
+#define IRQ_GPIO26 47
+#define IRQ_GPIO27 48
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase IRQ_BOARD_END, but keep it
+ * within sensible limits. IRQs 49 to 64 are available.
+ */
+#define IRQ_BOARD_START 49
+#define IRQ_BOARD_END 65
+
+/*
+ * Figure out the MAX IRQ number.
+ *
+ * If we have an SA1111, the max IRQ is S1_BVD1_STSCHG+1.
+ * If we have an LoCoMo, the max IRQ is IRQ_BOARD_START + 4
+ * Otherwise, we have the standard IRQs only.
+ */
+#ifdef CONFIG_SA1111
+#define NR_IRQS (IRQ_BOARD_END + 55)
+#elif defined(CONFIG_SHARP_LOCOMO)
+#define NR_IRQS (IRQ_BOARD_START + 4)
+#else
+#define NR_IRQS (IRQ_BOARD_START)
+#endif
+
+/*
+ * Board specific IRQs. Define them here.
+ * Do not surround them with ifdefs.
+ */
+#define IRQ_NEPONSET_SMC9196 (IRQ_BOARD_START + 0)
+#define IRQ_NEPONSET_USAR (IRQ_BOARD_START + 1)
+#define IRQ_NEPONSET_SA1111 (IRQ_BOARD_START + 2)
diff --git a/arch/arm/mach-sa1100/include/mach/jornada720.h b/arch/arm/mach-sa1100/include/mach/jornada720.h
new file mode 100644
index 00000000..cc6b4bfc
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/jornada720.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/jornada720.h
+ *
+ * SSP/MCU communication definitions for HP Jornada 710/720/728
+ *
+ * Copyright 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright 2000 John Ankcorn <jca@lcs.mit.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+ /* HP Jornada 7xx microprocessor commands */
+#define GETBATTERYDATA 0xc0
+#define GETSCANKEYCODE 0x90
+#define GETTOUCHSAMPLES 0xa0
+#define GETCONTRAST 0xD0
+#define SETCONTRAST 0xD1
+#define GETBRIGHTNESS 0xD2
+#define SETBRIGHTNESS 0xD3
+#define CONTRASTOFF 0xD8
+#define BRIGHTNESSOFF 0xD9
+#define PWMOFF 0xDF
+#define TXDUMMY 0x11
+#define ERRORCODE 0x00
+
+extern void jornada_ssp_start(void);
+extern void jornada_ssp_end(void);
+extern int jornada_ssp_inout(u8 byte);
+extern int jornada_ssp_byte(u8 byte);
diff --git a/arch/arm/mach-sa1100/include/mach/lart.h b/arch/arm/mach-sa1100/include/mach/lart.h
new file mode 100644
index 00000000..8a5482d9
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/lart.h
@@ -0,0 +1,13 @@
+#ifndef _INCLUDE_LART_H
+#define _INCLUDE_LART_H
+
+#define LART_GPIO_ETH0 GPIO_GPIO0
+#define LART_IRQ_ETH0 IRQ_GPIO0
+
+#define LART_GPIO_IDE GPIO_GPIO1
+#define LART_IRQ_IDE IRQ_GPIO1
+
+#define LART_GPIO_UCB1200 GPIO_GPIO18
+#define LART_IRQ_UCB1200 IRQ_GPIO18
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h
new file mode 100644
index 00000000..ed1a3315
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/mcp.h
+ *
+ * Copyright (C) 2005 Russell King.
+ *
+ * This program is free software; you can 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_MCP_H
+#define __ASM_ARM_ARCH_MCP_H
+
+#include <linux/types.h>
+
+struct mcp_plat_data {
+ u32 mccr0;
+ u32 mccr1;
+ unsigned int sclk_rate;
+ int gpio_base;
+};
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
new file mode 100644
index 00000000..cff31ee2
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/memory.h
+ *
+ * Copyright (C) 1999-2000 Nicolas Pitre <nico@fluxnic.net>
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/sizes.h>
+
+/*
+ * Physical DRAM offset is 0xc0000000 on the SA1100
+ */
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
+
+#ifdef CONFIG_SA1111
+#define ARM_DMA_ZONE_SIZE SZ_1M
+#endif
+
+/*
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much convenient to use Linux's SparseMEM support to implement
+ * our memory map representation. Assuming all memory nodes have equal access
+ * characteristics, we then have generic discontiguous memory support.
+ *
+ * The sparsemem banks are matched with the physical memory bank addresses
+ * which are incidentally the same as virtual addresses.
+ *
+ * node 0: 0xc0000000 - 0xc7ffffff
+ * node 1: 0xc8000000 - 0xcfffffff
+ * node 2: 0xd0000000 - 0xd7ffffff
+ * node 3: 0xd8000000 - 0xdfffffff
+ */
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 27
+
+/*
+ * Cache flushing area - SA1100 zero bank
+ */
+#define FLUSH_BASE_PHYS 0xe0000000
+#define FLUSH_BASE 0xf5000000
+#define FLUSH_BASE_MINICACHE 0xf5100000
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/mtd-xip.h b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
new file mode 100644
index 00000000..b3d68409
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
@@ -0,0 +1,26 @@
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 2, 2004
+ * Copyright: (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_SA1100_MTD_XIP_H__
+#define __ARCH_SA1100_MTD_XIP_H__
+
+#include <mach/hardware.h>
+
+#define xip_irqpending() (ICIP & ICMR)
+
+/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
+#define xip_currtime() (OSCR)
+#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4)
+
+#endif /* __ARCH_SA1100_MTD_XIP_H__ */
diff --git a/arch/arm/mach-sa1100/include/mach/nanoengine.h b/arch/arm/mach-sa1100/include/mach/nanoengine.h
new file mode 100644
index 00000000..14f8382d
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/nanoengine.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/nanoengine.h
+ *
+ * This file contains the hardware specific definitions for nanoEngine.
+ * Only include this file from SA1100-specific files.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can 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_NANOENGINE_H
+#define __ASM_ARCH_NANOENGINE_H
+
+#include <mach/irqs.h>
+
+#define GPIO_PC_READY0 GPIO_GPIO(11) /* ready for socket 0 (active high)*/
+#define GPIO_PC_READY1 GPIO_GPIO(12) /* ready for socket 1 (active high) */
+#define GPIO_PC_CD0 GPIO_GPIO(13) /* detect for socket 0 (active low) */
+#define GPIO_PC_CD1 GPIO_GPIO(14) /* detect for socket 1 (active low) */
+#define GPIO_PC_RESET0 GPIO_GPIO(15) /* reset socket 0 */
+#define GPIO_PC_RESET1 GPIO_GPIO(16) /* reset socket 1 */
+
+#define NANOENGINE_IRQ_GPIO_PCI IRQ_GPIO0
+#define NANOENGINE_IRQ_GPIO_PC_READY0 IRQ_GPIO11
+#define NANOENGINE_IRQ_GPIO_PC_READY1 IRQ_GPIO12
+#define NANOENGINE_IRQ_GPIO_PC_CD0 IRQ_GPIO13
+#define NANOENGINE_IRQ_GPIO_PC_CD1 IRQ_GPIO14
+
+/*
+ * nanoEngine Memory Map:
+ *
+ * 0000.0000 - 003F.0000 - 4 MB Flash
+ * C000.0000 - C1FF.FFFF - 32 MB SDRAM
+ * 1860.0000 - 186F.FFFF - 1 MB Internal PCI Memory Read/Write
+ * 18A1.0000 - 18A1.FFFF - 64 KB Internal PCI Config Space
+ * 4000.0000 - 47FF.FFFF - 128 MB External Bus I/O - Multiplexed Mode
+ * 4800.0000 - 4FFF.FFFF - 128 MB External Bus I/O - Non-Multiplexed Mode
+ *
+ */
+
+#define NANO_PCI_MEM_RW_PHYS 0x18600000
+#define NANO_PCI_MEM_RW_VIRT 0xf1000000
+#define NANO_PCI_MEM_RW_SIZE SZ_1M
+#define NANO_PCI_CONFIG_SPACE_PHYS 0x18A10000
+#define NANO_PCI_CONFIG_SPACE_VIRT 0xf2000000
+#define NANO_PCI_CONFIG_SPACE_SIZE SZ_64K
+
+#endif
+
diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h
new file mode 100644
index 00000000..ffe2bc45
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/neponset.h
@@ -0,0 +1,74 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/neponset.h
+ *
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware specific definitions for Assabet
+ * Only include this file from SA1100-specific files.
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for Neponset added.
+ */
+#ifndef __ASM_ARCH_NEPONSET_H
+#define __ASM_ARCH_NEPONSET_H
+
+/*
+ * Neponset definitions:
+ */
+
+#define NEPONSET_CPLD_BASE (0x10000000)
+#define Nep_p2v( x ) ((x) - NEPONSET_CPLD_BASE + 0xf3000000)
+#define Nep_v2p( x ) ((x) - 0xf3000000 + NEPONSET_CPLD_BASE)
+
+#define _IRR 0x10000024 /* Interrupt Reason Register */
+#define _AUD_CTL 0x100000c0 /* Audio controls (RW) */
+#define _MDM_CTL_0 0x100000b0 /* Modem control 0 (RW) */
+#define _MDM_CTL_1 0x100000b4 /* Modem control 1 (RW) */
+#define _NCR_0 0x100000a0 /* Control Register (RW) */
+#define _KP_X_OUT 0x10000090 /* Keypad row write (RW) */
+#define _KP_Y_IN 0x10000080 /* Keypad column read (RO) */
+#define _SWPK 0x10000020 /* Switch pack (RO) */
+#define _WHOAMI 0x10000000 /* System ID Register (RO) */
+
+#define _LEDS 0x10000010 /* LEDs [31:0] (WO) */
+
+#define IRR (*((volatile u_char *) Nep_p2v(_IRR)))
+#define AUD_CTL (*((volatile u_char *) Nep_p2v(_AUD_CTL)))
+#define MDM_CTL_0 (*((volatile u_char *) Nep_p2v(_MDM_CTL_0)))
+#define MDM_CTL_1 (*((volatile u_char *) Nep_p2v(_MDM_CTL_1)))
+#define NCR_0 (*((volatile u_char *) Nep_p2v(_NCR_0)))
+#define KP_X_OUT (*((volatile u_char *) Nep_p2v(_KP_X_OUT)))
+#define KP_Y_IN (*((volatile u_char *) Nep_p2v(_KP_Y_IN)))
+#define SWPK (*((volatile u_char *) Nep_p2v(_SWPK)))
+#define WHOAMI (*((volatile u_char *) Nep_p2v(_WHOAMI)))
+
+#define LEDS (*((volatile Word *) Nep_p2v(_LEDS)))
+
+#define IRR_ETHERNET (1<<0)
+#define IRR_USAR (1<<1)
+#define IRR_SA1111 (1<<2)
+
+#define AUD_SEL_1341 (1<<0)
+#define AUD_MUTE_1341 (1<<1)
+
+#define MDM_CTL0_RTS1 (1 << 0)
+#define MDM_CTL0_DTR1 (1 << 1)
+#define MDM_CTL0_RTS2 (1 << 2)
+#define MDM_CTL0_DTR2 (1 << 3)
+
+#define MDM_CTL1_CTS1 (1 << 0)
+#define MDM_CTL1_DSR1 (1 << 1)
+#define MDM_CTL1_DCD1 (1 << 2)
+#define MDM_CTL1_CTS2 (1 << 3)
+#define MDM_CTL1_DSR2 (1 << 4)
+#define MDM_CTL1_DCD2 (1 << 5)
+
+#define NCR_GP01_OFF (1<<0)
+#define NCR_TP_PWR_EN (1<<1)
+#define NCR_MS_PWR_EN (1<<2)
+#define NCR_ENET_OSC_EN (1<<3)
+#define NCR_SPI_KB_WK_UP (1<<4)
+#define NCR_A0VPP (1<<5)
+#define NCR_A1VPP (1<<6)
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/reset.h b/arch/arm/mach-sa1100/include/mach/reset.h
new file mode 100644
index 00000000..f61957e6
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/reset.h
@@ -0,0 +1,18 @@
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H
+
+#include "hardware.h"
+
+#define RESET_STATUS_HARDWARE (1 << 0) /* Hardware Reset */
+#define RESET_STATUS_WATCHDOG (1 << 1) /* Watchdog Reset */
+#define RESET_STATUS_LOWPOWER (1 << 2) /* Exit from Low Power/Sleep */
+#define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */
+#define RESET_STATUS_ALL (0xf)
+
+extern unsigned int reset_status;
+static inline void clear_reset_status(unsigned int mask)
+{
+ RCSR = mask;
+}
+
+#endif /* __ASM_ARCH_RESET_H */
diff --git a/arch/arm/mach-sa1100/include/mach/shannon.h b/arch/arm/mach-sa1100/include/mach/shannon.h
new file mode 100644
index 00000000..ec27d6e1
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/shannon.h
@@ -0,0 +1,43 @@
+#ifndef _INCLUDE_SHANNON_H
+#define _INCLUDE_SHANNON_H
+
+/* taken from comp.os.inferno Tue, 12 Sep 2000 09:21:50 GMT,
+ * written by <forsyth@vitanuova.com> */
+
+#define SHANNON_GPIO_SPI_FLASH GPIO_GPIO (0) /* Output - Driven low, enables SPI to flash */
+#define SHANNON_GPIO_SPI_DSP GPIO_GPIO (1) /* Output - Driven low, enables SPI to DSP */
+/* lcd lower = GPIO 2-9 */
+#define SHANNON_GPIO_SPI_OUTPUT GPIO_GPIO (10) /* Output - SPI output to DSP */
+#define SHANNON_GPIO_SPI_INPUT GPIO_GPIO (11) /* Input - SPI input from DSP */
+#define SHANNON_GPIO_SPI_CLOCK GPIO_GPIO (12) /* Output - Clock for SPI */
+#define SHANNON_GPIO_SPI_FRAME GPIO_GPIO (13) /* Output - Frame marker - not used */
+#define SHANNON_GPIO_SPI_RTS GPIO_GPIO (14) /* Input - SPI Ready to Send */
+#define SHANNON_IRQ_GPIO_SPI_RTS IRQ_GPIO14
+#define SHANNON_GPIO_SPI_CTS GPIO_GPIO (15) /* Output - SPI Clear to Send */
+#define SHANNON_GPIO_IRQ_CODEC GPIO_GPIO (16) /* in, irq from ucb1200 */
+#define SHANNON_IRQ_GPIO_IRQ_CODEC IRQ_GPIO16
+#define SHANNON_GPIO_DSP_RESET GPIO_GPIO (17) /* Output - Drive low to reset the DSP */
+#define SHANNON_GPIO_CODEC_RESET GPIO_GPIO (18) /* Output - Drive low to reset the UCB1x00 */
+#define SHANNON_GPIO_U3_RTS GPIO_GPIO (19) /* ?? */
+#define SHANNON_GPIO_U3_CTS GPIO_GPIO (20) /* ?? */
+#define SHANNON_GPIO_SENSE_12V GPIO_GPIO (21) /* Input, 12v flash unprotect detected */
+#define SHANNON_GPIO_DISP_EN GPIO_GPIO (22) /* out */
+/* XXX GPIO 23 unaccounted for */
+#define SHANNON_GPIO_EJECT_0 GPIO_GPIO (24) /* in */
+#define SHANNON_IRQ_GPIO_EJECT_0 IRQ_GPIO24
+#define SHANNON_GPIO_EJECT_1 GPIO_GPIO (25) /* in */
+#define SHANNON_IRQ_GPIO_EJECT_1 IRQ_GPIO25
+#define SHANNON_GPIO_RDY_0 GPIO_GPIO (26) /* in */
+#define SHANNON_IRQ_GPIO_RDY_0 IRQ_GPIO26
+#define SHANNON_GPIO_RDY_1 GPIO_GPIO (27) /* in */
+#define SHANNON_IRQ_GPIO_RDY_1 IRQ_GPIO27
+
+/* MCP UCB codec GPIO pins... */
+
+#define SHANNON_UCB_GPIO_BACKLIGHT 9
+#define SHANNON_UCB_GPIO_BRIGHT_MASK 7
+#define SHANNON_UCB_GPIO_BRIGHT 6
+#define SHANNON_UCB_GPIO_CONTRAST_MASK 0x3f
+#define SHANNON_UCB_GPIO_CONTRAST 0
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/simpad.h b/arch/arm/mach-sa1100/include/mach/simpad.h
new file mode 100644
index 00000000..9296c451
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/simpad.h
@@ -0,0 +1,112 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/simpad.h
+ *
+ * based of assabet.h same as HUW_Webpanel
+ *
+ * This file contains the hardware specific definitions for SIMpad
+ *
+ * 2001/05/14 Juergen Messerer <juergen.messerer@freesurf.ch>
+ */
+
+#ifndef __ASM_ARCH_SIMPAD_H
+#define __ASM_ARCH_SIMPAD_H
+
+
+#define GPIO_UART1_RTS GPIO_GPIO14
+#define GPIO_UART1_DTR GPIO_GPIO7
+#define GPIO_UART1_CTS GPIO_GPIO8
+#define GPIO_UART1_DCD GPIO_GPIO23
+#define GPIO_UART1_DSR GPIO_GPIO6
+
+#define GPIO_UART3_RTS GPIO_GPIO12
+#define GPIO_UART3_DTR GPIO_GPIO16
+#define GPIO_UART3_CTS GPIO_GPIO13
+#define GPIO_UART3_DCD GPIO_GPIO18
+#define GPIO_UART3_DSR GPIO_GPIO17
+
+#define GPIO_POWER_BUTTON GPIO_GPIO0
+#define GPIO_UCB1300_IRQ GPIO_GPIO22 /* UCB GPIO and touchscreen */
+
+#define IRQ_UART1_CTS IRQ_GPIO15
+#define IRQ_UART1_DCD GPIO_GPIO23
+#define IRQ_UART1_DSR GPIO_GPIO6
+#define IRQ_UART3_CTS GPIO_GPIO13
+#define IRQ_UART3_DCD GPIO_GPIO18
+#define IRQ_UART3_DSR GPIO_GPIO17
+
+#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22
+#define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0
+
+
+/*--- PCMCIA ---*/
+#define GPIO_CF_CD GPIO_GPIO24
+#define GPIO_CF_IRQ GPIO_GPIO1
+#define IRQ_GPIO_CF_IRQ IRQ_GPIO1
+#define IRQ_GPIO_CF_CD IRQ_GPIO24
+
+/*--- SmartCard ---*/
+#define GPIO_SMART_CARD GPIO_GPIO10
+#define IRQ_GPIO_SMARD_CARD IRQ_GPIO10
+
+// CS3 Latch is write only, a shadow is necessary
+
+#define CS3BUSTYPE unsigned volatile long
+#define CS3_BASE 0xf1000000
+
+#define VCC_5V_EN 0x0001 // For 5V PCMCIA
+#define VCC_3V_EN 0x0002 // FOR 3.3V PCMCIA
+#define EN1 0x0004 // This is only for EPROM's
+#define EN0 0x0008 // Both should be enable for 3.3V or 5V
+#define DISPLAY_ON 0x0010
+#define PCMCIA_BUFF_DIS 0x0020
+#define MQ_RESET 0x0040
+#define PCMCIA_RESET 0x0080
+#define DECT_POWER_ON 0x0100
+#define IRDA_SD 0x0200 // Shutdown for powersave
+#define RS232_ON 0x0400
+#define SD_MEDIAQ 0x0800 // Shutdown for powersave
+#define LED2_ON 0x1000
+#define IRDA_MODE 0x2000 // Fast/Slow IrDA mode
+#define ENABLE_5V 0x4000 // Enable 5V circuit
+#define RESET_SIMCARD 0x8000
+
+#define RS232_ENABLE 0x0440
+#define PCMCIAMASK 0x402f
+
+
+struct simpad_battery {
+ unsigned char ac_status; /* line connected yes/no */
+ unsigned char status; /* battery loading yes/no */
+ unsigned char percentage; /* percentage loaded */
+ unsigned short life; /* life till empty */
+};
+
+/* These should match the apm_bios.h definitions */
+#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
+#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
+#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
+#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
+
+/* These bitfields are rarely "or'd" together */
+#define SIMPAD_BATT_STATUS_HIGH 0x01
+#define SIMPAD_BATT_STATUS_LOW 0x02
+#define SIMPAD_BATT_STATUS_CRITICAL 0x04
+#define SIMPAD_BATT_STATUS_CHARGING 0x08
+#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
+#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
+#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
+#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
+#define SIMPAD_BATT_STATUS_NOBATT 0x80
+#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
+
+extern int simpad_get_battery(struct simpad_battery* );
+
+#endif // __ASM_ARCH_SIMPAD_H
+
+
+
+
+
+
+
+
diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h
new file mode 100644
index 00000000..ba9da9f7
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/system.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/system.h
+ *
+ * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
+ */
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (mode == 's') {
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+ } else {
+ /* Use on-chip reset capability */
+ RSRR = RSRR_SWR;
+ }
+}
diff --git a/arch/arm/mach-sa1100/include/mach/timex.h b/arch/arm/mach-sa1100/include/mach/timex.h
new file mode 100644
index 00000000..7a5d017b
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/timex.h
@@ -0,0 +1,12 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/timex.h
+ *
+ * SA1100 architecture timex specifications
+ *
+ * Copyright (C) 1998
+ */
+
+/*
+ * SA1100 timer
+ */
+#define CLOCK_TICK_RATE 3686400
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h
new file mode 100644
index 00000000..6cb39ddd
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/uncompress.h
+ *
+ * (C) 1999 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * Reorganised to be machine independent.
+ */
+
+#include "hardware.h"
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ */
+
+#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
+
+static void putc(int c)
+{
+ unsigned long serial_port;
+
+ do {
+ serial_port = _Ser3UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser1UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser2UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ return;
+ } while (0);
+
+ /* wait for space in the UART's transmitter */
+ while (!(UART(UTSR1) & UTSR1_TNF))
+ barrier();
+
+ /* send the character out. */
+ UART(UTDR) = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * Nothing to do for these
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-sa1100/include/mach/vmalloc.h b/arch/arm/mach-sa1100/include/mach/vmalloc.h
new file mode 100644
index 00000000..b3d00239
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/vmalloc.h
@@ -0,0 +1,4 @@
+/*
+ * arch/arm/mach-sa1100/include/mach/vmalloc.h
+ */
+#define VMALLOC_END (0xe8000000UL)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
new file mode 100644
index 00000000..dfbf824a
--- /dev/null
+++ b/arch/arm/mach-sa1100/irq.c
@@ -0,0 +1,343 @@
+/*
+ * linux/arch/arm/mach-sa1100/irq.c
+ *
+ * Copyright (C) 1999-2001 Nicolas Pitre
+ *
+ * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+
+
+/*
+ * SA1100 GPIO edge detection for IRQs:
+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
+ * Use this instead of directly setting GRER/GFER.
+ */
+static int GPIO_IRQ_rising_edge;
+static int GPIO_IRQ_falling_edge;
+static int GPIO_IRQ_mask = (1 << 11) - 1;
+
+/*
+ * To get the GPIO number from an IRQ number
+ */
+#define GPIO_11_27_IRQ(i) ((i) - 21)
+#define GPIO11_27_MASK(irq) (1 << GPIO_11_27_IRQ(irq))
+
+static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int mask;
+
+ if (d->irq <= 10)
+ mask = 1 << d->irq;
+ else
+ mask = GPIO11_27_MASK(d->irq);
+
+ if (type == IRQ_TYPE_PROBE) {
+ if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
+ return 0;
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ if (type & IRQ_TYPE_EDGE_RISING) {
+ GPIO_IRQ_rising_edge |= mask;
+ } else
+ GPIO_IRQ_rising_edge &= ~mask;
+ if (type & IRQ_TYPE_EDGE_FALLING) {
+ GPIO_IRQ_falling_edge |= mask;
+ } else
+ GPIO_IRQ_falling_edge &= ~mask;
+
+ GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+ GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+
+ return 0;
+}
+
+/*
+ * GPIO IRQs must be acknowledged. This is for IRQs from 0 to 10.
+ */
+static void sa1100_low_gpio_ack(struct irq_data *d)
+{
+ GEDR = (1 << d->irq);
+}
+
+static void sa1100_low_gpio_mask(struct irq_data *d)
+{
+ ICMR &= ~(1 << d->irq);
+}
+
+static void sa1100_low_gpio_unmask(struct irq_data *d)
+{
+ ICMR |= 1 << d->irq;
+}
+
+static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on)
+{
+ if (on)
+ PWER |= 1 << d->irq;
+ else
+ PWER &= ~(1 << d->irq);
+ return 0;
+}
+
+static struct irq_chip sa1100_low_gpio_chip = {
+ .name = "GPIO-l",
+ .irq_ack = sa1100_low_gpio_ack,
+ .irq_mask = sa1100_low_gpio_mask,
+ .irq_unmask = sa1100_low_gpio_unmask,
+ .irq_set_type = sa1100_gpio_type,
+ .irq_set_wake = sa1100_low_gpio_wake,
+};
+
+/*
+ * IRQ11 (GPIO11 through 27) handler. We enter here with the
+ * irq_controller_lock held, and IRQs disabled. Decode the IRQ
+ * and call the handler.
+ */
+static void
+sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int mask;
+
+ mask = GEDR & 0xfffff800;
+ do {
+ /*
+ * clear down all currently active IRQ sources.
+ * We will be processing them all.
+ */
+ GEDR = mask;
+
+ irq = IRQ_GPIO11;
+ mask >>= 11;
+ do {
+ if (mask & 1)
+ generic_handle_irq(irq);
+ mask >>= 1;
+ irq++;
+ } while (mask);
+
+ mask = GEDR & 0xfffff800;
+ } while (mask);
+}
+
+/*
+ * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially.
+ * In addition, the IRQs are all collected up into one bit in the
+ * interrupt controller registers.
+ */
+static void sa1100_high_gpio_ack(struct irq_data *d)
+{
+ unsigned int mask = GPIO11_27_MASK(d->irq);
+
+ GEDR = mask;
+}
+
+static void sa1100_high_gpio_mask(struct irq_data *d)
+{
+ unsigned int mask = GPIO11_27_MASK(d->irq);
+
+ GPIO_IRQ_mask &= ~mask;
+
+ GRER &= ~mask;
+ GFER &= ~mask;
+}
+
+static void sa1100_high_gpio_unmask(struct irq_data *d)
+{
+ unsigned int mask = GPIO11_27_MASK(d->irq);
+
+ GPIO_IRQ_mask |= mask;
+
+ GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+ GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+}
+
+static int sa1100_high_gpio_wake(struct irq_data *d, unsigned int on)
+{
+ if (on)
+ PWER |= GPIO11_27_MASK(d->irq);
+ else
+ PWER &= ~GPIO11_27_MASK(d->irq);
+ return 0;
+}
+
+static struct irq_chip sa1100_high_gpio_chip = {
+ .name = "GPIO-h",
+ .irq_ack = sa1100_high_gpio_ack,
+ .irq_mask = sa1100_high_gpio_mask,
+ .irq_unmask = sa1100_high_gpio_unmask,
+ .irq_set_type = sa1100_gpio_type,
+ .irq_set_wake = sa1100_high_gpio_wake,
+};
+
+/*
+ * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
+ * this is for internal IRQs i.e. from 11 to 31.
+ */
+static void sa1100_mask_irq(struct irq_data *d)
+{
+ ICMR &= ~(1 << d->irq);
+}
+
+static void sa1100_unmask_irq(struct irq_data *d)
+{
+ ICMR |= (1 << d->irq);
+}
+
+/*
+ * Apart form GPIOs, only the RTC alarm can be a wakeup event.
+ */
+static int sa1100_set_wake(struct irq_data *d, unsigned int on)
+{
+ if (d->irq == IRQ_RTCAlrm) {
+ if (on)
+ PWER |= PWER_RTC;
+ else
+ PWER &= ~PWER_RTC;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static struct irq_chip sa1100_normal_chip = {
+ .name = "SC",
+ .irq_ack = sa1100_mask_irq,
+ .irq_mask = sa1100_mask_irq,
+ .irq_unmask = sa1100_unmask_irq,
+ .irq_set_wake = sa1100_set_wake,
+};
+
+static struct resource irq_resource = {
+ .name = "irqs",
+ .start = 0x90050000,
+ .end = 0x9005ffff,
+};
+
+static struct sa1100irq_state {
+ unsigned int saved;
+ unsigned int icmr;
+ unsigned int iclr;
+ unsigned int iccr;
+} sa1100irq_state;
+
+static int sa1100irq_suspend(void)
+{
+ struct sa1100irq_state *st = &sa1100irq_state;
+
+ st->saved = 1;
+ st->icmr = ICMR;
+ st->iclr = ICLR;
+ st->iccr = ICCR;
+
+ /*
+ * Disable all GPIO-based interrupts.
+ */
+ ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7|
+ IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
+ IC_GPIO1|IC_GPIO0);
+
+ /*
+ * Set the appropriate edges for wakeup.
+ */
+ GRER = PWER & GPIO_IRQ_rising_edge;
+ GFER = PWER & GPIO_IRQ_falling_edge;
+
+ /*
+ * Clear any pending GPIO interrupts.
+ */
+ GEDR = GEDR;
+
+ return 0;
+}
+
+static void sa1100irq_resume(void)
+{
+ struct sa1100irq_state *st = &sa1100irq_state;
+
+ if (st->saved) {
+ ICCR = st->iccr;
+ ICLR = st->iclr;
+
+ GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
+ GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
+
+ ICMR = st->icmr;
+ }
+}
+
+static struct syscore_ops sa1100irq_syscore_ops = {
+ .suspend = sa1100irq_suspend,
+ .resume = sa1100irq_resume,
+};
+
+static int __init sa1100irq_init_devicefs(void)
+{
+ register_syscore_ops(&sa1100irq_syscore_ops);
+ return 0;
+}
+
+device_initcall(sa1100irq_init_devicefs);
+
+void __init sa1100_init_irq(void)
+{
+ unsigned int irq;
+
+ request_resource(&iomem_resource, &irq_resource);
+
+ /* disable all IRQs */
+ ICMR = 0;
+
+ /* all IRQs are IRQ, not FIQ */
+ ICLR = 0;
+
+ /* clear all GPIO edge detects */
+ GFER = 0;
+ GRER = 0;
+ GEDR = -1;
+
+ /*
+ * Whatever the doc says, this has to be set for the wait-on-irq
+ * instruction to work... on a SA1100 rev 9 at least.
+ */
+ ICCR = 1;
+
+ for (irq = 0; irq <= 10; irq++) {
+ irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ for (irq = 12; irq <= 31; irq++) {
+ irq_set_chip_and_handler(irq, &sa1100_normal_chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ for (irq = 32; irq <= 48; irq++) {
+ irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /*
+ * Install handler for GPIO 11-27 edge detect interrupts
+ */
+ irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
+ irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
+
+ sa1100_init_gpio();
+}
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
new file mode 100644
index 00000000..491ac9f2
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -0,0 +1,372 @@
+/*
+ * linux/arch/arm/mach-sa1100/jornada720.c
+ *
+ * HP Jornada720 init code
+ *
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ * Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <video/s1d13xxxfb.h>
+
+#include <mach/hardware.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+/*
+ * HP Documentation referred in this file:
+ * http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
+ */
+
+/* line 110 of HP's doc */
+#define TUCR_VAL 0x20000400
+
+/* memory space (line 52 of HP's doc) */
+#define SA1111REGSTART 0x40000000
+#define SA1111REGLEN 0x00001fff
+#define EPSONREGSTART 0x48000000
+#define EPSONREGLEN 0x00100000
+#define EPSONFBSTART 0x48200000
+/* 512kB framebuffer */
+#define EPSONFBLEN 512*1024
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+ /* line 344 of HP's doc */
+ {0x0001,0x00}, // Miscellaneous Register
+ {0x01FC,0x00}, // Display Mode Register
+ {0x0004,0x00}, // General IO Pins Configuration Register 0
+ {0x0005,0x00}, // General IO Pins Configuration Register 1
+ {0x0008,0x00}, // General IO Pins Control Register 0
+ {0x0009,0x00}, // General IO Pins Control Register 1
+ {0x0010,0x01}, // Memory Clock Configuration Register
+ {0x0014,0x11}, // LCD Pixel Clock Configuration Register
+ {0x0018,0x01}, // CRT/TV Pixel Clock Configuration Register
+ {0x001C,0x01}, // MediaPlug Clock Configuration Register
+ {0x001E,0x01}, // CPU To Memory Wait State Select Register
+ {0x0020,0x00}, // Memory Configuration Register
+ {0x0021,0x45}, // DRAM Refresh Rate Register
+ {0x002A,0x01}, // DRAM Timings Control Register 0
+ {0x002B,0x03}, // DRAM Timings Control Register 1
+ {0x0030,0x1c}, // Panel Type Register
+ {0x0031,0x00}, // MOD Rate Register
+ {0x0032,0x4F}, // LCD Horizontal Display Width Register
+ {0x0034,0x07}, // LCD Horizontal Non-Display Period Register
+ {0x0035,0x01}, // TFT FPLINE Start Position Register
+ {0x0036,0x0B}, // TFT FPLINE Pulse Width Register
+ {0x0038,0xEF}, // LCD Vertical Display Height Register 0
+ {0x0039,0x00}, // LCD Vertical Display Height Register 1
+ {0x003A,0x13}, // LCD Vertical Non-Display Period Register
+ {0x003B,0x0B}, // TFT FPFRAME Start Position Register
+ {0x003C,0x01}, // TFT FPFRAME Pulse Width Register
+ {0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0041,0x00}, // LCD Miscellaneous Register
+ {0x0042,0x00}, // LCD Display Start Address Register 0
+ {0x0043,0x00}, // LCD Display Start Address Register 1
+ {0x0044,0x00}, // LCD Display Start Address Register 2
+ {0x0046,0x80}, // LCD Memory Address Offset Register 0
+ {0x0047,0x02}, // LCD Memory Address Offset Register 1
+ {0x0048,0x00}, // LCD Pixel Panning Register
+ {0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
+ {0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
+ {0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
+ {0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
+ {0x0053,0x01}, // CRT/TV HRTC Start Position Register
+ {0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
+ {0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
+ {0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
+ {0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
+ {0x0059,0x09}, // CRT/TV VRTC Start Position Register
+ {0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
+ {0x005B,0x10}, // TV Output Control Register
+ {0x0060,0x03}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0062,0x00}, // CRT/TV Display Start Address Register 0
+ {0x0063,0x00}, // CRT/TV Display Start Address Register 1
+ {0x0064,0x00}, // CRT/TV Display Start Address Register 2
+ {0x0066,0x40}, // CRT/TV Memory Address Offset Register 0
+ {0x0067,0x01}, // CRT/TV Memory Address Offset Register 1
+ {0x0068,0x00}, // CRT/TV Pixel Panning Register
+ {0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
+ {0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
+ {0x0070,0x00}, // LCD Ink/Cursor Control Register
+ {0x0071,0x01}, // LCD Ink/Cursor Start Address Register
+ {0x0072,0x00}, // LCD Cursor X Position Register 0
+ {0x0073,0x00}, // LCD Cursor X Position Register 1
+ {0x0074,0x00}, // LCD Cursor Y Position Register 0
+ {0x0075,0x00}, // LCD Cursor Y Position Register 1
+ {0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
+ {0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
+ {0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
+ {0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
+ {0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
+ {0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
+ {0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
+ {0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
+ {0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
+ {0x0082,0x00}, // CRT/TV Cursor X Position Register 0
+ {0x0083,0x00}, // CRT/TV Cursor X Position Register 1
+ {0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
+ {0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
+ {0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
+ {0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
+ {0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
+ {0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
+ {0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
+ {0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
+ {0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
+ {0x0100,0x00}, // BitBlt Control Register 0
+ {0x0101,0x00}, // BitBlt Control Register 1
+ {0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
+ {0x0103,0x00}, // BitBlt Operation Register
+ {0x0104,0x00}, // BitBlt Source Start Address Register 0
+ {0x0105,0x00}, // BitBlt Source Start Address Register 1
+ {0x0106,0x00}, // BitBlt Source Start Address Register 2
+ {0x0108,0x00}, // BitBlt Destination Start Address Register 0
+ {0x0109,0x00}, // BitBlt Destination Start Address Register 1
+ {0x010A,0x00}, // BitBlt Destination Start Address Register 2
+ {0x010C,0x00}, // BitBlt Memory Address Offset Register 0
+ {0x010D,0x00}, // BitBlt Memory Address Offset Register 1
+ {0x0110,0x00}, // BitBlt Width Register 0
+ {0x0111,0x00}, // BitBlt Width Register 1
+ {0x0112,0x00}, // BitBlt Height Register 0
+ {0x0113,0x00}, // BitBlt Height Register 1
+ {0x0114,0x00}, // BitBlt Background Color Register 0
+ {0x0115,0x00}, // BitBlt Background Color Register 1
+ {0x0118,0x00}, // BitBlt Foreground Color Register 0
+ {0x0119,0x00}, // BitBlt Foreground Color Register 1
+ {0x01E0,0x00}, // Look-Up Table Mode Register
+ {0x01E2,0x00}, // Look-Up Table Address Register
+ /* not sure, wouldn't like to mess with the driver */
+ {0x01E4,0x00}, // Look-Up Table Data Register
+ /* jornada doc says 0x00, but I trust the driver */
+ {0x01F0,0x10}, // Power Save Configuration Register
+ {0x01F1,0x00}, // Power Save Status Register
+ {0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
+ {0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+};
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+ .initregs = s1d13xxxfb_initregs,
+ .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
+ .platform_init_video = NULL
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+ [0] = {
+ .start = EPSONFBSTART,
+ .end = EPSONFBSTART + EPSONFBLEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EPSONREGSTART,
+ .end = EPSONREGSTART + EPSONREGLEN,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device s1d13xxxfb_device = {
+ .name = S1D_DEVICENAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &s1d13xxxfb_data,
+ },
+ .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
+ .resource = s1d13xxxfb_resources,
+};
+
+static struct resource sa1111_resources[] = {
+ [0] = {
+ .start = SA1111REGSTART,
+ .end = SA1111REGSTART + SA1111REGLEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_GPIO1,
+ .end = IRQ_GPIO1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+ .name = "sa1111",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sa1111_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
+ },
+ .num_resources = ARRAY_SIZE(sa1111_resources),
+ .resource = sa1111_resources,
+};
+
+static struct platform_device jornada_ssp_device = {
+ .name = "jornada_ssp",
+ .id = -1,
+};
+
+static struct platform_device jornada_kbd_device = {
+ .name = "jornada720_kbd",
+ .id = -1,
+};
+
+static struct platform_device jornada_ts_device = {
+ .name = "jornada_ts",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+ &jornada_ssp_device,
+ &s1d13xxxfb_device,
+ &jornada_kbd_device,
+ &jornada_ts_device,
+};
+
+static int __init jornada720_init(void)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_jornada720()) {
+ /* we want to use gpio20 as input to drive the clock of our uart 3 */
+ GPDR |= GPIO_GPIO20; /* Clear gpio20 pin as input */
+ TUCR = TUCR_VAL;
+ GPSR = GPIO_GPIO20; /* start gpio20 pin */
+ udelay(1);
+ GPCR = GPIO_GPIO20; /* stop gpio20 */
+ udelay(1);
+ GPSR = GPIO_GPIO20; /* restart gpio20 */
+ udelay(20); /* give it some time to restart */
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+arch_initcall(jornada720_init);
+
+static struct map_desc jornada720_io_desc[] __initdata = {
+ { /* Epson registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(EPSONREGSTART),
+ .length = EPSONREGLEN,
+ .type = MT_DEVICE
+ }, { /* Epson frame buffer */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(EPSONFBSTART),
+ .length = EPSONFBLEN,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(SA1111REGSTART),
+ .length = SA1111REGLEN,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init jornada720_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc));
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+}
+
+static struct mtd_partition jornada720_partitions[] = {
+ {
+ .name = "JORNADA720 boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "JORNADA720 kernel",
+ .size = 0x000c0000,
+ .offset = 0x00040000,
+ }, {
+ .name = "JORNADA720 params",
+ .size = 0x00040000,
+ .offset = 0x00100000,
+ }, {
+ .name = "JORNADA720 initrd",
+ .size = 0x00100000,
+ .offset = 0x00140000,
+ }, {
+ .name = "JORNADA720 root cramfs",
+ .size = 0x00300000,
+ .offset = 0x00240000,
+ }, {
+ .name = "JORNADA720 usr cramfs",
+ .size = 0x00800000,
+ .offset = 0x00540000,
+ }, {
+ .name = "JORNADA720 usr local",
+ .size = 0, /* will expand to the end of the flash */
+ .offset = 0x00d00000,
+ }
+};
+
+static void jornada720_set_vpp(int vpp)
+{
+ if (vpp)
+ /* enabling flash write (line 470 of HP's doc) */
+ PPSR |= PPC_LDD7;
+ else
+ /* disabling flash write (line 470 of HP's doc) */
+ PPSR &= ~PPC_LDD7;
+ PPDR |= PPC_LDD7;
+}
+
+static struct flash_platform_data jornada720_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = jornada720_set_vpp,
+ .parts = jornada720_partitions,
+ .nr_parts = ARRAY_SIZE(jornada720_partitions),
+};
+
+static struct resource jornada720_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static void __init jornada720_mach_init(void)
+{
+ sa11x0_register_mtd(&jornada720_flash_data, &jornada720_flash_resource, 1);
+}
+
+MACHINE_START(JORNADA720, "HP Jornada 720")
+ /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
+ .boot_params = 0xc0000100,
+ .map_io = jornada720_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = jornada720_mach_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
new file mode 100644
index 00000000..f50b00bd
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -0,0 +1,200 @@
+/**
+ * arch/arm/mac-sa1100/jornada720_ssp.c
+ *
+ * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * SSP driver for the HP Jornada 710/720/728
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+
+#include <mach/hardware.h>
+#include <mach/jornada720.h>
+#include <asm/hardware/ssp.h>
+
+static DEFINE_SPINLOCK(jornada_ssp_lock);
+static unsigned long jornada_ssp_flags;
+
+/**
+ * jornada_ssp_reverse - reverses input byte
+ *
+ * we need to reverse all data we receive from the mcu due to its physical location
+ * returns : 01110111 -> 11101110
+ */
+u8 inline jornada_ssp_reverse(u8 byte)
+{
+ return
+ ((0x80 & byte) >> 7) |
+ ((0x40 & byte) >> 5) |
+ ((0x20 & byte) >> 3) |
+ ((0x10 & byte) >> 1) |
+ ((0x08 & byte) << 1) |
+ ((0x04 & byte) << 3) |
+ ((0x02 & byte) << 5) |
+ ((0x01 & byte) << 7);
+};
+EXPORT_SYMBOL(jornada_ssp_reverse);
+
+/**
+ * jornada_ssp_byte - waits for ready ssp bus and sends byte
+ *
+ * waits for fifo buffer to clear and then transmits, if it doesn't then we will
+ * timeout after <timeout> rounds. Needs mcu running before its called.
+ *
+ * returns : %mcu output on success
+ * : %-ETIMEDOUT on timeout
+ */
+int jornada_ssp_byte(u8 byte)
+{
+ int timeout = 400000;
+ u16 ret;
+
+ while ((GPLR & GPIO_GPIO10)) {
+ if (!--timeout) {
+ printk(KERN_WARNING "SSP: timeout while waiting for transmit\n");
+ return -ETIMEDOUT;
+ }
+ cpu_relax();
+ }
+
+ ret = jornada_ssp_reverse(byte) << 8;
+
+ ssp_write_word(ret);
+ ssp_read_word(&ret);
+
+ return jornada_ssp_reverse(ret);
+};
+EXPORT_SYMBOL(jornada_ssp_byte);
+
+/**
+ * jornada_ssp_inout - decide if input is command or trading byte
+ *
+ * returns : (jornada_ssp_byte(byte)) on success
+ * : %-ETIMEDOUT on timeout failure
+ */
+int jornada_ssp_inout(u8 byte)
+{
+ int ret, i;
+
+ /* true means command byte */
+ if (byte != TXDUMMY) {
+ ret = jornada_ssp_byte(byte);
+ /* Proper return to commands is TxDummy */
+ if (ret != TXDUMMY) {
+ for (i = 0; i < 256; i++)/* flushing bus */
+ if (jornada_ssp_byte(TXDUMMY) == -1)
+ break;
+ return -ETIMEDOUT;
+ }
+ } else /* Exchange TxDummy for data */
+ ret = jornada_ssp_byte(TXDUMMY);
+
+ return ret;
+};
+EXPORT_SYMBOL(jornada_ssp_inout);
+
+/**
+ * jornada_ssp_start - enable mcu
+ *
+ */
+void jornada_ssp_start(void)
+{
+ spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
+ GPCR = GPIO_GPIO25;
+ udelay(50);
+ return;
+};
+EXPORT_SYMBOL(jornada_ssp_start);
+
+/**
+ * jornada_ssp_end - disable mcu and turn off lock
+ *
+ */
+void jornada_ssp_end(void)
+{
+ GPSR = GPIO_GPIO25;
+ spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
+ return;
+};
+EXPORT_SYMBOL(jornada_ssp_end);
+
+static int __devinit jornada_ssp_probe(struct platform_device *dev)
+{
+ int ret;
+
+ GPSR = GPIO_GPIO25;
+
+ ret = ssp_init();
+
+ /* worked fine, lets not bother with anything else */
+ if (!ret) {
+ printk(KERN_INFO "SSP: device initialized with irq\n");
+ return ret;
+ }
+
+ printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n");
+
+ /* init of Serial 4 port */
+ Ser4MCCR0 = 0;
+ Ser4SSCR0 = 0x0387;
+ Ser4SSCR1 = 0x18;
+
+ /* clear out any left over data */
+ ssp_flush();
+
+ /* enable MCU */
+ jornada_ssp_start();
+
+ /* see if return value makes sense */
+ ret = jornada_ssp_inout(GETBRIGHTNESS);
+
+ /* seems like it worked, just feed it with TxDummy to get rid of data */
+ if (ret == TXDUMMY)
+ jornada_ssp_inout(TXDUMMY);
+
+ jornada_ssp_end();
+
+ /* failed, lets just kill everything */
+ if (ret == -ETIMEDOUT) {
+ printk(KERN_WARNING "SSP: attempts failed, bailing\n");
+ ssp_exit();
+ return -ENODEV;
+ }
+
+ /* all fine */
+ printk(KERN_INFO "SSP: device initialized\n");
+ return 0;
+};
+
+static int jornada_ssp_remove(struct platform_device *dev)
+{
+ /* Note that this doesn't actually remove the driver, since theres nothing to remove
+ * It just makes sure everything is turned off */
+ GPSR = GPIO_GPIO25;
+ ssp_exit();
+ return 0;
+};
+
+struct platform_driver jornadassp_driver = {
+ .probe = jornada_ssp_probe,
+ .remove = jornada_ssp_remove,
+ .driver = {
+ .name = "jornada_ssp",
+ },
+};
+
+static int __init jornada_ssp_init(void)
+{
+ return platform_driver_register(&jornadassp_driver);
+}
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
new file mode 100644
index 00000000..7b9556b5
--- /dev/null
+++ b/arch/arm/mach-sa1100/lart.c
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/mach-sa1100/lart.c
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/mcp.h>
+
+#include "generic.h"
+
+
+#warning "include/asm/arch-sa1100/ide.h needs fixing for lart"
+
+static struct mcp_plat_data lart_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+static void __init lart_init(void)
+{
+ sa11x0_register_mcp(&lart_mcp_data);
+}
+
+static struct map_desc lart_io_desc[] __initdata = {
+ { /* main flash memory */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }, { /* main flash, alternative location */
+ .virtual = 0xec000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x00400000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init lart_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(lart_io_desc, ARRAY_SIZE(lart_io_desc));
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+ sa1100_register_uart(2, 2);
+
+ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
+ GPDR |= GPIO_UART_TXD;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
+}
+
+MACHINE_START(LART, "LART")
+ .boot_params = 0xc0000100,
+ .map_io = lart_map_io,
+ .init_irq = sa1100_init_irq,
+ .init_machine = lart_init,
+ .timer = &sa1100_timer,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/leds-assabet.c b/arch/arm/mach-sa1100/leds-assabet.c
new file mode 100644
index 00000000..64e9b4b1
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-assabet.c
@@ -0,0 +1,114 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-assabet.c
+ *
+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * Assabet uses the LEDs as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Red - on if system is not idle
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <mach/assabet.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define ASSABET_BCR_LED_MASK (ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED)
+
+void assabet_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
+ ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= ASSABET_BCR_LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= ASSABET_BCR_LED_RED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~ASSABET_BCR_LED_RED;
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~ASSABET_BCR_LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= ASSABET_BCR_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~ASSABET_BCR_LED_RED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= ASSABET_BCR_LED_RED;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-sa1100/leds-badge4.c b/arch/arm/mach-sa1100/leds-badge4.c
new file mode 100644
index 00000000..cf1e3845
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-badge4.c
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-badge4.c
+ *
+ * Author: Christopher Hoover <ch@hpl.hp.com>
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can 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 <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_RED GPIO_GPIO(7)
+#define LED_GREEN GPIO_GPIO(9)
+#define LED_MASK (LED_RED|LED_GREEN)
+
+#define LED_IDLE LED_GREEN
+#define LED_TIMER LED_RED
+
+void badge4_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ GPDR |= LED_MASK;
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_TIMER;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ /* LED off when system is idle */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_IDLE;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_IDLE;
+ break;
+#endif
+
+ case led_red_on:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_RED;
+ break;
+
+ case led_red_off:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_RED;
+ break;
+
+ case led_green_on:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_GREEN;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-sa1100/leds-cerf.c b/arch/arm/mach-sa1100/leds-cerf.c
new file mode 100644
index 00000000..259b48e0
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-cerf.c
@@ -0,0 +1,110 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-cerf.c
+ *
+ * Author: ???
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_D0 GPIO_GPIO(0)
+#define LED_D1 GPIO_GPIO(1)
+#define LED_D2 GPIO_GPIO(2)
+#define LED_D3 GPIO_GPIO(3)
+#define LED_MASK (LED_D0|LED_D1|LED_D2|LED_D3)
+
+void cerf_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_D0;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_D1;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_D1;
+ break;
+#endif
+ case led_green_on:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_D2;
+ break;
+
+ case led_green_off:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_D2;
+ break;
+
+ case led_amber_on:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_D3;
+ break;
+
+ case led_amber_off:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_D3;
+ break;
+
+ case led_red_on:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_D1;
+ break;
+
+ case led_red_off:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_D1;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c
new file mode 100644
index 00000000..2bce1374
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-hackkit.c
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-hackkit.c
+ *
+ * based on leds-lart.c
+ *
+ * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ * (C) Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>, 2002
+ *
+ * The HackKit has two leds (GPIO 22/23). The red led (gpio 22) is used
+ * as cpu led, the green one is used as timer led.
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_GREEN GPIO_GPIO23
+#define LED_RED GPIO_GPIO22
+#define LED_MASK (LED_RED | LED_GREEN)
+
+void hackkit_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch(evt) {
+ case led_start:
+ /* pin 22/23 are outputs */
+ GPDR |= LED_MASK;
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ /* The LART people like the LED to be off when the
+ system is idle... */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_RED;
+ break;
+
+ case led_idle_end:
+ /* ... and on if the system is not idle */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_RED;
+ break;
+#endif
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_RED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_RED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_GREEN;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Now set the GPIO state, or nothing will happen at all */
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-sa1100/leds-lart.c b/arch/arm/mach-sa1100/leds-lart.c
new file mode 100644
index 00000000..0505a1fd
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-lart.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-lart.c
+ *
+ * (C) Erik Mouw (J.A.K.Mouw@its.tudelft.nl), April 21, 2000
+ *
+ * LART uses the LED as follows:
+ * - GPIO23 is the LED, on if system is not idle
+ * You can use both CONFIG_LEDS_CPU and CONFIG_LEDS_TIMER at the same
+ * time, but in that case the timer events will still dictate the
+ * pace of the LED.
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_23 GPIO_GPIO23
+#define LED_MASK (LED_23)
+
+void lart_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch(evt) {
+ case led_start:
+ /* pin 23 is output pin */
+ GPDR |= LED_23;
+ hw_led_state = LED_MASK;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_MASK;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_23;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ /* The LART people like the LED to be off when the
+ system is idle... */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~LED_23;
+ break;
+
+ case led_idle_end:
+ /* ... and on if the system is not idle */
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= LED_23;
+ break;
+#endif
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_23;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_23;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Now set the GPIO state, or nothing will happen at all */
+ if (led_state & LED_STATE_ENABLED) {
+ GPSR = hw_led_state;
+ GPCR = hw_led_state ^ LED_MASK;
+ }
+
+ local_irq_restore(flags);
+}
diff --git a/arch/arm/mach-sa1100/leds-simpad.c b/arch/arm/mach-sa1100/leds-simpad.c
new file mode 100644
index 00000000..d50f4eea
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds-simpad.c
@@ -0,0 +1,100 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-simpad.c
+ *
+ * Author: Juergen Messerer <juergen.messerer@siemens.ch>
+ */
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <mach/simpad.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+#define LED_GREEN (1)
+#define LED_MASK (1)
+
+extern void set_cs3_bit(int value);
+extern void clear_cs3_bit(int value);
+
+void simpad_leds_event(led_event_t evt)
+{
+ switch (evt)
+ {
+ case led_start:
+ hw_led_state = LED_GREEN;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = LED_GREEN;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = LED_GREEN;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ break;
+
+ case led_idle_end:
+ break;
+#endif
+
+ case led_halted:
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~LED_GREEN;
+ break;
+
+ case led_amber_on:
+ break;
+
+ case led_amber_off:
+ break;
+
+ case led_red_on:
+ break;
+
+ case led_red_off:
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ set_cs3_bit(LED2_ON);
+ else
+ clear_cs3_bit(LED2_ON);
+}
+
diff --git a/arch/arm/mach-sa1100/leds.c b/arch/arm/mach-sa1100/leds.c
new file mode 100644
index 00000000..bbfe197f
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds.c
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds.c
+ *
+ * SA1100 LEDs dispatcher
+ *
+ * Copyright (C) 2001 Nicolas Pitre
+ */
+#include <linux/compiler.h>
+#include <linux/init.h>
+
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include "leds.h"
+
+static int __init
+sa1100_leds_init(void)
+{
+ if (machine_is_assabet())
+ leds_event = assabet_leds_event;
+ if (machine_is_consus())
+ leds_event = consus_leds_event;
+ if (machine_is_badge4())
+ leds_event = badge4_leds_event;
+ if (machine_is_brutus())
+ leds_event = brutus_leds_event;
+ if (machine_is_cerf())
+ leds_event = cerf_leds_event;
+ if (machine_is_flexanet())
+ leds_event = flexanet_leds_event;
+ if (machine_is_graphicsclient())
+ leds_event = graphicsclient_leds_event;
+ if (machine_is_hackkit())
+ leds_event = hackkit_leds_event;
+ if (machine_is_lart())
+ leds_event = lart_leds_event;
+ if (machine_is_pfs168())
+ leds_event = pfs168_leds_event;
+ if (machine_is_graphicsmaster())
+ leds_event = graphicsmaster_leds_event;
+ if (machine_is_adsbitsy())
+ leds_event = adsbitsy_leds_event;
+ if (machine_is_pt_system3())
+ leds_event = system3_leds_event;
+ if (machine_is_simpad())
+ leds_event = simpad_leds_event; /* what about machine registry? including led, apm... -zecke */
+
+ leds_event(led_start);
+ return 0;
+}
+
+core_initcall(sa1100_leds_init);
diff --git a/arch/arm/mach-sa1100/leds.h b/arch/arm/mach-sa1100/leds.h
new file mode 100644
index 00000000..68cc9f77
--- /dev/null
+++ b/arch/arm/mach-sa1100/leds.h
@@ -0,0 +1,14 @@
+extern void assabet_leds_event(led_event_t evt);
+extern void badge4_leds_event(led_event_t evt);
+extern void consus_leds_event(led_event_t evt);
+extern void brutus_leds_event(led_event_t evt);
+extern void cerf_leds_event(led_event_t evt);
+extern void flexanet_leds_event(led_event_t evt);
+extern void graphicsclient_leds_event(led_event_t evt);
+extern void hackkit_leds_event(led_event_t evt);
+extern void lart_leds_event(led_event_t evt);
+extern void pfs168_leds_event(led_event_t evt);
+extern void graphicsmaster_leds_event(led_event_t evt);
+extern void adsbitsy_leds_event(led_event_t evt);
+extern void system3_leds_event(led_event_t evt);
+extern void simpad_leds_event(led_event_t evt);
diff --git a/arch/arm/mach-sa1100/nanoengine.c b/arch/arm/mach-sa1100/nanoengine.c
new file mode 100644
index 00000000..72087f06
--- /dev/null
+++ b/arch/arm/mach-sa1100/nanoengine.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/arm/mach-sa1100/nanoengine.c
+ *
+ * Bright Star Engineering's nanoEngine board init code.
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/root_dev.h>
+
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <mach/hardware.h>
+#include <mach/nanoengine.h>
+
+#include "generic.h"
+
+/* Flash bank 0 */
+static struct mtd_partition nanoengine_partitions[] = {
+ {
+ .name = "nanoEngine boot firmware and parameter table",
+ .size = 0x00010000, /* 32K */
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "kernel/initrd reserved",
+ .size = 0x002f0000,
+ .offset = 0x00010000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "experimental filesystem allocation",
+ .size = 0x00100000,
+ .offset = 0x00300000,
+ .mask_flags = MTD_WRITEABLE,
+ }
+};
+
+static struct flash_platform_data nanoengine_flash_data = {
+ .map_name = "jedec_probe",
+ .parts = nanoengine_partitions,
+ .nr_parts = ARRAY_SIZE(nanoengine_partitions),
+};
+
+static struct resource nanoengine_flash_resources[] = {
+ {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SA1100_CS1_PHYS,
+ .end = SA1100_CS1_PHYS + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct map_desc nanoengine_io_desc[] __initdata = {
+ {
+ /* System Registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, {
+ /* Internal PCI Memory Read/Write */
+ .virtual = NANO_PCI_MEM_RW_VIRT,
+ .pfn = __phys_to_pfn(NANO_PCI_MEM_RW_PHYS),
+ .length = NANO_PCI_MEM_RW_SIZE,
+ .type = MT_DEVICE
+ }, {
+ /* Internal PCI Config Space */
+ .virtual = NANO_PCI_CONFIG_SPACE_VIRT,
+ .pfn = __phys_to_pfn(NANO_PCI_CONFIG_SPACE_PHYS),
+ .length = NANO_PCI_CONFIG_SPACE_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init nanoengine_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(nanoengine_io_desc, ARRAY_SIZE(nanoengine_io_desc));
+
+ sa1100_register_uart(0, 1);
+ sa1100_register_uart(1, 2);
+ sa1100_register_uart(2, 3);
+ Ser1SDCR0 |= SDCR0_UART;
+ /* disable IRDA -- UART2 is used as a normal serial port */
+ Ser2UTCR4 = 0;
+ Ser2HSCR0 = 0;
+}
+
+static void __init nanoengine_init(void)
+{
+ sa11x0_register_mtd(&nanoengine_flash_data, nanoengine_flash_resources,
+ ARRAY_SIZE(nanoengine_flash_resources));
+}
+
+MACHINE_START(NANOENGINE, "BSE nanoEngine")
+ .boot_params = 0xc0000000,
+ .map_io = nanoengine_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = nanoengine_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
new file mode 100644
index 00000000..b4fa53a1
--- /dev/null
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -0,0 +1,346 @@
+/*
+ * linux/arch/arm/mach-sa1100/neponset.c
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/assabet.h>
+#include <mach/neponset.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/sizes.h>
+
+/*
+ * Install handler for Neponset IRQ. Note that we have to loop here
+ * since the ETHERNET and USAR IRQs are level based, and we need to
+ * ensure that the IRQ signal is deasserted before returning. This
+ * is rather unfortunate.
+ */
+static void
+neponset_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ unsigned int irr;
+
+ while (1) {
+ /*
+ * Acknowledge the parent IRQ.
+ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ /*
+ * Read the interrupt reason register. Let's have all
+ * active IRQ bits high. Note: there is a typo in the
+ * Neponset user's guide for the SA1111 IRR level.
+ */
+ irr = IRR ^ (IRR_ETHERNET | IRR_USAR);
+
+ if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
+ break;
+
+ /*
+ * Since there is no individual mask, we have to
+ * mask the parent IRQ. This is safe, since we'll
+ * recheck the register for any pending IRQs.
+ */
+ if (irr & (IRR_ETHERNET | IRR_USAR)) {
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+ /*
+ * Ack the interrupt now to prevent re-entering
+ * this neponset handler. Again, this is safe
+ * since we'll check the IRR register prior to
+ * leaving.
+ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ if (irr & IRR_ETHERNET) {
+ generic_handle_irq(IRQ_NEPONSET_SMC9196);
+ }
+
+ if (irr & IRR_USAR) {
+ generic_handle_irq(IRQ_NEPONSET_USAR);
+ }
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ }
+
+ if (irr & IRR_SA1111) {
+ generic_handle_irq(IRQ_NEPONSET_SA1111);
+ }
+ }
+}
+
+static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ u_int mdm_ctl0 = MDM_CTL_0;
+
+ if (port->mapbase == _Ser1UTCR0) {
+ if (mctrl & TIOCM_RTS)
+ mdm_ctl0 &= ~MDM_CTL0_RTS2;
+ else
+ mdm_ctl0 |= MDM_CTL0_RTS2;
+
+ if (mctrl & TIOCM_DTR)
+ mdm_ctl0 &= ~MDM_CTL0_DTR2;
+ else
+ mdm_ctl0 |= MDM_CTL0_DTR2;
+ } else if (port->mapbase == _Ser3UTCR0) {
+ if (mctrl & TIOCM_RTS)
+ mdm_ctl0 &= ~MDM_CTL0_RTS1;
+ else
+ mdm_ctl0 |= MDM_CTL0_RTS1;
+
+ if (mctrl & TIOCM_DTR)
+ mdm_ctl0 &= ~MDM_CTL0_DTR1;
+ else
+ mdm_ctl0 |= MDM_CTL0_DTR1;
+ }
+
+ MDM_CTL_0 = mdm_ctl0;
+}
+
+static u_int neponset_get_mctrl(struct uart_port *port)
+{
+ u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+ u_int mdm_ctl1 = MDM_CTL_1;
+
+ if (port->mapbase == _Ser1UTCR0) {
+ if (mdm_ctl1 & MDM_CTL1_DCD2)
+ ret &= ~TIOCM_CD;
+ if (mdm_ctl1 & MDM_CTL1_CTS2)
+ ret &= ~TIOCM_CTS;
+ if (mdm_ctl1 & MDM_CTL1_DSR2)
+ ret &= ~TIOCM_DSR;
+ } else if (port->mapbase == _Ser3UTCR0) {
+ if (mdm_ctl1 & MDM_CTL1_DCD1)
+ ret &= ~TIOCM_CD;
+ if (mdm_ctl1 & MDM_CTL1_CTS1)
+ ret &= ~TIOCM_CTS;
+ if (mdm_ctl1 & MDM_CTL1_DSR1)
+ ret &= ~TIOCM_DSR;
+ }
+
+ return ret;
+}
+
+static struct sa1100_port_fns neponset_port_fns __devinitdata = {
+ .set_mctrl = neponset_set_mctrl,
+ .get_mctrl = neponset_get_mctrl,
+};
+
+static int __devinit neponset_probe(struct platform_device *dev)
+{
+ sa1100_register_uart_fns(&neponset_port_fns);
+
+ /*
+ * Install handler for GPIO25.
+ */
+ irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler);
+
+ /*
+ * We would set IRQ_GPIO25 to be a wake-up IRQ, but
+ * unfortunately something on the Neponset activates
+ * this IRQ on sleep (ethernet?)
+ */
+#if 0
+ enable_irq_wake(IRQ_GPIO25);
+#endif
+
+ /*
+ * Setup other Neponset IRQs. SA1111 will be done by the
+ * generic SA1111 code.
+ */
+ irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
+ set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
+ irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
+ set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
+
+ /*
+ * Disable GPIO 0/1 drivers so the buttons work on the module.
+ */
+ NCR_0 = NCR_GP01_OFF;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * LDM power management.
+ */
+static unsigned int neponset_saved_state;
+
+static int neponset_suspend(struct platform_device *dev, pm_message_t state)
+{
+ /*
+ * Save state.
+ */
+ neponset_saved_state = NCR_0;
+
+ return 0;
+}
+
+static int neponset_resume(struct platform_device *dev)
+{
+ NCR_0 = neponset_saved_state;
+
+ return 0;
+}
+
+#else
+#define neponset_suspend NULL
+#define neponset_resume NULL
+#endif
+
+static struct platform_driver neponset_device_driver = {
+ .probe = neponset_probe,
+ .suspend = neponset_suspend,
+ .resume = neponset_resume,
+ .driver = {
+ .name = "neponset",
+ },
+};
+
+static struct resource neponset_resources[] = {
+ [0] = {
+ .start = 0x10000000,
+ .end = 0x17ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device neponset_device = {
+ .name = "neponset",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(neponset_resources),
+ .resource = neponset_resources,
+};
+
+static struct resource sa1111_resources[] = {
+ [0] = {
+ .start = 0x40000000,
+ .end = 0x40001fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_NEPONSET_SA1111,
+ .end = IRQ_NEPONSET_SA1111,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .irq_base = IRQ_BOARD_END,
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+ .name = "sa1111",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sa1111_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
+ },
+ .num_resources = ARRAY_SIZE(sa1111_resources),
+ .resource = sa1111_resources,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .name = "smc91x-regs",
+ .start = SA1100_CS3_PHYS,
+ .end = SA1100_CS3_PHYS + 0x01ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_NEPONSET_SMC9196,
+ .end = IRQ_NEPONSET_SMC9196,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "smc91x-attrib",
+ .start = SA1100_CS3_PHYS + 0x02000000,
+ .end = SA1100_CS3_PHYS + 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &neponset_device,
+ &sa1111_device,
+ &smc91x_device,
+};
+
+extern void sa1110_mb_disable(void);
+
+static int __init neponset_init(void)
+{
+ platform_driver_register(&neponset_device_driver);
+
+ /*
+ * The Neponset is only present on the Assabet machine type.
+ */
+ if (!machine_is_assabet())
+ return -ENODEV;
+
+ /*
+ * Ensure that the memory bus request/grant signals are setup,
+ * and the grant is held in its inactive state, whether or not
+ * we actually have a Neponset attached.
+ */
+ sa1110_mb_disable();
+
+ if (!machine_has_neponset()) {
+ printk(KERN_DEBUG "Neponset expansion board not present\n");
+ return -ENODEV;
+ }
+
+ if (WHOAMI != 0x11) {
+ printk(KERN_WARNING "Neponset board detected, but "
+ "wrong ID: %02x\n", WHOAMI);
+ return -ENODEV;
+ }
+
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+subsys_initcall(neponset_init);
+
+static struct map_desc neponset_io_desc[] __initdata = {
+ { /* System Registers */
+ .virtual = 0xf3000000,
+ .pfn = __phys_to_pfn(0x10000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }, { /* SA-1111 */
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(0x40000000),
+ .length = SZ_1M,
+ .type = MT_DEVICE
+ }
+};
+
+void __init neponset_map_io(void)
+{
+ iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
+}
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
new file mode 100644
index 00000000..fba7a913
--- /dev/null
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/mach-sa1100/pci-nanoengine.c
+ *
+ * PCI functions for BSE nanoEngine PCI
+ *
+ * Copyright (C) 2010 Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
+ *
+ * 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/irq.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+#include <mach/nanoengine.h>
+
+static DEFINE_SPINLOCK(nano_lock);
+
+static int nanoengine_get_pci_address(struct pci_bus *bus,
+ unsigned int devfn, int where, unsigned long *address)
+{
+ int ret = PCIBIOS_DEVICE_NOT_FOUND;
+ unsigned int busnr = bus->number;
+
+ *address = NANO_PCI_CONFIG_SPACE_VIRT +
+ ((bus->number << 16) | (devfn << 8) | (where & ~3));
+
+ ret = (busnr > 255 || devfn > 255 || where > 255) ?
+ PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
+
+ return ret;
+}
+
+static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ int ret;
+ unsigned long address;
+ unsigned long flags;
+ u32 v;
+
+ /* nanoEngine PCI bridge does not return -1 for a non-existing
+ * device. We must fake the answer. We know that the only valid
+ * device is device zero at bus 0, which is the network chip. */
+ if (bus->number != 0 || (devfn >> 3) != 0) {
+ v = -1;
+ nanoengine_get_pci_address(bus, devfn, where, &address);
+ goto exit_function;
+ }
+
+ spin_lock_irqsave(&nano_lock, flags);
+
+ ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
+ v = __raw_readl(address);
+
+ spin_unlock_irqrestore(&nano_lock, flags);
+
+ v >>= ((where & 3) * 8);
+ v &= (unsigned long)(-1) >> ((4 - size) * 8);
+
+exit_function:
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ int ret;
+ unsigned long address;
+ unsigned long flags;
+ unsigned shift;
+ u32 v;
+
+ shift = (where & 3) * 8;
+
+ spin_lock_irqsave(&nano_lock, flags);
+
+ ret = nanoengine_get_pci_address(bus, devfn, where, &address);
+ if (ret != PCIBIOS_SUCCESSFUL)
+ return ret;
+ v = __raw_readl(address);
+ switch (size) {
+ case 1:
+ v &= ~(0xFF << shift);
+ v |= val << shift;
+ break;
+ case 2:
+ v &= ~(0xFFFF << shift);
+ v |= val << shift;
+ break;
+ case 4:
+ v = val;
+ break;
+ }
+ __raw_writel(v, address);
+
+ spin_unlock_irqrestore(&nano_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_nano_ops = {
+ .read = nanoengine_read_config,
+ .write = nanoengine_write_config,
+};
+
+static int __init pci_nanoengine_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return NANOENGINE_IRQ_GPIO_PCI;
+}
+
+struct pci_bus * __init pci_nanoengine_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_nano_ops, sys);
+}
+
+static struct resource pci_io_ports = {
+ .name = "PCI IO",
+ .start = 0x400,
+ .end = 0x7FF,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource pci_non_prefetchable_memory = {
+ .name = "PCI non-prefetchable",
+ .start = NANO_PCI_MEM_RW_PHYS,
+ /* nanoEngine documentation says there is a 1 Megabyte window here,
+ * but PCI reports just 128 + 8 kbytes. */
+ .end = NANO_PCI_MEM_RW_PHYS + NANO_PCI_MEM_RW_SIZE - 1,
+/* .end = NANO_PCI_MEM_RW_PHYS + SZ_128K + SZ_8K - 1,*/
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ * nanoEngine PCI reports 1 Megabyte of prefetchable memory, but it
+ * overlaps with previously defined memory.
+ *
+ * Here is what happens:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: can't assign mem pref (size 0x100000)
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
+ *
+ * On the other hand, if we do not request the prefetchable memory resource,
+ * linux will alloc it first and the two non-prefetchable memory areas that
+ * are our real interest will not be mapped. So we choose to map it to an
+ * unused area. It gets recognized as expansion ROM, but becomes disabled.
+ *
+ * Here is what happens then:
+ *
+# dmesg
+...
+pci 0000:00:00.0: [8086:1209] type 0 class 0x000200
+pci 0000:00:00.0: reg 10: [mem 0x00021000-0x00021fff]
+pci 0000:00:00.0: reg 14: [io 0x0000-0x003f]
+pci 0000:00:00.0: reg 18: [mem 0x00000000-0x0001ffff]
+pci 0000:00:00.0: reg 30: [mem 0x00000000-0x000fffff pref]
+pci 0000:00:00.0: supports D1 D2
+pci 0000:00:00.0: PME# supported from D0 D1 D2 D3hot
+pci 0000:00:00.0: PME# disabled
+PCI: bus0: Fast back to back transfers enabled
+pci 0000:00:00.0: BAR 6: assigned [mem 0x78000000-0x780fffff pref]
+pci 0000:00:00.0: BAR 2: assigned [mem 0x18600000-0x1861ffff]
+pci 0000:00:00.0: BAR 2: set to [mem 0x18600000-0x1861ffff] (PCI address [0x0-0x1ffff])
+pci 0000:00:00.0: BAR 0: assigned [mem 0x18620000-0x18620fff]
+pci 0000:00:00.0: BAR 0: set to [mem 0x18620000-0x18620fff] (PCI address [0x20000-0x20fff])
+pci 0000:00:00.0: BAR 1: assigned [io 0x0400-0x043f]
+pci 0000:00:00.0: BAR 1: set to [io 0x0400-0x043f] (PCI address [0x0-0x3f])
+
+# lspci -vv -s 0000:00:00.0
+00:00.0 Class 0200: Device 8086:1209 (rev 09)
+ Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
+ Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR+ <PERR+ INTx-
+ Latency: 0 (2000ns min, 14000ns max), Cache Line Size: 32 bytes
+ Interrupt: pin A routed to IRQ 0
+ Region 0: Memory at 18620000 (32-bit, non-prefetchable) [size=4K]
+ Region 1: I/O ports at 0400 [size=64]
+ Region 2: [virtual] Memory at 18600000 (32-bit, non-prefetchable) [size=128K]
+ [virtual] Expansion ROM at 78000000 [disabled] [size=1M]
+ Capabilities: [dc] Power Management version 2
+ Flags: PMEClk- DSI+ D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
+ Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=2 PME-
+ Kernel driver in use: e100
+ Kernel modules: e100
+ *
+ */
+static struct resource pci_prefetchable_memory = {
+ .name = "PCI prefetchable",
+ .start = 0x78000000,
+ .end = 0x78000000 + NANO_PCI_MEM_RW_SIZE - 1,
+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_nanoengine_setup_resources(struct resource **resource)
+{
+ if (request_resource(&ioport_resource, &pci_io_ports)) {
+ printk(KERN_ERR "PCI: unable to allocate io port region\n");
+ return -EBUSY;
+ }
+ if (request_resource(&iomem_resource, &pci_non_prefetchable_memory)) {
+ release_resource(&pci_io_ports);
+ printk(KERN_ERR "PCI: unable to allocate non prefetchable\n");
+ return -EBUSY;
+ }
+ if (request_resource(&iomem_resource, &pci_prefetchable_memory)) {
+ release_resource(&pci_io_ports);
+ release_resource(&pci_non_prefetchable_memory);
+ printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
+ return -EBUSY;
+ }
+ resource[0] = &pci_io_ports;
+ resource[1] = &pci_non_prefetchable_memory;
+ resource[2] = &pci_prefetchable_memory;
+
+ return 1;
+}
+
+int __init pci_nanoengine_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+
+ if (nr == 0) {
+ sys->mem_offset = NANO_PCI_MEM_RW_PHYS;
+ sys->io_offset = 0x400;
+ ret = pci_nanoengine_setup_resources(sys->resource);
+ /* Enable alternate memory bus master mode, see
+ * "Intel StrongARM SA1110 Developer's Manual",
+ * section 10.8, "Alternate Memory Bus Master Mode". */
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+ GAFR |= GPIO_MBGNT | GPIO_MBREQ;
+ TUCR |= TUCR_MBGPIO;
+ }
+
+ return ret;
+}
+
+static struct hw_pci nanoengine_pci __initdata = {
+ .map_irq = pci_nanoengine_map_irq,
+ .nr_controllers = 1,
+ .scan = pci_nanoengine_scan_bus,
+ .setup = pci_nanoengine_setup,
+};
+
+static int __init nanoengine_pci_init(void)
+{
+ if (machine_is_nanoengine())
+ pci_common_init(&nanoengine_pci);
+ return 0;
+}
+
+subsys_initcall(nanoengine_pci_init);
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
new file mode 100644
index 00000000..65161f2b
--- /dev/null
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -0,0 +1,153 @@
+/*
+ * linux/arch/arm/mach-sa1100/pleb.c
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+
+/*
+ * Ethernet IRQ mappings
+ */
+
+#define PLEB_ETH0_P (0x20000300) /* Ethernet 0 in PCMCIA0 IO */
+#define PLEB_ETH0_V (0xf6000300)
+
+#define GPIO_ETH0_IRQ GPIO_GPIO(21)
+#define GPIO_ETH0_EN GPIO_GPIO(26)
+
+#define IRQ_GPIO_ETH0_IRQ IRQ_GPIO21
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = PLEB_ETH0_P,
+ .end = PLEB_ETH0_P | 0x03ffffff,
+ .flags = IORESOURCE_MEM,
+ },
+#if 0 /* Autoprobe instead, to get rising/falling edge characteristic right */
+ [1] = {
+ .start = IRQ_GPIO_ETH0_IRQ,
+ .end = IRQ_GPIO_ETH0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &smc91x_device,
+};
+
+
+/*
+ * Pleb's memory map
+ * has flash memory (typically 4 or 8 meg) selected by
+ * the two SA1100 lowest chip select outputs.
+ */
+static struct resource pleb_flash_resources[] = {
+ [0] = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SA1100_CS1_PHYS,
+ .end = SA1100_CS1_PHYS + SZ_8M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+
+static struct mtd_partition pleb_partitions[] = {
+ {
+ .name = "blob",
+ .offset = 0,
+ .size = 0x00020000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x000e0000,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00300000,
+ }
+};
+
+
+static struct flash_platform_data pleb_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = pleb_partitions,
+ .nr_parts = ARRAY_SIZE(pleb_partitions),
+};
+
+
+static void __init pleb_init(void)
+{
+ sa11x0_register_mtd(&pleb_flash_data, pleb_flash_resources,
+ ARRAY_SIZE(pleb_flash_resources));
+
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+
+static void __init pleb_map_io(void)
+{
+ sa1100_map_io();
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+
+ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
+ GPDR |= GPIO_UART_TXD;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
+
+ /*
+ * Fix expansion memory timing for network card
+ */
+ MECR = ((2<<10) | (2<<5) | (2<<0));
+
+ /*
+ * Enable the SMC ethernet controller
+ */
+ GPDR |= GPIO_ETH0_EN; /* set to output */
+ GPCR = GPIO_ETH0_EN; /* clear MCLK (enable smc) */
+
+ GPDR &= ~GPIO_ETH0_IRQ;
+
+ irq_set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING);
+}
+
+MACHINE_START(PLEB, "PLEB")
+ .map_io = pleb_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = pleb_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
new file mode 100644
index 00000000..c4661aab
--- /dev/null
+++ b/arch/arm/mach-sa1100/pm.c
@@ -0,0 +1,128 @@
+/*
+ * SA1100 Power Management Routines
+ *
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * History:
+ *
+ * 2001-02-06: Cliff Brake Initial code
+ *
+ * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
+ * Chester Kuo <chester@linux.org.tw>
+ * Save more value for the resume function! Support
+ * Bitsy/Assabet/Freebird board
+ *
+ * 2001-08-29: Nicolas Pitre <nico@fluxnic.net>
+ * Cleaned up, pushed platform dependent stuff
+ * in the platform specific files.
+ *
+ * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
+ * Storage is local on the stack now.
+ */
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <mach/hardware.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+#include <asm/mach/time.h>
+
+extern void sa1100_cpu_suspend(long);
+
+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
+
+/*
+ * List of global SA11x0 peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * on the stack and then the stack pointer is stored last in sleep.S.
+ */
+enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
+ SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
+
+ SLEEP_SAVE_Ser1SDCR0,
+
+ SLEEP_SAVE_COUNT
+};
+
+
+static int sa11x0_pm_enter(suspend_state_t state)
+{
+ unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
+
+ gpio = GPLR;
+
+ /* save vital registers */
+ SAVE(GPDR);
+ SAVE(GAFR);
+
+ SAVE(PPDR);
+ SAVE(PPSR);
+ SAVE(PPAR);
+ SAVE(PSDR);
+
+ SAVE(Ser1SDCR0);
+
+ /* Clear previous reset status */
+ RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
+
+ /* set resume return address */
+ PSPR = virt_to_phys(cpu_resume);
+
+ /* go zzz */
+ sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET);
+
+ cpu_init();
+
+ /*
+ * Ensure not to come back here if it wasn't intended
+ */
+ PSPR = 0;
+
+ /*
+ * Ensure interrupt sources are disabled; we will re-init
+ * the interrupt subsystem via the device manager.
+ */
+ ICLR = 0;
+ ICCR = 1;
+ ICMR = 0;
+
+ /* restore registers */
+ RESTORE(GPDR);
+ RESTORE(GAFR);
+
+ RESTORE(PPDR);
+ RESTORE(PPSR);
+ RESTORE(PPAR);
+ RESTORE(PSDR);
+
+ RESTORE(Ser1SDCR0);
+
+ GPSR = gpio;
+ GPCR = ~gpio;
+
+ /*
+ * Clear the peripheral sleep-hold bit.
+ */
+ PSSR = PSSR_PH;
+
+ return 0;
+}
+
+static const struct platform_suspend_ops sa11x0_pm_ops = {
+ .enter = sa11x0_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init sa11x0_pm_init(void)
+{
+ suspend_set_ops(&sa11x0_pm_ops);
+ return 0;
+}
+
+late_initcall(sa11x0_pm_init);
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
new file mode 100644
index 00000000..7917b240
--- /dev/null
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -0,0 +1,90 @@
+/*
+ * linux/arch/arm/mach-sa1100/shannon.c
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/mcp.h>
+#include <mach/shannon.h>
+
+#include "generic.h"
+
+static struct mtd_partition shannon_partitions[] = {
+ {
+ .name = "BLOB boot loader",
+ .offset = 0,
+ .size = 0x20000
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0xe0000
+ },
+ {
+ .name = "initrd",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ }
+};
+
+static struct flash_platform_data shannon_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = shannon_partitions,
+ .nr_parts = ARRAY_SIZE(shannon_partitions),
+};
+
+static struct resource shannon_flash_resource = {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_4M - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct mcp_plat_data shannon_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+static void __init shannon_init(void)
+{
+ sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
+ sa11x0_register_mcp(&shannon_mcp_data);
+}
+
+static void __init shannon_map_io(void)
+{
+ sa1100_map_io();
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+
+ Ser1SDCR0 |= SDCR0_SUS;
+ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
+ GPDR |= GPIO_UART_TXD | SHANNON_GPIO_CODEC_RESET;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
+
+ /* reset the codec */
+ GPCR = SHANNON_GPIO_CODEC_RESET;
+ GPSR = SHANNON_GPIO_CODEC_RESET;
+}
+
+MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
+ .boot_params = 0xc0000100,
+ .map_io = shannon_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+ .init_machine = shannon_init,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
new file mode 100644
index 00000000..cfb76077
--- /dev/null
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -0,0 +1,236 @@
+/*
+ * linux/arch/arm/mach-sa1100/simpad.c
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+#include <mach/mcp.h>
+#include <mach/simpad.h>
+
+#include <linux/serial_core.h>
+#include <linux/ioport.h>
+
+#include "generic.h"
+
+long cs3_shadow;
+
+long get_cs3_shadow(void)
+{
+ return cs3_shadow;
+}
+
+void set_cs3(long value)
+{
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
+}
+
+void set_cs3_bit(int value)
+{
+ cs3_shadow |= value;
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+}
+
+void clear_cs3_bit(int value)
+{
+ cs3_shadow &= ~value;
+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+}
+
+EXPORT_SYMBOL(set_cs3_bit);
+EXPORT_SYMBOL(clear_cs3_bit);
+
+static struct map_desc simpad_io_desc[] __initdata = {
+ { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* Paules CS3, write only */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x18000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ },
+};
+
+
+static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == (u_int)&Ser1UTCR0) {
+ if (state)
+ {
+ clear_cs3_bit(RS232_ON);
+ clear_cs3_bit(DECT_POWER_ON);
+ }else
+ {
+ set_cs3_bit(RS232_ON);
+ set_cs3_bit(DECT_POWER_ON);
+ }
+ }
+}
+
+static struct sa1100_port_fns simpad_port_fns __initdata = {
+ .pm = simpad_uart_pm,
+};
+
+
+static struct mtd_partition simpad_partitions[] = {
+ {
+ .name = "SIMpad boot firmware",
+ .size = 0x00080000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "SIMpad kernel",
+ .size = 0x0010000,
+ .offset = MTDPART_OFS_APPEND,
+ }, {
+ .name = "SIMpad root jffs2",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+
+static struct flash_platform_data simpad_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = simpad_partitions,
+ .nr_parts = ARRAY_SIZE(simpad_partitions),
+};
+
+
+static struct resource simpad_flash_resources [] = {
+ {
+ .start = SA1100_CS0_PHYS,
+ .end = SA1100_CS0_PHYS + SZ_16M -1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SA1100_CS1_PHYS,
+ .end = SA1100_CS1_PHYS + SZ_16M -1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct mcp_plat_data simpad_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+};
+
+
+
+static void __init simpad_map_io(void)
+{
+ sa1100_map_io();
+
+ iotable_init(simpad_io_desc, ARRAY_SIZE(simpad_io_desc));
+
+ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
+ ENABLE_5V | RESET_SIMCARD | DECT_POWER_ON);
+
+
+ sa1100_register_uart_fns(&simpad_port_fns);
+ sa1100_register_uart(0, 3); /* serial interface */
+ sa1100_register_uart(1, 1); /* DECT */
+
+ // Reassign UART 1 pins
+ GAFR |= GPIO_UART_TXD | GPIO_UART_RXD;
+ GPDR |= GPIO_UART_TXD | GPIO_LDD13 | GPIO_LDD15;
+ GPDR &= ~GPIO_UART_RXD;
+ PPAR |= PPAR_UPR;
+
+ /*
+ * Set up registers for sleep mode.
+ */
+
+
+ PWER = PWER_GPIO0| PWER_RTC;
+ PGSR = 0x818;
+ PCFR = 0;
+ PSDR = 0;
+
+}
+
+static void simpad_power_off(void)
+{
+ local_irq_disable(); // was cli
+ set_cs3(0x800); /* only SD_MEDIAQ */
+
+ /* disable internal oscillator, float CS lines */
+ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
+ /* enable wake-up on GPIO0 (Assabet...) */
+ PWER = GFER = GRER = 1;
+ /*
+ * set scratchpad to zero, just in case it is used as a
+ * restart address by the bootloader.
+ */
+ PSPR = 0;
+ PGSR = 0;
+ /* enter sleep mode */
+ PMCR = PMCR_SF;
+ while(1);
+
+ local_irq_enable(); /* we won't ever call it */
+
+
+}
+
+
+/*
+ * MediaQ Video Device
+ */
+static struct platform_device simpad_mq200fb = {
+ .name = "simpad-mq200",
+ .id = 0,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &simpad_mq200fb
+};
+
+
+
+static int __init simpad_init(void)
+{
+ int ret;
+
+ pm_power_off = simpad_power_off;
+
+ sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
+ ARRAY_SIZE(simpad_flash_resources));
+ sa11x0_register_mcp(&simpad_mcp_data);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if(ret)
+ printk(KERN_WARNING "simpad: Unable to register mq200 framebuffer device");
+
+ return 0;
+}
+
+arch_initcall(simpad_init);
+
+
+MACHINE_START(SIMPAD, "Simpad")
+ /* Maintainer: Holger Freyther */
+ .boot_params = 0xc0000100,
+ .map_io = simpad_map_io,
+ .init_irq = sa1100_init_irq,
+ .timer = &sa1100_timer,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
new file mode 100644
index 00000000..04f2a618
--- /dev/null
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -0,0 +1,151 @@
+/*
+ * SA11x0 Assembler Sleep/WakeUp Management Routines
+ *
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * History:
+ *
+ * 2001-02-06: Cliff Brake Initial code
+ *
+ * 2001-08-29: Nicolas Pitre Simplified.
+ *
+ * 2002-05-27: Nicolas Pitre Revisited, more cleanup and simplification.
+ * Storage is on the stack now.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+ .text
+/*
+ * sa1100_cpu_suspend()
+ *
+ * Causes sa11x0 to enter sleep state
+ *
+ */
+
+ENTRY(sa1100_cpu_suspend)
+ stmfd sp!, {r4 - r12, lr} @ save registers on stack
+ mov r1, r0
+ ldr r3, =sa1100_cpu_resume @ return function
+ bl cpu_suspend
+
+ @ disable clock switching
+ mcr p15, 0, r1, c15, c2, 2
+
+ @ Adjust memory timing before lowering CPU clock
+ @ Clock speed adjustment without changing memory timing makes
+ @ CPU hang in some cases
+ ldr r0, =MDREFR
+ ldr r1, [r0]
+ orr r1, r1, #MDREFR_K1DB2
+ str r1, [r0]
+
+ @ delay 90us and set CPU PLL to lowest speed
+ @ fixes resume problem on high speed SA1110
+ mov r0, #90
+ bl __udelay
+ ldr r0, =PPCR
+ mov r1, #0
+ str r1, [r0]
+ mov r0, #90
+ bl __udelay
+
+ /*
+ * SA1110 SDRAM controller workaround. register values:
+ *
+ * r0 = &MSC0
+ * r1 = &MSC1
+ * r2 = &MSC2
+ * r3 = MSC0 value
+ * r4 = MSC1 value
+ * r5 = MSC2 value
+ * r6 = &MDREFR
+ * r7 = first MDREFR value
+ * r8 = second MDREFR value
+ * r9 = &MDCNFG
+ * r10 = MDCNFG value
+ * r11 = third MDREFR value
+ * r12 = &PMCR
+ * r13 = PMCR value (1)
+ */
+
+ ldr r0, =MSC0
+ ldr r1, =MSC1
+ ldr r2, =MSC2
+
+ ldr r3, [r0]
+ bic r3, r3, #FMsk(MSC_RT)
+ bic r3, r3, #FMsk(MSC_RT)<<16
+
+ ldr r4, [r1]
+ bic r4, r4, #FMsk(MSC_RT)
+ bic r4, r4, #FMsk(MSC_RT)<<16
+
+ ldr r5, [r2]
+ bic r5, r5, #FMsk(MSC_RT)
+ bic r5, r5, #FMsk(MSC_RT)<<16
+
+ ldr r6, =MDREFR
+
+ ldr r7, [r6]
+bic r7, r7, #0x0000FF00
+bic r7, r7, #0x000000F0
+orr r8, r7, #MDREFR_SLFRSH
+
+ ldr r9, =MDCNFG
+ ldr r10, [r9]
+ bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
+ bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
+
+ bic r11, r8, #MDREFR_SLFRSH
+ bic r11, r11, #MDREFR_E1PIN
+
+ ldr r12, =PMCR
+
+ mov r13, #PMCR_SF
+
+ b sa1110_sdram_controller_fix
+
+ .align 5
+sa1110_sdram_controller_fix:
+
+ @ Step 1 clear RT field of all MSCx registers
+ str r3, [r0]
+ str r4, [r1]
+ str r5, [r2]
+
+ @ Step 2 clear DRI field in MDREFR
+ str r7, [r6]
+
+ @ Step 3 set SLFRSH bit in MDREFR
+ str r8, [r6]
+
+ @ Step 4 clear DE bis in MDCNFG
+ str r10, [r9]
+
+ @ Step 5 clear DRAM refresh control register
+ str r11, [r6]
+
+ @ Wow, now the hardware suspend request pins can be used, that makes them functional for
+ @ about 7 ns out of the entire time that the CPU is running!
+
+ @ Step 6 set force sleep bit in PMCR
+
+ str r13, [r12]
+
+20: b 20b @ loop waiting for sleep
+
+/*
+ * cpu_sa1100_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ */
+ .align 5
+sa1100_cpu_resume:
+ mcr p15, 0, r1, c15, c1, 2 @ enable clock switching
+ ldmfd sp!, {r4 - r12, pc} @ return to caller
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
new file mode 100644
index 00000000..b20ff93b
--- /dev/null
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -0,0 +1,243 @@
+/*
+ * linux/arch/arm/mach-sa1100/ssp.c
+ *
+ * Copyright (C) 2003 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Generic SSP driver. This provides the generic core for simple
+ * IO-based SSP applications.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <asm/hardware/ssp.h>
+
+#define TIMEOUT 100000
+
+static irqreturn_t ssp_interrupt(int irq, void *dev_id)
+{
+ unsigned int status = Ser4SSSR;
+
+ if (status & SSSR_ROR)
+ printk(KERN_WARNING "SSP: receiver overrun\n");
+
+ Ser4SSSR = SSSR_ROR;
+
+ return status ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/**
+ * ssp_write_word - write a word to the SSP port
+ * @data: 16-bit, MSB justified data to write.
+ *
+ * Wait for a free entry in the SSP transmit FIFO, and write a data
+ * word to the SSP port. Wait for the SSP port to start sending
+ * the data.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
+ */
+int ssp_write_word(u16 data)
+{
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_TNF)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ Ser4SSDR = data;
+
+ timeout = TIMEOUT;
+ while (!(Ser4SSSR & SSSR_BSY)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+/**
+ * ssp_read_word - read a word from the SSP port
+ *
+ * Wait for a data word in the SSP receive FIFO, and return the
+ * received data. Data is LSB justified.
+ *
+ * Note: Currently, if data is not expected to be received, this
+ * function will wait for ever.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 16-bit data success
+ */
+int ssp_read_word(u16 *data)
+{
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_RNE)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ *data = (u16)Ser4SSDR;
+
+ return 0;
+}
+
+/**
+ * ssp_flush - flush the transmit and receive FIFOs
+ *
+ * Wait for the SSP to idle, and ensure that the receive FIFO
+ * is empty.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
+ */
+int ssp_flush(void)
+{
+ int timeout = TIMEOUT * 2;
+
+ do {
+ while (Ser4SSSR & SSSR_RNE) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ (void) Ser4SSDR;
+ }
+ if (!--timeout)
+ return -ETIMEDOUT;
+ } while (Ser4SSSR & SSSR_BSY);
+
+ return 0;
+}
+
+/**
+ * ssp_enable - enable the SSP port
+ *
+ * Turn on the SSP port.
+ */
+void ssp_enable(void)
+{
+ Ser4SSCR0 |= SSCR0_SSE;
+}
+
+/**
+ * ssp_disable - shut down the SSP port
+ *
+ * Turn off the SSP port, optionally powering it down.
+ */
+void ssp_disable(void)
+{
+ Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_save_state - save the SSP configuration
+ * @ssp: pointer to structure to save SSP configuration
+ *
+ * Save the configured SSP state for suspend.
+ */
+void ssp_save_state(struct ssp_state *ssp)
+{
+ ssp->cr0 = Ser4SSCR0;
+ ssp->cr1 = Ser4SSCR1;
+
+ Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_restore_state - restore a previously saved SSP configuration
+ * @ssp: pointer to configuration saved by ssp_save_state
+ *
+ * Restore the SSP configuration saved previously by ssp_save_state.
+ */
+void ssp_restore_state(struct ssp_state *ssp)
+{
+ Ser4SSSR = SSSR_ROR;
+
+ Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
+ Ser4SSCR1 = ssp->cr1;
+ Ser4SSCR0 = ssp->cr0;
+}
+
+/**
+ * ssp_init - setup the SSP port
+ *
+ * initialise and claim resources for the SSP port.
+ *
+ * Returns:
+ * %-ENODEV if the SSP port is unavailable
+ * %-EBUSY if the resources are already in use
+ * %0 on success
+ */
+int ssp_init(void)
+{
+ int ret;
+
+ if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
+ return -ENODEV;
+
+ if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
+ return -EBUSY;
+ }
+
+ Ser4SSSR = SSSR_ROR;
+
+ ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
+ if (ret)
+ goto out_region;
+
+ return 0;
+
+ out_region:
+ release_mem_region(__PREG(Ser4SSCR0), 0x18);
+ return ret;
+}
+
+/**
+ * ssp_exit - undo the effects of ssp_init
+ *
+ * release and free resources for the SSP port.
+ */
+void ssp_exit(void)
+{
+ Ser4SSCR0 &= ~SSCR0_SSE;
+
+ free_irq(IRQ_Ser4SSP, NULL);
+ release_mem_region(__PREG(Ser4SSCR0), 0x18);
+}
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ssp_write_word);
+EXPORT_SYMBOL(ssp_read_word);
+EXPORT_SYMBOL(ssp_flush);
+EXPORT_SYMBOL(ssp_enable);
+EXPORT_SYMBOL(ssp_disable);
+EXPORT_SYMBOL(ssp_save_state);
+EXPORT_SYMBOL(ssp_restore_state);
+EXPORT_SYMBOL(ssp_init);
+EXPORT_SYMBOL(ssp_exit);
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
new file mode 100644
index 00000000..fa660249
--- /dev/null
+++ b/arch/arm/mach-sa1100/time.c
@@ -0,0 +1,164 @@
+/*
+ * linux/arch/arm/mach-sa1100/time.c
+ *
+ * Copyright (C) 1998 Deborah Wallach.
+ * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com>
+ *
+ * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net>
+ * Rewritten: big cleanup, much simpler, better HZ accuracy.
+ *
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h> /* just for sched_clock() - funny that */
+#include <linux/timex.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
+#include <mach/hardware.h>
+
+/*
+ * This is the SA11x0 sched_clock implementation.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 3.6864MHz,
+ * NSEC_PER_SEC, 60).
+ * This gives a resolution of about 271ns and a wrap period of about 19min.
+ */
+#define SC_MULT 2275555556u
+#define SC_SHIFT 23
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = OSCR;
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace sa1100_update_sched_clock(void)
+{
+ u32 cyc = OSCR;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+#define MIN_OSCR_DELTA 2
+
+static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *c = dev_id;
+
+ /* Disarm the compare/match, signal the event. */
+ OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
+ c->event_handler(c);
+
+ return IRQ_HANDLED;
+}
+
+static int
+sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
+{
+ unsigned long next, oscr;
+
+ OIER |= OIER_E0;
+ next = OSCR + delta;
+ OSMR0 = next;
+ oscr = OSCR;
+
+ return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
+}
+
+static void
+sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ OIER &= ~OIER_E0;
+ OSSR = OSSR_M0;
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+}
+
+static struct clock_event_device ckevt_sa1100_osmr0 = {
+ .name = "osmr0",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = sa1100_osmr0_set_next_event,
+ .set_mode = sa1100_osmr0_set_mode,
+};
+
+static struct irqaction sa1100_timer_irq = {
+ .name = "ost0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = sa1100_ost0_interrupt,
+ .dev_id = &ckevt_sa1100_osmr0,
+};
+
+static void __init sa1100_timer_init(void)
+{
+ OIER = 0;
+ OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
+
+ init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
+ 3686400, SC_MULT, SC_SHIFT);
+
+ clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4);
+ ckevt_sa1100_osmr0.max_delta_ns =
+ clockevent_delta2ns(0x7fffffff, &ckevt_sa1100_osmr0);
+ ckevt_sa1100_osmr0.min_delta_ns =
+ clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_sa1100_osmr0) + 1;
+ ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
+
+ setup_irq(IRQ_OST0, &sa1100_timer_irq);
+
+ clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32,
+ clocksource_mmio_readl_up);
+ clockevents_register_device(&ckevt_sa1100_osmr0);
+}
+
+#ifdef CONFIG_PM
+unsigned long osmr[4], oier;
+
+static void sa1100_timer_suspend(void)
+{
+ osmr[0] = OSMR0;
+ osmr[1] = OSMR1;
+ osmr[2] = OSMR2;
+ osmr[3] = OSMR3;
+ oier = OIER;
+}
+
+static void sa1100_timer_resume(void)
+{
+ OSSR = 0x0f;
+ OSMR0 = osmr[0];
+ OSMR1 = osmr[1];
+ OSMR2 = osmr[2];
+ OSMR3 = osmr[3];
+ OIER = oier;
+
+ /*
+ * OSMR0 is the system timer: make sure OSCR is sufficiently behind
+ */
+ OSCR = OSMR0 - LATCH;
+}
+#else
+#define sa1100_timer_suspend NULL
+#define sa1100_timer_resume NULL
+#endif
+
+struct sys_timer sa1100_timer = {
+ .init = sa1100_timer_init,
+ .suspend = sa1100_timer_suspend,
+ .resume = sa1100_timer_resume,
+};
diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile
new file mode 100644
index 00000000..45be9b04
--- /dev/null
+++ b/arch/arm/mach-shark/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := core.o dma.o irq.o pci.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_LEDS) += leds.o
diff --git a/arch/arm/mach-shark/Makefile.boot b/arch/arm/mach-shark/Makefile.boot
new file mode 100644
index 00000000..4320f8b9
--- /dev/null
+++ b/arch/arm/mach-shark/Makefile.boot
@@ -0,0 +1,2 @@
+ zreladdr-y := 0x08008000
+
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
new file mode 100644
index 00000000..5cf7f94c
--- /dev/null
+++ b/arch/arm/mach-shark/core.c
@@ -0,0 +1,159 @@
+/*
+ * linux/arch/arm/mach-shark/arch.c
+ *
+ * Architecture specific stuff.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/leds.h>
+#include <asm/param.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#define IO_BASE 0xe0000000
+#define IO_SIZE 0x08000000
+#define IO_START 0x40000000
+#define ROMCARD_SIZE 0x08000000
+#define ROMCARD_START 0x10000000
+
+void arch_reset(char mode, const char *cmd)
+{
+ short temp;
+ local_irq_disable();
+ /* Reset the Machine via pc[3] of the sequoia chipset */
+ outw(0x09,0x24);
+ temp=inw(0x26);
+ temp = temp | (1<<3) | (1<<10);
+ outw(0x09,0x24);
+ outw(temp,0x26);
+}
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .iobase = 0x3f8,
+ .irq = 4,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ {
+ .iobase = 0x2f8,
+ .irq = 3,
+ .uartclk = 1843200,
+ .regshift = 0,
+ .iotype = UPIO_PORT,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
+ },
+ { },
+};
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ [0] = {
+ .start = 0x70,
+ .end = 0x73,
+ .flags = IORESOURCE_IO,
+ },
+ [1] = {
+ .start = IRQ_ISA_RTC_ALARM,
+ .end = IRQ_ISA_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc_cmos",
+ .id = -1,
+ .resource = rtc_resources,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+};
+
+static int __init shark_init(void)
+{
+ int ret;
+
+ if (machine_is_shark())
+ {
+ ret = platform_device_register(&rtc_device);
+ if (ret) printk(KERN_ERR "Unable to register RTC device: %d\n", ret);
+ ret = platform_device_register(&serial_device);
+ if (ret) printk(KERN_ERR "Unable to register Serial device: %d\n", ret);
+ }
+ return 0;
+}
+
+arch_initcall(shark_init);
+
+extern void shark_init_irq(void);
+
+static struct map_desc shark_io_desc[] __initdata = {
+ {
+ .virtual = IO_BASE,
+ .pfn = __phys_to_pfn(IO_START),
+ .length = IO_SIZE,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init shark_map_io(void)
+{
+ iotable_init(shark_io_desc, ARRAY_SIZE(shark_io_desc));
+}
+
+#define IRQ_TIMER 0
+#define HZ_TIME ((1193180 + HZ/2) / HZ)
+
+static irqreturn_t
+shark_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction shark_timer_irq = {
+ .name = "Shark Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = shark_timer_interrupt,
+};
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init shark_timer_init(void)
+{
+ outb(0x34, 0x43); /* binary, mode 0, LSB/MSB, Ch 0 */
+ outb(HZ_TIME & 0xff, 0x40); /* LSB of count */
+ outb(HZ_TIME >> 8, 0x40);
+
+ setup_irq(IRQ_TIMER, &shark_timer_irq);
+}
+
+static struct sys_timer shark_timer = {
+ .init = shark_timer_init,
+};
+
+MACHINE_START(SHARK, "Shark")
+ /* Maintainer: Alexander Schulz */
+ .boot_params = 0x08003000,
+ .map_io = shark_map_io,
+ .init_irq = shark_init_irq,
+ .timer = &shark_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c
new file mode 100644
index 00000000..10b5b8b3
--- /dev/null
+++ b/arch/arm/mach-shark/dma.c
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/arm/mach-shark/dma.c
+ *
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/kernel/dma-ebsa285.c
+ * Copyright (C) 1998 Phil Blundell
+ */
+
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+static int __init shark_dma_init(void)
+{
+#ifdef CONFIG_ISA_DMA
+ isa_init_dma();
+#endif
+ return 0;
+}
+core_initcall(shark_dma_init);
diff --git a/arch/arm/mach-shark/include/mach/debug-macro.S b/arch/arm/mach-shark/include/mach/debug-macro.S
new file mode 100644
index 00000000..a473f55d
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/debug-macro.S
@@ -0,0 +1,33 @@
+/* arch/arm/mach-shark/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0xe0000000
+ orr \rp, \rp, #0x000003f8
+ mov \rv, \rp
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+ mov \rd, #0
+1001: add \rd, \rd, #1
+ teq \rd, #0x10000
+ bne 1001b
+ .endm
+
diff --git a/arch/arm/mach-shark/include/mach/entry-macro.S b/arch/arm/mach-shark/include/mach/entry-macro.S
new file mode 100644
index 00000000..e2853c0a
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-shark/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Shark platform
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ mov r4, #0xe0000000
+
+ mov \irqstat, #0x0C
+ strb \irqstat, [r4, #0x20] @outb(0x0C, 0x20) /* Poll command */
+ ldrb \irqnr, [r4, #0x20] @irq = inb(0x20) & 7
+ and \irqstat, \irqnr, #0x80
+ teq \irqstat, #0
+ beq 43f
+ and \irqnr, \irqnr, #7
+ teq \irqnr, #2
+ bne 44f
+43: mov \irqstat, #0x0C
+ strb \irqstat, [r4, #0xa0] @outb(0x0C, 0xA0) /* Poll command */
+ ldrb \irqnr, [r4, #0xa0] @irq = (inb(0xA0) & 7) + 8
+ and \irqstat, \irqnr, #0x80
+ teq \irqstat, #0
+ beq 44f
+ and \irqnr, \irqnr, #7
+ add \irqnr, \irqnr, #8
+44: teq \irqstat, #0
+ .endm
+
diff --git a/arch/arm/mach-shark/include/mach/framebuffer.h b/arch/arm/mach-shark/include/mach/framebuffer.h
new file mode 100644
index 00000000..84a5bf6e
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/framebuffer.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-shark/include/mach/framebuffer.h
+ *
+ * by Alexander Schulz
+ *
+ */
+
+#ifndef __ASM_ARCH_FRAMEBUFFER_H
+#define __ASM_ARCH_FRAMEBUFFER_H
+
+/* defines for the Framebuffer */
+#define FB_START 0x06000000
+#define FB_SIZE 0x01000000
+
+#endif
+
diff --git a/arch/arm/mach-shark/include/mach/hardware.h b/arch/arm/mach-shark/include/mach/hardware.h
new file mode 100644
index 00000000..94d84b27
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/hardware.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-shark/include/mach/hardware.h
+ *
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/mach-ebsa110/include/mach/hardware.h
+ * Copyright (C) 1996-1999 Russell King.
+ */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#define UNCACHEABLE_ADDR 0xdf010000
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x6000
+#define PCIBIOS_MIN_MEM 0x50000000
+#define PCIMEM_BASE 0xe8000000
+
+#endif
+
diff --git a/arch/arm/mach-shark/include/mach/io.h b/arch/arm/mach-shark/include/mach/io.h
new file mode 100644
index 00000000..9ccbcecc
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-shark/include/mach/io.h
+ *
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/mach-ebsa110/include/mach/io.h
+ * Copyright (C) 1997,1998 Russell King
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(0xe0000000 + (a)))
+
+#define __mem_pci(addr) (addr)
+
+#endif
diff --git a/arch/arm/mach-shark/include/mach/irqs.h b/arch/arm/mach-shark/include/mach/irqs.h
new file mode 100644
index 00000000..c8e8a4e1
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/irqs.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-shark/include/mach/irqs.h
+ *
+ * by Alexander Schulz
+ */
+
+#define NR_IRQS 16
+
+#define IRQ_ISA_KEYBOARD 1
+#define IRQ_ISA_RTC_ALARM 8
+#define I8042_KBD_IRQ 1
+#define I8042_AUX_IRQ 12
+#define IRQ_HARDDISK 14
diff --git a/arch/arm/mach-shark/include/mach/isa-dma.h b/arch/arm/mach-shark/include/mach/isa-dma.h
new file mode 100644
index 00000000..96c43b8f
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/isa-dma.h
@@ -0,0 +1,13 @@
+/*
+ * arch/arm/mach-shark/include/mach/isa-dma.h
+ *
+ * by Alexander Schulz
+ */
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define MAX_DMA_CHANNELS 8
+#define DMA_ISA_CASCADE 4
+
+#endif /* _ASM_ARCH_DMA_H */
+
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
new file mode 100644
index 00000000..4c0831f8
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-shark/include/mach/memory.h
+ *
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/mach-ebsa110/include/mach/memory.h
+ * Copyright (c) 1996-1999 Russell King.
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <asm/sizes.h>
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x08000000)
+
+#define ARM_DMA_ZONE_SIZE SZ_4M
+
+/*
+ * Cache flushing area
+ */
+#define FLUSH_BASE_PHYS 0x80000000
+#define FLUSH_BASE 0xdf000000
+
+#endif
diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h
new file mode 100644
index 00000000..21c373b3
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/system.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-shark/include/mach/system.h
+ *
+ * by Alexander Schulz
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+/* Found in arch/mach-shark/core.c */
+extern void arch_reset(char mode, const char *cmd);
+
+static inline void arch_idle(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-shark/include/mach/timex.h b/arch/arm/mach-shark/include/mach/timex.h
new file mode 100644
index 00000000..bb6eeaeb
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/timex.h
@@ -0,0 +1,7 @@
+/*
+ * arch/arm/mach-shark/include/mach/timex.h
+ *
+ * by Alexander Schulz
+ */
+
+#define CLOCK_TICK_RATE 1193180
diff --git a/arch/arm/mach-shark/include/mach/uncompress.h b/arch/arm/mach-shark/include/mach/uncompress.h
new file mode 100644
index 00000000..22ccab4c
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/uncompress.h
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-shark/include/mach/uncompress.h
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/mach-footbridge/include/mach/uncompress.h
+ * Copyright (C) 1996,1997,1998 Russell King
+ */
+
+#define SERIAL_BASE ((volatile unsigned char *)0x400003f8)
+
+static inline void putc(int c)
+{
+ volatile int t;
+
+ SERIAL_BASE[0] = c;
+ t=0x10000;
+ while (t--);
+}
+
+static inline void flush(void)
+{
+}
+
+#ifdef DEBUG
+static void putn(unsigned long z)
+{
+ int i;
+ char x;
+
+ putc('0');
+ putc('x');
+ for (i=0;i<8;i++) {
+ x='0'+((z>>((7-i)*4))&0xf);
+ if (x>'9') x=x-'0'+'A'-10;
+ putc(x);
+ }
+}
+
+static void putr()
+{
+ putc('\n');
+ putc('\r');
+}
+#endif
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-shark/include/mach/vmalloc.h b/arch/arm/mach-shark/include/mach/vmalloc.h
new file mode 100644
index 00000000..b10df988
--- /dev/null
+++ b/arch/arm/mach-shark/include/mach/vmalloc.h
@@ -0,0 +1,4 @@
+/*
+ * arch/arm/mach-shark/include/mach/vmalloc.h
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
new file mode 100644
index 00000000..5dce13e4
--- /dev/null
+++ b/arch/arm/mach-shark/irq.c
@@ -0,0 +1,108 @@
+/*
+ * linux/arch/arm/mach-shark/irq.c
+ *
+ * by Alexander Schulz
+ *
+ * derived from linux/arch/ppc/kernel/i8259.c and:
+ * arch/arm/mach-ebsa110/include/mach/irq.h
+ * Copyright (C) 1996-1998 Russell King
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+/*
+ * 8259A PIC functions to handle ISA devices:
+ */
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ * Let through the cascade-interrupt no. 2 (ff-(1<<2)==fb)
+ */
+static unsigned char cached_irq_mask[2] = { 0xfb, 0xff };
+
+/*
+ * These have to be protected by the irq controller spinlock
+ * before being called.
+ */
+static void shark_disable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask;
+ if (d->irq<8) {
+ mask = 1 << d->irq;
+ cached_irq_mask[0] |= mask;
+ outb(cached_irq_mask[1],0xA1);
+ } else {
+ mask = 1 << (d->irq-8);
+ cached_irq_mask[1] |= mask;
+ outb(cached_irq_mask[0],0x21);
+ }
+}
+
+static void shark_enable_8259A_irq(struct irq_data *d)
+{
+ unsigned int mask;
+ if (d->irq<8) {
+ mask = ~(1 << d->irq);
+ cached_irq_mask[0] &= mask;
+ outb(cached_irq_mask[0],0x21);
+ } else {
+ mask = ~(1 << (d->irq-8));
+ cached_irq_mask[1] &= mask;
+ outb(cached_irq_mask[1],0xA1);
+ }
+}
+
+static void shark_ack_8259A_irq(struct irq_data *d){}
+
+static irqreturn_t bogus_int(int irq, void *dev_id)
+{
+ printk("Got interrupt %i!\n",irq);
+ return IRQ_NONE;
+}
+
+static struct irqaction cascade;
+
+static struct irq_chip fb_chip = {
+ .name = "XT-PIC",
+ .irq_ack = shark_ack_8259A_irq,
+ .irq_mask = shark_disable_8259A_irq,
+ .irq_unmask = shark_enable_8259A_irq,
+};
+
+void __init shark_init_irq(void)
+{
+ int irq;
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ irq_set_chip_and_handler(irq, &fb_chip, handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* init master interrupt controller */
+ outb(0x11, 0x20); /* Start init sequence, edge triggered (level: 0x19)*/
+ outb(0x00, 0x21); /* Vector base */
+ outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */
+ outb(0x03, 0x21); /* Select 8086 mode , auto eoi*/
+ outb(0x0A, 0x20);
+ /* init slave interrupt controller */
+ outb(0x11, 0xA0); /* Start init sequence, edge triggered */
+ outb(0x08, 0xA1); /* Vector base */
+ outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */
+ outb(0x03, 0xA1); /* Select 8086 mode, auto eoi */
+ outb(0x0A, 0xA0);
+ outb(cached_irq_mask[1],0xA1);
+ outb(cached_irq_mask[0],0x21);
+ //request_region(0x20,0x2,"pic1");
+ //request_region(0xA0,0x2,"pic2");
+
+ cascade.handler = bogus_int;
+ cascade.name = "cascade";
+ setup_irq(2,&cascade);
+}
+
diff --git a/arch/arm/mach-shark/leds.c b/arch/arm/mach-shark/leds.c
new file mode 100644
index 00000000..c9e32de4
--- /dev/null
+++ b/arch/arm/mach-shark/leds.c
@@ -0,0 +1,166 @@
+/*
+ * arch/arm/mach-shark/leds.c
+ * by Alexander Schulz
+ *
+ * derived from:
+ * arch/arm/kernel/leds-footbridge.c
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * DIGITAL Shark LED control routines.
+ *
+ * The leds use is as follows:
+ * - Green front - toggles state every 50 timer interrupts
+ * - Amber front - Unused, this is a dual color led (Amber/Green)
+ * - Amber back - On if system is not idle
+ *
+ * Changelog:
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+
+#define SEQUOIA_LED_GREEN (1<<6)
+#define SEQUOIA_LED_AMBER (1<<5)
+#define SEQUOIA_LED_BACK (1<<7)
+
+static char led_state;
+static short hw_led_state;
+static short saved_state;
+
+static DEFINE_SPINLOCK(leds_lock);
+
+short sequoia_read(int addr) {
+ outw(addr,0x24);
+ return inw(0x26);
+}
+
+void sequoia_write(short value,short addr) {
+ outw(addr,0x24);
+ outw(value,0x26);
+}
+
+static void sequoia_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ hw_led_state = sequoia_read(0x09);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state |= SEQUOIA_LED_GREEN;
+ hw_led_state |= SEQUOIA_LED_AMBER;
+#ifdef CONFIG_LEDS_CPU
+ hw_led_state |= SEQUOIA_LED_BACK;
+#else
+ hw_led_state &= ~SEQUOIA_LED_BACK;
+#endif
+ led_state |= LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ hw_led_state &= ~SEQUOIA_LED_BACK;
+ hw_led_state |= SEQUOIA_LED_GREEN;
+ hw_led_state |= SEQUOIA_LED_AMBER;
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ saved_state = hw_led_state;
+ hw_led_state &= ~SEQUOIA_LED_BACK;
+ hw_led_state |= SEQUOIA_LED_GREEN;
+ hw_led_state |= SEQUOIA_LED_AMBER;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = saved_state;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= SEQUOIA_LED_GREEN;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~SEQUOIA_LED_BACK;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= SEQUOIA_LED_BACK;
+ break;
+#endif
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~SEQUOIA_LED_GREEN;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= SEQUOIA_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~SEQUOIA_LED_AMBER;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= SEQUOIA_LED_AMBER;
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= SEQUOIA_LED_BACK;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~SEQUOIA_LED_BACK;
+ break;
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED)
+ sequoia_write(hw_led_state,0x09);
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+}
+
+static int __init leds_init(void)
+{
+ extern void (*leds_event)(led_event_t);
+ short temp;
+
+ leds_event = sequoia_leds_event;
+
+ /* Make LEDs independent of power-state */
+ request_region(0x24,4,"sequoia");
+ temp = sequoia_read(0x09);
+ temp |= 1<<10;
+ sequoia_write(temp,0x09);
+ leds_event(led_start);
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
new file mode 100644
index 00000000..89d175ce
--- /dev/null
+++ b/arch/arm/mach-shark/pci.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-shark/pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->bus->number == 0)
+ if (dev->devfn == 0)
+ return 255;
+ else
+ return 11;
+ else
+ return 255;
+}
+
+extern void __init via82c505_preinit(void);
+
+static struct hw_pci shark_pci __initdata = {
+ .setup = via82c505_setup,
+ .swizzle = pci_std_swizzle,
+ .map_irq = shark_map_irq,
+ .nr_controllers = 1,
+ .scan = via82c505_scan_bus,
+ .preinit = via82c505_preinit,
+};
+
+static int __init shark_pci_init(void)
+{
+ if (machine_is_shark())
+ pci_common_init(&shark_pci);
+ return 0;
+}
+
+subsys_initcall(shark_pci_init);
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
new file mode 100644
index 00000000..0c8f6cf3
--- /dev/null
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -0,0 +1,134 @@
+if ARCH_SHMOBILE
+
+comment "SH-Mobile System Type"
+
+config ARCH_SH7367
+ bool "SH-Mobile G3 (SH7367)"
+ select CPU_V6
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+config ARCH_SH7377
+ bool "SH-Mobile G4 (SH7377)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+config ARCH_SH7372
+ bool "SH-Mobile AP4 (SH7372)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+
+config ARCH_SH73A0
+ bool "SH-Mobile AG5 (R8A73A00)"
+ select CPU_V7
+ select SH_CLK_CPG
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_GIC
+
+comment "SH-Mobile Board Type"
+
+config MACH_G3EVM
+ bool "G3EVM board"
+ depends on ARCH_SH7367
+ select ARCH_REQUIRE_GPIOLIB
+
+config MACH_G4EVM
+ bool "G4EVM board"
+ depends on ARCH_SH7377
+ select ARCH_REQUIRE_GPIOLIB
+
+config MACH_AP4EVB
+ bool "AP4EVB board"
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
+ select SH_LCD_MIPI_DSI
+
+choice
+ prompt "AP4EVB LCD panel selection"
+ default AP4EVB_QHD
+ depends on MACH_AP4EVB
+
+config AP4EVB_QHD
+ bool "MIPI-DSI QHD (960x540)"
+
+config AP4EVB_WVGA
+ bool "Parallel WVGA (800x480)"
+
+endchoice
+
+config MACH_AG5EVM
+ bool "AG5EVM board"
+ select ARCH_REQUIRE_GPIOLIB
+ select SH_LCD_MIPI_DSI
+ depends on ARCH_SH73A0
+
+config MACH_MACKEREL
+ bool "mackerel board"
+ depends on ARCH_SH7372
+ select ARCH_REQUIRE_GPIOLIB
+
+comment "SH-Mobile System Configuration"
+
+menu "Memory configuration"
+
+config MEMORY_START
+ hex "Physical memory start address"
+ default "0x50000000" if MACH_G3EVM
+ default "0x40000000" if MACH_G4EVM || MACH_AP4EVB || MACH_AG5EVM || \
+ MACH_MACKEREL
+ default "0x00000000"
+ ---help---
+ Tweak this only when porting to a new machine which does not
+ already have a defconfig. Changing it from the known correct
+ value on any of the known systems will only lead to disaster.
+
+config MEMORY_SIZE
+ hex "Physical memory size"
+ default "0x08000000" if MACH_G3EVM
+ default "0x08000000" if MACH_G4EVM
+ default "0x20000000" if MACH_AG5EVM
+ default "0x10000000" if MACH_AP4EVB || MACH_MACKEREL
+ default "0x04000000"
+ help
+ This sets the default memory size assumed by your kernel. It can
+ be overridden as normal by the 'mem=' argument on the kernel command
+ line.
+
+endmenu
+
+menu "Timer and clock configuration"
+
+config SHMOBILE_TIMER_HZ
+ int "Kernel HZ (jiffies per second)"
+ range 32 1024
+ default "128"
+ help
+ Allows the configuration of the timer frequency. It is customary
+ to have the timer interrupt run at 1000 Hz or 100 Hz, but in the
+ case of low timer frequencies other values may be more suitable.
+ SH-Mobile systems using a 32768 Hz RCLK for clock events may want
+ to select a HZ value such as 128 that can evenly divide RCLK.
+ A HZ value that does not divide evenly may cause timer drift.
+
+config SH_TIMER_CMT
+ bool "CMT timer driver"
+ default y
+ help
+ This enables build of the CMT timer driver.
+
+config SH_TIMER_TMU
+ bool "TMU timer driver"
+ default y
+ help
+ This enables build of the TMU timer driver.
+
+endmenu
+
+config SH_CLK_CPG
+ bool
+
+source "drivers/sh/Kconfig"
+
+endif
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
new file mode 100644
index 00000000..612b2700
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile
@@ -0,0 +1,47 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common objects
+obj-y := timer.o console.o clock.o pm_runtime.o
+
+# CPU objects
+obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
+obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
+obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
+obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
+
+# SMP objects
+smp-y := platsmp.o headsmp.o
+smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
+
+# Pinmux setup
+pfc-y :=
+pfc-$(CONFIG_ARCH_SH7367) += pfc-sh7367.o
+pfc-$(CONFIG_ARCH_SH7377) += pfc-sh7377.o
+pfc-$(CONFIG_ARCH_SH7372) += pfc-sh7372.o
+pfc-$(CONFIG_ARCH_SH73A0) += pfc-sh73a0.o
+
+# IRQ objects
+obj-$(CONFIG_ARCH_SH7367) += entry-intc.o
+obj-$(CONFIG_ARCH_SH7377) += entry-intc.o
+obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
+obj-$(CONFIG_ARCH_SH73A0) += entry-gic.o
+
+# PM objects
+obj-$(CONFIG_SUSPEND) += suspend.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
+
+# Board objects
+obj-$(CONFIG_MACH_G3EVM) += board-g3evm.o
+obj-$(CONFIG_MACH_G4EVM) += board-g4evm.o
+obj-$(CONFIG_MACH_AP4EVB) += board-ap4evb.o
+obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o
+obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
+
+# Framework support
+obj-$(CONFIG_SMP) += $(smp-y)
+obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y)
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
new file mode 100644
index 00000000..1c08ee9d
--- /dev/null
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -0,0 +1,9 @@
+__ZRELADDR := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_MEMORY_START) + 0x8000]')
+
+ zreladdr-y := $(__ZRELADDR)
+
+# Unsupported legacy stuff
+#
+#params_phys-y (Instead: Pass atags pointer in r2)
+#initrd_phys-y (Instead: Use compiled-in initramfs)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
new file mode 100644
index 00000000..ce5c2513
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -0,0 +1,598 @@
+/*
+ * arch/arm/mach-shmobile/board-ag5evm.c
+ *
+ * Copyright (C) 2010 Takashi Yoshii <yoshii.takashi.zj@renesas.com>
+ * Copyright (C) 2009 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_sci.h>
+#include <linux/smsc911x.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mfd/tmio.h>
+#include <linux/sh_clk.h>
+#include <video/sh_mobile_lcdc.h>
+#include <video/sh_mipi_dsi.h>
+#include <sound/sh_fsi.h>
+#include <mach/hardware.h>
+#include <mach/sh73a0.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/traps.h>
+
+static struct resource smsc9220_resources[] = {
+ [0] = {
+ .start = 0x14000000,
+ .end = 0x14000000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(33), /* PINT1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc9220_platdata = {
+ .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc9220_platdata,
+ },
+ .resource = smsc9220_resources,
+ .num_resources = ARRAY_SIZE(smsc9220_resources),
+};
+
+static struct sh_keysc_info keysc_platdata = {
+ .mode = SH_KEYSC_MODE_6,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
+ KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
+ KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+ KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
+ KEY_SPACE, KEY_9, KEY_6, KEY_3, KEY_WAKEUP, KEY_RIGHT, \
+ KEY_COFFEE,
+ KEY_0, KEY_8, KEY_5, KEY_2, KEY_DOWN, KEY_ENTER, KEY_UP,
+ KEY_KPASTERISK, KEY_7, KEY_4, KEY_1, KEY_STOP, KEY_LEFT, \
+ KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b0098 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(71),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_platdata,
+ },
+};
+
+/* FSI A */
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xEC230000,
+ .end = 0xEC230400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(146),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+};
+
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xe6bd0000,
+ .end = 0xe6bd00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(141),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(140),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_dma sh_mmcif_dma = {
+ .chan_priv_rx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ },
+ .chan_priv_tx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ },
+};
+static struct sh_mmcif_plat_data sh_mmcif_platdata = {
+ .sup_pclk = 0,
+ .ocr = MMC_VDD_165_195,
+ .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+ .dma = &sh_mmcif_dma,
+};
+
+static struct platform_device mmc_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_platdata,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+/* IrDA */
+static struct resource irda_resources[] = {
+ [0] = {
+ .start = 0xE6D00000,
+ .end = 0xE6D01FD4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(95),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_irda",
+ .id = 0,
+ .resource = irda_resources,
+ .num_resources = ARRAY_SIZE(irda_resources),
+};
+
+static unsigned char lcd_backlight_seq[3][2] = {
+ { 0x04, 0x07 },
+ { 0x23, 0x80 },
+ { 0x03, 0x01 },
+};
+
+static void lcd_backlight_on(void)
+{
+ struct i2c_adapter *a;
+ struct i2c_msg msg;
+ int k;
+
+ a = i2c_get_adapter(1);
+ for (k = 0; a && k < 3; k++) {
+ msg.addr = 0x6d;
+ msg.buf = &lcd_backlight_seq[k][0];
+ msg.len = 2;
+ msg.flags = 0;
+ if (i2c_transfer(a, &msg, 1) != 1)
+ break;
+ }
+}
+
+static void lcd_backlight_reset(void)
+{
+ gpio_set_value(GPIO_PORT235, 0);
+ mdelay(24);
+ gpio_set_value(GPIO_PORT235, 1);
+}
+
+static void lcd_on(void *board_data, struct fb_info *info)
+{
+ lcd_backlight_on();
+}
+
+static void lcd_off(void *board_data)
+{
+ lcd_backlight_reset();
+}
+
+/* LCDC0 */
+static const struct fb_videomode lcdc0_modes[] = {
+ {
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc0_info = {
+ .clock_source = LCDC_CLK_PERIPHERAL,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .lcd_size_cfg.width = 44,
+ .lcd_size_cfg.height = 79,
+ .bpp = 16,
+ .lcd_cfg = lcdc0_modes,
+ .num_cfg = ARRAY_SIZE(lcdc0_modes),
+ .board_cfg = {
+ .display_on = lcd_on,
+ .display_off = lcd_off,
+ },
+ }
+};
+
+static struct resource lcdc0_resources[] = {
+ [0] = {
+ .name = "LCDC0",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc0_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc0_resources),
+ .resource = lcdc0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &lcdc0_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/* MIPI-DSI */
+static struct resource mipidsi0_resources[] = {
+ [0] = {
+ .name = "DSI0",
+ .start = 0xfeab0000,
+ .end = 0xfeab3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "DSI0",
+ .start = 0xfeab4000,
+ .end = 0xfeab7fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct sh_mipi_dsi_info mipidsi0_info = {
+ .data_format = MIPI_RGB888,
+ .lcd_chan = &lcdc0_info.ch[0],
+ .vsynw_offset = 20,
+ .clksrc = 1,
+ .flags = SH_MIPI_DSI_HSABM,
+};
+
+static struct platform_device mipidsi0_device = {
+ .name = "sh-mipi-dsi",
+ .num_resources = ARRAY_SIZE(mipidsi0_resources),
+ .resource = mipidsi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &mipidsi0_info,
+ },
+};
+
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED,
+ .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xee100000,
+ .end = 0xee1000ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(83),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(84),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = gic_spi(85),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+ gpio_set_value(GPIO_PORT114, state);
+}
+
+static struct sh_mobile_sdhi_info sh_sdhi1_info = {
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
+ .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .set_pwr = ag5evm_sdhi1_set_pwr,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xee120000,
+ .end = 0xee1200ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(87),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = gic_spi(88),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = gic_spi(89),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 1,
+ .dev = {
+ .platform_data = &sh_sdhi1_info,
+ },
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+};
+
+static struct platform_device *ag5evm_devices[] __initdata = {
+ &eth_device,
+ &keysc_device,
+ &fsi_device,
+ &mmc_device,
+ &irda_device,
+ &lcdc0_device,
+ &mipidsi0_device,
+ &sdhi0_device,
+ &sdhi1_device,
+};
+
+static struct map_desc ag5evm_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init ag5evm_map_io(void)
+{
+ iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
+
+ /* setup early devices and console here as well */
+ sh73a0_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define PINTC_ADDR 0xe6900000
+#define PINTER0A (PINTC_ADDR + 0xa0)
+#define PINTCR0A (PINTC_ADDR + 0xb0)
+
+void __init ag5evm_init_irq(void)
+{
+ sh73a0_init_irq();
+
+ /* setup PINT: enable PINTA2 as active low */
+ __raw_writel(__raw_readl(PINTER0A) | (1<<29), PINTER0A);
+ __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
+}
+
+#define DSI0PHYCR 0xe615006c
+
+static void __init ag5evm_init(void)
+{
+ sh73a0_pinmux_init();
+
+ /* enable SCIFA2 */
+ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RTS1_, NULL);
+ gpio_request(GPIO_FN_SCIFA2_CTS1_, NULL);
+
+ /* enable KEYSC */
+ gpio_request(GPIO_FN_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN6_PU, NULL);
+ gpio_request(GPIO_FN_KEYIN7_PU, NULL);
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT59_KEYOUT6, NULL);
+ gpio_request(GPIO_FN_PORT58_KEYOUT7, NULL);
+ gpio_request(GPIO_FN_KEYOUT8, NULL);
+ gpio_request(GPIO_FN_PORT149_KEYOUT9, NULL);
+
+ /* enable I2C channel 2 and 3 */
+ gpio_request(GPIO_FN_PORT236_I2C_SDA2, NULL);
+ gpio_request(GPIO_FN_PORT237_I2C_SCL2, NULL);
+ gpio_request(GPIO_FN_PORT248_I2C_SCL3, NULL);
+ gpio_request(GPIO_FN_PORT249_I2C_SDA3, NULL);
+
+ /* enable MMCIF */
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+ gpio_request(GPIO_FN_MMCCMD0_PU, NULL);
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_PORT208, NULL); /* Reset */
+ gpio_direction_output(GPIO_PORT208, 1);
+
+ /* enable SMSC911X */
+ gpio_request(GPIO_PORT144, NULL); /* PINTA2 */
+ gpio_direction_input(GPIO_PORT144);
+ gpio_request(GPIO_PORT145, NULL); /* RESET */
+ gpio_direction_output(GPIO_PORT145, 1);
+
+ /* FSI A */
+ gpio_request(GPIO_FN_FSIACK, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+
+ /* IrDA */
+ gpio_request(GPIO_FN_PORT241_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_PORT242_IRDA_IN, NULL);
+ gpio_request(GPIO_FN_PORT243_IRDA_FIRSEL, NULL);
+
+ /* LCD panel */
+ gpio_request(GPIO_PORT217, NULL); /* RESET */
+ gpio_direction_output(GPIO_PORT217, 0);
+ mdelay(1);
+ gpio_set_value(GPIO_PORT217, 1);
+ mdelay(100);
+
+ /* LCD backlight controller */
+ gpio_request(GPIO_PORT235, NULL); /* RESET */
+ gpio_direction_output(GPIO_PORT235, 0);
+ lcd_backlight_reset();
+
+ /* MIPI-DSI clock setup */
+ __raw_writel(0x2a809010, DSI0PHYCR);
+
+ /* enable SDHI0 on CN15 [SD I/F] */
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+
+ /* enable SDHI1 on CN4 [WLAN I/F] */
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
+ gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
+ gpio_request(GPIO_PORT114, "sdhi1_power");
+ gpio_direction_output(GPIO_PORT114, 0);
+
+#ifdef CONFIG_CACHE_L2X0
+ /* Shared attribute override enable, 64K*8way */
+ l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
+#endif
+ sh73a0_add_standard_devices();
+ platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
+}
+
+static void __init ag5evm_timer_init(void)
+{
+ sh73a0_clock_init();
+ shmobile_timer.init();
+ return;
+}
+
+struct sys_timer ag5evm_timer = {
+ .init = ag5evm_timer_init,
+};
+
+MACHINE_START(AG5EVM, "ag5evm")
+ .map_io = ag5evm_map_io,
+ .init_irq = ag5evm_init_irq,
+ .handle_irq = shmobile_handle_irq_gic,
+ .init_machine = ag5evm_init,
+ .timer = &ag5evm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
new file mode 100644
index 00000000..803bc6ed
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -0,0 +1,1435 @@
+/*
+ * AP4EVB board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/io.h>
+#include <linux/smsc911x.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_clk.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/usb/r8a66597.h>
+
+#include <media/sh_mobile_ceu.h>
+#include <media/sh_mobile_csi2.h>
+#include <media/soc_camera.h>
+
+#include <sound/sh_fsi.h>
+
+#include <video/sh_mobile_hdmi.h>
+#include <video/sh_mobile_lcdc.h>
+#include <video/sh_mipi_dsi.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/sh7372.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+/*
+ * Address Interface BusWidth note
+ * ------------------------------------------------------------------
+ * 0x0000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = ON
+ * 0x0800_0000 user area -
+ * 0x1000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = OFF
+ * 0x1400_0000 Ether (LAN9220) 16bit
+ * 0x1600_0000 user area - cannot use with NAND
+ * 0x1800_0000 user area -
+ * 0x1A00_0000 -
+ * 0x4000_0000 LPDDR2-SDRAM (POP) 32bit
+ */
+
+/*
+ * NOR Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NOR Flash ROM
+ * bit1 | bit1 bit2 | bit1 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | Area 0
+ * OFF | ON OFF | OFF | Area 4
+ */
+
+/*
+ * NAND Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NAND Flash ROM
+ * bit1 | bit1 bit2 | bit2 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | FCE 0
+ * OFF | ON OFF | OFF | FCE 1
+ */
+
+/*
+ * SMSC 9220
+ *
+ * SW1 SMSC 9220
+ * -----------------------
+ * ON access disable
+ * OFF access enable
+ */
+
+/*
+ * LCD / IRQ / KEYSC / IrDA
+ *
+ * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (QHD-TouchScreen)
+ * LCD = 2nd LCDC (WVGA)
+ *
+ * | SW43 |
+ * SW3 | ON | OFF |
+ * -------------+-----------------------+---------------+
+ * ON | KEY / IrDA | LCD |
+ * OFF | KEY / IrDA / IRQ | IRQ |
+ *
+ *
+ * QHD / WVGA display
+ *
+ * You can choice display type on menuconfig.
+ * Then, check above dip-switch.
+ */
+
+/*
+ * USB
+ *
+ * J7 : 1-2 MAX3355E VBUS
+ * 2-3 DC 5.0V
+ *
+ * S39: bit2: off
+ */
+
+/*
+ * FSI/FSMI
+ *
+ * SW41 : ON : SH-Mobile AP4 Audio Mode
+ * : OFF : Bluetooth Audio Mode
+ */
+
+/*
+ * MMC0/SDHI1 (CN7)
+ *
+ * J22 : select card voltage
+ * 1-2 pin : 1.8v
+ * 2-3 pin : 3.3v
+ *
+ * SW1 | SW33
+ * | bit1 | bit2 | bit3 | bit4
+ * ------------+------+------+------+-------
+ * MMC0 OFF | OFF | ON | ON | X
+ * SDHI1 OFF | ON | X | OFF | ON
+ *
+ * voltage lebel
+ * CN7 : 1.8v
+ * CN12: 3.3v
+ */
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* SMSC 9220 */
+static struct resource smc911x_resources[] = {
+ {
+ .start = 0x14000000,
+ .end = 0x16000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x02c0) /* IRQ6A */,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc911x_resources),
+ .resource = smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/*
+ * The card detect pin of the top SD/MMC slot (CN7) is active low and is
+ * connected to GPIO A22 of SH7372 (GPIO_PORT41).
+ */
+static int slot_cn7_get_cd(struct platform_device *pdev)
+{
+ return !gpio_get_value(GPIO_PORT41);
+}
+/* MERAM */
+static struct sh_mobile_meram_info meram_info = {
+ .addr_mode = SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+ [0] = {
+ .name = "MERAM",
+ .start = 0xe8000000,
+ .end = 0xe81fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device meram_device = {
+ .name = "sh_mobile_meram",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(meram_resources),
+ .resource = meram_resources,
+ .dev = {
+ .platform_data = &meram_info,
+ },
+};
+
+/* SH_MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xE6BD0000,
+ .end = 0xE6BD00FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* MMC ERR */
+ .start = evt2irq(0x1ac0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* MMC NOR */
+ .start = evt2irq(0x1ae0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_dma sh_mmcif_dma = {
+ .chan_priv_rx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ },
+ .chan_priv_tx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0,
+ .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn7_get_cd,
+ .dma = &sh_mmcif_dma,
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+/* SDHI0 */
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+ .tmio_caps = MMC_CAP_SDIO_IRQ,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xe6850000,
+ .end = 0xe68500ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+/* SDHI1 */
+static struct sh_mobile_sdhi_info sdhi1_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
+ .tmio_ocr_mask = MMC_VDD_165_195,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ,
+ .get_cd = slot_cn7_get_cd,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6860000,
+ .end = 0xe68600ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+
+/* USB1 */
+static void usb1_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
+ __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+ .on_chip = 1,
+ .port_power = usb1_host_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xE68B0000,
+ .end = 0xE68B00E6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb1_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb1_host_data,
+ },
+ .num_resources = ARRAY_SIZE(usb1_host_resources),
+ .resource = usb1_host_resources,
+};
+
+const static struct fb_videomode ap4evb_lcdc_modes[] = {
+ {
+#ifdef CONFIG_AP4EVB_QHD
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+#endif
+ },
+};
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 28,
+ .cache_icb = 24,
+ .meram_offset = 0x0,
+ .meram_size = 0x40,
+ },
+ .icb[1] = {
+ .marker_icb = 29,
+ .cache_icb = 25,
+ .meram_offset = 0x40,
+ .meram_size = 0x40,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .meram_dev = &meram_info,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .lcd_cfg = ap4evb_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
+ .meram_cfg = &lcd_meram_cfg,
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/*
+ * QHD display
+ */
+#ifdef CONFIG_AP4EVB_QHD
+
+/* KEYSC (Needs SW43 set to ON) */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_1,
+ .scan_timing = 3,
+ .delay = 2500,
+ .keycodes = {
+ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9,
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
+ KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+ KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b0063,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0be0), /* KEYSC_KEY */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* "keysc0" clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+/* MIPI-DSI */
+static struct resource mipidsi0_resources[] = {
+ [0] = {
+ .start = 0xffc60000,
+ .end = 0xffc63073,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffc68000,
+ .end = 0xffc680ef,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct sh_mipi_dsi_info mipidsi0_info = {
+ .data_format = MIPI_RGB888,
+ .lcd_chan = &lcdc_info.ch[0],
+ .vsynw_offset = 17,
+};
+
+static struct platform_device mipidsi0_device = {
+ .name = "sh-mipi-dsi",
+ .num_resources = ARRAY_SIZE(mipidsi0_resources),
+ .resource = mipidsi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &mipidsi0_info,
+ },
+};
+
+static struct platform_device *qhd_devices[] __initdata = {
+ &mipidsi0_device,
+ &keysc_device,
+};
+#endif /* CONFIG_AP4EVB_QHD */
+
+/* FSI */
+#define IRQ_FSI evt2irq(0x1840)
+static int __fsi_set_rate(struct clk *clk, long rate, int enable)
+{
+ int ret = 0;
+
+ if (rate <= 0)
+ return ret;
+
+ if (enable) {
+ ret = clk_set_rate(clk, rate);
+ if (0 == ret)
+ ret = clk_enable(clk);
+ } else {
+ clk_disable(clk);
+ }
+
+ return ret;
+}
+
+static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
+{
+ return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
+}
+
+static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
+{
+ struct clk *fsia_ick;
+ struct clk *fsiack;
+ int ret = -EIO;
+
+ fsia_ick = clk_get(dev, "icka");
+ if (IS_ERR(fsia_ick))
+ return PTR_ERR(fsia_ick);
+
+ /*
+ * FSIACK is connected to AK4642,
+ * and use external clock pin from it.
+ * it is parent of fsia_ick now.
+ */
+ fsiack = clk_get_parent(fsia_ick);
+ if (!fsiack)
+ goto fsia_ick_out;
+
+ /*
+ * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
+ *
+ ** FIXME **
+ * Because the freq_table of external clk (fsiack) are all 0,
+ * the return value of clk_round_rate became 0.
+ * So, it use __fsi_set_rate here.
+ */
+ ret = __fsi_set_rate(fsiack, rate, enable);
+ if (ret < 0)
+ goto fsiack_out;
+
+ ret = __fsi_set_round_rate(fsia_ick, rate, enable);
+ if ((ret < 0) && enable)
+ __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
+
+fsiack_out:
+ clk_put(fsiack);
+
+fsia_ick_out:
+ clk_put(fsia_ick);
+
+ return 0;
+}
+
+static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
+{
+ struct clk *fsib_clk;
+ struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+ long fsib_rate = 0;
+ long fdiv_rate = 0;
+ int ackmd_bpfmd;
+ int ret;
+
+ switch (rate) {
+ case 44100:
+ fsib_rate = rate * 256;
+ ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+ break;
+ case 48000:
+ fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
+ fdiv_rate = rate * 256;
+ ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+ break;
+ default:
+ pr_err("unsupported rate in FSI2 port B\n");
+ return -EINVAL;
+ }
+
+ /* FSI B setting */
+ fsib_clk = clk_get(dev, "ickb");
+ if (IS_ERR(fsib_clk))
+ return -EIO;
+
+ ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
+ if (ret < 0)
+ goto fsi_set_rate_end;
+
+ /* FSI DIV setting */
+ ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
+ if (ret < 0) {
+ /* disable FSI B */
+ if (enable)
+ __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
+ goto fsi_set_rate_end;
+ }
+
+ ret = ackmd_bpfmd;
+
+fsi_set_rate_end:
+ clk_put(fsib_clk);
+ return ret;
+}
+
+static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+{
+ int ret;
+
+ if (is_porta)
+ ret = fsi_ak4642_set_rate(dev, rate, enable);
+ else
+ ret = fsi_hdmi_set_rate(dev, rate, enable);
+
+ return ret;
+}
+
+static struct sh_fsi_platform_info fsi_info = {
+ .porta_flags = SH_FSI_BRS_INV,
+
+ .portb_flags = SH_FSI_BRS_INV |
+ SH_FSI_BRM_INV |
+ SH_FSI_LRS_INV |
+ SH_FSI_FMT_SPDIF,
+ .set_rate = fsi_set_rate,
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C0400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct platform_device fsi_ak4643_device = {
+ .name = "sh_fsi2_a_ak4643",
+};
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 30,
+ .cache_icb = 26,
+ .meram_offset = 0x80,
+ .meram_size = 0x100,
+ },
+ .icb[1] = {
+ .marker_icb = 31,
+ .cache_icb = 27,
+ .meram_offset = 0x180,
+ .meram_size = 0x100,
+ },
+};
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
+ .clock_source = LCDC_CLK_EXTERNAL,
+ .meram_dev = &meram_info,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .meram_cfg = &hdmi_meram_cfg,
+ }
+};
+
+static struct resource lcdc1_resources[] = {
+ [0] = {
+ .name = "LCDC1",
+ .start = 0xfe944000,
+ .end = 0xfe947fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x1780),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc1_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc1_resources),
+ .resource = lcdc1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sh_mobile_lcdc1_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq);
+
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
+ .lcd_dev = &lcdc1_device.dev,
+ .flags = HDMI_SND_SRC_SPDIF,
+ .clk_optimize_parent = ap4evb_clk_optimize,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
+static struct platform_device fsi_hdmi_device = {
+ .name = "sh_fsi2_b_hdmi",
+};
+
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq)
+{
+ struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+ long error;
+
+ if (IS_ERR(hdmi_ick)) {
+ int ret = PTR_ERR(hdmi_ick);
+ pr_err("Cannot get HDMI ICK: %d\n", ret);
+ return ret;
+ }
+
+ error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
+
+ clk_put(hdmi_ick);
+
+ return error;
+}
+
+static struct gpio_led ap4evb_leds[] = {
+ {
+ .name = "led4",
+ .gpio = GPIO_PORT185,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led2",
+ .gpio = GPIO_PORT186,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led3",
+ .gpio = GPIO_PORT187,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led1",
+ .gpio = GPIO_PORT188,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data ap4evb_leds_pdata = {
+ .num_leds = ARRAY_SIZE(ap4evb_leds),
+ .leds = ap4evb_leds,
+};
+
+static struct platform_device leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &ap4evb_leds_pdata,
+ },
+};
+
+static struct i2c_board_info imx074_info = {
+ I2C_BOARD_INFO("imx074", 0x1a),
+};
+
+static struct soc_camera_link imx074_link = {
+ .bus_id = 0,
+ .board_info = &imx074_info,
+ .i2c_adapter_id = 0,
+ .module_name = "imx074",
+};
+
+static struct platform_device ap4evb_camera = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &imx074_link,
+ },
+};
+
+static struct sh_csi2_client_config csi2_clients[] = {
+ {
+ .phy = SH_CSI2_PHY_MAIN,
+ .lanes = 3,
+ .channel = 0,
+ .pdev = &ap4evb_camera,
+ },
+};
+
+static struct sh_csi2_pdata csi2_info = {
+ .type = SH_CSI2C,
+ .clients = csi2_clients,
+ .num_clients = ARRAY_SIZE(csi2_clients),
+ .flags = SH_CSI2_ECC | SH_CSI2_CRC,
+};
+
+static struct resource csi2_resources[] = {
+ [0] = {
+ .name = "CSI2",
+ .start = 0xffc90000,
+ .end = 0xffc90fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x17a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device csi2_device = {
+ .name = "sh-mobile-csi2",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(csi2_resources),
+ .resource = csi2_resources,
+ .dev = {
+ .platform_data = &csi2_info,
+ },
+};
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
+ .csi2_dev = &csi2_device.dev,
+};
+
+static struct resource ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device ceu_device = {
+ .name = "sh_mobile_ceu",
+ .id = 0, /* "ceu0" clock */
+ .num_resources = ARRAY_SIZE(ceu_resources),
+ .resource = ceu_resources,
+ .dev = {
+ .platform_data = &sh_mobile_ceu_info,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device *ap4evb_devices[] __initdata = {
+ &leds_device,
+ &nor_flash_device,
+ &smc911x_device,
+ &sdhi0_device,
+ &sdhi1_device,
+ &usb1_host_device,
+ &fsi_device,
+ &fsi_ak4643_device,
+ &fsi_hdmi_device,
+ &sh_mmcif_device,
+ &lcdc1_device,
+ &lcdc_device,
+ &hdmi_device,
+ &csi2_device,
+ &ceu_device,
+ &ap4evb_camera,
+ &meram_device,
+};
+
+static void __init hdmi_init_pm_clock(void)
+{
+ struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+ int ret;
+ long rate;
+
+ if (IS_ERR(hdmi_ick)) {
+ ret = PTR_ERR(hdmi_ick);
+ pr_err("Cannot get HDMI ICK: %d\n", ret);
+ goto out;
+ }
+
+ ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
+ if (ret < 0) {
+ pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, sh7372_pllc2_clk.usecount);
+ goto out;
+ }
+
+ pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&sh7372_pllc2_clk));
+
+ rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
+ if (rate < 0) {
+ pr_err("Cannot get suitable rate: %ld\n", rate);
+ ret = rate;
+ goto out;
+ }
+
+ ret = clk_set_rate(&sh7372_pllc2_clk, rate);
+ if (ret < 0) {
+ pr_err("Cannot set rate %ld: %d\n", rate, ret);
+ goto out;
+ }
+
+ pr_debug("PLLC2 set frequency %lu\n", rate);
+
+ ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
+ if (ret < 0)
+ pr_err("Cannot set HDMI parent: %d\n", ret);
+
+out:
+ if (!IS_ERR(hdmi_ick))
+ clk_put(hdmi_ick);
+}
+
+static void __init fsi_init_pm_clock(void)
+{
+ struct clk *fsia_ick;
+ int ret;
+
+ fsia_ick = clk_get(&fsi_device.dev, "icka");
+ if (IS_ERR(fsia_ick)) {
+ ret = PTR_ERR(fsia_ick);
+ pr_err("Cannot get FSI ICK: %d\n", ret);
+ return;
+ }
+
+ ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
+ if (ret < 0)
+ pr_err("Cannot set FSI-A parent: %d\n", ret);
+
+ clk_put(fsia_ick);
+}
+
+/*
+ * FIXME !!
+ *
+ * gpio_no_direction
+ * are quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_no_direction(u32 addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+/* TouchScreen */
+#ifdef CONFIG_AP4EVB_QHD
+# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
+# define GPIO_TSC_PORT GPIO_PORT123
+#else /* WVGA */
+# define GPIO_TSC_IRQ GPIO_FN_IRQ7_40
+# define GPIO_TSC_PORT GPIO_PORT40
+#endif
+
+#define IRQ28 evt2irq(0x3380) /* IRQ28A */
+#define IRQ7 evt2irq(0x02e0) /* IRQ7A */
+static int ts_get_pendown_state(void)
+{
+ int val;
+
+ gpio_free(GPIO_TSC_IRQ);
+
+ gpio_request(GPIO_TSC_PORT, NULL);
+
+ gpio_direction_input(GPIO_TSC_PORT);
+
+ val = gpio_get_value(GPIO_TSC_PORT);
+
+ gpio_request(GPIO_TSC_IRQ, NULL);
+
+ return !val;
+}
+
+static int ts_init(void)
+{
+ gpio_request(GPIO_TSC_IRQ, NULL);
+
+ return 0;
+}
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = ts_get_pendown_state,
+ .init_platform_hw = ts_init,
+};
+
+static struct i2c_board_info tsc_device = {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ /*.irq is selected on ap4evb_init */
+};
+
+/* I2C */
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4643", 0x13),
+ },
+};
+
+static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+};
+
+static struct map_desc ap4evb_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init ap4evb_map_io(void)
+{
+ iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
+
+ /* setup early devices and console here as well */
+ sh7372_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define GPIO_PORT9CR 0xE6051009
+#define GPIO_PORT10CR 0xE605100A
+#define USCCR1 0xE6058144
+static void __init ap4evb_init(void)
+{
+ u32 srcr4;
+ struct clk *clk;
+
+ sh7372_pinmux_init();
+
+ /* enable SCIFA0 */
+ gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
+
+ /* enable SMSC911X */
+ gpio_request(GPIO_FN_CS5A, NULL);
+ gpio_request(GPIO_FN_IRQ6_39, NULL);
+
+ /* enable Debug switch (S6) */
+ gpio_request(GPIO_PORT32, NULL);
+ gpio_request(GPIO_PORT33, NULL);
+ gpio_request(GPIO_PORT34, NULL);
+ gpio_request(GPIO_PORT35, NULL);
+ gpio_direction_input(GPIO_PORT32);
+ gpio_direction_input(GPIO_PORT33);
+ gpio_direction_input(GPIO_PORT34);
+ gpio_direction_input(GPIO_PORT35);
+ gpio_export(GPIO_PORT32, 0);
+ gpio_export(GPIO_PORT33, 0);
+ gpio_export(GPIO_PORT34, 0);
+ gpio_export(GPIO_PORT35, 0);
+
+ /* SDHI0 */
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+
+ /* SDHI1 */
+ gpio_request(GPIO_FN_SDHICMD1, NULL);
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHID1_3, NULL);
+ gpio_request(GPIO_FN_SDHID1_2, NULL);
+ gpio_request(GPIO_FN_SDHID1_1, NULL);
+ gpio_request(GPIO_FN_SDHID1_0, NULL);
+
+ /* MMCIF */
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_FN_MMCCMD0, NULL);
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+
+ /* USB enable */
+ gpio_request(GPIO_FN_VBUS0_1, NULL);
+ gpio_request(GPIO_FN_IDIN_1_18, NULL);
+ gpio_request(GPIO_FN_PWEN_1_115, NULL);
+ gpio_request(GPIO_FN_OVCN_1_114, NULL);
+ gpio_request(GPIO_FN_EXTLP_1, NULL);
+ gpio_request(GPIO_FN_OVCN2_1, NULL);
+
+ /* setup USB phy */
+ __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
+
+ /* enable FSI2 port A (ak4643) */
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+ gpio_request(GPIO_PORT161, NULL);
+ gpio_direction_output(GPIO_PORT161, 0); /* slave */
+
+ gpio_request(GPIO_PORT9, NULL);
+ gpio_request(GPIO_PORT10, NULL);
+ gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+
+ /* card detect pin for MMC slot (CN7) */
+ gpio_request(GPIO_PORT41, NULL);
+ gpio_direction_input(GPIO_PORT41);
+
+ /* setup FSI2 port B (HDMI) */
+ gpio_request(GPIO_FN_FSIBCK, NULL);
+ __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
+
+ /* set SPU2 clock to 119.6 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 119600000));
+ clk_put(clk);
+ }
+
+ /*
+ * set irq priority, to avoid sound chopping
+ * when NFS rootfs is used
+ * FSI(3) > SMSC911X(2)
+ */
+ intc_set_priority(IRQ_FSI, 3);
+
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+
+ i2c_register_board_info(1, i2c1_devices,
+ ARRAY_SIZE(i2c1_devices));
+
+#ifdef CONFIG_AP4EVB_QHD
+
+ /*
+ * For QHD Panel (MIPI-DSI, CONFIG_AP4EVB_QHD=y) and
+ * IRQ28 for Touch Panel, set dip switches S3, S43 as OFF, ON.
+ */
+
+ /* enable KEYSC */
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_KEYIN0_136, NULL);
+ gpio_request(GPIO_FN_KEYIN1_135, NULL);
+ gpio_request(GPIO_FN_KEYIN2_134, NULL);
+ gpio_request(GPIO_FN_KEYIN3_133, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+
+ /* enable TouchScreen */
+ irq_set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
+
+ tsc_device.irq = IRQ28;
+ i2c_register_board_info(1, &tsc_device, 1);
+
+ /* LCDC0 */
+ lcdc_info.clock_source = LCDC_CLK_PERIPHERAL;
+ lcdc_info.ch[0].interface_type = RGB24;
+ lcdc_info.ch[0].clock_divider = 1;
+ lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
+ lcdc_info.ch[0].lcd_size_cfg.width = 44;
+ lcdc_info.ch[0].lcd_size_cfg.height = 79;
+
+ platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
+
+#else
+ /*
+ * For WVGA Panel (18-bit RGB, CONFIG_AP4EVB_WVGA=y) and
+ * IRQ7 for Touch Panel, set dip switches S3, S43 to ON, OFF.
+ */
+
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+
+ gpio_request(GPIO_PORT189, NULL); /* backlight */
+ gpio_direction_output(GPIO_PORT189, 1);
+
+ gpio_request(GPIO_PORT151, NULL); /* LCDDON */
+ gpio_direction_output(GPIO_PORT151, 1);
+
+ lcdc_info.clock_source = LCDC_CLK_BUS;
+ lcdc_info.ch[0].interface_type = RGB18;
+ lcdc_info.ch[0].clock_divider = 3;
+ lcdc_info.ch[0].flags = 0;
+ lcdc_info.ch[0].lcd_size_cfg.width = 152;
+ lcdc_info.ch[0].lcd_size_cfg.height = 91;
+
+ /* enable TouchScreen */
+ irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
+
+ tsc_device.irq = IRQ7;
+ i2c_register_board_info(0, &tsc_device, 1);
+#endif /* CONFIG_AP4EVB_QHD */
+
+ /* CEU */
+
+ /*
+ * TODO: reserve memory for V4L2 DMA buffers, when a suitable API
+ * becomes available
+ */
+
+ /* MIPI-CSI stuff */
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+
+ clk = clk_get(NULL, "vck1_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 13000000));
+ clk_enable(clk);
+ clk_put(clk);
+ }
+
+ sh7372_add_standard_devices();
+
+ /* HDMI */
+ gpio_request(GPIO_FN_HDMI_HPD, NULL);
+ gpio_request(GPIO_FN_HDMI_CEC, NULL);
+
+ /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
+#define SRCR4 0xe61580bc
+ srcr4 = __raw_readl(SRCR4);
+ __raw_writel(srcr4 | (1 << 13), SRCR4);
+ udelay(50);
+ __raw_writel(srcr4 & ~(1 << 13), SRCR4);
+
+ platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
+
+ hdmi_init_pm_clock();
+ fsi_init_pm_clock();
+ sh7372_pm_init();
+}
+
+static void __init ap4evb_timer_init(void)
+{
+ sh7372_clock_init();
+ shmobile_timer.init();
+
+ /* External clock source */
+ clk_set_rate(&sh7372_dv_clki_clk, 27000000);
+}
+
+static struct sys_timer ap4evb_timer = {
+ .init = ap4evb_timer_init,
+};
+
+MACHINE_START(AP4EVB, "ap4evb")
+ .map_io = ap4evb_map_io,
+ .init_irq = sh7372_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = ap4evb_init,
+ .timer = &ap4evb_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
new file mode 100644
index 00000000..ef4613b9
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -0,0 +1,372 @@
+/*
+ * G3EVM board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/sh_flctl.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <mach/sh7367.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+/*
+ * IrDA
+ *
+ * S67: 5bit : ON power
+ * : 6bit : ON remote control
+ * OFF IrDA
+ */
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* USBHS */
+static void usb_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+ __raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+ .on_chip = 1,
+ .port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xe6890000,
+ .end = 0xe68900e5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xa20), /* USBHS_USHI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb_host_data,
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(usb_host_resources),
+ .resource = usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_5,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G,
+ KEY_H, KEY_I, KEY_J, KEY_K, KEY_L, KEY_M, KEY_N,
+ KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U,
+ KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP,
+ KEY_WAKEUP, KEY_COFFEE, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4,
+ KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xbe0), /* KEYSC_KEY */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+static struct mtd_partition nand_partition_info[] = {
+ {
+ .name = "system",
+ .offset = 0,
+ .size = 64 * 1024 * 1024,
+ },
+ {
+ .name = "userdata",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 128 * 1024 * 1024,
+ },
+ {
+ .name = "cache",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 64 * 1024 * 1024,
+ },
+};
+
+static struct resource nand_flash_resources[] = {
+ [0] = {
+ .start = 0xe6a30000,
+ .end = 0xe6a3009b,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct sh_flctl_platform_data nand_flash_data = {
+ .parts = nand_partition_info,
+ .nr_parts = ARRAY_SIZE(nand_partition_info),
+ .flcmncr_val = QTSEL_E | FCKSEL_E | TYPESEL_SET | NANWF_E
+ | SHBUSSEL | SEL_16BIT,
+};
+
+static struct platform_device nand_flash_device = {
+ .name = "sh_flctl",
+ .resource = nand_flash_resources,
+ .num_resources = ARRAY_SIZE(nand_flash_resources),
+ .dev = {
+ .platform_data = &nand_flash_data,
+ },
+};
+
+static struct resource irda_resources[] = {
+ [0] = {
+ .start = 0xE6D00000,
+ .end = 0xE6D01FD4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x480), /* IRDA */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_irda",
+ .id = -1,
+ .resource = irda_resources,
+ .num_resources = ARRAY_SIZE(irda_resources),
+};
+
+static struct platform_device *g3evm_devices[] __initdata = {
+ &nor_flash_device,
+ &usb_host_device,
+ &keysc_device,
+ &nand_flash_device,
+ &irda_device,
+};
+
+static struct map_desc g3evm_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init g3evm_map_io(void)
+{
+ iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
+
+ /* setup early devices and console here as well */
+ sh7367_add_early_devices();
+ shmobile_setup_console();
+}
+
+static void __init g3evm_init(void)
+{
+ sh7367_pinmux_init();
+
+ /* Lit DS4 LED */
+ gpio_request(GPIO_PORT22, NULL);
+ gpio_direction_output(GPIO_PORT22, 1);
+ gpio_export(GPIO_PORT22, 0);
+
+ /* Lit DS8 LED */
+ gpio_request(GPIO_PORT23, NULL);
+ gpio_direction_output(GPIO_PORT23, 1);
+ gpio_export(GPIO_PORT23, 0);
+
+ /* Lit DS3 LED */
+ gpio_request(GPIO_PORT24, NULL);
+ gpio_direction_output(GPIO_PORT24, 1);
+ gpio_export(GPIO_PORT24, 0);
+
+ /* SCIFA1 */
+ gpio_request(GPIO_FN_SCIFA1_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
+ gpio_request(GPIO_FN_SCIFA1_CTS, NULL);
+ gpio_request(GPIO_FN_SCIFA1_RTS, NULL);
+
+ /* USBHS */
+ gpio_request(GPIO_FN_VBUS0, NULL);
+ gpio_request(GPIO_FN_PWEN, NULL);
+ gpio_request(GPIO_FN_OVCN, NULL);
+ gpio_request(GPIO_FN_OVCN2, NULL);
+ gpio_request(GPIO_FN_EXTLP, NULL);
+ gpio_request(GPIO_FN_IDIN, NULL);
+
+ /* setup USB phy */
+ __raw_writew(0x0300, 0xe605810a); /* USBCR1 */
+ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
+ __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */
+ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */
+
+ /* KEYSC @ CN7 */
+ gpio_request(GPIO_FN_PORT42_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_PORT43_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_PORT44_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_PORT45_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_PORT46_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_PORT47_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT48_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_PORT49_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_PORT50_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_PORT55_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_PORT56_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_PORT57_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_PORT58_KEYIN6_PU, NULL);
+
+ /* FLCTL */
+ gpio_request(GPIO_FN_FCE0, NULL);
+ gpio_request(GPIO_FN_D0_ED0_NAF0, NULL);
+ gpio_request(GPIO_FN_D1_ED1_NAF1, NULL);
+ gpio_request(GPIO_FN_D2_ED2_NAF2, NULL);
+ gpio_request(GPIO_FN_D3_ED3_NAF3, NULL);
+ gpio_request(GPIO_FN_D4_ED4_NAF4, NULL);
+ gpio_request(GPIO_FN_D5_ED5_NAF5, NULL);
+ gpio_request(GPIO_FN_D6_ED6_NAF6, NULL);
+ gpio_request(GPIO_FN_D7_ED7_NAF7, NULL);
+ gpio_request(GPIO_FN_D8_ED8_NAF8, NULL);
+ gpio_request(GPIO_FN_D9_ED9_NAF9, NULL);
+ gpio_request(GPIO_FN_D10_ED10_NAF10, NULL);
+ gpio_request(GPIO_FN_D11_ED11_NAF11, NULL);
+ gpio_request(GPIO_FN_D12_ED12_NAF12, NULL);
+ gpio_request(GPIO_FN_D13_ED13_NAF13, NULL);
+ gpio_request(GPIO_FN_D14_ED14_NAF14, NULL);
+ gpio_request(GPIO_FN_D15_ED15_NAF15, NULL);
+ gpio_request(GPIO_FN_WE0_XWR0_FWE, NULL);
+ gpio_request(GPIO_FN_FRB, NULL);
+ /* FOE, FCDE, FSC on dedicated pins */
+ __raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
+
+ /* IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+ gpio_request(GPIO_FN_IRDA_FIRSEL, NULL);
+
+ sh7367_add_standard_devices();
+
+ platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
+}
+
+static void __init g3evm_timer_init(void)
+{
+ sh7367_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer g3evm_timer = {
+ .init = g3evm_timer_init,
+};
+
+MACHINE_START(G3EVM, "g3evm")
+ .map_io = g3evm_map_io,
+ .init_irq = sh7367_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = g3evm_init,
+ .timer = &g3evm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
new file mode 100644
index 00000000..8e3c5559
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -0,0 +1,415 @@
+/*
+ * G4EVM board support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/io.h>
+#include <linux/input.h>
+#include <linux/input/sh_keysc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/gpio.h>
+#include <mach/sh7377.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+/*
+ * SDHI
+ *
+ * SDHI0 : card detection is possible
+ * SDHI1 : card detection is impossible
+ *
+ * [G4-MAIN-BOARD]
+ * JP74 : short # DBG_2V8A for SDHI0
+ * JP75 : NC # DBG_3V3A for SDHI0
+ * JP76 : NC # DBG_3V3A_SD for SDHI0
+ * JP77 : NC # 3V3A_SDIO for SDHI1
+ * JP78 : short # DBG_2V8A for SDHI1
+ * JP79 : NC # DBG_3V3A for SDHI1
+ * JP80 : NC # DBG_3V3A_SD for SDHI1
+ *
+ * [G4-CORE-BOARD]
+ * S32 : all off # to dissever from G3-CORE_DBG board
+ * S33 : all off # to dissever from G3-CORE_DBG board
+ *
+ * [G3-CORE_DBG-BOARD]
+ * S1 : all off # to dissever from G3-CORE_DBG board
+ * S3 : all off # to dissever from G3-CORE_DBG board
+ * S4 : all off # to dissever from G3-CORE_DBG board
+ */
+
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* USBHS */
+static void usb_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP0 in DVSTCTR */
+ __raw_writew(__raw_readw(0xe6890008) | 0x600, 0xe6890008);
+}
+
+static struct r8a66597_platdata usb_host_data = {
+ .on_chip = 1,
+ .port_power = usb_host_port_power,
+};
+
+static struct resource usb_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xe6890000,
+ .end = 0xe68900e5,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0a20), /* USBHS_USHI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &usb_host_data,
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(usb_host_resources),
+ .resource = usb_host_resources,
+};
+
+/* KEYSC */
+static struct sh_keysc_info keysc_info = {
+ .mode = SH_KEYSC_MODE_5,
+ .scan_timing = 3,
+ .delay = 100,
+ .keycodes = {
+ KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F,
+ KEY_G, KEY_H, KEY_I, KEY_J, KEY_K, KEY_L,
+ KEY_M, KEY_N, KEY_U, KEY_P, KEY_Q, KEY_R,
+ KEY_S, KEY_T, KEY_U, KEY_V, KEY_W, KEY_X,
+ KEY_Y, KEY_Z, KEY_HOME, KEY_SLEEP, KEY_WAKEUP, KEY_COFFEE,
+ KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5,
+ KEY_6, KEY_7, KEY_8, KEY_9, KEY_STOP, KEY_COMPUTER,
+ },
+};
+
+static struct resource keysc_resources[] = {
+ [0] = {
+ .name = "KEYSC",
+ .start = 0xe61b0000,
+ .end = 0xe61b000f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0be0), /* KEYSC_KEY */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device keysc_device = {
+ .name = "sh_keysc",
+ .id = 0, /* keysc0 clock */
+ .num_resources = ARRAY_SIZE(keysc_resources),
+ .resource = keysc_resources,
+ .dev = {
+ .platform_data = &keysc_info,
+ },
+};
+
+/* SDHI */
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .tmio_caps = MMC_CAP_SDIO_IRQ,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xe6d50000,
+ .end = 0xe6d500ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e00), /* SDHI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+static struct sh_mobile_sdhi_info sdhi1_info = {
+ .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6d60000,
+ .end = 0xe6d600ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e80), /* SDHI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+
+static struct platform_device *g4evm_devices[] __initdata = {
+ &nor_flash_device,
+ &usb_host_device,
+ &keysc_device,
+ &sdhi0_device,
+ &sdhi1_device,
+};
+
+static struct map_desc g4evm_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init g4evm_map_io(void)
+{
+ iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
+
+ /* setup early devices and console here as well */
+ sh7377_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define GPIO_SDHID0_D0 0xe60520fc
+#define GPIO_SDHID0_D1 0xe60520fd
+#define GPIO_SDHID0_D2 0xe60520fe
+#define GPIO_SDHID0_D3 0xe60520ff
+#define GPIO_SDHICMD0 0xe6052100
+
+#define GPIO_SDHID1_D0 0xe6052103
+#define GPIO_SDHID1_D1 0xe6052104
+#define GPIO_SDHID1_D2 0xe6052105
+#define GPIO_SDHID1_D3 0xe6052106
+#define GPIO_SDHICMD1 0xe6052107
+
+/*
+ * FIXME !!
+ *
+ * gpio_pull_up is quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_pull_up(u32 addr)
+{
+ u8 data = __raw_readb(addr);
+
+ data &= 0x0F;
+ data |= 0xC0;
+ __raw_writeb(data, addr);
+}
+
+static void __init g4evm_init(void)
+{
+ sh7377_pinmux_init();
+
+ /* Lit DS14 LED */
+ gpio_request(GPIO_PORT109, NULL);
+ gpio_direction_output(GPIO_PORT109, 1);
+ gpio_export(GPIO_PORT109, 1);
+
+ /* Lit DS15 LED */
+ gpio_request(GPIO_PORT110, NULL);
+ gpio_direction_output(GPIO_PORT110, 1);
+ gpio_export(GPIO_PORT110, 1);
+
+ /* Lit DS16 LED */
+ gpio_request(GPIO_PORT112, NULL);
+ gpio_direction_output(GPIO_PORT112, 1);
+ gpio_export(GPIO_PORT112, 1);
+
+ /* Lit DS17 LED */
+ gpio_request(GPIO_PORT113, NULL);
+ gpio_direction_output(GPIO_PORT113, 1);
+ gpio_export(GPIO_PORT113, 1);
+
+ /* USBHS */
+ gpio_request(GPIO_FN_VBUS_0, NULL);
+ gpio_request(GPIO_FN_PWEN, NULL);
+ gpio_request(GPIO_FN_OVCN, NULL);
+ gpio_request(GPIO_FN_OVCN2, NULL);
+ gpio_request(GPIO_FN_EXTLP, NULL);
+ gpio_request(GPIO_FN_IDIN, NULL);
+
+ /* setup USB phy */
+ __raw_writew(0x0200, 0xe605810a); /* USBCR1 */
+ __raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
+ __raw_writew(0x6010, 0xe60581c6); /* CGPOSR */
+ __raw_writew(0x8a0a, 0xe605810c); /* USBCR2 */
+
+ /* KEYSC @ CN31 */
+ gpio_request(GPIO_FN_PORT60_KEYOUT5, NULL);
+ gpio_request(GPIO_FN_PORT61_KEYOUT4, NULL);
+ gpio_request(GPIO_FN_PORT62_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_PORT63_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_PORT64_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_PORT65_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_PORT66_KEYIN0_PU, NULL);
+ gpio_request(GPIO_FN_PORT67_KEYIN1_PU, NULL);
+ gpio_request(GPIO_FN_PORT68_KEYIN2_PU, NULL);
+ gpio_request(GPIO_FN_PORT69_KEYIN3_PU, NULL);
+ gpio_request(GPIO_FN_PORT70_KEYIN4_PU, NULL);
+ gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
+ gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
+
+ /* SDHI0 */
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_pull_up(GPIO_SDHID0_D0);
+ gpio_pull_up(GPIO_SDHID0_D1);
+ gpio_pull_up(GPIO_SDHID0_D2);
+ gpio_pull_up(GPIO_SDHID0_D3);
+ gpio_pull_up(GPIO_SDHICMD0);
+
+ /* SDHI1 */
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHID1_0, NULL);
+ gpio_request(GPIO_FN_SDHID1_1, NULL);
+ gpio_request(GPIO_FN_SDHID1_2, NULL);
+ gpio_request(GPIO_FN_SDHID1_3, NULL);
+ gpio_request(GPIO_FN_SDHICMD1, NULL);
+ gpio_pull_up(GPIO_SDHID1_D0);
+ gpio_pull_up(GPIO_SDHID1_D1);
+ gpio_pull_up(GPIO_SDHID1_D2);
+ gpio_pull_up(GPIO_SDHID1_D3);
+ gpio_pull_up(GPIO_SDHICMD1);
+
+ sh7377_add_standard_devices();
+
+ platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
+}
+
+static void __init g4evm_timer_init(void)
+{
+ sh7377_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer g4evm_timer = {
+ .init = g4evm_timer_init,
+};
+
+MACHINE_START(G4EVM, "g4evm")
+ .map_io = g4evm_map_io,
+ .init_irq = sh7377_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = g4evm_init,
+ .timer = &g4evm_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
new file mode 100644
index 00000000..3802f2af
--- /dev/null
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -0,0 +1,1608 @@
+/*
+ * mackerel board support
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on ap4evb
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/pm_runtime.h>
+#include <linux/smsc911x.h>
+#include <linux/sh_intc.h>
+#include <linux/tca6416_keypad.h>
+#include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
+
+#include <video/sh_mobile_hdmi.h>
+#include <video/sh_mobile_lcdc.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
+#include <media/soc_camera_platform.h>
+#include <sound/sh_fsi.h>
+
+#include <mach/common.h>
+#include <mach/sh7372.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+
+/*
+ * Address Interface BusWidth note
+ * ------------------------------------------------------------------
+ * 0x0000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = ON
+ * 0x0800_0000 user area -
+ * 0x1000_0000 NOR Flash ROM (MCP) 16bit SW7 : bit1 = OFF
+ * 0x1400_0000 Ether (LAN9220) 16bit
+ * 0x1600_0000 user area - cannot use with NAND
+ * 0x1800_0000 user area -
+ * 0x1A00_0000 -
+ * 0x4000_0000 LPDDR2-SDRAM (POP) 32bit
+ */
+
+/*
+ * CPU mode
+ *
+ * SW4 | Boot Area| Master | Remarks
+ * 1 | 2 | 3 | 4 | 5 | 6 | 8 | | Processor|
+ * ----+-----+-----+-----+-----+-----+-----+----------+----------+--------------
+ * ON | ON | OFF | ON | ON | OFF | OFF | External | System | External ROM
+ * ON | ON | ON | ON | ON | OFF | OFF | External | System | ROM Debug
+ * ON | ON | X | ON | OFF | OFF | OFF | Built-in | System | ROM Debug
+ * X | OFF | X | X | X | X | OFF | Built-in | System | MaskROM
+ * OFF | X | X | X | X | X | OFF | Built-in | System | MaskROM
+ * X | X | X | OFF | X | X | OFF | Built-in | System | MaskROM
+ * OFF | ON | OFF | X | X | OFF | ON | External | System | Standalone
+ * ON | OFF | OFF | X | X | OFF | ON | External | Realtime | Standalone
+*/
+
+/*
+ * NOR Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NOR Flash ROM
+ * bit1 | bit1 bit2 | bit1 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | Area 0
+ * OFF | ON OFF | OFF | Area 4
+ */
+
+/*
+ * SMSC 9220
+ *
+ * SW1 SMSC 9220
+ * -----------------------
+ * ON access disable
+ * OFF access enable
+ */
+
+/*
+ * NAND Flash ROM
+ *
+ * SW1 | SW2 | SW7 | NAND Flash ROM
+ * bit1 | bit1 bit2 | bit2 | Memory allocation
+ * ------+------------+------+------------------
+ * OFF | ON OFF | ON | FCE 0
+ * OFF | ON OFF | OFF | FCE 1
+ */
+
+/*
+ * External interrupt pin settings
+ *
+ * IRQX | pin setting | device | level
+ * ------+--------------------+--------------------+-------
+ * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
+ * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
+ * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Touch Panel | Low
+ * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
+ * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
+ * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
+ * IRQ22 | ICR4A.IRQ22SA=0011 | Sensor(AK8975) | High
+ */
+
+/*
+ * USB
+ *
+ * USB0 : CN22 : Function
+ * USB1 : CN31 : Function/Host *1
+ *
+ * J30 (for CN31) *1
+ * ----------+---------------+-------------
+ * 1-2 short | VBUS 5V | Host
+ * open | external VBUS | Function
+ *
+ * *1
+ * CN31 is used as
+ * CONFIG_USB_R8A66597_HCD Host
+ * CONFIG_USB_RENESAS_USBHS Function
+ *
+ * CAUTION
+ *
+ * renesas_usbhs driver can use external interrupt mode
+ * (which come from USB-PHY) or autonomy mode (it use own interrupt)
+ * for detecting connection/disconnection when Function.
+ * USB will be power OFF while it has been disconnecting
+ * if external interrupt mode, and it is always power ON if autonomy mode,
+ *
+ * mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
+ * because Touchscreen is using IRQ7-PORT40.
+ * It is impossible to use IRQ7 demux on this board.
+ *
+ * We can use external interrupt mode USB-Function on "USB1".
+ * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
+ * But don't select both drivers in same time.
+ * These uses same IRQ number for request_irq(), and aren't supporting
+ * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
+ *
+ * Actually these are old/new version of USB driver.
+ * This mean its register will be broken if it supports shared IRQ,
+ */
+
+/*
+ * SDHI0 (CN12)
+ *
+ * SW56 : OFF
+ *
+ */
+
+/* MMC /SDHI1 (CN7)
+ *
+ * I/O voltage : 1.8v
+ *
+ * Power voltage : 1.8v or 3.3v
+ * J22 : select power voltage *1
+ * 1-2 pin : 1.8v
+ * 2-3 pin : 3.3v
+ *
+ * *1
+ * Please change J22 depends the card to be used.
+ * MMC's OCR field set to support either voltage for the card inserted.
+ *
+ * SW1 | SW33
+ * | bit1 | bit2 | bit3 | bit4
+ * -------------+------+------+------+-------
+ * MMC0 OFF | OFF | X | ON | X (Use MMCIF)
+ * SDHI1 OFF | ON | X | OFF | X (Use MFD_SH_MOBILE_SDHI)
+ *
+ */
+
+/*
+ * SDHI2 (CN23)
+ *
+ * microSD card sloct
+ *
+ */
+
+/*
+ * FIXME !!
+ *
+ * gpio_no_direction
+ * gpio_pull_down
+ * are quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_no_direction(u32 addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+static void __init gpio_pull_down(u32 addr)
+{
+ u8 data = __raw_readb(addr);
+
+ data &= 0x0F;
+ data |= 0xA0;
+
+ __raw_writeb(data, addr);
+}
+
+/* MTD */
+static struct mtd_partition nor_flash_partitions[] = {
+ {
+ .name = "loader",
+ .offset = 0x00000000,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "bootenv",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel_ro",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ .mask_flags = MTD_WRITEABLE,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "data",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data nor_flash_data = {
+ .width = 2,
+ .parts = nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nor_flash_partitions),
+};
+
+static struct resource nor_flash_resources[] = {
+ [0] = {
+ .start = 0x00000000,
+ .end = 0x08000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nor_flash_device = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &nor_flash_data,
+ },
+ .num_resources = ARRAY_SIZE(nor_flash_resources),
+ .resource = nor_flash_resources,
+};
+
+/* SMSC */
+static struct resource smc911x_resources[] = {
+ {
+ .start = 0x14000000,
+ .end = 0x16000000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = evt2irq(0x02c0) /* IRQ6A */,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_info = {
+ .flags = SMSC911X_USE_16BIT | SMSC911X_SAVE_MAC_ADDRESS,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device smc911x_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc911x_resources),
+ .resource = smc911x_resources,
+ .dev = {
+ .platform_data = &smsc911x_info,
+ },
+};
+
+/* MERAM */
+static struct sh_mobile_meram_info mackerel_meram_info = {
+ .addr_mode = SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+ [0] = {
+ .name = "MERAM",
+ .start = 0xe8000000,
+ .end = 0xe81fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device meram_device = {
+ .name = "sh_mobile_meram",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(meram_resources),
+ .resource = meram_resources,
+ .dev = {
+ .platform_data = &mackerel_meram_info,
+ },
+};
+
+/* LCDC */
+static struct fb_videomode mackerel_lcdc_modes[] = {
+ {
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+ },
+};
+
+static int mackerel_set_brightness(void *board_data, int brightness)
+{
+ gpio_set_value(GPIO_PORT31, brightness);
+
+ return 0;
+}
+
+static int mackerel_get_brightness(void *board_data)
+{
+ return gpio_get_value(GPIO_PORT31);
+}
+
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 28,
+ .cache_icb = 24,
+ .meram_offset = 0x0,
+ .meram_size = 0x40,
+ },
+ .icb[1] = {
+ .marker_icb = 29,
+ .cache_icb = 25,
+ .meram_offset = 0x40,
+ .meram_size = 0x40,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .meram_dev = &mackerel_meram_info,
+ .clock_source = LCDC_CLK_BUS,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .lcd_cfg = mackerel_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
+ .interface_type = RGB24,
+ .clock_divider = 3,
+ .flags = 0,
+ .lcd_size_cfg.width = 152,
+ .lcd_size_cfg.height = 91,
+ .board_cfg = {
+ .set_brightness = mackerel_set_brightness,
+ .get_brightness = mackerel_get_brightness,
+ },
+ .bl_info = {
+ .name = "sh_mobile_lcdc_bl",
+ .max_brightness = 1,
+ },
+ .meram_cfg = &lcd_meram_cfg,
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000,
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 30,
+ .cache_icb = 26,
+ .meram_offset = 0x80,
+ .meram_size = 0x100,
+ },
+ .icb[1] = {
+ .marker_icb = 31,
+ .cache_icb = 27,
+ .meram_offset = 0x180,
+ .meram_size = 0x100,
+ },
+};
+/* HDMI */
+static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+ .meram_dev = &mackerel_meram_info,
+ .clock_source = LCDC_CLK_EXTERNAL,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .meram_cfg = &hdmi_meram_cfg,
+ }
+};
+
+static struct resource hdmi_lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC1",
+ .start = 0xfe944000,
+ .end = 0xfe947fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x1780),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(hdmi_lcdc_resources),
+ .resource = hdmi_lcdc_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &hdmi_lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &hdmi_lcdc_info.ch[0],
+ .lcd_dev = &hdmi_lcdc_device.dev,
+ .flags = HDMI_SND_SRC_SPDIF,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
+static struct platform_device fsi_hdmi_device = {
+ .name = "sh_fsi2_b_hdmi",
+};
+
+static void __init hdmi_init_pm_clock(void)
+{
+ struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+ int ret;
+ long rate;
+
+ if (IS_ERR(hdmi_ick)) {
+ ret = PTR_ERR(hdmi_ick);
+ pr_err("Cannot get HDMI ICK: %d\n", ret);
+ goto out;
+ }
+
+ ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk);
+ if (ret < 0) {
+ pr_err("Cannot set PLLC2 parent: %d, %d users\n",
+ ret, sh7372_pllc2_clk.usecount);
+ goto out;
+ }
+
+ pr_debug("PLLC2 initial frequency %lu\n",
+ clk_get_rate(&sh7372_pllc2_clk));
+
+ rate = clk_round_rate(&sh7372_pllc2_clk, 594000000);
+ if (rate < 0) {
+ pr_err("Cannot get suitable rate: %ld\n", rate);
+ ret = rate;
+ goto out;
+ }
+
+ ret = clk_set_rate(&sh7372_pllc2_clk, rate);
+ if (ret < 0) {
+ pr_err("Cannot set rate %ld: %d\n", rate, ret);
+ goto out;
+ }
+
+ pr_debug("PLLC2 set frequency %lu\n", rate);
+
+ ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
+ if (ret < 0)
+ pr_err("Cannot set HDMI parent: %d\n", ret);
+
+out:
+ if (!IS_ERR(hdmi_ick))
+ clk_put(hdmi_ick);
+}
+
+/* USBHS0 is connected to CN22 which takes a USB Mini-B plug
+ *
+ * The sh7372 SoC has IRQ7 set aside for USBHS0 hotplug,
+ * but on this particular board IRQ7 is already used by
+ * the touch screen. This leaves us with software polling.
+ */
+#define USBHS0_POLL_INTERVAL (HZ * 5)
+
+struct usbhs_private {
+ unsigned int usbphyaddr;
+ unsigned int usbcrcaddr;
+ struct renesas_usbhs_platform_info info;
+ struct delayed_work work;
+ struct platform_device *pdev;
+};
+
+#define usbhs_get_priv(pdev) \
+ container_of(renesas_usbhs_get_info(pdev), \
+ struct usbhs_private, info)
+
+#define usbhs_is_connected(priv) \
+ (!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
+
+static int usbhs_get_vbus(struct platform_device *pdev)
+{
+ return usbhs_is_connected(usbhs_get_priv(pdev));
+}
+
+static void usbhs_phy_reset(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* init phy */
+ __raw_writew(0x8a0a, priv->usbcrcaddr);
+}
+
+static int usbhs0_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static void usbhs0_work_function(struct work_struct *work)
+{
+ struct usbhs_private *priv = container_of(work, struct usbhs_private,
+ work.work);
+
+ renesas_usbhs_call_notify_hotplug(priv->pdev);
+ schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+}
+
+static int usbhs0_hardware_init(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ priv->pdev = pdev;
+ INIT_DELAYED_WORK(&priv->work, usbhs0_work_function);
+ schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+ return 0;
+}
+
+static void usbhs0_hardware_exit(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ cancel_delayed_work_sync(&priv->work);
+}
+
+static struct usbhs_private usbhs0_private = {
+ .usbcrcaddr = 0xe605810c, /* USBCR2 */
+ .info = {
+ .platform_callback = {
+ .hardware_init = usbhs0_hardware_init,
+ .hardware_exit = usbhs0_hardware_exit,
+ .phy_reset = usbhs_phy_reset,
+ .get_id = usbhs0_get_id,
+ .get_vbus = usbhs_get_vbus,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ },
+ },
+};
+
+static struct resource usbhs0_resources[] = {
+ [0] = {
+ .name = "USBHS0",
+ .start = 0xe6890000,
+ .end = 0xe68900e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ca0) /* USB0_USB0I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs0_device = {
+ .name = "renesas_usbhs",
+ .id = 0,
+ .dev = {
+ .platform_data = &usbhs0_private.info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs0_resources),
+ .resource = usbhs0_resources,
+};
+
+/* USBHS1 is connected to CN31 which takes a USB Mini-AB plug
+ *
+ * Use J30 to select between Host and Function. This setting
+ * can however not be detected by software. Hotplug of USBHS1
+ * is provided via IRQ8.
+ */
+#define IRQ8 evt2irq(0x0300)
+
+/* USBHS1 USB Host support via r8a66597_hcd */
+static void usb1_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on is supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
+ __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+ .on_chip = 1,
+ .port_power = usb1_host_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+ [0] = {
+ .name = "USBHS1",
+ .start = 0xe68b0000,
+ .end = 0xe68b00e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb1_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb1_host_data,
+ },
+ .num_resources = ARRAY_SIZE(usb1_host_resources),
+ .resource = usb1_host_resources,
+};
+
+/* USBHS1 USB Function support via renesas_usbhs */
+
+#define USB_PHY_MODE (1 << 4)
+#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
+#define USB_PHY_ON (1 << 1)
+#define USB_PHY_OFF (1 << 0)
+#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
+
+static irqreturn_t usbhs1_interrupt(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ renesas_usbhs_call_notify_hotplug(pdev);
+
+ /* clear status */
+ __raw_writew(__raw_readw(priv->usbphyaddr) | USB_PHY_INT_CLR,
+ priv->usbphyaddr);
+
+ return IRQ_HANDLED;
+}
+
+static int usbhs1_hardware_init(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+ int ret;
+
+ /* clear interrupt status */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
+
+ ret = request_irq(IRQ8, usbhs1_interrupt, IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq err\n");
+ return ret;
+ }
+
+ /* enable USB phy interrupt */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->usbphyaddr);
+
+ return 0;
+}
+
+static void usbhs1_hardware_exit(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* clear interrupt status */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
+
+ free_irq(IRQ8, pdev);
+}
+
+static int usbhs1_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static u32 usbhs1_pipe_cfg[] = {
+ USB_ENDPOINT_XFER_CONTROL,
+ USB_ENDPOINT_XFER_ISOC,
+ USB_ENDPOINT_XFER_ISOC,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usbhs_private usbhs1_private = {
+ .usbphyaddr = 0xe60581e2, /* USBPHY1INTAP */
+ .usbcrcaddr = 0xe6058130, /* USBCR4 */
+ .info = {
+ .platform_callback = {
+ .hardware_init = usbhs1_hardware_init,
+ .hardware_exit = usbhs1_hardware_exit,
+ .get_id = usbhs1_get_id,
+ .phy_reset = usbhs_phy_reset,
+ .get_vbus = usbhs_get_vbus,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ .pipe_type = usbhs1_pipe_cfg,
+ .pipe_size = ARRAY_SIZE(usbhs1_pipe_cfg),
+ },
+ },
+};
+
+static struct resource usbhs1_resources[] = {
+ [0] = {
+ .name = "USBHS1",
+ .start = 0xe68b0000,
+ .end = 0xe68b00e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs1_device = {
+ .name = "renesas_usbhs",
+ .id = 1,
+ .dev = {
+ .platform_data = &usbhs1_private.info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs1_resources),
+ .resource = usbhs1_resources,
+};
+
+/* LED */
+static struct gpio_led mackerel_leds[] = {
+ {
+ .name = "led0",
+ .gpio = GPIO_PORT0,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led1",
+ .gpio = GPIO_PORT1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led2",
+ .gpio = GPIO_PORT2,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ },
+ {
+ .name = "led3",
+ .gpio = GPIO_PORT159,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static struct gpio_led_platform_data mackerel_leds_pdata = {
+ .leds = mackerel_leds,
+ .num_leds = ARRAY_SIZE(mackerel_leds),
+};
+
+static struct platform_device leds_device = {
+ .name = "leds-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &mackerel_leds_pdata,
+ },
+};
+
+/* FSI */
+#define IRQ_FSI evt2irq(0x1840)
+static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
+{
+ int ret;
+
+ if (rate <= 0)
+ return 0;
+
+ if (!enable) {
+ clk_disable(clk);
+ return 0;
+ }
+
+ ret = clk_set_rate(clk, clk_round_rate(clk, rate));
+ if (ret < 0)
+ return ret;
+
+ return clk_enable(clk);
+}
+
+static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
+{
+ struct clk *fsib_clk;
+ struct clk *fdiv_clk = &sh7372_fsidivb_clk;
+ long fsib_rate = 0;
+ long fdiv_rate = 0;
+ int ackmd_bpfmd;
+ int ret;
+
+ /* FSIA is slave mode. nothing to do here */
+ if (is_porta)
+ return 0;
+
+ /* clock start */
+ switch (rate) {
+ case 44100:
+ fsib_rate = rate * 256;
+ ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+ break;
+ case 48000:
+ fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
+ fdiv_rate = rate * 256;
+ ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+ break;
+ default:
+ pr_err("unsupported rate in FSI2 port B\n");
+ return -EINVAL;
+ }
+
+ /* FSI B setting */
+ fsib_clk = clk_get(dev, "ickb");
+ if (IS_ERR(fsib_clk))
+ return -EIO;
+
+ /* fsib */
+ ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
+ if (ret < 0)
+ goto fsi_set_rate_end;
+
+ /* FSI DIV */
+ ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
+ if (ret < 0) {
+ /* disable FSI B */
+ if (enable)
+ __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
+ goto fsi_set_rate_end;
+ }
+
+ ret = ackmd_bpfmd;
+
+fsi_set_rate_end:
+ clk_put(fsib_clk);
+ return ret;
+}
+
+static struct sh_fsi_platform_info fsi_info = {
+ .porta_flags = SH_FSI_BRS_INV,
+
+ .portb_flags = SH_FSI_BRS_INV |
+ SH_FSI_BRM_INV |
+ SH_FSI_LRS_INV |
+ SH_FSI_FMT_SPDIF,
+
+ .set_rate = fsi_set_rate,
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C0400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct platform_device fsi_ak4643_device = {
+ .name = "sh_fsi2_a_ak4643",
+};
+
+/*
+ * The card detect pin of the top SD/MMC slot (CN7) is active low and is
+ * connected to GPIO A22 of SH7372 (GPIO_PORT41).
+ */
+static int slot_cn7_get_cd(struct platform_device *pdev)
+{
+ return !gpio_get_value(GPIO_PORT41);
+}
+
+/* SDHI0 */
+static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg)
+{
+ struct device *dev = arg;
+ struct sh_mobile_sdhi_info *info = dev->platform_data;
+ struct tmio_mmc_data *pdata = info->pdata;
+
+ tmio_mmc_cd_wakeup(pdata);
+
+ return IRQ_HANDLED;
+}
+
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
+};
+
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xe6850000,
+ .end = 0xe68500ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+/* SDHI1 */
+static struct sh_mobile_sdhi_info sdhi1_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
+ .tmio_ocr_mask = MMC_VDD_165_195,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn7_get_cd,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6860000,
+ .end = 0xe68600ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+#endif
+
+/*
+ * The card detect pin of the top SD/MMC slot (CN23) is active low and is
+ * connected to GPIO SCIFB_SCK of SH7372 (GPIO_PORT162).
+ */
+static int slot_cn23_get_cd(struct platform_device *pdev)
+{
+ return !gpio_get_value(GPIO_PORT162);
+}
+
+/* SDHI2 */
+static struct sh_mobile_sdhi_info sdhi2_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI2_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI2_RX,
+ .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn23_get_cd,
+};
+
+static struct resource sdhi2_resources[] = {
+ [0] = {
+ .name = "SDHI2",
+ .start = 0xe6870000,
+ .end = 0xe68700ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1200), /* SDHI2_SDHI2I0 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = evt2irq(0x1220), /* SDHI2_SDHI2I1 */
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = evt2irq(0x1240), /* SDHI2_SDHI2I2 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi2_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi2_resources),
+ .resource = sdhi2_resources,
+ .id = 2,
+ .dev = {
+ .platform_data = &sdhi2_info,
+ },
+};
+
+/* SH_MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "MMCIF",
+ .start = 0xE6BD0000,
+ .end = 0xE6BD00FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* MMC ERR */
+ .start = evt2irq(0x1ac0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* MMC NOR */
+ .start = evt2irq(0x1ae0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_dma sh_mmcif_dma = {
+ .chan_priv_rx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ },
+ .chan_priv_tx = {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0,
+ .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NEEDS_POLL,
+ .get_cd = slot_cn7_get_cd,
+ .dma = &sh_mmcif_dma,
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
+
+static int mackerel_camera_add(struct soc_camera_link *icl, struct device *dev);
+static void mackerel_camera_del(struct soc_camera_link *icl);
+
+static int camera_set_capture(struct soc_camera_platform_info *info,
+ int enable)
+{
+ return 0; /* camera sensor always enabled */
+}
+
+static struct soc_camera_platform_info camera_info = {
+ .format_name = "UYVY",
+ .format_depth = 16,
+ .format = {
+ .code = V4L2_MBUS_FMT_UYVY8_2X8,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
+ .field = V4L2_FIELD_NONE,
+ .width = 640,
+ .height = 480,
+ },
+ .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
+ SOCAM_DATA_ACTIVE_HIGH,
+ .set_capture = camera_set_capture,
+};
+
+static struct soc_camera_link camera_link = {
+ .bus_id = 0,
+ .add_device = mackerel_camera_add,
+ .del_device = mackerel_camera_del,
+ .module_name = "soc_camera_platform",
+ .priv = &camera_info,
+};
+
+static struct platform_device *camera_device;
+
+static void mackerel_camera_release(struct device *dev)
+{
+ soc_camera_platform_release(&camera_device);
+}
+
+static int mackerel_camera_add(struct soc_camera_link *icl,
+ struct device *dev)
+{
+ return soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
+ mackerel_camera_release, 0);
+}
+
+static void mackerel_camera_del(struct soc_camera_link *icl)
+{
+ soc_camera_platform_del(icl, camera_device, &camera_link);
+}
+
+static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
+ .flags = SH_CEU_FLAG_USE_8BIT_BUS,
+};
+
+static struct resource ceu_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x880),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device ceu_device = {
+ .name = "sh_mobile_ceu",
+ .id = 0, /* "ceu0" clock */
+ .num_resources = ARRAY_SIZE(ceu_resources),
+ .resource = ceu_resources,
+ .dev = {
+ .platform_data = &sh_mobile_ceu_info,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device mackerel_camera = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &camera_link,
+ },
+};
+
+static struct platform_device *mackerel_devices[] __initdata = {
+ &nor_flash_device,
+ &smc911x_device,
+ &lcdc_device,
+ &usb1_host_device,
+ &usbhs1_device,
+ &usbhs0_device,
+ &leds_device,
+ &fsi_device,
+ &fsi_ak4643_device,
+ &fsi_hdmi_device,
+ &sdhi0_device,
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ &sdhi1_device,
+#endif
+ &sdhi2_device,
+ &sh_mmcif_device,
+ &ceu_device,
+ &mackerel_camera,
+ &hdmi_lcdc_device,
+ &hdmi_device,
+ &meram_device,
+};
+
+/* Keypad Initialization */
+#define KEYPAD_BUTTON(ev_type, ev_code, act_low) \
+{ \
+ .type = ev_type, \
+ .code = ev_code, \
+ .active_low = act_low, \
+}
+
+#define KEYPAD_BUTTON_LOW(event_code) KEYPAD_BUTTON(EV_KEY, event_code, 1)
+
+static struct tca6416_button mackerel_gpio_keys[] = {
+ KEYPAD_BUTTON_LOW(KEY_HOME),
+ KEYPAD_BUTTON_LOW(KEY_MENU),
+ KEYPAD_BUTTON_LOW(KEY_BACK),
+ KEYPAD_BUTTON_LOW(KEY_POWER),
+};
+
+static struct tca6416_keys_platform_data mackerel_tca6416_keys_info = {
+ .buttons = mackerel_gpio_keys,
+ .nbuttons = ARRAY_SIZE(mackerel_gpio_keys),
+ .rep = 1,
+ .use_polling = 0,
+ .pinmask = 0x000F,
+};
+
+/* I2C */
+#define IRQ7 evt2irq(0x02e0)
+#define IRQ9 evt2irq(0x0320)
+
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4643", 0x13),
+ },
+ /* Keypad */
+ {
+ I2C_BOARD_INFO("tca6408-keys", 0x20),
+ .platform_data = &mackerel_tca6416_keys_info,
+ .irq = IRQ9,
+ },
+ /* Touchscreen */
+ {
+ I2C_BOARD_INFO("st1232-ts", 0x55),
+ .irq = IRQ7,
+ },
+};
+
+#define IRQ21 evt2irq(0x32a0)
+
+static struct i2c_board_info i2c1_devices[] = {
+ /* Accelerometer */
+ {
+ I2C_BOARD_INFO("adxl34x", 0x53),
+ .irq = IRQ21,
+ },
+};
+
+static struct map_desc mackerel_io_desc[] __initdata = {
+ /* create a 1:1 entity map for 0xe6xxxxxx
+ * used by CPGA, INTC and PFC.
+ */
+ {
+ .virtual = 0xe6000000,
+ .pfn = __phys_to_pfn(0xe6000000),
+ .length = 256 << 20,
+ .type = MT_DEVICE_NONSHARED
+ },
+};
+
+static void __init mackerel_map_io(void)
+{
+ iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
+
+ /* setup early devices and console here as well */
+ sh7372_add_early_devices();
+ shmobile_setup_console();
+}
+
+#define GPIO_PORT9CR 0xE6051009
+#define GPIO_PORT10CR 0xE605100A
+#define GPIO_PORT167CR 0xE60520A7
+#define GPIO_PORT168CR 0xE60520A8
+#define SRCR4 0xe61580bc
+#define USCCR1 0xE6058144
+static void __init mackerel_init(void)
+{
+ u32 srcr4;
+ struct clk *clk;
+ int ret;
+
+ sh7372_pinmux_init();
+
+ /* enable SCIFA0 */
+ gpio_request(GPIO_FN_SCIFA0_TXD, NULL);
+ gpio_request(GPIO_FN_SCIFA0_RXD, NULL);
+
+ /* enable SMSC911X */
+ gpio_request(GPIO_FN_CS5A, NULL);
+ gpio_request(GPIO_FN_IRQ6_39, NULL);
+
+ /* LCDC */
+ gpio_request(GPIO_FN_LCDD23, NULL);
+ gpio_request(GPIO_FN_LCDD22, NULL);
+ gpio_request(GPIO_FN_LCDD21, NULL);
+ gpio_request(GPIO_FN_LCDD20, NULL);
+ gpio_request(GPIO_FN_LCDD19, NULL);
+ gpio_request(GPIO_FN_LCDD18, NULL);
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+
+ gpio_request(GPIO_PORT31, NULL); /* backlight */
+ gpio_direction_output(GPIO_PORT31, 0); /* off by default */
+
+ gpio_request(GPIO_PORT151, NULL); /* LCDDON */
+ gpio_direction_output(GPIO_PORT151, 1);
+
+ /* USBHS0 */
+ gpio_request(GPIO_FN_VBUS0_0, NULL);
+ gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
+
+ /* USBHS1 */
+ gpio_request(GPIO_FN_VBUS0_1, NULL);
+ gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
+ gpio_request(GPIO_FN_IDIN_1_113, NULL);
+
+ /* USB phy tweak to make the r8a66597_hcd host driver work */
+ __raw_writew(0x8a0a, 0xe6058130); /* USBCR4 */
+
+ /* enable FSI2 port A (ak4643) */
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+ gpio_request(GPIO_PORT161, NULL);
+ gpio_direction_output(GPIO_PORT161, 0); /* slave */
+
+ gpio_request(GPIO_PORT9, NULL);
+ gpio_request(GPIO_PORT10, NULL);
+ gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+
+ intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
+
+ /* setup FSI2 port B (HDMI) */
+ gpio_request(GPIO_FN_FSIBCK, NULL);
+ __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
+
+ /* set SPU2 clock to 119.6 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 119600000));
+ clk_put(clk);
+ }
+
+ /* enable Keypad */
+ gpio_request(GPIO_FN_IRQ9_42, NULL);
+ irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
+
+ /* enable Touchscreen */
+ gpio_request(GPIO_FN_IRQ7_40, NULL);
+ irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
+
+ /* enable Accelerometer */
+ gpio_request(GPIO_FN_IRQ21, NULL);
+ irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
+
+ /* enable SDHI0 */
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+
+ ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd,
+ IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev);
+ if (!ret)
+ sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
+ else
+ pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret);
+
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
+ /* enable SDHI1 */
+ gpio_request(GPIO_FN_SDHICMD1, NULL);
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHID1_3, NULL);
+ gpio_request(GPIO_FN_SDHID1_2, NULL);
+ gpio_request(GPIO_FN_SDHID1_1, NULL);
+ gpio_request(GPIO_FN_SDHID1_0, NULL);
+#endif
+ /* card detect pin for MMC slot (CN7) */
+ gpio_request(GPIO_PORT41, NULL);
+ gpio_direction_input(GPIO_PORT41);
+
+ /* enable SDHI2 */
+ gpio_request(GPIO_FN_SDHICMD2, NULL);
+ gpio_request(GPIO_FN_SDHICLK2, NULL);
+ gpio_request(GPIO_FN_SDHID2_3, NULL);
+ gpio_request(GPIO_FN_SDHID2_2, NULL);
+ gpio_request(GPIO_FN_SDHID2_1, NULL);
+ gpio_request(GPIO_FN_SDHID2_0, NULL);
+
+ /* card detect pin for microSD slot (CN23) */
+ gpio_request(GPIO_PORT162, NULL);
+ gpio_direction_input(GPIO_PORT162);
+
+ /* MMCIF */
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_FN_MMCCMD0, NULL);
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+
+ /* enable GPS module (GT-720F) */
+ gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
+ gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
+
+ /* CEU */
+ gpio_request(GPIO_FN_VIO_CLK, NULL);
+ gpio_request(GPIO_FN_VIO_VD, NULL);
+ gpio_request(GPIO_FN_VIO_HD, NULL);
+ gpio_request(GPIO_FN_VIO_FIELD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO_D7, NULL);
+ gpio_request(GPIO_FN_VIO_D6, NULL);
+ gpio_request(GPIO_FN_VIO_D5, NULL);
+ gpio_request(GPIO_FN_VIO_D4, NULL);
+ gpio_request(GPIO_FN_VIO_D3, NULL);
+ gpio_request(GPIO_FN_VIO_D2, NULL);
+ gpio_request(GPIO_FN_VIO_D1, NULL);
+ gpio_request(GPIO_FN_VIO_D0, NULL);
+
+ /* HDMI */
+ gpio_request(GPIO_FN_HDMI_HPD, NULL);
+ gpio_request(GPIO_FN_HDMI_CEC, NULL);
+
+ /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */
+ srcr4 = __raw_readl(SRCR4);
+ __raw_writel(srcr4 | (1 << 13), SRCR4);
+ udelay(50);
+ __raw_writel(srcr4 & ~(1 << 13), SRCR4);
+
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+ i2c_register_board_info(1, i2c1_devices,
+ ARRAY_SIZE(i2c1_devices));
+
+ sh7372_add_standard_devices();
+
+ platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
+
+ hdmi_init_pm_clock();
+ sh7372_pm_init();
+}
+
+static void __init mackerel_timer_init(void)
+{
+ sh7372_clock_init();
+ shmobile_timer.init();
+
+ /* External clock source */
+ clk_set_rate(&sh7372_dv_clki_clk, 27000000);
+}
+
+static struct sys_timer mackerel_timer = {
+ .init = mackerel_timer_init,
+};
+
+MACHINE_START(MACKEREL, "mackerel")
+ .map_io = mackerel_map_io,
+ .init_irq = sh7372_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = mackerel_init,
+ .timer = &mackerel_timer,
+MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
new file mode 100644
index 00000000..6b186aef
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -0,0 +1,358 @@
+/*
+ * SH7367 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+/* SH7367 registers */
+#define RTFRQCR 0xe6150000
+#define SYFRQCR 0xe6150004
+#define CMFRQCR 0xe61500E0
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define SCLKACR 0xe6150010
+#define SCLKBCR 0xe6150014
+#define SUBUSBCKCR 0xe6158080
+#define SPUCKCR 0xe6150084
+#define MSUCKCR 0xe6150088
+#define MVI3CKCR 0xe6150090
+#define VOUCKCR 0xe6150094
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define PLLC1CR 0xe6150028
+#define PLLC2CR 0xe615002C
+#define RTMSTPCR0 0xe6158030
+#define RTMSTPCR2 0xe6158038
+#define SYMSTPCR0 0xe6158040
+#define SYMSTPCR2 0xe6158048
+#define CMMSTPCR0 0xe615804c
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTALB1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7367_extalb1_clk = {
+ .rate = 26666666,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7367_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extalb1 by two */
+static struct clk extalb1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7367_extalb1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7367_extal2_clk,
+};
+
+/* PLLC1 */
+static unsigned long pllc1_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC1CR) & (1 << 14))
+ mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc1_clk_ops = {
+ .recalc = pllc1_recalc,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc1_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalb1_div2_clk,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+static unsigned long pllc2_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+};
+
+static struct clk pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalb1_div2_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh7367_extalb1_clk,
+ &sh7367_extal2_clk,
+ &extalb1_div2_clk,
+ &extal2_div2_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &pllc2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in SYFRQCR to update hardware setting */
+ value = __raw_readl(SYFRQCR);
+ value |= (1 << 31);
+ __raw_writel(value, SYFRQCR);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 0, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B,
+ DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP,
+ DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
+ [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0),
+ [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
+ [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
+};
+
+enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU,
+ DIV6_MVI3, DIV6_MF1, DIV6_MF2,
+ DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0),
+ [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0),
+ [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
+ [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
+ [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
+};
+
+enum { RTMSTP001,
+ RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226,
+ RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201,
+ SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004,
+ SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000,
+ SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222,
+ SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211,
+ CMMSTP003,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */
+ [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */
+ [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */
+ [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */
+ [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */
+ [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */
+ [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */
+ [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */
+ [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */
+ [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */
+ [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */
+ [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */
+ [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */
+ [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */
+ [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */
+ [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */
+ [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */
+ [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */
+ [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */
+ [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */
+ [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */
+ [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */
+ [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */
+ [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */
+ [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */
+ [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */
+ [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */
+ [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk),
+ CLKDEV_CON_ID("extal2", &sh7367_extal2_clk),
+ CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
+ CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]),
+ CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]),
+ CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
+ CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
+ CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */
+ CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[SYMSTP229]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */
+ CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */
+};
+
+void __init sh7367_clock_init(void)
+{
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7367 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
new file mode 100644
index 00000000..c0800d83
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -0,0 +1,703 @@
+/*
+ * SH7372 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+/* SH7372 registers */
+#define FRQCRA 0xe6150000
+#define FRQCRB 0xe6150004
+#define FRQCRC 0xe61500e0
+#define FRQCRD 0xe61500e4
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000c
+#define VCLKCR3 0xe615001c
+#define FMSICKCR 0xe6150010
+#define FMSOCKCR 0xe6150014
+#define FSIACKCR 0xe6150018
+#define FSIBCKCR 0xe6150090
+#define SUBCKCR 0xe6150080
+#define SPUCKCR 0xe6150084
+#define VOUCKCR 0xe6150088
+#define HDMICKCR 0xe6150094
+#define DSITCKCR 0xe6150060
+#define DSI0PCKCR 0xe6150064
+#define DSI1PCKCR 0xe6150098
+#define PLLC01CR 0xe6150028
+#define PLLC2CR 0xe615002c
+#define RMSTPCR0 0xe6150110
+#define RMSTPCR1 0xe6150114
+#define RMSTPCR2 0xe6150118
+#define RMSTPCR3 0xe615011c
+#define RMSTPCR4 0xe6150120
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR4 0xe6150140
+
+#define FSIDIVA 0xFE1F8000
+#define FSIDIVB 0xFE1F8008
+
+/* Platforms must set frequency on their DV_CLKI pin */
+struct clk sh7372_dv_clki_clk = {
+};
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7372_extal1_clk = {
+ .rate = 26000000,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7372_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide dv_clki by two */
+struct clk sh7372_dv_clki_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7372_dv_clki_clk,
+};
+
+/* Divide extal1 by two */
+static struct clk extal1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7372_extal1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7372_extal2_clk,
+};
+
+/* Divide extal2 by four */
+static struct clk extal2_div4_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &extal2_div2_clk,
+};
+
+/* PLLC0 and PLLC1 */
+static unsigned long pllc01_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC01CR) & (1 << 14))
+ mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc01_clk_ops = {
+ .recalc = pllc01_recalc,
+};
+
+static struct clk pllc0_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extal1_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRC,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extal1_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRA,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+
+/* Indices are important - they are the actual src selecting values */
+static struct clk *pllc2_parent[] = {
+ [0] = &extal1_div2_clk,
+ [1] = &extal2_div2_clk,
+ [2] = &sh7372_dv_clki_div2_clk,
+};
+
+/* Only multipliers 20 * 2 to 46 * 2 are valid, last entry for CPUFREQ_TABLE_END */
+static struct cpufreq_frequency_table pllc2_freq_table[29];
+
+static void pllc2_table_rebuild(struct clk *clk)
+{
+ int i;
+
+ /* Initialise PLLC2 frequency table */
+ for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
+ pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
+ pllc2_freq_table[i].index = i;
+ }
+
+ /* This is a special entry - switching PLL off makes it a repeater */
+ pllc2_freq_table[i].frequency = clk->parent->rate;
+ pllc2_freq_table[i].index = i;
+
+ pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
+ pllc2_freq_table[i].index = i;
+}
+
+static unsigned long pllc2_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ pllc2_table_rebuild(clk);
+
+ /*
+ * If the PLL is off, mult == 1, clk->rate will be updated in
+ * pllc2_enable().
+ */
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static long pllc2_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_table_round(clk, clk->freq_table, rate);
+}
+
+static int pllc2_enable(struct clk *clk)
+{
+ int i;
+
+ __raw_writel(__raw_readl(PLLC2CR) | 0x80000000, PLLC2CR);
+
+ for (i = 0; i < 100; i++)
+ if (__raw_readl(PLLC2CR) & 0x80000000) {
+ clk->rate = pllc2_recalc(clk);
+ return 0;
+ }
+
+ pr_err("%s(): timeout!\n", __func__);
+
+ return -ETIMEDOUT;
+}
+
+static void pllc2_disable(struct clk *clk)
+{
+ __raw_writel(__raw_readl(PLLC2CR) & ~0x80000000, PLLC2CR);
+}
+
+static int pllc2_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long value;
+ int idx;
+
+ idx = clk_rate_table_find(clk, clk->freq_table, rate);
+ if (idx < 0)
+ return idx;
+
+ if (rate == clk->parent->rate)
+ return -EINVAL;
+
+ value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
+
+ __raw_writel(value | ((idx + 19) << 24), PLLC2CR);
+
+ clk->rate = clk->freq_table[idx].frequency;
+
+ return 0;
+}
+
+static int pllc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 value;
+ int ret, i;
+
+ if (!clk->parent_table || !clk->parent_num)
+ return -EINVAL;
+
+ /* Search the parent */
+ for (i = 0; i < clk->parent_num; i++)
+ if (clk->parent_table[i] == parent)
+ break;
+
+ if (i == clk->parent_num)
+ return -ENODEV;
+
+ ret = clk_reparent(clk, parent);
+ if (ret < 0)
+ return ret;
+
+ value = __raw_readl(PLLC2CR) & ~(3 << 6);
+
+ __raw_writel(value | (i << 6), PLLC2CR);
+
+ /* Rebiuld the frequency table */
+ pllc2_table_rebuild(clk);
+
+ return 0;
+}
+
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+ .round_rate = pllc2_round_rate,
+ .set_rate = pllc2_set_rate,
+ .enable = pllc2_enable,
+ .disable = pllc2_disable,
+ .set_parent = pllc2_set_parent,
+};
+
+struct clk sh7372_pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .parent = &extal1_div2_clk,
+ .freq_table = pllc2_freq_table,
+ .nr_freqs = ARRAY_SIZE(pllc2_freq_table) - 1,
+ .parent_table = pllc2_parent,
+ .parent_num = ARRAY_SIZE(pllc2_parent),
+};
+
+/* External input clock (pin name: FSIACK/FSIBCK ) */
+struct clk sh7372_fsiack_clk = {
+};
+
+struct clk sh7372_fsibck_clk = {
+};
+
+static struct clk *main_clks[] = {
+ &sh7372_dv_clki_clk,
+ &r_clk,
+ &sh7372_extal1_clk,
+ &sh7372_extal2_clk,
+ &sh7372_dv_clki_div2_clk,
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &extal2_div4_clk,
+ &pllc0_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &sh7372_pllc2_clk,
+ &sh7372_fsiack_clk,
+ &sh7372_fsibck_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRB to update hardware setting */
+ value = __raw_readl(FRQCRB);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
+ DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
+ DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
+ DIV4_DDRP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
+ [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
+ [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
+ [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
+ [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
+ [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
+ [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
+ DIV6_SUB, DIV6_SPU,
+ DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
+ [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
+ [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
+};
+
+enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR };
+
+/* Indices are important - they are the actual src selecting values */
+static struct clk *hdmi_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_dv_clki_clk,
+ [3] = NULL, /* pllc2_div4 not implemented yet */
+};
+
+static struct clk *fsiackcr_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_fsiack_clk, /* external input for FSI A */
+ [3] = NULL, /* setting prohibited */
+};
+
+static struct clk *fsibckcr_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &sh7372_pllc2_clk,
+ [2] = &sh7372_fsibck_clk, /* external input for FSI B */
+ [3] = NULL, /* setting prohibited */
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0,
+ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0,
+ fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0,
+ fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2),
+};
+
+/* FSI DIV */
+static unsigned long fsidiv_recalc(struct clk *clk)
+{
+ unsigned long value;
+
+ value = __raw_readl(clk->mapping->base);
+
+ value >>= 16;
+ if (value < 2)
+ return 0;
+
+ return clk->parent->rate / value;
+}
+
+static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_div_range_round(clk, 2, 0xffff, rate);
+}
+
+static void fsidiv_disable(struct clk *clk)
+{
+ __raw_writel(0, clk->mapping->base);
+}
+
+static int fsidiv_enable(struct clk *clk)
+{
+ unsigned long value;
+
+ value = __raw_readl(clk->mapping->base) >> 16;
+ if (value < 2)
+ return -EIO;
+
+ __raw_writel((value << 16) | 0x3, clk->mapping->base);
+
+ return 0;
+}
+
+static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
+{
+ int idx;
+
+ idx = (clk->parent->rate / rate) & 0xffff;
+ if (idx < 2)
+ return -EINVAL;
+
+ __raw_writel(idx << 16, clk->mapping->base);
+ return 0;
+}
+
+static struct clk_ops fsidiv_clk_ops = {
+ .recalc = fsidiv_recalc,
+ .round_rate = fsidiv_round_rate,
+ .set_rate = fsidiv_set_rate,
+ .enable = fsidiv_enable,
+ .disable = fsidiv_disable,
+};
+
+static struct clk_mapping sh7372_fsidiva_clk_mapping = {
+ .phys = FSIDIVA,
+ .len = 8,
+};
+
+struct clk sh7372_fsidiva_clk = {
+ .ops = &fsidiv_clk_ops,
+ .parent = &div6_reparent_clks[DIV6_FSIA], /* late install */
+ .mapping = &sh7372_fsidiva_clk_mapping,
+};
+
+static struct clk_mapping sh7372_fsidivb_clk_mapping = {
+ .phys = FSIDIVB,
+ .len = 8,
+};
+
+struct clk sh7372_fsidivb_clk = {
+ .ops = &fsidiv_clk_ops,
+ .parent = &div6_reparent_clks[DIV6_FSIB], /* late install */
+ .mapping = &sh7372_fsidivb_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+ &sh7372_fsidiva_clk,
+ &sh7372_fsidivb_clk,
+};
+
+enum { MSTP001,
+ MSTP131, MSTP130,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
+ MSTP118, MSTP117, MSTP116, MSTP113,
+ MSTP106, MSTP101, MSTP100,
+ MSTP223,
+ MSTP218, MSTP217, MSTP216,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
+ MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
+ [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
+ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
+ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
+ [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU */
+ [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2 */
+ [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
+ [MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
+ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
+ [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
+ [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
+ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+ [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+ [MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+ [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+ [MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
+ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
+ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
+ [MSTP423] = MSTP(&div4_clks[DIV4_B], SMSTPCR4, 23, 0), /* DSITX1 */
+ [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+ [MSTP413] = MSTP(&pllc1_div2_clk, SMSTPCR4, 13, 0), /* HDMI */
+ [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
+ [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("dv_clki_div2_clk", &sh7372_dv_clki_div2_clk),
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
+ CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
+ CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
+ CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &sh7372_pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
+ CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
+ CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
+ CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+ CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
+ CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
+ CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU */
+ CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2 */
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
+ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+ CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
+ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
+ CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
+ CLKDEV_DEV_ID("sh-mipi-dsi.1", &mstp_clks[MSTP423]), /* DSITX1 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
+ CLKDEV_DEV_ID("sh-mobile-hdmi", &mstp_clks[MSTP413]), /* HDMI */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
+ CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+
+ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
+ CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
+ CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
+};
+
+void __init sh7372_clock_init(void)
+{
+ int k, ret = 0;
+
+ /* make sure MSTP bits on the RT/SH4AL-DSP side are off */
+ __raw_writel(0xe4ef8087, RMSTPCR0);
+ __raw_writel(0xffffffff, RMSTPCR1);
+ __raw_writel(0x37c7f7ff, RMSTPCR2);
+ __raw_writel(0xffffffff, RMSTPCR3);
+ __raw_writel(0xffe0fffd, RMSTPCR4);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7372 clocks\n");
+
+}
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
new file mode 100644
index 00000000..95942466
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -0,0 +1,369 @@
+/*
+ * SH7377 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+/* SH7377 registers */
+#define RTFRQCR 0xe6150000
+#define SYFRQCR 0xe6150004
+#define CMFRQCR 0xe61500E0
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define FMSICKCR 0xe6150010
+#define FMSOCKCR 0xe6150014
+#define FSICKCR 0xe6150018
+#define PLLC1CR 0xe6150028
+#define PLLC2CR 0xe615002C
+#define SUBUSBCKCR 0xe6150080
+#define SPUCKCR 0xe6150084
+#define MSUCKCR 0xe6150088
+#define MVI3CKCR 0xe6150090
+#define HDMICKCR 0xe6150094
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define DSITCKCR 0xe6150060
+#define DSIPCKCR 0xe6150064
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013C
+#define SMSTPCR4 0xe6150140
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTALC1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7377_extalc1_clk = {
+ .rate = 26666666,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7377_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extalc1 by two */
+static struct clk extalc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7377_extalc1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7377_extal2_clk,
+};
+
+/* Divide extal2 by four */
+static struct clk extal2_div4_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &extal2_div2_clk,
+};
+
+/* PLLC1 */
+static unsigned long pllc1_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC1CR) & (1 << 14))
+ mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc1_clk_ops = {
+ .recalc = pllc1_recalc,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc1_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalc1_div2_clk,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+static unsigned long pllc2_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+};
+
+static struct clk pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalc1_div2_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh7377_extalc1_clk,
+ &sh7377_extal2_clk,
+ &extalc1_div2_clk,
+ &extal2_div2_clk,
+ &extal2_div4_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &pllc2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in SYFRQCR to update hardware setting */
+ value = __raw_readl(SYFRQCR);
+ value |= (1 << 31);
+ __raw_writel(value, SYFRQCR);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
+ DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP,
+ DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0),
+ [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
+ [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
+ [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
+ [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
+ DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI,
+ DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP,
+ DIV6_NR };
+
+static struct clk div6_clks[] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
+ [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
+ [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
+ [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
+ [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
+ [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
+ [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0),
+};
+
+enum { MSTP001,
+ MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101,
+ MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP325, MSTP323, MSTP322,
+ MSTP315, MSTP314, MSTP313,
+ MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[] = {
+ [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
+ [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
+ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
+ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
+ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
+ [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
+ [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */
+ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
+ [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */
+ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk),
+ CLKDEV_CON_ID("extal2", &sh7377_extal2_clk),
+ CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
+ CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
+ CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
+ CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
+ CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]),
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
+ CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
+ CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
+ CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
+ CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
+ CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
+ CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */
+ CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+};
+
+void __init sh7377_clock_init(void)
+{
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7377 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
new file mode 100644
index 00000000..bcacb1e8
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -0,0 +1,405 @@
+/*
+ * sh73a0 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+#define FRQCRA 0xe6150000
+#define FRQCRB 0xe6150004
+#define FRQCRD 0xe61500e4
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define ZBCKCR 0xe6150010
+#define FLCKCR 0xe6150014
+#define SD0CKCR 0xe6150074
+#define SD1CKCR 0xe6150078
+#define SD2CKCR 0xe615007C
+#define FSIACKCR 0xe6150018
+#define FSIBCKCR 0xe6150090
+#define SUBCKCR 0xe6150080
+#define SPUACKCR 0xe6150084
+#define SPUVCKCR 0xe6150094
+#define MSUCKCR 0xe6150088
+#define HSICKCR 0xe615008C
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define DSITCKCR 0xe6150060
+#define DSI0PCKCR 0xe6150064
+#define DSI1PCKCR 0xe6150068
+#define DSI0PHYCR 0xe615006C
+#define DSI1PHYCR 0xe6150070
+#define PLLECR 0xe61500d0
+#define PLL0CR 0xe61500d8
+#define PLL1CR 0xe6150028
+#define PLL2CR 0xe615002c
+#define PLL3CR 0xe61500dc
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR4 0xe6150140
+#define SMSTPCR5 0xe6150144
+#define CKSCR 0xe61500c0
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh73a0_extal1_clk = {
+ .rate = 26000000,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh73a0_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extal1 by two */
+static struct clk extal1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh73a0_extal1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh73a0_extal2_clk,
+};
+
+static struct clk_ops main_clk_ops = {
+ .recalc = followparent_recalc,
+};
+
+/* Main clock */
+static struct clk main_clk = {
+ .ops = &main_clk_ops,
+};
+
+/* PLL0, PLL1, PLL2, PLL3 */
+static unsigned long pll_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
+ mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
+ /* handle CFG bit for PLL1 and PLL2 */
+ switch (clk->enable_bit) {
+ case 1:
+ case 2:
+ if (__raw_readl(clk->enable_reg) & (1 << 20))
+ mult *= 2;
+ }
+ }
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
+};
+
+static struct clk pll0_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL0CR,
+ .enable_bit = 0,
+};
+
+static struct clk pll1_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL1CR,
+ .enable_bit = 1,
+};
+
+static struct clk pll2_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL2CR,
+ .enable_bit = 2,
+};
+
+static struct clk pll3_clk = {
+ .ops = &pll_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &main_clk,
+ .enable_reg = (void __iomem *)PLL3CR,
+ .enable_bit = 3,
+};
+
+/* Divide PLL1 by two */
+static struct clk pll1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pll1_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh73a0_extal1_clk,
+ &sh73a0_extal2_clk,
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &main_clk,
+ &pll0_clk,
+ &pll1_clk,
+ &pll2_clk,
+ &pll3_clk,
+ &pll1_div2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRB to update hardware setting */
+ value = __raw_readl(FRQCRB);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 0, 36, 48, 7 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
+ DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
+ [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
+ [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
+ [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
+ [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
+ [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
+ [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
+ [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
+ DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
+ DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
+ DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
+ DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
+ DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
+ [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
+ [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
+ [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
+ [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
+ [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
+ [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
+ [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
+ [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
+ [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
+ [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
+ [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
+ [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
+ [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
+};
+
+enum { MSTP001,
+ MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
+ MSTP219,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
+ MSTP314, MSTP313, MSTP312, MSTP311,
+ MSTP411, MSTP410, MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* CEU1 */
+ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* CSI2-RX1 */
+ [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0), /* CEU0 */
+ [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0), /* CSI2-RX0 */
+ [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+ [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
+ [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+ [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
+ [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
+ [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
+ [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
+ [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
+ [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
+ CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
+ CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+ CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+ CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]), /* CEU1 */
+ CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]), /* CSI2-RX1 */
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), /* CEU0 */
+ CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]), /* CSI2-RX0 */
+ CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
+ CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
+ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+};
+
+void __init sh73a0_clock_init(void)
+{
+ int k, ret = 0;
+
+ /* Set SDHI clocks to a known state */
+ __raw_writel(0x108, SD0CKCR);
+ __raw_writel(0x108, SD1CKCR);
+ __raw_writel(0x108, SD2CKCR);
+
+ /* detect main clock parent */
+ switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
+ case 0:
+ main_clk.parent = &sh73a0_extal1_clk;
+ break;
+ case 1:
+ main_clk.parent = &extal1_div2_clk;
+ break;
+ case 2:
+ main_clk.parent = &sh73a0_extal2_clk;
+ break;
+ case 3:
+ main_clk.parent = &extal2_div2_clk;
+ break;
+ }
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh73a0 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c
new file mode 100644
index 00000000..6b7c7c42
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock.c
@@ -0,0 +1,46 @@
+/*
+ * SH-Mobile Clock Framework
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * Used together with arch/arm/common/clkdev.c and drivers/sh/clk.c.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sh_clk.h>
+
+int __init clk_init(void)
+{
+ /* Kick the child clocks.. */
+ recalculate_root_clocks();
+
+ /* Enable the necessary init clocks */
+ clk_enable_init_clocks();
+
+ return 0;
+}
+
+int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
diff --git a/arch/arm/mach-shmobile/console.c b/arch/arm/mach-shmobile/console.c
new file mode 100644
index 00000000..9411a5bf
--- /dev/null
+++ b/arch/arm/mach-shmobile/console.c
@@ -0,0 +1,31 @@
+/*
+ * SH-Mobile Console
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+#include <asm/mach/map.h>
+
+void __init shmobile_setup_console(void)
+{
+ parse_early_param();
+
+ /* Let earlyprintk output early console messages */
+ early_platform_driver_probe("earlyprintk", 1, 1);
+}
diff --git a/arch/arm/mach-shmobile/cpuidle.c b/arch/arm/mach-shmobile/cpuidle.c
new file mode 100644
index 00000000..2e44f11f
--- /dev/null
+++ b/arch/arm/mach-shmobile/cpuidle.c
@@ -0,0 +1,92 @@
+/*
+ * CPUIdle support code for SH-Mobile ARM
+ *
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/cpuidle.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void shmobile_enter_wfi(void)
+{
+ cpu_do_idle();
+}
+
+void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
+ shmobile_enter_wfi, /* regular sleep mode */
+};
+
+static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ ktime_t before, after;
+ int requested_state = state - &dev->states[0];
+
+ dev->last_state = &dev->states[requested_state];
+ before = ktime_get();
+
+ local_irq_disable();
+ local_fiq_disable();
+
+ shmobile_cpuidle_modes[requested_state]();
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ after = ktime_get();
+ return ktime_to_ns(ktime_sub(after, before)) >> 10;
+}
+
+static struct cpuidle_device shmobile_cpuidle_dev;
+static struct cpuidle_driver shmobile_cpuidle_driver = {
+ .name = "shmobile_cpuidle",
+ .owner = THIS_MODULE,
+};
+
+void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+
+static int shmobile_cpuidle_init(void)
+{
+ struct cpuidle_device *dev = &shmobile_cpuidle_dev;
+ struct cpuidle_state *state;
+ int i;
+
+ cpuidle_register_driver(&shmobile_cpuidle_driver);
+
+ for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+ dev->states[i].name[0] = '\0';
+ dev->states[i].desc[0] = '\0';
+ dev->states[i].enter = shmobile_cpuidle_enter;
+ }
+
+ i = CPUIDLE_DRIVER_STATE_START;
+
+ state = &dev->states[i++];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+ strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
+ state->exit_latency = 1;
+ state->target_residency = 1 * 2;
+ state->power_usage = 3;
+ state->flags = 0;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
+ dev->safe_state = state;
+ dev->state_count = i;
+
+ if (shmobile_cpuidle_setup)
+ shmobile_cpuidle_setup(dev);
+
+ cpuidle_register_device(dev);
+
+ return 0;
+}
+late_initcall(shmobile_cpuidle_init);
diff --git a/arch/arm/mach-shmobile/entry-gic.S b/arch/arm/mach-shmobile/entry-gic.S
new file mode 100644
index 00000000..e20239b0
--- /dev/null
+++ b/arch/arm/mach-shmobile/entry-gic.S
@@ -0,0 +1,18 @@
+/*
+ * ARM Interrupt demux handler using GIC
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2011 Paul Mundt
+ * Copyright (C) 2010 - 2011 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/assembler.h>
+#include <asm/entry-macro-multi.S>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+ arch_irq_handler shmobile_handle_irq_gic
diff --git a/arch/arm/mach-shmobile/entry-intc.S b/arch/arm/mach-shmobile/entry-intc.S
new file mode 100644
index 00000000..cac0a7ae
--- /dev/null
+++ b/arch/arm/mach-shmobile/entry-intc.S
@@ -0,0 +1,57 @@
+/*
+ * ARM Interrupt demux handler using INTC
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/entry-macro-multi.S>
+
+#define INTCA_BASE 0xe6980000
+#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
+#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
+#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
+#define INTLVLB_OFFS 0x00000034 /* previous priority level */
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =INTCA_BASE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ /* The single INTFLGA read access below results in the following:
+ *
+ * 1. INTLVLB is updated with old priority value from INTLVLA
+ * 2. Highest priority interrupt is accepted
+ * 3. INTLVLA is updated to contain priority of accepted interrupt
+ * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
+ */
+ ldr \irqnr, [\base, #INTFLGA_OFFS]
+
+ /* Restore INTLVLA with the value saved in INTLVLB.
+ * This is required to support interrupt priorities properly.
+ */
+ ldrb \tmp, [\base, #INTLVLB_OFFS]
+ strb \tmp, [\base, #INTLVLA_OFFS]
+
+ /* Handle invalid vector number case */
+ cmp \irqnr, #0
+ beq 1000f
+
+ /* Convert vector to irq number, same as the evt2irq() macro */
+ lsr \irqnr, \irqnr, #0x5
+ subs \irqnr, \irqnr, #16
+
+1000:
+ .endm
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ .endm
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ .endm
+
+ arch_irq_handler shmobile_handle_irq_intc
diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S
new file mode 100644
index 00000000..26079d93
--- /dev/null
+++ b/arch/arm/mach-shmobile/headsmp.S
@@ -0,0 +1,27 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Takashi Yoshii
+ *
+ * Based on vexpress, Copyright (c) 2003 ARM Limited, 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/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+
+ __INIT
+
+/*
+ * Reset vector for secondary CPUs.
+ * This will be mapped at address 0 by SBAR register.
+ * We need _long_ jump to the physical address.
+ */
+ .align 12
+ENTRY(shmobile_secondary_vector)
+ ldr pc, 1f
+1: .long secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET
diff --git a/arch/arm/mach-shmobile/hotplug.c b/arch/arm/mach-shmobile/hotplug.c
new file mode 100644
index 00000000..238a0d97
--- /dev/null
+++ b/arch/arm/mach-shmobile/hotplug.c
@@ -0,0 +1,41 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * Based on realview, Copyright (C) 2002 ARM Ltd, All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+void platform_cpu_die(unsigned int cpu)
+{
+ while (1) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+ }
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-shmobile/include/mach/clkdev.h b/arch/arm/mach-shmobile/include/mach/clkdev.h
new file mode 100644
index 00000000..36d0163a
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+#endif /* __ASM_MACH_CLKDEV_H */
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
new file mode 100644
index 00000000..06aecb31
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -0,0 +1,56 @@
+#ifndef __ARCH_MACH_COMMON_H
+#define __ARCH_MACH_COMMON_H
+
+extern struct sys_timer shmobile_timer;
+extern void shmobile_setup_console(void);
+extern void shmobile_secondary_vector(void);
+struct clk;
+extern int clk_init(void);
+extern void shmobile_handle_irq_intc(struct pt_regs *);
+extern void shmobile_handle_irq_gic(struct pt_regs *);
+extern struct platform_suspend_ops shmobile_suspend_ops;
+struct cpuidle_device;
+extern void (*shmobile_cpuidle_modes[])(void);
+extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+
+extern void sh7367_init_irq(void);
+extern void sh7367_add_early_devices(void);
+extern void sh7367_add_standard_devices(void);
+extern void sh7367_clock_init(void);
+extern void sh7367_pinmux_init(void);
+extern struct clk sh7367_extalb1_clk;
+extern struct clk sh7367_extal2_clk;
+
+extern void sh7377_init_irq(void);
+extern void sh7377_add_early_devices(void);
+extern void sh7377_add_standard_devices(void);
+extern void sh7377_clock_init(void);
+extern void sh7377_pinmux_init(void);
+extern struct clk sh7377_extalc1_clk;
+extern struct clk sh7377_extal2_clk;
+
+extern void sh7372_init_irq(void);
+extern void sh7372_add_early_devices(void);
+extern void sh7372_add_standard_devices(void);
+extern void sh7372_clock_init(void);
+extern void sh7372_pinmux_init(void);
+extern void sh7372_pm_init(void);
+extern void sh7372_cpu_suspend(void);
+extern void sh7372_cpu_resume(void);
+extern struct clk sh7372_extal1_clk;
+extern struct clk sh7372_extal2_clk;
+
+extern void sh73a0_init_irq(void);
+extern void sh73a0_add_early_devices(void);
+extern void sh73a0_add_standard_devices(void);
+extern void sh73a0_clock_init(void);
+extern void sh73a0_pinmux_init(void);
+extern struct clk sh73a0_extal1_clk;
+extern struct clk sh73a0_extal2_clk;
+
+extern unsigned int sh73a0_get_core_count(void);
+extern void sh73a0_secondary_init(unsigned int cpu);
+extern int sh73a0_boot_secondary(unsigned int cpu);
+extern void sh73a0_smp_prepare_cpus(void);
+
+#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/dma.h b/arch/arm/mach-shmobile/include/mach/dma.h
new file mode 100644
index 00000000..40a8c178
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/dma.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S
new file mode 100644
index 00000000..d791f10e
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Paul Mundt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ .endm
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ .endm
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h
new file mode 100644
index 00000000..2b1bb9e4
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * Generic GPIO API and pinmux table support
+ *
+ * Copyright (c) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#define ARCH_NR_GPIOS 1024
+#include <linux/sh_pfc.h>
+
+#ifdef CONFIG_GPIOLIB
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return -ENOSYS;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-shmobile/include/mach/hardware.h b/arch/arm/mach-shmobile/include/mach/hardware.h
new file mode 100644
index 00000000..99264a5c
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/hardware.h
@@ -0,0 +1,4 @@
+#ifndef __ASM_MACH_HARDWARE_H
+#define __ASM_MACH_HARDWARE_H
+
+#endif /* __ASM_MACH_HARDWARE_H */
diff --git a/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
new file mode 100644
index 00000000..9f134dfe
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
@@ -0,0 +1,93 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2010 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
+
+LIST "RWT Setting"
+EW 0xE6020004, 0xA500
+EW 0xE6030004, 0xA500
+
+LIST "GPIO Setting"
+EB 0xE6051013, 0xA2
+
+LIST "CPG"
+ED 0xE61500C0, 0x00000002
+
+WAIT 1, 0xFE40009C
+
+LIST "FRQCR"
+ED 0xE6150000, 0x2D1305C3
+ED 0xE61500E0, 0x9E40358E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE61500E4, 0x00002000
+
+WAIT 1, 0xFE40009C
+
+LIST "PLL"
+ED 0xE6150028, 0x00004000
+
+WAIT 1, 0xFE40009C
+
+ED 0xE615002C, 0x93000040
+
+WAIT 1, 0xFE40009C
+
+LIST "SUB/USBClk"
+ED 0xE6150080, 0x00000180
+
+LIST "BSC"
+ED 0xFEC10000, 0x00E0001B
+
+LIST "SBSC1"
+ED 0xFE400354, 0x01AD8000
+ED 0xFE400354, 0x01AD8001
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400008, 0xBCC90151
+ED 0xFE400040, 0x41774113
+ED 0xFE400044, 0x2712E229
+ED 0xFE400048, 0x20C18505
+ED 0xFE40004C, 0x00110209
+ED 0xFE400010, 0x00000087
+
+WAIT 30, 0xFE40009C
+
+ED 0xFE400084, 0x0000003F
+EB 0xFE500000, 0x00
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400084, 0x0000FF0A
+EB 0xFE500000, 0x00
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400084, 0x00002201
+EB 0xFE500000, 0x00
+ED 0xFE400084, 0x00000302
+EB 0xFE500000, 0x00
+EB 0xFE5C0000, 0x00
+ED 0xFE400008, 0xBCC90159
+ED 0xFE40008C, 0x88800004
+ED 0xFE400094, 0x00000004
+ED 0xFE400028, 0xA55A0032
+ED 0xFE40002C, 0xA55A000C
+ED 0xFE400020, 0xA55A2048
+ED 0xFE400008, 0xBCC90959
+
+LIST "Change CPGA setting"
+ED 0xE61500E0, 0x9E40352E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400354, 0x01AD8002
+
+LIST "SCIF0 - Serial port for earlyprintk"
+EB 0xE6053098, 0xe1
+EW 0xE6C40000, 0x0000
+EB 0xE6C40004, 0x19
+EW 0xE6C40008, 0x0030
diff --git a/arch/arm/mach-shmobile/include/mach/head-mackerel.txt b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
new file mode 100644
index 00000000..9f134dfe
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
@@ -0,0 +1,93 @@
+LIST "partner-jet-setup.txt"
+LIST "(C) Copyright 2010 Renesas Solutions Corp"
+LIST "Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"
+
+LIST "RWT Setting"
+EW 0xE6020004, 0xA500
+EW 0xE6030004, 0xA500
+
+LIST "GPIO Setting"
+EB 0xE6051013, 0xA2
+
+LIST "CPG"
+ED 0xE61500C0, 0x00000002
+
+WAIT 1, 0xFE40009C
+
+LIST "FRQCR"
+ED 0xE6150000, 0x2D1305C3
+ED 0xE61500E0, 0x9E40358E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xE61500E4, 0x00002000
+
+WAIT 1, 0xFE40009C
+
+LIST "PLL"
+ED 0xE6150028, 0x00004000
+
+WAIT 1, 0xFE40009C
+
+ED 0xE615002C, 0x93000040
+
+WAIT 1, 0xFE40009C
+
+LIST "SUB/USBClk"
+ED 0xE6150080, 0x00000180
+
+LIST "BSC"
+ED 0xFEC10000, 0x00E0001B
+
+LIST "SBSC1"
+ED 0xFE400354, 0x01AD8000
+ED 0xFE400354, 0x01AD8001
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400008, 0xBCC90151
+ED 0xFE400040, 0x41774113
+ED 0xFE400044, 0x2712E229
+ED 0xFE400048, 0x20C18505
+ED 0xFE40004C, 0x00110209
+ED 0xFE400010, 0x00000087
+
+WAIT 30, 0xFE40009C
+
+ED 0xFE400084, 0x0000003F
+EB 0xFE500000, 0x00
+
+WAIT 5, 0xFE40009C
+
+ED 0xFE400084, 0x0000FF0A
+EB 0xFE500000, 0x00
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400084, 0x00002201
+EB 0xFE500000, 0x00
+ED 0xFE400084, 0x00000302
+EB 0xFE500000, 0x00
+EB 0xFE5C0000, 0x00
+ED 0xFE400008, 0xBCC90159
+ED 0xFE40008C, 0x88800004
+ED 0xFE400094, 0x00000004
+ED 0xFE400028, 0xA55A0032
+ED 0xFE40002C, 0xA55A000C
+ED 0xFE400020, 0xA55A2048
+ED 0xFE400008, 0xBCC90959
+
+LIST "Change CPGA setting"
+ED 0xE61500E0, 0x9E40352E
+ED 0xE6150004, 0x80331050
+
+WAIT 1, 0xFE40009C
+
+ED 0xFE400354, 0x01AD8002
+
+LIST "SCIF0 - Serial port for earlyprintk"
+EB 0xE6053098, 0xe1
+EW 0xE6C40000, 0x0000
+EB 0xE6C40004, 0x19
+EW 0xE6C40008, 0x0030
diff --git a/arch/arm/mach-shmobile/include/mach/io.h b/arch/arm/mach-shmobile/include/mach/io.h
new file mode 100644
index 00000000..7339fe46
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/io.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_IO_H
+#define __ASM_MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(a))
+#define __mem_pci(a) (a)
+
+#endif /* __ASM_MACH_IO_H */
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
new file mode 100644
index 00000000..dcb714f4
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -0,0 +1,18 @@
+#ifndef __ASM_MACH_IRQS_H
+#define __ASM_MACH_IRQS_H
+
+#define NR_IRQS 1024
+
+/* GIC */
+#define gic_spi(nr) ((nr) + 32)
+
+/* INTCA */
+#define evt2irq(evt) (((evt) >> 5) - 16)
+#define irq2evt(irq) (((irq) + 16) << 5)
+
+/* INTCS */
+#define INTCS_VECT_BASE 0x2200
+#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
+#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
+
+#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h
new file mode 100644
index 00000000..ad00c3c2
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/memory.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_MACH_MEMORY_H
+#define __ASM_MACH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(CONFIG_MEMORY_START)
+#define MEM_SIZE UL(CONFIG_MEMORY_SIZE)
+
+/* DMA memory at 0xf6000000 - 0xffdfffff */
+#define CONSISTENT_DMA_SIZE (158 << 20)
+
+#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h
new file mode 100644
index 00000000..db59fdbd
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmc-ap4eb.h
@@ -0,0 +1,29 @@
+#ifndef MMC_AP4EB_H
+#define MMC_AP4EB_H
+
+#define PORT185CR (void __iomem *)0xe60520b9
+#define PORT186CR (void __iomem *)0xe60520ba
+#define PORT187CR (void __iomem *)0xe60520bb
+#define PORT188CR (void __iomem *)0xe60520bc
+
+#define PORTR191_160DR (void __iomem *)0xe6056014
+
+static inline void mmc_init_progress(void)
+{
+ /* Initialise LEDS1-4
+ * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
+ * value: 0x10 - enable output
+ */
+ __raw_writeb(0x10, PORT185CR);
+ __raw_writeb(0x10, PORT186CR);
+ __raw_writeb(0x10, PORT187CR);
+ __raw_writeb(0x10, PORT188CR);
+}
+
+static inline void mmc_update_progress(int n)
+{
+ __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
+ (1 << (25 + n)), PORTR191_160DR);
+}
+
+#endif /* MMC_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmc-mackerel.h b/arch/arm/mach-shmobile/include/mach/mmc-mackerel.h
new file mode 100644
index 00000000..15d3a9ef
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmc-mackerel.h
@@ -0,0 +1,38 @@
+#ifndef MMC_MACKEREL_H
+#define MMC_MACKEREL_H
+
+#define PORT0CR (void __iomem *)0xe6051000
+#define PORT1CR (void __iomem *)0xe6051001
+#define PORT2CR (void __iomem *)0xe6051002
+#define PORT159CR (void __iomem *)0xe605009f
+
+#define PORTR031_000DR (void __iomem *)0xe6055000
+#define PORTL159_128DR (void __iomem *)0xe6054010
+
+static inline void mmc_init_progress(void)
+{
+ /* Initialise LEDS0-3
+ * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control)
+ * value: 0x10 - enable output
+ */
+ __raw_writeb(0x10, PORT0CR);
+ __raw_writeb(0x10, PORT1CR);
+ __raw_writeb(0x10, PORT2CR);
+ __raw_writeb(0x10, PORT159CR);
+}
+
+static inline void mmc_update_progress(int n)
+{
+ unsigned a = 0, b = 0;
+
+ if (n < 3)
+ a = 1 << n;
+ else
+ b = 1 << 31;
+
+ __raw_writel((__raw_readl(PORTR031_000DR) & ~0x7) | a,
+ PORTR031_000DR);
+ __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b,
+ PORTL159_128DR);
+}
+#endif /* MMC_MACKEREL_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmc.h b/arch/arm/mach-shmobile/include/mach/mmc.h
new file mode 100644
index 00000000..21a59db6
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmc.h
@@ -0,0 +1,18 @@
+#ifndef MMC_H
+#define MMC_H
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#include "mach/mmc-ap4eb.h"
+#elif defined(CONFIG_MACH_MACKEREL)
+#include "mach/mmc-mackerel.h"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* MMC_H */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7367.h b/arch/arm/mach-shmobile/include/mach/sh7367.h
new file mode 100644
index 00000000..52d0de68
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7367.h
@@ -0,0 +1,332 @@
+#ifndef __ASM_SH7367_H__
+#define __ASM_SH7367_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* 49-1 -> 49-6 (GPIO) */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+ GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+ GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+ GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+ GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+ GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+ GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+ GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+ GPIO_PORT190, GPIO_PORT191, GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+ GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+ GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+ GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+ GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+ GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+ GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+ GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+ GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+ GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+ GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+ GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
+
+ GPIO_PORT270, GPIO_PORT271, GPIO_PORT272,
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN_PORT48_KEYIN0_PU, GPIO_FN_PORT49_KEYIN1_PU,
+ GPIO_FN_PORT50_KEYIN2_PU, GPIO_FN_PORT55_KEYIN3_PU,
+ GPIO_FN_PORT56_KEYIN4_PU, GPIO_FN_PORT57_KEYIN5_PU,
+ GPIO_FN_PORT58_KEYIN6_PU,
+
+ /* 49-1 (FN) */
+ GPIO_FN_VBUS0, GPIO_FN_CPORT0, GPIO_FN_CPORT1, GPIO_FN_CPORT2,
+ GPIO_FN_CPORT3, GPIO_FN_CPORT4, GPIO_FN_CPORT5, GPIO_FN_CPORT6,
+ GPIO_FN_CPORT7, GPIO_FN_CPORT8, GPIO_FN_CPORT9, GPIO_FN_CPORT10,
+ GPIO_FN_CPORT11, GPIO_FN_SIN2, GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+ GPIO_FN_CPORT13, GPIO_FN_RFSPO4, GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+ GPIO_FN_CPORT15, GPIO_FN_CPORT16, GPIO_FN_CPORT17, GPIO_FN_SOUT2,
+ GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_CPORT19, GPIO_FN_CPORT20,
+ GPIO_FN_RFSPO6, GPIO_FN_CPORT21, GPIO_FN_STATUS0, GPIO_FN_CPORT22,
+ GPIO_FN_STATUS1, GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+ GPIO_FN_MPORT0, GPIO_FN_MPORT1, GPIO_FN_B_SYNLD1, GPIO_FN_B_SYNLD2,
+ GPIO_FN_XMAINPS, GPIO_FN_XDIVPS, GPIO_FN_XIDRST, GPIO_FN_IDCLK,
+ GPIO_FN_IDIO, GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD,
+ GPIO_FN_M02_BERDAT, GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+ GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+
+ /* 49-2 (FN) */
+ GPIO_FN_HSU_IQ_AGC6, GPIO_FN_MFG2_IN2, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_HSU_IQ_AGC5, GPIO_FN_MFG2_IN1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_HSU_IQ_AGC4, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_HSU_IQ_AGC3, GPIO_FN_MFG2_OUT1, GPIO_FN_MSIOF2_RSCK,
+ GPIO_FN_HSU_IQ_AGC2, GPIO_FN_PORT42_KEYOUT0,
+ GPIO_FN_HSU_IQ_AGC1, GPIO_FN_PORT43_KEYOUT1,
+ GPIO_FN_HSU_IQ_AGC0, GPIO_FN_PORT44_KEYOUT2,
+ GPIO_FN_HSU_IQ_AGC_ST, GPIO_FN_PORT45_KEYOUT3,
+ GPIO_FN_HSU_IQ_PDO, GPIO_FN_PORT46_KEYOUT4,
+ GPIO_FN_HSU_IQ_PYO, GPIO_FN_PORT47_KEYOUT5,
+ GPIO_FN_HSU_EN_TXMUX_G3MO, GPIO_FN_PORT48_KEYIN0,
+ GPIO_FN_HSU_I_TXMUX_G3MO, GPIO_FN_PORT49_KEYIN1,
+ GPIO_FN_HSU_Q_TXMUX_G3MO, GPIO_FN_PORT50_KEYIN2,
+ GPIO_FN_HSU_SYO, GPIO_FN_PORT51_MSIOF2_TSYNC,
+ GPIO_FN_HSU_SDO, GPIO_FN_PORT52_MSIOF2_TSCK,
+ GPIO_FN_HSU_TGTTI_G3MO, GPIO_FN_PORT53_MSIOF2_TXD,
+ GPIO_FN_B_TIME_STAMP, GPIO_FN_PORT54_MSIOF2_RXD,
+ GPIO_FN_HSU_SDI, GPIO_FN_PORT55_KEYIN3,
+ GPIO_FN_HSU_SCO, GPIO_FN_PORT56_KEYIN4,
+ GPIO_FN_HSU_DREQ, GPIO_FN_PORT57_KEYIN5,
+ GPIO_FN_HSU_DACK, GPIO_FN_PORT58_KEYIN6,
+ GPIO_FN_HSU_CLK61M, GPIO_FN_PORT59_MSIOF2_SS1,
+ GPIO_FN_HSU_XRST, GPIO_FN_PORT60_MSIOF2_SS2,
+ GPIO_FN_PCMCLKO, GPIO_FN_SYNC8KO, GPIO_FN_DNPCM_A, GPIO_FN_UPPCM_A,
+ GPIO_FN_XTALB1L,
+ GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_GPS_AGC2, GPIO_FN_SCIFA0_SCK,
+ GPIO_FN_GPS_AGC3, GPIO_FN_SCIFA0_TXD,
+ GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_GPS_PWRD, GPIO_FN_SCIFA0_CTS,
+ GPIO_FN_GPS_IM, GPIO_FN_GPS_IS, GPIO_FN_GPS_QM, GPIO_FN_GPS_QS,
+ GPIO_FN_SIUBOMC, GPIO_FN_TPU2TO0,
+ GPIO_FN_SIUCKB, GPIO_FN_TPU2TO1,
+ GPIO_FN_SIUBOLR, GPIO_FN_BBIF2_TSYNC, GPIO_FN_TPU2TO2,
+ GPIO_FN_SIUBOBT, GPIO_FN_BBIF2_TSCK, GPIO_FN_TPU2TO3,
+ GPIO_FN_SIUBOSLD, GPIO_FN_BBIF2_TXD, GPIO_FN_TPU3TO0,
+ GPIO_FN_SIUBILR, GPIO_FN_TPU3TO1,
+ GPIO_FN_SIUBIBT, GPIO_FN_TPU3TO2,
+ GPIO_FN_SIUBISLD, GPIO_FN_TPU3TO3,
+ GPIO_FN_NMI, GPIO_FN_TPU4TO0,
+ GPIO_FN_DNPCM_M, GPIO_FN_TPU4TO1, GPIO_FN_TPU4TO2, GPIO_FN_TPU4TO3,
+ GPIO_FN_IRQ_TMPB,
+ GPIO_FN_PWEN, GPIO_FN_MFG1_OUT1,
+ GPIO_FN_OVCN, GPIO_FN_MFG1_IN1,
+ GPIO_FN_OVCN2, GPIO_FN_MFG1_IN2,
+
+ /* 49-3 (FN) */
+ GPIO_FN_RFSPO1, GPIO_FN_RFSPO2, GPIO_FN_RFSPO3, GPIO_FN_PORT93_VIO_CKO2,
+ GPIO_FN_USBTERM, GPIO_FN_EXTLP, GPIO_FN_IDIN,
+ GPIO_FN_SCIFA5_CTS, GPIO_FN_MFG0_IN1,
+ GPIO_FN_SCIFA5_RTS, GPIO_FN_MFG0_IN2,
+ GPIO_FN_SCIFA5_RXD,
+ GPIO_FN_SCIFA5_TXD,
+ GPIO_FN_SCIFA5_SCK, GPIO_FN_MFG0_OUT1,
+ GPIO_FN_A0_EA0, GPIO_FN_BS,
+ GPIO_FN_A14_EA14, GPIO_FN_PORT102_KEYOUT0,
+ GPIO_FN_A15_EA15, GPIO_FN_PORT103_KEYOUT1, GPIO_FN_DV_CLKOL,
+ GPIO_FN_A16_EA16, GPIO_FN_PORT104_KEYOUT2,
+ GPIO_FN_DV_VSYNCL, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17_EA17, GPIO_FN_PORT105_KEYOUT3,
+ GPIO_FN_DV_HSYNCL, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18_EA18, GPIO_FN_PORT106_KEYOUT4,
+ GPIO_FN_DV_DL0, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19_EA19, GPIO_FN_PORT107_KEYOUT5,
+ GPIO_FN_DV_DL1, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20_EA20, GPIO_FN_PORT108_KEYIN0,
+ GPIO_FN_DV_DL2, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21_EA21, GPIO_FN_PORT109_KEYIN1,
+ GPIO_FN_DV_DL3, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22_EA22, GPIO_FN_PORT110_KEYIN2,
+ GPIO_FN_DV_DL4, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23_EA23, GPIO_FN_PORT111_KEYIN3,
+ GPIO_FN_DV_DL5, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24_EA24, GPIO_FN_PORT112_KEYIN4,
+ GPIO_FN_DV_DL6, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25_EA25, GPIO_FN_PORT113_KEYIN5,
+ GPIO_FN_DV_DL7, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_PORT113_KEYIN6, GPIO_FN_DV_CLKIL,
+ GPIO_FN_D0_ED0_NAF0, GPIO_FN_D1_ED1_NAF1, GPIO_FN_D2_ED2_NAF2,
+ GPIO_FN_D3_ED3_NAF3, GPIO_FN_D4_ED4_NAF4, GPIO_FN_D5_ED5_NAF5,
+ GPIO_FN_D6_ED6_NAF6, GPIO_FN_D7_ED7_NAF7, GPIO_FN_D8_ED8_NAF8,
+ GPIO_FN_D9_ED9_NAF9, GPIO_FN_D10_ED10_NAF10, GPIO_FN_D11_ED11_NAF11,
+ GPIO_FN_D12_ED12_NAF12, GPIO_FN_D13_ED13_NAF13,
+ GPIO_FN_D14_ED14_NAF14, GPIO_FN_D15_ED15_NAF15,
+ GPIO_FN_CS4, GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_FCE1,
+ GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_FCE0, GPIO_FN_CS6A,
+ GPIO_FN_DACK0, GPIO_FN_WAIT, GPIO_FN_DREQ0, GPIO_FN_RD_XRD,
+ GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_WE0_XWR0_FWE,
+ GPIO_FN_WE1_XWR1, GPIO_FN_FRB, GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT, GPIO_FN_NBRST,
+
+ /* 49-4 (FN) */
+ GPIO_FN_RFSPO0, GPIO_FN_PORT146_VIO_CKO2, GPIO_FN_TSTMD,
+ GPIO_FN_VIO_VD, GPIO_FN_VIO_HD,
+ GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
+ GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
+ GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
+ GPIO_FN_VIO_D15, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_MFG3_IN1, GPIO_FN_MFG3_IN2,
+ GPIO_FN_M9_SLCD_A01, GPIO_FN_MFG3_OUT1, GPIO_FN_TPU0TO0,
+ GPIO_FN_M10_SLCD_CK1, GPIO_FN_MFG4_IN1, GPIO_FN_TPU0TO1,
+ GPIO_FN_M11_SLCD_SO1, GPIO_FN_MFG4_IN2, GPIO_FN_TPU0TO2,
+ GPIO_FN_M12_SLCD_CE1, GPIO_FN_MFG4_OUT1, GPIO_FN_TPU0TO3,
+ GPIO_FN_LCDD0, GPIO_FN_PORT175_KEYOUT0, GPIO_FN_DV_D0,
+ GPIO_FN_SIUCKA, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_LCDD1, GPIO_FN_PORT176_KEYOUT1, GPIO_FN_DV_D1,
+ GPIO_FN_SIUAOLR, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT177_KEYOUT2, GPIO_FN_DV_D2,
+ GPIO_FN_SIUAOBT, GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT178_KEYOUT3, GPIO_FN_DV_D3,
+ GPIO_FN_SIUAOSLD, GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT179_KEYOUT4, GPIO_FN_DV_D4,
+ GPIO_FN_SIUAISPD, GPIO_FN_MFG1_OUT2,
+ GPIO_FN_LCDD5, GPIO_FN_PORT180_KEYOUT5, GPIO_FN_DV_D5,
+ GPIO_FN_SIUAILR, GPIO_FN_MFG2_OUT2,
+ GPIO_FN_LCDD6, GPIO_FN_DV_D6,
+ GPIO_FN_SIUAIBT, GPIO_FN_MFG3_OUT2, GPIO_FN_XWR2,
+ GPIO_FN_LCDD7, GPIO_FN_DV_D7,
+ GPIO_FN_SIUAISLD, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+ GPIO_FN_LCDD8, GPIO_FN_DV_D8, GPIO_FN_D16, GPIO_FN_ED16,
+ GPIO_FN_LCDD9, GPIO_FN_DV_D9, GPIO_FN_D17, GPIO_FN_ED17,
+ GPIO_FN_LCDD10, GPIO_FN_DV_D10, GPIO_FN_D18, GPIO_FN_ED18,
+ GPIO_FN_LCDD11, GPIO_FN_DV_D11, GPIO_FN_D19, GPIO_FN_ED19,
+ GPIO_FN_LCDD12, GPIO_FN_DV_D12, GPIO_FN_D20, GPIO_FN_ED20,
+ GPIO_FN_LCDD13, GPIO_FN_DV_D13, GPIO_FN_D21, GPIO_FN_ED21,
+ GPIO_FN_LCDD14, GPIO_FN_DV_D14, GPIO_FN_D22, GPIO_FN_ED22,
+ GPIO_FN_LCDD15, GPIO_FN_DV_D15, GPIO_FN_D23, GPIO_FN_ED23,
+ GPIO_FN_LCDD16, GPIO_FN_DV_HSYNC, GPIO_FN_D24, GPIO_FN_ED24,
+ GPIO_FN_LCDD17, GPIO_FN_DV_VSYNC, GPIO_FN_D25, GPIO_FN_ED25,
+ GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_MSIOF0L_TSCK,
+ GPIO_FN_D26, GPIO_FN_ED26,
+ GPIO_FN_LCDD19, GPIO_FN_MSIOF0L_TSYNC,
+ GPIO_FN_D27, GPIO_FN_ED27,
+ GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0,
+ GPIO_FN_D28, GPIO_FN_ED28,
+ GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1,
+ GPIO_FN_D29, GPIO_FN_ED29,
+ GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_SS1,
+ GPIO_FN_D30, GPIO_FN_ED30,
+ GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_SS2,
+ GPIO_FN_D31, GPIO_FN_ED31,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_DV_CKO, GPIO_FN_SIUAOSPD,
+ GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_RSYNC,
+
+
+ /* 49-5 (FN) */
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_RSCK,
+ GPIO_FN_LCDCSYN, GPIO_FN_LCDCSYN2, GPIO_FN_DV_CKI,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_MSIOF0L_RXD,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_MSIOF0L_TXD,
+ GPIO_FN_VIO_DR0, GPIO_FN_VIO_DR1, GPIO_FN_VIO_DR2, GPIO_FN_VIO_DR3,
+ GPIO_FN_VIO_DR4, GPIO_FN_VIO_DR5, GPIO_FN_VIO_DR6, GPIO_FN_VIO_DR7,
+ GPIO_FN_VIO_VDR, GPIO_FN_VIO_HDR,
+ GPIO_FN_VIO_CLKR, GPIO_FN_VIO_CKOR,
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_GPS_PGFA0,
+ GPIO_FN_SCIFA1_SCK, GPIO_FN_GPS_PGFA1,
+ GPIO_FN_SCIFA1_RTS, GPIO_FN_GPS_EPPSINMON,
+ GPIO_FN_SCIFA1_RXD, GPIO_FN_SCIFA1_CTS,
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA1_TXD2, GPIO_FN_GPS_TXD,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA1_CTS2, GPIO_FN_I2C_SDA2,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA1_SCK2,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA1_RXD2, GPIO_FN_GPS_RXD,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA1_RTS2,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_I2C_SCL2,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+ GPIO_FN_MSIOF1_SS2,
+ GPIO_FN_PORT236_IROUT, GPIO_FN_IRDA_OUT,
+ GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
+ GPIO_FN_TPU1TO0, GPIO_FN_TS_SPSYNC3,
+ GPIO_FN_TPU1TO1, GPIO_FN_TS_SDAT3,
+ GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT241_MSIOF2_SS1,
+ GPIO_FN_TPU1TO3, GPIO_FN_PORT242_MSIOF2_TSCK,
+ GPIO_FN_M13_BSW, GPIO_FN_PORT243_MSIOF2_TSYNC,
+ GPIO_FN_M14_GSW, GPIO_FN_PORT244_MSIOF2_TXD,
+ GPIO_FN_PORT245_IROUT, GPIO_FN_M15_RSW,
+ GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1,
+ GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1,
+ GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT248_MSIOF2_SS2,
+ GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT249_MSIOF2_RXD,
+ GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+ GPIO_FN_SDHICLK0, GPIO_FN_TCK2,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0, GPIO_FN_TMS2,
+ GPIO_FN_SDHID0_1, GPIO_FN_TDO2,
+ GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+ GPIO_FN_SDHID0_3, GPIO_FN_RTCK2,
+
+ /* 49-6 (FN) */
+ GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+ GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+ GPIO_FN_SDHICLK1, GPIO_FN_TCK3,
+ GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2,
+ GPIO_FN_TS_SPSYNC2, GPIO_FN_TMS3,
+ GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_AO2,
+ GPIO_FN_TS_SDAT2, GPIO_FN_TDO3,
+ GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2,
+ GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+ GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2,
+ GPIO_FN_TS_SCK2, GPIO_FN_RTCK3,
+ GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+ GPIO_FN_SDHICLK2, GPIO_FN_SCIFB_SCK,
+ GPIO_FN_SDHID2_0, GPIO_FN_SCIFB_TXD,
+ GPIO_FN_SDHID2_1, GPIO_FN_SCIFB_CTS,
+ GPIO_FN_SDHID2_2, GPIO_FN_SCIFB_RXD,
+ GPIO_FN_SDHID2_3, GPIO_FN_SCIFB_RTS,
+ GPIO_FN_SDHICMD2,
+ GPIO_FN_RESETOUTS,
+ GPIO_FN_DIVLOCK,
+};
+
+#endif /* __ASM_SH7367_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
new file mode 100644
index 00000000..df20d767
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __ASM_SH7372_H__
+#define __ASM_SH7372_H__
+
+#include <linux/sh_clk.h>
+
+/*
+ * Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* PORT */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118, GPIO_PORT119,
+
+ GPIO_PORT120, GPIO_PORT121, GPIO_PORT122, GPIO_PORT123, GPIO_PORT124,
+ GPIO_PORT125, GPIO_PORT126, GPIO_PORT127, GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+ GPIO_PORT165, GPIO_PORT166, GPIO_PORT167, GPIO_PORT168, GPIO_PORT169,
+
+ GPIO_PORT170, GPIO_PORT171, GPIO_PORT172, GPIO_PORT173, GPIO_PORT174,
+ GPIO_PORT175, GPIO_PORT176, GPIO_PORT177, GPIO_PORT178, GPIO_PORT179,
+
+ GPIO_PORT180, GPIO_PORT181, GPIO_PORT182, GPIO_PORT183, GPIO_PORT184,
+ GPIO_PORT185, GPIO_PORT186, GPIO_PORT187, GPIO_PORT188, GPIO_PORT189,
+
+ GPIO_PORT190,
+
+ /* IRQ */
+ GPIO_FN_IRQ0_6, /* PORT 6 */
+ GPIO_FN_IRQ0_162, /* PORT 162 */
+ GPIO_FN_IRQ1, /* PORT 12 */
+ GPIO_FN_IRQ2_4, /* PORT 4 */
+ GPIO_FN_IRQ2_5, /* PORT 5 */
+ GPIO_FN_IRQ3_8, /* PORT 8 */
+ GPIO_FN_IRQ3_16, /* PORT 16 */
+ GPIO_FN_IRQ4_17, /* PORT 17 */
+ GPIO_FN_IRQ4_163, /* PORT 163 */
+ GPIO_FN_IRQ5, /* PORT 18 */
+ GPIO_FN_IRQ6_39, /* PORT 39 */
+ GPIO_FN_IRQ6_164, /* PORT 164 */
+ GPIO_FN_IRQ7_40, /* PORT 40 */
+ GPIO_FN_IRQ7_167, /* PORT 167 */
+ GPIO_FN_IRQ8_41, /* PORT 41 */
+ GPIO_FN_IRQ8_168, /* PORT 168 */
+ GPIO_FN_IRQ9_42, /* PORT 42 */
+ GPIO_FN_IRQ9_169, /* PORT 169 */
+ GPIO_FN_IRQ10, /* PORT 65 */
+ GPIO_FN_IRQ11, /* PORT 67 */
+ GPIO_FN_IRQ12_80, /* PORT 80 */
+ GPIO_FN_IRQ12_137, /* PORT 137 */
+ GPIO_FN_IRQ13_81, /* PORT 81 */
+ GPIO_FN_IRQ13_145, /* PORT 145 */
+ GPIO_FN_IRQ14_82, /* PORT 82 */
+ GPIO_FN_IRQ14_146, /* PORT 146 */
+ GPIO_FN_IRQ15_83, /* PORT 83 */
+ GPIO_FN_IRQ15_147, /* PORT 147 */
+ GPIO_FN_IRQ16_84, /* PORT 84 */
+ GPIO_FN_IRQ16_170, /* PORT 170 */
+ GPIO_FN_IRQ17, /* PORT 85 */
+ GPIO_FN_IRQ18, /* PORT 86 */
+ GPIO_FN_IRQ19, /* PORT 87 */
+ GPIO_FN_IRQ20, /* PORT 92 */
+ GPIO_FN_IRQ21, /* PORT 93 */
+ GPIO_FN_IRQ22, /* PORT 94 */
+ GPIO_FN_IRQ23, /* PORT 95 */
+ GPIO_FN_IRQ24, /* PORT 112 */
+ GPIO_FN_IRQ25, /* PORT 119 */
+ GPIO_FN_IRQ26_121, /* PORT 121 */
+ GPIO_FN_IRQ26_172, /* PORT 172 */
+ GPIO_FN_IRQ27_122, /* PORT 122 */
+ GPIO_FN_IRQ27_180, /* PORT 180 */
+ GPIO_FN_IRQ28_123, /* PORT 123 */
+ GPIO_FN_IRQ28_181, /* PORT 181 */
+ GPIO_FN_IRQ29_129, /* PORT 129 */
+ GPIO_FN_IRQ29_182, /* PORT 182 */
+ GPIO_FN_IRQ30_130, /* PORT 130 */
+ GPIO_FN_IRQ30_183, /* PORT 183 */
+ GPIO_FN_IRQ31_138, /* PORT 138 */
+ GPIO_FN_IRQ31_184, /* PORT 184 */
+
+ /*
+ * MSIOF0 (PORT 36, 37, 38, 39
+ * 40, 41, 42, 43, 44, 45)
+ */
+ GPIO_FN_MSIOF0_TSYNC, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_MSIOF0_RXD, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_MSIOF0_RSYNC, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_MSIOF0_MCK1, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_MSIOF0_SS2, GPIO_FN_MSIOF0_TXD,
+
+ /*
+ * MSIOF1 (PORT 39, 40, 41, 42, 43, 44
+ * 84, 85, 86, 87, 88, 89, 90, 91, 92, 93)
+ */
+ GPIO_FN_MSIOF1_TSCK_39, GPIO_FN_MSIOF1_TSYNC_40,
+ GPIO_FN_MSIOF1_TSCK_88, GPIO_FN_MSIOF1_TSYNC_89,
+ GPIO_FN_MSIOF1_TXD_41, GPIO_FN_MSIOF1_RXD_42,
+ GPIO_FN_MSIOF1_TXD_90, GPIO_FN_MSIOF1_RXD_91,
+ GPIO_FN_MSIOF1_SS1_43, GPIO_FN_MSIOF1_SS2_44,
+ GPIO_FN_MSIOF1_SS1_92, GPIO_FN_MSIOF1_SS2_93,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_MSIOF1_RSYNC,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_MSIOF1_MCK1,
+
+ /*
+ * MSIOF2 (PORT 134, 135, 136, 137, 138, 139
+ * 148, 149, 150, 151)
+ */
+ GPIO_FN_MSIOF2_RSCK, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_MSIOF2_MCK0, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_MSIOF2_SS1, GPIO_FN_MSIOF2_SS2,
+ GPIO_FN_MSIOF2_TSYNC, GPIO_FN_MSIOF2_TSCK,
+ GPIO_FN_MSIOF2_RXD, GPIO_FN_MSIOF2_TXD,
+
+ /* MSIOF3 (PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+ GPIO_FN_BBIF1_RXD, GPIO_FN_BBIF1_TSYNC,
+ GPIO_FN_BBIF1_TSCK, GPIO_FN_BBIF1_TXD,
+ GPIO_FN_BBIF1_RSCK, GPIO_FN_BBIF1_RSYNC,
+ GPIO_FN_BBIF1_FLOW, GPIO_FN_BB_RX_FLOW_N,
+
+ /* MSIOF4 (PORT 0, 1, 2, 3) */
+ GPIO_FN_BBIF2_TSCK1, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_BBIF2_TXD1, GPIO_FN_BBIF2_RXD,
+
+ /* FSI (PORT 4, 5, 6, 7, 8, 9, 10, 11, 15) */
+ GPIO_FN_FSIACK, GPIO_FN_FSIBCK,
+ GPIO_FN_FSIAILR, GPIO_FN_FSIAIBT,
+ GPIO_FN_FSIAISLD, GPIO_FN_FSIAOMC,
+ GPIO_FN_FSIAOLR, GPIO_FN_FSIAOBT,
+ GPIO_FN_FSIAOSLD, GPIO_FN_FSIASPDIF_11,
+ GPIO_FN_FSIASPDIF_15,
+
+ /* FMSI (PORT 12, 13, 14, 15, 16, 17, 18, 65) */
+ GPIO_FN_FMSOCK, GPIO_FN_FMSOOLR,
+ GPIO_FN_FMSIOLR, GPIO_FN_FMSOOBT,
+ GPIO_FN_FMSIOBT, GPIO_FN_FMSOSLD,
+ GPIO_FN_FMSOILR, GPIO_FN_FMSIILR,
+ GPIO_FN_FMSOIBT, GPIO_FN_FMSIIBT,
+ GPIO_FN_FMSISLD, GPIO_FN_FMSICK,
+
+ /* SCIFA0 (PORT 152, 153, 156, 157, 158) */
+ GPIO_FN_SCIFA0_TXD, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_SCIFA0_SCK, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_SCIFA0_CTS,
+
+ /* SCIFA1 (PORT 154, 155, 159, 160, 161) */
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_SCIFA1_RXD,
+ GPIO_FN_SCIFA1_SCK, GPIO_FN_SCIFA1_RTS,
+ GPIO_FN_SCIFA1_CTS,
+
+ /* SCIFA2 (PORT 94, 95, 96, 97, 98) */
+ GPIO_FN_SCIFA2_CTS1, GPIO_FN_SCIFA2_RTS1,
+ GPIO_FN_SCIFA2_TXD1, GPIO_FN_SCIFA2_RXD1,
+ GPIO_FN_SCIFA2_SCK1,
+
+ /* SCIFA3 (PORT 43, 44,
+ 140, 141, 142, 143, 144) */
+ GPIO_FN_SCIFA3_CTS_43, GPIO_FN_SCIFA3_CTS_140,
+ GPIO_FN_SCIFA3_RTS_44, GPIO_FN_SCIFA3_RTS_141,
+ GPIO_FN_SCIFA3_SCK, GPIO_FN_SCIFA3_TXD,
+ GPIO_FN_SCIFA3_RXD,
+
+ /* SCIFA4 (PORT 5, 6) */
+ GPIO_FN_SCIFA4_RXD, GPIO_FN_SCIFA4_TXD,
+
+ /* SCIFA5 (PORT 8, 12) */
+ GPIO_FN_SCIFA5_RXD, GPIO_FN_SCIFA5_TXD,
+
+ /* SCIFB (PORT 162, 163, 164, 165, 166) */
+ GPIO_FN_SCIFB_SCK, GPIO_FN_SCIFB_RTS,
+ GPIO_FN_SCIFB_CTS, GPIO_FN_SCIFB_TXD,
+ GPIO_FN_SCIFB_RXD,
+
+ /*
+ * CEU (PORT 16, 17,
+ * 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ * 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ * 120)
+ */
+ GPIO_FN_VIO_HD, GPIO_FN_VIO_CKO1, GPIO_FN_VIO_CKO2,
+ GPIO_FN_VIO_VD, GPIO_FN_VIO_CLK, GPIO_FN_VIO_FIELD,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_VIO_D0, GPIO_FN_VIO_D1, GPIO_FN_VIO_D2,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D4, GPIO_FN_VIO_D5,
+ GPIO_FN_VIO_D6, GPIO_FN_VIO_D7, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D9, GPIO_FN_VIO_D10, GPIO_FN_VIO_D11,
+ GPIO_FN_VIO_D12, GPIO_FN_VIO_D13, GPIO_FN_VIO_D14,
+ GPIO_FN_VIO_D15,
+
+ /* USB0 (PORT 113, 114, 115, 116, 117, 167) */
+ GPIO_FN_IDIN_0, GPIO_FN_EXTLP_0,
+ GPIO_FN_OVCN2_0, GPIO_FN_PWEN_0,
+ GPIO_FN_OVCN_0, GPIO_FN_VBUS0_0,
+
+ /* USB1 (PORT 18, 113, 114, 115, 116, 117, 138, 162, 168) */
+ GPIO_FN_IDIN_1_18, GPIO_FN_IDIN_1_113,
+ GPIO_FN_PWEN_1_115, GPIO_FN_PWEN_1_138,
+ GPIO_FN_OVCN_1_114, GPIO_FN_OVCN_1_162,
+ GPIO_FN_EXTLP_1, GPIO_FN_OVCN2_1,
+ GPIO_FN_VBUS0_1,
+
+ /* GPIO (PORT 41, 42, 43, 44) */
+ GPIO_FN_GPI0, GPIO_FN_GPI1, GPIO_FN_GPO0, GPIO_FN_GPO1,
+
+ /*
+ * BSC (PORT 19,
+ * 20, 21, 22, 25, 26, 27, 28, 29,
+ * 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ * 40, 41, 42, 43, 44, 45,
+ * 62, 63, 64, 65, 66, 67,
+ * 71, 72, 74, 75)
+ */
+ GPIO_FN_BS, GPIO_FN_WE1,
+ GPIO_FN_CKO, GPIO_FN_WAIT, GPIO_FN_RDWR,
+
+ GPIO_FN_A0, GPIO_FN_A1, GPIO_FN_A2, GPIO_FN_A3,
+ GPIO_FN_A6, GPIO_FN_A7, GPIO_FN_A8, GPIO_FN_A9,
+ GPIO_FN_A10, GPIO_FN_A11, GPIO_FN_A12, GPIO_FN_A13,
+ GPIO_FN_A14, GPIO_FN_A15, GPIO_FN_A16, GPIO_FN_A17,
+ GPIO_FN_A18, GPIO_FN_A19, GPIO_FN_A20, GPIO_FN_A21,
+ GPIO_FN_A22, GPIO_FN_A23, GPIO_FN_A24, GPIO_FN_A25,
+ GPIO_FN_A26,
+
+ GPIO_FN_CS0, GPIO_FN_CS2, GPIO_FN_CS4,
+ GPIO_FN_CS5A, GPIO_FN_CS5B, GPIO_FN_CS6A,
+
+ /*
+ * BSC/FLCTL (PORT 23, 24,
+ * 46, 47, 48, 49,
+ * 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ * 60, 61, 69, 70)
+ */
+ GPIO_FN_RD_FSC, GPIO_FN_WE0_FWE,
+ GPIO_FN_A4_FOE, GPIO_FN_A5_FCDE,
+ GPIO_FN_D0_NAF0, GPIO_FN_D1_NAF1, GPIO_FN_D2_NAF2,
+ GPIO_FN_D3_NAF3, GPIO_FN_D4_NAF4, GPIO_FN_D5_NAF5,
+ GPIO_FN_D6_NAF6, GPIO_FN_D7_NAF7, GPIO_FN_D8_NAF8,
+ GPIO_FN_D9_NAF9, GPIO_FN_D10_NAF10, GPIO_FN_D11_NAF11,
+ GPIO_FN_D12_NAF12, GPIO_FN_D13_NAF13, GPIO_FN_D14_NAF14,
+ GPIO_FN_D15_NAF15,
+
+ /*
+ * MMCIF(1) (PORT 84, 85, 86, 87, 88, 89,
+ * 90, 91, 92, 99)
+ */
+ GPIO_FN_MMCD0_0, GPIO_FN_MMCD0_1, GPIO_FN_MMCD0_2,
+ GPIO_FN_MMCD0_3, GPIO_FN_MMCD0_4, GPIO_FN_MMCD0_5,
+ GPIO_FN_MMCD0_6, GPIO_FN_MMCD0_7,
+ GPIO_FN_MMCCMD0, GPIO_FN_MMCCLK0,
+
+ /* MMCIF(2) (PORT 54, 55, 56, 57, 58, 59, 60, 61, 66, 67) */
+ GPIO_FN_MMCD1_0, GPIO_FN_MMCD1_1, GPIO_FN_MMCD1_2,
+ GPIO_FN_MMCD1_3, GPIO_FN_MMCD1_4, GPIO_FN_MMCD1_5,
+ GPIO_FN_MMCD1_6, GPIO_FN_MMCD1_7,
+ GPIO_FN_MMCCLK1, GPIO_FN_MMCCMD1,
+
+ /* SPU2 (PORT 65) */
+ GPIO_FN_VINT_I,
+
+ /* FLCTL (PORT 66, 68, 73) */
+ GPIO_FN_FCE1, GPIO_FN_FCE0, GPIO_FN_FRB,
+
+ /* HSI (PORT 76, 77, 78, 79, 80, 81, 82, 83) */
+ GPIO_FN_GP_RX_FLAG, GPIO_FN_GP_RX_DATA, GPIO_FN_GP_TX_READY,
+ GPIO_FN_GP_RX_WAKE, GPIO_FN_MP_TX_FLAG, GPIO_FN_MP_TX_DATA,
+ GPIO_FN_MP_RX_READY, GPIO_FN_MP_TX_WAKE,
+
+ /*
+ * MFI (PORT 76, 77, 78, 79,
+ * 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ * 90, 91, 92, 93, 94, 95, 96, 97, 98, 99)
+ */
+ GPIO_FN_MFIv6, /* see MSEL4CR 6 */
+ GPIO_FN_MFIv4, /* see MSEL4CR 6 */
+
+ GPIO_FN_MEMC_CS0, GPIO_FN_MEMC_BUSCLK_MEMC_A0,
+ GPIO_FN_MEMC_CS1_MEMC_A1, GPIO_FN_MEMC_ADV_MEMC_DREQ0,
+ GPIO_FN_MEMC_WAIT_MEMC_DREQ1, GPIO_FN_MEMC_NOE,
+ GPIO_FN_MEMC_NWE, GPIO_FN_MEMC_INT,
+
+ GPIO_FN_MEMC_AD0, GPIO_FN_MEMC_AD1, GPIO_FN_MEMC_AD2,
+ GPIO_FN_MEMC_AD3, GPIO_FN_MEMC_AD4, GPIO_FN_MEMC_AD5,
+ GPIO_FN_MEMC_AD6, GPIO_FN_MEMC_AD7, GPIO_FN_MEMC_AD8,
+ GPIO_FN_MEMC_AD9, GPIO_FN_MEMC_AD10, GPIO_FN_MEMC_AD11,
+ GPIO_FN_MEMC_AD12, GPIO_FN_MEMC_AD13, GPIO_FN_MEMC_AD14,
+ GPIO_FN_MEMC_AD15,
+
+ /* SIM (PORT 94, 95, 98) */
+ GPIO_FN_SIM_RST, GPIO_FN_SIM_CLK, GPIO_FN_SIM_D,
+
+ /* TPU (PORT 93, 99, 112, 160, 161) */
+ GPIO_FN_TPU0TO0, GPIO_FN_TPU0TO1,
+ GPIO_FN_TPU0TO2_93, GPIO_FN_TPU0TO2_99,
+ GPIO_FN_TPU0TO3,
+
+ /* I2C2 (PORT 110, 111) */
+ GPIO_FN_I2C_SCL2, GPIO_FN_I2C_SDA2,
+
+ /* I2C3(1) (PORT 114, 115) */
+ GPIO_FN_I2C_SCL3, GPIO_FN_I2C_SDA3,
+
+ /* I2C3(2) (PORT 137, 145) */
+ GPIO_FN_I2C_SCL3S, GPIO_FN_I2C_SDA3S,
+
+ /* I2C4(2) (PORT 116, 117) */
+ GPIO_FN_I2C_SCL4, GPIO_FN_I2C_SDA4,
+
+ /* I2C4(2) (PORT 146, 147) */
+ GPIO_FN_I2C_SCL4S, GPIO_FN_I2C_SDA4S,
+
+ /*
+ * KEYSC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ * 130, 131, 132, 133, 134, 135, 136)
+ */
+ GPIO_FN_KEYOUT0, GPIO_FN_KEYIN0_121, GPIO_FN_KEYIN0_136,
+ GPIO_FN_KEYOUT1, GPIO_FN_KEYIN1_122, GPIO_FN_KEYIN1_135,
+ GPIO_FN_KEYOUT2, GPIO_FN_KEYIN2_123, GPIO_FN_KEYIN2_134,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYIN3_124, GPIO_FN_KEYIN3_133,
+ GPIO_FN_KEYOUT4, GPIO_FN_KEYIN4,
+ GPIO_FN_KEYOUT5, GPIO_FN_KEYIN5,
+ GPIO_FN_KEYOUT6, GPIO_FN_KEYIN6,
+ GPIO_FN_KEYOUT7, GPIO_FN_KEYIN7,
+
+ /*
+ * LCDC (PORT 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ * 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ * 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ * 150, 151)
+ */
+ GPIO_FN_LCDC0_SELECT, /* LCDC 0 */
+ GPIO_FN_LCDC1_SELECT, /* LCDC 1 */
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDVSYN,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_LCDRD,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_LCDLCLK,
+ GPIO_FN_LCDDON,
+
+ GPIO_FN_LCDD0, GPIO_FN_LCDD1, GPIO_FN_LCDD2, GPIO_FN_LCDD3,
+ GPIO_FN_LCDD4, GPIO_FN_LCDD5, GPIO_FN_LCDD6, GPIO_FN_LCDD7,
+ GPIO_FN_LCDD8, GPIO_FN_LCDD9, GPIO_FN_LCDD10, GPIO_FN_LCDD11,
+ GPIO_FN_LCDD12, GPIO_FN_LCDD13, GPIO_FN_LCDD14, GPIO_FN_LCDD15,
+ GPIO_FN_LCDD16, GPIO_FN_LCDD17, GPIO_FN_LCDD18, GPIO_FN_LCDD19,
+ GPIO_FN_LCDD20, GPIO_FN_LCDD21, GPIO_FN_LCDD22, GPIO_FN_LCDD23,
+
+ /* IRDA (PORT 139, 140, 141, 142) */
+ GPIO_FN_IRDA_OUT, GPIO_FN_IRDA_IN, GPIO_FN_IRDA_FIRSEL,
+ GPIO_FN_IROUT_139, GPIO_FN_IROUT_140,
+
+ /* TSIF1 (PORT 156, 157, 158, 159) */
+ GPIO_FN_TS0_1SELECT, /* TSIF0 - 1 select */
+ GPIO_FN_TS0_2SELECT, /* TSIF0 - 2 select */
+ GPIO_FN_TS1_1SELECT, /* TSIF1 - 1 select */
+ GPIO_FN_TS1_2SELECT, /* TSIF1 - 2 select */
+
+ GPIO_FN_TS_SPSYNC1, GPIO_FN_TS_SDAT1,
+ GPIO_FN_TS_SDEN1, GPIO_FN_TS_SCK1,
+
+ /* TSIF2 (PORT 137, 145, 146, 147) */
+ GPIO_FN_TS_SPSYNC2, GPIO_FN_TS_SDAT2,
+ GPIO_FN_TS_SDEN2, GPIO_FN_TS_SCK2,
+
+ /* HDMI (PORT 169, 170) */
+ GPIO_FN_HDMI_HPD, GPIO_FN_HDMI_CEC,
+
+ /* SDHI0 (PORT 171, 172, 173, 174, 175, 176, 177, 178) */
+ GPIO_FN_SDHICLK0, GPIO_FN_SDHICD0,
+ GPIO_FN_SDHICMD0, GPIO_FN_SDHIWP0,
+ GPIO_FN_SDHID0_0, GPIO_FN_SDHID0_1,
+ GPIO_FN_SDHID0_2, GPIO_FN_SDHID0_3,
+
+ /* SDHI1 (PORT 179, 180, 181, 182, 183, 184) */
+ GPIO_FN_SDHICLK1, GPIO_FN_SDHICMD1, GPIO_FN_SDHID1_0,
+ GPIO_FN_SDHID1_1, GPIO_FN_SDHID1_2, GPIO_FN_SDHID1_3,
+
+ /* SDHI2 (PORT 185, 186, 187, 188, 189, 190) */
+ GPIO_FN_SDHICLK2, GPIO_FN_SDHICMD2, GPIO_FN_SDHID2_0,
+ GPIO_FN_SDHID2_1, GPIO_FN_SDHID2_2, GPIO_FN_SDHID2_3,
+
+ /* SDENC see MSEL4CR 19 */
+ GPIO_FN_SDENC_CPG,
+ GPIO_FN_SDENC_DV_CLKI,
+};
+
+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_INVALID,
+ SHDMA_SLAVE_SCIF0_TX,
+ SHDMA_SLAVE_SCIF0_RX,
+ SHDMA_SLAVE_SCIF1_TX,
+ SHDMA_SLAVE_SCIF1_RX,
+ SHDMA_SLAVE_SCIF2_TX,
+ SHDMA_SLAVE_SCIF2_RX,
+ SHDMA_SLAVE_SCIF3_TX,
+ SHDMA_SLAVE_SCIF3_RX,
+ SHDMA_SLAVE_SCIF4_TX,
+ SHDMA_SLAVE_SCIF4_RX,
+ SHDMA_SLAVE_SCIF5_TX,
+ SHDMA_SLAVE_SCIF5_RX,
+ SHDMA_SLAVE_SCIF6_TX,
+ SHDMA_SLAVE_SCIF6_RX,
+ SHDMA_SLAVE_SDHI0_RX,
+ SHDMA_SLAVE_SDHI0_TX,
+ SHDMA_SLAVE_SDHI1_RX,
+ SHDMA_SLAVE_SDHI1_TX,
+ SHDMA_SLAVE_SDHI2_RX,
+ SHDMA_SLAVE_SDHI2_TX,
+ SHDMA_SLAVE_MMCIF_RX,
+ SHDMA_SLAVE_MMCIF_TX,
+};
+
+extern struct clk sh7372_extal1_clk;
+extern struct clk sh7372_extal2_clk;
+extern struct clk sh7372_dv_clki_clk;
+extern struct clk sh7372_dv_clki_div2_clk;
+extern struct clk sh7372_pllc2_clk;
+extern struct clk sh7372_fsiack_clk;
+extern struct clk sh7372_fsibck_clk;
+extern struct clk sh7372_fsidiva_clk;
+extern struct clk sh7372_fsidivb_clk;
+
+#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7377.h b/arch/arm/mach-shmobile/include/mach/sh7377.h
new file mode 100644
index 00000000..f580e227
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh7377.h
@@ -0,0 +1,360 @@
+#ifndef __ASM_SH7377_H__
+#define __ASM_SH7377_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* 55-1 -> 55-5 (GPIO) */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
+
+ GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+
+ GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+ GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+ GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+ GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+ GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+ GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+ GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+ GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+ GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+ GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+ GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN_PORT66_KEYIN0_PU, GPIO_FN_PORT67_KEYIN1_PU,
+ GPIO_FN_PORT68_KEYIN2_PU, GPIO_FN_PORT69_KEYIN3_PU,
+ GPIO_FN_PORT70_KEYIN4_PU, GPIO_FN_PORT71_KEYIN5_PU,
+ GPIO_FN_PORT72_KEYIN6_PU,
+
+ /* 55-1 (FN) */
+ GPIO_FN_VBUS_0,
+ GPIO_FN_CPORT0,
+ GPIO_FN_CPORT1,
+ GPIO_FN_CPORT2,
+ GPIO_FN_CPORT3,
+ GPIO_FN_CPORT4,
+ GPIO_FN_CPORT5,
+ GPIO_FN_CPORT6,
+ GPIO_FN_CPORT7,
+ GPIO_FN_CPORT8,
+ GPIO_FN_CPORT9,
+ GPIO_FN_CPORT10,
+ GPIO_FN_CPORT11, GPIO_FN_SIN2,
+ GPIO_FN_CPORT12, GPIO_FN_XCTS2,
+ GPIO_FN_CPORT13, GPIO_FN_RFSPO4,
+ GPIO_FN_CPORT14, GPIO_FN_RFSPO5,
+ GPIO_FN_CPORT15, GPIO_FN_SCIFA0_SCK, GPIO_FN_GPS_AGC2,
+ GPIO_FN_CPORT16, GPIO_FN_SCIFA0_TXD, GPIO_FN_GPS_AGC3,
+ GPIO_FN_CPORT17_IC_OE, GPIO_FN_SOUT2,
+ GPIO_FN_CPORT18, GPIO_FN_XRTS2, GPIO_FN_PORT19_VIO_CKO2,
+ GPIO_FN_CPORT19_MPORT1,
+ GPIO_FN_CPORT20, GPIO_FN_RFSPO6,
+ GPIO_FN_CPORT21, GPIO_FN_STATUS0,
+ GPIO_FN_CPORT22, GPIO_FN_STATUS1,
+ GPIO_FN_CPORT23, GPIO_FN_STATUS2, GPIO_FN_RFSPO7,
+ GPIO_FN_B_SYNLD1,
+ GPIO_FN_B_SYNLD2, GPIO_FN_SYSENMSK,
+ GPIO_FN_XMAINPS,
+ GPIO_FN_XDIVPS,
+ GPIO_FN_XIDRST,
+ GPIO_FN_IDCLK, GPIO_FN_IC_DP,
+ GPIO_FN_IDIO, GPIO_FN_IC_DM,
+ GPIO_FN_SOUT1, GPIO_FN_SCIFA4_TXD, GPIO_FN_M02_BERDAT,
+ GPIO_FN_SIN1, GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_XRTS1, GPIO_FN_SCIFA4_RTS, GPIO_FN_M03_BERCLK,
+ GPIO_FN_XCTS1, GPIO_FN_SCIFA4_CTS,
+ GPIO_FN_PCMCLKO,
+ GPIO_FN_SYNC8KO,
+
+ /* 55-2 (FN) */
+ GPIO_FN_DNPCM_A,
+ GPIO_FN_UPPCM_A,
+ GPIO_FN_VACK,
+ GPIO_FN_XTALB1L,
+ GPIO_FN_GPS_AGC1, GPIO_FN_SCIFA0_RTS,
+ GPIO_FN_GPS_AGC4, GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_GPS_PWRDOWN, GPIO_FN_SCIFA0_CTS,
+ GPIO_FN_GPS_IM,
+ GPIO_FN_GPS_IS,
+ GPIO_FN_GPS_QM,
+ GPIO_FN_GPS_QS,
+ GPIO_FN_FMSOCK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT,
+ GPIO_FN_FMSOOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_IPORT3,
+ GPIO_FN_FMSIOLR,
+ GPIO_FN_FMSOOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_OPORT1,
+ GPIO_FN_FMSIOBT,
+ GPIO_FN_FMSOSLD, GPIO_FN_BBIF2_TXD2, GPIO_FN_OPORT2,
+ GPIO_FN_FMSOILR, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3,
+ GPIO_FN_OPORT3, GPIO_FN_FMSIILR,
+ GPIO_FN_FMSOIBT, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2,
+ GPIO_FN_FMSIIBT,
+ GPIO_FN_FMSISLD, GPIO_FN_MFG0_OUT1, GPIO_FN_TPU0TO0,
+ GPIO_FN_A0_EA0, GPIO_FN_BS,
+ GPIO_FN_A12_EA12, GPIO_FN_PORT58_VIO_CKOR, GPIO_FN_TPU4TO2,
+ GPIO_FN_A13_EA13, GPIO_FN_PORT59_IROUT, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_TPU0TO1,
+ GPIO_FN_A14_EA14, GPIO_FN_PORT60_KEYOUT5,
+ GPIO_FN_A15_EA15, GPIO_FN_PORT61_KEYOUT4,
+ GPIO_FN_A16_EA16, GPIO_FN_PORT62_KEYOUT3, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17_EA17, GPIO_FN_PORT63_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18_EA18, GPIO_FN_PORT64_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19_EA19, GPIO_FN_PORT65_KEYOUT0, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20_EA20, GPIO_FN_PORT66_KEYIN0, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21_EA21, GPIO_FN_PORT67_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22_EA22, GPIO_FN_PORT68_KEYIN2, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23_EA23, GPIO_FN_PORT69_KEYIN3, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24_EA24, GPIO_FN_PORT70_KEYIN4, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25_EA25, GPIO_FN_PORT71_KEYIN5, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_PORT72_KEYIN6,
+ GPIO_FN_D0_ED0_NAF0,
+ GPIO_FN_D1_ED1_NAF1,
+ GPIO_FN_D2_ED2_NAF2,
+ GPIO_FN_D3_ED3_NAF3,
+ GPIO_FN_D4_ED4_NAF4,
+ GPIO_FN_D5_ED5_NAF5,
+ GPIO_FN_D6_ED6_NAF6,
+ GPIO_FN_D7_ED7_NAF7,
+ GPIO_FN_D8_ED8_NAF8,
+ GPIO_FN_D9_ED9_NAF9,
+ GPIO_FN_D10_ED10_NAF10,
+ GPIO_FN_D11_ED11_NAF11,
+ GPIO_FN_D12_ED12_NAF12,
+ GPIO_FN_D13_ED13_NAF13,
+ GPIO_FN_D14_ED14_NAF14,
+ GPIO_FN_D15_ED15_NAF15,
+ GPIO_FN_CS4,
+ GPIO_FN_CS5A, GPIO_FN_FMSICK,
+ GPIO_FN_CS5B, GPIO_FN_FCE1,
+
+ /* 55-3 (FN) */
+ GPIO_FN_CS6B, GPIO_FN_XCS2, GPIO_FN_CS6A, GPIO_FN_DACK0,
+ GPIO_FN_FCE0,
+ GPIO_FN_WAIT, GPIO_FN_DREQ0,
+ GPIO_FN_RD_XRD,
+ GPIO_FN_WE0_XWR0_FWE,
+ GPIO_FN_WE1_XWR1,
+ GPIO_FN_FRB,
+ GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT,
+ GPIO_FN_NBRST,
+ GPIO_FN_GPS_EPPSIN,
+ GPIO_FN_LATCHPULSE,
+ GPIO_FN_LTESIGNAL,
+ GPIO_FN_LEGACYSTATE,
+ GPIO_FN_TCKON,
+ GPIO_FN_VIO_VD, GPIO_FN_PORT128_KEYOUT0, GPIO_FN_IPORT0,
+ GPIO_FN_VIO_HD, GPIO_FN_PORT129_KEYOUT1, GPIO_FN_IPORT1,
+ GPIO_FN_VIO_D0, GPIO_FN_PORT130_KEYOUT2, GPIO_FN_PORT130_MSIOF2_RXD,
+ GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT3, GPIO_FN_PORT131_MSIOF2_SS1,
+ GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT4, GPIO_FN_PORT132_MSIOF2_SS2,
+ GPIO_FN_VIO_D3, GPIO_FN_PORT133_KEYOUT5, GPIO_FN_PORT133_MSIOF2_TSYNC,
+ GPIO_FN_VIO_D4, GPIO_FN_PORT134_KEYIN0, GPIO_FN_PORT134_MSIOF2_TXD,
+ GPIO_FN_VIO_D5, GPIO_FN_PORT135_KEYIN1, GPIO_FN_PORT135_MSIOF2_TSCK,
+ GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYIN2,
+ GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYIN3,
+ GPIO_FN_VIO_D8, GPIO_FN_M9_SLCD_A01, GPIO_FN_PORT138_FSIAOMC,
+ GPIO_FN_VIO_D9, GPIO_FN_M10_SLCD_CK1, GPIO_FN_PORT139_FSIAOLR,
+ GPIO_FN_VIO_D10, GPIO_FN_M11_SLCD_SO1, GPIO_FN_TPU0TO2,
+ GPIO_FN_PORT140_FSIAOBT,
+ GPIO_FN_VIO_D11, GPIO_FN_M12_SLCD_CE1, GPIO_FN_TPU0TO3,
+ GPIO_FN_PORT141_FSIAOSLD,
+ GPIO_FN_VIO_D12, GPIO_FN_M13_BSW, GPIO_FN_PORT142_FSIACK,
+ GPIO_FN_VIO_D13, GPIO_FN_M14_GSW, GPIO_FN_PORT143_FSIAILR,
+ GPIO_FN_VIO_D14, GPIO_FN_M15_RSW, GPIO_FN_PORT144_FSIAIBT,
+ GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_FSIAISLD,
+ GPIO_FN_VIO_CLK, GPIO_FN_PORT146_KEYIN4, GPIO_FN_IPORT2,
+ GPIO_FN_VIO_FIELD, GPIO_FN_PORT147_KEYIN5,
+ GPIO_FN_VIO_CKO, GPIO_FN_PORT148_KEYIN6,
+ GPIO_FN_A27, GPIO_FN_RDWR_XWE, GPIO_FN_MFG0_IN1,
+ GPIO_FN_MFG0_IN2,
+ GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
+ GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
+ GPIO_FN_SOUT3, GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_SIN3, GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_XRTS3, GPIO_FN_SCIFA2_RTS1, GPIO_FN_PORT156_MSIOF2_SS2,
+ GPIO_FN_XCTS3, GPIO_FN_SCIFA2_CTS1, GPIO_FN_PORT157_MSIOF2_RXD,
+
+ /* 55-4 (FN) */
+ GPIO_FN_DINT, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+ GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
+ GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD, GPIO_FN_SOUT0,
+ GPIO_FN_PORT161_SCIFB_CTS, GPIO_FN_PORT161_SCIFA5_CTS, GPIO_FN_XCTS0,
+ GPIO_FN_MFG3_IN2,
+ GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD, GPIO_FN_SIN0,
+ GPIO_FN_MFG3_IN1,
+ GPIO_FN_PORT163_SCIFB_RTS, GPIO_FN_PORT163_SCIFA5_RTS, GPIO_FN_XRTS0,
+ GPIO_FN_MFG3_OUT1,
+ GPIO_FN_TPU3TO0,
+ GPIO_FN_LCDD0, GPIO_FN_PORT192_KEYOUT0, GPIO_FN_EXT_CKI,
+ GPIO_FN_LCDD1, GPIO_FN_PORT193_KEYOUT1, GPIO_FN_PORT193_SCIFA5_CTS,
+ GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT194_KEYOUT2, GPIO_FN_PORT194_SCIFA5_RTS,
+ GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT195_KEYOUT3, GPIO_FN_PORT195_SCIFA5_RXD,
+ GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT196_KEYOUT4, GPIO_FN_PORT196_SCIFA5_TXD,
+ GPIO_FN_LCDD5, GPIO_FN_PORT197_KEYOUT5, GPIO_FN_PORT197_SCIFA5_SCK,
+ GPIO_FN_MFG2_OUT2, GPIO_FN_TPU2TO1,
+ GPIO_FN_LCDD6, GPIO_FN_XWR2,
+ GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2, GPIO_FN_XWR3,
+ GPIO_FN_LCDD8, GPIO_FN_PORT200_KEYIN0, GPIO_FN_VIO_DR0, GPIO_FN_D16,
+ GPIO_FN_ED16,
+ GPIO_FN_LCDD9, GPIO_FN_PORT201_KEYIN1, GPIO_FN_VIO_DR1, GPIO_FN_D17,
+ GPIO_FN_ED17,
+ GPIO_FN_LCDD10, GPIO_FN_PORT202_KEYIN2, GPIO_FN_VIO_DR2, GPIO_FN_D18,
+ GPIO_FN_ED18,
+ GPIO_FN_LCDD11, GPIO_FN_PORT203_KEYIN3, GPIO_FN_VIO_DR3, GPIO_FN_D19,
+ GPIO_FN_ED19,
+ GPIO_FN_LCDD12, GPIO_FN_PORT204_KEYIN4, GPIO_FN_VIO_DR4, GPIO_FN_D20,
+ GPIO_FN_ED20,
+ GPIO_FN_LCDD13, GPIO_FN_PORT205_KEYIN5, GPIO_FN_VIO_DR5, GPIO_FN_D21,
+ GPIO_FN_ED21,
+ GPIO_FN_LCDD14, GPIO_FN_PORT206_KEYIN6, GPIO_FN_VIO_DR6, GPIO_FN_D22,
+ GPIO_FN_ED22,
+ GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_PORT207_KEYOUT0,
+ GPIO_FN_VIO_DR7,
+ GPIO_FN_D23, GPIO_FN_ED23,
+ GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_PORT208_KEYOUT1,
+ GPIO_FN_VIO_VDR,
+ GPIO_FN_D24, GPIO_FN_ED24,
+ GPIO_FN_LCDD17, GPIO_FN_PORT209_KEYOUT2, GPIO_FN_VIO_HDR, GPIO_FN_D25,
+ GPIO_FN_ED25,
+ GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
+ GPIO_FN_ED26,
+ GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27, GPIO_FN_ED27,
+ GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
+ GPIO_FN_ED28,
+ GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
+ GPIO_FN_ED29,
+ GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
+ GPIO_FN_ED30,
+ GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
+ GPIO_FN_ED31,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR, GPIO_FN_PORT216_KEYOUT3,
+ GPIO_FN_VIO_CLKR,
+ GPIO_FN_LCDRD, GPIO_FN_DACK2, GPIO_FN_MSIOF0L_TSYNC,
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS, GPIO_FN_LCDCS2, GPIO_FN_DACK3,
+ GPIO_FN_PORT218_VIO_CKOR, GPIO_FN_PORT218_KEYOUT4,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK,
+ GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2, GPIO_FN_PORT220_KEYOUT5,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN,
+ GPIO_FN_MSIOF0L_TXD,
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
+ GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_USBTERM,
+ GPIO_FN_PORT226_VIO_CKO2,
+ GPIO_FN_SCIFA1_RTS, GPIO_FN_IDIN,
+ GPIO_FN_SCIFA1_RXD,
+ GPIO_FN_SCIFA1_CTS, GPIO_FN_MFG1_IN1,
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2, GPIO_FN_PORT230_FSIAOMC,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2, GPIO_FN_PORT231_FSIAOLR,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2, GPIO_FN_PORT232_FSIAOBT,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2, GPIO_FN_GPS_VCOTRIG,
+ GPIO_FN_PORT233_FSIACK,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2, GPIO_FN_PORT234_FSIAOSLD,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_OPORT0, GPIO_FN_MFG1_IN2,
+ GPIO_FN_PORT235_FSIAILR,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_I2C_SDA2, GPIO_FN_PORT236_FSIAIBT,
+ GPIO_FN_MSIOF1_MCK1, GPIO_FN_I2C_SCL2, GPIO_FN_PORT237_FSIAISLD,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_EDBGREQ3,
+
+ /* 55-5 (FN) */
+ GPIO_FN_MSIOF1_SS2,
+ GPIO_FN_SCIFA6_TXD,
+ GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1,
+ GPIO_FN_TPU4TO0,
+ GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
+ GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
+ GPIO_FN_PORT244_SCIFA5_CTS, GPIO_FN_MFG2_IN1, GPIO_FN_PORT244_SCIFB_CTS,
+ GPIO_FN_PORT244_MSIOF2_RXD,
+ GPIO_FN_PORT245_SCIFA5_RTS, GPIO_FN_MFG2_IN2, GPIO_FN_PORT245_SCIFB_RTS,
+ GPIO_FN_PORT245_MSIOF2_TXD,
+ GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1,
+ GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
+ GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2,
+ GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
+ GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1,
+ GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0,
+ GPIO_FN_PORT248_MSIOF2_TSCK,
+ GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, GPIO_FN_PORT249_MSIOF2_TSYNC,
+ GPIO_FN_SDHICLK0, GPIO_FN_TCK2_SWCLK_MC0,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0, GPIO_FN_TMS2_SWDIO_MC0,
+ GPIO_FN_SDHID0_1, GPIO_FN_TDO2_SWO0_MC0,
+ GPIO_FN_SDHID0_2, GPIO_FN_TDI2,
+ GPIO_FN_SDHID0_3, GPIO_FN_RTCK2_SWO1_MC0,
+ GPIO_FN_SDHICMD0, GPIO_FN_TRST2,
+ GPIO_FN_SDHIWP0, GPIO_FN_EDBGREQ2,
+ GPIO_FN_SDHICLK1, GPIO_FN_TCK3_SWCLK_MC1,
+ GPIO_FN_SDHID1_0, GPIO_FN_M11_SLCD_SO2, GPIO_FN_TS_SPSYNC2,
+ GPIO_FN_TMS3_SWDIO_MC1,
+ GPIO_FN_SDHID1_1, GPIO_FN_M9_SLCD_A02, GPIO_FN_TS_SDAT2,
+ GPIO_FN_TDO3_SWO0_MC1,
+ GPIO_FN_SDHID1_2, GPIO_FN_M10_SLCD_CK2, GPIO_FN_TS_SDEN2, GPIO_FN_TDI3,
+ GPIO_FN_SDHID1_3, GPIO_FN_M12_SLCD_CE2, GPIO_FN_TS_SCK2,
+ GPIO_FN_RTCK3_SWO1_MC1,
+ GPIO_FN_SDHICMD1, GPIO_FN_TRST3,
+ GPIO_FN_RESETOUTS,
+};
+
+#endif /* __ASM_SH7377_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
new file mode 100644
index 00000000..216c3d69
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -0,0 +1,497 @@
+#ifndef __ASM_SH73A0_H__
+#define __ASM_SH73A0_H__
+
+/* Pin Function Controller:
+ * GPIO_FN_xx - GPIO used to select pin function and MSEL switch
+ * GPIO_PORTxx - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+ /* Hardware manual Table 25-1 (GPIO) */
+ GPIO_PORT0, GPIO_PORT1, GPIO_PORT2, GPIO_PORT3, GPIO_PORT4,
+ GPIO_PORT5, GPIO_PORT6, GPIO_PORT7, GPIO_PORT8, GPIO_PORT9,
+
+ GPIO_PORT10, GPIO_PORT11, GPIO_PORT12, GPIO_PORT13, GPIO_PORT14,
+ GPIO_PORT15, GPIO_PORT16, GPIO_PORT17, GPIO_PORT18, GPIO_PORT19,
+
+ GPIO_PORT20, GPIO_PORT21, GPIO_PORT22, GPIO_PORT23, GPIO_PORT24,
+ GPIO_PORT25, GPIO_PORT26, GPIO_PORT27, GPIO_PORT28, GPIO_PORT29,
+
+ GPIO_PORT30, GPIO_PORT31, GPIO_PORT32, GPIO_PORT33, GPIO_PORT34,
+ GPIO_PORT35, GPIO_PORT36, GPIO_PORT37, GPIO_PORT38, GPIO_PORT39,
+
+ GPIO_PORT40, GPIO_PORT41, GPIO_PORT42, GPIO_PORT43, GPIO_PORT44,
+ GPIO_PORT45, GPIO_PORT46, GPIO_PORT47, GPIO_PORT48, GPIO_PORT49,
+
+ GPIO_PORT50, GPIO_PORT51, GPIO_PORT52, GPIO_PORT53, GPIO_PORT54,
+ GPIO_PORT55, GPIO_PORT56, GPIO_PORT57, GPIO_PORT58, GPIO_PORT59,
+
+ GPIO_PORT60, GPIO_PORT61, GPIO_PORT62, GPIO_PORT63, GPIO_PORT64,
+ GPIO_PORT65, GPIO_PORT66, GPIO_PORT67, GPIO_PORT68, GPIO_PORT69,
+
+ GPIO_PORT70, GPIO_PORT71, GPIO_PORT72, GPIO_PORT73, GPIO_PORT74,
+ GPIO_PORT75, GPIO_PORT76, GPIO_PORT77, GPIO_PORT78, GPIO_PORT79,
+
+ GPIO_PORT80, GPIO_PORT81, GPIO_PORT82, GPIO_PORT83, GPIO_PORT84,
+ GPIO_PORT85, GPIO_PORT86, GPIO_PORT87, GPIO_PORT88, GPIO_PORT89,
+
+ GPIO_PORT90, GPIO_PORT91, GPIO_PORT92, GPIO_PORT93, GPIO_PORT94,
+ GPIO_PORT95, GPIO_PORT96, GPIO_PORT97, GPIO_PORT98, GPIO_PORT99,
+
+ GPIO_PORT100, GPIO_PORT101, GPIO_PORT102, GPIO_PORT103, GPIO_PORT104,
+ GPIO_PORT105, GPIO_PORT106, GPIO_PORT107, GPIO_PORT108, GPIO_PORT109,
+
+ GPIO_PORT110, GPIO_PORT111, GPIO_PORT112, GPIO_PORT113, GPIO_PORT114,
+ GPIO_PORT115, GPIO_PORT116, GPIO_PORT117, GPIO_PORT118,
+
+ GPIO_PORT128, GPIO_PORT129,
+
+ GPIO_PORT130, GPIO_PORT131, GPIO_PORT132, GPIO_PORT133, GPIO_PORT134,
+ GPIO_PORT135, GPIO_PORT136, GPIO_PORT137, GPIO_PORT138, GPIO_PORT139,
+
+ GPIO_PORT140, GPIO_PORT141, GPIO_PORT142, GPIO_PORT143, GPIO_PORT144,
+ GPIO_PORT145, GPIO_PORT146, GPIO_PORT147, GPIO_PORT148, GPIO_PORT149,
+
+ GPIO_PORT150, GPIO_PORT151, GPIO_PORT152, GPIO_PORT153, GPIO_PORT154,
+ GPIO_PORT155, GPIO_PORT156, GPIO_PORT157, GPIO_PORT158, GPIO_PORT159,
+
+ GPIO_PORT160, GPIO_PORT161, GPIO_PORT162, GPIO_PORT163, GPIO_PORT164,
+
+ GPIO_PORT192, GPIO_PORT193, GPIO_PORT194,
+ GPIO_PORT195, GPIO_PORT196, GPIO_PORT197, GPIO_PORT198, GPIO_PORT199,
+
+ GPIO_PORT200, GPIO_PORT201, GPIO_PORT202, GPIO_PORT203, GPIO_PORT204,
+ GPIO_PORT205, GPIO_PORT206, GPIO_PORT207, GPIO_PORT208, GPIO_PORT209,
+
+ GPIO_PORT210, GPIO_PORT211, GPIO_PORT212, GPIO_PORT213, GPIO_PORT214,
+ GPIO_PORT215, GPIO_PORT216, GPIO_PORT217, GPIO_PORT218, GPIO_PORT219,
+
+ GPIO_PORT220, GPIO_PORT221, GPIO_PORT222, GPIO_PORT223, GPIO_PORT224,
+ GPIO_PORT225, GPIO_PORT226, GPIO_PORT227, GPIO_PORT228, GPIO_PORT229,
+
+ GPIO_PORT230, GPIO_PORT231, GPIO_PORT232, GPIO_PORT233, GPIO_PORT234,
+ GPIO_PORT235, GPIO_PORT236, GPIO_PORT237, GPIO_PORT238, GPIO_PORT239,
+
+ GPIO_PORT240, GPIO_PORT241, GPIO_PORT242, GPIO_PORT243, GPIO_PORT244,
+ GPIO_PORT245, GPIO_PORT246, GPIO_PORT247, GPIO_PORT248, GPIO_PORT249,
+
+ GPIO_PORT250, GPIO_PORT251, GPIO_PORT252, GPIO_PORT253, GPIO_PORT254,
+ GPIO_PORT255, GPIO_PORT256, GPIO_PORT257, GPIO_PORT258, GPIO_PORT259,
+
+ GPIO_PORT260, GPIO_PORT261, GPIO_PORT262, GPIO_PORT263, GPIO_PORT264,
+ GPIO_PORT265, GPIO_PORT266, GPIO_PORT267, GPIO_PORT268, GPIO_PORT269,
+
+ GPIO_PORT270, GPIO_PORT271, GPIO_PORT272, GPIO_PORT273, GPIO_PORT274,
+ GPIO_PORT275, GPIO_PORT276, GPIO_PORT277, GPIO_PORT278, GPIO_PORT279,
+
+ GPIO_PORT280, GPIO_PORT281, GPIO_PORT282,
+
+ GPIO_PORT288, GPIO_PORT289,
+
+ GPIO_PORT290, GPIO_PORT291, GPIO_PORT292, GPIO_PORT293, GPIO_PORT294,
+ GPIO_PORT295, GPIO_PORT296, GPIO_PORT297, GPIO_PORT298, GPIO_PORT299,
+
+ GPIO_PORT300, GPIO_PORT301, GPIO_PORT302, GPIO_PORT303, GPIO_PORT304,
+ GPIO_PORT305, GPIO_PORT306, GPIO_PORT307, GPIO_PORT308, GPIO_PORT309,
+
+ /* Table 25-1 (Function 0-7) */
+ GPIO_FN_VBUS_0,
+ GPIO_FN_GPI0,
+ GPIO_FN_GPI1,
+ GPIO_FN_GPI2,
+ GPIO_FN_GPI3,
+ GPIO_FN_GPI4,
+ GPIO_FN_GPI5,
+ GPIO_FN_GPI6,
+ GPIO_FN_GPI7,
+ GPIO_FN_SCIFA7_RXD,
+ GPIO_FN_SCIFA7_CTS_,
+ GPIO_FN_GPO7, GPIO_FN_MFG0_OUT2,
+ GPIO_FN_GPO6, GPIO_FN_MFG1_OUT2,
+ GPIO_FN_GPO5, GPIO_FN_SCIFA0_SCK, GPIO_FN_FSICOSLDT3, \
+ GPIO_FN_PORT16_VIO_CKOR,
+ GPIO_FN_SCIFA0_TXD,
+ GPIO_FN_SCIFA7_TXD,
+ GPIO_FN_SCIFA7_RTS_, GPIO_FN_PORT19_VIO_CKO2,
+ GPIO_FN_GPO0,
+ GPIO_FN_GPO1,
+ GPIO_FN_GPO2, GPIO_FN_STATUS0,
+ GPIO_FN_GPO3, GPIO_FN_STATUS1,
+ GPIO_FN_GPO4, GPIO_FN_STATUS2,
+ GPIO_FN_VINT,
+ GPIO_FN_TCKON,
+ GPIO_FN_XDVFS1, GPIO_FN_PORT27_I2C_SCL2, GPIO_FN_PORT27_I2C_SCL3, \
+ GPIO_FN_MFG0_OUT1, GPIO_FN_PORT27_IROUT,
+ GPIO_FN_XDVFS2, GPIO_FN_PORT28_I2C_SDA2, GPIO_FN_PORT28_I2C_SDA3, \
+ GPIO_FN_PORT28_TPU1TO1,
+ GPIO_FN_SIM_RST, GPIO_FN_PORT29_TPU1TO1,
+ GPIO_FN_SIM_CLK, GPIO_FN_PORT30_VIO_CKOR,
+ GPIO_FN_SIM_D, GPIO_FN_PORT31_IROUT,
+ GPIO_FN_SCIFA4_TXD,
+ GPIO_FN_SCIFA4_RXD, GPIO_FN_XWUP,
+ GPIO_FN_SCIFA4_RTS_,
+ GPIO_FN_SCIFA4_CTS_,
+ GPIO_FN_FSIBOBT, GPIO_FN_FSIBIBT,
+ GPIO_FN_FSIBOLR, GPIO_FN_FSIBILR,
+ GPIO_FN_FSIBOSLD,
+ GPIO_FN_FSIBISLD,
+ GPIO_FN_VACK,
+ GPIO_FN_XTAL1L,
+ GPIO_FN_SCIFA0_RTS_, GPIO_FN_FSICOSLDT2,
+ GPIO_FN_SCIFA0_RXD,
+ GPIO_FN_SCIFA0_CTS_, GPIO_FN_FSICOSLDT1,
+ GPIO_FN_FSICOBT, GPIO_FN_FSICIBT, GPIO_FN_FSIDOBT, GPIO_FN_FSIDIBT,
+ GPIO_FN_FSICOLR, GPIO_FN_FSICILR, GPIO_FN_FSIDOLR, GPIO_FN_FSIDILR,
+ GPIO_FN_FSICOSLD, GPIO_FN_PORT47_FSICSPDIF,
+ GPIO_FN_FSICISLD, GPIO_FN_FSIDISLD,
+ GPIO_FN_FSIACK, GPIO_FN_PORT49_IRDA_OUT, GPIO_FN_PORT49_IROUT, \
+ GPIO_FN_FSIAOMC,
+ GPIO_FN_FSIAOLR, GPIO_FN_BBIF2_TSYNC2, GPIO_FN_TPU2TO2, GPIO_FN_FSIAILR,
+
+ GPIO_FN_FSIAOBT, GPIO_FN_BBIF2_TSCK2, GPIO_FN_TPU2TO3, GPIO_FN_FSIAIBT,
+ GPIO_FN_FSIAOSLD, GPIO_FN_BBIF2_TXD2,
+ GPIO_FN_FSIASPDIF, GPIO_FN_PORT53_IRDA_IN, GPIO_FN_TPU3TO3, \
+ GPIO_FN_FSIBSPDIF, GPIO_FN_PORT53_FSICSPDIF,
+ GPIO_FN_FSIBCK, GPIO_FN_PORT54_IRDA_FIRSEL, GPIO_FN_TPU3TO2, \
+ GPIO_FN_FSIBOMC, GPIO_FN_FSICCK, GPIO_FN_FSICOMC,
+ GPIO_FN_FSIAISLD, GPIO_FN_TPU0TO0,
+ GPIO_FN_A0, GPIO_FN_BS_,
+ GPIO_FN_A12, GPIO_FN_PORT58_KEYOUT7, GPIO_FN_TPU4TO2,
+ GPIO_FN_A13, GPIO_FN_PORT59_KEYOUT6, GPIO_FN_TPU0TO1,
+ GPIO_FN_A14, GPIO_FN_KEYOUT5,
+ GPIO_FN_A15, GPIO_FN_KEYOUT4,
+ GPIO_FN_A16, GPIO_FN_KEYOUT3, GPIO_FN_MSIOF0_SS1,
+ GPIO_FN_A17, GPIO_FN_KEYOUT2, GPIO_FN_MSIOF0_TSYNC,
+ GPIO_FN_A18, GPIO_FN_KEYOUT1, GPIO_FN_MSIOF0_TSCK,
+ GPIO_FN_A19, GPIO_FN_KEYOUT0, GPIO_FN_MSIOF0_TXD,
+ GPIO_FN_A20, GPIO_FN_KEYIN0, GPIO_FN_MSIOF0_RSCK,
+ GPIO_FN_A21, GPIO_FN_KEYIN1, GPIO_FN_MSIOF0_RSYNC,
+ GPIO_FN_A22, GPIO_FN_KEYIN2, GPIO_FN_MSIOF0_MCK0,
+ GPIO_FN_A23, GPIO_FN_KEYIN3, GPIO_FN_MSIOF0_MCK1,
+ GPIO_FN_A24, GPIO_FN_KEYIN4, GPIO_FN_MSIOF0_RXD,
+ GPIO_FN_A25, GPIO_FN_KEYIN5, GPIO_FN_MSIOF0_SS2,
+ GPIO_FN_A26, GPIO_FN_KEYIN6,
+ GPIO_FN_KEYIN7,
+ GPIO_FN_D0_NAF0,
+ GPIO_FN_D1_NAF1,
+ GPIO_FN_D2_NAF2,
+ GPIO_FN_D3_NAF3,
+ GPIO_FN_D4_NAF4,
+ GPIO_FN_D5_NAF5,
+ GPIO_FN_D6_NAF6,
+ GPIO_FN_D7_NAF7,
+ GPIO_FN_D8_NAF8,
+ GPIO_FN_D9_NAF9,
+ GPIO_FN_D10_NAF10,
+ GPIO_FN_D11_NAF11,
+ GPIO_FN_D12_NAF12,
+ GPIO_FN_D13_NAF13,
+ GPIO_FN_D14_NAF14,
+ GPIO_FN_D15_NAF15,
+ GPIO_FN_CS4_,
+ GPIO_FN_CS5A_, GPIO_FN_PORT91_RDWR,
+ GPIO_FN_CS5B_, GPIO_FN_FCE1_,
+ GPIO_FN_CS6B_, GPIO_FN_DACK0,
+ GPIO_FN_FCE0_, GPIO_FN_CS6A_,
+ GPIO_FN_WAIT_, GPIO_FN_DREQ0,
+ GPIO_FN_RD__FSC,
+ GPIO_FN_WE0__FWE, GPIO_FN_RDWR_FWE,
+ GPIO_FN_WE1_,
+ GPIO_FN_FRB,
+ GPIO_FN_CKO,
+ GPIO_FN_NBRSTOUT_,
+ GPIO_FN_NBRST_,
+ GPIO_FN_BBIF2_TXD,
+ GPIO_FN_BBIF2_RXD,
+ GPIO_FN_BBIF2_SYNC,
+ GPIO_FN_BBIF2_SCK,
+ GPIO_FN_SCIFA3_CTS_, GPIO_FN_MFG3_IN2,
+ GPIO_FN_SCIFA3_RXD, GPIO_FN_MFG3_IN1,
+ GPIO_FN_BBIF1_SS2, GPIO_FN_SCIFA3_RTS_, GPIO_FN_MFG3_OUT1,
+ GPIO_FN_SCIFA3_TXD,
+ GPIO_FN_HSI_RX_DATA, GPIO_FN_BBIF1_RXD,
+ GPIO_FN_HSI_TX_WAKE, GPIO_FN_BBIF1_TSCK,
+ GPIO_FN_HSI_TX_DATA, GPIO_FN_BBIF1_TSYNC,
+ GPIO_FN_HSI_TX_READY, GPIO_FN_BBIF1_TXD,
+ GPIO_FN_HSI_RX_READY, GPIO_FN_BBIF1_RSCK, GPIO_FN_PORT115_I2C_SCL2, \
+ GPIO_FN_PORT115_I2C_SCL3,
+ GPIO_FN_HSI_RX_WAKE, GPIO_FN_BBIF1_RSYNC, GPIO_FN_PORT116_I2C_SDA2, \
+ GPIO_FN_PORT116_I2C_SDA3,
+ GPIO_FN_HSI_RX_FLAG, GPIO_FN_BBIF1_SS1, GPIO_FN_BBIF1_FLOW,
+ GPIO_FN_HSI_TX_FLAG,
+ GPIO_FN_VIO_VD, GPIO_FN_PORT128_LCD2VSYN, GPIO_FN_VIO2_VD, \
+ GPIO_FN_LCD2D0,
+
+ GPIO_FN_VIO_HD, GPIO_FN_PORT129_LCD2HSYN, GPIO_FN_PORT129_LCD2CS_, \
+ GPIO_FN_VIO2_HD, GPIO_FN_LCD2D1,
+ GPIO_FN_VIO_D0, GPIO_FN_PORT130_MSIOF2_RXD, GPIO_FN_LCD2D10,
+ GPIO_FN_VIO_D1, GPIO_FN_PORT131_KEYOUT6, GPIO_FN_PORT131_MSIOF2_SS1, \
+ GPIO_FN_PORT131_KEYOUT11, GPIO_FN_LCD2D11,
+ GPIO_FN_VIO_D2, GPIO_FN_PORT132_KEYOUT7, GPIO_FN_PORT132_MSIOF2_SS2, \
+ GPIO_FN_PORT132_KEYOUT10, GPIO_FN_LCD2D12,
+ GPIO_FN_VIO_D3, GPIO_FN_MSIOF2_TSYNC, GPIO_FN_LCD2D13,
+ GPIO_FN_VIO_D4, GPIO_FN_MSIOF2_TXD, GPIO_FN_LCD2D14,
+ GPIO_FN_VIO_D5, GPIO_FN_MSIOF2_TSCK, GPIO_FN_LCD2D15,
+ GPIO_FN_VIO_D6, GPIO_FN_PORT136_KEYOUT8, GPIO_FN_LCD2D16,
+ GPIO_FN_VIO_D7, GPIO_FN_PORT137_KEYOUT9, GPIO_FN_LCD2D17,
+ GPIO_FN_VIO_D8, GPIO_FN_PORT138_KEYOUT8, GPIO_FN_VIO2_D0, \
+ GPIO_FN_LCD2D6,
+ GPIO_FN_VIO_D9, GPIO_FN_PORT139_KEYOUT9, GPIO_FN_VIO2_D1, \
+ GPIO_FN_LCD2D7,
+ GPIO_FN_VIO_D10, GPIO_FN_TPU0TO2, GPIO_FN_VIO2_D2, GPIO_FN_LCD2D8,
+ GPIO_FN_VIO_D11, GPIO_FN_TPU0TO3, GPIO_FN_VIO2_D3, GPIO_FN_LCD2D9,
+ GPIO_FN_VIO_D12, GPIO_FN_PORT142_KEYOUT10, GPIO_FN_VIO2_D4, \
+ GPIO_FN_LCD2D2,
+ GPIO_FN_VIO_D13, GPIO_FN_PORT143_KEYOUT11, GPIO_FN_PORT143_KEYOUT6, \
+ GPIO_FN_VIO2_D5, GPIO_FN_LCD2D3,
+ GPIO_FN_VIO_D14, GPIO_FN_PORT144_KEYOUT7, GPIO_FN_VIO2_D6, \
+ GPIO_FN_LCD2D4,
+ GPIO_FN_VIO_D15, GPIO_FN_TPU1TO3, GPIO_FN_PORT145_LCD2DISP, \
+ GPIO_FN_PORT145_LCD2RS, GPIO_FN_VIO2_D7, GPIO_FN_LCD2D5,
+ GPIO_FN_VIO_CLK, GPIO_FN_LCD2DCK, GPIO_FN_PORT146_LCD2WR_, \
+ GPIO_FN_VIO2_CLK, GPIO_FN_LCD2D18,
+ GPIO_FN_VIO_FIELD, GPIO_FN_LCD2RD_, GPIO_FN_VIO2_FIELD, GPIO_FN_LCD2D19,
+ GPIO_FN_VIO_CKO,
+ GPIO_FN_A27, GPIO_FN_PORT149_RDWR, GPIO_FN_MFG0_IN1, \
+ GPIO_FN_PORT149_KEYOUT9,
+ GPIO_FN_MFG0_IN2,
+ GPIO_FN_TS_SPSYNC3, GPIO_FN_MSIOF2_RSCK,
+ GPIO_FN_TS_SDAT3, GPIO_FN_MSIOF2_RSYNC,
+ GPIO_FN_TPU1TO2, GPIO_FN_TS_SDEN3, GPIO_FN_PORT153_MSIOF2_SS1,
+ GPIO_FN_SCIFA2_TXD1, GPIO_FN_MSIOF2_MCK0,
+ GPIO_FN_SCIFA2_RXD1, GPIO_FN_MSIOF2_MCK1,
+ GPIO_FN_SCIFA2_RTS1_, GPIO_FN_PORT156_MSIOF2_SS2,
+ GPIO_FN_SCIFA2_CTS1_, GPIO_FN_PORT157_MSIOF2_RXD,
+ GPIO_FN_DINT_, GPIO_FN_SCIFA2_SCK1, GPIO_FN_TS_SCK3,
+ GPIO_FN_PORT159_SCIFB_SCK, GPIO_FN_PORT159_SCIFA5_SCK, GPIO_FN_NMI,
+ GPIO_FN_PORT160_SCIFB_TXD, GPIO_FN_PORT160_SCIFA5_TXD,
+ GPIO_FN_PORT161_SCIFB_CTS_, GPIO_FN_PORT161_SCIFA5_CTS_,
+ GPIO_FN_PORT162_SCIFB_RXD, GPIO_FN_PORT162_SCIFA5_RXD,
+ GPIO_FN_PORT163_SCIFB_RTS_, GPIO_FN_PORT163_SCIFA5_RTS_, \
+ GPIO_FN_TPU3TO0,
+ GPIO_FN_LCDD0,
+ GPIO_FN_LCDD1, GPIO_FN_PORT193_SCIFA5_CTS_, GPIO_FN_BBIF2_TSYNC1,
+ GPIO_FN_LCDD2, GPIO_FN_PORT194_SCIFA5_RTS_, GPIO_FN_BBIF2_TSCK1,
+ GPIO_FN_LCDD3, GPIO_FN_PORT195_SCIFA5_RXD, GPIO_FN_BBIF2_TXD1,
+ GPIO_FN_LCDD4, GPIO_FN_PORT196_SCIFA5_TXD,
+ GPIO_FN_LCDD5, GPIO_FN_PORT197_SCIFA5_SCK, GPIO_FN_MFG2_OUT2, \
+ GPIO_FN_TPU2TO1,
+ GPIO_FN_LCDD6,
+ GPIO_FN_LCDD7, GPIO_FN_TPU4TO1, GPIO_FN_MFG4_OUT2,
+ GPIO_FN_LCDD8, GPIO_FN_D16,
+ GPIO_FN_LCDD9, GPIO_FN_D17,
+ GPIO_FN_LCDD10, GPIO_FN_D18,
+ GPIO_FN_LCDD11, GPIO_FN_D19,
+ GPIO_FN_LCDD12, GPIO_FN_D20,
+ GPIO_FN_LCDD13, GPIO_FN_D21,
+ GPIO_FN_LCDD14, GPIO_FN_D22,
+ GPIO_FN_LCDD15, GPIO_FN_PORT207_MSIOF0L_SS1, GPIO_FN_D23,
+ GPIO_FN_LCDD16, GPIO_FN_PORT208_MSIOF0L_SS2, GPIO_FN_D24,
+ GPIO_FN_LCDD17, GPIO_FN_D25,
+ GPIO_FN_LCDD18, GPIO_FN_DREQ2, GPIO_FN_PORT210_MSIOF0L_SS1, GPIO_FN_D26,
+ GPIO_FN_LCDD19, GPIO_FN_PORT211_MSIOF0L_SS2, GPIO_FN_D27,
+ GPIO_FN_LCDD20, GPIO_FN_TS_SPSYNC1, GPIO_FN_MSIOF0L_MCK0, GPIO_FN_D28,
+ GPIO_FN_LCDD21, GPIO_FN_TS_SDAT1, GPIO_FN_MSIOF0L_MCK1, GPIO_FN_D29,
+ GPIO_FN_LCDD22, GPIO_FN_TS_SDEN1, GPIO_FN_MSIOF0L_RSCK, GPIO_FN_D30,
+ GPIO_FN_LCDD23, GPIO_FN_TS_SCK1, GPIO_FN_MSIOF0L_RSYNC, GPIO_FN_D31,
+ GPIO_FN_LCDDCK, GPIO_FN_LCDWR_,
+ GPIO_FN_LCDRD_, GPIO_FN_DACK2, GPIO_FN_PORT217_LCD2RS, \
+ GPIO_FN_MSIOF0L_TSYNC, GPIO_FN_VIO2_FIELD3, GPIO_FN_PORT217_LCD2DISP,
+ GPIO_FN_LCDHSYN, GPIO_FN_LCDCS_, GPIO_FN_LCDCS2_, GPIO_FN_DACK3, \
+ GPIO_FN_PORT218_VIO_CKOR,
+ GPIO_FN_LCDDISP, GPIO_FN_LCDRS, GPIO_FN_PORT219_LCD2WR_, \
+ GPIO_FN_DREQ3, GPIO_FN_MSIOF0L_TSCK, GPIO_FN_VIO2_CLK3, \
+ GPIO_FN_LCD2DCK_2,
+ GPIO_FN_LCDVSYN, GPIO_FN_LCDVSYN2,
+ GPIO_FN_LCDLCLK, GPIO_FN_DREQ1, GPIO_FN_PORT221_LCD2CS_, \
+ GPIO_FN_PWEN, GPIO_FN_MSIOF0L_RXD, GPIO_FN_VIO2_HD3, \
+ GPIO_FN_PORT221_LCD2HSYN,
+ GPIO_FN_LCDDON, GPIO_FN_LCDDON2, GPIO_FN_DACK1, GPIO_FN_OVCN, \
+ GPIO_FN_MSIOF0L_TXD, GPIO_FN_VIO2_VD3, GPIO_FN_PORT222_LCD2VSYN,
+
+ GPIO_FN_SCIFA1_TXD, GPIO_FN_OVCN2,
+ GPIO_FN_EXTLP, GPIO_FN_SCIFA1_SCK, GPIO_FN_PORT226_VIO_CKO2,
+ GPIO_FN_SCIFA1_RTS_, GPIO_FN_IDIN,
+ GPIO_FN_SCIFA1_RXD,
+ GPIO_FN_SCIFA1_CTS_, GPIO_FN_MFG1_IN1,
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_SCIFA2_TXD2,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_SCIFA2_CTS2_,
+ GPIO_FN_MSIOF1_TSCK, GPIO_FN_SCIFA2_SCK2,
+ GPIO_FN_MSIOF1_RXD, GPIO_FN_SCIFA2_RXD2,
+ GPIO_FN_MSIOF1_RSCK, GPIO_FN_SCIFA2_RTS2_, GPIO_FN_VIO2_CLK2, \
+ GPIO_FN_LCD2D20,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_MFG1_IN2, GPIO_FN_VIO2_VD2, \
+ GPIO_FN_LCD2D21,
+ GPIO_FN_MSIOF1_MCK0, GPIO_FN_PORT236_I2C_SDA2,
+ GPIO_FN_MSIOF1_MCK1, GPIO_FN_PORT237_I2C_SCL2,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_VIO2_FIELD2, GPIO_FN_LCD2D22,
+ GPIO_FN_MSIOF1_SS2, GPIO_FN_VIO2_HD2, GPIO_FN_LCD2D23,
+ GPIO_FN_SCIFA6_TXD,
+ GPIO_FN_PORT241_IRDA_OUT, GPIO_FN_PORT241_IROUT, GPIO_FN_MFG4_OUT1, \
+ GPIO_FN_TPU4TO0,
+ GPIO_FN_PORT242_IRDA_IN, GPIO_FN_MFG4_IN2,
+ GPIO_FN_PORT243_IRDA_FIRSEL, GPIO_FN_PORT243_VIO_CKO2,
+ GPIO_FN_PORT244_SCIFA5_CTS_, GPIO_FN_MFG2_IN1, \
+ GPIO_FN_PORT244_SCIFB_CTS_, GPIO_FN_MSIOF2R_RXD,
+ GPIO_FN_PORT245_SCIFA5_RTS_, GPIO_FN_MFG2_IN2, \
+ GPIO_FN_PORT245_SCIFB_RTS_, GPIO_FN_MSIOF2R_TXD,
+ GPIO_FN_PORT246_SCIFA5_RXD, GPIO_FN_MFG1_OUT1, \
+ GPIO_FN_PORT246_SCIFB_RXD, GPIO_FN_TPU1TO0,
+ GPIO_FN_PORT247_SCIFA5_TXD, GPIO_FN_MFG3_OUT2, \
+ GPIO_FN_PORT247_SCIFB_TXD, GPIO_FN_TPU3TO1,
+ GPIO_FN_PORT248_SCIFA5_SCK, GPIO_FN_MFG2_OUT1, \
+ GPIO_FN_PORT248_SCIFB_SCK, GPIO_FN_TPU2TO0, \
+ GPIO_FN_PORT248_I2C_SCL3, GPIO_FN_MSIOF2R_TSCK,
+ GPIO_FN_PORT249_IROUT, GPIO_FN_MFG4_IN1, \
+ GPIO_FN_PORT249_I2C_SDA3, GPIO_FN_MSIOF2R_TSYNC,
+ GPIO_FN_SDHICLK0,
+ GPIO_FN_SDHICD0,
+ GPIO_FN_SDHID0_0,
+ GPIO_FN_SDHID0_1,
+ GPIO_FN_SDHID0_2,
+ GPIO_FN_SDHID0_3,
+ GPIO_FN_SDHICMD0,
+ GPIO_FN_SDHIWP0,
+ GPIO_FN_SDHICLK1,
+ GPIO_FN_SDHID1_0, GPIO_FN_TS_SPSYNC2,
+ GPIO_FN_SDHID1_1, GPIO_FN_TS_SDAT2,
+ GPIO_FN_SDHID1_2, GPIO_FN_TS_SDEN2,
+ GPIO_FN_SDHID1_3, GPIO_FN_TS_SCK2,
+ GPIO_FN_SDHICMD1,
+ GPIO_FN_SDHICLK2,
+ GPIO_FN_SDHID2_0, GPIO_FN_TS_SPSYNC4,
+ GPIO_FN_SDHID2_1, GPIO_FN_TS_SDAT4,
+ GPIO_FN_SDHID2_2, GPIO_FN_TS_SDEN4,
+ GPIO_FN_SDHID2_3, GPIO_FN_TS_SCK4,
+ GPIO_FN_SDHICMD2,
+ GPIO_FN_MMCCLK0,
+ GPIO_FN_MMCD0_0,
+ GPIO_FN_MMCD0_1,
+ GPIO_FN_MMCD0_2,
+ GPIO_FN_MMCD0_3,
+ GPIO_FN_MMCD0_4, GPIO_FN_TS_SPSYNC5,
+ GPIO_FN_MMCD0_5, GPIO_FN_TS_SDAT5,
+ GPIO_FN_MMCD0_6, GPIO_FN_TS_SDEN5,
+ GPIO_FN_MMCD0_7, GPIO_FN_TS_SCK5,
+ GPIO_FN_MMCCMD0,
+ GPIO_FN_RESETOUTS_, GPIO_FN_EXTAL2OUT,
+ GPIO_FN_MCP_WAIT__MCP_FRB,
+ GPIO_FN_MCP_CKO, GPIO_FN_MMCCLK1,
+ GPIO_FN_MCP_D15_MCP_NAF15,
+ GPIO_FN_MCP_D14_MCP_NAF14,
+ GPIO_FN_MCP_D13_MCP_NAF13,
+ GPIO_FN_MCP_D12_MCP_NAF12,
+ GPIO_FN_MCP_D11_MCP_NAF11,
+ GPIO_FN_MCP_D10_MCP_NAF10,
+ GPIO_FN_MCP_D9_MCP_NAF9,
+ GPIO_FN_MCP_D8_MCP_NAF8, GPIO_FN_MMCCMD1,
+ GPIO_FN_MCP_D7_MCP_NAF7, GPIO_FN_MMCD1_7,
+
+ GPIO_FN_MCP_D6_MCP_NAF6, GPIO_FN_MMCD1_6,
+ GPIO_FN_MCP_D5_MCP_NAF5, GPIO_FN_MMCD1_5,
+ GPIO_FN_MCP_D4_MCP_NAF4, GPIO_FN_MMCD1_4,
+ GPIO_FN_MCP_D3_MCP_NAF3, GPIO_FN_MMCD1_3,
+ GPIO_FN_MCP_D2_MCP_NAF2, GPIO_FN_MMCD1_2,
+ GPIO_FN_MCP_D1_MCP_NAF1, GPIO_FN_MMCD1_1,
+ GPIO_FN_MCP_D0_MCP_NAF0, GPIO_FN_MMCD1_0,
+ GPIO_FN_MCP_NBRSTOUT_,
+ GPIO_FN_MCP_WE0__MCP_FWE, GPIO_FN_MCP_RDWR_MCP_FWE,
+
+ /* MSEL2 special case */
+ GPIO_FN_TSIF2_TS_XX1,
+ GPIO_FN_TSIF2_TS_XX2,
+ GPIO_FN_TSIF2_TS_XX3,
+ GPIO_FN_TSIF2_TS_XX4,
+ GPIO_FN_TSIF2_TS_XX5,
+ GPIO_FN_TSIF1_TS_XX1,
+ GPIO_FN_TSIF1_TS_XX2,
+ GPIO_FN_TSIF1_TS_XX3,
+ GPIO_FN_TSIF1_TS_XX4,
+ GPIO_FN_TSIF1_TS_XX5,
+ GPIO_FN_TSIF0_TS_XX1,
+ GPIO_FN_TSIF0_TS_XX2,
+ GPIO_FN_TSIF0_TS_XX3,
+ GPIO_FN_TSIF0_TS_XX4,
+ GPIO_FN_TSIF0_TS_XX5,
+ GPIO_FN_MST1_TS_XX1,
+ GPIO_FN_MST1_TS_XX2,
+ GPIO_FN_MST1_TS_XX3,
+ GPIO_FN_MST1_TS_XX4,
+ GPIO_FN_MST1_TS_XX5,
+ GPIO_FN_MST0_TS_XX1,
+ GPIO_FN_MST0_TS_XX2,
+ GPIO_FN_MST0_TS_XX3,
+ GPIO_FN_MST0_TS_XX4,
+ GPIO_FN_MST0_TS_XX5,
+
+ /* MSEL3 special cases */
+ GPIO_FN_SDHI0_VCCQ_MC0_ON,
+ GPIO_FN_SDHI0_VCCQ_MC0_OFF,
+ GPIO_FN_DEBUG_MON_VIO,
+ GPIO_FN_DEBUG_MON_LCDD,
+ GPIO_FN_LCDC_LCDC0,
+ GPIO_FN_LCDC_LCDC1,
+
+ /* MSEL4 special cases */
+ GPIO_FN_IRQ9_MEM_INT,
+ GPIO_FN_IRQ9_MCP_INT,
+ GPIO_FN_A11,
+ GPIO_FN_KEYOUT8,
+ GPIO_FN_TPU4TO3,
+ GPIO_FN_RESETA_N_PU_ON,
+ GPIO_FN_RESETA_N_PU_OFF,
+ GPIO_FN_EDBGREQ_PD,
+ GPIO_FN_EDBGREQ_PU,
+
+ /* Functions with pull-ups */
+ GPIO_FN_KEYIN0_PU,
+ GPIO_FN_KEYIN1_PU,
+ GPIO_FN_KEYIN2_PU,
+ GPIO_FN_KEYIN3_PU,
+ GPIO_FN_KEYIN4_PU,
+ GPIO_FN_KEYIN5_PU,
+ GPIO_FN_KEYIN6_PU,
+ GPIO_FN_KEYIN7_PU,
+ GPIO_FN_SDHID1_0_PU,
+ GPIO_FN_SDHID1_1_PU,
+ GPIO_FN_SDHID1_2_PU,
+ GPIO_FN_SDHID1_3_PU,
+ GPIO_FN_SDHICMD1_PU,
+ GPIO_FN_MMCCMD0_PU,
+ GPIO_FN_MMCCMD1_PU,
+ GPIO_FN_FSIACK_PU,
+ GPIO_FN_FSIAILR_PU,
+ GPIO_FN_FSIAIBT_PU,
+ GPIO_FN_FSIAISLD_PU,
+};
+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_INVALID,
+ SHDMA_SLAVE_SCIF0_TX,
+ SHDMA_SLAVE_SCIF0_RX,
+ SHDMA_SLAVE_SCIF1_TX,
+ SHDMA_SLAVE_SCIF1_RX,
+ SHDMA_SLAVE_SCIF2_TX,
+ SHDMA_SLAVE_SCIF2_RX,
+ SHDMA_SLAVE_SCIF3_TX,
+ SHDMA_SLAVE_SCIF3_RX,
+ SHDMA_SLAVE_SCIF4_TX,
+ SHDMA_SLAVE_SCIF4_RX,
+ SHDMA_SLAVE_SCIF5_TX,
+ SHDMA_SLAVE_SCIF5_RX,
+ SHDMA_SLAVE_SCIF6_TX,
+ SHDMA_SLAVE_SCIF6_RX,
+ SHDMA_SLAVE_SCIF7_TX,
+ SHDMA_SLAVE_SCIF7_RX,
+ SHDMA_SLAVE_SCIF8_TX,
+ SHDMA_SLAVE_SCIF8_RX,
+ SHDMA_SLAVE_SDHI0_TX,
+ SHDMA_SLAVE_SDHI0_RX,
+ SHDMA_SLAVE_SDHI1_TX,
+ SHDMA_SLAVE_SDHI1_RX,
+ SHDMA_SLAVE_SDHI2_TX,
+ SHDMA_SLAVE_SDHI2_RX,
+ SHDMA_SLAVE_MMCIF_TX,
+ SHDMA_SLAVE_MMCIF_RX,
+};
+
+#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h
new file mode 100644
index 00000000..76a687ee
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/system.h
@@ -0,0 +1,14 @@
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ cpu_reset(0);
+}
+
+#endif
diff --git a/arch/arm/mach-shmobile/include/mach/timex.h b/arch/arm/mach-shmobile/include/mach/timex.h
new file mode 100644
index 00000000..ae0d8d82
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/timex.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_MACH_TIMEX_H
+#define __ASM_MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE 1193180 /* unused i8253 PIT value */
+
+#endif /* __ASM_MACH_TIMEX_H */
diff --git a/arch/arm/mach-shmobile/include/mach/uncompress.h b/arch/arm/mach-shmobile/include/mach/uncompress.h
new file mode 100644
index 00000000..0bd7556b
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/uncompress.h
@@ -0,0 +1,21 @@
+#ifndef __ASM_MACH_UNCOMPRESS_H
+#define __ASM_MACH_UNCOMPRESS_H
+
+/*
+ * This does not append a newline
+ */
+static void putc(int c)
+{
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog()
+
+#endif /* __ASM_MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
new file mode 100644
index 00000000..2b8fd8b9
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_VMALLOC_H
+#define __ASM_MACH_VMALLOC_H
+
+/* Vmalloc at ... - 0xe5ffffff */
+#define VMALLOC_END 0xe6000000UL
+
+#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot.h b/arch/arm/mach-shmobile/include/mach/zboot.h
new file mode 100644
index 00000000..9320aff0
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot.h
@@ -0,0 +1,23 @@
+#ifndef ZBOOT_H
+#define ZBOOT_H
+
+#include <asm/mach-types.h>
+#include <mach/zboot_macros.h>
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#define MACH_TYPE MACH_TYPE_AP4EVB
+#include "mach/head-ap4evb.txt"
+#elif defined(CONFIG_MACH_MACKEREL)
+#define MACH_TYPE MACH_TYPE_MACKEREL
+#include "mach/head-mackerel.txt"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* ZBOOT_H */
diff --git a/arch/arm/mach-shmobile/include/mach/zboot_macros.h b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
new file mode 100644
index 00000000..aa6111fb
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/zboot_macros.h
@@ -0,0 +1,65 @@
+#ifndef __ZBOOT_MACRO_H
+#define __ZBOOT_MACRO_H
+
+/* The LIST command is used to include comments in the script */
+.macro LIST comment
+.endm
+
+/* The ED command is used to write a 32-bit word */
+.macro ED, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STR r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EW command is used to write a 16-bit word */
+.macro EW, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STRH r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The EB command is used to write an 8-bit word */
+.macro EB, addr, data
+ LDR r0, 1f
+ LDR r1, 2f
+ STRB r1, [r0]
+ B 3f
+1 : .long \addr
+2 : .long \data
+3 :
+.endm
+
+/* The WAIT command is used to delay the execution */
+.macro WAIT, time, reg
+ LDR r1, 1f
+ LDR r0, 2f
+ STR r0, [r1]
+10 :
+ LDR r0, [r1]
+ CMP r0, #0x00000000
+ BNE 10b
+ NOP
+ B 3f
+1 : .long \reg
+2 : .long \time * 100
+3 :
+.endm
+
+/* The DD command is used to read a 32-bit word */
+.macro DD, start, end
+ LDR r1, 1f
+ B 2f
+1 : .long \start
+2 :
+.endm
+
+#endif /* __ZBOOT_MACRO_H */
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
new file mode 100644
index 00000000..cc442d19
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -0,0 +1,440 @@
+/*
+ * sh7367 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+ ENABLED,
+ DISABLED,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ DIRC,
+ CRYPT1_ERR, CRYPT2_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMRX,
+ ETM11_ACQCMP, ETM11_FULL,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBDMAC_USHDMI,
+ USBHS_USHI0, USBHS_USHI1,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0,
+ SDHI1,
+ MSU_MSU, MSU_MSU2,
+ IREM,
+ SIU,
+ SPU,
+ IRDA,
+ TPU0, TPU1, TPU2, TPU3, TPU4,
+ LCRC,
+ PINT1, PINT2,
+ TTI20,
+ MISTY,
+ DDM,
+ SDHI2,
+ RWDT0, RWDT1,
+ DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+ DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+
+ /* interrupt groups INTCA */
+ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2,
+ ETM11, ARM11, USBHS, FLCTL, IIC1
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(CRYPT1_ERR, 0x05e0),
+ INTC_VECT(CRYPT2_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(ARM11_IRQPMU, 0x0800), INTC_VECT(ARM11_COMMTX, 0x0840),
+ INTC_VECT(ARM11_COMMRX, 0x0860),
+ INTC_VECT(ETM11_ACQCMP, 0x0880), INTC_VECT(ETM11_FULL, 0x08a0),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+ INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+ INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+ INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+ INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+ INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+ INTC_VECT(IREM, 0x0f60),
+ INTC_VECT(SIU, 0x0fa0),
+ INTC_VECT(SPU, 0x0fc0),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+ INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+ INTC_VECT(TPU4, 0x0520),
+ INTC_VECT(LCRC, 0x0540),
+ INTC_VECT(PINT1, 0x1000), INTC_VECT(PINT2, 0x1020),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(MISTY, 0x1120),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(SDHI2, 0x1200), INTC_VECT(SDHI2, 0x1220),
+ INTC_VECT(SDHI2, 0x1240), INTC_VECT(SDHI2, 0x1260),
+ INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+ INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+ INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+ INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+ DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+ INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+ DMAC_2_DEI5, DMAC_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(ETM11, ETM11_ACQCMP, ETM11_FULL),
+ INTC_GROUP(ARM11, ARM11_IRQPMU, ARM11_COMMTX, ARM11_COMMTX),
+ INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ ARM11_IRQPMU, 0, ARM11_COMMTX, ARM11_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { CRYPT1_ERR, CRYPT2_STD, DIRC, 0,
+ DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { PINT1, PINT2, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, ETM11_FULL, ETM11_ACQCMP } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { DISABLED, ENABLED, ENABLED, ENABLED,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { DISABLED, ENABLED, ENABLED, ENABLED,
+ TTI20, USBDMAC_USHDMI, SPU, SIU } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, USBHS_USHI1, USBHS_USHI0, 0 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ LCRC, MSU_MSU2, IREM, MSU_MSU } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, TPU1,
+ TPU2, TPU3, TPU4, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { DISABLED, ENABLED, ENABLED, ENABLED,
+ MISTY, CMT3, RWDT1, RWDT0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, ETM11, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { CRYPT1_ERR, CRYPT2_STD,
+ CMT1_CMT11, ARM11 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { PINT1, PINT2,
+ CMT1_CMT12, TPU4 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+ MFI_MFIM, USBHS } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+ 0, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, SIU, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, SPU, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 16, 2, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 16, 2, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+ .name = "sh7367-intca",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers),
+};
+
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+ VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3,
+ VIO3_VOU,
+ RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
+ VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2,
+ VPU,
+ SGX530,
+ _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUB, IPMMU_IPMMUS,
+ RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+ MSIOF,
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT,
+ TSIF,
+ IPMMUI,
+ MVI3,
+ ICB,
+ PEP,
+ ASA,
+ BEM,
+ VE2HO,
+ HQE,
+ JPEG,
+ LCDC,
+
+ /* interrupt groups INTCS */
+ _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720),
+ INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760),
+ INTCS_VECT(VIO3_VOU, 0x780),
+ INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
+ INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
+ INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0),
+ INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0),
+ INTCS_VECT(VPU, 0x980),
+ INTCS_VECT(SGX530, 0x9e0),
+ INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20),
+ INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60),
+ INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
+ INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
+ INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60),
+ INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
+ INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+ INTCS_VECT(MSIOF, 0xd20),
+ INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
+ INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
+ INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
+ INTCS_VECT(TMU_TUNI2, 0xec0),
+ INTCS_VECT(CMT, 0xf00),
+ INTCS_VECT(TSIF, 0xf20),
+ INTCS_VECT(IPMMUI, 0xf60),
+ INTCS_VECT(MVI3, 0x420),
+ INTCS_VECT(ICB, 0x480),
+ INTCS_VECT(PEP, 0x4a0),
+ INTCS_VECT(ASA, 0x4c0),
+ INTCS_VECT(BEM, 0x4e0),
+ INTCS_VECT(VE2HO, 0x520),
+ INTCS_VECT(HQE, 0x540),
+ INTCS_VECT(JPEG, 0x560),
+ INTCS_VECT(LCDC, 0x580),
+
+ INTC_VECT(INTCS, 0xf80),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1,
+ _2DDMAC_2DDM2, _2DDMAC_2DDM3),
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
+ RTDMAC_1_DEI2, RTDMAC_1_DEI3),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
+ INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3),
+ INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU,
+ VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { VIO3_VOU, 0, VE2HO, VPU,
+ 0, 0, 0, 0 } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0,
+ BEM, ASA, PEP, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, MVI3, 0,
+ JPEG, HQE, 0, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
+ RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ SGX530, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, 0, 0, CMT,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
+ { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, 0, IPMMUI, TSIF } },
+ { 0xffd20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } },
+ { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
+ TMU_TUNI2, 0 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } },
+ { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd2ffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7367-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
+void __init sh7367_init_irq(void)
+{
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
+}
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
new file mode 100644
index 00000000..3b28743c
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -0,0 +1,620 @@
+/*
+ * sh7372 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+ IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+ DIRC,
+ CRYPT_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBHSDMAC0_USHDMI,
+ _3DG_SGX540,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
+ SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2,
+ IRREM,
+ IRDA,
+ TPU0,
+ TTI20,
+ DDM,
+ SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
+ RWDT0,
+ DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
+ DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ HDMI,
+ SPU2_SPU0, SPU2_SPU1,
+ FSI, FMSI,
+ MIPI_HSI,
+ IPMMU_IPMMUD,
+ CEC_1, CEC_2,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+ MFIS2,
+ CPORTR2S,
+ CMT14, CMT15,
+ MMC_MMC_ERR, MMC_MMC_NOR,
+ IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+ IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3,
+ USB0_USB0I1, USB0_USB0I0,
+ USB1_USB1I1, USB1_USB1I0,
+ USBHSDMAC1_USHDMI,
+
+ /* interrupt groups INTCA */
+ DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+ AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+ INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+ INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ21A, 0x32a0),
+ INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+ INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+ INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+ INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+ INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(CRYPT_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+ INTC_VECT(AP_ARM_COMMRX, 0x0860),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBHSDMAC0_USHDMI, 0x0a00),
+ INTC_VECT(_3DG_SGX540, 0x0a60),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
+ INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
+ INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
+ INTC_VECT(SDHI1_SDHI1I2, 0x0ec0),
+ INTC_VECT(IRREM, 0x0f60),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
+ INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 0x1260),
+ INTC_VECT(RWDT0, 0x1280),
+ INTC_VECT(DMAC1_1_DEI0, 0x2000), INTC_VECT(DMAC1_1_DEI1, 0x2020),
+ INTC_VECT(DMAC1_1_DEI2, 0x2040), INTC_VECT(DMAC1_1_DEI3, 0x2060),
+ INTC_VECT(DMAC1_2_DEI4, 0x2080), INTC_VECT(DMAC1_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC1_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+ INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1320),
+ INTC_VECT(SHWYSTAT_COM, 0x1340),
+ INTC_VECT(HDMI, 0x17e0),
+ INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(MIPI_HSI, 0x18e0),
+ INTC_VECT(IPMMU_IPMMUD, 0x1920),
+ INTC_VECT(CEC_1, 0x1940), INTC_VECT(CEC_2, 0x1960),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+ INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+ INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+ INTC_VECT(MFIS2, 0x1a00),
+ INTC_VECT(CPORTR2S, 0x1a20),
+ INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+ INTC_VECT(MMC_MMC_ERR, 0x1ac0), INTC_VECT(MMC_MMC_NOR, 0x1ae0),
+ INTC_VECT(IIC4_ALI4, 0x1b00), INTC_VECT(IIC4_TACKI4, 0x1b20),
+ INTC_VECT(IIC4_WAITI4, 0x1b40), INTC_VECT(IIC4_DTEI4, 0x1b60),
+ INTC_VECT(IIC3_ALI3, 0x1b80), INTC_VECT(IIC3_TACKI3, 0x1ba0),
+ INTC_VECT(IIC3_WAITI3, 0x1bc0), INTC_VECT(IIC3_DTEI3, 0x1be0),
+ INTC_VECT(USB0_USB0I1, 0x1c80), INTC_VECT(USB0_USB0I0, 0x1ca0),
+ INTC_VECT(USB1_USB1I1, 0x1cc0), INTC_VECT(USB1_USB1I0, 0x1ce0),
+ INTC_VECT(USBHSDMAC1_USHDMI, 0x1d00),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC1_1, DMAC1_1_DEI0,
+ DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3),
+ INTC_GROUP(DMAC1_2, DMAC1_2_DEI4,
+ DMAC1_2_DEI5, DMAC1_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX),
+ INTC_GROUP(AP_ARM2, AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+ INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
+ SDHI0_SDHI0I2, SDHI0_SDHI0I3),
+ INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
+ SDHI1_SDHI1I2),
+ INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
+ SDHI2_SDHI2I2, SDHI2_SDHI2I3),
+ INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { 0, CRYPT_STD, DIRC, 0,
+ DMAC1_1_DEI3, DMAC1_1_DEI2, DMAC1_1_DEI1, DMAC1_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { 0, 0, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC1_2_DADERR, DMAC1_2_DEI5, DMAC1_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
+ TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, 0, 0, _3DG_SGX540 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ 0, 0, IRREM, 0 } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
+ 0, CMT3, 0, RWDT0 } },
+ { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+ { 0, 0, 0, 0,
+ 0, 0, 0, HDMI } },
+ { 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ 0, 0, 0, MIPI_HSI } },
+ { 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+ { 0, IPMMU_IPMMUD, CEC_1, CEC_2,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+ { 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+ { MFIS2, CPORTR2S, CMT14, CMT15,
+ 0, 0, MMC_MMC_ERR, MMC_MMC_NOR } },
+ { 0xe69500a0, 0xe69500e0, 8, /* IMR8A3 / IMCR8A3 */
+ { IIC4_ALI4, IIC4_TACKI4, IIC4_WAITI4, IIC4_DTEI4,
+ IIC3_ALI3, IIC3_TACKI3, IIC3_WAITI3, IIC3_DTEI3 } },
+ { 0xe69500a4, 0xe69500e4, 8, /* IMR9A3 / IMCR9A3 */
+ { 0, 0, 0, 0,
+ USB0_USB0I1, USB0_USB0I0, USB1_USB1I1, USB1_USB1I0 } },
+ { 0xe69500a8, 0xe69500e8, 8, /* IMR10A3 / IMCR10A3 */
+ { USBHSDMAC1_USHDMI, 0, 0, 0,
+ 0, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900018, 0, 32, 4, /* INTPRI20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690001c, 0, 32, 4, /* INTPRI30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, 0 } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { 0, CRYPT_STD,
+ CMT1_CMT11, AP_ARM1 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { 0, 0,
+ CMT1_CMT12, 0 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC1_1, MFI_MFIS,
+ MFI_MFIM, 0 } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC1_2,
+ _3DG_SGX540, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBHSDMAC0_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4,
+ 0/* MSU */, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2,
+ 0/* MSUG */, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, 0, 0, 0 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { 0, CMT3, 0, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, SDHI2 } },
+ { 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { 0, 0, 0, HDMI } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, 0, 0, MIPI_HSI } },
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUD, 0,
+ CEC_1, CEC_2 } },
+ { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+ { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+ CMT14, CMT15 } },
+ { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0,
+ MMC_MMC_ERR, MMC_MMC_NOR } },
+ { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
+ IIC4_WAITI4, IIC4_DTEI4 } },
+ { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
+ IIC3_WAITI3, IIC3_DTEI3 } },
+ { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
+ 0/*TXI*/, 0/*TEI*/} },
+ { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
+ USB1_USB1I1, USB1_USB1I0 } },
+ { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 32, 4, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 32, 4, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900008, 32, 4, /* ICR3A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690000c, 32, 4, /* ICR4A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900028, 0, 8, /* INTREQ20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690002c, 0, 8, /* INTREQ30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
+ intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers);
+
+enum {
+ UNUSED_INTCS = 0,
+ ENABLED_INTCS,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+
+ /* IRQ0S - IRQ31S */
+ VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
+ RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
+ CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
+ /* MFI */
+ /* BBIF2 */
+ VPU,
+ TSIF1,
+ _3DG_SGX530,
+ _2DDMAC,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+ /* KEYSC */
+ /* TTI20 */
+ MSIOF,
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT0,
+ TSIF0,
+ /* CMT2 */
+ LMB,
+ CTI,
+ /* RWDT0 */
+ ICB,
+ JPU_JPEG,
+ LCDC,
+ LCRC,
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
+ ISP,
+ LCDC1,
+ CSIRX,
+ DSITX_DSITX0,
+ DSITX_DSITX1,
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ /* HDMI */
+ TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
+ CMT4,
+ DSITX1_DSITX1_0,
+ DSITX1_DSITX1_1,
+ MFIS2_INTCS, /* Priority always enabled using ENABLED_INTCS */
+ CPORTS2R,
+ /* CEC */
+ JPU6E,
+
+ /* interrupt groups INTCS */
+ RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
+ RTDMAC2_1, RTDMAC2_2, TMU1, DSITX,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ /* IRQ0S - IRQ31S */
+ INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
+ INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
+ INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
+ INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
+ INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
+ INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
+ /* MFI */
+ /* BBIF2 */
+ INTCS_VECT(VPU, 0x980),
+ INTCS_VECT(TSIF1, 0x9a0),
+ INTCS_VECT(_3DG_SGX530, 0x9e0),
+ INTCS_VECT(_2DDMAC, 0xa00),
+ INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
+ INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
+ INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
+ INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
+ INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+ /* KEYSC */
+ /* TTI20 */
+ INTCS_VECT(MSIOF, 0x0d20),
+ INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
+ INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
+ INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
+ INTCS_VECT(TMU_TUNI2, 0xec0),
+ INTCS_VECT(CMT0, 0xf00),
+ INTCS_VECT(TSIF0, 0xf20),
+ /* CMT2 */
+ INTCS_VECT(LMB, 0xf60),
+ INTCS_VECT(CTI, 0x400),
+ /* RWDT0 */
+ INTCS_VECT(ICB, 0x480),
+ INTCS_VECT(JPU_JPEG, 0x560),
+ INTCS_VECT(LCDC, 0x580),
+ INTCS_VECT(LCRC, 0x5a0),
+ INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
+ INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
+ INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0),
+ INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0),
+ INTCS_VECT(ISP, 0x1720),
+ INTCS_VECT(LCDC1, 0x1780),
+ INTCS_VECT(CSIRX, 0x17a0),
+ INTCS_VECT(DSITX_DSITX0, 0x17c0),
+ INTCS_VECT(DSITX_DSITX1, 0x17e0),
+ /* SPU2 */
+ /* FSI */
+ /* FMSI */
+ /* HDMI */
+ INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
+ INTCS_VECT(TMU1_TUNI2, 0x1940),
+ INTCS_VECT(CMT4, 0x1980),
+ INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
+ INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
+ INTCS_VECT(MFIS2_INTCS, 0x1a00),
+ INTCS_VECT(CPORTS2R, 0x1a20),
+ /* CEC */
+ INTCS_VECT(JPU6E, 0x1a80),
+
+ INTC_VECT(INTCS, 0xf80),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
+ RTDMAC_1_DEI2, RTDMAC_1_DEI3),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
+ INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
+ INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+ INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
+ RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
+ INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4,
+ RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
+ INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0),
+ INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
+ VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { 0, 0, 0, VPU,
+ 0, 0, 0, 0 } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { 0, 0, 0, _2DDMAC,
+ 0, 0, 0, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, 0, CTI,
+ JPU_JPEG, 0, LCRC, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
+ RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ _3DG_SGX530, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, 0, 0, CMT0,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
+ { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
+ { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4,
+ RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } },
+ { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
+ { 0, ISP, 0, 0,
+ LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
+ { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
+ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
+ CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } },
+ { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
+ { MFIS2_INTCS, CPORTS2R, 0, 0,
+ JPU6E, 0, 0, 0 } },
+ { 0xffd20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
+ TMU_TUNI2, TSIF1 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } },
+ { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
+ { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } },
+ { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } },
+ { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } },
+ { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } },
+ { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } },
+ { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0,
+ DSITX1_DSITX1_1, 0 } },
+ { 0xffd50038, 0, 16, 4, /* IPROS3 */ { ENABLED_INTCS, CPORTS2R,
+ 0, 0 } },
+ { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd201ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffd50000,
+ .end = 0xffd501ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7372-intcs",
+ .force_enable = ENABLED_INTCS,
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
+void __init sh7372_init_irq(void)
+{
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
+}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
new file mode 100644
index 00000000..fe45154c
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -0,0 +1,646 @@
+/*
+ * sh7377 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED_INTCA = 0,
+ ENABLED,
+ DISABLED,
+
+ /* interrupt sources INTCA */
+ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
+ IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A,
+ IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A,
+ IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A,
+ DIRC,
+ _2DG,
+ CRYPT_STD,
+ IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1,
+ AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMRX,
+ MFI_MFIM, MFI_MFIS,
+ BBIF1, BBIF2,
+ USBDMAC_USHDMI,
+ USBHS_USHI0, USBHS_USHI1,
+ _3DG_SGX540,
+ CMT1_CMT10, CMT1_CMT11, CMT1_CMT12, CMT1_CMT13, CMT2, CMT3,
+ KEYSC_KEY,
+ SCIFA0, SCIFA1, SCIFA2, SCIFA3,
+ MSIOF2, MSIOF1,
+ SCIFA4, SCIFA5, SCIFB,
+ FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
+ SDHI0,
+ SDHI1,
+ MSU_MSU, MSU_MSU2,
+ IRREM,
+ MSUG,
+ IRDA,
+ TPU0, TPU1, TPU2, TPU3, TPU4,
+ LCRC,
+ PINTCA_PINT1, PINTCA_PINT2,
+ TTI20,
+ MISTY,
+ DDM,
+ RWDT0, RWDT1,
+ DMAC_1_DEI0, DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3,
+ DMAC_2_DEI4, DMAC_2_DEI5, DMAC_2_DADERR,
+ DMAC2_1_DEI0, DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3,
+ DMAC2_2_DEI4, DMAC2_2_DEI5, DMAC2_2_DADERR,
+ DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
+ DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
+ SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ ICUSB_ICUSB0, ICUSB_ICUSB1,
+ ICUDMC_ICUDMC1, ICUDMC_ICUDMC2,
+ SPU2_SPU0, SPU2_SPU1,
+ FSI,
+ FMSI,
+ SCUV,
+ IPMMU_IPMMUB,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ, AP_ARM_DMAIRQ, AP_ARM_DMASIRQ,
+ MFIS2,
+ CPORTR2S,
+ CMT14, CMT15,
+ SCIFA6,
+
+ /* interrupt groups INTCA */
+ DMAC_1, DMAC_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
+ AP_ARM1, AP_ARM2, USBHS, SPU2, FLCTL, IIC1,
+ ICUSB, ICUDMC
+};
+
+static struct intc_vect intca_vectors[] __initdata = {
+ INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
+ INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
+ INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
+ INTC_VECT(IRQ6A, 0x02c0), INTC_VECT(IRQ7A, 0x02e0),
+ INTC_VECT(IRQ8A, 0x0300), INTC_VECT(IRQ9A, 0x0320),
+ INTC_VECT(IRQ10A, 0x0340), INTC_VECT(IRQ11A, 0x0360),
+ INTC_VECT(IRQ12A, 0x0380), INTC_VECT(IRQ13A, 0x03a0),
+ INTC_VECT(IRQ14A, 0x03c0), INTC_VECT(IRQ15A, 0x03e0),
+ INTC_VECT(IRQ16A, 0x3200), INTC_VECT(IRQ17A, 0x3220),
+ INTC_VECT(IRQ18A, 0x3240), INTC_VECT(IRQ19A, 0x3260),
+ INTC_VECT(IRQ20A, 0x3280), INTC_VECT(IRQ31A, 0x32a0),
+ INTC_VECT(IRQ22A, 0x32c0), INTC_VECT(IRQ23A, 0x32e0),
+ INTC_VECT(IRQ24A, 0x3300), INTC_VECT(IRQ25A, 0x3320),
+ INTC_VECT(IRQ26A, 0x3340), INTC_VECT(IRQ27A, 0x3360),
+ INTC_VECT(IRQ28A, 0x3380), INTC_VECT(IRQ29A, 0x33a0),
+ INTC_VECT(IRQ30A, 0x33c0), INTC_VECT(IRQ31A, 0x33e0),
+ INTC_VECT(DIRC, 0x0560),
+ INTC_VECT(_2DG, 0x05e0),
+ INTC_VECT(CRYPT_STD, 0x0700),
+ INTC_VECT(IIC1_ALI1, 0x0780), INTC_VECT(IIC1_TACKI1, 0x07a0),
+ INTC_VECT(IIC1_WAITI1, 0x07c0), INTC_VECT(IIC1_DTEI1, 0x07e0),
+ INTC_VECT(AP_ARM_IRQPMU, 0x0800), INTC_VECT(AP_ARM_COMMTX, 0x0840),
+ INTC_VECT(AP_ARM_COMMRX, 0x0860),
+ INTC_VECT(MFI_MFIM, 0x0900), INTC_VECT(MFI_MFIS, 0x0920),
+ INTC_VECT(BBIF1, 0x0940), INTC_VECT(BBIF2, 0x0960),
+ INTC_VECT(USBDMAC_USHDMI, 0x0a00),
+ INTC_VECT(USBHS_USHI0, 0x0a20), INTC_VECT(USBHS_USHI1, 0x0a40),
+ INTC_VECT(_3DG_SGX540, 0x0a60),
+ INTC_VECT(CMT1_CMT10, 0x0b00), INTC_VECT(CMT1_CMT11, 0x0b20),
+ INTC_VECT(CMT1_CMT12, 0x0b40), INTC_VECT(CMT1_CMT13, 0x0b60),
+ INTC_VECT(CMT2, 0x0b80), INTC_VECT(CMT3, 0x0ba0),
+ INTC_VECT(KEYSC_KEY, 0x0be0),
+ INTC_VECT(SCIFA0, 0x0c00), INTC_VECT(SCIFA1, 0x0c20),
+ INTC_VECT(SCIFA2, 0x0c40), INTC_VECT(SCIFA3, 0x0c60),
+ INTC_VECT(MSIOF2, 0x0c80), INTC_VECT(MSIOF1, 0x0d00),
+ INTC_VECT(SCIFA4, 0x0d20), INTC_VECT(SCIFA5, 0x0d40),
+ INTC_VECT(SCIFB, 0x0d60),
+ INTC_VECT(FLCTL_FLSTEI, 0x0d80), INTC_VECT(FLCTL_FLTENDI, 0x0da0),
+ INTC_VECT(FLCTL_FLTREQ0I, 0x0dc0), INTC_VECT(FLCTL_FLTREQ1I, 0x0de0),
+ INTC_VECT(SDHI0, 0x0e00), INTC_VECT(SDHI0, 0x0e20),
+ INTC_VECT(SDHI0, 0x0e40), INTC_VECT(SDHI0, 0x0e60),
+ INTC_VECT(SDHI1, 0x0e80), INTC_VECT(SDHI1, 0x0ea0),
+ INTC_VECT(SDHI1, 0x0ec0), INTC_VECT(SDHI1, 0x0ee0),
+ INTC_VECT(MSU_MSU, 0x0f20), INTC_VECT(MSU_MSU2, 0x0f40),
+ INTC_VECT(IRREM, 0x0f60),
+ INTC_VECT(MSUG, 0x0fa0),
+ INTC_VECT(IRDA, 0x0480),
+ INTC_VECT(TPU0, 0x04a0), INTC_VECT(TPU1, 0x04c0),
+ INTC_VECT(TPU2, 0x04e0), INTC_VECT(TPU3, 0x0500),
+ INTC_VECT(TPU4, 0x0520),
+ INTC_VECT(LCRC, 0x0540),
+ INTC_VECT(PINTCA_PINT1, 0x1000), INTC_VECT(PINTCA_PINT2, 0x1020),
+ INTC_VECT(TTI20, 0x1100),
+ INTC_VECT(MISTY, 0x1120),
+ INTC_VECT(DDM, 0x1140),
+ INTC_VECT(RWDT0, 0x1280), INTC_VECT(RWDT1, 0x12a0),
+ INTC_VECT(DMAC_1_DEI0, 0x2000), INTC_VECT(DMAC_1_DEI1, 0x2020),
+ INTC_VECT(DMAC_1_DEI2, 0x2040), INTC_VECT(DMAC_1_DEI3, 0x2060),
+ INTC_VECT(DMAC_2_DEI4, 0x2080), INTC_VECT(DMAC_2_DEI5, 0x20a0),
+ INTC_VECT(DMAC_2_DADERR, 0x20c0),
+ INTC_VECT(DMAC2_1_DEI0, 0x2100), INTC_VECT(DMAC2_1_DEI1, 0x2120),
+ INTC_VECT(DMAC2_1_DEI2, 0x2140), INTC_VECT(DMAC2_1_DEI3, 0x2160),
+ INTC_VECT(DMAC2_2_DEI4, 0x2180), INTC_VECT(DMAC2_2_DEI5, 0x21a0),
+ INTC_VECT(DMAC2_2_DADERR, 0x21c0),
+ INTC_VECT(DMAC3_1_DEI0, 0x2200), INTC_VECT(DMAC3_1_DEI1, 0x2220),
+ INTC_VECT(DMAC3_1_DEI2, 0x2240), INTC_VECT(DMAC3_1_DEI3, 0x2260),
+ INTC_VECT(DMAC3_2_DEI4, 0x2280), INTC_VECT(DMAC3_2_DEI5, 0x22a0),
+ INTC_VECT(DMAC3_2_DADERR, 0x22c0),
+ INTC_VECT(SHWYSTAT_RT, 0x1300), INTC_VECT(SHWYSTAT_HS, 0x1d20),
+ INTC_VECT(SHWYSTAT_COM, 0x1340),
+ INTC_VECT(ICUSB_ICUSB0, 0x1700), INTC_VECT(ICUSB_ICUSB1, 0x1720),
+ INTC_VECT(ICUDMC_ICUDMC1, 0x1780), INTC_VECT(ICUDMC_ICUDMC2, 0x17a0),
+ INTC_VECT(SPU2_SPU0, 0x1800), INTC_VECT(SPU2_SPU1, 0x1820),
+ INTC_VECT(FSI, 0x1840),
+ INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(SCUV, 0x1880),
+ INTC_VECT(IPMMU_IPMMUB, 0x1900),
+ INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
+ INTC_VECT(AP_ARM_DMAEXTERRIRQ, 0x19a0),
+ INTC_VECT(AP_ARM_DMAIRQ, 0x19c0),
+ INTC_VECT(AP_ARM_DMASIRQ, 0x19e0),
+ INTC_VECT(MFIS2, 0x1a00),
+ INTC_VECT(CPORTR2S, 0x1a20),
+ INTC_VECT(CMT14, 0x1a40), INTC_VECT(CMT15, 0x1a60),
+ INTC_VECT(SCIFA6, 0x1a80),
+};
+
+static struct intc_group intca_groups[] __initdata = {
+ INTC_GROUP(DMAC_1, DMAC_1_DEI0,
+ DMAC_1_DEI1, DMAC_1_DEI2, DMAC_1_DEI3),
+ INTC_GROUP(DMAC_2, DMAC_2_DEI4,
+ DMAC_2_DEI5, DMAC_2_DADERR),
+ INTC_GROUP(DMAC2_1, DMAC2_1_DEI0,
+ DMAC2_1_DEI1, DMAC2_1_DEI2, DMAC2_1_DEI3),
+ INTC_GROUP(DMAC2_2, DMAC2_2_DEI4,
+ DMAC2_2_DEI5, DMAC2_2_DADERR),
+ INTC_GROUP(DMAC3_1, DMAC3_1_DEI0,
+ DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3),
+ INTC_GROUP(DMAC3_2, DMAC3_2_DEI4,
+ DMAC3_2_DEI5, DMAC3_2_DADERR),
+ INTC_GROUP(AP_ARM1, AP_ARM_IRQPMU, AP_ARM_COMMTX, AP_ARM_COMMTX),
+ INTC_GROUP(USBHS, USBHS_USHI0, USBHS_USHI1),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
+ FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
+ INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+ INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
+ INTC_GROUP(ICUSB, ICUSB_ICUSB0, ICUSB_ICUSB1),
+ INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
+};
+
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
+ { 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900048, 0xe6900068, 8, /* INTMSK20A / INTMSKCLR20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690004c, 0xe690006c, 8, /* INTMSK30A / INTMSKCLR30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940080, 0xe69400c0, 8, /* IMR0A / IMCR0A */
+ { DMAC2_1_DEI3, DMAC2_1_DEI2, DMAC2_1_DEI1, DMAC2_1_DEI0,
+ AP_ARM_IRQPMU, 0, AP_ARM_COMMTX, AP_ARM_COMMRX } },
+ { 0xe6940084, 0xe69400c4, 8, /* IMR1A / IMCR1A */
+ { _2DG, CRYPT_STD, DIRC, 0,
+ DMAC_1_DEI3, DMAC_1_DEI2, DMAC_1_DEI1, DMAC_1_DEI0 } },
+ { 0xe6940088, 0xe69400c8, 8, /* IMR2A / IMCR2A */
+ { PINTCA_PINT1, PINTCA_PINT2, 0, 0,
+ BBIF1, BBIF2, MFI_MFIS, MFI_MFIM } },
+ { 0xe694008c, 0xe69400cc, 8, /* IMR3A / IMCR3A */
+ { DMAC3_1_DEI3, DMAC3_1_DEI2, DMAC3_1_DEI1, DMAC3_1_DEI0,
+ DMAC3_2_DADERR, DMAC3_2_DEI5, DMAC3_2_DEI4, IRDA } },
+ { 0xe6940090, 0xe69400d0, 8, /* IMR4A / IMCR4A */
+ { DDM, 0, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6940094, 0xe69400d4, 8, /* IMR5A / IMCR5A */
+ { KEYSC_KEY, DMAC_2_DADERR, DMAC_2_DEI5, DMAC_2_DEI4,
+ SCIFA3, SCIFA2, SCIFA1, SCIFA0 } },
+ { 0xe6940098, 0xe69400d8, 8, /* IMR6A / IMCR6A */
+ { SCIFB, SCIFA5, SCIFA4, MSIOF1,
+ 0, 0, MSIOF2, 0 } },
+ { 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
+ { DISABLED, ENABLED, ENABLED, ENABLED,
+ FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
+ { 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
+ { DISABLED, ENABLED, ENABLED, ENABLED,
+ TTI20, USBDMAC_USHDMI, 0, MSUG } },
+ { 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
+ { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
+ CMT2, USBHS_USHI1, USBHS_USHI0, _3DG_SGX540 } },
+ { 0xe69400a8, 0xe69400e8, 8, /* IMR10A / IMCR10A */
+ { 0, DMAC2_2_DADERR, DMAC2_2_DEI5, DMAC2_2_DEI4,
+ 0, 0, 0, 0 } },
+ { 0xe69400ac, 0xe69400ec, 8, /* IMR11A / IMCR11A */
+ { IIC1_DTEI1, IIC1_WAITI1, IIC1_TACKI1, IIC1_ALI1,
+ LCRC, MSU_MSU2, IRREM, MSU_MSU } },
+ { 0xe69400b0, 0xe69400f0, 8, /* IMR12A / IMCR12A */
+ { 0, 0, TPU0, TPU1,
+ TPU2, TPU3, TPU4, 0 } },
+ { 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
+ { 0, 0, 0, 0,
+ MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
+ { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
+ 0, 0, 0, 0 } },
+ { 0xe6950090, 0xe69500d0, 8, /* IMR4A3 / IMCR4A3 */
+ { ICUSB_ICUSB0, ICUSB_ICUSB1, 0, 0,
+ ICUDMC_ICUDMC1, ICUDMC_ICUDMC2, 0, 0 } },
+ { 0xe6950094, 0xe69500d4, 8, /* IMR5A3 / IMCR5A3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ SCUV, 0, 0, 0 } },
+ { 0xe6950098, 0xe69500d8, 8, /* IMR6A3 / IMCR6A3 */
+ { IPMMU_IPMMUB, 0, 0, 0,
+ AP_ARM_CTIIRQ, AP_ARM_DMAEXTERRIRQ,
+ AP_ARM_DMAIRQ, AP_ARM_DMASIRQ } },
+ { 0xe695009c, 0xe69500dc, 8, /* IMR7A3 / IMCR7A3 */
+ { MFIS2, CPORTR2S, CMT14, CMT15,
+ SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
+ { 0xe6900010, 0, 32, 4, /* INTPRI00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900014, 0, 32, 4, /* INTPRI10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900018, 0, 32, 4, /* INTPRI10A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690001c, 0, 32, 4, /* INTPRI30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+
+ { 0xe6940000, 0, 16, 4, /* IPRAA */ { DMAC3_1, DMAC3_2, CMT2, LCRC } },
+ { 0xe6940004, 0, 16, 4, /* IPRBA */ { IRDA, 0, BBIF1, BBIF2 } },
+ { 0xe6940008, 0, 16, 4, /* IPRCA */ { _2DG, CRYPT_STD,
+ CMT1_CMT11, AP_ARM1 } },
+ { 0xe694000c, 0, 16, 4, /* IPRDA */ { PINTCA_PINT1, PINTCA_PINT2,
+ CMT1_CMT12, TPU4 } },
+ { 0xe6940010, 0, 16, 4, /* IPREA */ { DMAC_1, MFI_MFIS,
+ MFI_MFIM, USBHS } },
+ { 0xe6940014, 0, 16, 4, /* IPRFA */ { KEYSC_KEY, DMAC_2,
+ _3DG_SGX540, CMT1_CMT10 } },
+ { 0xe6940018, 0, 16, 4, /* IPRGA */ { SCIFA0, SCIFA1,
+ SCIFA2, SCIFA3 } },
+ { 0xe694001c, 0, 16, 4, /* IPRGH */ { MSIOF2, USBDMAC_USHDMI,
+ FLCTL, SDHI0 } },
+ { 0xe6940020, 0, 16, 4, /* IPRIA */ { MSIOF1, SCIFA4, MSU_MSU, IIC1 } },
+ { 0xe6940024, 0, 16, 4, /* IPRJA */ { DMAC2_1, DMAC2_2, MSUG, TTI20 } },
+ { 0xe6940028, 0, 16, 4, /* IPRKA */ { 0, CMT1_CMT13, IRREM, SDHI1 } },
+ { 0xe694002c, 0, 16, 4, /* IPRLA */ { TPU0, TPU1, TPU2, TPU3 } },
+ { 0xe6940030, 0, 16, 4, /* IPRMA */ { MISTY, CMT3, RWDT1, RWDT0 } },
+ { 0xe6940034, 0, 16, 4, /* IPRNA */ { SCIFB, SCIFA5, 0, DDM } },
+ { 0xe6940038, 0, 16, 4, /* IPROA */ { 0, 0, DIRC, 0 } },
+ { 0xe6950000, 0, 16, 4, /* IPRAA3 */ { SHWYSTAT, 0, 0, 0 } },
+ { 0xe6950020, 0, 16, 4, /* IPRIA3 */ { ICUSB, 0, 0, 0 } },
+ { 0xe6950024, 0, 16, 4, /* IPRJA3 */ { ICUDMC, 0, 0, 0 } },
+ { 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
+ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { SCUV, 0, 0, 0 } },
+ { 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU_IPMMUB, 0, 0, 0 } },
+ { 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
+ { 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
+ CMT14, CMT15 } },
+ { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { SCIFA6, 0, 0, 0 } },
+};
+
+static struct intc_sense_reg intca_sense_registers[] __initdata = {
+ { 0xe6900000, 16, 2, /* ICR1A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900004, 16, 2, /* ICR2A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900008, 16, 2, /* ICR3A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690000c, 16, 2, /* ICR4A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_mask_reg intca_ack_registers[] __initdata = {
+ { 0xe6900020, 0, 8, /* INTREQ00A */
+ { IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
+ { 0xe6900024, 0, 8, /* INTREQ10A */
+ { IRQ8A, IRQ9A, IRQ10A, IRQ11A, IRQ12A, IRQ13A, IRQ14A, IRQ15A } },
+ { 0xe6900028, 0, 8, /* INTREQ20A */
+ { IRQ16A, IRQ17A, IRQ18A, IRQ19A, IRQ20A, IRQ21A, IRQ22A, IRQ23A } },
+ { 0xe690002c, 0, 8, /* INTREQ30A */
+ { IRQ24A, IRQ25A, IRQ26A, IRQ27A, IRQ28A, IRQ29A, IRQ30A, IRQ31A } },
+};
+
+static struct intc_desc intca_desc __initdata = {
+ .name = "sh7377-intca",
+ .force_enable = ENABLED,
+ .force_disable = DISABLED,
+ .hw = INTC_HW_DESC(intca_vectors, intca_groups,
+ intca_mask_registers, intca_prio_registers,
+ intca_sense_registers, intca_ack_registers),
+};
+
+/* this macro ignore entry which is also in INTCA */
+#define __IGNORE(a...)
+#define __IGNORE0(a...) 0
+
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+ VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
+ RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3,
+ CEU,
+ BEU_BEU0, BEU_BEU1, BEU_BEU2,
+ __IGNORE(MFI)
+ __IGNORE(BBIF2)
+ VPU,
+ TSIF1,
+ __IGNORE(SGX540)
+ _2DDMAC,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR,
+ __IGNORE(KEYSC)
+ __IGNORE(TTI20)
+ __IGNORE(MSIOF)
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT0,
+ TSIF0,
+ __IGNORE(CMT2)
+ LMB,
+ __IGNORE(MSUG)
+ __IGNORE(MSU_MSU, MSU_MSU2)
+ __IGNORE(CTI)
+ MVI3,
+ __IGNORE(RWDT0)
+ __IGNORE(RWDT1)
+ ICB,
+ PEP,
+ ASA,
+ __IGNORE(_2DG)
+ HQE,
+ JPU,
+ LCDC0,
+ __IGNORE(LCRC)
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
+ FRC,
+ LCDC1,
+ CSIRX,
+ DSITX_DSITX0, DSITX_DSITX1,
+ __IGNORE(SPU2_SPU0, SPU2_SPU1)
+ __IGNORE(FSI)
+ __IGNORE(FMSI)
+ __IGNORE(SCUV)
+ TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
+ TSIF2,
+ CMT4,
+ __IGNORE(MFIS2)
+ CPORTS2R,
+
+ /* interrupt groups INTCS */
+ RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU,
+ IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1,
+};
+
+#define INTCS_INTVECT 0x0F80
+static struct intc_vect intcs_vectors[] __initdata = {
+ INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720),
+ INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760),
+ INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820),
+ INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860),
+ INTCS_VECT(CEU, 0x0880),
+ INTCS_VECT(BEU_BEU0, 0x08A0),
+ INTCS_VECT(BEU_BEU1, 0x08C0),
+ INTCS_VECT(BEU_BEU2, 0x08E0),
+ __IGNORE(INTCS_VECT(MFI, 0x0900))
+ __IGNORE(INTCS_VECT(BBIF2, 0x0960))
+ INTCS_VECT(VPU, 0x0980),
+ INTCS_VECT(TSIF1, 0x09A0),
+ __IGNORE(INTCS_VECT(SGX540, 0x09E0))
+ INTCS_VECT(_2DDMAC, 0x0A00),
+ INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0),
+ INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0),
+ INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20),
+ INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80),
+ INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0),
+ INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0),
+ __IGNORE(INTCS_VECT(KEYSC 0x0BE0))
+ __IGNORE(INTCS_VECT(TTI20, 0x0C80))
+ __IGNORE(INTCS_VECT(MSIOF, 0x0D20))
+ INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20),
+ INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60),
+ INTCS_VECT(TMU_TUNI0, 0x0E80),
+ INTCS_VECT(TMU_TUNI1, 0x0EA0),
+ INTCS_VECT(TMU_TUNI2, 0x0EC0),
+ INTCS_VECT(CMT0, 0x0F00),
+ INTCS_VECT(TSIF0, 0x0F20),
+ __IGNORE(INTCS_VECT(CMT2, 0x0F40))
+ INTCS_VECT(LMB, 0x0F60),
+ __IGNORE(INTCS_VECT(MSUG, 0x0F80))
+ __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0))
+ __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0))
+ __IGNORE(INTCS_VECT(CTI, 0x0400))
+ INTCS_VECT(MVI3, 0x0420),
+ __IGNORE(INTCS_VECT(RWDT0, 0x0440))
+ __IGNORE(INTCS_VECT(RWDT1, 0x0460))
+ INTCS_VECT(ICB, 0x0480),
+ INTCS_VECT(PEP, 0x04A0),
+ INTCS_VECT(ASA, 0x04C0),
+ __IGNORE(INTCS_VECT(_2DG, 0x04E0))
+ INTCS_VECT(HQE, 0x0540),
+ INTCS_VECT(JPU, 0x0560),
+ INTCS_VECT(LCDC0, 0x0580),
+ __IGNORE(INTCS_VECT(LCRC, 0x05A0))
+ INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
+ INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
+ INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0),
+ INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0),
+ INTCS_VECT(FRC, 0x1700),
+ INTCS_VECT(LCDC1, 0x1780),
+ INTCS_VECT(CSIRX, 0x17A0),
+ INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0),
+ __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800))
+ __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820))
+ __IGNORE(INTCS_VECT(FSI, 0x1840))
+ __IGNORE(INTCS_VECT(FMSI, 0x1860))
+ __IGNORE(INTCS_VECT(SCUV, 0x1880))
+ INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
+ INTCS_VECT(TMU1_TUNI12, 0x1940),
+ INTCS_VECT(TSIF2, 0x1960),
+ INTCS_VECT(CMT4, 0x1980),
+ __IGNORE(INTCS_VECT(MFIS2, 0x1A00))
+ INTCS_VECT(CPORTS2R, 0x1A20),
+
+ INTC_VECT(INTCS, INTCS_INTVECT),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC1_1,
+ RTDMAC1_1_DEI0, RTDMAC1_1_DEI1,
+ RTDMAC1_1_DEI2, RTDMAC1_1_DEI3),
+ INTC_GROUP(RTDMAC1_2,
+ RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR),
+ INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
+ INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2))
+ INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+ INTC_GROUP(RTDMAC2_1,
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
+ RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
+ INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
+ INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
+ __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1))
+ INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] __initdata = {
+ { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */
+ { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
+ VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
+ { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */
+ { 0, 0, 0, VPU,
+ __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } },
+ { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */
+ { 0, 0, 0, _2DDMAC,
+ __IGNORE0(_2DG), ASA, PEP, ICB } },
+ { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */
+ { 0, 0, MVI3, __IGNORE0(CTI),
+ JPU, HQE, __IGNORE0(LCRC), LCDC0 } },
+ { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */
+ { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4,
+ RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } },
+ __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */
+ { 0, 0, MSIOF, 0,
+ SGX540, 0, TTI20, 0 } })
+ { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */
+ { 0, 0, 0, 0,
+ 0, MSU_MSU, MSU_MSU2, MSUG } })
+ { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */
+ { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */
+ { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ 0, 0, 0, 0 } },
+ { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */
+ { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } },
+ { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */
+ { FRC, 0, 0, 0,
+ LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
+ __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */
+ {SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ SCUV, 0, 0, 0 } })
+ { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */
+ { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2,
+ CMT4, 0, 0, 0 } },
+ { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */
+ { __IGNORE0(MFIS2), CPORTS2R, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xFFD20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } }
+};
+
+static struct intc_prio_reg intcs_prio_registers[] __initdata = {
+ /* IPRAS */
+ { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } },
+ /* IPRBS */
+ { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } },
+ /* IPRCS */
+ __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } })
+ /* IPRES */
+ { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } },
+ /* IPRFS */
+ { 0xFFD20014, 0, 16, 4,
+ { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } },
+ /* IPRGS */
+ { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } },
+ /* IPRHS */
+ { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } },
+ /* IPRIS */
+ { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } },
+ /* IPRJS */
+ __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } })
+ /* IPRKS */
+ { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } },
+ /* IPRLS */
+ { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } },
+ /* IPRMS */
+ { 0xFFD20030, 0, 16, 4,
+ { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } },
+ /* IPRAS3 */
+ { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } },
+ /* IPRBS3 */
+ { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } },
+ /* IPRIS3 */
+ { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } },
+ /* IPRJS3 */
+ { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } },
+ /* IPRKS3 */
+ __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } })
+ /* IPRLS3 */
+ __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } })
+ /* IPRMS3 */
+ { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } },
+ /* IPRNS3 */
+ { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } },
+ /* IPROS3 */
+ { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd500ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7377-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups,
+ intcs_mask_registers, intcs_prio_registers,
+ NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
+#define INTEVTSA 0xFFD20100
+void __init sh7377_init_irq(void)
+{
+ void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE);
+
+ register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ irq_set_handler_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
+}
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
new file mode 100644
index 00000000..a911a60e
--- /dev/null
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -0,0 +1,274 @@
+/*
+ * sh73a0 processor support - INTC hardware block
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sh_intc.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+enum {
+ UNUSED = 0,
+
+ /* interrupt sources INTCS */
+ PINTCS_PINT1, PINTCS_PINT2,
+ RTDMAC_0_DEI0, RTDMAC_0_DEI1, RTDMAC_0_DEI2, RTDMAC_0_DEI3,
+ CEU, MFI, BBIF2, VPU, TSIF1, _3DG_SGX543, _2DDMAC_2DDM0,
+ RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR,
+ KEYSC_KEY, VINT, MSIOF,
+ TMU0_TUNI00, TMU0_TUNI01, TMU0_TUNI02,
+ CMT0, TSIF0, CMT2, LMB, MSUG, MSU_MSU, MSU_MSU2,
+ CTI, RWDT0, ICB, PEP, ASA, JPU_JPEG, LCDC, LCRC,
+ RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
+ RTDMAC_3_DEI10, RTDMAC_3_DEI11,
+ FRC, GCU, LCDC1, CSIRX,
+ DSITX0_DSITX00, DSITX0_DSITX01,
+ SPU2_SPU0, SPU2_SPU1, FSI,
+ TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
+ TSIF2, CMT4, MFIS2, CPORTS2R, TSG, DMASCH1, SCUW,
+ VIO60, VIO61, CEU21, CSI21, DSITX1_DSITX10, DSITX1_DSITX11,
+ DISP, DSRV, EMUX2_EMUX20I, EMUX2_EMUX21I,
+ MSTIF0_MST00I, MSTIF0_MST01I, MSTIF1_MST10I, MSTIF1_MST11I,
+ SPUV,
+
+ /* interrupt groups INTCS */
+ RTDMAC_0, RTDMAC_1, RTDMAC_2, RTDMAC_3,
+ DSITX0, SPU2, TMU1, MSU,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ INTCS_VECT(PINTCS_PINT1, 0x0600), INTCS_VECT(PINTCS_PINT2, 0x0620),
+ INTCS_VECT(RTDMAC_0_DEI0, 0x0800), INTCS_VECT(RTDMAC_0_DEI1, 0x0820),
+ INTCS_VECT(RTDMAC_0_DEI2, 0x0840), INTCS_VECT(RTDMAC_0_DEI3, 0x0860),
+ INTCS_VECT(CEU, 0x0880), INTCS_VECT(MFI, 0x0900),
+ INTCS_VECT(BBIF2, 0x0960), INTCS_VECT(VPU, 0x0980),
+ INTCS_VECT(TSIF1, 0x09a0), INTCS_VECT(_3DG_SGX543, 0x09e0),
+ INTCS_VECT(_2DDMAC_2DDM0, 0x0a00),
+ INTCS_VECT(RTDMAC_1_DEI4, 0x0b80), INTCS_VECT(RTDMAC_1_DEI5, 0x0ba0),
+ INTCS_VECT(RTDMAC_1_DADERR, 0x0bc0),
+ INTCS_VECT(KEYSC_KEY, 0x0be0), INTCS_VECT(VINT, 0x0c80),
+ INTCS_VECT(MSIOF, 0x0d20),
+ INTCS_VECT(TMU0_TUNI00, 0x0e80), INTCS_VECT(TMU0_TUNI01, 0x0ea0),
+ INTCS_VECT(TMU0_TUNI02, 0x0ec0),
+ INTCS_VECT(CMT0, 0x0f00), INTCS_VECT(TSIF0, 0x0f20),
+ INTCS_VECT(CMT2, 0x0f40), INTCS_VECT(LMB, 0x0f60),
+ INTCS_VECT(MSUG, 0x0f80),
+ INTCS_VECT(MSU_MSU, 0x0fa0), INTCS_VECT(MSU_MSU2, 0x0fc0),
+ INTCS_VECT(CTI, 0x0400), INTCS_VECT(RWDT0, 0x0440),
+ INTCS_VECT(ICB, 0x0480), INTCS_VECT(PEP, 0x04a0),
+ INTCS_VECT(ASA, 0x04c0), INTCS_VECT(JPU_JPEG, 0x0560),
+ INTCS_VECT(LCDC, 0x0580), INTCS_VECT(LCRC, 0x05a0),
+ INTCS_VECT(RTDMAC_2_DEI6, 0x1300), INTCS_VECT(RTDMAC_2_DEI7, 0x1320),
+ INTCS_VECT(RTDMAC_2_DEI8, 0x1340), INTCS_VECT(RTDMAC_2_DEI9, 0x1360),
+ INTCS_VECT(RTDMAC_3_DEI10, 0x1380), INTCS_VECT(RTDMAC_3_DEI11, 0x13a0),
+ INTCS_VECT(FRC, 0x1700), INTCS_VECT(GCU, 0x1760),
+ INTCS_VECT(LCDC1, 0x1780), INTCS_VECT(CSIRX, 0x17a0),
+ INTCS_VECT(DSITX0_DSITX00, 0x17c0), INTCS_VECT(DSITX0_DSITX01, 0x17e0),
+ INTCS_VECT(SPU2_SPU0, 0x1800), INTCS_VECT(SPU2_SPU1, 0x1820),
+ INTCS_VECT(FSI, 0x1840),
+ INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
+ INTCS_VECT(TMU1_TUNI12, 0x1940),
+ INTCS_VECT(TSIF2, 0x1960), INTCS_VECT(CMT4, 0x1980),
+ INTCS_VECT(MFIS2, 0x1a00), INTCS_VECT(CPORTS2R, 0x1a20),
+ INTCS_VECT(TSG, 0x1ae0), INTCS_VECT(DMASCH1, 0x1b00),
+ INTCS_VECT(SCUW, 0x1b40),
+ INTCS_VECT(VIO60, 0x1b60), INTCS_VECT(VIO61, 0x1b80),
+ INTCS_VECT(CEU21, 0x1ba0), INTCS_VECT(CSI21, 0x1be0),
+ INTCS_VECT(DSITX1_DSITX10, 0x1c00), INTCS_VECT(DSITX1_DSITX11, 0x1c20),
+ INTCS_VECT(DISP, 0x1c40), INTCS_VECT(DSRV, 0x1c60),
+ INTCS_VECT(EMUX2_EMUX20I, 0x1c80), INTCS_VECT(EMUX2_EMUX21I, 0x1ca0),
+ INTCS_VECT(MSTIF0_MST00I, 0x1cc0), INTCS_VECT(MSTIF0_MST01I, 0x1ce0),
+ INTCS_VECT(MSTIF1_MST10I, 0x1d00), INTCS_VECT(MSTIF1_MST11I, 0x1d20),
+ INTCS_VECT(SPUV, 0x2300),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC_0, RTDMAC_0_DEI0, RTDMAC_0_DEI1,
+ RTDMAC_0_DEI2, RTDMAC_0_DEI3),
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI4, RTDMAC_1_DEI5, RTDMAC_1_DADERR),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI6, RTDMAC_2_DEI7,
+ RTDMAC_2_DEI8, RTDMAC_2_DEI9),
+ INTC_GROUP(RTDMAC_3, RTDMAC_3_DEI10, RTDMAC_3_DEI11),
+ INTC_GROUP(TMU1, TMU1_TUNI12, TMU1_TUNI11, TMU1_TUNI10),
+ INTC_GROUP(DSITX0, DSITX0_DSITX00, DSITX0_DSITX01),
+ INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1),
+ INTC_GROUP(MSU, MSU_MSU, MSU_MSU2),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { 0, 0, 0, CEU,
+ 0, 0, 0, 0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { 0, 0, 0, VPU,
+ BBIF2, 0, 0, MFI } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { 0, 0, 0, _2DDMAC_2DDM0,
+ 0, ASA, PEP, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, 0, CTI,
+ JPU_JPEG, 0, LCRC, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { KEYSC_KEY, RTDMAC_1_DADERR, RTDMAC_1_DEI5, RTDMAC_1_DEI4,
+ RTDMAC_0_DEI3, RTDMAC_0_DEI2, RTDMAC_0_DEI1, RTDMAC_0_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ _3DG_SGX543, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU0_TUNI02, TMU0_TUNI01, TMU0_TUNI00,
+ 0, 0, 0, 0 } },
+ { 0xffd201a0, 0xffd201e0, 8, /* IMR8SA / IMCR8SA */
+ { 0, 0, 0, 0,
+ 0, MSU_MSU, MSU_MSU2, MSUG } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, RWDT0, CMT2, CMT0,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { 0, 0, 0, 0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xffd201b0, 0xffd201f0, 8, /* IMR12SA / IMCR12SA */
+ { 0, 0, 0, 0,
+ 0, 0, PINTCS_PINT2, PINTCS_PINT1 } },
+ { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
+ { RTDMAC_2_DEI6, RTDMAC_2_DEI7, RTDMAC_2_DEI8, RTDMAC_2_DEI9,
+ RTDMAC_3_DEI10, RTDMAC_3_DEI11, 0, 0 } },
+ { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
+ { FRC, 0, 0, GCU,
+ LCDC1, CSIRX, DSITX0_DSITX00, DSITX0_DSITX01 } },
+ { 0xffd50194, 0xffd501d4, 8, /* IMR5SA3 / IMCR5SA3 */
+ { SPU2_SPU0, SPU2_SPU1, FSI, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
+ { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, 0,
+ TSIF2, CMT4, 0, 0 } },
+ { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
+ { MFIS2, CPORTS2R, 0, 0,
+ 0, 0, 0, TSG } },
+ { 0xffd501a0, 0xffd501e0, 8, /* IMR8SA3 / IMCR8SA3 */
+ { DMASCH1, 0, SCUW, VIO60,
+ VIO61, CEU21, 0, CSI21 } },
+ { 0xffd501a4, 0xffd501e4, 8, /* IMR9SA3 / IMCR9SA3 */
+ { DSITX1_DSITX10, DSITX1_DSITX11, DISP, DSRV,
+ EMUX2_EMUX20I, EMUX2_EMUX21I, MSTIF0_MST00I, MSTIF0_MST01I } },
+ { 0xffd501a8, 0xffd501e8, 8, /* IMR10SA3 / IMCR10SA3 */
+ { MSTIF0_MST00I, MSTIF0_MST01I, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd60180, 0xffd601c0, 8, /* IMR0SA4 / IMCR0SA4 */
+ { SPUV, 0, 0, 0,
+ 0, 0, 0, 0 } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC_2DDM0, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
+ { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
+ { 0xffd2000c, 0, 16, 4, /* IPRDS */ { PINTCS_PINT1, PINTCS_PINT2,
+ 0, 0 } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_0, CEU, MFI, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { KEYSC_KEY, RTDMAC_1,
+ CMT2, CMT0 } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU0_TUNI00, TMU0_TUNI01,
+ TMU0_TUNI02, TSIF1 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { VINT, 0, 0, 0 } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, 0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX543, MSUG, MSU } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, ASA, LMB, PEP } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { 0, 0, 0, RWDT0 } },
+ { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC_2, 0, 0, 0 } },
+ { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC_3, 0, 0, 0 } },
+ { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { FRC, 0, 0, 0 } },
+ { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX0, 0 } },
+ { 0xffd50028, 0, 16, 4, /* IPRKS3 */ { SPU2, 0, FSI, 0 } },
+ { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, TSIF2 } },
+ { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, 0, 0, 0 } },
+ { 0xffd50038, 0, 16, 4, /* IPROS3 */ { MFIS2, CPORTS2R, 0, 0 } },
+ { 0xffd50040, 0, 16, 4, /* IPRQS3 */ { DMASCH1, 0, SCUW, VIO60 } },
+ { 0xffd50044, 0, 16, 4, /* IPRRS3 */ { VIO61, CEU21, 0, CSI21 } },
+ { 0xffd50048, 0, 16, 4, /* IPRSS3 */ { DSITX1_DSITX10, DSITX1_DSITX11,
+ DISP, DSRV } },
+ { 0xffd5004c, 0, 16, 4, /* IPRTS3 */ { EMUX2_EMUX20I, EMUX2_EMUX21I,
+ MSTIF0_MST00I, MSTIF0_MST01I } },
+ { 0xffd50050, 0, 16, 4, /* IPRUS3 */ { MSTIF1_MST10I, MSTIF1_MST11I,
+ 0, 0 } },
+ { 0xffd60000, 0, 16, 4, /* IPRAS4 */ { SPUV, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd201ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffd50000,
+ .end = 0xffd501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = 0xffd60000,
+ .end = 0xffd601ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh73a0-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static struct irqaction sh73a0_intcs_cascade;
+
+static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
+{
+ unsigned int evtcodeas = ioread32((void __iomem *)dev_id);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+
+ return IRQ_HANDLED;
+}
+
+static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
+{
+ return 0; /* always allow wakeup */
+}
+
+void __init sh73a0_init_irq(void)
+{
+ void __iomem *gic_dist_base = __io(0xf0001000);
+ void __iomem *gic_cpu_base = __io(0xf0000100);
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+ gic_arch_extn.irq_set_wake = sh73a0_set_wake;
+
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ sh73a0_intcs_cascade.name = "INTCS cascade";
+ sh73a0_intcs_cascade.handler = sh73a0_intcs_demux;
+ sh73a0_intcs_cascade.dev_id = intevtsa;
+ setup_irq(gic_spi(50), &sh73a0_intcs_cascade);
+}
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
new file mode 100644
index 00000000..ad9ccc99
--- /dev/null
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -0,0 +1,26 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile - local timer portion
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * Based on vexpress, 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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/smp_twd.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 = 29;
+ twd_timer_setup(evt);
+ return 0;
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7367.c b/arch/arm/mach-shmobile/pfc-sh7367.c
new file mode 100644
index 00000000..128555e7
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7367.c
@@ -0,0 +1,1801 @@
+/*
+ * sh7367 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7367.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
+ _10(fn, pfx##9, sfx)
+
+#define _273(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
+ _10(fn, pfx##10, sfx), _90(fn, pfx##1, sfx), \
+ _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
+ _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
+ _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
+ _10(fn, pfx##26, sfx), _1(fn, pfx##270, sfx), \
+ _1(fn, pfx##271, sfx), _1(fn, pfx##272, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_273(str) _273(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_273(DATA), /* PORT0_DATA -> PORT272_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_273(IN), /* PORT0_IN -> PORT272_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_273(IN_PU), /* PORT0_IN_PU -> PORT272_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_273(IN_PD), /* PORT0_IN_PD -> PORT272_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_273(OUT), /* PORT0_OUT -> PORT272_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_273(FN_IN), /* PORT0_FN_IN -> PORT272_FN_IN */
+ PORT_273(FN_OUT), /* PORT0_FN_OUT -> PORT272_FN_OUT */
+ PORT_273(FN0), /* PORT0_FN0 -> PORT272_FN0 */
+ PORT_273(FN1), /* PORT0_FN1 -> PORT272_FN1 */
+ PORT_273(FN2), /* PORT0_FN2 -> PORT272_FN2 */
+ PORT_273(FN3), /* PORT0_FN3 -> PORT272_FN3 */
+ PORT_273(FN4), /* PORT0_FN4 -> PORT272_FN4 */
+ PORT_273(FN5), /* PORT0_FN5 -> PORT272_FN5 */
+ PORT_273(FN6), /* PORT0_FN6 -> PORT272_FN6 */
+ PORT_273(FN7), /* PORT0_FN7 -> PORT272_FN7 */
+
+ MSELBCR_MSEL2_1, MSELBCR_MSEL2_0,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Special Pull-up / Pull-down Functions */
+ PORT48_KEYIN0_PU_MARK, PORT49_KEYIN1_PU_MARK,
+ PORT50_KEYIN2_PU_MARK, PORT55_KEYIN3_PU_MARK,
+ PORT56_KEYIN4_PU_MARK, PORT57_KEYIN5_PU_MARK,
+ PORT58_KEYIN6_PU_MARK,
+
+ /* 49-1 */
+ VBUS0_MARK, CPORT0_MARK, CPORT1_MARK, CPORT2_MARK,
+ CPORT3_MARK, CPORT4_MARK, CPORT5_MARK, CPORT6_MARK,
+ CPORT7_MARK, CPORT8_MARK, CPORT9_MARK, CPORT10_MARK,
+ CPORT11_MARK, SIN2_MARK, CPORT12_MARK, XCTS2_MARK,
+ CPORT13_MARK, RFSPO4_MARK, CPORT14_MARK, RFSPO5_MARK,
+ CPORT15_MARK, CPORT16_MARK, CPORT17_MARK, SOUT2_MARK,
+ CPORT18_MARK, XRTS2_MARK, CPORT19_MARK, CPORT20_MARK,
+ RFSPO6_MARK, CPORT21_MARK, STATUS0_MARK, CPORT22_MARK,
+ STATUS1_MARK, CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+ MPORT0_MARK, MPORT1_MARK, B_SYNLD1_MARK, B_SYNLD2_MARK,
+ XMAINPS_MARK, XDIVPS_MARK, XIDRST_MARK, IDCLK_MARK,
+ IDIO_MARK, SOUT1_MARK, SCIFA4_TXD_MARK,
+ M02_BERDAT_MARK, SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+ XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+ XCTS1_MARK, SCIFA4_CTS_MARK,
+
+ /* 49-2 */
+ HSU_IQ_AGC6_MARK, MFG2_IN2_MARK, MSIOF2_MCK0_MARK,
+ HSU_IQ_AGC5_MARK, MFG2_IN1_MARK, MSIOF2_MCK1_MARK,
+ HSU_IQ_AGC4_MARK, MSIOF2_RSYNC_MARK,
+ HSU_IQ_AGC3_MARK, MFG2_OUT1_MARK, MSIOF2_RSCK_MARK,
+ HSU_IQ_AGC2_MARK, PORT42_KEYOUT0_MARK,
+ HSU_IQ_AGC1_MARK, PORT43_KEYOUT1_MARK,
+ HSU_IQ_AGC0_MARK, PORT44_KEYOUT2_MARK,
+ HSU_IQ_AGC_ST_MARK, PORT45_KEYOUT3_MARK,
+ HSU_IQ_PDO_MARK, PORT46_KEYOUT4_MARK,
+ HSU_IQ_PYO_MARK, PORT47_KEYOUT5_MARK,
+ HSU_EN_TXMUX_G3MO_MARK, PORT48_KEYIN0_MARK,
+ HSU_I_TXMUX_G3MO_MARK, PORT49_KEYIN1_MARK,
+ HSU_Q_TXMUX_G3MO_MARK, PORT50_KEYIN2_MARK,
+ HSU_SYO_MARK, PORT51_MSIOF2_TSYNC_MARK,
+ HSU_SDO_MARK, PORT52_MSIOF2_TSCK_MARK,
+ HSU_TGTTI_G3MO_MARK, PORT53_MSIOF2_TXD_MARK,
+ B_TIME_STAMP_MARK, PORT54_MSIOF2_RXD_MARK,
+ HSU_SDI_MARK, PORT55_KEYIN3_MARK,
+ HSU_SCO_MARK, PORT56_KEYIN4_MARK,
+ HSU_DREQ_MARK, PORT57_KEYIN5_MARK,
+ HSU_DACK_MARK, PORT58_KEYIN6_MARK,
+ HSU_CLK61M_MARK, PORT59_MSIOF2_SS1_MARK,
+ HSU_XRST_MARK, PORT60_MSIOF2_SS2_MARK,
+ PCMCLKO_MARK, SYNC8KO_MARK, DNPCM_A_MARK, UPPCM_A_MARK,
+ XTALB1L_MARK,
+ GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+ GPS_AGC2_MARK, SCIFA0_SCK_MARK,
+ GPS_AGC3_MARK, SCIFA0_TXD_MARK,
+ GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+ GPS_PWRD_MARK, SCIFA0_CTS_MARK,
+ GPS_IM_MARK, GPS_IS_MARK, GPS_QM_MARK, GPS_QS_MARK,
+ SIUBOMC_MARK, TPU2TO0_MARK,
+ SIUCKB_MARK, TPU2TO1_MARK,
+ SIUBOLR_MARK, BBIF2_TSYNC_MARK, TPU2TO2_MARK,
+ SIUBOBT_MARK, BBIF2_TSCK_MARK, TPU2TO3_MARK,
+ SIUBOSLD_MARK, BBIF2_TXD_MARK, TPU3TO0_MARK,
+ SIUBILR_MARK, TPU3TO1_MARK,
+ SIUBIBT_MARK, TPU3TO2_MARK,
+ SIUBISLD_MARK, TPU3TO3_MARK,
+ NMI_MARK, TPU4TO0_MARK,
+ DNPCM_M_MARK, TPU4TO1_MARK, TPU4TO2_MARK, TPU4TO3_MARK,
+ IRQ_TMPB_MARK,
+ PWEN_MARK, MFG1_OUT1_MARK,
+ OVCN_MARK, MFG1_IN1_MARK,
+ OVCN2_MARK, MFG1_IN2_MARK,
+
+ /* 49-3 */
+ RFSPO1_MARK, RFSPO2_MARK, RFSPO3_MARK, PORT93_VIO_CKO2_MARK,
+ USBTERM_MARK, EXTLP_MARK, IDIN_MARK,
+ SCIFA5_CTS_MARK, MFG0_IN1_MARK,
+ SCIFA5_RTS_MARK, MFG0_IN2_MARK,
+ SCIFA5_RXD_MARK,
+ SCIFA5_TXD_MARK,
+ SCIFA5_SCK_MARK, MFG0_OUT1_MARK,
+ A0_EA0_MARK, BS_MARK,
+ A14_EA14_MARK, PORT102_KEYOUT0_MARK,
+ A15_EA15_MARK, PORT103_KEYOUT1_MARK, DV_CLKOL_MARK,
+ A16_EA16_MARK, PORT104_KEYOUT2_MARK,
+ DV_VSYNCL_MARK, MSIOF0_SS1_MARK,
+ A17_EA17_MARK, PORT105_KEYOUT3_MARK,
+ DV_HSYNCL_MARK, MSIOF0_TSYNC_MARK,
+ A18_EA18_MARK, PORT106_KEYOUT4_MARK,
+ DV_DL0_MARK, MSIOF0_TSCK_MARK,
+ A19_EA19_MARK, PORT107_KEYOUT5_MARK,
+ DV_DL1_MARK, MSIOF0_TXD_MARK,
+ A20_EA20_MARK, PORT108_KEYIN0_MARK,
+ DV_DL2_MARK, MSIOF0_RSCK_MARK,
+ A21_EA21_MARK, PORT109_KEYIN1_MARK,
+ DV_DL3_MARK, MSIOF0_RSYNC_MARK,
+ A22_EA22_MARK, PORT110_KEYIN2_MARK,
+ DV_DL4_MARK, MSIOF0_MCK0_MARK,
+ A23_EA23_MARK, PORT111_KEYIN3_MARK,
+ DV_DL5_MARK, MSIOF0_MCK1_MARK,
+ A24_EA24_MARK, PORT112_KEYIN4_MARK,
+ DV_DL6_MARK, MSIOF0_RXD_MARK,
+ A25_EA25_MARK, PORT113_KEYIN5_MARK,
+ DV_DL7_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, PORT113_KEYIN6_MARK, DV_CLKIL_MARK,
+ D0_ED0_NAF0_MARK, D1_ED1_NAF1_MARK, D2_ED2_NAF2_MARK,
+ D3_ED3_NAF3_MARK, D4_ED4_NAF4_MARK, D5_ED5_NAF5_MARK,
+ D6_ED6_NAF6_MARK, D7_ED7_NAF7_MARK, D8_ED8_NAF8_MARK,
+ D9_ED9_NAF9_MARK, D10_ED10_NAF10_MARK, D11_ED11_NAF11_MARK,
+ D12_ED12_NAF12_MARK, D13_ED13_NAF13_MARK,
+ D14_ED14_NAF14_MARK, D15_ED15_NAF15_MARK,
+ CS4_MARK, CS5A_MARK, CS5B_MARK, FCE1_MARK,
+ CS6B_MARK, XCS2_MARK, FCE0_MARK, CS6A_MARK,
+ DACK0_MARK, WAIT_MARK, DREQ0_MARK, RD_XRD_MARK,
+ A27_MARK, RDWR_XWE_MARK, WE0_XWR0_FWE_MARK,
+ WE1_XWR1_MARK, FRB_MARK, CKO_MARK,
+ NBRSTOUT_MARK, NBRST_MARK,
+
+ /* 49-4 */
+ RFSPO0_MARK, PORT146_VIO_CKO2_MARK, TSTMD_MARK,
+ VIO_VD_MARK, VIO_HD_MARK,
+ VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK,
+ VIO_D3_MARK, VIO_D4_MARK, VIO_D5_MARK,
+ VIO_D6_MARK, VIO_D7_MARK, VIO_D8_MARK,
+ VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+ VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK,
+ VIO_D15_MARK, VIO_CLK_MARK, VIO_FIELD_MARK,
+ VIO_CKO_MARK,
+ MFG3_IN1_MARK, MFG3_IN2_MARK,
+ M9_SLCD_A01_MARK, MFG3_OUT1_MARK, TPU0TO0_MARK,
+ M10_SLCD_CK1_MARK, MFG4_IN1_MARK, TPU0TO1_MARK,
+ M11_SLCD_SO1_MARK, MFG4_IN2_MARK, TPU0TO2_MARK,
+ M12_SLCD_CE1_MARK, MFG4_OUT1_MARK, TPU0TO3_MARK,
+ LCDD0_MARK, PORT175_KEYOUT0_MARK, DV_D0_MARK,
+ SIUCKA_MARK, MFG0_OUT2_MARK,
+ LCDD1_MARK, PORT176_KEYOUT1_MARK, DV_D1_MARK,
+ SIUAOLR_MARK, BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT177_KEYOUT2_MARK, DV_D2_MARK,
+ SIUAOBT_MARK, BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT178_KEYOUT3_MARK, DV_D3_MARK,
+ SIUAOSLD_MARK, BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT179_KEYOUT4_MARK, DV_D4_MARK,
+ SIUAISPD_MARK, MFG1_OUT2_MARK,
+ LCDD5_MARK, PORT180_KEYOUT5_MARK, DV_D5_MARK,
+ SIUAILR_MARK, MFG2_OUT2_MARK,
+ LCDD6_MARK, DV_D6_MARK,
+ SIUAIBT_MARK, MFG3_OUT2_MARK, XWR2_MARK,
+ LCDD7_MARK, DV_D7_MARK,
+ SIUAISLD_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+ LCDD8_MARK, DV_D8_MARK, D16_MARK, ED16_MARK,
+ LCDD9_MARK, DV_D9_MARK, D17_MARK, ED17_MARK,
+ LCDD10_MARK, DV_D10_MARK, D18_MARK, ED18_MARK,
+ LCDD11_MARK, DV_D11_MARK, D19_MARK, ED19_MARK,
+ LCDD12_MARK, DV_D12_MARK, D20_MARK, ED20_MARK,
+ LCDD13_MARK, DV_D13_MARK, D21_MARK, ED21_MARK,
+ LCDD14_MARK, DV_D14_MARK, D22_MARK, ED22_MARK,
+ LCDD15_MARK, DV_D15_MARK, D23_MARK, ED23_MARK,
+ LCDD16_MARK, DV_HSYNC_MARK, D24_MARK, ED24_MARK,
+ LCDD17_MARK, DV_VSYNC_MARK, D25_MARK, ED25_MARK,
+ LCDD18_MARK, DREQ2_MARK, MSIOF0L_TSCK_MARK,
+ D26_MARK, ED26_MARK,
+ LCDD19_MARK, MSIOF0L_TSYNC_MARK,
+ D27_MARK, ED27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK,
+ D28_MARK, ED28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK,
+ D29_MARK, ED29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_SS1_MARK,
+ D30_MARK, ED30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_SS2_MARK,
+ D31_MARK, ED31_MARK,
+ LCDDCK_MARK, LCDWR_MARK, DV_CKO_MARK, SIUAOSPD_MARK,
+ LCDRD_MARK, DACK2_MARK, MSIOF0L_RSYNC_MARK,
+
+ /* 49-5 */
+ LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+ LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_RSCK_MARK,
+ LCDCSYN_MARK, LCDCSYN2_MARK, DV_CKI_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, MSIOF0L_RXD_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, MSIOF0L_TXD_MARK,
+ VIO_DR0_MARK, VIO_DR1_MARK, VIO_DR2_MARK, VIO_DR3_MARK,
+ VIO_DR4_MARK, VIO_DR5_MARK, VIO_DR6_MARK, VIO_DR7_MARK,
+ VIO_VDR_MARK, VIO_HDR_MARK,
+ VIO_CLKR_MARK, VIO_CKOR_MARK,
+ SCIFA1_TXD_MARK, GPS_PGFA0_MARK,
+ SCIFA1_SCK_MARK, GPS_PGFA1_MARK,
+ SCIFA1_RTS_MARK, GPS_EPPSINMON_MARK,
+ SCIFA1_RXD_MARK, SCIFA1_CTS_MARK,
+ MSIOF1_TXD_MARK, SCIFA1_TXD2_MARK, GPS_TXD_MARK,
+ MSIOF1_TSYNC_MARK, SCIFA1_CTS2_MARK, I2C_SDA2_MARK,
+ MSIOF1_TSCK_MARK, SCIFA1_SCK2_MARK,
+ MSIOF1_RXD_MARK, SCIFA1_RXD2_MARK, GPS_RXD_MARK,
+ MSIOF1_RSCK_MARK, SCIFA1_RTS2_MARK,
+ MSIOF1_RSYNC_MARK, I2C_SCL2_MARK,
+ MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+ MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+ MSIOF1_SS2_MARK,
+ PORT236_IROUT_MARK, IRDA_OUT_MARK,
+ IRDA_IN_MARK, IRDA_FIRSEL_MARK,
+ TPU1TO0_MARK, TS_SPSYNC3_MARK,
+ TPU1TO1_MARK, TS_SDAT3_MARK,
+ TPU1TO2_MARK, TS_SDEN3_MARK, PORT241_MSIOF2_SS1_MARK,
+ TPU1TO3_MARK, PORT242_MSIOF2_TSCK_MARK,
+ M13_BSW_MARK, PORT243_MSIOF2_TSYNC_MARK,
+ M14_GSW_MARK, PORT244_MSIOF2_TXD_MARK,
+ PORT245_IROUT_MARK, M15_RSW_MARK,
+ SOUT3_MARK, SCIFA2_TXD1_MARK,
+ SIN3_MARK, SCIFA2_RXD1_MARK,
+ XRTS3_MARK, SCIFA2_RTS1_MARK, PORT248_MSIOF2_SS2_MARK,
+ XCTS3_MARK, SCIFA2_CTS1_MARK, PORT249_MSIOF2_RXD_MARK,
+ DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+ SDHICLK0_MARK, TCK2_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK, TMS2_MARK,
+ SDHID0_1_MARK, TDO2_MARK,
+ SDHID0_2_MARK, TDI2_MARK,
+ SDHID0_3_MARK, RTCK2_MARK,
+
+ /* 49-6 */
+ SDHICMD0_MARK, TRST2_MARK,
+ SDHIWP0_MARK, EDBGREQ2_MARK,
+ SDHICLK1_MARK, TCK3_MARK,
+ SDHID1_0_MARK, M11_SLCD_SO2_MARK,
+ TS_SPSYNC2_MARK, TMS3_MARK,
+ SDHID1_1_MARK, M9_SLCD_AO2_MARK,
+ TS_SDAT2_MARK, TDO3_MARK,
+ SDHID1_2_MARK, M10_SLCD_CK2_MARK,
+ TS_SDEN2_MARK, TDI3_MARK,
+ SDHID1_3_MARK, M12_SLCD_CE2_MARK,
+ TS_SCK2_MARK, RTCK3_MARK,
+ SDHICMD1_MARK, TRST3_MARK,
+ SDHICLK2_MARK, SCIFB_SCK_MARK,
+ SDHID2_0_MARK, SCIFB_TXD_MARK,
+ SDHID2_1_MARK, SCIFB_CTS_MARK,
+ SDHID2_2_MARK, SCIFB_RXD_MARK,
+ SDHID2_3_MARK, SCIFB_RTS_MARK,
+ SDHICMD2_MARK,
+ RESETOUTS_MARK,
+ DIVLOCK_MARK,
+ PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* specify valid pin states for each pin in GPIO mode */
+
+ /* 49-1 (GPIO) */
+ PORT_DATA_I_PD(0),
+ PORT_DATA_I_PU(1), PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+ PORT_DATA_I_PU(4), PORT_DATA_I_PU(5), PORT_DATA_I_PU(6),
+ PORT_DATA_I_PU(7), PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+ PORT_DATA_I_PU(10), PORT_DATA_I_PU(11), PORT_DATA_I_PU(12),
+ PORT_DATA_I_PU(13),
+ PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_O(16), PORT_DATA_O(17), PORT_DATA_O(18), PORT_DATA_O(19),
+ PORT_DATA_O(20), PORT_DATA_O(21), PORT_DATA_O(22), PORT_DATA_O(23),
+ PORT_DATA_O(24), PORT_DATA_O(25), PORT_DATA_O(26),
+ PORT_DATA_I_PD(27), PORT_DATA_I_PD(28),
+ PORT_DATA_O(29), PORT_DATA_O(30), PORT_DATA_O(31), PORT_DATA_O(32),
+ PORT_DATA_IO_PU(33),
+ PORT_DATA_O(34),
+ PORT_DATA_I_PU(35),
+ PORT_DATA_O(36),
+ PORT_DATA_I_PU_PD(37),
+
+ /* 49-2 (GPIO) */
+ PORT_DATA_IO_PU_PD(38),
+ PORT_DATA_IO_PD(39), PORT_DATA_IO_PD(40), PORT_DATA_IO_PD(41),
+ PORT_DATA_O(42), PORT_DATA_O(43), PORT_DATA_O(44), PORT_DATA_O(45),
+ PORT_DATA_O(46), PORT_DATA_O(47),
+ PORT_DATA_I_PU_PD(48), PORT_DATA_I_PU_PD(49), PORT_DATA_I_PU_PD(50),
+ PORT_DATA_IO_PD(51), PORT_DATA_IO_PD(52),
+ PORT_DATA_O(53),
+ PORT_DATA_IO_PD(54),
+ PORT_DATA_I_PU_PD(55),
+ PORT_DATA_IO_PU_PD(56),
+ PORT_DATA_I_PU_PD(57),
+ PORT_DATA_IO_PU_PD(58),
+ PORT_DATA_O(59), PORT_DATA_O(60), PORT_DATA_O(61), PORT_DATA_O(62),
+ PORT_DATA_O(63),
+ PORT_DATA_I_PU(64),
+ PORT_DATA_O(65), PORT_DATA_O(66), PORT_DATA_O(67), PORT_DATA_O(68),
+ PORT_DATA_IO_PD(69), PORT_DATA_IO_PD(70),
+ PORT_DATA_I_PD(71), PORT_DATA_I_PD(72), PORT_DATA_I_PD(73),
+ PORT_DATA_I_PD(74),
+ PORT_DATA_IO_PU_PD(75), PORT_DATA_IO_PU_PD(76),
+ PORT_DATA_IO_PD(77), PORT_DATA_IO_PD(78),
+ PORT_DATA_O(79),
+ PORT_DATA_IO_PD(80), PORT_DATA_IO_PD(81), PORT_DATA_IO_PD(82),
+ PORT_DATA_IO_PU_PD(83), PORT_DATA_IO_PU_PD(84),
+ PORT_DATA_IO_PU_PD(85), PORT_DATA_IO_PU_PD(86),
+ PORT_DATA_I_PD(87),
+ PORT_DATA_IO_PU_PD(88),
+ PORT_DATA_I_PU_PD(89), PORT_DATA_I_PU_PD(90),
+
+ /* 49-3 (GPIO) */
+ PORT_DATA_O(91), PORT_DATA_O(92), PORT_DATA_O(93), PORT_DATA_O(94),
+ PORT_DATA_I_PU_PD(95),
+ PORT_DATA_IO_PU_PD(96), PORT_DATA_IO_PU_PD(97), PORT_DATA_IO_PU_PD(98),
+ PORT_DATA_IO_PU_PD(99), PORT_DATA_IO_PU_PD(100),
+ PORT_DATA_IO(101), PORT_DATA_IO(102), PORT_DATA_IO(103),
+ PORT_DATA_IO_PD(104), PORT_DATA_IO_PD(105), PORT_DATA_IO_PD(106),
+ PORT_DATA_IO_PD(107),
+ PORT_DATA_IO_PU_PD(108), PORT_DATA_IO_PU_PD(109),
+ PORT_DATA_IO_PU_PD(110), PORT_DATA_IO_PU_PD(111),
+ PORT_DATA_IO_PU_PD(112), PORT_DATA_IO_PU_PD(113),
+ PORT_DATA_IO_PU_PD(114),
+ PORT_DATA_IO_PU(115), PORT_DATA_IO_PU(116), PORT_DATA_IO_PU(117),
+ PORT_DATA_IO_PU(118), PORT_DATA_IO_PU(119), PORT_DATA_IO_PU(120),
+ PORT_DATA_IO_PU(121), PORT_DATA_IO_PU(122), PORT_DATA_IO_PU(123),
+ PORT_DATA_IO_PU(124), PORT_DATA_IO_PU(125), PORT_DATA_IO_PU(126),
+ PORT_DATA_IO_PU(127), PORT_DATA_IO_PU(128), PORT_DATA_IO_PU(129),
+ PORT_DATA_IO_PU(130),
+ PORT_DATA_O(131), PORT_DATA_O(132), PORT_DATA_O(133),
+ PORT_DATA_IO_PU(134),
+ PORT_DATA_O(135), PORT_DATA_O(136),
+ PORT_DATA_I_PU_PD(137),
+ PORT_DATA_IO(138),
+ PORT_DATA_IO_PU_PD(139),
+ PORT_DATA_IO(140), PORT_DATA_IO(141),
+ PORT_DATA_I_PU(142),
+ PORT_DATA_O(143), PORT_DATA_O(144),
+ PORT_DATA_I_PU(145),
+
+ /* 49-4 (GPIO) */
+ PORT_DATA_O(146),
+ PORT_DATA_I_PU_PD(147),
+ PORT_DATA_I_PD(148), PORT_DATA_I_PD(149),
+ PORT_DATA_IO_PD(150), PORT_DATA_IO_PD(151), PORT_DATA_IO_PD(152),
+ PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154), PORT_DATA_IO_PD(155),
+ PORT_DATA_IO_PD(156), PORT_DATA_IO_PD(157), PORT_DATA_IO_PD(158),
+ PORT_DATA_IO_PD(159), PORT_DATA_IO_PD(160), PORT_DATA_IO_PD(161),
+ PORT_DATA_IO_PD(162), PORT_DATA_IO_PD(163), PORT_DATA_IO_PD(164),
+ PORT_DATA_IO_PD(165), PORT_DATA_IO_PD(166),
+ PORT_DATA_IO_PU_PD(167),
+ PORT_DATA_O(168),
+ PORT_DATA_I_PD(169), PORT_DATA_I_PD(170),
+ PORT_DATA_O(171),
+ PORT_DATA_IO_PD(172), PORT_DATA_IO_PD(173),
+ PORT_DATA_O(174),
+ PORT_DATA_IO_PD(175), PORT_DATA_IO_PD(176), PORT_DATA_IO_PD(177),
+ PORT_DATA_IO_PD(178), PORT_DATA_IO_PD(179), PORT_DATA_IO_PD(180),
+ PORT_DATA_IO_PD(181), PORT_DATA_IO_PD(182), PORT_DATA_IO_PD(183),
+ PORT_DATA_IO_PD(184), PORT_DATA_IO_PD(185), PORT_DATA_IO_PD(186),
+ PORT_DATA_IO_PD(187), PORT_DATA_IO_PD(188), PORT_DATA_IO_PD(189),
+ PORT_DATA_IO_PD(190), PORT_DATA_IO_PD(191), PORT_DATA_IO_PD(192),
+ PORT_DATA_IO_PD(193), PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+ PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197), PORT_DATA_IO_PD(198),
+ PORT_DATA_O(199),
+ PORT_DATA_IO_PD(200),
+
+ /* 49-5 (GPIO) */
+ PORT_DATA_O(201),
+ PORT_DATA_IO_PD(202), PORT_DATA_IO_PD(203),
+ PORT_DATA_I(204),
+ PORT_DATA_O(205),
+ PORT_DATA_IO_PD(206), PORT_DATA_IO_PD(207), PORT_DATA_IO_PD(208),
+ PORT_DATA_IO_PD(209), PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+ PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213), PORT_DATA_IO_PD(214),
+ PORT_DATA_IO_PD(215), PORT_DATA_IO_PD(216),
+ PORT_DATA_O(217),
+ PORT_DATA_I_PU_PD(218), PORT_DATA_I_PU_PD(219),
+ PORT_DATA_O(220), PORT_DATA_O(221), PORT_DATA_O(222),
+ PORT_DATA_I_PD(223),
+ PORT_DATA_I_PU_PD(224),
+ PORT_DATA_O(225),
+ PORT_DATA_IO_PD(226),
+ PORT_DATA_IO_PU_PD(227),
+ PORT_DATA_I_PD(228),
+ PORT_DATA_IO_PD(229), PORT_DATA_IO_PD(230),
+ PORT_DATA_I_PU_PD(231), PORT_DATA_I_PU_PD(232),
+ PORT_DATA_IO_PU_PD(233), PORT_DATA_IO_PU_PD(234),
+ PORT_DATA_I_PU_PD(235),
+ PORT_DATA_O(236),
+ PORT_DATA_I_PD(237),
+ PORT_DATA_IO_PU_PD(238), PORT_DATA_IO_PU_PD(239),
+ PORT_DATA_IO_PD(240), PORT_DATA_IO_PD(241),
+ PORT_DATA_IO_PD(242), PORT_DATA_IO_PD(243),
+ PORT_DATA_O(244),
+ PORT_DATA_IO_PU_PD(245),
+ PORT_DATA_O(246),
+ PORT_DATA_I_PD(247),
+ PORT_DATA_IO_PU_PD(248),
+ PORT_DATA_I_PU_PD(249),
+ PORT_DATA_IO_PD(250), PORT_DATA_IO_PD(251),
+ PORT_DATA_IO_PU_PD(252), PORT_DATA_IO_PU_PD(253),
+ PORT_DATA_IO_PU_PD(254), PORT_DATA_IO_PU_PD(255),
+ PORT_DATA_IO_PU_PD(256),
+
+ /* 49-6 (GPIO) */
+ PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PU_PD(258),
+ PORT_DATA_IO_PD(259),
+ PORT_DATA_IO_PU(260), PORT_DATA_IO_PU(261), PORT_DATA_IO_PU(262),
+ PORT_DATA_IO_PU(263), PORT_DATA_IO_PU(264),
+ PORT_DATA_O(265),
+ PORT_DATA_IO_PU(266), PORT_DATA_IO_PU(267), PORT_DATA_IO_PU(268),
+ PORT_DATA_IO_PU(269), PORT_DATA_IO_PU(270),
+ PORT_DATA_O(271),
+ PORT_DATA_I_PD(272),
+
+ /* Special Pull-up / Pull-down Functions */
+ PINMUX_DATA(PORT48_KEYIN0_PU_MARK, MSELBCR_MSEL2_1,
+ PORT48_FN2, PORT48_IN_PU),
+ PINMUX_DATA(PORT49_KEYIN1_PU_MARK, MSELBCR_MSEL2_1,
+ PORT49_FN2, PORT49_IN_PU),
+ PINMUX_DATA(PORT50_KEYIN2_PU_MARK, MSELBCR_MSEL2_1,
+ PORT50_FN2, PORT50_IN_PU),
+ PINMUX_DATA(PORT55_KEYIN3_PU_MARK, MSELBCR_MSEL2_1,
+ PORT55_FN2, PORT55_IN_PU),
+ PINMUX_DATA(PORT56_KEYIN4_PU_MARK, MSELBCR_MSEL2_1,
+ PORT56_FN2, PORT56_IN_PU),
+ PINMUX_DATA(PORT57_KEYIN5_PU_MARK, MSELBCR_MSEL2_1,
+ PORT57_FN2, PORT57_IN_PU),
+ PINMUX_DATA(PORT58_KEYIN6_PU_MARK, MSELBCR_MSEL2_1,
+ PORT58_FN2, PORT58_IN_PU),
+
+ /* 49-1 (FN) */
+ PINMUX_DATA(VBUS0_MARK, PORT0_FN1),
+ PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+ PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+ PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+ PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+ PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+ PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+ PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+ PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+ PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+ PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+ PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+ PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+ PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+ PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+ PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+ PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+ PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+ PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+ PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+ PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+ PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+ PINMUX_DATA(CPORT17_MARK, PORT18_FN1),
+ PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+ PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+ PINMUX_DATA(XRTS2_MARK, PORT19_FN1),
+ PINMUX_DATA(CPORT19_MARK, PORT20_FN1),
+ PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+ PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+ PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+ PINMUX_DATA(MPORT0_MARK, PORT25_FN1),
+ PINMUX_DATA(MPORT1_MARK, PORT26_FN1),
+ PINMUX_DATA(B_SYNLD1_MARK, PORT27_FN1),
+ PINMUX_DATA(B_SYNLD2_MARK, PORT28_FN1),
+ PINMUX_DATA(XMAINPS_MARK, PORT29_FN1),
+ PINMUX_DATA(XDIVPS_MARK, PORT30_FN1),
+ PINMUX_DATA(XIDRST_MARK, PORT31_FN1),
+ PINMUX_DATA(IDCLK_MARK, PORT32_FN1),
+ PINMUX_DATA(IDIO_MARK, PORT33_FN1),
+ PINMUX_DATA(SOUT1_MARK, PORT34_FN1),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT34_FN2),
+ PINMUX_DATA(M02_BERDAT_MARK, PORT34_FN3),
+ PINMUX_DATA(SIN1_MARK, PORT35_FN1),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT35_FN2),
+ PINMUX_DATA(XWUP_MARK, PORT35_FN3),
+ PINMUX_DATA(XRTS1_MARK, PORT36_FN1),
+ PINMUX_DATA(SCIFA4_RTS_MARK, PORT36_FN2),
+ PINMUX_DATA(M03_BERCLK_MARK, PORT36_FN3),
+ PINMUX_DATA(XCTS1_MARK, PORT37_FN1),
+ PINMUX_DATA(SCIFA4_CTS_MARK, PORT37_FN2),
+
+ /* 49-2 (FN) */
+ PINMUX_DATA(HSU_IQ_AGC6_MARK, PORT38_FN1),
+ PINMUX_DATA(MFG2_IN2_MARK, PORT38_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT38_FN3),
+ PINMUX_DATA(HSU_IQ_AGC5_MARK, PORT39_FN1),
+ PINMUX_DATA(MFG2_IN1_MARK, PORT39_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT39_FN3),
+ PINMUX_DATA(HSU_IQ_AGC4_MARK, PORT40_FN1),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT40_FN3),
+ PINMUX_DATA(HSU_IQ_AGC3_MARK, PORT41_FN1),
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT41_FN2),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT41_FN3),
+ PINMUX_DATA(HSU_IQ_AGC2_MARK, PORT42_FN1),
+ PINMUX_DATA(PORT42_KEYOUT0_MARK, MSELBCR_MSEL2_1, PORT42_FN2),
+ PINMUX_DATA(HSU_IQ_AGC1_MARK, PORT43_FN1),
+ PINMUX_DATA(PORT43_KEYOUT1_MARK, MSELBCR_MSEL2_1, PORT43_FN2),
+ PINMUX_DATA(HSU_IQ_AGC0_MARK, PORT44_FN1),
+ PINMUX_DATA(PORT44_KEYOUT2_MARK, MSELBCR_MSEL2_1, PORT44_FN2),
+ PINMUX_DATA(HSU_IQ_AGC_ST_MARK, PORT45_FN1),
+ PINMUX_DATA(PORT45_KEYOUT3_MARK, MSELBCR_MSEL2_1, PORT45_FN2),
+ PINMUX_DATA(HSU_IQ_PDO_MARK, PORT46_FN1),
+ PINMUX_DATA(PORT46_KEYOUT4_MARK, MSELBCR_MSEL2_1, PORT46_FN2),
+ PINMUX_DATA(HSU_IQ_PYO_MARK, PORT47_FN1),
+ PINMUX_DATA(PORT47_KEYOUT5_MARK, MSELBCR_MSEL2_1, PORT47_FN2),
+ PINMUX_DATA(HSU_EN_TXMUX_G3MO_MARK, PORT48_FN1),
+ PINMUX_DATA(PORT48_KEYIN0_MARK, MSELBCR_MSEL2_1, PORT48_FN2),
+ PINMUX_DATA(HSU_I_TXMUX_G3MO_MARK, PORT49_FN1),
+ PINMUX_DATA(PORT49_KEYIN1_MARK, MSELBCR_MSEL2_1, PORT49_FN2),
+ PINMUX_DATA(HSU_Q_TXMUX_G3MO_MARK, PORT50_FN1),
+ PINMUX_DATA(PORT50_KEYIN2_MARK, MSELBCR_MSEL2_1, PORT50_FN2),
+ PINMUX_DATA(HSU_SYO_MARK, PORT51_FN1),
+ PINMUX_DATA(PORT51_MSIOF2_TSYNC_MARK, PORT51_FN2),
+ PINMUX_DATA(HSU_SDO_MARK, PORT52_FN1),
+ PINMUX_DATA(PORT52_MSIOF2_TSCK_MARK, PORT52_FN2),
+ PINMUX_DATA(HSU_TGTTI_G3MO_MARK, PORT53_FN1),
+ PINMUX_DATA(PORT53_MSIOF2_TXD_MARK, PORT53_FN2),
+ PINMUX_DATA(B_TIME_STAMP_MARK, PORT54_FN1),
+ PINMUX_DATA(PORT54_MSIOF2_RXD_MARK, PORT54_FN2),
+ PINMUX_DATA(HSU_SDI_MARK, PORT55_FN1),
+ PINMUX_DATA(PORT55_KEYIN3_MARK, MSELBCR_MSEL2_1, PORT55_FN2),
+ PINMUX_DATA(HSU_SCO_MARK, PORT56_FN1),
+ PINMUX_DATA(PORT56_KEYIN4_MARK, MSELBCR_MSEL2_1, PORT56_FN2),
+ PINMUX_DATA(HSU_DREQ_MARK, PORT57_FN1),
+ PINMUX_DATA(PORT57_KEYIN5_MARK, MSELBCR_MSEL2_1, PORT57_FN2),
+ PINMUX_DATA(HSU_DACK_MARK, PORT58_FN1),
+ PINMUX_DATA(PORT58_KEYIN6_MARK, MSELBCR_MSEL2_1, PORT58_FN2),
+ PINMUX_DATA(HSU_CLK61M_MARK, PORT59_FN1),
+ PINMUX_DATA(PORT59_MSIOF2_SS1_MARK, PORT59_FN2),
+ PINMUX_DATA(HSU_XRST_MARK, PORT60_FN1),
+ PINMUX_DATA(PORT60_MSIOF2_SS2_MARK, PORT60_FN2),
+ PINMUX_DATA(PCMCLKO_MARK, PORT61_FN1),
+ PINMUX_DATA(SYNC8KO_MARK, PORT62_FN1),
+ PINMUX_DATA(DNPCM_A_MARK, PORT63_FN1),
+ PINMUX_DATA(UPPCM_A_MARK, PORT64_FN1),
+ PINMUX_DATA(XTALB1L_MARK, PORT65_FN1),
+ PINMUX_DATA(GPS_AGC1_MARK, PORT66_FN1),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT66_FN2),
+ PINMUX_DATA(GPS_AGC2_MARK, PORT67_FN1),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT67_FN2),
+ PINMUX_DATA(GPS_AGC3_MARK, PORT68_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT68_FN2),
+ PINMUX_DATA(GPS_AGC4_MARK, PORT69_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT69_FN2),
+ PINMUX_DATA(GPS_PWRD_MARK, PORT70_FN1),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT70_FN2),
+ PINMUX_DATA(GPS_IM_MARK, PORT71_FN1),
+ PINMUX_DATA(GPS_IS_MARK, PORT72_FN1),
+ PINMUX_DATA(GPS_QM_MARK, PORT73_FN1),
+ PINMUX_DATA(GPS_QS_MARK, PORT74_FN1),
+ PINMUX_DATA(SIUBOMC_MARK, PORT75_FN1),
+ PINMUX_DATA(TPU2TO0_MARK, PORT75_FN3),
+ PINMUX_DATA(SIUCKB_MARK, PORT76_FN1),
+ PINMUX_DATA(TPU2TO1_MARK, PORT76_FN3),
+ PINMUX_DATA(SIUBOLR_MARK, PORT77_FN1),
+ PINMUX_DATA(BBIF2_TSYNC_MARK, PORT77_FN2),
+ PINMUX_DATA(TPU2TO2_MARK, PORT77_FN3),
+ PINMUX_DATA(SIUBOBT_MARK, PORT78_FN1),
+ PINMUX_DATA(BBIF2_TSCK_MARK, PORT78_FN2),
+ PINMUX_DATA(TPU2TO3_MARK, PORT78_FN3),
+ PINMUX_DATA(SIUBOSLD_MARK, PORT79_FN1),
+ PINMUX_DATA(BBIF2_TXD_MARK, PORT79_FN2),
+ PINMUX_DATA(TPU3TO0_MARK, PORT79_FN3),
+ PINMUX_DATA(SIUBILR_MARK, PORT80_FN1),
+ PINMUX_DATA(TPU3TO1_MARK, PORT80_FN3),
+ PINMUX_DATA(SIUBIBT_MARK, PORT81_FN1),
+ PINMUX_DATA(TPU3TO2_MARK, PORT81_FN3),
+ PINMUX_DATA(SIUBISLD_MARK, PORT82_FN1),
+ PINMUX_DATA(TPU3TO3_MARK, PORT82_FN3),
+ PINMUX_DATA(NMI_MARK, PORT83_FN1),
+ PINMUX_DATA(TPU4TO0_MARK, PORT83_FN3),
+ PINMUX_DATA(DNPCM_M_MARK, PORT84_FN1),
+ PINMUX_DATA(TPU4TO1_MARK, PORT84_FN3),
+ PINMUX_DATA(TPU4TO2_MARK, PORT85_FN3),
+ PINMUX_DATA(TPU4TO3_MARK, PORT86_FN3),
+ PINMUX_DATA(IRQ_TMPB_MARK, PORT87_FN1),
+ PINMUX_DATA(PWEN_MARK, PORT88_FN1),
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT88_FN2),
+ PINMUX_DATA(OVCN_MARK, PORT89_FN1),
+ PINMUX_DATA(MFG1_IN1_MARK, PORT89_FN2),
+ PINMUX_DATA(OVCN2_MARK, PORT90_FN1),
+ PINMUX_DATA(MFG1_IN2_MARK, PORT90_FN2),
+
+ /* 49-3 (FN) */
+ PINMUX_DATA(RFSPO1_MARK, PORT91_FN1),
+ PINMUX_DATA(RFSPO2_MARK, PORT92_FN1),
+ PINMUX_DATA(RFSPO3_MARK, PORT93_FN1),
+ PINMUX_DATA(PORT93_VIO_CKO2_MARK, PORT93_FN2),
+ PINMUX_DATA(USBTERM_MARK, PORT94_FN1),
+ PINMUX_DATA(EXTLP_MARK, PORT94_FN2),
+ PINMUX_DATA(IDIN_MARK, PORT95_FN1),
+ PINMUX_DATA(SCIFA5_CTS_MARK, PORT96_FN1),
+ PINMUX_DATA(MFG0_IN1_MARK, PORT96_FN2),
+ PINMUX_DATA(SCIFA5_RTS_MARK, PORT97_FN1),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT97_FN2),
+ PINMUX_DATA(SCIFA5_RXD_MARK, PORT98_FN1),
+ PINMUX_DATA(SCIFA5_TXD_MARK, PORT99_FN1),
+ PINMUX_DATA(SCIFA5_SCK_MARK, PORT100_FN1),
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT100_FN2),
+ PINMUX_DATA(A0_EA0_MARK, PORT101_FN1),
+ PINMUX_DATA(BS_MARK, PORT101_FN2),
+ PINMUX_DATA(A14_EA14_MARK, PORT102_FN1),
+ PINMUX_DATA(PORT102_KEYOUT0_MARK, MSELBCR_MSEL2_0, PORT102_FN2),
+ PINMUX_DATA(A15_EA15_MARK, PORT103_FN1),
+ PINMUX_DATA(PORT103_KEYOUT1_MARK, MSELBCR_MSEL2_0, PORT103_FN2),
+ PINMUX_DATA(DV_CLKOL_MARK, PORT103_FN3),
+ PINMUX_DATA(A16_EA16_MARK, PORT104_FN1),
+ PINMUX_DATA(PORT104_KEYOUT2_MARK, MSELBCR_MSEL2_0, PORT104_FN2),
+ PINMUX_DATA(DV_VSYNCL_MARK, PORT104_FN3),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT104_FN4),
+ PINMUX_DATA(A17_EA17_MARK, PORT105_FN1),
+ PINMUX_DATA(PORT105_KEYOUT3_MARK, MSELBCR_MSEL2_0, PORT105_FN2),
+ PINMUX_DATA(DV_HSYNCL_MARK, PORT105_FN3),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT105_FN4),
+ PINMUX_DATA(A18_EA18_MARK, PORT106_FN1),
+ PINMUX_DATA(PORT106_KEYOUT4_MARK, MSELBCR_MSEL2_0, PORT106_FN2),
+ PINMUX_DATA(DV_DL0_MARK, PORT106_FN3),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT106_FN4),
+ PINMUX_DATA(A19_EA19_MARK, PORT107_FN1),
+ PINMUX_DATA(PORT107_KEYOUT5_MARK, MSELBCR_MSEL2_0, PORT107_FN2),
+ PINMUX_DATA(DV_DL1_MARK, PORT107_FN3),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT107_FN4),
+ PINMUX_DATA(A20_EA20_MARK, PORT108_FN1),
+ PINMUX_DATA(PORT108_KEYIN0_MARK, MSELBCR_MSEL2_0, PORT108_FN2),
+ PINMUX_DATA(DV_DL2_MARK, PORT108_FN3),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT108_FN4),
+ PINMUX_DATA(A21_EA21_MARK, PORT109_FN1),
+ PINMUX_DATA(PORT109_KEYIN1_MARK, MSELBCR_MSEL2_0, PORT109_FN2),
+ PINMUX_DATA(DV_DL3_MARK, PORT109_FN3),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT109_FN4),
+ PINMUX_DATA(A22_EA22_MARK, PORT110_FN1),
+ PINMUX_DATA(PORT110_KEYIN2_MARK, MSELBCR_MSEL2_0, PORT110_FN2),
+ PINMUX_DATA(DV_DL4_MARK, PORT110_FN3),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT110_FN4),
+ PINMUX_DATA(A23_EA23_MARK, PORT111_FN1),
+ PINMUX_DATA(PORT111_KEYIN3_MARK, MSELBCR_MSEL2_0, PORT111_FN2),
+ PINMUX_DATA(DV_DL5_MARK, PORT111_FN3),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT111_FN4),
+ PINMUX_DATA(A24_EA24_MARK, PORT112_FN1),
+ PINMUX_DATA(PORT112_KEYIN4_MARK, MSELBCR_MSEL2_0, PORT112_FN2),
+ PINMUX_DATA(DV_DL6_MARK, PORT112_FN3),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT112_FN4),
+ PINMUX_DATA(A25_EA25_MARK, PORT113_FN1),
+ PINMUX_DATA(PORT113_KEYIN5_MARK, MSELBCR_MSEL2_0, PORT113_FN2),
+ PINMUX_DATA(DV_DL7_MARK, PORT113_FN3),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT113_FN4),
+ PINMUX_DATA(A26_MARK, PORT114_FN1),
+ PINMUX_DATA(PORT113_KEYIN6_MARK, MSELBCR_MSEL2_0, PORT114_FN2),
+ PINMUX_DATA(DV_CLKIL_MARK, PORT114_FN3),
+ PINMUX_DATA(D0_ED0_NAF0_MARK, PORT115_FN1),
+ PINMUX_DATA(D1_ED1_NAF1_MARK, PORT116_FN1),
+ PINMUX_DATA(D2_ED2_NAF2_MARK, PORT117_FN1),
+ PINMUX_DATA(D3_ED3_NAF3_MARK, PORT118_FN1),
+ PINMUX_DATA(D4_ED4_NAF4_MARK, PORT119_FN1),
+ PINMUX_DATA(D5_ED5_NAF5_MARK, PORT120_FN1),
+ PINMUX_DATA(D6_ED6_NAF6_MARK, PORT121_FN1),
+ PINMUX_DATA(D7_ED7_NAF7_MARK, PORT122_FN1),
+ PINMUX_DATA(D8_ED8_NAF8_MARK, PORT123_FN1),
+ PINMUX_DATA(D9_ED9_NAF9_MARK, PORT124_FN1),
+ PINMUX_DATA(D10_ED10_NAF10_MARK, PORT125_FN1),
+ PINMUX_DATA(D11_ED11_NAF11_MARK, PORT126_FN1),
+ PINMUX_DATA(D12_ED12_NAF12_MARK, PORT127_FN1),
+ PINMUX_DATA(D13_ED13_NAF13_MARK, PORT128_FN1),
+ PINMUX_DATA(D14_ED14_NAF14_MARK, PORT129_FN1),
+ PINMUX_DATA(D15_ED15_NAF15_MARK, PORT130_FN1),
+ PINMUX_DATA(CS4_MARK, PORT131_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT132_FN1),
+ PINMUX_DATA(CS5B_MARK, PORT133_FN1),
+ PINMUX_DATA(FCE1_MARK, PORT133_FN2),
+ PINMUX_DATA(CS6B_MARK, PORT134_FN1),
+ PINMUX_DATA(XCS2_MARK, PORT134_FN2),
+ PINMUX_DATA(FCE0_MARK, PORT135_FN1),
+ PINMUX_DATA(CS6A_MARK, PORT136_FN1),
+ PINMUX_DATA(DACK0_MARK, PORT136_FN2),
+ PINMUX_DATA(WAIT_MARK, PORT137_FN1),
+ PINMUX_DATA(DREQ0_MARK, PORT137_FN2),
+ PINMUX_DATA(RD_XRD_MARK, PORT138_FN1),
+ PINMUX_DATA(A27_MARK, PORT139_FN1),
+ PINMUX_DATA(RDWR_XWE_MARK, PORT139_FN2),
+ PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT140_FN1),
+ PINMUX_DATA(WE1_XWR1_MARK, PORT141_FN1),
+ PINMUX_DATA(FRB_MARK, PORT142_FN1),
+ PINMUX_DATA(CKO_MARK, PORT143_FN1),
+ PINMUX_DATA(NBRSTOUT_MARK, PORT144_FN1),
+ PINMUX_DATA(NBRST_MARK, PORT145_FN1),
+
+ /* 49-4 (FN) */
+ PINMUX_DATA(RFSPO0_MARK, PORT146_FN1),
+ PINMUX_DATA(PORT146_VIO_CKO2_MARK, PORT146_FN2),
+ PINMUX_DATA(TSTMD_MARK, PORT147_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT148_FN1),
+ PINMUX_DATA(VIO_HD_MARK, PORT149_FN1),
+ PINMUX_DATA(VIO_D0_MARK, PORT150_FN1),
+ PINMUX_DATA(VIO_D1_MARK, PORT151_FN1),
+ PINMUX_DATA(VIO_D2_MARK, PORT152_FN1),
+ PINMUX_DATA(VIO_D3_MARK, PORT153_FN1),
+ PINMUX_DATA(VIO_D4_MARK, PORT154_FN1),
+ PINMUX_DATA(VIO_D5_MARK, PORT155_FN1),
+ PINMUX_DATA(VIO_D6_MARK, PORT156_FN1),
+ PINMUX_DATA(VIO_D7_MARK, PORT157_FN1),
+ PINMUX_DATA(VIO_D8_MARK, PORT158_FN1),
+ PINMUX_DATA(VIO_D9_MARK, PORT159_FN1),
+ PINMUX_DATA(VIO_D10_MARK, PORT160_FN1),
+ PINMUX_DATA(VIO_D11_MARK, PORT161_FN1),
+ PINMUX_DATA(VIO_D12_MARK, PORT162_FN1),
+ PINMUX_DATA(VIO_D13_MARK, PORT163_FN1),
+ PINMUX_DATA(VIO_D14_MARK, PORT164_FN1),
+ PINMUX_DATA(VIO_D15_MARK, PORT165_FN1),
+ PINMUX_DATA(VIO_CLK_MARK, PORT166_FN1),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT167_FN1),
+ PINMUX_DATA(VIO_CKO_MARK, PORT168_FN1),
+ PINMUX_DATA(MFG3_IN1_MARK, PORT169_FN2),
+ PINMUX_DATA(MFG3_IN2_MARK, PORT170_FN2),
+ PINMUX_DATA(M9_SLCD_A01_MARK, PORT171_FN1),
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT171_FN2),
+ PINMUX_DATA(TPU0TO0_MARK, PORT171_FN3),
+ PINMUX_DATA(M10_SLCD_CK1_MARK, PORT172_FN1),
+ PINMUX_DATA(MFG4_IN1_MARK, PORT172_FN2),
+ PINMUX_DATA(TPU0TO1_MARK, PORT172_FN3),
+ PINMUX_DATA(M11_SLCD_SO1_MARK, PORT173_FN1),
+ PINMUX_DATA(MFG4_IN2_MARK, PORT173_FN2),
+ PINMUX_DATA(TPU0TO2_MARK, PORT173_FN3),
+ PINMUX_DATA(M12_SLCD_CE1_MARK, PORT174_FN1),
+ PINMUX_DATA(MFG4_OUT1_MARK, PORT174_FN2),
+ PINMUX_DATA(TPU0TO3_MARK, PORT174_FN3),
+ PINMUX_DATA(LCDD0_MARK, PORT175_FN1),
+ PINMUX_DATA(PORT175_KEYOUT0_MARK, PORT175_FN2),
+ PINMUX_DATA(DV_D0_MARK, PORT175_FN3),
+ PINMUX_DATA(SIUCKA_MARK, PORT175_FN4),
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT175_FN5),
+ PINMUX_DATA(LCDD1_MARK, PORT176_FN1),
+ PINMUX_DATA(PORT176_KEYOUT1_MARK, PORT176_FN2),
+ PINMUX_DATA(DV_D1_MARK, PORT176_FN3),
+ PINMUX_DATA(SIUAOLR_MARK, PORT176_FN4),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT176_FN5),
+ PINMUX_DATA(LCDD2_MARK, PORT177_FN1),
+ PINMUX_DATA(PORT177_KEYOUT2_MARK, PORT177_FN2),
+ PINMUX_DATA(DV_D2_MARK, PORT177_FN3),
+ PINMUX_DATA(SIUAOBT_MARK, PORT177_FN4),
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT177_FN5),
+ PINMUX_DATA(LCDD3_MARK, PORT178_FN1),
+ PINMUX_DATA(PORT178_KEYOUT3_MARK, PORT178_FN2),
+ PINMUX_DATA(DV_D3_MARK, PORT178_FN3),
+ PINMUX_DATA(SIUAOSLD_MARK, PORT178_FN4),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT178_FN5),
+ PINMUX_DATA(LCDD4_MARK, PORT179_FN1),
+ PINMUX_DATA(PORT179_KEYOUT4_MARK, PORT179_FN2),
+ PINMUX_DATA(DV_D4_MARK, PORT179_FN3),
+ PINMUX_DATA(SIUAISPD_MARK, PORT179_FN4),
+ PINMUX_DATA(MFG1_OUT2_MARK, PORT179_FN5),
+ PINMUX_DATA(LCDD5_MARK, PORT180_FN1),
+ PINMUX_DATA(PORT180_KEYOUT5_MARK, PORT180_FN2),
+ PINMUX_DATA(DV_D5_MARK, PORT180_FN3),
+ PINMUX_DATA(SIUAILR_MARK, PORT180_FN4),
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT180_FN5),
+ PINMUX_DATA(LCDD6_MARK, PORT181_FN1),
+ PINMUX_DATA(DV_D6_MARK, PORT181_FN3),
+ PINMUX_DATA(SIUAIBT_MARK, PORT181_FN4),
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT181_FN5),
+ PINMUX_DATA(XWR2_MARK, PORT181_FN7),
+ PINMUX_DATA(LCDD7_MARK, PORT182_FN1),
+ PINMUX_DATA(DV_D7_MARK, PORT182_FN3),
+ PINMUX_DATA(SIUAISLD_MARK, PORT182_FN4),
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT182_FN5),
+ PINMUX_DATA(XWR3_MARK, PORT182_FN7),
+ PINMUX_DATA(LCDD8_MARK, PORT183_FN1),
+ PINMUX_DATA(DV_D8_MARK, PORT183_FN3),
+ PINMUX_DATA(D16_MARK, PORT183_FN6),
+ PINMUX_DATA(ED16_MARK, PORT183_FN7),
+ PINMUX_DATA(LCDD9_MARK, PORT184_FN1),
+ PINMUX_DATA(DV_D9_MARK, PORT184_FN3),
+ PINMUX_DATA(D17_MARK, PORT184_FN6),
+ PINMUX_DATA(ED17_MARK, PORT184_FN7),
+ PINMUX_DATA(LCDD10_MARK, PORT185_FN1),
+ PINMUX_DATA(DV_D10_MARK, PORT185_FN3),
+ PINMUX_DATA(D18_MARK, PORT185_FN6),
+ PINMUX_DATA(ED18_MARK, PORT185_FN7),
+ PINMUX_DATA(LCDD11_MARK, PORT186_FN1),
+ PINMUX_DATA(DV_D11_MARK, PORT186_FN3),
+ PINMUX_DATA(D19_MARK, PORT186_FN6),
+ PINMUX_DATA(ED19_MARK, PORT186_FN7),
+ PINMUX_DATA(LCDD12_MARK, PORT187_FN1),
+ PINMUX_DATA(DV_D12_MARK, PORT187_FN3),
+ PINMUX_DATA(D20_MARK, PORT187_FN6),
+ PINMUX_DATA(ED20_MARK, PORT187_FN7),
+ PINMUX_DATA(LCDD13_MARK, PORT188_FN1),
+ PINMUX_DATA(DV_D13_MARK, PORT188_FN3),
+ PINMUX_DATA(D21_MARK, PORT188_FN6),
+ PINMUX_DATA(ED21_MARK, PORT188_FN7),
+ PINMUX_DATA(LCDD14_MARK, PORT189_FN1),
+ PINMUX_DATA(DV_D14_MARK, PORT189_FN3),
+ PINMUX_DATA(D22_MARK, PORT189_FN6),
+ PINMUX_DATA(ED22_MARK, PORT189_FN7),
+ PINMUX_DATA(LCDD15_MARK, PORT190_FN1),
+ PINMUX_DATA(DV_D15_MARK, PORT190_FN3),
+ PINMUX_DATA(D23_MARK, PORT190_FN6),
+ PINMUX_DATA(ED23_MARK, PORT190_FN7),
+ PINMUX_DATA(LCDD16_MARK, PORT191_FN1),
+ PINMUX_DATA(DV_HSYNC_MARK, PORT191_FN3),
+ PINMUX_DATA(D24_MARK, PORT191_FN6),
+ PINMUX_DATA(ED24_MARK, PORT191_FN7),
+ PINMUX_DATA(LCDD17_MARK, PORT192_FN1),
+ PINMUX_DATA(DV_VSYNC_MARK, PORT192_FN3),
+ PINMUX_DATA(D25_MARK, PORT192_FN6),
+ PINMUX_DATA(ED25_MARK, PORT192_FN7),
+ PINMUX_DATA(LCDD18_MARK, PORT193_FN1),
+ PINMUX_DATA(DREQ2_MARK, PORT193_FN2),
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT193_FN5),
+ PINMUX_DATA(D26_MARK, PORT193_FN6),
+ PINMUX_DATA(ED26_MARK, PORT193_FN7),
+ PINMUX_DATA(LCDD19_MARK, PORT194_FN1),
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT194_FN5),
+ PINMUX_DATA(D27_MARK, PORT194_FN6),
+ PINMUX_DATA(ED27_MARK, PORT194_FN7),
+ PINMUX_DATA(LCDD20_MARK, PORT195_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT195_FN2),
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT195_FN5),
+ PINMUX_DATA(D28_MARK, PORT195_FN6),
+ PINMUX_DATA(ED28_MARK, PORT195_FN7),
+ PINMUX_DATA(LCDD21_MARK, PORT196_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT196_FN2),
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT196_FN5),
+ PINMUX_DATA(D29_MARK, PORT196_FN6),
+ PINMUX_DATA(ED29_MARK, PORT196_FN7),
+ PINMUX_DATA(LCDD22_MARK, PORT197_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT197_FN2),
+ PINMUX_DATA(MSIOF0L_SS1_MARK, PORT197_FN5),
+ PINMUX_DATA(D30_MARK, PORT197_FN6),
+ PINMUX_DATA(ED30_MARK, PORT197_FN7),
+ PINMUX_DATA(LCDD23_MARK, PORT198_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT198_FN2),
+ PINMUX_DATA(MSIOF0L_SS2_MARK, PORT198_FN5),
+ PINMUX_DATA(D31_MARK, PORT198_FN6),
+ PINMUX_DATA(ED31_MARK, PORT198_FN7),
+ PINMUX_DATA(LCDDCK_MARK, PORT199_FN1),
+ PINMUX_DATA(LCDWR_MARK, PORT199_FN2),
+ PINMUX_DATA(DV_CKO_MARK, PORT199_FN3),
+ PINMUX_DATA(SIUAOSPD_MARK, PORT199_FN4),
+ PINMUX_DATA(LCDRD_MARK, PORT200_FN1),
+ PINMUX_DATA(DACK2_MARK, PORT200_FN2),
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT200_FN5),
+
+ /* 49-5 (FN) */
+ PINMUX_DATA(LCDHSYN_MARK, PORT201_FN1),
+ PINMUX_DATA(LCDCS_MARK, PORT201_FN2),
+ PINMUX_DATA(LCDCS2_MARK, PORT201_FN3),
+ PINMUX_DATA(DACK3_MARK, PORT201_FN4),
+ PINMUX_DATA(LCDDISP_MARK, PORT202_FN1),
+ PINMUX_DATA(LCDRS_MARK, PORT202_FN2),
+ PINMUX_DATA(DREQ3_MARK, PORT202_FN4),
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT202_FN5),
+ PINMUX_DATA(LCDCSYN_MARK, PORT203_FN1),
+ PINMUX_DATA(LCDCSYN2_MARK, PORT203_FN2),
+ PINMUX_DATA(DV_CKI_MARK, PORT203_FN3),
+ PINMUX_DATA(LCDLCLK_MARK, PORT204_FN1),
+ PINMUX_DATA(DREQ1_MARK, PORT204_FN3),
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT204_FN5),
+ PINMUX_DATA(LCDDON_MARK, PORT205_FN1),
+ PINMUX_DATA(LCDDON2_MARK, PORT205_FN2),
+ PINMUX_DATA(DACK1_MARK, PORT205_FN3),
+ PINMUX_DATA(MSIOF0L_TXD_MARK, PORT205_FN5),
+ PINMUX_DATA(VIO_DR0_MARK, PORT206_FN1),
+ PINMUX_DATA(VIO_DR1_MARK, PORT207_FN1),
+ PINMUX_DATA(VIO_DR2_MARK, PORT208_FN1),
+ PINMUX_DATA(VIO_DR3_MARK, PORT209_FN1),
+ PINMUX_DATA(VIO_DR4_MARK, PORT210_FN1),
+ PINMUX_DATA(VIO_DR5_MARK, PORT211_FN1),
+ PINMUX_DATA(VIO_DR6_MARK, PORT212_FN1),
+ PINMUX_DATA(VIO_DR7_MARK, PORT213_FN1),
+ PINMUX_DATA(VIO_VDR_MARK, PORT214_FN1),
+ PINMUX_DATA(VIO_HDR_MARK, PORT215_FN1),
+ PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN1),
+ PINMUX_DATA(VIO_CKOR_MARK, PORT217_FN1),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT220_FN2),
+ PINMUX_DATA(GPS_PGFA0_MARK, PORT220_FN3),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT221_FN2),
+ PINMUX_DATA(GPS_PGFA1_MARK, PORT221_FN3),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT222_FN2),
+ PINMUX_DATA(GPS_EPPSINMON_MARK, PORT222_FN3),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT223_FN2),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT224_FN2),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT225_FN1),
+ PINMUX_DATA(SCIFA1_TXD2_MARK, PORT225_FN2),
+ PINMUX_DATA(GPS_TXD_MARK, PORT225_FN3),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT226_FN1),
+ PINMUX_DATA(SCIFA1_CTS2_MARK, PORT226_FN2),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT226_FN3),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT227_FN1),
+ PINMUX_DATA(SCIFA1_SCK2_MARK, PORT227_FN2),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT228_FN1),
+ PINMUX_DATA(SCIFA1_RXD2_MARK, PORT228_FN2),
+ PINMUX_DATA(GPS_RXD_MARK, PORT228_FN3),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT229_FN1),
+ PINMUX_DATA(SCIFA1_RTS2_MARK, PORT229_FN2),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT230_FN1),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT230_FN3),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT231_FN1),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT232_FN1),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT233_FN1),
+ PINMUX_DATA(EDBGREQ3_MARK, PORT233_FN2),
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT234_FN1),
+ PINMUX_DATA(PORT236_IROUT_MARK, PORT236_FN1),
+ PINMUX_DATA(IRDA_OUT_MARK, PORT236_FN2),
+ PINMUX_DATA(IRDA_IN_MARK, PORT237_FN2),
+ PINMUX_DATA(IRDA_FIRSEL_MARK, PORT238_FN1),
+ PINMUX_DATA(TPU1TO0_MARK, PORT239_FN3),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT239_FN4),
+ PINMUX_DATA(TPU1TO1_MARK, PORT240_FN3),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT240_FN4),
+ PINMUX_DATA(TPU1TO2_MARK, PORT241_FN3),
+ PINMUX_DATA(TS_SDEN3_MARK, PORT241_FN4),
+ PINMUX_DATA(PORT241_MSIOF2_SS1_MARK, PORT241_FN5),
+ PINMUX_DATA(TPU1TO3_MARK, PORT242_FN3),
+ PINMUX_DATA(PORT242_MSIOF2_TSCK_MARK, PORT242_FN5),
+ PINMUX_DATA(M13_BSW_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT243_MSIOF2_TSYNC_MARK, PORT243_FN5),
+ PINMUX_DATA(M14_GSW_MARK, PORT244_FN2),
+ PINMUX_DATA(PORT244_MSIOF2_TXD_MARK, PORT244_FN5),
+ PINMUX_DATA(PORT245_IROUT_MARK, PORT245_FN1),
+ PINMUX_DATA(M15_RSW_MARK, PORT245_FN2),
+ PINMUX_DATA(SOUT3_MARK, PORT246_FN1),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT246_FN2),
+ PINMUX_DATA(SIN3_MARK, PORT247_FN1),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT247_FN2),
+ PINMUX_DATA(XRTS3_MARK, PORT248_FN1),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT248_FN2),
+ PINMUX_DATA(PORT248_MSIOF2_SS2_MARK, PORT248_FN5),
+ PINMUX_DATA(XCTS3_MARK, PORT249_FN1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT249_FN2),
+ PINMUX_DATA(PORT249_MSIOF2_RXD_MARK, PORT249_FN5),
+ PINMUX_DATA(DINT_MARK, PORT250_FN1),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT250_FN2),
+ PINMUX_DATA(TS_SCK3_MARK, PORT250_FN4),
+ PINMUX_DATA(SDHICLK0_MARK, PORT251_FN1),
+ PINMUX_DATA(TCK2_MARK, PORT251_FN2),
+ PINMUX_DATA(SDHICD0_MARK, PORT252_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT253_FN1),
+ PINMUX_DATA(TMS2_MARK, PORT253_FN2),
+ PINMUX_DATA(SDHID0_1_MARK, PORT254_FN1),
+ PINMUX_DATA(TDO2_MARK, PORT254_FN2),
+ PINMUX_DATA(SDHID0_2_MARK, PORT255_FN1),
+ PINMUX_DATA(TDI2_MARK, PORT255_FN2),
+ PINMUX_DATA(SDHID0_3_MARK, PORT256_FN1),
+ PINMUX_DATA(RTCK2_MARK, PORT256_FN2),
+
+ /* 49-6 (FN) */
+ PINMUX_DATA(SDHICMD0_MARK, PORT257_FN1),
+ PINMUX_DATA(TRST2_MARK, PORT257_FN2),
+ PINMUX_DATA(SDHIWP0_MARK, PORT258_FN1),
+ PINMUX_DATA(EDBGREQ2_MARK, PORT258_FN2),
+ PINMUX_DATA(SDHICLK1_MARK, PORT259_FN1),
+ PINMUX_DATA(TCK3_MARK, PORT259_FN4),
+ PINMUX_DATA(SDHID1_0_MARK, PORT260_FN1),
+ PINMUX_DATA(M11_SLCD_SO2_MARK, PORT260_FN2),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT260_FN3),
+ PINMUX_DATA(TMS3_MARK, PORT260_FN4),
+ PINMUX_DATA(SDHID1_1_MARK, PORT261_FN1),
+ PINMUX_DATA(M9_SLCD_AO2_MARK, PORT261_FN2),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT261_FN3),
+ PINMUX_DATA(TDO3_MARK, PORT261_FN4),
+ PINMUX_DATA(SDHID1_2_MARK, PORT262_FN1),
+ PINMUX_DATA(M10_SLCD_CK2_MARK, PORT262_FN2),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT262_FN3),
+ PINMUX_DATA(TDI3_MARK, PORT262_FN4),
+ PINMUX_DATA(SDHID1_3_MARK, PORT263_FN1),
+ PINMUX_DATA(M12_SLCD_CE2_MARK, PORT263_FN2),
+ PINMUX_DATA(TS_SCK2_MARK, PORT263_FN3),
+ PINMUX_DATA(RTCK3_MARK, PORT263_FN4),
+ PINMUX_DATA(SDHICMD1_MARK, PORT264_FN1),
+ PINMUX_DATA(TRST3_MARK, PORT264_FN4),
+ PINMUX_DATA(SDHICLK2_MARK, PORT265_FN1),
+ PINMUX_DATA(SCIFB_SCK_MARK, PORT265_FN2),
+ PINMUX_DATA(SDHID2_0_MARK, PORT266_FN1),
+ PINMUX_DATA(SCIFB_TXD_MARK, PORT266_FN2),
+ PINMUX_DATA(SDHID2_1_MARK, PORT267_FN1),
+ PINMUX_DATA(SCIFB_CTS_MARK, PORT267_FN2),
+ PINMUX_DATA(SDHID2_2_MARK, PORT268_FN1),
+ PINMUX_DATA(SCIFB_RXD_MARK, PORT268_FN2),
+ PINMUX_DATA(SDHID2_3_MARK, PORT269_FN1),
+ PINMUX_DATA(SCIFB_RTS_MARK, PORT269_FN2),
+ PINMUX_DATA(SDHICMD2_MARK, PORT270_FN1),
+ PINMUX_DATA(RESETOUTS_MARK, PORT271_FN1),
+ PINMUX_DATA(DIVLOCK_MARK, PORT272_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_273() _273(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* 49-1 -> 49-6 (GPIO) */
+ GPIO_PORT_273(),
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN(PORT48_KEYIN0_PU), GPIO_FN(PORT49_KEYIN1_PU),
+ GPIO_FN(PORT50_KEYIN2_PU), GPIO_FN(PORT55_KEYIN3_PU),
+ GPIO_FN(PORT56_KEYIN4_PU), GPIO_FN(PORT57_KEYIN5_PU),
+ GPIO_FN(PORT58_KEYIN6_PU),
+
+ /* 49-1 (FN) */
+ GPIO_FN(VBUS0), GPIO_FN(CPORT0), GPIO_FN(CPORT1), GPIO_FN(CPORT2),
+ GPIO_FN(CPORT3), GPIO_FN(CPORT4), GPIO_FN(CPORT5), GPIO_FN(CPORT6),
+ GPIO_FN(CPORT7), GPIO_FN(CPORT8), GPIO_FN(CPORT9), GPIO_FN(CPORT10),
+ GPIO_FN(CPORT11), GPIO_FN(SIN2), GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+ GPIO_FN(CPORT13), GPIO_FN(RFSPO4), GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+ GPIO_FN(CPORT15), GPIO_FN(CPORT16), GPIO_FN(CPORT17), GPIO_FN(SOUT2),
+ GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(CPORT19), GPIO_FN(CPORT20),
+ GPIO_FN(RFSPO6), GPIO_FN(CPORT21), GPIO_FN(STATUS0), GPIO_FN(CPORT22),
+ GPIO_FN(STATUS1), GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+ GPIO_FN(MPORT0), GPIO_FN(MPORT1), GPIO_FN(B_SYNLD1), GPIO_FN(B_SYNLD2),
+ GPIO_FN(XMAINPS), GPIO_FN(XDIVPS), GPIO_FN(XIDRST), GPIO_FN(IDCLK),
+ GPIO_FN(IDIO), GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD),
+ GPIO_FN(M02_BERDAT), GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+ GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+ GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+
+ /* 49-2 (FN) */
+ GPIO_FN(HSU_IQ_AGC6), GPIO_FN(MFG2_IN2), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(HSU_IQ_AGC5), GPIO_FN(MFG2_IN1), GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(HSU_IQ_AGC4), GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(HSU_IQ_AGC3), GPIO_FN(MFG2_OUT1), GPIO_FN(MSIOF2_RSCK),
+ GPIO_FN(HSU_IQ_AGC2), GPIO_FN(PORT42_KEYOUT0),
+ GPIO_FN(HSU_IQ_AGC1), GPIO_FN(PORT43_KEYOUT1),
+ GPIO_FN(HSU_IQ_AGC0), GPIO_FN(PORT44_KEYOUT2),
+ GPIO_FN(HSU_IQ_AGC_ST), GPIO_FN(PORT45_KEYOUT3),
+ GPIO_FN(HSU_IQ_PDO), GPIO_FN(PORT46_KEYOUT4),
+ GPIO_FN(HSU_IQ_PYO), GPIO_FN(PORT47_KEYOUT5),
+ GPIO_FN(HSU_EN_TXMUX_G3MO), GPIO_FN(PORT48_KEYIN0),
+ GPIO_FN(HSU_I_TXMUX_G3MO), GPIO_FN(PORT49_KEYIN1),
+ GPIO_FN(HSU_Q_TXMUX_G3MO), GPIO_FN(PORT50_KEYIN2),
+ GPIO_FN(HSU_SYO), GPIO_FN(PORT51_MSIOF2_TSYNC),
+ GPIO_FN(HSU_SDO), GPIO_FN(PORT52_MSIOF2_TSCK),
+ GPIO_FN(HSU_TGTTI_G3MO), GPIO_FN(PORT53_MSIOF2_TXD),
+ GPIO_FN(B_TIME_STAMP), GPIO_FN(PORT54_MSIOF2_RXD),
+ GPIO_FN(HSU_SDI), GPIO_FN(PORT55_KEYIN3),
+ GPIO_FN(HSU_SCO), GPIO_FN(PORT56_KEYIN4),
+ GPIO_FN(HSU_DREQ), GPIO_FN(PORT57_KEYIN5),
+ GPIO_FN(HSU_DACK), GPIO_FN(PORT58_KEYIN6),
+ GPIO_FN(HSU_CLK61M), GPIO_FN(PORT59_MSIOF2_SS1),
+ GPIO_FN(HSU_XRST), GPIO_FN(PORT60_MSIOF2_SS2),
+ GPIO_FN(PCMCLKO), GPIO_FN(SYNC8KO), GPIO_FN(DNPCM_A), GPIO_FN(UPPCM_A),
+ GPIO_FN(XTALB1L),
+ GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+ GPIO_FN(GPS_AGC2), GPIO_FN(SCIFA0_SCK),
+ GPIO_FN(GPS_AGC3), GPIO_FN(SCIFA0_TXD),
+ GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(GPS_PWRD), GPIO_FN(SCIFA0_CTS),
+ GPIO_FN(GPS_IM), GPIO_FN(GPS_IS), GPIO_FN(GPS_QM), GPIO_FN(GPS_QS),
+ GPIO_FN(SIUBOMC), GPIO_FN(TPU2TO0),
+ GPIO_FN(SIUCKB), GPIO_FN(TPU2TO1),
+ GPIO_FN(SIUBOLR), GPIO_FN(BBIF2_TSYNC), GPIO_FN(TPU2TO2),
+ GPIO_FN(SIUBOBT), GPIO_FN(BBIF2_TSCK), GPIO_FN(TPU2TO3),
+ GPIO_FN(SIUBOSLD), GPIO_FN(BBIF2_TXD), GPIO_FN(TPU3TO0),
+ GPIO_FN(SIUBILR), GPIO_FN(TPU3TO1),
+ GPIO_FN(SIUBIBT), GPIO_FN(TPU3TO2),
+ GPIO_FN(SIUBISLD), GPIO_FN(TPU3TO3),
+ GPIO_FN(NMI), GPIO_FN(TPU4TO0),
+ GPIO_FN(DNPCM_M), GPIO_FN(TPU4TO1), GPIO_FN(TPU4TO2), GPIO_FN(TPU4TO3),
+ GPIO_FN(IRQ_TMPB),
+ GPIO_FN(PWEN), GPIO_FN(MFG1_OUT1),
+ GPIO_FN(OVCN), GPIO_FN(MFG1_IN1),
+ GPIO_FN(OVCN2), GPIO_FN(MFG1_IN2),
+
+ /* 49-3 (FN) */
+ GPIO_FN(RFSPO1), GPIO_FN(RFSPO2), GPIO_FN(RFSPO3),
+ GPIO_FN(PORT93_VIO_CKO2),
+ GPIO_FN(USBTERM), GPIO_FN(EXTLP), GPIO_FN(IDIN),
+ GPIO_FN(SCIFA5_CTS), GPIO_FN(MFG0_IN1),
+ GPIO_FN(SCIFA5_RTS), GPIO_FN(MFG0_IN2),
+ GPIO_FN(SCIFA5_RXD),
+ GPIO_FN(SCIFA5_TXD),
+ GPIO_FN(SCIFA5_SCK), GPIO_FN(MFG0_OUT1),
+ GPIO_FN(A0_EA0), GPIO_FN(BS),
+ GPIO_FN(A14_EA14), GPIO_FN(PORT102_KEYOUT0),
+ GPIO_FN(A15_EA15), GPIO_FN(PORT103_KEYOUT1), GPIO_FN(DV_CLKOL),
+ GPIO_FN(A16_EA16), GPIO_FN(PORT104_KEYOUT2),
+ GPIO_FN(DV_VSYNCL), GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17_EA17), GPIO_FN(PORT105_KEYOUT3),
+ GPIO_FN(DV_HSYNCL), GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18_EA18), GPIO_FN(PORT106_KEYOUT4),
+ GPIO_FN(DV_DL0), GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19_EA19), GPIO_FN(PORT107_KEYOUT5),
+ GPIO_FN(DV_DL1), GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20_EA20), GPIO_FN(PORT108_KEYIN0),
+ GPIO_FN(DV_DL2), GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21_EA21), GPIO_FN(PORT109_KEYIN1),
+ GPIO_FN(DV_DL3), GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22_EA22), GPIO_FN(PORT110_KEYIN2),
+ GPIO_FN(DV_DL4), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23_EA23), GPIO_FN(PORT111_KEYIN3),
+ GPIO_FN(DV_DL5), GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24_EA24), GPIO_FN(PORT112_KEYIN4),
+ GPIO_FN(DV_DL6), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25_EA25), GPIO_FN(PORT113_KEYIN5),
+ GPIO_FN(DV_DL7), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), GPIO_FN(PORT113_KEYIN6), GPIO_FN(DV_CLKIL),
+ GPIO_FN(D0_ED0_NAF0), GPIO_FN(D1_ED1_NAF1), GPIO_FN(D2_ED2_NAF2),
+ GPIO_FN(D3_ED3_NAF3), GPIO_FN(D4_ED4_NAF4), GPIO_FN(D5_ED5_NAF5),
+ GPIO_FN(D6_ED6_NAF6), GPIO_FN(D7_ED7_NAF7), GPIO_FN(D8_ED8_NAF8),
+ GPIO_FN(D9_ED9_NAF9), GPIO_FN(D10_ED10_NAF10), GPIO_FN(D11_ED11_NAF11),
+ GPIO_FN(D12_ED12_NAF12), GPIO_FN(D13_ED13_NAF13),
+ GPIO_FN(D14_ED14_NAF14), GPIO_FN(D15_ED15_NAF15),
+ GPIO_FN(CS4), GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(FCE1),
+ GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(FCE0), GPIO_FN(CS6A),
+ GPIO_FN(DACK0), GPIO_FN(WAIT), GPIO_FN(DREQ0), GPIO_FN(RD_XRD),
+ GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(WE0_XWR0_FWE),
+ GPIO_FN(WE1_XWR1), GPIO_FN(FRB), GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT), GPIO_FN(NBRST),
+
+ /* 49-4 (FN) */
+ GPIO_FN(RFSPO0), GPIO_FN(PORT146_VIO_CKO2), GPIO_FN(TSTMD),
+ GPIO_FN(VIO_VD), GPIO_FN(VIO_HD),
+ GPIO_FN(VIO_D0), GPIO_FN(VIO_D1), GPIO_FN(VIO_D2),
+ GPIO_FN(VIO_D3), GPIO_FN(VIO_D4), GPIO_FN(VIO_D5),
+ GPIO_FN(VIO_D6), GPIO_FN(VIO_D7), GPIO_FN(VIO_D8),
+ GPIO_FN(VIO_D9), GPIO_FN(VIO_D10), GPIO_FN(VIO_D11),
+ GPIO_FN(VIO_D12), GPIO_FN(VIO_D13), GPIO_FN(VIO_D14),
+ GPIO_FN(VIO_D15), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
+ GPIO_FN(VIO_CKO),
+ GPIO_FN(MFG3_IN1), GPIO_FN(MFG3_IN2),
+ GPIO_FN(M9_SLCD_A01), GPIO_FN(MFG3_OUT1), GPIO_FN(TPU0TO0),
+ GPIO_FN(M10_SLCD_CK1), GPIO_FN(MFG4_IN1), GPIO_FN(TPU0TO1),
+ GPIO_FN(M11_SLCD_SO1), GPIO_FN(MFG4_IN2), GPIO_FN(TPU0TO2),
+ GPIO_FN(M12_SLCD_CE1), GPIO_FN(MFG4_OUT1), GPIO_FN(TPU0TO3),
+ GPIO_FN(LCDD0), GPIO_FN(PORT175_KEYOUT0), GPIO_FN(DV_D0),
+ GPIO_FN(SIUCKA), GPIO_FN(MFG0_OUT2),
+ GPIO_FN(LCDD1), GPIO_FN(PORT176_KEYOUT1), GPIO_FN(DV_D1),
+ GPIO_FN(SIUAOLR), GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), GPIO_FN(PORT177_KEYOUT2), GPIO_FN(DV_D2),
+ GPIO_FN(SIUAOBT), GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), GPIO_FN(PORT178_KEYOUT3), GPIO_FN(DV_D3),
+ GPIO_FN(SIUAOSLD), GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), GPIO_FN(PORT179_KEYOUT4), GPIO_FN(DV_D4),
+ GPIO_FN(SIUAISPD), GPIO_FN(MFG1_OUT2),
+ GPIO_FN(LCDD5), GPIO_FN(PORT180_KEYOUT5), GPIO_FN(DV_D5),
+ GPIO_FN(SIUAILR), GPIO_FN(MFG2_OUT2),
+ GPIO_FN(LCDD6), GPIO_FN(DV_D6),
+ GPIO_FN(SIUAIBT), GPIO_FN(MFG3_OUT2), GPIO_FN(XWR2),
+ GPIO_FN(LCDD7), GPIO_FN(DV_D7),
+ GPIO_FN(SIUAISLD), GPIO_FN(MFG4_OUT2), GPIO_FN(XWR3),
+ GPIO_FN(LCDD8), GPIO_FN(DV_D8), GPIO_FN(D16), GPIO_FN(ED16),
+ GPIO_FN(LCDD9), GPIO_FN(DV_D9), GPIO_FN(D17), GPIO_FN(ED17),
+ GPIO_FN(LCDD10), GPIO_FN(DV_D10), GPIO_FN(D18), GPIO_FN(ED18),
+ GPIO_FN(LCDD11), GPIO_FN(DV_D11), GPIO_FN(D19), GPIO_FN(ED19),
+ GPIO_FN(LCDD12), GPIO_FN(DV_D12), GPIO_FN(D20), GPIO_FN(ED20),
+ GPIO_FN(LCDD13), GPIO_FN(DV_D13), GPIO_FN(D21), GPIO_FN(ED21),
+ GPIO_FN(LCDD14), GPIO_FN(DV_D14), GPIO_FN(D22), GPIO_FN(ED22),
+ GPIO_FN(LCDD15), GPIO_FN(DV_D15), GPIO_FN(D23), GPIO_FN(ED23),
+ GPIO_FN(LCDD16), GPIO_FN(DV_HSYNC), GPIO_FN(D24), GPIO_FN(ED24),
+ GPIO_FN(LCDD17), GPIO_FN(DV_VSYNC), GPIO_FN(D25), GPIO_FN(ED25),
+ GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(MSIOF0L_TSCK),
+ GPIO_FN(D26), GPIO_FN(ED26),
+ GPIO_FN(LCDD19), GPIO_FN(MSIOF0L_TSYNC),
+ GPIO_FN(D27), GPIO_FN(ED27),
+ GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+ GPIO_FN(D28), GPIO_FN(ED28),
+ GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+ GPIO_FN(D29), GPIO_FN(ED29),
+ GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_SS1),
+ GPIO_FN(D30), GPIO_FN(ED30),
+ GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_SS2),
+ GPIO_FN(D31), GPIO_FN(ED31),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(DV_CKO), GPIO_FN(SIUAOSPD),
+ GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_RSYNC),
+
+ /* 49-5 (FN) */
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_RSCK),
+ GPIO_FN(LCDCSYN), GPIO_FN(LCDCSYN2), GPIO_FN(DV_CKI),
+ GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(MSIOF0L_RXD),
+ GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(MSIOF0L_TXD),
+ GPIO_FN(VIO_DR0), GPIO_FN(VIO_DR1), GPIO_FN(VIO_DR2), GPIO_FN(VIO_DR3),
+ GPIO_FN(VIO_DR4), GPIO_FN(VIO_DR5), GPIO_FN(VIO_DR6), GPIO_FN(VIO_DR7),
+ GPIO_FN(VIO_VDR), GPIO_FN(VIO_HDR),
+ GPIO_FN(VIO_CLKR), GPIO_FN(VIO_CKOR),
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(GPS_PGFA0),
+ GPIO_FN(SCIFA1_SCK), GPIO_FN(GPS_PGFA1),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(GPS_EPPSINMON),
+ GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_CTS),
+ GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA1_TXD2), GPIO_FN(GPS_TXD),
+ GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA1_CTS2), GPIO_FN(I2C_SDA2),
+ GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA1_SCK2),
+ GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA1_RXD2), GPIO_FN(GPS_RXD),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA1_RTS2),
+ GPIO_FN(MSIOF1_RSYNC), GPIO_FN(I2C_SCL2),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+ GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+ GPIO_FN(MSIOF1_SS2),
+ GPIO_FN(PORT236_IROUT), GPIO_FN(IRDA_OUT),
+ GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
+ GPIO_FN(TPU1TO0), GPIO_FN(TS_SPSYNC3),
+ GPIO_FN(TPU1TO1), GPIO_FN(TS_SDAT3),
+ GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT241_MSIOF2_SS1),
+ GPIO_FN(TPU1TO3), GPIO_FN(PORT242_MSIOF2_TSCK),
+ GPIO_FN(M13_BSW), GPIO_FN(PORT243_MSIOF2_TSYNC),
+ GPIO_FN(M14_GSW), GPIO_FN(PORT244_MSIOF2_TXD),
+ GPIO_FN(PORT245_IROUT), GPIO_FN(M15_RSW),
+ GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1),
+ GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1),
+ GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT248_MSIOF2_SS2),
+ GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT249_MSIOF2_RXD),
+ GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+ GPIO_FN(SDHICLK0), GPIO_FN(TCK2),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0), GPIO_FN(TMS2),
+ GPIO_FN(SDHID0_1), GPIO_FN(TDO2),
+ GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+ GPIO_FN(SDHID0_3), GPIO_FN(RTCK2),
+
+ /* 49-6 (FN) */
+ GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+ GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+ GPIO_FN(SDHICLK1), GPIO_FN(TCK3),
+ GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2),
+ GPIO_FN(TS_SPSYNC2), GPIO_FN(TMS3),
+ GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_AO2),
+ GPIO_FN(TS_SDAT2), GPIO_FN(TDO3),
+ GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2),
+ GPIO_FN(TS_SDEN2), GPIO_FN(TDI3),
+ GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2),
+ GPIO_FN(TS_SCK2), GPIO_FN(RTCK3),
+ GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+ GPIO_FN(SDHICLK2), GPIO_FN(SCIFB_SCK),
+ GPIO_FN(SDHID2_0), GPIO_FN(SCIFB_TXD),
+ GPIO_FN(SDHID2_1), GPIO_FN(SCIFB_CTS),
+ GPIO_FN(SDHID2_2), GPIO_FN(SCIFB_RXD),
+ GPIO_FN(SDHID2_3), GPIO_FN(SCIFB_RTS),
+ GPIO_FN(SDHICMD2),
+ GPIO_FN(RESETOUTS),
+ GPIO_FN(DIVLOCK),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6050020), /* PORT32CR */
+ PORTCR(33, 0xe6050021), /* PORT33CR */
+ PORTCR(34, 0xe6050022), /* PORT34CR */
+ PORTCR(35, 0xe6050023), /* PORT35CR */
+ PORTCR(36, 0xe6050024), /* PORT36CR */
+ PORTCR(37, 0xe6050025), /* PORT37CR */
+ PORTCR(38, 0xe6050026), /* PORT38CR */
+ PORTCR(39, 0xe6050027), /* PORT39CR */
+
+ PORTCR(40, 0xe6050028), /* PORT40CR */
+ PORTCR(41, 0xe6050029), /* PORT41CR */
+ PORTCR(42, 0xe605002a), /* PORT42CR */
+ PORTCR(43, 0xe605002b), /* PORT43CR */
+ PORTCR(44, 0xe605002c), /* PORT44CR */
+ PORTCR(45, 0xe605002d), /* PORT45CR */
+ PORTCR(46, 0xe605002e), /* PORT46CR */
+ PORTCR(47, 0xe605002f), /* PORT47CR */
+ PORTCR(48, 0xe6050030), /* PORT48CR */
+ PORTCR(49, 0xe6050031), /* PORT49CR */
+
+ PORTCR(50, 0xe6050032), /* PORT50CR */
+ PORTCR(51, 0xe6050033), /* PORT51CR */
+ PORTCR(52, 0xe6050034), /* PORT52CR */
+ PORTCR(53, 0xe6050035), /* PORT53CR */
+ PORTCR(54, 0xe6050036), /* PORT54CR */
+ PORTCR(55, 0xe6050037), /* PORT55CR */
+ PORTCR(56, 0xe6050038), /* PORT56CR */
+ PORTCR(57, 0xe6050039), /* PORT57CR */
+ PORTCR(58, 0xe605003a), /* PORT58CR */
+ PORTCR(59, 0xe605003b), /* PORT59CR */
+
+ PORTCR(60, 0xe605003c), /* PORT60CR */
+ PORTCR(61, 0xe605003d), /* PORT61CR */
+ PORTCR(62, 0xe605003e), /* PORT62CR */
+ PORTCR(63, 0xe605003f), /* PORT63CR */
+ PORTCR(64, 0xe6050040), /* PORT64CR */
+ PORTCR(65, 0xe6050041), /* PORT65CR */
+ PORTCR(66, 0xe6050042), /* PORT66CR */
+ PORTCR(67, 0xe6050043), /* PORT67CR */
+ PORTCR(68, 0xe6050044), /* PORT68CR */
+ PORTCR(69, 0xe6050045), /* PORT69CR */
+
+ PORTCR(70, 0xe6050046), /* PORT70CR */
+ PORTCR(71, 0xe6050047), /* PORT71CR */
+ PORTCR(72, 0xe6050048), /* PORT72CR */
+ PORTCR(73, 0xe6050049), /* PORT73CR */
+ PORTCR(74, 0xe605004a), /* PORT74CR */
+ PORTCR(75, 0xe605004b), /* PORT75CR */
+ PORTCR(76, 0xe605004c), /* PORT76CR */
+ PORTCR(77, 0xe605004d), /* PORT77CR */
+ PORTCR(78, 0xe605004e), /* PORT78CR */
+ PORTCR(79, 0xe605004f), /* PORT79CR */
+
+ PORTCR(80, 0xe6050050), /* PORT80CR */
+ PORTCR(81, 0xe6050051), /* PORT81CR */
+ PORTCR(82, 0xe6050052), /* PORT82CR */
+ PORTCR(83, 0xe6050053), /* PORT83CR */
+ PORTCR(84, 0xe6050054), /* PORT84CR */
+ PORTCR(85, 0xe6050055), /* PORT85CR */
+ PORTCR(86, 0xe6050056), /* PORT86CR */
+ PORTCR(87, 0xe6050057), /* PORT87CR */
+ PORTCR(88, 0xe6051058), /* PORT88CR */
+ PORTCR(89, 0xe6051059), /* PORT89CR */
+
+ PORTCR(90, 0xe605105a), /* PORT90CR */
+ PORTCR(91, 0xe605105b), /* PORT91CR */
+ PORTCR(92, 0xe605105c), /* PORT92CR */
+ PORTCR(93, 0xe605105d), /* PORT93CR */
+ PORTCR(94, 0xe605105e), /* PORT94CR */
+ PORTCR(95, 0xe605105f), /* PORT95CR */
+ PORTCR(96, 0xe6051060), /* PORT96CR */
+ PORTCR(97, 0xe6051061), /* PORT97CR */
+ PORTCR(98, 0xe6051062), /* PORT98CR */
+ PORTCR(99, 0xe6051063), /* PORT99CR */
+
+ PORTCR(100, 0xe6051064), /* PORT100CR */
+ PORTCR(101, 0xe6051065), /* PORT101CR */
+ PORTCR(102, 0xe6051066), /* PORT102CR */
+ PORTCR(103, 0xe6051067), /* PORT103CR */
+ PORTCR(104, 0xe6051068), /* PORT104CR */
+ PORTCR(105, 0xe6051069), /* PORT105CR */
+ PORTCR(106, 0xe605106a), /* PORT106CR */
+ PORTCR(107, 0xe605106b), /* PORT107CR */
+ PORTCR(108, 0xe605106c), /* PORT108CR */
+ PORTCR(109, 0xe605106d), /* PORT109CR */
+
+ PORTCR(110, 0xe605106e), /* PORT110CR */
+ PORTCR(111, 0xe605106f), /* PORT111CR */
+ PORTCR(112, 0xe6051070), /* PORT112CR */
+ PORTCR(113, 0xe6051071), /* PORT113CR */
+ PORTCR(114, 0xe6051072), /* PORT114CR */
+ PORTCR(115, 0xe6051073), /* PORT115CR */
+ PORTCR(116, 0xe6051074), /* PORT116CR */
+ PORTCR(117, 0xe6051075), /* PORT117CR */
+ PORTCR(118, 0xe6051076), /* PORT118CR */
+ PORTCR(119, 0xe6051077), /* PORT119CR */
+
+ PORTCR(120, 0xe6051078), /* PORT120CR */
+ PORTCR(121, 0xe6051079), /* PORT121CR */
+ PORTCR(122, 0xe605107a), /* PORT122CR */
+ PORTCR(123, 0xe605107b), /* PORT123CR */
+ PORTCR(124, 0xe605107c), /* PORT124CR */
+ PORTCR(125, 0xe605107d), /* PORT125CR */
+ PORTCR(126, 0xe605107e), /* PORT126CR */
+ PORTCR(127, 0xe605107f), /* PORT127CR */
+ PORTCR(128, 0xe6051080), /* PORT128CR */
+ PORTCR(129, 0xe6051081), /* PORT129CR */
+
+ PORTCR(130, 0xe6051082), /* PORT130CR */
+ PORTCR(131, 0xe6051083), /* PORT131CR */
+ PORTCR(132, 0xe6051084), /* PORT132CR */
+ PORTCR(133, 0xe6051085), /* PORT133CR */
+ PORTCR(134, 0xe6051086), /* PORT134CR */
+ PORTCR(135, 0xe6051087), /* PORT135CR */
+ PORTCR(136, 0xe6051088), /* PORT136CR */
+ PORTCR(137, 0xe6051089), /* PORT137CR */
+ PORTCR(138, 0xe605108a), /* PORT138CR */
+ PORTCR(139, 0xe605108b), /* PORT139CR */
+
+ PORTCR(140, 0xe605108c), /* PORT140CR */
+ PORTCR(141, 0xe605108d), /* PORT141CR */
+ PORTCR(142, 0xe605108e), /* PORT142CR */
+ PORTCR(143, 0xe605108f), /* PORT143CR */
+ PORTCR(144, 0xe6051090), /* PORT144CR */
+ PORTCR(145, 0xe6051091), /* PORT145CR */
+ PORTCR(146, 0xe6051092), /* PORT146CR */
+ PORTCR(147, 0xe6051093), /* PORT147CR */
+ PORTCR(148, 0xe6051094), /* PORT148CR */
+ PORTCR(149, 0xe6051095), /* PORT149CR */
+
+ PORTCR(150, 0xe6051096), /* PORT150CR */
+ PORTCR(151, 0xe6051097), /* PORT151CR */
+ PORTCR(152, 0xe6051098), /* PORT152CR */
+ PORTCR(153, 0xe6051099), /* PORT153CR */
+ PORTCR(154, 0xe605109a), /* PORT154CR */
+ PORTCR(155, 0xe605109b), /* PORT155CR */
+ PORTCR(156, 0xe605109c), /* PORT156CR */
+ PORTCR(157, 0xe605109d), /* PORT157CR */
+ PORTCR(158, 0xe605109e), /* PORT158CR */
+ PORTCR(159, 0xe605109f), /* PORT159CR */
+
+ PORTCR(160, 0xe60510a0), /* PORT160CR */
+ PORTCR(161, 0xe60510a1), /* PORT161CR */
+ PORTCR(162, 0xe60510a2), /* PORT162CR */
+ PORTCR(163, 0xe60510a3), /* PORT163CR */
+ PORTCR(164, 0xe60510a4), /* PORT164CR */
+ PORTCR(165, 0xe60510a5), /* PORT165CR */
+ PORTCR(166, 0xe60510a6), /* PORT166CR */
+ PORTCR(167, 0xe60510a7), /* PORT167CR */
+ PORTCR(168, 0xe60510a8), /* PORT168CR */
+ PORTCR(169, 0xe60510a9), /* PORT169CR */
+
+ PORTCR(170, 0xe60510aa), /* PORT170CR */
+ PORTCR(171, 0xe60510ab), /* PORT171CR */
+ PORTCR(172, 0xe60510ac), /* PORT172CR */
+ PORTCR(173, 0xe60510ad), /* PORT173CR */
+ PORTCR(174, 0xe60510ae), /* PORT174CR */
+ PORTCR(175, 0xe60520af), /* PORT175CR */
+ PORTCR(176, 0xe60520b0), /* PORT176CR */
+ PORTCR(177, 0xe60520b1), /* PORT177CR */
+ PORTCR(178, 0xe60520b2), /* PORT178CR */
+ PORTCR(179, 0xe60520b3), /* PORT179CR */
+
+ PORTCR(180, 0xe60520b4), /* PORT180CR */
+ PORTCR(181, 0xe60520b5), /* PORT181CR */
+ PORTCR(182, 0xe60520b6), /* PORT182CR */
+ PORTCR(183, 0xe60520b7), /* PORT183CR */
+ PORTCR(184, 0xe60520b8), /* PORT184CR */
+ PORTCR(185, 0xe60520b9), /* PORT185CR */
+ PORTCR(186, 0xe60520ba), /* PORT186CR */
+ PORTCR(187, 0xe60520bb), /* PORT187CR */
+ PORTCR(188, 0xe60520bc), /* PORT188CR */
+ PORTCR(189, 0xe60520bd), /* PORT189CR */
+
+ PORTCR(190, 0xe60520be), /* PORT190CR */
+ PORTCR(191, 0xe60520bf), /* PORT191CR */
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60520d2), /* PORT210CR */
+ PORTCR(211, 0xe60520d3), /* PORT211CR */
+ PORTCR(212, 0xe60520d4), /* PORT212CR */
+ PORTCR(213, 0xe60520d5), /* PORT213CR */
+ PORTCR(214, 0xe60520d6), /* PORT214CR */
+ PORTCR(215, 0xe60520d7), /* PORT215CR */
+ PORTCR(216, 0xe60520d8), /* PORT216CR */
+ PORTCR(217, 0xe60520d9), /* PORT217CR */
+ PORTCR(218, 0xe60520da), /* PORT218CR */
+ PORTCR(219, 0xe60520db), /* PORT219CR */
+
+ PORTCR(220, 0xe60520dc), /* PORT220CR */
+ PORTCR(221, 0xe60520dd), /* PORT221CR */
+ PORTCR(222, 0xe60520de), /* PORT222CR */
+ PORTCR(223, 0xe60520df), /* PORT223CR */
+ PORTCR(224, 0xe60520e0), /* PORT224CR */
+ PORTCR(225, 0xe60520e1), /* PORT225CR */
+ PORTCR(226, 0xe60520e2), /* PORT226CR */
+ PORTCR(227, 0xe60520e3), /* PORT227CR */
+ PORTCR(228, 0xe60520e4), /* PORT228CR */
+ PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60520e6), /* PORT230CR */
+ PORTCR(231, 0xe60520e7), /* PORT231CR */
+ PORTCR(232, 0xe60520e8), /* PORT232CR */
+ PORTCR(233, 0xe60520e9), /* PORT233CR */
+ PORTCR(234, 0xe60520ea), /* PORT234CR */
+ PORTCR(235, 0xe60520eb), /* PORT235CR */
+ PORTCR(236, 0xe60530ec), /* PORT236CR */
+ PORTCR(237, 0xe60530ed), /* PORT237CR */
+ PORTCR(238, 0xe60530ee), /* PORT238CR */
+ PORTCR(239, 0xe60530ef), /* PORT239CR */
+
+ PORTCR(240, 0xe60530f0), /* PORT240CR */
+ PORTCR(241, 0xe60530f1), /* PORT241CR */
+ PORTCR(242, 0xe60530f2), /* PORT242CR */
+ PORTCR(243, 0xe60530f3), /* PORT243CR */
+ PORTCR(244, 0xe60530f4), /* PORT244CR */
+ PORTCR(245, 0xe60530f5), /* PORT245CR */
+ PORTCR(246, 0xe60530f6), /* PORT246CR */
+ PORTCR(247, 0xe60530f7), /* PORT247CR */
+ PORTCR(248, 0xe60530f8), /* PORT248CR */
+ PORTCR(249, 0xe60530f9), /* PORT249CR */
+
+ PORTCR(250, 0xe60530fa), /* PORT250CR */
+ PORTCR(251, 0xe60530fb), /* PORT251CR */
+ PORTCR(252, 0xe60530fc), /* PORT252CR */
+ PORTCR(253, 0xe60530fd), /* PORT253CR */
+ PORTCR(254, 0xe60530fe), /* PORT254CR */
+ PORTCR(255, 0xe60530ff), /* PORT255CR */
+ PORTCR(256, 0xe6053100), /* PORT256CR */
+ PORTCR(257, 0xe6053101), /* PORT257CR */
+ PORTCR(258, 0xe6053102), /* PORT258CR */
+ PORTCR(259, 0xe6053103), /* PORT259CR */
+
+ PORTCR(260, 0xe6053104), /* PORT260CR */
+ PORTCR(261, 0xe6053105), /* PORT261CR */
+ PORTCR(262, 0xe6053106), /* PORT262CR */
+ PORTCR(263, 0xe6053107), /* PORT263CR */
+ PORTCR(264, 0xe6053108), /* PORT264CR */
+ PORTCR(265, 0xe6053109), /* PORT265CR */
+ PORTCR(266, 0xe605310a), /* PORT266CR */
+ PORTCR(267, 0xe605310b), /* PORT267CR */
+ PORTCR(268, 0xe605310c), /* PORT268CR */
+ PORTCR(269, 0xe605310d), /* PORT269CR */
+
+ PORTCR(270, 0xe605310e), /* PORT270CR */
+ PORTCR(271, 0xe605310f), /* PORT271CR */
+ PORTCR(272, 0xe6053110), /* PORT272CR */
+
+ { PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSELBCR_MSEL2_0, MSELBCR_MSEL2_1,
+ 0, 0,
+ 0, 0 }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD127_096DR", 0xe6055004, 32) {
+ PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+ PORT123_DATA, PORT122_DATA, PORT121_DATA, PORT120_DATA,
+ PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD159_128DR", 0xe6055008, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056000, 32) {
+ PORT191_DATA, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+ PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+ PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+ PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+ PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+ PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+ PORT167_DATA, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056004, 32) {
+ PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+ PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+ PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+ PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) {
+ PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+ PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+ PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+ PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+ PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+ PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+ PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+ PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT272_DATA,
+ PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA,
+ PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA,
+ PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+ PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7367_pinmux_info = {
+ .name = "sh7367_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_DIVLOCK,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7367_pinmux_init(void)
+{
+ register_pinmux(&sh7367_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
new file mode 100644
index 00000000..9c265dae
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -0,0 +1,1640 @@
+/*
+ * sh7372 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * Based on
+ * sh7367 processor support - PFC hardware block
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7372.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _80(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx)
+
+#define _190(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _80(fn, pfx, sfx), _10(fn, pfx##9, sfx), \
+ _10(fn, pfx##10, sfx), _80(fn, pfx##1, sfx), _1(fn, pfx##190, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_ALL(str) _190(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ /* PORT0_DATA -> PORT190_DATA */
+ PINMUX_DATA_BEGIN,
+ PORT_ALL(DATA),
+ PINMUX_DATA_END,
+
+ /* PORT0_IN -> PORT190_IN */
+ PINMUX_INPUT_BEGIN,
+ PORT_ALL(IN),
+ PINMUX_INPUT_END,
+
+ /* PORT0_IN_PU -> PORT190_IN_PU */
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_ALL(IN_PU),
+ PINMUX_INPUT_PULLUP_END,
+
+ /* PORT0_IN_PD -> PORT190_IN_PD */
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_ALL(IN_PD),
+ PINMUX_INPUT_PULLDOWN_END,
+
+ /* PORT0_OUT -> PORT190_OUT */
+ PINMUX_OUTPUT_BEGIN,
+ PORT_ALL(OUT),
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_ALL(FN_IN), /* PORT0_FN_IN -> PORT190_FN_IN */
+ PORT_ALL(FN_OUT), /* PORT0_FN_OUT -> PORT190_FN_OUT */
+ PORT_ALL(FN0), /* PORT0_FN0 -> PORT190_FN0 */
+ PORT_ALL(FN1), /* PORT0_FN1 -> PORT190_FN1 */
+ PORT_ALL(FN2), /* PORT0_FN2 -> PORT190_FN2 */
+ PORT_ALL(FN3), /* PORT0_FN3 -> PORT190_FN3 */
+ PORT_ALL(FN4), /* PORT0_FN4 -> PORT190_FN4 */
+ PORT_ALL(FN5), /* PORT0_FN5 -> PORT190_FN5 */
+ PORT_ALL(FN6), /* PORT0_FN6 -> PORT190_FN6 */
+ PORT_ALL(FN7), /* PORT0_FN7 -> PORT190_FN7 */
+
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ MSEL1CR_8_0, MSEL1CR_8_1,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+
+ MSEL3CR_27_0, MSEL3CR_27_1,
+ MSEL3CR_26_0, MSEL3CR_26_1,
+ MSEL3CR_21_0, MSEL3CR_21_1,
+ MSEL3CR_20_0, MSEL3CR_20_1,
+ MSEL3CR_15_0, MSEL3CR_15_1,
+ MSEL3CR_9_0, MSEL3CR_9_1,
+ MSEL3CR_6_0, MSEL3CR_6_1,
+
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ MSEL4CR_17_0, MSEL4CR_17_1,
+ MSEL4CR_16_0, MSEL4CR_16_1,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ MSEL4CR_14_0, MSEL4CR_14_1,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+
+ /* IRQ */
+ IRQ0_6_MARK, IRQ0_162_MARK, IRQ1_MARK, IRQ2_4_MARK,
+ IRQ2_5_MARK, IRQ3_8_MARK, IRQ3_16_MARK, IRQ4_17_MARK,
+ IRQ4_163_MARK, IRQ5_MARK, IRQ6_39_MARK, IRQ6_164_MARK,
+ IRQ7_40_MARK, IRQ7_167_MARK, IRQ8_41_MARK, IRQ8_168_MARK,
+ IRQ9_42_MARK, IRQ9_169_MARK, IRQ10_MARK, IRQ11_MARK,
+ IRQ12_80_MARK, IRQ12_137_MARK, IRQ13_81_MARK, IRQ13_145_MARK,
+ IRQ14_82_MARK, IRQ14_146_MARK, IRQ15_83_MARK, IRQ15_147_MARK,
+ IRQ16_84_MARK, IRQ16_170_MARK, IRQ17_MARK, IRQ18_MARK,
+ IRQ19_MARK, IRQ20_MARK, IRQ21_MARK, IRQ22_MARK,
+ IRQ23_MARK, IRQ24_MARK, IRQ25_MARK, IRQ26_121_MARK,
+ IRQ26_172_MARK, IRQ27_122_MARK, IRQ27_180_MARK, IRQ28_123_MARK,
+ IRQ28_181_MARK, IRQ29_129_MARK, IRQ29_182_MARK, IRQ30_130_MARK,
+ IRQ30_183_MARK, IRQ31_138_MARK, IRQ31_184_MARK,
+
+ /* MSIOF0 */
+ MSIOF0_TSYNC_MARK, MSIOF0_TSCK_MARK, MSIOF0_RXD_MARK,
+ MSIOF0_RSCK_MARK, MSIOF0_RSYNC_MARK, MSIOF0_MCK0_MARK,
+ MSIOF0_MCK1_MARK, MSIOF0_SS1_MARK, MSIOF0_SS2_MARK,
+ MSIOF0_TXD_MARK,
+
+ /* MSIOF1 */
+ MSIOF1_TSCK_39_MARK, MSIOF1_TSYNC_40_MARK,
+ MSIOF1_TSCK_88_MARK, MSIOF1_TSYNC_89_MARK,
+ MSIOF1_TXD_41_MARK, MSIOF1_RXD_42_MARK,
+ MSIOF1_TXD_90_MARK, MSIOF1_RXD_91_MARK,
+ MSIOF1_SS1_43_MARK, MSIOF1_SS2_44_MARK,
+ MSIOF1_SS1_92_MARK, MSIOF1_SS2_93_MARK,
+ MSIOF1_RSCK_MARK, MSIOF1_RSYNC_MARK,
+ MSIOF1_MCK0_MARK, MSIOF1_MCK1_MARK,
+
+ /* MSIOF2 */
+ MSIOF2_RSCK_MARK, MSIOF2_RSYNC_MARK, MSIOF2_MCK0_MARK,
+ MSIOF2_MCK1_MARK, MSIOF2_SS1_MARK, MSIOF2_SS2_MARK,
+ MSIOF2_TSYNC_MARK, MSIOF2_TSCK_MARK, MSIOF2_RXD_MARK,
+ MSIOF2_TXD_MARK,
+
+ /* BBIF1 */
+ BBIF1_RXD_MARK, BBIF1_TSYNC_MARK, BBIF1_TSCK_MARK,
+ BBIF1_TXD_MARK, BBIF1_RSCK_MARK, BBIF1_RSYNC_MARK,
+ BBIF1_FLOW_MARK, BB_RX_FLOW_N_MARK,
+
+ /* BBIF2 */
+ BBIF2_TSCK1_MARK, BBIF2_TSYNC1_MARK,
+ BBIF2_TXD1_MARK, BBIF2_RXD_MARK,
+
+ /* FSI */
+ FSIACK_MARK, FSIBCK_MARK, FSIAILR_MARK, FSIAIBT_MARK,
+ FSIAISLD_MARK, FSIAOMC_MARK, FSIAOLR_MARK, FSIAOBT_MARK,
+ FSIAOSLD_MARK, FSIASPDIF_11_MARK, FSIASPDIF_15_MARK,
+
+ /* FMSI */
+ FMSOCK_MARK, FMSOOLR_MARK, FMSIOLR_MARK, FMSOOBT_MARK,
+ FMSIOBT_MARK, FMSOSLD_MARK, FMSOILR_MARK, FMSIILR_MARK,
+ FMSOIBT_MARK, FMSIIBT_MARK, FMSISLD_MARK, FMSICK_MARK,
+
+ /* SCIFA0 */
+ SCIFA0_TXD_MARK, SCIFA0_RXD_MARK, SCIFA0_SCK_MARK,
+ SCIFA0_RTS_MARK, SCIFA0_CTS_MARK,
+
+ /* SCIFA1 */
+ SCIFA1_TXD_MARK, SCIFA1_RXD_MARK, SCIFA1_SCK_MARK,
+ SCIFA1_RTS_MARK, SCIFA1_CTS_MARK,
+
+ /* SCIFA2 */
+ SCIFA2_CTS1_MARK, SCIFA2_RTS1_MARK, SCIFA2_TXD1_MARK,
+ SCIFA2_RXD1_MARK, SCIFA2_SCK1_MARK,
+
+ /* SCIFA3 */
+ SCIFA3_CTS_43_MARK, SCIFA3_CTS_140_MARK, SCIFA3_RTS_44_MARK,
+ SCIFA3_RTS_141_MARK, SCIFA3_SCK_MARK, SCIFA3_TXD_MARK,
+ SCIFA3_RXD_MARK,
+
+ /* SCIFA4 */
+ SCIFA4_RXD_MARK, SCIFA4_TXD_MARK,
+
+ /* SCIFA5 */
+ SCIFA5_RXD_MARK, SCIFA5_TXD_MARK,
+
+ /* SCIFB */
+ SCIFB_SCK_MARK, SCIFB_RTS_MARK, SCIFB_CTS_MARK,
+ SCIFB_TXD_MARK, SCIFB_RXD_MARK,
+
+ /* CEU */
+ VIO_HD_MARK, VIO_CKO1_MARK, VIO_CKO2_MARK, VIO_VD_MARK,
+ VIO_CLK_MARK, VIO_FIELD_MARK, VIO_CKO_MARK,
+ VIO_D0_MARK, VIO_D1_MARK, VIO_D2_MARK, VIO_D3_MARK,
+ VIO_D4_MARK, VIO_D5_MARK, VIO_D6_MARK, VIO_D7_MARK,
+ VIO_D8_MARK, VIO_D9_MARK, VIO_D10_MARK, VIO_D11_MARK,
+ VIO_D12_MARK, VIO_D13_MARK, VIO_D14_MARK, VIO_D15_MARK,
+
+ /* USB0 */
+ IDIN_0_MARK, EXTLP_0_MARK, OVCN2_0_MARK, PWEN_0_MARK,
+ OVCN_0_MARK, VBUS0_0_MARK,
+
+ /* USB1 */
+ IDIN_1_18_MARK, IDIN_1_113_MARK,
+ PWEN_1_115_MARK, PWEN_1_138_MARK,
+ OVCN_1_114_MARK, OVCN_1_162_MARK,
+ EXTLP_1_MARK, OVCN2_1_MARK,
+ VBUS0_1_MARK,
+
+ /* GPIO */
+ GPI0_MARK, GPI1_MARK, GPO0_MARK, GPO1_MARK,
+
+ /* BSC */
+ BS_MARK, WE1_MARK,
+ CKO_MARK, WAIT_MARK, RDWR_MARK,
+
+ A0_MARK, A1_MARK, A2_MARK, A3_MARK,
+ A6_MARK, A7_MARK, A8_MARK, A9_MARK,
+ A10_MARK, A11_MARK, A12_MARK, A13_MARK,
+ A14_MARK, A15_MARK, A16_MARK, A17_MARK,
+ A18_MARK, A19_MARK, A20_MARK, A21_MARK,
+ A22_MARK, A23_MARK, A24_MARK, A25_MARK,
+ A26_MARK,
+
+ CS0_MARK, CS2_MARK, CS4_MARK,
+ CS5A_MARK, CS5B_MARK, CS6A_MARK,
+
+ /* BSC/FLCTL */
+ RD_FSC_MARK, WE0_FWE_MARK, A4_FOE_MARK, A5_FCDE_MARK,
+ D0_NAF0_MARK, D1_NAF1_MARK, D2_NAF2_MARK, D3_NAF3_MARK,
+ D4_NAF4_MARK, D5_NAF5_MARK, D6_NAF6_MARK, D7_NAF7_MARK,
+ D8_NAF8_MARK, D9_NAF9_MARK, D10_NAF10_MARK, D11_NAF11_MARK,
+ D12_NAF12_MARK, D13_NAF13_MARK, D14_NAF14_MARK, D15_NAF15_MARK,
+
+ /* MMCIF(1) */
+ MMCD0_0_MARK, MMCD0_1_MARK, MMCD0_2_MARK, MMCD0_3_MARK,
+ MMCD0_4_MARK, MMCD0_5_MARK, MMCD0_6_MARK, MMCD0_7_MARK,
+ MMCCMD0_MARK, MMCCLK0_MARK,
+
+ /* MMCIF(2) */
+ MMCD1_0_MARK, MMCD1_1_MARK, MMCD1_2_MARK, MMCD1_3_MARK,
+ MMCD1_4_MARK, MMCD1_5_MARK, MMCD1_6_MARK, MMCD1_7_MARK,
+ MMCCLK1_MARK, MMCCMD1_MARK,
+
+ /* SPU2 */
+ VINT_I_MARK,
+
+ /* FLCTL */
+ FCE1_MARK, FCE0_MARK, FRB_MARK,
+
+ /* HSI */
+ GP_RX_FLAG_MARK, GP_RX_DATA_MARK, GP_TX_READY_MARK,
+ GP_RX_WAKE_MARK, MP_TX_FLAG_MARK, MP_TX_DATA_MARK,
+ MP_RX_READY_MARK, MP_TX_WAKE_MARK,
+
+ /* MFI */
+ MFIv6_MARK,
+ MFIv4_MARK,
+
+ MEMC_CS0_MARK, MEMC_BUSCLK_MEMC_A0_MARK,
+ MEMC_CS1_MEMC_A1_MARK, MEMC_ADV_MEMC_DREQ0_MARK,
+ MEMC_WAIT_MEMC_DREQ1_MARK, MEMC_NOE_MARK,
+ MEMC_NWE_MARK, MEMC_INT_MARK,
+
+ MEMC_AD0_MARK, MEMC_AD1_MARK, MEMC_AD2_MARK,
+ MEMC_AD3_MARK, MEMC_AD4_MARK, MEMC_AD5_MARK,
+ MEMC_AD6_MARK, MEMC_AD7_MARK, MEMC_AD8_MARK,
+ MEMC_AD9_MARK, MEMC_AD10_MARK, MEMC_AD11_MARK,
+ MEMC_AD12_MARK, MEMC_AD13_MARK, MEMC_AD14_MARK,
+ MEMC_AD15_MARK,
+
+ /* SIM */
+ SIM_RST_MARK, SIM_CLK_MARK, SIM_D_MARK,
+
+ /* TPU */
+ TPU0TO0_MARK, TPU0TO1_MARK,
+ TPU0TO2_93_MARK, TPU0TO2_99_MARK,
+ TPU0TO3_MARK,
+
+ /* I2C2 */
+ I2C_SCL2_MARK, I2C_SDA2_MARK,
+
+ /* I2C3(1) */
+ I2C_SCL3_MARK, I2C_SDA3_MARK,
+
+ /* I2C3(2) */
+ I2C_SCL3S_MARK, I2C_SDA3S_MARK,
+
+ /* I2C4(2) */
+ I2C_SCL4_MARK, I2C_SDA4_MARK,
+
+ /* I2C4(2) */
+ I2C_SCL4S_MARK, I2C_SDA4S_MARK,
+
+ /* KEYSC */
+ KEYOUT0_MARK, KEYIN0_121_MARK, KEYIN0_136_MARK,
+ KEYOUT1_MARK, KEYIN1_122_MARK, KEYIN1_135_MARK,
+ KEYOUT2_MARK, KEYIN2_123_MARK, KEYIN2_134_MARK,
+ KEYOUT3_MARK, KEYIN3_124_MARK, KEYIN3_133_MARK,
+ KEYOUT4_MARK, KEYIN4_MARK,
+ KEYOUT5_MARK, KEYIN5_MARK,
+ KEYOUT6_MARK, KEYIN6_MARK,
+ KEYOUT7_MARK, KEYIN7_MARK,
+
+ /* LCDC */
+ LCDC0_SELECT_MARK,
+ LCDC1_SELECT_MARK,
+ LCDHSYN_MARK, LCDCS_MARK, LCDVSYN_MARK, LCDDCK_MARK,
+ LCDWR_MARK, LCDRD_MARK, LCDDISP_MARK, LCDRS_MARK,
+ LCDLCLK_MARK, LCDDON_MARK,
+
+ LCDD0_MARK, LCDD1_MARK, LCDD2_MARK, LCDD3_MARK,
+ LCDD4_MARK, LCDD5_MARK, LCDD6_MARK, LCDD7_MARK,
+ LCDD8_MARK, LCDD9_MARK, LCDD10_MARK, LCDD11_MARK,
+ LCDD12_MARK, LCDD13_MARK, LCDD14_MARK, LCDD15_MARK,
+ LCDD16_MARK, LCDD17_MARK, LCDD18_MARK, LCDD19_MARK,
+ LCDD20_MARK, LCDD21_MARK, LCDD22_MARK, LCDD23_MARK,
+
+ /* IRDA */
+ IRDA_OUT_MARK, IRDA_IN_MARK, IRDA_FIRSEL_MARK,
+ IROUT_139_MARK, IROUT_140_MARK,
+
+ /* TSIF1 */
+ TS0_1SELECT_MARK,
+ TS0_2SELECT_MARK,
+ TS1_1SELECT_MARK,
+ TS1_2SELECT_MARK,
+
+ TS_SPSYNC1_MARK, TS_SDAT1_MARK,
+ TS_SDEN1_MARK, TS_SCK1_MARK,
+
+ /* TSIF2 */
+ TS_SPSYNC2_MARK, TS_SDAT2_MARK,
+ TS_SDEN2_MARK, TS_SCK2_MARK,
+
+ /* HDMI */
+ HDMI_HPD_MARK, HDMI_CEC_MARK,
+
+ /* SDHI0 */
+ SDHICLK0_MARK, SDHICD0_MARK,
+ SDHICMD0_MARK, SDHIWP0_MARK,
+ SDHID0_0_MARK, SDHID0_1_MARK,
+ SDHID0_2_MARK, SDHID0_3_MARK,
+
+ /* SDHI1 */
+ SDHICLK1_MARK, SDHICMD1_MARK, SDHID1_0_MARK,
+ SDHID1_1_MARK, SDHID1_2_MARK, SDHID1_3_MARK,
+
+ /* SDHI2 */
+ SDHICLK2_MARK, SDHICMD2_MARK, SDHID2_0_MARK,
+ SDHID2_1_MARK, SDHID2_2_MARK, SDHID2_3_MARK,
+
+ /* SDENC */
+ SDENC_CPG_MARK,
+ SDENC_DV_CLKI_MARK,
+
+ PINMUX_MARK_END,
+};
+
+/* PORT_DATA_I_PD(nr) */
+#define _I___D(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_I_PU(nr) */
+#define _I__U_(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_I_PU_PD(nr) */
+#define _I__UD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+/* PORT_DATA_O(nr) */
+#define __O___(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT)
+
+/* PORT_DATA_IO(nr) */
+#define _IO___(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN)
+
+/* PORT_DATA_IO_PD(nr) */
+#define _IO__D(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+/* PORT_DATA_IO_PU(nr) */
+#define _IO_U_(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+/* PORT_DATA_IO_PU_PD(nr) */
+#define _IO_UD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_OUT, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* specify valid pin states for each pin in GPIO mode */
+
+ _IO__D(0), _IO__D(1), __O___(2), _I___D(3), _I___D(4),
+ _I___D(5), _IO_UD(6), _I___D(7), _IO__D(8), __O___(9),
+
+ __O___(10), __O___(11), _IO_UD(12), _IO__D(13), _IO__D(14),
+ __O___(15), _IO__D(16), _IO__D(17), _I___D(18), _IO___(19),
+
+ _IO___(20), _IO___(21), _IO___(22), _IO___(23), _IO___(24),
+ _IO___(25), _IO___(26), _IO___(27), _IO___(28), _IO___(29),
+
+ _IO___(30), _IO___(31), _IO___(32), _IO___(33), _IO___(34),
+ _IO___(35), _IO___(36), _IO___(37), _IO___(38), _IO___(39),
+
+ _IO___(40), _IO___(41), _IO___(42), _IO___(43), _IO___(44),
+ _IO___(45), _IO_U_(46), _IO_U_(47), _IO_U_(48), _IO_U_(49),
+
+ _IO_U_(50), _IO_U_(51), _IO_U_(52), _IO_U_(53), _IO_U_(54),
+ _IO_U_(55), _IO_U_(56), _IO_U_(57), _IO_U_(58), _IO_U_(59),
+
+ _IO_U_(60), _IO_U_(61), _IO___(62), __O___(63), __O___(64),
+ _IO_U_(65), __O___(66), _IO_U_(67), __O___(68), _IO___(69), /*66?*/
+
+ _IO___(70), _IO___(71), __O___(72), _I__U_(73), _I__UD(74),
+ _IO_UD(75), _IO_UD(76), _IO_UD(77), _IO_UD(78), _IO_UD(79),
+
+ _IO_UD(80), _IO_UD(81), _IO_UD(82), _IO_UD(83), _IO_UD(84),
+ _IO_UD(85), _IO_UD(86), _IO_UD(87), _IO_UD(88), _IO_UD(89),
+
+ _IO_UD(90), _IO_UD(91), _IO_UD(92), _IO_UD(93), _IO_UD(94),
+ _IO_UD(95), _IO_U_(96), _IO_UD(97), _IO_UD(98), __O___(99), /*99?*/
+
+ _IO__D(100), _IO__D(101), _IO__D(102), _IO__D(103), _IO__D(104),
+ _IO__D(105), _IO_U_(106), _IO_U_(107), _IO_U_(108), _IO_U_(109),
+
+ _IO_U_(110), _IO_U_(111), _IO__D(112), _IO__D(113), _IO_U_(114),
+ _IO_U_(115), _IO_U_(116), _IO_U_(117), _IO_U_(118), _IO_U_(119),
+
+ _IO_U_(120), _IO__D(121), _IO__D(122), _IO__D(123), _IO__D(124),
+ _IO__D(125), _IO__D(126), _IO__D(127), _IO__D(128), _IO_UD(129),
+
+ _IO_UD(130), _IO_UD(131), _IO_UD(132), _IO_UD(133), _IO_UD(134),
+ _IO_UD(135), _IO__D(136), _IO__D(137), _IO__D(138), _IO__D(139),
+
+ _IO__D(140), _IO__D(141), _IO__D(142), _IO_UD(143), _IO__D(144),
+ _IO__D(145), _IO__D(146), _IO__D(147), _IO__D(148), _IO__D(149),
+
+ _IO__D(150), _IO__D(151), _IO_UD(152), _I___D(153), _IO_UD(154),
+ _I___D(155), _IO__D(156), _IO__D(157), _I___D(158), _IO__D(159),
+
+ __O___(160), _IO__D(161), _IO__D(162), _IO__D(163), _I___D(164),
+ _IO__D(165), _I___D(166), _I___D(167), _I___D(168), _I___D(169),
+
+ _I___D(170), __O___(171), _IO_UD(172), _IO_UD(173), _IO_UD(174),
+ _IO_UD(175), _IO_UD(176), _IO_UD(177), _IO_UD(178), __O___(179),
+
+ _IO_UD(180), _IO_UD(181), _IO_UD(182), _IO_UD(183), _IO_UD(184),
+ __O___(185), _IO_UD(186), _IO_UD(187), _IO_UD(188), _IO_UD(189),
+
+ _IO_UD(190),
+
+ /* IRQ */
+ PINMUX_DATA(IRQ0_6_MARK, PORT6_FN0, MSEL1CR_0_0),
+ PINMUX_DATA(IRQ0_162_MARK, PORT162_FN0, MSEL1CR_0_1),
+ PINMUX_DATA(IRQ1_MARK, PORT12_FN0),
+ PINMUX_DATA(IRQ2_4_MARK, PORT4_FN0, MSEL1CR_2_0),
+ PINMUX_DATA(IRQ2_5_MARK, PORT5_FN0, MSEL1CR_2_1),
+ PINMUX_DATA(IRQ3_8_MARK, PORT8_FN0, MSEL1CR_3_0),
+ PINMUX_DATA(IRQ3_16_MARK, PORT16_FN0, MSEL1CR_3_1),
+ PINMUX_DATA(IRQ4_17_MARK, PORT17_FN0, MSEL1CR_4_0),
+ PINMUX_DATA(IRQ4_163_MARK, PORT163_FN0, MSEL1CR_4_1),
+ PINMUX_DATA(IRQ5_MARK, PORT18_FN0),
+ PINMUX_DATA(IRQ6_39_MARK, PORT39_FN0, MSEL1CR_6_0),
+ PINMUX_DATA(IRQ6_164_MARK, PORT164_FN0, MSEL1CR_6_1),
+ PINMUX_DATA(IRQ7_40_MARK, PORT40_FN0, MSEL1CR_7_1),
+ PINMUX_DATA(IRQ7_167_MARK, PORT167_FN0, MSEL1CR_7_0),
+ PINMUX_DATA(IRQ8_41_MARK, PORT41_FN0, MSEL1CR_8_1),
+ PINMUX_DATA(IRQ8_168_MARK, PORT168_FN0, MSEL1CR_8_0),
+ PINMUX_DATA(IRQ9_42_MARK, PORT42_FN0, MSEL1CR_9_0),
+ PINMUX_DATA(IRQ9_169_MARK, PORT169_FN0, MSEL1CR_9_1),
+ PINMUX_DATA(IRQ10_MARK, PORT65_FN0, MSEL1CR_9_1),
+ PINMUX_DATA(IRQ11_MARK, PORT67_FN0),
+ PINMUX_DATA(IRQ12_80_MARK, PORT80_FN0, MSEL1CR_12_0),
+ PINMUX_DATA(IRQ12_137_MARK, PORT137_FN0, MSEL1CR_12_1),
+ PINMUX_DATA(IRQ13_81_MARK, PORT81_FN0, MSEL1CR_13_0),
+ PINMUX_DATA(IRQ13_145_MARK, PORT145_FN0, MSEL1CR_13_1),
+ PINMUX_DATA(IRQ14_82_MARK, PORT82_FN0, MSEL1CR_14_0),
+ PINMUX_DATA(IRQ14_146_MARK, PORT146_FN0, MSEL1CR_14_1),
+ PINMUX_DATA(IRQ15_83_MARK, PORT83_FN0, MSEL1CR_15_0),
+ PINMUX_DATA(IRQ15_147_MARK, PORT147_FN0, MSEL1CR_15_1),
+ PINMUX_DATA(IRQ16_84_MARK, PORT84_FN0, MSEL1CR_16_0),
+ PINMUX_DATA(IRQ16_170_MARK, PORT170_FN0, MSEL1CR_16_1),
+ PINMUX_DATA(IRQ17_MARK, PORT85_FN0),
+ PINMUX_DATA(IRQ18_MARK, PORT86_FN0),
+ PINMUX_DATA(IRQ19_MARK, PORT87_FN0),
+ PINMUX_DATA(IRQ20_MARK, PORT92_FN0),
+ PINMUX_DATA(IRQ21_MARK, PORT93_FN0),
+ PINMUX_DATA(IRQ22_MARK, PORT94_FN0),
+ PINMUX_DATA(IRQ23_MARK, PORT95_FN0),
+ PINMUX_DATA(IRQ24_MARK, PORT112_FN0),
+ PINMUX_DATA(IRQ25_MARK, PORT119_FN0),
+ PINMUX_DATA(IRQ26_121_MARK, PORT121_FN0, MSEL1CR_26_1),
+ PINMUX_DATA(IRQ26_172_MARK, PORT172_FN0, MSEL1CR_26_0),
+ PINMUX_DATA(IRQ27_122_MARK, PORT122_FN0, MSEL1CR_27_1),
+ PINMUX_DATA(IRQ27_180_MARK, PORT180_FN0, MSEL1CR_27_0),
+ PINMUX_DATA(IRQ28_123_MARK, PORT123_FN0, MSEL1CR_28_1),
+ PINMUX_DATA(IRQ28_181_MARK, PORT181_FN0, MSEL1CR_28_0),
+ PINMUX_DATA(IRQ29_129_MARK, PORT129_FN0, MSEL1CR_29_1),
+ PINMUX_DATA(IRQ29_182_MARK, PORT182_FN0, MSEL1CR_29_0),
+ PINMUX_DATA(IRQ30_130_MARK, PORT130_FN0, MSEL1CR_30_1),
+ PINMUX_DATA(IRQ30_183_MARK, PORT183_FN0, MSEL1CR_30_0),
+ PINMUX_DATA(IRQ31_138_MARK, PORT138_FN0, MSEL1CR_31_1),
+ PINMUX_DATA(IRQ31_184_MARK, PORT184_FN0, MSEL1CR_31_0),
+
+ /* Function 1 */
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT0_FN1),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT1_FN1),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT2_FN1),
+ PINMUX_DATA(BBIF2_RXD_MARK, PORT3_FN1),
+ PINMUX_DATA(FSIACK_MARK, PORT4_FN1),
+ PINMUX_DATA(FSIAILR_MARK, PORT5_FN1),
+ PINMUX_DATA(FSIAIBT_MARK, PORT6_FN1),
+ PINMUX_DATA(FSIAISLD_MARK, PORT7_FN1),
+ PINMUX_DATA(FSIAOMC_MARK, PORT8_FN1),
+ PINMUX_DATA(FSIAOLR_MARK, PORT9_FN1),
+ PINMUX_DATA(FSIAOBT_MARK, PORT10_FN1),
+ PINMUX_DATA(FSIAOSLD_MARK, PORT11_FN1),
+ PINMUX_DATA(FMSOCK_MARK, PORT12_FN1),
+ PINMUX_DATA(FMSOOLR_MARK, PORT13_FN1),
+ PINMUX_DATA(FMSOOBT_MARK, PORT14_FN1),
+ PINMUX_DATA(FMSOSLD_MARK, PORT15_FN1),
+ PINMUX_DATA(FMSOILR_MARK, PORT16_FN1),
+ PINMUX_DATA(FMSOIBT_MARK, PORT17_FN1),
+ PINMUX_DATA(FMSISLD_MARK, PORT18_FN1),
+ PINMUX_DATA(A0_MARK, PORT19_FN1),
+ PINMUX_DATA(A1_MARK, PORT20_FN1),
+ PINMUX_DATA(A2_MARK, PORT21_FN1),
+ PINMUX_DATA(A3_MARK, PORT22_FN1),
+ PINMUX_DATA(A4_FOE_MARK, PORT23_FN1),
+ PINMUX_DATA(A5_FCDE_MARK, PORT24_FN1),
+ PINMUX_DATA(A6_MARK, PORT25_FN1),
+ PINMUX_DATA(A7_MARK, PORT26_FN1),
+ PINMUX_DATA(A8_MARK, PORT27_FN1),
+ PINMUX_DATA(A9_MARK, PORT28_FN1),
+ PINMUX_DATA(A10_MARK, PORT29_FN1),
+ PINMUX_DATA(A11_MARK, PORT30_FN1),
+ PINMUX_DATA(A12_MARK, PORT31_FN1),
+ PINMUX_DATA(A13_MARK, PORT32_FN1),
+ PINMUX_DATA(A14_MARK, PORT33_FN1),
+ PINMUX_DATA(A15_MARK, PORT34_FN1),
+ PINMUX_DATA(A16_MARK, PORT35_FN1),
+ PINMUX_DATA(A17_MARK, PORT36_FN1),
+ PINMUX_DATA(A18_MARK, PORT37_FN1),
+ PINMUX_DATA(A19_MARK, PORT38_FN1),
+ PINMUX_DATA(A20_MARK, PORT39_FN1),
+ PINMUX_DATA(A21_MARK, PORT40_FN1),
+ PINMUX_DATA(A22_MARK, PORT41_FN1),
+ PINMUX_DATA(A23_MARK, PORT42_FN1),
+ PINMUX_DATA(A24_MARK, PORT43_FN1),
+ PINMUX_DATA(A25_MARK, PORT44_FN1),
+ PINMUX_DATA(A26_MARK, PORT45_FN1),
+ PINMUX_DATA(D0_NAF0_MARK, PORT46_FN1),
+ PINMUX_DATA(D1_NAF1_MARK, PORT47_FN1),
+ PINMUX_DATA(D2_NAF2_MARK, PORT48_FN1),
+ PINMUX_DATA(D3_NAF3_MARK, PORT49_FN1),
+ PINMUX_DATA(D4_NAF4_MARK, PORT50_FN1),
+ PINMUX_DATA(D5_NAF5_MARK, PORT51_FN1),
+ PINMUX_DATA(D6_NAF6_MARK, PORT52_FN1),
+ PINMUX_DATA(D7_NAF7_MARK, PORT53_FN1),
+ PINMUX_DATA(D8_NAF8_MARK, PORT54_FN1),
+ PINMUX_DATA(D9_NAF9_MARK, PORT55_FN1),
+ PINMUX_DATA(D10_NAF10_MARK, PORT56_FN1),
+ PINMUX_DATA(D11_NAF11_MARK, PORT57_FN1),
+ PINMUX_DATA(D12_NAF12_MARK, PORT58_FN1),
+ PINMUX_DATA(D13_NAF13_MARK, PORT59_FN1),
+ PINMUX_DATA(D14_NAF14_MARK, PORT60_FN1),
+ PINMUX_DATA(D15_NAF15_MARK, PORT61_FN1),
+ PINMUX_DATA(CS0_MARK, PORT62_FN1),
+ PINMUX_DATA(CS2_MARK, PORT63_FN1),
+ PINMUX_DATA(CS4_MARK, PORT64_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT65_FN1),
+ PINMUX_DATA(CS5B_MARK, PORT66_FN1),
+ PINMUX_DATA(CS6A_MARK, PORT67_FN1),
+ PINMUX_DATA(FCE0_MARK, PORT68_FN1),
+ PINMUX_DATA(RD_FSC_MARK, PORT69_FN1),
+ PINMUX_DATA(WE0_FWE_MARK, PORT70_FN1),
+ PINMUX_DATA(WE1_MARK, PORT71_FN1),
+ PINMUX_DATA(CKO_MARK, PORT72_FN1),
+ PINMUX_DATA(FRB_MARK, PORT73_FN1),
+ PINMUX_DATA(WAIT_MARK, PORT74_FN1),
+ PINMUX_DATA(RDWR_MARK, PORT75_FN1),
+ PINMUX_DATA(MEMC_AD0_MARK, PORT76_FN1),
+ PINMUX_DATA(MEMC_AD1_MARK, PORT77_FN1),
+ PINMUX_DATA(MEMC_AD2_MARK, PORT78_FN1),
+ PINMUX_DATA(MEMC_AD3_MARK, PORT79_FN1),
+ PINMUX_DATA(MEMC_AD4_MARK, PORT80_FN1),
+ PINMUX_DATA(MEMC_AD5_MARK, PORT81_FN1),
+ PINMUX_DATA(MEMC_AD6_MARK, PORT82_FN1),
+ PINMUX_DATA(MEMC_AD7_MARK, PORT83_FN1),
+ PINMUX_DATA(MEMC_AD8_MARK, PORT84_FN1),
+ PINMUX_DATA(MEMC_AD9_MARK, PORT85_FN1),
+ PINMUX_DATA(MEMC_AD10_MARK, PORT86_FN1),
+ PINMUX_DATA(MEMC_AD11_MARK, PORT87_FN1),
+ PINMUX_DATA(MEMC_AD12_MARK, PORT88_FN1),
+ PINMUX_DATA(MEMC_AD13_MARK, PORT89_FN1),
+ PINMUX_DATA(MEMC_AD14_MARK, PORT90_FN1),
+ PINMUX_DATA(MEMC_AD15_MARK, PORT91_FN1),
+ PINMUX_DATA(MEMC_CS0_MARK, PORT92_FN1),
+ PINMUX_DATA(MEMC_BUSCLK_MEMC_A0_MARK, PORT93_FN1),
+ PINMUX_DATA(MEMC_CS1_MEMC_A1_MARK, PORT94_FN1),
+ PINMUX_DATA(MEMC_ADV_MEMC_DREQ0_MARK, PORT95_FN1),
+ PINMUX_DATA(MEMC_WAIT_MEMC_DREQ1_MARK, PORT96_FN1),
+ PINMUX_DATA(MEMC_NOE_MARK, PORT97_FN1),
+ PINMUX_DATA(MEMC_NWE_MARK, PORT98_FN1),
+ PINMUX_DATA(MEMC_INT_MARK, PORT99_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT100_FN1),
+ PINMUX_DATA(VIO_HD_MARK, PORT101_FN1),
+ PINMUX_DATA(VIO_D0_MARK, PORT102_FN1),
+ PINMUX_DATA(VIO_D1_MARK, PORT103_FN1),
+ PINMUX_DATA(VIO_D2_MARK, PORT104_FN1),
+ PINMUX_DATA(VIO_D3_MARK, PORT105_FN1),
+ PINMUX_DATA(VIO_D4_MARK, PORT106_FN1),
+ PINMUX_DATA(VIO_D5_MARK, PORT107_FN1),
+ PINMUX_DATA(VIO_D6_MARK, PORT108_FN1),
+ PINMUX_DATA(VIO_D7_MARK, PORT109_FN1),
+ PINMUX_DATA(VIO_D8_MARK, PORT110_FN1),
+ PINMUX_DATA(VIO_D9_MARK, PORT111_FN1),
+ PINMUX_DATA(VIO_D10_MARK, PORT112_FN1),
+ PINMUX_DATA(VIO_D11_MARK, PORT113_FN1),
+ PINMUX_DATA(VIO_D12_MARK, PORT114_FN1),
+ PINMUX_DATA(VIO_D13_MARK, PORT115_FN1),
+ PINMUX_DATA(VIO_D14_MARK, PORT116_FN1),
+ PINMUX_DATA(VIO_D15_MARK, PORT117_FN1),
+ PINMUX_DATA(VIO_CLK_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT119_FN1),
+ PINMUX_DATA(VIO_CKO_MARK, PORT120_FN1),
+ PINMUX_DATA(LCDD0_MARK, PORT121_FN1),
+ PINMUX_DATA(LCDD1_MARK, PORT122_FN1),
+ PINMUX_DATA(LCDD2_MARK, PORT123_FN1),
+ PINMUX_DATA(LCDD3_MARK, PORT124_FN1),
+ PINMUX_DATA(LCDD4_MARK, PORT125_FN1),
+ PINMUX_DATA(LCDD5_MARK, PORT126_FN1),
+ PINMUX_DATA(LCDD6_MARK, PORT127_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT128_FN1),
+ PINMUX_DATA(LCDD8_MARK, PORT129_FN1),
+ PINMUX_DATA(LCDD9_MARK, PORT130_FN1),
+ PINMUX_DATA(LCDD10_MARK, PORT131_FN1),
+ PINMUX_DATA(LCDD11_MARK, PORT132_FN1),
+ PINMUX_DATA(LCDD12_MARK, PORT133_FN1),
+ PINMUX_DATA(LCDD13_MARK, PORT134_FN1),
+ PINMUX_DATA(LCDD14_MARK, PORT135_FN1),
+ PINMUX_DATA(LCDD15_MARK, PORT136_FN1),
+ PINMUX_DATA(LCDD16_MARK, PORT137_FN1),
+ PINMUX_DATA(LCDD17_MARK, PORT138_FN1),
+ PINMUX_DATA(LCDD18_MARK, PORT139_FN1),
+ PINMUX_DATA(LCDD19_MARK, PORT140_FN1),
+ PINMUX_DATA(LCDD20_MARK, PORT141_FN1),
+ PINMUX_DATA(LCDD21_MARK, PORT142_FN1),
+ PINMUX_DATA(LCDD22_MARK, PORT143_FN1),
+ PINMUX_DATA(LCDD23_MARK, PORT144_FN1),
+ PINMUX_DATA(LCDHSYN_MARK, PORT145_FN1),
+ PINMUX_DATA(LCDVSYN_MARK, PORT146_FN1),
+ PINMUX_DATA(LCDDCK_MARK, PORT147_FN1),
+ PINMUX_DATA(LCDRD_MARK, PORT148_FN1),
+ PINMUX_DATA(LCDDISP_MARK, PORT149_FN1),
+ PINMUX_DATA(LCDLCLK_MARK, PORT150_FN1),
+ PINMUX_DATA(LCDDON_MARK, PORT151_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT152_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT153_FN1),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT154_FN1),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT155_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT156_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT157_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT158_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT159_FN1),
+ PINMUX_DATA(TPU0TO0_MARK, PORT160_FN1),
+ PINMUX_DATA(TPU0TO1_MARK, PORT161_FN1),
+ PINMUX_DATA(SCIFB_SCK_MARK, PORT162_FN1),
+ PINMUX_DATA(SCIFB_RTS_MARK, PORT163_FN1),
+ PINMUX_DATA(SCIFB_CTS_MARK, PORT164_FN1),
+ PINMUX_DATA(SCIFB_TXD_MARK, PORT165_FN1),
+ PINMUX_DATA(SCIFB_RXD_MARK, PORT166_FN1),
+ PINMUX_DATA(VBUS0_0_MARK, PORT167_FN1),
+ PINMUX_DATA(VBUS0_1_MARK, PORT168_FN1),
+ PINMUX_DATA(HDMI_HPD_MARK, PORT169_FN1),
+ PINMUX_DATA(HDMI_CEC_MARK, PORT170_FN1),
+ PINMUX_DATA(SDHICLK0_MARK, PORT171_FN1),
+ PINMUX_DATA(SDHICD0_MARK, PORT172_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT173_FN1),
+ PINMUX_DATA(SDHID0_1_MARK, PORT174_FN1),
+ PINMUX_DATA(SDHID0_2_MARK, PORT175_FN1),
+ PINMUX_DATA(SDHID0_3_MARK, PORT176_FN1),
+ PINMUX_DATA(SDHICMD0_MARK, PORT177_FN1),
+ PINMUX_DATA(SDHIWP0_MARK, PORT178_FN1),
+ PINMUX_DATA(SDHICLK1_MARK, PORT179_FN1),
+ PINMUX_DATA(SDHID1_0_MARK, PORT180_FN1),
+ PINMUX_DATA(SDHID1_1_MARK, PORT181_FN1),
+ PINMUX_DATA(SDHID1_2_MARK, PORT182_FN1),
+ PINMUX_DATA(SDHID1_3_MARK, PORT183_FN1),
+ PINMUX_DATA(SDHICMD1_MARK, PORT184_FN1),
+ PINMUX_DATA(SDHICLK2_MARK, PORT185_FN1),
+ PINMUX_DATA(SDHID2_0_MARK, PORT186_FN1),
+ PINMUX_DATA(SDHID2_1_MARK, PORT187_FN1),
+ PINMUX_DATA(SDHID2_2_MARK, PORT188_FN1),
+ PINMUX_DATA(SDHID2_3_MARK, PORT189_FN1),
+ PINMUX_DATA(SDHICMD2_MARK, PORT190_FN1),
+
+ /* Function 2 */
+ PINMUX_DATA(FSIBCK_MARK, PORT4_FN2),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT5_FN2),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT6_FN2),
+ PINMUX_DATA(SCIFA5_RXD_MARK, PORT8_FN2),
+ PINMUX_DATA(FSIASPDIF_11_MARK, PORT11_FN2),
+ PINMUX_DATA(SCIFA5_TXD_MARK, PORT12_FN2),
+ PINMUX_DATA(FMSIOLR_MARK, PORT13_FN2),
+ PINMUX_DATA(FMSIOBT_MARK, PORT14_FN2),
+ PINMUX_DATA(FSIASPDIF_15_MARK, PORT15_FN2),
+ PINMUX_DATA(FMSIILR_MARK, PORT16_FN2),
+ PINMUX_DATA(FMSIIBT_MARK, PORT17_FN2),
+ PINMUX_DATA(BS_MARK, PORT19_FN2),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT36_FN2),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT37_FN2),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT38_FN2),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT39_FN2),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT40_FN2),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT41_FN2),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT42_FN2),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT43_FN2),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT44_FN2),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT45_FN2),
+ PINMUX_DATA(FMSICK_MARK, PORT65_FN2),
+ PINMUX_DATA(FCE1_MARK, PORT66_FN2),
+ PINMUX_DATA(BBIF1_RXD_MARK, PORT76_FN2),
+ PINMUX_DATA(BBIF1_TSYNC_MARK, PORT77_FN2),
+ PINMUX_DATA(BBIF1_TSCK_MARK, PORT78_FN2),
+ PINMUX_DATA(BBIF1_TXD_MARK, PORT79_FN2),
+ PINMUX_DATA(BBIF1_RSCK_MARK, PORT80_FN2),
+ PINMUX_DATA(BBIF1_RSYNC_MARK, PORT81_FN2),
+ PINMUX_DATA(BBIF1_FLOW_MARK, PORT82_FN2),
+ PINMUX_DATA(BB_RX_FLOW_N_MARK, PORT83_FN2),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT84_FN2),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT85_FN2),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT86_FN2),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT87_FN2),
+ PINMUX_DATA(MSIOF1_TSCK_88_MARK, PORT88_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_TSYNC_89_MARK, PORT89_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_TXD_90_MARK, PORT90_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_RXD_91_MARK, PORT91_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_SS1_92_MARK, PORT92_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(MSIOF1_SS2_93_MARK, PORT93_FN2, MSEL4CR_10_1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT94_FN2),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT95_FN2),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT96_FN2),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT97_FN2),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT98_FN2),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT110_FN2),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT111_FN2),
+ PINMUX_DATA(I2C_SCL3_MARK, PORT114_FN2, MSEL4CR_16_1),
+ PINMUX_DATA(I2C_SDA3_MARK, PORT115_FN2, MSEL4CR_16_1),
+ PINMUX_DATA(I2C_SCL4_MARK, PORT116_FN2, MSEL4CR_17_1),
+ PINMUX_DATA(I2C_SDA4_MARK, PORT117_FN2, MSEL4CR_17_1),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT134_FN2),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT135_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT136_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT137_FN2),
+ PINMUX_DATA(MSIOF2_SS1_MARK, PORT138_FN2),
+ PINMUX_DATA(MSIOF2_SS2_MARK, PORT139_FN2),
+ PINMUX_DATA(SCIFA3_CTS_140_MARK, PORT140_FN2, MSEL3CR_9_1),
+ PINMUX_DATA(SCIFA3_RTS_141_MARK, PORT141_FN2),
+ PINMUX_DATA(SCIFA3_SCK_MARK, PORT142_FN2),
+ PINMUX_DATA(SCIFA3_TXD_MARK, PORT143_FN2),
+ PINMUX_DATA(SCIFA3_RXD_MARK, PORT144_FN2),
+ PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT148_FN2),
+ PINMUX_DATA(MSIOF2_TSCK_MARK, PORT149_FN2),
+ PINMUX_DATA(MSIOF2_RXD_MARK, PORT150_FN2),
+ PINMUX_DATA(MSIOF2_TXD_MARK, PORT151_FN2),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT156_FN2),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT157_FN2),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT158_FN2),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT159_FN2),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT160_FN2),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT161_FN2),
+
+ /* Function 3 */
+ PINMUX_DATA(VIO_CKO1_MARK, PORT16_FN3),
+ PINMUX_DATA(VIO_CKO2_MARK, PORT17_FN3),
+ PINMUX_DATA(IDIN_1_18_MARK, PORT18_FN3, MSEL4CR_14_1),
+ PINMUX_DATA(MSIOF1_TSCK_39_MARK, PORT39_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_TSYNC_40_MARK, PORT40_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_TXD_41_MARK, PORT41_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_RXD_42_MARK, PORT42_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_SS1_43_MARK, PORT43_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MSIOF1_SS2_44_MARK, PORT44_FN3, MSEL4CR_10_0),
+ PINMUX_DATA(MMCD1_0_MARK, PORT54_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_1_MARK, PORT55_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_2_MARK, PORT56_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_3_MARK, PORT57_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_4_MARK, PORT58_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_5_MARK, PORT59_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_6_MARK, PORT60_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCD1_7_MARK, PORT61_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(VINT_I_MARK, PORT65_FN3),
+ PINMUX_DATA(MMCCLK1_MARK, PORT66_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(MMCCMD1_MARK, PORT67_FN3, MSEL4CR_15_1),
+ PINMUX_DATA(TPU0TO2_93_MARK, PORT93_FN3),
+ PINMUX_DATA(TPU0TO2_99_MARK, PORT99_FN3),
+ PINMUX_DATA(TPU0TO3_MARK, PORT112_FN3),
+ PINMUX_DATA(IDIN_0_MARK, PORT113_FN3),
+ PINMUX_DATA(EXTLP_0_MARK, PORT114_FN3),
+ PINMUX_DATA(OVCN2_0_MARK, PORT115_FN3),
+ PINMUX_DATA(PWEN_0_MARK, PORT116_FN3),
+ PINMUX_DATA(OVCN_0_MARK, PORT117_FN3),
+ PINMUX_DATA(KEYOUT7_MARK, PORT121_FN3),
+ PINMUX_DATA(KEYOUT6_MARK, PORT122_FN3),
+ PINMUX_DATA(KEYOUT5_MARK, PORT123_FN3),
+ PINMUX_DATA(KEYOUT4_MARK, PORT124_FN3),
+ PINMUX_DATA(KEYOUT3_MARK, PORT125_FN3),
+ PINMUX_DATA(KEYOUT2_MARK, PORT126_FN3),
+ PINMUX_DATA(KEYOUT1_MARK, PORT127_FN3),
+ PINMUX_DATA(KEYOUT0_MARK, PORT128_FN3),
+ PINMUX_DATA(KEYIN7_MARK, PORT129_FN3),
+ PINMUX_DATA(KEYIN6_MARK, PORT130_FN3),
+ PINMUX_DATA(KEYIN5_MARK, PORT131_FN3),
+ PINMUX_DATA(KEYIN4_MARK, PORT132_FN3),
+ PINMUX_DATA(KEYIN3_133_MARK, PORT133_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN2_134_MARK, PORT134_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN1_135_MARK, PORT135_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(KEYIN0_136_MARK, PORT136_FN3, MSEL4CR_18_0),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT137_FN3),
+ PINMUX_DATA(IROUT_139_MARK, PORT139_FN3),
+ PINMUX_DATA(IRDA_OUT_MARK, PORT140_FN3),
+ PINMUX_DATA(IRDA_IN_MARK, PORT141_FN3),
+ PINMUX_DATA(IRDA_FIRSEL_MARK, PORT142_FN3),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT145_FN3),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT146_FN3),
+ PINMUX_DATA(TS_SCK2_MARK, PORT147_FN3),
+
+ /* Function 4 */
+ PINMUX_DATA(SCIFA3_CTS_43_MARK, PORT43_FN4, MSEL3CR_9_0),
+ PINMUX_DATA(SCIFA3_RTS_44_MARK, PORT44_FN4),
+ PINMUX_DATA(GP_RX_FLAG_MARK, PORT76_FN4),
+ PINMUX_DATA(GP_RX_DATA_MARK, PORT77_FN4),
+ PINMUX_DATA(GP_TX_READY_MARK, PORT78_FN4),
+ PINMUX_DATA(GP_RX_WAKE_MARK, PORT79_FN4),
+ PINMUX_DATA(MP_TX_FLAG_MARK, PORT80_FN4),
+ PINMUX_DATA(MP_TX_DATA_MARK, PORT81_FN4),
+ PINMUX_DATA(MP_RX_READY_MARK, PORT82_FN4),
+ PINMUX_DATA(MP_TX_WAKE_MARK, PORT83_FN4),
+ PINMUX_DATA(MMCD0_0_MARK, PORT84_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_1_MARK, PORT85_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_2_MARK, PORT86_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_3_MARK, PORT87_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_4_MARK, PORT88_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_5_MARK, PORT89_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_6_MARK, PORT90_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCD0_7_MARK, PORT91_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(MMCCMD0_MARK, PORT92_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(SIM_RST_MARK, PORT94_FN4),
+ PINMUX_DATA(SIM_CLK_MARK, PORT95_FN4),
+ PINMUX_DATA(SIM_D_MARK, PORT98_FN4),
+ PINMUX_DATA(MMCCLK0_MARK, PORT99_FN4, MSEL4CR_15_0),
+ PINMUX_DATA(IDIN_1_113_MARK, PORT113_FN4, MSEL4CR_14_0),
+ PINMUX_DATA(OVCN_1_114_MARK, PORT114_FN4, MSEL4CR_14_0),
+ PINMUX_DATA(PWEN_1_115_MARK, PORT115_FN4),
+ PINMUX_DATA(EXTLP_1_MARK, PORT116_FN4),
+ PINMUX_DATA(OVCN2_1_MARK, PORT117_FN4),
+ PINMUX_DATA(KEYIN0_121_MARK, PORT121_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN1_122_MARK, PORT122_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN2_123_MARK, PORT123_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(KEYIN3_124_MARK, PORT124_FN4, MSEL4CR_18_1),
+ PINMUX_DATA(PWEN_1_138_MARK, PORT138_FN4),
+ PINMUX_DATA(IROUT_140_MARK, PORT140_FN4),
+ PINMUX_DATA(LCDCS_MARK, PORT145_FN4),
+ PINMUX_DATA(LCDWR_MARK, PORT147_FN4),
+ PINMUX_DATA(LCDRS_MARK, PORT149_FN4),
+ PINMUX_DATA(OVCN_1_162_MARK, PORT162_FN4, MSEL4CR_14_1),
+
+ /* Function 5 */
+ PINMUX_DATA(GPI0_MARK, PORT41_FN5),
+ PINMUX_DATA(GPI1_MARK, PORT42_FN5),
+ PINMUX_DATA(GPO0_MARK, PORT43_FN5),
+ PINMUX_DATA(GPO1_MARK, PORT44_FN5),
+ PINMUX_DATA(I2C_SCL3S_MARK, PORT137_FN5, MSEL4CR_16_0),
+ PINMUX_DATA(I2C_SDA3S_MARK, PORT145_FN5, MSEL4CR_16_0),
+ PINMUX_DATA(I2C_SCL4S_MARK, PORT146_FN5, MSEL4CR_17_0),
+ PINMUX_DATA(I2C_SDA4S_MARK, PORT147_FN5, MSEL4CR_17_0),
+
+ /* Function select */
+ PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0),
+ PINMUX_DATA(LCDC1_SELECT_MARK, MSEL3CR_6_1),
+
+ PINMUX_DATA(TS0_1SELECT_MARK, MSEL3CR_21_0, MSEL3CR_20_0),
+ PINMUX_DATA(TS0_2SELECT_MARK, MSEL3CR_21_0, MSEL3CR_20_1),
+ PINMUX_DATA(TS1_1SELECT_MARK, MSEL3CR_27_0, MSEL3CR_26_0),
+ PINMUX_DATA(TS1_2SELECT_MARK, MSEL3CR_27_0, MSEL3CR_26_1),
+
+ PINMUX_DATA(SDENC_CPG_MARK, MSEL4CR_19_0),
+ PINMUX_DATA(SDENC_DV_CLKI_MARK, MSEL4CR_19_1),
+
+ PINMUX_DATA(MFIv6_MARK, MSEL4CR_6_0),
+ PINMUX_DATA(MFIv4_MARK, MSEL4CR_6_1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_ALL() _190(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+
+ /* PORT */
+ GPIO_PORT_ALL(),
+
+ /* IRQ */
+ GPIO_FN(IRQ0_6), GPIO_FN(IRQ0_162), GPIO_FN(IRQ1),
+ GPIO_FN(IRQ2_4), GPIO_FN(IRQ2_5), GPIO_FN(IRQ3_8),
+ GPIO_FN(IRQ3_16), GPIO_FN(IRQ4_17), GPIO_FN(IRQ4_163),
+ GPIO_FN(IRQ5), GPIO_FN(IRQ6_39), GPIO_FN(IRQ6_164),
+ GPIO_FN(IRQ7_40), GPIO_FN(IRQ7_167), GPIO_FN(IRQ8_41),
+ GPIO_FN(IRQ8_168), GPIO_FN(IRQ9_42), GPIO_FN(IRQ9_169),
+ GPIO_FN(IRQ10), GPIO_FN(IRQ11), GPIO_FN(IRQ12_80),
+ GPIO_FN(IRQ12_137), GPIO_FN(IRQ13_81), GPIO_FN(IRQ13_145),
+ GPIO_FN(IRQ14_82), GPIO_FN(IRQ14_146), GPIO_FN(IRQ15_83),
+ GPIO_FN(IRQ15_147), GPIO_FN(IRQ16_84), GPIO_FN(IRQ16_170),
+ GPIO_FN(IRQ17), GPIO_FN(IRQ18), GPIO_FN(IRQ19),
+ GPIO_FN(IRQ20), GPIO_FN(IRQ21), GPIO_FN(IRQ22),
+ GPIO_FN(IRQ23), GPIO_FN(IRQ24), GPIO_FN(IRQ25),
+ GPIO_FN(IRQ26_121), GPIO_FN(IRQ26_172), GPIO_FN(IRQ27_122),
+ GPIO_FN(IRQ27_180), GPIO_FN(IRQ28_123), GPIO_FN(IRQ28_181),
+ GPIO_FN(IRQ29_129), GPIO_FN(IRQ29_182), GPIO_FN(IRQ30_130),
+ GPIO_FN(IRQ30_183), GPIO_FN(IRQ31_138), GPIO_FN(IRQ31_184),
+
+ /* MSIOF0 */
+ GPIO_FN(MSIOF0_TSYNC), GPIO_FN(MSIOF0_TSCK), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(MSIOF0_RSCK), GPIO_FN(MSIOF0_RSYNC), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(MSIOF0_MCK1), GPIO_FN(MSIOF0_SS1), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(MSIOF0_TXD),
+
+ /* MSIOF1 */
+ GPIO_FN(MSIOF1_TSCK_39), GPIO_FN(MSIOF1_TSCK_88),
+ GPIO_FN(MSIOF1_TSYNC_40), GPIO_FN(MSIOF1_TSYNC_89),
+ GPIO_FN(MSIOF1_TXD_41), GPIO_FN(MSIOF1_TXD_90),
+ GPIO_FN(MSIOF1_RXD_42), GPIO_FN(MSIOF1_RXD_91),
+ GPIO_FN(MSIOF1_SS1_43), GPIO_FN(MSIOF1_SS1_92),
+ GPIO_FN(MSIOF1_SS2_44), GPIO_FN(MSIOF1_SS2_93),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(MSIOF1_RSYNC),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(MSIOF1_MCK1),
+
+ /* MSIOF2 */
+ GPIO_FN(MSIOF2_RSCK), GPIO_FN(MSIOF2_RSYNC), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(MSIOF2_MCK1), GPIO_FN(MSIOF2_SS1), GPIO_FN(MSIOF2_SS2),
+ GPIO_FN(MSIOF2_TSYNC), GPIO_FN(MSIOF2_TSCK), GPIO_FN(MSIOF2_RXD),
+ GPIO_FN(MSIOF2_TXD),
+
+ /* BBIF1 */
+ GPIO_FN(BBIF1_RXD), GPIO_FN(BBIF1_TSYNC), GPIO_FN(BBIF1_TSCK),
+ GPIO_FN(BBIF1_TXD), GPIO_FN(BBIF1_RSCK), GPIO_FN(BBIF1_RSYNC),
+ GPIO_FN(BBIF1_FLOW), GPIO_FN(BB_RX_FLOW_N),
+
+ /* BBIF2 */
+ GPIO_FN(BBIF2_TSCK1), GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(BBIF2_TXD1), GPIO_FN(BBIF2_RXD),
+
+ /* FSI */
+ GPIO_FN(FSIACK), GPIO_FN(FSIBCK), GPIO_FN(FSIAILR),
+ GPIO_FN(FSIAIBT), GPIO_FN(FSIAISLD), GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIAOLR), GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD),
+ GPIO_FN(FSIASPDIF_11), GPIO_FN(FSIASPDIF_15),
+
+ /* FMSI */
+ GPIO_FN(FMSOCK), GPIO_FN(FMSOOLR), GPIO_FN(FMSIOLR),
+ GPIO_FN(FMSOOBT), GPIO_FN(FMSIOBT), GPIO_FN(FMSOSLD),
+ GPIO_FN(FMSOILR), GPIO_FN(FMSIILR), GPIO_FN(FMSOIBT),
+ GPIO_FN(FMSIIBT), GPIO_FN(FMSISLD), GPIO_FN(FMSICK),
+
+ /* SCIFA0 */
+ GPIO_FN(SCIFA0_TXD), GPIO_FN(SCIFA0_RXD), GPIO_FN(SCIFA0_SCK),
+ GPIO_FN(SCIFA0_RTS), GPIO_FN(SCIFA0_CTS),
+
+ /* SCIFA1 */
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(SCIFA1_RXD), GPIO_FN(SCIFA1_SCK),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(SCIFA1_CTS),
+
+ /* SCIFA2 */
+ GPIO_FN(SCIFA2_CTS1), GPIO_FN(SCIFA2_RTS1), GPIO_FN(SCIFA2_TXD1),
+ GPIO_FN(SCIFA2_RXD1), GPIO_FN(SCIFA2_SCK1),
+
+ /* SCIFA3 */
+ GPIO_FN(SCIFA3_CTS_43), GPIO_FN(SCIFA3_CTS_140),
+ GPIO_FN(SCIFA3_RTS_44), GPIO_FN(SCIFA3_RTS_141),
+ GPIO_FN(SCIFA3_SCK), GPIO_FN(SCIFA3_TXD),
+ GPIO_FN(SCIFA3_RXD),
+
+ /* SCIFA4 */
+ GPIO_FN(SCIFA4_RXD), GPIO_FN(SCIFA4_TXD),
+
+ /* SCIFA5 */
+ GPIO_FN(SCIFA5_RXD), GPIO_FN(SCIFA5_TXD),
+
+ /* SCIFB */
+ GPIO_FN(SCIFB_SCK), GPIO_FN(SCIFB_RTS), GPIO_FN(SCIFB_CTS),
+ GPIO_FN(SCIFB_TXD), GPIO_FN(SCIFB_RXD),
+
+ /* CEU */
+ GPIO_FN(VIO_HD), GPIO_FN(VIO_CKO1), GPIO_FN(VIO_CKO2),
+ GPIO_FN(VIO_VD), GPIO_FN(VIO_CLK), GPIO_FN(VIO_FIELD),
+ GPIO_FN(VIO_CKO), GPIO_FN(VIO_D0), GPIO_FN(VIO_D1),
+ GPIO_FN(VIO_D2), GPIO_FN(VIO_D3), GPIO_FN(VIO_D4),
+ GPIO_FN(VIO_D5), GPIO_FN(VIO_D6), GPIO_FN(VIO_D7),
+ GPIO_FN(VIO_D8), GPIO_FN(VIO_D9), GPIO_FN(VIO_D10),
+ GPIO_FN(VIO_D11), GPIO_FN(VIO_D12), GPIO_FN(VIO_D13),
+ GPIO_FN(VIO_D14), GPIO_FN(VIO_D15),
+
+ /* USB0 */
+ GPIO_FN(IDIN_0), GPIO_FN(EXTLP_0), GPIO_FN(OVCN2_0),
+ GPIO_FN(PWEN_0), GPIO_FN(OVCN_0), GPIO_FN(VBUS0_0),
+
+ /* USB1 */
+ GPIO_FN(IDIN_1_18), GPIO_FN(IDIN_1_113),
+ GPIO_FN(OVCN_1_114), GPIO_FN(OVCN_1_162),
+ GPIO_FN(PWEN_1_115), GPIO_FN(PWEN_1_138),
+ GPIO_FN(EXTLP_1), GPIO_FN(OVCN2_1),
+ GPIO_FN(VBUS0_1),
+
+ /* GPIO */
+ GPIO_FN(GPI0), GPIO_FN(GPI1), GPIO_FN(GPO0), GPIO_FN(GPO1),
+
+ /* BSC */
+ GPIO_FN(BS), GPIO_FN(WE1), GPIO_FN(CKO),
+ GPIO_FN(WAIT), GPIO_FN(RDWR),
+
+ GPIO_FN(A0), GPIO_FN(A1), GPIO_FN(A2),
+ GPIO_FN(A3), GPIO_FN(A6), GPIO_FN(A7),
+ GPIO_FN(A8), GPIO_FN(A9), GPIO_FN(A10),
+ GPIO_FN(A11), GPIO_FN(A12), GPIO_FN(A13),
+ GPIO_FN(A14), GPIO_FN(A15), GPIO_FN(A16),
+ GPIO_FN(A17), GPIO_FN(A18), GPIO_FN(A19),
+ GPIO_FN(A20), GPIO_FN(A21), GPIO_FN(A22),
+ GPIO_FN(A23), GPIO_FN(A24), GPIO_FN(A25),
+ GPIO_FN(A26),
+
+ GPIO_FN(CS0), GPIO_FN(CS2), GPIO_FN(CS4),
+ GPIO_FN(CS5A), GPIO_FN(CS5B), GPIO_FN(CS6A),
+
+ /* BSC/FLCTL */
+ GPIO_FN(RD_FSC), GPIO_FN(WE0_FWE), GPIO_FN(A4_FOE),
+ GPIO_FN(A5_FCDE), GPIO_FN(D0_NAF0), GPIO_FN(D1_NAF1),
+ GPIO_FN(D2_NAF2), GPIO_FN(D3_NAF3), GPIO_FN(D4_NAF4),
+ GPIO_FN(D5_NAF5), GPIO_FN(D6_NAF6), GPIO_FN(D7_NAF7),
+ GPIO_FN(D8_NAF8), GPIO_FN(D9_NAF9), GPIO_FN(D10_NAF10),
+ GPIO_FN(D11_NAF11), GPIO_FN(D12_NAF12), GPIO_FN(D13_NAF13),
+ GPIO_FN(D14_NAF14), GPIO_FN(D15_NAF15),
+
+ /* MMCIF(1) */
+ GPIO_FN(MMCD0_0), GPIO_FN(MMCD0_1), GPIO_FN(MMCD0_2),
+ GPIO_FN(MMCD0_3), GPIO_FN(MMCD0_4), GPIO_FN(MMCD0_5),
+ GPIO_FN(MMCD0_6), GPIO_FN(MMCD0_7), GPIO_FN(MMCCMD0),
+ GPIO_FN(MMCCLK0),
+
+ /* MMCIF(2) */
+ GPIO_FN(MMCD1_0), GPIO_FN(MMCD1_1), GPIO_FN(MMCD1_2),
+ GPIO_FN(MMCD1_3), GPIO_FN(MMCD1_4), GPIO_FN(MMCD1_5),
+ GPIO_FN(MMCD1_6), GPIO_FN(MMCD1_7), GPIO_FN(MMCCLK1),
+ GPIO_FN(MMCCMD1),
+
+ /* SPU2 */
+ GPIO_FN(VINT_I),
+
+ /* FLCTL */
+ GPIO_FN(FCE1), GPIO_FN(FCE0), GPIO_FN(FRB),
+
+ /* HSI */
+ GPIO_FN(GP_RX_FLAG), GPIO_FN(GP_RX_DATA), GPIO_FN(GP_TX_READY),
+ GPIO_FN(GP_RX_WAKE), GPIO_FN(MP_TX_FLAG), GPIO_FN(MP_TX_DATA),
+ GPIO_FN(MP_RX_READY), GPIO_FN(MP_TX_WAKE),
+
+ /* MFI */
+ GPIO_FN(MFIv6),
+ GPIO_FN(MFIv4),
+
+ GPIO_FN(MEMC_BUSCLK_MEMC_A0), GPIO_FN(MEMC_ADV_MEMC_DREQ0),
+ GPIO_FN(MEMC_WAIT_MEMC_DREQ1), GPIO_FN(MEMC_CS1_MEMC_A1),
+ GPIO_FN(MEMC_CS0), GPIO_FN(MEMC_NOE),
+ GPIO_FN(MEMC_NWE), GPIO_FN(MEMC_INT),
+
+ GPIO_FN(MEMC_AD0), GPIO_FN(MEMC_AD1), GPIO_FN(MEMC_AD2),
+ GPIO_FN(MEMC_AD3), GPIO_FN(MEMC_AD4), GPIO_FN(MEMC_AD5),
+ GPIO_FN(MEMC_AD6), GPIO_FN(MEMC_AD7), GPIO_FN(MEMC_AD8),
+ GPIO_FN(MEMC_AD9), GPIO_FN(MEMC_AD10), GPIO_FN(MEMC_AD11),
+ GPIO_FN(MEMC_AD12), GPIO_FN(MEMC_AD13), GPIO_FN(MEMC_AD14),
+ GPIO_FN(MEMC_AD15),
+
+ /* SIM */
+ GPIO_FN(SIM_RST), GPIO_FN(SIM_CLK), GPIO_FN(SIM_D),
+
+ /* TPU */
+ GPIO_FN(TPU0TO0), GPIO_FN(TPU0TO1), GPIO_FN(TPU0TO2_93),
+ GPIO_FN(TPU0TO2_99), GPIO_FN(TPU0TO3),
+
+ /* I2C2 */
+ GPIO_FN(I2C_SCL2), GPIO_FN(I2C_SDA2),
+
+ /* I2C3(1) */
+ GPIO_FN(I2C_SCL3), GPIO_FN(I2C_SDA3),
+
+ /* I2C3(2) */
+ GPIO_FN(I2C_SCL3S), GPIO_FN(I2C_SDA3S),
+
+ /* I2C4(2) */
+ GPIO_FN(I2C_SCL4), GPIO_FN(I2C_SDA4),
+
+ /* I2C4(2) */
+ GPIO_FN(I2C_SCL4S), GPIO_FN(I2C_SDA4S),
+
+ /* KEYSC */
+ GPIO_FN(KEYOUT0), GPIO_FN(KEYIN0_121), GPIO_FN(KEYIN0_136),
+ GPIO_FN(KEYOUT1), GPIO_FN(KEYIN1_122), GPIO_FN(KEYIN1_135),
+ GPIO_FN(KEYOUT2), GPIO_FN(KEYIN2_123), GPIO_FN(KEYIN2_134),
+ GPIO_FN(KEYOUT3), GPIO_FN(KEYIN3_124), GPIO_FN(KEYIN3_133),
+ GPIO_FN(KEYOUT4), GPIO_FN(KEYIN4), GPIO_FN(KEYOUT5),
+ GPIO_FN(KEYIN5), GPIO_FN(KEYOUT6), GPIO_FN(KEYIN6),
+ GPIO_FN(KEYOUT7), GPIO_FN(KEYIN7),
+
+ /* LCDC */
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDVSYN),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(LCDRD),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(LCDLCLK),
+ GPIO_FN(LCDDON),
+
+ GPIO_FN(LCDD0), GPIO_FN(LCDD1), GPIO_FN(LCDD2),
+ GPIO_FN(LCDD3), GPIO_FN(LCDD4), GPIO_FN(LCDD5),
+ GPIO_FN(LCDD6), GPIO_FN(LCDD7), GPIO_FN(LCDD8),
+ GPIO_FN(LCDD9), GPIO_FN(LCDD10), GPIO_FN(LCDD11),
+ GPIO_FN(LCDD12), GPIO_FN(LCDD13), GPIO_FN(LCDD14),
+ GPIO_FN(LCDD15), GPIO_FN(LCDD16), GPIO_FN(LCDD17),
+ GPIO_FN(LCDD18), GPIO_FN(LCDD19), GPIO_FN(LCDD20),
+ GPIO_FN(LCDD21), GPIO_FN(LCDD22), GPIO_FN(LCDD23),
+
+ GPIO_FN(LCDC0_SELECT),
+ GPIO_FN(LCDC1_SELECT),
+
+ /* IRDA */
+ GPIO_FN(IRDA_OUT), GPIO_FN(IRDA_IN), GPIO_FN(IRDA_FIRSEL),
+ GPIO_FN(IROUT_139), GPIO_FN(IROUT_140),
+
+ /* TSIF1 */
+ GPIO_FN(TS0_1SELECT),
+ GPIO_FN(TS0_2SELECT),
+ GPIO_FN(TS1_1SELECT),
+ GPIO_FN(TS1_2SELECT),
+
+ GPIO_FN(TS_SPSYNC1), GPIO_FN(TS_SDAT1),
+ GPIO_FN(TS_SDEN1), GPIO_FN(TS_SCK1),
+
+ /* TSIF2 */
+ GPIO_FN(TS_SPSYNC2), GPIO_FN(TS_SDAT2),
+ GPIO_FN(TS_SDEN2), GPIO_FN(TS_SCK2),
+
+ /* HDMI */
+ GPIO_FN(HDMI_HPD), GPIO_FN(HDMI_CEC),
+
+ /* SDHI0 */
+ GPIO_FN(SDHICLK0), GPIO_FN(SDHICD0), GPIO_FN(SDHICMD0),
+ GPIO_FN(SDHIWP0), GPIO_FN(SDHID0_0), GPIO_FN(SDHID0_1),
+ GPIO_FN(SDHID0_2), GPIO_FN(SDHID0_3),
+
+ /* SDHI1 */
+ GPIO_FN(SDHICLK1), GPIO_FN(SDHICMD1), GPIO_FN(SDHID1_0),
+ GPIO_FN(SDHID1_1), GPIO_FN(SDHID1_2), GPIO_FN(SDHID1_3),
+
+ /* SDHI2 */
+ GPIO_FN(SDHICLK2), GPIO_FN(SDHICMD2), GPIO_FN(SDHID2_0),
+ GPIO_FN(SDHID2_1), GPIO_FN(SDHID2_2), GPIO_FN(SDHID2_3),
+
+ /* SDENC */
+ GPIO_FN(SDENC_CPG),
+ GPIO_FN(SDENC_DV_CLKI),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xE6051000), /* PORT0CR */
+ PORTCR(1, 0xE6051001), /* PORT1CR */
+ PORTCR(2, 0xE6051002), /* PORT2CR */
+ PORTCR(3, 0xE6051003), /* PORT3CR */
+ PORTCR(4, 0xE6051004), /* PORT4CR */
+ PORTCR(5, 0xE6051005), /* PORT5CR */
+ PORTCR(6, 0xE6051006), /* PORT6CR */
+ PORTCR(7, 0xE6051007), /* PORT7CR */
+ PORTCR(8, 0xE6051008), /* PORT8CR */
+ PORTCR(9, 0xE6051009), /* PORT9CR */
+ PORTCR(10, 0xE605100A), /* PORT10CR */
+ PORTCR(11, 0xE605100B), /* PORT11CR */
+ PORTCR(12, 0xE605100C), /* PORT12CR */
+ PORTCR(13, 0xE605100D), /* PORT13CR */
+ PORTCR(14, 0xE605100E), /* PORT14CR */
+ PORTCR(15, 0xE605100F), /* PORT15CR */
+ PORTCR(16, 0xE6051010), /* PORT16CR */
+ PORTCR(17, 0xE6051011), /* PORT17CR */
+ PORTCR(18, 0xE6051012), /* PORT18CR */
+ PORTCR(19, 0xE6051013), /* PORT19CR */
+ PORTCR(20, 0xE6051014), /* PORT20CR */
+ PORTCR(21, 0xE6051015), /* PORT21CR */
+ PORTCR(22, 0xE6051016), /* PORT22CR */
+ PORTCR(23, 0xE6051017), /* PORT23CR */
+ PORTCR(24, 0xE6051018), /* PORT24CR */
+ PORTCR(25, 0xE6051019), /* PORT25CR */
+ PORTCR(26, 0xE605101A), /* PORT26CR */
+ PORTCR(27, 0xE605101B), /* PORT27CR */
+ PORTCR(28, 0xE605101C), /* PORT28CR */
+ PORTCR(29, 0xE605101D), /* PORT29CR */
+ PORTCR(30, 0xE605101E), /* PORT30CR */
+ PORTCR(31, 0xE605101F), /* PORT31CR */
+ PORTCR(32, 0xE6051020), /* PORT32CR */
+ PORTCR(33, 0xE6051021), /* PORT33CR */
+ PORTCR(34, 0xE6051022), /* PORT34CR */
+ PORTCR(35, 0xE6051023), /* PORT35CR */
+ PORTCR(36, 0xE6051024), /* PORT36CR */
+ PORTCR(37, 0xE6051025), /* PORT37CR */
+ PORTCR(38, 0xE6051026), /* PORT38CR */
+ PORTCR(39, 0xE6051027), /* PORT39CR */
+ PORTCR(40, 0xE6051028), /* PORT40CR */
+ PORTCR(41, 0xE6051029), /* PORT41CR */
+ PORTCR(42, 0xE605102A), /* PORT42CR */
+ PORTCR(43, 0xE605102B), /* PORT43CR */
+ PORTCR(44, 0xE605102C), /* PORT44CR */
+ PORTCR(45, 0xE605102D), /* PORT45CR */
+ PORTCR(46, 0xE605202E), /* PORT46CR */
+ PORTCR(47, 0xE605202F), /* PORT47CR */
+ PORTCR(48, 0xE6052030), /* PORT48CR */
+ PORTCR(49, 0xE6052031), /* PORT49CR */
+ PORTCR(50, 0xE6052032), /* PORT50CR */
+ PORTCR(51, 0xE6052033), /* PORT51CR */
+ PORTCR(52, 0xE6052034), /* PORT52CR */
+ PORTCR(53, 0xE6052035), /* PORT53CR */
+ PORTCR(54, 0xE6052036), /* PORT54CR */
+ PORTCR(55, 0xE6052037), /* PORT55CR */
+ PORTCR(56, 0xE6052038), /* PORT56CR */
+ PORTCR(57, 0xE6052039), /* PORT57CR */
+ PORTCR(58, 0xE605203A), /* PORT58CR */
+ PORTCR(59, 0xE605203B), /* PORT59CR */
+ PORTCR(60, 0xE605203C), /* PORT60CR */
+ PORTCR(61, 0xE605203D), /* PORT61CR */
+ PORTCR(62, 0xE605203E), /* PORT62CR */
+ PORTCR(63, 0xE605203F), /* PORT63CR */
+ PORTCR(64, 0xE6052040), /* PORT64CR */
+ PORTCR(65, 0xE6052041), /* PORT65CR */
+ PORTCR(66, 0xE6052042), /* PORT66CR */
+ PORTCR(67, 0xE6052043), /* PORT67CR */
+ PORTCR(68, 0xE6052044), /* PORT68CR */
+ PORTCR(69, 0xE6052045), /* PORT69CR */
+ PORTCR(70, 0xE6052046), /* PORT70CR */
+ PORTCR(71, 0xE6052047), /* PORT71CR */
+ PORTCR(72, 0xE6052048), /* PORT72CR */
+ PORTCR(73, 0xE6052049), /* PORT73CR */
+ PORTCR(74, 0xE605204A), /* PORT74CR */
+ PORTCR(75, 0xE605204B), /* PORT75CR */
+ PORTCR(76, 0xE605004C), /* PORT76CR */
+ PORTCR(77, 0xE605004D), /* PORT77CR */
+ PORTCR(78, 0xE605004E), /* PORT78CR */
+ PORTCR(79, 0xE605004F), /* PORT79CR */
+ PORTCR(80, 0xE6050050), /* PORT80CR */
+ PORTCR(81, 0xE6050051), /* PORT81CR */
+ PORTCR(82, 0xE6050052), /* PORT82CR */
+ PORTCR(83, 0xE6050053), /* PORT83CR */
+ PORTCR(84, 0xE6050054), /* PORT84CR */
+ PORTCR(85, 0xE6050055), /* PORT85CR */
+ PORTCR(86, 0xE6050056), /* PORT86CR */
+ PORTCR(87, 0xE6050057), /* PORT87CR */
+ PORTCR(88, 0xE6050058), /* PORT88CR */
+ PORTCR(89, 0xE6050059), /* PORT89CR */
+ PORTCR(90, 0xE605005A), /* PORT90CR */
+ PORTCR(91, 0xE605005B), /* PORT91CR */
+ PORTCR(92, 0xE605005C), /* PORT92CR */
+ PORTCR(93, 0xE605005D), /* PORT93CR */
+ PORTCR(94, 0xE605005E), /* PORT94CR */
+ PORTCR(95, 0xE605005F), /* PORT95CR */
+ PORTCR(96, 0xE6050060), /* PORT96CR */
+ PORTCR(97, 0xE6050061), /* PORT97CR */
+ PORTCR(98, 0xE6050062), /* PORT98CR */
+ PORTCR(99, 0xE6050063), /* PORT99CR */
+ PORTCR(100, 0xE6053064), /* PORT100CR */
+ PORTCR(101, 0xE6053065), /* PORT101CR */
+ PORTCR(102, 0xE6053066), /* PORT102CR */
+ PORTCR(103, 0xE6053067), /* PORT103CR */
+ PORTCR(104, 0xE6053068), /* PORT104CR */
+ PORTCR(105, 0xE6053069), /* PORT105CR */
+ PORTCR(106, 0xE605306A), /* PORT106CR */
+ PORTCR(107, 0xE605306B), /* PORT107CR */
+ PORTCR(108, 0xE605306C), /* PORT108CR */
+ PORTCR(109, 0xE605306D), /* PORT109CR */
+ PORTCR(110, 0xE605306E), /* PORT110CR */
+ PORTCR(111, 0xE605306F), /* PORT111CR */
+ PORTCR(112, 0xE6053070), /* PORT112CR */
+ PORTCR(113, 0xE6053071), /* PORT113CR */
+ PORTCR(114, 0xE6053072), /* PORT114CR */
+ PORTCR(115, 0xE6053073), /* PORT115CR */
+ PORTCR(116, 0xE6053074), /* PORT116CR */
+ PORTCR(117, 0xE6053075), /* PORT117CR */
+ PORTCR(118, 0xE6053076), /* PORT118CR */
+ PORTCR(119, 0xE6053077), /* PORT119CR */
+ PORTCR(120, 0xE6053078), /* PORT120CR */
+ PORTCR(121, 0xE6050079), /* PORT121CR */
+ PORTCR(122, 0xE605007A), /* PORT122CR */
+ PORTCR(123, 0xE605007B), /* PORT123CR */
+ PORTCR(124, 0xE605007C), /* PORT124CR */
+ PORTCR(125, 0xE605007D), /* PORT125CR */
+ PORTCR(126, 0xE605007E), /* PORT126CR */
+ PORTCR(127, 0xE605007F), /* PORT127CR */
+ PORTCR(128, 0xE6050080), /* PORT128CR */
+ PORTCR(129, 0xE6050081), /* PORT129CR */
+ PORTCR(130, 0xE6050082), /* PORT130CR */
+ PORTCR(131, 0xE6050083), /* PORT131CR */
+ PORTCR(132, 0xE6050084), /* PORT132CR */
+ PORTCR(133, 0xE6050085), /* PORT133CR */
+ PORTCR(134, 0xE6050086), /* PORT134CR */
+ PORTCR(135, 0xE6050087), /* PORT135CR */
+ PORTCR(136, 0xE6050088), /* PORT136CR */
+ PORTCR(137, 0xE6050089), /* PORT137CR */
+ PORTCR(138, 0xE605008A), /* PORT138CR */
+ PORTCR(139, 0xE605008B), /* PORT139CR */
+ PORTCR(140, 0xE605008C), /* PORT140CR */
+ PORTCR(141, 0xE605008D), /* PORT141CR */
+ PORTCR(142, 0xE605008E), /* PORT142CR */
+ PORTCR(143, 0xE605008F), /* PORT143CR */
+ PORTCR(144, 0xE6050090), /* PORT144CR */
+ PORTCR(145, 0xE6050091), /* PORT145CR */
+ PORTCR(146, 0xE6050092), /* PORT146CR */
+ PORTCR(147, 0xE6050093), /* PORT147CR */
+ PORTCR(148, 0xE6050094), /* PORT148CR */
+ PORTCR(149, 0xE6050095), /* PORT149CR */
+ PORTCR(150, 0xE6050096), /* PORT150CR */
+ PORTCR(151, 0xE6050097), /* PORT151CR */
+ PORTCR(152, 0xE6053098), /* PORT152CR */
+ PORTCR(153, 0xE6053099), /* PORT153CR */
+ PORTCR(154, 0xE605309A), /* PORT154CR */
+ PORTCR(155, 0xE605309B), /* PORT155CR */
+ PORTCR(156, 0xE605009C), /* PORT156CR */
+ PORTCR(157, 0xE605009D), /* PORT157CR */
+ PORTCR(158, 0xE605009E), /* PORT158CR */
+ PORTCR(159, 0xE605009F), /* PORT159CR */
+ PORTCR(160, 0xE60500A0), /* PORT160CR */
+ PORTCR(161, 0xE60500A1), /* PORT161CR */
+ PORTCR(162, 0xE60500A2), /* PORT162CR */
+ PORTCR(163, 0xE60500A3), /* PORT163CR */
+ PORTCR(164, 0xE60500A4), /* PORT164CR */
+ PORTCR(165, 0xE60500A5), /* PORT165CR */
+ PORTCR(166, 0xE60500A6), /* PORT166CR */
+ PORTCR(167, 0xE60520A7), /* PORT167CR */
+ PORTCR(168, 0xE60520A8), /* PORT168CR */
+ PORTCR(169, 0xE60520A9), /* PORT169CR */
+ PORTCR(170, 0xE60520AA), /* PORT170CR */
+ PORTCR(171, 0xE60520AB), /* PORT171CR */
+ PORTCR(172, 0xE60520AC), /* PORT172CR */
+ PORTCR(173, 0xE60520AD), /* PORT173CR */
+ PORTCR(174, 0xE60520AE), /* PORT174CR */
+ PORTCR(175, 0xE60520AF), /* PORT175CR */
+ PORTCR(176, 0xE60520B0), /* PORT176CR */
+ PORTCR(177, 0xE60520B1), /* PORT177CR */
+ PORTCR(178, 0xE60520B2), /* PORT178CR */
+ PORTCR(179, 0xE60520B3), /* PORT179CR */
+ PORTCR(180, 0xE60520B4), /* PORT180CR */
+ PORTCR(181, 0xE60520B5), /* PORT181CR */
+ PORTCR(182, 0xE60520B6), /* PORT182CR */
+ PORTCR(183, 0xE60520B7), /* PORT183CR */
+ PORTCR(184, 0xE60520B8), /* PORT184CR */
+ PORTCR(185, 0xE60520B9), /* PORT185CR */
+ PORTCR(186, 0xE60520BA), /* PORT186CR */
+ PORTCR(187, 0xE60520BB), /* PORT187CR */
+ PORTCR(188, 0xE60520BC), /* PORT188CR */
+ PORTCR(189, 0xE60520BD), /* PORT189CR */
+ PORTCR(190, 0xE60520BE), /* PORT190CR */
+
+ { PINMUX_CFG_REG("MSEL1CR", 0xE605800C, 32, 1) {
+ MSEL1CR_31_0, MSEL1CR_31_1,
+ MSEL1CR_30_0, MSEL1CR_30_1,
+ MSEL1CR_29_0, MSEL1CR_29_1,
+ MSEL1CR_28_0, MSEL1CR_28_1,
+ MSEL1CR_27_0, MSEL1CR_27_1,
+ MSEL1CR_26_0, MSEL1CR_26_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ MSEL1CR_16_0, MSEL1CR_16_1,
+ MSEL1CR_15_0, MSEL1CR_15_1,
+ MSEL1CR_14_0, MSEL1CR_14_1,
+ MSEL1CR_13_0, MSEL1CR_13_1,
+ MSEL1CR_12_0, MSEL1CR_12_1,
+ 0, 0, 0, 0,
+ MSEL1CR_9_0, MSEL1CR_9_1,
+ MSEL1CR_8_0, MSEL1CR_8_1,
+ MSEL1CR_7_0, MSEL1CR_7_1,
+ MSEL1CR_6_0, MSEL1CR_6_1,
+ 0, 0,
+ MSEL1CR_4_0, MSEL1CR_4_1,
+ MSEL1CR_3_0, MSEL1CR_3_1,
+ MSEL1CR_2_0, MSEL1CR_2_1,
+ 0, 0,
+ MSEL1CR_0_0, MSEL1CR_0_1,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL3CR", 0xE6058020, 32, 1) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_27_0, MSEL3CR_27_1,
+ MSEL3CR_26_0, MSEL3CR_26_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_21_0, MSEL3CR_21_1,
+ MSEL3CR_20_0, MSEL3CR_20_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL3CR_15_0, MSEL3CR_15_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL3CR_9_0, MSEL3CR_9_1,
+ 0, 0, 0, 0,
+ MSEL3CR_6_0, MSEL3CR_6_1,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL4CR", 0xE6058024, 32, 1) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ MSEL4CR_19_0, MSEL4CR_19_1,
+ MSEL4CR_18_0, MSEL4CR_18_1,
+ MSEL4CR_17_0, MSEL4CR_17_1,
+ MSEL4CR_16_0, MSEL4CR_16_1,
+ MSEL4CR_15_0, MSEL4CR_15_1,
+ MSEL4CR_14_0, MSEL4CR_14_1,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL4CR_10_0, MSEL4CR_10_1,
+ 0, 0, 0, 0,
+ 0, 0,
+ MSEL4CR_6_0, MSEL4CR_6_1,
+ 0, 0,
+ MSEL4CR_4_0, MSEL4CR_4_1,
+ 0, 0, 0, 0,
+ MSEL4CR_1_0, MSEL4CR_1_1,
+ 0, 0,
+ }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xE6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL127_096DR", 0xE605400C, 32) {
+ PORT127_DATA, PORT126_DATA, PORT125_DATA, PORT124_DATA,
+ PORT123_DATA, PORT122_DATA, PORT121_DATA, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL159_128DR", 0xE6054010, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ 0, 0, 0, 0,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTL191_160DR", 0xE6054014, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT166_DATA, PORT165_DATA, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTD031_000DR", 0xE6055000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTD063_032DR", 0xE6055004, 32) {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR063_032DR", 0xE6056004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR095_064DR", 0xE6056008, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA,
+ }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xE6056014, 32) {
+ 0, PORT190_DATA, PORT189_DATA, PORT188_DATA,
+ PORT187_DATA, PORT186_DATA, PORT185_DATA, PORT184_DATA,
+ PORT183_DATA, PORT182_DATA, PORT181_DATA, PORT180_DATA,
+ PORT179_DATA, PORT178_DATA, PORT177_DATA, PORT176_DATA,
+ PORT175_DATA, PORT174_DATA, PORT173_DATA, PORT172_DATA,
+ PORT171_DATA, PORT170_DATA, PORT169_DATA, PORT168_DATA,
+ PORT167_DATA, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTU127_096DR", 0xE605700C, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT120_DATA,
+ PORT119_DATA, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ 0, 0, 0, 0,
+ }
+ },
+ { PINMUX_DATA_REG("PORTU159_128DR", 0xE6057010, 32) {
+ 0, 0, 0, 0,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+ },
+ { },
+};
+
+static struct pinmux_info sh7372_pinmux_info = {
+ .name = "sh7372_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_SDENC_DV_CLKI,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7372_pinmux_init(void)
+{
+ register_pinmux(&sh7372_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh7377.c b/arch/arm/mach-shmobile/pfc-sh7377.c
new file mode 100644
index 00000000..613e6842
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh7377.c
@@ -0,0 +1,1767 @@
+/*
+ * sh7377 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 NISHIMOTO Hiroki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh7377.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _90(fn, pfx, sfx) \
+ _10(fn, pfx##1, sfx), _10(fn, pfx##2, sfx), \
+ _10(fn, pfx##3, sfx), _10(fn, pfx##4, sfx), \
+ _10(fn, pfx##5, sfx), _10(fn, pfx##6, sfx), \
+ _10(fn, pfx##7, sfx), _10(fn, pfx##8, sfx), \
+ _10(fn, pfx##9, sfx)
+
+#define _265(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _90(fn, pfx, sfx), \
+ _10(fn, pfx##10, sfx), \
+ _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx), \
+ _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx), \
+ _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx), \
+ _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx), \
+ _1(fn, pfx##118, sfx), \
+ _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx), \
+ _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx), \
+ _10(fn, pfx##15, sfx), \
+ _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx), \
+ _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx), \
+ _1(fn, pfx##164, sfx), \
+ _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx), \
+ _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx), \
+ _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx), \
+ _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx), \
+ _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
+ _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
+ _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
+ _1(fn, pfx##260, sfx), _1(fn, pfx##261, sfx), \
+ _1(fn, pfx##262, sfx), _1(fn, pfx##263, sfx), \
+ _1(fn, pfx##264, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_265(str) _265(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_265(DATA), /* PORT0_DATA -> PORT264_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_265(IN), /* PORT0_IN -> PORT264_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_265(IN_PU), /* PORT0_IN_PU -> PORT264_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_265(IN_PD), /* PORT0_IN_PD -> PORT264_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_265(OUT), /* PORT0_OUT -> PORT264_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_265(FN_IN), /* PORT0_FN_IN -> PORT264_FN_IN */
+ PORT_265(FN_OUT), /* PORT0_FN_OUT -> PORT264_FN_OUT */
+ PORT_265(FN0), /* PORT0_FN0 -> PORT264_FN0 */
+ PORT_265(FN1), /* PORT0_FN1 -> PORT264_FN1 */
+ PORT_265(FN2), /* PORT0_FN2 -> PORT264_FN2 */
+ PORT_265(FN3), /* PORT0_FN3 -> PORT264_FN3 */
+ PORT_265(FN4), /* PORT0_FN4 -> PORT264_FN4 */
+ PORT_265(FN5), /* PORT0_FN5 -> PORT264_FN5 */
+ PORT_265(FN6), /* PORT0_FN6 -> PORT264_FN6 */
+ PORT_265(FN7), /* PORT0_FN7 -> PORT264_FN7 */
+
+ MSELBCR_MSEL17_1, MSELBCR_MSEL17_0,
+ MSELBCR_MSEL16_1, MSELBCR_MSEL16_0,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Special Pull-up / Pull-down Functions */
+ PORT66_KEYIN0_PU_MARK, PORT67_KEYIN1_PU_MARK,
+ PORT68_KEYIN2_PU_MARK, PORT69_KEYIN3_PU_MARK,
+ PORT70_KEYIN4_PU_MARK, PORT71_KEYIN5_PU_MARK,
+ PORT72_KEYIN6_PU_MARK,
+
+ /* 55-1 */
+ VBUS_0_MARK,
+ CPORT0_MARK,
+ CPORT1_MARK,
+ CPORT2_MARK,
+ CPORT3_MARK,
+ CPORT4_MARK,
+ CPORT5_MARK,
+ CPORT6_MARK,
+ CPORT7_MARK,
+ CPORT8_MARK,
+ CPORT9_MARK,
+ CPORT10_MARK,
+ CPORT11_MARK, SIN2_MARK,
+ CPORT12_MARK, XCTS2_MARK,
+ CPORT13_MARK, RFSPO4_MARK,
+ CPORT14_MARK, RFSPO5_MARK,
+ CPORT15_MARK, SCIFA0_SCK_MARK, GPS_AGC2_MARK,
+ CPORT16_MARK, SCIFA0_TXD_MARK, GPS_AGC3_MARK,
+ CPORT17_IC_OE_MARK, SOUT2_MARK,
+ CPORT18_MARK, XRTS2_MARK, PORT19_VIO_CKO2_MARK,
+ CPORT19_MPORT1_MARK,
+ CPORT20_MARK, RFSPO6_MARK,
+ CPORT21_MARK, STATUS0_MARK,
+ CPORT22_MARK, STATUS1_MARK,
+ CPORT23_MARK, STATUS2_MARK, RFSPO7_MARK,
+ B_SYNLD1_MARK,
+ B_SYNLD2_MARK, SYSENMSK_MARK,
+ XMAINPS_MARK,
+ XDIVPS_MARK,
+ XIDRST_MARK,
+ IDCLK_MARK, IC_DP_MARK,
+ IDIO_MARK, IC_DM_MARK,
+ SOUT1_MARK, SCIFA4_TXD_MARK, M02_BERDAT_MARK,
+ SIN1_MARK, SCIFA4_RXD_MARK, XWUP_MARK,
+ XRTS1_MARK, SCIFA4_RTS_MARK, M03_BERCLK_MARK,
+ XCTS1_MARK, SCIFA4_CTS_MARK,
+ PCMCLKO_MARK,
+ SYNC8KO_MARK,
+
+ /* 55-2 */
+ DNPCM_A_MARK,
+ UPPCM_A_MARK,
+ VACK_MARK,
+ XTALB1L_MARK,
+ GPS_AGC1_MARK, SCIFA0_RTS_MARK,
+ GPS_AGC4_MARK, SCIFA0_RXD_MARK,
+ GPS_PWRDOWN_MARK, SCIFA0_CTS_MARK,
+ GPS_IM_MARK,
+ GPS_IS_MARK,
+ GPS_QM_MARK,
+ GPS_QS_MARK,
+ FMSOCK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK,
+ FMSOOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, IPORT3_MARK,
+ FMSIOLR_MARK,
+ FMSOOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, OPORT1_MARK,
+ FMSIOBT_MARK,
+ FMSOSLD_MARK, BBIF2_TXD2_MARK, OPORT2_MARK,
+ FMSOILR_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, OPORT3_MARK,
+ FMSIILR_MARK,
+ FMSOIBT_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FMSIIBT_MARK,
+ FMSISLD_MARK, MFG0_OUT1_MARK, TPU0TO0_MARK,
+ A0_EA0_MARK, BS_MARK,
+ A12_EA12_MARK, PORT58_VIO_CKOR_MARK, TPU4TO2_MARK,
+ A13_EA13_MARK, PORT59_IROUT_MARK, MFG0_OUT2_MARK, TPU0TO1_MARK,
+ A14_EA14_MARK, PORT60_KEYOUT5_MARK,
+ A15_EA15_MARK, PORT61_KEYOUT4_MARK,
+ A16_EA16_MARK, PORT62_KEYOUT3_MARK, MSIOF0_SS1_MARK,
+ A17_EA17_MARK, PORT63_KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
+ A18_EA18_MARK, PORT64_KEYOUT1_MARK, MSIOF0_TSCK_MARK,
+ A19_EA19_MARK, PORT65_KEYOUT0_MARK, MSIOF0_TXD_MARK,
+ A20_EA20_MARK, PORT66_KEYIN0_MARK, MSIOF0_RSCK_MARK,
+ A21_EA21_MARK, PORT67_KEYIN1_MARK, MSIOF0_RSYNC_MARK,
+ A22_EA22_MARK, PORT68_KEYIN2_MARK, MSIOF0_MCK0_MARK,
+ A23_EA23_MARK, PORT69_KEYIN3_MARK, MSIOF0_MCK1_MARK,
+ A24_EA24_MARK, PORT70_KEYIN4_MARK, MSIOF0_RXD_MARK,
+ A25_EA25_MARK, PORT71_KEYIN5_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, PORT72_KEYIN6_MARK,
+ D0_ED0_NAF0_MARK,
+ D1_ED1_NAF1_MARK,
+ D2_ED2_NAF2_MARK,
+ D3_ED3_NAF3_MARK,
+ D4_ED4_NAF4_MARK,
+ D5_ED5_NAF5_MARK,
+ D6_ED6_NAF6_MARK,
+ D7_ED7_NAF7_MARK,
+ D8_ED8_NAF8_MARK,
+ D9_ED9_NAF9_MARK,
+ D10_ED10_NAF10_MARK,
+ D11_ED11_NAF11_MARK,
+ D12_ED12_NAF12_MARK,
+ D13_ED13_NAF13_MARK,
+ D14_ED14_NAF14_MARK,
+ D15_ED15_NAF15_MARK,
+ CS4_MARK,
+ CS5A_MARK, FMSICK_MARK,
+ CS5B_MARK, FCE1_MARK,
+
+ /* 55-3 */
+ CS6B_MARK, XCS2_MARK, CS6A_MARK, DACK0_MARK,
+ FCE0_MARK,
+ WAIT_MARK, DREQ0_MARK,
+ RD_XRD_MARK,
+ WE0_XWR0_FWE_MARK,
+ WE1_XWR1_MARK,
+ FRB_MARK,
+ CKO_MARK,
+ NBRSTOUT_MARK,
+ NBRST_MARK,
+ GPS_EPPSIN_MARK,
+ LATCHPULSE_MARK,
+ LTESIGNAL_MARK,
+ LEGACYSTATE_MARK,
+ TCKON_MARK,
+ VIO_VD_MARK, PORT128_KEYOUT0_MARK, IPORT0_MARK,
+ VIO_HD_MARK, PORT129_KEYOUT1_MARK, IPORT1_MARK,
+ VIO_D0_MARK, PORT130_KEYOUT2_MARK, PORT130_MSIOF2_RXD_MARK,
+ VIO_D1_MARK, PORT131_KEYOUT3_MARK, PORT131_MSIOF2_SS1_MARK,
+ VIO_D2_MARK, PORT132_KEYOUT4_MARK, PORT132_MSIOF2_SS2_MARK,
+ VIO_D3_MARK, PORT133_KEYOUT5_MARK, PORT133_MSIOF2_TSYNC_MARK,
+ VIO_D4_MARK, PORT134_KEYIN0_MARK, PORT134_MSIOF2_TXD_MARK,
+ VIO_D5_MARK, PORT135_KEYIN1_MARK, PORT135_MSIOF2_TSCK_MARK,
+ VIO_D6_MARK, PORT136_KEYIN2_MARK,
+ VIO_D7_MARK, PORT137_KEYIN3_MARK,
+ VIO_D8_MARK, M9_SLCD_A01_MARK, PORT138_FSIAOMC_MARK,
+ VIO_D9_MARK, M10_SLCD_CK1_MARK, PORT139_FSIAOLR_MARK,
+ VIO_D10_MARK, M11_SLCD_SO1_MARK, TPU0TO2_MARK, PORT140_FSIAOBT_MARK,
+ VIO_D11_MARK, M12_SLCD_CE1_MARK, TPU0TO3_MARK, PORT141_FSIAOSLD_MARK,
+ VIO_D12_MARK, M13_BSW_MARK, PORT142_FSIACK_MARK,
+ VIO_D13_MARK, M14_GSW_MARK, PORT143_FSIAILR_MARK,
+ VIO_D14_MARK, M15_RSW_MARK, PORT144_FSIAIBT_MARK,
+ VIO_D15_MARK, TPU1TO3_MARK, PORT145_FSIAISLD_MARK,
+ VIO_CLK_MARK, PORT146_KEYIN4_MARK, IPORT2_MARK,
+ VIO_FIELD_MARK, PORT147_KEYIN5_MARK,
+ VIO_CKO_MARK, PORT148_KEYIN6_MARK,
+ A27_MARK, RDWR_XWE_MARK, MFG0_IN1_MARK,
+ MFG0_IN2_MARK,
+ TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK,
+ TS_SDAT3_MARK, MSIOF2_RSYNC_MARK,
+ TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK,
+ SOUT3_MARK, SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
+ SIN3_MARK, SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
+ XRTS3_MARK, SCIFA2_RTS1_MARK, PORT156_MSIOF2_SS2_MARK,
+ XCTS3_MARK, SCIFA2_CTS1_MARK, PORT157_MSIOF2_RXD_MARK,
+
+ /* 55-4 */
+ DINT_MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+ PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK,
+ PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK, SOUT0_MARK,
+ PORT161_SCIFB_CTS_MARK, PORT161_SCIFA5_CTS_MARK, XCTS0_MARK,
+ MFG3_IN2_MARK,
+ PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK, SIN0_MARK,
+ MFG3_IN1_MARK,
+ PORT163_SCIFB_RTS_MARK, PORT163_SCIFA5_RTS_MARK, XRTS0_MARK,
+ MFG3_OUT1_MARK, TPU3TO0_MARK,
+ LCDD0_MARK, PORT192_KEYOUT0_MARK, EXT_CKI_MARK,
+ LCDD1_MARK, PORT193_KEYOUT1_MARK, PORT193_SCIFA5_CTS_MARK,
+ BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT194_KEYOUT2_MARK, PORT194_SCIFA5_RTS_MARK,
+ BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT195_KEYOUT3_MARK, PORT195_SCIFA5_RXD_MARK,
+ BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT196_KEYOUT4_MARK, PORT196_SCIFA5_TXD_MARK,
+ LCDD5_MARK, PORT197_KEYOUT5_MARK, PORT197_SCIFA5_SCK_MARK,
+ MFG2_OUT2_MARK,
+ TPU2TO1_MARK,
+ LCDD6_MARK, XWR2_MARK,
+ LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK, XWR3_MARK,
+ LCDD8_MARK, PORT200_KEYIN0_MARK, VIO_DR0_MARK, D16_MARK, ED16_MARK,
+ LCDD9_MARK, PORT201_KEYIN1_MARK, VIO_DR1_MARK, D17_MARK, ED17_MARK,
+ LCDD10_MARK, PORT202_KEYIN2_MARK, VIO_DR2_MARK, D18_MARK, ED18_MARK,
+ LCDD11_MARK, PORT203_KEYIN3_MARK, VIO_DR3_MARK, D19_MARK, ED19_MARK,
+ LCDD12_MARK, PORT204_KEYIN4_MARK, VIO_DR4_MARK, D20_MARK, ED20_MARK,
+ LCDD13_MARK, PORT205_KEYIN5_MARK, VIO_DR5_MARK, D21_MARK, ED21_MARK,
+ LCDD14_MARK, PORT206_KEYIN6_MARK, VIO_DR6_MARK, D22_MARK, ED22_MARK,
+ LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, PORT207_KEYOUT0_MARK,
+ VIO_DR7_MARK, D23_MARK, ED23_MARK,
+ LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, PORT208_KEYOUT1_MARK,
+ VIO_VDR_MARK, D24_MARK, ED24_MARK,
+ LCDD17_MARK, PORT209_KEYOUT2_MARK, VIO_HDR_MARK, D25_MARK, ED25_MARK,
+ LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK, ED26_MARK,
+ LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK, ED27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK, ED28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK, ED29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK, ED30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK, ED31_MARK,
+ LCDDCK_MARK, LCDWR_MARK, PORT216_KEYOUT3_MARK, VIO_CLKR_MARK,
+ LCDRD_MARK, DACK2_MARK, MSIOF0L_TSYNC_MARK,
+ LCDHSYN_MARK, LCDCS_MARK, LCDCS2_MARK, DACK3_MARK,
+ PORT218_VIO_CKOR_MARK, PORT218_KEYOUT4_MARK,
+ LCDDISP_MARK, LCDRS_MARK, DREQ3_MARK, MSIOF0L_TSCK_MARK,
+ LCDVSYN_MARK, LCDVSYN2_MARK, PORT220_KEYOUT5_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, PWEN_MARK, MSIOF0L_RXD_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK,
+ SCIFA1_TXD_MARK, OVCN2_MARK,
+ EXTLP_MARK, SCIFA1_SCK_MARK, USBTERM_MARK, PORT226_VIO_CKO2_MARK,
+ SCIFA1_RTS_MARK, IDIN_MARK,
+ SCIFA1_RXD_MARK,
+ SCIFA1_CTS_MARK, MFG1_IN1_MARK,
+ MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK, PORT230_FSIAOMC_MARK,
+ MSIOF1_TSYNC_MARK, SCIFA2_CTS2_MARK, PORT231_FSIAOLR_MARK,
+ MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK, PORT232_FSIAOBT_MARK,
+ MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK, GPS_VCOTRIG_MARK,
+ PORT233_FSIACK_MARK,
+ MSIOF1_RSCK_MARK, SCIFA2_RTS2_MARK, PORT234_FSIAOSLD_MARK,
+ MSIOF1_RSYNC_MARK, OPORT0_MARK, MFG1_IN2_MARK, PORT235_FSIAILR_MARK,
+ MSIOF1_MCK0_MARK, I2C_SDA2_MARK, PORT236_FSIAIBT_MARK,
+ MSIOF1_MCK1_MARK, I2C_SCL2_MARK, PORT237_FSIAISLD_MARK,
+ MSIOF1_SS1_MARK, EDBGREQ3_MARK,
+
+ /* 55-5 */
+ MSIOF1_SS2_MARK,
+ SCIFA6_TXD_MARK,
+ PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK,
+ TPU4TO0_MARK,
+ PORT242_IRDA_IN_MARK, MFG4_IN2_MARK,
+ PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK,
+ PORT244_SCIFA5_CTS_MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS_MARK,
+ PORT244_MSIOF2_RXD_MARK,
+ PORT245_SCIFA5_RTS_MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS_MARK,
+ PORT245_MSIOF2_TXD_MARK,
+ PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK,
+ TPU1TO0_MARK,
+ PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK,
+ TPU3TO1_MARK,
+ PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK,
+ TPU2TO0_MARK,
+ PORT248_MSIOF2_TSCK_MARK,
+ PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_MSIOF2_TSYNC_MARK,
+ SDHICLK0_MARK, TCK2_SWCLK_MC0_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK, TMS2_SWDIO_MC0_MARK,
+ SDHID0_1_MARK, TDO2_SWO0_MC0_MARK,
+ SDHID0_2_MARK, TDI2_MARK,
+ SDHID0_3_MARK, RTCK2_SWO1_MC0_MARK,
+ SDHICMD0_MARK, TRST2_MARK,
+ SDHIWP0_MARK, EDBGREQ2_MARK,
+ SDHICLK1_MARK, TCK3_SWCLK_MC1_MARK,
+ SDHID1_0_MARK, M11_SLCD_SO2_MARK, TS_SPSYNC2_MARK,
+ TMS3_SWDIO_MC1_MARK,
+ SDHID1_1_MARK, M9_SLCD_A02_MARK, TS_SDAT2_MARK, TDO3_SWO0_MC1_MARK,
+ SDHID1_2_MARK, M10_SLCD_CK2_MARK, TS_SDEN2_MARK, TDI3_MARK,
+ SDHID1_3_MARK, M12_SLCD_CE2_MARK, TS_SCK2_MARK, RTCK3_SWO1_MC1_MARK,
+ SDHICMD1_MARK, TRST3_MARK,
+ RESETOUTS_MARK,
+ PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+static pinmux_enum_t pinmux_data[] = {
+ /* specify valid pin states for each pin in GPIO mode */
+ /* 55-1 (GPIO) */
+ PORT_DATA_I_PD(0), PORT_DATA_I_PU(1),
+ PORT_DATA_I_PU(2), PORT_DATA_I_PU(3),
+ PORT_DATA_I_PU(4), PORT_DATA_I_PU(5),
+ PORT_DATA_I_PU(6), PORT_DATA_I_PU(7),
+ PORT_DATA_I_PU(8), PORT_DATA_I_PU(9),
+ PORT_DATA_I_PU(10), PORT_DATA_I_PU(11),
+ PORT_DATA_IO_PU(12), PORT_DATA_IO_PU(13),
+ PORT_DATA_IO_PU_PD(14), PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_O(16), PORT_DATA_IO(17),
+ PORT_DATA_O(18), PORT_DATA_O(19),
+ PORT_DATA_O(20), PORT_DATA_O(21),
+ PORT_DATA_O(22), PORT_DATA_O(23),
+ PORT_DATA_O(24), PORT_DATA_I_PD(25),
+ PORT_DATA_I_PD(26), PORT_DATA_O(27),
+ PORT_DATA_O(28), PORT_DATA_O(29),
+ PORT_DATA_IO(30), PORT_DATA_IO_PU(31),
+ PORT_DATA_IO_PD(32), PORT_DATA_I_PU(33),
+ PORT_DATA_IO_PD(34), PORT_DATA_I_PU_PD(35),
+ PORT_DATA_O(36), PORT_DATA_IO(37),
+
+ /* 55-2 (GPIO) */
+ PORT_DATA_O(38), PORT_DATA_I_PU(39),
+ PORT_DATA_I_PU_PD(40), PORT_DATA_O(41),
+ PORT_DATA_IO_PD(42), PORT_DATA_IO_PD(43),
+ PORT_DATA_IO_PD(44), PORT_DATA_I_PD(45),
+ PORT_DATA_I_PD(46), PORT_DATA_I_PD(47),
+ PORT_DATA_I_PD(48), PORT_DATA_IO_PU_PD(49),
+ PORT_DATA_IO_PD(50), PORT_DATA_IO_PD(51),
+ PORT_DATA_O(52), PORT_DATA_IO_PU_PD(53),
+ PORT_DATA_IO_PU_PD(54), PORT_DATA_IO_PD(55),
+ PORT_DATA_I_PU_PD(56), PORT_DATA_IO(57),
+ PORT_DATA_IO(58), PORT_DATA_IO(59),
+ PORT_DATA_IO(60), PORT_DATA_IO(61),
+ PORT_DATA_IO_PD(62), PORT_DATA_IO_PD(63),
+ PORT_DATA_IO_PD(64), PORT_DATA_IO_PD(65),
+ PORT_DATA_IO_PU_PD(66), PORT_DATA_IO_PU_PD(67),
+ PORT_DATA_IO_PU_PD(68), PORT_DATA_IO_PU_PD(69),
+ PORT_DATA_IO_PU_PD(70), PORT_DATA_IO_PU_PD(71),
+ PORT_DATA_IO_PU_PD(72), PORT_DATA_I_PU_PD(73),
+ PORT_DATA_IO_PU(74), PORT_DATA_IO_PU(75),
+ PORT_DATA_IO_PU(76), PORT_DATA_IO_PU(77),
+ PORT_DATA_IO_PU(78), PORT_DATA_IO_PU(79),
+ PORT_DATA_IO_PU(80), PORT_DATA_IO_PU(81),
+ PORT_DATA_IO_PU(82), PORT_DATA_IO_PU(83),
+ PORT_DATA_IO_PU(84), PORT_DATA_IO_PU(85),
+ PORT_DATA_IO_PU(86), PORT_DATA_IO_PU(87),
+ PORT_DATA_IO_PU(88), PORT_DATA_IO_PU(89),
+ PORT_DATA_O(90), PORT_DATA_IO_PU(91),
+ PORT_DATA_O(92),
+
+ /* 55-3 (GPIO) */
+ PORT_DATA_IO_PU(93),
+ PORT_DATA_O(94),
+ PORT_DATA_I_PU_PD(95),
+ PORT_DATA_IO(96), PORT_DATA_IO(97),
+ PORT_DATA_IO(98), PORT_DATA_I_PU(99),
+ PORT_DATA_O(100), PORT_DATA_O(101),
+ PORT_DATA_I_PU(102), PORT_DATA_IO_PD(103),
+ PORT_DATA_I_PD(104), PORT_DATA_I_PD(105),
+ PORT_DATA_I_PD(106), PORT_DATA_I_PD(107),
+ PORT_DATA_I_PD(108), PORT_DATA_IO_PD(109),
+ PORT_DATA_IO_PD(110), PORT_DATA_I_PD(111),
+ PORT_DATA_IO_PD(112), PORT_DATA_IO_PD(113),
+ PORT_DATA_IO_PD(114), PORT_DATA_I_PD(115),
+ PORT_DATA_I_PD(116), PORT_DATA_IO_PD(117),
+ PORT_DATA_I_PD(118), PORT_DATA_IO_PD(128),
+ PORT_DATA_IO_PD(129), PORT_DATA_IO_PD(130),
+ PORT_DATA_IO_PD(131), PORT_DATA_IO_PD(132),
+ PORT_DATA_IO_PD(133), PORT_DATA_IO_PU_PD(134),
+ PORT_DATA_IO_PU_PD(135), PORT_DATA_IO_PU_PD(136),
+ PORT_DATA_IO_PU_PD(137), PORT_DATA_IO_PD(138),
+ PORT_DATA_IO_PD(139), PORT_DATA_IO_PD(140),
+ PORT_DATA_IO_PD(141), PORT_DATA_IO_PD(142),
+ PORT_DATA_IO_PD(143), PORT_DATA_IO_PU_PD(144),
+ PORT_DATA_IO_PD(145), PORT_DATA_IO_PU_PD(146),
+ PORT_DATA_IO_PU_PD(147), PORT_DATA_IO_PU_PD(148),
+ PORT_DATA_IO_PU_PD(149), PORT_DATA_I_PD(150),
+ PORT_DATA_IO_PU_PD(151), PORT_DATA_IO_PD(152),
+ PORT_DATA_IO_PD(153), PORT_DATA_IO_PD(154),
+ PORT_DATA_I_PD(155), PORT_DATA_IO_PU_PD(156),
+ PORT_DATA_I_PD(157), PORT_DATA_IO_PD(158),
+
+ /* 55-4 (GPIO) */
+ PORT_DATA_IO_PU_PD(159), PORT_DATA_IO_PU_PD(160),
+ PORT_DATA_I_PU_PD(161), PORT_DATA_I_PU_PD(162),
+ PORT_DATA_IO_PU_PD(163), PORT_DATA_I_PU_PD(164),
+ PORT_DATA_IO_PD(192), PORT_DATA_IO_PD(193),
+ PORT_DATA_IO_PD(194), PORT_DATA_IO_PD(195),
+ PORT_DATA_IO_PD(196), PORT_DATA_IO_PD(197),
+ PORT_DATA_IO_PD(198), PORT_DATA_IO_PD(199),
+ PORT_DATA_IO_PU_PD(200), PORT_DATA_IO_PU_PD(201),
+ PORT_DATA_IO_PU_PD(202), PORT_DATA_IO_PU_PD(203),
+ PORT_DATA_IO_PU_PD(204), PORT_DATA_IO_PU_PD(205),
+ PORT_DATA_IO_PU_PD(206), PORT_DATA_IO_PD(207),
+ PORT_DATA_IO_PD(208), PORT_DATA_IO_PD(209),
+ PORT_DATA_IO_PD(210), PORT_DATA_IO_PD(211),
+ PORT_DATA_IO_PD(212), PORT_DATA_IO_PD(213),
+ PORT_DATA_IO_PD(214), PORT_DATA_IO_PD(215),
+ PORT_DATA_IO_PD(216), PORT_DATA_IO_PD(217),
+ PORT_DATA_O(218), PORT_DATA_IO_PD(219),
+ PORT_DATA_IO_PD(220), PORT_DATA_IO_PD(221),
+ PORT_DATA_IO_PU_PD(222),
+ PORT_DATA_I_PU_PD(223), PORT_DATA_I_PU_PD(224),
+ PORT_DATA_IO_PU_PD(225), PORT_DATA_O(226),
+ PORT_DATA_IO_PU_PD(227), PORT_DATA_I_PD(228),
+ PORT_DATA_I_PD(229), PORT_DATA_IO(230),
+ PORT_DATA_IO_PD(231), PORT_DATA_IO_PU_PD(232),
+ PORT_DATA_I_PD(233), PORT_DATA_IO_PU_PD(234),
+ PORT_DATA_IO_PU_PD(235), PORT_DATA_IO_PU_PD(236),
+ PORT_DATA_IO_PD(237), PORT_DATA_IO_PU_PD(238),
+
+ /* 55-5 (GPIO) */
+ PORT_DATA_IO_PU_PD(239), PORT_DATA_IO_PU_PD(240),
+ PORT_DATA_O(241), PORT_DATA_I_PD(242),
+ PORT_DATA_IO_PU_PD(243), PORT_DATA_IO_PU_PD(244),
+ PORT_DATA_IO_PU_PD(245), PORT_DATA_IO_PU_PD(246),
+ PORT_DATA_IO_PU_PD(247), PORT_DATA_IO_PU_PD(248),
+ PORT_DATA_IO_PU_PD(249), PORT_DATA_IO_PD(250),
+ PORT_DATA_IO_PU_PD(251), PORT_DATA_IO_PU_PD(252),
+ PORT_DATA_IO_PU_PD(253), PORT_DATA_IO_PU_PD(254),
+ PORT_DATA_IO_PU_PD(255), PORT_DATA_IO_PU_PD(256),
+ PORT_DATA_IO_PU_PD(257), PORT_DATA_IO_PD(258),
+ PORT_DATA_IO_PU_PD(259), PORT_DATA_IO_PU_PD(260),
+ PORT_DATA_IO_PU_PD(261), PORT_DATA_IO_PU_PD(262),
+ PORT_DATA_IO_PU_PD(263),
+
+ /* Special Pull-up / Pull-down Functions */
+ PINMUX_DATA(PORT66_KEYIN0_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT66_FN2, PORT66_IN_PU),
+ PINMUX_DATA(PORT67_KEYIN1_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT67_FN2, PORT67_IN_PU),
+ PINMUX_DATA(PORT68_KEYIN2_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT68_FN2, PORT68_IN_PU),
+ PINMUX_DATA(PORT69_KEYIN3_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT69_FN2, PORT69_IN_PU),
+ PINMUX_DATA(PORT70_KEYIN4_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT70_FN2, PORT70_IN_PU),
+ PINMUX_DATA(PORT71_KEYIN5_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT71_FN2, PORT71_IN_PU),
+ PINMUX_DATA(PORT72_KEYIN6_PU_MARK, MSELBCR_MSEL17_0, MSELBCR_MSEL16_0,
+ PORT72_FN2, PORT72_IN_PU),
+
+
+ /* 55-1 (FN) */
+ PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
+ PINMUX_DATA(CPORT0_MARK, PORT1_FN1),
+ PINMUX_DATA(CPORT1_MARK, PORT2_FN1),
+ PINMUX_DATA(CPORT2_MARK, PORT3_FN1),
+ PINMUX_DATA(CPORT3_MARK, PORT4_FN1),
+ PINMUX_DATA(CPORT4_MARK, PORT5_FN1),
+ PINMUX_DATA(CPORT5_MARK, PORT6_FN1),
+ PINMUX_DATA(CPORT6_MARK, PORT7_FN1),
+ PINMUX_DATA(CPORT7_MARK, PORT8_FN1),
+ PINMUX_DATA(CPORT8_MARK, PORT9_FN1),
+ PINMUX_DATA(CPORT9_MARK, PORT10_FN1),
+ PINMUX_DATA(CPORT10_MARK, PORT11_FN1),
+ PINMUX_DATA(CPORT11_MARK, PORT12_FN1),
+ PINMUX_DATA(SIN2_MARK, PORT12_FN2),
+ PINMUX_DATA(CPORT12_MARK, PORT13_FN1),
+ PINMUX_DATA(XCTS2_MARK, PORT13_FN2),
+ PINMUX_DATA(CPORT13_MARK, PORT14_FN1),
+ PINMUX_DATA(RFSPO4_MARK, PORT14_FN2),
+ PINMUX_DATA(CPORT14_MARK, PORT15_FN1),
+ PINMUX_DATA(RFSPO5_MARK, PORT15_FN2),
+ PINMUX_DATA(CPORT15_MARK, PORT16_FN1),
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2),
+ PINMUX_DATA(GPS_AGC2_MARK, PORT16_FN3),
+ PINMUX_DATA(CPORT16_MARK, PORT17_FN1),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
+ PINMUX_DATA(GPS_AGC3_MARK, PORT17_FN3),
+ PINMUX_DATA(CPORT17_IC_OE_MARK, PORT18_FN1),
+ PINMUX_DATA(SOUT2_MARK, PORT18_FN2),
+ PINMUX_DATA(CPORT18_MARK, PORT19_FN1),
+ PINMUX_DATA(XRTS2_MARK, PORT19_FN2),
+ PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
+ PINMUX_DATA(CPORT19_MPORT1_MARK, PORT20_FN1),
+ PINMUX_DATA(CPORT20_MARK, PORT21_FN1),
+ PINMUX_DATA(RFSPO6_MARK, PORT21_FN2),
+ PINMUX_DATA(CPORT21_MARK, PORT22_FN1),
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(CPORT22_MARK, PORT23_FN1),
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(CPORT23_MARK, PORT24_FN1),
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(RFSPO7_MARK, PORT24_FN3),
+ PINMUX_DATA(B_SYNLD1_MARK, PORT25_FN1),
+ PINMUX_DATA(B_SYNLD2_MARK, PORT26_FN1),
+ PINMUX_DATA(SYSENMSK_MARK, PORT26_FN2),
+ PINMUX_DATA(XMAINPS_MARK, PORT27_FN1),
+ PINMUX_DATA(XDIVPS_MARK, PORT28_FN1),
+ PINMUX_DATA(XIDRST_MARK, PORT29_FN1),
+ PINMUX_DATA(IDCLK_MARK, PORT30_FN1),
+ PINMUX_DATA(IC_DP_MARK, PORT30_FN2),
+ PINMUX_DATA(IDIO_MARK, PORT31_FN1),
+ PINMUX_DATA(IC_DM_MARK, PORT31_FN2),
+ PINMUX_DATA(SOUT1_MARK, PORT32_FN1),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
+ PINMUX_DATA(M02_BERDAT_MARK, PORT32_FN3),
+ PINMUX_DATA(SIN1_MARK, PORT33_FN1),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2),
+ PINMUX_DATA(XWUP_MARK, PORT33_FN3),
+ PINMUX_DATA(XRTS1_MARK, PORT34_FN1),
+ PINMUX_DATA(SCIFA4_RTS_MARK, PORT34_FN2),
+ PINMUX_DATA(M03_BERCLK_MARK, PORT34_FN3),
+ PINMUX_DATA(XCTS1_MARK, PORT35_FN1),
+ PINMUX_DATA(SCIFA4_CTS_MARK, PORT35_FN2),
+ PINMUX_DATA(PCMCLKO_MARK, PORT36_FN1),
+ PINMUX_DATA(SYNC8KO_MARK, PORT37_FN1),
+
+ /* 55-2 (FN) */
+ PINMUX_DATA(DNPCM_A_MARK, PORT38_FN1),
+ PINMUX_DATA(UPPCM_A_MARK, PORT39_FN1),
+ PINMUX_DATA(VACK_MARK, PORT40_FN1),
+ PINMUX_DATA(XTALB1L_MARK, PORT41_FN1),
+ PINMUX_DATA(GPS_AGC1_MARK, PORT42_FN1),
+ PINMUX_DATA(SCIFA0_RTS_MARK, PORT42_FN2),
+ PINMUX_DATA(GPS_AGC4_MARK, PORT43_FN1),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
+ PINMUX_DATA(GPS_PWRDOWN_MARK, PORT44_FN1),
+ PINMUX_DATA(SCIFA0_CTS_MARK, PORT44_FN2),
+ PINMUX_DATA(GPS_IM_MARK, PORT45_FN1),
+ PINMUX_DATA(GPS_IS_MARK, PORT46_FN1),
+ PINMUX_DATA(GPS_QM_MARK, PORT47_FN1),
+ PINMUX_DATA(GPS_QS_MARK, PORT48_FN1),
+ PINMUX_DATA(FMSOCK_MARK, PORT49_FN1),
+ PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2),
+ PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN3),
+ PINMUX_DATA(FMSOOLR_MARK, PORT50_FN1),
+ PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2),
+ PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3),
+ PINMUX_DATA(IPORT3_MARK, PORT50_FN4),
+ PINMUX_DATA(FMSIOLR_MARK, PORT50_FN5),
+ PINMUX_DATA(FMSOOBT_MARK, PORT51_FN1),
+ PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2),
+ PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3),
+ PINMUX_DATA(OPORT1_MARK, PORT51_FN4),
+ PINMUX_DATA(FMSIOBT_MARK, PORT51_FN5),
+ PINMUX_DATA(FMSOSLD_MARK, PORT52_FN1),
+ PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
+ PINMUX_DATA(OPORT2_MARK, PORT52_FN3),
+ PINMUX_DATA(FMSOILR_MARK, PORT53_FN1),
+ PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2),
+ PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3),
+ PINMUX_DATA(OPORT3_MARK, PORT53_FN4),
+ PINMUX_DATA(FMSIILR_MARK, PORT53_FN5),
+ PINMUX_DATA(FMSOIBT_MARK, PORT54_FN1),
+ PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2),
+ PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3),
+ PINMUX_DATA(FMSIIBT_MARK, PORT54_FN4),
+ PINMUX_DATA(FMSISLD_MARK, PORT55_FN1),
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT55_FN2),
+ PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
+ PINMUX_DATA(A0_EA0_MARK, PORT57_FN1),
+ PINMUX_DATA(BS_MARK, PORT57_FN2),
+ PINMUX_DATA(A12_EA12_MARK, PORT58_FN1),
+ PINMUX_DATA(PORT58_VIO_CKOR_MARK, PORT58_FN2),
+ PINMUX_DATA(TPU4TO2_MARK, PORT58_FN3),
+ PINMUX_DATA(A13_EA13_MARK, PORT59_FN1),
+ PINMUX_DATA(PORT59_IROUT_MARK, PORT59_FN2),
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT59_FN3),
+ PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
+ PINMUX_DATA(A14_EA14_MARK, PORT60_FN1),
+ PINMUX_DATA(PORT60_KEYOUT5_MARK, PORT60_FN2),
+ PINMUX_DATA(A15_EA15_MARK, PORT61_FN1),
+ PINMUX_DATA(PORT61_KEYOUT4_MARK, PORT61_FN2),
+ PINMUX_DATA(A16_EA16_MARK, PORT62_FN1),
+ PINMUX_DATA(PORT62_KEYOUT3_MARK, PORT62_FN2),
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN3),
+ PINMUX_DATA(A17_EA17_MARK, PORT63_FN1),
+ PINMUX_DATA(PORT63_KEYOUT2_MARK, PORT63_FN2),
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN3),
+ PINMUX_DATA(A18_EA18_MARK, PORT64_FN1),
+ PINMUX_DATA(PORT64_KEYOUT1_MARK, PORT64_FN2),
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN3),
+ PINMUX_DATA(A19_EA19_MARK, PORT65_FN1),
+ PINMUX_DATA(PORT65_KEYOUT0_MARK, PORT65_FN2),
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN3),
+ PINMUX_DATA(A20_EA20_MARK, PORT66_FN1),
+ PINMUX_DATA(PORT66_KEYIN0_MARK, PORT66_FN2),
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN3),
+ PINMUX_DATA(A21_EA21_MARK, PORT67_FN1),
+ PINMUX_DATA(PORT67_KEYIN1_MARK, PORT67_FN2),
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN3),
+ PINMUX_DATA(A22_EA22_MARK, PORT68_FN1),
+ PINMUX_DATA(PORT68_KEYIN2_MARK, PORT68_FN2),
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN3),
+ PINMUX_DATA(A23_EA23_MARK, PORT69_FN1),
+ PINMUX_DATA(PORT69_KEYIN3_MARK, PORT69_FN2),
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN3),
+ PINMUX_DATA(A24_EA24_MARK, PORT70_FN1),
+ PINMUX_DATA(PORT70_KEYIN4_MARK, PORT70_FN2),
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN3),
+ PINMUX_DATA(A25_EA25_MARK, PORT71_FN1),
+ PINMUX_DATA(PORT71_KEYIN5_MARK, PORT71_FN2),
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN3),
+ PINMUX_DATA(A26_MARK, PORT72_FN1),
+ PINMUX_DATA(PORT72_KEYIN6_MARK, PORT72_FN2),
+ PINMUX_DATA(D0_ED0_NAF0_MARK, PORT74_FN1),
+ PINMUX_DATA(D1_ED1_NAF1_MARK, PORT75_FN1),
+ PINMUX_DATA(D2_ED2_NAF2_MARK, PORT76_FN1),
+ PINMUX_DATA(D3_ED3_NAF3_MARK, PORT77_FN1),
+ PINMUX_DATA(D4_ED4_NAF4_MARK, PORT78_FN1),
+ PINMUX_DATA(D5_ED5_NAF5_MARK, PORT79_FN1),
+ PINMUX_DATA(D6_ED6_NAF6_MARK, PORT80_FN1),
+ PINMUX_DATA(D7_ED7_NAF7_MARK, PORT81_FN1),
+ PINMUX_DATA(D8_ED8_NAF8_MARK, PORT82_FN1),
+ PINMUX_DATA(D9_ED9_NAF9_MARK, PORT83_FN1),
+ PINMUX_DATA(D10_ED10_NAF10_MARK, PORT84_FN1),
+ PINMUX_DATA(D11_ED11_NAF11_MARK, PORT85_FN1),
+ PINMUX_DATA(D12_ED12_NAF12_MARK, PORT86_FN1),
+ PINMUX_DATA(D13_ED13_NAF13_MARK, PORT87_FN1),
+ PINMUX_DATA(D14_ED14_NAF14_MARK, PORT88_FN1),
+ PINMUX_DATA(D15_ED15_NAF15_MARK, PORT89_FN1),
+ PINMUX_DATA(CS4_MARK, PORT90_FN1),
+ PINMUX_DATA(CS5A_MARK, PORT91_FN1),
+ PINMUX_DATA(FMSICK_MARK, PORT91_FN2),
+ PINMUX_DATA(CS5B_MARK, PORT92_FN1),
+ PINMUX_DATA(FCE1_MARK, PORT92_FN2),
+
+ /* 55-3 (FN) */
+ PINMUX_DATA(CS6B_MARK, PORT93_FN1),
+ PINMUX_DATA(XCS2_MARK, PORT93_FN2),
+ PINMUX_DATA(CS6A_MARK, PORT93_FN3),
+ PINMUX_DATA(DACK0_MARK, PORT93_FN4),
+ PINMUX_DATA(FCE0_MARK, PORT94_FN1),
+ PINMUX_DATA(WAIT_MARK, PORT95_FN1),
+ PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
+ PINMUX_DATA(RD_XRD_MARK, PORT96_FN1),
+ PINMUX_DATA(WE0_XWR0_FWE_MARK, PORT97_FN1),
+ PINMUX_DATA(WE1_XWR1_MARK, PORT98_FN1),
+ PINMUX_DATA(FRB_MARK, PORT99_FN1),
+ PINMUX_DATA(CKO_MARK, PORT100_FN1),
+ PINMUX_DATA(NBRSTOUT_MARK, PORT101_FN1),
+ PINMUX_DATA(NBRST_MARK, PORT102_FN1),
+ PINMUX_DATA(GPS_EPPSIN_MARK, PORT106_FN1),
+ PINMUX_DATA(LATCHPULSE_MARK, PORT110_FN1),
+ PINMUX_DATA(LTESIGNAL_MARK, PORT111_FN1),
+ PINMUX_DATA(LEGACYSTATE_MARK, PORT112_FN1),
+ PINMUX_DATA(TCKON_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT128_FN1),
+ PINMUX_DATA(PORT128_KEYOUT0_MARK, PORT128_FN2),
+ PINMUX_DATA(IPORT0_MARK, PORT128_FN3),
+ PINMUX_DATA(VIO_HD_MARK, PORT129_FN1),
+ PINMUX_DATA(PORT129_KEYOUT1_MARK, PORT129_FN2),
+ PINMUX_DATA(IPORT1_MARK, PORT129_FN3),
+ PINMUX_DATA(VIO_D0_MARK, PORT130_FN1),
+ PINMUX_DATA(PORT130_KEYOUT2_MARK, PORT130_FN2),
+ PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3),
+ PINMUX_DATA(VIO_D1_MARK, PORT131_FN1),
+ PINMUX_DATA(PORT131_KEYOUT3_MARK, PORT131_FN2),
+ PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3),
+ PINMUX_DATA(VIO_D2_MARK, PORT132_FN1),
+ PINMUX_DATA(PORT132_KEYOUT4_MARK, PORT132_FN2),
+ PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3),
+ PINMUX_DATA(VIO_D3_MARK, PORT133_FN1),
+ PINMUX_DATA(PORT133_KEYOUT5_MARK, PORT133_FN2),
+ PINMUX_DATA(PORT133_MSIOF2_TSYNC_MARK, PORT133_FN3),
+ PINMUX_DATA(VIO_D4_MARK, PORT134_FN1),
+ PINMUX_DATA(PORT134_KEYIN0_MARK, PORT134_FN2),
+ PINMUX_DATA(PORT134_MSIOF2_TXD_MARK, PORT134_FN3),
+ PINMUX_DATA(VIO_D5_MARK, PORT135_FN1),
+ PINMUX_DATA(PORT135_KEYIN1_MARK, PORT135_FN2),
+ PINMUX_DATA(PORT135_MSIOF2_TSCK_MARK, PORT135_FN3),
+ PINMUX_DATA(VIO_D6_MARK, PORT136_FN1),
+ PINMUX_DATA(PORT136_KEYIN2_MARK, PORT136_FN2),
+ PINMUX_DATA(VIO_D7_MARK, PORT137_FN1),
+ PINMUX_DATA(PORT137_KEYIN3_MARK, PORT137_FN2),
+ PINMUX_DATA(VIO_D8_MARK, PORT138_FN1),
+ PINMUX_DATA(M9_SLCD_A01_MARK, PORT138_FN2),
+ PINMUX_DATA(PORT138_FSIAOMC_MARK, PORT138_FN3),
+ PINMUX_DATA(VIO_D9_MARK, PORT139_FN1),
+ PINMUX_DATA(M10_SLCD_CK1_MARK, PORT139_FN2),
+ PINMUX_DATA(PORT139_FSIAOLR_MARK, PORT139_FN3),
+ PINMUX_DATA(VIO_D10_MARK, PORT140_FN1),
+ PINMUX_DATA(M11_SLCD_SO1_MARK, PORT140_FN2),
+ PINMUX_DATA(TPU0TO2_MARK, PORT140_FN3),
+ PINMUX_DATA(PORT140_FSIAOBT_MARK, PORT140_FN4),
+ PINMUX_DATA(VIO_D11_MARK, PORT141_FN1),
+ PINMUX_DATA(M12_SLCD_CE1_MARK, PORT141_FN2),
+ PINMUX_DATA(TPU0TO3_MARK, PORT141_FN3),
+ PINMUX_DATA(PORT141_FSIAOSLD_MARK, PORT141_FN4),
+ PINMUX_DATA(VIO_D12_MARK, PORT142_FN1),
+ PINMUX_DATA(M13_BSW_MARK, PORT142_FN2),
+ PINMUX_DATA(PORT142_FSIACK_MARK, PORT142_FN3),
+ PINMUX_DATA(VIO_D13_MARK, PORT143_FN1),
+ PINMUX_DATA(M14_GSW_MARK, PORT143_FN2),
+ PINMUX_DATA(PORT143_FSIAILR_MARK, PORT143_FN3),
+ PINMUX_DATA(VIO_D14_MARK, PORT144_FN1),
+ PINMUX_DATA(M15_RSW_MARK, PORT144_FN2),
+ PINMUX_DATA(PORT144_FSIAIBT_MARK, PORT144_FN3),
+ PINMUX_DATA(VIO_D15_MARK, PORT145_FN1),
+ PINMUX_DATA(TPU1TO3_MARK, PORT145_FN2),
+ PINMUX_DATA(PORT145_FSIAISLD_MARK, PORT145_FN3),
+ PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1),
+ PINMUX_DATA(PORT146_KEYIN4_MARK, PORT146_FN2),
+ PINMUX_DATA(IPORT2_MARK, PORT146_FN3),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1),
+ PINMUX_DATA(PORT147_KEYIN5_MARK, PORT147_FN2),
+ PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
+ PINMUX_DATA(PORT148_KEYIN6_MARK, PORT148_FN2),
+ PINMUX_DATA(A27_MARK, PORT149_FN1),
+ PINMUX_DATA(RDWR_XWE_MARK, PORT149_FN2),
+ PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN1),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN1),
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN2),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN1),
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN2),
+ PINMUX_DATA(TPU1TO2_MARK, PORT153_FN1),
+ PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN2),
+ PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN3),
+ PINMUX_DATA(SOUT3_MARK, PORT154_FN1),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2),
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN3),
+ PINMUX_DATA(SIN3_MARK, PORT155_FN1),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2),
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN3),
+ PINMUX_DATA(XRTS3_MARK, PORT156_FN1),
+ PINMUX_DATA(SCIFA2_RTS1_MARK, PORT156_FN2),
+ PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN3),
+ PINMUX_DATA(XCTS3_MARK, PORT157_FN1),
+ PINMUX_DATA(SCIFA2_CTS1_MARK, PORT157_FN2),
+ PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN3),
+
+ /* 55-4 (FN) */
+ PINMUX_DATA(DINT_MARK, PORT158_FN1),
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2),
+ PINMUX_DATA(TS_SCK3_MARK, PORT158_FN3),
+ PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1),
+ PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2),
+ PINMUX_DATA(NMI_MARK, PORT159_FN3),
+ PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1),
+ PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2),
+ PINMUX_DATA(SOUT0_MARK, PORT160_FN3),
+ PINMUX_DATA(PORT161_SCIFB_CTS_MARK, PORT161_FN1),
+ PINMUX_DATA(PORT161_SCIFA5_CTS_MARK, PORT161_FN2),
+ PINMUX_DATA(XCTS0_MARK, PORT161_FN3),
+ PINMUX_DATA(MFG3_IN2_MARK, PORT161_FN4),
+ PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1),
+ PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2),
+ PINMUX_DATA(SIN0_MARK, PORT162_FN3),
+ PINMUX_DATA(MFG3_IN1_MARK, PORT162_FN4),
+ PINMUX_DATA(PORT163_SCIFB_RTS_MARK, PORT163_FN1),
+ PINMUX_DATA(PORT163_SCIFA5_RTS_MARK, PORT163_FN2),
+ PINMUX_DATA(XRTS0_MARK, PORT163_FN3),
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT163_FN4),
+ PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
+ PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
+ PINMUX_DATA(PORT192_KEYOUT0_MARK, PORT192_FN2),
+ PINMUX_DATA(EXT_CKI_MARK, PORT192_FN3),
+ PINMUX_DATA(LCDD1_MARK, PORT193_FN1),
+ PINMUX_DATA(PORT193_KEYOUT1_MARK, PORT193_FN2),
+ PINMUX_DATA(PORT193_SCIFA5_CTS_MARK, PORT193_FN3),
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN4),
+ PINMUX_DATA(LCDD2_MARK, PORT194_FN1),
+ PINMUX_DATA(PORT194_KEYOUT2_MARK, PORT194_FN2),
+ PINMUX_DATA(PORT194_SCIFA5_RTS_MARK, PORT194_FN3),
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN4),
+ PINMUX_DATA(LCDD3_MARK, PORT195_FN1),
+ PINMUX_DATA(PORT195_KEYOUT3_MARK, PORT195_FN2),
+ PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3),
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN4),
+ PINMUX_DATA(LCDD4_MARK, PORT196_FN1),
+ PINMUX_DATA(PORT196_KEYOUT4_MARK, PORT196_FN2),
+ PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3),
+ PINMUX_DATA(LCDD5_MARK, PORT197_FN1),
+ PINMUX_DATA(PORT197_KEYOUT5_MARK, PORT197_FN2),
+ PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3),
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN4),
+ PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT199_FN1),
+ PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2),
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN3),
+ PINMUX_DATA(LCDD8_MARK, PORT200_FN1),
+ PINMUX_DATA(PORT200_KEYIN0_MARK, PORT200_FN2),
+ PINMUX_DATA(VIO_DR0_MARK, PORT200_FN3),
+ PINMUX_DATA(D16_MARK, PORT200_FN4),
+ PINMUX_DATA(LCDD9_MARK, PORT201_FN1),
+ PINMUX_DATA(PORT201_KEYIN1_MARK, PORT201_FN2),
+ PINMUX_DATA(VIO_DR1_MARK, PORT201_FN3),
+ PINMUX_DATA(D17_MARK, PORT201_FN4),
+ PINMUX_DATA(LCDD10_MARK, PORT202_FN1),
+ PINMUX_DATA(PORT202_KEYIN2_MARK, PORT202_FN2),
+ PINMUX_DATA(VIO_DR2_MARK, PORT202_FN3),
+ PINMUX_DATA(D18_MARK, PORT202_FN4),
+ PINMUX_DATA(LCDD11_MARK, PORT203_FN1),
+ PINMUX_DATA(PORT203_KEYIN3_MARK, PORT203_FN2),
+ PINMUX_DATA(VIO_DR3_MARK, PORT203_FN3),
+ PINMUX_DATA(D19_MARK, PORT203_FN4),
+ PINMUX_DATA(LCDD12_MARK, PORT204_FN1),
+ PINMUX_DATA(PORT204_KEYIN4_MARK, PORT204_FN2),
+ PINMUX_DATA(VIO_DR4_MARK, PORT204_FN3),
+ PINMUX_DATA(D20_MARK, PORT204_FN4),
+ PINMUX_DATA(LCDD13_MARK, PORT205_FN1),
+ PINMUX_DATA(PORT205_KEYIN5_MARK, PORT205_FN2),
+ PINMUX_DATA(VIO_DR5_MARK, PORT205_FN3),
+ PINMUX_DATA(D21_MARK, PORT205_FN4),
+ PINMUX_DATA(LCDD14_MARK, PORT206_FN1),
+ PINMUX_DATA(PORT206_KEYIN6_MARK, PORT206_FN2),
+ PINMUX_DATA(VIO_DR6_MARK, PORT206_FN3),
+ PINMUX_DATA(D22_MARK, PORT206_FN4),
+ PINMUX_DATA(LCDD15_MARK, PORT207_FN1),
+ PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2),
+ PINMUX_DATA(PORT207_KEYOUT0_MARK, PORT207_FN3),
+ PINMUX_DATA(VIO_DR7_MARK, PORT207_FN4),
+ PINMUX_DATA(D23_MARK, PORT207_FN5),
+ PINMUX_DATA(LCDD16_MARK, PORT208_FN1),
+ PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2),
+ PINMUX_DATA(PORT208_KEYOUT1_MARK, PORT208_FN3),
+ PINMUX_DATA(VIO_VDR_MARK, PORT208_FN4),
+ PINMUX_DATA(D24_MARK, PORT208_FN5),
+ PINMUX_DATA(LCDD17_MARK, PORT209_FN1),
+ PINMUX_DATA(PORT209_KEYOUT2_MARK, PORT209_FN2),
+ PINMUX_DATA(VIO_HDR_MARK, PORT209_FN3),
+ PINMUX_DATA(D25_MARK, PORT209_FN4),
+ PINMUX_DATA(LCDD18_MARK, PORT210_FN1),
+ PINMUX_DATA(DREQ2_MARK, PORT210_FN2),
+ PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN3),
+ PINMUX_DATA(D26_MARK, PORT210_FN4),
+ PINMUX_DATA(LCDD19_MARK, PORT211_FN1),
+ PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN2),
+ PINMUX_DATA(D27_MARK, PORT211_FN3),
+ PINMUX_DATA(LCDD20_MARK, PORT212_FN1),
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2),
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN3),
+ PINMUX_DATA(D28_MARK, PORT212_FN4),
+ PINMUX_DATA(LCDD21_MARK, PORT213_FN1),
+ PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2),
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN3),
+ PINMUX_DATA(D29_MARK, PORT213_FN4),
+ PINMUX_DATA(LCDD22_MARK, PORT214_FN1),
+ PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2),
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN3),
+ PINMUX_DATA(D30_MARK, PORT214_FN4),
+ PINMUX_DATA(LCDD23_MARK, PORT215_FN1),
+ PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2),
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN3),
+ PINMUX_DATA(D31_MARK, PORT215_FN4),
+ PINMUX_DATA(LCDDCK_MARK, PORT216_FN1),
+ PINMUX_DATA(LCDWR_MARK, PORT216_FN2),
+ PINMUX_DATA(PORT216_KEYOUT3_MARK, PORT216_FN3),
+ PINMUX_DATA(VIO_CLKR_MARK, PORT216_FN4),
+ PINMUX_DATA(LCDRD_MARK, PORT217_FN1),
+ PINMUX_DATA(DACK2_MARK, PORT217_FN2),
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN3),
+ PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1),
+ PINMUX_DATA(LCDCS_MARK, PORT218_FN2),
+ PINMUX_DATA(LCDCS2_MARK, PORT218_FN3),
+ PINMUX_DATA(DACK3_MARK, PORT218_FN4),
+ PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5),
+ PINMUX_DATA(PORT218_KEYOUT4_MARK, PORT218_FN6),
+ PINMUX_DATA(LCDDISP_MARK, PORT219_FN1),
+ PINMUX_DATA(LCDRS_MARK, PORT219_FN2),
+ PINMUX_DATA(DREQ3_MARK, PORT219_FN3),
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN4),
+ PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1),
+ PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
+ PINMUX_DATA(PORT220_KEYOUT5_MARK, PORT220_FN3),
+ PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1),
+ PINMUX_DATA(DREQ1_MARK, PORT221_FN2),
+ PINMUX_DATA(PWEN_MARK, PORT221_FN3),
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN4),
+ PINMUX_DATA(LCDDON_MARK, PORT222_FN1),
+ PINMUX_DATA(LCDDON2_MARK, PORT222_FN2),
+ PINMUX_DATA(DACK1_MARK, PORT222_FN3),
+ PINMUX_DATA(OVCN_MARK, PORT222_FN4),
+ PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5),
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN1),
+ PINMUX_DATA(OVCN2_MARK, PORT225_FN2),
+ PINMUX_DATA(EXTLP_MARK, PORT226_FN1),
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2),
+ PINMUX_DATA(USBTERM_MARK, PORT226_FN3),
+ PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN4),
+ PINMUX_DATA(SCIFA1_RTS_MARK, PORT227_FN1),
+ PINMUX_DATA(IDIN_MARK, PORT227_FN2),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN1),
+ PINMUX_DATA(SCIFA1_CTS_MARK, PORT229_FN1),
+ PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN2),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1),
+ PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2),
+ PINMUX_DATA(PORT230_FSIAOMC_MARK, PORT230_FN3),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1),
+ PINMUX_DATA(SCIFA2_CTS2_MARK, PORT231_FN2),
+ PINMUX_DATA(PORT231_FSIAOLR_MARK, PORT231_FN3),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1),
+ PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2),
+ PINMUX_DATA(PORT232_FSIAOBT_MARK, PORT232_FN3),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1),
+ PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2),
+ PINMUX_DATA(GPS_VCOTRIG_MARK, PORT233_FN3),
+ PINMUX_DATA(PORT233_FSIACK_MARK, PORT233_FN4),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1),
+ PINMUX_DATA(SCIFA2_RTS2_MARK, PORT234_FN2),
+ PINMUX_DATA(PORT234_FSIAOSLD_MARK, PORT234_FN3),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1),
+ PINMUX_DATA(OPORT0_MARK, PORT235_FN2),
+ PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3),
+ PINMUX_DATA(PORT235_FSIAILR_MARK, PORT235_FN4),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1),
+ PINMUX_DATA(I2C_SDA2_MARK, PORT236_FN2),
+ PINMUX_DATA(PORT236_FSIAIBT_MARK, PORT236_FN3),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1),
+ PINMUX_DATA(I2C_SCL2_MARK, PORT237_FN2),
+ PINMUX_DATA(PORT237_FSIAISLD_MARK, PORT237_FN3),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1),
+ PINMUX_DATA(EDBGREQ3_MARK, PORT238_FN2),
+
+ /* 55-5 (FN) */
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1),
+ PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
+ PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1),
+ PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2),
+ PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3),
+ PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4),
+ PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1),
+ PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN2),
+ PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1),
+ PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT244_SCIFA5_CTS_MARK, PORT244_FN1),
+ PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2),
+ PINMUX_DATA(PORT244_SCIFB_CTS_MARK, PORT244_FN3),
+ PINMUX_DATA(PORT245_SCIFA5_RTS_MARK, PORT245_FN1),
+ PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2),
+ PINMUX_DATA(PORT245_SCIFB_RTS_MARK, PORT245_FN3),
+ PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1),
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2),
+ PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3),
+ PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
+ PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1),
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2),
+ PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3),
+ PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
+ PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1),
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2),
+ PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3),
+ PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4),
+ PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1),
+ PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2),
+ PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
+ PINMUX_DATA(TCK2_SWCLK_MC0_MARK, PORT250_FN2),
+ PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
+ PINMUX_DATA(TMS2_SWDIO_MC0_MARK, PORT252_FN2),
+ PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
+ PINMUX_DATA(TDO2_SWO0_MC0_MARK, PORT253_FN2),
+ PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
+ PINMUX_DATA(TDI2_MARK, PORT254_FN2),
+ PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
+ PINMUX_DATA(RTCK2_SWO1_MC0_MARK, PORT255_FN2),
+ PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
+ PINMUX_DATA(TRST2_MARK, PORT256_FN2),
+ PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
+ PINMUX_DATA(EDBGREQ2_MARK, PORT257_FN2),
+ PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
+ PINMUX_DATA(TCK3_SWCLK_MC1_MARK, PORT258_FN2),
+ PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1),
+ PINMUX_DATA(M11_SLCD_SO2_MARK, PORT259_FN2),
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
+ PINMUX_DATA(TMS3_SWDIO_MC1_MARK, PORT259_FN4),
+ PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1),
+ PINMUX_DATA(M9_SLCD_A02_MARK, PORT260_FN2),
+ PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
+ PINMUX_DATA(TDO3_SWO0_MC1_MARK, PORT260_FN4),
+ PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1),
+ PINMUX_DATA(M10_SLCD_CK2_MARK, PORT261_FN2),
+ PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
+ PINMUX_DATA(TDI3_MARK, PORT261_FN4),
+ PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1),
+ PINMUX_DATA(M12_SLCD_CE2_MARK, PORT262_FN2),
+ PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
+ PINMUX_DATA(RTCK3_SWO1_MC1_MARK, PORT262_FN4),
+ PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
+ PINMUX_DATA(TRST3_MARK, PORT263_FN2),
+ PINMUX_DATA(RESETOUTS_MARK, PORT264_FN1),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_265() _265(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* 55-1 -> 55-5 (GPIO) */
+ GPIO_PORT_265(),
+
+ /* Special Pull-up / Pull-down Functions */
+ GPIO_FN(PORT66_KEYIN0_PU), GPIO_FN(PORT67_KEYIN1_PU),
+ GPIO_FN(PORT68_KEYIN2_PU), GPIO_FN(PORT69_KEYIN3_PU),
+ GPIO_FN(PORT70_KEYIN4_PU), GPIO_FN(PORT71_KEYIN5_PU),
+ GPIO_FN(PORT72_KEYIN6_PU),
+
+ /* 55-1 (FN) */
+ GPIO_FN(VBUS_0),
+ GPIO_FN(CPORT0),
+ GPIO_FN(CPORT1),
+ GPIO_FN(CPORT2),
+ GPIO_FN(CPORT3),
+ GPIO_FN(CPORT4),
+ GPIO_FN(CPORT5),
+ GPIO_FN(CPORT6),
+ GPIO_FN(CPORT7),
+ GPIO_FN(CPORT8),
+ GPIO_FN(CPORT9),
+ GPIO_FN(CPORT10),
+ GPIO_FN(CPORT11), GPIO_FN(SIN2),
+ GPIO_FN(CPORT12), GPIO_FN(XCTS2),
+ GPIO_FN(CPORT13), GPIO_FN(RFSPO4),
+ GPIO_FN(CPORT14), GPIO_FN(RFSPO5),
+ GPIO_FN(CPORT15), GPIO_FN(SCIFA0_SCK), GPIO_FN(GPS_AGC2),
+ GPIO_FN(CPORT16), GPIO_FN(SCIFA0_TXD), GPIO_FN(GPS_AGC3),
+ GPIO_FN(CPORT17_IC_OE), GPIO_FN(SOUT2),
+ GPIO_FN(CPORT18), GPIO_FN(XRTS2), GPIO_FN(PORT19_VIO_CKO2),
+ GPIO_FN(CPORT19_MPORT1),
+ GPIO_FN(CPORT20), GPIO_FN(RFSPO6),
+ GPIO_FN(CPORT21), GPIO_FN(STATUS0),
+ GPIO_FN(CPORT22), GPIO_FN(STATUS1),
+ GPIO_FN(CPORT23), GPIO_FN(STATUS2), GPIO_FN(RFSPO7),
+ GPIO_FN(B_SYNLD1),
+ GPIO_FN(B_SYNLD2), GPIO_FN(SYSENMSK),
+ GPIO_FN(XMAINPS),
+ GPIO_FN(XDIVPS),
+ GPIO_FN(XIDRST),
+ GPIO_FN(IDCLK), GPIO_FN(IC_DP),
+ GPIO_FN(IDIO), GPIO_FN(IC_DM),
+ GPIO_FN(SOUT1), GPIO_FN(SCIFA4_TXD), GPIO_FN(M02_BERDAT),
+ GPIO_FN(SIN1), GPIO_FN(SCIFA4_RXD), GPIO_FN(XWUP),
+ GPIO_FN(XRTS1), GPIO_FN(SCIFA4_RTS), GPIO_FN(M03_BERCLK),
+ GPIO_FN(XCTS1), GPIO_FN(SCIFA4_CTS),
+ GPIO_FN(PCMCLKO),
+ GPIO_FN(SYNC8KO),
+
+ /* 55-2 (FN) */
+ GPIO_FN(DNPCM_A),
+ GPIO_FN(UPPCM_A),
+ GPIO_FN(VACK),
+ GPIO_FN(XTALB1L),
+ GPIO_FN(GPS_AGC1), GPIO_FN(SCIFA0_RTS),
+ GPIO_FN(GPS_AGC4), GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(GPS_PWRDOWN), GPIO_FN(SCIFA0_CTS),
+ GPIO_FN(GPS_IM),
+ GPIO_FN(GPS_IS),
+ GPIO_FN(GPS_QM),
+ GPIO_FN(GPS_QS),
+ GPIO_FN(FMSOCK), GPIO_FN(PORT49_IRDA_OUT), GPIO_FN(PORT49_IROUT),
+ GPIO_FN(FMSOOLR), GPIO_FN(BBIF2_TSYNC2), GPIO_FN(TPU2TO2),
+ GPIO_FN(IPORT3), GPIO_FN(FMSIOLR),
+ GPIO_FN(FMSOOBT), GPIO_FN(BBIF2_TSCK2), GPIO_FN(TPU2TO3),
+ GPIO_FN(OPORT1), GPIO_FN(FMSIOBT),
+ GPIO_FN(FMSOSLD), GPIO_FN(BBIF2_TXD2), GPIO_FN(OPORT2),
+ GPIO_FN(FMSOILR), GPIO_FN(PORT53_IRDA_IN), GPIO_FN(TPU3TO3),
+ GPIO_FN(OPORT3), GPIO_FN(FMSIILR),
+ GPIO_FN(FMSOIBT), GPIO_FN(PORT54_IRDA_FIRSEL), GPIO_FN(TPU3TO2),
+ GPIO_FN(FMSIIBT),
+ GPIO_FN(FMSISLD), GPIO_FN(MFG0_OUT1), GPIO_FN(TPU0TO0),
+ GPIO_FN(A0_EA0), GPIO_FN(BS),
+ GPIO_FN(A12_EA12), GPIO_FN(PORT58_VIO_CKOR), GPIO_FN(TPU4TO2),
+ GPIO_FN(A13_EA13), GPIO_FN(PORT59_IROUT), GPIO_FN(MFG0_OUT2),
+ GPIO_FN(TPU0TO1),
+ GPIO_FN(A14_EA14), GPIO_FN(PORT60_KEYOUT5),
+ GPIO_FN(A15_EA15), GPIO_FN(PORT61_KEYOUT4),
+ GPIO_FN(A16_EA16), GPIO_FN(PORT62_KEYOUT3), GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17_EA17), GPIO_FN(PORT63_KEYOUT2), GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18_EA18), GPIO_FN(PORT64_KEYOUT1), GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19_EA19), GPIO_FN(PORT65_KEYOUT0), GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20_EA20), GPIO_FN(PORT66_KEYIN0), GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21_EA21), GPIO_FN(PORT67_KEYIN1), GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22_EA22), GPIO_FN(PORT68_KEYIN2), GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23_EA23), GPIO_FN(PORT69_KEYIN3), GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24_EA24), GPIO_FN(PORT70_KEYIN4), GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25_EA25), GPIO_FN(PORT71_KEYIN5), GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), GPIO_FN(PORT72_KEYIN6),
+ GPIO_FN(D0_ED0_NAF0),
+ GPIO_FN(D1_ED1_NAF1),
+ GPIO_FN(D2_ED2_NAF2),
+ GPIO_FN(D3_ED3_NAF3),
+ GPIO_FN(D4_ED4_NAF4),
+ GPIO_FN(D5_ED5_NAF5),
+ GPIO_FN(D6_ED6_NAF6),
+ GPIO_FN(D7_ED7_NAF7),
+ GPIO_FN(D8_ED8_NAF8),
+ GPIO_FN(D9_ED9_NAF9),
+ GPIO_FN(D10_ED10_NAF10),
+ GPIO_FN(D11_ED11_NAF11),
+ GPIO_FN(D12_ED12_NAF12),
+ GPIO_FN(D13_ED13_NAF13),
+ GPIO_FN(D14_ED14_NAF14),
+ GPIO_FN(D15_ED15_NAF15),
+ GPIO_FN(CS4),
+ GPIO_FN(CS5A), GPIO_FN(FMSICK),
+
+ /* 55-3 (FN) */
+ GPIO_FN(CS5B), GPIO_FN(FCE1),
+ GPIO_FN(CS6B), GPIO_FN(XCS2), GPIO_FN(CS6A), GPIO_FN(DACK0),
+ GPIO_FN(FCE0),
+ GPIO_FN(WAIT), GPIO_FN(DREQ0),
+ GPIO_FN(RD_XRD),
+ GPIO_FN(WE0_XWR0_FWE),
+ GPIO_FN(WE1_XWR1),
+ GPIO_FN(FRB),
+ GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT),
+ GPIO_FN(NBRST),
+ GPIO_FN(GPS_EPPSIN),
+ GPIO_FN(LATCHPULSE),
+ GPIO_FN(LTESIGNAL),
+ GPIO_FN(LEGACYSTATE),
+ GPIO_FN(TCKON),
+ GPIO_FN(VIO_VD), GPIO_FN(PORT128_KEYOUT0), GPIO_FN(IPORT0),
+ GPIO_FN(VIO_HD), GPIO_FN(PORT129_KEYOUT1), GPIO_FN(IPORT1),
+ GPIO_FN(VIO_D0), GPIO_FN(PORT130_KEYOUT2), GPIO_FN(PORT130_MSIOF2_RXD),
+ GPIO_FN(VIO_D1), GPIO_FN(PORT131_KEYOUT3), GPIO_FN(PORT131_MSIOF2_SS1),
+ GPIO_FN(VIO_D2), GPIO_FN(PORT132_KEYOUT4), GPIO_FN(PORT132_MSIOF2_SS2),
+ GPIO_FN(VIO_D3), GPIO_FN(PORT133_KEYOUT5),
+ GPIO_FN(PORT133_MSIOF2_TSYNC),
+ GPIO_FN(VIO_D4), GPIO_FN(PORT134_KEYIN0), GPIO_FN(PORT134_MSIOF2_TXD),
+ GPIO_FN(VIO_D5), GPIO_FN(PORT135_KEYIN1), GPIO_FN(PORT135_MSIOF2_TSCK),
+ GPIO_FN(VIO_D6), GPIO_FN(PORT136_KEYIN2),
+ GPIO_FN(VIO_D7), GPIO_FN(PORT137_KEYIN3),
+ GPIO_FN(VIO_D8), GPIO_FN(M9_SLCD_A01), GPIO_FN(PORT138_FSIAOMC),
+ GPIO_FN(VIO_D9), GPIO_FN(M10_SLCD_CK1), GPIO_FN(PORT139_FSIAOLR),
+ GPIO_FN(VIO_D10), GPIO_FN(M11_SLCD_SO1), GPIO_FN(TPU0TO2),
+ GPIO_FN(PORT140_FSIAOBT),
+ GPIO_FN(VIO_D11), GPIO_FN(M12_SLCD_CE1), GPIO_FN(TPU0TO3),
+ GPIO_FN(PORT141_FSIAOSLD),
+ GPIO_FN(VIO_D12), GPIO_FN(M13_BSW), GPIO_FN(PORT142_FSIACK),
+ GPIO_FN(VIO_D13), GPIO_FN(M14_GSW), GPIO_FN(PORT143_FSIAILR),
+ GPIO_FN(VIO_D14), GPIO_FN(M15_RSW), GPIO_FN(PORT144_FSIAIBT),
+ GPIO_FN(VIO_D15), GPIO_FN(TPU1TO3), GPIO_FN(PORT145_FSIAISLD),
+ GPIO_FN(VIO_CLK), GPIO_FN(PORT146_KEYIN4), GPIO_FN(IPORT2),
+ GPIO_FN(VIO_FIELD), GPIO_FN(PORT147_KEYIN5),
+ GPIO_FN(VIO_CKO), GPIO_FN(PORT148_KEYIN6),
+ GPIO_FN(A27), GPIO_FN(RDWR_XWE), GPIO_FN(MFG0_IN1),
+ GPIO_FN(MFG0_IN2),
+ GPIO_FN(TS_SPSYNC3), GPIO_FN(MSIOF2_RSCK),
+ GPIO_FN(TS_SDAT3), GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(TPU1TO2), GPIO_FN(TS_SDEN3), GPIO_FN(PORT153_MSIOF2_SS1),
+ GPIO_FN(SOUT3), GPIO_FN(SCIFA2_TXD1), GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(SIN3), GPIO_FN(SCIFA2_RXD1), GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(XRTS3), GPIO_FN(SCIFA2_RTS1), GPIO_FN(PORT156_MSIOF2_SS2),
+ GPIO_FN(XCTS3), GPIO_FN(SCIFA2_CTS1), GPIO_FN(PORT157_MSIOF2_RXD),
+
+ /* 55-4 (FN) */
+ GPIO_FN(DINT), GPIO_FN(SCIFA2_SCK1), GPIO_FN(TS_SCK3),
+ GPIO_FN(PORT159_SCIFB_SCK), GPIO_FN(PORT159_SCIFA5_SCK), GPIO_FN(NMI),
+ GPIO_FN(PORT160_SCIFB_TXD), GPIO_FN(PORT160_SCIFA5_TXD), GPIO_FN(SOUT0),
+ GPIO_FN(PORT161_SCIFB_CTS), GPIO_FN(PORT161_SCIFA5_CTS), GPIO_FN(XCTS0),
+ GPIO_FN(MFG3_IN2),
+ GPIO_FN(PORT162_SCIFB_RXD), GPIO_FN(PORT162_SCIFA5_RXD), GPIO_FN(SIN0),
+ GPIO_FN(MFG3_IN1),
+ GPIO_FN(PORT163_SCIFB_RTS), GPIO_FN(PORT163_SCIFA5_RTS), GPIO_FN(XRTS0),
+ GPIO_FN(MFG3_OUT1), GPIO_FN(TPU3TO0),
+ GPIO_FN(LCDD0), GPIO_FN(PORT192_KEYOUT0), GPIO_FN(EXT_CKI),
+ GPIO_FN(LCDD1), GPIO_FN(PORT193_KEYOUT1), GPIO_FN(PORT193_SCIFA5_CTS),
+ GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), GPIO_FN(PORT194_KEYOUT2), GPIO_FN(PORT194_SCIFA5_RTS),
+ GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), GPIO_FN(PORT195_KEYOUT3), GPIO_FN(PORT195_SCIFA5_RXD),
+ GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), GPIO_FN(PORT196_KEYOUT4), GPIO_FN(PORT196_SCIFA5_TXD),
+ GPIO_FN(LCDD5), GPIO_FN(PORT197_KEYOUT5), GPIO_FN(PORT197_SCIFA5_SCK),
+ GPIO_FN(MFG2_OUT2),
+ GPIO_FN(LCDD6),
+ GPIO_FN(LCDD7), GPIO_FN(TPU4TO1), GPIO_FN(MFG4_OUT2),
+ GPIO_FN(LCDD8), GPIO_FN(PORT200_KEYIN0), GPIO_FN(VIO_DR0),
+ GPIO_FN(D16),
+ GPIO_FN(LCDD9), GPIO_FN(PORT201_KEYIN1), GPIO_FN(VIO_DR1),
+ GPIO_FN(D17),
+ GPIO_FN(LCDD10), GPIO_FN(PORT202_KEYIN2), GPIO_FN(VIO_DR2),
+ GPIO_FN(D18),
+ GPIO_FN(LCDD11), GPIO_FN(PORT203_KEYIN3), GPIO_FN(VIO_DR3),
+ GPIO_FN(D19),
+ GPIO_FN(LCDD12), GPIO_FN(PORT204_KEYIN4), GPIO_FN(VIO_DR4),
+ GPIO_FN(D20),
+ GPIO_FN(LCDD13), GPIO_FN(PORT205_KEYIN5), GPIO_FN(VIO_DR5),
+ GPIO_FN(D21),
+ GPIO_FN(LCDD14), GPIO_FN(PORT206_KEYIN6), GPIO_FN(VIO_DR6),
+ GPIO_FN(D22),
+ GPIO_FN(LCDD15), GPIO_FN(PORT207_MSIOF0L_SS1), GPIO_FN(PORT207_KEYOUT0),
+ GPIO_FN(VIO_DR7), GPIO_FN(D23),
+ GPIO_FN(LCDD16), GPIO_FN(PORT208_MSIOF0L_SS2), GPIO_FN(PORT208_KEYOUT1),
+ GPIO_FN(VIO_VDR), GPIO_FN(D24),
+ GPIO_FN(LCDD17), GPIO_FN(PORT209_KEYOUT2), GPIO_FN(VIO_HDR),
+ GPIO_FN(D25),
+ GPIO_FN(LCDD18), GPIO_FN(DREQ2), GPIO_FN(PORT210_MSIOF0L_SS1),
+ GPIO_FN(D26),
+ GPIO_FN(LCDD19), GPIO_FN(PORT211_MSIOF0L_SS2), GPIO_FN(D27),
+ GPIO_FN(LCDD20), GPIO_FN(TS_SPSYNC1), GPIO_FN(MSIOF0L_MCK0),
+ GPIO_FN(D28),
+ GPIO_FN(LCDD21), GPIO_FN(TS_SDAT1), GPIO_FN(MSIOF0L_MCK1),
+ GPIO_FN(D29),
+ GPIO_FN(LCDD22), GPIO_FN(TS_SDEN1), GPIO_FN(MSIOF0L_RSCK),
+ GPIO_FN(D30),
+ GPIO_FN(LCDD23), GPIO_FN(TS_SCK1), GPIO_FN(MSIOF0L_RSYNC),
+ GPIO_FN(D31),
+ GPIO_FN(LCDDCK), GPIO_FN(LCDWR), GPIO_FN(PORT216_KEYOUT3),
+ GPIO_FN(VIO_CLKR),
+ GPIO_FN(LCDRD), GPIO_FN(DACK2), GPIO_FN(MSIOF0L_TSYNC),
+ GPIO_FN(LCDHSYN), GPIO_FN(LCDCS), GPIO_FN(LCDCS2), GPIO_FN(DACK3),
+ GPIO_FN(PORT218_VIO_CKOR), GPIO_FN(PORT218_KEYOUT4),
+ GPIO_FN(LCDDISP), GPIO_FN(LCDRS), GPIO_FN(DREQ3), GPIO_FN(MSIOF0L_TSCK),
+ GPIO_FN(LCDVSYN), GPIO_FN(LCDVSYN2), GPIO_FN(PORT220_KEYOUT5),
+ GPIO_FN(LCDLCLK), GPIO_FN(DREQ1), GPIO_FN(PWEN), GPIO_FN(MSIOF0L_RXD),
+ GPIO_FN(LCDDON), GPIO_FN(LCDDON2), GPIO_FN(DACK1), GPIO_FN(OVCN),
+ GPIO_FN(MSIOF0L_TXD),
+ GPIO_FN(SCIFA1_TXD), GPIO_FN(OVCN2),
+ GPIO_FN(EXTLP), GPIO_FN(SCIFA1_SCK), GPIO_FN(USBTERM),
+ GPIO_FN(PORT226_VIO_CKO2),
+ GPIO_FN(SCIFA1_RTS), GPIO_FN(IDIN),
+ GPIO_FN(SCIFA1_RXD),
+ GPIO_FN(SCIFA1_CTS), GPIO_FN(MFG1_IN1),
+ GPIO_FN(MSIOF1_TXD), GPIO_FN(SCIFA2_TXD2), GPIO_FN(PORT230_FSIAOMC),
+ GPIO_FN(MSIOF1_TSYNC), GPIO_FN(SCIFA2_CTS2), GPIO_FN(PORT231_FSIAOLR),
+ GPIO_FN(MSIOF1_TSCK), GPIO_FN(SCIFA2_SCK2), GPIO_FN(PORT232_FSIAOBT),
+ GPIO_FN(MSIOF1_RXD), GPIO_FN(SCIFA2_RXD2), GPIO_FN(GPS_VCOTRIG),
+ GPIO_FN(PORT233_FSIACK),
+ GPIO_FN(MSIOF1_RSCK), GPIO_FN(SCIFA2_RTS2), GPIO_FN(PORT234_FSIAOSLD),
+ GPIO_FN(MSIOF1_RSYNC), GPIO_FN(OPORT0), GPIO_FN(MFG1_IN2),
+ GPIO_FN(PORT235_FSIAILR),
+ GPIO_FN(MSIOF1_MCK0), GPIO_FN(I2C_SDA2), GPIO_FN(PORT236_FSIAIBT),
+ GPIO_FN(MSIOF1_MCK1), GPIO_FN(I2C_SCL2), GPIO_FN(PORT237_FSIAISLD),
+ GPIO_FN(MSIOF1_SS1), GPIO_FN(EDBGREQ3),
+
+ /* 55-5 (FN) */
+ GPIO_FN(MSIOF1_SS2),
+ GPIO_FN(SCIFA6_TXD),
+ GPIO_FN(PORT241_IRDA_OUT), GPIO_FN(PORT241_IROUT), GPIO_FN(MFG4_OUT1),
+ GPIO_FN(TPU4TO0),
+ GPIO_FN(PORT242_IRDA_IN), GPIO_FN(MFG4_IN2),
+ GPIO_FN(PORT243_IRDA_FIRSEL), GPIO_FN(PORT243_VIO_CKO2),
+ GPIO_FN(PORT244_SCIFA5_CTS), GPIO_FN(MFG2_IN1),
+ GPIO_FN(PORT244_SCIFB_CTS),
+ GPIO_FN(PORT245_SCIFA5_RTS), GPIO_FN(MFG2_IN2),
+ GPIO_FN(PORT245_SCIFB_RTS),
+ GPIO_FN(PORT246_SCIFA5_RXD), GPIO_FN(MFG1_OUT1),
+ GPIO_FN(PORT246_SCIFB_RXD), GPIO_FN(TPU1TO0),
+ GPIO_FN(PORT247_SCIFA5_TXD), GPIO_FN(MFG3_OUT2),
+ GPIO_FN(PORT247_SCIFB_TXD), GPIO_FN(TPU3TO1),
+ GPIO_FN(PORT248_SCIFA5_SCK), GPIO_FN(MFG2_OUT1),
+ GPIO_FN(PORT248_SCIFB_SCK), GPIO_FN(TPU2TO0),
+ GPIO_FN(PORT249_IROUT), GPIO_FN(MFG4_IN1),
+ GPIO_FN(SDHICLK0), GPIO_FN(TCK2_SWCLK_MC0),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0), GPIO_FN(TMS2_SWDIO_MC0),
+ GPIO_FN(SDHID0_1), GPIO_FN(TDO2_SWO0_MC0),
+ GPIO_FN(SDHID0_2), GPIO_FN(TDI2),
+ GPIO_FN(SDHID0_3), GPIO_FN(RTCK2_SWO1_MC0),
+ GPIO_FN(SDHICMD0), GPIO_FN(TRST2),
+ GPIO_FN(SDHIWP0), GPIO_FN(EDBGREQ2),
+ GPIO_FN(SDHICLK1), GPIO_FN(TCK3_SWCLK_MC1),
+ GPIO_FN(SDHID1_0), GPIO_FN(M11_SLCD_SO2), GPIO_FN(TS_SPSYNC2),
+ GPIO_FN(TMS3_SWDIO_MC1),
+ GPIO_FN(SDHID1_1), GPIO_FN(M9_SLCD_A02), GPIO_FN(TS_SDAT2),
+ GPIO_FN(TDO3_SWO0_MC1),
+ GPIO_FN(SDHID1_2), GPIO_FN(M10_SLCD_CK2), GPIO_FN(TS_SDEN2),
+ GPIO_FN(TDI3),
+ GPIO_FN(SDHID1_3), GPIO_FN(M12_SLCD_CE2), GPIO_FN(TS_SCK2),
+ GPIO_FN(RTCK3_SWO1_MC1),
+ GPIO_FN(SDHICMD1), GPIO_FN(TRST3),
+ GPIO_FN(RESETOUTS),
+};
+
+/* helper for top 4 bits in PORTnCR */
+#define PCRH(in, in_pd, in_pu, out) \
+ 0, (out), (in), 0, \
+ 0, 0, 0, 0, \
+ 0, 0, (in_pd), 0, \
+ 0, 0, (in_pu), 0
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ PCRH(PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU, PORT##nr##_OUT), \
+ PORT##nr##_FN0, PORT##nr##_FN1, \
+ PORT##nr##_FN2, PORT##nr##_FN3, \
+ PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6050020), /* PORT32CR */
+ PORTCR(33, 0xe6050021), /* PORT33CR */
+ PORTCR(34, 0xe6050022), /* PORT34CR */
+ PORTCR(35, 0xe6050023), /* PORT35CR */
+ PORTCR(36, 0xe6050024), /* PORT36CR */
+ PORTCR(37, 0xe6050025), /* PORT37CR */
+ PORTCR(38, 0xe6050026), /* PORT38CR */
+ PORTCR(39, 0xe6050027), /* PORT39CR */
+
+ PORTCR(40, 0xe6050028), /* PORT40CR */
+ PORTCR(41, 0xe6050029), /* PORT41CR */
+ PORTCR(42, 0xe605002a), /* PORT42CR */
+ PORTCR(43, 0xe605002b), /* PORT43CR */
+ PORTCR(44, 0xe605002c), /* PORT44CR */
+ PORTCR(45, 0xe605002d), /* PORT45CR */
+ PORTCR(46, 0xe605002e), /* PORT46CR */
+ PORTCR(47, 0xe605002f), /* PORT47CR */
+ PORTCR(48, 0xe6050030), /* PORT48CR */
+ PORTCR(49, 0xe6050031), /* PORT49CR */
+
+ PORTCR(50, 0xe6050032), /* PORT50CR */
+ PORTCR(51, 0xe6050033), /* PORT51CR */
+ PORTCR(52, 0xe6050034), /* PORT52CR */
+ PORTCR(53, 0xe6050035), /* PORT53CR */
+ PORTCR(54, 0xe6050036), /* PORT54CR */
+ PORTCR(55, 0xe6050037), /* PORT55CR */
+ PORTCR(56, 0xe6050038), /* PORT56CR */
+ PORTCR(57, 0xe6050039), /* PORT57CR */
+ PORTCR(58, 0xe605003a), /* PORT58CR */
+ PORTCR(59, 0xe605003b), /* PORT59CR */
+
+ PORTCR(60, 0xe605003c), /* PORT60CR */
+ PORTCR(61, 0xe605003d), /* PORT61CR */
+ PORTCR(62, 0xe605003e), /* PORT62CR */
+ PORTCR(63, 0xe605003f), /* PORT63CR */
+ PORTCR(64, 0xe6050040), /* PORT64CR */
+ PORTCR(65, 0xe6050041), /* PORT65CR */
+ PORTCR(66, 0xe6050042), /* PORT66CR */
+ PORTCR(67, 0xe6050043), /* PORT67CR */
+ PORTCR(68, 0xe6050044), /* PORT68CR */
+ PORTCR(69, 0xe6050045), /* PORT69CR */
+
+ PORTCR(70, 0xe6050046), /* PORT70CR */
+ PORTCR(71, 0xe6050047), /* PORT71CR */
+ PORTCR(72, 0xe6050048), /* PORT72CR */
+ PORTCR(73, 0xe6050049), /* PORT73CR */
+ PORTCR(74, 0xe605004a), /* PORT74CR */
+ PORTCR(75, 0xe605004b), /* PORT75CR */
+ PORTCR(76, 0xe605004c), /* PORT76CR */
+ PORTCR(77, 0xe605004d), /* PORT77CR */
+ PORTCR(78, 0xe605004e), /* PORT78CR */
+ PORTCR(79, 0xe605004f), /* PORT79CR */
+
+ PORTCR(80, 0xe6050050), /* PORT80CR */
+ PORTCR(81, 0xe6050051), /* PORT81CR */
+ PORTCR(82, 0xe6050052), /* PORT82CR */
+ PORTCR(83, 0xe6050053), /* PORT83CR */
+ PORTCR(84, 0xe6050054), /* PORT84CR */
+ PORTCR(85, 0xe6050055), /* PORT85CR */
+ PORTCR(86, 0xe6050056), /* PORT86CR */
+ PORTCR(87, 0xe6050057), /* PORT87CR */
+ PORTCR(88, 0xe6050058), /* PORT88CR */
+ PORTCR(89, 0xe6050059), /* PORT89CR */
+
+ PORTCR(90, 0xe605005a), /* PORT90CR */
+ PORTCR(91, 0xe605005b), /* PORT91CR */
+ PORTCR(92, 0xe605005c), /* PORT92CR */
+ PORTCR(93, 0xe605005d), /* PORT93CR */
+ PORTCR(94, 0xe605005e), /* PORT94CR */
+ PORTCR(95, 0xe605005f), /* PORT95CR */
+ PORTCR(96, 0xe6050060), /* PORT96CR */
+ PORTCR(97, 0xe6050061), /* PORT97CR */
+ PORTCR(98, 0xe6050062), /* PORT98CR */
+ PORTCR(99, 0xe6050063), /* PORT99CR */
+
+ PORTCR(100, 0xe6050064), /* PORT100CR */
+ PORTCR(101, 0xe6050065), /* PORT101CR */
+ PORTCR(102, 0xe6050066), /* PORT102CR */
+ PORTCR(103, 0xe6050067), /* PORT103CR */
+ PORTCR(104, 0xe6050068), /* PORT104CR */
+ PORTCR(105, 0xe6050069), /* PORT105CR */
+ PORTCR(106, 0xe605006a), /* PORT106CR */
+ PORTCR(107, 0xe605006b), /* PORT107CR */
+ PORTCR(108, 0xe605006c), /* PORT108CR */
+ PORTCR(109, 0xe605006d), /* PORT109CR */
+
+ PORTCR(110, 0xe605006e), /* PORT110CR */
+ PORTCR(111, 0xe605006f), /* PORT111CR */
+ PORTCR(112, 0xe6050070), /* PORT112CR */
+ PORTCR(113, 0xe6050071), /* PORT113CR */
+ PORTCR(114, 0xe6050072), /* PORT114CR */
+ PORTCR(115, 0xe6050073), /* PORT115CR */
+ PORTCR(116, 0xe6050074), /* PORT116CR */
+ PORTCR(117, 0xe6050075), /* PORT117CR */
+ PORTCR(118, 0xe6050076), /* PORT118CR */
+
+ PORTCR(128, 0xe6051080), /* PORT128CR */
+ PORTCR(129, 0xe6051081), /* PORT129CR */
+
+ PORTCR(130, 0xe6051082), /* PORT130CR */
+ PORTCR(131, 0xe6051083), /* PORT131CR */
+ PORTCR(132, 0xe6051084), /* PORT132CR */
+ PORTCR(133, 0xe6051085), /* PORT133CR */
+ PORTCR(134, 0xe6051086), /* PORT134CR */
+ PORTCR(135, 0xe6051087), /* PORT135CR */
+ PORTCR(136, 0xe6051088), /* PORT136CR */
+ PORTCR(137, 0xe6051089), /* PORT137CR */
+ PORTCR(138, 0xe605108a), /* PORT138CR */
+ PORTCR(139, 0xe605108b), /* PORT139CR */
+
+ PORTCR(140, 0xe605108c), /* PORT140CR */
+ PORTCR(141, 0xe605108d), /* PORT141CR */
+ PORTCR(142, 0xe605108e), /* PORT142CR */
+ PORTCR(143, 0xe605108f), /* PORT143CR */
+ PORTCR(144, 0xe6051090), /* PORT144CR */
+ PORTCR(145, 0xe6051091), /* PORT145CR */
+ PORTCR(146, 0xe6051092), /* PORT146CR */
+ PORTCR(147, 0xe6051093), /* PORT147CR */
+ PORTCR(148, 0xe6051094), /* PORT148CR */
+ PORTCR(149, 0xe6051095), /* PORT149CR */
+
+ PORTCR(150, 0xe6051096), /* PORT150CR */
+ PORTCR(151, 0xe6051097), /* PORT151CR */
+ PORTCR(152, 0xe6051098), /* PORT152CR */
+ PORTCR(153, 0xe6051099), /* PORT153CR */
+ PORTCR(154, 0xe605109a), /* PORT154CR */
+ PORTCR(155, 0xe605109b), /* PORT155CR */
+ PORTCR(156, 0xe605109c), /* PORT156CR */
+ PORTCR(157, 0xe605109d), /* PORT157CR */
+ PORTCR(158, 0xe605109e), /* PORT158CR */
+ PORTCR(159, 0xe605109f), /* PORT159CR */
+
+ PORTCR(160, 0xe60510a0), /* PORT160CR */
+ PORTCR(161, 0xe60510a1), /* PORT161CR */
+ PORTCR(162, 0xe60510a2), /* PORT162CR */
+ PORTCR(163, 0xe60510a3), /* PORT163CR */
+ PORTCR(164, 0xe60510a4), /* PORT164CR */
+
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60520d2), /* PORT210CR */
+ PORTCR(211, 0xe60520d3), /* PORT211CR */
+ PORTCR(212, 0xe60520d4), /* PORT212CR */
+ PORTCR(213, 0xe60520d5), /* PORT213CR */
+ PORTCR(214, 0xe60520d6), /* PORT214CR */
+ PORTCR(215, 0xe60520d7), /* PORT215CR */
+ PORTCR(216, 0xe60520d8), /* PORT216CR */
+ PORTCR(217, 0xe60520d9), /* PORT217CR */
+ PORTCR(218, 0xe60520da), /* PORT218CR */
+ PORTCR(219, 0xe60520db), /* PORT219CR */
+
+ PORTCR(220, 0xe60520dc), /* PORT220CR */
+ PORTCR(221, 0xe60520dd), /* PORT221CR */
+ PORTCR(222, 0xe60520de), /* PORT222CR */
+ PORTCR(223, 0xe60520df), /* PORT223CR */
+ PORTCR(224, 0xe60520e0), /* PORT224CR */
+ PORTCR(225, 0xe60520e1), /* PORT225CR */
+ PORTCR(226, 0xe60520e2), /* PORT226CR */
+ PORTCR(227, 0xe60520e3), /* PORT227CR */
+ PORTCR(228, 0xe60520e4), /* PORT228CR */
+ PORTCR(229, 0xe60520e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60520e6), /* PORT230CR */
+ PORTCR(231, 0xe60520e7), /* PORT231CR */
+ PORTCR(232, 0xe60520e8), /* PORT232CR */
+ PORTCR(233, 0xe60520e9), /* PORT233CR */
+ PORTCR(234, 0xe60520ea), /* PORT234CR */
+ PORTCR(235, 0xe60520eb), /* PORT235CR */
+ PORTCR(236, 0xe60520ec), /* PORT236CR */
+ PORTCR(237, 0xe60520ed), /* PORT237CR */
+ PORTCR(238, 0xe60520ee), /* PORT238CR */
+ PORTCR(239, 0xe60520ef), /* PORT239CR */
+
+ PORTCR(240, 0xe60520f0), /* PORT240CR */
+ PORTCR(241, 0xe60520f1), /* PORT241CR */
+ PORTCR(242, 0xe60520f2), /* PORT242CR */
+ PORTCR(243, 0xe60520f3), /* PORT243CR */
+ PORTCR(244, 0xe60520f4), /* PORT244CR */
+ PORTCR(245, 0xe60520f5), /* PORT245CR */
+ PORTCR(246, 0xe60520f6), /* PORT246CR */
+ PORTCR(247, 0xe60520f7), /* PORT247CR */
+ PORTCR(248, 0xe60520f8), /* PORT248CR */
+ PORTCR(249, 0xe60520f9), /* PORT249CR */
+
+ PORTCR(250, 0xe60520fa), /* PORT250CR */
+ PORTCR(251, 0xe60520fb), /* PORT251CR */
+ PORTCR(252, 0xe60520fc), /* PORT252CR */
+ PORTCR(253, 0xe60520fd), /* PORT253CR */
+ PORTCR(254, 0xe60520fe), /* PORT254CR */
+ PORTCR(255, 0xe60520ff), /* PORT255CR */
+ PORTCR(256, 0xe6052100), /* PORT256CR */
+ PORTCR(257, 0xe6052101), /* PORT257CR */
+ PORTCR(258, 0xe6052102), /* PORT258CR */
+ PORTCR(259, 0xe6052103), /* PORT259CR */
+
+ PORTCR(260, 0xe6052104), /* PORT260CR */
+ PORTCR(261, 0xe6052105), /* PORT261CR */
+ PORTCR(262, 0xe6052106), /* PORT262CR */
+ PORTCR(263, 0xe6052107), /* PORT263CR */
+ PORTCR(264, 0xe6052108), /* PORT264CR */
+
+ { PINMUX_CFG_REG("MSELBCR", 0xe6058024, 32, 1) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ MSELBCR_MSEL17_0, MSELBCR_MSEL17_1,
+ MSELBCR_MSEL16_0, MSELBCR_MSEL16_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL063_032DR", 0xe6054004, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTL095_064DR", 0xe6054008, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD127_096DR", 0xe605400C, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD159_128DR", 0xe6055000, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6055004, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe6056000, 32) {
+ PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+ PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+ PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+ PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU255_224DR", 0xe6056004, 32) {
+ PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+ PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+ PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+ PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+ PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+ PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+ PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+ PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU287_256DR", 0xe6056008, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT264_DATA,
+ PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+ PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7377_pinmux_info = {
+ .name = "sh7377_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_RESETOUTS,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh7377_pinmux_init(void)
+{
+ register_pinmux(&sh7377_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/pfc-sh73a0.c b/arch/arm/mach-shmobile/pfc-sh73a0.c
new file mode 100644
index 00000000..3eed44eb
--- /dev/null
+++ b/arch/arm/mach-shmobile/pfc-sh73a0.c
@@ -0,0 +1,2746 @@
+/*
+ * sh73a0 processor support - PFC hardware block
+ *
+ * Copyright (C) 2010 Renesas Solutions Corp.
+ * Copyright (C) 2010 NISHIMOTO Hiroki
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/sh73a0.h>
+
+#define _1(fn, pfx, sfx) fn(pfx, sfx)
+
+#define _10(fn, pfx, sfx) \
+ _1(fn, pfx##0, sfx), _1(fn, pfx##1, sfx), \
+ _1(fn, pfx##2, sfx), _1(fn, pfx##3, sfx), \
+ _1(fn, pfx##4, sfx), _1(fn, pfx##5, sfx), \
+ _1(fn, pfx##6, sfx), _1(fn, pfx##7, sfx), \
+ _1(fn, pfx##8, sfx), _1(fn, pfx##9, sfx)
+
+#define _310(fn, pfx, sfx) \
+ _10(fn, pfx, sfx), _10(fn, pfx##1, sfx), \
+ _10(fn, pfx##2, sfx), _10(fn, pfx##3, sfx), \
+ _10(fn, pfx##4, sfx), _10(fn, pfx##5, sfx), \
+ _10(fn, pfx##6, sfx), _10(fn, pfx##7, sfx), \
+ _10(fn, pfx##8, sfx), _10(fn, pfx##9, sfx), \
+ _10(fn, pfx##10, sfx), \
+ _1(fn, pfx##110, sfx), _1(fn, pfx##111, sfx), \
+ _1(fn, pfx##112, sfx), _1(fn, pfx##113, sfx), \
+ _1(fn, pfx##114, sfx), _1(fn, pfx##115, sfx), \
+ _1(fn, pfx##116, sfx), _1(fn, pfx##117, sfx), \
+ _1(fn, pfx##118, sfx), \
+ _1(fn, pfx##128, sfx), _1(fn, pfx##129, sfx), \
+ _10(fn, pfx##13, sfx), _10(fn, pfx##14, sfx), \
+ _10(fn, pfx##15, sfx), \
+ _1(fn, pfx##160, sfx), _1(fn, pfx##161, sfx), \
+ _1(fn, pfx##162, sfx), _1(fn, pfx##163, sfx), \
+ _1(fn, pfx##164, sfx), \
+ _1(fn, pfx##192, sfx), _1(fn, pfx##193, sfx), \
+ _1(fn, pfx##194, sfx), _1(fn, pfx##195, sfx), \
+ _1(fn, pfx##196, sfx), _1(fn, pfx##197, sfx), \
+ _1(fn, pfx##198, sfx), _1(fn, pfx##199, sfx), \
+ _10(fn, pfx##20, sfx), _10(fn, pfx##21, sfx), \
+ _10(fn, pfx##22, sfx), _10(fn, pfx##23, sfx), \
+ _10(fn, pfx##24, sfx), _10(fn, pfx##25, sfx), \
+ _10(fn, pfx##26, sfx), _10(fn, pfx##27, sfx), \
+ _1(fn, pfx##280, sfx), _1(fn, pfx##281, sfx), \
+ _1(fn, pfx##282, sfx), \
+ _1(fn, pfx##288, sfx), _1(fn, pfx##289, sfx), \
+ _10(fn, pfx##29, sfx), _10(fn, pfx##30, sfx)
+
+#define _PORT(pfx, sfx) pfx##_##sfx
+#define PORT_310(str) _310(_PORT, PORT, str)
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PORT_310(DATA), /* PORT0_DATA -> PORT309_DATA */
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PORT_310(IN), /* PORT0_IN -> PORT309_IN */
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PORT_310(IN_PU), /* PORT0_IN_PU -> PORT309_IN_PU */
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PORT_310(IN_PD), /* PORT0_IN_PD -> PORT309_IN_PD */
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PORT_310(OUT), /* PORT0_OUT -> PORT309_OUT */
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PORT_310(FN_IN), /* PORT0_FN_IN -> PORT309_FN_IN */
+ PORT_310(FN_OUT), /* PORT0_FN_OUT -> PORT309_FN_OUT */
+ PORT_310(FN0), /* PORT0_FN0 -> PORT309_FN0 */
+ PORT_310(FN1), /* PORT0_FN1 -> PORT309_FN1 */
+ PORT_310(FN2), /* PORT0_FN2 -> PORT309_FN2 */
+ PORT_310(FN3), /* PORT0_FN3 -> PORT309_FN3 */
+ PORT_310(FN4), /* PORT0_FN4 -> PORT309_FN4 */
+ PORT_310(FN5), /* PORT0_FN5 -> PORT309_FN5 */
+ PORT_310(FN6), /* PORT0_FN6 -> PORT309_FN6 */
+ PORT_310(FN7), /* PORT0_FN7 -> PORT309_FN7 */
+
+ MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
+ MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
+ MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1,
+ MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1,
+ MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1,
+ MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1,
+ MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1,
+ MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1,
+ MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1,
+ MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1,
+ MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1,
+ MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1,
+ MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1,
+ MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1,
+ MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_1,
+ MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1,
+ MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1,
+ MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1,
+ MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1,
+ MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1,
+ MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1,
+ MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1,
+ MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1,
+ MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1,
+ MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1,
+ MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1,
+ MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1,
+ MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1,
+ MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1,
+ MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1,
+ MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1,
+ MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1,
+ MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1,
+ MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1,
+ MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1,
+ MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ /* Hardware manual Table 25-1 (Function 0-7) */
+ VBUS_0_MARK,
+ GPI0_MARK,
+ GPI1_MARK,
+ GPI2_MARK,
+ GPI3_MARK,
+ GPI4_MARK,
+ GPI5_MARK,
+ GPI6_MARK,
+ GPI7_MARK,
+ SCIFA7_RXD_MARK,
+ SCIFA7_CTS__MARK,
+ GPO7_MARK, MFG0_OUT2_MARK,
+ GPO6_MARK, MFG1_OUT2_MARK,
+ GPO5_MARK, SCIFA0_SCK_MARK, FSICOSLDT3_MARK, PORT16_VIO_CKOR_MARK,
+ SCIFA0_TXD_MARK,
+ SCIFA7_TXD_MARK,
+ SCIFA7_RTS__MARK, PORT19_VIO_CKO2_MARK,
+ GPO0_MARK,
+ GPO1_MARK,
+ GPO2_MARK, STATUS0_MARK,
+ GPO3_MARK, STATUS1_MARK,
+ GPO4_MARK, STATUS2_MARK,
+ VINT_MARK,
+ TCKON_MARK,
+ XDVFS1_MARK, PORT27_I2C_SCL2_MARK, PORT27_I2C_SCL3_MARK, \
+ MFG0_OUT1_MARK, PORT27_IROUT_MARK,
+ XDVFS2_MARK, PORT28_I2C_SDA2_MARK, PORT28_I2C_SDA3_MARK, \
+ PORT28_TPU1TO1_MARK,
+ SIM_RST_MARK, PORT29_TPU1TO1_MARK,
+ SIM_CLK_MARK, PORT30_VIO_CKOR_MARK,
+ SIM_D_MARK, PORT31_IROUT_MARK,
+ SCIFA4_TXD_MARK,
+ SCIFA4_RXD_MARK, XWUP_MARK,
+ SCIFA4_RTS__MARK,
+ SCIFA4_CTS__MARK,
+ FSIBOBT_MARK, FSIBIBT_MARK,
+ FSIBOLR_MARK, FSIBILR_MARK,
+ FSIBOSLD_MARK,
+ FSIBISLD_MARK,
+ VACK_MARK,
+ XTAL1L_MARK,
+ SCIFA0_RTS__MARK, FSICOSLDT2_MARK,
+ SCIFA0_RXD_MARK,
+ SCIFA0_CTS__MARK, FSICOSLDT1_MARK,
+ FSICOBT_MARK, FSICIBT_MARK, FSIDOBT_MARK, FSIDIBT_MARK,
+ FSICOLR_MARK, FSICILR_MARK, FSIDOLR_MARK, FSIDILR_MARK,
+ FSICOSLD_MARK, PORT47_FSICSPDIF_MARK,
+ FSICISLD_MARK, FSIDISLD_MARK,
+ FSIACK_MARK, PORT49_IRDA_OUT_MARK, PORT49_IROUT_MARK, FSIAOMC_MARK,
+ FSIAOLR_MARK, BBIF2_TSYNC2_MARK, TPU2TO2_MARK, FSIAILR_MARK,
+
+ FSIAOBT_MARK, BBIF2_TSCK2_MARK, TPU2TO3_MARK, FSIAIBT_MARK,
+ FSIAOSLD_MARK, BBIF2_TXD2_MARK,
+ FSIASPDIF_MARK, PORT53_IRDA_IN_MARK, TPU3TO3_MARK, FSIBSPDIF_MARK, \
+ PORT53_FSICSPDIF_MARK,
+ FSIBCK_MARK, PORT54_IRDA_FIRSEL_MARK, TPU3TO2_MARK, FSIBOMC_MARK, \
+ FSICCK_MARK, FSICOMC_MARK,
+ FSIAISLD_MARK, TPU0TO0_MARK,
+ A0_MARK, BS__MARK,
+ A12_MARK, PORT58_KEYOUT7_MARK, TPU4TO2_MARK,
+ A13_MARK, PORT59_KEYOUT6_MARK, TPU0TO1_MARK,
+ A14_MARK, KEYOUT5_MARK,
+ A15_MARK, KEYOUT4_MARK,
+ A16_MARK, KEYOUT3_MARK, MSIOF0_SS1_MARK,
+ A17_MARK, KEYOUT2_MARK, MSIOF0_TSYNC_MARK,
+ A18_MARK, KEYOUT1_MARK, MSIOF0_TSCK_MARK,
+ A19_MARK, KEYOUT0_MARK, MSIOF0_TXD_MARK,
+ A20_MARK, KEYIN0_MARK, MSIOF0_RSCK_MARK,
+ A21_MARK, KEYIN1_MARK, MSIOF0_RSYNC_MARK,
+ A22_MARK, KEYIN2_MARK, MSIOF0_MCK0_MARK,
+ A23_MARK, KEYIN3_MARK, MSIOF0_MCK1_MARK,
+ A24_MARK, KEYIN4_MARK, MSIOF0_RXD_MARK,
+ A25_MARK, KEYIN5_MARK, MSIOF0_SS2_MARK,
+ A26_MARK, KEYIN6_MARK,
+ KEYIN7_MARK,
+ D0_NAF0_MARK,
+ D1_NAF1_MARK,
+ D2_NAF2_MARK,
+ D3_NAF3_MARK,
+ D4_NAF4_MARK,
+ D5_NAF5_MARK,
+ D6_NAF6_MARK,
+ D7_NAF7_MARK,
+ D8_NAF8_MARK,
+ D9_NAF9_MARK,
+ D10_NAF10_MARK,
+ D11_NAF11_MARK,
+ D12_NAF12_MARK,
+ D13_NAF13_MARK,
+ D14_NAF14_MARK,
+ D15_NAF15_MARK,
+ CS4__MARK,
+ CS5A__MARK, PORT91_RDWR_MARK,
+ CS5B__MARK, FCE1__MARK,
+ CS6B__MARK, DACK0_MARK,
+ FCE0__MARK, CS6A__MARK,
+ WAIT__MARK, DREQ0_MARK,
+ RD__FSC_MARK,
+ WE0__FWE_MARK, RDWR_FWE_MARK,
+ WE1__MARK,
+ FRB_MARK,
+ CKO_MARK,
+ NBRSTOUT__MARK,
+ NBRST__MARK,
+ BBIF2_TXD_MARK,
+ BBIF2_RXD_MARK,
+ BBIF2_SYNC_MARK,
+ BBIF2_SCK_MARK,
+ SCIFA3_CTS__MARK, MFG3_IN2_MARK,
+ SCIFA3_RXD_MARK, MFG3_IN1_MARK,
+ BBIF1_SS2_MARK, SCIFA3_RTS__MARK, MFG3_OUT1_MARK,
+ SCIFA3_TXD_MARK,
+ HSI_RX_DATA_MARK, BBIF1_RXD_MARK,
+ HSI_TX_WAKE_MARK, BBIF1_TSCK_MARK,
+ HSI_TX_DATA_MARK, BBIF1_TSYNC_MARK,
+ HSI_TX_READY_MARK, BBIF1_TXD_MARK,
+ HSI_RX_READY_MARK, BBIF1_RSCK_MARK, PORT115_I2C_SCL2_MARK, \
+ PORT115_I2C_SCL3_MARK,
+ HSI_RX_WAKE_MARK, BBIF1_RSYNC_MARK, PORT116_I2C_SDA2_MARK, \
+ PORT116_I2C_SDA3_MARK,
+ HSI_RX_FLAG_MARK, BBIF1_SS1_MARK, BBIF1_FLOW_MARK,
+ HSI_TX_FLAG_MARK,
+ VIO_VD_MARK, PORT128_LCD2VSYN_MARK, VIO2_VD_MARK, LCD2D0_MARK,
+
+ VIO_HD_MARK, PORT129_LCD2HSYN_MARK, PORT129_LCD2CS__MARK, \
+ VIO2_HD_MARK, LCD2D1_MARK,
+ VIO_D0_MARK, PORT130_MSIOF2_RXD_MARK, LCD2D10_MARK,
+ VIO_D1_MARK, PORT131_KEYOUT6_MARK, PORT131_MSIOF2_SS1_MARK, \
+ PORT131_KEYOUT11_MARK, LCD2D11_MARK,
+ VIO_D2_MARK, PORT132_KEYOUT7_MARK, PORT132_MSIOF2_SS2_MARK, \
+ PORT132_KEYOUT10_MARK, LCD2D12_MARK,
+ VIO_D3_MARK, MSIOF2_TSYNC_MARK, LCD2D13_MARK,
+ VIO_D4_MARK, MSIOF2_TXD_MARK, LCD2D14_MARK,
+ VIO_D5_MARK, MSIOF2_TSCK_MARK, LCD2D15_MARK,
+ VIO_D6_MARK, PORT136_KEYOUT8_MARK, LCD2D16_MARK,
+ VIO_D7_MARK, PORT137_KEYOUT9_MARK, LCD2D17_MARK,
+ VIO_D8_MARK, PORT138_KEYOUT8_MARK, VIO2_D0_MARK, LCD2D6_MARK,
+ VIO_D9_MARK, PORT139_KEYOUT9_MARK, VIO2_D1_MARK, LCD2D7_MARK,
+ VIO_D10_MARK, TPU0TO2_MARK, VIO2_D2_MARK, LCD2D8_MARK,
+ VIO_D11_MARK, TPU0TO3_MARK, VIO2_D3_MARK, LCD2D9_MARK,
+ VIO_D12_MARK, PORT142_KEYOUT10_MARK, VIO2_D4_MARK, LCD2D2_MARK,
+ VIO_D13_MARK, PORT143_KEYOUT11_MARK, PORT143_KEYOUT6_MARK, \
+ VIO2_D5_MARK, LCD2D3_MARK,
+ VIO_D14_MARK, PORT144_KEYOUT7_MARK, VIO2_D6_MARK, LCD2D4_MARK,
+ VIO_D15_MARK, TPU1TO3_MARK, PORT145_LCD2DISP_MARK, \
+ PORT145_LCD2RS_MARK, VIO2_D7_MARK, LCD2D5_MARK,
+ VIO_CLK_MARK, LCD2DCK_MARK, PORT146_LCD2WR__MARK, VIO2_CLK_MARK, \
+ LCD2D18_MARK,
+ VIO_FIELD_MARK, LCD2RD__MARK, VIO2_FIELD_MARK, LCD2D19_MARK,
+ VIO_CKO_MARK,
+ A27_MARK, PORT149_RDWR_MARK, MFG0_IN1_MARK, PORT149_KEYOUT9_MARK,
+ MFG0_IN2_MARK,
+ TS_SPSYNC3_MARK, MSIOF2_RSCK_MARK,
+ TS_SDAT3_MARK, MSIOF2_RSYNC_MARK,
+ TPU1TO2_MARK, TS_SDEN3_MARK, PORT153_MSIOF2_SS1_MARK,
+ SCIFA2_TXD1_MARK, MSIOF2_MCK0_MARK,
+ SCIFA2_RXD1_MARK, MSIOF2_MCK1_MARK,
+ SCIFA2_RTS1__MARK, PORT156_MSIOF2_SS2_MARK,
+ SCIFA2_CTS1__MARK, PORT157_MSIOF2_RXD_MARK,
+ DINT__MARK, SCIFA2_SCK1_MARK, TS_SCK3_MARK,
+ PORT159_SCIFB_SCK_MARK, PORT159_SCIFA5_SCK_MARK, NMI_MARK,
+ PORT160_SCIFB_TXD_MARK, PORT160_SCIFA5_TXD_MARK,
+ PORT161_SCIFB_CTS__MARK, PORT161_SCIFA5_CTS__MARK,
+ PORT162_SCIFB_RXD_MARK, PORT162_SCIFA5_RXD_MARK,
+ PORT163_SCIFB_RTS__MARK, PORT163_SCIFA5_RTS__MARK, TPU3TO0_MARK,
+ LCDD0_MARK,
+ LCDD1_MARK, PORT193_SCIFA5_CTS__MARK, BBIF2_TSYNC1_MARK,
+ LCDD2_MARK, PORT194_SCIFA5_RTS__MARK, BBIF2_TSCK1_MARK,
+ LCDD3_MARK, PORT195_SCIFA5_RXD_MARK, BBIF2_TXD1_MARK,
+ LCDD4_MARK, PORT196_SCIFA5_TXD_MARK,
+ LCDD5_MARK, PORT197_SCIFA5_SCK_MARK, MFG2_OUT2_MARK, TPU2TO1_MARK,
+ LCDD6_MARK,
+ LCDD7_MARK, TPU4TO1_MARK, MFG4_OUT2_MARK,
+ LCDD8_MARK, D16_MARK,
+ LCDD9_MARK, D17_MARK,
+ LCDD10_MARK, D18_MARK,
+ LCDD11_MARK, D19_MARK,
+ LCDD12_MARK, D20_MARK,
+ LCDD13_MARK, D21_MARK,
+ LCDD14_MARK, D22_MARK,
+ LCDD15_MARK, PORT207_MSIOF0L_SS1_MARK, D23_MARK,
+ LCDD16_MARK, PORT208_MSIOF0L_SS2_MARK, D24_MARK,
+ LCDD17_MARK, D25_MARK,
+ LCDD18_MARK, DREQ2_MARK, PORT210_MSIOF0L_SS1_MARK, D26_MARK,
+ LCDD19_MARK, PORT211_MSIOF0L_SS2_MARK, D27_MARK,
+ LCDD20_MARK, TS_SPSYNC1_MARK, MSIOF0L_MCK0_MARK, D28_MARK,
+ LCDD21_MARK, TS_SDAT1_MARK, MSIOF0L_MCK1_MARK, D29_MARK,
+ LCDD22_MARK, TS_SDEN1_MARK, MSIOF0L_RSCK_MARK, D30_MARK,
+ LCDD23_MARK, TS_SCK1_MARK, MSIOF0L_RSYNC_MARK, D31_MARK,
+ LCDDCK_MARK, LCDWR__MARK,
+ LCDRD__MARK, DACK2_MARK, PORT217_LCD2RS_MARK, MSIOF0L_TSYNC_MARK, \
+ VIO2_FIELD3_MARK, PORT217_LCD2DISP_MARK,
+ LCDHSYN_MARK, LCDCS__MARK, LCDCS2__MARK, DACK3_MARK, \
+ PORT218_VIO_CKOR_MARK,
+ LCDDISP_MARK, LCDRS_MARK, PORT219_LCD2WR__MARK, DREQ3_MARK, \
+ MSIOF0L_TSCK_MARK, VIO2_CLK3_MARK, LCD2DCK_2_MARK,
+ LCDVSYN_MARK, LCDVSYN2_MARK,
+ LCDLCLK_MARK, DREQ1_MARK, PORT221_LCD2CS__MARK, PWEN_MARK, \
+ MSIOF0L_RXD_MARK, VIO2_HD3_MARK, PORT221_LCD2HSYN_MARK,
+ LCDDON_MARK, LCDDON2_MARK, DACK1_MARK, OVCN_MARK, MSIOF0L_TXD_MARK, \
+ VIO2_VD3_MARK, PORT222_LCD2VSYN_MARK,
+
+ SCIFA1_TXD_MARK, OVCN2_MARK,
+ EXTLP_MARK, SCIFA1_SCK_MARK, PORT226_VIO_CKO2_MARK,
+ SCIFA1_RTS__MARK, IDIN_MARK,
+ SCIFA1_RXD_MARK,
+ SCIFA1_CTS__MARK, MFG1_IN1_MARK,
+ MSIOF1_TXD_MARK, SCIFA2_TXD2_MARK,
+ MSIOF1_TSYNC_MARK, SCIFA2_CTS2__MARK,
+ MSIOF1_TSCK_MARK, SCIFA2_SCK2_MARK,
+ MSIOF1_RXD_MARK, SCIFA2_RXD2_MARK,
+ MSIOF1_RSCK_MARK, SCIFA2_RTS2__MARK, VIO2_CLK2_MARK, LCD2D20_MARK,
+ MSIOF1_RSYNC_MARK, MFG1_IN2_MARK, VIO2_VD2_MARK, LCD2D21_MARK,
+ MSIOF1_MCK0_MARK, PORT236_I2C_SDA2_MARK,
+ MSIOF1_MCK1_MARK, PORT237_I2C_SCL2_MARK,
+ MSIOF1_SS1_MARK, VIO2_FIELD2_MARK, LCD2D22_MARK,
+ MSIOF1_SS2_MARK, VIO2_HD2_MARK, LCD2D23_MARK,
+ SCIFA6_TXD_MARK,
+ PORT241_IRDA_OUT_MARK, PORT241_IROUT_MARK, MFG4_OUT1_MARK, TPU4TO0_MARK,
+ PORT242_IRDA_IN_MARK, MFG4_IN2_MARK,
+ PORT243_IRDA_FIRSEL_MARK, PORT243_VIO_CKO2_MARK,
+ PORT244_SCIFA5_CTS__MARK, MFG2_IN1_MARK, PORT244_SCIFB_CTS__MARK, \
+ MSIOF2R_RXD_MARK,
+ PORT245_SCIFA5_RTS__MARK, MFG2_IN2_MARK, PORT245_SCIFB_RTS__MARK, \
+ MSIOF2R_TXD_MARK,
+ PORT246_SCIFA5_RXD_MARK, MFG1_OUT1_MARK, PORT246_SCIFB_RXD_MARK, \
+ TPU1TO0_MARK,
+ PORT247_SCIFA5_TXD_MARK, MFG3_OUT2_MARK, PORT247_SCIFB_TXD_MARK, \
+ TPU3TO1_MARK,
+ PORT248_SCIFA5_SCK_MARK, MFG2_OUT1_MARK, PORT248_SCIFB_SCK_MARK, \
+ TPU2TO0_MARK, PORT248_I2C_SCL3_MARK, MSIOF2R_TSCK_MARK,
+ PORT249_IROUT_MARK, MFG4_IN1_MARK, PORT249_I2C_SDA3_MARK, \
+ MSIOF2R_TSYNC_MARK,
+ SDHICLK0_MARK,
+ SDHICD0_MARK,
+ SDHID0_0_MARK,
+ SDHID0_1_MARK,
+ SDHID0_2_MARK,
+ SDHID0_3_MARK,
+ SDHICMD0_MARK,
+ SDHIWP0_MARK,
+ SDHICLK1_MARK,
+ SDHID1_0_MARK, TS_SPSYNC2_MARK,
+ SDHID1_1_MARK, TS_SDAT2_MARK,
+ SDHID1_2_MARK, TS_SDEN2_MARK,
+ SDHID1_3_MARK, TS_SCK2_MARK,
+ SDHICMD1_MARK,
+ SDHICLK2_MARK,
+ SDHID2_0_MARK, TS_SPSYNC4_MARK,
+ SDHID2_1_MARK, TS_SDAT4_MARK,
+ SDHID2_2_MARK, TS_SDEN4_MARK,
+ SDHID2_3_MARK, TS_SCK4_MARK,
+ SDHICMD2_MARK,
+ MMCCLK0_MARK,
+ MMCD0_0_MARK,
+ MMCD0_1_MARK,
+ MMCD0_2_MARK,
+ MMCD0_3_MARK,
+ MMCD0_4_MARK, TS_SPSYNC5_MARK,
+ MMCD0_5_MARK, TS_SDAT5_MARK,
+ MMCD0_6_MARK, TS_SDEN5_MARK,
+ MMCD0_7_MARK, TS_SCK5_MARK,
+ MMCCMD0_MARK,
+ RESETOUTS__MARK, EXTAL2OUT_MARK,
+ MCP_WAIT__MCP_FRB_MARK,
+ MCP_CKO_MARK, MMCCLK1_MARK,
+ MCP_D15_MCP_NAF15_MARK,
+ MCP_D14_MCP_NAF14_MARK,
+ MCP_D13_MCP_NAF13_MARK,
+ MCP_D12_MCP_NAF12_MARK,
+ MCP_D11_MCP_NAF11_MARK,
+ MCP_D10_MCP_NAF10_MARK,
+ MCP_D9_MCP_NAF9_MARK,
+ MCP_D8_MCP_NAF8_MARK, MMCCMD1_MARK,
+ MCP_D7_MCP_NAF7_MARK, MMCD1_7_MARK,
+
+ MCP_D6_MCP_NAF6_MARK, MMCD1_6_MARK,
+ MCP_D5_MCP_NAF5_MARK, MMCD1_5_MARK,
+ MCP_D4_MCP_NAF4_MARK, MMCD1_4_MARK,
+ MCP_D3_MCP_NAF3_MARK, MMCD1_3_MARK,
+ MCP_D2_MCP_NAF2_MARK, MMCD1_2_MARK,
+ MCP_D1_MCP_NAF1_MARK, MMCD1_1_MARK,
+ MCP_D0_MCP_NAF0_MARK, MMCD1_0_MARK,
+ MCP_NBRSTOUT__MARK,
+ MCP_WE0__MCP_FWE_MARK, MCP_RDWR_MCP_FWE_MARK,
+
+ /* MSEL2 special cases */
+ TSIF2_TS_XX1_MARK,
+ TSIF2_TS_XX2_MARK,
+ TSIF2_TS_XX3_MARK,
+ TSIF2_TS_XX4_MARK,
+ TSIF2_TS_XX5_MARK,
+ TSIF1_TS_XX1_MARK,
+ TSIF1_TS_XX2_MARK,
+ TSIF1_TS_XX3_MARK,
+ TSIF1_TS_XX4_MARK,
+ TSIF1_TS_XX5_MARK,
+ TSIF0_TS_XX1_MARK,
+ TSIF0_TS_XX2_MARK,
+ TSIF0_TS_XX3_MARK,
+ TSIF0_TS_XX4_MARK,
+ TSIF0_TS_XX5_MARK,
+ MST1_TS_XX1_MARK,
+ MST1_TS_XX2_MARK,
+ MST1_TS_XX3_MARK,
+ MST1_TS_XX4_MARK,
+ MST1_TS_XX5_MARK,
+ MST0_TS_XX1_MARK,
+ MST0_TS_XX2_MARK,
+ MST0_TS_XX3_MARK,
+ MST0_TS_XX4_MARK,
+ MST0_TS_XX5_MARK,
+
+ /* MSEL3 special cases */
+ SDHI0_VCCQ_MC0_ON_MARK,
+ SDHI0_VCCQ_MC0_OFF_MARK,
+ DEBUG_MON_VIO_MARK,
+ DEBUG_MON_LCDD_MARK,
+ LCDC_LCDC0_MARK,
+ LCDC_LCDC1_MARK,
+
+ /* MSEL4 special cases */
+ IRQ9_MEM_INT_MARK,
+ IRQ9_MCP_INT_MARK,
+ A11_MARK,
+ KEYOUT8_MARK,
+ TPU4TO3_MARK,
+ RESETA_N_PU_ON_MARK,
+ RESETA_N_PU_OFF_MARK,
+ EDBGREQ_PD_MARK,
+ EDBGREQ_PU_MARK,
+
+ /* Functions with pull-ups */
+ KEYIN0_PU_MARK,
+ KEYIN1_PU_MARK,
+ KEYIN2_PU_MARK,
+ KEYIN3_PU_MARK,
+ KEYIN4_PU_MARK,
+ KEYIN5_PU_MARK,
+ KEYIN6_PU_MARK,
+ KEYIN7_PU_MARK,
+ SDHID1_0_PU_MARK,
+ SDHID1_1_PU_MARK,
+ SDHID1_2_PU_MARK,
+ SDHID1_3_PU_MARK,
+ SDHICMD1_PU_MARK,
+ MMCCMD0_PU_MARK,
+ MMCCMD1_PU_MARK,
+ FSIACK_PU_MARK,
+ FSIAILR_PU_MARK,
+ FSIAIBT_PU_MARK,
+ FSIAISLD_PU_MARK,
+
+ PINMUX_MARK_END,
+};
+
+#define PORT_DATA_I(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, PORT##nr##_IN)
+
+#define PORT_DATA_I_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD)
+
+#define PORT_DATA_I_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PU)
+
+#define PORT_DATA_I_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_IN, PORT##nr##_IN_PD, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_O(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT)
+
+#define PORT_DATA_IO(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN)
+
+#define PORT_DATA_IO_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD)
+
+#define PORT_DATA_IO_PU(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PU)
+
+#define PORT_DATA_IO_PU_PD(nr) \
+ PINMUX_DATA(PORT##nr##_DATA, PORT##nr##_FN0, \
+ PORT##nr##_OUT, PORT##nr##_IN, \
+ PORT##nr##_IN_PD, PORT##nr##_IN_PU)
+
+static pinmux_enum_t pinmux_data[] = {
+ /* specify valid pin states for each pin in GPIO mode */
+
+ /* Table 25-1 (I/O and Pull U/D) */
+ PORT_DATA_I_PD(0),
+ PORT_DATA_I_PU(1),
+ PORT_DATA_I_PU(2),
+ PORT_DATA_I_PU(3),
+ PORT_DATA_I_PU(4),
+ PORT_DATA_I_PU(5),
+ PORT_DATA_I_PU(6),
+ PORT_DATA_I_PU(7),
+ PORT_DATA_I_PU(8),
+ PORT_DATA_I_PD(9),
+ PORT_DATA_I_PD(10),
+ PORT_DATA_I_PU_PD(11),
+ PORT_DATA_IO_PU_PD(12),
+ PORT_DATA_IO_PU_PD(13),
+ PORT_DATA_IO_PU_PD(14),
+ PORT_DATA_IO_PU_PD(15),
+ PORT_DATA_IO_PD(16),
+ PORT_DATA_IO_PD(17),
+ PORT_DATA_IO_PU(18),
+ PORT_DATA_IO_PU(19),
+ PORT_DATA_O(20),
+ PORT_DATA_O(21),
+ PORT_DATA_O(22),
+ PORT_DATA_O(23),
+ PORT_DATA_O(24),
+ PORT_DATA_I_PD(25),
+ PORT_DATA_I_PD(26),
+ PORT_DATA_IO_PU(27),
+ PORT_DATA_IO_PU(28),
+ PORT_DATA_IO_PD(29),
+ PORT_DATA_IO_PD(30),
+ PORT_DATA_IO_PU(31),
+ PORT_DATA_IO_PD(32),
+ PORT_DATA_I_PU_PD(33),
+ PORT_DATA_IO_PD(34),
+ PORT_DATA_I_PU_PD(35),
+ PORT_DATA_IO_PD(36),
+ PORT_DATA_IO(37),
+ PORT_DATA_O(38),
+ PORT_DATA_I_PU(39),
+ PORT_DATA_I_PU_PD(40),
+ PORT_DATA_O(41),
+ PORT_DATA_IO_PD(42),
+ PORT_DATA_IO_PU_PD(43),
+ PORT_DATA_IO_PU_PD(44),
+ PORT_DATA_IO_PD(45),
+ PORT_DATA_IO_PD(46),
+ PORT_DATA_IO_PD(47),
+ PORT_DATA_I_PD(48),
+ PORT_DATA_IO_PU_PD(49),
+ PORT_DATA_IO_PD(50),
+
+ PORT_DATA_IO_PD(51),
+ PORT_DATA_O(52),
+ PORT_DATA_IO_PU_PD(53),
+ PORT_DATA_IO_PU_PD(54),
+ PORT_DATA_IO_PD(55),
+ PORT_DATA_I_PU_PD(56),
+ PORT_DATA_IO(57),
+ PORT_DATA_IO(58),
+ PORT_DATA_IO(59),
+ PORT_DATA_IO(60),
+ PORT_DATA_IO(61),
+ PORT_DATA_IO_PD(62),
+ PORT_DATA_IO_PD(63),
+ PORT_DATA_IO_PU_PD(64),
+ PORT_DATA_IO_PD(65),
+ PORT_DATA_IO_PU_PD(66),
+ PORT_DATA_IO_PU_PD(67),
+ PORT_DATA_IO_PU_PD(68),
+ PORT_DATA_IO_PU_PD(69),
+ PORT_DATA_IO_PU_PD(70),
+ PORT_DATA_IO_PU_PD(71),
+ PORT_DATA_IO_PU_PD(72),
+ PORT_DATA_I_PU_PD(73),
+ PORT_DATA_IO_PU(74),
+ PORT_DATA_IO_PU(75),
+ PORT_DATA_IO_PU(76),
+ PORT_DATA_IO_PU(77),
+ PORT_DATA_IO_PU(78),
+ PORT_DATA_IO_PU(79),
+ PORT_DATA_IO_PU(80),
+ PORT_DATA_IO_PU(81),
+ PORT_DATA_IO_PU(82),
+ PORT_DATA_IO_PU(83),
+ PORT_DATA_IO_PU(84),
+ PORT_DATA_IO_PU(85),
+ PORT_DATA_IO_PU(86),
+ PORT_DATA_IO_PU(87),
+ PORT_DATA_IO_PU(88),
+ PORT_DATA_IO_PU(89),
+ PORT_DATA_O(90),
+ PORT_DATA_IO_PU(91),
+ PORT_DATA_O(92),
+ PORT_DATA_IO_PU(93),
+ PORT_DATA_O(94),
+ PORT_DATA_I_PU_PD(95),
+ PORT_DATA_IO(96),
+ PORT_DATA_IO(97),
+ PORT_DATA_IO(98),
+ PORT_DATA_I_PU(99),
+ PORT_DATA_O(100),
+ PORT_DATA_O(101),
+ PORT_DATA_I_PU(102),
+ PORT_DATA_IO_PD(103),
+ PORT_DATA_I_PU_PD(104),
+ PORT_DATA_I_PD(105),
+ PORT_DATA_I_PD(106),
+ PORT_DATA_I_PU_PD(107),
+ PORT_DATA_I_PU_PD(108),
+ PORT_DATA_IO_PD(109),
+ PORT_DATA_IO_PD(110),
+ PORT_DATA_IO_PU_PD(111),
+ PORT_DATA_IO_PU_PD(112),
+ PORT_DATA_IO_PU_PD(113),
+ PORT_DATA_IO_PD(114),
+ PORT_DATA_IO_PU(115),
+ PORT_DATA_IO_PU(116),
+ PORT_DATA_IO_PU_PD(117),
+ PORT_DATA_IO_PU_PD(118),
+ PORT_DATA_IO_PD(128),
+
+ PORT_DATA_IO_PD(129),
+ PORT_DATA_IO_PU_PD(130),
+ PORT_DATA_IO_PD(131),
+ PORT_DATA_IO_PD(132),
+ PORT_DATA_IO_PD(133),
+ PORT_DATA_IO_PU_PD(134),
+ PORT_DATA_IO_PU_PD(135),
+ PORT_DATA_IO_PU_PD(136),
+ PORT_DATA_IO_PU_PD(137),
+ PORT_DATA_IO_PD(138),
+ PORT_DATA_IO_PD(139),
+ PORT_DATA_IO_PD(140),
+ PORT_DATA_IO_PD(141),
+ PORT_DATA_IO_PD(142),
+ PORT_DATA_IO_PD(143),
+ PORT_DATA_IO_PU_PD(144),
+ PORT_DATA_IO_PD(145),
+ PORT_DATA_IO_PU_PD(146),
+ PORT_DATA_IO_PU_PD(147),
+ PORT_DATA_IO_PU_PD(148),
+ PORT_DATA_IO_PU_PD(149),
+ PORT_DATA_I_PU_PD(150),
+ PORT_DATA_IO_PU_PD(151),
+ PORT_DATA_IO_PU_PD(152),
+ PORT_DATA_IO_PD(153),
+ PORT_DATA_IO_PD(154),
+ PORT_DATA_I_PU_PD(155),
+ PORT_DATA_IO_PU_PD(156),
+ PORT_DATA_I_PD(157),
+ PORT_DATA_IO_PD(158),
+ PORT_DATA_IO_PU_PD(159),
+ PORT_DATA_IO_PU_PD(160),
+ PORT_DATA_I_PU_PD(161),
+ PORT_DATA_I_PU_PD(162),
+ PORT_DATA_IO_PU_PD(163),
+ PORT_DATA_I_PU_PD(164),
+ PORT_DATA_IO_PD(192),
+ PORT_DATA_IO_PU_PD(193),
+ PORT_DATA_IO_PD(194),
+ PORT_DATA_IO_PU_PD(195),
+ PORT_DATA_IO_PD(196),
+ PORT_DATA_IO_PD(197),
+ PORT_DATA_IO_PD(198),
+ PORT_DATA_IO_PD(199),
+ PORT_DATA_IO_PU_PD(200),
+ PORT_DATA_IO_PU_PD(201),
+ PORT_DATA_IO_PU_PD(202),
+ PORT_DATA_IO_PU_PD(203),
+ PORT_DATA_IO_PU_PD(204),
+ PORT_DATA_IO_PU_PD(205),
+ PORT_DATA_IO_PU_PD(206),
+ PORT_DATA_IO_PD(207),
+ PORT_DATA_IO_PD(208),
+ PORT_DATA_IO_PD(209),
+ PORT_DATA_IO_PD(210),
+ PORT_DATA_IO_PD(211),
+ PORT_DATA_IO_PD(212),
+ PORT_DATA_IO_PD(213),
+ PORT_DATA_IO_PU_PD(214),
+ PORT_DATA_IO_PU_PD(215),
+ PORT_DATA_IO_PD(216),
+ PORT_DATA_IO_PD(217),
+ PORT_DATA_O(218),
+ PORT_DATA_IO_PD(219),
+ PORT_DATA_IO_PD(220),
+ PORT_DATA_IO_PU_PD(221),
+ PORT_DATA_IO_PU_PD(222),
+ PORT_DATA_I_PU_PD(223),
+ PORT_DATA_I_PU_PD(224),
+
+ PORT_DATA_IO_PU_PD(225),
+ PORT_DATA_O(226),
+ PORT_DATA_IO_PU_PD(227),
+ PORT_DATA_I_PU_PD(228),
+ PORT_DATA_I_PD(229),
+ PORT_DATA_IO(230),
+ PORT_DATA_IO_PU_PD(231),
+ PORT_DATA_IO_PU_PD(232),
+ PORT_DATA_I_PU_PD(233),
+ PORT_DATA_IO_PU_PD(234),
+ PORT_DATA_IO_PU_PD(235),
+ PORT_DATA_IO_PU_PD(236),
+ PORT_DATA_IO_PD(237),
+ PORT_DATA_IO_PU_PD(238),
+ PORT_DATA_IO_PU_PD(239),
+ PORT_DATA_IO_PU_PD(240),
+ PORT_DATA_O(241),
+ PORT_DATA_I_PD(242),
+ PORT_DATA_IO_PU_PD(243),
+ PORT_DATA_IO_PU_PD(244),
+ PORT_DATA_IO_PU_PD(245),
+ PORT_DATA_IO_PU_PD(246),
+ PORT_DATA_IO_PU_PD(247),
+ PORT_DATA_IO_PU_PD(248),
+ PORT_DATA_IO_PU_PD(249),
+ PORT_DATA_IO_PU_PD(250),
+ PORT_DATA_IO_PU_PD(251),
+ PORT_DATA_IO_PU_PD(252),
+ PORT_DATA_IO_PU_PD(253),
+ PORT_DATA_IO_PU_PD(254),
+ PORT_DATA_IO_PU_PD(255),
+ PORT_DATA_IO_PU_PD(256),
+ PORT_DATA_IO_PU_PD(257),
+ PORT_DATA_IO_PU_PD(258),
+ PORT_DATA_IO_PU_PD(259),
+ PORT_DATA_IO_PU_PD(260),
+ PORT_DATA_IO_PU_PD(261),
+ PORT_DATA_IO_PU_PD(262),
+ PORT_DATA_IO_PU_PD(263),
+ PORT_DATA_IO_PU_PD(264),
+ PORT_DATA_IO_PU_PD(265),
+ PORT_DATA_IO_PU_PD(266),
+ PORT_DATA_IO_PU_PD(267),
+ PORT_DATA_IO_PU_PD(268),
+ PORT_DATA_IO_PU_PD(269),
+ PORT_DATA_IO_PU_PD(270),
+ PORT_DATA_IO_PU_PD(271),
+ PORT_DATA_IO_PU_PD(272),
+ PORT_DATA_IO_PU_PD(273),
+ PORT_DATA_IO_PU_PD(274),
+ PORT_DATA_IO_PU_PD(275),
+ PORT_DATA_IO_PU_PD(276),
+ PORT_DATA_IO_PU_PD(277),
+ PORT_DATA_IO_PU_PD(278),
+ PORT_DATA_IO_PU_PD(279),
+ PORT_DATA_IO_PU_PD(280),
+ PORT_DATA_O(281),
+ PORT_DATA_O(282),
+ PORT_DATA_I_PU(288),
+ PORT_DATA_IO_PU_PD(289),
+ PORT_DATA_IO_PU_PD(290),
+ PORT_DATA_IO_PU_PD(291),
+ PORT_DATA_IO_PU_PD(292),
+ PORT_DATA_IO_PU_PD(293),
+ PORT_DATA_IO_PU_PD(294),
+ PORT_DATA_IO_PU_PD(295),
+ PORT_DATA_IO_PU_PD(296),
+ PORT_DATA_IO_PU_PD(297),
+ PORT_DATA_IO_PU_PD(298),
+
+ PORT_DATA_IO_PU_PD(299),
+ PORT_DATA_IO_PU_PD(300),
+ PORT_DATA_IO_PU_PD(301),
+ PORT_DATA_IO_PU_PD(302),
+ PORT_DATA_IO_PU_PD(303),
+ PORT_DATA_IO_PU_PD(304),
+ PORT_DATA_IO_PU_PD(305),
+ PORT_DATA_O(306),
+ PORT_DATA_O(307),
+ PORT_DATA_I_PU(308),
+ PORT_DATA_O(309),
+
+ /* Table 25-1 (Function 0-7) */
+ PINMUX_DATA(VBUS_0_MARK, PORT0_FN1),
+ PINMUX_DATA(GPI0_MARK, PORT1_FN1),
+ PINMUX_DATA(GPI1_MARK, PORT2_FN1),
+ PINMUX_DATA(GPI2_MARK, PORT3_FN1),
+ PINMUX_DATA(GPI3_MARK, PORT4_FN1),
+ PINMUX_DATA(GPI4_MARK, PORT5_FN1),
+ PINMUX_DATA(GPI5_MARK, PORT6_FN1),
+ PINMUX_DATA(GPI6_MARK, PORT7_FN1),
+ PINMUX_DATA(GPI7_MARK, PORT8_FN1),
+ PINMUX_DATA(SCIFA7_RXD_MARK, PORT12_FN2),
+ PINMUX_DATA(SCIFA7_CTS__MARK, PORT13_FN2),
+ PINMUX_DATA(GPO7_MARK, PORT14_FN1), \
+ PINMUX_DATA(MFG0_OUT2_MARK, PORT14_FN4),
+ PINMUX_DATA(GPO6_MARK, PORT15_FN1), \
+ PINMUX_DATA(MFG1_OUT2_MARK, PORT15_FN4),
+ PINMUX_DATA(GPO5_MARK, PORT16_FN1), \
+ PINMUX_DATA(SCIFA0_SCK_MARK, PORT16_FN2), \
+ PINMUX_DATA(FSICOSLDT3_MARK, PORT16_FN3), \
+ PINMUX_DATA(PORT16_VIO_CKOR_MARK, PORT16_FN4),
+ PINMUX_DATA(SCIFA0_TXD_MARK, PORT17_FN2),
+ PINMUX_DATA(SCIFA7_TXD_MARK, PORT18_FN2),
+ PINMUX_DATA(SCIFA7_RTS__MARK, PORT19_FN2), \
+ PINMUX_DATA(PORT19_VIO_CKO2_MARK, PORT19_FN3),
+ PINMUX_DATA(GPO0_MARK, PORT20_FN1),
+ PINMUX_DATA(GPO1_MARK, PORT21_FN1),
+ PINMUX_DATA(GPO2_MARK, PORT22_FN1), \
+ PINMUX_DATA(STATUS0_MARK, PORT22_FN2),
+ PINMUX_DATA(GPO3_MARK, PORT23_FN1), \
+ PINMUX_DATA(STATUS1_MARK, PORT23_FN2),
+ PINMUX_DATA(GPO4_MARK, PORT24_FN1), \
+ PINMUX_DATA(STATUS2_MARK, PORT24_FN2),
+ PINMUX_DATA(VINT_MARK, PORT25_FN1),
+ PINMUX_DATA(TCKON_MARK, PORT26_FN1),
+ PINMUX_DATA(XDVFS1_MARK, PORT27_FN1), \
+ PINMUX_DATA(PORT27_I2C_SCL2_MARK, PORT27_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT27_I2C_SCL3_MARK, PORT27_FN3, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MFG0_OUT1_MARK, PORT27_FN4), \
+ PINMUX_DATA(PORT27_IROUT_MARK, PORT27_FN7),
+ PINMUX_DATA(XDVFS2_MARK, PORT28_FN1), \
+ PINMUX_DATA(PORT28_I2C_SDA2_MARK, PORT28_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_1), \
+ PINMUX_DATA(PORT28_I2C_SDA3_MARK, PORT28_FN3, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(PORT28_TPU1TO1_MARK, PORT28_FN7),
+ PINMUX_DATA(SIM_RST_MARK, PORT29_FN1), \
+ PINMUX_DATA(PORT29_TPU1TO1_MARK, PORT29_FN4),
+ PINMUX_DATA(SIM_CLK_MARK, PORT30_FN1), \
+ PINMUX_DATA(PORT30_VIO_CKOR_MARK, PORT30_FN4),
+ PINMUX_DATA(SIM_D_MARK, PORT31_FN1), \
+ PINMUX_DATA(PORT31_IROUT_MARK, PORT31_FN4),
+ PINMUX_DATA(SCIFA4_TXD_MARK, PORT32_FN2),
+ PINMUX_DATA(SCIFA4_RXD_MARK, PORT33_FN2), \
+ PINMUX_DATA(XWUP_MARK, PORT33_FN3),
+ PINMUX_DATA(SCIFA4_RTS__MARK, PORT34_FN2),
+ PINMUX_DATA(SCIFA4_CTS__MARK, PORT35_FN2),
+ PINMUX_DATA(FSIBOBT_MARK, PORT36_FN1), \
+ PINMUX_DATA(FSIBIBT_MARK, PORT36_FN2),
+ PINMUX_DATA(FSIBOLR_MARK, PORT37_FN1), \
+ PINMUX_DATA(FSIBILR_MARK, PORT37_FN2),
+ PINMUX_DATA(FSIBOSLD_MARK, PORT38_FN1),
+ PINMUX_DATA(FSIBISLD_MARK, PORT39_FN1),
+ PINMUX_DATA(VACK_MARK, PORT40_FN1),
+ PINMUX_DATA(XTAL1L_MARK, PORT41_FN1),
+ PINMUX_DATA(SCIFA0_RTS__MARK, PORT42_FN2), \
+ PINMUX_DATA(FSICOSLDT2_MARK, PORT42_FN3),
+ PINMUX_DATA(SCIFA0_RXD_MARK, PORT43_FN2),
+ PINMUX_DATA(SCIFA0_CTS__MARK, PORT44_FN2), \
+ PINMUX_DATA(FSICOSLDT1_MARK, PORT44_FN3),
+ PINMUX_DATA(FSICOBT_MARK, PORT45_FN1), \
+ PINMUX_DATA(FSICIBT_MARK, PORT45_FN2), \
+ PINMUX_DATA(FSIDOBT_MARK, PORT45_FN3), \
+ PINMUX_DATA(FSIDIBT_MARK, PORT45_FN4),
+ PINMUX_DATA(FSICOLR_MARK, PORT46_FN1), \
+ PINMUX_DATA(FSICILR_MARK, PORT46_FN2), \
+ PINMUX_DATA(FSIDOLR_MARK, PORT46_FN3), \
+ PINMUX_DATA(FSIDILR_MARK, PORT46_FN4),
+ PINMUX_DATA(FSICOSLD_MARK, PORT47_FN1), \
+ PINMUX_DATA(PORT47_FSICSPDIF_MARK, PORT47_FN2),
+ PINMUX_DATA(FSICISLD_MARK, PORT48_FN1), \
+ PINMUX_DATA(FSIDISLD_MARK, PORT48_FN3),
+ PINMUX_DATA(FSIACK_MARK, PORT49_FN1), \
+ PINMUX_DATA(PORT49_IRDA_OUT_MARK, PORT49_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(PORT49_IROUT_MARK, PORT49_FN4), \
+ PINMUX_DATA(FSIAOMC_MARK, PORT49_FN5),
+ PINMUX_DATA(FSIAOLR_MARK, PORT50_FN1), \
+ PINMUX_DATA(BBIF2_TSYNC2_MARK, PORT50_FN2), \
+ PINMUX_DATA(TPU2TO2_MARK, PORT50_FN3), \
+ PINMUX_DATA(FSIAILR_MARK, PORT50_FN5),
+
+ PINMUX_DATA(FSIAOBT_MARK, PORT51_FN1), \
+ PINMUX_DATA(BBIF2_TSCK2_MARK, PORT51_FN2), \
+ PINMUX_DATA(TPU2TO3_MARK, PORT51_FN3), \
+ PINMUX_DATA(FSIAIBT_MARK, PORT51_FN5),
+ PINMUX_DATA(FSIAOSLD_MARK, PORT52_FN1), \
+ PINMUX_DATA(BBIF2_TXD2_MARK, PORT52_FN2),
+ PINMUX_DATA(FSIASPDIF_MARK, PORT53_FN1), \
+ PINMUX_DATA(PORT53_IRDA_IN_MARK, PORT53_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(TPU3TO3_MARK, PORT53_FN3), \
+ PINMUX_DATA(FSIBSPDIF_MARK, PORT53_FN5), \
+ PINMUX_DATA(PORT53_FSICSPDIF_MARK, PORT53_FN6),
+ PINMUX_DATA(FSIBCK_MARK, PORT54_FN1), \
+ PINMUX_DATA(PORT54_IRDA_FIRSEL_MARK, PORT54_FN2, MSEL4CR_MSEL19_1), \
+ PINMUX_DATA(TPU3TO2_MARK, PORT54_FN3), \
+ PINMUX_DATA(FSIBOMC_MARK, PORT54_FN5), \
+ PINMUX_DATA(FSICCK_MARK, PORT54_FN6), \
+ PINMUX_DATA(FSICOMC_MARK, PORT54_FN7),
+ PINMUX_DATA(FSIAISLD_MARK, PORT55_FN1), \
+ PINMUX_DATA(TPU0TO0_MARK, PORT55_FN3),
+ PINMUX_DATA(A0_MARK, PORT57_FN1), \
+ PINMUX_DATA(BS__MARK, PORT57_FN2),
+ PINMUX_DATA(A12_MARK, PORT58_FN1), \
+ PINMUX_DATA(PORT58_KEYOUT7_MARK, PORT58_FN2), \
+ PINMUX_DATA(TPU4TO2_MARK, PORT58_FN4),
+ PINMUX_DATA(A13_MARK, PORT59_FN1), \
+ PINMUX_DATA(PORT59_KEYOUT6_MARK, PORT59_FN2), \
+ PINMUX_DATA(TPU0TO1_MARK, PORT59_FN4),
+ PINMUX_DATA(A14_MARK, PORT60_FN1), \
+ PINMUX_DATA(KEYOUT5_MARK, PORT60_FN2),
+ PINMUX_DATA(A15_MARK, PORT61_FN1), \
+ PINMUX_DATA(KEYOUT4_MARK, PORT61_FN2),
+ PINMUX_DATA(A16_MARK, PORT62_FN1), \
+ PINMUX_DATA(KEYOUT3_MARK, PORT62_FN2), \
+ PINMUX_DATA(MSIOF0_SS1_MARK, PORT62_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A17_MARK, PORT63_FN1), \
+ PINMUX_DATA(KEYOUT2_MARK, PORT63_FN2), \
+ PINMUX_DATA(MSIOF0_TSYNC_MARK, PORT63_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A18_MARK, PORT64_FN1), \
+ PINMUX_DATA(KEYOUT1_MARK, PORT64_FN2), \
+ PINMUX_DATA(MSIOF0_TSCK_MARK, PORT64_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A19_MARK, PORT65_FN1), \
+ PINMUX_DATA(KEYOUT0_MARK, PORT65_FN2), \
+ PINMUX_DATA(MSIOF0_TXD_MARK, PORT65_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A20_MARK, PORT66_FN1), \
+ PINMUX_DATA(KEYIN0_MARK, PORT66_FN2), \
+ PINMUX_DATA(MSIOF0_RSCK_MARK, PORT66_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A21_MARK, PORT67_FN1), \
+ PINMUX_DATA(KEYIN1_MARK, PORT67_FN2), \
+ PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT67_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A22_MARK, PORT68_FN1), \
+ PINMUX_DATA(KEYIN2_MARK, PORT68_FN2), \
+ PINMUX_DATA(MSIOF0_MCK0_MARK, PORT68_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A23_MARK, PORT69_FN1), \
+ PINMUX_DATA(KEYIN3_MARK, PORT69_FN2), \
+ PINMUX_DATA(MSIOF0_MCK1_MARK, PORT69_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A24_MARK, PORT70_FN1), \
+ PINMUX_DATA(KEYIN4_MARK, PORT70_FN2), \
+ PINMUX_DATA(MSIOF0_RXD_MARK, PORT70_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A25_MARK, PORT71_FN1), \
+ PINMUX_DATA(KEYIN5_MARK, PORT71_FN2), \
+ PINMUX_DATA(MSIOF0_SS2_MARK, PORT71_FN4, MSEL3CR_MSEL11_0),
+ PINMUX_DATA(A26_MARK, PORT72_FN1), \
+ PINMUX_DATA(KEYIN6_MARK, PORT72_FN2),
+ PINMUX_DATA(KEYIN7_MARK, PORT73_FN2),
+ PINMUX_DATA(D0_NAF0_MARK, PORT74_FN1),
+ PINMUX_DATA(D1_NAF1_MARK, PORT75_FN1),
+ PINMUX_DATA(D2_NAF2_MARK, PORT76_FN1),
+ PINMUX_DATA(D3_NAF3_MARK, PORT77_FN1),
+ PINMUX_DATA(D4_NAF4_MARK, PORT78_FN1),
+ PINMUX_DATA(D5_NAF5_MARK, PORT79_FN1),
+ PINMUX_DATA(D6_NAF6_MARK, PORT80_FN1),
+ PINMUX_DATA(D7_NAF7_MARK, PORT81_FN1),
+ PINMUX_DATA(D8_NAF8_MARK, PORT82_FN1),
+ PINMUX_DATA(D9_NAF9_MARK, PORT83_FN1),
+ PINMUX_DATA(D10_NAF10_MARK, PORT84_FN1),
+ PINMUX_DATA(D11_NAF11_MARK, PORT85_FN1),
+ PINMUX_DATA(D12_NAF12_MARK, PORT86_FN1),
+ PINMUX_DATA(D13_NAF13_MARK, PORT87_FN1),
+ PINMUX_DATA(D14_NAF14_MARK, PORT88_FN1),
+ PINMUX_DATA(D15_NAF15_MARK, PORT89_FN1),
+ PINMUX_DATA(CS4__MARK, PORT90_FN1),
+ PINMUX_DATA(CS5A__MARK, PORT91_FN1), \
+ PINMUX_DATA(PORT91_RDWR_MARK, PORT91_FN2),
+ PINMUX_DATA(CS5B__MARK, PORT92_FN1), \
+ PINMUX_DATA(FCE1__MARK, PORT92_FN2),
+ PINMUX_DATA(CS6B__MARK, PORT93_FN1), \
+ PINMUX_DATA(DACK0_MARK, PORT93_FN4),
+ PINMUX_DATA(FCE0__MARK, PORT94_FN1), \
+ PINMUX_DATA(CS6A__MARK, PORT94_FN2),
+ PINMUX_DATA(WAIT__MARK, PORT95_FN1), \
+ PINMUX_DATA(DREQ0_MARK, PORT95_FN2),
+ PINMUX_DATA(RD__FSC_MARK, PORT96_FN1),
+ PINMUX_DATA(WE0__FWE_MARK, PORT97_FN1), \
+ PINMUX_DATA(RDWR_FWE_MARK, PORT97_FN2),
+ PINMUX_DATA(WE1__MARK, PORT98_FN1),
+ PINMUX_DATA(FRB_MARK, PORT99_FN1),
+ PINMUX_DATA(CKO_MARK, PORT100_FN1),
+ PINMUX_DATA(NBRSTOUT__MARK, PORT101_FN1),
+ PINMUX_DATA(NBRST__MARK, PORT102_FN1),
+ PINMUX_DATA(BBIF2_TXD_MARK, PORT103_FN3),
+ PINMUX_DATA(BBIF2_RXD_MARK, PORT104_FN3),
+ PINMUX_DATA(BBIF2_SYNC_MARK, PORT105_FN3),
+ PINMUX_DATA(BBIF2_SCK_MARK, PORT106_FN3),
+ PINMUX_DATA(SCIFA3_CTS__MARK, PORT107_FN3), \
+ PINMUX_DATA(MFG3_IN2_MARK, PORT107_FN4),
+ PINMUX_DATA(SCIFA3_RXD_MARK, PORT108_FN3), \
+ PINMUX_DATA(MFG3_IN1_MARK, PORT108_FN4),
+ PINMUX_DATA(BBIF1_SS2_MARK, PORT109_FN2), \
+ PINMUX_DATA(SCIFA3_RTS__MARK, PORT109_FN3), \
+ PINMUX_DATA(MFG3_OUT1_MARK, PORT109_FN4),
+ PINMUX_DATA(SCIFA3_TXD_MARK, PORT110_FN3),
+ PINMUX_DATA(HSI_RX_DATA_MARK, PORT111_FN1), \
+ PINMUX_DATA(BBIF1_RXD_MARK, PORT111_FN3),
+ PINMUX_DATA(HSI_TX_WAKE_MARK, PORT112_FN1), \
+ PINMUX_DATA(BBIF1_TSCK_MARK, PORT112_FN3),
+ PINMUX_DATA(HSI_TX_DATA_MARK, PORT113_FN1), \
+ PINMUX_DATA(BBIF1_TSYNC_MARK, PORT113_FN3),
+ PINMUX_DATA(HSI_TX_READY_MARK, PORT114_FN1), \
+ PINMUX_DATA(BBIF1_TXD_MARK, PORT114_FN3),
+ PINMUX_DATA(HSI_RX_READY_MARK, PORT115_FN1), \
+ PINMUX_DATA(BBIF1_RSCK_MARK, PORT115_FN3), \
+ PINMUX_DATA(PORT115_I2C_SCL2_MARK, PORT115_FN5, MSEL2CR_MSEL17_1), \
+ PINMUX_DATA(PORT115_I2C_SCL3_MARK, PORT115_FN6, MSEL2CR_MSEL19_1),
+ PINMUX_DATA(HSI_RX_WAKE_MARK, PORT116_FN1), \
+ PINMUX_DATA(BBIF1_RSYNC_MARK, PORT116_FN3), \
+ PINMUX_DATA(PORT116_I2C_SDA2_MARK, PORT116_FN5, MSEL2CR_MSEL17_1), \
+ PINMUX_DATA(PORT116_I2C_SDA3_MARK, PORT116_FN6, MSEL2CR_MSEL19_1),
+ PINMUX_DATA(HSI_RX_FLAG_MARK, PORT117_FN1), \
+ PINMUX_DATA(BBIF1_SS1_MARK, PORT117_FN2), \
+ PINMUX_DATA(BBIF1_FLOW_MARK, PORT117_FN3),
+ PINMUX_DATA(HSI_TX_FLAG_MARK, PORT118_FN1),
+ PINMUX_DATA(VIO_VD_MARK, PORT128_FN1), \
+ PINMUX_DATA(PORT128_LCD2VSYN_MARK, PORT128_FN4, MSEL3CR_MSEL2_0), \
+ PINMUX_DATA(VIO2_VD_MARK, PORT128_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D0_MARK, PORT128_FN7),
+
+ PINMUX_DATA(VIO_HD_MARK, PORT129_FN1), \
+ PINMUX_DATA(PORT129_LCD2HSYN_MARK, PORT129_FN4), \
+ PINMUX_DATA(PORT129_LCD2CS__MARK, PORT129_FN5), \
+ PINMUX_DATA(VIO2_HD_MARK, PORT129_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D1_MARK, PORT129_FN7),
+ PINMUX_DATA(VIO_D0_MARK, PORT130_FN1), \
+ PINMUX_DATA(PORT130_MSIOF2_RXD_MARK, PORT130_FN3, MSEL4CR_MSEL11_0,
+ MSEL4CR_MSEL10_1), \
+ PINMUX_DATA(LCD2D10_MARK, PORT130_FN7),
+ PINMUX_DATA(VIO_D1_MARK, PORT131_FN1), \
+ PINMUX_DATA(PORT131_KEYOUT6_MARK, PORT131_FN2), \
+ PINMUX_DATA(PORT131_MSIOF2_SS1_MARK, PORT131_FN3), \
+ PINMUX_DATA(PORT131_KEYOUT11_MARK, PORT131_FN4), \
+ PINMUX_DATA(LCD2D11_MARK, PORT131_FN7),
+ PINMUX_DATA(VIO_D2_MARK, PORT132_FN1), \
+ PINMUX_DATA(PORT132_KEYOUT7_MARK, PORT132_FN2), \
+ PINMUX_DATA(PORT132_MSIOF2_SS2_MARK, PORT132_FN3), \
+ PINMUX_DATA(PORT132_KEYOUT10_MARK, PORT132_FN4), \
+ PINMUX_DATA(LCD2D12_MARK, PORT132_FN7),
+ PINMUX_DATA(VIO_D3_MARK, PORT133_FN1), \
+ PINMUX_DATA(MSIOF2_TSYNC_MARK, PORT133_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D13_MARK, PORT133_FN7),
+ PINMUX_DATA(VIO_D4_MARK, PORT134_FN1), \
+ PINMUX_DATA(MSIOF2_TXD_MARK, PORT134_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D14_MARK, PORT134_FN7),
+ PINMUX_DATA(VIO_D5_MARK, PORT135_FN1), \
+ PINMUX_DATA(MSIOF2_TSCK_MARK, PORT135_FN3, MSEL4CR_MSEL11_0), \
+ PINMUX_DATA(LCD2D15_MARK, PORT135_FN7),
+ PINMUX_DATA(VIO_D6_MARK, PORT136_FN1), \
+ PINMUX_DATA(PORT136_KEYOUT8_MARK, PORT136_FN2), \
+ PINMUX_DATA(LCD2D16_MARK, PORT136_FN7),
+ PINMUX_DATA(VIO_D7_MARK, PORT137_FN1), \
+ PINMUX_DATA(PORT137_KEYOUT9_MARK, PORT137_FN2), \
+ PINMUX_DATA(LCD2D17_MARK, PORT137_FN7),
+ PINMUX_DATA(VIO_D8_MARK, PORT138_FN1), \
+ PINMUX_DATA(PORT138_KEYOUT8_MARK, PORT138_FN2), \
+ PINMUX_DATA(VIO2_D0_MARK, PORT138_FN6), \
+ PINMUX_DATA(LCD2D6_MARK, PORT138_FN7),
+ PINMUX_DATA(VIO_D9_MARK, PORT139_FN1), \
+ PINMUX_DATA(PORT139_KEYOUT9_MARK, PORT139_FN2), \
+ PINMUX_DATA(VIO2_D1_MARK, PORT139_FN6), \
+ PINMUX_DATA(LCD2D7_MARK, PORT139_FN7),
+ PINMUX_DATA(VIO_D10_MARK, PORT140_FN1), \
+ PINMUX_DATA(TPU0TO2_MARK, PORT140_FN4), \
+ PINMUX_DATA(VIO2_D2_MARK, PORT140_FN6), \
+ PINMUX_DATA(LCD2D8_MARK, PORT140_FN7),
+ PINMUX_DATA(VIO_D11_MARK, PORT141_FN1), \
+ PINMUX_DATA(TPU0TO3_MARK, PORT141_FN4), \
+ PINMUX_DATA(VIO2_D3_MARK, PORT141_FN6), \
+ PINMUX_DATA(LCD2D9_MARK, PORT141_FN7),
+ PINMUX_DATA(VIO_D12_MARK, PORT142_FN1), \
+ PINMUX_DATA(PORT142_KEYOUT10_MARK, PORT142_FN2), \
+ PINMUX_DATA(VIO2_D4_MARK, PORT142_FN6), \
+ PINMUX_DATA(LCD2D2_MARK, PORT142_FN7),
+ PINMUX_DATA(VIO_D13_MARK, PORT143_FN1), \
+ PINMUX_DATA(PORT143_KEYOUT11_MARK, PORT143_FN2), \
+ PINMUX_DATA(PORT143_KEYOUT6_MARK, PORT143_FN3), \
+ PINMUX_DATA(VIO2_D5_MARK, PORT143_FN6), \
+ PINMUX_DATA(LCD2D3_MARK, PORT143_FN7),
+ PINMUX_DATA(VIO_D14_MARK, PORT144_FN1), \
+ PINMUX_DATA(PORT144_KEYOUT7_MARK, PORT144_FN2), \
+ PINMUX_DATA(VIO2_D6_MARK, PORT144_FN6), \
+ PINMUX_DATA(LCD2D4_MARK, PORT144_FN7),
+ PINMUX_DATA(VIO_D15_MARK, PORT145_FN1), \
+ PINMUX_DATA(TPU1TO3_MARK, PORT145_FN3), \
+ PINMUX_DATA(PORT145_LCD2DISP_MARK, PORT145_FN4), \
+ PINMUX_DATA(PORT145_LCD2RS_MARK, PORT145_FN5), \
+ PINMUX_DATA(VIO2_D7_MARK, PORT145_FN6), \
+ PINMUX_DATA(LCD2D5_MARK, PORT145_FN7),
+ PINMUX_DATA(VIO_CLK_MARK, PORT146_FN1), \
+ PINMUX_DATA(LCD2DCK_MARK, PORT146_FN4), \
+ PINMUX_DATA(PORT146_LCD2WR__MARK, PORT146_FN5), \
+ PINMUX_DATA(VIO2_CLK_MARK, PORT146_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D18_MARK, PORT146_FN7),
+ PINMUX_DATA(VIO_FIELD_MARK, PORT147_FN1), \
+ PINMUX_DATA(LCD2RD__MARK, PORT147_FN4), \
+ PINMUX_DATA(VIO2_FIELD_MARK, PORT147_FN6, MSEL4CR_MSEL27_0), \
+ PINMUX_DATA(LCD2D19_MARK, PORT147_FN7),
+ PINMUX_DATA(VIO_CKO_MARK, PORT148_FN1),
+ PINMUX_DATA(A27_MARK, PORT149_FN1), \
+ PINMUX_DATA(PORT149_RDWR_MARK, PORT149_FN2), \
+ PINMUX_DATA(MFG0_IN1_MARK, PORT149_FN3), \
+ PINMUX_DATA(PORT149_KEYOUT9_MARK, PORT149_FN4),
+ PINMUX_DATA(MFG0_IN2_MARK, PORT150_FN3),
+ PINMUX_DATA(TS_SPSYNC3_MARK, PORT151_FN4), \
+ PINMUX_DATA(MSIOF2_RSCK_MARK, PORT151_FN5),
+ PINMUX_DATA(TS_SDAT3_MARK, PORT152_FN4), \
+ PINMUX_DATA(MSIOF2_RSYNC_MARK, PORT152_FN5),
+ PINMUX_DATA(TPU1TO2_MARK, PORT153_FN3), \
+ PINMUX_DATA(TS_SDEN3_MARK, PORT153_FN4), \
+ PINMUX_DATA(PORT153_MSIOF2_SS1_MARK, PORT153_FN5),
+ PINMUX_DATA(SCIFA2_TXD1_MARK, PORT154_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(MSIOF2_MCK0_MARK, PORT154_FN5),
+ PINMUX_DATA(SCIFA2_RXD1_MARK, PORT155_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(MSIOF2_MCK1_MARK, PORT155_FN5),
+ PINMUX_DATA(SCIFA2_RTS1__MARK, PORT156_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(PORT156_MSIOF2_SS2_MARK, PORT156_FN5),
+ PINMUX_DATA(SCIFA2_CTS1__MARK, PORT157_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(PORT157_MSIOF2_RXD_MARK, PORT157_FN5, MSEL4CR_MSEL11_0,
+ MSEL4CR_MSEL10_0),
+ PINMUX_DATA(DINT__MARK, PORT158_FN1), \
+ PINMUX_DATA(SCIFA2_SCK1_MARK, PORT158_FN2, MSEL3CR_MSEL9_0), \
+ PINMUX_DATA(TS_SCK3_MARK, PORT158_FN4),
+ PINMUX_DATA(PORT159_SCIFB_SCK_MARK, PORT159_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT159_SCIFA5_SCK_MARK, PORT159_FN2, MSEL4CR_MSEL21_1), \
+ PINMUX_DATA(NMI_MARK, PORT159_FN3),
+ PINMUX_DATA(PORT160_SCIFB_TXD_MARK, PORT160_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT160_SCIFA5_TXD_MARK, PORT160_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT161_SCIFB_CTS__MARK, PORT161_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT161_SCIFA5_CTS__MARK, PORT161_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT162_SCIFB_RXD_MARK, PORT162_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT162_SCIFA5_RXD_MARK, PORT162_FN2, MSEL4CR_MSEL21_1),
+ PINMUX_DATA(PORT163_SCIFB_RTS__MARK, PORT163_FN1, MSEL4CR_MSEL22_0), \
+ PINMUX_DATA(PORT163_SCIFA5_RTS__MARK, PORT163_FN2, MSEL4CR_MSEL21_1), \
+ PINMUX_DATA(TPU3TO0_MARK, PORT163_FN5),
+ PINMUX_DATA(LCDD0_MARK, PORT192_FN1),
+ PINMUX_DATA(LCDD1_MARK, PORT193_FN1), \
+ PINMUX_DATA(PORT193_SCIFA5_CTS__MARK, PORT193_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TSYNC1_MARK, PORT193_FN5),
+ PINMUX_DATA(LCDD2_MARK, PORT194_FN1), \
+ PINMUX_DATA(PORT194_SCIFA5_RTS__MARK, PORT194_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TSCK1_MARK, PORT194_FN5),
+ PINMUX_DATA(LCDD3_MARK, PORT195_FN1), \
+ PINMUX_DATA(PORT195_SCIFA5_RXD_MARK, PORT195_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(BBIF2_TXD1_MARK, PORT195_FN5),
+ PINMUX_DATA(LCDD4_MARK, PORT196_FN1), \
+ PINMUX_DATA(PORT196_SCIFA5_TXD_MARK, PORT196_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1),
+ PINMUX_DATA(LCDD5_MARK, PORT197_FN1), \
+ PINMUX_DATA(PORT197_SCIFA5_SCK_MARK, PORT197_FN3, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_1), \
+ PINMUX_DATA(MFG2_OUT2_MARK, PORT197_FN5), \
+ PINMUX_DATA(TPU2TO1_MARK, PORT197_FN7),
+ PINMUX_DATA(LCDD6_MARK, PORT198_FN1),
+ PINMUX_DATA(LCDD7_MARK, PORT199_FN1), \
+ PINMUX_DATA(TPU4TO1_MARK, PORT199_FN2), \
+ PINMUX_DATA(MFG4_OUT2_MARK, PORT199_FN5),
+ PINMUX_DATA(LCDD8_MARK, PORT200_FN1), \
+ PINMUX_DATA(D16_MARK, PORT200_FN6),
+ PINMUX_DATA(LCDD9_MARK, PORT201_FN1), \
+ PINMUX_DATA(D17_MARK, PORT201_FN6),
+ PINMUX_DATA(LCDD10_MARK, PORT202_FN1), \
+ PINMUX_DATA(D18_MARK, PORT202_FN6),
+ PINMUX_DATA(LCDD11_MARK, PORT203_FN1), \
+ PINMUX_DATA(D19_MARK, PORT203_FN6),
+ PINMUX_DATA(LCDD12_MARK, PORT204_FN1), \
+ PINMUX_DATA(D20_MARK, PORT204_FN6),
+ PINMUX_DATA(LCDD13_MARK, PORT205_FN1), \
+ PINMUX_DATA(D21_MARK, PORT205_FN6),
+ PINMUX_DATA(LCDD14_MARK, PORT206_FN1), \
+ PINMUX_DATA(D22_MARK, PORT206_FN6),
+ PINMUX_DATA(LCDD15_MARK, PORT207_FN1), \
+ PINMUX_DATA(PORT207_MSIOF0L_SS1_MARK, PORT207_FN2, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D23_MARK, PORT207_FN6),
+ PINMUX_DATA(LCDD16_MARK, PORT208_FN1), \
+ PINMUX_DATA(PORT208_MSIOF0L_SS2_MARK, PORT208_FN2, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D24_MARK, PORT208_FN6),
+ PINMUX_DATA(LCDD17_MARK, PORT209_FN1), \
+ PINMUX_DATA(D25_MARK, PORT209_FN6),
+ PINMUX_DATA(LCDD18_MARK, PORT210_FN1), \
+ PINMUX_DATA(DREQ2_MARK, PORT210_FN2), \
+ PINMUX_DATA(PORT210_MSIOF0L_SS1_MARK, PORT210_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D26_MARK, PORT210_FN6),
+ PINMUX_DATA(LCDD19_MARK, PORT211_FN1), \
+ PINMUX_DATA(PORT211_MSIOF0L_SS2_MARK, PORT211_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D27_MARK, PORT211_FN6),
+ PINMUX_DATA(LCDD20_MARK, PORT212_FN1), \
+ PINMUX_DATA(TS_SPSYNC1_MARK, PORT212_FN2), \
+ PINMUX_DATA(MSIOF0L_MCK0_MARK, PORT212_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D28_MARK, PORT212_FN6),
+ PINMUX_DATA(LCDD21_MARK, PORT213_FN1), \
+ PINMUX_DATA(TS_SDAT1_MARK, PORT213_FN2), \
+ PINMUX_DATA(MSIOF0L_MCK1_MARK, PORT213_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D29_MARK, PORT213_FN6),
+ PINMUX_DATA(LCDD22_MARK, PORT214_FN1), \
+ PINMUX_DATA(TS_SDEN1_MARK, PORT214_FN2), \
+ PINMUX_DATA(MSIOF0L_RSCK_MARK, PORT214_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D30_MARK, PORT214_FN6),
+ PINMUX_DATA(LCDD23_MARK, PORT215_FN1), \
+ PINMUX_DATA(TS_SCK1_MARK, PORT215_FN2), \
+ PINMUX_DATA(MSIOF0L_RSYNC_MARK, PORT215_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(D31_MARK, PORT215_FN6),
+ PINMUX_DATA(LCDDCK_MARK, PORT216_FN1), \
+ PINMUX_DATA(LCDWR__MARK, PORT216_FN2),
+ PINMUX_DATA(LCDRD__MARK, PORT217_FN1), \
+ PINMUX_DATA(DACK2_MARK, PORT217_FN2), \
+ PINMUX_DATA(PORT217_LCD2RS_MARK, PORT217_FN3), \
+ PINMUX_DATA(MSIOF0L_TSYNC_MARK, PORT217_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_FIELD3_MARK, PORT217_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT217_LCD2DISP_MARK, PORT217_FN7),
+ PINMUX_DATA(LCDHSYN_MARK, PORT218_FN1), \
+ PINMUX_DATA(LCDCS__MARK, PORT218_FN2), \
+ PINMUX_DATA(LCDCS2__MARK, PORT218_FN3), \
+ PINMUX_DATA(DACK3_MARK, PORT218_FN4), \
+ PINMUX_DATA(PORT218_VIO_CKOR_MARK, PORT218_FN5),
+ PINMUX_DATA(LCDDISP_MARK, PORT219_FN1), \
+ PINMUX_DATA(LCDRS_MARK, PORT219_FN2), \
+ PINMUX_DATA(PORT219_LCD2WR__MARK, PORT219_FN3), \
+ PINMUX_DATA(DREQ3_MARK, PORT219_FN4), \
+ PINMUX_DATA(MSIOF0L_TSCK_MARK, PORT219_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_CLK3_MARK, PORT219_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(LCD2DCK_2_MARK, PORT219_FN7),
+ PINMUX_DATA(LCDVSYN_MARK, PORT220_FN1), \
+ PINMUX_DATA(LCDVSYN2_MARK, PORT220_FN2),
+ PINMUX_DATA(LCDLCLK_MARK, PORT221_FN1), \
+ PINMUX_DATA(DREQ1_MARK, PORT221_FN2), \
+ PINMUX_DATA(PORT221_LCD2CS__MARK, PORT221_FN3), \
+ PINMUX_DATA(PWEN_MARK, PORT221_FN4), \
+ PINMUX_DATA(MSIOF0L_RXD_MARK, PORT221_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_HD3_MARK, PORT221_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT221_LCD2HSYN_MARK, PORT221_FN7),
+ PINMUX_DATA(LCDDON_MARK, PORT222_FN1), \
+ PINMUX_DATA(LCDDON2_MARK, PORT222_FN2), \
+ PINMUX_DATA(DACK1_MARK, PORT222_FN3), \
+ PINMUX_DATA(OVCN_MARK, PORT222_FN4), \
+ PINMUX_DATA(MSIOF0L_TXD_MARK, PORT222_FN5, MSEL3CR_MSEL11_1), \
+ PINMUX_DATA(VIO2_VD3_MARK, PORT222_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_1), \
+ PINMUX_DATA(PORT222_LCD2VSYN_MARK, PORT222_FN7, MSEL3CR_MSEL2_1),
+
+ PINMUX_DATA(SCIFA1_TXD_MARK, PORT225_FN2), \
+ PINMUX_DATA(OVCN2_MARK, PORT225_FN4),
+ PINMUX_DATA(EXTLP_MARK, PORT226_FN1), \
+ PINMUX_DATA(SCIFA1_SCK_MARK, PORT226_FN2), \
+ PINMUX_DATA(PORT226_VIO_CKO2_MARK, PORT226_FN5),
+ PINMUX_DATA(SCIFA1_RTS__MARK, PORT227_FN2), \
+ PINMUX_DATA(IDIN_MARK, PORT227_FN4),
+ PINMUX_DATA(SCIFA1_RXD_MARK, PORT228_FN2),
+ PINMUX_DATA(SCIFA1_CTS__MARK, PORT229_FN2), \
+ PINMUX_DATA(MFG1_IN1_MARK, PORT229_FN3),
+ PINMUX_DATA(MSIOF1_TXD_MARK, PORT230_FN1), \
+ PINMUX_DATA(SCIFA2_TXD2_MARK, PORT230_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PORT231_FN1), \
+ PINMUX_DATA(SCIFA2_CTS2__MARK, PORT231_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PORT232_FN1), \
+ PINMUX_DATA(SCIFA2_SCK2_MARK, PORT232_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PORT233_FN1), \
+ PINMUX_DATA(SCIFA2_RXD2_MARK, PORT233_FN2, MSEL3CR_MSEL9_1),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PORT234_FN1), \
+ PINMUX_DATA(SCIFA2_RTS2__MARK, PORT234_FN2, MSEL3CR_MSEL9_1), \
+ PINMUX_DATA(VIO2_CLK2_MARK, PORT234_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D20_MARK, PORT234_FN7),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PORT235_FN1), \
+ PINMUX_DATA(MFG1_IN2_MARK, PORT235_FN3), \
+ PINMUX_DATA(VIO2_VD2_MARK, PORT235_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D21_MARK, PORT235_FN7),
+ PINMUX_DATA(MSIOF1_MCK0_MARK, PORT236_FN1), \
+ PINMUX_DATA(PORT236_I2C_SDA2_MARK, PORT236_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_0),
+ PINMUX_DATA(MSIOF1_MCK1_MARK, PORT237_FN1), \
+ PINMUX_DATA(PORT237_I2C_SCL2_MARK, PORT237_FN2, MSEL2CR_MSEL17_0,
+ MSEL2CR_MSEL16_0),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PORT238_FN1), \
+ PINMUX_DATA(VIO2_FIELD2_MARK, PORT238_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D22_MARK, PORT238_FN7),
+ PINMUX_DATA(MSIOF1_SS2_MARK, PORT239_FN1), \
+ PINMUX_DATA(VIO2_HD2_MARK, PORT239_FN6, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0), \
+ PINMUX_DATA(LCD2D23_MARK, PORT239_FN7),
+ PINMUX_DATA(SCIFA6_TXD_MARK, PORT240_FN1),
+ PINMUX_DATA(PORT241_IRDA_OUT_MARK, PORT241_FN1, MSEL4CR_MSEL19_0), \
+ PINMUX_DATA(PORT241_IROUT_MARK, PORT241_FN2), \
+ PINMUX_DATA(MFG4_OUT1_MARK, PORT241_FN3), \
+ PINMUX_DATA(TPU4TO0_MARK, PORT241_FN4),
+ PINMUX_DATA(PORT242_IRDA_IN_MARK, PORT242_FN1, MSEL4CR_MSEL19_0), \
+ PINMUX_DATA(MFG4_IN2_MARK, PORT242_FN3),
+ PINMUX_DATA(PORT243_IRDA_FIRSEL_MARK, PORT243_FN1, MSEL4CR_MSEL19_0), \
+ PINMUX_DATA(PORT243_VIO_CKO2_MARK, PORT243_FN2),
+ PINMUX_DATA(PORT244_SCIFA5_CTS__MARK, PORT244_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_IN1_MARK, PORT244_FN2), \
+ PINMUX_DATA(PORT244_SCIFB_CTS__MARK, PORT244_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(MSIOF2R_RXD_MARK, PORT244_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT245_SCIFA5_RTS__MARK, PORT245_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_IN2_MARK, PORT245_FN2), \
+ PINMUX_DATA(PORT245_SCIFB_RTS__MARK, PORT245_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(MSIOF2R_TXD_MARK, PORT245_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT246_SCIFA5_RXD_MARK, PORT246_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG1_OUT1_MARK, PORT246_FN2), \
+ PINMUX_DATA(PORT246_SCIFB_RXD_MARK, PORT246_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU1TO0_MARK, PORT246_FN4),
+ PINMUX_DATA(PORT247_SCIFA5_TXD_MARK, PORT247_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG3_OUT2_MARK, PORT247_FN2), \
+ PINMUX_DATA(PORT247_SCIFB_TXD_MARK, PORT247_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU3TO1_MARK, PORT247_FN4),
+ PINMUX_DATA(PORT248_SCIFA5_SCK_MARK, PORT248_FN1, MSEL4CR_MSEL21_0,
+ MSEL4CR_MSEL20_0), \
+ PINMUX_DATA(MFG2_OUT1_MARK, PORT248_FN2), \
+ PINMUX_DATA(PORT248_SCIFB_SCK_MARK, PORT248_FN3, MSEL4CR_MSEL22_1), \
+ PINMUX_DATA(TPU2TO0_MARK, PORT248_FN4), \
+ PINMUX_DATA(PORT248_I2C_SCL3_MARK, PORT248_FN5, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MSIOF2R_TSCK_MARK, PORT248_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(PORT249_IROUT_MARK, PORT249_FN1), \
+ PINMUX_DATA(MFG4_IN1_MARK, PORT249_FN2), \
+ PINMUX_DATA(PORT249_I2C_SDA3_MARK, PORT249_FN5, MSEL2CR_MSEL19_0,
+ MSEL2CR_MSEL18_0), \
+ PINMUX_DATA(MSIOF2R_TSYNC_MARK, PORT249_FN7, MSEL4CR_MSEL11_1),
+ PINMUX_DATA(SDHICLK0_MARK, PORT250_FN1),
+ PINMUX_DATA(SDHICD0_MARK, PORT251_FN1),
+ PINMUX_DATA(SDHID0_0_MARK, PORT252_FN1),
+ PINMUX_DATA(SDHID0_1_MARK, PORT253_FN1),
+ PINMUX_DATA(SDHID0_2_MARK, PORT254_FN1),
+ PINMUX_DATA(SDHID0_3_MARK, PORT255_FN1),
+ PINMUX_DATA(SDHICMD0_MARK, PORT256_FN1),
+ PINMUX_DATA(SDHIWP0_MARK, PORT257_FN1),
+ PINMUX_DATA(SDHICLK1_MARK, PORT258_FN1),
+ PINMUX_DATA(SDHID1_0_MARK, PORT259_FN1), \
+ PINMUX_DATA(TS_SPSYNC2_MARK, PORT259_FN3),
+ PINMUX_DATA(SDHID1_1_MARK, PORT260_FN1), \
+ PINMUX_DATA(TS_SDAT2_MARK, PORT260_FN3),
+ PINMUX_DATA(SDHID1_2_MARK, PORT261_FN1), \
+ PINMUX_DATA(TS_SDEN2_MARK, PORT261_FN3),
+ PINMUX_DATA(SDHID1_3_MARK, PORT262_FN1), \
+ PINMUX_DATA(TS_SCK2_MARK, PORT262_FN3),
+ PINMUX_DATA(SDHICMD1_MARK, PORT263_FN1),
+ PINMUX_DATA(SDHICLK2_MARK, PORT264_FN1),
+ PINMUX_DATA(SDHID2_0_MARK, PORT265_FN1), \
+ PINMUX_DATA(TS_SPSYNC4_MARK, PORT265_FN3),
+ PINMUX_DATA(SDHID2_1_MARK, PORT266_FN1), \
+ PINMUX_DATA(TS_SDAT4_MARK, PORT266_FN3),
+ PINMUX_DATA(SDHID2_2_MARK, PORT267_FN1), \
+ PINMUX_DATA(TS_SDEN4_MARK, PORT267_FN3),
+ PINMUX_DATA(SDHID2_3_MARK, PORT268_FN1), \
+ PINMUX_DATA(TS_SCK4_MARK, PORT268_FN3),
+ PINMUX_DATA(SDHICMD2_MARK, PORT269_FN1),
+ PINMUX_DATA(MMCCLK0_MARK, PORT270_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_0_MARK, PORT271_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_1_MARK, PORT272_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_2_MARK, PORT273_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_3_MARK, PORT274_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCD0_4_MARK, PORT275_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SPSYNC5_MARK, PORT275_FN3),
+ PINMUX_DATA(MMCD0_5_MARK, PORT276_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDAT5_MARK, PORT276_FN3),
+ PINMUX_DATA(MMCD0_6_MARK, PORT277_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SDEN5_MARK, PORT277_FN3),
+ PINMUX_DATA(MMCD0_7_MARK, PORT278_FN1, MSEL4CR_MSEL15_0), \
+ PINMUX_DATA(TS_SCK5_MARK, PORT278_FN3),
+ PINMUX_DATA(MMCCMD0_MARK, PORT279_FN1, MSEL4CR_MSEL15_0),
+ PINMUX_DATA(RESETOUTS__MARK, PORT281_FN1), \
+ PINMUX_DATA(EXTAL2OUT_MARK, PORT281_FN2),
+ PINMUX_DATA(MCP_WAIT__MCP_FRB_MARK, PORT288_FN1),
+ PINMUX_DATA(MCP_CKO_MARK, PORT289_FN1), \
+ PINMUX_DATA(MMCCLK1_MARK, PORT289_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D15_MCP_NAF15_MARK, PORT290_FN1),
+ PINMUX_DATA(MCP_D14_MCP_NAF14_MARK, PORT291_FN1),
+ PINMUX_DATA(MCP_D13_MCP_NAF13_MARK, PORT292_FN1),
+ PINMUX_DATA(MCP_D12_MCP_NAF12_MARK, PORT293_FN1),
+ PINMUX_DATA(MCP_D11_MCP_NAF11_MARK, PORT294_FN1),
+ PINMUX_DATA(MCP_D10_MCP_NAF10_MARK, PORT295_FN1),
+ PINMUX_DATA(MCP_D9_MCP_NAF9_MARK, PORT296_FN1),
+ PINMUX_DATA(MCP_D8_MCP_NAF8_MARK, PORT297_FN1), \
+ PINMUX_DATA(MMCCMD1_MARK, PORT297_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D7_MCP_NAF7_MARK, PORT298_FN1), \
+ PINMUX_DATA(MMCD1_7_MARK, PORT298_FN2, MSEL4CR_MSEL15_1),
+
+ PINMUX_DATA(MCP_D6_MCP_NAF6_MARK, PORT299_FN1), \
+ PINMUX_DATA(MMCD1_6_MARK, PORT299_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D5_MCP_NAF5_MARK, PORT300_FN1), \
+ PINMUX_DATA(MMCD1_5_MARK, PORT300_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D4_MCP_NAF4_MARK, PORT301_FN1), \
+ PINMUX_DATA(MMCD1_4_MARK, PORT301_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D3_MCP_NAF3_MARK, PORT302_FN1), \
+ PINMUX_DATA(MMCD1_3_MARK, PORT302_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D2_MCP_NAF2_MARK, PORT303_FN1), \
+ PINMUX_DATA(MMCD1_2_MARK, PORT303_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D1_MCP_NAF1_MARK, PORT304_FN1), \
+ PINMUX_DATA(MMCD1_1_MARK, PORT304_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_D0_MCP_NAF0_MARK, PORT305_FN1), \
+ PINMUX_DATA(MMCD1_0_MARK, PORT305_FN2, MSEL4CR_MSEL15_1),
+ PINMUX_DATA(MCP_NBRSTOUT__MARK, PORT306_FN1),
+ PINMUX_DATA(MCP_WE0__MCP_FWE_MARK, PORT309_FN1), \
+ PINMUX_DATA(MCP_RDWR_MCP_FWE_MARK, PORT309_FN2),
+
+ /* MSEL2 special cases */
+ PINMUX_DATA(TSIF2_TS_XX1_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF2_TS_XX2_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_1),
+ PINMUX_DATA(TSIF2_TS_XX3_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF2_TS_XX4_MARK, MSEL2CR_MSEL14_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_1),
+ PINMUX_DATA(TSIF2_TS_XX5_MARK, MSEL2CR_MSEL14_1, MSEL2CR_MSEL13_0,
+ MSEL2CR_MSEL12_0),
+ PINMUX_DATA(TSIF1_TS_XX1_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF1_TS_XX2_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_1),
+ PINMUX_DATA(TSIF1_TS_XX3_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF1_TS_XX4_MARK, MSEL2CR_MSEL11_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_1),
+ PINMUX_DATA(TSIF1_TS_XX5_MARK, MSEL2CR_MSEL11_1, MSEL2CR_MSEL10_0,
+ MSEL2CR_MSEL9_0),
+ PINMUX_DATA(TSIF0_TS_XX1_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(TSIF0_TS_XX2_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_1),
+ PINMUX_DATA(TSIF0_TS_XX3_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(TSIF0_TS_XX4_MARK, MSEL2CR_MSEL8_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_1),
+ PINMUX_DATA(TSIF0_TS_XX5_MARK, MSEL2CR_MSEL8_1, MSEL2CR_MSEL7_0,
+ MSEL2CR_MSEL6_0),
+ PINMUX_DATA(MST1_TS_XX1_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST1_TS_XX2_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_1),
+ PINMUX_DATA(MST1_TS_XX3_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST1_TS_XX4_MARK, MSEL2CR_MSEL5_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_1),
+ PINMUX_DATA(MST1_TS_XX5_MARK, MSEL2CR_MSEL5_1, MSEL2CR_MSEL4_0,
+ MSEL2CR_MSEL3_0),
+ PINMUX_DATA(MST0_TS_XX1_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_0),
+ PINMUX_DATA(MST0_TS_XX2_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_1),
+ PINMUX_DATA(MST0_TS_XX3_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0),
+ PINMUX_DATA(MST0_TS_XX4_MARK, MSEL2CR_MSEL2_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_1),
+ PINMUX_DATA(MST0_TS_XX5_MARK, MSEL2CR_MSEL2_1, MSEL2CR_MSEL1_0,
+ MSEL2CR_MSEL0_0),
+
+ /* MSEL3 special cases */
+ PINMUX_DATA(SDHI0_VCCQ_MC0_ON_MARK, MSEL3CR_MSEL28_1),
+ PINMUX_DATA(SDHI0_VCCQ_MC0_OFF_MARK, MSEL3CR_MSEL28_0),
+ PINMUX_DATA(DEBUG_MON_VIO_MARK, MSEL3CR_MSEL15_0),
+ PINMUX_DATA(DEBUG_MON_LCDD_MARK, MSEL3CR_MSEL15_1),
+ PINMUX_DATA(LCDC_LCDC0_MARK, MSEL3CR_MSEL6_0),
+ PINMUX_DATA(LCDC_LCDC1_MARK, MSEL3CR_MSEL6_1),
+
+ /* MSEL4 special cases */
+ PINMUX_DATA(IRQ9_MEM_INT_MARK, MSEL4CR_MSEL29_0),
+ PINMUX_DATA(IRQ9_MCP_INT_MARK, MSEL4CR_MSEL29_1),
+ PINMUX_DATA(A11_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_0),
+ PINMUX_DATA(KEYOUT8_MARK, MSEL4CR_MSEL13_0, MSEL4CR_MSEL12_1),
+ PINMUX_DATA(TPU4TO3_MARK, MSEL4CR_MSEL13_1, MSEL4CR_MSEL12_0),
+ PINMUX_DATA(RESETA_N_PU_ON_MARK, MSEL4CR_MSEL4_0),
+ PINMUX_DATA(RESETA_N_PU_OFF_MARK, MSEL4CR_MSEL4_1),
+ PINMUX_DATA(EDBGREQ_PD_MARK, MSEL4CR_MSEL1_0),
+ PINMUX_DATA(EDBGREQ_PU_MARK, MSEL4CR_MSEL1_1),
+
+ /* Functions with pull-ups */
+ PINMUX_DATA(KEYIN0_PU_MARK, PORT66_FN2, PORT66_IN_PU),
+ PINMUX_DATA(KEYIN1_PU_MARK, PORT67_FN2, PORT67_IN_PU),
+ PINMUX_DATA(KEYIN2_PU_MARK, PORT68_FN2, PORT68_IN_PU),
+ PINMUX_DATA(KEYIN3_PU_MARK, PORT69_FN2, PORT69_IN_PU),
+ PINMUX_DATA(KEYIN4_PU_MARK, PORT70_FN2, PORT70_IN_PU),
+ PINMUX_DATA(KEYIN5_PU_MARK, PORT71_FN2, PORT71_IN_PU),
+ PINMUX_DATA(KEYIN6_PU_MARK, PORT72_FN2, PORT72_IN_PU),
+ PINMUX_DATA(KEYIN7_PU_MARK, PORT73_FN2, PORT73_IN_PU),
+
+ PINMUX_DATA(SDHID1_0_PU_MARK, PORT259_IN_PU, PORT259_FN1),
+ PINMUX_DATA(SDHID1_1_PU_MARK, PORT260_IN_PU, PORT260_FN1),
+ PINMUX_DATA(SDHID1_2_PU_MARK, PORT261_IN_PU, PORT261_FN1),
+ PINMUX_DATA(SDHID1_3_PU_MARK, PORT262_IN_PU, PORT262_FN1),
+ PINMUX_DATA(SDHICMD1_PU_MARK, PORT263_IN_PU, PORT263_FN1),
+
+ PINMUX_DATA(MMCCMD0_PU_MARK, PORT279_FN1, PORT279_IN_PU,
+ MSEL4CR_MSEL15_0),
+ PINMUX_DATA(MMCCMD1_PU_MARK, PORT297_FN2, PORT279_IN_PU,
+ MSEL4CR_MSEL15_1),
+ PINMUX_DATA(FSIACK_PU_MARK, PORT49_FN1, PORT49_IN_PU),
+ PINMUX_DATA(FSIAILR_PU_MARK, PORT50_FN5, PORT50_IN_PU),
+ PINMUX_DATA(FSIAIBT_PU_MARK, PORT51_FN5, PORT51_IN_PU),
+ PINMUX_DATA(FSIAISLD_PU_MARK, PORT55_FN1, PORT55_IN_PU),
+};
+
+#define _GPIO_PORT(pfx, sfx) PINMUX_GPIO(GPIO_PORT##pfx, PORT##pfx##_DATA)
+#define GPIO_PORT_310() _310(_GPIO_PORT, , unused)
+#define GPIO_FN(str) PINMUX_GPIO(GPIO_FN_##str, str##_MARK)
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ GPIO_PORT_310(),
+
+ /* Table 25-1 (Functions 0-7) */
+ GPIO_FN(VBUS_0),
+ GPIO_FN(GPI0),
+ GPIO_FN(GPI1),
+ GPIO_FN(GPI2),
+ GPIO_FN(GPI3),
+ GPIO_FN(GPI4),
+ GPIO_FN(GPI5),
+ GPIO_FN(GPI6),
+ GPIO_FN(GPI7),
+ GPIO_FN(SCIFA7_RXD),
+ GPIO_FN(SCIFA7_CTS_),
+ GPIO_FN(GPO7), \
+ GPIO_FN(MFG0_OUT2),
+ GPIO_FN(GPO6), \
+ GPIO_FN(MFG1_OUT2),
+ GPIO_FN(GPO5), \
+ GPIO_FN(SCIFA0_SCK), \
+ GPIO_FN(FSICOSLDT3), \
+ GPIO_FN(PORT16_VIO_CKOR),
+ GPIO_FN(SCIFA0_TXD),
+ GPIO_FN(SCIFA7_TXD),
+ GPIO_FN(SCIFA7_RTS_), \
+ GPIO_FN(PORT19_VIO_CKO2),
+ GPIO_FN(GPO0),
+ GPIO_FN(GPO1),
+ GPIO_FN(GPO2), \
+ GPIO_FN(STATUS0),
+ GPIO_FN(GPO3), \
+ GPIO_FN(STATUS1),
+ GPIO_FN(GPO4), \
+ GPIO_FN(STATUS2),
+ GPIO_FN(VINT),
+ GPIO_FN(TCKON),
+ GPIO_FN(XDVFS1), \
+ GPIO_FN(PORT27_I2C_SCL2), \
+ GPIO_FN(PORT27_I2C_SCL3), \
+ GPIO_FN(MFG0_OUT1), \
+ GPIO_FN(PORT27_IROUT),
+ GPIO_FN(XDVFS2), \
+ GPIO_FN(PORT28_I2C_SDA2), \
+ GPIO_FN(PORT28_I2C_SDA3), \
+ GPIO_FN(PORT28_TPU1TO1),
+ GPIO_FN(SIM_RST), \
+ GPIO_FN(PORT29_TPU1TO1),
+ GPIO_FN(SIM_CLK), \
+ GPIO_FN(PORT30_VIO_CKOR),
+ GPIO_FN(SIM_D), \
+ GPIO_FN(PORT31_IROUT),
+ GPIO_FN(SCIFA4_TXD),
+ GPIO_FN(SCIFA4_RXD), \
+ GPIO_FN(XWUP),
+ GPIO_FN(SCIFA4_RTS_),
+ GPIO_FN(SCIFA4_CTS_),
+ GPIO_FN(FSIBOBT), \
+ GPIO_FN(FSIBIBT),
+ GPIO_FN(FSIBOLR), \
+ GPIO_FN(FSIBILR),
+ GPIO_FN(FSIBOSLD),
+ GPIO_FN(FSIBISLD),
+ GPIO_FN(VACK),
+ GPIO_FN(XTAL1L),
+ GPIO_FN(SCIFA0_RTS_), \
+ GPIO_FN(FSICOSLDT2),
+ GPIO_FN(SCIFA0_RXD),
+ GPIO_FN(SCIFA0_CTS_), \
+ GPIO_FN(FSICOSLDT1),
+ GPIO_FN(FSICOBT), \
+ GPIO_FN(FSICIBT), \
+ GPIO_FN(FSIDOBT), \
+ GPIO_FN(FSIDIBT),
+ GPIO_FN(FSICOLR), \
+ GPIO_FN(FSICILR), \
+ GPIO_FN(FSIDOLR), \
+ GPIO_FN(FSIDILR),
+ GPIO_FN(FSICOSLD), \
+ GPIO_FN(PORT47_FSICSPDIF),
+ GPIO_FN(FSICISLD), \
+ GPIO_FN(FSIDISLD),
+ GPIO_FN(FSIACK), \
+ GPIO_FN(PORT49_IRDA_OUT), \
+ GPIO_FN(PORT49_IROUT), \
+ GPIO_FN(FSIAOMC),
+ GPIO_FN(FSIAOLR), \
+ GPIO_FN(BBIF2_TSYNC2), \
+ GPIO_FN(TPU2TO2), \
+ GPIO_FN(FSIAILR),
+
+ GPIO_FN(FSIAOBT), \
+ GPIO_FN(BBIF2_TSCK2), \
+ GPIO_FN(TPU2TO3), \
+ GPIO_FN(FSIAIBT),
+ GPIO_FN(FSIAOSLD), \
+ GPIO_FN(BBIF2_TXD2),
+ GPIO_FN(FSIASPDIF), \
+ GPIO_FN(PORT53_IRDA_IN), \
+ GPIO_FN(TPU3TO3), \
+ GPIO_FN(FSIBSPDIF), \
+ GPIO_FN(PORT53_FSICSPDIF),
+ GPIO_FN(FSIBCK), \
+ GPIO_FN(PORT54_IRDA_FIRSEL), \
+ GPIO_FN(TPU3TO2), \
+ GPIO_FN(FSIBOMC), \
+ GPIO_FN(FSICCK), \
+ GPIO_FN(FSICOMC),
+ GPIO_FN(FSIAISLD), \
+ GPIO_FN(TPU0TO0),
+ GPIO_FN(A0), \
+ GPIO_FN(BS_),
+ GPIO_FN(A12), \
+ GPIO_FN(PORT58_KEYOUT7), \
+ GPIO_FN(TPU4TO2),
+ GPIO_FN(A13), \
+ GPIO_FN(PORT59_KEYOUT6), \
+ GPIO_FN(TPU0TO1),
+ GPIO_FN(A14), \
+ GPIO_FN(KEYOUT5),
+ GPIO_FN(A15), \
+ GPIO_FN(KEYOUT4),
+ GPIO_FN(A16), \
+ GPIO_FN(KEYOUT3), \
+ GPIO_FN(MSIOF0_SS1),
+ GPIO_FN(A17), \
+ GPIO_FN(KEYOUT2), \
+ GPIO_FN(MSIOF0_TSYNC),
+ GPIO_FN(A18), \
+ GPIO_FN(KEYOUT1), \
+ GPIO_FN(MSIOF0_TSCK),
+ GPIO_FN(A19), \
+ GPIO_FN(KEYOUT0), \
+ GPIO_FN(MSIOF0_TXD),
+ GPIO_FN(A20), \
+ GPIO_FN(KEYIN0), \
+ GPIO_FN(MSIOF0_RSCK),
+ GPIO_FN(A21), \
+ GPIO_FN(KEYIN1), \
+ GPIO_FN(MSIOF0_RSYNC),
+ GPIO_FN(A22), \
+ GPIO_FN(KEYIN2), \
+ GPIO_FN(MSIOF0_MCK0),
+ GPIO_FN(A23), \
+ GPIO_FN(KEYIN3), \
+ GPIO_FN(MSIOF0_MCK1),
+ GPIO_FN(A24), \
+ GPIO_FN(KEYIN4), \
+ GPIO_FN(MSIOF0_RXD),
+ GPIO_FN(A25), \
+ GPIO_FN(KEYIN5), \
+ GPIO_FN(MSIOF0_SS2),
+ GPIO_FN(A26), \
+ GPIO_FN(KEYIN6),
+ GPIO_FN(KEYIN7),
+ GPIO_FN(D0_NAF0),
+ GPIO_FN(D1_NAF1),
+ GPIO_FN(D2_NAF2),
+ GPIO_FN(D3_NAF3),
+ GPIO_FN(D4_NAF4),
+ GPIO_FN(D5_NAF5),
+ GPIO_FN(D6_NAF6),
+ GPIO_FN(D7_NAF7),
+ GPIO_FN(D8_NAF8),
+ GPIO_FN(D9_NAF9),
+ GPIO_FN(D10_NAF10),
+ GPIO_FN(D11_NAF11),
+ GPIO_FN(D12_NAF12),
+ GPIO_FN(D13_NAF13),
+ GPIO_FN(D14_NAF14),
+ GPIO_FN(D15_NAF15),
+ GPIO_FN(CS4_),
+ GPIO_FN(CS5A_), \
+ GPIO_FN(PORT91_RDWR),
+ GPIO_FN(CS5B_), \
+ GPIO_FN(FCE1_),
+ GPIO_FN(CS6B_), \
+ GPIO_FN(DACK0),
+ GPIO_FN(FCE0_), \
+ GPIO_FN(CS6A_),
+ GPIO_FN(WAIT_), \
+ GPIO_FN(DREQ0),
+ GPIO_FN(RD__FSC),
+ GPIO_FN(WE0__FWE), \
+ GPIO_FN(RDWR_FWE),
+ GPIO_FN(WE1_),
+ GPIO_FN(FRB),
+ GPIO_FN(CKO),
+ GPIO_FN(NBRSTOUT_),
+ GPIO_FN(NBRST_),
+ GPIO_FN(BBIF2_TXD),
+ GPIO_FN(BBIF2_RXD),
+ GPIO_FN(BBIF2_SYNC),
+ GPIO_FN(BBIF2_SCK),
+ GPIO_FN(SCIFA3_CTS_), \
+ GPIO_FN(MFG3_IN2),
+ GPIO_FN(SCIFA3_RXD), \
+ GPIO_FN(MFG3_IN1),
+ GPIO_FN(BBIF1_SS2), \
+ GPIO_FN(SCIFA3_RTS_), \
+ GPIO_FN(MFG3_OUT1),
+ GPIO_FN(SCIFA3_TXD),
+ GPIO_FN(HSI_RX_DATA), \
+ GPIO_FN(BBIF1_RXD),
+ GPIO_FN(HSI_TX_WAKE), \
+ GPIO_FN(BBIF1_TSCK),
+ GPIO_FN(HSI_TX_DATA), \
+ GPIO_FN(BBIF1_TSYNC),
+ GPIO_FN(HSI_TX_READY), \
+ GPIO_FN(BBIF1_TXD),
+ GPIO_FN(HSI_RX_READY), \
+ GPIO_FN(BBIF1_RSCK), \
+ GPIO_FN(PORT115_I2C_SCL2), \
+ GPIO_FN(PORT115_I2C_SCL3),
+ GPIO_FN(HSI_RX_WAKE), \
+ GPIO_FN(BBIF1_RSYNC), \
+ GPIO_FN(PORT116_I2C_SDA2), \
+ GPIO_FN(PORT116_I2C_SDA3),
+ GPIO_FN(HSI_RX_FLAG), \
+ GPIO_FN(BBIF1_SS1), \
+ GPIO_FN(BBIF1_FLOW),
+ GPIO_FN(HSI_TX_FLAG),
+ GPIO_FN(VIO_VD), \
+ GPIO_FN(PORT128_LCD2VSYN), \
+ GPIO_FN(VIO2_VD), \
+ GPIO_FN(LCD2D0),
+
+ GPIO_FN(VIO_HD), \
+ GPIO_FN(PORT129_LCD2HSYN), \
+ GPIO_FN(PORT129_LCD2CS_), \
+ GPIO_FN(VIO2_HD), \
+ GPIO_FN(LCD2D1),
+ GPIO_FN(VIO_D0), \
+ GPIO_FN(PORT130_MSIOF2_RXD), \
+ GPIO_FN(LCD2D10),
+ GPIO_FN(VIO_D1), \
+ GPIO_FN(PORT131_KEYOUT6), \
+ GPIO_FN(PORT131_MSIOF2_SS1), \
+ GPIO_FN(PORT131_KEYOUT11), \
+ GPIO_FN(LCD2D11),
+ GPIO_FN(VIO_D2), \
+ GPIO_FN(PORT132_KEYOUT7), \
+ GPIO_FN(PORT132_MSIOF2_SS2), \
+ GPIO_FN(PORT132_KEYOUT10), \
+ GPIO_FN(LCD2D12),
+ GPIO_FN(VIO_D3), \
+ GPIO_FN(MSIOF2_TSYNC), \
+ GPIO_FN(LCD2D13),
+ GPIO_FN(VIO_D4), \
+ GPIO_FN(MSIOF2_TXD), \
+ GPIO_FN(LCD2D14),
+ GPIO_FN(VIO_D5), \
+ GPIO_FN(MSIOF2_TSCK), \
+ GPIO_FN(LCD2D15),
+ GPIO_FN(VIO_D6), \
+ GPIO_FN(PORT136_KEYOUT8), \
+ GPIO_FN(LCD2D16),
+ GPIO_FN(VIO_D7), \
+ GPIO_FN(PORT137_KEYOUT9), \
+ GPIO_FN(LCD2D17),
+ GPIO_FN(VIO_D8), \
+ GPIO_FN(PORT138_KEYOUT8), \
+ GPIO_FN(VIO2_D0), \
+ GPIO_FN(LCD2D6),
+ GPIO_FN(VIO_D9), \
+ GPIO_FN(PORT139_KEYOUT9), \
+ GPIO_FN(VIO2_D1), \
+ GPIO_FN(LCD2D7),
+ GPIO_FN(VIO_D10), \
+ GPIO_FN(TPU0TO2), \
+ GPIO_FN(VIO2_D2), \
+ GPIO_FN(LCD2D8),
+ GPIO_FN(VIO_D11), \
+ GPIO_FN(TPU0TO3), \
+ GPIO_FN(VIO2_D3), \
+ GPIO_FN(LCD2D9),
+ GPIO_FN(VIO_D12), \
+ GPIO_FN(PORT142_KEYOUT10), \
+ GPIO_FN(VIO2_D4), \
+ GPIO_FN(LCD2D2),
+ GPIO_FN(VIO_D13), \
+ GPIO_FN(PORT143_KEYOUT11), \
+ GPIO_FN(PORT143_KEYOUT6), \
+ GPIO_FN(VIO2_D5), \
+ GPIO_FN(LCD2D3),
+ GPIO_FN(VIO_D14), \
+ GPIO_FN(PORT144_KEYOUT7), \
+ GPIO_FN(VIO2_D6), \
+ GPIO_FN(LCD2D4),
+ GPIO_FN(VIO_D15), \
+ GPIO_FN(TPU1TO3), \
+ GPIO_FN(PORT145_LCD2DISP), \
+ GPIO_FN(PORT145_LCD2RS), \
+ GPIO_FN(VIO2_D7), \
+ GPIO_FN(LCD2D5),
+ GPIO_FN(VIO_CLK), \
+ GPIO_FN(LCD2DCK), \
+ GPIO_FN(PORT146_LCD2WR_), \
+ GPIO_FN(VIO2_CLK), \
+ GPIO_FN(LCD2D18),
+ GPIO_FN(VIO_FIELD), \
+ GPIO_FN(LCD2RD_), \
+ GPIO_FN(VIO2_FIELD), \
+ GPIO_FN(LCD2D19),
+ GPIO_FN(VIO_CKO),
+ GPIO_FN(A27), \
+ GPIO_FN(PORT149_RDWR), \
+ GPIO_FN(MFG0_IN1), \
+ GPIO_FN(PORT149_KEYOUT9),
+ GPIO_FN(MFG0_IN2),
+ GPIO_FN(TS_SPSYNC3), \
+ GPIO_FN(MSIOF2_RSCK),
+ GPIO_FN(TS_SDAT3), \
+ GPIO_FN(MSIOF2_RSYNC),
+ GPIO_FN(TPU1TO2), \
+ GPIO_FN(TS_SDEN3), \
+ GPIO_FN(PORT153_MSIOF2_SS1),
+ GPIO_FN(SCIFA2_TXD1), \
+ GPIO_FN(MSIOF2_MCK0),
+ GPIO_FN(SCIFA2_RXD1), \
+ GPIO_FN(MSIOF2_MCK1),
+ GPIO_FN(SCIFA2_RTS1_), \
+ GPIO_FN(PORT156_MSIOF2_SS2),
+ GPIO_FN(SCIFA2_CTS1_), \
+ GPIO_FN(PORT157_MSIOF2_RXD),
+ GPIO_FN(DINT_), \
+ GPIO_FN(SCIFA2_SCK1), \
+ GPIO_FN(TS_SCK3),
+ GPIO_FN(PORT159_SCIFB_SCK), \
+ GPIO_FN(PORT159_SCIFA5_SCK), \
+ GPIO_FN(NMI),
+ GPIO_FN(PORT160_SCIFB_TXD), \
+ GPIO_FN(PORT160_SCIFA5_TXD),
+ GPIO_FN(PORT161_SCIFB_CTS_), \
+ GPIO_FN(PORT161_SCIFA5_CTS_),
+ GPIO_FN(PORT162_SCIFB_RXD), \
+ GPIO_FN(PORT162_SCIFA5_RXD),
+ GPIO_FN(PORT163_SCIFB_RTS_), \
+ GPIO_FN(PORT163_SCIFA5_RTS_), \
+ GPIO_FN(TPU3TO0),
+ GPIO_FN(LCDD0),
+ GPIO_FN(LCDD1), \
+ GPIO_FN(PORT193_SCIFA5_CTS_), \
+ GPIO_FN(BBIF2_TSYNC1),
+ GPIO_FN(LCDD2), \
+ GPIO_FN(PORT194_SCIFA5_RTS_), \
+ GPIO_FN(BBIF2_TSCK1),
+ GPIO_FN(LCDD3), \
+ GPIO_FN(PORT195_SCIFA5_RXD), \
+ GPIO_FN(BBIF2_TXD1),
+ GPIO_FN(LCDD4), \
+ GPIO_FN(PORT196_SCIFA5_TXD),
+ GPIO_FN(LCDD5), \
+ GPIO_FN(PORT197_SCIFA5_SCK), \
+ GPIO_FN(MFG2_OUT2), \
+ GPIO_FN(TPU2TO1),
+ GPIO_FN(LCDD6),
+ GPIO_FN(LCDD7), \
+ GPIO_FN(TPU4TO1), \
+ GPIO_FN(MFG4_OUT2),
+ GPIO_FN(LCDD8), \
+ GPIO_FN(D16),
+ GPIO_FN(LCDD9), \
+ GPIO_FN(D17),
+ GPIO_FN(LCDD10), \
+ GPIO_FN(D18),
+ GPIO_FN(LCDD11), \
+ GPIO_FN(D19),
+ GPIO_FN(LCDD12), \
+ GPIO_FN(D20),
+ GPIO_FN(LCDD13), \
+ GPIO_FN(D21),
+ GPIO_FN(LCDD14), \
+ GPIO_FN(D22),
+ GPIO_FN(LCDD15), \
+ GPIO_FN(PORT207_MSIOF0L_SS1), \
+ GPIO_FN(D23),
+ GPIO_FN(LCDD16), \
+ GPIO_FN(PORT208_MSIOF0L_SS2), \
+ GPIO_FN(D24),
+ GPIO_FN(LCDD17), \
+ GPIO_FN(D25),
+ GPIO_FN(LCDD18), \
+ GPIO_FN(DREQ2), \
+ GPIO_FN(PORT210_MSIOF0L_SS1), \
+ GPIO_FN(D26),
+ GPIO_FN(LCDD19), \
+ GPIO_FN(PORT211_MSIOF0L_SS2), \
+ GPIO_FN(D27),
+ GPIO_FN(LCDD20), \
+ GPIO_FN(TS_SPSYNC1), \
+ GPIO_FN(MSIOF0L_MCK0), \
+ GPIO_FN(D28),
+ GPIO_FN(LCDD21), \
+ GPIO_FN(TS_SDAT1), \
+ GPIO_FN(MSIOF0L_MCK1), \
+ GPIO_FN(D29),
+ GPIO_FN(LCDD22), \
+ GPIO_FN(TS_SDEN1), \
+ GPIO_FN(MSIOF0L_RSCK), \
+ GPIO_FN(D30),
+ GPIO_FN(LCDD23), \
+ GPIO_FN(TS_SCK1), \
+ GPIO_FN(MSIOF0L_RSYNC), \
+ GPIO_FN(D31),
+ GPIO_FN(LCDDCK), \
+ GPIO_FN(LCDWR_),
+ GPIO_FN(LCDRD_), \
+ GPIO_FN(DACK2), \
+ GPIO_FN(PORT217_LCD2RS), \
+ GPIO_FN(MSIOF0L_TSYNC), \
+ GPIO_FN(VIO2_FIELD3), \
+ GPIO_FN(PORT217_LCD2DISP),
+ GPIO_FN(LCDHSYN), \
+ GPIO_FN(LCDCS_), \
+ GPIO_FN(LCDCS2_), \
+ GPIO_FN(DACK3), \
+ GPIO_FN(PORT218_VIO_CKOR),
+ GPIO_FN(LCDDISP), \
+ GPIO_FN(LCDRS), \
+ GPIO_FN(PORT219_LCD2WR_), \
+ GPIO_FN(DREQ3), \
+ GPIO_FN(MSIOF0L_TSCK), \
+ GPIO_FN(VIO2_CLK3), \
+ GPIO_FN(LCD2DCK_2),
+ GPIO_FN(LCDVSYN), \
+ GPIO_FN(LCDVSYN2),
+ GPIO_FN(LCDLCLK), \
+ GPIO_FN(DREQ1), \
+ GPIO_FN(PORT221_LCD2CS_), \
+ GPIO_FN(PWEN), \
+ GPIO_FN(MSIOF0L_RXD), \
+ GPIO_FN(VIO2_HD3), \
+ GPIO_FN(PORT221_LCD2HSYN),
+ GPIO_FN(LCDDON), \
+ GPIO_FN(LCDDON2), \
+ GPIO_FN(DACK1), \
+ GPIO_FN(OVCN), \
+ GPIO_FN(MSIOF0L_TXD), \
+ GPIO_FN(VIO2_VD3), \
+ GPIO_FN(PORT222_LCD2VSYN),
+
+ GPIO_FN(SCIFA1_TXD), \
+ GPIO_FN(OVCN2),
+ GPIO_FN(EXTLP), \
+ GPIO_FN(SCIFA1_SCK), \
+ GPIO_FN(PORT226_VIO_CKO2),
+ GPIO_FN(SCIFA1_RTS_), \
+ GPIO_FN(IDIN),
+ GPIO_FN(SCIFA1_RXD),
+ GPIO_FN(SCIFA1_CTS_), \
+ GPIO_FN(MFG1_IN1),
+ GPIO_FN(MSIOF1_TXD), \
+ GPIO_FN(SCIFA2_TXD2),
+ GPIO_FN(MSIOF1_TSYNC), \
+ GPIO_FN(SCIFA2_CTS2_),
+ GPIO_FN(MSIOF1_TSCK), \
+ GPIO_FN(SCIFA2_SCK2),
+ GPIO_FN(MSIOF1_RXD), \
+ GPIO_FN(SCIFA2_RXD2),
+ GPIO_FN(MSIOF1_RSCK), \
+ GPIO_FN(SCIFA2_RTS2_), \
+ GPIO_FN(VIO2_CLK2), \
+ GPIO_FN(LCD2D20),
+ GPIO_FN(MSIOF1_RSYNC), \
+ GPIO_FN(MFG1_IN2), \
+ GPIO_FN(VIO2_VD2), \
+ GPIO_FN(LCD2D21),
+ GPIO_FN(MSIOF1_MCK0), \
+ GPIO_FN(PORT236_I2C_SDA2),
+ GPIO_FN(MSIOF1_MCK1), \
+ GPIO_FN(PORT237_I2C_SCL2),
+ GPIO_FN(MSIOF1_SS1), \
+ GPIO_FN(VIO2_FIELD2), \
+ GPIO_FN(LCD2D22),
+ GPIO_FN(MSIOF1_SS2), \
+ GPIO_FN(VIO2_HD2), \
+ GPIO_FN(LCD2D23),
+ GPIO_FN(SCIFA6_TXD),
+ GPIO_FN(PORT241_IRDA_OUT), \
+ GPIO_FN(PORT241_IROUT), \
+ GPIO_FN(MFG4_OUT1), \
+ GPIO_FN(TPU4TO0),
+ GPIO_FN(PORT242_IRDA_IN), \
+ GPIO_FN(MFG4_IN2),
+ GPIO_FN(PORT243_IRDA_FIRSEL), \
+ GPIO_FN(PORT243_VIO_CKO2),
+ GPIO_FN(PORT244_SCIFA5_CTS_), \
+ GPIO_FN(MFG2_IN1), \
+ GPIO_FN(PORT244_SCIFB_CTS_), \
+ GPIO_FN(MSIOF2R_RXD),
+ GPIO_FN(PORT245_SCIFA5_RTS_), \
+ GPIO_FN(MFG2_IN2), \
+ GPIO_FN(PORT245_SCIFB_RTS_), \
+ GPIO_FN(MSIOF2R_TXD),
+ GPIO_FN(PORT246_SCIFA5_RXD), \
+ GPIO_FN(MFG1_OUT1), \
+ GPIO_FN(PORT246_SCIFB_RXD), \
+ GPIO_FN(TPU1TO0),
+ GPIO_FN(PORT247_SCIFA5_TXD), \
+ GPIO_FN(MFG3_OUT2), \
+ GPIO_FN(PORT247_SCIFB_TXD), \
+ GPIO_FN(TPU3TO1),
+ GPIO_FN(PORT248_SCIFA5_SCK), \
+ GPIO_FN(MFG2_OUT1), \
+ GPIO_FN(PORT248_SCIFB_SCK), \
+ GPIO_FN(TPU2TO0), \
+ GPIO_FN(PORT248_I2C_SCL3), \
+ GPIO_FN(MSIOF2R_TSCK),
+ GPIO_FN(PORT249_IROUT), \
+ GPIO_FN(MFG4_IN1), \
+ GPIO_FN(PORT249_I2C_SDA3), \
+ GPIO_FN(MSIOF2R_TSYNC),
+ GPIO_FN(SDHICLK0),
+ GPIO_FN(SDHICD0),
+ GPIO_FN(SDHID0_0),
+ GPIO_FN(SDHID0_1),
+ GPIO_FN(SDHID0_2),
+ GPIO_FN(SDHID0_3),
+ GPIO_FN(SDHICMD0),
+ GPIO_FN(SDHIWP0),
+ GPIO_FN(SDHICLK1),
+ GPIO_FN(SDHID1_0), \
+ GPIO_FN(TS_SPSYNC2),
+ GPIO_FN(SDHID1_1), \
+ GPIO_FN(TS_SDAT2),
+ GPIO_FN(SDHID1_2), \
+ GPIO_FN(TS_SDEN2),
+ GPIO_FN(SDHID1_3), \
+ GPIO_FN(TS_SCK2),
+ GPIO_FN(SDHICMD1),
+ GPIO_FN(SDHICLK2),
+ GPIO_FN(SDHID2_0), \
+ GPIO_FN(TS_SPSYNC4),
+ GPIO_FN(SDHID2_1), \
+ GPIO_FN(TS_SDAT4),
+ GPIO_FN(SDHID2_2), \
+ GPIO_FN(TS_SDEN4),
+ GPIO_FN(SDHID2_3), \
+ GPIO_FN(TS_SCK4),
+ GPIO_FN(SDHICMD2),
+ GPIO_FN(MMCCLK0),
+ GPIO_FN(MMCD0_0),
+ GPIO_FN(MMCD0_1),
+ GPIO_FN(MMCD0_2),
+ GPIO_FN(MMCD0_3),
+ GPIO_FN(MMCD0_4), \
+ GPIO_FN(TS_SPSYNC5),
+ GPIO_FN(MMCD0_5), \
+ GPIO_FN(TS_SDAT5),
+ GPIO_FN(MMCD0_6), \
+ GPIO_FN(TS_SDEN5),
+ GPIO_FN(MMCD0_7), \
+ GPIO_FN(TS_SCK5),
+ GPIO_FN(MMCCMD0),
+ GPIO_FN(RESETOUTS_), \
+ GPIO_FN(EXTAL2OUT),
+ GPIO_FN(MCP_WAIT__MCP_FRB),
+ GPIO_FN(MCP_CKO), \
+ GPIO_FN(MMCCLK1),
+ GPIO_FN(MCP_D15_MCP_NAF15),
+ GPIO_FN(MCP_D14_MCP_NAF14),
+ GPIO_FN(MCP_D13_MCP_NAF13),
+ GPIO_FN(MCP_D12_MCP_NAF12),
+ GPIO_FN(MCP_D11_MCP_NAF11),
+ GPIO_FN(MCP_D10_MCP_NAF10),
+ GPIO_FN(MCP_D9_MCP_NAF9),
+ GPIO_FN(MCP_D8_MCP_NAF8), \
+ GPIO_FN(MMCCMD1),
+ GPIO_FN(MCP_D7_MCP_NAF7), \
+ GPIO_FN(MMCD1_7),
+
+ GPIO_FN(MCP_D6_MCP_NAF6), \
+ GPIO_FN(MMCD1_6),
+ GPIO_FN(MCP_D5_MCP_NAF5), \
+ GPIO_FN(MMCD1_5),
+ GPIO_FN(MCP_D4_MCP_NAF4), \
+ GPIO_FN(MMCD1_4),
+ GPIO_FN(MCP_D3_MCP_NAF3), \
+ GPIO_FN(MMCD1_3),
+ GPIO_FN(MCP_D2_MCP_NAF2), \
+ GPIO_FN(MMCD1_2),
+ GPIO_FN(MCP_D1_MCP_NAF1), \
+ GPIO_FN(MMCD1_1),
+ GPIO_FN(MCP_D0_MCP_NAF0), \
+ GPIO_FN(MMCD1_0),
+ GPIO_FN(MCP_NBRSTOUT_),
+ GPIO_FN(MCP_WE0__MCP_FWE), \
+ GPIO_FN(MCP_RDWR_MCP_FWE),
+
+ /* MSEL2 special cases */
+ GPIO_FN(TSIF2_TS_XX1),
+ GPIO_FN(TSIF2_TS_XX2),
+ GPIO_FN(TSIF2_TS_XX3),
+ GPIO_FN(TSIF2_TS_XX4),
+ GPIO_FN(TSIF2_TS_XX5),
+ GPIO_FN(TSIF1_TS_XX1),
+ GPIO_FN(TSIF1_TS_XX2),
+ GPIO_FN(TSIF1_TS_XX3),
+ GPIO_FN(TSIF1_TS_XX4),
+ GPIO_FN(TSIF1_TS_XX5),
+ GPIO_FN(TSIF0_TS_XX1),
+ GPIO_FN(TSIF0_TS_XX2),
+ GPIO_FN(TSIF0_TS_XX3),
+ GPIO_FN(TSIF0_TS_XX4),
+ GPIO_FN(TSIF0_TS_XX5),
+ GPIO_FN(MST1_TS_XX1),
+ GPIO_FN(MST1_TS_XX2),
+ GPIO_FN(MST1_TS_XX3),
+ GPIO_FN(MST1_TS_XX4),
+ GPIO_FN(MST1_TS_XX5),
+ GPIO_FN(MST0_TS_XX1),
+ GPIO_FN(MST0_TS_XX2),
+ GPIO_FN(MST0_TS_XX3),
+ GPIO_FN(MST0_TS_XX4),
+ GPIO_FN(MST0_TS_XX5),
+
+ /* MSEL3 special cases */
+ GPIO_FN(SDHI0_VCCQ_MC0_ON),
+ GPIO_FN(SDHI0_VCCQ_MC0_OFF),
+ GPIO_FN(DEBUG_MON_VIO),
+ GPIO_FN(DEBUG_MON_LCDD),
+ GPIO_FN(LCDC_LCDC0),
+ GPIO_FN(LCDC_LCDC1),
+
+ /* MSEL4 special cases */
+ GPIO_FN(IRQ9_MEM_INT),
+ GPIO_FN(IRQ9_MCP_INT),
+ GPIO_FN(A11),
+ GPIO_FN(KEYOUT8),
+ GPIO_FN(TPU4TO3),
+ GPIO_FN(RESETA_N_PU_ON),
+ GPIO_FN(RESETA_N_PU_OFF),
+ GPIO_FN(EDBGREQ_PD),
+ GPIO_FN(EDBGREQ_PU),
+
+ /* Functions with pull-ups */
+ GPIO_FN(KEYIN0_PU),
+ GPIO_FN(KEYIN1_PU),
+ GPIO_FN(KEYIN2_PU),
+ GPIO_FN(KEYIN3_PU),
+ GPIO_FN(KEYIN4_PU),
+ GPIO_FN(KEYIN5_PU),
+ GPIO_FN(KEYIN6_PU),
+ GPIO_FN(KEYIN7_PU),
+ GPIO_FN(SDHID1_0_PU),
+ GPIO_FN(SDHID1_1_PU),
+ GPIO_FN(SDHID1_2_PU),
+ GPIO_FN(SDHID1_3_PU),
+ GPIO_FN(SDHICMD1_PU),
+ GPIO_FN(MMCCMD0_PU),
+ GPIO_FN(MMCCMD1_PU),
+ GPIO_FN(FSIACK_PU),
+ GPIO_FN(FSIAILR_PU),
+ GPIO_FN(FSIAIBT_PU),
+ GPIO_FN(FSIAISLD_PU),
+};
+
+#define PORTCR(nr, reg) \
+ { PINMUX_CFG_REG("PORT" nr "CR", reg, 8, 4) { \
+ 0, \
+ /*0001*/ PORT##nr##_OUT , \
+ /*0010*/ PORT##nr##_IN , 0, 0, 0, 0, 0, 0, 0, \
+ /*1010*/ PORT##nr##_IN_PD, 0, 0, 0, \
+ /*1110*/ PORT##nr##_IN_PU, 0, \
+ PORT##nr##_FN0, PORT##nr##_FN1, PORT##nr##_FN2, \
+ PORT##nr##_FN3, PORT##nr##_FN4, PORT##nr##_FN5, \
+ PORT##nr##_FN6, PORT##nr##_FN7, 0, 0, 0, 0, 0, 0, 0, 0 } \
+ }
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ PORTCR(0, 0xe6050000), /* PORT0CR */
+ PORTCR(1, 0xe6050001), /* PORT1CR */
+ PORTCR(2, 0xe6050002), /* PORT2CR */
+ PORTCR(3, 0xe6050003), /* PORT3CR */
+ PORTCR(4, 0xe6050004), /* PORT4CR */
+ PORTCR(5, 0xe6050005), /* PORT5CR */
+ PORTCR(6, 0xe6050006), /* PORT6CR */
+ PORTCR(7, 0xe6050007), /* PORT7CR */
+ PORTCR(8, 0xe6050008), /* PORT8CR */
+ PORTCR(9, 0xe6050009), /* PORT9CR */
+
+ PORTCR(10, 0xe605000a), /* PORT10CR */
+ PORTCR(11, 0xe605000b), /* PORT11CR */
+ PORTCR(12, 0xe605000c), /* PORT12CR */
+ PORTCR(13, 0xe605000d), /* PORT13CR */
+ PORTCR(14, 0xe605000e), /* PORT14CR */
+ PORTCR(15, 0xe605000f), /* PORT15CR */
+ PORTCR(16, 0xe6050010), /* PORT16CR */
+ PORTCR(17, 0xe6050011), /* PORT17CR */
+ PORTCR(18, 0xe6050012), /* PORT18CR */
+ PORTCR(19, 0xe6050013), /* PORT19CR */
+
+ PORTCR(20, 0xe6050014), /* PORT20CR */
+ PORTCR(21, 0xe6050015), /* PORT21CR */
+ PORTCR(22, 0xe6050016), /* PORT22CR */
+ PORTCR(23, 0xe6050017), /* PORT23CR */
+ PORTCR(24, 0xe6050018), /* PORT24CR */
+ PORTCR(25, 0xe6050019), /* PORT25CR */
+ PORTCR(26, 0xe605001a), /* PORT26CR */
+ PORTCR(27, 0xe605001b), /* PORT27CR */
+ PORTCR(28, 0xe605001c), /* PORT28CR */
+ PORTCR(29, 0xe605001d), /* PORT29CR */
+
+ PORTCR(30, 0xe605001e), /* PORT30CR */
+ PORTCR(31, 0xe605001f), /* PORT31CR */
+ PORTCR(32, 0xe6051020), /* PORT32CR */
+ PORTCR(33, 0xe6051021), /* PORT33CR */
+ PORTCR(34, 0xe6051022), /* PORT34CR */
+ PORTCR(35, 0xe6051023), /* PORT35CR */
+ PORTCR(36, 0xe6051024), /* PORT36CR */
+ PORTCR(37, 0xe6051025), /* PORT37CR */
+ PORTCR(38, 0xe6051026), /* PORT38CR */
+ PORTCR(39, 0xe6051027), /* PORT39CR */
+
+ PORTCR(40, 0xe6051028), /* PORT40CR */
+ PORTCR(41, 0xe6051029), /* PORT41CR */
+ PORTCR(42, 0xe605102a), /* PORT42CR */
+ PORTCR(43, 0xe605102b), /* PORT43CR */
+ PORTCR(44, 0xe605102c), /* PORT44CR */
+ PORTCR(45, 0xe605102d), /* PORT45CR */
+ PORTCR(46, 0xe605102e), /* PORT46CR */
+ PORTCR(47, 0xe605102f), /* PORT47CR */
+ PORTCR(48, 0xe6051030), /* PORT48CR */
+ PORTCR(49, 0xe6051031), /* PORT49CR */
+
+ PORTCR(50, 0xe6051032), /* PORT50CR */
+ PORTCR(51, 0xe6051033), /* PORT51CR */
+ PORTCR(52, 0xe6051034), /* PORT52CR */
+ PORTCR(53, 0xe6051035), /* PORT53CR */
+ PORTCR(54, 0xe6051036), /* PORT54CR */
+ PORTCR(55, 0xe6051037), /* PORT55CR */
+ PORTCR(56, 0xe6051038), /* PORT56CR */
+ PORTCR(57, 0xe6051039), /* PORT57CR */
+ PORTCR(58, 0xe605103a), /* PORT58CR */
+ PORTCR(59, 0xe605103b), /* PORT59CR */
+
+ PORTCR(60, 0xe605103c), /* PORT60CR */
+ PORTCR(61, 0xe605103d), /* PORT61CR */
+ PORTCR(62, 0xe605103e), /* PORT62CR */
+ PORTCR(63, 0xe605103f), /* PORT63CR */
+ PORTCR(64, 0xe6051040), /* PORT64CR */
+ PORTCR(65, 0xe6051041), /* PORT65CR */
+ PORTCR(66, 0xe6051042), /* PORT66CR */
+ PORTCR(67, 0xe6051043), /* PORT67CR */
+ PORTCR(68, 0xe6051044), /* PORT68CR */
+ PORTCR(69, 0xe6051045), /* PORT69CR */
+
+ PORTCR(70, 0xe6051046), /* PORT70CR */
+ PORTCR(71, 0xe6051047), /* PORT71CR */
+ PORTCR(72, 0xe6051048), /* PORT72CR */
+ PORTCR(73, 0xe6051049), /* PORT73CR */
+ PORTCR(74, 0xe605104a), /* PORT74CR */
+ PORTCR(75, 0xe605104b), /* PORT75CR */
+ PORTCR(76, 0xe605104c), /* PORT76CR */
+ PORTCR(77, 0xe605104d), /* PORT77CR */
+ PORTCR(78, 0xe605104e), /* PORT78CR */
+ PORTCR(79, 0xe605104f), /* PORT79CR */
+
+ PORTCR(80, 0xe6051050), /* PORT80CR */
+ PORTCR(81, 0xe6051051), /* PORT81CR */
+ PORTCR(82, 0xe6051052), /* PORT82CR */
+ PORTCR(83, 0xe6051053), /* PORT83CR */
+ PORTCR(84, 0xe6051054), /* PORT84CR */
+ PORTCR(85, 0xe6051055), /* PORT85CR */
+ PORTCR(86, 0xe6051056), /* PORT86CR */
+ PORTCR(87, 0xe6051057), /* PORT87CR */
+ PORTCR(88, 0xe6051058), /* PORT88CR */
+ PORTCR(89, 0xe6051059), /* PORT89CR */
+
+ PORTCR(90, 0xe605105a), /* PORT90CR */
+ PORTCR(91, 0xe605105b), /* PORT91CR */
+ PORTCR(92, 0xe605105c), /* PORT92CR */
+ PORTCR(93, 0xe605105d), /* PORT93CR */
+ PORTCR(94, 0xe605105e), /* PORT94CR */
+ PORTCR(95, 0xe605105f), /* PORT95CR */
+ PORTCR(96, 0xe6052060), /* PORT96CR */
+ PORTCR(97, 0xe6052061), /* PORT97CR */
+ PORTCR(98, 0xe6052062), /* PORT98CR */
+ PORTCR(99, 0xe6052063), /* PORT99CR */
+
+ PORTCR(100, 0xe6052064), /* PORT100CR */
+ PORTCR(101, 0xe6052065), /* PORT101CR */
+ PORTCR(102, 0xe6052066), /* PORT102CR */
+ PORTCR(103, 0xe6052067), /* PORT103CR */
+ PORTCR(104, 0xe6052068), /* PORT104CR */
+ PORTCR(105, 0xe6052069), /* PORT105CR */
+ PORTCR(106, 0xe605206a), /* PORT106CR */
+ PORTCR(107, 0xe605206b), /* PORT107CR */
+ PORTCR(108, 0xe605206c), /* PORT108CR */
+ PORTCR(109, 0xe605206d), /* PORT109CR */
+
+ PORTCR(110, 0xe605206e), /* PORT110CR */
+ PORTCR(111, 0xe605206f), /* PORT111CR */
+ PORTCR(112, 0xe6052070), /* PORT112CR */
+ PORTCR(113, 0xe6052071), /* PORT113CR */
+ PORTCR(114, 0xe6052072), /* PORT114CR */
+ PORTCR(115, 0xe6052073), /* PORT115CR */
+ PORTCR(116, 0xe6052074), /* PORT116CR */
+ PORTCR(117, 0xe6052075), /* PORT117CR */
+ PORTCR(118, 0xe6052076), /* PORT118CR */
+
+ PORTCR(128, 0xe6052080), /* PORT128CR */
+ PORTCR(129, 0xe6052081), /* PORT129CR */
+
+ PORTCR(130, 0xe6052082), /* PORT130CR */
+ PORTCR(131, 0xe6052083), /* PORT131CR */
+ PORTCR(132, 0xe6052084), /* PORT132CR */
+ PORTCR(133, 0xe6052085), /* PORT133CR */
+ PORTCR(134, 0xe6052086), /* PORT134CR */
+ PORTCR(135, 0xe6052087), /* PORT135CR */
+ PORTCR(136, 0xe6052088), /* PORT136CR */
+ PORTCR(137, 0xe6052089), /* PORT137CR */
+ PORTCR(138, 0xe605208a), /* PORT138CR */
+ PORTCR(139, 0xe605208b), /* PORT139CR */
+
+ PORTCR(140, 0xe605208c), /* PORT140CR */
+ PORTCR(141, 0xe605208d), /* PORT141CR */
+ PORTCR(142, 0xe605208e), /* PORT142CR */
+ PORTCR(143, 0xe605208f), /* PORT143CR */
+ PORTCR(144, 0xe6052090), /* PORT144CR */
+ PORTCR(145, 0xe6052091), /* PORT145CR */
+ PORTCR(146, 0xe6052092), /* PORT146CR */
+ PORTCR(147, 0xe6052093), /* PORT147CR */
+ PORTCR(148, 0xe6052094), /* PORT148CR */
+ PORTCR(149, 0xe6052095), /* PORT149CR */
+
+ PORTCR(150, 0xe6052096), /* PORT150CR */
+ PORTCR(151, 0xe6052097), /* PORT151CR */
+ PORTCR(152, 0xe6052098), /* PORT152CR */
+ PORTCR(153, 0xe6052099), /* PORT153CR */
+ PORTCR(154, 0xe605209a), /* PORT154CR */
+ PORTCR(155, 0xe605209b), /* PORT155CR */
+ PORTCR(156, 0xe605209c), /* PORT156CR */
+ PORTCR(157, 0xe605209d), /* PORT157CR */
+ PORTCR(158, 0xe605209e), /* PORT158CR */
+ PORTCR(159, 0xe605209f), /* PORT159CR */
+
+ PORTCR(160, 0xe60520a0), /* PORT160CR */
+ PORTCR(161, 0xe60520a1), /* PORT161CR */
+ PORTCR(162, 0xe60520a2), /* PORT162CR */
+ PORTCR(163, 0xe60520a3), /* PORT163CR */
+ PORTCR(164, 0xe60520a4), /* PORT164CR */
+
+ PORTCR(192, 0xe60520c0), /* PORT192CR */
+ PORTCR(193, 0xe60520c1), /* PORT193CR */
+ PORTCR(194, 0xe60520c2), /* PORT194CR */
+ PORTCR(195, 0xe60520c3), /* PORT195CR */
+ PORTCR(196, 0xe60520c4), /* PORT196CR */
+ PORTCR(197, 0xe60520c5), /* PORT197CR */
+ PORTCR(198, 0xe60520c6), /* PORT198CR */
+ PORTCR(199, 0xe60520c7), /* PORT199CR */
+
+ PORTCR(200, 0xe60520c8), /* PORT200CR */
+ PORTCR(201, 0xe60520c9), /* PORT201CR */
+ PORTCR(202, 0xe60520ca), /* PORT202CR */
+ PORTCR(203, 0xe60520cb), /* PORT203CR */
+ PORTCR(204, 0xe60520cc), /* PORT204CR */
+ PORTCR(205, 0xe60520cd), /* PORT205CR */
+ PORTCR(206, 0xe60520ce), /* PORT206CR */
+ PORTCR(207, 0xe60520cf), /* PORT207CR */
+ PORTCR(208, 0xe60520d0), /* PORT208CR */
+ PORTCR(209, 0xe60520d1), /* PORT209CR */
+
+ PORTCR(210, 0xe60520d2), /* PORT210CR */
+ PORTCR(211, 0xe60520d3), /* PORT211CR */
+ PORTCR(212, 0xe60520d4), /* PORT212CR */
+ PORTCR(213, 0xe60520d5), /* PORT213CR */
+ PORTCR(214, 0xe60520d6), /* PORT214CR */
+ PORTCR(215, 0xe60520d7), /* PORT215CR */
+ PORTCR(216, 0xe60520d8), /* PORT216CR */
+ PORTCR(217, 0xe60520d9), /* PORT217CR */
+ PORTCR(218, 0xe60520da), /* PORT218CR */
+ PORTCR(219, 0xe60520db), /* PORT219CR */
+
+ PORTCR(220, 0xe60520dc), /* PORT220CR */
+ PORTCR(221, 0xe60520dd), /* PORT221CR */
+ PORTCR(222, 0xe60520de), /* PORT222CR */
+ PORTCR(223, 0xe60520df), /* PORT223CR */
+ PORTCR(224, 0xe60530e0), /* PORT224CR */
+ PORTCR(225, 0xe60530e1), /* PORT225CR */
+ PORTCR(226, 0xe60530e2), /* PORT226CR */
+ PORTCR(227, 0xe60530e3), /* PORT227CR */
+ PORTCR(228, 0xe60530e4), /* PORT228CR */
+ PORTCR(229, 0xe60530e5), /* PORT229CR */
+
+ PORTCR(230, 0xe60530e6), /* PORT230CR */
+ PORTCR(231, 0xe60530e7), /* PORT231CR */
+ PORTCR(232, 0xe60530e8), /* PORT232CR */
+ PORTCR(233, 0xe60530e9), /* PORT233CR */
+ PORTCR(234, 0xe60530ea), /* PORT234CR */
+ PORTCR(235, 0xe60530eb), /* PORT235CR */
+ PORTCR(236, 0xe60530ec), /* PORT236CR */
+ PORTCR(237, 0xe60530ed), /* PORT237CR */
+ PORTCR(238, 0xe60530ee), /* PORT238CR */
+ PORTCR(239, 0xe60530ef), /* PORT239CR */
+
+ PORTCR(240, 0xe60530f0), /* PORT240CR */
+ PORTCR(241, 0xe60530f1), /* PORT241CR */
+ PORTCR(242, 0xe60530f2), /* PORT242CR */
+ PORTCR(243, 0xe60530f3), /* PORT243CR */
+ PORTCR(244, 0xe60530f4), /* PORT244CR */
+ PORTCR(245, 0xe60530f5), /* PORT245CR */
+ PORTCR(246, 0xe60530f6), /* PORT246CR */
+ PORTCR(247, 0xe60530f7), /* PORT247CR */
+ PORTCR(248, 0xe60530f8), /* PORT248CR */
+ PORTCR(249, 0xe60530f9), /* PORT249CR */
+
+ PORTCR(250, 0xe60530fa), /* PORT250CR */
+ PORTCR(251, 0xe60530fb), /* PORT251CR */
+ PORTCR(252, 0xe60530fc), /* PORT252CR */
+ PORTCR(253, 0xe60530fd), /* PORT253CR */
+ PORTCR(254, 0xe60530fe), /* PORT254CR */
+ PORTCR(255, 0xe60530ff), /* PORT255CR */
+ PORTCR(256, 0xe6053100), /* PORT256CR */
+ PORTCR(257, 0xe6053101), /* PORT257CR */
+ PORTCR(258, 0xe6053102), /* PORT258CR */
+ PORTCR(259, 0xe6053103), /* PORT259CR */
+
+ PORTCR(260, 0xe6053104), /* PORT260CR */
+ PORTCR(261, 0xe6053105), /* PORT261CR */
+ PORTCR(262, 0xe6053106), /* PORT262CR */
+ PORTCR(263, 0xe6053107), /* PORT263CR */
+ PORTCR(264, 0xe6053108), /* PORT264CR */
+ PORTCR(265, 0xe6053109), /* PORT265CR */
+ PORTCR(266, 0xe605310a), /* PORT266CR */
+ PORTCR(267, 0xe605310b), /* PORT267CR */
+ PORTCR(268, 0xe605310c), /* PORT268CR */
+ PORTCR(269, 0xe605310d), /* PORT269CR */
+
+ PORTCR(270, 0xe605310e), /* PORT270CR */
+ PORTCR(271, 0xe605310f), /* PORT271CR */
+ PORTCR(272, 0xe6053110), /* PORT272CR */
+ PORTCR(273, 0xe6053111), /* PORT273CR */
+ PORTCR(274, 0xe6053112), /* PORT274CR */
+ PORTCR(275, 0xe6053113), /* PORT275CR */
+ PORTCR(276, 0xe6053114), /* PORT276CR */
+ PORTCR(277, 0xe6053115), /* PORT277CR */
+ PORTCR(278, 0xe6053116), /* PORT278CR */
+ PORTCR(279, 0xe6053117), /* PORT279CR */
+
+ PORTCR(280, 0xe6053118), /* PORT280CR */
+ PORTCR(281, 0xe6053119), /* PORT281CR */
+ PORTCR(282, 0xe605311a), /* PORT282CR */
+
+ PORTCR(288, 0xe6052120), /* PORT288CR */
+ PORTCR(289, 0xe6052121), /* PORT289CR */
+
+ PORTCR(290, 0xe6052122), /* PORT290CR */
+ PORTCR(291, 0xe6052123), /* PORT291CR */
+ PORTCR(292, 0xe6052124), /* PORT292CR */
+ PORTCR(293, 0xe6052125), /* PORT293CR */
+ PORTCR(294, 0xe6052126), /* PORT294CR */
+ PORTCR(295, 0xe6052127), /* PORT295CR */
+ PORTCR(296, 0xe6052128), /* PORT296CR */
+ PORTCR(297, 0xe6052129), /* PORT297CR */
+ PORTCR(298, 0xe605212a), /* PORT298CR */
+ PORTCR(299, 0xe605212b), /* PORT299CR */
+
+ PORTCR(300, 0xe605212c), /* PORT300CR */
+ PORTCR(301, 0xe605212d), /* PORT301CR */
+ PORTCR(302, 0xe605212e), /* PORT302CR */
+ PORTCR(303, 0xe605212f), /* PORT303CR */
+ PORTCR(304, 0xe6052130), /* PORT304CR */
+ PORTCR(305, 0xe6052131), /* PORT305CR */
+ PORTCR(306, 0xe6052132), /* PORT306CR */
+ PORTCR(307, 0xe6052133), /* PORT307CR */
+ PORTCR(308, 0xe6052134), /* PORT308CR */
+ PORTCR(309, 0xe6052135), /* PORT309CR */
+
+ { PINMUX_CFG_REG("MSEL2CR", 0xe605801c, 32, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL2CR_MSEL19_0, MSEL2CR_MSEL19_1,
+ MSEL2CR_MSEL18_0, MSEL2CR_MSEL18_1,
+ MSEL2CR_MSEL17_0, MSEL2CR_MSEL17_1,
+ MSEL2CR_MSEL16_0, MSEL2CR_MSEL16_1,
+ 0, 0,
+ MSEL2CR_MSEL14_0, MSEL2CR_MSEL14_1,
+ MSEL2CR_MSEL13_0, MSEL2CR_MSEL13_1,
+ MSEL2CR_MSEL12_0, MSEL2CR_MSEL12_1,
+ MSEL2CR_MSEL11_0, MSEL2CR_MSEL11_1,
+ MSEL2CR_MSEL10_0, MSEL2CR_MSEL10_1,
+ MSEL2CR_MSEL9_0, MSEL2CR_MSEL9_1,
+ MSEL2CR_MSEL8_0, MSEL2CR_MSEL8_1,
+ MSEL2CR_MSEL7_0, MSEL2CR_MSEL7_1,
+ MSEL2CR_MSEL6_0, MSEL2CR_MSEL6_1,
+ MSEL2CR_MSEL5_0, MSEL2CR_MSEL5_1,
+ MSEL2CR_MSEL4_0, MSEL2CR_MSEL4_1,
+ MSEL2CR_MSEL3_0, MSEL2CR_MSEL3_1,
+ MSEL2CR_MSEL2_0, MSEL2CR_MSEL2_1,
+ MSEL2CR_MSEL1_0, MSEL2CR_MSEL1_1,
+ MSEL2CR_MSEL0_0, MSEL2CR_MSEL0_1,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL3CR", 0xe6058020, 32, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL28_0, MSEL3CR_MSEL28_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL15_0, MSEL3CR_MSEL15_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL11_0, MSEL3CR_MSEL11_1,
+ 0, 0,
+ MSEL3CR_MSEL9_0, MSEL3CR_MSEL9_1,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL6_0, MSEL3CR_MSEL6_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL3CR_MSEL2_0, MSEL3CR_MSEL2_1,
+ 0, 0,
+ 0, 0,
+ }
+ },
+ { PINMUX_CFG_REG("MSEL4CR", 0xe6058024, 32, 1) {
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL29_0, MSEL4CR_MSEL29_1,
+ 0, 0,
+ MSEL4CR_MSEL27_0, MSEL4CR_MSEL27_1,
+ MSEL4CR_MSEL26_0, MSEL4CR_MSEL26_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL22_0, MSEL4CR_MSEL22_1,
+ MSEL4CR_MSEL21_0, MSEL4CR_MSEL21_1,
+ MSEL4CR_MSEL20_0, MSEL4CR_MSEL20_1,
+ MSEL4CR_MSEL19_0, MSEL4CR_MSEL19_1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL15_0, MSEL4CR_MSEL15_1,
+ 0, 0,
+ MSEL4CR_MSEL13_0, MSEL4CR_MSEL13_1,
+ MSEL4CR_MSEL12_0, MSEL4CR_MSEL12_1,
+ MSEL4CR_MSEL11_0, MSEL4CR_MSEL11_1,
+ MSEL4CR_MSEL10_0, MSEL4CR_MSEL10_1,
+ MSEL4CR_MSEL9_0, MSEL4CR_MSEL9_1,
+ MSEL4CR_MSEL8_0, MSEL4CR_MSEL8_1,
+ MSEL4CR_MSEL7_0, MSEL4CR_MSEL7_1,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL4_0, MSEL4CR_MSEL4_1,
+ 0, 0,
+ 0, 0,
+ MSEL4CR_MSEL1_0, MSEL4CR_MSEL1_1,
+ 0, 0,
+ }
+ },
+ { },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PORTL031_000DR", 0xe6054000, 32) {
+ PORT31_DATA, PORT30_DATA, PORT29_DATA, PORT28_DATA,
+ PORT27_DATA, PORT26_DATA, PORT25_DATA, PORT24_DATA,
+ PORT23_DATA, PORT22_DATA, PORT21_DATA, PORT20_DATA,
+ PORT19_DATA, PORT18_DATA, PORT17_DATA, PORT16_DATA,
+ PORT15_DATA, PORT14_DATA, PORT13_DATA, PORT12_DATA,
+ PORT11_DATA, PORT10_DATA, PORT9_DATA, PORT8_DATA,
+ PORT7_DATA, PORT6_DATA, PORT5_DATA, PORT4_DATA,
+ PORT3_DATA, PORT2_DATA, PORT1_DATA, PORT0_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD063_032DR", 0xe6055000, 32) {
+ PORT63_DATA, PORT62_DATA, PORT61_DATA, PORT60_DATA,
+ PORT59_DATA, PORT58_DATA, PORT57_DATA, PORT56_DATA,
+ PORT55_DATA, PORT54_DATA, PORT53_DATA, PORT52_DATA,
+ PORT51_DATA, PORT50_DATA, PORT49_DATA, PORT48_DATA,
+ PORT47_DATA, PORT46_DATA, PORT45_DATA, PORT44_DATA,
+ PORT43_DATA, PORT42_DATA, PORT41_DATA, PORT40_DATA,
+ PORT39_DATA, PORT38_DATA, PORT37_DATA, PORT36_DATA,
+ PORT35_DATA, PORT34_DATA, PORT33_DATA, PORT32_DATA }
+ },
+ { PINMUX_DATA_REG("PORTD095_064DR", 0xe6055004, 32) {
+ PORT95_DATA, PORT94_DATA, PORT93_DATA, PORT92_DATA,
+ PORT91_DATA, PORT90_DATA, PORT89_DATA, PORT88_DATA,
+ PORT87_DATA, PORT86_DATA, PORT85_DATA, PORT84_DATA,
+ PORT83_DATA, PORT82_DATA, PORT81_DATA, PORT80_DATA,
+ PORT79_DATA, PORT78_DATA, PORT77_DATA, PORT76_DATA,
+ PORT75_DATA, PORT74_DATA, PORT73_DATA, PORT72_DATA,
+ PORT71_DATA, PORT70_DATA, PORT69_DATA, PORT68_DATA,
+ PORT67_DATA, PORT66_DATA, PORT65_DATA, PORT64_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR127_096DR", 0xe6056000, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, PORT118_DATA, PORT117_DATA, PORT116_DATA,
+ PORT115_DATA, PORT114_DATA, PORT113_DATA, PORT112_DATA,
+ PORT111_DATA, PORT110_DATA, PORT109_DATA, PORT108_DATA,
+ PORT107_DATA, PORT106_DATA, PORT105_DATA, PORT104_DATA,
+ PORT103_DATA, PORT102_DATA, PORT101_DATA, PORT100_DATA,
+ PORT99_DATA, PORT98_DATA, PORT97_DATA, PORT96_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR159_128DR", 0xe6056004, 32) {
+ PORT159_DATA, PORT158_DATA, PORT157_DATA, PORT156_DATA,
+ PORT155_DATA, PORT154_DATA, PORT153_DATA, PORT152_DATA,
+ PORT151_DATA, PORT150_DATA, PORT149_DATA, PORT148_DATA,
+ PORT147_DATA, PORT146_DATA, PORT145_DATA, PORT144_DATA,
+ PORT143_DATA, PORT142_DATA, PORT141_DATA, PORT140_DATA,
+ PORT139_DATA, PORT138_DATA, PORT137_DATA, PORT136_DATA,
+ PORT135_DATA, PORT134_DATA, PORT133_DATA, PORT132_DATA,
+ PORT131_DATA, PORT130_DATA, PORT129_DATA, PORT128_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR191_160DR", 0xe6056008, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PORT164_DATA,
+ PORT163_DATA, PORT162_DATA, PORT161_DATA, PORT160_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR223_192DR", 0xe605600C, 32) {
+ PORT223_DATA, PORT222_DATA, PORT221_DATA, PORT220_DATA,
+ PORT219_DATA, PORT218_DATA, PORT217_DATA, PORT216_DATA,
+ PORT215_DATA, PORT214_DATA, PORT213_DATA, PORT212_DATA,
+ PORT211_DATA, PORT210_DATA, PORT209_DATA, PORT208_DATA,
+ PORT207_DATA, PORT206_DATA, PORT205_DATA, PORT204_DATA,
+ PORT203_DATA, PORT202_DATA, PORT201_DATA, PORT200_DATA,
+ PORT199_DATA, PORT198_DATA, PORT197_DATA, PORT196_DATA,
+ PORT195_DATA, PORT194_DATA, PORT193_DATA, PORT192_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU255_224DR", 0xe6057000, 32) {
+ PORT255_DATA, PORT254_DATA, PORT253_DATA, PORT252_DATA,
+ PORT251_DATA, PORT250_DATA, PORT249_DATA, PORT248_DATA,
+ PORT247_DATA, PORT246_DATA, PORT245_DATA, PORT244_DATA,
+ PORT243_DATA, PORT242_DATA, PORT241_DATA, PORT240_DATA,
+ PORT239_DATA, PORT238_DATA, PORT237_DATA, PORT236_DATA,
+ PORT235_DATA, PORT234_DATA, PORT233_DATA, PORT232_DATA,
+ PORT231_DATA, PORT230_DATA, PORT229_DATA, PORT228_DATA,
+ PORT227_DATA, PORT226_DATA, PORT225_DATA, PORT224_DATA }
+ },
+ { PINMUX_DATA_REG("PORTU287_256DR", 0xe6057004, 32) {
+ 0, 0, 0, 0,
+ 0, PORT282_DATA, PORT281_DATA, PORT280_DATA,
+ PORT279_DATA, PORT278_DATA, PORT277_DATA, PORT276_DATA,
+ PORT275_DATA, PORT274_DATA, PORT273_DATA, PORT272_DATA,
+ PORT271_DATA, PORT270_DATA, PORT269_DATA, PORT268_DATA,
+ PORT267_DATA, PORT266_DATA, PORT265_DATA, PORT264_DATA,
+ PORT263_DATA, PORT262_DATA, PORT261_DATA, PORT260_DATA,
+ PORT259_DATA, PORT258_DATA, PORT257_DATA, PORT256_DATA }
+ },
+ { PINMUX_DATA_REG("PORTR319_288DR", 0xe6056010, 32) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, PORT309_DATA, PORT308_DATA,
+ PORT307_DATA, PORT306_DATA, PORT305_DATA, PORT304_DATA,
+ PORT303_DATA, PORT302_DATA, PORT301_DATA, PORT300_DATA,
+ PORT299_DATA, PORT298_DATA, PORT297_DATA, PORT296_DATA,
+ PORT295_DATA, PORT294_DATA, PORT293_DATA, PORT292_DATA,
+ PORT291_DATA, PORT290_DATA, PORT289_DATA, PORT288_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh73a0_pinmux_info = {
+ .name = "sh73a0_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PORT0,
+ .last_gpio = GPIO_FN_FSIAISLD_PU,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void sh73a0_pinmux_init(void)
+{
+ register_pinmux(&sh73a0_pinmux_info);
+}
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
new file mode 100644
index 00000000..f3888feb
--- /dev/null
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -0,0 +1,73 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2011 Paul Mundt
+ *
+ * Based on vexpress, 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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/hardware/gic.h>
+#include <asm/localtimer.h>
+#include <asm/mach-types.h>
+#include <mach/common.h>
+
+static unsigned int __init shmobile_smp_get_core_count(void)
+{
+ if (machine_is_ag5evm())
+ return sh73a0_get_core_count();
+
+ return 1;
+}
+
+static void __init shmobile_smp_prepare_cpus(void)
+{
+ if (machine_is_ag5evm())
+ sh73a0_smp_prepare_cpus();
+}
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ trace_hardirqs_off();
+
+ if (machine_is_ag5evm())
+ sh73a0_secondary_init(cpu);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ if (machine_is_ag5evm())
+ return sh73a0_boot_secondary(cpu);
+
+ return -ENOSYS;
+}
+
+void __init smp_init_cpus(void)
+{
+ unsigned int ncores = shmobile_smp_get_core_count();
+ unsigned int i;
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ shmobile_smp_prepare_cpus();
+}
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
new file mode 100644
index 00000000..8e4aadf1
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -0,0 +1,108 @@
+/*
+ * sh7372 Power management support
+ *
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+#include <mach/common.h>
+
+#define SMFRAM 0xe6a70000
+#define SYSTBCR 0xe6150024
+#define SBAR 0xe6180020
+#define APARMBAREA 0xe6f10020
+
+static void sh7372_enter_core_standby(void)
+{
+ void __iomem *smfram = (void __iomem *)SMFRAM;
+
+ __raw_writel(0, APARMBAREA); /* translate 4k */
+ __raw_writel(__pa(sh7372_cpu_resume), SBAR); /* set reset vector */
+ __raw_writel(0x10, SYSTBCR); /* enable core standby */
+
+ __raw_writel(0, smfram + 0x3c); /* clear page table address */
+
+ sh7372_cpu_suspend();
+ cpu_init();
+
+ /* if page table address is non-NULL then we have been powered down */
+ if (__raw_readl(smfram + 0x3c)) {
+ __raw_writel(__raw_readl(smfram + 0x40),
+ __va(__raw_readl(smfram + 0x3c)));
+
+ flush_tlb_all();
+ set_cr(__raw_readl(smfram + 0x38));
+ }
+
+ __raw_writel(0, SYSTBCR); /* disable core standby */
+ __raw_writel(0, SBAR); /* disable reset vector translation */
+}
+
+#ifdef CONFIG_CPU_IDLE
+static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
+{
+ struct cpuidle_state *state;
+ int i = dev->state_count;
+
+ state = &dev->states[i];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+ strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
+ state->exit_latency = 10;
+ state->target_residency = 20 + 10;
+ state->power_usage = 1; /* perhaps not */
+ state->flags = 0;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
+
+ dev->state_count = i + 1;
+}
+
+static void sh7372_cpuidle_init(void)
+{
+ shmobile_cpuidle_setup = sh7372_cpuidle_setup;
+}
+#else
+static void sh7372_cpuidle_init(void) {}
+#endif
+
+#ifdef CONFIG_SUSPEND
+static int sh7372_enter_suspend(suspend_state_t suspend_state)
+{
+ sh7372_enter_core_standby();
+ return 0;
+}
+
+static void sh7372_suspend_init(void)
+{
+ shmobile_suspend_ops.enter = sh7372_enter_suspend;
+}
+#else
+static void sh7372_suspend_init(void) {}
+#endif
+
+#define DBGREG1 0xe6100020
+#define DBGREG9 0xe6100040
+
+void __init sh7372_pm_init(void)
+{
+ /* enable DBG hardware block to kick SYSC */
+ __raw_writel(0x0000a500, DBGREG9);
+ __raw_writel(0x0000a501, DBGREG9);
+ __raw_writel(0x00000000, DBGREG1);
+
+ sh7372_suspend_init();
+ sh7372_cpuidle_init();
+}
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c
new file mode 100644
index 00000000..2d1b67a5
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm_runtime.c
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-shmobile/pm_runtime.c
+ *
+ * Runtime PM support code for SuperH Mobile ARM
+ *
+ * Copyright (C) 2009-2010 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int default_platform_runtime_idle(struct device *dev)
+{
+ /* suspend synchronously to disable clocks immediately */
+ return pm_runtime_suspend(dev);
+}
+
+static struct dev_power_domain default_power_domain = {
+ .ops = {
+ .runtime_suspend = pm_runtime_clk_suspend,
+ .runtime_resume = pm_runtime_clk_resume,
+ .runtime_idle = default_platform_runtime_idle,
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+
+#define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain)
+
+#else
+
+#define DEFAULT_PWR_DOMAIN_PTR NULL
+
+#endif /* CONFIG_PM_RUNTIME */
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+ .pwr_domain = DEFAULT_PWR_DOMAIN_PTR,
+ .con_ids = { NULL, },
+};
+
+static int __init sh_pm_runtime_init(void)
+{
+ pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+ return 0;
+}
+core_initcall(sh_pm_runtime_init);
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
new file mode 100644
index 00000000..e546017f
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -0,0 +1,448 @@
+/*
+ * sh7367 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+/* SCIFA0 */
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc00), evt2irq(0xc00),
+ evt2irq(0xc00), evt2irq(0xc00) },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+/* SCIFA1 */
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc20), evt2irq(0xc20),
+ evt2irq(0xc20), evt2irq(0xc20) },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+/* SCIFA2 */
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc40), evt2irq(0xc40),
+ evt2irq(0xc40), evt2irq(0xc40) },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+/* SCIFA3 */
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc60), evt2irq(0xc60),
+ evt2irq(0xc60), evt2irq(0xc60) },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+/* SCIFA4 */
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xd20), evt2irq(0xd20),
+ evt2irq(0xd20), evt2irq(0xd20) },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+/* SCIFA5 */
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xd40), evt2irq(0xd40),
+ evt2irq(0xd40), evt2irq(0xd40) },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+/* SCIFB */
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFB,
+ .irqs = { evt2irq(0xd60), evt2irq(0xd60),
+ evt2irq(0xd60), evt2irq(0xd60) },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xb00), /* CMT1_CMT10 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+/* VPU */
+static struct uio_info vpu_platform_data = {
+ .name = "VPU5",
+ .version = "0",
+ .irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+ [0] = {
+ .name = "VPU",
+ .start = 0xfe900000,
+ .end = 0xfe902807,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device vpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 0,
+ .dev = {
+ .platform_data = &vpu_platform_data,
+ },
+ .resource = vpu_resources,
+ .num_resources = ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+ .name = "VEU0",
+ .version = "0",
+ .irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+ [0] = {
+ .name = "VEU0",
+ .start = 0xfe920000,
+ .end = 0xfe9200b7,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 1,
+ .dev = {
+ .platform_data = &veu0_platform_data,
+ },
+ .resource = veu0_resources,
+ .num_resources = ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+ .name = "VEU1",
+ .version = "0",
+ .irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+ [0] = {
+ .name = "VEU1",
+ .start = 0xfe924000,
+ .end = 0xfe9240b7,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 2,
+ .dev = {
+ .platform_data = &veu1_platform_data,
+ },
+ .resource = veu1_resources,
+ .num_resources = ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+ .name = "VEU2",
+ .version = "0",
+ .irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+ [0] = {
+ .name = "VEU2",
+ .start = 0xfe928000,
+ .end = 0xfe9280b7,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu2_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 3,
+ .dev = {
+ .platform_data = &veu2_platform_data,
+ },
+ .resource = veu2_resources,
+ .num_resources = ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+ .name = "VEU3",
+ .version = "0",
+ .irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+ [0] = {
+ .name = "VEU3",
+ .start = 0xfe92c000,
+ .end = 0xfe92c0b7,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu3_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 4,
+ .dev = {
+ .platform_data = &veu3_platform_data,
+ },
+ .resource = veu3_resources,
+ .num_resources = ARRAY_SIZE(veu3_resources),
+};
+
+/* VEU2H */
+static struct uio_info veu2h_platform_data = {
+ .name = "VEU2H",
+ .version = "0",
+ .irq = intcs_evt2irq(0x520),
+};
+
+static struct resource veu2h_resources[] = {
+ [0] = {
+ .name = "VEU2H",
+ .start = 0xfe93c000,
+ .end = 0xfe93c27b,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu2h_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 5,
+ .dev = {
+ .platform_data = &veu2h_platform_data,
+ },
+ .resource = veu2h_resources,
+ .num_resources = ARRAY_SIZE(veu2h_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+ .name = "JPU",
+ .version = "0",
+ .irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+ [0] = {
+ .name = "JPU",
+ .start = 0xfe980000,
+ .end = 0xfe9902d3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device jpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 6,
+ .dev = {
+ .platform_data = &jpu_platform_data,
+ },
+ .resource = jpu_resources,
+ .num_resources = ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU1 */
+static struct uio_info spu1_platform_data = {
+ .name = "SPU1",
+ .version = "0",
+ .irq = evt2irq(0xfc0),
+};
+
+static struct resource spu1_resources[] = {
+ [0] = {
+ .name = "SPU1",
+ .start = 0xfe300000,
+ .end = 0xfe3fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 7,
+ .dev = {
+ .platform_data = &spu1_platform_data,
+ },
+ .resource = spu1_resources,
+ .num_resources = ARRAY_SIZE(spu1_resources),
+};
+
+static struct platform_device *sh7367_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &cmt10_device,
+};
+
+static struct platform_device *sh7367_devices[] __initdata = {
+ &vpu_device,
+ &veu0_device,
+ &veu1_device,
+ &veu2_device,
+ &veu3_device,
+ &veu2h_device,
+ &jpu_device,
+ &spu1_device,
+};
+
+void __init sh7367_add_standard_devices(void)
+{
+ platform_add_devices(sh7367_early_devices,
+ ARRAY_SIZE(sh7367_early_devices));
+
+ platform_add_devices(sh7367_devices,
+ ARRAY_SIZE(sh7367_devices));
+}
+
+#define SYMSTPCR2 0xe6158048
+#define SYMSTPCR2_CMT1 (1 << 29)
+
+void __init sh7367_add_early_devices(void)
+{
+ /* enable clock to CMT1 */
+ __raw_writel(__raw_readl(SYMSTPCR2) & ~SYMSTPCR2_CMT1, SYMSTPCR2);
+
+ early_platform_add_devices(sh7367_early_devices,
+ ARRAY_SIZE(sh7367_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
new file mode 100644
index 00000000..cd807eea
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -0,0 +1,855 @@
+/*
+ * sh7372 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <mach/sh7372.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+/* SCIFA0 */
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c00), evt2irq(0x0c00),
+ evt2irq(0x0c00), evt2irq(0x0c00) },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+/* SCIFA1 */
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c20), evt2irq(0x0c20),
+ evt2irq(0x0c20), evt2irq(0x0c20) },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+/* SCIFA2 */
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c40), evt2irq(0x0c40),
+ evt2irq(0x0c40), evt2irq(0x0c40) },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+/* SCIFA3 */
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c60), evt2irq(0x0c60),
+ evt2irq(0x0c60), evt2irq(0x0c60) },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+/* SCIFA4 */
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0d20), evt2irq(0x0d20),
+ evt2irq(0x0d20), evt2irq(0x0d20) },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+/* SCIFA5 */
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0d40), evt2irq(0x0d40),
+ evt2irq(0x0d40), evt2irq(0x0d40) },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+/* SCIFB */
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFB,
+ .irqs = { evt2irq(0x0d60), evt2irq(0x0d60),
+ evt2irq(0x0d60), evt2irq(0x0d60) },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+/* CMT */
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0b00), /* CMT1_CMT10 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+ .name = "TMU00",
+ .channel_offset = 0x4,
+ .timer_bit = 0,
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+ [0] = {
+ .name = "TMU00",
+ .start = 0xfff60008,
+ .end = 0xfff60013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xe80), /* TMU_TUNI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu00_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu00_platform_data,
+ },
+ .resource = tmu00_resources,
+ .num_resources = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+ .name = "TMU01",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+ [0] = {
+ .name = "TMU01",
+ .start = 0xfff60014,
+ .end = 0xfff6001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xea0), /* TMU_TUNI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu01_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu01_platform_data,
+ },
+ .resource = tmu01_resources,
+ .num_resources = ARRAY_SIZE(tmu01_resources),
+};
+
+/* I2C */
+static struct resource iic0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xFFF20000,
+ .end = 0xFFF20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */
+ .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0, /* "i2c0" clock */
+ .num_resources = ARRAY_SIZE(iic0_resources),
+ .resource = iic0_resources,
+};
+
+static struct resource iic1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xE6C20000,
+ .end = 0xE6C20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x780), /* IIC1_ALI1 */
+ .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1, /* "i2c1" clock */
+ .num_resources = ARRAY_SIZE(iic1_resources),
+ .resource = iic1_resources,
+};
+
+/* DMA */
+/* Transmit sizes and respective CHCR register values */
+enum {
+ XMIT_SZ_8BIT = 0,
+ XMIT_SZ_16BIT = 1,
+ XMIT_SZ_32BIT = 2,
+ XMIT_SZ_64BIT = 7,
+ XMIT_SZ_128BIT = 3,
+ XMIT_SZ_256BIT = 4,
+ XMIT_SZ_512BIT = 5,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_64BIT] = 3, \
+ [XMIT_SZ_128BIT] = 4, \
+ [XMIT_SZ_256BIT] = 5, \
+ [XMIT_SZ_512BIT] = 6, \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \
+ (((i) & 0xc) << (20 - 2)))
+
+static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SCIF0_TX,
+ .addr = 0xe6c40020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x21,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF0_RX,
+ .addr = 0xe6c40024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x22,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_TX,
+ .addr = 0xe6c50020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x25,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_RX,
+ .addr = 0xe6c50024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x26,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_TX,
+ .addr = 0xe6c60020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x29,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_RX,
+ .addr = 0xe6c60024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_TX,
+ .addr = 0xe6c70020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_RX,
+ .addr = 0xe6c70024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_TX,
+ .addr = 0xe6c80020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x39,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_RX,
+ .addr = 0xe6c80024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_TX,
+ .addr = 0xe6cb0020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x35,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_RX,
+ .addr = 0xe6cb0024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x36,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_TX,
+ .addr = 0xe6c30040,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_RX,
+ .addr = 0xe6c30060,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xe6850030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xe6850030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xe6860030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xe6860030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xe6870030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xe6870030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ .addr = 0xe6bd0034,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xd1,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ .addr = 0xe6bd0034,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .mid_rid = 0xd2,
+ },
+};
+
+static const struct sh_dmae_channel sh7372_dmae_channels[] = {
+ {
+ .offset = 0,
+ .dmars = 0,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x10,
+ .dmars = 0,
+ .dmars_bit = 8,
+ }, {
+ .offset = 0x20,
+ .dmars = 4,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x30,
+ .dmars = 4,
+ .dmars_bit = 8,
+ }, {
+ .offset = 0x50,
+ .dmars = 8,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x60,
+ .dmars = 8,
+ .dmars_bit = 8,
+ }
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma_platform_data = {
+ .slave = sh7372_dmae_slaves,
+ .slave_num = ARRAY_SIZE(sh7372_dmae_slaves),
+ .channel = sh7372_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh7372_dmae_channels),
+ .ts_low_shift = 3,
+ .ts_low_mask = 0x18,
+ .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
+ .ts_high_mask = 0x00300000,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_DME,
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe008020,
+ .end = 0xfe00808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe009000,
+ .end = 0xfe00900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = evt2irq(0x20c0),
+ .end = evt2irq(0x20c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2000),
+ .end = evt2irq(0x20a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe018020,
+ .end = 0xfe01808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe019000,
+ .end = 0xfe01900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = evt2irq(0x21c0),
+ .end = evt2irq(0x21c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2100),
+ .end = evt2irq(0x21a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae2_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe028020,
+ .end = 0xfe02808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe029000,
+ .end = 0xfe02900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = evt2irq(0x22c0),
+ .end = evt2irq(0x22c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2200),
+ .end = evt2irq(0x22a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = sh7372_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae0_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh7372_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae1_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma2_device = {
+ .name = "sh-dma-engine",
+ .id = 2,
+ .resource = sh7372_dmae2_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae2_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+/* VPU */
+static struct uio_info vpu_platform_data = {
+ .name = "VPU5HG",
+ .version = "0",
+ .irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+ [0] = {
+ .name = "VPU",
+ .start = 0xfe900000,
+ .end = 0xfe900157,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device vpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 0,
+ .dev = {
+ .platform_data = &vpu_platform_data,
+ },
+ .resource = vpu_resources,
+ .num_resources = ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+ .name = "VEU0",
+ .version = "0",
+ .irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+ [0] = {
+ .name = "VEU0",
+ .start = 0xfe920000,
+ .end = 0xfe9200cb,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 1,
+ .dev = {
+ .platform_data = &veu0_platform_data,
+ },
+ .resource = veu0_resources,
+ .num_resources = ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+ .name = "VEU1",
+ .version = "0",
+ .irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+ [0] = {
+ .name = "VEU1",
+ .start = 0xfe924000,
+ .end = 0xfe9240cb,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 2,
+ .dev = {
+ .platform_data = &veu1_platform_data,
+ },
+ .resource = veu1_resources,
+ .num_resources = ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+ .name = "VEU2",
+ .version = "0",
+ .irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+ [0] = {
+ .name = "VEU2",
+ .start = 0xfe928000,
+ .end = 0xfe928307,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu2_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 3,
+ .dev = {
+ .platform_data = &veu2_platform_data,
+ },
+ .resource = veu2_resources,
+ .num_resources = ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+ .name = "VEU3",
+ .version = "0",
+ .irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+ [0] = {
+ .name = "VEU3",
+ .start = 0xfe92c000,
+ .end = 0xfe92c307,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu3_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 4,
+ .dev = {
+ .platform_data = &veu3_platform_data,
+ },
+ .resource = veu3_resources,
+ .num_resources = ARRAY_SIZE(veu3_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+ .name = "JPU",
+ .version = "0",
+ .irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+ [0] = {
+ .name = "JPU",
+ .start = 0xfe980000,
+ .end = 0xfe9902d3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device jpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 5,
+ .dev = {
+ .platform_data = &jpu_platform_data,
+ },
+ .resource = jpu_resources,
+ .num_resources = ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+ .name = "SPU2DSP0",
+ .version = "0",
+ .irq = evt2irq(0x1800),
+};
+
+static struct resource spu0_resources[] = {
+ [0] = {
+ .name = "SPU2DSP0",
+ .start = 0xfe200000,
+ .end = 0xfe2fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 6,
+ .dev = {
+ .platform_data = &spu0_platform_data,
+ },
+ .resource = spu0_resources,
+ .num_resources = ARRAY_SIZE(spu0_resources),
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+ .name = "SPU2DSP1",
+ .version = "0",
+ .irq = evt2irq(0x1820),
+};
+
+static struct resource spu1_resources[] = {
+ [0] = {
+ .name = "SPU2DSP1",
+ .start = 0xfe300000,
+ .end = 0xfe3fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 7,
+ .dev = {
+ .platform_data = &spu1_platform_data,
+ },
+ .resource = spu1_resources,
+ .num_resources = ARRAY_SIZE(spu1_resources),
+};
+
+static struct platform_device *sh7372_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &cmt10_device,
+ &tmu00_device,
+ &tmu01_device,
+};
+
+static struct platform_device *sh7372_late_devices[] __initdata = {
+ &iic0_device,
+ &iic1_device,
+ &dma0_device,
+ &dma1_device,
+ &dma2_device,
+ &vpu_device,
+ &veu0_device,
+ &veu1_device,
+ &veu2_device,
+ &veu3_device,
+ &jpu_device,
+ &spu0_device,
+ &spu1_device,
+};
+
+void __init sh7372_add_standard_devices(void)
+{
+ platform_add_devices(sh7372_early_devices,
+ ARRAY_SIZE(sh7372_early_devices));
+
+ platform_add_devices(sh7372_late_devices,
+ ARRAY_SIZE(sh7372_late_devices));
+}
+
+void __init sh7372_add_early_devices(void)
+{
+ early_platform_add_devices(sh7372_early_devices,
+ ARRAY_SIZE(sh7372_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
new file mode 100644
index 00000000..bb405b8e
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -0,0 +1,469 @@
+/*
+ * sh7377 processor support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+/* SCIFA0 */
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc00), evt2irq(0xc00),
+ evt2irq(0xc00), evt2irq(0xc00) },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+/* SCIFA1 */
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc20), evt2irq(0xc20),
+ evt2irq(0xc20), evt2irq(0xc20) },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+/* SCIFA2 */
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc40), evt2irq(0xc40),
+ evt2irq(0xc40), evt2irq(0xc40) },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+/* SCIFA3 */
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xc60), evt2irq(0xc60),
+ evt2irq(0xc60), evt2irq(0xc60) },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+/* SCIFA4 */
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xd20), evt2irq(0xd20),
+ evt2irq(0xd20), evt2irq(0xd20) },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+/* SCIFA5 */
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0xd40), evt2irq(0xd40),
+ evt2irq(0xd40), evt2irq(0xd40) },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+/* SCIFA6 */
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6cc0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
+ intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+/* SCIFB */
+static struct plat_sci_port scif7_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFB,
+ .irqs = { evt2irq(0xd60), evt2irq(0xd60),
+ evt2irq(0xd60), evt2irq(0xd60) },
+};
+
+static struct platform_device scif7_device = {
+ .name = "sh-sci",
+ .id = 7,
+ .dev = {
+ .platform_data = &scif7_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0xb00), /* CMT1_CMT10 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+/* VPU */
+static struct uio_info vpu_platform_data = {
+ .name = "VPU5HG",
+ .version = "0",
+ .irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+ [0] = {
+ .name = "VPU",
+ .start = 0xfe900000,
+ .end = 0xfe900157,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device vpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 0,
+ .dev = {
+ .platform_data = &vpu_platform_data,
+ },
+ .resource = vpu_resources,
+ .num_resources = ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+ .name = "VEU0",
+ .version = "0",
+ .irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+ [0] = {
+ .name = "VEU0",
+ .start = 0xfe920000,
+ .end = 0xfe9200cb,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 1,
+ .dev = {
+ .platform_data = &veu0_platform_data,
+ },
+ .resource = veu0_resources,
+ .num_resources = ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+ .name = "VEU1",
+ .version = "0",
+ .irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+ [0] = {
+ .name = "VEU1",
+ .start = 0xfe924000,
+ .end = 0xfe9240cb,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 2,
+ .dev = {
+ .platform_data = &veu1_platform_data,
+ },
+ .resource = veu1_resources,
+ .num_resources = ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+ .name = "VEU2",
+ .version = "0",
+ .irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+ [0] = {
+ .name = "VEU2",
+ .start = 0xfe928000,
+ .end = 0xfe928307,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu2_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 3,
+ .dev = {
+ .platform_data = &veu2_platform_data,
+ },
+ .resource = veu2_resources,
+ .num_resources = ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+ .name = "VEU3",
+ .version = "0",
+ .irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+ [0] = {
+ .name = "VEU3",
+ .start = 0xfe92c000,
+ .end = 0xfe92c307,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device veu3_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 4,
+ .dev = {
+ .platform_data = &veu3_platform_data,
+ },
+ .resource = veu3_resources,
+ .num_resources = ARRAY_SIZE(veu3_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+ .name = "JPU",
+ .version = "0",
+ .irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+ [0] = {
+ .name = "JPU",
+ .start = 0xfe980000,
+ .end = 0xfe9902d3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device jpu_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 5,
+ .dev = {
+ .platform_data = &jpu_platform_data,
+ },
+ .resource = jpu_resources,
+ .num_resources = ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+ .name = "SPU2DSP0",
+ .version = "0",
+ .irq = evt2irq(0x1800),
+};
+
+static struct resource spu0_resources[] = {
+ [0] = {
+ .name = "SPU2DSP0",
+ .start = 0xfe200000,
+ .end = 0xfe2fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spu0_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 6,
+ .dev = {
+ .platform_data = &spu0_platform_data,
+ },
+ .resource = spu0_resources,
+ .num_resources = ARRAY_SIZE(spu0_resources),
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+ .name = "SPU2DSP1",
+ .version = "0",
+ .irq = evt2irq(0x1820),
+};
+
+static struct resource spu1_resources[] = {
+ [0] = {
+ .name = "SPU2DSP1",
+ .start = 0xfe300000,
+ .end = 0xfe3fffff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device spu1_device = {
+ .name = "uio_pdrv_genirq",
+ .id = 7,
+ .dev = {
+ .platform_data = &spu1_platform_data,
+ },
+ .resource = spu1_resources,
+ .num_resources = ARRAY_SIZE(spu1_resources),
+};
+
+static struct platform_device *sh7377_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &cmt10_device,
+};
+
+static struct platform_device *sh7377_devices[] __initdata = {
+ &vpu_device,
+ &veu0_device,
+ &veu1_device,
+ &veu2_device,
+ &veu3_device,
+ &jpu_device,
+ &spu0_device,
+ &spu1_device,
+};
+
+void __init sh7377_add_standard_devices(void)
+{
+ platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+
+ platform_add_devices(sh7377_devices,
+ ARRAY_SIZE(sh7377_devices));
+}
+
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR3_CMT1 (1 << 29)
+
+void __init sh7377_add_early_devices(void)
+{
+ /* enable clock to CMT1 */
+ __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
+
+ early_platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
new file mode 100644
index 00000000..e46821c0
--- /dev/null
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -0,0 +1,674 @@
+/*
+ * sh73a0 processor support
+ *
+ * Copyright (C) 2010 Takashi Yoshii
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2008 Yoshihiro Shimoda
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <mach/sh73a0.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+ .mapbase = 0xe6c40000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(72), gic_spi(72),
+ gic_spi(72), gic_spi(72) },
+};
+
+static struct platform_device scif0_device = {
+ .name = "sh-sci",
+ .id = 0,
+ .dev = {
+ .platform_data = &scif0_platform_data,
+ },
+};
+
+static struct plat_sci_port scif1_platform_data = {
+ .mapbase = 0xe6c50000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(73), gic_spi(73),
+ gic_spi(73), gic_spi(73) },
+};
+
+static struct platform_device scif1_device = {
+ .name = "sh-sci",
+ .id = 1,
+ .dev = {
+ .platform_data = &scif1_platform_data,
+ },
+};
+
+static struct plat_sci_port scif2_platform_data = {
+ .mapbase = 0xe6c60000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(74), gic_spi(74),
+ gic_spi(74), gic_spi(74) },
+};
+
+static struct platform_device scif2_device = {
+ .name = "sh-sci",
+ .id = 2,
+ .dev = {
+ .platform_data = &scif2_platform_data,
+ },
+};
+
+static struct plat_sci_port scif3_platform_data = {
+ .mapbase = 0xe6c70000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(75), gic_spi(75),
+ gic_spi(75), gic_spi(75) },
+};
+
+static struct platform_device scif3_device = {
+ .name = "sh-sci",
+ .id = 3,
+ .dev = {
+ .platform_data = &scif3_platform_data,
+ },
+};
+
+static struct plat_sci_port scif4_platform_data = {
+ .mapbase = 0xe6c80000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(78), gic_spi(78),
+ gic_spi(78), gic_spi(78) },
+};
+
+static struct platform_device scif4_device = {
+ .name = "sh-sci",
+ .id = 4,
+ .dev = {
+ .platform_data = &scif4_platform_data,
+ },
+};
+
+static struct plat_sci_port scif5_platform_data = {
+ .mapbase = 0xe6cb0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(79), gic_spi(79),
+ gic_spi(79), gic_spi(79) },
+};
+
+static struct platform_device scif5_device = {
+ .name = "sh-sci",
+ .id = 5,
+ .dev = {
+ .platform_data = &scif5_platform_data,
+ },
+};
+
+static struct plat_sci_port scif6_platform_data = {
+ .mapbase = 0xe6cc0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(156), gic_spi(156),
+ gic_spi(156), gic_spi(156) },
+};
+
+static struct platform_device scif6_device = {
+ .name = "sh-sci",
+ .id = 6,
+ .dev = {
+ .platform_data = &scif6_platform_data,
+ },
+};
+
+static struct plat_sci_port scif7_platform_data = {
+ .mapbase = 0xe6cd0000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFA,
+ .irqs = { gic_spi(143), gic_spi(143),
+ gic_spi(143), gic_spi(143) },
+};
+
+static struct platform_device scif7_device = {
+ .name = "sh-sci",
+ .id = 7,
+ .dev = {
+ .platform_data = &scif7_platform_data,
+ },
+};
+
+static struct plat_sci_port scif8_platform_data = {
+ .mapbase = 0xe6c30000,
+ .flags = UPF_BOOT_AUTOCONF,
+ .scscr = SCSCR_RE | SCSCR_TE,
+ .scbrr_algo_id = SCBRR_ALGO_4,
+ .type = PORT_SCIFB,
+ .irqs = { gic_spi(80), gic_spi(80),
+ gic_spi(80), gic_spi(80) },
+};
+
+static struct platform_device scif8_device = {
+ .name = "sh-sci",
+ .id = 8,
+ .dev = {
+ .platform_data = &scif8_platform_data,
+ },
+};
+
+static struct sh_timer_config cmt10_platform_data = {
+ .name = "CMT10",
+ .channel_offset = 0x10,
+ .timer_bit = 0,
+ .clockevent_rating = 125,
+ .clocksource_rating = 125,
+};
+
+static struct resource cmt10_resources[] = {
+ [0] = {
+ .name = "CMT10",
+ .start = 0xe6138010,
+ .end = 0xe613801b,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(65),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cmt10_device = {
+ .name = "sh_cmt",
+ .id = 10,
+ .dev = {
+ .platform_data = &cmt10_platform_data,
+ },
+ .resource = cmt10_resources,
+ .num_resources = ARRAY_SIZE(cmt10_resources),
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+ .name = "TMU00",
+ .channel_offset = 0x4,
+ .timer_bit = 0,
+ .clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+ [0] = {
+ .name = "TMU00",
+ .start = 0xfff60008,
+ .end = 0xfff60013,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu00_device = {
+ .name = "sh_tmu",
+ .id = 0,
+ .dev = {
+ .platform_data = &tmu00_platform_data,
+ },
+ .resource = tmu00_resources,
+ .num_resources = ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+ .name = "TMU01",
+ .channel_offset = 0x10,
+ .timer_bit = 1,
+ .clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+ [0] = {
+ .name = "TMU01",
+ .start = 0xfff60014,
+ .end = 0xfff6001f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tmu01_device = {
+ .name = "sh_tmu",
+ .id = 1,
+ .dev = {
+ .platform_data = &tmu01_platform_data,
+ },
+ .resource = tmu01_resources,
+ .num_resources = ARRAY_SIZE(tmu01_resources),
+};
+
+static struct resource i2c0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xe6820000,
+ .end = 0xe6820425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(167),
+ .end = gic_spi(170),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xe6822000,
+ .end = 0xe6822425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(51),
+ .end = gic_spi(54),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c2_resources[] = {
+ [0] = {
+ .name = "IIC2",
+ .start = 0xe6824000,
+ .end = 0xe6824425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(171),
+ .end = gic_spi(174),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c3_resources[] = {
+ [0] = {
+ .name = "IIC3",
+ .start = 0xe6826000,
+ .end = 0xe6826425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(183),
+ .end = gic_spi(186),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c4_resources[] = {
+ [0] = {
+ .name = "IIC4",
+ .start = 0xe6828000,
+ .end = 0xe6828425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(187),
+ .end = gic_spi(190),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0,
+ .resource = i2c0_resources,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+};
+
+static struct platform_device i2c1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1,
+ .resource = i2c1_resources,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+};
+
+static struct platform_device i2c2_device = {
+ .name = "i2c-sh_mobile",
+ .id = 2,
+ .resource = i2c2_resources,
+ .num_resources = ARRAY_SIZE(i2c2_resources),
+};
+
+static struct platform_device i2c3_device = {
+ .name = "i2c-sh_mobile",
+ .id = 3,
+ .resource = i2c3_resources,
+ .num_resources = ARRAY_SIZE(i2c3_resources),
+};
+
+static struct platform_device i2c4_device = {
+ .name = "i2c-sh_mobile",
+ .id = 4,
+ .resource = i2c4_resources,
+ .num_resources = ARRAY_SIZE(i2c4_resources),
+};
+
+/* Transmit sizes and respective CHCR register values */
+enum {
+ XMIT_SZ_8BIT = 0,
+ XMIT_SZ_16BIT = 1,
+ XMIT_SZ_32BIT = 2,
+ XMIT_SZ_64BIT = 7,
+ XMIT_SZ_128BIT = 3,
+ XMIT_SZ_256BIT = 4,
+ XMIT_SZ_512BIT = 5,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_64BIT] = 3, \
+ [XMIT_SZ_128BIT] = 4, \
+ [XMIT_SZ_256BIT] = 5, \
+ [XMIT_SZ_512BIT] = 6, \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+
+static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SCIF0_TX,
+ .addr = 0xe6c40020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x21,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF0_RX,
+ .addr = 0xe6c40024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x22,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_TX,
+ .addr = 0xe6c50020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x25,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_RX,
+ .addr = 0xe6c50024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x26,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_TX,
+ .addr = 0xe6c60020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x29,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_RX,
+ .addr = 0xe6c60024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x2a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_TX,
+ .addr = 0xe6c70020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x2d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_RX,
+ .addr = 0xe6c70024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x2e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_TX,
+ .addr = 0xe6c80020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x39,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_RX,
+ .addr = 0xe6c80024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x3a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_TX,
+ .addr = 0xe6cb0020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x35,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_RX,
+ .addr = 0xe6cb0024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x36,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_TX,
+ .addr = 0xe6cc0020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x1d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_RX,
+ .addr = 0xe6cc0024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x1e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF7_TX,
+ .addr = 0xe6cd0020,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x19,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF7_RX,
+ .addr = 0xe6cd0024,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x1a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF8_TX,
+ .addr = 0xe6c30040,
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
+ .mid_rid = 0x3d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF8_RX,
+ .addr = 0xe6c30060,
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
+ .mid_rid = 0x3e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xee100030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xee100030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xee120030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xee120030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xee140030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xee140030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_TX,
+ .addr = 0xe6bd0034,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd1,
+ }, {
+ .slave_id = SHDMA_SLAVE_MMCIF_RX,
+ .addr = 0xe6bd0034,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd2,
+ },
+};
+
+#define DMAE_CHANNEL(_offset) \
+ { \
+ .offset = _offset - 0x20, \
+ .dmars = _offset - 0x20 + 0x40, \
+ }
+
+static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
+ DMAE_CHANNEL(0x8000),
+ DMAE_CHANNEL(0x8080),
+ DMAE_CHANNEL(0x8100),
+ DMAE_CHANNEL(0x8180),
+ DMAE_CHANNEL(0x8200),
+ DMAE_CHANNEL(0x8280),
+ DMAE_CHANNEL(0x8300),
+ DMAE_CHANNEL(0x8380),
+ DMAE_CHANNEL(0x8400),
+ DMAE_CHANNEL(0x8480),
+ DMAE_CHANNEL(0x8500),
+ DMAE_CHANNEL(0x8580),
+ DMAE_CHANNEL(0x8600),
+ DMAE_CHANNEL(0x8680),
+ DMAE_CHANNEL(0x8700),
+ DMAE_CHANNEL(0x8780),
+ DMAE_CHANNEL(0x8800),
+ DMAE_CHANNEL(0x8880),
+ DMAE_CHANNEL(0x8900),
+ DMAE_CHANNEL(0x8980),
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
+ .slave = sh73a0_dmae_slaves,
+ .slave_num = ARRAY_SIZE(sh73a0_dmae_slaves),
+ .channel = sh73a0_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh73a0_dmae_channels),
+ .ts_low_shift = 3,
+ .ts_low_mask = 0x18,
+ .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
+ .ts_high_mask = 0x00300000,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_DME,
+};
+
+static struct resource sh73a0_dmae_resources[] = {
+ {
+ /* Registers including DMAOR and channels including DMARSx */
+ .start = 0xfe000020,
+ .end = 0xfe008a00 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = gic_spi(129),
+ .end = gic_spi(129),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-19 */
+ .start = gic_spi(109),
+ .end = gic_spi(128),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = sh73a0_dmae_resources,
+ .num_resources = ARRAY_SIZE(sh73a0_dmae_resources),
+ .dev = {
+ .platform_data = &sh73a0_dmae_platform_data,
+ },
+};
+
+static struct platform_device *sh73a0_early_devices[] __initdata = {
+ &scif0_device,
+ &scif1_device,
+ &scif2_device,
+ &scif3_device,
+ &scif4_device,
+ &scif5_device,
+ &scif6_device,
+ &scif7_device,
+ &scif8_device,
+ &cmt10_device,
+ &tmu00_device,
+ &tmu01_device,
+};
+
+static struct platform_device *sh73a0_late_devices[] __initdata = {
+ &i2c0_device,
+ &i2c1_device,
+ &i2c2_device,
+ &i2c3_device,
+ &i2c4_device,
+ &dma0_device,
+};
+
+#define SRCR2 0xe61580b0
+
+void __init sh73a0_add_standard_devices(void)
+{
+ /* Clear software reset bit on SY-DMAC module */
+ __raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
+
+ platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
+ platform_add_devices(sh73a0_late_devices,
+ ARRAY_SIZE(sh73a0_late_devices));
+}
+
+void __init sh73a0_add_early_devices(void)
+{
+ early_platform_add_devices(sh73a0_early_devices,
+ ARRAY_SIZE(sh73a0_early_devices));
+}
diff --git a/arch/arm/mach-shmobile/sleep-sh7372.S b/arch/arm/mach-shmobile/sleep-sh7372.S
new file mode 100644
index 00000000..d37d3ca4
--- /dev/null
+++ b/arch/arm/mach-shmobile/sleep-sh7372.S
@@ -0,0 +1,260 @@
+/*
+ * sh7372 lowlevel sleep code for "Core Standby Mode"
+ *
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * In "Core Standby Mode" the ARM core is off, but L2 cache is still on
+ *
+ * Based on mach-omap2/sleep34xx.S
+ *
+ * (C) Copyright 2007 Texas Instruments
+ * Karthik Dasu <karthik-dp@ti.com>
+ *
+ * (C) Copyright 2004 Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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>
+
+#define SMFRAM 0xe6a70000
+
+ .align
+kernel_flush:
+ .word v7_flush_dcache_all
+
+ .align 3
+ENTRY(sh7372_cpu_suspend)
+ stmfd sp!, {r0-r12, lr} @ save registers on stack
+
+ ldr r8, =SMFRAM
+
+ mov r4, sp @ Store sp
+ mrs r5, spsr @ Store spsr
+ mov r6, lr @ Store lr
+ stmia r8!, {r4-r6}
+
+ mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register
+ mrc p15, 0, r5, c2, c0, 0 @ TTBR0
+ mrc p15, 0, r6, c2, c0, 1 @ TTBR1
+ mrc p15, 0, r7, c2, c0, 2 @ TTBCR
+ stmia r8!, {r4-r7}
+
+ mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register
+ mrc p15, 0, r5, c10, c2, 0 @ PRRR
+ mrc p15, 0, r6, c10, c2, 1 @ NMRR
+ stmia r8!,{r4-r6}
+
+ mrc p15, 0, r4, c13, c0, 1 @ Context ID
+ mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
+ mrs r7, cpsr @ Store current cpsr
+ stmia r8!, {r4-r7}
+
+ mrc p15, 0, r4, c1, c0, 0 @ save control register
+ stmia r8!, {r4}
+
+ /*
+ * jump out to kernel flush routine
+ * - reuse that code is better
+ * - it executes in a cached space so is faster than refetch per-block
+ * - should be faster and will change with kernel
+ * - 'might' have to copy address, load and jump to it
+ * Flush all data from the L1 data cache before disabling
+ * SCTLR.C bit.
+ */
+ ldr r1, kernel_flush
+ mov lr, pc
+ bx r1
+
+ /*
+ * Clear the SCTLR.C bit to prevent further data cache
+ * allocation. Clearing SCTLR.C would make all the data accesses
+ * strongly ordered and would not hit the cache.
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #(1 << 2) @ Disable the C bit
+ mcr p15, 0, r0, c1, c0, 0
+ isb
+
+ /*
+ * Invalidate L1 data cache. Even though only invalidate is
+ * necessary exported flush API is used here. Doing clean
+ * on already clean cache would be almost NOP.
+ */
+ ldr r1, kernel_flush
+ blx r1
+ /*
+ * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
+ * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
+ * This sequence switches back to ARM. Note that .align may insert a
+ * nop: bx pc needs to be word-aligned in order to work.
+ */
+ THUMB( .thumb )
+ THUMB( .align )
+ THUMB( bx pc )
+ THUMB( nop )
+ .arm
+
+ /* Data memory barrier and Data sync barrier */
+ dsb
+ dmb
+
+/*
+ * ===================================
+ * == WFI instruction => Enter idle ==
+ * ===================================
+ */
+ wfi @ wait for interrupt
+
+/*
+ * ===================================
+ * == Resume path for non-OFF modes ==
+ * ===================================
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ tst r0, #(1 << 2) @ Check C bit enabled?
+ orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared
+ mcreq p15, 0, r0, c1, c0, 0
+ isb
+
+/*
+ * ===================================
+ * == Exit point from non-OFF modes ==
+ * ===================================
+ */
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
+
+ .pool
+
+ .align 12
+ .text
+ .global sh7372_cpu_resume
+sh7372_cpu_resume:
+
+ mov r1, #0
+ /*
+ * Invalidate all instruction caches to PoU
+ * and flush branch target cache
+ */
+ mcr p15, 0, r1, c7, c5, 0
+
+ ldr r3, =SMFRAM
+
+ ldmia r3!, {r4-r6}
+ mov sp, r4 @ Restore sp
+ msr spsr_cxsf, r5 @ Restore spsr
+ mov lr, r6 @ Restore lr
+
+ ldmia r3!, {r4-r7}
+ mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register
+ mcr p15, 0, r5, c2, c0, 0 @ TTBR0
+ mcr p15, 0, r6, c2, c0, 1 @ TTBR1
+ mcr p15, 0, r7, c2, c0, 2 @ TTBCR
+
+ ldmia r3!,{r4-r6}
+ mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register
+ mcr p15, 0, r5, c10, c2, 0 @ PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ NMRR
+
+ ldmia r3!,{r4-r7}
+ mcr p15, 0, r4, c13, c0, 1 @ Context ID
+ mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID
+ mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address
+ msr cpsr, r7 @ store cpsr
+
+ /* Starting to enable MMU here */
+ mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl
+ /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
+ and r7, #0x7
+ cmp r7, #0x0
+ beq usettbr0
+ttbr_error:
+ /*
+ * More work needs to be done to support N[0:2] value other than 0
+ * So looping here so that the error can be detected
+ */
+ b ttbr_error
+
+ .align
+cache_pred_disable_mask:
+ .word 0xFFFFE7FB
+ttbrbit_mask:
+ .word 0xFFFFC000
+table_index_mask:
+ .word 0xFFF00000
+table_entry:
+ .word 0x00000C02
+usettbr0:
+
+ mrc p15, 0, r2, c2, c0, 0
+ ldr r5, ttbrbit_mask
+ and r2, r5
+ mov r4, pc
+ ldr r5, table_index_mask
+ and r4, r5 @ r4 = 31 to 20 bits of pc
+ /* Extract the value to be written to table entry */
+ ldr r6, table_entry
+ /* r6 has the value to be written to table entry */
+ add r6, r6, r4
+ /* Getting the address of table entry to modify */
+ lsr r4, #18
+ /* r2 has the location which needs to be modified */
+ add r2, r4
+ ldr r4, [r2]
+ str r6, [r2] /* modify the table entry */
+
+ mov r7, r6
+ mov r5, r2
+ mov r6, r4
+ /* r5 = original page table address */
+ /* r6 = original page table data */
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array
+ mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB
+ mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB
+
+ /*
+ * Restore control register. This enables the MMU.
+ * The caches and prediction are not enabled here, they
+ * will be enabled after restoring the MMU table entry.
+ */
+ ldmia r3!, {r4}
+ stmia r3!, {r5} /* save original page table address */
+ stmia r3!, {r6} /* save original page table data */
+ stmia r3!, {r7} /* save modified page table data */
+
+ ldr r2, cache_pred_disable_mask
+ and r4, r2
+ mcr p15, 0, r4, c1, c0, 0
+ dsb
+ isb
+
+ ldr r0, =restoremmu_on
+ bx r0
+
+/*
+ * ==============================
+ * == Exit point from OFF mode ==
+ * ==============================
+ */
+restoremmu_on:
+
+ ldmfd sp!, {r0-r12, pc} @ restore regs and return
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
new file mode 100644
index 00000000..3ffdbc92
--- /dev/null
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -0,0 +1,98 @@
+/*
+ * SMP support for R-Mobile / SH-Mobile - sh73a0 portion
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Takashi Yoshii
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <mach/common.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
+
+#define WUPCR 0xe6151010
+#define SRESCR 0xe6151018
+#define PSTR 0xe6151040
+#define SBAR 0xe6180020
+#define APARMBAREA 0xe6f10020
+
+static void __iomem *scu_base_addr(void)
+{
+ return (void __iomem *)0xf0000000;
+}
+
+static DEFINE_SPINLOCK(scu_lock);
+static unsigned long tmp;
+
+static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+ spin_lock(&scu_lock);
+ tmp = __raw_readl(scu_base + 8);
+ tmp &= ~clr;
+ tmp |= set;
+ spin_unlock(&scu_lock);
+
+ /* disable cache coherency after releasing the lock */
+ __raw_writel(tmp, scu_base + 8);
+}
+
+unsigned int __init sh73a0_get_core_count(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ /* twd_base needs to be initialized before percpu_timer_setup() */
+ twd_base = (void __iomem *)0xf0000600;
+#endif
+
+ return scu_get_core_count(scu_base);
+}
+
+void __cpuinit sh73a0_secondary_init(unsigned int cpu)
+{
+ gic_secondary_init(0);
+}
+
+int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
+{
+ /* enable cache coherency */
+ modify_scu_cpu_psr(0, 3 << (cpu * 8));
+
+ if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
+ __raw_writel(1 << cpu, __io(WUPCR)); /* wake up */
+ else
+ __raw_writel(1 << cpu, __io(SRESCR)); /* reset */
+
+ return 0;
+}
+
+void __init sh73a0_smp_prepare_cpus(void)
+{
+ scu_enable(scu_base_addr());
+
+ /* Map the reset vector (in headsmp.S) */
+ __raw_writel(0, __io(APARMBAREA)); /* 4k */
+ __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR));
+
+ /* enable cache coherency on CPU0 */
+ modify_scu_cpu_psr(0, 3 << (0 * 8));
+}
diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c
new file mode 100644
index 00000000..c1febe13
--- /dev/null
+++ b/arch/arm/mach-shmobile/suspend.c
@@ -0,0 +1,47 @@
+/*
+ * Suspend-to-RAM support code for SH-Mobile ARM
+ *
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static int shmobile_suspend_default_enter(suspend_state_t suspend_state)
+{
+ cpu_do_idle();
+ return 0;
+}
+
+static int shmobile_suspend_begin(suspend_state_t state)
+{
+ disable_hlt();
+ return 0;
+}
+
+static void shmobile_suspend_end(void)
+{
+ enable_hlt();
+}
+
+struct platform_suspend_ops shmobile_suspend_ops = {
+ .begin = shmobile_suspend_begin,
+ .end = shmobile_suspend_end,
+ .enter = shmobile_suspend_default_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init shmobile_suspend_init(void)
+{
+ suspend_set_ops(&shmobile_suspend_ops);
+ return 0;
+}
+late_initcall(shmobile_suspend_init);
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
new file mode 100644
index 00000000..895794b5
--- /dev/null
+++ b/arch/arm/mach-shmobile/timer.c
@@ -0,0 +1,46 @@
+/*
+ * SH-Mobile Timer
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2002 - 2009 Paul Mundt
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <linux/platform_device.h>
+#include <asm/mach/time.h>
+
+static void __init shmobile_late_time_init(void)
+{
+ /*
+ * Make sure all compiled-in early timers register themselves.
+ *
+ * Run probe() for two "earlytimer" devices, these will be the
+ * clockevents and clocksource devices respectively. In the event
+ * that only a clockevents device is available, we -ENODEV on the
+ * clocksource and the jiffies clocksource is used transparently
+ * instead. No error handling is necessary here.
+ */
+ early_platform_driver_register_all("earlytimer");
+ early_platform_driver_probe("earlytimer", 2, 0);
+}
+
+static void __init shmobile_timer_init(void)
+{
+ late_time_init = shmobile_late_time_init;
+}
+
+struct sys_timer shmobile_timer = {
+ .init = shmobile_timer_init,
+};
diff --git a/arch/arm/mach-spear3xx/Kconfig b/arch/arm/mach-spear3xx/Kconfig
new file mode 100644
index 00000000..2cee6b0d
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Kconfig
@@ -0,0 +1,43 @@
+#
+# SPEAr3XX Machine configuration file
+#
+
+if ARCH_SPEAR3XX
+
+menu "SPEAr3xx Implementations"
+config BOARD_SPEAR300_EVB
+ bool "SPEAr300 Evaluation Board"
+ select MACH_SPEAR300
+ help
+ Supports ST SPEAr300 Evaluation Board
+
+config BOARD_SPEAR310_EVB
+ bool "SPEAr310 Evaluation Board"
+ select MACH_SPEAR310
+ help
+ Supports ST SPEAr310 Evaluation Board
+
+config BOARD_SPEAR320_EVB
+ bool "SPEAr320 Evaluation Board"
+ select MACH_SPEAR320
+ help
+ Supports ST SPEAr320 Evaluation Board
+
+endmenu
+
+config MACH_SPEAR300
+ bool "SPEAr300"
+ help
+ Supports ST SPEAr300 Machine
+
+config MACH_SPEAR310
+ bool "SPEAr310"
+ help
+ Supports ST SPEAr310 Machine
+
+config MACH_SPEAR320
+ bool "SPEAr320"
+ help
+ Supports ST SPEAr320 Machine
+
+endif #ARCH_SPEAR3XX
diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile
new file mode 100644
index 00000000..b2486248
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for SPEAr3XX machine series
+#
+
+# common files
+obj-y += spear3xx.o clock.o
+
+# spear300 specific files
+obj-$(CONFIG_MACH_SPEAR300) += spear300.o
+
+# spear300 boards files
+obj-$(CONFIG_BOARD_SPEAR300_EVB) += spear300_evb.o
+
+
+# spear310 specific files
+obj-$(CONFIG_MACH_SPEAR310) += spear310.o
+
+# spear310 boards files
+obj-$(CONFIG_BOARD_SPEAR310_EVB) += spear310_evb.o
+
+
+# spear320 specific files
+obj-$(CONFIG_MACH_SPEAR320) += spear320.o
+
+# spear320 boards files
+obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o
diff --git a/arch/arm/mach-spear3xx/Makefile.boot b/arch/arm/mach-spear3xx/Makefile.boot
new file mode 100644
index 00000000..7a1f3c0e
--- /dev/null
+++ b/arch/arm/mach-spear3xx/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
new file mode 100644
index 00000000..f67860cd
--- /dev/null
+++ b/arch/arm/mach-spear3xx/clock.c
@@ -0,0 +1,759 @@
+/*
+ * arch/arm/mach-spear3xx/clock.c
+ *
+ * SPEAr3xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/mach-types.h>
+#include <plat/clock.h>
+#include <mach/misc_regs.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+ .flags = ALWAYS_ENABLED,
+ .rate = 32000,
+};
+
+/* 24 MHz oscillator clock */
+static struct clk osc_24m_clk = {
+ .flags = ALWAYS_ENABLED,
+ .rate = 24000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+ .pclk = &osc_32k_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = RTC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from 24 MHz osc clk */
+/* pll masks structure */
+static struct pll_clk_masks pll1_masks = {
+ .mode_mask = PLL_MODE_MASK,
+ .mode_shift = PLL_MODE_SHIFT,
+ .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
+ .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
+ .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
+ .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
+ .div_p_mask = PLL_DIV_P_MASK,
+ .div_p_shift = PLL_DIV_P_SHIFT,
+ .div_n_mask = PLL_DIV_N_MASK,
+ .div_n_shift = PLL_DIV_N_SHIFT,
+};
+
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+ .mode_reg = PLL1_CTR,
+ .cfg_reg = PLL1_FRQ,
+ .masks = &pll1_masks,
+};
+
+/* pll rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll_rtbl[] = {
+ {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
+ {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+ .flags = ENABLED_ON_INIT,
+ .pclk = &osc_24m_clk,
+ .en_reg = PLL1_CTR,
+ .en_reg_bit = PLL_ENABLE,
+ .calc_rate = &pll_calc_rate,
+ .recalc = &pll_clk_recalc,
+ .set_rate = &pll_clk_set_rate,
+ .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
+ .private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &osc_24m_clk,
+ .rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &osc_24m_clk,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .recalc = &follow_parent,
+};
+
+/* ahb masks structure */
+static struct bus_clk_masks ahb_masks = {
+ .mask = PLL_HCLK_RATIO_MASK,
+ .shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+ .reg = CORE_CLK_CFG,
+ .masks = &ahb_masks,
+};
+
+/* ahb rate configuration table, in ascending order of rates */
+struct bus_rate_tbl bus_rtbl[] = {
+ {.div = 3}, /* == parent divided by 4 */
+ {.div = 2}, /* == parent divided by 3 */
+ {.div = 1}, /* == parent divided by 2 */
+ {.div = 0}, /* == parent divided by 1 */
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &bus_calc_rate,
+ .recalc = &bus_clk_recalc,
+ .set_rate = &bus_clk_set_rate,
+ .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
+ .private_data = &ahb_config,
+};
+
+/* auxiliary synthesizers masks */
+static struct aux_clk_masks aux_masks = {
+ .eq_sel_mask = AUX_EQ_SEL_MASK,
+ .eq_sel_shift = AUX_EQ_SEL_SHIFT,
+ .eq1_mask = AUX_EQ1_SEL,
+ .eq2_mask = AUX_EQ2_SEL,
+ .xscale_sel_mask = AUX_XSCALE_MASK,
+ .xscale_sel_shift = AUX_XSCALE_SHIFT,
+ .yscale_sel_mask = AUX_YSCALE_MASK,
+ .yscale_sel_shift = AUX_YSCALE_SHIFT,
+};
+
+/* uart synth configurations */
+static struct aux_clk_config uart_synth_config = {
+ .synth_reg = UART_CLK_SYNT,
+ .masks = &aux_masks,
+};
+
+/* aux rate configuration table, in ascending order of rates */
+struct aux_rate_tbl aux_rtbl[] = {
+ /* For PLL1 = 332 MHz */
+ {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
+ {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
+ {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
+};
+
+/* uart synth clock */
+static struct clk uart_synth_clk = {
+ .en_reg = UART_CLK_SYNT,
+ .en_reg_bit = AUX_SYNT_ENB,
+ .pclk = &pll1_clk,
+ .calc_rate = &aux_calc_rate,
+ .recalc = &aux_clk_recalc,
+ .set_rate = &aux_clk_set_rate,
+ .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
+ .private_data = &uart_synth_config,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+ {
+ .pclk = &uart_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+ .pclk_info = uart_pclk_info,
+ .pclk_count = ARRAY_SIZE(uart_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart clock */
+static struct clk uart_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = UART_CLK_ENB,
+ .pclk_sel = &uart_pclk_sel,
+ .pclk_sel_shift = UART_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_synth_config = {
+ .synth_reg = FIRDA_CLK_SYNT,
+ .masks = &aux_masks,
+};
+
+/* firda synth clock */
+static struct clk firda_synth_clk = {
+ .en_reg = FIRDA_CLK_SYNT,
+ .en_reg_bit = AUX_SYNT_ENB,
+ .pclk = &pll1_clk,
+ .calc_rate = &aux_calc_rate,
+ .recalc = &aux_clk_recalc,
+ .set_rate = &aux_clk_set_rate,
+ .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 1},
+ .private_data = &firda_synth_config,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+ {
+ .pclk = &firda_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+ .pclk_info = firda_pclk_info,
+ .pclk_count = ARRAY_SIZE(firda_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = FIRDA_CLK_ENB,
+ .pclk_sel = &firda_pclk_sel,
+ .pclk_sel_shift = FIRDA_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt synthesizer masks */
+static struct gpt_clk_masks gpt_masks = {
+ .mscale_sel_mask = GPT_MSCALE_MASK,
+ .mscale_sel_shift = GPT_MSCALE_SHIFT,
+ .nscale_sel_mask = GPT_NSCALE_MASK,
+ .nscale_sel_shift = GPT_NSCALE_SHIFT,
+};
+
+/* gpt rate configuration table, in ascending order of rates */
+struct gpt_rate_tbl gpt_rtbl[] = {
+ /* For pll1 = 332 MHz */
+ {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
+ {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
+ {.mscale = 1, .nscale = 0}, /* 83 MHz */
+};
+
+/* gpt0 synth clk config*/
+static struct gpt_clk_config gpt0_synth_config = {
+ .synth_reg = PRSC1_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt synth clock */
+static struct clk gpt0_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt0_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt0_pclk_info[] = {
+ {
+ .pclk = &gpt0_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt0_pclk_sel = {
+ .pclk_info = gpt0_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0 timer clock */
+static struct clk gpt0_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk_sel = &gpt0_pclk_sel,
+ .pclk_sel_shift = GPT0_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt1 synth clk configurations */
+static struct gpt_clk_config gpt1_synth_config = {
+ .synth_reg = PRSC2_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt1 synth clock */
+static struct clk gpt1_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt1_synth_config,
+};
+
+static struct pclk_info gpt1_pclk_info[] = {
+ {
+ .pclk = &gpt1_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt1_pclk_sel = {
+ .pclk_info = gpt1_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt1_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GPT1_CLK_ENB,
+ .pclk_sel = &gpt1_pclk_sel,
+ .pclk_sel_shift = GPT1_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt2 synth clk configurations */
+static struct gpt_clk_config gpt2_synth_config = {
+ .synth_reg = PRSC3_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt1 synth clock */
+static struct clk gpt2_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt2_synth_config,
+};
+
+static struct pclk_info gpt2_pclk_info[] = {
+ {
+ .pclk = &gpt2_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt2_pclk_sel = {
+ .pclk_info = gpt2_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GPT2_CLK_ENB,
+ .pclk_sel = &gpt2_pclk_sel,
+ .pclk_sel_shift = GPT2_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from pll3 clk */
+/* usbh clock */
+static struct clk usbh_clk = {
+ .pclk = &pll3_48m_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = USBH_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+ .pclk = &pll3_48m_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = USBD_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb masks structure */
+static struct bus_clk_masks apb_masks = {
+ .mask = HCLK_PCLK_RATIO_MASK,
+ .shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+ .reg = CORE_CLK_CFG,
+ .masks = &apb_masks,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .calc_rate = &bus_calc_rate,
+ .recalc = &bus_clk_recalc,
+ .set_rate = &bus_clk_set_rate,
+ .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
+ .private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = I2C_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = DMA_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = JPEG_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GMAC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SMI_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* c3 clock */
+static struct clk c3_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = C3_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = ADC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* emi clock */
+static struct clk emi_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .recalc = &follow_parent,
+};
+#endif
+
+/* ssp clock */
+static struct clk ssp0_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SSP_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* gpio clock */
+static struct clk gpio_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GPIO_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+static struct clk dummy_apb_pclk;
+
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
+ defined(CONFIG_MACH_SPEAR320)
+/* fsmc clock */
+static struct clk fsmc_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .recalc = &follow_parent,
+};
+#endif
+
+/* common clocks to spear310 and spear320 */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* uart1 clock */
+static struct clk uart1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* uart2 clock */
+static struct clk uart2_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
+
+/* common clocks to spear300 and spear320 */
+#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
+/* clcd clock */
+static struct clk clcd_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll3_48m_clk,
+ .recalc = &follow_parent,
+};
+
+/* sdhci clock */
+static struct clk sdhci_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .recalc = &follow_parent,
+};
+#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
+
+/* spear300 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR300
+/* gpio1 clock */
+static struct clk gpio1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* keyboard clock */
+static struct clk kbd_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+#endif
+
+/* spear310 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR310
+/* uart3 clock */
+static struct clk uart3_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* uart4 clock */
+static struct clk uart4_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* uart5 clock */
+static struct clk uart5_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+#endif
+
+/* spear320 machine specific clock structures */
+#ifdef CONFIG_MACH_SPEAR320
+/* can0 clock */
+static struct clk can0_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* can1 clock */
+static struct clk can1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* i2c1 clock */
+static struct clk i2c1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .recalc = &follow_parent,
+};
+
+/* ssp1 clock */
+static struct clk ssp1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* ssp2 clock */
+static struct clk ssp2_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* pwm clock */
+static struct clk pwm_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+#endif
+
+/* array of all spear 3xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+ { .con_id = "apb_pclk", .clk = &dummy_apb_pclk},
+ /* root clks */
+ { .con_id = "osc_32k_clk", .clk = &osc_32k_clk},
+ { .con_id = "osc_24m_clk", .clk = &osc_24m_clk},
+ /* clock derived from 32 KHz osc clk */
+ { .dev_id = "rtc-spear", .clk = &rtc_clk},
+ /* clock derived from 24 MHz osc clk */
+ { .con_id = "pll1_clk", .clk = &pll1_clk},
+ { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk},
+ { .dev_id = "wdt", .clk = &wdt_clk},
+ /* clock derived from pll1 clk */
+ { .con_id = "cpu_clk", .clk = &cpu_clk},
+ { .con_id = "ahb_clk", .clk = &ahb_clk},
+ { .con_id = "uart_synth_clk", .clk = &uart_synth_clk},
+ { .con_id = "firda_synth_clk", .clk = &firda_synth_clk},
+ { .con_id = "gpt0_synth_clk", .clk = &gpt0_synth_clk},
+ { .con_id = "gpt1_synth_clk", .clk = &gpt1_synth_clk},
+ { .con_id = "gpt2_synth_clk", .clk = &gpt2_synth_clk},
+ { .dev_id = "uart", .clk = &uart_clk},
+ { .dev_id = "firda", .clk = &firda_clk},
+ { .dev_id = "gpt0", .clk = &gpt0_clk},
+ { .dev_id = "gpt1", .clk = &gpt1_clk},
+ { .dev_id = "gpt2", .clk = &gpt2_clk},
+ /* clock derived from pll3 clk */
+ { .dev_id = "designware_udc", .clk = &usbd_clk},
+ { .con_id = "usbh_clk", .clk = &usbh_clk},
+ /* clock derived from ahb clk */
+ { .con_id = "apb_clk", .clk = &apb_clk},
+ { .dev_id = "i2c_designware.0", .clk = &i2c_clk},
+ { .dev_id = "dma", .clk = &dma_clk},
+ { .dev_id = "jpeg", .clk = &jpeg_clk},
+ { .dev_id = "gmac", .clk = &gmac_clk},
+ { .dev_id = "smi", .clk = &smi_clk},
+ { .dev_id = "c3", .clk = &c3_clk},
+ /* clock derived from apb clk */
+ { .dev_id = "adc", .clk = &adc_clk},
+ { .dev_id = "ssp-pl022.0", .clk = &ssp0_clk},
+ { .dev_id = "gpio", .clk = &gpio_clk},
+};
+
+/* array of all spear 300 clock lookups */
+#ifdef CONFIG_MACH_SPEAR300
+static struct clk_lookup spear300_clk_lookups[] = {
+ { .dev_id = "clcd", .clk = &clcd_clk},
+ { .con_id = "fsmc", .clk = &fsmc_clk},
+ { .dev_id = "gpio1", .clk = &gpio1_clk},
+ { .dev_id = "keyboard", .clk = &kbd_clk},
+ { .dev_id = "sdhci", .clk = &sdhci_clk},
+};
+#endif
+
+/* array of all spear 310 clock lookups */
+#ifdef CONFIG_MACH_SPEAR310
+static struct clk_lookup spear310_clk_lookups[] = {
+ { .con_id = "fsmc", .clk = &fsmc_clk},
+ { .con_id = "emi", .clk = &emi_clk},
+ { .dev_id = "uart1", .clk = &uart1_clk},
+ { .dev_id = "uart2", .clk = &uart2_clk},
+ { .dev_id = "uart3", .clk = &uart3_clk},
+ { .dev_id = "uart4", .clk = &uart4_clk},
+ { .dev_id = "uart5", .clk = &uart5_clk},
+};
+#endif
+
+/* array of all spear 320 clock lookups */
+#ifdef CONFIG_MACH_SPEAR320
+static struct clk_lookup spear320_clk_lookups[] = {
+ { .dev_id = "clcd", .clk = &clcd_clk},
+ { .con_id = "fsmc", .clk = &fsmc_clk},
+ { .dev_id = "i2c_designware.1", .clk = &i2c1_clk},
+ { .con_id = "emi", .clk = &emi_clk},
+ { .dev_id = "pwm", .clk = &pwm_clk},
+ { .dev_id = "sdhci", .clk = &sdhci_clk},
+ { .dev_id = "c_can_platform.0", .clk = &can0_clk},
+ { .dev_id = "c_can_platform.1", .clk = &can1_clk},
+ { .dev_id = "ssp-pl022.1", .clk = &ssp1_clk},
+ { .dev_id = "ssp-pl022.2", .clk = &ssp2_clk},
+ { .dev_id = "uart1", .clk = &uart1_clk},
+ { .dev_id = "uart2", .clk = &uart2_clk},
+};
+#endif
+
+void __init spear3xx_clk_init(void)
+{
+ int i, cnt;
+ struct clk_lookup *lookups;
+
+ if (machine_is_spear300()) {
+ cnt = ARRAY_SIZE(spear300_clk_lookups);
+ lookups = spear300_clk_lookups;
+ } else if (machine_is_spear310()) {
+ cnt = ARRAY_SIZE(spear310_clk_lookups);
+ lookups = spear310_clk_lookups;
+ } else {
+ cnt = ARRAY_SIZE(spear320_clk_lookups);
+ lookups = spear320_clk_lookups;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+ clk_register(&spear_clk_lookups[i]);
+
+ for (i = 0; i < cnt; i++)
+ clk_register(&lookups[i]);
+
+ clk_init();
+}
diff --git a/arch/arm/mach-spear3xx/include/mach/clkdev.h b/arch/arm/mach-spear3xx/include/mach/clkdev.h
new file mode 100644
index 00000000..a3d07339
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/debug-macro.S b/arch/arm/mach-spear3xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..590519f1
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header spear3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear3xx/include/mach/entry-macro.S b/arch/arm/mach-spear3xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..53da4224
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/entry-macro.S
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware/vic.h>
+#include <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =VA_SPEAR3XX_ML1_VIC_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status
+ teq \irqstat, #0
+ beq 1001f @ this will set/reset
+ @ zero register
+ /*
+ * Following code will find bit position of least significang
+ * bit set in irqstat, using following equation
+ * least significant bit set in n = (n & ~(n-1))
+ */
+ sub \tmp, \irqstat, #1 @ tmp = irqstat - 1
+ mvn \tmp, \tmp @ tmp = ~tmp
+ and \irqstat, \irqstat, \tmp @ irqstat &= tmp
+ /* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+ clz \tmp, \irqstat @ tmp = leading zeros
+ rsb \irqnr, \tmp, #0x1F @ irqnr = 32 - tmp - 1
+
+1001: /* EQ will be set if no irqs pending */
+ .endm
diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h
new file mode 100644
index 00000000..b8f31c39
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/generic.h
@@ -0,0 +1,200 @@
+/*
+ * arch/arm/mach-spear3xx/generic.h
+ *
+ * SPEAr3XX machine family generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <plat/padmux.h>
+
+/* spear3xx declarations */
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE SPEAR3XX_ML1_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ SPEAR3XX_IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ SPEAR3XX_IRQ_CPU_GPT1_2
+
+/* Add spear3xx family device structure declarations here */
+extern struct amba_device spear3xx_gpio_device;
+extern struct amba_device spear3xx_uart_device;
+extern struct sys_timer spear3xx_timer;
+
+/* Add spear3xx family function declarations here */
+void __init spear3xx_clk_init(void);
+void __init spear_setup_timer(void);
+void __init spear3xx_map_io(void);
+void __init spear3xx_init_irq(void);
+void __init spear3xx_init(void);
+
+/* pad mux declarations */
+#define PMX_FIRDA_MASK (1 << 14)
+#define PMX_I2C_MASK (1 << 13)
+#define PMX_SSP_CS_MASK (1 << 12)
+#define PMX_SSP_MASK (1 << 11)
+#define PMX_MII_MASK (1 << 10)
+#define PMX_GPIO_PIN0_MASK (1 << 9)
+#define PMX_GPIO_PIN1_MASK (1 << 8)
+#define PMX_GPIO_PIN2_MASK (1 << 7)
+#define PMX_GPIO_PIN3_MASK (1 << 6)
+#define PMX_GPIO_PIN4_MASK (1 << 5)
+#define PMX_GPIO_PIN5_MASK (1 << 4)
+#define PMX_UART0_MODEM_MASK (1 << 3)
+#define PMX_UART0_MASK (1 << 2)
+#define PMX_TIMER_3_4_MASK (1 << 1)
+#define PMX_TIMER_1_2_MASK (1 << 0)
+
+/* pad mux devices */
+extern struct pmx_dev spear3xx_pmx_firda;
+extern struct pmx_dev spear3xx_pmx_i2c;
+extern struct pmx_dev spear3xx_pmx_ssp_cs;
+extern struct pmx_dev spear3xx_pmx_ssp;
+extern struct pmx_dev spear3xx_pmx_mii;
+extern struct pmx_dev spear3xx_pmx_gpio_pin0;
+extern struct pmx_dev spear3xx_pmx_gpio_pin1;
+extern struct pmx_dev spear3xx_pmx_gpio_pin2;
+extern struct pmx_dev spear3xx_pmx_gpio_pin3;
+extern struct pmx_dev spear3xx_pmx_gpio_pin4;
+extern struct pmx_dev spear3xx_pmx_gpio_pin5;
+extern struct pmx_dev spear3xx_pmx_uart0_modem;
+extern struct pmx_dev spear3xx_pmx_uart0;
+extern struct pmx_dev spear3xx_pmx_timer_3_4;
+extern struct pmx_dev spear3xx_pmx_timer_1_2;
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* padmux plgpio devices */
+extern struct pmx_dev spear3xx_pmx_plgpio_0_1;
+extern struct pmx_dev spear3xx_pmx_plgpio_2_3;
+extern struct pmx_dev spear3xx_pmx_plgpio_4_5;
+extern struct pmx_dev spear3xx_pmx_plgpio_6_9;
+extern struct pmx_dev spear3xx_pmx_plgpio_10_27;
+extern struct pmx_dev spear3xx_pmx_plgpio_28;
+extern struct pmx_dev spear3xx_pmx_plgpio_29;
+extern struct pmx_dev spear3xx_pmx_plgpio_30;
+extern struct pmx_dev spear3xx_pmx_plgpio_31;
+extern struct pmx_dev spear3xx_pmx_plgpio_32;
+extern struct pmx_dev spear3xx_pmx_plgpio_33;
+extern struct pmx_dev spear3xx_pmx_plgpio_34_36;
+extern struct pmx_dev spear3xx_pmx_plgpio_37_42;
+extern struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48;
+extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
+#endif
+
+/* spear300 declarations */
+#ifdef CONFIG_MACH_SPEAR300
+/* Add spear300 machine device structure declarations here */
+extern struct amba_device spear300_gpio1_device;
+
+/* pad mux modes */
+extern struct pmx_mode spear300_nand_mode;
+extern struct pmx_mode spear300_nor_mode;
+extern struct pmx_mode spear300_photo_frame_mode;
+extern struct pmx_mode spear300_lend_ip_phone_mode;
+extern struct pmx_mode spear300_hend_ip_phone_mode;
+extern struct pmx_mode spear300_lend_wifi_phone_mode;
+extern struct pmx_mode spear300_hend_wifi_phone_mode;
+extern struct pmx_mode spear300_ata_pabx_wi2s_mode;
+extern struct pmx_mode spear300_ata_pabx_i2s_mode;
+extern struct pmx_mode spear300_caml_lcdw_mode;
+extern struct pmx_mode spear300_camu_lcd_mode;
+extern struct pmx_mode spear300_camu_wlcd_mode;
+extern struct pmx_mode spear300_caml_lcd_mode;
+
+/* pad mux devices */
+extern struct pmx_dev spear300_pmx_fsmc_2_chips;
+extern struct pmx_dev spear300_pmx_fsmc_4_chips;
+extern struct pmx_dev spear300_pmx_keyboard;
+extern struct pmx_dev spear300_pmx_clcd;
+extern struct pmx_dev spear300_pmx_telecom_gpio;
+extern struct pmx_dev spear300_pmx_telecom_tdm;
+extern struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk;
+extern struct pmx_dev spear300_pmx_telecom_camera;
+extern struct pmx_dev spear300_pmx_telecom_dac;
+extern struct pmx_dev spear300_pmx_telecom_i2s;
+extern struct pmx_dev spear300_pmx_telecom_boot_pins;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_4bit;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_8bit;
+extern struct pmx_dev spear300_pmx_gpio1;
+
+/* Add spear300 machine function declarations here */
+void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count);
+
+#endif /* CONFIG_MACH_SPEAR300 */
+
+/* spear310 declarations */
+#ifdef CONFIG_MACH_SPEAR310
+/* Add spear310 machine device structure declarations here */
+
+/* pad mux devices */
+extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
+extern struct pmx_dev spear310_pmx_emi_cs_2_3;
+extern struct pmx_dev spear310_pmx_uart1;
+extern struct pmx_dev spear310_pmx_uart2;
+extern struct pmx_dev spear310_pmx_uart3_4_5;
+extern struct pmx_dev spear310_pmx_fsmc;
+extern struct pmx_dev spear310_pmx_rs485_0_1;
+extern struct pmx_dev spear310_pmx_tdm0;
+
+/* Add spear310 machine function declarations here */
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count);
+
+#endif /* CONFIG_MACH_SPEAR310 */
+
+/* spear320 declarations */
+#ifdef CONFIG_MACH_SPEAR320
+/* Add spear320 machine device structure declarations here */
+
+/* pad mux modes */
+extern struct pmx_mode spear320_auto_net_smii_mode;
+extern struct pmx_mode spear320_auto_net_mii_mode;
+extern struct pmx_mode spear320_auto_exp_mode;
+extern struct pmx_mode spear320_small_printers_mode;
+
+/* pad mux devices */
+extern struct pmx_dev spear320_pmx_clcd;
+extern struct pmx_dev spear320_pmx_emi;
+extern struct pmx_dev spear320_pmx_fsmc;
+extern struct pmx_dev spear320_pmx_spp;
+extern struct pmx_dev spear320_pmx_sdhci;
+extern struct pmx_dev spear320_pmx_i2s;
+extern struct pmx_dev spear320_pmx_uart1;
+extern struct pmx_dev spear320_pmx_uart1_modem;
+extern struct pmx_dev spear320_pmx_uart2;
+extern struct pmx_dev spear320_pmx_touchscreen;
+extern struct pmx_dev spear320_pmx_can;
+extern struct pmx_dev spear320_pmx_sdhci_led;
+extern struct pmx_dev spear320_pmx_pwm0;
+extern struct pmx_dev spear320_pmx_pwm1;
+extern struct pmx_dev spear320_pmx_pwm2;
+extern struct pmx_dev spear320_pmx_pwm3;
+extern struct pmx_dev spear320_pmx_ssp1;
+extern struct pmx_dev spear320_pmx_ssp2;
+extern struct pmx_dev spear320_pmx_mii1;
+extern struct pmx_dev spear320_pmx_smii0;
+extern struct pmx_dev spear320_pmx_smii1;
+extern struct pmx_dev spear320_pmx_i2c1;
+
+/* Add spear320 machine function declarations here */
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count);
+
+#endif /* CONFIG_MACH_SPEAR320 */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/gpio.h b/arch/arm/mach-spear3xx/include/mach/gpio.h
new file mode 100644
index 00000000..451b2081
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/hardware.h b/arch/arm/mach-spear3xx/include/mach/hardware.h
new file mode 100644
index 00000000..4660c0d8
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/hardware.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <plat/hardware.h>
+#include <mach/spear.h>
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x) (x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/io.h b/arch/arm/mach-spear3xx/include/mach/io.h
new file mode 100644
index 00000000..30cff8a1
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/io.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
new file mode 100644
index 00000000..6e265442
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* SPEAr3xx IRQ definitions */
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_0 0
+#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1
+#define SPEAR3XX_IRQ_CPU_GPT1_1 2
+#define SPEAR3XX_IRQ_CPU_GPT1_2 3
+#define SPEAR3XX_IRQ_BASIC_GPT1_1 4
+#define SPEAR3XX_IRQ_BASIC_GPT1_2 5
+#define SPEAR3XX_IRQ_BASIC_GPT2_1 6
+#define SPEAR3XX_IRQ_BASIC_GPT2_2 7
+#define SPEAR3XX_IRQ_BASIC_DMA 8
+#define SPEAR3XX_IRQ_BASIC_SMI 9
+#define SPEAR3XX_IRQ_BASIC_RTC 10
+#define SPEAR3XX_IRQ_BASIC_GPIO 11
+#define SPEAR3XX_IRQ_BASIC_WDT 12
+#define SPEAR3XX_IRQ_DDR_CONTROLLER 13
+#define SPEAR3XX_IRQ_SYS_ERROR 14
+#define SPEAR3XX_IRQ_WAKEUP_RCV 15
+#define SPEAR3XX_IRQ_JPEG 16
+#define SPEAR3XX_IRQ_IRDA 17
+#define SPEAR3XX_IRQ_ADC 18
+#define SPEAR3XX_IRQ_UART 19
+#define SPEAR3XX_IRQ_SSP 20
+#define SPEAR3XX_IRQ_I2C 21
+#define SPEAR3XX_IRQ_MAC_1 22
+#define SPEAR3XX_IRQ_MAC_2 23
+#define SPEAR3XX_IRQ_USB_DEV 24
+#define SPEAR3XX_IRQ_USB_H_OHCI_0 25
+#define SPEAR3XX_IRQ_USB_H_EHCI_0 26
+#define SPEAR3XX_IRQ_USB_H_EHCI_1 SPEAR3XX_IRQ_USB_H_EHCI_0
+#define SPEAR3XX_IRQ_USB_H_OHCI_1 27
+#define SPEAR3XX_IRQ_GEN_RAS_1 28
+#define SPEAR3XX_IRQ_GEN_RAS_2 29
+#define SPEAR3XX_IRQ_GEN_RAS_3 30
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_1 31
+#define SPEAR3XX_IRQ_VIC_END 32
+
+#define SPEAR3XX_VIRQ_START SPEAR3XX_IRQ_VIC_END
+
+/* SPEAr300 Virtual irq definitions */
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define SPEAR300_VIRQ_IT_PERS_S (SPEAR3XX_VIRQ_START + 0)
+#define SPEAR300_VIRQ_IT_CHANGE_S (SPEAR3XX_VIRQ_START + 1)
+#define SPEAR300_VIRQ_I2S (SPEAR3XX_VIRQ_START + 2)
+#define SPEAR300_VIRQ_TDM (SPEAR3XX_VIRQ_START + 3)
+#define SPEAR300_VIRQ_CAMERA_L (SPEAR3XX_VIRQ_START + 4)
+#define SPEAR300_VIRQ_CAMERA_F (SPEAR3XX_VIRQ_START + 5)
+#define SPEAR300_VIRQ_CAMERA_V (SPEAR3XX_VIRQ_START + 6)
+#define SPEAR300_VIRQ_KEYBOARD (SPEAR3XX_VIRQ_START + 7)
+#define SPEAR300_VIRQ_GPIO1 (SPEAR3XX_VIRQ_START + 8)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define SPEAR300_IRQ_CLCD SPEAR3XX_IRQ_GEN_RAS_3
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define SPEAR300_IRQ_SDHCI SPEAR3XX_IRQ_INTRCOMM_RAS_ARM
+
+/* SPEAr310 Virtual irq definitions */
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define SPEAR310_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 0)
+#define SPEAR310_VIRQ_SMII1 (SPEAR3XX_VIRQ_START + 1)
+#define SPEAR310_VIRQ_SMII2 (SPEAR3XX_VIRQ_START + 2)
+#define SPEAR310_VIRQ_SMII3 (SPEAR3XX_VIRQ_START + 3)
+#define SPEAR310_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 4)
+#define SPEAR310_VIRQ_WAKEUP_SMII1 (SPEAR3XX_VIRQ_START + 5)
+#define SPEAR310_VIRQ_WAKEUP_SMII2 (SPEAR3XX_VIRQ_START + 6)
+#define SPEAR310_VIRQ_WAKEUP_SMII3 (SPEAR3XX_VIRQ_START + 7)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define SPEAR310_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8)
+#define SPEAR310_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9)
+#define SPEAR310_VIRQ_UART3 (SPEAR3XX_VIRQ_START + 10)
+#define SPEAR310_VIRQ_UART4 (SPEAR3XX_VIRQ_START + 11)
+#define SPEAR310_VIRQ_UART5 (SPEAR3XX_VIRQ_START + 12)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define SPEAR310_VIRQ_EMI (SPEAR3XX_VIRQ_START + 13)
+#define SPEAR310_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 14)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define SPEAR310_VIRQ_TDM_HDLC (SPEAR3XX_VIRQ_START + 15)
+#define SPEAR310_VIRQ_RS485_0 (SPEAR3XX_VIRQ_START + 16)
+#define SPEAR310_VIRQ_RS485_1 (SPEAR3XX_VIRQ_START + 17)
+
+/* SPEAr320 Virtual irq definitions */
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define SPEAR320_VIRQ_EMI (SPEAR3XX_VIRQ_START + 0)
+#define SPEAR320_VIRQ_CLCD (SPEAR3XX_VIRQ_START + 1)
+#define SPEAR320_VIRQ_SPP (SPEAR3XX_VIRQ_START + 2)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define SPEAR320_IRQ_SDHCI SPEAR3XX_IRQ_GEN_RAS_2
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define SPEAR320_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 3)
+#define SPEAR320_VIRQ_I2S_PLAY (SPEAR3XX_VIRQ_START + 4)
+#define SPEAR320_VIRQ_I2S_REC (SPEAR3XX_VIRQ_START + 5)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define SPEAR320_VIRQ_CANU (SPEAR3XX_VIRQ_START + 6)
+#define SPEAR320_VIRQ_CANL (SPEAR3XX_VIRQ_START + 7)
+#define SPEAR320_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8)
+#define SPEAR320_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9)
+#define SPEAR320_VIRQ_SSP1 (SPEAR3XX_VIRQ_START + 10)
+#define SPEAR320_VIRQ_SSP2 (SPEAR3XX_VIRQ_START + 11)
+#define SPEAR320_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 12)
+#define SPEAR320_VIRQ_MII1_SMII1 (SPEAR3XX_VIRQ_START + 13)
+#define SPEAR320_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 14)
+#define SPEAR320_VIRQ_WAKEUP_MII1_SMII1 (SPEAR3XX_VIRQ_START + 15)
+#define SPEAR320_VIRQ_I2C1 (SPEAR3XX_VIRQ_START + 16)
+
+/*
+ * GPIO pins virtual irqs
+ * Use the lowest number for the GPIO virtual IRQs base on which subarchs
+ * we have compiled in
+ */
+#if defined(CONFIG_MACH_SPEAR310)
+#define SPEAR3XX_GPIO_INT_BASE (SPEAR3XX_VIRQ_START + 18)
+#elif defined(CONFIG_MACH_SPEAR320)
+#define SPEAR3XX_GPIO_INT_BASE (SPEAR3XX_VIRQ_START + 17)
+#else
+#define SPEAR3XX_GPIO_INT_BASE (SPEAR3XX_VIRQ_START + 9)
+#endif
+
+#define SPEAR300_GPIO1_INT_BASE (SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_PLGPIO_COUNT 102
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#define SPEAR3XX_PLGPIO_INT_BASE (SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_GPIO_INT_END (SPEAR3XX_PLGPIO_INT_BASE + \
+ SPEAR3XX_PLGPIO_COUNT)
+#else
+#define SPEAR3XX_GPIO_INT_END (SPEAR300_GPIO1_INT_BASE + 8)
+#endif
+
+#define SPEAR3XX_VIRQ_END SPEAR3XX_GPIO_INT_END
+#define NR_IRQS SPEAR3XX_VIRQ_END
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/memory.h b/arch/arm/mach-spear3xx/include/mach/memory.h
new file mode 100644
index 00000000..51735221
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/misc_regs.h b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
new file mode 100644
index 00000000..5bd8cd8d
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/misc_regs.h
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/hardware.h>
+
+#define MISC_BASE IOMEM(VA_SPEAR3XX_ICM3_MISC_REG_BASE)
+
+#define SOC_CFG_CTR (MISC_BASE + 0x000)
+#define DIAG_CFG_CTR (MISC_BASE + 0x004)
+#define PLL1_CTR (MISC_BASE + 0x008)
+#define PLL1_FRQ (MISC_BASE + 0x00C)
+#define PLL1_MOD (MISC_BASE + 0x010)
+#define PLL2_CTR (MISC_BASE + 0x014)
+/* PLL_CTR register masks */
+#define PLL_ENABLE 2
+#define PLL_MODE_SHIFT 4
+#define PLL_MODE_MASK 0x3
+#define PLL_MODE_NORMAL 0
+#define PLL_MODE_FRACTION 1
+#define PLL_MODE_DITH_DSB 2
+#define PLL_MODE_DITH_SSB 3
+
+#define PLL2_FRQ (MISC_BASE + 0x018)
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT 0
+#define PLL_DIV_N_MASK 0xFF
+#define PLL_DIV_P_SHIFT 8
+#define PLL_DIV_P_MASK 0x7
+#define PLL_NORM_FDBK_M_SHIFT 24
+#define PLL_NORM_FDBK_M_MASK 0xFF
+#define PLL_DITH_FDBK_M_SHIFT 16
+#define PLL_DITH_FDBK_M_MASK 0xFFFF
+
+#define PLL2_MOD (MISC_BASE + 0x01C)
+#define PLL_CLK_CFG (MISC_BASE + 0x020)
+#define CORE_CLK_CFG (MISC_BASE + 0x024)
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT 10
+#define PLL_HCLK_RATIO_MASK 0x3
+#define HCLK_PCLK_RATIO_SHIFT 8
+#define HCLK_PCLK_RATIO_MASK 0x3
+
+#define PERIP_CLK_CFG (MISC_BASE + 0x028)
+/* PERIP_CLK_CFG register masks */
+#define UART_CLK_SHIFT 4
+#define UART_CLK_MASK 0x1
+#define FIRDA_CLK_SHIFT 5
+#define FIRDA_CLK_MASK 0x3
+#define GPT0_CLK_SHIFT 8
+#define GPT1_CLK_SHIFT 11
+#define GPT2_CLK_SHIFT 12
+#define GPT_CLK_MASK 0x1
+#define AUX_CLK_PLL3_VAL 0
+#define AUX_CLK_PLL1_VAL 1
+
+#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
+/* PERIP1_CLK_ENB register masks */
+#define UART_CLK_ENB 3
+#define SSP_CLK_ENB 5
+#define I2C_CLK_ENB 7
+#define JPEG_CLK_ENB 8
+#define FIRDA_CLK_ENB 10
+#define GPT1_CLK_ENB 11
+#define GPT2_CLK_ENB 12
+#define ADC_CLK_ENB 15
+#define RTC_CLK_ENB 17
+#define GPIO_CLK_ENB 18
+#define DMA_CLK_ENB 19
+#define SMI_CLK_ENB 21
+#define GMAC_CLK_ENB 23
+#define USBD_CLK_ENB 24
+#define USBH_CLK_ENB 25
+#define C3_CLK_ENB 31
+
+#define SOC_CORE_ID (MISC_BASE + 0x030)
+#define RAS_CLK_ENB (MISC_BASE + 0x034)
+#define PERIP1_SOF_RST (MISC_BASE + 0x038)
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST 8
+
+#define SOC_USER_ID (MISC_BASE + 0x03C)
+#define RAS_SOF_RST (MISC_BASE + 0x040)
+#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
+#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
+#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT 0
+#define GPT_MSCALE_MASK 0xFFF
+#define GPT_NSCALE_SHIFT 12
+#define GPT_NSCALE_MASK 0xF
+
+#define AMEM_CLK_CFG (MISC_BASE + 0x050)
+#define EXPI_CLK_CFG (MISC_BASE + 0x054)
+#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
+#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
+#define UART_CLK_SYNT (MISC_BASE + 0x064)
+#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
+#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
+#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
+#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
+#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_SYNT_ENB 31
+#define AUX_EQ_SEL_SHIFT 30
+#define AUX_EQ_SEL_MASK 1
+#define AUX_EQ1_SEL 0
+#define AUX_EQ2_SEL 1
+#define AUX_XSCALE_SHIFT 16
+#define AUX_XSCALE_MASK 0xFFF
+#define AUX_YSCALE_SHIFT 0
+#define AUX_YSCALE_MASK 0xFFF
+
+#define ICM1_ARB_CFG (MISC_BASE + 0x07C)
+#define ICM2_ARB_CFG (MISC_BASE + 0x080)
+#define ICM3_ARB_CFG (MISC_BASE + 0x084)
+#define ICM4_ARB_CFG (MISC_BASE + 0x088)
+#define ICM5_ARB_CFG (MISC_BASE + 0x08C)
+#define ICM6_ARB_CFG (MISC_BASE + 0x090)
+#define ICM7_ARB_CFG (MISC_BASE + 0x094)
+#define ICM8_ARB_CFG (MISC_BASE + 0x098)
+#define ICM9_ARB_CFG (MISC_BASE + 0x09C)
+#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
+#define USB2_PHY_CFG (MISC_BASE + 0x0A4)
+#define GMAC_CFG_CTR (MISC_BASE + 0x0A8)
+#define EXPI_CFG_CTR (MISC_BASE + 0x0AC)
+#define PRC1_LOCK_CTR (MISC_BASE + 0x0C0)
+#define PRC2_LOCK_CTR (MISC_BASE + 0x0C4)
+#define PRC3_LOCK_CTR (MISC_BASE + 0x0C8)
+#define PRC4_LOCK_CTR (MISC_BASE + 0x0CC)
+#define PRC1_IRQ_CTR (MISC_BASE + 0x0D0)
+#define PRC2_IRQ_CTR (MISC_BASE + 0x0D4)
+#define PRC3_IRQ_CTR (MISC_BASE + 0x0D8)
+#define PRC4_IRQ_CTR (MISC_BASE + 0x0DC)
+#define PWRDOWN_CFG_CTR (MISC_BASE + 0x0E0)
+#define COMPSSTL_1V8_CFG (MISC_BASE + 0x0E4)
+#define COMPSSTL_2V5_CFG (MISC_BASE + 0x0E8)
+#define COMPCOR_3V3_CFG (MISC_BASE + 0x0EC)
+#define SSTLPAD_CFG_CTR (MISC_BASE + 0x0F0)
+#define BIST1_CFG_CTR (MISC_BASE + 0x0F4)
+#define BIST2_CFG_CTR (MISC_BASE + 0x0F8)
+#define BIST3_CFG_CTR (MISC_BASE + 0x0FC)
+#define BIST4_CFG_CTR (MISC_BASE + 0x100)
+#define BIST5_CFG_CTR (MISC_BASE + 0x104)
+#define BIST1_STS_RES (MISC_BASE + 0x108)
+#define BIST2_STS_RES (MISC_BASE + 0x10C)
+#define BIST3_STS_RES (MISC_BASE + 0x110)
+#define BIST4_STS_RES (MISC_BASE + 0x114)
+#define BIST5_STS_RES (MISC_BASE + 0x118)
+#define SYSERR_CFG_CTR (MISC_BASE + 0x11C)
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear.h b/arch/arm/mach-spear3xx/include/mach/spear.h
new file mode 100644
index 00000000..63fd9835
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear.h
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear.h
+ *
+ * SPEAr3xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR3XX_H
+#define __MACH_SPEAR3XX_H
+
+#include <asm/memory.h>
+#include <mach/spear300.h>
+#include <mach/spear310.h>
+#include <mach/spear320.h>
+
+#define SPEAR3XX_ML_SDRAM_BASE UL(0x00000000)
+
+#define SPEAR3XX_ICM9_BASE UL(0xC0000000)
+
+/* ICM1 - Low speed connection */
+#define SPEAR3XX_ICM1_2_BASE UL(0xD0000000)
+#define SPEAR3XX_ICM1_UART_BASE UL(0xD0000000)
+#define VA_SPEAR3XX_ICM1_UART_BASE IO_ADDRESS(SPEAR3XX_ICM1_UART_BASE)
+#define SPEAR3XX_ICM1_ADC_BASE UL(0xD0080000)
+#define SPEAR3XX_ICM1_SSP_BASE UL(0xD0100000)
+#define SPEAR3XX_ICM1_I2C_BASE UL(0xD0180000)
+#define SPEAR3XX_ICM1_JPEG_BASE UL(0xD0800000)
+#define SPEAR3XX_ICM1_IRDA_BASE UL(0xD1000000)
+#define SPEAR3XX_ICM1_SRAM_BASE UL(0xD2800000)
+
+/* ICM2 - Application Subsystem */
+#define SPEAR3XX_ICM2_HWACCEL0_BASE UL(0xD8800000)
+#define SPEAR3XX_ICM2_HWACCEL1_BASE UL(0xD9000000)
+
+/* ICM4 - High Speed Connection */
+#define SPEAR3XX_ICM4_BASE UL(0xE0000000)
+#define SPEAR3XX_ICM4_MII_BASE UL(0xE0800000)
+#define SPEAR3XX_ICM4_USBD_FIFO_BASE UL(0xE1000000)
+#define SPEAR3XX_ICM4_USBD_CSR_BASE UL(0xE1100000)
+#define SPEAR3XX_ICM4_USBD_PLDT_BASE UL(0xE1200000)
+#define SPEAR3XX_ICM4_USB_EHCI0_1_BASE UL(0xE1800000)
+#define SPEAR3XX_ICM4_USB_OHCI0_BASE UL(0xE1900000)
+#define SPEAR3XX_ICM4_USB_OHCI1_BASE UL(0xE2100000)
+#define SPEAR3XX_ICM4_USB_ARB_BASE UL(0xE2800000)
+
+/* ML1 - Multi Layer CPU Subsystem */
+#define SPEAR3XX_ICM3_ML1_2_BASE UL(0xF0000000)
+#define SPEAR3XX_ML1_TMR_BASE UL(0xF0000000)
+#define SPEAR3XX_ML1_VIC_BASE UL(0xF1100000)
+#define VA_SPEAR3XX_ML1_VIC_BASE IO_ADDRESS(SPEAR3XX_ML1_VIC_BASE)
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR3XX_ICM3_SMEM_BASE UL(0xF8000000)
+#define SPEAR3XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
+#define SPEAR3XX_ICM3_DMA_BASE UL(0xFC400000)
+#define SPEAR3XX_ICM3_SDRAM_CTRL_BASE UL(0xFC600000)
+#define SPEAR3XX_ICM3_TMR0_BASE UL(0xFC800000)
+#define SPEAR3XX_ICM3_WDT_BASE UL(0xFC880000)
+#define SPEAR3XX_ICM3_RTC_BASE UL(0xFC900000)
+#define SPEAR3XX_ICM3_GPIO_BASE UL(0xFC980000)
+#define SPEAR3XX_ICM3_SYS_CTRL_BASE UL(0xFCA00000)
+#define VA_SPEAR3XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR3XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR3XX_ICM3_MISC_REG_BASE UL(0xFCA80000)
+#define VA_SPEAR3XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR3XX_ICM3_MISC_REG_BASE)
+#define SPEAR3XX_ICM3_TMR1_BASE UL(0xFCB00000)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE SPEAR3XX_ICM1_UART_BASE
+#define VA_SPEAR_DBG_UART_BASE VA_SPEAR3XX_ICM1_UART_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE SPEAR3XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR3XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR3XX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
new file mode 100644
index 00000000..3b6ea072
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear300.h
+ *
+ * SPEAr300 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR300
+
+#ifndef __MACH_SPEAR300_H
+#define __MACH_SPEAR300_H
+
+/* Base address of various IPs */
+#define SPEAR300_TELECOM_BASE UL(0x50000000)
+
+/* Interrupt registers offsets and masks */
+#define SPEAR300_INT_ENB_MASK_REG 0x54
+#define SPEAR300_INT_STS_MASK_REG 0x58
+#define SPEAR300_IT_PERS_S_IRQ_MASK (1 << 0)
+#define SPEAR300_IT_CHANGE_S_IRQ_MASK (1 << 1)
+#define SPEAR300_I2S_IRQ_MASK (1 << 2)
+#define SPEAR300_TDM_IRQ_MASK (1 << 3)
+#define SPEAR300_CAMERA_L_IRQ_MASK (1 << 4)
+#define SPEAR300_CAMERA_F_IRQ_MASK (1 << 5)
+#define SPEAR300_CAMERA_V_IRQ_MASK (1 << 6)
+#define SPEAR300_KEYBOARD_IRQ_MASK (1 << 7)
+#define SPEAR300_GPIO1_IRQ_MASK (1 << 8)
+
+#define SPEAR300_SHIRQ_RAS1_MASK 0x1FF
+
+#define SPEAR300_CLCD_BASE UL(0x60000000)
+#define SPEAR300_SDHCI_BASE UL(0x70000000)
+#define SPEAR300_NAND_0_BASE UL(0x80000000)
+#define SPEAR300_NAND_1_BASE UL(0x84000000)
+#define SPEAR300_NAND_2_BASE UL(0x88000000)
+#define SPEAR300_NAND_3_BASE UL(0x8c000000)
+#define SPEAR300_NOR_0_BASE UL(0x90000000)
+#define SPEAR300_NOR_1_BASE UL(0x91000000)
+#define SPEAR300_NOR_2_BASE UL(0x92000000)
+#define SPEAR300_NOR_3_BASE UL(0x93000000)
+#define SPEAR300_FSMC_BASE UL(0x94000000)
+#define SPEAR300_SOC_CONFIG_BASE UL(0x99000000)
+#define SPEAR300_KEYBOARD_BASE UL(0xA0000000)
+#define SPEAR300_GPIO_BASE UL(0xA9000000)
+
+#endif /* __MACH_SPEAR300_H */
+
+#endif /* CONFIG_MACH_SPEAR300 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
new file mode 100644
index 00000000..1567d0da
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -0,0 +1,58 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear310.h
+ *
+ * SPEAr310 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR310
+
+#ifndef __MACH_SPEAR310_H
+#define __MACH_SPEAR310_H
+
+#define SPEAR310_NAND_BASE UL(0x40000000)
+#define SPEAR310_FSMC_BASE UL(0x44000000)
+#define SPEAR310_UART1_BASE UL(0xB2000000)
+#define SPEAR310_UART2_BASE UL(0xB2080000)
+#define SPEAR310_UART3_BASE UL(0xB2100000)
+#define SPEAR310_UART4_BASE UL(0xB2180000)
+#define SPEAR310_UART5_BASE UL(0xB2200000)
+#define SPEAR310_HDLC_BASE UL(0xB2800000)
+#define SPEAR310_RS485_0_BASE UL(0xB3000000)
+#define SPEAR310_RS485_1_BASE UL(0xB3800000)
+#define SPEAR310_SOC_CONFIG_BASE UL(0xB4000000)
+
+/* Interrupt registers offsets and masks */
+#define SPEAR310_INT_STS_MASK_REG 0x04
+#define SPEAR310_SMII0_IRQ_MASK (1 << 0)
+#define SPEAR310_SMII1_IRQ_MASK (1 << 1)
+#define SPEAR310_SMII2_IRQ_MASK (1 << 2)
+#define SPEAR310_SMII3_IRQ_MASK (1 << 3)
+#define SPEAR310_WAKEUP_SMII0_IRQ_MASK (1 << 4)
+#define SPEAR310_WAKEUP_SMII1_IRQ_MASK (1 << 5)
+#define SPEAR310_WAKEUP_SMII2_IRQ_MASK (1 << 6)
+#define SPEAR310_WAKEUP_SMII3_IRQ_MASK (1 << 7)
+#define SPEAR310_UART1_IRQ_MASK (1 << 8)
+#define SPEAR310_UART2_IRQ_MASK (1 << 9)
+#define SPEAR310_UART3_IRQ_MASK (1 << 10)
+#define SPEAR310_UART4_IRQ_MASK (1 << 11)
+#define SPEAR310_UART5_IRQ_MASK (1 << 12)
+#define SPEAR310_EMI_IRQ_MASK (1 << 13)
+#define SPEAR310_TDM_HDLC_IRQ_MASK (1 << 14)
+#define SPEAR310_RS485_0_IRQ_MASK (1 << 15)
+#define SPEAR310_RS485_1_IRQ_MASK (1 << 16)
+
+#define SPEAR310_SHIRQ_RAS1_MASK 0x000FF
+#define SPEAR310_SHIRQ_RAS2_MASK 0x01F00
+#define SPEAR310_SHIRQ_RAS3_MASK 0x02000
+#define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK 0x1C000
+
+#endif /* __MACH_SPEAR310_H */
+
+#endif /* CONFIG_MACH_SPEAR310 */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
new file mode 100644
index 00000000..8cfa83fa
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/spear320.h
+ *
+ * SPEAr320 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR320
+
+#ifndef __MACH_SPEAR320_H
+#define __MACH_SPEAR320_H
+
+#define SPEAR320_EMI_CTRL_BASE UL(0x40000000)
+#define SPEAR320_FSMC_BASE UL(0x4C000000)
+#define SPEAR320_NAND_BASE UL(0x50000000)
+#define SPEAR320_I2S_BASE UL(0x60000000)
+#define SPEAR320_SDHCI_BASE UL(0x70000000)
+#define SPEAR320_CLCD_BASE UL(0x90000000)
+#define SPEAR320_PAR_PORT_BASE UL(0xA0000000)
+#define SPEAR320_CAN0_BASE UL(0xA1000000)
+#define SPEAR320_CAN1_BASE UL(0xA2000000)
+#define SPEAR320_UART1_BASE UL(0xA3000000)
+#define SPEAR320_UART2_BASE UL(0xA4000000)
+#define SPEAR320_SSP0_BASE UL(0xA5000000)
+#define SPEAR320_SSP1_BASE UL(0xA6000000)
+#define SPEAR320_I2C_BASE UL(0xA7000000)
+#define SPEAR320_PWM_BASE UL(0xA8000000)
+#define SPEAR320_SMII0_BASE UL(0xAA000000)
+#define SPEAR320_SMII1_BASE UL(0xAB000000)
+#define SPEAR320_SOC_CONFIG_BASE UL(0xB3000000)
+
+/* Interrupt registers offsets and masks */
+#define SPEAR320_INT_STS_MASK_REG 0x04
+#define SPEAR320_INT_CLR_MASK_REG 0x04
+#define SPEAR320_INT_ENB_MASK_REG 0x08
+#define SPEAR320_GPIO_IRQ_MASK (1 << 0)
+#define SPEAR320_I2S_PLAY_IRQ_MASK (1 << 1)
+#define SPEAR320_I2S_REC_IRQ_MASK (1 << 2)
+#define SPEAR320_EMI_IRQ_MASK (1 << 7)
+#define SPEAR320_CLCD_IRQ_MASK (1 << 8)
+#define SPEAR320_SPP_IRQ_MASK (1 << 9)
+#define SPEAR320_SDHCI_IRQ_MASK (1 << 10)
+#define SPEAR320_CAN_U_IRQ_MASK (1 << 11)
+#define SPEAR320_CAN_L_IRQ_MASK (1 << 12)
+#define SPEAR320_UART1_IRQ_MASK (1 << 13)
+#define SPEAR320_UART2_IRQ_MASK (1 << 14)
+#define SPEAR320_SSP1_IRQ_MASK (1 << 15)
+#define SPEAR320_SSP2_IRQ_MASK (1 << 16)
+#define SPEAR320_SMII0_IRQ_MASK (1 << 17)
+#define SPEAR320_MII1_SMII1_IRQ_MASK (1 << 18)
+#define SPEAR320_WAKEUP_SMII0_IRQ_MASK (1 << 19)
+#define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK (1 << 20)
+#define SPEAR320_I2C1_IRQ_MASK (1 << 21)
+
+#define SPEAR320_SHIRQ_RAS1_MASK 0x000380
+#define SPEAR320_SHIRQ_RAS3_MASK 0x000007
+#define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK 0x3FF800
+
+#endif /* __MACH_SPEAR320_H */
+
+#endif /* CONFIG_MACH_SPEAR320 */
diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h
new file mode 100644
index 00000000..92cee633
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/system.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/system.h
+ *
+ * SPEAr3xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/timex.h b/arch/arm/mach-spear3xx/include/mach/timex.h
new file mode 100644
index 00000000..a38cc9de
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/timex.h
+ *
+ * SPEAr3XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/uncompress.h b/arch/arm/mach-spear3xx/include/mach/uncompress.h
new file mode 100644
index 00000000..53ba8bbc
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/vmalloc.h b/arch/arm/mach-spear3xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..df977b3c
--- /dev/null
+++ b/arch/arm/mach-spear3xx/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear3xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr3xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
new file mode 100644
index 00000000..a5e46b4a
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -0,0 +1,477 @@
+/*
+ * arch/arm/mach-spear3xx/spear300.c
+ *
+ * SPEAr300 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <plat/shirq.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG 0x00
+#define MODE_CONFIG_REG 0x04
+
+/* modes */
+#define NAND_MODE (1 << 0)
+#define NOR_MODE (1 << 1)
+#define PHOTO_FRAME_MODE (1 << 2)
+#define LEND_IP_PHONE_MODE (1 << 3)
+#define HEND_IP_PHONE_MODE (1 << 4)
+#define LEND_WIFI_PHONE_MODE (1 << 5)
+#define HEND_WIFI_PHONE_MODE (1 << 6)
+#define ATA_PABX_WI2S_MODE (1 << 7)
+#define ATA_PABX_I2S_MODE (1 << 8)
+#define CAML_LCDW_MODE (1 << 9)
+#define CAMU_LCD_MODE (1 << 10)
+#define CAMU_WLCD_MODE (1 << 11)
+#define CAML_LCD_MODE (1 << 12)
+#define ALL_MODES 0x1FFF
+
+struct pmx_mode spear300_nand_mode = {
+ .id = NAND_MODE,
+ .name = "nand mode",
+ .mask = 0x00,
+};
+
+struct pmx_mode spear300_nor_mode = {
+ .id = NOR_MODE,
+ .name = "nor mode",
+ .mask = 0x01,
+};
+
+struct pmx_mode spear300_photo_frame_mode = {
+ .id = PHOTO_FRAME_MODE,
+ .name = "photo frame mode",
+ .mask = 0x02,
+};
+
+struct pmx_mode spear300_lend_ip_phone_mode = {
+ .id = LEND_IP_PHONE_MODE,
+ .name = "lend ip phone mode",
+ .mask = 0x03,
+};
+
+struct pmx_mode spear300_hend_ip_phone_mode = {
+ .id = HEND_IP_PHONE_MODE,
+ .name = "hend ip phone mode",
+ .mask = 0x04,
+};
+
+struct pmx_mode spear300_lend_wifi_phone_mode = {
+ .id = LEND_WIFI_PHONE_MODE,
+ .name = "lend wifi phone mode",
+ .mask = 0x05,
+};
+
+struct pmx_mode spear300_hend_wifi_phone_mode = {
+ .id = HEND_WIFI_PHONE_MODE,
+ .name = "hend wifi phone mode",
+ .mask = 0x06,
+};
+
+struct pmx_mode spear300_ata_pabx_wi2s_mode = {
+ .id = ATA_PABX_WI2S_MODE,
+ .name = "ata pabx wi2s mode",
+ .mask = 0x07,
+};
+
+struct pmx_mode spear300_ata_pabx_i2s_mode = {
+ .id = ATA_PABX_I2S_MODE,
+ .name = "ata pabx i2s mode",
+ .mask = 0x08,
+};
+
+struct pmx_mode spear300_caml_lcdw_mode = {
+ .id = CAML_LCDW_MODE,
+ .name = "caml lcdw mode",
+ .mask = 0x0C,
+};
+
+struct pmx_mode spear300_camu_lcd_mode = {
+ .id = CAMU_LCD_MODE,
+ .name = "camu lcd mode",
+ .mask = 0x0D,
+};
+
+struct pmx_mode spear300_camu_wlcd_mode = {
+ .id = CAMU_WLCD_MODE,
+ .name = "camu wlcd mode",
+ .mask = 0x0E,
+};
+
+struct pmx_mode spear300_caml_lcd_mode = {
+ .id = CAML_LCD_MODE,
+ .name = "caml lcd mode",
+ .mask = 0x0F,
+};
+
+/* devices */
+static struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
+ {
+ .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .mask = PMX_FIRDA_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_fsmc_2_chips = {
+ .name = "fsmc_2_chips",
+ .modes = pmx_fsmc_2_chips_modes,
+ .mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
+ {
+ .ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_fsmc_4_chips = {
+ .name = "fsmc_4_chips",
+ .modes = pmx_fsmc_4_chips_modes,
+ .mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_keyboard_modes[] = {
+ {
+ .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+ LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ CAML_LCDW_MODE | CAMU_LCD_MODE | CAMU_WLCD_MODE |
+ CAML_LCD_MODE,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear300_pmx_keyboard = {
+ .name = "keyboard",
+ .modes = pmx_keyboard_modes,
+ .mode_count = ARRAY_SIZE(pmx_keyboard_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_clcd_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
+ }, {
+ .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ CAMU_LCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_clcd = {
+ .name = "clcd",
+ .modes = pmx_clcd_modes,
+ .mode_count = ARRAY_SIZE(pmx_clcd_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_MII_MASK,
+ }, {
+ .ids = LEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE,
+ .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+ }, {
+ .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_WLCD_MODE,
+ .mask = PMX_MII_MASK | PMX_TIMER_3_4_MASK,
+ }, {
+ .ids = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE,
+ .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK,
+ }, {
+ .ids = ATA_PABX_WI2S_MODE,
+ .mask = PMX_MII_MASK | PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK
+ | PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_gpio = {
+ .name = "telecom_gpio",
+ .modes = pmx_telecom_gpio_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+ | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+ | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_tdm = {
+ .name = "telecom_tdm",
+ .modes = pmx_telecom_tdm_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
+ {
+ .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+ LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
+ | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE |
+ CAML_LCDW_MODE | CAML_LCD_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk = {
+ .name = "telecom_spi_cs_i2c_clk",
+ .modes = pmx_telecom_spi_cs_i2c_clk_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+ {
+ .ids = CAML_LCDW_MODE | CAML_LCD_MODE,
+ .mask = PMX_MII_MASK,
+ }, {
+ .ids = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK | PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_camera = {
+ .name = "telecom_camera",
+ .modes = pmx_telecom_camera_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_dac_modes[] = {
+ {
+ .ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_TIMER_1_2_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_dac = {
+ .name = "telecom_dac",
+ .modes = pmx_telecom_dac_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
+ {
+ .ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+ | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_i2s = {
+ .name = "telecom_i2s",
+ .modes = pmx_telecom_i2s_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+ {
+ .ids = NAND_MODE | NOR_MODE,
+ .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+ PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_boot_pins = {
+ .name = "telecom_boot_pins",
+ .modes = pmx_telecom_boot_pins_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE |
+ ATA_PABX_I2S_MODE,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_sdhci_4bit = {
+ .name = "telecom_sdhci_4bit",
+ .modes = pmx_telecom_sdhci_4bit_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_telecom_sdhci_8bit = {
+ .name = "telecom_sdhci_8bit",
+ .modes = pmx_telecom_sdhci_8bit_modes,
+ .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_gpio1_modes[] = {
+ {
+ .ids = PHOTO_FRAME_MODE,
+ .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
+ PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear300_pmx_gpio1 = {
+ .name = "arm gpio1",
+ .modes = pmx_gpio1_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio1_modes),
+ .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+static struct pmx_driver pmx_driver = {
+ .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
+ .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* spear3xx shared irq */
+static struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = SPEAR300_VIRQ_IT_PERS_S,
+ .enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
+ .status_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_IT_CHANGE_S,
+ .enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
+ .status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_I2S,
+ .enb_mask = SPEAR300_I2S_IRQ_MASK,
+ .status_mask = SPEAR300_I2S_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_TDM,
+ .enb_mask = SPEAR300_TDM_IRQ_MASK,
+ .status_mask = SPEAR300_TDM_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_CAMERA_L,
+ .enb_mask = SPEAR300_CAMERA_L_IRQ_MASK,
+ .status_mask = SPEAR300_CAMERA_L_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_CAMERA_F,
+ .enb_mask = SPEAR300_CAMERA_F_IRQ_MASK,
+ .status_mask = SPEAR300_CAMERA_F_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_CAMERA_V,
+ .enb_mask = SPEAR300_CAMERA_V_IRQ_MASK,
+ .status_mask = SPEAR300_CAMERA_V_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_KEYBOARD,
+ .enb_mask = SPEAR300_KEYBOARD_IRQ_MASK,
+ .status_mask = SPEAR300_KEYBOARD_IRQ_MASK,
+ }, {
+ .virq = SPEAR300_VIRQ_GPIO1,
+ .enb_mask = SPEAR300_GPIO1_IRQ_MASK,
+ .status_mask = SPEAR300_GPIO1_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras1 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = SPEAR300_INT_ENB_MASK_REG,
+ .status_reg = SPEAR300_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK,
+ .clear_reg = -1,
+ },
+};
+
+/* Add spear300 specific devices here */
+/* arm gpio1 device registration */
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = SPEAR300_GPIO1_INT_BASE,
+};
+
+struct amba_device spear300_gpio1_device = {
+ .dev = {
+ .init_name = "gpio1",
+ .platform_data = &gpio1_plat_data,
+ },
+ .res = {
+ .start = SPEAR300_GPIO_BASE,
+ .end = SPEAR300_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
+};
+
+/* spear300 routines */
+void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count)
+{
+ int ret = 0;
+
+ /* call spear3xx family common init function */
+ spear3xx_init();
+
+ /* shared irq registration */
+ shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K);
+ if (shirq_ras1.regs.base) {
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ\n");
+ }
+
+ /* pmx initialization */
+ pmx_driver.mode = pmx_mode;
+ pmx_driver.devs = pmx_devs;
+ pmx_driver.devs_count = pmx_dev_count;
+
+ pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
+ if (pmx_driver.base) {
+ ret = pmx_register(&pmx_driver);
+ if (ret)
+ printk(KERN_ERR "padmux: registeration failed. err no"
+ ": %d\n", ret);
+ /* Free Mapping, device selection already done */
+ iounmap(pmx_driver.base);
+ }
+}
diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c
new file mode 100644
index 00000000..69006f69
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear300_evb.c
@@ -0,0 +1,72 @@
+/*
+ * arch/arm/mach-spear3xx/spear300_evb.c
+ *
+ * SPEAr300 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+ /* spear3xx specific devices */
+ &spear3xx_pmx_i2c,
+ &spear3xx_pmx_ssp_cs,
+ &spear3xx_pmx_ssp,
+ &spear3xx_pmx_mii,
+ &spear3xx_pmx_uart0,
+
+ /* spear300 specific devices */
+ &spear300_pmx_fsmc_2_chips,
+ &spear300_pmx_clcd,
+ &spear300_pmx_telecom_sdhci_4bit,
+ &spear300_pmx_gpio1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ /* spear3xx specific devices */
+ &spear3xx_gpio_device,
+ &spear3xx_uart_device,
+
+ /* spear300 specific devices */
+ &spear300_gpio1_device,
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+ /* spear3xx specific devices */
+
+ /* spear300 specific devices */
+};
+
+static void __init spear300_evb_init(void)
+{
+ unsigned int i;
+
+ /* call spear300 machine init function */
+ spear300_init(&spear300_photo_frame_mode, pmx_devs,
+ ARRAY_SIZE(pmx_devs));
+
+ /* Add Platform Devices */
+ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+ /* Add Amba Devices */
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR300, "ST-SPEAR300-EVB")
+ .boot_params = 0x00000100,
+ .map_io = spear3xx_map_io,
+ .init_irq = spear3xx_init_irq,
+ .timer = &spear3xx_timer,
+ .init_machine = spear300_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
new file mode 100644
index 00000000..9004cf9f
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -0,0 +1,308 @@
+/*
+ * arch/arm/mach-spear3xx/spear310.c
+ *
+ * SPEAr310 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <plat/shirq.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG 0x08
+
+/* devices */
+static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_emi_cs_0_1_4_5 = {
+ .name = "emi_cs_0_1_4_5",
+ .modes = pmx_emi_cs_0_1_4_5_modes,
+ .mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_TIMER_1_2_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_emi_cs_2_3 = {
+ .name = "emi_cs_2_3",
+ .modes = pmx_emi_cs_2_3_modes,
+ .mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart1_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_FIRDA_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_uart1 = {
+ .name = "uart1",
+ .modes = pmx_uart1_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart2_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_TIMER_1_2_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_uart2 = {
+ .name = "uart2",
+ .modes = pmx_uart2_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart2_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_uart3_4_5 = {
+ .name = "uart3_4_5",
+ .modes = pmx_uart3_4_5_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_fsmc = {
+ .name = "fsmc",
+ .modes = pmx_fsmc_modes,
+ .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_rs485_0_1 = {
+ .name = "rs485_0_1",
+ .modes = pmx_rs485_0_1_modes,
+ .mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_tdm0_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear310_pmx_tdm0 = {
+ .name = "tdm0",
+ .modes = pmx_tdm0_modes,
+ .mode_count = ARRAY_SIZE(pmx_tdm0_modes),
+ .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+static struct pmx_driver pmx_driver = {
+ .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* spear3xx shared irq */
+static struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = SPEAR310_VIRQ_SMII0,
+ .status_mask = SPEAR310_SMII0_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_SMII1,
+ .status_mask = SPEAR310_SMII1_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_SMII2,
+ .status_mask = SPEAR310_SMII2_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_SMII3,
+ .status_mask = SPEAR310_SMII3_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_WAKEUP_SMII0,
+ .status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_WAKEUP_SMII1,
+ .status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_WAKEUP_SMII2,
+ .status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_WAKEUP_SMII3,
+ .status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras1 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK,
+ .clear_reg = -1,
+ },
+};
+
+static struct shirq_dev_config shirq_ras2_config[] = {
+ {
+ .virq = SPEAR310_VIRQ_UART1,
+ .status_mask = SPEAR310_UART1_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_UART2,
+ .status_mask = SPEAR310_UART2_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_UART3,
+ .status_mask = SPEAR310_UART3_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_UART4,
+ .status_mask = SPEAR310_UART4_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_UART5,
+ .status_mask = SPEAR310_UART5_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras2 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_2,
+ .dev_config = shirq_ras2_config,
+ .dev_count = ARRAY_SIZE(shirq_ras2_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK,
+ .clear_reg = -1,
+ },
+};
+
+static struct shirq_dev_config shirq_ras3_config[] = {
+ {
+ .virq = SPEAR310_VIRQ_EMI,
+ .status_mask = SPEAR310_EMI_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras3 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_3,
+ .dev_config = shirq_ras3_config,
+ .dev_count = ARRAY_SIZE(shirq_ras3_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK,
+ .clear_reg = -1,
+ },
+};
+
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+ {
+ .virq = SPEAR310_VIRQ_TDM_HDLC,
+ .status_mask = SPEAR310_TDM_HDLC_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_RS485_0,
+ .status_mask = SPEAR310_RS485_0_IRQ_MASK,
+ }, {
+ .virq = SPEAR310_VIRQ_RS485_1,
+ .status_mask = SPEAR310_RS485_1_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_intrcomm_ras = {
+ .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
+ .dev_config = shirq_intrcomm_ras_config,
+ .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR310_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK,
+ .clear_reg = -1,
+ },
+};
+
+/* Add spear310 specific devices here */
+
+/* spear310 routines */
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count)
+{
+ void __iomem *base;
+ int ret = 0;
+
+ /* call spear3xx family common init function */
+ spear3xx_init();
+
+ /* shared irq registration */
+ base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K);
+ if (base) {
+ /* shirq 1 */
+ shirq_ras1.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+ /* shirq 2 */
+ shirq_ras2.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras2);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 2\n");
+
+ /* shirq 3 */
+ shirq_ras3.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras3);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+ /* shirq 4 */
+ shirq_intrcomm_ras.regs.base = base;
+ ret = spear_shirq_register(&shirq_intrcomm_ras);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 4\n");
+ }
+
+ /* pmx initialization */
+ pmx_driver.base = base;
+ pmx_driver.mode = pmx_mode;
+ pmx_driver.devs = pmx_devs;
+ pmx_driver.devs_count = pmx_dev_count;
+
+ ret = pmx_register(&pmx_driver);
+ if (ret)
+ printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+ ret);
+}
diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c
new file mode 100644
index 00000000..c8684ce1
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear310_evb.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-spear3xx/spear310_evb.c
+ *
+ * SPEAr310 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+ /* spear3xx specific devices */
+ &spear3xx_pmx_i2c,
+ &spear3xx_pmx_ssp,
+ &spear3xx_pmx_gpio_pin0,
+ &spear3xx_pmx_gpio_pin1,
+ &spear3xx_pmx_gpio_pin2,
+ &spear3xx_pmx_gpio_pin3,
+ &spear3xx_pmx_gpio_pin4,
+ &spear3xx_pmx_gpio_pin5,
+ &spear3xx_pmx_uart0,
+
+ /* spear310 specific devices */
+ &spear310_pmx_emi_cs_0_1_4_5,
+ &spear310_pmx_emi_cs_2_3,
+ &spear310_pmx_uart1,
+ &spear310_pmx_uart2,
+ &spear310_pmx_uart3_4_5,
+ &spear310_pmx_fsmc,
+ &spear310_pmx_rs485_0_1,
+ &spear310_pmx_tdm0,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ /* spear3xx specific devices */
+ &spear3xx_gpio_device,
+ &spear3xx_uart_device,
+
+ /* spear310 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+ /* spear3xx specific devices */
+
+ /* spear310 specific devices */
+};
+
+static void __init spear310_evb_init(void)
+{
+ unsigned int i;
+
+ /* call spear310 machine init function */
+ spear310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
+
+ /* Add Platform Devices */
+ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+ /* Add Amba Devices */
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR310, "ST-SPEAR310-EVB")
+ .boot_params = 0x00000100,
+ .map_io = spear3xx_map_io,
+ .init_irq = spear3xx_init_irq,
+ .timer = &spear3xx_timer,
+ .init_machine = spear310_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
new file mode 100644
index 00000000..ee29bef4
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -0,0 +1,555 @@
+/*
+ * arch/arm/mach-spear3xx/spear320.c
+ *
+ * SPEAr320 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <plat/shirq.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* pad multiplexing support */
+/* muxing registers */
+#define PAD_MUX_CONFIG_REG 0x0C
+#define MODE_CONFIG_REG 0x10
+
+/* modes */
+#define AUTO_NET_SMII_MODE (1 << 0)
+#define AUTO_NET_MII_MODE (1 << 1)
+#define AUTO_EXP_MODE (1 << 2)
+#define SMALL_PRINTERS_MODE (1 << 3)
+#define ALL_MODES 0xF
+
+struct pmx_mode spear320_auto_net_smii_mode = {
+ .id = AUTO_NET_SMII_MODE,
+ .name = "Automation Networking SMII Mode",
+ .mask = 0x00,
+};
+
+struct pmx_mode spear320_auto_net_mii_mode = {
+ .id = AUTO_NET_MII_MODE,
+ .name = "Automation Networking MII Mode",
+ .mask = 0x01,
+};
+
+struct pmx_mode spear320_auto_exp_mode = {
+ .id = AUTO_EXP_MODE,
+ .name = "Automation Expanded Mode",
+ .mask = 0x02,
+};
+
+struct pmx_mode spear320_small_printers_mode = {
+ .id = SMALL_PRINTERS_MODE,
+ .name = "Small Printers Mode",
+ .mask = 0x03,
+};
+
+/* devices */
+static struct pmx_dev_mode pmx_clcd_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear320_pmx_clcd = {
+ .name = "clcd",
+ .modes = pmx_clcd_modes,
+ .mode_count = ARRAY_SIZE(pmx_clcd_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_emi_modes[] = {
+ {
+ .ids = AUTO_EXP_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_emi = {
+ .name = "emi",
+ .modes = pmx_emi_modes,
+ .mode_count = ARRAY_SIZE(pmx_emi_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
+ {
+ .ids = ALL_MODES,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear320_pmx_fsmc = {
+ .name = "fsmc",
+ .modes = pmx_fsmc_modes,
+ .mode_count = ARRAY_SIZE(pmx_fsmc_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_spp_modes[] = {
+ {
+ .ids = SMALL_PRINTERS_MODE,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear320_pmx_spp = {
+ .name = "spp",
+ .modes = pmx_spp_modes,
+ .mode_count = ARRAY_SIZE(pmx_spp_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_sdhci_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
+ SMALL_PRINTERS_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_sdhci = {
+ .name = "sdhci",
+ .modes = pmx_sdhci_modes,
+ .mode_count = ARRAY_SIZE(pmx_sdhci_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_i2s_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+ .mask = PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_i2s = {
+ .name = "i2s",
+ .modes = pmx_i2s_modes,
+ .mode_count = ARRAY_SIZE(pmx_i2s_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart1_modes[] = {
+ {
+ .ids = ALL_MODES,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_uart1 = {
+ .name = "uart1",
+ .modes = pmx_uart1_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+ {
+ .ids = AUTO_EXP_MODE,
+ .mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
+ PMX_SSP_CS_MASK,
+ }, {
+ .ids = SMALL_PRINTERS_MODE,
+ .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+ PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_uart1_modem = {
+ .name = "uart1_modem",
+ .modes = pmx_uart1_modem_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_uart2_modes[] = {
+ {
+ .ids = ALL_MODES,
+ .mask = PMX_FIRDA_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_uart2 = {
+ .name = "uart2",
+ .modes = pmx_uart2_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart2_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_touchscreen_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE,
+ .mask = PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_touchscreen = {
+ .name = "touchscreen",
+ .modes = pmx_touchscreen_modes,
+ .mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_can_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
+ .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_can = {
+ .name = "can",
+ .modes = pmx_can_modes,
+ .mode_count = ARRAY_SIZE(pmx_can_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+ .mask = PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_sdhci_led = {
+ .name = "sdhci_led",
+ .modes = pmx_sdhci_led_modes,
+ .mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_pwm0_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+ .mask = PMX_UART0_MODEM_MASK,
+ }, {
+ .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_pwm0 = {
+ .name = "pwm0",
+ .modes = pmx_pwm0_modes,
+ .mode_count = ARRAY_SIZE(pmx_pwm0_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_pwm1_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+ .mask = PMX_UART0_MODEM_MASK,
+ }, {
+ .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_pwm1 = {
+ .name = "pwm1",
+ .modes = pmx_pwm1_modes,
+ .mode_count = ARRAY_SIZE(pmx_pwm1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_pwm2_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
+ .mask = PMX_SSP_CS_MASK,
+ }, {
+ .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_pwm2 = {
+ .name = "pwm2",
+ .modes = pmx_pwm2_modes,
+ .mode_count = ARRAY_SIZE(pmx_pwm2_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_pwm3_modes[] = {
+ {
+ .ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_pwm3 = {
+ .name = "pwm3",
+ .modes = pmx_pwm3_modes,
+ .mode_count = ARRAY_SIZE(pmx_pwm3_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_ssp1_modes[] = {
+ {
+ .ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_ssp1 = {
+ .name = "ssp1",
+ .modes = pmx_ssp1_modes,
+ .mode_count = ARRAY_SIZE(pmx_ssp1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_ssp2_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_ssp2 = {
+ .name = "ssp2",
+ .modes = pmx_ssp2_modes,
+ .mode_count = ARRAY_SIZE(pmx_ssp2_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_mii1_modes[] = {
+ {
+ .ids = AUTO_NET_MII_MODE,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear320_pmx_mii1 = {
+ .name = "mii1",
+ .modes = pmx_mii1_modes,
+ .mode_count = ARRAY_SIZE(pmx_mii1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_smii0_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_smii0 = {
+ .name = "smii0",
+ .modes = pmx_smii0_modes,
+ .mode_count = ARRAY_SIZE(pmx_smii0_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_smii1_modes[] = {
+ {
+ .ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear320_pmx_smii1 = {
+ .name = "smii1",
+ .modes = pmx_smii1_modes,
+ .mode_count = ARRAY_SIZE(pmx_smii1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_i2c1_modes[] = {
+ {
+ .ids = AUTO_EXP_MODE,
+ .mask = 0x0,
+ },
+};
+
+struct pmx_dev spear320_pmx_i2c1 = {
+ .name = "i2c1",
+ .modes = pmx_i2c1_modes,
+ .mode_count = ARRAY_SIZE(pmx_i2c1_modes),
+ .enb_on_reset = 1,
+};
+
+/* pmx driver structure */
+static struct pmx_driver pmx_driver = {
+ .mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
+ .mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
+};
+
+/* spear3xx shared irq */
+static struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = SPEAR320_VIRQ_EMI,
+ .status_mask = SPEAR320_EMI_IRQ_MASK,
+ .clear_mask = SPEAR320_EMI_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_CLCD,
+ .status_mask = SPEAR320_CLCD_IRQ_MASK,
+ .clear_mask = SPEAR320_CLCD_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_SPP,
+ .status_mask = SPEAR320_SPP_IRQ_MASK,
+ .clear_mask = SPEAR320_SPP_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras1 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK,
+ .clear_reg = SPEAR320_INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
+static struct shirq_dev_config shirq_ras3_config[] = {
+ {
+ .virq = SPEAR320_VIRQ_PLGPIO,
+ .enb_mask = SPEAR320_GPIO_IRQ_MASK,
+ .status_mask = SPEAR320_GPIO_IRQ_MASK,
+ .clear_mask = SPEAR320_GPIO_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_I2S_PLAY,
+ .enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+ .status_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+ .clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_I2S_REC,
+ .enb_mask = SPEAR320_I2S_REC_IRQ_MASK,
+ .status_mask = SPEAR320_I2S_REC_IRQ_MASK,
+ .clear_mask = SPEAR320_I2S_REC_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_ras3 = {
+ .irq = SPEAR3XX_IRQ_GEN_RAS_3,
+ .dev_config = shirq_ras3_config,
+ .dev_count = ARRAY_SIZE(shirq_ras3_config),
+ .regs = {
+ .enb_reg = SPEAR320_INT_ENB_MASK_REG,
+ .reset_to_enb = 1,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK,
+ .clear_reg = SPEAR320_INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+ {
+ .virq = SPEAR320_VIRQ_CANU,
+ .status_mask = SPEAR320_CAN_U_IRQ_MASK,
+ .clear_mask = SPEAR320_CAN_U_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_CANL,
+ .status_mask = SPEAR320_CAN_L_IRQ_MASK,
+ .clear_mask = SPEAR320_CAN_L_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_UART1,
+ .status_mask = SPEAR320_UART1_IRQ_MASK,
+ .clear_mask = SPEAR320_UART1_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_UART2,
+ .status_mask = SPEAR320_UART2_IRQ_MASK,
+ .clear_mask = SPEAR320_UART2_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_SSP1,
+ .status_mask = SPEAR320_SSP1_IRQ_MASK,
+ .clear_mask = SPEAR320_SSP1_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_SSP2,
+ .status_mask = SPEAR320_SSP2_IRQ_MASK,
+ .clear_mask = SPEAR320_SSP2_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_SMII0,
+ .status_mask = SPEAR320_SMII0_IRQ_MASK,
+ .clear_mask = SPEAR320_SMII0_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_MII1_SMII1,
+ .status_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
+ .clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_WAKEUP_SMII0,
+ .status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
+ .clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1,
+ .status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
+ .clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
+ }, {
+ .virq = SPEAR320_VIRQ_I2C1,
+ .status_mask = SPEAR320_I2C1_IRQ_MASK,
+ .clear_mask = SPEAR320_I2C1_IRQ_MASK,
+ },
+};
+
+static struct spear_shirq shirq_intrcomm_ras = {
+ .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
+ .dev_config = shirq_intrcomm_ras_config,
+ .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = SPEAR320_INT_STS_MASK_REG,
+ .status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK,
+ .clear_reg = SPEAR320_INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
+/* Add spear320 specific devices here */
+
+/* spear320 routines */
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+ u8 pmx_dev_count)
+{
+ void __iomem *base;
+ int ret = 0;
+
+ /* call spear3xx family common init function */
+ spear3xx_init();
+
+ /* shared irq registration */
+ base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K);
+ if (base) {
+ /* shirq 1 */
+ shirq_ras1.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+ /* shirq 3 */
+ shirq_ras3.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras3);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+ /* shirq 4 */
+ shirq_intrcomm_ras.regs.base = base;
+ ret = spear_shirq_register(&shirq_intrcomm_ras);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 4\n");
+ }
+
+ /* pmx initialization */
+ pmx_driver.base = base;
+ pmx_driver.mode = pmx_mode;
+ pmx_driver.devs = pmx_devs;
+ pmx_driver.devs_count = pmx_dev_count;
+
+ ret = pmx_register(&pmx_driver);
+ if (ret)
+ printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
+ ret);
+}
diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c
new file mode 100644
index 00000000..a12b3539
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear320_evb.c
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-spear3xx/spear320_evb.c
+ *
+ * SPEAr320 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* padmux devices to enable */
+static struct pmx_dev *pmx_devs[] = {
+ /* spear3xx specific devices */
+ &spear3xx_pmx_i2c,
+ &spear3xx_pmx_ssp,
+ &spear3xx_pmx_mii,
+ &spear3xx_pmx_uart0,
+
+ /* spear320 specific devices */
+ &spear320_pmx_fsmc,
+ &spear320_pmx_sdhci,
+ &spear320_pmx_i2s,
+ &spear320_pmx_uart1,
+ &spear320_pmx_uart2,
+ &spear320_pmx_can,
+ &spear320_pmx_pwm0,
+ &spear320_pmx_pwm1,
+ &spear320_pmx_pwm2,
+ &spear320_pmx_mii1,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+ /* spear3xx specific devices */
+ &spear3xx_gpio_device,
+ &spear3xx_uart_device,
+
+ /* spear320 specific devices */
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+ /* spear3xx specific devices */
+
+ /* spear320 specific devices */
+};
+
+static void __init spear320_evb_init(void)
+{
+ unsigned int i;
+
+ /* call spear320 machine init function */
+ spear320_init(&spear320_auto_net_mii_mode, pmx_devs,
+ ARRAY_SIZE(pmx_devs));
+
+ /* Add Platform Devices */
+ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+ /* Add Amba Devices */
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR320, "ST-SPEAR320-EVB")
+ .boot_params = 0x00000100,
+ .map_io = spear3xx_map_io,
+ .init_irq = spear3xx_init_irq,
+ .timer = &spear3xx_timer,
+ .init_machine = spear320_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
new file mode 100644
index 00000000..10af45da
--- /dev/null
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -0,0 +1,557 @@
+/*
+ * arch/arm/mach-spear3xx/spear3xx.c
+ *
+ * SPEAr3XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* Add spear3xx machines common devices here */
+/* gpio device registration */
+static struct pl061_platform_data gpio_plat_data = {
+ .gpio_base = 0,
+ .irq_base = SPEAR3XX_GPIO_INT_BASE,
+};
+
+struct amba_device spear3xx_gpio_device = {
+ .dev = {
+ .init_name = "gpio",
+ .platform_data = &gpio_plat_data,
+ },
+ .res = {
+ .start = SPEAR3XX_ICM3_GPIO_BASE,
+ .end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
+};
+
+/* uart device registration */
+struct amba_device spear3xx_uart_device = {
+ .dev = {
+ .init_name = "uart",
+ },
+ .res = {
+ .start = SPEAR3XX_ICM1_UART_BASE,
+ .end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
+};
+
+/* Do spear3xx familiy common initialization part here */
+void __init spear3xx_init(void)
+{
+ /* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear3xx_init_irq(void)
+{
+ vic_init((void __iomem *)VA_SPEAR3XX_ML1_VIC_BASE, 0, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+struct map_desc spear3xx_io_desc[] __initdata = {
+ {
+ .virtual = VA_SPEAR3XX_ICM1_UART_BASE,
+ .pfn = __phys_to_pfn(SPEAR3XX_ICM1_UART_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR3XX_ML1_VIC_BASE,
+ .pfn = __phys_to_pfn(SPEAR3XX_ML1_VIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR3XX_ICM3_SYS_CTRL_BASE,
+ .pfn = __phys_to_pfn(SPEAR3XX_ICM3_SYS_CTRL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR3XX_ICM3_MISC_REG_BASE,
+ .pfn = __phys_to_pfn(SPEAR3XX_ICM3_MISC_REG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear3xx_map_io(void)
+{
+ iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
+
+ /* This will initialize clock framework */
+ spear3xx_clk_init();
+}
+
+/* pad multiplexing support */
+/* devices */
+static struct pmx_dev_mode pmx_firda_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_FIRDA_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_firda = {
+ .name = "firda",
+ .modes = pmx_firda_modes,
+ .mode_count = ARRAY_SIZE(pmx_firda_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_i2c_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_I2C_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_i2c = {
+ .name = "i2c",
+ .modes = pmx_i2c_modes,
+ .mode_count = ARRAY_SIZE(pmx_i2c_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_ssp_cs = {
+ .name = "ssp_chip_selects",
+ .modes = pmx_ssp_cs_modes,
+ .mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_ssp_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_SSP_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_ssp = {
+ .name = "ssp",
+ .modes = pmx_ssp_modes,
+ .mode_count = ARRAY_SIZE(pmx_ssp_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_mii_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_mii = {
+ .name = "mii",
+ .modes = pmx_mii_modes,
+ .mode_count = ARRAY_SIZE(pmx_mii_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN0_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin0 = {
+ .name = "gpio_pin0",
+ .modes = pmx_gpio_pin0_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN1_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin1 = {
+ .name = "gpio_pin1",
+ .modes = pmx_gpio_pin1_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN2_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin2 = {
+ .name = "gpio_pin2",
+ .modes = pmx_gpio_pin2_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN3_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin3 = {
+ .name = "gpio_pin3",
+ .modes = pmx_gpio_pin3_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN4_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin4 = {
+ .name = "gpio_pin4",
+ .modes = pmx_gpio_pin4_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_GPIO_PIN5_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_gpio_pin5 = {
+ .name = "gpio_pin5",
+ .modes = pmx_gpio_pin5_modes,
+ .mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_uart0_modem = {
+ .name = "uart0_modem",
+ .modes = pmx_uart0_modem_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_uart0_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_UART0_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_uart0 = {
+ .name = "uart0",
+ .modes = pmx_uart0_modes,
+ .mode_count = ARRAY_SIZE(pmx_uart0_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_timer_3_4 = {
+ .name = "timer_3_4",
+ .modes = pmx_timer_3_4_modes,
+ .mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
+ .enb_on_reset = 0,
+};
+
+static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+ {
+ .ids = 0xffffffff,
+ .mask = PMX_TIMER_1_2_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_timer_1_2 = {
+ .name = "timer_1_2",
+ .modes = pmx_timer_1_2_modes,
+ .mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
+ .enb_on_reset = 0,
+};
+
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+/* plgpios devices */
+static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_FIRDA_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_0_1 = {
+ .name = "plgpio 0 and 1",
+ .modes = pmx_plgpio_0_1_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_UART0_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_2_3 = {
+ .name = "plgpio 2 and 3",
+ .modes = pmx_plgpio_2_3_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_I2C_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_4_5 = {
+ .name = "plgpio 4 and 5",
+ .modes = pmx_plgpio_4_5_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_SSP_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_6_9 = {
+ .name = "plgpio 6 to 9",
+ .modes = pmx_plgpio_6_9_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_MII_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_10_27 = {
+ .name = "plgpio 10 to 27",
+ .modes = pmx_plgpio_10_27_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN0_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_28 = {
+ .name = "plgpio 28",
+ .modes = pmx_plgpio_28_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN1_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_29 = {
+ .name = "plgpio 29",
+ .modes = pmx_plgpio_29_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN2_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_30 = {
+ .name = "plgpio 30",
+ .modes = pmx_plgpio_30_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN3_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_31 = {
+ .name = "plgpio 31",
+ .modes = pmx_plgpio_31_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN4_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_32 = {
+ .name = "plgpio 32",
+ .modes = pmx_plgpio_32_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_GPIO_PIN5_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_33 = {
+ .name = "plgpio 33",
+ .modes = pmx_plgpio_33_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_SSP_CS_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_34_36 = {
+ .name = "plgpio 34 to 36",
+ .modes = pmx_plgpio_34_36_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_UART0_MODEM_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_37_42 = {
+ .name = "plgpio 37 to 42",
+ .modes = pmx_plgpio_37_42_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_TIMER_1_2_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48 = {
+ .name = "plgpio 43, 44, 47 and 48",
+ .modes = pmx_plgpio_43_44_47_48_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
+ .enb_on_reset = 1,
+};
+
+static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+ {
+ .ids = 0x00,
+ .mask = PMX_TIMER_3_4_MASK,
+ },
+};
+
+struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50 = {
+ .name = "plgpio 45, 46, 49 and 50",
+ .modes = pmx_plgpio_45_46_49_50_modes,
+ .mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
+ .enb_on_reset = 1,
+};
+#endif /* CONFIG_MACH_SPEAR310 || CONFIG_MACH_SPEAR320 */
+
+static void __init spear3xx_timer_init(void)
+{
+ char pclk_name[] = "pll3_48m_clk";
+ struct clk *gpt_clk, *pclk;
+
+ /* get the system timer clock */
+ gpt_clk = clk_get_sys("gpt0", NULL);
+ if (IS_ERR(gpt_clk)) {
+ pr_err("%s:couldn't get clk for gpt\n", __func__);
+ BUG();
+ }
+
+ /* get the suitable parent clock for timer*/
+ pclk = clk_get(NULL, pclk_name);
+ if (IS_ERR(pclk)) {
+ pr_err("%s:couldn't get %s as parent for gpt\n",
+ __func__, pclk_name);
+ BUG();
+ }
+
+ clk_set_parent(gpt_clk, pclk);
+ clk_put(gpt_clk);
+ clk_put(pclk);
+
+ spear_setup_timer();
+}
+
+struct sys_timer spear3xx_timer = {
+ .init = spear3xx_timer_init,
+};
diff --git a/arch/arm/mach-spear6xx/Kconfig b/arch/arm/mach-spear6xx/Kconfig
new file mode 100644
index 00000000..ff4ae5ba
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Kconfig
@@ -0,0 +1,21 @@
+#
+# SPEAr6XX Machine configuration file
+#
+
+if ARCH_SPEAR6XX
+
+menu "SPEAr6xx Implementations"
+config BOARD_SPEAR600_EVB
+ bool "SPEAr600 Evaluation Board"
+ select MACH_SPEAR600
+ help
+ Supports ST SPEAr600 Evaluation Board
+
+endmenu
+
+config MACH_SPEAR600
+ bool "SPEAr600"
+ help
+ Supports ST SPEAr600 Machine
+
+endif #ARCH_SPEAR6XX
diff --git a/arch/arm/mach-spear6xx/Makefile b/arch/arm/mach-spear6xx/Makefile
new file mode 100644
index 00000000..cc1a4d82
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for SPEAr6XX machine series
+#
+
+# common files
+obj-y += clock.o spear6xx.o
+
+# spear600 specific files
+obj-$(CONFIG_MACH_SPEAR600) += spear600.o
+
+# spear600 boards files
+obj-$(CONFIG_BOARD_SPEAR600_EVB) += spear600_evb.o
diff --git a/arch/arm/mach-spear6xx/Makefile.boot b/arch/arm/mach-spear6xx/Makefile.boot
new file mode 100644
index 00000000..7a1f3c0e
--- /dev/null
+++ b/arch/arm/mach-spear6xx/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c
new file mode 100644
index 00000000..ac70e0d8
--- /dev/null
+++ b/arch/arm/mach-spear6xx/clock.c
@@ -0,0 +1,682 @@
+/*
+ * arch/arm/mach-spear6xx/clock.c
+ *
+ * SPEAr6xx machines clock framework source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <plat/clock.h>
+#include <mach/misc_regs.h>
+
+/* root clks */
+/* 32 KHz oscillator clock */
+static struct clk osc_32k_clk = {
+ .flags = ALWAYS_ENABLED,
+ .rate = 32000,
+};
+
+/* 30 MHz oscillator clock */
+static struct clk osc_30m_clk = {
+ .flags = ALWAYS_ENABLED,
+ .rate = 30000000,
+};
+
+/* clock derived from 32 KHz osc clk */
+/* rtc clock */
+static struct clk rtc_clk = {
+ .pclk = &osc_32k_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = RTC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from 30 MHz osc clk */
+/* pll masks structure */
+static struct pll_clk_masks pll1_masks = {
+ .mode_mask = PLL_MODE_MASK,
+ .mode_shift = PLL_MODE_SHIFT,
+ .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK,
+ .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT,
+ .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK,
+ .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT,
+ .div_p_mask = PLL_DIV_P_MASK,
+ .div_p_shift = PLL_DIV_P_SHIFT,
+ .div_n_mask = PLL_DIV_N_MASK,
+ .div_n_shift = PLL_DIV_N_SHIFT,
+};
+
+/* pll1 configuration structure */
+static struct pll_clk_config pll1_config = {
+ .mode_reg = PLL1_CTR,
+ .cfg_reg = PLL1_FRQ,
+ .masks = &pll1_masks,
+};
+
+/* pll rate configuration table, in ascending order of rates */
+struct pll_rate_tbl pll_rtbl[] = {
+ {.mode = 0, .m = 0x85, .n = 0x0C, .p = 0x1}, /* 266 MHz */
+ {.mode = 0, .m = 0xA6, .n = 0x0C, .p = 0x1}, /* 332 MHz */
+};
+
+/* PLL1 clock */
+static struct clk pll1_clk = {
+ .flags = ENABLED_ON_INIT,
+ .pclk = &osc_30m_clk,
+ .en_reg = PLL1_CTR,
+ .en_reg_bit = PLL_ENABLE,
+ .calc_rate = &pll_calc_rate,
+ .recalc = &pll_clk_recalc,
+ .set_rate = &pll_clk_set_rate,
+ .rate_config = {pll_rtbl, ARRAY_SIZE(pll_rtbl), 1},
+ .private_data = &pll1_config,
+};
+
+/* PLL3 48 MHz clock */
+static struct clk pll3_48m_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &osc_30m_clk,
+ .rate = 48000000,
+};
+
+/* watch dog timer clock */
+static struct clk wdt_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &osc_30m_clk,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from pll1 clk */
+/* cpu clock */
+static struct clk cpu_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .recalc = &follow_parent,
+};
+
+/* ahb masks structure */
+static struct bus_clk_masks ahb_masks = {
+ .mask = PLL_HCLK_RATIO_MASK,
+ .shift = PLL_HCLK_RATIO_SHIFT,
+};
+
+/* ahb configuration structure */
+static struct bus_clk_config ahb_config = {
+ .reg = CORE_CLK_CFG,
+ .masks = &ahb_masks,
+};
+
+/* ahb rate configuration table, in ascending order of rates */
+struct bus_rate_tbl bus_rtbl[] = {
+ {.div = 3}, /* == parent divided by 4 */
+ {.div = 2}, /* == parent divided by 3 */
+ {.div = 1}, /* == parent divided by 2 */
+ {.div = 0}, /* == parent divided by 1 */
+};
+
+/* ahb clock */
+static struct clk ahb_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &bus_calc_rate,
+ .recalc = &bus_clk_recalc,
+ .set_rate = &bus_clk_set_rate,
+ .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
+ .private_data = &ahb_config,
+};
+
+/* auxiliary synthesizers masks */
+static struct aux_clk_masks aux_masks = {
+ .eq_sel_mask = AUX_EQ_SEL_MASK,
+ .eq_sel_shift = AUX_EQ_SEL_SHIFT,
+ .eq1_mask = AUX_EQ1_SEL,
+ .eq2_mask = AUX_EQ2_SEL,
+ .xscale_sel_mask = AUX_XSCALE_MASK,
+ .xscale_sel_shift = AUX_XSCALE_SHIFT,
+ .yscale_sel_mask = AUX_YSCALE_MASK,
+ .yscale_sel_shift = AUX_YSCALE_SHIFT,
+};
+
+/* uart configurations */
+static struct aux_clk_config uart_synth_config = {
+ .synth_reg = UART_CLK_SYNT,
+ .masks = &aux_masks,
+};
+
+/* aux rate configuration table, in ascending order of rates */
+struct aux_rate_tbl aux_rtbl[] = {
+ /* For PLL1 = 332 MHz */
+ {.xscale = 1, .yscale = 8, .eq = 1}, /* 41.5 MHz */
+ {.xscale = 1, .yscale = 4, .eq = 1}, /* 83 MHz */
+ {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */
+};
+
+/* uart synth clock */
+static struct clk uart_synth_clk = {
+ .en_reg = UART_CLK_SYNT,
+ .en_reg_bit = AUX_SYNT_ENB,
+ .pclk = &pll1_clk,
+ .calc_rate = &aux_calc_rate,
+ .recalc = &aux_clk_recalc,
+ .set_rate = &aux_clk_set_rate,
+ .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+ .private_data = &uart_synth_config,
+};
+
+/* uart parents */
+static struct pclk_info uart_pclk_info[] = {
+ {
+ .pclk = &uart_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* uart parent select structure */
+static struct pclk_sel uart_pclk_sel = {
+ .pclk_info = uart_pclk_info,
+ .pclk_count = ARRAY_SIZE(uart_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = UART_CLK_MASK,
+};
+
+/* uart0 clock */
+static struct clk uart0_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = UART0_CLK_ENB,
+ .pclk_sel = &uart_pclk_sel,
+ .pclk_sel_shift = UART_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* uart1 clock */
+static struct clk uart1_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = UART1_CLK_ENB,
+ .pclk_sel = &uart_pclk_sel,
+ .pclk_sel_shift = UART_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* firda configurations */
+static struct aux_clk_config firda_synth_config = {
+ .synth_reg = FIRDA_CLK_SYNT,
+ .masks = &aux_masks,
+};
+
+/* firda synth clock */
+static struct clk firda_synth_clk = {
+ .en_reg = FIRDA_CLK_SYNT,
+ .en_reg_bit = AUX_SYNT_ENB,
+ .pclk = &pll1_clk,
+ .calc_rate = &aux_calc_rate,
+ .recalc = &aux_clk_recalc,
+ .set_rate = &aux_clk_set_rate,
+ .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+ .private_data = &firda_synth_config,
+};
+
+/* firda parents */
+static struct pclk_info firda_pclk_info[] = {
+ {
+ .pclk = &firda_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* firda parent select structure */
+static struct pclk_sel firda_pclk_sel = {
+ .pclk_info = firda_pclk_info,
+ .pclk_count = ARRAY_SIZE(firda_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = FIRDA_CLK_MASK,
+};
+
+/* firda clock */
+static struct clk firda_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = FIRDA_CLK_ENB,
+ .pclk_sel = &firda_pclk_sel,
+ .pclk_sel_shift = FIRDA_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* clcd configurations */
+static struct aux_clk_config clcd_synth_config = {
+ .synth_reg = CLCD_CLK_SYNT,
+ .masks = &aux_masks,
+};
+
+/* firda synth clock */
+static struct clk clcd_synth_clk = {
+ .en_reg = CLCD_CLK_SYNT,
+ .en_reg_bit = AUX_SYNT_ENB,
+ .pclk = &pll1_clk,
+ .calc_rate = &aux_calc_rate,
+ .recalc = &aux_clk_recalc,
+ .set_rate = &aux_clk_set_rate,
+ .rate_config = {aux_rtbl, ARRAY_SIZE(aux_rtbl), 2},
+ .private_data = &clcd_synth_config,
+};
+
+/* clcd parents */
+static struct pclk_info clcd_pclk_info[] = {
+ {
+ .pclk = &clcd_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* clcd parent select structure */
+static struct pclk_sel clcd_pclk_sel = {
+ .pclk_info = clcd_pclk_info,
+ .pclk_count = ARRAY_SIZE(clcd_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = CLCD_CLK_MASK,
+};
+
+/* clcd clock */
+static struct clk clcd_clk = {
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = CLCD_CLK_ENB,
+ .pclk_sel = &clcd_pclk_sel,
+ .pclk_sel_shift = CLCD_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt synthesizer masks */
+static struct gpt_clk_masks gpt_masks = {
+ .mscale_sel_mask = GPT_MSCALE_MASK,
+ .mscale_sel_shift = GPT_MSCALE_SHIFT,
+ .nscale_sel_mask = GPT_NSCALE_MASK,
+ .nscale_sel_shift = GPT_NSCALE_SHIFT,
+};
+
+/* gpt rate configuration table, in ascending order of rates */
+struct gpt_rate_tbl gpt_rtbl[] = {
+ /* For pll1 = 332 MHz */
+ {.mscale = 4, .nscale = 0}, /* 41.5 MHz */
+ {.mscale = 2, .nscale = 0}, /* 55.3 MHz */
+ {.mscale = 1, .nscale = 0}, /* 83 MHz */
+};
+
+/* gpt0 synth clk config*/
+static struct gpt_clk_config gpt0_synth_config = {
+ .synth_reg = PRSC1_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt synth clock */
+static struct clk gpt0_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt0_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt0_pclk_info[] = {
+ {
+ .pclk = &gpt0_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt0_pclk_sel = {
+ .pclk_info = gpt0_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt0 ARM1 subsystem timer clock */
+static struct clk gpt0_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk_sel = &gpt0_pclk_sel,
+ .pclk_sel_shift = GPT0_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+
+/* Note: gpt0 and gpt1 share same parent clocks */
+/* gpt parent select structure */
+static struct pclk_sel gpt1_pclk_sel = {
+ .pclk_info = gpt0_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt0_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt1 timer clock */
+static struct clk gpt1_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk_sel = &gpt1_pclk_sel,
+ .pclk_sel_shift = GPT1_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt2 synth clk config*/
+static struct gpt_clk_config gpt2_synth_config = {
+ .synth_reg = PRSC2_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt synth clock */
+static struct clk gpt2_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt2_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt2_pclk_info[] = {
+ {
+ .pclk = &gpt2_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt2_pclk_sel = {
+ .pclk_info = gpt2_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt2_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt2 timer clock */
+static struct clk gpt2_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk_sel = &gpt2_pclk_sel,
+ .pclk_sel_shift = GPT2_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* gpt3 synth clk config*/
+static struct gpt_clk_config gpt3_synth_config = {
+ .synth_reg = PRSC3_CLK_CFG,
+ .masks = &gpt_masks,
+};
+
+/* gpt synth clock */
+static struct clk gpt3_synth_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &pll1_clk,
+ .calc_rate = &gpt_calc_rate,
+ .recalc = &gpt_clk_recalc,
+ .set_rate = &gpt_clk_set_rate,
+ .rate_config = {gpt_rtbl, ARRAY_SIZE(gpt_rtbl), 2},
+ .private_data = &gpt3_synth_config,
+};
+
+/* gpt parents */
+static struct pclk_info gpt3_pclk_info[] = {
+ {
+ .pclk = &gpt3_synth_clk,
+ .pclk_val = AUX_CLK_PLL1_VAL,
+ }, {
+ .pclk = &pll3_48m_clk,
+ .pclk_val = AUX_CLK_PLL3_VAL,
+ },
+};
+
+/* gpt parent select structure */
+static struct pclk_sel gpt3_pclk_sel = {
+ .pclk_info = gpt3_pclk_info,
+ .pclk_count = ARRAY_SIZE(gpt3_pclk_info),
+ .pclk_sel_reg = PERIP_CLK_CFG,
+ .pclk_sel_mask = GPT_CLK_MASK,
+};
+
+/* gpt3 timer clock */
+static struct clk gpt3_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk_sel = &gpt3_pclk_sel,
+ .pclk_sel_shift = GPT3_CLK_SHIFT,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from pll3 clk */
+/* usbh0 clock */
+static struct clk usbh0_clk = {
+ .pclk = &pll3_48m_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = USBH0_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* usbh1 clock */
+static struct clk usbh1_clk = {
+ .pclk = &pll3_48m_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = USBH1_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* usbd clock */
+static struct clk usbd_clk = {
+ .pclk = &pll3_48m_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = USBD_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from ahb clk */
+/* apb masks structure */
+static struct bus_clk_masks apb_masks = {
+ .mask = HCLK_PCLK_RATIO_MASK,
+ .shift = HCLK_PCLK_RATIO_SHIFT,
+};
+
+/* apb configuration structure */
+static struct bus_clk_config apb_config = {
+ .reg = CORE_CLK_CFG,
+ .masks = &apb_masks,
+};
+
+/* apb clock */
+static struct clk apb_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &ahb_clk,
+ .calc_rate = &bus_calc_rate,
+ .recalc = &bus_clk_recalc,
+ .set_rate = &bus_clk_set_rate,
+ .rate_config = {bus_rtbl, ARRAY_SIZE(bus_rtbl), 2},
+ .private_data = &apb_config,
+};
+
+/* i2c clock */
+static struct clk i2c_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = I2C_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* dma clock */
+static struct clk dma_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = DMA_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* jpeg clock */
+static struct clk jpeg_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = JPEG_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* gmac clock */
+static struct clk gmac_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GMAC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* smi clock */
+static struct clk smi_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SMI_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* fsmc clock */
+static struct clk fsmc_clk = {
+ .pclk = &ahb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = FSMC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* clock derived from apb clk */
+/* adc clock */
+static struct clk adc_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = ADC_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* ssp0 clock */
+static struct clk ssp0_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SSP0_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* ssp1 clock */
+static struct clk ssp1_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SSP1_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* ssp2 clock */
+static struct clk ssp2_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = SSP2_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* gpio0 ARM subsystem clock */
+static struct clk gpio0_clk = {
+ .flags = ALWAYS_ENABLED,
+ .pclk = &apb_clk,
+ .recalc = &follow_parent,
+};
+
+/* gpio1 clock */
+static struct clk gpio1_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GPIO1_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+/* gpio2 clock */
+static struct clk gpio2_clk = {
+ .pclk = &apb_clk,
+ .en_reg = PERIP1_CLK_ENB,
+ .en_reg_bit = GPIO2_CLK_ENB,
+ .recalc = &follow_parent,
+};
+
+static struct clk dummy_apb_pclk;
+
+/* array of all spear 6xx clock lookups */
+static struct clk_lookup spear_clk_lookups[] = {
+ { .con_id = "apb_pclk", .clk = &dummy_apb_pclk},
+ /* root clks */
+ { .con_id = "osc_32k_clk", .clk = &osc_32k_clk},
+ { .con_id = "osc_30m_clk", .clk = &osc_30m_clk},
+ /* clock derived from 32 KHz os clk */
+ { .dev_id = "rtc-spear", .clk = &rtc_clk},
+ /* clock derived from 30 MHz os clk */
+ { .con_id = "pll1_clk", .clk = &pll1_clk},
+ { .con_id = "pll3_48m_clk", .clk = &pll3_48m_clk},
+ { .dev_id = "wdt", .clk = &wdt_clk},
+ /* clock derived from pll1 clk */
+ { .con_id = "cpu_clk", .clk = &cpu_clk},
+ { .con_id = "ahb_clk", .clk = &ahb_clk},
+ { .con_id = "uart_synth_clk", .clk = &uart_synth_clk},
+ { .con_id = "firda_synth_clk", .clk = &firda_synth_clk},
+ { .con_id = "clcd_synth_clk", .clk = &clcd_synth_clk},
+ { .con_id = "gpt0_synth_clk", .clk = &gpt0_synth_clk},
+ { .con_id = "gpt2_synth_clk", .clk = &gpt2_synth_clk},
+ { .con_id = "gpt3_synth_clk", .clk = &gpt3_synth_clk},
+ { .dev_id = "uart0", .clk = &uart0_clk},
+ { .dev_id = "uart1", .clk = &uart1_clk},
+ { .dev_id = "firda", .clk = &firda_clk},
+ { .dev_id = "clcd", .clk = &clcd_clk},
+ { .dev_id = "gpt0", .clk = &gpt0_clk},
+ { .dev_id = "gpt1", .clk = &gpt1_clk},
+ { .dev_id = "gpt2", .clk = &gpt2_clk},
+ { .dev_id = "gpt3", .clk = &gpt3_clk},
+ /* clock derived from pll3 clk */
+ { .dev_id = "designware_udc", .clk = &usbd_clk},
+ { .con_id = "usbh.0_clk", .clk = &usbh0_clk},
+ { .con_id = "usbh.1_clk", .clk = &usbh1_clk},
+ /* clock derived from ahb clk */
+ { .con_id = "apb_clk", .clk = &apb_clk},
+ { .dev_id = "i2c_designware.0", .clk = &i2c_clk},
+ { .dev_id = "dma", .clk = &dma_clk},
+ { .dev_id = "jpeg", .clk = &jpeg_clk},
+ { .dev_id = "gmac", .clk = &gmac_clk},
+ { .dev_id = "smi", .clk = &smi_clk},
+ { .con_id = "fsmc", .clk = &fsmc_clk},
+ /* clock derived from apb clk */
+ { .dev_id = "adc", .clk = &adc_clk},
+ { .dev_id = "ssp-pl022.0", .clk = &ssp0_clk},
+ { .dev_id = "ssp-pl022.1", .clk = &ssp1_clk},
+ { .dev_id = "ssp-pl022.2", .clk = &ssp2_clk},
+ { .dev_id = "gpio0", .clk = &gpio0_clk},
+ { .dev_id = "gpio1", .clk = &gpio1_clk},
+ { .dev_id = "gpio2", .clk = &gpio2_clk},
+};
+
+void __init spear6xx_clk_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
+ clk_register(&spear_clk_lookups[i]);
+
+ clk_init();
+}
diff --git a/arch/arm/mach-spear6xx/include/mach/clkdev.h b/arch/arm/mach-spear6xx/include/mach/clkdev.h
new file mode 100644
index 00000000..05676bf4
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/clkdev.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+#include <plat/clkdev.h>
+
+#endif /* __MACH_CLKDEV_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/debug-macro.S b/arch/arm/mach-spear6xx/include/mach/debug-macro.S
new file mode 100644
index 00000000..0f3ea39e
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/debug-macro.S
@@ -0,0 +1,14 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-spear6xx/include/mach/entry-macro.S b/arch/arm/mach-spear6xx/include/mach/entry-macro.S
new file mode 100644
index 00000000..8a0b0ed7
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/entry-macro.S
@@ -0,0 +1,54 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/hardware/vic.h>
+#include <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =VA_SPEAR6XX_CPU_VIC_PRI_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status
+ mov \irqnr, #0
+ teq \irqstat, #0
+ bne 1001f
+ ldr \base, =VA_SPEAR6XX_CPU_VIC_SEC_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get status
+ teq \irqstat, #0
+ beq 1002f @ this will set/reset
+ @ zero register
+ mov \irqnr, #32
+1001:
+ /*
+ * Following code will find bit position of least significang
+ * bit set in irqstat, using following equation
+ * least significant bit set in n = (n & ~(n-1))
+ */
+ sub \tmp, \irqstat, #1 @ tmp = irqstat - 1
+ mvn \tmp, \tmp @ tmp = ~tmp
+ and \irqstat, \irqstat, \tmp @ irqstat &= tmp
+ /* Now, irqstat is = bit no. of 1st bit set in vic irq status */
+ clz \tmp, \irqstat @ tmp = leading zeros
+
+ rsb \tmp, \tmp, #0x1F @ tmp = 32 - tmp - 1
+ add \irqnr, \irqnr, \tmp
+
+1002: /* EQ will be set if no irqs pending */
+ .endm
diff --git a/arch/arm/mach-spear6xx/include/mach/generic.h b/arch/arm/mach-spear6xx/include/mach/generic.h
new file mode 100644
index 00000000..183f0238
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/generic.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/generic.h
+ *
+ * SPEAr6XX machine family specific generic header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GENERIC_H
+#define __MACH_GENERIC_H
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+/*
+ * Each GPT has 2 timer channels
+ * Following GPT channels will be used as clock source and clockevent
+ */
+#define SPEAR_GPT0_BASE SPEAR6XX_CPU_TMR_BASE
+#define SPEAR_GPT0_CHAN0_IRQ IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ IRQ_CPU_GPT1_2
+
+/* Add spear6xx family device structure declarations here */
+extern struct amba_device gpio_device[];
+extern struct amba_device uart_device[];
+extern struct sys_timer spear6xx_timer;
+
+/* Add spear6xx family function declarations here */
+void __init spear_setup_timer(void);
+void __init spear6xx_map_io(void);
+void __init spear6xx_init_irq(void);
+void __init spear6xx_init(void);
+void __init spear600_init(void);
+void __init spear6xx_clk_init(void);
+
+/* Add spear600 machine device structure declarations here */
+
+#endif /* __MACH_GENERIC_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/gpio.h b/arch/arm/mach-spear6xx/include/mach/gpio.h
new file mode 100644
index 00000000..3a789dbb
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/gpio.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/gpio.h
+ *
+ * GPIO macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_GPIO_H
+#define __MACH_GPIO_H
+
+#include <plat/gpio.h>
+
+#endif /* __MACH_GPIO_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/hardware.h b/arch/arm/mach-spear6xx/include/mach/hardware.h
new file mode 100644
index 00000000..0b3f96ae
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/hardware.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/hardware.h
+ *
+ * Hardware definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#include <plat/hardware.h>
+#include <mach/spear.h>
+
+/* Vitual to physical translation of statically mapped space */
+#define IO_ADDRESS(x) (x | 0xF0000000)
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/io.h b/arch/arm/mach-spear6xx/include/mach/io.h
new file mode 100644
index 00000000..fb7c106c
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/io.h
+ *
+ * IO definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#include <plat/io.h>
+
+#endif /* __MACH_IO_H */
+
diff --git a/arch/arm/mach-spear6xx/include/mach/irqs.h b/arch/arm/mach-spear6xx/include/mach/irqs.h
new file mode 100644
index 00000000..8f214b03
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/irqs.h
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/irqs.h
+ *
+ * IRQ helper macros for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+/* IRQ definitions */
+/* VIC 1 */
+#define IRQ_INTRCOMM_SW_IRQ 0
+#define IRQ_INTRCOMM_CPU_1 1
+#define IRQ_INTRCOMM_CPU_2 2
+#define IRQ_INTRCOMM_RAS2A11_1 3
+#define IRQ_INTRCOMM_RAS2A11_2 4
+#define IRQ_INTRCOMM_RAS2A12_1 5
+#define IRQ_INTRCOMM_RAS2A12_2 6
+#define IRQ_GEN_RAS_0 7
+#define IRQ_GEN_RAS_1 8
+#define IRQ_GEN_RAS_2 9
+#define IRQ_GEN_RAS_3 10
+#define IRQ_GEN_RAS_4 11
+#define IRQ_GEN_RAS_5 12
+#define IRQ_GEN_RAS_6 13
+#define IRQ_GEN_RAS_7 14
+#define IRQ_GEN_RAS_8 15
+#define IRQ_CPU_GPT1_1 16
+#define IRQ_CPU_GPT1_2 17
+#define IRQ_LOCAL_GPIO 18
+#define IRQ_PLL_UNLOCK 19
+#define IRQ_JPEG 20
+#define IRQ_FSMC 21
+#define IRQ_IRDA 22
+#define IRQ_RESERVED 23
+#define IRQ_UART_0 24
+#define IRQ_UART_1 25
+#define IRQ_SSP_1 26
+#define IRQ_SSP_2 27
+#define IRQ_I2C 28
+#define IRQ_GEN_RAS_9 29
+#define IRQ_GEN_RAS_10 30
+#define IRQ_GEN_RAS_11 31
+
+/* VIC 2 */
+#define IRQ_APPL_GPT1_1 32
+#define IRQ_APPL_GPT1_2 33
+#define IRQ_APPL_GPT2_1 34
+#define IRQ_APPL_GPT2_2 35
+#define IRQ_APPL_GPIO 36
+#define IRQ_APPL_SSP 37
+#define IRQ_APPL_ADC 38
+#define IRQ_APPL_RESERVED 39
+#define IRQ_AHB_EXP_MASTER 40
+#define IRQ_DDR_CONTROLLER 41
+#define IRQ_BASIC_DMA 42
+#define IRQ_BASIC_RESERVED1 43
+#define IRQ_BASIC_SMI 44
+#define IRQ_BASIC_CLCD 45
+#define IRQ_EXP_AHB_1 46
+#define IRQ_EXP_AHB_2 47
+#define IRQ_BASIC_GPT1_1 48
+#define IRQ_BASIC_GPT1_2 49
+#define IRQ_BASIC_RTC 50
+#define IRQ_BASIC_GPIO 51
+#define IRQ_BASIC_WDT 52
+#define IRQ_BASIC_RESERVED 53
+#define IRQ_AHB_EXP_SLAVE 54
+#define IRQ_GMAC_1 55
+#define IRQ_GMAC_2 56
+#define IRQ_USB_DEV 57
+#define IRQ_USB_H_OHCI_0 58
+#define IRQ_USB_H_EHCI_0 59
+#define IRQ_USB_H_OHCI_1 60
+#define IRQ_USB_H_EHCI_1 61
+#define IRQ_EXP_AHB_3 62
+#define IRQ_EXP_AHB_4 63
+
+#define IRQ_VIC_END 64
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE IRQ_VIC_END
+#define SPEAR_GPIO0_INT_BASE SPEAR_GPIO_INT_BASE
+#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO0_INT_BASE + 8)
+#define SPEAR_GPIO2_INT_BASE (SPEAR_GPIO1_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END (SPEAR_GPIO2_INT_BASE + 8)
+#define VIRTUAL_IRQS (SPEAR_GPIO_INT_END - IRQ_VIC_END)
+#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS)
+
+#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/memory.h b/arch/arm/mach-spear6xx/include/mach/memory.h
new file mode 100644
index 00000000..781f088f
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/memory.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/memory.h
+ *
+ * Memory map for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#include <plat/memory.h>
+
+#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/misc_regs.h b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
new file mode 100644
index 00000000..68c20a00
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/misc_regs.h
@@ -0,0 +1,174 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/misc_regs.h
+ *
+ * Miscellaneous registers definitions for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MISC_REGS_H
+#define __MACH_MISC_REGS_H
+
+#include <mach/hardware.h>
+
+#define MISC_BASE IOMEM(VA_SPEAR6XX_ICM3_MISC_REG_BASE)
+
+#define SOC_CFG_CTR (MISC_BASE + 0x000)
+#define DIAG_CFG_CTR (MISC_BASE + 0x004)
+#define PLL1_CTR (MISC_BASE + 0x008)
+#define PLL1_FRQ (MISC_BASE + 0x00C)
+#define PLL1_MOD (MISC_BASE + 0x010)
+#define PLL2_CTR (MISC_BASE + 0x014)
+/* PLL_CTR register masks */
+#define PLL_ENABLE 2
+#define PLL_MODE_SHIFT 4
+#define PLL_MODE_MASK 0x3
+#define PLL_MODE_NORMAL 0
+#define PLL_MODE_FRACTION 1
+#define PLL_MODE_DITH_DSB 2
+#define PLL_MODE_DITH_SSB 3
+
+#define PLL2_FRQ (MISC_BASE + 0x018)
+/* PLL FRQ register masks */
+#define PLL_DIV_N_SHIFT 0
+#define PLL_DIV_N_MASK 0xFF
+#define PLL_DIV_P_SHIFT 8
+#define PLL_DIV_P_MASK 0x7
+#define PLL_NORM_FDBK_M_SHIFT 24
+#define PLL_NORM_FDBK_M_MASK 0xFF
+#define PLL_DITH_FDBK_M_SHIFT 16
+#define PLL_DITH_FDBK_M_MASK 0xFFFF
+
+#define PLL2_MOD (MISC_BASE + 0x01C)
+#define PLL_CLK_CFG (MISC_BASE + 0x020)
+#define CORE_CLK_CFG (MISC_BASE + 0x024)
+/* CORE CLK CFG register masks */
+#define PLL_HCLK_RATIO_SHIFT 10
+#define PLL_HCLK_RATIO_MASK 0x3
+#define HCLK_PCLK_RATIO_SHIFT 8
+#define HCLK_PCLK_RATIO_MASK 0x3
+
+#define PERIP_CLK_CFG (MISC_BASE + 0x028)
+/* PERIP_CLK_CFG register masks */
+#define CLCD_CLK_SHIFT 2
+#define CLCD_CLK_MASK 0x3
+#define UART_CLK_SHIFT 4
+#define UART_CLK_MASK 0x1
+#define FIRDA_CLK_SHIFT 5
+#define FIRDA_CLK_MASK 0x3
+#define GPT0_CLK_SHIFT 8
+#define GPT1_CLK_SHIFT 10
+#define GPT2_CLK_SHIFT 11
+#define GPT3_CLK_SHIFT 12
+#define GPT_CLK_MASK 0x1
+#define AUX_CLK_PLL3_VAL 0
+#define AUX_CLK_PLL1_VAL 1
+
+#define PERIP1_CLK_ENB (MISC_BASE + 0x02C)
+/* PERIP1_CLK_ENB register masks */
+#define UART0_CLK_ENB 3
+#define UART1_CLK_ENB 4
+#define SSP0_CLK_ENB 5
+#define SSP1_CLK_ENB 6
+#define I2C_CLK_ENB 7
+#define JPEG_CLK_ENB 8
+#define FSMC_CLK_ENB 9
+#define FIRDA_CLK_ENB 10
+#define GPT2_CLK_ENB 11
+#define GPT3_CLK_ENB 12
+#define GPIO2_CLK_ENB 13
+#define SSP2_CLK_ENB 14
+#define ADC_CLK_ENB 15
+#define GPT1_CLK_ENB 11
+#define RTC_CLK_ENB 17
+#define GPIO1_CLK_ENB 18
+#define DMA_CLK_ENB 19
+#define SMI_CLK_ENB 21
+#define CLCD_CLK_ENB 22
+#define GMAC_CLK_ENB 23
+#define USBD_CLK_ENB 24
+#define USBH0_CLK_ENB 25
+#define USBH1_CLK_ENB 26
+
+#define SOC_CORE_ID (MISC_BASE + 0x030)
+#define RAS_CLK_ENB (MISC_BASE + 0x034)
+#define PERIP1_SOF_RST (MISC_BASE + 0x038)
+/* PERIP1_SOF_RST register masks */
+#define JPEG_SOF_RST 8
+
+#define SOC_USER_ID (MISC_BASE + 0x03C)
+#define RAS_SOF_RST (MISC_BASE + 0x040)
+#define PRSC1_CLK_CFG (MISC_BASE + 0x044)
+#define PRSC2_CLK_CFG (MISC_BASE + 0x048)
+#define PRSC3_CLK_CFG (MISC_BASE + 0x04C)
+/* gpt synthesizer register masks */
+#define GPT_MSCALE_SHIFT 0
+#define GPT_MSCALE_MASK 0xFFF
+#define GPT_NSCALE_SHIFT 12
+#define GPT_NSCALE_MASK 0xF
+
+#define AMEM_CLK_CFG (MISC_BASE + 0x050)
+#define EXPI_CLK_CFG (MISC_BASE + 0x054)
+#define CLCD_CLK_SYNT (MISC_BASE + 0x05C)
+#define FIRDA_CLK_SYNT (MISC_BASE + 0x060)
+#define UART_CLK_SYNT (MISC_BASE + 0x064)
+#define GMAC_CLK_SYNT (MISC_BASE + 0x068)
+#define RAS1_CLK_SYNT (MISC_BASE + 0x06C)
+#define RAS2_CLK_SYNT (MISC_BASE + 0x070)
+#define RAS3_CLK_SYNT (MISC_BASE + 0x074)
+#define RAS4_CLK_SYNT (MISC_BASE + 0x078)
+/* aux clk synthesiser register masks for irda to ras4 */
+#define AUX_SYNT_ENB 31
+#define AUX_EQ_SEL_SHIFT 30
+#define AUX_EQ_SEL_MASK 1
+#define AUX_EQ1_SEL 0
+#define AUX_EQ2_SEL 1
+#define AUX_XSCALE_SHIFT 16
+#define AUX_XSCALE_MASK 0xFFF
+#define AUX_YSCALE_SHIFT 0
+#define AUX_YSCALE_MASK 0xFFF
+
+#define ICM1_ARB_CFG (MISC_BASE + 0x07C)
+#define ICM2_ARB_CFG (MISC_BASE + 0x080)
+#define ICM3_ARB_CFG (MISC_BASE + 0x084)
+#define ICM4_ARB_CFG (MISC_BASE + 0x088)
+#define ICM5_ARB_CFG (MISC_BASE + 0x08C)
+#define ICM6_ARB_CFG (MISC_BASE + 0x090)
+#define ICM7_ARB_CFG (MISC_BASE + 0x094)
+#define ICM8_ARB_CFG (MISC_BASE + 0x098)
+#define ICM9_ARB_CFG (MISC_BASE + 0x09C)
+#define DMA_CHN_CFG (MISC_BASE + 0x0A0)
+#define USB2_PHY_CFG (MISC_BASE + 0x0A4)
+#define GMAC_CFG_CTR (MISC_BASE + 0x0A8)
+#define EXPI_CFG_CTR (MISC_BASE + 0x0AC)
+#define PRC1_LOCK_CTR (MISC_BASE + 0x0C0)
+#define PRC2_LOCK_CTR (MISC_BASE + 0x0C4)
+#define PRC3_LOCK_CTR (MISC_BASE + 0x0C8)
+#define PRC4_LOCK_CTR (MISC_BASE + 0x0CC)
+#define PRC1_IRQ_CTR (MISC_BASE + 0x0D0)
+#define PRC2_IRQ_CTR (MISC_BASE + 0x0D4)
+#define PRC3_IRQ_CTR (MISC_BASE + 0x0D8)
+#define PRC4_IRQ_CTR (MISC_BASE + 0x0DC)
+#define PWRDOWN_CFG_CTR (MISC_BASE + 0x0E0)
+#define COMPSSTL_1V8_CFG (MISC_BASE + 0x0E4)
+#define COMPSSTL_2V5_CFG (MISC_BASE + 0x0E8)
+#define COMPCOR_3V3_CFG (MISC_BASE + 0x0EC)
+#define SSTLPAD_CFG_CTR (MISC_BASE + 0x0F0)
+#define BIST1_CFG_CTR (MISC_BASE + 0x0F4)
+#define BIST2_CFG_CTR (MISC_BASE + 0x0F8)
+#define BIST3_CFG_CTR (MISC_BASE + 0x0FC)
+#define BIST4_CFG_CTR (MISC_BASE + 0x100)
+#define BIST5_CFG_CTR (MISC_BASE + 0x104)
+#define BIST1_STS_RES (MISC_BASE + 0x108)
+#define BIST2_STS_RES (MISC_BASE + 0x10C)
+#define BIST3_STS_RES (MISC_BASE + 0x110)
+#define BIST4_STS_RES (MISC_BASE + 0x114)
+#define BIST5_STS_RES (MISC_BASE + 0x118)
+#define SYSERR_CFG_CTR (MISC_BASE + 0x11C)
+
+#endif /* __MACH_MISC_REGS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear.h b/arch/arm/mach-spear6xx/include/mach/spear.h
new file mode 100644
index 00000000..7fd62153
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/spear.h
@@ -0,0 +1,90 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/spear.h
+ *
+ * SPEAr6xx Machine family specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SPEAR6XX_H
+#define __MACH_SPEAR6XX_H
+
+#include <asm/memory.h>
+#include <mach/spear600.h>
+
+#define SPEAR6XX_ML_SDRAM_BASE UL(0x00000000)
+/* ICM1 - Low speed connection */
+#define SPEAR6XX_ICM1_BASE UL(0xD0000000)
+
+#define SPEAR6XX_ICM1_UART0_BASE UL(0xD0000000)
+#define VA_SPEAR6XX_ICM1_UART0_BASE IO_ADDRESS(SPEAR6XX_ICM1_UART0_BASE)
+
+#define SPEAR6XX_ICM1_UART1_BASE UL(0xD0080000)
+#define SPEAR6XX_ICM1_SSP0_BASE UL(0xD0100000)
+#define SPEAR6XX_ICM1_SSP1_BASE UL(0xD0180000)
+#define SPEAR6XX_ICM1_I2C_BASE UL(0xD0200000)
+#define SPEAR6XX_ICM1_JPEG_BASE UL(0xD0800000)
+#define SPEAR6XX_ICM1_IRDA_BASE UL(0xD1000000)
+#define SPEAR6XX_ICM1_FSMC_BASE UL(0xD1800000)
+#define SPEAR6XX_ICM1_NAND_BASE UL(0xD2000000)
+#define SPEAR6XX_ICM1_SRAM_BASE UL(0xD2800000)
+
+/* ICM2 - Application Subsystem */
+#define SPEAR6XX_ICM2_BASE UL(0xD8000000)
+#define SPEAR6XX_ICM2_TMR0_BASE UL(0xD8000000)
+#define SPEAR6XX_ICM2_TMR1_BASE UL(0xD8080000)
+#define SPEAR6XX_ICM2_GPIO_BASE UL(0xD8100000)
+#define SPEAR6XX_ICM2_SSP2_BASE UL(0xD8180000)
+#define SPEAR6XX_ICM2_ADC_BASE UL(0xD8200000)
+
+/* ML-1, 2 - Multi Layer CPU Subsystem */
+#define SPEAR6XX_ML_CPU_BASE UL(0xF0000000)
+#define SPEAR6XX_CPU_TMR_BASE UL(0xF0000000)
+#define SPEAR6XX_CPU_GPIO_BASE UL(0xF0100000)
+#define SPEAR6XX_CPU_VIC_SEC_BASE UL(0xF1000000)
+#define VA_SPEAR6XX_CPU_VIC_SEC_BASE IO_ADDRESS(SPEAR6XX_CPU_VIC_SEC_BASE)
+#define SPEAR6XX_CPU_VIC_PRI_BASE UL(0xF1100000)
+#define VA_SPEAR6XX_CPU_VIC_PRI_BASE IO_ADDRESS(SPEAR6XX_CPU_VIC_PRI_BASE)
+
+/* ICM3 - Basic Subsystem */
+#define SPEAR6XX_ICM3_BASE UL(0xF8000000)
+#define SPEAR6XX_ICM3_SMEM_BASE UL(0xF8000000)
+#define SPEAR6XX_ICM3_SMI_CTRL_BASE UL(0xFC000000)
+#define SPEAR6XX_ICM3_CLCD_BASE UL(0xFC200000)
+#define SPEAR6XX_ICM3_DMA_BASE UL(0xFC400000)
+#define SPEAR6XX_ICM3_SDRAM_CTRL_BASE UL(0xFC600000)
+#define SPEAR6XX_ICM3_TMR_BASE UL(0xFC800000)
+#define SPEAR6XX_ICM3_WDT_BASE UL(0xFC880000)
+#define SPEAR6XX_ICM3_RTC_BASE UL(0xFC900000)
+#define SPEAR6XX_ICM3_GPIO_BASE UL(0xFC980000)
+#define SPEAR6XX_ICM3_SYS_CTRL_BASE UL(0xFCA00000)
+#define VA_SPEAR6XX_ICM3_SYS_CTRL_BASE IO_ADDRESS(SPEAR6XX_ICM3_SYS_CTRL_BASE)
+#define SPEAR6XX_ICM3_MISC_REG_BASE UL(0xFCA80000)
+#define VA_SPEAR6XX_ICM3_MISC_REG_BASE IO_ADDRESS(SPEAR6XX_ICM3_MISC_REG_BASE)
+
+/* ICM4 - High Speed Connection */
+#define SPEAR6XX_ICM4_BASE UL(0xE0000000)
+#define SPEAR6XX_ICM4_GMAC_BASE UL(0xE0800000)
+#define SPEAR6XX_ICM4_USBD_FIFO_BASE UL(0xE1000000)
+#define SPEAR6XX_ICM4_USBD_CSR_BASE UL(0xE1100000)
+#define SPEAR6XX_ICM4_USBD_PLDT_BASE UL(0xE1200000)
+#define SPEAR6XX_ICM4_USB_EHCI0_BASE UL(0xE1800000)
+#define SPEAR6XX_ICM4_USB_OHCI0_BASE UL(0xE1900000)
+#define SPEAR6XX_ICM4_USB_EHCI1_BASE UL(0xE2000000)
+#define SPEAR6XX_ICM4_USB_OHCI1_BASE UL(0xE2100000)
+#define SPEAR6XX_ICM4_USB_ARB_BASE UL(0xE2800000)
+
+/* Debug uart for linux, will be used for debug and uncompress messages */
+#define SPEAR_DBG_UART_BASE SPEAR6XX_ICM1_UART0_BASE
+#define VA_SPEAR_DBG_UART_BASE VA_SPEAR6XX_ICM1_UART0_BASE
+
+/* Sysctl base for spear platform */
+#define SPEAR_SYS_CTRL_BASE SPEAR6XX_ICM3_SYS_CTRL_BASE
+#define VA_SPEAR_SYS_CTRL_BASE VA_SPEAR6XX_ICM3_SYS_CTRL_BASE
+
+#endif /* __MACH_SPEAR6XX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/spear600.h b/arch/arm/mach-spear6xx/include/mach/spear600.h
new file mode 100644
index 00000000..c068cc50
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/spear600.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-spear66xx/include/mach/spear600.h
+ *
+ * SPEAr600 Machine specific definition
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifdef CONFIG_MACH_SPEAR600
+
+#ifndef __MACH_SPEAR600_H
+#define __MACH_SPEAR600_H
+
+#endif /* __MACH_SPEAR600_H */
+
+#endif /* CONFIG_MACH_SPEAR600 */
diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h
new file mode 100644
index 00000000..0b1d2be8
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/system.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/system.h
+ *
+ * SPEAr6xx Machine family specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_SYSTEM_H
+#define __MACH_SYSTEM_H
+
+#include <plat/system.h>
+
+#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/timex.h b/arch/arm/mach-spear6xx/include/mach/timex.h
new file mode 100644
index 00000000..ac1c5b00
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/timex.h
+ *
+ * SPEAr6XX machine family specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+#include <plat/timex.h>
+
+#endif /* __MACH_TIMEX_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/uncompress.h b/arch/arm/mach-spear6xx/include/mach/uncompress.h
new file mode 100644
index 00000000..77f0765e
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/uncompress.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_UNCOMPRESS_H
+#define __MACH_UNCOMPRESS_H
+
+#include <plat/uncompress.h>
+
+#endif /* __MACH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-spear6xx/include/mach/vmalloc.h b/arch/arm/mach-spear6xx/include/mach/vmalloc.h
new file mode 100644
index 00000000..4a0b56cb
--- /dev/null
+++ b/arch/arm/mach-spear6xx/include/mach/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-spear6xx/include/mach/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr6xx machine family
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_VMALLOC_H
+#define __MACH_VMALLOC_H
+
+#include <plat/vmalloc.h>
+
+#endif /* __MACH_VMALLOC_H */
diff --git a/arch/arm/mach-spear6xx/spear600.c b/arch/arm/mach-spear6xx/spear600.c
new file mode 100644
index 00000000..d0e6eeae
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear600.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-spear6xx/spear600.c
+ *
+ * SPEAr600 machine source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/ptrace.h>
+#include <asm/irq.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+/* Add spear600 specific devices here */
+
+void __init spear600_init(void)
+{
+ /* call spear6xx family common init function */
+ spear6xx_init();
+}
diff --git a/arch/arm/mach-spear6xx/spear600_evb.c b/arch/arm/mach-spear6xx/spear600_evb.c
new file mode 100644
index 00000000..f19cefe9
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear600_evb.c
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-spear6xx/spear600_evb.c
+ *
+ * SPEAr600 evaluation board source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+
+static struct amba_device *amba_devs[] __initdata = {
+ &gpio_device[0],
+ &gpio_device[1],
+ &gpio_device[2],
+ &uart_device[0],
+ &uart_device[1],
+};
+
+static struct platform_device *plat_devs[] __initdata = {
+};
+
+static void __init spear600_evb_init(void)
+{
+ unsigned int i;
+
+ /* call spear600 machine init function */
+ spear600_init();
+
+ /* Add Platform Devices */
+ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
+
+ /* Add Amba Devices */
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+ amba_device_register(amba_devs[i], &iomem_resource);
+}
+
+MACHINE_START(SPEAR600, "ST-SPEAR600-EVB")
+ .boot_params = 0x00000100,
+ .map_io = spear6xx_map_io,
+ .init_irq = spear6xx_init_irq,
+ .timer = &spear6xx_timer,
+ .init_machine = spear600_evb_init,
+MACHINE_END
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
new file mode 100644
index 00000000..e0f6628c
--- /dev/null
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -0,0 +1,183 @@
+/*
+ * arch/arm/mach-spear6xx/spear6xx.c
+ *
+ * SPEAr6XX machines common source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/amba/pl061.h>
+#include <linux/ptrace.h>
+#include <linux/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+/* Add spear6xx machines common devices here */
+/* uart device registration */
+struct amba_device uart_device[] = {
+ {
+ .dev = {
+ .init_name = "uart0",
+ },
+ .res = {
+ .start = SPEAR6XX_ICM1_UART0_BASE,
+ .end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_UART_0, NO_IRQ},
+ }, {
+ .dev = {
+ .init_name = "uart1",
+ },
+ .res = {
+ .start = SPEAR6XX_ICM1_UART1_BASE,
+ .end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_UART_1, NO_IRQ},
+ }
+};
+
+/* gpio device registration */
+static struct pl061_platform_data gpio_plat_data[] = {
+ {
+ .gpio_base = 0,
+ .irq_base = SPEAR_GPIO0_INT_BASE,
+ }, {
+ .gpio_base = 8,
+ .irq_base = SPEAR_GPIO1_INT_BASE,
+ }, {
+ .gpio_base = 16,
+ .irq_base = SPEAR_GPIO2_INT_BASE,
+ },
+};
+
+struct amba_device gpio_device[] = {
+ {
+ .dev = {
+ .init_name = "gpio0",
+ .platform_data = &gpio_plat_data[0],
+ },
+ .res = {
+ .start = SPEAR6XX_CPU_GPIO_BASE,
+ .end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_LOCAL_GPIO, NO_IRQ},
+ }, {
+ .dev = {
+ .init_name = "gpio1",
+ .platform_data = &gpio_plat_data[1],
+ },
+ .res = {
+ .start = SPEAR6XX_ICM3_GPIO_BASE,
+ .end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_BASIC_GPIO, NO_IRQ},
+ }, {
+ .dev = {
+ .init_name = "gpio2",
+ .platform_data = &gpio_plat_data[2],
+ },
+ .res = {
+ .start = SPEAR6XX_ICM2_GPIO_BASE,
+ .end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_APPL_GPIO, NO_IRQ},
+ }
+};
+
+/* This will add devices, and do machine specific tasks */
+void __init spear6xx_init(void)
+{
+ /* nothing to do for now */
+}
+
+/* This will initialize vic */
+void __init spear6xx_init_irq(void)
+{
+ vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_PRI_BASE, 0, ~0, 0);
+ vic_init((void __iomem *)VA_SPEAR6XX_CPU_VIC_SEC_BASE, 32, ~0, 0);
+}
+
+/* Following will create static virtual/physical mappings */
+static struct map_desc spear6xx_io_desc[] __initdata = {
+ {
+ .virtual = VA_SPEAR6XX_ICM1_UART0_BASE,
+ .pfn = __phys_to_pfn(SPEAR6XX_ICM1_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR6XX_CPU_VIC_PRI_BASE,
+ .pfn = __phys_to_pfn(SPEAR6XX_CPU_VIC_PRI_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR6XX_CPU_VIC_SEC_BASE,
+ .pfn = __phys_to_pfn(SPEAR6XX_CPU_VIC_SEC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR6XX_ICM3_SYS_CTRL_BASE,
+ .pfn = __phys_to_pfn(SPEAR6XX_ICM3_SYS_CTRL_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VA_SPEAR6XX_ICM3_MISC_REG_BASE,
+ .pfn = __phys_to_pfn(SPEAR6XX_ICM3_MISC_REG_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
+};
+
+/* This will create static memory mapping for selected devices */
+void __init spear6xx_map_io(void)
+{
+ iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
+
+ /* This will initialize clock framework */
+ spear6xx_clk_init();
+}
+
+static void __init spear6xx_timer_init(void)
+{
+ char pclk_name[] = "pll3_48m_clk";
+ struct clk *gpt_clk, *pclk;
+
+ /* get the system timer clock */
+ gpt_clk = clk_get_sys("gpt0", NULL);
+ if (IS_ERR(gpt_clk)) {
+ pr_err("%s:couldn't get clk for gpt\n", __func__);
+ BUG();
+ }
+
+ /* get the suitable parent clock for timer*/
+ pclk = clk_get(NULL, pclk_name);
+ if (IS_ERR(pclk)) {
+ pr_err("%s:couldn't get %s as parent for gpt\n",
+ __func__, pclk_name);
+ BUG();
+ }
+
+ clk_set_parent(gpt_clk, pclk);
+ clk_put(gpt_clk);
+ clk_put(pclk);
+
+ spear_setup_timer();
+}
+
+struct sys_timer spear6xx_timer = {
+ .init = spear6xx_timer_init,
+};
diff --git a/arch/arm/mach-tcc8k/Kconfig b/arch/arm/mach-tcc8k/Kconfig
new file mode 100644
index 00000000..ad86415d
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_TCC8K
+
+comment "TCC8000 systems:"
+
+config MACH_TCC8000_SDK
+ bool "Telechips TCC8000-SDK development kit"
+ default y
+ help
+ Support for the Telechips TCC8000-SDK board.
+
+endif
diff --git a/arch/arm/mach-tcc8k/Makefile b/arch/arm/mach-tcc8k/Makefile
new file mode 100644
index 00000000..9bacf31e
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for TCC8K boards and common files.
+#
+
+# Common support
+obj-y += clock.o irq.o time.o io.o devices.o
+
+# Board specific support
+obj-$(CONFIG_MACH_TCC8000_SDK) += board-tcc8000-sdk.o
diff --git a/arch/arm/mach-tcc8k/Makefile.boot b/arch/arm/mach-tcc8k/Makefile.boot
new file mode 100644
index 00000000..f135c9de
--- /dev/null
+++ b/arch/arm/mach-tcc8k/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x20008000
+params_phys-y := 0x20000100
+initrd_phys-y := 0x20800000
diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
new file mode 100644
index 00000000..4cb3c2dd
--- /dev/null
+++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include <mach/clock.h>
+#include <mach/tcc-nand.h>
+#include <mach/tcc8k-regs.h>
+
+#include "common.h"
+
+#define XI_FREQUENCY 12000000
+#define XTI_FREQUENCY 32768
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND */
+static struct tcc_nand_platform_data tcc8k_sdk_nand_data = {
+ .width = 1,
+ .hw_ecc = 0,
+};
+#endif
+
+static void __init tcc8k_init(void)
+{
+#ifdef CONFIG_MTD_NAND_TCC
+ tcc_nand_device.dev.platform_data = &tcc8k_sdk_nand_data;
+ platform_device_register(&tcc_nand_device);
+#endif
+}
+
+static void __init tcc8k_init_timer(void)
+{
+ tcc_clocks_init(XI_FREQUENCY, XTI_FREQUENCY);
+}
+
+static struct sys_timer tcc8k_timer = {
+ .init = tcc8k_init_timer,
+};
+
+static void __init tcc8k_map_io(void)
+{
+ tcc8k_map_common_io();
+
+ /* set PLL0 clock to 96MHz, adapt UART0 divisor */
+ __raw_writel(0x00026003, CKC_BASE + PLL0CFG_OFFS);
+ __raw_writel(0x10000001, CKC_BASE + ACLKUART0_OFFS);
+
+ /* set PLL1 clock to 192MHz */
+ __raw_writel(0x00016003, CKC_BASE + PLL1CFG_OFFS);
+
+ /* set PLL2 clock to 48MHz */
+ __raw_writel(0x00036003, CKC_BASE + PLL2CFG_OFFS);
+
+ /* with CPU freq higher than 150 MHz, need extra DTCM wait */
+ __raw_writel(0x00000001, SCFG_BASE + DTCMWAIT_OFFS);
+
+ /* PLL locking time as specified */
+ udelay(300);
+}
+
+MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .map_io = tcc8k_map_io,
+ .init_irq = tcc8k_init_irq,
+ .init_machine = tcc8k_init,
+ .timer = &tcc8k_timer,
+MACHINE_END
diff --git a/arch/arm/mach-tcc8k/clock.c b/arch/arm/mach-tcc8k/clock.c
new file mode 100644
index 00000000..e7cdae5c
--- /dev/null
+++ b/arch/arm/mach-tcc8k/clock.c
@@ -0,0 +1,580 @@
+/*
+ * Lowlevel clock handling for Telechips TCC8xxx SoCs
+ *
+ * Copyright (C) 2010 by Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/irqs.h>
+#include <mach/tcc8k-regs.h>
+
+#include "common.h"
+
+#define BCLKCTR0 (CKC_BASE + BCLKCTR0_OFFS)
+#define BCLKCTR1 (CKC_BASE + BCLKCTR1_OFFS)
+
+#define ACLKREF (CKC_BASE + ACLKREF_OFFS)
+#define ACLKUART0 (CKC_BASE + ACLKUART0_OFFS)
+#define ACLKUART1 (CKC_BASE + ACLKUART1_OFFS)
+#define ACLKUART2 (CKC_BASE + ACLKUART2_OFFS)
+#define ACLKUART3 (CKC_BASE + ACLKUART3_OFFS)
+#define ACLKUART4 (CKC_BASE + ACLKUART4_OFFS)
+#define ACLKI2C (CKC_BASE + ACLKI2C_OFFS)
+#define ACLKADC (CKC_BASE + ACLKADC_OFFS)
+#define ACLKUSBH (CKC_BASE + ACLKUSBH_OFFS)
+#define ACLKLCD (CKC_BASE + ACLKLCD_OFFS)
+#define ACLKSDH0 (CKC_BASE + ACLKSDH0_OFFS)
+#define ACLKSDH1 (CKC_BASE + ACLKSDH1_OFFS)
+#define ACLKSPI0 (CKC_BASE + ACLKSPI0_OFFS)
+#define ACLKSPI1 (CKC_BASE + ACLKSPI1_OFFS)
+#define ACLKSPDIF (CKC_BASE + ACLKSPDIF_OFFS)
+#define ACLKC3DEC (CKC_BASE + ACLKC3DEC_OFFS)
+#define ACLKCAN0 (CKC_BASE + ACLKCAN0_OFFS)
+#define ACLKCAN1 (CKC_BASE + ACLKCAN1_OFFS)
+#define ACLKGSB0 (CKC_BASE + ACLKGSB0_OFFS)
+#define ACLKGSB1 (CKC_BASE + ACLKGSB1_OFFS)
+#define ACLKGSB2 (CKC_BASE + ACLKGSB2_OFFS)
+#define ACLKGSB3 (CKC_BASE + ACLKGSB3_OFFS)
+#define ACLKTCT (CKC_BASE + ACLKTCT_OFFS)
+#define ACLKTCX (CKC_BASE + ACLKTCX_OFFS)
+#define ACLKTCZ (CKC_BASE + ACLKTCZ_OFFS)
+
+#define ACLK_MAX_DIV (0xfff + 1)
+
+/* Crystal frequencies */
+static unsigned long xi_rate, xti_rate;
+
+static void __iomem *pll_cfg_addr(int pll)
+{
+ switch (pll) {
+ case 0: return (CKC_BASE + PLL0CFG_OFFS);
+ case 1: return (CKC_BASE + PLL1CFG_OFFS);
+ case 2: return (CKC_BASE + PLL2CFG_OFFS);
+ default:
+ BUG();
+ }
+}
+
+static int pll_enable(int pll, int enable)
+{
+ u32 reg;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ if (enable)
+ reg &= ~PLLxCFG_PD;
+ else
+ reg |= PLLxCFG_PD;
+
+ __raw_writel(reg, addr);
+ return 0;
+}
+
+static int xi_enable(int enable)
+{
+ u32 reg;
+
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (enable)
+ reg |= CLKCTRL_XE;
+ else
+ reg &= ~CLKCTRL_XE;
+
+ __raw_writel(reg, CKC_BASE + CLKCTRL_OFFS);
+ return 0;
+}
+
+static int root_clk_enable(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 1);
+ case CLK_SRC_PLL1: return pll_enable(1, 1);
+ case CLK_SRC_PLL2: return pll_enable(2, 1);
+ case CLK_SRC_XI: return xi_enable(1);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int root_clk_disable(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return pll_enable(0, 0);
+ case CLK_SRC_PLL1: return pll_enable(1, 0);
+ case CLK_SRC_PLL2: return pll_enable(2, 0);
+ case CLK_SRC_XI: return xi_enable(0);
+ default:
+ BUG();
+ }
+ return 0;
+}
+
+static int enable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT)
+ return root_clk_enable(clk->root_id);
+
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg |= ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg |= 1 << clk->bclk_shift;
+ __raw_writel(reg, clk->bclkctr);
+ }
+ return 0;
+}
+
+static void disable_clk(struct clk *clk)
+{
+ u32 reg;
+
+ if (clk->root_id != CLK_SRC_NOROOT) {
+ root_clk_disable(clk->root_id);
+ return;
+ }
+
+ if (clk->bclkctr) {
+ reg = __raw_readl(clk->bclkctr);
+ reg &= ~(1 << clk->bclk_shift);
+ __raw_writel(reg, clk->bclkctr);
+ }
+ if (clk->aclkreg) {
+ reg = __raw_readl(clk->aclkreg);
+ reg &= ~ACLK_EN;
+ __raw_writel(reg, clk->aclkreg);
+ }
+}
+
+static unsigned long get_rate_pll(int pll)
+{
+ u32 reg;
+ unsigned long s, m, p;
+ void __iomem *addr = pll_cfg_addr(pll);
+
+ reg = __raw_readl(addr);
+ s = (reg >> 16) & 0x07;
+ m = (reg >> 8) & 0xff;
+ p = reg & 0x3f;
+
+ return (m * xi_rate) / (p * (1 << s));
+}
+
+static unsigned long get_rate_pll_div(int pll)
+{
+ u32 reg;
+ unsigned long div = 0;
+ void __iomem *addr;
+
+ switch (pll) {
+ case 0:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P0E)
+ div = (reg >> 24) & 0x3f;
+ break;
+ case 1:
+ addr = CKC_BASE + CLKDIVC0_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC0_P1E)
+ div = (reg >> 16) & 0x3f;
+ break;
+ case 2:
+ addr = CKC_BASE + CLKDIVC1_OFFS;
+ reg = __raw_readl(addr);
+ if (reg & CLKDIVC1_P2E)
+ div = reg & 0x3f;
+ break;
+ }
+ return get_rate_pll(pll) / (div + 1);
+}
+
+static unsigned long get_rate_xi_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XE)
+ div = (reg >> 8) & 0x3f;
+
+ return xi_rate / (div + 1);
+}
+
+static unsigned long get_rate_xti_div(void)
+{
+ unsigned long div = 0;
+ u32 reg = __raw_readl(CKC_BASE + CLKDIVC0_OFFS);
+
+ if (reg & CLKDIVC0_XTE)
+ div = reg & 0x3f;
+
+ return xti_rate / (div + 1);
+}
+
+static unsigned long root_clk_get_rate(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return get_rate_pll(0);
+ case CLK_SRC_PLL1: return get_rate_pll(1);
+ case CLK_SRC_PLL2: return get_rate_pll(2);
+ case CLK_SRC_PLL0DIV: return get_rate_pll_div(0);
+ case CLK_SRC_PLL1DIV: return get_rate_pll_div(1);
+ case CLK_SRC_PLL2DIV: return get_rate_pll_div(2);
+ case CLK_SRC_XI: return xi_rate;
+ case CLK_SRC_XTI: return xti_rate;
+ case CLK_SRC_XIDIV: return get_rate_xi_div();
+ case CLK_SRC_XTIDIV: return get_rate_xti_div();
+ default: return 0;
+ }
+}
+
+static unsigned long aclk_get_rate(struct clk *clk)
+{
+ u32 reg;
+ unsigned long div;
+ unsigned int src;
+
+ reg = __raw_readl(clk->aclkreg);
+ div = reg & 0x0fff;
+ src = (reg >> ACLK_SEL_SHIFT) & CLK_SRC_MASK;
+ return root_clk_get_rate(src) / (div + 1);
+}
+
+static unsigned long aclk_best_div(struct clk *clk, unsigned long rate)
+{
+ unsigned long div, src, freq, r1, r2;
+
+ if (!rate)
+ return ACLK_MAX_DIV;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+ freq = root_clk_get_rate(src);
+ div = freq / rate;
+ if (!div)
+ return 1;
+ if (div >= ACLK_MAX_DIV)
+ return ACLK_MAX_DIV;
+ r1 = freq / div;
+ r2 = freq / (div + 1);
+ if ((rate - r2) < (r1 - rate))
+ return div + 1;
+
+ return div;
+}
+
+static unsigned long aclk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned int src;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ return root_clk_get_rate(src) / aclk_best_div(clk, rate);
+}
+
+static int aclk_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->aclkreg) & ~ACLK_DIV_MASK;
+ reg |= aclk_best_div(clk, rate) - 1;
+ __raw_writel(reg, clk->aclkreg);
+ return 0;
+}
+
+static unsigned long get_rate_sys(struct clk *clk)
+{
+ unsigned int src;
+
+ src = __raw_readl(CKC_BASE + CLKCTRL_OFFS) & CLK_SRC_MASK;
+ return root_clk_get_rate(src);
+}
+
+static unsigned long get_rate_bus(struct clk *clk)
+{
+ unsigned int reg, sdiv, bdiv, rate;
+
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ rate = get_rate_sys(clk);
+ sdiv = (reg >> 20) & 3;
+ if (sdiv)
+ rate /= sdiv + 1;
+ bdiv = (reg >> 4) & 0xff;
+ if (bdiv)
+ rate /= bdiv + 1;
+ return rate;
+}
+
+static unsigned long get_rate_cpu(struct clk *clk)
+{
+ unsigned int reg, div, fsys, fbus;
+
+ fbus = get_rate_bus(clk);
+ reg = __raw_readl(CKC_BASE + CLKCTRL_OFFS);
+ if (reg & (1 << 29))
+ return fbus;
+ fsys = get_rate_sys(clk);
+ div = (reg >> 16) & 0x0f;
+ return fbus + ((fsys - fbus) * (div + 1)) / 16;
+}
+
+static unsigned long get_rate_root(struct clk *clk)
+{
+ return root_clk_get_rate(clk->root_id);
+}
+
+static int aclk_set_parent(struct clk *clock, struct clk *parent)
+{
+ u32 reg;
+
+ if (clock->parent == parent)
+ return 0;
+
+ clock->parent = parent;
+
+ if (!parent)
+ return 0;
+
+ if (parent->root_id == CLK_SRC_NOROOT)
+ return 0;
+ reg = __raw_readl(clock->aclkreg);
+ reg &= ~ACLK_SEL_MASK;
+ reg |= (parent->root_id << ACLK_SEL_SHIFT) & ACLK_SEL_MASK;
+ __raw_writel(reg, clock->aclkreg);
+
+ return 0;
+}
+
+#define DEFINE_ROOT_CLOCK(name, ri, p) \
+ static struct clk name = { \
+ .root_id = ri, \
+ .get_rate = get_rate_root, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+#define DEFINE_SPECIAL_CLOCK(name, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .get_rate = gr, \
+ .parent = p, \
+ };
+
+#define DEFINE_ACLOCK(name, bc, bs, ar) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .aclkreg = ar, \
+ .get_rate = aclk_get_rate, \
+ .set_rate = aclk_set_rate, \
+ .round_rate = aclk_round_rate, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .set_parent = aclk_set_parent, \
+ };
+
+#define DEFINE_BCLOCK(name, bc, bs, gr, p) \
+ static struct clk name = { \
+ .root_id = CLK_SRC_NOROOT, \
+ .bclkctr = bc, \
+ .bclk_shift = bs, \
+ .get_rate = gr, \
+ .enable = enable_clk, \
+ .disable = disable_clk, \
+ .parent = p, \
+ };
+
+DEFINE_ROOT_CLOCK(xi, CLK_SRC_XI, NULL)
+DEFINE_ROOT_CLOCK(xti, CLK_SRC_XTI, NULL)
+DEFINE_ROOT_CLOCK(xidiv, CLK_SRC_XIDIV, &xi)
+DEFINE_ROOT_CLOCK(xtidiv, CLK_SRC_XTIDIV, &xti)
+DEFINE_ROOT_CLOCK(pll0, CLK_SRC_PLL0, &xi)
+DEFINE_ROOT_CLOCK(pll1, CLK_SRC_PLL1, &xi)
+DEFINE_ROOT_CLOCK(pll2, CLK_SRC_PLL2, &xi)
+DEFINE_ROOT_CLOCK(pll0div, CLK_SRC_PLL0DIV, &pll0)
+DEFINE_ROOT_CLOCK(pll1div, CLK_SRC_PLL1DIV, &pll1)
+DEFINE_ROOT_CLOCK(pll2div, CLK_SRC_PLL2DIV, &pll2)
+
+/* The following 3 clocks are special and are initialized explicitly later */
+DEFINE_SPECIAL_CLOCK(sys, get_rate_sys, NULL)
+DEFINE_SPECIAL_CLOCK(bus, get_rate_bus, &sys)
+DEFINE_SPECIAL_CLOCK(cpu, get_rate_cpu, &sys)
+
+DEFINE_ACLOCK(tct, NULL, 0, ACLKTCT)
+DEFINE_ACLOCK(tcx, NULL, 0, ACLKTCX)
+DEFINE_ACLOCK(tcz, NULL, 0, ACLKTCZ)
+DEFINE_ACLOCK(ref, NULL, 0, ACLKREF)
+DEFINE_ACLOCK(uart0, BCLKCTR0, 5, ACLKUART0)
+DEFINE_ACLOCK(uart1, BCLKCTR0, 23, ACLKUART1)
+DEFINE_ACLOCK(uart2, BCLKCTR0, 6, ACLKUART2)
+DEFINE_ACLOCK(uart3, BCLKCTR0, 8, ACLKUART3)
+DEFINE_ACLOCK(uart4, BCLKCTR1, 6, ACLKUART4)
+DEFINE_ACLOCK(i2c, BCLKCTR0, 7, ACLKI2C)
+DEFINE_ACLOCK(adc, BCLKCTR0, 10, ACLKADC)
+DEFINE_ACLOCK(usbh0, BCLKCTR0, 11, ACLKUSBH)
+DEFINE_ACLOCK(lcd, BCLKCTR0, 13, ACLKLCD)
+DEFINE_ACLOCK(sd0, BCLKCTR0, 17, ACLKSDH0)
+DEFINE_ACLOCK(sd1, BCLKCTR1, 5, ACLKSDH1)
+DEFINE_ACLOCK(spi0, BCLKCTR0, 24, ACLKSPI0)
+DEFINE_ACLOCK(spi1, BCLKCTR0, 30, ACLKSPI1)
+DEFINE_ACLOCK(spdif, BCLKCTR1, 2, ACLKSPDIF)
+DEFINE_ACLOCK(c3dec, BCLKCTR1, 9, ACLKC3DEC)
+DEFINE_ACLOCK(can0, BCLKCTR1, 10, ACLKCAN0)
+DEFINE_ACLOCK(can1, BCLKCTR1, 11, ACLKCAN1)
+DEFINE_ACLOCK(gsb0, BCLKCTR1, 13, ACLKGSB0)
+DEFINE_ACLOCK(gsb1, BCLKCTR1, 14, ACLKGSB1)
+DEFINE_ACLOCK(gsb2, BCLKCTR1, 15, ACLKGSB2)
+DEFINE_ACLOCK(gsb3, BCLKCTR1, 16, ACLKGSB3)
+DEFINE_ACLOCK(usbh1, BCLKCTR1, 20, ACLKUSBH)
+
+DEFINE_BCLOCK(dai0, BCLKCTR0, 0, NULL, NULL)
+DEFINE_BCLOCK(pic, BCLKCTR0, 1, NULL, NULL)
+DEFINE_BCLOCK(tc, BCLKCTR0, 2, NULL, NULL)
+DEFINE_BCLOCK(gpio, BCLKCTR0, 3, NULL, NULL)
+DEFINE_BCLOCK(usbd, BCLKCTR0, 4, NULL, NULL)
+DEFINE_BCLOCK(ecc, BCLKCTR0, 9, NULL, NULL)
+DEFINE_BCLOCK(gdma0, BCLKCTR0, 12, NULL, NULL)
+DEFINE_BCLOCK(rtc, BCLKCTR0, 15, NULL, NULL)
+DEFINE_BCLOCK(nfc, BCLKCTR0, 16, NULL, NULL)
+DEFINE_BCLOCK(g2d, BCLKCTR0, 18, NULL, NULL)
+DEFINE_BCLOCK(gdma1, BCLKCTR0, 22, NULL, NULL)
+DEFINE_BCLOCK(mscl, BCLKCTR0, 25, NULL, NULL)
+DEFINE_BCLOCK(bdma, BCLKCTR1, 0, NULL, NULL)
+DEFINE_BCLOCK(adma0, BCLKCTR1, 1, NULL, NULL)
+DEFINE_BCLOCK(scfg, BCLKCTR1, 3, NULL, NULL)
+DEFINE_BCLOCK(cid, BCLKCTR1, 4, NULL, NULL)
+DEFINE_BCLOCK(dai1, BCLKCTR1, 7, NULL, NULL)
+DEFINE_BCLOCK(adma1, BCLKCTR1, 8, NULL, NULL)
+DEFINE_BCLOCK(gps, BCLKCTR1, 12, NULL, NULL)
+DEFINE_BCLOCK(gdma2, BCLKCTR1, 17, NULL, NULL)
+DEFINE_BCLOCK(gdma3, BCLKCTR1, 18, NULL, NULL)
+DEFINE_BCLOCK(ddrc, BCLKCTR1, 19, NULL, NULL)
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK(NULL, "bus", bus)
+ _REGISTER_CLOCK(NULL, "cpu", cpu)
+ _REGISTER_CLOCK(NULL, "tct", tct)
+ _REGISTER_CLOCK(NULL, "tcx", tcx)
+ _REGISTER_CLOCK(NULL, "tcz", tcz)
+ _REGISTER_CLOCK(NULL, "ref", ref)
+ _REGISTER_CLOCK(NULL, "dai0", dai0)
+ _REGISTER_CLOCK(NULL, "pic", pic)
+ _REGISTER_CLOCK(NULL, "tc", tc)
+ _REGISTER_CLOCK(NULL, "gpio", gpio)
+ _REGISTER_CLOCK(NULL, "usbd", usbd)
+ _REGISTER_CLOCK("tcc-uart.0", NULL, uart0)
+ _REGISTER_CLOCK("tcc-uart.2", NULL, uart2)
+ _REGISTER_CLOCK("tcc-i2c", NULL, i2c)
+ _REGISTER_CLOCK("tcc-uart.3", NULL, uart3)
+ _REGISTER_CLOCK(NULL, "ecc", ecc)
+ _REGISTER_CLOCK(NULL, "adc", adc)
+ _REGISTER_CLOCK("tcc-usbh.0", "usb", usbh0)
+ _REGISTER_CLOCK(NULL, "gdma0", gdma0)
+ _REGISTER_CLOCK(NULL, "lcd", lcd)
+ _REGISTER_CLOCK(NULL, "rtc", rtc)
+ _REGISTER_CLOCK(NULL, "nfc", nfc)
+ _REGISTER_CLOCK("tcc-mmc.0", NULL, sd0)
+ _REGISTER_CLOCK(NULL, "g2d", g2d)
+ _REGISTER_CLOCK(NULL, "gdma1", gdma1)
+ _REGISTER_CLOCK("tcc-uart.1", NULL, uart1)
+ _REGISTER_CLOCK("tcc-spi.0", NULL, spi0)
+ _REGISTER_CLOCK(NULL, "mscl", mscl)
+ _REGISTER_CLOCK("tcc-spi.1", NULL, spi1)
+ _REGISTER_CLOCK(NULL, "bdma", bdma)
+ _REGISTER_CLOCK(NULL, "adma0", adma0)
+ _REGISTER_CLOCK(NULL, "spdif", spdif)
+ _REGISTER_CLOCK(NULL, "scfg", scfg)
+ _REGISTER_CLOCK(NULL, "cid", cid)
+ _REGISTER_CLOCK("tcc-mmc.1", NULL, sd1)
+ _REGISTER_CLOCK("tcc-uart.4", NULL, uart4)
+ _REGISTER_CLOCK(NULL, "dai1", dai1)
+ _REGISTER_CLOCK(NULL, "adma1", adma1)
+ _REGISTER_CLOCK(NULL, "c3dec", c3dec)
+ _REGISTER_CLOCK("tcc-can.0", NULL, can0)
+ _REGISTER_CLOCK("tcc-can.1", NULL, can1)
+ _REGISTER_CLOCK(NULL, "gps", gps)
+ _REGISTER_CLOCK("tcc-gsb.0", NULL, gsb0)
+ _REGISTER_CLOCK("tcc-gsb.1", NULL, gsb1)
+ _REGISTER_CLOCK("tcc-gsb.2", NULL, gsb2)
+ _REGISTER_CLOCK("tcc-gsb.3", NULL, gsb3)
+ _REGISTER_CLOCK(NULL, "gdma2", gdma2)
+ _REGISTER_CLOCK(NULL, "gdma3", gdma3)
+ _REGISTER_CLOCK(NULL, "ddrc", ddrc)
+ _REGISTER_CLOCK("tcc-usbh.1", "usb", usbh1)
+};
+
+static struct clk *root_clk_by_index(enum root_clks src)
+{
+ switch (src) {
+ case CLK_SRC_PLL0: return &pll0;
+ case CLK_SRC_PLL1: return &pll1;
+ case CLK_SRC_PLL2: return &pll2;
+ case CLK_SRC_PLL0DIV: return &pll0div;
+ case CLK_SRC_PLL1DIV: return &pll1div;
+ case CLK_SRC_PLL2DIV: return &pll2div;
+ case CLK_SRC_XI: return &xi;
+ case CLK_SRC_XTI: return &xti;
+ case CLK_SRC_XIDIV: return &xidiv;
+ case CLK_SRC_XTIDIV: return &xtidiv;
+ default: return NULL;
+ }
+}
+
+static void find_aclk_parent(struct clk *clk)
+{
+ unsigned int src;
+ struct clk *clock;
+
+ if (!clk->aclkreg)
+ return;
+
+ src = __raw_readl(clk->aclkreg) >> ACLK_SEL_SHIFT;
+ src &= CLK_SRC_MASK;
+
+ clock = root_clk_by_index(src);
+ if (!clock)
+ return;
+
+ clk->parent = clock;
+ clk->set_parent = aclk_set_parent;
+}
+
+void __init tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq)
+{
+ int i;
+
+ xi_rate = xi_freq;
+ xti_rate = xti_freq;
+
+ /* fixup parents and add the clock */
+ for (i = 0; i < ARRAY_SIZE(lookups); i++) {
+ find_aclk_parent(lookups[i].clk);
+ clkdev_add(&lookups[i]);
+ }
+ tcc8k_timer_init(&tcz, (void __iomem *)TIMER_BASE, INT_TC32);
+}
diff --git a/arch/arm/mach-tcc8k/common.h b/arch/arm/mach-tcc8k/common.h
new file mode 100644
index 00000000..705690ad
--- /dev/null
+++ b/arch/arm/mach-tcc8k/common.h
@@ -0,0 +1,15 @@
+#ifndef MACH_TCC8K_COMMON_H
+#define MACH_TCC8K_COMMON_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device tcc_nand_device;
+
+struct clk;
+
+extern void tcc_clocks_init(unsigned long xi_freq, unsigned long xti_freq);
+extern void tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq);
+extern void tcc8k_init_irq(void);
+extern void tcc8k_map_common_io(void);
+
+#endif
diff --git a/arch/arm/mach-tcc8k/devices.c b/arch/arm/mach-tcc8k/devices.c
new file mode 100644
index 00000000..6722ad7c
--- /dev/null
+++ b/arch/arm/mach-tcc8k/devices.c
@@ -0,0 +1,239 @@
+/*
+ * linux/arch/arm/mach-tcc8k/devices.c
+ *
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of GPL v2.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static u64 tcc8k_dmamask = DMA_BIT_MASK(32);
+
+#ifdef CONFIG_MTD_NAND_TCC
+/* NAND controller */
+static struct resource tcc_nand_resources[] = {
+ {
+ .start = (resource_size_t)NFC_BASE,
+ .end = (resource_size_t)NFC_BASE + 0x7f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_NFC,
+ .end = INT_NFC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc_nand_device = {
+ .name = "tcc_nand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc_nand_resources),
+ .resource = tcc_nand_resources,
+};
+#endif
+
+#ifdef CONFIG_MMC_TCC8K
+/* MMC controller */
+static struct resource tcc8k_mmc0_resource[] = {
+ {
+ .start = INT_SD0,
+ .end = INT_SD0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tcc8k_mmc1_resource[] = {
+ {
+ .start = INT_SD1,
+ .end = INT_SD1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tcc8k_mmc0_device = {
+ .name = "tcc-mmc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc0_resource),
+ .resource = tcc8k_mmc0_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+struct platform_device tcc8k_mmc1_device = {
+ .name = "tcc-mmc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tcc8k_mmc1_resource),
+ .resource = tcc8k_mmc1_resource,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+
+static inline void tcc8k_init_mmc(void)
+{
+ u32 reg = __raw_readl(GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ reg |= GPIOPS_FS1_SDH0_BITS | GPIOPS_FS1_SDH1_BITS;
+ __raw_writel(reg, GPIOPS_BASE + GPIOPS_FS1_OFFS);
+
+ platform_device_register(&tcc8k_mmc0_device);
+ platform_device_register(&tcc8k_mmc1_device);
+}
+#else
+static inline void tcc8k_init_mmc(void) { }
+#endif
+
+#ifdef CONFIG_USB_OHCI_HCD
+static int tcc8k_ohci_init(struct device *dev)
+{
+ u32 reg;
+
+ /* Use GPIO PK19 as VBUS control output */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS0_OFFS);
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_FS1_OFFS);
+ reg &= ~(1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_FS1_OFFS);
+
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DOE_OFFS);
+ /* Turn on VBUS */
+ reg = __raw_readl(GPIOPK_BASE + GPIOPK_DAT_OFFS);
+ reg |= (1 << 19);
+ __raw_writel(reg, GPIOPK_BASE + GPIOPK_DAT_OFFS);
+
+ return 0;
+}
+
+static struct resource tcc8k_ohci0_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH0_BASE,
+ .end = (resource_size_t)USBH0_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH0,
+ .end = INT_USBH0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource tcc8k_ohci1_resources[] = {
+ [0] = {
+ .start = (resource_size_t)USBH1_BASE,
+ .end = (resource_size_t)USBH1_BASE + 0x5c,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USBH1,
+ .end = INT_USBH1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct tccohci_platform_data tcc8k_ohci0_platform_data = {
+ .controller = 0,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct tccohci_platform_data tcc8k_ohci1_platform_data = {
+ .controller = 1,
+ .port_mode = PMM_PERPORT_MODE,
+ .init = tcc8k_ohci_init,
+};
+
+static struct platform_device ohci0_device = {
+ .name = "tcc-ohci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci0_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci0_resources),
+ .resource = tcc8k_ohci0_resources,
+};
+
+static struct platform_device ohci1_device = {
+ .name = "tcc-ohci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &tcc8k_ohci1_platform_data,
+ },
+ .num_resources = ARRAY_SIZE(tcc8k_ohci1_resources),
+ .resource = tcc8k_ohci1_resources,
+};
+
+static void __init tcc8k_init_usbhost(void)
+{
+ platform_device_register(&ohci0_device);
+ platform_device_register(&ohci1_device);
+}
+#else
+static void __init tcc8k_init_usbhost(void) { }
+#endif
+
+/* USB device controller*/
+#ifdef CONFIG_USB_GADGET_TCC8K
+static struct resource udc_resources[] = {
+ [0] = {
+ .start = INT_USBD,
+ .end = INT_USBD,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = INT_UDMA,
+ .end = INT_UDMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tcc8k_udc_device = {
+ .name = "tcc-udc",
+ .id = 0,
+ .resource = udc_resources,
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .dev = {
+ .dma_mask = &tcc8k_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static void __init tcc8k_init_usb_gadget(void)
+{
+ platform_device_register(&tcc8k_udc_device);
+}
+#else
+static void __init tcc8k_init_usb_gadget(void) { }
+#endif /* CONFIG_USB_GADGET_TCC83X */
+
+static int __init tcc8k_init_devices(void)
+{
+ tcc8k_init_mmc();
+ tcc8k_init_usbhost();
+ tcc8k_init_usb_gadget();
+ return 0;
+}
+
+arch_initcall(tcc8k_init_devices);
diff --git a/arch/arm/mach-tcc8k/io.c b/arch/arm/mach-tcc8k/io.c
new file mode 100644
index 00000000..9b39d7fa
--- /dev/null
+++ b/arch/arm/mach-tcc8k/io.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-tcc8k/io.c
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * derived from TCC83xx io.c
+ * Copyright (C) Telechips, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/tcc8k-regs.h>
+
+/*
+ * The machine specific code may provide the extra mapping besides the
+ * default mapping provided here.
+ */
+static struct map_desc tcc8k_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)CS1_BASE_VIRT,
+ .pfn = __phys_to_pfn(CS1_BASE),
+ .length = CS1_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)AHB_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(AHB_PERI_BASE),
+ .length = AHB_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB0_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB0_PERI_BASE),
+ .length = APB0_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)APB1_PERI_BASE_VIRT,
+ .pfn = __phys_to_pfn(APB1_PERI_BASE),
+ .length = APB1_PERI_SIZE,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)EXT_MEM_CTRL_BASE_VIRT,
+ .pfn = __phys_to_pfn(EXT_MEM_CTRL_BASE),
+ .length = EXT_MEM_CTRL_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+/*
+ * Maps common IO regions for tcc8k.
+ *
+ */
+void __init tcc8k_map_common_io(void)
+{
+ iotable_init(tcc8k_io_desc, ARRAY_SIZE(tcc8k_io_desc));
+}
diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c
new file mode 100644
index 00000000..209fa5c6
--- /dev/null
+++ b/arch/arm/mach-tcc8k/irq.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) Telechips, Inc.
+ * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU GPL version 2.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+/* Disable IRQ */
+static void tcc8000_mask_ack_irq0(struct irq_data *d)
+{
+ PIC0_IEN &= ~(1 << d->irq);
+ PIC0_CREQ |= (1 << d->irq);
+}
+
+static void tcc8000_mask_ack_irq1(struct irq_data *d)
+{
+ PIC1_IEN &= ~(1 << (d->irq - 32));
+ PIC1_CREQ |= (1 << (d->irq - 32));
+}
+
+static void tcc8000_mask_irq0(struct irq_data *d)
+{
+ PIC0_IEN &= ~(1 << d->irq);
+}
+
+static void tcc8000_mask_irq1(struct irq_data *d)
+{
+ PIC1_IEN &= ~(1 << (d->irq - 32));
+}
+
+static void tcc8000_ack_irq0(struct irq_data *d)
+{
+ PIC0_CREQ |= (1 << d->irq);
+}
+
+static void tcc8000_ack_irq1(struct irq_data *d)
+{
+ PIC1_CREQ |= (1 << (d->irq - 32));
+}
+
+/* Enable IRQ */
+static void tcc8000_unmask_irq0(struct irq_data *d)
+{
+ PIC0_IEN |= (1 << d->irq);
+ PIC0_INTOEN |= (1 << d->irq);
+}
+
+static void tcc8000_unmask_irq1(struct irq_data *d)
+{
+ PIC1_IEN |= (1 << (d->irq - 32));
+ PIC1_INTOEN |= (1 << (d->irq - 32));
+}
+
+static struct irq_chip tcc8000_irq_chip0 = {
+ .name = "tcc_irq0",
+ .irq_mask = tcc8000_mask_irq0,
+ .irq_ack = tcc8000_ack_irq0,
+ .irq_mask_ack = tcc8000_mask_ack_irq0,
+ .irq_unmask = tcc8000_unmask_irq0,
+};
+
+static struct irq_chip tcc8000_irq_chip1 = {
+ .name = "tcc_irq1",
+ .irq_mask = tcc8000_mask_irq1,
+ .irq_ack = tcc8000_ack_irq1,
+ .irq_mask_ack = tcc8000_mask_ack_irq1,
+ .irq_unmask = tcc8000_unmask_irq1,
+};
+
+void __init tcc8k_init_irq(void)
+{
+ int irqno;
+
+ /* Mask and clear all interrupts */
+ PIC0_IEN = 0x00000000;
+ PIC0_CREQ = 0xffffffff;
+ PIC1_IEN = 0x00000000;
+ PIC1_CREQ = 0xffffffff;
+
+ PIC0_MEN0 = 0x00000003;
+ PIC1_MEN1 = 0x00000003;
+ PIC1_MEN = 0x00000003;
+
+ /* let all IRQs be level triggered */
+ PIC0_TMODE = 0xffffffff;
+ PIC1_TMODE = 0xffffffff;
+ /* all IRQs are IRQs (not FIQs) */
+ PIC0_IRQSEL = 0xffffffff;
+ PIC1_IRQSEL = 0xffffffff;
+
+ for (irqno = 0; irqno < NR_IRQS; irqno++) {
+ if (irqno < 32)
+ irq_set_chip(irqno, &tcc8000_irq_chip0);
+ else
+ irq_set_chip(irqno, &tcc8000_irq_chip1);
+ irq_set_handler(irqno, handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-tcc8k/time.c b/arch/arm/mach-tcc8k/time.c
new file mode 100644
index 00000000..a96babe8
--- /dev/null
+++ b/arch/arm/mach-tcc8k/time.c
@@ -0,0 +1,134 @@
+/*
+ * TCC8000 system timer setup
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL version 2.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach/time.h>
+
+#include <mach/tcc8k-regs.h>
+#include <mach/irqs.h>
+
+#include "common.h"
+
+static void __iomem *timer_base;
+
+static int tcc_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long reg = __raw_readl(timer_base + TC32MCNT_OFFS);
+
+ __raw_writel(reg + evt, timer_base + TC32CMP0_OFFS);
+ return 0;
+}
+
+static void tcc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long tc32irq;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_ONESHOT:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq |= TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ tc32irq = __raw_readl(timer_base + TC32IRQ_OFFS);
+ tc32irq &= ~TC32IRQ_IRQEN0;
+ __raw_writel(tc32irq, timer_base + TC32IRQ_OFFS);
+ break;
+ case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static irqreturn_t tcc8k_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ /* Acknowledge TC32 interrupt by reading TC32IRQ */
+ __raw_readl(timer_base + TC32IRQ_OFFS);
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct clock_event_device clockevent_tcc = {
+ .name = "tcc_timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = tcc_set_mode,
+ .set_next_event = tcc_set_next_event,
+ .rating = 200,
+};
+
+static struct irqaction tcc8k_timer_irq = {
+ .name = "TC32_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = tcc8k_timer_interrupt,
+ .dev_id = &clockevent_tcc,
+};
+
+static int __init tcc_clockevent_init(struct clk *clock)
+{
+ unsigned int c = clk_get_rate(clock);
+
+ clocksource_mmio_init(timer_base + TC32MCNT_OFFS, "tcc_tc32", c,
+ 200, 32, clocksource_mmio_readl_up);
+
+ clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_tcc.shift);
+ clockevent_tcc.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_tcc);
+ clockevent_tcc.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_tcc);
+
+ clockevent_tcc.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_tcc);
+
+ return 0;
+}
+
+void __init tcc8k_timer_init(struct clk *clock, void __iomem *base, int irq)
+{
+ u32 reg;
+
+ timer_base = base;
+ tcc8k_timer_irq.irq = irq;
+
+ /* Enable clocks */
+ clk_enable(clock);
+
+ /* Initialize 32-bit timer */
+ reg = __raw_readl(timer_base + TC32EN_OFFS);
+ reg &= ~TC32EN_ENABLE; /* Disable timer */
+ __raw_writel(reg, timer_base + TC32EN_OFFS);
+ /* Free running timer, counting from 0 to 0xffffffff */
+ __raw_writel(0, timer_base + TC32EN_OFFS);
+ __raw_writel(0, timer_base + TC32LDV_OFFS);
+ reg = __raw_readl(timer_base + TC32IRQ_OFFS);
+ reg |= TC32IRQ_IRQEN0; /* irq at match with CMP0 */
+ __raw_writel(reg, timer_base + TC32IRQ_OFFS);
+
+ __raw_writel(TC32EN_ENABLE, timer_base + TC32EN_OFFS);
+
+ tcc_clockevent_init(clock);
+ setup_irq(irq, &tcc8k_timer_irq);
+}
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
new file mode 100644
index 00000000..5ec1846a
--- /dev/null
+++ b/arch/arm/mach-tegra/Kconfig
@@ -0,0 +1,100 @@
+if ARCH_TEGRA
+
+comment "NVIDIA Tegra options"
+
+choice
+ prompt "Select Tegra processor family for target system"
+
+config ARCH_TEGRA_2x_SOC
+ bool "Tegra 2 family"
+ select CPU_V7
+ select ARM_GIC
+ select ARCH_REQUIRE_GPIOLIB
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
+ select USB_ULPI if USB_SUPPORT
+ select USB_ULPI_VIEWPORT if USB_SUPPORT
+ help
+ Support for NVIDIA Tegra AP20 and T20 processors, based on the
+ ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+
+endchoice
+
+config TEGRA_PCI
+ bool "PCI Express support"
+ select PCI
+
+comment "Tegra board type"
+
+config MACH_HARMONY
+ bool "Harmony board"
+ select MACH_HAS_SND_SOC_TEGRA_WM8903
+ help
+ Support for nVidia Harmony development platform
+
+config MACH_KAEN
+ bool "Kaen board"
+ select MACH_SEABOARD
+ select MACH_HAS_SND_SOC_TEGRA_WM8903
+ help
+ Support for the Kaen version of Seaboard
+
+config MACH_PAZ00
+ bool "Paz00 board"
+ help
+ Support for the Toshiba AC100/Dynabook AZ netbook
+
+config MACH_SEABOARD
+ bool "Seaboard board"
+ select MACH_HAS_SND_SOC_TEGRA_WM8903
+ help
+ Support for nVidia Seaboard development platform. It will
+ also be included for some of the derivative boards that
+ have large similarities with the seaboard design.
+
+config MACH_TRIMSLICE
+ bool "TrimSlice board"
+ select TEGRA_PCI
+ help
+ Support for CompuLab TrimSlice platform
+
+config MACH_WARIO
+ bool "Wario board"
+ select MACH_SEABOARD
+ help
+ Support for the Wario version of Seaboard
+
+choice
+ prompt "Low-level debug console UART"
+ default TEGRA_DEBUG_UART_NONE
+
+config TEGRA_DEBUG_UART_NONE
+ bool "None"
+
+config TEGRA_DEBUG_UARTA
+ bool "UART-A"
+
+config TEGRA_DEBUG_UARTB
+ bool "UART-B"
+
+config TEGRA_DEBUG_UARTC
+ bool "UART-C"
+
+config TEGRA_DEBUG_UARTD
+ bool "UART-D"
+
+config TEGRA_DEBUG_UARTE
+ bool "UART-E"
+
+endchoice
+
+config TEGRA_SYSTEM_DMA
+ bool "Enable system DMA driver for NVIDIA Tegra SoCs"
+ default y
+ help
+ Adds system DMA functionality for NVIDIA Tegra SoCs, used by
+ several Tegra device drivers
+
+config TEGRA_EMC_SCALING_ENABLE
+ bool "Enable scaling the memory frequency"
+
+endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
new file mode 100644
index 00000000..823c703e
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile
@@ -0,0 +1,34 @@
+obj-y += common.o
+obj-y += devices.o
+obj-y += io.o
+obj-y += irq.o
+obj-y += clock.o
+obj-y += timer.o
+obj-y += gpio.o
+obj-y += pinmux.o
+obj-y += powergate.o
+obj-y += fuse.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o
+obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
+obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
+obj-$(CONFIG_TEGRA_PCI) += pcie.o
+obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
+
+obj-${CONFIG_MACH_HARMONY} += board-harmony.o
+obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
+obj-${CONFIG_MACH_HARMONY} += board-harmony-pcie.o
+obj-${CONFIG_MACH_HARMONY} += board-harmony-power.o
+
+obj-${CONFIG_MACH_PAZ00} += board-paz00.o
+obj-${CONFIG_MACH_PAZ00} += board-paz00-pinmux.o
+
+obj-${CONFIG_MACH_SEABOARD} += board-seaboard.o
+obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o
+
+obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o
+obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
new file mode 100644
index 00000000..db52d61a
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000
+params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
+initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
diff --git a/arch/arm/mach-tegra/board-harmony-pcie.c b/arch/arm/mach-tegra/board-harmony-pcie.c
new file mode 100644
index 00000000..9c27b95b
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pcie.c
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/mach-tegra/board-harmony-pcie.c
+ *
+ * Copyright (C) 2010 CompuLab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+
+#include <asm/mach-types.h>
+
+#include <mach/pinmux.h>
+#include "board.h"
+
+#ifdef CONFIG_TEGRA_PCI
+
+/* GPIO 3 of the PMIC */
+#define EN_VDD_1V05_GPIO (TEGRA_NR_GPIOS + 2)
+
+static int __init harmony_pcie_init(void)
+{
+ struct regulator *regulator = NULL;
+ int err;
+
+ if (!machine_is_harmony())
+ return 0;
+
+ err = gpio_request(EN_VDD_1V05_GPIO, "EN_VDD_1V05");
+ if (err)
+ return err;
+
+ gpio_direction_output(EN_VDD_1V05_GPIO, 1);
+
+ regulator = regulator_get(NULL, "pex_clk");
+ if (IS_ERR_OR_NULL(regulator))
+ goto err_reg;
+
+ regulator_enable(regulator);
+
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_NORMAL);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_NORMAL);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_NORMAL);
+
+ err = tegra_pcie_init(true, true);
+ if (err)
+ goto err_pcie;
+
+ return 0;
+
+err_pcie:
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_GPV, TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXA, TEGRA_TRI_TRISTATE);
+ tegra_pinmux_set_tristate(TEGRA_PINGROUP_SLXK, TEGRA_TRI_TRISTATE);
+
+ regulator_disable(regulator);
+ regulator_put(regulator);
+err_reg:
+ gpio_free(EN_VDD_1V05_GPIO);
+
+ return err;
+}
+
+/* PCI should be initialized after I2C, mfd and regulators */
+subsys_initcall_sync(harmony_pcie_init);
+
+#endif
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
new file mode 100644
index 00000000..4d63e2e9
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -0,0 +1,161 @@
+/*
+ * arch/arm/mach-tegra/board-harmony-pinmux.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 <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/pinmux.h>
+
+#include "gpio-names.h"
+#include "board-harmony.h"
+
+static struct tegra_pingroup_config harmony_pinmux[] = {
+ {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+};
+
+static struct tegra_gpio_table gpio_table[] = {
+ { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
+ { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
+ { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
+ { .gpio = TEGRA_GPIO_CDC_IRQ, .enable = true },
+ { .gpio = TEGRA_GPIO_HP_DET, .enable = true },
+ { .gpio = TEGRA_GPIO_INT_MIC_EN, .enable = true },
+ { .gpio = TEGRA_GPIO_EXT_MIC_EN, .enable = true },
+};
+
+void harmony_pinmux_init(void)
+{
+ tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
+
+ tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
+}
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
new file mode 100644
index 00000000..5ad8b2f9
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 NVIDIA, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/platform_device.h>
+#include <linux/gpio.h>
+
+#include <linux/regulator/machine.h>
+#include <linux/mfd/tps6586x.h>
+
+#include <mach/irqs.h>
+
+#include "board-harmony.h"
+
+#define PMC_CTRL 0x0
+#define PMC_CTRL_INTR_LOW (1 << 17)
+
+static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
+ REGULATOR_SUPPLY("pex_clk", NULL),
+};
+
+static struct regulator_init_data ldo0_data = {
+ .constraints = {
+ .min_uV = 1250 * 1000,
+ .max_uV = 3300 * 1000,
+ .valid_modes_mask = (REGULATOR_MODE_NORMAL |
+ REGULATOR_MODE_STANDBY),
+ .valid_ops_mask = (REGULATOR_CHANGE_MODE |
+ REGULATOR_CHANGE_STATUS |
+ REGULATOR_CHANGE_VOLTAGE),
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply),
+ .consumer_supplies = tps658621_ldo0_supply,
+};
+
+#define HARMONY_REGULATOR_INIT(_id, _minmv, _maxmv) \
+ static struct regulator_init_data _id##_data = { \
+ .constraints = { \
+ .min_uV = (_minmv)*1000, \
+ .max_uV = (_maxmv)*1000, \
+ .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
+ REGULATOR_MODE_STANDBY), \
+ .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
+ REGULATOR_CHANGE_STATUS | \
+ REGULATOR_CHANGE_VOLTAGE), \
+ }, \
+ }
+
+HARMONY_REGULATOR_INIT(sm0, 725, 1500);
+HARMONY_REGULATOR_INIT(sm1, 725, 1500);
+HARMONY_REGULATOR_INIT(sm2, 3000, 4550);
+HARMONY_REGULATOR_INIT(ldo1, 725, 1500);
+HARMONY_REGULATOR_INIT(ldo2, 725, 1500);
+HARMONY_REGULATOR_INIT(ldo3, 1250, 3300);
+HARMONY_REGULATOR_INIT(ldo4, 1700, 2475);
+HARMONY_REGULATOR_INIT(ldo5, 1250, 3300);
+HARMONY_REGULATOR_INIT(ldo6, 1250, 3300);
+HARMONY_REGULATOR_INIT(ldo7, 1250, 3300);
+HARMONY_REGULATOR_INIT(ldo8, 1250, 3300);
+HARMONY_REGULATOR_INIT(ldo9, 1250, 3300);
+
+#define TPS_REG(_id, _data) \
+ { \
+ .id = TPS6586X_ID_##_id, \
+ .name = "tps6586x-regulator", \
+ .platform_data = _data, \
+ }
+
+static struct tps6586x_subdev_info tps_devs[] = {
+ TPS_REG(SM_0, &sm0_data),
+ TPS_REG(SM_1, &sm1_data),
+ TPS_REG(SM_2, &sm2_data),
+ TPS_REG(LDO_0, &ldo0_data),
+ TPS_REG(LDO_1, &ldo1_data),
+ TPS_REG(LDO_2, &ldo2_data),
+ TPS_REG(LDO_3, &ldo3_data),
+ TPS_REG(LDO_4, &ldo4_data),
+ TPS_REG(LDO_5, &ldo5_data),
+ TPS_REG(LDO_6, &ldo6_data),
+ TPS_REG(LDO_7, &ldo7_data),
+ TPS_REG(LDO_8, &ldo8_data),
+ TPS_REG(LDO_9, &ldo9_data),
+};
+
+static struct tps6586x_platform_data tps_platform = {
+ .irq_base = TEGRA_NR_IRQS,
+ .num_subdevs = ARRAY_SIZE(tps_devs),
+ .subdevs = tps_devs,
+ .gpio_base = HARMONY_GPIO_TPS6586X(0),
+};
+
+static struct i2c_board_info __initdata harmony_regulators[] = {
+ {
+ I2C_BOARD_INFO("tps6586x", 0x34),
+ .irq = INT_EXTERNAL_PMU,
+ .platform_data = &tps_platform,
+ },
+};
+
+int __init harmony_regulator_init(void)
+{
+ i2c_register_board_info(3, harmony_regulators, 1);
+
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 00000000..30e18bc6
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,211 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 NVIDIA, 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/pda_power.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+
+#include <sound/wm8903.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/tegra_wm8903_pdata.h>
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/sdhci.h>
+
+#include "board.h"
+#include "board-harmony.h"
+#include "clock.h"
+#include "devices.h"
+#include "gpio-names.h"
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
+ .mapbase = TEGRA_UARTD_BASE,
+ .irq = INT_UARTD,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+
+static struct tegra_wm8903_platform_data harmony_audio_pdata = {
+ .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
+ .gpio_hp_det = TEGRA_GPIO_HP_DET,
+ .gpio_hp_mute = -1,
+ .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
+ .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
+};
+
+static struct platform_device harmony_audio_device = {
+ .name = "tegra-snd-wm8903",
+ .id = 0,
+ .dev = {
+ .platform_data = &harmony_audio_pdata,
+ },
+};
+
+static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct wm8903_platform_data harmony_wm8903_pdata = {
+ .irq_active_low = 0,
+ .micdet_cfg = 0,
+ .micdet_delay = 100,
+ .gpio_base = HARMONY_GPIO_WM8903(0),
+ .gpio_cfg = {
+ WM8903_GPIO_NO_CONFIG,
+ WM8903_GPIO_NO_CONFIG,
+ 0,
+ WM8903_GPIO_NO_CONFIG,
+ WM8903_GPIO_NO_CONFIG,
+ },
+};
+
+static struct i2c_board_info __initdata wm8903_board_info = {
+ I2C_BOARD_INFO("wm8903", 0x1a),
+ .platform_data = &harmony_wm8903_pdata,
+ .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
+};
+
+static void __init harmony_i2c_init(void)
+{
+ tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data;
+ tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data;
+ tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data;
+ tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data;
+
+ platform_device_register(&tegra_i2c_device1);
+ platform_device_register(&tegra_i2c_device2);
+ platform_device_register(&tegra_i2c_device3);
+ platform_device_register(&tegra_i2c_device4);
+
+ i2c_register_board_info(0, &wm8903_board_info, 1);
+}
+
+static struct platform_device *harmony_devices[] __initdata = {
+ &debug_uart,
+ &tegra_sdhci_device1,
+ &tegra_sdhci_device2,
+ &tegra_sdhci_device4,
+ &tegra_i2s_device1,
+ &tegra_das_device,
+ &tegra_pcm_device,
+ &harmony_audio_device,
+};
+
+static void __init tegra_harmony_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 2;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = 448 * SZ_1M;
+ mi->bank[1].start = SZ_512M;
+ mi->bank[1].size = SZ_512M;
+}
+
+static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "uartd", "pll_p", 216000000, true },
+ { "pll_a", "pll_p_out1", 56448000, true },
+ { "pll_a_out0", "pll_a", 11289600, true },
+ { "cdev1", NULL, 0, true },
+ { "i2s1", "pll_a_out0", 11289600, false},
+ { NULL, NULL, 0, 0},
+};
+
+
+static struct tegra_sdhci_platform_data sdhci_pdata1 = {
+ .cd_gpio = -1,
+ .wp_gpio = -1,
+ .power_gpio = -1,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata2 = {
+ .cd_gpio = TEGRA_GPIO_SD2_CD,
+ .wp_gpio = TEGRA_GPIO_SD2_WP,
+ .power_gpio = TEGRA_GPIO_SD2_POWER,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata4 = {
+ .cd_gpio = TEGRA_GPIO_SD4_CD,
+ .wp_gpio = TEGRA_GPIO_SD4_WP,
+ .power_gpio = TEGRA_GPIO_SD4_POWER,
+ .is_8bit = 1,
+};
+
+static void __init tegra_harmony_init(void)
+{
+ tegra_clk_init_from_table(harmony_clk_init_table);
+
+ harmony_pinmux_init();
+
+ tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
+ tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
+ tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
+
+ platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
+ harmony_i2c_init();
+ harmony_regulator_init();
+}
+
+MACHINE_START(HARMONY, "harmony")
+ .boot_params = 0x00000100,
+ .fixup = tegra_harmony_fixup,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_harmony_init,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
new file mode 100644
index 00000000..d85142ed
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_BOARD_HARMONY_H
+#define _MACH_TEGRA_BOARD_HARMONY_H
+
+#define HARMONY_GPIO_TPS6586X(_x_) (TEGRA_NR_GPIOS + (_x_))
+#define HARMONY_GPIO_WM8903(_x_) (HARMONY_GPIO_TPS6586X(4) + (_x_))
+
+#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
+#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
+#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PT3
+#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
+#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
+#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
+#define TEGRA_GPIO_CDC_IRQ TEGRA_GPIO_PX3
+#define TEGRA_GPIO_SPKR_EN HARMONY_GPIO_WM8903(2)
+#define TEGRA_GPIO_HP_DET TEGRA_GPIO_PW2
+#define TEGRA_GPIO_INT_MIC_EN TEGRA_GPIO_PX0
+#define TEGRA_GPIO_EXT_MIC_EN TEGRA_GPIO_PX1
+
+void harmony_pinmux_init(void);
+int harmony_regulator_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/board-paz00-pinmux.c b/arch/arm/mach-tegra/board-paz00-pinmux.c
new file mode 100644
index 00000000..2643d1bd
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00-pinmux.c
@@ -0,0 +1,157 @@
+/*
+ * arch/arm/mach-tegra/board-paz00-pinmux.c
+ *
+ * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/pinmux.h>
+
+#include "gpio-names.h"
+#include "board-paz00.h"
+
+static struct tegra_pingroup_config paz00_pinmux[] = {
+ {TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CSUS, TEGRA_MUX_PLLC_OUT1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP2, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_RSVD1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCB, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_OWC, TEGRA_MUX_OWR, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDC, TEGRA_MUX_TWC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPI4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPID, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIE, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIF, TEGRA_MUX_RSVD4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAD, TEGRA_MUX_SPDIF, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+};
+
+static struct tegra_gpio_table gpio_table[] = {
+ { .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
+ { .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
+ { .gpio = TEGRA_GPIO_SD1_POWER, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_CD, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_WP, .enable = true },
+ { .gpio = TEGRA_GPIO_SD4_POWER, .enable = true },
+};
+
+void paz00_pinmux_init(void)
+{
+ tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
+
+ tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
+}
diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c
new file mode 100644
index 00000000..57e50a82
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.c
@@ -0,0 +1,128 @@
+/*
+ * arch/arm/mach-tegra/board-paz00.c
+ *
+ * Copyright (C) 2011 Marc Dietrich <marvin24@gmx.de>
+ *
+ * Based on board-harmony.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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/pda_power.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/sdhci.h>
+
+#include "board.h"
+#include "board-paz00.h"
+#include "clock.h"
+#include "devices.h"
+#include "gpio-names.h"
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
+ .mapbase = TEGRA_UARTD_BASE,
+ .irq = INT_UARTD,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+
+static struct platform_device *paz00_devices[] __initdata = {
+ &debug_uart,
+ &tegra_sdhci_device1,
+ &tegra_sdhci_device2,
+ &tegra_sdhci_device4,
+};
+
+static void __init tegra_paz00_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = 448 * SZ_1M;
+}
+
+static __initdata struct tegra_clk_init_table paz00_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "uartd", "pll_p", 216000000, true },
+ { NULL, NULL, 0, 0},
+};
+
+
+static struct tegra_sdhci_platform_data sdhci_pdata1 = {
+ .cd_gpio = TEGRA_GPIO_SD1_CD,
+ .wp_gpio = TEGRA_GPIO_SD1_WP,
+ .power_gpio = TEGRA_GPIO_SD1_POWER,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata2 = {
+ .cd_gpio = -1,
+ .wp_gpio = -1,
+ .power_gpio = -1,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata4 = {
+ .cd_gpio = TEGRA_GPIO_SD4_CD,
+ .wp_gpio = TEGRA_GPIO_SD4_WP,
+ .power_gpio = TEGRA_GPIO_SD4_POWER,
+ .is_8bit = 1,
+};
+
+static void __init tegra_paz00_init(void)
+{
+ tegra_clk_init_from_table(paz00_clk_init_table);
+
+ paz00_pinmux_init();
+
+ tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
+ tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
+ tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
+
+ platform_add_devices(paz00_devices, ARRAY_SIZE(paz00_devices));
+}
+
+MACHINE_START(PAZ00, "paz00")
+ .boot_params = 0x00000100,
+ .fixup = tegra_paz00_fixup,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_paz00_init,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-paz00.h b/arch/arm/mach-tegra/board-paz00.h
new file mode 100644
index 00000000..da193ca7
--- /dev/null
+++ b/arch/arm/mach-tegra/board-paz00.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-tegra/board-paz00.h
+ *
+ * Copyright (C) 2010 Marc Dietrich <marvin24@gmx.de>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_BOARD_PAZ00_H
+#define _MACH_TEGRA_BOARD_PAZ00_H
+
+#define TEGRA_GPIO_SD1_CD TEGRA_GPIO_PV5
+#define TEGRA_GPIO_SD1_WP TEGRA_GPIO_PH1
+#define TEGRA_GPIO_SD1_POWER TEGRA_GPIO_PT3
+#define TEGRA_GPIO_SD4_CD TEGRA_GPIO_PH2
+#define TEGRA_GPIO_SD4_WP TEGRA_GPIO_PH3
+#define TEGRA_GPIO_SD4_POWER TEGRA_GPIO_PI6
+
+void paz00_pinmux_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/board-seaboard-pinmux.c b/arch/arm/mach-tegra/board-seaboard-pinmux.c
new file mode 100644
index 00000000..0bda495e
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard-pinmux.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/gpio.h>
+
+#include <mach/pinmux.h>
+#include <mach/pinmux-t2.h>
+
+#include "gpio-names.h"
+#include "board-seaboard.h"
+
+#define DEFAULT_DRIVE(_name) \
+ { \
+ .pingroup = TEGRA_DRIVE_PINGROUP_##_name, \
+ .hsm = TEGRA_HSM_DISABLE, \
+ .schmitt = TEGRA_SCHMITT_ENABLE, \
+ .drive = TEGRA_DRIVE_DIV_1, \
+ .pull_down = TEGRA_PULL_31, \
+ .pull_up = TEGRA_PULL_31, \
+ .slew_rising = TEGRA_SLEW_SLOWEST, \
+ .slew_falling = TEGRA_SLEW_SLOWEST, \
+ }
+
+static __initdata struct tegra_drive_pingroup_config seaboard_drive_pinmux[] = {
+ DEFAULT_DRIVE(SDIO1),
+};
+
+static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
+ {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_PLLA_OUT, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LCSN, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDC, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM1, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDI, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVP0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDB, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+};
+
+
+
+
+static struct tegra_gpio_table gpio_table[] = {
+ { .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
+ { .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
+ { .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
+ { .gpio = TEGRA_GPIO_LIDSWITCH, .enable = true },
+ { .gpio = TEGRA_GPIO_POWERKEY, .enable = true },
+ { .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
+};
+
+void __init seaboard_pinmux_init(void)
+{
+ tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
+
+ tegra_drive_pinmux_config_table(seaboard_drive_pinmux,
+ ARRAY_SIZE(seaboard_drive_pinmux));
+
+ tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
+}
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
new file mode 100644
index 00000000..a8d7ace9
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2010, 2011 NVIDIA Corporation.
+ * Copyright (C) 2010, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/sdhci.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "board.h"
+#include "board-seaboard.h"
+#include "clock.h"
+#include "devices.h"
+#include "gpio-names.h"
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ /* Memory and IRQ filled in before registration */
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+ }, {
+ .flags = 0,
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+
+static __initdata struct tegra_clk_init_table seaboard_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "uartb", "pll_p", 216000000, true},
+ { "uartd", "pll_p", 216000000, true},
+ { NULL, NULL, 0, 0},
+};
+
+static struct tegra_i2c_platform_data seaboard_i2c1_platform_data = {
+ .bus_clk_rate = 400000.
+};
+
+static struct tegra_i2c_platform_data seaboard_i2c2_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct tegra_i2c_platform_data seaboard_i2c3_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct tegra_i2c_platform_data seaboard_dvc_platform_data = {
+ .bus_clk_rate = 400000,
+};
+
+static struct gpio_keys_button seaboard_gpio_keys_buttons[] = {
+ {
+ .code = SW_LID,
+ .gpio = TEGRA_GPIO_LIDSWITCH,
+ .active_low = 0,
+ .desc = "Lid",
+ .type = EV_SW,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+ {
+ .code = KEY_POWER,
+ .gpio = TEGRA_GPIO_POWERKEY,
+ .active_low = 1,
+ .desc = "Power",
+ .type = EV_KEY,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data seaboard_gpio_keys = {
+ .buttons = seaboard_gpio_keys_buttons,
+ .nbuttons = ARRAY_SIZE(seaboard_gpio_keys_buttons),
+};
+
+static struct platform_device seaboard_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &seaboard_gpio_keys,
+ }
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata1 = {
+ .cd_gpio = -1,
+ .wp_gpio = -1,
+ .power_gpio = -1,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata3 = {
+ .cd_gpio = TEGRA_GPIO_SD2_CD,
+ .wp_gpio = TEGRA_GPIO_SD2_WP,
+ .power_gpio = TEGRA_GPIO_SD2_POWER,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata4 = {
+ .cd_gpio = -1,
+ .wp_gpio = -1,
+ .power_gpio = -1,
+ .is_8bit = 1,
+};
+
+static struct platform_device *seaboard_devices[] __initdata = {
+ &debug_uart,
+ &tegra_pmu_device,
+ &tegra_sdhci_device1,
+ &tegra_sdhci_device3,
+ &tegra_sdhci_device4,
+ &seaboard_gpio_keys_device,
+};
+
+static struct i2c_board_info __initdata isl29018_device = {
+ I2C_BOARD_INFO("isl29018", 0x44),
+ .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
+};
+
+static struct i2c_board_info __initdata adt7461_device = {
+ I2C_BOARD_INFO("adt7461", 0x4c),
+};
+
+static void __init seaboard_i2c_init(void)
+{
+ gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
+ gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
+
+ i2c_register_board_info(0, &isl29018_device, 1);
+
+ i2c_register_board_info(4, &adt7461_device, 1);
+
+ tegra_i2c_device1.dev.platform_data = &seaboard_i2c1_platform_data;
+ tegra_i2c_device2.dev.platform_data = &seaboard_i2c2_platform_data;
+ tegra_i2c_device3.dev.platform_data = &seaboard_i2c3_platform_data;
+ tegra_i2c_device4.dev.platform_data = &seaboard_dvc_platform_data;
+
+ platform_device_register(&tegra_i2c_device1);
+ platform_device_register(&tegra_i2c_device2);
+ platform_device_register(&tegra_i2c_device3);
+ platform_device_register(&tegra_i2c_device4);
+}
+
+static void __init seaboard_common_init(void)
+{
+ seaboard_pinmux_init();
+
+ tegra_clk_init_from_table(seaboard_clk_init_table);
+
+ tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
+ tegra_sdhci_device3.dev.platform_data = &sdhci_pdata3;
+ tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
+
+ platform_add_devices(seaboard_devices, ARRAY_SIZE(seaboard_devices));
+}
+
+static void __init tegra_seaboard_init(void)
+{
+ /* Seaboard uses UARTD for the debug port. */
+ debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTD_BASE);
+ debug_uart_platform_data[0].mapbase = TEGRA_UARTD_BASE;
+ debug_uart_platform_data[0].irq = INT_UARTD;
+
+ seaboard_common_init();
+
+ seaboard_i2c_init();
+}
+
+static void __init tegra_kaen_init(void)
+{
+ /* Kaen uses UARTB for the debug port. */
+ debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
+ debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
+ debug_uart_platform_data[0].irq = INT_UARTB;
+
+ seaboard_common_init();
+
+ seaboard_i2c_init();
+}
+
+static void __init tegra_wario_init(void)
+{
+ /* Wario uses UARTB for the debug port. */
+ debug_uart_platform_data[0].membase = IO_ADDRESS(TEGRA_UARTB_BASE);
+ debug_uart_platform_data[0].mapbase = TEGRA_UARTB_BASE;
+ debug_uart_platform_data[0].irq = INT_UARTB;
+
+ seaboard_common_init();
+
+ seaboard_i2c_init();
+}
+
+
+MACHINE_START(SEABOARD, "seaboard")
+ .boot_params = 0x00000100,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_seaboard_init,
+MACHINE_END
+
+MACHINE_START(KAEN, "kaen")
+ .boot_params = 0x00000100,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_kaen_init,
+MACHINE_END
+
+MACHINE_START(WARIO, "wario")
+ .boot_params = 0x00000100,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_wario_init,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-seaboard.h b/arch/arm/mach-tegra/board-seaboard.h
new file mode 100644
index 00000000..d8415e1a
--- /dev/null
+++ b/arch/arm/mach-tegra/board-seaboard.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-tegra/board-seaboard.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_BOARD_SEABOARD_H
+#define _MACH_TEGRA_BOARD_SEABOARD_H
+
+#define TEGRA_GPIO_SD2_CD TEGRA_GPIO_PI5
+#define TEGRA_GPIO_SD2_WP TEGRA_GPIO_PH1
+#define TEGRA_GPIO_SD2_POWER TEGRA_GPIO_PI6
+#define TEGRA_GPIO_LIDSWITCH TEGRA_GPIO_PC7
+#define TEGRA_GPIO_USB1 TEGRA_GPIO_PD0
+#define TEGRA_GPIO_POWERKEY TEGRA_GPIO_PV2
+#define TEGRA_GPIO_BACKLIGHT TEGRA_GPIO_PD4
+#define TEGRA_GPIO_LVDS_SHUTDOWN TEGRA_GPIO_PB2
+#define TEGRA_GPIO_BACKLIGHT_PWM TEGRA_GPIO_PU5
+#define TEGRA_GPIO_BACKLIGHT_VDD TEGRA_GPIO_PW0
+#define TEGRA_GPIO_EN_VDD_PNL TEGRA_GPIO_PC6
+#define TEGRA_GPIO_MAGNETOMETER TEGRA_GPIO_PN5
+#define TEGRA_GPIO_ISL29018_IRQ TEGRA_GPIO_PZ2
+#define TEGRA_GPIO_AC_ONLINE TEGRA_GPIO_PV3
+
+#define TPS_GPIO_BASE TEGRA_NR_GPIOS
+
+#define TPS_GPIO_WWAN_PWR (TPS_GPIO_BASE + 2)
+
+void seaboard_pinmux_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/board-trimslice-pinmux.c b/arch/arm/mach-tegra/board-trimslice-pinmux.c
new file mode 100644
index 00000000..13534fa0
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice-pinmux.c
@@ -0,0 +1,154 @@
+/*
+ * arch/arm/mach-tegra/board-trimslice-pinmux.c
+ *
+ * Copyright (C) 2011 CompuLab, 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <mach/pinmux.h>
+#include <mach/gpio.h>
+
+#include "gpio-names.h"
+#include "board-trimslice.h"
+
+static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
+ {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTE, TEGRA_MUX_VI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMB, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GMC, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GME, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GPU, TEGRA_MUX_UARTA, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTB, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPDI, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDO, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIB, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_SPI2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+};
+
+static struct tegra_gpio_table gpio_table[] = {
+ { .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
+ { .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
+};
+
+void __init trimslice_pinmux_init(void)
+{
+ tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
+ tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
+}
diff --git a/arch/arm/mach-tegra/board-trimslice.c b/arch/arm/mach-tegra/board-trimslice.c
new file mode 100644
index 00000000..cda4cfd7
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.c
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-tegra/board-trimslice.c
+ *
+ * Copyright (C) 2011 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on board-harmony.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 <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/setup.h>
+
+#include <mach/iomap.h>
+#include <mach/sdhci.h>
+
+#include "board.h"
+#include "clock.h"
+#include "devices.h"
+#include "gpio-names.h"
+
+#include "board-trimslice.h"
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ .membase = IO_ADDRESS(TEGRA_UARTA_BASE),
+ .mapbase = TEGRA_UARTA_BASE,
+ .irq = INT_UARTA,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+static struct tegra_sdhci_platform_data sdhci_pdata1 = {
+ .cd_gpio = -1,
+ .wp_gpio = -1,
+ .power_gpio = -1,
+};
+
+static struct tegra_sdhci_platform_data sdhci_pdata4 = {
+ .cd_gpio = TRIMSLICE_GPIO_SD4_CD,
+ .wp_gpio = TRIMSLICE_GPIO_SD4_WP,
+ .power_gpio = -1,
+};
+
+static struct platform_device *trimslice_devices[] __initdata = {
+ &debug_uart,
+ &tegra_sdhci_device1,
+ &tegra_sdhci_device4,
+};
+
+static void __init tegra_trimslice_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 2;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = 448 * SZ_1M;
+ mi->bank[1].start = SZ_512M;
+ mi->bank[1].size = SZ_512M;
+}
+
+static __initdata struct tegra_clk_init_table trimslice_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "uarta", "pll_p", 216000000, true },
+ { NULL, NULL, 0, 0},
+};
+
+static int __init tegra_trimslice_pci_init(void)
+{
+ if (!machine_is_trimslice())
+ return 0;
+
+ return tegra_pcie_init(true, true);
+}
+subsys_initcall(tegra_trimslice_pci_init);
+
+static void __init tegra_trimslice_init(void)
+{
+ tegra_clk_init_from_table(trimslice_clk_init_table);
+
+ trimslice_pinmux_init();
+
+ tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
+ tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
+
+ platform_add_devices(trimslice_devices, ARRAY_SIZE(trimslice_devices));
+}
+
+MACHINE_START(TRIMSLICE, "trimslice")
+ .boot_params = 0x00000100,
+ .fixup = tegra_trimslice_fixup,
+ .map_io = tegra_map_common_io,
+ .init_early = tegra_init_early,
+ .init_irq = tegra_init_irq,
+ .timer = &tegra_timer,
+ .init_machine = tegra_trimslice_init,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-trimslice.h b/arch/arm/mach-tegra/board-trimslice.h
new file mode 100644
index 00000000..e8ef6291
--- /dev/null
+++ b/arch/arm/mach-tegra/board-trimslice.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-tegra/board-trimslice.h
+ *
+ * Copyright (C) 2011 CompuLab, 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_TEGRA_BOARD_TRIMSLICE_H
+#define _MACH_TEGRA_BOARD_TRIMSLICE_H
+
+#define TRIMSLICE_GPIO_SD4_CD TEGRA_GPIO_PP1 /* mmc4 cd */
+#define TRIMSLICE_GPIO_SD4_WP TEGRA_GPIO_PP2 /* mmc4 wp */
+
+void trimslice_pinmux_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
new file mode 100644
index 00000000..1d14df7e
--- /dev/null
+++ b/arch/arm/mach-tegra/board.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-tegra/board.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_BOARD_H
+#define __MACH_TEGRA_BOARD_H
+
+#include <linux/types.h>
+
+void tegra_assert_system_reset(char mode, const char *cmd);
+
+void __init tegra_init_early(void);
+void __init tegra_map_common_io(void);
+void __init tegra_init_irq(void);
+void __init tegra_init_clock(void);
+int __init tegra_pcie_init(bool init_port0, bool init_port1);
+
+extern struct sys_timer tegra_timer;
+#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
new file mode 100644
index 00000000..e028320a
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.c
@@ -0,0 +1,671 @@
+/*
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include <mach/clk.h>
+
+#include "board.h"
+#include "clock.h"
+
+/*
+ * Locking:
+ *
+ * Each struct clk has a spinlock.
+ *
+ * To avoid AB-BA locking problems, locks must always be traversed from child
+ * clock to parent clock. For example, when enabling a clock, the clock's lock
+ * is taken, and then clk_enable is called on the parent, which take's the
+ * parent clock's lock. There is one exceptions to this ordering: When dumping
+ * the clock tree through debugfs. In this case, clk_lock_all is called,
+ * which attemps to iterate through the entire list of clocks and take every
+ * clock lock. If any call to spin_trylock fails, all locked clocks are
+ * unlocked, and the process is retried. When all the locks are held,
+ * the only clock operation that can be called is clk_get_rate_all_locked.
+ *
+ * Within a single clock, no clock operation can call another clock operation
+ * on itself, except for clk_get_rate_locked and clk_set_rate_locked. Any
+ * clock operation can call any other clock operation on any of it's possible
+ * parents.
+ *
+ * An additional mutex, clock_list_lock, is used to protect the list of all
+ * clocks.
+ *
+ * The clock operations must lock internally to protect against
+ * read-modify-write on registers that are shared by multiple clocks
+ */
+static DEFINE_MUTEX(clock_list_lock);
+static LIST_HEAD(clocks);
+
+struct clk *tegra_get_clock_by_name(const char *name)
+{
+ struct clk *c;
+ struct clk *ret = NULL;
+ mutex_lock(&clock_list_lock);
+ list_for_each_entry(c, &clocks, node) {
+ if (strcmp(c->name, name) == 0) {
+ ret = c;
+ break;
+ }
+ }
+ mutex_unlock(&clock_list_lock);
+ return ret;
+}
+
+/* Must be called with c->spinlock held */
+static unsigned long clk_predict_rate_from_parent(struct clk *c, struct clk *p)
+{
+ u64 rate;
+
+ rate = clk_get_rate(p);
+
+ if (c->mul != 0 && c->div != 0) {
+ rate *= c->mul;
+ rate += c->div - 1; /* round up */
+ do_div(rate, c->div);
+ }
+
+ return rate;
+}
+
+/* Must be called with c->spinlock held */
+unsigned long clk_get_rate_locked(struct clk *c)
+{
+ unsigned long rate;
+
+ if (c->parent)
+ rate = clk_predict_rate_from_parent(c, c->parent);
+ else
+ rate = c->rate;
+
+ return rate;
+}
+
+unsigned long clk_get_rate(struct clk *c)
+{
+ unsigned long flags;
+ unsigned long rate;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ rate = clk_get_rate_locked(c);
+
+ spin_unlock_irqrestore(&c->spinlock, flags);
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+int clk_reparent(struct clk *c, struct clk *parent)
+{
+ c->parent = parent;
+ return 0;
+}
+
+void clk_init(struct clk *c)
+{
+ spin_lock_init(&c->spinlock);
+
+ if (c->ops && c->ops->init)
+ c->ops->init(c);
+
+ if (!c->ops || !c->ops->enable) {
+ c->refcnt++;
+ c->set = true;
+ if (c->parent)
+ c->state = c->parent->state;
+ else
+ c->state = ON;
+ }
+
+ mutex_lock(&clock_list_lock);
+ list_add(&c->node, &clocks);
+ mutex_unlock(&clock_list_lock);
+}
+
+int clk_enable(struct clk *c)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ if (c->refcnt == 0) {
+ if (c->parent) {
+ ret = clk_enable(c->parent);
+ if (ret)
+ goto out;
+ }
+
+ if (c->ops && c->ops->enable) {
+ ret = c->ops->enable(c);
+ if (ret) {
+ if (c->parent)
+ clk_disable(c->parent);
+ goto out;
+ }
+ c->state = ON;
+ c->set = true;
+ }
+ }
+ c->refcnt++;
+out:
+ spin_unlock_irqrestore(&c->spinlock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ if (c->refcnt == 0) {
+ WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
+ spin_unlock_irqrestore(&c->spinlock, flags);
+ return;
+ }
+ if (c->refcnt == 1) {
+ if (c->ops && c->ops->disable)
+ c->ops->disable(c);
+
+ if (c->parent)
+ clk_disable(c->parent);
+
+ c->state = OFF;
+ }
+ c->refcnt--;
+
+ spin_unlock_irqrestore(&c->spinlock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_set_parent(struct clk *c, struct clk *parent)
+{
+ int ret;
+ unsigned long flags;
+ unsigned long new_rate;
+ unsigned long old_rate;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ if (!c->ops || !c->ops->set_parent) {
+ ret = -ENOSYS;
+ goto out;
+ }
+
+ new_rate = clk_predict_rate_from_parent(c, parent);
+ old_rate = clk_get_rate_locked(c);
+
+ ret = c->ops->set_parent(c, parent);
+ if (ret)
+ goto out;
+
+out:
+ spin_unlock_irqrestore(&c->spinlock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *c)
+{
+ return c->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_rate_locked(struct clk *c, unsigned long rate)
+{
+ long new_rate;
+
+ if (!c->ops || !c->ops->set_rate)
+ return -ENOSYS;
+
+ if (rate > c->max_rate)
+ rate = c->max_rate;
+
+ if (c->ops && c->ops->round_rate) {
+ new_rate = c->ops->round_rate(c, rate);
+
+ if (new_rate < 0)
+ return new_rate;
+
+ rate = new_rate;
+ }
+
+ return c->ops->set_rate(c, rate);
+}
+
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ ret = clk_set_rate_locked(c, rate);
+
+ spin_unlock_irqrestore(&c->spinlock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+
+/* Must be called with clocks lock and all indvidual clock locks held */
+unsigned long clk_get_rate_all_locked(struct clk *c)
+{
+ u64 rate;
+ int mul = 1;
+ int div = 1;
+ struct clk *p = c;
+
+ while (p) {
+ c = p;
+ if (c->mul != 0 && c->div != 0) {
+ mul *= c->mul;
+ div *= c->div;
+ }
+ p = c->parent;
+ }
+
+ rate = c->rate;
+ rate *= mul;
+ do_div(rate, div);
+
+ return rate;
+}
+
+long clk_round_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long flags;
+ long ret;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+
+ if (!c->ops || !c->ops->round_rate) {
+ ret = -ENOSYS;
+ goto out;
+ }
+
+ if (rate > c->max_rate)
+ rate = c->max_rate;
+
+ ret = c->ops->round_rate(c, rate);
+
+out:
+ spin_unlock_irqrestore(&c->spinlock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
+{
+ struct clk *c;
+ struct clk *p;
+
+ int ret = 0;
+
+ c = tegra_get_clock_by_name(table->name);
+
+ if (!c) {
+ pr_warning("Unable to initialize clock %s\n",
+ table->name);
+ return -ENODEV;
+ }
+
+ if (table->parent) {
+ p = tegra_get_clock_by_name(table->parent);
+ if (!p) {
+ pr_warning("Unable to find parent %s of clock %s\n",
+ table->parent, table->name);
+ return -ENODEV;
+ }
+
+ if (c->parent != p) {
+ ret = clk_set_parent(c, p);
+ if (ret) {
+ pr_warning("Unable to set parent %s of clock %s: %d\n",
+ table->parent, table->name, ret);
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (table->rate && table->rate != clk_get_rate(c)) {
+ ret = clk_set_rate(c, table->rate);
+ if (ret) {
+ pr_warning("Unable to set clock %s to rate %lu: %d\n",
+ table->name, table->rate, ret);
+ return -EINVAL;
+ }
+ }
+
+ if (table->enabled) {
+ ret = clk_enable(c);
+ if (ret) {
+ pr_warning("Unable to enable clock %s: %d\n",
+ table->name, ret);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
+{
+ for (; table->name; table++)
+ tegra_clk_init_one_from_table(table);
+}
+EXPORT_SYMBOL(tegra_clk_init_from_table);
+
+void tegra_periph_reset_deassert(struct clk *c)
+{
+ tegra2_periph_reset_deassert(c);
+}
+EXPORT_SYMBOL(tegra_periph_reset_deassert);
+
+void tegra_periph_reset_assert(struct clk *c)
+{
+ tegra2_periph_reset_assert(c);
+}
+EXPORT_SYMBOL(tegra_periph_reset_assert);
+
+void __init tegra_init_clock(void)
+{
+ tegra2_init_clocks();
+}
+
+/*
+ * The SDMMC controllers have extra bits in the clock source register that
+ * adjust the delay between the clock and data to compenstate for delays
+ * on the PCB.
+ */
+void tegra_sdmmc_tap_delay(struct clk *c, int delay)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&c->spinlock, flags);
+ tegra2_sdmmc_tap_delay(c, delay);
+ spin_unlock_irqrestore(&c->spinlock, flags);
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static int __clk_lock_all_spinlocks(void)
+{
+ struct clk *c;
+
+ list_for_each_entry(c, &clocks, node)
+ if (!spin_trylock(&c->spinlock))
+ goto unlock_spinlocks;
+
+ return 0;
+
+unlock_spinlocks:
+ list_for_each_entry_continue_reverse(c, &clocks, node)
+ spin_unlock(&c->spinlock);
+
+ return -EAGAIN;
+}
+
+static void __clk_unlock_all_spinlocks(void)
+{
+ struct clk *c;
+
+ list_for_each_entry_reverse(c, &clocks, node)
+ spin_unlock(&c->spinlock);
+}
+
+/*
+ * This function retries until it can take all locks, and may take
+ * an arbitrarily long time to complete.
+ * Must be called with irqs enabled, returns with irqs disabled
+ * Must be called with clock_list_lock held
+ */
+static void clk_lock_all(void)
+{
+ int ret;
+retry:
+ local_irq_disable();
+
+ ret = __clk_lock_all_spinlocks();
+ if (ret)
+ goto failed_spinlocks;
+
+ /* All locks taken successfully, return */
+ return;
+
+failed_spinlocks:
+ local_irq_enable();
+ yield();
+ goto retry;
+}
+
+/*
+ * Unlocks all clocks after a clk_lock_all
+ * Must be called with irqs disabled, returns with irqs enabled
+ * Must be called with clock_list_lock held
+ */
+static void clk_unlock_all(void)
+{
+ __clk_unlock_all_spinlocks();
+
+ local_irq_enable();
+}
+
+static struct dentry *clk_debugfs_root;
+
+
+static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
+{
+ struct clk *child;
+ const char *state = "uninit";
+ char div[8] = {0};
+
+ if (c->state == ON)
+ state = "on";
+ else if (c->state == OFF)
+ state = "off";
+
+ if (c->mul != 0 && c->div != 0) {
+ if (c->mul > c->div) {
+ int mul = c->mul / c->div;
+ int mul2 = (c->mul * 10 / c->div) % 10;
+ int mul3 = (c->mul * 10) % c->div;
+ if (mul2 == 0 && mul3 == 0)
+ snprintf(div, sizeof(div), "x%d", mul);
+ else if (mul3 == 0)
+ snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
+ else
+ snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
+ } else {
+ snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
+ (c->div % c->mul) ? ".5" : "");
+ }
+ }
+
+ seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
+ level * 3 + 1, "",
+ c->rate > c->max_rate ? '!' : ' ',
+ !c->set ? '*' : ' ',
+ 30 - level * 3, c->name,
+ state, c->refcnt, div, clk_get_rate_all_locked(c));
+
+ list_for_each_entry(child, &clocks, node) {
+ if (child->parent != c)
+ continue;
+
+ clock_tree_show_one(s, child, level + 1);
+ }
+}
+
+static int clock_tree_show(struct seq_file *s, void *data)
+{
+ struct clk *c;
+ seq_printf(s, " clock state ref div rate\n");
+ seq_printf(s, "--------------------------------------------------------------\n");
+
+ mutex_lock(&clock_list_lock);
+
+ clk_lock_all();
+
+ list_for_each_entry(c, &clocks, node)
+ if (c->parent == NULL)
+ clock_tree_show_one(s, c, 0);
+
+ clk_unlock_all();
+
+ mutex_unlock(&clock_list_lock);
+ return 0;
+}
+
+static int clock_tree_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, clock_tree_show, inode->i_private);
+}
+
+static const struct file_operations clock_tree_fops = {
+ .open = clock_tree_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int possible_parents_show(struct seq_file *s, void *data)
+{
+ struct clk *c = s->private;
+ int i;
+
+ for (i = 0; c->inputs[i].input; i++) {
+ char *first = (i == 0) ? "" : " ";
+ seq_printf(s, "%s%s", first, c->inputs[i].input->name);
+ }
+ seq_printf(s, "\n");
+ return 0;
+}
+
+static int possible_parents_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, possible_parents_show, inode->i_private);
+}
+
+static const struct file_operations possible_parents_fops = {
+ .open = possible_parents_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ struct dentry *d, *child, *child_tmp;
+
+ d = debugfs_create_dir(c->name, clk_debugfs_root);
+ if (!d)
+ return -ENOMEM;
+ c->dent = d;
+
+ d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
+ if (!d)
+ goto err_out;
+
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (!d)
+ goto err_out;
+
+ d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ if (!d)
+ goto err_out;
+
+ if (c->inputs) {
+ d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
+ c, &possible_parents_fops);
+ if (!d)
+ goto err_out;
+ }
+
+ 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);
+ return -ENOMEM;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err = -ENOMEM;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
+ &clock_tree_fops);
+ if (!d)
+ goto err_out;
+
+ list_for_each_entry(c, &clocks, node) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+
+late_initcall(clk_debugfs_init);
+#endif
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
new file mode 100644
index 00000000..688316ab
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.h
@@ -0,0 +1,160 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clock.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_CLOCK_H
+#define __MACH_TEGRA_CLOCK_H
+
+#include <linux/clkdev.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+#define DIV_BUS (1 << 0)
+#define DIV_U71 (1 << 1)
+#define DIV_U71_FIXED (1 << 2)
+#define DIV_2 (1 << 3)
+#define DIV_U16 (1 << 4)
+#define PLL_FIXED (1 << 5)
+#define PLL_HAS_CPCON (1 << 6)
+#define MUX (1 << 7)
+#define PLLD (1 << 8)
+#define PERIPH_NO_RESET (1 << 9)
+#define PERIPH_NO_ENB (1 << 10)
+#define PERIPH_EMC_ENB (1 << 11)
+#define PERIPH_MANUAL_RESET (1 << 12)
+#define PLL_ALT_MISC_REG (1 << 13)
+#define PLLU (1 << 14)
+#define ENABLE_ON_INIT (1 << 28)
+
+struct clk;
+
+struct clk_mux_sel {
+ struct clk *input;
+ u32 value;
+};
+
+struct clk_pll_freq_table {
+ unsigned long input_rate;
+ unsigned long output_rate;
+ u16 n;
+ u16 m;
+ u8 p;
+ u8 cpcon;
+};
+
+struct clk_ops {
+ void (*init)(struct clk *);
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ int (*set_parent)(struct clk *, struct clk *);
+ int (*set_rate)(struct clk *, unsigned long);
+ long (*round_rate)(struct clk *, unsigned long);
+ void (*reset)(struct clk *, bool);
+};
+
+enum clk_state {
+ UNINITIALIZED = 0,
+ ON,
+ OFF,
+};
+
+struct clk {
+ /* node for master clocks list */
+ struct list_head node; /* node for list of all clocks */
+ struct clk_lookup lookup;
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dent;
+#endif
+ bool set;
+ struct clk_ops *ops;
+ unsigned long rate;
+ unsigned long max_rate;
+ unsigned long min_rate;
+ u32 flags;
+ const char *name;
+
+ u32 refcnt;
+ enum clk_state state;
+ struct clk *parent;
+ u32 div;
+ u32 mul;
+
+ const struct clk_mux_sel *inputs;
+ u32 reg;
+ u32 reg_shift;
+
+ struct list_head shared_bus_list;
+
+ union {
+ struct {
+ unsigned int clk_num;
+ } periph;
+ struct {
+ unsigned long input_min;
+ unsigned long input_max;
+ unsigned long cf_min;
+ unsigned long cf_max;
+ unsigned long vco_min;
+ unsigned long vco_max;
+ const struct clk_pll_freq_table *freq_table;
+ int lock_delay;
+ } pll;
+ struct {
+ u32 sel;
+ u32 reg_mask;
+ } mux;
+ struct {
+ struct clk *main;
+ struct clk *backup;
+ } cpu;
+ struct {
+ struct list_head node;
+ bool enabled;
+ unsigned long rate;
+ } shared_bus_user;
+ } u;
+
+ spinlock_t spinlock;
+};
+
+struct clk_duplicate {
+ const char *name;
+ struct clk_lookup lookup;
+};
+
+struct tegra_clk_init_table {
+ const char *name;
+ const char *parent;
+ unsigned long rate;
+ bool enabled;
+};
+
+void tegra2_init_clocks(void);
+void tegra2_periph_reset_deassert(struct clk *c);
+void tegra2_periph_reset_assert(struct clk *c);
+void clk_init(struct clk *clk);
+struct clk *tegra_get_clock_by_name(const char *name);
+unsigned long clk_measure_input_freq(void);
+int clk_reparent(struct clk *c, struct clk *parent);
+void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
+unsigned long clk_get_rate_locked(struct clk *c);
+int clk_set_rate_locked(struct clk *c, unsigned long rate);
+void tegra2_sdmmc_tap_delay(struct clk *c, int delay);
+
+#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
new file mode 100644
index 00000000..d5e3f89b
--- /dev/null
+++ b/arch/arm/mach-tegra/common.c
@@ -0,0 +1,83 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/iomap.h>
+#include <mach/system.h>
+
+#include "board.h"
+#include "clock.h"
+#include "fuse.h"
+
+void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
+
+void tegra_assert_system_reset(char mode, const char *cmd)
+{
+ void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
+ u32 reg;
+
+ /* use *_related to avoid spinlock since caches are off */
+ reg = readl_relaxed(reset);
+ reg |= 0x04;
+ writel_relaxed(reg, reset);
+}
+
+static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "clk_m", NULL, 0, true },
+ { "pll_p", "clk_m", 216000000, true },
+ { "pll_p_out1", "pll_p", 28800000, true },
+ { "pll_p_out2", "pll_p", 48000000, true },
+ { "pll_p_out3", "pll_p", 72000000, true },
+ { "pll_p_out4", "pll_p", 108000000, true },
+ { "sclk", "pll_p_out4", 108000000, true },
+ { "hclk", "sclk", 108000000, true },
+ { "pclk", "hclk", 54000000, true },
+ { "csite", NULL, 0, true },
+ { "emc", NULL, 0, true },
+ { "cpu", NULL, 0, true },
+ { NULL, NULL, 0, 0},
+};
+
+void __init tegra_init_cache(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+
+ writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
+ writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
+
+ l2x0_init(p, 0x6C080001, 0x8200c3fe);
+#endif
+
+}
+
+void __init tegra_init_early(void)
+{
+ tegra_init_fuse();
+ tegra_init_clock();
+ tegra_clk_init_from_table(common_clk_init_table);
+ tegra_init_cache();
+}
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
new file mode 100644
index 00000000..0e1016a8
--- /dev/null
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -0,0 +1,253 @@
+/*
+ * arch/arm/mach-tegra/cpu-tegra.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/clk.h>
+
+/* Frequency table index must be sequential starting at 0 */
+static struct cpufreq_frequency_table freq_table[] = {
+ { 0, 216000 },
+ { 1, 312000 },
+ { 2, 456000 },
+ { 3, 608000 },
+ { 4, 760000 },
+ { 5, 816000 },
+ { 6, 912000 },
+ { 7, 1000000 },
+ { 8, CPUFREQ_TABLE_END },
+};
+
+#define NUM_CPUS 2
+
+static struct clk *cpu_clk;
+static struct clk *emc_clk;
+
+static unsigned long target_cpu_speed[NUM_CPUS];
+static DEFINE_MUTEX(tegra_cpu_lock);
+static bool is_suspended;
+
+int tegra_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+unsigned int tegra_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu >= NUM_CPUS)
+ return 0;
+
+ rate = clk_get_rate(cpu_clk) / 1000;
+ return rate;
+}
+
+static int tegra_update_cpu_speed(unsigned long rate)
+{
+ int ret = 0;
+ struct cpufreq_freqs freqs;
+
+ freqs.old = tegra_getspeed(0);
+ freqs.new = rate;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ /*
+ * Vote on memory bus frequency based on cpu frequency
+ * This sets the minimum frequency, display or avp may request higher
+ */
+ if (rate >= 816000)
+ clk_set_rate(emc_clk, 600000000); /* cpu 816 MHz, emc max */
+ else if (rate >= 456000)
+ clk_set_rate(emc_clk, 300000000); /* cpu 456 MHz, emc 150Mhz */
+ else
+ clk_set_rate(emc_clk, 100000000); /* emc 50Mhz */
+
+ for_each_online_cpu(freqs.cpu)
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ printk(KERN_DEBUG "cpufreq-tegra: transition: %u --> %u\n",
+ freqs.old, freqs.new);
+#endif
+
+ ret = clk_set_rate(cpu_clk, freqs.new * 1000);
+ if (ret) {
+ pr_err("cpu-tegra: Failed to set cpu frequency to %d kHz\n",
+ freqs.new);
+ return ret;
+ }
+
+ for_each_online_cpu(freqs.cpu)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return 0;
+}
+
+static unsigned long tegra_cpu_highest_speed(void)
+{
+ unsigned long rate = 0;
+ int i;
+
+ for_each_online_cpu(i)
+ rate = max(rate, target_cpu_speed[i]);
+ return rate;
+}
+
+static int tegra_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ int idx;
+ unsigned int freq;
+ int ret = 0;
+
+ mutex_lock(&tegra_cpu_lock);
+
+ if (is_suspended) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ cpufreq_frequency_table_target(policy, freq_table, target_freq,
+ relation, &idx);
+
+ freq = freq_table[idx].frequency;
+
+ target_cpu_speed[policy->cpu] = freq;
+
+ ret = tegra_update_cpu_speed(tegra_cpu_highest_speed());
+
+out:
+ mutex_unlock(&tegra_cpu_lock);
+ return ret;
+}
+
+static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ mutex_lock(&tegra_cpu_lock);
+ if (event == PM_SUSPEND_PREPARE) {
+ is_suspended = true;
+ pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
+ freq_table[0].frequency);
+ tegra_update_cpu_speed(freq_table[0].frequency);
+ } else if (event == PM_POST_SUSPEND) {
+ is_suspended = false;
+ }
+ mutex_unlock(&tegra_cpu_lock);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block tegra_cpu_pm_notifier = {
+ .notifier_call = tegra_pm_notify,
+};
+
+static int tegra_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu >= NUM_CPUS)
+ return -EINVAL;
+
+ cpu_clk = clk_get_sys(NULL, "cpu");
+ if (IS_ERR(cpu_clk))
+ return PTR_ERR(cpu_clk);
+
+ emc_clk = clk_get_sys("cpu", "emc");
+ if (IS_ERR(emc_clk)) {
+ clk_put(cpu_clk);
+ return PTR_ERR(emc_clk);
+ }
+
+ clk_enable(emc_clk);
+ clk_enable(cpu_clk);
+
+ cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+ policy->cur = tegra_getspeed(policy->cpu);
+ target_cpu_speed[policy->cpu] = policy->cur;
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+ cpumask_copy(policy->related_cpus, cpu_possible_mask);
+
+ if (policy->cpu == 0)
+ register_pm_notifier(&tegra_cpu_pm_notifier);
+
+ return 0;
+}
+
+static int tegra_cpu_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ clk_disable(emc_clk);
+ clk_put(emc_clk);
+ clk_put(cpu_clk);
+ return 0;
+}
+
+static struct freq_attr *tegra_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver tegra_cpufreq_driver = {
+ .verify = tegra_verify_speed,
+ .target = tegra_target,
+ .get = tegra_getspeed,
+ .init = tegra_cpu_init,
+ .exit = tegra_cpu_exit,
+ .name = "tegra",
+ .attr = tegra_cpufreq_attr,
+};
+
+static int __init tegra_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&tegra_cpufreq_driver);
+}
+
+static void __exit tegra_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&tegra_cpufreq_driver);
+}
+
+
+MODULE_AUTHOR("Colin Cross <ccross@android.com>");
+MODULE_DESCRIPTION("cpufreq driver for Nvidia Tegra2");
+MODULE_LICENSE("GPL");
+module_init(tegra_cpufreq_init);
+module_exit(tegra_cpufreq_exit);
diff --git a/arch/arm/mach-tegra/devices.c b/arch/arm/mach-tegra/devices.c
new file mode 100644
index 00000000..1528f9da
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2010,2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ * Erik Gilling <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#include <linux/resource.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/serial_8250.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+#include <mach/dma.h>
+
+static struct resource i2c_resource1[] = {
+ [0] = {
+ .start = INT_I2C,
+ .end = INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_I2C_BASE,
+ .end = TEGRA_I2C_BASE + TEGRA_I2C_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource i2c_resource2[] = {
+ [0] = {
+ .start = INT_I2C2,
+ .end = INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_I2C2_BASE,
+ .end = TEGRA_I2C2_BASE + TEGRA_I2C2_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource i2c_resource3[] = {
+ [0] = {
+ .start = INT_I2C3,
+ .end = INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_I2C3_BASE,
+ .end = TEGRA_I2C3_BASE + TEGRA_I2C3_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource i2c_resource4[] = {
+ [0] = {
+ .start = INT_DVC,
+ .end = INT_DVC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_DVC_BASE,
+ .end = TEGRA_DVC_BASE + TEGRA_DVC_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tegra_i2c_device1 = {
+ .name = "tegra-i2c",
+ .id = 0,
+ .resource = i2c_resource1,
+ .num_resources = ARRAY_SIZE(i2c_resource1),
+ .dev = {
+ .platform_data = 0,
+ },
+};
+
+struct platform_device tegra_i2c_device2 = {
+ .name = "tegra-i2c",
+ .id = 1,
+ .resource = i2c_resource2,
+ .num_resources = ARRAY_SIZE(i2c_resource2),
+ .dev = {
+ .platform_data = 0,
+ },
+};
+
+struct platform_device tegra_i2c_device3 = {
+ .name = "tegra-i2c",
+ .id = 2,
+ .resource = i2c_resource3,
+ .num_resources = ARRAY_SIZE(i2c_resource3),
+ .dev = {
+ .platform_data = 0,
+ },
+};
+
+struct platform_device tegra_i2c_device4 = {
+ .name = "tegra-i2c",
+ .id = 3,
+ .resource = i2c_resource4,
+ .num_resources = ARRAY_SIZE(i2c_resource4),
+ .dev = {
+ .platform_data = 0,
+ },
+};
+
+static struct resource spi_resource1[] = {
+ [0] = {
+ .start = INT_S_LINK1,
+ .end = INT_S_LINK1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SPI1_BASE,
+ .end = TEGRA_SPI1_BASE + TEGRA_SPI1_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource spi_resource2[] = {
+ [0] = {
+ .start = INT_SPI_2,
+ .end = INT_SPI_2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SPI2_BASE,
+ .end = TEGRA_SPI2_BASE + TEGRA_SPI2_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource spi_resource3[] = {
+ [0] = {
+ .start = INT_SPI_3,
+ .end = INT_SPI_3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SPI3_BASE,
+ .end = TEGRA_SPI3_BASE + TEGRA_SPI3_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource spi_resource4[] = {
+ [0] = {
+ .start = INT_SPI_4,
+ .end = INT_SPI_4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SPI4_BASE,
+ .end = TEGRA_SPI4_BASE + TEGRA_SPI4_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tegra_spi_device1 = {
+ .name = "spi_tegra",
+ .id = 0,
+ .resource = spi_resource1,
+ .num_resources = ARRAY_SIZE(spi_resource1),
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device tegra_spi_device2 = {
+ .name = "spi_tegra",
+ .id = 1,
+ .resource = spi_resource2,
+ .num_resources = ARRAY_SIZE(spi_resource2),
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device tegra_spi_device3 = {
+ .name = "spi_tegra",
+ .id = 2,
+ .resource = spi_resource3,
+ .num_resources = ARRAY_SIZE(spi_resource3),
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+struct platform_device tegra_spi_device4 = {
+ .name = "spi_tegra",
+ .id = 3,
+ .resource = spi_resource4,
+ .num_resources = ARRAY_SIZE(spi_resource4),
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+
+static struct resource sdhci_resource1[] = {
+ [0] = {
+ .start = INT_SDMMC1,
+ .end = INT_SDMMC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SDMMC1_BASE,
+ .end = TEGRA_SDMMC1_BASE + TEGRA_SDMMC1_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource sdhci_resource2[] = {
+ [0] = {
+ .start = INT_SDMMC2,
+ .end = INT_SDMMC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SDMMC2_BASE,
+ .end = TEGRA_SDMMC2_BASE + TEGRA_SDMMC2_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource sdhci_resource3[] = {
+ [0] = {
+ .start = INT_SDMMC3,
+ .end = INT_SDMMC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SDMMC3_BASE,
+ .end = TEGRA_SDMMC3_BASE + TEGRA_SDMMC3_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource sdhci_resource4[] = {
+ [0] = {
+ .start = INT_SDMMC4,
+ .end = INT_SDMMC4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = TEGRA_SDMMC4_BASE,
+ .end = TEGRA_SDMMC4_BASE + TEGRA_SDMMC4_SIZE-1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/* board files should fill in platform_data register the devices themselvs.
+ * See board-harmony.c for an example
+ */
+struct platform_device tegra_sdhci_device1 = {
+ .name = "sdhci-tegra",
+ .id = 0,
+ .resource = sdhci_resource1,
+ .num_resources = ARRAY_SIZE(sdhci_resource1),
+};
+
+struct platform_device tegra_sdhci_device2 = {
+ .name = "sdhci-tegra",
+ .id = 1,
+ .resource = sdhci_resource2,
+ .num_resources = ARRAY_SIZE(sdhci_resource2),
+};
+
+struct platform_device tegra_sdhci_device3 = {
+ .name = "sdhci-tegra",
+ .id = 2,
+ .resource = sdhci_resource3,
+ .num_resources = ARRAY_SIZE(sdhci_resource3),
+};
+
+struct platform_device tegra_sdhci_device4 = {
+ .name = "sdhci-tegra",
+ .id = 3,
+ .resource = sdhci_resource4,
+ .num_resources = ARRAY_SIZE(sdhci_resource4),
+};
+
+static struct resource tegra_usb1_resources[] = {
+ [0] = {
+ .start = TEGRA_USB_BASE,
+ .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USB,
+ .end = INT_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_usb2_resources[] = {
+ [0] = {
+ .start = TEGRA_USB2_BASE,
+ .end = TEGRA_USB2_BASE + TEGRA_USB2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USB2,
+ .end = INT_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_usb3_resources[] = {
+ [0] = {
+ .start = TEGRA_USB3_BASE,
+ .end = TEGRA_USB3_BASE + TEGRA_USB3_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_USB3,
+ .end = INT_USB3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 tegra_ehci_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device tegra_ehci1_device = {
+ .name = "tegra-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &tegra_ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = tegra_usb1_resources,
+ .num_resources = ARRAY_SIZE(tegra_usb1_resources),
+};
+
+struct platform_device tegra_ehci2_device = {
+ .name = "tegra-ehci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &tegra_ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = tegra_usb2_resources,
+ .num_resources = ARRAY_SIZE(tegra_usb2_resources),
+};
+
+struct platform_device tegra_ehci3_device = {
+ .name = "tegra-ehci",
+ .id = 2,
+ .dev = {
+ .dma_mask = &tegra_ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = tegra_usb3_resources,
+ .num_resources = ARRAY_SIZE(tegra_usb3_resources),
+};
+
+static struct resource tegra_pmu_resources[] = {
+ [0] = {
+ .start = INT_CPU0_PMU_INTR,
+ .end = INT_CPU0_PMU_INTR,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = INT_CPU1_PMU_INTR,
+ .end = INT_CPU1_PMU_INTR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tegra_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(tegra_pmu_resources),
+ .resource = tegra_pmu_resources,
+};
+
+static struct resource tegra_uarta_resources[] = {
+ [0] = {
+ .start = TEGRA_UARTA_BASE,
+ .end = TEGRA_UARTA_BASE + TEGRA_UARTA_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_UARTA,
+ .end = INT_UARTA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_uartb_resources[] = {
+ [0] = {
+ .start = TEGRA_UARTB_BASE,
+ .end = TEGRA_UARTB_BASE + TEGRA_UARTB_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_UARTB,
+ .end = INT_UARTB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_uartc_resources[] = {
+ [0] = {
+ .start = TEGRA_UARTC_BASE,
+ .end = TEGRA_UARTC_BASE + TEGRA_UARTC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_UARTC,
+ .end = INT_UARTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_uartd_resources[] = {
+ [0] = {
+ .start = TEGRA_UARTD_BASE,
+ .end = TEGRA_UARTD_BASE + TEGRA_UARTD_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_UARTD,
+ .end = INT_UARTD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource tegra_uarte_resources[] = {
+ [0] = {
+ .start = TEGRA_UARTE_BASE,
+ .end = TEGRA_UARTE_BASE + TEGRA_UARTE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = INT_UARTE,
+ .end = INT_UARTE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device tegra_uarta_device = {
+ .name = "tegra_uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tegra_uarta_resources),
+ .resource = tegra_uarta_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device tegra_uartb_device = {
+ .name = "tegra_uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(tegra_uartb_resources),
+ .resource = tegra_uartb_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device tegra_uartc_device = {
+ .name = "tegra_uart",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(tegra_uartc_resources),
+ .resource = tegra_uartc_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device tegra_uartd_device = {
+ .name = "tegra_uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(tegra_uartd_resources),
+ .resource = tegra_uartd_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device tegra_uarte_device = {
+ .name = "tegra_uart",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(tegra_uarte_resources),
+ .resource = tegra_uarte_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource i2s_resource1[] = {
+ [0] = {
+ .start = INT_I2S1,
+ .end = INT_I2S1,
+ .flags = IORESOURCE_IRQ
+ },
+ [1] = {
+ .start = TEGRA_DMA_REQ_SEL_I2S_1,
+ .end = TEGRA_DMA_REQ_SEL_I2S_1,
+ .flags = IORESOURCE_DMA
+ },
+ [2] = {
+ .start = TEGRA_I2S1_BASE,
+ .end = TEGRA_I2S1_BASE + TEGRA_I2S1_SIZE - 1,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+static struct resource i2s_resource2[] = {
+ [0] = {
+ .start = INT_I2S2,
+ .end = INT_I2S2,
+ .flags = IORESOURCE_IRQ
+ },
+ [1] = {
+ .start = TEGRA_DMA_REQ_SEL_I2S2_1,
+ .end = TEGRA_DMA_REQ_SEL_I2S2_1,
+ .flags = IORESOURCE_DMA
+ },
+ [2] = {
+ .start = TEGRA_I2S2_BASE,
+ .end = TEGRA_I2S2_BASE + TEGRA_I2S2_SIZE - 1,
+ .flags = IORESOURCE_MEM
+ }
+};
+
+struct platform_device tegra_i2s_device1 = {
+ .name = "tegra-i2s",
+ .id = 0,
+ .resource = i2s_resource1,
+ .num_resources = ARRAY_SIZE(i2s_resource1),
+};
+
+struct platform_device tegra_i2s_device2 = {
+ .name = "tegra-i2s",
+ .id = 1,
+ .resource = i2s_resource2,
+ .num_resources = ARRAY_SIZE(i2s_resource2),
+};
+
+static struct resource tegra_das_resources[] = {
+ [0] = {
+ .start = TEGRA_APB_MISC_DAS_BASE,
+ .end = TEGRA_APB_MISC_DAS_BASE + TEGRA_APB_MISC_DAS_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tegra_das_device = {
+ .name = "tegra-das",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(tegra_das_resources),
+ .resource = tegra_das_resources,
+};
+
+struct platform_device tegra_pcm_device = {
+ .name = "tegra-pcm-audio",
+ .id = -1,
+};
diff --git a/arch/arm/mach-tegra/devices.h b/arch/arm/mach-tegra/devices.h
new file mode 100644
index 00000000..4a7dc0a0
--- /dev/null
+++ b/arch/arm/mach-tegra/devices.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010,2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ * Erik Gilling <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 __MACH_TEGRA_DEVICES_H
+#define __MACH_TEGRA_DEVICES_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device tegra_sdhci_device1;
+extern struct platform_device tegra_sdhci_device2;
+extern struct platform_device tegra_sdhci_device3;
+extern struct platform_device tegra_sdhci_device4;
+extern struct platform_device tegra_i2c_device1;
+extern struct platform_device tegra_i2c_device2;
+extern struct platform_device tegra_i2c_device3;
+extern struct platform_device tegra_i2c_device4;
+extern struct platform_device tegra_spi_device1;
+extern struct platform_device tegra_spi_device2;
+extern struct platform_device tegra_spi_device3;
+extern struct platform_device tegra_spi_device4;
+extern struct platform_device tegra_ehci1_device;
+extern struct platform_device tegra_ehci2_device;
+extern struct platform_device tegra_ehci3_device;
+extern struct platform_device tegra_uarta_device;
+extern struct platform_device tegra_uartb_device;
+extern struct platform_device tegra_uartc_device;
+extern struct platform_device tegra_uartd_device;
+extern struct platform_device tegra_uarte_device;
+extern struct platform_device tegra_pmu_device;
+extern struct platform_device tegra_i2s_device1;
+extern struct platform_device tegra_i2s_device2;
+extern struct platform_device tegra_das_device;
+extern struct platform_device tegra_pcm_device;
+
+#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
new file mode 100644
index 00000000..f4ef5eb3
--- /dev/null
+++ b/arch/arm/mach-tegra/dma.c
@@ -0,0 +1,793 @@
+/*
+ * arch/arm/mach-tegra/dma.c
+ *
+ * System DMA driver for NVIDIA Tegra SoCs
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+#include <mach/suspend.h>
+
+#define APB_DMA_GEN 0x000
+#define GEN_ENABLE (1<<31)
+
+#define APB_DMA_CNTRL 0x010
+
+#define APB_DMA_IRQ_MASK 0x01c
+
+#define APB_DMA_IRQ_MASK_SET 0x020
+
+#define APB_DMA_CHAN_CSR 0x000
+#define CSR_ENB (1<<31)
+#define CSR_IE_EOC (1<<30)
+#define CSR_HOLD (1<<29)
+#define CSR_DIR (1<<28)
+#define CSR_ONCE (1<<27)
+#define CSR_FLOW (1<<21)
+#define CSR_REQ_SEL_SHIFT 16
+#define CSR_REQ_SEL_MASK (0x1F<<CSR_REQ_SEL_SHIFT)
+#define CSR_REQ_SEL_INVALID (31<<CSR_REQ_SEL_SHIFT)
+#define CSR_WCOUNT_SHIFT 2
+#define CSR_WCOUNT_MASK 0xFFFC
+
+#define APB_DMA_CHAN_STA 0x004
+#define STA_BUSY (1<<31)
+#define STA_ISE_EOC (1<<30)
+#define STA_HALT (1<<29)
+#define STA_PING_PONG (1<<28)
+#define STA_COUNT_SHIFT 2
+#define STA_COUNT_MASK 0xFFFC
+
+#define APB_DMA_CHAN_AHB_PTR 0x010
+
+#define APB_DMA_CHAN_AHB_SEQ 0x014
+#define AHB_SEQ_INTR_ENB (1<<31)
+#define AHB_SEQ_BUS_WIDTH_SHIFT 28
+#define AHB_SEQ_BUS_WIDTH_MASK (0x7<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_8 (0<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_16 (1<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_32 (2<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_64 (3<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_BUS_WIDTH_128 (4<<AHB_SEQ_BUS_WIDTH_SHIFT)
+#define AHB_SEQ_DATA_SWAP (1<<27)
+#define AHB_SEQ_BURST_MASK (0x7<<24)
+#define AHB_SEQ_BURST_1 (4<<24)
+#define AHB_SEQ_BURST_4 (5<<24)
+#define AHB_SEQ_BURST_8 (6<<24)
+#define AHB_SEQ_DBL_BUF (1<<19)
+#define AHB_SEQ_WRAP_SHIFT 16
+#define AHB_SEQ_WRAP_MASK (0x7<<AHB_SEQ_WRAP_SHIFT)
+
+#define APB_DMA_CHAN_APB_PTR 0x018
+
+#define APB_DMA_CHAN_APB_SEQ 0x01c
+#define APB_SEQ_BUS_WIDTH_SHIFT 28
+#define APB_SEQ_BUS_WIDTH_MASK (0x7<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_8 (0<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_16 (1<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_32 (2<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_64 (3<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_BUS_WIDTH_128 (4<<APB_SEQ_BUS_WIDTH_SHIFT)
+#define APB_SEQ_DATA_SWAP (1<<27)
+#define APB_SEQ_WRAP_SHIFT 16
+#define APB_SEQ_WRAP_MASK (0x7<<APB_SEQ_WRAP_SHIFT)
+
+#define TEGRA_SYSTEM_DMA_CH_NR 16
+#define TEGRA_SYSTEM_DMA_AVP_CH_NUM 4
+#define TEGRA_SYSTEM_DMA_CH_MIN 0
+#define TEGRA_SYSTEM_DMA_CH_MAX \
+ (TEGRA_SYSTEM_DMA_CH_NR - TEGRA_SYSTEM_DMA_AVP_CH_NUM - 1)
+
+#define NV_DMA_MAX_TRASFER_SIZE 0x10000
+
+const unsigned int ahb_addr_wrap_table[8] = {
+ 0, 32, 64, 128, 256, 512, 1024, 2048
+};
+
+const unsigned int apb_addr_wrap_table[8] = {0, 1, 2, 4, 8, 16, 32, 64};
+
+const unsigned int bus_width_table[5] = {8, 16, 32, 64, 128};
+
+#define TEGRA_DMA_NAME_SIZE 16
+struct tegra_dma_channel {
+ struct list_head list;
+ int id;
+ spinlock_t lock;
+ char name[TEGRA_DMA_NAME_SIZE];
+ void __iomem *addr;
+ int mode;
+ int irq;
+ int req_transfer_count;
+};
+
+#define NV_DMA_MAX_CHANNELS 32
+
+static bool tegra_dma_initialized;
+static DEFINE_MUTEX(tegra_dma_lock);
+
+static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
+static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
+
+static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+static void tegra_dma_stop(struct tegra_dma_channel *ch);
+
+void tegra_dma_flush(struct tegra_dma_channel *ch)
+{
+}
+EXPORT_SYMBOL(tegra_dma_flush);
+
+void tegra_dma_dequeue(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+
+ if (tegra_dma_is_empty(ch))
+ return;
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+
+ tegra_dma_dequeue_req(ch, req);
+ return;
+}
+
+void tegra_dma_stop(struct tegra_dma_channel *ch)
+{
+ u32 csr;
+ u32 status;
+
+ csr = readl(ch->addr + APB_DMA_CHAN_CSR);
+ csr &= ~CSR_IE_EOC;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ csr &= ~CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ if (status & STA_ISE_EOC)
+ writel(status, ch->addr + APB_DMA_CHAN_STA);
+}
+
+int tegra_dma_cancel(struct tegra_dma_channel *ch)
+{
+ u32 csr;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ while (!list_empty(&ch->list))
+ list_del(ch->list.next);
+
+ csr = readl(ch->addr + APB_DMA_CHAN_CSR);
+ csr &= ~CSR_REQ_SEL_MASK;
+ csr |= CSR_REQ_SEL_INVALID;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ tegra_dma_stop(ch);
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return 0;
+}
+
+int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *_req)
+{
+ unsigned int csr;
+ unsigned int status;
+ struct tegra_dma_req *req = NULL;
+ int found = 0;
+ unsigned long irq_flags;
+ int to_transfer;
+ int req_transfer_count;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ list_for_each_entry(req, &ch->list, node) {
+ if (req == _req) {
+ list_del(&req->node);
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return 0;
+ }
+
+ /* STOP the DMA and get the transfer count.
+ * Getting the transfer count is tricky.
+ * - Change the source selector to invalid to stop the DMA from
+ * FIFO to memory.
+ * - Read the status register to know the number of pending
+ * bytes to be transferred.
+ * - Finally stop or program the DMA to the next buffer in the
+ * list.
+ */
+ csr = readl(ch->addr + APB_DMA_CHAN_CSR);
+ csr &= ~CSR_REQ_SEL_MASK;
+ csr |= CSR_REQ_SEL_INVALID;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ /* Get the transfer count */
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
+ req_transfer_count = ch->req_transfer_count;
+ req_transfer_count += 1;
+ to_transfer += 1;
+
+ req->bytes_transferred = req_transfer_count;
+
+ if (status & STA_BUSY)
+ req->bytes_transferred -= to_transfer;
+
+ /* In continuous transfer mode, DMA only tracks the count of the
+ * half DMA buffer. So, if the DMA already finished half the DMA
+ * then add the half buffer to the completed count.
+ *
+ * FIXME: There can be a race here. What if the req to
+ * dequue happens at the same time as the DMA just moved to
+ * the new buffer and SW didn't yet received the interrupt?
+ */
+ if (ch->mode & TEGRA_DMA_MODE_CONTINOUS)
+ if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
+ req->bytes_transferred += req_transfer_count;
+
+ req->bytes_transferred *= 4;
+
+ tegra_dma_stop(ch);
+ if (!list_empty(&ch->list)) {
+ /* if the list is not empty, queue the next request */
+ struct tegra_dma_req *next_req;
+ next_req = list_entry(ch->list.next,
+ typeof(*next_req), node);
+ tegra_dma_update_hw(ch, next_req);
+ }
+ req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ /* Callback should be called without any lock */
+ req->complete(req);
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dma_dequeue_req);
+
+bool tegra_dma_is_empty(struct tegra_dma_channel *ch)
+{
+ unsigned long irq_flags;
+ bool is_empty;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if (list_empty(&ch->list))
+ is_empty = true;
+ else
+ is_empty = false;
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return is_empty;
+}
+EXPORT_SYMBOL(tegra_dma_is_empty);
+
+bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *_req)
+{
+ unsigned long irq_flags;
+ struct tegra_dma_req *req;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ list_for_each_entry(req, &ch->list, node) {
+ if (req == _req) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return true;
+ }
+ }
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return false;
+}
+EXPORT_SYMBOL(tegra_dma_is_req_inflight);
+
+int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ unsigned long irq_flags;
+ struct tegra_dma_req *_req;
+ int start_dma = 0;
+
+ if (req->size > NV_DMA_MAX_TRASFER_SIZE ||
+ req->source_addr & 0x3 || req->dest_addr & 0x3) {
+ pr_err("Invalid DMA request for channel %d\n", ch->id);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+
+ list_for_each_entry(_req, &ch->list, node) {
+ if (req == _req) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return -EEXIST;
+ }
+ }
+
+ req->bytes_transferred = 0;
+ req->status = 0;
+ req->buffer_status = 0;
+ if (list_empty(&ch->list))
+ start_dma = 1;
+
+ list_add_tail(&req->node, &ch->list);
+
+ if (start_dma)
+ tegra_dma_update_hw(ch, req);
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dma_enqueue_req);
+
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
+{
+ int channel;
+ struct tegra_dma_channel *ch = NULL;
+
+ if (WARN_ON(!tegra_dma_initialized))
+ return NULL;
+
+ mutex_lock(&tegra_dma_lock);
+
+ /* first channel is the shared channel */
+ if (mode & TEGRA_DMA_SHARED) {
+ channel = TEGRA_SYSTEM_DMA_CH_MIN;
+ } else {
+ channel = find_first_zero_bit(channel_usage,
+ ARRAY_SIZE(dma_channels));
+ if (channel >= ARRAY_SIZE(dma_channels))
+ goto out;
+ }
+ __set_bit(channel, channel_usage);
+ ch = &dma_channels[channel];
+ ch->mode = mode;
+
+out:
+ mutex_unlock(&tegra_dma_lock);
+ return ch;
+}
+EXPORT_SYMBOL(tegra_dma_allocate_channel);
+
+void tegra_dma_free_channel(struct tegra_dma_channel *ch)
+{
+ if (ch->mode & TEGRA_DMA_SHARED)
+ return;
+ tegra_dma_cancel(ch);
+ mutex_lock(&tegra_dma_lock);
+ __clear_bit(ch->id, channel_usage);
+ mutex_unlock(&tegra_dma_lock);
+}
+EXPORT_SYMBOL(tegra_dma_free_channel);
+
+static void tegra_dma_update_hw_partial(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ u32 apb_ptr;
+ u32 ahb_ptr;
+
+ if (req->to_memory) {
+ apb_ptr = req->source_addr;
+ ahb_ptr = req->dest_addr;
+ } else {
+ apb_ptr = req->dest_addr;
+ ahb_ptr = req->source_addr;
+ }
+ writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
+ writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
+ return;
+}
+
+static void tegra_dma_update_hw(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req)
+{
+ int ahb_addr_wrap;
+ int apb_addr_wrap;
+ int ahb_bus_width;
+ int apb_bus_width;
+ int index;
+
+ u32 ahb_seq;
+ u32 apb_seq;
+ u32 ahb_ptr;
+ u32 apb_ptr;
+ u32 csr;
+
+ csr = CSR_IE_EOC | CSR_FLOW;
+ ahb_seq = AHB_SEQ_INTR_ENB | AHB_SEQ_BURST_1;
+ apb_seq = 0;
+
+ csr |= req->req_sel << CSR_REQ_SEL_SHIFT;
+
+ /* One shot mode is always single buffered,
+ * continuous mode is always double buffered
+ * */
+ if (ch->mode & TEGRA_DMA_MODE_ONESHOT) {
+ csr |= CSR_ONCE;
+ ch->req_transfer_count = (req->size >> 2) - 1;
+ } else {
+ ahb_seq |= AHB_SEQ_DBL_BUF;
+
+ /* In double buffered mode, we set the size to half the
+ * requested size and interrupt when half the buffer
+ * is full */
+ ch->req_transfer_count = (req->size >> 3) - 1;
+ }
+
+ csr |= ch->req_transfer_count << CSR_WCOUNT_SHIFT;
+
+ if (req->to_memory) {
+ apb_ptr = req->source_addr;
+ ahb_ptr = req->dest_addr;
+
+ apb_addr_wrap = req->source_wrap;
+ ahb_addr_wrap = req->dest_wrap;
+ apb_bus_width = req->source_bus_width;
+ ahb_bus_width = req->dest_bus_width;
+
+ } else {
+ csr |= CSR_DIR;
+ apb_ptr = req->dest_addr;
+ ahb_ptr = req->source_addr;
+
+ apb_addr_wrap = req->dest_wrap;
+ ahb_addr_wrap = req->source_wrap;
+ apb_bus_width = req->dest_bus_width;
+ ahb_bus_width = req->source_bus_width;
+ }
+
+ apb_addr_wrap >>= 2;
+ ahb_addr_wrap >>= 2;
+
+ /* set address wrap for APB size */
+ index = 0;
+ do {
+ if (apb_addr_wrap_table[index] == apb_addr_wrap)
+ break;
+ index++;
+ } while (index < ARRAY_SIZE(apb_addr_wrap_table));
+ BUG_ON(index == ARRAY_SIZE(apb_addr_wrap_table));
+ apb_seq |= index << APB_SEQ_WRAP_SHIFT;
+
+ /* set address wrap for AHB size */
+ index = 0;
+ do {
+ if (ahb_addr_wrap_table[index] == ahb_addr_wrap)
+ break;
+ index++;
+ } while (index < ARRAY_SIZE(ahb_addr_wrap_table));
+ BUG_ON(index == ARRAY_SIZE(ahb_addr_wrap_table));
+ ahb_seq |= index << AHB_SEQ_WRAP_SHIFT;
+
+ for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
+ if (bus_width_table[index] == ahb_bus_width)
+ break;
+ }
+ BUG_ON(index == ARRAY_SIZE(bus_width_table));
+ ahb_seq |= index << AHB_SEQ_BUS_WIDTH_SHIFT;
+
+ for (index = 0; index < ARRAY_SIZE(bus_width_table); index++) {
+ if (bus_width_table[index] == apb_bus_width)
+ break;
+ }
+ BUG_ON(index == ARRAY_SIZE(bus_width_table));
+ apb_seq |= index << APB_SEQ_BUS_WIDTH_SHIFT;
+
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+ writel(apb_seq, ch->addr + APB_DMA_CHAN_APB_SEQ);
+ writel(apb_ptr, ch->addr + APB_DMA_CHAN_APB_PTR);
+ writel(ahb_seq, ch->addr + APB_DMA_CHAN_AHB_SEQ);
+ writel(ahb_ptr, ch->addr + APB_DMA_CHAN_AHB_PTR);
+
+ csr |= CSR_ENB;
+ writel(csr, ch->addr + APB_DMA_CHAN_CSR);
+
+ req->status = TEGRA_DMA_REQ_INFLIGHT;
+}
+
+static void handle_oneshot_dma(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if (list_empty(&ch->list)) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+ if (req) {
+ int bytes_transferred;
+
+ bytes_transferred = ch->req_transfer_count;
+ bytes_transferred += 1;
+ bytes_transferred <<= 2;
+
+ list_del(&req->node);
+ req->bytes_transferred = bytes_transferred;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ /* Callback should be called without any lock */
+ pr_debug("%s: transferred %d bytes\n", __func__,
+ req->bytes_transferred);
+ req->complete(req);
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ }
+
+ if (!list_empty(&ch->list)) {
+ req = list_entry(ch->list.next, typeof(*req), node);
+ /* the complete function we just called may have enqueued
+ another req, in which case dma has already started */
+ if (req->status != TEGRA_DMA_REQ_INFLIGHT)
+ tegra_dma_update_hw(ch, req);
+ }
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+}
+
+static void handle_continuous_dma(struct tegra_dma_channel *ch)
+{
+ struct tegra_dma_req *req;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&ch->lock, irq_flags);
+ if (list_empty(&ch->list)) {
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
+
+ req = list_entry(ch->list.next, typeof(*req), node);
+ if (req) {
+ if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_EMPTY) {
+ bool is_dma_ping_complete;
+ is_dma_ping_complete = (readl(ch->addr + APB_DMA_CHAN_STA)
+ & STA_PING_PONG) ? true : false;
+ if (req->to_memory)
+ is_dma_ping_complete = !is_dma_ping_complete;
+ /* Out of sync - Release current buffer */
+ if (!is_dma_ping_complete) {
+ int bytes_transferred;
+
+ bytes_transferred = ch->req_transfer_count;
+ bytes_transferred += 1;
+ bytes_transferred <<= 3;
+ req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
+ req->bytes_transferred = bytes_transferred;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+ tegra_dma_stop(ch);
+
+ if (!list_is_last(&req->node, &ch->list)) {
+ struct tegra_dma_req *next_req;
+
+ next_req = list_entry(req->node.next,
+ typeof(*next_req), node);
+ tegra_dma_update_hw(ch, next_req);
+ }
+
+ list_del(&req->node);
+
+ /* DMA lock is NOT held when callbak is called */
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ req->complete(req);
+ return;
+ }
+ /* Load the next request into the hardware, if available
+ * */
+ if (!list_is_last(&req->node, &ch->list)) {
+ struct tegra_dma_req *next_req;
+
+ next_req = list_entry(req->node.next,
+ typeof(*next_req), node);
+ tegra_dma_update_hw_partial(ch, next_req);
+ }
+ req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+ /* DMA lock is NOT held when callback is called */
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ if (likely(req->threshold))
+ req->threshold(req);
+ return;
+
+ } else if (req->buffer_status ==
+ TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL) {
+ /* Callback when the buffer is completely full (i.e on
+ * the second interrupt */
+ int bytes_transferred;
+
+ bytes_transferred = ch->req_transfer_count;
+ bytes_transferred += 1;
+ bytes_transferred <<= 3;
+
+ req->buffer_status = TEGRA_DMA_REQ_BUF_STATUS_FULL;
+ req->bytes_transferred = bytes_transferred;
+ req->status = TEGRA_DMA_REQ_SUCCESS;
+ list_del(&req->node);
+
+ /* DMA lock is NOT held when callbak is called */
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ req->complete(req);
+ return;
+
+ } else {
+ BUG();
+ }
+ }
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+}
+
+static irqreturn_t dma_isr(int irq, void *data)
+{
+ struct tegra_dma_channel *ch = data;
+ unsigned long status;
+
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ if (status & STA_ISE_EOC)
+ writel(status, ch->addr + APB_DMA_CHAN_STA);
+ else {
+ pr_warning("Got a spurious ISR for DMA channel %d\n", ch->id);
+ return IRQ_HANDLED;
+ }
+ return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t dma_thread_fn(int irq, void *data)
+{
+ struct tegra_dma_channel *ch = data;
+
+ if (ch->mode & TEGRA_DMA_MODE_ONESHOT)
+ handle_oneshot_dma(ch);
+ else
+ handle_continuous_dma(ch);
+
+
+ return IRQ_HANDLED;
+}
+
+int __init tegra_dma_init(void)
+{
+ int ret = 0;
+ int i;
+ unsigned int irq;
+ void __iomem *addr;
+ struct clk *c;
+
+ bitmap_fill(channel_usage, NV_DMA_MAX_CHANNELS);
+
+ c = clk_get_sys("tegra-dma", NULL);
+ if (IS_ERR(c)) {
+ pr_err("Unable to get clock for APB DMA\n");
+ ret = PTR_ERR(c);
+ goto fail;
+ }
+ ret = clk_enable(c);
+ if (ret != 0) {
+ pr_err("Unable to enable clock for APB DMA\n");
+ goto fail;
+ }
+
+ addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ writel(GEN_ENABLE, addr + APB_DMA_GEN);
+ writel(0, addr + APB_DMA_CNTRL);
+ writel(0xFFFFFFFFul >> (31 - TEGRA_SYSTEM_DMA_CH_MAX),
+ addr + APB_DMA_IRQ_MASK_SET);
+
+ for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
+ struct tegra_dma_channel *ch = &dma_channels[i];
+
+ ch->id = i;
+ snprintf(ch->name, TEGRA_DMA_NAME_SIZE, "dma_channel_%d", i);
+
+ ch->addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ spin_lock_init(&ch->lock);
+ INIT_LIST_HEAD(&ch->list);
+
+ irq = INT_APB_DMA_CH0 + i;
+ ret = request_threaded_irq(irq, dma_isr, dma_thread_fn, 0,
+ dma_channels[i].name, ch);
+ if (ret) {
+ pr_err("Failed to register IRQ %d for DMA %d\n",
+ irq, i);
+ goto fail;
+ }
+ ch->irq = irq;
+
+ __clear_bit(i, channel_usage);
+ }
+ /* mark the shared channel allocated */
+ __set_bit(TEGRA_SYSTEM_DMA_CH_MIN, channel_usage);
+
+ tegra_dma_initialized = true;
+
+ return 0;
+fail:
+ writel(0, addr + APB_DMA_GEN);
+ for (i = TEGRA_SYSTEM_DMA_CH_MIN; i <= TEGRA_SYSTEM_DMA_CH_MAX; i++) {
+ struct tegra_dma_channel *ch = &dma_channels[i];
+ if (ch->irq)
+ free_irq(ch->irq, ch);
+ }
+ return ret;
+}
+postcore_initcall(tegra_dma_init);
+
+#ifdef CONFIG_PM
+static u32 apb_dma[5*TEGRA_SYSTEM_DMA_CH_NR + 3];
+
+void tegra_dma_suspend(void)
+{
+ void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ u32 *ctx = apb_dma;
+ int i;
+
+ *ctx++ = readl(addr + APB_DMA_GEN);
+ *ctx++ = readl(addr + APB_DMA_CNTRL);
+ *ctx++ = readl(addr + APB_DMA_IRQ_MASK);
+
+ for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
+ addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ *ctx++ = readl(addr + APB_DMA_CHAN_CSR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ);
+ *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR);
+ *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ);
+ }
+}
+
+void tegra_dma_resume(void)
+{
+ void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ u32 *ctx = apb_dma;
+ int i;
+
+ writel(*ctx++, addr + APB_DMA_GEN);
+ writel(*ctx++, addr + APB_DMA_CNTRL);
+ writel(*ctx++, addr + APB_DMA_IRQ_MASK);
+
+ for (i = 0; i < TEGRA_SYSTEM_DMA_CH_NR; i++) {
+ addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE +
+ TEGRA_APB_DMA_CH0_SIZE * i);
+
+ writel(*ctx++, addr + APB_DMA_CHAN_CSR);
+ writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR);
+ writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ);
+ writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR);
+ writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ);
+ }
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
new file mode 100644
index 00000000..1fa26d9a
--- /dev/null
+++ b/arch/arm/mach-tegra/fuse.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-tegra/fuse.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+
+#include "fuse.h"
+
+#define FUSE_UID_LOW 0x108
+#define FUSE_UID_HIGH 0x10c
+#define FUSE_SKU_INFO 0x110
+#define FUSE_SPARE_BIT 0x200
+
+static inline u32 fuse_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+}
+
+static inline void fuse_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+}
+
+void tegra_init_fuse(void)
+{
+ u32 reg = readl(IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
+ reg |= 1 << 28;
+ writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
+
+ pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_sku_id(), tegra_cpu_process_id(),
+ tegra_core_process_id());
+}
+
+unsigned long long tegra_chip_uid(void)
+{
+ unsigned long long lo, hi;
+
+ lo = fuse_readl(FUSE_UID_LOW);
+ hi = fuse_readl(FUSE_UID_HIGH);
+ return (hi << 32ull) | lo;
+}
+
+int tegra_sku_id(void)
+{
+ int sku_id;
+ u32 reg = fuse_readl(FUSE_SKU_INFO);
+ sku_id = reg & 0xFF;
+ return sku_id;
+}
+
+int tegra_cpu_process_id(void)
+{
+ int cpu_process_id;
+ u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ cpu_process_id = (reg >> 6) & 3;
+ return cpu_process_id;
+}
+
+int tegra_core_process_id(void)
+{
+ int core_process_id;
+ u32 reg = fuse_readl(FUSE_SPARE_BIT);
+ core_process_id = (reg >> 12) & 3;
+ return core_process_id;
+}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
new file mode 100644
index 00000000..584b2e27
--- /dev/null
+++ b/arch/arm/mach-tegra/fuse.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-tegra/fuse.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+unsigned long long tegra_chip_uid(void);
+int tegra_sku_id(void);
+int tegra_cpu_process_id(void);
+int tegra_core_process_id(void);
+void tegra_init_fuse(void);
diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h
new file mode 100644
index 00000000..f28220a6
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio-names.h
@@ -0,0 +1,247 @@
+/*
+ * arch/arm/mach-tegra/include/mach/gpio-names.h
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_TEGRA_GPIO_NAMES_H
+#define __MACH_TEGRA_GPIO_NAMES_H
+
+#define TEGRA_GPIO_PA0 0
+#define TEGRA_GPIO_PA1 1
+#define TEGRA_GPIO_PA2 2
+#define TEGRA_GPIO_PA3 3
+#define TEGRA_GPIO_PA4 4
+#define TEGRA_GPIO_PA5 5
+#define TEGRA_GPIO_PA6 6
+#define TEGRA_GPIO_PA7 7
+#define TEGRA_GPIO_PB0 8
+#define TEGRA_GPIO_PB1 9
+#define TEGRA_GPIO_PB2 10
+#define TEGRA_GPIO_PB3 11
+#define TEGRA_GPIO_PB4 12
+#define TEGRA_GPIO_PB5 13
+#define TEGRA_GPIO_PB6 14
+#define TEGRA_GPIO_PB7 15
+#define TEGRA_GPIO_PC0 16
+#define TEGRA_GPIO_PC1 17
+#define TEGRA_GPIO_PC2 18
+#define TEGRA_GPIO_PC3 19
+#define TEGRA_GPIO_PC4 20
+#define TEGRA_GPIO_PC5 21
+#define TEGRA_GPIO_PC6 22
+#define TEGRA_GPIO_PC7 23
+#define TEGRA_GPIO_PD0 24
+#define TEGRA_GPIO_PD1 25
+#define TEGRA_GPIO_PD2 26
+#define TEGRA_GPIO_PD3 27
+#define TEGRA_GPIO_PD4 28
+#define TEGRA_GPIO_PD5 29
+#define TEGRA_GPIO_PD6 30
+#define TEGRA_GPIO_PD7 31
+#define TEGRA_GPIO_PE0 32
+#define TEGRA_GPIO_PE1 33
+#define TEGRA_GPIO_PE2 34
+#define TEGRA_GPIO_PE3 35
+#define TEGRA_GPIO_PE4 36
+#define TEGRA_GPIO_PE5 37
+#define TEGRA_GPIO_PE6 38
+#define TEGRA_GPIO_PE7 39
+#define TEGRA_GPIO_PF0 40
+#define TEGRA_GPIO_PF1 41
+#define TEGRA_GPIO_PF2 42
+#define TEGRA_GPIO_PF3 43
+#define TEGRA_GPIO_PF4 44
+#define TEGRA_GPIO_PF5 45
+#define TEGRA_GPIO_PF6 46
+#define TEGRA_GPIO_PF7 47
+#define TEGRA_GPIO_PG0 48
+#define TEGRA_GPIO_PG1 49
+#define TEGRA_GPIO_PG2 50
+#define TEGRA_GPIO_PG3 51
+#define TEGRA_GPIO_PG4 52
+#define TEGRA_GPIO_PG5 53
+#define TEGRA_GPIO_PG6 54
+#define TEGRA_GPIO_PG7 55
+#define TEGRA_GPIO_PH0 56
+#define TEGRA_GPIO_PH1 57
+#define TEGRA_GPIO_PH2 58
+#define TEGRA_GPIO_PH3 59
+#define TEGRA_GPIO_PH4 60
+#define TEGRA_GPIO_PH5 61
+#define TEGRA_GPIO_PH6 62
+#define TEGRA_GPIO_PH7 63
+#define TEGRA_GPIO_PI0 64
+#define TEGRA_GPIO_PI1 65
+#define TEGRA_GPIO_PI2 66
+#define TEGRA_GPIO_PI3 67
+#define TEGRA_GPIO_PI4 68
+#define TEGRA_GPIO_PI5 69
+#define TEGRA_GPIO_PI6 70
+#define TEGRA_GPIO_PI7 71
+#define TEGRA_GPIO_PJ0 72
+#define TEGRA_GPIO_PJ1 73
+#define TEGRA_GPIO_PJ2 74
+#define TEGRA_GPIO_PJ3 75
+#define TEGRA_GPIO_PJ4 76
+#define TEGRA_GPIO_PJ5 77
+#define TEGRA_GPIO_PJ6 78
+#define TEGRA_GPIO_PJ7 79
+#define TEGRA_GPIO_PK0 80
+#define TEGRA_GPIO_PK1 81
+#define TEGRA_GPIO_PK2 82
+#define TEGRA_GPIO_PK3 83
+#define TEGRA_GPIO_PK4 84
+#define TEGRA_GPIO_PK5 85
+#define TEGRA_GPIO_PK6 86
+#define TEGRA_GPIO_PK7 87
+#define TEGRA_GPIO_PL0 88
+#define TEGRA_GPIO_PL1 89
+#define TEGRA_GPIO_PL2 90
+#define TEGRA_GPIO_PL3 91
+#define TEGRA_GPIO_PL4 92
+#define TEGRA_GPIO_PL5 93
+#define TEGRA_GPIO_PL6 94
+#define TEGRA_GPIO_PL7 95
+#define TEGRA_GPIO_PM0 96
+#define TEGRA_GPIO_PM1 97
+#define TEGRA_GPIO_PM2 98
+#define TEGRA_GPIO_PM3 99
+#define TEGRA_GPIO_PM4 100
+#define TEGRA_GPIO_PM5 101
+#define TEGRA_GPIO_PM6 102
+#define TEGRA_GPIO_PM7 103
+#define TEGRA_GPIO_PN0 104
+#define TEGRA_GPIO_PN1 105
+#define TEGRA_GPIO_PN2 106
+#define TEGRA_GPIO_PN3 107
+#define TEGRA_GPIO_PN4 108
+#define TEGRA_GPIO_PN5 109
+#define TEGRA_GPIO_PN6 110
+#define TEGRA_GPIO_PN7 111
+#define TEGRA_GPIO_PO0 112
+#define TEGRA_GPIO_PO1 113
+#define TEGRA_GPIO_PO2 114
+#define TEGRA_GPIO_PO3 115
+#define TEGRA_GPIO_PO4 116
+#define TEGRA_GPIO_PO5 117
+#define TEGRA_GPIO_PO6 118
+#define TEGRA_GPIO_PO7 119
+#define TEGRA_GPIO_PP0 120
+#define TEGRA_GPIO_PP1 121
+#define TEGRA_GPIO_PP2 122
+#define TEGRA_GPIO_PP3 123
+#define TEGRA_GPIO_PP4 124
+#define TEGRA_GPIO_PP5 125
+#define TEGRA_GPIO_PP6 126
+#define TEGRA_GPIO_PP7 127
+#define TEGRA_GPIO_PQ0 128
+#define TEGRA_GPIO_PQ1 129
+#define TEGRA_GPIO_PQ2 130
+#define TEGRA_GPIO_PQ3 131
+#define TEGRA_GPIO_PQ4 132
+#define TEGRA_GPIO_PQ5 133
+#define TEGRA_GPIO_PQ6 134
+#define TEGRA_GPIO_PQ7 135
+#define TEGRA_GPIO_PR0 136
+#define TEGRA_GPIO_PR1 137
+#define TEGRA_GPIO_PR2 138
+#define TEGRA_GPIO_PR3 139
+#define TEGRA_GPIO_PR4 140
+#define TEGRA_GPIO_PR5 141
+#define TEGRA_GPIO_PR6 142
+#define TEGRA_GPIO_PR7 143
+#define TEGRA_GPIO_PS0 144
+#define TEGRA_GPIO_PS1 145
+#define TEGRA_GPIO_PS2 146
+#define TEGRA_GPIO_PS3 147
+#define TEGRA_GPIO_PS4 148
+#define TEGRA_GPIO_PS5 149
+#define TEGRA_GPIO_PS6 150
+#define TEGRA_GPIO_PS7 151
+#define TEGRA_GPIO_PT0 152
+#define TEGRA_GPIO_PT1 153
+#define TEGRA_GPIO_PT2 154
+#define TEGRA_GPIO_PT3 155
+#define TEGRA_GPIO_PT4 156
+#define TEGRA_GPIO_PT5 157
+#define TEGRA_GPIO_PT6 158
+#define TEGRA_GPIO_PT7 159
+#define TEGRA_GPIO_PU0 160
+#define TEGRA_GPIO_PU1 161
+#define TEGRA_GPIO_PU2 162
+#define TEGRA_GPIO_PU3 163
+#define TEGRA_GPIO_PU4 164
+#define TEGRA_GPIO_PU5 165
+#define TEGRA_GPIO_PU6 166
+#define TEGRA_GPIO_PU7 167
+#define TEGRA_GPIO_PV0 168
+#define TEGRA_GPIO_PV1 169
+#define TEGRA_GPIO_PV2 170
+#define TEGRA_GPIO_PV3 171
+#define TEGRA_GPIO_PV4 172
+#define TEGRA_GPIO_PV5 173
+#define TEGRA_GPIO_PV6 174
+#define TEGRA_GPIO_PV7 175
+#define TEGRA_GPIO_PW0 176
+#define TEGRA_GPIO_PW1 177
+#define TEGRA_GPIO_PW2 178
+#define TEGRA_GPIO_PW3 179
+#define TEGRA_GPIO_PW4 180
+#define TEGRA_GPIO_PW5 181
+#define TEGRA_GPIO_PW6 182
+#define TEGRA_GPIO_PW7 183
+#define TEGRA_GPIO_PX0 184
+#define TEGRA_GPIO_PX1 185
+#define TEGRA_GPIO_PX2 186
+#define TEGRA_GPIO_PX3 187
+#define TEGRA_GPIO_PX4 188
+#define TEGRA_GPIO_PX5 189
+#define TEGRA_GPIO_PX6 190
+#define TEGRA_GPIO_PX7 191
+#define TEGRA_GPIO_PY0 192
+#define TEGRA_GPIO_PY1 193
+#define TEGRA_GPIO_PY2 194
+#define TEGRA_GPIO_PY3 195
+#define TEGRA_GPIO_PY4 196
+#define TEGRA_GPIO_PY5 197
+#define TEGRA_GPIO_PY6 198
+#define TEGRA_GPIO_PY7 199
+#define TEGRA_GPIO_PZ0 200
+#define TEGRA_GPIO_PZ1 201
+#define TEGRA_GPIO_PZ2 202
+#define TEGRA_GPIO_PZ3 203
+#define TEGRA_GPIO_PZ4 204
+#define TEGRA_GPIO_PZ5 205
+#define TEGRA_GPIO_PZ6 206
+#define TEGRA_GPIO_PZ7 207
+#define TEGRA_GPIO_PAA0 208
+#define TEGRA_GPIO_PAA1 209
+#define TEGRA_GPIO_PAA2 210
+#define TEGRA_GPIO_PAA3 211
+#define TEGRA_GPIO_PAA4 212
+#define TEGRA_GPIO_PAA5 213
+#define TEGRA_GPIO_PAA6 214
+#define TEGRA_GPIO_PAA7 215
+#define TEGRA_GPIO_PBB0 216
+#define TEGRA_GPIO_PBB1 217
+#define TEGRA_GPIO_PBB2 218
+#define TEGRA_GPIO_PBB3 219
+#define TEGRA_GPIO_PBB4 220
+#define TEGRA_GPIO_PBB5 221
+#define TEGRA_GPIO_PBB6 222
+#define TEGRA_GPIO_PBB7 223
+
+#endif
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
new file mode 100644
index 00000000..919d6383
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio.c
@@ -0,0 +1,431 @@
+/*
+ * arch/arm/mach-tegra/gpio.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/iomap.h>
+#include <mach/suspend.h>
+
+#define GPIO_BANK(x) ((x) >> 5)
+#define GPIO_PORT(x) (((x) >> 3) & 0x3)
+#define GPIO_BIT(x) ((x) & 0x7)
+
+#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
+ GPIO_BANK(x) * 0x80 + \
+ GPIO_PORT(x) * 4)
+
+#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
+#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
+#define GPIO_OUT(x) (GPIO_REG(x) + 0X20)
+#define GPIO_IN(x) (GPIO_REG(x) + 0x30)
+#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40)
+#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50)
+#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
+#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
+
+#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
+#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
+#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
+#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
+#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
+#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
+
+#define GPIO_INT_LVL_MASK 0x010101
+#define GPIO_INT_LVL_EDGE_RISING 0x000101
+#define GPIO_INT_LVL_EDGE_FALLING 0x000100
+#define GPIO_INT_LVL_EDGE_BOTH 0x010100
+#define GPIO_INT_LVL_LEVEL_HIGH 0x000001
+#define GPIO_INT_LVL_LEVEL_LOW 0x000000
+
+struct tegra_gpio_bank {
+ int bank;
+ int irq;
+ spinlock_t lvl_lock[4];
+#ifdef CONFIG_PM
+ u32 cnf[4];
+ u32 out[4];
+ u32 oe[4];
+ u32 int_enb[4];
+ u32 int_lvl[4];
+#endif
+};
+
+
+static struct tegra_gpio_bank tegra_gpio_banks[] = {
+ {.bank = 0, .irq = INT_GPIO1},
+ {.bank = 1, .irq = INT_GPIO2},
+ {.bank = 2, .irq = INT_GPIO3},
+ {.bank = 3, .irq = INT_GPIO4},
+ {.bank = 4, .irq = INT_GPIO5},
+ {.bank = 5, .irq = INT_GPIO6},
+ {.bank = 6, .irq = INT_GPIO7},
+};
+
+static int tegra_gpio_compose(int bank, int port, int bit)
+{
+ return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7);
+}
+
+static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
+{
+ u32 val;
+
+ val = 0x100 << GPIO_BIT(gpio);
+ if (value)
+ val |= 1 << GPIO_BIT(gpio);
+ __raw_writel(val, reg);
+}
+
+void tegra_gpio_enable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
+}
+
+void tegra_gpio_disable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
+}
+
+static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value);
+}
+
+static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
+}
+
+static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
+ return 0;
+}
+
+static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ tegra_gpio_set(chip, offset, value);
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
+ return 0;
+}
+
+
+
+static struct gpio_chip tegra_gpio_chip = {
+ .label = "tegra-gpio",
+ .direction_input = tegra_gpio_direction_input,
+ .get = tegra_gpio_get,
+ .direction_output = tegra_gpio_direction_output,
+ .set = tegra_gpio_set,
+ .base = 0,
+ .ngpio = TEGRA_NR_GPIOS,
+};
+
+static void tegra_gpio_irq_ack(struct irq_data *d)
+{
+ int gpio = d->irq - INT_GPIO_BASE;
+
+ __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
+}
+
+static void tegra_gpio_irq_mask(struct irq_data *d)
+{
+ int gpio = d->irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
+}
+
+static void tegra_gpio_irq_unmask(struct irq_data *d)
+{
+ int gpio = d->irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
+}
+
+static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ int gpio = d->irq - INT_GPIO_BASE;
+ struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+ int port = GPIO_PORT(gpio);
+ int lvl_type;
+ int val;
+ unsigned long flags;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_RISING:
+ lvl_type = GPIO_INT_LVL_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ lvl_type = GPIO_INT_LVL_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ lvl_type = GPIO_INT_LVL_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ lvl_type = GPIO_INT_LVL_LEVEL_HIGH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ lvl_type = GPIO_INT_LVL_LEVEL_LOW;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&bank->lvl_lock[port], flags);
+
+ val = __raw_readl(GPIO_INT_LVL(gpio));
+ val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
+ val |= lvl_type << GPIO_BIT(gpio);
+ __raw_writel(val, GPIO_INT_LVL(gpio));
+
+ spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+
+ return 0;
+}
+
+static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct tegra_gpio_bank *bank;
+ int port;
+ int pin;
+ int unmasked = 0;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ chained_irq_enter(chip, desc);
+
+ bank = irq_get_handler_data(irq);
+
+ for (port = 0; port < 4; port++) {
+ int gpio = tegra_gpio_compose(bank->bank, port, 0);
+ unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
+ __raw_readl(GPIO_INT_ENB(gpio));
+ u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
+
+ for_each_set_bit(pin, &sta, 8) {
+ __raw_writel(1 << pin, GPIO_INT_CLR(gpio));
+
+ /* if gpio is edge triggered, clear condition
+ * before executing the hander so that we don't
+ * miss edges
+ */
+ if (lvl & (0x100 << pin)) {
+ unmasked = 1;
+ chained_irq_exit(chip, desc);
+ }
+
+ generic_handle_irq(gpio_to_irq(gpio + pin));
+ }
+ }
+
+ if (!unmasked)
+ chained_irq_exit(chip, desc);
+
+}
+
+#ifdef CONFIG_PM
+void tegra_gpio_resume(void)
+{
+ unsigned long flags;
+ int b;
+ int p;
+
+ local_irq_save(flags);
+
+ for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ __raw_writel(bank->cnf[p], GPIO_CNF(gpio));
+ __raw_writel(bank->out[p], GPIO_OUT(gpio));
+ __raw_writel(bank->oe[p], GPIO_OE(gpio));
+ __raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
+ __raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
+ }
+ }
+
+ local_irq_restore(flags);
+}
+
+void tegra_gpio_suspend(void)
+{
+ unsigned long flags;
+ int b;
+ int p;
+
+ local_irq_save(flags);
+ for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
+
+ for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
+ unsigned int gpio = (b<<5) | (p<<3);
+ bank->cnf[p] = __raw_readl(GPIO_CNF(gpio));
+ bank->out[p] = __raw_readl(GPIO_OUT(gpio));
+ bank->oe[p] = __raw_readl(GPIO_OE(gpio));
+ bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio));
+ bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio));
+ }
+ }
+ local_irq_restore(flags);
+}
+
+static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
+{
+ struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+ return irq_set_irq_wake(bank->irq, enable);
+}
+#endif
+
+static struct irq_chip tegra_gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_ack = tegra_gpio_irq_ack,
+ .irq_mask = tegra_gpio_irq_mask,
+ .irq_unmask = tegra_gpio_irq_unmask,
+ .irq_set_type = tegra_gpio_irq_set_type,
+#ifdef CONFIG_PM
+ .irq_set_wake = tegra_gpio_wake_enable,
+#endif
+};
+
+
+/* This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static int __init tegra_gpio_init(void)
+{
+ struct tegra_gpio_bank *bank;
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ __raw_writel(0x00, GPIO_INT_ENB(gpio));
+ }
+ }
+
+ gpiochip_add(&tegra_gpio_chip);
+
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
+ bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
+
+ irq_set_lockdep_class(i, &gpio_lock_class);
+ irq_set_chip_data(i, bank);
+ irq_set_chip_and_handler(i, &tegra_gpio_irq_chip,
+ handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ bank = &tegra_gpio_banks[i];
+
+ irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
+ irq_set_handler_data(bank->irq, bank);
+
+ for (j = 0; j < 4; j++)
+ spin_lock_init(&bank->lvl_lock[j]);
+ }
+
+ return 0;
+}
+
+postcore_initcall(tegra_gpio_init);
+
+void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ int gpio = table[i].gpio;
+
+ if (table[i].enable)
+ tegra_gpio_enable(gpio);
+ else
+ tegra_gpio_disable(gpio);
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ seq_printf(s,
+ "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
+ i, j,
+ __raw_readl(GPIO_CNF(gpio)),
+ __raw_readl(GPIO_OE(gpio)),
+ __raw_readl(GPIO_OUT(gpio)),
+ __raw_readl(GPIO_IN(gpio)),
+ __raw_readl(GPIO_INT_STA(gpio)),
+ __raw_readl(GPIO_INT_ENB(gpio)),
+ __raw_readl(GPIO_INT_LVL(gpio)));
+ }
+ }
+ return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_gpio_debuginit(void)
+{
+ (void) debugfs_create_file("tegra_gpio", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ return 0;
+}
+late_initcall(tegra_gpio_debuginit);
+#endif
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
new file mode 100644
index 00000000..b5349b2f
--- /dev/null
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -0,0 +1,61 @@
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ .section ".text.head", "ax"
+ __CPUINIT
+
+/*
+ * Tegra specific entry point for secondary CPUs.
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the main
+ * processor. We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ */
+ENTRY(v7_invalidate_l1)
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1: sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2: subs r3, r3, #1 @ Temp--
+ mov r5, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+ mcr p15, 0, r5, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+ mov pc, lr
+ENDPROC(v7_invalidate_l1)
+
+ENTRY(tegra_secondary_startup)
+ msr cpsr_fsxc, #0xd3
+ bl v7_invalidate_l1
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ ldr r1, =0x6000f100
+ str r0, [r1]
+1: ldr r2, [r1]
+ cmp r0, r2
+ beq 1b
+ b secondary_startup
+ENDPROC(tegra_secondary_startup)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
new file mode 100644
index 00000000..f3294040
--- /dev/null
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C)
+ : "cc");
+}
+
+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 (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ /*if (pen_release == cpu) {*/
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ /*}*/
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h
new file mode 100644
index 00000000..425b42e9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/barriers.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-realview/include/mach/barriers.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_BARRIERS_H
+#define __MACH_BARRIERS_H
+
+#include <asm/outercache.h>
+
+#define rmb() dsb()
+#define wmb() do { dsb(); outer_sync(); } while (0)
+#define mb() wmb()
+
+#endif /* __MACH_BARRIERS_H */
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
new file mode 100644
index 00000000..c8baf8f8
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clk.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_CLK_H
+#define __MACH_CLK_H
+
+struct clk;
+
+void tegra_periph_reset_deassert(struct clk *c);
+void tegra_periph_reset_assert(struct clk *c);
+
+unsigned long clk_get_rate_all_locked(struct clk *c);
+void tegra_sdmmc_tap_delay(struct clk *c, int delay);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h
new file mode 100644
index 00000000..66cd3f4f
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clkdev.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
new file mode 100644
index 00000000..e0ebe65c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-tegra/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <mach/io.h>
+#include <mach/iomap.h>
+
+ .macro addruart, rp, rv
+ ldr \rp, =IO_APB_PHYS @ physical
+ ldr \rv, =IO_APB_VIRT @ virtual
+ orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
+ orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
+ orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
+ orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
+
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
new file mode 100644
index 00000000..d0132e80
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-tegra/include/mach/dma.h
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_TEGRA_DMA_H
+#define __MACH_TEGRA_DMA_H
+
+#include <linux/list.h>
+
+#if defined(CONFIG_TEGRA_SYSTEM_DMA)
+
+struct tegra_dma_req;
+struct tegra_dma_channel;
+
+#define TEGRA_DMA_REQ_SEL_CNTR 0
+#define TEGRA_DMA_REQ_SEL_I2S_2 1
+#define TEGRA_DMA_REQ_SEL_I2S_1 2
+#define TEGRA_DMA_REQ_SEL_SPD_I 3
+#define TEGRA_DMA_REQ_SEL_UI_I 4
+#define TEGRA_DMA_REQ_SEL_MIPI 5
+#define TEGRA_DMA_REQ_SEL_I2S2_2 6
+#define TEGRA_DMA_REQ_SEL_I2S2_1 7
+#define TEGRA_DMA_REQ_SEL_UARTA 8
+#define TEGRA_DMA_REQ_SEL_UARTB 9
+#define TEGRA_DMA_REQ_SEL_UARTC 10
+#define TEGRA_DMA_REQ_SEL_SPI 11
+#define TEGRA_DMA_REQ_SEL_AC97 12
+#define TEGRA_DMA_REQ_SEL_ACMODEM 13
+#define TEGRA_DMA_REQ_SEL_SL4B 14
+#define TEGRA_DMA_REQ_SEL_SL2B1 15
+#define TEGRA_DMA_REQ_SEL_SL2B2 16
+#define TEGRA_DMA_REQ_SEL_SL2B3 17
+#define TEGRA_DMA_REQ_SEL_SL2B4 18
+#define TEGRA_DMA_REQ_SEL_UARTD 19
+#define TEGRA_DMA_REQ_SEL_UARTE 20
+#define TEGRA_DMA_REQ_SEL_I2C 21
+#define TEGRA_DMA_REQ_SEL_I2C2 22
+#define TEGRA_DMA_REQ_SEL_I2C3 23
+#define TEGRA_DMA_REQ_SEL_DVC_I2C 24
+#define TEGRA_DMA_REQ_SEL_OWR 25
+#define TEGRA_DMA_REQ_SEL_INVALID 31
+
+enum tegra_dma_mode {
+ TEGRA_DMA_SHARED = 1,
+ TEGRA_DMA_MODE_CONTINOUS = 2,
+ TEGRA_DMA_MODE_ONESHOT = 4,
+};
+
+enum tegra_dma_req_error {
+ TEGRA_DMA_REQ_SUCCESS = 0,
+ TEGRA_DMA_REQ_ERROR_ABORTED,
+ TEGRA_DMA_REQ_INFLIGHT,
+};
+
+enum tegra_dma_req_buff_status {
+ TEGRA_DMA_REQ_BUF_STATUS_EMPTY = 0,
+ TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL,
+ TEGRA_DMA_REQ_BUF_STATUS_FULL,
+};
+
+struct tegra_dma_req {
+ struct list_head node;
+ unsigned int modid;
+ int instance;
+
+ /* Called when the req is complete and from the DMA ISR context.
+ * When this is called the req structure is no longer queued by
+ * the DMA channel.
+ *
+ * State of the DMA depends on the number of req it has. If there are
+ * no DMA requests queued up, then it will STOP the DMA. It there are
+ * more requests in the DMA, then it will queue the next request.
+ */
+ void (*complete)(struct tegra_dma_req *req);
+
+ /* This is a called from the DMA ISR context when the DMA is still in
+ * progress and is actively filling same buffer.
+ *
+ * In case of continuous mode receive, this threshold is 1/2 the buffer
+ * size. In other cases, this will not even be called as there is no
+ * hardware support for it.
+ *
+ * In the case of continuous mode receive, if there is next req already
+ * queued, DMA programs the HW to use that req when this req is
+ * completed. If there is no "next req" queued, then DMA ISR doesn't do
+ * anything before calling this callback.
+ *
+ * This is mainly used by the cases, where the clients has queued
+ * only one req and want to get some sort of DMA threshold
+ * callback to program the next buffer.
+ *
+ */
+ void (*threshold)(struct tegra_dma_req *req);
+
+ /* 1 to copy to memory.
+ * 0 to copy from the memory to device FIFO */
+ int to_memory;
+
+ void *virt_addr;
+
+ unsigned long source_addr;
+ unsigned long dest_addr;
+ unsigned long dest_wrap;
+ unsigned long source_wrap;
+ unsigned long source_bus_width;
+ unsigned long dest_bus_width;
+ unsigned long req_sel;
+ unsigned int size;
+
+ /* Updated by the DMA driver on the conpletion of the request. */
+ int bytes_transferred;
+ int status;
+
+ /* DMA completion tracking information */
+ int buffer_status;
+
+ /* Client specific data */
+ void *dev;
+};
+
+int tegra_dma_enqueue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+void tegra_dma_dequeue(struct tegra_dma_channel *ch);
+void tegra_dma_flush(struct tegra_dma_channel *ch);
+
+bool tegra_dma_is_req_inflight(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req);
+bool tegra_dma_is_empty(struct tegra_dma_channel *ch);
+
+struct tegra_dma_channel *tegra_dma_allocate_channel(int mode);
+void tegra_dma_free_channel(struct tegra_dma_channel *ch);
+
+int __init tegra_dma_init(void);
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
new file mode 100644
index 00000000..dd165c53
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -0,0 +1,56 @@
+/* arch/arm/mach-tegra/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2009 Palm, 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 <mach/iomap.h>
+#include <mach/io.h>
+
+#if defined(CONFIG_ARM_GIC)
+#define HAVE_GET_IRQNR_PREAMBLE
+#include <asm/hardware/entry-macro-gic.S>
+
+ /* Uses the GIC interrupt controller built into the cpu */
+#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ movw \base, #(ICTRL_BASE & 0x0000ffff)
+ movt \base, #((ICTRL_BASE & 0xffff0000) >> 16)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+#else
+ /* legacy interrupt controller for AP16 */
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ enable imprecise aborts
+ cpsie a
+ @ EVP base at 0xf010f000
+ mov \base, #0xf0000000
+ orr \base, #0x00100000
+ orr \base, #0x0000f000
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS
+ cmp \irqnr, #0x80
+ .endm
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
new file mode 100644
index 00000000..196f114d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-tegra/include/mach/gpio.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_GPIO_H
+#define __MACH_TEGRA_GPIO_H
+
+#include <linux/init.h>
+#include <mach/irqs.h>
+
+#define TEGRA_NR_GPIOS INT_GPIO_NR
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
+#define TEGRA_IRQ_TO_GPIO(irq) ((irq) - INT_GPIO_BASE)
+
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ if (gpio < TEGRA_NR_GPIOS)
+ return INT_GPIO_BASE + gpio;
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
+ return irq - INT_GPIO_BASE;
+ return -EINVAL;
+}
+
+struct tegra_gpio_table {
+ int gpio; /* GPIO number */
+ bool enable; /* Enable for GPIO at init? */
+};
+
+void tegra_gpio_config(struct tegra_gpio_table *table, int num);
+void tegra_gpio_enable(int gpio);
+void tegra_gpio_disable(int gpio);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
new file mode 100644
index 00000000..56e43b3a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-tegra/include/mach/hardware.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_HARDWARE_H
+#define __MACH_TEGRA_HARDWARE_H
+
+#define PCIBIOS_MIN_IO 0x1000
+#define PCIBIOS_MIN_MEM 0
+#define pcibios_assign_all_busses() 1
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
new file mode 100644
index 00000000..4cea2230
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -0,0 +1,95 @@
+/*
+ * arch/arm/mach-tegra/include/mach/io.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IO_H
+#define __MACH_TEGRA_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+/* On TEGRA, many peripherals are very closely packed in
+ * two 256MB io windows (that actually only use about 64KB
+ * at the start of each).
+ *
+ * We will just map the first 1MB of each window (to minimize
+ * pt entries needed) and provide a macro to transform physical
+ * io addresses to an appropriate void __iomem *.
+ *
+ */
+
+#define IO_IRAM_PHYS 0x40000000
+#define IO_IRAM_VIRT 0xFE400000
+#define IO_IRAM_SIZE SZ_256K
+
+#define IO_CPU_PHYS 0x50040000
+#define IO_CPU_VIRT 0xFE000000
+#define IO_CPU_SIZE SZ_16K
+
+#define IO_PPSB_PHYS 0x60000000
+#define IO_PPSB_VIRT 0xFE200000
+#define IO_PPSB_SIZE SZ_1M
+
+#define IO_APB_PHYS 0x70000000
+#define IO_APB_VIRT 0xFE300000
+#define IO_APB_SIZE SZ_1M
+
+#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
+#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
+
+#define IO_TO_VIRT(n) ( \
+ IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_IRAM_PHYS, IO_IRAM_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_IRAM_PHYS, IO_IRAM_VIRT) : \
+ 0)
+
+#ifndef __ASSEMBLER__
+
+#define __arch_ioremap tegra_ioremap
+#define __arch_iounmap tegra_iounmap
+
+void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
+void tegra_iounmap(volatile void __iomem *addr);
+
+#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
+
+#ifdef CONFIG_TEGRA_PCI
+extern void __iomem *tegra_pcie_io_base;
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
+}
+#else
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+#endif
+
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
new file mode 100644
index 00000000..19dec3ac
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -0,0 +1,274 @@
+/*
+ * arch/arm/mach-tegra/include/mach/iomap.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IOMAP_H
+#define __MACH_TEGRA_IOMAP_H
+
+#include <asm/sizes.h>
+
+#define TEGRA_IRAM_BASE 0x40000000
+#define TEGRA_IRAM_SIZE SZ_256K
+
+#define TEGRA_HOST1X_BASE 0x50000000
+#define TEGRA_HOST1X_SIZE 0x24000
+
+#define TEGRA_ARM_PERIF_BASE 0x50040000
+#define TEGRA_ARM_PERIF_SIZE SZ_8K
+
+#define TEGRA_ARM_PL310_BASE 0x50043000
+#define TEGRA_ARM_PL310_SIZE SZ_4K
+
+#define TEGRA_ARM_INT_DIST_BASE 0x50041000
+#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
+
+#define TEGRA_MPE_BASE 0x54040000
+#define TEGRA_MPE_SIZE SZ_256K
+
+#define TEGRA_VI_BASE 0x54080000
+#define TEGRA_VI_SIZE SZ_256K
+
+#define TEGRA_ISP_BASE 0x54100000
+#define TEGRA_ISP_SIZE SZ_256K
+
+#define TEGRA_DISPLAY_BASE 0x54200000
+#define TEGRA_DISPLAY_SIZE SZ_256K
+
+#define TEGRA_DISPLAY2_BASE 0x54240000
+#define TEGRA_DISPLAY2_SIZE SZ_256K
+
+#define TEGRA_HDMI_BASE 0x54280000
+#define TEGRA_HDMI_SIZE SZ_256K
+
+#define TEGRA_GART_BASE 0x58000000
+#define TEGRA_GART_SIZE SZ_32M
+
+#define TEGRA_RES_SEMA_BASE 0x60001000
+#define TEGRA_RES_SEMA_SIZE SZ_4K
+
+#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
+#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
+#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
+#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
+#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TMR1_BASE 0x60005000
+#define TEGRA_TMR1_SIZE SZ_8
+
+#define TEGRA_TMR2_BASE 0x60005008
+#define TEGRA_TMR2_SIZE SZ_8
+
+#define TEGRA_TMRUS_BASE 0x60005010
+#define TEGRA_TMRUS_SIZE SZ_64
+
+#define TEGRA_TMR3_BASE 0x60005050
+#define TEGRA_TMR3_SIZE SZ_8
+
+#define TEGRA_TMR4_BASE 0x60005058
+#define TEGRA_TMR4_SIZE SZ_8
+
+#define TEGRA_CLK_RESET_BASE 0x60006000
+#define TEGRA_CLK_RESET_SIZE SZ_4K
+
+#define TEGRA_FLOW_CTRL_BASE 0x60007000
+#define TEGRA_FLOW_CTRL_SIZE 20
+
+#define TEGRA_AHB_DMA_BASE 0x60008000
+#define TEGRA_AHB_DMA_SIZE SZ_4K
+
+#define TEGRA_AHB_DMA_CH0_BASE 0x60009000
+#define TEGRA_AHB_DMA_CH0_SIZE 32
+
+#define TEGRA_APB_DMA_BASE 0x6000A000
+#define TEGRA_APB_DMA_SIZE SZ_4K
+
+#define TEGRA_APB_DMA_CH0_BASE 0x6000B000
+#define TEGRA_APB_DMA_CH0_SIZE 32
+
+#define TEGRA_AHB_GIZMO_BASE 0x6000C004
+#define TEGRA_AHB_GIZMO_SIZE 0x10C
+
+#define TEGRA_STATMON_BASE 0x6000C400
+#define TEGRA_STATMON_SIZE SZ_1K
+
+#define TEGRA_GPIO_BASE 0x6000D000
+#define TEGRA_GPIO_SIZE SZ_4K
+
+#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
+#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
+
+#define TEGRA_APB_MISC_BASE 0x70000000
+#define TEGRA_APB_MISC_SIZE SZ_4K
+
+#define TEGRA_APB_MISC_DAS_BASE 0x70000c00
+#define TEGRA_APB_MISC_DAS_SIZE SZ_128
+
+#define TEGRA_AC97_BASE 0x70002000
+#define TEGRA_AC97_SIZE SZ_512
+
+#define TEGRA_SPDIF_BASE 0x70002400
+#define TEGRA_SPDIF_SIZE SZ_512
+
+#define TEGRA_I2S1_BASE 0x70002800
+#define TEGRA_I2S1_SIZE SZ_256
+
+#define TEGRA_I2S2_BASE 0x70002A00
+#define TEGRA_I2S2_SIZE SZ_256
+
+#define TEGRA_UARTA_BASE 0x70006000
+#define TEGRA_UARTA_SIZE SZ_64
+
+#define TEGRA_UARTB_BASE 0x70006040
+#define TEGRA_UARTB_SIZE SZ_64
+
+#define TEGRA_UARTC_BASE 0x70006200
+#define TEGRA_UARTC_SIZE SZ_256
+
+#define TEGRA_UARTD_BASE 0x70006300
+#define TEGRA_UARTD_SIZE SZ_256
+
+#define TEGRA_UARTE_BASE 0x70006400
+#define TEGRA_UARTE_SIZE SZ_256
+
+#define TEGRA_NAND_BASE 0x70008000
+#define TEGRA_NAND_SIZE SZ_256
+
+#define TEGRA_HSMMC_BASE 0x70008500
+#define TEGRA_HSMMC_SIZE SZ_256
+
+#define TEGRA_SNOR_BASE 0x70009000
+#define TEGRA_SNOR_SIZE SZ_4K
+
+#define TEGRA_PWFM_BASE 0x7000A000
+#define TEGRA_PWFM_SIZE SZ_256
+
+#define TEGRA_PWFM0_BASE 0x7000A000
+#define TEGRA_PWFM0_SIZE 4
+
+#define TEGRA_PWFM1_BASE 0x7000A010
+#define TEGRA_PWFM1_SIZE 4
+
+#define TEGRA_PWFM2_BASE 0x7000A020
+#define TEGRA_PWFM2_SIZE 4
+
+#define TEGRA_PWFM3_BASE 0x7000A030
+#define TEGRA_PWFM3_SIZE 4
+
+#define TEGRA_MIPI_BASE 0x7000B000
+#define TEGRA_MIPI_SIZE SZ_256
+
+#define TEGRA_I2C_BASE 0x7000C000
+#define TEGRA_I2C_SIZE SZ_256
+
+#define TEGRA_TWC_BASE 0x7000C100
+#define TEGRA_TWC_SIZE SZ_256
+
+#define TEGRA_SPI_BASE 0x7000C380
+#define TEGRA_SPI_SIZE 48
+
+#define TEGRA_I2C2_BASE 0x7000C400
+#define TEGRA_I2C2_SIZE SZ_256
+
+#define TEGRA_I2C3_BASE 0x7000C500
+#define TEGRA_I2C3_SIZE SZ_256
+
+#define TEGRA_OWR_BASE 0x7000C600
+#define TEGRA_OWR_SIZE 80
+
+#define TEGRA_DVC_BASE 0x7000D000
+#define TEGRA_DVC_SIZE SZ_512
+
+#define TEGRA_SPI1_BASE 0x7000D400
+#define TEGRA_SPI1_SIZE SZ_512
+
+#define TEGRA_SPI2_BASE 0x7000D600
+#define TEGRA_SPI2_SIZE SZ_512
+
+#define TEGRA_SPI3_BASE 0x7000D800
+#define TEGRA_SPI3_SIZE SZ_512
+
+#define TEGRA_SPI4_BASE 0x7000DA00
+#define TEGRA_SPI4_SIZE SZ_512
+
+#define TEGRA_RTC_BASE 0x7000E000
+#define TEGRA_RTC_SIZE SZ_256
+
+#define TEGRA_KBC_BASE 0x7000E200
+#define TEGRA_KBC_SIZE SZ_256
+
+#define TEGRA_PMC_BASE 0x7000E400
+#define TEGRA_PMC_SIZE SZ_256
+
+#define TEGRA_MC_BASE 0x7000F000
+#define TEGRA_MC_SIZE SZ_1K
+
+#define TEGRA_EMC_BASE 0x7000F400
+#define TEGRA_EMC_SIZE SZ_1K
+
+#define TEGRA_FUSE_BASE 0x7000F800
+#define TEGRA_FUSE_SIZE SZ_1K
+
+#define TEGRA_KFUSE_BASE 0x7000FC00
+#define TEGRA_KFUSE_SIZE SZ_1K
+
+#define TEGRA_CSITE_BASE 0x70040000
+#define TEGRA_CSITE_SIZE SZ_256K
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB_SIZE SZ_16K
+
+#define TEGRA_USB2_BASE 0xC5004000
+#define TEGRA_USB2_SIZE SZ_16K
+
+#define TEGRA_USB3_BASE 0xC5008000
+#define TEGRA_USB3_SIZE SZ_16K
+
+#define TEGRA_SDMMC1_BASE 0xC8000000
+#define TEGRA_SDMMC1_SIZE SZ_512
+
+#define TEGRA_SDMMC2_BASE 0xC8000200
+#define TEGRA_SDMMC2_SIZE SZ_512
+
+#define TEGRA_SDMMC3_BASE 0xC8000400
+#define TEGRA_SDMMC3_SIZE SZ_512
+
+#define TEGRA_SDMMC4_BASE 0xC8000600
+#define TEGRA_SDMMC4_SIZE SZ_512
+
+#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
+# define TEGRA_DEBUG_UART_BASE 0
+#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
+# define TEGRA_DEBUG_UART_BASE TEGRA_UARTA_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
+# define TEGRA_DEBUG_UART_BASE TEGRA_UARTB_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
+# define TEGRA_DEBUG_UART_BASE TEGRA_UARTC_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
+# define TEGRA_DEBUG_UART_BASE TEGRA_UARTD_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
+# define TEGRA_DEBUG_UART_BASE TEGRA_UARTE_BASE
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
new file mode 100644
index 00000000..73265af4
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -0,0 +1,183 @@
+/*
+ * arch/arm/mach-tegra/include/mach/irqs.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IRQS_H
+#define __MACH_TEGRA_IRQS_H
+
+#define INT_GIC_BASE 0
+
+#define IRQ_LOCALTIMER 29
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+/* Primary Interrupt Controller */
+#define INT_PRI_BASE (INT_GIC_BASE + 32)
+#define INT_TMR1 (INT_PRI_BASE + 0)
+#define INT_TMR2 (INT_PRI_BASE + 1)
+#define INT_RTC (INT_PRI_BASE + 2)
+#define INT_I2S2 (INT_PRI_BASE + 3)
+#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
+#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
+#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
+#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
+#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
+#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
+#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
+#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
+#define INT_VDE_SXE (INT_PRI_BASE + 12)
+#define INT_I2S1 (INT_PRI_BASE + 13)
+#define INT_SDMMC1 (INT_PRI_BASE + 14)
+#define INT_SDMMC2 (INT_PRI_BASE + 15)
+#define INT_XIO (INT_PRI_BASE + 16)
+#define INT_VDE (INT_PRI_BASE + 17)
+#define INT_AVP_UCQ (INT_PRI_BASE + 18)
+#define INT_SDMMC3 (INT_PRI_BASE + 19)
+#define INT_USB (INT_PRI_BASE + 20)
+#define INT_USB2 (INT_PRI_BASE + 21)
+#define INT_PRI_RES_22 (INT_PRI_BASE + 22)
+#define INT_EIDE (INT_PRI_BASE + 23)
+#define INT_NANDFLASH (INT_PRI_BASE + 24)
+#define INT_VCP (INT_PRI_BASE + 25)
+#define INT_APB_DMA (INT_PRI_BASE + 26)
+#define INT_AHB_DMA (INT_PRI_BASE + 27)
+#define INT_GNT_0 (INT_PRI_BASE + 28)
+#define INT_GNT_1 (INT_PRI_BASE + 29)
+#define INT_OWR (INT_PRI_BASE + 30)
+#define INT_SDMMC4 (INT_PRI_BASE + 31)
+
+/* Secondary Interrupt Controller */
+#define INT_SEC_BASE (INT_PRI_BASE + 32)
+#define INT_GPIO1 (INT_SEC_BASE + 0)
+#define INT_GPIO2 (INT_SEC_BASE + 1)
+#define INT_GPIO3 (INT_SEC_BASE + 2)
+#define INT_GPIO4 (INT_SEC_BASE + 3)
+#define INT_UARTA (INT_SEC_BASE + 4)
+#define INT_UARTB (INT_SEC_BASE + 5)
+#define INT_I2C (INT_SEC_BASE + 6)
+#define INT_SPI (INT_SEC_BASE + 7)
+#define INT_TWC (INT_SEC_BASE + 8)
+#define INT_TMR3 (INT_SEC_BASE + 9)
+#define INT_TMR4 (INT_SEC_BASE + 10)
+#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
+#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
+#define INT_SPDIF (INT_SEC_BASE + 13)
+#define INT_UARTC (INT_SEC_BASE + 14)
+#define INT_MIPI (INT_SEC_BASE + 15)
+#define INT_EVENTA (INT_SEC_BASE + 16)
+#define INT_EVENTB (INT_SEC_BASE + 17)
+#define INT_EVENTC (INT_SEC_BASE + 18)
+#define INT_EVENTD (INT_SEC_BASE + 19)
+#define INT_VFIR (INT_SEC_BASE + 20)
+#define INT_DVC (INT_SEC_BASE + 21)
+#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
+#define INT_GPIO5 (INT_SEC_BASE + 23)
+#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
+#define INT_CPU1_PMU_INTR (INT_SEC_BASE + 25)
+#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
+#define INT_S_LINK1 (INT_SEC_BASE + 27)
+#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
+#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
+#define INT_DMA_TX (INT_SEC_BASE + 30)
+#define INT_DMA_RX (INT_SEC_BASE + 31)
+
+/* Tertiary Interrupt Controller */
+#define INT_TRI_BASE (INT_SEC_BASE + 32)
+#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
+#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
+#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
+#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
+#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
+#define INT_VI_GENERAL (INT_TRI_BASE + 5)
+#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
+#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
+#define INT_2D_GENERAL (INT_TRI_BASE + 8)
+#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
+#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
+#define INT_HDMI (INT_TRI_BASE + 11)
+#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
+#define INT_MC_GENERAL (INT_TRI_BASE + 13)
+#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
+#define INT_TRI_RES_15 (INT_TRI_BASE + 15)
+#define INT_TRI_RES_16 (INT_TRI_BASE + 16)
+#define INT_AC97 (INT_TRI_BASE + 17)
+#define INT_SPI_2 (INT_TRI_BASE + 18)
+#define INT_SPI_3 (INT_TRI_BASE + 19)
+#define INT_I2C2 (INT_TRI_BASE + 20)
+#define INT_KBC (INT_TRI_BASE + 21)
+#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
+#define INT_GPIO6 (INT_TRI_BASE + 23)
+#define INT_TVDAC (INT_TRI_BASE + 24)
+#define INT_GPIO7 (INT_TRI_BASE + 25)
+#define INT_UARTD (INT_TRI_BASE + 26)
+#define INT_UARTE (INT_TRI_BASE + 27)
+#define INT_I2C3 (INT_TRI_BASE + 28)
+#define INT_SPI_4 (INT_TRI_BASE + 29)
+#define INT_TRI_RES_30 (INT_TRI_BASE + 30)
+#define INT_SW_RESERVED (INT_TRI_BASE + 31)
+
+/* Quaternary Interrupt Controller */
+#define INT_QUAD_BASE (INT_TRI_BASE + 32)
+#define INT_SNOR (INT_QUAD_BASE + 0)
+#define INT_USB3 (INT_QUAD_BASE + 1)
+#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
+#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
+#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4)
+#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5)
+#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6)
+#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7)
+#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
+#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
+#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
+#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
+#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
+#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
+#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
+#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
+#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
+#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
+#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
+#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
+#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
+#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
+#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
+#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
+#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24)
+#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25)
+#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26)
+#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27)
+#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28)
+#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29)
+#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
+#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
+
+#define INT_MAIN_NR (INT_QUAD_BASE + 32 - INT_PRI_BASE)
+
+#define INT_GPIO_BASE (INT_PRI_BASE + INT_MAIN_NR)
+
+#define INT_GPIO_NR (28 * 8)
+
+#define TEGRA_NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
+
+#define INT_BOARD_BASE TEGRA_NR_IRQS
+#define NR_BOARD_IRQS 32
+
+#define NR_IRQS (INT_BOARD_BASE + NR_BOARD_IRQS)
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
new file mode 100644
index 00000000..4f3572a1
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/kbc.h
@@ -0,0 +1,60 @@
+/*
+ * Platform definitions for tegra-kbc keyboard input driver
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ASMARM_ARCH_TEGRA_KBC_H
+#define ASMARM_ARCH_TEGRA_KBC_H
+
+#include <linux/types.h>
+#include <linux/input/matrix_keypad.h>
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define KBC_MAX_GPIO 24
+#define KBC_MAX_KPENT 8
+#else
+#define KBC_MAX_GPIO 20
+#define KBC_MAX_KPENT 7
+#endif
+
+#define KBC_MAX_ROW 16
+#define KBC_MAX_COL 8
+#define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL)
+
+struct tegra_kbc_pin_cfg {
+ bool is_row;
+ unsigned char num;
+};
+
+struct tegra_kbc_wake_key {
+ u8 row:4;
+ u8 col:4;
+};
+
+struct tegra_kbc_platform_data {
+ unsigned int debounce_cnt;
+ unsigned int repeat_cnt;
+
+ struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
+ const struct matrix_keymap_data *keymap_data;
+
+ bool wakeup;
+ bool use_fn_map;
+ bool use_ghost_filter;
+};
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
new file mode 100644
index 00000000..537db3aa
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-tegra/include/mach/memory.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_MEMORY_H
+#define __MACH_TEGRA_MEMORY_H
+
+/* physical offset of RAM */
+#define PLAT_PHYS_OFFSET UL(0)
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-t2.h b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
new file mode 100644
index 00000000..4c262634
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux-t2.h
@@ -0,0 +1,184 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux-t2.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_T2_H
+#define __MACH_TEGRA_PINMUX_T2_H
+
+enum tegra_pingroup {
+ TEGRA_PINGROUP_ATA = 0,
+ TEGRA_PINGROUP_ATB,
+ TEGRA_PINGROUP_ATC,
+ TEGRA_PINGROUP_ATD,
+ TEGRA_PINGROUP_ATE,
+ TEGRA_PINGROUP_CDEV1,
+ TEGRA_PINGROUP_CDEV2,
+ TEGRA_PINGROUP_CRTP,
+ TEGRA_PINGROUP_CSUS,
+ TEGRA_PINGROUP_DAP1,
+ TEGRA_PINGROUP_DAP2,
+ TEGRA_PINGROUP_DAP3,
+ TEGRA_PINGROUP_DAP4,
+ TEGRA_PINGROUP_DDC,
+ TEGRA_PINGROUP_DTA,
+ TEGRA_PINGROUP_DTB,
+ TEGRA_PINGROUP_DTC,
+ TEGRA_PINGROUP_DTD,
+ TEGRA_PINGROUP_DTE,
+ TEGRA_PINGROUP_DTF,
+ TEGRA_PINGROUP_GMA,
+ TEGRA_PINGROUP_GMB,
+ TEGRA_PINGROUP_GMC,
+ TEGRA_PINGROUP_GMD,
+ TEGRA_PINGROUP_GME,
+ TEGRA_PINGROUP_GPU,
+ TEGRA_PINGROUP_GPU7,
+ TEGRA_PINGROUP_GPV,
+ TEGRA_PINGROUP_HDINT,
+ TEGRA_PINGROUP_I2CP,
+ TEGRA_PINGROUP_IRRX,
+ TEGRA_PINGROUP_IRTX,
+ TEGRA_PINGROUP_KBCA,
+ TEGRA_PINGROUP_KBCB,
+ TEGRA_PINGROUP_KBCC,
+ TEGRA_PINGROUP_KBCD,
+ TEGRA_PINGROUP_KBCE,
+ TEGRA_PINGROUP_KBCF,
+ TEGRA_PINGROUP_LCSN,
+ TEGRA_PINGROUP_LD0,
+ TEGRA_PINGROUP_LD1,
+ TEGRA_PINGROUP_LD10,
+ TEGRA_PINGROUP_LD11,
+ TEGRA_PINGROUP_LD12,
+ TEGRA_PINGROUP_LD13,
+ TEGRA_PINGROUP_LD14,
+ TEGRA_PINGROUP_LD15,
+ TEGRA_PINGROUP_LD16,
+ TEGRA_PINGROUP_LD17,
+ TEGRA_PINGROUP_LD2,
+ TEGRA_PINGROUP_LD3,
+ TEGRA_PINGROUP_LD4,
+ TEGRA_PINGROUP_LD5,
+ TEGRA_PINGROUP_LD6,
+ TEGRA_PINGROUP_LD7,
+ TEGRA_PINGROUP_LD8,
+ TEGRA_PINGROUP_LD9,
+ TEGRA_PINGROUP_LDC,
+ TEGRA_PINGROUP_LDI,
+ TEGRA_PINGROUP_LHP0,
+ TEGRA_PINGROUP_LHP1,
+ TEGRA_PINGROUP_LHP2,
+ TEGRA_PINGROUP_LHS,
+ TEGRA_PINGROUP_LM0,
+ TEGRA_PINGROUP_LM1,
+ TEGRA_PINGROUP_LPP,
+ TEGRA_PINGROUP_LPW0,
+ TEGRA_PINGROUP_LPW1,
+ TEGRA_PINGROUP_LPW2,
+ TEGRA_PINGROUP_LSC0,
+ TEGRA_PINGROUP_LSC1,
+ TEGRA_PINGROUP_LSCK,
+ TEGRA_PINGROUP_LSDA,
+ TEGRA_PINGROUP_LSDI,
+ TEGRA_PINGROUP_LSPI,
+ TEGRA_PINGROUP_LVP0,
+ TEGRA_PINGROUP_LVP1,
+ TEGRA_PINGROUP_LVS,
+ TEGRA_PINGROUP_OWC,
+ TEGRA_PINGROUP_PMC,
+ TEGRA_PINGROUP_PTA,
+ TEGRA_PINGROUP_RM,
+ TEGRA_PINGROUP_SDB,
+ TEGRA_PINGROUP_SDC,
+ TEGRA_PINGROUP_SDD,
+ TEGRA_PINGROUP_SDIO1,
+ TEGRA_PINGROUP_SLXA,
+ TEGRA_PINGROUP_SLXC,
+ TEGRA_PINGROUP_SLXD,
+ TEGRA_PINGROUP_SLXK,
+ TEGRA_PINGROUP_SPDI,
+ TEGRA_PINGROUP_SPDO,
+ TEGRA_PINGROUP_SPIA,
+ TEGRA_PINGROUP_SPIB,
+ TEGRA_PINGROUP_SPIC,
+ TEGRA_PINGROUP_SPID,
+ TEGRA_PINGROUP_SPIE,
+ TEGRA_PINGROUP_SPIF,
+ TEGRA_PINGROUP_SPIG,
+ TEGRA_PINGROUP_SPIH,
+ TEGRA_PINGROUP_UAA,
+ TEGRA_PINGROUP_UAB,
+ TEGRA_PINGROUP_UAC,
+ TEGRA_PINGROUP_UAD,
+ TEGRA_PINGROUP_UCA,
+ TEGRA_PINGROUP_UCB,
+ TEGRA_PINGROUP_UDA,
+ /* these pin groups only have pullup and pull down control */
+ TEGRA_PINGROUP_CK32,
+ TEGRA_PINGROUP_DDRC,
+ TEGRA_PINGROUP_PMCA,
+ TEGRA_PINGROUP_PMCB,
+ TEGRA_PINGROUP_PMCC,
+ TEGRA_PINGROUP_PMCD,
+ TEGRA_PINGROUP_PMCE,
+ TEGRA_PINGROUP_XM2C,
+ TEGRA_PINGROUP_XM2D,
+ TEGRA_MAX_PINGROUP,
+};
+
+enum tegra_drive_pingroup {
+ TEGRA_DRIVE_PINGROUP_AO1 = 0,
+ TEGRA_DRIVE_PINGROUP_AO2,
+ TEGRA_DRIVE_PINGROUP_AT1,
+ TEGRA_DRIVE_PINGROUP_AT2,
+ TEGRA_DRIVE_PINGROUP_CDEV1,
+ TEGRA_DRIVE_PINGROUP_CDEV2,
+ TEGRA_DRIVE_PINGROUP_CSUS,
+ TEGRA_DRIVE_PINGROUP_DAP1,
+ TEGRA_DRIVE_PINGROUP_DAP2,
+ TEGRA_DRIVE_PINGROUP_DAP3,
+ TEGRA_DRIVE_PINGROUP_DAP4,
+ TEGRA_DRIVE_PINGROUP_DBG,
+ TEGRA_DRIVE_PINGROUP_LCD1,
+ TEGRA_DRIVE_PINGROUP_LCD2,
+ TEGRA_DRIVE_PINGROUP_SDMMC2,
+ TEGRA_DRIVE_PINGROUP_SDMMC3,
+ TEGRA_DRIVE_PINGROUP_SPI,
+ TEGRA_DRIVE_PINGROUP_UAA,
+ TEGRA_DRIVE_PINGROUP_UAB,
+ TEGRA_DRIVE_PINGROUP_UART2,
+ TEGRA_DRIVE_PINGROUP_UART3,
+ TEGRA_DRIVE_PINGROUP_VI1,
+ TEGRA_DRIVE_PINGROUP_VI2,
+ TEGRA_DRIVE_PINGROUP_XM2A,
+ TEGRA_DRIVE_PINGROUP_XM2C,
+ TEGRA_DRIVE_PINGROUP_XM2D,
+ TEGRA_DRIVE_PINGROUP_XM2CLK,
+ TEGRA_DRIVE_PINGROUP_MEMCOMP,
+ TEGRA_DRIVE_PINGROUP_SDIO1,
+ TEGRA_DRIVE_PINGROUP_CRT,
+ TEGRA_DRIVE_PINGROUP_DDC,
+ TEGRA_DRIVE_PINGROUP_GMA,
+ TEGRA_DRIVE_PINGROUP_GMB,
+ TEGRA_DRIVE_PINGROUP_GMC,
+ TEGRA_DRIVE_PINGROUP_GMD,
+ TEGRA_DRIVE_PINGROUP_GME,
+ TEGRA_DRIVE_PINGROUP_OWR,
+ TEGRA_DRIVE_PINGROUP_UAD,
+ TEGRA_MAX_DRIVE_PINGROUP,
+};
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644
index 00000000..defd8775
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -0,0 +1,240 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_H
+#define __MACH_TEGRA_PINMUX_H
+
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
+#include "pinmux-t2.h"
+#else
+#error "Undefined Tegra architecture"
+#endif
+
+enum tegra_mux_func {
+ TEGRA_MUX_RSVD = 0x8000,
+ TEGRA_MUX_RSVD1 = 0x8000,
+ TEGRA_MUX_RSVD2 = 0x8001,
+ TEGRA_MUX_RSVD3 = 0x8002,
+ TEGRA_MUX_RSVD4 = 0x8003,
+ TEGRA_MUX_NONE = -1,
+ TEGRA_MUX_AHB_CLK,
+ TEGRA_MUX_APB_CLK,
+ TEGRA_MUX_AUDIO_SYNC,
+ TEGRA_MUX_CRT,
+ TEGRA_MUX_DAP1,
+ TEGRA_MUX_DAP2,
+ TEGRA_MUX_DAP3,
+ TEGRA_MUX_DAP4,
+ TEGRA_MUX_DAP5,
+ TEGRA_MUX_DISPLAYA,
+ TEGRA_MUX_DISPLAYB,
+ TEGRA_MUX_EMC_TEST0_DLL,
+ TEGRA_MUX_EMC_TEST1_DLL,
+ TEGRA_MUX_GMI,
+ TEGRA_MUX_GMI_INT,
+ TEGRA_MUX_HDMI,
+ TEGRA_MUX_I2C,
+ TEGRA_MUX_I2C2,
+ TEGRA_MUX_I2C3,
+ TEGRA_MUX_IDE,
+ TEGRA_MUX_IRDA,
+ TEGRA_MUX_KBC,
+ TEGRA_MUX_MIO,
+ TEGRA_MUX_MIPI_HS,
+ TEGRA_MUX_NAND,
+ TEGRA_MUX_OSC,
+ TEGRA_MUX_OWR,
+ TEGRA_MUX_PCIE,
+ TEGRA_MUX_PLLA_OUT,
+ TEGRA_MUX_PLLC_OUT1,
+ TEGRA_MUX_PLLM_OUT1,
+ TEGRA_MUX_PLLP_OUT2,
+ TEGRA_MUX_PLLP_OUT3,
+ TEGRA_MUX_PLLP_OUT4,
+ TEGRA_MUX_PWM,
+ TEGRA_MUX_PWR_INTR,
+ TEGRA_MUX_PWR_ON,
+ TEGRA_MUX_RTCK,
+ TEGRA_MUX_SDIO1,
+ TEGRA_MUX_SDIO2,
+ TEGRA_MUX_SDIO3,
+ TEGRA_MUX_SDIO4,
+ TEGRA_MUX_SFLASH,
+ TEGRA_MUX_SPDIF,
+ TEGRA_MUX_SPI1,
+ TEGRA_MUX_SPI2,
+ TEGRA_MUX_SPI2_ALT,
+ TEGRA_MUX_SPI3,
+ TEGRA_MUX_SPI4,
+ TEGRA_MUX_TRACE,
+ TEGRA_MUX_TWC,
+ TEGRA_MUX_UARTA,
+ TEGRA_MUX_UARTB,
+ TEGRA_MUX_UARTC,
+ TEGRA_MUX_UARTD,
+ TEGRA_MUX_UARTE,
+ TEGRA_MUX_ULPI,
+ TEGRA_MUX_VI,
+ TEGRA_MUX_VI_SENSOR_CLK,
+ TEGRA_MUX_XIO,
+ TEGRA_MUX_SAFE,
+ TEGRA_MAX_MUX,
+};
+
+enum tegra_pullupdown {
+ TEGRA_PUPD_NORMAL = 0,
+ TEGRA_PUPD_PULL_DOWN,
+ TEGRA_PUPD_PULL_UP,
+};
+
+enum tegra_tristate {
+ TEGRA_TRI_NORMAL = 0,
+ TEGRA_TRI_TRISTATE = 1,
+};
+
+enum tegra_vddio {
+ TEGRA_VDDIO_BB = 0,
+ TEGRA_VDDIO_LCD,
+ TEGRA_VDDIO_VI,
+ TEGRA_VDDIO_UART,
+ TEGRA_VDDIO_DDR,
+ TEGRA_VDDIO_NAND,
+ TEGRA_VDDIO_SYS,
+ TEGRA_VDDIO_AUDIO,
+ TEGRA_VDDIO_SD,
+};
+
+struct tegra_pingroup_config {
+ enum tegra_pingroup pingroup;
+ enum tegra_mux_func func;
+ enum tegra_pullupdown pupd;
+ enum tegra_tristate tristate;
+};
+
+enum tegra_slew {
+ TEGRA_SLEW_FASTEST = 0,
+ TEGRA_SLEW_FAST,
+ TEGRA_SLEW_SLOW,
+ TEGRA_SLEW_SLOWEST,
+ TEGRA_MAX_SLEW,
+};
+
+enum tegra_pull_strength {
+ TEGRA_PULL_0 = 0,
+ TEGRA_PULL_1,
+ TEGRA_PULL_2,
+ TEGRA_PULL_3,
+ TEGRA_PULL_4,
+ TEGRA_PULL_5,
+ TEGRA_PULL_6,
+ TEGRA_PULL_7,
+ TEGRA_PULL_8,
+ TEGRA_PULL_9,
+ TEGRA_PULL_10,
+ TEGRA_PULL_11,
+ TEGRA_PULL_12,
+ TEGRA_PULL_13,
+ TEGRA_PULL_14,
+ TEGRA_PULL_15,
+ TEGRA_PULL_16,
+ TEGRA_PULL_17,
+ TEGRA_PULL_18,
+ TEGRA_PULL_19,
+ TEGRA_PULL_20,
+ TEGRA_PULL_21,
+ TEGRA_PULL_22,
+ TEGRA_PULL_23,
+ TEGRA_PULL_24,
+ TEGRA_PULL_25,
+ TEGRA_PULL_26,
+ TEGRA_PULL_27,
+ TEGRA_PULL_28,
+ TEGRA_PULL_29,
+ TEGRA_PULL_30,
+ TEGRA_PULL_31,
+ TEGRA_MAX_PULL,
+};
+
+enum tegra_drive {
+ TEGRA_DRIVE_DIV_8 = 0,
+ TEGRA_DRIVE_DIV_4,
+ TEGRA_DRIVE_DIV_2,
+ TEGRA_DRIVE_DIV_1,
+ TEGRA_MAX_DRIVE,
+};
+
+enum tegra_hsm {
+ TEGRA_HSM_DISABLE = 0,
+ TEGRA_HSM_ENABLE,
+};
+
+enum tegra_schmitt {
+ TEGRA_SCHMITT_DISABLE = 0,
+ TEGRA_SCHMITT_ENABLE,
+};
+
+struct tegra_drive_pingroup_config {
+ enum tegra_drive_pingroup pingroup;
+ enum tegra_hsm hsm;
+ enum tegra_schmitt schmitt;
+ enum tegra_drive drive;
+ enum tegra_pull_strength pull_down;
+ enum tegra_pull_strength pull_up;
+ enum tegra_slew slew_rising;
+ enum tegra_slew slew_falling;
+};
+
+struct tegra_drive_pingroup_desc {
+ const char *name;
+ s16 reg;
+};
+
+struct tegra_pingroup_desc {
+ const char *name;
+ int funcs[4];
+ int func_safe;
+ int vddio;
+ s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */
+ s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
+ s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
+ s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
+ s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
+ s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
+};
+
+extern const struct tegra_pingroup_desc tegra_soc_pingroups[];
+extern const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[];
+
+int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
+ enum tegra_tristate tristate);
+int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
+ enum tegra_pullupdown pupd);
+
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config,
+ int len);
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+ int len);
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+ int len);
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+ int len);
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_tristate tristate);
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_pullupdown pupd);
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/powergate.h b/arch/arm/mach-tegra/include/mach/powergate.h
new file mode 100644
index 00000000..401d1b72
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/powergate.h
@@ -0,0 +1,40 @@
+/*
+ * drivers/regulator/tegra-regulator.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_POWERGATE_H_
+#define _MACH_TEGRA_POWERGATE_H_
+
+#define TEGRA_POWERGATE_CPU 0
+#define TEGRA_POWERGATE_3D 1
+#define TEGRA_POWERGATE_VENC 2
+#define TEGRA_POWERGATE_PCIE 3
+#define TEGRA_POWERGATE_VDEC 4
+#define TEGRA_POWERGATE_L2 5
+#define TEGRA_POWERGATE_MPE 6
+#define TEGRA_NUM_POWERGATE 7
+
+int tegra_powergate_power_on(int id);
+int tegra_powergate_power_off(int id);
+bool tegra_powergate_is_powered(int id);
+int tegra_powergate_remove_clamping(int id);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk);
+
+#endif /* _MACH_TEGRA_POWERGATE_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/sdhci.h b/arch/arm/mach-tegra/include/mach/sdhci.h
new file mode 100644
index 00000000..4231bc7b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/sdhci.h
@@ -0,0 +1,30 @@
+/*
+ * include/asm-arm/arch-tegra/include/mach/sdhci.h
+ *
+ * Copyright (C) 2009 Palm, Inc.
+ * Author: Yvonne Yip <y@palm.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 __ASM_ARM_ARCH_TEGRA_SDHCI_H
+#define __ASM_ARM_ARCH_TEGRA_SDHCI_H
+
+#include <linux/mmc/host.h>
+
+struct tegra_sdhci_platform_data {
+ int cd_gpio;
+ int wp_gpio;
+ int power_gpio;
+ int is_8bit;
+ int pm_flags;
+};
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/suspend.h b/arch/arm/mach-tegra/include/mach/suspend.h
new file mode 100644
index 00000000..5af8715d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/suspend.h
@@ -0,0 +1,38 @@
+/*
+ * arch/arm/mach-tegra/include/mach/suspend.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#ifndef _MACH_TEGRA_SUSPEND_H_
+#define _MACH_TEGRA_SUSPEND_H_
+
+void tegra_pinmux_suspend(void);
+void tegra_irq_suspend(void);
+void tegra_gpio_suspend(void);
+void tegra_clk_suspend(void);
+void tegra_dma_suspend(void);
+void tegra_timer_suspend(void);
+
+void tegra_pinmux_resume(void);
+void tegra_irq_resume(void);
+void tegra_gpio_resume(void);
+void tegra_clk_resume(void);
+void tegra_dma_resume(void);
+void tegra_timer_resume(void);
+
+#endif /* _MACH_TEGRA_SUSPEND_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
new file mode 100644
index 00000000..d0183d87
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-tegra/include/mach/system.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_SYSTEM_H
+#define __MACH_TEGRA_SYSTEM_H
+
+#include <mach/hardware.h>
+#include <mach/iomap.h>
+
+extern void (*arch_reset)(char mode, const char *cmd);
+
+static inline void arch_idle(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
new file mode 100644
index 00000000..9d293344
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
+ *
+ * Copyright 2011 NVIDIA, 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.
+ *
+ */
+
+struct tegra_wm8903_platform_data {
+ int gpio_spkr_en;
+ int gpio_hp_det;
+ int gpio_hp_mute;
+ int gpio_int_mic_en;
+ int gpio_ext_mic_en;
+};
diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h
new file mode 100644
index 00000000..a44ccbdb
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/timex.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-tegra/include/mach/timex.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_TIMEX_H
+#define __MACH_TEGRA_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
new file mode 100644
index 00000000..4e832377
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -0,0 +1,64 @@
+/*
+ * arch/arm/mach-tegra/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_UNCOMPRESS_H
+#define __MACH_TEGRA_UNCOMPRESS_H
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <mach/iomap.h>
+
+static void putc(int c)
+{
+ volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+ int shift = 2;
+
+ if (uart == NULL)
+ return;
+
+ while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX << shift] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+ volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+ int shift = 2;
+
+ if (uart == NULL)
+ return;
+
+ uart[UART_LCR << shift] |= UART_LCR_DLAB;
+ uart[UART_DLL << shift] = 0x75;
+ uart[UART_DLM << shift] = 0x0;
+ uart[UART_LCR << shift] = 3;
+}
+
+static inline void arch_decomp_wdog(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/usb_phy.h b/arch/arm/mach-tegra/include/mach/usb_phy.h
new file mode 100644
index 00000000..d4b8f9e2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/usb_phy.h
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-tegra/include/mach/usb_phy.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_USB_PHY_H
+#define __MACH_USB_PHY_H
+
+#include <linux/clk.h>
+#include <linux/usb/otg.h>
+
+struct tegra_utmip_config {
+ u8 hssync_start_delay;
+ u8 elastic_limit;
+ u8 idle_wait_delay;
+ u8 term_range_adj;
+ u8 xcvr_setup;
+ u8 xcvr_lsfslew;
+ u8 xcvr_lsrslew;
+};
+
+struct tegra_ulpi_config {
+ int reset_gpio;
+ const char *clk;
+};
+
+enum tegra_usb_phy_port_speed {
+ TEGRA_USB_PHY_PORT_SPEED_FULL = 0,
+ TEGRA_USB_PHY_PORT_SPEED_LOW,
+ TEGRA_USB_PHY_PORT_SPEED_HIGH,
+};
+
+enum tegra_usb_phy_mode {
+ TEGRA_USB_PHY_MODE_DEVICE,
+ TEGRA_USB_PHY_MODE_HOST,
+};
+
+struct tegra_xtal_freq;
+
+struct tegra_usb_phy {
+ int instance;
+ const struct tegra_xtal_freq *freq;
+ void __iomem *regs;
+ void __iomem *pad_regs;
+ struct clk *clk;
+ struct clk *pll_u;
+ struct clk *pad_clk;
+ enum tegra_usb_phy_mode mode;
+ void *config;
+ struct otg_transceiver *ulpi;
+};
+
+struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
+ void *config, enum tegra_usb_phy_mode phy_mode);
+
+int tegra_usb_phy_power_on(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_power_off(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_preresume(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_postresume(struct tegra_usb_phy *phy);
+
+void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
+ enum tegra_usb_phy_port_speed port_speed);
+
+void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy);
+
+void tegra_usb_phy_close(struct tegra_usb_phy *phy);
+
+#endif /* __MACH_USB_PHY_H */
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h
new file mode 100644
index 00000000..fd6aa65b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/vmalloc.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-tegra/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_VMALLOC_H
+#define __MACH_TEGRA_VMALLOC_H
+
+#include <asm/sizes.h>
+
+#define VMALLOC_END 0xFE000000UL
+
+#endif
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
new file mode 100644
index 00000000..31848a95
--- /dev/null
+++ b/arch/arm/mach-tegra/io.c
@@ -0,0 +1,84 @@
+/*
+ * arch/arm/mach-tegra/io.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
+#include "board.h"
+
+static struct map_desc tegra_io_desc[] __initdata = {
+ {
+ .virtual = IO_PPSB_VIRT,
+ .pfn = __phys_to_pfn(IO_PPSB_PHYS),
+ .length = IO_PPSB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_APB_VIRT,
+ .pfn = __phys_to_pfn(IO_APB_PHYS),
+ .length = IO_APB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_CPU_VIRT,
+ .pfn = __phys_to_pfn(IO_CPU_PHYS),
+ .length = IO_CPU_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_IRAM_VIRT,
+ .pfn = __phys_to_pfn(IO_IRAM_PHYS),
+ .length = IO_IRAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init tegra_map_common_io(void)
+{
+ iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
+}
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+ void __iomem *v = IO_ADDRESS(p);
+ if (v == NULL)
+ v = __arm_ioremap(p, size, type);
+ return v;
+}
+EXPORT_SYMBOL(tegra_ioremap);
+
+void tegra_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(tegra_iounmap);
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
new file mode 100644
index 00000000..4956c3ce
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * Copyright (C) 2010, NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/gic.h>
+
+#include <mach/iomap.h>
+
+#include "board.h"
+
+#define INT_SYS_NR (INT_GPIO_BASE - INT_PRI_BASE)
+#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
+#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
+
+#define ICTLR_CPU_IEP_VFIQ 0x08
+#define ICTLR_CPU_IEP_FIR 0x14
+#define ICTLR_CPU_IEP_FIR_SET 0x18
+#define ICTLR_CPU_IEP_FIR_CLR 0x1c
+
+#define ICTLR_CPU_IER 0x20
+#define ICTLR_CPU_IER_SET 0x24
+#define ICTLR_CPU_IER_CLR 0x28
+#define ICTLR_CPU_IEP_CLASS 0x2C
+
+#define ICTLR_COP_IER 0x30
+#define ICTLR_COP_IER_SET 0x34
+#define ICTLR_COP_IER_CLR 0x38
+#define ICTLR_COP_IEP_CLASS 0x3c
+
+#define NUM_ICTLRS 4
+#define FIRST_LEGACY_IRQ 32
+
+static void __iomem *ictlr_reg_base[] = {
+ IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
+ IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+};
+
+static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
+{
+ void __iomem *base;
+ u32 mask;
+
+ BUG_ON(irq < FIRST_LEGACY_IRQ ||
+ irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
+
+ base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
+ mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
+
+ __raw_writel(mask, base + reg);
+}
+
+static void tegra_mask(struct irq_data *d)
+{
+ if (d->irq < FIRST_LEGACY_IRQ)
+ return;
+
+ tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR);
+}
+
+static void tegra_unmask(struct irq_data *d)
+{
+ if (d->irq < FIRST_LEGACY_IRQ)
+ return;
+
+ tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET);
+}
+
+static void tegra_ack(struct irq_data *d)
+{
+ if (d->irq < FIRST_LEGACY_IRQ)
+ return;
+
+ tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR);
+}
+
+static void tegra_eoi(struct irq_data *d)
+{
+ if (d->irq < FIRST_LEGACY_IRQ)
+ return;
+
+ tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR);
+}
+
+static int tegra_retrigger(struct irq_data *d)
+{
+ if (d->irq < FIRST_LEGACY_IRQ)
+ return 0;
+
+ tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET);
+
+ return 1;
+}
+
+void __init tegra_init_irq(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_ICTLRS; i++) {
+ void __iomem *ictlr = ictlr_reg_base[i];
+ writel(~0, ictlr + ICTLR_CPU_IER_CLR);
+ writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
+ }
+
+ gic_arch_extn.irq_ack = tegra_ack;
+ gic_arch_extn.irq_eoi = tegra_eoi;
+ gic_arch_extn.irq_mask = tegra_mask;
+ gic_arch_extn.irq_unmask = tegra_unmask;
+ gic_arch_extn.irq_retrigger = tegra_retrigger;
+
+ gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
+ IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+}
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
new file mode 100644
index 00000000..e91d681d
--- /dev/null
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-tegra/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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/irq.h>
+#include <asm/smp_twd.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-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
new file mode 100644
index 00000000..2941212b
--- /dev/null
+++ b/arch/arm/mach-tegra/pcie.c
@@ -0,0 +1,933 @@
+/*
+ * arch/arm/mach-tegra/pci.c
+ *
+ * PCIe host controller driver for TEGRA(2) SOCs
+ *
+ * Copyright (c) 2010, CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on NVIDIA PCIe driver
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * Bits taken from arch/arm/mach-dove/pcie.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <asm/sizes.h>
+#include <asm/mach/pci.h>
+
+#include <mach/pinmux.h>
+#include <mach/iomap.h>
+#include <mach/clk.h>
+#include <mach/powergate.h>
+
+/* register definitions */
+#define AFI_OFFSET 0x3800
+#define PADS_OFFSET 0x3000
+#define RP0_OFFSET 0x0000
+#define RP1_OFFSET 0x1000
+
+#define AFI_AXI_BAR0_SZ 0x00
+#define AFI_AXI_BAR1_SZ 0x04
+#define AFI_AXI_BAR2_SZ 0x08
+#define AFI_AXI_BAR3_SZ 0x0c
+#define AFI_AXI_BAR4_SZ 0x10
+#define AFI_AXI_BAR5_SZ 0x14
+
+#define AFI_AXI_BAR0_START 0x18
+#define AFI_AXI_BAR1_START 0x1c
+#define AFI_AXI_BAR2_START 0x20
+#define AFI_AXI_BAR3_START 0x24
+#define AFI_AXI_BAR4_START 0x28
+#define AFI_AXI_BAR5_START 0x2c
+
+#define AFI_FPCI_BAR0 0x30
+#define AFI_FPCI_BAR1 0x34
+#define AFI_FPCI_BAR2 0x38
+#define AFI_FPCI_BAR3 0x3c
+#define AFI_FPCI_BAR4 0x40
+#define AFI_FPCI_BAR5 0x44
+
+#define AFI_CACHE_BAR0_SZ 0x48
+#define AFI_CACHE_BAR0_ST 0x4c
+#define AFI_CACHE_BAR1_SZ 0x50
+#define AFI_CACHE_BAR1_ST 0x54
+
+#define AFI_MSI_BAR_SZ 0x60
+#define AFI_MSI_FPCI_BAR_ST 0x64
+#define AFI_MSI_AXI_BAR_ST 0x68
+
+#define AFI_CONFIGURATION 0xac
+#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
+
+#define AFI_FPCI_ERROR_MASKS 0xb0
+
+#define AFI_INTR_MASK 0xb4
+#define AFI_INTR_MASK_INT_MASK (1 << 0)
+#define AFI_INTR_MASK_MSI_MASK (1 << 8)
+
+#define AFI_INTR_CODE 0xb8
+#define AFI_INTR_CODE_MASK 0xf
+#define AFI_INTR_MASTER_ABORT 4
+#define AFI_INTR_LEGACY 6
+
+#define AFI_INTR_SIGNATURE 0xbc
+#define AFI_SM_INTR_ENABLE 0xc4
+
+#define AFI_AFI_INTR_ENABLE 0xc8
+#define AFI_INTR_EN_INI_SLVERR (1 << 0)
+#define AFI_INTR_EN_INI_DECERR (1 << 1)
+#define AFI_INTR_EN_TGT_SLVERR (1 << 2)
+#define AFI_INTR_EN_TGT_DECERR (1 << 3)
+#define AFI_INTR_EN_TGT_WRERR (1 << 4)
+#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
+#define AFI_INTR_EN_AXI_DECERR (1 << 6)
+#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
+
+#define AFI_PCIE_CONFIG 0x0f8
+#define AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE (1 << 1)
+#define AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE (1 << 2)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
+
+#define AFI_FUSE 0x104
+#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
+
+#define AFI_PEX0_CTRL 0x110
+#define AFI_PEX1_CTRL 0x118
+#define AFI_PEX_CTRL_RST (1 << 0)
+#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
+
+#define RP_VEND_XP 0x00000F00
+#define RP_VEND_XP_DL_UP (1 << 30)
+
+#define RP_LINK_CONTROL_STATUS 0x00000090
+#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
+
+#define PADS_CTL_SEL 0x0000009C
+
+#define PADS_CTL 0x000000A0
+#define PADS_CTL_IDDQ_1L (1 << 0)
+#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
+#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
+
+#define PADS_PLL_CTL 0x000000B8
+#define PADS_PLL_CTL_RST_B4SM (1 << 1)
+#define PADS_PLL_CTL_LOCKDET (1 << 8)
+#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (1 << 16)
+#define PADS_PLL_CTL_REFCLK_EXTERNAL (2 << 16)
+#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
+
+/* PMC access is required for PCIE xclk (un)clamping */
+#define PMC_SCRATCH42 0x144
+#define PMC_SCRATCH42_PCX_CLAMP (1 << 0)
+
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+
+#define pmc_writel(value, reg) \
+ __raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+ __raw_readl((u32)reg_pmc_base + (reg))
+
+/*
+ * Tegra2 defines 1GB in the AXI address map for PCIe.
+ *
+ * That address space is split into different regions, with sizes and
+ * offsets as follows:
+ *
+ * 0x80000000 - 0x80003fff - PCI controller registers
+ * 0x80004000 - 0x80103fff - PCI configuration space
+ * 0x80104000 - 0x80203fff - PCI extended configuration space
+ * 0x80203fff - 0x803fffff - unused
+ * 0x80400000 - 0x8040ffff - downstream IO
+ * 0x80410000 - 0x8fffffff - unused
+ * 0x90000000 - 0x9fffffff - non-prefetchable memory
+ * 0xa0000000 - 0xbfffffff - prefetchable memory
+ */
+#define TEGRA_PCIE_BASE 0x80000000
+
+#define PCIE_REGS_SZ SZ_16K
+#define PCIE_CFG_OFF PCIE_REGS_SZ
+#define PCIE_CFG_SZ SZ_1M
+#define PCIE_EXT_CFG_OFF (PCIE_CFG_SZ + PCIE_CFG_OFF)
+#define PCIE_EXT_CFG_SZ SZ_1M
+#define PCIE_IOMAP_SZ (PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
+
+#define MMIO_BASE (TEGRA_PCIE_BASE + SZ_4M)
+#define MMIO_SIZE SZ_64K
+#define MEM_BASE_0 (TEGRA_PCIE_BASE + SZ_256M)
+#define MEM_SIZE_0 SZ_128M
+#define MEM_BASE_1 (MEM_BASE_0 + MEM_SIZE_0)
+#define MEM_SIZE_1 SZ_128M
+#define PREFETCH_MEM_BASE_0 (MEM_BASE_1 + MEM_SIZE_1)
+#define PREFETCH_MEM_SIZE_0 SZ_128M
+#define PREFETCH_MEM_BASE_1 (PREFETCH_MEM_BASE_0 + PREFETCH_MEM_SIZE_0)
+#define PREFETCH_MEM_SIZE_1 SZ_128M
+
+#define PCIE_CONF_BUS(b) ((b) << 16)
+#define PCIE_CONF_DEV(d) ((d) << 11)
+#define PCIE_CONF_FUNC(f) ((f) << 8)
+#define PCIE_CONF_REG(r) \
+ (((r) & ~0x3) | (((r) < 256) ? PCIE_CFG_OFF : PCIE_EXT_CFG_OFF))
+
+struct tegra_pcie_port {
+ int index;
+ u8 root_bus_nr;
+ void __iomem *base;
+
+ bool link_up;
+
+ char io_space_name[16];
+ char mem_space_name[16];
+ char prefetch_space_name[20];
+ struct resource res[3];
+};
+
+struct tegra_pcie_info {
+ struct tegra_pcie_port port[2];
+ int num_ports;
+
+ void __iomem *regs;
+ struct resource res_mmio;
+
+ struct clk *pex_clk;
+ struct clk *afi_clk;
+ struct clk *pcie_xclk;
+ struct clk *pll_e;
+};
+
+static struct tegra_pcie_info tegra_pcie = {
+ .res_mmio = {
+ .name = "PCI IO",
+ .start = MMIO_BASE,
+ .end = MMIO_BASE + MMIO_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+void __iomem *tegra_pcie_io_base;
+EXPORT_SYMBOL(tegra_pcie_io_base);
+
+static inline void afi_writel(u32 value, unsigned long offset)
+{
+ writel(value, offset + AFI_OFFSET + tegra_pcie.regs);
+}
+
+static inline u32 afi_readl(unsigned long offset)
+{
+ return readl(offset + AFI_OFFSET + tegra_pcie.regs);
+}
+
+static inline void pads_writel(u32 value, unsigned long offset)
+{
+ writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
+}
+
+static inline u32 pads_readl(unsigned long offset)
+{
+ return readl(offset + PADS_OFFSET + tegra_pcie.regs);
+}
+
+static struct tegra_pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = tegra_pcie.num_ports - 1; i >= 0; i--) {
+ int rbus = tegra_pcie.port[i].root_bus_nr;
+ if (rbus != -1 && rbus == bus)
+ break;
+ }
+
+ return i >= 0 ? tegra_pcie.port + i : NULL;
+}
+
+static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ struct tegra_pcie_port *pp = bus_to_port(bus->number);
+ void __iomem *addr;
+
+ if (pp) {
+ if (devfn != 0) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ addr = pp->base + (where & ~0x3);
+ } else {
+ addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ PCIE_CONF_REG(where));
+ }
+
+ *val = readl(addr);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ struct tegra_pcie_port *pp = bus_to_port(bus->number);
+ void __iomem *addr;
+
+ u32 mask;
+ u32 tmp;
+
+ if (pp) {
+ if (devfn != 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pp->base + (where & ~0x3);
+ } else {
+ addr = tegra_pcie.regs + (PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ PCIE_CONF_REG(where));
+ }
+
+ if (size == 4) {
+ writel(val, addr);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ if (size == 2)
+ mask = ~(0xffff << ((where & 0x3) * 8));
+ else if (size == 1)
+ mask = ~(0xff << ((where & 0x3) * 8));
+ else
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ tmp = readl(addr) & mask;
+ tmp |= val << ((where & 0x3) * 8);
+ writel(tmp, addr);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops tegra_pcie_ops = {
+ .read = tegra_pcie_read_conf,
+ .write = tegra_pcie_write_conf,
+};
+
+static void __devinit tegra_pcie_fixup_bridge(struct pci_dev *dev)
+{
+ u16 reg;
+
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+ pci_read_config_word(dev, PCI_COMMAND, &reg);
+ reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+ pci_write_config_word(dev, PCI_COMMAND, reg);
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
+
+/* Tegra PCIE root complex wrongly reports device class */
+static void __devinit tegra_pcie_fixup_class(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
+
+/* Tegra PCIE requires relaxed ordering */
+static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev)
+{
+ u16 val16;
+ int pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+
+ if (pos <= 0) {
+ dev_err(&dev->dev, "skipping relaxed ordering fixup\n");
+ return;
+ }
+
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16);
+ val16 |= PCI_EXP_DEVCTL_RELAX_EN;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
+
+static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct tegra_pcie_port *pp;
+
+ if (nr >= tegra_pcie.num_ports)
+ return 0;
+
+ pp = tegra_pcie.port + nr;
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * IORESOURCE_IO
+ */
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = PCIBIOS_MIN_IO;
+ pp->res[0].end = pp->res[0].start + SZ_32K - 1;
+ } else {
+ pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K;
+ pp->res[0].end = IO_SPACE_LIMIT;
+ }
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = MEM_BASE_0;
+ pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1;
+ } else {
+ pp->res[1].start = MEM_BASE_1;
+ pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1;
+ }
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ /*
+ * IORESOURCE_MEM | IORESOURCE_PREFETCH
+ */
+ snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
+ "PCIe %d PREFETCH MEM", pp->index);
+ pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
+ pp->res[2].name = pp->prefetch_space_name;
+ if (pp->index == 0) {
+ pp->res[2].start = PREFETCH_MEM_BASE_0;
+ pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1;
+ } else {
+ pp->res[2].start = PREFETCH_MEM_BASE_1;
+ pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1;
+ }
+ pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ if (request_resource(&iomem_resource, &pp->res[2]))
+ panic("Request PCIe Prefetch Memory resource failed\n");
+ sys->resource[2] = &pp->res[2];
+
+ return 1;
+}
+
+static int tegra_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return INT_PCIE_INTR;
+}
+
+static struct pci_bus __init *tegra_pcie_scan_bus(int nr,
+ struct pci_sys_data *sys)
+{
+ struct tegra_pcie_port *pp;
+
+ if (nr >= tegra_pcie.num_ports)
+ return 0;
+
+ pp = tegra_pcie.port + nr;
+ pp->root_bus_nr = sys->busnr;
+
+ return pci_scan_bus(sys->busnr, &tegra_pcie_ops, sys);
+}
+
+static struct hw_pci tegra_pcie_hw __initdata = {
+ .nr_controllers = 2,
+ .setup = tegra_pcie_setup,
+ .scan = tegra_pcie_scan_bus,
+ .swizzle = pci_std_swizzle,
+ .map_irq = tegra_pcie_map_irq,
+};
+
+
+static irqreturn_t tegra_pcie_isr(int irq, void *arg)
+{
+ const char *err_msg[] = {
+ "Unknown",
+ "AXI slave error",
+ "AXI decode error",
+ "Target abort",
+ "Master abort",
+ "Invalid write",
+ "Response decoding error",
+ "AXI response decoding error",
+ "Transcation timeout",
+ };
+
+ u32 code, signature;
+
+ code = afi_readl(AFI_INTR_CODE) & AFI_INTR_CODE_MASK;
+ signature = afi_readl(AFI_INTR_SIGNATURE);
+ afi_writel(0, AFI_INTR_CODE);
+
+ if (code == AFI_INTR_LEGACY)
+ return IRQ_NONE;
+
+ if (code >= ARRAY_SIZE(err_msg))
+ code = 0;
+
+ /*
+ * do not pollute kernel log with master abort reports since they
+ * happen a lot during enumeration
+ */
+ if (code == AFI_INTR_MASTER_ABORT)
+ pr_debug("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+ else
+ pr_err("PCIE: %s, signature: %08x\n", err_msg[code], signature);
+
+ return IRQ_HANDLED;
+}
+
+static void tegra_pcie_setup_translations(void)
+{
+ u32 fpci_bar;
+ u32 size;
+ u32 axi_address;
+
+ /* Bar 0: config Bar */
+ fpci_bar = ((u32)0xfdff << 16);
+ size = PCIE_CFG_SZ;
+ axi_address = TEGRA_PCIE_BASE + PCIE_CFG_OFF;
+ afi_writel(axi_address, AFI_AXI_BAR0_START);
+ afi_writel(size >> 12, AFI_AXI_BAR0_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR0);
+
+ /* Bar 1: extended config Bar */
+ fpci_bar = ((u32)0xfe1 << 20);
+ size = PCIE_EXT_CFG_SZ;
+ axi_address = TEGRA_PCIE_BASE + PCIE_EXT_CFG_OFF;
+ afi_writel(axi_address, AFI_AXI_BAR1_START);
+ afi_writel(size >> 12, AFI_AXI_BAR1_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR1);
+
+ /* Bar 2: downstream IO bar */
+ fpci_bar = ((__u32)0xfdfc << 16);
+ size = MMIO_SIZE;
+ axi_address = MMIO_BASE;
+ afi_writel(axi_address, AFI_AXI_BAR2_START);
+ afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR2);
+
+ /* Bar 3: prefetchable memory BAR */
+ fpci_bar = (((PREFETCH_MEM_BASE_0 >> 12) & 0x0fffffff) << 4) | 0x1;
+ size = PREFETCH_MEM_SIZE_0 + PREFETCH_MEM_SIZE_1;
+ axi_address = PREFETCH_MEM_BASE_0;
+ afi_writel(axi_address, AFI_AXI_BAR3_START);
+ afi_writel(size >> 12, AFI_AXI_BAR3_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR3);
+
+ /* Bar 4: non prefetchable memory BAR */
+ fpci_bar = (((MEM_BASE_0 >> 12) & 0x0FFFFFFF) << 4) | 0x1;
+ size = MEM_SIZE_0 + MEM_SIZE_1;
+ axi_address = MEM_BASE_0;
+ afi_writel(axi_address, AFI_AXI_BAR4_START);
+ afi_writel(size >> 12, AFI_AXI_BAR4_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR4);
+
+ /* Bar 5: NULL out the remaining BAR as it is not used */
+ fpci_bar = 0;
+ size = 0;
+ axi_address = 0;
+ afi_writel(axi_address, AFI_AXI_BAR5_START);
+ afi_writel(size >> 12, AFI_AXI_BAR5_SZ);
+ afi_writel(fpci_bar, AFI_FPCI_BAR5);
+
+ /* map all upstream transactions as uncached */
+ afi_writel(PHYS_OFFSET, AFI_CACHE_BAR0_ST);
+ afi_writel(0, AFI_CACHE_BAR0_SZ);
+ afi_writel(0, AFI_CACHE_BAR1_ST);
+ afi_writel(0, AFI_CACHE_BAR1_SZ);
+
+ /* No MSI */
+ afi_writel(0, AFI_MSI_FPCI_BAR_ST);
+ afi_writel(0, AFI_MSI_BAR_SZ);
+ afi_writel(0, AFI_MSI_AXI_BAR_ST);
+ afi_writel(0, AFI_MSI_BAR_SZ);
+}
+
+static void tegra_pcie_enable_controller(void)
+{
+ u32 val, reg;
+ int i;
+
+ /* Enable slot clock and pulse the reset signals */
+ for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
+ val = afi_readl(reg) | AFI_PEX_CTRL_REFCLK_EN;
+ afi_writel(val, reg);
+ val &= ~AFI_PEX_CTRL_RST;
+ afi_writel(val, reg);
+
+ val = afi_readl(reg) | AFI_PEX_CTRL_RST;
+ afi_writel(val, reg);
+ }
+
+ /* Enable dual controller and both ports */
+ val = afi_readl(AFI_PCIE_CONFIG);
+ val &= ~(AFI_PCIE_CONFIG_PCIEC0_DISABLE_DEVICE |
+ AFI_PCIE_CONFIG_PCIEC1_DISABLE_DEVICE |
+ AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK);
+ val |= AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
+ afi_writel(val, AFI_PCIE_CONFIG);
+
+ val = afi_readl(AFI_FUSE) & ~AFI_FUSE_PCIE_T0_GEN2_DIS;
+ afi_writel(val, AFI_FUSE);
+
+ /* Initialze internal PHY, enable up to 16 PCIE lanes */
+ pads_writel(0x0, PADS_CTL_SEL);
+
+ /* override IDDQ to 1 on all 4 lanes */
+ val = pads_readl(PADS_CTL) | PADS_CTL_IDDQ_1L;
+ pads_writel(val, PADS_CTL);
+
+ /*
+ * set up PHY PLL inputs select PLLE output as refclock,
+ * set TX ref sel to div10 (not div5)
+ */
+ val = pads_readl(PADS_PLL_CTL);
+ val &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
+ val |= (PADS_PLL_CTL_REFCLK_INTERNAL_CML | PADS_PLL_CTL_TXCLKREF_DIV10);
+ pads_writel(val, PADS_PLL_CTL);
+
+ /* take PLL out of reset */
+ val = pads_readl(PADS_PLL_CTL) | PADS_PLL_CTL_RST_B4SM;
+ pads_writel(val, PADS_PLL_CTL);
+
+ /*
+ * Hack, set the clock voltage to the DEFAULT provided by hw folks.
+ * This doesn't exist in the documentation
+ */
+ pads_writel(0xfa5cfa5c, 0xc8);
+
+ /* Wait for the PLL to lock */
+ do {
+ val = pads_readl(PADS_PLL_CTL);
+ } while (!(val & PADS_PLL_CTL_LOCKDET));
+
+ /* turn off IDDQ override */
+ val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L;
+ pads_writel(val, PADS_CTL);
+
+ /* enable TX/RX data */
+ val = pads_readl(PADS_CTL);
+ val |= (PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L);
+ pads_writel(val, PADS_CTL);
+
+ /* Take the PCIe interface module out of reset */
+ tegra_periph_reset_deassert(tegra_pcie.pcie_xclk);
+
+ /* Finally enable PCIe */
+ val = afi_readl(AFI_CONFIGURATION) | AFI_CONFIGURATION_EN_FPCI;
+ afi_writel(val, AFI_CONFIGURATION);
+
+ val = (AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
+ AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
+ AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR);
+ afi_writel(val, AFI_AFI_INTR_ENABLE);
+ afi_writel(0xffffffff, AFI_SM_INTR_ENABLE);
+
+ /* FIXME: No MSI for now, only INT */
+ afi_writel(AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+
+ /* Disable all execptions */
+ afi_writel(0, AFI_FPCI_ERROR_MASKS);
+
+ return;
+}
+
+static void tegra_pcie_xclk_clamp(bool clamp)
+{
+ u32 reg;
+
+ reg = pmc_readl(PMC_SCRATCH42) & ~PMC_SCRATCH42_PCX_CLAMP;
+
+ if (clamp)
+ reg |= PMC_SCRATCH42_PCX_CLAMP;
+
+ pmc_writel(reg, PMC_SCRATCH42);
+}
+
+static void tegra_pcie_power_off(void)
+{
+ tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
+ tegra_periph_reset_assert(tegra_pcie.afi_clk);
+ tegra_periph_reset_assert(tegra_pcie.pex_clk);
+
+ tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+ tegra_pcie_xclk_clamp(true);
+}
+
+static int tegra_pcie_power_regate(void)
+{
+ int err;
+
+ tegra_pcie_power_off();
+
+ tegra_pcie_xclk_clamp(true);
+
+ tegra_periph_reset_assert(tegra_pcie.pcie_xclk);
+ tegra_periph_reset_assert(tegra_pcie.afi_clk);
+
+ err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
+ tegra_pcie.pex_clk);
+ if (err) {
+ pr_err("PCIE: powerup sequence failed: %d\n", err);
+ return err;
+ }
+
+ tegra_periph_reset_deassert(tegra_pcie.afi_clk);
+
+ tegra_pcie_xclk_clamp(false);
+
+ clk_enable(tegra_pcie.afi_clk);
+ clk_enable(tegra_pcie.pex_clk);
+ return clk_enable(tegra_pcie.pll_e);
+}
+
+static int tegra_pcie_clocks_get(void)
+{
+ int err;
+
+ tegra_pcie.pex_clk = clk_get(NULL, "pex");
+ if (IS_ERR(tegra_pcie.pex_clk))
+ return PTR_ERR(tegra_pcie.pex_clk);
+
+ tegra_pcie.afi_clk = clk_get(NULL, "afi");
+ if (IS_ERR(tegra_pcie.afi_clk)) {
+ err = PTR_ERR(tegra_pcie.afi_clk);
+ goto err_afi_clk;
+ }
+
+ tegra_pcie.pcie_xclk = clk_get(NULL, "pcie_xclk");
+ if (IS_ERR(tegra_pcie.pcie_xclk)) {
+ err = PTR_ERR(tegra_pcie.pcie_xclk);
+ goto err_pcie_xclk;
+ }
+
+ tegra_pcie.pll_e = clk_get_sys(NULL, "pll_e");
+ if (IS_ERR(tegra_pcie.pll_e)) {
+ err = PTR_ERR(tegra_pcie.pll_e);
+ goto err_pll_e;
+ }
+
+ return 0;
+
+err_pll_e:
+ clk_put(tegra_pcie.pcie_xclk);
+err_pcie_xclk:
+ clk_put(tegra_pcie.afi_clk);
+err_afi_clk:
+ clk_put(tegra_pcie.pex_clk);
+
+ return err;
+}
+
+static void tegra_pcie_clocks_put(void)
+{
+ clk_put(tegra_pcie.pll_e);
+ clk_put(tegra_pcie.pcie_xclk);
+ clk_put(tegra_pcie.afi_clk);
+ clk_put(tegra_pcie.pex_clk);
+}
+
+static int __init tegra_pcie_get_resources(void)
+{
+ struct resource *res_mmio = &tegra_pcie.res_mmio;
+ int err;
+
+ err = tegra_pcie_clocks_get();
+ if (err) {
+ pr_err("PCIE: failed to get clocks: %d\n", err);
+ return err;
+ }
+
+ err = tegra_pcie_power_regate();
+ if (err) {
+ pr_err("PCIE: failed to power up: %d\n", err);
+ goto err_pwr_on;
+ }
+
+ tegra_pcie.regs = ioremap_nocache(TEGRA_PCIE_BASE, PCIE_IOMAP_SZ);
+ if (tegra_pcie.regs == NULL) {
+ pr_err("PCIE: Failed to map PCI/AFI registers\n");
+ err = -ENOMEM;
+ goto err_map_reg;
+ }
+
+ err = request_resource(&iomem_resource, res_mmio);
+ if (err) {
+ pr_err("PCIE: Failed to request resources: %d\n", err);
+ goto err_req_io;
+ }
+
+ tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
+ resource_size(res_mmio));
+ if (tegra_pcie_io_base == NULL) {
+ pr_err("PCIE: Failed to map IO\n");
+ err = -ENOMEM;
+ goto err_map_io;
+ }
+
+ err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
+ IRQF_SHARED, "PCIE", &tegra_pcie);
+ if (err) {
+ pr_err("PCIE: Failed to register IRQ: %d\n", err);
+ goto err_irq;
+ }
+ set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
+
+ return 0;
+
+err_irq:
+ iounmap(tegra_pcie_io_base);
+err_map_io:
+ release_resource(&tegra_pcie.res_mmio);
+err_req_io:
+ iounmap(tegra_pcie.regs);
+err_map_reg:
+ tegra_pcie_power_off();
+err_pwr_on:
+ tegra_pcie_clocks_put();
+
+ return err;
+}
+
+/*
+ * FIXME: If there are no PCIe cards attached, then calling this function
+ * can result in the increase of the bootup time as there are big timeout
+ * loops.
+ */
+#define TEGRA_PCIE_LINKUP_TIMEOUT 200 /* up to 1.2 seconds */
+static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
+ u32 reset_reg)
+{
+ u32 reg;
+ int retries = 3;
+ int timeout;
+
+ do {
+ timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
+ while (timeout) {
+ reg = readl(pp->base + RP_VEND_XP);
+
+ if (reg & RP_VEND_XP_DL_UP)
+ break;
+
+ mdelay(1);
+ timeout--;
+ }
+
+ if (!timeout) {
+ pr_err("PCIE: port %d: link down, retrying\n", idx);
+ goto retry;
+ }
+
+ timeout = TEGRA_PCIE_LINKUP_TIMEOUT;
+ while (timeout) {
+ reg = readl(pp->base + RP_LINK_CONTROL_STATUS);
+
+ if (reg & 0x20000000)
+ return true;
+
+ mdelay(1);
+ timeout--;
+ }
+
+retry:
+ /* Pulse the PEX reset */
+ reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+ mdelay(1);
+ reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+
+ retries--;
+ } while (retries);
+
+ return false;
+}
+
+static void __init tegra_pcie_add_port(int index, u32 offset, u32 reset_reg)
+{
+ struct tegra_pcie_port *pp;
+
+ pp = tegra_pcie.port + tegra_pcie.num_ports;
+
+ pp->index = -1;
+ pp->base = tegra_pcie.regs + offset;
+ pp->link_up = tegra_pcie_check_link(pp, index, reset_reg);
+
+ if (!pp->link_up) {
+ pp->base = NULL;
+ printk(KERN_INFO "PCIE: port %d: link down, ignoring\n", index);
+ return;
+ }
+
+ tegra_pcie.num_ports++;
+ pp->index = index;
+ pp->root_bus_nr = -1;
+ memset(pp->res, 0, sizeof(pp->res));
+}
+
+int __init tegra_pcie_init(bool init_port0, bool init_port1)
+{
+ int err;
+
+ if (!(init_port0 || init_port1))
+ return -ENODEV;
+
+ err = tegra_pcie_get_resources();
+ if (err)
+ return err;
+
+ tegra_pcie_enable_controller();
+
+ /* setup the AFI address translations */
+ tegra_pcie_setup_translations();
+
+ if (init_port0)
+ tegra_pcie_add_port(0, RP0_OFFSET, AFI_PEX0_CTRL);
+
+ if (init_port1)
+ tegra_pcie_add_port(1, RP1_OFFSET, AFI_PEX1_CTRL);
+
+ pci_common_init(&tegra_pcie_hw);
+
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c
new file mode 100644
index 00000000..a475367b
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux-t2-tables.c
@@ -0,0 +1,278 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux-t2-tables.c
+ *
+ * Common pinmux configurations for Tegra 2 SoCs
+ *
+ * Copyright (C) 2010 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <mach/iomap.h>
+#include <mach/pinmux.h>
+#include <mach/suspend.h>
+
+#define DRIVE_PINGROUP(pg_name, r) \
+ [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .reg = r \
+ }
+
+const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+ DRIVE_PINGROUP(AO1, 0x868),
+ DRIVE_PINGROUP(AO2, 0x86c),
+ DRIVE_PINGROUP(AT1, 0x870),
+ DRIVE_PINGROUP(AT2, 0x874),
+ DRIVE_PINGROUP(CDEV1, 0x878),
+ DRIVE_PINGROUP(CDEV2, 0x87c),
+ DRIVE_PINGROUP(CSUS, 0x880),
+ DRIVE_PINGROUP(DAP1, 0x884),
+ DRIVE_PINGROUP(DAP2, 0x888),
+ DRIVE_PINGROUP(DAP3, 0x88c),
+ DRIVE_PINGROUP(DAP4, 0x890),
+ DRIVE_PINGROUP(DBG, 0x894),
+ DRIVE_PINGROUP(LCD1, 0x898),
+ DRIVE_PINGROUP(LCD2, 0x89c),
+ DRIVE_PINGROUP(SDMMC2, 0x8a0),
+ DRIVE_PINGROUP(SDMMC3, 0x8a4),
+ DRIVE_PINGROUP(SPI, 0x8a8),
+ DRIVE_PINGROUP(UAA, 0x8ac),
+ DRIVE_PINGROUP(UAB, 0x8b0),
+ DRIVE_PINGROUP(UART2, 0x8b4),
+ DRIVE_PINGROUP(UART3, 0x8b8),
+ DRIVE_PINGROUP(VI1, 0x8bc),
+ DRIVE_PINGROUP(VI2, 0x8c0),
+ DRIVE_PINGROUP(XM2A, 0x8c4),
+ DRIVE_PINGROUP(XM2C, 0x8c8),
+ DRIVE_PINGROUP(XM2D, 0x8cc),
+ DRIVE_PINGROUP(XM2CLK, 0x8d0),
+ DRIVE_PINGROUP(MEMCOMP, 0x8d4),
+ DRIVE_PINGROUP(SDIO1, 0x8e0),
+ DRIVE_PINGROUP(CRT, 0x8ec),
+ DRIVE_PINGROUP(DDC, 0x8f0),
+ DRIVE_PINGROUP(GMA, 0x8f4),
+ DRIVE_PINGROUP(GMB, 0x8f8),
+ DRIVE_PINGROUP(GMC, 0x8fc),
+ DRIVE_PINGROUP(GMD, 0x900),
+ DRIVE_PINGROUP(GME, 0x904),
+ DRIVE_PINGROUP(OWR, 0x908),
+ DRIVE_PINGROUP(UAD, 0x90c),
+};
+
+#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe, \
+ tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
+ [TEGRA_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .vddio = TEGRA_VDDIO_ ## vdd, \
+ .funcs = { \
+ TEGRA_MUX_ ## f0, \
+ TEGRA_MUX_ ## f1, \
+ TEGRA_MUX_ ## f2, \
+ TEGRA_MUX_ ## f3, \
+ }, \
+ .func_safe = TEGRA_MUX_ ## f_safe, \
+ .tri_reg = tri_r, \
+ .tri_bit = tri_b, \
+ .mux_reg = mux_r, \
+ .mux_bit = mux_b, \
+ .pupd_reg = pupd_r, \
+ .pupd_bit = pupd_b, \
+ }
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
+ PINGROUP(ATA, NAND, IDE, NAND, GMI, RSVD, IDE, 0x14, 0, 0x80, 24, 0xA0, 0),
+ PINGROUP(ATB, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xA0, 2),
+ PINGROUP(ATC, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xA0, 4),
+ PINGROUP(ATD, NAND, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xA0, 6),
+ PINGROUP(ATE, NAND, IDE, NAND, GMI, RSVD, IDE, 0x18, 25, 0x80, 12, 0xA0, 8),
+ PINGROUP(CDEV1, AUDIO, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xA8, 0),
+ PINGROUP(CDEV2, AUDIO, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xA8, 2),
+ PINGROUP(CRTP, LCD, CRT, RSVD, RSVD, RSVD, RSVD, 0x20, 14, 0x98, 20, 0xA4, 24),
+ PINGROUP(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xAC, 24),
+ PINGROUP(DAP1, AUDIO, DAP1, RSVD, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xA0, 10),
+ PINGROUP(DAP2, AUDIO, DAP2, TWC, RSVD, GMI, DAP2, 0x14, 8, 0x88, 22, 0xA0, 12),
+ PINGROUP(DAP3, BB, DAP3, RSVD, RSVD, RSVD, DAP3, 0x14, 9, 0x88, 24, 0xA0, 14),
+ PINGROUP(DAP4, UART, DAP4, RSVD, GMI, RSVD, DAP4, 0x14, 10, 0x88, 26, 0xA0, 16),
+ PINGROUP(DDC, LCD, I2C2, RSVD, RSVD, RSVD, RSVD4, 0x18, 31, 0x88, 0, 0xB0, 28),
+ PINGROUP(DTA, VI, RSVD, SDIO2, VI, RSVD, RSVD4, 0x14, 11, 0x84, 20, 0xA0, 18),
+ PINGROUP(DTB, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xA0, 20),
+ PINGROUP(DTC, VI, RSVD, RSVD, VI, RSVD, RSVD1, 0x14, 13, 0x84, 26, 0xA0, 22),
+ PINGROUP(DTD, VI, RSVD, SDIO2, VI, RSVD, RSVD1, 0x14, 14, 0x84, 28, 0xA0, 24),
+ PINGROUP(DTE, VI, RSVD, RSVD, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xA0, 26),
+ PINGROUP(DTF, VI, I2C3, RSVD, VI, RSVD, RSVD4, 0x20, 12, 0x98, 30, 0xA0, 28),
+ PINGROUP(GMA, NAND, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xB0, 20),
+ PINGROUP(GMB, NAND, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xB0, 22),
+ PINGROUP(GMC, NAND, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xB0, 24),
+ PINGROUP(GMD, NAND, RSVD, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xB0, 26),
+ PINGROUP(GME, NAND, RSVD, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8C, 0, 0xA8, 24),
+ PINGROUP(GPU, UART, PWM, UARTA, GMI, RSVD, RSVD4, 0x14, 16, 0x8C, 4, 0xA4, 20),
+ PINGROUP(GPU7, SYS, RTCK, RSVD, RSVD, RSVD, RTCK, 0x20, 11, 0x98, 28, 0xA4, 6),
+ PINGROUP(GPV, SD, PCIE, RSVD, RSVD, RSVD, PCIE, 0x14, 17, 0x8C, 2, 0xA0, 30),
+ PINGROUP(HDINT, LCD, HDMI, RSVD, RSVD, RSVD, HDMI, 0x1C, 23, 0x84, 4, 0xAC, 22),
+ PINGROUP(I2CP, SYS, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 18, 0x88, 8, 0xA4, 2),
+ PINGROUP(IRRX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xA8, 22),
+ PINGROUP(IRTX, UART, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xA8, 20),
+ PINGROUP(KBCA, SYS, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xA4, 8),
+ PINGROUP(KBCB, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xA4, 10),
+ PINGROUP(KBCC, SYS, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xA4, 12),
+ PINGROUP(KBCD, SYS, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xA4, 14),
+ PINGROUP(KBCE, SYS, KBC, NAND, OWR, RSVD, KBC, 0x14, 26, 0x80, 28, 0xB0, 2),
+ PINGROUP(KBCF, SYS, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xB0, 0),
+ PINGROUP(LCSN, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 31, 0x90, 12, 0xAC, 20),
+ PINGROUP(LD0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 0, 0x94, 0, 0xAC, 12),
+ PINGROUP(LD1, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 1, 0x94, 2, 0xAC, 12),
+ PINGROUP(LD10, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 10, 0x94, 20, 0xAC, 12),
+ PINGROUP(LD11, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 11, 0x94, 22, 0xAC, 12),
+ PINGROUP(LD12, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 12, 0x94, 24, 0xAC, 12),
+ PINGROUP(LD13, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 13, 0x94, 26, 0xAC, 12),
+ PINGROUP(LD14, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 14, 0x94, 28, 0xAC, 12),
+ PINGROUP(LD15, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 15, 0x94, 30, 0xAC, 12),
+ PINGROUP(LD16, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 16, 0x98, 0, 0xAC, 12),
+ PINGROUP(LD17, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 17, 0x98, 2, 0xAC, 12),
+ PINGROUP(LD2, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 2, 0x94, 4, 0xAC, 12),
+ PINGROUP(LD3, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 3, 0x94, 6, 0xAC, 12),
+ PINGROUP(LD4, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 4, 0x94, 8, 0xAC, 12),
+ PINGROUP(LD5, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 5, 0x94, 10, 0xAC, 12),
+ PINGROUP(LD6, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 6, 0x94, 12, 0xAC, 12),
+ PINGROUP(LD7, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 7, 0x94, 14, 0xAC, 12),
+ PINGROUP(LD8, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 8, 0x94, 16, 0xAC, 12),
+ PINGROUP(LD9, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 9, 0x94, 18, 0xAC, 12),
+ PINGROUP(LDC, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 30, 0x90, 14, 0xAC, 20),
+ PINGROUP(LDI, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 6, 0x98, 16, 0xAC, 18),
+ PINGROUP(LHP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 18, 0x98, 10, 0xAC, 16),
+ PINGROUP(LHP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 19, 0x98, 4, 0xAC, 14),
+ PINGROUP(LHP2, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 20, 0x98, 6, 0xAC, 14),
+ PINGROUP(LHS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x20, 7, 0x90, 22, 0xAC, 22),
+ PINGROUP(LM0, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, RSVD4, 0x1C, 24, 0x90, 26, 0xAC, 22),
+ PINGROUP(LM1, LCD, DISPLAYA, DISPLAYB, RSVD, CRT, RSVD3, 0x1C, 25, 0x90, 28, 0xAC, 22),
+ PINGROUP(LPP, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 8, 0x98, 14, 0xAC, 18),
+ PINGROUP(LPW0, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, 0xAC, 20),
+ PINGROUP(LPW1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x20, 4, 0x90, 2, 0xAC, 20),
+ PINGROUP(LPW2, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, 0xAC, 20),
+ PINGROUP(LSC0, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 27, 0x90, 18, 0xAC, 22),
+ PINGROUP(LSC1, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 28, 0x90, 20, 0xAC, 20),
+ PINGROUP(LSCK, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1C, 29, 0x90, 16, 0xAC, 20),
+ PINGROUP(LSDA, LCD, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, 0xAC, 20),
+ PINGROUP(LSDI, LCD, DISPLAYA, DISPLAYB, SPI3, RSVD, DISPLAYA, 0x20, 2, 0x90, 6, 0xAC, 20),
+ PINGROUP(LSPI, LCD, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, 0xAC, 22),
+ PINGROUP(LVP0, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 21, 0x90, 30, 0xAC, 22),
+ PINGROUP(LVP1, LCD, DISPLAYA, DISPLAYB, RSVD, RSVD, RSVD4, 0x1C, 22, 0x98, 8, 0xAC, 16),
+ PINGROUP(LVS, LCD, DISPLAYA, DISPLAYB, XIO, RSVD, RSVD4, 0x1C, 26, 0x90, 24, 0xAC, 22),
+ PINGROUP(OWC, SYS, OWR, RSVD, RSVD, RSVD, OWR, 0x14, 31, 0x84, 8, 0xB0, 30),
+ PINGROUP(PMC, SYS, PWR_ON, PWR_INTR, RSVD, RSVD, PWR_ON, 0x14, 23, 0x98, 18, -1, -1),
+ PINGROUP(PTA, NAND, I2C2, HDMI, GMI, RSVD, RSVD4, 0x14, 24, 0x98, 22, 0xA4, 4),
+ PINGROUP(RM, UART, I2C, RSVD, RSVD, RSVD, RSVD4, 0x14, 25, 0x80, 14, 0xA4, 0),
+ PINGROUP(SDB, SD, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8C, 10, -1, -1),
+ PINGROUP(SDC, SD, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8C, 12, 0xAC, 28),
+ PINGROUP(SDD, SD, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8C, 14, 0xAC, 30),
+ PINGROUP(SDIO1, BB, SDIO1, RSVD, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xB0, 18),
+ PINGROUP(SLXA, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xA4, 22),
+ PINGROUP(SLXC, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xA4, 26),
+ PINGROUP(SLXD, SD, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xA4, 28),
+ PINGROUP(SLXK, SD, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xA4, 30),
+ PINGROUP(SPDI, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 8, 0x8C, 8, 0xA4, 16),
+ PINGROUP(SPDO, AUDIO, SPDIF, RSVD, I2C, SDIO2, RSVD2, 0x18, 9, 0x8C, 6, 0xA4, 18),
+ PINGROUP(SPIA, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8C, 30, 0xA8, 4),
+ PINGROUP(SPIB, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8C, 28, 0xA8, 6),
+ PINGROUP(SPIC, AUDIO, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8C, 26, 0xA8, 8),
+ PINGROUP(SPID, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8C, 24, 0xA8, 10),
+ PINGROUP(SPIE, AUDIO, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8C, 22, 0xA8, 12),
+ PINGROUP(SPIF, AUDIO, SPI3, SPI1, SPI2, RSVD, RSVD4, 0x18, 15, 0x8C, 20, 0xA8, 14),
+ PINGROUP(SPIG, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 16, 0x8C, 18, 0xA8, 16),
+ PINGROUP(SPIH, AUDIO, SPI3, SPI2, SPI2_ALT, I2C, SPI2_ALT, 0x18, 17, 0x8C, 16, 0xA8, 18),
+ PINGROUP(UAA, BB, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xAC, 0),
+ PINGROUP(UAB, BB, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xAC, 2),
+ PINGROUP(UAC, BB, OWR, RSVD, RSVD, RSVD, RSVD4, 0x18, 20, 0x80, 4, 0xAC, 4),
+ PINGROUP(UAD, UART, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xAC, 6),
+ PINGROUP(UCA, UART, UARTC, RSVD, GMI, RSVD, RSVD4, 0x18, 22, 0x84, 16, 0xAC, 8),
+ PINGROUP(UCB, UART, UARTC, PWM, GMI, RSVD, RSVD4, 0x18, 23, 0x84, 18, 0xAC, 10),
+ PINGROUP(UDA, BB, SPI1, RSVD, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xB0, 16),
+ /* these pin groups only have pullup and pull down control */
+ PINGROUP(CK32, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 14),
+ PINGROUP(DDRC, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xAC, 26),
+ PINGROUP(PMCA, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 4),
+ PINGROUP(PMCB, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 6),
+ PINGROUP(PMCC, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 8),
+ PINGROUP(PMCD, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 10),
+ PINGROUP(PMCE, SYS, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xB0, 12),
+ PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30),
+ PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28),
+};
+
+#ifdef CONFIG_PM
+#define TRISTATE_REG_A 0x14
+#define TRISTATE_REG_NUM 4
+#define PIN_MUX_CTL_REG_A 0x80
+#define PIN_MUX_CTL_REG_NUM 8
+#define PULLUPDOWN_REG_A 0xa0
+#define PULLUPDOWN_REG_NUM 5
+
+static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
+ PULLUPDOWN_REG_NUM +
+ ARRAY_SIZE(tegra_soc_drive_pingroups)];
+
+static inline unsigned long pg_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+static inline void pg_writel(unsigned long value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+void tegra_pinmux_suspend(void)
+{
+ unsigned int i;
+ u32 *ctx = pinmux_reg;
+
+ for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
+ *ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4);
+
+ for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
+ *ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4);
+
+ for (i = 0; i < TRISTATE_REG_NUM; i++)
+ *ctx++ = pg_readl(TRISTATE_REG_A + i*4);
+
+ for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
+ *ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg);
+}
+
+void tegra_pinmux_resume(void)
+{
+ unsigned int i;
+ u32 *ctx = pinmux_reg;
+
+ for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
+ pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4);
+
+ for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
+ pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4);
+
+ for (i = 0; i < TRISTATE_REG_NUM; i++)
+ pg_writel(*ctx++, TRISTATE_REG_A + i*4);
+
+ for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
+ pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg);
+}
+#endif
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 00000000..f80d5076
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,825 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux.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 <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+#include <mach/pinmux.h>
+
+#define HSM_EN(reg) (((reg) >> 2) & 0x1)
+#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
+#define LPMD(reg) (((reg) >> 4) & 0x3)
+#define DRVDN(reg) (((reg) >> 12) & 0x1f)
+#define DRVUP(reg) (((reg) >> 20) & 0x1f)
+#define SLWR(reg) (((reg) >> 28) & 0x3)
+#define SLWF(reg) (((reg) >> 30) & 0x3)
+
+static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups;
+static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups;
+
+static char *tegra_mux_names[TEGRA_MAX_MUX] = {
+ [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
+ [TEGRA_MUX_APB_CLK] = "APB_CLK",
+ [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
+ [TEGRA_MUX_CRT] = "CRT",
+ [TEGRA_MUX_DAP1] = "DAP1",
+ [TEGRA_MUX_DAP2] = "DAP2",
+ [TEGRA_MUX_DAP3] = "DAP3",
+ [TEGRA_MUX_DAP4] = "DAP4",
+ [TEGRA_MUX_DAP5] = "DAP5",
+ [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
+ [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
+ [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
+ [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
+ [TEGRA_MUX_GMI] = "GMI",
+ [TEGRA_MUX_GMI_INT] = "GMI_INT",
+ [TEGRA_MUX_HDMI] = "HDMI",
+ [TEGRA_MUX_I2C] = "I2C",
+ [TEGRA_MUX_I2C2] = "I2C2",
+ [TEGRA_MUX_I2C3] = "I2C3",
+ [TEGRA_MUX_IDE] = "IDE",
+ [TEGRA_MUX_IRDA] = "IRDA",
+ [TEGRA_MUX_KBC] = "KBC",
+ [TEGRA_MUX_MIO] = "MIO",
+ [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
+ [TEGRA_MUX_NAND] = "NAND",
+ [TEGRA_MUX_OSC] = "OSC",
+ [TEGRA_MUX_OWR] = "OWR",
+ [TEGRA_MUX_PCIE] = "PCIE",
+ [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
+ [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
+ [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
+ [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
+ [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
+ [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
+ [TEGRA_MUX_PWM] = "PWM",
+ [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
+ [TEGRA_MUX_PWR_ON] = "PWR_ON",
+ [TEGRA_MUX_RTCK] = "RTCK",
+ [TEGRA_MUX_SDIO1] = "SDIO1",
+ [TEGRA_MUX_SDIO2] = "SDIO2",
+ [TEGRA_MUX_SDIO3] = "SDIO3",
+ [TEGRA_MUX_SDIO4] = "SDIO4",
+ [TEGRA_MUX_SFLASH] = "SFLASH",
+ [TEGRA_MUX_SPDIF] = "SPDIF",
+ [TEGRA_MUX_SPI1] = "SPI1",
+ [TEGRA_MUX_SPI2] = "SPI2",
+ [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
+ [TEGRA_MUX_SPI3] = "SPI3",
+ [TEGRA_MUX_SPI4] = "SPI4",
+ [TEGRA_MUX_TRACE] = "TRACE",
+ [TEGRA_MUX_TWC] = "TWC",
+ [TEGRA_MUX_UARTA] = "UARTA",
+ [TEGRA_MUX_UARTB] = "UARTB",
+ [TEGRA_MUX_UARTC] = "UARTC",
+ [TEGRA_MUX_UARTD] = "UARTD",
+ [TEGRA_MUX_UARTE] = "UARTE",
+ [TEGRA_MUX_ULPI] = "ULPI",
+ [TEGRA_MUX_VI] = "VI",
+ [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
+ [TEGRA_MUX_XIO] = "XIO",
+ [TEGRA_MUX_SAFE] = "<safe>",
+};
+
+static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
+ [TEGRA_DRIVE_DIV_8] = "DIV_8",
+ [TEGRA_DRIVE_DIV_4] = "DIV_4",
+ [TEGRA_DRIVE_DIV_2] = "DIV_2",
+ [TEGRA_DRIVE_DIV_1] = "DIV_1",
+};
+
+static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
+ [TEGRA_SLEW_FASTEST] = "FASTEST",
+ [TEGRA_SLEW_FAST] = "FAST",
+ [TEGRA_SLEW_SLOW] = "SLOW",
+ [TEGRA_SLEW_SLOWEST] = "SLOWEST",
+};
+
+static DEFINE_SPINLOCK(mux_lock);
+
+static const char *pingroup_name(enum tegra_pingroup pg)
+{
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return "<UNKNOWN>";
+
+ return pingroups[pg].name;
+}
+
+static const char *func_name(enum tegra_mux_func func)
+{
+ if (func == TEGRA_MUX_RSVD1)
+ return "RSVD1";
+
+ if (func == TEGRA_MUX_RSVD2)
+ return "RSVD2";
+
+ if (func == TEGRA_MUX_RSVD3)
+ return "RSVD3";
+
+ if (func == TEGRA_MUX_RSVD4)
+ return "RSVD4";
+
+ if (func == TEGRA_MUX_NONE)
+ return "NONE";
+
+ if (func < 0 || func >= TEGRA_MAX_MUX)
+ return "<UNKNOWN>";
+
+ return tegra_mux_names[func];
+}
+
+
+static const char *tri_name(unsigned long val)
+{
+ return val ? "TRISTATE" : "NORMAL";
+}
+
+static const char *pupd_name(unsigned long val)
+{
+ switch (val) {
+ case 0:
+ return "NORMAL";
+
+ case 1:
+ return "PULL_DOWN";
+
+ case 2:
+ return "PULL_UP";
+
+ default:
+ return "RSVD";
+ }
+}
+
+
+static inline unsigned long pg_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+static inline void pg_writel(unsigned long value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
+{
+ int mux = -1;
+ int i;
+ unsigned long reg;
+ unsigned long flags;
+ enum tegra_pingroup pg = config->pingroup;
+ enum tegra_mux_func func = config->func;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if (func < 0)
+ return -ERANGE;
+
+ if (func == TEGRA_MUX_SAFE)
+ func = pingroups[pg].func_safe;
+
+ if (func & TEGRA_MUX_RSVD) {
+ mux = func & 0x3;
+ } else {
+ for (i = 0; i < 4; i++) {
+ if (pingroups[pg].funcs[i] == func) {
+ mux = i;
+ break;
+ }
+ }
+ }
+
+ if (mux < 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x3 << pingroups[pg].mux_bit);
+ reg |= mux << pingroups[pg].mux_bit;
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
+ enum tegra_tristate tristate)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].tri_reg < 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].tri_reg);
+ reg &= ~(0x1 << pingroups[pg].tri_bit);
+ if (tristate)
+ reg |= 1 << pingroups[pg].tri_bit;
+ pg_writel(reg, pingroups[pg].tri_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
+ enum tegra_pullupdown pupd)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].pupd_reg < 0)
+ return -EINVAL;
+
+ if (pupd != TEGRA_PUPD_NORMAL &&
+ pupd != TEGRA_PUPD_PULL_DOWN &&
+ pupd != TEGRA_PUPD_PULL_UP)
+ return -EINVAL;
+
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].pupd_reg);
+ reg &= ~(0x3 << pingroups[pg].pupd_bit);
+ reg |= pupd << pingroups[pg].pupd_bit;
+ pg_writel(reg, pingroups[pg].pupd_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
+{
+ enum tegra_pingroup pingroup = config->pingroup;
+ enum tegra_mux_func func = config->func;
+ enum tegra_pullupdown pupd = config->pupd;
+ enum tegra_tristate tristate = config->tristate;
+ int err;
+
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_func(config);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
+ pingroup_name(pingroup), func_name(func), err);
+ }
+
+ if (pingroups[pingroup].pupd_reg >= 0) {
+ err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
+ pingroup_name(pingroup), pupd_name(pupd), err);
+ }
+
+ if (pingroups[pingroup].tri_reg >= 0) {
+ err = tegra_pinmux_set_tristate(pingroup, tristate);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
+ pingroup_name(pingroup), tri_name(func), err);
+ }
+}
+
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ tegra_pinmux_config_pingroup(&config[i]);
+}
+
+static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
+{
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return "<UNKNOWN>";
+
+ return drive_pingroups[pg].name;
+}
+
+static const char *enable_name(unsigned long val)
+{
+ return val ? "ENABLE" : "DISABLE";
+}
+
+static const char *drive_name(unsigned long val)
+{
+ if (val >= TEGRA_MAX_DRIVE)
+ return "<UNKNOWN>";
+
+ return tegra_drive_names[val];
+}
+
+static const char *slew_name(unsigned long val)
+{
+ if (val >= TEGRA_MAX_SLEW)
+ return "<UNKNOWN>";
+
+ return tegra_slew_names[val];
+}
+
+static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
+ enum tegra_hsm hsm)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ if (hsm == TEGRA_HSM_ENABLE)
+ reg |= (1 << 2);
+ else
+ reg &= ~(1 << 2);
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
+ enum tegra_schmitt schmitt)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ if (schmitt == TEGRA_SCHMITT_ENABLE)
+ reg |= (1 << 3);
+ else
+ reg &= ~(1 << 3);
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
+ enum tegra_drive drive)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 4);
+ reg |= drive << 4;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
+ enum tegra_pull_strength pull_down)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x1f << 12);
+ reg |= pull_down << 12;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
+ enum tegra_pull_strength pull_up)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x1f << 12);
+ reg |= pull_up << 12;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
+ enum tegra_slew slew_rising)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 28);
+ reg |= slew_rising << 28;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
+ enum tegra_slew slew_falling)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 30);
+ reg |= slew_falling << 30;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
+ enum tegra_hsm hsm,
+ enum tegra_schmitt schmitt,
+ enum tegra_drive drive,
+ enum tegra_pull_strength pull_down,
+ enum tegra_pull_strength pull_up,
+ enum tegra_slew slew_rising,
+ enum tegra_slew slew_falling)
+{
+ int err;
+
+ err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ enable_name(hsm), err);
+
+ err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ enable_name(schmitt), err);
+
+ err = tegra_drive_pinmux_set_drive(pingroup, drive);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ drive_name(drive), err);
+
+ err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
+ drive_pinmux_name(pingroup),
+ pull_down, err);
+
+ err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
+ drive_pinmux_name(pingroup),
+ pull_up, err);
+
+ err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ slew_name(slew_rising), err);
+
+ err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ slew_name(slew_falling), err);
+}
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ tegra_drive_pinmux_config_pingroup(config[i].pingroup,
+ config[i].hsm,
+ config[i].schmitt,
+ config[i].drive,
+ config[i].pull_down,
+ config[i].pull_up,
+ config[i].slew_rising,
+ config[i].slew_falling);
+}
+
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+ int len)
+{
+ int i;
+ struct tegra_pingroup_config c;
+
+ for (i = 0; i < len; i++) {
+ int err;
+ c = config[i];
+ if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) {
+ WARN_ON(1);
+ continue;
+ }
+ c.func = pingroups[c.pingroup].func_safe;
+ err = tegra_pinmux_set_func(&c);
+ if (err < 0)
+ pr_err("%s: tegra_pinmux_set_func returned %d setting "
+ "%s to %s\n", __func__, err,
+ pingroup_name(c.pingroup), func_name(c.func));
+ }
+}
+
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int err;
+ if (config[i].pingroup < 0 ||
+ config[i].pingroup >= TEGRA_MAX_PINGROUP) {
+ WARN_ON(1);
+ continue;
+ }
+ err = tegra_pinmux_set_func(&config[i]);
+ if (err < 0)
+ pr_err("%s: tegra_pinmux_set_func returned %d setting "
+ "%s to %s\n", __func__, err,
+ pingroup_name(config[i].pingroup),
+ func_name(config[i].func));
+ }
+}
+
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_tristate tristate)
+{
+ int i;
+ int err;
+ enum tegra_pingroup pingroup;
+
+ for (i = 0; i < len; i++) {
+ pingroup = config[i].pingroup;
+ if (pingroups[pingroup].tri_reg >= 0) {
+ err = tegra_pinmux_set_tristate(pingroup, tristate);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s tristate"
+ " to %s: %d\n", pingroup_name(pingroup),
+ tri_name(tristate), err);
+ }
+ }
+}
+
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+ int len, enum tegra_pullupdown pupd)
+{
+ int i;
+ int err;
+ enum tegra_pingroup pingroup;
+
+ for (i = 0; i < len; i++) {
+ pingroup = config[i].pingroup;
+ if (pingroups[pingroup].pupd_reg >= 0) {
+ err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pullupdown"
+ " to %s: %d\n", pingroup_name(pingroup),
+ pupd_name(pupd), err);
+ }
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void dbg_pad_field(struct seq_file *s, int len)
+{
+ seq_putc(s, ',');
+
+ while (len-- > -1)
+ seq_putc(s, ' ');
+}
+
+static int dbg_pinmux_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int len;
+
+ for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
+ unsigned long tri;
+ unsigned long mux;
+ unsigned long pupd;
+
+ seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
+ len = strlen(pingroups[i].name);
+ dbg_pad_field(s, 5 - len);
+
+ if (pingroups[i].mux_reg < 0) {
+ seq_printf(s, "TEGRA_MUX_NONE");
+ len = strlen("NONE");
+ } else {
+ mux = (pg_readl(pingroups[i].mux_reg) >>
+ pingroups[i].mux_bit) & 0x3;
+ if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
+ seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
+ len = 5;
+ } else {
+ seq_printf(s, "TEGRA_MUX_%s",
+ tegra_mux_names[pingroups[i].funcs[mux]]);
+ len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
+ }
+ }
+ dbg_pad_field(s, 13-len);
+
+ if (pingroups[i].pupd_reg < 0) {
+ seq_printf(s, "TEGRA_PUPD_NORMAL");
+ len = strlen("NORMAL");
+ } else {
+ pupd = (pg_readl(pingroups[i].pupd_reg) >>
+ pingroups[i].pupd_bit) & 0x3;
+ seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
+ len = strlen(pupd_name(pupd));
+ }
+ dbg_pad_field(s, 9 - len);
+
+ if (pingroups[i].tri_reg < 0) {
+ seq_printf(s, "TEGRA_TRI_NORMAL");
+ } else {
+ tri = (pg_readl(pingroups[i].tri_reg) >>
+ pingroups[i].tri_bit) & 0x1;
+
+ seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
+ }
+ seq_printf(s, "},\n");
+ }
+ return 0;
+}
+
+static int dbg_pinmux_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_pinmux_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int len;
+
+ for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
+ u32 reg;
+
+ seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
+ drive_pingroups[i].name);
+ len = strlen(drive_pingroups[i].name);
+ dbg_pad_field(s, 7 - len);
+
+
+ reg = pg_readl(drive_pingroups[i].reg);
+ if (HSM_EN(reg)) {
+ seq_printf(s, "TEGRA_HSM_ENABLE");
+ len = 16;
+ } else {
+ seq_printf(s, "TEGRA_HSM_DISABLE");
+ len = 17;
+ }
+ dbg_pad_field(s, 17 - len);
+
+ if (SCHMT_EN(reg)) {
+ seq_printf(s, "TEGRA_SCHMITT_ENABLE");
+ len = 21;
+ } else {
+ seq_printf(s, "TEGRA_SCHMITT_DISABLE");
+ len = 22;
+ }
+ dbg_pad_field(s, 22 - len);
+
+ seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
+ len = strlen(drive_name(LPMD(reg)));
+ dbg_pad_field(s, 5 - len);
+
+ seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
+ len = DRVDN(reg) < 10 ? 1 : 2;
+ dbg_pad_field(s, 2 - len);
+
+ seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
+ len = DRVUP(reg) < 10 ? 1 : 2;
+ dbg_pad_field(s, 2 - len);
+
+ seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
+ len = strlen(slew_name(SLWR(reg)));
+ dbg_pad_field(s, 7 - len);
+
+ seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
+
+ seq_printf(s, "},\n");
+ }
+ return 0;
+}
+
+static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_drive_fops = {
+ .open = dbg_drive_pinmux_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_pinmux_debuginit(void)
+{
+ (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
+ NULL, NULL, &debug_drive_fops);
+ return 0;
+}
+late_initcall(tegra_pinmux_debuginit);
+#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
new file mode 100644
index 00000000..b8ae3c97
--- /dev/null
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/arm/mach-tegra/platsmp.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * Copyright (C) 2009 Palm
+ * 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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/smp_scu.h>
+
+#include <mach/iomap.h>
+
+extern void tegra_secondary_startup(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
+
+#define EVP_CPU_RESET_VECTOR \
+ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
+#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
+ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
+#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
+ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long old_boot_vector;
+ unsigned long boot_vector;
+ unsigned long timeout;
+ u32 reg;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+
+ /* set the reset vector to point to the secondary_startup routine */
+
+ boot_vector = virt_to_phys(tegra_secondary_startup);
+ old_boot_vector = readl(EVP_CPU_RESET_VECTOR);
+ writel(boot_vector, EVP_CPU_RESET_VECTOR);
+
+ /* enable cpu clock on cpu1 */
+ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+ writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+
+ reg = (1<<13) | (1<<9) | (1<<5) | (1<<1);
+ writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
+
+ smp_wmb();
+ flush_cache_all();
+
+ /* unhalt the cpu */
+ writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ if (readl(EVP_CPU_RESET_VECTOR) != boot_vector)
+ break;
+ udelay(10);
+ }
+
+ /* put the old boot vector back */
+ writel(old_boot_vector, EVP_CPU_RESET_VECTOR);
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * 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)
+{
+ unsigned int i, ncores = scu_get_core_count(scu_base);
+
+ if (ncores > NR_CPUS) {
+ printk(KERN_ERR "Tegra: no. of cores (%u) greater than configured (%u), clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ cpu_set(i, cpu_possible_map);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base);
+}
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c
new file mode 100644
index 00000000..3cee9aa1
--- /dev/null
+++ b/arch/arm/mach-tegra/powergate.c
@@ -0,0 +1,212 @@
+/*
+ * drivers/powergate/tegra-powergate.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+
+#include <mach/clk.h>
+#include <mach/iomap.h>
+#include <mach/powergate.h>
+
+#define PWRGATE_TOGGLE 0x30
+#define PWRGATE_TOGGLE_START (1 << 8)
+
+#define REMOVE_CLAMPING 0x34
+
+#define PWRGATE_STATUS 0x38
+
+static DEFINE_SPINLOCK(tegra_powergate_lock);
+
+static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+
+static u32 pmc_read(unsigned long reg)
+{
+ return readl(pmc + reg);
+}
+
+static void pmc_write(u32 val, unsigned long reg)
+{
+ writel(val, pmc + reg);
+}
+
+static int tegra_powergate_set(int id, bool new_state)
+{
+ bool status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+ status = pmc_read(PWRGATE_STATUS) & (1 << id);
+
+ if (status == new_state) {
+ spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+ return -EINVAL;
+ }
+
+ pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
+
+ spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+ return 0;
+}
+
+int tegra_powergate_power_on(int id)
+{
+ if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, true);
+}
+
+int tegra_powergate_power_off(int id)
+{
+ if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, false);
+}
+
+bool tegra_powergate_is_powered(int id)
+{
+ u32 status;
+
+ if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+ return -EINVAL;
+
+ status = pmc_read(PWRGATE_STATUS) & (1 << id);
+ return !!status;
+}
+
+int tegra_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ if (id < 0 || id >= TEGRA_NUM_POWERGATE)
+ return -EINVAL;
+
+ /*
+ * Tegra 2 has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ pmc_write(mask, REMOVE_CLAMPING);
+
+ return 0;
+}
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk)
+{
+ int ret;
+
+ tegra_periph_reset_assert(clk);
+
+ ret = tegra_powergate_power_on(id);
+ if (ret)
+ goto err_power;
+
+ ret = clk_enable(clk);
+ if (ret)
+ goto err_clk;
+
+ udelay(10);
+
+ ret = tegra_powergate_remove_clamping(id);
+ if (ret)
+ goto err_clamp;
+
+ udelay(10);
+ tegra_periph_reset_deassert(clk);
+
+ return 0;
+
+err_clamp:
+ clk_disable(clk);
+err_clk:
+ tegra_powergate_power_off(id);
+err_power:
+ return ret;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static const char * const powergate_name[] = {
+ [TEGRA_POWERGATE_CPU] = "cpu",
+ [TEGRA_POWERGATE_3D] = "3d",
+ [TEGRA_POWERGATE_VENC] = "venc",
+ [TEGRA_POWERGATE_VDEC] = "vdec",
+ [TEGRA_POWERGATE_PCIE] = "pcie",
+ [TEGRA_POWERGATE_L2] = "l2",
+ [TEGRA_POWERGATE_MPE] = "mpe",
+};
+
+static int powergate_show(struct seq_file *s, void *data)
+{
+ int i;
+
+ seq_printf(s, " powergate powered\n");
+ seq_printf(s, "------------------\n");
+
+ for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+ seq_printf(s, " %9s %7s\n", powergate_name[i],
+ tegra_powergate_is_powered(i) ? "yes" : "no");
+ return 0;
+}
+
+static int powergate_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, powergate_show, inode->i_private);
+}
+
+static const struct file_operations powergate_fops = {
+ .open = powergate_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init powergate_debugfs_init(void)
+{
+ struct dentry *d;
+ int err = -ENOMEM;
+
+ d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL,
+ &powergate_fops);
+ if (!d)
+ return -ENOMEM;
+
+ return err;
+}
+
+late_initcall(powergate_debugfs_init);
+
+#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
new file mode 100644
index 00000000..bb618075
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -0,0 +1,2441 @@
+/*
+ * arch/arm/mach-tegra/tegra2_clocks.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+
+#include <mach/iomap.h>
+#include <mach/suspend.h>
+
+#include "clock.h"
+#include "fuse.h"
+#include "tegra2_emc.h"
+
+#define RST_DEVICES 0x004
+#define RST_DEVICES_SET 0x300
+#define RST_DEVICES_CLR 0x304
+#define RST_DEVICES_NUM 3
+
+#define CLK_OUT_ENB 0x010
+#define CLK_OUT_ENB_SET 0x320
+#define CLK_OUT_ENB_CLR 0x324
+#define CLK_OUT_ENB_NUM 3
+
+#define CLK_MASK_ARM 0x44
+#define MISC_CLK_ENB 0x48
+
+#define OSC_CTRL 0x50
+#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
+#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
+#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
+#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
+#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+
+#define OSC_FREQ_DET 0x58
+#define OSC_FREQ_DET_TRIG (1<<31)
+
+#define OSC_FREQ_DET_STATUS 0x5C
+#define OSC_FREQ_DET_BUSY (1<<31)
+#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+
+#define PERIPH_CLK_SOURCE_I2S1 0x100
+#define PERIPH_CLK_SOURCE_EMC 0x19c
+#define PERIPH_CLK_SOURCE_OSC 0x1fc
+#define PERIPH_CLK_SOURCE_NUM \
+ ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
+#define PERIPH_CLK_SOURCE_MASK (3<<30)
+#define PERIPH_CLK_SOURCE_SHIFT 30
+#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
+#define PERIPH_CLK_SOURCE_DIVU71_MASK 0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK 0xFFFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
+
+#define SDMMC_CLK_INT_FB_SEL (1 << 23)
+#define SDMMC_CLK_INT_FB_DLY_SHIFT 16
+#define SDMMC_CLK_INT_FB_DLY_MASK (0xF << SDMMC_CLK_INT_FB_DLY_SHIFT)
+
+#define PLL_BASE 0x0
+#define PLL_BASE_BYPASS (1<<31)
+#define PLL_BASE_ENABLE (1<<30)
+#define PLL_BASE_REF_ENABLE (1<<29)
+#define PLL_BASE_OVERRIDE (1<<28)
+#define PLL_BASE_DIVP_MASK (0x7<<20)
+#define PLL_BASE_DIVP_SHIFT 20
+#define PLL_BASE_DIVN_MASK (0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT 8
+#define PLL_BASE_DIVM_MASK (0x1F)
+#define PLL_BASE_DIVM_SHIFT 0
+
+#define PLL_OUT_RATIO_MASK (0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT 8
+#define PLL_OUT_OVERRIDE (1<<2)
+#define PLL_OUT_CLKEN (1<<1)
+#define PLL_OUT_RESET_DISABLE (1<<0)
+
+#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+
+#define PLL_MISC_DCCON_SHIFT 20
+#define PLL_MISC_CPCON_SHIFT 8
+#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT 4
+#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT 0
+#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
+
+#define PLLU_BASE_POST_DIV (1<<20)
+
+#define PLLD_MISC_CLKENABLE (1<<30)
+#define PLLD_MISC_DIV_RST (1<<23)
+#define PLLD_MISC_DCCON_SHIFT 12
+
+#define PLLE_MISC_READY (1 << 15)
+
+#define PERIPH_CLK_TO_ENB_REG(c) ((c->u.periph.clk_num / 32) * 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->u.periph.clk_num / 32) * 8)
+#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->u.periph.clk_num % 32))
+
+#define SUPER_CLK_MUX 0x00
+#define SUPER_STATE_SHIFT 28
+#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
+#define SUPER_SOURCE_MASK 0xF
+#define SUPER_FIQ_SOURCE_SHIFT 12
+#define SUPER_IRQ_SOURCE_SHIFT 8
+#define SUPER_RUN_SOURCE_SHIFT 4
+#define SUPER_IDLE_SOURCE_SHIFT 0
+
+#define SUPER_CLK_DIVIDER 0x04
+
+#define BUS_CLK_DISABLE (1<<3)
+#define BUS_CLK_DIV_MASK 0x3
+
+#define PMC_CTRL 0x0
+ #define PMC_CTRL_BLINK_ENB (1 << 7)
+
+#define PMC_DPD_PADS_ORIDE 0x1c
+ #define PMC_DPD_PADS_ORIDE_BLINK_ENB (1 << 20)
+
+#define PMC_BLINK_TIMER_DATA_ON_SHIFT 0
+#define PMC_BLINK_TIMER_DATA_ON_MASK 0x7fff
+#define PMC_BLINK_TIMER_ENB (1 << 15)
+#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
+#define PMC_BLINK_TIMER_DATA_OFF_MASK 0xffff
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+
+/*
+ * Some clocks share a register with other clocks. Any clock op that
+ * non-atomically modifies a register used by another clock must lock
+ * clock_register_lock first.
+ */
+static DEFINE_SPINLOCK(clock_register_lock);
+
+/*
+ * Some peripheral clocks share an enable bit, so refcount the enable bits
+ * in registers CLK_ENABLE_L, CLK_ENABLE_H, and CLK_ENABLE_U
+ */
+static int tegra_periph_clk_enable_refcount[3 * 32];
+
+#define clk_writel(value, reg) \
+ __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+ __raw_readl((u32)reg_clk_base + (reg))
+#define pmc_writel(value, reg) \
+ __raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+ __raw_readl((u32)reg_pmc_base + (reg))
+
+unsigned long clk_measure_input_freq(void)
+{
+ u32 clock_autodetect;
+ clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+ do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+ clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+ if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
+ return 12000000;
+ } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
+ return 13000000;
+ } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
+ return 19200000;
+ } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
+ return 26000000;
+ } else {
+ pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
+ BUG();
+ return 0;
+ }
+}
+
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+ s64 divider_u71 = parent_rate * 2;
+ divider_u71 += rate - 1;
+ do_div(divider_u71, rate);
+
+ if (divider_u71 - 2 < 0)
+ return 0;
+
+ if (divider_u71 - 2 > 255)
+ return -EINVAL;
+
+ return divider_u71 - 2;
+}
+
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+ s64 divider_u16;
+
+ divider_u16 = parent_rate;
+ divider_u16 += rate - 1;
+ do_div(divider_u16, rate);
+
+ if (divider_u16 - 1 < 0)
+ return 0;
+
+ if (divider_u16 - 1 > 255)
+ return -EINVAL;
+
+ return divider_u16 - 1;
+}
+
+/* clk_m functions */
+static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
+{
+ u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
+
+ c->rate = clk_measure_input_freq();
+ switch (c->rate) {
+ case 12000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+ break;
+ case 13000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+ break;
+ case 19200000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+ break;
+ case 26000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+ break;
+ default:
+ pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+ BUG();
+ }
+ clk_writel(auto_clock_control, OSC_CTRL);
+ return c->rate;
+}
+
+static void tegra2_clk_m_init(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ tegra2_clk_m_autodetect_rate(c);
+}
+
+static int tegra2_clk_m_enable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ return 0;
+}
+
+static void tegra2_clk_m_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ BUG();
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+ .init = tegra2_clk_m_init,
+ .enable = tegra2_clk_m_enable,
+ .disable = tegra2_clk_m_disable,
+};
+
+void tegra2_periph_reset_assert(struct clk *c)
+{
+ BUG_ON(!c->ops->reset);
+ c->ops->reset(c, true);
+}
+
+void tegra2_periph_reset_deassert(struct clk *c)
+{
+ BUG_ON(!c->ops->reset);
+ c->ops->reset(c, false);
+}
+
+/* super clock functions */
+/* "super clocks" on tegra have two-stage muxes and a clock skipping
+ * super divider. We will ignore the clock skipping divider, since we
+ * can't lower the voltage when using the clock skip, but we can if we
+ * lower the PLL frequency.
+ */
+static void tegra2_super_clk_init(struct clk *c)
+{
+ u32 val;
+ int source;
+ int shift;
+ const struct clk_mux_sel *sel;
+ val = clk_readl(c->reg + SUPER_CLK_MUX);
+ c->state = ON;
+ BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+ ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+ shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+ SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+ source = (val >> shift) & SUPER_SOURCE_MASK;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->value == source)
+ break;
+ }
+ BUG_ON(sel->input == NULL);
+ c->parent = sel->input;
+}
+
+static int tegra2_super_clk_enable(struct clk *c)
+{
+ clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+ return 0;
+}
+
+static void tegra2_super_clk_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ /* oops - don't disable the CPU clock! */
+ BUG();
+}
+
+static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ int shift;
+
+ val = clk_readl(c->reg + SUPER_CLK_MUX);
+ BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+ ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+ shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+ SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ val &= ~(SUPER_SOURCE_MASK << shift);
+ val |= sel->value << shift;
+
+ if (c->refcnt)
+ clk_enable(p);
+
+ clk_writel(val, c->reg);
+
+ if (c->refcnt && c->parent)
+ clk_disable(c->parent);
+
+ clk_reparent(c, p);
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+/*
+ * Super clocks have "clock skippers" instead of dividers. Dividing using
+ * a clock skipper does not allow the voltage to be scaled down, so instead
+ * adjust the rate of the parent clock. This requires that the parent of a
+ * super clock have no other children, otherwise the rate will change
+ * underneath the other children.
+ */
+static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ return clk_set_rate(c->parent, rate);
+}
+
+static struct clk_ops tegra_super_ops = {
+ .init = tegra2_super_clk_init,
+ .enable = tegra2_super_clk_enable,
+ .disable = tegra2_super_clk_disable,
+ .set_parent = tegra2_super_clk_set_parent,
+ .set_rate = tegra2_super_clk_set_rate,
+};
+
+/* virtual cpu clock functions */
+/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
+ To change the frequency of these clocks, the parent pll may need to be
+ reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
+ and then the clock moved back to the pll. To hide this sequence, a virtual
+ clock handles it.
+ */
+static void tegra2_cpu_clk_init(struct clk *c)
+{
+}
+
+static int tegra2_cpu_clk_enable(struct clk *c)
+{
+ return 0;
+}
+
+static void tegra2_cpu_clk_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ /* oops - don't disable the CPU clock! */
+ BUG();
+}
+
+static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+ /*
+ * Take an extra reference to the main pll so it doesn't turn
+ * off when we move the cpu off of it
+ */
+ clk_enable(c->u.cpu.main);
+
+ ret = clk_set_parent(c->parent, c->u.cpu.backup);
+ if (ret) {
+ pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
+ goto out;
+ }
+
+ if (rate == clk_get_rate(c->u.cpu.backup))
+ goto out;
+
+ ret = clk_set_rate(c->u.cpu.main, rate);
+ if (ret) {
+ pr_err("Failed to change cpu pll to %lu\n", rate);
+ goto out;
+ }
+
+ ret = clk_set_parent(c->parent, c->u.cpu.main);
+ if (ret) {
+ pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
+ goto out;
+ }
+
+out:
+ clk_disable(c->u.cpu.main);
+ return ret;
+}
+
+static struct clk_ops tegra_cpu_ops = {
+ .init = tegra2_cpu_clk_init,
+ .enable = tegra2_cpu_clk_enable,
+ .disable = tegra2_cpu_clk_disable,
+ .set_rate = tegra2_cpu_clk_set_rate,
+};
+
+/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
+ * reset the COP block (i.e. AVP) */
+static void tegra2_cop_clk_reset(struct clk *c, bool assert)
+{
+ unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
+
+ pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
+ clk_writel(1 << 1, reg);
+}
+
+static struct clk_ops tegra_cop_ops = {
+ .reset = tegra2_cop_clk_reset,
+};
+
+/* bus clock functions */
+static void tegra2_bus_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
+ c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
+ c->mul = 1;
+}
+
+static int tegra2_bus_clk_enable(struct clk *c)
+{
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&clock_register_lock, flags);
+
+ val = clk_readl(c->reg);
+ val &= ~(BUS_CLK_DISABLE << c->reg_shift);
+ clk_writel(val, c->reg);
+
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+
+ return 0;
+}
+
+static void tegra2_bus_clk_disable(struct clk *c)
+{
+ u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&clock_register_lock, flags);
+
+ val = clk_readl(c->reg);
+ val |= BUS_CLK_DISABLE << c->reg_shift;
+ clk_writel(val, c->reg);
+
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+}
+
+static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ unsigned long parent_rate = clk_get_rate(c->parent);
+ unsigned long flags;
+ int ret = -EINVAL;
+ int i;
+
+ spin_lock_irqsave(&clock_register_lock, flags);
+
+ val = clk_readl(c->reg);
+ for (i = 1; i <= 4; i++) {
+ if (rate == parent_rate / i) {
+ val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
+ val |= (i - 1) << c->reg_shift;
+ clk_writel(val, c->reg);
+ c->div = i;
+ c->mul = 1;
+ ret = 0;
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+
+ return ret;
+}
+
+static struct clk_ops tegra_bus_ops = {
+ .init = tegra2_bus_clk_init,
+ .enable = tegra2_bus_clk_enable,
+ .disable = tegra2_bus_clk_disable,
+ .set_rate = tegra2_bus_clk_set_rate,
+};
+
+/* Blink output functions */
+
+static void tegra2_blink_clk_init(struct clk *c)
+{
+ u32 val;
+
+ val = pmc_readl(PMC_CTRL);
+ c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
+ c->mul = 1;
+ val = pmc_readl(c->reg);
+
+ if (val & PMC_BLINK_TIMER_ENB) {
+ unsigned int on_off;
+
+ on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+ PMC_BLINK_TIMER_DATA_ON_MASK;
+ val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+ val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+ on_off += val;
+ /* each tick in the blink timer is 4 32KHz clocks */
+ c->div = on_off * 4;
+ } else {
+ c->div = 1;
+ }
+}
+
+static int tegra2_blink_clk_enable(struct clk *c)
+{
+ u32 val;
+
+ val = pmc_readl(PMC_DPD_PADS_ORIDE);
+ pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+
+ val = pmc_readl(PMC_CTRL);
+ pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+ return 0;
+}
+
+static void tegra2_blink_clk_disable(struct clk *c)
+{
+ u32 val;
+
+ val = pmc_readl(PMC_CTRL);
+ pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+ val = pmc_readl(PMC_DPD_PADS_ORIDE);
+ pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+}
+
+static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(c->parent);
+ if (rate >= parent_rate) {
+ c->div = 1;
+ pmc_writel(0, c->reg);
+ } else {
+ unsigned int on_off;
+ u32 val;
+
+ on_off = DIV_ROUND_UP(parent_rate / 8, rate);
+ c->div = on_off * 8;
+
+ val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
+ PMC_BLINK_TIMER_DATA_ON_SHIFT;
+ on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+ on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+ val |= on_off;
+ val |= PMC_BLINK_TIMER_ENB;
+ pmc_writel(val, c->reg);
+ }
+
+ return 0;
+}
+
+static struct clk_ops tegra_blink_clk_ops = {
+ .init = &tegra2_blink_clk_init,
+ .enable = &tegra2_blink_clk_enable,
+ .disable = &tegra2_blink_clk_disable,
+ .set_rate = &tegra2_blink_clk_set_rate,
+};
+
+/* PLL Functions */
+static int tegra2_pll_clk_wait_for_lock(struct clk *c)
+{
+ udelay(c->u.pll.lock_delay);
+
+ return 0;
+}
+
+static void tegra2_pll_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg + PLL_BASE);
+
+ c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+
+ if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+ pr_warning("Clock %s has unknown fixed frequency\n", c->name);
+ c->mul = 1;
+ c->div = 1;
+ } else if (val & PLL_BASE_BYPASS) {
+ c->mul = 1;
+ c->div = 1;
+ } else {
+ c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+ c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+ if (c->flags & PLLU)
+ c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+ else
+ c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
+ }
+}
+
+static int tegra2_pll_clk_enable(struct clk *c)
+{
+ u32 val;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ val = clk_readl(c->reg + PLL_BASE);
+ val &= ~PLL_BASE_BYPASS;
+ val |= PLL_BASE_ENABLE;
+ clk_writel(val, c->reg + PLL_BASE);
+
+ tegra2_pll_clk_wait_for_lock(c);
+
+ return 0;
+}
+
+static void tegra2_pll_clk_disable(struct clk *c)
+{
+ u32 val;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ val = clk_readl(c->reg);
+ val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+ clk_writel(val, c->reg);
+}
+
+static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ unsigned long input_rate;
+ const struct clk_pll_freq_table *sel;
+
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+ input_rate = clk_get_rate(c->parent);
+ for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+ if (sel->input_rate == input_rate && sel->output_rate == rate) {
+ c->mul = sel->n;
+ c->div = sel->m * sel->p;
+
+ val = clk_readl(c->reg + PLL_BASE);
+ if (c->flags & PLL_FIXED)
+ val |= PLL_BASE_OVERRIDE;
+ val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
+ PLL_BASE_DIVM_MASK);
+ val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+ (sel->n << PLL_BASE_DIVN_SHIFT);
+ BUG_ON(sel->p < 1 || sel->p > 2);
+ if (c->flags & PLLU) {
+ if (sel->p == 1)
+ val |= PLLU_BASE_POST_DIV;
+ } else {
+ if (sel->p == 2)
+ val |= 1 << PLL_BASE_DIVP_SHIFT;
+ }
+ clk_writel(val, c->reg + PLL_BASE);
+
+ if (c->flags & PLL_HAS_CPCON) {
+ val = clk_readl(c->reg + PLL_MISC(c));
+ val &= ~PLL_MISC_CPCON_MASK;
+ val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
+ clk_writel(val, c->reg + PLL_MISC(c));
+ }
+
+ if (c->state == ON)
+ tegra2_pll_clk_enable(c);
+
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_ops = {
+ .init = tegra2_pll_clk_init,
+ .enable = tegra2_pll_clk_enable,
+ .disable = tegra2_pll_clk_disable,
+ .set_rate = tegra2_pll_clk_set_rate,
+};
+
+static void tegra2_pllx_clk_init(struct clk *c)
+{
+ tegra2_pll_clk_init(c);
+
+ if (tegra_sku_id() == 7)
+ c->max_rate = 750000000;
+}
+
+static struct clk_ops tegra_pllx_ops = {
+ .init = tegra2_pllx_clk_init,
+ .enable = tegra2_pll_clk_enable,
+ .disable = tegra2_pll_clk_disable,
+ .set_rate = tegra2_pll_clk_set_rate,
+};
+
+static int tegra2_plle_clk_enable(struct clk *c)
+{
+ u32 val;
+
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ mdelay(1);
+
+ val = clk_readl(c->reg + PLL_BASE);
+ if (!(val & PLLE_MISC_READY))
+ return -EBUSY;
+
+ val = clk_readl(c->reg + PLL_BASE);
+ val |= PLL_BASE_ENABLE | PLL_BASE_BYPASS;
+ clk_writel(val, c->reg + PLL_BASE);
+
+ return 0;
+}
+
+static struct clk_ops tegra_plle_ops = {
+ .init = tegra2_pll_clk_init,
+ .enable = tegra2_plle_clk_enable,
+ .set_rate = tegra2_pll_clk_set_rate,
+};
+
+/* Clock divider ops */
+static void tegra2_pll_div_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ u32 divu71;
+ val >>= c->reg_shift;
+ c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+ if (!(val & PLL_OUT_RESET_DISABLE))
+ c->state = OFF;
+
+ if (c->flags & DIV_U71) {
+ divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+ c->div = (divu71 + 2);
+ c->mul = 2;
+ } else if (c->flags & DIV_2) {
+ c->div = 2;
+ c->mul = 1;
+ } else {
+ c->div = 1;
+ c->mul = 1;
+ }
+}
+
+static int tegra2_pll_div_clk_enable(struct clk *c)
+{
+ u32 val;
+ u32 new_val;
+ unsigned long flags;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->flags & DIV_U71) {
+ spin_lock_irqsave(&clock_register_lock, flags);
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+
+ new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+ return 0;
+ } else if (c->flags & DIV_2) {
+ BUG_ON(!(c->flags & PLLD));
+ spin_lock_irqsave(&clock_register_lock, flags);
+ val = clk_readl(c->reg);
+ val &= ~PLLD_MISC_DIV_RST;
+ clk_writel(val, c->reg);
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void tegra2_pll_div_clk_disable(struct clk *c)
+{
+ u32 val;
+ u32 new_val;
+ unsigned long flags;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->flags & DIV_U71) {
+ spin_lock_irqsave(&clock_register_lock, flags);
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+
+ new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+ } else if (c->flags & DIV_2) {
+ BUG_ON(!(c->flags & PLLD));
+ spin_lock_irqsave(&clock_register_lock, flags);
+ val = clk_readl(c->reg);
+ val |= PLLD_MISC_DIV_RST;
+ clk_writel(val, c->reg);
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+ }
+}
+
+static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ u32 new_val;
+ int divider_u71;
+ unsigned long parent_rate = clk_get_rate(c->parent);
+ unsigned long flags;
+
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+ if (c->flags & DIV_U71) {
+ divider_u71 = clk_div71_get_divider(parent_rate, rate);
+ if (divider_u71 >= 0) {
+ spin_lock_irqsave(&clock_register_lock, flags);
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+ if (c->flags & DIV_U71_FIXED)
+ new_val |= PLL_OUT_OVERRIDE;
+ new_val &= ~PLL_OUT_RATIO_MASK;
+ new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ c->div = divider_u71 + 2;
+ c->mul = 2;
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+ return 0;
+ }
+ } else if (c->flags & DIV_2) {
+ if (parent_rate == rate * 2)
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+{
+ int divider;
+ unsigned long parent_rate = clk_get_rate(c->parent);
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+ if (c->flags & DIV_U71) {
+ divider = clk_div71_get_divider(parent_rate, rate);
+ if (divider < 0)
+ return divider;
+ return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+ } else if (c->flags & DIV_2) {
+ return DIV_ROUND_UP(parent_rate, 2);
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_div_ops = {
+ .init = tegra2_pll_div_clk_init,
+ .enable = tegra2_pll_div_clk_enable,
+ .disable = tegra2_pll_div_clk_disable,
+ .set_rate = tegra2_pll_div_clk_set_rate,
+ .round_rate = tegra2_pll_div_clk_round_rate,
+};
+
+/* Periph clk ops */
+
+static void tegra2_periph_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ const struct clk_mux_sel *mux = 0;
+ const struct clk_mux_sel *sel;
+ if (c->flags & MUX) {
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
+ mux = sel;
+ }
+ BUG_ON(!mux);
+
+ c->parent = mux->input;
+ } else {
+ c->parent = c->inputs[0].input;
+ }
+
+ if (c->flags & DIV_U71) {
+ u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+ c->div = divu71 + 2;
+ c->mul = 2;
+ } else if (c->flags & DIV_U16) {
+ u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+ c->div = divu16 + 1;
+ c->mul = 1;
+ } else {
+ c->div = 1;
+ c->mul = 1;
+ }
+
+ c->state = ON;
+
+ if (!c->u.periph.clk_num)
+ return;
+
+ if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c)))
+ c->state = OFF;
+
+ if (!(c->flags & PERIPH_NO_RESET))
+ if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c))
+ c->state = OFF;
+}
+
+static int tegra2_periph_clk_enable(struct clk *c)
+{
+ u32 val;
+ unsigned long flags;
+ int refcount;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ if (!c->u.periph.clk_num)
+ return 0;
+
+ spin_lock_irqsave(&clock_register_lock, flags);
+
+ refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
+
+ if (refcount > 1)
+ goto out;
+
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+ if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+ if (c->flags & PERIPH_EMC_ENB) {
+ /* The EMC peripheral clock has 2 extra enable bits */
+ /* FIXME: Do they need to be disabled? */
+ val = clk_readl(c->reg);
+ val |= 0x3 << 24;
+ clk_writel(val, c->reg);
+ }
+
+out:
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+
+ return 0;
+}
+
+static void tegra2_periph_clk_disable(struct clk *c)
+{
+ unsigned long flags;
+
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ if (!c->u.periph.clk_num)
+ return;
+
+ spin_lock_irqsave(&clock_register_lock, flags);
+
+ if (c->refcnt)
+ tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+ if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0)
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+
+ spin_unlock_irqrestore(&clock_register_lock, flags);
+}
+
+static void tegra2_periph_clk_reset(struct clk *c, bool assert)
+{
+ unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
+
+ pr_debug("%s %s on clock %s\n", __func__,
+ assert ? "assert" : "deassert", c->name);
+
+ BUG_ON(!c->u.periph.clk_num);
+
+ if (!(c->flags & PERIPH_NO_RESET))
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ base + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_MASK;
+ val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
+
+ if (c->refcnt)
+ clk_enable(p);
+
+ clk_writel(val, c->reg);
+
+ if (c->refcnt && c->parent)
+ clk_disable(c->parent);
+
+ clk_reparent(c, p);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ int divider;
+ unsigned long parent_rate = clk_get_rate(c->parent);
+
+ if (c->flags & DIV_U71) {
+ divider = clk_div71_get_divider(parent_rate, rate);
+ if (divider >= 0) {
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+ val |= divider;
+ clk_writel(val, c->reg);
+ c->div = divider + 2;
+ c->mul = 2;
+ return 0;
+ }
+ } else if (c->flags & DIV_U16) {
+ divider = clk_div16_get_divider(parent_rate, rate);
+ if (divider >= 0) {
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+ val |= divider;
+ clk_writel(val, c->reg);
+ c->div = divider + 1;
+ c->mul = 1;
+ return 0;
+ }
+ } else if (parent_rate <= rate) {
+ c->div = 1;
+ c->mul = 1;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static long tegra2_periph_clk_round_rate(struct clk *c,
+ unsigned long rate)
+{
+ int divider;
+ unsigned long parent_rate = clk_get_rate(c->parent);
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+ if (c->flags & DIV_U71) {
+ divider = clk_div71_get_divider(parent_rate, rate);
+ if (divider < 0)
+ return divider;
+
+ return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+ } else if (c->flags & DIV_U16) {
+ divider = clk_div16_get_divider(parent_rate, rate);
+ if (divider < 0)
+ return divider;
+ return DIV_ROUND_UP(parent_rate, divider + 1);
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+ .init = &tegra2_periph_clk_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .set_parent = &tegra2_periph_clk_set_parent,
+ .set_rate = &tegra2_periph_clk_set_rate,
+ .round_rate = &tegra2_periph_clk_round_rate,
+ .reset = &tegra2_periph_clk_reset,
+};
+
+/* The SDMMC controllers have extra bits in the clock source register that
+ * adjust the delay between the clock and data to compenstate for delays
+ * on the PCB. */
+void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
+{
+ u32 reg;
+
+ delay = clamp(delay, 0, 15);
+ reg = clk_readl(c->reg);
+ reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
+ reg |= SDMMC_CLK_INT_FB_SEL;
+ reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
+ clk_writel(reg, c->reg);
+}
+
+/* External memory controller clock ops */
+static void tegra2_emc_clk_init(struct clk *c)
+{
+ tegra2_periph_clk_init(c);
+ c->max_rate = clk_get_rate_locked(c);
+}
+
+static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
+{
+ long new_rate = rate;
+
+ new_rate = tegra_emc_round_rate(new_rate);
+ if (new_rate < 0)
+ return c->max_rate;
+
+ BUG_ON(new_rate != tegra2_periph_clk_round_rate(c, new_rate));
+
+ return new_rate;
+}
+
+static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret;
+ /*
+ * The Tegra2 memory controller has an interlock with the clock
+ * block that allows memory shadowed registers to be updated,
+ * and then transfer them to the main registers at the same
+ * time as the clock update without glitches.
+ */
+ ret = tegra_emc_set_rate(rate);
+ if (ret < 0)
+ return ret;
+
+ ret = tegra2_periph_clk_set_rate(c, rate);
+ udelay(1);
+
+ return ret;
+}
+
+static struct clk_ops tegra_emc_clk_ops = {
+ .init = &tegra2_emc_clk_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .set_parent = &tegra2_periph_clk_set_parent,
+ .set_rate = &tegra2_emc_clk_set_rate,
+ .round_rate = &tegra2_emc_clk_round_rate,
+ .reset = &tegra2_periph_clk_reset,
+};
+
+/* Clock doubler ops */
+static void tegra2_clk_double_init(struct clk *c)
+{
+ c->mul = 2;
+ c->div = 1;
+ c->state = ON;
+
+ if (!c->u.periph.clk_num)
+ return;
+
+ if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c)))
+ c->state = OFF;
+};
+
+static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate)
+{
+ if (rate != 2 * clk_get_rate(c->parent))
+ return -EINVAL;
+ c->mul = 2;
+ c->div = 1;
+ return 0;
+}
+
+static struct clk_ops tegra_clk_double_ops = {
+ .init = &tegra2_clk_double_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .set_rate = &tegra2_clk_double_set_rate,
+};
+
+/* Audio sync clock ops */
+static void tegra2_audio_sync_clk_init(struct clk *c)
+{
+ int source;
+ const struct clk_mux_sel *sel;
+ u32 val = clk_readl(c->reg);
+ c->state = (val & (1<<4)) ? OFF : ON;
+ source = val & 0xf;
+ for (sel = c->inputs; sel->input != NULL; sel++)
+ if (sel->value == source)
+ break;
+ BUG_ON(sel->input == NULL);
+ c->parent = sel->input;
+}
+
+static int tegra2_audio_sync_clk_enable(struct clk *c)
+{
+ clk_writel(0, c->reg);
+ return 0;
+}
+
+static void tegra2_audio_sync_clk_disable(struct clk *c)
+{
+ clk_writel(1, c->reg);
+}
+
+static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ val = clk_readl(c->reg);
+ val &= ~0xf;
+ val |= sel->value;
+
+ if (c->refcnt)
+ clk_enable(p);
+
+ clk_writel(val, c->reg);
+
+ if (c->refcnt && c->parent)
+ clk_disable(c->parent);
+
+ clk_reparent(c, p);
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_audio_sync_clk_ops = {
+ .init = tegra2_audio_sync_clk_init,
+ .enable = tegra2_audio_sync_clk_enable,
+ .disable = tegra2_audio_sync_clk_disable,
+ .set_parent = tegra2_audio_sync_clk_set_parent,
+};
+
+/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
+
+static void tegra2_cdev_clk_init(struct clk *c)
+{
+ /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
+ * currently done in the pinmux code. */
+ c->state = ON;
+
+ BUG_ON(!c->u.periph.clk_num);
+
+ if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c)))
+ c->state = OFF;
+}
+
+static int tegra2_cdev_clk_enable(struct clk *c)
+{
+ BUG_ON(!c->u.periph.clk_num);
+
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+ return 0;
+}
+
+static void tegra2_cdev_clk_disable(struct clk *c)
+{
+ BUG_ON(!c->u.periph.clk_num);
+
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+static struct clk_ops tegra_cdev_clk_ops = {
+ .init = &tegra2_cdev_clk_init,
+ .enable = &tegra2_cdev_clk_enable,
+ .disable = &tegra2_cdev_clk_disable,
+};
+
+/* shared bus ops */
+/*
+ * Some clocks may have multiple downstream users that need to request a
+ * higher clock rate. Shared bus clocks provide a unique shared_bus_user
+ * clock to each user. The frequency of the bus is set to the highest
+ * enabled shared_bus_user clock, with a minimum value set by the
+ * shared bus.
+ */
+static int tegra_clk_shared_bus_update(struct clk *bus)
+{
+ struct clk *c;
+ unsigned long rate = bus->min_rate;
+
+ list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
+ if (c->u.shared_bus_user.enabled)
+ rate = max(c->u.shared_bus_user.rate, rate);
+
+ if (rate == clk_get_rate_locked(bus))
+ return 0;
+
+ return clk_set_rate_locked(bus, rate);
+};
+
+static void tegra_clk_shared_bus_init(struct clk *c)
+{
+ unsigned long flags;
+
+ c->max_rate = c->parent->max_rate;
+ c->u.shared_bus_user.rate = c->parent->max_rate;
+ c->state = OFF;
+ c->set = true;
+
+ spin_lock_irqsave(&c->parent->spinlock, flags);
+
+ list_add_tail(&c->u.shared_bus_user.node,
+ &c->parent->shared_bus_list);
+
+ spin_unlock_irqrestore(&c->parent->spinlock, flags);
+}
+
+static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
+{
+ unsigned long flags;
+ int ret;
+ long new_rate = rate;
+
+ new_rate = clk_round_rate(c->parent, new_rate);
+ if (new_rate < 0)
+ return new_rate;
+
+ spin_lock_irqsave(&c->parent->spinlock, flags);
+
+ c->u.shared_bus_user.rate = new_rate;
+ ret = tegra_clk_shared_bus_update(c->parent);
+
+ spin_unlock_irqrestore(&c->parent->spinlock, flags);
+
+ return ret;
+}
+
+static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
+{
+ return clk_round_rate(c->parent, rate);
+}
+
+static int tegra_clk_shared_bus_enable(struct clk *c)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&c->parent->spinlock, flags);
+
+ c->u.shared_bus_user.enabled = true;
+ ret = tegra_clk_shared_bus_update(c->parent);
+
+ spin_unlock_irqrestore(&c->parent->spinlock, flags);
+
+ return ret;
+}
+
+static void tegra_clk_shared_bus_disable(struct clk *c)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&c->parent->spinlock, flags);
+
+ c->u.shared_bus_user.enabled = false;
+ ret = tegra_clk_shared_bus_update(c->parent);
+ WARN_ON_ONCE(ret);
+
+ spin_unlock_irqrestore(&c->parent->spinlock, flags);
+}
+
+static struct clk_ops tegra_clk_shared_bus_ops = {
+ .init = tegra_clk_shared_bus_init,
+ .enable = tegra_clk_shared_bus_enable,
+ .disable = tegra_clk_shared_bus_disable,
+ .set_rate = tegra_clk_shared_bus_set_rate,
+ .round_rate = tegra_clk_shared_bus_round_rate,
+};
+
+
+/* Clock definitions */
+static struct clk tegra_clk_32k = {
+ .name = "clk_32k",
+ .rate = 32768,
+ .ops = NULL,
+ .max_rate = 32768,
+};
+
+static struct clk_pll_freq_table tegra_pll_s_freq_table[] = {
+ {32768, 12000000, 366, 1, 1, 0},
+ {32768, 13000000, 397, 1, 1, 0},
+ {32768, 19200000, 586, 1, 1, 0},
+ {32768, 26000000, 793, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct clk tegra_pll_s = {
+ .name = "pll_s",
+ .flags = PLL_ALT_MISC_REG,
+ .ops = &tegra_pll_ops,
+ .parent = &tegra_clk_32k,
+ .max_rate = 26000000,
+ .reg = 0xf0,
+ .u.pll = {
+ .input_min = 32768,
+ .input_max = 32768,
+ .cf_min = 0, /* FIXME */
+ .cf_max = 0, /* FIXME */
+ .vco_min = 12000000,
+ .vco_max = 26000000,
+ .freq_table = tegra_pll_s_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk_mux_sel tegra_clk_m_sel[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { .input = &tegra_pll_s, .value = 1},
+ { 0, 0},
+};
+
+static struct clk tegra_clk_m = {
+ .name = "clk_m",
+ .flags = ENABLE_ON_INIT,
+ .ops = &tegra_clk_m_ops,
+ .inputs = tegra_clk_m_sel,
+ .reg = 0x1fc,
+ .reg_shift = 28,
+ .max_rate = 26000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_c_freq_table[] = {
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_c = {
+ .name = "pll_c",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x80,
+ .parent = &tegra_clk_m,
+ .max_rate = 600000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .freq_table = tegra_pll_c_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk tegra_pll_c_out1 = {
+ .name = "pll_c_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_c,
+ .reg = 0x84,
+ .reg_shift = 0,
+ .max_rate = 600000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_m_freq_table[] = {
+ { 12000000, 666000000, 666, 12, 1, 8},
+ { 13000000, 666000000, 666, 13, 1, 8},
+ { 19200000, 666000000, 555, 16, 1, 8},
+ { 26000000, 666000000, 666, 26, 1, 8},
+ { 12000000, 600000000, 600, 12, 1, 8},
+ { 13000000, 600000000, 600, 13, 1, 8},
+ { 19200000, 600000000, 375, 12, 1, 6},
+ { 26000000, 600000000, 600, 26, 1, 8},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_m = {
+ .name = "pll_m",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x90,
+ .parent = &tegra_clk_m,
+ .max_rate = 800000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1200000000,
+ .freq_table = tegra_pll_m_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk tegra_pll_m_out1 = {
+ .name = "pll_m_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_m,
+ .reg = 0x94,
+ .reg_shift = 0,
+ .max_rate = 600000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_p_freq_table[] = {
+ { 12000000, 216000000, 432, 12, 2, 8},
+ { 13000000, 216000000, 432, 13, 2, 8},
+ { 19200000, 216000000, 90, 4, 2, 1},
+ { 26000000, 216000000, 432, 26, 2, 8},
+ { 12000000, 432000000, 432, 12, 1, 8},
+ { 13000000, 432000000, 432, 13, 1, 8},
+ { 19200000, 432000000, 90, 4, 1, 1},
+ { 26000000, 432000000, 432, 26, 1, 8},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_p = {
+ .name = "pll_p",
+ .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xa0,
+ .parent = &tegra_clk_m,
+ .max_rate = 432000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .freq_table = tegra_pll_p_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk tegra_pll_p_out1 = {
+ .name = "pll_p_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 0,
+ .max_rate = 432000000,
+};
+
+static struct clk tegra_pll_p_out2 = {
+ .name = "pll_p_out2",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 16,
+ .max_rate = 432000000,
+};
+
+static struct clk tegra_pll_p_out3 = {
+ .name = "pll_p_out3",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 0,
+ .max_rate = 432000000,
+};
+
+static struct clk tegra_pll_p_out4 = {
+ .name = "pll_p_out4",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 16,
+ .max_rate = 432000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_a_freq_table[] = {
+ { 28800000, 56448000, 49, 25, 1, 1},
+ { 28800000, 73728000, 64, 25, 1, 1},
+ { 28800000, 24000000, 5, 6, 1, 1},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_a = {
+ .name = "pll_a",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xb0,
+ .parent = &tegra_pll_p_out1,
+ .max_rate = 73728000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .freq_table = tegra_pll_a_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk tegra_pll_a_out0 = {
+ .name = "pll_a_out0",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_a,
+ .reg = 0xb4,
+ .reg_shift = 0,
+ .max_rate = 73728000,
+};
+
+static struct clk_pll_freq_table tegra_pll_d_freq_table[] = {
+ { 12000000, 216000000, 216, 12, 1, 4},
+ { 13000000, 216000000, 216, 13, 1, 4},
+ { 19200000, 216000000, 135, 12, 1, 3},
+ { 26000000, 216000000, 216, 26, 1, 4},
+
+ { 12000000, 594000000, 594, 12, 1, 8},
+ { 13000000, 594000000, 594, 13, 1, 8},
+ { 19200000, 594000000, 495, 16, 1, 8},
+ { 26000000, 594000000, 594, 26, 1, 8},
+
+ { 12000000, 1000000000, 1000, 12, 1, 12},
+ { 13000000, 1000000000, 1000, 13, 1, 12},
+ { 19200000, 1000000000, 625, 12, 1, 8},
+ { 26000000, 1000000000, 1000, 26, 1, 12},
+
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_d = {
+ .name = "pll_d",
+ .flags = PLL_HAS_CPCON | PLLD,
+ .ops = &tegra_pll_ops,
+ .reg = 0xd0,
+ .parent = &tegra_clk_m,
+ .max_rate = 1000000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 40000000,
+ .vco_max = 1000000000,
+ .freq_table = tegra_pll_d_freq_table,
+ .lock_delay = 1000,
+ },
+};
+
+static struct clk tegra_pll_d_out0 = {
+ .name = "pll_d_out0",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_2 | PLLD,
+ .parent = &tegra_pll_d,
+ .max_rate = 500000000,
+};
+
+static struct clk_pll_freq_table tegra_pll_u_freq_table[] = {
+ { 12000000, 480000000, 960, 12, 2, 0},
+ { 13000000, 480000000, 960, 13, 2, 0},
+ { 19200000, 480000000, 200, 4, 2, 0},
+ { 26000000, 480000000, 960, 26, 2, 0},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_u = {
+ .name = "pll_u",
+ .flags = PLLU,
+ .ops = &tegra_pll_ops,
+ .reg = 0xc0,
+ .parent = &tegra_clk_m,
+ .max_rate = 480000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 480000000,
+ .vco_max = 960000000,
+ .freq_table = tegra_pll_u_freq_table,
+ .lock_delay = 1000,
+ },
+};
+
+static struct clk_pll_freq_table tegra_pll_x_freq_table[] = {
+ /* 1 GHz */
+ { 12000000, 1000000000, 1000, 12, 1, 12},
+ { 13000000, 1000000000, 1000, 13, 1, 12},
+ { 19200000, 1000000000, 625, 12, 1, 8},
+ { 26000000, 1000000000, 1000, 26, 1, 12},
+
+ /* 912 MHz */
+ { 12000000, 912000000, 912, 12, 1, 12},
+ { 13000000, 912000000, 912, 13, 1, 12},
+ { 19200000, 912000000, 760, 16, 1, 8},
+ { 26000000, 912000000, 912, 26, 1, 12},
+
+ /* 816 MHz */
+ { 12000000, 816000000, 816, 12, 1, 12},
+ { 13000000, 816000000, 816, 13, 1, 12},
+ { 19200000, 816000000, 680, 16, 1, 8},
+ { 26000000, 816000000, 816, 26, 1, 12},
+
+ /* 760 MHz */
+ { 12000000, 760000000, 760, 12, 1, 12},
+ { 13000000, 760000000, 760, 13, 1, 12},
+ { 19200000, 760000000, 950, 24, 1, 8},
+ { 26000000, 760000000, 760, 26, 1, 12},
+
+ /* 608 MHz */
+ { 12000000, 608000000, 608, 12, 1, 12},
+ { 13000000, 608000000, 608, 13, 1, 12},
+ { 19200000, 608000000, 380, 12, 1, 8},
+ { 26000000, 608000000, 608, 26, 1, 12},
+
+ /* 456 MHz */
+ { 12000000, 456000000, 456, 12, 1, 12},
+ { 13000000, 456000000, 456, 13, 1, 12},
+ { 19200000, 456000000, 380, 16, 1, 8},
+ { 26000000, 456000000, 456, 26, 1, 12},
+
+ /* 312 MHz */
+ { 12000000, 312000000, 312, 12, 1, 12},
+ { 13000000, 312000000, 312, 13, 1, 12},
+ { 19200000, 312000000, 260, 16, 1, 8},
+ { 26000000, 312000000, 312, 26, 1, 12},
+
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_x = {
+ .name = "pll_x",
+ .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
+ .ops = &tegra_pllx_ops,
+ .reg = 0xe0,
+ .parent = &tegra_clk_m,
+ .max_rate = 1000000000,
+ .u.pll = {
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1200000000,
+ .freq_table = tegra_pll_x_freq_table,
+ .lock_delay = 300,
+ },
+};
+
+static struct clk_pll_freq_table tegra_pll_e_freq_table[] = {
+ { 12000000, 100000000, 200, 24, 1, 0 },
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_e = {
+ .name = "pll_e",
+ .flags = PLL_ALT_MISC_REG,
+ .ops = &tegra_plle_ops,
+ .parent = &tegra_clk_m,
+ .reg = 0xe8,
+ .max_rate = 100000000,
+ .u.pll = {
+ .input_min = 12000000,
+ .input_max = 12000000,
+ .freq_table = tegra_pll_e_freq_table,
+ },
+};
+
+static struct clk tegra_clk_d = {
+ .name = "clk_d",
+ .flags = PERIPH_NO_RESET,
+ .ops = &tegra_clk_double_ops,
+ .reg = 0x34,
+ .reg_shift = 12,
+ .parent = &tegra_clk_m,
+ .max_rate = 52000000,
+ .u.periph = {
+ .clk_num = 90,
+ },
+};
+
+/* dap_mclk1, belongs to the cdev1 pingroup. */
+static struct clk tegra_clk_cdev1 = {
+ .name = "cdev1",
+ .ops = &tegra_cdev_clk_ops,
+ .rate = 26000000,
+ .max_rate = 26000000,
+ .u.periph = {
+ .clk_num = 94,
+ },
+};
+
+/* dap_mclk2, belongs to the cdev2 pingroup. */
+static struct clk tegra_clk_cdev2 = {
+ .name = "cdev2",
+ .ops = &tegra_cdev_clk_ops,
+ .rate = 26000000,
+ .max_rate = 26000000,
+ .u.periph = {
+ .clk_num = 93,
+ },
+};
+
+/* initialized before peripheral clocks */
+static struct clk_mux_sel mux_audio_sync_clk[8+1];
+static const struct audio_sources {
+ const char *name;
+ int value;
+} mux_audio_sync_clk_sources[] = {
+ { .name = "spdif_in", .value = 0 },
+ { .name = "i2s1", .value = 1 },
+ { .name = "i2s2", .value = 2 },
+ { .name = "pll_a_out0", .value = 4 },
+#if 0 /* FIXME: not implemented */
+ { .name = "ac97", .value = 3 },
+ { .name = "ext_audio_clk2", .value = 5 },
+ { .name = "ext_audio_clk1", .value = 6 },
+ { .name = "ext_vimclk", .value = 7 },
+#endif
+ { 0, 0 }
+};
+
+static struct clk tegra_clk_audio = {
+ .name = "audio",
+ .inputs = mux_audio_sync_clk,
+ .reg = 0x38,
+ .max_rate = 73728000,
+ .ops = &tegra_audio_sync_clk_ops
+};
+
+static struct clk tegra_clk_audio_2x = {
+ .name = "audio_2x",
+ .flags = PERIPH_NO_RESET,
+ .max_rate = 48000000,
+ .ops = &tegra_clk_double_ops,
+ .reg = 0x34,
+ .reg_shift = 8,
+ .parent = &tegra_clk_audio,
+ .u.periph = {
+ .clk_num = 89,
+ },
+};
+
+struct clk_lookup tegra_audio_clk_lookups[] = {
+ { .con_id = "audio", .clk = &tegra_clk_audio },
+ { .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
+};
+
+/* This is called after peripheral clocks are initialized, as the
+ * audio_sync clock depends on some of the peripheral clocks.
+ */
+
+static void init_audio_sync_clock_mux(void)
+{
+ int i;
+ struct clk_mux_sel *sel = mux_audio_sync_clk;
+ const struct audio_sources *src = mux_audio_sync_clk_sources;
+ struct clk_lookup *lookup;
+
+ for (i = 0; src->name; i++, sel++, src++) {
+ sel->input = tegra_get_clock_by_name(src->name);
+ if (!sel->input)
+ pr_err("%s: could not find clk %s\n", __func__,
+ src->name);
+ sel->value = src->value;
+ }
+
+ lookup = tegra_audio_clk_lookups;
+ for (i = 0; i < ARRAY_SIZE(tegra_audio_clk_lookups); i++, lookup++) {
+ clk_init(lookup->clk);
+ clkdev_add(lookup);
+ }
+}
+
+static struct clk_mux_sel mux_cclk[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_clk_32k, .value = 2},
+ { .input = &tegra_pll_m, .value = 3},
+ { .input = &tegra_pll_p, .value = 4},
+ { .input = &tegra_pll_p_out4, .value = 5},
+ { .input = &tegra_pll_p_out3, .value = 6},
+ { .input = &tegra_clk_d, .value = 7},
+ { .input = &tegra_pll_x, .value = 8},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_sclk[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { .input = &tegra_pll_c_out1, .value = 1},
+ { .input = &tegra_pll_p_out4, .value = 2},
+ { .input = &tegra_pll_p_out3, .value = 3},
+ { .input = &tegra_pll_p_out2, .value = 4},
+ { .input = &tegra_clk_d, .value = 5},
+ { .input = &tegra_clk_32k, .value = 6},
+ { .input = &tegra_pll_m_out1, .value = 7},
+ { 0, 0},
+};
+
+static struct clk tegra_clk_cclk = {
+ .name = "cclk",
+ .inputs = mux_cclk,
+ .reg = 0x20,
+ .ops = &tegra_super_ops,
+ .max_rate = 1000000000,
+};
+
+static struct clk tegra_clk_sclk = {
+ .name = "sclk",
+ .inputs = mux_sclk,
+ .reg = 0x28,
+ .ops = &tegra_super_ops,
+ .max_rate = 240000000,
+ .min_rate = 120000000,
+};
+
+static struct clk tegra_clk_virtual_cpu = {
+ .name = "cpu",
+ .parent = &tegra_clk_cclk,
+ .ops = &tegra_cpu_ops,
+ .max_rate = 1000000000,
+ .u.cpu = {
+ .main = &tegra_pll_x,
+ .backup = &tegra_pll_p,
+ },
+};
+
+static struct clk tegra_clk_cop = {
+ .name = "cop",
+ .parent = &tegra_clk_sclk,
+ .ops = &tegra_cop_ops,
+ .max_rate = 240000000,
+};
+
+static struct clk tegra_clk_hclk = {
+ .name = "hclk",
+ .flags = DIV_BUS,
+ .parent = &tegra_clk_sclk,
+ .reg = 0x30,
+ .reg_shift = 4,
+ .ops = &tegra_bus_ops,
+ .max_rate = 240000000,
+};
+
+static struct clk tegra_clk_pclk = {
+ .name = "pclk",
+ .flags = DIV_BUS,
+ .parent = &tegra_clk_hclk,
+ .reg = 0x30,
+ .reg_shift = 0,
+ .ops = &tegra_bus_ops,
+ .max_rate = 120000000,
+};
+
+static struct clk tegra_clk_blink = {
+ .name = "blink",
+ .parent = &tegra_clk_32k,
+ .reg = 0x40,
+ .ops = &tegra_blink_clk_ops,
+ .max_rate = 32768,
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
+ { .input = &tegra_pll_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_p, .value = 2},
+ { .input = &tegra_pll_a_out0, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
+ { .input = &tegra_pll_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_p, .value = 2},
+ { .input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
+ { .input = &tegra_pll_p, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_m, .value = 2},
+ { .input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllaout0_audio2x_pllp_clkm[] = {
+ {.input = &tegra_pll_a_out0, .value = 0},
+ {.input = &tegra_clk_audio_2x, .value = 1},
+ {.input = &tegra_pll_p, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_d_out0, .value = 1},
+ {.input = &tegra_pll_c, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ {.input = &tegra_clk_audio, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ {.input = &tegra_clk_32k, .value = 4},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ {.input = &tegra_pll_m, .value = 2},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_m[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_out3[] = {
+ { .input = &tegra_pll_p_out3, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_plld[] = {
+ { .input = &tegra_pll_d, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_32k[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pclk[] = {
+ { .input = &tegra_clk_pclk, .value = 0},
+ { 0, 0},
+};
+
+static struct clk tegra_clk_emc = {
+ .name = "emc",
+ .ops = &tegra_emc_clk_ops,
+ .reg = 0x19c,
+ .max_rate = 800000000,
+ .inputs = mux_pllm_pllc_pllp_clkm,
+ .flags = MUX | DIV_U71 | PERIPH_EMC_ENB,
+ .u.periph = {
+ .clk_num = 57,
+ },
+};
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _max, _inputs, _flags) \
+ { \
+ .name = _name, \
+ .lookup = { \
+ .dev_id = _dev, \
+ .con_id = _con, \
+ }, \
+ .ops = &tegra_periph_clk_ops, \
+ .reg = _reg, \
+ .inputs = _inputs, \
+ .flags = _flags, \
+ .max_rate = _max, \
+ .u.periph = { \
+ .clk_num = _clk_num, \
+ }, \
+ }
+
+#define SHARED_CLK(_name, _dev, _con, _parent) \
+ { \
+ .name = _name, \
+ .lookup = { \
+ .dev_id = _dev, \
+ .con_id = _con, \
+ }, \
+ .ops = &tegra_clk_shared_bus_ops, \
+ .parent = _parent, \
+ }
+
+struct clk tegra_list_clks[] = {
+ PERIPH_CLK("apbdma", "tegra-dma", NULL, 34, 0, 108000000, mux_pclk, 0),
+ PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, 32768, mux_clk_32k, PERIPH_NO_RESET),
+ PERIPH_CLK("timer", "timer", NULL, 5, 0, 26000000, mux_clk_m, 0),
+ PERIPH_CLK("i2s1", "tegra-i2s.0", NULL, 11, 0x100, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2s2", "tegra-i2s.1", NULL, 18, 0x104, 26000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, 100000000, mux_pllaout0_audio2x_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, 100000000, mux_pllp_pllc_pllm, MUX | DIV_U71),
+ PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, 432000000, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
+ PERIPH_CLK("spi", "spi", NULL, 43, 0x114, 40000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("xio", "xio", NULL, 45, 0x120, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, 150000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, 160000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("ide", "ide", NULL, 25, 0x144, 100000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, 164000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, 72000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x164, 52000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("vcp", "tegra-avp", "vcp", 29, 0, 250000000, mux_clk_m, 0),
+ PERIPH_CLK("bsea", "tegra-avp", "bsea", 62, 0, 250000000, mux_clk_m, 0),
+ PERIPH_CLK("bsev", "tegra-aes", "bsev", 63, 0, 250000000, mux_clk_m, 0),
+ PERIPH_CLK("vde", "tegra-avp", "vde", 61, 0x1c8, 250000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, 144000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* max rate ??? */
+ /* FIXME: what is la? */
+ PERIPH_CLK("la", "la", NULL, 76, 0x1f8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("owr", "tegra_w1", NULL, 71, 0x1cc, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, 92000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, 60000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71), /* scales with voltage */
+ PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, 26000000, mux_pllp_pllc_pllm_clkm, MUX | DIV_U16),
+ PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, 600000000, mux_pllp_pllc_pllm_clkm, MUX),
+ PERIPH_CLK("3d", "3d", NULL, 24, 0x158, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET), /* scales with voltage and process_id */
+ PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("vi", "tegra_camera", "vi", 20, 0x148, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("vi_sensor", "tegra_camera", "vi_sensor", 20, 0x1a8, 150000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_NO_RESET), /* scales with voltage and process_id */
+ PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, 300000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, 250000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, 166000000, mux_pllm_pllc_pllp_plla, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("cve", "cve", NULL, 49, 0x140, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, 250000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* requires min voltage */
+ PERIPH_CLK("disp1", "tegradc.0", NULL, 27, 0x138, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("disp2", "tegradc.1", NULL, 26, 0x13c, 600000000, mux_pllp_plld_pllc_clkm, MUX | DIV_U71), /* scales with voltage and process_id */
+ PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usb2", "tegra-ehci.1", NULL, 58, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("usb3", "tegra-ehci.2", NULL, 59, 0, 480000000, mux_clk_m, 0), /* requires min voltage */
+ PERIPH_CLK("dsi", "dsi", NULL, 48, 0, 500000000, mux_plld, 0), /* scales with voltage */
+ PERIPH_CLK("csi", "tegra_camera", "csi", 52, 0, 72000000, mux_pllp_out3, 0),
+ PERIPH_CLK("isp", "tegra_camera", "isp", 23, 0, 150000000, mux_clk_m, 0), /* same frequency as VI */
+ PERIPH_CLK("csus", "tegra_camera", "csus", 92, 0, 150000000, mux_clk_m, PERIPH_NO_RESET),
+ PERIPH_CLK("pex", NULL, "pex", 70, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
+ PERIPH_CLK("afi", NULL, "afi", 72, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
+ PERIPH_CLK("pcie_xclk", NULL, "pcie_xclk", 74, 0, 26000000, mux_clk_m, PERIPH_MANUAL_RESET),
+
+ SHARED_CLK("avp.sclk", "tegra-avp", "sclk", &tegra_clk_sclk),
+ SHARED_CLK("avp.emc", "tegra-avp", "emc", &tegra_clk_emc),
+ SHARED_CLK("cpu.emc", "cpu", "emc", &tegra_clk_emc),
+ SHARED_CLK("disp1.emc", "tegradc.0", "emc", &tegra_clk_emc),
+ SHARED_CLK("disp2.emc", "tegradc.1", "emc", &tegra_clk_emc),
+ SHARED_CLK("hdmi.emc", "hdmi", "emc", &tegra_clk_emc),
+ SHARED_CLK("host.emc", "tegra_grhost", "emc", &tegra_clk_emc),
+ SHARED_CLK("usbd.emc", "fsl-tegra-udc", "emc", &tegra_clk_emc),
+ SHARED_CLK("usb1.emc", "tegra-ehci.0", "emc", &tegra_clk_emc),
+ SHARED_CLK("usb2.emc", "tegra-ehci.1", "emc", &tegra_clk_emc),
+ SHARED_CLK("usb3.emc", "tegra-ehci.2", "emc", &tegra_clk_emc),
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con) \
+ { \
+ .name = _name, \
+ .lookup = { \
+ .dev_id = _dev, \
+ .con_id = _con, \
+ }, \
+ }
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration. List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+struct clk_duplicate tegra_clk_duplicates[] = {
+ CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
+ CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
+ CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
+ CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
+ CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
+ CLK_DUPLICATE("usbd", "utmip-pad", NULL),
+ CLK_DUPLICATE("usbd", "tegra-ehci.0", NULL),
+ CLK_DUPLICATE("usbd", "tegra-otg", NULL),
+ CLK_DUPLICATE("hdmi", "tegradc.0", "hdmi"),
+ CLK_DUPLICATE("hdmi", "tegradc.1", "hdmi"),
+ CLK_DUPLICATE("pwm", "tegra_pwm.0", NULL),
+ CLK_DUPLICATE("pwm", "tegra_pwm.1", NULL),
+ CLK_DUPLICATE("pwm", "tegra_pwm.2", NULL),
+ CLK_DUPLICATE("pwm", "tegra_pwm.3", NULL),
+ CLK_DUPLICATE("host1x", "tegra_grhost", "host1x"),
+ CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
+ CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
+ CLK_DUPLICATE("epp", "tegra_grhost", "epp"),
+ CLK_DUPLICATE("mpe", "tegra_grhost", "mpe"),
+ CLK_DUPLICATE("cop", "tegra-avp", "cop"),
+ CLK_DUPLICATE("vde", "tegra-aes", "vde"),
+};
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }
+
+struct clk *tegra_ptr_clks[] = {
+ &tegra_clk_32k,
+ &tegra_pll_s,
+ &tegra_clk_m,
+ &tegra_pll_m,
+ &tegra_pll_m_out1,
+ &tegra_pll_c,
+ &tegra_pll_c_out1,
+ &tegra_pll_p,
+ &tegra_pll_p_out1,
+ &tegra_pll_p_out2,
+ &tegra_pll_p_out3,
+ &tegra_pll_p_out4,
+ &tegra_pll_a,
+ &tegra_pll_a_out0,
+ &tegra_pll_d,
+ &tegra_pll_d_out0,
+ &tegra_pll_u,
+ &tegra_pll_x,
+ &tegra_pll_e,
+ &tegra_clk_cclk,
+ &tegra_clk_sclk,
+ &tegra_clk_hclk,
+ &tegra_clk_pclk,
+ &tegra_clk_d,
+ &tegra_clk_cdev1,
+ &tegra_clk_cdev2,
+ &tegra_clk_virtual_cpu,
+ &tegra_clk_blink,
+ &tegra_clk_cop,
+ &tegra_clk_emc,
+};
+
+static void tegra2_init_one_clock(struct clk *c)
+{
+ clk_init(c);
+ INIT_LIST_HEAD(&c->shared_bus_list);
+ if (!c->lookup.dev_id && !c->lookup.con_id)
+ c->lookup.con_id = c->name;
+ c->lookup.clk = c;
+ clkdev_add(&c->lookup);
+}
+
+void __init tegra2_init_clocks(void)
+{
+ int i;
+ struct clk *c;
+
+ for (i = 0; i < ARRAY_SIZE(tegra_ptr_clks); i++)
+ tegra2_init_one_clock(tegra_ptr_clks[i]);
+
+ for (i = 0; i < ARRAY_SIZE(tegra_list_clks); i++)
+ tegra2_init_one_clock(&tegra_list_clks[i]);
+
+ for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+ c = tegra_get_clock_by_name(tegra_clk_duplicates[i].name);
+ if (!c) {
+ pr_err("%s: Unknown duplicate clock %s\n", __func__,
+ tegra_clk_duplicates[i].name);
+ continue;
+ }
+
+ tegra_clk_duplicates[i].lookup.clk = c;
+ clkdev_add(&tegra_clk_duplicates[i].lookup);
+ }
+
+ init_audio_sync_clock_mux();
+}
+
+#ifdef CONFIG_PM
+static u32 clk_rst_suspend[RST_DEVICES_NUM + CLK_OUT_ENB_NUM +
+ PERIPH_CLK_SOURCE_NUM + 22];
+
+void tegra_clk_suspend(void)
+{
+ unsigned long off, i;
+ u32 *ctx = clk_rst_suspend;
+
+ *ctx++ = clk_readl(OSC_CTRL) & OSC_CTRL_MASK;
+ *ctx++ = clk_readl(tegra_pll_c.reg + PLL_BASE);
+ *ctx++ = clk_readl(tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
+ *ctx++ = clk_readl(tegra_pll_a.reg + PLL_BASE);
+ *ctx++ = clk_readl(tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
+ *ctx++ = clk_readl(tegra_pll_s.reg + PLL_BASE);
+ *ctx++ = clk_readl(tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
+ *ctx++ = clk_readl(tegra_pll_d.reg + PLL_BASE);
+ *ctx++ = clk_readl(tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
+ *ctx++ = clk_readl(tegra_pll_u.reg + PLL_BASE);
+ *ctx++ = clk_readl(tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
+
+ *ctx++ = clk_readl(tegra_pll_m_out1.reg);
+ *ctx++ = clk_readl(tegra_pll_a_out0.reg);
+ *ctx++ = clk_readl(tegra_pll_c_out1.reg);
+
+ *ctx++ = clk_readl(tegra_clk_cclk.reg);
+ *ctx++ = clk_readl(tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
+
+ *ctx++ = clk_readl(tegra_clk_sclk.reg);
+ *ctx++ = clk_readl(tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
+ *ctx++ = clk_readl(tegra_clk_pclk.reg);
+
+ *ctx++ = clk_readl(tegra_clk_audio.reg);
+
+ for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
+ off += 4) {
+ if (off == PERIPH_CLK_SOURCE_EMC)
+ continue;
+ *ctx++ = clk_readl(off);
+ }
+
+ off = RST_DEVICES;
+ for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
+ *ctx++ = clk_readl(off);
+
+ off = CLK_OUT_ENB;
+ for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
+ *ctx++ = clk_readl(off);
+
+ *ctx++ = clk_readl(MISC_CLK_ENB);
+ *ctx++ = clk_readl(CLK_MASK_ARM);
+
+ BUG_ON(ctx - clk_rst_suspend != ARRAY_SIZE(clk_rst_suspend));
+}
+
+void tegra_clk_resume(void)
+{
+ unsigned long off, i;
+ const u32 *ctx = clk_rst_suspend;
+ u32 val;
+
+ val = clk_readl(OSC_CTRL) & ~OSC_CTRL_MASK;
+ val |= *ctx++;
+ clk_writel(val, OSC_CTRL);
+
+ clk_writel(*ctx++, tegra_pll_c.reg + PLL_BASE);
+ clk_writel(*ctx++, tegra_pll_c.reg + PLL_MISC(&tegra_pll_c));
+ clk_writel(*ctx++, tegra_pll_a.reg + PLL_BASE);
+ clk_writel(*ctx++, tegra_pll_a.reg + PLL_MISC(&tegra_pll_a));
+ clk_writel(*ctx++, tegra_pll_s.reg + PLL_BASE);
+ clk_writel(*ctx++, tegra_pll_s.reg + PLL_MISC(&tegra_pll_s));
+ clk_writel(*ctx++, tegra_pll_d.reg + PLL_BASE);
+ clk_writel(*ctx++, tegra_pll_d.reg + PLL_MISC(&tegra_pll_d));
+ clk_writel(*ctx++, tegra_pll_u.reg + PLL_BASE);
+ clk_writel(*ctx++, tegra_pll_u.reg + PLL_MISC(&tegra_pll_u));
+ udelay(1000);
+
+ clk_writel(*ctx++, tegra_pll_m_out1.reg);
+ clk_writel(*ctx++, tegra_pll_a_out0.reg);
+ clk_writel(*ctx++, tegra_pll_c_out1.reg);
+
+ clk_writel(*ctx++, tegra_clk_cclk.reg);
+ clk_writel(*ctx++, tegra_clk_cclk.reg + SUPER_CLK_DIVIDER);
+
+ clk_writel(*ctx++, tegra_clk_sclk.reg);
+ clk_writel(*ctx++, tegra_clk_sclk.reg + SUPER_CLK_DIVIDER);
+ clk_writel(*ctx++, tegra_clk_pclk.reg);
+
+ clk_writel(*ctx++, tegra_clk_audio.reg);
+
+ /* enable all clocks before configuring clock sources */
+ clk_writel(0xbffffff9ul, CLK_OUT_ENB);
+ clk_writel(0xfefffff7ul, CLK_OUT_ENB + 4);
+ clk_writel(0x77f01bfful, CLK_OUT_ENB + 8);
+ wmb();
+
+ for (off = PERIPH_CLK_SOURCE_I2S1; off <= PERIPH_CLK_SOURCE_OSC;
+ off += 4) {
+ if (off == PERIPH_CLK_SOURCE_EMC)
+ continue;
+ clk_writel(*ctx++, off);
+ }
+ wmb();
+
+ off = RST_DEVICES;
+ for (i = 0; i < RST_DEVICES_NUM; i++, off += 4)
+ clk_writel(*ctx++, off);
+ wmb();
+
+ off = CLK_OUT_ENB;
+ for (i = 0; i < CLK_OUT_ENB_NUM; i++, off += 4)
+ clk_writel(*ctx++, off);
+ wmb();
+
+ clk_writel(*ctx++, MISC_CLK_ENB);
+ clk_writel(*ctx++, CLK_MASK_ARM);
+}
+#endif
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
new file mode 100644
index 00000000..0f7ae6e9
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+
+#include <mach/iomap.h>
+
+#include "tegra2_emc.h"
+
+#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
+static bool emc_enable = true;
+#else
+static bool emc_enable;
+#endif
+module_param(emc_enable, bool, 0644);
+
+static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
+static const struct tegra_emc_table *tegra_emc_table;
+static int tegra_emc_table_size;
+
+static inline void emc_writel(u32 val, unsigned long addr)
+{
+ writel(val, emc + addr);
+}
+
+static inline u32 emc_readl(unsigned long addr)
+{
+ return readl(emc + addr);
+}
+
+static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
+ 0x2c, /* RC */
+ 0x30, /* RFC */
+ 0x34, /* RAS */
+ 0x38, /* RP */
+ 0x3c, /* R2W */
+ 0x40, /* W2R */
+ 0x44, /* R2P */
+ 0x48, /* W2P */
+ 0x4c, /* RD_RCD */
+ 0x50, /* WR_RCD */
+ 0x54, /* RRD */
+ 0x58, /* REXT */
+ 0x5c, /* WDV */
+ 0x60, /* QUSE */
+ 0x64, /* QRST */
+ 0x68, /* QSAFE */
+ 0x6c, /* RDV */
+ 0x70, /* REFRESH */
+ 0x74, /* BURST_REFRESH_NUM */
+ 0x78, /* PDEX2WR */
+ 0x7c, /* PDEX2RD */
+ 0x80, /* PCHG2PDEN */
+ 0x84, /* ACT2PDEN */
+ 0x88, /* AR2PDEN */
+ 0x8c, /* RW2PDEN */
+ 0x90, /* TXSR */
+ 0x94, /* TCKE */
+ 0x98, /* TFAW */
+ 0x9c, /* TRPAB */
+ 0xa0, /* TCLKSTABLE */
+ 0xa4, /* TCLKSTOP */
+ 0xa8, /* TREFBW */
+ 0xac, /* QUSE_EXTRA */
+ 0x114, /* FBIO_CFG6 */
+ 0xb0, /* ODT_WRITE */
+ 0xb4, /* ODT_READ */
+ 0x104, /* FBIO_CFG5 */
+ 0x2bc, /* CFG_DIG_DLL */
+ 0x2c0, /* DLL_XFORM_DQS */
+ 0x2c4, /* DLL_XFORM_QUSE */
+ 0x2e0, /* ZCAL_REF_CNT */
+ 0x2e4, /* ZCAL_WAIT_CNT */
+ 0x2a8, /* AUTO_CAL_INTERVAL */
+ 0x2d0, /* CFG_CLKTRIM_0 */
+ 0x2d4, /* CFG_CLKTRIM_1 */
+ 0x2d8, /* CFG_CLKTRIM_2 */
+};
+
+/* Select the closest EMC rate that is higher than the requested rate */
+long tegra_emc_round_rate(unsigned long rate)
+{
+ int i;
+ int best = -1;
+ unsigned long distance = ULONG_MAX;
+
+ if (!tegra_emc_table)
+ return -EINVAL;
+
+ if (!emc_enable)
+ return -EINVAL;
+
+ pr_debug("%s: %lu\n", __func__, rate);
+
+ /*
+ * The EMC clock rate is twice the bus rate, and the bus rate is
+ * measured in kHz
+ */
+ rate = rate / 2 / 1000;
+
+ for (i = 0; i < tegra_emc_table_size; i++) {
+ if (tegra_emc_table[i].rate >= rate &&
+ (tegra_emc_table[i].rate - rate) < distance) {
+ distance = tegra_emc_table[i].rate - rate;
+ best = i;
+ }
+ }
+
+ if (best < 0)
+ return -EINVAL;
+
+ pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+
+ return tegra_emc_table[best].rate * 2 * 1000;
+}
+
+/*
+ * The EMC registers have shadow registers. When the EMC clock is updated
+ * in the clock controller, the shadow registers are copied to the active
+ * registers, allowing glitchless memory bus frequency changes.
+ * This function updates the shadow registers for a new clock frequency,
+ * and relies on the clock lock on the emc clock to avoid races between
+ * multiple frequency changes
+ */
+int tegra_emc_set_rate(unsigned long rate)
+{
+ int i;
+ int j;
+
+ if (!tegra_emc_table)
+ return -EINVAL;
+
+ /*
+ * The EMC clock rate is twice the bus rate, and the bus rate is
+ * measured in kHz
+ */
+ rate = rate / 2 / 1000;
+
+ for (i = 0; i < tegra_emc_table_size; i++)
+ if (tegra_emc_table[i].rate == rate)
+ break;
+
+ if (i >= tegra_emc_table_size)
+ return -EINVAL;
+
+ pr_debug("%s: setting to %lu\n", __func__, rate);
+
+ for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
+ emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+
+ emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+
+ return 0;
+}
+
+void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+{
+ tegra_emc_table = table;
+ tegra_emc_table_size = table_size;
+}
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
new file mode 100644
index 00000000..19f08cb3
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 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.
+ *
+ */
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
+
+int tegra_emc_set_rate(unsigned long rate);
+long tegra_emc_round_rate(unsigned long rate);
+void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
new file mode 100644
index 00000000..90350420
--- /dev/null
+++ b/arch/arm/mach-tegra/timer.c
@@ -0,0 +1,262 @@
+/*
+ * arch/arch/mach-tegra/timer.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/mach/time.h>
+#include <asm/localtimer.h>
+#include <asm/sched_clock.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/suspend.h>
+
+#include "board.h"
+#include "clock.h"
+
+#define RTC_SECONDS 0x08
+#define RTC_SHADOW_SECONDS 0x0c
+#define RTC_MILLISECONDS 0x10
+
+#define TIMERUS_CNTR_1US 0x10
+#define TIMERUS_USEC_CFG 0x14
+#define TIMERUS_CNTR_FREEZE 0x4c
+
+#define TIMER1_BASE 0x0
+#define TIMER2_BASE 0x8
+#define TIMER3_BASE 0x50
+#define TIMER4_BASE 0x58
+
+#define TIMER_PTV 0x0
+#define TIMER_PCR 0x4
+
+static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
+static void __iomem *rtc_base = IO_ADDRESS(TEGRA_RTC_BASE);
+
+static struct timespec persistent_ts;
+static u64 persistent_ms, last_persistent_ms;
+
+#define timer_writel(value, reg) \
+ __raw_writel(value, (u32)timer_reg_base + (reg))
+#define timer_readl(reg) \
+ __raw_readl((u32)timer_reg_base + (reg))
+
+static int tegra_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
+ timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+
+ return 0;
+}
+
+static void tegra_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ timer_writel(0, TIMER3_BASE + TIMER_PTV);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ reg = 0xC0000000 | ((1000000/HZ)-1);
+ timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+ 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 tegra_clockevent = {
+ .name = "timer0",
+ .rating = 300,
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .set_next_event = tegra_timer_set_next_event,
+ .set_mode = tegra_timer_set_mode,
+};
+
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 1MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 1us and a wrap period of about 1h11min.
+ */
+#define SC_MULT 4194304000u
+#define SC_SHIFT 22
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+static void notrace tegra_update_sched_clock(void)
+{
+ u32 cyc = timer_readl(TIMERUS_CNTR_1US);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/*
+ * tegra_rtc_read - Reads the Tegra RTC registers
+ * Care must be taken that this funciton is not called while the
+ * tegra_rtc driver could be executing to avoid race conditions
+ * on the RTC shadow register
+ */
+u64 tegra_rtc_read_ms(void)
+{
+ u32 ms = readl(rtc_base + RTC_MILLISECONDS);
+ u32 s = readl(rtc_base + RTC_SHADOW_SECONDS);
+ return (u64)s * MSEC_PER_SEC + ms;
+}
+
+/*
+ * read_persistent_clock - Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer. Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ * Care must be taken that this funciton is not called while the
+ * tegra_rtc driver could be executing to avoid race conditions
+ * on the RTC shadow register
+ */
+void read_persistent_clock(struct timespec *ts)
+{
+ u64 delta;
+ struct timespec *tsp = &persistent_ts;
+
+ last_persistent_ms = persistent_ms;
+ persistent_ms = tegra_rtc_read_ms();
+ delta = persistent_ms - last_persistent_ms;
+
+ timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
+ *ts = *tsp;
+}
+
+static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+ timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction tegra_timer_irq = {
+ .name = "timer0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
+ .handler = tegra_timer_interrupt,
+ .dev_id = &tegra_clockevent,
+ .irq = INT_TMR3,
+};
+
+static void __init tegra_init_timer(void)
+{
+ struct clk *clk;
+ unsigned long rate = clk_measure_input_freq();
+ int ret;
+
+ clk = clk_get_sys("timer", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+
+ /*
+ * rtc registers are used by read_persistent_clock, keep the rtc clock
+ * enabled
+ */
+ clk = clk_get_sys("rtc-tegra", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
+#endif
+
+ switch (rate) {
+ case 12000000:
+ timer_writel(0x000b, TIMERUS_USEC_CFG);
+ break;
+ case 13000000:
+ timer_writel(0x000c, TIMERUS_USEC_CFG);
+ break;
+ case 19200000:
+ timer_writel(0x045f, TIMERUS_USEC_CFG);
+ break;
+ case 26000000:
+ timer_writel(0x0019, TIMERUS_USEC_CFG);
+ break;
+ default:
+ WARN(1, "Unknown clock rate");
+ }
+
+ init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
+ 1000000, SC_MULT, SC_SHIFT);
+
+ if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
+ "timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
+ printk(KERN_ERR "Failed to register clocksource\n");
+ BUG();
+ }
+
+ ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
+ if (ret) {
+ printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
+ BUG();
+ }
+
+ clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
+ tegra_clockevent.max_delta_ns =
+ clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
+ tegra_clockevent.min_delta_ns =
+ clockevent_delta2ns(0x1, &tegra_clockevent);
+ tegra_clockevent.cpumask = cpu_all_mask;
+ tegra_clockevent.irq = tegra_timer_irq.irq;
+ clockevents_register_device(&tegra_clockevent);
+}
+
+struct sys_timer tegra_timer = {
+ .init = tegra_init_timer,
+};
+
+#ifdef CONFIG_PM
+static u32 usec_config;
+
+void tegra_timer_suspend(void)
+{
+ usec_config = timer_readl(TIMERUS_USEC_CFG);
+}
+
+void tegra_timer_resume(void)
+{
+ timer_writel(usec_config, TIMERUS_USEC_CFG);
+}
+#endif
diff --git a/arch/arm/mach-tegra/usb_phy.c b/arch/arm/mach-tegra/usb_phy.c
new file mode 100644
index 00000000..88081bb3
--- /dev/null
+++ b/arch/arm/mach-tegra/usb_phy.c
@@ -0,0 +1,795 @@
+/*
+ * arch/arm/mach-tegra/usb_phy.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ * Benoit Goby <benoit@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/resource.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <asm/mach-types.h>
+#include <mach/usb_phy.h>
+#include <mach/iomap.h>
+
+#define ULPI_VIEWPORT 0x170
+
+#define USB_PORTSC1 0x184
+#define USB_PORTSC1_PTS(x) (((x) & 0x3) << 30)
+#define USB_PORTSC1_PSPD(x) (((x) & 0x3) << 26)
+#define USB_PORTSC1_PHCD (1 << 23)
+#define USB_PORTSC1_WKOC (1 << 22)
+#define USB_PORTSC1_WKDS (1 << 21)
+#define USB_PORTSC1_WKCN (1 << 20)
+#define USB_PORTSC1_PTC(x) (((x) & 0xf) << 16)
+#define USB_PORTSC1_PP (1 << 12)
+#define USB_PORTSC1_SUSP (1 << 7)
+#define USB_PORTSC1_PE (1 << 2)
+#define USB_PORTSC1_CCS (1 << 0)
+
+#define USB_SUSP_CTRL 0x400
+#define USB_WAKE_ON_CNNT_EN_DEV (1 << 3)
+#define USB_WAKE_ON_DISCON_EN_DEV (1 << 4)
+#define USB_SUSP_CLR (1 << 5)
+#define USB_PHY_CLK_VALID (1 << 7)
+#define UTMIP_RESET (1 << 11)
+#define UHSIC_RESET (1 << 11)
+#define UTMIP_PHY_ENABLE (1 << 12)
+#define ULPI_PHY_ENABLE (1 << 13)
+#define USB_SUSP_SET (1 << 14)
+#define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16)
+
+#define USB1_LEGACY_CTRL 0x410
+#define USB1_NO_LEGACY_MODE (1 << 0)
+#define USB1_VBUS_SENSE_CTL_MASK (3 << 1)
+#define USB1_VBUS_SENSE_CTL_VBUS_WAKEUP (0 << 1)
+#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD_OR_VBUS_WAKEUP \
+ (1 << 1)
+#define USB1_VBUS_SENSE_CTL_AB_SESS_VLD (2 << 1)
+#define USB1_VBUS_SENSE_CTL_A_SESS_VLD (3 << 1)
+
+#define ULPI_TIMING_CTRL_0 0x424
+#define ULPI_OUTPUT_PINMUX_BYP (1 << 10)
+#define ULPI_CLKOUT_PINMUX_BYP (1 << 11)
+
+#define ULPI_TIMING_CTRL_1 0x428
+#define ULPI_DATA_TRIMMER_LOAD (1 << 0)
+#define ULPI_DATA_TRIMMER_SEL(x) (((x) & 0x7) << 1)
+#define ULPI_STPDIRNXT_TRIMMER_LOAD (1 << 16)
+#define ULPI_STPDIRNXT_TRIMMER_SEL(x) (((x) & 0x7) << 17)
+#define ULPI_DIR_TRIMMER_LOAD (1 << 24)
+#define ULPI_DIR_TRIMMER_SEL(x) (((x) & 0x7) << 25)
+
+#define UTMIP_PLL_CFG1 0x804
+#define UTMIP_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
+#define UTMIP_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
+
+#define UTMIP_XCVR_CFG0 0x808
+#define UTMIP_XCVR_SETUP(x) (((x) & 0xf) << 0)
+#define UTMIP_XCVR_LSRSLEW(x) (((x) & 0x3) << 8)
+#define UTMIP_XCVR_LSFSLEW(x) (((x) & 0x3) << 10)
+#define UTMIP_FORCE_PD_POWERDOWN (1 << 14)
+#define UTMIP_FORCE_PD2_POWERDOWN (1 << 16)
+#define UTMIP_FORCE_PDZI_POWERDOWN (1 << 18)
+#define UTMIP_XCVR_HSSLEW_MSB(x) (((x) & 0x7f) << 25)
+
+#define UTMIP_BIAS_CFG0 0x80c
+#define UTMIP_OTGPD (1 << 11)
+#define UTMIP_BIASPD (1 << 10)
+
+#define UTMIP_HSRX_CFG0 0x810
+#define UTMIP_ELASTIC_LIMIT(x) (((x) & 0x1f) << 10)
+#define UTMIP_IDLE_WAIT(x) (((x) & 0x1f) << 15)
+
+#define UTMIP_HSRX_CFG1 0x814
+#define UTMIP_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1)
+
+#define UTMIP_TX_CFG0 0x820
+#define UTMIP_FS_PREABMLE_J (1 << 19)
+#define UTMIP_HS_DISCON_DISABLE (1 << 8)
+
+#define UTMIP_MISC_CFG0 0x824
+#define UTMIP_DPDM_OBSERVE (1 << 26)
+#define UTMIP_DPDM_OBSERVE_SEL(x) (((x) & 0xf) << 27)
+#define UTMIP_DPDM_OBSERVE_SEL_FS_J UTMIP_DPDM_OBSERVE_SEL(0xf)
+#define UTMIP_DPDM_OBSERVE_SEL_FS_K UTMIP_DPDM_OBSERVE_SEL(0xe)
+#define UTMIP_DPDM_OBSERVE_SEL_FS_SE1 UTMIP_DPDM_OBSERVE_SEL(0xd)
+#define UTMIP_DPDM_OBSERVE_SEL_FS_SE0 UTMIP_DPDM_OBSERVE_SEL(0xc)
+#define UTMIP_SUSPEND_EXIT_ON_EDGE (1 << 22)
+
+#define UTMIP_MISC_CFG1 0x828
+#define UTMIP_PLL_ACTIVE_DLY_COUNT(x) (((x) & 0x1f) << 18)
+#define UTMIP_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 6)
+
+#define UTMIP_DEBOUNCE_CFG0 0x82c
+#define UTMIP_BIAS_DEBOUNCE_A(x) (((x) & 0xffff) << 0)
+
+#define UTMIP_BAT_CHRG_CFG0 0x830
+#define UTMIP_PD_CHRG (1 << 0)
+
+#define UTMIP_SPARE_CFG0 0x834
+#define FUSE_SETUP_SEL (1 << 3)
+
+#define UTMIP_XCVR_CFG1 0x838
+#define UTMIP_FORCE_PDDISC_POWERDOWN (1 << 0)
+#define UTMIP_FORCE_PDCHRP_POWERDOWN (1 << 2)
+#define UTMIP_FORCE_PDDR_POWERDOWN (1 << 4)
+#define UTMIP_XCVR_TERM_RANGE_ADJ(x) (((x) & 0xf) << 18)
+
+#define UTMIP_BIAS_CFG1 0x83c
+#define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3)
+
+static DEFINE_SPINLOCK(utmip_pad_lock);
+static int utmip_pad_count;
+
+struct tegra_xtal_freq {
+ int freq;
+ u8 enable_delay;
+ u8 stable_count;
+ u8 active_delay;
+ u8 xtal_freq_count;
+ u16 debounce;
+};
+
+static const struct tegra_xtal_freq tegra_freq_table[] = {
+ {
+ .freq = 12000000,
+ .enable_delay = 0x02,
+ .stable_count = 0x2F,
+ .active_delay = 0x04,
+ .xtal_freq_count = 0x76,
+ .debounce = 0x7530,
+ },
+ {
+ .freq = 13000000,
+ .enable_delay = 0x02,
+ .stable_count = 0x33,
+ .active_delay = 0x05,
+ .xtal_freq_count = 0x7F,
+ .debounce = 0x7EF4,
+ },
+ {
+ .freq = 19200000,
+ .enable_delay = 0x03,
+ .stable_count = 0x4B,
+ .active_delay = 0x06,
+ .xtal_freq_count = 0xBB,
+ .debounce = 0xBB80,
+ },
+ {
+ .freq = 26000000,
+ .enable_delay = 0x04,
+ .stable_count = 0x66,
+ .active_delay = 0x09,
+ .xtal_freq_count = 0xFE,
+ .debounce = 0xFDE8,
+ },
+};
+
+static struct tegra_utmip_config utmip_default[] = {
+ [0] = {
+ .hssync_start_delay = 9,
+ .idle_wait_delay = 17,
+ .elastic_limit = 16,
+ .term_range_adj = 6,
+ .xcvr_setup = 9,
+ .xcvr_lsfslew = 1,
+ .xcvr_lsrslew = 1,
+ },
+ [2] = {
+ .hssync_start_delay = 9,
+ .idle_wait_delay = 17,
+ .elastic_limit = 16,
+ .term_range_adj = 6,
+ .xcvr_setup = 9,
+ .xcvr_lsfslew = 2,
+ .xcvr_lsrslew = 2,
+ },
+};
+
+static inline bool phy_is_ulpi(struct tegra_usb_phy *phy)
+{
+ return (phy->instance == 1);
+}
+
+static int utmip_pad_open(struct tegra_usb_phy *phy)
+{
+ phy->pad_clk = clk_get_sys("utmip-pad", NULL);
+ if (IS_ERR(phy->pad_clk)) {
+ pr_err("%s: can't get utmip pad clock\n", __func__);
+ return PTR_ERR(phy->pad_clk);
+ }
+
+ if (phy->instance == 0) {
+ phy->pad_regs = phy->regs;
+ } else {
+ phy->pad_regs = ioremap(TEGRA_USB_BASE, TEGRA_USB_SIZE);
+ if (!phy->pad_regs) {
+ pr_err("%s: can't remap usb registers\n", __func__);
+ clk_put(phy->pad_clk);
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static void utmip_pad_close(struct tegra_usb_phy *phy)
+{
+ if (phy->instance != 0)
+ iounmap(phy->pad_regs);
+ clk_put(phy->pad_clk);
+}
+
+static void utmip_pad_power_on(struct tegra_usb_phy *phy)
+{
+ unsigned long val, flags;
+ void __iomem *base = phy->pad_regs;
+
+ clk_enable(phy->pad_clk);
+
+ spin_lock_irqsave(&utmip_pad_lock, flags);
+
+ if (utmip_pad_count++ == 0) {
+ val = readl(base + UTMIP_BIAS_CFG0);
+ val &= ~(UTMIP_OTGPD | UTMIP_BIASPD);
+ writel(val, base + UTMIP_BIAS_CFG0);
+ }
+
+ spin_unlock_irqrestore(&utmip_pad_lock, flags);
+
+ clk_disable(phy->pad_clk);
+}
+
+static int utmip_pad_power_off(struct tegra_usb_phy *phy)
+{
+ unsigned long val, flags;
+ void __iomem *base = phy->pad_regs;
+
+ if (!utmip_pad_count) {
+ pr_err("%s: utmip pad already powered off\n", __func__);
+ return -EINVAL;
+ }
+
+ clk_enable(phy->pad_clk);
+
+ spin_lock_irqsave(&utmip_pad_lock, flags);
+
+ if (--utmip_pad_count == 0) {
+ val = readl(base + UTMIP_BIAS_CFG0);
+ val |= UTMIP_OTGPD | UTMIP_BIASPD;
+ writel(val, base + UTMIP_BIAS_CFG0);
+ }
+
+ spin_unlock_irqrestore(&utmip_pad_lock, flags);
+
+ clk_disable(phy->pad_clk);
+
+ return 0;
+}
+
+static int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)
+{
+ unsigned long timeout = 2000;
+ do {
+ if ((readl(reg) & mask) == result)
+ return 0;
+ udelay(1);
+ timeout--;
+ } while (timeout);
+ return -1;
+}
+
+static void utmi_phy_clk_disable(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ if (phy->instance == 0) {
+ val = readl(base + USB_SUSP_CTRL);
+ val |= USB_SUSP_SET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ udelay(10);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~USB_SUSP_SET;
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ if (phy->instance == 2) {
+ val = readl(base + USB_PORTSC1);
+ val |= USB_PORTSC1_PHCD;
+ writel(val, base + USB_PORTSC1);
+ }
+
+ if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0)
+ pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
+}
+
+static void utmi_phy_clk_enable(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ if (phy->instance == 0) {
+ val = readl(base + USB_SUSP_CTRL);
+ val |= USB_SUSP_CLR;
+ writel(val, base + USB_SUSP_CTRL);
+
+ udelay(10);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~USB_SUSP_CLR;
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ if (phy->instance == 2) {
+ val = readl(base + USB_PORTSC1);
+ val &= ~USB_PORTSC1_PHCD;
+ writel(val, base + USB_PORTSC1);
+ }
+
+ if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
+ USB_PHY_CLK_VALID))
+ pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
+}
+
+static int utmi_phy_power_on(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+ struct tegra_utmip_config *config = phy->config;
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= UTMIP_RESET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ if (phy->instance == 0) {
+ val = readl(base + USB1_LEGACY_CTRL);
+ val |= USB1_NO_LEGACY_MODE;
+ writel(val, base + USB1_LEGACY_CTRL);
+ }
+
+ val = readl(base + UTMIP_TX_CFG0);
+ val &= ~UTMIP_FS_PREABMLE_J;
+ writel(val, base + UTMIP_TX_CFG0);
+
+ val = readl(base + UTMIP_HSRX_CFG0);
+ val &= ~(UTMIP_IDLE_WAIT(~0) | UTMIP_ELASTIC_LIMIT(~0));
+ val |= UTMIP_IDLE_WAIT(config->idle_wait_delay);
+ val |= UTMIP_ELASTIC_LIMIT(config->elastic_limit);
+ writel(val, base + UTMIP_HSRX_CFG0);
+
+ val = readl(base + UTMIP_HSRX_CFG1);
+ val &= ~UTMIP_HS_SYNC_START_DLY(~0);
+ val |= UTMIP_HS_SYNC_START_DLY(config->hssync_start_delay);
+ writel(val, base + UTMIP_HSRX_CFG1);
+
+ val = readl(base + UTMIP_DEBOUNCE_CFG0);
+ val &= ~UTMIP_BIAS_DEBOUNCE_A(~0);
+ val |= UTMIP_BIAS_DEBOUNCE_A(phy->freq->debounce);
+ writel(val, base + UTMIP_DEBOUNCE_CFG0);
+
+ val = readl(base + UTMIP_MISC_CFG0);
+ val &= ~UTMIP_SUSPEND_EXIT_ON_EDGE;
+ writel(val, base + UTMIP_MISC_CFG0);
+
+ val = readl(base + UTMIP_MISC_CFG1);
+ val &= ~(UTMIP_PLL_ACTIVE_DLY_COUNT(~0) | UTMIP_PLLU_STABLE_COUNT(~0));
+ val |= UTMIP_PLL_ACTIVE_DLY_COUNT(phy->freq->active_delay) |
+ UTMIP_PLLU_STABLE_COUNT(phy->freq->stable_count);
+ writel(val, base + UTMIP_MISC_CFG1);
+
+ val = readl(base + UTMIP_PLL_CFG1);
+ val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0));
+ val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) |
+ UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay);
+ writel(val, base + UTMIP_PLL_CFG1);
+
+ if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~(USB_WAKE_ON_CNNT_EN_DEV | USB_WAKE_ON_DISCON_EN_DEV);
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ utmip_pad_power_on(phy);
+
+ val = readl(base + UTMIP_XCVR_CFG0);
+ val &= ~(UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
+ UTMIP_FORCE_PDZI_POWERDOWN | UTMIP_XCVR_SETUP(~0) |
+ UTMIP_XCVR_LSFSLEW(~0) | UTMIP_XCVR_LSRSLEW(~0) |
+ UTMIP_XCVR_HSSLEW_MSB(~0));
+ val |= UTMIP_XCVR_SETUP(config->xcvr_setup);
+ val |= UTMIP_XCVR_LSFSLEW(config->xcvr_lsfslew);
+ val |= UTMIP_XCVR_LSRSLEW(config->xcvr_lsrslew);
+ writel(val, base + UTMIP_XCVR_CFG0);
+
+ val = readl(base + UTMIP_XCVR_CFG1);
+ val &= ~(UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
+ UTMIP_FORCE_PDDR_POWERDOWN | UTMIP_XCVR_TERM_RANGE_ADJ(~0));
+ val |= UTMIP_XCVR_TERM_RANGE_ADJ(config->term_range_adj);
+ writel(val, base + UTMIP_XCVR_CFG1);
+
+ val = readl(base + UTMIP_BAT_CHRG_CFG0);
+ val &= ~UTMIP_PD_CHRG;
+ writel(val, base + UTMIP_BAT_CHRG_CFG0);
+
+ val = readl(base + UTMIP_BIAS_CFG1);
+ val &= ~UTMIP_BIAS_PDTRK_COUNT(~0);
+ val |= UTMIP_BIAS_PDTRK_COUNT(0x5);
+ writel(val, base + UTMIP_BIAS_CFG1);
+
+ if (phy->instance == 0) {
+ val = readl(base + UTMIP_SPARE_CFG0);
+ if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE)
+ val &= ~FUSE_SETUP_SEL;
+ else
+ val |= FUSE_SETUP_SEL;
+ writel(val, base + UTMIP_SPARE_CFG0);
+ }
+
+ if (phy->instance == 2) {
+ val = readl(base + USB_SUSP_CTRL);
+ val |= UTMIP_PHY_ENABLE;
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~UTMIP_RESET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ if (phy->instance == 0) {
+ val = readl(base + USB1_LEGACY_CTRL);
+ val &= ~USB1_VBUS_SENSE_CTL_MASK;
+ val |= USB1_VBUS_SENSE_CTL_A_SESS_VLD;
+ writel(val, base + USB1_LEGACY_CTRL);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~USB_SUSP_SET;
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ utmi_phy_clk_enable(phy);
+
+ if (phy->instance == 2) {
+ val = readl(base + USB_PORTSC1);
+ val &= ~USB_PORTSC1_PTS(~0);
+ writel(val, base + USB_PORTSC1);
+ }
+
+ return 0;
+}
+
+static void utmi_phy_power_off(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ utmi_phy_clk_disable(phy);
+
+ if (phy->mode == TEGRA_USB_PHY_MODE_DEVICE) {
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~USB_WAKEUP_DEBOUNCE_COUNT(~0);
+ val |= USB_WAKE_ON_CNNT_EN_DEV | USB_WAKEUP_DEBOUNCE_COUNT(5);
+ writel(val, base + USB_SUSP_CTRL);
+ }
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= UTMIP_RESET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ val = readl(base + UTMIP_BAT_CHRG_CFG0);
+ val |= UTMIP_PD_CHRG;
+ writel(val, base + UTMIP_BAT_CHRG_CFG0);
+
+ val = readl(base + UTMIP_XCVR_CFG0);
+ val |= UTMIP_FORCE_PD_POWERDOWN | UTMIP_FORCE_PD2_POWERDOWN |
+ UTMIP_FORCE_PDZI_POWERDOWN;
+ writel(val, base + UTMIP_XCVR_CFG0);
+
+ val = readl(base + UTMIP_XCVR_CFG1);
+ val |= UTMIP_FORCE_PDDISC_POWERDOWN | UTMIP_FORCE_PDCHRP_POWERDOWN |
+ UTMIP_FORCE_PDDR_POWERDOWN;
+ writel(val, base + UTMIP_XCVR_CFG1);
+
+ utmip_pad_power_off(phy);
+}
+
+static void utmi_phy_preresume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ val = readl(base + UTMIP_TX_CFG0);
+ val |= UTMIP_HS_DISCON_DISABLE;
+ writel(val, base + UTMIP_TX_CFG0);
+}
+
+static void utmi_phy_postresume(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ val = readl(base + UTMIP_TX_CFG0);
+ val &= ~UTMIP_HS_DISCON_DISABLE;
+ writel(val, base + UTMIP_TX_CFG0);
+}
+
+static void utmi_phy_restore_start(struct tegra_usb_phy *phy,
+ enum tegra_usb_phy_port_speed port_speed)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ val = readl(base + UTMIP_MISC_CFG0);
+ val &= ~UTMIP_DPDM_OBSERVE_SEL(~0);
+ if (port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW)
+ val |= UTMIP_DPDM_OBSERVE_SEL_FS_K;
+ else
+ val |= UTMIP_DPDM_OBSERVE_SEL_FS_J;
+ writel(val, base + UTMIP_MISC_CFG0);
+ udelay(1);
+
+ val = readl(base + UTMIP_MISC_CFG0);
+ val |= UTMIP_DPDM_OBSERVE;
+ writel(val, base + UTMIP_MISC_CFG0);
+ udelay(10);
+}
+
+static void utmi_phy_restore_end(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+
+ val = readl(base + UTMIP_MISC_CFG0);
+ val &= ~UTMIP_DPDM_OBSERVE;
+ writel(val, base + UTMIP_MISC_CFG0);
+ udelay(10);
+}
+
+static int ulpi_phy_power_on(struct tegra_usb_phy *phy)
+{
+ int ret;
+ unsigned long val;
+ void __iomem *base = phy->regs;
+ struct tegra_ulpi_config *config = phy->config;
+
+ gpio_direction_output(config->reset_gpio, 0);
+ msleep(5);
+ gpio_direction_output(config->reset_gpio, 1);
+
+ clk_enable(phy->clk);
+ msleep(1);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= UHSIC_RESET;
+ writel(val, base + USB_SUSP_CTRL);
+
+ val = readl(base + ULPI_TIMING_CTRL_0);
+ val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
+ writel(val, base + ULPI_TIMING_CTRL_0);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= ULPI_PHY_ENABLE;
+ writel(val, base + USB_SUSP_CTRL);
+
+ val = 0;
+ writel(val, base + ULPI_TIMING_CTRL_1);
+
+ val |= ULPI_DATA_TRIMMER_SEL(4);
+ val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
+ val |= ULPI_DIR_TRIMMER_SEL(4);
+ writel(val, base + ULPI_TIMING_CTRL_1);
+ udelay(10);
+
+ val |= ULPI_DATA_TRIMMER_LOAD;
+ val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
+ val |= ULPI_DIR_TRIMMER_LOAD;
+ writel(val, base + ULPI_TIMING_CTRL_1);
+
+ /* Fix VbusInvalid due to floating VBUS */
+ ret = otg_io_write(phy->ulpi, 0x40, 0x08);
+ if (ret) {
+ pr_err("%s: ulpi write failed\n", __func__);
+ return ret;
+ }
+
+ ret = otg_io_write(phy->ulpi, 0x80, 0x0B);
+ if (ret) {
+ pr_err("%s: ulpi write failed\n", __func__);
+ return ret;
+ }
+
+ val = readl(base + USB_PORTSC1);
+ val |= USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN;
+ writel(val, base + USB_PORTSC1);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val |= USB_SUSP_CLR;
+ writel(val, base + USB_SUSP_CTRL);
+ udelay(100);
+
+ val = readl(base + USB_SUSP_CTRL);
+ val &= ~USB_SUSP_CLR;
+ writel(val, base + USB_SUSP_CTRL);
+
+ return 0;
+}
+
+static void ulpi_phy_power_off(struct tegra_usb_phy *phy)
+{
+ unsigned long val;
+ void __iomem *base = phy->regs;
+ struct tegra_ulpi_config *config = phy->config;
+
+ /* Clear WKCN/WKDS/WKOC wake-on events that can cause the USB
+ * Controller to immediately bring the ULPI PHY out of low power
+ */
+ val = readl(base + USB_PORTSC1);
+ val &= ~(USB_PORTSC1_WKOC | USB_PORTSC1_WKDS | USB_PORTSC1_WKCN);
+ writel(val, base + USB_PORTSC1);
+
+ gpio_direction_output(config->reset_gpio, 0);
+ clk_disable(phy->clk);
+}
+
+struct tegra_usb_phy *tegra_usb_phy_open(int instance, void __iomem *regs,
+ void *config, enum tegra_usb_phy_mode phy_mode)
+{
+ struct tegra_usb_phy *phy;
+ struct tegra_ulpi_config *ulpi_config;
+ unsigned long parent_rate;
+ int i;
+ int err;
+
+ phy = kmalloc(sizeof(struct tegra_usb_phy), GFP_KERNEL);
+ if (!phy)
+ return ERR_PTR(-ENOMEM);
+
+ phy->instance = instance;
+ phy->regs = regs;
+ phy->config = config;
+ phy->mode = phy_mode;
+
+ if (!phy->config) {
+ if (phy_is_ulpi(phy)) {
+ pr_err("%s: ulpi phy configuration missing", __func__);
+ err = -EINVAL;
+ goto err0;
+ } else {
+ phy->config = &utmip_default[instance];
+ }
+ }
+
+ phy->pll_u = clk_get_sys(NULL, "pll_u");
+ if (IS_ERR(phy->pll_u)) {
+ pr_err("Can't get pll_u clock\n");
+ err = PTR_ERR(phy->pll_u);
+ goto err0;
+ }
+ clk_enable(phy->pll_u);
+
+ parent_rate = clk_get_rate(clk_get_parent(phy->pll_u));
+ for (i = 0; i < ARRAY_SIZE(tegra_freq_table); i++) {
+ if (tegra_freq_table[i].freq == parent_rate) {
+ phy->freq = &tegra_freq_table[i];
+ break;
+ }
+ }
+ if (!phy->freq) {
+ pr_err("invalid pll_u parent rate %ld\n", parent_rate);
+ err = -EINVAL;
+ goto err1;
+ }
+
+ if (phy_is_ulpi(phy)) {
+ ulpi_config = config;
+ phy->clk = clk_get_sys(NULL, ulpi_config->clk);
+ if (IS_ERR(phy->clk)) {
+ pr_err("%s: can't get ulpi clock\n", __func__);
+ err = -ENXIO;
+ goto err1;
+ }
+ tegra_gpio_enable(ulpi_config->reset_gpio);
+ gpio_request(ulpi_config->reset_gpio, "ulpi_phy_reset_b");
+ gpio_direction_output(ulpi_config->reset_gpio, 0);
+ phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
+ phy->ulpi->io_priv = regs + ULPI_VIEWPORT;
+ } else {
+ err = utmip_pad_open(phy);
+ if (err < 0)
+ goto err1;
+ }
+
+ return phy;
+
+err1:
+ clk_disable(phy->pll_u);
+ clk_put(phy->pll_u);
+err0:
+ kfree(phy);
+ return ERR_PTR(err);
+}
+
+int tegra_usb_phy_power_on(struct tegra_usb_phy *phy)
+{
+ if (phy_is_ulpi(phy))
+ return ulpi_phy_power_on(phy);
+ else
+ return utmi_phy_power_on(phy);
+}
+
+void tegra_usb_phy_power_off(struct tegra_usb_phy *phy)
+{
+ if (phy_is_ulpi(phy))
+ ulpi_phy_power_off(phy);
+ else
+ utmi_phy_power_off(phy);
+}
+
+void tegra_usb_phy_preresume(struct tegra_usb_phy *phy)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_preresume(phy);
+}
+
+void tegra_usb_phy_postresume(struct tegra_usb_phy *phy)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_postresume(phy);
+}
+
+void tegra_ehci_phy_restore_start(struct tegra_usb_phy *phy,
+ enum tegra_usb_phy_port_speed port_speed)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_restore_start(phy, port_speed);
+}
+
+void tegra_ehci_phy_restore_end(struct tegra_usb_phy *phy)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_restore_end(phy);
+}
+
+void tegra_usb_phy_clk_disable(struct tegra_usb_phy *phy)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_clk_disable(phy);
+}
+
+void tegra_usb_phy_clk_enable(struct tegra_usb_phy *phy)
+{
+ if (!phy_is_ulpi(phy))
+ utmi_phy_clk_enable(phy);
+}
+
+void tegra_usb_phy_close(struct tegra_usb_phy *phy)
+{
+ if (phy_is_ulpi(phy))
+ clk_put(phy->clk);
+ else
+ utmip_pad_close(phy);
+ clk_disable(phy->pll_u);
+ clk_put(phy->pll_u);
+ kfree(phy);
+}
diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig
new file mode 100644
index 00000000..32a7b0f7
--- /dev/null
+++ b/arch/arm/mach-u300/Kconfig
@@ -0,0 +1,117 @@
+if ARCH_U300
+
+menu "ST-Ericsson AB U300/U330/U335/U365 Platform"
+
+comment "ST-Ericsson Mobile Platform Products"
+
+config MACH_U300
+ bool "U300"
+
+comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"
+
+choice
+ prompt "U300/U330/U335/U365 system type"
+ default MACH_U300_BS2X
+ ---help---
+ You need to select the target system, i.e. the
+ U300/U330/U335/U365 board that you want to compile your kernel
+ for.
+
+config MACH_U300_BS2X
+ bool "S26/S26/B25/B26 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S26/S25 test products. (Also works on
+ B26/B25 big boards.)
+
+config MACH_U300_BS330
+ bool "S330/B330 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S330/B330 test products.
+
+config MACH_U300_BS335
+ bool "S335/B335 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S335/B335 test products.
+
+config MACH_U300_BS365
+ bool "S365/B365 Test Products"
+ depends on MACH_U300
+ help
+ Select this if you're developing on the
+ S365/B365 test products.
+
+endchoice
+
+choice
+ prompt "Memory configuration"
+ default MACH_U300_SINGLE_RAM
+ ---help---
+ You have to config the kernel according to the physical memory
+ configuration.
+
+config MACH_U300_SINGLE_RAM
+ bool "Single RAM"
+ help
+ Select this if you want support for Single RAM phones.
+
+config MACH_U300_DUAL_RAM
+ bool "Dual RAM"
+ help
+ Select this if you want support for Dual RAM phones.
+ This is two RAM memories on different EMIFs.
+endchoice
+
+config U300_DEBUG
+ bool "Debug support for U300"
+ depends on PM
+ help
+ Debug support for U300 in sysfs, procfs etc.
+
+config MACH_U300_SEMI_IS_SHARED
+ bool "The SEMI is used by both the access and application side"
+ depends on MACH_U300
+ help
+ This makes it possible to use the SEMI (Shared External
+ Memory Interface) from both from access and application
+ side.
+
+config MACH_U300_SPIDUMMY
+ bool "SSP/SPI dummy chip"
+ select SPI
+ select SPI_MASTER
+ select SPI_PL022
+ help
+ This creates a small kernel module that creates a dummy
+ SPI device to be used for loopback tests. Regularly used
+ to test reference designs. If you're not testing SPI,
+ you don't need it. Selecting this will activate the
+ SPI framework and ARM PL022 support.
+
+comment "All the settings below must match the bootloader's settings"
+
+config MACH_U300_ACCESS_MEM_SIZE
+ int "Access CPU memory allocation"
+ range 7 25
+ depends on MACH_U300_SINGLE_RAM
+ default 13
+ help
+ How much memory in MiB that the Access side CPU has allocated
+
+config MACH_U300_2MB_ALIGNMENT_FIX
+ bool "2MiB alignment fix"
+ depends on MACH_U300_SINGLE_RAM
+ default y
+ help
+ If yes and the Access side CPU has allocated an odd size in
+ MiB, this fix gives you one MiB extra that would otherwise be
+ lost due to Linux 2 MiB alignment policy.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile
new file mode 100644
index 00000000..8fd354aa
--- /dev/null
+++ b/arch/arm/mach-u300/Makefile
@@ -0,0 +1,15 @@
+#
+# Makefile for the linux kernel, U300 machine.
+#
+
+obj-y := core.o clock.o timer.o padmux.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_ARCH_U300) += u300.o
+obj-$(CONFIG_MMC) += mmc.o
+obj-$(CONFIG_SPI_PL022) += spi.o
+obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o
+obj-$(CONFIG_I2C_STU300) += i2c.o
+obj-$(CONFIG_REGULATOR_AB3100) += regulator.o
diff --git a/arch/arm/mach-u300/Makefile.boot b/arch/arm/mach-u300/Makefile.boot
new file mode 100644
index 00000000..6fbfc6ea
--- /dev/null
+++ b/arch/arm/mach-u300/Makefile.boot
@@ -0,0 +1,15 @@
+# Note: the following conditions must always be true:
+# ZRELADDR == virt_to_phys(TEXTADDR)
+# PARAMS_PHYS must be within 4MB of ZRELADDR
+# INITRD_PHYS must be in RAM
+
+ifdef CONFIG_MACH_U300_SINGLE_RAM
+ zreladdr-y := 0x28E08000
+ params_phys-y := 0x28E00100
+else
+ zreladdr-y := 0x48008000
+ params_phys-y := 0x48000100
+endif
+
+# This isn't used.
+#initrd_phys-y := 0x29800000
diff --git a/arch/arm/mach-u300/clock.c b/arch/arm/mach-u300/clock.c
new file mode 100644
index 00000000..5535dd0a
--- /dev/null
+++ b/arch/arm/mach-u300/clock.c
@@ -0,0 +1,1504 @@
+/*
+ *
+ * arch/arm/mach-u300/clock.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Define clocks in the app platform.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <linux/seq_file.h>
+#include <linux/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+
+#include "clock.h"
+
+/*
+ * TODO:
+ * - move all handling of the CCR register into this file and create
+ * a spinlock for the CCR register
+ * - switch to the clkdevice lookup mechanism that maps clocks to
+ * device ID:s instead when it becomes available in kernel 2.6.29.
+ * - implement rate get/set for all clocks that need it.
+ */
+
+/*
+ * Syscon clock I/O registers lock so clock requests don't collide
+ * NOTE: this is a local lock only used to lock access to clock and
+ * reset registers in syscon.
+ */
+static DEFINE_SPINLOCK(syscon_clkreg_lock);
+static DEFINE_SPINLOCK(syscon_resetreg_lock);
+
+/*
+ * The clocking hierarchy currently looks like this.
+ * NOTE: the idea is NOT to show how the clocks are routed on the chip!
+ * The ideas is to show dependencies, so a clock higher up in the
+ * hierarchy has to be on in order for another clock to be on. Now,
+ * both CPU and DMA can actually be on top of the hierarchy, and that
+ * is not modeled currently. Instead we have the backbone AMBA bus on
+ * top. This bus cannot be programmed in any way but conceptually it
+ * needs to be active for the bridges and devices to transport data.
+ *
+ * Please be aware that a few clocks are hw controlled, which mean that
+ * the hw itself can turn on/off or change the rate of the clock when
+ * needed!
+ *
+ * AMBA bus
+ * |
+ * +- CPU
+ * +- FSMC NANDIF NAND Flash interface
+ * +- SEMI Shared Memory interface
+ * +- ISP Image Signal Processor (U335 only)
+ * +- CDS (U335 only)
+ * +- DMA Direct Memory Access Controller
+ * +- AAIF APP/ACC Inteface (Mobile Scalable Link, MSL)
+ * +- APEX
+ * +- VIDEO_ENC AVE2/3 Video Encoder
+ * +- XGAM Graphics Accelerator Controller
+ * +- AHB
+ * |
+ * +- ahb:0 AHB Bridge
+ * | |
+ * | +- ahb:1 INTCON Interrupt controller
+ * | +- ahb:3 MSPRO Memory Stick Pro controller
+ * | +- ahb:4 EMIF External Memory interface
+ * |
+ * +- fast:0 FAST bridge
+ * | |
+ * | +- fast:1 MMCSD MMC/SD card reader controller
+ * | +- fast:2 I2S0 PCM I2S channel 0 controller
+ * | +- fast:3 I2S1 PCM I2S channel 1 controller
+ * | +- fast:4 I2C0 I2C channel 0 controller
+ * | +- fast:5 I2C1 I2C channel 1 controller
+ * | +- fast:6 SPI SPI controller
+ * | +- fast:7 UART1 Secondary UART (U335 only)
+ * |
+ * +- slow:0 SLOW bridge
+ * |
+ * +- slow:1 SYSCON (not possible to control)
+ * +- slow:2 WDOG Watchdog
+ * +- slow:3 UART0 primary UART
+ * +- slow:4 TIMER_APP Application timer - used in Linux
+ * +- slow:5 KEYPAD controller
+ * +- slow:6 GPIO controller
+ * +- slow:7 RTC controller
+ * +- slow:8 BT Bus Tracer (not used currently)
+ * +- slow:9 EH Event Handler (not used currently)
+ * +- slow:a TIMER_ACC Access style timer (not used currently)
+ * +- slow:b PPM (U335 only, what is that?)
+ */
+
+/*
+ * Reset control functions. We remember if a block has been
+ * taken out of reset and don't remove the reset assertion again
+ * and vice versa. Currently we only remove resets so the
+ * enablement function is defined out.
+ */
+static void syscon_block_reset_enable(struct clk *clk)
+{
+ u16 val;
+ unsigned long iflags;
+
+ /* Not all blocks support resetting */
+ if (!clk->res_reg || !clk->res_mask)
+ return;
+ spin_lock_irqsave(&syscon_resetreg_lock, iflags);
+ val = readw(clk->res_reg);
+ val |= clk->res_mask;
+ writew(val, clk->res_reg);
+ spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
+ clk->reset = true;
+}
+
+static void syscon_block_reset_disable(struct clk *clk)
+{
+ u16 val;
+ unsigned long iflags;
+
+ /* Not all blocks support resetting */
+ if (!clk->res_reg || !clk->res_mask)
+ return;
+ spin_lock_irqsave(&syscon_resetreg_lock, iflags);
+ val = readw(clk->res_reg);
+ val &= ~clk->res_mask;
+ writew(val, clk->res_reg);
+ spin_unlock_irqrestore(&syscon_resetreg_lock, iflags);
+ clk->reset = false;
+}
+
+int __clk_get(struct clk *clk)
+{
+ u16 val;
+
+ /* The MMC and MSPRO clocks need some special set-up */
+ if (!strcmp(clk->name, "MCLK")) {
+ /* Set default MMC clock divisor to 18.9 MHz */
+ writew(0x0054U, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ /* Disable the MMC feedback clock */
+ val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
+ /* Disable MSPRO frequency */
+ val &= ~U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ }
+ if (!strcmp(clk->name, "MSPRO")) {
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ /* Disable the MMC feedback clock */
+ val &= ~U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE;
+ /* Enable MSPRO frequency */
+ val |= U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_MMCR);
+ }
+ return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
+
+static void syscon_clk_disable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ /* Don't touch the hardware controlled clocks */
+ if (clk->hw_ctrld)
+ return;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCDR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void syscon_clk_enable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ /* Don't touch the hardware controlled clocks */
+ if (clk->hw_ctrld)
+ return;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ writew(clk->clk_val, U300_SYSCON_VBASE + U300_SYSCON_SBCER);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static u16 syscon_clk_get_rate(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+ return val;
+}
+
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+static void enable_i2s0_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Set I2S0 to use the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_I2S0_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val |= U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void enable_i2s1_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Set I2S1 to use the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val |= U300_SYSCON_CCR_I2S1_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val |= U300_SYSCON_CEFR_I2S1_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void disable_i2s0_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Disable I2S0 use of the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_I2S0_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Deactivate VCXO if no one else is using VCXO */
+ if (!(val & U300_SYSCON_CCR_I2S1_USE_VCXO))
+ val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+static void disable_i2s1_vcxo(void)
+{
+ u16 val;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ /* Disable I2S1 use of the VCXO 26 MHz clock */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_I2S1_USE_VCXO;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Deactivate VCXO if no one else is using VCXO */
+ if (!(val & U300_SYSCON_CCR_I2S0_USE_VCXO))
+ val &= ~U300_SYSCON_CCR_TURN_VCXO_ON;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ val &= ~U300_SYSCON_CEFR_I2S0_CLK_EN;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CEFR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+#endif /* CONFIG_MACH_U300_USE_I2S_AS_MASTER */
+
+
+static void syscon_clk_rate_set_mclk(unsigned long rate)
+{
+ u16 val;
+ u32 reg;
+ unsigned long iflags;
+
+ switch (rate) {
+ case 18900000:
+ val = 0x0054;
+ break;
+ case 20800000:
+ val = 0x0044;
+ break;
+ case 23100000:
+ val = 0x0043;
+ break;
+ case 26000000:
+ val = 0x0033;
+ break;
+ case 29700000:
+ val = 0x0032;
+ break;
+ case 34700000:
+ val = 0x0022;
+ break;
+ case 41600000:
+ val = 0x0021;
+ break;
+ case 52000000:
+ val = 0x0011;
+ break;
+ case 104000000:
+ val = 0x0000;
+ break;
+ default:
+ printk(KERN_ERR "Trying to set MCLK to unknown speed! %ld\n",
+ rate);
+ return;
+ }
+
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ reg = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
+ ~U300_SYSCON_MMF0R_MASK;
+ writew(reg | val, U300_SYSCON_VBASE + U300_SYSCON_MMF0R);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+
+void syscon_clk_rate_set_cpuclk(unsigned long rate)
+{
+ u16 val;
+ unsigned long iflags;
+
+ switch (rate) {
+ case 13000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER;
+ break;
+ case 52000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE;
+ break;
+ case 104000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH;
+ break;
+ case 208000000:
+ val = U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST;
+ break;
+ default:
+ return;
+ }
+ spin_lock_irqsave(&syscon_clkreg_lock, iflags);
+ val |= readw(U300_SYSCON_VBASE + U300_SYSCON_CCR) &
+ ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK ;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ spin_unlock_irqrestore(&syscon_clkreg_lock, iflags);
+}
+EXPORT_SYMBOL(syscon_clk_rate_set_cpuclk);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long iflags;
+
+ spin_lock_irqsave(&clk->lock, iflags);
+ if (clk->usecount > 0 && !(--clk->usecount)) {
+ /* some blocks lack clocking registers and cannot be disabled */
+ if (clk->disable)
+ clk->disable(clk);
+ if (likely((u32)clk->parent))
+ clk_disable(clk->parent);
+ }
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+ if (unlikely(!strcmp(clk->name, "I2S0")))
+ disable_i2s0_vcxo();
+ if (unlikely(!strcmp(clk->name, "I2S1")))
+ disable_i2s1_vcxo();
+#endif
+ spin_unlock_irqrestore(&clk->lock, iflags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+ unsigned long iflags;
+
+ spin_lock_irqsave(&clk->lock, iflags);
+ if (clk->usecount++ == 0) {
+ if (likely((u32)clk->parent))
+ ret = clk_enable(clk->parent);
+
+ if (unlikely(ret != 0))
+ clk->usecount--;
+ else {
+ /* remove reset line (we never enable reset again) */
+ syscon_block_reset_disable(clk);
+ /* clocks without enable function are always on */
+ if (clk->enable)
+ clk->enable(clk);
+#ifdef CONFIG_MACH_U300_USE_I2S_AS_MASTER
+ if (unlikely(!strcmp(clk->name, "I2S0")))
+ enable_i2s0_vcxo();
+ if (unlikely(!strcmp(clk->name, "I2S1")))
+ enable_i2s1_vcxo();
+#endif
+ }
+ }
+ spin_unlock_irqrestore(&clk->lock, iflags);
+ return ret;
+
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* Returns the clock rate in Hz */
+static unsigned long clk_get_rate_cpuclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 52000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ return 104000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 208000000;
+ default:
+ break;
+ }
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_ahb_clk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 6500000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 26000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 52000000;
+ default:
+ break;
+ }
+ return clk->rate;
+
+}
+
+static unsigned long clk_get_rate_emif_clk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 52000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 104000000;
+ default:
+ break;
+ }
+ return clk->rate;
+
+}
+
+static unsigned long clk_get_rate_xgamclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 6500000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ return 26000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 52000000;
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_mclk(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ /*
+ * Here, the 208 MHz PLL gets shut down and the always
+ * on 13 MHz PLL used for RTC etc kicks into use
+ * instead.
+ */
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ {
+ /*
+ * This clock is under program control. The register is
+ * divided in two nybbles, bit 7-4 gives cycles-1 to count
+ * high, bit 3-0 gives cycles-1 to count low. Distribute
+ * these with no more than 1 cycle difference between
+ * low and high and add low and high to get the actual
+ * divisor. The base PLL is 208 MHz. Writing 0x00 will
+ * divide by 1 and 1 so the highest frequency possible
+ * is 104 MHz.
+ *
+ * e.g. 0x54 =>
+ * f = 208 / ((5+1) + (4+1)) = 208 / 11 = 18.9 MHz
+ */
+ u16 val = readw(U300_SYSCON_VBASE + U300_SYSCON_MMF0R) &
+ U300_SYSCON_MMF0R_MASK;
+ switch (val) {
+ case 0x0054:
+ return 18900000;
+ case 0x0044:
+ return 20800000;
+ case 0x0043:
+ return 23100000;
+ case 0x0033:
+ return 26000000;
+ case 0x0032:
+ return 29700000;
+ case 0x0022:
+ return 34700000;
+ case 0x0021:
+ return 41600000;
+ case 0x0011:
+ return 52000000;
+ case 0x0000:
+ return 104000000;
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+static unsigned long clk_get_rate_i2s_i2c_spi(struct clk *clk)
+{
+ u16 val;
+
+ val = syscon_clk_get_rate();
+
+ switch (val) {
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW:
+ return 13000000;
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH:
+ case U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST:
+ return 26000000;
+ default:
+ break;
+ }
+
+ return clk->rate;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+ else
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static unsigned long clk_round_rate_mclk(struct clk *clk, unsigned long rate)
+{
+ if (rate <= 18900000)
+ return 18900000;
+ if (rate <= 20800000)
+ return 20800000;
+ if (rate <= 23100000)
+ return 23100000;
+ if (rate <= 26000000)
+ return 26000000;
+ if (rate <= 29700000)
+ return 29700000;
+ if (rate <= 34700000)
+ return 34700000;
+ if (rate <= 41600000)
+ return 41600000;
+ if (rate <= 52000000)
+ return 52000000;
+ return -EINVAL;
+}
+
+static unsigned long clk_round_rate_cpuclk(struct clk *clk, unsigned long rate)
+{
+ if (rate <= 13000000)
+ return 13000000;
+ if (rate <= 52000000)
+ return 52000000;
+ if (rate <= 104000000)
+ return 104000000;
+ if (rate <= 208000000)
+ return 208000000;
+ return -EINVAL;
+}
+
+/*
+ * This adjusts a requested rate to the closest exact rate
+ * a certain clock can provide. For a fixed clock it's
+ * mostly clk->rate.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ /* TODO: get appropriate switches for EMIFCLK, AHBCLK and MCLK */
+ /* Else default to fixed value */
+
+ if (clk->round_rate) {
+ return (long) clk->round_rate(clk, rate);
+ } else {
+ printk(KERN_ERR "clock: Failed to round rate of %s\n",
+ clk->name);
+ }
+ return (long) clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+static int clk_set_rate_mclk(struct clk *clk, unsigned long rate)
+{
+ syscon_clk_rate_set_mclk(clk_round_rate(clk, rate));
+ return 0;
+}
+
+static int clk_set_rate_cpuclk(struct clk *clk, unsigned long rate)
+{
+ syscon_clk_rate_set_cpuclk(clk_round_rate(clk, rate));
+ return 0;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ /* TODO: set for EMIFCLK and AHBCLK */
+ /* Else assume the clock is fixed and fail */
+ if (clk->set_rate) {
+ return clk->set_rate(clk, rate);
+ } else {
+ printk(KERN_ERR "clock: Failed to set %s to %ld hz\n",
+ clk->name, rate);
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/*
+ * Clock definitions. The clock parents are set to respective
+ * bridge and the clock framework makes sure that the clocks have
+ * parents activated and are brought out of reset when in use.
+ *
+ * Clocks that have hw_ctrld = true are hw controlled, and the hw
+ * can by itself turn these clocks on and off.
+ * So in other words, we don't really have to care about them.
+ */
+
+static struct clk amba_clk = {
+ .name = "AMBA",
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = false,
+ .lock = __SPIN_LOCK_UNLOCKED(amba_clk.lock),
+};
+
+/*
+ * These blocks are connected directly to the AMBA bus
+ * with no bridge.
+ */
+
+static struct clk cpu_clk = {
+ .name = "CPU",
+ .parent = &amba_clk,
+ .rate = 208000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_CPU_RESET_EN,
+ .set_rate = clk_set_rate_cpuclk,
+ .get_rate = clk_get_rate_cpuclk,
+ .round_rate = clk_round_rate_cpuclk,
+ .lock = __SPIN_LOCK_UNLOCKED(cpu_clk.lock),
+};
+
+static struct clk nandif_clk = {
+ .name = "FSMC",
+ .parent = &amba_clk,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_NANDIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_NANDIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(nandif_clk.lock),
+};
+
+static struct clk semi_clk = {
+ .name = "SEMI",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ /* It is not possible to reset SEMI */
+ .hw_ctrld = false,
+ .reset = false,
+ .clk_val = U300_SYSCON_SBCER_SEMI_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(semi_clk.lock),
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk isp_clk = {
+ .name = "ISP",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_ISP_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_ISP_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(isp_clk.lock),
+};
+
+static struct clk cds_clk = {
+ .name = "CDS",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_CDS_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_CDS_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(cds_clk.lock),
+};
+#endif
+
+static struct clk dma_clk = {
+ .name = "DMA",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_DMAC_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_DMAC_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(dma_clk.lock),
+};
+
+static struct clk aaif_clk = {
+ .name = "AAIF",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_AAIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_AAIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(aaif_clk.lock),
+};
+
+static struct clk apex_clk = {
+ .name = "APEX",
+ .parent = &amba_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_APEX_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_APEX_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(apex_clk.lock),
+};
+
+static struct clk video_enc_clk = {
+ .name = "VIDEO_ENC",
+ .parent = &amba_clk,
+ .rate = 208000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = false,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ /* This has XGAM in the name but refers to the video encoder */
+ .res_mask = U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(video_enc_clk.lock),
+};
+
+static struct clk xgam_clk = {
+ .name = "XGAMCLK",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_XGAM_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_XGAM_CLK_EN,
+ .get_rate = clk_get_rate_xgamclk,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(xgam_clk.lock),
+};
+
+/* This clock is used to activate the video encoder */
+static struct clk ahb_clk = {
+ .name = "AHB",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false, /* This one is set to false due to HW bug */
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_AHB_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_AHB_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_ahb_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(ahb_clk.lock),
+};
+
+
+/*
+ * Clocks on the AHB bridge
+ */
+
+static struct clk ahb_subsys_clk = {
+ .name = "AHB_SUBSYS",
+ .parent = &amba_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = false,
+ .clk_val = U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_ahb_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(ahb_subsys_clk.lock),
+};
+
+static struct clk intcon_clk = {
+ .name = "INTCON",
+ .parent = &ahb_subsys_clk,
+ .rate = 52000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_INTCON_RESET_EN,
+ /* INTCON can be reset but not clock-gated */
+ .lock = __SPIN_LOCK_UNLOCKED(intcon_clk.lock),
+
+};
+
+static struct clk mspro_clk = {
+ .name = "MSPRO",
+ .parent = &ahb_subsys_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_MSPRO_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_MSPRO_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(mspro_clk.lock),
+};
+
+static struct clk emif_clk = {
+ .name = "EMIF",
+ .parent = &ahb_subsys_clk,
+ .rate = 104000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RRR,
+ .res_mask = U300_SYSCON_RRR_EMIF_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_EMIF_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_emif_clk,
+ .lock = __SPIN_LOCK_UNLOCKED(emif_clk.lock),
+};
+
+
+/*
+ * Clocks on the FAST bridge
+ */
+static struct clk fast_clk = {
+ .name = "FAST_BRIDGE",
+ .parent = &amba_clk,
+ .rate = 13000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(fast_clk.lock),
+};
+
+/*
+ * The MMCI apb_pclk is hardwired to the same terminal as the
+ * external MCI clock. Thus this will be referenced twice.
+ */
+static struct clk mmcsd_clk = {
+ .name = "MCLK",
+ .parent = &fast_clk,
+ .rate = 18900000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_MMC_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_MMC_CLK_EN,
+ .get_rate = clk_get_rate_mclk,
+ .set_rate = clk_set_rate_mclk,
+ .round_rate = clk_round_rate_mclk,
+ .disable = syscon_clk_disable,
+ .enable = syscon_clk_enable,
+ .lock = __SPIN_LOCK_UNLOCKED(mmcsd_clk.lock),
+};
+
+static struct clk i2s0_clk = {
+ .name = "i2s0",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2S0_CORE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2s0_clk.lock),
+};
+
+static struct clk i2s1_clk = {
+ .name = "i2s1",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2S1_CORE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2s1_clk.lock),
+};
+
+static struct clk i2c0_clk = {
+ .name = "I2C0",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_I2C0_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2C0_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2c0_clk.lock),
+};
+
+static struct clk i2c1_clk = {
+ .name = "I2C1",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_I2C1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_I2C1_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(i2c1_clk.lock),
+};
+
+/*
+ * The SPI apb_pclk is hardwired to the same terminal as the
+ * external SPI clock. Thus this will be referenced twice.
+ */
+static struct clk spi_clk = {
+ .name = "SPI",
+ .parent = &fast_clk,
+ .rate = 26000000, /* this varies! */
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_SPI_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_SPI_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .get_rate = clk_get_rate_i2s_i2c_spi,
+ .lock = __SPIN_LOCK_UNLOCKED(spi_clk.lock),
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk uart1_pclk = {
+ .name = "UART1_PCLK",
+ .parent = &fast_clk,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RFR,
+ .res_mask = U300_SYSCON_RFR_UART1_RESET_ENABLE,
+ .clk_val = U300_SYSCON_SBCER_UART1_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(uart1_pclk.lock),
+};
+
+/* This one is hardwired to PLL13 */
+static struct clk uart1_clk = {
+ .name = "UART1_CLK",
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .lock = __SPIN_LOCK_UNLOCKED(uart1_clk.lock),
+};
+#endif
+
+
+/*
+ * Clocks on the SLOW bridge
+ */
+static struct clk slow_clk = {
+ .name = "SLOW_BRIDGE",
+ .parent = &amba_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(slow_clk.lock),
+};
+
+/* TODO: implement SYSCON clock? */
+
+static struct clk wdog_clk = {
+ .name = "WDOG",
+ .parent = &slow_clk,
+ .hw_ctrld = false,
+ .rate = 32768,
+ .reset = false,
+ /* This is always on, cannot be enabled/disabled or reset */
+ .lock = __SPIN_LOCK_UNLOCKED(wdog_clk.lock),
+};
+
+static struct clk uart0_pclk = {
+ .name = "UART0_PCLK",
+ .parent = &slow_clk,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_UART_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_UART_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(uart0_pclk.lock),
+};
+
+/* This one is hardwired to PLL13 */
+static struct clk uart0_clk = {
+ .name = "UART0_CLK",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .lock = __SPIN_LOCK_UNLOCKED(uart0_clk.lock),
+};
+
+static struct clk keypad_clk = {
+ .name = "KEYPAD",
+ .parent = &slow_clk,
+ .rate = 32768,
+ .hw_ctrld = false,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_KEYPAD_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_KEYPAD_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(keypad_clk.lock),
+};
+
+static struct clk gpio_clk = {
+ .name = "GPIO",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_GPIO_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_GPIO_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(gpio_clk.lock),
+};
+
+static struct clk rtc_clk = {
+ .name = "RTC",
+ .parent = &slow_clk,
+ .rate = 32768,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_RTC_RESET_EN,
+ /* This clock is always on, cannot be enabled/disabled */
+ .lock = __SPIN_LOCK_UNLOCKED(rtc_clk.lock),
+};
+
+static struct clk bustr_clk = {
+ .name = "BUSTR",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_BTR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_BTR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(bustr_clk.lock),
+};
+
+static struct clk evhist_clk = {
+ .name = "EVHIST",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_EH_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_EH_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(evhist_clk.lock),
+};
+
+static struct clk timer_clk = {
+ .name = "TIMER",
+ .parent = &slow_clk,
+ .rate = 13000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_ACC_TMR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_ACC_TMR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(timer_clk.lock),
+};
+
+/*
+ * There is a binary divider in the hardware that divides
+ * the 13MHz PLL by 13 down to 1 MHz.
+ */
+static struct clk app_timer_clk = {
+ .name = "TIMER_APP",
+ .parent = &slow_clk,
+ .rate = 1000000,
+ .hw_ctrld = true,
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_APP_TMR_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_APP_TMR_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(app_timer_clk.lock),
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+static struct clk ppm_clk = {
+ .name = "PPM",
+ .parent = &slow_clk,
+ .rate = 0, /* FIXME */
+ .hw_ctrld = true, /* TODO: Look up if it is hw ctrld or not */
+ .reset = true,
+ .res_reg = U300_SYSCON_VBASE + U300_SYSCON_RSR,
+ .res_mask = U300_SYSCON_RSR_PPM_RESET_EN,
+ .clk_val = U300_SYSCON_SBCER_PPM_CLK_EN,
+ .enable = syscon_clk_enable,
+ .disable = syscon_clk_disable,
+ .lock = __SPIN_LOCK_UNLOCKED(ppm_clk.lock),
+};
+#endif
+
+#define DEF_LOOKUP(devid, clkref) \
+ { \
+ .dev_id = devid, \
+ .clk = clkref, \
+ }
+
+#define DEF_LOOKUP_CON(devid, conid, clkref) \
+ { \
+ .dev_id = devid, \
+ .con_id = conid, \
+ .clk = clkref, \
+ }
+
+/*
+ * Here we only define clocks that are meaningful to
+ * look up through clockdevice.
+ */
+static struct clk_lookup lookups[] = {
+ /* Connected directly to the AMBA bus */
+ DEF_LOOKUP("amba", &amba_clk),
+ DEF_LOOKUP("cpu", &cpu_clk),
+ DEF_LOOKUP("fsmc-nand", &nandif_clk),
+ DEF_LOOKUP("semi", &semi_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("isp", &isp_clk),
+ DEF_LOOKUP("cds", &cds_clk),
+#endif
+ DEF_LOOKUP("dma", &dma_clk),
+ DEF_LOOKUP("msl", &aaif_clk),
+ DEF_LOOKUP("apex", &apex_clk),
+ DEF_LOOKUP("video_enc", &video_enc_clk),
+ DEF_LOOKUP("xgam", &xgam_clk),
+ DEF_LOOKUP("ahb", &ahb_clk),
+ /* AHB bridge clocks */
+ DEF_LOOKUP("ahb_subsys", &ahb_subsys_clk),
+ DEF_LOOKUP("intcon", &intcon_clk),
+ DEF_LOOKUP_CON("intcon", "apb_pclk", &intcon_clk),
+ DEF_LOOKUP("mspro", &mspro_clk),
+ DEF_LOOKUP("pl172", &emif_clk),
+ DEF_LOOKUP_CON("pl172", "apb_pclk", &emif_clk),
+ /* FAST bridge clocks */
+ DEF_LOOKUP("fast", &fast_clk),
+ DEF_LOOKUP("mmci", &mmcsd_clk),
+ DEF_LOOKUP_CON("mmci", "apb_pclk", &mmcsd_clk),
+ /*
+ * The .0 and .1 identifiers on these comes from the platform device
+ * .id field and are assigned when the platform devices are registered.
+ */
+ DEF_LOOKUP("i2s.0", &i2s0_clk),
+ DEF_LOOKUP("i2s.1", &i2s1_clk),
+ DEF_LOOKUP("stu300.0", &i2c0_clk),
+ DEF_LOOKUP("stu300.1", &i2c1_clk),
+ DEF_LOOKUP("pl022", &spi_clk),
+ DEF_LOOKUP_CON("pl022", "apb_pclk", &spi_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("uart1", &uart1_clk),
+ DEF_LOOKUP_CON("uart1", "apb_pclk", &uart1_pclk),
+#endif
+ /* SLOW bridge clocks */
+ DEF_LOOKUP("slow", &slow_clk),
+ DEF_LOOKUP("coh901327_wdog", &wdog_clk),
+ DEF_LOOKUP("uart0", &uart0_clk),
+ DEF_LOOKUP_CON("uart0", "apb_pclk", &uart0_pclk),
+ DEF_LOOKUP("apptimer", &app_timer_clk),
+ DEF_LOOKUP("coh901461-keypad", &keypad_clk),
+ DEF_LOOKUP("u300-gpio", &gpio_clk),
+ DEF_LOOKUP("rtc-coh901331", &rtc_clk),
+ DEF_LOOKUP("bustr", &bustr_clk),
+ DEF_LOOKUP("evhist", &evhist_clk),
+ DEF_LOOKUP("timer", &timer_clk),
+#ifdef CONFIG_MACH_U300_BS335
+ DEF_LOOKUP("ppm", &ppm_clk),
+#endif
+};
+
+static void __init clk_register(void)
+{
+ /* Register the lookups */
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
+
+#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
+/*
+ * The following makes it possible to view the status (especially
+ * reference count and reset status) for the clocks in the platform
+ * by looking into the special file <debugfs>/u300_clocks
+ */
+
+/* A list of all clocks in the platform */
+static struct clk *clks[] = {
+ /* Top node clock for the AMBA bus */
+ &amba_clk,
+ /* Connected directly to the AMBA bus */
+ &cpu_clk,
+ &nandif_clk,
+ &semi_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &isp_clk,
+ &cds_clk,
+#endif
+ &dma_clk,
+ &aaif_clk,
+ &apex_clk,
+ &video_enc_clk,
+ &xgam_clk,
+ &ahb_clk,
+
+ /* AHB bridge clocks */
+ &ahb_subsys_clk,
+ &intcon_clk,
+ &mspro_clk,
+ &emif_clk,
+ /* FAST bridge clocks */
+ &fast_clk,
+ &mmcsd_clk,
+ &i2s0_clk,
+ &i2s1_clk,
+ &i2c0_clk,
+ &i2c1_clk,
+ &spi_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &uart1_clk,
+ &uart1_pclk,
+#endif
+ /* SLOW bridge clocks */
+ &slow_clk,
+ &wdog_clk,
+ &uart0_clk,
+ &uart0_pclk,
+ &app_timer_clk,
+ &keypad_clk,
+ &gpio_clk,
+ &rtc_clk,
+ &bustr_clk,
+ &evhist_clk,
+ &timer_clk,
+#ifdef CONFIG_MACH_U300_BS335
+ &ppm_clk,
+#endif
+};
+
+static int u300_clocks_show(struct seq_file *s, void *data)
+{
+ struct clk *clk;
+ int i;
+
+ seq_printf(s, "CLOCK DEVICE RESET STATE\t" \
+ "ACTIVE\tUSERS\tHW CTRL FREQ\n");
+ seq_printf(s, "---------------------------------------------" \
+ "-----------------------------------------\n");
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ clk = clks[i];
+ if (clk != ERR_PTR(-ENOENT)) {
+ /* Format clock and device name nicely */
+ char cdp[33];
+ int chars;
+
+ chars = snprintf(&cdp[0], 17, "%s", clk->name);
+ while (chars < 16) {
+ cdp[chars] = ' ';
+ chars++;
+ }
+ chars = snprintf(&cdp[16], 17, "%s", clk->dev ?
+ dev_name(clk->dev) : "N/A");
+ while (chars < 16) {
+ cdp[chars+16] = ' ';
+ chars++;
+ }
+ cdp[32] = '\0';
+ if (clk->get_rate || clk->rate != 0)
+ seq_printf(s,
+ "%s%s\t%s\t%d\t%s\t%lu Hz\n",
+ &cdp[0],
+ clk->reset ?
+ "ASSERTED" : "RELEASED",
+ clk->usecount ? "ON" : "OFF",
+ clk->usecount,
+ clk->hw_ctrld ? "YES" : "NO ",
+ clk_get_rate(clk));
+ else
+ seq_printf(s,
+ "%s%s\t%s\t%d\t%s\t" \
+ "(unknown rate)\n",
+ &cdp[0],
+ clk->reset ?
+ "ASSERTED" : "RELEASED",
+ clk->usecount ? "ON" : "OFF",
+ clk->usecount,
+ clk->hw_ctrld ? "YES" : "NO ");
+ }
+ }
+ return 0;
+}
+
+static int u300_clocks_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, u300_clocks_show, NULL);
+}
+
+static const struct file_operations u300_clocks_operations = {
+ .open = u300_clocks_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init init_clk_read_debugfs(void)
+{
+ /* Expose a simple debugfs interface to view all clocks */
+ (void) debugfs_create_file("u300_clocks", S_IFREG | S_IRUGO,
+ NULL, NULL,
+ &u300_clocks_operations);
+ return 0;
+}
+/*
+ * This needs to come in after the core_initcall() for the
+ * overall clocks, because debugfs is not available until
+ * the subsystems come up.
+ */
+module_init(init_clk_read_debugfs);
+#endif
+
+int __init u300_clock_init(void)
+{
+ u16 val;
+
+ /*
+ * FIXME: shall all this powermanagement stuff really live here???
+ */
+
+ /* Set system to run at PLL208, max performance, a known state. */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Wait for the PLL208 to lock if not locked in yet */
+ while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
+ U300_SYSCON_CSR_PLL208_LOCK_IND));
+
+ /* Power management enable */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+ val |= U300_SYSCON_PMCR_PWR_MGNT_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+
+ clk_register();
+
+ /*
+ * Some of these may be on when we boot the system so make sure they
+ * are turned OFF.
+ */
+ syscon_block_reset_enable(&timer_clk);
+ timer_clk.disable(&timer_clk);
+
+ /*
+ * These shall be turned on by default when we boot the system
+ * so make sure they are ON. (Adding CPU here is a bit too much.)
+ * These clocks will be claimed by drivers later.
+ */
+ syscon_block_reset_disable(&semi_clk);
+ syscon_block_reset_disable(&emif_clk);
+ clk_enable(&semi_clk);
+ clk_enable(&emif_clk);
+
+ return 0;
+}
diff --git a/arch/arm/mach-u300/clock.h b/arch/arm/mach-u300/clock.h
new file mode 100644
index 00000000..4f50ca8f
--- /dev/null
+++ b/arch/arm/mach-u300/clock.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-u300/include/mach/clock.h
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * Adopted to ST-Ericsson U300 platforms by
+ * Jonas Aaberg <jonas.aberg@stericsson.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_CLOCK_H
+#define __MACH_CLOCK_H
+
+#include <linux/clk.h>
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ struct device *dev;
+ const char *name;
+ struct clk *parent;
+
+ spinlock_t lock;
+ unsigned long rate;
+ bool reset;
+ __u16 clk_val;
+ __s8 usecount;
+ void __iomem * res_reg;
+ __u16 res_mask;
+
+ bool hw_ctrld;
+
+ void (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *, unsigned long);
+ unsigned long (*get_rate) (struct clk *);
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ void (*init) (struct clk *);
+ void (*enable) (struct clk *);
+ void (*disable) (struct clk *);
+};
+
+int u300_clock_init(void);
+
+#endif
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
new file mode 100644
index 00000000..513d6abe
--- /dev/null
+++ b/arch/arm/mach-u300/core.c
@@ -0,0 +1,1861 @@
+/*
+ *
+ * arch/arm/mach-u300/core.c
+ *
+ *
+ * Copyright (C) 2007-2010 ST-Ericsson SA
+ * License terms: GNU General Public License (GPL) version 2
+ * Core platform support, IRQ handling and device definitions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/termios.h>
+#include <linux/dmaengine.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/fsmc.h>
+
+#include <asm/types.h>
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <mach/coh901318.h>
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+#include <mach/dma_channels.h>
+
+#include "clock.h"
+#include "mmc.h"
+#include "spi.h"
+#include "i2c.h"
+
+/*
+ * Static I/O mappings that are needed for booting the U300 platforms. The
+ * only things we need are the areas where we find the timer, syscon and
+ * intcon, since the remaining device drivers will map their own memory
+ * physical to virtual as the need arise.
+ */
+static struct map_desc u300_io_desc[] __initdata = {
+ {
+ .virtual = U300_SLOW_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_SLOW_PER_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_AHB_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_AHB_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = U300_FAST_PER_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_FAST_PER_PHYS_BASE),
+ .length = SZ_32K,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = 0xffff2000, /* TCM memory */
+ .pfn = __phys_to_pfn(0xffff2000),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ },
+
+ /*
+ * This overlaps with the IRQ vectors etc at 0xffff0000, so these
+ * may have to be moved to 0x00000000 in order to use the ROM.
+ */
+ /*
+ {
+ .virtual = U300_BOOTROM_VIRT_BASE,
+ .pfn = __phys_to_pfn(U300_BOOTROM_PHYS_BASE),
+ .length = SZ_64K,
+ .type = MT_ROM,
+ },
+ */
+};
+
+void __init u300_map_io(void)
+{
+ iotable_init(u300_io_desc, ARRAY_SIZE(u300_io_desc));
+}
+
+/*
+ * Declaration of devices found on the U300 board and
+ * their respective memory locations.
+ */
+
+static struct amba_pl011_data uart0_plat_data = {
+#ifdef CONFIG_COH901318
+ .dma_filter = coh901318_filter_id,
+ .dma_rx_param = (void *) U300_DMA_UART0_RX,
+ .dma_tx_param = (void *) U300_DMA_UART0_TX,
+#endif
+};
+
+static struct amba_device uart0_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "uart0", /* Slow device at 0x3000 offset */
+ .platform_data = &uart0_plat_data,
+ },
+ .res = {
+ .start = U300_UART0_BASE,
+ .end = U300_UART0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART0, NO_IRQ },
+};
+
+/* The U335 have an additional UART1 on the APP CPU */
+#ifdef CONFIG_MACH_U300_BS335
+static struct amba_pl011_data uart1_plat_data = {
+#ifdef CONFIG_COH901318
+ .dma_filter = coh901318_filter_id,
+ .dma_rx_param = (void *) U300_DMA_UART1_RX,
+ .dma_tx_param = (void *) U300_DMA_UART1_TX,
+#endif
+};
+
+static struct amba_device uart1_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "uart1", /* Fast device at 0x7000 offset */
+ .platform_data = &uart1_plat_data,
+ },
+ .res = {
+ .start = U300_UART1_BASE,
+ .end = U300_UART1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = { IRQ_U300_UART1, NO_IRQ },
+};
+#endif
+
+static struct amba_device pl172_device = {
+ .dev = {
+ .init_name = "pl172", /* AHB device at 0x4000 offset */
+ .platform_data = NULL,
+ },
+ .res = {
+ .start = U300_EMIF_CFG_BASE,
+ .end = U300_EMIF_CFG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+
+/*
+ * Everything within this next ifdef deals with external devices connected to
+ * the APP SPI bus.
+ */
+static struct amba_device pl022_device = {
+ .dev = {
+ .coherent_dma_mask = ~0,
+ .init_name = "pl022", /* Fast device at 0x6000 offset */
+ },
+ .res = {
+ .start = U300_SPI_BASE,
+ .end = U300_SPI_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_SPI, NO_IRQ },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+};
+
+static struct amba_device mmcsd_device = {
+ .dev = {
+ .init_name = "mmci", /* Fast device at 0x1000 offset */
+ .platform_data = NULL, /* Added later */
+ },
+ .res = {
+ .start = U300_MMCSD_BASE,
+ .end = U300_MMCSD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
+ /*
+ * This device has a DMA channel but the Linux driver does not use
+ * it currently.
+ */
+};
+
+/*
+ * The order of device declaration may be important, since some devices
+ * have dependencies on other devices being initialized first.
+ */
+static struct amba_device *amba_devs[] __initdata = {
+ &uart0_device,
+#ifdef CONFIG_MACH_U300_BS335
+ &uart1_device,
+#endif
+ &pl022_device,
+ &pl172_device,
+ &mmcsd_device,
+};
+
+/* Here follows a list of all hw resources that the platform devices
+ * allocate. Note, clock dependencies are not included
+ */
+
+static struct resource gpio_resources[] = {
+ {
+ .start = U300_GPIO_BASE,
+ .end = (U300_GPIO_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gpio0",
+ .start = IRQ_U300_GPIO_PORT0,
+ .end = IRQ_U300_GPIO_PORT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio1",
+ .start = IRQ_U300_GPIO_PORT1,
+ .end = IRQ_U300_GPIO_PORT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio2",
+ .start = IRQ_U300_GPIO_PORT2,
+ .end = IRQ_U300_GPIO_PORT2,
+ .flags = IORESOURCE_IRQ,
+ },
+#ifdef U300_COH901571_3
+ {
+ .name = "gpio3",
+ .start = IRQ_U300_GPIO_PORT3,
+ .end = IRQ_U300_GPIO_PORT3,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio4",
+ .start = IRQ_U300_GPIO_PORT4,
+ .end = IRQ_U300_GPIO_PORT4,
+ .flags = IORESOURCE_IRQ,
+ },
+#ifdef CONFIG_MACH_U300_BS335
+ {
+ .name = "gpio5",
+ .start = IRQ_U300_GPIO_PORT5,
+ .end = IRQ_U300_GPIO_PORT5,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "gpio6",
+ .start = IRQ_U300_GPIO_PORT6,
+ .end = IRQ_U300_GPIO_PORT6,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif /* CONFIG_MACH_U300_BS335 */
+#endif /* U300_COH901571_3 */
+};
+
+static struct resource keypad_resources[] = {
+ {
+ .start = U300_KEYPAD_BASE,
+ .end = U300_KEYPAD_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "coh901461-press",
+ .start = IRQ_U300_KEYPAD_KEYBF,
+ .end = IRQ_U300_KEYPAD_KEYBF,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "coh901461-release",
+ .start = IRQ_U300_KEYPAD_KEYBR,
+ .end = IRQ_U300_KEYPAD_KEYBR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource rtc_resources[] = {
+ {
+ .start = U300_RTC_BASE,
+ .end = U300_RTC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_RTC,
+ .end = IRQ_U300_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * Fsmc does have IRQs: #43 and #44 (NFIF and NFIF2)
+ * but these are not yet used by the driver.
+ */
+static struct resource fsmc_resources[] = {
+ {
+ .name = "nand_data",
+ .start = U300_NAND_CS0_PHYS_BASE,
+ .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "fsmc_regs",
+ .start = U300_NAND_IF_PHYS_BASE,
+ .end = U300_NAND_IF_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource i2c0_resources[] = {
+ {
+ .start = U300_I2C0_BASE,
+ .end = U300_I2C0_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C0,
+ .end = IRQ_U300_I2C0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource i2c1_resources[] = {
+ {
+ .start = U300_I2C1_BASE,
+ .end = U300_I2C1_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_I2C1,
+ .end = IRQ_U300_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+
+};
+
+static struct resource wdog_resources[] = {
+ {
+ .start = U300_WDOG_BASE,
+ .end = U300_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_WDOG,
+ .end = IRQ_U300_WDOG,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* TODO: These should be protected by suitable #ifdef's */
+static struct resource ave_resources[] = {
+ {
+ .name = "AVE3e I/O Area",
+ .start = U300_VIDEOENC_BASE,
+ .end = U300_VIDEOENC_BASE + SZ_512K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e IRQ0",
+ .start = IRQ_U300_VIDEO_ENC_0,
+ .end = IRQ_U300_VIDEO_ENC_0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e IRQ1",
+ .start = IRQ_U300_VIDEO_ENC_1,
+ .end = IRQ_U300_VIDEO_ENC_1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "AVE3e Physmem Area",
+ .start = 0, /* 0 will be remapped to reserved memory */
+ .end = SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /*
+ * The AVE3e requires two regions of 256MB that it considers
+ * "invisible". The hardware will not be able to access these
+ * addresses, so they should never point to system RAM.
+ */
+ {
+ .name = "AVE3e Reserved 0",
+ .start = 0xd0000000,
+ .end = 0xd0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AVE3e Reserved 1",
+ .start = 0xe0000000,
+ .end = 0xe0000000 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource dma_resource[] = {
+ {
+ .start = U300_DMAC_BASE,
+ .end = U300_DMAC_BASE + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_U300_DMA,
+ .end = IRQ_U300_DMA,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+#ifdef CONFIG_MACH_U300_BS335
+/* points out all dma slave channels.
+ * Syntax is [A1, B1, A2, B2, .... ,-1,-1]
+ * Select all channels from A to B, end of list is marked with -1,-1
+ */
+static int dma_slave_channels[] = {
+ U300_DMA_MSL_TX_0, U300_DMA_SPI_RX,
+ U300_DMA_UART1_TX, U300_DMA_UART1_RX, -1, -1};
+
+/* points out all dma memcpy channels. */
+static int dma_memcpy_channels[] = {
+ U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_8, -1, -1};
+
+#else /* CONFIG_MACH_U300_BS335 */
+
+static int dma_slave_channels[] = {U300_DMA_MSL_TX_0, U300_DMA_SPI_RX, -1, -1};
+static int dma_memcpy_channels[] = {
+ U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_10, -1, -1};
+
+#endif
+
+/** register dma for memory access
+ *
+ * active 1 means dma intends to access memory
+ * 0 means dma wont access memory
+ */
+static void coh901318_access_memory_state(struct device *dev, bool active)
+{
+}
+
+#define flags_memcpy_config (COH901318_CX_CFG_CH_DISABLE | \
+ COH901318_CX_CFG_RM_MEMORY_TO_MEMORY | \
+ COH901318_CX_CFG_LCR_DISABLE | \
+ COH901318_CX_CFG_TC_IRQ_ENABLE | \
+ COH901318_CX_CFG_BE_IRQ_ENABLE)
+#define flags_memcpy_lli_chained (COH901318_CX_CTRL_TC_ENABLE | \
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+ COH901318_CX_CTRL_TCP_DISABLE | \
+ COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+ COH901318_CX_CTRL_HSP_DISABLE | \
+ COH901318_CX_CTRL_HSS_DISABLE | \
+ COH901318_CX_CTRL_DDMA_LEGACY | \
+ COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli (COH901318_CX_CTRL_TC_ENABLE | \
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+ COH901318_CX_CTRL_TCP_DISABLE | \
+ COH901318_CX_CTRL_TC_IRQ_DISABLE | \
+ COH901318_CX_CTRL_HSP_DISABLE | \
+ COH901318_CX_CTRL_HSS_DISABLE | \
+ COH901318_CX_CTRL_DDMA_LEGACY | \
+ COH901318_CX_CTRL_PRDD_SOURCE)
+#define flags_memcpy_lli_last (COH901318_CX_CTRL_TC_ENABLE | \
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
+ COH901318_CX_CTRL_MASTER_MODE_M1RW | \
+ COH901318_CX_CTRL_TCP_DISABLE | \
+ COH901318_CX_CTRL_TC_IRQ_ENABLE | \
+ COH901318_CX_CTRL_HSP_DISABLE | \
+ COH901318_CX_CTRL_HSS_DISABLE | \
+ COH901318_CX_CTRL_DDMA_LEGACY | \
+ COH901318_CX_CTRL_PRDD_SOURCE)
+
+const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
+ {
+ .number = U300_DMA_MSL_TX_0,
+ .name = "MSL TX 0",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x20,
+ },
+ {
+ .number = U300_DMA_MSL_TX_1,
+ .name = "MSL TX 1",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x20,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ },
+ {
+ .number = U300_DMA_MSL_TX_2,
+ .name = "MSL TX 2",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x20,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .desc_nbr_max = 10,
+ },
+ {
+ .number = U300_DMA_MSL_TX_3,
+ .name = "MSL TX 3",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x20,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ },
+ {
+ .number = U300_DMA_MSL_TX_4,
+ .name = "MSL TX 4",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x20,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ },
+ {
+ .number = U300_DMA_MSL_TX_5,
+ .name = "MSL TX 5",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x20,
+ },
+ {
+ .number = U300_DMA_MSL_TX_6,
+ .name = "MSL TX 6",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x20,
+ },
+ {
+ .number = U300_DMA_MSL_RX_0,
+ .name = "MSL RX 0",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 0 * 0x40 + 0x220,
+ },
+ {
+ .number = U300_DMA_MSL_RX_1,
+ .name = "MSL RX 1",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 1 * 0x40 + 0x220,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_MSL_RX_2,
+ .name = "MSL RX 2",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 2 * 0x40 + 0x220,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_MSL_RX_3,
+ .name = "MSL RX 3",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 3 * 0x40 + 0x220,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_MSL_RX_4,
+ .name = "MSL RX 4",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 4 * 0x40 + 0x220,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_MSL_RX_5,
+ .name = "MSL RX 5",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 5 * 0x40 + 0x220,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_MSL_RX_6,
+ .name = "MSL RX 6",
+ .priority_high = 0,
+ .dev_addr = U300_MSL_BASE + 6 * 0x40 + 0x220,
+ },
+ /*
+ * Don't set up device address, burst count or size of src
+ * or dst bus for this peripheral - handled by PrimeCell
+ * DMA extension.
+ */
+ {
+ .number = U300_DMA_MMCSD_RX_TX,
+ .name = "MMCSD RX TX",
+ .priority_high = 0,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+
+ },
+ {
+ .number = U300_DMA_MSPRO_TX,
+ .name = "MSPRO TX",
+ .priority_high = 0,
+ },
+ {
+ .number = U300_DMA_MSPRO_RX,
+ .name = "MSPRO RX",
+ .priority_high = 0,
+ },
+ /*
+ * Don't set up device address, burst count or size of src
+ * or dst bus for this peripheral - handled by PrimeCell
+ * DMA extension.
+ */
+ {
+ .number = U300_DMA_UART0_TX,
+ .name = "UART0 TX",
+ .priority_high = 0,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ },
+ {
+ .number = U300_DMA_UART0_RX,
+ .name = "UART0 RX",
+ .priority_high = 0,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ },
+ {
+ .number = U300_DMA_APEX_TX,
+ .name = "APEX TX",
+ .priority_high = 0,
+ },
+ {
+ .number = U300_DMA_APEX_RX,
+ .name = "APEX RX",
+ .priority_high = 0,
+ },
+ {
+ .number = U300_DMA_PCM_I2S0_TX,
+ .name = "PCM I2S0 TX",
+ .priority_high = 1,
+ .dev_addr = U300_PCM_I2S0_BASE + 0x14,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ },
+ {
+ .number = U300_DMA_PCM_I2S0_RX,
+ .name = "PCM I2S0 RX",
+ .priority_high = 1,
+ .dev_addr = U300_PCM_I2S0_BASE + 0x10,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_PCM_I2S1_TX,
+ .name = "PCM I2S1 TX",
+ .priority_high = 1,
+ .dev_addr = U300_PCM_I2S1_BASE + 0x14,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_SOURCE,
+ },
+ {
+ .number = U300_DMA_PCM_I2S1_RX,
+ .name = "PCM I2S1 RX",
+ .priority_high = 1,
+ .dev_addr = U300_PCM_I2S1_BASE + 0x10,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
+ COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
+ COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
+ COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_ENABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY |
+ COH901318_CX_CTRL_PRDD_DEST,
+ },
+ {
+ .number = U300_DMA_XGAM_CDI,
+ .name = "XGAM CDI",
+ .priority_high = 0,
+ },
+ {
+ .number = U300_DMA_XGAM_PDI,
+ .name = "XGAM PDI",
+ .priority_high = 0,
+ },
+ /*
+ * Don't set up device address, burst count or size of src
+ * or dst bus for this peripheral - handled by PrimeCell
+ * DMA extension.
+ */
+ {
+ .number = U300_DMA_SPI_TX,
+ .name = "SPI TX",
+ .priority_high = 0,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ },
+ {
+ .number = U300_DMA_SPI_RX,
+ .name = "SPI RX",
+ .priority_high = 0,
+ .param.config = COH901318_CX_CFG_CH_DISABLE |
+ COH901318_CX_CFG_LCR_DISABLE |
+ COH901318_CX_CFG_TC_IRQ_ENABLE |
+ COH901318_CX_CFG_BE_IRQ_ENABLE,
+ .param.ctrl_lli_chained = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_DISABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+ .param.ctrl_lli_last = 0 |
+ COH901318_CX_CTRL_TC_ENABLE |
+ COH901318_CX_CTRL_MASTER_MODE_M1RW |
+ COH901318_CX_CTRL_TCP_DISABLE |
+ COH901318_CX_CTRL_TC_IRQ_ENABLE |
+ COH901318_CX_CTRL_HSP_ENABLE |
+ COH901318_CX_CTRL_HSS_DISABLE |
+ COH901318_CX_CTRL_DDMA_LEGACY,
+
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_0,
+ .name = "GENERAL 00",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_1,
+ .name = "GENERAL 01",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_2,
+ .name = "GENERAL 02",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_3,
+ .name = "GENERAL 03",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_4,
+ .name = "GENERAL 04",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_5,
+ .name = "GENERAL 05",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_6,
+ .name = "GENERAL 06",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_7,
+ .name = "GENERAL 07",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_8,
+ .name = "GENERAL 08",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+#ifdef CONFIG_MACH_U300_BS335
+ {
+ .number = U300_DMA_UART1_TX,
+ .name = "UART1 TX",
+ .priority_high = 0,
+ },
+ {
+ .number = U300_DMA_UART1_RX,
+ .name = "UART1 RX",
+ .priority_high = 0,
+ }
+#else
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_9,
+ .name = "GENERAL 09",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ },
+ {
+ .number = U300_DMA_GENERAL_PURPOSE_10,
+ .name = "GENERAL 10",
+ .priority_high = 0,
+
+ .param.config = flags_memcpy_config,
+ .param.ctrl_lli_chained = flags_memcpy_lli_chained,
+ .param.ctrl_lli = flags_memcpy_lli,
+ .param.ctrl_lli_last = flags_memcpy_lli_last,
+ }
+#endif
+};
+
+
+static struct coh901318_platform coh901318_platform = {
+ .chans_slave = dma_slave_channels,
+ .chans_memcpy = dma_memcpy_channels,
+ .access_memory_state = coh901318_access_memory_state,
+ .chan_conf = chan_config,
+ .max_channels = U300_DMA_CHANNELS,
+};
+
+static struct platform_device wdog_device = {
+ .name = "coh901327_wdog",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(wdog_resources),
+ .resource = wdog_resources,
+};
+
+static struct platform_device i2c0_device = {
+ .name = "stu300",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(i2c0_resources),
+ .resource = i2c0_resources,
+};
+
+static struct platform_device i2c1_device = {
+ .name = "stu300",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(i2c1_resources),
+ .resource = i2c1_resources,
+};
+
+static struct platform_device gpio_device = {
+ .name = "u300-gpio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(gpio_resources),
+ .resource = gpio_resources,
+};
+
+static struct platform_device keypad_device = {
+ .name = "keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
+
+static struct platform_device rtc_device = {
+ .name = "rtc-coh901331",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+
+static struct mtd_partition u300_partitions[] = {
+ {
+ .name = "bootrecords",
+ .offset = 0,
+ .size = SZ_128K,
+ },
+ {
+ .name = "free",
+ .offset = SZ_128K,
+ .size = 8064 * SZ_1K,
+ },
+ {
+ .name = "platform",
+ .offset = 8192 * SZ_1K,
+ .size = 253952 * SZ_1K,
+ },
+};
+
+static struct fsmc_nand_platform_data nand_platform_data = {
+ .partitions = u300_partitions,
+ .nr_partitions = ARRAY_SIZE(u300_partitions),
+ .options = NAND_SKIP_BBTSCAN,
+ .width = FSMC_NAND_BW8,
+};
+
+static struct platform_device nand_device = {
+ .name = "fsmc-nand",
+ .id = -1,
+ .resource = fsmc_resources,
+ .num_resources = ARRAY_SIZE(fsmc_resources),
+ .dev = {
+ .platform_data = &nand_platform_data,
+ },
+};
+
+static struct platform_device ave_device = {
+ .name = "video_enc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ave_resources),
+ .resource = ave_resources,
+};
+
+static struct platform_device dma_device = {
+ .name = "coh901318",
+ .id = -1,
+ .resource = dma_resource,
+ .num_resources = ARRAY_SIZE(dma_resource),
+ .dev = {
+ .platform_data = &coh901318_platform,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+/*
+ * Notice that AMBA devices are initialized before platform devices.
+ *
+ */
+static struct platform_device *platform_devs[] __initdata = {
+ &dma_device,
+ &i2c0_device,
+ &i2c1_device,
+ &keypad_device,
+ &rtc_device,
+ &gpio_device,
+ &nand_device,
+ &wdog_device,
+ &ave_device
+};
+
+
+/*
+ * Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
+ * together so some interrupts are connected to the first one and some
+ * to the second one.
+ */
+void __init u300_init_irq(void)
+{
+ u32 mask[2] = {0, 0};
+ struct clk *clk;
+ int i;
+
+ /* initialize clocking early, we want to clock the INTCON */
+ u300_clock_init();
+
+ /* Clock the interrupt controller */
+ clk = clk_get_sys("intcon", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+
+ for (i = 0; i < NR_IRQS; i++)
+ set_bit(i, (unsigned long *) &mask[0]);
+ vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]);
+ vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]);
+}
+
+
+/*
+ * U300 platforms peripheral handling
+ */
+struct db_chip {
+ u16 chipid;
+ const char *name;
+};
+
+/*
+ * This is a list of the Digital Baseband chips used in the U300 platform.
+ */
+static struct db_chip db_chips[] __initdata = {
+ {
+ .chipid = 0xb800,
+ .name = "DB3000",
+ },
+ {
+ .chipid = 0xc000,
+ .name = "DB3100",
+ },
+ {
+ .chipid = 0xc800,
+ .name = "DB3150",
+ },
+ {
+ .chipid = 0xd800,
+ .name = "DB3200",
+ },
+ {
+ .chipid = 0xe000,
+ .name = "DB3250",
+ },
+ {
+ .chipid = 0xe800,
+ .name = "DB3210",
+ },
+ {
+ .chipid = 0xf000,
+ .name = "DB3350 P1x",
+ },
+ {
+ .chipid = 0xf100,
+ .name = "DB3350 P2x",
+ },
+ {
+ .chipid = 0x0000, /* List terminator */
+ .name = NULL,
+ }
+};
+
+static void __init u300_init_check_chip(void)
+{
+
+ u16 val;
+ struct db_chip *chip;
+ const char *chipname;
+ const char unknown[] = "UNKNOWN";
+
+ /* Read out and print chip ID */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CIDR);
+ /* This is in funky bigendian order... */
+ val = (val & 0xFFU) << 8 | (val >> 8);
+ chip = db_chips;
+ chipname = unknown;
+
+ for ( ; chip->chipid; chip++) {
+ if (chip->chipid == (val & 0xFF00U)) {
+ chipname = chip->name;
+ break;
+ }
+ }
+ printk(KERN_INFO "Initializing U300 system on %s baseband chip " \
+ "(chip ID 0x%04x)\n", chipname, val);
+
+#ifdef CONFIG_MACH_U300_BS330
+ if ((val & 0xFF00U) != 0xd800) {
+ printk(KERN_ERR "Platform configured for BS330 " \
+ "with DB3200 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+#ifdef CONFIG_MACH_U300_BS335
+ if ((val & 0xFF00U) != 0xf000 && (val & 0xFF00U) != 0xf100) {
+ printk(KERN_ERR "Platform configured for BS335 " \
+ " with DB3350 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+#ifdef CONFIG_MACH_U300_BS365
+ if ((val & 0xFF00U) != 0xe800) {
+ printk(KERN_ERR "Platform configured for BS365 " \
+ "with DB3210 but %s detected, expect problems!",
+ chipname);
+ }
+#endif
+
+
+}
+
+/*
+ * Some devices and their resources require reserved physical memory from
+ * the end of the available RAM. This function traverses the list of devices
+ * and assigns actual addresses to these.
+ */
+static void __init u300_assign_physmem(void)
+{
+ unsigned long curr_start = __pa(high_memory);
+ int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(platform_devs); i++) {
+ for (j = 0; j < platform_devs[i]->num_resources; j++) {
+ struct resource *const res =
+ &platform_devs[i]->resource[j];
+
+ if (IORESOURCE_MEM == res->flags &&
+ 0 == res->start) {
+ res->start = curr_start;
+ res->end += curr_start;
+ curr_start += (res->end - res->start + 1);
+
+ printk(KERN_INFO "core.c: Mapping RAM " \
+ "%#x-%#x to device %s:%s\n",
+ res->start, res->end,
+ platform_devs[i]->name, res->name);
+ }
+ }
+ }
+}
+
+void __init u300_init_devices(void)
+{
+ int i;
+ u16 val;
+
+ /* Check what platform we run and print some status information */
+ u300_init_check_chip();
+
+ /* Set system to run at PLL208, max performance, a known state. */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ val &= ~U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_CCR);
+ /* Wait for the PLL208 to lock if not locked in yet */
+ while (!(readw(U300_SYSCON_VBASE + U300_SYSCON_CSR) &
+ U300_SYSCON_CSR_PLL208_LOCK_IND));
+ /* Initialize SPI device with some board specifics */
+ u300_spi_init(&pl022_device);
+
+ /* Register the AMBA devices in the AMBA bus abstraction layer */
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+ u300_assign_physmem();
+
+ /* Register subdevices on the I2C buses */
+ u300_i2c_register_board_devices();
+
+ /* Register the platform devices */
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+ /* Register subdevices on the SPI bus */
+ u300_spi_register_board_devices();
+
+#ifndef CONFIG_MACH_U300_SEMI_IS_SHARED
+ /*
+ * Enable SEMI self refresh. Self-refresh of the SDRAM is entered when
+ * both subsystems are requesting this mode.
+ * If we not share the Acc SDRAM, this is never the case. Therefore
+ * enable it here from the App side.
+ */
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_SMCR) |
+ U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
+#endif /* CONFIG_MACH_U300_SEMI_IS_SHARED */
+}
+
+static int core_module_init(void)
+{
+ /*
+ * This needs to be initialized later: it needs the input framework
+ * to be initialized first.
+ */
+ return mmc_init(&mmcsd_device);
+}
+module_init(core_module_init);
diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c
new file mode 100644
index 00000000..03f79361
--- /dev/null
+++ b/arch/arm/mach-u300/dummyspichip.c
@@ -0,0 +1,290 @@
+/*
+ * arch/arm/mach-u300/dummyspichip.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * This is a dummy loopback SPI "chip" used for testing SPI.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/mutex.h>
+#include <linux/spi/spi.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+/*
+ * WARNING! Do not include this pl022-specific controller header
+ * for any generic driver. It is only done in this dummy chip
+ * because we alter the chip configuration in order to test some
+ * different settings on the loopback device. Normal chip configs
+ * shall be STATIC and not altered by the driver!
+ */
+#include <linux/amba/pl022.h>
+
+struct dummy {
+ struct device *dev;
+ struct mutex lock;
+};
+
+#define DMA_TEST_SIZE 2048
+
+/* When we cat /sys/bus/spi/devices/spi0.0/looptest this will be triggered */
+static ssize_t dummy_looptest(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct dummy *p_dummy = dev_get_drvdata(&spi->dev);
+
+ /*
+ * WARNING! Do not dereference the chip-specific data in any normal
+ * driver for a chip. It is usually STATIC and shall not be read
+ * or written to. Your chip driver should NOT depend on fields in this
+ * struct, this is just used here to alter the behaviour of the chip
+ * in order to perform tests.
+ */
+ int status;
+ u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD,
+ 0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05,
+ 0xF0, 0x0D};
+ u8 rxbuf[14];
+ u8 *bigtxbuf_virtual;
+ u8 *bigrxbuf_virtual;
+
+ if (mutex_lock_interruptible(&p_dummy->lock))
+ return -ERESTARTSYS;
+
+ bigtxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);
+ if (bigtxbuf_virtual == NULL) {
+ status = -ENOMEM;
+ goto out;
+ }
+ bigrxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL);
+
+ /* Fill TXBUF with some happy pattern */
+ memset(bigtxbuf_virtual, 0xAA, DMA_TEST_SIZE);
+
+ /*
+ * Force chip to 8 bit mode
+ * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
+ */
+ spi->bits_per_word = 8;
+ /* You should NOT DO THIS EITHER */
+ spi->master->setup(spi);
+
+ /* Now run the tests for 8bit mode */
+ pr_info("Simple test 1: write 0xAA byte, read back garbage byte "
+ "in 8bit mode\n");
+ status = spi_w8r8(spi, 0xAA);
+ if (status < 0)
+ pr_warning("Siple test 1: FAILURE: spi_write_then_read "
+ "failed with status %d\n", status);
+ else
+ pr_info("Simple test 1: SUCCESS!\n");
+
+ pr_info("Simple test 2: write 8 bytes, read back 8 bytes garbage "
+ "in 8bit mode (full FIFO)\n");
+ status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
+ if (status < 0)
+ pr_warning("Simple test 2: FAILURE: spi_write_then_read() "
+ "failed with status %d\n", status);
+ else
+ pr_info("Simple test 2: SUCCESS!\n");
+
+ pr_info("Simple test 3: write 14 bytes, read back 14 bytes garbage "
+ "in 8bit mode (see if we overflow FIFO)\n");
+ status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
+ if (status < 0)
+ pr_warning("Simple test 3: FAILURE: failed with status %d "
+ "(probably FIFO overrun)\n", status);
+ else
+ pr_info("Simple test 3: SUCCESS!\n");
+
+ pr_info("Simple test 4: write 8 bytes with spi_write(), read 8 "
+ "bytes garbage with spi_read() in 8bit mode\n");
+ status = spi_write(spi, &txbuf[0], 8);
+ if (status < 0)
+ pr_warning("Simple test 4 step 1: FAILURE: spi_write() "
+ "failed with status %d\n", status);
+ else
+ pr_info("Simple test 4 step 1: SUCCESS!\n");
+ status = spi_read(spi, &rxbuf[0], 8);
+ if (status < 0)
+ pr_warning("Simple test 4 step 2: FAILURE: spi_read() "
+ "failed with status %d\n", status);
+ else
+ pr_info("Simple test 4 step 2: SUCCESS!\n");
+
+ pr_info("Simple test 5: write 14 bytes with spi_write(), read "
+ "14 bytes garbage with spi_read() in 8bit mode\n");
+ status = spi_write(spi, &txbuf[0], 14);
+ if (status < 0)
+ pr_warning("Simple test 5 step 1: FAILURE: spi_write() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 5 step 1: SUCCESS!\n");
+ status = spi_read(spi, &rxbuf[0], 14);
+ if (status < 0)
+ pr_warning("Simple test 5 step 2: FAILURE: spi_read() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 5: SUCCESS!\n");
+
+ pr_info("Simple test 6: write %d bytes with spi_write(), "
+ "read %d bytes garbage with spi_read() in 8bit mode\n",
+ DMA_TEST_SIZE, DMA_TEST_SIZE);
+ status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
+ if (status < 0)
+ pr_warning("Simple test 6 step 1: FAILURE: spi_write() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 6 step 1: SUCCESS!\n");
+ status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
+ if (status < 0)
+ pr_warning("Simple test 6 step 2: FAILURE: spi_read() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 6: SUCCESS!\n");
+
+
+ /*
+ * Force chip to 16 bit mode
+ * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC!
+ */
+ spi->bits_per_word = 16;
+ /* You should NOT DO THIS EITHER */
+ spi->master->setup(spi);
+
+ pr_info("Simple test 7: write 0xAA byte, read back garbage byte "
+ "in 16bit bus mode\n");
+ status = spi_w8r8(spi, 0xAA);
+ if (status == -EIO)
+ pr_info("Simple test 7: SUCCESS! (expected failure with "
+ "status EIO)\n");
+ else if (status < 0)
+ pr_warning("Siple test 7: FAILURE: spi_write_then_read "
+ "failed with status %d\n", status);
+ else
+ pr_warning("Siple test 7: FAILURE: spi_write_then_read "
+ "succeeded but it was expected to fail!\n");
+
+ pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage "
+ "in 16bit mode (full FIFO)\n");
+ status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8);
+ if (status < 0)
+ pr_warning("Simple test 8: FAILURE: spi_write_then_read() "
+ "failed with status %d\n", status);
+ else
+ pr_info("Simple test 8: SUCCESS!\n");
+
+ pr_info("Simple test 9: write 14 bytes, read back 14 bytes garbage "
+ "in 16bit mode (see if we overflow FIFO)\n");
+ status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14);
+ if (status < 0)
+ pr_warning("Simple test 9: FAILURE: failed with status %d "
+ "(probably FIFO overrun)\n", status);
+ else
+ pr_info("Simple test 9: SUCCESS!\n");
+
+ pr_info("Simple test 10: write %d bytes with spi_write(), "
+ "read %d bytes garbage with spi_read() in 16bit mode\n",
+ DMA_TEST_SIZE, DMA_TEST_SIZE);
+ status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE);
+ if (status < 0)
+ pr_warning("Simple test 10 step 1: FAILURE: spi_write() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 10 step 1: SUCCESS!\n");
+
+ status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE);
+ if (status < 0)
+ pr_warning("Simple test 10 step 2: FAILURE: spi_read() "
+ "failed with status %d (probably FIFO overrun)\n",
+ status);
+ else
+ pr_info("Simple test 10: SUCCESS!\n");
+
+ status = sprintf(buf, "loop test complete\n");
+ kfree(bigrxbuf_virtual);
+ kfree(bigtxbuf_virtual);
+ out:
+ mutex_unlock(&p_dummy->lock);
+ return status;
+}
+
+static DEVICE_ATTR(looptest, S_IRUGO, dummy_looptest, NULL);
+
+static int __devinit pl022_dummy_probe(struct spi_device *spi)
+{
+ struct dummy *p_dummy;
+ int status;
+
+ dev_info(&spi->dev, "probing dummy SPI device\n");
+
+ p_dummy = kzalloc(sizeof *p_dummy, GFP_KERNEL);
+ if (!p_dummy)
+ return -ENOMEM;
+
+ dev_set_drvdata(&spi->dev, p_dummy);
+ mutex_init(&p_dummy->lock);
+
+ /* sysfs hook */
+ status = device_create_file(&spi->dev, &dev_attr_looptest);
+ if (status) {
+ dev_dbg(&spi->dev, "device_create_file looptest failure.\n");
+ goto out_dev_create_looptest_failed;
+ }
+
+ return 0;
+
+out_dev_create_looptest_failed:
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(p_dummy);
+ return status;
+}
+
+static int __devexit pl022_dummy_remove(struct spi_device *spi)
+{
+ struct dummy *p_dummy = dev_get_drvdata(&spi->dev);
+
+ dev_info(&spi->dev, "removing dummy SPI device\n");
+ device_remove_file(&spi->dev, &dev_attr_looptest);
+ dev_set_drvdata(&spi->dev, NULL);
+ kfree(p_dummy);
+
+ return 0;
+}
+
+static struct spi_driver pl022_dummy_driver = {
+ .driver = {
+ .name = "spi-dummy",
+ .owner = THIS_MODULE,
+ },
+ .probe = pl022_dummy_probe,
+ .remove = __devexit_p(pl022_dummy_remove),
+};
+
+static int __init pl022_init_dummy(void)
+{
+ return spi_register_driver(&pl022_dummy_driver);
+}
+
+static void __exit pl022_exit_dummy(void)
+{
+ spi_unregister_driver(&pl022_dummy_driver);
+}
+
+module_init(pl022_init_dummy);
+module_exit(pl022_exit_dummy);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+MODULE_DESCRIPTION("PL022 SSP/SPI DUMMY Linux driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c
new file mode 100644
index 00000000..f0394baa
--- /dev/null
+++ b/arch/arm/mach-u300/i2c.c
@@ -0,0 +1,347 @@
+/*
+ * arch/arm/mach-u300/i2c.c
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Register board i2c devices
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/mfd/abx500.h>
+#include <linux/regulator/machine.h>
+#include <linux/amba/bus.h>
+#include <mach/irqs.h>
+
+/*
+ * Initial settings of ab3100 registers.
+ * Common for below LDO regulator settings are that
+ * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
+ * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
+ */
+
+/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
+#define LDO_A_SETTING 0x16
+/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_C_SETTING 0x10
+/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
+#define LDO_D_SETTING 0x10
+/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_E_SETTING 0x10
+/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
+#define LDO_E_SLEEP_SETTING 0x00
+/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_F_SETTING 0xD0
+/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
+#define LDO_G_SETTING 0x00
+/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
+#define LDO_H_SETTING 0x18
+/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
+#define LDO_K_SETTING 0x00
+/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
+#define LDO_EXT_SETTING 0x00
+/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
+#define BUCK_SETTING 0x7D
+/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
+#define BUCK_SLEEP_SETTING 0xAC
+
+#ifdef CONFIG_AB3100_CORE
+static struct regulator_consumer_supply supply_ldo_c[] = {
+ {
+ .dev_name = "ab3100-codec",
+ .supply = "vaudio", /* Powers the codec */
+ },
+};
+
+/*
+ * This one needs to be a supply so we can turn it off
+ * in order to shut down the system.
+ */
+static struct regulator_consumer_supply supply_ldo_d[] = {
+ {
+ .dev = NULL,
+ .supply = "vana15", /* Powers the SoC (CPU etc) */
+ },
+};
+
+static struct regulator_consumer_supply supply_ldo_g[] = {
+ {
+ .dev_name = "mmci",
+ .supply = "vmmc", /* Powers MMC/SD card */
+ },
+};
+
+static struct regulator_consumer_supply supply_ldo_h[] = {
+ {
+ .dev_name = "xgam_pdi",
+ .supply = "vdisp", /* Powers camera, display etc */
+ },
+};
+
+static struct regulator_consumer_supply supply_ldo_k[] = {
+ {
+ .dev_name = "irda",
+ .supply = "vir", /* Power IrDA */
+ },
+};
+
+/*
+ * This is a placeholder for whoever wish to use the
+ * external power.
+ */
+static struct regulator_consumer_supply supply_ldo_ext[] = {
+ {
+ .dev = NULL,
+ .supply = "vext", /* External power */
+ },
+};
+
+/* Preset (hardware defined) voltages for these regulators */
+#define LDO_A_VOLTAGE 2750000
+#define LDO_C_VOLTAGE 2650000
+#define LDO_D_VOLTAGE 2650000
+
+static struct ab3100_platform_data ab3100_plf_data = {
+ .reg_constraints = {
+ /* LDO A routing and constraints */
+ {
+ .constraints = {
+ .name = "vrad",
+ .min_uV = LDO_A_VOLTAGE,
+ .max_uV = LDO_A_VOLTAGE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ },
+ /* LDO C routing and constraints */
+ {
+ .constraints = {
+ .min_uV = LDO_C_VOLTAGE,
+ .max_uV = LDO_C_VOLTAGE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_c),
+ .consumer_supplies = supply_ldo_c,
+ },
+ /* LDO D routing and constraints */
+ {
+ .constraints = {
+ .min_uV = LDO_D_VOLTAGE,
+ .max_uV = LDO_D_VOLTAGE,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ /*
+ * Actually this is boot_on but we need
+ * to reference count it externally to
+ * be able to shut down the system.
+ */
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_d),
+ .consumer_supplies = supply_ldo_d,
+ },
+ /* LDO E routing and constraints */
+ {
+ .constraints = {
+ .name = "vio",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ },
+ /* LDO F routing and constraints */
+ {
+ .constraints = {
+ .name = "vana25",
+ .min_uV = 2500000,
+ .max_uV = 2500000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ },
+ /* LDO G routing and constraints */
+ {
+ .constraints = {
+ .min_uV = 1500000,
+ .max_uV = 2850000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_g),
+ .consumer_supplies = supply_ldo_g,
+ },
+ /* LDO H routing and constraints */
+ {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2750000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_h),
+ .consumer_supplies = supply_ldo_h,
+ },
+ /* LDO K routing and constraints */
+ {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 2750000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_k),
+ .consumer_supplies = supply_ldo_k,
+ },
+ /* External regulator interface. No fixed voltage specified.
+ * If we knew the voltage of the external regulator and it
+ * was connected on the board, we could add the (fixed)
+ * voltage for it here.
+ */
+ {
+ .constraints = {
+ .min_uV = 0,
+ .max_uV = 0,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext),
+ .consumer_supplies = supply_ldo_ext,
+ },
+ /* Buck converter routing and constraints */
+ {
+ .constraints = {
+ .name = "vcore",
+ .min_uV = 1200000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL,
+ .valid_ops_mask =
+ REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .always_on = 1,
+ .boot_on = 1,
+ },
+ },
+ },
+ .reg_initvals = {
+ LDO_A_SETTING,
+ LDO_C_SETTING,
+ LDO_E_SETTING,
+ LDO_E_SLEEP_SETTING,
+ LDO_F_SETTING,
+ LDO_G_SETTING,
+ LDO_H_SETTING,
+ LDO_K_SETTING,
+ LDO_EXT_SETTING,
+ BUCK_SETTING,
+ BUCK_SLEEP_SETTING,
+ LDO_D_SETTING,
+ },
+};
+#endif
+
+#ifdef CONFIG_AB3550_CORE
+static struct abx500_init_settings ab3550_init_settings[] = {
+ {
+ .bank = 0,
+ .reg = AB3550_IMR1,
+ .setting = 0xff
+ },
+ {
+ .bank = 0,
+ .reg = AB3550_IMR2,
+ .setting = 0xff
+ },
+ {
+ .bank = 0,
+ .reg = AB3550_IMR3,
+ .setting = 0xff
+ },
+ {
+ .bank = 0,
+ .reg = AB3550_IMR4,
+ .setting = 0xff
+ },
+ {
+ .bank = 0,
+ .reg = AB3550_IMR5,
+ /* The two most significant bits are not used */
+ .setting = 0x3f
+ },
+};
+
+static struct ab3550_platform_data ab3550_plf_data = {
+ .irq = {
+ .base = IRQ_AB3550_BASE,
+ .count = (IRQ_AB3550_END - IRQ_AB3550_BASE + 1),
+ },
+ .dev_data = {
+ },
+ .init_settings = ab3550_init_settings,
+ .init_settings_sz = ARRAY_SIZE(ab3550_init_settings),
+};
+#endif
+
+static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
+#if defined(CONFIG_AB3550_CORE)
+ {
+ .type = "ab3550",
+ .addr = 0x4A,
+ .irq = IRQ_U300_IRQ0_EXT,
+ .platform_data = &ab3550_plf_data,
+ },
+#elif defined(CONFIG_AB3100_CORE)
+ {
+ .type = "ab3100",
+ .addr = 0x48,
+ .irq = IRQ_U300_IRQ0_EXT,
+ .platform_data = &ab3100_plf_data,
+ },
+#else
+ { },
+#endif
+};
+
+static struct i2c_board_info __initdata bus1_i2c_board_info[] = {
+#ifdef CONFIG_MACH_U300_BS335
+ {
+ .type = "fwcam",
+ .addr = 0x10,
+ },
+ {
+ .type = "fwcam",
+ .addr = 0x5d,
+ },
+#else
+ { },
+#endif
+};
+
+void __init u300_i2c_register_board_devices(void)
+{
+ i2c_register_board_info(0, bus0_i2c_board_info,
+ ARRAY_SIZE(bus0_i2c_board_info));
+ /*
+ * This makes the core shut down all unused regulators
+ * after all the initcalls have completed.
+ */
+ regulator_has_full_constraints();
+ i2c_register_board_info(1, bus1_i2c_board_info,
+ ARRAY_SIZE(bus1_i2c_board_info));
+}
diff --git a/arch/arm/mach-u300/i2c.h b/arch/arm/mach-u300/i2c.h
new file mode 100644
index 00000000..485c02e5
--- /dev/null
+++ b/arch/arm/mach-u300/i2c.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-u300/i2c.h
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Register board i2c devices
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef MACH_U300_I2C_H
+#define MACH_U300_I2C_H
+
+#ifdef CONFIG_I2C_STU300
+void __init u300_i2c_register_board_devices(void);
+#else
+/* Compile out this stuff if no I2C adapter is available */
+static inline void __init u300_i2c_register_board_devices(void)
+{
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/clkdev.h b/arch/arm/mach-u300/include/mach/clkdev.h
new file mode 100644
index 00000000..92e3cc87
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h
new file mode 100644
index 00000000..7c3b2b2d
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/coh901318.h
@@ -0,0 +1,267 @@
+/*
+ *
+ * include/linux/coh901318.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * DMA driver for COH 901 318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef COH901318_H
+#define COH901318_H
+
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+
+#define MAX_DMA_PACKET_SIZE_SHIFT 11
+#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT)
+
+/**
+ * struct coh901318_lli - linked list item for DMAC
+ * @control: control settings for DMAC
+ * @src_addr: transfer source address
+ * @dst_addr: transfer destination address
+ * @link_addr: physical address to next lli
+ * @virt_link_addr: virtual address of next lli (only used by pool_free)
+ * @phy_this: physical address of current lli (only used by pool_free)
+ */
+struct coh901318_lli {
+ u32 control;
+ dma_addr_t src_addr;
+ dma_addr_t dst_addr;
+ dma_addr_t link_addr;
+
+ void *virt_link_addr;
+ dma_addr_t phy_this;
+};
+/**
+ * struct coh901318_params - parameters for DMAC configuration
+ * @config: DMA config register
+ * @ctrl_lli_last: DMA control register for the last lli in the list
+ * @ctrl_lli: DMA control register for an lli
+ * @ctrl_lli_chained: DMA control register for a chained lli
+ */
+struct coh901318_params {
+ u32 config;
+ u32 ctrl_lli_last;
+ u32 ctrl_lli;
+ u32 ctrl_lli_chained;
+};
+/**
+ * struct coh_dma_channel - dma channel base
+ * @name: ascii name of dma channel
+ * @number: channel id number
+ * @desc_nbr_max: number of preallocated descriptors
+ * @priority_high: prio of channel, 0 low otherwise high.
+ * @param: configuration parameters
+ * @dev_addr: physical address of periphal connected to channel
+ */
+struct coh_dma_channel {
+ const char name[32];
+ const int number;
+ const int desc_nbr_max;
+ const int priority_high;
+ const struct coh901318_params param;
+ const dma_addr_t dev_addr;
+};
+
+/**
+ * dma_access_memory_state_t - register dma for memory access
+ *
+ * @dev: The dma device
+ * @active: 1 means dma intends to access memory
+ * 0 means dma wont access memory
+ */
+typedef void (*dma_access_memory_state_t)(struct device *dev,
+ bool active);
+
+/**
+ * struct powersave - DMA power save structure
+ * @lock: lock protecting data in this struct
+ * @started_channels: bit mask indicating active dma channels
+ */
+struct powersave {
+ spinlock_t lock;
+ u64 started_channels;
+};
+/**
+ * struct coh901318_platform - platform arch structure
+ * @chans_slave: specifying dma slave channels
+ * @chans_memcpy: specifying dma memcpy channels
+ * @access_memory_state: requesting DMA memory access (on / off)
+ * @chan_conf: dma channel configurations
+ * @max_channels: max number of dma chanenls
+ */
+struct coh901318_platform {
+ const int *chans_slave;
+ const int *chans_memcpy;
+ const dma_access_memory_state_t access_memory_state;
+ const struct coh_dma_channel *chan_conf;
+ const int max_channels;
+};
+
+#ifdef CONFIG_COH901318
+/**
+ * coh901318_filter_id() - DMA channel filter function
+ * @chan: dma channel handle
+ * @chan_id: id of dma channel to be filter out
+ *
+ * In dma_request_channel() it specifies what channel id to be requested
+ */
+bool coh901318_filter_id(struct dma_chan *chan, void *chan_id);
+#else
+static inline bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
+{
+ return false;
+}
+#endif
+
+/*
+ * DMA Controller - this access the static mappings of the coh901318 dma.
+ *
+ */
+
+#define COH901318_MOD32_MASK (0x1F)
+#define COH901318_WORD_MASK (0xFFFFFFFF)
+/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */
+#define COH901318_INT_STATUS1 (0x0000)
+#define COH901318_INT_STATUS2 (0x0004)
+/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_TC_INT_STATUS1 (0x0008)
+#define COH901318_TC_INT_STATUS2 (0x000C)
+/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_TC_INT_CLEAR1 (0x0010)
+#define COH901318_TC_INT_CLEAR2 (0x0014)
+/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_TC_INT_STATUS1 (0x0018)
+#define COH901318_RAW_TC_INT_STATUS2 (0x001C)
+/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */
+#define COH901318_BE_INT_STATUS1 (0x0020)
+#define COH901318_BE_INT_STATUS2 (0x0024)
+/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_BE_INT_CLEAR1 (0x0028)
+#define COH901318_BE_INT_CLEAR2 (0x002C)
+/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_BE_INT_STATUS1 (0x0030)
+#define COH901318_RAW_BE_INT_STATUS2 (0x0034)
+
+/*
+ * CX_CFG - Channel Configuration Registers 32bit (R/W)
+ */
+#define COH901318_CX_CFG (0x0100)
+#define COH901318_CX_CFG_SPACING (0x04)
+/* Channel enable activates tha dma job */
+#define COH901318_CX_CFG_CH_ENABLE (0x00000001)
+#define COH901318_CX_CFG_CH_DISABLE (0x00000000)
+/* Request Mode */
+#define COH901318_CX_CFG_RM_MASK (0x00000006)
+#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY (0x0 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY (0x1 << 1)
+#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY (0x1 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY (0x3 << 1)
+#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY (0x3 << 1)
+/* Linked channel request field. RM must == 11 */
+#define COH901318_CX_CFG_LCRF_SHIFT 3
+#define COH901318_CX_CFG_LCRF_MASK (0x000001F8)
+#define COH901318_CX_CFG_LCR_DISABLE (0x00000000)
+/* Terminal Counter Interrupt Request Mask */
+#define COH901318_CX_CFG_TC_IRQ_ENABLE (0x00000200)
+#define COH901318_CX_CFG_TC_IRQ_DISABLE (0x00000000)
+/* Bus Error interrupt Mask */
+#define COH901318_CX_CFG_BE_IRQ_ENABLE (0x00000400)
+#define COH901318_CX_CFG_BE_IRQ_DISABLE (0x00000000)
+
+/*
+ * CX_STAT - Channel Status Registers 32bit (R/-)
+ */
+#define COH901318_CX_STAT (0x0200)
+#define COH901318_CX_STAT_SPACING (0x04)
+#define COH901318_CX_STAT_RBE_IRQ_IND (0x00000008)
+#define COH901318_CX_STAT_RTC_IRQ_IND (0x00000004)
+#define COH901318_CX_STAT_ACTIVE (0x00000002)
+#define COH901318_CX_STAT_ENABLED (0x00000001)
+
+/*
+ * CX_CTRL - Channel Control Registers 32bit (R/W)
+ */
+#define COH901318_CX_CTRL (0x0400)
+#define COH901318_CX_CTRL_SPACING (0x10)
+/* Transfer Count Enable */
+#define COH901318_CX_CTRL_TC_ENABLE (0x00001000)
+#define COH901318_CX_CTRL_TC_DISABLE (0x00000000)
+/* Transfer Count Value 0 - 4095 */
+#define COH901318_CX_CTRL_TC_VALUE_MASK (0x00000FFF)
+/* Burst count */
+#define COH901318_CX_CTRL_BURST_COUNT_MASK (0x0000E000)
+#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES (0x7 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES (0x6 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES (0x5 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES (0x4 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES (0x3 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES (0x2 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES (0x1 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE (0x0 << 13)
+/* Source bus size */
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK (0x00030000)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS (0x2 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS (0x1 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS (0x0 << 16)
+/* Source address increment */
+#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE (0x00040000)
+#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE (0x00000000)
+/* Destination Bus Size */
+#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK (0x00180000)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS (0x2 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS (0x1 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS (0x0 << 19)
+/* Destination address increment */
+#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE (0x00200000)
+#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE (0x00000000)
+/* Master Mode (Master2 is only connected to MSL) */
+#define COH901318_CX_CTRL_MASTER_MODE_MASK (0x00C00000)
+#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W (0x3 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W (0x2 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M2RW (0x1 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1RW (0x0 << 22)
+/* Terminal Count flag to PER enable */
+#define COH901318_CX_CTRL_TCP_ENABLE (0x01000000)
+#define COH901318_CX_CTRL_TCP_DISABLE (0x00000000)
+/* Terminal Count flags to CPU enable */
+#define COH901318_CX_CTRL_TC_IRQ_ENABLE (0x02000000)
+#define COH901318_CX_CTRL_TC_IRQ_DISABLE (0x00000000)
+/* Hand shake to peripheral */
+#define COH901318_CX_CTRL_HSP_ENABLE (0x04000000)
+#define COH901318_CX_CTRL_HSP_DISABLE (0x00000000)
+#define COH901318_CX_CTRL_HSS_ENABLE (0x08000000)
+#define COH901318_CX_CTRL_HSS_DISABLE (0x00000000)
+/* DMA mode */
+#define COH901318_CX_CTRL_DDMA_MASK (0x30000000)
+#define COH901318_CX_CTRL_DDMA_LEGACY (0x0 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1 (0x1 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2 (0x2 << 28)
+/* Primary Request Data Destination */
+#define COH901318_CX_CTRL_PRDD_MASK (0x40000000)
+#define COH901318_CX_CTRL_PRDD_DEST (0x1 << 30)
+#define COH901318_CX_CTRL_PRDD_SOURCE (0x0 << 30)
+
+/*
+ * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_SRC_ADDR (0x0404)
+#define COH901318_CX_SRC_ADDR_SPACING (0x10)
+
+/*
+ * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W
+ */
+#define COH901318_CX_DST_ADDR (0x0408)
+#define COH901318_CX_DST_ADDR_SPACING (0x10)
+
+/*
+ * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_LNK_ADDR (0x040C)
+#define COH901318_CX_LNK_ADDR_SPACING (0x10)
+#define COH901318_CX_LNK_LINK_IMMEDIATE (0x00000001)
+#endif /* COH901318_H */
diff --git a/arch/arm/mach-u300/include/mach/debug-macro.S b/arch/arm/mach-u300/include/mach/debug-macro.S
new file mode 100644
index 00000000..df715707
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/*
+ *
+ * arch-arm/mach-u300/include/mach/debug-macro.S
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Debugging macro include header.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+
+ .macro addruart, rp, rv
+ /* If we move the address using MMU, use this. */
+ ldr \rp, = U300_SLOW_PER_PHYS_BASE @ MMU off, physical address
+ ldr \rv, = U300_SLOW_PER_VIRT_BASE @ MMU on, virtual address
+ orr \rp, \rp, #0x00003000
+ orr \rv, \rv, #0x00003000
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-u300/include/mach/dma_channels.h b/arch/arm/mach-u300/include/mach/dma_channels.h
new file mode 100644
index 00000000..b239149b
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/dma_channels.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/dma_channels.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Map file for the U300 dma driver.
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef DMA_CHANNELS_H
+#define DMA_CHANNELS_H
+
+#define U300_DMA_MSL_TX_0 0
+#define U300_DMA_MSL_TX_1 1
+#define U300_DMA_MSL_TX_2 2
+#define U300_DMA_MSL_TX_3 3
+#define U300_DMA_MSL_TX_4 4
+#define U300_DMA_MSL_TX_5 5
+#define U300_DMA_MSL_TX_6 6
+#define U300_DMA_MSL_RX_0 7
+#define U300_DMA_MSL_RX_1 8
+#define U300_DMA_MSL_RX_2 9
+#define U300_DMA_MSL_RX_3 10
+#define U300_DMA_MSL_RX_4 11
+#define U300_DMA_MSL_RX_5 12
+#define U300_DMA_MSL_RX_6 13
+#define U300_DMA_MMCSD_RX_TX 14
+#define U300_DMA_MSPRO_TX 15
+#define U300_DMA_MSPRO_RX 16
+#define U300_DMA_UART0_TX 17
+#define U300_DMA_UART0_RX 18
+#define U300_DMA_APEX_TX 19
+#define U300_DMA_APEX_RX 20
+#define U300_DMA_PCM_I2S0_TX 21
+#define U300_DMA_PCM_I2S0_RX 22
+#define U300_DMA_PCM_I2S1_TX 23
+#define U300_DMA_PCM_I2S1_RX 24
+#define U300_DMA_XGAM_CDI 25
+#define U300_DMA_XGAM_PDI 26
+#define U300_DMA_SPI_TX 27
+#define U300_DMA_SPI_RX 28
+#define U300_DMA_GENERAL_PURPOSE_0 29
+#define U300_DMA_GENERAL_PURPOSE_1 30
+#define U300_DMA_GENERAL_PURPOSE_2 31
+#define U300_DMA_GENERAL_PURPOSE_3 32
+#define U300_DMA_GENERAL_PURPOSE_4 33
+#define U300_DMA_GENERAL_PURPOSE_5 34
+#define U300_DMA_GENERAL_PURPOSE_6 35
+#define U300_DMA_GENERAL_PURPOSE_7 36
+#define U300_DMA_GENERAL_PURPOSE_8 37
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_UART1_TX 38
+#define U300_DMA_UART1_RX 39
+#else
+#define U300_DMA_GENERAL_PURPOSE_9 38
+#define U300_DMA_GENERAL_PURPOSE_10 39
+#endif
+
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_DMA_DEVICE_CHANNELS 32
+#else
+#define U300_DMA_DEVICE_CHANNELS 30
+#endif
+#define U300_DMA_CHANNELS 40
+
+
+#endif /* DMA_CHANNELS_H */
diff --git a/arch/arm/mach-u300/include/mach/entry-macro.S b/arch/arm/mach-u300/include/mach/entry-macro.S
new file mode 100644
index 00000000..20731ae3
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/entry-macro.S
@@ -0,0 +1,40 @@
+/*
+ *
+ * arch-arm/mach-u300/include/mach/entry-macro.S
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Low-level IRQ helper macros for ST-Ericsson U300
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+#include <asm/hardware/vic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON0_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
+ mov \irqnr, #0
+ teq \irqstat, #0
+ bne 1002f
+1001: ldr \base, = U300_AHB_PER_VIRT_BASE-U300_AHB_PER_PHYS_BASE+U300_INTCON1_BASE
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
+ mov \irqnr, #32
+ teq \irqstat, #0
+ beq 1003f
+1002: tst \irqstat, #1
+ bne 1003f
+ add \irqnr, \irqnr, #1
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
+ .endm
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h
new file mode 100644
index 00000000..d5a71abc
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/gpio.h
@@ -0,0 +1,294 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/gpio.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * GPIO block resgister definitions and inline macros for
+ * U300 GPIO COH 901 335 or COH 901 571/3
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_GPIO_H
+#define __MACH_U300_GPIO_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+/* Switch type depending on platform/chip variant */
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+#define U300_COH901335
+#endif
+#if defined(CONFIG_MACH_U300_BS365) || defined(CONFIG_MACH_U300_BS335)
+#define U300_COH901571_3
+#endif
+
+/* Get base address for regs here */
+#include "u300-regs.h"
+/* IRQ numbers */
+#include "irqs.h"
+
+/*
+ * This is the GPIO block definitions. GPIO (General Purpose I/O) can be
+ * used for anything, and often is. The event/enable etc figures are for
+ * the lowermost pin (pin 0 on each port), shift this left to match your
+ * pin if you're gonna use these values.
+ */
+#ifdef U300_COH901335
+#define U300_GPIO_PORTX_SPACING (0x1C)
+/* Port X Pin Data Register 32bit, this is both input and output (R/W) */
+#define U300_GPIO_PXPDIR (0x00)
+#define U300_GPIO_PXPDOR (0x00)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR (0x04)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV (0x08)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN (0x0C)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR (0x10)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR (0x14)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER (0x18)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
+/* Control Register 32bit (R/W) */
+#define U300_GPIO_CR (0x54)
+#define U300_GPIO_CR_BLOCK_CLOCK_ENABLE (0x00000001UL)
+/* three ports of 8 bits each = GPIO pins 0..23 */
+#define U300_GPIO_NUM_PORTS 3
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+#ifdef U300_COH901571_3
+/*
+ * Control Register 32bit (R/W)
+ * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores
+ * gives the number of GPIO pins.
+ * bit 8-2 (mask 0x000001FC) contains the core version ID.
+ */
+#define U300_GPIO_CR (0x00)
+#define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL)
+#define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL)
+#define U300_GPIO_PORTX_SPACING (0x30)
+/* Port X Pin Data INPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDIR (0x04)
+/* Port X Pin Data OUTPUT Register 32bit (R/W) */
+#define U300_GPIO_PXPDOR (0x08)
+/* Port X Pin Config Register 32bit (R/W) */
+#define U300_GPIO_PXPCR (0x0C)
+#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL)
+#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL)
+#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL)
+#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL)
+/* Port X Pull-up Enable Register 32bit (R/W) */
+#define U300_GPIO_PXPER (0x10)
+#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL)
+/* Port X Interrupt Event Register 32bit (R/W) */
+#define U300_GPIO_PXIEV (0x14)
+#define U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEV_IRQ_EVENT (0x00000001UL)
+/* Port X Interrupt Enable Register 32bit (R/W) */
+#define U300_GPIO_PXIEN (0x18)
+#define U300_GPIO_PXIEN_ALL_IRQ_ENABLE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIEN_IRQ_ENABLE (0x00000001UL)
+/* Port X Interrupt Force Register 32bit (R/W) */
+#define U300_GPIO_PXIFR (0x1C)
+#define U300_GPIO_PXIFR_ALL_IRQ_FORCE_MASK (0x000000FFUL)
+#define U300_GPIO_PXIFR_IRQ_FORCE (0x00000001UL)
+/* Port X Interrupt Config Register 32bit (R/W) */
+#define U300_GPIO_PXICR (0x20)
+#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL)
+#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL)
+#ifdef CONFIG_MACH_U300_BS335
+/* seven ports of 8 bits each = GPIO pins 0..55 */
+#define U300_GPIO_NUM_PORTS 7
+#else
+/* five ports of 8 bits each = GPIO pins 0..39 */
+#define U300_GPIO_NUM_PORTS 5
+#endif
+#define U300_GPIO_PINS_PER_PORT 8
+#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * U300_GPIO_NUM_PORTS - 1)
+#endif
+
+/*
+ * Individual pin assignments for the B26/S26. Notice that the
+ * actual usage of these pins depends on the PAD MUX settings, that
+ * is why the same number can potentially appear several times.
+ * In the reference design each pin is only used for one purpose.
+ * These were determined by inspecting the B26/S26 schematic:
+ * 2/1911-ROA 128 1603
+ */
+#ifdef CONFIG_MACH_U300_BS2X
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_GPIO02 2 /* Unrouted */
+#define U300_GPIO_PIN_GPIO03 3 /* Unrouted */
+#define U300_GPIO_PIN_CAM_SLEEP 4
+#define U300_GPIO_PIN_CAM_REG_EN 5
+#define U300_GPIO_PIN_GPIO06 6 /* Unrouted */
+#define U300_GPIO_PIN_GPIO07 7 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Service point SP2321 */
+#define U300_GPIO_PIN_GPIO09 9 /* Service point SP2322 */
+#define U300_GPIO_PIN_PHFSENSE 10 /* Headphone jack sensing */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_FLIPSENSE 13 /* Mechanical flip sensing */
+#define U300_GPIO_PIN_GPIO14 14 /* DSP JTAG Port RTCK */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Unrouted */
+#define U300_GPIO_PIN_GPIO17 17 /* Unrouted */
+#define U300_GPIO_PIN_GPIO18 18 /* Unrouted */
+#define U300_GPIO_PIN_GPIO19 19 /* Unrouted */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+#endif
+
+/*
+ * Individual pin assignments for the B330/S330 and B365/S365.
+ * Notice that the actual usage of these pins depends on the
+ * PAD MUX settings, that is why the same number can potentially
+ * appear several times. In the reference design each pin is only
+ * used for one purpose. These were determined by inspecting the
+ * S365 schematic.
+ */
+#if defined(CONFIG_MACH_U300_BS330) || defined(CONFIG_MACH_U300_BS365) || \
+ defined(CONFIG_MACH_U300_BS335)
+#define U300_GPIO_PIN_UART_RX 0
+#define U300_GPIO_PIN_UART_TX 1
+#define U300_GPIO_PIN_UART_CTS 2
+#define U300_GPIO_PIN_UART_RTS 3
+#define U300_GPIO_PIN_CAM_MAIN_STANDBY 4 /* Camera MAIN standby */
+#define U300_GPIO_PIN_GPIO05 5 /* Unrouted */
+#define U300_GPIO_PIN_MS_CD 6 /* Memory Stick Card insertion */
+#define U300_GPIO_PIN_GPIO07 7 /* Test point TP2430 */
+
+#define U300_GPIO_PIN_GPIO08 8 /* Test point TP2437 */
+#define U300_GPIO_PIN_GPIO09 9 /* Test point TP2431 */
+#define U300_GPIO_PIN_GPIO10 10 /* Test point TP2432 */
+#define U300_GPIO_PIN_MMC_CLKRET 11 /* Clock return from MMC/SD card */
+#define U300_GPIO_PIN_MMC_CD 12 /* MMC Card insertion detection */
+#define U300_GPIO_PIN_CAM_SUB_STANDBY 13 /* Camera SUB standby */
+#define U300_GPIO_PIN_GPIO14 14 /* Test point TP2436 */
+#define U300_GPIO_PIN_GPIO15 15 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO16 16 /* Test point TP2438 */
+#define U300_GPIO_PIN_PHFSENSE 17 /* Headphone jack sensing */
+#define U300_GPIO_PIN_GPIO18 18 /* Test point TP2439 */
+#define U300_GPIO_PIN_GPIO19 19 /* Routed somewhere */
+#define U300_GPIO_PIN_GPIO20 20 /* Unrouted */
+#define U300_GPIO_PIN_GPIO21 21 /* Unrouted */
+#define U300_GPIO_PIN_GPIO22 22 /* Unrouted */
+#define U300_GPIO_PIN_GPIO23 23 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO24 24 /* Unrouted */
+#define U300_GPIO_PIN_GPIO25 25 /* Unrouted */
+#define U300_GPIO_PIN_GPIO26 26 /* Unrouted */
+#define U300_GPIO_PIN_GPIO27 27 /* Unrouted */
+#define U300_GPIO_PIN_GPIO28 28 /* Unrouted */
+#define U300_GPIO_PIN_GPIO29 29 /* Unrouted */
+#define U300_GPIO_PIN_GPIO30 30 /* Unrouted */
+#define U300_GPIO_PIN_GPIO31 31 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO32 32 /* Unrouted */
+#define U300_GPIO_PIN_GPIO33 33 /* Unrouted */
+#define U300_GPIO_PIN_GPIO34 34 /* Unrouted */
+#define U300_GPIO_PIN_GPIO35 35 /* Unrouted */
+#define U300_GPIO_PIN_GPIO36 36 /* Unrouted */
+#define U300_GPIO_PIN_GPIO37 37 /* Unrouted */
+#define U300_GPIO_PIN_GPIO38 38 /* Unrouted */
+#define U300_GPIO_PIN_GPIO39 39 /* Unrouted */
+
+#ifdef CONFIG_MACH_U300_BS335
+
+#define U300_GPIO_PIN_GPIO40 40 /* Unrouted */
+#define U300_GPIO_PIN_GPIO41 41 /* Unrouted */
+#define U300_GPIO_PIN_GPIO42 42 /* Unrouted */
+#define U300_GPIO_PIN_GPIO43 43 /* Unrouted */
+#define U300_GPIO_PIN_GPIO44 44 /* Unrouted */
+#define U300_GPIO_PIN_GPIO45 45 /* Unrouted */
+#define U300_GPIO_PIN_GPIO46 46 /* Unrouted */
+#define U300_GPIO_PIN_GPIO47 47 /* Unrouted */
+
+#define U300_GPIO_PIN_GPIO48 48 /* Unrouted */
+#define U300_GPIO_PIN_GPIO49 49 /* Unrouted */
+#define U300_GPIO_PIN_GPIO50 50 /* Unrouted */
+#define U300_GPIO_PIN_GPIO51 51 /* Unrouted */
+#define U300_GPIO_PIN_GPIO52 52 /* Unrouted */
+#define U300_GPIO_PIN_GPIO53 53 /* Unrouted */
+#define U300_GPIO_PIN_GPIO54 54 /* Unrouted */
+#define U300_GPIO_PIN_GPIO55 55 /* Unrouted */
+#endif
+
+#endif
+
+/* translates a pin number to a port number */
+#define PIN_TO_PORT(val) (val >> 3)
+
+/* These can be found in arch/arm/mach-u300/gpio.c */
+extern int gpio_is_valid(int number);
+extern int gpio_request(unsigned gpio, const char *label);
+extern void gpio_free(unsigned gpio);
+extern int gpio_direction_input(unsigned gpio);
+extern int gpio_direction_output(unsigned gpio, int value);
+extern int gpio_register_callback(unsigned gpio,
+ int (*func)(void *arg),
+ void *);
+extern int gpio_unregister_callback(unsigned gpio);
+extern void enable_irq_on_gpio_pin(unsigned gpio, int edge);
+extern void disable_irq_on_gpio_pin(unsigned gpio);
+extern void gpio_pullup(unsigned gpio, int value);
+extern int gpio_get_value(unsigned gpio);
+extern void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_get_value_cansleep gpio_get_value
+#define gpio_set_value_cansleep gpio_set_value
+
+/* wrappers to sleep-enable the previous two functions */
+static inline unsigned gpio_to_irq(unsigned gpio)
+{
+ return PIN_TO_PORT(gpio) + IRQ_U300_GPIO_PORT0;
+}
+
+static inline unsigned irq_to_gpio(unsigned irq)
+{
+ /*
+ * FIXME: This is no 1-1 mapping at all, it points to the
+ * whole block of 8 pins.
+ */
+ return (irq - IRQ_U300_GPIO_PORT0) << 3;
+}
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/hardware.h b/arch/arm/mach-u300/include/mach/hardware.h
new file mode 100644
index 00000000..b99d4ce0
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/hardware.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-u300/include/mach/hardware.h
+ */
+#include <asm/sizes.h>
+#include <mach/u300-regs.h>
diff --git a/arch/arm/mach-u300/include/mach/io.h b/arch/arm/mach-u300/include/mach/io.h
new file mode 100644
index 00000000..5d6b4c13
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/io.h
@@ -0,0 +1,20 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/io.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Dummy IO map for being able to use writew()/readw(),
+ * writel()/readw() and similar accessor functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#ifndef __MACH_IO_H
+#define __MACH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h
new file mode 100644
index 00000000..09b1b28f
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/irqs.h
@@ -0,0 +1,121 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/irqs.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * IRQ channel definitions for the U300 platforms.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_IRQS_H
+#define __MACH_IRQS_H
+
+#define IRQ_U300_INTCON0_START 0
+#define IRQ_U300_INTCON1_START 32
+/* These are on INTCON0 - 30 lines */
+#define IRQ_U300_IRQ0_EXT 0
+#define IRQ_U300_IRQ1_EXT 1
+#define IRQ_U300_DMA 2
+#define IRQ_U300_VIDEO_ENC_0 3
+#define IRQ_U300_VIDEO_ENC_1 4
+#define IRQ_U300_AAIF_RX 5
+#define IRQ_U300_AAIF_TX 6
+#define IRQ_U300_AAIF_VGPIO 7
+#define IRQ_U300_AAIF_WAKEUP 8
+#define IRQ_U300_PCM_I2S0_FRAME 9
+#define IRQ_U300_PCM_I2S0_FIFO 10
+#define IRQ_U300_PCM_I2S1_FRAME 11
+#define IRQ_U300_PCM_I2S1_FIFO 12
+#define IRQ_U300_XGAM_GAMCON 13
+#define IRQ_U300_XGAM_CDI 14
+#define IRQ_U300_XGAM_CDICON 15
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+/* MMIACC not used on the DB3210 or DB3350 chips */
+#define IRQ_U300_XGAM_MMIACC 16
+#endif
+#define IRQ_U300_XGAM_PDI 17
+#define IRQ_U300_XGAM_PDICON 18
+#define IRQ_U300_XGAM_GAMEACC 19
+#define IRQ_U300_XGAM_MCIDCT 20
+#define IRQ_U300_APEX 21
+#define IRQ_U300_UART0 22
+#define IRQ_U300_SPI 23
+#define IRQ_U300_TIMER_APP_OS 24
+#define IRQ_U300_TIMER_APP_DD 25
+#define IRQ_U300_TIMER_APP_GP1 26
+#define IRQ_U300_TIMER_APP_GP2 27
+#define IRQ_U300_TIMER_OS 28
+#define IRQ_U300_TIMER_MS 29
+#define IRQ_U300_KEYPAD_KEYBF 30
+#define IRQ_U300_KEYPAD_KEYBR 31
+/* These are on INTCON1 - 32 lines */
+#define IRQ_U300_GPIO_PORT0 32
+#define IRQ_U300_GPIO_PORT1 33
+#define IRQ_U300_GPIO_PORT2 34
+
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \
+ defined(CONFIG_MACH_U300_BS335)
+/* These are for DB3150, DB3200 and DB3350 */
+#define IRQ_U300_WDOG 35
+#define IRQ_U300_EVHIST 36
+#define IRQ_U300_MSPRO 37
+#define IRQ_U300_MMCSD_MCIINTR0 38
+#define IRQ_U300_MMCSD_MCIINTR1 39
+#define IRQ_U300_I2C0 40
+#define IRQ_U300_I2C1 41
+#define IRQ_U300_RTC 42
+#define IRQ_U300_NFIF 43
+#define IRQ_U300_NFIF2 44
+#endif
+
+/* DB3150 and DB3200 have only 45 IRQs */
+#if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330)
+#define U300_NR_IRQS 45
+#endif
+
+/* The DB3350-specific interrupt lines */
+#ifdef CONFIG_MACH_U300_BS335
+#define IRQ_U300_ISP_F0 45
+#define IRQ_U300_ISP_F1 46
+#define IRQ_U300_ISP_F2 47
+#define IRQ_U300_ISP_F3 48
+#define IRQ_U300_ISP_F4 49
+#define IRQ_U300_GPIO_PORT3 50
+#define IRQ_U300_SYSCON_PLL_LOCK 51
+#define IRQ_U300_UART1 52
+#define IRQ_U300_GPIO_PORT4 53
+#define IRQ_U300_GPIO_PORT5 54
+#define IRQ_U300_GPIO_PORT6 55
+#define U300_NR_IRQS 56
+#endif
+
+/* The DB3210-specific interrupt lines */
+#ifdef CONFIG_MACH_U300_BS365
+#define IRQ_U300_GPIO_PORT3 35
+#define IRQ_U300_GPIO_PORT4 36
+#define IRQ_U300_WDOG 37
+#define IRQ_U300_EVHIST 38
+#define IRQ_U300_MSPRO 39
+#define IRQ_U300_MMCSD_MCIINTR0 40
+#define IRQ_U300_MMCSD_MCIINTR1 41
+#define IRQ_U300_I2C0 42
+#define IRQ_U300_I2C1 43
+#define IRQ_U300_RTC 44
+#define IRQ_U300_NFIF 45
+#define IRQ_U300_NFIF2 46
+#define IRQ_U300_SYSCON_PLL_LOCK 47
+#define U300_NR_IRQS 48
+#endif
+
+#ifdef CONFIG_AB3550_CORE
+#define IRQ_AB3550_BASE (U300_NR_IRQS)
+#define IRQ_AB3550_END (IRQ_AB3550_BASE + 37)
+
+#define NR_IRQS (IRQ_AB3550_END + 1)
+#else
+#define NR_IRQS U300_NR_IRQS
+#endif
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
new file mode 100644
index 00000000..888e2e35
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/memory.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/memory.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Memory virtual/physical mapping constants.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+
+#ifndef __MACH_MEMORY_H
+#define __MACH_MEMORY_H
+
+#ifdef CONFIG_MACH_U300_DUAL_RAM
+
+#define PLAT_PHYS_OFFSET UL(0x48000000)
+#define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100)
+
+#else
+
+#ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+#define PLAT_PHYS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE - \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
+#else
+#define PLAT_PHYS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
+#endif
+#define BOOT_PARAMS_OFFSET (0x28000000 + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
+ (CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024 + 0x100)
+#endif
+
+/*
+ * We enable a real big DMA buffer if need be.
+ */
+#define CONSISTENT_DMA_SIZE SZ_4M
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/platform.h b/arch/arm/mach-u300/include/mach/platform.h
new file mode 100644
index 00000000..77d9210a
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/platform.h
@@ -0,0 +1,19 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/platform.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Basic platform init and mapping functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __ASSEMBLY__
+
+void u300_map_io(void);
+void u300_init_irq(void);
+void u300_init_devices(void);
+extern struct sys_timer u300_timer;
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/syscon.h b/arch/arm/mach-u300/include/mach/syscon.h
new file mode 100644
index 00000000..7444f5c7
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/syscon.h
@@ -0,0 +1,750 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/syscon.h
+ *
+ *
+ * Copyright (C) 2008 ST-Ericsson AB
+ *
+ * Author: Rickard Andersson <rickard.andersson@stericsson.com>
+ */
+
+#ifndef __MACH_SYSCON_H
+#define __MACH_SYSCON_H
+
+/*
+ * All register defines for SYSCON registers that concerns individual
+ * block clocks and reset lines are registered here. This is because
+ * we don't want any other file to try to fool around with this stuff.
+ */
+
+/* APP side SYSCON registers */
+/* TODO: this is incomplete. Add all from asic_syscon_map.h eventually. */
+/* CLK Control Register 16bit (R/W) */
+#define U300_SYSCON_CCR (0x0000)
+#define U300_SYSCON_CCR_I2S1_USE_VCXO (0x0040)
+#define U300_SYSCON_CCR_I2S0_USE_VCXO (0x0020)
+#define U300_SYSCON_CCR_TURN_VCXO_ON (0x0008)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_MASK (0x0007)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW_POWER (0x04)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_LOW (0x03)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_INTERMEDIATE (0x02)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_HIGH (0x01)
+#define U300_SYSCON_CCR_CLKING_PERFORMANCE_BEST (0x00)
+/* CLK Status Register 16bit (R/W) */
+#define U300_SYSCON_CSR (0x0004)
+#define U300_SYSCON_CSR_PLL208_LOCK_IND (0x0002)
+#define U300_SYSCON_CSR_PLL13_LOCK_IND (0x0001)
+/* Reset lines for SLOW devices 16bit (R/W) */
+#define U300_SYSCON_RSR (0x0014)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RSR_PPM_RESET_EN (0x0200)
+#endif
+#define U300_SYSCON_RSR_ACC_TMR_RESET_EN (0x0100)
+#define U300_SYSCON_RSR_APP_TMR_RESET_EN (0x0080)
+#define U300_SYSCON_RSR_RTC_RESET_EN (0x0040)
+#define U300_SYSCON_RSR_KEYPAD_RESET_EN (0x0020)
+#define U300_SYSCON_RSR_GPIO_RESET_EN (0x0010)
+#define U300_SYSCON_RSR_EH_RESET_EN (0x0008)
+#define U300_SYSCON_RSR_BTR_RESET_EN (0x0004)
+#define U300_SYSCON_RSR_UART_RESET_EN (0x0002)
+#define U300_SYSCON_RSR_SLOW_BRIDGE_RESET_EN (0x0001)
+/* Reset lines for FAST devices 16bit (R/W) */
+#define U300_SYSCON_RFR (0x0018)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RFR_UART1_RESET_ENABLE (0x0080)
+#endif
+#define U300_SYSCON_RFR_SPI_RESET_ENABLE (0x0040)
+#define U300_SYSCON_RFR_MMC_RESET_ENABLE (0x0020)
+#define U300_SYSCON_RFR_PCM_I2S1_RESET_ENABLE (0x0010)
+#define U300_SYSCON_RFR_PCM_I2S0_RESET_ENABLE (0x0008)
+#define U300_SYSCON_RFR_I2C1_RESET_ENABLE (0x0004)
+#define U300_SYSCON_RFR_I2C0_RESET_ENABLE (0x0002)
+#define U300_SYSCON_RFR_FAST_BRIDGE_RESET_ENABLE (0x0001)
+/* Reset lines for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_RRR (0x001c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_RRR_CDS_RESET_EN (0x4000)
+#define U300_SYSCON_RRR_ISP_RESET_EN (0x2000)
+#endif
+#define U300_SYSCON_RRR_INTCON_RESET_EN (0x1000)
+#define U300_SYSCON_RRR_MSPRO_RESET_EN (0x0800)
+#define U300_SYSCON_RRR_XGAM_RESET_EN (0x0100)
+#define U300_SYSCON_RRR_XGAM_VC_SYNC_RESET_EN (0x0080)
+#define U300_SYSCON_RRR_NANDIF_RESET_EN (0x0040)
+#define U300_SYSCON_RRR_EMIF_RESET_EN (0x0020)
+#define U300_SYSCON_RRR_DMAC_RESET_EN (0x0010)
+#define U300_SYSCON_RRR_CPU_RESET_EN (0x0008)
+#define U300_SYSCON_RRR_APEX_RESET_EN (0x0004)
+#define U300_SYSCON_RRR_AHB_RESET_EN (0x0002)
+#define U300_SYSCON_RRR_AAIF_RESET_EN (0x0001)
+/* Clock enable for SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CESR (0x0020)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CESR_PPM_CLK_EN (0x0200)
+#endif
+#define U300_SYSCON_CESR_ACC_TMR_CLK_EN (0x0100)
+#define U300_SYSCON_CESR_APP_TMR_CLK_EN (0x0080)
+#define U300_SYSCON_CESR_KEYPAD_CLK_EN (0x0040)
+#define U300_SYSCON_CESR_GPIO_CLK_EN (0x0010)
+#define U300_SYSCON_CESR_EH_CLK_EN (0x0008)
+#define U300_SYSCON_CESR_BTR_CLK_EN (0x0004)
+#define U300_SYSCON_CESR_UART_CLK_EN (0x0002)
+#define U300_SYSCON_CESR_SLOW_BRIDGE_CLK_EN (0x0001)
+/* Clock enable for FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CEFR (0x0024)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CEFR_UART1_CLK_EN (0x0200)
+#endif
+#define U300_SYSCON_CEFR_I2S1_CORE_CLK_EN (0x0100)
+#define U300_SYSCON_CEFR_I2S0_CORE_CLK_EN (0x0080)
+#define U300_SYSCON_CEFR_SPI_CLK_EN (0x0040)
+#define U300_SYSCON_CEFR_MMC_CLK_EN (0x0020)
+#define U300_SYSCON_CEFR_I2S1_CLK_EN (0x0010)
+#define U300_SYSCON_CEFR_I2S0_CLK_EN (0x0008)
+#define U300_SYSCON_CEFR_I2C1_CLK_EN (0x0004)
+#define U300_SYSCON_CEFR_I2C0_CLK_EN (0x0002)
+#define U300_SYSCON_CEFR_FAST_BRIDGE_CLK_EN (0x0001)
+/* Clock enable for the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CERR (0x0028)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CERR_CDS_CLK_EN (0x2000)
+#define U300_SYSCON_CERR_ISP_CLK_EN (0x1000)
+#endif
+#define U300_SYSCON_CERR_MSPRO_CLK_EN (0x0800)
+#define U300_SYSCON_CERR_AHB_SUBSYS_BRIDGE_CLK_EN (0x0400)
+#define U300_SYSCON_CERR_SEMI_CLK_EN (0x0200)
+#define U300_SYSCON_CERR_XGAM_CLK_EN (0x0100)
+#define U300_SYSCON_CERR_VIDEO_ENC_CLK_EN (0x0080)
+#define U300_SYSCON_CERR_NANDIF_CLK_EN (0x0040)
+#define U300_SYSCON_CERR_EMIF_CLK_EN (0x0020)
+#define U300_SYSCON_CERR_DMAC_CLK_EN (0x0010)
+#define U300_SYSCON_CERR_CPU_CLK_EN (0x0008)
+#define U300_SYSCON_CERR_APEX_CLK_EN (0x0004)
+#define U300_SYSCON_CERR_AHB_CLK_EN (0x0002)
+#define U300_SYSCON_CERR_AAIF_CLK_EN (0x0001)
+/* Single block clock enable 16bit (-/W) */
+#define U300_SYSCON_SBCER (0x002c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_PPM_CLK_EN (0x0009)
+#endif
+#define U300_SYSCON_SBCER_ACC_TMR_CLK_EN (0x0008)
+#define U300_SYSCON_SBCER_APP_TMR_CLK_EN (0x0007)
+#define U300_SYSCON_SBCER_KEYPAD_CLK_EN (0x0006)
+#define U300_SYSCON_SBCER_GPIO_CLK_EN (0x0004)
+#define U300_SYSCON_SBCER_EH_CLK_EN (0x0003)
+#define U300_SYSCON_SBCER_BTR_CLK_EN (0x0002)
+#define U300_SYSCON_SBCER_UART_CLK_EN (0x0001)
+#define U300_SYSCON_SBCER_SLOW_BRIDGE_CLK_EN (0x0000)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_UART1_CLK_EN (0x0019)
+#endif
+#define U300_SYSCON_SBCER_I2S1_CORE_CLK_EN (0x0018)
+#define U300_SYSCON_SBCER_I2S0_CORE_CLK_EN (0x0017)
+#define U300_SYSCON_SBCER_SPI_CLK_EN (0x0016)
+#define U300_SYSCON_SBCER_MMC_CLK_EN (0x0015)
+#define U300_SYSCON_SBCER_I2S1_CLK_EN (0x0014)
+#define U300_SYSCON_SBCER_I2S0_CLK_EN (0x0013)
+#define U300_SYSCON_SBCER_I2C1_CLK_EN (0x0012)
+#define U300_SYSCON_SBCER_I2C0_CLK_EN (0x0011)
+#define U300_SYSCON_SBCER_FAST_BRIDGE_CLK_EN (0x0010)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_SBCER_CDS_CLK_EN (0x002D)
+#define U300_SYSCON_SBCER_ISP_CLK_EN (0x002C)
+#endif
+#define U300_SYSCON_SBCER_MSPRO_CLK_EN (0x002B)
+#define U300_SYSCON_SBCER_AHB_SUBSYS_BRIDGE_CLK_EN (0x002A)
+#define U300_SYSCON_SBCER_SEMI_CLK_EN (0x0029)
+#define U300_SYSCON_SBCER_XGAM_CLK_EN (0x0028)
+#define U300_SYSCON_SBCER_VIDEO_ENC_CLK_EN (0x0027)
+#define U300_SYSCON_SBCER_NANDIF_CLK_EN (0x0026)
+#define U300_SYSCON_SBCER_EMIF_CLK_EN (0x0025)
+#define U300_SYSCON_SBCER_DMAC_CLK_EN (0x0024)
+#define U300_SYSCON_SBCER_CPU_CLK_EN (0x0023)
+#define U300_SYSCON_SBCER_APEX_CLK_EN (0x0022)
+#define U300_SYSCON_SBCER_AHB_CLK_EN (0x0021)
+#define U300_SYSCON_SBCER_AAIF_CLK_EN (0x0020)
+/* Single block clock disable 16bit (-/W) */
+#define U300_SYSCON_SBCDR (0x0030)
+/* Same values as above for SBCER */
+/* Clock force SLOW peripherals 16bit (R/W) */
+#define U300_SYSCON_CFSR (0x003c)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CFSR_PPM_CLK_FORCE_EN (0x0200)
+#endif
+#define U300_SYSCON_CFSR_ACC_TMR_CLK_FORCE_EN (0x0100)
+#define U300_SYSCON_CFSR_APP_TMR_CLK_FORCE_EN (0x0080)
+#define U300_SYSCON_CFSR_KEYPAD_CLK_FORCE_EN (0x0020)
+#define U300_SYSCON_CFSR_GPIO_CLK_FORCE_EN (0x0010)
+#define U300_SYSCON_CFSR_EH_CLK_FORCE_EN (0x0008)
+#define U300_SYSCON_CFSR_BTR_CLK_FORCE_EN (0x0004)
+#define U300_SYSCON_CFSR_UART_CLK_FORCE_EN (0x0002)
+#define U300_SYSCON_CFSR_SLOW_BRIDGE_CLK_FORCE_EN (0x0001)
+/* Clock force FAST peripherals 16bit (R/W) */
+#define U300_SYSCON_CFFR (0x40)
+/* Values not defined. Define if you want to use them. */
+/* Clock force the rest of the peripherals 16bit (R/W) */
+#define U300_SYSCON_CFRR (0x44)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_CFRR_CDS_CLK_FORCE_EN (0x2000)
+#define U300_SYSCON_CFRR_ISP_CLK_FORCE_EN (0x1000)
+#endif
+#define U300_SYSCON_CFRR_MSPRO_CLK_FORCE_EN (0x0800)
+#define U300_SYSCON_CFRR_AHB_SUBSYS_BRIDGE_CLK_FORCE_EN (0x0400)
+#define U300_SYSCON_CFRR_SEMI_CLK_FORCE_EN (0x0200)
+#define U300_SYSCON_CFRR_XGAM_CLK_FORCE_EN (0x0100)
+#define U300_SYSCON_CFRR_VIDEO_ENC_CLK_FORCE_EN (0x0080)
+#define U300_SYSCON_CFRR_NANDIF_CLK_FORCE_EN (0x0040)
+#define U300_SYSCON_CFRR_EMIF_CLK_FORCE_EN (0x0020)
+#define U300_SYSCON_CFRR_DMAC_CLK_FORCE_EN (0x0010)
+#define U300_SYSCON_CFRR_CPU_CLK_FORCE_EN (0x0008)
+#define U300_SYSCON_CFRR_APEX_CLK_FORCE_EN (0x0004)
+#define U300_SYSCON_CFRR_AHB_CLK_FORCE_EN (0x0002)
+#define U300_SYSCON_CFRR_AAIF_CLK_FORCE_EN (0x0001)
+/* PLL208 Frequency Control 16bit (R/W) */
+#define U300_SYSCON_PFCR (0x48)
+#define U300_SYSCON_PFCR_DPLL_MULT_NUM (0x000F)
+/* Power Management Control 16bit (R/W) */
+#define U300_SYSCON_PMCR (0x50)
+#define U300_SYSCON_PMCR_DCON_ENABLE (0x0002)
+#define U300_SYSCON_PMCR_PWR_MGNT_ENABLE (0x0001)
+/*
+ * All other clocking registers moved to clock.c!
+ */
+/* Reset Out 16bit (R/W) */
+#define U300_SYSCON_RCR (0x6c)
+#define U300_SYSCON_RCR_RESOUT0_RST_N_DISABLE (0x0001)
+/* EMIF Slew Rate Control 16bit (R/W) */
+#define U300_SYSCON_SRCLR (0x70)
+#define U300_SYSCON_SRCLR_MASK (0x03FF)
+#define U300_SYSCON_SRCLR_VALUE (0x03FF)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_B (0x0200)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_5_A (0x0100)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_B (0x0080)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_4_A (0x0040)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_B (0x0020)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_3_A (0x0010)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_B (0x0008)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_2_A (0x0004)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_B (0x0002)
+#define U300_SYSCON_SRCLR_EMIF_1_SLRC_1_A (0x0001)
+/* EMIF Clock Control Register 16bit (R/W) */
+#define U300_SYSCON_ECCR (0x0078)
+#define U300_SYSCON_ECCR_MASK (0x000F)
+#define U300_SYSCON_ECCR_EMIF_1_STATIC_CLK_EN_N_DISABLE (0x0008)
+#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004)
+#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002)
+#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001)
+/* PAD MUX Control register 1 (LOW) 16bit (R/W) */
+#define U300_SYSCON_PMC1LR (0x007C)
+#define U300_SYSCON_PMC1LR_MASK (0xFFFF)
+#define U300_SYSCON_PMC1LR_CDI_MASK (0xC000)
+#define U300_SYSCON_PMC1LR_CDI_CDI (0x0000)
+#define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000)
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SYSCON_PMC1LR_CDI_CDI2 (0x8000)
+#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO (0xC000)
+#elif CONFIG_MACH_U300_BS365
+#define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000)
+#define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000)
+#endif
+#define U300_SYSCON_PMC1LR_PDI_MASK (0x3000)
+#define U300_SYSCON_PMC1LR_PDI_PDI (0x0000)
+#define U300_SYSCON_PMC1LR_PDI_EGG (0x1000)
+#define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000)
+#define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00)
+#define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000)
+#define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400)
+#define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800)
+#define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00)
+#define U300_SYSCON_PMC1LR_ETM_MASK (0x0300)
+#define U300_SYSCON_PMC1LR_ETM_ACC (0x0000)
+#define U300_SYSCON_PMC1LR_ETM_APP (0x0100)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008)
+#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C)
+#define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003)
+#define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000)
+#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001)
+#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002)
+#define U300_SYSCON_PMC1LR_EMIF_1 (0x0003)
+/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */
+#define U300_SYSCON_PMC1HR (0x007E)
+#define U300_SYSCON_PMC1HR_MASK (0xFFFF)
+#define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000)
+#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000)
+#define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000)
+#define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800)
+#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040)
+#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020)
+#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008)
+#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001)
+#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003)
+/* Step one for killing the applications system 16bit (-/W) */
+#define U300_SYSCON_KA1R (0x0080)
+#define U300_SYSCON_KA1R_MASK (0xFFFF)
+#define U300_SYSCON_KA1R_VALUE (0xFFFF)
+/* Step two for killing the application system 16bit (-/W) */
+#define U300_SYSCON_KA2R (0x0084)
+#define U300_SYSCON_KA2R_MASK (0xFFFF)
+#define U300_SYSCON_KA2R_VALUE (0xFFFF)
+/* MMC/MSPRO frequency divider register 0 16bit (R/W) */
+#define U300_SYSCON_MMF0R (0x90)
+#define U300_SYSCON_MMF0R_MASK (0x00FF)
+#define U300_SYSCON_MMF0R_FREQ_0_HIGH_MASK (0x00F0)
+#define U300_SYSCON_MMF0R_FREQ_0_LOW_MASK (0x000F)
+/* MMC/MSPRO frequency divider register 1 16bit (R/W) */
+#define U300_SYSCON_MMF1R (0x94)
+#define U300_SYSCON_MMF1R_MASK (0x00FF)
+#define U300_SYSCON_MMF1R_FREQ_1_HIGH_MASK (0x00F0)
+#define U300_SYSCON_MMF1R_FREQ_1_LOW_MASK (0x000F)
+/* AAIF control register 16 bit (R/W) */
+#define U300_SYSCON_AAIFCR (0x98)
+#define U300_SYSCON_AAIFCR_MASK (0x0003)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_MASK (0x0003)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_FUNCTIONAL (0x0000)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_MONITORING (0x0001)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_ACC_TO_EXT (0x0002)
+#define U300_SYSCON_AAIFCR_AASW_CTRL_APP_TO_EXT (0x0003)
+/* Clock control for the MMC and MSPRO blocks 16bit (R/W) */
+#define U300_SYSCON_MMCR (0x9C)
+#define U300_SYSCON_MMCR_MASK (0x0003)
+#define U300_SYSCON_MMCR_MMC_FB_CLK_SEL_ENABLE (0x0002)
+#define U300_SYSCON_MMCR_MSPRO_FREQSEL_ENABLE (0x0001)
+/* Pull up/down control (R/W) */
+#define U300_SYSCON_PUCR (0x104)
+#define U300_SYSCON_PUCR_EMIF_1_WAIT_N_PU_ENABLE (0x0200)
+#define U300_SYSCON_PUCR_EMIF_1_NFIF_READY_PU_ENABLE (0x0100)
+#define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080)
+#define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040)
+#define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F)
+/* Padmux 2 control */
+#define U300_SYSCON_PMC2R (0x100)
+#define U300_SYSCON_PMC2R_APP_MISC_0_MASK (0x00C0)
+#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM (0x0040)
+#define U300_SYSCON_PMC2R_APP_MISC_0_MMC (0x0080)
+#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 (0x00C0)
+#define U300_SYSCON_PMC2R_APP_MISC_1_MASK (0x0300)
+#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM (0x0100)
+#define U300_SYSCON_PMC2R_APP_MISC_1_MMC (0x0200)
+#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 (0x0300)
+#define U300_SYSCON_PMC2R_APP_MISC_2_MASK (0x0C00)
+#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM (0x0400)
+#define U300_SYSCON_PMC2R_APP_MISC_2_MMC (0x0800)
+#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 (0x0C00)
+#define U300_SYSCON_PMC2R_APP_MISC_3_MASK (0x3000)
+#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM (0x1000)
+#define U300_SYSCON_PMC2R_APP_MISC_3_MMC (0x2000)
+#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 (0x3000)
+#define U300_SYSCON_PMC2R_APP_MISC_4_MASK (0xC000)
+#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM (0x4000)
+#define U300_SYSCON_PMC2R_APP_MISC_4_MMC (0x8000)
+#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO (0xC000)
+/* TODO: More SYSCON registers missing */
+#define U300_SYSCON_PMC3R (0x10c)
+#define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000)
+#define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000)
+#define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000)
+#define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000)
+/* TODO: Missing other configs */
+#define U300_SYSCON_PMC4R (0x168)
+#define U300_SYSCON_PMC4R_APP_MISC_12_MASK (0x0003)
+#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO (0x0000)
+#define U300_SYSCON_PMC4R_APP_MISC_13_MASK (0x000C)
+#define U300_SYSCON_PMC4R_APP_MISC_13_CDI (0x0000)
+#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA (0x0004)
+#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 (0x0008)
+#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO (0x000C)
+#define U300_SYSCON_PMC4R_APP_MISC_14_MASK (0x0030)
+#define U300_SYSCON_PMC4R_APP_MISC_14_CDI (0x0000)
+#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA (0x0010)
+#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 (0x0020)
+#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO (0x0030)
+#define U300_SYSCON_PMC4R_APP_MISC_16_MASK (0x0300)
+#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 (0x0000)
+#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS (0x0100)
+#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N (0x0200)
+/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
+#define U300_SYSCON_S0CCR (0x120)
+#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
+#define U300_SYSCON_S0CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S0CCR_CLOCK_REQ_MONITOR (0x2000)
+#define U300_SYSCON_S0CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S0CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S0CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S0CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S0CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S0CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S0CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S0CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S0CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_1_CLK_CONTROL second clock control 16 bit (R/W) */
+#define U300_SYSCON_S1CCR (0x124)
+#define U300_SYSCON_S1CCR_FIELD_MASK (0x43FF)
+#define U300_SYSCON_S1CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S1CCR_CLOCK_REQ_MONITOR (0x2000)
+#define U300_SYSCON_S1CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S1CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S1CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S1CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S1CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S1CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S1CCR_SEL_ACC_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S1CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S1CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_2_CLK_CONTROL third clock contol 16 bit (R/W) */
+#define U300_SYSCON_S2CCR (0x128)
+#define U300_SYSCON_S2CCR_FIELD_MASK (0xC3FF)
+#define U300_SYSCON_S2CCR_CLK_STEAL (0x8000)
+#define U300_SYSCON_S2CCR_CLOCK_REQ (0x4000)
+#define U300_SYSCON_S2CCR_CLOCK_REQ_MONITOR (0x2000)
+#define U300_SYSCON_S2CCR_CLOCK_INV (0x0200)
+#define U300_SYSCON_S2CCR_CLOCK_FREQ_MASK (0x01E0)
+#define U300_SYSCON_S2CCR_CLOCK_SELECT_MASK (0x001E)
+#define U300_SYSCON_S2CCR_CLOCK_ENABLE (0x0001)
+#define U300_SYSCON_S2CCR_SEL_MCLK (0x8<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_FSM_CLK (0xA<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_48_CLK (0xC<<1)
+#define U300_SYSCON_S2CCR_SEL_PLL60_60_CLK (0xD<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL208_CLK (0xE<<1)
+#define U300_SYSCON_S2CCR_SEL_ACC_PLL13_CLK (0x0<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_FSM_CLK (0x2<<1)
+#define U300_SYSCON_S2CCR_SEL_RTC_CLK (0x4<<1)
+#define U300_SYSCON_S2CCR_SEL_APP_PLL208_CLK (0x6<<1)
+/* SYS_MISC_CONTROL, miscellaneous 16bit (R/W) */
+#define U300_SYSCON_MCR (0x12c)
+#define U300_SYSCON_MCR_FIELD_MASK (0x00FF)
+#define U300_SYSCON_MCR_PMGEN_CR_4_MASK (0x00C0)
+#define U300_SYSCON_MCR_PMGEN_CR_4_GPIO (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_4_SPI (0x0040)
+#define U300_SYSCON_MCR_PMGEN_CR_4_AAIF (0x00C0)
+#define U300_SYSCON_MCR_PMGEN_CR_2_MASK (0x0030)
+#define U300_SYSCON_MCR_PMGEN_CR_2_GPIO (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_2_EMIF_1_STATIC (0x0010)
+#define U300_SYSCON_MCR_PMGEN_CR_2_DSP (0x0020)
+#define U300_SYSCON_MCR_PMGEN_CR_2_AAIF (0x0030)
+#define U300_SYSCON_MCR_PMGEN_CR_0_MASK (0x000C)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M1 (0x0000)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M2 (0x0004)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_1_SDRAM_M3 (0x0008)
+#define U300_SYSCON_MCR_PMGEN_CR_0_EMIF_0_SDRAM (0x000C)
+#define U300_SYSCON_MCR_PM1G_MODE_ENABLE (0x0002)
+#define U300_SYSCON_MCR_PMTG5_MODE_ENABLE (0x0001)
+/* SC_PLL_IRQ_CONTROL 16bit (R/W) */
+#define U300_SYSCON_PICR (0x0130)
+#define U300_SYSCON_PICR_MASK (0x00FF)
+#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_LOW_ENABLE (0x0080)
+#define U300_SYSCON_PICR_FORCE_PLL208_LOCK_HIGH_ENABLE (0x0040)
+#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_LOW_ENABLE (0x0020)
+#define U300_SYSCON_PICR_FORCE_PLL13_LOCK_HIGH_ENABLE (0x0010)
+#define U300_SYSCON_PICR_IRQMASK_PLL13_UNLOCK_ENABLE (0x0008)
+#define U300_SYSCON_PICR_IRQMASK_PLL13_LOCK_ENABLE (0x0004)
+#define U300_SYSCON_PICR_IRQMASK_PLL208_UNLOCK_ENABLE (0x0002)
+#define U300_SYSCON_PICR_IRQMASK_PLL208_LOCK_ENABLE (0x0001)
+/* SC_PLL_IRQ_STATUS 16 bit (R/-) */
+#define U300_SYSCON_PISR (0x0134)
+#define U300_SYSCON_PISR_MASK (0x000F)
+#define U300_SYSCON_PISR_PLL13_UNLOCK_IND (0x0008)
+#define U300_SYSCON_PISR_PLL13_LOCK_IND (0x0004)
+#define U300_SYSCON_PISR_PLL208_UNLOCK_IND (0x0002)
+#define U300_SYSCON_PISR_PLL208_LOCK_IND (0x0001)
+/* SC_PLL_IRQ_CLEAR 16 bit (-/W) */
+#define U300_SYSCON_PICLR (0x0138)
+#define U300_SYSCON_PICLR_MASK (0x000F)
+#define U300_SYSCON_PICLR_RWMASK (0x0000)
+#define U300_SYSCON_PICLR_PLL13_UNLOCK_SC (0x0008)
+#define U300_SYSCON_PICLR_PLL13_LOCK_SC (0x0004)
+#define U300_SYSCON_PICLR_PLL208_UNLOCK_SC (0x0002)
+#define U300_SYSCON_PICLR_PLL208_LOCK_SC (0x0001)
+/* CAMIF_CONTROL 16 bit (-/W) */
+#define U300_SYSCON_CICR (0x013C)
+#define U300_SYSCON_CICR_MASK (0x0FFF)
+#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_MASK (0x0F00)
+#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_PORT1 (0x0C00)
+#define U300_SYSCON_CICR_APP_SUBLVDS_TESTMODE_PORT0 (0x0300)
+#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_MASK (0x00F0)
+#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_PORT1 (0x00C0)
+#define U300_SYSCON_CICR_APP_SUBLVDS_RESCON_PORT0 (0x0030)
+#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_MASK (0x000F)
+#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_PORT1 (0x000C)
+#define U300_SYSCON_CICR_APP_SUBLVDS_PWR_DWN_N_PORT0 (0x0003)
+/* Clock activity observability register 0 */
+#define U300_SYSCON_C0OAR (0x140)
+#define U300_SYSCON_C0OAR_MASK (0xFFFF)
+#define U300_SYSCON_C0OAR_VALUE (0xFFFF)
+#define U300_SYSCON_C0OAR_BT_H_CLK (0x8000)
+#define U300_SYSCON_C0OAR_ASPB_P_CLK (0x4000)
+#define U300_SYSCON_C0OAR_APP_SEMI_H_CLK (0x2000)
+#define U300_SYSCON_C0OAR_APP_SEMI_CLK (0x1000)
+#define U300_SYSCON_C0OAR_APP_MMC_MSPRO_CLK (0x0800)
+#define U300_SYSCON_C0OAR_APP_I2S1_CLK (0x0400)
+#define U300_SYSCON_C0OAR_APP_I2S0_CLK (0x0200)
+#define U300_SYSCON_C0OAR_APP_CPU_CLK (0x0100)
+#define U300_SYSCON_C0OAR_APP_52_CLK (0x0080)
+#define U300_SYSCON_C0OAR_APP_208_CLK (0x0040)
+#define U300_SYSCON_C0OAR_APP_104_CLK (0x0020)
+#define U300_SYSCON_C0OAR_APEX_CLK (0x0010)
+#define U300_SYSCON_C0OAR_AHPB_M_H_CLK (0x0008)
+#define U300_SYSCON_C0OAR_AHB_CLK (0x0004)
+#define U300_SYSCON_C0OAR_AFPB_P_CLK (0x0002)
+#define U300_SYSCON_C0OAR_AAIF_CLK (0x0001)
+/* Clock activity observability register 1 */
+#define U300_SYSCON_C1OAR (0x144)
+#define U300_SYSCON_C1OAR_MASK (0x3FFE)
+#define U300_SYSCON_C1OAR_VALUE (0x3FFE)
+#define U300_SYSCON_C1OAR_NFIF_F_CLK (0x2000)
+#define U300_SYSCON_C1OAR_MSPRO_CLK (0x1000)
+#define U300_SYSCON_C1OAR_MMC_P_CLK (0x0800)
+#define U300_SYSCON_C1OAR_MMC_CLK (0x0400)
+#define U300_SYSCON_C1OAR_KP_P_CLK (0x0200)
+#define U300_SYSCON_C1OAR_I2C1_P_CLK (0x0100)
+#define U300_SYSCON_C1OAR_I2C0_P_CLK (0x0080)
+#define U300_SYSCON_C1OAR_GPIO_CLK (0x0040)
+#define U300_SYSCON_C1OAR_EMIF_MPMC_CLK (0x0020)
+#define U300_SYSCON_C1OAR_EMIF_H_CLK (0x0010)
+#define U300_SYSCON_C1OAR_EVHIST_CLK (0x0008)
+#define U300_SYSCON_C1OAR_PPM_CLK (0x0004)
+#define U300_SYSCON_C1OAR_DMA_CLK (0x0002)
+/* Clock activity observability register 2 */
+#define U300_SYSCON_C2OAR (0x148)
+#define U300_SYSCON_C2OAR_MASK (0x0FFF)
+#define U300_SYSCON_C2OAR_VALUE (0x0FFF)
+#define U300_SYSCON_C2OAR_XGAM_CDI_CLK (0x0800)
+#define U300_SYSCON_C2OAR_XGAM_CLK (0x0400)
+#define U300_SYSCON_C2OAR_VC_H_CLK (0x0200)
+#define U300_SYSCON_C2OAR_VC_CLK (0x0100)
+#define U300_SYSCON_C2OAR_UA_P_CLK (0x0080)
+#define U300_SYSCON_C2OAR_TMR1_CLK (0x0040)
+#define U300_SYSCON_C2OAR_TMR0_CLK (0x0020)
+#define U300_SYSCON_C2OAR_SPI_P_CLK (0x0010)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CORE_CLK (0x0008)
+#define U300_SYSCON_C2OAR_PCM_I2S1_CLK (0x0004)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CORE_CLK (0x0002)
+#define U300_SYSCON_C2OAR_PCM_I2S0_CLK (0x0001)
+
+/* Chip ID register 16bit (R/-) */
+#define U300_SYSCON_CIDR (0x400)
+/* Video IRQ clear 16bit (R/W) */
+#define U300_SYSCON_VICR (0x404)
+#define U300_SYSCON_VICR_VIDEO1_IRQ_CLEAR_ENABLE (0x0002)
+#define U300_SYSCON_VICR_VIDEO0_IRQ_CLEAR_ENABLE (0x0001)
+/* SMCR */
+#define U300_SYSCON_SMCR (0x4d0)
+#define U300_SYSCON_SMCR_FIELD_MASK (0x000e)
+#define U300_SYSCON_SMCR_SEMI_SREFACK_IND (0x0008)
+#define U300_SYSCON_SMCR_SEMI_SREFREQ_ENABLE (0x0004)
+#define U300_SYSCON_SMCR_SEMI_EXT_BOOT_MODE_ENABLE (0x0002)
+/* CPU_SW_DBGEN Software Debug Enable 16bit (R/W) */
+#define U300_SYSCON_CSDR (0x4f0)
+#define U300_SYSCON_CSDR_SW_DEBUG_ENABLE (0x0001)
+/* PRINT_CONTROL Print Control 16bit (R/-) */
+#define U300_SYSCON_PCR (0x4f8)
+#define U300_SYSCON_PCR_SERV_IND (0x0001)
+/* BOOT_CONTROL 16bit (R/-) */
+#define U300_SYSCON_BCR (0x4fc)
+#define U300_SYSCON_BCR_ACC_CPU_SUBSYS_VINITHI_IND (0x0400)
+#define U300_SYSCON_BCR_APP_CPU_SUBSYS_VINITHI_IND (0x0200)
+#define U300_SYSCON_BCR_EXTRA_BOOT_OPTION_MASK (0x01FC)
+#define U300_SYSCON_BCR_APP_BOOT_SERV_MASK (0x0003)
+
+
+/* CPU clock defines */
+/**
+ * CPU high frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_HIGH 208
+/**
+ * CPU medium frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_MEDIUM 52
+/**
+ * CPU low frequency in MHz
+ */
+#define SYSCON_CPU_CLOCK_LOW 13
+
+/* EMIF clock defines */
+/**
+ * EMIF high frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_HIGH 104
+/**
+ * EMIF medium frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_MEDIUM 52
+/**
+ * EMIF low frequency in MHz
+ */
+#define SYSCON_EMIF_CLOCK_LOW 13
+
+/* AHB clock defines */
+/**
+ * AHB high frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_HIGH 52
+/**
+ * AHB medium frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_MEDIUM 26
+/**
+ * AHB low frequency in MHz
+ */
+#define SYSCON_AHB_CLOCK_LOW 7 /* i.e 13/2=6.5MHz */
+
+enum syscon_busmaster {
+ SYSCON_BM_DMAC,
+ SYSCON_BM_XGAM,
+ SYSCON_BM_VIDEO_ENC
+};
+
+/* Selectr a resistor or a set of resistors */
+enum syscon_pull_up_down {
+ SYSCON_PU_KEY_IN_EN,
+ SYSCON_PU_EMIF_1_8_BIT_EN,
+ SYSCON_PU_EMIF_1_16_BIT_EN,
+ SYSCON_PU_EMIF_1_NFIF_READY_EN,
+ SYSCON_PU_EMIF_1_NFIF_WAIT_N_EN,
+};
+
+/*
+ * Note that this array must match the order of the array "clk_reg"
+ * in syscon.c
+ */
+enum syscon_clk {
+ SYSCON_CLKCONTROL_SLOW_BRIDGE,
+ SYSCON_CLKCONTROL_UART,
+ SYSCON_CLKCONTROL_BTR,
+ SYSCON_CLKCONTROL_EH,
+ SYSCON_CLKCONTROL_GPIO,
+ SYSCON_CLKCONTROL_KEYPAD,
+ SYSCON_CLKCONTROL_APP_TIMER,
+ SYSCON_CLKCONTROL_ACC_TIMER,
+ SYSCON_CLKCONTROL_FAST_BRIDGE,
+ SYSCON_CLKCONTROL_I2C0,
+ SYSCON_CLKCONTROL_I2C1,
+ SYSCON_CLKCONTROL_I2S0,
+ SYSCON_CLKCONTROL_I2S1,
+ SYSCON_CLKCONTROL_MMC,
+ SYSCON_CLKCONTROL_SPI,
+ SYSCON_CLKCONTROL_I2S0_CORE,
+ SYSCON_CLKCONTROL_I2S1_CORE,
+ SYSCON_CLKCONTROL_UART1,
+ SYSCON_CLKCONTROL_AAIF,
+ SYSCON_CLKCONTROL_AHB,
+ SYSCON_CLKCONTROL_APEX,
+ SYSCON_CLKCONTROL_CPU,
+ SYSCON_CLKCONTROL_DMA,
+ SYSCON_CLKCONTROL_EMIF,
+ SYSCON_CLKCONTROL_NAND_IF,
+ SYSCON_CLKCONTROL_VIDEO_ENC,
+ SYSCON_CLKCONTROL_XGAM,
+ SYSCON_CLKCONTROL_SEMI,
+ SYSCON_CLKCONTROL_AHB_SUBSYS,
+ SYSCON_CLKCONTROL_MSPRO
+};
+
+enum syscon_sysclk_mode {
+ SYSCON_SYSCLK_DISABLED,
+ SYSCON_SYSCLK_M_CLK,
+ SYSCON_SYSCLK_ACC_FSM,
+ SYSCON_SYSCLK_PLL60_48,
+ SYSCON_SYSCLK_PLL60_60,
+ SYSCON_SYSCLK_ACC_PLL208,
+ SYSCON_SYSCLK_APP_PLL13,
+ SYSCON_SYSCLK_APP_FSM,
+ SYSCON_SYSCLK_RTC,
+ SYSCON_SYSCLK_APP_PLL208
+};
+
+enum syscon_sysclk_req {
+ SYSCON_SYSCLKREQ_DISABLED,
+ SYSCON_SYSCLKREQ_ACTIVE_LOW,
+ SYSCON_SYSCLKREQ_MONITOR
+};
+
+enum syscon_clk_mode {
+ SYSCON_CLKMODE_OFF,
+ SYSCON_CLKMODE_DEFAULT,
+ SYSCON_CLKMODE_LOW,
+ SYSCON_CLKMODE_MEDIUM,
+ SYSCON_CLKMODE_HIGH,
+ SYSCON_CLKMODE_PERMANENT,
+ SYSCON_CLKMODE_ON,
+};
+
+enum syscon_call_mode {
+ SYSCON_CLKCALL_NOWAIT,
+ SYSCON_CLKCALL_WAIT,
+};
+
+int syscon_dc_on(bool keep_power_on);
+int syscon_set_busmaster_active_state(enum syscon_busmaster busmaster,
+ bool active);
+bool syscon_get_busmaster_active_state(void);
+int syscon_set_sleep_mask(enum syscon_clk,
+ bool sleep_ctrl);
+int syscon_config_sysclk(u32 sysclk,
+ enum syscon_sysclk_mode sysclkmode,
+ bool inverse,
+ u32 divisor,
+ enum syscon_sysclk_req sysclkreq);
+bool syscon_can_turn_off_semi_clock(void);
+
+/* This function is restricted to core.c */
+int syscon_request_normal_power(bool req);
+
+/* This function is restricted to be used by platform_speed.c */
+int syscon_speed_request(enum syscon_call_mode wait_mode,
+ enum syscon_clk_mode req_clk_mode);
+#endif /* __MACH_SYSCON_H */
diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h
new file mode 100644
index 00000000..8daf1363
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/system.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/system.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * System shutdown and reset functions.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/hardware/vic.h>
+#include <asm/irq.h>
+
+/* Forward declare this function from the watchdog */
+void coh901327_watchdog_reset(void);
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ switch (mode) {
+ case 's':
+ case 'h':
+ printk(KERN_CRIT "RESET: shutting down/rebooting system\n");
+ /* Disable interrupts */
+ local_irq_disable();
+#ifdef CONFIG_COH901327_WATCHDOG
+ coh901327_watchdog_reset();
+#endif
+ break;
+ default:
+ /* Do nothing */
+ break;
+ }
+ /* Wait for system do die/reset. */
+ while (1);
+}
diff --git a/arch/arm/mach-u300/include/mach/timex.h b/arch/arm/mach-u300/include/mach/timex.h
new file mode 100644
index 00000000..f233b726
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/timex.h
@@ -0,0 +1,17 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/timex.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Platform tick rate definition.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#ifndef __MACH_TIMEX_H
+#define __MACH_TIMEX_H
+
+/* This is for the APP OS GP1 (General Purpose 1) timer */
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/u300-regs.h b/arch/arm/mach-u300/include/mach/u300-regs.h
new file mode 100644
index 00000000..035fdc9d
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/u300-regs.h
@@ -0,0 +1,183 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/u300-regs.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Basic register address definitions in physical memory and
+ * some block definitions for core devices like the timer.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+
+#ifndef __MACH_U300_REGS_H
+#define __MACH_U300_REGS_H
+
+/*
+ * These are the large blocks of memory allocated for I/O.
+ * the defines are used for setting up the I/O memory mapping.
+ */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(a) (a)
+#else
+#define IOMEM(a) (void __iomem *) a
+#endif
+
+/* NAND Flash CS0 */
+#define U300_NAND_CS0_PHYS_BASE 0x80000000
+
+/* NFIF */
+#define U300_NAND_IF_PHYS_BASE 0x9f800000
+
+/* AHB Peripherals */
+#define U300_AHB_PER_PHYS_BASE 0xa0000000
+#define U300_AHB_PER_VIRT_BASE 0xff010000
+
+/* FAST Peripherals */
+#define U300_FAST_PER_PHYS_BASE 0xc0000000
+#define U300_FAST_PER_VIRT_BASE 0xff020000
+
+/* SLOW Peripherals */
+#define U300_SLOW_PER_PHYS_BASE 0xc0010000
+#define U300_SLOW_PER_VIRT_BASE 0xff000000
+
+/* Boot ROM */
+#define U300_BOOTROM_PHYS_BASE 0xffff0000
+#define U300_BOOTROM_VIRT_BASE 0xffff0000
+
+/* SEMI config base */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_SEMI_CONFIG_BASE 0x2FFE0000
+#else
+#define U300_SEMI_CONFIG_BASE 0x30000000
+#endif
+
+/*
+ * AHB peripherals
+ */
+
+/* AHB Peripherals Bridge Controller */
+#define U300_AHB_BRIDGE_BASE (U300_AHB_PER_PHYS_BASE+0x0000)
+
+/* Vectored Interrupt Controller 0, servicing 32 interrupts */
+#define U300_INTCON0_BASE (U300_AHB_PER_PHYS_BASE+0x1000)
+#define U300_INTCON0_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
+
+/* Vectored Interrupt Controller 1, servicing 32 interrupts */
+#define U300_INTCON1_BASE (U300_AHB_PER_PHYS_BASE+0x2000)
+#define U300_INTCON1_VBASE IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
+
+/* Memory Stick Pro (MSPRO) controller */
+#define U300_MSPRO_BASE (U300_AHB_PER_PHYS_BASE+0x3000)
+
+/* EMIF Configuration Area */
+#define U300_EMIF_CFG_BASE (U300_AHB_PER_PHYS_BASE+0x4000)
+
+
+/*
+ * FAST peripherals
+ */
+
+/* FAST bridge control */
+#define U300_FAST_BRIDGE_BASE (U300_FAST_PER_PHYS_BASE+0x0000)
+
+/* MMC/SD controller */
+#define U300_MMCSD_BASE (U300_FAST_PER_PHYS_BASE+0x1000)
+
+/* PCM I2S0 controller */
+#define U300_PCM_I2S0_BASE (U300_FAST_PER_PHYS_BASE+0x2000)
+
+/* PCM I2S1 controller */
+#define U300_PCM_I2S1_BASE (U300_FAST_PER_PHYS_BASE+0x3000)
+
+/* I2C0 controller */
+#define U300_I2C0_BASE (U300_FAST_PER_PHYS_BASE+0x4000)
+
+/* I2C1 controller */
+#define U300_I2C1_BASE (U300_FAST_PER_PHYS_BASE+0x5000)
+
+/* SPI controller */
+#define U300_SPI_BASE (U300_FAST_PER_PHYS_BASE+0x6000)
+
+#ifdef CONFIG_MACH_U300_BS335
+/* Fast UART1 on U335 only */
+#define U300_UART1_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
+#endif
+
+/*
+ * SLOW peripherals
+ */
+
+/* SLOW bridge control */
+#define U300_SLOW_BRIDGE_BASE (U300_SLOW_PER_PHYS_BASE)
+
+/* SYSCON */
+#define U300_SYSCON_BASE (U300_SLOW_PER_PHYS_BASE+0x1000)
+#define U300_SYSCON_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
+
+/* Watchdog */
+#define U300_WDOG_BASE (U300_SLOW_PER_PHYS_BASE+0x2000)
+
+/* UART0 */
+#define U300_UART0_BASE (U300_SLOW_PER_PHYS_BASE+0x3000)
+
+/* APP side special timer */
+#define U300_TIMER_APP_BASE (U300_SLOW_PER_PHYS_BASE+0x4000)
+#define U300_TIMER_APP_VBASE IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
+
+/* Keypad */
+#define U300_KEYPAD_BASE (U300_SLOW_PER_PHYS_BASE+0x5000)
+
+/* GPIO */
+#define U300_GPIO_BASE (U300_SLOW_PER_PHYS_BASE+0x6000)
+
+/* RTC */
+#define U300_RTC_BASE (U300_SLOW_PER_PHYS_BASE+0x7000)
+
+/* Bus tracer */
+#define U300_BUSTR_BASE (U300_SLOW_PER_PHYS_BASE+0x8000)
+
+/* Event handler (hardware queue) */
+#define U300_EVHIST_BASE (U300_SLOW_PER_PHYS_BASE+0x9000)
+
+/* Genric Timer */
+#define U300_TIMER_BASE (U300_SLOW_PER_PHYS_BASE+0xa000)
+
+/* PPM */
+#define U300_PPM_BASE (U300_SLOW_PER_PHYS_BASE+0xb000)
+
+
+/*
+ * REST peripherals
+ */
+
+/* ISP (image signal processor) is only available in U335 */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_ISP_BASE (0xA0008000)
+#endif
+
+/* DMA Controller base */
+#define U300_DMAC_BASE (0xC0020000)
+
+/* MSL Base */
+#define U300_MSL_BASE (0xc0022000)
+
+/* APEX Base */
+#define U300_APEX_BASE (0xc0030000)
+
+/* Video Encoder Base */
+#ifdef CONFIG_MACH_U300_BS335
+#define U300_VIDEOENC_BASE (0xc0080000)
+#else
+#define U300_VIDEOENC_BASE (0xc0040000)
+#endif
+
+/* XGAM Base */
+#define U300_XGAM_BASE (0xd0000000)
+
+/*
+ * Virtual accessor macros for static devices
+ */
+
+#endif
diff --git a/arch/arm/mach-u300/include/mach/uncompress.h b/arch/arm/mach-u300/include/mach/uncompress.h
new file mode 100644
index 00000000..29acb718
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-u300/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#define AMBA_UART_DR (*(volatile unsigned char *)0xc0013000)
+#define AMBA_UART_LCRH (*(volatile unsigned char *)0xc001302C)
+#define AMBA_UART_CR (*(volatile unsigned char *)0xc0013030)
+#define AMBA_UART_FR (*(volatile unsigned char *)0xc0013018)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = c;
+}
+
+static inline void flush(void)
+{
+ while (AMBA_UART_FR & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-u300/include/mach/vmalloc.h b/arch/arm/mach-u300/include/mach/vmalloc.h
new file mode 100644
index 00000000..ec423b92
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/vmalloc.h
@@ -0,0 +1,12 @@
+/*
+ *
+ * arch/arm/mach-u300/include/mach/vmalloc.h
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Virtual memory allocations
+ * End must be above the I/O registers and on an even 2MiB boundary.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#define VMALLOC_END 0xfe800000UL
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c
new file mode 100644
index 00000000..677ccef5
--- /dev/null
+++ b/arch/arm/mach-u300/mmc.c
@@ -0,0 +1,68 @@
+/*
+ *
+ * arch/arm/mach-u300/mmc.c
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson SA
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Johan Lundin
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+#include <linux/dmaengine.h>
+#include <linux/amba/mmci.h>
+#include <linux/slab.h>
+#include <mach/coh901318.h>
+#include <mach/dma_channels.h>
+
+#include "mmc.h"
+#include "padmux.h"
+
+static struct mmci_platform_data mmc0_plat_data = {
+ /*
+ * Do not set ocr_mask or voltage translation function,
+ * we have a regulator we can control instead.
+ */
+ /* Nominally 2.85V on our platform */
+ .f_max = 24000000,
+ .gpio_wp = -1,
+ .gpio_cd = U300_GPIO_PIN_MMC_CD,
+ .cd_invert = true,
+ .capabilities = MMC_CAP_MMC_HIGHSPEED |
+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+#ifdef CONFIG_COH901318
+ .dma_filter = coh901318_filter_id,
+ .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
+ /* Don't specify a TX channel, this RX channel is bidirectional */
+#endif
+};
+
+int __devinit mmc_init(struct amba_device *adev)
+{
+ struct device *mmcsd_device = &adev->dev;
+ struct pmx *pmx;
+ int ret = 0;
+
+ mmcsd_device->platform_data = &mmc0_plat_data;
+
+ /*
+ * Setup padmuxing for MMC. Since this must always be
+ * compiled into the kernel, pmx is never released.
+ */
+ pmx = pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING);
+
+ if (IS_ERR(pmx))
+ pr_warning("Could not get padmux handle\n");
+ else {
+ ret = pmx_activate(mmcsd_device, pmx);
+ if (IS_ERR_VALUE(ret))
+ pr_warning("Could not activate padmuxing\n");
+ }
+
+ return ret;
+}
diff --git a/arch/arm/mach-u300/mmc.h b/arch/arm/mach-u300/mmc.h
new file mode 100644
index 00000000..92b85125
--- /dev/null
+++ b/arch/arm/mach-u300/mmc.h
@@ -0,0 +1,18 @@
+/*
+ *
+ * arch/arm/mach-u300/mmc.h
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+#ifndef MMC_H
+#define MMC_H
+
+#include <linux/amba/bus.h>
+
+int __devinit mmc_init(struct amba_device *adev);
+
+#endif
diff --git a/arch/arm/mach-u300/padmux.c b/arch/arm/mach-u300/padmux.c
new file mode 100644
index 00000000..4c93c6ce
--- /dev/null
+++ b/arch/arm/mach-u300/padmux.c
@@ -0,0 +1,367 @@
+/*
+ *
+ * arch/arm/mach-u300/padmux.c
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 PADMUX functions
+ * Author: Martin Persson <martin.persson@stericsson.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/bug.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <mach/u300-regs.h>
+#include <mach/syscon.h>
+#include "padmux.h"
+
+static DEFINE_MUTEX(pmx_mutex);
+
+const u32 pmx_registers[] = {
+ (U300_SYSCON_VBASE + U300_SYSCON_PMC1LR),
+ (U300_SYSCON_VBASE + U300_SYSCON_PMC1HR),
+ (U300_SYSCON_VBASE + U300_SYSCON_PMC2R),
+ (U300_SYSCON_VBASE + U300_SYSCON_PMC3R),
+ (U300_SYSCON_VBASE + U300_SYSCON_PMC4R)
+};
+
+/* High level functionality */
+
+/* Lazy dog:
+ * onmask = {
+ * {"PMC1LR" mask, "PMC1LR" value},
+ * {"PMC1HR" mask, "PMC1HR" value},
+ * {"PMC2R" mask, "PMC2R" value},
+ * {"PMC3R" mask, "PMC3R" value},
+ * {"PMC4R" mask, "PMC4R" value}
+ * }
+ */
+static struct pmx mmc_setting = {
+ .setting = U300_APP_PMX_MMC_SETTING,
+ .default_on = false,
+ .activated = false,
+ .name = "MMC",
+ .onmask = {
+ {U300_SYSCON_PMC1LR_MMCSD_MASK,
+ U300_SYSCON_PMC1LR_MMCSD_MMCSD},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {U300_SYSCON_PMC4R_APP_MISC_12_MASK,
+ U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO}
+ },
+};
+
+static struct pmx spi_setting = {
+ .setting = U300_APP_PMX_SPI_SETTING,
+ .default_on = false,
+ .activated = false,
+ .name = "SPI",
+ .onmask = {{0, 0},
+ {U300_SYSCON_PMC1HR_APP_SPI_2_MASK |
+ U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK |
+ U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK,
+ U300_SYSCON_PMC1HR_APP_SPI_2_SPI |
+ U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI |
+ U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI},
+ {0, 0},
+ {0, 0},
+ {0, 0}
+ },
+};
+
+/* Available padmux settings */
+static struct pmx *pmx_settings[] = {
+ &mmc_setting,
+ &spi_setting,
+};
+
+static void update_registers(struct pmx *pmx, bool activate)
+{
+ u16 regval, val, mask;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pmx_registers); i++) {
+ if (activate)
+ val = pmx->onmask[i].val;
+ else
+ val = 0;
+
+ mask = pmx->onmask[i].mask;
+ if (mask != 0) {
+ regval = readw(pmx_registers[i]);
+ regval &= ~mask;
+ regval |= val;
+ writew(regval, pmx_registers[i]);
+ }
+ }
+}
+
+struct pmx *pmx_get(struct device *dev, enum pmx_settings setting)
+{
+ int i;
+ struct pmx *pmx = ERR_PTR(-ENOENT);
+
+ if (dev == NULL)
+ return ERR_PTR(-EINVAL);
+
+ mutex_lock(&pmx_mutex);
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+
+ if (setting == pmx_settings[i]->setting) {
+
+ if (pmx_settings[i]->dev != NULL) {
+ WARN(1, "padmux: required setting "
+ "in use by another consumer\n");
+ } else {
+ pmx = pmx_settings[i];
+ pmx->dev = dev;
+ dev_dbg(dev, "padmux: setting nr %d is now "
+ "bound to %s and ready to use\n",
+ setting, dev_name(dev));
+ break;
+ }
+ }
+ }
+ mutex_unlock(&pmx_mutex);
+
+ return pmx;
+}
+EXPORT_SYMBOL(pmx_get);
+
+int pmx_put(struct device *dev, struct pmx *pmx)
+{
+ int i;
+ int ret = -ENOENT;
+
+ if (pmx == NULL || dev == NULL)
+ return -EINVAL;
+
+ mutex_lock(&pmx_mutex);
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+
+ if (pmx->setting == pmx_settings[i]->setting) {
+
+ if (dev != pmx->dev) {
+ WARN(1, "padmux: cannot release handle as "
+ "it is bound to another consumer\n");
+ ret = -EINVAL;
+ break;
+ } else {
+ pmx_settings[i]->dev = NULL;
+ ret = 0;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&pmx_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(pmx_put);
+
+int pmx_activate(struct device *dev, struct pmx *pmx)
+{
+ int i, j, ret;
+ ret = 0;
+
+ if (pmx == NULL || dev == NULL)
+ return -EINVAL;
+
+ mutex_lock(&pmx_mutex);
+
+ /* Make sure the required bits are not used */
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+
+ if (pmx_settings[i]->dev == NULL || pmx_settings[i] == pmx)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) {
+
+ if (pmx_settings[i]->onmask[j].mask & pmx->
+ onmask[j].mask) {
+ /* More than one entry on the same bits */
+ WARN(1, "padmux: cannot activate "
+ "setting. Bit conflict with "
+ "an active setting\n");
+
+ ret = -EUSERS;
+ goto exit;
+ }
+ }
+ }
+ update_registers(pmx, true);
+ pmx->activated = true;
+ dev_dbg(dev, "padmux: setting nr %d is activated\n",
+ pmx->setting);
+
+exit:
+ mutex_unlock(&pmx_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(pmx_activate);
+
+int pmx_deactivate(struct device *dev, struct pmx *pmx)
+{
+ int i;
+ int ret = -ENOENT;
+
+ if (pmx == NULL || dev == NULL)
+ return -EINVAL;
+
+ mutex_lock(&pmx_mutex);
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+
+ if (pmx_settings[i]->dev == NULL)
+ continue;
+
+ if (pmx->setting == pmx_settings[i]->setting) {
+
+ if (dev != pmx->dev) {
+ WARN(1, "padmux: cannot deactivate "
+ "pmx setting as it was activated "
+ "by another consumer\n");
+
+ ret = -EBUSY;
+ continue;
+ } else {
+ update_registers(pmx, false);
+ pmx_settings[i]->dev = NULL;
+ pmx->activated = false;
+ ret = 0;
+ dev_dbg(dev, "padmux: setting nr %d is deactivated",
+ pmx->setting);
+ break;
+ }
+ }
+ }
+ mutex_unlock(&pmx_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(pmx_deactivate);
+
+/*
+ * For internal use only. If it is to be exported,
+ * it should be reentrant. Notice that pmx_activate
+ * (i.e. runtime settings) always override default settings.
+ */
+static int pmx_set_default(void)
+{
+ /* Used to identify several entries on the same bits */
+ u16 modbits[ARRAY_SIZE(pmx_registers)];
+
+ int i, j;
+
+ memset(modbits, 0, ARRAY_SIZE(pmx_registers) * sizeof(u16));
+
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+
+ if (!pmx_settings[i]->default_on)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(pmx_registers); j++) {
+
+ /* Make sure there is only one entry on the same bits */
+ if (modbits[j] & pmx_settings[i]->onmask[j].mask) {
+ BUG();
+ return -EUSERS;
+ }
+ modbits[j] |= pmx_settings[i]->onmask[j].mask;
+ }
+ update_registers(pmx_settings[i], true);
+ }
+ return 0;
+}
+
+#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
+static int pmx_show(struct seq_file *s, void *data)
+{
+ int i;
+ seq_printf(s, "-------------------------------------------------\n");
+ seq_printf(s, "SETTING BOUND TO DEVICE STATE\n");
+ seq_printf(s, "-------------------------------------------------\n");
+ mutex_lock(&pmx_mutex);
+ for (i = 0; i < ARRAY_SIZE(pmx_settings); i++) {
+ /* Format pmx and device name nicely */
+ char cdp[33];
+ int chars;
+
+ chars = snprintf(&cdp[0], 17, "%s", pmx_settings[i]->name);
+ while (chars < 16) {
+ cdp[chars] = ' ';
+ chars++;
+ }
+ chars = snprintf(&cdp[16], 17, "%s", pmx_settings[i]->dev ?
+ dev_name(pmx_settings[i]->dev) : "N/A");
+ while (chars < 16) {
+ cdp[chars+16] = ' ';
+ chars++;
+ }
+ cdp[32] = '\0';
+
+ seq_printf(s,
+ "%s\t%s\n",
+ &cdp[0],
+ pmx_settings[i]->activated ?
+ "ACTIVATED" : "DEACTIVATED"
+ );
+
+ }
+ mutex_unlock(&pmx_mutex);
+ return 0;
+}
+
+static int pmx_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pmx_show, NULL);
+}
+
+static const struct file_operations pmx_operations = {
+ .owner = THIS_MODULE,
+ .open = pmx_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init init_pmx_read_debugfs(void)
+{
+ /* Expose a simple debugfs interface to view pmx settings */
+ (void) debugfs_create_file("padmux", S_IFREG | S_IRUGO,
+ NULL, NULL,
+ &pmx_operations);
+ return 0;
+}
+
+/*
+ * This needs to come in after the core_initcall(),
+ * because debugfs is not available until
+ * the subsystems come up.
+ */
+module_init(init_pmx_read_debugfs);
+#endif
+
+static int __init pmx_init(void)
+{
+ int ret;
+
+ ret = pmx_set_default();
+
+ if (IS_ERR_VALUE(ret))
+ pr_crit("padmux: default settings could not be set\n");
+
+ return 0;
+}
+
+/* Should be initialized before consumers */
+core_initcall(pmx_init);
diff --git a/arch/arm/mach-u300/padmux.h b/arch/arm/mach-u300/padmux.h
new file mode 100644
index 00000000..6e8b8606
--- /dev/null
+++ b/arch/arm/mach-u300/padmux.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * arch/arm/mach-u300/padmux.h
+ *
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 PADMUX API
+ * Author: Martin Persson <martin.persson@stericsson.com>
+ */
+
+#ifndef __MACH_U300_PADMUX_H
+#define __MACH_U300_PADMUX_H
+
+enum pmx_settings {
+ U300_APP_PMX_MMC_SETTING,
+ U300_APP_PMX_SPI_SETTING
+};
+
+struct pmx_onmask {
+ u16 mask; /* Mask bits */
+ u16 val; /* Value when active */
+};
+
+struct pmx {
+ struct device *dev;
+ enum pmx_settings setting;
+ char *name;
+ bool activated;
+ bool default_on;
+ struct pmx_onmask onmask[];
+};
+
+struct pmx *pmx_get(struct device *dev, enum pmx_settings setting);
+int pmx_put(struct device *dev, struct pmx *pmx);
+int pmx_activate(struct device *dev, struct pmx *pmx);
+int pmx_deactivate(struct device *dev, struct pmx *pmx);
+
+#endif
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c
new file mode 100644
index 00000000..9c53f01c
--- /dev/null
+++ b/arch/arm/mach-u300/regulator.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-u300/regulator.c
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Handle board-bound regulators and board power not related
+ * to any devices.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+/* Those are just for writing in syscon */
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+
+/*
+ * Regulators that power the board and chip and which are
+ * not copuled to specific drivers are hogged in these
+ * instances.
+ */
+static struct regulator *main_power_15;
+
+/*
+ * This function is used from pm.h to shut down the system by
+ * resetting all regulators in turn and then disable regulator
+ * LDO D (main power).
+ */
+void u300_pm_poweroff(void)
+{
+ sigset_t old, all;
+
+ sigfillset(&all);
+ if (!sigprocmask(SIG_BLOCK, &all, &old)) {
+ /* Disable LDO D to shut down the system */
+ if (main_power_15)
+ regulator_disable(main_power_15);
+ else
+ pr_err("regulator not available to shut down system\n");
+ (void) sigprocmask(SIG_SETMASK, &old, NULL);
+ }
+ return;
+}
+
+/*
+ * Hog the regulators needed to power up the board.
+ */
+static int __init u300_init_boardpower(void)
+{
+ int err;
+ u32 val;
+
+ pr_info("U300: setting up board power\n");
+ main_power_15 = regulator_get(NULL, "vana15");
+ if (IS_ERR(main_power_15)) {
+ pr_err("could not get vana15");
+ return PTR_ERR(main_power_15);
+ }
+ err = regulator_enable(main_power_15);
+ if (err) {
+ pr_err("could not enable vana15\n");
+ return err;
+ }
+
+ /*
+ * On U300 a special system controller register pulls up the DC
+ * until the vana15 (LDO D) regulator comes up. At this point, all
+ * regulators are set and we do not need power control via
+ * DC ON anymore. This function will likely be moved whenever
+ * the rest of the U300 power management is implemented.
+ */
+ pr_info("U300: disable system controller pull-up\n");
+ val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+ val &= ~U300_SYSCON_PMCR_DCON_ENABLE;
+ writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+
+ /* Register globally exported PM poweroff hook */
+ pm_power_off = u300_pm_poweroff;
+
+ return 0;
+}
+
+/*
+ * So at module init time we hog the regulator!
+ */
+module_init(u300_init_boardpower);
diff --git a/arch/arm/mach-u300/spi.c b/arch/arm/mach-u300/spi.c
new file mode 100644
index 00000000..5767208f
--- /dev/null
+++ b/arch/arm/mach-u300/spi.c
@@ -0,0 +1,123 @@
+/*
+ * arch/arm/mach-u300/spi.c
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/spi/spi.h>
+#include <linux/amba/pl022.h>
+#include <linux/err.h>
+#include <mach/coh901318.h>
+#include <mach/dma_channels.h>
+
+#include "padmux.h"
+
+/*
+ * The following is for the actual devices on the SSP/SPI bus
+ */
+#ifdef CONFIG_MACH_U300_SPIDUMMY
+static void select_dummy_chip(u32 chipselect)
+{
+ pr_debug("CORE: %s called with CS=0x%x (%s)\n",
+ __func__,
+ chipselect,
+ chipselect ? "unselect chip" : "select chip");
+ /*
+ * Here you would write the chip select value to the GPIO pins if
+ * this was a real chip (but this is a loopback dummy).
+ */
+}
+
+struct pl022_config_chip dummy_chip_info = {
+ /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */
+ .com_mode = DMA_TRANSFER,
+ .iface = SSP_INTERFACE_MOTOROLA_SPI,
+ /* We can only act as master but SSP_SLAVE is possible in theory */
+ .hierarchy = SSP_MASTER,
+ /* 0 = drive TX even as slave, 1 = do not drive TX as slave */
+ .slave_tx_disable = 0,
+ .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
+ .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
+ .ctrl_len = SSP_BITS_12,
+ .wait_state = SSP_MWIRE_WAIT_ZERO,
+ .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
+ /*
+ * This is where you insert a call to a function to enable CS
+ * (usually GPIO) for a certain chip.
+ */
+ .cs_control = select_dummy_chip,
+};
+#endif
+
+static struct spi_board_info u300_spi_devices[] = {
+#ifdef CONFIG_MACH_U300_SPIDUMMY
+ {
+ /* A dummy chip used for loopback tests */
+ .modalias = "spi-dummy",
+ /* Really dummy, pass in additional chip config here */
+ .platform_data = NULL,
+ /* This defines how the controller shall handle the device */
+ .controller_data = &dummy_chip_info,
+ /* .irq - no external IRQ routed from this device */
+ .max_speed_hz = 1000000,
+ .bus_num = 0, /* Only one bus on this chip */
+ .chip_select = 0,
+ /* Means SPI_CS_HIGH, change if e.g low CS */
+ .mode = SPI_MODE_1 | SPI_LOOP,
+ },
+#endif
+};
+
+static struct pl022_ssp_controller ssp_platform_data = {
+ /* If you have several SPI buses this varies, we have only bus 0 */
+ .bus_id = 0,
+ /*
+ * On the APP CPU GPIO 4, 5 and 6 are connected as generic
+ * chip selects for SPI. (Same on U330, U335 and U365.)
+ * TODO: make sure the GPIO driver can select these properly
+ * and do padmuxing accordingly too.
+ */
+ .num_chipselect = 3,
+#ifdef CONFIG_COH901318
+ .enable_dma = 1,
+ .dma_filter = coh901318_filter_id,
+ .dma_rx_param = (void *) U300_DMA_SPI_RX,
+ .dma_tx_param = (void *) U300_DMA_SPI_TX,
+#else
+ .enable_dma = 0,
+#endif
+};
+
+
+void __init u300_spi_init(struct amba_device *adev)
+{
+ struct pmx *pmx;
+
+ adev->dev.platform_data = &ssp_platform_data;
+ /*
+ * Setup padmuxing for SPI. Since this must always be
+ * compiled into the kernel, pmx is never released.
+ */
+ pmx = pmx_get(&adev->dev, U300_APP_PMX_SPI_SETTING);
+
+ if (IS_ERR(pmx))
+ dev_warn(&adev->dev, "Could not get padmux handle\n");
+ else {
+ int ret;
+
+ ret = pmx_activate(&adev->dev, pmx);
+ if (IS_ERR_VALUE(ret))
+ dev_warn(&adev->dev, "Could not activate padmuxing\n");
+ }
+
+}
+
+void __init u300_spi_register_board_devices(void)
+{
+ /* Register any SPI devices */
+ spi_register_board_info(u300_spi_devices, ARRAY_SIZE(u300_spi_devices));
+}
diff --git a/arch/arm/mach-u300/spi.h b/arch/arm/mach-u300/spi.h
new file mode 100644
index 00000000..bd3d867e
--- /dev/null
+++ b/arch/arm/mach-u300/spi.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-u300/spi.h
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#ifndef SPI_H
+#define SPI_H
+#include <linux/amba/bus.h>
+
+#ifdef CONFIG_SPI_PL022
+void __init u300_spi_init(struct amba_device *adev);
+void __init u300_spi_register_board_devices(void);
+#else
+/* Compile out SPI support if PL022 is not selected */
+static inline void __init u300_spi_init(struct amba_device *adev)
+{
+}
+static inline void __init u300_spi_register_board_devices(void)
+{
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
new file mode 100644
index 00000000..18d7fa06
--- /dev/null
+++ b/arch/arm/mach-u300/timer.c
@@ -0,0 +1,438 @@
+/*
+ *
+ * arch/arm/mach-u300/timer.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Timer COH 901 328, runs the OS timer interrupt.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <mach/hardware.h>
+
+/* Generic stuff */
+#include <asm/sched_clock.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/mach/irq.h>
+
+/* Be able to sleep for atleast 4 seconds (usually more) */
+#define APPTIMER_MIN_RANGE 4
+
+/*
+ * APP side special timer registers
+ * This timer contains four timers which can fire an interrupt each.
+ * OS (operating system) timer @ 32768 Hz
+ * DD (device driver) timer @ 1 kHz
+ * GP1 (general purpose 1) timer @ 1MHz
+ * GP2 (general purpose 2) timer @ 1MHz
+ */
+
+/* Reset OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_ROST (0x0000)
+#define U300_TIMER_APP_ROST_TIMER_RESET (0x00000000)
+/* Enable OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_EOST (0x0004)
+#define U300_TIMER_APP_EOST_TIMER_ENABLE (0x00000000)
+/* Disable OS Timer 32bit (-/W) */
+#define U300_TIMER_APP_DOST (0x0008)
+#define U300_TIMER_APP_DOST_TIMER_DISABLE (0x00000000)
+/* OS Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SOSTM (0x000c)
+#define U300_TIMER_APP_SOSTM_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SOSTM_MODE_ONE_SHOT (0x00000001)
+/* OS Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_OSTS (0x0010)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_OSTS_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_OSTS_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_OSTS_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_OSTS_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_OSTS_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_OSTS_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_OSTS_IRQ_PENDING_IND (0x00000080)
+/* OS Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_OSTCC (0x0014)
+/* OS Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_OSTTC (0x0018)
+/* OS Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_OSTIE (0x001c)
+#define U300_TIMER_APP_OSTIE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_OSTIE_IRQ_ENABLE (0x00000001)
+/* OS Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_OSTIA (0x0020)
+#define U300_TIMER_APP_OSTIA_IRQ_ACK (0x00000080)
+
+/* Reset DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_RDDT (0x0040)
+#define U300_TIMER_APP_RDDT_TIMER_RESET (0x00000000)
+/* Enable DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_EDDT (0x0044)
+#define U300_TIMER_APP_EDDT_TIMER_ENABLE (0x00000000)
+/* Disable DD Timer 32bit (-/W) */
+#define U300_TIMER_APP_DDDT (0x0048)
+#define U300_TIMER_APP_DDDT_TIMER_DISABLE (0x00000000)
+/* DD Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SDDTM (0x004c)
+#define U300_TIMER_APP_SDDTM_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SDDTM_MODE_ONE_SHOT (0x00000001)
+/* DD Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_DDTS (0x0050)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_DDTS_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_DDTS_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_DDTS_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_DDTS_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_DDTS_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_DDTS_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_DDTS_IRQ_PENDING_IND (0x00000080)
+/* DD Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_DDTCC (0x0054)
+/* DD Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_DDTTC (0x0058)
+/* DD Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_DDTIE (0x005c)
+#define U300_TIMER_APP_DDTIE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_DDTIE_IRQ_ENABLE (0x00000001)
+/* DD Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_DDTIA (0x0060)
+#define U300_TIMER_APP_DDTIA_IRQ_ACK (0x00000080)
+
+/* Reset GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_RGPT1 (0x0080)
+#define U300_TIMER_APP_RGPT1_TIMER_RESET (0x00000000)
+/* Enable GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_EGPT1 (0x0084)
+#define U300_TIMER_APP_EGPT1_TIMER_ENABLE (0x00000000)
+/* Disable GP1 Timer 32bit (-/W) */
+#define U300_TIMER_APP_DGPT1 (0x0088)
+#define U300_TIMER_APP_DGPT1_TIMER_DISABLE (0x00000000)
+/* GP1 Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SGPT1M (0x008c)
+#define U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT (0x00000001)
+/* GP1 Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT1S (0x0090)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_GPT1S_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_GPT1S_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_GPT1S_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_GPT1S_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_GPT1S_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_GPT1S_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_GPT1S_IRQ_PENDING_IND (0x00000080)
+/* GP1 Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT1CC (0x0094)
+/* GP1 Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_GPT1TC (0x0098)
+/* GP1 Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT1IE (0x009c)
+#define U300_TIMER_APP_GPT1IE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_GPT1IE_IRQ_ENABLE (0x00000001)
+/* GP1 Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT1IA (0x00a0)
+#define U300_TIMER_APP_GPT1IA_IRQ_ACK (0x00000080)
+
+/* Reset GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_RGPT2 (0x00c0)
+#define U300_TIMER_APP_RGPT2_TIMER_RESET (0x00000000)
+/* Enable GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_EGPT2 (0x00c4)
+#define U300_TIMER_APP_EGPT2_TIMER_ENABLE (0x00000000)
+/* Disable GP2 Timer 32bit (-/W) */
+#define U300_TIMER_APP_DGPT2 (0x00c8)
+#define U300_TIMER_APP_DGPT2_TIMER_DISABLE (0x00000000)
+/* GP2 Timer Mode Register 32bit (-/W) */
+#define U300_TIMER_APP_SGPT2M (0x00cc)
+#define U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_SGPT2M_MODE_ONE_SHOT (0x00000001)
+/* GP2 Timer Status Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT2S (0x00d0)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_MASK (0x0000000F)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_IDLE (0x00000001)
+#define U300_TIMER_APP_GPT2S_TIMER_STATE_ACTIVE (0x00000002)
+#define U300_TIMER_APP_GPT2S_ENABLE_IND (0x00000010)
+#define U300_TIMER_APP_GPT2S_MODE_MASK (0x00000020)
+#define U300_TIMER_APP_GPT2S_MODE_CONTINUOUS (0x00000000)
+#define U300_TIMER_APP_GPT2S_MODE_ONE_SHOT (0x00000020)
+#define U300_TIMER_APP_GPT2S_IRQ_ENABLED_IND (0x00000040)
+#define U300_TIMER_APP_GPT2S_IRQ_PENDING_IND (0x00000080)
+/* GP2 Timer Current Count Register 32bit (R/-) */
+#define U300_TIMER_APP_GPT2CC (0x00d4)
+/* GP2 Timer Terminal Count Register 32bit (R/W) */
+#define U300_TIMER_APP_GPT2TC (0x00d8)
+/* GP2 Timer Interrupt Enable Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT2IE (0x00dc)
+#define U300_TIMER_APP_GPT2IE_IRQ_DISABLE (0x00000000)
+#define U300_TIMER_APP_GPT2IE_IRQ_ENABLE (0x00000001)
+/* GP2 Timer Interrupt Acknowledge Register 32bit (-/W) */
+#define U300_TIMER_APP_GPT2IA (0x00e0)
+#define U300_TIMER_APP_GPT2IA_IRQ_ACK (0x00000080)
+
+/* Clock request control register - all four timers */
+#define U300_TIMER_APP_CRC (0x100)
+#define U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE (0x00000001)
+
+#define TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ)
+#define US_PER_TICK ((1000000 + (HZ/2)) / HZ)
+
+/*
+ * The u300_set_mode() function is always called first, if we
+ * have oneshot timer active, the oneshot scheduling function
+ * u300_set_next_event() is called immediately after.
+ */
+static void u300_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Set the periodic mode to a certain number of ticks per
+ * jiffy.
+ */
+ writel(TICKS_PER_JIFFY,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * Set continuous mode, so the timer keeps triggering
+ * interrupts.
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Just break; here? */
+ /*
+ * The actual event will be programmed by the next event hook,
+ * so we just set a dummy value somewhere at the end of the
+ * universe here.
+ */
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /*
+ * Expire far in the future, u300_set_next_event() will be
+ * called soon...
+ */
+ writel(0xFFFFFFFF, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /* We run one shot per tick here! */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable interrupts for this timer */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Enable timer */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* Disable interrupts on GP1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ /* Ignore this call */
+ break;
+ }
+}
+
+/*
+ * The app timer in one shot mode obviously has to be reprogrammed
+ * in EXACTLY this sequence to work properly. Do NOT try to e.g. replace
+ * the interrupt disable + timer disable commands with a reset command,
+ * it will fail miserably. Apparently (and I found this the hard way)
+ * the timer is very sensitive to the instruction order, though you don't
+ * get that impression from the data sheet.
+ */
+static int u300_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+
+{
+ /* Disable interrupts on GPT1 */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Disable GP1 while we're reprogramming it. */
+ writel(U300_TIMER_APP_DGPT1_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DGPT1);
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+ /* IRQ in n * cycles */
+ writel(cycles, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1TC);
+ /*
+ * We run one shot per tick here! (This is necessary to reconfigure,
+ * the timer will tilt if you don't!)
+ */
+ writel(U300_TIMER_APP_SGPT1M_MODE_ONE_SHOT,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT1M);
+ /* Enable timer interrupts */
+ writel(U300_TIMER_APP_GPT1IE_IRQ_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IE);
+ /* Then enable the OS timer again */
+ writel(U300_TIMER_APP_EGPT1_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT1);
+ return 0;
+}
+
+
+/* Use general purpose timer 1 as clock event */
+static struct clock_event_device clockevent_u300_1mhz = {
+ .name = "GPT1",
+ .rating = 300, /* Reasonably fast and accurate clock event */
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_next_event = u300_set_next_event,
+ .set_mode = u300_set_mode,
+};
+
+/* Clock event timer interrupt handler */
+static irqreturn_t u300_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_u300_1mhz;
+ /* ACK/Clear timer IRQ for the APP GPT1 Timer */
+ writel(U300_TIMER_APP_GPT1IA_IRQ_ACK,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT1IA);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction u300_timer_irq = {
+ .name = "U300 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = u300_timer_interrupt,
+};
+
+/*
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by OMAP implementation.)
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace u300_update_sched_clock(void)
+{
+ u32 cyc = readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+
+/*
+ * This sets up the system timers, clock source and clock event.
+ */
+static void __init u300_timer_init(void)
+{
+ struct clk *clk;
+ unsigned long rate;
+
+ /* Clock the interrupt controller */
+ clk = clk_get_sys("apptimer", NULL);
+ BUG_ON(IS_ERR(clk));
+ clk_enable(clk);
+ rate = clk_get_rate(clk);
+
+ init_sched_clock(&cd, u300_update_sched_clock, 32, rate);
+
+ /*
+ * Disable the "OS" and "DD" timers - these are designed for Symbian!
+ * Example usage in cnh1601578 cpu subsystem pd_timer_app.c
+ */
+ writel(U300_TIMER_APP_CRC_CLOCK_REQUEST_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_CRC);
+ writel(U300_TIMER_APP_ROST_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_ROST);
+ writel(U300_TIMER_APP_DOST_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DOST);
+ writel(U300_TIMER_APP_RDDT_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RDDT);
+ writel(U300_TIMER_APP_DDDT_TIMER_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_DDDT);
+
+ /* Reset the General Purpose timer 1. */
+ writel(U300_TIMER_APP_RGPT1_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT1);
+
+ /* Set up the IRQ handler */
+ setup_irq(IRQ_U300_TIMER_APP_GP1, &u300_timer_irq);
+
+ /* Reset the General Purpose timer 2 */
+ writel(U300_TIMER_APP_RGPT2_TIMER_RESET,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_RGPT2);
+ /* Set this timer to run around forever */
+ writel(0xFFFFFFFFU, U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2TC);
+ /* Set continuous mode so it wraps around */
+ writel(U300_TIMER_APP_SGPT2M_MODE_CONTINUOUS,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_SGPT2M);
+ /* Disable timer interrupts */
+ writel(U300_TIMER_APP_GPT2IE_IRQ_DISABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2IE);
+ /* Then enable the GP2 timer to use as a free running us counter */
+ writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
+ U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
+
+ /* Use general purpose timer 2 as clock source */
+ if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC,
+ "GPT2", rate, 300, 32, clocksource_mmio_readl_up))
+ pr_err("timer: failed to initialize U300 clock source\n");
+
+ clockevents_calc_mult_shift(&clockevent_u300_1mhz,
+ rate, APPTIMER_MIN_RANGE);
+ /* 32bit counter, so 32bits delta is max */
+ clockevent_u300_1mhz.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &clockevent_u300_1mhz);
+ /* This timer is slow enough to set for 1 cycle == 1 MHz */
+ clockevent_u300_1mhz.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_u300_1mhz);
+ clockevent_u300_1mhz.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_u300_1mhz);
+ /*
+ * TODO: init and register the rest of the timers too, they can be
+ * used by hrtimers!
+ */
+}
+
+/*
+ * Very simple system timer that only register the clock event and
+ * clock source.
+ */
+struct sys_timer u300_timer = {
+ .init = u300_timer_init,
+};
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
new file mode 100644
index 00000000..48b3b7f3
--- /dev/null
+++ b/arch/arm/mach-u300/u300.c
@@ -0,0 +1,70 @@
+/*
+ *
+ * arch/arm/mach-u300/u300.c
+ *
+ *
+ * Copyright (C) 2006-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Platform machine definition.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/memblock.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/memory.h>
+
+static void __init u300_reserve(void)
+{
+ /*
+ * U300 - This platform family can share physical memory
+ * between two ARM cpus, one running Linux and the other
+ * running another OS.
+ */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+ memblock_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
+static void __init u300_init_machine(void)
+{
+ u300_init_devices();
+}
+
+#ifdef CONFIG_MACH_U300_BS2X
+#define MACH_U300_STRING "Ericsson AB U300 S25/S26/B25/B26 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS330
+#define MACH_U300_STRING "Ericsson AB U330 S330/B330 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS335
+#define MACH_U300_STRING "Ericsson AB U335 S335/B335 Prototype Board"
+#endif
+
+#ifdef CONFIG_MACH_U300_BS365
+#define MACH_U300_STRING "Ericsson AB U365 S365/B365 Prototype Board"
+#endif
+
+MACHINE_START(U300, MACH_U300_STRING)
+ /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */
+ .boot_params = BOOT_PARAMS_OFFSET,
+ .map_io = u300_map_io,
+ .reserve = u300_reserve,
+ .init_irq = u300_init_irq,
+ .timer = &u300_timer,
+ .init_machine = u300_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
new file mode 100644
index 00000000..6ebdb0d0
--- /dev/null
+++ b/arch/arm/mach-ux500/Kconfig
@@ -0,0 +1,62 @@
+if ARCH_U8500
+
+config UX500_SOC_COMMON
+ bool
+ default y
+ select ARM_GIC
+ select HAS_MTU
+ select ARM_ERRATA_753970
+ select ARM_ERRATA_754322
+ select ARM_ERRATA_764369
+
+menu "Ux500 SoC"
+
+config UX500_SOC_DB5500
+ bool "DB5500"
+ select MFD_DB5500_PRCMU
+
+config UX500_SOC_DB8500
+ bool "DB8500"
+ select MFD_DB8500_PRCMU
+ select REGULATOR_DB8500_PRCMU
+
+endmenu
+
+menu "Ux500 target platform"
+
+config MACH_U8500
+ bool "U8500 Development platform"
+ depends on UX500_SOC_DB8500
+ select TPS6105X
+ help
+ Include support for the mop500 development platform.
+
+config MACH_U5500
+ bool "U5500 Development platform"
+ depends on UX500_SOC_DB5500
+ help
+ Include support for the U5500 development platform.
+endmenu
+
+config UX500_DEBUG_UART
+ int "Ux500 UART to use for low-level debug"
+ default 2
+ help
+ Choose the UART on which kernel low-level debug messages should be
+ output.
+
+config U5500_MODEM_IRQ
+ bool "Modem IRQ support"
+ depends on UX500_SOC_DB5500
+ default y
+ help
+ Add support for handling IRQ:s from modem side
+
+config U5500_MBOX
+ bool "Mailbox support"
+ depends on U5500_MODEM_IRQ
+ default y
+ help
+ Add support for U5500 mailbox communication with modem side
+
+endif
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
new file mode 100644
index 00000000..1694916e
--- /dev/null
+++ b/arch/arm/mach-ux500/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux kernel, U8500 machine.
+#
+
+obj-y := clock.o cpu.o devices.o devices-common.o \
+ id.o usb.o
+obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
+obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
+obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \
+ board-mop500-regulators.o \
+ board-mop500-uib.o board-mop500-stuib.o \
+ board-mop500-u8500uib.o \
+ board-mop500-pins.o
+obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
+obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o
+obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o
+
diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot
new file mode 100644
index 00000000..c7e75acf
--- /dev/null
+++ b/arch/arm/mach-ux500/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c
new file mode 100644
index 00000000..70cdbd60
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-pins.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <plat/pincfg.h>
+#include <mach/hardware.h>
+
+#include "pins-db8500.h"
+
+static pin_cfg_t mop500_pins_common[] = {
+ /* I2C */
+ GPIO147_I2C0_SCL,
+ GPIO148_I2C0_SDA,
+ GPIO16_I2C1_SCL,
+ GPIO17_I2C1_SDA,
+ GPIO10_I2C2_SDA,
+ GPIO11_I2C2_SCL,
+ GPIO229_I2C3_SDA,
+ GPIO230_I2C3_SCL,
+
+ /* MSP0 */
+ GPIO12_MSP0_TXD,
+ GPIO13_MSP0_TFS,
+ GPIO14_MSP0_TCK,
+ GPIO15_MSP0_RXD,
+
+ /* MSP2: HDMI */
+ GPIO193_MSP2_TXD,
+ GPIO194_MSP2_TCK,
+ GPIO195_MSP2_TFS,
+ GPIO196_MSP2_RXD | PIN_OUTPUT_LOW,
+
+ /* Touch screen INTERFACE */
+ GPIO84_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT1 */
+
+ /* STMPE1601/tc35893 keypad IRQ */
+ GPIO218_GPIO | PIN_INPUT_PULLUP,
+
+ /* MMC0 (MicroSD card) */
+ GPIO18_MC0_CMDDIR | PIN_OUTPUT_HIGH,
+ GPIO19_MC0_DAT0DIR | PIN_OUTPUT_HIGH,
+ GPIO20_MC0_DAT2DIR | PIN_OUTPUT_HIGH,
+
+ GPIO22_MC0_FBCLK | PIN_INPUT_NOPULL,
+ GPIO23_MC0_CLK | PIN_OUTPUT_LOW,
+ GPIO24_MC0_CMD | PIN_INPUT_PULLUP,
+ GPIO25_MC0_DAT0 | PIN_INPUT_PULLUP,
+ GPIO26_MC0_DAT1 | PIN_INPUT_PULLUP,
+ GPIO27_MC0_DAT2 | PIN_INPUT_PULLUP,
+ GPIO28_MC0_DAT3 | PIN_INPUT_PULLUP,
+
+ /* SDI1 (SDIO) */
+ GPIO208_MC1_CLK | PIN_OUTPUT_LOW,
+ GPIO209_MC1_FBCLK | PIN_INPUT_NOPULL,
+ GPIO210_MC1_CMD | PIN_INPUT_PULLUP,
+ GPIO211_MC1_DAT0 | PIN_INPUT_PULLUP,
+ GPIO212_MC1_DAT1 | PIN_INPUT_PULLUP,
+ GPIO213_MC1_DAT2 | PIN_INPUT_PULLUP,
+ GPIO214_MC1_DAT3 | PIN_INPUT_PULLUP,
+
+ /* MMC2 (On-board DATA INTERFACE eMMC) */
+ GPIO128_MC2_CLK | PIN_OUTPUT_LOW,
+ GPIO129_MC2_CMD | PIN_INPUT_PULLUP,
+ GPIO130_MC2_FBCLK | PIN_INPUT_NOPULL,
+ GPIO131_MC2_DAT0 | PIN_INPUT_PULLUP,
+ GPIO132_MC2_DAT1 | PIN_INPUT_PULLUP,
+ GPIO133_MC2_DAT2 | PIN_INPUT_PULLUP,
+ GPIO134_MC2_DAT3 | PIN_INPUT_PULLUP,
+ GPIO135_MC2_DAT4 | PIN_INPUT_PULLUP,
+ GPIO136_MC2_DAT5 | PIN_INPUT_PULLUP,
+ GPIO137_MC2_DAT6 | PIN_INPUT_PULLUP,
+ GPIO138_MC2_DAT7 | PIN_INPUT_PULLUP,
+
+ /* MMC4 (On-board STORAGE INTERFACE eMMC) */
+ GPIO197_MC4_DAT3 | PIN_INPUT_PULLUP,
+ GPIO198_MC4_DAT2 | PIN_INPUT_PULLUP,
+ GPIO199_MC4_DAT1 | PIN_INPUT_PULLUP,
+ GPIO200_MC4_DAT0 | PIN_INPUT_PULLUP,
+ GPIO201_MC4_CMD | PIN_INPUT_PULLUP,
+ GPIO202_MC4_FBCLK | PIN_INPUT_NOPULL,
+ GPIO203_MC4_CLK | PIN_OUTPUT_LOW,
+ GPIO204_MC4_DAT7 | PIN_INPUT_PULLUP,
+ GPIO205_MC4_DAT6 | PIN_INPUT_PULLUP,
+ GPIO206_MC4_DAT5 | PIN_INPUT_PULLUP,
+ GPIO207_MC4_DAT4 | PIN_INPUT_PULLUP,
+
+ /* SKE keypad */
+ GPIO153_KP_I7,
+ GPIO154_KP_I6,
+ GPIO155_KP_I5,
+ GPIO156_KP_I4,
+ GPIO157_KP_O7,
+ GPIO158_KP_O6,
+ GPIO159_KP_O5,
+ GPIO160_KP_O4,
+ GPIO161_KP_I3,
+ GPIO162_KP_I2,
+ GPIO163_KP_I1,
+ GPIO164_KP_I0,
+ GPIO165_KP_O3,
+ GPIO166_KP_O2,
+ GPIO167_KP_O1,
+ GPIO168_KP_O0,
+
+ /* UART */
+ /* uart-0 pins gpio configuration should be
+ * kept intact to prevent glitch in tx line
+ * when tty dev is opened. Later these pins
+ * are configured to uart mop500_pins_uart0
+ *
+ * It will be replaced with uart configuration
+ * once the issue is solved.
+ */
+ GPIO0_GPIO | PIN_INPUT_PULLUP,
+ GPIO1_GPIO | PIN_OUTPUT_HIGH,
+ GPIO2_GPIO | PIN_INPUT_PULLUP,
+ GPIO3_GPIO | PIN_OUTPUT_HIGH,
+
+ GPIO29_U2_RXD | PIN_INPUT_PULLUP,
+ GPIO30_U2_TXD | PIN_OUTPUT_HIGH,
+ GPIO31_U2_CTSn | PIN_INPUT_PULLUP,
+ GPIO32_U2_RTSn | PIN_OUTPUT_HIGH,
+
+ /* Display & HDMI HW sync */
+ GPIO68_LCD_VSI0 | PIN_INPUT_PULLUP,
+ GPIO69_LCD_VSI1 | PIN_INPUT_PULLUP,
+};
+
+static pin_cfg_t mop500_pins_default[] = {
+ /* SSP0 */
+ GPIO143_SSP0_CLK,
+ GPIO144_SSP0_FRM,
+ GPIO145_SSP0_RXD | PIN_PULL_DOWN,
+ GPIO146_SSP0_TXD,
+
+
+ GPIO217_GPIO | PIN_INPUT_PULLUP, /* TC35892 IRQ */
+
+ /* SDI0 (MicroSD card) */
+ GPIO21_MC0_DAT31DIR | PIN_OUTPUT_HIGH,
+
+ /* UART */
+ GPIO4_U1_RXD | PIN_INPUT_PULLUP,
+ GPIO5_U1_TXD | PIN_OUTPUT_HIGH,
+ GPIO6_U1_CTSn | PIN_INPUT_PULLUP,
+ GPIO7_U1_RTSn | PIN_OUTPUT_HIGH,
+};
+
+static pin_cfg_t mop500_pins_hrefv60[] = {
+ /* WLAN */
+ GPIO4_GPIO | PIN_INPUT_PULLUP,/* WLAN_IRQ */
+ GPIO85_GPIO | PIN_OUTPUT_LOW,/* WLAN_ENA */
+
+ /* XENON Flashgun INTERFACE */
+ GPIO6_IP_GPIO0 | PIN_INPUT_PULLUP,/* XENON_FLASH_ID */
+ GPIO7_IP_GPIO1 | PIN_INPUT_PULLUP,/* XENON_READY */
+ GPIO170_GPIO | PIN_OUTPUT_LOW, /* XENON_CHARGE */
+
+ /* Assistant LED INTERFACE */
+ GPIO21_GPIO | PIN_OUTPUT_LOW, /* XENON_EN1 */
+ GPIO64_IP_GPIO4 | PIN_OUTPUT_LOW, /* XENON_EN2 */
+
+ /* Magnetometer */
+ GPIO31_GPIO | PIN_INPUT_PULLUP, /* magnetometer_INT */
+ GPIO32_GPIO | PIN_INPUT_PULLDOWN, /* Magnetometer DRDY */
+
+ /* Display Interface */
+ GPIO65_GPIO | PIN_OUTPUT_LOW, /* DISP1 RST */
+ GPIO66_GPIO | PIN_OUTPUT_LOW, /* DISP2 RST */
+
+ /* Touch screen INTERFACE */
+ GPIO143_GPIO | PIN_OUTPUT_LOW,/*TOUCH_RST1 */
+
+ /* Touch screen INTERFACE 2 */
+ GPIO67_GPIO | PIN_INPUT_PULLUP, /* TOUCH_INT2 */
+ GPIO146_GPIO | PIN_OUTPUT_LOW,/*TOUCH_RST2 */
+
+ /* ETM_PTM_TRACE INTERFACE */
+ GPIO70_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA23 */
+ GPIO71_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA22 */
+ GPIO72_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA21 */
+ GPIO73_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA20 */
+ GPIO74_GPIO | PIN_OUTPUT_LOW,/* ETM_PTM_DATA19 */
+
+ /* NAHJ INTERFACE */
+ GPIO76_GPIO | PIN_OUTPUT_LOW,/* NAHJ_CTRL */
+ GPIO216_GPIO | PIN_OUTPUT_HIGH,/* NAHJ_CTRL_INV */
+
+ /* NFC INTERFACE */
+ GPIO77_GPIO | PIN_OUTPUT_LOW, /* NFC_ENA */
+ GPIO144_GPIO | PIN_INPUT_PULLDOWN, /* NFC_IRQ */
+ GPIO142_GPIO | PIN_OUTPUT_LOW, /* NFC_RESET */
+
+ /* Keyboard MATRIX INTERFACE */
+ GPIO90_MC5_CMD | PIN_OUTPUT_LOW, /* KP_O_1 */
+ GPIO87_MC5_DAT1 | PIN_OUTPUT_LOW, /* KP_O_2 */
+ GPIO86_MC5_DAT0 | PIN_OUTPUT_LOW, /* KP_O_3 */
+ GPIO96_KP_O6 | PIN_OUTPUT_LOW, /* KP_O_6 */
+ GPIO94_KP_O7 | PIN_OUTPUT_LOW, /* KP_O_7 */
+ GPIO93_MC5_DAT4 | PIN_INPUT_PULLUP, /* KP_I_0 */
+ GPIO89_MC5_DAT3 | PIN_INPUT_PULLUP, /* KP_I_2 */
+ GPIO88_MC5_DAT2 | PIN_INPUT_PULLUP, /* KP_I_3 */
+ GPIO91_GPIO | PIN_INPUT_PULLUP, /* FORCE_SENSING_INT */
+ GPIO92_GPIO | PIN_OUTPUT_LOW, /* FORCE_SENSING_RST */
+ GPIO97_GPIO | PIN_OUTPUT_LOW, /* FORCE_SENSING_WU */
+
+ /* DiPro Sensor Interface */
+ GPIO139_GPIO | PIN_INPUT_PULLUP, /* DIPRO_INT */
+
+ /* HAL SWITCH INTERFACE */
+ GPIO145_GPIO | PIN_INPUT_PULLDOWN,/* HAL_SW */
+
+ /* Audio Amplifier Interface */
+ GPIO149_GPIO | PIN_OUTPUT_LOW, /* VAUDIO_HF_EN */
+
+ /* GBF INTERFACE */
+ GPIO171_GPIO | PIN_OUTPUT_LOW, /* GBF_ENA_RESET */
+
+ /* MSP : HDTV INTERFACE */
+ GPIO192_GPIO | PIN_INPUT_PULLDOWN,
+
+ /* ACCELEROMETER_INTERFACE */
+ GPIO82_GPIO | PIN_INPUT_PULLUP, /* ACC_INT1 */
+ GPIO83_GPIO | PIN_INPUT_PULLUP, /* ACC_INT2 */
+
+ /* Proximity Sensor */
+ GPIO217_GPIO | PIN_INPUT_PULLUP,
+
+
+};
+
+void __init mop500_pins_init(void)
+{
+ nmk_config_pins(mop500_pins_common,
+ ARRAY_SIZE(mop500_pins_common));
+ if (machine_is_hrefv60())
+ nmk_config_pins(mop500_pins_hrefv60,
+ ARRAY_SIZE(mop500_pins_hrefv60));
+ else
+ nmk_config_pins(mop500_pins_default,
+ ARRAY_SIZE(mop500_pins_default));
+}
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c
new file mode 100644
index 00000000..9ed0f90c
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-regulators.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Authors: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Bengt Jonsson <bengt.g.jonsson@stericsson.com>
+ *
+ * MOP500 board specific initialization for regulators
+ */
+#include <linux/kernel.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/ab8500.h>
+#include "board-mop500-regulators.h"
+
+/*
+ * TPS61052 regulator
+ */
+static struct regulator_consumer_supply tps61052_vaudio_consumers[] = {
+ /*
+ * Boost converter supply to raise voltage on audio speaker, this
+ * is actually connected to three pins, VInVhfL (left amplifier)
+ * VInVhfR (right amplifier) and VIntDClassInt - all three must
+ * be connected to the same voltage.
+ */
+ REGULATOR_SUPPLY("vintdclassint", "ab8500-codec.0"),
+};
+
+struct regulator_init_data tps61052_regulator = {
+ .constraints = {
+ .name = "vaudio-hf",
+ .min_uV = 4500000,
+ .max_uV = 4500000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps61052_vaudio_consumers),
+ .consumer_supplies = tps61052_vaudio_consumers,
+};
+
+static struct regulator_consumer_supply ab8500_vaux1_consumers[] = {
+ /* External displays, connector on board 2v5 power supply */
+ REGULATOR_SUPPLY("vaux12v5", "mcde.0"),
+ /* SFH7741 proximity sensor */
+ REGULATOR_SUPPLY("vcc", "gpio-keys.0"),
+ /* BH1780GLS ambient light sensor */
+ REGULATOR_SUPPLY("vcc", "2-0029"),
+ /* lsm303dlh accelerometer */
+ REGULATOR_SUPPLY("vdd", "3-0018"),
+ /* lsm303dlh magnetometer */
+ REGULATOR_SUPPLY("vdd", "3-001e"),
+ /* Rohm BU21013 Touchscreen devices */
+ REGULATOR_SUPPLY("avdd", "3-005c"),
+ REGULATOR_SUPPLY("avdd", "3-005d"),
+ /* Synaptics RMI4 Touchscreen device */
+ REGULATOR_SUPPLY("vdd", "3-004b"),
+};
+
+static struct regulator_consumer_supply ab8500_vaux2_consumers[] = {
+ /* On-board eMMC power */
+ REGULATOR_SUPPLY("vmmc", "sdi4"),
+ /* AB8500 audio codec */
+ REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vaux3_consumers[] = {
+ /* External MMC slot power */
+ REGULATOR_SUPPLY("vmmc", "sdi0"),
+};
+
+static struct regulator_consumer_supply ab8500_vtvout_consumers[] = {
+ /* TV-out DENC supply */
+ REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"),
+ /* Internal general-purpose ADC */
+ REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vintcore_consumers[] = {
+ /* SoC core supply, no device */
+ REGULATOR_SUPPLY("v-intcore", NULL),
+ /* USB Transciever */
+ REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"),
+};
+
+static struct regulator_consumer_supply ab8500_vana_consumers[] = {
+ /* External displays, connector on board, 1v8 power supply */
+ REGULATOR_SUPPLY("vsmps2", "mcde.0"),
+};
+
+/* ab8500 regulator register initialization */
+struct ab8500_regulator_reg_init
+ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = {
+ /*
+ * VanaRequestCtrl = HP/LP depending on VxRequest
+ * VextSupply1RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00),
+ /*
+ * VextSupply2RequestCtrl = HP/LP depending on VxRequest
+ * VextSupply3RequestCtrl = HP/LP depending on VxRequest
+ * Vaux1RequestCtrl = HP/LP depending on VxRequest
+ * Vaux2RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00),
+ /*
+ * Vaux3RequestCtrl = HP/LP depending on VxRequest
+ * SwHPReq = Control through SWValid disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00),
+ /*
+ * VanaSysClkReq1HPValid = disabled
+ * Vaux1SysClkReq1HPValid = disabled
+ * Vaux2SysClkReq1HPValid = disabled
+ * Vaux3SysClkReq1HPValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x00),
+ /*
+ * VextSupply1SysClkReq1HPValid = disabled
+ * VextSupply2SysClkReq1HPValid = disabled
+ * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40),
+ /*
+ * VanaHwHPReq1Valid = disabled
+ * Vaux1HwHPreq1Valid = disabled
+ * Vaux2HwHPReq1Valid = disabled
+ * Vaux3HwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00),
+ /*
+ * VextSupply1HwHPReq1Valid = disabled
+ * VextSupply2HwHPReq1Valid = disabled
+ * VextSupply3HwHPReq1Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00),
+ /*
+ * VanaHwHPReq2Valid = disabled
+ * Vaux1HwHPReq2Valid = disabled
+ * Vaux2HwHPReq2Valid = disabled
+ * Vaux3HwHPReq2Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00),
+ /*
+ * VextSupply1HwHPReq2Valid = disabled
+ * VextSupply2HwHPReq2Valid = disabled
+ * VextSupply3HwHPReq2Valid = HWReq2 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04),
+ /*
+ * VanaSwHPReqValid = disabled
+ * Vaux1SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00),
+ /*
+ * Vaux2SwHPReqValid = disabled
+ * Vaux3SwHPReqValid = disabled
+ * VextSupply1SwHPReqValid = disabled
+ * VextSupply2SwHPReqValid = disabled
+ * VextSupply3SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00),
+ /*
+ * SysClkReq2Valid1 = SysClkReq2 controlled
+ * SysClkReq3Valid1 = disabled
+ * SysClkReq4Valid1 = SysClkReq4 controlled
+ * SysClkReq5Valid1 = disabled
+ * SysClkReq6Valid1 = SysClkReq6 controlled
+ * SysClkReq7Valid1 = disabled
+ * SysClkReq8Valid1 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a),
+ /*
+ * SysClkReq2Valid2 = disabled
+ * SysClkReq3Valid2 = disabled
+ * SysClkReq4Valid2 = disabled
+ * SysClkReq5Valid2 = disabled
+ * SysClkReq6Valid2 = SysClkReq6 controlled
+ * SysClkReq7Valid2 = disabled
+ * SysClkReq8Valid2 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20),
+ /*
+ * VTVoutEna = disabled
+ * Vintcore12Ena = disabled
+ * Vintcore12Sel = 1.25 V
+ * Vintcore12LP = inactive (HP)
+ * VTVoutLP = inactive (HP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10),
+ /*
+ * VaudioEna = disabled
+ * VdmicEna = disabled
+ * Vamic1Ena = disabled
+ * Vamic2Ena = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00),
+ /*
+ * Vamic1_dzout = high-Z when Vamic1 is disabled
+ * Vamic2_dzout = high-Z when Vamic2 is disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00),
+ /*
+ * VPll = Hw controlled
+ * VanaRegu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02),
+ /*
+ * VrefDDREna = disabled
+ * VrefDDRSleepMode = inactive (no pulldown)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00),
+ /*
+ * VextSupply1Regu = HW control
+ * VextSupply2Regu = HW control
+ * VextSupply3Regu = HW control
+ * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0
+ * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0
+ */
+ INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a),
+ /*
+ * Vaux1Regu = force HP
+ * Vaux2Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01),
+ /*
+ * Vaux3regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x00),
+ /*
+ * Vsmps1 = 1.15V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24),
+ /*
+ * Vaux1Sel = 2.5 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08),
+ /*
+ * Vaux2Sel = 2.9 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d),
+ /*
+ * Vaux3Sel = 2.91 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07),
+ /*
+ * VextSupply12LP = disabled (no LP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00),
+ /*
+ * Vaux1Disch = short discharge time
+ * Vaux2Disch = short discharge time
+ * Vaux3Disch = short discharge time
+ * Vintcore12Disch = short discharge time
+ * VTVoutDisch = short discharge time
+ * VaudioDisch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00),
+ /*
+ * VanaDisch = short discharge time
+ * VdmicPullDownEna = pulldown disabled when Vdmic is disabled
+ * VdmicDisch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00),
+};
+
+/* AB8500 regulators */
+struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
+ /* supplies to the display/camera */
+ [AB8500_LDO_AUX1] = {
+ .constraints = {
+ .name = "V-DISPLAY",
+ .min_uV = 2500000,
+ .max_uV = 2900000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ .boot_on = 1, /* must be on for display */
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers),
+ .consumer_supplies = ab8500_vaux1_consumers,
+ },
+ /* supplies to the on-board eMMC */
+ [AB8500_LDO_AUX2] = {
+ .constraints = {
+ .name = "V-eMMC1",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers),
+ .consumer_supplies = ab8500_vaux2_consumers,
+ },
+ /* supply for VAUX3, supplies to SDcard slots */
+ [AB8500_LDO_AUX3] = {
+ .constraints = {
+ .name = "V-MMC-SD",
+ .min_uV = 1100000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers),
+ .consumer_supplies = ab8500_vaux3_consumers,
+ },
+ /* supply for tvout, gpadc, TVOUT LDO */
+ [AB8500_LDO_TVOUT] = {
+ .constraints = {
+ .name = "V-TVOUT",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vtvout_consumers),
+ .consumer_supplies = ab8500_vtvout_consumers,
+ },
+ /* supply for ab8500-vaudio, VAUDIO LDO */
+ [AB8500_LDO_AUDIO] = {
+ .constraints = {
+ .name = "V-AUD",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ },
+ /* supply for v-anamic1 VAMic1-LDO */
+ [AB8500_LDO_ANAMIC1] = {
+ .constraints = {
+ .name = "V-AMIC1",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ },
+ /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */
+ [AB8500_LDO_ANAMIC2] = {
+ .constraints = {
+ .name = "V-AMIC2",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ },
+ /* supply for v-dmic, VDMIC LDO */
+ [AB8500_LDO_DMIC] = {
+ .constraints = {
+ .name = "V-DMIC",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ },
+ /* supply for v-intcore12, VINTCORE12 LDO */
+ [AB8500_LDO_INTCORE] = {
+ .constraints = {
+ .name = "V-INTCORE",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers),
+ .consumer_supplies = ab8500_vintcore_consumers,
+ },
+ /* supply for U8500 CSI/DSI, VANA LDO */
+ [AB8500_LDO_ANA] = {
+ .constraints = {
+ .name = "V-CSI/DSI",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers),
+ .consumer_supplies = ab8500_vana_consumers,
+ },
+};
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h
new file mode 100644
index 00000000..94992158
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-regulators.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
+ *
+ * MOP500 board specific initialization for regulators
+ */
+
+#ifndef __BOARD_MOP500_REGULATORS_H
+#define __BOARD_MOP500_REGULATORS_H
+
+#include <linux/regulator/machine.h>
+#include <linux/regulator/ab8500.h>
+
+extern struct ab8500_regulator_reg_init
+ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS];
+extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS];
+extern struct regulator_init_data tps61052_regulator;
+
+#endif
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
new file mode 100644
index 00000000..7c6cb4fa
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Hanumath Prasad <hanumath.prasad@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/mmc/host.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <plat/ste_dma40.h>
+#include <mach/devices.h>
+#include <mach/hardware.h>
+
+#include "devices-db8500.h"
+#include "board-mop500.h"
+#include "ste-dma40-db8500.h"
+
+/*
+ * SDI 0 (MicroSD slot)
+ */
+
+/* MMCIPOWER bits */
+#define MCI_DATA2DIREN (1 << 2)
+#define MCI_CMDDIREN (1 << 3)
+#define MCI_DATA0DIREN (1 << 4)
+#define MCI_DATA31DIREN (1 << 5)
+#define MCI_FBCLKEN (1 << 7)
+
+static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd,
+ unsigned char power_mode)
+{
+ if (power_mode == MMC_POWER_UP)
+ gpio_set_value_cansleep(GPIO_SDMMC_EN, 1);
+ else if (power_mode == MMC_POWER_OFF)
+ gpio_set_value_cansleep(GPIO_SDMMC_EN, 0);
+
+ return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN |
+ MCI_DATA2DIREN | MCI_DATA31DIREN;
+}
+
+#ifdef CONFIG_STE_DMA40
+struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV29_SD_MM0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+
+static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV29_SD_MM0_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+#endif
+
+static struct mmci_platform_data mop500_sdi0_data = {
+ .vdd_handler = mop500_sdi0_vdd_handler,
+ .ocr_mask = MMC_VDD_29_30,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA,
+ .gpio_wp = -1,
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &mop500_sdi0_dma_cfg_rx,
+ .dma_tx_param = &mop500_sdi0_dma_cfg_tx,
+#endif
+};
+
+/* GPIO pins used by the sdi0 level shifter */
+static int sdi0_en = -1;
+static int sdi0_vsel = -1;
+
+static void sdi0_configure(void)
+{
+ int ret;
+
+ ret = gpio_request(sdi0_en, "level shifter enable");
+ if (!ret)
+ ret = gpio_request(sdi0_vsel,
+ "level shifter 1v8-3v select");
+
+ if (ret) {
+ pr_warning("unable to config sdi0 gpios for level shifter.\n");
+ return;
+ }
+
+ /* Select the default 2.9V and enable level shifter */
+ gpio_direction_output(sdi0_vsel, 0);
+ gpio_direction_output(sdi0_en, 1);
+
+ /* Add the device, force v2 to subrevision 1 */
+ if (cpu_is_u8500v2())
+ db8500_add_sdi0(&mop500_sdi0_data, 0x10480180);
+ else
+ db8500_add_sdi0(&mop500_sdi0_data, 0);
+}
+
+void mop500_sdi_tc35892_init(void)
+{
+ mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD;
+ sdi0_en = GPIO_SDMMC_EN;
+ sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL;
+ sdi0_configure();
+}
+
+/*
+ * SDI 2 (POP eMMC, not on DB8500ed)
+ */
+
+#ifdef CONFIG_STE_DMA40
+struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV28_SD_MM2_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+
+static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+#endif
+
+static struct mmci_platform_data mop500_sdi2_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &mop500_sdi2_dma_cfg_rx,
+ .dma_tx_param = &mop500_sdi2_dma_cfg_tx,
+#endif
+};
+
+/*
+ * SDI 4 (on-board eMMC)
+ */
+
+#ifdef CONFIG_STE_DMA40
+struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV42_SD_MM4_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+
+static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV42_SD_MM4_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+#endif
+
+static struct mmci_platform_data mop500_sdi4_data = {
+ .ocr_mask = MMC_VDD_29_30,
+ .f_max = 100000000,
+ .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &mop500_sdi4_dma_cfg_rx,
+ .dma_tx_param = &mop500_sdi4_dma_cfg_tx,
+#endif
+};
+
+void __init mop500_sdi_init(void)
+{
+ u32 periphid = 0;
+
+ /* v2 has a new version of this block that need to be forced */
+ if (cpu_is_u8500v2())
+ periphid = 0x10480180;
+ /* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */
+ if (!cpu_is_u8500v10())
+ mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
+ db8500_add_sdi2(&mop500_sdi2_data, periphid);
+
+ /* On-board eMMC */
+ db8500_add_sdi4(&mop500_sdi4_data, periphid);
+
+ if (machine_is_hrefv60()) {
+ mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
+ sdi0_en = HREFV60_SDMMC_EN_GPIO;
+ sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO;
+ sdi0_configure();
+ }
+ /*
+ * On boards with the TC35892 GPIO expander, sdi0 will finally
+ * be added when the TC35892 initializes and calls
+ * mop500_sdi_tc35892_init() above.
+ */
+}
diff --git a/arch/arm/mach-ux500/board-mop500-stuib.c b/arch/arm/mach-ux500/board-mop500-stuib.c
new file mode 100644
index 00000000..8c979770
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-stuib.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mfd/stmpe.h>
+#include <linux/input/bu21013.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/input/matrix_keypad.h>
+#include <asm/mach-types.h>
+
+#include "board-mop500.h"
+
+/* STMPE/SKE keypad use this key layout */
+static const unsigned int mop500_keymap[] = {
+ KEY(2, 5, KEY_END),
+ KEY(4, 1, KEY_POWER),
+ KEY(3, 5, KEY_VOLUMEDOWN),
+ KEY(1, 3, KEY_3),
+ KEY(5, 2, KEY_RIGHT),
+ KEY(5, 0, KEY_9),
+
+ KEY(0, 5, KEY_MENU),
+ KEY(7, 6, KEY_ENTER),
+ KEY(4, 5, KEY_0),
+ KEY(6, 7, KEY_2),
+ KEY(3, 4, KEY_UP),
+ KEY(3, 3, KEY_DOWN),
+
+ KEY(6, 4, KEY_SEND),
+ KEY(6, 2, KEY_BACK),
+ KEY(4, 2, KEY_VOLUMEUP),
+ KEY(5, 5, KEY_1),
+ KEY(4, 3, KEY_LEFT),
+ KEY(3, 2, KEY_7),
+};
+
+static const struct matrix_keymap_data mop500_keymap_data = {
+ .keymap = mop500_keymap,
+ .keymap_size = ARRAY_SIZE(mop500_keymap),
+};
+/*
+ * STMPE1601
+ */
+static struct stmpe_keypad_platform_data stmpe1601_keypad_data = {
+ .debounce_ms = 64,
+ .scan_count = 8,
+ .no_autorepeat = true,
+ .keymap_data = &mop500_keymap_data,
+};
+
+static struct stmpe_platform_data stmpe1601_data = {
+ .id = 1,
+ .blocks = STMPE_BLOCK_KEYPAD,
+ .irq_trigger = IRQF_TRIGGER_FALLING,
+ .irq_base = MOP500_STMPE1601_IRQ(0),
+ .keypad = &stmpe1601_keypad_data,
+ .autosleep = true,
+ .autosleep_timeout = 1024,
+};
+
+static struct i2c_board_info __initdata mop500_i2c0_devices_stuib[] = {
+ {
+ I2C_BOARD_INFO("stmpe1601", 0x40),
+ .irq = NOMADIK_GPIO_TO_IRQ(218),
+ .platform_data = &stmpe1601_data,
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+/*
+ * BU21013 ROHM touchscreen interface on the STUIBs
+ */
+
+/* tracks number of bu21013 devices being enabled */
+static int bu21013_devices;
+
+#define TOUCH_GPIO_PIN 84
+
+#define TOUCH_XMAX 384
+#define TOUCH_YMAX 704
+
+#define PRCMU_CLOCK_OCR 0x1CC
+#define TSC_EXT_CLOCK_9_6MHZ 0x840000
+
+/**
+ * bu21013_gpio_board_init : configures the touch panel.
+ * @reset_pin: reset pin number
+ * This function can be used to configures
+ * the voltage and reset the touch panel controller.
+ */
+static int bu21013_gpio_board_init(int reset_pin)
+{
+ int retval = 0;
+
+ bu21013_devices++;
+ if (bu21013_devices == 1) {
+ retval = gpio_request(reset_pin, "touchp_reset");
+ if (retval) {
+ printk(KERN_ERR "Unable to request gpio reset_pin");
+ return retval;
+ }
+ retval = gpio_direction_output(reset_pin, 1);
+ if (retval < 0) {
+ printk(KERN_ERR "%s: gpio direction failed\n",
+ __func__);
+ return retval;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * bu21013_gpio_board_exit : deconfigures the touch panel controller
+ * @reset_pin: reset pin number
+ * This function can be used to deconfigures the chip selection
+ * for touch panel controller.
+ */
+static int bu21013_gpio_board_exit(int reset_pin)
+{
+ int retval = 0;
+
+ if (bu21013_devices == 1) {
+ retval = gpio_direction_output(reset_pin, 0);
+ if (retval < 0) {
+ printk(KERN_ERR "%s: gpio direction failed\n",
+ __func__);
+ return retval;
+ }
+ gpio_set_value(reset_pin, 0);
+ }
+ bu21013_devices--;
+
+ return retval;
+}
+
+/**
+ * bu21013_read_pin_val : get the interrupt pin value
+ * This function can be used to get the interrupt pin value for touch panel
+ * controller.
+ */
+static int bu21013_read_pin_val(void)
+{
+ return gpio_get_value(TOUCH_GPIO_PIN);
+}
+
+static struct bu21013_platform_device tsc_plat_device = {
+ .cs_en = bu21013_gpio_board_init,
+ .cs_dis = bu21013_gpio_board_exit,
+ .irq_read_val = bu21013_read_pin_val,
+ .irq = NOMADIK_GPIO_TO_IRQ(TOUCH_GPIO_PIN),
+ .touch_x_max = TOUCH_XMAX,
+ .touch_y_max = TOUCH_YMAX,
+ .ext_clk = false,
+ .x_flip = false,
+ .y_flip = true,
+};
+
+static struct bu21013_platform_device tsc_plat2_device = {
+ .cs_en = bu21013_gpio_board_init,
+ .cs_dis = bu21013_gpio_board_exit,
+ .irq_read_val = bu21013_read_pin_val,
+ .irq = NOMADIK_GPIO_TO_IRQ(TOUCH_GPIO_PIN),
+ .touch_x_max = TOUCH_XMAX,
+ .touch_y_max = TOUCH_YMAX,
+ .ext_clk = false,
+ .x_flip = false,
+ .y_flip = true,
+};
+
+static struct i2c_board_info __initdata u8500_i2c3_devices_stuib[] = {
+ {
+ I2C_BOARD_INFO("bu21013_tp", 0x5C),
+ .platform_data = &tsc_plat_device,
+ },
+ {
+ I2C_BOARD_INFO("bu21013_tp", 0x5D),
+ .platform_data = &tsc_plat2_device,
+ },
+
+};
+
+void __init mop500_stuib_init(void)
+{
+ if (machine_is_hrefv60()) {
+ tsc_plat_device.cs_pin = HREFV60_TOUCH_RST_GPIO;
+ tsc_plat2_device.cs_pin = HREFV60_TOUCH_RST_GPIO;
+ } else {
+ tsc_plat_device.cs_pin = GPIO_BU21013_CS;
+ tsc_plat2_device.cs_pin = GPIO_BU21013_CS;
+
+ }
+
+ mop500_uib_i2c_add(0, mop500_i2c0_devices_stuib,
+ ARRAY_SIZE(mop500_i2c0_devices_stuib));
+
+ mop500_uib_i2c_add(3, u8500_i2c3_devices_stuib,
+ ARRAY_SIZE(u8500_i2c3_devices_stuib));
+}
diff --git a/arch/arm/mach-ux500/board-mop500-u8500uib.c b/arch/arm/mach-ux500/board-mop500-u8500uib.c
new file mode 100644
index 00000000..d8a8734a
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-u8500uib.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Board data for the U8500 UIB, also known as the New UIB
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/tc3589x.h>
+#include <linux/input/matrix_keypad.h>
+#include <../drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h>
+
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+#include "board-mop500.h"
+
+/*
+ * Synaptics RMI4 touchscreen interface on the U8500 UIB
+ */
+
+/*
+ * Descriptor structure.
+ * Describes the number of i2c devices on the bus that speak RMI.
+ */
+static struct synaptics_rmi4_platform_data rmi4_i2c_dev_platformdata = {
+ .irq_number = NOMADIK_GPIO_TO_IRQ(84),
+ .irq_type = (IRQF_TRIGGER_FALLING | IRQF_SHARED),
+ .x_flip = false,
+ .y_flip = true,
+ .regulator_en = false,
+};
+
+static struct i2c_board_info __initdata mop500_i2c3_devices_u8500[] = {
+ {
+ I2C_BOARD_INFO("synaptics_rmi4_i2c", 0x4B),
+ .platform_data = &rmi4_i2c_dev_platformdata,
+ },
+};
+
+/*
+ * TC35893
+ */
+static const unsigned int u8500_keymap[] = {
+ KEY(3, 1, KEY_END),
+ KEY(4, 1, KEY_POWER),
+ KEY(6, 4, KEY_VOLUMEDOWN),
+ KEY(4, 2, KEY_EMAIL),
+ KEY(3, 3, KEY_RIGHT),
+ KEY(2, 5, KEY_BACKSPACE),
+
+ KEY(6, 7, KEY_MENU),
+ KEY(5, 0, KEY_ENTER),
+ KEY(4, 3, KEY_0),
+ KEY(3, 4, KEY_DOT),
+ KEY(5, 2, KEY_UP),
+ KEY(3, 5, KEY_DOWN),
+
+ KEY(4, 5, KEY_SEND),
+ KEY(0, 5, KEY_BACK),
+ KEY(6, 2, KEY_VOLUMEUP),
+ KEY(1, 3, KEY_SPACE),
+ KEY(7, 6, KEY_LEFT),
+ KEY(5, 5, KEY_SEARCH),
+};
+
+static struct matrix_keymap_data u8500_keymap_data = {
+ .keymap = u8500_keymap,
+ .keymap_size = ARRAY_SIZE(u8500_keymap),
+};
+
+static struct tc3589x_keypad_platform_data tc35893_data = {
+ .krow = TC_KPD_ROWS,
+ .kcol = TC_KPD_COLUMNS,
+ .debounce_period = TC_KPD_DEBOUNCE_PERIOD,
+ .settle_time = TC_KPD_SETTLE_TIME,
+ .irqtype = IRQF_TRIGGER_FALLING,
+ .enable_wakeup = true,
+ .keymap_data = &u8500_keymap_data,
+ .no_autorepeat = true,
+};
+
+static struct tc3589x_platform_data tc3589x_keypad_data = {
+ .block = TC3589x_BLOCK_KEYPAD,
+ .keypad = &tc35893_data,
+ .irq_base = MOP500_EGPIO_IRQ_BASE,
+};
+
+static struct i2c_board_info __initdata mop500_i2c0_devices_u8500[] = {
+ {
+ I2C_BOARD_INFO("tc3589x", 0x44),
+ .platform_data = &tc3589x_keypad_data,
+ .irq = NOMADIK_GPIO_TO_IRQ(218),
+ .flags = I2C_CLIENT_WAKE,
+ },
+};
+
+
+void __init mop500_u8500uib_init(void)
+{
+ mop500_uib_i2c_add(3, mop500_i2c3_devices_u8500,
+ ARRAY_SIZE(mop500_i2c3_devices_u8500));
+
+ mop500_uib_i2c_add(0, mop500_i2c0_devices_u8500,
+ ARRAY_SIZE(mop500_i2c0_devices_u8500));
+
+}
diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c
new file mode 100644
index 00000000..69cce41f
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-uib.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#define pr_fmt(fmt) "mop500-uib: " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+#include <mach/hardware.h>
+#include "board-mop500.h"
+
+enum mop500_uib {
+ STUIB,
+ U8500UIB,
+};
+
+struct uib {
+ const char *name;
+ const char *option;
+ void (*init)(void);
+};
+
+static struct __initdata uib mop500_uibs[] = {
+ [STUIB] = {
+ .name = "ST-UIB",
+ .option = "stuib",
+ .init = mop500_stuib_init,
+ },
+ [U8500UIB] = {
+ .name = "U8500-UIB",
+ .option = "u8500uib",
+ .init = mop500_u8500uib_init,
+ },
+};
+
+static struct uib *mop500_uib;
+
+static int __init mop500_uib_setup(char *str)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mop500_uibs); i++) {
+ struct uib *uib = &mop500_uibs[i];
+
+ if (!strcmp(str, uib->option)) {
+ mop500_uib = uib;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(mop500_uibs))
+ pr_err("invalid uib= option (%s)\n", str);
+
+ return 1;
+}
+__setup("uib=", mop500_uib_setup);
+
+/*
+ * The UIBs are detected after the I2C host controllers are registered, so
+ * i2c_register_board_info() can't be used.
+ */
+void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
+ unsigned n)
+{
+ struct i2c_adapter *adap;
+ struct i2c_client *client;
+ int i;
+
+ adap = i2c_get_adapter(busnum);
+ if (!adap) {
+ pr_err("failed to get adapter i2c%d\n", busnum);
+ return;
+ }
+
+ for (i = 0; i < n; i++) {
+ client = i2c_new_device(adap, &info[i]);
+ if (!client)
+ pr_err("failed to register %s to i2c%d\n",
+ info[i].type, busnum);
+ }
+
+ i2c_put_adapter(adap);
+}
+
+static void __init __mop500_uib_init(struct uib *uib, const char *why)
+{
+ pr_info("%s (%s)\n", uib->name, why);
+ uib->init();
+}
+
+/*
+ * Detect the UIB attached based on the presence or absence of i2c devices.
+ */
+static int __init mop500_uib_init(void)
+{
+ struct uib *uib = mop500_uib;
+ struct i2c_adapter *i2c0;
+ int ret;
+
+ if (!cpu_is_u8500())
+ return -ENODEV;
+
+ if (uib) {
+ __mop500_uib_init(uib, "from uib= boot argument");
+ return 0;
+ }
+
+ i2c0 = i2c_get_adapter(0);
+ if (!i2c0) {
+ __mop500_uib_init(&mop500_uibs[STUIB],
+ "fallback, could not get i2c0");
+ return -ENODEV;
+ }
+
+ /* U8500-UIB has the TC35893 at 0x44 on I2C0, the ST-UIB doesn't. */
+ ret = i2c_smbus_xfer(i2c0, 0x44, 0, I2C_SMBUS_WRITE, 0,
+ I2C_SMBUS_QUICK, NULL);
+ i2c_put_adapter(i2c0);
+
+ if (ret == 0)
+ uib = &mop500_uibs[U8500UIB];
+ else
+ uib = &mop500_uibs[STUIB];
+
+ __mop500_uib_init(uib, "detected");
+
+ return 0;
+}
+
+module_init(mop500_uib_init);
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
new file mode 100644
index 00000000..2a08c07d
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl022.h>
+#include <linux/amba/serial.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/ab8500.h>
+#include <linux/regulator/ab8500.h>
+#include <linux/mfd/tc3589x.h>
+#include <linux/mfd/tps6105x.h>
+#include <linux/mfd/ab8500/gpio.h>
+#include <linux/leds-lp5521.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+#include <linux/delay.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/i2c.h>
+#include <plat/ste_dma40.h>
+#include <plat/pincfg.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+#include <mach/irqs.h>
+
+#include "pins-db8500.h"
+#include "ste-dma40-db8500.h"
+#include "devices-db8500.h"
+#include "board-mop500.h"
+#include "board-mop500-regulators.h"
+
+static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
+ .gpio_base = MOP500_AB8500_GPIO(0),
+ .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
+ /* config_reg is the initial configuration of ab8500 pins.
+ * The pins can be configured as GPIO or alt functions based
+ * on value present in GpioSel1 to GpioSel6 and AlternatFunction
+ * register. This is the array of 7 configuration settings.
+ * One has to compile time decide these settings. Below is the
+ * explanation of these setting
+ * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
+ * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
+ * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
+ * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
+ * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
+ * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
+ * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
+ * as GPIO then this register selectes the alternate fucntions
+ */
+ .config_reg = {0x00, 0x1E, 0x80, 0x01,
+ 0x7A, 0x00, 0x00},
+};
+
+static struct ab8500_platform_data ab8500_platdata = {
+ .irq_base = MOP500_AB8500_IRQ_BASE,
+ .regulator_reg_init = ab8500_regulator_reg_init,
+ .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init),
+ .regulator = ab8500_regulators,
+ .num_regulator = ARRAY_SIZE(ab8500_regulators),
+ .gpio = &ab8500_gpio_pdata,
+};
+
+static struct resource ab8500_resources[] = {
+ [0] = {
+ .start = IRQ_DB8500_AB8500,
+ .end = IRQ_DB8500_AB8500,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device ab8500_device = {
+ .name = "ab8500-i2c",
+ .id = 0,
+ .dev = {
+ .platform_data = &ab8500_platdata,
+ },
+ .num_resources = 1,
+ .resource = ab8500_resources,
+};
+
+/*
+ * TPS61052
+ */
+
+static struct tps6105x_platform_data mop500_tps61052_data = {
+ .mode = TPS6105X_MODE_VOLTAGE,
+ .regulator_data = &tps61052_regulator,
+};
+
+/*
+ * TC35892
+ */
+
+static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base)
+{
+ mop500_sdi_tc35892_init();
+}
+
+static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = {
+ .gpio_base = MOP500_EGPIO(0),
+ .setup = mop500_tc35892_init,
+};
+
+static struct tc3589x_platform_data mop500_tc35892_data = {
+ .block = TC3589x_BLOCK_GPIO,
+ .gpio = &mop500_tc35892_gpio_data,
+ .irq_base = MOP500_EGPIO_IRQ_BASE,
+};
+
+static struct lp5521_led_config lp5521_pri_led[] = {
+ [0] = {
+ .chan_nr = 0,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+ [1] = {
+ .chan_nr = 1,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+ [2] = {
+ .chan_nr = 2,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+};
+
+static struct lp5521_platform_data __initdata lp5521_pri_data = {
+ .label = "lp5521_pri",
+ .led_config = &lp5521_pri_led[0],
+ .num_channels = 3,
+ .clock_mode = LP5521_CLOCK_EXT,
+};
+
+static struct lp5521_led_config lp5521_sec_led[] = {
+ [0] = {
+ .chan_nr = 0,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+ [1] = {
+ .chan_nr = 1,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+ [2] = {
+ .chan_nr = 2,
+ .led_current = 0x2f,
+ .max_current = 0x5f,
+ },
+};
+
+static struct lp5521_platform_data __initdata lp5521_sec_data = {
+ .label = "lp5521_sec",
+ .led_config = &lp5521_sec_led[0],
+ .num_channels = 3,
+ .clock_mode = LP5521_CLOCK_EXT,
+};
+
+static struct i2c_board_info __initdata mop500_i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("tc3589x", 0x42),
+ .irq = NOMADIK_GPIO_TO_IRQ(217),
+ .platform_data = &mop500_tc35892_data,
+ },
+ /* I2C0 devices only available prior to HREFv60 */
+ {
+ I2C_BOARD_INFO("tps61052", 0x33),
+ .platform_data = &mop500_tps61052_data,
+ },
+};
+
+#define NUM_PRE_V60_I2C0_DEVICES 1
+
+static struct i2c_board_info __initdata mop500_i2c2_devices[] = {
+ {
+ /* lp5521 LED driver, 1st device */
+ I2C_BOARD_INFO("lp5521", 0x33),
+ .platform_data = &lp5521_pri_data,
+ },
+ {
+ /* lp5521 LED driver, 2st device */
+ I2C_BOARD_INFO("lp5521", 0x34),
+ .platform_data = &lp5521_sec_data,
+ },
+ {
+ /* Light sensor Rohm BH1780GLI */
+ I2C_BOARD_INFO("bh1780", 0x29),
+ },
+};
+
+#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, t_out, _sm) \
+static struct nmk_i2c_controller u8500_i2c##id##_data = { \
+ /* \
+ * slave data setup time, which is \
+ * 250 ns,100ns,10ns which is 14,6,2 \
+ * respectively for a 48 Mhz \
+ * i2c clock \
+ */ \
+ .slsu = _slsu, \
+ /* Tx FIFO threshold */ \
+ .tft = _tft, \
+ /* Rx FIFO threshold */ \
+ .rft = _rft, \
+ /* std. mode operation */ \
+ .clk_freq = clk, \
+ /* Slave response timeout(ms) */\
+ .timeout = t_out, \
+ .sm = _sm, \
+}
+
+/*
+ * The board uses 4 i2c controllers, initialize all of
+ * them with slave data setup time of 250 ns,
+ * Tx & Rx FIFO threshold values as 8 and standard
+ * mode of operation
+ */
+U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+
+static void __init mop500_i2c_init(void)
+{
+ db8500_add_i2c0(&u8500_i2c0_data);
+ db8500_add_i2c1(&u8500_i2c1_data);
+ db8500_add_i2c2(&u8500_i2c2_data);
+ db8500_add_i2c3(&u8500_i2c3_data);
+}
+
+static struct gpio_keys_button mop500_gpio_keys[] = {
+ {
+ .desc = "SFH7741 Proximity Sensor",
+ .type = EV_SW,
+ .code = SW_FRONT_PROXIMITY,
+ .active_low = 0,
+ .can_disable = 1,
+ }
+};
+
+static struct regulator *prox_regulator;
+static int mop500_prox_activate(struct device *dev);
+static void mop500_prox_deactivate(struct device *dev);
+
+static struct gpio_keys_platform_data mop500_gpio_keys_data = {
+ .buttons = mop500_gpio_keys,
+ .nbuttons = ARRAY_SIZE(mop500_gpio_keys),
+ .enable = mop500_prox_activate,
+ .disable = mop500_prox_deactivate,
+};
+
+static struct platform_device mop500_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = 0,
+ .dev = {
+ .platform_data = &mop500_gpio_keys_data,
+ },
+};
+
+static int mop500_prox_activate(struct device *dev)
+{
+ prox_regulator = regulator_get(&mop500_gpio_keys_device.dev,
+ "vcc");
+ if (IS_ERR(prox_regulator)) {
+ dev_err(&mop500_gpio_keys_device.dev,
+ "no regulator\n");
+ return PTR_ERR(prox_regulator);
+ }
+ regulator_enable(prox_regulator);
+ return 0;
+}
+
+static void mop500_prox_deactivate(struct device *dev)
+{
+ regulator_disable(prox_regulator);
+ regulator_put(prox_regulator);
+}
+
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
+ &mop500_gpio_keys_device,
+};
+
+#ifdef CONFIG_STE_DMA40
+static struct stedma40_chan_cfg ssp0_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV8_SSP0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg ssp0_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+#endif
+
+static struct pl022_ssp_controller ssp0_platform_data = {
+ .bus_id = 0,
+#ifdef CONFIG_STE_DMA40
+ .enable_dma = 1,
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &ssp0_dma_cfg_rx,
+ .dma_tx_param = &ssp0_dma_cfg_tx,
+#else
+ .enable_dma = 0,
+#endif
+ /* on this platform, gpio 31,142,144,214 &
+ * 224 are connected as chip selects
+ */
+ .num_chipselect = 5,
+};
+
+static void __init mop500_spi_init(void)
+{
+ db8500_add_ssp0(&ssp0_platform_data);
+}
+
+#ifdef CONFIG_STE_DMA40
+static struct stedma40_chan_cfg uart0_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV13_UART0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg uart0_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV13_UART0_TX,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg uart1_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV12_UART1_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg uart1_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV12_UART1_TX,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg uart2_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB8500_DMA_DEV11_UART2_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+
+static struct stedma40_chan_cfg uart2_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB8500_DMA_DEV11_UART2_TX,
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+};
+#endif
+
+
+static pin_cfg_t mop500_pins_uart0[] = {
+ GPIO0_U0_CTSn | PIN_INPUT_PULLUP,
+ GPIO1_U0_RTSn | PIN_OUTPUT_HIGH,
+ GPIO2_U0_RXD | PIN_INPUT_PULLUP,
+ GPIO3_U0_TXD | PIN_OUTPUT_HIGH,
+};
+
+#define PRCC_K_SOFTRST_SET 0x18
+#define PRCC_K_SOFTRST_CLEAR 0x1C
+static void ux500_uart0_reset(void)
+{
+ void __iomem *prcc_rst_set, *prcc_rst_clr;
+
+ prcc_rst_set = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
+ PRCC_K_SOFTRST_SET);
+ prcc_rst_clr = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
+ PRCC_K_SOFTRST_CLEAR);
+
+ /* Activate soft reset PRCC_K_SOFTRST_CLEAR */
+ writel((readl(prcc_rst_clr) | 0x1), prcc_rst_clr);
+ udelay(1);
+
+ /* Release soft reset PRCC_K_SOFTRST_SET */
+ writel((readl(prcc_rst_set) | 0x1), prcc_rst_set);
+ udelay(1);
+}
+
+static void ux500_uart0_init(void)
+{
+ int ret;
+
+ ret = nmk_config_pins(mop500_pins_uart0,
+ ARRAY_SIZE(mop500_pins_uart0));
+ if (ret < 0)
+ pr_err("pl011: uart pins_enable failed\n");
+}
+
+static void ux500_uart0_exit(void)
+{
+ int ret;
+
+ ret = nmk_config_pins_sleep(mop500_pins_uart0,
+ ARRAY_SIZE(mop500_pins_uart0));
+ if (ret < 0)
+ pr_err("pl011: uart pins_disable failed\n");
+}
+
+static struct amba_pl011_data uart0_plat = {
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &uart0_dma_cfg_rx,
+ .dma_tx_param = &uart0_dma_cfg_tx,
+#endif
+ .init = ux500_uart0_init,
+ .exit = ux500_uart0_exit,
+ .reset = ux500_uart0_reset,
+};
+
+static struct amba_pl011_data uart1_plat = {
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &uart1_dma_cfg_rx,
+ .dma_tx_param = &uart1_dma_cfg_tx,
+#endif
+};
+
+static struct amba_pl011_data uart2_plat = {
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &uart2_dma_cfg_rx,
+ .dma_tx_param = &uart2_dma_cfg_tx,
+#endif
+};
+
+static void __init mop500_uart_init(void)
+{
+ db8500_add_uart0(&uart0_plat);
+ db8500_add_uart1(&uart1_plat);
+ db8500_add_uart2(&uart2_plat);
+}
+
+static void __init mop500_init_machine(void)
+{
+ int i2c0_devs;
+
+ /*
+ * The HREFv60 board removed a GPIO expander and routed
+ * all these GPIO pins to the internal GPIO controller
+ * instead.
+ */
+ if (machine_is_hrefv60())
+ mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
+ else
+ mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
+
+ u8500_init_devices();
+
+ mop500_pins_init();
+
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+ mop500_i2c_init();
+ mop500_sdi_init();
+ mop500_spi_init();
+ mop500_uart_init();
+
+ platform_device_register(&ab8500_device);
+
+ i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices);
+ if (machine_is_hrefv60())
+ i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES;
+
+ i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs);
+ i2c_register_board_info(2, mop500_i2c2_devices,
+ ARRAY_SIZE(mop500_i2c2_devices));
+}
+
+MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
+ /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
+ .boot_params = 0x100,
+ .map_io = u8500_map_io,
+ .init_irq = ux500_init_irq,
+ /* we re-use nomadik timer here */
+ .timer = &ux500_timer,
+ .init_machine = mop500_init_machine,
+MACHINE_END
+
+MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+")
+ .boot_params = 0x100,
+ .map_io = u8500_map_io,
+ .init_irq = ux500_init_irq,
+ .timer = &ux500_timer,
+ .init_machine = mop500_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
new file mode 100644
index 00000000..03a31cc9
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __BOARD_MOP500_H
+#define __BOARD_MOP500_H
+
+/* HREFv60-specific GPIO assignments, this board has no GPIO expander */
+#define HREFV60_TOUCH_RST_GPIO 143
+#define HREFV60_PROX_SENSE_GPIO 217
+#define HREFV60_HAL_SW_GPIO 145
+#define HREFV60_SDMMC_EN_GPIO 169
+#define HREFV60_SDMMC_1V8_3V_GPIO 5
+#define HREFV60_SDMMC_CD_GPIO 95
+#define HREFV60_ACCEL_INT1_GPIO 82
+#define HREFV60_ACCEL_INT2_GPIO 83
+#define HREFV60_MAGNET_DRDY_GPIO 32
+#define HREFV60_DISP1_RST_GPIO 65
+#define HREFV60_DISP2_RST_GPIO 66
+
+/* GPIOs on the TC35892 expander */
+#define MOP500_EGPIO(x) (NOMADIK_NR_GPIO + (x))
+#define GPIO_SDMMC_CD MOP500_EGPIO(3)
+#define GPIO_PROX_SENSOR MOP500_EGPIO(7)
+#define GPIO_BU21013_CS MOP500_EGPIO(13)
+#define GPIO_SDMMC_EN MOP500_EGPIO(17)
+#define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18)
+#define MOP500_EGPIO_END MOP500_EGPIO(24)
+
+/* GPIOs on the AB8500 mixed-signals circuit */
+#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x))
+
+struct i2c_board_info;
+
+extern void mop500_sdi_init(void);
+extern void mop500_sdi_tc35892_init(void);
+void __init mop500_u8500uib_init(void);
+void __init mop500_stuib_init(void);
+void __init mop500_pins_init(void);
+
+void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info,
+ unsigned n);
+
+#endif
diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c
new file mode 100644
index 00000000..739fb4c5
--- /dev/null
+++ b/arch/arm/mach-ux500/board-u5500-sdi.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Hanumath Prasad <ulf.hansson@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/amba/mmci.h>
+#include <linux/mmc/host.h>
+#include <linux/gpio.h>
+
+#include <plat/pincfg.h>
+#include <mach/db5500-regs.h>
+#include <plat/ste_dma40.h>
+
+#include "pins-db5500.h"
+#include "devices-db5500.h"
+#include "ste-dma40-db5500.h"
+
+static pin_cfg_t u5500_sdi_pins[] = {
+ /* SDI0 (POP eMMC) */
+ GPIO5_MC0_DAT0 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO6_MC0_DAT1 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO7_MC0_DAT2 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO8_MC0_DAT3 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO9_MC0_DAT4 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO10_MC0_DAT5 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO11_MC0_DAT6 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO12_MC0_DAT7 | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO13_MC0_CMD | PIN_DIR_INPUT | PIN_PULL_UP,
+ GPIO14_MC0_CLK | PIN_DIR_OUTPUT | PIN_VAL_LOW,
+};
+
+#ifdef CONFIG_STE_DMA40
+struct stedma40_chan_cfg u5500_sdi0_dma_cfg_rx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_PERIPH_TO_MEM,
+ .src_dev_type = DB5500_DMA_DEV24_SDMMC0_RX,
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+
+static struct stedma40_chan_cfg u5500_sdi0_dma_cfg_tx = {
+ .mode = STEDMA40_MODE_LOGICAL,
+ .dir = STEDMA40_MEM_TO_PERIPH,
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY,
+ .dst_dev_type = DB5500_DMA_DEV24_SDMMC0_TX,
+ .src_info.data_width = STEDMA40_WORD_WIDTH,
+ .dst_info.data_width = STEDMA40_WORD_WIDTH,
+};
+#endif
+
+static struct mmci_platform_data u5500_sdi0_data = {
+ .ocr_mask = MMC_VDD_165_195,
+ .f_max = 50000000,
+ .capabilities = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED,
+ .gpio_cd = -1,
+ .gpio_wp = -1,
+#ifdef CONFIG_STE_DMA40
+ .dma_filter = stedma40_filter,
+ .dma_rx_param = &u5500_sdi0_dma_cfg_rx,
+ .dma_tx_param = &u5500_sdi0_dma_cfg_tx,
+#endif
+};
+
+void __init u5500_sdi_init(void)
+{
+ nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins));
+
+ db5500_add_sdi0(&u5500_sdi0_data);
+}
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
new file mode 100644
index 00000000..44fd3b5c
--- /dev/null
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+
+#include "devices-db5500.h"
+
+static void __init u5500_uart_init(void)
+{
+ db5500_add_uart0(NULL);
+ db5500_add_uart1(NULL);
+ db5500_add_uart2(NULL);
+}
+
+static void __init u5500_init_machine(void)
+{
+ u5500_init_devices();
+
+ u5500_sdi_init();
+ u5500_uart_init();
+}
+
+MACHINE_START(U5500, "ST-Ericsson U5500 Platform")
+ .boot_params = 0x00000100,
+ .map_io = u5500_map_io,
+ .init_irq = ux500_init_irq,
+ .timer = &ux500_timer,
+ .init_machine = u5500_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
new file mode 100644
index 00000000..32ce9084
--- /dev/null
+++ b/arch/arm/mach-ux500/clock.c
@@ -0,0 +1,790 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ * Copyright (C) 2009 STMicroelectronics
+ *
+ * This program is free software; you can 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/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <plat/mtu.h>
+#include <mach/hardware.h>
+#include "clock.h"
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h> /* for copy_from_user */
+static LIST_HEAD(clk_list);
+#endif
+
+#define PRCC_PCKEN 0x00
+#define PRCC_PCKDIS 0x04
+#define PRCC_KCKEN 0x08
+#define PRCC_KCKDIS 0x0C
+
+#define PRCM_YYCLKEN0_MGT_SET 0x510
+#define PRCM_YYCLKEN1_MGT_SET 0x514
+#define PRCM_YYCLKEN0_MGT_CLR 0x518
+#define PRCM_YYCLKEN1_MGT_CLR 0x51C
+#define PRCM_YYCLKEN0_MGT_VAL 0x520
+#define PRCM_YYCLKEN1_MGT_VAL 0x524
+
+#define PRCM_SVAMMDSPCLK_MGT 0x008
+#define PRCM_SIAMMDSPCLK_MGT 0x00C
+#define PRCM_SGACLK_MGT 0x014
+#define PRCM_UARTCLK_MGT 0x018
+#define PRCM_MSP02CLK_MGT 0x01C
+#define PRCM_MSP1CLK_MGT 0x288
+#define PRCM_I2CCLK_MGT 0x020
+#define PRCM_SDMMCCLK_MGT 0x024
+#define PRCM_SLIMCLK_MGT 0x028
+#define PRCM_PER1CLK_MGT 0x02C
+#define PRCM_PER2CLK_MGT 0x030
+#define PRCM_PER3CLK_MGT 0x034
+#define PRCM_PER5CLK_MGT 0x038
+#define PRCM_PER6CLK_MGT 0x03C
+#define PRCM_PER7CLK_MGT 0x040
+#define PRCM_LCDCLK_MGT 0x044
+#define PRCM_BMLCLK_MGT 0x04C
+#define PRCM_HSITXCLK_MGT 0x050
+#define PRCM_HSIRXCLK_MGT 0x054
+#define PRCM_HDMICLK_MGT 0x058
+#define PRCM_APEATCLK_MGT 0x05C
+#define PRCM_APETRACECLK_MGT 0x060
+#define PRCM_MCDECLK_MGT 0x064
+#define PRCM_IPI2CCLK_MGT 0x068
+#define PRCM_DSIALTCLK_MGT 0x06C
+#define PRCM_DMACLK_MGT 0x074
+#define PRCM_B2R2CLK_MGT 0x078
+#define PRCM_TVCLK_MGT 0x07C
+#define PRCM_TCR 0x1C8
+#define PRCM_TCR_STOPPED (1 << 16)
+#define PRCM_TCR_DOZE_MODE (1 << 17)
+#define PRCM_UNIPROCLK_MGT 0x278
+#define PRCM_SSPCLK_MGT 0x280
+#define PRCM_RNGCLK_MGT 0x284
+#define PRCM_UICCCLK_MGT 0x27C
+
+#define PRCM_MGT_ENABLE (1 << 8)
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+ if (clk->enabled++ == 0) {
+ if (clk->parent_cluster)
+ __clk_enable(clk->parent_cluster);
+
+ if (clk->parent_periph)
+ __clk_enable(clk->parent_periph);
+
+ if (clk->ops && clk->ops->enable)
+ clk->ops->enable(clk);
+ }
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+static void __clk_disable(struct clk *clk)
+{
+ if (--clk->enabled == 0) {
+ if (clk->ops && clk->ops->disable)
+ clk->ops->disable(clk);
+
+ if (clk->parent_periph)
+ __clk_disable(clk->parent_periph);
+
+ if (clk->parent_cluster)
+ __clk_disable(clk->parent_cluster);
+ }
+}
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(!clk->enabled);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/*
+ * The MTU has a separate, rather complex muxing setup
+ * with alternative parents (peripheral cluster or
+ * ULP or fixed 32768 Hz) depending on settings
+ */
+static unsigned long clk_mtu_get_rate(struct clk *clk)
+{
+ void __iomem *addr;
+ u32 tcr;
+ int mtu = (int) clk->data;
+ /*
+ * One of these is selected eventually
+ * TODO: Replace the constant with a reference
+ * to the ULP source once this is modeled.
+ */
+ unsigned long clk32k = 32768;
+ unsigned long mturate;
+ unsigned long retclk;
+
+ if (cpu_is_u5500())
+ addr = __io_address(U5500_PRCMU_BASE);
+ else if (cpu_is_u8500())
+ addr = __io_address(U8500_PRCMU_BASE);
+ else
+ ux500_unknown_soc();
+
+ /*
+ * On a startup, always conifgure the TCR to the doze mode;
+ * bootloaders do it for us. Do this in the kernel too.
+ */
+ writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
+
+ tcr = readl(addr + PRCM_TCR);
+
+ /* Get the rate from the parent as a default */
+ if (clk->parent_periph)
+ mturate = clk_get_rate(clk->parent_periph);
+ else if (clk->parent_cluster)
+ mturate = clk_get_rate(clk->parent_cluster);
+ else
+ /* We need to be connected SOMEWHERE */
+ BUG();
+
+ /* Return the clock selected for this MTU */
+ if (tcr & (1 << mtu))
+ retclk = clk32k;
+ else
+ retclk = mturate;
+
+ pr_info("MTU%d clock rate: %lu Hz\n", mtu, retclk);
+ return retclk;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long rate;
+
+ /*
+ * If there is a custom getrate callback for this clock,
+ * it will take precedence.
+ */
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ if (clk->ops && clk->ops->get_rate)
+ return clk->ops->get_rate(clk);
+
+ rate = clk->rate;
+ if (!rate) {
+ if (clk->parent_periph)
+ rate = clk_get_rate(clk->parent_periph);
+ else if (clk->parent_cluster)
+ rate = clk_get_rate(clk->parent_cluster);
+ }
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ /*TODO*/
+ return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ clk->rate = rate;
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+static void clk_prcmu_enable(struct clk *clk)
+{
+ void __iomem *cg_set_reg = __io_address(U8500_PRCMU_BASE)
+ + PRCM_YYCLKEN0_MGT_SET + clk->prcmu_cg_off;
+
+ writel(1 << clk->prcmu_cg_bit, cg_set_reg);
+}
+
+static void clk_prcmu_disable(struct clk *clk)
+{
+ void __iomem *cg_clr_reg = __io_address(U8500_PRCMU_BASE)
+ + PRCM_YYCLKEN0_MGT_CLR + clk->prcmu_cg_off;
+
+ writel(1 << clk->prcmu_cg_bit, cg_clr_reg);
+}
+
+/* ED doesn't have the combined set/clr registers */
+static void clk_prcmu_ed_enable(struct clk *clk)
+{
+ void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+ + clk->prcmu_cg_mgt;
+
+ writel(readl(addr) | PRCM_MGT_ENABLE, addr);
+}
+
+static void clk_prcmu_ed_disable(struct clk *clk)
+{
+ void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+ + clk->prcmu_cg_mgt;
+
+ writel(readl(addr) & ~PRCM_MGT_ENABLE, addr);
+}
+
+static struct clkops clk_prcmu_ops = {
+ .enable = clk_prcmu_enable,
+ .disable = clk_prcmu_disable,
+};
+
+static unsigned int clkrst_base[] = {
+ [1] = U8500_CLKRST1_BASE,
+ [2] = U8500_CLKRST2_BASE,
+ [3] = U8500_CLKRST3_BASE,
+ [5] = U8500_CLKRST5_BASE,
+ [6] = U8500_CLKRST6_BASE,
+ [7] = U8500_CLKRST7_BASE_ED,
+};
+
+static void clk_prcc_enable(struct clk *clk)
+{
+ void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+ if (clk->prcc_kernel != -1)
+ writel(1 << clk->prcc_kernel, addr + PRCC_KCKEN);
+
+ if (clk->prcc_bus != -1)
+ writel(1 << clk->prcc_bus, addr + PRCC_PCKEN);
+}
+
+static void clk_prcc_disable(struct clk *clk)
+{
+ void __iomem *addr = __io_address(clkrst_base[clk->cluster]);
+
+ if (clk->prcc_bus != -1)
+ writel(1 << clk->prcc_bus, addr + PRCC_PCKDIS);
+
+ if (clk->prcc_kernel != -1)
+ writel(1 << clk->prcc_kernel, addr + PRCC_KCKDIS);
+}
+
+static struct clkops clk_prcc_ops = {
+ .enable = clk_prcc_enable,
+ .disable = clk_prcc_disable,
+};
+
+static struct clk clk_32khz = {
+ .name = "clk_32khz",
+ .rate = 32000,
+};
+
+/*
+ * PRCMU level clock gating
+ */
+
+/* Bank 0 */
+static DEFINE_PRCMU_CLK(svaclk, 0x0, 2, SVAMMDSPCLK);
+static DEFINE_PRCMU_CLK(siaclk, 0x0, 3, SIAMMDSPCLK);
+static DEFINE_PRCMU_CLK(sgaclk, 0x0, 4, SGACLK);
+static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000);
+static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK);
+static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000);
+static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000);
+static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK);
+static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK);
+static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
+static DEFINE_PRCMU_CLK(per3clk, 0x0, 13, PER3CLK);
+static DEFINE_PRCMU_CLK(per5clk, 0x0, 14, PER5CLK);
+static DEFINE_PRCMU_CLK_RATE(per6clk, 0x0, 15, PER6CLK, 133330000);
+static DEFINE_PRCMU_CLK_RATE(per7clk, 0x0, 16, PER7CLK, 100000000);
+static DEFINE_PRCMU_CLK(lcdclk, 0x0, 17, LCDCLK);
+static DEFINE_PRCMU_CLK(bmlclk, 0x0, 18, BMLCLK);
+static DEFINE_PRCMU_CLK(hsitxclk, 0x0, 19, HSITXCLK);
+static DEFINE_PRCMU_CLK(hsirxclk, 0x0, 20, HSIRXCLK);
+static DEFINE_PRCMU_CLK(hdmiclk, 0x0, 21, HDMICLK);
+static DEFINE_PRCMU_CLK(apeatclk, 0x0, 22, APEATCLK);
+static DEFINE_PRCMU_CLK(apetraceclk, 0x0, 23, APETRACECLK);
+static DEFINE_PRCMU_CLK(mcdeclk, 0x0, 24, MCDECLK);
+static DEFINE_PRCMU_CLK(ipi2clk, 0x0, 25, IPI2CCLK);
+static DEFINE_PRCMU_CLK(dsialtclk, 0x0, 26, DSIALTCLK); /* v1 */
+static DEFINE_PRCMU_CLK(dmaclk, 0x0, 27, DMACLK);
+static DEFINE_PRCMU_CLK(b2r2clk, 0x0, 28, B2R2CLK);
+static DEFINE_PRCMU_CLK(tvclk, 0x0, 29, TVCLK);
+static DEFINE_PRCMU_CLK(uniproclk, 0x0, 30, UNIPROCLK); /* v1 */
+static DEFINE_PRCMU_CLK_RATE(sspclk, 0x0, 31, SSPCLK, 48000000); /* v1 */
+
+/* Bank 1 */
+static DEFINE_PRCMU_CLK(rngclk, 0x4, 0, RNGCLK); /* v1 */
+static DEFINE_PRCMU_CLK(uiccclk, 0x4, 1, UICCCLK); /* v1 */
+
+/*
+ * PRCC level clock gating
+ * Format: per#, clk, PCKEN bit, KCKEN bit, parent
+ */
+
+/* Peripheral Cluster #1 */
+static DEFINE_PRCC_CLK(1, i2c4, 10, 9, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, gpio0, 9, -1, NULL);
+static DEFINE_PRCC_CLK(1, slimbus0, 8, 8, &clk_slimclk);
+static DEFINE_PRCC_CLK(1, spi3_ed, 7, 7, NULL);
+static DEFINE_PRCC_CLK(1, spi3_v1, 7, -1, NULL);
+static DEFINE_PRCC_CLK(1, i2c2, 6, 6, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, sdi0, 5, 5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(1, msp1_ed, 4, 4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, msp1_v1, 4, 4, &clk_msp1clk);
+static DEFINE_PRCC_CLK(1, msp0, 3, 3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(1, i2c1, 2, 2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(1, uart1, 1, 1, &clk_uartclk);
+static DEFINE_PRCC_CLK(1, uart0, 0, 0, &clk_uartclk);
+
+/* Peripheral Cluster #2 */
+
+static DEFINE_PRCC_CLK(2, gpio1_ed, 12, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_ed, 11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_ed, 10, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi0_ed, 9, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_ed, 8, 6, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_ed, 7, 5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_ed, 6, 4, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_ed, 4, 2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_ed, 3, 1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_ed, 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_ed, 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_ed, 0, 0, &clk_i2cclk);
+
+static DEFINE_PRCC_CLK(2, gpio1_v1, 11, -1, NULL);
+static DEFINE_PRCC_CLK(2, ssitx_v1, 10, 7, NULL);
+static DEFINE_PRCC_CLK(2, ssirx_v1, 9, 6, NULL);
+static DEFINE_PRCC_CLK(2, spi0_v1, 8, -1, NULL);
+static DEFINE_PRCC_CLK(2, sdi3_v1, 7, 5, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, sdi1_v1, 6, 4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, msp2_v1, 5, 3, &clk_msp02clk);
+static DEFINE_PRCC_CLK(2, sdi4_v1, 4, 2, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(2, pwl_v1, 3, 1, NULL);
+static DEFINE_PRCC_CLK(2, spi1_v1, 2, -1, NULL);
+static DEFINE_PRCC_CLK(2, spi2_v1, 1, -1, NULL);
+static DEFINE_PRCC_CLK(2, i2c3_v1, 0, 0, &clk_i2cclk);
+
+/* Peripheral Cluster #3 */
+static DEFINE_PRCC_CLK(3, gpio2, 8, -1, NULL);
+static DEFINE_PRCC_CLK(3, sdi5, 7, 7, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, uart2, 6, 6, &clk_uartclk);
+static DEFINE_PRCC_CLK(3, ske, 5, 5, &clk_32khz);
+static DEFINE_PRCC_CLK(3, sdi2, 4, 4, &clk_sdmmcclk);
+static DEFINE_PRCC_CLK(3, i2c0, 3, 3, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_ed, 2, 2, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp0_ed, 1, 1, &clk_i2cclk);
+static DEFINE_PRCC_CLK(3, ssp1_v1, 2, 2, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, ssp0_v1, 1, 1, &clk_sspclk);
+static DEFINE_PRCC_CLK(3, fsmc, 0, -1, NULL);
+
+/* Peripheral Cluster #4 is in the always on domain */
+
+/* Peripheral Cluster #5 */
+static DEFINE_PRCC_CLK(5, gpio3, 1, -1, NULL);
+static DEFINE_PRCC_CLK(5, usb_ed, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(5, usb_v1, 0, 0, NULL);
+
+/* Peripheral Cluster #6 */
+
+/* MTU ID in data */
+static DEFINE_PRCC_CLK_CUSTOM(6, mtu1_v1, 8, -1, NULL, clk_mtu_get_rate, 1);
+static DEFINE_PRCC_CLK_CUSTOM(6, mtu0_v1, 7, -1, NULL, clk_mtu_get_rate, 0);
+static DEFINE_PRCC_CLK(6, cfgreg_v1, 6, 6, NULL);
+static DEFINE_PRCC_CLK(6, dmc_ed, 6, 6, NULL);
+static DEFINE_PRCC_CLK(6, hash1, 5, -1, NULL);
+static DEFINE_PRCC_CLK(6, unipro_v1, 4, 1, &clk_uniproclk);
+static DEFINE_PRCC_CLK(6, cryp1_ed, 4, -1, NULL);
+static DEFINE_PRCC_CLK(6, pka, 3, -1, NULL);
+static DEFINE_PRCC_CLK(6, hash0, 2, -1, NULL);
+static DEFINE_PRCC_CLK(6, cryp0, 1, -1, NULL);
+static DEFINE_PRCC_CLK(6, rng_ed, 0, 0, &clk_i2cclk);
+static DEFINE_PRCC_CLK(6, rng_v1, 0, 0, &clk_rngclk);
+
+/* Peripheral Cluster #7 */
+
+static DEFINE_PRCC_CLK(7, tzpc0_ed, 4, -1, NULL);
+/* MTU ID in data */
+static DEFINE_PRCC_CLK_CUSTOM(7, mtu1_ed, 3, -1, NULL, clk_mtu_get_rate, 1);
+static DEFINE_PRCC_CLK_CUSTOM(7, mtu0_ed, 2, -1, NULL, clk_mtu_get_rate, 0);
+static DEFINE_PRCC_CLK(7, wdg_ed, 1, -1, NULL);
+static DEFINE_PRCC_CLK(7, cfgreg_ed, 0, -1, NULL);
+
+static struct clk clk_dummy_apb_pclk = {
+ .name = "apb_pclk",
+};
+
+static struct clk_lookup u8500_common_clks[] = {
+ CLK(dummy_apb_pclk, NULL, "apb_pclk"),
+
+ /* Peripheral Cluster #1 */
+ CLK(gpio0, "gpio.0", NULL),
+ CLK(gpio0, "gpio.1", NULL),
+ CLK(slimbus0, "slimbus0", NULL),
+ CLK(i2c2, "nmk-i2c.2", NULL),
+ CLK(sdi0, "sdi0", NULL),
+ CLK(msp0, "msp0", NULL),
+ CLK(i2c1, "nmk-i2c.1", NULL),
+ CLK(uart1, "uart1", NULL),
+ CLK(uart0, "uart0", NULL),
+
+ /* Peripheral Cluster #3 */
+ CLK(gpio2, "gpio.2", NULL),
+ CLK(gpio2, "gpio.3", NULL),
+ CLK(gpio2, "gpio.4", NULL),
+ CLK(gpio2, "gpio.5", NULL),
+ CLK(sdi5, "sdi5", NULL),
+ CLK(uart2, "uart2", NULL),
+ CLK(ske, "ske", NULL),
+ CLK(ske, "nmk-ske-keypad", NULL),
+ CLK(sdi2, "sdi2", NULL),
+ CLK(i2c0, "nmk-i2c.0", NULL),
+ CLK(fsmc, "fsmc", NULL),
+
+ /* Peripheral Cluster #5 */
+ CLK(gpio3, "gpio.8", NULL),
+
+ /* Peripheral Cluster #6 */
+ CLK(hash1, "hash1", NULL),
+ CLK(pka, "pka", NULL),
+ CLK(hash0, "hash0", NULL),
+ CLK(cryp0, "cryp0", NULL),
+
+ /* PRCMU level clock gating */
+
+ /* Bank 0 */
+ CLK(svaclk, "sva", NULL),
+ CLK(siaclk, "sia", NULL),
+ CLK(sgaclk, "sga", NULL),
+ CLK(slimclk, "slim", NULL),
+ CLK(lcdclk, "lcd", NULL),
+ CLK(bmlclk, "bml", NULL),
+ CLK(hsitxclk, "stm-hsi.0", NULL),
+ CLK(hsirxclk, "stm-hsi.1", NULL),
+ CLK(hdmiclk, "hdmi", NULL),
+ CLK(apeatclk, "apeat", NULL),
+ CLK(apetraceclk, "apetrace", NULL),
+ CLK(mcdeclk, "mcde", NULL),
+ CLK(ipi2clk, "ipi2", NULL),
+ CLK(dmaclk, "dma40.0", NULL),
+ CLK(b2r2clk, "b2r2", NULL),
+ CLK(tvclk, "tv", NULL),
+};
+
+static struct clk_lookup u8500_ed_clks[] = {
+ /* Peripheral Cluster #1 */
+ CLK(spi3_ed, "spi3", NULL),
+ CLK(msp1_ed, "msp1", NULL),
+
+ /* Peripheral Cluster #2 */
+ CLK(gpio1_ed, "gpio.6", NULL),
+ CLK(gpio1_ed, "gpio.7", NULL),
+ CLK(ssitx_ed, "ssitx", NULL),
+ CLK(ssirx_ed, "ssirx", NULL),
+ CLK(spi0_ed, "spi0", NULL),
+ CLK(sdi3_ed, "sdi3", NULL),
+ CLK(sdi1_ed, "sdi1", NULL),
+ CLK(msp2_ed, "msp2", NULL),
+ CLK(sdi4_ed, "sdi4", NULL),
+ CLK(pwl_ed, "pwl", NULL),
+ CLK(spi1_ed, "spi1", NULL),
+ CLK(spi2_ed, "spi2", NULL),
+ CLK(i2c3_ed, "nmk-i2c.3", NULL),
+
+ /* Peripheral Cluster #3 */
+ CLK(ssp1_ed, "ssp1", NULL),
+ CLK(ssp0_ed, "ssp0", NULL),
+
+ /* Peripheral Cluster #5 */
+ CLK(usb_ed, "musb-ux500.0", "usb"),
+
+ /* Peripheral Cluster #6 */
+ CLK(dmc_ed, "dmc", NULL),
+ CLK(cryp1_ed, "cryp1", NULL),
+ CLK(rng_ed, "rng", NULL),
+
+ /* Peripheral Cluster #7 */
+ CLK(tzpc0_ed, "tzpc0", NULL),
+ CLK(mtu1_ed, "mtu1", NULL),
+ CLK(mtu0_ed, "mtu0", NULL),
+ CLK(wdg_ed, "wdg", NULL),
+ CLK(cfgreg_ed, "cfgreg", NULL),
+};
+
+static struct clk_lookup u8500_v1_clks[] = {
+ /* Peripheral Cluster #1 */
+ CLK(i2c4, "nmk-i2c.4", NULL),
+ CLK(spi3_v1, "spi3", NULL),
+ CLK(msp1_v1, "msp1", NULL),
+
+ /* Peripheral Cluster #2 */
+ CLK(gpio1_v1, "gpio.6", NULL),
+ CLK(gpio1_v1, "gpio.7", NULL),
+ CLK(ssitx_v1, "ssitx", NULL),
+ CLK(ssirx_v1, "ssirx", NULL),
+ CLK(spi0_v1, "spi0", NULL),
+ CLK(sdi3_v1, "sdi3", NULL),
+ CLK(sdi1_v1, "sdi1", NULL),
+ CLK(msp2_v1, "msp2", NULL),
+ CLK(sdi4_v1, "sdi4", NULL),
+ CLK(pwl_v1, "pwl", NULL),
+ CLK(spi1_v1, "spi1", NULL),
+ CLK(spi2_v1, "spi2", NULL),
+ CLK(i2c3_v1, "nmk-i2c.3", NULL),
+
+ /* Peripheral Cluster #3 */
+ CLK(ssp1_v1, "ssp1", NULL),
+ CLK(ssp0_v1, "ssp0", NULL),
+
+ /* Peripheral Cluster #5 */
+ CLK(usb_v1, "musb-ux500.0", "usb"),
+
+ /* Peripheral Cluster #6 */
+ CLK(mtu1_v1, "mtu1", NULL),
+ CLK(mtu0_v1, "mtu0", NULL),
+ CLK(cfgreg_v1, "cfgreg", NULL),
+ CLK(hash1, "hash1", NULL),
+ CLK(unipro_v1, "unipro", NULL),
+ CLK(rng_v1, "rng", NULL),
+
+ /* PRCMU level clock gating */
+
+ /* Bank 0 */
+ CLK(uniproclk, "uniproclk", NULL),
+ CLK(dsialtclk, "dsialt", NULL),
+
+ /* Bank 1 */
+ CLK(rngclk, "rng", NULL),
+ CLK(uiccclk, "uicc", NULL),
+};
+
+#ifdef CONFIG_DEBUG_FS
+/*
+ * debugfs support to trace clock tree hierarchy and attributes with
+ * powerdebug
+ */
+static struct dentry *clk_debugfs_root;
+
+void __init clk_debugfs_add_table(struct clk_lookup *cl, size_t num)
+{
+ while (num--) {
+ /* Check that the clock has not been already registered */
+ if (!(cl->clk->list.prev != cl->clk->list.next))
+ list_add_tail(&cl->clk->list, &clk_list);
+
+ cl++;
+ }
+}
+
+static ssize_t usecount_dbg_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
+{
+ struct clk *clk = file->f_dentry->d_inode->i_private;
+ char cusecount[128];
+ unsigned int len;
+
+ len = sprintf(cusecount, "%u\n", clk->enabled);
+ return simple_read_from_buffer(buf, size, off, cusecount, len);
+}
+
+static ssize_t rate_dbg_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
+{
+ struct clk *clk = file->f_dentry->d_inode->i_private;
+ char crate[128];
+ unsigned int rate;
+ unsigned int len;
+
+ rate = clk_get_rate(clk);
+ len = sprintf(crate, "%u\n", rate);
+ return simple_read_from_buffer(buf, size, off, crate, len);
+}
+
+static const struct file_operations usecount_fops = {
+ .read = usecount_dbg_read,
+};
+
+static const struct file_operations set_rate_fops = {
+ .read = rate_dbg_read,
+};
+
+static struct dentry *clk_debugfs_register_dir(struct clk *c,
+ struct dentry *p_dentry)
+{
+ struct dentry *d, *clk_d, *child, *child_tmp;
+ char s[255];
+ char *p = s;
+
+ if (c->name == NULL)
+ p += sprintf(p, "BUG");
+ else
+ p += sprintf(p, "%s", c->name);
+
+ clk_d = debugfs_create_dir(s, p_dentry);
+ if (!clk_d)
+ return NULL;
+
+ d = debugfs_create_file("usecount", S_IRUGO,
+ clk_d, c, &usecount_fops);
+ if (!d)
+ goto err_out;
+ d = debugfs_create_file("rate", S_IRUGO,
+ clk_d, c, &set_rate_fops);
+ if (!d)
+ goto err_out;
+ /*
+ * TODO : not currently available in ux500
+ * d = debugfs_create_x32("flags", S_IRUGO, clk_d, (u32 *)&c->flags);
+ * if (!d)
+ * goto err_out;
+ */
+
+ return clk_d;
+
+err_out:
+ d = clk_d;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(clk_d);
+ return NULL;
+}
+
+static void clk_debugfs_remove_dir(struct dentry *cdentry)
+{
+ struct dentry *d, *child, *child_tmp;
+
+ d = cdentry;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(cdentry);
+ return ;
+}
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ struct clk *pa = c->parent_periph;
+ struct clk *bpa = c->parent_cluster;
+
+ if (!(bpa && !pa)) {
+ c->dent = clk_debugfs_register_dir(c,
+ pa ? pa->dent : clk_debugfs_root);
+ if (!c->dent)
+ return -ENOMEM;
+ }
+
+ if (bpa) {
+ c->dent_bus = clk_debugfs_register_dir(c,
+ bpa->dent_bus ? bpa->dent_bus : bpa->dent);
+ if ((!c->dent_bus) && (c->dent)) {
+ clk_debugfs_remove_dir(c->dent);
+ c->dent = NULL;
+ return -ENOMEM;
+ }
+ }
+ return 0;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent_periph;
+ struct clk *bpa = c->parent_cluster;
+
+ if (pa && (!pa->dent && !pa->dent_bus)) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (bpa && (!bpa->dent && !bpa->dent_bus)) {
+ err = clk_debugfs_register(bpa);
+ if (err)
+ return err;
+ }
+
+ if ((!c->dent) && (!c->dent_bus)) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clk_list, list) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+
+late_initcall(clk_debugfs_init);
+#endif /* defined(CONFIG_DEBUG_FS) */
+
+int __init clk_init(void)
+{
+ if (cpu_is_u8500ed()) {
+ clk_prcmu_ops.enable = clk_prcmu_ed_enable;
+ clk_prcmu_ops.disable = clk_prcmu_ed_disable;
+ clk_per6clk.rate = 100000000;
+ } else if (cpu_is_u5500()) {
+ /* Clock tree for U5500 not implemented yet */
+ clk_prcc_ops.enable = clk_prcc_ops.disable = NULL;
+ clk_prcmu_ops.enable = clk_prcmu_ops.disable = NULL;
+ clk_uartclk.rate = 36360000;
+ clk_sdmmcclk.rate = 99900000;
+ }
+
+ clkdev_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
+ if (cpu_is_u8500ed())
+ clkdev_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
+ else
+ clkdev_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+
+#ifdef CONFIG_DEBUG_FS
+ clk_debugfs_add_table(u8500_common_clks, ARRAY_SIZE(u8500_common_clks));
+ if (cpu_is_u8500ed())
+ clk_debugfs_add_table(u8500_ed_clks, ARRAY_SIZE(u8500_ed_clks));
+ else
+ clk_debugfs_add_table(u8500_v1_clks, ARRAY_SIZE(u8500_v1_clks));
+#endif
+ return 0;
+}
diff --git a/arch/arm/mach-ux500/clock.h b/arch/arm/mach-ux500/clock.h
new file mode 100644
index 00000000..07449070
--- /dev/null
+++ b/arch/arm/mach-ux500/clock.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2010 ST-Ericsson
+ * Copyright (C) 2009 STMicroelectronics
+ *
+ * This program is free software; you can 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 clkops - ux500 clock operations
+ * @enable: function to enable the clock
+ * @disable: function to disable the clock
+ * @get_rate: function to get the current clock rate
+ *
+ * This structure contains function pointers to functions that will be used to
+ * control the clock. All of these functions are optional. If get_rate is
+ * NULL, the rate in the struct clk will be used.
+ */
+struct clkops {
+ void (*enable) (struct clk *);
+ void (*disable) (struct clk *);
+ unsigned long (*get_rate) (struct clk *);
+};
+
+/**
+ * struct clk - ux500 clock structure
+ * @ops: pointer to clkops struct used to control this clock
+ * @name: name, for debugging
+ * @enabled: refcount. positive if enabled, zero if disabled
+ * @get_rate: custom callback for getting the clock rate
+ * @data: custom per-clock data for example for the get_rate
+ * callback
+ * @rate: fixed rate for clocks which don't implement
+ * ops->getrate
+ * @prcmu_cg_off: address offset of the combined enable/disable register
+ * (used on u8500v1)
+ * @prcmu_cg_bit: bit in the combined enable/disable register (used on
+ * u8500v1)
+ * @prcmu_cg_mgt: address of the enable/disable register (used on
+ * u8500ed)
+ * @cluster: peripheral cluster number
+ * @prcc_bus: bit for the bus clock in the peripheral's CLKRST
+ * @prcc_kernel: bit for the kernel clock in the peripheral's CLKRST.
+ * -1 if no kernel clock exists.
+ * @parent_cluster: pointer to parent's cluster clk struct
+ * @parent_periph: pointer to parent's peripheral clk struct
+ *
+ * Peripherals are organised into clusters, and each cluster has an associated
+ * bus clock. Some peripherals also have a parent peripheral clock.
+ *
+ * In order to enable a clock for a peripheral, we need to enable:
+ * (1) the parent cluster (bus) clock at the PRCMU level
+ * (2) the parent peripheral clock (if any) at the PRCMU level
+ * (3) the peripheral's bus & kernel clock at the PRCC level
+ *
+ * (1) and (2) are handled by defining clk structs (DEFINE_PRCMU_CLK) for each
+ * of the cluster and peripheral clocks, and hooking these as the parents of
+ * the individual peripheral clocks.
+ *
+ * (3) is handled by specifying the bits in the PRCC control registers required
+ * to enable these clocks and modifying them in the ->enable and
+ * ->disable callbacks of the peripheral clocks (DEFINE_PRCC_CLK).
+ *
+ * This structure describes both the PRCMU-level clocks and PRCC-level clocks.
+ * The prcmu_* fields are only used for the PRCMU clocks, and the cluster,
+ * prcc, and parent pointers are only used for the PRCC-level clocks.
+ */
+struct clk {
+ const struct clkops *ops;
+ const char *name;
+ unsigned int enabled;
+ unsigned long (*get_rate)(struct clk *);
+ void *data;
+
+ unsigned long rate;
+ struct list_head list;
+
+ /* These three are only for PRCMU clks */
+
+ unsigned int prcmu_cg_off;
+ unsigned int prcmu_cg_bit;
+ unsigned int prcmu_cg_mgt;
+
+ /* The rest are only for PRCC clks */
+
+ int cluster;
+ unsigned int prcc_bus;
+ unsigned int prcc_kernel;
+
+ struct clk *parent_cluster;
+ struct clk *parent_periph;
+#if defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+ struct dentry *dent_bus; /* For visible tree hierarchy */
+#endif
+};
+
+#define DEFINE_PRCMU_CLK(_name, _cg_off, _cg_bit, _reg) \
+struct clk clk_##_name = { \
+ .name = #_name, \
+ .ops = &clk_prcmu_ops, \
+ .prcmu_cg_off = _cg_off, \
+ .prcmu_cg_bit = _cg_bit, \
+ .prcmu_cg_mgt = PRCM_##_reg##_MGT \
+ }
+
+#define DEFINE_PRCMU_CLK_RATE(_name, _cg_off, _cg_bit, _reg, _rate) \
+struct clk clk_##_name = { \
+ .name = #_name, \
+ .ops = &clk_prcmu_ops, \
+ .prcmu_cg_off = _cg_off, \
+ .prcmu_cg_bit = _cg_bit, \
+ .rate = _rate, \
+ .prcmu_cg_mgt = PRCM_##_reg##_MGT \
+ }
+
+#define DEFINE_PRCC_CLK(_pclust, _name, _bus_en, _kernel_en, _kernclk) \
+struct clk clk_##_name = { \
+ .name = #_name, \
+ .ops = &clk_prcc_ops, \
+ .cluster = _pclust, \
+ .prcc_bus = _bus_en, \
+ .prcc_kernel = _kernel_en, \
+ .parent_cluster = &clk_per##_pclust##clk, \
+ .parent_periph = _kernclk \
+ }
+
+#define DEFINE_PRCC_CLK_CUSTOM(_pclust, _name, _bus_en, _kernel_en, _kernclk, _callback, _data) \
+struct clk clk_##_name = { \
+ .name = #_name, \
+ .ops = &clk_prcc_ops, \
+ .cluster = _pclust, \
+ .prcc_bus = _bus_en, \
+ .prcc_kernel = _kernel_en, \
+ .parent_cluster = &clk_per##_pclust##clk, \
+ .parent_periph = _kernclk, \
+ .get_rate = _callback, \
+ .data = (void *) _data \
+ }
+
+
+#define CLK(_clk, _devname, _conname) \
+ { \
+ .clk = &clk_##_clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
+int __init clk_db8500_ed_fixup(void);
+int __init clk_init(void);
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
new file mode 100644
index 00000000..c01bc19e
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/mach/map.h>
+#include <asm/pmu.h>
+
+#include <plat/gpio.h>
+
+#include <mach/hardware.h>
+#include <mach/devices.h>
+#include <mach/setup.h>
+#include <mach/irqs.h>
+#include <mach/usb.h>
+
+#include "devices-db5500.h"
+#include "ste-dma40-db5500.h"
+
+static struct map_desc u5500_uart_io_desc[] __initdata = {
+ __IO_DEV_DESC(U5500_UART0_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_UART2_BASE, SZ_4K),
+};
+
+static struct map_desc u5500_io_desc[] __initdata = {
+ __IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_TWD_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_SCU_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K),
+
+ __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K),
+};
+
+static struct resource db5500_pmu_resources[] = {
+ [0] = {
+ .start = IRQ_DB5500_PMU0,
+ .end = IRQ_DB5500_PMU0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_DB5500_PMU1,
+ .end = IRQ_DB5500_PMU1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device db5500_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(db5500_pmu_resources),
+ .resource = db5500_pmu_resources,
+};
+
+static struct resource mbox0_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX0_PEER_START,
+ .end = U5500_MBOX0_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX0_LOCAL_START,
+ .end = U5500_MBOX0_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR0_VIRT_IRQ,
+ .end = MBOX_PAIR0_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource mbox1_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX1_PEER_START,
+ .end = U5500_MBOX1_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX1_LOCAL_START,
+ .end = U5500_MBOX1_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR1_VIRT_IRQ,
+ .end = MBOX_PAIR1_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource mbox2_resources[] = {
+ {
+ .name = "mbox_peer",
+ .start = U5500_MBOX2_PEER_START,
+ .end = U5500_MBOX2_PEER_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_local",
+ .start = U5500_MBOX2_LOCAL_START,
+ .end = U5500_MBOX2_LOCAL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mbox_irq",
+ .start = MBOX_PAIR2_VIRT_IRQ,
+ .end = MBOX_PAIR2_VIRT_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device mbox0_device = {
+ .id = 0,
+ .name = "mbox",
+ .resource = mbox0_resources,
+ .num_resources = ARRAY_SIZE(mbox0_resources),
+};
+
+static struct platform_device mbox1_device = {
+ .id = 1,
+ .name = "mbox",
+ .resource = mbox1_resources,
+ .num_resources = ARRAY_SIZE(mbox1_resources),
+};
+
+static struct platform_device mbox2_device = {
+ .id = 2,
+ .name = "mbox",
+ .resource = mbox2_resources,
+ .num_resources = ARRAY_SIZE(mbox2_resources),
+};
+
+static struct platform_device *db5500_platform_devs[] __initdata = {
+ &db5500_pmu_device,
+ &mbox0_device,
+ &mbox1_device,
+ &mbox2_device,
+};
+
+static resource_size_t __initdata db5500_gpio_base[] = {
+ U5500_GPIOBANK0_BASE,
+ U5500_GPIOBANK1_BASE,
+ U5500_GPIOBANK2_BASE,
+ U5500_GPIOBANK3_BASE,
+ U5500_GPIOBANK4_BASE,
+ U5500_GPIOBANK5_BASE,
+ U5500_GPIOBANK6_BASE,
+ U5500_GPIOBANK7_BASE,
+};
+
+static void __init db5500_add_gpios(void)
+{
+ struct nmk_gpio_platform_data pdata = {
+ /* No custom data yet */
+ };
+
+ dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base),
+ IRQ_DB5500_GPIO0, &pdata);
+}
+
+void __init u5500_map_io(void)
+{
+ /*
+ * Map the UARTs early so that the DEBUG_LL stuff continues to work.
+ */
+ iotable_init(u5500_uart_io_desc, ARRAY_SIZE(u5500_uart_io_desc));
+
+ ux500_map_io();
+
+ iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
+
+ _PRCMU_BASE = __io_address(U5500_PRCMU_BASE);
+}
+
+static int usb_db5500_rx_dma_cfg[] = {
+ DB5500_DMA_DEV4_USB_OTG_IEP_1_9,
+ DB5500_DMA_DEV5_USB_OTG_IEP_2_10,
+ DB5500_DMA_DEV6_USB_OTG_IEP_3_11,
+ DB5500_DMA_DEV20_USB_OTG_IEP_4_12,
+ DB5500_DMA_DEV21_USB_OTG_IEP_5_13,
+ DB5500_DMA_DEV22_USB_OTG_IEP_6_14,
+ DB5500_DMA_DEV23_USB_OTG_IEP_7_15,
+ DB5500_DMA_DEV38_USB_OTG_IEP_8
+};
+
+static int usb_db5500_tx_dma_cfg[] = {
+ DB5500_DMA_DEV4_USB_OTG_OEP_1_9,
+ DB5500_DMA_DEV5_USB_OTG_OEP_2_10,
+ DB5500_DMA_DEV6_USB_OTG_OEP_3_11,
+ DB5500_DMA_DEV20_USB_OTG_OEP_4_12,
+ DB5500_DMA_DEV21_USB_OTG_OEP_5_13,
+ DB5500_DMA_DEV22_USB_OTG_OEP_6_14,
+ DB5500_DMA_DEV23_USB_OTG_OEP_7_15,
+ DB5500_DMA_DEV38_USB_OTG_OEP_8
+};
+
+void __init u5500_init_devices(void)
+{
+ db5500_add_gpios();
+ db5500_dma_init();
+ db5500_add_rtc();
+ db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg);
+
+ platform_add_devices(db5500_platform_devs,
+ ARRAY_SIZE(db5500_platform_devs));
+}
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
new file mode 100644
index 00000000..4598b06c
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+#include <asm/pmu.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+#include <mach/usb.h>
+
+#include "devices-db8500.h"
+#include "ste-dma40-db8500.h"
+
+/* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_uart_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
+};
+
+static struct map_desc u8500_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
+
+ __IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K),
+
+ __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
+};
+
+static struct map_desc u8500_ed_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_MTU0_BASE_ED, SZ_4K),
+ __IO_DEV_DESC(U8500_CLKRST7_BASE_ED, SZ_8K),
+};
+
+static struct map_desc u8500_v1_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE_V1, SZ_4K),
+};
+
+static struct map_desc u8500_v2_io_desc[] __initdata = {
+ __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
+};
+
+void __init u8500_map_io(void)
+{
+ /*
+ * Map the UARTs early so that the DEBUG_LL stuff continues to work.
+ */
+ iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc));
+
+ ux500_map_io();
+
+ iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+
+ if (cpu_is_u8500ed())
+ iotable_init(u8500_ed_io_desc, ARRAY_SIZE(u8500_ed_io_desc));
+ else if (cpu_is_u8500v1())
+ iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
+ else if (cpu_is_u8500v2())
+ iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
+
+ _PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
+}
+
+static struct resource db8500_pmu_resources[] = {
+ [0] = {
+ .start = IRQ_DB8500_PMU,
+ .end = IRQ_DB8500_PMU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * The PMU IRQ lines of two cores are wired together into a single interrupt.
+ * Bounce the interrupt to the other core if it's not ours.
+ */
+static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
+{
+ irqreturn_t ret = handler(irq, dev);
+ int other = !smp_processor_id();
+
+ if (ret == IRQ_NONE && cpu_online(other))
+ irq_set_affinity(irq, cpumask_of(other));
+
+ /*
+ * We should be able to get away with the amount of IRQ_NONEs we give,
+ * while still having the spurious IRQ detection code kick in if the
+ * interrupt really starts hitting spuriously.
+ */
+ return ret;
+}
+
+static struct arm_pmu_platdata db8500_pmu_platdata = {
+ .handle_irq = db8500_pmu_handler,
+};
+
+static struct platform_device db8500_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(db8500_pmu_resources),
+ .resource = db8500_pmu_resources,
+ .dev.platform_data = &db8500_pmu_platdata,
+};
+
+static struct platform_device db8500_prcmu_device = {
+ .name = "db8500-prcmu",
+};
+
+static struct platform_device *platform_devs[] __initdata = {
+ &u8500_dma40_device,
+ &db8500_pmu_device,
+ &db8500_prcmu_device,
+};
+
+static resource_size_t __initdata db8500_gpio_base[] = {
+ U8500_GPIOBANK0_BASE,
+ U8500_GPIOBANK1_BASE,
+ U8500_GPIOBANK2_BASE,
+ U8500_GPIOBANK3_BASE,
+ U8500_GPIOBANK4_BASE,
+ U8500_GPIOBANK5_BASE,
+ U8500_GPIOBANK6_BASE,
+ U8500_GPIOBANK7_BASE,
+ U8500_GPIOBANK8_BASE,
+};
+
+static void __init db8500_add_gpios(void)
+{
+ struct nmk_gpio_platform_data pdata = {
+ /* No custom data yet */
+ };
+
+ if (cpu_is_u8500v2())
+ pdata.supports_sleepmode = true;
+
+ dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
+ IRQ_DB8500_GPIO0, &pdata);
+}
+
+static int usb_db8500_rx_dma_cfg[] = {
+ DB8500_DMA_DEV38_USB_OTG_IEP_1_9,
+ DB8500_DMA_DEV37_USB_OTG_IEP_2_10,
+ DB8500_DMA_DEV36_USB_OTG_IEP_3_11,
+ DB8500_DMA_DEV19_USB_OTG_IEP_4_12,
+ DB8500_DMA_DEV18_USB_OTG_IEP_5_13,
+ DB8500_DMA_DEV17_USB_OTG_IEP_6_14,
+ DB8500_DMA_DEV16_USB_OTG_IEP_7_15,
+ DB8500_DMA_DEV39_USB_OTG_IEP_8
+};
+
+static int usb_db8500_tx_dma_cfg[] = {
+ DB8500_DMA_DEV38_USB_OTG_OEP_1_9,
+ DB8500_DMA_DEV37_USB_OTG_OEP_2_10,
+ DB8500_DMA_DEV36_USB_OTG_OEP_3_11,
+ DB8500_DMA_DEV19_USB_OTG_OEP_4_12,
+ DB8500_DMA_DEV18_USB_OTG_OEP_5_13,
+ DB8500_DMA_DEV17_USB_OTG_OEP_6_14,
+ DB8500_DMA_DEV16_USB_OTG_OEP_7_15,
+ DB8500_DMA_DEV39_USB_OTG_OEP_8
+};
+
+/*
+ * This function is called from the board init
+ */
+void __init u8500_init_devices(void)
+{
+ if (cpu_is_u8500ed())
+ dma40_u8500ed_fixup();
+
+ db8500_add_rtc();
+ db8500_add_gpios();
+ db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg);
+
+ platform_device_register_simple("cpufreq-u8500", -1, NULL, 0);
+ platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+ return ;
+}
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
new file mode 100644
index 00000000..8aa104a4
--- /dev/null
+++ b/arch/arm/mach-ux500/cpu.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/mfd/db8500-prcmu.h>
+#include <linux/mfd/db5500-prcmu.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <asm/localtimer.h>
+
+#include <plat/mtu.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+#include <mach/devices.h>
+
+#include "clock.h"
+
+void __iomem *_PRCMU_BASE;
+
+#ifdef CONFIG_CACHE_L2X0
+static void __iomem *l2x0_base;
+#endif
+
+void __init ux500_init_irq(void)
+{
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+
+ if (cpu_is_u5500()) {
+ dist_base = __io_address(U5500_GIC_DIST_BASE);
+ cpu_base = __io_address(U5500_GIC_CPU_BASE);
+ } else if (cpu_is_u8500()) {
+ dist_base = __io_address(U8500_GIC_DIST_BASE);
+ cpu_base = __io_address(U8500_GIC_CPU_BASE);
+ } else
+ ux500_unknown_soc();
+
+ gic_init(0, 29, dist_base, cpu_base);
+
+ /*
+ * Init clocks here so that they are available for system timer
+ * initialization.
+ */
+ if (cpu_is_u5500())
+ db5500_prcmu_early_init();
+ if (cpu_is_u8500())
+ prcmu_early_init();
+ clk_init();
+}
+
+#ifdef CONFIG_CACHE_L2X0
+static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
+{
+ /* wait for the operation to complete */
+ while (readl_relaxed(reg) & mask)
+ ;
+}
+
+static inline void ux500_cache_sync(void)
+{
+ void __iomem *base = l2x0_base;
+
+ writel_relaxed(0, base + L2X0_CACHE_SYNC);
+ ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
+}
+
+/*
+ * The L2 cache cannot be turned off in the non-secure world.
+ * Dummy until a secure service is in place.
+ */
+static void ux500_l2x0_disable(void)
+{
+}
+
+/*
+ * This is only called when doing a kexec, just after turning off the L2
+ * and L1 cache, and it is surrounded by a spinlock in the generic version.
+ * However, we're not really turning off the L2 cache right now and the
+ * PL310 does not support exclusive accesses (used to implement the spinlock).
+ * So, the invalidation needs to be done without the spinlock.
+ */
+static void ux500_l2x0_inv_all(void)
+{
+ void __iomem *base = l2x0_base;
+ uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
+
+ /* invalidate all ways */
+ writel_relaxed(l2x0_way_mask, base + L2X0_INV_WAY);
+ ux500_cache_wait(base + L2X0_INV_WAY, l2x0_way_mask);
+ ux500_cache_sync();
+}
+
+static int __init ux500_l2x0_unlock(void)
+{
+ int i;
+
+ /*
+ * Unlock Data and Instruction Lock if locked. Ux500 U-Boot versions
+ * apparently locks both caches before jumping to the kernel. The
+ * l2x0 core will not touch the unlock registers if the l2x0 is
+ * already enabled, so we do it right here instead. The PL310 has
+ * 8 sets of registers, one per possible CPU.
+ */
+ for (i = 0; i < 8; i++) {
+ writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_D_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE +
+ i * L2X0_LOCKDOWN_STRIDE);
+ }
+ return 0;
+}
+
+static int __init ux500_l2x0_init(void)
+{
+ if (cpu_is_u5500())
+ l2x0_base = __io_address(U5500_L2CC_BASE);
+ else if (cpu_is_u8500())
+ l2x0_base = __io_address(U8500_L2CC_BASE);
+ else
+ ux500_unknown_soc();
+
+ /* Unlock before init */
+ ux500_l2x0_unlock();
+
+ /* 64KB way size, 8 way associativity, force WA */
+ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+
+ /* Override invalidate function */
+ outer_cache.disable = ux500_l2x0_disable;
+ outer_cache.inv_all = ux500_l2x0_inv_all;
+
+ return 0;
+}
+early_initcall(ux500_l2x0_init);
+#endif
+
+static void __init ux500_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+ /* Setup the local timer base */
+ if (cpu_is_u5500())
+ twd_base = __io_address(U5500_TWD_BASE);
+ else if (cpu_is_u8500())
+ twd_base = __io_address(U8500_TWD_BASE);
+ else
+ ux500_unknown_soc();
+#endif
+ if (cpu_is_u5500())
+ mtu_base = __io_address(U5500_MTU0_BASE);
+ else if (cpu_is_u8500ed())
+ mtu_base = __io_address(U8500_MTU0_BASE_ED);
+ else if (cpu_is_u8500())
+ mtu_base = __io_address(U8500_MTU0_BASE);
+ else
+ ux500_unknown_soc();
+
+ nmdk_timer_init();
+}
+
+struct sys_timer ux500_timer = {
+ .init = ux500_timer_init,
+};
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
new file mode 100644
index 00000000..13a4ce04
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+
+#include <plat/gpio.h>
+
+#include <mach/hardware.h>
+
+#include "devices-common.h"
+
+struct amba_device *
+dbx500_add_amba_device(const char *name, resource_size_t base,
+ int irq, void *pdata, unsigned int periphid)
+{
+ struct amba_device *dev;
+ int ret;
+
+ dev = kzalloc(sizeof *dev, GFP_KERNEL);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->dev.init_name = name;
+
+ dev->res.start = base;
+ dev->res.end = base + SZ_4K - 1;
+ dev->res.flags = IORESOURCE_MEM;
+
+ dev->dma_mask = DMA_BIT_MASK(32);
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ dev->irq[0] = irq;
+ dev->irq[1] = NO_IRQ;
+
+ dev->periphid = periphid;
+
+ dev->dev.platform_data = pdata;
+
+ ret = amba_device_register(dev, &iomem_resource);
+ if (ret) {
+ kfree(dev);
+ return ERR_PTR(ret);
+ }
+
+ return dev;
+}
+
+static struct platform_device *
+dbx500_add_platform_device(const char *name, int id, void *pdata,
+ struct resource *res, int resnum)
+{
+ struct platform_device *dev;
+ int ret;
+
+ dev = platform_device_alloc(name, id);
+ if (!dev)
+ return ERR_PTR(-ENOMEM);
+
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+
+ ret = platform_device_add_resources(dev, res, resnum);
+ if (ret)
+ goto out_free;
+
+ dev->dev.platform_data = pdata;
+
+ ret = platform_device_add(dev);
+ if (ret)
+ goto out_free;
+
+ return dev;
+
+out_free:
+ platform_device_put(dev);
+ return ERR_PTR(ret);
+}
+
+struct platform_device *
+dbx500_add_platform_device_4k1irq(const char *name, int id,
+ resource_size_t base,
+ int irq, void *pdata)
+{
+ struct resource resources[] = {
+ [0] = {
+ .start = base,
+ .end = base + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ return dbx500_add_platform_device(name, id, pdata, resources,
+ ARRAY_SIZE(resources));
+}
+
+static struct platform_device *
+dbx500_add_gpio(int id, resource_size_t addr, int irq,
+ struct nmk_gpio_platform_data *pdata)
+{
+ struct resource resources[] = {
+ {
+ .start = addr,
+ .end = addr + 127,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ }
+ };
+
+ return platform_device_register_resndata(NULL, "gpio", id,
+ resources, ARRAY_SIZE(resources),
+ pdata, sizeof(*pdata));
+}
+
+void dbx500_add_gpios(resource_size_t *base, int num, int irq,
+ struct nmk_gpio_platform_data *pdata)
+{
+ int first = 0;
+ int i;
+
+ for (i = 0; i < num; i++, first += 32, irq++) {
+ pdata->first_gpio = first;
+ pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first);
+ pdata->num_gpio = 32;
+
+ dbx500_add_gpio(i, base[i], irq, pdata);
+ }
+}
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
new file mode 100644
index 00000000..78257050
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_COMMON_H
+#define __DEVICES_COMMON_H
+
+extern struct amba_device *
+dbx500_add_amba_device(const char *name, resource_size_t base,
+ int irq, void *pdata, unsigned int periphid);
+
+extern struct platform_device *
+dbx500_add_platform_device_4k1irq(const char *name, int id,
+ resource_size_t base,
+ int irq, void *pdata);
+
+struct spi_master_cntlr;
+
+static inline struct amba_device *
+dbx500_add_msp_spi(const char *name, resource_size_t base, int irq,
+ struct spi_master_cntlr *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+static inline struct amba_device *
+dbx500_add_spi(const char *name, resource_size_t base, int irq,
+ struct spi_master_cntlr *pdata,
+ u32 periphid)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+}
+
+struct mmci_platform_data;
+
+static inline struct amba_device *
+dbx500_add_sdi(const char *name, resource_size_t base, int irq,
+ struct mmci_platform_data *pdata,
+ u32 periphid)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, periphid);
+}
+
+struct amba_pl011_data;
+
+static inline struct amba_device *
+dbx500_add_uart(const char *name, resource_size_t base, int irq,
+ struct amba_pl011_data *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+struct nmk_i2c_controller;
+
+static inline struct platform_device *
+dbx500_add_i2c(int id, resource_size_t base, int irq,
+ struct nmk_i2c_controller *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq,
+ pdata);
+}
+
+struct msp_i2s_platform_data;
+
+static inline struct platform_device *
+dbx500_add_msp_i2s(int id, resource_size_t base, int irq,
+ struct msp_i2s_platform_data *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq,
+ pdata);
+}
+
+static inline struct amba_device *
+dbx500_add_rtc(resource_size_t base, int irq)
+{
+ return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0);
+}
+
+struct nmk_gpio_platform_data;
+
+void dbx500_add_gpios(resource_size_t *base, int num, int irq,
+ struct nmk_gpio_platform_data *pdata);
+
+#endif
diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h
new file mode 100644
index 00000000..0c4bccd0
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db5500.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_DB5500_H
+#define __DEVICES_DB5500_H
+
+#include "devices-common.h"
+
+#define db5500_add_i2c1(pdata) \
+ dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata)
+#define db5500_add_i2c2(pdata) \
+ dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata)
+#define db5500_add_i2c3(pdata) \
+ dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata)
+
+#define db5500_add_msp0_i2s(pdata) \
+ dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_i2s(pdata) \
+ dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_i2s(pdata) \
+ dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+
+#define db5500_add_msp0_spi(pdata) \
+ dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata)
+#define db5500_add_msp1_spi(pdata) \
+ dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata)
+#define db5500_add_msp2_spi(pdata) \
+ dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata)
+
+#define db5500_add_rtc() \
+ dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC);
+
+#define db5500_add_usb(rx_cfg, tx_cfg) \
+ ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
+
+#define db5500_add_sdi0(pdata) \
+ dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \
+ 0x10480180)
+#define db5500_add_sdi1(pdata) \
+ dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \
+ 0x10480180)
+#define db5500_add_sdi2(pdata) \
+ dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \
+ 0x10480180)
+#define db5500_add_sdi3(pdata) \
+ dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \
+ 0x10480180)
+#define db5500_add_sdi4(pdata) \
+ dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \
+ 0x10480180)
+
+/* This one has a bad peripheral ID in the U5500 silicon */
+#define db5500_add_spi0(pdata) \
+ dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \
+ 0x10080023)
+#define db5500_add_spi1(pdata) \
+ dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \
+ 0x10080023)
+#define db5500_add_spi2(pdata) \
+ dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \
+ 0x10080023)
+#define db5500_add_spi3(pdata) \
+ dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \
+ 0x10080023)
+
+#define db5500_add_uart0(plat) \
+ dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat)
+#define db5500_add_uart1(plat) \
+ dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat)
+#define db5500_add_uart2(plat) \
+ dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat)
+#define db5500_add_uart3(plat) \
+ dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat)
+
+#endif
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c
new file mode 100644
index 00000000..73b17404
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db8500.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl022.h>
+
+#include <plat/ste_dma40.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+#include "ste-dma40-db8500.h"
+
+static struct resource dma40_resources[] = {
+ [0] = {
+ .start = U8500_DMA_BASE,
+ .end = U8500_DMA_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "base",
+ },
+ [1] = {
+ .start = U8500_DMA_LCPA_BASE,
+ .end = U8500_DMA_LCPA_BASE + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "lcpa",
+ },
+ [2] = {
+ .start = IRQ_DB8500_DMA,
+ .end = IRQ_DB8500_DMA,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* Default configuration for physcial memcpy */
+struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
+ .mode = STEDMA40_MODE_PHYSICAL,
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_PHY_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_PHY_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+/* Default configuration for logical memcpy */
+struct stedma40_chan_cfg dma40_memcpy_conf_log = {
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_LOG_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/*
+ * Mapping between destination event lines and physical device address.
+ * The event line is tied to a device and therefore the address is constant.
+ * When the address comes from a primecell it will be configured in runtime
+ * and we set the address to -1 as a placeholder.
+ */
+static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV] = {
+ /* MUSB - these will be runtime-reconfigured */
+ [DB8500_DMA_DEV39_USB_OTG_OEP_8] = -1,
+ [DB8500_DMA_DEV16_USB_OTG_OEP_7_15] = -1,
+ [DB8500_DMA_DEV17_USB_OTG_OEP_6_14] = -1,
+ [DB8500_DMA_DEV18_USB_OTG_OEP_5_13] = -1,
+ [DB8500_DMA_DEV19_USB_OTG_OEP_4_12] = -1,
+ [DB8500_DMA_DEV36_USB_OTG_OEP_3_11] = -1,
+ [DB8500_DMA_DEV37_USB_OTG_OEP_2_10] = -1,
+ [DB8500_DMA_DEV38_USB_OTG_OEP_1_9] = -1,
+ /* PrimeCells - run-time configured */
+ [DB8500_DMA_DEV0_SPI0_TX] = -1,
+ [DB8500_DMA_DEV1_SD_MMC0_TX] = -1,
+ [DB8500_DMA_DEV2_SD_MMC1_TX] = -1,
+ [DB8500_DMA_DEV3_SD_MMC2_TX] = -1,
+ [DB8500_DMA_DEV8_SSP0_TX] = -1,
+ [DB8500_DMA_DEV9_SSP1_TX] = -1,
+ [DB8500_DMA_DEV11_UART2_TX] = -1,
+ [DB8500_DMA_DEV12_UART1_TX] = -1,
+ [DB8500_DMA_DEV13_UART0_TX] = -1,
+ [DB8500_DMA_DEV28_SD_MM2_TX] = -1,
+ [DB8500_DMA_DEV29_SD_MM0_TX] = -1,
+ [DB8500_DMA_DEV32_SD_MM1_TX] = -1,
+ [DB8500_DMA_DEV33_SPI2_TX] = -1,
+ [DB8500_DMA_DEV35_SPI1_TX] = -1,
+ [DB8500_DMA_DEV40_SPI3_TX] = -1,
+ [DB8500_DMA_DEV41_SD_MM3_TX] = -1,
+ [DB8500_DMA_DEV42_SD_MM4_TX] = -1,
+ [DB8500_DMA_DEV43_SD_MM5_TX] = -1,
+};
+
+/* Mapping between source event lines and physical device address */
+static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV] = {
+ /* MUSB - these will be runtime-reconfigured */
+ [DB8500_DMA_DEV39_USB_OTG_IEP_8] = -1,
+ [DB8500_DMA_DEV16_USB_OTG_IEP_7_15] = -1,
+ [DB8500_DMA_DEV17_USB_OTG_IEP_6_14] = -1,
+ [DB8500_DMA_DEV18_USB_OTG_IEP_5_13] = -1,
+ [DB8500_DMA_DEV19_USB_OTG_IEP_4_12] = -1,
+ [DB8500_DMA_DEV36_USB_OTG_IEP_3_11] = -1,
+ [DB8500_DMA_DEV37_USB_OTG_IEP_2_10] = -1,
+ [DB8500_DMA_DEV38_USB_OTG_IEP_1_9] = -1,
+ /* PrimeCells */
+ [DB8500_DMA_DEV0_SPI0_RX] = -1,
+ [DB8500_DMA_DEV1_SD_MMC0_RX] = -1,
+ [DB8500_DMA_DEV2_SD_MMC1_RX] = -1,
+ [DB8500_DMA_DEV3_SD_MMC2_RX] = -1,
+ [DB8500_DMA_DEV8_SSP0_RX] = -1,
+ [DB8500_DMA_DEV9_SSP1_RX] = -1,
+ [DB8500_DMA_DEV11_UART2_RX] = -1,
+ [DB8500_DMA_DEV12_UART1_RX] = -1,
+ [DB8500_DMA_DEV13_UART0_RX] = -1,
+ [DB8500_DMA_DEV28_SD_MM2_RX] = -1,
+ [DB8500_DMA_DEV29_SD_MM0_RX] = -1,
+ [DB8500_DMA_DEV32_SD_MM1_RX] = -1,
+ [DB8500_DMA_DEV33_SPI2_RX] = -1,
+ [DB8500_DMA_DEV35_SPI1_RX] = -1,
+ [DB8500_DMA_DEV40_SPI3_RX] = -1,
+ [DB8500_DMA_DEV41_SD_MM3_RX] = -1,
+ [DB8500_DMA_DEV42_SD_MM4_RX] = -1,
+ [DB8500_DMA_DEV43_SD_MM5_RX] = -1,
+};
+
+/* Reserved event lines for memcpy only */
+static int dma40_memcpy_event[] = {
+ DB8500_DMA_MEMCPY_TX_0,
+ DB8500_DMA_MEMCPY_TX_1,
+ DB8500_DMA_MEMCPY_TX_2,
+ DB8500_DMA_MEMCPY_TX_3,
+ DB8500_DMA_MEMCPY_TX_4,
+ DB8500_DMA_MEMCPY_TX_5,
+};
+
+static struct stedma40_platform_data dma40_plat_data = {
+ .dev_len = DB8500_DMA_NR_DEV,
+ .dev_rx = dma40_rx_map,
+ .dev_tx = dma40_tx_map,
+ .memcpy = dma40_memcpy_event,
+ .memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
+ .memcpy_conf_phy = &dma40_memcpy_conf_phy,
+ .memcpy_conf_log = &dma40_memcpy_conf_log,
+ .disabled_channels = {-1},
+};
+
+struct platform_device u8500_dma40_device = {
+ .dev = {
+ .platform_data = &dma40_plat_data,
+ },
+ .name = "dma40",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dma40_resources),
+ .resource = dma40_resources
+};
+
+void dma40_u8500ed_fixup(void)
+{
+ dma40_plat_data.memcpy = NULL;
+ dma40_plat_data.memcpy_len = 0;
+ dma40_resources[0].start = U8500_DMA_BASE_ED;
+ dma40_resources[0].end = U8500_DMA_BASE_ED + SZ_4K - 1;
+ dma40_resources[1].start = U8500_DMA_LCPA_BASE_ED;
+ dma40_resources[1].end = U8500_DMA_LCPA_BASE_ED + 2 * SZ_1K - 1;
+}
+
+struct resource keypad_resources[] = {
+ [0] = {
+ .start = U8500_SKE_BASE,
+ .end = U8500_SKE_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DB8500_KB,
+ .end = IRQ_DB8500_KB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device u8500_ske_keypad_device = {
+ .name = "nmk-ske-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(keypad_resources),
+ .resource = keypad_resources,
+};
diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h
new file mode 100644
index 00000000..cbd4a9ae
--- /dev/null
+++ b/arch/arm/mach-ux500/devices-db8500.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __DEVICES_DB8500_H
+#define __DEVICES_DB8500_H
+
+#include "devices-common.h"
+
+struct ske_keypad_platform_data;
+struct pl022_ssp_controller;
+
+static inline struct platform_device *
+db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata)
+{
+ return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1,
+ U8500_SKE_BASE,
+ IRQ_DB8500_KB, pdata);
+}
+
+static inline struct amba_device *
+db8500_add_ssp(const char *name, resource_size_t base, int irq,
+ struct pl022_ssp_controller *pdata)
+{
+ return dbx500_add_amba_device(name, base, irq, pdata, 0);
+}
+
+
+#define db8500_add_i2c0(pdata) \
+ dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata)
+#define db8500_add_i2c1(pdata) \
+ dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata)
+#define db8500_add_i2c2(pdata) \
+ dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata)
+#define db8500_add_i2c3(pdata) \
+ dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata)
+#define db8500_add_i2c4(pdata) \
+ dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata)
+
+#define db8500_add_msp0_i2s(pdata) \
+ dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_i2s(pdata) \
+ dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_i2s(pdata) \
+ dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_i2s(pdata) \
+ dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_msp0_spi(pdata) \
+ dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata)
+#define db8500_add_msp1_spi(pdata) \
+ dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata)
+#define db8500_add_msp2_spi(pdata) \
+ dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata)
+#define db8500_add_msp3_spi(pdata) \
+ dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata)
+
+#define db8500_add_rtc() \
+ dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC);
+
+#define db8500_add_usb(rx_cfg, tx_cfg) \
+ ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
+
+#define db8500_add_sdi0(pdata, pid) \
+ dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid)
+#define db8500_add_sdi1(pdata, pid) \
+ dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid)
+#define db8500_add_sdi2(pdata, pid) \
+ dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid)
+#define db8500_add_sdi3(pdata, pid) \
+ dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid)
+#define db8500_add_sdi4(pdata, pid) \
+ dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid)
+#define db8500_add_sdi5(pdata, pid) \
+ dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid)
+
+#define db8500_add_ssp0(pdata) \
+ db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
+#define db8500_add_ssp1(pdata) \
+ db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
+
+#define db8500_add_spi0(pdata) \
+ dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0)
+#define db8500_add_spi1(pdata) \
+ dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0)
+#define db8500_add_spi2(pdata) \
+ dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0)
+#define db8500_add_spi3(pdata) \
+ dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0)
+
+#define db8500_add_uart0(pdata) \
+ dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata)
+#define db8500_add_uart1(pdata) \
+ dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata)
+#define db8500_add_uart2(pdata) \
+ dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata)
+
+#endif
diff --git a/arch/arm/mach-ux500/devices.c b/arch/arm/mach-ux500/devices.c
new file mode 100644
index 00000000..ea0a2f92
--- /dev/null
+++ b/arch/arm/mach-ux500/devices.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/amba/bus.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+void __init amba_add_devices(struct amba_device *devs[], int num)
+{
+ int i;
+
+ for (i = 0; i < num; i++) {
+ struct amba_device *d = devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+}
diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c
new file mode 100644
index 00000000..1cfab68a
--- /dev/null
+++ b/arch/arm/mach-ux500/dma-db5500.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * Author: Rabin Vincent <rabinv.vincent@stericsson.com> for ST-Ericsson
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <plat/ste_dma40.h>
+#include <mach/setup.h>
+#include <mach/hardware.h>
+
+#include "ste-dma40-db5500.h"
+
+static struct resource dma40_resources[] = {
+ [0] = {
+ .start = U5500_DMA_BASE,
+ .end = U5500_DMA_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "base",
+ },
+ [1] = {
+ .start = U5500_DMA_LCPA_BASE,
+ .end = U5500_DMA_LCPA_BASE + 2 * SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ .name = "lcpa",
+ },
+ [2] = {
+ .start = IRQ_DB5500_DMA,
+ .end = IRQ_DB5500_DMA,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+/* Default configuration for physical memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_phy = {
+ .mode = STEDMA40_MODE_PHYSICAL,
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_PHY_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_PHY_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/* Default configuration for logical memcpy */
+static struct stedma40_chan_cfg dma40_memcpy_conf_log = {
+ .dir = STEDMA40_MEM_TO_MEM,
+
+ .src_info.data_width = STEDMA40_BYTE_WIDTH,
+ .src_info.psize = STEDMA40_PSIZE_LOG_1,
+ .src_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+
+ .dst_info.data_width = STEDMA40_BYTE_WIDTH,
+ .dst_info.psize = STEDMA40_PSIZE_LOG_1,
+ .dst_info.flow_ctrl = STEDMA40_NO_FLOW_CTRL,
+};
+
+/*
+ * Mapping between soruce event lines and physical device address This was
+ * created assuming that the event line is tied to a device and therefore the
+ * address is constant, however this is not true for at least USB, and the
+ * values are just placeholders for USB. This table is preserved and used for
+ * now.
+ */
+static const dma_addr_t dma40_rx_map[DB5500_DMA_NR_DEV] = {
+ [DB5500_DMA_DEV24_SDMMC0_RX] = -1,
+ [DB5500_DMA_DEV38_USB_OTG_IEP_8] = -1,
+ [DB5500_DMA_DEV23_USB_OTG_IEP_7_15] = -1,
+ [DB5500_DMA_DEV22_USB_OTG_IEP_6_14] = -1,
+ [DB5500_DMA_DEV21_USB_OTG_IEP_5_13] = -1,
+ [DB5500_DMA_DEV20_USB_OTG_IEP_4_12] = -1,
+ [DB5500_DMA_DEV6_USB_OTG_IEP_3_11] = -1,
+ [DB5500_DMA_DEV5_USB_OTG_IEP_2_10] = -1,
+ [DB5500_DMA_DEV4_USB_OTG_IEP_1_9] = -1,
+};
+
+/* Mapping between destination event lines and physical device address */
+static const dma_addr_t dma40_tx_map[DB5500_DMA_NR_DEV] = {
+ [DB5500_DMA_DEV24_SDMMC0_TX] = -1,
+ [DB5500_DMA_DEV38_USB_OTG_OEP_8] = -1,
+ [DB5500_DMA_DEV23_USB_OTG_OEP_7_15] = -1,
+ [DB5500_DMA_DEV22_USB_OTG_OEP_6_14] = -1,
+ [DB5500_DMA_DEV21_USB_OTG_OEP_5_13] = -1,
+ [DB5500_DMA_DEV20_USB_OTG_OEP_4_12] = -1,
+ [DB5500_DMA_DEV6_USB_OTG_OEP_3_11] = -1,
+ [DB5500_DMA_DEV5_USB_OTG_OEP_2_10] = -1,
+ [DB5500_DMA_DEV4_USB_OTG_OEP_1_9] = -1,
+};
+
+static int dma40_memcpy_event[] = {
+ DB5500_DMA_MEMCPY_TX_1,
+ DB5500_DMA_MEMCPY_TX_2,
+ DB5500_DMA_MEMCPY_TX_3,
+ DB5500_DMA_MEMCPY_TX_4,
+ DB5500_DMA_MEMCPY_TX_5,
+};
+
+static struct stedma40_platform_data dma40_plat_data = {
+ .dev_len = ARRAY_SIZE(dma40_rx_map),
+ .dev_rx = dma40_rx_map,
+ .dev_tx = dma40_tx_map,
+ .memcpy = dma40_memcpy_event,
+ .memcpy_len = ARRAY_SIZE(dma40_memcpy_event),
+ .memcpy_conf_phy = &dma40_memcpy_conf_phy,
+ .memcpy_conf_log = &dma40_memcpy_conf_log,
+ .disabled_channels = {-1},
+};
+
+static struct platform_device dma40_device = {
+ .dev = {
+ .platform_data = &dma40_plat_data,
+ },
+ .name = "dma40",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dma40_resources),
+ .resource = dma40_resources
+};
+
+void __init db5500_dma_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&dma40_device);
+ if (ret)
+ dev_err(&dma40_device.dev, "unable to register device: %d\n", ret);
+
+}
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
new file mode 100644
index 00000000..64fa451e
--- /dev/null
+++ b/arch/arm/mach-ux500/headsmp.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009 ST-Ericsson
+ * This file is based ARM Realview platform
+ * Copyright (c) 2003 ARM Limited
+ * 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/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * U8500 specific entry point for secondary CPUs.
+ */
+ENTRY(u8500_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+1: .long .
+ .long pen_release
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c
new file mode 100644
index 00000000..dd8037eb
--- /dev/null
+++ b/arch/arm/mach-ux500/hotplug.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Based on ARM realview platform
+ *
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ flush_cache_all();
+
+ /* we put the platform to just WFI */
+ for (;;) {
+ __asm__ __volatile__("dsb\n\t" "wfi\n\t"
+ : : : "memory");
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ /* directly enter low power state, skipping secure registers */
+ platform_do_lowpower(cpu);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c
new file mode 100644
index 00000000..d35122eb
--- /dev/null
+++ b/arch/arm/mach-ux500/id.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+struct dbx500_asic_id dbx500_id;
+
+static unsigned int ux500_read_asicid(phys_addr_t addr)
+{
+ phys_addr_t base = addr & ~0xfff;
+ struct map_desc desc = {
+ .virtual = IO_ADDRESS(base),
+ .pfn = __phys_to_pfn(base),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ };
+
+ iotable_init(&desc, 1);
+
+ /* As in devicemaps_init() */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ return readl(__io_address(addr));
+}
+
+static void ux500_print_soc_info(unsigned int asicid)
+{
+ unsigned int rev = dbx500_revision();
+
+ pr_info("DB%4x ", dbx500_partnumber());
+
+ if (rev == 0x01)
+ pr_cont("Early Drop");
+ else if (rev >= 0xA0)
+ pr_cont("v%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf);
+ else
+ pr_cont("Unknown");
+
+ pr_cont(" [%#010x]\n", asicid);
+}
+
+static unsigned int partnumber(unsigned int asicid)
+{
+ return (asicid >> 8) & 0xffff;
+}
+
+/*
+ * SOC MIDR ASICID ADDRESS ASICID VALUE
+ * DB8500ed 0x410fc090 0x9001FFF4 0x00850001
+ * DB8500v1 0x411fc091 0x9001FFF4 0x008500A0
+ * DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1
+ * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0
+ * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
+ */
+
+void __init ux500_map_io(void)
+{
+ unsigned int cpuid = read_cpuid_id();
+ unsigned int asicid = 0;
+ phys_addr_t addr = 0;
+
+ switch (cpuid) {
+ case 0x410fc090: /* DB8500ed */
+ case 0x411fc091: /* DB8500v1 */
+ addr = 0x9001FFF4;
+ break;
+
+ case 0x412fc091: /* DB8500v2 / DB5500v1 */
+ asicid = ux500_read_asicid(0x9001DBF4);
+ if (partnumber(asicid) == 0x8500)
+ /* DB8500v2 */
+ break;
+
+ /* DB5500v1 */
+ addr = 0x9001FFF4;
+ break;
+ }
+
+ if (addr)
+ asicid = ux500_read_asicid(addr);
+
+ if (!asicid) {
+ pr_err("Unable to identify SoC\n");
+ ux500_unknown_soc();
+ }
+
+ dbx500_id.process = asicid >> 24;
+ dbx500_id.partnumber = partnumber(asicid);
+ dbx500_id.revision = asicid & 0xff;
+
+ ux500_print_soc_info(asicid);
+}
diff --git a/arch/arm/mach-ux500/include/mach/clkdev.h b/arch/arm/mach-ux500/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h
new file mode 100644
index 00000000..6ad98329
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB5500_REGS_H
+#define __MACH_DB5500_REGS_H
+
+#define U5500_PER1_BASE 0xA0020000
+#define U5500_PER2_BASE 0xA0010000
+#define U5500_PER3_BASE 0x80140000
+#define U5500_PER4_BASE 0x80150000
+#define U5500_PER5_BASE 0x80100000
+#define U5500_PER6_BASE 0x80120000
+
+#define U5500_GIC_DIST_BASE 0xA0411000
+#define U5500_GIC_CPU_BASE 0xA0410100
+#define U5500_DMA_BASE 0x90030000
+#define U5500_STM_BASE 0x90020000
+#define U5500_STM_REG_BASE (U5500_STM_BASE + 0xF000)
+#define U5500_MCDE_BASE 0xA0400000
+#define U5500_MODEM_BASE 0xB0000000
+#define U5500_L2CC_BASE 0xA0412000
+#define U5500_SCU_BASE 0xA0410000
+#define U5500_DSI1_BASE 0xA0401000
+#define U5500_DSI2_BASE 0xA0402000
+#define U5500_SIA_BASE 0xA0100000
+#define U5500_SVA_BASE 0x80200000
+#define U5500_HSEM_BASE 0xA0000000
+#define U5500_NAND0_BASE 0x60000000
+#define U5500_NAND1_BASE 0x70000000
+#define U5500_TWD_BASE 0xa0410600
+#define U5500_ICN_BASE 0xA0040000
+#define U5500_B2R2_BASE 0xa0200000
+#define U5500_BOOT_ROM_BASE 0x90000000
+
+#define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000)
+#define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000)
+#define U5500_SDI2_BASE (U5500_PER1_BASE + 0x2000)
+#define U5500_UART0_BASE (U5500_PER1_BASE + 0x3000)
+#define U5500_I2C1_BASE (U5500_PER1_BASE + 0x4000)
+#define U5500_MSP0_BASE (U5500_PER1_BASE + 0x5000)
+#define U5500_GPIO0_BASE (U5500_PER1_BASE + 0xE000)
+#define U5500_CLKRST1_BASE (U5500_PER1_BASE + 0xF000)
+
+#define U5500_USBOTG_BASE (U5500_PER2_BASE + 0x0000)
+#define U5500_GPIO1_BASE (U5500_PER2_BASE + 0xE000)
+#define U5500_CLKRST2_BASE (U5500_PER2_BASE + 0xF000)
+
+#define U5500_KEYPAD_BASE (U5500_PER3_BASE + 0x0000)
+#define U5500_PWM_BASE (U5500_PER3_BASE + 0x1000)
+#define U5500_GPIO3_BASE (U5500_PER3_BASE + 0xE000)
+#define U5500_CLKRST3_BASE (U5500_PER3_BASE + 0xF000)
+
+#define U5500_BACKUPRAM0_BASE (U5500_PER4_BASE + 0x0000)
+#define U5500_BACKUPRAM1_BASE (U5500_PER4_BASE + 0x1000)
+#define U5500_RTT0_BASE (U5500_PER4_BASE + 0x2000)
+#define U5500_RTT1_BASE (U5500_PER4_BASE + 0x3000)
+#define U5500_RTC_BASE (U5500_PER4_BASE + 0x4000)
+#define U5500_SCR_BASE (U5500_PER4_BASE + 0x5000)
+#define U5500_DMC_BASE (U5500_PER4_BASE + 0x6000)
+#define U5500_PRCMU_BASE (U5500_PER4_BASE + 0x7000)
+#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000)
+#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000)
+#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000)
+#define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000)
+
+#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000)
+#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000)
+#define U5500_SPI2_BASE (U5500_PER5_BASE + 0x2000)
+#define U5500_SPI3_BASE (U5500_PER5_BASE + 0x3000)
+#define U5500_UART1_BASE (U5500_PER5_BASE + 0x4000)
+#define U5500_UART2_BASE (U5500_PER5_BASE + 0x5000)
+#define U5500_UART3_BASE (U5500_PER5_BASE + 0x6000)
+#define U5500_SDI1_BASE (U5500_PER5_BASE + 0x7000)
+#define U5500_SDI3_BASE (U5500_PER5_BASE + 0x8000)
+#define U5500_SDI4_BASE (U5500_PER5_BASE + 0x9000)
+#define U5500_I2C2_BASE (U5500_PER5_BASE + 0xA000)
+#define U5500_I2C3_BASE (U5500_PER5_BASE + 0xB000)
+#define U5500_MSP2_BASE (U5500_PER5_BASE + 0xC000)
+#define U5500_IRDA_BASE (U5500_PER5_BASE + 0xD000)
+#define U5500_IRRC_BASE (U5500_PER5_BASE + 0x10000)
+#define U5500_GPIO4_BASE (U5500_PER5_BASE + 0x1E000)
+#define U5500_CLKRST5_BASE (U5500_PER5_BASE + 0x1F000)
+
+#define U5500_RNG_BASE (U5500_PER6_BASE + 0x0000)
+#define U5500_HASH0_BASE (U5500_PER6_BASE + 0x1000)
+#define U5500_HASH1_BASE (U5500_PER6_BASE + 0x2000)
+#define U5500_PKA_BASE (U5500_PER6_BASE + 0x4000)
+#define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5100)
+#define U5500_MTU0_BASE (U5500_PER6_BASE + 0x6000)
+#define U5500_MTU1_BASE (U5500_PER6_BASE + 0x7000)
+#define U5500_CR_BASE (U5500_PER6_BASE + 0x8000)
+#define U5500_CRYP0_BASE (U5500_PER6_BASE + 0xA000)
+#define U5500_CRYP1_BASE (U5500_PER6_BASE + 0xB000)
+#define U5500_CLKRST6_BASE (U5500_PER6_BASE + 0xF000)
+
+#define U5500_GPIOBANK0_BASE U5500_GPIO0_BASE
+#define U5500_GPIOBANK1_BASE (U5500_GPIO0_BASE + 0x80)
+#define U5500_GPIOBANK2_BASE U5500_GPIO1_BASE
+#define U5500_GPIOBANK3_BASE U5500_GPIO2_BASE
+#define U5500_GPIOBANK4_BASE U5500_GPIO3_BASE
+#define U5500_GPIOBANK5_BASE U5500_GPIO4_BASE
+#define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80)
+#define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100)
+
+#define U5500_MBOX_BASE (U5500_MODEM_BASE + 0xFFD1000)
+#define U5500_MBOX0_PEER_START (U5500_MBOX_BASE + 0x40)
+#define U5500_MBOX0_PEER_END (U5500_MBOX_BASE + 0x5F)
+#define U5500_MBOX0_LOCAL_START (U5500_MBOX_BASE + 0x60)
+#define U5500_MBOX0_LOCAL_END (U5500_MBOX_BASE + 0x7F)
+#define U5500_MBOX1_PEER_START (U5500_MBOX_BASE + 0x80)
+#define U5500_MBOX1_PEER_END (U5500_MBOX_BASE + 0x9F)
+#define U5500_MBOX1_LOCAL_START (U5500_MBOX_BASE + 0xA0)
+#define U5500_MBOX1_LOCAL_END (U5500_MBOX_BASE + 0xBF)
+#define U5500_MBOX2_PEER_START (U5500_MBOX_BASE + 0x00)
+#define U5500_MBOX2_PEER_END (U5500_MBOX_BASE + 0x1F)
+#define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20)
+#define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F)
+
+#define U5500_ACCCON_BASE_SEC (0xBFFF0000)
+#define U5500_ACCCON_BASE (0xBFFF1000)
+#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020)
+#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC)
+
+#define U5500_ESRAM_BASE 0x40000000
+#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000
+#define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET)
+
+#define U5500_MCDE_SIZE 0x1000
+#define U5500_DSI_LINK_SIZE 0x1000
+#define U5500_DSI_LINK_COUNT 0x2
+#define U5500_DSI_LINK1_BASE (U5500_MCDE_BASE + U5500_MCDE_SIZE)
+#define U5500_DSI_LINK2_BASE (U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
new file mode 100644
index 00000000..04999710
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_DB8500_REGS_H
+#define __MACH_DB8500_REGS_H
+
+/* Base address and bank offsets for ESRAM */
+#define U8500_ESRAM_BASE 0x40000000
+#define U8500_ESRAM_BANK_SIZE 0x00020000
+#define U8500_ESRAM_BANK0 U8500_ESRAM_BASE
+#define U8500_ESRAM_BANK1 (U8500_ESRAM_BASE + U8500_ESRAM_BANK_SIZE)
+#define U8500_ESRAM_BANK2 (U8500_ESRAM_BANK1 + U8500_ESRAM_BANK_SIZE)
+#define U8500_ESRAM_BANK3 (U8500_ESRAM_BANK2 + U8500_ESRAM_BANK_SIZE)
+#define U8500_ESRAM_BANK4 (U8500_ESRAM_BANK3 + U8500_ESRAM_BANK_SIZE)
+/*
+ * on V1 DMA uses 4KB for logical parameters position is right after the 64KB
+ * reserved for security
+ */
+#define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000
+
+#define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET)
+#define U8500_DMA_LCPA_BASE_ED (U8500_ESRAM_BANK4 + 0x4000)
+
+#define U8500_PER3_BASE 0x80000000
+#define U8500_STM_BASE 0x80100000
+#define U8500_STM_REG_BASE (U8500_STM_BASE + 0xF000)
+#define U8500_PER2_BASE 0x80110000
+#define U8500_PER1_BASE 0x80120000
+#define U8500_B2R2_BASE 0x80130000
+#define U8500_HSEM_BASE 0x80140000
+#define U8500_PER4_BASE 0x80150000
+#define U8500_TPIU_BASE 0x80190000
+#define U8500_ICN_BASE 0x81000000
+
+#define U8500_BOOT_ROM_BASE 0x90000000
+/* ASIC ID is at 0xbf4 offset within this region */
+#define U8500_ASIC_ID_BASE 0x9001D000
+
+#define U8500_PER6_BASE 0xa03c0000
+#define U8500_PER5_BASE 0xa03e0000
+#define U8500_PER7_BASE_ED 0xa03d0000
+
+#define U8500_SVA_BASE 0xa0100000
+#define U8500_SIA_BASE 0xa0200000
+
+#define U8500_SGA_BASE 0xa0300000
+#define U8500_MCDE_BASE 0xa0350000
+#define U8500_DMA_BASE_ED 0xa0362000
+#define U8500_DMA_BASE 0x801C0000 /* v1 */
+
+#define U8500_SBAG_BASE 0xa0390000
+
+#define U8500_SCU_BASE 0xa0410000
+#define U8500_GIC_CPU_BASE 0xa0410100
+#define U8500_TWD_BASE 0xa0410600
+#define U8500_GIC_DIST_BASE 0xa0411000
+#define U8500_L2CC_BASE 0xa0412000
+
+#define U8500_MODEM_I2C 0xb7e02000
+
+#define U8500_GPIO0_BASE (U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE (U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO3_BASE (U8500_PER5_BASE + 0x1E000)
+
+/* per7 base addresses */
+#define U8500_CR_BASE_ED (U8500_PER7_BASE_ED + 0x8000)
+#define U8500_MTU0_BASE_ED (U8500_PER7_BASE_ED + 0xa000)
+#define U8500_MTU1_BASE_ED (U8500_PER7_BASE_ED + 0xb000)
+#define U8500_TZPC0_BASE_ED (U8500_PER7_BASE_ED + 0xc000)
+#define U8500_CLKRST7_BASE_ED (U8500_PER7_BASE_ED + 0xf000)
+
+#define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000)
+
+/* per6 base addresses */
+#define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000)
+#define U8500_HASH0_BASE (U8500_PER6_BASE + 0x1000)
+#define U8500_HASH1_BASE (U8500_PER6_BASE + 0x2000)
+#define U8500_PKA_BASE (U8500_PER6_BASE + 0x4000)
+#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x5100)
+#define U8500_MTU0_BASE (U8500_PER6_BASE + 0x6000) /* v1 */
+#define U8500_MTU1_BASE (U8500_PER6_BASE + 0x7000) /* v1 */
+#define U8500_CR_BASE (U8500_PER6_BASE + 0x8000) /* v1 */
+#define U8500_CRYP0_BASE (U8500_PER6_BASE + 0xa000)
+#define U8500_CRYP1_BASE (U8500_PER6_BASE + 0xb000)
+#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000)
+
+/* per5 base addresses */
+#define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000)
+#define U8500_CLKRST5_BASE (U8500_PER5_BASE + 0x1f000)
+
+/* per4 base addresses */
+#define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x00000)
+#define U8500_BACKUPRAM1_BASE (U8500_PER4_BASE + 0x01000)
+#define U8500_RTT0_BASE (U8500_PER4_BASE + 0x02000)
+#define U8500_RTT1_BASE (U8500_PER4_BASE + 0x03000)
+#define U8500_RTC_BASE (U8500_PER4_BASE + 0x04000)
+#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000)
+#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
+#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
+#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
+#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
+
+/* per3 base addresses */
+#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000)
+#define U8500_SSP0_BASE (U8500_PER3_BASE + 0x2000)
+#define U8500_SSP1_BASE (U8500_PER3_BASE + 0x3000)
+#define U8500_I2C0_BASE (U8500_PER3_BASE + 0x4000)
+#define U8500_SDI2_BASE (U8500_PER3_BASE + 0x5000)
+#define U8500_SKE_BASE (U8500_PER3_BASE + 0x6000)
+#define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000)
+#define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000)
+#define U8500_CLKRST3_BASE (U8500_PER3_BASE + 0xf000)
+
+/* per2 base addresses */
+#define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000)
+#define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000)
+#define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000)
+#define U8500_PWL_BASE (U8500_PER2_BASE + 0x3000)
+#define U8500_SDI4_BASE (U8500_PER2_BASE + 0x4000)
+#define U8500_MSP2_BASE (U8500_PER2_BASE + 0x7000)
+#define U8500_SDI1_BASE (U8500_PER2_BASE + 0x8000)
+#define U8500_SDI3_BASE (U8500_PER2_BASE + 0x9000)
+#define U8500_SPI0_BASE (U8500_PER2_BASE + 0xa000)
+#define U8500_HSIR_BASE (U8500_PER2_BASE + 0xb000)
+#define U8500_HSIT_BASE (U8500_PER2_BASE + 0xc000)
+#define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000)
+
+/* per1 base addresses */
+#define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000)
+#define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000)
+#define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000)
+#define U8500_MSP3_BASE (U8500_PER1_BASE + 0x5000)
+#define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000)
+#define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000)
+#define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000)
+#define U8500_I2C4_BASE (U8500_PER1_BASE + 0xa000)
+#define U8500_SLIM0_BASE (U8500_PER1_BASE + 0xb000)
+#define U8500_CLKRST1_BASE (U8500_PER1_BASE + 0xf000)
+
+#define U8500_SHRM_GOP_INTERRUPT_BASE 0xB7C00040
+
+#define U8500_GPIOBANK0_BASE U8500_GPIO0_BASE
+#define U8500_GPIOBANK1_BASE (U8500_GPIO0_BASE + 0x80)
+#define U8500_GPIOBANK2_BASE U8500_GPIO1_BASE
+#define U8500_GPIOBANK3_BASE (U8500_GPIO1_BASE + 0x80)
+#define U8500_GPIOBANK4_BASE (U8500_GPIO1_BASE + 0x100)
+#define U8500_GPIOBANK5_BASE (U8500_GPIO1_BASE + 0x180)
+#define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE
+#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80)
+#define U8500_GPIOBANK8_BASE U8500_GPIO3_BASE
+
+#define U8500_MCDE_SIZE 0x1000
+#define U8500_DSI_LINK_SIZE 0x1000
+#define U8500_DSI_LINK1_BASE (U8500_MCDE_BASE + U8500_MCDE_SIZE)
+#define U8500_DSI_LINK2_BASE (U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE)
+#define U8500_DSI_LINK3_BASE (U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE)
+#define U8500_DSI_LINK_COUNT 0x3
+
+/* Modem and APE physical addresses */
+#define U8500_MODEM_BASE 0xe000000
+#define U8500_APE_BASE 0x6000000
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S
new file mode 100644
index 00000000..700fb05e
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/debug-macro.S
@@ -0,0 +1,43 @@
+/*
+ * Debugging macro include header
+ *
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <mach/hardware.h>
+
+#if CONFIG_UX500_DEBUG_UART > 2
+#error Invalid Ux500 debug UART
+#endif
+
+/*
+ * DEBUG_LL only works if only one SOC is built in. We don't use #else below
+ * in order to get "__UX500_UART redefined" warnings if more than one SOC is
+ * built, so that there's some hint during the build that something is wrong.
+ */
+
+#ifdef CONFIG_UX500_SOC_DB5500
+#define __UX500_UART(n) U5500_UART##n##_BASE
+#endif
+
+#ifdef CONFIG_UX500_SOC_DB8500
+#define __UX500_UART(n) U8500_UART##n##_BASE
+#endif
+
+#ifndef __UX500_UART
+#error Unknown SOC
+#endif
+
+#define UX500_UART(n) __UX500_UART(n)
+#define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_BASE @ no, physical address
+ ldr \rv, =IO_ADDRESS(UART_BASE) @ yes, virtual address
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h
new file mode 100644
index 00000000..020b6369
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/devices.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __ASM_ARCH_DEVICES_H__
+#define __ASM_ARCH_DEVICES_H__
+
+struct platform_device;
+struct amba_device;
+
+extern struct platform_device u5500_gpio_devs[];
+extern struct platform_device u8500_gpio_devs[];
+
+extern struct amba_device ux500_pl031_device;
+
+extern struct platform_device u8500_dma40_device;
+extern struct platform_device ux500_ske_keypad_device;
+
+void dma40_u8500ed_fixup(void);
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S
new file mode 100644
index 00000000..071bba94
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/entry-macro.S
@@ -0,0 +1,20 @@
+/*
+ * Low-level IRQ helper macros for U8500 platforms
+ *
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This file is a copy of ARM Realview platform.
+ * -just satisfied checkpatch script.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-ux500/include/mach/gpio.h b/arch/arm/mach-ux500/include/mach/gpio.h
new file mode 100644
index 00000000..3c4cd31a
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/gpio.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_ARCH_GPIO_H
+#define __ASM_ARCH_GPIO_H
+
+/*
+ * 288 (#267 is the highest one actually hooked up) onchip GPIOs, plus enough
+ * room for a couple of GPIO expanders.
+ */
+#define ARCH_NR_GPIOS 350
+
+#include <plat/gpio.h>
+
+#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
new file mode 100644
index 00000000..470ac526
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * U8500 hardware definitions
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* macros to get at IO space when running virtually
+ * We dont map all the peripherals, let ioremap do
+ * this for us. We map only very basic peripherals here.
+ */
+#define U8500_IO_VIRTUAL 0xf0000000
+#define U8500_IO_PHYSICAL 0xa0000000
+
+/* this macro is used in assembly, so no cast */
+#define IO_ADDRESS(x) \
+ (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)
+
+/* typesafe io address */
+#define __io_address(n) __io(IO_ADDRESS(n))
+/* used by some plat-nomadik code */
+#define io_p2v(n) __io_address(n)
+
+#include <mach/db8500-regs.h>
+#include <mach/db5500-regs.h>
+
+#ifndef __ASSEMBLY__
+
+#include <mach/id.h>
+extern void __iomem *_PRCMU_BASE;
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#endif
+
+#endif /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
new file mode 100644
index 00000000..02b541a3
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_UX500_ID
+#define __MACH_UX500_ID
+
+/**
+ * struct dbx500_asic_id - fields of the ASIC ID
+ * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard"
+ * @partnumber: hithereto 0x8500 for DB8500
+ * @revision: version code in the series
+ */
+struct dbx500_asic_id {
+ u16 partnumber;
+ u8 revision;
+ u8 process;
+};
+
+extern struct dbx500_asic_id dbx500_id;
+
+static inline unsigned int __attribute_const__ dbx500_partnumber(void)
+{
+ return dbx500_id.partnumber;
+}
+
+static inline unsigned int __attribute_const__ dbx500_revision(void)
+{
+ return dbx500_id.revision;
+}
+
+/*
+ * SOCs
+ */
+
+static inline bool __attribute_const__ cpu_is_u8500(void)
+{
+ return dbx500_partnumber() == 0x8500;
+}
+
+static inline bool __attribute_const__ cpu_is_u5500(void)
+{
+ return dbx500_partnumber() == 0x5500;
+}
+
+/*
+ * 8500 revisions
+ */
+
+static inline bool __attribute_const__ cpu_is_u8500ed(void)
+{
+ return cpu_is_u8500() && dbx500_revision() == 0x00;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v1(void)
+{
+ return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v10(void)
+{
+ return cpu_is_u8500() && dbx500_revision() == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v11(void)
+{
+ return cpu_is_u8500() && dbx500_revision() == 0xA1;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v2(void)
+{
+ return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0);
+}
+
+static inline bool cpu_is_u8500v20(void)
+{
+ return cpu_is_u8500() && (dbx500_revision() == 0xB0);
+}
+
+static inline bool cpu_is_u8500v21(void)
+{
+ return cpu_is_u8500() && (dbx500_revision() == 0xB1);
+}
+
+static inline bool cpu_is_u8500v20_or_later(void)
+{
+ return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11();
+}
+
+static inline bool ux500_is_svp(void)
+{
+ return false;
+}
+
+#define ux500_unknown_soc() BUG()
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/io.h b/arch/arm/mach-ux500/include/mach/io.h
new file mode 100644
index 00000000..1cf3f44c
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-u8500/include/mach/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
new file mode 100644
index 00000000..47969909
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_BOARD_MOP500_H
+#define __MACH_IRQS_BOARD_MOP500_H
+
+/* Number of AB8500 irqs is taken from header file */
+#include <linux/mfd/ab8500.h>
+
+#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
+#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
+ + AB8500_NR_IRQS)
+
+/* TC35892 */
+#define TC35892_NR_INTERNAL_IRQS 8
+#define TC35892_INT_GPIO(x) (TC35892_NR_INTERNAL_IRQS + (x))
+#define TC35892_NR_GPIOS 24
+#define TC35892_NR_IRQS TC35892_INT_GPIO(TC35892_NR_GPIOS)
+
+#define MOP500_EGPIO_NR_IRQS TC35892_NR_IRQS
+
+#define MOP500_EGPIO_IRQ_BASE MOP500_AB8500_IRQ_END
+#define MOP500_EGPIO_IRQ_END (MOP500_EGPIO_IRQ_BASE \
+ + MOP500_EGPIO_NR_IRQS)
+/* STMPE1601 irqs */
+#define STMPE_NR_INTERNAL_IRQS 9
+#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
+#define STMPE_NR_GPIOS 24
+#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
+
+#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
+#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
+
+#define MOP500_STMPE1601_IRQ_END \
+ MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
+
+/* AB8500 virtual gpio IRQ */
+#define AB8500_VIR_GPIO_NR_IRQS 16
+
+#define MOP500_AB8500_VIR_GPIO_IRQ_BASE \
+ MOP500_STMPE1601_IRQ_END
+#define MOP500_AB8500_VIR_GPIO_IRQ_END \
+ (MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS)
+
+#define MOP500_NR_IRQS MOP500_AB8500_VIR_GPIO_IRQ_END
+
+#define MOP500_IRQ_END MOP500_NR_IRQS
+
+/*
+ * We may have several boards, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_BOARD_START remains the same for either board.
+ */
+#if MOP500_IRQ_END > IRQ_BOARD_END
+#undef IRQ_BOARD_END
+#define IRQ_BOARD_END MOP500_IRQ_END
+#endif
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h b/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
new file mode 100644
index 00000000..29d972c7
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_BOARD_U5500_H
+#define __MACH_IRQS_BOARD_U5500_H
+
+#define AB5500_NR_IRQS 5
+#define IRQ_AB5500_BASE IRQ_BOARD_START
+#define IRQ_AB5500_END (IRQ_AB5500_BASE + AB5500_NR_IRQS)
+
+#define U5500_IRQ_END IRQ_AB5500_END
+
+#if IRQ_BOARD_END < U5500_IRQ_END
+#undef IRQ_BOARD_END
+#define IRQ_BOARD_END U5500_IRQ_END
+#endif
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
new file mode 100644
index 00000000..77239776
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-db5500.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_DB5500_H
+#define __MACH_IRQS_DB5500_H
+
+#define IRQ_DB5500_MTU0 (IRQ_SHPI_START + 4)
+#define IRQ_DB5500_SPI2 (IRQ_SHPI_START + 6)
+#define IRQ_DB5500_PMU0 (IRQ_SHPI_START + 7)
+#define IRQ_DB5500_SPI0 (IRQ_SHPI_START + 8)
+#define IRQ_DB5500_RTT (IRQ_SHPI_START + 9)
+#define IRQ_DB5500_PKA (IRQ_SHPI_START + 10)
+#define IRQ_DB5500_UART0 (IRQ_SHPI_START + 11)
+#define IRQ_DB5500_I2C3 (IRQ_SHPI_START + 12)
+#define IRQ_DB5500_L2CC (IRQ_SHPI_START + 13)
+#define IRQ_DB5500_MSP0 (IRQ_SHPI_START + 14)
+#define IRQ_DB5500_CRYP1 (IRQ_SHPI_START + 15)
+#define IRQ_DB5500_PMU1 (IRQ_SHPI_START + 16)
+#define IRQ_DB5500_MTU1 (IRQ_SHPI_START + 17)
+#define IRQ_DB5500_RTC (IRQ_SHPI_START + 18)
+#define IRQ_DB5500_UART1 (IRQ_SHPI_START + 19)
+#define IRQ_DB5500_USB_WAKEUP (IRQ_SHPI_START + 20)
+#define IRQ_DB5500_I2C0 (IRQ_SHPI_START + 21)
+#define IRQ_DB5500_I2C1 (IRQ_SHPI_START + 22)
+#define IRQ_DB5500_USBOTG (IRQ_SHPI_START + 23)
+#define IRQ_DB5500_DMA_SECURE (IRQ_SHPI_START + 24)
+#define IRQ_DB5500_DMA (IRQ_SHPI_START + 25)
+#define IRQ_DB5500_UART2 (IRQ_SHPI_START + 26)
+#define IRQ_DB5500_ICN_PMU1 (IRQ_SHPI_START + 27)
+#define IRQ_DB5500_ICN_PMU2 (IRQ_SHPI_START + 28)
+#define IRQ_DB5500_UART3 (IRQ_SHPI_START + 29)
+#define IRQ_DB5500_SPI3 (IRQ_SHPI_START + 30)
+#define IRQ_DB5500_SDMMC4 (IRQ_SHPI_START + 31)
+#define IRQ_DB5500_IRRC (IRQ_SHPI_START + 33)
+#define IRQ_DB5500_IRDA_FT (IRQ_SHPI_START + 34)
+#define IRQ_DB5500_IRDA_SD (IRQ_SHPI_START + 35)
+#define IRQ_DB5500_IRDA_FI (IRQ_SHPI_START + 36)
+#define IRQ_DB5500_IRDA_FD (IRQ_SHPI_START + 37)
+#define IRQ_DB5500_FSMC_CODEREADY (IRQ_SHPI_START + 38)
+#define IRQ_DB5500_FSMC_NANDWAIT (IRQ_SHPI_START + 39)
+#define IRQ_DB5500_AB5500 (IRQ_SHPI_START + 40)
+#define IRQ_DB5500_SDMMC2 (IRQ_SHPI_START + 41)
+#define IRQ_DB5500_SIA (IRQ_SHPI_START + 42)
+#define IRQ_DB5500_SIA2 (IRQ_SHPI_START + 43)
+#define IRQ_DB5500_HVA (IRQ_SHPI_START + 44)
+#define IRQ_DB5500_HVA2 (IRQ_SHPI_START + 45)
+#define IRQ_DB5500_PRCMU0 (IRQ_SHPI_START + 46)
+#define IRQ_DB5500_PRCMU1 (IRQ_SHPI_START + 47)
+#define IRQ_DB5500_DISP (IRQ_SHPI_START + 48)
+#define IRQ_DB5500_SDMMC1 (IRQ_SHPI_START + 50)
+#define IRQ_DB5500_MSP1 (IRQ_SHPI_START + 52)
+#define IRQ_DB5500_KBD (IRQ_SHPI_START + 53)
+#define IRQ_DB5500_I2C2 (IRQ_SHPI_START + 55)
+#define IRQ_DB5500_B2R2 (IRQ_SHPI_START + 56)
+#define IRQ_DB5500_CRYP0 (IRQ_SHPI_START + 57)
+#define IRQ_DB5500_SDMMC3 (IRQ_SHPI_START + 59)
+#define IRQ_DB5500_SDMMC0 (IRQ_SHPI_START + 60)
+#define IRQ_DB5500_HSEM (IRQ_SHPI_START + 61)
+#define IRQ_DB5500_SBAG (IRQ_SHPI_START + 63)
+#define IRQ_DB5500_MODEM (IRQ_SHPI_START + 65)
+#define IRQ_DB5500_SPI1 (IRQ_SHPI_START + 96)
+#define IRQ_DB5500_MSP2 (IRQ_SHPI_START + 98)
+#define IRQ_DB5500_SRPTIMER (IRQ_SHPI_START + 101)
+#define IRQ_DB5500_CTI0 (IRQ_SHPI_START + 108)
+#define IRQ_DB5500_CTI1 (IRQ_SHPI_START + 109)
+#define IRQ_DB5500_ICN_ERR (IRQ_SHPI_START + 110)
+#define IRQ_DB5500_MALI_PPMMU (IRQ_SHPI_START + 112)
+#define IRQ_DB5500_MALI_PP (IRQ_SHPI_START + 113)
+#define IRQ_DB5500_MALI_GPMMU (IRQ_SHPI_START + 114)
+#define IRQ_DB5500_MALI_GP (IRQ_SHPI_START + 115)
+#define IRQ_DB5500_MALI (IRQ_SHPI_START + 116)
+#define IRQ_DB5500_PRCMU_SEM (IRQ_SHPI_START + 118)
+#define IRQ_DB5500_GPIO0 (IRQ_SHPI_START + 119)
+#define IRQ_DB5500_GPIO1 (IRQ_SHPI_START + 120)
+#define IRQ_DB5500_GPIO2 (IRQ_SHPI_START + 121)
+#define IRQ_DB5500_GPIO3 (IRQ_SHPI_START + 122)
+#define IRQ_DB5500_GPIO4 (IRQ_SHPI_START + 123)
+#define IRQ_DB5500_GPIO5 (IRQ_SHPI_START + 124)
+#define IRQ_DB5500_GPIO6 (IRQ_SHPI_START + 125)
+#define IRQ_DB5500_GPIO7 (IRQ_SHPI_START + 126)
+
+#ifdef CONFIG_UX500_SOC_DB5500
+
+/*
+ * After the GPIO ones we reserve a range of IRQ:s in which virtual
+ * IRQ:s representing modem IRQ:s can be allocated
+ */
+#define IRQ_MODEM_EVENTS_BASE IRQ_SOC_START
+#define IRQ_MODEM_EVENTS_NBR 72
+#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
+
+/* List of virtual IRQ:s that are allocated from the range above */
+#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43)
+#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45)
+#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41)
+
+/*
+ * We may have several SoCs, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_SOC_START remains the same for either SoC.
+ */
+#if IRQ_SOC_END < IRQ_MODEM_EVENTS_END
+#undef IRQ_SOC_END
+#define IRQ_SOC_END IRQ_MODEM_EVENTS_END
+#endif
+
+#endif /* CONFIG_UX500_SOC_DB5500 */
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db8500.h b/arch/arm/mach-ux500/include/mach/irqs-db8500.h
new file mode 100644
index 00000000..68bc1497
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-db8500.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_DB8500_H
+#define __MACH_IRQS_DB8500_H
+
+#define IRQ_DB8500_MTU0 (IRQ_SHPI_START + 4)
+#define IRQ_DB8500_SPI2 (IRQ_SHPI_START + 6)
+#define IRQ_DB8500_PMU (IRQ_SHPI_START + 7)
+#define IRQ_DB8500_SPI0 (IRQ_SHPI_START + 8)
+#define IRQ_DB8500_RTT (IRQ_SHPI_START + 9)
+#define IRQ_DB8500_PKA (IRQ_SHPI_START + 10)
+#define IRQ_DB8500_UART0 (IRQ_SHPI_START + 11)
+#define IRQ_DB8500_I2C3 (IRQ_SHPI_START + 12)
+#define IRQ_DB8500_L2CC (IRQ_SHPI_START + 13)
+#define IRQ_DB8500_SSP0 (IRQ_SHPI_START + 14)
+#define IRQ_DB8500_CRYP1 (IRQ_SHPI_START + 15)
+#define IRQ_DB8500_MSP1_RX (IRQ_SHPI_START + 16)
+#define IRQ_DB8500_MTU1 (IRQ_SHPI_START + 17)
+#define IRQ_DB8500_RTC (IRQ_SHPI_START + 18)
+#define IRQ_DB8500_UART1 (IRQ_SHPI_START + 19)
+#define IRQ_DB8500_USB_WAKEUP (IRQ_SHPI_START + 20)
+#define IRQ_DB8500_I2C0 (IRQ_SHPI_START + 21)
+#define IRQ_DB8500_I2C1 (IRQ_SHPI_START + 22)
+#define IRQ_DB8500_USBOTG (IRQ_SHPI_START + 23)
+#define IRQ_DB8500_DMA_SECURE (IRQ_SHPI_START + 24)
+#define IRQ_DB8500_DMA (IRQ_SHPI_START + 25)
+#define IRQ_DB8500_UART2 (IRQ_SHPI_START + 26)
+#define IRQ_DB8500_ICN_PMU1 (IRQ_SHPI_START + 27)
+#define IRQ_DB8500_ICN_PMU2 (IRQ_SHPI_START + 28)
+#define IRQ_DB8500_HSIR_EXCEP (IRQ_SHPI_START + 29)
+#define IRQ_DB8500_MSP0 (IRQ_SHPI_START + 31)
+#define IRQ_DB8500_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32)
+#define IRQ_DB8500_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33)
+#define IRQ_DB8500_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34)
+#define IRQ_DB8500_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35)
+#define IRQ_DB8500_HSIR_CH4_OVRRUN (IRQ_SHPI_START + 36)
+#define IRQ_DB8500_HSIR_CH5_OVRRUN (IRQ_SHPI_START + 37)
+#define IRQ_DB8500_HSIR_CH6_OVRRUN (IRQ_SHPI_START + 38)
+#define IRQ_DB8500_HSIR_CH7_OVRRUN (IRQ_SHPI_START + 39)
+#define IRQ_DB8500_AB8500 (IRQ_SHPI_START + 40)
+#define IRQ_DB8500_SDMMC2 (IRQ_SHPI_START + 41)
+#define IRQ_DB8500_SIA (IRQ_SHPI_START + 42)
+#define IRQ_DB8500_SIA2 (IRQ_SHPI_START + 43)
+#define IRQ_DB8500_SVA (IRQ_SHPI_START + 44)
+#define IRQ_DB8500_SVA2 (IRQ_SHPI_START + 45)
+#define IRQ_DB8500_PRCMU0 (IRQ_SHPI_START + 46)
+#define IRQ_DB8500_PRCMU1 (IRQ_SHPI_START + 47)
+#define IRQ_DB8500_DISP (IRQ_SHPI_START + 48)
+#define IRQ_DB8500_SPI3 (IRQ_SHPI_START + 49)
+#define IRQ_DB8500_SDMMC1 (IRQ_SHPI_START + 50)
+#define IRQ_DB8500_I2C4 (IRQ_SHPI_START + 51)
+#define IRQ_DB8500_SSP1 (IRQ_SHPI_START + 52)
+#define IRQ_DB8500_SKE (IRQ_SHPI_START + 53)
+#define IRQ_DB8500_KB (IRQ_SHPI_START + 54)
+#define IRQ_DB8500_I2C2 (IRQ_SHPI_START + 55)
+#define IRQ_DB8500_B2R2 (IRQ_SHPI_START + 56)
+#define IRQ_DB8500_CRYP0 (IRQ_SHPI_START + 57)
+#define IRQ_DB8500_SDMMC3 (IRQ_SHPI_START + 59)
+#define IRQ_DB8500_SDMMC0 (IRQ_SHPI_START + 60)
+#define IRQ_DB8500_HSEM (IRQ_SHPI_START + 61)
+#define IRQ_DB8500_MSP1 (IRQ_SHPI_START + 62)
+#define IRQ_DB8500_SBAG (IRQ_SHPI_START + 63)
+#define IRQ_DB8500_SPI1 (IRQ_SHPI_START + 96)
+#define IRQ_DB8500_SRPTIMER (IRQ_SHPI_START + 97)
+#define IRQ_DB8500_MSP2 (IRQ_SHPI_START + 98)
+#define IRQ_DB8500_SDMMC4 (IRQ_SHPI_START + 99)
+#define IRQ_DB8500_SDMMC5 (IRQ_SHPI_START + 100)
+#define IRQ_DB8500_HSIRD0 (IRQ_SHPI_START + 104)
+#define IRQ_DB8500_HSIRD1 (IRQ_SHPI_START + 105)
+#define IRQ_DB8500_HSITD0 (IRQ_SHPI_START + 106)
+#define IRQ_DB8500_HSITD1 (IRQ_SHPI_START + 107)
+#define IRQ_DB8500_CTI0 (IRQ_SHPI_START + 108)
+#define IRQ_DB8500_CTI1 (IRQ_SHPI_START + 109)
+#define IRQ_DB8500_ICN_ERR (IRQ_SHPI_START + 110)
+#define IRQ_DB8500_MALI_PPMMU (IRQ_SHPI_START + 112)
+#define IRQ_DB8500_MALI_PP (IRQ_SHPI_START + 113)
+#define IRQ_DB8500_MALI_GPMMU (IRQ_SHPI_START + 114)
+#define IRQ_DB8500_MALI_GP (IRQ_SHPI_START + 115)
+#define IRQ_DB8500_MALI (IRQ_SHPI_START + 116)
+#define IRQ_DB8500_PRCMU_SEM (IRQ_SHPI_START + 118)
+#define IRQ_DB8500_GPIO0 (IRQ_SHPI_START + 119)
+#define IRQ_DB8500_GPIO1 (IRQ_SHPI_START + 120)
+#define IRQ_DB8500_GPIO2 (IRQ_SHPI_START + 121)
+#define IRQ_DB8500_GPIO3 (IRQ_SHPI_START + 122)
+#define IRQ_DB8500_GPIO4 (IRQ_SHPI_START + 123)
+#define IRQ_DB8500_GPIO5 (IRQ_SHPI_START + 124)
+#define IRQ_DB8500_GPIO6 (IRQ_SHPI_START + 125)
+#define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126)
+#define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127)
+
+#define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71)
+#define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66)
+#define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65)
+
+#define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83)
+#define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78)
+#define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77)
+
+#ifdef CONFIG_UX500_SOC_DB8500
+
+/* Virtual interrupts corresponding to the PRCMU wakeups. */
+#define IRQ_PRCMU_BASE IRQ_SOC_START
+#define NUM_PRCMU_WAKEUPS (IRQ_PRCMU_END - IRQ_PRCMU_BASE)
+
+#define IRQ_PRCMU_RTC (IRQ_PRCMU_BASE)
+#define IRQ_PRCMU_RTT0 (IRQ_PRCMU_BASE + 1)
+#define IRQ_PRCMU_RTT1 (IRQ_PRCMU_BASE + 2)
+#define IRQ_PRCMU_HSI0 (IRQ_PRCMU_BASE + 3)
+#define IRQ_PRCMU_HSI1 (IRQ_PRCMU_BASE + 4)
+#define IRQ_PRCMU_CA_WAKE (IRQ_PRCMU_BASE + 5)
+#define IRQ_PRCMU_USB (IRQ_PRCMU_BASE + 6)
+#define IRQ_PRCMU_ABB (IRQ_PRCMU_BASE + 7)
+#define IRQ_PRCMU_ABB_FIFO (IRQ_PRCMU_BASE + 8)
+#define IRQ_PRCMU_ARM (IRQ_PRCMU_BASE + 9)
+#define IRQ_PRCMU_MODEM_SW_RESET_REQ (IRQ_PRCMU_BASE + 10)
+#define IRQ_PRCMU_GPIO0 (IRQ_PRCMU_BASE + 11)
+#define IRQ_PRCMU_GPIO1 (IRQ_PRCMU_BASE + 12)
+#define IRQ_PRCMU_GPIO2 (IRQ_PRCMU_BASE + 13)
+#define IRQ_PRCMU_GPIO3 (IRQ_PRCMU_BASE + 14)
+#define IRQ_PRCMU_GPIO4 (IRQ_PRCMU_BASE + 15)
+#define IRQ_PRCMU_GPIO5 (IRQ_PRCMU_BASE + 16)
+#define IRQ_PRCMU_GPIO6 (IRQ_PRCMU_BASE + 17)
+#define IRQ_PRCMU_GPIO7 (IRQ_PRCMU_BASE + 18)
+#define IRQ_PRCMU_GPIO8 (IRQ_PRCMU_BASE + 19)
+#define IRQ_PRCMU_CA_SLEEP (IRQ_PRCMU_BASE + 20)
+#define IRQ_PRCMU_HOTMON_LOW (IRQ_PRCMU_BASE + 21)
+#define IRQ_PRCMU_HOTMON_HIGH (IRQ_PRCMU_BASE + 22)
+#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
+
+/*
+ * We may have several SoCs, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_SOC_START remains the same for either SoC.
+ */
+#if IRQ_SOC_END < IRQ_PRCMU_END
+#undef IRQ_SOC_END
+#define IRQ_SOC_END IRQ_PRCMU_END
+#endif
+
+#endif /* CONFIG_UX500_SOC_DB8500 */
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
new file mode 100644
index 00000000..9db68d26
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * 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_IRQS_H
+#define ASM_ARCH_IRQS_H
+
+#include <mach/hardware.h>
+
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+
+/* Shared Peripheral Interrupt (SHPI) */
+#define IRQ_SHPI_START 32
+
+/*
+ * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't
+ * add any other IRQs here, use the irqs-dbx500.h files.
+ */
+#define IRQ_MTU0 (IRQ_SHPI_START + 4)
+
+#define DBX500_NR_INTERNAL_IRQS 160
+
+/* After chip-specific IRQ numbers we have the GPIO ones */
+#define NOMADIK_NR_GPIO 288
+#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
+#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS)
+#define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+
+#define IRQ_SOC_START IRQ_GPIO_END
+/* This will be overridden by SoC-specific irq headers */
+#define IRQ_SOC_END IRQ_SOC_START
+
+#include <mach/irqs-db5500.h>
+#include <mach/irqs-db8500.h>
+
+#define IRQ_BOARD_START IRQ_SOC_END
+/* This will be overridden by board-specific irq headers */
+#define IRQ_BOARD_END IRQ_BOARD_START
+
+#ifdef CONFIG_MACH_U8500
+#include <mach/irqs-board-mop500.h>
+#endif
+
+#ifdef CONFIG_MACH_U5500
+#include <mach/irqs-board-u5500.h>
+#endif
+
+#define NR_IRQS IRQ_BOARD_END
+
+#endif /* ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-ux500/include/mach/mbox-db5500.h b/arch/arm/mach-ux500/include/mach/mbox-db5500.h
new file mode 100644
index 00000000..7f9da4d2
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/mbox-db5500.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef __INC_STE_MBOX_H
+#define __INC_STE_MBOX_H
+
+#define MBOX_BUF_SIZE 16
+#define MBOX_NAME_SIZE 8
+
+/**
+ * mbox_recv_cb_t - Definition of the mailbox callback.
+ * @mbox_msg: The mailbox message.
+ * @priv: The clients private data as specified in the call to mbox_setup.
+ *
+ * This function will be called upon reception of new mailbox messages.
+ */
+typedef void mbox_recv_cb_t (u32 mbox_msg, void *priv);
+
+/**
+ * struct mbox - Mailbox instance struct
+ * @list: Linked list head.
+ * @pdev: Pointer to device struct.
+ * @cb: Callback function. Will be called
+ * when new data is received.
+ * @client_data: Clients private data. Will be sent back
+ * in the callback function.
+ * @virtbase_peer: Virtual address for outgoing mailbox.
+ * @virtbase_local: Virtual address for incoming mailbox.
+ * @buffer: Then internal queue for outgoing messages.
+ * @name: Name of this mailbox.
+ * @buffer_available: Completion variable to achieve "blocking send".
+ * This variable will be signaled when there is
+ * internal buffer space available.
+ * @client_blocked: To keep track if any client is currently
+ * blocked.
+ * @lock: Spinlock to protect this mailbox instance.
+ * @write_index: Index in internal buffer to write to.
+ * @read_index: Index in internal buffer to read from.
+ * @allocated: Indicates whether this particular mailbox
+ * id has been allocated by someone.
+ */
+struct mbox {
+ struct list_head list;
+ struct platform_device *pdev;
+ mbox_recv_cb_t *cb;
+ void *client_data;
+ void __iomem *virtbase_peer;
+ void __iomem *virtbase_local;
+ u32 buffer[MBOX_BUF_SIZE];
+ char name[MBOX_NAME_SIZE];
+ struct completion buffer_available;
+ u8 client_blocked;
+ spinlock_t lock;
+ u8 write_index;
+ u8 read_index;
+ bool allocated;
+};
+
+/**
+ * mbox_setup - Set up a mailbox and return its instance.
+ * @mbox_id: The ID number of the mailbox. 0 or 1 for modem CPU,
+ * 2 for modem DSP.
+ * @mbox_cb: Pointer to the callback function to be called when a new message
+ * is received.
+ * @priv: Client user data which will be returned in the callback.
+ *
+ * Returns a mailbox instance to be specified in subsequent calls to mbox_send.
+ */
+struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv);
+
+/**
+ * mbox_send - Send a mailbox message.
+ * @mbox: Mailbox instance (returned by mbox_setup)
+ * @mbox_msg: The mailbox message to send.
+ * @block: Specifies whether this call will block until send is possible,
+ * or return an error if the mailbox buffer is full.
+ *
+ * Returns 0 on success or a negative error code on error. -ENOMEM indicates
+ * that the internal buffer is full and you have to try again later (or
+ * specify "block" in order to block until send is possible).
+ */
+int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block);
+
+#endif /*INC_STE_MBOX_H*/
diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h
new file mode 100644
index 00000000..2ef697a6
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/memory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * 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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+#define BUS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
new file mode 100644
index 00000000..a7d363fd
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These symbols are needed for board-specific files to call their
+ * own cpu-specific files
+ */
+#ifndef __ASM_ARCH_SETUP_H
+#define __ASM_ARCH_SETUP_H
+
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+void __init ux500_map_io(void);
+extern void __init u5500_map_io(void);
+extern void __init u8500_map_io(void);
+
+extern void __init u5500_init_devices(void);
+extern void __init u8500_init_devices(void);
+
+extern void __init ux500_init_irq(void);
+
+extern void __init u5500_sdi_init(void);
+
+extern void __init db5500_dma_init(void);
+
+/* We re-use nomadik_timer for this platform */
+extern void nmdk_timer_init(void);
+
+struct amba_device;
+extern void __init amba_add_devices(struct amba_device *devs[], int num);
+
+struct sys_timer;
+extern struct sys_timer ux500_timer;
+
+#define __IO_DEV_DESC(x, sz) { \
+ .virtual = IO_ADDRESS(x), \
+ .pfn = __phys_to_pfn(x), \
+ .length = sz, \
+ .type = MT_DEVICE, \
+}
+
+#define __MEM_DEV_DESC(x, sz) { \
+ .virtual = IO_ADDRESS(x), \
+ .pfn = __phys_to_pfn(x), \
+ .length = sz, \
+ .type = MT_MEMORY, \
+}
+
+#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h
new file mode 100644
index 00000000..c0cd8006
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/system.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ /* yet to be implemented - TODO */
+}
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/timex.h b/arch/arm/mach-ux500/include/mach/timex.h
new file mode 100644
index 00000000..d0942c17
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/timex.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE 110000000
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h
new file mode 100644
index 00000000..088b550c
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/uncompress.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * 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 __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <linux/io.h>
+#include <linux/amba/serial.h>
+#include <mach/hardware.h>
+
+u32 ux500_uart_base;
+
+static void putc(const char c)
+{
+ /* Do nothing if the UART is not enabled. */
+ if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1))
+ return;
+
+ if (c == '\n')
+ putc('\r');
+
+ while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 5))
+ barrier();
+ __raw_writeb(c, ux500_uart_base + UART01x_DR);
+}
+
+static void flush(void)
+{
+ if (!(__raw_readb(ux500_uart_base + UART011_CR) & 0x1))
+ return;
+ while (__raw_readb(ux500_uart_base + UART01x_FR) & (1 << 3))
+ barrier();
+}
+
+static inline void arch_decomp_setup(void)
+{
+ /* Check in run time if we run on an U8500 or U5500 */
+ if (machine_is_u8500() ||
+ machine_is_svp8500v1() ||
+ machine_is_svp8500v2() ||
+ machine_is_hrefv60())
+ ux500_uart_base = U8500_UART2_BASE;
+ else if (machine_is_u5500())
+ ux500_uart_base = U5500_UART0_BASE;
+ else /* not much can be done to help here */
+ ux500_uart_base = U8500_UART2_BASE;
+}
+
+#define arch_decomp_wdog() /* nothing to do here */
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-ux500/include/mach/usb.h b/arch/arm/mach-ux500/include/mach/usb.h
new file mode 100644
index 00000000..d3739d41
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/usb.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#ifndef __ASM_ARCH_USB_H
+#define __ASM_ARCH_USB_H
+
+#include <linux/dmaengine.h>
+
+#define UX500_MUSB_DMA_NUM_RX_CHANNELS 8
+#define UX500_MUSB_DMA_NUM_TX_CHANNELS 8
+
+struct ux500_musb_board_data {
+ void **dma_rx_param_array;
+ void **dma_tx_param_array;
+ u32 num_rx_channels;
+ u32 num_tx_channels;
+ bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+};
+
+void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
+ int *dma_tx_cfg);
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/vmalloc.h b/arch/arm/mach-ux500/include/mach/vmalloc.h
new file mode 100644
index 00000000..a4945cb4
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/vmalloc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * 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
+ */
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
new file mode 100644
index 00000000..5ba11330
--- /dev/null
+++ b/arch/arm/mach-ux500/localtimer.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is heavily based on relaview platform, almost a copy.
+ *
+ * Copyright (C) 2002 ARM 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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/irq.h>
+#include <asm/smp_twd.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-ux500/mbox-db5500.c b/arch/arm/mach-ux500/mbox-db5500.c
new file mode 100644
index 00000000..2b2d51ca
--- /dev/null
+++ b/arch/arm/mach-ux500/mbox-db5500.c
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+/*
+ * Mailbox nomenclature:
+ *
+ * APE MODEM
+ * mbox pairX
+ * ..........................
+ * . .
+ * . peer .
+ * . send ---- .
+ * . --> | | .
+ * . | | .
+ * . ---- .
+ * . .
+ * . local .
+ * . rec ---- .
+ * . | | <-- .
+ * . | | .
+ * . ---- .
+ * .........................
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/completion.h>
+#include <mach/mbox-db5500.h>
+
+#define MBOX_NAME "mbox"
+
+#define MBOX_FIFO_DATA 0x000
+#define MBOX_FIFO_ADD 0x004
+#define MBOX_FIFO_REMOVE 0x008
+#define MBOX_FIFO_THRES_FREE 0x00C
+#define MBOX_FIFO_THRES_OCCUP 0x010
+#define MBOX_FIFO_STATUS 0x014
+
+#define MBOX_DISABLE_IRQ 0x4
+#define MBOX_ENABLE_IRQ 0x0
+#define MBOX_LATCH 1
+
+/* Global list of all mailboxes */
+static struct list_head mboxs = LIST_HEAD_INIT(mboxs);
+
+static struct mbox *get_mbox_with_id(u8 id)
+{
+ u8 i;
+ struct list_head *pos = &mboxs;
+ for (i = 0; i <= id; i++)
+ pos = pos->next;
+
+ return (struct mbox *) list_entry(pos, struct mbox, list);
+}
+
+int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block)
+{
+ int res = 0;
+
+ spin_lock(&mbox->lock);
+
+ dev_dbg(&(mbox->pdev->dev),
+ "About to buffer 0x%X to mailbox 0x%X."
+ " ri = %d, wi = %d\n",
+ mbox_msg, (u32)mbox, mbox->read_index,
+ mbox->write_index);
+
+ /* Check if write buffer is full */
+ while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) {
+ if (!block) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Buffer full in non-blocking call! "
+ "Returning -ENOMEM!\n");
+ res = -ENOMEM;
+ goto exit;
+ }
+ spin_unlock(&mbox->lock);
+ dev_dbg(&(mbox->pdev->dev),
+ "Buffer full in blocking call! Sleeping...\n");
+ mbox->client_blocked = 1;
+ wait_for_completion(&mbox->buffer_available);
+ dev_dbg(&(mbox->pdev->dev),
+ "Blocking send was woken up! Trying again...\n");
+ spin_lock(&mbox->lock);
+ }
+
+ mbox->buffer[mbox->write_index] = mbox_msg;
+ mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE;
+
+ /*
+ * Indicate that we want an IRQ as soon as there is a slot
+ * in the FIFO
+ */
+ writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+
+exit:
+ spin_unlock(&mbox->lock);
+ return res;
+}
+EXPORT_SYMBOL(mbox_send);
+
+#if defined(CONFIG_DEBUG_FS)
+/*
+ * Expected input: <value> <nbr sends>
+ * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times
+ */
+static ssize_t mbox_write_fifo(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ unsigned long mbox_mess;
+ unsigned long nbr_sends;
+ unsigned long i;
+ char int_buf[16];
+ char *token;
+ char *val;
+
+ struct mbox *mbox = (struct mbox *) dev->platform_data;
+
+ strncpy((char *) &int_buf, buf, sizeof(int_buf));
+ token = (char *) &int_buf;
+
+ /* Parse message */
+ val = strsep(&token, " ");
+ if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0))
+ mbox_mess = 0xDEADBEEF;
+
+ val = strsep(&token, " ");
+ if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0))
+ nbr_sends = 1;
+
+ dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n",
+ mbox_mess, nbr_sends, (u32) mbox);
+
+ for (i = 0; i < nbr_sends; i++)
+ mbox_send(mbox, mbox_mess, true);
+
+ return count;
+}
+
+static ssize_t mbox_read_fifo(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int mbox_value;
+ struct mbox *mbox = (struct mbox *) dev->platform_data;
+
+ if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0)
+ return sprintf(buf, "Mailbox is empty\n");
+
+ mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
+ writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
+
+ return sprintf(buf, "0x%X\n", mbox_value);
+}
+
+static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo);
+
+static int mbox_show(struct seq_file *s, void *data)
+{
+ struct list_head *pos;
+ u8 mbox_index = 0;
+
+ list_for_each(pos, &mboxs) {
+ struct mbox *m =
+ (struct mbox *) list_entry(pos, struct mbox, list);
+ if (m == NULL) {
+ seq_printf(s,
+ "Unable to retrieve mailbox %d\n",
+ mbox_index);
+ continue;
+ }
+
+ spin_lock(&m->lock);
+ if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) {
+ seq_printf(s, "MAILBOX %d not setup or corrupt\n",
+ mbox_index);
+ spin_unlock(&m->lock);
+ continue;
+ }
+
+ seq_printf(s,
+ "===========================\n"
+ " MAILBOX %d\n"
+ " PEER MAILBOX DUMP\n"
+ "---------------------------\n"
+ "FIFO: 0x%X (%d)\n"
+ "Free Threshold: 0x%.2X (%d)\n"
+ "Occupied Threshold: 0x%.2X (%d)\n"
+ "Status: 0x%.2X (%d)\n"
+ " Free spaces (ot): %d (%d)\n"
+ " Occup spaces (ot): %d (%d)\n"
+ "===========================\n"
+ " LOCAL MAILBOX DUMP\n"
+ "---------------------------\n"
+ "FIFO: 0x%.X (%d)\n"
+ "Free Threshold: 0x%.2X (%d)\n"
+ "Occupied Threshold: 0x%.2X (%d)\n"
+ "Status: 0x%.2X (%d)\n"
+ " Free spaces (ot): %d (%d)\n"
+ " Occup spaces (ot): %d (%d)\n"
+ "===========================\n"
+ "write_index: %d\n"
+ "read_index : %d\n"
+ "===========================\n"
+ "\n",
+ mbox_index,
+ readl(m->virtbase_peer + MBOX_FIFO_DATA),
+ readl(m->virtbase_peer + MBOX_FIFO_DATA),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_peer + MBOX_FIFO_STATUS),
+ readl(m->virtbase_peer + MBOX_FIFO_STATUS),
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7,
+ (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1,
+ readl(m->virtbase_local + MBOX_FIFO_DATA),
+ readl(m->virtbase_local + MBOX_FIFO_DATA),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_FREE),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP),
+ readl(m->virtbase_local + MBOX_FIFO_STATUS),
+ readl(m->virtbase_local + MBOX_FIFO_STATUS),
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7,
+ (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1,
+ m->write_index, m->read_index);
+ mbox_index++;
+ spin_unlock(&m->lock);
+ }
+
+ return 0;
+}
+
+static int mbox_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mbox_show, NULL);
+}
+
+static const struct file_operations mbox_operations = {
+ .owner = THIS_MODULE,
+ .open = mbox_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
+static irqreturn_t mbox_irq(int irq, void *arg)
+{
+ u32 mbox_value;
+ int nbr_occup;
+ int nbr_free;
+ struct mbox *mbox = (struct mbox *) arg;
+
+ spin_lock(&mbox->lock);
+
+ dev_dbg(&(mbox->pdev->dev),
+ "mbox IRQ [%d] received. ri = %d, wi = %d\n",
+ irq, mbox->read_index, mbox->write_index);
+
+ /*
+ * Check if we have any outgoing messages, and if there is space for
+ * them in the FIFO.
+ */
+ if (mbox->read_index != mbox->write_index) {
+ /*
+ * Check by reading FREE for LOCAL since that indicates
+ * OCCUP for PEER
+ */
+ nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS)
+ >> 4) & 0x7;
+ dev_dbg(&(mbox->pdev->dev),
+ "Status indicates %d empty spaces in the FIFO!\n",
+ nbr_free);
+
+ while ((nbr_free > 0) &&
+ (mbox->read_index != mbox->write_index)) {
+ /* Write the message and latch it into the FIFO */
+ writel(mbox->buffer[mbox->read_index],
+ (mbox->virtbase_peer + MBOX_FIFO_DATA));
+ writel(MBOX_LATCH,
+ (mbox->virtbase_peer + MBOX_FIFO_ADD));
+ dev_dbg(&(mbox->pdev->dev),
+ "Wrote message 0x%X to addr 0x%X\n",
+ mbox->buffer[mbox->read_index],
+ (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA));
+
+ nbr_free--;
+ mbox->read_index =
+ (mbox->read_index + 1) % MBOX_BUF_SIZE;
+ }
+
+ /*
+ * Check if we still want IRQ:s when there is free
+ * space to send
+ */
+ if (mbox->read_index != mbox->write_index) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Still have messages to send, but FIFO full. "
+ "Request IRQ again!\n");
+ writel(MBOX_ENABLE_IRQ,
+ mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+ } else {
+ dev_dbg(&(mbox->pdev->dev),
+ "No more messages to send. "
+ "Do not request IRQ again!\n");
+ writel(MBOX_DISABLE_IRQ,
+ mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+ }
+
+ /*
+ * Check if we can signal any blocked clients that it is OK to
+ * start buffering again
+ */
+ if (mbox->client_blocked &&
+ (((mbox->write_index + 1) % MBOX_BUF_SIZE)
+ != mbox->read_index)) {
+ dev_dbg(&(mbox->pdev->dev),
+ "Waking up blocked client\n");
+ complete(&mbox->buffer_available);
+ mbox->client_blocked = 0;
+ }
+ }
+
+ /* Check if we have any incoming messages */
+ nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7;
+ if (nbr_occup == 0)
+ goto exit;
+
+ if (mbox->cb == NULL) {
+ dev_dbg(&(mbox->pdev->dev), "No receive callback registered, "
+ "leaving %d incoming messages in fifo!\n", nbr_occup);
+ goto exit;
+ }
+
+ /* Read and acknowledge the message */
+ mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA);
+ writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE));
+
+ /* Notify consumer of new mailbox message */
+ dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n",
+ mbox_value);
+ mbox->cb(mbox_value, mbox->client_data);
+
+exit:
+ dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n",
+ mbox->read_index, mbox->write_index);
+ spin_unlock(&mbox->lock);
+
+ return IRQ_HANDLED;
+}
+
+/* Setup is executed once for each mbox pair */
+struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv)
+{
+ struct resource *resource;
+ int irq;
+ int res;
+ struct mbox *mbox;
+
+ mbox = get_mbox_with_id(mbox_id);
+ if (mbox == NULL) {
+ dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n",
+ mbox_id);
+ goto exit;
+ }
+
+ /*
+ * Check if mailbox has been allocated to someone else,
+ * otherwise allocate it
+ */
+ if (mbox->allocated) {
+ dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n",
+ mbox_id);
+ mbox = NULL;
+ goto exit;
+ }
+ mbox->allocated = true;
+
+ dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n",
+ mbox_id, (u32)mbox);
+
+ mbox->client_data = priv;
+ mbox->cb = mbox_cb;
+
+ /* Get addr for peer mailbox and ioremap it */
+ resource = platform_get_resource_byname(mbox->pdev,
+ IORESOURCE_MEM,
+ "mbox_peer");
+ if (resource == NULL) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox peer resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "Resource name: %s start: 0x%X, end: 0x%X\n",
+ resource->name, resource->start, resource->end);
+ mbox->virtbase_peer = ioremap(resource->start, resource_size(resource));
+ if (!mbox->virtbase_peer) {
+ dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n",
+ resource->start, resource->end, (u32) mbox->virtbase_peer);
+
+ /* Get addr for local mailbox and ioremap it */
+ resource = platform_get_resource_byname(mbox->pdev,
+ IORESOURCE_MEM,
+ "mbox_local");
+ if (resource == NULL) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox local resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "Resource name: %s start: 0x%X, end: 0x%X\n",
+ resource->name, resource->start, resource->end);
+ mbox->virtbase_local = ioremap(resource->start, resource_size(resource));
+ if (!mbox->virtbase_local) {
+ dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n");
+ mbox = NULL;
+ goto exit;
+ }
+ dev_dbg(&(mbox->pdev->dev),
+ "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n",
+ resource->start, resource->end, (u32) mbox->virtbase_peer);
+
+ init_completion(&mbox->buffer_available);
+ mbox->client_blocked = 0;
+
+ /* Get IRQ for mailbox and allocate it */
+ irq = platform_get_irq_byname(mbox->pdev, "mbox_irq");
+ if (irq < 0) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to retrieve mbox irq resource\n");
+ mbox = NULL;
+ goto exit;
+ }
+
+ dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq);
+ res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox);
+ if (res < 0) {
+ dev_err(&(mbox->pdev->dev),
+ "Unable to allocate mbox irq %d\n", irq);
+ mbox = NULL;
+ goto exit;
+ }
+
+ /* Set up mailbox to not launch IRQ on free space in mailbox */
+ writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE);
+
+ /*
+ * Set up mailbox to launch IRQ on new message if we have
+ * a callback set. If not, do not raise IRQ, but keep message
+ * in FIFO for manual retrieval
+ */
+ if (mbox_cb != NULL)
+ writel(MBOX_ENABLE_IRQ,
+ mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
+ else
+ writel(MBOX_DISABLE_IRQ,
+ mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP);
+
+#if defined(CONFIG_DEBUG_FS)
+ res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo);
+ if (res != 0)
+ dev_warn(&(mbox->pdev->dev),
+ "Unable to create mbox sysfs entry");
+
+ (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL,
+ NULL, &mbox_operations);
+#endif
+
+ dev_info(&(mbox->pdev->dev),
+ "Mailbox driver with index %d initiated!\n", mbox_id);
+
+exit:
+ return mbox;
+}
+EXPORT_SYMBOL(mbox_setup);
+
+
+int __init mbox_probe(struct platform_device *pdev)
+{
+ struct mbox local_mbox;
+ struct mbox *mbox;
+ int res = 0;
+ dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev);
+
+ memset(&local_mbox, 0x0, sizeof(struct mbox));
+
+ /* Associate our mbox data with the platform device */
+ res = platform_device_add_data(pdev,
+ (void *) &local_mbox,
+ sizeof(struct mbox));
+ if (res != 0) {
+ dev_err(&(pdev->dev),
+ "Unable to allocate driver platform data!\n");
+ goto exit;
+ }
+
+ mbox = (struct mbox *) pdev->dev.platform_data;
+ mbox->pdev = pdev;
+ mbox->write_index = 0;
+ mbox->read_index = 0;
+
+ INIT_LIST_HEAD(&(mbox->list));
+ list_add_tail(&(mbox->list), &mboxs);
+
+ sprintf(mbox->name, "%s", MBOX_NAME);
+ spin_lock_init(&mbox->lock);
+
+ dev_info(&(pdev->dev), "Mailbox driver loaded\n");
+
+exit:
+ return res;
+}
+
+static struct platform_driver mbox_driver = {
+ .driver = {
+ .name = MBOX_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mbox_init(void)
+{
+ return platform_driver_probe(&mbox_driver, mbox_probe);
+}
+
+module_init(mbox_init);
+
+void __exit mbox_exit(void)
+{
+ platform_driver_unregister(&mbox_driver);
+}
+
+module_exit(mbox_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MBOX driver");
diff --git a/arch/arm/mach-ux500/modem-irq-db5500.c b/arch/arm/mach-ux500/modem-irq-db5500.c
new file mode 100644
index 00000000..6b86416c
--- /dev/null
+++ b/arch/arm/mach-ux500/modem-irq-db5500.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/id.h>
+
+#define MODEM_INTCON_BASE_ADDR 0xBFFD3000
+#define MODEM_INTCON_SIZE 0xFFF
+
+#define DEST_IRQ41_OFFSET 0x2A4
+#define DEST_IRQ43_OFFSET 0x2AC
+#define DEST_IRQ45_OFFSET 0x2B4
+
+#define PRIO_IRQ41_OFFSET 0x6A4
+#define PRIO_IRQ43_OFFSET 0x6AC
+#define PRIO_IRQ45_OFFSET 0x6B4
+
+#define ALLOW_IRQ_OFFSET 0x104
+
+#define MODEM_INTCON_CPU_NBR 0x1
+#define MODEM_INTCON_PRIO_HIGH 0x0
+
+#define MODEM_INTCON_ALLOW_IRQ41 0x0200
+#define MODEM_INTCON_ALLOW_IRQ43 0x0800
+#define MODEM_INTCON_ALLOW_IRQ45 0x2000
+
+#define MODEM_IRQ_REG_OFFSET 0x4
+
+struct modem_irq {
+ void __iomem *modem_intcon_base;
+};
+
+
+static void setup_modem_intcon(void __iomem *modem_intcon_base)
+{
+ /* IC_DESTINATION_BASE_ARRAY - Which CPU to receive the IRQ */
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ41_OFFSET);
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ43_OFFSET);
+ writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ45_OFFSET);
+
+ /* IC_PRIORITY_BASE_ARRAY - IRQ priority in modem IRQ controller */
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ41_OFFSET);
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ43_OFFSET);
+ writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ45_OFFSET);
+
+ /* IC_ALLOW_ARRAY - IRQ enable */
+ writel(MODEM_INTCON_ALLOW_IRQ41 |
+ MODEM_INTCON_ALLOW_IRQ43 |
+ MODEM_INTCON_ALLOW_IRQ45,
+ modem_intcon_base + ALLOW_IRQ_OFFSET);
+}
+
+static irqreturn_t modem_cpu_irq_handler(int irq, void *data)
+{
+ int real_irq;
+ int virt_irq;
+ struct modem_irq *mi = (struct modem_irq *)data;
+
+ /* Read modem side IRQ number from modem IRQ controller */
+ real_irq = readl(mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET) & 0xFF;
+ virt_irq = IRQ_MODEM_EVENTS_BASE + real_irq;
+
+ pr_debug("modem_irq: Worker read addr 0x%X and got value 0x%X "
+ "which will be 0x%X (%d) which translates to "
+ "virtual IRQ 0x%X (%d)!\n",
+ (u32)mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET,
+ real_irq,
+ real_irq & 0xFF,
+ real_irq & 0xFF,
+ virt_irq,
+ virt_irq);
+
+ if (virt_irq != 0)
+ generic_handle_irq(virt_irq);
+
+ pr_debug("modem_irq: Done handling virtual IRQ %d!\n", virt_irq);
+
+ return IRQ_HANDLED;
+}
+
+static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip)
+{
+ irq_set_chip_and_handler(irq, modem_irq_chip, handle_simple_irq);
+ set_irq_flags(irq, IRQF_VALID);
+
+ pr_debug("modem_irq: Created virtual IRQ %d\n", irq);
+}
+
+static int modem_irq_init(void)
+{
+ int err;
+ static struct irq_chip modem_irq_chip;
+ struct modem_irq *mi;
+
+ if (!cpu_is_u5500())
+ return -ENODEV;
+
+ pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
+ IRQ_DB5500_MODEM);
+
+ mi = kmalloc(sizeof(struct modem_irq), GFP_KERNEL);
+ if (!mi) {
+ pr_err("modem_irq: Could not allocate device\n");
+ return -ENOMEM;
+ }
+
+ mi->modem_intcon_base =
+ ioremap(MODEM_INTCON_BASE_ADDR, MODEM_INTCON_SIZE);
+ pr_debug("modem_irq: ioremapped modem_intcon_base from "
+ "phy 0x%x to virt 0x%x\n", MODEM_INTCON_BASE_ADDR,
+ (u32)mi->modem_intcon_base);
+
+ setup_modem_intcon(mi->modem_intcon_base);
+
+ modem_irq_chip = dummy_irq_chip;
+ modem_irq_chip.name = "modem_irq";
+
+ /* Create the virtual IRQ:s needed */
+ create_virtual_irq(MBOX_PAIR0_VIRT_IRQ, &modem_irq_chip);
+ create_virtual_irq(MBOX_PAIR1_VIRT_IRQ, &modem_irq_chip);
+ create_virtual_irq(MBOX_PAIR2_VIRT_IRQ, &modem_irq_chip);
+
+ err = request_threaded_irq(IRQ_DB5500_MODEM, NULL,
+ modem_cpu_irq_handler, IRQF_ONESHOT,
+ "modem_irq", mi);
+ if (err)
+ pr_err("modem_irq: Could not register IRQ %d\n",
+ IRQ_DB5500_MODEM);
+
+ return 0;
+}
+
+arch_initcall(modem_irq_init);
diff --git a/arch/arm/mach-ux500/pins-db5500.h b/arch/arm/mach-ux500/pins-db5500.h
new file mode 100644
index 00000000..bf50c21f
--- /dev/null
+++ b/arch/arm/mach-ux500/pins-db5500.h
@@ -0,0 +1,620 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __MACH_DB5500_PINS_H
+#define __MACH_DB5500_PINS_H
+
+#define GPIO0_GPIO PIN_CFG(0, GPIO)
+#define GPIO0_SM_CS3n PIN_CFG(0, ALT_A)
+
+#define GPIO1_GPIO PIN_CFG(1, GPIO)
+#define GPIO1_SM_A3 PIN_CFG(1, ALT_A)
+
+#define GPIO2_GPIO PIN_CFG(2, GPIO)
+#define GPIO2_SM_A4 PIN_CFG(2, ALT_A)
+#define GPIO2_SM_AVD PIN_CFG(2, ALT_B)
+
+#define GPIO3_GPIO PIN_CFG(3, GPIO)
+#define GPIO3_I2C1_SCL PIN_CFG(3, ALT_A)
+
+#define GPIO4_GPIO PIN_CFG(4, GPIO)
+#define GPIO4_I2C1_SDA PIN_CFG(4, ALT_A)
+
+#define GPIO5_GPIO PIN_CFG(5, GPIO)
+#define GPIO5_MC0_DAT0 PIN_CFG(5, ALT_A)
+#define GPIO5_SM_ADQ8 PIN_CFG(5, ALT_B)
+
+#define GPIO6_GPIO PIN_CFG(6, GPIO)
+#define GPIO6_MC0_DAT1 PIN_CFG(6, ALT_A)
+#define GPIO6_SM_ADQ0 PIN_CFG(6, ALT_B)
+
+#define GPIO7_GPIO PIN_CFG(7, GPIO)
+#define GPIO7_MC0_DAT2 PIN_CFG(7, ALT_A)
+#define GPIO7_SM_ADQ9 PIN_CFG(7, ALT_B)
+
+#define GPIO8_GPIO PIN_CFG(8, GPIO)
+#define GPIO8_MC0_DAT3 PIN_CFG(8, ALT_A)
+#define GPIO8_SM_ADQ1 PIN_CFG(8, ALT_B)
+
+#define GPIO9_GPIO PIN_CFG(9, GPIO)
+#define GPIO9_MC0_DAT4 PIN_CFG(9, ALT_A)
+#define GPIO9_SM_ADQ10 PIN_CFG(9, ALT_B)
+
+#define GPIO10_GPIO PIN_CFG(10, GPIO)
+#define GPIO10_MC0_DAT5 PIN_CFG(10, ALT_A)
+#define GPIO10_SM_ADQ2 PIN_CFG(10, ALT_B)
+
+#define GPIO11_GPIO PIN_CFG(11, GPIO)
+#define GPIO11_MC0_DAT6 PIN_CFG(11, ALT_A)
+#define GPIO11_SM_ADQ11 PIN_CFG(11, ALT_B)
+
+#define GPIO12_GPIO PIN_CFG(12, GPIO)
+#define GPIO12_MC0_DAT7 PIN_CFG(12, ALT_A)
+#define GPIO12_SM_ADQ3 PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO PIN_CFG(13, GPIO)
+#define GPIO13_MC0_CMD PIN_CFG(13, ALT_A)
+#define GPIO13_SM_BUSY0n PIN_CFG(13, ALT_B)
+#define GPIO13_SM_WAIT0n PIN_CFG(13, ALT_C)
+
+#define GPIO14_GPIO PIN_CFG(14, GPIO)
+#define GPIO14_MC0_CLK PIN_CFG(14, ALT_A)
+#define GPIO14_SM_CS1n PIN_CFG(14, ALT_B)
+#define GPIO14_SM_CKO PIN_CFG(14, ALT_C)
+
+#define GPIO15_GPIO PIN_CFG(15, GPIO)
+#define GPIO15_SM_A5 PIN_CFG(15, ALT_A)
+#define GPIO15_SM_CLE PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO PIN_CFG(16, GPIO)
+#define GPIO16_MC2_CMD PIN_CFG(16, ALT_A)
+#define GPIO16_SM_OEn PIN_CFG(16, ALT_B)
+
+#define GPIO17_GPIO PIN_CFG(17, GPIO)
+#define GPIO17_MC2_CLK PIN_CFG(17, ALT_A)
+#define GPIO17_SM_WEn PIN_CFG(17, ALT_B)
+
+#define GPIO18_GPIO PIN_CFG(18, GPIO)
+#define GPIO18_SM_A6 PIN_CFG(18, ALT_A)
+#define GPIO18_SM_ALE PIN_CFG(18, ALT_B)
+#define GPIO18_SM_AVDn PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO PIN_CFG(19, GPIO)
+#define GPIO19_MC2_DAT1 PIN_CFG(19, ALT_A)
+#define GPIO19_SM_ADQ4 PIN_CFG(19, ALT_B)
+
+#define GPIO20_GPIO PIN_CFG(20, GPIO)
+#define GPIO20_MC2_DAT3 PIN_CFG(20, ALT_A)
+#define GPIO20_SM_ADQ5 PIN_CFG(20, ALT_B)
+
+#define GPIO21_GPIO PIN_CFG(21, GPIO)
+#define GPIO21_MC2_DAT5 PIN_CFG(21, ALT_A)
+#define GPIO21_SM_ADQ6 PIN_CFG(21, ALT_B)
+
+#define GPIO22_GPIO PIN_CFG(22, GPIO)
+#define GPIO22_MC2_DAT7 PIN_CFG(22, ALT_A)
+#define GPIO22_SM_ADQ7 PIN_CFG(22, ALT_B)
+
+#define GPIO23_GPIO PIN_CFG(23, GPIO)
+#define GPIO23_MC2_DAT0 PIN_CFG(23, ALT_A)
+#define GPIO23_SM_ADQ12 PIN_CFG(23, ALT_B)
+#define GPIO23_MC0_DAT1 PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO PIN_CFG(24, GPIO)
+#define GPIO24_MC2_DAT2 PIN_CFG(24, ALT_A)
+#define GPIO24_SM_ADQ13 PIN_CFG(24, ALT_B)
+#define GPIO24_MC0_DAT3 PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO PIN_CFG(25, GPIO)
+#define GPIO25_MC2_DAT4 PIN_CFG(25, ALT_A)
+#define GPIO25_SM_ADQ14 PIN_CFG(25, ALT_B)
+#define GPIO25_MC0_CMD PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO PIN_CFG(26, GPIO)
+#define GPIO26_MC2_DAT6 PIN_CFG(26, ALT_A)
+#define GPIO26_SM_ADQ15 PIN_CFG(26, ALT_B)
+
+#define GPIO27_GPIO PIN_CFG(27, GPIO)
+#define GPIO27_SM_CS0n PIN_CFG(27, ALT_A)
+#define GPIO27_SM_PS0n PIN_CFG(27, ALT_B)
+
+#define GPIO28_GPIO PIN_CFG(28, GPIO)
+#define GPIO28_U0_TXD PIN_CFG(28, ALT_A)
+#define GPIO28_SM_A0 PIN_CFG(28, ALT_B)
+
+#define GPIO29_GPIO PIN_CFG(29, GPIO)
+#define GPIO29_U0_RXD PIN_CFG(29, ALT_A)
+#define GPIO29_SM_A1 PIN_CFG(29, ALT_B)
+#define GPIO29_PWM_0 PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A)
+#define GPIO30_SM_A2 PIN_CFG(30, ALT_B)
+#define GPIO30_PWM_1 PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT7 PIN_CFG(31, ALT_A)
+#define GPIO31_SM_CS2n PIN_CFG(31, ALT_B)
+#define GPIO31_PWM_2 PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO PIN_CFG(32, GPIO)
+#define GPIO32_MSP0_TCK PIN_CFG(32, ALT_A)
+#define GPIO32_ACCI2S0_SCK PIN_CFG(32, ALT_B)
+
+#define GPIO33_GPIO PIN_CFG(33, GPIO)
+#define GPIO33_MSP0_TFS PIN_CFG(33, ALT_A)
+#define GPIO33_ACCI2S0_WS PIN_CFG(33, ALT_B)
+
+#define GPIO34_GPIO PIN_CFG(34, GPIO)
+#define GPIO34_MSP0_TXD PIN_CFG(34, ALT_A)
+#define GPIO34_ACCI2S0_DLD PIN_CFG(34, ALT_B)
+
+#define GPIO35_GPIO PIN_CFG(35, GPIO)
+#define GPIO35_MSP0_RXD PIN_CFG(35, ALT_A)
+#define GPIO35_ACCI2S0_ULD PIN_CFG(35, ALT_B)
+
+#define GPIO64_GPIO PIN_CFG(64, GPIO)
+#define GPIO64_USB_DAT0 PIN_CFG(64, ALT_A)
+#define GPIO64_U0_TXD PIN_CFG(64, ALT_B)
+
+#define GPIO65_GPIO PIN_CFG(65, GPIO)
+#define GPIO65_USB_DAT1 PIN_CFG(65, ALT_A)
+#define GPIO65_U0_RXD PIN_CFG(65, ALT_B)
+
+#define GPIO66_GPIO PIN_CFG(66, GPIO)
+#define GPIO66_USB_DAT2 PIN_CFG(66, ALT_A)
+
+#define GPIO67_GPIO PIN_CFG(67, GPIO)
+#define GPIO67_USB_DAT3 PIN_CFG(67, ALT_A)
+
+#define GPIO68_GPIO PIN_CFG(68, GPIO)
+#define GPIO68_USB_DAT4 PIN_CFG(68, ALT_A)
+
+#define GPIO69_GPIO PIN_CFG(69, GPIO)
+#define GPIO69_USB_DAT5 PIN_CFG(69, ALT_A)
+
+#define GPIO70_GPIO PIN_CFG(70, GPIO)
+#define GPIO70_USB_DAT6 PIN_CFG(70, ALT_A)
+
+#define GPIO71_GPIO PIN_CFG(71, GPIO)
+#define GPIO71_USB_DAT7 PIN_CFG(71, ALT_A)
+
+#define GPIO72_GPIO PIN_CFG(72, GPIO)
+#define GPIO72_USB_STP PIN_CFG(72, ALT_A)
+
+#define GPIO73_GPIO PIN_CFG(73, GPIO)
+#define GPIO73_USB_DIR PIN_CFG(73, ALT_A)
+
+#define GPIO74_GPIO PIN_CFG(74, GPIO)
+#define GPIO74_USB_NXT PIN_CFG(74, ALT_A)
+
+#define GPIO75_GPIO PIN_CFG(75, GPIO)
+#define GPIO75_USB_XCLK PIN_CFG(75, ALT_A)
+
+#define GPIO76_GPIO PIN_CFG(76, GPIO)
+
+#define GPIO77_GPIO PIN_CFG(77, GPIO)
+#define GPIO77_ACCTX_ON PIN_CFG(77, ALT_A)
+
+#define GPIO78_GPIO PIN_CFG(78, GPIO)
+#define GPIO78_IRQn PIN_CFG(78, ALT_A)
+
+#define GPIO79_GPIO PIN_CFG(79, GPIO)
+#define GPIO79_ACCSIM_Clk PIN_CFG(79, ALT_A)
+
+#define GPIO80_GPIO PIN_CFG(80, GPIO)
+#define GPIO80_ACCSIM_Da PIN_CFG(80, ALT_A)
+
+#define GPIO81_GPIO PIN_CFG(81, GPIO)
+#define GPIO81_ACCSIM_Reset PIN_CFG(81, ALT_A)
+
+#define GPIO82_GPIO PIN_CFG(82, GPIO)
+#define GPIO82_ACCSIM_DDir PIN_CFG(82, ALT_A)
+
+#define GPIO96_GPIO PIN_CFG(96, GPIO)
+#define GPIO96_MSP1_TCK PIN_CFG(96, ALT_A)
+#define GPIO96_PRCMU_DEBUG3 PIN_CFG(96, ALT_B)
+#define GPIO96_PRCMU_DEBUG7 PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO PIN_CFG(97, GPIO)
+#define GPIO97_MSP1_TFS PIN_CFG(97, ALT_A)
+#define GPIO97_PRCMU_DEBUG2 PIN_CFG(97, ALT_B)
+#define GPIO97_PRCMU_DEBUG6 PIN_CFG(97, ALT_C)
+
+#define GPIO98_GPIO PIN_CFG(98, GPIO)
+#define GPIO98_MSP1_TXD PIN_CFG(98, ALT_A)
+#define GPIO98_PRCMU_DEBUG1 PIN_CFG(98, ALT_B)
+#define GPIO98_PRCMU_DEBUG5 PIN_CFG(98, ALT_C)
+
+#define GPIO99_GPIO PIN_CFG(99, GPIO)
+#define GPIO99_MSP1_RXD PIN_CFG(99, ALT_A)
+#define GPIO99_PRCMU_DEBUG0 PIN_CFG(99, ALT_B)
+#define GPIO99_PRCMU_DEBUG4 PIN_CFG(99, ALT_C)
+
+#define GPIO100_GPIO PIN_CFG(100, GPIO)
+#define GPIO100_I2C0_SCL PIN_CFG(100, ALT_A)
+
+#define GPIO101_GPIO PIN_CFG(101, GPIO)
+#define GPIO101_I2C0_SDA PIN_CFG(101, ALT_A)
+
+#define GPIO128_GPIO PIN_CFG(128, GPIO)
+#define GPIO128_KP_I0 PIN_CFG(128, ALT_A)
+#define GPIO128_BUSMON_D0 PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO PIN_CFG(129, GPIO)
+#define GPIO129_KP_O0 PIN_CFG(129, ALT_A)
+#define GPIO129_BUSMON_D1 PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO PIN_CFG(130, GPIO)
+#define GPIO130_KP_I1 PIN_CFG(130, ALT_A)
+#define GPIO130_BUSMON_D2 PIN_CFG(130, ALT_B)
+
+#define GPIO131_GPIO PIN_CFG(131, GPIO)
+#define GPIO131_KP_O1 PIN_CFG(131, ALT_A)
+#define GPIO131_BUSMON_D3 PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO PIN_CFG(132, GPIO)
+#define GPIO132_KP_I2 PIN_CFG(132, ALT_A)
+#define GPIO132_ETM_D15 PIN_CFG(132, ALT_B)
+#define GPIO132_STMAPE_CLK PIN_CFG(132, ALT_C)
+
+#define GPIO133_GPIO PIN_CFG(133, GPIO)
+#define GPIO133_KP_O2 PIN_CFG(133, ALT_A)
+#define GPIO133_ETM_D14 PIN_CFG(133, ALT_B)
+#define GPIO133_U0_RXD PIN_CFG(133, ALT_C)
+
+#define GPIO134_GPIO PIN_CFG(134, GPIO)
+#define GPIO134_KP_I3 PIN_CFG(134, ALT_A)
+#define GPIO134_ETM_D13 PIN_CFG(134, ALT_B)
+#define GPIO134_STMAPE_DAT0 PIN_CFG(134, ALT_C)
+
+#define GPIO135_GPIO PIN_CFG(135, GPIO)
+#define GPIO135_KP_O3 PIN_CFG(135, ALT_A)
+#define GPIO135_ETM_D12 PIN_CFG(135, ALT_B)
+#define GPIO135_STMAPE_DAT1 PIN_CFG(135, ALT_C)
+
+#define GPIO136_GPIO PIN_CFG(136, GPIO)
+#define GPIO136_KP_I4 PIN_CFG(136, ALT_A)
+#define GPIO136_ETM_D11 PIN_CFG(136, ALT_B)
+#define GPIO136_STMAPE_DAT2 PIN_CFG(136, ALT_C)
+
+#define GPIO137_GPIO PIN_CFG(137, GPIO)
+#define GPIO137_KP_O4 PIN_CFG(137, ALT_A)
+#define GPIO137_ETM_D10 PIN_CFG(137, ALT_B)
+#define GPIO137_STMAPE_DAT3 PIN_CFG(137, ALT_C)
+
+#define GPIO138_GPIO PIN_CFG(138, GPIO)
+#define GPIO138_KP_I5 PIN_CFG(138, ALT_A)
+#define GPIO138_ETM_D9 PIN_CFG(138, ALT_B)
+#define GPIO138_U0_TXD PIN_CFG(138, ALT_C)
+
+#define GPIO139_GPIO PIN_CFG(139, GPIO)
+#define GPIO139_KP_O5 PIN_CFG(139, ALT_A)
+#define GPIO139_ETM_D8 PIN_CFG(139, ALT_B)
+#define GPIO139_BUSMON_D11 PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO PIN_CFG(140, GPIO)
+#define GPIO140_KP_I6 PIN_CFG(140, ALT_A)
+#define GPIO140_ETM_D7 PIN_CFG(140, ALT_B)
+#define GPIO140_STMAPE_CLK PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO PIN_CFG(141, GPIO)
+#define GPIO141_KP_O6 PIN_CFG(141, ALT_A)
+#define GPIO141_ETM_D6 PIN_CFG(141, ALT_B)
+#define GPIO141_U0_RXD PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO PIN_CFG(142, GPIO)
+#define GPIO142_KP_I7 PIN_CFG(142, ALT_A)
+#define GPIO142_ETM_D5 PIN_CFG(142, ALT_B)
+#define GPIO142_STMAPE_DAT0 PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO PIN_CFG(143, GPIO)
+#define GPIO143_KP_O7 PIN_CFG(143, ALT_A)
+#define GPIO143_ETM_D4 PIN_CFG(143, ALT_B)
+#define GPIO143_STMAPE_DAT1 PIN_CFG(143, ALT_C)
+
+#define GPIO144_GPIO PIN_CFG(144, GPIO)
+#define GPIO144_I2C3_SCL PIN_CFG(144, ALT_A)
+#define GPIO144_ETM_D3 PIN_CFG(144, ALT_B)
+#define GPIO144_STMAPE_DAT2 PIN_CFG(144, ALT_C)
+
+#define GPIO145_GPIO PIN_CFG(145, GPIO)
+#define GPIO145_I2C3_SDA PIN_CFG(145, ALT_A)
+#define GPIO145_ETM_D2 PIN_CFG(145, ALT_B)
+#define GPIO145_STMAPE_DAT3 PIN_CFG(145, ALT_C)
+
+#define GPIO146_GPIO PIN_CFG(146, GPIO)
+#define GPIO146_PWM_0 PIN_CFG(146, ALT_A)
+#define GPIO146_ETM_D1 PIN_CFG(146, ALT_B)
+
+#define GPIO147_GPIO PIN_CFG(147, GPIO)
+#define GPIO147_PWM_1 PIN_CFG(147, ALT_A)
+#define GPIO147_ETM_D0 PIN_CFG(147, ALT_B)
+
+#define GPIO148_GPIO PIN_CFG(148, GPIO)
+#define GPIO148_PWM_2 PIN_CFG(148, ALT_A)
+#define GPIO148_ETM_CLK PIN_CFG(148, ALT_B)
+
+#define GPIO160_GPIO PIN_CFG(160, GPIO)
+#define GPIO160_CLKOUT_REQn PIN_CFG(160, ALT_A)
+
+#define GPIO161_GPIO PIN_CFG(161, GPIO)
+#define GPIO161_CLKOUT_0 PIN_CFG(161, ALT_A)
+
+#define GPIO162_GPIO PIN_CFG(162, GPIO)
+#define GPIO162_CLKOUT_1 PIN_CFG(162, ALT_A)
+
+#define GPIO163_GPIO PIN_CFG(163, GPIO)
+
+#define GPIO164_GPIO PIN_CFG(164, GPIO)
+#define GPIO164_GPS_START PIN_CFG(164, ALT_A)
+
+#define GPIO165_GPIO PIN_CFG(165, GPIO)
+#define GPIO165_SPI1_CS2n PIN_CFG(165, ALT_A)
+#define GPIO165_U3_RXD PIN_CFG(165, ALT_B)
+#define GPIO165_BUSMON_D20 PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO PIN_CFG(166, GPIO)
+#define GPIO166_SPI1_CS1n PIN_CFG(166, ALT_A)
+#define GPIO166_U3_TXD PIN_CFG(166, ALT_B)
+#define GPIO166_BUSMON_D21 PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO PIN_CFG(167, GPIO)
+#define GPIO167_SPI1_CS0n PIN_CFG(167, ALT_A)
+#define GPIO167_U3_RTSn PIN_CFG(167, ALT_B)
+#define GPIO167_BUSMON_D22 PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO PIN_CFG(168, GPIO)
+#define GPIO168_SPI1_RXD PIN_CFG(168, ALT_A)
+#define GPIO168_U3_CTSn PIN_CFG(168, ALT_B)
+#define GPIO168_BUSMON_D23 PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO PIN_CFG(169, GPIO)
+#define GPIO169_SPI1_TXD PIN_CFG(169, ALT_A)
+#define GPIO169_DDR_RC PIN_CFG(169, ALT_B)
+#define GPIO169_BUSMON_D24 PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO PIN_CFG(170, GPIO)
+#define GPIO170_SPI1_CLK PIN_CFG(170, ALT_A)
+
+#define GPIO171_GPIO PIN_CFG(171, GPIO)
+#define GPIO171_MC3_DAT0 PIN_CFG(171, ALT_A)
+#define GPIO171_SPI3_RXD PIN_CFG(171, ALT_B)
+#define GPIO171_BUSMON_D25 PIN_CFG(171, ALT_C)
+
+#define GPIO172_GPIO PIN_CFG(172, GPIO)
+#define GPIO172_MC3_DAT1 PIN_CFG(172, ALT_A)
+#define GPIO172_SPI3_CS1n PIN_CFG(172, ALT_B)
+#define GPIO172_BUSMON_D26 PIN_CFG(172, ALT_C)
+
+#define GPIO173_GPIO PIN_CFG(173, GPIO)
+#define GPIO173_MC3_DAT2 PIN_CFG(173, ALT_A)
+#define GPIO173_SPI3_CS2n PIN_CFG(173, ALT_B)
+#define GPIO173_BUSMON_D27 PIN_CFG(173, ALT_C)
+
+#define GPIO174_GPIO PIN_CFG(174, GPIO)
+#define GPIO174_MC3_DAT3 PIN_CFG(174, ALT_A)
+#define GPIO174_SPI3_CS0n PIN_CFG(174, ALT_B)
+#define GPIO174_BUSMON_D28 PIN_CFG(174, ALT_C)
+
+#define GPIO175_GPIO PIN_CFG(175, GPIO)
+#define GPIO175_MC3_CMD PIN_CFG(175, ALT_A)
+#define GPIO175_SPI3_TXD PIN_CFG(175, ALT_B)
+#define GPIO175_BUSMON_D29 PIN_CFG(175, ALT_C)
+
+#define GPIO176_GPIO PIN_CFG(176, GPIO)
+#define GPIO176_MC3_CLK PIN_CFG(176, ALT_A)
+#define GPIO176_SPI3_CLK PIN_CFG(176, ALT_B)
+
+#define GPIO177_GPIO PIN_CFG(177, GPIO)
+#define GPIO177_U2_RXD PIN_CFG(177, ALT_A)
+#define GPIO177_I2C3_SCL PIN_CFG(177, ALT_B)
+#define GPIO177_BUSMON_D30 PIN_CFG(177, ALT_C)
+
+#define GPIO178_GPIO PIN_CFG(178, GPIO)
+#define GPIO178_U2_TXD PIN_CFG(178, ALT_A)
+#define GPIO178_I2C3_SDA PIN_CFG(178, ALT_B)
+#define GPIO178_BUSMON_D31 PIN_CFG(178, ALT_C)
+
+#define GPIO179_GPIO PIN_CFG(179, GPIO)
+#define GPIO179_U2_CTSn PIN_CFG(179, ALT_A)
+#define GPIO179_U3_RXD PIN_CFG(179, ALT_B)
+#define GPIO179_BUSMON_D32 PIN_CFG(179, ALT_C)
+
+#define GPIO180_GPIO PIN_CFG(180, GPIO)
+#define GPIO180_U2_RTSn PIN_CFG(180, ALT_A)
+#define GPIO180_U3_TXD PIN_CFG(180, ALT_B)
+#define GPIO180_BUSMON_D33 PIN_CFG(180, ALT_C)
+
+#define GPIO185_GPIO PIN_CFG(185, GPIO)
+#define GPIO185_SPI3_CS2n PIN_CFG(185, ALT_A)
+#define GPIO185_MC4_DAT0 PIN_CFG(185, ALT_B)
+
+#define GPIO186_GPIO PIN_CFG(186, GPIO)
+#define GPIO186_SPI3_CS1n PIN_CFG(186, ALT_A)
+#define GPIO186_MC4_DAT1 PIN_CFG(186, ALT_B)
+
+#define GPIO187_GPIO PIN_CFG(187, GPIO)
+#define GPIO187_SPI3_CS0n PIN_CFG(187, ALT_A)
+#define GPIO187_MC4_DAT2 PIN_CFG(187, ALT_B)
+
+#define GPIO188_GPIO PIN_CFG(188, GPIO)
+#define GPIO188_SPI3_RXD PIN_CFG(188, ALT_A)
+#define GPIO188_MC4_DAT3 PIN_CFG(188, ALT_B)
+
+#define GPIO189_GPIO PIN_CFG(189, GPIO)
+#define GPIO189_SPI3_TXD PIN_CFG(189, ALT_A)
+#define GPIO189_MC4_CMD PIN_CFG(189, ALT_B)
+
+#define GPIO190_GPIO PIN_CFG(190, GPIO)
+#define GPIO190_SPI3_CLK PIN_CFG(190, ALT_A)
+#define GPIO190_MC4_CLK PIN_CFG(190, ALT_B)
+
+#define GPIO191_GPIO PIN_CFG(191, GPIO)
+#define GPIO191_MC1_DAT0 PIN_CFG(191, ALT_A)
+#define GPIO191_MC4_DAT4 PIN_CFG(191, ALT_B)
+#define GPIO191_STMAPE_DAT0 PIN_CFG(191, ALT_C)
+
+#define GPIO192_GPIO PIN_CFG(192, GPIO)
+#define GPIO192_MC1_DAT1 PIN_CFG(192, ALT_A)
+#define GPIO192_MC4_DAT5 PIN_CFG(192, ALT_B)
+#define GPIO192_STMAPE_DAT1 PIN_CFG(192, ALT_C)
+
+#define GPIO193_GPIO PIN_CFG(193, GPIO)
+#define GPIO193_MC1_DAT2 PIN_CFG(193, ALT_A)
+#define GPIO193_MC4_DAT6 PIN_CFG(193, ALT_B)
+#define GPIO193_STMAPE_DAT2 PIN_CFG(193, ALT_C)
+
+#define GPIO194_GPIO PIN_CFG(194, GPIO)
+#define GPIO194_MC1_DAT3 PIN_CFG(194, ALT_A)
+#define GPIO194_MC4_DAT7 PIN_CFG(194, ALT_B)
+#define GPIO194_STMAPE_DAT3 PIN_CFG(194, ALT_C)
+
+#define GPIO195_GPIO PIN_CFG(195, GPIO)
+#define GPIO195_MC1_CLK PIN_CFG(195, ALT_A)
+#define GPIO195_STMAPE_CLK PIN_CFG(195, ALT_B)
+#define GPIO195_BUSMON_CLK PIN_CFG(195, ALT_C)
+
+#define GPIO196_GPIO PIN_CFG(196, GPIO)
+#define GPIO196_MC1_CMD PIN_CFG(196, ALT_A)
+#define GPIO196_U0_RXD PIN_CFG(196, ALT_B)
+#define GPIO196_BUSMON_D38 PIN_CFG(196, ALT_C)
+
+#define GPIO197_GPIO PIN_CFG(197, GPIO)
+#define GPIO197_MC1_CMDDIR PIN_CFG(197, ALT_A)
+#define GPIO197_BUSMON_D39 PIN_CFG(197, ALT_B)
+
+#define GPIO198_GPIO PIN_CFG(198, GPIO)
+#define GPIO198_MC1_FBCLK PIN_CFG(198, ALT_A)
+
+#define GPIO199_GPIO PIN_CFG(199, GPIO)
+#define GPIO199_MC1_DAT0DIR PIN_CFG(199, ALT_A)
+#define GPIO199_BUSMON_D40 PIN_CFG(199, ALT_B)
+
+#define GPIO200_GPIO PIN_CFG(200, GPIO)
+#define GPIO200_U1_TXD PIN_CFG(200, ALT_A)
+#define GPIO200_ACCU0_RTSn PIN_CFG(200, ALT_B)
+
+#define GPIO201_GPIO PIN_CFG(201, GPIO)
+#define GPIO201_U1_RXD PIN_CFG(201, ALT_A)
+#define GPIO201_ACCU0_CTSn PIN_CFG(201, ALT_B)
+
+#define GPIO202_GPIO PIN_CFG(202, GPIO)
+#define GPIO202_U1_CTSn PIN_CFG(202, ALT_A)
+#define GPIO202_ACCU0_RXD PIN_CFG(202, ALT_B)
+
+#define GPIO203_GPIO PIN_CFG(203, GPIO)
+#define GPIO203_U1_RTSn PIN_CFG(203, ALT_A)
+#define GPIO203_ACCU0_TXD PIN_CFG(203, ALT_B)
+
+#define GPIO204_GPIO PIN_CFG(204, GPIO)
+#define GPIO204_SPI0_CS2n PIN_CFG(204, ALT_A)
+#define GPIO204_ACCGPIO_000 PIN_CFG(204, ALT_B)
+#define GPIO204_LCD_VSI1 PIN_CFG(204, ALT_C)
+
+#define GPIO205_GPIO PIN_CFG(205, GPIO)
+#define GPIO205_SPI0_CS1n PIN_CFG(205, ALT_A)
+#define GPIO205_ACCGPIO_001 PIN_CFG(205, ALT_B)
+#define GPIO205_LCD_D3 PIN_CFG(205, ALT_C)
+
+#define GPIO206_GPIO PIN_CFG(206, GPIO)
+#define GPIO206_SPI0_CS0n PIN_CFG(206, ALT_A)
+#define GPIO206_ACCGPIO_002 PIN_CFG(206, ALT_B)
+#define GPIO206_LCD_D2 PIN_CFG(206, ALT_C)
+
+#define GPIO207_GPIO PIN_CFG(207, GPIO)
+#define GPIO207_SPI0_RXD PIN_CFG(207, ALT_A)
+#define GPIO207_ACCGPIO_003 PIN_CFG(207, ALT_B)
+#define GPIO207_LCD_D1 PIN_CFG(207, ALT_C)
+
+#define GPIO208_GPIO PIN_CFG(208, GPIO)
+#define GPIO208_SPI0_TXD PIN_CFG(208, ALT_A)
+#define GPIO208_ACCGPIO_004 PIN_CFG(208, ALT_B)
+#define GPIO208_LCD_D0 PIN_CFG(208, ALT_C)
+
+#define GPIO209_GPIO PIN_CFG(209, GPIO)
+#define GPIO209_SPI0_CLK PIN_CFG(209, ALT_A)
+#define GPIO209_ACCGPIO_005 PIN_CFG(209, ALT_B)
+#define GPIO209_LCD_CLK PIN_CFG(209, ALT_C)
+
+#define GPIO210_GPIO PIN_CFG(210, GPIO)
+#define GPIO210_LCD_VSO PIN_CFG(210, ALT_A)
+#define GPIO210_PRCMU_PWRCTRL1 PIN_CFG(210, ALT_B)
+
+#define GPIO211_GPIO PIN_CFG(211, GPIO)
+#define GPIO211_LCD_VSI0 PIN_CFG(211, ALT_A)
+#define GPIO211_PRCMU_PWRCTRL2 PIN_CFG(211, ALT_B)
+
+#define GPIO212_GPIO PIN_CFG(212, GPIO)
+#define GPIO212_SPI2_CS2n PIN_CFG(212, ALT_A)
+#define GPIO212_LCD_HSO PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO PIN_CFG(213, GPIO)
+#define GPIO213_SPI2_CS1n PIN_CFG(213, ALT_A)
+#define GPIO213_LCD_DE PIN_CFG(213, ALT_B)
+#define GPIO213_BUSMON_D16 PIN_CFG(213, ALT_C)
+
+#define GPIO214_GPIO PIN_CFG(214, GPIO)
+#define GPIO214_SPI2_CS0n PIN_CFG(214, ALT_A)
+#define GPIO214_LCD_D7 PIN_CFG(214, ALT_B)
+#define GPIO214_BUSMON_D17 PIN_CFG(214, ALT_C)
+
+#define GPIO215_GPIO PIN_CFG(215, GPIO)
+#define GPIO215_SPI2_RXD PIN_CFG(215, ALT_A)
+#define GPIO215_LCD_D6 PIN_CFG(215, ALT_B)
+#define GPIO215_BUSMON_D18 PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO PIN_CFG(216, GPIO)
+#define GPIO216_SPI2_CLK PIN_CFG(216, ALT_A)
+#define GPIO216_LCD_D5 PIN_CFG(216, ALT_B)
+
+#define GPIO217_GPIO PIN_CFG(217, GPIO)
+#define GPIO217_SPI2_TXD PIN_CFG(217, ALT_A)
+#define GPIO217_LCD_D4 PIN_CFG(217, ALT_B)
+#define GPIO217_BUSMON_D19 PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO PIN_CFG(218, GPIO)
+#define GPIO218_I2C2_SCL PIN_CFG(218, ALT_A)
+#define GPIO218_LCD_VSO PIN_CFG(218, ALT_B)
+
+#define GPIO219_GPIO PIN_CFG(219, GPIO)
+#define GPIO219_I2C2_SDA PIN_CFG(219, ALT_A)
+#define GPIO219_LCD_D3 PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO PIN_CFG(220, GPIO)
+#define GPIO220_MSP2_TCK PIN_CFG(220, ALT_A)
+#define GPIO220_LCD_D2 PIN_CFG(220, ALT_B)
+
+#define GPIO221_GPIO PIN_CFG(221, GPIO)
+#define GPIO221_MSP2_TFS PIN_CFG(221, ALT_A)
+#define GPIO221_LCD_D1 PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO PIN_CFG(222, GPIO)
+#define GPIO222_MSP2_TXD PIN_CFG(222, ALT_A)
+#define GPIO222_LCD_D0 PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO PIN_CFG(223, GPIO)
+#define GPIO223_MSP2_RXD PIN_CFG(223, ALT_A)
+#define GPIO223_LCD_CLK PIN_CFG(223, ALT_B)
+
+#define GPIO224_GPIO PIN_CFG(224, GPIO)
+#define GPIO224_PRCMU_PWRCTRL0 PIN_CFG(224, ALT_A)
+#define GPIO224_LCD_VSI1 PIN_CFG(224, ALT_B)
+
+#define GPIO225_GPIO PIN_CFG(225, GPIO)
+#define GPIO225_PRCMU_PWRCTRL1 PIN_CFG(225, ALT_A)
+#define GPIO225_IRDA_RXD PIN_CFG(225, ALT_B)
+
+#define GPIO226_GPIO PIN_CFG(226, GPIO)
+#define GPIO226_PRCMU_PWRCTRL2 PIN_CFG(226, ALT_A)
+#define GPIO226_IRRC_DAT PIN_CFG(226, ALT_B)
+
+#define GPIO227_GPIO PIN_CFG(227, GPIO)
+#define GPIO227_IRRC_DAT PIN_CFG(227, ALT_A)
+#define GPIO227_IRDA_TXD PIN_CFG(227, ALT_B)
+
+#endif
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h
new file mode 100644
index 00000000..f923764e
--- /dev/null
+++ b/arch/arm/mach-ux500/pins-db8500.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __MACH_PINS_DB8500_H
+#define __MACH_PINS_DB8500_H
+
+/*
+ * TODO: Eventually encode all non-board specific pull up/down configuration
+ * here.
+ */
+
+#define GPIO0_GPIO PIN_CFG(0, GPIO)
+#define GPIO0_U0_CTSn PIN_CFG(0, ALT_A)
+#define GPIO0_TRIG_OUT PIN_CFG(0, ALT_B)
+#define GPIO0_IP_TDO PIN_CFG(0, ALT_C)
+
+#define GPIO1_GPIO PIN_CFG(1, GPIO)
+#define GPIO1_U0_RTSn PIN_CFG(1, ALT_A)
+#define GPIO1_TRIG_IN PIN_CFG(1, ALT_B)
+#define GPIO1_IP_TDI PIN_CFG(1, ALT_C)
+
+#define GPIO2_GPIO PIN_CFG(2, GPIO)
+#define GPIO2_U0_RXD PIN_CFG(2, ALT_A)
+#define GPIO2_NONE PIN_CFG(2, ALT_B)
+#define GPIO2_IP_TMS PIN_CFG(2, ALT_C)
+
+#define GPIO3_GPIO PIN_CFG(3, GPIO)
+#define GPIO3_U0_TXD PIN_CFG(3, ALT_A)
+#define GPIO3_NONE PIN_CFG(3, ALT_B)
+#define GPIO3_IP_TCK PIN_CFG(3, ALT_C)
+
+#define GPIO4_GPIO PIN_CFG(4, GPIO)
+#define GPIO4_U1_RXD PIN_CFG(4, ALT_A)
+#define GPIO4_I2C4_SCL PIN_CFG_PULL(4, ALT_B, UP)
+#define GPIO4_IP_TRSTn PIN_CFG(4, ALT_C)
+
+#define GPIO5_GPIO PIN_CFG(5, GPIO)
+#define GPIO5_U1_TXD PIN_CFG(5, ALT_A)
+#define GPIO5_I2C4_SDA PIN_CFG_PULL(5, ALT_B, UP)
+#define GPIO5_IP_GPIO6 PIN_CFG(5, ALT_C)
+
+#define GPIO6_GPIO PIN_CFG(6, GPIO)
+#define GPIO6_U1_CTSn PIN_CFG(6, ALT_A)
+#define GPIO6_I2C1_SCL PIN_CFG_PULL(6, ALT_B, UP)
+#define GPIO6_IP_GPIO0 PIN_CFG(6, ALT_C)
+
+#define GPIO7_GPIO PIN_CFG(7, GPIO)
+#define GPIO7_U1_RTSn PIN_CFG(7, ALT_A)
+#define GPIO7_I2C1_SDA PIN_CFG_PULL(7, ALT_B, UP)
+#define GPIO7_IP_GPIO1 PIN_CFG(7, ALT_C)
+
+#define GPIO8_GPIO PIN_CFG(8, GPIO)
+#define GPIO8_IPI2C_SDA PIN_CFG_PULL(8, ALT_A, UP)
+#define GPIO8_I2C2_SDA PIN_CFG_PULL(8, ALT_B, UP)
+
+#define GPIO9_GPIO PIN_CFG(9, GPIO)
+#define GPIO9_IPI2C_SCL PIN_CFG_PULL(9, ALT_A, UP)
+#define GPIO9_I2C2_SCL PIN_CFG_PULL(9, ALT_B, UP)
+
+#define GPIO10_GPIO PIN_CFG(10, GPIO)
+#define GPIO10_IPI2C_SDA PIN_CFG_PULL(10, ALT_A, UP)
+#define GPIO10_I2C2_SDA PIN_CFG_PULL(10, ALT_B, UP)
+#define GPIO10_IP_GPIO3 PIN_CFG(10, ALT_C)
+
+#define GPIO11_GPIO PIN_CFG(11, GPIO)
+#define GPIO11_IPI2C_SCL PIN_CFG_PULL(11, ALT_A, UP)
+#define GPIO11_I2C2_SCL PIN_CFG_PULL(11, ALT_B, UP)
+#define GPIO11_IP_GPIO2 PIN_CFG(11, ALT_C)
+
+#define GPIO12_GPIO PIN_CFG(12, GPIO)
+#define GPIO12_MSP0_TXD PIN_CFG(12, ALT_A)
+#define GPIO12_MSP0_RXD PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO PIN_CFG(13, GPIO)
+#define GPIO13_MSP0_TFS PIN_CFG(13, ALT_A)
+
+#define GPIO14_GPIO PIN_CFG(14, GPIO)
+#define GPIO14_MSP0_TCK PIN_CFG(14, ALT_A)
+
+#define GPIO15_GPIO PIN_CFG(15, GPIO)
+#define GPIO15_MSP0_RXD PIN_CFG(15, ALT_A)
+#define GPIO15_MSP0_TXD PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO PIN_CFG(16, GPIO)
+#define GPIO16_MSP0_RFS PIN_CFG(16, ALT_A)
+#define GPIO16_I2C1_SCL PIN_CFG_PULL(16, ALT_B, UP)
+#define GPIO16_SLIM0_DAT PIN_CFG(16, ALT_C)
+
+#define GPIO17_GPIO PIN_CFG(17, GPIO)
+#define GPIO17_MSP0_RCK PIN_CFG(17, ALT_A)
+#define GPIO17_I2C1_SDA PIN_CFG_PULL(17, ALT_B, UP)
+#define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C)
+
+#define GPIO18_GPIO PIN_CFG(18, GPIO)
+#define GPIO18_MC0_CMDDIR PIN_CFG_PULL(18, ALT_A, UP)
+#define GPIO18_U2_RXD PIN_CFG(18, ALT_B)
+#define GPIO18_MS_IEP PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO PIN_CFG(19, GPIO)
+#define GPIO19_MC0_DAT0DIR PIN_CFG_PULL(19, ALT_A, UP)
+#define GPIO19_U2_TXD PIN_CFG(19, ALT_B)
+#define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C)
+
+#define GPIO20_GPIO PIN_CFG(20, GPIO)
+#define GPIO20_MC0_DAT2DIR PIN_CFG_PULL(20, ALT_A, UP)
+#define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B)
+#define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C)
+
+#define GPIO21_GPIO PIN_CFG(21, GPIO)
+#define GPIO21_MC0_DAT31DIR PIN_CFG_PULL(21, ALT_A, UP)
+#define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B)
+#define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C)
+
+#define GPIO22_GPIO PIN_CFG(22, GPIO)
+#define GPIO22_MC0_FBCLK PIN_CFG_PULL(22, ALT_A, UP)
+#define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B)
+#define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C)
+
+#define GPIO23_GPIO PIN_CFG(23, GPIO)
+#define GPIO23_MC0_CLK PIN_CFG_PULL(23, ALT_A, UP)
+#define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B)
+#define GPIO23_MS_CLK PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO PIN_CFG(24, GPIO)
+#define GPIO24_MC0_CMD PIN_CFG_PULL(24, ALT_A, UP)
+#define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B)
+#define GPIO24_MS_BS PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO PIN_CFG(25, GPIO)
+#define GPIO25_MC0_DAT0 PIN_CFG_PULL(25, ALT_A, UP)
+#define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B)
+#define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO PIN_CFG(26, GPIO)
+#define GPIO26_MC0_DAT1 PIN_CFG_PULL(26, ALT_A, UP)
+#define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B)
+#define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C)
+
+#define GPIO27_GPIO PIN_CFG(27, GPIO)
+#define GPIO27_MC0_DAT2 PIN_CFG_PULL(27, ALT_A, UP)
+#define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B)
+#define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C)
+
+#define GPIO28_GPIO PIN_CFG(28, GPIO)
+#define GPIO28_MC0_DAT3 PIN_CFG_PULL(28, ALT_A, UP)
+#define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B)
+#define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C)
+
+#define GPIO29_GPIO PIN_CFG(29, GPIO)
+#define GPIO29_MC0_DAT4 PIN_CFG(29, ALT_A)
+#define GPIO29_SPI3_CLK PIN_CFG(29, ALT_B)
+#define GPIO29_U2_RXD PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A)
+#define GPIO30_SPI3_RXD PIN_CFG(30, ALT_B)
+#define GPIO30_U2_TXD PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT6 PIN_CFG(31, ALT_A)
+#define GPIO31_SPI3_FRM PIN_CFG(31, ALT_B)
+#define GPIO31_U2_CTSn PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO PIN_CFG(32, GPIO)
+#define GPIO32_MC0_DAT7 PIN_CFG(32, ALT_A)
+#define GPIO32_SPI3_TXD PIN_CFG(32, ALT_B)
+#define GPIO32_U2_RTSn PIN_CFG(32, ALT_C)
+
+#define GPIO33_GPIO PIN_CFG(33, GPIO)
+#define GPIO33_MSP1_TXD PIN_CFG(33, ALT_A)
+#define GPIO33_MSP1_RXD PIN_CFG(33, ALT_B)
+#define GPIO33_U0_DTRn PIN_CFG(33, ALT_C)
+
+#define GPIO34_GPIO PIN_CFG(34, GPIO)
+#define GPIO34_MSP1_TFS PIN_CFG(34, ALT_A)
+#define GPIO34_NONE PIN_CFG(34, ALT_B)
+#define GPIO34_U0_DCDn PIN_CFG(34, ALT_C)
+
+#define GPIO35_GPIO PIN_CFG(35, GPIO)
+#define GPIO35_MSP1_TCK PIN_CFG(35, ALT_A)
+#define GPIO35_NONE PIN_CFG(35, ALT_B)
+#define GPIO35_U0_DSRn PIN_CFG(35, ALT_C)
+
+#define GPIO36_GPIO PIN_CFG(36, GPIO)
+#define GPIO36_MSP1_RXD PIN_CFG(36, ALT_A)
+#define GPIO36_MSP1_TXD PIN_CFG(36, ALT_B)
+#define GPIO36_U0_RIn PIN_CFG(36, ALT_C)
+
+#define GPIO64_GPIO PIN_CFG(64, GPIO)
+#define GPIO64_LCDB_DE PIN_CFG(64, ALT_A)
+#define GPIO64_KP_O1 PIN_CFG(64, ALT_B)
+#define GPIO64_IP_GPIO4 PIN_CFG(64, ALT_C)
+
+#define GPIO65_GPIO PIN_CFG(65, GPIO)
+#define GPIO65_LCDB_HSO PIN_CFG(65, ALT_A)
+#define GPIO65_KP_O0 PIN_CFG(65, ALT_B)
+#define GPIO65_IP_GPIO5 PIN_CFG(65, ALT_C)
+
+#define GPIO66_GPIO PIN_CFG(66, GPIO)
+#define GPIO66_LCDB_VSO PIN_CFG(66, ALT_A)
+#define GPIO66_KP_I1 PIN_CFG(66, ALT_B)
+#define GPIO66_IP_GPIO6 PIN_CFG(66, ALT_C)
+
+#define GPIO67_GPIO PIN_CFG(67, GPIO)
+#define GPIO67_LCDB_CLK PIN_CFG(67, ALT_A)
+#define GPIO67_KP_I0 PIN_CFG(67, ALT_B)
+#define GPIO67_IP_GPIO7 PIN_CFG(67, ALT_C)
+
+#define GPIO68_GPIO PIN_CFG(68, GPIO)
+#define GPIO68_LCD_VSI0 PIN_CFG(68, ALT_A)
+#define GPIO68_KP_O7 PIN_CFG(68, ALT_B)
+#define GPIO68_SM_CLE PIN_CFG(68, ALT_C)
+
+#define GPIO69_GPIO PIN_CFG(69, GPIO)
+#define GPIO69_LCD_VSI1 PIN_CFG(69, ALT_A)
+#define GPIO69_KP_I7 PIN_CFG(69, ALT_B)
+#define GPIO69_SM_ALE PIN_CFG(69, ALT_C)
+
+#define GPIO70_GPIO PIN_CFG(70, GPIO)
+#define GPIO70_LCD_D0 PIN_CFG(70, ALT_A)
+#define GPIO70_KP_O5 PIN_CFG(70, ALT_B)
+#define GPIO70_STMAPE_CLK PIN_CFG(70, ALT_C)
+
+#define GPIO71_GPIO PIN_CFG(71, GPIO)
+#define GPIO71_LCD_D1 PIN_CFG(71, ALT_A)
+#define GPIO71_KP_O4 PIN_CFG(71, ALT_B)
+#define GPIO71_STMAPE_DAT3 PIN_CFG(71, ALT_C)
+
+#define GPIO72_GPIO PIN_CFG(72, GPIO)
+#define GPIO72_LCD_D2 PIN_CFG(72, ALT_A)
+#define GPIO72_KP_O3 PIN_CFG(72, ALT_B)
+#define GPIO72_STMAPE_DAT2 PIN_CFG(72, ALT_C)
+
+#define GPIO73_GPIO PIN_CFG(73, GPIO)
+#define GPIO73_LCD_D3 PIN_CFG(73, ALT_A)
+#define GPIO73_KP_O2 PIN_CFG(73, ALT_B)
+#define GPIO73_STMAPE_DAT1 PIN_CFG(73, ALT_C)
+
+#define GPIO74_GPIO PIN_CFG(74, GPIO)
+#define GPIO74_LCD_D4 PIN_CFG(74, ALT_A)
+#define GPIO74_KP_I5 PIN_CFG(74, ALT_B)
+#define GPIO74_STMAPE_DAT0 PIN_CFG(74, ALT_C)
+
+#define GPIO75_GPIO PIN_CFG(75, GPIO)
+#define GPIO75_LCD_D5 PIN_CFG(75, ALT_A)
+#define GPIO75_KP_I4 PIN_CFG(75, ALT_B)
+#define GPIO75_U2_RXD PIN_CFG(75, ALT_C)
+
+#define GPIO76_GPIO PIN_CFG(76, GPIO)
+#define GPIO76_LCD_D6 PIN_CFG(76, ALT_A)
+#define GPIO76_KP_I3 PIN_CFG(76, ALT_B)
+#define GPIO76_U2_TXD PIN_CFG(76, ALT_C)
+
+#define GPIO77_GPIO PIN_CFG(77, GPIO)
+#define GPIO77_LCD_D7 PIN_CFG(77, ALT_A)
+#define GPIO77_KP_I2 PIN_CFG(77, ALT_B)
+#define GPIO77_NONE PIN_CFG(77, ALT_C)
+
+#define GPIO78_GPIO PIN_CFG(78, GPIO)
+#define GPIO78_LCD_D8 PIN_CFG(78, ALT_A)
+#define GPIO78_KP_O6 PIN_CFG(78, ALT_B)
+#define GPIO78_IP_GPIO2 PIN_CFG(78, ALT_C)
+
+#define GPIO79_GPIO PIN_CFG(79, GPIO)
+#define GPIO79_LCD_D9 PIN_CFG(79, ALT_A)
+#define GPIO79_KP_I6 PIN_CFG(79, ALT_B)
+#define GPIO79_IP_GPIO3 PIN_CFG(79, ALT_C)
+
+#define GPIO80_GPIO PIN_CFG(80, GPIO)
+#define GPIO80_LCD_D10 PIN_CFG(80, ALT_A)
+#define GPIO80_KP_SKA0 PIN_CFG(80, ALT_B)
+#define GPIO80_IP_GPIO4 PIN_CFG(80, ALT_C)
+
+#define GPIO81_GPIO PIN_CFG(81, GPIO)
+#define GPIO81_LCD_D11 PIN_CFG(81, ALT_A)
+#define GPIO81_KP_SKB0 PIN_CFG(81, ALT_B)
+#define GPIO81_IP_GPIO5 PIN_CFG(81, ALT_C)
+
+#define GPIO82_GPIO PIN_CFG(82, GPIO)
+#define GPIO82_LCD_D12 PIN_CFG(82, ALT_A)
+#define GPIO82_KP_O5 PIN_CFG(82, ALT_B)
+
+#define GPIO83_GPIO PIN_CFG(83, GPIO)
+#define GPIO83_LCD_D13 PIN_CFG(83, ALT_A)
+#define GPIO83_KP_O4 PIN_CFG(83, ALT_B)
+
+#define GPIO84_GPIO PIN_CFG(84, GPIO)
+#define GPIO84_LCD_D14 PIN_CFG(84, ALT_A)
+#define GPIO84_KP_I5 PIN_CFG(84, ALT_B)
+
+#define GPIO85_GPIO PIN_CFG(85, GPIO)
+#define GPIO85_LCD_D15 PIN_CFG(85, ALT_A)
+#define GPIO85_KP_I4 PIN_CFG(85, ALT_B)
+
+#define GPIO86_GPIO PIN_CFG(86, GPIO)
+#define GPIO86_LCD_D16 PIN_CFG(86, ALT_A)
+#define GPIO86_SM_ADQ0 PIN_CFG(86, ALT_B)
+#define GPIO86_MC5_DAT0 PIN_CFG(86, ALT_C)
+
+#define GPIO87_GPIO PIN_CFG(87, GPIO)
+#define GPIO87_LCD_D17 PIN_CFG(87, ALT_A)
+#define GPIO87_SM_ADQ1 PIN_CFG(87, ALT_B)
+#define GPIO87_MC5_DAT1 PIN_CFG(87, ALT_C)
+
+#define GPIO88_GPIO PIN_CFG(88, GPIO)
+#define GPIO88_LCD_D18 PIN_CFG(88, ALT_A)
+#define GPIO88_SM_ADQ2 PIN_CFG(88, ALT_B)
+#define GPIO88_MC5_DAT2 PIN_CFG(88, ALT_C)
+
+#define GPIO89_GPIO PIN_CFG(89, GPIO)
+#define GPIO89_LCD_D19 PIN_CFG(89, ALT_A)
+#define GPIO89_SM_ADQ3 PIN_CFG(89, ALT_B)
+#define GPIO89_MC5_DAT3 PIN_CFG(89, ALT_C)
+
+#define GPIO90_GPIO PIN_CFG(90, GPIO)
+#define GPIO90_LCD_D20 PIN_CFG(90, ALT_A)
+#define GPIO90_SM_ADQ4 PIN_CFG(90, ALT_B)
+#define GPIO90_MC5_CMD PIN_CFG(90, ALT_C)
+
+#define GPIO91_GPIO PIN_CFG(91, GPIO)
+#define GPIO91_LCD_D21 PIN_CFG(91, ALT_A)
+#define GPIO91_SM_ADQ5 PIN_CFG(91, ALT_B)
+#define GPIO91_MC5_FBCLK PIN_CFG(91, ALT_C)
+
+#define GPIO92_GPIO PIN_CFG(92, GPIO)
+#define GPIO92_LCD_D22 PIN_CFG(92, ALT_A)
+#define GPIO92_SM_ADQ6 PIN_CFG(92, ALT_B)
+#define GPIO92_MC5_CLK PIN_CFG(92, ALT_C)
+
+#define GPIO93_GPIO PIN_CFG(93, GPIO)
+#define GPIO93_LCD_D23 PIN_CFG(93, ALT_A)
+#define GPIO93_SM_ADQ7 PIN_CFG(93, ALT_B)
+#define GPIO93_MC5_DAT4 PIN_CFG(93, ALT_C)
+
+#define GPIO94_GPIO PIN_CFG(94, GPIO)
+#define GPIO94_KP_O7 PIN_CFG(94, ALT_A)
+#define GPIO94_SM_ADVn PIN_CFG(94, ALT_B)
+#define GPIO94_MC5_DAT5 PIN_CFG(94, ALT_C)
+
+#define GPIO95_GPIO PIN_CFG(95, GPIO)
+#define GPIO95_KP_I7 PIN_CFG(95, ALT_A)
+#define GPIO95_SM_CS0n PIN_CFG(95, ALT_B)
+#define GPIO95_SM_PS0n PIN_CFG(95, ALT_C)
+
+#define GPIO96_GPIO PIN_CFG(96, GPIO)
+#define GPIO96_KP_O6 PIN_CFG(96, ALT_A)
+#define GPIO96_SM_OEn PIN_CFG(96, ALT_B)
+#define GPIO96_MC5_DAT6 PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO PIN_CFG(97, GPIO)
+#define GPIO97_KP_I6 PIN_CFG(97, ALT_A)
+#define GPIO97_SM_WEn PIN_CFG(97, ALT_B)
+#define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C)
+
+#define GPIO128_GPIO PIN_CFG(128, GPIO)
+#define GPIO128_MC2_CLK PIN_CFG_PULL(128, ALT_A, UP)
+#define GPIO128_SM_CKO PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO PIN_CFG(129, GPIO)
+#define GPIO129_MC2_CMD PIN_CFG_PULL(129, ALT_A, UP)
+#define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO PIN_CFG(130, GPIO)
+#define GPIO130_MC2_FBCLK PIN_CFG_PULL(130, ALT_A, UP)
+#define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B)
+#define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C)
+
+#define GPIO131_GPIO PIN_CFG(131, GPIO)
+#define GPIO131_MC2_DAT0 PIN_CFG_PULL(131, ALT_A, UP)
+#define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO PIN_CFG(132, GPIO)
+#define GPIO132_MC2_DAT1 PIN_CFG_PULL(132, ALT_A, UP)
+#define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B)
+
+#define GPIO133_GPIO PIN_CFG(133, GPIO)
+#define GPIO133_MC2_DAT2 PIN_CFG_PULL(133, ALT_A, UP)
+#define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B)
+
+#define GPIO134_GPIO PIN_CFG(134, GPIO)
+#define GPIO134_MC2_DAT3 PIN_CFG_PULL(134, ALT_A, UP)
+#define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B)
+
+#define GPIO135_GPIO PIN_CFG(135, GPIO)
+#define GPIO135_MC2_DAT4 PIN_CFG_PULL(135, ALT_A, UP)
+#define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B)
+
+#define GPIO136_GPIO PIN_CFG(136, GPIO)
+#define GPIO136_MC2_DAT5 PIN_CFG_PULL(136, ALT_A, UP)
+#define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B)
+
+#define GPIO137_GPIO PIN_CFG(137, GPIO)
+#define GPIO137_MC2_DAT6 PIN_CFG_PULL(137, ALT_A, UP)
+#define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B)
+
+#define GPIO138_GPIO PIN_CFG(138, GPIO)
+#define GPIO138_MC2_DAT7 PIN_CFG_PULL(138, ALT_A, UP)
+#define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B)
+
+#define GPIO139_GPIO PIN_CFG(139, GPIO)
+#define GPIO139_SSP1_RXD PIN_CFG(139, ALT_A)
+#define GPIO139_SM_WAIT1n PIN_CFG(139, ALT_B)
+#define GPIO139_KP_O8 PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO PIN_CFG(140, GPIO)
+#define GPIO140_SSP1_TXD PIN_CFG(140, ALT_A)
+#define GPIO140_IP_GPIO7 PIN_CFG(140, ALT_B)
+#define GPIO140_KP_SKA1 PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO PIN_CFG(141, GPIO)
+#define GPIO141_SSP1_CLK PIN_CFG(141, ALT_A)
+#define GPIO141_IP_GPIO2 PIN_CFG(141, ALT_B)
+#define GPIO141_KP_O9 PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO PIN_CFG(142, GPIO)
+#define GPIO142_SSP1_FRM PIN_CFG(142, ALT_A)
+#define GPIO142_IP_GPIO3 PIN_CFG(142, ALT_B)
+#define GPIO142_KP_SKB1 PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO PIN_CFG(143, GPIO)
+#define GPIO143_SSP0_CLK PIN_CFG(143, ALT_A)
+
+#define GPIO144_GPIO PIN_CFG(144, GPIO)
+#define GPIO144_SSP0_FRM PIN_CFG(144, ALT_A)
+
+#define GPIO145_GPIO PIN_CFG(145, GPIO)
+#define GPIO145_SSP0_RXD PIN_CFG(145, ALT_A)
+
+#define GPIO146_GPIO PIN_CFG(146, GPIO)
+#define GPIO146_SSP0_TXD PIN_CFG(146, ALT_A)
+
+#define GPIO147_GPIO PIN_CFG(147, GPIO)
+#define GPIO147_I2C0_SCL PIN_CFG_PULL(147, ALT_A, UP)
+
+#define GPIO148_GPIO PIN_CFG(148, GPIO)
+#define GPIO148_I2C0_SDA PIN_CFG_PULL(148, ALT_A, UP)
+
+#define GPIO149_GPIO PIN_CFG(149, GPIO)
+#define GPIO149_IP_GPIO0 PIN_CFG(149, ALT_A)
+#define GPIO149_SM_CS1n PIN_CFG(149, ALT_B)
+#define GPIO149_SM_PS1n PIN_CFG(149, ALT_C)
+
+#define GPIO150_GPIO PIN_CFG(150, GPIO)
+#define GPIO150_IP_GPIO1 PIN_CFG(150, ALT_A)
+#define GPIO150_LCDA_CLK PIN_CFG(150, ALT_B)
+
+#define GPIO151_GPIO PIN_CFG(151, GPIO)
+#define GPIO151_KP_SKA0 PIN_CFG(151, ALT_A)
+#define GPIO151_LCD_VSI0 PIN_CFG(151, ALT_B)
+#define GPIO151_KP_O8 PIN_CFG(151, ALT_C)
+
+#define GPIO152_GPIO PIN_CFG(152, GPIO)
+#define GPIO152_KP_SKB0 PIN_CFG(152, ALT_A)
+#define GPIO152_LCD_VSI1 PIN_CFG(152, ALT_B)
+#define GPIO152_KP_O9 PIN_CFG(152, ALT_C)
+
+#define GPIO153_GPIO PIN_CFG(153, GPIO)
+#define GPIO153_KP_I7 PIN_CFG_PULL(153, ALT_A, DOWN)
+#define GPIO153_LCD_D24 PIN_CFG(153, ALT_B)
+#define GPIO153_U2_RXD PIN_CFG(153, ALT_C)
+
+#define GPIO154_GPIO PIN_CFG(154, GPIO)
+#define GPIO154_KP_I6 PIN_CFG_PULL(154, ALT_A, DOWN)
+#define GPIO154_LCD_D25 PIN_CFG(154, ALT_B)
+#define GPIO154_U2_TXD PIN_CFG(154, ALT_C)
+
+#define GPIO155_GPIO PIN_CFG(155, GPIO)
+#define GPIO155_KP_I5 PIN_CFG_PULL(155, ALT_A, DOWN)
+#define GPIO155_LCD_D26 PIN_CFG(155, ALT_B)
+#define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C)
+
+#define GPIO156_GPIO PIN_CFG(156, GPIO)
+#define GPIO156_KP_I4 PIN_CFG_PULL(156, ALT_A, DOWN)
+#define GPIO156_LCD_D27 PIN_CFG(156, ALT_B)
+#define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C)
+
+#define GPIO157_GPIO PIN_CFG(157, GPIO)
+#define GPIO157_KP_O7 PIN_CFG_PULL(157, ALT_A, UP)
+#define GPIO157_LCD_D28 PIN_CFG(157, ALT_B)
+#define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C)
+
+#define GPIO158_GPIO PIN_CFG(158, GPIO)
+#define GPIO158_KP_O6 PIN_CFG_PULL(158, ALT_A, UP)
+#define GPIO158_LCD_D29 PIN_CFG(158, ALT_B)
+#define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C)
+
+#define GPIO159_GPIO PIN_CFG(159, GPIO)
+#define GPIO159_KP_O5 PIN_CFG_PULL(159, ALT_A, UP)
+#define GPIO159_LCD_D30 PIN_CFG(159, ALT_B)
+#define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C)
+
+#define GPIO160_GPIO PIN_CFG(160, GPIO)
+#define GPIO160_KP_O4 PIN_CFG_PULL(160, ALT_A, UP)
+#define GPIO160_LCD_D31 PIN_CFG(160, ALT_B)
+#define GPIO160_NONE PIN_CFG(160, ALT_C)
+
+#define GPIO161_GPIO PIN_CFG(161, GPIO)
+#define GPIO161_KP_I3 PIN_CFG_PULL(161, ALT_A, DOWN)
+#define GPIO161_LCD_D32 PIN_CFG(161, ALT_B)
+#define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C)
+
+#define GPIO162_GPIO PIN_CFG(162, GPIO)
+#define GPIO162_KP_I2 PIN_CFG_PULL(162, ALT_A, DOWN)
+#define GPIO162_LCD_D33 PIN_CFG(162, ALT_B)
+#define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C)
+
+#define GPIO163_GPIO PIN_CFG(163, GPIO)
+#define GPIO163_KP_I1 PIN_CFG_PULL(163, ALT_A, DOWN)
+#define GPIO163_LCD_D34 PIN_CFG(163, ALT_B)
+#define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C)
+
+#define GPIO164_GPIO PIN_CFG(164, GPIO)
+#define GPIO164_KP_I0 PIN_CFG_PULL(164, ALT_A, UP)
+#define GPIO164_LCD_D35 PIN_CFG(164, ALT_B)
+#define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C)
+
+#define GPIO165_GPIO PIN_CFG(165, GPIO)
+#define GPIO165_KP_O3 PIN_CFG_PULL(165, ALT_A, UP)
+#define GPIO165_LCD_D36 PIN_CFG(165, ALT_B)
+#define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO PIN_CFG(166, GPIO)
+#define GPIO166_KP_O2 PIN_CFG_PULL(166, ALT_A, UP)
+#define GPIO166_LCD_D37 PIN_CFG(166, ALT_B)
+#define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO PIN_CFG(167, GPIO)
+#define GPIO167_KP_O1 PIN_CFG_PULL(167, ALT_A, UP)
+#define GPIO167_LCD_D38 PIN_CFG(167, ALT_B)
+#define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO PIN_CFG(168, GPIO)
+#define GPIO168_KP_O0 PIN_CFG_PULL(168, ALT_A, UP)
+#define GPIO168_LCD_D39 PIN_CFG(168, ALT_B)
+#define GPIO168_NONE PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO PIN_CFG(169, GPIO)
+#define GPIO169_RF_PURn PIN_CFG(169, ALT_A)
+#define GPIO169_LCDA_DE PIN_CFG(169, ALT_B)
+#define GPIO169_USBSIM_PDC PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO PIN_CFG(170, GPIO)
+#define GPIO170_MODEM_STATE PIN_CFG(170, ALT_A)
+#define GPIO170_LCDA_VSO PIN_CFG(170, ALT_B)
+#define GPIO170_KP_SKA1 PIN_CFG(170, ALT_C)
+
+#define GPIO171_GPIO PIN_CFG(171, GPIO)
+#define GPIO171_MODEM_PWREN PIN_CFG(171, ALT_A)
+#define GPIO171_LCDA_HSO PIN_CFG(171, ALT_B)
+#define GPIO171_KP_SKB1 PIN_CFG(171, ALT_C)
+
+#define GPIO192_GPIO PIN_CFG(192, GPIO)
+#define GPIO192_MSP2_SCK PIN_CFG(192, ALT_A)
+
+#define GPIO193_GPIO PIN_CFG(193, GPIO)
+#define GPIO193_MSP2_TXD PIN_CFG(193, ALT_A)
+
+#define GPIO194_GPIO PIN_CFG(194, GPIO)
+#define GPIO194_MSP2_TCK PIN_CFG(194, ALT_A)
+
+#define GPIO195_GPIO PIN_CFG(195, GPIO)
+#define GPIO195_MSP2_TFS PIN_CFG(195, ALT_A)
+
+#define GPIO196_GPIO PIN_CFG(196, GPIO)
+#define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A)
+
+#define GPIO197_GPIO PIN_CFG(197, GPIO)
+#define GPIO197_MC4_DAT3 PIN_CFG_PULL(197, ALT_A, UP)
+
+#define GPIO198_GPIO PIN_CFG(198, GPIO)
+#define GPIO198_MC4_DAT2 PIN_CFG_PULL(198, ALT_A, UP)
+
+#define GPIO199_GPIO PIN_CFG(199, GPIO)
+#define GPIO199_MC4_DAT1 PIN_CFG_PULL(199, ALT_A, UP)
+
+#define GPIO200_GPIO PIN_CFG(200, GPIO)
+#define GPIO200_MC4_DAT0 PIN_CFG_PULL(200, ALT_A, UP)
+
+#define GPIO201_GPIO PIN_CFG(201, GPIO)
+#define GPIO201_MC4_CMD PIN_CFG_PULL(201, ALT_A, UP)
+
+#define GPIO202_GPIO PIN_CFG(202, GPIO)
+#define GPIO202_MC4_FBCLK PIN_CFG_PULL(202, ALT_A, UP)
+#define GPIO202_PWL PIN_CFG(202, ALT_B)
+#define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C)
+
+#define GPIO203_GPIO PIN_CFG(203, GPIO)
+#define GPIO203_MC4_CLK PIN_CFG_PULL(203, ALT_A, UP)
+
+#define GPIO204_GPIO PIN_CFG(204, GPIO)
+#define GPIO204_MC4_DAT7 PIN_CFG_PULL(204, ALT_A, UP)
+
+#define GPIO205_GPIO PIN_CFG(205, GPIO)
+#define GPIO205_MC4_DAT6 PIN_CFG_PULL(205, ALT_A, UP)
+
+#define GPIO206_GPIO PIN_CFG(206, GPIO)
+#define GPIO206_MC4_DAT5 PIN_CFG_PULL(206, ALT_A, UP)
+
+#define GPIO207_GPIO PIN_CFG(207, GPIO)
+#define GPIO207_MC4_DAT4 PIN_CFG_PULL(207, ALT_A, UP)
+
+#define GPIO208_GPIO PIN_CFG(208, GPIO)
+#define GPIO208_MC1_CLK PIN_CFG(208, ALT_A)
+
+#define GPIO209_GPIO PIN_CFG(209, GPIO)
+#define GPIO209_MC1_FBCLK PIN_CFG(209, ALT_A)
+#define GPIO209_SPI1_CLK PIN_CFG(209, ALT_B)
+
+#define GPIO210_GPIO PIN_CFG(210, GPIO)
+#define GPIO210_MC1_CMD PIN_CFG(210, ALT_A)
+
+#define GPIO211_GPIO PIN_CFG(211, GPIO)
+#define GPIO211_MC1_DAT0 PIN_CFG(211, ALT_A)
+
+#define GPIO212_GPIO PIN_CFG(212, GPIO)
+#define GPIO212_MC1_DAT1 PIN_CFG(212, ALT_A)
+#define GPIO212_SPI1_FRM PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO PIN_CFG(213, GPIO)
+#define GPIO213_MC1_DAT2 PIN_CFG(213, ALT_A)
+#define GPIO213_SPI1_TXD PIN_CFG(213, ALT_B)
+
+#define GPIO214_GPIO PIN_CFG(214, GPIO)
+#define GPIO214_MC1_DAT3 PIN_CFG(214, ALT_A)
+#define GPIO214_SPI1_RXD PIN_CFG(214, ALT_B)
+
+#define GPIO215_GPIO PIN_CFG(215, GPIO)
+#define GPIO215_MC1_CMDDIR PIN_CFG(215, ALT_A)
+#define GPIO215_MC3_DAT2DIR PIN_CFG(215, ALT_B)
+#define GPIO215_CLKOUT1 PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO PIN_CFG(216, GPIO)
+#define GPIO216_MC1_DAT2DIR PIN_CFG(216, ALT_A)
+#define GPIO216_MC3_CMDDIR PIN_CFG(216, ALT_B)
+#define GPIO216_I2C3_SDA PIN_CFG_PULL(216, ALT_C, UP)
+
+#define GPIO217_GPIO PIN_CFG(217, GPIO)
+#define GPIO217_MC1_DAT0DIR PIN_CFG(217, ALT_A)
+#define GPIO217_MC3_DAT31DIR PIN_CFG(217, ALT_B)
+#define GPIO217_CLKOUT2 PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO PIN_CFG(218, GPIO)
+#define GPIO218_MC1_DAT31DIR PIN_CFG(218, ALT_A)
+#define GPIO218_MC3_DAT0DIR PIN_CFG(218, ALT_B)
+#define GPIO218_I2C3_SCL PIN_CFG_PULL(218, ALT_C, UP)
+
+#define GPIO219_GPIO PIN_CFG(219, GPIO)
+#define GPIO219_HSIR_FLA0 PIN_CFG(219, ALT_A)
+#define GPIO219_MC3_CLK PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO PIN_CFG(220, GPIO)
+#define GPIO220_HSIR_DAT0 PIN_CFG(220, ALT_A)
+#define GPIO220_MC3_FBCLK PIN_CFG(220, ALT_B)
+#define GPIO220_SPI0_CLK PIN_CFG(220, ALT_C)
+
+#define GPIO221_GPIO PIN_CFG(221, GPIO)
+#define GPIO221_HSIR_RDY0 PIN_CFG(221, ALT_A)
+#define GPIO221_MC3_CMD PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO PIN_CFG(222, GPIO)
+#define GPIO222_HSIT_FLA0 PIN_CFG(222, ALT_A)
+#define GPIO222_MC3_DAT0 PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO PIN_CFG(223, GPIO)
+#define GPIO223_HSIT_DAT0 PIN_CFG(223, ALT_A)
+#define GPIO223_MC3_DAT1 PIN_CFG(223, ALT_B)
+#define GPIO223_SPI0_FRM PIN_CFG(223, ALT_C)
+
+#define GPIO224_GPIO PIN_CFG(224, GPIO)
+#define GPIO224_HSIT_RDY0 PIN_CFG(224, ALT_A)
+#define GPIO224_MC3_DAT2 PIN_CFG(224, ALT_B)
+#define GPIO224_SPI0_TXD PIN_CFG(224, ALT_C)
+
+#define GPIO225_GPIO PIN_CFG(225, GPIO)
+#define GPIO225_HSIT_CAWAKE0 PIN_CFG(225, ALT_A)
+#define GPIO225_MC3_DAT3 PIN_CFG(225, ALT_B)
+#define GPIO225_SPI0_RXD PIN_CFG(225, ALT_C)
+
+#define GPIO226_GPIO PIN_CFG(226, GPIO)
+#define GPIO226_HSIT_ACWAKE0 PIN_CFG(226, ALT_A)
+#define GPIO226_PWL PIN_CFG(226, ALT_B)
+#define GPIO226_USBSIM_PDC PIN_CFG(226, ALT_C)
+
+#define GPIO227_GPIO PIN_CFG(227, GPIO)
+#define GPIO227_CLKOUT1 PIN_CFG(227, ALT_A)
+
+#define GPIO228_GPIO PIN_CFG(228, GPIO)
+#define GPIO228_CLKOUT2 PIN_CFG(228, ALT_A)
+
+#define GPIO229_GPIO PIN_CFG(229, GPIO)
+#define GPIO229_CLKOUT1 PIN_CFG(229, ALT_A)
+#define GPIO229_PWL PIN_CFG(229, ALT_B)
+#define GPIO229_I2C3_SDA PIN_CFG_PULL(229, ALT_C, UP)
+
+#define GPIO230_GPIO PIN_CFG(230, GPIO)
+#define GPIO230_CLKOUT2 PIN_CFG(230, ALT_A)
+#define GPIO230_PWL PIN_CFG(230, ALT_B)
+#define GPIO230_I2C3_SCL PIN_CFG_PULL(230, ALT_C, UP)
+
+#define GPIO256_GPIO PIN_CFG(256, GPIO)
+#define GPIO256_USB_NXT PIN_CFG(256, ALT_A)
+
+#define GPIO257_GPIO PIN_CFG(257, GPIO)
+#define GPIO257_USB_STP PIN_CFG(257, ALT_A)
+
+#define GPIO258_GPIO PIN_CFG(258, GPIO)
+#define GPIO258_USB_XCLK PIN_CFG(258, ALT_A)
+#define GPIO258_NONE PIN_CFG(258, ALT_B)
+#define GPIO258_DDR_TRIG PIN_CFG(258, ALT_C)
+
+#define GPIO259_GPIO PIN_CFG(259, GPIO)
+#define GPIO259_USB_DIR PIN_CFG(259, ALT_A)
+
+#define GPIO260_GPIO PIN_CFG(260, GPIO)
+#define GPIO260_USB_DAT7 PIN_CFG(260, ALT_A)
+
+#define GPIO261_GPIO PIN_CFG(261, GPIO)
+#define GPIO261_USB_DAT6 PIN_CFG(261, ALT_A)
+
+#define GPIO262_GPIO PIN_CFG(262, GPIO)
+#define GPIO262_USB_DAT5 PIN_CFG(262, ALT_A)
+
+#define GPIO263_GPIO PIN_CFG(263, GPIO)
+#define GPIO263_USB_DAT4 PIN_CFG(263, ALT_A)
+
+#define GPIO264_GPIO PIN_CFG(264, GPIO)
+#define GPIO264_USB_DAT3 PIN_CFG(264, ALT_A)
+
+#define GPIO265_GPIO PIN_CFG(265, GPIO)
+#define GPIO265_USB_DAT2 PIN_CFG(265, ALT_A)
+
+#define GPIO266_GPIO PIN_CFG(266, GPIO)
+#define GPIO266_USB_DAT1 PIN_CFG(266, ALT_A)
+
+#define GPIO267_GPIO PIN_CFG(267, GPIO)
+#define GPIO267_USB_DAT0 PIN_CFG(267, ALT_A)
+
+#endif
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
new file mode 100644
index 00000000..0c527fe2
--- /dev/null
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * Copyright (C) 2008 STMicroelctronics.
+ * Copyright (C) 2009 ST-Ericsson.
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is based on arm realview 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.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/smp_scu.h>
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+/* This is called from headsmp.S to wakeup the secondary core */
+extern void u8500_secondary_startup(void);
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int pen_release = -1;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ if (cpu_is_u5500())
+ return __io_address(U5500_SCU_BASE);
+ else if (cpu_is_u8500())
+ return __io_address(U8500_SCU_BASE);
+ else
+ ux500_unknown_soc();
+
+ return NULL;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ write_pen_release(-1);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * The secondary processor is waiting to be released from
+ * the holding pen - release it, then wait for it to flag
+ * that it has been released by resetting pen_release.
+ */
+ write_pen_release(cpu);
+
+ gic_raise_softirq(cpumask_of(cpu), 1);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ if (pen_release == -1)
+ break;
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init wakeup_secondary(void)
+{
+ void __iomem *backupram;
+
+ if (cpu_is_u5500())
+ backupram = __io_address(U5500_BACKUPRAM0_BASE);
+ else if (cpu_is_u8500())
+ backupram = __io_address(U8500_BACKUPRAM0_BASE);
+ else
+ ux500_unknown_soc();
+
+ /*
+ * write the address of secondary startup into the backup ram register
+ * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
+ * backup ram register at offset 0x1FF0, which is what boot rom code
+ * is waiting for. This would wake up the secondary core from WFE
+ */
+#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
+ __raw_writel(virt_to_phys(u8500_secondary_startup),
+ backupram + UX500_CPU1_JUMPADDR_OFFSET);
+
+#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
+ __raw_writel(0xA1FEED01,
+ backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
+
+ /* make sure write buffer is drained */
+ mb();
+}
+
+/*
+ * 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;
+
+ /* sanity check */
+ if (ncores > NR_CPUS) {
+ printk(KERN_WARNING
+ "U8500: no. of cores (%d) greater than configured "
+ "maximum of %d - clipping\n",
+ ncores, NR_CPUS);
+ ncores = NR_CPUS;
+ }
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base_addr());
+ wakeup_secondary();
+}
diff --git a/arch/arm/mach-ux500/ste-dma40-db5500.h b/arch/arm/mach-ux500/ste-dma40-db5500.h
new file mode 100644
index 00000000..cb2110c3
--- /dev/null
+++ b/arch/arm/mach-ux500/ste-dma40-db5500.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ *
+ * DB5500-SoC-specific configuration for DMA40
+ */
+
+#ifndef STE_DMA40_DB5500_H
+#define STE_DMA40_DB5500_H
+
+#define DB5500_DMA_NR_DEV 64
+
+enum dma_src_dev_type {
+ DB5500_DMA_DEV0_SPI0_RX = 0,
+ DB5500_DMA_DEV1_SPI1_RX = 1,
+ DB5500_DMA_DEV2_SPI2_RX = 2,
+ DB5500_DMA_DEV3_SPI3_RX = 3,
+ DB5500_DMA_DEV4_USB_OTG_IEP_1_9 = 4,
+ DB5500_DMA_DEV5_USB_OTG_IEP_2_10 = 5,
+ DB5500_DMA_DEV6_USB_OTG_IEP_3_11 = 6,
+ DB5500_DMA_DEV7_IRDA_RFS = 7,
+ DB5500_DMA_DEV8_IRDA_FIFO_RX = 8,
+ DB5500_DMA_DEV9_MSP0_RX = 9,
+ DB5500_DMA_DEV10_MSP1_RX = 10,
+ DB5500_DMA_DEV11_MSP2_RX = 11,
+ DB5500_DMA_DEV12_UART0_RX = 12,
+ DB5500_DMA_DEV13_UART1_RX = 13,
+ DB5500_DMA_DEV14_UART2_RX = 14,
+ DB5500_DMA_DEV15_UART3_RX = 15,
+ DB5500_DMA_DEV16_USB_OTG_IEP_8 = 16,
+ DB5500_DMA_DEV17_USB_OTG_IEP_1_9 = 17,
+ DB5500_DMA_DEV18_USB_OTG_IEP_2_10 = 18,
+ DB5500_DMA_DEV19_USB_OTG_IEP_3_11 = 19,
+ DB5500_DMA_DEV20_USB_OTG_IEP_4_12 = 20,
+ DB5500_DMA_DEV21_USB_OTG_IEP_5_13 = 21,
+ DB5500_DMA_DEV22_USB_OTG_IEP_6_14 = 22,
+ DB5500_DMA_DEV23_USB_OTG_IEP_7_15 = 23,
+ DB5500_DMA_DEV24_SDMMC0_RX = 24,
+ DB5500_DMA_DEV25_SDMMC1_RX = 25,
+ DB5500_DMA_DEV26_SDMMC2_RX = 26,
+ DB5500_DMA_DEV27_SDMMC3_RX = 27,
+ DB5500_DMA_DEV28_SDMMC4_RX = 28,
+ /* 29 - 32 not used */
+ DB5500_DMA_DEV33_SDMMC0_RX = 33,
+ DB5500_DMA_DEV34_SDMMC1_RX = 34,
+ DB5500_DMA_DEV35_SDMMC2_RX = 35,
+ DB5500_DMA_DEV36_SDMMC3_RX = 36,
+ DB5500_DMA_DEV37_SDMMC4_RX = 37,
+ DB5500_DMA_DEV38_USB_OTG_IEP_8 = 38,
+ DB5500_DMA_DEV39_USB_OTG_IEP_1_9 = 39,
+ DB5500_DMA_DEV40_USB_OTG_IEP_2_10 = 40,
+ DB5500_DMA_DEV41_USB_OTG_IEP_3_11 = 41,
+ DB5500_DMA_DEV42_USB_OTG_IEP_4_12 = 42,
+ DB5500_DMA_DEV43_USB_OTG_IEP_5_13 = 43,
+ DB5500_DMA_DEV44_USB_OTG_IEP_6_14 = 44,
+ DB5500_DMA_DEV45_USB_OTG_IEP_7_15 = 45,
+ /* 46 not used */
+ DB5500_DMA_DEV47_MCDE_RX = 47,
+ DB5500_DMA_DEV48_CRYPTO1_RX = 48,
+ /* 49, 50 not used */
+ DB5500_DMA_DEV49_I2C1_RX = 51,
+ DB5500_DMA_DEV50_I2C3_RX = 52,
+ DB5500_DMA_DEV51_I2C2_RX = 53,
+ /* 54 - 60 not used */
+ DB5500_DMA_DEV61_CRYPTO0_RX = 61,
+ /* 62, 63 not used */
+};
+
+enum dma_dest_dev_type {
+ DB5500_DMA_DEV0_SPI0_TX = 0,
+ DB5500_DMA_DEV1_SPI1_TX = 1,
+ DB5500_DMA_DEV2_SPI2_TX = 2,
+ DB5500_DMA_DEV3_SPI3_TX = 3,
+ DB5500_DMA_DEV4_USB_OTG_OEP_1_9 = 4,
+ DB5500_DMA_DEV5_USB_OTG_OEP_2_10 = 5,
+ DB5500_DMA_DEV6_USB_OTG_OEP_3_11 = 6,
+ DB5500_DMA_DEV7_IRRC_TX = 7,
+ DB5500_DMA_DEV8_IRDA_FIFO_TX = 8,
+ DB5500_DMA_DEV9_MSP0_TX = 9,
+ DB5500_DMA_DEV10_MSP1_TX = 10,
+ DB5500_DMA_DEV11_MSP2_TX = 11,
+ DB5500_DMA_DEV12_UART0_TX = 12,
+ DB5500_DMA_DEV13_UART1_TX = 13,
+ DB5500_DMA_DEV14_UART2_TX = 14,
+ DB5500_DMA_DEV15_UART3_TX = 15,
+ DB5500_DMA_DEV16_USB_OTG_OEP_8 = 16,
+ DB5500_DMA_DEV17_USB_OTG_OEP_1_9 = 17,
+ DB5500_DMA_DEV18_USB_OTG_OEP_2_10 = 18,
+ DB5500_DMA_DEV19_USB_OTG_OEP_3_11 = 19,
+ DB5500_DMA_DEV20_USB_OTG_OEP_4_12 = 20,
+ DB5500_DMA_DEV21_USB_OTG_OEP_5_13 = 21,
+ DB5500_DMA_DEV22_USB_OTG_OEP_6_14 = 22,
+ DB5500_DMA_DEV23_USB_OTG_OEP_7_15 = 23,
+ DB5500_DMA_DEV24_SDMMC0_TX = 24,
+ DB5500_DMA_DEV25_SDMMC1_TX = 25,
+ DB5500_DMA_DEV26_SDMMC2_TX = 26,
+ DB5500_DMA_DEV27_SDMMC3_TX = 27,
+ DB5500_DMA_DEV28_SDMMC4_TX = 28,
+ /* 29 - 31 not used */
+ DB5500_DMA_DEV32_FSMC_TX = 32,
+ DB5500_DMA_DEV33_SDMMC0_TX = 33,
+ DB5500_DMA_DEV34_SDMMC1_TX = 34,
+ DB5500_DMA_DEV35_SDMMC2_TX = 35,
+ DB5500_DMA_DEV36_SDMMC3_TX = 36,
+ DB5500_DMA_DEV37_SDMMC4_TX = 37,
+ DB5500_DMA_DEV38_USB_OTG_OEP_8 = 38,
+ DB5500_DMA_DEV39_USB_OTG_OEP_1_9 = 39,
+ DB5500_DMA_DEV40_USB_OTG_OEP_2_10 = 40,
+ DB5500_DMA_DEV41_USB_OTG_OEP_3_11 = 41,
+ DB5500_DMA_DEV42_USB_OTG_OEP_4_12 = 42,
+ DB5500_DMA_DEV43_USB_OTG_OEP_5_13 = 43,
+ DB5500_DMA_DEV44_USB_OTG_OEP_6_14 = 44,
+ DB5500_DMA_DEV45_USB_OTG_OEP_7_15 = 45,
+ /* 46 not used */
+ DB5500_DMA_DEV47_STM_TX = 47,
+ DB5500_DMA_DEV48_CRYPTO1_TX = 48,
+ DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX = 49,
+ DB5500_DMA_DEV50_HASH1_TX = 50,
+ DB5500_DMA_DEV51_I2C1_TX = 51,
+ DB5500_DMA_DEV52_I2C3_TX = 52,
+ DB5500_DMA_DEV53_I2C2_TX = 53,
+ /* 54, 55 not used */
+ DB5500_DMA_MEMCPY_TX_1 = 56,
+ DB5500_DMA_MEMCPY_TX_2 = 57,
+ DB5500_DMA_MEMCPY_TX_3 = 58,
+ DB5500_DMA_MEMCPY_TX_4 = 59,
+ DB5500_DMA_MEMCPY_TX_5 = 60,
+ DB5500_DMA_DEV61_CRYPTO0_TX = 61,
+ DB5500_DMA_DEV62_CRYPTO0_TX_HASH0_TX = 62,
+ DB5500_DMA_DEV63_HASH0_TX = 63,
+};
+
+#endif
diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h
new file mode 100644
index 00000000..a616419b
--- /dev/null
+++ b/arch/arm/mach-ux500/ste-dma40-db8500.h
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/mach-ux500/ste_dma40_db8500.h
+ * DB8500-SoC-specific configuration for DMA40
+ *
+ * Copyright (C) ST-Ericsson 2007-2010
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Per Friden <per.friden@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ */
+#ifndef STE_DMA40_DB8500_H
+#define STE_DMA40_DB8500_H
+
+#define DB8500_DMA_NR_DEV 64
+
+enum dma_src_dev_type {
+ DB8500_DMA_DEV0_SPI0_RX = 0,
+ DB8500_DMA_DEV1_SD_MMC0_RX = 1,
+ DB8500_DMA_DEV2_SD_MMC1_RX = 2,
+ DB8500_DMA_DEV3_SD_MMC2_RX = 3,
+ DB8500_DMA_DEV4_I2C1_RX = 4,
+ DB8500_DMA_DEV5_I2C3_RX = 5,
+ DB8500_DMA_DEV6_I2C2_RX = 6,
+ DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0_RX = 8,
+ DB8500_DMA_DEV9_SSP1_RX = 9,
+ DB8500_DMA_DEV10_MCDE_RX = 10,
+ DB8500_DMA_DEV11_UART2_RX = 11,
+ DB8500_DMA_DEV12_UART1_RX = 12,
+ DB8500_DMA_DEV13_UART0_RX = 13,
+ DB8500_DMA_DEV14_MSP2_RX = 14,
+ DB8500_DMA_DEV15_I2C0_RX = 15,
+ DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23,
+ DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24,
+ DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25,
+ DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26,
+ DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27,
+ DB8500_DMA_DEV28_SD_MM2_RX = 28,
+ DB8500_DMA_DEV29_SD_MM0_RX = 29,
+ DB8500_DMA_DEV30_MSP1_RX = 30,
+ /* On DB8500v2, MSP3 RX replaces MSP1 RX */
+ DB8500_DMA_DEV30_MSP3_RX = 30,
+ DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31,
+ DB8500_DMA_DEV32_SD_MM1_RX = 32,
+ DB8500_DMA_DEV33_SPI2_RX = 33,
+ DB8500_DMA_DEV34_I2C3_RX2 = 34,
+ DB8500_DMA_DEV35_SPI1_RX = 35,
+ DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3_RX = 40,
+ DB8500_DMA_DEV41_SD_MM3_RX = 41,
+ DB8500_DMA_DEV42_SD_MM4_RX = 42,
+ DB8500_DMA_DEV43_SD_MM5_RX = 43,
+ DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44,
+ DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47,
+ DB8500_DMA_DEV48_CAC1_RX = 48,
+ /* 49, 50 and 51 are not used */
+ DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55,
+ /* 56, 57, 58, 59 and 60 are not used */
+ DB8500_DMA_DEV61_CAC0_RX = 61,
+ /* 62 and 63 are not used */
+};
+
+enum dma_dest_dev_type {
+ DB8500_DMA_DEV0_SPI0_TX = 0,
+ DB8500_DMA_DEV1_SD_MMC0_TX = 1,
+ DB8500_DMA_DEV2_SD_MMC1_TX = 2,
+ DB8500_DMA_DEV3_SD_MMC2_TX = 3,
+ DB8500_DMA_DEV4_I2C1_TX = 4,
+ DB8500_DMA_DEV5_I2C3_TX = 5,
+ DB8500_DMA_DEV6_I2C2_TX = 6,
+ DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */
+ DB8500_DMA_DEV8_SSP0_TX = 8,
+ DB8500_DMA_DEV9_SSP1_TX = 9,
+ /* 10 is not used*/
+ DB8500_DMA_DEV11_UART2_TX = 11,
+ DB8500_DMA_DEV12_UART1_TX = 12,
+ DB8500_DMA_DEV13_UART0_TX = 13,
+ DB8500_DMA_DEV14_MSP2_TX = 14,
+ DB8500_DMA_DEV15_I2C0_TX = 15,
+ DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16,
+ DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17,
+ DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18,
+ DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19,
+ DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20,
+ DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21,
+ DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22,
+ DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23,
+ DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24,
+ DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25,
+ DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26,
+ DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27,
+ DB8500_DMA_DEV28_SD_MM2_TX = 28,
+ DB8500_DMA_DEV29_SD_MM0_TX = 29,
+ DB8500_DMA_DEV30_MSP1_TX = 30,
+ DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31,
+ DB8500_DMA_DEV32_SD_MM1_TX = 32,
+ DB8500_DMA_DEV33_SPI2_TX = 33,
+ DB8500_DMA_DEV34_I2C3_TX2 = 34,
+ DB8500_DMA_DEV35_SPI1_TX = 35,
+ DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36,
+ DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37,
+ DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38,
+ DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39,
+ DB8500_DMA_DEV40_SPI3_TX = 40,
+ DB8500_DMA_DEV41_SD_MM3_TX = 41,
+ DB8500_DMA_DEV42_SD_MM4_TX = 42,
+ DB8500_DMA_DEV43_SD_MM5_TX = 43,
+ DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44,
+ DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45,
+ DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46,
+ DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47,
+ DB8500_DMA_DEV48_CAC1_TX = 48,
+ DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49,
+ DB8500_DMA_DEV50_HAC1_TX = 50,
+ DB8500_DMA_MEMCPY_TX_0 = 51,
+ DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52,
+ DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53,
+ DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54,
+ DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55,
+ DB8500_DMA_MEMCPY_TX_1 = 56,
+ DB8500_DMA_MEMCPY_TX_2 = 57,
+ DB8500_DMA_MEMCPY_TX_3 = 58,
+ DB8500_DMA_MEMCPY_TX_4 = 59,
+ DB8500_DMA_MEMCPY_TX_5 = 60,
+ DB8500_DMA_DEV61_CAC0_TX = 61,
+ DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62,
+ DB8500_DMA_DEV63_HAC0_TX = 63,
+};
+
+#endif
diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c
new file mode 100644
index 00000000..82e53595
--- /dev/null
+++ b/arch/arm/mach-ux500/usb.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/platform_device.h>
+#include <linux/usb/musb.h>
+#include <plat/ste_dma40.h>
+#include <mach/hardware.h>
+#include <mach/usb.h>
+
+#define MUSB_DMA40_RX_CH { \
+ .mode = STEDMA40_MODE_LOGICAL, \
+ .dir = STEDMA40_PERIPH_TO_MEM, \
+ .dst_dev_type = STEDMA40_DEV_DST_MEMORY, \
+ .src_info.data_width = STEDMA40_WORD_WIDTH, \
+ .dst_info.data_width = STEDMA40_WORD_WIDTH, \
+ .src_info.psize = STEDMA40_PSIZE_LOG_16, \
+ .dst_info.psize = STEDMA40_PSIZE_LOG_16, \
+ }
+
+#define MUSB_DMA40_TX_CH { \
+ .mode = STEDMA40_MODE_LOGICAL, \
+ .dir = STEDMA40_MEM_TO_PERIPH, \
+ .src_dev_type = STEDMA40_DEV_SRC_MEMORY, \
+ .src_info.data_width = STEDMA40_WORD_WIDTH, \
+ .dst_info.data_width = STEDMA40_WORD_WIDTH, \
+ .src_info.psize = STEDMA40_PSIZE_LOG_16, \
+ .dst_info.psize = STEDMA40_PSIZE_LOG_16, \
+ }
+
+static struct stedma40_chan_cfg musb_dma_rx_ch[UX500_MUSB_DMA_NUM_RX_CHANNELS]
+ = {
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH,
+ MUSB_DMA40_RX_CH
+};
+
+static struct stedma40_chan_cfg musb_dma_tx_ch[UX500_MUSB_DMA_NUM_TX_CHANNELS]
+ = {
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+ MUSB_DMA40_TX_CH,
+};
+
+static void *ux500_dma_rx_param_array[UX500_MUSB_DMA_NUM_RX_CHANNELS] = {
+ &musb_dma_rx_ch[0],
+ &musb_dma_rx_ch[1],
+ &musb_dma_rx_ch[2],
+ &musb_dma_rx_ch[3],
+ &musb_dma_rx_ch[4],
+ &musb_dma_rx_ch[5],
+ &musb_dma_rx_ch[6],
+ &musb_dma_rx_ch[7]
+};
+
+static void *ux500_dma_tx_param_array[UX500_MUSB_DMA_NUM_TX_CHANNELS] = {
+ &musb_dma_tx_ch[0],
+ &musb_dma_tx_ch[1],
+ &musb_dma_tx_ch[2],
+ &musb_dma_tx_ch[3],
+ &musb_dma_tx_ch[4],
+ &musb_dma_tx_ch[5],
+ &musb_dma_tx_ch[6],
+ &musb_dma_tx_ch[7]
+};
+
+static struct ux500_musb_board_data musb_board_data = {
+ .dma_rx_param_array = ux500_dma_rx_param_array,
+ .dma_tx_param_array = ux500_dma_tx_param_array,
+ .num_rx_channels = UX500_MUSB_DMA_NUM_RX_CHANNELS,
+ .num_tx_channels = UX500_MUSB_DMA_NUM_TX_CHANNELS,
+ .dma_filter = stedma40_filter,
+};
+
+static u64 ux500_musb_dmamask = DMA_BIT_MASK(32);
+
+static struct musb_hdrc_config musb_hdrc_config = {
+ .multipoint = true,
+ .dyn_fifo = true,
+ .num_eps = 16,
+ .ram_bits = 16,
+};
+
+static struct musb_hdrc_platform_data musb_platform_data = {
+#if defined(CONFIG_USB_MUSB_OTG)
+ .mode = MUSB_OTG,
+#elif defined(CONFIG_USB_MUSB_PERIPHERAL)
+ .mode = MUSB_PERIPHERAL,
+#else /* defined(CONFIG_USB_MUSB_HOST) */
+ .mode = MUSB_HOST,
+#endif
+ .config = &musb_hdrc_config,
+ .board_data = &musb_board_data,
+};
+
+static struct resource usb_resources[] = {
+ [0] = {
+ .name = "usb-mem",
+ .flags = IORESOURCE_MEM,
+ },
+
+ [1] = {
+ .name = "mc", /* hard-coded in musb */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device ux500_musb_device = {
+ .name = "musb-ux500",
+ .id = 0,
+ .dev = {
+ .platform_data = &musb_platform_data,
+ .dma_mask = &ux500_musb_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(usb_resources),
+ .resource = usb_resources,
+};
+
+static inline void ux500_usb_dma_update_rx_ch_config(int *src_dev_type)
+{
+ u32 idx;
+
+ for (idx = 0; idx < UX500_MUSB_DMA_NUM_RX_CHANNELS; idx++)
+ musb_dma_rx_ch[idx].src_dev_type = src_dev_type[idx];
+}
+
+static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type)
+{
+ u32 idx;
+
+ for (idx = 0; idx < UX500_MUSB_DMA_NUM_TX_CHANNELS; idx++)
+ musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx];
+}
+
+void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg,
+ int *dma_tx_cfg)
+{
+ ux500_musb_device.resource[0].start = base;
+ ux500_musb_device.resource[0].end = base + SZ_64K - 1;
+ ux500_musb_device.resource[1].start = irq;
+ ux500_musb_device.resource[1].end = irq;
+
+ ux500_usb_dma_update_rx_ch_config(dma_rx_cfg);
+ ux500_usb_dma_update_tx_ch_config(dma_tx_cfg);
+
+ platform_device_register(&ux500_musb_device);
+}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 00000000..9cdec5aa
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,20 @@
+menu "Versatile platform type"
+ depends on ARCH_VERSATILE
+
+config ARCH_VERSATILE_PB
+ bool "Support Versatile Platform Baseboard for ARM926EJ-S"
+ select CPU_ARM926T
+ select MIGHT_HAVE_PCI
+ default y
+ help
+ Include support for the ARM(R) Versatile Platform Baseboard
+ for the ARM926EJ-S.
+
+config MACH_VERSATILE_AB
+ bool "Support Versatile Application Baseboard for ARM926EJ-S"
+ select CPU_ARM926T
+ help
+ Include support for the ARM(R) Versatile Application Baseboard
+ for the ARM926EJ-S.
+
+endmenu
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 00000000..97cf4d83
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := core.o
+obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
+obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
new file mode 100644
index 00000000..c7e75acf
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile.boot
@@ -0,0 +1,4 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x00800000
+
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 00000000..0c99cf07
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,758 @@
+/*
+ * linux/arch/arm/mach-versatile/core.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/amba/pl022.h>
+#include <linux/io.h>
+#include <linux/gfp.h>
+#include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/leds.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/icst.h>
+#include <asm/hardware/vic.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/hardware/timer-sp.h>
+
+#include <plat/clcd.h>
+#include <plat/fpga-irq.h>
+#include <plat/sched_clock.h>
+
+#include "core.h"
+
+/*
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Versatile Vectored Interrupt Controller.
+ */
+#define VA_VIC_BASE __io_address(VERSATILE_VIC_BASE)
+#define VA_SIC_BASE __io_address(VERSATILE_SIC_BASE)
+
+static struct fpga_irq_data sic_irq = {
+ .base = VA_SIC_BASE,
+ .irq_start = IRQ_SIC_START,
+ .chip.name = "SIC",
+};
+
+#if 1
+#define IRQ_MMCI0A IRQ_VICSOURCE22
+#define IRQ_AACI IRQ_VICSOURCE24
+#define IRQ_ETH IRQ_VICSOURCE25
+#define PIC_MASK 0xFFD00000
+#else
+#define IRQ_MMCI0A IRQ_SIC_MMCI0A
+#define IRQ_AACI IRQ_SIC_AACI
+#define IRQ_ETH IRQ_SIC_ETH
+#define PIC_MASK 0
+#endif
+
+void __init versatile_init_irq(void)
+{
+ vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
+
+ writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
+
+ fpga_irq_init(IRQ_VICSOURCE31, ~PIC_MASK, &sic_irq);
+
+ /*
+ * Interrupts on secondary controller from 0 to 8 are routed to
+ * source 31 on PIC.
+ * Interrupts from 21 to 31 are routed directly to the VIC on
+ * the corresponding number on primary controller. This is controlled
+ * by setting PIC_ENABLEx.
+ */
+ writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);
+}
+
+static struct map_desc versatile_io_desc[] __initdata = {
+ {
+ .virtual = IO_ADDRESS(VERSATILE_SYS_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SYS_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_VIC_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_VIC_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_SCTL_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_SCTL_BASE),
+ .length = SZ_4K * 9,
+ .type = MT_DEVICE
+ },
+#ifdef CONFIG_MACH_VERSATILE_AB
+ {
+ .virtual = IO_ADDRESS(VERSATILE_GPIO0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_GPIO0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = IO_ADDRESS(VERSATILE_IB2_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_IB2_BASE),
+ .length = SZ_64M,
+ .type = MT_DEVICE
+ },
+#endif
+#ifdef CONFIG_DEBUG_LL
+ {
+ .virtual = IO_ADDRESS(VERSATILE_UART0_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_UART0_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ },
+#endif
+#ifdef CONFIG_PCI
+ {
+ .virtual = IO_ADDRESS(VERSATILE_PCI_CORE_BASE),
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CORE_BASE),
+ .length = SZ_4K,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VERSATILE_PCI_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_BASE),
+ .length = VERSATILE_PCI_BASE_SIZE,
+ .type = MT_DEVICE
+ }, {
+ .virtual = (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_CFG_BASE),
+ .length = VERSATILE_PCI_CFG_BASE_SIZE,
+ .type = MT_DEVICE
+ },
+#if 0
+ {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE0,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE1,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ }, {
+ .virtual = VERSATILE_PCI_VIRT_MEM_BASE2,
+ .pfn = __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),
+ .length = SZ_16M,
+ .type = MT_DEVICE
+ },
+#endif
+#endif
+};
+
+void __init versatile_map_io(void)
+{
+ iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
+}
+
+
+#define VERSATILE_FLASHCTRL (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
+
+static void versatile_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ u32 val;
+
+ val = __raw_readl(VERSATILE_FLASHCTRL);
+ if (on)
+ val |= VERSATILE_FLASHPROG_FLVPPEN;
+ else
+ val &= ~VERSATILE_FLASHPROG_FLVPPEN;
+ __raw_writel(val, VERSATILE_FLASHCTRL);
+}
+
+static struct physmap_flash_data versatile_flash_data = {
+ .width = 4,
+ .set_vpp = versatile_flash_set_vpp,
+};
+
+static struct resource versatile_flash_resource = {
+ .start = VERSATILE_FLASH_BASE,
+ .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device versatile_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &versatile_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &versatile_flash_resource,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .start = VERSATILE_ETH_BASE,
+ .end = VERSATILE_ETH_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ETH,
+ .end = IRQ_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource versatile_i2c_resource = {
+ .start = VERSATILE_I2C_BASE,
+ .end = VERSATILE_I2C_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device versatile_i2c_device = {
+ .name = "versatile-i2c",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &versatile_i2c_resource,
+};
+
+static struct i2c_board_info versatile_i2c_board_info[] = {
+ {
+ I2C_BOARD_INFO("ds1338", 0xd0 >> 1),
+ },
+};
+
+static int __init versatile_i2c_init(void)
+{
+ return i2c_register_board_info(0, versatile_i2c_board_info,
+ ARRAY_SIZE(versatile_i2c_board_info));
+}
+arch_initcall(versatile_i2c_init);
+
+#define VERSATILE_SYSMCI (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)
+
+unsigned int mmc_status(struct device *dev)
+{
+ struct amba_device *adev = container_of(dev, struct amba_device, dev);
+ u32 mask;
+
+ if (adev->res.start == VERSATILE_MMCI0_BASE)
+ mask = 1;
+ else
+ mask = 2;
+
+ return readl(VERSATILE_SYSMCI) & mask;
+}
+
+static struct mmci_platform_data mmc0_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = mmc_status,
+ .gpio_wp = -1,
+ .gpio_cd = -1,
+};
+
+static struct resource char_lcd_resources[] = {
+ {
+ .start = VERSATILE_CHAR_LCD_BASE,
+ .end = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device char_lcd_device = {
+ .name = "arm-charlcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(char_lcd_resources),
+ .resource = char_lcd_resources,
+};
+
+/*
+ * Clock handling
+ */
+static const struct icst_params versatile_oscvco_params = {
+ .ref = 24000000,
+ .vco_max = ICST307_VCO_MAX,
+ .vco_min = ICST307_VCO_MIN,
+ .vd_min = 4 + 8,
+ .vd_max = 511 + 8,
+ .rd_min = 1 + 2,
+ .rd_max = 127 + 2,
+ .s2div = icst307_s2div,
+ .idx2s = icst307_idx2s,
+};
+
+static void versatile_oscvco_set(struct clk *clk, struct icst_vco vco)
+{
+ void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;
+ u32 val;
+
+ val = readl(clk->vcoreg) & ~0x7ffff;
+ val |= vco.v | (vco.r << 9) | (vco.s << 16);
+
+ writel(0xa05f, sys_lock);
+ writel(val, clk->vcoreg);
+ writel(0, sys_lock);
+}
+
+static const struct clk_ops osc4_clk_ops = {
+ .round = icst_clk_round,
+ .set = icst_clk_set,
+ .setvco = versatile_oscvco_set,
+};
+
+static struct clk osc4_clk = {
+ .ops = &osc4_clk_ops,
+ .params = &versatile_oscvco_params,
+};
+
+/*
+ * These are fixed clocks.
+ */
+static struct clk ref24_clk = {
+ .rate = 24000000,
+};
+
+static struct clk sp804_clk = {
+ .rate = 1000000,
+};
+
+static struct clk dummy_apb_pclk;
+
+static struct clk_lookup lookups[] = {
+ { /* AMBA bus clock */
+ .con_id = "apb_pclk",
+ .clk = &dummy_apb_pclk,
+ }, { /* UART0 */
+ .dev_id = "dev:f1",
+ .clk = &ref24_clk,
+ }, { /* UART1 */
+ .dev_id = "dev:f2",
+ .clk = &ref24_clk,
+ }, { /* UART2 */
+ .dev_id = "dev:f3",
+ .clk = &ref24_clk,
+ }, { /* UART3 */
+ .dev_id = "fpga:09",
+ .clk = &ref24_clk,
+ }, { /* KMI0 */
+ .dev_id = "fpga:06",
+ .clk = &ref24_clk,
+ }, { /* KMI1 */
+ .dev_id = "fpga:07",
+ .clk = &ref24_clk,
+ }, { /* MMC0 */
+ .dev_id = "fpga:05",
+ .clk = &ref24_clk,
+ }, { /* MMC1 */
+ .dev_id = "fpga:0b",
+ .clk = &ref24_clk,
+ }, { /* SSP */
+ .dev_id = "dev:f4",
+ .clk = &ref24_clk,
+ }, { /* CLCD */
+ .dev_id = "dev:20",
+ .clk = &osc4_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .clk = &sp804_clk,
+ },
+};
+
+/*
+ * CLCD support.
+ */
+#define SYS_CLCD_MODE_MASK (3 << 0)
+#define SYS_CLCD_MODE_888 (0 << 0)
+#define SYS_CLCD_MODE_5551 (1 << 0)
+#define SYS_CLCD_MODE_565_RLSB (2 << 0)
+#define SYS_CLCD_MODE_565_BLSB (3 << 0)
+#define SYS_CLCD_NLCDIOON (1 << 2)
+#define SYS_CLCD_VDDPOSSWITCH (1 << 3)
+#define SYS_CLCD_PWR3V5SWITCH (1 << 4)
+#define SYS_CLCD_ID_MASK (0x1f << 8)
+#define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8)
+#define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8)
+#define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8)
+#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8)
+#define SYS_CLCD_ID_VGA (0x1f << 8)
+
+static bool is_sanyo_2_5_lcd;
+
+/*
+ * Disable all display connectors on the interface module.
+ */
+static void versatile_clcd_disable(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+ /*
+ * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off
+ */
+ if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
+ void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
+ unsigned long ctrl;
+
+ ctrl = readl(versatile_ib2_ctrl);
+ ctrl &= ~0x01;
+ writel(ctrl, versatile_ib2_ctrl);
+ }
+#endif
+}
+
+/*
+ * Enable the relevant connector on the interface module.
+ */
+static void versatile_clcd_enable(struct clcd_fb *fb)
+{
+ struct fb_var_screeninfo *var = &fb->fb.var;
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ u32 val;
+
+ val = readl(sys_clcd);
+ val &= ~SYS_CLCD_MODE_MASK;
+
+ switch (var->green.length) {
+ case 5:
+ val |= SYS_CLCD_MODE_5551;
+ break;
+ case 6:
+ if (var->red.offset == 0)
+ val |= SYS_CLCD_MODE_565_RLSB;
+ else
+ val |= SYS_CLCD_MODE_565_BLSB;
+ break;
+ case 8:
+ val |= SYS_CLCD_MODE_888;
+ break;
+ }
+
+ /*
+ * Set the MUX
+ */
+ writel(val, sys_clcd);
+
+ /*
+ * And now enable the PSUs
+ */
+ val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;
+ writel(val, sys_clcd);
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+ /*
+ * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on
+ */
+ if (machine_is_versatile_ab() && is_sanyo_2_5_lcd) {
+ void __iomem *versatile_ib2_ctrl = __io_address(VERSATILE_IB2_CTRL);
+ unsigned long ctrl;
+
+ ctrl = readl(versatile_ib2_ctrl);
+ ctrl |= 0x01;
+ writel(ctrl, versatile_ib2_ctrl);
+ }
+#endif
+}
+
+/*
+ * Detect which LCD panel is connected, and return the appropriate
+ * clcd_panel structure. Note: we do not have any information on
+ * the required timings for the 8.4in panel, so we presently assume
+ * VGA timings.
+ */
+static int versatile_clcd_setup(struct clcd_fb *fb)
+{
+ void __iomem *sys_clcd = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;
+ const char *panel_name;
+ u32 val;
+
+ is_sanyo_2_5_lcd = false;
+
+ val = readl(sys_clcd) & SYS_CLCD_ID_MASK;
+ if (val == SYS_CLCD_ID_SANYO_3_8)
+ panel_name = "Sanyo TM38QV67A02A";
+ else if (val == SYS_CLCD_ID_SANYO_2_5) {
+ panel_name = "Sanyo QVGA Portrait";
+ is_sanyo_2_5_lcd = true;
+ } else if (val == SYS_CLCD_ID_EPSON_2_2)
+ panel_name = "Epson L2F50113T00";
+ else if (val == SYS_CLCD_ID_VGA)
+ panel_name = "VGA";
+ else {
+ printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n",
+ val);
+ panel_name = "VGA";
+ }
+
+ fb->panel = versatile_clcd_get_panel(panel_name);
+ if (!fb->panel)
+ return -EINVAL;
+
+ return versatile_clcd_setup_dma(fb, SZ_1M);
+}
+
+static void versatile_clcd_decode(struct clcd_fb *fb, struct clcd_regs *regs)
+{
+ clcdfb_decode(fb, regs);
+
+ /* Always clear BGR for RGB565: we do the routing externally */
+ if (fb->fb.var.green.length == 6)
+ regs->cntl &= ~CNTL_BGR;
+}
+
+static struct clcd_board clcd_plat_data = {
+ .name = "Versatile",
+ .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+ .check = clcdfb_check,
+ .decode = versatile_clcd_decode,
+ .disable = versatile_clcd_disable,
+ .enable = versatile_clcd_enable,
+ .setup = versatile_clcd_setup,
+ .mmap = versatile_clcd_mmap_dma,
+ .remove = versatile_clcd_remove_dma,
+};
+
+static struct pl061_platform_data gpio0_plat_data = {
+ .gpio_base = 0,
+ .irq_base = IRQ_GPIO0_START,
+};
+
+static struct pl061_platform_data gpio1_plat_data = {
+ .gpio_base = 8,
+ .irq_base = IRQ_GPIO1_START,
+};
+
+static struct pl022_ssp_controller ssp0_plat_data = {
+ .bus_id = 0,
+ .enable_dma = 0,
+ .num_chipselect = 1,
+};
+
+#define AACI_IRQ { IRQ_AACI, NO_IRQ }
+#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
+#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ }
+#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ }
+
+/*
+ * These devices are connected directly to the multi-layer AHB switch
+ */
+#define SMC_IRQ { NO_IRQ, NO_IRQ }
+#define MPMC_IRQ { NO_IRQ, NO_IRQ }
+#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
+#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define SCTL_IRQ { NO_IRQ, NO_IRQ }
+#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
+#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
+#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
+#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
+#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
+#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
+#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
+#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
+
+/* FPGA Primecells */
+AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
+AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data);
+AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL);
+AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL);
+
+/* DevChip Primecells */
+AMBA_DEVICE(smc, "dev:00", SMC, NULL);
+AMBA_DEVICE(mpmc, "dev:10", MPMC, NULL);
+AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
+AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
+AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
+AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
+AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data);
+AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
+AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
+AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
+AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
+AMBA_DEVICE(uart1, "dev:f2", UART1, NULL);
+AMBA_DEVICE(uart2, "dev:f3", UART2, NULL);
+AMBA_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &dmac_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &smc_device,
+ &mpmc_device,
+ &clcd_device,
+ &sctl_device,
+ &wdog_device,
+ &gpio0_device,
+ &gpio1_device,
+ &rtc_device,
+ &sci0_device,
+ &ssp0_device,
+ &aaci_device,
+ &mmc0_device,
+ &kmi0_device,
+ &kmi1_device,
+};
+
+#ifdef CONFIG_LEDS
+#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+
+static void versatile_leds_event(led_event_t ledevt)
+{
+ unsigned long flags;
+ u32 val;
+
+ local_irq_save(flags);
+ val = readl(VA_LEDS_BASE);
+
+ switch (ledevt) {
+ case led_idle_start:
+ val = val & ~VERSATILE_SYS_LED0;
+ break;
+
+ case led_idle_end:
+ val = val | VERSATILE_SYS_LED0;
+ break;
+
+ case led_timer:
+ val = val ^ VERSATILE_SYS_LED1;
+ break;
+
+ case led_halted:
+ val = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ writel(val, VA_LEDS_BASE);
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_LEDS */
+
+/* Early initializations */
+void __init versatile_init_early(void)
+{
+ void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
+
+ osc4_clk.vcoreg = sys + VERSATILE_SYS_OSCCLCD_OFFSET;
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
+}
+
+void __init versatile_init(void)
+{
+ int i;
+
+ platform_device_register(&versatile_flash_device);
+ platform_device_register(&versatile_i2c_device);
+ platform_device_register(&smc91x_device);
+ platform_device_register(&char_lcd_device);
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+
+#ifdef CONFIG_LEDS
+ leds_event = versatile_leds_event;
+#endif
+}
+
+/*
+ * Where is the timer (VA)?
+ */
+#define TIMER0_VA_BASE __io_address(VERSATILE_TIMER0_1_BASE)
+#define TIMER1_VA_BASE (__io_address(VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_VA_BASE __io_address(VERSATILE_TIMER2_3_BASE)
+#define TIMER3_VA_BASE (__io_address(VERSATILE_TIMER2_3_BASE) + 0x20)
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static void __init versatile_timer_init(void)
+{
+ u32 val;
+
+ /*
+ * set clock frequency:
+ * VERSATILE_REFCLK is 32KHz
+ * VERSATILE_TIMCLK is 1MHz
+ */
+ val = readl(__io_address(VERSATILE_SCTL_BASE));
+ writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+ (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+ __io_address(VERSATILE_SCTL_BASE));
+
+ /*
+ * Initialise to a known state (all timers off)
+ */
+ writel(0, TIMER0_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER1_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER2_VA_BASE + TIMER_CTRL);
+ writel(0, TIMER3_VA_BASE + TIMER_CTRL);
+
+ sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
+ sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
+}
+
+struct sys_timer versatile_timer = {
+ .init = versatile_timer_init,
+};
+
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
new file mode 100644
index 00000000..fd6404e5
--- /dev/null
+++ b/arch/arm/mach-versatile/core.h
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/arm/mach-versatile/core.h
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_VERSATILE_H
+#define __ASM_ARCH_VERSATILE_H
+
+#include <linux/amba/bus.h>
+
+extern void __init versatile_init(void);
+extern void __init versatile_init_early(void);
+extern void __init versatile_init_irq(void);
+extern void __init versatile_map_io(void);
+extern struct sys_timer versatile_timer;
+extern unsigned int mmc_status(struct device *dev);
+
+#define AMBA_DEVICE(name,busid,base,plat) \
+static struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0, \
+ .init_name = busid, \
+ .platform_data = plat, \
+ }, \
+ .res = { \
+ .start = VERSATILE_##base##_BASE, \
+ .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .dma_mask = ~0, \
+ .irq = base##_IRQ, \
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 00000000..e58d0771
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <plat/clock.h>
+
+struct clk {
+ unsigned long rate;
+ const struct clk_ops *ops;
+ const struct icst_params *params;
+ void __iomem *vcoreg;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug-macro.S b/arch/arm/mach-versatile/include/mach/debug-macro.S
new file mode 100644
index 00000000..eb2cf7dc
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/* arch/arm/mach-versatile/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x001F0000
+ orr \rp, \rp, #0x00001000
+ orr \rv, \rp, #0xf1000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-versatile/include/mach/entry-macro.S b/arch/arm/mach-versatile/include/mach/entry-macro.S
new file mode 100644
index 00000000..e6f7c166
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/entry-macro.S
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/mach-versatile/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Versatile platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <mach/hardware.h>
+#include <mach/platform.h>
+#include <asm/hardware/vic.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =IO_ADDRESS(VERSATILE_VIC_BASE)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #VIC_IRQ_STATUS] @ get masked status
+ mov \irqnr, #0
+ teq \irqstat, #0
+ beq 1003f
+
+1001: tst \irqstat, #15
+ bne 1002f
+ add \irqnr, \irqnr, #4
+ movs \irqstat, \irqstat, lsr #4
+ bne 1001b
+1002: tst \irqstat, #1
+ bne 1003f
+ add \irqnr, \irqnr, #1
+ movs \irqstat, \irqstat, lsr #1
+ bne 1002b
+1003: /* EQ will be set if no irqs pending */
+
+@ clz \irqnr, \irqstat
+@1003: /* EQ will be set if we reach MAXIRQNUM */
+ .endm
+
diff --git a/arch/arm/mach-versatile/include/mach/gpio.h b/arch/arm/mach-versatile/include/mach/gpio.h
new file mode 100644
index 00000000..94ff2767
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#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
diff --git a/arch/arm/mach-versatile/include/mach/hardware.h b/arch/arm/mach-versatile/include/mach/hardware.h
new file mode 100644
index 00000000..6911e1f5
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/hardware.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-versatile/include/mach/hardware.h
+ *
+ * This file contains the hardware definitions of the Versatile boards.
+ *
+ * Copyright (C) 2003 ARM Limited.
+ *
+ * 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 __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+
+/*
+ * PCI space virtual addresses
+ */
+#define VERSATILE_PCI_VIRT_BASE (void __iomem *)0xe8000000ul
+#define VERSATILE_PCI_CFG_VIRT_BASE (void __iomem *)0xe9000000ul
+
+/* CIK guesswork */
+#define PCIBIOS_MIN_IO 0x44000000
+#define PCIBIOS_MIN_MEM 0x50000000
+
+#define pcibios_assign_all_busses() 1
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+
+#define __io_address(n) ((void __iomem __force *)IO_ADDRESS(n))
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/io.h b/arch/arm/mach-versatile/include/mach/io.h
new file mode 100644
index 00000000..f067c14c
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-versatile/include/mach/io.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h
new file mode 100644
index 00000000..bf44c61b
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/irqs.h
@@ -0,0 +1,134 @@
+/*
+ * arch/arm/mach-versatile/include/mach/irqs.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/platform.h>
+
+/*
+ * IRQ interrupts definitions are the same as the INT definitions
+ * held within platform.h
+ */
+#define IRQ_VIC_START 0
+#define IRQ_WDOGINT (IRQ_VIC_START + INT_WDOGINT)
+#define IRQ_SOFTINT (IRQ_VIC_START + INT_SOFTINT)
+#define IRQ_COMMRx (IRQ_VIC_START + INT_COMMRx)
+#define IRQ_COMMTx (IRQ_VIC_START + INT_COMMTx)
+#define IRQ_TIMERINT0_1 (IRQ_VIC_START + INT_TIMERINT0_1)
+#define IRQ_TIMERINT2_3 (IRQ_VIC_START + INT_TIMERINT2_3)
+#define IRQ_GPIOINT0 (IRQ_VIC_START + INT_GPIOINT0)
+#define IRQ_GPIOINT1 (IRQ_VIC_START + INT_GPIOINT1)
+#define IRQ_GPIOINT2 (IRQ_VIC_START + INT_GPIOINT2)
+#define IRQ_GPIOINT3 (IRQ_VIC_START + INT_GPIOINT3)
+#define IRQ_RTCINT (IRQ_VIC_START + INT_RTCINT)
+#define IRQ_SSPINT (IRQ_VIC_START + INT_SSPINT)
+#define IRQ_UARTINT0 (IRQ_VIC_START + INT_UARTINT0)
+#define IRQ_UARTINT1 (IRQ_VIC_START + INT_UARTINT1)
+#define IRQ_UARTINT2 (IRQ_VIC_START + INT_UARTINT2)
+#define IRQ_SCIINT (IRQ_VIC_START + INT_SCIINT)
+#define IRQ_CLCDINT (IRQ_VIC_START + INT_CLCDINT)
+#define IRQ_DMAINT (IRQ_VIC_START + INT_DMAINT)
+#define IRQ_PWRFAILINT (IRQ_VIC_START + INT_PWRFAILINT)
+#define IRQ_MBXINT (IRQ_VIC_START + INT_MBXINT)
+#define IRQ_GNDINT (IRQ_VIC_START + INT_GNDINT)
+#define IRQ_VICSOURCE21 (IRQ_VIC_START + INT_VICSOURCE21)
+#define IRQ_VICSOURCE22 (IRQ_VIC_START + INT_VICSOURCE22)
+#define IRQ_VICSOURCE23 (IRQ_VIC_START + INT_VICSOURCE23)
+#define IRQ_VICSOURCE24 (IRQ_VIC_START + INT_VICSOURCE24)
+#define IRQ_VICSOURCE25 (IRQ_VIC_START + INT_VICSOURCE25)
+#define IRQ_VICSOURCE26 (IRQ_VIC_START + INT_VICSOURCE26)
+#define IRQ_VICSOURCE27 (IRQ_VIC_START + INT_VICSOURCE27)
+#define IRQ_VICSOURCE28 (IRQ_VIC_START + INT_VICSOURCE28)
+#define IRQ_VICSOURCE29 (IRQ_VIC_START + INT_VICSOURCE29)
+#define IRQ_VICSOURCE30 (IRQ_VIC_START + INT_VICSOURCE30)
+#define IRQ_VICSOURCE31 (IRQ_VIC_START + INT_VICSOURCE31)
+#define IRQ_VIC_END (IRQ_VIC_START + 31)
+
+/*
+ * FIQ interrupts definitions are the same as the INT definitions.
+ */
+#define FIQ_WDOGINT INT_WDOGINT
+#define FIQ_SOFTINT INT_SOFTINT
+#define FIQ_COMMRx INT_COMMRx
+#define FIQ_COMMTx INT_COMMTx
+#define FIQ_TIMERINT0_1 INT_TIMERINT0_1
+#define FIQ_TIMERINT2_3 INT_TIMERINT2_3
+#define FIQ_GPIOINT0 INT_GPIOINT0
+#define FIQ_GPIOINT1 INT_GPIOINT1
+#define FIQ_GPIOINT2 INT_GPIOINT2
+#define FIQ_GPIOINT3 INT_GPIOINT3
+#define FIQ_RTCINT INT_RTCINT
+#define FIQ_SSPINT INT_SSPINT
+#define FIQ_UARTINT0 INT_UARTINT0
+#define FIQ_UARTINT1 INT_UARTINT1
+#define FIQ_UARTINT2 INT_UARTINT2
+#define FIQ_SCIINT INT_SCIINT
+#define FIQ_CLCDINT INT_CLCDINT
+#define FIQ_DMAINT INT_DMAINT
+#define FIQ_PWRFAILINT INT_PWRFAILINT
+#define FIQ_MBXINT INT_MBXINT
+#define FIQ_GNDINT INT_GNDINT
+#define FIQ_VICSOURCE21 INT_VICSOURCE21
+#define FIQ_VICSOURCE22 INT_VICSOURCE22
+#define FIQ_VICSOURCE23 INT_VICSOURCE23
+#define FIQ_VICSOURCE24 INT_VICSOURCE24
+#define FIQ_VICSOURCE25 INT_VICSOURCE25
+#define FIQ_VICSOURCE26 INT_VICSOURCE26
+#define FIQ_VICSOURCE27 INT_VICSOURCE27
+#define FIQ_VICSOURCE28 INT_VICSOURCE28
+#define FIQ_VICSOURCE29 INT_VICSOURCE29
+#define FIQ_VICSOURCE30 INT_VICSOURCE30
+#define FIQ_VICSOURCE31 INT_VICSOURCE31
+
+
+/*
+ * Secondary interrupt controller
+ */
+#define IRQ_SIC_START 32
+#define IRQ_SIC_MMCI0B (IRQ_SIC_START + SIC_INT_MMCI0B)
+#define IRQ_SIC_MMCI1B (IRQ_SIC_START + SIC_INT_MMCI1B)
+#define IRQ_SIC_KMI0 (IRQ_SIC_START + SIC_INT_KMI0)
+#define IRQ_SIC_KMI1 (IRQ_SIC_START + SIC_INT_KMI1)
+#define IRQ_SIC_SCI3 (IRQ_SIC_START + SIC_INT_SCI3)
+#define IRQ_SIC_UART3 (IRQ_SIC_START + SIC_INT_UART3)
+#define IRQ_SIC_CLCD (IRQ_SIC_START + SIC_INT_CLCD)
+#define IRQ_SIC_TOUCH (IRQ_SIC_START + SIC_INT_TOUCH)
+#define IRQ_SIC_KEYPAD (IRQ_SIC_START + SIC_INT_KEYPAD)
+#define IRQ_SIC_DoC (IRQ_SIC_START + SIC_INT_DoC)
+#define IRQ_SIC_MMCI0A (IRQ_SIC_START + SIC_INT_MMCI0A)
+#define IRQ_SIC_MMCI1A (IRQ_SIC_START + SIC_INT_MMCI1A)
+#define IRQ_SIC_AACI (IRQ_SIC_START + SIC_INT_AACI)
+#define IRQ_SIC_ETH (IRQ_SIC_START + SIC_INT_ETH)
+#define IRQ_SIC_USB (IRQ_SIC_START + SIC_INT_USB)
+#define IRQ_SIC_PCI0 (IRQ_SIC_START + SIC_INT_PCI0)
+#define IRQ_SIC_PCI1 (IRQ_SIC_START + SIC_INT_PCI1)
+#define IRQ_SIC_PCI2 (IRQ_SIC_START + SIC_INT_PCI2)
+#define IRQ_SIC_PCI3 (IRQ_SIC_START + SIC_INT_PCI3)
+#define IRQ_SIC_END 63
+
+#define IRQ_GPIO0_START (IRQ_SIC_END + 1)
+#define IRQ_GPIO0_END (IRQ_GPIO0_START + 31)
+#define IRQ_GPIO1_START (IRQ_GPIO0_END + 1)
+#define IRQ_GPIO1_END (IRQ_GPIO1_START + 31)
+#define IRQ_GPIO2_START (IRQ_GPIO1_END + 1)
+#define IRQ_GPIO2_END (IRQ_GPIO2_START + 31)
+#define IRQ_GPIO3_START (IRQ_GPIO2_END + 1)
+#define IRQ_GPIO3_END (IRQ_GPIO3_START + 31)
+
+#define NR_IRQS (IRQ_GPIO3_END + 1)
diff --git a/arch/arm/mach-versatile/include/mach/memory.h b/arch/arm/mach-versatile/include/mach/memory.h
new file mode 100644
index 00000000..dacc9d8e
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-versatile/include/mach/memory.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 00000000..ec087407
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,414 @@
+/*
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __address_h
+#define __address_h 1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI 0x30000000
+#define VERSATILE_BOOT_ROM_BASE VERSATILE_BOOT_ROM_HI /* Normal position */
+#define VERSATILE_BOOT_ROM_SIZE SZ_64M
+
+#define VERSATILE_SSRAM_BASE /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE SZ_2M
+
+#define VERSATILE_FLASH_BASE 0x34000000
+#define VERSATILE_FLASH_SIZE SZ_64M
+
+/*
+ * SDRAM
+ */
+#define VERSATILE_SDRAM_BASE 0x00000000
+
+/*
+ * Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ * Versatile Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define VERSATILE_SYS_ID_OFFSET 0x00
+#define VERSATILE_SYS_SW_OFFSET 0x04
+#define VERSATILE_SYS_LED_OFFSET 0x08
+#define VERSATILE_SYS_OSC0_OFFSET 0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET 0x10
+#define VERSATILE_SYS_OSC2_OFFSET 0x14
+#define VERSATILE_SYS_OSC3_OFFSET 0x18
+#define VERSATILE_SYS_OSC4_OFFSET 0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET 0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET 0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET 0x20
+#define VERSATILE_SYS_100HZ_OFFSET 0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET 0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET 0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET 0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET 0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET 0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET 0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET 0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET 0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET 0x40
+#define VERSATILE_SYS_PCICTL_OFFSET 0x44
+#define VERSATILE_SYS_MCI_OFFSET 0x48
+#define VERSATILE_SYS_FLASH_OFFSET 0x4C
+#define VERSATILE_SYS_CLCD_OFFSET 0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET 0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET 0x58
+#define VERSATILE_SYS_24MHz_OFFSET 0x5C
+#define VERSATILE_SYS_MISC_OFFSET 0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET 0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET 0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET 0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET 0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET 0x90
+
+#define VERSATILE_SYS_BASE 0x10000000
+#define VERSATILE_SYS_ID (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1 (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2 (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/*
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR 0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT 0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET 0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET 0x04
+#define VERSATILE_SYS_CTRL_RESET_POR 0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC 0x06
+
+#define VERSATILE_SYS_CTRL_LED (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ * Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4 = build value
+ * 3:0 = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ * SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ * - used to acknowledge and control MMCI and UART interrupts
+ */
+#define VERSATILE_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */
+#define VERSATILE_INTREG_CARDIN 0x08 /* MMCI card in detect */
+ /* write 1 to acknowledge and clear */
+#define VERSATILE_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */
+#define VERSATILE_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE 0x10001000 /* PCI core control */
+#define VERSATILE_I2C_BASE 0x10002000 /* I2C control */
+#define VERSATILE_SIC_BASE 0x10003000 /* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE 0x10004000 /* Audio */
+#define VERSATILE_MMCI0_BASE 0x10005000 /* MMC interface */
+#define VERSATILE_KMI0_BASE 0x10006000 /* KMI interface */
+#define VERSATILE_KMI1_BASE 0x10007000 /* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE 0x10008000 /* Character LCD */
+#define VERSATILE_UART3_BASE 0x10009000 /* UART 3 */
+#define VERSATILE_SCI1_BASE 0x1000A000
+#define VERSATILE_MMCI1_BASE 0x1000B000 /* MMC Interface */
+ /* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE 0x10010000 /* Ethernet */
+#define VERSATILE_USB_BASE 0x10020000 /* USB */
+ /* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE 0x10100000 /* SMC */
+#define VERSATILE_MPMC_BASE 0x10110000 /* MPMC */
+#define VERSATILE_CLCD_BASE 0x10120000 /* CLCD */
+#define VERSATILE_DMAC_BASE 0x10130000 /* DMA controller */
+#define VERSATILE_VIC_BASE 0x10140000 /* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE 0x10150000 /* off-chip peripherals alias from */
+ /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE 0x101D0000 /* AHB monitor */
+#define VERSATILE_SCTL_BASE 0x101E0000 /* System controller */
+#define VERSATILE_WATCHDOG_BASE 0x101E1000 /* Watchdog */
+#define VERSATILE_TIMER0_1_BASE 0x101E2000 /* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE 0x101E3000 /* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE 0x101E4000 /* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE 0x101E5000 /* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE 0x101E6000 /* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE 0x101E7000 /* GPIO port 3 */
+#define VERSATILE_RTC_BASE 0x101E8000 /* Real Time Clock */
+ /* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE 0x101F0000 /* Smart card controller */
+#define VERSATILE_UART0_BASE 0x101F1000 /* Uart 0 */
+#define VERSATILE_UART1_BASE 0x101F2000 /* Uart 1 */
+#define VERSATILE_UART2_BASE 0x101F3000 /* Uart 2 */
+#define VERSATILE_SSP_BASE 0x101F4000 /* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */
+#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */
+#define VERSATILE_MBX_BASE 0x40000000 /* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE 0x42000000
+#define VERSATILE_PCI_MEM_BASE0 0x44000000
+#define VERSATILE_PCI_MEM_BASE1 0x50000000
+#define VERSATILE_PCI_MEM_BASE2 0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE 0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE 0x80000000 /* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE 0x2C000000
+#define VERSATILE_DOC_SIZE (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE 512
+#define VERSATILE_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES 32
+#define START_PAGE 0x80
+
+/*
+ * LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0 (1 << 0)
+#define VERSATILE_SYS_LED1 (1 << 1)
+#define VERSATILE_SYS_LED2 (1 << 2)
+#define VERSATILE_SYS_LED3 (1 << 3)
+#define VERSATILE_SYS_LED4 (1 << 4)
+#define VERSATILE_SYS_LED5 (1 << 5)
+#define VERSATILE_SYS_LED6 (1 << 6)
+#define VERSATILE_SYS_LED7 (1 << 7)
+
+#define ALL_LEDS 0xFF
+
+#define LED_BANK VERSATILE_SYS_LED
+
+/*
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET 0x0 /* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET 0x4 /* Flash devices */
+#define VERSATILE_INTREG_OFFSET 0x8 /* Interrupt control */
+#define VERSATILE_DECODE_OFFSET 0xC /* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ * Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ *
+ * Offsets from interrupt controller base
+ *
+ * System Controller interrupt controller base is
+ *
+ * VERSATILE_IC_BASE
+ *
+ * Core Module interrupt controller base is
+ *
+ * VERSATILE_SYS_IC
+ *
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS 0
+#define SIC_IRQ_RAW_STATUS 0x04
+#define SIC_IRQ_ENABLE 0x08
+#define SIC_IRQ_ENABLE_SET 0x08
+#define SIC_IRQ_ENABLE_CLEAR 0x0C
+#define SIC_INT_SOFT_SET 0x10
+#define SIC_INT_SOFT_CLEAR 0x14
+#define SIC_INT_PIC_ENABLE 0x20 /* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES 0x20 /* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC 0x24 /* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ * Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT 0 /* Watchdog timer */
+#define INT_SOFTINT 1 /* Software interrupt */
+#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
+#define INT_COMMTx 3 /* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1 4 /* Timer 0 and 1 */
+#define INT_TIMERINT2_3 5 /* Timer 2 and 3 */
+#define INT_GPIOINT0 6 /* GPIO 0 */
+#define INT_GPIOINT1 7 /* GPIO 1 */
+#define INT_GPIOINT2 8 /* GPIO 2 */
+#define INT_GPIOINT3 9 /* GPIO 3 */
+#define INT_RTCINT 10 /* Real Time Clock */
+#define INT_SSPINT 11 /* Synchronous Serial Port */
+#define INT_UARTINT0 12 /* UART 0 on development chip */
+#define INT_UARTINT1 13 /* UART 1 on development chip */
+#define INT_UARTINT2 14 /* UART 2 on development chip */
+#define INT_SCIINT 15 /* Smart Card Interface */
+#define INT_CLCDINT 16 /* CLCD controller */
+#define INT_DMAINT 17 /* DMA controller */
+#define INT_PWRFAILINT 18 /* Power failure */
+#define INT_MBXINT 19 /* Graphics processor */
+#define INT_GNDINT 20 /* Reserved */
+ /* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21 21 /* Disk on Chip */
+#define INT_VICSOURCE22 22 /* MCI0A */
+#define INT_VICSOURCE23 23 /* MCI1A */
+#define INT_VICSOURCE24 24 /* AACI */
+#define INT_VICSOURCE25 25 /* Ethernet */
+#define INT_VICSOURCE26 26 /* USB */
+#define INT_VICSOURCE27 27 /* PCI 0 */
+#define INT_VICSOURCE28 28 /* PCI 1 */
+#define INT_VICSOURCE29 29 /* PCI 2 */
+#define INT_VICSOURCE30 30 /* PCI 3 */
+#define INT_VICSOURCE31 31 /* SIC source */
+
+#define VERSATILE_SC_VALID_INT 0x003FFFFF
+
+#define MAXIRQNUM 31
+#define MAXFIQNUM 31
+#define MAXSWINUM 31
+
+/* ------------------------------------------------------------------------
+ * Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B 1 /* Multimedia Card 0B */
+#define SIC_INT_MMCI1B 2 /* Multimedia Card 1B */
+#define SIC_INT_KMI0 3 /* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1 4 /* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3 5 /* Smart Card interface */
+#define SIC_INT_UART3 6 /* UART 3 empty or data available */
+#define SIC_INT_CLCD 7 /* Character LCD */
+#define SIC_INT_TOUCH 8 /* Touchscreen */
+#define SIC_INT_KEYPAD 9 /* Key pressed on display keypad */
+ /* 10:20 - reserved */
+#define SIC_INT_DoC 21 /* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A 22 /* MMC 0A */
+#define SIC_INT_MMCI1A 23 /* MMC 1A */
+#define SIC_INT_AACI 24 /* Audio Codec */
+#define SIC_INT_ETH 25 /* Ethernet controller */
+#define SIC_INT_USB 26 /* USB controller */
+#define SIC_INT_PCI0 27
+#define SIC_INT_PCI1 28
+#define SIC_INT_PCI2 29
+#define SIC_INT_PCI3 30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK 0
+#define VERSATILE_TIMCLK 1
+
+#define VERSATILE_TIMER1_EnSel 15
+#define VERSATILE_TIMER2_EnSel 17
+#define VERSATILE_TIMER3_EnSel 19
+#define VERSATILE_TIMER4_EnSel 21
+
+
+#define VERSATILE_CSR_BASE 0x10000000
+#define VERSATILE_CSR_SIZE 0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG (VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE (VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER (VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR (VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE (VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL (VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT (VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h
new file mode 100644
index 00000000..8ffc12a7
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/system.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-versatile/include/mach/system.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ u32 val;
+
+ val = __raw_readl(IO_ADDRESS(VERSATILE_SYS_RESETCTL)) & ~0x7;
+ val |= 0x105;
+
+ __raw_writel(0xa05f, IO_ADDRESS(VERSATILE_SYS_LOCK));
+ __raw_writel(val, IO_ADDRESS(VERSATILE_SYS_RESETCTL));
+ __raw_writel(0, IO_ADDRESS(VERSATILE_SYS_LOCK));
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/timex.h b/arch/arm/mach-versatile/include/mach/timex.h
new file mode 100644
index 00000000..426199b1
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-versatile/include/mach/timex.h
+ *
+ * Versatile architecture timex specifications
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-versatile/include/mach/uncompress.h b/arch/arm/mach-versatile/include/mach/uncompress.h
new file mode 100644
index 00000000..3dd0048a
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/uncompress.h
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-versatile/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#define AMBA_UART_DR (*(volatile unsigned char *)0x101F1000)
+#define AMBA_UART_LCRH (*(volatile unsigned char *)0x101F102C)
+#define AMBA_UART_CR (*(volatile unsigned char *)0x101F1030)
+#define AMBA_UART_FR (*(volatile unsigned char *)0x101F1018)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ while (AMBA_UART_FR & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR = c;
+}
+
+static inline void flush(void)
+{
+ while (AMBA_UART_FR & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-versatile/include/mach/vmalloc.h b/arch/arm/mach-versatile/include/mach/vmalloc.h
new file mode 100644
index 00000000..7d8e069a
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-versatile/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xd8000000UL
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644
index 00000000..13c7e5f9
--- /dev/null
+++ b/arch/arm/mach-versatile/pci.c
@@ -0,0 +1,361 @@
+/*
+ * linux/arch/arm/mach-versatile/pci.c
+ *
+ * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
+ * You can redistribute and/or modify this software under the terms of version 2
+ * of the GNU General Public License as published by the Free Software Foundation.
+ * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
+ *
+ * ARM Versatile PCI driver.
+ *
+ * 14/04/2005 Initial version, colin.king@philips.com
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+
+/*
+ * these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory Base/Map registers used
+ *
+ * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0, non prefetch
+ * Mem 60000000 - 6FFFFFFF LB_BASE1/LB_MAP1, prefetch
+ * IO 44000000 - 4FFFFFFF LB_BASE2/LB_MAP2, IO
+ * Cfg 42000000 - 42FFFFFF PCI config
+ *
+ */
+#define __IO_ADDRESS(n) ((void __iomem *)(unsigned long)IO_ADDRESS(n))
+#define SYS_PCICTL __IO_ADDRESS(VERSATILE_SYS_PCICTL)
+#define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+#define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+#define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+
+#define DEVICE_ID_OFFSET 0x00
+#define CSR_OFFSET 0x04
+#define CLASS_ID_OFFSET 0x08
+
+#define VP_PCI_DEVICE_ID 0x030010ee
+#define VP_PCI_CLASS_ID 0x0b400000
+
+static unsigned long pci_slot_ignore = 0;
+
+static int __init versatile_pci_slot_ignore(char *str)
+{
+ int retval;
+ int slot;
+
+ while ((retval = get_option(&str,&slot))) {
+ if ((slot < 0) || (slot > 31)) {
+ printk("Illegal slot value: %d\n",slot);
+ } else {
+ pci_slot_ignore |= (1 << slot);
+ }
+ }
+ return 1;
+}
+
+__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
+
+
+static void __iomem *__pci_addr(struct pci_bus *bus,
+ unsigned int devfn, int offset)
+{
+ unsigned int busnr = bus->number;
+
+ /*
+ * Trap out illegal values
+ */
+ if (offset > 255)
+ BUG();
+ if (busnr > 255)
+ BUG();
+ if (devfn > 255)
+ BUG();
+
+ return VERSATILE_PCI_CFG_VIRT_BASE + ((busnr << 16) |
+ (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
+}
+
+static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ void __iomem *addr = __pci_addr(bus, devfn, where & ~3);
+ u32 v;
+ int slot = PCI_SLOT(devfn);
+
+ if (pci_slot_ignore & (1 << slot)) {
+ /* Ignore this slot */
+ switch (size) {
+ case 1:
+ v = 0xff;
+ break;
+ case 2:
+ v = 0xffff;
+ break;
+ default:
+ v = 0xffffffff;
+ }
+ } else {
+ switch (size) {
+ case 1:
+ v = __raw_readl(addr);
+ if (where & 2) v >>= 16;
+ if (where & 1) v >>= 8;
+ v &= 0xff;
+ break;
+
+ case 2:
+ v = __raw_readl(addr);
+ if (where & 2) v >>= 16;
+ v &= 0xffff;
+ break;
+
+ default:
+ v = __raw_readl(addr);
+ break;
+ }
+ }
+
+ *val = v;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ void __iomem *addr = __pci_addr(bus, devfn, where);
+ int slot = PCI_SLOT(devfn);
+
+ if (pci_slot_ignore & (1 << slot)) {
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ switch (size) {
+ case 1:
+ __raw_writeb((u8)val, addr);
+ break;
+
+ case 2:
+ __raw_writew((u16)val, addr);
+ break;
+
+ case 4:
+ __raw_writel(val, addr);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_versatile_ops = {
+ .read = versatile_read_config,
+ .write = versatile_write_config,
+};
+
+static struct resource io_mem = {
+ .name = "PCI I/O space",
+ .start = VERSATILE_PCI_MEM_BASE0,
+ .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource non_mem = {
+ .name = "PCI non-prefetchable",
+ .start = VERSATILE_PCI_MEM_BASE1,
+ .end = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+ .name = "PCI prefetchable",
+ .start = VERSATILE_PCI_MEM_BASE2,
+ .end = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
+ .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_versatile_setup_resources(struct resource **resource)
+{
+ int ret = 0;
+
+ ret = request_resource(&iomem_resource, &io_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate I/O "
+ "memory region (%d)\n", ret);
+ goto out;
+ }
+ ret = request_resource(&iomem_resource, &non_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+ "memory region (%d)\n", ret);
+ goto release_io_mem;
+ }
+ ret = request_resource(&iomem_resource, &pre_mem);
+ if (ret) {
+ printk(KERN_ERR "PCI: unable to allocate prefetchable "
+ "memory region (%d)\n", ret);
+ goto release_non_mem;
+ }
+
+ /*
+ * bus->resource[0] is the IO resource for this bus
+ * bus->resource[1] is the mem resource for this bus
+ * bus->resource[2] is the prefetch mem resource for this bus
+ */
+ resource[0] = &io_mem;
+ resource[1] = &non_mem;
+ resource[2] = &pre_mem;
+
+ goto out;
+
+ release_non_mem:
+ release_resource(&non_mem);
+ release_io_mem:
+ release_resource(&io_mem);
+ out:
+ return ret;
+}
+
+int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+{
+ int ret = 0;
+ int i;
+ int myslot = -1;
+ unsigned long val;
+ void __iomem *local_pci_cfg_base;
+
+ val = __raw_readl(SYS_PCICTL);
+ if (!(val & 1)) {
+ printk("Not plugged into PCI backplane!\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ if (nr == 0) {
+ sys->mem_offset = 0;
+ ret = pci_versatile_setup_resources(sys->resource);
+ if (ret < 0) {
+ printk("pci_versatile_setup: resources... oops?\n");
+ goto out;
+ }
+ } else {
+ printk("pci_versatile_setup: resources... nr == 0??\n");
+ goto out;
+ }
+
+ /*
+ * We need to discover the PCI core first to configure itself
+ * before the main PCI probing is performed
+ */
+ for (i=0; i<32; i++)
+ if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
+ (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
+ myslot = i;
+ break;
+ }
+
+ if (myslot == -1) {
+ printk("Cannot find PCI core!\n");
+ ret = -EIO;
+ goto out;
+ }
+
+ printk("PCI core found (slot %d)\n",myslot);
+
+ __raw_writel(myslot, PCI_SELFID);
+ local_pci_cfg_base = VERSATILE_PCI_CFG_VIRT_BASE + (myslot << 11);
+
+ val = __raw_readl(local_pci_cfg_base + CSR_OFFSET);
+ val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+ __raw_writel(val, local_pci_cfg_base + CSR_OFFSET);
+
+ /*
+ * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM
+ */
+ __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0);
+ __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1);
+ __raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);
+
+ /*
+ * Do not to map Versatile FPGA PCI device into memory space
+ */
+ pci_slot_ignore |= (1 << myslot);
+ ret = 1;
+
+ out:
+ return ret;
+}
+
+
+struct pci_bus * __init pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+}
+
+void __init pci_versatile_preinit(void)
+{
+ __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28, PCI_IMAP0);
+ __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28, PCI_IMAP1);
+ __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28, PCI_IMAP2);
+
+ __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP0);
+ __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP1);
+ __raw_writel(PHYS_OFFSET >> 28, PCI_SMAP2);
+
+ __raw_writel(1, SYS_PCICTL);
+}
+
+/*
+ * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this.
+ */
+static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+ int devslot = PCI_SLOT(dev->devfn);
+
+ /* slot, pin, irq
+ * 24 1 27
+ * 25 1 28
+ * 26 1 29
+ * 27 1 30
+ */
+ irq = 27 + ((slot + pin - 1) & 3);
+
+ printk("PCI map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
+
+ return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+ .swizzle = NULL,
+ .map_irq = versatile_map_irq,
+ .nr_controllers = 1,
+ .setup = pci_versatile_setup,
+ .scan = pci_versatile_scan_bus,
+ .preinit = pci_versatile_preinit,
+};
+
+static int __init versatile_pci_init(void)
+{
+ pci_common_init(&versatile_pci);
+ return 0;
+}
+
+subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
new file mode 100644
index 00000000..f8ae64b3
--- /dev/null
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -0,0 +1,44 @@
+/*
+ * linux/arch/arm/mach-versatile/versatile_ab.c
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include "core.h"
+
+MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = 0x00000100,
+ .map_io = versatile_map_io,
+ .init_early = versatile_init_early,
+ .init_irq = versatile_init_irq,
+ .timer = &versatile_timer,
+ .init_machine = versatile_init,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
new file mode 100644
index 00000000..37c23dfe
--- /dev/null
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/arm/mach-versatile/versatile_pb.c
+ *
+ * Copyright (C) 2004 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl061.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include "core.h"
+
+#if 1
+#define IRQ_MMCI1A IRQ_VICSOURCE23
+#else
+#define IRQ_MMCI1A IRQ_SIC_MMCI1A
+#endif
+
+static struct mmci_platform_data mmc1_plat_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = mmc_status,
+ .gpio_wp = -1,
+ .gpio_cd = -1,
+};
+
+static struct pl061_platform_data gpio2_plat_data = {
+ .gpio_base = 16,
+ .irq_base = IRQ_GPIO2_START,
+};
+
+static struct pl061_platform_data gpio3_plat_data = {
+ .gpio_base = 24,
+ .irq_base = IRQ_GPIO3_START,
+};
+
+#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
+#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
+#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
+
+/*
+ * These devices are connected via the core APB bridge
+ */
+#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
+#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
+
+/*
+ * These devices are connected via the DMA APB bridge
+ */
+
+/* FPGA Primecells */
+AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
+AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL);
+AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
+
+/* DevChip Primecells */
+AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
+AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data);
+
+static struct amba_device *amba_devs[] __initdata = {
+ &uart3_device,
+ &gpio2_device,
+ &gpio3_device,
+ &sci1_device,
+ &mmc1_device,
+};
+
+static void __init versatile_pb_init(void)
+{
+ int i;
+
+ versatile_init();
+
+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+ struct amba_device *d = amba_devs[i];
+ amba_device_register(d, &iomem_resource);
+ }
+}
+
+MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
+ /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+ .boot_params = 0x00000100,
+ .map_io = versatile_map_io,
+ .init_early = versatile_init_early,
+ .init_irq = versatile_init_irq,
+ .timer = &versatile_timer,
+ .init_machine = versatile_pb_init,
+MACHINE_END
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
new file mode 100644
index 00000000..93114848
--- /dev/null
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -0,0 +1,12 @@
+menu "Versatile Express platform type"
+ depends on ARCH_VEXPRESS
+
+config ARCH_VEXPRESS_CA9X4
+ bool "Versatile Express Cortex-A9x4 tile"
+ select CPU_V7
+ select ARM_GIC
+ select ARM_ERRATA_720789
+ select ARM_ERRATA_751472
+ select ARM_ERRATA_753970
+
+endmenu
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
new file mode 100644
index 00000000..90551b97
--- /dev/null
+++ b/arch/arm/mach-vexpress/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_CA9X4) += ct-ca9x4.o
+obj-$(CONFIG_SMP) += platsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
new file mode 100644
index 00000000..07c2d9c4
--- /dev/null
+++ b/arch/arm/mach-vexpress/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x60008000
+params_phys-y := 0x60000100
+initrd_phys-y := 0x60800000
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
new file mode 100644
index 00000000..f4397159
--- /dev/null
+++ b/arch/arm/mach-vexpress/core.h
@@ -0,0 +1,19 @@
+#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
+#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x))
+
+#define AMBA_DEVICE(name,busid,base,plat) \
+struct amba_device name##_device = { \
+ .dev = { \
+ .coherent_dma_mask = ~0UL, \
+ .init_name = busid, \
+ .platform_data = plat, \
+ }, \
+ .res = { \
+ .start = base, \
+ .end = base + SZ_4K - 1, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ .dma_mask = ~0UL, \
+ .irq = IRQ_##base, \
+ /* .dma = DMA_##base,*/ \
+}
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
new file mode 100644
index 00000000..765a71ff
--- /dev/null
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -0,0 +1,251 @@
+/*
+ * Versatile Express Core Tile Cortex A9x4 Support
+ */
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clkdev.h>
+
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/hardware/gic.h>
+#include <asm/pmu.h>
+#include <asm/smp_scu.h>
+#include <asm/smp_twd.h>
+
+#include <mach/ct-ca9x4.h>
+
+#include <asm/hardware/timer-sp.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+#include "core.h"
+
+#include <mach/motherboard.h>
+
+#include <plat/clcd.h>
+
+#define V2M_PA_CS7 0x10000000
+
+static struct map_desc ct_ca9x4_io_desc[] __initdata = {
+ {
+ .virtual = __MMIO_P2V(CT_CA9X4_MPIC),
+ .pfn = __phys_to_pfn(CT_CA9X4_MPIC),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
+ .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = __MMIO_P2V(CT_CA9X4_L2CC),
+ .pfn = __phys_to_pfn(CT_CA9X4_L2CC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init ct_ca9x4_map_io(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = MMIO_P2V(A9_MPCORE_TWD);
+#endif
+ iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
+}
+
+static void __init ct_ca9x4_init_irq(void)
+{
+ gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST),
+ MMIO_P2V(A9_MPCORE_GIC_CPU));
+}
+
+#if 0
+static void __init ct_ca9x4_timer_init(void)
+{
+ writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
+ writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
+
+ sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1");
+ sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0,
+ "ct-timer0");
+}
+
+static struct sys_timer ct_ca9x4_timer = {
+ .init = ct_ca9x4_timer_init,
+};
+#endif
+
+static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
+{
+ v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
+ v2m_cfg_write(SYS_CFG_DVIMODE | SYS_CFG_SITE_DB1, 2);
+}
+
+static int ct_ca9x4_clcd_setup(struct clcd_fb *fb)
+{
+ unsigned long framesize = 1024 * 768 * 2;
+
+ fb->panel = versatile_clcd_get_panel("XVGA");
+ if (!fb->panel)
+ return -EINVAL;
+
+ return versatile_clcd_setup_dma(fb, framesize);
+}
+
+static struct clcd_board ct_ca9x4_clcd_data = {
+ .name = "CT-CA9X4",
+ .caps = CLCD_CAP_5551 | CLCD_CAP_565,
+ .check = clcdfb_check,
+ .decode = clcdfb_decode,
+ .enable = ct_ca9x4_clcd_enable,
+ .setup = ct_ca9x4_clcd_setup,
+ .mmap = versatile_clcd_mmap_dma,
+ .remove = versatile_clcd_remove_dma,
+};
+
+static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
+static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
+static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+
+static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
+ &clcd_device,
+ &dmc_device,
+ &smc_device,
+ &gpio_device,
+};
+
+
+static long ct_round(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+
+static int ct_set(struct clk *clk, unsigned long rate)
+{
+ return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_DB1 | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+ .round = ct_round,
+ .set = ct_set,
+};
+
+static struct clk osc1_clk = {
+ .ops = &osc1_clk_ops,
+ .rate = 24000000,
+};
+
+static struct clk ct_sp804_clk = {
+ .rate = 1000000,
+};
+
+static struct clk_lookup lookups[] = {
+ { /* CLCD */
+ .dev_id = "ct:clcd",
+ .clk = &osc1_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .con_id = "ct-timer0",
+ .clk = &ct_sp804_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .con_id = "ct-timer1",
+ .clk = &ct_sp804_clk,
+ },
+};
+
+static struct resource pmu_resources[] = {
+ [0] = {
+ .start = IRQ_CT_CA9X4_PMU_CPU0,
+ .end = IRQ_CT_CA9X4_PMU_CPU0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = IRQ_CT_CA9X4_PMU_CPU1,
+ .end = IRQ_CT_CA9X4_PMU_CPU1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_CT_CA9X4_PMU_CPU2,
+ .end = IRQ_CT_CA9X4_PMU_CPU2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_CT_CA9X4_PMU_CPU3,
+ .end = IRQ_CT_CA9X4_PMU_CPU3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(pmu_resources),
+ .resource = pmu_resources,
+};
+
+static void __init ct_ca9x4_init_early(void)
+{
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
+
+static void __init ct_ca9x4_init(void)
+{
+ int i;
+
+#ifdef CONFIG_CACHE_L2X0
+ void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC);
+
+ /* set RAM latencies to 1 cycle for this core tile. */
+ writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
+ writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL);
+
+ l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff);
+#endif
+
+ for (i = 0; i < ARRAY_SIZE(ct_ca9x4_amba_devs); i++)
+ amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource);
+
+ platform_device_register(&pmu_device);
+}
+
+#ifdef CONFIG_SMP
+static void ct_ca9x4_init_cpu_map(void)
+{
+ int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU));
+
+ for (i = 0; i < ncores; ++i)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+static void ct_ca9x4_smp_enable(unsigned int max_cpus)
+{
+ int i;
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(MMIO_P2V(A9_MPCORE_SCU));
+}
+#endif
+
+struct ct_desc ct_ca9x4_desc __initdata = {
+ .id = V2M_CT_ID_CA9,
+ .name = "CA9x4",
+ .map_io = ct_ca9x4_map_io,
+ .init_early = ct_ca9x4_init_early,
+ .init_irq = ct_ca9x4_init_irq,
+ .init_tile = ct_ca9x4_init,
+#ifdef CONFIG_SMP
+ .init_cpu_map = ct_ca9x4_init_cpu_map,
+ .smp_enable = ct_ca9x4_smp_enable,
+#endif
+};
diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c
new file mode 100644
index 00000000..ea4cbfb9
--- /dev/null
+++ b/arch/arm/mach-vexpress/hotplug.c
@@ -0,0 +1,128 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+
+extern volatile int pen_release;
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ "mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, %3\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0), "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, %1\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, %2\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ : "Ir" (CR_C), "Ir" (0x40)
+ : "cc");
+}
+
+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 (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ if (pen_release == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+
+ /*
+ * Getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * Just note it happening - when we're woken, we can report
+ * its occurrence.
+ */
+ (*spurious)++;
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return 1;
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ int spurious = 0;
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu, &spurious);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+
+ if (spurious)
+ pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-vexpress/include/mach/clkdev.h b/arch/arm/mach-vexpress/include/mach/clkdev.h
new file mode 100644
index 00000000..3f8307d7
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/clkdev.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#include <plat/clock.h>
+
+struct clk {
+ const struct clk_ops *ops;
+ unsigned long rate;
+ const struct icst_params *params;
+};
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
new file mode 100644
index 00000000..a34d3d4f
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -0,0 +1,50 @@
+#ifndef __MACH_CT_CA9X4_H
+#define __MACH_CT_CA9X4_H
+
+/*
+ * Physical base addresses
+ */
+#define CT_CA9X4_CLCDC (0x10020000)
+#define CT_CA9X4_AXIRAM (0x10060000)
+#define CT_CA9X4_DMC (0x100e0000)
+#define CT_CA9X4_SMC (0x100e1000)
+#define CT_CA9X4_SCC (0x100e2000)
+#define CT_CA9X4_SP804_TIMER (0x100e4000)
+#define CT_CA9X4_SP805_WDT (0x100e5000)
+#define CT_CA9X4_TZPC (0x100e6000)
+#define CT_CA9X4_GPIO (0x100e8000)
+#define CT_CA9X4_FASTAXI (0x100e9000)
+#define CT_CA9X4_SLOWAXI (0x100ea000)
+#define CT_CA9X4_TZASC (0x100ec000)
+#define CT_CA9X4_CORESIGHT (0x10200000)
+#define CT_CA9X4_MPIC (0x1e000000)
+#define CT_CA9X4_SYSTIMER (0x1e004000)
+#define CT_CA9X4_SYSWDT (0x1e007000)
+#define CT_CA9X4_L2CC (0x1e00a000)
+
+#define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000)
+#define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020)
+
+#define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000)
+#define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100)
+#define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200)
+#define A9_MPCORE_TWD (CT_CA9X4_MPIC + 0x0600)
+#define A9_MPCORE_GIC_DIST (CT_CA9X4_MPIC + 0x1000)
+
+/*
+ * Interrupts. Those in {} are for AMBA devices
+ */
+#define IRQ_CT_CA9X4_CLCDC { 76 }
+#define IRQ_CT_CA9X4_DMC { -1 }
+#define IRQ_CT_CA9X4_SMC { 77, 78 }
+#define IRQ_CT_CA9X4_TIMER0 80
+#define IRQ_CT_CA9X4_TIMER1 81
+#define IRQ_CT_CA9X4_GPIO { 82 }
+#define IRQ_CT_CA9X4_PMU_CPU0 92
+#define IRQ_CT_CA9X4_PMU_CPU1 93
+#define IRQ_CT_CA9X4_PMU_CPU2 94
+#define IRQ_CT_CA9X4_PMU_CPU3 95
+
+extern struct ct_desc ct_ca9x4_desc;
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/debug-macro.S b/arch/arm/mach-vexpress/include/mach/debug-macro.S
new file mode 100644
index 00000000..050d65e0
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/debug-macro.S
@@ -0,0 +1,21 @@
+/* arch/arm/mach-realview/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define DEBUG_LL_UART_OFFSET 0x00009000
+
+ .macro addruart,rp,rv
+ mov \rp, #DEBUG_LL_UART_OFFSET
+ orr \rv, \rp, #0xf8000000 @ virtual base
+ orr \rp, \rp, #0x10000000 @ physical base
+ .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-vexpress/include/mach/entry-macro.S b/arch/arm/mach-vexpress/include/mach/entry-macro.S
new file mode 100644
index 00000000..73c11297
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/entry-macro.S
@@ -0,0 +1,7 @@
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
diff --git a/arch/arm/mach-vexpress/include/mach/hardware.h b/arch/arm/mach-vexpress/include/mach/hardware.h
new file mode 100644
index 00000000..40a8c178
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/hardware.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h
new file mode 100644
index 00000000..748bb524
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/io.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/irqs.h b/arch/arm/mach-vexpress/include/mach/irqs.h
new file mode 100644
index 00000000..7054cbfc
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/irqs.h
@@ -0,0 +1,4 @@
+#define IRQ_LOCALTIMER 29
+#define IRQ_LOCALWDOG 30
+
+#define NR_IRQS 128
diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h
new file mode 100644
index 00000000..5b7fcd43
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/memory.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/memory.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x60000000)
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
new file mode 100644
index 00000000..0a3a3751
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -0,0 +1,143 @@
+#ifndef __MACH_MOTHERBOARD_H
+#define __MACH_MOTHERBOARD_H
+
+/*
+ * Physical addresses, offset from V2M_PA_CS0-3
+ */
+#define V2M_NOR0 (V2M_PA_CS0)
+#define V2M_NOR1 (V2M_PA_CS1)
+#define V2M_SRAM (V2M_PA_CS2)
+#define V2M_VIDEO_SRAM (V2M_PA_CS3 + 0x00000000)
+#define V2M_LAN9118 (V2M_PA_CS3 + 0x02000000)
+#define V2M_ISP1761 (V2M_PA_CS3 + 0x03000000)
+
+/*
+ * Physical addresses, offset from V2M_PA_CS7
+ */
+#define V2M_SYSREGS (V2M_PA_CS7 + 0x00000000)
+#define V2M_SYSCTL (V2M_PA_CS7 + 0x00001000)
+#define V2M_SERIAL_BUS_PCI (V2M_PA_CS7 + 0x00002000)
+
+#define V2M_AACI (V2M_PA_CS7 + 0x00004000)
+#define V2M_MMCI (V2M_PA_CS7 + 0x00005000)
+#define V2M_KMI0 (V2M_PA_CS7 + 0x00006000)
+#define V2M_KMI1 (V2M_PA_CS7 + 0x00007000)
+
+#define V2M_UART0 (V2M_PA_CS7 + 0x00009000)
+#define V2M_UART1 (V2M_PA_CS7 + 0x0000a000)
+#define V2M_UART2 (V2M_PA_CS7 + 0x0000b000)
+#define V2M_UART3 (V2M_PA_CS7 + 0x0000c000)
+
+#define V2M_WDT (V2M_PA_CS7 + 0x0000f000)
+
+#define V2M_TIMER01 (V2M_PA_CS7 + 0x00011000)
+#define V2M_TIMER23 (V2M_PA_CS7 + 0x00012000)
+
+#define V2M_SERIAL_BUS_DVI (V2M_PA_CS7 + 0x00016000)
+#define V2M_RTC (V2M_PA_CS7 + 0x00017000)
+
+#define V2M_CF (V2M_PA_CS7 + 0x0001a000)
+#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000)
+
+#define V2M_SYS_ID (V2M_SYSREGS + 0x000)
+#define V2M_SYS_SW (V2M_SYSREGS + 0x004)
+#define V2M_SYS_LED (V2M_SYSREGS + 0x008)
+#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024)
+#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030)
+#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034)
+#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038)
+#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c)
+#define V2M_SYS_MCI (V2M_SYSREGS + 0x048)
+#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c)
+#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058)
+#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c)
+#define V2M_SYS_MISC (V2M_SYSREGS + 0x060)
+#define V2M_SYS_DMA (V2M_SYSREGS + 0x064)
+#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084)
+#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088)
+#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0)
+#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4)
+#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8)
+
+#define V2M_TIMER0 (V2M_TIMER01 + 0x000)
+#define V2M_TIMER1 (V2M_TIMER01 + 0x020)
+
+#define V2M_TIMER2 (V2M_TIMER23 + 0x000)
+#define V2M_TIMER3 (V2M_TIMER23 + 0x020)
+
+
+/*
+ * Interrupts. Those in {} are for AMBA devices
+ */
+#define IRQ_V2M_WDT { (32 + 0) }
+#define IRQ_V2M_TIMER0 (32 + 2)
+#define IRQ_V2M_TIMER1 (32 + 2)
+#define IRQ_V2M_TIMER2 (32 + 3)
+#define IRQ_V2M_TIMER3 (32 + 3)
+#define IRQ_V2M_RTC { (32 + 4) }
+#define IRQ_V2M_UART0 { (32 + 5) }
+#define IRQ_V2M_UART1 { (32 + 6) }
+#define IRQ_V2M_UART2 { (32 + 7) }
+#define IRQ_V2M_UART3 { (32 + 8) }
+#define IRQ_V2M_MMCI { (32 + 9), (32 + 10) }
+#define IRQ_V2M_AACI { (32 + 11) }
+#define IRQ_V2M_KMI0 { (32 + 12) }
+#define IRQ_V2M_KMI1 { (32 + 13) }
+#define IRQ_V2M_CLCD { (32 + 14) }
+#define IRQ_V2M_LAN9118 (32 + 15)
+#define IRQ_V2M_ISP1761 (32 + 16)
+#define IRQ_V2M_PCIE (32 + 17)
+
+
+/*
+ * Configuration
+ */
+#define SYS_CFG_START (1 << 31)
+#define SYS_CFG_WRITE (1 << 30)
+#define SYS_CFG_OSC (1 << 20)
+#define SYS_CFG_VOLT (2 << 20)
+#define SYS_CFG_AMP (3 << 20)
+#define SYS_CFG_TEMP (4 << 20)
+#define SYS_CFG_RESET (5 << 20)
+#define SYS_CFG_SCC (6 << 20)
+#define SYS_CFG_MUXFPGA (7 << 20)
+#define SYS_CFG_SHUTDOWN (8 << 20)
+#define SYS_CFG_REBOOT (9 << 20)
+#define SYS_CFG_DVIMODE (11 << 20)
+#define SYS_CFG_POWER (12 << 20)
+#define SYS_CFG_SITE_MB (0 << 16)
+#define SYS_CFG_SITE_DB1 (1 << 16)
+#define SYS_CFG_SITE_DB2 (2 << 16)
+#define SYS_CFG_STACK(n) ((n) << 12)
+
+#define SYS_CFG_ERR (1 << 1)
+#define SYS_CFG_COMPLETE (1 << 0)
+
+int v2m_cfg_write(u32 devfn, u32 data);
+int v2m_cfg_read(u32 devfn, u32 *data);
+
+/*
+ * Core tile IDs
+ */
+#define V2M_CT_ID_CA9 0x0c000191
+#define V2M_CT_ID_UNSUPPORTED 0xff000191
+#define V2M_CT_ID_MASK 0xff000fff
+
+struct ct_desc {
+ u32 id;
+ const char *name;
+ void (*map_io)(void);
+ void (*init_early)(void);
+ void (*init_irq)(void);
+ void (*init_tile)(void);
+#ifdef CONFIG_SMP
+ void (*init_cpu_map)(void);
+ void (*smp_enable)(unsigned int);
+#endif
+};
+
+extern struct ct_desc *ct_desc;
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h
new file mode 100644
index 00000000..899a4e62
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/system.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/system.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-vexpress/include/mach/timex.h b/arch/arm/mach-vexpress/include/mach/timex.h
new file mode 100644
index 00000000..00029bac
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/timex.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/timex.h
+ *
+ * RealView architecture timex specifications
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+
+#define CLOCK_TICK_RATE (50000000 / 16)
diff --git a/arch/arm/mach-vexpress/include/mach/uncompress.h b/arch/arm/mach-vexpress/include/mach/uncompress.h
new file mode 100644
index 00000000..7972c574
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/uncompress.h
@@ -0,0 +1,52 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/uncompress.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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
+ */
+#define AMBA_UART_DR(base) (*(volatile unsigned char *)((base) + 0x00))
+#define AMBA_UART_LCRH(base) (*(volatile unsigned char *)((base) + 0x2c))
+#define AMBA_UART_CR(base) (*(volatile unsigned char *)((base) + 0x30))
+#define AMBA_UART_FR(base) (*(volatile unsigned char *)((base) + 0x18))
+
+#define get_uart_base() (0x10000000 + 0x00009000)
+
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 5))
+ barrier();
+
+ AMBA_UART_DR(base) = c;
+}
+
+static inline void flush(void)
+{
+ unsigned long base = get_uart_base();
+
+ while (AMBA_UART_FR(base) & (1 << 3))
+ barrier();
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vexpress/include/mach/vmalloc.h b/arch/arm/mach-vexpress/include/mach/vmalloc.h
new file mode 100644
index 00000000..f43a36ef
--- /dev/null
+++ b/arch/arm/mach-vexpress/include/mach/vmalloc.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-vexpress/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xf8000000UL
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
new file mode 100644
index 00000000..2b5f7ac0
--- /dev/null
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/mach-vexpress/platsmp.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/init.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/unified.h>
+
+#include <mach/motherboard.h>
+#define V2M_PA_CS7 0x10000000
+
+#include "core.h"
+
+extern void versatile_secondary_startup(void);
+
+/*
+ * 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)
+{
+ ct_desc->init_cpu_map();
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ ct_desc->smp_enable(max_cpus);
+
+ /*
+ * 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.
+ */
+ writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
+ writel(BSYM(virt_to_phys(versatile_secondary_startup)),
+ MMIO_P2V(V2M_SYS_FLAGSSET));
+}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
new file mode 100644
index 00000000..9e6b93b1
--- /dev/null
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -0,0 +1,445 @@
+/*
+ * Versatile Express V2M Motherboard Support
+ */
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/smsc911x.h>
+#include <linux/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/usb/isp1760.h>
+#include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/mach-types.h>
+#include <asm/sizes.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
+#include <asm/hardware/sp810.h>
+
+#include <mach/ct-ca9x4.h>
+#include <mach/motherboard.h>
+
+#include <plat/sched_clock.h>
+
+#include "core.h"
+
+#define V2M_PA_CS0 0x40000000
+#define V2M_PA_CS1 0x44000000
+#define V2M_PA_CS2 0x48000000
+#define V2M_PA_CS3 0x4c000000
+#define V2M_PA_CS7 0x10000000
+
+static struct map_desc v2m_io_desc[] __initdata = {
+ {
+ .virtual = __MMIO_P2V(V2M_PA_CS7),
+ .pfn = __phys_to_pfn(V2M_PA_CS7),
+ .length = SZ_128K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init v2m_timer_init(void)
+{
+ u32 scctrl;
+
+ /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
+ scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
+ scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
+ scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
+ writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
+
+ writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
+ writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
+
+ sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1");
+ sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0,
+ "v2m-timer0");
+}
+
+static struct sys_timer v2m_timer = {
+ .init = v2m_timer_init,
+};
+
+
+static DEFINE_SPINLOCK(v2m_cfg_lock);
+
+int v2m_cfg_write(u32 devfn, u32 data)
+{
+ /* Configuration interface broken? */
+ u32 val;
+
+ printk("%s: writing %08x to %08x\n", __func__, data, devfn);
+
+ devfn |= SYS_CFG_START | SYS_CFG_WRITE;
+
+ spin_lock(&v2m_cfg_lock);
+ val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+ writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT));
+
+ writel(data, MMIO_P2V(V2M_SYS_CFGDATA));
+ writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+ do {
+ val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+ } while (val == 0);
+ spin_unlock(&v2m_cfg_lock);
+
+ return !!(val & SYS_CFG_ERR);
+}
+
+int v2m_cfg_read(u32 devfn, u32 *data)
+{
+ u32 val;
+
+ devfn |= SYS_CFG_START;
+
+ spin_lock(&v2m_cfg_lock);
+ writel(0, MMIO_P2V(V2M_SYS_CFGSTAT));
+ writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL));
+
+ mb();
+
+ do {
+ cpu_relax();
+ val = readl(MMIO_P2V(V2M_SYS_CFGSTAT));
+ } while (val == 0);
+
+ *data = readl(MMIO_P2V(V2M_SYS_CFGDATA));
+ spin_unlock(&v2m_cfg_lock);
+
+ return !!(val & SYS_CFG_ERR);
+}
+
+
+static struct resource v2m_pcie_i2c_resource = {
+ .start = V2M_SERIAL_BUS_PCI,
+ .end = V2M_SERIAL_BUS_PCI + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_pcie_i2c_device = {
+ .name = "versatile-i2c",
+ .id = 0,
+ .num_resources = 1,
+ .resource = &v2m_pcie_i2c_resource,
+};
+
+static struct resource v2m_ddc_i2c_resource = {
+ .start = V2M_SERIAL_BUS_DVI,
+ .end = V2M_SERIAL_BUS_DVI + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device v2m_ddc_i2c_device = {
+ .name = "versatile-i2c",
+ .id = 1,
+ .num_resources = 1,
+ .resource = &v2m_ddc_i2c_resource,
+};
+
+static struct resource v2m_eth_resources[] = {
+ {
+ .start = V2M_LAN9118,
+ .end = V2M_LAN9118 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_V2M_LAN9118,
+ .end = IRQ_V2M_LAN9118,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config v2m_eth_config = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device v2m_eth_device = {
+ .name = "smsc911x",
+ .id = -1,
+ .resource = v2m_eth_resources,
+ .num_resources = ARRAY_SIZE(v2m_eth_resources),
+ .dev.platform_data = &v2m_eth_config,
+};
+
+static struct resource v2m_usb_resources[] = {
+ {
+ .start = V2M_ISP1761,
+ .end = V2M_ISP1761 + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_V2M_ISP1761,
+ .end = IRQ_V2M_ISP1761,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct isp1760_platform_data v2m_usb_config = {
+ .is_isp1761 = true,
+ .bus_width_16 = false,
+ .port1_otg = true,
+ .analog_oc = false,
+ .dack_polarity_high = false,
+ .dreq_polarity_high = false,
+};
+
+static struct platform_device v2m_usb_device = {
+ .name = "isp1760",
+ .id = -1,
+ .resource = v2m_usb_resources,
+ .num_resources = ARRAY_SIZE(v2m_usb_resources),
+ .dev.platform_data = &v2m_usb_config,
+};
+
+static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
+{
+ writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
+}
+
+static struct physmap_flash_data v2m_flash_data = {
+ .width = 4,
+ .set_vpp = v2m_flash_set_vpp,
+};
+
+static struct resource v2m_flash_resources[] = {
+ {
+ .start = V2M_NOR0,
+ .end = V2M_NOR0 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = V2M_NOR1,
+ .end = V2M_NOR1 + SZ_64M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device v2m_flash_device = {
+ .name = "physmap-flash",
+ .id = -1,
+ .resource = v2m_flash_resources,
+ .num_resources = ARRAY_SIZE(v2m_flash_resources),
+ .dev.platform_data = &v2m_flash_data,
+};
+
+static struct pata_platform_info v2m_pata_data = {
+ .ioport_shift = 2,
+};
+
+static struct resource v2m_pata_resources[] = {
+ {
+ .start = V2M_CF,
+ .end = V2M_CF + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = V2M_CF + 0x100,
+ .end = V2M_CF + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device v2m_cf_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .resource = v2m_pata_resources,
+ .num_resources = ARRAY_SIZE(v2m_pata_resources),
+ .dev.platform_data = &v2m_pata_data,
+};
+
+static unsigned int v2m_mmci_status(struct device *dev)
+{
+ return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0);
+}
+
+static struct mmci_platform_data v2m_mmci_data = {
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .status = v2m_mmci_status,
+};
+
+static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL);
+static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data);
+static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL);
+static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL);
+static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
+static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
+static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
+static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
+static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL);
+static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL);
+
+static struct amba_device *v2m_amba_devs[] __initdata = {
+ &aaci_device,
+ &mmci_device,
+ &kmi0_device,
+ &kmi1_device,
+ &uart0_device,
+ &uart1_device,
+ &uart2_device,
+ &uart3_device,
+ &wdt_device,
+ &rtc_device,
+};
+
+
+static long v2m_osc_round(struct clk *clk, unsigned long rate)
+{
+ return rate;
+}
+
+static int v2m_osc1_set(struct clk *clk, unsigned long rate)
+{
+ return v2m_cfg_write(SYS_CFG_OSC | SYS_CFG_SITE_MB | 1, rate);
+}
+
+static const struct clk_ops osc1_clk_ops = {
+ .round = v2m_osc_round,
+ .set = v2m_osc1_set,
+};
+
+static struct clk osc1_clk = {
+ .ops = &osc1_clk_ops,
+ .rate = 24000000,
+};
+
+static struct clk osc2_clk = {
+ .rate = 24000000,
+};
+
+static struct clk v2m_sp804_clk = {
+ .rate = 1000000,
+};
+
+static struct clk dummy_apb_pclk;
+
+static struct clk_lookup v2m_lookups[] = {
+ { /* AMBA bus clock */
+ .con_id = "apb_pclk",
+ .clk = &dummy_apb_pclk,
+ }, { /* UART0 */
+ .dev_id = "mb:uart0",
+ .clk = &osc2_clk,
+ }, { /* UART1 */
+ .dev_id = "mb:uart1",
+ .clk = &osc2_clk,
+ }, { /* UART2 */
+ .dev_id = "mb:uart2",
+ .clk = &osc2_clk,
+ }, { /* UART3 */
+ .dev_id = "mb:uart3",
+ .clk = &osc2_clk,
+ }, { /* KMI0 */
+ .dev_id = "mb:kmi0",
+ .clk = &osc2_clk,
+ }, { /* KMI1 */
+ .dev_id = "mb:kmi1",
+ .clk = &osc2_clk,
+ }, { /* MMC0 */
+ .dev_id = "mb:mmci",
+ .clk = &osc2_clk,
+ }, { /* CLCD */
+ .dev_id = "mb:clcd",
+ .clk = &osc1_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .con_id = "v2m-timer0",
+ .clk = &v2m_sp804_clk,
+ }, { /* SP804 timers */
+ .dev_id = "sp804",
+ .con_id = "v2m-timer1",
+ .clk = &v2m_sp804_clk,
+ },
+};
+
+static void __init v2m_init_early(void)
+{
+ ct_desc->init_early();
+ clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+ versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
+}
+
+static void v2m_power_off(void)
+{
+ if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
+ printk(KERN_EMERG "Unable to shutdown\n");
+}
+
+static void v2m_restart(char str, const char *cmd)
+{
+ if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0))
+ printk(KERN_EMERG "Unable to reboot\n");
+}
+
+struct ct_desc *ct_desc;
+
+static struct ct_desc *ct_descs[] __initdata = {
+#ifdef CONFIG_ARCH_VEXPRESS_CA9X4
+ &ct_ca9x4_desc,
+#endif
+};
+
+static void __init v2m_populate_ct_desc(void)
+{
+ int i;
+ u32 current_tile_id;
+
+ ct_desc = NULL;
+ current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK;
+
+ for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
+ if (ct_descs[i]->id == current_tile_id)
+ ct_desc = ct_descs[i];
+
+ if (!ct_desc)
+ panic("vexpress: failed to populate core tile description "
+ "for tile ID 0x%8x\n", current_tile_id);
+}
+
+static void __init v2m_map_io(void)
+{
+ iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
+ v2m_populate_ct_desc();
+ ct_desc->map_io();
+}
+
+static void __init v2m_init_irq(void)
+{
+ ct_desc->init_irq();
+}
+
+static void __init v2m_init(void)
+{
+ int i;
+
+ platform_device_register(&v2m_pcie_i2c_device);
+ platform_device_register(&v2m_ddc_i2c_device);
+ platform_device_register(&v2m_flash_device);
+ platform_device_register(&v2m_cf_device);
+ platform_device_register(&v2m_eth_device);
+ platform_device_register(&v2m_usb_device);
+
+ for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++)
+ amba_device_register(v2m_amba_devs[i], &iomem_resource);
+
+ pm_power_off = v2m_power_off;
+ arm_pm_restart = v2m_restart;
+
+ ct_desc->init_tile();
+}
+
+MACHINE_START(VEXPRESS, "ARM-Versatile Express")
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
+ .map_io = v2m_map_io,
+ .init_early = v2m_init_early,
+ .init_irq = v2m_init_irq,
+ .timer = &v2m_timer,
+ .init_machine = v2m_init,
+MACHINE_END
diff --git a/arch/arm/mach-vt8500/Kconfig b/arch/arm/mach-vt8500/Kconfig
new file mode 100644
index 00000000..2c20a341
--- /dev/null
+++ b/arch/arm/mach-vt8500/Kconfig
@@ -0,0 +1,73 @@
+if ARCH_VT8500
+
+config VTWM_VERSION_VT8500
+ bool
+
+config VTWM_VERSION_WM8505
+ bool
+
+config MACH_BV07
+ bool "Benign BV07-8500 Mini Netbook"
+ depends on ARCH_VT8500
+ select VTWM_VERSION_VT8500
+ help
+ Add support for the inexpensive 7-inch netbooks sold by many
+ Chinese distributors under various names. Note that there are
+ many hardware implementations in identical exterior, make sure
+ that yours is indeed based on a VIA VT8500 chip.
+
+config MACH_WM8505_7IN_NETBOOK
+ bool "WM8505 7-inch generic netbook"
+ depends on ARCH_VT8500
+ select VTWM_VERSION_WM8505
+ help
+ Add support for the inexpensive 7-inch netbooks sold by many
+ Chinese distributors under various names. Note that there are
+ many hardware implementations in identical exterior, make sure
+ that yours is indeed based on a WonderMedia WM8505 chip.
+
+comment "LCD panel size"
+
+config WMT_PANEL_800X480
+ bool "7-inch with 800x480 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ default y
+ help
+ These are found in most of the netbooks in generic cases, as
+ well as in Eken M001 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=800x480' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_800X600
+ bool "8-inch with 800x600 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in Eken M003 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=800x600' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_1024X576
+ bool "10-inch with 1024x576 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in CherryPal netbooks and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=1024x576' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+config WMT_PANEL_1024X600
+ bool "10-inch with 1024x600 resolution"
+ depends on (FB_VT8500 || FB_WM8505)
+ help
+ These are found in Eken M006 tablets and possibly elsewhere.
+
+ To select this panel at runtime, say y here and append
+ 'panel=1024x600' to your kernel command line. Otherwise, the
+ largest one available will be used.
+
+endif
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
new file mode 100644
index 00000000..81aedb7c
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile
@@ -0,0 +1,9 @@
+obj-y += devices.o gpio.o irq.o timer.o
+
+obj-$(CONFIG_VTWM_VERSION_VT8500) += devices-vt8500.o
+obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
+
+obj-$(CONFIG_MACH_BV07) += bv07.o
+obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-vt8500/Makefile.boot b/arch/arm/mach-vt8500/Makefile.boot
new file mode 100644
index 00000000..a8acc4e2
--- /dev/null
+++ b/arch/arm/mach-vt8500/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+initrd_phys-y := 0x01000000
diff --git a/arch/arm/mach-vt8500/bv07.c b/arch/arm/mach-vt8500/bv07.c
new file mode 100644
index 00000000..94a261d8
--- /dev/null
+++ b/arch/arm/mach-vt8500/bv07.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-vt8500/bv07.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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/io.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "devices.h"
+
+static void __iomem *pmc_hiber;
+
+static struct platform_device *devices[] __initdata = {
+ &vt8500_device_uart0,
+ &vt8500_device_lcdc,
+ &vt8500_device_ehci,
+ &vt8500_device_ge_rops,
+ &vt8500_device_pwm,
+ &vt8500_device_pwmbl,
+ &vt8500_device_rtc,
+};
+
+static void vt8500_power_off(void)
+{
+ local_irq_disable();
+ writew(5, pmc_hiber);
+ asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+void __init bv07_init(void)
+{
+#ifdef CONFIG_FB_VT8500
+ void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
+ if (gpio_mux_reg) {
+ writel(readl(gpio_mux_reg) | 1, gpio_mux_reg);
+ iounmap(gpio_mux_reg);
+ } else {
+ printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
+ }
+#endif
+ pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
+ if (pmc_hiber)
+ pm_power_off = &vt8500_power_off;
+ else
+ printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
+
+ vt8500_set_resources();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ vt8500_gpio_init();
+}
+
+MACHINE_START(BV07, "Benign BV07 Mini Netbook")
+ .boot_params = 0x00000100,
+ .reserve = vt8500_reserve_mem,
+ .map_io = vt8500_map_io,
+ .init_irq = vt8500_init_irq,
+ .timer = &vt8500_timer,
+ .init_machine = bv07_init,
+MACHINE_END
diff --git a/arch/arm/mach-vt8500/devices-vt8500.c b/arch/arm/mach-vt8500/devices-vt8500.c
new file mode 100644
index 00000000..19519aee
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-vt8500.c
@@ -0,0 +1,91 @@
+/* linux/arch/arm/mach-vt8500/devices-vt8500.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <mach/vt8500_regs.h>
+#include <mach/vt8500_irqs.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+void __init vt8500_set_resources(void)
+{
+ struct resource tmp[3];
+
+ tmp[0] = wmt_mmio_res(VT8500_LCDC_BASE, SZ_1K);
+ tmp[1] = wmt_irq_res(IRQ_LCDC);
+ wmt_res_add(&vt8500_device_lcdc, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_UART0_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART0);
+ wmt_res_add(&vt8500_device_uart0, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_UART1_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART1);
+ wmt_res_add(&vt8500_device_uart1, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_UART2_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART2);
+ wmt_res_add(&vt8500_device_uart2, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_UART3_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART3);
+ wmt_res_add(&vt8500_device_uart3, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_EHCI_BASE, SZ_512);
+ tmp[1] = wmt_irq_res(IRQ_EHCI);
+ wmt_res_add(&vt8500_device_ehci, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(VT8500_GEGEA_BASE, SZ_256);
+ wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
+
+ tmp[0] = wmt_mmio_res(VT8500_PWM_BASE, 0x44);
+ wmt_res_add(&vt8500_device_pwm, tmp, 1);
+
+ tmp[0] = wmt_mmio_res(VT8500_RTC_BASE, 0x2c);
+ tmp[1] = wmt_irq_res(IRQ_RTC);
+ tmp[2] = wmt_irq_res(IRQ_RTCSM);
+ wmt_res_add(&vt8500_device_rtc, tmp, 3);
+}
+
+static void __init vt8500_set_externs(void)
+{
+ /* Non-resource-aware stuff */
+ wmt_ic_base = VT8500_IC_BASE;
+ wmt_gpio_base = VT8500_GPIO_BASE;
+ wmt_pmc_base = VT8500_PMC_BASE;
+ wmt_i8042_base = VT8500_PS2_BASE;
+
+ wmt_nr_irqs = VT8500_NR_IRQS;
+ wmt_timer_irq = IRQ_PMCOS0;
+ wmt_gpio_ext_irq[0] = IRQ_EXT0;
+ wmt_gpio_ext_irq[1] = IRQ_EXT1;
+ wmt_gpio_ext_irq[2] = IRQ_EXT2;
+ wmt_gpio_ext_irq[3] = IRQ_EXT3;
+ wmt_gpio_ext_irq[4] = IRQ_EXT4;
+ wmt_gpio_ext_irq[5] = IRQ_EXT5;
+ wmt_gpio_ext_irq[6] = IRQ_EXT6;
+ wmt_gpio_ext_irq[7] = IRQ_EXT7;
+ wmt_i8042_kbd_irq = IRQ_PS2KBD;
+ wmt_i8042_aux_irq = IRQ_PS2MOUSE;
+}
+
+void __init vt8500_map_io(void)
+{
+ iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
+
+ /* Should be done before interrupts and timers are initialized */
+ vt8500_set_externs();
+}
diff --git a/arch/arm/mach-vt8500/devices-wm8505.c b/arch/arm/mach-vt8500/devices-wm8505.c
new file mode 100644
index 00000000..db4594e0
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices-wm8505.c
@@ -0,0 +1,99 @@
+/* linux/arch/arm/mach-vt8500/devices-wm8505.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+
+#include <mach/wm8505_regs.h>
+#include <mach/wm8505_irqs.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+void __init wm8505_set_resources(void)
+{
+ struct resource tmp[3];
+
+ tmp[0] = wmt_mmio_res(WM8505_GOVR_BASE, SZ_512);
+ wmt_res_add(&vt8500_device_wm8505_fb, tmp, 1);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART0_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART0);
+ wmt_res_add(&vt8500_device_uart0, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART1_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART1);
+ wmt_res_add(&vt8500_device_uart1, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART2_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART2);
+ wmt_res_add(&vt8500_device_uart2, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART3_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART3);
+ wmt_res_add(&vt8500_device_uart3, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART4_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART4);
+ wmt_res_add(&vt8500_device_uart4, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_UART5_BASE, 0x1040);
+ tmp[1] = wmt_irq_res(IRQ_UART5);
+ wmt_res_add(&vt8500_device_uart5, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_EHCI_BASE, SZ_512);
+ tmp[1] = wmt_irq_res(IRQ_EHCI);
+ wmt_res_add(&vt8500_device_ehci, tmp, 2);
+
+ tmp[0] = wmt_mmio_res(WM8505_GEGEA_BASE, SZ_256);
+ wmt_res_add(&vt8500_device_ge_rops, tmp, 1);
+
+ tmp[0] = wmt_mmio_res(WM8505_PWM_BASE, 0x44);
+ wmt_res_add(&vt8500_device_pwm, tmp, 1);
+
+ tmp[0] = wmt_mmio_res(WM8505_RTC_BASE, 0x2c);
+ tmp[1] = wmt_irq_res(IRQ_RTC);
+ tmp[2] = wmt_irq_res(IRQ_RTCSM);
+ wmt_res_add(&vt8500_device_rtc, tmp, 3);
+}
+
+static void __init wm8505_set_externs(void)
+{
+ /* Non-resource-aware stuff */
+ wmt_ic_base = WM8505_IC_BASE;
+ wmt_sic_base = WM8505_SIC_BASE;
+ wmt_gpio_base = WM8505_GPIO_BASE;
+ wmt_pmc_base = WM8505_PMC_BASE;
+ wmt_i8042_base = WM8505_PS2_BASE;
+
+ wmt_nr_irqs = WM8505_NR_IRQS;
+ wmt_timer_irq = IRQ_PMCOS0;
+ wmt_gpio_ext_irq[0] = IRQ_EXT0;
+ wmt_gpio_ext_irq[1] = IRQ_EXT1;
+ wmt_gpio_ext_irq[2] = IRQ_EXT2;
+ wmt_gpio_ext_irq[3] = IRQ_EXT3;
+ wmt_gpio_ext_irq[4] = IRQ_EXT4;
+ wmt_gpio_ext_irq[5] = IRQ_EXT5;
+ wmt_gpio_ext_irq[6] = IRQ_EXT6;
+ wmt_gpio_ext_irq[7] = IRQ_EXT7;
+ wmt_i8042_kbd_irq = IRQ_PS2KBD;
+ wmt_i8042_aux_irq = IRQ_PS2MOUSE;
+}
+
+void __init wm8505_map_io(void)
+{
+ iotable_init(wmt_io_desc, ARRAY_SIZE(wmt_io_desc));
+
+ /* Should be done before interrupts and timers are initialized */
+ wm8505_set_externs();
+}
diff --git a/arch/arm/mach-vt8500/devices.c b/arch/arm/mach-vt8500/devices.c
new file mode 100644
index 00000000..1fcdc36b
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.c
@@ -0,0 +1,270 @@
+/* linux/arch/arm/mach-vt8500/devices.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/pwm_backlight.h>
+#include <linux/memblock.h>
+
+#include <asm/mach/arch.h>
+
+#include <mach/vt8500fb.h>
+#include <mach/i8042.h>
+#include "devices.h"
+
+/* These can't use resources currently */
+unsigned long wmt_ic_base __initdata;
+unsigned long wmt_sic_base __initdata;
+unsigned long wmt_gpio_base __initdata;
+unsigned long wmt_pmc_base __initdata;
+unsigned long wmt_i8042_base __initdata;
+
+int wmt_nr_irqs __initdata;
+int wmt_timer_irq __initdata;
+int wmt_gpio_ext_irq[8] __initdata;
+
+/* Should remain accessible after init.
+ * i8042 driver desperately calls for attention...
+ */
+int wmt_i8042_kbd_irq;
+int wmt_i8042_aux_irq;
+
+static u64 fb_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device vt8500_device_lcdc = {
+ .name = "vt8500-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &fb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device vt8500_device_wm8505_fb = {
+ .name = "wm8505-fb",
+ .id = 0,
+};
+
+/* Smallest to largest */
+static struct vt8500fb_platform_data panels[] = {
+#ifdef CONFIG_WMT_PANEL_800X480
+{
+ .xres_virtual = 800,
+ .yres_virtual = 480 * 2,
+ .mode = {
+ .name = "800x480",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 0,
+ .vsync_len = 1,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_800X600
+{
+ .xres_virtual = 800,
+ .yres_virtual = 600 * 2,
+ .mode = {
+ .name = "800x600",
+ .xres = 800,
+ .yres = 600,
+ .left_margin = 88,
+ .right_margin = 40,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 0,
+ .vsync_len = 1,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_1024X576
+{
+ .xres_virtual = 1024,
+ .yres_virtual = 576 * 2,
+ .mode = {
+ .name = "1024x576",
+ .xres = 1024,
+ .yres = 576,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+},
+#endif
+#ifdef CONFIG_WMT_PANEL_1024X600
+{
+ .xres_virtual = 1024,
+ .yres_virtual = 600 * 2,
+ .mode = {
+ .name = "1024x600",
+ .xres = 1024,
+ .yres = 600,
+ .left_margin = 66,
+ .right_margin = 2,
+ .upper_margin = 19,
+ .lower_margin = 1,
+ .hsync_len = 23,
+ .vsync_len = 8,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+},
+#endif
+};
+
+static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
+
+static int __init panel_setup(char *str)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(panels); i++) {
+ if (strcmp(panels[i].mode.name, str) == 0) {
+ current_panel_idx = i;
+ break;
+ }
+ }
+ return 0;
+}
+
+early_param("panel", panel_setup);
+
+static inline void preallocate_fb(struct vt8500fb_platform_data *p,
+ unsigned long align) {
+ p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
+ (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
+ (8 / p->bpp) + 1));
+ p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
+ align);
+ p->video_mem_virt = phys_to_virt(p->video_mem_phys);
+}
+
+struct platform_device vt8500_device_uart0 = {
+ .name = "vt8500_serial",
+ .id = 0,
+};
+
+struct platform_device vt8500_device_uart1 = {
+ .name = "vt8500_serial",
+ .id = 1,
+};
+
+struct platform_device vt8500_device_uart2 = {
+ .name = "vt8500_serial",
+ .id = 2,
+};
+
+struct platform_device vt8500_device_uart3 = {
+ .name = "vt8500_serial",
+ .id = 3,
+};
+
+struct platform_device vt8500_device_uart4 = {
+ .name = "vt8500_serial",
+ .id = 4,
+};
+
+struct platform_device vt8500_device_uart5 = {
+ .name = "vt8500_serial",
+ .id = 5,
+};
+
+static u64 ehci_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device vt8500_device_ehci = {
+ .name = "vt8500-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+struct platform_device vt8500_device_ge_rops = {
+ .name = "wmt_ge_rops",
+ .id = -1,
+};
+
+struct platform_device vt8500_device_pwm = {
+ .name = "vt8500-pwm",
+ .id = 0,
+};
+
+static struct platform_pwm_backlight_data vt8500_pwmbl_data = {
+ .pwm_id = 0,
+ .max_brightness = 128,
+ .dft_brightness = 70,
+ .pwm_period_ns = 250000, /* revisit when clocks are implemented */
+};
+
+struct platform_device vt8500_device_pwmbl = {
+ .name = "pwm-backlight",
+ .id = 0,
+ .dev = {
+ .platform_data = &vt8500_pwmbl_data,
+ },
+};
+
+struct platform_device vt8500_device_rtc = {
+ .name = "vt8500-rtc",
+ .id = 0,
+};
+
+struct map_desc wmt_io_desc[] __initdata = {
+ /* SoC MMIO registers */
+ [0] = {
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0xd8000000),
+ .length = 0x00390000, /* max of all chip variants */
+ .type = MT_DEVICE
+ },
+ /* PCI I/O space, numbers tied to those in <mach/io.h> */
+ [1] = {
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(0xc0000000),
+ .length = SZ_64K,
+ .type = MT_DEVICE
+ },
+};
+
+void __init vt8500_reserve_mem(void)
+{
+#ifdef CONFIG_FB_VT8500
+ panels[current_panel_idx].bpp = 16; /* Always use RGB565 */
+ preallocate_fb(&panels[current_panel_idx], SZ_4M);
+ vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx];
+#endif
+}
+
+void __init wm8505_reserve_mem(void)
+{
+#if defined CONFIG_FB_WM8505
+ panels[current_panel_idx].bpp = 32; /* Always use RGB888 */
+ preallocate_fb(&panels[current_panel_idx], 32);
+ vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx];
+#endif
+}
diff --git a/arch/arm/mach-vt8500/devices.h b/arch/arm/mach-vt8500/devices.h
new file mode 100644
index 00000000..188d4e17
--- /dev/null
+++ b/arch/arm/mach-vt8500/devices.h
@@ -0,0 +1,88 @@
+/* linux/arch/arm/mach-vt8500/devices.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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_VT8500_DEVICES_H
+#define __ARCH_ARM_MACH_VT8500_DEVICES_H
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+
+void __init vt8500_init_irq(void);
+void __init wm8505_init_irq(void);
+void __init vt8500_map_io(void);
+void __init wm8505_map_io(void);
+void __init vt8500_reserve_mem(void);
+void __init wm8505_reserve_mem(void);
+void __init vt8500_gpio_init(void);
+void __init vt8500_set_resources(void);
+void __init wm8505_set_resources(void);
+
+extern unsigned long wmt_ic_base __initdata;
+extern unsigned long wmt_sic_base __initdata;
+extern unsigned long wmt_gpio_base __initdata;
+extern unsigned long wmt_pmc_base __initdata;
+
+extern int wmt_nr_irqs __initdata;
+extern int wmt_timer_irq __initdata;
+extern int wmt_gpio_ext_irq[8] __initdata;
+
+extern struct map_desc wmt_io_desc[2] __initdata;
+
+static inline struct resource wmt_mmio_res(u32 start, u32 size)
+{
+ struct resource tmp = {
+ .flags = IORESOURCE_MEM,
+ .start = start,
+ .end = start + size - 1,
+ };
+
+ return tmp;
+}
+
+static inline struct resource wmt_irq_res(int irq)
+{
+ struct resource tmp = {
+ .flags = IORESOURCE_IRQ,
+ .start = irq,
+ .end = irq,
+ };
+
+ return tmp;
+}
+
+static inline void wmt_res_add(struct platform_device *pdev,
+ const struct resource *res, unsigned int num)
+{
+ if (unlikely(platform_device_add_resources(pdev, res, num)))
+ pr_err("Failed to assign resources\n");
+}
+
+extern struct sys_timer vt8500_timer;
+
+extern struct platform_device vt8500_device_uart0;
+extern struct platform_device vt8500_device_uart1;
+extern struct platform_device vt8500_device_uart2;
+extern struct platform_device vt8500_device_uart3;
+extern struct platform_device vt8500_device_uart4;
+extern struct platform_device vt8500_device_uart5;
+
+extern struct platform_device vt8500_device_lcdc;
+extern struct platform_device vt8500_device_wm8505_fb;
+extern struct platform_device vt8500_device_ehci;
+extern struct platform_device vt8500_device_ge_rops;
+extern struct platform_device vt8500_device_pwm;
+extern struct platform_device vt8500_device_pwmbl;
+extern struct platform_device vt8500_device_rtc;
+#endif
diff --git a/arch/arm/mach-vt8500/gpio.c b/arch/arm/mach-vt8500/gpio.c
new file mode 100644
index 00000000..2bcc0ec7
--- /dev/null
+++ b/arch/arm/mach-vt8500/gpio.c
@@ -0,0 +1,240 @@
+/* linux/arch/arm/mach-vt8500/gpio.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include "devices.h"
+
+#define to_vt8500(__chip) container_of(__chip, struct vt8500_gpio_chip, chip)
+
+#define ENABLE_REGS 0x0
+#define DIRECTION_REGS 0x20
+#define OUTVALUE_REGS 0x40
+#define INVALUE_REGS 0x60
+
+#define EXT_REGOFF 0x1c
+
+static void __iomem *regbase;
+
+struct vt8500_gpio_chip {
+ struct gpio_chip chip;
+ unsigned int shift;
+ unsigned int regoff;
+};
+
+static int gpio_to_irq_map[8];
+
+static int vt8500_muxed_gpio_request(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+ unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+ val |= (1 << vt8500_chip->shift << offset);
+ writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+ return 0;
+}
+
+static void vt8500_muxed_gpio_free(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+ unsigned val = readl(regbase + ENABLE_REGS + vt8500_chip->regoff);
+
+ val &= ~(1 << vt8500_chip->shift << offset);
+ writel(val, regbase + ENABLE_REGS + vt8500_chip->regoff);
+}
+
+static int vt8500_muxed_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+ unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+ val &= ~(1 << vt8500_chip->shift << offset);
+ writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+ return 0;
+}
+
+static int vt8500_muxed_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+ unsigned val = readl(regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+ val |= (1 << vt8500_chip->shift << offset);
+ writel(val, regbase + DIRECTION_REGS + vt8500_chip->regoff);
+
+ if (value) {
+ val = readl(regbase + OUTVALUE_REGS + vt8500_chip->regoff);
+ val |= (1 << vt8500_chip->shift << offset);
+ writel(val, regbase + OUTVALUE_REGS + vt8500_chip->regoff);
+ }
+ return 0;
+}
+
+static int vt8500_muxed_gpio_get_value(struct gpio_chip *chip,
+ unsigned offset)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+
+ return (readl(regbase + INVALUE_REGS + vt8500_chip->regoff)
+ >> vt8500_chip->shift >> offset) & 1;
+}
+
+static void vt8500_muxed_gpio_set_value(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct vt8500_gpio_chip *vt8500_chip = to_vt8500(chip);
+ unsigned val = readl(regbase + INVALUE_REGS + vt8500_chip->regoff);
+
+ if (value)
+ val |= (1 << vt8500_chip->shift << offset);
+ else
+ val &= ~(1 << vt8500_chip->shift << offset);
+
+ writel(val, regbase + INVALUE_REGS + vt8500_chip->regoff);
+}
+
+#define VT8500_GPIO_BANK(__name, __shift, __off, __base, __num) \
+{ \
+ .chip = { \
+ .label = __name, \
+ .request = vt8500_muxed_gpio_request, \
+ .free = vt8500_muxed_gpio_free, \
+ .direction_input = vt8500_muxed_gpio_direction_input, \
+ .direction_output = vt8500_muxed_gpio_direction_output, \
+ .get = vt8500_muxed_gpio_get_value, \
+ .set = vt8500_muxed_gpio_set_value, \
+ .can_sleep = 0, \
+ .base = __base, \
+ .ngpio = __num, \
+ }, \
+ .shift = __shift, \
+ .regoff = __off, \
+}
+
+static struct vt8500_gpio_chip vt8500_muxed_gpios[] = {
+ VT8500_GPIO_BANK("uart0", 0, 0x0, 8, 4),
+ VT8500_GPIO_BANK("uart1", 4, 0x0, 12, 4),
+ VT8500_GPIO_BANK("spi0", 8, 0x0, 16, 4),
+ VT8500_GPIO_BANK("spi1", 12, 0x0, 20, 4),
+ VT8500_GPIO_BANK("spi2", 16, 0x0, 24, 4),
+ VT8500_GPIO_BANK("pwmout", 24, 0x0, 28, 2),
+
+ VT8500_GPIO_BANK("sdmmc", 0, 0x4, 30, 11),
+ VT8500_GPIO_BANK("ms", 16, 0x4, 41, 7),
+ VT8500_GPIO_BANK("i2c0", 24, 0x4, 48, 2),
+ VT8500_GPIO_BANK("i2c1", 26, 0x4, 50, 2),
+
+ VT8500_GPIO_BANK("mii", 0, 0x8, 52, 20),
+ VT8500_GPIO_BANK("see", 20, 0x8, 72, 4),
+ VT8500_GPIO_BANK("ide", 24, 0x8, 76, 7),
+
+ VT8500_GPIO_BANK("ccir", 0, 0xc, 83, 19),
+
+ VT8500_GPIO_BANK("ts", 8, 0x10, 102, 11),
+
+ VT8500_GPIO_BANK("lcd", 0, 0x14, 113, 23),
+};
+
+static int vt8500_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
+
+ val &= ~(1 << offset);
+ writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
+ return 0;
+}
+
+static int vt8500_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned val = readl(regbase + DIRECTION_REGS + EXT_REGOFF);
+
+ val |= (1 << offset);
+ writel(val, regbase + DIRECTION_REGS + EXT_REGOFF);
+
+ if (value) {
+ val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
+ val |= (1 << offset);
+ writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
+ }
+ return 0;
+}
+
+static int vt8500_gpio_get_value(struct gpio_chip *chip,
+ unsigned offset)
+{
+ return (readl(regbase + INVALUE_REGS + EXT_REGOFF) >> offset) & 1;
+}
+
+static void vt8500_gpio_set_value(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ unsigned val = readl(regbase + OUTVALUE_REGS + EXT_REGOFF);
+
+ if (value)
+ val |= (1 << offset);
+ else
+ val &= ~(1 << offset);
+
+ writel(val, regbase + OUTVALUE_REGS + EXT_REGOFF);
+}
+
+static int vt8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset > 7)
+ return -EINVAL;
+
+ return gpio_to_irq_map[offset];
+}
+
+static struct gpio_chip vt8500_external_gpios = {
+ .label = "extgpio",
+ .direction_input = vt8500_gpio_direction_input,
+ .direction_output = vt8500_gpio_direction_output,
+ .get = vt8500_gpio_get_value,
+ .set = vt8500_gpio_set_value,
+ .to_irq = vt8500_gpio_to_irq,
+ .can_sleep = 0,
+ .base = 0,
+ .ngpio = 8,
+};
+
+void __init vt8500_gpio_init(void)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ gpio_to_irq_map[i] = wmt_gpio_ext_irq[i];
+
+ regbase = ioremap(wmt_gpio_base, SZ_64K);
+ if (!regbase) {
+ printk(KERN_ERR "Failed to map MMIO registers for GPIO\n");
+ return;
+ }
+
+ gpiochip_add(&vt8500_external_gpios);
+
+ for (i = 0; i < ARRAY_SIZE(vt8500_muxed_gpios); i++)
+ gpiochip_add(&vt8500_muxed_gpios[i].chip);
+}
diff --git a/arch/arm/mach-vt8500/include/mach/debug-macro.S b/arch/arm/mach-vt8500/include/mach/debug-macro.S
new file mode 100644
index 00000000..f1191626
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/debug-macro.S
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * Debugging macro include 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.
+ *
+*/
+
+ .macro addruart, rp, rv
+ mov \rp, #0x00200000
+ orr \rv, \rp, #0xf8000000
+ orr \rp, \rp, #0xd8000000
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0]
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x1c]
+ ands \rd, \rd, #0x2
+ bne 1001b
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
diff --git a/arch/arm/mach-vt8500/include/mach/entry-macro.S b/arch/arm/mach-vt8500/include/mach/entry-macro.S
new file mode 100644
index 00000000..92684c7e
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/entry-macro.S
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for VIA VT8500
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ physical 0xd8140000 is virtual 0xf8140000
+ mov \base, #0xf8000000
+ orr \base, \base, #0x00140000
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base]
+ cmp \irqnr, #63 @ may be false positive, check interrupt status
+ bne 1001f
+ ldr \irqstat, [\base, #0x84]
+ ands \irqstat, #0x80000000
+ moveq \irqnr, #0
+1001:
+ .endm
+
diff --git a/arch/arm/mach-vt8500/include/mach/gpio.h b/arch/arm/mach-vt8500/include/mach/gpio.h
new file mode 100644
index 00000000..94ff2767
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/gpio.h
@@ -0,0 +1,6 @@
+#include <asm-generic/gpio.h>
+
+#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
diff --git a/arch/arm/mach-vt8500/include/mach/hardware.h b/arch/arm/mach-vt8500/include/mach/hardware.h
new file mode 100644
index 00000000..db4163f7
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/hardware.h
@@ -0,0 +1,12 @@
+/* arch/arm/mach-vt8500/include/mach/hardware.h
+ *
+ * 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.
+ *
+ */
diff --git a/arch/arm/mach-vt8500/include/mach/i8042.h b/arch/arm/mach-vt8500/include/mach/i8042.h
new file mode 100644
index 00000000..cd7143ca
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/i8042.h
@@ -0,0 +1,18 @@
+/* arch/arm/mach-vt8500/include/mach/i8042.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+extern unsigned long wmt_i8042_base __initdata;
+extern int wmt_i8042_kbd_irq;
+extern int wmt_i8042_aux_irq;
diff --git a/arch/arm/mach-vt8500/include/mach/io.h b/arch/arm/mach-vt8500/include/mach/io.h
new file mode 100644
index 00000000..9077239f
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/io.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/io.h
+ *
+ * Copyright (C) 2010 Alexey Charkov
+ *
+ * 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 __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffff
+
+#define __io(a) __typesafe_io((a) + 0xf0000000)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/irqs.h b/arch/arm/mach-vt8500/include/mach/irqs.h
new file mode 100644
index 00000000..a129fd12
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/irqs.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/irqs.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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
+ */
+
+/* This value is just to make the core happy, never used otherwise */
+#define NR_IRQS 128
diff --git a/arch/arm/mach-vt8500/include/mach/memory.h b/arch/arm/mach-vt8500/include/mach/memory.h
new file mode 100644
index 00000000..175f914e
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/memory.h
+ *
+ * Copyright (C) 2003 ARM Limited
+ *
+ * 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 __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h
new file mode 100644
index 00000000..d6c757ea
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/system.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/system.h
+ *
+ */
+#include <asm/io.h>
+
+/* PM Software Reset request register */
+#define VT8500_PMSR_VIRT 0xf8130060
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ writel(1, VT8500_PMSR_VIRT);
+}
diff --git a/arch/arm/mach-vt8500/include/mach/timex.h b/arch/arm/mach-vt8500/include/mach/timex.h
new file mode 100644
index 00000000..8487e4c6
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/timex.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/timex.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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 MACH_TIMEX_H
+#define MACH_TIMEX_H
+
+#define CLOCK_TICK_RATE (3000000)
+
+#endif /* MACH_TIMEX_H */
diff --git a/arch/arm/mach-vt8500/include/mach/uncompress.h b/arch/arm/mach-vt8500/include/mach/uncompress.h
new file mode 100644
index 00000000..bb9e2d23
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/uncompress.h
@@ -0,0 +1,37 @@
+/* arch/arm/mach-vt8500/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * Based on arch/arm/mach-dove/include/mach/uncompress.h
+ *
+ * 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.
+ *
+ */
+
+#define UART0_PHYS 0xd8200000
+#include <asm/io.h>
+
+static void putc(const char c)
+{
+ while (readb(UART0_PHYS + 0x1c) & 0x2)
+ /* Tx busy, wait and poll */;
+
+ writeb(c, UART0_PHYS);
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-vt8500/include/mach/vmalloc.h b/arch/arm/mach-vt8500/include/mach/vmalloc.h
new file mode 100644
index 00000000..4642290c
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vmalloc.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2000 Russell King.
+ *
+ * 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
+ */
+#define VMALLOC_END 0xd0000000UL
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
new file mode 100644
index 00000000..ecfee912
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/vt8500_irqs.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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
+ */
+
+/* VT8500 Interrupt Sources */
+
+#define IRQ_JPEGENC 0 /* JPEG Encoder */
+#define IRQ_JPEGDEC 1 /* JPEG Decoder */
+ /* Reserved */
+#define IRQ_PATA 3 /* PATA Controller */
+ /* Reserved */
+#define IRQ_DMA 5 /* DMA Controller */
+#define IRQ_EXT0 6 /* External Interrupt 0 */
+#define IRQ_EXT1 7 /* External Interrupt 1 */
+#define IRQ_GE 8 /* Graphic Engine */
+#define IRQ_GOV 9 /* Graphic Overlay Engine */
+#define IRQ_ETHER 10 /* Ethernet MAC */
+#define IRQ_MPEGTS 11 /* Transport Stream Interface */
+#define IRQ_LCDC 12 /* LCD Controller */
+#define IRQ_EXT2 13 /* External Interrupt 2 */
+#define IRQ_EXT3 14 /* External Interrupt 3 */
+#define IRQ_EXT4 15 /* External Interrupt 4 */
+#define IRQ_CIPHER 16 /* Cipher */
+#define IRQ_VPP 17 /* Video Post-Processor */
+#define IRQ_I2C1 18 /* I2C 1 */
+#define IRQ_I2C0 19 /* I2C 0 */
+#define IRQ_SDMMC 20 /* SD/MMC Controller */
+#define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */
+#define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */
+ /* Reserved */
+#define IRQ_SPI0 24 /* SPI 0 */
+#define IRQ_SPI1 25 /* SPI 1 */
+#define IRQ_SPI2 26 /* SPI 2 */
+#define IRQ_LCDDF 27 /* LCD Data Formatter */
+#define IRQ_NAND 28 /* NAND Flash Controller */
+#define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */
+#define IRQ_MS 30 /* MemoryStick Controller */
+#define IRQ_MS_DMA 31 /* MemoryStick Controller DMA */
+#define IRQ_UART0 32 /* UART 0 */
+#define IRQ_UART1 33 /* UART 1 */
+#define IRQ_I2S 34 /* I2S */
+#define IRQ_PCM 35 /* PCM */
+#define IRQ_PMCOS0 36 /* PMC OS Timer 0 */
+#define IRQ_PMCOS1 37 /* PMC OS Timer 1 */
+#define IRQ_PMCOS2 38 /* PMC OS Timer 2 */
+#define IRQ_PMCOS3 39 /* PMC OS Timer 3 */
+#define IRQ_VPU 40 /* Video Processing Unit */
+#define IRQ_VID 41 /* Video Digital Input Interface */
+#define IRQ_AC97 42 /* AC97 Interface */
+#define IRQ_EHCI 43 /* USB */
+#define IRQ_NOR 44 /* NOR Flash Controller */
+#define IRQ_PS2MOUSE 45 /* PS/2 Mouse */
+#define IRQ_PS2KBD 46 /* PS/2 Keyboard */
+#define IRQ_UART2 47 /* UART 2 */
+#define IRQ_RTC 48 /* RTC Interrupt */
+#define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */
+#define IRQ_UART3 50 /* UART 3 */
+#define IRQ_ADC 51 /* ADC */
+#define IRQ_EXT5 52 /* External Interrupt 5 */
+#define IRQ_EXT6 53 /* External Interrupt 6 */
+#define IRQ_EXT7 54 /* External Interrupt 7 */
+#define IRQ_CIR 55 /* CIR */
+#define IRQ_DMA0 56 /* DMA Channel 0 */
+#define IRQ_DMA1 57 /* DMA Channel 1 */
+#define IRQ_DMA2 58 /* DMA Channel 2 */
+#define IRQ_DMA3 59 /* DMA Channel 3 */
+#define IRQ_DMA4 60 /* DMA Channel 4 */
+#define IRQ_DMA5 61 /* DMA Channel 5 */
+#define IRQ_DMA6 62 /* DMA Channel 6 */
+#define IRQ_DMA7 63 /* DMA Channel 7 */
+
+#define VT8500_NR_IRQS 64
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500_regs.h b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
new file mode 100644
index 00000000..29c63ecb
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500_regs.h
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/vt8500_regs.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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 __ASM_ARM_ARCH_VT8500_REGS_H
+#define __ASM_ARM_ARCH_VT8500_REGS_H
+
+/* VT8500 Registers Map */
+
+#define VT8500_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */
+#define VT8500_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */
+
+#define VT8500_DDR_BASE 0xd8000000 /* 1k DDR/DDR2 Memory
+ Controller */
+#define VT8500_DMA_BASE 0xd8001000 /* 1k DMA Controller */
+#define VT8500_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory
+ Controller */
+#define VT8500_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */
+#define VT8500_CIPHER_BASE 0xd8006000 /* 4k Cipher */
+#define VT8500_USB_BASE 0xd8007800 /* 2k USB OTG */
+# define VT8500_EHCI_BASE 0xd8007900 /* EHCI */
+# define VT8500_UHCI_BASE 0xd8007b01 /* UHCI */
+#define VT8500_PATA_BASE 0xd8008000 /* 512 PATA */
+#define VT8500_PS2_BASE 0xd8008800 /* 1k PS/2 */
+#define VT8500_NAND_BASE 0xd8009000 /* 1k NAND Controller */
+#define VT8500_NOR_BASE 0xd8009400 /* 1k NOR Controller */
+#define VT8500_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */
+#define VT8500_MS_BASE 0xd800b000 /* 1k MS/MSPRO Controller */
+#define VT8500_LCDC_BASE 0xd800e400 /* 1k LCD Controller */
+#define VT8500_VPU_BASE 0xd8050000 /* 256 VPU */
+#define VT8500_GOV_BASE 0xd8050300 /* 256 GOV */
+#define VT8500_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */
+#define VT8500_LCDF_BASE 0xd8050900 /* 256 LCD Formatter */
+#define VT8500_VID_BASE 0xd8050a00 /* 256 VID */
+#define VT8500_VPP_BASE 0xd8050b00 /* 256 VPP */
+#define VT8500_TSBK_BASE 0xd80f4000 /* 4k TSBK */
+#define VT8500_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */
+#define VT8500_JPEGENC_BASE 0xd80ff000 /* 4k JPEG Encoder */
+#define VT8500_RTC_BASE 0xd8100000 /* 64k RTC */
+#define VT8500_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */
+#define VT8500_SCC_BASE 0xd8120000 /* 64k System Configuration*/
+#define VT8500_PMC_BASE 0xd8130000 /* 64k PMC Configuration */
+#define VT8500_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/
+#define VT8500_UART0_BASE 0xd8200000 /* 64k UART 0 */
+#define VT8500_UART2_BASE 0xd8210000 /* 64k UART 2 */
+#define VT8500_PWM_BASE 0xd8220000 /* 64k PWM Configuration */
+#define VT8500_SPI0_BASE 0xd8240000 /* 64k SPI 0 */
+#define VT8500_SPI1_BASE 0xd8250000 /* 64k SPI 1 */
+#define VT8500_CIR_BASE 0xd8270000 /* 64k CIR */
+#define VT8500_I2C0_BASE 0xd8280000 /* 64k I2C 0 */
+#define VT8500_AC97_BASE 0xd8290000 /* 64k AC97 */
+#define VT8500_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */
+#define VT8500_UART1_BASE 0xd82b0000 /* 64k UART 1 */
+#define VT8500_UART3_BASE 0xd82c0000 /* 64k UART 3 */
+#define VT8500_PCM_BASE 0xd82d0000 /* 64k PCM */
+#define VT8500_I2C1_BASE 0xd8320000 /* 64k I2C 1 */
+#define VT8500_I2S_BASE 0xd8330000 /* 64k I2S */
+#define VT8500_ADC_BASE 0xd8340000 /* 64k ADC */
+
+#define VT8500_REGS_END_PHYS 0xd834ffff /* End of MMIO registers */
+#define VT8500_REGS_LENGTH (VT8500_REGS_END_PHYS \
+ - VT8500_REGS_START_PHYS + 1)
+
+#endif
diff --git a/arch/arm/mach-vt8500/include/mach/vt8500fb.h b/arch/arm/mach-vt8500/include/mach/vt8500fb.h
new file mode 100644
index 00000000..7f399c37
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/vt8500fb.h
@@ -0,0 +1,31 @@
+/*
+ * VT8500/WM8505 Frame Buffer platform data definitions
+ *
+ * Copyright (C) 2010 Ed Spiridonov <edo.rus@gmail.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 _VT8500FB_H
+#define _VT8500FB_H
+
+#include <linux/fb.h>
+
+struct vt8500fb_platform_data {
+ struct fb_videomode mode;
+ u32 xres_virtual;
+ u32 yres_virtual;
+ u32 bpp;
+ unsigned long video_mem_phys;
+ void *video_mem_virt;
+ unsigned long video_mem_len;
+};
+
+#endif /* _VT8500FB_H */
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
new file mode 100644
index 00000000..6128627a
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
@@ -0,0 +1,115 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/wm8505_irqs.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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
+ */
+
+/* WM8505 Interrupt Sources */
+
+#define IRQ_UHCI 0 /* UHC FS (UHCI?) */
+#define IRQ_EHCI 1 /* UHC HS */
+#define IRQ_UDCDMA 2 /* UDC DMA */
+ /* Reserved */
+#define IRQ_PS2MOUSE 4 /* PS/2 Mouse */
+#define IRQ_UDC 5 /* UDC */
+#define IRQ_EXT0 6 /* External Interrupt 0 */
+#define IRQ_EXT1 7 /* External Interrupt 1 */
+#define IRQ_KEYPAD 8 /* Keypad */
+#define IRQ_DMA 9 /* DMA Controller */
+#define IRQ_ETHER 10 /* Ethernet MAC */
+ /* Reserved */
+ /* Reserved */
+#define IRQ_EXT2 13 /* External Interrupt 2 */
+#define IRQ_EXT3 14 /* External Interrupt 3 */
+#define IRQ_EXT4 15 /* External Interrupt 4 */
+#define IRQ_APB 16 /* APB Bridge */
+#define IRQ_DMA0 17 /* DMA Channel 0 */
+#define IRQ_I2C1 18 /* I2C 1 */
+#define IRQ_I2C0 19 /* I2C 0 */
+#define IRQ_SDMMC 20 /* SD/MMC Controller */
+#define IRQ_SDMMC_DMA 21 /* SD/MMC Controller DMA */
+#define IRQ_PMC_WU 22 /* Power Management Controller Wakeup */
+#define IRQ_PS2KBD 23 /* PS/2 Keyboard */
+#define IRQ_SPI0 24 /* SPI 0 */
+#define IRQ_SPI1 25 /* SPI 1 */
+#define IRQ_SPI2 26 /* SPI 2 */
+#define IRQ_DMA1 27 /* DMA Channel 1 */
+#define IRQ_NAND 28 /* NAND Flash Controller */
+#define IRQ_NAND_DMA 29 /* NAND Flash Controller DMA */
+#define IRQ_UART5 30 /* UART 5 */
+#define IRQ_UART4 31 /* UART 4 */
+#define IRQ_UART0 32 /* UART 0 */
+#define IRQ_UART1 33 /* UART 1 */
+#define IRQ_DMA2 34 /* DMA Channel 2 */
+#define IRQ_I2S 35 /* I2S */
+#define IRQ_PMCOS0 36 /* PMC OS Timer 0 */
+#define IRQ_PMCOS1 37 /* PMC OS Timer 1 */
+#define IRQ_PMCOS2 38 /* PMC OS Timer 2 */
+#define IRQ_PMCOS3 39 /* PMC OS Timer 3 */
+#define IRQ_DMA3 40 /* DMA Channel 3 */
+#define IRQ_DMA4 41 /* DMA Channel 4 */
+#define IRQ_AC97 42 /* AC97 Interface */
+ /* Reserved */
+#define IRQ_NOR 44 /* NOR Flash Controller */
+#define IRQ_DMA5 45 /* DMA Channel 5 */
+#define IRQ_DMA6 46 /* DMA Channel 6 */
+#define IRQ_UART2 47 /* UART 2 */
+#define IRQ_RTC 48 /* RTC Interrupt */
+#define IRQ_RTCSM 49 /* RTC Second/Minute Update Interrupt */
+#define IRQ_UART3 50 /* UART 3 */
+#define IRQ_DMA7 51 /* DMA Channel 7 */
+#define IRQ_EXT5 52 /* External Interrupt 5 */
+#define IRQ_EXT6 53 /* External Interrupt 6 */
+#define IRQ_EXT7 54 /* External Interrupt 7 */
+#define IRQ_CIR 55 /* CIR */
+#define IRQ_SIC0 56 /* SIC IRQ0 */
+#define IRQ_SIC1 57 /* SIC IRQ1 */
+#define IRQ_SIC2 58 /* SIC IRQ2 */
+#define IRQ_SIC3 59 /* SIC IRQ3 */
+#define IRQ_SIC4 60 /* SIC IRQ4 */
+#define IRQ_SIC5 61 /* SIC IRQ5 */
+#define IRQ_SIC6 62 /* SIC IRQ6 */
+#define IRQ_SIC7 63 /* SIC IRQ7 */
+ /* Reserved */
+#define IRQ_JPEGDEC 65 /* JPEG Decoder */
+#define IRQ_SAE 66 /* SAE (?) */
+ /* Reserved */
+#define IRQ_VPU 79 /* Video Processing Unit */
+#define IRQ_VPP 80 /* Video Post-Processor */
+#define IRQ_VID 81 /* Video Digital Input Interface */
+#define IRQ_SPU 82 /* SPU (?) */
+#define IRQ_PIP 83 /* PIP Error */
+#define IRQ_GE 84 /* Graphic Engine */
+#define IRQ_GOV 85 /* Graphic Overlay Engine */
+#define IRQ_DVO 86 /* Digital Video Output */
+ /* Reserved */
+#define IRQ_DMA8 92 /* DMA Channel 8 */
+#define IRQ_DMA9 93 /* DMA Channel 9 */
+#define IRQ_DMA10 94 /* DMA Channel 10 */
+#define IRQ_DMA11 95 /* DMA Channel 11 */
+#define IRQ_DMA12 96 /* DMA Channel 12 */
+#define IRQ_DMA13 97 /* DMA Channel 13 */
+#define IRQ_DMA14 98 /* DMA Channel 14 */
+#define IRQ_DMA15 99 /* DMA Channel 15 */
+ /* Reserved */
+#define IRQ_GOVW 111 /* GOVW (?) */
+#define IRQ_GOVRSDSCD 112 /* GOVR SDSCD (?) */
+#define IRQ_GOVRSDMIF 113 /* GOVR SDMIF (?) */
+#define IRQ_GOVRHDSCD 114 /* GOVR HDSCD (?) */
+#define IRQ_GOVRHDMIF 115 /* GOVR HDMIF (?) */
+
+#define WM8505_NR_IRQS 116
diff --git a/arch/arm/mach-vt8500/include/mach/wm8505_regs.h b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
new file mode 100644
index 00000000..df155094
--- /dev/null
+++ b/arch/arm/mach-vt8500/include/mach/wm8505_regs.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-vt8500/include/mach/wm8505_regs.h
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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 __ASM_ARM_ARCH_WM8505_REGS_H
+#define __ASM_ARM_ARCH_WM8505_REGS_H
+
+/* WM8505 Registers Map */
+
+#define WM8505_REGS_START_PHYS 0xd8000000 /* Start of MMIO registers */
+#define WM8505_REGS_START_VIRT 0xf8000000 /* Virtual mapping start */
+
+#define WM8505_DDR_BASE 0xd8000400 /* 1k DDR/DDR2 Memory
+ Controller */
+#define WM8505_DMA_BASE 0xd8001800 /* 1k DMA Controller */
+#define WM8505_VDMA_BASE 0xd8001c00 /* 1k VDMA */
+#define WM8505_SFLASH_BASE 0xd8002000 /* 1k Serial Flash Memory
+ Controller */
+#define WM8505_ETHER_BASE 0xd8004000 /* 1k Ethernet MAC 0 */
+#define WM8505_CIPHER_BASE 0xd8006000 /* 4k Cipher */
+#define WM8505_USB_BASE 0xd8007000 /* 2k USB 2.0 Host */
+# define WM8505_EHCI_BASE 0xd8007100 /* EHCI */
+# define WM8505_UHCI_BASE 0xd8007301 /* UHCI */
+#define WM8505_PS2_BASE 0xd8008800 /* 1k PS/2 */
+#define WM8505_NAND_BASE 0xd8009000 /* 1k NAND Controller */
+#define WM8505_NOR_BASE 0xd8009400 /* 1k NOR Controller */
+#define WM8505_SDMMC_BASE 0xd800a000 /* 1k SD/MMC Controller */
+#define WM8505_VPU_BASE 0xd8050000 /* 256 VPU */
+#define WM8505_GOV_BASE 0xd8050300 /* 256 GOV */
+#define WM8505_GEGEA_BASE 0xd8050400 /* 768 GE/GE Alpha Mixing */
+#define WM8505_GOVR_BASE 0xd8050800 /* 512 GOVR (frambuffer) */
+#define WM8505_VID_BASE 0xd8050a00 /* 256 VID */
+#define WM8505_SCL_BASE 0xd8050d00 /* 256 SCL */
+#define WM8505_VPP_BASE 0xd8050f00 /* 256 VPP */
+#define WM8505_JPEGDEC_BASE 0xd80fe000 /* 4k JPEG Decoder */
+#define WM8505_RTC_BASE 0xd8100000 /* 64k RTC */
+#define WM8505_GPIO_BASE 0xd8110000 /* 64k GPIO Configuration */
+#define WM8505_SCC_BASE 0xd8120000 /* 64k System Configuration*/
+#define WM8505_PMC_BASE 0xd8130000 /* 64k PMC Configuration */
+#define WM8505_IC_BASE 0xd8140000 /* 64k Interrupt Controller*/
+#define WM8505_SIC_BASE 0xd8150000 /* 64k Secondary IC */
+#define WM8505_UART0_BASE 0xd8200000 /* 64k UART 0 */
+#define WM8505_UART2_BASE 0xd8210000 /* 64k UART 2 */
+#define WM8505_PWM_BASE 0xd8220000 /* 64k PWM Configuration */
+#define WM8505_SPI0_BASE 0xd8240000 /* 64k SPI 0 */
+#define WM8505_SPI1_BASE 0xd8250000 /* 64k SPI 1 */
+#define WM8505_KEYPAD_BASE 0xd8260000 /* 64k Keypad control */
+#define WM8505_CIR_BASE 0xd8270000 /* 64k CIR */
+#define WM8505_I2C0_BASE 0xd8280000 /* 64k I2C 0 */
+#define WM8505_AC97_BASE 0xd8290000 /* 64k AC97 */
+#define WM8505_SPI2_BASE 0xd82a0000 /* 64k SPI 2 */
+#define WM8505_UART1_BASE 0xd82b0000 /* 64k UART 1 */
+#define WM8505_UART3_BASE 0xd82c0000 /* 64k UART 3 */
+#define WM8505_I2C1_BASE 0xd8320000 /* 64k I2C 1 */
+#define WM8505_I2S_BASE 0xd8330000 /* 64k I2S */
+#define WM8505_UART4_BASE 0xd8370000 /* 64k UART 4 */
+#define WM8505_UART5_BASE 0xd8380000 /* 64k UART 5 */
+
+#define WM8505_REGS_END_PHYS 0xd838ffff /* End of MMIO registers */
+#define WM8505_REGS_LENGTH (WM8505_REGS_END_PHYS \
+ - WM8505_REGS_START_PHYS + 1)
+
+#endif
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
new file mode 100644
index 00000000..642de040
--- /dev/null
+++ b/arch/arm/mach-vt8500/irq.c
@@ -0,0 +1,180 @@
+/*
+ * arch/arm/mach-vt8500/irq.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/irq.h>
+
+#include "devices.h"
+
+#define VT8500_IC_DCTR 0x40 /* Destination control
+ register, 64*u8 */
+#define VT8500_INT_ENABLE (1 << 3)
+#define VT8500_TRIGGER_HIGH (0 << 4)
+#define VT8500_TRIGGER_RISING (1 << 4)
+#define VT8500_TRIGGER_FALLING (2 << 4)
+#define VT8500_EDGE ( VT8500_TRIGGER_RISING \
+ | VT8500_TRIGGER_FALLING)
+#define VT8500_IC_STATUS 0x80 /* Interrupt status, 2*u32 */
+
+static void __iomem *ic_regbase;
+static void __iomem *sic_regbase;
+
+static void vt8500_irq_mask(struct irq_data *d)
+{
+ void __iomem *base = ic_regbase;
+ unsigned irq = d->irq;
+ u8 edge;
+
+ if (irq >= 64) {
+ base = sic_regbase;
+ irq -= 64;
+ }
+ edge = readb(base + VT8500_IC_DCTR + irq) & VT8500_EDGE;
+ if (edge) {
+ void __iomem *stat_reg = base + VT8500_IC_STATUS
+ + (irq < 32 ? 0 : 4);
+ unsigned status = readl(stat_reg);
+
+ status |= (1 << (irq & 0x1f));
+ writel(status, stat_reg);
+ } else {
+ u8 dctr = readb(base + VT8500_IC_DCTR + irq);
+
+ dctr &= ~VT8500_INT_ENABLE;
+ writeb(dctr, base + VT8500_IC_DCTR + irq);
+ }
+}
+
+static void vt8500_irq_unmask(struct irq_data *d)
+{
+ void __iomem *base = ic_regbase;
+ unsigned irq = d->irq;
+ u8 dctr;
+
+ if (irq >= 64) {
+ base = sic_regbase;
+ irq -= 64;
+ }
+ dctr = readb(base + VT8500_IC_DCTR + irq);
+ dctr |= VT8500_INT_ENABLE;
+ writeb(dctr, base + VT8500_IC_DCTR + irq);
+}
+
+static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+ void __iomem *base = ic_regbase;
+ unsigned irq = d->irq;
+ unsigned orig_irq = irq;
+ u8 dctr;
+
+ if (irq >= 64) {
+ base = sic_regbase;
+ irq -= 64;
+ }
+
+ dctr = readb(base + VT8500_IC_DCTR + irq);
+ dctr &= ~VT8500_EDGE;
+
+ switch (flow_type) {
+ case IRQF_TRIGGER_LOW:
+ return -EINVAL;
+ case IRQF_TRIGGER_HIGH:
+ dctr |= VT8500_TRIGGER_HIGH;
+ __irq_set_handler_locked(orig_irq, handle_level_irq);
+ break;
+ case IRQF_TRIGGER_FALLING:
+ dctr |= VT8500_TRIGGER_FALLING;
+ __irq_set_handler_locked(orig_irq, handle_edge_irq);
+ break;
+ case IRQF_TRIGGER_RISING:
+ dctr |= VT8500_TRIGGER_RISING;
+ __irq_set_handler_locked(orig_irq, handle_edge_irq);
+ break;
+ }
+ writeb(dctr, base + VT8500_IC_DCTR + irq);
+
+ return 0;
+}
+
+static struct irq_chip vt8500_irq_chip = {
+ .name = "vt8500",
+ .irq_ack = vt8500_irq_mask,
+ .irq_mask = vt8500_irq_mask,
+ .irq_unmask = vt8500_irq_unmask,
+ .irq_set_type = vt8500_irq_set_type,
+};
+
+void __init vt8500_init_irq(void)
+{
+ unsigned int i;
+
+ ic_regbase = ioremap(wmt_ic_base, SZ_64K);
+
+ if (ic_regbase) {
+ /* Enable rotating priority for IRQ */
+ writel((1 << 6), ic_regbase + 0x20);
+ writel(0, ic_regbase + 0x24);
+
+ for (i = 0; i < wmt_nr_irqs; i++) {
+ /* Disable all interrupts and route them to IRQ */
+ writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
+
+ irq_set_chip_and_handler(i, &vt8500_irq_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ } else {
+ printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+ }
+}
+
+void __init wm8505_init_irq(void)
+{
+ unsigned int i;
+
+ ic_regbase = ioremap(wmt_ic_base, SZ_64K);
+ sic_regbase = ioremap(wmt_sic_base, SZ_64K);
+
+ if (ic_regbase && sic_regbase) {
+ /* Enable rotating priority for IRQ */
+ writel((1 << 6), ic_regbase + 0x20);
+ writel(0, ic_regbase + 0x24);
+ writel((1 << 6), sic_regbase + 0x20);
+ writel(0, sic_regbase + 0x24);
+
+ for (i = 0; i < wmt_nr_irqs; i++) {
+ /* Disable all interrupts and route them to IRQ */
+ if (i < 64)
+ writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
+ else
+ writeb(0x00, sic_regbase + VT8500_IC_DCTR
+ + i - 64);
+
+ irq_set_chip_and_handler(i, &vt8500_irq_chip,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ } else {
+ printk(KERN_ERR "Unable to remap the Interrupt Controller registers, not enabling IRQs!\n");
+ }
+}
diff --git a/arch/arm/mach-vt8500/pwm.c b/arch/arm/mach-vt8500/pwm.c
new file mode 100644
index 00000000..8ad825e9
--- /dev/null
+++ b/arch/arm/mach-vt8500/pwm.c
@@ -0,0 +1,265 @@
+/*
+ * arch/arm/mach-vt8500/pwm.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+#include <linux/delay.h>
+
+#include <asm/div64.h>
+
+#define VT8500_NR_PWMS 4
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device {
+ struct list_head node;
+ struct platform_device *pdev;
+
+ const char *label;
+
+ void __iomem *regbase;
+
+ unsigned int use_count;
+ unsigned int pwm_id;
+};
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask)
+{
+ int loops = msecs_to_loops(10);
+ while ((readb(reg) & bitmask) && --loops)
+ cpu_relax();
+
+ if (unlikely(!loops))
+ pr_warning("Waiting for status bits 0x%x to clear timed out\n",
+ bitmask);
+}
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long long c;
+ unsigned long period_cycles, prescale, pv, dc;
+
+ if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+ c = 25000000/2; /* wild guess --- need to implement clocks */
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ if (period_cycles < 1)
+ period_cycles = 1;
+ prescale = (period_cycles - 1) / 4096;
+ pv = period_cycles / (prescale + 1) - 1;
+ if (pv > 4095)
+ pv = 4095;
+
+ if (prescale > 1023)
+ return -EINVAL;
+
+ c = (unsigned long long)pv * duty_ns;
+ do_div(c, period_ns);
+ dc = c;
+
+ pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1));
+ writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4));
+
+ pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2));
+ writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4));
+
+ pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3));
+ writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4));
+
+ return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
+ writel(5, pwm->regbase + (pwm->pwm_id << 4));
+ return 0;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
+ writel(0, pwm->regbase + (pwm->pwm_id << 4));
+}
+EXPORT_SYMBOL(pwm_disable);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, node) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count++;
+ pwm->label = label;
+ } else {
+ pwm = ERR_PTR(-EBUSY);
+ }
+ } else {
+ pwm = ERR_PTR(-ENOENT);
+ }
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else {
+ pr_warning("PWM device already freed\n");
+ }
+
+ mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static inline void __add_pwm(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->node, &pwm_list);
+ mutex_unlock(&pwm_lock);
+}
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+ struct pwm_device *pwms;
+ struct resource *r;
+ int ret = 0;
+ int i;
+
+ pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL);
+ if (pwms == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < VT8500_NR_PWMS; i++) {
+ pwms[i].use_count = 0;
+ pwms[i].pwm_id = i;
+ pwms[i].pdev = pdev;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto err_free;
+ }
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ ret = -EBUSY;
+ goto err_free;
+ }
+
+ pwms[0].regbase = ioremap(r->start, resource_size(r));
+ if (pwms[0].regbase == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap() registers\n");
+ ret = -ENODEV;
+ goto err_free_mem;
+ }
+
+ for (i = 1; i < VT8500_NR_PWMS; i++)
+ pwms[i].regbase = pwms[0].regbase;
+
+ for (i = 0; i < VT8500_NR_PWMS; i++)
+ __add_pwm(&pwms[i]);
+
+ platform_set_drvdata(pdev, pwms);
+ return 0;
+
+err_free_mem:
+ release_mem_region(r->start, resource_size(r));
+err_free:
+ kfree(pwms);
+ return ret;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwms;
+ struct resource *r;
+ int i;
+
+ pwms = platform_get_drvdata(pdev);
+ if (pwms == NULL)
+ return -ENODEV;
+
+ mutex_lock(&pwm_lock);
+
+ for (i = 0; i < VT8500_NR_PWMS; i++)
+ list_del(&pwms[i].node);
+ mutex_unlock(&pwm_lock);
+
+ iounmap(pwms[0].regbase);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ kfree(pwms);
+ return 0;
+}
+
+static struct platform_driver pwm_driver = {
+ .driver = {
+ .name = "vt8500-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = pwm_probe,
+ .remove = __devexit_p(pwm_remove),
+};
+
+static int __init pwm_init(void)
+{
+ return platform_driver_register(&pwm_driver);
+}
+arch_initcall(pwm_init);
+
+static void __exit pwm_exit(void)
+{
+ platform_driver_unregister(&pwm_driver);
+}
+module_exit(pwm_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-vt8500/timer.c b/arch/arm/mach-vt8500/timer.c
new file mode 100644
index 00000000..d5376c59
--- /dev/null
+++ b/arch/arm/mach-vt8500/timer.c
@@ -0,0 +1,155 @@
+/*
+ * arch/arm/mach-vt8500/timer.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/delay.h>
+
+#include <asm/mach/time.h>
+
+#include "devices.h"
+
+#define VT8500_TIMER_OFFSET 0x0100
+#define TIMER_MATCH_VAL 0x0000
+#define TIMER_COUNT_VAL 0x0010
+#define TIMER_STATUS_VAL 0x0014
+#define TIMER_IER_VAL 0x001c /* interrupt enable */
+#define TIMER_CTRL_VAL 0x0020
+#define TIMER_AS_VAL 0x0024 /* access status */
+#define TIMER_COUNT_R_ACTIVE (1 << 5) /* not ready for read */
+#define TIMER_COUNT_W_ACTIVE (1 << 4) /* not ready for write */
+#define TIMER_MATCH_W_ACTIVE (1 << 0) /* not ready for write */
+#define VT8500_TIMER_HZ 3000000
+
+#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
+
+static void __iomem *regbase;
+
+static cycle_t vt8500_timer_read(struct clocksource *cs)
+{
+ int loops = msecs_to_loops(10);
+ writel(3, regbase + TIMER_CTRL_VAL);
+ while ((readl((regbase + TIMER_AS_VAL)) & TIMER_COUNT_R_ACTIVE)
+ && --loops)
+ cpu_relax();
+ return readl(regbase + TIMER_COUNT_VAL);
+}
+
+struct clocksource clocksource = {
+ .name = "vt8500_timer",
+ .rating = 200,
+ .read = vt8500_timer_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int vt8500_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ int loops = msecs_to_loops(10);
+ cycle_t alarm = clocksource.read(&clocksource) + cycles;
+ while ((readl(regbase + TIMER_AS_VAL) & TIMER_MATCH_W_ACTIVE)
+ && --loops)
+ cpu_relax();
+ writel((unsigned long)alarm, regbase + TIMER_MATCH_VAL);
+
+ if ((signed)(alarm - clocksource.read(&clocksource)) <= 16)
+ return -ETIME;
+
+ writel(1, regbase + TIMER_IER_VAL);
+
+ return 0;
+}
+
+static void vt8500_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ switch (mode) {
+ case CLOCK_EVT_MODE_RESUME:
+ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ writel(readl(regbase + TIMER_CTRL_VAL) | 1,
+ regbase + TIMER_CTRL_VAL);
+ writel(0, regbase + TIMER_IER_VAL);
+ break;
+ }
+}
+
+struct clock_event_device clockevent = {
+ .name = "vt8500_timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = vt8500_timer_set_next_event,
+ .set_mode = vt8500_timer_set_mode,
+};
+
+static irqreturn_t vt8500_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+ writel(0xf, regbase + TIMER_STATUS_VAL);
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+struct irqaction irq = {
+ .name = "vt8500_timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = vt8500_timer_interrupt,
+ .dev_id = &clockevent,
+};
+
+static void __init vt8500_timer_init(void)
+{
+ regbase = ioremap(wmt_pmc_base + VT8500_TIMER_OFFSET, 0x28);
+ if (!regbase)
+ printk(KERN_ERR "vt8500_timer_init: failed to map MMIO registers\n");
+
+ writel(1, regbase + TIMER_CTRL_VAL);
+ writel(0xf, regbase + TIMER_STATUS_VAL);
+ writel(~0, regbase + TIMER_MATCH_VAL);
+
+ if (clocksource_register_hz(&clocksource, VT8500_TIMER_HZ))
+ printk(KERN_ERR "vt8500_timer_init: clocksource_register failed for %s\n",
+ clocksource.name);
+
+ clockevents_calc_mult_shift(&clockevent, VT8500_TIMER_HZ, 4);
+
+ /* copy-pasted from mach-msm; no idea */
+ clockevent.max_delta_ns =
+ clockevent_delta2ns(0xf0000000, &clockevent);
+ clockevent.min_delta_ns = clockevent_delta2ns(4, &clockevent);
+ clockevent.cpumask = cpumask_of(0);
+
+ if (setup_irq(wmt_timer_irq, &irq))
+ printk(KERN_ERR "vt8500_timer_init: setup_irq failed for %s\n",
+ clockevent.name);
+ clockevents_register_device(&clockevent);
+}
+
+struct sys_timer vt8500_timer = {
+ .init = vt8500_timer_init
+};
diff --git a/arch/arm/mach-vt8500/wm8505_7in.c b/arch/arm/mach-vt8500/wm8505_7in.c
new file mode 100644
index 00000000..e73aadbc
--- /dev/null
+++ b/arch/arm/mach-vt8500/wm8505_7in.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/mach-vt8500/wm8505_7in.c
+ *
+ * Copyright (C) 2010 Alexey Charkov <alchark@gmail.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/io.h>
+#include <linux/pm.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include "devices.h"
+
+static void __iomem *pmc_hiber;
+
+static struct platform_device *devices[] __initdata = {
+ &vt8500_device_uart0,
+ &vt8500_device_ehci,
+ &vt8500_device_wm8505_fb,
+ &vt8500_device_ge_rops,
+ &vt8500_device_pwm,
+ &vt8500_device_pwmbl,
+ &vt8500_device_rtc,
+};
+
+static void vt8500_power_off(void)
+{
+ local_irq_disable();
+ writew(5, pmc_hiber);
+ asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0));
+}
+
+void __init wm8505_7in_init(void)
+{
+#ifdef CONFIG_FB_WM8505
+ void __iomem *gpio_mux_reg = ioremap(wmt_gpio_base + 0x200, 4);
+ if (gpio_mux_reg) {
+ writel(readl(gpio_mux_reg) | 0x80000000, gpio_mux_reg);
+ iounmap(gpio_mux_reg);
+ } else {
+ printk(KERN_ERR "Could not remap the GPIO mux register, display may not work properly!\n");
+ }
+#endif
+ pmc_hiber = ioremap(wmt_pmc_base + 0x12, 2);
+ if (pmc_hiber)
+ pm_power_off = &vt8500_power_off;
+ else
+ printk(KERN_ERR "PMC Hibernation register could not be remapped, not enabling power off!\n");
+
+ wm8505_set_resources();
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+ vt8500_gpio_init();
+}
+
+MACHINE_START(WM8505_7IN_NETBOOK, "WM8505 7-inch generic netbook")
+ .boot_params = 0x00000100,
+ .reserve = wm8505_reserve_mem,
+ .map_io = wm8505_map_io,
+ .init_irq = wm8505_init_irq,
+ .timer = &vt8500_timer,
+ .init_machine = wm8505_7in_init,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig
new file mode 100644
index 00000000..69bab32a
--- /dev/null
+++ b/arch/arm/mach-w90x900/Kconfig
@@ -0,0 +1,49 @@
+if ARCH_W90X900
+
+config CPU_W90P910
+ bool
+ help
+ Support for W90P910 of Nuvoton W90X900 CPUs.
+
+config CPU_NUC950
+ bool
+ help
+ Support for NUCP950 of Nuvoton NUC900 CPUs.
+
+config CPU_NUC960
+ bool
+ help
+ Support for NUCP960 of Nuvoton NUC900 CPUs.
+
+menu "W90P910 Machines"
+
+config MACH_W90P910EVB
+ bool "Nuvoton W90P910 Evaluation Board"
+ default y
+ select CPU_W90P910
+ help
+ Say Y here if you are using the Nuvoton W90P910EVB
+
+endmenu
+
+menu "NUC950 Machines"
+
+config MACH_W90P950EVB
+ bool "Nuvoton NUC950 Evaluation Board"
+ select CPU_NUC950
+ help
+ Say Y here if you are using the Nuvoton NUC950EVB
+
+endmenu
+
+menu "NUC960 Machines"
+
+config MACH_W90N960EVB
+ bool "Nuvoton NUC960 Evaluation Board"
+ select CPU_NUC960
+ help
+ Say Y here if you are using the Nuvoton NUC960EVB
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
new file mode 100644
index 00000000..828c0326
--- /dev/null
+++ b/arch/arm/mach-w90x900/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := irq.o time.o mfp.o gpio.o clock.o
+obj-y += clksel.o dev.o cpu.o
+# W90X900 CPU support files
+
+obj-$(CONFIG_CPU_W90P910) += nuc910.o
+obj-$(CONFIG_CPU_NUC950) += nuc950.o
+obj-$(CONFIG_CPU_NUC960) += nuc960.o
+
+# machine support
+
+obj-$(CONFIG_MACH_W90P910EVB) += mach-nuc910evb.o
+obj-$(CONFIG_MACH_W90P950EVB) += mach-nuc950evb.o
+obj-$(CONFIG_MACH_W90N960EVB) += mach-nuc960evb.o
diff --git a/arch/arm/mach-w90x900/Makefile.boot b/arch/arm/mach-w90x900/Makefile.boot
new file mode 100644
index 00000000..a057b546
--- /dev/null
+++ b/arch/arm/mach-w90x900/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y := 0x00008000
+params_phys-y := 0x00000100
+
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c
new file mode 100644
index 00000000..3de4a521
--- /dev/null
+++ b/arch/arm/mach-w90x900/clksel.c
@@ -0,0 +1,91 @@
+/*
+ * linux/arch/arm/mach-w90x900/clksel.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-clock.h>
+
+#define PLL0 0x00
+#define PLL1 0x01
+#define OTHER 0x02
+#define EXT 0x03
+#define MSOFFSET 0x0C
+#define ATAOFFSET 0x0a
+#define LCDOFFSET 0x06
+#define AUDOFFSET 0x04
+#define CPUOFFSET 0x00
+
+static DEFINE_MUTEX(clksel_sem);
+
+static void clock_source_select(const char *dev_id, unsigned int clkval)
+{
+ unsigned int clksel, offset;
+
+ clksel = __raw_readl(REG_CLKSEL);
+
+ if (strcmp(dev_id, "nuc900-ms") == 0)
+ offset = MSOFFSET;
+ else if (strcmp(dev_id, "nuc900-atapi") == 0)
+ offset = ATAOFFSET;
+ else if (strcmp(dev_id, "nuc900-lcd") == 0)
+ offset = LCDOFFSET;
+ else if (strcmp(dev_id, "nuc900-audio") == 0)
+ offset = AUDOFFSET;
+ else
+ offset = CPUOFFSET;
+
+ clksel &= ~(0x03 << offset);
+ clksel |= (clkval << offset);
+
+ __raw_writel(clksel, REG_CLKSEL);
+}
+
+void nuc900_clock_source(struct device *dev, unsigned char *src)
+{
+ unsigned int clkval;
+ const char *dev_id;
+
+ BUG_ON(!src);
+ clkval = 0;
+
+ mutex_lock(&clksel_sem);
+
+ if (dev)
+ dev_id = dev_name(dev);
+ else
+ dev_id = "cpufreq";
+
+ if (strcmp(src, "pll0") == 0)
+ clkval = PLL0;
+ else if (strcmp(src, "pll1") == 0)
+ clkval = PLL1;
+ else if (strcmp(src, "ext") == 0)
+ clkval = EXT;
+ else if (strcmp(src, "oth") == 0)
+ clkval = OTHER;
+
+ clock_source_select(dev_id, clkval);
+
+ mutex_unlock(&clksel_sem);
+}
+EXPORT_SYMBOL(nuc900_clock_source);
+
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
new file mode 100644
index 00000000..2c371ff2
--- /dev/null
+++ b/arch/arm/mach-w90x900/clock.c
@@ -0,0 +1,92 @@
+/*
+ * linux/arch/arm/mach-w90x900/clock.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#include "clock.h"
+
+#define SUBCLK 0x24
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ (clk->enable)(clk, 1);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ WARN_ON(clk->enabled == 0);
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ (clk->enable)(clk, 0);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return 15000000;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void nuc900_clk_enable(struct clk *clk, int enable)
+{
+ unsigned int clocks = clk->cken;
+ unsigned long clken;
+
+ clken = __raw_readl(W90X900_VA_CLKPWR);
+
+ if (enable)
+ clken |= clocks;
+ else
+ clken &= ~clocks;
+
+ __raw_writel(clken, W90X900_VA_CLKPWR);
+}
+
+void nuc900_subclk_enable(struct clk *clk, int enable)
+{
+ unsigned int clocks = clk->cken;
+ unsigned long clken;
+
+ clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK);
+
+ if (enable)
+ clken |= clocks;
+ else
+ clken &= ~clocks;
+
+ __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
+}
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
new file mode 100644
index 00000000..b88a1b16
--- /dev/null
+++ b/arch/arm/mach-w90x900/clock.h
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/mach-w90x900/clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ */
+
+#include <linux/clkdev.h>
+
+void nuc900_clk_enable(struct clk *clk, int enable);
+void nuc900_subclk_enable(struct clk *clk, int enable);
+
+struct clk {
+ unsigned long cken;
+ unsigned int enabled;
+ void (*enable)(struct clk *, int enable);
+};
+
+#define DEFINE_CLK(_name, _ctrlbit) \
+struct clk clk_##_name = { \
+ .enable = nuc900_clk_enable, \
+ .cken = (1 << _ctrlbit), \
+ }
+
+#define DEFINE_SUBCLK(_name, _ctrlbit) \
+struct clk clk_##_name = { \
+ .enable = nuc900_subclk_enable, \
+ .cken = (1 << _ctrlbit), \
+ }
+
+
+#define DEF_CLKLOOK(_clk, _devname, _conname) \
+ { \
+ .clk = _clk, \
+ .dev_id = _devname, \
+ .con_id = _conname, \
+ }
+
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c
new file mode 100644
index 00000000..83c56324
--- /dev/null
+++ b/arch/arm/mach-w90x900/cpu.c
@@ -0,0 +1,224 @@
+/*
+ * linux/arch/arm/mach-w90x900/cpu.c
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC900 series cpu common support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/serial_8250.h>
+#include <linux/delay.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-ebi.h>
+
+#include "cpu.h"
+#include "clock.h"
+
+/* Initial IO mappings */
+
+static struct map_desc nuc900_iodesc[] __initdata = {
+ IODESC_ENT(IRQ),
+ IODESC_ENT(GCR),
+ IODESC_ENT(UART),
+ IODESC_ENT(TIMER),
+ IODESC_ENT(EBI),
+ IODESC_ENT(GPIO),
+};
+
+/* Initial clock declarations. */
+static DEFINE_CLK(lcd, 0);
+static DEFINE_CLK(audio, 1);
+static DEFINE_CLK(fmi, 4);
+static DEFINE_SUBCLK(ms, 0);
+static DEFINE_SUBCLK(sd, 1);
+static DEFINE_CLK(dmac, 5);
+static DEFINE_CLK(atapi, 6);
+static DEFINE_CLK(emc, 7);
+static DEFINE_SUBCLK(rmii, 2);
+static DEFINE_CLK(usbd, 8);
+static DEFINE_CLK(usbh, 9);
+static DEFINE_CLK(g2d, 10);;
+static DEFINE_CLK(pwm, 18);
+static DEFINE_CLK(ps2, 24);
+static DEFINE_CLK(kpi, 25);
+static DEFINE_CLK(wdt, 26);
+static DEFINE_CLK(gdma, 27);
+static DEFINE_CLK(adc, 28);
+static DEFINE_CLK(usi, 29);
+static DEFINE_CLK(ext, 0);
+static DEFINE_CLK(timer0, 19);
+static DEFINE_CLK(timer1, 20);
+static DEFINE_CLK(timer2, 21);
+static DEFINE_CLK(timer3, 22);
+static DEFINE_CLK(timer4, 23);
+
+static struct clk_lookup nuc900_clkregs[] = {
+ DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
+ DEF_CLKLOOK(&clk_audio, "nuc900-audio", NULL),
+ DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL),
+ DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"),
+ DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"),
+ DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL),
+ DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL),
+ DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL),
+ DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"),
+ DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL),
+ DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL),
+ DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL),
+ DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL),
+ DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL),
+ DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
+ DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
+ DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
+ DEF_CLKLOOK(&clk_adc, "nuc900-ts", NULL),
+ DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
+ DEF_CLKLOOK(&clk_ext, NULL, "ext"),
+ DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
+ DEF_CLKLOOK(&clk_timer1, NULL, "timer1"),
+ DEF_CLKLOOK(&clk_timer2, NULL, "timer2"),
+ DEF_CLKLOOK(&clk_timer3, NULL, "timer3"),
+ DEF_CLKLOOK(&clk_timer4, NULL, "timer4"),
+};
+
+/* Initial serial platform data */
+
+struct plat_serial8250_port nuc900_uart_data[] = {
+ NUC900_8250PORT(UART0),
+ {},
+};
+
+struct platform_device nuc900_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = nuc900_uart_data,
+ },
+};
+
+/*Set NUC900 series cpu frequence*/
+static int __init nuc900_set_clkval(unsigned int cpufreq)
+{
+ unsigned int pllclk, ahbclk, apbclk, val;
+
+ pllclk = 0;
+ ahbclk = 0;
+ apbclk = 0;
+
+ switch (cpufreq) {
+ case 66:
+ pllclk = PLL_66MHZ;
+ ahbclk = AHB_CPUCLK_1_1;
+ apbclk = APB_AHB_1_2;
+ break;
+
+ case 100:
+ pllclk = PLL_100MHZ;
+ ahbclk = AHB_CPUCLK_1_1;
+ apbclk = APB_AHB_1_2;
+ break;
+
+ case 120:
+ pllclk = PLL_120MHZ;
+ ahbclk = AHB_CPUCLK_1_2;
+ apbclk = APB_AHB_1_2;
+ break;
+
+ case 166:
+ pllclk = PLL_166MHZ;
+ ahbclk = AHB_CPUCLK_1_2;
+ apbclk = APB_AHB_1_2;
+ break;
+
+ case 200:
+ pllclk = PLL_200MHZ;
+ ahbclk = AHB_CPUCLK_1_2;
+ apbclk = APB_AHB_1_2;
+ break;
+ }
+
+ __raw_writel(pllclk, REG_PLLCON0);
+
+ val = __raw_readl(REG_CLKDIV);
+ val &= ~(0x03 << 24 | 0x03 << 26);
+ val |= (ahbclk << 24 | apbclk << 26);
+ __raw_writel(val, REG_CLKDIV);
+
+ return 0;
+}
+static int __init nuc900_set_cpufreq(char *str)
+{
+ unsigned long cpufreq, val;
+
+ if (!*str)
+ return 0;
+
+ strict_strtoul(str, 0, &cpufreq);
+
+ nuc900_clock_source(NULL, "ext");
+
+ nuc900_set_clkval(cpufreq);
+
+ mdelay(1);
+
+ val = __raw_readl(REG_CKSKEW);
+ val &= ~0xff;
+ val |= DEFAULTSKEW;
+ __raw_writel(val, REG_CKSKEW);
+
+ nuc900_clock_source(NULL, "pll0");
+
+ return 1;
+}
+
+__setup("cpufreq=", nuc900_set_cpufreq);
+
+/*Init NUC900 evb io*/
+
+void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
+{
+ unsigned long idcode = 0x0;
+
+ iotable_init(mach_desc, mach_size);
+ iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc));
+
+ idcode = __raw_readl(NUC900PDID);
+ if (idcode == NUC910_CPUID)
+ printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
+ else if (idcode == NUC920_CPUID)
+ printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode);
+ else if (idcode == NUC950_CPUID)
+ printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode);
+ else if (idcode == NUC960_CPUID)
+ printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode);
+}
+
+/*Init NUC900 clock*/
+
+void __init nuc900_init_clocks(void)
+{
+ clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
+}
+
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
new file mode 100644
index 00000000..f8730b60
--- /dev/null
+++ b/arch/arm/mach-w90x900/cpu.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/mach-w90x900/cpu.h
+ *
+ * Based on linux/include/asm-arm/plat-s3c24xx/cpu.h by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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.
+ *
+ */
+
+#define IODESC_ENT(y) \
+{ \
+ .virtual = (unsigned long)W90X900_VA_##y, \
+ .pfn = __phys_to_pfn(W90X900_PA_##y), \
+ .length = W90X900_SZ_##y, \
+ .type = MT_DEVICE, \
+}
+
+#define NUC900_8250PORT(name) \
+{ \
+ .membase = name##_BA, \
+ .mapbase = name##_PA, \
+ .irq = IRQ_##name, \
+ .uartclk = 11313600, \
+ .regshift = 2, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, \
+}
+
+/*Cpu identifier register*/
+
+#define NUC900PDID W90X900_VA_GCR
+#define NUC910_CPUID 0x02900910
+#define NUC920_CPUID 0x02900920
+#define NUC950_CPUID 0x02900950
+#define NUC960_CPUID 0x02900960
+
+/* extern file from cpu.c */
+
+extern void nuc900_clock_source(struct device *dev, unsigned char *src);
+extern void nuc900_init_clocks(void);
+extern void nuc900_map_io(struct map_desc *mach_desc, int mach_size);
+extern void nuc900_board_init(struct platform_device **device, int size);
+
+/* for either public between 910 and 920, or between 920 and 950 */
+
+extern struct platform_device nuc900_serial_device;
+extern struct platform_device nuc900_device_fmi;
+extern struct platform_device nuc900_device_kpi;
+extern struct platform_device nuc900_device_rtc;
+extern struct platform_device nuc900_device_ts;
+extern struct platform_device nuc900_device_lcd;
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
new file mode 100644
index 00000000..7a1fa6ad
--- /dev/null
+++ b/arch/arm/mach-w90x900/dev.c
@@ -0,0 +1,538 @@
+/*
+ * linux/arch/arm/mach-w90x900/dev.c
+ *
+ * Copyright (C) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+
+#include <mach/regs-serial.h>
+#include <mach/nuc900_spi.h>
+#include <mach/map.h>
+#include <mach/fb.h>
+#include <mach/regs-ldm.h>
+#include <mach/w90p910_keypad.h>
+
+#include "cpu.h"
+
+/*NUC900 evb norflash driver data */
+
+#define NUC900_FLASH_BASE 0xA0000000
+#define NUC900_FLASH_SIZE 0x400000
+#define SPIOFFSET 0x200
+#define SPIOREG_SIZE 0x100
+
+static struct mtd_partition nuc900_flash_partitions[] = {
+ {
+ .name = "NOR Partition 1 for kernel (960K)",
+ .size = 0xF0000,
+ .offset = 0x10000,
+ },
+ {
+ .name = "NOR Partition 2 for image (1M)",
+ .size = 0x100000,
+ .offset = 0x100000,
+ },
+ {
+ .name = "NOR Partition 3 for user (2M)",
+ .size = 0x200000,
+ .offset = 0x00200000,
+ }
+};
+
+static struct physmap_flash_data nuc900_flash_data = {
+ .width = 2,
+ .parts = nuc900_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nuc900_flash_partitions),
+};
+
+static struct resource nuc900_flash_resources[] = {
+ {
+ .start = NUC900_FLASH_BASE,
+ .end = NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device nuc900_flash_device = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &nuc900_flash_data,
+ },
+ .resource = nuc900_flash_resources,
+ .num_resources = ARRAY_SIZE(nuc900_flash_resources),
+};
+
+/* USB EHCI Host Controller */
+
+static struct resource nuc900_usb_ehci_resource[] = {
+ [0] = {
+ .start = W90X900_PA_USBEHCIHOST,
+ .end = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;
+
+static struct platform_device nuc900_device_usb_ehci = {
+ .name = "nuc900-ehci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_usb_ehci_resource),
+ .resource = nuc900_usb_ehci_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_usb_ehci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+/* USB OHCI Host Controller */
+
+static struct resource nuc900_usb_ohci_resource[] = {
+ [0] = {
+ .start = W90X900_PA_USBOHCIHOST,
+ .end = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL;
+static struct platform_device nuc900_device_usb_ohci = {
+ .name = "nuc900-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_usb_ohci_resource),
+ .resource = nuc900_usb_ohci_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_usb_ohci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+/* USB Device (Gadget)*/
+
+static struct resource nuc900_usbgadget_resource[] = {
+ [0] = {
+ .start = W90X900_PA_USBDEV,
+ .end = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBD,
+ .end = IRQ_USBD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device nuc900_device_usbgadget = {
+ .name = "nuc900-usbgadget",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_usbgadget_resource),
+ .resource = nuc900_usbgadget_resource,
+};
+
+/* MAC device */
+
+static struct resource nuc900_emc_resource[] = {
+ [0] = {
+ .start = W90X900_PA_EMC,
+ .end = W90X900_PA_EMC + W90X900_SZ_EMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_EMCTX,
+ .end = IRQ_EMCTX,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_EMCRX,
+ .end = IRQ_EMCRX,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 nuc900_device_emc_dmamask = 0xffffffffUL;
+static struct platform_device nuc900_device_emc = {
+ .name = "nuc900-emc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_emc_resource),
+ .resource = nuc900_emc_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_emc_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+/* SPI device */
+
+static struct nuc900_spi_info nuc900_spiflash_data = {
+ .num_cs = 1,
+ .lsb = 0,
+ .txneg = 1,
+ .rxneg = 0,
+ .divider = 24,
+ .sleep = 0,
+ .txnum = 0,
+ .txbitlen = 8,
+ .bus_num = 0,
+};
+
+static struct resource nuc900_spi_resource[] = {
+ [0] = {
+ .start = W90X900_PA_I2C + SPIOFFSET,
+ .end = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SSP,
+ .end = IRQ_SSP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device nuc900_device_spi = {
+ .name = "nuc900-spi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_spi_resource),
+ .resource = nuc900_spi_resource,
+ .dev = {
+ .platform_data = &nuc900_spiflash_data,
+ }
+};
+
+/* spi device, spi flash info */
+
+static struct mtd_partition nuc900_spi_flash_partitions[] = {
+ {
+ .name = "bootloader(spi)",
+ .size = 0x0100000,
+ .offset = 0,
+ },
+};
+
+static struct flash_platform_data nuc900_spi_flash_data = {
+ .name = "m25p80",
+ .parts = nuc900_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions),
+ .type = "w25x16",
+};
+
+static struct spi_board_info nuc900_spi_board_info[] __initdata = {
+ {
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = &nuc900_spi_flash_data,
+ .mode = SPI_MODE_0,
+ },
+};
+
+/* WDT Device */
+
+static struct resource nuc900_wdt_resource[] = {
+ [0] = {
+ .start = W90X900_PA_TIMER,
+ .end = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_WDT,
+ .end = IRQ_WDT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device nuc900_device_wdt = {
+ .name = "nuc900-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_wdt_resource),
+ .resource = nuc900_wdt_resource,
+};
+
+/*
+ * public device definition between 910 and 920, or 910
+ * and 950 or 950 and 960...,their dev platform register
+ * should be in specific file such as nuc950, nuc960 c
+ * files rather than the public dev.c file here. so the
+ * corresponding platform_device definition should not be
+ * static.
+*/
+
+/* RTC controller*/
+
+static struct resource nuc900_rtc_resource[] = {
+ [0] = {
+ .start = W90X900_PA_RTC,
+ .end = W90X900_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC,
+ .end = IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device nuc900_device_rtc = {
+ .name = "nuc900-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_rtc_resource),
+ .resource = nuc900_rtc_resource,
+};
+
+/*TouchScreen controller*/
+
+static struct resource nuc900_ts_resource[] = {
+ [0] = {
+ .start = W90X900_PA_ADC,
+ .end = W90X900_PA_ADC + W90X900_SZ_ADC-1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device nuc900_device_ts = {
+ .name = "nuc900-ts",
+ .id = -1,
+ .resource = nuc900_ts_resource,
+ .num_resources = ARRAY_SIZE(nuc900_ts_resource),
+};
+
+/* FMI Device */
+
+static struct resource nuc900_fmi_resource[] = {
+ [0] = {
+ .start = W90X900_PA_FMI,
+ .end = W90X900_PA_FMI + W90X900_SZ_FMI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FMI,
+ .end = IRQ_FMI,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device nuc900_device_fmi = {
+ .name = "nuc900-fmi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_fmi_resource),
+ .resource = nuc900_fmi_resource,
+};
+
+/* KPI controller*/
+
+static int nuc900_keymap[] = {
+ KEY(0, 0, KEY_A),
+ KEY(0, 1, KEY_B),
+ KEY(0, 2, KEY_C),
+ KEY(0, 3, KEY_D),
+
+ KEY(1, 0, KEY_E),
+ KEY(1, 1, KEY_F),
+ KEY(1, 2, KEY_G),
+ KEY(1, 3, KEY_H),
+
+ KEY(2, 0, KEY_I),
+ KEY(2, 1, KEY_J),
+ KEY(2, 2, KEY_K),
+ KEY(2, 3, KEY_L),
+
+ KEY(3, 0, KEY_M),
+ KEY(3, 1, KEY_N),
+ KEY(3, 2, KEY_O),
+ KEY(3, 3, KEY_P),
+};
+
+static struct matrix_keymap_data nuc900_map_data = {
+ .keymap = nuc900_keymap,
+ .keymap_size = ARRAY_SIZE(nuc900_keymap),
+};
+
+struct w90p910_keypad_platform_data nuc900_keypad_info = {
+ .keymap_data = &nuc900_map_data,
+ .prescale = 0xfa,
+ .debounce = 0x50,
+};
+
+static struct resource nuc900_kpi_resource[] = {
+ [0] = {
+ .start = W90X900_PA_KPI,
+ .end = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KPI,
+ .end = IRQ_KPI,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device nuc900_device_kpi = {
+ .name = "nuc900-kpi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_kpi_resource),
+ .resource = nuc900_kpi_resource,
+ .dev = {
+ .platform_data = &nuc900_keypad_info,
+ }
+};
+
+/* LCD controller*/
+
+static struct nuc900fb_display __initdata nuc900_lcd_info[] = {
+ /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
+ [0] = {
+ .type = LCM_DCCS_VA_SRC_RGB565,
+ .width = 320,
+ .height = 240,
+ .xres = 320,
+ .yres = 240,
+ .bpp = 16,
+ .pixclock = 200000,
+ .left_margin = 34,
+ .right_margin = 54,
+ .hsync_len = 10,
+ .upper_margin = 18,
+ .lower_margin = 4,
+ .vsync_len = 1,
+ .dccs = 0x8e00041a,
+ .devctl = 0x060800c0,
+ .fbctrl = 0x00a000a0,
+ .scale = 0x04000400,
+ },
+};
+
+static struct nuc900fb_mach_info nuc900_fb_info __initdata = {
+#if defined(CONFIG_GPM1040A0_320X240)
+ .displays = &nuc900_lcd_info[0],
+#else
+ .displays = nuc900_lcd_info,
+#endif
+ .num_displays = ARRAY_SIZE(nuc900_lcd_info),
+ .default_display = 0,
+ .gpio_dir = 0x00000004,
+ .gpio_dir_mask = 0xFFFFFFFD,
+ .gpio_data = 0x00000004,
+ .gpio_data_mask = 0xFFFFFFFD,
+};
+
+static struct resource nuc900_lcd_resource[] = {
+ [0] = {
+ .start = W90X900_PA_LCD,
+ .end = W90X900_PA_LCD + W90X900_SZ_LCD - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 nuc900_device_lcd_dmamask = -1;
+struct platform_device nuc900_device_lcd = {
+ .name = "nuc900-lcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_lcd_resource),
+ .resource = nuc900_lcd_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_lcd_dmamask,
+ .coherent_dma_mask = -1,
+ .platform_data = &nuc900_fb_info,
+ }
+};
+
+/* AUDIO controller*/
+static u64 nuc900_device_audio_dmamask = -1;
+static struct resource nuc900_ac97_resource[] = {
+ [0] = {
+ .start = W90X900_PA_ACTL,
+ .end = W90X900_PA_ACTL + W90X900_SZ_ACTL - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ACTL,
+ .end = IRQ_ACTL,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device nuc900_device_audio = {
+ .name = "nuc900-audio",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(nuc900_ac97_resource),
+ .resource = nuc900_ac97_resource,
+ .dev = {
+ .dma_mask = &nuc900_device_audio_dmamask,
+ .coherent_dma_mask = -1,
+ }
+};
+
+/*Here should be your evb resourse,such as LCD*/
+
+static struct platform_device *nuc900_public_dev[] __initdata = {
+ &nuc900_serial_device,
+ &nuc900_flash_device,
+ &nuc900_device_usb_ehci,
+ &nuc900_device_usb_ohci,
+ &nuc900_device_usbgadget,
+ &nuc900_device_emc,
+ &nuc900_device_spi,
+ &nuc900_device_wdt,
+ &nuc900_device_audio,
+};
+
+/* Provide adding specific CPU platform devices API */
+
+void __init nuc900_board_init(struct platform_device **device, int size)
+{
+ platform_add_devices(device, size);
+ platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
+ spi_register_board_info(nuc900_spi_board_info,
+ ARRAY_SIZE(nuc900_spi_board_info));
+}
+
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
new file mode 100644
index 00000000..ba05aec7
--- /dev/null
+++ b/arch/arm/mach-w90x900/gpio.c
@@ -0,0 +1,154 @@
+/*
+ * linux/arch/arm/mach-w90x900/gpio.c
+ *
+ * Generic nuc900 GPIO handling
+ *
+ * Wan ZongShun <mcuos.com@gmail.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/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+
+#define GPIO_BASE (W90X900_VA_GPIO)
+#define GPIO_DIR (0x04)
+#define GPIO_OUT (0x08)
+#define GPIO_IN (0x0C)
+#define GROUPINERV (0x10)
+#define GPIO_GPIO(Nb) (0x00000001 << (Nb))
+#define to_nuc900_gpio_chip(c) container_of(c, struct nuc900_gpio_chip, chip)
+
+#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = nuc900_dir_input, \
+ .direction_output = nuc900_dir_output, \
+ .get = nuc900_gpio_get, \
+ .set = nuc900_gpio_set, \
+ .base = base_gpio, \
+ .ngpio = nr_gpio, \
+ } \
+ }
+
+struct nuc900_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase; /* Base of group register*/
+ spinlock_t gpio_lock;
+};
+
+static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
+ unsigned int regval;
+
+ regval = __raw_readl(pio);
+ regval &= GPIO_GPIO(offset);
+
+ return (regval != 0);
+}
+
+static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
+ unsigned int regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
+
+ regval = __raw_readl(pio);
+
+ if (val)
+ regval |= GPIO_GPIO(offset);
+ else
+ regval &= ~GPIO_GPIO(offset);
+
+ __raw_writel(regval, pio);
+
+ spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
+}
+
+static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
+ unsigned int regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
+
+ regval = __raw_readl(pio);
+ regval &= ~GPIO_GPIO(offset);
+ __raw_writel(regval, pio);
+
+ spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
+
+ return 0;
+}
+
+static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct nuc900_gpio_chip *nuc900_gpio = to_nuc900_gpio_chip(chip);
+ void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
+ void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
+ unsigned int regval;
+ unsigned long flags;
+
+ spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
+
+ regval = __raw_readl(pio);
+ regval |= GPIO_GPIO(offset);
+ __raw_writel(regval, pio);
+
+ regval = __raw_readl(outreg);
+
+ if (val)
+ regval |= GPIO_GPIO(offset);
+ else
+ regval &= ~GPIO_GPIO(offset);
+
+ __raw_writel(regval, outreg);
+
+ spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
+
+ return 0;
+}
+
+static struct nuc900_gpio_chip nuc900_gpio[] = {
+ NUC900_GPIO_CHIP("GROUPC", 0, 16),
+ NUC900_GPIO_CHIP("GROUPD", 16, 10),
+ NUC900_GPIO_CHIP("GROUPE", 26, 14),
+ NUC900_GPIO_CHIP("GROUPF", 40, 10),
+ NUC900_GPIO_CHIP("GROUPG", 50, 17),
+ NUC900_GPIO_CHIP("GROUPH", 67, 8),
+ NUC900_GPIO_CHIP("GROUPI", 75, 17),
+};
+
+void __init nuc900_init_gpio(int nr_group)
+{
+ unsigned i;
+ struct nuc900_gpio_chip *gpio_chip;
+
+ for (i = 0; i < nr_group; i++) {
+ gpio_chip = &nuc900_gpio[i];
+ spin_lock_init(&gpio_chip->gpio_lock);
+ gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
+ gpiochip_add(&gpio_chip->chip);
+ }
+}
diff --git a/arch/arm/mach-w90x900/include/mach/clkdev.h b/arch/arm/mach-w90x900/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-w90x900/include/mach/entry-macro.S b/arch/arm/mach-w90x900/include/mach/entry-macro.S
new file mode 100644
index 00000000..d39aca5b
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/entry-macro.S
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for W90P910-based platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ */
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ mov \base, #AIC_BA
+
+ ldr \irqnr, [ \base, #AIC_IPER]
+ ldr \irqnr, [ \base, #AIC_ISNR]
+ cmp \irqnr, #0
+
+ .endm
+
+ /* currently don't need an disable_fiq macro */
+
+ .macro disable_fiq
+ .endm
diff --git a/arch/arm/mach-w90x900/include/mach/fb.h b/arch/arm/mach-w90x900/include/mach/fb.h
new file mode 100644
index 00000000..cec5ece7
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/fb.h
@@ -0,0 +1,83 @@
+/* linux/include/asm/arch-nuc900/fb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Changelog:
+ *
+ * 2008/08/26 vincen.zswan modify this file for LCD.
+ */
+
+#ifndef __ASM_ARM_FB_H
+#define __ASM_ARM_FB_H
+
+
+
+/* LCD Controller Hardware Desc */
+struct nuc900fb_hw {
+ unsigned int lcd_dccs;
+ unsigned int lcd_device_ctrl;
+ unsigned int lcd_mpulcd_cmd;
+ unsigned int lcd_int_cs;
+ unsigned int lcd_crtc_size;
+ unsigned int lcd_crtc_dend;
+ unsigned int lcd_crtc_hr;
+ unsigned int lcd_crtc_hsync;
+ unsigned int lcd_crtc_vr;
+ unsigned int lcd_va_baddr0;
+ unsigned int lcd_va_baddr1;
+ unsigned int lcd_va_fbctrl;
+ unsigned int lcd_va_scale;
+ unsigned int lcd_va_test;
+ unsigned int lcd_va_win;
+ unsigned int lcd_va_stuff;
+};
+
+/* LCD Display Description */
+struct nuc900fb_display {
+ /* LCD Image type */
+ unsigned type;
+
+ /* LCD Screen Size */
+ unsigned short width;
+ unsigned short height;
+
+ /* LCD Screen Info */
+ unsigned short xres;
+ unsigned short yres;
+ unsigned short bpp;
+
+ unsigned long pixclock;
+ unsigned short left_margin;
+ unsigned short right_margin;
+ unsigned short hsync_len;
+ unsigned short upper_margin;
+ unsigned short lower_margin;
+ unsigned short vsync_len;
+
+ /* hardware special register value */
+ unsigned int dccs;
+ unsigned int devctl;
+ unsigned int fbctrl;
+ unsigned int scale;
+};
+
+struct nuc900fb_mach_info {
+ struct nuc900fb_display *displays;
+ unsigned num_displays;
+ unsigned default_display;
+ /* GPIO Setting Info */
+ unsigned gpio_dir;
+ unsigned gpio_dir_mask;
+ unsigned gpio_data;
+ unsigned gpio_data_mask;
+};
+
+extern void __init nuc900_fb_set_platdata(struct nuc900fb_mach_info *);
+
+#endif /* __ASM_ARM_FB_H */
diff --git a/arch/arm/mach-w90x900/include/mach/gpio.h b/arch/arm/mach-w90x900/include/mach/gpio.h
new file mode 100644
index 00000000..034da3e3
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * linux/arch/arm/mach-w90p910/include/mach/gpio.h
+ *
+ * Generic w90p910 GPIO handling
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_W90P910_GPIO_H
+#define __ASM_ARCH_W90P910_GPIO_H
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return gpio;
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ return irq;
+}
+
+#endif
diff --git a/arch/arm/mach-w90x900/include/mach/hardware.h b/arch/arm/mach-w90x900/include/mach/hardware.h
new file mode 100644
index 00000000..fe3c6265
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/hardware.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/hardware.h
+ *
+ * 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_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include <asm/sizes.h>
+#include <mach/map.h>
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-w90x900/include/mach/i2c.h b/arch/arm/mach-w90x900/include/mach/i2c.h
new file mode 100644
index 00000000..9ffb12d0
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/i2c.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_ARCH_NUC900_I2C_H
+#define __ASM_ARCH_NUC900_I2C_H
+
+struct nuc900_platform_i2c {
+ int bus_num;
+ unsigned long bus_freq;
+};
+
+#endif /* __ASM_ARCH_NUC900_I2C_H */
diff --git a/arch/arm/mach-w90x900/include/mach/io.h b/arch/arm/mach-w90x900/include/mach/io.h
new file mode 100644
index 00000000..d96ab99d
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/io.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/io.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/io.h
+ *
+ * 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_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * 1:1 mapping for ioremapped regions.
+ */
+
+#define __mem_pci(a) (a)
+#define __io(a) __typesafe_io(a)
+
+#endif
diff --git a/arch/arm/mach-w90x900/include/mach/irqs.h b/arch/arm/mach-w90x900/include/mach/irqs.h
new file mode 100644
index 00000000..9d5cba3a
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/irqs.h
@@ -0,0 +1,86 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/irqs.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/irqs.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+/*
+ * we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ */
+
+#define W90X900_IRQ(x) (x)
+
+/* Main cpu interrupts */
+
+#define IRQ_WDT W90X900_IRQ(1)
+#define IRQ_GROUP0 W90X900_IRQ(2)
+#define IRQ_GROUP1 W90X900_IRQ(3)
+#define IRQ_ACTL W90X900_IRQ(4)
+#define IRQ_LCD W90X900_IRQ(5)
+#define IRQ_RTC W90X900_IRQ(6)
+#define IRQ_UART0 W90X900_IRQ(7)
+#define IRQ_UART1 W90X900_IRQ(8)
+#define IRQ_UART2 W90X900_IRQ(9)
+#define IRQ_UART3 W90X900_IRQ(10)
+#define IRQ_UART4 W90X900_IRQ(11)
+#define IRQ_TIMER0 W90X900_IRQ(12)
+#define IRQ_TIMER1 W90X900_IRQ(13)
+#define IRQ_T_INT_GROUP W90X900_IRQ(14)
+#define IRQ_USBH W90X900_IRQ(15)
+#define IRQ_EMCTX W90X900_IRQ(16)
+#define IRQ_EMCRX W90X900_IRQ(17)
+#define IRQ_GDMAGROUP W90X900_IRQ(18)
+#define IRQ_DMAC W90X900_IRQ(19)
+#define IRQ_FMI W90X900_IRQ(20)
+#define IRQ_USBD W90X900_IRQ(21)
+#define IRQ_ATAPI W90X900_IRQ(22)
+#define IRQ_G2D W90X900_IRQ(23)
+#define IRQ_PCI W90X900_IRQ(24)
+#define IRQ_SCGROUP W90X900_IRQ(25)
+#define IRQ_I2CGROUP W90X900_IRQ(26)
+#define IRQ_SSP W90X900_IRQ(27)
+#define IRQ_PWM W90X900_IRQ(28)
+#define IRQ_KPI W90X900_IRQ(29)
+#define IRQ_P2SGROUP W90X900_IRQ(30)
+#define IRQ_ADC W90X900_IRQ(31)
+#define NR_IRQS (IRQ_ADC+1)
+
+/*for irq group*/
+
+#define IRQ_PS2_PORT0 0x10000000
+#define IRQ_PS2_PORT1 0x20000000
+#define IRQ_I2C_LINE0 0x04000000
+#define IRQ_I2C_LINE1 0x08000000
+#define IRQ_SC_CARD0 0x01000000
+#define IRQ_SC_CARD1 0x02000000
+#define IRQ_GDMA_CH0 0x00100000
+#define IRQ_GDMA_CH1 0x00200000
+#define IRQ_TIMER2 0x00010000
+#define IRQ_TIMER3 0x00020000
+#define IRQ_TIMER4 0x00040000
+#define IRQ_GROUP0_IRQ0 0x00000001
+#define IRQ_GROUP0_IRQ1 0x00000002
+#define IRQ_GROUP0_IRQ2 0x00000004
+#define IRQ_GROUP0_IRQ3 0x00000008
+#define IRQ_GROUP1_IRQ4 0x00000010
+#define IRQ_GROUP1_IRQ5 0x00000020
+#define IRQ_GROUP1_IRQ6 0x00000040
+#define IRQ_GROUP1_IRQ7 0x00000080
+
+#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-w90x900/include/mach/map.h b/arch/arm/mach-w90x900/include/mach/map.h
new file mode 100644
index 00000000..1a209530
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/map.h
@@ -0,0 +1,157 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/map.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/map.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_MAP_H
+#define __ASM_ARCH_MAP_H
+
+#ifndef __ASSEMBLY__
+#define W90X900_ADDR(x) ((void __iomem *)(0xF0000000 + (x)))
+#else
+#define W90X900_ADDR(x) (0xF0000000 + (x))
+#endif
+
+#define AHB_IO_BASE 0xB0000000
+#define APB_IO_BASE 0xB8000000
+#define CLOCKPW_BASE (APB_IO_BASE+0x200)
+#define AIC_IO_BASE (APB_IO_BASE+0x2000)
+#define TIMER_IO_BASE (APB_IO_BASE+0x1000)
+
+/*
+ * interrupt controller is the first thing we put in, to make
+ * the assembly code for the irq detection easier
+ */
+#define W90X900_VA_IRQ W90X900_ADDR(0x00000000)
+#define W90X900_PA_IRQ (0xB8002000)
+#define W90X900_SZ_IRQ SZ_4K
+
+#define W90X900_VA_GCR W90X900_ADDR(0x08002000)
+#define W90X900_PA_GCR (0xB0000000)
+#define W90X900_SZ_GCR SZ_4K
+
+/* Clock and Power management */
+#define W90X900_VA_CLKPWR (W90X900_VA_GCR+0x200)
+#define W90X900_PA_CLKPWR (0xB0000200)
+#define W90X900_SZ_CLKPWR SZ_4K
+
+/* EBI management */
+#define W90X900_VA_EBI W90X900_ADDR(0x00001000)
+#define W90X900_PA_EBI (0xB0001000)
+#define W90X900_SZ_EBI SZ_4K
+
+/* UARTs */
+#define W90X900_VA_UART W90X900_ADDR(0x08000000)
+#define W90X900_PA_UART (0xB8000000)
+#define W90X900_SZ_UART SZ_4K
+
+/* Timers */
+#define W90X900_VA_TIMER W90X900_ADDR(0x08001000)
+#define W90X900_PA_TIMER (0xB8001000)
+#define W90X900_SZ_TIMER SZ_4K
+
+/* GPIO ports */
+#define W90X900_VA_GPIO W90X900_ADDR(0x08003000)
+#define W90X900_PA_GPIO (0xB8003000)
+#define W90X900_SZ_GPIO SZ_4K
+
+/* GDMA control */
+#define W90X900_VA_GDMA W90X900_ADDR(0x00004000)
+#define W90X900_PA_GDMA (0xB0004000)
+#define W90X900_SZ_GDMA SZ_4K
+
+/* USB host controller*/
+#define W90X900_VA_USBEHCIHOST W90X900_ADDR(0x00005000)
+#define W90X900_PA_USBEHCIHOST (0xB0005000)
+#define W90X900_SZ_USBEHCIHOST SZ_4K
+
+#define W90X900_VA_USBOHCIHOST W90X900_ADDR(0x00007000)
+#define W90X900_PA_USBOHCIHOST (0xB0007000)
+#define W90X900_SZ_USBOHCIHOST SZ_4K
+
+/* I2C hardware controller */
+#define W90X900_VA_I2C W90X900_ADDR(0x08006000)
+#define W90X900_PA_I2C (0xB8006000)
+#define W90X900_SZ_I2C SZ_4K
+
+/* Keypad Interface*/
+#define W90X900_VA_KPI W90X900_ADDR(0x08008000)
+#define W90X900_PA_KPI (0xB8008000)
+#define W90X900_SZ_KPI SZ_4K
+
+/* Smart card host*/
+#define W90X900_VA_SC W90X900_ADDR(0x08005000)
+#define W90X900_PA_SC (0xB8005000)
+#define W90X900_SZ_SC SZ_4K
+
+/* LCD controller*/
+#define W90X900_VA_LCD W90X900_ADDR(0x00008000)
+#define W90X900_PA_LCD (0xB0008000)
+#define W90X900_SZ_LCD SZ_4K
+
+/* 2D controller*/
+#define W90X900_VA_GE W90X900_ADDR(0x0000B000)
+#define W90X900_PA_GE (0xB000B000)
+#define W90X900_SZ_GE SZ_4K
+
+/* ATAPI */
+#define W90X900_VA_ATAPI W90X900_ADDR(0x0000A000)
+#define W90X900_PA_ATAPI (0xB000A000)
+#define W90X900_SZ_ATAPI SZ_4K
+
+/* ADC */
+#define W90X900_VA_ADC W90X900_ADDR(0x0800A000)
+#define W90X900_PA_ADC (0xB800A000)
+#define W90X900_SZ_ADC SZ_4K
+
+/* PS2 Interface*/
+#define W90X900_VA_PS2 W90X900_ADDR(0x08009000)
+#define W90X900_PA_PS2 (0xB8009000)
+#define W90X900_SZ_PS2 SZ_4K
+
+/* RTC */
+#define W90X900_VA_RTC W90X900_ADDR(0x08004000)
+#define W90X900_PA_RTC (0xB8004000)
+#define W90X900_SZ_RTC SZ_4K
+
+/* Pulse Width Modulation(PWM) Registers */
+#define W90X900_VA_PWM W90X900_ADDR(0x08007000)
+#define W90X900_PA_PWM (0xB8007000)
+#define W90X900_SZ_PWM SZ_4K
+
+/* Audio Controller controller */
+#define W90X900_VA_ACTL W90X900_ADDR(0x00009000)
+#define W90X900_PA_ACTL (0xB0009000)
+#define W90X900_SZ_ACTL SZ_4K
+
+/* DMA controller */
+#define W90X900_VA_DMA W90X900_ADDR(0x0000c000)
+#define W90X900_PA_DMA (0xB000c000)
+#define W90X900_SZ_DMA SZ_4K
+
+/* FMI controller */
+#define W90X900_VA_FMI W90X900_ADDR(0x0000d000)
+#define W90X900_PA_FMI (0xB000d000)
+#define W90X900_SZ_FMI SZ_4K
+
+/* USB Device port */
+#define W90X900_VA_USBDEV W90X900_ADDR(0x00006000)
+#define W90X900_PA_USBDEV (0xB0006000)
+#define W90X900_SZ_USBDEV SZ_4K
+
+/* External MAC control*/
+#define W90X900_VA_EMC W90X900_ADDR(0x00003000)
+#define W90X900_PA_EMC (0xB0003000)
+#define W90X900_SZ_EMC SZ_4K
+
+#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-w90x900/include/mach/memory.h b/arch/arm/mach-w90x900/include/mach/memory.h
new file mode 100644
index 00000000..f02905ba
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/memory.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/memory.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/memory.h
+ *
+ * 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_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-w90x900/include/mach/mfp.h b/arch/arm/mach-w90x900/include/mach/mfp.h
new file mode 100644
index 00000000..94c0e716
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/mfp.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/mfp.h
+ *
+ * Copyright (c) 2010 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/map.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_MFP_H
+#define __ASM_ARCH_MFP_H
+
+extern void mfp_set_groupf(struct device *dev);
+extern void mfp_set_groupc(struct device *dev);
+extern void mfp_set_groupi(struct device *dev);
+extern void mfp_set_groupg(struct device *dev);
+
+#endif /* __ASM_ARCH_MFP_H */
diff --git a/arch/arm/mach-w90x900/include/mach/nuc900_spi.h b/arch/arm/mach-w90x900/include/mach/nuc900_spi.h
new file mode 100644
index 00000000..bd94819e
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/nuc900_spi.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/nuc900_spi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_SPI_H
+#define __ASM_ARCH_SPI_H
+
+extern void mfp_set_groupg(struct device *dev);
+
+struct nuc900_spi_info {
+ unsigned int num_cs;
+ unsigned int lsb;
+ unsigned int txneg;
+ unsigned int rxneg;
+ unsigned int divider;
+ unsigned int sleep;
+ unsigned int txnum;
+ unsigned int txbitlen;
+ int bus_num;
+};
+
+struct nuc900_spi_chip {
+ unsigned char bits_per_word;
+};
+
+#endif /* __ASM_ARCH_SPI_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h
new file mode 100644
index 00000000..516d6b47
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-clock.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-clock.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_CLOCK_H
+#define __ASM_ARCH_REGS_CLOCK_H
+
+/* Clock Control Registers */
+#define CLK_BA W90X900_VA_CLKPWR
+#define REG_CLKEN (CLK_BA + 0x00)
+#define REG_CLKSEL (CLK_BA + 0x04)
+#define REG_CLKDIV (CLK_BA + 0x08)
+#define REG_PLLCON0 (CLK_BA + 0x0C)
+#define REG_PLLCON1 (CLK_BA + 0x10)
+#define REG_PMCON (CLK_BA + 0x14)
+#define REG_IRQWAKECON (CLK_BA + 0x18)
+#define REG_IRQWAKEFLAG (CLK_BA + 0x1C)
+#define REG_IPSRST (CLK_BA + 0x20)
+#define REG_CLKEN1 (CLK_BA + 0x24)
+#define REG_CLKDIV1 (CLK_BA + 0x28)
+
+/* Define PLL freq setting */
+#define PLL_DISABLE 0x12B63
+#define PLL_66MHZ 0x2B63
+#define PLL_100MHZ 0x4F64
+#define PLL_120MHZ 0x4F63
+#define PLL_166MHZ 0x4124
+#define PLL_200MHZ 0x4F24
+
+/* Define AHB:CPUFREQ ratio */
+#define AHB_CPUCLK_1_1 0x00
+#define AHB_CPUCLK_1_2 0x01
+#define AHB_CPUCLK_1_4 0x02
+#define AHB_CPUCLK_1_8 0x03
+
+/* Define APB:AHB ratio */
+#define APB_AHB_1_2 0x01
+#define APB_AHB_1_4 0x02
+#define APB_AHB_1_8 0x03
+
+/* Define clock skew */
+#define DEFAULTSKEW 0x48
+
+#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ebi.h b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
new file mode 100644
index 00000000..b68455e7
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-ebi.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-ebi.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_EBI_H
+#define __ASM_ARCH_REGS_EBI_H
+
+/* EBI Control Registers */
+
+#define EBI_BA W90X900_VA_EBI
+#define REG_EBICON (EBI_BA + 0x00)
+#define REG_ROMCON (EBI_BA + 0x04)
+#define REG_SDCONF0 (EBI_BA + 0x08)
+#define REG_SDCONF1 (EBI_BA + 0x0C)
+#define REG_SDTIME0 (EBI_BA + 0x10)
+#define REG_SDTIME1 (EBI_BA + 0x14)
+#define REG_EXT0CON (EBI_BA + 0x18)
+#define REG_EXT1CON (EBI_BA + 0x1C)
+#define REG_EXT2CON (EBI_BA + 0x20)
+#define REG_EXT3CON (EBI_BA + 0x24)
+#define REG_EXT4CON (EBI_BA + 0x28)
+#define REG_CKSKEW (EBI_BA + 0x2C)
+
+#endif /* __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-gcr.h b/arch/arm/mach-w90x900/include/mach/regs-gcr.h
new file mode 100644
index 00000000..6087abd9
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-gcr.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-gcr.h
+ *
+ * Copyright (c) 2010 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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_GCR_H
+#define __ASM_ARCH_REGS_GCR_H
+
+/* Global control registers */
+
+#define GCR_BA W90X900_VA_GCR
+#define REG_PDID (GCR_BA+0x000)
+#define REG_PWRON (GCR_BA+0x004)
+#define REG_ARBCON (GCR_BA+0x008)
+#define REG_MFSEL (GCR_BA+0x00C)
+#define REG_EBIDPE (GCR_BA+0x010)
+#define REG_LCDDPE (GCR_BA+0x014)
+#define REG_GPIOCPE (GCR_BA+0x018)
+#define REG_GPIODPE (GCR_BA+0x01C)
+#define REG_GPIOEPE (GCR_BA+0x020)
+#define REG_GPIOFPE (GCR_BA+0x024)
+#define REG_GPIOGPE (GCR_BA+0x028)
+#define REG_GPIOHPE (GCR_BA+0x02C)
+#define REG_GPIOIPE (GCR_BA+0x030)
+#define REG_GTMP1 (GCR_BA+0x034)
+#define REG_GTMP2 (GCR_BA+0x038)
+#define REG_GTMP3 (GCR_BA+0x03C)
+
+#endif /* __ASM_ARCH_REGS_GCR_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-irq.h b/arch/arm/mach-w90x900/include/mach/regs-irq.h
new file mode 100644
index 00000000..8a3185fb
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-irq.h
@@ -0,0 +1,51 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-irq.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/regs-irq.h
+ *
+ * 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_IRQ_H
+#define ___ASM_ARCH_REGS_IRQ_H
+
+/* Advance Interrupt Controller (AIC) Registers */
+
+#define AIC_BA W90X900_VA_IRQ
+
+#define REG_AIC_IRQSC (AIC_BA+0x80)
+#define REG_AIC_GEN (AIC_BA+0x84)
+#define REG_AIC_GASR (AIC_BA+0x88)
+#define REG_AIC_GSCR (AIC_BA+0x8C)
+#define REG_AIC_IRSR (AIC_BA+0x100)
+#define REG_AIC_IASR (AIC_BA+0x104)
+#define REG_AIC_ISR (AIC_BA+0x108)
+#define REG_AIC_IPER (AIC_BA+0x10C)
+#define REG_AIC_ISNR (AIC_BA+0x110)
+#define REG_AIC_IMR (AIC_BA+0x114)
+#define REG_AIC_OISR (AIC_BA+0x118)
+#define REG_AIC_MECR (AIC_BA+0x120)
+#define REG_AIC_MDCR (AIC_BA+0x124)
+#define REG_AIC_SSCR (AIC_BA+0x128)
+#define REG_AIC_SCCR (AIC_BA+0x12C)
+#define REG_AIC_EOSCR (AIC_BA+0x130)
+#define AIC_IPER (0x10C)
+#define AIC_ISNR (0x110)
+
+/*16-18 bits of REG_AIC_GEN define irq(2-4) group*/
+
+#define TIMER2_IRQ (1 << 16)
+#define TIMER3_IRQ (1 << 17)
+#define TIMER4_IRQ (1 << 18)
+#define TIME_GROUP_IRQ (TIMER2_IRQ|TIMER3_IRQ|TIMER4_IRQ)
+
+#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ldm.h b/arch/arm/mach-w90x900/include/mach/regs-ldm.h
new file mode 100644
index 00000000..e9d480a5
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-ldm.h
@@ -0,0 +1,253 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Description:
+ * Nuvoton Display, LCM Register list
+ * Author: Wang Qiang (rurality.linux@gmail.com) 2009/12/11
+ *
+ */
+
+
+#ifndef __ASM_ARM_W90X900_REGS_LDM_H
+#define __ASM_ARM_W90X900_REGS_LDM_H
+
+#include <mach/map.h>
+
+/* Display Controller Control/Status Register */
+#define REG_LCM_DCCS (0x00)
+
+#define LCM_DCCS_ENG_RST (1 << 0)
+#define LCM_DCCS_VA_EN (1 << 1)
+#define LCM_DCCS_OSD_EN (1 << 2)
+#define LCM_DCCS_DISP_OUT_EN (1 << 3)
+#define LCM_DCCS_DISP_INT_EN (1 << 4)
+#define LCM_DCCS_CMD_ON (1 << 5)
+#define LCM_DCCS_FIELD_INTR (1 << 6)
+#define LCM_DCCS_SINGLE (1 << 7)
+
+enum LCM_DCCS_VA_SRC {
+ LCM_DCCS_VA_SRC_YUV422 = (0 << 8),
+ LCM_DCCS_VA_SRC_YCBCR422 = (1 << 8),
+ LCM_DCCS_VA_SRC_RGB888 = (2 << 8),
+ LCM_DCCS_VA_SRC_RGB666 = (3 << 8),
+ LCM_DCCS_VA_SRC_RGB565 = (4 << 8),
+ LCM_DCCS_VA_SRC_RGB444LOW = (5 << 8),
+ LCM_DCCS_VA_SRC_RGB444HIGH = (7 << 8)
+};
+
+
+/* Display Device Control Register */
+#define REG_LCM_DEV_CTRL (0x04)
+
+enum LCM_DEV_CTRL_SWAP_YCbCr {
+ LCM_DEV_CTRL_SWAP_UYVY = (0 << 1),
+ LCM_DEV_CTRL_SWAP_YUYV = (1 << 1),
+ LCM_DEV_CTRL_SWAP_VYUY = (2 << 1),
+ LCM_DEV_CTRL_SWAP_YVYU = (3 << 1)
+};
+
+enum LCM_DEV_CTRL_RGB_SHIFT {
+ LCM_DEV_CTRL_RGB_SHIFT_NOT = (0 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_ONECYCLE = (1 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_TWOCYCLE = (2 << 3),
+ LCM_DEV_CTRL_RGB_SHIFT_NOT_DEF = (3 << 3)
+};
+
+enum LCM_DEV_CTRL_DEVICE {
+ LCM_DEV_CTRL_DEVICE_YUV422 = (0 << 5),
+ LCM_DEV_CTRL_DEVICE_YUV444 = (1 << 5),
+ LCM_DEV_CTRL_DEVICE_UNIPAC = (4 << 5),
+ LCM_DEV_CTRL_DEVICE_SEIKO_EPSON = (5 << 5),
+ LCM_DEV_CTRL_DEVICE_HIGH_COLOR = (6 << 5),
+ LCM_DEV_CTRL_DEVICE_MPU = (7 << 5)
+};
+
+#define LCM_DEV_CTRL_LCD_DDA (8)
+#define LCM_DEV_CTRL_YUV2CCIR (16)
+
+enum LCM_DEV_CTRL_LCD_SEL {
+ LCM_DEV_CTRL_LCD_SEL_RGB_GBR = (0 << 17),
+ LCM_DEV_CTRL_LCD_SEL_BGR_RBG = (1 << 17),
+ LCM_DEV_CTRL_LCD_SEL_GBR_RGB = (2 << 17),
+ LCM_DEV_CTRL_LCD_SEL_RBG_BGR = (3 << 17)
+};
+
+enum LCM_DEV_CTRL_FAL_D {
+ LCM_DEV_CTRL_FAL_D_FALLING = (0 << 19),
+ LCM_DEV_CTRL_FAL_D_RISING = (1 << 19),
+};
+
+enum LCM_DEV_CTRL_H_POL {
+ LCM_DEV_CTRL_H_POL_LOW = (0 << 20),
+ LCM_DEV_CTRL_H_POL_HIGH = (1 << 20),
+};
+
+enum LCM_DEV_CTRL_V_POL {
+ LCM_DEV_CTRL_V_POL_LOW = (0 << 21),
+ LCM_DEV_CTRL_V_POL_HIGH = (1 << 21),
+};
+
+enum LCM_DEV_CTRL_VR_LACE {
+ LCM_DEV_CTRL_VR_LACE_NINTERLACE = (0 << 22),
+ LCM_DEV_CTRL_VR_LACE_INTERLACE = (1 << 22),
+};
+
+enum LCM_DEV_CTRL_LACE {
+ LCM_DEV_CTRL_LACE_NINTERLACE = (0 << 23),
+ LCM_DEV_CTRL_LACE_INTERLACE = (1 << 23),
+};
+
+enum LCM_DEV_CTRL_RGB_SCALE {
+ LCM_DEV_CTRL_RGB_SCALE_4096 = (0 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_65536 = (1 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_262144 = (2 << 24),
+ LCM_DEV_CTRL_RGB_SCALE_16777216 = (3 << 24),
+};
+
+enum LCM_DEV_CTRL_DBWORD {
+ LCM_DEV_CTRL_DBWORD_HALFWORD = (0 << 26),
+ LCM_DEV_CTRL_DBWORD_FULLWORD = (1 << 26),
+};
+
+enum LCM_DEV_CTRL_MPU68 {
+ LCM_DEV_CTRL_MPU68_80_SERIES = (0 << 27),
+ LCM_DEV_CTRL_MPU68_68_SERIES = (1 << 27),
+};
+
+enum LCM_DEV_CTRL_DE_POL {
+ LCM_DEV_CTRL_DE_POL_HIGH = (0 << 28),
+ LCM_DEV_CTRL_DE_POL_LOW = (1 << 28),
+};
+
+#define LCM_DEV_CTRL_CMD16 (29)
+#define LCM_DEV_CTRL_CM16t18 (30)
+#define LCM_DEV_CTRL_CMD_LOW (31)
+
+/* MPU-Interface LCD Write Command */
+#define REG_LCM_MPU_CMD (0x08)
+
+/* Interrupt Control/Status Register */
+#define REG_LCM_INT_CS (0x0c)
+#define LCM_INT_CS_DISP_F_EN (1 << 0)
+#define LCM_INT_CS_UNDERRUN_EN (1 << 1)
+#define LCM_INT_CS_BUS_ERROR_INT (1 << 28)
+#define LCM_INT_CS_UNDERRUN_INT (1 << 29)
+#define LCM_INT_CS_DISP_F_STATUS (1 << 30)
+#define LCM_INT_CS_DISP_F_INT (1 << 31)
+
+/* CRTC Display Size Control Register */
+#define REG_LCM_CRTC_SIZE (0x10)
+#define LCM_CRTC_SIZE_VTTVAL(x) ((x) << 16)
+#define LCM_CRTC_SIZE_HTTVAL(x) ((x) << 0)
+
+/* CRTC Display Enable End */
+#define REG_LCM_CRTC_DEND (0x14)
+#define LCM_CRTC_DEND_VDENDVAL(x) ((x) << 16)
+#define LCM_CRTC_DEND_HDENDVAL(x) ((x) << 0)
+
+/* CRTC Internal Horizontal Retrace Control Register */
+#define REG_LCM_CRTC_HR (0x18)
+#define LCM_CRTC_HR_EVAL(x) ((x) << 16)
+#define LCM_CRTC_HR_SVAL(x) ((x) << 0)
+
+/* CRTC Horizontal Sync Control Register */
+#define REG_LCM_CRTC_HSYNC (0x1C)
+#define LCM_CRTC_HSYNC_SHIFTVAL(x) ((x) << 30)
+#define LCM_CRTC_HSYNC_EVAL(x) ((x) << 16)
+#define LCM_CRTC_HSYNC_SVAL(x) ((x) << 0)
+
+/* CRTC Internal Vertical Retrace Control Register */
+#define REG_LCM_CRTC_VR (0x20)
+#define LCM_CRTC_VR_EVAL(x) ((x) << 16)
+#define LCM_CRTC_VR_SVAL(x) ((x) << 0)
+
+/* Video Stream Frame Buffer-0 Starting Address */
+#define REG_LCM_VA_BADDR0 (0x24)
+
+/* Video Stream Frame Buffer-1 Starting Address */
+#define REG_LCM_VA_BADDR1 (0x28)
+
+/* Video Stream Frame Buffer Control Register */
+#define REG_LCM_VA_FBCTRL (0x2C)
+#define LCM_VA_FBCTRL_IO_REGION_HALF (1 << 28)
+#define LCM_VA_FBCTRL_FIELD_DUAL (1 << 29)
+#define LCM_VA_FBCTRL_START_BUF (1 << 30)
+#define LCM_VA_FBCTRL_DB_EN (1 << 31)
+
+/* Video Stream Scaling Control Register */
+#define REG_LCM_VA_SCALE (0x30)
+#define LCM_VA_SCALE_XCOPY_INTERPOLATION (0 << 15)
+#define LCM_VA_SCALE_XCOPY_DUPLICATION (1 << 15)
+
+/* Image Stream Active Window Coordinates */
+#define REG_LCM_VA_WIN (0x38)
+
+/* Image Stream Stuff Pixel */
+#define REG_LCM_VA_STUFF (0x3C)
+
+/* OSD Window Starting Coordinates */
+#define REG_LCM_OSD_WINS (0x40)
+
+/* OSD Window Ending Coordinates */
+#define REG_LCM_OSD_WINE (0x44)
+
+/* OSD Stream Frame Buffer Starting Address */
+#define REG_LCM_OSD_BADDR (0x48)
+
+/* OSD Stream Frame Buffer Control Register */
+#define REG_LCM_OSD_FBCTRL (0x4c)
+
+/* OSD Overlay Control Register */
+#define REG_LCM_OSD_OVERLAY (0x50)
+
+/* OSD Overlay Color-Key Pattern Register */
+#define REG_LCM_OSD_CKEY (0x54)
+
+/* OSD Overlay Color-Key Mask Register */
+#define REG_LCM_OSD_CMASK (0x58)
+
+/* OSD Window Skip1 Register */
+#define REG_LCM_OSD_SKIP1 (0x5C)
+
+/* OSD Window Skip2 Register */
+#define REG_LCM_OSD_SKIP2 (0x60)
+
+/* OSD horizontal up scaling control register */
+#define REG_LCM_OSD_SCALE (0x64)
+
+/* MPU Vsync control register */
+#define REG_LCM_MPU_VSYNC (0x68)
+
+/* Hardware cursor control Register */
+#define REG_LCM_HC_CTRL (0x6C)
+
+/* Hardware cursot tip point potison on va picture */
+#define REG_LCM_HC_POS (0x70)
+
+/* Hardware Cursor Window Buffer Control Register */
+#define REG_LCM_HC_WBCTRL (0x74)
+
+/* Hardware cursor memory base address register */
+#define REG_LCM_HC_BADDR (0x78)
+
+/* Hardware cursor color ram register mapped to bpp = 0 */
+#define REG_LCM_HC_COLOR0 (0x7C)
+
+/* Hardware cursor color ram register mapped to bpp = 1 */
+#define REG_LCM_HC_COLOR1 (0x80)
+
+/* Hardware cursor color ram register mapped to bpp = 2 */
+#define REG_LCM_HC_COLOR2 (0x84)
+
+/* Hardware cursor color ram register mapped to bpp = 3 */
+#define REG_LCM_HC_COLOR3 (0x88)
+
+#endif /* __ASM_ARM_W90X900_REGS_LDM_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-serial.h b/arch/arm/mach-w90x900/include/mach/regs-serial.h
new file mode 100644
index 00000000..f08fa0d7
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-serial.h
@@ -0,0 +1,59 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-serial.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/regs-serial.h
+ *
+ * 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_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define UART0_BA W90X900_VA_UART
+#define UART1_BA (W90X900_VA_UART+0x100)
+#define UART2_BA (W90X900_VA_UART+0x200)
+#define UART3_BA (W90X900_VA_UART+0x300)
+#define UART4_BA (W90X900_VA_UART+0x400)
+
+#define UART0_PA W90X900_PA_UART
+#define UART1_PA (W90X900_PA_UART+0x100)
+#define UART2_PA (W90X900_PA_UART+0x200)
+#define UART3_PA (W90X900_PA_UART+0x300)
+#define UART4_PA (W90X900_PA_UART+0x400)
+
+#ifndef __ASSEMBLY__
+
+struct w90x900_uart_clksrc {
+ const char *name;
+ unsigned int divisor;
+ unsigned int min_baud;
+ unsigned int max_baud;
+};
+
+struct w90x900_uartcfg {
+ unsigned char hwport;
+ unsigned char unused;
+ unsigned short flags;
+ unsigned long uart_flags;
+
+ unsigned long ucon;
+ unsigned long ulcon;
+ unsigned long ufcon;
+
+ struct w90x900_uart_clksrc *clocks;
+ unsigned int clocks_size;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_ARM_REGS_SERIAL_H */
+
diff --git a/arch/arm/mach-w90x900/include/mach/regs-timer.h b/arch/arm/mach-w90x900/include/mach/regs-timer.h
new file mode 100644
index 00000000..8f390620
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-timer.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/regs-timer.h
+ *
+ * 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_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+/* Timer Registers */
+
+#define TMR_BA W90X900_VA_TIMER
+#define REG_TCSR0 (TMR_BA+0x00)
+#define REG_TCSR1 (TMR_BA+0x04)
+#define REG_TICR0 (TMR_BA+0x08)
+#define REG_TICR1 (TMR_BA+0x0C)
+#define REG_TDR0 (TMR_BA+0x10)
+#define REG_TDR1 (TMR_BA+0x14)
+#define REG_TISR (TMR_BA+0x18)
+#define REG_WTCR (TMR_BA+0x1C)
+#define REG_TCSR2 (TMR_BA+0x20)
+#define REG_TCSR3 (TMR_BA+0x24)
+#define REG_TICR2 (TMR_BA+0x28)
+#define REG_TICR3 (TMR_BA+0x2C)
+#define REG_TDR2 (TMR_BA+0x30)
+#define REG_TDR3 (TMR_BA+0x34)
+#define REG_TCSR4 (TMR_BA+0x40)
+#define REG_TICR4 (TMR_BA+0x48)
+#define REG_TDR4 (TMR_BA+0x50)
+
+#endif /* __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-usb.h b/arch/arm/mach-w90x900/include/mach/regs-usb.h
new file mode 100644
index 00000000..ab74b0c2
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/regs-usb.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/regs-usb.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#ifndef __ASM_ARCH_REGS_USB_H
+#define __ASM_ARCH_REGS_USB_H
+
+/* usb Control Registers */
+#define USBH_BA W90X900_VA_USBEHCIHOST
+#define USBD_BA W90X900_VA_USBDEV
+#define USBO_BA W90X900_VA_USBOHCIHOST
+
+/* USB Host Control Registers */
+#define REG_UPSCR0 (USBH_BA+0x064)
+#define REG_UPSCR1 (USBH_BA+0x068)
+#define REG_USBPCR0 (USBH_BA+0x0C4)
+#define REG_USBPCR1 (USBH_BA+0x0C8)
+
+/* USBH OHCI Control Registers */
+#define REG_OpModEn (USBO_BA+0x204)
+/*This bit controls the polarity of over
+*current flag from external power IC.
+*/
+#define OCALow 0x08
+
+#endif /* __ASM_ARCH_REGS_USB_H */
diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h
new file mode 100644
index 00000000..ce228bdc
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/system.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/system.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/system.h
+ *
+ * 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/io.h>
+#include <asm/proc-fns.h>
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define WTCR (TMR_BA + 0x1C)
+#define WTCLK (1 << 10)
+#define WTE (1 << 7)
+#define WTRE (1 << 1)
+
+static void arch_idle(void)
+{
+}
+
+static void arch_reset(char mode, const char *cmd)
+{
+ if (mode == 's') {
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
+ } else {
+ __raw_writel(WTE | WTRE | WTCLK, WTCR);
+ }
+}
+
diff --git a/arch/arm/mach-w90x900/include/mach/timex.h b/arch/arm/mach-w90x900/include/mach/timex.h
new file mode 100644
index 00000000..164dce0b
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/timex.h
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/timex.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/timex.h
+ *
+ * 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_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+/* CLOCK_TICK_RATE Now, I don't use it. */
+
+#define CLOCK_TICK_RATE 15000000
+
+#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h
new file mode 100644
index 00000000..03130212
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/uncompress.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/uncompress.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/uncompress.h
+ *
+ * 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_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+/* Defines for UART registers */
+
+#include <mach/regs-serial.h>
+#include <mach/map.h>
+#include <linux/serial_reg.h>
+
+#define arch_decomp_wdog()
+
+#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
+static volatile u32 * const uart_base = (u32 *)UART0_PA;
+
+static void putc(int ch)
+{
+ /* Check THRE and TEMT bits before we transmit the character.
+ */
+ while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
+ barrier();
+
+ *uart_base = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+static void arch_decomp_setup(void)
+{
+}
+
+#endif/* __ASM_W90X900_UNCOMPRESS_H */
diff --git a/arch/arm/mach-w90x900/include/mach/vmalloc.h b/arch/arm/mach-w90x900/include/mach/vmalloc.h
new file mode 100644
index 00000000..b067e445
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/vmalloc.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-w90x900/include/mach/vmalloc.h
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * Based on arch/arm/mach-s3c2410/include/mach/vmalloc.h
+ *
+ * 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_VMALLOC_H
+#define __ASM_ARCH_VMALLOC_H
+
+#define VMALLOC_END (0xe0000000UL)
+
+#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
new file mode 100644
index 00000000..556778e8
--- /dev/null
+++ b/arch/arm/mach-w90x900/include/mach/w90p910_keypad.h
@@ -0,0 +1,15 @@
+#ifndef __ASM_ARCH_W90P910_KEYPAD_H
+#define __ASM_ARCH_W90P910_KEYPAD_H
+
+#include <linux/input/matrix_keypad.h>
+
+extern void mfp_set_groupi(struct device *dev);
+
+struct w90p910_keypad_platform_data {
+ const struct matrix_keymap_data *keymap_data;
+
+ unsigned int prescale;
+ unsigned int debounce;
+};
+
+#endif /* __ASM_ARCH_W90P910_KEYPAD_H */
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
new file mode 100644
index 00000000..7bf143c4
--- /dev/null
+++ b/arch/arm/mach-w90x900/irq.c
@@ -0,0 +1,214 @@
+/*
+ * linux/arch/arm/mach-w90x900/irq.c
+ *
+ * based on linux/arch/arm/plat-s3c24xx/irq.c by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/ptrace.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-irq.h>
+
+struct group_irq {
+ unsigned long gpen;
+ unsigned int enabled;
+ void (*enable)(struct group_irq *, int enable);
+};
+
+static DEFINE_SPINLOCK(groupirq_lock);
+
+#define DEFINE_GROUP(_name, _ctrlbit, _num) \
+struct group_irq group_##_name = { \
+ .enable = nuc900_group_enable, \
+ .gpen = ((1 << _num) - 1) << _ctrlbit, \
+ }
+
+static void nuc900_group_enable(struct group_irq *gpirq, int enable);
+
+static DEFINE_GROUP(nirq0, 0, 4);
+static DEFINE_GROUP(nirq1, 4, 4);
+static DEFINE_GROUP(usbh, 8, 2);
+static DEFINE_GROUP(ottimer, 16, 3);
+static DEFINE_GROUP(gdma, 20, 2);
+static DEFINE_GROUP(sc, 24, 2);
+static DEFINE_GROUP(i2c, 26, 2);
+static DEFINE_GROUP(ps2, 28, 2);
+
+static int group_irq_enable(struct group_irq *group_irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&groupirq_lock, flags);
+ if (group_irq->enabled++ == 0)
+ (group_irq->enable)(group_irq, 1);
+ spin_unlock_irqrestore(&groupirq_lock, flags);
+
+ return 0;
+}
+
+static void group_irq_disable(struct group_irq *group_irq)
+{
+ unsigned long flags;
+
+ WARN_ON(group_irq->enabled == 0);
+
+ spin_lock_irqsave(&groupirq_lock, flags);
+ if (--group_irq->enabled == 0)
+ (group_irq->enable)(group_irq, 0);
+ spin_unlock_irqrestore(&groupirq_lock, flags);
+}
+
+static void nuc900_group_enable(struct group_irq *gpirq, int enable)
+{
+ unsigned int groupen = gpirq->gpen;
+ unsigned long regval;
+
+ regval = __raw_readl(REG_AIC_GEN);
+
+ if (enable)
+ regval |= groupen;
+ else
+ regval &= ~groupen;
+
+ __raw_writel(regval, REG_AIC_GEN);
+}
+
+static void nuc900_irq_mask(struct irq_data *d)
+{
+ struct group_irq *group_irq;
+
+ group_irq = NULL;
+
+ __raw_writel(1 << d->irq, REG_AIC_MDCR);
+
+ switch (d->irq) {
+ case IRQ_GROUP0:
+ group_irq = &group_nirq0;
+ break;
+
+ case IRQ_GROUP1:
+ group_irq = &group_nirq1;
+ break;
+
+ case IRQ_USBH:
+ group_irq = &group_usbh;
+ break;
+
+ case IRQ_T_INT_GROUP:
+ group_irq = &group_ottimer;
+ break;
+
+ case IRQ_GDMAGROUP:
+ group_irq = &group_gdma;
+ break;
+
+ case IRQ_SCGROUP:
+ group_irq = &group_sc;
+ break;
+
+ case IRQ_I2CGROUP:
+ group_irq = &group_i2c;
+ break;
+
+ case IRQ_P2SGROUP:
+ group_irq = &group_ps2;
+ break;
+ }
+
+ if (group_irq)
+ group_irq_disable(group_irq);
+}
+
+/*
+ * By the w90p910 spec,any irq,only write 1
+ * to REG_AIC_EOSCR for ACK
+ */
+
+static void nuc900_irq_ack(struct irq_data *d)
+{
+ __raw_writel(0x01, REG_AIC_EOSCR);
+}
+
+static void nuc900_irq_unmask(struct irq_data *d)
+{
+ struct group_irq *group_irq;
+
+ group_irq = NULL;
+
+ __raw_writel(1 << d->irq, REG_AIC_MECR);
+
+ switch (d->irq) {
+ case IRQ_GROUP0:
+ group_irq = &group_nirq0;
+ break;
+
+ case IRQ_GROUP1:
+ group_irq = &group_nirq1;
+ break;
+
+ case IRQ_USBH:
+ group_irq = &group_usbh;
+ break;
+
+ case IRQ_T_INT_GROUP:
+ group_irq = &group_ottimer;
+ break;
+
+ case IRQ_GDMAGROUP:
+ group_irq = &group_gdma;
+ break;
+
+ case IRQ_SCGROUP:
+ group_irq = &group_sc;
+ break;
+
+ case IRQ_I2CGROUP:
+ group_irq = &group_i2c;
+ break;
+
+ case IRQ_P2SGROUP:
+ group_irq = &group_ps2;
+ break;
+ }
+
+ if (group_irq)
+ group_irq_enable(group_irq);
+}
+
+static struct irq_chip nuc900_irq_chip = {
+ .irq_ack = nuc900_irq_ack,
+ .irq_mask = nuc900_irq_mask,
+ .irq_unmask = nuc900_irq_unmask,
+};
+
+void __init nuc900_init_irq(void)
+{
+ int irqno;
+
+ __raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
+
+ for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
+ irq_set_chip_and_handler(irqno, &nuc900_irq_chip,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c
new file mode 100644
index 00000000..30fccde9
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc910evb.c
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc910.h"
+
+static void __init nuc910evb_map_io(void)
+{
+ nuc910_map_io();
+ nuc910_init_clocks();
+}
+
+static void __init nuc910evb_init(void)
+{
+ nuc910_board_init();
+}
+
+MACHINE_START(W90P910EVB, "W90P910EVB")
+ /* Maintainer: Wan ZongShun */
+ .boot_params = 0,
+ .map_io = nuc910evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc910evb_init,
+ .timer = &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
new file mode 100644
index 00000000..590c99b9
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc950evb.c
@@ -0,0 +1,45 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc950evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ * history:
+ * Wang Qiang (rurality.linux@gmail.com) add LCD support
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+#include <mach/fb.h>
+
+#include "nuc950.h"
+
+static void __init nuc950evb_map_io(void)
+{
+ nuc950_map_io();
+ nuc950_init_clocks();
+}
+
+static void __init nuc950evb_init(void)
+{
+ nuc950_board_init();
+}
+
+MACHINE_START(W90P950EVB, "W90P950EVB")
+ /* Maintainer: Wan ZongShun */
+ .boot_params = 0,
+ .map_io = nuc950evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc950evb_init,
+ .timer = &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c
new file mode 100644
index 00000000..e09c645d
--- /dev/null
+++ b/arch/arm/mach-w90x900/mach-nuc960evb.c
@@ -0,0 +1,42 @@
+/*
+ * linux/arch/arm/mach-w90x900/mach-nuc960evb.c
+ *
+ * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
+ *
+ * Copyright (C) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <mach/map.h>
+
+#include "nuc960.h"
+
+static void __init nuc960evb_map_io(void)
+{
+ nuc960_map_io();
+ nuc960_init_clocks();
+}
+
+static void __init nuc960evb_init(void)
+{
+ nuc960_board_init();
+}
+
+MACHINE_START(W90N960EVB, "W90N960EVB")
+ /* Maintainer: Wan ZongShun */
+ .boot_params = 0,
+ .map_io = nuc960evb_map_io,
+ .init_irq = nuc900_init_irq,
+ .init_machine = nuc960evb_init,
+ .timer = &nuc900_timer,
+MACHINE_END
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c
new file mode 100644
index 00000000..fb7fb627
--- /dev/null
+++ b/arch/arm/mach-w90x900/mfp.c
@@ -0,0 +1,164 @@
+/*
+ * linux/arch/arm/mach-w90x900/mfp.c
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation
+ *
+ * Wan ZongShun <mcuos.com@gmail.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;version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#define REG_MFSEL (W90X900_VA_GCR + 0xC)
+
+#define GPSELF (0x01 << 1)
+
+#define GPSELC (0x03 << 2)
+#define ENKPI (0x02 << 2)
+#define ENNAND (0x01 << 2)
+
+#define GPSELEI0 (0x01 << 26)
+#define GPSELEI1 (0x01 << 27)
+
+#define GPIOG0TO1 (0x03 << 14)
+#define GPIOG2TO3 (0x03 << 16)
+#define GPIOG22TO23 (0x03 << 22)
+
+#define ENSPI (0x0a << 14)
+#define ENI2C0 (0x01 << 14)
+#define ENI2C1 (0x01 << 16)
+#define ENAC97 (0x02 << 22)
+
+static DEFINE_MUTEX(mfp_mutex);
+
+void mfp_set_groupf(struct device *dev)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON(!dev);
+
+ mutex_lock(&mfp_mutex);
+
+ dev_id = dev_name(dev);
+
+ mfpen = __raw_readl(REG_MFSEL);
+
+ if (strcmp(dev_id, "nuc900-emc") == 0)
+ mfpen |= GPSELF;/*enable mac*/
+ else
+ mfpen &= ~GPSELF;/*GPIOF[9:0]*/
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupf);
+
+void mfp_set_groupc(struct device *dev)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON(!dev);
+
+ mutex_lock(&mfp_mutex);
+
+ dev_id = dev_name(dev);
+
+ mfpen = __raw_readl(REG_MFSEL);
+
+ if (strcmp(dev_id, "nuc900-lcd") == 0)
+ mfpen |= GPSELC;/*enable lcd*/
+ else if (strcmp(dev_id, "nuc900-kpi") == 0) {
+ mfpen &= (~GPSELC);/*enable kpi*/
+ mfpen |= ENKPI;
+ } else if (strcmp(dev_id, "nuc900-nand") == 0) {
+ mfpen &= (~GPSELC);/*enable nand*/
+ mfpen |= ENNAND;
+ } else
+ mfpen &= (~GPSELC);/*GPIOC[14:0]*/
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupc);
+
+void mfp_set_groupi(struct device *dev)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON(!dev);
+
+ mutex_lock(&mfp_mutex);
+
+ dev_id = dev_name(dev);
+
+ mfpen = __raw_readl(REG_MFSEL);
+
+ mfpen &= ~GPSELEI1;/*default gpio16*/
+
+ if (strcmp(dev_id, "nuc900-wdog") == 0)
+ mfpen |= GPSELEI1;/*enable wdog*/
+ else if (strcmp(dev_id, "nuc900-atapi") == 0)
+ mfpen |= GPSELEI0;/*enable atapi*/
+ else if (strcmp(dev_id, "nuc900-keypad") == 0)
+ mfpen &= ~GPSELEI0;/*enable keypad*/
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupi);
+
+void mfp_set_groupg(struct device *dev)
+{
+ unsigned long mfpen;
+ const char *dev_id;
+
+ BUG_ON(!dev);
+
+ mutex_lock(&mfp_mutex);
+
+ dev_id = dev_name(dev);
+
+ mfpen = __raw_readl(REG_MFSEL);
+
+ if (strcmp(dev_id, "nuc900-spi") == 0) {
+ mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
+ mfpen |= ENSPI;/*enable spi*/
+ } else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
+ mfpen &= ~(GPIOG0TO1);
+ mfpen |= ENI2C0;/*enable i2c0*/
+ } else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
+ mfpen &= ~(GPIOG2TO3);
+ mfpen |= ENI2C1;/*enable i2c1*/
+ } else if (strcmp(dev_id, "nuc900-audio") == 0) {
+ mfpen &= ~(GPIOG22TO23);
+ mfpen |= ENAC97;/*enable AC97*/
+ } else {
+ mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
+ }
+
+ __raw_writel(mfpen, REG_MFSEL);
+
+ mutex_unlock(&mfp_mutex);
+}
+EXPORT_SYMBOL(mfp_set_groupg);
+
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
new file mode 100644
index 00000000..1523f413
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.c
@@ -0,0 +1,62 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc910.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2009 Nuvoton corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC910 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include "cpu.h"
+#include "clock.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc910_dev[] __initdata = {
+ &nuc900_device_ts,
+ &nuc900_device_rtc,
+ &nuc900_device_lcd,
+ &nuc900_device_kpi,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc910evb_iodesc[] __initdata = {
+ IODESC_ENT(USBEHCIHOST),
+ IODESC_ENT(USBOHCIHOST),
+ IODESC_ENT(KPI),
+ IODESC_ENT(USBDEV),
+ IODESC_ENT(ADC),
+};
+
+/*Init NUC910 evb io*/
+
+void __init nuc910_map_io(void)
+{
+ nuc900_map_io(nuc910evb_iodesc, ARRAY_SIZE(nuc910evb_iodesc));
+}
+
+/*Init NUC910 clock*/
+
+void __init nuc910_init_clocks(void)
+{
+ nuc900_init_clocks();
+}
+
+/*Init NUC910 board info*/
+
+void __init nuc910_board_init(void)
+{
+ nuc900_board_init(nuc910_dev, ARRAY_SIZE(nuc910_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc910.h b/arch/arm/mach-w90x900/nuc910.h
new file mode 100644
index 00000000..83e9ba5f
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc910.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc910.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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 map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc910.c */
+
+extern void nuc910_board_init(void);
+extern void nuc910_init_clocks(void);
+extern void nuc910_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
new file mode 100644
index 00000000..5704f74a
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.c
@@ -0,0 +1,56 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc950.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC950 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+#include "cpu.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc950_dev[] __initdata = {
+ &nuc900_device_kpi,
+ &nuc900_device_fmi,
+ &nuc900_device_lcd,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc950evb_iodesc[] __initdata = {
+};
+
+/*Init NUC950 evb io*/
+
+void __init nuc950_map_io(void)
+{
+ nuc900_map_io(nuc950evb_iodesc, ARRAY_SIZE(nuc950evb_iodesc));
+}
+
+/*Init NUC950 clock*/
+
+void __init nuc950_init_clocks(void)
+{
+ nuc900_init_clocks();
+}
+
+/*Init NUC950 board info*/
+
+void __init nuc950_board_init(void)
+{
+ nuc900_board_init(nuc950_dev, ARRAY_SIZE(nuc950_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc950.h b/arch/arm/mach-w90x900/nuc950.h
new file mode 100644
index 00000000..98a1148b
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc950.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc950.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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 map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc950.c */
+
+extern void nuc950_board_init(void);
+extern void nuc950_init_clocks(void);
+extern void nuc950_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc960.c b/arch/arm/mach-w90x900/nuc960.c
new file mode 100644
index 00000000..8851a3a2
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-w90x900/nuc960.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
+ *
+ * Copyright (c) 2008 Nuvoton technology corporation.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * NUC960 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation;version 2 of the License.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include "cpu.h"
+
+/* define specific CPU platform device */
+
+static struct platform_device *nuc960_dev[] __initdata = {
+ &nuc900_device_kpi,
+ &nuc900_device_fmi,
+};
+
+/* define specific CPU platform io map */
+
+static struct map_desc nuc960evb_iodesc[] __initdata = {
+};
+
+/*Init NUC960 evb io*/
+
+void __init nuc960_map_io(void)
+{
+ nuc900_map_io(nuc960evb_iodesc, ARRAY_SIZE(nuc960evb_iodesc));
+}
+
+/*Init NUC960 clock*/
+
+void __init nuc960_init_clocks(void)
+{
+ nuc900_init_clocks();
+}
+
+/*Init NUC960 board info*/
+
+void __init nuc960_board_init(void)
+{
+ nuc900_board_init(nuc960_dev, ARRAY_SIZE(nuc960_dev));
+}
diff --git a/arch/arm/mach-w90x900/nuc960.h b/arch/arm/mach-w90x900/nuc960.h
new file mode 100644
index 00000000..f0c07cbe
--- /dev/null
+++ b/arch/arm/mach-w90x900/nuc960.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-w90x900/nuc960.h
+ *
+ * Copyright (c) 2008 Nuvoton corporation
+ *
+ * Header file for NUC900 CPU support
+ *
+ * Wan ZongShun <mcuos.com@gmail.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 map_desc;
+struct sys_timer;
+
+/* core initialisation functions */
+
+extern void nuc900_init_irq(void);
+extern struct sys_timer nuc900_timer;
+
+/* extern file from nuc960.c */
+
+extern void nuc960_board_init(void);
+extern void nuc960_init_clocks(void);
+extern void nuc960_map_io(void);
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
new file mode 100644
index 00000000..a2c4e2d0
--- /dev/null
+++ b/arch/arm/mach-w90x900/time.c
@@ -0,0 +1,176 @@
+/*
+ * linux/arch/arm/mach-w90x900/time.c
+ *
+ * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks
+ *
+ * Copyright (c) 2009 Nuvoton technology corporation
+ * All rights reserved.
+ *
+ * Wan ZongShun <mcuos.com@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+
+#include <mach/map.h>
+#include <mach/regs-timer.h>
+
+#define RESETINT 0x1f
+#define PERIOD (0x01 << 27)
+#define ONESHOT (0x00 << 27)
+#define COUNTEN (0x01 << 30)
+#define INTEN (0x01 << 29)
+
+#define TICKS_PER_SEC 100
+#define PRESCALE 0x63 /* Divider = prescale + 1 */
+
+#define TDR_SHIFT 24
+
+static unsigned int timer0_load;
+
+static void nuc900_clockevent_setmode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+ unsigned int val;
+
+ val = __raw_readl(REG_TCSR0);
+ val &= ~(0x03 << 27);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ __raw_writel(timer0_load, REG_TICR0);
+ val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+
+ __raw_writel(val, REG_TCSR0);
+}
+
+static int nuc900_clockevent_setnextevent(unsigned long evt,
+ struct clock_event_device *clk)
+{
+ unsigned int val;
+
+ __raw_writel(evt, REG_TICR0);
+
+ val = __raw_readl(REG_TCSR0);
+ val |= (COUNTEN | INTEN | PRESCALE);
+ __raw_writel(val, REG_TCSR0);
+
+ return 0;
+}
+
+static struct clock_event_device nuc900_clockevent_device = {
+ .name = "nuc900-timer0",
+ .shift = 32,
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = nuc900_clockevent_setmode,
+ .set_next_event = nuc900_clockevent_setnextevent,
+ .rating = 300,
+};
+
+/*IRQ handler for the timer*/
+
+static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &nuc900_clockevent_device;
+
+ __raw_writel(0x01, REG_TISR); /* clear TIF0 */
+
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction nuc900_timer0_irq = {
+ .name = "nuc900-timer0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = nuc900_timer0_interrupt,
+};
+
+static void __init nuc900_clockevents_init(void)
+{
+ unsigned int rate;
+ struct clk *clk = clk_get(NULL, "timer0");
+
+ BUG_ON(IS_ERR(clk));
+
+ __raw_writel(0x00, REG_TCSR0);
+
+ clk_enable(clk);
+ rate = clk_get_rate(clk) / (PRESCALE + 1);
+
+ timer0_load = (rate / TICKS_PER_SEC);
+
+ __raw_writel(RESETINT, REG_TISR);
+ setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
+
+ nuc900_clockevent_device.mult = div_sc(rate, NSEC_PER_SEC,
+ nuc900_clockevent_device.shift);
+ nuc900_clockevent_device.max_delta_ns = clockevent_delta2ns(0xffffffff,
+ &nuc900_clockevent_device);
+ nuc900_clockevent_device.min_delta_ns = clockevent_delta2ns(0xf,
+ &nuc900_clockevent_device);
+ nuc900_clockevent_device.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&nuc900_clockevent_device);
+}
+
+static void __init nuc900_clocksource_init(void)
+{
+ unsigned int val;
+ unsigned int rate;
+ struct clk *clk = clk_get(NULL, "timer1");
+
+ BUG_ON(IS_ERR(clk));
+
+ __raw_writel(0x00, REG_TCSR1);
+
+ clk_enable(clk);
+ rate = clk_get_rate(clk) / (PRESCALE + 1);
+
+ __raw_writel(0xffffffff, REG_TICR1);
+
+ val = __raw_readl(REG_TCSR1);
+ val |= (COUNTEN | PERIOD | PRESCALE);
+ __raw_writel(val, REG_TCSR1);
+
+ clocksource_mmio_init(REG_TDR1, "nuc900-timer1", rate, 200,
+ TDR_SHIFT, clocksource_mmio_readl_down);
+}
+
+static void __init nuc900_timer_init(void)
+{
+ nuc900_clocksource_init();
+ nuc900_clockevents_init();
+}
+
+struct sys_timer nuc900_timer = {
+ .init = nuc900_timer_init,
+};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
new file mode 100644
index 00000000..9df1154a
--- /dev/null
+++ b/arch/arm/mm/Kconfig
@@ -0,0 +1,891 @@
+comment "Processor Type"
+
+# Select CPU types depending on the architecture selected. This selects
+# which CPUs we support in the kernel image, and the compiler instruction
+# optimiser behaviour.
+
+# ARM610
+config CPU_ARM610
+ bool "Support ARM610 processor" if ARCH_RPC
+ select CPU_32v3
+ select CPU_CACHE_V3
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V3 if MMU
+ select CPU_TLB_V3 if MMU
+ select CPU_PABRT_LEGACY
+ help
+ The ARM610 is the successor to the ARM3 processor
+ and was produced by VLSI Technology Inc.
+
+ Say Y if you want support for the ARM610 processor.
+ Otherwise, say N.
+
+# ARM7TDMI
+config CPU_ARM7TDMI
+ bool "Support ARM7TDMI processor"
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4
+ help
+ A 32-bit RISC microprocessor based on the ARM7 processor core
+ which has no memory control unit and cache.
+
+ Say Y if you want support for the ARM7TDMI processor.
+ Otherwise, say N.
+
+# ARM710
+config CPU_ARM710
+ bool "Support ARM710 processor" if ARCH_RPC
+ select CPU_32v3
+ select CPU_CACHE_V3
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V3 if MMU
+ select CPU_TLB_V3 if MMU
+ select CPU_PABRT_LEGACY
+ help
+ A 32-bit RISC microprocessor based on the ARM7 processor core
+ designed by Advanced RISC Machines Ltd. The ARM710 is the
+ successor to the ARM610 processor. It was released in
+ July 1994 by VLSI Technology Inc.
+
+ Say Y if you want support for the ARM710 processor.
+ Otherwise, say N.
+
+# ARM720T
+config CPU_ARM720T
+ bool "Support ARM720T processor" if ARCH_INTEGRATOR
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WT if MMU
+ select CPU_TLB_V4WT if MMU
+ help
+ A 32-bit RISC processor with 8kByte Cache, Write Buffer and
+ MMU built around an ARM7TDMI core.
+
+ Say Y if you want support for the ARM720T processor.
+ Otherwise, say N.
+
+# ARM740T
+config CPU_ARM740T
+ bool "Support ARM740T processor" if ARCH_INTEGRATOR
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_LV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V3 # although the core is v4t
+ select CPU_CP15_MPU
+ help
+ A 32-bit RISC processor with 8KB cache or 4KB variants,
+ write buffer and MPU(Protection Unit) built around
+ an ARM7TDMI core.
+
+ Say Y if you want support for the ARM740T processor.
+ Otherwise, say N.
+
+# ARM9TDMI
+config CPU_ARM9TDMI
+ bool "Support ARM9TDMI processor"
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_NOMMU
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4
+ help
+ A 32-bit RISC microprocessor based on the ARM9 processor core
+ which has no memory control unit and cache.
+
+ Say Y if you want support for the ARM9TDMI processor.
+ Otherwise, say N.
+
+# ARM920T
+config CPU_ARM920T
+ bool "Support ARM920T processor" if ARCH_INTEGRATOR
+ select CPU_32v4T
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM920T is licensed to be produced by numerous vendors,
+ and is used in the Cirrus EP93xx and the Samsung S3C2410.
+
+ Say Y if you want support for the ARM920T processor.
+ Otherwise, say N.
+
+# ARM922T
+config CPU_ARM922T
+ bool "Support ARM922T processor" if ARCH_INTEGRATOR
+ select CPU_32v4T
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM922T is a version of the ARM920T, but with smaller
+ instruction and data caches. It is used in Altera's
+ Excalibur XA device family and Micrel's KS8695 Centaur.
+
+ Say Y if you want support for the ARM922T processor.
+ Otherwise, say N.
+
+# ARM925T
+config CPU_ARM925T
+ bool "Support ARM925T processor" if ARCH_OMAP1
+ select CPU_32v4T
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM925T is a mix between the ARM920T and ARM926T, but with
+ different instruction and data caches. It is used in TI's OMAP
+ device family.
+
+ Say Y if you want support for the ARM925T processor.
+ Otherwise, say N.
+
+# ARM926T
+config CPU_ARM926T
+ bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
+ select CPU_32v5
+ select CPU_ABRT_EV5TJ
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ help
+ This is a variant of the ARM920. It has slightly different
+ instruction sequences for cache and TLB operations. Curiously,
+ there is no documentation on it at the ARM corporate website.
+
+ Say Y if you want support for the ARM926T processor.
+ Otherwise, say N.
+
+# FA526
+config CPU_FA526
+ bool
+ select CPU_32v4
+ select CPU_ABRT_EV4
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_CACHE_FA
+ select CPU_COPY_FA if MMU
+ select CPU_TLB_FA if MMU
+ help
+ The FA526 is a version of the ARMv4 compatible processor with
+ Branch Target Buffer, Unified TLB and cache line size 16.
+
+ Say Y if you want support for the FA526 processor.
+ Otherwise, say N.
+
+# ARM940T
+config CPU_ARM940T
+ bool "Support ARM940T processor" if ARCH_INTEGRATOR
+ depends on !MMU
+ select CPU_32v4T
+ select CPU_ABRT_NOMMU
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MPU
+ help
+ ARM940T is a member of the ARM9TDMI family of general-
+ purpose microprocessors with MPU and separate 4KB
+ instruction and 4KB data cases, each with a 4-word line
+ length.
+
+ Say Y if you want support for the ARM940T processor.
+ Otherwise, say N.
+
+# ARM946E-S
+config CPU_ARM946E
+ bool "Support ARM946E-S processor" if ARCH_INTEGRATOR
+ depends on !MMU
+ select CPU_32v5
+ select CPU_ABRT_NOMMU
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MPU
+ help
+ ARM946E-S is a member of the ARM9E-S family of high-
+ performance, 32-bit system-on-chip processor solutions.
+ The TCM and ARMv5TE 32-bit instruction set is supported.
+
+ Say Y if you want support for the ARM946E-S processor.
+ Otherwise, say N.
+
+# ARM1020 - needs validating
+config CPU_ARM1020
+ bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM1020 is the 32K cached version of the ARM10 processor,
+ with an addition of a floating-point unit.
+
+ Say Y if you want support for the ARM1020 processor.
+ Otherwise, say N.
+
+# ARM1020E - needs validating
+config CPU_ARM1020E
+ bool "Support ARM1020E processor" if ARCH_INTEGRATOR
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WT
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WBI if MMU
+ depends on n
+
+# ARM1022E
+config CPU_ARM1022
+ bool "Support ARM1022E processor" if ARCH_INTEGRATOR
+ select CPU_32v5
+ select CPU_ABRT_EV4T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM1022E is an implementation of the ARMv5TE architecture
+ based upon the ARM10 integer core with a 16KiB L1 Harvard cache,
+ embedded trace macrocell, and a floating-point unit.
+
+ Say Y if you want support for the ARM1022E processor.
+ Otherwise, say N.
+
+# ARM1026EJ-S
+config CPU_ARM1026
+ bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
+ select CPU_32v5
+ select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU # can probably do better
+ select CPU_TLB_V4WBI if MMU
+ help
+ The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture
+ based upon the ARM10 integer core.
+
+ Say Y if you want support for the ARM1026EJ-S processor.
+ Otherwise, say N.
+
+# SA110
+config CPU_SA110
+ bool "Support StrongARM(R) SA-110 processor" if ARCH_RPC
+ select CPU_32v3 if ARCH_RPC
+ select CPU_32v4 if !ARCH_RPC
+ select CPU_ABRT_EV4
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WB
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_V4WB if MMU
+ select CPU_TLB_V4WB if MMU
+ help
+ The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and
+ is available at five speeds ranging from 100 MHz to 233 MHz.
+ More information is available at
+ <http://developer.intel.com/design/strong/sa110.htm>.
+
+ Say Y if you want support for the SA-110 processor.
+ Otherwise, say N.
+
+# SA1100
+config CPU_SA1100
+ bool
+ select CPU_32v4
+ select CPU_ABRT_EV4
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_V4WB
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_TLB_V4WB if MMU
+
+# XScale
+config CPU_XSCALE
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_TLB_V4WBI if MMU
+
+# XScale Core Version 3
+config CPU_XSC3
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_TLB_V4WBI if MMU
+ select IO_36
+
+# Marvell PJ1 (Mohawk)
+config CPU_MOHAWK
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_TLB_V4WBI if MMU
+ select CPU_COPY_V4WB if MMU
+
+# Feroceon
+config CPU_FEROCEON
+ bool
+ select CPU_32v5
+ select CPU_ABRT_EV5T
+ select CPU_PABRT_LEGACY
+ select CPU_CACHE_VIVT
+ select CPU_CP15_MMU
+ select CPU_COPY_FEROCEON if MMU
+ select CPU_TLB_FEROCEON if MMU
+
+config CPU_FEROCEON_OLD_ID
+ bool "Accept early Feroceon cores with an ARM926 ID"
+ depends on CPU_FEROCEON && !CPU_ARM926T
+ default y
+ help
+ This enables the usage of some old Feroceon cores
+ for which the CPU ID is equal to the ARM926 ID.
+ Relevant for Feroceon-1850 and early Feroceon-2850.
+
+# Marvell PJ4
+config CPU_PJ4
+ bool
+ select CPU_V7
+ select ARM_THUMBEE
+
+# ARMv6
+config CPU_V6
+ bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+ select CPU_32v6
+ select CPU_ABRT_EV6
+ select CPU_PABRT_V6
+ select CPU_CACHE_V6
+ select CPU_CACHE_VIPT
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_COPY_V6 if MMU
+ select CPU_TLB_V6 if MMU
+
+# ARMv6k
+config CPU_V6K
+ bool "Support ARM V6K processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+ select CPU_32v6
+ select CPU_32v6K
+ select CPU_ABRT_EV6
+ select CPU_PABRT_V6
+ select CPU_CACHE_V6
+ select CPU_CACHE_VIPT
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_COPY_V6 if MMU
+ select CPU_TLB_V6 if MMU
+
+# ARMv7
+config CPU_V7
+ bool "Support ARM V7 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+ select CPU_32v6K
+ select CPU_32v7
+ select CPU_ABRT_EV7
+ select CPU_PABRT_V7
+ select CPU_CACHE_V7
+ select CPU_CACHE_VIPT
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_COPY_V6 if MMU
+ select CPU_TLB_V7 if MMU
+
+# Figure out what processor architecture version we should be using.
+# This defines the compiler instruction set which depends on the machine type.
+config CPU_32v3
+ bool
+ select TLS_REG_EMUL if SMP || !MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
+
+config CPU_32v4
+ bool
+ select TLS_REG_EMUL if SMP || !MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
+
+config CPU_32v4T
+ bool
+ select TLS_REG_EMUL if SMP || !MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
+
+config CPU_32v5
+ bool
+ select TLS_REG_EMUL if SMP || !MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
+
+config CPU_32v6
+ bool
+ select TLS_REG_EMUL if !CPU_32v6K && !MMU
+ select CPU_USE_DOMAINS if CPU_V6 && MMU
+
+config CPU_32v6K
+ bool
+
+config CPU_32v7
+ bool
+
+# The abort model
+config CPU_ABRT_NOMMU
+ bool
+
+config CPU_ABRT_EV4
+ bool
+
+config CPU_ABRT_EV4T
+ bool
+
+config CPU_ABRT_LV4T
+ bool
+
+config CPU_ABRT_EV5T
+ bool
+
+config CPU_ABRT_EV5TJ
+ bool
+
+config CPU_ABRT_EV6
+ bool
+
+config CPU_ABRT_EV7
+ bool
+
+config CPU_PABRT_LEGACY
+ bool
+
+config CPU_PABRT_V6
+ bool
+
+config CPU_PABRT_V7
+ bool
+
+# The cache model
+config CPU_CACHE_V3
+ bool
+
+config CPU_CACHE_V4
+ bool
+
+config CPU_CACHE_V4WT
+ bool
+
+config CPU_CACHE_V4WB
+ bool
+
+config CPU_CACHE_V6
+ bool
+
+config CPU_CACHE_V7
+ bool
+
+config CPU_CACHE_VIVT
+ bool
+
+config CPU_CACHE_VIPT
+ bool
+
+config CPU_CACHE_FA
+ bool
+
+if MMU
+# The copy-page model
+config CPU_COPY_V3
+ bool
+
+config CPU_COPY_V4WT
+ bool
+
+config CPU_COPY_V4WB
+ bool
+
+config CPU_COPY_FEROCEON
+ bool
+
+config CPU_COPY_FA
+ bool
+
+config CPU_COPY_V6
+ bool
+
+# This selects the TLB model
+config CPU_TLB_V3
+ bool
+ help
+ ARM Architecture Version 3 TLB.
+
+config CPU_TLB_V4WT
+ bool
+ help
+ ARM Architecture Version 4 TLB with writethrough cache.
+
+config CPU_TLB_V4WB
+ bool
+ help
+ ARM Architecture Version 4 TLB with writeback cache.
+
+config CPU_TLB_V4WBI
+ bool
+ help
+ ARM Architecture Version 4 TLB with writeback cache and invalidate
+ instruction cache entry.
+
+config CPU_TLB_FEROCEON
+ bool
+ help
+ Feroceon TLB (v4wbi with non-outer-cachable page table walks).
+
+config CPU_TLB_FA
+ bool
+ help
+ Faraday ARM FA526 architecture, unified TLB with writeback cache
+ and invalidate instruction cache entry. Branch target buffer is
+ also supported.
+
+config CPU_TLB_V6
+ bool
+
+config CPU_TLB_V7
+ bool
+
+config VERIFY_PERMISSION_FAULT
+ bool
+endif
+
+config CPU_HAS_ASID
+ bool
+ help
+ This indicates whether the CPU has the ASID register; used to
+ tag TLB and possibly cache entries.
+
+config CPU_CP15
+ bool
+ help
+ Processor has the CP15 register.
+
+config CPU_CP15_MMU
+ bool
+ select CPU_CP15
+ help
+ Processor has the CP15 register, which has MMU related registers.
+
+config CPU_CP15_MPU
+ bool
+ select CPU_CP15
+ help
+ Processor has the CP15 register, which has MPU related registers.
+
+config CPU_USE_DOMAINS
+ bool
+ help
+ This option enables or disables the use of domain switching
+ via the set_fs() function.
+
+#
+# CPU supports 36-bit I/O
+#
+config IO_36
+ bool
+
+comment "Processor Features"
+
+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
+ default y
+ help
+ Say Y if you want to include kernel support for running user space
+ Thumb binaries.
+
+ The Thumb instruction set is a compressed form of the standard ARM
+ instruction set resulting in smaller binaries at the expense of
+ slightly less efficient code.
+
+ If you don't know what this all is, saying Y is a safe choice.
+
+config ARM_THUMBEE
+ bool "Enable ThumbEE CPU extension"
+ depends on CPU_V7
+ help
+ Say Y here if you have a CPU with the ThumbEE extension and code to
+ make use of it. Say N for code that can run on CPUs without ThumbEE.
+
+config SWP_EMULATE
+ bool "Emulate SWP/SWPB instructions"
+ depends on !CPU_USE_DOMAINS && CPU_V7
+ select HAVE_PROC_CPU if PROC_FS
+ default y if SMP
+ help
+ ARMv6 architecture deprecates use of the SWP/SWPB instructions.
+ ARMv7 multiprocessing extensions introduce the ability to disable
+ these instructions, triggering an undefined instruction exception
+ when executed. Say Y here to enable software emulation of these
+ instructions for userspace (not kernel) using LDREX/STREX.
+ Also creates /proc/cpu/swp_emulation for statistics.
+
+ In some older versions of glibc [<=2.8] SWP is used during futex
+ trylock() operations with the assumption that the code will not
+ be preempted. This invalid assumption may be more likely to fail
+ with SWP emulation enabled, leading to deadlock of the user
+ application.
+
+ NOTE: when accessing uncached shared regions, LDREX/STREX rely
+ on an external transaction monitoring block called a global
+ monitor to maintain update atomicity. If your system does not
+ implement a global monitor, this option can cause programs that
+ perform SWP operations to uncached memory to deadlock.
+
+ If unsure, say Y.
+
+config CPU_BIG_ENDIAN
+ bool "Build big-endian kernel"
+ depends on ARCH_SUPPORTS_BIG_ENDIAN
+ help
+ Say Y if you plan on running a kernel in big-endian mode.
+ Note that your board must be properly built and your board
+ port must properly enable any big-endian related features
+ of your chipset/board/processor.
+
+config CPU_ENDIAN_BE8
+ bool
+ depends on CPU_BIG_ENDIAN
+ default CPU_V6 || CPU_V6K || CPU_V7
+ help
+ Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors.
+
+config CPU_ENDIAN_BE32
+ bool
+ depends on CPU_BIG_ENDIAN
+ default !CPU_ENDIAN_BE8
+ help
+ Support for the BE-32 (big-endian) mode on pre-ARMv6 processors.
+
+config CPU_HIGH_VECTOR
+ depends on !MMU && CPU_CP15 && !CPU_ARM740T
+ bool "Select the High exception vector"
+ help
+ Say Y here to select high exception vector(0xFFFF0000~).
+ The exception vector can be vary depending on the platform
+ design in nommu mode. If your platform needs to select
+ high exception vector, say Y.
+ Otherwise or if you are unsure, say N, and the low exception
+ vector (0x00000000~) will be used.
+
+config CPU_ICACHE_DISABLE
+ bool "Disable I-Cache (I-bit)"
+ depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3)
+ help
+ Say Y here to disable the processor instruction cache. Unless
+ you have a reason not to or are unsure, say N.
+
+config CPU_DCACHE_DISABLE
+ bool "Disable D-Cache (C-bit)"
+ depends on CPU_CP15
+ help
+ Say Y here to disable the processor data cache. Unless
+ you have a reason not to or are unsure, say N.
+
+config CPU_DCACHE_SIZE
+ hex
+ depends on CPU_ARM740T || CPU_ARM946E
+ default 0x00001000 if CPU_ARM740T
+ default 0x00002000 # default size for ARM946E-S
+ help
+ Some cores are synthesizable to have various sized cache. For
+ ARM946E-S case, it can vary from 0KB to 1MB.
+ To support such cache operations, it is efficient to know the size
+ before compile time.
+ If your SoC is configured to have a different size, define the value
+ here with proper conditions.
+
+config CPU_DCACHE_WRITETHROUGH
+ bool "Force write through D-cache"
+ depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE
+ default y if CPU_ARM925T
+ help
+ Say Y here to use the data cache in writethrough mode. Unless you
+ specifically require this or are unsure, say N.
+
+config CPU_CACHE_ROUND_ROBIN
+ bool "Round robin I and D cache replacement algorithm"
+ depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE)
+ help
+ Say Y here to use the predictable round-robin cache replacement
+ policy. Unless you specifically require this or are unsure, say N.
+
+config CPU_BPREDICT_DISABLE
+ bool "Disable branch prediction"
+ depends on CPU_ARM1020 || CPU_V6 || CPU_V6K || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526
+ help
+ Say Y here to disable branch prediction. If unsure, say N.
+
+config TLS_REG_EMUL
+ bool
+ help
+ An SMP system using a pre-ARMv6 processor (there are apparently
+ a few prototypes like that in existence) and therefore access to
+ that required register must be emulated.
+
+config NEEDS_SYSCALL_FOR_CMPXCHG
+ bool
+ help
+ SMP on a pre-ARMv6 processor? Well OK then.
+ Forget about fast user space cmpxchg support.
+ It is just not possible.
+
+config DMA_CACHE_RWFO
+ bool "Enable read/write for ownership DMA cache maintenance"
+ depends on CPU_V6K && SMP
+ default y
+ help
+ The Snoop Control Unit on ARM11MPCore does not detect the
+ cache maintenance operations and the dma_{map,unmap}_area()
+ functions may leave stale cache entries on other CPUs. By
+ enabling this option, Read or Write For Ownership in the ARMv6
+ DMA cache maintenance functions is performed. These LDR/STR
+ instructions change the cache line state to shared or modified
+ so that the cache operation has the desired effect.
+
+ Note that the workaround is only valid on processors that do
+ not perform speculative loads into the D-cache. For such
+ processors, if cache maintenance operations are not broadcast
+ in hardware, other workarounds are needed (e.g. cache
+ maintenance broadcasting in software via FIQ).
+
+config OUTER_CACHE
+ bool
+
+config OUTER_CACHE_SYNC
+ bool
+ help
+ The outer cache has a outer_cache_fns.sync function pointer
+ that can be used to drain the write buffer of the outer cache.
+
+config CACHE_FEROCEON_L2
+ bool "Enable the Feroceon L2 cache controller"
+ depends on ARCH_KIRKWOOD || ARCH_MV78XX0
+ default y
+ select OUTER_CACHE
+ help
+ This option enables the Feroceon L2 cache controller.
+
+config CACHE_FEROCEON_L2_WRITETHROUGH
+ bool "Force Feroceon L2 cache write through"
+ depends on CACHE_FEROCEON_L2
+ help
+ Say Y here to use the Feroceon L2 cache in writethrough mode.
+ Unless you specifically require this, say N for writeback mode.
+
+config CACHE_L2X0
+ bool "Enable the L2x0 outer cache controller"
+ depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
+ REALVIEW_EB_A9MP || SOC_IMX35 || SOC_IMX31 || MACH_REALVIEW_PBX || \
+ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_EXYNOS4 || ARCH_TEGRA || \
+ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_SHMOBILE || SOC_IMX6Q
+ default y
+ select OUTER_CACHE
+ select OUTER_CACHE_SYNC
+ help
+ This option enables the L2x0 PrimeCell.
+
+config CACHE_PL310
+ bool
+ depends on CACHE_L2X0
+ default y if CPU_V7 && !(CPU_V6 || CPU_V6K)
+ help
+ This option enables optimisations for the PL310 cache
+ controller.
+
+config CACHE_TAUROS2
+ bool "Enable the Tauros2 L2 cache controller"
+ depends on (ARCH_DOVE || ARCH_MMP || CPU_PJ4)
+ default y
+ select OUTER_CACHE
+ help
+ This option enables the Tauros2 L2 cache controller (as
+ found on PJ1/PJ4).
+
+config CACHE_XSC3L2
+ bool "Enable the L2 cache on XScale3"
+ depends on CPU_XSC3
+ default y
+ select OUTER_CACHE
+ help
+ This option enables the L2 cache on XScale3.
+
+config ARM_L1_CACHE_SHIFT_6
+ bool
+ help
+ Setting ARM L1 cache line size to 64 Bytes.
+
+config ARM_L1_CACHE_SHIFT
+ int
+ default 6 if ARM_L1_CACHE_SHIFT_6
+ default 5
+
+config ARM_DMA_MEM_BUFFERABLE
+ bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
+ depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
+ MACH_REALVIEW_PB11MP)
+ default y if CPU_V6 || CPU_V6K || CPU_V7
+ help
+ Historically, the kernel has used strongly ordered mappings to
+ provide DMA coherent memory. With the advent of ARMv7, mapping
+ memory with differing types results in unpredictable behaviour,
+ so on these CPUs, this option is forced on.
+
+ Multiple mappings with differing attributes is also unpredictable
+ on ARMv6 CPUs, but since they do not have aggressive speculative
+ prefetch, no harm appears to occur.
+
+ However, drivers may be missing the necessary barriers for ARMv6,
+ and therefore turning this on may result in unpredictable driver
+ behaviour. Therefore, we offer this as an option.
+
+ You are recommended say 'Y' here and debug any affected drivers.
+
+config ARCH_HAS_BARRIERS
+ bool
+ help
+ This option allows the use of custom mandatory barriers
+ included via the mach/barriers.h file.
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
new file mode 100644
index 00000000..bca7e619
--- /dev/null
+++ b/arch/arm/mm/Makefile
@@ -0,0 +1,102 @@
+#
+# Makefile for the linux arm-specific parts of the memory manager.
+#
+
+obj-y := dma-mapping.o extable.o fault.o init.o \
+ iomap.o
+
+obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
+ mmap.o pgd.o mmu.o vmregion.o
+
+ifneq ($(CONFIG_MMU),y)
+obj-y += nommu.o
+endif
+
+obj-$(CONFIG_MODULES) += proc-syms.o
+
+obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
+
+obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
+obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o
+obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o
+obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o
+obj-$(CONFIG_CPU_ABRT_EV5T) += abort-ev5t.o
+obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
+obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o
+obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o
+
+AFLAGS_abort-ev6.o :=-Wa,-march=armv6k
+AFLAGS_abort-ev7.o :=-Wa,-march=armv7-a
+
+obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o
+obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o
+obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o
+
+obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
+obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
+obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
+obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
+obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o
+obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
+obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o
+
+AFLAGS_cache-v6.o :=-Wa,-march=armv6
+AFLAGS_cache-v7.o :=-Wa,-march=armv7-a
+
+obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
+obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
+obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o
+obj-$(CONFIG_CPU_COPY_FEROCEON) += copypage-feroceon.o
+obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o
+obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
+obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
+obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o
+obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o
+
+obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
+obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
+obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o
+obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o
+obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions
+obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o
+obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o
+obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o
+
+AFLAGS_tlb-v6.o :=-Wa,-march=armv6
+AFLAGS_tlb-v7.o :=-Wa,-march=armv7-a
+
+obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o
+obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o
+obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o
+obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o
+obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o
+obj-$(CONFIG_CPU_ARM9TDMI) += proc-arm9tdmi.o
+obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o
+obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o
+obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o
+obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o
+obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o
+obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o
+obj-$(CONFIG_CPU_FA526) += proc-fa526.o
+obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
+obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o
+obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
+obj-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
+obj-$(CONFIG_CPU_SA110) += proc-sa110.o
+obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
+obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
+obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
+obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk.o
+obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o
+obj-$(CONFIG_CPU_V6) += proc-v6.o
+obj-$(CONFIG_CPU_V6K) += proc-v6.o
+obj-$(CONFIG_CPU_V7) += proc-v7.o
+
+AFLAGS_proc-v6.o :=-Wa,-march=armv6
+AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
+
+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
diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S
new file mode 100644
index 00000000..4f18f9e8
--- /dev/null
+++ b/arch/arm/mm/abort-ev4.S
@@ -0,0 +1,30 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v4_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ .align 5
+ENTRY(v4_early_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ ldr r3, [r2] @ read aborted ARM instruction
+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ tst r3, #1 << 20 @ L = 1 -> write?
+ orreq r1, r1, #1 << 11 @ yes.
+ mov pc, lr
+
+
diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S
new file mode 100644
index 00000000..b6282548
--- /dev/null
+++ b/arch/arm/mm/abort-ev4t.S
@@ -0,0 +1,30 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v4t_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ .align 5
+ENTRY(v4t_early_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ do_thumb_abort
+ ldreq r3, [r2] @ read aborted ARM instruction
+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ tst r3, #1 << 20 @ check write
+ orreq r1, r1, #1 << 11
+ mov pc, lr
diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S
new file mode 100644
index 00000000..02251b52
--- /dev/null
+++ b/arch/arm/mm/abort-ev5t.S
@@ -0,0 +1,31 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v5t_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ .align 5
+ENTRY(v5t_early_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ do_thumb_abort
+ ldreq r3, [r2] @ read aborted ARM instruction
+ bic r1, r1, #1 << 11 @ clear bits 11 of FSR
+ do_ldrd_abort
+ tst r3, #1 << 20 @ check write
+ orreq r1, r1, #1 << 11
+ mov pc, lr
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S
new file mode 100644
index 00000000..bce68d60
--- /dev/null
+++ b/arch/arm/mm/abort-ev5tj.S
@@ -0,0 +1,35 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v5tj_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ .align 5
+ENTRY(v5tj_early_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+ tst r3, #PSR_J_BIT @ Java?
+ movne pc, lr
+ do_thumb_abort
+ ldreq r3, [r2] @ read aborted ARM instruction
+ do_ldrd_abort
+ tst r3, #1 << 20 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+ mov pc, lr
+
+
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
new file mode 100644
index 00000000..1478aa52
--- /dev/null
+++ b/arch/arm/mm/abort-ev6.S
@@ -0,0 +1,48 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "abort-macro.S"
+/*
+ * Function: v6_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ .align 5
+ENTRY(v6_early_abort)
+#ifdef CONFIG_CPU_V6
+ sub r1, sp, #4 @ Get unused stack location
+ strex r0, r1, [r1] @ Clear the exclusive monitor
+#elif defined(CONFIG_CPU_32v6K)
+ clrex
+#endif
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+/*
+ * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103).
+ * The test below covers all the write situations, including Java bytecodes
+ */
+ bic r1, r1, #1 << 11 @ clear bit 11 of FSR
+ tst r3, #PSR_J_BIT @ Java?
+ movne pc, lr
+ do_thumb_abort
+ ldreq r3, [r2] @ read aborted ARM instruction
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ reveq r3, r3
+#endif
+ do_ldrd_abort
+ tst r3, #1 << 20 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+ mov pc, lr
+
+
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S
new file mode 100644
index 00000000..ec88b157
--- /dev/null
+++ b/arch/arm/mm/abort-ev7.S
@@ -0,0 +1,54 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v7_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ */
+ .align 5
+ENTRY(v7_early_abort)
+ /*
+ * The effect of data aborts on on the exclusive access monitor are
+ * UNPREDICTABLE. Do a CLREX to clear the state
+ */
+ clrex
+
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+
+ /*
+ * V6 code adjusts the returned DFSR.
+ * New designs should not need to patch up faults.
+ */
+
+#if defined(CONFIG_VERIFY_PERMISSION_FAULT)
+ /*
+ * Detect erroneous permission failures and fix
+ */
+ ldr r3, =0x40d @ On permission fault
+ and r3, r1, r3
+ cmp r3, #0x0d
+ movne pc, lr
+
+ mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR
+ isb
+ mrc p15, 0, r2, c7, c4, 0 @ Read the PAR
+ and r3, r2, #0x7b @ On translation fault
+ cmp r3, #0x0b
+ movne pc, lr
+ bic r1, r1, #0xf @ Fix up FSR FS[5:0]
+ and r2, r2, #0x7e
+ orr r1, r1, r2, LSR #1
+#endif
+
+ mov pc, lr
+ENDPROC(v7_early_abort)
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S
new file mode 100644
index 00000000..9fb7b0e2
--- /dev/null
+++ b/arch/arm/mm/abort-lv4t.S
@@ -0,0 +1,225 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: v4t_late_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR, bit 11 = write
+ * : r2-r8 = corrupted
+ * : r9 = preserved
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction.
+ * Note: we read user space. This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture. Unfortunately, this does happen. We live with it.
+ */
+ENTRY(v4t_late_abort)
+ tst r3, #PSR_T_BIT @ check for thumb mode
+#ifdef CONFIG_CPU_CP15_MMU
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
+#else
+ mov r0, #0 @ clear r0, r1 (no FSR/FAR)
+ mov r1, #0
+#endif
+ bne .data_thumb_abort
+ ldr r8, [r2] @ read arm instruction
+ tst r8, #1 << 20 @ L = 1 -> write?
+ orreq r1, r1, #1 << 11 @ yes.
+ and r7, r8, #15 << 24
+ add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
+ nop
+
+/* 0 */ b .data_arm_lateldrhpost @ ldrh rd, [rn], #m/rm
+/* 1 */ b .data_arm_lateldrhpre @ ldrh rd, [rn, #m/rm]
+/* 2 */ b .data_unknown
+/* 3 */ b .data_unknown
+/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
+/* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m]
+/* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
+/* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
+/* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist>
+/* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
+/* a */ b .data_unknown
+/* b */ b .data_unknown
+/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+/* d */ mov pc, lr @ ldc rd, [rn, #m]
+/* e */ b .data_unknown
+/* f */
+.data_unknown: @ Part of jumptable
+ mov r0, r2
+ mov r1, r8
+ mov r2, sp
+ bl baddataabort
+ b ret_from_exception
+
+.data_arm_ldmstm:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+ mov r7, #0x11
+ orr r7, r7, #0x1100
+ and r6, r8, r7
+ and r2, r8, r7, lsl #1
+ add r6, r6, r2, lsr #1
+ and r2, r8, r7, lsl #2
+ add r6, r6, r2, lsr #2
+ and r2, r8, r7, lsl #3
+ add r6, r6, r2, lsr #3
+ add r6, r6, r6, lsr #8
+ add r6, r6, r6, lsr #4
+ and r6, r6, #15 @ r6 = no. of registers to transfer.
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r6, lsl #2 @ Undo increment
+ addeq r7, r7, r6, lsl #2 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_lateldrhpre:
+ tst r8, #1 << 21 @ Check writeback bit
+ moveq pc, lr @ No writeback -> no fixup
+.data_arm_lateldrhpost:
+ and r5, r8, #0x00f @ get Rm / low nibble of immediate value
+ tst r8, #1 << 22 @ if (immediate offset)
+ andne r6, r8, #0xf00 @ { immediate high nibble
+ orrne r6, r5, r6, lsr #4 @ combine nibbles } else
+ ldreq r6, [sp, r5, lsl #2] @ { load Rm value }
+.data_arm_apply_r6_and_rn:
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r6 @ Undo incrmenet
+ addeq r7, r7, r6 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_lateldrpreconst:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+.data_arm_lateldrpostconst:
+ movs r2, r8, lsl #20 @ Get offset
+ moveq pc, lr @ zero -> no fixup
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r2, lsr #20 @ Undo increment
+ addeq r7, r7, r2, lsr #20 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_lateldrprereg:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+.data_arm_lateldrpostreg:
+ and r7, r8, #15 @ Extract 'm' from instruction
+ ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
+ mov r5, r8, lsr #7 @ get shift count
+ ands r5, r5, #31
+ and r7, r8, #0x70 @ get shift type
+ orreq r7, r7, #8 @ shift count = 0
+ add pc, pc, r7
+ nop
+
+ mov r6, r6, lsl r5 @ 0: LSL #!0
+ b .data_arm_apply_r6_and_rn
+ b .data_arm_apply_r6_and_rn @ 1: LSL #0
+ nop
+ b .data_unknown @ 2: MUL?
+ nop
+ b .data_unknown @ 3: MUL?
+ nop
+ mov r6, r6, lsr r5 @ 4: LSR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, lsr #32 @ 5: LSR #32
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ 6: MUL?
+ nop
+ b .data_unknown @ 7: MUL?
+ nop
+ mov r6, r6, asr r5 @ 8: ASR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, asr #32 @ 9: ASR #32
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ A: MUL?
+ nop
+ b .data_unknown @ B: MUL?
+ nop
+ mov r6, r6, ror r5 @ C: ROR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, rrx @ D: RRX
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ E: MUL?
+ nop
+ b .data_unknown @ F: MUL?
+
+.data_thumb_abort:
+ ldrh r8, [r2] @ read instruction
+ tst r8, #1 << 11 @ L = 1 -> write?
+ orreq r1, r1, #1 << 8 @ yes
+ and r7, r8, #15 << 12
+ add pc, pc, r7, lsr #10 @ lookup in table
+ nop
+
+/* 0 */ b .data_unknown
+/* 1 */ b .data_unknown
+/* 2 */ b .data_unknown
+/* 3 */ b .data_unknown
+/* 4 */ b .data_unknown
+/* 5 */ b .data_thumb_reg
+/* 6 */ mov pc, lr
+/* 7 */ mov pc, lr
+/* 8 */ mov pc, lr
+/* 9 */ mov pc, lr
+/* A */ b .data_unknown
+/* B */ b .data_thumb_pushpop
+/* C */ b .data_thumb_ldmstm
+/* D */ b .data_unknown
+/* E */ b .data_unknown
+/* F */ b .data_unknown
+
+.data_thumb_reg:
+ tst r8, #1 << 9
+ moveq pc, lr
+ tst r8, #1 << 10 @ If 'S' (signed) bit is set
+ movne r1, #0 @ it must be a load instr
+ mov pc, lr
+
+.data_thumb_pushpop:
+ tst r8, #1 << 10
+ beq .data_unknown
+ and r6, r8, #0x55 @ hweight8(r8) + R bit
+ and r2, r8, #0xaa
+ add r6, r6, r2, lsr #1
+ and r2, r6, #0xcc
+ and r6, r6, #0x33
+ add r6, r6, r2, lsr #2
+ movs r7, r8, lsr #9 @ C = r8 bit 8 (R bit)
+ adc r6, r6, r6, lsr #4 @ high + low nibble + R bit
+ and r6, r6, #15 @ number of regs to transfer
+ ldr r7, [sp, #13 << 2]
+ tst r8, #1 << 11
+ addeq r7, r7, r6, lsl #2 @ increment SP if PUSH
+ subne r7, r7, r6, lsl #2 @ decrement SP if POP
+ str r7, [sp, #13 << 2]
+ mov pc, lr
+
+.data_thumb_ldmstm:
+ and r6, r8, #0x55 @ hweight8(r8)
+ and r2, r8, #0xaa
+ add r6, r6, r2, lsr #1
+ and r2, r6, #0xcc
+ and r6, r6, #0x33
+ add r6, r6, r2, lsr #2
+ add r6, r6, r6, lsr #4
+ and r5, r8, #7 << 8
+ ldr r7, [sp, r5, lsr #6]
+ and r6, r6, #15 @ number of regs to transfer
+ sub r7, r7, r6, lsl #2 @ always decrement
+ str r7, [sp, r5, lsr #6]
+ mov pc, lr
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S
new file mode 100644
index 00000000..d7cb1bfa
--- /dev/null
+++ b/arch/arm/mm/abort-macro.S
@@ -0,0 +1,42 @@
+/*
+ * The ARM LDRD and Thumb LDRSB instructions use bit 20/11 (ARM/Thumb)
+ * differently than every other instruction, so it is set to 0 (write)
+ * even though the instructions are read instructions. This means that
+ * during an abort the instructions will be treated as a write and the
+ * handler will raise a signal from unwriteable locations if they
+ * fault. We have to specifically check for these instructions
+ * from the abort handlers to treat them properly.
+ *
+ */
+
+ .macro do_thumb_abort
+ tst r3, #PSR_T_BIT
+ beq not_thumb
+ ldrh r3, [r2] @ Read aborted Thumb instruction
+ and r3, r3, # 0xfe00 @ Mask opcode field
+ cmp r3, # 0x5600 @ Is it ldrsb?
+ orreq r3, r3, #1 << 11 @ Set L-bit if yes
+ tst r3, #1 << 11 @ L = 0 -> write
+ orreq r1, r1, #1 << 11 @ yes.
+ mov pc, lr
+not_thumb:
+ .endm
+
+/*
+ * We check for the following insturction encoding for LDRD.
+ *
+ * [27:25] == 0
+ * [7:4] == 1101
+ * [20] == 0
+ */
+ .macro do_ldrd_abort
+ tst r3, #0x0e000000 @ [27:25] == 0
+ bne not_ldrd
+ and r2, r3, #0x000000f0 @ [7:4] == 1101
+ cmp r2, #0x000000d0
+ bne not_ldrd
+ tst r3, #1 << 20 @ [20] == 0
+ moveq pc, lr
+not_ldrd:
+ .endm
+
diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S
new file mode 100644
index 00000000..625e5809
--- /dev/null
+++ b/arch/arm/mm/abort-nommu.S
@@ -0,0 +1,20 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+/*
+ * Function: nommu_early_abort
+ *
+ * Params : r2 = address of aborted instruction
+ * : r3 = saved SPSR
+ *
+ * Returns : r0 = 0 (abort address)
+ * : r1 = 0 (FSR)
+ *
+ * Note: There is no FSR/FAR on !CPU_CP15_MMU cores.
+ * Just fill zero into the registers.
+ */
+ .align 5
+ENTRY(nommu_early_abort)
+ mov r0, #0 @ clear r0, r1 (no FSR/FAR)
+ mov r1, #0
+ mov pc, lr
+ENDPROC(nommu_early_abort)
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
new file mode 100644
index 00000000..724ba3bc
--- /dev/null
+++ b/arch/arm/mm/alignment.c
@@ -0,0 +1,960 @@
+/*
+ * linux/arch/arm/mm/alignment.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Modifications for ARM processor (c) 1995-2001 Russell King
+ * Thumb alignment fault fixups (c) 2004 MontaVista Software, Inc.
+ * - Adapted from gdb/sim/arm/thumbemu.c -- Thumb instruction emulation.
+ * Copyright (C) 1996, Cygnus Software Technologies 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/moduleparam.h>
+#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include <asm/unaligned.h>
+
+#include "fault.h"
+
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * Speed optimisations and better fault handling by Russell King.
+ *
+ * *** NOTE ***
+ * This code is not portable to processors with late data abort handling.
+ */
+#define CODING_BITS(i) (i & 0x0e000000)
+
+#define LDST_I_BIT(i) (i & (1 << 26)) /* Immediate constant */
+#define LDST_P_BIT(i) (i & (1 << 24)) /* Preindex */
+#define LDST_U_BIT(i) (i & (1 << 23)) /* Add offset */
+#define LDST_W_BIT(i) (i & (1 << 21)) /* Writeback */
+#define LDST_L_BIT(i) (i & (1 << 20)) /* Load */
+
+#define LDST_P_EQ_U(i) ((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
+
+#define LDSTHD_I_BIT(i) (i & (1 << 22)) /* double/half-word immed */
+#define LDM_S_BIT(i) (i & (1 << 22)) /* write CPSR from SPSR */
+
+#define RN_BITS(i) ((i >> 16) & 15) /* Rn */
+#define RD_BITS(i) ((i >> 12) & 15) /* Rd */
+#define RM_BITS(i) (i & 15) /* Rm */
+
+#define REGMASK_BITS(i) (i & 0xffff)
+#define OFFSET_BITS(i) (i & 0x0fff)
+
+#define IS_SHIFT(i) (i & 0x0ff0)
+#define SHIFT_BITS(i) ((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i) (i & 0x60)
+#define SHIFT_LSL 0x00
+#define SHIFT_LSR 0x20
+#define SHIFT_ASR 0x40
+#define SHIFT_RORRRX 0x60
+
+#define BAD_INSTR 0xdeadc0de
+
+/* Thumb-2 32 bit format per ARMv7 DDI0406A A6.3, either f800h,e800h,f800h */
+#define IS_T32(hi16) \
+ (((hi16) & 0xe000) == 0xe000 && ((hi16) & 0x1800))
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_dword;
+static unsigned long ai_multi;
+static int ai_usermode;
+
+core_param(alignment, ai_usermode, int, 0600);
+
+#define UM_WARN (1 << 0)
+#define UM_FIXUP (1 << 1)
+#define UM_SIGNAL (1 << 2)
+
+#ifdef CONFIG_PROC_FS
+static const char *usermode_action[] = {
+ "ignored",
+ "warn",
+ "fixup",
+ "fixup+warn",
+ "signal",
+ "signal+warn"
+};
+
+static int alignment_proc_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "User:\t\t%lu\n", ai_user);
+ seq_printf(m, "System:\t\t%lu\n", ai_sys);
+ seq_printf(m, "Skipped:\t%lu\n", ai_skipped);
+ seq_printf(m, "Half:\t\t%lu\n", ai_half);
+ seq_printf(m, "Word:\t\t%lu\n", ai_word);
+ if (cpu_architecture() >= CPU_ARCH_ARMv5TE)
+ seq_printf(m, "DWord:\t\t%lu\n", ai_dword);
+ seq_printf(m, "Multi:\t\t%lu\n", ai_multi);
+ seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode,
+ usermode_action[ai_usermode]);
+
+ return 0;
+}
+
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, alignment_proc_show, NULL);
+}
+
+static ssize_t alignment_proc_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *pos)
+{
+ char mode;
+
+ if (count > 0) {
+ if (get_user(mode, buffer))
+ return -EFAULT;
+ if (mode >= '0' && mode <= '5')
+ ai_usermode = mode - '0';
+ }
+ return count;
+}
+
+static const struct file_operations alignment_proc_fops = {
+ .open = alignment_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = alignment_proc_write,
+};
+#endif /* CONFIG_PROC_FS */
+
+union offset_union {
+ unsigned long un;
+ signed long sn;
+};
+
+#define TYPE_ERROR 0
+#define TYPE_FAULT 1
+#define TYPE_LDST 2
+#define TYPE_DONE 3
+
+#ifdef __ARMEB__
+#define BE 1
+#define FIRST_BYTE_16 "mov %1, %1, ror #8\n"
+#define FIRST_BYTE_32 "mov %1, %1, ror #24\n"
+#define NEXT_BYTE "ror #24"
+#else
+#define BE 0
+#define FIRST_BYTE_16
+#define FIRST_BYTE_32
+#define NEXT_BYTE "lsr #8"
+#endif
+
+#define __get8_unaligned_check(ins,val,addr,err) \
+ __asm__( \
+ ARM( "1: "ins" %1, [%2], #1\n" ) \
+ THUMB( "1: "ins" %1, [%2]\n" ) \
+ THUMB( " add %2, %2, #1\n" ) \
+ "2:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "3: mov %0, #1\n" \
+ " b 2b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 3b\n" \
+ " .popsection\n" \
+ : "=r" (err), "=&r" (val), "=r" (addr) \
+ : "0" (err), "2" (addr))
+
+#define __get16_unaligned_check(ins,val,addr) \
+ do { \
+ unsigned int err = 0, v, a = addr; \
+ __get8_unaligned_check(ins,v,a,err); \
+ val = v << ((BE) ? 8 : 0); \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << ((BE) ? 0 : 8); \
+ if (err) \
+ goto fault; \
+ } while (0)
+
+#define get16_unaligned_check(val,addr) \
+ __get16_unaligned_check("ldrb",val,addr)
+
+#define get16t_unaligned_check(val,addr) \
+ __get16_unaligned_check("ldrbt",val,addr)
+
+#define __get32_unaligned_check(ins,val,addr) \
+ do { \
+ unsigned int err = 0, v, a = addr; \
+ __get8_unaligned_check(ins,v,a,err); \
+ val = v << ((BE) ? 24 : 0); \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << ((BE) ? 16 : 8); \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << ((BE) ? 8 : 16); \
+ __get8_unaligned_check(ins,v,a,err); \
+ val |= v << ((BE) ? 0 : 24); \
+ if (err) \
+ goto fault; \
+ } while (0)
+
+#define get32_unaligned_check(val,addr) \
+ __get32_unaligned_check("ldrb",val,addr)
+
+#define get32t_unaligned_check(val,addr) \
+ __get32_unaligned_check("ldrbt",val,addr)
+
+#define __put16_unaligned_check(ins,val,addr) \
+ do { \
+ unsigned int err = 0, v = val, a = addr; \
+ __asm__( FIRST_BYTE_16 \
+ ARM( "1: "ins" %1, [%2], #1\n" ) \
+ THUMB( "1: "ins" %1, [%2]\n" ) \
+ THUMB( " add %2, %2, #1\n" ) \
+ " mov %1, %1, "NEXT_BYTE"\n" \
+ "2: "ins" %1, [%2]\n" \
+ "3:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "4: mov %0, #1\n" \
+ " b 3b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 4b\n" \
+ " .long 2b, 4b\n" \
+ " .popsection\n" \
+ : "=r" (err), "=&r" (v), "=&r" (a) \
+ : "0" (err), "1" (v), "2" (a)); \
+ if (err) \
+ goto fault; \
+ } while (0)
+
+#define put16_unaligned_check(val,addr) \
+ __put16_unaligned_check("strb",val,addr)
+
+#define put16t_unaligned_check(val,addr) \
+ __put16_unaligned_check("strbt",val,addr)
+
+#define __put32_unaligned_check(ins,val,addr) \
+ do { \
+ unsigned int err = 0, v = val, a = addr; \
+ __asm__( FIRST_BYTE_32 \
+ ARM( "1: "ins" %1, [%2], #1\n" ) \
+ THUMB( "1: "ins" %1, [%2]\n" ) \
+ THUMB( " add %2, %2, #1\n" ) \
+ " mov %1, %1, "NEXT_BYTE"\n" \
+ ARM( "2: "ins" %1, [%2], #1\n" ) \
+ THUMB( "2: "ins" %1, [%2]\n" ) \
+ THUMB( " add %2, %2, #1\n" ) \
+ " mov %1, %1, "NEXT_BYTE"\n" \
+ ARM( "3: "ins" %1, [%2], #1\n" ) \
+ THUMB( "3: "ins" %1, [%2]\n" ) \
+ THUMB( " add %2, %2, #1\n" ) \
+ " mov %1, %1, "NEXT_BYTE"\n" \
+ "4: "ins" %1, [%2]\n" \
+ "5:\n" \
+ " .pushsection .fixup,\"ax\"\n" \
+ " .align 2\n" \
+ "6: mov %0, #1\n" \
+ " b 5b\n" \
+ " .popsection\n" \
+ " .pushsection __ex_table,\"a\"\n" \
+ " .align 3\n" \
+ " .long 1b, 6b\n" \
+ " .long 2b, 6b\n" \
+ " .long 3b, 6b\n" \
+ " .long 4b, 6b\n" \
+ " .popsection\n" \
+ : "=r" (err), "=&r" (v), "=&r" (a) \
+ : "0" (err), "1" (v), "2" (a)); \
+ if (err) \
+ goto fault; \
+ } while (0)
+
+#define put32_unaligned_check(val,addr) \
+ __put32_unaligned_check("strb", val, addr)
+
+#define put32t_unaligned_check(val,addr) \
+ __put32_unaligned_check("strbt", val, addr)
+
+static void
+do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
+{
+ if (!LDST_U_BIT(instr))
+ offset.un = -offset.un;
+
+ if (!LDST_P_BIT(instr))
+ addr += offset.un;
+
+ if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
+ regs->uregs[RN_BITS(instr)] = addr;
+}
+
+static int
+do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+ unsigned int rd = RD_BITS(instr);
+
+ ai_half += 1;
+
+ if (user_mode(regs))
+ goto user;
+
+ if (LDST_L_BIT(instr)) {
+ unsigned long val;
+ get16_unaligned_check(val, addr);
+
+ /* signed half-word? */
+ if (instr & 0x40)
+ val = (signed long)((signed short) val);
+
+ regs->uregs[rd] = val;
+ } else
+ put16_unaligned_check(regs->uregs[rd], addr);
+
+ return TYPE_LDST;
+
+ user:
+ if (LDST_L_BIT(instr)) {
+ unsigned long val;
+ get16t_unaligned_check(val, addr);
+
+ /* signed half-word? */
+ if (instr & 0x40)
+ val = (signed long)((signed short) val);
+
+ regs->uregs[rd] = val;
+ } else
+ put16t_unaligned_check(regs->uregs[rd], addr);
+
+ return TYPE_LDST;
+
+ fault:
+ return TYPE_FAULT;
+}
+
+static int
+do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
+ struct pt_regs *regs)
+{
+ unsigned int rd = RD_BITS(instr);
+ unsigned int rd2;
+ int load;
+
+ if ((instr & 0xfe000000) == 0xe8000000) {
+ /* ARMv7 Thumb-2 32-bit LDRD/STRD */
+ rd2 = (instr >> 8) & 0xf;
+ load = !!(LDST_L_BIT(instr));
+ } else if (((rd & 1) == 1) || (rd == 14))
+ goto bad;
+ else {
+ load = ((instr & 0xf0) == 0xd0);
+ rd2 = rd + 1;
+ }
+
+ ai_dword += 1;
+
+ if (user_mode(regs))
+ goto user;
+
+ if (load) {
+ unsigned long val;
+ get32_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ get32_unaligned_check(val, addr + 4);
+ regs->uregs[rd2] = val;
+ } else {
+ put32_unaligned_check(regs->uregs[rd], addr);
+ put32_unaligned_check(regs->uregs[rd2], addr + 4);
+ }
+
+ return TYPE_LDST;
+
+ user:
+ if (load) {
+ unsigned long val;
+ get32t_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ get32t_unaligned_check(val, addr + 4);
+ regs->uregs[rd2] = val;
+ } else {
+ put32t_unaligned_check(regs->uregs[rd], addr);
+ put32t_unaligned_check(regs->uregs[rd2], addr + 4);
+ }
+
+ return TYPE_LDST;
+ bad:
+ return TYPE_ERROR;
+ fault:
+ return TYPE_FAULT;
+}
+
+static int
+do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+ unsigned int rd = RD_BITS(instr);
+
+ ai_word += 1;
+
+ if ((!LDST_P_BIT(instr) && LDST_W_BIT(instr)) || user_mode(regs))
+ goto trans;
+
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ } else
+ put32_unaligned_check(regs->uregs[rd], addr);
+ return TYPE_LDST;
+
+ trans:
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32t_unaligned_check(val, addr);
+ regs->uregs[rd] = val;
+ } else
+ put32t_unaligned_check(regs->uregs[rd], addr);
+ return TYPE_LDST;
+
+ fault:
+ return TYPE_FAULT;
+}
+
+/*
+ * LDM/STM alignment handler.
+ *
+ * There are 4 variants of this instruction:
+ *
+ * B = rn pointer before instruction, A = rn pointer after instruction
+ * ------ increasing address ----->
+ * | | r0 | r1 | ... | rx | |
+ * PU = 01 B A
+ * PU = 11 B A
+ * PU = 00 A B
+ * PU = 10 A B
+ */
+static int
+do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+ unsigned int rd, rn, correction, nr_regs, regbits;
+ unsigned long eaddr, newaddr;
+
+ if (LDM_S_BIT(instr))
+ goto bad;
+
+ correction = 4; /* processor implementation defined */
+ regs->ARM_pc += correction;
+
+ ai_multi += 1;
+
+ /* count the number of registers in the mask to be transferred */
+ nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
+
+ rn = RN_BITS(instr);
+ newaddr = eaddr = regs->uregs[rn];
+
+ if (!LDST_U_BIT(instr))
+ nr_regs = -nr_regs;
+ newaddr += nr_regs;
+ if (!LDST_U_BIT(instr))
+ eaddr = newaddr;
+
+ if (LDST_P_EQ_U(instr)) /* U = P */
+ eaddr += 4;
+
+ /*
+ * For alignment faults on the ARM922T/ARM920T the MMU makes
+ * the FSR (and hence addr) equal to the updated base address
+ * of the multiple access rather than the restored value.
+ * Switch this message off if we've got a ARM92[02], otherwise
+ * [ls]dm alignment faults are noisy!
+ */
+#if !(defined CONFIG_CPU_ARM922T) && !(defined CONFIG_CPU_ARM920T)
+ /*
+ * This is a "hint" - we already have eaddr worked out by the
+ * processor for us.
+ */
+ if (addr != eaddr) {
+ printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
+ "addr = %08lx, eaddr = %08lx\n",
+ instruction_pointer(regs), instr, addr, eaddr);
+ show_regs(regs);
+ }
+#endif
+
+ if (user_mode(regs)) {
+ for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+ regbits >>= 1, rd += 1)
+ if (regbits & 1) {
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32t_unaligned_check(val, eaddr);
+ regs->uregs[rd] = val;
+ } else
+ put32t_unaligned_check(regs->uregs[rd], eaddr);
+ eaddr += 4;
+ }
+ } else {
+ for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+ regbits >>= 1, rd += 1)
+ if (regbits & 1) {
+ if (LDST_L_BIT(instr)) {
+ unsigned int val;
+ get32_unaligned_check(val, eaddr);
+ regs->uregs[rd] = val;
+ } else
+ put32_unaligned_check(regs->uregs[rd], eaddr);
+ eaddr += 4;
+ }
+ }
+
+ if (LDST_W_BIT(instr))
+ regs->uregs[rn] = newaddr;
+ if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
+ regs->ARM_pc -= correction;
+ return TYPE_DONE;
+
+fault:
+ regs->ARM_pc -= correction;
+ return TYPE_FAULT;
+
+bad:
+ printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n");
+ return TYPE_ERROR;
+}
+
+/*
+ * Convert Thumb ld/st instruction forms to equivalent ARM instructions so
+ * we can reuse ARM userland alignment fault fixups for Thumb.
+ *
+ * This implementation was initially based on the algorithm found in
+ * gdb/sim/arm/thumbemu.c. It is basically just a code reduction of same
+ * to convert only Thumb ld/st instruction forms to equivalent ARM forms.
+ *
+ * NOTES:
+ * 1. Comments below refer to ARM ARM DDI0100E Thumb Instruction sections.
+ * 2. If for some reason we're passed an non-ld/st Thumb instruction to
+ * decode, we return 0xdeadc0de. This should never happen under normal
+ * circumstances but if it does, we've got other problems to deal with
+ * elsewhere and we obviously can't fix those problems here.
+ */
+
+static unsigned long
+thumb2arm(u16 tinstr)
+{
+ u32 L = (tinstr & (1<<11)) >> 11;
+
+ switch ((tinstr & 0xf800) >> 11) {
+ /* 6.5.1 Format 1: */
+ case 0x6000 >> 11: /* 7.1.52 STR(1) */
+ case 0x6800 >> 11: /* 7.1.26 LDR(1) */
+ case 0x7000 >> 11: /* 7.1.55 STRB(1) */
+ case 0x7800 >> 11: /* 7.1.30 LDRB(1) */
+ return 0xe5800000 |
+ ((tinstr & (1<<12)) << (22-12)) | /* fixup */
+ (L<<20) | /* L==1? */
+ ((tinstr & (7<<0)) << (12-0)) | /* Rd */
+ ((tinstr & (7<<3)) << (16-3)) | /* Rn */
+ ((tinstr & (31<<6)) >> /* immed_5 */
+ (6 - ((tinstr & (1<<12)) ? 0 : 2)));
+ case 0x8000 >> 11: /* 7.1.57 STRH(1) */
+ case 0x8800 >> 11: /* 7.1.32 LDRH(1) */
+ return 0xe1c000b0 |
+ (L<<20) | /* L==1? */
+ ((tinstr & (7<<0)) << (12-0)) | /* Rd */
+ ((tinstr & (7<<3)) << (16-3)) | /* Rn */
+ ((tinstr & (7<<6)) >> (6-1)) | /* immed_5[2:0] */
+ ((tinstr & (3<<9)) >> (9-8)); /* immed_5[4:3] */
+
+ /* 6.5.1 Format 2: */
+ case 0x5000 >> 11:
+ case 0x5800 >> 11:
+ {
+ static const u32 subset[8] = {
+ 0xe7800000, /* 7.1.53 STR(2) */
+ 0xe18000b0, /* 7.1.58 STRH(2) */
+ 0xe7c00000, /* 7.1.56 STRB(2) */
+ 0xe19000d0, /* 7.1.34 LDRSB */
+ 0xe7900000, /* 7.1.27 LDR(2) */
+ 0xe19000b0, /* 7.1.33 LDRH(2) */
+ 0xe7d00000, /* 7.1.31 LDRB(2) */
+ 0xe19000f0 /* 7.1.35 LDRSH */
+ };
+ return subset[(tinstr & (7<<9)) >> 9] |
+ ((tinstr & (7<<0)) << (12-0)) | /* Rd */
+ ((tinstr & (7<<3)) << (16-3)) | /* Rn */
+ ((tinstr & (7<<6)) >> (6-0)); /* Rm */
+ }
+
+ /* 6.5.1 Format 3: */
+ case 0x4800 >> 11: /* 7.1.28 LDR(3) */
+ /* NOTE: This case is not technically possible. We're
+ * loading 32-bit memory data via PC relative
+ * addressing mode. So we can and should eliminate
+ * this case. But I'll leave it here for now.
+ */
+ return 0xe59f0000 |
+ ((tinstr & (7<<8)) << (12-8)) | /* Rd */
+ ((tinstr & 255) << (2-0)); /* immed_8 */
+
+ /* 6.5.1 Format 4: */
+ case 0x9000 >> 11: /* 7.1.54 STR(3) */
+ case 0x9800 >> 11: /* 7.1.29 LDR(4) */
+ return 0xe58d0000 |
+ (L<<20) | /* L==1? */
+ ((tinstr & (7<<8)) << (12-8)) | /* Rd */
+ ((tinstr & 255) << 2); /* immed_8 */
+
+ /* 6.6.1 Format 1: */
+ case 0xc000 >> 11: /* 7.1.51 STMIA */
+ case 0xc800 >> 11: /* 7.1.25 LDMIA */
+ {
+ u32 Rn = (tinstr & (7<<8)) >> 8;
+ u32 W = ((L<<Rn) & (tinstr&255)) ? 0 : 1<<21;
+
+ return 0xe8800000 | W | (L<<20) | (Rn<<16) |
+ (tinstr&255);
+ }
+
+ /* 6.6.1 Format 2: */
+ case 0xb000 >> 11: /* 7.1.48 PUSH */
+ case 0xb800 >> 11: /* 7.1.47 POP */
+ if ((tinstr & (3 << 9)) == 0x0400) {
+ static const u32 subset[4] = {
+ 0xe92d0000, /* STMDB sp!,{registers} */
+ 0xe92d4000, /* STMDB sp!,{registers,lr} */
+ 0xe8bd0000, /* LDMIA sp!,{registers} */
+ 0xe8bd8000 /* LDMIA sp!,{registers,pc} */
+ };
+ return subset[(L<<1) | ((tinstr & (1<<8)) >> 8)] |
+ (tinstr & 255); /* register_list */
+ }
+ /* Else fall through for illegal instruction case */
+
+ default:
+ return BAD_INSTR;
+ }
+}
+
+/*
+ * Convert Thumb-2 32 bit LDM, STM, LDRD, STRD to equivalent instruction
+ * handlable by ARM alignment handler, also find the corresponding handler,
+ * so that we can reuse ARM userland alignment fault fixups for Thumb.
+ *
+ * @pinstr: original Thumb-2 instruction; returns new handlable instruction
+ * @regs: register context.
+ * @poffset: return offset from faulted addr for later writeback
+ *
+ * NOTES:
+ * 1. Comments below refer to ARMv7 DDI0406A Thumb Instruction sections.
+ * 2. Register name Rt from ARMv7 is same as Rd from ARMv6 (Rd is Rt)
+ */
+static void *
+do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
+ union offset_union *poffset)
+{
+ unsigned long instr = *pinstr;
+ u16 tinst1 = (instr >> 16) & 0xffff;
+ u16 tinst2 = instr & 0xffff;
+ poffset->un = 0;
+
+ switch (tinst1 & 0xffe0) {
+ /* A6.3.5 Load/Store multiple */
+ case 0xe880: /* STM/STMIA/STMEA,LDM/LDMIA, PUSH/POP T2 */
+ case 0xe8a0: /* ...above writeback version */
+ case 0xe900: /* STMDB/STMFD, LDMDB/LDMEA */
+ case 0xe920: /* ...above writeback version */
+ /* no need offset decision since handler calculates it */
+ return do_alignment_ldmstm;
+
+ case 0xf840: /* POP/PUSH T3 (single register) */
+ if (RN_BITS(instr) == 13 && (tinst2 & 0x09ff) == 0x0904) {
+ u32 L = !!(LDST_L_BIT(instr));
+ const u32 subset[2] = {
+ 0xe92d0000, /* STMDB sp!,{registers} */
+ 0xe8bd0000, /* LDMIA sp!,{registers} */
+ };
+ *pinstr = subset[L] | (1<<RD_BITS(instr));
+ return do_alignment_ldmstm;
+ }
+ /* Else fall through for illegal instruction case */
+ break;
+
+ /* A6.3.6 Load/store double, STRD/LDRD(immed, lit, reg) */
+ case 0xe860:
+ case 0xe960:
+ case 0xe8e0:
+ case 0xe9e0:
+ poffset->un = (tinst2 & 0xff) << 2;
+ case 0xe940:
+ case 0xe9c0:
+ return do_alignment_ldrdstrd;
+
+ /*
+ * No need to handle load/store instructions up to word size
+ * since ARMv6 and later CPUs can perform unaligned accesses.
+ */
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int
+do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ union offset_union offset;
+ unsigned long instr = 0, instrptr;
+ int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+ unsigned int type;
+ mm_segment_t fs;
+ unsigned int fault;
+ u16 tinstr = 0;
+ int isize = 4;
+ int thumb2_32b = 0;
+
+ instrptr = instruction_pointer(regs);
+
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ if (thumb_mode(regs)) {
+ fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
+ if (!fault) {
+ if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
+ IS_T32(tinstr)) {
+ /* Thumb-2 32-bit */
+ u16 tinst2 = 0;
+ fault = __get_user(tinst2, (u16 *)(instrptr+2));
+ instr = (tinstr << 16) | tinst2;
+ thumb2_32b = 1;
+ } else {
+ isize = 2;
+ instr = thumb2arm(tinstr);
+ }
+ }
+ } else
+ fault = __get_user(instr, (u32 *)instrptr);
+ set_fs(fs);
+
+ if (fault) {
+ type = TYPE_FAULT;
+ goto bad_or_fault;
+ }
+
+ if (user_mode(regs))
+ goto user;
+
+ ai_sys += 1;
+
+ fixup:
+
+ regs->ARM_pc += isize;
+
+ switch (CODING_BITS(instr)) {
+ case 0x00000000: /* 3.13.4 load/store instruction extensions */
+ if (LDSTHD_I_BIT(instr))
+ offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+ else
+ offset.un = regs->uregs[RM_BITS(instr)];
+
+ if ((instr & 0x000000f0) == 0x000000b0 || /* LDRH, STRH */
+ (instr & 0x001000f0) == 0x001000f0) /* LDRSH */
+ handler = do_alignment_ldrhstrh;
+ else if ((instr & 0x001000f0) == 0x000000d0 || /* LDRD */
+ (instr & 0x001000f0) == 0x000000f0) /* STRD */
+ handler = do_alignment_ldrdstrd;
+ else if ((instr & 0x01f00ff0) == 0x01000090) /* SWP */
+ goto swp;
+ else
+ goto bad;
+ break;
+
+ case 0x04000000: /* ldr or str immediate */
+ offset.un = OFFSET_BITS(instr);
+ handler = do_alignment_ldrstr;
+ break;
+
+ case 0x06000000: /* ldr or str register */
+ offset.un = regs->uregs[RM_BITS(instr)];
+
+ if (IS_SHIFT(instr)) {
+ unsigned int shiftval = SHIFT_BITS(instr);
+
+ switch(SHIFT_TYPE(instr)) {
+ case SHIFT_LSL:
+ offset.un <<= shiftval;
+ break;
+
+ case SHIFT_LSR:
+ offset.un >>= shiftval;
+ break;
+
+ case SHIFT_ASR:
+ offset.sn >>= shiftval;
+ break;
+
+ case SHIFT_RORRRX:
+ if (shiftval == 0) {
+ offset.un >>= 1;
+ if (regs->ARM_cpsr & PSR_C_BIT)
+ offset.un |= 1 << 31;
+ } else
+ offset.un = offset.un >> shiftval |
+ offset.un << (32 - shiftval);
+ break;
+ }
+ }
+ handler = do_alignment_ldrstr;
+ break;
+
+ case 0x08000000: /* ldm or stm, or thumb-2 32bit instruction */
+ if (thumb2_32b)
+ handler = do_alignment_t32_to_handler(&instr, regs, &offset);
+ else
+ handler = do_alignment_ldmstm;
+ break;
+
+ default:
+ goto bad;
+ }
+
+ if (!handler)
+ goto bad;
+ type = handler(addr, instr, regs);
+
+ if (type == TYPE_ERROR || type == TYPE_FAULT) {
+ regs->ARM_pc -= isize;
+ goto bad_or_fault;
+ }
+
+ if (type == TYPE_LDST)
+ do_alignment_finish_ldst(addr, instr, regs, offset);
+
+ return 0;
+
+ bad_or_fault:
+ if (type == TYPE_ERROR)
+ goto bad;
+ /*
+ * We got a fault - fix it up, or die.
+ */
+ do_bad_area(addr, fsr, regs);
+ return 0;
+
+ swp:
+ printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
+
+ bad:
+ /*
+ * Oops, we didn't handle the instruction.
+ */
+ printk(KERN_ERR "Alignment trap: not handling instruction "
+ "%0*lx at [<%08lx>]\n",
+ isize << 1,
+ isize == 2 ? tinstr : instr, instrptr);
+ ai_skipped += 1;
+ return 1;
+
+ user:
+ ai_user += 1;
+
+ if (ai_usermode & UM_WARN)
+ printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
+ "Address=0x%08lx FSR 0x%03x\n", current->comm,
+ task_pid_nr(current), instrptr,
+ isize << 1,
+ isize == 2 ? tinstr : instr,
+ addr, fsr);
+
+ if (ai_usermode & UM_FIXUP)
+ goto fixup;
+
+ if (ai_usermode & UM_SIGNAL)
+ force_sig(SIGBUS, current);
+ else {
+ /*
+ * We're about to disable the alignment trap and return to
+ * user space. But if an interrupt occurs before actually
+ * reaching user space, then the IRQ vector entry code will
+ * notice that we were still in kernel space and therefore
+ * the alignment trap won't be re-enabled in that case as it
+ * is presumed to be always on from kernel space.
+ * Let's prevent that race by disabling interrupts here (they
+ * are disabled on the way back to user space anyway in
+ * entry-common.S) and disable the alignment trap only if
+ * there is no work pending for this thread.
+ */
+ raw_local_irq_disable();
+ if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+ set_cr(cr_no_alignment);
+ }
+
+ return 0;
+}
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten. Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *res;
+
+ res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
+ &alignment_proc_fops);
+ if (!res)
+ return -ENOMEM;
+#endif
+
+ /*
+ * ARMv6 and later CPUs can perform unaligned accesses for
+ * most single load and store instructions up to word size.
+ * LDM, STM, LDRD and STRD still need to be handled.
+ *
+ * Ignoring the alignment fault is not an option on these
+ * CPUs since we spin re-faulting the instruction without
+ * making any progress.
+ */
+ if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) {
+ cr_alignment &= ~CR_A;
+ cr_no_alignment &= ~CR_A;
+ set_cr(cr_alignment);
+ ai_usermode = UM_FIXUP;
+ }
+
+ hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN,
+ "alignment exception");
+
+ /*
+ * ARMv6K and ARMv7 use fault status 3 (0b00011) as Access Flag section
+ * fault, not as alignment error.
+ *
+ * TODO: handle ARMv6K properly. Runtime check for 'K' extension is
+ * needed.
+ */
+ if (cpu_architecture() <= CPU_ARCH_ARMv6) {
+ hook_fault_code(3, do_alignment, SIGBUS, BUS_ADRALN,
+ "alignment exception");
+ }
+
+ return 0;
+}
+
+fs_initcall(alignment_init);
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
new file mode 100644
index 00000000..1fa6f714
--- /dev/null
+++ b/arch/arm/mm/cache-fa.S
@@ -0,0 +1,257 @@
+/*
+ * linux/arch/arm/mm/cache-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on cache-v4wb.S:
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Processors: FA520 FA526 FA626
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 16
+
+/*
+ * The total size of the data cache.
+ */
+#ifdef CONFIG_ARCH_GEMINI
+#define CACHE_DSIZE 8192
+#else
+#define CACHE_DSIZE 16384
+#endif
+
+/* FIXME: put optimal value here. Current one is just estimation */
+#define CACHE_DLIMIT (CACHE_DSIZE * 2)
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(fa_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(fa_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(fa_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(fa_flush_kern_cache_all)
+ mov ip, #0
+ mov r2, #VM_EXEC
+__flush_whole_cache:
+ mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive, page aligned)
+ * - end - end address (exclusive, page aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(fa_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT @ total size >= limit?
+ bhs __flush_whole_cache @ flush whole D cache
+
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_coherent_kern_range)
+ /* fall through */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(fa_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure that the data held in the page kaddr is written back
+ * to the page in question.
+ *
+ * - addr - kernel address
+ * - size - size of region
+ */
+ENTRY(fa_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+fa_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ bic r1, r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean (write back) the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+fa_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_flush_range(start,end)
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+ENTRY(fa_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(fa_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq fa_dma_clean_range
+ bcs fa_dma_inv_range
+ b fa_dma_flush_range
+ENDPROC(fa_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(fa_dma_unmap_area)
+ mov pc, lr
+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
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
new file mode 100644
index 00000000..e0b0e7a4
--- /dev/null
+++ b/arch/arm/mm/cache-feroceon-l2.c
@@ -0,0 +1,350 @@
+/*
+ * arch/arm/mm/cache-feroceon-l2.c - Feroceon L2 cache controller support
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * References:
+ * - Unified Layer 2 Cache for Feroceon CPU Cores,
+ * Document ID MV-S104858-00, Rev. A, October 23 2007.
+ */
+
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/cacheflush.h>
+#include <plat/cache-feroceon-l2.h>
+
+/*
+ * Low-level cache maintenance operations.
+ *
+ * As well as the regular 'clean/invalidate/flush L2 cache line by
+ * MVA' instructions, the Feroceon L2 cache controller also features
+ * 'clean/invalidate L2 range by MVA' operations.
+ *
+ * Cache range operations are initiated by writing the start and
+ * end addresses to successive cp15 registers, and process every
+ * cache line whose first byte address lies in the inclusive range
+ * [start:end].
+ *
+ * The cache range operations stall the CPU pipeline until completion.
+ *
+ * The range operations require two successive cp15 writes, in
+ * between which we don't want to be preempted.
+ */
+
+static inline unsigned long l2_get_va(unsigned long paddr)
+{
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Because range ops can't be done on physical addresses,
+ * we simply install a virtual mapping for it only for the
+ * TLB lookup to occur, hence no need to flush the untouched
+ * memory mapping afterwards (note: a cache flush may happen
+ * in some circumstances depending on the path taken in kunmap_atomic).
+ */
+ void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
+ return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
+#else
+ return __phys_to_virt(paddr);
+#endif
+}
+
+static inline void l2_put_va(unsigned long vaddr)
+{
+#ifdef CONFIG_HIGHMEM
+ kunmap_atomic((void *)vaddr);
+#endif
+}
+
+static inline void l2_clean_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
+}
+
+static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
+{
+ unsigned long va_start, va_end, flags;
+
+ /*
+ * Make sure 'start' and 'end' reference the same page, as
+ * L2 is PIPT and range operations only do a TLB lookup on
+ * the start address.
+ */
+ BUG_ON((start ^ end) >> PAGE_SHIFT);
+
+ va_start = l2_get_va(start);
+ va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
+ __asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
+ "mcr p15, 1, %1, c15, c9, 5"
+ : : "r" (va_start), "r" (va_end));
+ raw_local_irq_restore(flags);
+ l2_put_va(va_start);
+}
+
+static inline void l2_clean_inv_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c15, c10, 3" : : "r" (addr));
+}
+
+static inline void l2_inv_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c15, c11, 3" : : "r" (addr));
+}
+
+static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
+{
+ unsigned long va_start, va_end, flags;
+
+ /*
+ * Make sure 'start' and 'end' reference the same page, as
+ * L2 is PIPT and range operations only do a TLB lookup on
+ * the start address.
+ */
+ BUG_ON((start ^ end) >> PAGE_SHIFT);
+
+ va_start = l2_get_va(start);
+ va_end = va_start + (end - start);
+ raw_local_irq_save(flags);
+ __asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
+ "mcr p15, 1, %1, c15, c11, 5"
+ : : "r" (va_start), "r" (va_end));
+ raw_local_irq_restore(flags);
+ l2_put_va(va_start);
+}
+
+static inline void l2_inv_all(void)
+{
+ __asm__("mcr p15, 1, %0, c15, c11, 0" : : "r" (0));
+}
+
+/*
+ * Linux primitives.
+ *
+ * Note that the end addresses passed to Linux primitives are
+ * noninclusive, while the hardware cache range operations use
+ * inclusive start and end addresses.
+ */
+#define CACHE_LINE_SIZE 32
+#define MAX_RANGE_SIZE 1024
+
+static int l2_wt_override;
+
+static unsigned long calc_range_end(unsigned long start, unsigned long end)
+{
+ unsigned long range_end;
+
+ BUG_ON(start & (CACHE_LINE_SIZE - 1));
+ BUG_ON(end & (CACHE_LINE_SIZE - 1));
+
+ /*
+ * Try to process all cache lines between 'start' and 'end'.
+ */
+ range_end = end;
+
+ /*
+ * Limit the number of cache lines processed at once,
+ * since cache range operations stall the CPU pipeline
+ * until completion.
+ */
+ if (range_end > start + MAX_RANGE_SIZE)
+ range_end = start + MAX_RANGE_SIZE;
+
+ /*
+ * Cache range operations can't straddle a page boundary.
+ */
+ if (range_end > (start | (PAGE_SIZE - 1)) + 1)
+ range_end = (start | (PAGE_SIZE - 1)) + 1;
+
+ return range_end;
+}
+
+static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
+{
+ /*
+ * Clean and invalidate partial first cache line.
+ */
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ l2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
+ start = (start | (CACHE_LINE_SIZE - 1)) + 1;
+ }
+
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+ if (start < end && end & (CACHE_LINE_SIZE - 1)) {
+ l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ end &= ~(CACHE_LINE_SIZE - 1);
+ }
+
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+ while (start < end) {
+ unsigned long range_end = calc_range_end(start, end);
+ l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE);
+ start = range_end;
+ }
+
+ dsb();
+}
+
+static void feroceon_l2_clean_range(unsigned long start, unsigned long end)
+{
+ /*
+ * If L2 is forced to WT, the L2 will always be clean and we
+ * don't need to do anything here.
+ */
+ if (!l2_wt_override) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = (end + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
+ while (start != end) {
+ unsigned long range_end = calc_range_end(start, end);
+ l2_clean_pa_range(start, range_end - CACHE_LINE_SIZE);
+ start = range_end;
+ }
+ }
+
+ dsb();
+}
+
+static void feroceon_l2_flush_range(unsigned long start, unsigned long end)
+{
+ start &= ~(CACHE_LINE_SIZE - 1);
+ end = (end + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1);
+ while (start != end) {
+ unsigned long range_end = calc_range_end(start, end);
+ if (!l2_wt_override)
+ l2_clean_pa_range(start, range_end - CACHE_LINE_SIZE);
+ l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE);
+ start = range_end;
+ }
+
+ dsb();
+}
+
+
+/*
+ * Routines to disable and re-enable the D-cache and I-cache at run
+ * time. These are necessary because the L2 cache can only be enabled
+ * or disabled while the L1 Dcache and Icache are both disabled.
+ */
+static int __init flush_and_disable_dcache(void)
+{
+ u32 cr;
+
+ cr = get_cr();
+ if (cr & CR_C) {
+ unsigned long flags;
+
+ raw_local_irq_save(flags);
+ flush_cache_all();
+ set_cr(cr & ~CR_C);
+ raw_local_irq_restore(flags);
+ return 1;
+ }
+ return 0;
+}
+
+static void __init enable_dcache(void)
+{
+ u32 cr;
+
+ cr = get_cr();
+ set_cr(cr | CR_C);
+}
+
+static void __init __invalidate_icache(void)
+{
+ __asm__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+}
+
+static int __init invalidate_and_disable_icache(void)
+{
+ u32 cr;
+
+ cr = get_cr();
+ if (cr & CR_I) {
+ set_cr(cr & ~CR_I);
+ __invalidate_icache();
+ return 1;
+ }
+ return 0;
+}
+
+static void __init enable_icache(void)
+{
+ u32 cr;
+
+ cr = get_cr();
+ set_cr(cr | CR_I);
+}
+
+static inline u32 read_extra_features(void)
+{
+ u32 u;
+
+ __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u));
+
+ return u;
+}
+
+static inline void write_extra_features(u32 u)
+{
+ __asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
+}
+
+static void __init disable_l2_prefetch(void)
+{
+ u32 u;
+
+ /*
+ * Read the CPU Extra Features register and verify that the
+ * Disable L2 Prefetch bit is set.
+ */
+ u = read_extra_features();
+ if (!(u & 0x01000000)) {
+ printk(KERN_INFO "Feroceon L2: Disabling L2 prefetch.\n");
+ write_extra_features(u | 0x01000000);
+ }
+}
+
+static void __init enable_l2(void)
+{
+ u32 u;
+
+ u = read_extra_features();
+ if (!(u & 0x00400000)) {
+ int i, d;
+
+ printk(KERN_INFO "Feroceon L2: Enabling L2\n");
+
+ d = flush_and_disable_dcache();
+ i = invalidate_and_disable_icache();
+ l2_inv_all();
+ write_extra_features(u | 0x00400000);
+ if (i)
+ enable_icache();
+ if (d)
+ enable_dcache();
+ }
+}
+
+void __init feroceon_l2_init(int __l2_wt_override)
+{
+ l2_wt_override = __l2_wt_override;
+
+ disable_l2_prefetch();
+
+ outer_cache.inv_range = feroceon_l2_inv_range;
+ outer_cache.clean_range = feroceon_l2_clean_range;
+ outer_cache.flush_range = feroceon_l2_flush_range;
+
+ enable_l2();
+
+ printk(KERN_INFO "Feroceon L2: Cache support initialised%s.\n",
+ l2_wt_override ? ", in WT override mode" : "");
+}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
new file mode 100644
index 00000000..19d5d86a
--- /dev/null
+++ b/arch/arm/mm/cache-l2x0.c
@@ -0,0 +1,395 @@
+/*
+ * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#define CACHE_LINE_SIZE 32
+
+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)
+{
+ /* wait for cache operation by line or way to complete */
+ while (readl_relaxed(reg) & mask)
+ ;
+}
+
+#ifdef CONFIG_CACHE_PL310
+static inline void cache_wait(void __iomem *reg, unsigned long mask)
+{
+ /* cache operations by line are atomic on PL310 */
+}
+#else
+#define cache_wait cache_wait_way
+#endif
+
+static inline void cache_sync(void)
+{
+ void __iomem *base = l2x0_base;
+
+#ifdef CONFIG_ARM_ERRATA_753970
+ /* write to an unmmapped register */
+ writel_relaxed(0, base + L2X0_DUMMY_REG);
+#else
+ writel_relaxed(0, base + L2X0_CACHE_SYNC);
+#endif
+ cache_wait(base + L2X0_CACHE_SYNC, 1);
+}
+
+static inline void l2x0_clean_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
+}
+
+static inline void l2x0_inv_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+ cache_wait(base + L2X0_INV_LINE_PA, 1);
+ writel_relaxed(addr, base + L2X0_INV_LINE_PA);
+}
+
+#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
+
+#define debug_writel(val) outer_cache.set_debug(val)
+
+static void l2x0_set_debug(unsigned long val)
+{
+ writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);
+}
+#else
+/* Optimised out for non-errata case */
+static inline void debug_writel(unsigned long val)
+{
+}
+
+#define l2x0_set_debug NULL
+#endif
+
+#ifdef CONFIG_PL310_ERRATA_588369
+static inline void l2x0_flush_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+
+ /* Clean by PA followed by Invalidate by PA */
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ writel_relaxed(addr, base + L2X0_CLEAN_LINE_PA);
+ cache_wait(base + L2X0_INV_LINE_PA, 1);
+ writel_relaxed(addr, base + L2X0_INV_LINE_PA);
+}
+#else
+
+static inline void l2x0_flush_line(unsigned long addr)
+{
+ void __iomem *base = l2x0_base;
+ cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+ writel_relaxed(addr, base + L2X0_CLEAN_INV_LINE_PA);
+}
+#endif
+
+static void l2x0_cache_sync(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ cache_sync();
+ 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);
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
+ cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
+ cache_sync();
+ debug_writel(0x00);
+}
+
+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();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+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);
+}
+
+static void l2x0_inv_all(void)
+{
+ unsigned long flags;
+
+ /* invalidate all ways */
+ spin_lock_irqsave(&l2x0_lock, flags);
+ /* Invalidating when L2 is enabled is a nono */
+ BUG_ON(readl(l2x0_base + L2X0_CTRL) & 1);
+ writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
+ cache_wait_way(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_inv_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ start &= ~(CACHE_LINE_SIZE - 1);
+ debug_writel(0x03);
+ l2x0_flush_line(start);
+ debug_writel(0x00);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ end &= ~(CACHE_LINE_SIZE - 1);
+ debug_writel(0x03);
+ l2x0_flush_line(end);
+ debug_writel(0x00);
+ }
+
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2x0_inv_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (blk_end < end) {
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
+ }
+ }
+ cache_wait(base + L2X0_INV_LINE_PA, 1);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_clean_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ if ((end - start) >= l2x0_size) {
+ l2x0_clean_all();
+ return;
+ }
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ while (start < blk_end) {
+ l2x0_clean_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ if (blk_end < end) {
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
+ }
+ }
+ cache_wait(base + L2X0_CLEAN_LINE_PA, 1);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_flush_range(unsigned long start, unsigned long end)
+{
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ if ((end - start) >= l2x0_size) {
+ l2x0_flush_all();
+ return;
+ }
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ unsigned long blk_end = start + min(end - start, 4096UL);
+
+ debug_writel(0x03);
+ while (start < blk_end) {
+ l2x0_flush_line(start);
+ start += CACHE_LINE_SIZE;
+ }
+ debug_writel(0x00);
+
+ if (blk_end < end) {
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+ spin_lock_irqsave(&l2x0_lock, flags);
+ }
+ }
+ cache_wait(base + L2X0_CLEAN_INV_LINE_PA, 1);
+ cache_sync();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void l2x0_disable(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&l2x0_lock, flags);
+ __l2x0_flush_all();
+ writel_relaxed(0, l2x0_base + L2X0_CTRL);
+ dsb();
+ spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+void l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
+{
+ __u32 aux;
+ __u32 way_size = 0;
+ const char *type;
+
+ l2x0_base = base;
+
+ 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 (l2x0_cache_id & L2X0_CACHE_ID_PART_MASK) {
+ case L2X0_CACHE_ID_PART_L310:
+ if (aux & (1 << 16))
+ l2x0_ways = 16;
+ else
+ l2x0_ways = 8;
+ type = "L310";
+ break;
+ case L2X0_CACHE_ID_PART_L210:
+ l2x0_ways = (aux >> 13) & 0xf;
+ type = "L210";
+ break;
+ default:
+ /* Assume unknown chips have 8 ways */
+ l2x0_ways = 8;
+ type = "L2x0 series";
+ break;
+ }
+
+ 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 = 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.
+ * If you are booting from non-secure mode
+ * accessing the below registers will fault.
+ */
+ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) {
+
+ /* l2x0 controller is disabled */
+ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
+
+ l2x0_inv_all();
+
+ /* enable L2X0 */
+ writel_relaxed(1, l2x0_base + L2X0_CTRL);
+ }
+
+ outer_cache.inv_range = l2x0_inv_range;
+ outer_cache.clean_range = l2x0_clean_range;
+ outer_cache.flush_range = l2x0_flush_range;
+ outer_cache.sync = l2x0_cache_sync;
+ outer_cache.flush_all = l2x0_flush_all;
+ outer_cache.inv_all = l2x0_inv_all;
+ outer_cache.disable = l2x0_disable;
+ 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",
+ l2x0_ways, l2x0_cache_id, aux, l2x0_size);
+}
diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c
new file mode 100644
index 00000000..50868651
--- /dev/null
+++ b/arch/arm/mm/cache-tauros2.c
@@ -0,0 +1,263 @@
+/*
+ * arch/arm/mm/cache-tauros2.c - Tauros2 L2 cache controller support
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * References:
+ * - PJ1 CPU Core Datasheet,
+ * Document ID MV-S104837-01, Rev 0.7, January 24 2008.
+ * - PJ4 CPU Core Datasheet,
+ * Document ID MV-S105190-00, Rev 0.7, March 14 2008.
+ */
+
+#include <linux/init.h>
+#include <asm/cacheflush.h>
+#include <asm/hardware/cache-tauros2.h>
+
+
+/*
+ * When Tauros2 is used on a CPU that supports the v7 hierarchical
+ * cache operations, the cache handling code in proc-v7.S takes care
+ * of everything, including handling DMA coherency.
+ *
+ * So, we only need to register outer cache operations here if we're
+ * being used on a pre-v7 CPU, and we only need to build support for
+ * outer cache operations into the kernel image if the kernel has been
+ * configured to support a pre-v7 CPU.
+ */
+#if __LINUX_ARM_ARCH__ < 7
+/*
+ * Low-level cache maintenance operations.
+ */
+static inline void tauros2_clean_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c7, c11, 3" : : "r" (addr));
+}
+
+static inline void tauros2_clean_inv_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c7, c15, 3" : : "r" (addr));
+}
+
+static inline void tauros2_inv_pa(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c7, c7, 3" : : "r" (addr));
+}
+
+
+/*
+ * Linux primitives.
+ *
+ * Note that the end addresses passed to Linux primitives are
+ * noninclusive.
+ */
+#define CACHE_LINE_SIZE 32
+
+static void tauros2_inv_range(unsigned long start, unsigned long end)
+{
+ /*
+ * Clean and invalidate partial first cache line.
+ */
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ tauros2_clean_inv_pa(start & ~(CACHE_LINE_SIZE - 1));
+ start = (start | (CACHE_LINE_SIZE - 1)) + 1;
+ }
+
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+ if (end & (CACHE_LINE_SIZE - 1)) {
+ tauros2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ end &= ~(CACHE_LINE_SIZE - 1);
+ }
+
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+ while (start < end) {
+ tauros2_inv_pa(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ dsb();
+}
+
+static void tauros2_clean_range(unsigned long start, unsigned long end)
+{
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ tauros2_clean_pa(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ dsb();
+}
+
+static void tauros2_flush_range(unsigned long start, unsigned long end)
+{
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ tauros2_clean_inv_pa(start);
+ start += CACHE_LINE_SIZE;
+ }
+
+ dsb();
+}
+#endif
+
+static inline u32 __init read_extra_features(void)
+{
+ u32 u;
+
+ __asm__("mrc p15, 1, %0, c15, c1, 0" : "=r" (u));
+
+ return u;
+}
+
+static inline void __init write_extra_features(u32 u)
+{
+ __asm__("mcr p15, 1, %0, c15, c1, 0" : : "r" (u));
+}
+
+static void __init disable_l2_prefetch(void)
+{
+ u32 u;
+
+ /*
+ * Read the CPU Extra Features register and verify that the
+ * Disable L2 Prefetch bit is set.
+ */
+ u = read_extra_features();
+ if (!(u & 0x01000000)) {
+ printk(KERN_INFO "Tauros2: Disabling L2 prefetch.\n");
+ write_extra_features(u | 0x01000000);
+ }
+}
+
+static inline int __init cpuid_scheme(void)
+{
+ extern int processor_id;
+
+ return !!((processor_id & 0x000f0000) == 0x000f0000);
+}
+
+static inline u32 __init read_mmfr3(void)
+{
+ u32 mmfr3;
+
+ __asm__("mrc p15, 0, %0, c0, c1, 7\n" : "=r" (mmfr3));
+
+ return mmfr3;
+}
+
+static inline u32 __init read_actlr(void)
+{
+ u32 actlr;
+
+ __asm__("mrc p15, 0, %0, c1, c0, 1\n" : "=r" (actlr));
+
+ return actlr;
+}
+
+static inline void __init write_actlr(u32 actlr)
+{
+ __asm__("mcr p15, 0, %0, c1, c0, 1\n" : : "r" (actlr));
+}
+
+void __init tauros2_init(void)
+{
+ extern int processor_id;
+ char *mode;
+
+ disable_l2_prefetch();
+
+#ifdef CONFIG_CPU_32v5
+ if ((processor_id & 0xff0f0000) == 0x56050000) {
+ u32 feat;
+
+ /*
+ * v5 CPUs with Tauros2 have the L2 cache enable bit
+ * located in the CPU Extra Features register.
+ */
+ feat = read_extra_features();
+ if (!(feat & 0x00400000)) {
+ printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+ write_extra_features(feat | 0x00400000);
+ }
+
+ mode = "ARMv5";
+ outer_cache.inv_range = tauros2_inv_range;
+ outer_cache.clean_range = tauros2_clean_range;
+ outer_cache.flush_range = tauros2_flush_range;
+ }
+#endif
+
+#ifdef CONFIG_CPU_32v6
+ /*
+ * Check whether this CPU lacks support for the v7 hierarchical
+ * cache ops. (PJ4 is in its v6 personality mode if the MMFR3
+ * register indicates no support for the v7 hierarchical cache
+ * ops.)
+ */
+ if (cpuid_scheme() && (read_mmfr3() & 0xf) == 0) {
+ /*
+ * When Tauros2 is used in an ARMv6 system, the L2
+ * enable bit is in the ARMv6 ARM-mandated position
+ * (bit [26] of the System Control Register).
+ */
+ if (!(get_cr() & 0x04000000)) {
+ printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+ adjust_cr(0x04000000, 0x04000000);
+ }
+
+ mode = "ARMv6";
+ outer_cache.inv_range = tauros2_inv_range;
+ outer_cache.clean_range = tauros2_clean_range;
+ outer_cache.flush_range = tauros2_flush_range;
+ }
+#endif
+
+#ifdef CONFIG_CPU_32v7
+ /*
+ * Check whether this CPU has support for the v7 hierarchical
+ * cache ops. (PJ4 is in its v7 personality mode if the MMFR3
+ * register indicates support for the v7 hierarchical cache
+ * ops.)
+ *
+ * (Although strictly speaking there may exist CPUs that
+ * implement the v7 cache ops but are only ARMv6 CPUs (due to
+ * not complying with all of the other ARMv7 requirements),
+ * there are no real-life examples of Tauros2 being used on
+ * such CPUs as of yet.)
+ */
+ if (cpuid_scheme() && (read_mmfr3() & 0xf) == 1) {
+ u32 actlr;
+
+ /*
+ * When Tauros2 is used in an ARMv7 system, the L2
+ * enable bit is located in the Auxiliary System Control
+ * Register (which is the only register allowed by the
+ * ARMv7 spec to contain fine-grained cache control bits).
+ */
+ actlr = read_actlr();
+ if (!(actlr & 0x00000002)) {
+ printk(KERN_INFO "Tauros2: Enabling L2 cache.\n");
+ write_actlr(actlr | 0x00000002);
+ }
+
+ mode = "ARMv7";
+ }
+#endif
+
+ if (mode == NULL) {
+ printk(KERN_CRIT "Tauros2: Unable to detect CPU mode.\n");
+ return;
+ }
+
+ printk(KERN_INFO "Tauros2: L2 cache support initialised "
+ "in %s mode.\n", mode);
+}
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
new file mode 100644
index 00000000..2e2bc406
--- /dev/null
+++ b/arch/arm/mm/cache-v3.S
@@ -0,0 +1,144 @@
+/*
+ * linux/arch/arm/mm/cache-v3.S
+ *
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include "proc-macros.S"
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v3_flush_icache_all)
+ mov pc, lr
+ENDPROC(v3_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ *
+ * - mm - mm_struct describing address space
+ */
+ENTRY(v3_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(v3_flush_kern_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(v3_flush_user_cache_range)
+ mov ip, #0
+ mcreq p15, 0, ip, c7, c0, 0 @ flush ID cache
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v3_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v3_coherent_user_range)
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *page, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v3_flush_kern_dcache_area)
+ /* FALLTHROUGH */
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v3_dma_flush_range)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ flush ID cache
+ mov pc, lr
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v3_dma_unmap_area)
+ teq r2, #DMA_TO_DEVICE
+ bne v3_dma_flush_range
+ /* FALLTHROUGH */
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v3_dma_map_area)
+ mov pc, lr
+ENDPROC(v3_dma_unmap_area)
+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
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
new file mode 100644
index 00000000..a8fefb52
--- /dev/null
+++ b/arch/arm/mm/cache-v4.S
@@ -0,0 +1,156 @@
+/*
+ * linux/arch/arm/mm/cache-v4.S
+ *
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include "proc-macros.S"
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4_flush_icache_all)
+ mov pc, lr
+ENDPROC(v4_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ *
+ * - mm - mm_struct describing address space
+ */
+ENTRY(v4_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(v4_flush_kern_cache_all)
+#ifdef CONFIG_CPU_CP15
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
+ mov pc, lr
+#else
+ /* FALLTHROUGH */
+#endif
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(v4_flush_user_cache_range)
+#ifdef CONFIG_CPU_CP15
+ mov ip, #0
+ mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache
+ mov pc, lr
+#else
+ /* FALLTHROUGH */
+#endif
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4_coherent_user_range)
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v4_flush_kern_dcache_area)
+ /* FALLTHROUGH */
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4_dma_flush_range)
+#ifdef CONFIG_CPU_CP15
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
+#endif
+ mov pc, lr
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4_dma_unmap_area)
+ teq r2, #DMA_TO_DEVICE
+ bne v4_dma_flush_range
+ /* FALLTHROUGH */
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4_dma_map_area)
+ mov pc, lr
+ENDPROC(v4_dma_unmap_area)
+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
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
new file mode 100644
index 00000000..f40c6965
--- /dev/null
+++ b/arch/arm/mm/cache-v4wb.S
@@ -0,0 +1,268 @@
+/*
+ * linux/arch/arm/mm/cache-v4wb.S
+ *
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can 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/linkage.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The total size of the data cache.
+ */
+#if defined(CONFIG_CPU_SA110)
+# define CACHE_DSIZE 16384
+#elif defined(CONFIG_CPU_SA1100)
+# define CACHE_DSIZE 8192
+#else
+# error Unknown cache size
+#endif
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ *
+ * Size Clean (ticks) Dirty (ticks)
+ * 4096 21 20 21 53 55 54
+ * 8192 40 41 40 106 100 102
+ * 16384 77 77 76 140 140 138
+ * 32768 150 149 150 214 216 212 <---
+ * 65536 296 297 296 351 358 361
+ * 131072 591 591 591 656 657 651
+ * Whole 132 136 132 221 217 207 <---
+ */
+#define CACHE_DLIMIT (CACHE_DSIZE * 4)
+
+ .data
+flush_base:
+ .long FLUSH_BASE
+ .text
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wb_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(v4wb_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(v4wb_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(v4wb_flush_kern_cache_all)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+__flush_whole_cache:
+ ldr r3, =flush_base
+ ldr r1, [r3, #0]
+ eor r1, r1, #CACHE_DSIZE
+ str r1, [r3, #0]
+ add r2, r1, #CACHE_DSIZE
+1: ldr r3, [r1], #32
+ cmp r1, r2
+ blo 1b
+#ifdef FLUSH_BASE_MINICACHE
+ add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE
+ sub r1, r2, #512 @ only 512 bytes
+1: ldr r3, [r1], #32
+ cmp r1, r2
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive, page aligned)
+ * - end - end address (exclusive, page aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(v4wb_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ tst r2, #VM_EXEC @ executable region?
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+
+ cmp r3, #CACHE_DLIMIT @ total size >= limit?
+ bhs __flush_whole_cache @ flush whole D cache
+
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v4wb_flush_kern_dcache_area)
+ add r1, r0, r1
+ /* fall through */
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4wb_coherent_kern_range)
+ /* fall through */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4wb_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+v4wb_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean (write back) the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+v4wb_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * This is actually the same as v4wb_coherent_kern_range()
+ */
+ .globl v4wb_dma_flush_range
+ .set v4wb_dma_flush_range, v4wb_coherent_kern_range
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4wb_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq v4wb_dma_clean_range
+ bcs v4wb_dma_inv_range
+ b v4wb_dma_flush_range
+ENDPROC(v4wb_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4wb_dma_unmap_area)
+ mov pc, lr
+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
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
new file mode 100644
index 00000000..a7b276db
--- /dev/null
+++ b/arch/arm/mm/cache-v4wt.S
@@ -0,0 +1,212 @@
+/*
+ * linux/arch/arm/mm/cache-v4wt.S
+ *
+ * Copyright (C) 1997-2002 Russell king
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARMv4 write through cache operations support.
+ *
+ * We assume that the write buffer is not enabled.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 8
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ *
+ * *** This needs benchmarking
+ */
+#define CACHE_DLIMIT 16384
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(v4wt_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(v4wt_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(v4wt_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(v4wt_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive, page aligned)
+ * - end - end address (exclusive, page aligned)
+ * - flags - vma_area_struct flags describing address space
+ */
+ENTRY(v4wt_flush_user_cache_range)
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4wt_coherent_kern_range)
+ /* FALLTRHOUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(v4wt_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v4wt_flush_kern_dcache_area)
+ mov r2, #0
+ mcr p15, 0, r2, c7, c5, 0 @ invalidate I cache
+ add r1, r0, r1
+ /* fallthrough */
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+v4wt_dma_inv_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ .globl v4wt_dma_flush_range
+ .equ v4wt_dma_flush_range, v4wt_dma_inv_range
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4wt_dma_unmap_area)
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ bne v4wt_dma_inv_range
+ /* FALLTHROUGH */
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v4wt_dma_map_area)
+ mov pc, lr
+ENDPROC(v4wt_dma_unmap_area)
+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
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
new file mode 100644
index 00000000..6b5441d7
--- /dev/null
+++ b/arch/arm/mm/cache-v6.S
@@ -0,0 +1,362 @@
+/*
+ * linux/arch/arm/mm/cache-v6.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions 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.
+ *
+ * This is the "shell" of the ARMv6 processor support.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/unwind.h>
+
+#include "proc-macros.S"
+
+#define HARVARD_CACHE
+#define CACHE_LINE_SIZE 32
+#define D_CACHE_LINE_SIZE 32
+#define BTB_FLUSH_SIZE 8
+
+/*
+ * v6_flush_icache_all()
+ *
+ * Flush the whole I-cache.
+ *
+ * ARM1136 erratum 411920 - Invalidate Instruction Cache operation can fail.
+ * This erratum is present in 1136, 1156 and 1176. It does not affect the
+ * MPCore.
+ *
+ * Registers:
+ * r0 - set to 0
+ * r1 - corrupted
+ */
+ENTRY(v6_flush_icache_all)
+ mov r0, #0
+#ifdef CONFIG_ARM_ERRATA_411920
+ mrs r1, cpsr
+ cpsid ifa @ disable interrupts
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache
+ msr cpsr_cx, r1 @ restore interrupts
+ .rept 11 @ ARM Ltd recommends at least
+ nop @ 11 NOPs
+ .endr
+#else
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I-cache
+#endif
+ mov pc, lr
+ENDPROC(v6_flush_icache_all)
+
+/*
+ * v6_flush_cache_all()
+ *
+ * Flush the entire cache.
+ *
+ * It is assumed that:
+ */
+ENTRY(v6_flush_kern_cache_all)
+ mov r0, #0
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c14, 0 @ D cache clean+invalidate
+#ifndef CONFIG_ARM_ERRATA_411920
+ mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
+#else
+ b v6_flush_icache_all
+#endif
+#else
+ mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate
+#endif
+ mov pc, lr
+
+/*
+ * v6_flush_cache_all()
+ *
+ * Flush all TLB entries in a particular address space
+ *
+ * - mm - mm_struct describing address space
+ */
+ENTRY(v6_flush_user_cache_all)
+ /*FALLTHROUGH*/
+
+/*
+ * v6_flush_cache_range(start, end, flags)
+ *
+ * Flush a range of TLB entries in the specified address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - flags - vm_area_struct flags describing address space
+ *
+ * It is assumed that:
+ * - we have a VIPT cache.
+ */
+ENTRY(v6_flush_user_cache_range)
+ mov pc, lr
+
+/*
+ * v6_coherent_kern_range(start,end)
+ *
+ * Ensure that the I and D caches are coherent within specified
+ * region. This is typically used when code has been written to
+ * a memory region, and will be executed.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ *
+ * It is assumed that:
+ * - the Icache does not read data from the write buffer
+ */
+ENTRY(v6_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * v6_coherent_user_range(start,end)
+ *
+ * Ensure that the I and D caches are coherent within specified
+ * region. This is typically used when code has been written to
+ * a memory region, and will be executed.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ *
+ * It is assumed that:
+ * - the Icache does not read data from the write buffer
+ */
+ENTRY(v6_coherent_user_range)
+ UNWIND(.fnstart )
+#ifdef HARVARD_CACHE
+ bic r0, r0, #CACHE_LINE_SIZE - 1
+1:
+ USER( mcr p15, 0, r0, c7, c10, 1 ) @ clean D line
+ add r0, r0, #CACHE_LINE_SIZE
+2:
+ cmp r0, r1
+ blo 1b
+#endif
+ mov r0, #0
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+#ifndef CONFIG_ARM_ERRATA_411920
+ mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate
+#else
+ b v6_flush_icache_all
+#endif
+#else
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
+#endif
+ mov pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+ mov r0, r0, lsr #12
+ mov r0, r0, lsl #12
+ add r0, r0, #4096
+ b 2b
+ UNWIND(.fnend )
+ENDPROC(v6_coherent_user_range)
+ENDPROC(v6_coherent_kern_range)
+
+/*
+ * v6_flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure that the data held in the page kaddr is written back
+ * to the page in question.
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v6_flush_kern_dcache_area)
+ add r1, r0, r1
+ bic r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
+#else
+ mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate unified line
+#endif
+ add r0, r0, #D_CACHE_LINE_SIZE
+ cmp r0, r1
+ blo 1b
+#ifdef HARVARD_CACHE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4
+#endif
+ mov pc, lr
+
+
+/*
+ * v6_dma_inv_range(start,end)
+ *
+ * Invalidate the data cache within the specified region; we will
+ * be performing a DMA operation in this region and we want to
+ * purge old data in the cache.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+v6_dma_inv_range:
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrb r2, [r0] @ read for ownership
+ strb r2, [r0] @ write for ownership
+#endif
+ tst r0, #D_CACHE_LINE_SIZE - 1
+ bic r0, r0, #D_CACHE_LINE_SIZE - 1
+#ifdef HARVARD_CACHE
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D line
+#else
+ mcrne p15, 0, r0, c7, c11, 1 @ clean unified line
+#endif
+ tst r1, #D_CACHE_LINE_SIZE - 1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrneb r2, [r1, #-1] @ read for ownership
+ strneb r2, [r1, #-1] @ write for ownership
+#endif
+ bic r1, r1, #D_CACHE_LINE_SIZE - 1
+#ifdef HARVARD_CACHE
+ mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line
+#else
+ mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line
+#endif
+1:
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D line
+#else
+ mcr p15, 0, r0, c7, c7, 1 @ invalidate unified line
+#endif
+ add r0, r0, #D_CACHE_LINE_SIZE
+ cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlo r2, [r0] @ read for ownership
+ strlo r2, [r0] @ write for ownership
+#endif
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * v6_dma_clean_range(start,end)
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+v6_dma_clean_range:
+ bic r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldr r2, [r0] @ read for ownership
+#endif
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D line
+#else
+ mcr p15, 0, r0, c7, c11, 1 @ clean unified line
+#endif
+ add r0, r0, #D_CACHE_LINE_SIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mov pc, lr
+
+/*
+ * v6_dma_flush_range(start,end)
+ * - start - virtual start address of region
+ * - 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
+#endif
+ bic r0, r0, #D_CACHE_LINE_SIZE - 1
+1:
+#ifdef HARVARD_CACHE
+ mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
+#else
+ mcr p15, 0, r0, c7, c15, 1 @ clean & invalidate line
+#endif
+ add r0, r0, #D_CACHE_LINE_SIZE
+ cmp r0, r1
+#ifdef CONFIG_DMA_CACHE_RWFO
+ ldrlob r2, [r0] @ read for ownership
+ strlob r2, [r0] @ write for ownership
+#endif
+ blo 1b
+ mov r0, #0
+ 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
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v6_dma_map_area)
+ add r1, r1, r0
+ teq r2, #DMA_FROM_DEVICE
+ beq v6_dma_inv_range
+#ifndef CONFIG_DMA_CACHE_RWFO
+ b v6_dma_clean_range
+#else
+ teq r2, #DMA_TO_DEVICE
+ beq v6_dma_clean_range
+ b v6_dma_flush_range
+#endif
+ENDPROC(v6_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v6_dma_unmap_area)
+#ifndef CONFIG_DMA_CACHE_RWFO
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ bne v6_dma_inv_range
+#endif
+ mov pc, lr
+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
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
new file mode 100644
index 00000000..428b2431
--- /dev/null
+++ b/arch/arm/mm/cache-v7.S
@@ -0,0 +1,369 @@
+/*
+ * linux/arch/arm/mm/cache-v7.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright (C) 2005 ARM 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.
+ *
+ * This is the "shell" of the ARMv7 processor support.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/unwind.h>
+
+#include "proc-macros.S"
+
+/*
+ * v7_flush_icache_all()
+ *
+ * Flush the whole I-cache.
+ *
+ * Registers:
+ * r0 - set to 0
+ */
+ENTRY(v7_flush_icache_all)
+ mov r0, #0
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
+ mov pc, lr
+ENDPROC(v7_flush_icache_all)
+
+/*
+ * v7_flush_dcache_all()
+ *
+ * Flush the whole D-cache.
+ *
+ * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ *
+ * - mm - mm_struct describing address space
+ */
+ENTRY(v7_flush_dcache_all)
+ 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 finished @ 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
+#ifdef CONFIG_PREEMPT
+ save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic
+#endif
+ 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
+#ifdef CONFIG_PREEMPT
+ restore_irqs_notrace r9
+#endif
+ 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:
+ add r10, r10, #2 @ increment cache number
+ cmp r3, r10
+ bgt loop1
+finished:
+ 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(v7_flush_dcache_all)
+
+/*
+ * v7_flush_cache_all()
+ *
+ * Flush the entire cache system.
+ * The data cache flush is now achieved using atomic clean / invalidates
+ * working outwards from L1 cache. This is done using Set/Way based cache
+ * maintenance instructions.
+ * The instruction cache can still be invalidated back to the point of
+ * unification in a single instruction.
+ *
+ */
+ENTRY(v7_flush_kern_cache_all)
+ ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
+ bl v7_flush_dcache_all
+ mov r0, #0
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate
+ ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
+ THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
+ mov pc, lr
+ENDPROC(v7_flush_kern_cache_all)
+
+/*
+ * v7_flush_cache_all()
+ *
+ * Flush all TLB entries in a particular address space
+ *
+ * - mm - mm_struct describing address space
+ */
+ENTRY(v7_flush_user_cache_all)
+ /*FALLTHROUGH*/
+
+/*
+ * v7_flush_cache_range(start, end, flags)
+ *
+ * Flush a range of TLB entries in the specified address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - flags - vm_area_struct flags describing address space
+ *
+ * It is assumed that:
+ * - we have a VIPT cache.
+ */
+ENTRY(v7_flush_user_cache_range)
+ mov pc, lr
+ENDPROC(v7_flush_user_cache_all)
+ENDPROC(v7_flush_user_cache_range)
+
+/*
+ * v7_coherent_kern_range(start,end)
+ *
+ * Ensure that the I and D caches are coherent within specified
+ * region. This is typically used when code has been written to
+ * a memory region, and will be executed.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ *
+ * It is assumed that:
+ * - the Icache does not read data from the write buffer
+ */
+ENTRY(v7_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * v7_coherent_user_range(start,end)
+ *
+ * Ensure that the I and D caches are coherent within specified
+ * region. This is typically used when code has been written to
+ * a memory region, and will be executed.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ *
+ * It is assumed that:
+ * - the Icache does not read data from the write buffer
+ */
+ENTRY(v7_coherent_user_range)
+ UNWIND(.fnstart )
+ dcache_line_size r2, r3
+ sub r3, r2, #1
+ bic r12, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+ ALT_SMP(W(dsb))
+ ALT_UP(W(nop))
+#endif
+1:
+ USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification
+ add r12, r12, r2
+ cmp r12, r1
+ blo 1b
+ dsb
+ icache_line_size r2, r3
+ sub r3, r2, #1
+ bic r12, r0, r3
+2:
+ USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line
+ add r12, r12, r2
+ cmp r12, r1
+ blo 2b
+3:
+ mov r0, #0
+ ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable
+ ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB
+ dsb
+ isb
+ mov pc, lr
+
+/*
+ * Fault handling for the cache operation above. If the virtual address in r0
+ * isn't mapped, just try the next page.
+ */
+9001:
+#ifdef CONFIG_ARM_ERRATA_775420
+ dsb
+#endif
+ mov r12, r12, lsr #12
+ mov r12, r12, lsl #12
+ add r12, r12, #4096
+ b 3b
+ UNWIND(.fnend )
+ENDPROC(v7_coherent_kern_range)
+ENDPROC(v7_coherent_user_range)
+
+/*
+ * v7_flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure that the data held in the page kaddr is written back
+ * to the page in question.
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(v7_flush_kern_dcache_area)
+ dcache_line_size r2, r3
+ add r1, r0, r1
+ sub r3, r2, #1
+ bic r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+ ALT_SMP(W(dsb))
+ ALT_UP(W(nop))
+#endif
+1:
+ mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line / unified line
+ add r0, r0, r2
+ cmp r0, r1
+ blo 1b
+ dsb
+ mov pc, lr
+ENDPROC(v7_flush_kern_dcache_area)
+
+/*
+ * v7_dma_inv_range(start,end)
+ *
+ * Invalidate the data cache within the specified region; we will
+ * be performing a DMA operation in this region and we want to
+ * purge old data in the cache.
+ *
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+v7_dma_inv_range:
+ dcache_line_size r2, r3
+ sub r3, r2, #1
+ tst r0, r3
+ bic r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+ ALT_SMP(W(dsb))
+ ALT_UP(W(nop))
+#endif
+ mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
+
+ tst r1, r3
+ bic r1, r1, r3
+ mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D / U line
+1:
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D / U line
+ add r0, r0, r2
+ cmp r0, r1
+ blo 1b
+ dsb
+ mov pc, lr
+ENDPROC(v7_dma_inv_range)
+
+/*
+ * v7_dma_clean_range(start,end)
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+v7_dma_clean_range:
+ dcache_line_size r2, r3
+ sub r3, r2, #1
+ bic r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+ ALT_SMP(W(dsb))
+ ALT_UP(W(nop))
+#endif
+1:
+ mcr p15, 0, r0, c7, c10, 1 @ clean D / U line
+ add r0, r0, r2
+ cmp r0, r1
+ blo 1b
+ dsb
+ mov pc, lr
+ENDPROC(v7_dma_clean_range)
+
+/*
+ * v7_dma_flush_range(start,end)
+ * - start - virtual start address of region
+ * - end - virtual end address of region
+ */
+ENTRY(v7_dma_flush_range)
+ dcache_line_size r2, r3
+ sub r3, r2, #1
+ bic r0, r0, r3
+#ifdef CONFIG_ARM_ERRATA_764369
+ ALT_SMP(W(dsb))
+ ALT_UP(W(nop))
+#endif
+1:
+ mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D / U line
+ add r0, r0, r2
+ cmp r0, r1
+ blo 1b
+ dsb
+ mov pc, lr
+ENDPROC(v7_dma_flush_range)
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v7_dma_map_area)
+ add r1, r1, r0
+ teq r2, #DMA_FROM_DEVICE
+ beq v7_dma_inv_range
+ b v7_dma_clean_range
+ENDPROC(v7_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(v7_dma_unmap_area)
+ add r1, r1, r0
+ teq r2, #DMA_TO_DEVICE
+ bne v7_dma_inv_range
+ mov pc, lr
+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
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c
new file mode 100644
index 00000000..5a320204
--- /dev/null
+++ b/arch/arm/mm/cache-xsc3l2.c
@@ -0,0 +1,220 @@
+/*
+ * arch/arm/mm/cache-xsc3l2.c - XScale3 L2 cache controller support
+ *
+ * Copyright (C) 2007 ARM Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <asm/system.h>
+#include <asm/cputype.h>
+#include <asm/cacheflush.h>
+
+#define CR_L2 (1 << 26)
+
+#define CACHE_LINE_SIZE 32
+#define CACHE_LINE_SHIFT 5
+#define CACHE_WAY_PER_SET 8
+
+#define CACHE_WAY_SIZE(l2ctype) (8192 << (((l2ctype) >> 8) & 0xf))
+#define CACHE_SET_SIZE(l2ctype) (CACHE_WAY_SIZE(l2ctype) >> CACHE_LINE_SHIFT)
+
+static inline int xsc3_l2_present(void)
+{
+ unsigned long l2ctype;
+
+ __asm__("mrc p15, 1, %0, c0, c0, 1" : "=r" (l2ctype));
+
+ return !!(l2ctype & 0xf8);
+}
+
+static inline void xsc3_l2_clean_mva(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c7, c11, 1" : : "r" (addr));
+}
+
+static inline void xsc3_l2_inv_mva(unsigned long addr)
+{
+ __asm__("mcr p15, 1, %0, c7, c7, 1" : : "r" (addr));
+}
+
+static inline void xsc3_l2_inv_all(void)
+{
+ unsigned long l2ctype, set_way;
+ int set, way;
+
+ __asm__("mrc p15, 1, %0, c0, c0, 1" : "=r" (l2ctype));
+
+ for (set = 0; set < CACHE_SET_SIZE(l2ctype); set++) {
+ for (way = 0; way < CACHE_WAY_PER_SET; way++) {
+ set_way = (way << 29) | (set << 5);
+ __asm__("mcr p15, 1, %0, c7, c11, 2" : : "r"(set_way));
+ }
+ }
+
+ dsb();
+}
+
+static inline void l2_unmap_va(unsigned long va)
+{
+#ifdef CONFIG_HIGHMEM
+ if (va != -1)
+ kunmap_atomic((void *)va);
+#endif
+}
+
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long va = prev_va & PAGE_MASK;
+ unsigned long pa_offset = pa << (32 - PAGE_SHIFT);
+ if (unlikely(pa_offset < (prev_va << (32 - PAGE_SHIFT)))) {
+ /*
+ * Switching to a new page. Because cache ops are
+ * using virtual addresses only, we must put a mapping
+ * in place for it.
+ */
+ l2_unmap_va(prev_va);
+ va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
+ }
+ return va + (pa_offset >> (32 - PAGE_SHIFT));
+#else
+ return __phys_to_virt(pa);
+#endif
+}
+
+static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
+{
+ unsigned long vaddr;
+
+ if (start == 0 && end == -1ul) {
+ xsc3_l2_inv_all();
+ return;
+ }
+
+ vaddr = -1; /* to force the first mapping */
+
+ /*
+ * Clean and invalidate partial first cache line.
+ */
+ if (start & (CACHE_LINE_SIZE - 1)) {
+ vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
+ start = (start | (CACHE_LINE_SIZE - 1)) + 1;
+ }
+
+ /*
+ * Invalidate all full cache lines between 'start' and 'end'.
+ */
+ while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
+ vaddr = l2_map_va(start, vaddr);
+ xsc3_l2_inv_mva(vaddr);
+ start += CACHE_LINE_SIZE;
+ }
+
+ /*
+ * Clean and invalidate partial last cache line.
+ */
+ if (start < end) {
+ vaddr = l2_map_va(start, vaddr);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
+ }
+
+ l2_unmap_va(vaddr);
+
+ dsb();
+}
+
+static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
+{
+ unsigned long vaddr;
+
+ vaddr = -1; /* to force the first mapping */
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ vaddr = l2_map_va(start, vaddr);
+ xsc3_l2_clean_mva(vaddr);
+ start += CACHE_LINE_SIZE;
+ }
+
+ l2_unmap_va(vaddr);
+
+ dsb();
+}
+
+/*
+ * optimize L2 flush all operation by set/way format
+ */
+static inline void xsc3_l2_flush_all(void)
+{
+ unsigned long l2ctype, set_way;
+ int set, way;
+
+ __asm__("mrc p15, 1, %0, c0, c0, 1" : "=r" (l2ctype));
+
+ for (set = 0; set < CACHE_SET_SIZE(l2ctype); set++) {
+ for (way = 0; way < CACHE_WAY_PER_SET; way++) {
+ set_way = (way << 29) | (set << 5);
+ __asm__("mcr p15, 1, %0, c7, c15, 2" : : "r"(set_way));
+ }
+ }
+
+ dsb();
+}
+
+static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
+{
+ unsigned long vaddr;
+
+ if (start == 0 && end == -1ul) {
+ xsc3_l2_flush_all();
+ return;
+ }
+
+ vaddr = -1; /* to force the first mapping */
+
+ start &= ~(CACHE_LINE_SIZE - 1);
+ while (start < end) {
+ vaddr = l2_map_va(start, vaddr);
+ xsc3_l2_clean_mva(vaddr);
+ xsc3_l2_inv_mva(vaddr);
+ start += CACHE_LINE_SIZE;
+ }
+
+ l2_unmap_va(vaddr);
+
+ dsb();
+}
+
+static int __init xsc3_l2_init(void)
+{
+ if (!cpu_is_xsc3() || !xsc3_l2_present())
+ return 0;
+
+ if (get_cr() & CR_L2) {
+ pr_info("XScale3 L2 cache enabled.\n");
+ xsc3_l2_inv_all();
+
+ outer_cache.inv_range = xsc3_l2_inv_range;
+ outer_cache.clean_range = xsc3_l2_clean_range;
+ outer_cache.flush_range = xsc3_l2_flush_range;
+ }
+
+ return 0;
+}
+core_initcall(xsc3_l2_init);
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
new file mode 100644
index 00000000..b0ee9ba3
--- /dev/null
+++ b/arch/arm/mm/context.c
@@ -0,0 +1,157 @@
+/*
+ * linux/arch/arm/mm/context.c
+ *
+ * Copyright (C) 2002-2003 Deep Blue Solutions 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/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
+
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+
+static DEFINE_SPINLOCK(cpu_asid_lock);
+unsigned int cpu_last_asid = ASID_FIRST_VERSION;
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(struct mm_struct *, current_mm);
+#endif
+
+/*
+ * We fork()ed a process, and we need a new context for the child
+ * to run in. We reserve version 0 for initial tasks so we will
+ * always allocate an ASID. The ASID 0 is reserved for the TTBR
+ * register changing sequence.
+ */
+void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ mm->context.id = 0;
+ spin_lock_init(&mm->context.id_lock);
+}
+
+static void flush_context(void)
+{
+ /* set the reserved ASID before flushing the TLB */
+ asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (0));
+ isb();
+ local_flush_tlb_all();
+ if (icache_is_vivt_asid_tagged()) {
+ __flush_icache_all();
+ dsb();
+ }
+}
+
+#ifdef CONFIG_SMP
+
+static void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+ unsigned long flags;
+
+ /*
+ * Locking needed for multi-threaded applications where the
+ * same mm->context.id could be set from different CPUs during
+ * the broadcast. This function is also called via IPI so the
+ * mm->context.id_lock has to be IRQ-safe.
+ */
+ spin_lock_irqsave(&mm->context.id_lock, flags);
+ if (likely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) {
+ /*
+ * Old version of ASID found. Set the new one and
+ * reset mm_cpumask(mm).
+ */
+ mm->context.id = asid;
+ cpumask_clear(mm_cpumask(mm));
+ }
+ spin_unlock_irqrestore(&mm->context.id_lock, flags);
+
+ /*
+ * Set the mm_cpumask(mm) bit for the current CPU.
+ */
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+}
+
+/*
+ * Reset the ASID on the current CPU. This function call is broadcast
+ * from the CPU handling the ASID rollover and holding cpu_asid_lock.
+ */
+static void reset_context(void *info)
+{
+ unsigned int asid;
+ unsigned int cpu = smp_processor_id();
+ struct mm_struct *mm = per_cpu(current_mm, cpu);
+
+ /*
+ * Check if a current_mm was set on this CPU as it might still
+ * be in the early booting stages and using the reserved ASID.
+ */
+ if (!mm)
+ return;
+
+ smp_rmb();
+ asid = cpu_last_asid + cpu + 1;
+
+ flush_context();
+ set_mm_context(mm, asid);
+
+ /* set the new ASID */
+ asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
+ isb();
+}
+
+#else
+
+static inline void set_mm_context(struct mm_struct *mm, unsigned int asid)
+{
+ mm->context.id = asid;
+ cpumask_copy(mm_cpumask(mm), cpumask_of(smp_processor_id()));
+}
+
+#endif
+
+void __new_context(struct mm_struct *mm)
+{
+ unsigned int asid;
+
+ spin_lock(&cpu_asid_lock);
+#ifdef CONFIG_SMP
+ /*
+ * Check the ASID again, in case the change was broadcast from
+ * another CPU before we acquired the lock.
+ */
+ if (unlikely(((mm->context.id ^ cpu_last_asid) >> ASID_BITS) == 0)) {
+ cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm));
+ spin_unlock(&cpu_asid_lock);
+ return;
+ }
+#endif
+ /*
+ * At this point, it is guaranteed that the current mm (with
+ * an old ASID) isn't active on any other CPU since the ASIDs
+ * are changed simultaneously via IPI.
+ */
+ asid = ++cpu_last_asid;
+ if (asid == 0)
+ asid = cpu_last_asid = ASID_FIRST_VERSION;
+
+ /*
+ * If we've used up all our ASIDs, we need
+ * to start a new version and flush the TLB.
+ */
+ if (unlikely((asid & ~ASID_MASK) == 0)) {
+ asid = cpu_last_asid + smp_processor_id() + 1;
+ flush_context();
+#ifdef CONFIG_SMP
+ smp_wmb();
+ smp_call_function(reset_context, NULL, 1);
+#endif
+ cpu_last_asid += NR_CPUS;
+ }
+
+ set_mm_context(mm, asid);
+ spin_unlock(&cpu_asid_lock);
+}
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
new file mode 100644
index 00000000..d2852e16
--- /dev/null
+++ b/arch/arm/mm/copypage-fa.c
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/lib/copypage-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on copypage-v4wb.S:
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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/highmem.h>
+
+/*
+ * Faraday optimised copy_user_page
+ */
+static void __naked
+fa_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4, lr} @ 2\n\
+ mov r2, %0 @ 1\n\
+1: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ stmia r0, {r3, r4, ip, lr} @ 4\n\
+ mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add r0, r0, #16 @ 1\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ stmia r0, {r3, r4, ip, lr} @ 4\n\
+ mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add r0, r0, #16 @ 1\n\
+ subs r2, r2, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "I" (PAGE_SIZE / 32));
+}
+
+void fa_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ fa_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * Faraday optimised clear_user_page
+ *
+ * Same story as above.
+ */
+void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: stmia %0, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add %0, %0, #16 @ 1\n\
+ stmia %0, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
+ add %0, %0, #16 @ 1\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 32)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns fa_user_fns __initdata = {
+ .cpu_clear_user_highpage = fa_clear_user_highpage,
+ .cpu_copy_user_highpage = fa_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-feroceon.c b/arch/arm/mm/copypage-feroceon.c
new file mode 100644
index 00000000..ac163de7
--- /dev/null
+++ b/arch/arm/mm/copypage-feroceon.c
@@ -0,0 +1,112 @@
+/*
+ * linux/arch/arm/mm/copypage-feroceon.S
+ *
+ * Copyright (C) 2008 Marvell Semiconductors
+ *
+ * This program is free software; you can 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 handles copy_user_highpage and clear_user_page on Feroceon
+ * more optimally than the generic implementations.
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+static void __naked
+feroceon_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4-r9, lr} \n\
+ mov ip, %2 \n\
+1: mov lr, r1 \n\
+ ldmia r1!, {r2 - r9} \n\
+ pld [lr, #32] \n\
+ pld [lr, #64] \n\
+ pld [lr, #96] \n\
+ pld [lr, #128] \n\
+ pld [lr, #160] \n\
+ pld [lr, #192] \n\
+ pld [lr, #224] \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ ldmia r1!, {r2 - r9} \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ stmia r0, {r2 - r9} \n\
+ subs ip, ip, #(32 * 8) \n\
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D line\n\
+ add r0, r0, #32 \n\
+ bne 1b \n\
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB\n\
+ ldmfd sp!, {r4-r9, pc}"
+ :
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE));
+}
+
+void feroceon_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ feroceon_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+void feroceon_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile ("\
+ mov r1, %2 \n\
+ mov r2, #0 \n\
+ mov r3, #0 \n\
+ mov r4, #0 \n\
+ mov r5, #0 \n\
+ mov r6, #0 \n\
+ mov r7, #0 \n\
+ mov ip, #0 \n\
+ mov lr, #0 \n\
+1: stmia %0, {r2-r7, ip, lr} \n\
+ subs r1, r1, #1 \n\
+ mcr p15, 0, %0, c7, c14, 1 @ clean and invalidate D line\n\
+ add %0, %0, #32 \n\
+ bne 1b \n\
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 32)
+ : "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns feroceon_user_fns __initdata = {
+ .cpu_clear_user_highpage = feroceon_clear_user_highpage,
+ .cpu_copy_user_highpage = feroceon_copy_user_highpage,
+};
+
diff --git a/arch/arm/mm/copypage-v3.c b/arch/arm/mm/copypage-v3.c
new file mode 100644
index 00000000..f72303e1
--- /dev/null
+++ b/arch/arm/mm/copypage-v3.c
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/arm/mm/copypage-v3.c
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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/highmem.h>
+
+/*
+ * ARMv3 optimised copy_user_highpage
+ *
+ * FIXME: do we need to handle cache stuff...
+ */
+static void __naked
+v3_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\n\
+ stmfd sp!, {r4, lr} @ 2\n\
+ mov r2, %2 @ 1\n\
+ ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\
+1: stmia %1!, {r3, r4, ip, lr} @ 4\n\
+ ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\
+ stmia %1!, {r3, r4, ip, lr} @ 4\n\
+ ldmia %0!, {r3, r4, ip, lr} @ 4+1\n\
+ stmia %1!, {r3, r4, ip, lr} @ 4\n\
+ ldmia %0!, {r3, r4, ip, lr} @ 4\n\
+ subs r2, r2, #1 @ 1\n\
+ stmia %1!, {r3, r4, ip, lr} @ 4\n\
+ ldmneia %0!, {r3, r4, ip, lr} @ 4\n\
+ bne 1b @ 1\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "r" (kfrom), "r" (kto), "I" (PAGE_SIZE / 64));
+}
+
+void v3_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ v3_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * ARMv3 optimised clear_user_page
+ *
+ * FIXME: do we need to handle cache stuff...
+ */
+void v3_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\n\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 64)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns v3_user_fns __initdata = {
+ .cpu_clear_user_highpage = v3_clear_user_highpage,
+ .cpu_copy_user_highpage = v3_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
new file mode 100644
index 00000000..b8061519
--- /dev/null
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -0,0 +1,120 @@
+/*
+ * linux/arch/arm/lib/copypage-armv4mc.S
+ *
+ * Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can 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 handles the mini data cache, as found on SA11x0 and XScale
+ * processors. When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache. This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+#include "mm.h"
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+ L_PTE_MT_MINICACHE)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * ARMv4 mini-dcache optimised copy_user_highpage
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address. Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue. The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ *
+ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
+ * instruction. If your processor does not supply this, you have to write your
+ * own copy_user_highpage that does the right thing.
+ */
+static void __naked
+mc_copy_user_page(void *from, void *to)
+{
+ asm volatile(
+ "stmfd sp!, {r4, lr} @ 2\n\
+ mov r4, %2 @ 1\n\
+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\
+1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %1!, {r2, r3, ip, lr} @ 4\n\
+ ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\
+ stmia %1!, {r2, r3, ip, lr} @ 4\n\
+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %1!, {r2, r3, ip, lr} @ 4\n\
+ ldmia %0!, {r2, r3, ip, lr} @ 4\n\
+ subs r4, r4, #1 @ 1\n\
+ stmia %1!, {r2, r3, ip, lr} @ 4\n\
+ ldmneia %0!, {r2, r3, ip, lr} @ 4\n\
+ bne 1b @ 1\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
+}
+
+void v4_mc_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto = kmap_atomic(to, KM_USER1);
+
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
+ __flush_dcache_page(page_mapping(from), from);
+
+ spin_lock(&minicache_lock);
+
+ set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
+ flush_tlb_kernel_page(0xffff8000);
+
+ mc_copy_user_page((void *)0xffff8000, kto);
+
+ spin_unlock(&minicache_lock);
+
+ kunmap_atomic(kto, KM_USER1);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ */
+void v4_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 64)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns v4_mc_user_fns __initdata = {
+ .cpu_clear_user_highpage = v4_mc_clear_user_highpage,
+ .cpu_copy_user_highpage = v4_mc_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-v4wb.c b/arch/arm/mm/copypage-v4wb.c
new file mode 100644
index 00000000..cb589cbb
--- /dev/null
+++ b/arch/arm/mm/copypage-v4wb.c
@@ -0,0 +1,95 @@
+/*
+ * linux/arch/arm/mm/copypage-v4wb.c
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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/highmem.h>
+
+/*
+ * ARMv4 optimised copy_user_highpage
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address. Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue. The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ *
+ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
+ * instruction. If your processor does not supply this, you have to write your
+ * own copy_user_highpage that does the right thing.
+ */
+static void __naked
+v4wb_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4, lr} @ 2\n\
+ mov r2, %2 @ 1\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ subs r2, r2, #1 @ 1\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
+}
+
+void v4wb_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ v4wb_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ *
+ * Same story as above.
+ */
+void v4wb_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ mcr p15, 0, %0, c7, c6, 1 @ 1 invalidate D line\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 64)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns v4wb_user_fns __initdata = {
+ .cpu_clear_user_highpage = v4wb_clear_user_highpage,
+ .cpu_copy_user_highpage = v4wb_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-v4wt.c b/arch/arm/mm/copypage-v4wt.c
new file mode 100644
index 00000000..30c7d048
--- /dev/null
+++ b/arch/arm/mm/copypage-v4wt.c
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/mm/copypage-v4wt.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * This program is free software; you can 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 is for CPUs with a writethrough cache and 'flush ID cache' is
+ * the only supported cache operation.
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+/*
+ * ARMv4 optimised copy_user_highpage
+ *
+ * Since we have writethrough caches, we don't have to worry about
+ * dirty data in the cache. However, we do have to ensure that
+ * subsequent reads are up to date.
+ */
+static void __naked
+v4wt_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4, lr} @ 2\n\
+ mov r2, %2 @ 1\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+1: stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmia r1!, {r3, r4, ip, lr} @ 4\n\
+ subs r2, r2, #1 @ 1\n\
+ stmia r0!, {r3, r4, ip, lr} @ 4\n\
+ ldmneia r1!, {r3, r4, ip, lr} @ 4\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r2, c7, c7, 0 @ flush ID cache\n\
+ ldmfd sp!, {r4, pc} @ 3"
+ :
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64));
+}
+
+void v4wt_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ v4wt_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ *
+ * Same story as above.
+ */
+void v4wt_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile("\
+ mov r1, %2 @ 1\n\
+ mov r2, #0 @ 1\n\
+ mov r3, #0 @ 1\n\
+ mov ip, #0 @ 1\n\
+ mov lr, #0 @ 1\n\
+1: stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ stmia %0!, {r2, r3, ip, lr} @ 4\n\
+ subs r1, r1, #1 @ 1\n\
+ bne 1b @ 1\n\
+ mcr p15, 0, r2, c7, c7, 0 @ flush ID cache"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 64)
+ : "r1", "r2", "r3", "ip", "lr");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns v4wt_user_fns __initdata = {
+ .cpu_clear_user_highpage = v4wt_clear_user_highpage,
+ .cpu_copy_user_highpage = v4wt_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
new file mode 100644
index 00000000..bdba6c65
--- /dev/null
+++ b/arch/arm/mm/copypage-v6.c
@@ -0,0 +1,149 @@
+/*
+ * linux/arch/arm/mm/copypage-v6.c
+ *
+ * Copyright (C) 2002 Deep Blue Solutions 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/init.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/shmparam.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+
+#include "mm.h"
+
+#if SHMLBA > 16384
+#error FIX ME
+#endif
+
+#define from_address (0xffff8000)
+#define to_address (0xffffc000)
+
+static DEFINE_SPINLOCK(v6_lock);
+
+/*
+ * Copy the user page. No aliasing to deal with so we can just
+ * attack the kernel's existing mapping of these pages.
+ */
+static void v6_copy_user_highpage_nonaliasing(struct page *to,
+ struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kfrom = kmap_atomic(from, KM_USER0);
+ kto = kmap_atomic(to, KM_USER1);
+ copy_page(kto, kfrom);
+ __cpuc_flush_dcache_area(kto, PAGE_SIZE);
+ kunmap_atomic(kto, KM_USER1);
+ kunmap_atomic(kfrom, KM_USER0);
+}
+
+/*
+ * Clear the user page. No aliasing to deal with so we can just
+ * attack the kernel's existing mapping of this page.
+ */
+static void v6_clear_user_highpage_nonaliasing(struct page *page, unsigned long vaddr)
+{
+ void *kaddr = kmap_atomic(page, KM_USER0);
+ clear_page(kaddr);
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+/*
+ * Discard data in the kernel mapping for the new page.
+ * FIXME: needs this MCRR to be supported.
+ */
+static void discard_old_kernel_data(void *kto)
+{
+ __asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06"
+ :
+ : "r" (kto),
+ "r" ((unsigned long)kto + PAGE_SIZE - L1_CACHE_BYTES)
+ : "cc");
+}
+
+/*
+ * Copy the page, taking account of the cache colour.
+ */
+static void v6_copy_user_highpage_aliasing(struct page *to,
+ struct page *from, unsigned long vaddr, struct vm_area_struct *vma)
+{
+ unsigned int offset = CACHE_COLOUR(vaddr);
+ unsigned long kfrom, kto;
+
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
+ __flush_dcache_page(page_mapping(from), from);
+
+ /* FIXME: not highmem safe */
+ discard_old_kernel_data(page_address(to));
+
+ /*
+ * Now copy the page using the same cache colour as the
+ * pages ultimate destination.
+ */
+ spin_lock(&v6_lock);
+
+ set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0);
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0);
+
+ kfrom = from_address + (offset << PAGE_SHIFT);
+ kto = to_address + (offset << PAGE_SHIFT);
+
+ flush_tlb_kernel_page(kfrom);
+ flush_tlb_kernel_page(kto);
+
+ copy_page((void *)kto, (void *)kfrom);
+
+ spin_unlock(&v6_lock);
+}
+
+/*
+ * Clear the user page. We need to deal with the aliasing issues,
+ * so remap the kernel page into the same cache colour as the user
+ * page.
+ */
+static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr)
+{
+ unsigned int offset = CACHE_COLOUR(vaddr);
+ unsigned long to = to_address + (offset << PAGE_SHIFT);
+
+ /* FIXME: not highmem safe */
+ discard_old_kernel_data(page_address(page));
+
+ /*
+ * Now clear the page using the same cache colour as
+ * the pages ultimate destination.
+ */
+ spin_lock(&v6_lock);
+
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0);
+ flush_tlb_kernel_page(to);
+ clear_page((void *)to);
+
+ spin_unlock(&v6_lock);
+}
+
+struct cpu_user_fns v6_user_fns __initdata = {
+ .cpu_clear_user_highpage = v6_clear_user_highpage_nonaliasing,
+ .cpu_copy_user_highpage = v6_copy_user_highpage_nonaliasing,
+};
+
+static int __init v6_userpage_init(void)
+{
+ if (cache_is_vipt_aliasing()) {
+ cpu_user.cpu_clear_user_highpage = v6_clear_user_highpage_aliasing;
+ cpu_user.cpu_copy_user_highpage = v6_copy_user_highpage_aliasing;
+ }
+
+ return 0;
+}
+
+core_initcall(v6_userpage_init);
diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c
new file mode 100644
index 00000000..f9cde070
--- /dev/null
+++ b/arch/arm/mm/copypage-xsc3.c
@@ -0,0 +1,114 @@
+/*
+ * linux/arch/arm/mm/copypage-xsc3.S
+ *
+ * Copyright (C) 2004 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Adapted for 3rd gen XScale core, no more mini-dcache
+ * Author: Matt Gilbert (matthew.m.gilbert@intel.com)
+ */
+#include <linux/init.h>
+#include <linux/highmem.h>
+
+/*
+ * General note:
+ * We don't really want write-allocate cache behaviour for these functions
+ * since that will just eat through 8K of the cache.
+ */
+
+/*
+ * XSC3 optimised copy_user_highpage
+ * r0 = destination
+ * r1 = source
+ *
+ * The source page may have some clean entries in the cache already, but we
+ * can safely ignore them - break_cow() will flush them out of the cache
+ * if we eventually end up using our copied page.
+ *
+ */
+static void __naked
+xsc3_mc_copy_user_page(void *kto, const void *kfrom)
+{
+ asm("\
+ stmfd sp!, {r4, r5, lr} \n\
+ mov lr, %2 \n\
+ \n\
+ pld [r1, #0] \n\
+ pld [r1, #32] \n\
+1: pld [r1, #64] \n\
+ pld [r1, #96] \n\
+ \n\
+2: ldrd r2, [r1], #8 \n\
+ mov ip, r0 \n\
+ ldrd r4, [r1], #8 \n\
+ mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
+ strd r2, [r0], #8 \n\
+ ldrd r2, [r1], #8 \n\
+ strd r4, [r0], #8 \n\
+ ldrd r4, [r1], #8 \n\
+ strd r2, [r0], #8 \n\
+ strd r4, [r0], #8 \n\
+ ldrd r2, [r1], #8 \n\
+ mov ip, r0 \n\
+ ldrd r4, [r1], #8 \n\
+ mcr p15, 0, ip, c7, c6, 1 @ invalidate\n\
+ strd r2, [r0], #8 \n\
+ ldrd r2, [r1], #8 \n\
+ subs lr, lr, #1 \n\
+ strd r4, [r0], #8 \n\
+ ldrd r4, [r1], #8 \n\
+ strd r2, [r0], #8 \n\
+ strd r4, [r0], #8 \n\
+ bgt 1b \n\
+ beq 2b \n\
+ \n\
+ ldmfd sp!, {r4, r5, pc}"
+ :
+ : "r" (kto), "r" (kfrom), "I" (PAGE_SIZE / 64 - 1));
+}
+
+void xsc3_mc_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto, *kfrom;
+
+ kto = kmap_atomic(to, KM_USER0);
+ kfrom = kmap_atomic(from, KM_USER1);
+ flush_cache_page(vma, vaddr, page_to_pfn(from));
+ xsc3_mc_copy_user_page(kto, kfrom);
+ kunmap_atomic(kfrom, KM_USER1);
+ kunmap_atomic(kto, KM_USER0);
+}
+
+/*
+ * XScale optimised clear_user_page
+ * r0 = destination
+ * r1 = virtual user address of ultimate destination page
+ */
+void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile ("\
+ mov r1, %2 \n\
+ mov r2, #0 \n\
+ mov r3, #0 \n\
+1: mcr p15, 0, %0, c7, c6, 1 @ invalidate line\n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ subs r1, r1, #1 \n\
+ bne 1b"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 32)
+ : "r1", "r2", "r3");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns xsc3_mc_user_fns __initdata = {
+ .cpu_clear_user_highpage = xsc3_mc_clear_user_highpage,
+ .cpu_copy_user_highpage = xsc3_mc_copy_user_highpage,
+};
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
new file mode 100644
index 00000000..649bbcd3
--- /dev/null
+++ b/arch/arm/mm/copypage-xscale.c
@@ -0,0 +1,142 @@
+/*
+ * linux/arch/arm/lib/copypage-xscale.S
+ *
+ * Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can 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 handles the mini data cache, as found on SA11x0 and XScale
+ * processors. When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache. This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+#include "mm.h"
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define COPYPAGE_MINICACHE 0xffff8000
+
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+ L_PTE_MT_MINICACHE)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * XScale mini-dcache optimised copy_user_highpage
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address. Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue. The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ */
+static void __naked
+mc_copy_user_page(void *from, void *to)
+{
+ /*
+ * Strangely enough, best performance is achieved
+ * when prefetching destination as well. (NP)
+ */
+ asm volatile(
+ "stmfd sp!, {r4, r5, lr} \n\
+ mov lr, %2 \n\
+ pld [r0, #0] \n\
+ pld [r0, #32] \n\
+ pld [r1, #0] \n\
+ pld [r1, #32] \n\
+1: pld [r0, #64] \n\
+ pld [r0, #96] \n\
+ pld [r1, #64] \n\
+ pld [r1, #96] \n\
+2: ldrd r2, [r0], #8 \n\
+ ldrd r4, [r0], #8 \n\
+ mov ip, r1 \n\
+ strd r2, [r1], #8 \n\
+ ldrd r2, [r0], #8 \n\
+ strd r4, [r1], #8 \n\
+ ldrd r4, [r0], #8 \n\
+ strd r2, [r1], #8 \n\
+ strd r4, [r1], #8 \n\
+ mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
+ ldrd r2, [r0], #8 \n\
+ mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
+ ldrd r4, [r0], #8 \n\
+ mov ip, r1 \n\
+ strd r2, [r1], #8 \n\
+ ldrd r2, [r0], #8 \n\
+ strd r4, [r1], #8 \n\
+ ldrd r4, [r0], #8 \n\
+ strd r2, [r1], #8 \n\
+ strd r4, [r1], #8 \n\
+ mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
+ subs lr, lr, #1 \n\
+ mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
+ bgt 1b \n\
+ beq 2b \n\
+ ldmfd sp!, {r4, r5, pc} "
+ :
+ : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1));
+}
+
+void xscale_mc_copy_user_highpage(struct page *to, struct page *from,
+ unsigned long vaddr, struct vm_area_struct *vma)
+{
+ void *kto = kmap_atomic(to, KM_USER1);
+
+ if (!test_and_set_bit(PG_dcache_clean, &from->flags))
+ __flush_dcache_page(page_mapping(from), from);
+
+ spin_lock(&minicache_lock);
+
+ set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0);
+ flush_tlb_kernel_page(COPYPAGE_MINICACHE);
+
+ mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
+
+ spin_unlock(&minicache_lock);
+
+ kunmap_atomic(kto, KM_USER1);
+}
+
+/*
+ * XScale optimised clear_user_page
+ */
+void
+xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
+{
+ void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
+ asm volatile(
+ "mov r1, %2 \n\
+ mov r2, #0 \n\
+ mov r3, #0 \n\
+1: mov ip, %0 \n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ strd r2, [%0], #8 \n\
+ mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\
+ subs r1, r1, #1 \n\
+ mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\
+ bne 1b"
+ : "=r" (ptr)
+ : "0" (kaddr), "I" (PAGE_SIZE / 32)
+ : "r1", "r2", "r3", "ip");
+ kunmap_atomic(kaddr, KM_USER0);
+}
+
+struct cpu_user_fns xscale_mc_user_fns __initdata = {
+ .cpu_clear_user_highpage = xscale_mc_clear_user_highpage,
+ .cpu_copy_user_highpage = xscale_mc_copy_user_highpage,
+};
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
new file mode 100644
index 00000000..feb83cb5
--- /dev/null
+++ b/arch/arm/mm/dma-mapping.c
@@ -0,0 +1,711 @@
+/*
+ * linux/arch/arm/mm/dma-mapping.c
+ *
+ * Copyright (C) 2000-2004 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DMA uncached mapping support.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/gfp.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/highmem.h>
+
+#include <asm/memory.h>
+#include <asm/highmem.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/sizes.h>
+
+static u64 get_coherent_dma_mask(struct device *dev)
+{
+ u64 mask = ISA_DMA_THRESHOLD;
+
+ if (dev) {
+ mask = dev->coherent_dma_mask;
+
+ /*
+ * Sanity check the DMA mask - it must be non-zero, and
+ * must be able to be satisfied by a DMA allocation.
+ */
+ if (mask == 0) {
+ dev_warn(dev, "coherent DMA mask is unset\n");
+ return 0;
+ }
+
+ if ((~mask) & ISA_DMA_THRESHOLD) {
+ dev_warn(dev, "coherent DMA mask %#llx is smaller "
+ "than system GFP_DMA mask %#llx\n",
+ mask, (unsigned long long)ISA_DMA_THRESHOLD);
+ return 0;
+ }
+ }
+
+ return mask;
+}
+
+/*
+ * Allocate a DMA buffer for 'dev' of size 'size' using the
+ * specified gfp mask. Note that 'size' must be page aligned.
+ */
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+{
+ unsigned long order = get_order(size);
+ struct page *page, *p, *e;
+ void *ptr;
+ u64 mask = get_coherent_dma_mask(dev);
+
+#ifdef CONFIG_DMA_API_DEBUG
+ u64 limit = (mask + 1) & ~mask;
+ if (limit && size >= limit) {
+ dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
+ size, mask);
+ return NULL;
+ }
+#endif
+
+ if (!mask)
+ return NULL;
+
+ if (mask < 0xffffffffULL)
+ gfp |= GFP_DMA;
+
+ page = alloc_pages(gfp, order);
+ if (!page)
+ return NULL;
+
+ /*
+ * Now split the huge page and free the excess pages
+ */
+ split_page(page, order);
+ for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
+ __free_page(p);
+
+ /*
+ * Ensure that the allocated pages are zeroed, and that any data
+ * lurking in the kernel direct-mapped region is invalidated.
+ */
+ ptr = page_address(page);
+ memset(ptr, 0, size);
+ dmac_flush_range(ptr, ptr + size);
+ outer_flush_range(__pa(ptr), __pa(ptr) + size);
+
+ return page;
+}
+
+/*
+ * Free a DMA buffer. 'size' must be page aligned.
+ */
+static void __dma_free_buffer(struct page *page, size_t size)
+{
+ struct page *e = page + (size >> PAGE_SHIFT);
+
+ while (page < e) {
+ __free_page(page);
+ page++;
+ }
+}
+
+#ifdef CONFIG_MMU
+/* Sanity check size */
+#if (CONSISTENT_DMA_SIZE % SZ_2M)
+#error "CONSISTENT_DMA_SIZE must be multiple of 2MiB"
+#endif
+
+#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT)
+#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
+#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
+
+/*
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+ */
+static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
+
+#include "vmregion.h"
+
+static struct arm_vmregion_head consistent_head = {
+ .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
+ .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
+ .vm_start = CONSISTENT_BASE,
+ .vm_end = CONSISTENT_END,
+};
+
+#ifdef CONFIG_HUGETLB_PAGE
+#error ARM Coherent DMA allocator does not (yet) support huge TLB
+#endif
+
+/*
+ * Initialise the consistent memory allocation.
+ */
+static int __init consistent_init(void)
+{
+ int ret = 0;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ int i = 0;
+ u32 base = CONSISTENT_BASE;
+
+ do {
+ pgd = pgd_offset(&init_mm, base);
+
+ pud = pud_alloc(&init_mm, pgd, base);
+ if (!pud) {
+ printk(KERN_ERR "%s: no pud tables\n", __func__);
+ ret = -ENOMEM;
+ break;
+ }
+
+ pmd = pmd_alloc(&init_mm, pud, base);
+ if (!pmd) {
+ printk(KERN_ERR "%s: no pmd tables\n", __func__);
+ ret = -ENOMEM;
+ break;
+ }
+ WARN_ON(!pmd_none(*pmd));
+
+ pte = pte_alloc_kernel(pmd, base);
+ if (!pte) {
+ printk(KERN_ERR "%s: no pte tables\n", __func__);
+ ret = -ENOMEM;
+ break;
+ }
+
+ consistent_pte[i++] = pte;
+ base += (1 << PGDIR_SHIFT);
+ } while (base < CONSISTENT_END);
+
+ return ret;
+}
+
+core_initcall(consistent_init);
+
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
+{
+ struct arm_vmregion *c;
+ size_t align;
+ int bit;
+
+ if (!consistent_pte[0]) {
+ printk(KERN_ERR "%s: not initialised\n", __func__);
+ dump_stack();
+ return NULL;
+ }
+
+ /*
+ * Align the virtual region allocation - maximum alignment is
+ * a section size, minimum is a page size. This helps reduce
+ * fragmentation of the DMA space, and also prevents allocations
+ * smaller than a section from crossing a section boundary.
+ */
+ bit = fls(size - 1);
+ if (bit > SECTION_SHIFT)
+ bit = SECTION_SHIFT;
+ align = 1 << bit;
+
+ /*
+ * Allocate a virtual address in the consistent mapping region.
+ */
+ c = arm_vmregion_alloc(&consistent_head, align, size,
+ gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
+ if (c) {
+ pte_t *pte;
+ int idx = CONSISTENT_PTE_INDEX(c->vm_start);
+ u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+
+ pte = consistent_pte[idx] + off;
+ c->vm_pages = page;
+
+ do {
+ BUG_ON(!pte_none(*pte));
+
+ set_pte_ext(pte, mk_pte(page, prot), 0);
+ page++;
+ pte++;
+ off++;
+ if (off >= PTRS_PER_PTE) {
+ off = 0;
+ pte = consistent_pte[++idx];
+ }
+ } while (size -= PAGE_SIZE);
+
+ dsb();
+
+ return (void *)c->vm_start;
+ }
+ return NULL;
+}
+
+static void __dma_free_remap(void *cpu_addr, size_t size)
+{
+ struct arm_vmregion *c;
+ unsigned long addr;
+ pte_t *ptep;
+ int idx;
+ u32 off;
+
+ c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
+ if (!c) {
+ printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+ __func__, cpu_addr);
+ dump_stack();
+ return;
+ }
+
+ if ((c->vm_end - c->vm_start) != size) {
+ printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+ __func__, c->vm_end - c->vm_start, size);
+ dump_stack();
+ size = c->vm_end - c->vm_start;
+ }
+
+ idx = CONSISTENT_PTE_INDEX(c->vm_start);
+ off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+ ptep = consistent_pte[idx] + off;
+ addr = c->vm_start;
+ do {
+ pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
+
+ ptep++;
+ addr += PAGE_SIZE;
+ off++;
+ if (off >= PTRS_PER_PTE) {
+ off = 0;
+ ptep = consistent_pte[++idx];
+ }
+
+ if (pte_none(pte) || !pte_present(pte))
+ printk(KERN_CRIT "%s: bad page in kernel page table\n",
+ __func__);
+ } while (size -= PAGE_SIZE);
+
+ flush_tlb_kernel_range(c->vm_start, c->vm_end);
+
+ arm_vmregion_free(&consistent_head, c);
+}
+
+#else /* !CONFIG_MMU */
+
+#define __dma_alloc_remap(page, size, gfp, prot) page_address(page)
+#define __dma_free_remap(addr, size) do { } while (0)
+
+#endif /* CONFIG_MMU */
+
+static void *
+__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+ pgprot_t prot)
+{
+ struct page *page;
+ void *addr;
+
+ *handle = ~0;
+ size = PAGE_ALIGN(size);
+
+ page = __dma_alloc_buffer(dev, size, gfp);
+ if (!page)
+ return NULL;
+
+ if (!arch_is_coherent())
+ addr = __dma_alloc_remap(page, size, gfp, prot);
+ else
+ addr = page_address(page);
+
+ if (addr)
+ *handle = pfn_to_dma(dev, page_to_pfn(page));
+ else
+ __dma_free_buffer(page, size);
+
+ return addr;
+}
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+dma_alloc_noncached(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ void *memory;
+
+ if (dma_alloc_from_coherent(dev, size, handle, &memory))
+ return memory;
+
+ return __dma_alloc(dev, size, handle, gfp,
+ pgprot_noncached(pgprot_kernel));
+}
+EXPORT_SYMBOL(dma_alloc_noncached);
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ void *memory;
+
+ if (dma_alloc_from_coherent(dev, size, handle, &memory))
+ return memory;
+
+ return __dma_alloc(dev, size, handle, gfp,
+ pgprot_dmacoherent(pgprot_kernel));
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+/*
+ * Allocate a writecombining region, in much the same way as
+ * dma_alloc_coherent above.
+ */
+void *
+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ return __dma_alloc(dev, size, handle, gfp,
+ pgprot_writecombine(pgprot_kernel));
+}
+EXPORT_SYMBOL(dma_alloc_writecombine);
+
+/*
+ * Allocate DMA-writethrough memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+dma_alloc_writethrough(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ return __dma_alloc(dev, size, handle, gfp,
+ pgprot_writethrough(pgprot_kernel));
+}
+EXPORT_SYMBOL(dma_alloc_writethrough);
+
+/*
+ * Allocate noncacheable memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ */
+void *
+dma_alloc_noncacheable(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ return __dma_alloc(dev, size, handle, gfp,
+ /*pgprot_writethrough(pgprot_kernel));*/
+ pgprot_noncached(pgprot_kernel));
+}
+EXPORT_SYMBOL(dma_alloc_noncacheable);
+
+static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ int ret = -ENXIO;
+#ifdef CONFIG_MMU
+ unsigned long user_size, kern_size;
+ struct arm_vmregion *c;
+
+ user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+
+ c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
+ if (c) {
+ unsigned long off = vma->vm_pgoff;
+
+ kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
+
+ if (off < kern_size &&
+ user_size <= (kern_size - off)) {
+ ret = remap_pfn_range(vma, vma->vm_start,
+ page_to_pfn(c->vm_pages) + off,
+ user_size << PAGE_SHIFT,
+ vma->vm_page_prot);
+ }
+ }
+#endif /* CONFIG_MMU */
+
+ return ret;
+}
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
+int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_writecombine);
+
+/*
+ * free a page as defined by the above mapping.
+ * Must not be called with IRQs disabled.
+ */
+void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
+{
+ WARN_ON(irqs_disabled());
+
+ if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
+ return;
+
+ size = PAGE_ALIGN(size);
+
+ if (!arch_is_coherent())
+ __dma_free_remap(cpu_addr, size);
+
+ __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+/*
+ * Make an area consistent for devices.
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
+ */
+void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ unsigned long paddr;
+
+ BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
+
+ dmac_map_area(kaddr, size, dir);
+
+ paddr = __pa(kaddr);
+ if (dir == DMA_FROM_DEVICE) {
+ outer_inv_range(paddr, paddr + size);
+ } else {
+ outer_clean_range(paddr, paddr + size);
+ }
+ /* FIXME: non-speculating: flush on bidirectional mappings? */
+}
+EXPORT_SYMBOL(___dma_single_cpu_to_dev);
+
+void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
+
+ /* FIXME: non-speculating: not required */
+ /* don't bother invalidating if DMA to device */
+ if (dir != DMA_TO_DEVICE) {
+ unsigned long paddr = __pa(kaddr);
+ outer_inv_range(paddr, paddr + size);
+ }
+
+ dmac_unmap_area(kaddr, size, dir);
+}
+EXPORT_SYMBOL(___dma_single_dev_to_cpu);
+
+static void dma_cache_maint_page(struct page *page, unsigned long offset,
+ size_t size, enum dma_data_direction dir,
+ void (*op)(const void *, size_t, int))
+{
+ /*
+ * A single sg entry may refer to multiple physically contiguous
+ * pages. But we still need to process highmem pages individually.
+ * If highmem is not configured then the bulk of this loop gets
+ * optimized out.
+ */
+ size_t left = size;
+ do {
+ size_t len = left;
+ void *vaddr;
+
+ if (PageHighMem(page)) {
+ if (len + offset > PAGE_SIZE) {
+ if (offset >= PAGE_SIZE) {
+ page += offset / PAGE_SIZE;
+ offset %= PAGE_SIZE;
+ }
+ len = PAGE_SIZE - offset;
+ }
+ vaddr = kmap_high_get(page);
+ if (vaddr) {
+ vaddr += offset;
+ op(vaddr, len, dir);
+ kunmap_high(page);
+ } else if (cache_is_vipt()) {
+ /* unmapped pages might still be cached */
+ vaddr = kmap_atomic(page);
+ op(vaddr + offset, len, dir);
+ kunmap_atomic(vaddr);
+ }
+ } else {
+ vaddr = page_address(page) + offset;
+ op(vaddr, len, dir);
+ }
+ offset = 0;
+ page++;
+ left -= len;
+ } while (left);
+}
+
+void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long paddr;
+
+ dma_cache_maint_page(page, off, size, dir, dmac_map_area);
+
+ paddr = page_to_phys(page) + off;
+ if (dir == DMA_FROM_DEVICE) {
+ outer_inv_range(paddr, paddr + size);
+ } else {
+ outer_clean_range(paddr, paddr + size);
+ }
+ /* FIXME: non-speculating: flush on bidirectional mappings? */
+}
+EXPORT_SYMBOL(___dma_page_cpu_to_dev);
+
+void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long paddr = page_to_phys(page) + off;
+
+ /* FIXME: non-speculating: not required */
+ /* don't bother invalidating if DMA to device */
+ if (dir != DMA_TO_DEVICE)
+ outer_inv_range(paddr, paddr + size);
+
+ dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
+
+ /*
+ * Mark the D-cache clean for this page to avoid extra flushing.
+ */
+ if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
+ set_bit(PG_dcache_clean, &page->flags);
+}
+EXPORT_SYMBOL(___dma_page_dev_to_cpu);
+
+/**
+ * dma_map_sg - map a set of SG buffers for streaming mode DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map
+ * @dir: DMA transfer direction
+ *
+ * Map a set of buffers described by scatterlist in streaming mode for DMA.
+ * This is the scatter-gather version of the dma_map_single interface.
+ * Here the scatter gather list elements are each tagged with the
+ * appropriate dma address and length. They are obtained via
+ * sg_dma_{address,length}.
+ *
+ * Device ownership issues as mentioned for dma_map_single are the same
+ * here.
+ */
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i, j;
+
+ BUG_ON(!valid_dma_direction(dir));
+
+ for_each_sg(sg, s, nents, i) {
+ s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
+ s->length, dir);
+ if (dma_mapping_error(dev, s->dma_address))
+ goto bad_mapping;
+ }
+ debug_dma_map_sg(dev, sg, nents, nents, dir);
+ return nents;
+
+ bad_mapping:
+ for_each_sg(sg, s, i, j)
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+ return 0;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+/**
+ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ *
+ * Unmap a set of streaming mode DMA translations. Again, CPU access
+ * rules concerning calls here are the same as for dma_unmap_single().
+ */
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i;
+
+ debug_dma_unmap_sg(dev, sg, nents, dir);
+
+ for_each_sg(sg, s, nents, i)
+ __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
+}
+EXPORT_SYMBOL(dma_unmap_sg);
+
+/**
+ * dma_sync_sg_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
+ sg_dma_len(s), dir))
+ continue;
+
+ __dma_page_dev_to_cpu(sg_page(s), s->offset,
+ s->length, dir);
+ }
+
+ debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+/**
+ * dma_sync_sg_for_device
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
+ sg_dma_len(s), dir))
+ continue;
+
+ __dma_page_cpu_to_dev(sg_page(s), s->offset,
+ s->length, dir);
+ }
+
+ debug_dma_sync_sg_for_device(dev, sg, nents, dir);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES 4096
+
+static int __init dma_debug_do_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ return 0;
+}
+fs_initcall(dma_debug_do_init);
diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c
new file mode 100644
index 00000000..9d285626
--- /dev/null
+++ b/arch/arm/mm/extable.c
@@ -0,0 +1,16 @@
+/*
+ * linux/arch/arm/mm/extable.c
+ */
+#include <linux/module.h>
+#include <linux/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(instruction_pointer(regs));
+ if (fixup)
+ regs->ARM_pc = fixup->fixup;
+
+ return fixup != NULL;
+}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
new file mode 100644
index 00000000..7cab7917
--- /dev/null
+++ b/arch/arm/mm/fault-armv.c
@@ -0,0 +1,271 @@
+/*
+ * linux/arch/arm/mm/fault-armv.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Modifications for ARM processor (c) 1995-2002 Russell King
+ *
+ * This program is free software; you can 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/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/gfp.h>
+
+#include <asm/bugs.h>
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+static pteval_t shared_pte_mask = L_PTE_MT_BUFFERABLE;
+
+#if __LINUX_ARM_ARCH__ < 6
+/*
+ * We take the easy way out of this problem - we make the
+ * PTE uncacheable. However, we leave the write buffer on.
+ *
+ * Note that the pte lock held when calling update_mmu_cache must also
+ * guard the pte (somewhere else in the same mm) that we modify here.
+ * Therefore those configurations which might call adjust_pte (those
+ * without CONFIG_CPU_CACHE_VIPT) cannot support split page_table_lock.
+ */
+static int do_adjust_pte(struct vm_area_struct *vma, unsigned long address,
+ unsigned long pfn, pte_t *ptep)
+{
+ pte_t entry = *ptep;
+ int ret;
+
+ /*
+ * If this page is present, it's actually being shared.
+ */
+ ret = pte_present(entry);
+
+ /*
+ * If this page isn't present, or is already setup to
+ * fault (ie, is old), we can safely ignore any issues.
+ */
+ if (ret && (pte_val(entry) & L_PTE_MT_MASK) != shared_pte_mask) {
+ flush_cache_page(vma, address, pfn);
+ outer_flush_range((pfn << PAGE_SHIFT),
+ (pfn << PAGE_SHIFT) + PAGE_SIZE);
+ pte_val(entry) &= ~L_PTE_MT_MASK;
+ pte_val(entry) |= shared_pte_mask;
+ set_pte_at(vma->vm_mm, address, ptep, entry);
+ flush_tlb_page(vma, address);
+ }
+
+ return ret;
+}
+
+#if USE_SPLIT_PTLOCKS
+/*
+ * If we are using split PTE locks, then we need to take the page
+ * lock here. Otherwise we are using shared mm->page_table_lock
+ * which is already locked, thus cannot take it.
+ */
+static inline void do_pte_lock(spinlock_t *ptl)
+{
+ /*
+ * Use nested version here to indicate that we are already
+ * holding one similar spinlock.
+ */
+ spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
+}
+
+static inline void do_pte_unlock(spinlock_t *ptl)
+{
+ spin_unlock(ptl);
+}
+#else /* !USE_SPLIT_PTLOCKS */
+static inline void do_pte_lock(spinlock_t *ptl) {}
+static inline void do_pte_unlock(spinlock_t *ptl) {}
+#endif /* USE_SPLIT_PTLOCKS */
+
+static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
+ unsigned long pfn)
+{
+ spinlock_t *ptl;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ int ret;
+
+ pgd = pgd_offset(vma->vm_mm, address);
+ if (pgd_none_or_clear_bad(pgd))
+ return 0;
+
+ pud = pud_offset(pgd, address);
+ if (pud_none_or_clear_bad(pud))
+ return 0;
+
+ pmd = pmd_offset(pud, address);
+ if (pmd_none_or_clear_bad(pmd))
+ return 0;
+
+ /*
+ * This is called while another page table is mapped, so we
+ * must use the nested version. This also means we need to
+ * open-code the spin-locking.
+ */
+ ptl = pte_lockptr(vma->vm_mm, pmd);
+ pte = pte_offset_map(pmd, address);
+ do_pte_lock(ptl);
+
+ ret = do_adjust_pte(vma, address, pfn, pte);
+
+ do_pte_unlock(ptl);
+ pte_unmap(pte);
+
+ return ret;
+}
+
+static void
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep, unsigned long pfn)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ struct vm_area_struct *mpnt;
+ struct prio_tree_iter iter;
+ unsigned long offset;
+ pgoff_t pgoff;
+ int aliases = 0;
+
+ pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
+
+ /*
+ * If we have any shared mappings that are in the same mm
+ * space, then we need to handle them specially to maintain
+ * cache coherency.
+ */
+ flush_dcache_mmap_lock(mapping);
+ vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ /*
+ * If this VMA is not in our MM, we can ignore it.
+ * Note that we intentionally mask out the VMA
+ * that we are fixing up.
+ */
+ if (mpnt->vm_mm != mm || mpnt == vma)
+ continue;
+ if (!(mpnt->vm_flags & VM_MAYSHARE))
+ continue;
+ offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
+ aliases += adjust_pte(mpnt, mpnt->vm_start + offset, pfn);
+ }
+ flush_dcache_mmap_unlock(mapping);
+ if (aliases)
+ do_adjust_pte(vma, addr, pfn, ptep);
+}
+
+/*
+ * Take care of architecture specific things when placing a new PTE into
+ * a page table, or changing an existing PTE. Basically, there are two
+ * things that we need to take care of:
+ *
+ * 1. If PG_dcache_clean is not set for the page, we need to ensure
+ * that any cache entries for the kernels virtual memory
+ * range are written back to the page.
+ * 2. If we have multiple shared mappings of the same space in
+ * an object, we need to deal with the cache aliasing issues.
+ *
+ * Note that the pte lock will be held.
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
+ pte_t *ptep)
+{
+ unsigned long pfn = pte_pfn(*ptep);
+ struct address_space *mapping;
+ struct page *page;
+
+ if (!pfn_valid(pfn))
+ return;
+
+ /*
+ * The zero page is never written to, so never has any dirty
+ * cache lines, and therefore never needs to be flushed.
+ */
+ page = pfn_to_page(pfn);
+ if (page == ZERO_PAGE(0))
+ return;
+
+ mapping = page_mapping(page);
+ if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+ __flush_dcache_page(mapping, page);
+ if (mapping) {
+ if (cache_is_vivt())
+ make_coherent(mapping, vma, addr, ptep, pfn);
+ else if (vma->vm_flags & VM_EXEC)
+ __flush_icache_all();
+ }
+}
+#endif /* __LINUX_ARM_ARCH__ < 6 */
+
+/*
+ * Check whether the write buffer has physical address aliasing
+ * issues. If it has, we need to avoid them for the case where
+ * we have several shared mappings of the same object in user
+ * space.
+ */
+static int __init check_writebuffer(unsigned long *p1, unsigned long *p2)
+{
+ register unsigned long zero = 0, one = 1, val;
+
+ local_irq_disable();
+ mb();
+ *p1 = one;
+ mb();
+ *p2 = zero;
+ mb();
+ val = *p1;
+ mb();
+ local_irq_enable();
+ return val != zero;
+}
+
+void __init check_writebuffer_bugs(void)
+{
+ struct page *page;
+ const char *reason;
+ unsigned long v = 1;
+
+ printk(KERN_INFO "CPU: Testing write buffer coherency: ");
+
+ page = alloc_page(GFP_KERNEL);
+ if (page) {
+ unsigned long *p1, *p2;
+ pgprot_t prot = __pgprot_modify(PAGE_KERNEL,
+ L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE);
+
+ p1 = vmap(&page, 1, VM_IOREMAP, prot);
+ p2 = vmap(&page, 1, VM_IOREMAP, prot);
+
+ if (p1 && p2) {
+ v = check_writebuffer(p1, p2);
+ reason = "enabling work-around";
+ } else {
+ reason = "unable to map memory\n";
+ }
+
+ vunmap(p1);
+ vunmap(p2);
+ put_page(page);
+ } else {
+ reason = "unable to grab page\n";
+ }
+
+ if (v) {
+ printk("failed, %s\n", reason);
+ shared_pte_mask = L_PTE_MT_UNCACHED;
+ } else {
+ printk("ok\n");
+ }
+}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
new file mode 100644
index 00000000..8799eae5
--- /dev/null
+++ b/arch/arm/mm/fault.c
@@ -0,0 +1,662 @@
+/*
+ * linux/arch/arm/mm/fault.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Modifications for ARM processor (c) 1995-2004 Russell King
+ *
+ * This program is free software; you can 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/signal.h>
+#include <linux/mm.h>
+#include <linux/hardirq.h>
+#include <linux/init.h>
+#include <linux/kprobes.h>
+#include <linux/uaccess.h>
+#include <linux/page-flags.h>
+#include <linux/sched.h>
+#include <linux/highmem.h>
+#include <linux/perf_event.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+#include "fault.h"
+
+/*
+ * Fault status register encodings. We steal bit 31 for our own purposes.
+ */
+#define FSR_LNX_PF (1 << 31)
+#define FSR_WRITE (1 << 11)
+#define FSR_FS4 (1 << 10)
+#define FSR_FS3_0 (15)
+
+static inline int fsr_fs(unsigned int fsr)
+{
+ return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
+}
+
+#ifdef CONFIG_MMU
+
+#ifdef CONFIG_KPROBES
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
+{
+ int ret = 0;
+
+ if (!user_mode(regs)) {
+ /* kprobe_running() needs smp_processor_id() */
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, fsr))
+ ret = 1;
+ preempt_enable();
+ }
+
+ return ret;
+}
+#else
+static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr)
+{
+ return 0;
+}
+#endif
+
+/*
+ * This is useful to dump out the page tables associated with
+ * 'addr' in mm 'mm'.
+ */
+void show_pte(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+
+ if (!mm)
+ mm = &init_mm;
+
+ printk(KERN_ALERT "pgd = %p\n", mm->pgd);
+ pgd = pgd_offset(mm, addr);
+ printk(KERN_ALERT "[%08lx] *pgd=%08llx",
+ addr, (long long)pgd_val(*pgd));
+
+ do {
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (pgd_none(*pgd))
+ break;
+
+ if (pgd_bad(*pgd)) {
+ printk("(bad)");
+ break;
+ }
+
+ pud = pud_offset(pgd, addr);
+ if (PTRS_PER_PUD != 1)
+ printk(", *pud=%08lx", pud_val(*pud));
+
+ if (pud_none(*pud))
+ break;
+
+ if (pud_bad(*pud)) {
+ printk("(bad)");
+ break;
+ }
+
+ pmd = pmd_offset(pud, addr);
+ if (PTRS_PER_PMD != 1)
+ printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
+
+ if (pmd_none(*pmd))
+ break;
+
+ if (pmd_bad(*pmd)) {
+ printk("(bad)");
+ break;
+ }
+
+ /* We must not map this if we have highmem enabled */
+ if (PageHighMem(pfn_to_page(pmd_val(*pmd) >> PAGE_SHIFT)))
+ break;
+
+ pte = pte_offset_map(pmd, addr);
+ printk(", *pte=%08llx", (long long)pte_val(*pte));
+ printk(", *ppte=%08llx",
+ (long long)pte_val(pte[PTE_HWTABLE_PTRS]));
+ pte_unmap(pte);
+ } while(0);
+
+ printk("\n");
+}
+#else /* CONFIG_MMU */
+void show_pte(struct mm_struct *mm, unsigned long addr)
+{ }
+#endif /* CONFIG_MMU */
+
+/*
+ * Oops. The kernel tried to access some page that wasn't present.
+ */
+static void
+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ /*
+ * Are we prepared to handle this kernel fault?
+ */
+ if (fixup_exception(regs))
+ return;
+
+ /*
+ * No handler, we'll have to terminate things with extreme prejudice.
+ */
+ bust_spinlocks(1);
+ printk(KERN_ALERT
+ "Unable to handle kernel %s at virtual address %08lx\n",
+ (addr < PAGE_SIZE) ? "NULL pointer dereference" :
+ "paging request", addr);
+
+ show_pte(mm, addr);
+ die("Oops", regs, fsr);
+ bust_spinlocks(0);
+ do_exit(SIGKILL);
+}
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * User mode accesses just cause a SIGSEGV
+ */
+static void
+__do_user_fault(struct task_struct *tsk, unsigned long addr,
+ unsigned int fsr, unsigned int sig, int code,
+ struct pt_regs *regs)
+{
+ struct siginfo si;
+
+#ifdef CONFIG_DEBUG_USER
+ if (user_debug & UDBG_SEGV) {
+ printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
+ tsk->comm, sig, addr, fsr);
+ show_pte(tsk->mm, addr);
+ show_regs(regs);
+ }
+#endif
+
+ tsk->thread.address = addr;
+ tsk->thread.error_code = fsr;
+ tsk->thread.trap_no = 14;
+ si.si_signo = sig;
+ si.si_errno = 0;
+ si.si_code = code;
+ si.si_addr = (void __user *)addr;
+ force_sig_info(sig, &si, tsk);
+}
+
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ struct task_struct *tsk = current;
+ struct mm_struct *mm = tsk->active_mm;
+
+ /*
+ * If we are in kernel mode at this point, we
+ * have no context to handle this fault with.
+ */
+ if (user_mode(regs))
+ __do_user_fault(tsk, addr, fsr, SIGSEGV, SEGV_MAPERR, regs);
+ else
+ __do_kernel_fault(mm, addr, fsr, regs);
+}
+
+#ifdef CONFIG_MMU
+#define VM_FAULT_BADMAP 0x010000
+#define VM_FAULT_BADACCESS 0x020000
+
+/*
+ * Check that the permissions on the VMA allow for the fault which occurred.
+ * If we encountered a write fault, we must have write permission, otherwise
+ * we allow any permission.
+ */
+static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma)
+{
+ unsigned int mask = VM_READ | VM_WRITE | VM_EXEC;
+
+ if (fsr & FSR_WRITE)
+ mask = VM_WRITE;
+ if (fsr & FSR_LNX_PF)
+ mask = VM_EXEC;
+
+ return vma->vm_flags & mask ? false : true;
+}
+
+static int __kprobes
+__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
+ struct task_struct *tsk)
+{
+ struct vm_area_struct *vma;
+ int fault;
+
+ vma = find_vma(mm, addr);
+ fault = VM_FAULT_BADMAP;
+ if (unlikely(!vma))
+ goto out;
+ if (unlikely(vma->vm_start > addr))
+ goto check_stack;
+
+ /*
+ * Ok, we have a good vm_area for this
+ * memory access, so we can handle it.
+ */
+good_area:
+ if (access_error(fsr, vma)) {
+ fault = VM_FAULT_BADACCESS;
+ goto out;
+ }
+
+ /*
+ * If for any reason at all we couldn't handle the fault, make
+ * sure we exit gracefully rather than endlessly redo the fault.
+ */
+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, (fsr & FSR_WRITE) ? FAULT_FLAG_WRITE : 0);
+ if (unlikely(fault & VM_FAULT_ERROR))
+ return fault;
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ return fault;
+
+check_stack:
+ /* Don't allow expansion below FIRST_USER_ADDRESS */
+ if (vma->vm_flags & VM_GROWSDOWN &&
+ addr >= FIRST_USER_ADDRESS && !expand_stack(vma, addr))
+ goto good_area;
+out:
+ return fault;
+}
+
+static int __kprobes
+do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ struct task_struct *tsk;
+ struct mm_struct *mm;
+ int fault, sig, code;
+
+ if (notify_page_fault(regs, fsr))
+ return 0;
+
+ tsk = current;
+ mm = tsk->mm;
+
+ /*
+ * If we're in an interrupt or have no user
+ * context, we must not take the fault..
+ */
+ if (in_atomic() || !mm)
+ goto no_context;
+
+ /*
+ * As per x86, we may deadlock here. However, since the kernel only
+ * validly references user space from well defined areas of the code,
+ * we can bug out early if this is from code which shouldn't.
+ */
+ if (!down_read_trylock(&mm->mmap_sem)) {
+ if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))
+ goto no_context;
+ down_read(&mm->mmap_sem);
+ } else {
+ /*
+ * The above down_read_trylock() might have succeeded in
+ * which case, we'll have missed the might_sleep() from
+ * down_read()
+ */
+ might_sleep();
+#ifdef CONFIG_DEBUG_VM
+ if (!user_mode(regs) &&
+ !search_exception_tables(regs->ARM_pc))
+ goto no_context;
+#endif
+ }
+
+ fault = __do_page_fault(mm, addr, fsr, tsk);
+ up_read(&mm->mmap_sem);
+
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, addr);
+ if (fault & VM_FAULT_MAJOR)
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, regs, addr);
+ else if (fault & VM_FAULT_MINOR)
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, regs, addr);
+
+ /*
+ * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR
+ */
+ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS))))
+ return 0;
+
+ if (fault & VM_FAULT_OOM) {
+ /*
+ * We ran out of memory, call the OOM killer, and return to
+ * userspace (which will retry the fault, or kill us if we
+ * got oom-killed)
+ */
+ pagefault_out_of_memory();
+ return 0;
+ }
+
+ /*
+ * If we are in kernel mode at this point, we
+ * have no context to handle this fault with.
+ */
+ if (!user_mode(regs))
+ goto no_context;
+
+ if (fault & VM_FAULT_SIGBUS) {
+ /*
+ * We had some memory, but were unable to
+ * successfully fix up this page fault.
+ */
+ sig = SIGBUS;
+ code = BUS_ADRERR;
+ } else {
+ /*
+ * Something tried to access memory that
+ * isn't in our memory map..
+ */
+ sig = SIGSEGV;
+ code = fault == VM_FAULT_BADACCESS ?
+ SEGV_ACCERR : SEGV_MAPERR;
+ }
+
+ __do_user_fault(tsk, addr, fsr, sig, code, regs);
+ return 0;
+
+no_context:
+ __do_kernel_fault(mm, addr, fsr, regs);
+ return 0;
+}
+#else /* CONFIG_MMU */
+static int
+do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ return 0;
+}
+#endif /* CONFIG_MMU */
+
+/*
+ * First Level Translation Fault Handler
+ *
+ * We enter here because the first level page table doesn't contain
+ * a valid entry for the address.
+ *
+ * If the address is in kernel space (>= TASK_SIZE), then we are
+ * probably faulting in the vmalloc() area.
+ *
+ * If the init_task's first level page tables contains the relevant
+ * entry, we copy the it to this task. If not, we send the process
+ * a signal, fixup the exception, or oops the kernel.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may be in an
+ * interrupt or a critical region, and should only copy the information
+ * from the master page table, nothing more.
+ */
+#ifdef CONFIG_MMU
+static int __kprobes
+do_translation_fault(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ unsigned int index;
+ pgd_t *pgd, *pgd_k;
+ pud_t *pud, *pud_k;
+ pmd_t *pmd, *pmd_k;
+
+ if (addr < TASK_SIZE)
+ return do_page_fault(addr, fsr, regs);
+
+ if (user_mode(regs))
+ goto bad_area;
+
+ index = pgd_index(addr);
+
+ /*
+ * FIXME: CP15 C1 is write only on ARMv3 architectures.
+ */
+ pgd = cpu_get_pgd() + index;
+ pgd_k = init_mm.pgd + index;
+
+ if (pgd_none(*pgd_k))
+ goto bad_area;
+ if (!pgd_present(*pgd))
+ set_pgd(pgd, *pgd_k);
+
+ pud = pud_offset(pgd, addr);
+ pud_k = pud_offset(pgd_k, addr);
+
+ if (pud_none(*pud_k))
+ goto bad_area;
+ if (!pud_present(*pud))
+ set_pud(pud, *pud_k);
+
+ pmd = pmd_offset(pud, addr);
+ pmd_k = pmd_offset(pud_k, addr);
+
+ /*
+ * On ARM one Linux PGD entry contains two hardware entries (see page
+ * tables layout in pgtable.h). We normally guarantee that we always
+ * fill both L1 entries. But create_mapping() doesn't follow the rule.
+ * It can create inidividual L1 entries, so here we have to call
+ * pmd_none() check for the entry really corresponded to address, not
+ * for the first of pair.
+ */
+ index = (addr >> SECTION_SHIFT) & 1;
+ if (pmd_none(pmd_k[index]))
+ goto bad_area;
+
+ copy_pmd(pmd, pmd_k);
+ return 0;
+
+bad_area:
+ do_bad_area(addr, fsr, regs);
+ return 0;
+}
+#else /* CONFIG_MMU */
+static int
+do_translation_fault(unsigned long addr, unsigned int fsr,
+ struct pt_regs *regs)
+{
+ return 0;
+}
+#endif /* CONFIG_MMU */
+
+/*
+ * Some section permission faults need to be handled gracefully.
+ * They can happen due to a __{get,put}_user during an oops.
+ */
+static int
+do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ do_bad_area(addr, fsr, regs);
+ return 0;
+}
+
+/*
+ * This abort handler always returns "fault".
+ */
+static int
+do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ return 1;
+}
+
+static struct fsr_info {
+ int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+ int sig;
+ int code;
+ const char *name;
+} fsr_info[] = {
+ /*
+ * The following are the standard ARMv3 and ARMv4 aborts. ARMv5
+ * defines these to be "precise" aborts.
+ */
+ { do_bad, SIGSEGV, 0, "vector exception" },
+ { do_bad, SIGBUS, BUS_ADRALN, "alignment exception" },
+ { do_bad, SIGKILL, 0, "terminal exception" },
+ { do_bad, SIGBUS, BUS_ADRALN, "alignment exception" },
+ { do_bad, SIGBUS, 0, "external abort on linefetch" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
+ { do_bad, SIGBUS, 0, "external abort on linefetch" },
+ { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
+ { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
+ { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
+ /*
+ * The following are "imprecise" aborts, which are signalled by bit
+ * 10 of the FSR, and may not be recoverable. These are only
+ * supported if the CPU abort handler supports bit 10.
+ */
+ { do_bad, SIGBUS, 0, "unknown 16" },
+ { do_bad, SIGBUS, 0, "unknown 17" },
+ { do_bad, SIGBUS, 0, "unknown 18" },
+ { do_bad, SIGBUS, 0, "unknown 19" },
+ { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */
+ { do_bad, SIGBUS, 0, "unknown 21" },
+ { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */
+ { do_bad, SIGBUS, 0, "unknown 23" },
+ { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */
+ { do_bad, SIGBUS, 0, "unknown 25" },
+ { do_bad, SIGBUS, 0, "unknown 26" },
+ { do_bad, SIGBUS, 0, "unknown 27" },
+ { do_bad, SIGBUS, 0, "unknown 28" },
+ { do_bad, SIGBUS, 0, "unknown 29" },
+ { do_bad, SIGBUS, 0, "unknown 30" },
+ { do_bad, SIGBUS, 0, "unknown 31" }
+};
+
+void __init
+hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+ int sig, int code, const char *name)
+{
+ if (nr < 0 || nr >= ARRAY_SIZE(fsr_info))
+ BUG();
+
+ fsr_info[nr].fn = fn;
+ fsr_info[nr].sig = sig;
+ fsr_info[nr].code = code;
+ fsr_info[nr].name = name;
+}
+
+/*
+ * Dispatch a data abort to the relevant handler.
+ */
+asmlinkage void __exception
+do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ const struct fsr_info *inf = fsr_info + fsr_fs(fsr);
+ struct siginfo info;
+
+ if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
+ return;
+
+ printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
+ inf->name, fsr, addr);
+
+ info.si_signo = inf->sig;
+ info.si_errno = 0;
+ info.si_code = inf->code;
+ info.si_addr = (void __user *)addr;
+ arm_notify_die("", regs, &info, fsr, 0);
+}
+
+
+static struct fsr_info ifsr_info[] = {
+ { do_bad, SIGBUS, 0, "unknown 0" },
+ { do_bad, SIGBUS, 0, "unknown 1" },
+ { do_bad, SIGBUS, 0, "debug event" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section access flag fault" },
+ { do_bad, SIGBUS, 0, "unknown 4" },
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page access flag fault" },
+ { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
+ { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
+ { do_bad, SIGBUS, 0, "unknown 10" },
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
+ { do_bad, SIGBUS, 0, "external abort on translation" },
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
+ { do_bad, SIGBUS, 0, "unknown 16" },
+ { do_bad, SIGBUS, 0, "unknown 17" },
+ { do_bad, SIGBUS, 0, "unknown 18" },
+ { do_bad, SIGBUS, 0, "unknown 19" },
+ { do_bad, SIGBUS, 0, "unknown 20" },
+ { do_bad, SIGBUS, 0, "unknown 21" },
+ { do_bad, SIGBUS, 0, "unknown 22" },
+ { do_bad, SIGBUS, 0, "unknown 23" },
+ { do_bad, SIGBUS, 0, "unknown 24" },
+ { do_bad, SIGBUS, 0, "unknown 25" },
+ { do_bad, SIGBUS, 0, "unknown 26" },
+ { do_bad, SIGBUS, 0, "unknown 27" },
+ { do_bad, SIGBUS, 0, "unknown 28" },
+ { do_bad, SIGBUS, 0, "unknown 29" },
+ { do_bad, SIGBUS, 0, "unknown 30" },
+ { do_bad, SIGBUS, 0, "unknown 31" },
+};
+
+void __init
+hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+ int sig, int code, const char *name)
+{
+ if (nr < 0 || nr >= ARRAY_SIZE(ifsr_info))
+ BUG();
+
+ ifsr_info[nr].fn = fn;
+ ifsr_info[nr].sig = sig;
+ ifsr_info[nr].code = code;
+ ifsr_info[nr].name = name;
+}
+
+asmlinkage void __exception
+do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
+{
+ const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
+ struct siginfo info;
+
+ if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
+ return;
+
+ printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
+ inf->name, ifsr, addr);
+
+ info.si_signo = inf->sig;
+ info.si_errno = 0;
+ info.si_code = inf->code;
+ info.si_addr = (void __user *)addr;
+ arm_notify_die("", regs, &info, ifsr, 0);
+}
+
+static int __init exceptions_init(void)
+{
+ if (cpu_architecture() >= CPU_ARCH_ARMv6) {
+ hook_fault_code(4, do_translation_fault, SIGSEGV, SEGV_MAPERR,
+ "I-cache maintenance fault");
+ }
+
+ if (cpu_architecture() >= CPU_ARCH_ARMv7) {
+ /*
+ * TODO: Access flag faults introduced in ARMv6K.
+ * Runtime check for 'K' extension is needed
+ */
+ hook_fault_code(3, do_bad, SIGSEGV, SEGV_MAPERR,
+ "section access flag fault");
+ hook_fault_code(6, do_bad, SIGSEGV, SEGV_MAPERR,
+ "section access flag fault");
+ }
+
+ return 0;
+}
+
+arch_initcall(exceptions_init);
diff --git a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
new file mode 100644
index 00000000..49e9e380
--- /dev/null
+++ b/arch/arm/mm/fault.h
@@ -0,0 +1,3 @@
+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+unsigned long search_exception_table(unsigned long addr);
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
new file mode 100644
index 00000000..1a8d4aa8
--- /dev/null
+++ b/arch/arm/mm/flush.c
@@ -0,0 +1,346 @@
+/*
+ * linux/arch/arm/mm/flush.c
+ *
+ * Copyright (C) 1995-2002 Russell King
+ *
+ * This program is free software; you can 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/mm.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cachetype.h>
+#include <asm/highmem.h>
+#include <asm/smp_plat.h>
+#include <asm/system.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#define ALIAS_FLUSH_START 0xffff4000
+
+static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
+{
+ unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+ const int zero = 0;
+
+ set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
+ flush_tlb_kernel_page(to);
+
+ asm( "mcrr p15, 0, %1, %0, c14\n"
+ " mcr p15, 0, %2, c7, c10, 4"
+ :
+ : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
+ : "cc");
+}
+
+static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len)
+{
+ unsigned long colour = CACHE_COLOUR(vaddr);
+ unsigned long offset = vaddr & (PAGE_SIZE - 1);
+ unsigned long to;
+
+ set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0);
+ to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset;
+ flush_tlb_kernel_page(to);
+ flush_icache_range(to, to + len);
+}
+
+void flush_cache_mm(struct mm_struct *mm)
+{
+ if (cache_is_vivt()) {
+ vivt_flush_cache_mm(mm);
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ asm( "mcr p15, 0, %0, c7, c14, 0\n"
+ " mcr p15, 0, %0, c7, c10, 4"
+ :
+ : "r" (0)
+ : "cc");
+ }
+}
+
+void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+{
+ if (cache_is_vivt()) {
+ vivt_flush_cache_range(vma, start, end);
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ asm( "mcr p15, 0, %0, c7, c14, 0\n"
+ " mcr p15, 0, %0, c7, c10, 4"
+ :
+ : "r" (0)
+ : "cc");
+ }
+
+ if (vma->vm_flags & VM_EXEC)
+ __flush_icache_all();
+}
+
+void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+{
+ if (cache_is_vivt()) {
+ vivt_flush_cache_page(vma, user_addr, pfn);
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ flush_pfn_alias(pfn, user_addr);
+ __flush_icache_all();
+ }
+
+ if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
+ __flush_icache_all();
+}
+
+#else
+#define flush_pfn_alias(pfn,vaddr) do { } while (0)
+#define flush_icache_alias(pfn,vaddr,len) do { } while (0)
+#endif
+
+static void flush_ptrace_access_other(void *args)
+{
+ __flush_icache_all();
+}
+
+static
+void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+ unsigned long uaddr, void *kaddr, unsigned long len)
+{
+ if (cache_is_vivt()) {
+ if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+ unsigned long addr = (unsigned long)kaddr;
+ __cpuc_coherent_kern_range(addr, addr + len);
+ }
+ return;
+ }
+
+ if (cache_is_vipt_aliasing()) {
+ flush_pfn_alias(page_to_pfn(page), uaddr);
+ __flush_icache_all();
+ return;
+ }
+
+ /* VIPT non-aliasing D-cache */
+ if (vma->vm_flags & VM_EXEC) {
+ unsigned long addr = (unsigned long)kaddr;
+ if (icache_is_vipt_aliasing())
+ flush_icache_alias(page_to_pfn(page), uaddr, len);
+ else
+ __cpuc_coherent_kern_range(addr, addr + len);
+ if (cache_ops_need_broadcast())
+ smp_call_function(flush_ptrace_access_other,
+ NULL, 1);
+ }
+}
+
+/*
+ * Copy user data from/to a page which is mapped into a different
+ * processes address space. Really, we want to allow our "user
+ * space" model to handle this.
+ *
+ * Note that this code needs to run on the current CPU.
+ */
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long uaddr, void *dst, const void *src,
+ unsigned long len)
+{
+#ifdef CONFIG_SMP
+ preempt_disable();
+#endif
+ memcpy(dst, src, len);
+ flush_ptrace_access(vma, page, uaddr, dst, len);
+#ifdef CONFIG_SMP
+ preempt_enable();
+#endif
+}
+
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
+{
+ /*
+ * Writeback any data associated with the kernel mapping of this
+ * page. This ensures that data in the physical page is mutually
+ * coherent with the kernels mapping.
+ */
+ if (!PageHighMem(page)) {
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+ } else {
+ void *addr = kmap_high_get(page);
+ if (addr) {
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_high(page);
+ } else if (cache_is_vipt()) {
+ /* unmapped pages might still be cached */
+ addr = kmap_atomic(page);
+ __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+ kunmap_atomic(addr);
+ }
+ }
+
+ /*
+ * If this is a page cache page, and we have an aliasing VIPT cache,
+ * we only need to do one flush - which would be at the relevant
+ * userspace colour, which is congruent with page->index.
+ */
+ if (mapping && cache_is_vipt_aliasing())
+ flush_pfn_alias(page_to_pfn(page),
+ page->index << PAGE_CACHE_SHIFT);
+}
+
+static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
+{
+ struct mm_struct *mm = current->active_mm;
+ struct vm_area_struct *mpnt;
+ struct prio_tree_iter iter;
+ pgoff_t pgoff;
+
+ /*
+ * There are possible user space mappings of this page:
+ * - VIVT cache: we need to also write back and invalidate all user
+ * data in the current VM view associated with this page.
+ * - aliasing VIPT: we only need to find one mapping of this page.
+ */
+ pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+
+ flush_dcache_mmap_lock(mapping);
+ vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+ unsigned long offset;
+
+ /*
+ * If this VMA is not in our MM, we can ignore it.
+ */
+ if (mpnt->vm_mm != mm)
+ continue;
+ if (!(mpnt->vm_flags & VM_MAYSHARE))
+ continue;
+ offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
+ flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
+ }
+ flush_dcache_mmap_unlock(mapping);
+}
+
+#if __LINUX_ARM_ARCH__ >= 6
+void __sync_icache_dcache(pte_t pteval)
+{
+ unsigned long pfn;
+ struct page *page;
+ struct address_space *mapping;
+
+ if (!pte_present_user(pteval))
+ return;
+ if (cache_is_vipt_nonaliasing() && !pte_exec(pteval))
+ /* only flush non-aliasing VIPT caches for exec mappings */
+ return;
+ pfn = pte_pfn(pteval);
+ if (!pfn_valid(pfn))
+ return;
+
+ page = pfn_to_page(pfn);
+ if (cache_is_vipt_aliasing())
+ mapping = page_mapping(page);
+ else
+ mapping = NULL;
+
+ if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+ __flush_dcache_page(mapping, page);
+
+ if (pte_exec(pteval))
+ __flush_icache_all();
+}
+#endif
+
+/*
+ * Ensure cache coherency between kernel mapping and userspace mapping
+ * of this page.
+ *
+ * We have three cases to consider:
+ * - VIPT non-aliasing cache: fully coherent so nothing required.
+ * - VIVT: fully aliasing, so we need to handle every alias in our
+ * current VM view.
+ * - VIPT aliasing: need to handle one alias in our current VM view.
+ *
+ * If we need to handle aliasing:
+ * If the page only exists in the page cache and there are no user
+ * space mappings, we can be lazy and remember that we may have dirty
+ * kernel cache lines for later. Otherwise, we assume we have
+ * aliasing mappings.
+ *
+ * Note that we disable the lazy flush for SMP configurations where
+ * the cache maintenance operations are not automatically broadcasted.
+ */
+void flush_dcache_page(struct page *page)
+{
+ struct address_space *mapping;
+
+ /*
+ * The zero page is never written to, so never has any dirty
+ * cache lines, and therefore never needs to be flushed.
+ */
+ if (page == ZERO_PAGE(0))
+ return;
+
+ mapping = page_mapping(page);
+
+ if (!cache_ops_need_broadcast() &&
+ mapping && !mapping_mapped(mapping))
+ clear_bit(PG_dcache_clean, &page->flags);
+ else {
+ __flush_dcache_page(mapping, page);
+ if (mapping && cache_is_vivt())
+ __flush_dcache_aliases(mapping, page);
+ else if (mapping)
+ __flush_icache_all();
+ set_bit(PG_dcache_clean, &page->flags);
+ }
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+/*
+ * Flush an anonymous page so that users of get_user_pages()
+ * can safely access the data. The expected sequence is:
+ *
+ * get_user_pages()
+ * -> flush_anon_page
+ * memcpy() to/from page
+ * if written to page, flush_dcache_page()
+ */
+void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
+{
+ unsigned long pfn;
+
+ /* VIPT non-aliasing caches need do nothing */
+ if (cache_is_vipt_nonaliasing())
+ return;
+
+ /*
+ * Write back and invalidate userspace mapping.
+ */
+ pfn = page_to_pfn(page);
+ if (cache_is_vivt()) {
+ flush_cache_page(vma, vmaddr, pfn);
+ } else {
+ /*
+ * For aliasing VIPT, we can flush an alias of the
+ * userspace address only.
+ */
+ flush_pfn_alias(pfn, vmaddr);
+ __flush_icache_all();
+ }
+
+ /*
+ * Invalidate kernel mapping. No data should be contained
+ * in this mapping of the page. FIXME: this is overkill
+ * since we actually ask for a write-back and invalidate.
+ */
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+}
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
new file mode 100644
index 00000000..807c0573
--- /dev/null
+++ b/arch/arm/mm/highmem.c
@@ -0,0 +1,142 @@
+/*
+ * arch/arm/mm/highmem.c -- ARM highmem support
+ *
+ * Author: Nicolas Pitre
+ * Created: september 8, 2008
+ * Copyright: Marvell Semiconductors Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <asm/fixmap.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include "mm.h"
+
+void *kmap(struct page *page)
+{
+ might_sleep();
+ if (!PageHighMem(page))
+ return page_address(page);
+ return kmap_high(page);
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+ BUG_ON(in_interrupt());
+ if (!PageHighMem(page))
+ return;
+ kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+void *__kmap_atomic(struct page *page)
+{
+ unsigned int idx;
+ unsigned long vaddr;
+ void *kmap;
+ int type;
+
+ pagefault_disable();
+ if (!PageHighMem(page))
+ return page_address(page);
+
+#ifdef CONFIG_DEBUG_HIGHMEM
+ /*
+ * There is no cache coherency issue when non VIVT, so force the
+ * dedicated kmap usage for better debugging purposes in that case.
+ */
+ if (!cache_is_vivt())
+ kmap = NULL;
+ else
+#endif
+ kmap = kmap_high_get(page);
+ if (kmap)
+ return kmap;
+
+ type = kmap_atomic_idx_push();
+
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ /*
+ * With debugging enabled, kunmap_atomic forces that entry to 0.
+ * Make sure it was indeed properly unmapped.
+ */
+ BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+ set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0);
+ /*
+ * When debugging is off, kunmap_atomic leaves the previous mapping
+ * in place, so this TLB flush ensures the TLB is updated with the
+ * new mapping.
+ */
+ local_flush_tlb_kernel_page(vaddr);
+
+ return (void *)vaddr;
+}
+EXPORT_SYMBOL(__kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+ int idx, type;
+
+ if (kvaddr >= (void *)FIXADDR_START) {
+ type = kmap_atomic_idx();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+
+ if (cache_is_vivt())
+ __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+ set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
+ local_flush_tlb_kernel_page(vaddr);
+#else
+ (void) idx; /* to kill a warning */
+#endif
+ kmap_atomic_idx_pop();
+ } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
+ /* this address was obtained through kmap_high_get() */
+ kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
+ }
+ pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
+
+void *kmap_atomic_pfn(unsigned long pfn)
+{
+ unsigned long vaddr;
+ int idx, type;
+
+ pagefault_disable();
+
+ type = kmap_atomic_idx_push();
+ idx = type + KM_TYPE_NR * smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+ BUG_ON(!pte_none(*(TOP_PTE(vaddr))));
+#endif
+ set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0);
+ local_flush_tlb_kernel_page(vaddr);
+
+ return (void *)vaddr;
+}
+
+struct page *kmap_atomic_to_page(const void *ptr)
+{
+ unsigned long vaddr = (unsigned long)ptr;
+ pte_t *pte;
+
+ if (vaddr < FIXADDR_START)
+ return virt_to_page(ptr);
+
+ pte = TOP_PTE(vaddr);
+ return pte_page(*pte);
+}
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
new file mode 100644
index 00000000..2be9139a
--- /dev/null
+++ b/arch/arm/mm/idmap.c
@@ -0,0 +1,90 @@
+#include <linux/kernel.h>
+
+#include <asm/cputype.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+ unsigned long prot)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+
+ addr = (addr & PMD_MASK) | prot;
+ pmd[0] = __pmd(addr);
+ addr += SECTION_SIZE;
+ pmd[1] = __pmd(addr);
+ flush_pmd_entry(pmd);
+}
+
+static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+ unsigned long prot)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ idmap_add_pmd(pud, addr, next, prot);
+ } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ unsigned long prot, next;
+
+ prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
+ if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+ prot |= PMD_BIT4;
+
+ pgd += pgd_index(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ idmap_add_pud(pgd, addr, next, prot);
+ } while (pgd++, addr = next, addr != end);
+}
+
+#ifdef CONFIG_SMP
+static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+ pmd_clear(pmd);
+}
+
+static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ idmap_del_pmd(pud, addr, next);
+ } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+ unsigned long next;
+
+ pgd += pgd_index(addr);
+ do {
+ next = pgd_addr_end(addr, end);
+ idmap_del_pud(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+#endif
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages. This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+ /*
+ * We need to access to user-mode page tables here. For kernel threads
+ * we don't have any user-mode mappings so we use the context that we
+ * "borrowed".
+ */
+ identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
+ local_flush_tlb_all();
+}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
new file mode 100644
index 00000000..4a4eba51
--- /dev/null
+++ b/arch/arm/mm/init.c
@@ -0,0 +1,744 @@
+/*
+ * linux/arch/arm/mm/init.c
+ *
+ * Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can 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/swap.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mman.h>
+#include <linux/nodemask.h>
+#include <linux/initrd.h>
+#include <linux/of_fdt.h>
+#include <linux/highmem.h>
+#include <linux/gfp.h>
+#include <linux/memblock.h>
+#include <linux/sort.h>
+
+#include <asm/mach-types.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/sizes.h>
+#include <asm/tlb.h>
+#include <asm/fixmap.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mm.h"
+
+static unsigned long phys_initrd_start __initdata = 0;
+static unsigned long phys_initrd_size __initdata = 0;
+
+static int __init early_initrd(char *p)
+{
+ unsigned long start, size;
+ char *endp;
+
+ start = memparse(p, &endp);
+ if (*endp == ',') {
+ size = memparse(endp + 1, NULL);
+
+ phys_initrd_start = start;
+ phys_initrd_size = size;
+ }
+ return 0;
+}
+early_param("initrd", early_initrd);
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+ printk(KERN_WARNING "ATAG_INITRD is deprecated; "
+ "please update your bootloader.\n");
+ phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
+ phys_initrd_size = tag->u.initrd.size;
+ return 0;
+}
+
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
+static int __init parse_tag_initrd2(const struct tag *tag)
+{
+ phys_initrd_start = tag->u.initrd.start;
+ phys_initrd_size = tag->u.initrd.size;
+ return 0;
+}
+
+__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+
+#ifdef CONFIG_OF_FLATTREE
+void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+{
+ phys_initrd_start = start;
+ phys_initrd_size = end - start;
+}
+#endif /* CONFIG_OF_FLATTREE */
+
+/*
+ * This keeps memory configuration data used by a couple memory
+ * initialization functions, as well as show_mem() for the skipping
+ * of holes in the memory map. It is populated by arm_add_memory().
+ */
+struct meminfo meminfo;
+
+void show_mem(unsigned int filter)
+{
+ int free = 0, total = 0, reserved = 0;
+ int shared = 0, cached = 0, slab = 0, i;
+ struct meminfo * mi = &meminfo;
+
+ printk("Mem-info:\n");
+ show_free_areas(filter);
+
+ for_each_bank (i, mi) {
+ struct membank *bank = &mi->bank[i];
+ unsigned int pfn1, pfn2;
+ struct page *page, *end;
+
+ pfn1 = bank_pfn_start(bank);
+ pfn2 = bank_pfn_end(bank);
+
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
+
+ do {
+ total++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (PageSlab(page))
+ slab++;
+ else if (!page_count(page))
+ free++;
+ else
+ shared += page_count(page) - 1;
+ page++;
+ } while (page < end);
+ }
+
+ printk("%d pages of RAM\n", total);
+ printk("%d free pages\n", free);
+ printk("%d reserved pages\n", reserved);
+ printk("%d slab pages\n", slab);
+ printk("%d pages shared\n", shared);
+ printk("%d pages swap cached\n", cached);
+}
+
+static void __init find_limits(unsigned long *min, unsigned long *max_low,
+ unsigned long *max_high)
+{
+ struct meminfo *mi = &meminfo;
+ int i;
+
+ *min = -1UL;
+ *max_low = *max_high = 0;
+
+ for_each_bank (i, mi) {
+ struct membank *bank = &mi->bank[i];
+ unsigned long start, end;
+
+ start = bank_pfn_start(bank);
+ end = bank_pfn_end(bank);
+
+ if (*min > start)
+ *min = start;
+ if (*max_high < end)
+ *max_high = end;
+ if (bank->highmem)
+ continue;
+ if (*max_low < end)
+ *max_low = end;
+ }
+}
+
+static void __init arm_bootmem_init(unsigned long start_pfn,
+ unsigned long end_pfn)
+{
+ struct memblock_region *reg;
+ unsigned int boot_pages;
+ phys_addr_t bitmap;
+ pg_data_t *pgdat;
+
+ /*
+ * Allocate the bootmem bitmap page. This must be in a region
+ * of memory which has already been mapped.
+ */
+ boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ bitmap = memblock_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+ __pfn_to_phys(end_pfn));
+
+ /*
+ * Initialise the bootmem allocator, handing the
+ * memory banks over to bootmem.
+ */
+ node_set_online(0);
+ pgdat = NODE_DATA(0);
+ init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
+
+ /* Free the lowmem regions from memblock into bootmem. */
+ for_each_memblock(memory, reg) {
+ unsigned long start = memblock_region_memory_base_pfn(reg);
+ unsigned long end = memblock_region_memory_end_pfn(reg);
+
+ if (end >= end_pfn)
+ end = end_pfn;
+ if (start >= end)
+ break;
+
+ free_bootmem(__pfn_to_phys(start), (end - start) << PAGE_SHIFT);
+ }
+
+ /* Reserve the lowmem memblock reserved regions in bootmem. */
+ for_each_memblock(reserved, reg) {
+ unsigned long start = memblock_region_reserved_base_pfn(reg);
+ unsigned long end = memblock_region_reserved_end_pfn(reg);
+
+ if (end >= end_pfn)
+ end = end_pfn;
+ if (start >= end)
+ break;
+
+ reserve_bootmem(__pfn_to_phys(start),
+ (end - start) << PAGE_SHIFT, BOOTMEM_DEFAULT);
+ }
+}
+
+#ifdef CONFIG_ZONE_DMA
+static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
+ unsigned long dma_size)
+{
+ if (size[0] <= dma_size)
+ return;
+
+ size[ZONE_NORMAL] = size[0] - dma_size;
+ size[ZONE_DMA] = dma_size;
+ hole[ZONE_NORMAL] = hole[0];
+ hole[ZONE_DMA] = 0;
+}
+#endif
+
+static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
+ unsigned long max_high)
+{
+ unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
+ struct memblock_region *reg;
+
+ /*
+ * initialise the zones.
+ */
+ memset(zone_size, 0, sizeof(zone_size));
+
+ /*
+ * The memory size has already been determined. If we need
+ * to do anything fancy with the allocation of this memory
+ * to the zones, now is the time to do it.
+ */
+ zone_size[0] = max_low - min;
+#ifdef CONFIG_HIGHMEM
+ zone_size[ZONE_HIGHMEM] = max_high - max_low;
+#endif
+
+ /*
+ * Calculate the size of the holes.
+ * holes = node_size - sum(bank_sizes)
+ */
+ memcpy(zhole_size, zone_size, sizeof(zhole_size));
+ for_each_memblock(memory, reg) {
+ unsigned long start = memblock_region_memory_base_pfn(reg);
+ unsigned long end = memblock_region_memory_end_pfn(reg);
+
+ if (start < max_low) {
+ unsigned long low_end = min(end, max_low);
+ zhole_size[0] -= low_end - start;
+ }
+#ifdef CONFIG_HIGHMEM
+ if (end > max_low) {
+ unsigned long high_start = max(start, max_low);
+ zhole_size[ZONE_HIGHMEM] -= end - high_start;
+ }
+#endif
+ }
+
+#ifdef ARM_DMA_ZONE_SIZE
+#ifndef CONFIG_ZONE_DMA
+#error ARM_DMA_ZONE_SIZE set but no DMA zone to limit allocations
+#endif
+
+ /*
+ * Adjust the sizes according to any special requirements for
+ * this machine type.
+ */
+ arm_adjust_dma_zone(zone_size, zhole_size,
+ ARM_DMA_ZONE_SIZE >> PAGE_SHIFT);
+#endif
+
+ free_area_init_node(0, zone_size, min, zhole_size);
+}
+
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
+int pfn_valid(unsigned long pfn)
+{
+ return memblock_is_memory(pfn << PAGE_SHIFT);
+}
+EXPORT_SYMBOL(pfn_valid);
+#endif
+
+#ifndef CONFIG_SPARSEMEM
+static void arm_memory_present(void)
+{
+}
+#else
+static void arm_memory_present(void)
+{
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg)
+ memory_present(0, memblock_region_memory_base_pfn(reg),
+ memblock_region_memory_end_pfn(reg));
+}
+#endif
+
+static int __init meminfo_cmp(const void *_a, const void *_b)
+{
+ const struct membank *a = _a, *b = _b;
+ long cmp = bank_pfn_start(a) - bank_pfn_start(b);
+ return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
+}
+
+void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
+{
+ int i;
+
+ sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
+
+ memblock_init();
+ for (i = 0; i < mi->nr_banks; i++)
+ memblock_add(mi->bank[i].start, mi->bank[i].size);
+
+ /* Register the kernel text, kernel data and initrd with memblock. */
+#ifdef CONFIG_XIP_KERNEL
+ memblock_reserve(__pa(_sdata), _end - _sdata);
+#else
+ memblock_reserve(__pa(_stext), _end - _stext);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (phys_initrd_size &&
+ !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
+ pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
+ phys_initrd_start, phys_initrd_size);
+ phys_initrd_start = phys_initrd_size = 0;
+ }
+ if (phys_initrd_size &&
+ memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
+ pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+ phys_initrd_start, phys_initrd_size);
+ phys_initrd_start = phys_initrd_size = 0;
+ }
+ if (phys_initrd_size) {
+ memblock_reserve(phys_initrd_start, phys_initrd_size);
+
+ /* Now convert initrd to virtual addresses */
+ initrd_start = __phys_to_virt(phys_initrd_start);
+ initrd_end = initrd_start + phys_initrd_size;
+ }
+#endif
+
+ arm_mm_memblock_reserve();
+ arm_dt_memblock_reserve();
+
+ /* reserve any platform specific memblock areas */
+ if (mdesc->reserve)
+ mdesc->reserve();
+
+ memblock_analyze();
+ memblock_dump_all();
+}
+
+void __init bootmem_init(void)
+{
+ unsigned long min, max_low, max_high;
+
+ max_low = max_high = 0;
+
+ find_limits(&min, &max_low, &max_high);
+
+ arm_bootmem_init(min, max_low);
+
+ /*
+ * Sparsemem tries to allocate bootmem in memory_present(),
+ * so must be done after the fixed reservations
+ */
+ arm_memory_present();
+
+ /*
+ * sparse_init() needs the bootmem allocator up and running.
+ */
+ sparse_init();
+
+ /*
+ * Now free the memory - free_area_init_node needs
+ * the sparse mem_map arrays initialized by sparse_init()
+ * for memmap_init_zone(), otherwise all PFNs are invalid.
+ */
+ arm_bootmem_free(min, max_low, max_high);
+
+ high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1;
+
+ /*
+ * This doesn't seem to be used by the Linux memory manager any
+ * more, but is used by ll_rw_block. If we can get rid of it, we
+ * also get rid of some of the stuff above as well.
+ *
+ * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
+ * the system, not the maximum PFN.
+ */
+ max_low_pfn = max_low - PHYS_PFN_OFFSET;
+ max_pfn = max_high - PHYS_PFN_OFFSET;
+}
+
+static inline int free_area(unsigned long pfn, unsigned long end, char *s)
+{
+ unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10);
+
+ for (; pfn < end; pfn++) {
+ struct page *page = pfn_to_page(pfn);
+ ClearPageReserved(page);
+ init_page_count(page);
+ __free_page(page);
+ pages++;
+ }
+
+ if (size && s)
+ printk(KERN_INFO "Freeing %s memory: %dK\n", s, size);
+
+ return pages;
+}
+
+static inline void
+free_memmap(unsigned long start_pfn, unsigned long end_pfn)
+{
+ struct page *start_pg, *end_pg;
+ unsigned long pg, pgend;
+
+ /*
+ * Convert start_pfn/end_pfn to a struct page pointer.
+ */
+ start_pg = pfn_to_page(start_pfn - 1) + 1;
+ end_pg = pfn_to_page(end_pfn - 1) + 1;
+
+ /*
+ * Convert to physical addresses, and
+ * round start upwards and end downwards.
+ */
+ pg = (unsigned long)PAGE_ALIGN(__pa(start_pg));
+ pgend = (unsigned long)__pa(end_pg) & PAGE_MASK;
+
+ /*
+ * If there are free pages between these,
+ * free the section of the memmap array.
+ */
+ if (pg < pgend)
+ free_bootmem(pg, pgend - pg);
+}
+
+/*
+ * The mem_map array can get very big. Free the unused area of the memory map.
+ */
+static void __init free_unused_memmap(struct meminfo *mi)
+{
+ unsigned long bank_start, prev_bank_end = 0;
+ unsigned int i;
+
+ /*
+ * This relies on each bank being in address order.
+ * The banks are sorted previously in bootmem_init().
+ */
+ for_each_bank(i, mi) {
+ struct membank *bank = &mi->bank[i];
+
+ bank_start = bank_pfn_start(bank);
+
+#ifdef CONFIG_SPARSEMEM
+ /*
+ * Take care not to free memmap entries that don't exist
+ * due to SPARSEMEM sections which aren't present.
+ */
+ bank_start = min(bank_start,
+ ALIGN(prev_bank_end, PAGES_PER_SECTION));
+#else
+ /*
+ * Align down here since the VM subsystem insists that the
+ * memmap entries are valid from the bank start aligned to
+ * MAX_ORDER_NR_PAGES.
+ */
+ bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES);
+#endif
+ /*
+ * If we had a previous bank, and there is a space
+ * between the current bank and the previous, free it.
+ */
+ if (prev_bank_end && prev_bank_end < bank_start)
+ free_memmap(prev_bank_end, bank_start);
+
+ /*
+ * Align up here since the VM subsystem insists that the
+ * memmap entries are valid from the bank end aligned to
+ * MAX_ORDER_NR_PAGES.
+ */
+ prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES);
+ }
+
+#ifdef CONFIG_SPARSEMEM
+ if (!IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION))
+ free_memmap(prev_bank_end,
+ ALIGN(prev_bank_end, PAGES_PER_SECTION));
+#endif
+}
+
+static void __init free_highpages(void)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long max_low = max_low_pfn + PHYS_PFN_OFFSET;
+ struct memblock_region *mem, *res;
+
+ /* set highmem page free */
+ for_each_memblock(memory, mem) {
+ unsigned long start = memblock_region_memory_base_pfn(mem);
+ unsigned long end = memblock_region_memory_end_pfn(mem);
+
+ /* Ignore complete lowmem entries */
+ if (end <= max_low)
+ continue;
+
+ /* Truncate partial highmem entries */
+ if (start < max_low)
+ start = max_low;
+
+ /* Find and exclude any reserved regions */
+ for_each_memblock(reserved, res) {
+ unsigned long res_start, res_end;
+
+ res_start = memblock_region_reserved_base_pfn(res);
+ res_end = memblock_region_reserved_end_pfn(res);
+
+ if (res_end < start)
+ continue;
+ if (res_start < start)
+ res_start = start;
+ if (res_start > end)
+ res_start = end;
+ if (res_end > end)
+ res_end = end;
+ if (res_start != start)
+ totalhigh_pages += free_area(start, res_start,
+ NULL);
+ start = res_end;
+ if (start == end)
+ break;
+ }
+
+ /* And now free anything which remains */
+ if (start < end)
+ totalhigh_pages += free_area(start, end, NULL);
+ }
+ totalram_pages += totalhigh_pages;
+#endif
+}
+
+/*
+ * mem_init() marks the free areas in the mem_map and tells us how much
+ * memory is free. This is done after various parts of the system have
+ * claimed their memory after the kernel image.
+ */
+void __init mem_init(void)
+{
+ unsigned long reserved_pages, free_pages;
+ struct memblock_region *reg;
+ int i;
+#ifdef CONFIG_HAVE_TCM
+ /* These pointers are filled in on TCM detection */
+ extern u32 dtcm_end;
+ extern u32 itcm_end;
+#endif
+
+ max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
+
+ /* this will put all unused low memory onto the freelists */
+ free_unused_memmap(&meminfo);
+
+ totalram_pages += free_all_bootmem();
+
+#ifdef CONFIG_SA1111
+ /* now that our DMA memory is actually so designated, we can free it */
+ totalram_pages += free_area(PHYS_PFN_OFFSET,
+ __phys_to_pfn(__pa(swapper_pg_dir)), NULL);
+#endif
+
+ free_highpages();
+
+ reserved_pages = free_pages = 0;
+
+ for_each_bank(i, &meminfo) {
+ struct membank *bank = &meminfo.bank[i];
+ unsigned int pfn1, pfn2;
+ struct page *page, *end;
+
+ pfn1 = bank_pfn_start(bank);
+ pfn2 = bank_pfn_end(bank);
+
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
+
+ do {
+ if (PageReserved(page))
+ reserved_pages++;
+ else if (!page_count(page))
+ free_pages++;
+ page++;
+ } while (page < end);
+ }
+
+ /*
+ * Since our memory may not be contiguous, calculate the
+ * real number of pages we have in this system
+ */
+ printk(KERN_INFO "Memory:");
+ num_physpages = 0;
+ for_each_memblock(memory, reg) {
+ unsigned long pages = memblock_region_memory_end_pfn(reg) -
+ memblock_region_memory_base_pfn(reg);
+ num_physpages += pages;
+ printk(" %ldMB", pages >> (20 - PAGE_SHIFT));
+ }
+ printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+
+ printk(KERN_NOTICE "Memory: %luk/%luk available, %luk reserved, %luK highmem\n",
+ nr_free_pages() << (PAGE_SHIFT-10),
+ free_pages << (PAGE_SHIFT-10),
+ reserved_pages << (PAGE_SHIFT-10),
+ totalhigh_pages << (PAGE_SHIFT-10));
+
+#define MLK(b, t) b, t, ((t) - (b)) >> 10
+#define MLM(b, t) b, t, ((t) - (b)) >> 20
+#define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K)
+
+ printk(KERN_NOTICE "Virtual kernel memory layout:\n"
+ " vector : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#ifdef CONFIG_HAVE_TCM
+ " DTCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
+ " ITCM : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#endif
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
+#ifdef CONFIG_MMU
+ " DMA : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#ifdef CONFIG_HIGHMEM
+ " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n"
+#endif
+ " modules : 0x%08lx - 0x%08lx (%4ld MB)\n"
+ " .init : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .text : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .data : 0x%p" " - 0x%p" " (%4d kB)\n"
+ " .bss : 0x%p" " - 0x%p" " (%4d kB)\n",
+
+ MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
+ (PAGE_SIZE)),
+#ifdef CONFIG_HAVE_TCM
+ MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
+ MLK(ITCM_OFFSET, (unsigned long) itcm_end),
+#endif
+ MLK(FIXADDR_START, FIXADDR_TOP),
+#ifdef CONFIG_MMU
+ MLM(CONSISTENT_BASE, CONSISTENT_END),
+#endif
+ MLM(VMALLOC_START, VMALLOC_END),
+ MLM(PAGE_OFFSET, (unsigned long)high_memory),
+#ifdef CONFIG_HIGHMEM
+ MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) *
+ (PAGE_SIZE)),
+#endif
+ MLM(MODULES_VADDR, MODULES_END),
+
+ MLK_ROUNDUP(__init_begin, __init_end),
+ MLK_ROUNDUP(_text, _etext),
+ MLK_ROUNDUP(_sdata, _edata),
+ MLK_ROUNDUP(__bss_start, __bss_stop));
+
+#undef MLK
+#undef MLM
+#undef MLK_ROUNDUP
+
+ /*
+ * Check boundaries twice: Some fundamental inconsistencies can
+ * be detected at build time already.
+ */
+#ifdef CONFIG_MMU
+ BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);
+ BUG_ON(VMALLOC_END > CONSISTENT_BASE);
+
+ BUILD_BUG_ON(TASK_SIZE > MODULES_VADDR);
+ BUG_ON(TASK_SIZE > MODULES_VADDR);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+ BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
+ BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > PAGE_OFFSET);
+#endif
+
+ if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
+ extern int sysctl_overcommit_memory;
+ /*
+ * On a machine this small we won't get
+ * anywhere without overcommit, so turn
+ * it on by default.
+ */
+ sysctl_overcommit_memory = OVERCOMMIT_ALWAYS;
+ }
+}
+
+void free_initmem(void)
+{
+#ifdef CONFIG_HAVE_TCM
+ extern char __tcm_start, __tcm_end;
+
+ totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)),
+ __phys_to_pfn(__pa(&__tcm_end)),
+ "TCM link");
+#endif
+
+ if (!machine_is_integrator() && !machine_is_cintegrator())
+ totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)),
+ __phys_to_pfn(__pa(__init_end)),
+ "init");
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+
+static int keep_initrd;
+
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (!keep_initrd)
+ totalram_pages += free_area(__phys_to_pfn(__pa(start)),
+ __phys_to_pfn(__pa(end)),
+ "initrd");
+}
+
+static int __init keepinitrd_setup(char *__unused)
+{
+ keep_initrd = 1;
+ return 1;
+}
+
+__setup("keepinitrd", keepinitrd_setup);
+#endif
diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c
new file mode 100644
index 00000000..ffad039c
--- /dev/null
+++ b/arch/arm/mm/iomap.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mm/iomap.c
+ *
+ * Map IO port and PCI memory spaces so that {read,write}[bwl] can
+ * be used to access this memory.
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#ifdef __io
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+ return __io(port);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_unmap);
+#endif
+
+#ifdef CONFIG_PCI
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ resource_size_t start = pci_resource_start(dev, bar);
+ resource_size_t len = pci_resource_len(dev, bar);
+ unsigned long flags = pci_resource_flags(dev, bar);
+
+ if (!len || !start)
+ return NULL;
+ if (maxlen && len > maxlen)
+ len = maxlen;
+ if (flags & IORESOURCE_IO)
+ return ioport_map(start, len);
+ if (flags & IORESOURCE_MEM) {
+ if (flags & IORESOURCE_CACHEABLE)
+ return ioremap(start, len);
+ return ioremap_nocache(start, len);
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+ if ((unsigned long)addr >= VMALLOC_START &&
+ (unsigned long)addr < VMALLOC_END)
+ iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
+#endif
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
new file mode 100644
index 00000000..ab506272
--- /dev/null
+++ b/arch/arm/mm/ioremap.c
@@ -0,0 +1,320 @@
+/*
+ * linux/arch/arm/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ *
+ * Hacked for ARM by Phil Blundell <philb@gnu.org>
+ * Hacked to allow all architectures to build, and various cleanups
+ * by Russell King
+ *
+ * This allows a driver to remap an arbitrary region of bus memory into
+ * virtual space. One should *only* use readl, writel, memcpy_toio and
+ * so on with such remapped areas.
+ *
+ * Because the ARM only has a 32-bit address space we can't address the
+ * whole of the (physical) PCI space at once. PCI huge-mode addressing
+ * allows us to circumvent this restriction by splitting PCI space into
+ * two 2GB chunks and mapping only one at a time into processor memory.
+ * We use MMU protection domains to trap any attempt to access the bank
+ * that is not currently mapped. (This isn't fully implemented yet.)
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/cacheflush.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/sizes.h>
+
+#include <asm/mach/map.h>
+#include "mm.h"
+
+/*
+ * Used by ioremap() and iounmap() code to mark (super)section-mapped
+ * I/O regions in vm_struct->flags field.
+ */
+#define VM_ARM_SECTION_MAPPING 0x80000000
+
+int ioremap_page(unsigned long virt, unsigned long phys,
+ const struct mem_type *mtype)
+{
+ return ioremap_page_range(virt, virt + PAGE_SIZE, phys,
+ __pgprot(mtype->prot_pte));
+}
+EXPORT_SYMBOL(ioremap_page);
+
+void __check_kvm_seq(struct mm_struct *mm)
+{
+ unsigned int seq;
+
+ do {
+ seq = init_mm.context.kvm_seq;
+ memcpy(pgd_offset(mm, VMALLOC_START),
+ pgd_offset_k(VMALLOC_START),
+ sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
+ pgd_index(VMALLOC_START)));
+ mm->context.kvm_seq = seq;
+ } while (seq != init_mm.context.kvm_seq);
+}
+
+#ifndef CONFIG_SMP
+/*
+ * Section support is unsafe on SMP - If you iounmap and ioremap a region,
+ * the other CPUs will not see this change until their next context switch.
+ * Meanwhile, (eg) if an interrupt comes in on one of those other CPUs
+ * which requires the new ioremap'd region to be referenced, the CPU will
+ * reference the _old_ region.
+ *
+ * Note that get_vm_area_caller() allocates a guard 4K page, so we need to
+ * mask the size back to 1MB aligned or we will overflow in the loop below.
+ */
+static void unmap_area_sections(unsigned long virt, unsigned long size)
+{
+ unsigned long addr = virt, end = virt + (size & ~(SZ_1M - 1));
+ pgd_t *pgd;
+
+ flush_cache_vunmap(addr, end);
+ pgd = pgd_offset_k(addr);
+ do {
+ pmd_t pmd, *pmdp = pmd_offset(pgd, addr);
+
+ pmd = *pmdp;
+ if (!pmd_none(pmd)) {
+ /*
+ * Clear the PMD from the page table, and
+ * increment the kvm sequence so others
+ * notice this change.
+ *
+ * Note: this is still racy on SMP machines.
+ */
+ pmd_clear(pmdp);
+ init_mm.context.kvm_seq++;
+
+ /*
+ * Free the page table, if there was one.
+ */
+ if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE)
+ pte_free_kernel(&init_mm, pmd_page_vaddr(pmd));
+ }
+
+ addr += PGDIR_SIZE;
+ pgd++;
+ } while (addr < end);
+
+ /*
+ * Ensure that the active_mm is up to date - we want to
+ * catch any use-after-iounmap cases.
+ */
+ if (current->active_mm->context.kvm_seq != init_mm.context.kvm_seq)
+ __check_kvm_seq(current->active_mm);
+
+ flush_tlb_kernel_range(virt, end);
+}
+
+static int
+remap_area_sections(unsigned long virt, unsigned long pfn,
+ size_t size, const struct mem_type *type)
+{
+ unsigned long addr = virt, end = virt + size;
+ pgd_t *pgd;
+
+ /*
+ * Remove and free any PTE-based mapping, and
+ * sync the current kernel mapping.
+ */
+ unmap_area_sections(virt, size);
+
+ pgd = pgd_offset_k(addr);
+ do {
+ pmd_t *pmd = pmd_offset(pgd, addr);
+
+ pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
+ pfn += SZ_1M >> PAGE_SHIFT;
+ pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect);
+ pfn += SZ_1M >> PAGE_SHIFT;
+ flush_pmd_entry(pmd);
+
+ addr += PGDIR_SIZE;
+ pgd++;
+ } while (addr < end);
+
+ return 0;
+}
+
+static int
+remap_area_supersections(unsigned long virt, unsigned long pfn,
+ size_t size, const struct mem_type *type)
+{
+ unsigned long addr = virt, end = virt + size;
+ pgd_t *pgd;
+
+ /*
+ * Remove and free any PTE-based mapping, and
+ * sync the current kernel mapping.
+ */
+ unmap_area_sections(virt, size);
+
+ pgd = pgd_offset_k(virt);
+ do {
+ unsigned long super_pmd_val, i;
+
+ super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect |
+ PMD_SECT_SUPER;
+ super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20;
+
+ for (i = 0; i < 8; i++) {
+ pmd_t *pmd = pmd_offset(pgd, addr);
+
+ pmd[0] = __pmd(super_pmd_val);
+ pmd[1] = __pmd(super_pmd_val);
+ flush_pmd_entry(pmd);
+
+ addr += PGDIR_SIZE;
+ pgd++;
+ }
+
+ pfn += SUPERSECTION_SIZE >> PAGE_SHIFT;
+ } while (addr < end);
+
+ return 0;
+}
+#endif
+
+void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
+ unsigned long offset, size_t size, unsigned int mtype, void *caller)
+{
+ const struct mem_type *type;
+ int err;
+ unsigned long addr;
+ struct vm_struct * area;
+
+ /*
+ * High mappings must be supersection aligned
+ */
+ if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
+ return NULL;
+
+ /*
+ * Don't allow RAM to be mapped - this causes problems with ARMv6+
+ */
+ if (WARN_ON(pfn_valid(pfn)))
+ return NULL;
+
+ type = get_mem_type(mtype);
+ if (!type)
+ return NULL;
+
+ /*
+ * Page align the mapping size, taking account of any offset.
+ */
+ size = PAGE_ALIGN(offset + size);
+
+ area = get_vm_area_caller(size, VM_IOREMAP, caller);
+ if (!area)
+ return NULL;
+ addr = (unsigned long)area->addr;
+
+#ifndef CONFIG_SMP
+ if (DOMAIN_IO == 0 &&
+ (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) ||
+ cpu_is_xsc3()) && pfn >= 0x100000 &&
+ !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) {
+ area->flags |= VM_ARM_SECTION_MAPPING;
+ err = remap_area_supersections(addr, pfn, size, type);
+ } else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) {
+ area->flags |= VM_ARM_SECTION_MAPPING;
+ err = remap_area_sections(addr, pfn, size, type);
+ } else
+#endif
+ err = ioremap_page_range(addr, addr + size, __pfn_to_phys(pfn),
+ __pgprot(type->prot_pte));
+
+ if (err) {
+ vunmap((void *)addr);
+ return NULL;
+ }
+
+ flush_cache_vmap(addr, addr + size);
+ return (void __iomem *) (offset + addr);
+}
+
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ unsigned long last_addr;
+ unsigned long offset = phys_addr & ~PAGE_MASK;
+ unsigned long pfn = __phys_to_pfn(phys_addr);
+
+ /*
+ * Don't allow wraparound or zero size
+ */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+ caller);
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+void __iomem *
+__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
+ unsigned int mtype)
+{
+ return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__arm_ioremap_pfn);
+
+void __iomem *
+__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+ return __arm_ioremap_caller(phys_addr, size, mtype,
+ __builtin_return_address(0));
+}
+EXPORT_SYMBOL(__arm_ioremap);
+
+void __iounmap(volatile void __iomem *io_addr)
+{
+ void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
+#ifndef CONFIG_SMP
+ struct vm_struct **p, *tmp;
+
+ /*
+ * If this is a section based mapping we need to handle it
+ * specially as the VM subsystem does not know how to handle
+ * such a beast. We need the lock here b/c we need to clear
+ * all the mappings before the area can be reclaimed
+ * by someone else.
+ */
+ write_lock(&vmlist_lock);
+ for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
+ if ((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) {
+ if (tmp->flags & VM_ARM_SECTION_MAPPING) {
+ unmap_area_sections((unsigned long)tmp->addr,
+ tmp->size);
+ }
+ break;
+ }
+ }
+ write_unlock(&vmlist_lock);
+#endif
+
+ vunmap(addr);
+}
+EXPORT_SYMBOL(__iounmap);
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
new file mode 100644
index 00000000..5b3d7d54
--- /dev/null
+++ b/arch/arm/mm/mm.h
@@ -0,0 +1,27 @@
+#ifdef CONFIG_MMU
+
+/* the upper-most page table pointer */
+extern pmd_t *top_pmd;
+
+#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+ return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt);
+}
+
+struct mem_type {
+ pteval_t prot_pte;
+ unsigned int prot_l1;
+ unsigned int prot_sect;
+ unsigned int domain;
+};
+
+const struct mem_type *get_mem_type(unsigned int type);
+
+extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
+#endif
+
+void __init bootmem_init(void);
+void arm_mm_memblock_reserve(void);
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
new file mode 100644
index 00000000..74be05f3
--- /dev/null
+++ b/arch/arm/mm/mmap.c
@@ -0,0 +1,170 @@
+/*
+ * linux/arch/arm/mm/mmap.c
+ */
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/shm.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <linux/personality.h>
+#include <linux/random.h>
+#include <asm/cputype.h>
+#include <asm/system.h>
+
+#define COLOUR_ALIGN(addr,pgoff) \
+ ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
+ (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
+
+/*
+ * We need to ensure that shared mappings are correctly aligned to
+ * avoid aliasing issues with VIPT caches. We need to ensure that
+ * a specific page of an object is always mapped at a multiple of
+ * SHMLBA bytes.
+ *
+ * We unconditionally provide this function for all cases, however
+ * in the VIVT case, we optimise out the alignment rules.
+ */
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long start_addr;
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+ unsigned int cache_type;
+ int do_align = 0, aliasing = 0;
+
+ /*
+ * We only need to do colour alignment if either the I or D
+ * caches alias. This is indicated by bits 9 and 21 of the
+ * cache type register.
+ */
+ cache_type = read_cpuid_cachetype();
+ if (cache_type != read_cpuid_id()) {
+ aliasing = (cache_type | cache_type >> 12) & (1 << 11);
+ if (aliasing)
+ do_align = filp || flags & MAP_SHARED;
+ }
+#else
+#define do_align 0
+#define aliasing 0
+#endif
+
+ /*
+ * We enforce the MAP_FIXED case.
+ */
+ if (flags & MAP_FIXED) {
+ if (aliasing && flags & MAP_SHARED &&
+ (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
+ return -EINVAL;
+ return addr;
+ }
+
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
+ if (addr) {
+ if (do_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
+
+ vma = find_vma(mm, addr);
+ if (TASK_SIZE - len >= addr &&
+ (!vma || addr + len <= vma->vm_start))
+ return addr;
+ }
+ if (len > mm->cached_hole_size) {
+ start_addr = addr = mm->free_area_cache;
+ } else {
+ start_addr = addr = TASK_UNMAPPED_BASE;
+ mm->cached_hole_size = 0;
+ }
+ /* 8 bits of randomness in 20 address space bits */
+ if ((current->flags & PF_RANDOMIZE) &&
+ !(current->personality & ADDR_NO_RANDOMIZE))
+ addr += (get_random_int() % (1 << 8)) << PAGE_SHIFT;
+
+full_search:
+ if (do_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
+
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (TASK_SIZE - len < addr) {
+ /*
+ * Start a new search - just in case we missed
+ * some holes.
+ */
+ if (start_addr != TASK_UNMAPPED_BASE) {
+ start_addr = addr = TASK_UNMAPPED_BASE;
+ mm->cached_hole_size = 0;
+ goto full_search;
+ }
+ return -ENOMEM;
+ }
+ if (!vma || addr + len <= vma->vm_start) {
+ /*
+ * Remember the place where we stopped the search:
+ */
+ mm->free_area_cache = addr + len;
+ return addr;
+ }
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+ addr = vma->vm_end;
+ if (do_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ }
+}
+
+
+/*
+ * You really shouldn't be using read() or write() on /dev/mem. This
+ * might go away in the future.
+ */
+int valid_phys_addr_range(unsigned long addr, size_t size)
+{
+ if (addr < PHYS_OFFSET)
+ return 0;
+ if (addr + size > __pa(high_memory - 1) + 1)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * We don't use supersection mappings for mmap() on /dev/mem, which
+ * means that we can't map the memory area above the 4G barrier into
+ * userspace.
+ */
+int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
+{
+ return !(pfn + (size >> PAGE_SHIFT) > 0x00100000);
+}
+
+#ifdef CONFIG_STRICT_DEVMEM
+
+#include <linux/ioport.h>
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain
+ * address is valid. The argument is a physical page number.
+ * We mimic x86 here by disallowing access to system RAM as well as
+ * device-exclusive MMIO regions. This effectively disable read()/write()
+ * on /dev/mem.
+ */
+int devmem_is_allowed(unsigned long pfn)
+{
+ if (iomem_is_exclusive(pfn << PAGE_SHIFT))
+ return 0;
+ if (!page_is_ram(pfn))
+ return 1;
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
new file mode 100644
index 00000000..594d677b
--- /dev/null
+++ b/arch/arm/mm/mmu.c
@@ -0,0 +1,1052 @@
+/*
+ * linux/arch/arm/mm/mmu.c
+ *
+ * Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/init.h>
+#include <linux/mman.h>
+#include <linux/nodemask.h>
+#include <linux/memblock.h>
+#include <linux/fs.h>
+
+#include <asm/cputype.h>
+#include <asm/sections.h>
+#include <asm/cachetype.h>
+#include <asm/setup.h>
+#include <asm/sizes.h>
+#include <asm/smp_plat.h>
+#include <asm/tlb.h>
+#include <asm/highmem.h>
+#include <asm/traps.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "mm.h"
+
+/*
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
+ */
+struct page *empty_zero_page;
+EXPORT_SYMBOL(empty_zero_page);
+
+/*
+ * The pmd table for the upper-most set of pages.
+ */
+pmd_t *top_pmd;
+
+#define CPOLICY_UNCACHED 0
+#define CPOLICY_BUFFERED 1
+#define CPOLICY_WRITETHROUGH 2
+#define CPOLICY_WRITEBACK 3
+#define CPOLICY_WRITEALLOC 4
+
+static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
+static unsigned int ecc_mask __initdata = 0;
+pgprot_t pgprot_user;
+pgprot_t pgprot_kernel;
+
+EXPORT_SYMBOL(pgprot_user);
+EXPORT_SYMBOL(pgprot_kernel);
+
+struct cachepolicy {
+ const char policy[16];
+ unsigned int cr_mask;
+ unsigned int pmd;
+ pteval_t pte;
+};
+
+static struct cachepolicy cache_policies[] __initdata = {
+ {
+ .policy = "uncached",
+ .cr_mask = CR_W|CR_C,
+ .pmd = PMD_SECT_UNCACHED,
+ .pte = L_PTE_MT_UNCACHED,
+ }, {
+ .policy = "buffered",
+ .cr_mask = CR_C,
+ .pmd = PMD_SECT_BUFFERED,
+ .pte = L_PTE_MT_BUFFERABLE,
+ }, {
+ .policy = "writethrough",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WT,
+ .pte = L_PTE_MT_WRITETHROUGH,
+ }, {
+ .policy = "writeback",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WB,
+ .pte = L_PTE_MT_WRITEBACK,
+ }, {
+ .policy = "writealloc",
+ .cr_mask = 0,
+ .pmd = PMD_SECT_WBWA,
+ .pte = L_PTE_MT_WRITEALLOC,
+ }
+};
+
+/*
+ * These are useful for identifying cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off. (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static int __init early_cachepolicy(char *p)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
+ int len = strlen(cache_policies[i].policy);
+
+ if (memcmp(p, cache_policies[i].policy, len) == 0) {
+ cachepolicy = i;
+ cr_alignment &= ~cache_policies[i].cr_mask;
+ cr_no_alignment &= ~cache_policies[i].cr_mask;
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(cache_policies))
+ printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
+ /*
+ * This restriction is partly to do with the way we boot; it is
+ * unpredictable to have memory mapped using two different sets of
+ * memory attributes (shared, type, and cache attribs). We can not
+ * change these attributes once the initial assembly has setup the
+ * page tables.
+ */
+ if (cpu_architecture() >= CPU_ARCH_ARMv6) {
+ printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
+ cachepolicy = CPOLICY_WRITEBACK;
+ }
+ flush_cache_all();
+ set_cr(cr_alignment);
+ return 0;
+}
+early_param("cachepolicy", early_cachepolicy);
+
+static int __init early_nocache(char *__unused)
+{
+ char *p = "buffered";
+ printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
+ early_cachepolicy(p);
+ return 0;
+}
+early_param("nocache", early_nocache);
+
+static int __init early_nowrite(char *__unused)
+{
+ char *p = "uncached";
+ printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
+ early_cachepolicy(p);
+ return 0;
+}
+early_param("nowb", early_nowrite);
+
+static int __init early_ecc(char *p)
+{
+ if (memcmp(p, "on", 2) == 0)
+ ecc_mask = PMD_PROTECTION;
+ else if (memcmp(p, "off", 3) == 0)
+ ecc_mask = 0;
+ return 0;
+}
+early_param("ecc", early_ecc);
+
+static int __init noalign_setup(char *__unused)
+{
+ cr_alignment &= ~CR_A;
+ cr_no_alignment &= ~CR_A;
+ set_cr(cr_alignment);
+ return 1;
+}
+__setup("noalign", noalign_setup);
+
+#ifndef CONFIG_SMP
+void adjust_cr(unsigned long mask, unsigned long set)
+{
+ unsigned long flags;
+
+ mask &= ~CR_A;
+
+ set &= mask;
+
+ local_irq_save(flags);
+
+ cr_no_alignment = (cr_no_alignment & ~mask) | set;
+ cr_alignment = (cr_alignment & ~mask) | set;
+
+ set_cr((get_cr() & ~mask) | set);
+
+ local_irq_restore(flags);
+}
+#endif
+
+#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
+#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
+
+static struct mem_type mem_types[] = {
+ [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
+ L_PTE_SHARED,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_S,
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_NONSHARED,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE,
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_CACHED] = { /* ioremap_cached */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,
+ .domain = DOMAIN_IO,
+ },
+ [MT_DEVICE_WC] = { /* ioremap_wc */
+ .prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PROT_SECT_DEVICE,
+ .domain = DOMAIN_IO,
+ },
+ [MT_UNCACHED] = {
+ .prot_pte = PROT_PTE_DEVICE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_IO,
+ },
+ [MT_CACHECLEAN] = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MINICLEAN] = {
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_LOW_VECTORS] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_RDONLY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_USER,
+ },
+ [MT_HIGH_VECTORS] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_USER | L_PTE_RDONLY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_USER,
+ },
+ [MT_MEMORY] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_ROM] = {
+ .prot_sect = PMD_TYPE_SECT,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_NONCACHED] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_MT_BUFFERABLE,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_DTCM] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_XN,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
+ .domain = DOMAIN_KERNEL,
+ },
+ [MT_MEMORY_ITCM] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
+ .prot_l1 = PMD_TYPE_TABLE,
+ .domain = DOMAIN_KERNEL,
+ },
+};
+
+const struct mem_type *get_mem_type(unsigned int type)
+{
+ return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL;
+}
+EXPORT_SYMBOL(get_mem_type);
+
+/*
+ * Adjust the PMD section entries according to the CPU in use.
+ */
+static void __init build_mem_type_table(void)
+{
+ struct cachepolicy *cp;
+ unsigned int cr = get_cr();
+ unsigned int user_pgprot, kern_pgprot, vecs_pgprot;
+ int cpu_arch = cpu_architecture();
+ int i;
+
+ if (cpu_arch < CPU_ARCH_ARMv6) {
+#if defined(CONFIG_CPU_DCACHE_DISABLE)
+ if (cachepolicy > CPOLICY_BUFFERED)
+ cachepolicy = CPOLICY_BUFFERED;
+#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
+ if (cachepolicy > CPOLICY_WRITETHROUGH)
+ cachepolicy = CPOLICY_WRITETHROUGH;
+#endif
+ }
+ if (cpu_arch < CPU_ARCH_ARMv5) {
+ if (cachepolicy >= CPOLICY_WRITEALLOC)
+ cachepolicy = CPOLICY_WRITEBACK;
+ ecc_mask = 0;
+ }
+ if (is_smp())
+ cachepolicy = CPOLICY_WRITEALLOC;
+
+ /*
+ * Strip out features not present on earlier architectures.
+ * Pre-ARMv5 CPUs don't have TEX bits. Pre-ARMv6 CPUs or those
+ * without extended page tables don't have the 'Shared' bit.
+ */
+ if (cpu_arch < CPU_ARCH_ARMv5)
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+ mem_types[i].prot_sect &= ~PMD_SECT_TEX(7);
+ if ((cpu_arch < CPU_ARCH_ARMv6 || !(cr & CR_XP)) && !cpu_is_xsc3())
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+ mem_types[i].prot_sect &= ~PMD_SECT_S;
+
+ /*
+ * ARMv5 and lower, bit 4 must be set for page tables (was: cache
+ * "update-able on write" bit on ARM610). However, Xscale and
+ * Xscale3 require this bit to be cleared.
+ */
+ if (cpu_is_xscale() || cpu_is_xsc3()) {
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+ mem_types[i].prot_sect &= ~PMD_BIT4;
+ mem_types[i].prot_l1 &= ~PMD_BIT4;
+ }
+ } else if (cpu_arch < CPU_ARCH_ARMv6) {
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+ if (mem_types[i].prot_l1)
+ mem_types[i].prot_l1 |= PMD_BIT4;
+ if (mem_types[i].prot_sect)
+ mem_types[i].prot_sect |= PMD_BIT4;
+ }
+ }
+
+ /*
+ * Mark the device areas according to the CPU/architecture.
+ */
+ if (cpu_is_xsc3() || (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP))) {
+ if (!cpu_is_xsc3()) {
+ /*
+ * Mark device regions on ARMv6+ as execute-never
+ * to prevent speculative instruction fetches.
+ */
+ mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
+ mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN;
+ mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN;
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN;
+ }
+ if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ /*
+ * For ARMv7 with TEX remapping,
+ * - shared device is SXCB=1100
+ * - nonshared device is SXCB=0100
+ * - write combine device mem is SXCB=0001
+ * (Uncached Normal memory)
+ */
+ mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1);
+ mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(1);
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
+ } else if (cpu_is_xsc3()) {
+ /*
+ * For Xscale3,
+ * - shared device is TEXCB=00101
+ * - nonshared device is TEXCB=01000
+ * - write combine device mem is TEXCB=00100
+ * (Inner/Outer Uncacheable in xsc3 parlance)
+ */
+ mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1) | PMD_SECT_BUFFERED;
+ mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(2);
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_TEX(1);
+ } else {
+ /*
+ * For ARMv6 and ARMv7 without TEX remapping,
+ * - shared device is TEXCB=00001
+ * - nonshared device is TEXCB=01000
+ * - write combine device mem is TEXCB=00100
+ * (Uncached Normal in ARMv6 parlance).
+ */
+ mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
+ mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(2);
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_TEX(1);
+ }
+ } else {
+ /*
+ * On others, write combining is "Uncached/Buffered"
+ */
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
+ }
+
+ /*
+ * Now deal with the memory-type mappings
+ */
+ cp = &cache_policies[cachepolicy];
+ vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
+
+ /*
+ * Only use write-through for non-SMP systems
+ */
+ if (!is_smp() && cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH)
+ vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte;
+
+ /*
+ * Enable CPU-specific coherency if supported.
+ * (Only available on XSC3 at the moment.)
+ */
+ if (arch_is_coherent() && cpu_is_xsc3()) {
+ mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
+ /*
+ * ARMv6 and above have extended page tables.
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
+ /*
+ * Mark cache clean areas and XIP ROM read only
+ * from SVC mode and no access from userspace.
+ */
+ mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+ mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
+
+ if (is_smp()) {
+ /*
+ * Mark memory with the "shared" attribute
+ * for SMP systems
+ */
+ user_pgprot |= L_PTE_SHARED;
+ kern_pgprot |= L_PTE_SHARED;
+ vecs_pgprot |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
+ }
+
+ /*
+ * Non-cacheable Normal - intended for memory areas that must
+ * not cause dirty cache line writebacks when used
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6) {
+ if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
+ /* Non-cacheable Normal is XCB = 001 */
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+ PMD_SECT_BUFFERED;
+ } else {
+ /* For both ARMv6 and non-TEX-remapping ARMv7 */
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |=
+ PMD_SECT_TEX(1);
+ }
+ } else {
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
+ }
+
+ for (i = 0; i < 16; i++) {
+ unsigned long v = pgprot_val(protection_map[i]);
+ protection_map[i] = __pgprot(v | user_pgprot);
+ }
+
+ mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
+ mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
+
+ pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
+ pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+ L_PTE_DIRTY | kern_pgprot);
+
+ mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
+ mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
+ mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
+ mem_types[MT_ROM].prot_sect |= cp->pmd;
+
+ switch (cp->pmd) {
+ case PMD_SECT_WT:
+ mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
+ break;
+ case PMD_SECT_WB:
+ case PMD_SECT_WBWA:
+ mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
+ break;
+ }
+ printk("Memory policy: ECC %sabled, Data cache %s\n",
+ ecc_mask ? "en" : "dis", cp->policy);
+
+ for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+ struct mem_type *t = &mem_types[i];
+ if (t->prot_l1)
+ t->prot_l1 |= PMD_DOMAIN(t->domain);
+ if (t->prot_sect)
+ t->prot_sect |= PMD_DOMAIN(t->domain);
+ }
+}
+
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ unsigned long size, pgprot_t vma_prot)
+{
+ if (!pfn_valid(pfn))
+ return pgprot_noncached(vma_prot);
+ else if (file->f_flags & O_SYNC)
+ return pgprot_writecombine(vma_prot);
+ return vma_prot;
+}
+EXPORT_SYMBOL(phys_mem_access_prot);
+#endif
+
+#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
+
+static void __init *early_alloc(unsigned long sz)
+{
+ void *ptr = __va(memblock_alloc(sz, sz));
+ memset(ptr, 0, sz);
+ return ptr;
+}
+
+static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
+{
+ if (pmd_none(*pmd)) {
+ pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
+ __pmd_populate(pmd, __pa(pte), prot);
+ }
+ BUG_ON(pmd_bad(*pmd));
+ return pte_offset_kernel(pmd, addr);
+}
+
+static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
+ unsigned long end, unsigned long pfn,
+ const struct mem_type *type)
+{
+ pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
+ do {
+ set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
+ pfn++;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+}
+
+static void __init alloc_init_section(pud_t *pud, unsigned long addr,
+ unsigned long end, phys_addr_t phys,
+ const struct mem_type *type)
+{
+ pmd_t *pmd = pmd_offset(pud, addr);
+
+ /*
+ * Try a section mapping - end, addr and phys must all be aligned
+ * to a section boundary. Note that PMDs refer to the individual
+ * L1 entries, whereas PGDs refer to a group of L1 entries making
+ * up one logical pointer to an L2 table.
+ */
+ if (((addr | end | phys) & ~SECTION_MASK) == 0) {
+ pmd_t *p = pmd;
+
+ if (addr & SECTION_SIZE)
+ pmd++;
+
+ do {
+ *pmd = __pmd(phys | type->prot_sect);
+ phys += SECTION_SIZE;
+ } while (pmd++, addr += SECTION_SIZE, addr != end);
+
+ flush_pmd_entry(p);
+ } else {
+ /*
+ * No need to loop; pte's aren't interested in the
+ * individual L1 entries.
+ */
+ alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
+ }
+}
+
+static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+ unsigned long phys, const struct mem_type *type)
+{
+ pud_t *pud = pud_offset(pgd, addr);
+ unsigned long next;
+
+ do {
+ next = pud_addr_end(addr, end);
+ alloc_init_section(pud, addr, next, phys, type);
+ phys += next - addr;
+ } while (pud++, addr = next, addr != end);
+}
+
+static void __init create_36bit_mapping(struct map_desc *md,
+ const struct mem_type *type)
+{
+ unsigned long addr, length, end;
+ phys_addr_t phys;
+ pgd_t *pgd;
+
+ addr = md->virtual;
+ phys = __pfn_to_phys(md->pfn);
+ length = PAGE_ALIGN(md->length);
+
+ if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
+ printk(KERN_ERR "MM: CPU does not support supersection "
+ "mapping for 0x%08llx at 0x%08lx\n",
+ (long long)__pfn_to_phys((u64)md->pfn), addr);
+ return;
+ }
+
+ /* N.B. ARMv6 supersections are only defined to work with domain 0.
+ * Since domain assignments can in fact be arbitrary, the
+ * 'domain == 0' check below is required to insure that ARMv6
+ * supersections are only allocated for domain 0 regardless
+ * of the actual domain assignments in use.
+ */
+ if (type->domain) {
+ printk(KERN_ERR "MM: invalid domain in supersection "
+ "mapping for 0x%08llx at 0x%08lx\n",
+ (long long)__pfn_to_phys((u64)md->pfn), addr);
+ return;
+ }
+
+ if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
+ printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
+ " at 0x%08lx invalid alignment\n",
+ (long long)__pfn_to_phys((u64)md->pfn), addr);
+ return;
+ }
+
+ /*
+ * Shift bits [35:32] of address into bits [23:20] of PMD
+ * (See ARMv6 spec).
+ */
+ phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
+
+ pgd = pgd_offset_k(addr);
+ end = addr + length;
+ do {
+ pud_t *pud = pud_offset(pgd, addr);
+ pmd_t *pmd = pmd_offset(pud, addr);
+ int i;
+
+ for (i = 0; i < 16; i++)
+ *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER);
+
+ addr += SUPERSECTION_SIZE;
+ phys += SUPERSECTION_SIZE;
+ pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT;
+ } while (addr != end);
+}
+
+/*
+ * Create the page directory entries and any necessary
+ * page tables for the mapping specified by `md'. We
+ * are able to cope here with varying sizes and address
+ * offsets, and we take full advantage of sections and
+ * supersections.
+ */
+static void __init create_mapping(struct map_desc *md)
+{
+ unsigned long addr, length, end;
+ phys_addr_t phys;
+ const struct mem_type *type;
+ pgd_t *pgd;
+
+ if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
+ printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
+ " at 0x%08lx in user region\n",
+ (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
+ return;
+ }
+
+ if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
+ md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
+ printk(KERN_WARNING "BUG: mapping for 0x%08llx"
+ " at 0x%08lx overlaps vmalloc space\n",
+ (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
+ }
+
+ type = &mem_types[md->type];
+
+ /*
+ * Catch 36-bit addresses
+ */
+ if (md->pfn >= 0x100000) {
+ create_36bit_mapping(md, type);
+ return;
+ }
+
+ addr = md->virtual & PAGE_MASK;
+ phys = __pfn_to_phys(md->pfn);
+ length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
+
+ if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
+ printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
+ "be mapped using pages, ignoring.\n",
+ (long long)__pfn_to_phys(md->pfn), addr);
+ return;
+ }
+
+ pgd = pgd_offset_k(addr);
+ end = addr + length;
+ do {
+ unsigned long next = pgd_addr_end(addr, end);
+
+ alloc_init_pud(pgd, addr, next, phys, type);
+
+ phys += next - addr;
+ addr = next;
+ } while (pgd++, addr != end);
+}
+
+/*
+ * Create the architecture specific mappings
+ */
+void __init iotable_init(struct map_desc *io_desc, int nr)
+{
+ int i;
+
+ for (i = 0; i < nr; i++)
+ create_mapping(io_desc + i);
+}
+
+static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
+
+/*
+ * vmalloc=size forces the vmalloc area to be exactly 'size'
+ * bytes. This can be used to increase (or decrease) the vmalloc
+ * area - the default is 128m.
+ */
+static int __init early_vmalloc(char *arg)
+{
+ unsigned long vmalloc_reserve = memparse(arg, NULL);
+
+ if (vmalloc_reserve < SZ_16M) {
+ vmalloc_reserve = SZ_16M;
+ printk(KERN_WARNING
+ "vmalloc area too small, limiting to %luMB\n",
+ vmalloc_reserve >> 20);
+ }
+
+ if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
+ vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
+ printk(KERN_WARNING
+ "vmalloc area is too big, limiting to %luMB\n",
+ vmalloc_reserve >> 20);
+ }
+
+ vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve);
+ return 0;
+}
+early_param("vmalloc", early_vmalloc);
+
+static phys_addr_t lowmem_limit __initdata = 0;
+
+void __init sanity_check_meminfo(void)
+{
+ int i, j, highmem = 0;
+
+ for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
+ struct membank *bank = &meminfo.bank[j];
+ *bank = meminfo.bank[i];
+
+#ifdef CONFIG_HIGHMEM
+ if (__va(bank->start) >= vmalloc_min ||
+ __va(bank->start) < (void *)PAGE_OFFSET)
+ highmem = 1;
+
+ bank->highmem = highmem;
+
+ /*
+ * Split those memory banks which are partially overlapping
+ * the vmalloc area greatly simplifying things later.
+ */
+ if (__va(bank->start) < vmalloc_min &&
+ bank->size > vmalloc_min - __va(bank->start)) {
+ if (meminfo.nr_banks >= NR_BANKS) {
+ printk(KERN_CRIT "NR_BANKS too low, "
+ "ignoring high memory\n");
+ } else {
+ memmove(bank + 1, bank,
+ (meminfo.nr_banks - i) * sizeof(*bank));
+ meminfo.nr_banks++;
+ i++;
+ bank[1].size -= vmalloc_min - __va(bank->start);
+ bank[1].start = __pa(vmalloc_min - 1) + 1;
+ bank[1].highmem = highmem = 1;
+ j++;
+ }
+ bank->size = vmalloc_min - __va(bank->start);
+ }
+#else
+ bank->highmem = highmem;
+
+ /*
+ * Check whether this memory bank would entirely overlap
+ * the vmalloc area.
+ */
+ if (__va(bank->start) >= vmalloc_min ||
+ __va(bank->start) < (void *)PAGE_OFFSET) {
+ printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
+ "(vmalloc region overlap).\n",
+ (unsigned long long)bank->start,
+ (unsigned long long)bank->start + bank->size - 1);
+ continue;
+ }
+
+ /*
+ * Check whether this memory bank would partially overlap
+ * the vmalloc area.
+ */
+ if (__va(bank->start + bank->size) > vmalloc_min ||
+ __va(bank->start + bank->size) < __va(bank->start)) {
+ unsigned long newsize = vmalloc_min - __va(bank->start);
+ printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
+ "to -%.8llx (vmalloc region overlap).\n",
+ (unsigned long long)bank->start,
+ (unsigned long long)bank->start + bank->size - 1,
+ (unsigned long long)bank->start + newsize - 1);
+ bank->size = newsize;
+ }
+#endif
+ if (!bank->highmem && bank->start + bank->size > lowmem_limit)
+ lowmem_limit = bank->start + bank->size;
+
+ j++;
+ }
+#ifdef CONFIG_HIGHMEM
+ if (highmem) {
+ const char *reason = NULL;
+
+ if (cache_is_vipt_aliasing()) {
+ /*
+ * Interactions between kmap and other mappings
+ * make highmem support with aliasing VIPT caches
+ * rather difficult.
+ */
+ reason = "with VIPT aliasing cache";
+ }
+ if (reason) {
+ printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
+ reason);
+ while (j > 0 && meminfo.bank[j - 1].highmem)
+ j--;
+ }
+ }
+#endif
+ meminfo.nr_banks = j;
+ memblock_set_current_limit(lowmem_limit);
+}
+
+static inline void prepare_page_table(void)
+{
+ unsigned long addr;
+ phys_addr_t end;
+
+ /*
+ * Clear out all the mappings below the kernel image.
+ */
+ for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+
+#ifdef CONFIG_XIP_KERNEL
+ /* The XIP kernel is mapped in the module area -- skip over it */
+ addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK;
+#endif
+ for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+
+ /*
+ * Find the end of the first block of lowmem.
+ */
+ end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
+ if (end >= lowmem_limit)
+ end = lowmem_limit;
+
+ /*
+ * Clear out all the kernel space mappings, except for the first
+ * memory bank, up to the end of the vmalloc region.
+ */
+ for (addr = __phys_to_virt(end);
+ addr < VMALLOC_END; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+}
+
+/*
+ * Reserve the special regions of memory
+ */
+void __init arm_mm_memblock_reserve(void)
+{
+ /*
+ * Reserve the page tables. These are already in use,
+ * and can only be in node 0.
+ */
+ memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
+
+#ifdef CONFIG_SA1111
+ /*
+ * Because of the SA1111 DMA bug, we want to preserve our
+ * precious DMA-able memory...
+ */
+ memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+#endif
+}
+
+/*
+ * Set up device the mappings. Since we clear out the page tables for all
+ * mappings above VMALLOC_END, we will remove any debug device mappings.
+ * This means you have to be careful how you debug this function, or any
+ * called function. This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
+ */
+static void __init devicemaps_init(struct machine_desc *mdesc)
+{
+ struct map_desc map;
+ unsigned long addr;
+
+ /*
+ * Allocate the vector page early.
+ */
+ vectors_page = early_alloc(PAGE_SIZE);
+
+ for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
+ pmd_clear(pmd_off_k(addr));
+
+ /*
+ * Map the kernel if it is XIP.
+ * It is always first in the modulearea.
+ */
+#ifdef CONFIG_XIP_KERNEL
+ map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+ map.virtual = MODULES_VADDR;
+ map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+ map.type = MT_ROM;
+ create_mapping(&map);
+#endif
+
+ /*
+ * Map the cache flushing regions.
+ */
+#ifdef FLUSH_BASE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
+ map.virtual = FLUSH_BASE;
+ map.length = SZ_1M;
+ map.type = MT_CACHECLEAN;
+ create_mapping(&map);
+#endif
+#ifdef FLUSH_BASE_MINICACHE
+ map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
+ map.virtual = FLUSH_BASE_MINICACHE;
+ map.length = SZ_1M;
+ map.type = MT_MINICLEAN;
+ create_mapping(&map);
+#endif
+
+ /*
+ * Create a mapping for the machine vectors at the high-vectors
+ * location (0xffff0000). If we aren't using high-vectors, also
+ * create a mapping at the low-vectors virtual address.
+ */
+ map.pfn = __phys_to_pfn(virt_to_phys(vectors_page));
+ map.virtual = 0xffff0000;
+ map.length = PAGE_SIZE;
+ map.type = MT_HIGH_VECTORS;
+ create_mapping(&map);
+
+ if (!vectors_high()) {
+ map.virtual = 0;
+ map.type = MT_LOW_VECTORS;
+ create_mapping(&map);
+ }
+
+ /*
+ * Ask the machine support to map in the statically mapped devices.
+ */
+ if (mdesc->map_io)
+ mdesc->map_io();
+
+ /*
+ * Finally flush the caches and tlb to ensure that we're in a
+ * consistent state wrt the writebuffer. This also ensures that
+ * any write-allocated cache lines in the vector page are written
+ * back. After this point, we can start to touch devices again.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+}
+
+static void __init kmap_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+ pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
+ PKMAP_BASE, _PAGE_KERNEL_TABLE);
+#endif
+}
+
+static void __init map_lowmem(void)
+{
+ struct memblock_region *reg;
+
+ /* Map all the lowmem memory banks. */
+ for_each_memblock(memory, reg) {
+ phys_addr_t start = reg->base;
+ phys_addr_t end = start + reg->size;
+ struct map_desc map;
+
+ if (end > lowmem_limit)
+ end = lowmem_limit;
+ if (start >= end)
+ break;
+
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = end - start;
+ map.type = MT_MEMORY;
+
+ create_mapping(&map);
+ }
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct machine_desc *mdesc)
+{
+ void *zero_page;
+
+ memblock_set_current_limit(lowmem_limit);
+
+ build_mem_type_table();
+ prepare_page_table();
+ map_lowmem();
+ devicemaps_init(mdesc);
+ kmap_init();
+
+ top_pmd = pmd_off_k(0xffff0000);
+
+ /* allocate the zero page. */
+ zero_page = early_alloc(PAGE_SIZE);
+
+ bootmem_init();
+
+ empty_zero_page = virt_to_page(zero_page);
+ __flush_dcache_page(NULL, empty_zero_page);
+}
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
new file mode 100644
index 00000000..941a98c9
--- /dev/null
+++ b/arch/arm/mm/nommu.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/mm/nommu.c
+ *
+ * ARM uCLinux supporting functions.
+ */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/io.h>
+#include <linux/memblock.h>
+
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+
+#include "mm.h"
+
+void __init arm_mm_memblock_reserve(void)
+{
+ /*
+ * Register the exception vector page.
+ * some architectures which the DRAM is the exception vector to trap,
+ * alloc_page breaks with error, although it is not NULL, but "0."
+ */
+ memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
+}
+
+void __init sanity_check_meminfo(void)
+{
+}
+
+/*
+ * paging_init() sets up the page tables, initialises the zone memory
+ * maps, and sets up the zero page, bad page and bad page tables.
+ */
+void __init paging_init(struct machine_desc *mdesc)
+{
+ bootmem_init();
+}
+
+/*
+ * We don't need to do anything here for nommu machines.
+ */
+void setup_mm_for_reboot(char mode)
+{
+}
+
+void flush_dcache_page(struct page *page)
+{
+ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+}
+EXPORT_SYMBOL(flush_dcache_page);
+
+void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
+ unsigned long uaddr, void *dst, const void *src,
+ unsigned long len)
+{
+ memcpy(dst, src, len);
+ if (vma->vm_flags & VM_EXEC)
+ __cpuc_coherent_user_range(uaddr, uaddr + len);
+}
+
+void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
+ size_t size, unsigned int mtype)
+{
+ if (pfn >= (0x100000000ULL >> PAGE_SHIFT))
+ return NULL;
+ return (void __iomem *) (offset + (pfn << PAGE_SHIFT));
+}
+EXPORT_SYMBOL(__arm_ioremap_pfn);
+
+void __iomem *__arm_ioremap_pfn_caller(unsigned long pfn, unsigned long offset,
+ size_t size, unsigned int mtype, void *caller)
+{
+ return __arm_ioremap_pfn(pfn, offset, size, mtype);
+}
+
+void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
+ unsigned int mtype)
+{
+ return (void __iomem *)phys_addr;
+}
+EXPORT_SYMBOL(__arm_ioremap);
+
+void __iomem *__arm_ioremap_caller(unsigned long phys_addr, size_t size,
+ unsigned int mtype, void *caller)
+{
+ return __arm_ioremap(phys_addr, size, mtype);
+}
+
+void __iounmap(volatile void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(__iounmap);
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S
new file mode 100644
index 00000000..87970eba
--- /dev/null
+++ b/arch/arm/mm/pabort-legacy.S
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: legacy_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = Simulated IFSR with section translation fault status
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(legacy_pabort)
+ mov r1, #5
+ mov pc, lr
+ENDPROC(legacy_pabort)
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S
new file mode 100644
index 00000000..06e3d1ef
--- /dev/null
+++ b/arch/arm/mm/pabort-v6.S
@@ -0,0 +1,19 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(v6_pabort)
+ mrc p15, 0, r1, c5, c0, 1 @ get IFSR
+ mov pc, lr
+ENDPROC(v6_pabort)
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S
new file mode 100644
index 00000000..a8b3b300
--- /dev/null
+++ b/arch/arm/mm/pabort-v7.S
@@ -0,0 +1,20 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Function: v6_pabort
+ *
+ * Params : r0 = address of aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = IFSR
+ *
+ * Purpose : obtain information about current prefetch abort.
+ */
+
+ .align 5
+ENTRY(v7_pabort)
+ mrc p15, 0, r0, c6, c0, 2 @ get IFAR
+ mrc p15, 0, r1, c5, c0, 1 @ get IFSR
+ mov pc, lr
+ENDPROC(v7_pabort)
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
new file mode 100644
index 00000000..b2027c15
--- /dev/null
+++ b/arch/arm/mm/pgd.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/arm/mm/pgd.c
+ *
+ * Copyright (C) 1998-2005 Russell King
+ *
+ * This program is free software; you can 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/gfp.h>
+#include <linux/highmem.h>
+
+#include <asm/pgalloc.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+
+#include "mm.h"
+
+/*
+ * need to get a 16k page for level 1
+ */
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *new_pgd, *init_pgd;
+ pud_t *new_pud, *init_pud;
+ pmd_t *new_pmd, *init_pmd;
+ pte_t *new_pte, *init_pte;
+
+ new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2);
+ if (!new_pgd)
+ goto no_pgd;
+
+ memset(new_pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
+
+ /*
+ * Copy over the kernel and IO PGD entries
+ */
+ init_pgd = pgd_offset_k(0);
+ memcpy(new_pgd + USER_PTRS_PER_PGD, init_pgd + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+ clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+
+ if (!vectors_high()) {
+ /*
+ * On ARM, first page must always be allocated since it
+ * contains the machine vectors.
+ */
+ new_pud = pud_alloc(mm, new_pgd, 0);
+ if (!new_pud)
+ goto no_pud;
+
+ new_pmd = pmd_alloc(mm, new_pud, 0);
+ if (!new_pmd)
+ goto no_pmd;
+
+ new_pte = pte_alloc_map(mm, NULL, new_pmd, 0);
+ if (!new_pte)
+ goto no_pte;
+
+ init_pud = pud_offset(init_pgd, 0);
+ init_pmd = pmd_offset(init_pud, 0);
+ init_pte = pte_offset_map(init_pmd, 0);
+ set_pte_ext(new_pte, *init_pte, 0);
+ pte_unmap(init_pte);
+ pte_unmap(new_pte);
+ }
+
+ return new_pgd;
+
+no_pte:
+ pmd_free(mm, new_pmd);
+no_pmd:
+ pud_free(mm, new_pud);
+no_pud:
+ free_pages((unsigned long)new_pgd, 2);
+no_pgd:
+ return NULL;
+}
+
+void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pgtable_t pte;
+
+ if (!pgd_base)
+ return;
+
+ pgd = pgd_base + pgd_index(0);
+ if (pgd_none_or_clear_bad(pgd))
+ goto no_pgd;
+
+ pud = pud_offset(pgd, 0);
+ if (pud_none_or_clear_bad(pud))
+ goto no_pud;
+
+ pmd = pmd_offset(pud, 0);
+ if (pmd_none_or_clear_bad(pmd))
+ goto no_pmd;
+
+ pte = pmd_pgtable(*pmd);
+ pmd_clear(pmd);
+ pte_free(mm, pte);
+no_pmd:
+ pud_clear(pud);
+ pmd_free(mm, pmd);
+no_pud:
+ pgd_clear(pgd);
+ pud_free(mm, pud);
+no_pgd:
+ free_pages((unsigned long) pgd_base, 2);
+}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
new file mode 100644
index 00000000..6c4e7fd6
--- /dev/null
+++ b/arch/arm/mm/proc-arm1020.S
@@ -0,0 +1,559 @@
+/*
+ * linux/arch/arm/mm/proc-arm1020.S: MMU functions for ARM1020
+ *
+ * Copyright (C) 2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm1020.
+ *
+ * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 16
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 32768
+
+ .text
+/*
+ * cpu_arm1020_proc_init()
+ */
+ENTRY(cpu_arm1020_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm1020_proc_fin()
+ */
+ENTRY(cpu_arm1020_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm1020_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm1020_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm1020_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1020_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+ .align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1020_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(arm1020_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm1020_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 15 to 0
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags for this space
+ */
+ENTRY(arm1020_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, ip, c7, c10, 4
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020_coherent_kern_range)
+ /* FALLTRHOUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020_coherent_user_range)
+ mov ip, #0
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcr p15, 0, ip, c7, c10, 4
+1:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm1020_flush_kern_dcache_area)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1020_dma_inv_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, ip, c7, c10, 4
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, ip, c7, c10, 4
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1020_dma_clean_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020_dma_flush_range)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcr p15, 0, ip, c7, c10, 4
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm1020_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm1020_dma_clean_range
+ bcs arm1020_dma_inv_range
+ b arm1020_dma_flush_range
+ENDPROC(arm1020_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ .align 5
+ENTRY(cpu_arm1020_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov ip, #0
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1020_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm1020_switch_mm)
+#ifdef CONFIG_MMU
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r3, c7, c10, 4
+ mov r1, #0xF @ 16 segments
+1: mov r3, #0x3F @ 64 entries
+2: mov ip, r3, LSL #26 @ shift up entry
+ orr ip, ip, r1, LSL #5 @ shift in/up index
+ mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry
+ mov ip, #0
+ mcr p15, 0, ip, c7, c10, 4
+ subs r3, r3, #1
+ cmp r3, #0
+ bge 2b @ entries 3F to 0
+ subs r1, r1, #1
+ cmp r1, #0
+ bge 1b @ segments 15 to 0
+
+#endif
+ mov r1, #0
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
+#endif
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+/*
+ * cpu_arm1020_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm1020_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 4
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm1020_setup, #function
+__arm1020_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+
+ adr r5, arm1020_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .R.. .... .... ....
+#endif
+ mov pc, lr
+ .size __arm1020_setup, . - __arm1020_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..11 0101
+ */
+ .type arm1020_crval, #object
+arm1020_crval:
+ crval clear=0x0000593f, mmuset=0x00003935, ucset=0x00001930
+
+ __INITDATA
+
+/*
+ * 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
+
+ .type cpu_arm1020_name, #object
+cpu_arm1020_name:
+ .ascii "ARM1020"
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ .ascii "i"
+#endif
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ .ascii "d"
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ .ascii "(wt)"
+#else
+ .ascii "(wb)"
+#endif
+#endif
+#ifndef CONFIG_CPU_BPREDICT_DISABLE
+ .ascii "B"
+#endif
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ .ascii "RR"
+#endif
+ .ascii "\0"
+ .size cpu_arm1020_name, . - cpu_arm1020_name
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm1020_proc_info,#object
+__arm1020_proc_info:
+ .long 0x4104a200 @ ARM 1020T (Architecture v5T)
+ .long 0xff0ffff0
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ .long PMD_TYPE_SECT | \
+ PMD_SECT_AP_WRITE | \
+ PMD_SECT_AP_READ
+ b __arm1020_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+ .long cpu_arm1020_name
+ .long arm1020_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long arm1020_cache_fns
+ .size __arm1020_proc_info, . - __arm1020_proc_info
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
new file mode 100644
index 00000000..4ce947c1
--- /dev/null
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -0,0 +1,524 @@
+/*
+ * linux/arch/arm/mm/proc-arm1020e.S: MMU functions for ARM1020
+ *
+ * Copyright (C) 2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm1020e.
+ *
+ * CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 16
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 32768
+
+ .text
+/*
+ * cpu_arm1020e_proc_init()
+ */
+ENTRY(cpu_arm1020e_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm1020e_proc_fin()
+ */
+ENTRY(cpu_arm1020e_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm1020e_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm1020e_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm1020e_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1020e_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+ .align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1020e_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1020e_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(arm1020e_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm1020e_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 15 to 0
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags for this space
+ */
+ENTRY(arm1020e_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020e_coherent_kern_range)
+ /* FALLTHROUGH */
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020e_coherent_user_range)
+ mov ip, #0
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm1020e_flush_kern_dcache_area)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1020e_dma_inv_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1020e_dma_clean_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1020e_dma_flush_range)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm1020e_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm1020e_dma_clean_range
+ bcs arm1020e_dma_inv_range
+ b arm1020e_dma_flush_range
+ENDPROC(arm1020e_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ .align 5
+ENTRY(cpu_arm1020e_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov ip, #0
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1020e_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm1020e_switch_mm)
+#ifdef CONFIG_MMU
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r3, c7, c10, 4
+ mov r1, #0xF @ 16 segments
+1: mov r3, #0x3F @ 64 entries
+2: mov ip, r3, LSL #26 @ shift up entry
+ orr ip, ip, r1, LSL #5 @ shift in/up index
+ mcr p15, 0, ip, c7, c14, 2 @ Clean & Inval DCache entry
+ mov ip, #0
+ subs r3, r3, #1
+ cmp r3, #0
+ bge 2b @ entries 3F to 0
+ subs r1, r1, #1
+ cmp r1, #0
+ bge 1b @ segments 15 to 0
+
+#endif
+ mov r1, #0
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
+#endif
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm1020e_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm1020e_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm1020e_setup, #function
+__arm1020e_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ adr r5, arm1020e_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .R.. .... .... ....
+#endif
+ mov pc, lr
+ .size __arm1020e_setup, . - __arm1020e_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..11 0101
+ */
+ .type arm1020e_crval, #object
+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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm1020e_proc_info,#object
+__arm1020e_proc_info:
+ .long 0x4105a200 @ ARM 1020TE (Architecture v5TE)
+ .long 0xff0ffff0
+ .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 __arm1020e_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP
+ .long cpu_arm1020e_name
+ .long arm1020e_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long arm1020e_cache_fns
+ .size __arm1020e_proc_info, . - __arm1020e_proc_info
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
new file mode 100644
index 00000000..c8884c54
--- /dev/null
+++ b/arch/arm/mm/proc-arm1022.S
@@ -0,0 +1,507 @@
+/*
+ * linux/arch/arm/mm/proc-arm1022.S: MMU functions for ARM1022E
+ *
+ * Copyright (C) 2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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.
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM1022E.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 16
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 32768
+
+ .text
+/*
+ * cpu_arm1022_proc_init()
+ */
+ENTRY(cpu_arm1022_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm1022_proc_fin()
+ */
+ENTRY(cpu_arm1022_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm1022_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm1022_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm1022_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1022_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+ .align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1022_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1022_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(arm1022_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm1022_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 15 to 0
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags for this space
+ */
+ENTRY(arm1022_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1022_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1022_coherent_user_range)
+ mov ip, #0
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm1022_flush_kern_dcache_area)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1022_dma_inv_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1022_dma_clean_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1022_dma_flush_range)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm1022_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm1022_dma_clean_range
+ bcs arm1022_dma_inv_range
+ b arm1022_dma_flush_range
+ENDPROC(arm1022_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ .align 5
+ENTRY(cpu_arm1022_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov ip, #0
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1022_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm1022_switch_mm)
+#ifdef CONFIG_MMU
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 15 to 0
+#endif
+ mov r1, #0
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
+#endif
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm1022_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm1022_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm1022_setup, #function
+__arm1022_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ adr r5, arm1022_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .R..............
+#endif
+ mov pc, lr
+ .size __arm1022_setup, . - __arm1022_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..11 0101
+ *
+ */
+ .type arm1022_crval, #object
+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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm1022_proc_info,#object
+__arm1022_proc_info:
+ .long 0x4105a220 @ ARM 1022E (v5TE)
+ .long 0xff0ffff0
+ .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 __arm1022_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_EDSP
+ .long cpu_arm1022_name
+ .long arm1022_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long arm1022_cache_fns
+ .size __arm1022_proc_info, . - __arm1022_proc_info
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
new file mode 100644
index 00000000..41368466
--- /dev/null
+++ b/arch/arm/mm/proc-arm1026.S
@@ -0,0 +1,503 @@
+/*
+ * linux/arch/arm/mm/proc-arm1026.S: MMU functions for ARM1026EJ-S
+ *
+ * Copyright (C) 2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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.
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM1026EJ-S.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 16
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 32768
+
+ .text
+/*
+ * cpu_arm1026_proc_init()
+ */
+ENTRY(cpu_arm1026_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm1026_proc_fin()
+ */
+ENTRY(cpu_arm1026_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm1026_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm1026_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm1026_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm1026_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+ .align 5
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm1026_flush_icache_all)
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+#endif
+ mov pc, lr
+ENDPROC(arm1026_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(arm1026_flush_user_cache_all)
+ /* FALLTHROUGH */
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm1026_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
+ bne 1b
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags for this space
+ */
+ENTRY(arm1026_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ tst r2, #VM_EXEC
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+#endif
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1026_coherent_kern_range)
+ /* FALLTHROUGH */
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1026_coherent_user_range)
+ mov ip, #0
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm1026_flush_kern_dcache_area)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1026_dma_inv_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm1026_dma_clean_range:
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm1026_dma_flush_range)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm1026_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm1026_dma_clean_range
+ bcs arm1026_dma_inv_range
+ b arm1026_dma_flush_range
+ENDPROC(arm1026_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ .align 5
+ENTRY(cpu_arm1026_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mov ip, #0
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm1026_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm1026_switch_mm)
+#ifdef CONFIG_MMU
+ mov r1, #0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate
+ bne 1b
+#endif
+#ifndef CONFIG_CPU_ICACHE_DISABLE
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
+#endif
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm1026_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm1026_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+
+ __CPUINIT
+
+ .type __arm1026_setup, #function
+__arm1026_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+#endif
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #4 @ explicitly disable writeback
+ mcr p15, 7, r0, c15, c0, 0
+#endif
+ adr r5, arm1026_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .R.. .... .... ....
+#endif
+ mov pc, lr
+ .size __arm1026_setup, . - __arm1026_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..11 0101
+ *
+ */
+ .type arm1026_crval, #object
+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
+
+ .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
+ .align
+
+ .type cpu_arm1026_name, #object
+cpu_arm1026_name:
+ .asciz "ARM1026EJ-S"
+ .size cpu_arm1026_name, . - cpu_arm1026_name
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm1026_proc_info,#object
+__arm1026_proc_info:
+ .long 0x4106a260 @ ARM 1026EJ-S (v5TEJ)
+ .long 0xff0ffff0
+ .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 __arm1026_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
+ .long cpu_arm1026_name
+ .long arm1026_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long arm1026_cache_fns
+ .size __arm1026_proc_info, . - __arm1026_proc_info
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
new file mode 100644
index 00000000..5f79dc4c
--- /dev/null
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -0,0 +1,427 @@
+/*
+ * linux/arch/arm/mm/proc-arm6,7.S
+ *
+ * Copyright (C) 1997-2000 Russell King
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM610 & ARM710.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+ENTRY(cpu_arm6_dcache_clean_area)
+ENTRY(cpu_arm7_dcache_clean_area)
+ mov pc, lr
+
+/*
+ * Function: arm6_7_data_abort ()
+ *
+ * Params : r2 = address of aborted instruction
+ * : sp = pointer to registers
+ *
+ * Purpose : obtain information about current aborted instruction
+ *
+ * Returns : r0 = address of abort
+ * : r1 = FSR
+ */
+
+ENTRY(cpu_arm7_data_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ ldr r8, [r2] @ read arm instruction
+ tst r8, #1 << 20 @ L = 0 -> write?
+ orreq r1, r1, #1 << 11 @ yes.
+ and r7, r8, #15 << 24
+ add pc, pc, r7, lsr #22 @ Now branch to the relevant processing routine
+ nop
+
+/* 0 */ b .data_unknown
+/* 1 */ mov pc, lr @ swp
+/* 2 */ b .data_unknown
+/* 3 */ b .data_unknown
+/* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m
+/* 5 */ b .data_arm_lateldrpreconst @ ldr rd, [rn, #m]
+/* 6 */ b .data_arm_lateldrpostreg @ ldr rd, [rn], rm
+/* 7 */ b .data_arm_lateldrprereg @ ldr rd, [rn, rm]
+/* 8 */ b .data_arm_ldmstm @ ldm*a rn, <rlist>
+/* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist>
+/* a */ b .data_unknown
+/* b */ b .data_unknown
+/* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m
+/* d */ mov pc, lr @ ldc rd, [rn, #m]
+/* e */ b .data_unknown
+/* f */
+.data_unknown: @ Part of jumptable
+ mov r0, r2
+ mov r1, r8
+ mov r2, sp
+ bl baddataabort
+ b ret_from_exception
+
+ENTRY(cpu_arm6_data_abort)
+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ ldr r8, [r2] @ read arm instruction
+ tst r8, #1 << 20 @ L = 0 -> write?
+ orreq r1, r1, #1 << 11 @ yes.
+ and r7, r8, #14 << 24
+ teq r7, #8 << 24 @ was it ldm/stm
+ movne pc, lr
+
+.data_arm_ldmstm:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+ mov r7, #0x11
+ orr r7, r7, #0x1100
+ and r6, r8, r7
+ and r2, r8, r7, lsl #1
+ add r6, r6, r2, lsr #1
+ and r2, r8, r7, lsl #2
+ add r6, r6, r2, lsr #2
+ and r2, r8, r7, lsl #3
+ add r6, r6, r2, lsr #3
+ add r6, r6, r6, lsr #8
+ add r6, r6, r6, lsr #4
+ and r6, r6, #15 @ r6 = no. of registers to transfer.
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r6, lsl #2 @ Undo increment
+ addeq r7, r7, r6, lsl #2 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_apply_r6_and_rn:
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r6 @ Undo incrmenet
+ addeq r7, r7, r6 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_lateldrpreconst:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+.data_arm_lateldrpostconst:
+ movs r2, r8, lsl #20 @ Get offset
+ moveq pc, lr @ zero -> no fixup
+ and r5, r8, #15 << 16 @ Extract 'n' from instruction
+ ldr r7, [sp, r5, lsr #14] @ Get register 'Rn'
+ tst r8, #1 << 23 @ Check U bit
+ subne r7, r7, r2, lsr #20 @ Undo increment
+ addeq r7, r7, r2, lsr #20 @ Undo decrement
+ str r7, [sp, r5, lsr #14] @ Put register 'Rn'
+ mov pc, lr
+
+.data_arm_lateldrprereg:
+ tst r8, #1 << 21 @ check writeback bit
+ moveq pc, lr @ no writeback -> no fixup
+.data_arm_lateldrpostreg:
+ and r7, r8, #15 @ Extract 'm' from instruction
+ ldr r6, [sp, r7, lsl #2] @ Get register 'Rm'
+ mov r5, r8, lsr #7 @ get shift count
+ ands r5, r5, #31
+ and r7, r8, #0x70 @ get shift type
+ orreq r7, r7, #8 @ shift count = 0
+ add pc, pc, r7
+ nop
+
+ mov r6, r6, lsl r5 @ 0: LSL #!0
+ b .data_arm_apply_r6_and_rn
+ b .data_arm_apply_r6_and_rn @ 1: LSL #0
+ nop
+ b .data_unknown @ 2: MUL?
+ nop
+ b .data_unknown @ 3: MUL?
+ nop
+ mov r6, r6, lsr r5 @ 4: LSR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, lsr #32 @ 5: LSR #32
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ 6: MUL?
+ nop
+ b .data_unknown @ 7: MUL?
+ nop
+ mov r6, r6, asr r5 @ 8: ASR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, asr #32 @ 9: ASR #32
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ A: MUL?
+ nop
+ b .data_unknown @ B: MUL?
+ nop
+ mov r6, r6, ror r5 @ C: ROR #!0
+ b .data_arm_apply_r6_and_rn
+ mov r6, r6, rrx @ D: RRX
+ b .data_arm_apply_r6_and_rn
+ b .data_unknown @ E: MUL?
+ nop
+ b .data_unknown @ F: MUL?
+
+/*
+ * Function: arm6_7_proc_init (void)
+ * : arm6_7_proc_fin (void)
+ *
+ * Notes : This processor does not require these
+ */
+ENTRY(cpu_arm6_proc_init)
+ENTRY(cpu_arm7_proc_init)
+ mov pc, lr
+
+ENTRY(cpu_arm6_proc_fin)
+ENTRY(cpu_arm7_proc_fin)
+ mov r0, #0x31 @ ....S..DP...M
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+ENTRY(cpu_arm6_do_idle)
+ENTRY(cpu_arm7_do_idle)
+ mov pc, lr
+
+/*
+ * Function: arm6_7_switch_mm(unsigned long pgd_phys)
+ * Params : pgd_phys Physical address of page table
+ * Purpose : Perform a task switch, saving the old processes state, and restoring
+ * the new.
+ */
+ENTRY(cpu_arm6_switch_mm)
+ENTRY(cpu_arm7_switch_mm)
+#ifdef CONFIG_MMU
+ mov r1, #0
+ mcr p15, 0, r1, c7, c0, 0 @ flush cache
+ mcr p15, 0, r0, c2, c0, 0 @ update page table ptr
+ mcr p15, 0, r1, c5, c0, 0 @ flush TLBs
+#endif
+ mov pc, lr
+
+/*
+ * Function: arm6_7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
+ * Params : r0 = Address to set
+ * : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+ .align 5
+ENTRY(cpu_arm6_set_pte_ext)
+ENTRY(cpu_arm7_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext wc_disable=0
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+/*
+ * Function: _arm6_7_reset
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm6_reset)
+ENTRY(cpu_arm7_reset)
+ mov r1, #0
+ mcr p15, 0, r1, c7, c0, 0 @ flush cache
+#ifdef CONFIG_MMU
+ mcr p15, 0, r1, c5, c0, 0 @ flush TLB
+#endif
+ mov r1, #0x30
+ mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc
+ mov pc, r0
+
+ __CPUINIT
+
+ .type __arm6_setup, #function
+__arm6_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+ mov r0, #0x3d @ . ..RS BLDP WCAM
+ orr r0, r0, #0x100 @ . ..01 0011 1101
+#else
+ mov r0, #0x3c @ . ..RS BLDP WCA.
+#endif
+ mov pc, lr
+ .size __arm6_setup, . - __arm6_setup
+
+ .type __arm7_setup, #function
+__arm7_setup: mov r0, #0
+ mcr p15, 0, r0, c7, c0 @ flush caches on v3
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c5, c0 @ flush TLBs on v3
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mov r0, #0x7d @ . ..RS BLDP WCAM
+ orr r0, r0, #0x100 @ . ..01 0111 1101
+#else
+ mov r0, #0x7c @ . ..RS BLDP WCA.
+#endif
+ mov pc, lr
+ .size __arm7_setup, . - __arm7_setup
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm6_proc_info, #object
+__arm6_proc_info:
+ .long 0x41560600
+ .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_arm6_name
+ .long arm6_processor_functions
+ .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 | \
+ 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
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
new file mode 100644
index 00000000..7a06e596
--- /dev/null
+++ b/arch/arm/mm/proc-arm720.S
@@ -0,0 +1,269 @@
+/*
+ * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720
+ *
+ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ * Rob Scott (rscott@mtrob.fdns.net)
+ * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2004.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM720T. The ARM720T has a writethrough IDC
+ * cache, so we don't need to clean it.
+ *
+ * Changelog:
+ * 05-09-2000 SJH Created by moving 720 specific functions
+ * out of 'proc-arm6,7.S' per RMK discussion
+ * 07-25-2000 SJH Added idle function.
+ * 08-25-2000 DBS Updated for integration of ARM Ltd version.
+ * 04-20-2004 HSC modified for non-paged memory management mode.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * Function: arm720_proc_init (void)
+ * : arm720_proc_fin (void)
+ *
+ * Notes : This processor does not require these
+ */
+ENTRY(cpu_arm720_dcache_clean_area)
+ENTRY(cpu_arm720_proc_init)
+ mov pc, lr
+
+ENTRY(cpu_arm720_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * Function: arm720_proc_do_idle(void)
+ * Params : r0 = unused
+ * Purpose : put the processor in proper idle mode
+ */
+ENTRY(cpu_arm720_do_idle)
+ mov pc, lr
+
+/*
+ * Function: arm720_switch_mm(unsigned long pgd_phys)
+ * Params : pgd_phys Physical address of page table
+ * Purpose : Perform a task switch, saving the old process' state and restoring
+ * the new.
+ */
+ENTRY(cpu_arm720_switch_mm)
+#ifdef CONFIG_MMU
+ mov r1, #0
+ mcr p15, 0, r1, c7, c7, 0 @ invalidate cache
+ mcr p15, 0, r0, c2, c0, 0 @ update page table ptr
+ mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)
+#endif
+ mov pc, lr
+
+/*
+ * Function: arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
+ * Params : r0 = Address to set
+ * : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+ .align 5
+ENTRY(cpu_arm720_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext wc_disable=0
+#endif
+ mov pc, lr
+
+/*
+ * Function: arm720_reset
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm720_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x2100 @ ..v....s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+ __CPUINIT
+
+ .type __arm710_setup, #function
+__arm710_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ invalidate caches
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+#endif
+ mrc p15, 0, r0, c1, c0 @ get control register
+ ldr r5, arm710_cr1_clear
+ bic r0, r0, r5
+ ldr r5, arm710_cr1_set
+ orr r0, r0, r5
+ mov pc, lr @ __ret (head.S)
+ .size __arm710_setup, . - __arm710_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .... 0001 ..11 1101
+ *
+ */
+ .type arm710_cr1_clear, #object
+ .type arm710_cr1_set, #object
+arm710_cr1_clear:
+ .word 0x0f3f
+arm710_cr1_set:
+ .word 0x013d
+
+ .type __arm720_setup, #function
+__arm720_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 @ invalidate caches
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
+#endif
+ adr r5, arm720_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr @ __ret (head.S)
+ .size __arm720_setup, . - __arm720_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..1. 1001 ..11 1101
+ *
+ */
+ .type arm720_crval, #object
+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
+
+ .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
+
+ .align
+
+/*
+ * See <asm/procinfo.h> for a definition of this structure.
+ */
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm710_proc_info, #object
+__arm710_proc_info:
+ .long 0x41807100 @ 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 __arm710_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_arm710_name @ name
+ .long arm720_processor_functions
+ .long v4_tlb_fns
+ .long v4wt_user_fns
+ .long v4_cache_fns
+ .size __arm710_proc_info, . - __arm710_proc_info
+
+ .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
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
new file mode 100644
index 00000000..6f9d12ef
--- /dev/null
+++ b/arch/arm/mm/proc-arm740.S
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/arm/mm/arm740.S: utility functions for ARM740
+ *
+ * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+ .text
+/*
+ * cpu_arm740_proc_init()
+ * cpu_arm740_do_idle()
+ * cpu_arm740_dcache_clean_area()
+ * cpu_arm740_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm740_proc_init)
+ENTRY(cpu_arm740_do_idle)
+ENTRY(cpu_arm740_dcache_clean_area)
+ENTRY(cpu_arm740_switch_mm)
+ mov pc, lr
+
+/*
+ * cpu_arm740_proc_fin()
+ */
+ENTRY(cpu_arm740_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x3f000000 @ bank/f/lock/s
+ bic r0, r0, #0x0000000c @ w-buffer/cache
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm740_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm740_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c0, 0 @ invalidate cache
+ mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
+ bic ip, ip, #0x0000000c @ ............wc..
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+ __CPUINIT
+
+ .type __arm740_setup, #function
+__arm740_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c0, 0 @ invalidate caches
+
+ mcr p15, 0, r0, c6, c3 @ disable area 3~7
+ mcr p15, 0, r0, c6, c4
+ mcr p15, 0, r0, c6, c5
+ mcr p15, 0, r0, c6, c6
+ mcr p15, 0, r0, c6, c7
+
+ mov r0, #0x0000003F @ base = 0, size = 4GB
+ mcr p15, 0, r0, c6, c0 @ set area 0, default
+
+ ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+ ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the area register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c1 @ set area 1, RAM
+
+ ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+ ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the area register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH
+
+ mov r0, #0x06
+ mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #0x00 @ disable whole write buffer
+#else
+ mov r0, #0x02 @ Region 1 write bufferred
+#endif
+ mcr p15, 0, r0, c3, c0
+
+ mov r0, #0x10000
+ sub r0, r0, #1 @ r0 = 0xffff
+ mcr p15, 0, r0, c5, c0 @ all read/write access
+
+ mrc p15, 0, r0, c1, c0 @ get control register
+ bic r0, r0, #0x3F000000 @ set to standard caching mode
+ @ need some benchmark
+ orr r0, r0, #0x0000000d @ MPU/Cache/WB
+
+ mov pc, lr
+
+ .size __arm740_setup, . - __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+ .type __arm740_proc_info,#object
+__arm740_proc_info:
+ .long 0x41807400
+ .long 0xfffffff0
+ .long 0
+ b __arm740_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_arm740_name
+ .long arm740_processor_functions
+ .long 0
+ .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
new file mode 100644
index 00000000..537ffcb0
--- /dev/null
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -0,0 +1,251 @@
+/*
+ * linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI
+ *
+ * Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+ .text
+/*
+ * cpu_arm7tdmi_proc_init()
+ * cpu_arm7tdmi_do_idle()
+ * cpu_arm7tdmi_dcache_clean_area()
+ * cpu_arm7tdmi_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm7tdmi_proc_init)
+ENTRY(cpu_arm7tdmi_do_idle)
+ENTRY(cpu_arm7tdmi_dcache_clean_area)
+ENTRY(cpu_arm7tdmi_switch_mm)
+ mov pc, lr
+
+/*
+ * cpu_arm7tdmi_proc_fin()
+ */
+ENTRY(cpu_arm7tdmi_proc_fin)
+ mov pc, lr
+
+/*
+ * Function: cpu_arm7tdmi_reset(loc)
+ * Params : loc(r0) address to jump to
+ * Purpose : Sets up everything for a reset and jump to the location for soft reset.
+ */
+ENTRY(cpu_arm7tdmi_reset)
+ mov pc, r0
+
+ __CPUINIT
+
+ .type __arm7tdmi_setup, #function
+__arm7tdmi_setup:
+ mov pc, lr
+ .size __arm7tdmi_setup, . - __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
+
+ .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
+
+ .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
+ .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 arm7tdmi_processor_functions
+ .long 0
+ .long 0
+ .long v4_cache_fns
+ .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
new file mode 100644
index 00000000..bf8a1d1c
--- /dev/null
+++ b/arch/arm/mm/proc-arm920.S
@@ -0,0 +1,522 @@
+/*
+ * linux/arch/arm/mm/proc-arm920.S: MMU functions for ARM920
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm920.
+ *
+ * CONFIG_CPU_ARM920_CPU_IDLE -> nohlt
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 8
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 65536
+
+
+ .text
+/*
+ * cpu_arm920_proc_init()
+ */
+ENTRY(cpu_arm920_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm920_proc_fin()
+ */
+ENTRY(cpu_arm920_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm920_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm920_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm920_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm920_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm920_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm920_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(arm920_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm920_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags for address space
+ */
+ENTRY(arm920_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm920_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm920_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm920_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm920_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm920_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm920_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm920_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm920_dma_clean_range
+ bcs arm920_dma_inv_range
+ b arm920_dma_flush_range
+ENDPROC(arm920_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+#endif
+
+
+ENTRY(cpu_arm920_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm920_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm920_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+@ && Re-written to use Index Ops.
+@ && Uses registers r1, r3 and ip
+
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm920_set_pte(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm920_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl cpu_arm920_suspend_size
+.equ cpu_arm920_suspend_size, 4 * 3
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_arm920_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_arm920_do_suspend)
+
+ENTRY(cpu_arm920_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_arm920_do_resume)
+#else
+#define cpu_arm920_do_suspend 0
+#define cpu_arm920_do_resume 0
+#endif
+
+ __CPUINIT
+
+ .type __arm920_setup, #function
+__arm920_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ adr r5, arm920_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __arm920_setup, . - __arm920_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..11 0001 ..11 0101
+ *
+ */
+ .type arm920_crval, #object
+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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm920_proc_info,#object
+__arm920_proc_info:
+ .long 0x41009200
+ .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 __arm920_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+ .long cpu_arm920_name
+ .long arm920_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ .long arm920_cache_fns
+#else
+ .long v4wt_cache_fns
+#endif
+ .size __arm920_proc_info, . - __arm920_proc_info
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
new file mode 100644
index 00000000..95ba1fc5
--- /dev/null
+++ b/arch/arm/mm/proc-arm922.S
@@ -0,0 +1,492 @@
+/*
+ * linux/arch/arm/mm/proc-arm922.S: MMU functions for ARM922
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * Copyright (C) 2001 Altera Corporation
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm922.
+ *
+ * CONFIG_CPU_ARM922_CPU_IDLE -> nohlt
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 4
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 64
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions. (I think this should
+ * be 32768).
+ */
+#define CACHE_DLIMIT 8192
+
+
+ .text
+/*
+ * cpu_arm922_proc_init()
+ */
+ENTRY(cpu_arm922_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm922_proc_fin()
+ */
+ENTRY(cpu_arm922_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm922_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm922_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm922_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm922_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm922_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm922_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ENTRY(arm922_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm922_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 8 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ */
+ENTRY(arm922_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm922_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm922_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm922_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm922_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm922_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm922_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm922_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm922_dma_clean_range
+ bcs arm922_dma_inv_range
+ b arm922_dma_flush_range
+ENDPROC(arm922_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+#endif
+
+
+ENTRY(cpu_arm922_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm922_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm922_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+@ && Re-written to use Index Ops.
+@ && Uses registers r1, r3 and ip
+
+ mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm922_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm922_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm922_setup, #function
+__arm922_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ adr r5, arm922_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __arm922_setup, . - __arm922_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..11 0001 ..11 0101
+ *
+ */
+ .type arm922_crval, #object
+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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm922_proc_info,#object
+__arm922_proc_info:
+ .long 0x41009220
+ .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 __arm922_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+ .long cpu_arm922_name
+ .long arm922_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ .long arm922_cache_fns
+#else
+ .long v4wt_cache_fns
+#endif
+ .size __arm922_proc_info, . - __arm922_proc_info
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
new file mode 100644
index 00000000..541e4774
--- /dev/null
+++ b/arch/arm/mm/proc-arm925.S
@@ -0,0 +1,576 @@
+/*
+ * linux/arch/arm/mm/arm925.S: MMU functions for ARM925
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * Copyright (C) 2002 RidgeRun, Inc.
+ * Copyright (C) 2002-2003 MontaVista Software, Inc.
+ *
+ * Update for Linux-2.6 and cache flush improvements
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindgren <tony@atomide.com>
+ *
+ * hacked for non-paged-MM by Hyok S. Choi, 2004.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm925.
+ *
+ * CONFIG_CPU_ARM925_CPU_IDLE -> nohlt
+ *
+ * Some additional notes based on deciphering the TI TRM on OMAP-5910:
+ *
+ * NOTE1: The TI925T Configuration Register bit "D-cache clean and flush
+ * entry mode" must be 0 to flush the entries in both segments
+ * at once. This is the default value. See TRM 2-20 and 2-24 for
+ * more information.
+ *
+ * NOTE2: Default is the "D-cache clean and flush entry mode". It looks
+ * like the "Transparent mode" must be on for partial cache flushes
+ * to work in this mode. This mode only works with 16-bit external
+ * memory. See TRM 2-24 for more information.
+ *
+ * NOTE3: Write-back cache flushing seems to be flakey with devices using
+ * direct memory access, such as USB OHCI. The workaround is to use
+ * write-through cache with CONFIG_CPU_DCACHE_WRITETHROUGH (this is
+ * the default for OMAP-1510).
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * The size of one data cache line.
+ */
+#define CACHE_DLINESIZE 16
+
+/*
+ * The number of data cache segments.
+ */
+#define CACHE_DSEGMENTS 2
+
+/*
+ * The number of lines in a cache segment.
+ */
+#define CACHE_DENTRIES 256
+
+/*
+ * This is the size at which it becomes more efficient to
+ * clean the whole cache, rather than using the individual
+ * cache line maintenance instructions.
+ */
+#define CACHE_DLIMIT 8192
+
+ .text
+/*
+ * cpu_arm925_proc_init()
+ */
+ENTRY(cpu_arm925_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm925_proc_fin()
+ */
+ENTRY(cpu_arm925_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm925_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm925_reset)
+ /* Send software reset to MPU and DSP */
+ mov ip, #0xff000000
+ orr ip, ip, #0x00fe0000
+ orr ip, ip, #0x0000ce00
+ mov r4, #1
+ strh r4, [ip, #0x10]
+
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm925_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+ .align 10
+ENTRY(cpu_arm925_do_idle)
+ mov r0, #0
+ mrc p15, 0, r1, c1, c0, 0 @ Read control register
+ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
+ bic r2, r1, #1 << 12
+ mcr p15, 0, r2, c1, c0, 0 @ Disable I cache
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable
+ mov pc, lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm925_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm925_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ENTRY(arm925_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm925_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+ /* Flush entries in both segments at once, see NOTE1 above */
+ mov r3, #(CACHE_DENTRIES - 1) << 4 @ 256 entries in segment
+2: mcr p15, 0, r3, c7, c14, 2 @ clean+invalidate D index
+ subs r3, r3, #1 << 4
+ bcs 2b @ entries 255 to 0
+#endif
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ */
+ENTRY(arm925_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bgt __flush_whole_cache
+1: tst r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#else
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#endif
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm925_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm925_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm925_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm925_dma_inv_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+#endif
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm925_dma_clean_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm925_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+#else
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm925_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm925_dma_clean_range
+ bcs arm925_dma_inv_range
+ b arm925_dma_flush_range
+ENDPROC(arm925_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ENTRY(cpu_arm925_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm925_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm925_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+ /* Flush entries in bothe segments at once, see NOTE1 above */
+ mov r3, #(CACHE_DENTRIES - 1) << 4 @ 256 entries in segment
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 4
+ bcs 2b @ entries 255 to 0
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm925_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm925_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif /* CONFIG_MMU */
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm925_setup, #function
+__arm925_setup:
+ mov r0, #0
+#if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE)
+ orr r0,r0,#1 << 7
+#endif
+
+ /* Transparent on, D-cache clean & flush mode. See NOTE2 above */
+ orr r0,r0,#1 << 1 @ transparent mode on
+ mcr p15, 0, r0, c15, c1, 0 @ write TI config register
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #4 @ disable write-back on caches explicitly
+ mcr p15, 7, r0, c15, c0, 0
+#endif
+
+ adr r5, arm925_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .1.. .... .... ....
+#endif
+ mov pc, lr
+ .size __arm925_setup, . - __arm925_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 0001 ..11 1101
+ *
+ */
+ .type arm925_crval, #object
+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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm925_proc_info,#object
+__arm925_proc_info:
+ .long 0x54029250
+ .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
+
+ .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
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
new file mode 100644
index 00000000..0ed85d93
--- /dev/null
+++ b/arch/arm/mm/proc-arm926.S
@@ -0,0 +1,542 @@
+/*
+ * linux/arch/arm/mm/proc-arm926.S: MMU functions for ARM926EJ-S
+ *
+ * Copyright (C) 1999-2001 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm926.
+ *
+ * CONFIG_CPU_ARM926_CPU_IDLE -> nohlt
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define CACHE_DLIMIT 16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHE_DLINESIZE 32
+
+ .text
+/*
+ * cpu_arm926_proc_init()
+ */
+ENTRY(cpu_arm926_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm926_proc_fin()
+ */
+ENTRY(cpu_arm926_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm926_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm926_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm926_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+ .align 10
+ENTRY(cpu_arm926_do_idle)
+ mov r0, #0
+ mrc p15, 0, r1, c1, c0, 0 @ Read control register
+ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
+ bic r2, r1, #1 << 12
+ mrs r3, cpsr @ Disable FIQs while Icache
+ orr ip, r3, #PSR_F_BIT @ is disabled
+ msr cpsr_c, ip
+ mcr p15, 0, r2, c1, c0, 0 @ Disable I cache
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mcr p15, 0, r1, c1, c0, 0 @ Restore ICache enable
+ msr cpsr_c, r3 @ Restore FIQ state
+ mov pc, lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm926_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm926_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ENTRY(arm926_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm926_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
+ bne 1b
+#endif
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ */
+ENTRY(arm926_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bgt __flush_whole_cache
+1: tst r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#else
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#endif
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm926_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm926_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm926_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm926_dma_inv_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+#endif
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+arm926_dma_clean_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm926_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+#else
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm926_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm926_dma_clean_range
+ bcs arm926_dma_inv_range
+ b arm926_dma_flush_range
+ENDPROC(arm926_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ENTRY(cpu_arm926_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm926_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm926_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
+ bne 1b
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm926_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm926_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+/* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */
+.globl cpu_arm926_suspend_size
+.equ cpu_arm926_suspend_size, 4 * 3
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_arm926_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ PID
+ mrc p15, 0, r5, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r6, c2, c0, 0 @ TTB address
+ mrc p15, 0, r7, c1, c0, 0 @ Control register
+ stmia r0, {r4 - r7}
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_arm926_do_suspend)
+
+ENTRY(cpu_arm926_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I+D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I+D caches
+ ldmia r0, {r4 - r7}
+ mcr p15, 0, r4, c13, c0, 0 @ PID
+ mcr p15, 0, r5, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r6, c2, c0, 0 @ TTB address
+ mov r0, r7 @ control register
+ mov r2, r6, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_BIT4 | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_arm926_do_resume)
+#else
+#define cpu_arm926_do_suspend 0
+#define cpu_arm926_do_resume 0
+#endif
+
+ __CPUINIT
+
+ .type __arm926_setup, #function
+__arm926_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+
+
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #4 @ disable write-back on caches explicitly
+ mcr p15, 7, r0, c15, c0, 0
+#endif
+
+ adr r5, arm926_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x4000 @ .1.. .... .... ....
+#endif
+ mov pc, lr
+ .size __arm926_setup, . - __arm926_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 0001 ..11 0101
+ *
+ */
+ .type arm926_crval, #object
+arm926_crval:
+ crval clear=0x00007f3f, mmuset=0x00003135, ucset=0x00001134
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm926_proc_info,#object
+__arm926_proc_info:
+ .long 0x41069260 @ ARM926EJ-S (v5TEJ)
+ .long 0xff0ffff0
+ .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 __arm926_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
+ .long cpu_arm926_name
+ .long arm926_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long arm926_cache_fns
+ .size __arm926_proc_info, . - __arm926_proc_info
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
new file mode 100644
index 00000000..26aea3f7
--- /dev/null
+++ b/arch/arm/mm/proc-arm940.S
@@ -0,0 +1,407 @@
+/*
+ * linux/arch/arm/mm/arm940.S: utility functions for ARM940T
+ *
+ * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */
+#define CACHE_DLINESIZE 16
+#define CACHE_DSEGMENTS 4
+#define CACHE_DENTRIES 64
+
+ .text
+/*
+ * cpu_arm940_proc_init()
+ * cpu_arm940_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm940_proc_init)
+ENTRY(cpu_arm940_switch_mm)
+ mov pc, lr
+
+/*
+ * cpu_arm940_proc_fin()
+ */
+ENTRY(cpu_arm940_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x00001000 @ i-cache
+ bic r0, r0, #0x00000004 @ d-cache
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm940_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm940_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ flush I cache
+ mcr p15, 0, ip, c7, c6, 0 @ flush D cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x00000005 @ .............c.p
+ bic ip, ip, #0x00001000 @ i-cache
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm940_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm940_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm940_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm940_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ */
+ENTRY(arm940_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm940_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ /* FALLTHROUGH */
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * There is no efficient way to flush a range of cache entries
+ * in the specified address range. Thus, flushes all.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ */
+ENTRY(arm940_flush_user_cache_range)
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ flush D cache
+#else
+ mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 4
+ bcs 1b @ segments 3 to 0
+#endif
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm940_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm940_coherent_user_range)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(arm940_flush_kern_dcache_area)
+ mov ip, #0
+ mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 4
+ bcs 1b @ segments 7 to 0
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * There is no efficient way to invalidate a specifid virtual
+ * address range. Thus, invalidates all.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+arm940_dma_inv_range:
+ mov ip, #0
+ mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c6, 2 @ flush D entry
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 4
+ bcs 1b @ segments 7 to 0
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * There is no efficient way to clean a specifid virtual
+ * address range. Thus, cleans all.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+arm940_dma_clean_range:
+ENTRY(cpu_arm940_dcache_clean_area)
+ mov ip, #0
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c10, 2 @ clean D entry
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 4
+ bcs 1b @ segments 7 to 0
+#endif
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * There is no efficient way to clean and invalidate a specifid
+ * virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm940_dma_flush_range)
+ mov ip, #0
+ mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries
+2:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r3, c7, c14, 2 @ clean/flush D entry
+#else
+ mcr p15, 0, r3, c7, c6, 2 @ invalidate D entry
+#endif
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 4
+ bcs 1b @ segments 7 to 0
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm940_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm940_dma_clean_range
+ bcs arm940_dma_inv_range
+ b arm940_dma_flush_range
+ENDPROC(arm940_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ __CPUINIT
+
+ .type __arm940_setup, #function
+__arm940_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+
+ mcr p15, 0, r0, c6, c3, 0 @ disable data area 3~7
+ mcr p15, 0, r0, c6, c4, 0
+ mcr p15, 0, r0, c6, c5, 0
+ mcr p15, 0, r0, c6, c6, 0
+ mcr p15, 0, r0, c6, c7, 0
+
+ mcr p15, 0, r0, c6, c3, 1 @ disable instruction area 3~7
+ mcr p15, 0, r0, c6, c4, 1
+ mcr p15, 0, r0, c6, c5, 1
+ mcr p15, 0, r0, c6, c6, 1
+ mcr p15, 0, r0, c6, c7, 1
+
+ mov r0, #0x0000003F @ base = 0, size = 4GB
+ mcr p15, 0, r0, c6, c0, 0 @ set area 0, default
+ mcr p15, 0, r0, c6, c0, 1
+
+ ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+ ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the area register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c1, 0 @ set area 1, RAM
+ mcr p15, 0, r0, c6, c1, 1
+
+ ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+ ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the area register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c2, 0 @ set area 2, ROM/FLASH
+ mcr p15, 0, r0, c6, c2, 1
+
+ mov r0, #0x06
+ mcr p15, 0, r0, c2, c0, 0 @ Region 1&2 cacheable
+ mcr p15, 0, r0, c2, c0, 1
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #0x00 @ disable whole write buffer
+#else
+ mov r0, #0x02 @ Region 1 write bufferred
+#endif
+ mcr p15, 0, r0, c3, c0, 0
+
+ mov r0, #0x10000
+ sub r0, r0, #1 @ r0 = 0xffff
+ mcr p15, 0, r0, c5, c0, 0 @ all read/write access
+ mcr p15, 0, r0, c5, c0, 1
+
+ mrc p15, 0, r0, c1, c0 @ get control register
+ orr r0, r0, #0x00001000 @ I-cache
+ orr r0, r0, #0x00000005 @ MPU/D-cache
+
+ mov pc, lr
+
+ .size __arm940_setup, . - __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm940_proc_info,#object
+__arm940_proc_info:
+ .long 0x41009400
+ .long 0xff00fff0
+ .long 0
+ b __arm940_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+ .long cpu_arm940_name
+ .long arm940_processor_functions
+ .long 0
+ .long 0
+ .long arm940_cache_fns
+ .size __arm940_proc_info, . - __arm940_proc_info
+
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
new file mode 100644
index 00000000..80633454
--- /dev/null
+++ b/arch/arm/mm/proc-arm946.S
@@ -0,0 +1,462 @@
+/*
+ * linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S
+ *
+ * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com)
+ *
+ * (Many of cache codes are from proc-arm926.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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache,
+ * comprising 256 lines of 32 bytes (8 words).
+ */
+#define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */
+#define CACHE_DLINESIZE 32 /* fixed */
+#define CACHE_DSEGMENTS 4 /* fixed */
+#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE)
+#define CACHE_DLIMIT (CACHE_DSIZE * 4) /* benchmark needed */
+
+ .text
+/*
+ * cpu_arm946_proc_init()
+ * cpu_arm946_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm946_proc_init)
+ENTRY(cpu_arm946_switch_mm)
+ mov pc, lr
+
+/*
+ * cpu_arm946_proc_fin()
+ */
+ENTRY(cpu_arm946_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x00001000 @ i-cache
+ bic r0, r0, #0x00000004 @ d-cache
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_arm946_reset(loc)
+ * Params : r0 = address to jump to
+ * Notes : This sets up everything for a reset
+ */
+ENTRY(cpu_arm946_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ flush I cache
+ mcr p15, 0, ip, c7, c6, 0 @ flush D cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x00000005 @ .............c.p
+ bic ip, ip, #0x00001000 @ i-cache
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm946_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm946_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(arm946_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(arm946_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ */
+ENTRY(arm946_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(arm946_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ flush D cache
+#else
+ mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments
+1: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index
+ subs r3, r3, #1 << 4
+ bcs 2b @ entries n to 0
+ subs r1, r1, #1 << 29
+ bcs 1b @ segments 3 to 0
+#endif
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ * (same as arm926)
+ */
+ENTRY(arm946_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bhs __flush_whole_cache
+
+1: tst r2, #VM_EXEC
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#else
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+#endif
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(arm946_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ * (same as arm926)
+ */
+ENTRY(arm946_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ * (same as arm926)
+ */
+ENTRY(arm946_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ * (same as arm926)
+ */
+arm946_dma_inv_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+#endif
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as arm926)
+ */
+arm946_dma_clean_range:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as arm926)
+ */
+ENTRY(arm946_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+#else
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+#endif
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(arm946_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq arm946_dma_clean_range
+ bcs arm946_dma_inv_range
+ b arm946_dma_flush_range
+ENDPROC(arm946_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+
+ENTRY(cpu_arm946_dcache_clean_area)
+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __arm946_setup, #function
+__arm946_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+
+ mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7
+ mcr p15, 0, r0, c6, c4, 0
+ mcr p15, 0, r0, c6, c5, 0
+ mcr p15, 0, r0, c6, c6, 0
+ mcr p15, 0, r0, c6, c7, 0
+
+ mov r0, #0x0000003F @ base = 0, size = 4GB
+ mcr p15, 0, r0, c6, c0, 0 @ set region 0, default
+
+ ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM
+ ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the region register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c1, 0 @ set region 1, RAM
+
+ ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH
+ ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB)
+ mov r2, #10 @ 11 is the minimum (4KB)
+1: add r2, r2, #1 @ area size *= 2
+ mov r1, r1, lsr #1
+ bne 1b @ count not zero r-shift
+ orr r0, r0, r2, lsl #1 @ the region register value
+ orr r0, r0, #1 @ set enable bit
+ mcr p15, 0, r0, c6, c2, 0 @ set region 2, ROM/FLASH
+
+ mov r0, #0x06
+ mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable
+ mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mov r0, #0x00 @ disable whole write buffer
+#else
+ mov r0, #0x02 @ region 1 write bufferred
+#endif
+ mcr p15, 0, r0, c3, c0, 0
+
+/*
+ * Access Permission Settings for future permission control by PU.
+ *
+ * priv. user
+ * region 0 (whole) rw -- : b0001
+ * region 1 (RAM) rw rw : b0011
+ * region 2 (FLASH) rw r- : b0010
+ * region 3~7 (none) -- -- : b0000
+ */
+ mov r0, #0x00000031
+ orr r0, r0, #0x00000200
+ mcr p15, 0, r0, c5, c0, 2 @ set data access permission
+ mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission
+
+ mrc p15, 0, r0, c1, c0 @ get control register
+ orr r0, r0, #0x00001000 @ I-cache
+ orr r0, r0, #0x00000005 @ MPU/D-cache
+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
+ orr r0, r0, #0x00004000 @ .1.. .... .... ....
+#endif
+ mov pc, lr
+
+ .size __arm946_setup, . - __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+ .type __arm946_proc_info,#object
+__arm946_proc_info:
+ .long 0x41009460
+ .long 0xff00fff0
+ .long 0
+ b __arm946_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
+ .long cpu_arm946_name
+ .long arm946_processor_functions
+ .long 0
+ .long 0
+ .long arm940_cache_fns
+ .size __arm946_proc_info, . - __arm946_proc_info
+
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
new file mode 100644
index 00000000..546b54da
--- /dev/null
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -0,0 +1,136 @@
+/*
+ * linux/arch/arm/mm/proc-arm9tdmi.S: utility functions for ARM9TDMI
+ *
+ * Copyright (C) 2003-2006 Hyok S. Choi <hyok.choi@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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+ .text
+/*
+ * cpu_arm9tdmi_proc_init()
+ * cpu_arm9tdmi_do_idle()
+ * cpu_arm9tdmi_dcache_clean_area()
+ * cpu_arm9tdmi_switch_mm()
+ *
+ * These are not required.
+ */
+ENTRY(cpu_arm9tdmi_proc_init)
+ENTRY(cpu_arm9tdmi_do_idle)
+ENTRY(cpu_arm9tdmi_dcache_clean_area)
+ENTRY(cpu_arm9tdmi_switch_mm)
+ mov pc, lr
+
+/*
+ * cpu_arm9tdmi_proc_fin()
+ */
+ENTRY(cpu_arm9tdmi_proc_fin)
+ mov pc, lr
+
+/*
+ * Function: cpu_arm9tdmi_reset(loc)
+ * Params : loc(r0) address to jump to
+ * Purpose : Sets up everything for a reset and jump to the location for soft reset.
+ */
+ENTRY(cpu_arm9tdmi_reset)
+ mov pc, r0
+
+ __CPUINIT
+
+ .type __arm9tdmi_setup, #function
+__arm9tdmi_setup:
+ mov pc, lr
+ .size __arm9tdmi_setup, . - __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __arm9tdmi_proc_info, #object
+__arm9tdmi_proc_info:
+ .long 0x41009900
+ .long 0xfff8ff00
+ .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 arm9tdmi_processor_functions
+ .long 0
+ .long 0
+ .long v4_cache_fns
+ .size __arm9tdmi_proc_info, . - __arm9tdmi_proc_info
+
+ .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
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
new file mode 100644
index 00000000..fc2a4ae1
--- /dev/null
+++ b/arch/arm/mm/proc-fa526.S
@@ -0,0 +1,247 @@
+/*
+ * linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
+ *
+ * Written by : Luke Lee
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * 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.
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the fa526.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#include "proc-macros.S"
+
+#define CACHE_DLINESIZE 16
+
+ .text
+/*
+ * cpu_fa526_proc_init()
+ */
+ENTRY(cpu_fa526_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_fa526_proc_fin()
+ */
+ENTRY(cpu_fa526_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ nop
+ nop
+ mov pc, lr
+
+/*
+ * cpu_fa526_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 4
+ENTRY(cpu_fa526_reset)
+/* TODO: Use CP8 if possible... */
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ bic ip, ip, #0x0800 @ BTB off
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ nop
+ nop
+ mov pc, r0
+
+/*
+ * cpu_fa526_do_idle()
+ */
+ .align 4
+ENTRY(cpu_fa526_do_idle)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+
+ENTRY(cpu_fa526_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_fa526_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 4
+ENTRY(cpu_fa526_switch_mm)
+#ifdef CONFIG_MMU
+ mov ip, #0
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+ mcr p15, 0, ip, c7, c14, 0 @ clean and invalidate whole D cache
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB since mm changed
+ mcr p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB
+#endif
+ mov pc, lr
+
+/*
+ * cpu_fa526_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 4
+ENTRY(cpu_fa526_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __fa526_setup, #function
+__fa526_setup:
+ /* On return of this routine, r0 must carry correct flags for CFG register */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ mcr p15, 0, r0, c7, c5, 5 @ invalidate IScratchpad RAM
+
+ mov r0, #1
+ mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB All
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+
+ mov r0, #0x1f @ Domains 0, 1 = manager, 2 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ ldr r5, fa526_cr1_clear
+ bic r0, r0, r5
+ ldr r5, fa526_cr1_set
+ orr r0, r0, r5
+ mov pc, lr
+ .size __fa526_setup, . - __fa526_setup
+
+ /*
+ * .RVI ZFRS BLDP WCAM
+ * ..11 1001 .111 1101
+ *
+ */
+ .type fa526_cr1_clear, #object
+ .type fa526_cr1_set, #object
+fa526_cr1_clear:
+ .word 0x3f3f
+fa526_cr1_set:
+ .word 0x397D
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __fa526_proc_info,#object
+__fa526_proc_info:
+ .long 0x66015261
+ .long 0xff01fff1
+ .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 __fa526_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF
+ .long cpu_fa526_name
+ .long fa526_processor_functions
+ .long fa_tlb_fns
+ .long fa_user_fns
+ .long fa_cache_fns
+ .size __fa526_proc_info, . - __fa526_proc_info
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
new file mode 100644
index 00000000..d3883eed
--- /dev/null
+++ b/arch/arm/mm/proc-feroceon.S
@@ -0,0 +1,698 @@
+/*
+ * linux/arch/arm/mm/proc-feroceon.S: MMU functions for Feroceon
+ *
+ * Heavily based on proc-arm926.S
+ * Maintainer: Assaf Hoffman <hoffman@marvell.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/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define CACHE_DLIMIT 16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHE_DLINESIZE 32
+
+ .bss
+ .align 3
+__cache_params_loc:
+ .space 8
+
+ .text
+__cache_params:
+ .word __cache_params_loc
+
+/*
+ * cpu_feroceon_proc_init()
+ */
+ENTRY(cpu_feroceon_proc_init)
+ mrc p15, 0, r0, c0, c0, 1 @ read cache type register
+ ldr r1, __cache_params
+ mov r2, #(16 << 5)
+ tst r0, #(1 << 16) @ get way
+ mov r0, r0, lsr #18 @ get cache size order
+ movne r3, #((4 - 1) << 30) @ 4-way
+ and r0, r0, #0xf
+ moveq r3, #0 @ 1-way
+ mov r2, r2, lsl r0 @ actual cache size
+ movne r2, r2, lsr #2 @ turned into # of sets
+ sub r2, r2, #(1 << 5)
+ stmia r1, {r2, r3}
+ mov pc, lr
+
+/*
+ * cpu_feroceon_proc_fin()
+ */
+ENTRY(cpu_feroceon_proc_fin)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+ !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+ mov r0, #0
+ mcr p15, 1, r0, c15, c9, 0 @ clean L2
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_feroceon_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_feroceon_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_feroceon_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+ .align 5
+ENTRY(cpu_feroceon_do_idle)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+ mov pc, lr
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(feroceon_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(feroceon_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ .align 5
+ENTRY(feroceon_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(feroceon_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+
+__flush_whole_cache:
+ ldr r1, __cache_params
+ ldmia r1, {r1, r3}
+1: orr ip, r1, r3
+2: mcr p15, 0, ip, c7, c14, 2 @ clean + invalidate D set/way
+ subs ip, ip, #(1 << 30) @ next way
+ bcs 2b
+ subs r1, r1, #(1 << 5) @ next set
+ bcs 1b
+
+ tst r2, #VM_EXEC
+ mov ip, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ */
+ .align 5
+ENTRY(feroceon_flush_user_cache_range)
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bgt __flush_whole_cache
+1: tst r2, #VM_EXEC
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mov ip, #0
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ .align 5
+ENTRY(feroceon_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(feroceon_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ .align 5
+ENTRY(feroceon_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+ENTRY(feroceon_range_flush_kern_dcache_area)
+ mrs r2, cpsr
+ add r1, r0, #PAGE_SZ - CACHE_DLINESIZE @ top addr is inclusive
+ orr r3, r2, #PSR_I_BIT
+ msr cpsr_c, r3 @ disable interrupts
+ mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start
+ mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top
+ msr cpsr_c, r2 @ restore interrupts
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+ .align 5
+feroceon_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ bic r0, r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+feroceon_range_dma_inv_range:
+ mrs r2, cpsr
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+ cmp r1, r0
+ subne r1, r1, #1 @ top address is inclusive
+ orr r3, r2, #PSR_I_BIT
+ msr cpsr_c, r3 @ disable interrupts
+ mcr p15, 5, r0, c15, c14, 0 @ D inv range start
+ mcr p15, 5, r1, c15, c14, 1 @ D inv range top
+ msr cpsr_c, r2 @ restore interrupts
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+ .align 5
+feroceon_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+feroceon_range_dma_clean_range:
+ mrs r2, cpsr
+ cmp r1, r0
+ subne r1, r1, #1 @ top address is inclusive
+ orr r3, r2, #PSR_I_BIT
+ msr cpsr_c, r3 @ disable interrupts
+ mcr p15, 5, r0, c15, c13, 0 @ D clean range start
+ mcr p15, 5, r1, c15, c13, 1 @ D clean range top
+ msr cpsr_c, r2 @ restore interrupts
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ .align 5
+ENTRY(feroceon_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+ENTRY(feroceon_range_dma_flush_range)
+ mrs r2, cpsr
+ cmp r1, r0
+ subne r1, r1, #1 @ top address is inclusive
+ orr r3, r2, #PSR_I_BIT
+ msr cpsr_c, r3 @ disable interrupts
+ mcr p15, 5, r0, c15, c15, 0 @ D clean/inv range start
+ mcr p15, 5, r1, c15, c15, 1 @ D clean/inv range top
+ msr cpsr_c, r2 @ restore interrupts
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(feroceon_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq feroceon_dma_clean_range
+ bcs feroceon_dma_inv_range
+ b feroceon_dma_flush_range
+ENDPROC(feroceon_dma_map_area)
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(feroceon_range_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq feroceon_range_dma_clean_range
+ bcs feroceon_range_dma_inv_range
+ b feroceon_range_dma_flush_range
+ENDPROC(feroceon_range_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ .align 5
+ENTRY(cpu_feroceon_dcache_clean_area)
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+ !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+ mov r2, r0
+ mov r3, r1
+#endif
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+ !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry
+ add r2, r2, #CACHE_DLINESIZE
+ subs r3, r3, #CACHE_DLINESIZE
+ bhi 1b
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_feroceon_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_feroceon_switch_mm)
+#ifdef CONFIG_MMU
+ /*
+ * Note: we wish to call __flush_whole_cache but we need to preserve
+ * lr to do so. The only way without touching main memory is to
+ * use r2 which is normally used to test the VM_EXEC flag, and
+ * compensate locally for the skipped ops if it is not set.
+ */
+ mov r2, lr @ abuse r2 to preserve lr
+ bl __flush_whole_cache
+ @ if r2 contains the VM_EXEC bit then the next 2 ops are done already
+ tst r2, #VM_EXEC
+ mcreq p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcreq p15, 0, ip, c7, c10, 4 @ drain WB
+
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, r2
+#else
+ mov pc, lr
+#endif
+
+/*
+ * cpu_feroceon_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_feroceon_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext wc_disable=0
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#if defined(CONFIG_CACHE_FEROCEON_L2) && \
+ !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH)
+ mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __feroceon_setup, #function
+__feroceon_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+
+ adr r5, feroceon_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __feroceon_setup, . - __feroceon_setup
+
+ /*
+ * B
+ * R P
+ * .RVI UFRS BLDP WCAM
+ * .011 .001 ..11 0101
+ *
+ */
+ .type feroceon_crval, #object
+feroceon_crval:
+ crval clear=0x0000773f, mmuset=0x00003135, ucset=0x00001134
+
+ __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
+
+ .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
+
+ .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
+ .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_88fr531_name
+ .long feroceon_processor_functions
+ .long v4wbi_tlb_fns
+ .long feroceon_user_fns
+ .long feroceon_cache_fns
+ .size __88fr531_proc_info, . - __88fr531_proc_info
+
+ .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
+
+ .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
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
new file mode 100644
index 00000000..34261f94
--- /dev/null
+++ b/arch/arm/mm/proc-macros.S
@@ -0,0 +1,256 @@
+/*
+ * We need constants.h for:
+ * VMA_VM_MM
+ * VMA_VM_FLAGS
+ * VM_EXEC
+ */
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+
+/*
+ * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
+ */
+ .macro vma_vm_mm, rd, rn
+ ldr \rd, [\rn, #VMA_VM_MM]
+ .endm
+
+/*
+ * vma_vm_flags - get vma->vm_flags
+ */
+ .macro vma_vm_flags, rd, rn
+ ldr \rd, [\rn, #VMA_VM_FLAGS]
+ .endm
+
+ .macro tsk_mm, rd, rn
+ ldr \rd, [\rn, #TI_TASK]
+ ldr \rd, [\rd, #TSK_ACTIVE_MM]
+ .endm
+
+/*
+ * act_mm - get current->active_mm
+ */
+ .macro act_mm, rd
+ bic \rd, sp, #8128
+ bic \rd, \rd, #63
+ ldr \rd, [\rd, #TI_TASK]
+ ldr \rd, [\rd, #TSK_ACTIVE_MM]
+ .endm
+
+/*
+ * mmid - get context id from mm pointer (mm->context.id)
+ */
+ .macro mmid, rd, rn
+ ldr \rd, [\rn, #MM_CONTEXT_ID]
+ .endm
+
+/*
+ * mask_asid - mask the ASID from the context ID
+ */
+ .macro asid, rd, rn
+ and \rd, \rn, #255
+ .endm
+
+ .macro crval, clear, mmuset, ucset
+#ifdef CONFIG_MMU
+ .word \clear
+ .word \mmuset
+#else
+ .word \clear
+ .word \ucset
+#endif
+ .endm
+
+/*
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
+ */
+ .macro dcache_line_size, reg, tmp
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ lsr \tmp, \tmp, #16
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
+ mov \reg, \reg, lsl \tmp @ actual cache line size
+ .endm
+
+/*
+ * icache_line_size - get the minimum I-cache line size from the CTR register
+ * on ARMv7.
+ */
+ .macro icache_line_size, reg, tmp
+ mrc p15, 0, \tmp, c0, c0, 1 @ read ctr
+ and \tmp, \tmp, #0xf @ cache line size encoding
+ mov \reg, #4 @ bytes per word
+ mov \reg, \reg, lsl \tmp @ actual cache line size
+ .endm
+
+/*
+ * Sanity check the PTE configuration for the code below - which makes
+ * certain assumptions about how these bits are laid out.
+ */
+#ifdef CONFIG_MMU
+#if L_PTE_SHARED != PTE_EXT_SHARED
+#error PTE shared bit mismatch
+#endif
+#if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
+ L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
+#error Invalid Linux PTE bit settings
+#endif
+#endif /* CONFIG_MMU */
+
+/*
+ * The ARMv6 and ARMv7 set_pte_ext translation function.
+ *
+ * Permission translation:
+ * YUWD APX AP1 AP0 SVC User
+ * 0xxx 0 0 0 no acc no acc
+ * 100x 1 0 1 r/o no acc
+ * 10x0 1 0 1 r/o no acc
+ * 1011 0 0 1 r/w no acc
+ * 110x 0 1 0 r/w r/o
+ * 11x0 0 1 0 r/w r/o
+ * 1111 0 1 1 r/w r/w
+ *
+ * If !CONFIG_CPU_USE_DOMAINS, the following permissions are changed:
+ * 110x 1 1 1 r/o r/o
+ * 11x0 1 1 1 r/o r/o
+ */
+ .macro armv6_mt_table pfx
+\pfx\()_mt_table:
+ .long 0x00 @ L_PTE_MT_UNCACHED
+ .long PTE_EXT_TEX(1) @ L_PTE_MT_BUFFERABLE
+ .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK
+ .long PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED
+ .long 0x00 @ unused
+ .long 0x00 @ L_PTE_MT_MINICACHE (not present)
+ .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC
+ .long 0x00 @ unused
+ .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC
+ .long 0x00 @ unused
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED
+ .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+ .endm
+
+ .macro armv6_set_pte_ext pfx
+ str r1, [r0], #2048 @ linux version
+
+ bic r3, r1, #0x000003fc
+ bic r3, r3, #PTE_TYPE_MASK
+ orr r3, r3, r2
+ orr r3, r3, #PTE_EXT_AP0 | 2
+
+ adr ip, \pfx\()_mt_table
+ and r2, r1, #L_PTE_MT_MASK
+ ldr r2, [ip, r2]
+
+ eor r1, r1, #L_PTE_DIRTY
+ tst r1, #L_PTE_DIRTY|L_PTE_RDONLY
+ orrne r3, r3, #PTE_EXT_APX
+
+ tst r1, #L_PTE_USER
+ orrne r3, r3, #PTE_EXT_AP1
+#ifdef CONFIG_CPU_USE_DOMAINS
+ @ allow kernel read/write access to read-only user pages
+ tstne r3, #PTE_EXT_APX
+ bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
+#endif
+
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
+
+ orr r3, r3, r2
+
+ tst r1, #L_PTE_YOUNG
+ tstne r1, #L_PTE_PRESENT
+ moveq r3, #0
+
+ str r3, [r0]
+ mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+ .endm
+
+
+/*
+ * The ARMv3, ARMv4 and ARMv5 set_pte_ext translation function,
+ * covering most CPUs except Xscale and Xscale 3.
+ *
+ * Permission translation:
+ * YUWD AP SVC User
+ * 0xxx 0x00 no acc no acc
+ * 100x 0x00 r/o no acc
+ * 10x0 0x00 r/o no acc
+ * 1011 0x55 r/w no acc
+ * 110x 0xaa r/w r/o
+ * 11x0 0xaa r/w r/o
+ * 1111 0xff r/w r/w
+ */
+ .macro armv3_set_pte_ext wc_disable=1
+ str r1, [r0], #2048 @ linux version
+
+ eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
+
+ bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
+ bic r2, r2, #PTE_TYPE_MASK
+ orr r2, r2, #PTE_TYPE_SMALL
+
+ tst r3, #L_PTE_USER @ user?
+ orrne r2, r2, #PTE_SMALL_AP_URO_SRW
+
+ tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
+ orreq r2, r2, #PTE_SMALL_AP_UNO_SRW
+
+ tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
+ movne r2, #0
+
+ .if \wc_disable
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+ tst r2, #PTE_CACHEABLE
+ bicne r2, r2, #PTE_BUFFERABLE
+#endif
+ .endif
+ str r2, [r0] @ hardware version
+ .endm
+
+
+/*
+ * Xscale set_pte_ext translation, split into two halves to cope
+ * with work-arounds. r3 must be preserved by code between these
+ * two macros.
+ *
+ * Permission translation:
+ * YUWD AP SVC User
+ * 0xxx 00 no acc no acc
+ * 100x 00 r/o no acc
+ * 10x0 00 r/o no acc
+ * 1011 01 r/w no acc
+ * 110x 10 r/w r/o
+ * 11x0 10 r/w r/o
+ * 1111 11 r/w r/w
+ */
+ .macro xscale_set_pte_ext_prologue
+ str r1, [r0] @ linux version
+
+ eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
+
+ bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits
+ orr r2, r2, #PTE_TYPE_EXT @ extended page
+
+ tst r3, #L_PTE_USER @ user?
+ orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
+
+ tst r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
+ orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
+ @ combined with user -> user r/w
+ .endm
+
+ .macro xscale_set_pte_ext_epilogue
+ tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
+ movne r2, #0 @ no -> fault
+
+ str r2, [r0, #2048]! @ hardware version
+ mov ip, #0
+ mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ mcr p15, 0, ip, c7, c10, 4 @ data write barrier
+ .endm
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
new file mode 100644
index 00000000..9d4f2ae6
--- /dev/null
+++ b/arch/arm/mm/proc-mohawk.S
@@ -0,0 +1,440 @@
+/*
+ * linux/arch/arm/mm/proc-mohawk.S: MMU functions for Marvell PJ1 core
+ *
+ * PJ1 (codename Mohawk) is a hybrid of the xscale3 and Marvell's own core.
+ *
+ * Heavily based on proc-arm926.S and proc-xsc3.S
+ *
+ * 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 <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed. If the
+ * area is larger than this, then we flush the whole cache.
+ */
+#define CACHE_DLIMIT 32768
+
+/*
+ * The cache line size of the L1 D cache.
+ */
+#define CACHE_DLINESIZE 32
+
+/*
+ * cpu_mohawk_proc_init()
+ */
+ENTRY(cpu_mohawk_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_mohawk_proc_fin()
+ */
+ENTRY(cpu_mohawk_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1800 @ ...iz...........
+ bic r0, r0, #0x0006 @ .............ca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_mohawk_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ *
+ * (same as arm926)
+ */
+ .align 5
+ENTRY(cpu_mohawk_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x0007 @ .............cam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_mohawk_do_idle()
+ *
+ * Called with IRQs disabled
+ */
+ .align 5
+ENTRY(cpu_mohawk_do_idle)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
+ mov pc, lr
+
+/*
+ * flush_user_cache_all()
+ *
+ * Clean and invalidate all cache entries in a particular
+ * address space.
+ */
+ENTRY(mohawk_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(mohawk_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcrne p15, 0, ip, c7, c10, 0 @ drain write buffer
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, flags)
+ *
+ * Clean and invalidate a range of cache entries in the
+ * specified address range.
+ *
+ * - start - start address (inclusive)
+ * - end - end address (exclusive)
+ * - flags - vm_flags describing address space
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #CACHE_DLIMIT
+ bgt __flush_whole_cache
+1: tst r2, #VM_EXEC
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(mohawk_coherent_kern_range)
+ /* FALLTHROUGH */
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start, end. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as arm926)
+ */
+ENTRY(mohawk_coherent_user_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(mohawk_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+mohawk_dma_inv_range:
+ tst r0, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHE_DLINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * (same as v4wb)
+ */
+mohawk_dma_clean_range:
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(mohawk_dma_flush_range)
+ bic r0, r0, #CACHE_DLINESIZE - 1
+1:
+ mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry
+ add r0, r0, #CACHE_DLINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(mohawk_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq mohawk_dma_clean_range
+ bcs mohawk_dma_inv_range
+ b mohawk_dma_flush_range
+ENDPROC(mohawk_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ENTRY(cpu_mohawk_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHE_DLINESIZE
+ subs r1, r1, #CACHE_DLINESIZE
+ bhi 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * cpu_mohawk_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_mohawk_switch_mm)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean & invalidate all D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ orr r0, r0, #0x18 @ cache the page table in L2
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
+
+/*
+ * cpu_mohawk_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_mohawk_set_pte_ext)
+ armv3_set_pte_ext
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __mohawk_setup, #function
+__mohawk_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs
+ orr r4, r4, #0x18 @ cache the page table in L2
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+
+ mov r0, #0 @ don't allow CP access
+ mcr p15, 0, r0, c15, c1, 0 @ write CP access register
+
+ adr r5, mohawk_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+
+ .size __mohawk_setup, . - __mohawk_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * .011 1001 ..00 0101
+ *
+ */
+ .type mohawk_crval, #object
+mohawk_crval:
+ crval clear=0x00007f3f, mmuset=0x00003905, ucset=0x00001134
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __88sv331x_proc_info,#object
+__88sv331x_proc_info:
+ .long 0x56158000 @ Marvell 88SV331x (MOHAWK)
+ .long 0xfffff000
+ .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 __mohawk_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long cpu_mohawk_name
+ .long mohawk_processor_functions
+ .long v4wbi_tlb_fns
+ .long v4wb_user_fns
+ .long mohawk_cache_fns
+ .size __88sv331x_proc_info, . - __88sv331x_proc_info
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
new file mode 100644
index 00000000..46f09ed1
--- /dev/null
+++ b/arch/arm/mm/proc-sa110.S
@@ -0,0 +1,253 @@
+/*
+ * linux/arch/arm/mm/proc-sa110.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for SA110
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the StrongARM-110.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <mach/hardware.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+#include <asm/ptrace.h>
+
+#include "proc-macros.S"
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE 32
+
+ .text
+
+/*
+ * cpu_sa110_proc_init()
+ */
+ENTRY(cpu_sa110_proc_init)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
+ mov pc, lr
+
+/*
+ * cpu_sa110_proc_fin()
+ */
+ENTRY(cpu_sa110_proc_fin)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_sa110_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_sa110_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_sa110_do_idle(type)
+ *
+ * Cause the processor to idle
+ *
+ * type: call type:
+ * 0 = slow idle
+ * 1 = fast idle
+ * 2 = switch to slow processor clock
+ * 3 = switch to fast processor clock
+ */
+ .align 5
+
+ENTRY(cpu_sa110_do_idle)
+ mcr p15, 0, ip, c15, c2, 2 @ disable clock switching
+ ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc
+ ldr r1, [r1, #0] @ force switch to MCLK
+ mov r0, r0 @ safety
+ mov r0, r0 @ safety
+ mov r0, r0 @ safety
+ mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned
+ mov r0, r0 @ safety
+ mov r0, r0 @ safety
+ mov r0, r0 @ safety
+ mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ * cpu_sa110_dcache_clean_area(addr,sz)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+ .align 5
+ENTRY(cpu_sa110_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #DCACHELINESIZE
+ bhi 1b
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_sa110_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_sa110_switch_mm)
+#ifdef CONFIG_MMU
+ str lr, [sp, #-4]!
+ bl v4wb_flush_kern_cache_all @ clears IP
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ ldr pc, [sp], #4
+#else
+ mov pc, lr
+#endif
+
+/*
+ * cpu_sa110_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_sa110_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext wc_disable=0
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+ __CPUINIT
+
+ .type __sa110_setup, #function
+__sa110_setup:
+ mov r10, #0
+ mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+
+ adr r5, sa110_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __sa110_setup, . - __sa110_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..01 0001 ..11 1101
+ *
+ */
+ .type sa110_crval, #object
+sa110_crval:
+ crval clear=0x00003f3f, mmuset=0x0000113d, ucset=0x00001130
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __sa110_proc_info,#object
+__sa110_proc_info:
+ .long 0x4401a100
+ .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 __sa110_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
+ .long cpu_sa110_name
+ .long sa110_processor_functions
+ .long v4wb_tlb_fns
+ .long v4wb_user_fns
+ .long v4wb_cache_fns
+ .size __sa110_proc_info, . - __sa110_proc_info
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
new file mode 100644
index 00000000..184a9c99
--- /dev/null
+++ b/arch/arm/mm/proc-sa1100.S
@@ -0,0 +1,332 @@
+/*
+ * linux/arch/arm/mm/proc-sa1100.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ * hacked for non-paged-MM by Hyok S. Choi, 2003.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for SA110
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the StrongARM-1100 and StrongARM-1110.
+ *
+ * Note that SA1100 and SA1110 share everything but their name and CPU ID.
+ *
+ * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ * Flush the read buffer at context switches
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <mach/hardware.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+
+#include "proc-macros.S"
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE 32
+
+ __INIT
+
+/*
+ * cpu_sa1100_proc_init()
+ */
+ENTRY(cpu_sa1100_proc_init)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
+ mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland
+ mov pc, lr
+
+ .section .text
+
+/*
+ * cpu_sa1100_proc_fin()
+ *
+ * Prepare the CPU for reset:
+ * - Disable interrupts
+ * - Clean and turn off caches.
+ */
+ENTRY(cpu_sa1100_proc_fin)
+ mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_sa1100_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_sa1100_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+#ifdef CONFIG_MMU
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+#endif
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_sa1100_do_idle(type)
+ *
+ * Cause the processor to idle
+ *
+ * type: call type:
+ * 0 = slow idle
+ * 1 = fast idle
+ * 2 = switch to slow processor clock
+ * 3 = switch to fast processor clock
+ */
+ .align 5
+ENTRY(cpu_sa1100_do_idle)
+ mov r0, r0 @ 4 nop padding
+ mov r0, r0
+ mov r0, r0
+ mov r0, r0 @ 4 nop padding
+ mov r0, r0
+ mov r0, r0
+ mov r0, #0
+ ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address
+ @ --- aligned to a cache line
+ mcr p15, 0, r0, c15, c2, 2 @ disable clock switching
+ ldr r1, [r1, #0] @ force switch to MCLK
+ mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt
+ mov r0, r0 @ safety
+ mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ * cpu_sa1100_dcache_clean_area(addr,sz)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+ .align 5
+ENTRY(cpu_sa1100_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #DCACHELINESIZE
+ bhi 1b
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_sa1100_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_sa1100_switch_mm)
+#ifdef CONFIG_MMU
+ str lr, [sp, #-4]!
+ bl v4wb_flush_kern_cache_all @ clears IP
+ mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ ldr pc, [sp], #4
+#else
+ mov pc, lr
+#endif
+
+/*
+ * cpu_sa1100_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_sa1100_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv3_set_pte_ext wc_disable=0
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+#endif
+ mov pc, lr
+
+.globl cpu_sa1100_suspend_size
+.equ cpu_sa1100_suspend_size, 4*4
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_sa1100_do_suspend)
+ stmfd sp!, {r4 - r7, lr}
+ mrc p15, 0, r4, c3, c0, 0 @ domain ID
+ mrc p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c1, c0, 0 @ control reg
+ stmia r0, {r4 - r7} @ store cp regs
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(cpu_sa1100_do_suspend)
+
+ENTRY(cpu_sa1100_do_resume)
+ ldmia r0, {r4 - r7} @ load cp regs
+ mov r1, #0
+ mcr p15, 0, r1, c8, c7, 0 @ flush I+D TLBs
+ mcr p15, 0, r1, c7, c7, 0 @ flush I&D cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, r1, c9, c0, 5 @ allow user space to use RB
+
+ mcr p15, 0, r4, c3, c0, 0 @ domain ID
+ mcr p15, 0, r5, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mov r0, r7 @ control register
+ mov r2, r5, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_sa1100_do_resume)
+#else
+#define cpu_sa1100_do_suspend 0
+#define cpu_sa1100_do_resume 0
+#endif
+
+ __CPUINIT
+
+ .type __sa1100_setup, #function
+__sa1100_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+#endif
+ adr r5, sa1100_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __sa1100_setup, . - __sa1100_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..11 0001 ..11 1101
+ *
+ */
+ .type sa1100_crval, #object
+sa1100_crval:
+ crval clear=0x00003f3f, mmuset=0x0000313d, ucset=0x00001130
+
+ __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
+
+ .type cpu_sa1100_name, #object
+cpu_sa1100_name:
+ .asciz "StrongARM-1100"
+ .size cpu_sa1100_name, . - cpu_sa1100_name
+
+ .type cpu_sa1110_name, #object
+cpu_sa1110_name:
+ .asciz "StrongARM-1110"
+ .size cpu_sa1110_name, . - cpu_sa1110_name
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __sa1100_proc_info,#object
+__sa1100_proc_info:
+ .long 0x4401a110
+ .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_sa1100_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
+
+ .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
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
new file mode 100644
index 00000000..3e6210b4
--- /dev/null
+++ b/arch/arm/mm/proc-syms.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/mm/proc-syms.c
+ *
+ * Copyright (C) 2000-2002 Russell King
+ *
+ * This program is free software; you can 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/mm.h>
+
+#include <asm/cacheflush.h>
+#include <asm/proc-fns.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+
+#ifndef MULTI_CPU
+EXPORT_SYMBOL(cpu_dcache_clean_area);
+EXPORT_SYMBOL(cpu_set_pte_ext);
+#else
+EXPORT_SYMBOL(processor);
+#endif
+
+#ifndef MULTI_CACHE
+EXPORT_SYMBOL(__cpuc_flush_kern_all);
+EXPORT_SYMBOL(__cpuc_flush_user_all);
+EXPORT_SYMBOL(__cpuc_flush_user_range);
+EXPORT_SYMBOL(__cpuc_coherent_kern_range);
+EXPORT_SYMBOL(__cpuc_flush_dcache_area);
+#else
+EXPORT_SYMBOL(cpu_cache);
+#endif
+
+#ifdef CONFIG_MMU
+#ifndef MULTI_USER
+EXPORT_SYMBOL(__cpu_clear_user_highpage);
+EXPORT_SYMBOL(__cpu_copy_user_highpage);
+#else
+EXPORT_SYMBOL(cpu_user);
+#endif
+#endif
+
+/*
+ * No module should need to touch the TLB (and currently
+ * no modules do. We export this for "loadkernel" support
+ * (booting a new kernel from within a running kernel.)
+ */
+#ifdef MULTI_TLB
+EXPORT_SYMBOL(cpu_tlb);
+#endif
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
new file mode 100644
index 00000000..10c93632
--- /dev/null
+++ b/arch/arm/mm/proc-v6.S
@@ -0,0 +1,320 @@
+/*
+ * linux/arch/arm/mm/proc-v6.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Modified by Catalin Marinas for noMMU 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.
+ *
+ * This is the "shell" of the ARMv6 processor support.
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+
+#include "proc-macros.S"
+
+#define D_CACHE_LINE_SIZE 32
+
+#define TTB_C (1 << 0)
+#define TTB_S (1 << 1)
+#define TTB_IMP (1 << 2)
+#define TTB_RGN_NC (0 << 3)
+#define TTB_RGN_WBWA (1 << 3)
+#define TTB_RGN_WT (2 << 3)
+#define TTB_RGN_WB (3 << 3)
+
+#define TTB_FLAGS_UP TTB_RGN_WBWA
+#define PMD_FLAGS_UP PMD_SECT_WB
+#define TTB_FLAGS_SMP TTB_RGN_WBWA|TTB_S
+#define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
+
+ENTRY(cpu_v6_proc_init)
+ mov pc, lr
+
+ENTRY(cpu_v6_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x0006 @ .............ca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_v6_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * - loc - location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_v6_reset)
+ mov pc, r0
+
+/*
+ * cpu_v6_do_idle()
+ *
+ * Idle the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_v6_do_idle)
+ mov r1, #0
+ mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode
+ mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt
+ mov pc, lr
+
+ENTRY(cpu_v6_dcache_clean_area)
+#ifndef TLB_CAN_READ_FROM_L1_CACHE
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #D_CACHE_LINE_SIZE
+ subs r1, r1, #D_CACHE_LINE_SIZE
+ bhi 1b
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm926_switch_mm(pgd_phys, tsk)
+ *
+ * Set the translation table base pointer to be pgd_phys
+ *
+ * - pgd_phys - physical address of new TTB
+ *
+ * It is assumed that:
+ * - we are not using split page tables
+ */
+ENTRY(cpu_v6_switch_mm)
+#ifdef CONFIG_MMU
+ mov r2, #0
+ ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
+ ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
+ ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
+ mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
+ mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
+ mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ mcr p15, 0, r1, c13, c0, 1 @ set context ID
+#endif
+ mov pc, lr
+
+/*
+ * cpu_v6_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a level 2 translation table entry.
+ *
+ * - ptep - pointer to level 2 translation table entry
+ * (hardware version is stored at -1024 bytes)
+ * - pte - PTE value to store
+ * - ext - value for extended PTE bits
+ */
+ armv6_mt_table cpu_v6
+
+ENTRY(cpu_v6_set_pte_ext)
+#ifdef CONFIG_MMU
+ armv6_set_pte_ext cpu_v6
+#endif
+ mov pc, lr
+
+/* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */
+.globl cpu_v6_suspend_size
+.equ cpu_v6_suspend_size, 4 * 8
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_v6_do_suspend)
+ stmfd sp!, {r4 - r11, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mrc p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control register
+ mrc p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mrc p15, 0, r11, c1, c0, 0 @ control register
+ stmia r0, {r4 - r11}
+ ldmfd sp!, {r4- r11, pc}
+ENDPROC(cpu_v6_do_suspend)
+
+ENTRY(cpu_v6_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ ldmia r0, {r4 - r11}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r7, c2, c0, 0 @ Translation table base 0
+ mcr p15, 0, r8, c2, c0, 1 @ Translation table base 1
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control register
+ mcr p15, 0, r10, c1, c0, 2 @ co-processor access control
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, ip, c7, c5, 4 @ ISB
+ mov r0, r11 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v6_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v6_do_suspend 0
+#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
+
+ .align
+
+ __CPUINIT
+
+/*
+ * __v6_setup
+ *
+ * Initialise TLB, Caches, and MMU state ready to switch the MMU
+ * on. Return in r0 the new CP15 C1 control register setting.
+ *
+ * We automatically detect if we have a Harvard cache, and use the
+ * Harvard cache control instructions insead of the unified cache
+ * control instructions.
+ *
+ * This should be able to cover all ARMv6 cores.
+ *
+ * It is assumed that:
+ * - cache type register is implemented
+ */
+__v6_setup:
+#ifdef CONFIG_SMP
+ ALT_SMP(mrc p15, 0, r0, c1, c0, 1) @ Enable SMP/nAMP mode
+ ALT_UP(nop)
+ orr r0, r0, #0x20
+ ALT_SMP(mcr p15, 0, r0, c1, c0, 1)
+ ALT_UP(nop)
+#endif
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
+#ifdef CONFIG_MMU
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
+ mcr p15, 0, r0, c2, c0, 2 @ TTB control register
+ ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
+ ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
+ ALT_SMP(orr r8, r8, #TTB_FLAGS_SMP)
+ ALT_UP(orr r8, r8, #TTB_FLAGS_UP)
+ mcr p15, 0, r8, c2, c0, 1 @ load TTB1
+#endif /* CONFIG_MMU */
+ adr r5, v6_crval
+ ldmia r5, {r5, r6}
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ orr r6, r6, #1 << 25 @ big-endian page tables
+#endif
+ mrc p15, 0, r0, c1, c0, 0 @ read control register
+ bic r0, r0, r5 @ clear bits them
+ orr r0, r0, r6 @ set them
+#ifdef CONFIG_ARM_ERRATA_364296
+ /* Workaround for the 364296 ARM1136 r0pX errata (possible cache data
+ * corruption with hit-under-miss enabled). The conditional code below
+ * (setting the undocumented bit 31 in the auxiliary control register
+ * and the FI bit in the control register) disables hit-under-miss
+ * without putting the processor into full low interrupt latency mode.
+ */
+ ldr r6, =0x4107b360 @ id for ARM1136 r0pX
+ mrc p15, 0, r5, c0, c0, 0 @ get processor id
+ bic r5, r5, #0xf @ mask out part bits [3:0]
+ teq r5, r6 @ check for the faulty core
+ mrceq p15, 0, r5, c1, c0, 1 @ load aux control reg
+ orreq r5, r5, #(1 << 31) @ set the undocumented bit 31
+ mcreq p15, 0, r5, c1, c0, 1 @ write aux control reg
+ orreq r0, r0, #(1 << 21) @ low interrupt latency configuration
+#endif
+ mov pc, lr @ return to head.S:__ret
+
+ /*
+ * V X F I D LR
+ * .... ...E PUI. .T.T 4RVI ZFRS BLDP WCAM
+ * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
+ * 0 110 0011 1.00 .111 1101 < we want
+ */
+ .type v6_crval, #object
+v6_crval:
+ crval clear=0x01e0fb7f, mmuset=0x00c0387d, ucset=0x00c0187c
+
+ __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
+
+ .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
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ /*
+ * Match any ARMv6 processor core.
+ */
+ .type __v6_proc_info, #object
+__v6_proc_info:
+ .long 0x0007b000
+ .long 0x0007f000
+ 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
+ b __v6_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ /* See also feat_v6_fixup() for HWCAP_TLS */
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA|HWCAP_TLS
+ .long cpu_v6_name
+ .long v6_processor_functions
+ .long v6wbi_tlb_fns
+ .long v6_user_fns
+ .long v6_cache_fns
+ .size __v6_proc_info, . - __v6_proc_info
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
new file mode 100644
index 00000000..21cd2983
--- /dev/null
+++ b/arch/arm/mm/proc-v7.S
@@ -0,0 +1,508 @@
+/*
+ * linux/arch/arm/mm/proc-v7.S
+ *
+ * Copyright (C) 2001 Deep Blue Solutions 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.
+ *
+ * This is the "shell" of the ARMv7 processor support.
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/pgtable.h>
+
+#include "proc-macros.S"
+
+#define TTB_S (1 << 1)
+#define TTB_RGN_NC (0 << 3)
+#define TTB_RGN_OC_WBWA (1 << 3)
+#define TTB_RGN_OC_WT (2 << 3)
+#define TTB_RGN_OC_WB (3 << 3)
+#define TTB_NOS (1 << 5)
+#define TTB_IRGN_NC ((0 << 0) | (0 << 6))
+#define TTB_IRGN_WBWA ((0 << 0) | (1 << 6))
+#define TTB_IRGN_WT ((1 << 0) | (0 << 6))
+#define TTB_IRGN_WB ((1 << 0) | (1 << 6))
+
+/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
+#define TTB_FLAGS_UP TTB_IRGN_WB|TTB_RGN_OC_WB
+#define PMD_FLAGS_UP PMD_SECT_WB
+
+/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
+#define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
+#define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S
+
+ENTRY(cpu_v7_proc_init)
+ mov pc, lr
+ENDPROC(cpu_v7_proc_init)
+
+ENTRY(cpu_v7_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x0006 @ .............ca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+ENDPROC(cpu_v7_proc_fin)
+
+/*
+ * cpu_v7_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * - loc - location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_v7_reset)
+ mov pc, r0
+ENDPROC(cpu_v7_reset)
+
+/*
+ * cpu_v7_do_idle()
+ *
+ * Idle the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_v7_do_idle)
+ dsb @ WFI may enter a low-power mode
+ wfi
+ mov pc, lr
+ENDPROC(cpu_v7_do_idle)
+
+ENTRY(cpu_v7_dcache_clean_area)
+#ifndef TLB_CAN_READ_FROM_L1_CACHE
+ dcache_line_size r2, r3
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, r2
+ subs r1, r1, r2
+ bhi 1b
+ dsb
+#endif
+ mov pc, lr
+ENDPROC(cpu_v7_dcache_clean_area)
+
+/*
+ * cpu_v7_switch_mm(pgd_phys, tsk)
+ *
+ * Set the translation table base pointer to be pgd_phys
+ *
+ * - pgd_phys - physical address of new TTB
+ *
+ * It is assumed that:
+ * - we are not using split page tables
+ */
+ENTRY(cpu_v7_switch_mm)
+#ifdef CONFIG_MMU
+ mov r2, #0
+ ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
+ ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
+ ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
+#ifdef CONFIG_ARM_ERRATA_430973
+ mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
+#endif
+#ifdef CONFIG_ARM_ERRATA_754322
+ dsb
+#endif
+ mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
+ isb
+1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ isb
+#ifdef CONFIG_ARM_ERRATA_754322
+ dsb
+#endif
+ mcr p15, 0, r1, c13, c0, 1 @ set context ID
+ isb
+#endif
+ mov pc, lr
+ENDPROC(cpu_v7_switch_mm)
+
+/*
+ * cpu_v7_set_pte_ext(ptep, pte)
+ *
+ * Set a level 2 translation table entry.
+ *
+ * - ptep - pointer to level 2 translation table entry
+ * (hardware version is stored at +2048 bytes)
+ * - pte - PTE value to store
+ * - ext - value for extended PTE bits
+ */
+ENTRY(cpu_v7_set_pte_ext)
+#ifdef CONFIG_MMU
+ str r1, [r0] @ linux version
+
+ bic r3, r1, #0x000003f0
+ bic r3, r3, #PTE_TYPE_MASK
+ orr r3, r3, r2
+ orr r3, r3, #PTE_EXT_AP0 | 2
+
+ tst r1, #1 << 4
+ orrne r3, r3, #PTE_EXT_TEX(1)
+
+ eor r1, r1, #L_PTE_DIRTY
+ tst r1, #L_PTE_RDONLY | L_PTE_DIRTY
+ orrne r3, r3, #PTE_EXT_APX
+
+ tst r1, #L_PTE_USER
+ orrne r3, r3, #PTE_EXT_AP1
+#ifdef CONFIG_CPU_USE_DOMAINS
+ @ allow kernel read/write access to read-only user pages
+ tstne r3, #PTE_EXT_APX
+ bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
+#endif
+
+ tst r1, #L_PTE_XN
+ orrne r3, r3, #PTE_EXT_XN
+
+ tst r1, #L_PTE_YOUNG
+ tstne r1, #L_PTE_PRESENT
+ moveq r3, #0
+
+ ARM( str r3, [r0, #2048]! )
+ THUMB( add r0, r0, #2048 )
+ THUMB( str r3, [r0] )
+ mcr p15, 0, r0, c7, c10, 1 @ flush_pte
+#endif
+ mov pc, lr
+ENDPROC(cpu_v7_set_pte_ext)
+
+cpu_v7_name:
+ .ascii "ARMv7 Processor"
+ .align
+
+ /*
+ * Memory region attributes with SCTLR.TRE=1
+ *
+ * n = TEX[0],C,B
+ * TR = PRRR[2n+1:2n] - memory type
+ * IR = NMRR[2n+1:2n] - inner cacheable property
+ * OR = NMRR[2n+17:2n+16] - outer cacheable property
+ *
+ * n TR IR OR
+ * UNCACHED 000 00
+ * BUFFERABLE 001 10 00 00
+ * WRITETHROUGH 010 10 10 10
+ * WRITEBACK 011 10 11 11
+ * reserved 110
+ * WRITEALLOC 111 10 01 01
+ * DEV_SHARED 100 01
+ * DEV_NONSHARED 100 01
+ * DEV_WC 001 10
+ * DEV_CACHED 011 10
+ *
+ * Other attributes:
+ *
+ * DS0 = PRRR[16] = 0 - device shareable property
+ * DS1 = PRRR[17] = 1 - device shareable property
+ * NS0 = PRRR[18] = 0 - normal shareable property
+ * NS1 = PRRR[19] = 1 - normal shareable property
+ * NOS = PRRR[24+n] = 1 - not outer shareable
+ */
+.equ PRRR, 0xff0a81a8
+.equ NMRR, 0x40e040e0
+
+/* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
+.globl cpu_v7_suspend_size
+.equ cpu_v7_suspend_size, 4 * 9
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_v7_do_suspend)
+ stmfd sp!, {r4 - r11, lr}
+ mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mrc p15, 0, r5, c13, c0, 1 @ Context ID
+ mrc p15, 0, r6, c13, c0, 3 @ User r/o thread ID
+ stmia r0!, {r4 - r6}
+ mrc p15, 0, r6, c3, c0, 0 @ Domain ID
+ mrc p15, 0, r7, c2, c0, 0 @ TTB 0
+ mrc p15, 0, r8, c2, c0, 1 @ TTB 1
+ mrc p15, 0, r9, c1, c0, 0 @ Control register
+ mrc p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mrc p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ stmia r0, {r6 - r11}
+ ldmfd sp!, {r4 - r11, pc}
+ENDPROC(cpu_v7_do_suspend)
+
+ENTRY(cpu_v7_do_resume)
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate TLBs
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ ldmia r0!, {r4 - r6}
+ mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID
+ mcr p15, 0, r5, c13, c0, 1 @ Context ID
+ mcr p15, 0, r6, c13, c0, 3 @ User r/o thread ID
+ ldmia r0, {r6 - r11}
+ mcr p15, 0, r6, c3, c0, 0 @ Domain ID
+ mcr p15, 0, r7, c2, c0, 0 @ TTB 0
+ mcr p15, 0, r8, c2, c0, 1 @ TTB 1
+ mcr p15, 0, ip, c2, c0, 2 @ TTB control register
+ mcr p15, 0, r10, c1, c0, 1 @ Auxiliary control register
+ mcr p15, 0, r11, c1, c0, 2 @ Co-processor access control
+ ldr r4, =PRRR @ PRRR
+ ldr r5, =NMRR @ NMRR
+ mcr p15, 0, r4, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r5, c10, c2, 1 @ write NMRR
+ isb
+ mov r0, r9 @ control register
+ mov r2, r7, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, cpu_resume_l1_flags
+ b cpu_resume_mmu
+ENDPROC(cpu_v7_do_resume)
+cpu_resume_l1_flags:
+ ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_SMP)
+ ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_FLAGS_UP)
+#else
+#define cpu_v7_do_suspend 0
+#define cpu_v7_do_resume 0
+#endif
+
+ __CPUINIT
+
+/*
+ * __v7_setup
+ *
+ * Initialise TLB, Caches, and MMU state ready to switch the MMU
+ * on. Return in r0 the new CP15 C1 control register setting.
+ *
+ * This should be able to cover all ARMv7 cores.
+ *
+ * It is assumed that:
+ * - cache type register is implemented
+ */
+__v7_ca9mp_setup:
+#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
+#endif
+__v7_setup:
+ adr r12, __v7_setup_stack @ the local stack
+ stmia r12, {r0-r5, r7, r9, r11, lr}
+ bl v7_flush_dcache_all
+ ldmia r12, {r0-r5, r7, r9, r11, lr}
+
+ mrc p15, 0, r0, c0, c0, 0 @ read main ID register
+ and r10, r0, #0xff000000 @ ARM?
+ teq r10, #0x41000000
+ bne 3f
+ and r5, r0, #0x00f00000 @ variant
+ and r6, r0, #0x0000000f @ revision
+ orr r6, r6, r5, lsr #20-4 @ combine variant and revision
+ ubfx r0, r0, #4, #12 @ primary part number
+
+ /* Cortex-A8 Errata */
+ ldr r10, =0x00000c08 @ Cortex-A8 primary part number
+ teq r0, r10
+ bne 2f
+#ifdef CONFIG_ARM_ERRATA_430973
+ teq r5, #0x00100000 @ only present in r1p*
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #(1 << 6) @ set IBE to 1
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#ifdef CONFIG_ARM_ERRATA_458693
+ teq r6, #0x20 @ only present in r2p0
+ mrceq p15, 0, r10, c1, c0, 1 @ read aux control register
+ orreq r10, r10, #(1 << 5) @ set L1NEON to 1
+ orreq r10, r10, #(1 << 9) @ set PLDNOP to 1
+ mcreq p15, 0, r10, c1, c0, 1 @ write aux control register
+#endif
+#ifdef CONFIG_ARM_ERRATA_460075
+ teq r6, #0x20 @ only present in r2p0
+ mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register
+ tsteq r10, #1 << 22
+ 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
+
+ /* Cortex-A9 Errata */
+2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
+ teq r0, r10
+ bne 3f
+#ifdef CONFIG_ARM_ERRATA_742230
+ cmp r6, #0x22 @ only present up to r2p2
+ mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orrle r10, r10, #1 << 4 @ set bit #4
+ mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_742231
+ teq r6, #0x20 @ present in r2p0
+ teqne r6, #0x21 @ present in r2p1
+ teqne r6, #0x22 @ present in r2p2
+ mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orreq r10, r10, #1 << 12 @ set bit #12
+ orreq r10, r10, #1 << 22 @ set bit #22
+ mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
+#ifdef CONFIG_ARM_ERRATA_743622
+ teq r5, #0x00200000 @ only 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
+#endif
+#ifdef CONFIG_ARM_ERRATA_751472
+ cmp r6, #0x30 @ present prior to r3p0
+ mrclt p15, 0, r10, c15, c0, 1 @ read diagnostic register
+ orrlt r10, r10, #1 << 11 @ set bit #11
+ mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
+#endif
+
+3: mov r10, #0
+ mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
+ dsb
+#ifdef CONFIG_MMU
+ mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
+ mcr p15, 0, r10, c2, c0, 2 @ TTB control register
+ ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP)
+ ALT_UP(orr r4, r4, #TTB_FLAGS_UP)
+ ALT_SMP(orr r8, r8, #TTB_FLAGS_SMP)
+ ALT_UP(orr r8, r8, #TTB_FLAGS_UP)
+ mcr p15, 0, r8, c2, c0, 1 @ load TTB1
+ ldr r5, =PRRR @ PRRR
+ ldr r6, =NMRR @ NMRR
+ mcr p15, 0, r5, c10, c2, 0 @ write PRRR
+ mcr p15, 0, r6, c10, c2, 1 @ write NMRR
+#endif
+#ifndef CONFIG_ARM_THUMBEE
+ mrc p15, 0, r0, c0, c1, 0 @ read ID_PFR0 for ThumbEE
+ and r0, r0, #(0xf << 12) @ ThumbEE enabled field
+ teq r0, #(1 << 12) @ check if ThumbEE is present
+ bne 1f
+ mov r5, #0
+ mcr p14, 6, r5, c1, c0, 0 @ Initialize TEEHBR to 0
+ mrc p14, 6, r0, c0, c0, 0 @ load TEECR
+ orr r0, r0, #1 @ set the 1st bit in order to
+ mcr p14, 6, r0, c0, c0, 0 @ stop userspace TEEHBR access
+1:
+#endif
+ adr r5, v7_crval
+ ldmia r5, {r5, r6}
+#ifdef CONFIG_CPU_ENDIAN_BE8
+ orr r6, r6, #1 << 25 @ big-endian page tables
+#endif
+#ifdef CONFIG_SWP_EMULATE
+ orr r5, r5, #(1 << 10) @ set SW bit in "clear"
+ bic r6, r6, #(1 << 10) @ clear it in "mmuset"
+#endif
+ mrc p15, 0, r0, c1, c0, 0 @ read control register
+ bic r0, r0, r5 @ clear bits them
+ orr r0, r0, r6 @ set them
+ THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions
+ mov pc, lr @ return to head.S:__ret
+ENDPROC(__v7_setup)
+
+ /* AT
+ * TFR EV X F I D LR S
+ * .EEE ..EE PUI. .T.T 4RVI ZWRS BLDP WCAM
+ * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced
+ * 1 0 110 0011 1100 .111 1101 < we want
+ */
+ .type v7_crval, #object
+v7_crval:
+ crval clear=0x0120c302, mmuset=0x10c03c7d, ucset=0x00c01c7c
+
+__v7_setup_stack:
+ .space 4 * 11 @ 11 registers
+
+ __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
+
+ .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
+ .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
+ .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
+ .size __v7_ca9mp_proc_info, . - __v7_ca9mp_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
+ .size __v7_proc_info, . - __v7_proc_info
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
new file mode 100644
index 00000000..59621369
--- /dev/null
+++ b/arch/arm/mm/proc-xsc3.S
@@ -0,0 +1,594 @@
+/*
+ * linux/arch/arm/mm/proc-xsc3.S
+ *
+ * Original Author: Matthew Gilbert
+ * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * Copyright 2004 (C) Intel Corp.
+ * Copyright 2005 (C) MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is
+ * an extension to Intel's original XScale core that adds the following
+ * features:
+ *
+ * - ARMv6 Supersections
+ * - Low Locality Reference pages (replaces mini-cache)
+ * - 36-bit addressing
+ * - L2 cache
+ * - Cache coherency if chipset supports it
+ *
+ * Based on original XScale code by Nicolas Pitre.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed. If the
+ * area is larger than this, then we flush the whole cache.
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * The cache line size of the L1 I, L1 D and unified L2 cache.
+ */
+#define CACHELINESIZE 32
+
+/*
+ * The size of the L1 D cache.
+ */
+#define CACHESIZE 32768
+
+/*
+ * This macro is used to wait for a CP15 write and is needed when we
+ * have to ensure that the last operation to the coprocessor was
+ * completed before continuing with operation.
+ */
+ .macro cpwait_ret, lr, rd
+ mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
+ sub pc, \lr, \rd, LSR #32 @ wait for completion and
+ @ flush instruction pipeline
+ .endm
+
+/*
+ * This macro cleans and invalidates the entire L1 D cache.
+ */
+
+ .macro clean_d_cache rd, rs
+ mov \rd, #0x1f00
+ orr \rd, \rd, #0x00e0
+1: mcr p15, 0, \rd, c7, c14, 2 @ clean/invalidate L1 D line
+ adds \rd, \rd, #0x40000000
+ bcc 1b
+ subs \rd, \rd, #0x20
+ bpl 1b
+ .endm
+
+ .text
+
+/*
+ * cpu_xsc3_proc_init()
+ *
+ * Nothing too exciting at the moment
+ */
+ENTRY(cpu_xsc3_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_xsc3_proc_fin()
+ */
+ENTRY(cpu_xsc3_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1800 @ ...IZ...........
+ bic r0, r0, #0x0006 @ .............CA.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_xsc3_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_xsc3_reset)
+ mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+ msr cpsr_c, r1 @ reset CPSR
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x3900 @ ..VIZ..S........
+ bic r1, r1, #0x0086 @ ........B....CA.
+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
+ bic r1, r1, #0x0001 @ ...............M
+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
+ @ CAUTION: MMU turned off from this point. We count on the pipeline
+ @ already containing those two last instructions to survive.
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
+ mov pc, r0
+
+/*
+ * cpu_xsc3_do_idle()
+ *
+ * Cause the processor to idle
+ *
+ * For now we do nothing but go to idle mode for every case
+ *
+ * XScale supports clock switching, but using idle mode support
+ * allows external hardware to react to system state changes.
+ */
+ .align 5
+
+ENTRY(cpu_xsc3_do_idle)
+ mov r0, #1
+ mcr p14, 0, r0, c7, c0, 0 @ go to idle
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xsc3_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(xsc3_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(xsc3_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(xsc3_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ clean_d_cache r0, r1
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, vm_flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - vma - vma_area_struct describing address space
+ */
+ .align 5
+ENTRY(xsc3_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #MAX_AREA_SIZE
+ bhs __flush_whole_cache
+
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate L1 I line
+ mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the I cache and the D cache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * Note: single I-cache line invalidation isn't used here since
+ * it also trashes the mini I-cache used by JTAG debuggers.
+ */
+ENTRY(xsc3_coherent_kern_range)
+/* FALLTHROUGH */
+ENTRY(xsc3_coherent_user_range)
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache.
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(xsc3_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+xsc3_dma_inv_range:
+ tst r0, #CACHELINESIZE - 1
+ bic r0, r0, #CACHELINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ tst r1, #CACHELINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D line
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+xsc3_dma_clean_range:
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(xsc3_dma_flush_range)
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ data write barrier
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(xsc3_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq xsc3_dma_clean_range
+ bcs xsc3_dma_inv_range
+ b xsc3_dma_flush_range
+ENDPROC(xsc3_dma_map_area)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+ENTRY(cpu_xsc3_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
+ add r0, r0, #CACHELINESIZE
+ subs r1, r1, #CACHELINESIZE
+ bhi 1b
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_xsc3_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_xsc3_switch_mm)
+ clean_d_cache r1, r2
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
+ mcr p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
+ orr r0, r0, #0x18 @ cache the page table in L2
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
+ cpwait_ret lr, ip
+
+/*
+ * cpu_xsc3_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ */
+cpu_xsc3_mt_table:
+ .long 0x00 @ L_PTE_MT_UNCACHED
+ .long PTE_EXT_TEX(1) @ L_PTE_MT_BUFFERABLE
+ .long PTE_EXT_TEX(5) | PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK
+ .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED
+ .long 0x00 @ unused
+ .long 0x00 @ L_PTE_MT_MINICACHE (not present)
+ .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC (not present?)
+ .long 0x00 @ unused
+ .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC
+ .long 0x00 @ unused
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED
+ .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+
+ .align 5
+ENTRY(cpu_xsc3_set_pte_ext)
+ xscale_set_pte_ext_prologue
+
+ tst r1, #L_PTE_SHARED @ shared?
+ and r1, r1, #L_PTE_MT_MASK
+ adr ip, cpu_xsc3_mt_table
+ ldr ip, [ip, r1]
+ orrne r2, r2, #PTE_EXT_COHERENT @ interlock: mask in coherent bit
+ bic r2, r2, #0x0c @ clear old C,B bits
+ orr r2, r2, ip
+
+ xscale_set_pte_ext_epilogue
+ mov pc, lr
+
+ .ltorg
+ .align
+
+.globl cpu_xsc3_suspend_size
+.equ cpu_xsc3_suspend_size, 4 * 8
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_xsc3_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r1, r4 - r10} @ store v:p offset + cp regs
+ ldmia sp!, {r4 - r10, pc}
+ENDPROC(cpu_xsc3_do_suspend)
+
+ENTRY(cpu_xsc3_do_resume)
+ ldmia r0, {r1, r4 - r10} @ load v:p offset + cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer
+ mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c0, 1 @ auxiliary control reg
+
+ @ temporarily map resume_turn_on_mmu into the page table,
+ @ otherwise prefetch abort occurs after MMU is turned on
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =0x542e @ section flags
+ b cpu_resume_mmu
+ENDPROC(cpu_xsc3_do_resume)
+#else
+#define cpu_xsc3_do_suspend 0
+#define cpu_xsc3_do_resume 0
+#endif
+
+ __CPUINIT
+
+ .type __xsc3_setup, #function
+__xsc3_setup:
+ mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+ msr cpsr_c, r0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
+ mcr p15, 0, ip, c7, c10, 4 @ data write barrier
+ mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
+ orr r4, r4, #0x18 @ cache the page table in L2
+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
+
+ mov r0, #1 << 6 @ cp6 access for early sched_clock
+ mcr p15, 0, r0, c15, c1, 0 @ write CP access register
+
+ mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg
+ and r0, r0, #2 @ preserve bit P bit setting
+ orr r0, r0, #(1 << 10) @ enable L2 for LLR cache
+ mcr p15, 0, r0, c1, c0, 1 @ set auxiliary control reg
+
+ adr r5, xsc3_crval
+ ldmia r5, {r5, r6}
+
+#ifdef CONFIG_CACHE_XSC3L2
+ mrc p15, 1, r0, c0, c0, 1 @ get L2 present information
+ ands r0, r0, #0xf8
+ orrne r6, r6, #(1 << 26) @ enable L2 if present
+#endif
+
+ mrc p15, 0, r0, c1, c0, 0 @ get control register
+ bic r0, r0, r5 @ ..V. ..R. .... ..A.
+ orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu)
+ @ ...I Z..S .... .... (uc)
+ mov pc, lr
+
+ .size __xsc3_setup, . - __xsc3_setup
+
+ .type xsc3_crval, #object
+xsc3_crval:
+ crval clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
+
+ __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
+
+ .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
+
+ .align
+
+ .section ".proc.info.init", #alloc, #execinstr
+
+ .type __xsc3_proc_info,#object
+__xsc3_proc_info:
+ .long 0x69056000
+ .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_proc_info, . - __xsc3_proc_info
+
+/* Note: PXA935 changed its implementor ID from Intel to Marvell */
+
+ .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
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
new file mode 100644
index 00000000..42af9766
--- /dev/null
+++ b/arch/arm/mm/proc-xscale.S
@@ -0,0 +1,1018 @@
+/*
+ * linux/arch/arm/mm/proc-xscale.S
+ *
+ * Author: Nicolas Pitre
+ * Created: November 2000
+ * Copyright: (C) 2000, 2001 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for the Intel XScale CPUs
+ *
+ * 2001 Aug 21:
+ * some contributions by Brett Gaines <brett.w.gaines@intel.com>
+ * Copyright 2001 by Intel Corp.
+ *
+ * 2001 Sep 08:
+ * Completely revisited, many important fixes
+ * Nicolas Pitre <nico@fluxnic.net>
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+#include <asm/hwcap.h>
+#include <asm/pgtable.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include "proc-macros.S"
+
+/*
+ * This is the maximum size of an area which will be flushed. If the area
+ * is larger than this, then we flush the whole cache
+ */
+#define MAX_AREA_SIZE 32768
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define CACHELINESIZE 32
+
+/*
+ * the size of the data cache
+ */
+#define CACHESIZE 32768
+
+/*
+ * Virtual address used to allocate the cache when flushed
+ *
+ * This must be an address range which is _never_ used. It should
+ * apparently have a mapping in the corresponding page table for
+ * compatibility with future CPUs that _could_ require it. For instance we
+ * don't care.
+ *
+ * This must be aligned on a 2*CACHESIZE boundary. The code selects one of
+ * the 2 areas in alternance each time the clean_d_cache macro is used.
+ * Without this the XScale core exhibits cache eviction problems and no one
+ * knows why.
+ *
+ * Reminder: the vector table is located at 0xffff0000-0xffff0fff.
+ */
+#define CLEAN_ADDR 0xfffe0000
+
+/*
+ * This macro is used to wait for a CP15 write and is needed
+ * when we have to ensure that the last operation to the co-pro
+ * was completed before continuing with operation.
+ */
+ .macro cpwait, rd
+ mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
+ mov \rd, \rd @ wait for completion
+ sub pc, pc, #4 @ flush instruction pipeline
+ .endm
+
+ .macro cpwait_ret, lr, rd
+ mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
+ sub pc, \lr, \rd, LSR #32 @ wait for completion and
+ @ flush instruction pipeline
+ .endm
+
+/*
+ * This macro cleans the entire dcache using line allocate.
+ * The main loop has been unrolled to reduce loop overhead.
+ * rd and rs are two scratch registers.
+ */
+ .macro clean_d_cache, rd, rs
+ ldr \rs, =clean_addr
+ ldr \rd, [\rs]
+ eor \rd, \rd, #CACHESIZE
+ str \rd, [\rs]
+ add \rs, \rd, #CACHESIZE
+1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
+ add \rd, \rd, #CACHELINESIZE
+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
+ add \rd, \rd, #CACHELINESIZE
+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
+ add \rd, \rd, #CACHELINESIZE
+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
+ add \rd, \rd, #CACHELINESIZE
+ teq \rd, \rs
+ bne 1b
+ .endm
+
+ .data
+clean_addr: .word CLEAN_ADDR
+
+ .text
+
+/*
+ * cpu_xscale_proc_init()
+ *
+ * Nothing too exciting at the moment
+ */
+ENTRY(cpu_xscale_proc_init)
+ @ enable write buffer coalescing. Some bootloader disable it
+ mrc p15, 0, r1, c1, c0, 1
+ bic r1, r1, #1
+ mcr p15, 0, r1, c1, c0, 1
+ mov pc, lr
+
+/*
+ * cpu_xscale_proc_fin()
+ */
+ENTRY(cpu_xscale_proc_fin)
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1800 @ ...IZ...........
+ bic r0, r0, #0x0006 @ .............CA.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ mov pc, lr
+
+/*
+ * cpu_xscale_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ *
+ * Beware PXA270 erratum E7.
+ */
+ .align 5
+ENTRY(cpu_xscale_reset)
+ mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
+ msr cpsr_c, r1 @ reset CPSR
+ mcr p15, 0, r1, c10, c4, 1 @ unlock I-TLB
+ mcr p15, 0, r1, c8, c5, 0 @ invalidate I-TLB
+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x0086 @ ........B....CA.
+ bic r1, r1, #0x3900 @ ..VIZ..S........
+ sub pc, pc, #4 @ flush pipeline
+ @ *** cache line aligned ***
+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
+ bic r1, r1, #0x0001 @ ...............M
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB
+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
+ @ CAUTION: MMU turned off from this point. We count on the pipeline
+ @ already containing those two last instructions to survive.
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, r0
+
+/*
+ * cpu_xscale_do_idle()
+ *
+ * Cause the processor to idle
+ *
+ * For now we do nothing but go to idle mode for every case
+ *
+ * XScale supports clock switching, but using idle mode support
+ * allows external hardware to react to system state changes.
+ */
+ .align 5
+
+ENTRY(cpu_xscale_do_idle)
+ mov r0, #1
+ mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+/*
+ * flush_icache_all()
+ *
+ * Unconditionally clean and invalidate the entire icache.
+ */
+ENTRY(xscale_flush_icache_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+ENDPROC(xscale_flush_icache_all)
+
+/*
+ * flush_user_cache_all()
+ *
+ * Invalidate all cache entries in a particular address
+ * space.
+ */
+ENTRY(xscale_flush_user_cache_all)
+ /* FALLTHROUGH */
+
+/*
+ * flush_kern_cache_all()
+ *
+ * Clean and invalidate the entire cache.
+ */
+ENTRY(xscale_flush_kern_cache_all)
+ mov r2, #VM_EXEC
+ mov ip, #0
+__flush_whole_cache:
+ clean_d_cache r0, r1
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * flush_user_cache_range(start, end, vm_flags)
+ *
+ * Invalidate a range of cache entries in the specified
+ * address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - vma - vma_area_struct describing address space
+ */
+ .align 5
+ENTRY(xscale_flush_user_cache_range)
+ mov ip, #0
+ sub r3, r1, r0 @ calculate total size
+ cmp r3, #MAX_AREA_SIZE
+ bhs __flush_whole_cache
+
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
+ mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ tst r2, #VM_EXEC
+ mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB
+ mcrne p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * coherent_kern_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ *
+ * Note: single I-cache line invalidation isn't used here since
+ * it also trashes the mini I-cache used by JTAG debuggers.
+ */
+ENTRY(xscale_coherent_kern_range)
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * coherent_user_range(start, end)
+ *
+ * Ensure coherency between the Icache and the Dcache in the
+ * region described by start. If you have non-snooping
+ * Harvard caches, you need to implement this function.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(xscale_coherent_user_range)
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * flush_kern_dcache_area(void *addr, size_t size)
+ *
+ * Ensure no D cache aliasing occurs, either with itself or
+ * the I cache
+ *
+ * - addr - kernel address
+ * - size - region size
+ */
+ENTRY(xscale_flush_kern_dcache_area)
+ add r1, r0, r1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * dma_inv_range(start, end)
+ *
+ * Invalidate (discard) the specified virtual address range.
+ * May not write back any entries. If 'start' or 'end'
+ * are not cache line aligned, those lines must be written
+ * back.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+xscale_dma_inv_range:
+ tst r0, #CACHELINESIZE - 1
+ bic r0, r0, #CACHELINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #CACHELINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * dma_clean_range(start, end)
+ *
+ * Clean the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+xscale_dma_clean_range:
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * dma_flush_range(start, end)
+ *
+ * Clean and invalidate the specified virtual address range.
+ *
+ * - start - virtual start address
+ * - end - virtual end address
+ */
+ENTRY(xscale_dma_flush_range)
+ bic r0, r0, #CACHELINESIZE - 1
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #CACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mov pc, lr
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(xscale_dma_map_area)
+ add r1, r1, r0
+ cmp r2, #DMA_TO_DEVICE
+ beq xscale_dma_clean_range
+ bcs xscale_dma_inv_range
+ b xscale_dma_flush_range
+ENDPROC(xscale_dma_map_area)
+
+/*
+ * dma_map_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+ENTRY(xscale_dma_a0_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)
+
+/*
+ * dma_unmap_area(start, size, dir)
+ * - start - kernel virtual start address
+ * - size - size of region
+ * - dir - DMA direction
+ */
+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
+
+/*
+ * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't
+ * clear the dirty bits, which means that if we invalidate a dirty line,
+ * the dirty data can still be written back to external memory later on.
+ *
+ * The recommended workaround is to always do a clean D-cache line before
+ * doing an invalidate D-cache line, so on the affected processors,
+ * dma_inv_range() is implemented as dma_flush_range().
+ *
+ * See erratum #25 of "Intel 80200 Processor Specification Update",
+ * 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
+
+ENTRY(cpu_xscale_dcache_clean_area)
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #CACHELINESIZE
+ subs r1, r1, #CACHELINESIZE
+ bhi 1b
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_xscale_switch_mm(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_xscale_switch_mm)
+ clean_d_cache r1, r2
+ mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ cpwait_ret lr, ip
+
+/*
+ * cpu_xscale_set_pte_ext(ptep, pte, ext)
+ *
+ * Set a PTE and flush it out
+ *
+ * Errata 40: must set memory to write-through for user read-only pages.
+ */
+cpu_xscale_mt_table:
+ .long 0x00 @ L_PTE_MT_UNCACHED
+ .long PTE_BUFFERABLE @ L_PTE_MT_BUFFERABLE
+ .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK
+ .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED
+ .long 0x00 @ unused
+ .long PTE_EXT_TEX(1) | PTE_CACHEABLE @ L_PTE_MT_MINICACHE
+ .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC
+ .long 0x00 @ unused
+ .long PTE_BUFFERABLE @ L_PTE_MT_DEV_WC
+ .long 0x00 @ unused
+ .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED
+ .long 0x00 @ L_PTE_MT_DEV_NONSHARED
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+ .long 0x00 @ unused
+
+ .align 5
+ENTRY(cpu_xscale_set_pte_ext)
+ xscale_set_pte_ext_prologue
+
+ @
+ @ Erratum 40: must set memory to write-through for user read-only pages
+ @
+ and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_RDONLY) & ~(4 << 2)
+ teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER | L_PTE_RDONLY
+
+ moveq r1, #L_PTE_MT_WRITETHROUGH
+ and r1, r1, #L_PTE_MT_MASK
+ adr ip, cpu_xscale_mt_table
+ ldr ip, [ip, r1]
+ bic r2, r2, #0x0c
+ orr r2, r2, ip
+
+ xscale_set_pte_ext_epilogue
+ mov pc, lr
+
+ .ltorg
+ .align
+
+.globl cpu_xscale_suspend_size
+.equ cpu_xscale_suspend_size, 4 * 7
+#ifdef CONFIG_PM_SLEEP
+ENTRY(cpu_xscale_do_suspend)
+ stmfd sp!, {r4 - r10, lr}
+ mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode
+ mrc p15, 0, r5, c15, c1, 0 @ CP access reg
+ mrc p15, 0, r6, c13, c0, 0 @ PID
+ mrc p15, 0, r7, c3, c0, 0 @ domain ID
+ mrc p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mrc p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mrc p15, 0, r10, c1, c0, 0 @ control reg
+ bic r4, r4, #2 @ clear frequency change bit
+ stmia r0, {r4 - r10} @ store cp regs
+ ldmfd sp!, {r4 - r10, pc}
+ENDPROC(cpu_xscale_do_suspend)
+
+ENTRY(cpu_xscale_do_resume)
+ ldmia r0, {r4 - r10} @ load cp regs
+ mov ip, #0
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB
+ mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode.
+ mcr p15, 0, r5, c15, c1, 0 @ CP access reg
+ mcr p15, 0, r6, c13, c0, 0 @ PID
+ mcr p15, 0, r7, c3, c0, 0 @ domain ID
+ mcr p15, 0, r8, c2, c0, 0 @ translation table base addr
+ mcr p15, 0, r9, c1, c1, 0 @ auxiliary control reg
+ mov r0, r10 @ control register
+ mov r2, r8, lsr #14 @ get TTB0 base
+ mov r2, r2, lsl #14
+ ldr r3, =PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
+ PMD_SECT_CACHEABLE | PMD_SECT_AP_WRITE
+ b cpu_resume_mmu
+ENDPROC(cpu_xscale_do_resume)
+#else
+#define cpu_xscale_do_suspend 0
+#define cpu_xscale_do_resume 0
+#endif
+
+ __CPUINIT
+
+ .type __xscale_setup, #function
+__xscale_setup:
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB
+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs
+ mov r0, #1 << 6 @ cp6 for IOP3xx and Bulverde
+ orr r0, r0, #1 << 13 @ Its undefined whether this
+ mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes
+
+ adr r5, xscale_crval
+ ldmia r5, {r5, r6}
+ mrc p15, 0, r0, c1, c0, 0 @ get control register
+ bic r0, r0, r5
+ orr r0, r0, r6
+ mov pc, lr
+ .size __xscale_setup, . - __xscale_setup
+
+ /*
+ * R
+ * .RVI ZFRS BLDP WCAM
+ * ..11 1.01 .... .101
+ *
+ */
+ .type xscale_crval, #object
+xscale_crval:
+ crval clear=0x00003b07, mmuset=0x00003905, ucset=0x00001900
+
+ __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
+
+ .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
+
+ .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 | \
+ 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_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
+
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
new file mode 100644
index 00000000..9694f1f6
--- /dev/null
+++ b/arch/arm/mm/tlb-fa.S
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/arm/mm/tlb-fa.S
+ *
+ * Copyright (C) 2005 Faraday Corp.
+ * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on tlb-v4wbi.S:
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4, Faraday variation.
+ * This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
+ *
+ * Processors: FA520 FA526 FA626
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+
+/*
+ * flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 4
+ENTRY(fa_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r3, c7, c10, 4 @ data write barrier
+ mov pc, lr
+
+
+ENTRY(fa_flush_kern_tlb_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
+ mcr p15, 0, r3, c7, c10, 4 @ data write barrier
+ mcr p15, 0, r3, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+ __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
diff --git a/arch/arm/mm/tlb-v3.S b/arch/arm/mm/tlb-v3.S
new file mode 100644
index 00000000..c10786ec
--- /dev/null
+++ b/arch/arm/mm/tlb-v3.S
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/arm/mm/tlbv3.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 3 TLB handling functions.
+ *
+ * Processors: ARM610, ARM710.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+ .align 5
+/*
+ * v3_flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 5
+ENTRY(v3_flush_user_tlb_range)
+ vma_vm_mm r2, r2
+ act_mm r3 @ get current->active_mm
+ teq r2, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ENTRY(v3_flush_kern_tlb_range)
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c6, c0, 0 @ invalidate TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ __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
diff --git a/arch/arm/mm/tlb-v4.S b/arch/arm/mm/tlb-v4.S
new file mode 100644
index 00000000..d6c94457
--- /dev/null
+++ b/arch/arm/mm/tlb-v4.S
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mm/tlbv4.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4 TLB handling functions.
+ * These assume a split I/D TLBs, and no write buffer.
+ *
+ * Processors: ARM720T
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+ .align 5
+/*
+ * v4_flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified user address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 5
+ENTRY(v4_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+.v4_flush_kern_tlb_range:
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c7, 1 @ invalidate TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+/*
+ * v4_flush_kern_tlb_range(start, end)
+ *
+ * Invalidate a range of TLB entries in the specified kernel
+ * address range.
+ *
+ * - start - virtual address (may not be aligned)
+ * - end - virtual address (may not be aligned)
+ */
+.globl v4_flush_kern_tlb_range
+.equ v4_flush_kern_tlb_range, .v4_flush_kern_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
diff --git a/arch/arm/mm/tlb-v4wb.S b/arch/arm/mm/tlb-v4wb.S
new file mode 100644
index 00000000..cb829ca7
--- /dev/null
+++ b/arch/arm/mm/tlb-v4wb.S
@@ -0,0 +1,77 @@
+/*
+ * linux/arch/arm/mm/tlbv4wb.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4 TLB handling functions.
+ * These assume a split I/D TLBs w/o I TLB entry, with a write buffer.
+ *
+ * Processors: SA110 SA1100 SA1110
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+ .align 5
+/*
+ * v4wb_flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 5
+ENTRY(v4wb_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ vma_vm_flags r2, r2
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ tst r2, #VM_EXEC
+ mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+/*
+ * v4_flush_kern_tlb_range(start, end)
+ *
+ * Invalidate a range of TLB entries in the specified kernel
+ * address range.
+ *
+ * - start - virtual address (may not be aligned)
+ * - end - virtual address (may not be aligned)
+ */
+ENTRY(v4wb_flush_kern_tlb_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+ mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB
+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ __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
diff --git a/arch/arm/mm/tlb-v4wbi.S b/arch/arm/mm/tlb-v4wbi.S
new file mode 100644
index 00000000..60cfc4a2
--- /dev/null
+++ b/arch/arm/mm/tlb-v4wbi.S
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/mm/tlbv4wbi.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 4 and version 5 TLB handling functions.
+ * These assume a split I/D TLBs, with a write buffer.
+ *
+ * Processors: ARM920 ARM922 ARM925 ARM926 XScale
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/asm-offsets.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+/*
+ * v4wb_flush_user_tlb_range(start, end, mm)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - range start address
+ * - end - range end address
+ * - mm - mm_struct describing address space
+ */
+ .align 5
+ENTRY(v4wbi_flush_user_tlb_range)
+ vma_vm_mm ip, r2
+ act_mm r3 @ get current->active_mm
+ eors r3, ip, r3 @ == mm ?
+ movne pc, lr @ no, we dont do anything
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ vma_vm_flags r2, r2
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: tst r2, #VM_EXEC
+ mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ENTRY(v4wbi_flush_kern_tlb_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ bic r0, r0, #0x0ff
+ bic r0, r0, #0xf00
+1: mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov pc, lr
+
+ __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
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
new file mode 100644
index 00000000..73d7d89b
--- /dev/null
+++ b/arch/arm/mm/tlb-v6.S
@@ -0,0 +1,98 @@
+/*
+ * linux/arch/arm/mm/tlb-v6.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 6 TLB handling functions.
+ * These assume a split I/D TLB.
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+#define HARVARD_TLB
+
+/*
+ * v6wbi_flush_user_tlb_range(start, end, vma)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - vma - vma_struct describing address range
+ *
+ * It is assumed that:
+ * - the "Invalidate single entry" instruction will invalidate
+ * both the I and the D TLBs on Harvard-style TLBs
+ */
+ENTRY(v6wbi_flush_user_tlb_range)
+ vma_vm_mm r3, r2 @ get vma->vm_mm
+ mov ip, #0
+ mmid r3, r3 @ get vm_mm->context.id
+ mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+ asid r3, r3 @ mask ASID
+ orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
+ mov r1, r1, lsl #PAGE_SHIFT
+ vma_vm_flags r2, r2 @ get vma->vm_flags
+1:
+#ifdef HARVARD_TLB
+ mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1)
+ tst r2, #VM_EXEC @ Executable area ?
+ mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1)
+#else
+ mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate MVA (was 1)
+#endif
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB
+ mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier
+ mov pc, lr
+
+/*
+ * v6wbi_flush_kern_tlb_range(start,end)
+ *
+ * Invalidate a range of kernel TLB entries
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ */
+ENTRY(v6wbi_flush_kern_tlb_range)
+ mov r2, #0
+ mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+ mov r0, r0, lsl #PAGE_SHIFT
+ mov r1, r1, lsl #PAGE_SHIFT
+1:
+#ifdef HARVARD_TLB
+ mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA
+ mcr p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA
+#else
+ mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate MVA
+#endif
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
+ mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier
+ mcr p15, 0, r2, c7, c5, 4 @ prefetch flush
+ mov pc, lr
+
+ __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
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
new file mode 100644
index 00000000..53cd5b45
--- /dev/null
+++ b/arch/arm/mm/tlb-v7.S
@@ -0,0 +1,94 @@
+/*
+ * linux/arch/arm/mm/tlb-v7.S
+ *
+ * Copyright (C) 1997-2002 Russell King
+ * Modified for ARMv7 by Catalin Marinas
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ARM architecture version 6 TLB handling functions.
+ * These assume a split I/D TLB.
+ */
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+#include "proc-macros.S"
+
+/*
+ * v7wbi_flush_user_tlb_range(start, end, vma)
+ *
+ * Invalidate a range of TLB entries in the specified address space.
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ * - vma - vma_struct describing address range
+ *
+ * It is assumed that:
+ * - the "Invalidate single entry" instruction will invalidate
+ * both the I and the D TLBs on Harvard-style TLBs
+ */
+ENTRY(v7wbi_flush_user_tlb_range)
+ vma_vm_mm r3, r2 @ get vma->vm_mm
+ mmid r3, r3 @ get vm_mm->context.id
+ dsb
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+ asid r3, r3 @ mask ASID
+ orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
+ mov r1, r1, lsl #PAGE_SHIFT
+1:
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
+
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov ip, #0
+ ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable
+ ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB
+ dsb
+ mov pc, lr
+ENDPROC(v7wbi_flush_user_tlb_range)
+
+/*
+ * v7wbi_flush_kern_tlb_range(start,end)
+ *
+ * Invalidate a range of kernel TLB entries
+ *
+ * - start - start address (may not be aligned)
+ * - end - end address (exclusive, may not be aligned)
+ */
+ENTRY(v7wbi_flush_kern_tlb_range)
+ dsb
+ mov r0, r0, lsr #PAGE_SHIFT @ align address
+ mov r1, r1, lsr #PAGE_SHIFT
+ mov r0, r0, lsl #PAGE_SHIFT
+ mov r1, r1, lsl #PAGE_SHIFT
+1:
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+ ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
+ add r0, r0, #PAGE_SZ
+ cmp r0, r1
+ blo 1b
+ mov r2, #0
+ ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable
+ ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB
+ dsb
+ isb
+ mov pc, lr
+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
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
new file mode 100644
index 00000000..036fdbfd
--- /dev/null
+++ b/arch/arm/mm/vmregion.c
@@ -0,0 +1,131 @@
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "vmregion.h"
+
+/*
+ * VM region handling support.
+ *
+ * This should become something generic, handling VM region allocations for
+ * vmalloc and similar (ioremap, module space, etc).
+ *
+ * I envisage vmalloc()'s supporting vm_struct becoming:
+ *
+ * struct vm_struct {
+ * struct vmregion region;
+ * unsigned long flags;
+ * struct page **pages;
+ * unsigned int nr_pages;
+ * unsigned long phys_addr;
+ * };
+ *
+ * get_vm_area() would then call vmregion_alloc with an appropriate
+ * struct vmregion head (eg):
+ *
+ * struct vmregion vmalloc_head = {
+ * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list),
+ * .vm_start = VMALLOC_START,
+ * .vm_end = VMALLOC_END,
+ * };
+ *
+ * However, vmalloc_head.vm_start is variable (typically, it is dependent on
+ * the amount of RAM found at boot time.) I would imagine that get_vm_area()
+ * would have to initialise this each time prior to calling vmregion_alloc().
+ */
+
+struct arm_vmregion *
+arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
+ size_t size, gfp_t gfp)
+{
+ unsigned long start = head->vm_start, addr = head->vm_end;
+ unsigned long flags;
+ struct arm_vmregion *c, *new;
+
+ if (head->vm_end - head->vm_start < size) {
+ printk(KERN_WARNING "%s: allocation too big (requested %#x)\n",
+ __func__, size);
+ goto out;
+ }
+
+ new = kmalloc(sizeof(struct arm_vmregion), gfp);
+ if (!new)
+ goto out;
+
+ spin_lock_irqsave(&head->vm_lock, flags);
+
+ addr = rounddown(addr - size, align);
+ list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
+ if (addr >= c->vm_end)
+ goto found;
+ addr = rounddown(c->vm_start - size, align);
+ if (addr < start)
+ goto nospc;
+ }
+
+ found:
+ /*
+ * Insert this entry after the one we found.
+ */
+ list_add(&new->vm_list, &c->vm_list);
+ new->vm_start = addr;
+ new->vm_end = addr + size;
+ new->vm_active = 1;
+
+ spin_unlock_irqrestore(&head->vm_lock, flags);
+ return new;
+
+ nospc:
+ spin_unlock_irqrestore(&head->vm_lock, flags);
+ kfree(new);
+ out:
+ return NULL;
+}
+
+static struct arm_vmregion *__arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+ struct arm_vmregion *c;
+
+ list_for_each_entry(c, &head->vm_list, vm_list) {
+ if (c->vm_active && c->vm_start == addr)
+ goto out;
+ }
+ c = NULL;
+ out:
+ return c;
+}
+
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+ struct arm_vmregion *c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&head->vm_lock, flags);
+ c = __arm_vmregion_find(head, addr);
+ spin_unlock_irqrestore(&head->vm_lock, flags);
+ return c;
+}
+
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *head, unsigned long addr)
+{
+ struct arm_vmregion *c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&head->vm_lock, flags);
+ c = __arm_vmregion_find(head, addr);
+ if (c)
+ c->vm_active = 0;
+ spin_unlock_irqrestore(&head->vm_lock, flags);
+ return c;
+}
+
+void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&head->vm_lock, flags);
+ list_del(&c->vm_list);
+ spin_unlock_irqrestore(&head->vm_lock, flags);
+
+ kfree(c);
+}
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
new file mode 100644
index 00000000..15e9f044
--- /dev/null
+++ b/arch/arm/mm/vmregion.h
@@ -0,0 +1,29 @@
+#ifndef VMREGION_H
+#define VMREGION_H
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+struct page;
+
+struct arm_vmregion_head {
+ spinlock_t vm_lock;
+ struct list_head vm_list;
+ unsigned long vm_start;
+ unsigned long vm_end;
+};
+
+struct arm_vmregion {
+ struct list_head vm_list;
+ unsigned long vm_start;
+ unsigned long vm_end;
+ struct page *vm_pages;
+ int vm_active;
+};
+
+struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t);
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
+void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
+
+#endif
diff --git a/arch/arm/nwfpe/ARM-gcc.h b/arch/arm/nwfpe/ARM-gcc.h
new file mode 100644
index 00000000..436e54aa
--- /dev/null
+++ b/arch/arm/nwfpe/ARM-gcc.h
@@ -0,0 +1,120 @@
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified. For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits. The `flag' type must be able to hold either a 0 or 1. For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef char flag;
+typedef unsigned char uint8;
+typedef signed char int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified. For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and if
+necessary ``marks'' the literal as having a 64-bit integer type. For
+example, the Gnu C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type. Some compilers may allow `LIT64' to be
+defined as the identity macro: `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined. If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE static inline
+
+
+/* For use as a GCC soft-float library we need some special function names. */
+
+#ifdef __LIBFLOAT__
+
+/* Some 32-bit ops can be mapped straight across by just changing the name. */
+#define float32_add __addsf3
+#define float32_sub __subsf3
+#define float32_mul __mulsf3
+#define float32_div __divsf3
+#define int32_to_float32 __floatsisf
+#define float32_to_int32_round_to_zero __fixsfsi
+#define float32_to_uint32_round_to_zero __fixunssfsi
+
+/* These ones go through the glue code. To avoid namespace pollution
+ we rename the internal functions too. */
+#define float32_eq ___float32_eq
+#define float32_le ___float32_le
+#define float32_lt ___float32_lt
+
+/* All the 64-bit ops have to go through the glue, so we pull the same
+ trick. */
+#define float64_add ___float64_add
+#define float64_sub ___float64_sub
+#define float64_mul ___float64_mul
+#define float64_div ___float64_div
+#define int32_to_float64 ___int32_to_float64
+#define float64_to_int32_round_to_zero ___float64_to_int32_round_to_zero
+#define float64_to_uint32_round_to_zero ___float64_to_uint32_round_to_zero
+#define float64_to_float32 ___float64_to_float32
+#define float32_to_float64 ___float32_to_float64
+#define float64_eq ___float64_eq
+#define float64_le ___float64_le
+#define float64_lt ___float64_lt
+
+#if 0
+#define float64_add __adddf3
+#define float64_sub __subdf3
+#define float64_mul __muldf3
+#define float64_div __divdf3
+#define int32_to_float64 __floatsidf
+#define float64_to_int32_round_to_zero __fixdfsi
+#define float64_to_uint32_round_to_zero __fixunsdfsi
+#define float64_to_float32 __truncdfsf2
+#define float32_to_float64 __extendsfdf2
+#endif
+
+#endif
diff --git a/arch/arm/nwfpe/ChangeLog b/arch/arm/nwfpe/ChangeLog
new file mode 100644
index 00000000..fa8028b1
--- /dev/null
+++ b/arch/arm/nwfpe/ChangeLog
@@ -0,0 +1,91 @@
+2003-03-22 Ralph Siemsen <ralphs@netwinder.org>
+ * Reformat all but softfloat files to get a consistent coding style.
+ Used "indent -kr -i8 -ts8 -sob -l132 -ss" and a few manual fixups.
+ * Removed dead code and fixed function protypes to match definitions.
+ * Consolidated use of (opcode && MASK_ARITHMETIC_OPCODE) >> 20.
+ * Make 80-bit precision a compile-time option. (1%)
+ * Only initialize FPE state once in repeat-FP situations. (6%)
+
+2002-01-19 Russell King <rmk@arm.linux.org.uk>
+
+ * fpa11.h - Add documentation
+ - remove userRegisters pointer from this structure.
+ - add new method to obtain integer register values.
+ * softfloat.c - Remove float128
+ * softfloat.h - Remove float128
+ * softfloat-specialize - Remove float128
+
+ * The FPA11 structure is not a kernel-specific data structure.
+ It is used by users of ptrace to examine the values of the
+ floating point registers. Therefore, any changes to the
+ FPA11 structure (size or position of elements contained
+ within) have to be well thought out.
+
+ * Since 128-bit float requires the FPA11 structure to change
+ size, it has been removed. 128-bit float is currently unused,
+ and needs various things to be re-worked so that we won't
+ overflow the available space in the task structure.
+
+ * The changes are designed to break any patch that goes on top
+ of this code, so that the authors properly review their changes.
+
+1999-08-19 Scott Bambrough <scottb@netwinder.org>
+
+ * fpmodule.c - Changed version number to 0.95
+ * fpa11.h - modified FPA11, FPREG structures
+ * fpa11.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cpdt.c - Changes due to FPA11, FPREG structure alterations.
+ * fpa11_cprt.c - Changes due to FPA11, FPREG structure alterations.
+ * single_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * double_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+ * extended_cpdo.c - Changes due to FPA11, FPREG structure alterations.
+
+ * I discovered several bugs. First and worst is that the kernel
+ passes in a pointer to the FPE's state area. This is defined
+ as a struct user_fp (see user.h). This pointer was cast to a
+ FPA11*. Unfortunately FPA11 and user_fp are of different sizes;
+ user_fp is smaller. This meant that the FPE scribbled on things
+ below its area, which is bad, as the area is in the thread_struct
+ embedded in the process task structure. Thus we were scribbling
+ over one of the most important structures in the entire OS.
+
+ * user_fp and FPA11 have now been harmonized. Most of the changes
+ in the above code were dereferencing problems due to moving the
+ register type out of FPREG, and getting rid of the union variable
+ fpvalue.
+
+ * Second I noticed resetFPA11 was not always being called for a
+ task. This should happen on the first floating point exception
+ that occurs. It is controlled by init_flag in FPA11. The
+ comment in the code beside init_flag state the kernel guarantees
+ this to be zero. Not so. I found that the kernel recycles task
+ structures, and that recycled ones may not have init_flag zeroed.
+ I couldn't even find anything that guarantees it is zeroed when
+ when the task structure is initially allocated. In any case
+ I now initialize the entire FPE state in the thread structure to
+ zero when allocated and recycled. See alloc_task_struct() and
+ flush_thread() in arch/arm/process.c. The change to
+ alloc_task_struct() may not be necessary, but I left it in for
+ completeness (better safe than sorry).
+
+1998-11-23 Scott Bambrough <scottb@netwinder.org>
+
+ * README.FPE - fix typo in description of lfm/sfm instructions
+ * NOTES - Added file to describe known bugs/problems
+ * fpmodule.c - Changed version number to 0.94
+
+1998-11-20 Scott Bambrough <scottb@netwinder.org>
+
+ * README.FPE - fix description of URD, NRM instructions
+ * TODO - remove URD, NRM instructions from TODO list
+ * single_cpdo.c - implement URD, NRM
+ * double_cpdo.c - implement URD, NRM
+ * extended_cpdo.c - implement URD, NRM
+
+1998-11-19 Scott Bambrough <scottb@netwinder.org>
+
+ * ChangeLog - Added this file to track changes made.
+ * fpa11.c - added code to initialize register types to typeNone
+ * fpa11_cpdt.c - fixed bug in storeExtended (typeExtended changed to
+ typeDouble in switch statement)
diff --git a/arch/arm/nwfpe/Makefile b/arch/arm/nwfpe/Makefile
new file mode 100644
index 00000000..deb3a82d
--- /dev/null
+++ b/arch/arm/nwfpe/Makefile
@@ -0,0 +1,12 @@
+#
+# Copyright (C) 1998, 1999, 2001 Philip Blundell
+#
+
+obj-$(CONFIG_FPE_NWFPE) += nwfpe.o
+
+nwfpe-y += fpa11.o fpa11_cpdo.o fpa11_cpdt.o \
+ fpa11_cprt.o fpmodule.o fpopcode.o \
+ softfloat.o single_cpdo.o double_cpdo.o \
+ entry.o
+
+nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o
diff --git a/arch/arm/nwfpe/double_cpdo.c b/arch/arm/nwfpe/double_cpdo.c
new file mode 100644
index 00000000..c51d1386
--- /dev/null
+++ b/arch/arm/nwfpe/double_cpdo.c
@@ -0,0 +1,167 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+
+union float64_components {
+ float64 f64;
+ unsigned int i[2];
+};
+
+float64 float64_exp(float64 Fm);
+float64 float64_ln(float64 Fm);
+float64 float64_sin(float64 rFm);
+float64 float64_cos(float64 rFm);
+float64 float64_arcsin(float64 rFm);
+float64 float64_arctan(float64 rFm);
+float64 float64_log(float64 rFm);
+float64 float64_tan(float64 rFm);
+float64 float64_arccos(float64 rFm);
+float64 float64_pow(float64 rFn, float64 rFm);
+float64 float64_pol(float64 rFn, float64 rFm);
+
+static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm)
+{
+ return float64_sub(roundData, rFm, rFn);
+}
+
+static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm)
+{
+ return float64_div(roundData, rFm, rFn);
+}
+
+static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = {
+ [ADF_CODE >> 20] = float64_add,
+ [MUF_CODE >> 20] = float64_mul,
+ [SUF_CODE >> 20] = float64_sub,
+ [RSF_CODE >> 20] = float64_rsf,
+ [DVF_CODE >> 20] = float64_div,
+ [RDF_CODE >> 20] = float64_rdv,
+ [RMF_CODE >> 20] = float64_rem,
+
+ /* strictly, these opcodes should not be implemented */
+ [FML_CODE >> 20] = float64_mul,
+ [FDV_CODE >> 20] = float64_div,
+ [FRD_CODE >> 20] = float64_rdv,
+};
+
+static float64 float64_mvf(struct roundingData *roundData,float64 rFm)
+{
+ return rFm;
+}
+
+static float64 float64_mnf(struct roundingData *roundData,float64 rFm)
+{
+ union float64_components u;
+
+ u.f64 = rFm;
+#ifdef __ARMEB__
+ u.i[0] ^= 0x80000000;
+#else
+ u.i[1] ^= 0x80000000;
+#endif
+
+ return u.f64;
+}
+
+static float64 float64_abs(struct roundingData *roundData,float64 rFm)
+{
+ union float64_components u;
+
+ u.f64 = rFm;
+#ifdef __ARMEB__
+ u.i[0] &= 0x7fffffff;
+#else
+ u.i[1] &= 0x7fffffff;
+#endif
+
+ return u.f64;
+}
+
+static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = {
+ [MVF_CODE >> 20] = float64_mvf,
+ [MNF_CODE >> 20] = float64_mnf,
+ [ABS_CODE >> 20] = float64_abs,
+ [RND_CODE >> 20] = float64_round_to_int,
+ [URD_CODE >> 20] = float64_round_to_int,
+ [SQT_CODE >> 20] = float64_sqrt,
+ [NRM_CODE >> 20] = float64_mvf,
+};
+
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ float64 rFm;
+ unsigned int Fm, opc_mask_shift;
+
+ Fm = getFm(opcode);
+ if (CONSTANT_FM(opcode)) {
+ rFm = getDoubleConstant(Fm);
+ } else {
+ switch (fpa11->fType[Fm]) {
+ case typeSingle:
+ rFm = float32_to_float64(fpa11->fpreg[Fm].fSingle);
+ break;
+
+ case typeDouble:
+ rFm = fpa11->fpreg[Fm].fDouble;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+ if (!MONADIC_INSTRUCTION(opcode)) {
+ unsigned int Fn = getFn(opcode);
+ float64 rFn;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ rFn = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+ break;
+
+ case typeDouble:
+ rFn = fpa11->fpreg[Fn].fDouble;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (dyadic_double[opc_mask_shift]) {
+ rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm);
+ } else {
+ return 0;
+ }
+ } else {
+ if (monadic_double[opc_mask_shift]) {
+ rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm);
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/arch/arm/nwfpe/entry.S b/arch/arm/nwfpe/entry.S
new file mode 100644
index 00000000..cafa1835
--- /dev/null
+++ b/arch/arm/nwfpe/entry.S
@@ -0,0 +1,122 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998
+ (c) 1998, 1999 Philip Blundell
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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.
+*/
+
+/* This is the kernel's entry point into the floating point emulator.
+It is called from the kernel with code similar to this:
+
+ sub r4, r5, #4
+ ldrt r0, [r4] @ r0 = instruction
+ adrsvc al, r9, ret_from_exception @ r9 = normal FP return
+ adrsvc al, lr, fpundefinstr @ lr = undefined instr return
+
+ get_current_task r10
+ mov r8, #1
+ strb r8, [r10, #TSK_USED_MATH] @ set current->used_math
+ add r10, r10, #TSS_FPESAVE @ r10 = workspace
+ ldr r4, .LC2
+ ldr pc, [r4] @ Call FP emulator entry point
+
+The kernel expects the emulator to return via one of two possible
+points of return it passes to the emulator. The emulator, if
+successful in its emulation, jumps to ret_from_exception (passed in
+r9) and the kernel takes care of returning control from the trap to
+the user code. If the emulator is unable to emulate the instruction,
+it returns via _fpundefinstr (passed via lr) and the kernel halts the
+user program with a core dump.
+
+On entry to the emulator r10 points to an area of private FP workspace
+reserved in the thread structure for this process. This is where the
+emulator saves its registers across calls. The first word of this area
+is used as a flag to detect the first time a process uses floating point,
+so that the emulator startup cost can be avoided for tasks that don't
+want it.
+
+This routine does three things:
+
+1) The kernel has created a struct pt_regs on the stack and saved the
+user registers into it. See /usr/include/asm/proc/ptrace.h for details.
+
+2) It calls EmulateAll to emulate a floating point instruction.
+EmulateAll returns 1 if the emulation was successful, or 0 if not.
+
+3) If an instruction has been emulated successfully, it looks ahead at
+the next instruction. If it is a floating point instruction, it
+executes the instruction, without returning to user space. In this
+way it repeatedly looks ahead and executes floating point instructions
+until it encounters a non floating point instruction, at which time it
+returns via _fpreturn.
+
+This is done to reduce the effect of the trap overhead on each
+floating point instructions. GCC attempts to group floating point
+instructions to allow the emulator to spread the cost of the trap over
+several floating point instructions. */
+
+#include <asm/asm-offsets.h>
+
+ .globl nwfpe_enter
+nwfpe_enter:
+ mov r4, lr @ save the failure-return addresses
+ mov sl, sp @ we access the registers via 'sl'
+
+ ldr r5, [sp, #S_PC] @ get contents of PC;
+ mov r6, r0 @ save the opcode
+emulate:
+ ldr r1, [sp, #S_PSR] @ fetch the PSR
+ bl checkCondition @ check the condition
+ cmp r0, #0 @ r0 = 0 ==> condition failed
+
+ @ if condition code failed to match, next insn
+ beq next @ get the next instruction;
+
+ mov r0, r6 @ prepare for EmulateAll()
+ bl EmulateAll @ emulate the instruction
+ cmp r0, #0 @ was emulation successful
+ moveq pc, r4 @ no, return failure
+
+next:
+.Lx1: ldrt r6, [r5], #4 @ get the next instruction and
+ @ increment PC
+
+ and r2, r6, #0x0F000000 @ test for FP insns
+ teq r2, #0x0C000000
+ teqne r2, #0x0D000000
+ teqne r2, #0x0E000000
+ movne pc, r9 @ return ok if not a fp insn
+
+ str r5, [sp, #S_PC] @ update PC copy in regs
+
+ mov r0, r6 @ save a copy
+ b emulate @ check condition and emulate
+
+ @ We need to be prepared for the instructions at .Lx1 and .Lx2
+ @ to fault. Emit the appropriate exception gunk to fix things up.
+ @ ??? For some reason, faults can happen at .Lx2 even with a
+ @ plain LDR instruction. Weird, but it seems harmless.
+ .pushsection .fixup,"ax"
+ .align 2
+.Lfix: mov pc, r9 @ let the user eat segfaults
+ .popsection
+
+ .pushsection __ex_table,"a"
+ .align 3
+ .long .Lx1, .Lfix
+ .popsection
diff --git a/arch/arm/nwfpe/extended_cpdo.c b/arch/arm/nwfpe/extended_cpdo.c
new file mode 100644
index 00000000..65a279ba
--- /dev/null
+++ b/arch/arm/nwfpe/extended_cpdo.c
@@ -0,0 +1,154 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+
+floatx80 floatx80_exp(floatx80 Fm);
+floatx80 floatx80_ln(floatx80 Fm);
+floatx80 floatx80_sin(floatx80 rFm);
+floatx80 floatx80_cos(floatx80 rFm);
+floatx80 floatx80_arcsin(floatx80 rFm);
+floatx80 floatx80_arctan(floatx80 rFm);
+floatx80 floatx80_log(floatx80 rFm);
+floatx80 floatx80_tan(floatx80 rFm);
+floatx80 floatx80_arccos(floatx80 rFm);
+floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
+floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
+
+static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
+{
+ return floatx80_sub(roundData, rFm, rFn);
+}
+
+static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
+{
+ return floatx80_div(roundData, rFm, rFn);
+}
+
+static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
+ [ADF_CODE >> 20] = floatx80_add,
+ [MUF_CODE >> 20] = floatx80_mul,
+ [SUF_CODE >> 20] = floatx80_sub,
+ [RSF_CODE >> 20] = floatx80_rsf,
+ [DVF_CODE >> 20] = floatx80_div,
+ [RDF_CODE >> 20] = floatx80_rdv,
+ [RMF_CODE >> 20] = floatx80_rem,
+
+ /* strictly, these opcodes should not be implemented */
+ [FML_CODE >> 20] = floatx80_mul,
+ [FDV_CODE >> 20] = floatx80_div,
+ [FRD_CODE >> 20] = floatx80_rdv,
+};
+
+static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
+{
+ return rFm;
+}
+
+static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
+{
+ rFm.high ^= 0x8000;
+ return rFm;
+}
+
+static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
+{
+ rFm.high &= 0x7fff;
+ return rFm;
+}
+
+static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
+ [MVF_CODE >> 20] = floatx80_mvf,
+ [MNF_CODE >> 20] = floatx80_mnf,
+ [ABS_CODE >> 20] = floatx80_abs,
+ [RND_CODE >> 20] = floatx80_round_to_int,
+ [URD_CODE >> 20] = floatx80_round_to_int,
+ [SQT_CODE >> 20] = floatx80_sqrt,
+ [NRM_CODE >> 20] = floatx80_mvf,
+};
+
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ floatx80 rFm;
+ unsigned int Fm, opc_mask_shift;
+
+ Fm = getFm(opcode);
+ if (CONSTANT_FM(opcode)) {
+ rFm = getExtendedConstant(Fm);
+ } else {
+ switch (fpa11->fType[Fm]) {
+ case typeSingle:
+ rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+ break;
+
+ case typeDouble:
+ rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+ break;
+
+ case typeExtended:
+ rFm = fpa11->fpreg[Fm].fExtended;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+ if (!MONADIC_INSTRUCTION(opcode)) {
+ unsigned int Fn = getFn(opcode);
+ floatx80 rFn;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+ break;
+
+ case typeDouble:
+ rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+ break;
+
+ case typeExtended:
+ rFn = fpa11->fpreg[Fn].fExtended;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (dyadic_extended[opc_mask_shift]) {
+ rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
+ } else {
+ return 0;
+ }
+ } else {
+ if (monadic_extended[opc_mask_shift]) {
+ rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c
new file mode 100644
index 00000000..cc60acde
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11.c
@@ -0,0 +1,129 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+ (c) Philip Blundell, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "fpopcode.h"
+
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+#include <linux/compiler.h>
+#include <linux/string.h>
+#include <asm/system.h>
+
+/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
+static void resetFPA11(void)
+{
+ int i;
+ FPA11 *fpa11 = GET_FPA11();
+
+ /* initialize the register type array */
+ for (i = 0; i <= 7; i++) {
+ fpa11->fType[i] = typeNone;
+ }
+
+ /* FPSR: set system id to FP_EMULATOR, set AC, clear all other bits */
+ fpa11->fpsr = FP_EMULATOR | BIT_AC;
+}
+
+int8 SetRoundingMode(const unsigned int opcode)
+{
+ switch (opcode & MASK_ROUNDING_MODE) {
+ default:
+ case ROUND_TO_NEAREST:
+ return float_round_nearest_even;
+
+ case ROUND_TO_PLUS_INFINITY:
+ return float_round_up;
+
+ case ROUND_TO_MINUS_INFINITY:
+ return float_round_down;
+
+ case ROUND_TO_ZERO:
+ return float_round_to_zero;
+ }
+}
+
+int8 SetRoundingPrecision(const unsigned int opcode)
+{
+#ifdef CONFIG_FPE_NWFPE_XP
+ switch (opcode & MASK_ROUNDING_PRECISION) {
+ case ROUND_SINGLE:
+ return 32;
+
+ case ROUND_DOUBLE:
+ return 64;
+
+ case ROUND_EXTENDED:
+ return 80;
+
+ default:
+ return 80;
+ }
+#endif
+ return 80;
+}
+
+void nwfpe_init_fpa(union fp_state *fp)
+{
+ FPA11 *fpa11 = (FPA11 *)fp;
+#ifdef NWFPE_DEBUG
+ printk("NWFPE: setting up state.\n");
+#endif
+ memset(fpa11, 0, sizeof(FPA11));
+ resetFPA11();
+ fpa11->initflag = 1;
+}
+
+/* Emulate the instruction in the opcode. */
+unsigned int EmulateAll(unsigned int opcode)
+{
+ unsigned int code;
+
+#ifdef NWFPE_DEBUG
+ printk("NWFPE: emulating opcode %08x\n", opcode);
+#endif
+ code = opcode & 0x00000f00;
+ if (code == 0x00000100 || code == 0x00000200) {
+ /* For coprocessor 1 or 2 (FPA11) */
+ code = opcode & 0x0e000000;
+ if (code == 0x0e000000) {
+ if (opcode & 0x00000010) {
+ /* Emulate conversion opcodes. */
+ /* Emulate register transfer opcodes. */
+ /* Emulate comparison opcodes. */
+ return EmulateCPRT(opcode);
+ } else {
+ /* Emulate monadic arithmetic opcodes. */
+ /* Emulate dyadic arithmetic opcodes. */
+ return EmulateCPDO(opcode);
+ }
+ } else if (code == 0x0c000000) {
+ /* Emulate load/store opcodes. */
+ /* Emulate load/store multiple opcodes. */
+ return EmulateCPDT(opcode);
+ }
+ }
+
+ /* Invalid instruction detected. Return FALSE. */
+ return 0;
+}
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
new file mode 100644
index 00000000..d3a6f929
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11.h
@@ -0,0 +1,121 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.com, 1998-1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPA11_H__
+#define __FPA11_H__
+
+#define GET_FPA11() ((FPA11 *)(&current_thread_info()->fpstate))
+
+/*
+ * The processes registers are always at the very top of the 8K
+ * stack+task struct. Use the same method as 'current' uses to
+ * reach them.
+ */
+#define GET_USERREG() ((struct pt_regs *)(THREAD_START_SP + (unsigned long)current_thread_info()) - 1)
+
+#include <linux/thread_info.h>
+
+/* includes */
+#include "fpsr.h" /* FP control and status register definitions */
+#include "milieu.h"
+
+struct roundingData {
+ int8 mode;
+ int8 precision;
+ signed char exception;
+};
+
+#include "softfloat.h"
+
+#define typeNone 0x00
+#define typeSingle 0x01
+#define typeDouble 0x02
+#define typeExtended 0x03
+
+/*
+ * This must be no more and no less than 12 bytes.
+ */
+typedef union tagFPREG {
+ float32 fSingle;
+ float64 fDouble;
+#ifdef CONFIG_FPE_NWFPE_XP
+ floatx80 fExtended;
+#else
+ u32 padding[3];
+#endif
+} __attribute__ ((packed,aligned(4))) FPREG;
+
+/*
+ * FPA11 device model.
+ *
+ * This structure is exported to user space. Do not re-order.
+ * Only add new stuff to the end, and do not change the size of
+ * any element. Elements of this structure are used by user
+ * space, and must match struct user_fp in <asm/user.h>.
+ * We include the byte offsets below for documentation purposes.
+ *
+ * The size of this structure and FPREG are checked by fpmodule.c
+ * on initialisation. If the rules have been broken, NWFPE will
+ * not initialise.
+ */
+typedef struct tagFPA11 {
+/* 0 */ FPREG fpreg[8]; /* 8 floating point registers */
+/* 96 */ FPSR fpsr; /* floating point status register */
+/* 100 */ FPCR fpcr; /* floating point control register */
+/* 104 */ unsigned char fType[8]; /* type of floating point value held in
+ floating point registers. One of
+ none, single, double or extended. */
+/* 112 */ int initflag; /* this is special. The kernel guarantees
+ to set it to 0 when a thread is launched,
+ so we can use it to detect whether this
+ instance of the emulator needs to be
+ initialised. */
+} __attribute__ ((packed,aligned(4))) FPA11;
+
+extern int8 SetRoundingMode(const unsigned int);
+extern int8 SetRoundingPrecision(const unsigned int);
+extern void nwfpe_init_fpa(union fp_state *fp);
+
+extern unsigned int EmulateAll(unsigned int opcode);
+
+extern unsigned int EmulateCPDT(const unsigned int opcode);
+extern unsigned int EmulateCPDO(const unsigned int opcode);
+extern unsigned int EmulateCPRT(const unsigned int opcode);
+
+/* fpa11_cpdt.c */
+extern unsigned int PerformLDF(const unsigned int opcode);
+extern unsigned int PerformSTF(const unsigned int opcode);
+extern unsigned int PerformLFM(const unsigned int opcode);
+extern unsigned int PerformSFM(const unsigned int opcode);
+
+/* single_cpdo.c */
+
+extern unsigned int SingleCPDO(struct roundingData *roundData,
+ const unsigned int opcode, FPREG * rFd);
+/* double_cpdo.c */
+extern unsigned int DoubleCPDO(struct roundingData *roundData,
+ const unsigned int opcode, FPREG * rFd);
+
+/* extneded_cpdo.c */
+extern unsigned int ExtendedCPDO(struct roundingData *roundData,
+ const unsigned int opcode, FPREG * rFd);
+
+#endif
diff --git a/arch/arm/nwfpe/fpa11.inl b/arch/arm/nwfpe/fpa11.inl
new file mode 100644
index 00000000..ab8d6826
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11.inl
@@ -0,0 +1,51 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+
+/* Read and write floating point status register */
+static inline unsigned int readFPSR(void)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ return (fpa11->fpsr);
+}
+
+static inline void writeFPSR(FPSR reg)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ /* the sysid byte in the status register is readonly */
+ fpa11->fpsr = (fpa11->fpsr & MASK_SYSID) | (reg & ~MASK_SYSID);
+}
+
+/* Read and write floating point control register */
+static inline FPCR readFPCR(void)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ /* clear SB, AB and DA bits before returning FPCR */
+ return (fpa11->fpcr & ~MASK_RFC);
+}
+
+static inline void writeFPCR(FPCR reg)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ fpa11->fpcr &= ~MASK_WFC; /* clear SB, AB and DA bits */
+ fpa11->fpcr |= (reg & MASK_WFC); /* write SB, AB and DA bits */
+}
diff --git a/arch/arm/nwfpe/fpa11_cpdo.c b/arch/arm/nwfpe/fpa11_cpdo.c
new file mode 100644
index 00000000..2cebb152
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11_cpdo.c
@@ -0,0 +1,137 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+ (c) Philip Blundell, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "fpopcode.h"
+
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
+unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
+unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd);
+
+unsigned int EmulateCPDO(const unsigned int opcode)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ FPREG *rFd;
+ unsigned int nType, nDest, nRc;
+ struct roundingData roundData;
+
+ /* Get the destination size. If not valid let Linux perform
+ an invalid instruction trap. */
+ nDest = getDestinationSize(opcode);
+ if (typeNone == nDest)
+ return 0;
+
+ roundData.mode = SetRoundingMode(opcode);
+ roundData.precision = SetRoundingPrecision(opcode);
+ roundData.exception = 0;
+
+ /* Compare the size of the operands in Fn and Fm.
+ Choose the largest size and perform operations in that size,
+ in order to make use of all the precision of the operands.
+ If Fm is a constant, we just grab a constant of a size
+ matching the size of the operand in Fn. */
+ if (MONADIC_INSTRUCTION(opcode))
+ nType = nDest;
+ else
+ nType = fpa11->fType[getFn(opcode)];
+
+ if (!CONSTANT_FM(opcode)) {
+ register unsigned int Fm = getFm(opcode);
+ if (nType < fpa11->fType[Fm]) {
+ nType = fpa11->fType[Fm];
+ }
+ }
+
+ rFd = &fpa11->fpreg[getFd(opcode)];
+
+ switch (nType) {
+ case typeSingle:
+ nRc = SingleCPDO(&roundData, opcode, rFd);
+ break;
+ case typeDouble:
+ nRc = DoubleCPDO(&roundData, opcode, rFd);
+ break;
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ nRc = ExtendedCPDO(&roundData, opcode, rFd);
+ break;
+#endif
+ default:
+ nRc = 0;
+ }
+
+ /* The CPDO functions used to always set the destination type
+ to be the same as their working size. */
+
+ if (nRc != 0) {
+ /* If the operation succeeded, check to see if the result in the
+ destination register is the correct size. If not force it
+ to be. */
+
+ fpa11->fType[getFd(opcode)] = nDest;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ if (nDest != nType) {
+ switch (nDest) {
+ case typeSingle:
+ {
+ if (typeDouble == nType)
+ rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
+ else
+ rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended);
+ }
+ break;
+
+ case typeDouble:
+ {
+ if (typeSingle == nType)
+ rFd->fDouble = float32_to_float64(rFd->fSingle);
+ else
+ rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended);
+ }
+ break;
+
+ case typeExtended:
+ {
+ if (typeSingle == nType)
+ rFd->fExtended = float32_to_floatx80(rFd->fSingle);
+ else
+ rFd->fExtended = float64_to_floatx80(rFd->fDouble);
+ }
+ break;
+ }
+ }
+#else
+ if (nDest != nType) {
+ if (nDest == typeSingle)
+ rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble);
+ else
+ rFd->fDouble = float32_to_float64(rFd->fSingle);
+ }
+#endif
+ }
+
+ if (roundData.exception)
+ float_raise(roundData.exception);
+
+ return nRc;
+}
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
new file mode 100644
index 00000000..d31c49f9
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -0,0 +1,407 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.com, 1998-1999
+ (c) Philip Blundell, 1998, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+#include <linux/uaccess.h>
+
+static inline void loadSingle(const unsigned int Fn, const unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ fpa11->fType[Fn] = typeSingle;
+ get_user(fpa11->fpreg[Fn].fSingle, pMem);
+}
+
+static inline void loadDouble(const unsigned int Fn, const unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int *p;
+ p = (unsigned int *) &fpa11->fpreg[Fn].fDouble;
+ fpa11->fType[Fn] = typeDouble;
+#ifdef __ARMEB__
+ get_user(p[0], &pMem[0]); /* sign & exponent */
+ get_user(p[1], &pMem[1]);
+#else
+ get_user(p[0], &pMem[1]);
+ get_user(p[1], &pMem[0]); /* sign & exponent */
+#endif
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void loadExtended(const unsigned int Fn, const unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int *p;
+ p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
+ fpa11->fType[Fn] = typeExtended;
+ get_user(p[0], &pMem[0]); /* sign & exponent */
+#ifdef __ARMEB__
+ get_user(p[1], &pMem[1]); /* ms bits */
+ get_user(p[2], &pMem[2]); /* ls bits */
+#else
+ get_user(p[1], &pMem[2]); /* ls bits */
+ get_user(p[2], &pMem[1]); /* ms bits */
+#endif
+}
+#endif
+
+static inline void loadMultiple(const unsigned int Fn, const unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ register unsigned int *p;
+ unsigned long x;
+
+ p = (unsigned int *) &(fpa11->fpreg[Fn]);
+ get_user(x, &pMem[0]);
+ fpa11->fType[Fn] = (x >> 14) & 0x00000003;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ case typeDouble:
+ {
+ get_user(p[0], &pMem[2]); /* Single */
+ get_user(p[1], &pMem[1]); /* double msw */
+ p[2] = 0; /* empty */
+ }
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ {
+ get_user(p[1], &pMem[2]);
+ get_user(p[2], &pMem[1]); /* msw */
+ p[0] = (x & 0x80003fff);
+ }
+ break;
+#endif
+ }
+}
+
+static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ union {
+ float32 f;
+ unsigned int i[1];
+ } val;
+
+ switch (fpa11->fType[Fn]) {
+ case typeDouble:
+ val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble);
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended);
+ break;
+#endif
+
+ default:
+ val.f = fpa11->fpreg[Fn].fSingle;
+ }
+
+ put_user(val.i[0], pMem);
+}
+
+static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ union {
+ float64 f;
+ unsigned int i[2];
+ } val;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ val.f = float32_to_float64(fpa11->fpreg[Fn].fSingle);
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended);
+ break;
+#endif
+
+ default:
+ val.f = fpa11->fpreg[Fn].fDouble;
+ }
+
+#ifdef __ARMEB__
+ put_user(val.i[0], &pMem[0]); /* msw */
+ put_user(val.i[1], &pMem[1]); /* lsw */
+#else
+ put_user(val.i[1], &pMem[0]); /* msw */
+ put_user(val.i[0], &pMem[1]); /* lsw */
+#endif
+}
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ union {
+ floatx80 f;
+ unsigned int i[3];
+ } val;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ val.f = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+ break;
+
+ case typeDouble:
+ val.f = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+ break;
+
+ default:
+ val.f = fpa11->fpreg[Fn].fExtended;
+ }
+
+ put_user(val.i[0], &pMem[0]); /* sign & exp */
+#ifdef __ARMEB__
+ put_user(val.i[1], &pMem[1]); /* msw */
+ put_user(val.i[2], &pMem[2]);
+#else
+ put_user(val.i[1], &pMem[2]);
+ put_user(val.i[2], &pMem[1]); /* msw */
+#endif
+}
+#endif
+
+static inline void storeMultiple(const unsigned int Fn, unsigned int __user *pMem)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ register unsigned int nType, *p;
+
+ p = (unsigned int *) &(fpa11->fpreg[Fn]);
+ nType = fpa11->fType[Fn];
+
+ switch (nType) {
+ case typeSingle:
+ case typeDouble:
+ {
+ put_user(p[0], &pMem[2]); /* single */
+ put_user(p[1], &pMem[1]); /* double msw */
+ put_user(nType << 14, &pMem[0]);
+ }
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ {
+ put_user(p[2], &pMem[1]); /* msw */
+ put_user(p[1], &pMem[2]);
+ put_user((p[0] & 0x80003fff) | (nType << 14), &pMem[0]);
+ }
+ break;
+#endif
+ }
+}
+
+unsigned int PerformLDF(const unsigned int opcode)
+{
+ unsigned int __user *pBase, *pAddress, *pFinal;
+ unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
+
+ pBase = (unsigned int __user *) readRegister(getRn(opcode));
+ if (REG_PC == getRn(opcode)) {
+ pBase += 2;
+ write_back = 0;
+ }
+
+ pFinal = pBase;
+ if (BIT_UP_SET(opcode))
+ pFinal += getOffset(opcode);
+ else
+ pFinal -= getOffset(opcode);
+
+ if (PREINDEXED(opcode))
+ pAddress = pFinal;
+ else
+ pAddress = pBase;
+
+ switch (opcode & MASK_TRANSFER_LENGTH) {
+ case TRANSFER_SINGLE:
+ loadSingle(getFd(opcode), pAddress);
+ break;
+ case TRANSFER_DOUBLE:
+ loadDouble(getFd(opcode), pAddress);
+ break;
+#ifdef CONFIG_FPE_NWFPE_XP
+ case TRANSFER_EXTENDED:
+ loadExtended(getFd(opcode), pAddress);
+ break;
+#endif
+ default:
+ nRc = 0;
+ }
+
+ if (write_back)
+ writeRegister(getRn(opcode), (unsigned long) pFinal);
+ return nRc;
+}
+
+unsigned int PerformSTF(const unsigned int opcode)
+{
+ unsigned int __user *pBase, *pAddress, *pFinal;
+ unsigned int nRc = 1, write_back = WRITE_BACK(opcode);
+ struct roundingData roundData;
+
+ roundData.mode = SetRoundingMode(opcode);
+ roundData.precision = SetRoundingPrecision(opcode);
+ roundData.exception = 0;
+
+ pBase = (unsigned int __user *) readRegister(getRn(opcode));
+ if (REG_PC == getRn(opcode)) {
+ pBase += 2;
+ write_back = 0;
+ }
+
+ pFinal = pBase;
+ if (BIT_UP_SET(opcode))
+ pFinal += getOffset(opcode);
+ else
+ pFinal -= getOffset(opcode);
+
+ if (PREINDEXED(opcode))
+ pAddress = pFinal;
+ else
+ pAddress = pBase;
+
+ switch (opcode & MASK_TRANSFER_LENGTH) {
+ case TRANSFER_SINGLE:
+ storeSingle(&roundData, getFd(opcode), pAddress);
+ break;
+ case TRANSFER_DOUBLE:
+ storeDouble(&roundData, getFd(opcode), pAddress);
+ break;
+#ifdef CONFIG_FPE_NWFPE_XP
+ case TRANSFER_EXTENDED:
+ storeExtended(getFd(opcode), pAddress);
+ break;
+#endif
+ default:
+ nRc = 0;
+ }
+
+ if (roundData.exception)
+ float_raise(roundData.exception);
+
+ if (write_back)
+ writeRegister(getRn(opcode), (unsigned long) pFinal);
+ return nRc;
+}
+
+unsigned int PerformLFM(const unsigned int opcode)
+{
+ unsigned int __user *pBase, *pAddress, *pFinal;
+ unsigned int i, Fd, write_back = WRITE_BACK(opcode);
+
+ pBase = (unsigned int __user *) readRegister(getRn(opcode));
+ if (REG_PC == getRn(opcode)) {
+ pBase += 2;
+ write_back = 0;
+ }
+
+ pFinal = pBase;
+ if (BIT_UP_SET(opcode))
+ pFinal += getOffset(opcode);
+ else
+ pFinal -= getOffset(opcode);
+
+ if (PREINDEXED(opcode))
+ pAddress = pFinal;
+ else
+ pAddress = pBase;
+
+ Fd = getFd(opcode);
+ for (i = getRegisterCount(opcode); i > 0; i--) {
+ loadMultiple(Fd, pAddress);
+ pAddress += 3;
+ Fd++;
+ if (Fd == 8)
+ Fd = 0;
+ }
+
+ if (write_back)
+ writeRegister(getRn(opcode), (unsigned long) pFinal);
+ return 1;
+}
+
+unsigned int PerformSFM(const unsigned int opcode)
+{
+ unsigned int __user *pBase, *pAddress, *pFinal;
+ unsigned int i, Fd, write_back = WRITE_BACK(opcode);
+
+ pBase = (unsigned int __user *) readRegister(getRn(opcode));
+ if (REG_PC == getRn(opcode)) {
+ pBase += 2;
+ write_back = 0;
+ }
+
+ pFinal = pBase;
+ if (BIT_UP_SET(opcode))
+ pFinal += getOffset(opcode);
+ else
+ pFinal -= getOffset(opcode);
+
+ if (PREINDEXED(opcode))
+ pAddress = pFinal;
+ else
+ pAddress = pBase;
+
+ Fd = getFd(opcode);
+ for (i = getRegisterCount(opcode); i > 0; i--) {
+ storeMultiple(Fd, pAddress);
+ pAddress += 3;
+ Fd++;
+ if (Fd == 8)
+ Fd = 0;
+ }
+
+ if (write_back)
+ writeRegister(getRn(opcode), (unsigned long) pFinal);
+ return 1;
+}
+
+unsigned int EmulateCPDT(const unsigned int opcode)
+{
+ unsigned int nRc = 0;
+
+ if (LDF_OP(opcode)) {
+ nRc = PerformLDF(opcode);
+ } else if (LFM_OP(opcode)) {
+ nRc = PerformLFM(opcode);
+ } else if (STF_OP(opcode)) {
+ nRc = PerformSTF(opcode);
+ } else if (SFM_OP(opcode)) {
+ nRc = PerformSFM(opcode);
+ } else {
+ nRc = 0;
+ }
+
+ return nRc;
+}
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c
new file mode 100644
index 00000000..31c4eeec
--- /dev/null
+++ b/arch/arm/nwfpe/fpa11_cprt.c
@@ -0,0 +1,373 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+ (c) Philip Blundell, 1999, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "fpopcode.h"
+#include "fpa11.inl"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+#include "softfloat.h"
+
+unsigned int PerformFLT(const unsigned int opcode);
+unsigned int PerformFIX(const unsigned int opcode);
+
+static unsigned int PerformComparison(const unsigned int opcode);
+
+unsigned int EmulateCPRT(const unsigned int opcode)
+{
+
+ if (opcode & 0x800000) {
+ /* This is some variant of a comparison (PerformComparison
+ will sort out which one). Since most of the other CPRT
+ instructions are oddball cases of some sort or other it
+ makes sense to pull this out into a fast path. */
+ return PerformComparison(opcode);
+ }
+
+ /* Hint to GCC that we'd like a jump table rather than a load of CMPs */
+ switch ((opcode & 0x700000) >> 20) {
+ case FLT_CODE >> 20:
+ return PerformFLT(opcode);
+ break;
+ case FIX_CODE >> 20:
+ return PerformFIX(opcode);
+ break;
+
+ case WFS_CODE >> 20:
+ writeFPSR(readRegister(getRd(opcode)));
+ break;
+ case RFS_CODE >> 20:
+ writeRegister(getRd(opcode), readFPSR());
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+unsigned int PerformFLT(const unsigned int opcode)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ struct roundingData roundData;
+
+ roundData.mode = SetRoundingMode(opcode);
+ roundData.precision = SetRoundingPrecision(opcode);
+ roundData.exception = 0;
+
+ switch (opcode & MASK_ROUNDING_PRECISION) {
+ case ROUND_SINGLE:
+ {
+ fpa11->fType[getFn(opcode)] = typeSingle;
+ fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode)));
+ }
+ break;
+
+ case ROUND_DOUBLE:
+ {
+ fpa11->fType[getFn(opcode)] = typeDouble;
+ fpa11->fpreg[getFn(opcode)].fDouble = int32_to_float64(readRegister(getRd(opcode)));
+ }
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case ROUND_EXTENDED:
+ {
+ fpa11->fType[getFn(opcode)] = typeExtended;
+ fpa11->fpreg[getFn(opcode)].fExtended = int32_to_floatx80(readRegister(getRd(opcode)));
+ }
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ if (roundData.exception)
+ float_raise(roundData.exception);
+
+ return 1;
+}
+
+unsigned int PerformFIX(const unsigned int opcode)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int Fn = getFm(opcode);
+ struct roundingData roundData;
+
+ roundData.mode = SetRoundingMode(opcode);
+ roundData.precision = SetRoundingPrecision(opcode);
+ roundData.exception = 0;
+
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ {
+ writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle));
+ }
+ break;
+
+ case typeDouble:
+ {
+ writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble));
+ }
+ break;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ case typeExtended:
+ {
+ writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended));
+ }
+ break;
+#endif
+
+ default:
+ return 0;
+ }
+
+ if (roundData.exception)
+ float_raise(roundData.exception);
+
+ return 1;
+}
+
+/* This instruction sets the flags N, Z, C, V in the FPSR. */
+static unsigned int PerformComparison(const unsigned int opcode)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ unsigned int Fn = getFn(opcode), Fm = getFm(opcode);
+ int e_flag = opcode & 0x400000; /* 1 if CxFE */
+ int n_flag = opcode & 0x200000; /* 1 if CNxx */
+ unsigned int flags = 0;
+
+#ifdef CONFIG_FPE_NWFPE_XP
+ floatx80 rFn, rFm;
+
+ /* Check for unordered condition and convert all operands to 80-bit
+ format.
+ ?? Might be some mileage in avoiding this conversion if possible.
+ Eg, if both operands are 32-bit, detect this and do a 32-bit
+ comparison (cheaper than an 80-bit one). */
+ switch (fpa11->fType[Fn]) {
+ case typeSingle:
+ //printk("single.\n");
+ if (float32_is_nan(fpa11->fpreg[Fn].fSingle))
+ goto unordered;
+ rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
+ break;
+
+ case typeDouble:
+ //printk("double.\n");
+ if (float64_is_nan(fpa11->fpreg[Fn].fDouble))
+ goto unordered;
+ rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
+ break;
+
+ case typeExtended:
+ //printk("extended.\n");
+ if (floatx80_is_nan(fpa11->fpreg[Fn].fExtended))
+ goto unordered;
+ rFn = fpa11->fpreg[Fn].fExtended;
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (CONSTANT_FM(opcode)) {
+ //printk("Fm is a constant: #%d.\n",Fm);
+ rFm = getExtendedConstant(Fm);
+ if (floatx80_is_nan(rFm))
+ goto unordered;
+ } else {
+ //printk("Fm = r%d which contains a ",Fm);
+ switch (fpa11->fType[Fm]) {
+ case typeSingle:
+ //printk("single.\n");
+ if (float32_is_nan(fpa11->fpreg[Fm].fSingle))
+ goto unordered;
+ rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
+ break;
+
+ case typeDouble:
+ //printk("double.\n");
+ if (float64_is_nan(fpa11->fpreg[Fm].fDouble))
+ goto unordered;
+ rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
+ break;
+
+ case typeExtended:
+ //printk("extended.\n");
+ if (floatx80_is_nan(fpa11->fpreg[Fm].fExtended))
+ goto unordered;
+ rFm = fpa11->fpreg[Fm].fExtended;
+ break;
+
+ default:
+ return 0;
+ }
+ }
+
+ if (n_flag)
+ rFm.high ^= 0x8000;
+
+ /* test for less than condition */
+ if (floatx80_lt(rFn, rFm))
+ flags |= CC_NEGATIVE;
+
+ /* test for equal condition */
+ if (floatx80_eq(rFn, rFm))
+ flags |= CC_ZERO;
+
+ /* test for greater than or equal condition */
+ if (floatx80_lt(rFm, rFn))
+ flags |= CC_CARRY;
+
+#else
+ if (CONSTANT_FM(opcode)) {
+ /* Fm is a constant. Do the comparison in whatever precision
+ Fn happens to be stored in. */
+ if (fpa11->fType[Fn] == typeSingle) {
+ float32 rFm = getSingleConstant(Fm);
+ float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+ if (float32_is_nan(rFn))
+ goto unordered;
+
+ if (n_flag)
+ rFm ^= 0x80000000;
+
+ /* test for less than condition */
+ if (float32_lt_nocheck(rFn, rFm))
+ flags |= CC_NEGATIVE;
+
+ /* test for equal condition */
+ if (float32_eq_nocheck(rFn, rFm))
+ flags |= CC_ZERO;
+
+ /* test for greater than or equal condition */
+ if (float32_lt_nocheck(rFm, rFn))
+ flags |= CC_CARRY;
+ } else {
+ float64 rFm = getDoubleConstant(Fm);
+ float64 rFn = fpa11->fpreg[Fn].fDouble;
+
+ if (float64_is_nan(rFn))
+ goto unordered;
+
+ if (n_flag)
+ rFm ^= 0x8000000000000000ULL;
+
+ /* test for less than condition */
+ if (float64_lt_nocheck(rFn, rFm))
+ flags |= CC_NEGATIVE;
+
+ /* test for equal condition */
+ if (float64_eq_nocheck(rFn, rFm))
+ flags |= CC_ZERO;
+
+ /* test for greater than or equal condition */
+ if (float64_lt_nocheck(rFm, rFn))
+ flags |= CC_CARRY;
+ }
+ } else {
+ /* Both operands are in registers. */
+ if (fpa11->fType[Fn] == typeSingle
+ && fpa11->fType[Fm] == typeSingle) {
+ float32 rFm = fpa11->fpreg[Fm].fSingle;
+ float32 rFn = fpa11->fpreg[Fn].fSingle;
+
+ if (float32_is_nan(rFn)
+ || float32_is_nan(rFm))
+ goto unordered;
+
+ if (n_flag)
+ rFm ^= 0x80000000;
+
+ /* test for less than condition */
+ if (float32_lt_nocheck(rFn, rFm))
+ flags |= CC_NEGATIVE;
+
+ /* test for equal condition */
+ if (float32_eq_nocheck(rFn, rFm))
+ flags |= CC_ZERO;
+
+ /* test for greater than or equal condition */
+ if (float32_lt_nocheck(rFm, rFn))
+ flags |= CC_CARRY;
+ } else {
+ /* Promote 32-bit operand to 64 bits. */
+ float64 rFm, rFn;
+
+ rFm = (fpa11->fType[Fm] == typeSingle) ?
+ float32_to_float64(fpa11->fpreg[Fm].fSingle)
+ : fpa11->fpreg[Fm].fDouble;
+
+ rFn = (fpa11->fType[Fn] == typeSingle) ?
+ float32_to_float64(fpa11->fpreg[Fn].fSingle)
+ : fpa11->fpreg[Fn].fDouble;
+
+ if (float64_is_nan(rFn)
+ || float64_is_nan(rFm))
+ goto unordered;
+
+ if (n_flag)
+ rFm ^= 0x8000000000000000ULL;
+
+ /* test for less than condition */
+ if (float64_lt_nocheck(rFn, rFm))
+ flags |= CC_NEGATIVE;
+
+ /* test for equal condition */
+ if (float64_eq_nocheck(rFn, rFm))
+ flags |= CC_ZERO;
+
+ /* test for greater than or equal condition */
+ if (float64_lt_nocheck(rFm, rFn))
+ flags |= CC_CARRY;
+ }
+ }
+
+#endif
+
+ writeConditionCodes(flags);
+
+ return 1;
+
+ unordered:
+ /* ?? The FPA data sheet is pretty vague about this, in particular
+ about whether the non-E comparisons can ever raise exceptions.
+ This implementation is based on a combination of what it says in
+ the data sheet, observation of how the Acorn emulator actually
+ behaves (and how programs expect it to) and guesswork. */
+ flags |= CC_OVERFLOW;
+ flags &= ~(CC_ZERO | CC_NEGATIVE);
+
+ if (BIT_AC & readFPSR())
+ flags |= CC_CARRY;
+
+ if (e_flag)
+ float_raise(float_flag_invalid);
+
+ writeConditionCodes(flags);
+ return 1;
+}
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c
new file mode 100644
index 00000000..cb7658e8
--- /dev/null
+++ b/arch/arm/nwfpe/fpmodule.c
@@ -0,0 +1,190 @@
+
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.com, 1998-1999
+ (c) Philip Blundell, 1998-1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+/* XXX */
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/thread_notify.h>
+
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpmodule.h"
+#include "fpa11.inl"
+
+/* kernel symbols required for signal handling */
+#ifdef CONFIG_FPE_NWFPE_XP
+#define NWFPE_BITS "extended"
+#else
+#define NWFPE_BITS "double"
+#endif
+
+#ifdef MODULE
+void fp_send_sig(unsigned long sig, struct task_struct *p, int priv);
+#else
+#define fp_send_sig send_sig
+#define kern_fp_enter fp_enter
+
+extern char fpe_type[];
+#endif
+
+static int nwfpe_notify(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ struct thread_info *thread = v;
+
+ if (cmd == THREAD_NOTIFY_FLUSH)
+ nwfpe_init_fpa(&thread->fpstate);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block nwfpe_notifier_block = {
+ .notifier_call = nwfpe_notify,
+};
+
+/* kernel function prototypes required */
+void fp_setup(void);
+
+/* external declarations for saved kernel symbols */
+extern void (*kern_fp_enter)(void);
+
+/* Original value of fp_enter from kernel before patched by fpe_init. */
+static void (*orig_fp_enter)(void);
+
+/* forward declarations */
+extern void nwfpe_enter(void);
+
+static int __init fpe_init(void)
+{
+ if (sizeof(FPA11) > sizeof(union fp_state)) {
+ printk(KERN_ERR "nwfpe: bad structure size\n");
+ return -EINVAL;
+ }
+
+ if (sizeof(FPREG) != 12) {
+ printk(KERN_ERR "nwfpe: bad register size\n");
+ return -EINVAL;
+ }
+ if (fpe_type[0] && strcmp(fpe_type, "nwfpe"))
+ return 0;
+
+ /* Display title, version and copyright information. */
+ printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 ("
+ NWFPE_BITS " precision)\n");
+
+ thread_register_notifier(&nwfpe_notifier_block);
+
+ /* Save pointer to the old FP handler and then patch ourselves in */
+ orig_fp_enter = kern_fp_enter;
+ kern_fp_enter = nwfpe_enter;
+
+ return 0;
+}
+
+static void __exit fpe_exit(void)
+{
+ thread_unregister_notifier(&nwfpe_notifier_block);
+ /* Restore the values we saved earlier. */
+ kern_fp_enter = orig_fp_enter;
+}
+
+/*
+ScottB: November 4, 1998
+
+Moved this function out of softfloat-specialize into fpmodule.c.
+This effectively isolates all the changes required for integrating with the
+Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying
+fpmodule.c to integrate with the NetBSD kernel (I hope!).
+
+[1/1/99: Not quite true any more unfortunately. There is Linux-specific
+code to access data in user space in some other source files at the
+moment (grep for get_user / put_user calls). --philb]
+
+This function is called by the SoftFloat routines to raise a floating
+point exception. We check the trap enable byte in the FPSR, and raise
+a SIGFPE exception if necessary. If not the relevant bits in the
+cumulative exceptions flag byte are set and we return.
+*/
+
+#ifdef CONFIG_DEBUG_USER
+/* By default, ignore inexact errors as there are far too many of them to log */
+static int debug = ~BIT_IXC;
+#endif
+
+void float_raise(signed char flags)
+{
+ register unsigned int fpsr, cumulativeTraps;
+
+#ifdef CONFIG_DEBUG_USER
+ if (flags & debug)
+ printk(KERN_DEBUG
+ "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n",
+ current->comm, current->pid, flags,
+ __builtin_return_address(0), GET_USERREG()->ARM_pc);
+#endif
+
+ /* Read fpsr and initialize the cumulativeTraps. */
+ fpsr = readFPSR();
+ cumulativeTraps = 0;
+
+ /* For each type of exception, the cumulative trap exception bit is only
+ set if the corresponding trap enable bit is not set. */
+ if ((!(fpsr & BIT_IXE)) && (flags & BIT_IXC))
+ cumulativeTraps |= BIT_IXC;
+ if ((!(fpsr & BIT_UFE)) && (flags & BIT_UFC))
+ cumulativeTraps |= BIT_UFC;
+ if ((!(fpsr & BIT_OFE)) && (flags & BIT_OFC))
+ cumulativeTraps |= BIT_OFC;
+ if ((!(fpsr & BIT_DZE)) && (flags & BIT_DZC))
+ cumulativeTraps |= BIT_DZC;
+ if ((!(fpsr & BIT_IOE)) && (flags & BIT_IOC))
+ cumulativeTraps |= BIT_IOC;
+
+ /* Set the cumulative exceptions flags. */
+ if (cumulativeTraps)
+ writeFPSR(fpsr | cumulativeTraps);
+
+ /* Raise an exception if necessary. */
+ if (fpsr & (flags << 16))
+ fp_send_sig(SIGFPE, current, 1);
+}
+
+module_init(fpe_init);
+module_exit(fpe_exit);
+
+MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
+MODULE_DESCRIPTION("NWFPE floating point emulator (" NWFPE_BITS " precision)");
+MODULE_LICENSE("GPL");
+
+#ifdef CONFIG_DEBUG_USER
+module_param(debug, int, 0644);
+#endif
diff --git a/arch/arm/nwfpe/fpmodule.h b/arch/arm/nwfpe/fpmodule.h
new file mode 100644
index 00000000..5c2e8e48
--- /dev/null
+++ b/arch/arm/nwfpe/fpmodule.h
@@ -0,0 +1,47 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.com, 1998-1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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.
+
+ 27/03/03 Ian Molton Clean up CONFIG_CPU
+*/
+
+#ifndef __FPMODULE_H__
+#define __FPMODULE_H__
+
+#define REG_ORIG_R0 17
+#define REG_CPSR 16
+#define REG_PC 15
+#define REG_LR 14
+#define REG_SP 13
+#define REG_IP 12
+#define REG_FP 11
+#define REG_R10 10
+#define REG_R9 9
+#define REG_R9 9
+#define REG_R8 8
+#define REG_R7 7
+#define REG_R6 6
+#define REG_R5 5
+#define REG_R4 4
+#define REG_R3 3
+#define REG_R2 2
+#define REG_R1 1
+#define REG_R0 0
+
+#endif
diff --git a/arch/arm/nwfpe/fpmodule.inl b/arch/arm/nwfpe/fpmodule.inl
new file mode 100644
index 00000000..2c39ad40
--- /dev/null
+++ b/arch/arm/nwfpe/fpmodule.inl
@@ -0,0 +1,74 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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.
+*/
+
+static inline unsigned long readRegister(const unsigned int nReg)
+{
+ /* Note: The CPU thinks it has dealt with the current instruction.
+ As a result the program counter has been advanced to the next
+ instruction, and points 4 bytes beyond the actual instruction
+ that caused the invalid instruction trap to occur. We adjust
+ for this in this routine. LDF/STF instructions with Rn = PC
+ depend on the PC being correct, as they use PC+8 in their
+ address calculations. */
+ struct pt_regs *regs = GET_USERREG();
+ unsigned int val = regs->uregs[nReg];
+ if (REG_PC == nReg)
+ val -= 4;
+ return val;
+}
+
+static inline void
+writeRegister(const unsigned int nReg, const unsigned long val)
+{
+ struct pt_regs *regs = GET_USERREG();
+ regs->uregs[nReg] = val;
+}
+
+static inline unsigned long readCPSR(void)
+{
+ return (readRegister(REG_CPSR));
+}
+
+static inline void writeCPSR(const unsigned long val)
+{
+ writeRegister(REG_CPSR, val);
+}
+
+static inline unsigned long readConditionCodes(void)
+{
+#ifdef __FPEM_TEST__
+ return (0);
+#else
+ return (readCPSR() & CC_MASK);
+#endif
+}
+
+static inline void writeConditionCodes(const unsigned long val)
+{
+ struct pt_regs *regs = GET_USERREG();
+ unsigned long rval;
+ /*
+ * Operate directly on userRegisters since
+ * the CPSR may be the PC register itself.
+ */
+ rval = regs->ARM_cpsr & ~CC_MASK;
+ regs->ARM_cpsr = rval | (val & CC_MASK);
+}
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
new file mode 100644
index 00000000..922b8110
--- /dev/null
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -0,0 +1,89 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+#include "fpsr.h"
+#include "fpmodule.h"
+#include "fpmodule.inl"
+
+#ifdef CONFIG_FPE_NWFPE_XP
+const floatx80 floatx80Constant[] = {
+ { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
+ { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
+ { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
+ { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
+ { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
+ { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
+ { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
+ { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
+};
+#endif
+
+const float64 float64Constant[] = {
+ 0x0000000000000000ULL, /* double 0.0 */
+ 0x3ff0000000000000ULL, /* double 1.0 */
+ 0x4000000000000000ULL, /* double 2.0 */
+ 0x4008000000000000ULL, /* double 3.0 */
+ 0x4010000000000000ULL, /* double 4.0 */
+ 0x4014000000000000ULL, /* double 5.0 */
+ 0x3fe0000000000000ULL, /* double 0.5 */
+ 0x4024000000000000ULL /* double 10.0 */
+};
+
+const float32 float32Constant[] = {
+ 0x00000000, /* single 0.0 */
+ 0x3f800000, /* single 1.0 */
+ 0x40000000, /* single 2.0 */
+ 0x40400000, /* single 3.0 */
+ 0x40800000, /* single 4.0 */
+ 0x40a00000, /* single 5.0 */
+ 0x3f000000, /* single 0.5 */
+ 0x41200000 /* single 10.0 */
+};
+
+/* condition code lookup table
+ index into the table is test code: EQ, NE, ... LT, GT, AL, NV
+ bit position in short is condition code: NZCV */
+static const unsigned short aCC[16] = {
+ 0xF0F0, // EQ == Z set
+ 0x0F0F, // NE
+ 0xCCCC, // CS == C set
+ 0x3333, // CC
+ 0xFF00, // MI == N set
+ 0x00FF, // PL
+ 0xAAAA, // VS == V set
+ 0x5555, // VC
+ 0x0C0C, // HI == C set && Z clear
+ 0xF3F3, // LS == C clear || Z set
+ 0xAA55, // GE == (N==V)
+ 0x55AA, // LT == (N!=V)
+ 0x0A05, // GT == (!Z && (N==V))
+ 0xF5FA, // LE == (Z || (N!=V))
+ 0xFFFF, // AL always
+ 0 // NV
+};
+
+unsigned int checkCondition(const unsigned int opcode, const unsigned int ccodes)
+{
+ return (aCC[opcode >> 28] >> (ccodes >> 28)) & 1;
+}
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
new file mode 100644
index 00000000..786e4c96
--- /dev/null
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -0,0 +1,484 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+ (c) Philip Blundell, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPOPCODE_H__
+#define __FPOPCODE_H__
+
+
+/*
+ARM Floating Point Instruction Classes
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+|c o n d|1 1 0 P|U|u|W|L| Rn |v| Fd |0|0|0|1| o f f s e t | CPDT
+|c o n d|1 1 0 P|U|w|W|L| Rn |x| Fd |0|0|1|0| o f f s e t | CPDT (copro 2)
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+|c o n d|1 1 1 0|a|b|c|d|e| Fn |j| Fd |0|0|0|1|f|g|h|0|i| Fm | CPDO
+|c o n d|1 1 1 0|a|b|c|L|e| Fn | Rd |0|0|0|1|f|g|h|1|i| Fm | CPRT
+|c o n d|1 1 1 0|a|b|c|1|e| Fn |1|1|1|1|0|0|0|1|f|g|h|1|i| Fm | comparisons
+| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+
+CPDT data transfer instructions
+ LDF, STF, LFM (copro 2), SFM (copro 2)
+
+CPDO dyadic arithmetic instructions
+ ADF, MUF, SUF, RSF, DVF, RDF,
+ POW, RPW, RMF, FML, FDV, FRD, POL
+
+CPDO monadic arithmetic instructions
+ MVF, MNF, ABS, RND, SQT, LOG, LGN, EXP,
+ SIN, COS, TAN, ASN, ACS, ATN, URD, NRM
+
+CPRT joint arithmetic/data transfer instructions
+ FIX (arithmetic followed by load/store)
+ FLT (load/store followed by arithmetic)
+ CMF, CNF CMFE, CNFE (comparisons)
+ WFS, RFS (write/read floating point status register)
+ WFC, RFC (write/read floating point control register)
+
+cond condition codes
+P pre/post index bit: 0 = postindex, 1 = preindex
+U up/down bit: 0 = stack grows down, 1 = stack grows up
+W write back bit: 1 = update base register (Rn)
+L load/store bit: 0 = store, 1 = load
+Rn base register
+Rd destination/source register
+Fd floating point destination register
+Fn floating point source register
+Fm floating point source register or floating point constant
+
+uv transfer length (TABLE 1)
+wx register count (TABLE 2)
+abcd arithmetic opcode (TABLES 3 & 4)
+ef destination size (rounding precision) (TABLE 5)
+gh rounding mode (TABLE 6)
+j dyadic/monadic bit: 0 = dyadic, 1 = monadic
+i constant bit: 1 = constant (TABLE 6)
+*/
+
+/*
+TABLE 1
++-------------------------+---+---+---------+---------+
+| Precision | u | v | FPSR.EP | length |
++-------------------------+---+---+---------+---------+
+| Single | 0 | 0 | x | 1 words |
+| Double | 1 | 1 | x | 2 words |
+| Extended | 1 | 1 | x | 3 words |
+| Packed decimal | 1 | 1 | 0 | 3 words |
+| Expanded packed decimal | 1 | 1 | 1 | 4 words |
++-------------------------+---+---+---------+---------+
+Note: x = don't care
+*/
+
+/*
+TABLE 2
++---+---+---------------------------------+
+| w | x | Number of registers to transfer |
++---+---+---------------------------------+
+| 0 | 1 | 1 |
+| 1 | 0 | 2 |
+| 1 | 1 | 3 |
+| 0 | 0 | 4 |
++---+---+---------------------------------+
+*/
+
+/*
+TABLE 3: Dyadic Floating Point Opcodes
++---+---+---+---+----------+-----------------------+-----------------------+
+| a | b | c | d | Mnemonic | Description | Operation |
++---+---+---+---+----------+-----------------------+-----------------------+
+| 0 | 0 | 0 | 0 | ADF | Add | Fd := Fn + Fm |
+| 0 | 0 | 0 | 1 | MUF | Multiply | Fd := Fn * Fm |
+| 0 | 0 | 1 | 0 | SUF | Subtract | Fd := Fn - Fm |
+| 0 | 0 | 1 | 1 | RSF | Reverse subtract | Fd := Fm - Fn |
+| 0 | 1 | 0 | 0 | DVF | Divide | Fd := Fn / Fm |
+| 0 | 1 | 0 | 1 | RDF | Reverse divide | Fd := Fm / Fn |
+| 0 | 1 | 1 | 0 | POW | Power | Fd := Fn ^ Fm |
+| 0 | 1 | 1 | 1 | RPW | Reverse power | Fd := Fm ^ Fn |
+| 1 | 0 | 0 | 0 | RMF | Remainder | Fd := IEEE rem(Fn/Fm) |
+| 1 | 0 | 0 | 1 | FML | Fast Multiply | Fd := Fn * Fm |
+| 1 | 0 | 1 | 0 | FDV | Fast Divide | Fd := Fn / Fm |
+| 1 | 0 | 1 | 1 | FRD | Fast reverse divide | Fd := Fm / Fn |
+| 1 | 1 | 0 | 0 | POL | Polar angle (ArcTan2) | Fd := arctan2(Fn,Fm) |
+| 1 | 1 | 0 | 1 | | undefined instruction | trap |
+| 1 | 1 | 1 | 0 | | undefined instruction | trap |
+| 1 | 1 | 1 | 1 | | undefined instruction | trap |
++---+---+---+---+----------+-----------------------+-----------------------+
+Note: POW, RPW, POL are deprecated, and are available for backwards
+ compatibility only.
+*/
+
+/*
+TABLE 4: Monadic Floating Point Opcodes
++---+---+---+---+----------+-----------------------+-----------------------+
+| a | b | c | d | Mnemonic | Description | Operation |
++---+---+---+---+----------+-----------------------+-----------------------+
+| 0 | 0 | 0 | 0 | MVF | Move | Fd := Fm |
+| 0 | 0 | 0 | 1 | MNF | Move negated | Fd := - Fm |
+| 0 | 0 | 1 | 0 | ABS | Absolute value | Fd := abs(Fm) |
+| 0 | 0 | 1 | 1 | RND | Round to integer | Fd := int(Fm) |
+| 0 | 1 | 0 | 0 | SQT | Square root | Fd := sqrt(Fm) |
+| 0 | 1 | 0 | 1 | LOG | Log base 10 | Fd := log10(Fm) |
+| 0 | 1 | 1 | 0 | LGN | Log base e | Fd := ln(Fm) |
+| 0 | 1 | 1 | 1 | EXP | Exponent | Fd := e ^ Fm |
+| 1 | 0 | 0 | 0 | SIN | Sine | Fd := sin(Fm) |
+| 1 | 0 | 0 | 1 | COS | Cosine | Fd := cos(Fm) |
+| 1 | 0 | 1 | 0 | TAN | Tangent | Fd := tan(Fm) |
+| 1 | 0 | 1 | 1 | ASN | Arc Sine | Fd := arcsin(Fm) |
+| 1 | 1 | 0 | 0 | ACS | Arc Cosine | Fd := arccos(Fm) |
+| 1 | 1 | 0 | 1 | ATN | Arc Tangent | Fd := arctan(Fm) |
+| 1 | 1 | 1 | 0 | URD | Unnormalized round | Fd := int(Fm) |
+| 1 | 1 | 1 | 1 | NRM | Normalize | Fd := norm(Fm) |
++---+---+---+---+----------+-----------------------+-----------------------+
+Note: LOG, LGN, EXP, SIN, COS, TAN, ASN, ACS, ATN are deprecated, and are
+ available for backwards compatibility only.
+*/
+
+/*
+TABLE 5
++-------------------------+---+---+
+| Rounding Precision | e | f |
++-------------------------+---+---+
+| IEEE Single precision | 0 | 0 |
+| IEEE Double precision | 0 | 1 |
+| IEEE Extended precision | 1 | 0 |
+| undefined (trap) | 1 | 1 |
++-------------------------+---+---+
+*/
+
+/*
+TABLE 5
++---------------------------------+---+---+
+| Rounding Mode | g | h |
++---------------------------------+---+---+
+| Round to nearest (default) | 0 | 0 |
+| Round toward plus infinity | 0 | 1 |
+| Round toward negative infinity | 1 | 0 |
+| Round toward zero | 1 | 1 |
++---------------------------------+---+---+
+*/
+
+/*
+===
+=== Definitions for load and store instructions
+===
+*/
+
+/* bit masks */
+#define BIT_PREINDEX 0x01000000
+#define BIT_UP 0x00800000
+#define BIT_WRITE_BACK 0x00200000
+#define BIT_LOAD 0x00100000
+
+/* masks for load/store */
+#define MASK_CPDT 0x0c000000 /* data processing opcode */
+#define MASK_OFFSET 0x000000ff
+#define MASK_TRANSFER_LENGTH 0x00408000
+#define MASK_REGISTER_COUNT MASK_TRANSFER_LENGTH
+#define MASK_COPROCESSOR 0x00000f00
+
+/* Tests for transfer length */
+#define TRANSFER_SINGLE 0x00000000
+#define TRANSFER_DOUBLE 0x00008000
+#define TRANSFER_EXTENDED 0x00400000
+#define TRANSFER_PACKED MASK_TRANSFER_LENGTH
+
+/* Get the coprocessor number from the opcode. */
+#define getCoprocessorNumber(opcode) ((opcode & MASK_COPROCESSOR) >> 8)
+
+/* Get the offset from the opcode. */
+#define getOffset(opcode) (opcode & MASK_OFFSET)
+
+/* Tests for specific data transfer load/store opcodes. */
+#define TEST_OPCODE(opcode,mask) (((opcode) & (mask)) == (mask))
+
+#define LOAD_OP(opcode) TEST_OPCODE((opcode),MASK_CPDT | BIT_LOAD)
+#define STORE_OP(opcode) ((opcode & (MASK_CPDT | BIT_LOAD)) == MASK_CPDT)
+
+#define LDF_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
+#define LFM_OP(opcode) (LOAD_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
+#define STF_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 1))
+#define SFM_OP(opcode) (STORE_OP(opcode) && (getCoprocessorNumber(opcode) == 2))
+
+#define PREINDEXED(opcode) ((opcode & BIT_PREINDEX) != 0)
+#define POSTINDEXED(opcode) ((opcode & BIT_PREINDEX) == 0)
+#define BIT_UP_SET(opcode) ((opcode & BIT_UP) != 0)
+#define BIT_UP_CLEAR(opcode) ((opcode & BIT_DOWN) == 0)
+#define WRITE_BACK(opcode) ((opcode & BIT_WRITE_BACK) != 0)
+#define LOAD(opcode) ((opcode & BIT_LOAD) != 0)
+#define STORE(opcode) ((opcode & BIT_LOAD) == 0)
+
+/*
+===
+=== Definitions for arithmetic instructions
+===
+*/
+/* bit masks */
+#define BIT_MONADIC 0x00008000
+#define BIT_CONSTANT 0x00000008
+
+#define CONSTANT_FM(opcode) ((opcode & BIT_CONSTANT) != 0)
+#define MONADIC_INSTRUCTION(opcode) ((opcode & BIT_MONADIC) != 0)
+
+/* instruction identification masks */
+#define MASK_CPDO 0x0e000000 /* arithmetic opcode */
+#define MASK_ARITHMETIC_OPCODE 0x00f08000
+#define MASK_DESTINATION_SIZE 0x00080080
+
+/* dyadic arithmetic opcodes. */
+#define ADF_CODE 0x00000000
+#define MUF_CODE 0x00100000
+#define SUF_CODE 0x00200000
+#define RSF_CODE 0x00300000
+#define DVF_CODE 0x00400000
+#define RDF_CODE 0x00500000
+#define POW_CODE 0x00600000
+#define RPW_CODE 0x00700000
+#define RMF_CODE 0x00800000
+#define FML_CODE 0x00900000
+#define FDV_CODE 0x00a00000
+#define FRD_CODE 0x00b00000
+#define POL_CODE 0x00c00000
+/* 0x00d00000 is an invalid dyadic arithmetic opcode */
+/* 0x00e00000 is an invalid dyadic arithmetic opcode */
+/* 0x00f00000 is an invalid dyadic arithmetic opcode */
+
+/* monadic arithmetic opcodes. */
+#define MVF_CODE 0x00008000
+#define MNF_CODE 0x00108000
+#define ABS_CODE 0x00208000
+#define RND_CODE 0x00308000
+#define SQT_CODE 0x00408000
+#define LOG_CODE 0x00508000
+#define LGN_CODE 0x00608000
+#define EXP_CODE 0x00708000
+#define SIN_CODE 0x00808000
+#define COS_CODE 0x00908000
+#define TAN_CODE 0x00a08000
+#define ASN_CODE 0x00b08000
+#define ACS_CODE 0x00c08000
+#define ATN_CODE 0x00d08000
+#define URD_CODE 0x00e08000
+#define NRM_CODE 0x00f08000
+
+/*
+===
+=== Definitions for register transfer and comparison instructions
+===
+*/
+
+#define MASK_CPRT 0x0e000010 /* register transfer opcode */
+#define MASK_CPRT_CODE 0x00f00000
+#define FLT_CODE 0x00000000
+#define FIX_CODE 0x00100000
+#define WFS_CODE 0x00200000
+#define RFS_CODE 0x00300000
+#define WFC_CODE 0x00400000
+#define RFC_CODE 0x00500000
+#define CMF_CODE 0x00900000
+#define CNF_CODE 0x00b00000
+#define CMFE_CODE 0x00d00000
+#define CNFE_CODE 0x00f00000
+
+/*
+===
+=== Common definitions
+===
+*/
+
+/* register masks */
+#define MASK_Rd 0x0000f000
+#define MASK_Rn 0x000f0000
+#define MASK_Fd 0x00007000
+#define MASK_Fm 0x00000007
+#define MASK_Fn 0x00070000
+
+/* condition code masks */
+#define CC_MASK 0xf0000000
+#define CC_NEGATIVE 0x80000000
+#define CC_ZERO 0x40000000
+#define CC_CARRY 0x20000000
+#define CC_OVERFLOW 0x10000000
+#define CC_EQ 0x00000000
+#define CC_NE 0x10000000
+#define CC_CS 0x20000000
+#define CC_HS CC_CS
+#define CC_CC 0x30000000
+#define CC_LO CC_CC
+#define CC_MI 0x40000000
+#define CC_PL 0x50000000
+#define CC_VS 0x60000000
+#define CC_VC 0x70000000
+#define CC_HI 0x80000000
+#define CC_LS 0x90000000
+#define CC_GE 0xa0000000
+#define CC_LT 0xb0000000
+#define CC_GT 0xc0000000
+#define CC_LE 0xd0000000
+#define CC_AL 0xe0000000
+#define CC_NV 0xf0000000
+
+/* rounding masks/values */
+#define MASK_ROUNDING_MODE 0x00000060
+#define ROUND_TO_NEAREST 0x00000000
+#define ROUND_TO_PLUS_INFINITY 0x00000020
+#define ROUND_TO_MINUS_INFINITY 0x00000040
+#define ROUND_TO_ZERO 0x00000060
+
+#define MASK_ROUNDING_PRECISION 0x00080080
+#define ROUND_SINGLE 0x00000000
+#define ROUND_DOUBLE 0x00000080
+#define ROUND_EXTENDED 0x00080000
+
+/* Get the condition code from the opcode. */
+#define getCondition(opcode) (opcode >> 28)
+
+/* Get the source register from the opcode. */
+#define getRn(opcode) ((opcode & MASK_Rn) >> 16)
+
+/* Get the destination floating point register from the opcode. */
+#define getFd(opcode) ((opcode & MASK_Fd) >> 12)
+
+/* Get the first source floating point register from the opcode. */
+#define getFn(opcode) ((opcode & MASK_Fn) >> 16)
+
+/* Get the second source floating point register from the opcode. */
+#define getFm(opcode) (opcode & MASK_Fm)
+
+/* Get the destination register from the opcode. */
+#define getRd(opcode) ((opcode & MASK_Rd) >> 12)
+
+/* Get the rounding mode from the opcode. */
+#define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5)
+
+#ifdef CONFIG_FPE_NWFPE_XP
+static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex)
+{
+ extern const floatx80 floatx80Constant[];
+ return floatx80Constant[nIndex];
+}
+#endif
+
+static inline float64 __pure getDoubleConstant(const unsigned int nIndex)
+{
+ extern const float64 float64Constant[];
+ return float64Constant[nIndex];
+}
+
+static inline float32 __pure getSingleConstant(const unsigned int nIndex)
+{
+ extern const float32 float32Constant[];
+ return float32Constant[nIndex];
+}
+
+static inline unsigned int getTransferLength(const unsigned int opcode)
+{
+ unsigned int nRc;
+
+ switch (opcode & MASK_TRANSFER_LENGTH) {
+ case 0x00000000:
+ nRc = 1;
+ break; /* single precision */
+ case 0x00008000:
+ nRc = 2;
+ break; /* double precision */
+ case 0x00400000:
+ nRc = 3;
+ break; /* extended precision */
+ default:
+ nRc = 0;
+ }
+
+ return (nRc);
+}
+
+static inline unsigned int getRegisterCount(const unsigned int opcode)
+{
+ unsigned int nRc;
+
+ switch (opcode & MASK_REGISTER_COUNT) {
+ case 0x00000000:
+ nRc = 4;
+ break;
+ case 0x00008000:
+ nRc = 1;
+ break;
+ case 0x00400000:
+ nRc = 2;
+ break;
+ case 0x00408000:
+ nRc = 3;
+ break;
+ default:
+ nRc = 0;
+ }
+
+ return (nRc);
+}
+
+static inline unsigned int getRoundingPrecision(const unsigned int opcode)
+{
+ unsigned int nRc;
+
+ switch (opcode & MASK_ROUNDING_PRECISION) {
+ case 0x00000000:
+ nRc = 1;
+ break;
+ case 0x00000080:
+ nRc = 2;
+ break;
+ case 0x00080000:
+ nRc = 3;
+ break;
+ default:
+ nRc = 0;
+ }
+
+ return (nRc);
+}
+
+static inline unsigned int getDestinationSize(const unsigned int opcode)
+{
+ unsigned int nRc;
+
+ switch (opcode & MASK_DESTINATION_SIZE) {
+ case 0x00000000:
+ nRc = typeSingle;
+ break;
+ case 0x00000080:
+ nRc = typeDouble;
+ break;
+ case 0x00080000:
+ nRc = typeExtended;
+ break;
+ default:
+ nRc = typeNone;
+ }
+
+ return (nRc);
+}
+
+extern unsigned int checkCondition(const unsigned int opcode,
+ const unsigned int ccodes);
+
+extern const float64 float64Constant[];
+extern const float32 float32Constant[];
+
+#endif
diff --git a/arch/arm/nwfpe/fpsr.h b/arch/arm/nwfpe/fpsr.h
new file mode 100644
index 00000000..bd425dc1
--- /dev/null
+++ b/arch/arm/nwfpe/fpsr.h
@@ -0,0 +1,108 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.com, 1998-1999
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __FPSR_H__
+#define __FPSR_H__
+
+/*
+The FPSR is a 32 bit register consisting of 4 parts, each exactly
+one byte.
+
+ SYSTEM ID
+ EXCEPTION TRAP ENABLE BYTE
+ SYSTEM CONTROL BYTE
+ CUMULATIVE EXCEPTION FLAGS BYTE
+
+The FPCR is a 32 bit register consisting of bit flags.
+*/
+
+/* SYSTEM ID
+------------
+Note: the system id byte is read only */
+
+typedef unsigned int FPSR; /* type for floating point status register */
+typedef unsigned int FPCR; /* type for floating point control register */
+
+#define MASK_SYSID 0xff000000
+#define BIT_HARDWARE 0x80000000
+#define FP_EMULATOR 0x01000000 /* System ID for emulator */
+#define FP_ACCELERATOR 0x81000000 /* System ID for FPA11 */
+
+/* EXCEPTION TRAP ENABLE BYTE
+----------------------------- */
+
+#define MASK_TRAP_ENABLE 0x00ff0000
+#define MASK_TRAP_ENABLE_STRICT 0x001f0000
+#define BIT_IXE 0x00100000 /* inexact exception enable */
+#define BIT_UFE 0x00080000 /* underflow exception enable */
+#define BIT_OFE 0x00040000 /* overflow exception enable */
+#define BIT_DZE 0x00020000 /* divide by zero exception enable */
+#define BIT_IOE 0x00010000 /* invalid operation exception enable */
+
+/* SYSTEM CONTROL BYTE
+---------------------- */
+
+#define MASK_SYSTEM_CONTROL 0x0000ff00
+#define MASK_TRAP_STRICT 0x00001f00
+
+#define BIT_AC 0x00001000 /* use alternative C-flag definition
+ for compares */
+#define BIT_EP 0x00000800 /* use expanded packed decimal format */
+#define BIT_SO 0x00000400 /* select synchronous operation of FPA */
+#define BIT_NE 0x00000200 /* NaN exception bit */
+#define BIT_ND 0x00000100 /* no denormalized numbers bit */
+
+/* CUMULATIVE EXCEPTION FLAGS BYTE
+---------------------------------- */
+
+#define MASK_EXCEPTION_FLAGS 0x000000ff
+#define MASK_EXCEPTION_FLAGS_STRICT 0x0000001f
+
+#define BIT_IXC 0x00000010 /* inexact exception flag */
+#define BIT_UFC 0x00000008 /* underflow exception flag */
+#define BIT_OFC 0x00000004 /* overfloat exception flag */
+#define BIT_DZC 0x00000002 /* divide by zero exception flag */
+#define BIT_IOC 0x00000001 /* invalid operation exception flag */
+
+/* Floating Point Control Register
+----------------------------------*/
+
+#define BIT_RU 0x80000000 /* rounded up bit */
+#define BIT_IE 0x10000000 /* inexact bit */
+#define BIT_MO 0x08000000 /* mantissa overflow bit */
+#define BIT_EO 0x04000000 /* exponent overflow bit */
+#define BIT_SB 0x00000800 /* store bounce */
+#define BIT_AB 0x00000400 /* arithmetic bounce */
+#define BIT_RE 0x00000200 /* rounding exception */
+#define BIT_DA 0x00000100 /* disable FPA */
+
+#define MASK_OP 0x00f08010 /* AU operation code */
+#define MASK_PR 0x00080080 /* AU precision */
+#define MASK_S1 0x00070000 /* AU source register 1 */
+#define MASK_S2 0x00000007 /* AU source register 2 */
+#define MASK_DS 0x00007000 /* AU destination register */
+#define MASK_RM 0x00000060 /* AU rounding mode */
+#define MASK_ALU 0x9cfff2ff /* only ALU can write these bits */
+#define MASK_RESET 0x00000d00 /* bits set on reset, all others cleared */
+#define MASK_WFC MASK_RESET
+#define MASK_RFC ~MASK_RESET
+
+#endif
diff --git a/arch/arm/nwfpe/milieu.h b/arch/arm/nwfpe/milieu.h
new file mode 100644
index 00000000..09a4f2dd
--- /dev/null
+++ b/arch/arm/nwfpe/milieu.h
@@ -0,0 +1,48 @@
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "ARM-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+ FALSE = 0,
+ TRUE = 1
+};
+
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c
new file mode 100644
index 00000000..c66981d6
--- /dev/null
+++ b/arch/arm/nwfpe/single_cpdo.c
@@ -0,0 +1,124 @@
+/*
+ NetWinder Floating Point Emulator
+ (c) Rebel.COM, 1998,1999
+ (c) Philip Blundell, 2001
+
+ Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ 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 "fpa11.h"
+#include "softfloat.h"
+#include "fpopcode.h"
+
+float32 float32_exp(float32 Fm);
+float32 float32_ln(float32 Fm);
+float32 float32_sin(float32 rFm);
+float32 float32_cos(float32 rFm);
+float32 float32_arcsin(float32 rFm);
+float32 float32_arctan(float32 rFm);
+float32 float32_log(float32 rFm);
+float32 float32_tan(float32 rFm);
+float32 float32_arccos(float32 rFm);
+float32 float32_pow(float32 rFn, float32 rFm);
+float32 float32_pol(float32 rFn, float32 rFm);
+
+static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm)
+{
+ return float32_sub(roundData, rFm, rFn);
+}
+
+static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm)
+{
+ return float32_div(roundData, rFm, rFn);
+}
+
+static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = {
+ [ADF_CODE >> 20] = float32_add,
+ [MUF_CODE >> 20] = float32_mul,
+ [SUF_CODE >> 20] = float32_sub,
+ [RSF_CODE >> 20] = float32_rsf,
+ [DVF_CODE >> 20] = float32_div,
+ [RDF_CODE >> 20] = float32_rdv,
+ [RMF_CODE >> 20] = float32_rem,
+
+ [FML_CODE >> 20] = float32_mul,
+ [FDV_CODE >> 20] = float32_div,
+ [FRD_CODE >> 20] = float32_rdv,
+};
+
+static float32 float32_mvf(struct roundingData *roundData, float32 rFm)
+{
+ return rFm;
+}
+
+static float32 float32_mnf(struct roundingData *roundData, float32 rFm)
+{
+ return rFm ^ 0x80000000;
+}
+
+static float32 float32_abs(struct roundingData *roundData, float32 rFm)
+{
+ return rFm & 0x7fffffff;
+}
+
+static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = {
+ [MVF_CODE >> 20] = float32_mvf,
+ [MNF_CODE >> 20] = float32_mnf,
+ [ABS_CODE >> 20] = float32_abs,
+ [RND_CODE >> 20] = float32_round_to_int,
+ [URD_CODE >> 20] = float32_round_to_int,
+ [SQT_CODE >> 20] = float32_sqrt,
+ [NRM_CODE >> 20] = float32_mvf,
+};
+
+unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
+{
+ FPA11 *fpa11 = GET_FPA11();
+ float32 rFm;
+ unsigned int Fm, opc_mask_shift;
+
+ Fm = getFm(opcode);
+ if (CONSTANT_FM(opcode)) {
+ rFm = getSingleConstant(Fm);
+ } else if (fpa11->fType[Fm] == typeSingle) {
+ rFm = fpa11->fpreg[Fm].fSingle;
+ } else {
+ return 0;
+ }
+
+ opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
+ if (!MONADIC_INSTRUCTION(opcode)) {
+ unsigned int Fn = getFn(opcode);
+ float32 rFn;
+
+ if (fpa11->fType[Fn] == typeSingle &&
+ dyadic_single[opc_mask_shift]) {
+ rFn = fpa11->fpreg[Fn].fSingle;
+ rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm);
+ } else {
+ return 0;
+ }
+ } else {
+ if (monadic_single[opc_mask_shift]) {
+ rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm);
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
diff --git a/arch/arm/nwfpe/softfloat-macros b/arch/arm/nwfpe/softfloat-macros
new file mode 100644
index 00000000..cf2a6173
--- /dev/null
+++ b/arch/arm/nwfpe/softfloat-macros
@@ -0,0 +1,754 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Shifts `a' right by the number of bits given in `count'. If any nonzero
+bits are shifted off, they are ``jammed'' into the least significant bit of
+the result by setting the least significant bit to 1. The value of `count'
+can be arbitrarily large; in particular, if `count' is greater than 32, the
+result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+The result is stored in the location pointed to by `zPtr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
+{
+ bits32 z;
+ if ( count == 0 ) {
+ z = a;
+ }
+ else if ( count < 32 ) {
+ z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
+ }
+ else {
+ z = ( a != 0 );
+ }
+ *zPtr = z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts `a' right by the number of bits given in `count'. If any nonzero
+bits are shifted off, they are ``jammed'' into the least significant bit of
+the result by setting the least significant bit to 1. The value of `count'
+can be arbitrarily large; in particular, if `count' is greater than 64, the
+result will be either 0 or 1, depending on whether `a' is zero or nonzero.
+The result is stored in the location pointed to by `zPtr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
+{
+ bits64 z;
+
+ __asm__("@shift64RightJamming -- start");
+ if ( count == 0 ) {
+ z = a;
+ }
+ else if ( count < 64 ) {
+ z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
+ }
+ else {
+ z = ( a != 0 );
+ }
+ __asm__("@shift64RightJamming -- end");
+ *zPtr = z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
+_plus_ the number of bits given in `count'. The shifted result is at most
+64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
+bits shifted off form a second 64-bit result as follows: The _last_ bit
+shifted off is the most-significant bit of the extra result, and the other
+63 bits of the extra result are all zero if and only if _all_but_the_last_
+bits shifted off were all zero. This extra result is stored in the location
+pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
+ (This routine makes more sense if `a0' and `a1' are considered to form a
+fixed-point value with binary point between `a0' and `a1'. This fixed-point
+value is shifted right by the number of bits given in `count', and the
+integer part of the result is returned at the location pointed to by
+`z0Ptr'. The fractional part of the result may be slightly corrupted as
+described above, and is returned at the location pointed to by `z1Ptr'.)
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift64ExtraRightJamming(
+ bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+ bits64 z0, z1;
+ int8 negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1 != 0 );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z1 = a0 | ( a1 != 0 );
+ }
+ else {
+ z1 = ( ( a0 | a1 ) != 0 );
+ }
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'. Any bits shifted off are lost. The value
+of `count' can be arbitrarily large; in particular, if `count' is greater
+than 128, the result will be 0. The result is broken into two 64-bit pieces
+which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128Right(
+ bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+ bits64 z0, z1;
+ int8 negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1>>count );
+ z0 = a0>>count;
+ }
+ else {
+ z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
+number of bits given in `count'. If any nonzero bits are shifted off, they
+are ``jammed'' into the least significant bit of the result by setting the
+least significant bit to 1. The value of `count' can be arbitrarily large;
+in particular, if `count' is greater than 128, the result will be either 0
+or 1, depending on whether the concatenation of `a0' and `a1' is zero or
+nonzero. The result is broken into two 64-bit pieces which are stored at
+the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128RightJamming(
+ bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+ bits64 z0, z1;
+ int8 negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z1 = a1;
+ z0 = a0;
+ }
+ else if ( count < 64 ) {
+ z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z1 = a0 | ( a1 != 0 );
+ }
+ else if ( count < 128 ) {
+ z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
+ }
+ else {
+ z1 = ( ( a0 | a1 ) != 0 );
+ }
+ z0 = 0;
+ }
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
+by 64 _plus_ the number of bits given in `count'. The shifted result is
+at most 128 nonzero bits; these are broken into two 64-bit pieces which are
+stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
+off form a third 64-bit result as follows: The _last_ bit shifted off is
+the most-significant bit of the extra result, and the other 63 bits of the
+extra result are all zero if and only if _all_but_the_last_ bits shifted off
+were all zero. This extra result is stored in the location pointed to by
+`z2Ptr'. The value of `count' can be arbitrarily large.
+ (This routine makes more sense if `a0', `a1', and `a2' are considered
+to form a fixed-point value with binary point between `a1' and `a2'. This
+fixed-point value is shifted right by the number of bits given in `count',
+and the integer part of the result is returned at the locations pointed to
+by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
+corrupted as described above, and is returned at the location pointed to by
+`z2Ptr'.)
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shift128ExtraRightJamming(
+ bits64 a0,
+ bits64 a1,
+ bits64 a2,
+ int16 count,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr
+ )
+{
+ bits64 z0, z1, z2;
+ int8 negCount = ( - count ) & 63;
+
+ if ( count == 0 ) {
+ z2 = a2;
+ z1 = a1;
+ z0 = a0;
+ }
+ else {
+ if ( count < 64 ) {
+ z2 = a1<<negCount;
+ z1 = ( a0<<negCount ) | ( a1>>count );
+ z0 = a0>>count;
+ }
+ else {
+ if ( count == 64 ) {
+ z2 = a1;
+ z1 = a0;
+ }
+ else {
+ a2 |= a1;
+ if ( count < 128 ) {
+ z2 = a0<<negCount;
+ z1 = a0>>( count & 63 );
+ }
+ else {
+ z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
+ z1 = 0;
+ }
+ }
+ z0 = 0;
+ }
+ z2 |= ( a2 != 0 );
+ }
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
+number of bits given in `count'. Any bits shifted off are lost. The value
+of `count' must be less than 64. The result is broken into two 64-bit
+pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift128Left(
+ bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+
+ *z1Ptr = a1<<count;
+ *z0Ptr =
+ ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
+by the number of bits given in `count'. Any bits shifted off are lost.
+The value of `count' must be less than 64. The result is broken into three
+64-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ shortShift192Left(
+ bits64 a0,
+ bits64 a1,
+ bits64 a2,
+ int16 count,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr
+ )
+{
+ bits64 z0, z1, z2;
+ int8 negCount;
+
+ z2 = a2<<count;
+ z1 = a1<<count;
+ z0 = a0<<count;
+ if ( 0 < count ) {
+ negCount = ( ( - count ) & 63 );
+ z1 |= a2>>negCount;
+ z0 |= a1>>negCount;
+ }
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
+value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
+any carry out is lost. The result is broken into two 64-bit pieces which
+are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add128(
+ bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+ bits64 z1;
+
+ z1 = a1 + b1;
+ *z1Ptr = z1;
+ *z0Ptr = a0 + b0 + ( z1 < a1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
+192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
+modulo 2^192, so any carry out is lost. The result is broken into three
+64-bit pieces which are stored at the locations pointed to by `z0Ptr',
+`z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ add192(
+ bits64 a0,
+ bits64 a1,
+ bits64 a2,
+ bits64 b0,
+ bits64 b1,
+ bits64 b2,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr
+ )
+{
+ bits64 z0, z1, z2;
+ int8 carry0, carry1;
+
+ z2 = a2 + b2;
+ carry1 = ( z2 < a2 );
+ z1 = a1 + b1;
+ carry0 = ( z1 < a1 );
+ z0 = a0 + b0;
+ z1 += carry1;
+ z0 += ( z1 < carry1 );
+ z0 += carry0;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
+128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
+2^128, so any borrow out (carry out) is lost. The result is broken into two
+64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
+`z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub128(
+ bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+
+ *z1Ptr = a1 - b1;
+ *z0Ptr = a0 - b0 - ( a1 < b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
+from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
+Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
+result is broken into three 64-bit pieces which are stored at the locations
+pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ sub192(
+ bits64 a0,
+ bits64 a1,
+ bits64 a2,
+ bits64 b0,
+ bits64 b1,
+ bits64 b2,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr
+ )
+{
+ bits64 z0, z1, z2;
+ int8 borrow0, borrow1;
+
+ z2 = a2 - b2;
+ borrow1 = ( a2 < b2 );
+ z1 = a1 - b1;
+ borrow0 = ( a1 < b1 );
+ z0 = a0 - b0;
+ z0 -= ( z1 < borrow1 );
+ z1 -= borrow1;
+ z0 -= borrow0;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
+into two 64-bit pieces which are stored at the locations pointed to by
+`z0Ptr' and `z1Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+ bits32 aHigh, aLow, bHigh, bLow;
+ bits64 z0, zMiddleA, zMiddleB, z1;
+
+ aLow = a;
+ aHigh = a>>32;
+ bLow = b;
+ bHigh = b>>32;
+ z1 = ( (bits64) aLow ) * bLow;
+ zMiddleA = ( (bits64) aLow ) * bHigh;
+ zMiddleB = ( (bits64) aHigh ) * bLow;
+ z0 = ( (bits64) aHigh ) * bHigh;
+ zMiddleA += zMiddleB;
+ z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
+ zMiddleA <<= 32;
+ z1 += zMiddleA;
+ z0 += ( z1 < zMiddleA );
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 128-bit value formed by concatenating `a0' and `a1' by `b' to
+obtain a 192-bit product. The product is broken into three 64-bit pieces
+which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
+`z2Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul128By64To192(
+ bits64 a0,
+ bits64 a1,
+ bits64 b,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr
+ )
+{
+ bits64 z0, z1, z2, more1;
+
+ mul64To128( a1, b, &z1, &z2 );
+ mul64To128( a0, b, &z0, &more1 );
+ add128( z0, more1, 0, z1, &z0, &z1 );
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
+128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
+product. The product is broken into four 64-bit pieces which are stored at
+the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
+-------------------------------------------------------------------------------
+*/
+INLINE void
+ mul128To256(
+ bits64 a0,
+ bits64 a1,
+ bits64 b0,
+ bits64 b1,
+ bits64 *z0Ptr,
+ bits64 *z1Ptr,
+ bits64 *z2Ptr,
+ bits64 *z3Ptr
+ )
+{
+ bits64 z0, z1, z2, z3;
+ bits64 more1, more2;
+
+ mul64To128( a1, b1, &z2, &z3 );
+ mul64To128( a1, b0, &z1, &more2 );
+ add128( z1, more2, 0, z2, &z1, &z2 );
+ mul64To128( a0, b0, &z0, &more1 );
+ add128( z0, more1, 0, z1, &z0, &z1 );
+ mul64To128( a0, b1, &more1, &more2 );
+ add128( more1, more2, 0, z2, &more1, &z2 );
+ add128( z0, z1, 0, more1, &z0, &z1 );
+ *z3Ptr = z3;
+ *z2Ptr = z2;
+ *z1Ptr = z1;
+ *z0Ptr = z0;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the 64-bit integer quotient obtained by dividing
+`b' into the 128-bit value formed by concatenating `a0' and `a1'. The
+divisor `b' must be at least 2^63. If q is the exact quotient truncated
+toward zero, the approximation returned lies between q and q + 2 inclusive.
+If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
+unsigned integer is returned.
+-------------------------------------------------------------------------------
+*/
+static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
+{
+ bits64 b0, b1;
+ bits64 rem0, rem1, term0, term1;
+ bits64 z;
+ if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+ b0 = b>>32; /* hence b0 is 32 bits wide now */
+ if ( b0<<32 <= a0 ) {
+ z = LIT64( 0xFFFFFFFF00000000 );
+ } else {
+ z = a0;
+ do_div( z, b0 );
+ z <<= 32;
+ }
+ mul64To128( b, z, &term0, &term1 );
+ sub128( a0, a1, term0, term1, &rem0, &rem1 );
+ while ( ( (sbits64) rem0 ) < 0 ) {
+ z -= LIT64( 0x100000000 );
+ b1 = b<<32;
+ add128( rem0, rem1, b0, b1, &rem0, &rem1 );
+ }
+ rem0 = ( rem0<<32 ) | ( rem1>>32 );
+ if ( b0<<32 <= rem0 ) {
+ z |= 0xFFFFFFFF;
+ } else {
+ do_div( rem0, b0 );
+ z |= rem0;
+ }
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns an approximation to the square root of the 32-bit significand given
+by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
+`aExp' (the least significant bit) is 1, the integer returned approximates
+2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
+is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
+case, the approximation returned lies strictly within +/-2 of the exact
+value.
+-------------------------------------------------------------------------------
+*/
+static bits32 estimateSqrt32( int16 aExp, bits32 a )
+{
+ static const bits16 sqrtOddAdjustments[] = {
+ 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
+ 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
+ };
+ static const bits16 sqrtEvenAdjustments[] = {
+ 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
+ 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
+ };
+ int8 index;
+ bits32 z;
+ bits64 A;
+
+ index = ( a>>27 ) & 15;
+ if ( aExp & 1 ) {
+ z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
+ z = ( ( a / z )<<14 ) + ( z<<15 );
+ a >>= 1;
+ }
+ else {
+ z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
+ z = a / z + z;
+ z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
+ if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
+ }
+ A = ( (bits64) a )<<31;
+ do_div( A, z );
+ return ( (bits32) A ) + ( z>>1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the number of leading 0 bits before the most-significant 1 bit
+of `a'. If `a' is zero, 32 is returned.
+-------------------------------------------------------------------------------
+*/
+static int8 countLeadingZeros32( bits32 a )
+{
+ static const int8 countLeadingZerosHigh[] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ int8 shiftCount;
+
+ shiftCount = 0;
+ if ( a < 0x10000 ) {
+ shiftCount += 16;
+ a <<= 16;
+ }
+ if ( a < 0x1000000 ) {
+ shiftCount += 8;
+ a <<= 8;
+ }
+ shiftCount += countLeadingZerosHigh[ a>>24 ];
+ return shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the number of leading 0 bits before the most-significant 1 bit
+of `a'. If `a' is zero, 64 is returned.
+-------------------------------------------------------------------------------
+*/
+static int8 countLeadingZeros64( bits64 a )
+{
+ int8 shiftCount;
+
+ shiftCount = 0;
+ if ( a < ( (bits64) 1 )<<32 ) {
+ shiftCount += 32;
+ }
+ else {
+ a >>= 32;
+ }
+ shiftCount += countLeadingZeros32( a );
+ return shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
+is equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+ return ( a0 == b0 ) && ( a1 == b1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+ return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
+than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
+returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+ return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
+not equal to the 128-bit value formed by concatenating `b0' and `b1'.
+Otherwise, returns 0.
+-------------------------------------------------------------------------------
+*/
+INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
+{
+
+ return ( a0 != b0 ) || ( a1 != b1 );
+
+}
+
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
new file mode 100644
index 00000000..679a0269
--- /dev/null
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -0,0 +1,367 @@
+
+/*
+===============================================================================
+
+This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Underflow tininess-detection mode, statically initialized to default value.
+(The declaration in `softfloat.h' must match the `int8' type here.)
+-------------------------------------------------------------------------------
+*/
+int8 float_detect_tininess = float_tininess_after_rounding;
+
+/*
+-------------------------------------------------------------------------------
+Raises the exceptions specified by `flags'. Floating-point traps can be
+defined here if desired. It is currently not possible for such a trap to
+substitute a result value. If traps are not implemented, this routine
+should be simply `float_exception_flags |= flags;'.
+
+ScottB: November 4, 1998
+Moved this function out of softfloat-specialize into fpmodule.c.
+This effectively isolates all the changes required for integrating with the
+Linux kernel into fpmodule.c. Porting to NetBSD should only require modifying
+fpmodule.c to integrate with the NetBSD kernel (I hope!).
+-------------------------------------------------------------------------------
+void float_raise( int8 flags )
+{
+ float_exception_flags |= flags;
+}
+*/
+
+/*
+-------------------------------------------------------------------------------
+Internal canonical NaN format.
+-------------------------------------------------------------------------------
+*/
+typedef struct {
+ flag sign;
+ bits64 high, low;
+} commonNaNT;
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated single-precision NaN.
+-------------------------------------------------------------------------------
+*/
+#define float32_default_nan 0xFFFFFFFF
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_nan( float32 a )
+{
+
+ return ( 0xFF000000 < (bits32) ( a<<1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is a signaling
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float32_is_signaling_nan( float32 a )
+{
+
+ return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point NaN
+`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
+exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT float32ToCommonNaN( float32 a )
+{
+ commonNaNT z;
+
+ if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a>>31;
+ z.low = 0;
+ z.high = ( (bits64) a )<<41;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the single-
+precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static float32 commonNaNToFloat32( commonNaNT a )
+{
+
+ return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two single-precision floating-point values `a' and `b', one of which
+is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
+signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float32 propagateFloat32NaN( float32 a, float32 b )
+{
+ flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+ aIsNaN = float32_is_nan( a );
+ aIsSignalingNaN = float32_is_signaling_nan( a );
+ bIsNaN = float32_is_nan( b );
+ bIsSignalingNaN = float32_is_signaling_nan( b );
+ a |= 0x00400000;
+ b |= 0x00400000;
+ if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+ if ( aIsNaN ) {
+ return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+ }
+ else {
+ return b;
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated double-precision NaN.
+-------------------------------------------------------------------------------
+*/
+#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is a NaN;
+otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float64_is_nan( float64 a )
+{
+
+ return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is a signaling
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag float64_is_signaling_nan( float64 a )
+{
+
+ return
+ ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+ && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point NaN
+`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
+exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT float64ToCommonNaN( float64 a )
+{
+ commonNaNT z;
+
+ if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a>>63;
+ z.low = 0;
+ z.high = a<<12;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the double-
+precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static float64 commonNaNToFloat64( commonNaNT a )
+{
+
+ return
+ ( ( (bits64) a.sign )<<63 )
+ | LIT64( 0x7FF8000000000000 )
+ | ( a.high>>12 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two double-precision floating-point values `a' and `b', one of which
+is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
+signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static float64 propagateFloat64NaN( float64 a, float64 b )
+{
+ flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+ aIsNaN = float64_is_nan( a );
+ aIsSignalingNaN = float64_is_signaling_nan( a );
+ bIsNaN = float64_is_nan( b );
+ bIsSignalingNaN = float64_is_signaling_nan( b );
+ a |= LIT64( 0x0008000000000000 );
+ b |= LIT64( 0x0008000000000000 );
+ if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+ if ( aIsNaN ) {
+ return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+ }
+ else {
+ return b;
+ }
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+The pattern for a default generated extended double-precision NaN. The
+`high' and `low' values hold the most- and least-significant bits,
+respectively.
+-------------------------------------------------------------------------------
+*/
+#define floatx80_default_nan_high 0xFFFF
+#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is a
+NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_is_nan( floatx80 a )
+{
+
+ return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is a
+signaling NaN; otherwise returns 0.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_is_signaling_nan( floatx80 a )
+{
+ //register int lr;
+ bits64 aLow;
+
+ //__asm__("mov %0, lr" : : "g" (lr));
+ //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
+ aLow = a.low & ~ LIT64( 0x4000000000000000 );
+ return
+ ( ( a.high & 0x7FFF ) == 0x7FFF )
+ && (bits64) ( aLow<<1 )
+ && ( a.low == aLow );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
+invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static commonNaNT floatx80ToCommonNaN( floatx80 a )
+{
+ commonNaNT z;
+
+ if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
+ z.sign = a.high>>15;
+ z.low = 0;
+ z.high = a.low<<1;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the canonical NaN `a' to the extended
+double-precision floating-point format.
+-------------------------------------------------------------------------------
+*/
+static floatx80 commonNaNToFloatx80( commonNaNT a )
+{
+ floatx80 z;
+
+ z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
+ z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
+ z.__padding = 0;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes two extended double-precision floating-point values `a' and `b', one
+of which is a NaN, and returns the appropriate NaN result. If either `a' or
+`b' is a signaling NaN, the invalid exception is raised.
+-------------------------------------------------------------------------------
+*/
+static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
+{
+ flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
+
+ aIsNaN = floatx80_is_nan( a );
+ aIsSignalingNaN = floatx80_is_signaling_nan( a );
+ bIsNaN = floatx80_is_nan( b );
+ bIsSignalingNaN = floatx80_is_signaling_nan( b );
+ a.low |= LIT64( 0xC000000000000000 );
+ b.low |= LIT64( 0xC000000000000000 );
+ if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
+ if ( aIsNaN ) {
+ return ( aIsSignalingNaN & bIsNaN ) ? b : a;
+ }
+ else {
+ return b;
+ }
+
+}
+
+#endif
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
new file mode 100644
index 00000000..ffa6b438
--- /dev/null
+++ b/arch/arm/nwfpe/softfloat.c
@@ -0,0 +1,3435 @@
+/*
+===============================================================================
+
+This C source file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include <asm/div64.h>
+
+#include "fpa11.h"
+//#include "milieu.h"
+//#include "softfloat.h"
+
+/*
+-------------------------------------------------------------------------------
+Primitive arithmetic functions, including multi-word arithmetic, and
+division and square root approximations. (Can be specialized to target if
+desired.)
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-macros"
+
+/*
+-------------------------------------------------------------------------------
+Functions and definitions to determine: (1) whether tininess for underflow
+is detected before or after rounding by default, (2) what (if anything)
+happens when exceptions are raised, (3) how signaling NaNs are distinguished
+from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
+are propagated from function inputs to output. These details are target-
+specific.
+-------------------------------------------------------------------------------
+*/
+#include "softfloat-specialize"
+
+/*
+-------------------------------------------------------------------------------
+Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
+and 7, and returns the properly rounded 32-bit integer corresponding to the
+input. If `zSign' is nonzero, the input is negated before being converted
+to an integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point
+input is simply rounded to an integer, with the inexact exception raised if
+the input cannot be represented exactly as an integer. If the fixed-point
+input is too large, however, the invalid exception is raised and the largest
+positive or negative integer is returned.
+-------------------------------------------------------------------------------
+*/
+static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
+{
+ int8 roundingMode;
+ flag roundNearestEven;
+ int8 roundIncrement, roundBits;
+ int32 z;
+
+ roundingMode = roundData->mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x40;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x7F;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = absZ & 0x7F;
+ absZ = ( absZ + roundIncrement )>>7;
+ absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+ z = absZ;
+ if ( zSign ) z = - z;
+ if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
+ roundData->exception |= float_flag_invalid;
+ return zSign ? 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( roundBits ) roundData->exception |= float_flag_inexact;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits32 extractFloat32Frac( float32 a )
+{
+
+ return a & 0x007FFFFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int16 extractFloat32Exp( float32 a )
+{
+
+ return ( a>>23 ) & 0xFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the single-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+#if 0 /* in softfloat.h */
+INLINE flag extractFloat32Sign( float32 a )
+{
+
+ return a>>31;
+
+}
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal single-precision floating-point value represented
+by the denormalized significand `aSig'. The normalized exponent and
+significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
+{
+ int8 shiftCount;
+
+ shiftCount = countLeadingZeros32( aSig ) - 8;
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+single-precision floating-point value, returning the result. After being
+shifted into the proper positions, the three fields are simply added
+together to form the result. This means that any integer portion of `zSig'
+will be added into the exponent. Since a properly normalized significand
+will have an integer portion equal to 1, the `zExp' input should be 1 less
+than the desired result exponent whenever `zSig' is a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
+{
+#if 0
+ float32 f;
+ __asm__("@ packFloat32 \n\
+ mov %0, %1, asl #31 \n\
+ orr %0, %2, asl #23 \n\
+ orr %0, %3"
+ : /* no outputs */
+ : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
+ : "cc");
+ return f;
+#else
+ return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
+#endif
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input. Ordinarily, the abstract
+value is simply rounded and packed into the single-precision format, with
+the inexact exception raised if the abstract input cannot be represented
+exactly. If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned. If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal single-
+precision floating-point number.
+ The input significand `zSig' has its binary point between bits 30
+and 29, which is 7 bits to the left of the usual location. This shifted
+significand must be normalized or smaller. If `zSig' is not normalized,
+`zExp' must be 0; in that case, the result returned is a subnormal number,
+and it must not require rounding. In the usual case that `zSig' is
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+The handling of underflow and overflow follows the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
+{
+ int8 roundingMode;
+ flag roundNearestEven;
+ int8 roundIncrement, roundBits;
+ flag isTiny;
+
+ roundingMode = roundData->mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x40;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x7F;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig & 0x7F;
+ if ( 0xFD <= (bits16) zExp ) {
+ if ( ( 0xFD < zExp )
+ || ( ( zExp == 0xFD )
+ && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
+ ) {
+ roundData->exception |= float_flag_overflow | float_flag_inexact;
+ return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
+ }
+ if ( zExp < 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < -1 )
+ || ( zSig + roundIncrement < 0x80000000 );
+ shift32RightJamming( zSig, - zExp, &zSig );
+ zExp = 0;
+ roundBits = zSig & 0x7F;
+ if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
+ }
+ }
+ if ( roundBits ) roundData->exception |= float_flag_inexact;
+ zSig = ( zSig + roundIncrement )>>7;
+ zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
+ if ( zSig == 0 ) zExp = 0;
+ return packFloat32( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper single-precision floating-
+point value corresponding to the abstract input. This routine is just like
+`roundAndPackFloat32' except that `zSig' does not have to be normalized in
+any way. In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float32
+ normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
+{
+ int8 shiftCount;
+
+ shiftCount = countLeadingZeros32( zSig ) - 1;
+ return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloat64Frac( float64 a )
+{
+
+ return a & LIT64( 0x000FFFFFFFFFFFFF );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int16 extractFloat64Exp( float64 a )
+{
+
+ return ( a>>52 ) & 0x7FF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the double-precision floating-point value `a'.
+-------------------------------------------------------------------------------
+*/
+#if 0 /* in softfloat.h */
+INLINE flag extractFloat64Sign( float64 a )
+{
+
+ return a>>63;
+
+}
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal double-precision floating-point value represented
+by the denormalized significand `aSig'. The normalized exponent and
+significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
+{
+ int8 shiftCount;
+
+ shiftCount = countLeadingZeros64( aSig ) - 11;
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
+double-precision floating-point value, returning the result. After being
+shifted into the proper positions, the three fields are simply added
+together to form the result. This means that any integer portion of `zSig'
+will be added into the exponent. Since a properly normalized significand
+will have an integer portion equal to 1, the `zExp' input should be 1 less
+than the desired result exponent whenever `zSig' is a complete, normalized
+significand.
+-------------------------------------------------------------------------------
+*/
+INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
+{
+
+ return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper double-precision floating-
+point value corresponding to the abstract input. Ordinarily, the abstract
+value is simply rounded and packed into the double-precision format, with
+the inexact exception raised if the abstract input cannot be represented
+exactly. If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned. If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal double-
+precision floating-point number.
+ The input significand `zSig' has its binary point between bits 62
+and 61, which is 10 bits to the left of the usual location. This shifted
+significand must be normalized or smaller. If `zSig' is not normalized,
+`zExp' must be 0; in that case, the result returned is a subnormal number,
+and it must not require rounding. In the usual case that `zSig' is
+normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
+The handling of underflow and overflow follows the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
+{
+ int8 roundingMode;
+ flag roundNearestEven;
+ int16 roundIncrement, roundBits;
+ flag isTiny;
+
+ roundingMode = roundData->mode;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ roundIncrement = 0x200;
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = 0x3FF;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig & 0x3FF;
+ if ( 0x7FD <= (bits16) zExp ) {
+ if ( ( 0x7FD < zExp )
+ || ( ( zExp == 0x7FD )
+ && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
+ ) {
+ //register int lr = __builtin_return_address(0);
+ //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
+ roundData->exception |= float_flag_overflow | float_flag_inexact;
+ return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
+ }
+ if ( zExp < 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < -1 )
+ || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
+ shift64RightJamming( zSig, - zExp, &zSig );
+ zExp = 0;
+ roundBits = zSig & 0x3FF;
+ if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
+ }
+ }
+ if ( roundBits ) roundData->exception |= float_flag_inexact;
+ zSig = ( zSig + roundIncrement )>>10;
+ zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
+ if ( zSig == 0 ) zExp = 0;
+ return packFloat64( zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and significand `zSig', and returns the proper double-precision floating-
+point value corresponding to the abstract input. This routine is just like
+`roundAndPackFloat64' except that `zSig' does not have to be normalized in
+any way. In all cases, `zExp' must be 1 less than the ``true'' floating-
+point exponent.
+-------------------------------------------------------------------------------
+*/
+static float64
+ normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
+{
+ int8 shiftCount;
+
+ shiftCount = countLeadingZeros64( zSig ) - 1;
+ return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the fraction bits of the extended double-precision floating-point
+value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE bits64 extractFloatx80Frac( floatx80 a )
+{
+
+ return a.low;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the exponent bits of the extended double-precision floating-point
+value `a'.
+-------------------------------------------------------------------------------
+*/
+INLINE int32 extractFloatx80Exp( floatx80 a )
+{
+
+ return a.high & 0x7FFF;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the sign bit of the extended double-precision floating-point value
+`a'.
+-------------------------------------------------------------------------------
+*/
+INLINE flag extractFloatx80Sign( floatx80 a )
+{
+
+ return a.high>>15;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Normalizes the subnormal extended double-precision floating-point value
+represented by the denormalized significand `aSig'. The normalized exponent
+and significand are stored at the locations pointed to by `zExpPtr' and
+`zSigPtr', respectively.
+-------------------------------------------------------------------------------
+*/
+static void
+ normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
+{
+ int8 shiftCount;
+
+ shiftCount = countLeadingZeros64( aSig );
+ *zSigPtr = aSig<<shiftCount;
+ *zExpPtr = 1 - shiftCount;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
+extended double-precision floating-point value, returning the result.
+-------------------------------------------------------------------------------
+*/
+INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
+{
+ floatx80 z;
+
+ z.low = zSig;
+ z.high = ( ( (bits16) zSign )<<15 ) + zExp;
+ z.__padding = 0;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent `zExp',
+and extended significand formed by the concatenation of `zSig0' and `zSig1',
+and returns the proper extended double-precision floating-point value
+corresponding to the abstract input. Ordinarily, the abstract value is
+rounded and packed into the extended double-precision format, with the
+inexact exception raised if the abstract input cannot be represented
+exactly. If the abstract value is too large, however, the overflow and
+inexact exceptions are raised and an infinity or maximal finite value is
+returned. If the abstract value is too small, the input value is rounded to
+a subnormal number, and the underflow and inexact exceptions are raised if
+the abstract input cannot be represented exactly as a subnormal extended
+double-precision floating-point number.
+ If `roundingPrecision' is 32 or 64, the result is rounded to the same
+number of bits as single or double precision, respectively. Otherwise, the
+result is rounded to the full precision of the extended double-precision
+format.
+ The input significand must be normalized or smaller. If the input
+significand is not normalized, `zExp' must be 0; in that case, the result
+returned is a subnormal number, and it must not require rounding. The
+handling of underflow and overflow follows the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80
+ roundAndPackFloatx80(
+ struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+ )
+{
+ int8 roundingMode, roundingPrecision;
+ flag roundNearestEven, increment, isTiny;
+ int64 roundIncrement, roundMask, roundBits;
+
+ roundingMode = roundData->mode;
+ roundingPrecision = roundData->precision;
+ roundNearestEven = ( roundingMode == float_round_nearest_even );
+ if ( roundingPrecision == 80 ) goto precision80;
+ if ( roundingPrecision == 64 ) {
+ roundIncrement = LIT64( 0x0000000000000400 );
+ roundMask = LIT64( 0x00000000000007FF );
+ }
+ else if ( roundingPrecision == 32 ) {
+ roundIncrement = LIT64( 0x0000008000000000 );
+ roundMask = LIT64( 0x000000FFFFFFFFFF );
+ }
+ else {
+ goto precision80;
+ }
+ zSig0 |= ( zSig1 != 0 );
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ roundIncrement = 0;
+ }
+ else {
+ roundIncrement = roundMask;
+ if ( zSign ) {
+ if ( roundingMode == float_round_up ) roundIncrement = 0;
+ }
+ else {
+ if ( roundingMode == float_round_down ) roundIncrement = 0;
+ }
+ }
+ }
+ roundBits = zSig0 & roundMask;
+ if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
+ if ( ( 0x7FFE < zExp )
+ || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
+ ) {
+ goto overflow;
+ }
+ if ( zExp <= 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < 0 )
+ || ( zSig0 <= zSig0 + roundIncrement );
+ shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
+ zExp = 0;
+ roundBits = zSig0 & roundMask;
+ if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
+ if ( roundBits ) roundData->exception |= float_flag_inexact;
+ zSig0 += roundIncrement;
+ if ( (sbits64) zSig0 < 0 ) zExp = 1;
+ roundIncrement = roundMask + 1;
+ if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+ roundMask |= roundIncrement;
+ }
+ zSig0 &= ~ roundMask;
+ return packFloatx80( zSign, zExp, zSig0 );
+ }
+ }
+ if ( roundBits ) roundData->exception |= float_flag_inexact;
+ zSig0 += roundIncrement;
+ if ( zSig0 < roundIncrement ) {
+ ++zExp;
+ zSig0 = LIT64( 0x8000000000000000 );
+ }
+ roundIncrement = roundMask + 1;
+ if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
+ roundMask |= roundIncrement;
+ }
+ zSig0 &= ~ roundMask;
+ if ( zSig0 == 0 ) zExp = 0;
+ return packFloatx80( zSign, zExp, zSig0 );
+ precision80:
+ increment = ( (sbits64) zSig1 < 0 );
+ if ( ! roundNearestEven ) {
+ if ( roundingMode == float_round_to_zero ) {
+ increment = 0;
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig1;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig1;
+ }
+ }
+ }
+ if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
+ if ( ( 0x7FFE < zExp )
+ || ( ( zExp == 0x7FFE )
+ && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
+ && increment
+ )
+ ) {
+ roundMask = 0;
+ overflow:
+ roundData->exception |= float_flag_overflow | float_flag_inexact;
+ if ( ( roundingMode == float_round_to_zero )
+ || ( zSign && ( roundingMode == float_round_up ) )
+ || ( ! zSign && ( roundingMode == float_round_down ) )
+ ) {
+ return packFloatx80( zSign, 0x7FFE, ~ roundMask );
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( zExp <= 0 ) {
+ isTiny =
+ ( float_detect_tininess == float_tininess_before_rounding )
+ || ( zExp < 0 )
+ || ! increment
+ || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
+ shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
+ zExp = 0;
+ if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow;
+ if ( zSig1 ) roundData->exception |= float_flag_inexact;
+ if ( roundNearestEven ) {
+ increment = ( (sbits64) zSig1 < 0 );
+ }
+ else {
+ if ( zSign ) {
+ increment = ( roundingMode == float_round_down ) && zSig1;
+ }
+ else {
+ increment = ( roundingMode == float_round_up ) && zSig1;
+ }
+ }
+ if ( increment ) {
+ ++zSig0;
+ zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
+ if ( (sbits64) zSig0 < 0 ) zExp = 1;
+ }
+ return packFloatx80( zSign, zExp, zSig0 );
+ }
+ }
+ if ( zSig1 ) roundData->exception |= float_flag_inexact;
+ if ( increment ) {
+ ++zSig0;
+ if ( zSig0 == 0 ) {
+ ++zExp;
+ zSig0 = LIT64( 0x8000000000000000 );
+ }
+ else {
+ zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
+ }
+ }
+ else {
+ if ( zSig0 == 0 ) zExp = 0;
+ }
+
+ return packFloatx80( zSign, zExp, zSig0 );
+}
+
+/*
+-------------------------------------------------------------------------------
+Takes an abstract floating-point value having sign `zSign', exponent
+`zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
+and returns the proper extended double-precision floating-point value
+corresponding to the abstract input. This routine is just like
+`roundAndPackFloatx80' except that the input significand does not have to be
+normalized.
+-------------------------------------------------------------------------------
+*/
+static floatx80
+ normalizeRoundAndPackFloatx80(
+ struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
+ )
+{
+ int8 shiftCount;
+
+ if ( zSig0 == 0 ) {
+ zSig0 = zSig1;
+ zSig1 = 0;
+ zExp -= 64;
+ }
+ shiftCount = countLeadingZeros64( zSig0 );
+ shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
+ zExp -= shiftCount;
+ return
+ roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the single-precision floating-point format. The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32(struct roundingData *roundData, int32 a)
+{
+ flag zSign;
+
+ if ( a == 0 ) return 0;
+ if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
+ zSign = ( a < 0 );
+ return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a' to
+the double-precision floating-point format. The conversion is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 int32_to_float64( int32 a )
+{
+ flag aSign;
+ uint32 absA;
+ int8 shiftCount;
+ bits64 zSig;
+
+ if ( a == 0 ) return 0;
+ aSign = ( a < 0 );
+ absA = aSign ? - a : a;
+ shiftCount = countLeadingZeros32( absA ) + 21;
+ zSig = absA;
+ return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the 32-bit two's complement integer `a'
+to the extended double-precision floating-point format. The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 int32_to_floatx80( int32 a )
+{
+ flag zSign;
+ uint32 absA;
+ int8 shiftCount;
+ bits64 zSig;
+
+ if ( a == 0 ) return packFloatx80( 0, 0, 0 );
+ zSign = ( a < 0 );
+ absA = zSign ? - a : a;
+ shiftCount = countLeadingZeros32( absA ) + 32;
+ zSig = absA;
+ return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode. If `a' is a NaN, the largest
+positive integer is returned. Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32( struct roundingData *roundData, float32 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits32 aSig;
+ bits64 zSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+ if ( aExp ) aSig |= 0x00800000;
+ shiftCount = 0xAF - aExp;
+ zSig = aSig;
+ zSig <<= 32;
+ if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
+ return roundAndPackInt32( roundData, aSign, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the 32-bit two's complement integer format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero. If
+`a' is a NaN, the largest positive integer is returned. Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float32_to_int32_round_to_zero( float32 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits32 aSig;
+ int32 z;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ shiftCount = aExp - 0x9E;
+ if ( 0 <= shiftCount ) {
+ if ( a == 0xCF000000 ) return 0x80000000;
+ float_raise( float_flag_invalid );
+ if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
+ return 0x80000000;
+ }
+ else if ( aExp <= 0x7E ) {
+ if ( aExp | aSig ) float_raise( float_flag_inexact );
+ return 0;
+ }
+ aSig = ( aSig | 0x00800000 )<<8;
+ z = aSig>>( - shiftCount );
+ if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
+ float_raise( float_flag_inexact );
+ }
+ return aSign ? - z : z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the double-precision floating-point format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float32_to_float64( float32 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits32 aSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
+ return packFloat64( aSign, 0x7FF, 0 );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ --aExp;
+ }
+ return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the single-precision floating-point value
+`a' to the extended double-precision floating-point format. The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 float32_to_floatx80( float32 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits32 aSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
+ return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ aSig |= 0x00800000;
+ return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the single-precision floating-point value `a' to an integer, and
+returns the result as a single-precision floating-point value. The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( struct roundingData *roundData, float32 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits32 lastBitMask, roundBitsMask;
+ int8 roundingMode;
+ float32 z;
+
+ aExp = extractFloat32Exp( a );
+ if ( 0x96 <= aExp ) {
+ if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
+ return propagateFloat32NaN( a, a );
+ }
+ return a;
+ }
+ roundingMode = roundData->mode;
+ if ( aExp <= 0x7E ) {
+ if ( (bits32) ( a<<1 ) == 0 ) return a;
+ roundData->exception |= float_flag_inexact;
+ aSign = extractFloat32Sign( a );
+ switch ( roundingMode ) {
+ case float_round_nearest_even:
+ if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
+ return packFloat32( aSign, 0x7F, 0 );
+ }
+ break;
+ case float_round_down:
+ return aSign ? 0xBF800000 : 0;
+ case float_round_up:
+ return aSign ? 0x80000000 : 0x3F800000;
+ }
+ return packFloat32( aSign, 0, 0 );
+ }
+ lastBitMask = 1;
+ lastBitMask <<= 0x96 - aExp;
+ roundBitsMask = lastBitMask - 1;
+ z = a;
+ if ( roundingMode == float_round_nearest_even ) {
+ z += lastBitMask>>1;
+ if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
+ }
+ else if ( roundingMode != float_round_to_zero ) {
+ if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+ z += roundBitsMask;
+ }
+ }
+ z &= ~ roundBitsMask;
+ if ( z != a ) roundData->exception |= float_flag_inexact;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the single-precision
+floating-point values `a' and `b'. If `zSign' is true, the sum is negated
+before being returned. `zSign' is ignored if the result is a NaN. The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
+{
+ int16 aExp, bExp, zExp;
+ bits32 aSig, bSig, zSig;
+ int16 expDiff;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ bSig = extractFloat32Frac( b );
+ bExp = extractFloat32Exp( b );
+ expDiff = aExp - bExp;
+ aSig <<= 6;
+ bSig <<= 6;
+ if ( 0 < expDiff ) {
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return propagateFloat32NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig |= 0x20000000;
+ }
+ shift32RightJamming( bSig, expDiff, &bSig );
+ zExp = aExp;
+ }
+ else if ( expDiff < 0 ) {
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ return packFloat32( zSign, 0xFF, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig |= 0x20000000;
+ }
+ shift32RightJamming( aSig, - expDiff, &aSig );
+ zExp = bExp;
+ }
+ else {
+ if ( aExp == 0xFF ) {
+ if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+ return a;
+ }
+ if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
+ zSig = 0x40000000 + aSig + bSig;
+ zExp = aExp;
+ goto roundAndPack;
+ }
+ aSig |= 0x20000000;
+ zSig = ( aSig + bSig )<<1;
+ --zExp;
+ if ( (sbits32) zSig < 0 ) {
+ zSig = aSig + bSig;
+ ++zExp;
+ }
+ roundAndPack:
+ return roundAndPackFloat32( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the single-
+precision floating-point values `a' and `b'. If `zSign' is true, the
+difference is negated before being returned. `zSign' is ignored if the
+result is a NaN. The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
+{
+ int16 aExp, bExp, zExp;
+ bits32 aSig, bSig, zSig;
+ int16 expDiff;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ bSig = extractFloat32Frac( b );
+ bExp = extractFloat32Exp( b );
+ expDiff = aExp - bExp;
+ aSig <<= 7;
+ bSig <<= 7;
+ if ( 0 < expDiff ) goto aExpBigger;
+ if ( expDiff < 0 ) goto bExpBigger;
+ if ( aExp == 0xFF ) {
+ if ( aSig | bSig ) return propagateFloat32NaN( a, b );
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ if ( aExp == 0 ) {
+ aExp = 1;
+ bExp = 1;
+ }
+ if ( bSig < aSig ) goto aBigger;
+ if ( aSig < bSig ) goto bBigger;
+ return packFloat32( roundData->mode == float_round_down, 0, 0 );
+ bExpBigger:
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ return packFloat32( zSign ^ 1, 0xFF, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig |= 0x40000000;
+ }
+ shift32RightJamming( aSig, - expDiff, &aSig );
+ bSig |= 0x40000000;
+ bBigger:
+ zSig = bSig - aSig;
+ zExp = bExp;
+ zSign ^= 1;
+ goto normalizeRoundAndPack;
+ aExpBigger:
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return propagateFloat32NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig |= 0x40000000;
+ }
+ shift32RightJamming( bSig, expDiff, &bSig );
+ aSig |= 0x40000000;
+ aBigger:
+ zSig = aSig - bSig;
+ zExp = aExp;
+ normalizeRoundAndPack:
+ --zExp;
+ return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the single-precision floating-point values `a'
+and `b'. The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign == bSign ) {
+ return addFloat32Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return subFloat32Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the single-precision floating-point values
+`a' and `b'. The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign == bSign ) {
+ return subFloat32Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return addFloat32Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the single-precision floating-point values
+`a' and `b'. The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, zExp;
+ bits32 aSig, bSig;
+ bits64 zSig64;
+ bits32 zSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ bSig = extractFloat32Frac( b );
+ bExp = extractFloat32Exp( b );
+ bSign = extractFloat32Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0xFF ) {
+ if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
+ return propagateFloat32NaN( a, b );
+ }
+ if ( ( bExp | bSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ return packFloat32( zSign, 0xFF, 0 );
+ }
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ if ( ( aExp | aSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ return packFloat32( zSign, 0xFF, 0 );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
+ normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+ }
+ zExp = aExp + bExp - 0x7F;
+ aSig = ( aSig | 0x00800000 )<<7;
+ bSig = ( bSig | 0x00800000 )<<8;
+ shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
+ zSig = zSig64;
+ if ( 0 <= (sbits32) ( zSig<<1 ) ) {
+ zSig <<= 1;
+ --zExp;
+ }
+ return roundAndPackFloat32( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the single-precision floating-point value `a'
+by the corresponding value `b'. The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, zExp;
+ bits32 aSig, bSig, zSig;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ bSig = extractFloat32Frac( b );
+ bExp = extractFloat32Exp( b );
+ bSign = extractFloat32Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return propagateFloat32NaN( a, b );
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ return packFloat32( zSign, 0xFF, 0 );
+ }
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ return packFloat32( zSign, 0, 0 );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ if ( ( aExp | aSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ roundData->exception |= float_flag_divbyzero;
+ return packFloat32( zSign, 0xFF, 0 );
+ }
+ normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ zExp = aExp - bExp + 0x7D;
+ aSig = ( aSig | 0x00800000 )<<7;
+ bSig = ( bSig | 0x00800000 )<<8;
+ if ( bSig <= ( aSig + aSig ) ) {
+ aSig >>= 1;
+ ++zExp;
+ }
+ {
+ bits64 tmp = ( (bits64) aSig )<<32;
+ do_div( tmp, bSig );
+ zSig = tmp;
+ }
+ if ( ( zSig & 0x3F ) == 0 ) {
+ zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
+ }
+ return roundAndPackFloat32( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the single-precision floating-point value `a'
+with respect to the corresponding value `b'. The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, expDiff;
+ bits32 aSig, bSig;
+ bits32 q;
+ bits64 aSig64, bSig64, q64;
+ bits32 alternateASig;
+ sbits32 sigMean;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ bSig = extractFloat32Frac( b );
+ bExp = extractFloat32Exp( b );
+ bSign = extractFloat32Sign( b );
+ if ( aExp == 0xFF ) {
+ if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
+ return propagateFloat32NaN( a, b );
+ }
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ if ( bExp == 0xFF ) {
+ if ( bSig ) return propagateFloat32NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ normalizeFloat32Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return a;
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ expDiff = aExp - bExp;
+ aSig |= 0x00800000;
+ bSig |= 0x00800000;
+ if ( expDiff < 32 ) {
+ aSig <<= 8;
+ bSig <<= 8;
+ if ( expDiff < 0 ) {
+ if ( expDiff < -1 ) return a;
+ aSig >>= 1;
+ }
+ q = ( bSig <= aSig );
+ if ( q ) aSig -= bSig;
+ if ( 0 < expDiff ) {
+ bits64 tmp = ( (bits64) aSig )<<32;
+ do_div( tmp, bSig );
+ q = tmp;
+ q >>= 32 - expDiff;
+ bSig >>= 2;
+ aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
+ }
+ else {
+ aSig >>= 2;
+ bSig >>= 2;
+ }
+ }
+ else {
+ if ( bSig <= aSig ) aSig -= bSig;
+ aSig64 = ( (bits64) aSig )<<40;
+ bSig64 = ( (bits64) bSig )<<40;
+ expDiff -= 64;
+ while ( 0 < expDiff ) {
+ q64 = estimateDiv128To64( aSig64, 0, bSig64 );
+ q64 = ( 2 < q64 ) ? q64 - 2 : 0;
+ aSig64 = - ( ( bSig * q64 )<<38 );
+ expDiff -= 62;
+ }
+ expDiff += 64;
+ q64 = estimateDiv128To64( aSig64, 0, bSig64 );
+ q64 = ( 2 < q64 ) ? q64 - 2 : 0;
+ q = q64>>( 64 - expDiff );
+ bSig <<= 6;
+ aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
+ }
+ do {
+ alternateASig = aSig;
+ ++q;
+ aSig -= bSig;
+ } while ( 0 <= (sbits32) aSig );
+ sigMean = aSig + alternateASig;
+ if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
+ aSig = alternateASig;
+ }
+ zSign = ( (sbits32) aSig < 0 );
+ if ( zSign ) aSig = - aSig;
+ return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the single-precision floating-point value `a'.
+The operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float32_sqrt( struct roundingData *roundData, float32 a )
+{
+ flag aSign;
+ int16 aExp, zExp;
+ bits32 aSig, zSig;
+ bits64 rem, term;
+
+ aSig = extractFloat32Frac( a );
+ aExp = extractFloat32Exp( a );
+ aSign = extractFloat32Sign( a );
+ if ( aExp == 0xFF ) {
+ if ( aSig ) return propagateFloat32NaN( a, 0 );
+ if ( ! aSign ) return a;
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ if ( aSign ) {
+ if ( ( aExp | aSig ) == 0 ) return a;
+ roundData->exception |= float_flag_invalid;
+ return float32_default_nan;
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return 0;
+ normalizeFloat32Subnormal( aSig, &aExp, &aSig );
+ }
+ zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
+ aSig = ( aSig | 0x00800000 )<<8;
+ zSig = estimateSqrt32( aExp, aSig ) + 2;
+ if ( ( zSig & 0x7F ) <= 5 ) {
+ if ( zSig < 2 ) {
+ zSig = 0xFFFFFFFF;
+ }
+ else {
+ aSig >>= aExp & 1;
+ term = ( (bits64) zSig ) * zSig;
+ rem = ( ( (bits64) aSig )<<32 ) - term;
+ while ( (sbits64) rem < 0 ) {
+ --zSig;
+ rem += ( ( (bits64) zSig )<<1 ) | 1;
+ }
+ zSig |= ( rem != 0 );
+ }
+ }
+ shift32RightJamming( zSig, 1, &zSig );
+ return roundAndPackFloat32( roundData, 0, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise. The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_eq( float32 a, float32 b )
+{
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise. The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_le( float32 a, float32 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
+ return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise. The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_lt( float32 a, float32 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
+ return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise. The invalid exception is raised
+if either operand is a NaN. Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_eq_signaling( float32 a, float32 b )
+{
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
+cause an exception. Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_le_quiet( float32 a, float32 b )
+{
+ flag aSign, bSign;
+ //int16 aExp, bExp;
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
+ return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the single-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
+exception. Otherwise, the comparison is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float32_lt_quiet( float32 a, float32 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
+ || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloat32Sign( a );
+ bSign = extractFloat32Sign( b );
+ if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
+ return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode. If `a' is a NaN, the largest
+positive integer is returned. Otherwise, if the conversion overflows, the
+largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_int32( struct roundingData *roundData, float64 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits64 aSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+ if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
+ shiftCount = 0x42C - aExp;
+ if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
+ return roundAndPackInt32( roundData, aSign, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero. If
+`a' is a NaN, the largest positive integer is returned. Otherwise, if the
+conversion overflows, the largest integer with the same sign as `a' is
+returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_int32_round_to_zero( float64 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits64 aSig, savedASig;
+ int32 z;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ shiftCount = 0x433 - aExp;
+ if ( shiftCount < 21 ) {
+ if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+ goto invalid;
+ }
+ else if ( 52 < shiftCount ) {
+ if ( aExp || aSig ) float_raise( float_flag_inexact );
+ return 0;
+ }
+ aSig |= LIT64( 0x0010000000000000 );
+ savedASig = aSig;
+ aSig >>= shiftCount;
+ z = aSig;
+ if ( aSign ) z = - z;
+ if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ return aSign ? 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ( aSig<<shiftCount ) != savedASig ) {
+ float_raise( float_flag_inexact );
+ }
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement unsigned integer format. The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic---which means in particular that the conversion is rounded
+according to the current rounding mode. If `a' is a NaN, the largest
+positive integer is returned. Otherwise, if the conversion overflows, the
+largest positive integer is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_uint32( struct roundingData *roundData, float64 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits64 aSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = 0; //extractFloat64Sign( a );
+ //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+ if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
+ shiftCount = 0x42C - aExp;
+ if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
+ return roundAndPackInt32( roundData, aSign, aSig );
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the 32-bit two's complement integer format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic, except that the conversion is always rounded toward zero. If
+`a' is a NaN, the largest positive integer is returned. Otherwise, if the
+conversion overflows, the largest positive integer is returned.
+-------------------------------------------------------------------------------
+*/
+int32 float64_to_uint32_round_to_zero( float64 a )
+{
+ flag aSign;
+ int16 aExp, shiftCount;
+ bits64 aSig, savedASig;
+ int32 z;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ shiftCount = 0x433 - aExp;
+ if ( shiftCount < 21 ) {
+ if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
+ goto invalid;
+ }
+ else if ( 52 < shiftCount ) {
+ if ( aExp || aSig ) float_raise( float_flag_inexact );
+ return 0;
+ }
+ aSig |= LIT64( 0x0010000000000000 );
+ savedASig = aSig;
+ aSig >>= shiftCount;
+ z = aSig;
+ if ( aSign ) z = - z;
+ if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ return aSign ? 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ( aSig<<shiftCount ) != savedASig ) {
+ float_raise( float_flag_inexact );
+ }
+ return z;
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the single-precision floating-point format. The conversion is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 float64_to_float32( struct roundingData *roundData, float64 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits64 aSig;
+ bits32 zSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
+ return packFloat32( aSign, 0xFF, 0 );
+ }
+ shift64RightJamming( aSig, 22, &aSig );
+ zSig = aSig;
+ if ( aExp || zSig ) {
+ zSig |= 0x40000000;
+ aExp -= 0x381;
+ }
+ return roundAndPackFloat32( roundData, aSign, aExp, zSig );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the double-precision floating-point value
+`a' to the extended double-precision floating-point format. The conversion
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 float64_to_floatx80( float64 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits64 aSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
+ return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ return
+ packFloatx80(
+ aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
+
+}
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Rounds the double-precision floating-point value `a' to an integer, and
+returns the result as a double-precision floating-point value. The
+operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( struct roundingData *roundData, float64 a )
+{
+ flag aSign;
+ int16 aExp;
+ bits64 lastBitMask, roundBitsMask;
+ int8 roundingMode;
+ float64 z;
+
+ aExp = extractFloat64Exp( a );
+ if ( 0x433 <= aExp ) {
+ if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
+ return propagateFloat64NaN( a, a );
+ }
+ return a;
+ }
+ if ( aExp <= 0x3FE ) {
+ if ( (bits64) ( a<<1 ) == 0 ) return a;
+ roundData->exception |= float_flag_inexact;
+ aSign = extractFloat64Sign( a );
+ switch ( roundData->mode ) {
+ case float_round_nearest_even:
+ if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
+ return packFloat64( aSign, 0x3FF, 0 );
+ }
+ break;
+ case float_round_down:
+ return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
+ case float_round_up:
+ return
+ aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
+ }
+ return packFloat64( aSign, 0, 0 );
+ }
+ lastBitMask = 1;
+ lastBitMask <<= 0x433 - aExp;
+ roundBitsMask = lastBitMask - 1;
+ z = a;
+ roundingMode = roundData->mode;
+ if ( roundingMode == float_round_nearest_even ) {
+ z += lastBitMask>>1;
+ if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
+ }
+ else if ( roundingMode != float_round_to_zero ) {
+ if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+ z += roundBitsMask;
+ }
+ }
+ z &= ~ roundBitsMask;
+ if ( z != a ) roundData->exception |= float_flag_inexact;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the double-precision
+floating-point values `a' and `b'. If `zSign' is true, the sum is negated
+before being returned. `zSign' is ignored if the result is a NaN. The
+addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
+{
+ int16 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig;
+ int16 expDiff;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ bSig = extractFloat64Frac( b );
+ bExp = extractFloat64Exp( b );
+ expDiff = aExp - bExp;
+ aSig <<= 9;
+ bSig <<= 9;
+ if ( 0 < expDiff ) {
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return propagateFloat64NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig |= LIT64( 0x2000000000000000 );
+ }
+ shift64RightJamming( bSig, expDiff, &bSig );
+ zExp = aExp;
+ }
+ else if ( expDiff < 0 ) {
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ return packFloat64( zSign, 0x7FF, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig |= LIT64( 0x2000000000000000 );
+ }
+ shift64RightJamming( aSig, - expDiff, &aSig );
+ zExp = bExp;
+ }
+ else {
+ if ( aExp == 0x7FF ) {
+ if ( aSig | bSig ) return propagateFloat64NaN( a, b );
+ return a;
+ }
+ if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
+ zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
+ zExp = aExp;
+ goto roundAndPack;
+ }
+ aSig |= LIT64( 0x2000000000000000 );
+ zSig = ( aSig + bSig )<<1;
+ --zExp;
+ if ( (sbits64) zSig < 0 ) {
+ zSig = aSig + bSig;
+ ++zExp;
+ }
+ roundAndPack:
+ return roundAndPackFloat64( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the double-
+precision floating-point values `a' and `b'. If `zSign' is true, the
+difference is negated before being returned. `zSign' is ignored if the
+result is a NaN. The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
+{
+ int16 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig;
+ int16 expDiff;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ bSig = extractFloat64Frac( b );
+ bExp = extractFloat64Exp( b );
+ expDiff = aExp - bExp;
+ aSig <<= 10;
+ bSig <<= 10;
+ if ( 0 < expDiff ) goto aExpBigger;
+ if ( expDiff < 0 ) goto bExpBigger;
+ if ( aExp == 0x7FF ) {
+ if ( aSig | bSig ) return propagateFloat64NaN( a, b );
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ if ( aExp == 0 ) {
+ aExp = 1;
+ bExp = 1;
+ }
+ if ( bSig < aSig ) goto aBigger;
+ if ( aSig < bSig ) goto bBigger;
+ return packFloat64( roundData->mode == float_round_down, 0, 0 );
+ bExpBigger:
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ return packFloat64( zSign ^ 1, 0x7FF, 0 );
+ }
+ if ( aExp == 0 ) {
+ ++expDiff;
+ }
+ else {
+ aSig |= LIT64( 0x4000000000000000 );
+ }
+ shift64RightJamming( aSig, - expDiff, &aSig );
+ bSig |= LIT64( 0x4000000000000000 );
+ bBigger:
+ zSig = bSig - aSig;
+ zExp = bExp;
+ zSign ^= 1;
+ goto normalizeRoundAndPack;
+ aExpBigger:
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return propagateFloat64NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ --expDiff;
+ }
+ else {
+ bSig |= LIT64( 0x4000000000000000 );
+ }
+ shift64RightJamming( bSig, expDiff, &bSig );
+ aSig |= LIT64( 0x4000000000000000 );
+ aBigger:
+ zSig = aSig - bSig;
+ zExp = aExp;
+ normalizeRoundAndPack:
+ --zExp;
+ return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the double-precision floating-point values `a'
+and `b'. The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign == bSign ) {
+ return addFloat64Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return subFloat64Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the double-precision floating-point values
+`a' and `b'. The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign == bSign ) {
+ return subFloat64Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return addFloat64Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the double-precision floating-point values
+`a' and `b'. The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig0, zSig1;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ bSig = extractFloat64Frac( b );
+ bExp = extractFloat64Exp( b );
+ bSign = extractFloat64Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FF ) {
+ if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
+ return propagateFloat64NaN( a, b );
+ }
+ if ( ( bExp | bSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ return packFloat64( zSign, 0x7FF, 0 );
+ }
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ if ( ( aExp | aSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ return packFloat64( zSign, 0x7FF, 0 );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
+ normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+ }
+ zExp = aExp + bExp - 0x3FF;
+ aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
+ bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+ mul64To128( aSig, bSig, &zSig0, &zSig1 );
+ zSig0 |= ( zSig1 != 0 );
+ if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
+ zSig0 <<= 1;
+ --zExp;
+ }
+ return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the double-precision floating-point value `a'
+by the corresponding value `b'. The operation is performed according to
+the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig;
+ bits64 rem0, rem1;
+ bits64 term0, term1;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ bSig = extractFloat64Frac( b );
+ bExp = extractFloat64Exp( b );
+ bSign = extractFloat64Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return propagateFloat64NaN( a, b );
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ return packFloat64( zSign, 0x7FF, 0 );
+ }
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ return packFloat64( zSign, 0, 0 );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ if ( ( aExp | aSig ) == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ roundData->exception |= float_flag_divbyzero;
+ return packFloat64( zSign, 0x7FF, 0 );
+ }
+ normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ zExp = aExp - bExp + 0x3FD;
+ aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
+ bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+ if ( bSig <= ( aSig + aSig ) ) {
+ aSig >>= 1;
+ ++zExp;
+ }
+ zSig = estimateDiv128To64( aSig, 0, bSig );
+ if ( ( zSig & 0x1FF ) <= 2 ) {
+ mul64To128( bSig, zSig, &term0, &term1 );
+ sub128( aSig, 0, term0, term1, &rem0, &rem1 );
+ while ( (sbits64) rem0 < 0 ) {
+ --zSig;
+ add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
+ }
+ zSig |= ( rem1 != 0 );
+ }
+ return roundAndPackFloat64( roundData, zSign, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the double-precision floating-point value `a'
+with respect to the corresponding value `b'. The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
+{
+ flag aSign, bSign, zSign;
+ int16 aExp, bExp, expDiff;
+ bits64 aSig, bSig;
+ bits64 q, alternateASig;
+ sbits64 sigMean;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ bSig = extractFloat64Frac( b );
+ bExp = extractFloat64Exp( b );
+ bSign = extractFloat64Sign( b );
+ if ( aExp == 0x7FF ) {
+ if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
+ return propagateFloat64NaN( a, b );
+ }
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ if ( bExp == 0x7FF ) {
+ if ( bSig ) return propagateFloat64NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ normalizeFloat64Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return a;
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ expDiff = aExp - bExp;
+ aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
+ bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
+ if ( expDiff < 0 ) {
+ if ( expDiff < -1 ) return a;
+ aSig >>= 1;
+ }
+ q = ( bSig <= aSig );
+ if ( q ) aSig -= bSig;
+ expDiff -= 64;
+ while ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig, 0, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ aSig = - ( ( bSig>>2 ) * q );
+ expDiff -= 62;
+ }
+ expDiff += 64;
+ if ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig, 0, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ q >>= 64 - expDiff;
+ bSig >>= 2;
+ aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
+ }
+ else {
+ aSig >>= 2;
+ bSig >>= 2;
+ }
+ do {
+ alternateASig = aSig;
+ ++q;
+ aSig -= bSig;
+ } while ( 0 <= (sbits64) aSig );
+ sigMean = aSig + alternateASig;
+ if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
+ aSig = alternateASig;
+ }
+ zSign = ( (sbits64) aSig < 0 );
+ if ( zSign ) aSig = - aSig;
+ return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the double-precision floating-point value `a'.
+The operation is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 float64_sqrt( struct roundingData *roundData, float64 a )
+{
+ flag aSign;
+ int16 aExp, zExp;
+ bits64 aSig, zSig;
+ bits64 rem0, rem1, term0, term1; //, shiftedRem;
+ //float64 z;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+ if ( aExp == 0x7FF ) {
+ if ( aSig ) return propagateFloat64NaN( a, a );
+ if ( ! aSign ) return a;
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ if ( aSign ) {
+ if ( ( aExp | aSig ) == 0 ) return a;
+ roundData->exception |= float_flag_invalid;
+ return float64_default_nan;
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return 0;
+ normalizeFloat64Subnormal( aSig, &aExp, &aSig );
+ }
+ zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
+ aSig |= LIT64( 0x0010000000000000 );
+ zSig = estimateSqrt32( aExp, aSig>>21 );
+ zSig <<= 31;
+ aSig <<= 9 - ( aExp & 1 );
+ zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2;
+ if ( ( zSig & 0x3FF ) <= 5 ) {
+ if ( zSig < 2 ) {
+ zSig = LIT64( 0xFFFFFFFFFFFFFFFF );
+ }
+ else {
+ aSig <<= 2;
+ mul64To128( zSig, zSig, &term0, &term1 );
+ sub128( aSig, 0, term0, term1, &rem0, &rem1 );
+ while ( (sbits64) rem0 < 0 ) {
+ --zSig;
+ shortShift128Left( 0, zSig, 1, &term0, &term1 );
+ term1 |= 1;
+ add128( rem0, rem1, term0, term1, &rem0, &rem1 );
+ }
+ zSig |= ( ( rem0 | rem1 ) != 0 );
+ }
+ }
+ shift64RightJamming( zSig, 1, &zSig );
+ return roundAndPackFloat64( roundData, 0, zExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise. The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_eq( float64 a, float64 b )
+{
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise. The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_le( float64 a, float64 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
+ return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise. The comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_lt( float64 a, float64 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
+ return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is equal to the
+corresponding value `b', and 0 otherwise. The invalid exception is raised
+if either operand is a NaN. Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_eq_signaling( float64 a, float64 b )
+{
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than or
+equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
+cause an exception. Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_le_quiet( float64 a, float64 b )
+{
+ flag aSign, bSign;
+ //int16 aExp, bExp;
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
+ return ( a == b ) || ( aSign ^ ( a < b ) );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the double-precision floating-point value `a' is less than
+the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
+exception. Otherwise, the comparison is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag float64_lt_quiet( float64 a, float64 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
+ || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloat64Sign( a );
+ bSign = extractFloat64Sign( b );
+ if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
+ return ( a != b ) && ( aSign ^ ( a < b ) );
+
+}
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the 32-bit two's complement integer format. The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic---which means in particular that the conversion
+is rounded according to the current rounding mode. If `a' is a NaN, the
+largest positive integer is returned. Otherwise, if the conversion
+overflows, the largest integer with the same sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
+{
+ flag aSign;
+ int32 aExp, shiftCount;
+ bits64 aSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
+ shiftCount = 0x4037 - aExp;
+ if ( shiftCount <= 0 ) shiftCount = 1;
+ shift64RightJamming( aSig, shiftCount, &aSig );
+ return roundAndPackInt32( roundData, aSign, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the 32-bit two's complement integer format. The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic, except that the conversion is always rounded
+toward zero. If `a' is a NaN, the largest positive integer is returned.
+Otherwise, if the conversion overflows, the largest integer with the same
+sign as `a' is returned.
+-------------------------------------------------------------------------------
+*/
+int32 floatx80_to_int32_round_to_zero( floatx80 a )
+{
+ flag aSign;
+ int32 aExp, shiftCount;
+ bits64 aSig, savedASig;
+ int32 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ shiftCount = 0x403E - aExp;
+ if ( shiftCount < 32 ) {
+ if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
+ goto invalid;
+ }
+ else if ( 63 < shiftCount ) {
+ if ( aExp || aSig ) float_raise( float_flag_inexact );
+ return 0;
+ }
+ savedASig = aSig;
+ aSig >>= shiftCount;
+ z = aSig;
+ if ( aSign ) z = - z;
+ if ( ( z < 0 ) ^ aSign ) {
+ invalid:
+ float_raise( float_flag_invalid );
+ return aSign ? 0x80000000 : 0x7FFFFFFF;
+ }
+ if ( ( aSig<<shiftCount ) != savedASig ) {
+ float_raise( float_flag_inexact );
+ }
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the single-precision floating-point format. The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
+{
+ flag aSign;
+ int32 aExp;
+ bits64 aSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 ) ) {
+ return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
+ }
+ return packFloat32( aSign, 0xFF, 0 );
+ }
+ shift64RightJamming( aSig, 33, &aSig );
+ if ( aExp || aSig ) aExp -= 0x3F81;
+ return roundAndPackFloat32( roundData, aSign, aExp, aSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of converting the extended double-precision floating-
+point value `a' to the double-precision floating-point format. The
+conversion is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
+{
+ flag aSign;
+ int32 aExp;
+ bits64 aSig, zSig;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 ) ) {
+ return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
+ }
+ return packFloat64( aSign, 0x7FF, 0 );
+ }
+ shift64RightJamming( aSig, 1, &zSig );
+ if ( aExp || aSig ) aExp -= 0x3C01;
+ return roundAndPackFloat64( roundData, aSign, aExp, zSig );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Rounds the extended double-precision floating-point value `a' to an integer,
+and returns the result as an extended quadruple-precision floating-point
+value. The operation is performed according to the IEC/IEEE Standard for
+Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
+{
+ flag aSign;
+ int32 aExp;
+ bits64 lastBitMask, roundBitsMask;
+ int8 roundingMode;
+ floatx80 z;
+
+ aExp = extractFloatx80Exp( a );
+ if ( 0x403E <= aExp ) {
+ if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
+ return propagateFloatx80NaN( a, a );
+ }
+ return a;
+ }
+ if ( aExp <= 0x3FFE ) {
+ if ( ( aExp == 0 )
+ && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
+ return a;
+ }
+ roundData->exception |= float_flag_inexact;
+ aSign = extractFloatx80Sign( a );
+ switch ( roundData->mode ) {
+ case float_round_nearest_even:
+ if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
+ ) {
+ return
+ packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
+ }
+ break;
+ case float_round_down:
+ return
+ aSign ?
+ packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
+ : packFloatx80( 0, 0, 0 );
+ case float_round_up:
+ return
+ aSign ? packFloatx80( 1, 0, 0 )
+ : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
+ }
+ return packFloatx80( aSign, 0, 0 );
+ }
+ lastBitMask = 1;
+ lastBitMask <<= 0x403E - aExp;
+ roundBitsMask = lastBitMask - 1;
+ z = a;
+ roundingMode = roundData->mode;
+ if ( roundingMode == float_round_nearest_even ) {
+ z.low += lastBitMask>>1;
+ if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
+ }
+ else if ( roundingMode != float_round_to_zero ) {
+ if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
+ z.low += roundBitsMask;
+ }
+ }
+ z.low &= ~ roundBitsMask;
+ if ( z.low == 0 ) {
+ ++z.high;
+ z.low = LIT64( 0x8000000000000000 );
+ }
+ if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
+ return z;
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the absolute values of the extended double-
+precision floating-point values `a' and `b'. If `zSign' is true, the sum is
+negated before being returned. `zSign' is ignored if the result is a NaN.
+The addition is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
+{
+ int32 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig0, zSig1;
+ int32 expDiff;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ expDiff = aExp - bExp;
+ if ( 0 < expDiff ) {
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) --expDiff;
+ shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+ zExp = aExp;
+ }
+ else if ( expDiff < 0 ) {
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) ++expDiff;
+ shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+ zExp = bExp;
+ }
+ else {
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ return a;
+ }
+ zSig1 = 0;
+ zSig0 = aSig + bSig;
+ if ( aExp == 0 ) {
+ normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
+ goto roundAndPack;
+ }
+ zExp = aExp;
+ goto shiftRight1;
+ }
+
+ zSig0 = aSig + bSig;
+
+ if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
+ shiftRight1:
+ shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
+ zSig0 |= LIT64( 0x8000000000000000 );
+ ++zExp;
+ roundAndPack:
+ return
+ roundAndPackFloatx80(
+ roundData, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the absolute values of the extended
+double-precision floating-point values `a' and `b'. If `zSign' is true,
+the difference is negated before being returned. `zSign' is ignored if the
+result is a NaN. The subtraction is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
+{
+ int32 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig0, zSig1;
+ int32 expDiff;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ expDiff = aExp - bExp;
+ if ( 0 < expDiff ) goto aExpBigger;
+ if ( expDiff < 0 ) goto bExpBigger;
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ roundData->exception |= float_flag_invalid;
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ z.__padding = 0;
+ return z;
+ }
+ if ( aExp == 0 ) {
+ aExp = 1;
+ bExp = 1;
+ }
+ zSig1 = 0;
+ if ( bSig < aSig ) goto aBigger;
+ if ( aSig < bSig ) goto bBigger;
+ return packFloatx80( roundData->mode == float_round_down, 0, 0 );
+ bExpBigger:
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) ++expDiff;
+ shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
+ bBigger:
+ sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
+ zExp = bExp;
+ zSign ^= 1;
+ goto normalizeRoundAndPack;
+ aExpBigger:
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) --expDiff;
+ shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
+ aBigger:
+ sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
+ zExp = aExp;
+ normalizeRoundAndPack:
+ return
+ normalizeRoundAndPackFloatx80(
+ roundData, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of adding the extended double-precision floating-point
+values `a' and `b'. The operation is performed according to the IEC/IEEE
+Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign == bSign ) {
+ return addFloatx80Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return subFloatx80Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of subtracting the extended double-precision floating-
+point values `a' and `b'. The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign == bSign ) {
+ return subFloatx80Sigs( roundData, a, b, aSign );
+ }
+ else {
+ return addFloatx80Sigs( roundData, a, b, aSign );
+ }
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of multiplying the extended double-precision floating-
+point values `a' and `b'. The operation is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
+{
+ flag aSign, bSign, zSign;
+ int32 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig0, zSig1;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ bSign = extractFloatx80Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 )
+ || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ if ( ( bExp | bSig ) == 0 ) goto invalid;
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+ roundData->exception |= float_flag_invalid;
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ z.__padding = 0;
+ return z;
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ zExp = aExp + bExp - 0x3FFE;
+ mul64To128( aSig, bSig, &zSig0, &zSig1 );
+ if ( 0 < (sbits64) zSig0 ) {
+ shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
+ --zExp;
+ }
+ return
+ roundAndPackFloatx80(
+ roundData, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the result of dividing the extended double-precision floating-point
+value `a' by the corresponding value `b'. The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
+{
+ flag aSign, bSign, zSign;
+ int32 aExp, bExp, zExp;
+ bits64 aSig, bSig, zSig0, zSig1;
+ bits64 rem0, rem1, rem2, term0, term1, term2;
+ floatx80 z;
+
+ aSig = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ bSign = extractFloatx80Sign( b );
+ zSign = aSign ^ bSign;
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ goto invalid;
+ }
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return packFloatx80( zSign, 0, 0 );
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ if ( ( aExp | aSig ) == 0 ) {
+ invalid:
+ roundData->exception |= float_flag_invalid;
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ z.__padding = 0;
+ return z;
+ }
+ roundData->exception |= float_flag_divbyzero;
+ return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+ }
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
+ normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
+ }
+ zExp = aExp - bExp + 0x3FFE;
+ rem1 = 0;
+ if ( bSig <= aSig ) {
+ shift128Right( aSig, 0, 1, &aSig, &rem1 );
+ ++zExp;
+ }
+ zSig0 = estimateDiv128To64( aSig, rem1, bSig );
+ mul64To128( bSig, zSig0, &term0, &term1 );
+ sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
+ while ( (sbits64) rem0 < 0 ) {
+ --zSig0;
+ add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
+ }
+ zSig1 = estimateDiv128To64( rem1, 0, bSig );
+ if ( (bits64) ( zSig1<<1 ) <= 8 ) {
+ mul64To128( bSig, zSig1, &term1, &term2 );
+ sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+ while ( (sbits64) rem1 < 0 ) {
+ --zSig1;
+ add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
+ }
+ zSig1 |= ( ( rem1 | rem2 ) != 0 );
+ }
+ return
+ roundAndPackFloatx80(
+ roundData, zSign, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the remainder of the extended double-precision floating-point value
+`a' with respect to the corresponding value `b'. The operation is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
+{
+ flag aSign, bSign, zSign;
+ int32 aExp, bExp, expDiff;
+ bits64 aSig0, aSig1, bSig;
+ bits64 q, term0, term1, alternateASig0, alternateASig1;
+ floatx80 z;
+
+ aSig0 = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ bSig = extractFloatx80Frac( b );
+ bExp = extractFloatx80Exp( b );
+ bSign = extractFloatx80Sign( b );
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig0<<1 )
+ || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
+ return propagateFloatx80NaN( a, b );
+ }
+ goto invalid;
+ }
+ if ( bExp == 0x7FFF ) {
+ if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
+ return a;
+ }
+ if ( bExp == 0 ) {
+ if ( bSig == 0 ) {
+ invalid:
+ roundData->exception |= float_flag_invalid;
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ z.__padding = 0;
+ return z;
+ }
+ normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
+ }
+ if ( aExp == 0 ) {
+ if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
+ normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+ }
+ bSig |= LIT64( 0x8000000000000000 );
+ zSign = aSign;
+ expDiff = aExp - bExp;
+ aSig1 = 0;
+ if ( expDiff < 0 ) {
+ if ( expDiff < -1 ) return a;
+ shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
+ expDiff = 0;
+ }
+ q = ( bSig <= aSig0 );
+ if ( q ) aSig0 -= bSig;
+ expDiff -= 64;
+ while ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ mul64To128( bSig, q, &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
+ expDiff -= 62;
+ }
+ expDiff += 64;
+ if ( 0 < expDiff ) {
+ q = estimateDiv128To64( aSig0, aSig1, bSig );
+ q = ( 2 < q ) ? q - 2 : 0;
+ q >>= 64 - expDiff;
+ mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
+ while ( le128( term0, term1, aSig0, aSig1 ) ) {
+ ++q;
+ sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
+ }
+ }
+ else {
+ term1 = 0;
+ term0 = bSig;
+ }
+ sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
+ if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
+ && ( q & 1 ) )
+ ) {
+ aSig0 = alternateASig0;
+ aSig1 = alternateASig1;
+ zSign = ! zSign;
+ }
+
+ return
+ normalizeRoundAndPackFloatx80(
+ roundData, zSign, bExp + expDiff, aSig0, aSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns the square root of the extended double-precision floating-point
+value `a'. The operation is performed according to the IEC/IEEE Standard
+for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
+{
+ flag aSign;
+ int32 aExp, zExp;
+ bits64 aSig0, aSig1, zSig0, zSig1;
+ bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
+ bits64 shiftedRem0, shiftedRem1;
+ floatx80 z;
+
+ aSig0 = extractFloatx80Frac( a );
+ aExp = extractFloatx80Exp( a );
+ aSign = extractFloatx80Sign( a );
+ if ( aExp == 0x7FFF ) {
+ if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
+ if ( ! aSign ) return a;
+ goto invalid;
+ }
+ if ( aSign ) {
+ if ( ( aExp | aSig0 ) == 0 ) return a;
+ invalid:
+ roundData->exception |= float_flag_invalid;
+ z.low = floatx80_default_nan_low;
+ z.high = floatx80_default_nan_high;
+ z.__padding = 0;
+ return z;
+ }
+ if ( aExp == 0 ) {
+ if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
+ normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
+ }
+ zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
+ zSig0 = estimateSqrt32( aExp, aSig0>>32 );
+ zSig0 <<= 31;
+ aSig1 = 0;
+ shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
+ zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
+ if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
+ shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
+ mul64To128( zSig0, zSig0, &term0, &term1 );
+ sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
+ while ( (sbits64) rem0 < 0 ) {
+ --zSig0;
+ shortShift128Left( 0, zSig0, 1, &term0, &term1 );
+ term1 |= 1;
+ add128( rem0, rem1, term0, term1, &rem0, &rem1 );
+ }
+ shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
+ zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
+ if ( (bits64) ( zSig1<<1 ) <= 10 ) {
+ if ( zSig1 == 0 ) zSig1 = 1;
+ mul64To128( zSig0, zSig1, &term1, &term2 );
+ shortShift128Left( term1, term2, 1, &term1, &term2 );
+ sub128( rem1, 0, term1, term2, &rem1, &rem2 );
+ mul64To128( zSig1, zSig1, &term2, &term3 );
+ sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
+ while ( (sbits64) rem1 < 0 ) {
+ --zSig1;
+ shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
+ term3 |= 1;
+ add192(
+ rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
+ }
+ zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
+ }
+ return
+ roundAndPackFloatx80(
+ roundData, 0, zExp, zSig0, zSig1 );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+equal to the corresponding value `b', and 0 otherwise. The comparison is
+performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_eq( floatx80 a, floatx80 b )
+{
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ if ( floatx80_is_signaling_nan( a )
+ || floatx80_is_signaling_nan( b ) ) {
+ float_raise( float_flag_invalid );
+ }
+ return 0;
+ }
+ return
+ ( a.low == b.low )
+ && ( ( a.high == b.high )
+ || ( ( a.low == 0 )
+ && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
+ );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+less than or equal to the corresponding value `b', and 0 otherwise. The
+comparison is performed according to the IEC/IEEE Standard for Binary
+Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_le( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ == 0 );
+ }
+ return
+ aSign ? le128( b.high, b.low, a.high, a.low )
+ : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is
+less than the corresponding value `b', and 0 otherwise. The comparison
+is performed according to the IEC/IEEE Standard for Binary Floating-point
+Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_lt( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ != 0 );
+ }
+ return
+ aSign ? lt128( b.high, b.low, a.high, a.low )
+ : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is equal
+to the corresponding value `b', and 0 otherwise. The invalid exception is
+raised if either operand is a NaN. Otherwise, the comparison is performed
+according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_eq_signaling( floatx80 a, floatx80 b )
+{
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ float_raise( float_flag_invalid );
+ return 0;
+ }
+ return
+ ( a.low == b.low )
+ && ( ( a.high == b.high )
+ || ( ( a.low == 0 )
+ && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
+ );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is less
+than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs
+do not cause an exception. Otherwise, the comparison is performed according
+to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_le_quiet( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ == 0 );
+ }
+ return
+ aSign ? le128( b.high, b.low, a.high, a.low )
+ : le128( a.high, a.low, b.high, b.low );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Returns 1 if the extended double-precision floating-point value `a' is less
+than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause
+an exception. Otherwise, the comparison is performed according to the
+IEC/IEEE Standard for Binary Floating-point Arithmetic.
+-------------------------------------------------------------------------------
+*/
+flag floatx80_lt_quiet( floatx80 a, floatx80 b )
+{
+ flag aSign, bSign;
+
+ if ( ( ( extractFloatx80Exp( a ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( a )<<1 ) )
+ || ( ( extractFloatx80Exp( b ) == 0x7FFF )
+ && (bits64) ( extractFloatx80Frac( b )<<1 ) )
+ ) {
+ /* Do nothing, even if NaN as we're quiet */
+ return 0;
+ }
+ aSign = extractFloatx80Sign( a );
+ bSign = extractFloatx80Sign( b );
+ if ( aSign != bSign ) {
+ return
+ aSign
+ && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
+ != 0 );
+ }
+ return
+ aSign ? lt128( b.high, b.low, a.high, a.low )
+ : lt128( a.high, a.low, b.high, b.low );
+
+}
+
+#endif
+
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
new file mode 100644
index 00000000..df4d243a
--- /dev/null
+++ b/arch/arm/nwfpe/softfloat.h
@@ -0,0 +1,281 @@
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page
+http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these three paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#ifndef __SOFTFLOAT_H__
+#define __SOFTFLOAT_H__
+
+
+/*
+-------------------------------------------------------------------------------
+The macro `FLOATX80' must be defined to enable the extended double-precision
+floating-point format `floatx80'. If this macro is not defined, the
+`floatx80' type will not be defined, and none of the functions that either
+input or output the `floatx80' type will be defined.
+-------------------------------------------------------------------------------
+*/
+#ifdef CONFIG_FPE_NWFPE_XP
+#define FLOATX80
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point types.
+-------------------------------------------------------------------------------
+*/
+typedef u32 float32;
+typedef u64 float64;
+typedef struct {
+#ifdef __ARMEB__
+ u16 __padding;
+ u16 high;
+#else
+ u16 high;
+ u16 __padding;
+#endif
+ u64 low;
+} __attribute__ ((packed,aligned(4))) floatx80;
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point underflow tininess-detection mode.
+-------------------------------------------------------------------------------
+*/
+extern signed char float_detect_tininess;
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+//extern int8 float_rounding_mode;
+enum {
+ float_round_nearest_even = 0,
+ float_round_to_zero = 1,
+ float_round_down = 2,
+ float_round_up = 3
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point exception flags.
+-------------------------------------------------------------------------------
+enum {
+ float_flag_inexact = 1,
+ float_flag_underflow = 2,
+ float_flag_overflow = 4,
+ float_flag_divbyzero = 8,
+ float_flag_invalid = 16
+};
+
+ScottB: November 4, 1998
+Changed the enumeration to match the bit order in the FPA11.
+*/
+
+enum {
+ float_flag_invalid = 1,
+ float_flag_divbyzero = 2,
+ float_flag_overflow = 4,
+ float_flag_underflow = 8,
+ float_flag_inexact = 16
+};
+
+/*
+-------------------------------------------------------------------------------
+Routine to raise any or all of the software IEC/IEEE floating-point
+exception flags.
+-------------------------------------------------------------------------------
+*/
+void float_raise( signed char );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE integer-to-floating-point conversion routines.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( struct roundingData *, signed int );
+float64 int32_to_float64( signed int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( signed int );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int float32_to_int32( struct roundingData *, float32 );
+signed int float32_to_int32_round_to_zero( float32 );
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision operations.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( struct roundingData*, float32 );
+float32 float32_add( struct roundingData *, float32, float32 );
+float32 float32_sub( struct roundingData *, float32, float32 );
+float32 float32_mul( struct roundingData *, float32, float32 );
+float32 float32_div( struct roundingData *, float32, float32 );
+float32 float32_rem( struct roundingData *, float32, float32 );
+float32 float32_sqrt( struct roundingData*, float32 );
+char float32_eq( float32, float32 );
+char float32_le( float32, float32 );
+char float32_lt( float32, float32 );
+char float32_eq_signaling( float32, float32 );
+char float32_le_quiet( float32, float32 );
+char float32_lt_quiet( float32, float32 );
+char float32_is_signaling_nan( float32 );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int float64_to_int32( struct roundingData *, float64 );
+signed int float64_to_int32_round_to_zero( float64 );
+float32 float64_to_float32( struct roundingData *, float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision operations.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( struct roundingData *, float64 );
+float64 float64_add( struct roundingData *, float64, float64 );
+float64 float64_sub( struct roundingData *, float64, float64 );
+float64 float64_mul( struct roundingData *, float64, float64 );
+float64 float64_div( struct roundingData *, float64, float64 );
+float64 float64_rem( struct roundingData *, float64, float64 );
+float64 float64_sqrt( struct roundingData *, float64 );
+char float64_eq( float64, float64 );
+char float64_le( float64, float64 );
+char float64_lt( float64, float64 );
+char float64_eq_signaling( float64, float64 );
+char float64_le_quiet( float64, float64 );
+char float64_lt_quiet( float64, float64 );
+char float64_is_signaling_nan( float64 );
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+signed int floatx80_to_int32( struct roundingData *, floatx80 );
+signed int floatx80_to_int32_round_to_zero( floatx80 );
+float32 floatx80_to_float32( struct roundingData *, floatx80 );
+float64 floatx80_to_float64( struct roundingData *, floatx80 );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision operations.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( struct roundingData *, floatx80 );
+floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 );
+floatx80 floatx80_sqrt( struct roundingData *, floatx80 );
+char floatx80_eq( floatx80, floatx80 );
+char floatx80_le( floatx80, floatx80 );
+char floatx80_lt( floatx80, floatx80 );
+char floatx80_eq_signaling( floatx80, floatx80 );
+char floatx80_le_quiet( floatx80, floatx80 );
+char floatx80_lt_quiet( floatx80, floatx80 );
+char floatx80_is_signaling_nan( floatx80 );
+
+extern flag floatx80_is_nan(floatx80);
+
+#endif
+
+static inline flag extractFloat32Sign(float32 a)
+{
+ return a >> 31;
+}
+
+static inline flag float32_eq_nocheck(float32 a, float32 b)
+{
+ return (a == b) || ((bits32) ((a | b) << 1) == 0);
+}
+
+static inline flag float32_lt_nocheck(float32 a, float32 b)
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat32Sign(a);
+ bSign = extractFloat32Sign(b);
+ if (aSign != bSign)
+ return aSign && ((bits32) ((a | b) << 1) != 0);
+ return (a != b) && (aSign ^ (a < b));
+}
+
+static inline flag extractFloat64Sign(float64 a)
+{
+ return a >> 63;
+}
+
+static inline flag float64_eq_nocheck(float64 a, float64 b)
+{
+ return (a == b) || ((bits64) ((a | b) << 1) == 0);
+}
+
+static inline flag float64_lt_nocheck(float64 a, float64 b)
+{
+ flag aSign, bSign;
+
+ aSign = extractFloat64Sign(a);
+ bSign = extractFloat64Sign(b);
+ if (aSign != bSign)
+ return aSign && ((bits64) ((a | b) << 1) != 0);
+ return (a != b) && (aSign ^ (a < b));
+}
+
+extern flag float32_is_nan( float32 a );
+extern flag float64_is_nan( float64 a );
+
+extern int32 float64_to_uint32( struct roundingData *roundData, float64 a );
+extern int32 float64_to_uint32_round_to_zero( float64 a );
+
+#endif
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
new file mode 100644
index 00000000..b2215c61
--- /dev/null
+++ b/arch/arm/oprofile/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+ oprof.o cpu_buffer.o buffer_sync.o \
+ event_buffer.o oprofile_files.o \
+ oprofilefs.o oprofile_stats.o \
+ timer_int.o )
+
+ifeq ($(CONFIG_HW_PERF_EVENTS),y)
+DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o)
+endif
+
+oprofile-y := $(DRIVER_OBJS) common.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
new file mode 100644
index 00000000..4e0a3716
--- /dev/null
+++ b/arch/arm/oprofile/common.c
@@ -0,0 +1,122 @@
+/**
+ * @file common.c
+ *
+ * @remark Copyright 2004 Oprofile Authors
+ * @remark Copyright 2010 ARM Ltd.
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo
+ * @author Will Deacon [move to perf]
+ */
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/oprofile.h>
+#include <linux/perf_event.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <asm/stacktrace.h>
+#include <linux/uaccess.h>
+
+#include <asm/perf_event.h>
+#include <asm/ptrace.h>
+
+#ifdef CONFIG_HW_PERF_EVENTS
+char *op_name_from_perf_id(void)
+{
+ enum arm_perf_pmu_ids id = armpmu_get_pmu_id();
+
+ switch (id) {
+ case ARM_PERF_PMU_ID_XSCALE1:
+ return "arm/xscale1";
+ case ARM_PERF_PMU_ID_XSCALE2:
+ return "arm/xscale2";
+ case ARM_PERF_PMU_ID_V6:
+ return "arm/armv6";
+ case ARM_PERF_PMU_ID_V6MP:
+ return "arm/mpcore";
+ case ARM_PERF_PMU_ID_CA8:
+ return "arm/armv7";
+ case ARM_PERF_PMU_ID_CA9:
+ return "arm/armv7-ca9";
+ default:
+ return NULL;
+ }
+}
+#endif
+
+static int report_trace(struct stackframe *frame, void *d)
+{
+ unsigned int *depth = d;
+
+ if (*depth) {
+ oprofile_add_trace(frame->pc);
+ (*depth)--;
+ }
+
+ return *depth == 0;
+}
+
+/*
+ * The registers we're interested in are at the end of the variable
+ * length saved register structure. The fp points at the end of this
+ * structure so the address of this struct is:
+ * (struct frame_tail *)(xxx->fp)-1
+ */
+struct frame_tail {
+ struct frame_tail *fp;
+ unsigned long sp;
+ unsigned long lr;
+} __attribute__((packed));
+
+static struct frame_tail* user_backtrace(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)))
+ return NULL;
+ if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail)))
+ return NULL;
+
+ oprofile_add_trace(buftail[0].lr);
+
+ /* frame pointers should strictly progress back up the stack
+ * (towards higher addresses) */
+ if (tail + 1 >= buftail[0].fp)
+ return NULL;
+
+ return buftail[0].fp-1;
+}
+
+static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+ struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
+
+ 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;
+ walk_stackframe(&frame, report_trace, &depth);
+ return;
+ }
+
+ while (depth-- && tail && !((unsigned long) tail & 3))
+ tail = user_backtrace(tail);
+}
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+ /* provide backtrace support also in timer mode: */
+ ops->backtrace = arm_backtrace;
+
+ return oprofile_perf_init(ops);
+}
+
+void oprofile_arch_exit(void)
+{
+ oprofile_perf_exit();
+}
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
new file mode 100644
index 00000000..69b09c1c
--- /dev/null
+++ b/arch/arm/plat-iop/Makefile
@@ -0,0 +1,35 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y :=
+
+# IOP32X
+obj-$(CONFIG_ARCH_IOP32X) += gpio.o
+obj-$(CONFIG_ARCH_IOP32X) += i2c.o
+obj-$(CONFIG_ARCH_IOP32X) += pci.o
+obj-$(CONFIG_ARCH_IOP32X) += setup.o
+obj-$(CONFIG_ARCH_IOP32X) += time.o
+obj-$(CONFIG_ARCH_IOP32X) += io.o
+obj-$(CONFIG_ARCH_IOP32X) += cp6.o
+obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
+
+# IOP33X
+obj-$(CONFIG_ARCH_IOP33X) += gpio.o
+obj-$(CONFIG_ARCH_IOP33X) += i2c.o
+obj-$(CONFIG_ARCH_IOP33X) += pci.o
+obj-$(CONFIG_ARCH_IOP33X) += setup.o
+obj-$(CONFIG_ARCH_IOP33X) += time.o
+obj-$(CONFIG_ARCH_IOP33X) += io.o
+obj-$(CONFIG_ARCH_IOP33X) += cp6.o
+obj-$(CONFIG_ARCH_IOP33X) += adma.o
+obj-$(CONFIG_ARCH_IOP33X) += pmu.o
+
+# IOP13XX
+obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
+obj-$(CONFIG_ARCH_IOP13XX) += time.o
+
+obj-m :=
+obj-n :=
+obj- :=
diff --git a/arch/arm/plat-iop/adma.c b/arch/arm/plat-iop/adma.c
new file mode 100644
index 00000000..1ff6a37e
--- /dev/null
+++ b/arch/arm/plat-iop/adma.c
@@ -0,0 +1,207 @@
+/*
+ * platform device definitions for the iop3xx dma/xor engines
+ * Copyright © 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+#include <linux/platform_device.h>
+#include <asm/hardware/iop3xx.h>
+#include <linux/dma-mapping.h>
+#include <mach/adma.h>
+#include <asm/hardware/iop_adma.h>
+
+#ifdef CONFIG_ARCH_IOP32X
+#define IRQ_DMA0_EOT IRQ_IOP32X_DMA0_EOT
+#define IRQ_DMA0_EOC IRQ_IOP32X_DMA0_EOC
+#define IRQ_DMA0_ERR IRQ_IOP32X_DMA0_ERR
+
+#define IRQ_DMA1_EOT IRQ_IOP32X_DMA1_EOT
+#define IRQ_DMA1_EOC IRQ_IOP32X_DMA1_EOC
+#define IRQ_DMA1_ERR IRQ_IOP32X_DMA1_ERR
+
+#define IRQ_AA_EOT IRQ_IOP32X_AA_EOT
+#define IRQ_AA_EOC IRQ_IOP32X_AA_EOC
+#define IRQ_AA_ERR IRQ_IOP32X_AA_ERR
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+#define IRQ_DMA0_EOT IRQ_IOP33X_DMA0_EOT
+#define IRQ_DMA0_EOC IRQ_IOP33X_DMA0_EOC
+#define IRQ_DMA0_ERR IRQ_IOP33X_DMA0_ERR
+
+#define IRQ_DMA1_EOT IRQ_IOP33X_DMA1_EOT
+#define IRQ_DMA1_EOC IRQ_IOP33X_DMA1_EOC
+#define IRQ_DMA1_ERR IRQ_IOP33X_DMA1_ERR
+
+#define IRQ_AA_EOT IRQ_IOP33X_AA_EOT
+#define IRQ_AA_EOC IRQ_IOP33X_AA_EOC
+#define IRQ_AA_ERR IRQ_IOP33X_AA_ERR
+#endif
+/* AAU and DMA Channels */
+static struct resource iop3xx_dma_0_resources[] = {
+ [0] = {
+ .start = IOP3XX_DMA_PHYS_BASE(0),
+ .end = IOP3XX_DMA_UPPER_PA(0),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DMA0_EOT,
+ .end = IRQ_DMA0_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_DMA0_EOC,
+ .end = IRQ_DMA0_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_DMA0_ERR,
+ .end = IRQ_DMA0_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static struct resource iop3xx_dma_1_resources[] = {
+ [0] = {
+ .start = IOP3XX_DMA_PHYS_BASE(1),
+ .end = IOP3XX_DMA_UPPER_PA(1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_DMA1_EOT,
+ .end = IRQ_DMA1_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_DMA1_EOC,
+ .end = IRQ_DMA1_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_DMA1_ERR,
+ .end = IRQ_DMA1_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+
+static struct resource iop3xx_aau_resources[] = {
+ [0] = {
+ .start = IOP3XX_AAU_PHYS_BASE,
+ .end = IOP3XX_AAU_UPPER_PA,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_AA_EOT,
+ .end = IRQ_AA_EOT,
+ .flags = IORESOURCE_IRQ
+ },
+ [2] = {
+ .start = IRQ_AA_EOC,
+ .end = IRQ_AA_EOC,
+ .flags = IORESOURCE_IRQ
+ },
+ [3] = {
+ .start = IRQ_AA_ERR,
+ .end = IRQ_AA_ERR,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+static u64 iop3xx_adma_dmamask = DMA_BIT_MASK(32);
+
+static struct iop_adma_platform_data iop3xx_dma_0_data = {
+ .hw_id = DMA0_ID,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct iop_adma_platform_data iop3xx_dma_1_data = {
+ .hw_id = DMA1_ID,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct iop_adma_platform_data iop3xx_aau_data = {
+ .hw_id = AAU_ID,
+ .pool_size = 3 * PAGE_SIZE,
+};
+
+struct platform_device iop3xx_dma_0_channel = {
+ .name = "iop-adma",
+ .id = 0,
+ .num_resources = 4,
+ .resource = iop3xx_dma_0_resources,
+ .dev = {
+ .dma_mask = &iop3xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop3xx_dma_0_data,
+ },
+};
+
+struct platform_device iop3xx_dma_1_channel = {
+ .name = "iop-adma",
+ .id = 1,
+ .num_resources = 4,
+ .resource = iop3xx_dma_1_resources,
+ .dev = {
+ .dma_mask = &iop3xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop3xx_dma_1_data,
+ },
+};
+
+struct platform_device iop3xx_aau_channel = {
+ .name = "iop-adma",
+ .id = 2,
+ .num_resources = 4,
+ .resource = iop3xx_aau_resources,
+ .dev = {
+ .dma_mask = &iop3xx_adma_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = (void *) &iop3xx_aau_data,
+ },
+};
+
+static int __init iop3xx_adma_cap_init(void)
+{
+ #ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
+ dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
+ #else
+ dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
+ #endif
+
+ #ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
+ dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
+ #else
+ dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
+ #endif
+
+ #ifdef CONFIG_ARCH_IOP32X /* the 32x AAU does not perform zero sum */
+ dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
+ dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
+ #else
+ dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
+ dma_cap_set(DMA_XOR_VAL, iop3xx_aau_data.cap_mask);
+ dma_cap_set(DMA_MEMSET, iop3xx_aau_data.cap_mask);
+ dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
+ #endif
+
+ return 0;
+}
+
+arch_initcall(iop3xx_adma_cap_init);
diff --git a/arch/arm/plat-iop/cp6.c b/arch/arm/plat-iop/cp6.c
new file mode 100644
index 00000000..bab73e2c
--- /dev/null
+++ b/arch/arm/plat-iop/cp6.c
@@ -0,0 +1,51 @@
+/*
+ * IOP Coprocessor-6 access handler
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/init.h>
+#include <asm/traps.h>
+#include <asm/ptrace.h>
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+ u32 temp;
+
+ /* enable cp6 access */
+ asm volatile (
+ "mrc p15, 0, %0, c15, c1, 0\n\t"
+ "orr %0, %0, #(1 << 6)\n\t"
+ "mcr p15, 0, %0, c15, c1, 0\n\t"
+ : "=r"(temp));
+
+ return 0;
+}
+
+/* permit kernel space cp6 access
+ * deny user space cp6 access
+ */
+static struct undef_hook cp6_hook = {
+ .instr_mask = 0x0f000ff0,
+ .instr_val = 0x0e000610,
+ .cpsr_mask = MODE_MASK,
+ .cpsr_val = SVC_MODE,
+ .fn = cp6_trap,
+};
+
+void __init iop_init_cp6_handler(void)
+{
+ register_undef_hook(&cp6_hook);
+}
diff --git a/arch/arm/plat-iop/gpio.c b/arch/arm/plat-iop/gpio.c
new file mode 100644
index 00000000..640e498c
--- /dev/null
+++ b/arch/arm/plat-iop/gpio.c
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/plat-iop/gpio.c
+ * GPIO handling for Intel IOP3xx processors.
+ *
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <asm/hardware/iop3xx.h>
+
+void gpio_line_config(int line, int direction)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (direction == GPIO_IN) {
+ *IOP3XX_GPOE |= 1 << line;
+ } else if (direction == GPIO_OUT) {
+ *IOP3XX_GPOE &= ~(1 << line);
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_line_config);
+
+int gpio_line_get(int line)
+{
+ return !!(*IOP3XX_GPID & (1 << line));
+}
+EXPORT_SYMBOL(gpio_line_get);
+
+void gpio_line_set(int line, int value)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ if (value == GPIO_LOW) {
+ *IOP3XX_GPOD &= ~(1 << line);
+ } else if (value == GPIO_HIGH) {
+ *IOP3XX_GPOD |= 1 << line;
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_line_set);
+
+static int iop3xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+ gpio_line_config(gpio, GPIO_IN);
+ return 0;
+}
+
+static int iop3xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
+{
+ gpio_line_set(gpio, level);
+ gpio_line_config(gpio, GPIO_OUT);
+ return 0;
+}
+
+static int iop3xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ return gpio_line_get(gpio);
+}
+
+static void iop3xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value)
+{
+ gpio_line_set(gpio, value);
+}
+
+static struct gpio_chip iop3xx_chip = {
+ .label = "iop3xx",
+ .direction_input = iop3xx_gpio_direction_input,
+ .get = iop3xx_gpio_get_value,
+ .direction_output = iop3xx_gpio_direction_output,
+ .set = iop3xx_gpio_set_value,
+ .base = 0,
+ .ngpio = IOP3XX_N_GPIOS,
+};
+
+static int __init iop3xx_gpio_setup(void)
+{
+ return gpiochip_add(&iop3xx_chip);
+}
+arch_initcall(iop3xx_gpio_setup);
diff --git a/arch/arm/plat-iop/i2c.c b/arch/arm/plat-iop/i2c.c
new file mode 100644
index 00000000..4efe3928
--- /dev/null
+++ b/arch/arm/plat-iop/i2c.c
@@ -0,0 +1,80 @@
+/*
+ * arch/arm/plat-iop/i2c.c
+ *
+ * Author: Nicolas Pitre <nico@cam.org>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/major.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iop3xx.h>
+#include <asm/mach/arch.h>
+
+#ifdef CONFIG_ARCH_IOP32X
+#define IRQ_IOP3XX_I2C_0 IRQ_IOP32X_I2C_0
+#define IRQ_IOP3XX_I2C_1 IRQ_IOP32X_I2C_1
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+#define IRQ_IOP3XX_I2C_0 IRQ_IOP33X_I2C_0
+#define IRQ_IOP3XX_I2C_1 IRQ_IOP33X_I2C_1
+#endif
+
+static struct resource iop3xx_i2c0_resources[] = {
+ [0] = {
+ .start = 0xfffff680,
+ .end = 0xfffff697,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP3XX_I2C_0,
+ .end = IRQ_IOP3XX_I2C_0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device iop3xx_i2c0_device = {
+ .name = "IOP3xx-I2C",
+ .id = 0,
+ .num_resources = 2,
+ .resource = iop3xx_i2c0_resources,
+};
+
+
+static struct resource iop3xx_i2c1_resources[] = {
+ [0] = {
+ .start = 0xfffff6a0,
+ .end = 0xfffff6b7,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IOP3XX_I2C_1,
+ .end = IRQ_IOP3XX_I2C_1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device iop3xx_i2c1_device = {
+ .name = "IOP3xx-I2C",
+ .id = 1,
+ .num_resources = 2,
+ .resource = iop3xx_i2c1_resources,
+};
diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c
new file mode 100644
index 00000000..e15bc17d
--- /dev/null
+++ b/arch/arm/plat-iop/io.c
@@ -0,0 +1,59 @@
+/*
+ * iop3xx custom ioremap implementation
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * 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/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype)
+{
+ void __iomem * retval;
+
+ switch (cookie) {
+ case IOP3XX_PCI_LOWER_IO_PA ... IOP3XX_PCI_UPPER_IO_PA:
+ retval = (void *) IOP3XX_PCI_IO_PHYS_TO_VIRT(cookie);
+ break;
+ case IOP3XX_PERIPHERAL_PHYS_BASE ... IOP3XX_PERIPHERAL_UPPER_PA:
+ retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
+ break;
+ default:
+ retval = __arm_ioremap_caller(cookie, size, mtype,
+ __builtin_return_address(0));
+ }
+
+ return retval;
+}
+EXPORT_SYMBOL(__iop3xx_ioremap);
+
+void __iop3xx_iounmap(void __iomem *addr)
+{
+ extern void __iounmap(volatile void __iomem *addr);
+
+ switch ((u32) addr) {
+ case IOP3XX_PCI_LOWER_IO_VA ... IOP3XX_PCI_UPPER_IO_VA:
+ case IOP3XX_PERIPHERAL_VIRT_BASE ... IOP3XX_PERIPHERAL_UPPER_VA:
+ goto skip;
+ }
+ __iounmap(addr);
+
+skip:
+ return;
+}
+EXPORT_SYMBOL(__iop3xx_iounmap);
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
new file mode 100644
index 00000000..43f2b158
--- /dev/null
+++ b/arch/arm/plat-iop/pci.c
@@ -0,0 +1,415 @@
+/*
+ * arch/arm/plat-iop/pci.c
+ *
+ * PCI support for the Intel IOP32X and IOP33X processors
+ *
+ * Author: Rory Bolt <rorybolt@pacbell.net>
+ * Copyright (C) 2002 Rory Bolt
+ *
+ * This program is free software; you can 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/pci.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/mach/pci.h>
+#include <asm/hardware/iop3xx.h>
+
+// #define DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...) do { } while (0)
+#endif
+
+/*
+ * This routine builds either a type0 or type1 configuration command. If the
+ * bus is on the 803xx then a type0 made, else a type1 is created.
+ */
+static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where)
+{
+ struct pci_sys_data *sys = bus->sysdata;
+ u32 addr;
+
+ if (sys->busnr == bus->number)
+ addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
+ else
+ addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
+
+ addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
+
+ return addr;
+}
+
+/*
+ * This routine checks the status of the last configuration cycle. If an error
+ * was detected it returns a 1, else it returns a 0. The errors being checked
+ * are parity, master abort, target abort (master and target). These types of
+ * errors occur during a config cycle where there is no device, like during
+ * the discovery stage.
+ */
+static int iop3xx_pci_status(void)
+{
+ unsigned int status;
+ int ret = 0;
+
+ /*
+ * Check the status registers.
+ */
+ status = *IOP3XX_ATUSR;
+ if (status & 0xf900) {
+ DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status);
+ *IOP3XX_ATUSR = status & 0xf900;
+ ret = 1;
+ }
+
+ status = *IOP3XX_ATUISR;
+ if (status & 0x679f) {
+ DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status);
+ *IOP3XX_ATUISR = status & 0x679f;
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/*
+ * Simply write the address register and read the configuration
+ * data. Note that the 4 nops ensure that we are able to handle
+ * a delayed abort (in theory.)
+ */
+static u32 iop3xx_read(unsigned long addr)
+{
+ u32 val;
+
+ __asm__ __volatile__(
+ "str %1, [%2]\n\t"
+ "ldr %0, [%3]\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ : "=r" (val)
+ : "r" (addr), "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR));
+
+ return val;
+}
+
+/*
+ * The read routines must check the error status of the last configuration
+ * cycle. If there was an error, the routine returns all hex f's.
+ */
+static int
+iop3xx_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *value)
+{
+ unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
+ u32 val = iop3xx_read(addr) >> ((where & 3) * 8);
+
+ if (iop3xx_pci_status())
+ val = 0xffffffff;
+
+ *value = val;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 value)
+{
+ unsigned long addr = iop3xx_cfg_address(bus, devfn, where);
+ u32 val;
+
+ if (size != 4) {
+ val = iop3xx_read(addr);
+ if (iop3xx_pci_status())
+ return PCIBIOS_SUCCESSFUL;
+
+ where = (where & 3) * 8;
+
+ if (size == 1)
+ val &= ~(0xff << where);
+ else
+ val &= ~(0xffff << where);
+
+ *IOP3XX_OCCDR = val | value << where;
+ } else {
+ asm volatile(
+ "str %1, [%2]\n\t"
+ "str %0, [%3]\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ :
+ : "r" (value), "r" (addr),
+ "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR));
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops iop3xx_ops = {
+ .read = iop3xx_read_config,
+ .write = iop3xx_write_config,
+};
+
+/*
+ * When a PCI device does not exist during config cycles, the 80200 gets a
+ * bus error instead of returning 0xffffffff. This handler simply returns.
+ */
+static int
+iop3xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
+{
+ DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
+ addr, fsr, regs->ARM_pc, regs->ARM_lr);
+
+ /*
+ * If it was an imprecise abort, then we need to correct the
+ * return address to be _after_ the instruction.
+ */
+ if (fsr & (1 << 10))
+ regs->ARM_pc += 4;
+
+ return 0;
+}
+
+int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
+{
+ struct resource *res;
+
+ if (nr != 0)
+ return 0;
+
+ res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL);
+ if (!res)
+ panic("PCI: unable to alloc resources");
+
+ res[0].start = IOP3XX_PCI_LOWER_IO_PA;
+ res[0].end = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
+ res[0].name = "IOP3XX PCI I/O Space";
+ res[0].flags = IORESOURCE_IO;
+ request_resource(&ioport_resource, &res[0]);
+
+ res[1].start = IOP3XX_PCI_LOWER_MEM_PA;
+ res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1;
+ res[1].name = "IOP3XX PCI Memory Space";
+ res[1].flags = IORESOURCE_MEM;
+ request_resource(&iomem_resource, &res[1]);
+
+ /*
+ * Use whatever translation is already setup.
+ */
+ sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
+ sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
+
+ sys->resource[0] = &res[0];
+ sys->resource[1] = &res[1];
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
+}
+
+void __init iop3xx_atu_setup(void)
+{
+ /* BAR 0 ( Disabled ) */
+ *IOP3XX_IAUBAR0 = 0x0;
+ *IOP3XX_IABAR0 = 0x0;
+ *IOP3XX_IATVR0 = 0x0;
+ *IOP3XX_IALR0 = 0x0;
+
+ /* BAR 1 ( Disabled ) */
+ *IOP3XX_IAUBAR1 = 0x0;
+ *IOP3XX_IABAR1 = 0x0;
+ *IOP3XX_IALR1 = 0x0;
+
+ /* BAR 2 (1:1 mapping with Physical RAM) */
+ /* Set limit and enable */
+ *IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1;
+ *IOP3XX_IAUBAR2 = 0x0;
+
+ /* Align the inbound bar with the base of memory */
+ *IOP3XX_IABAR2 = PHYS_OFFSET |
+ PCI_BASE_ADDRESS_MEM_TYPE_64 |
+ PCI_BASE_ADDRESS_MEM_PREFETCH;
+
+ *IOP3XX_IATVR2 = PHYS_OFFSET;
+
+ /* Outbound window 0 */
+ *IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_BA;
+ *IOP3XX_OUMWTVR0 = 0;
+
+ /* Outbound window 1 */
+ *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA +
+ IOP3XX_PCI_MEM_WINDOW_SIZE / 2;
+ *IOP3XX_OUMWTVR1 = 0;
+
+ /* BAR 3 ( Disabled ) */
+ *IOP3XX_IAUBAR3 = 0x0;
+ *IOP3XX_IABAR3 = 0x0;
+ *IOP3XX_IATVR3 = 0x0;
+ *IOP3XX_IALR3 = 0x0;
+
+ /* Setup the I/O Bar
+ */
+ *IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_BA;
+
+ /* Enable inbound and outbound cycles
+ */
+ *IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+ *IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN;
+}
+
+void __init iop3xx_atu_disable(void)
+{
+ *IOP3XX_ATUCMD = 0;
+ *IOP3XX_ATUCR = 0;
+
+ /* wait for cycles to quiesce */
+ while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY |
+ IOP3XX_PCSR_IN_Q_BUSY))
+ cpu_relax();
+
+ /* BAR 0 ( Disabled ) */
+ *IOP3XX_IAUBAR0 = 0x0;
+ *IOP3XX_IABAR0 = 0x0;
+ *IOP3XX_IATVR0 = 0x0;
+ *IOP3XX_IALR0 = 0x0;
+
+ /* BAR 1 ( Disabled ) */
+ *IOP3XX_IAUBAR1 = 0x0;
+ *IOP3XX_IABAR1 = 0x0;
+ *IOP3XX_IALR1 = 0x0;
+
+ /* BAR 2 ( Disabled ) */
+ *IOP3XX_IAUBAR2 = 0x0;
+ *IOP3XX_IABAR2 = 0x0;
+ *IOP3XX_IATVR2 = 0x0;
+ *IOP3XX_IALR2 = 0x0;
+
+ /* BAR 3 ( Disabled ) */
+ *IOP3XX_IAUBAR3 = 0x0;
+ *IOP3XX_IABAR3 = 0x0;
+ *IOP3XX_IATVR3 = 0x0;
+ *IOP3XX_IALR3 = 0x0;
+
+ /* Clear the outbound windows */
+ *IOP3XX_OIOWTVR = 0;
+
+ /* Outbound window 0 */
+ *IOP3XX_OMWTVR0 = 0;
+ *IOP3XX_OUMWTVR0 = 0;
+
+ /* Outbound window 1 */
+ *IOP3XX_OMWTVR1 = 0;
+ *IOP3XX_OUMWTVR1 = 0;
+}
+
+/* Flag to determine whether the ATU is initialized and the PCI bus scanned */
+int init_atu;
+
+int iop3xx_get_init_atu(void) {
+ /* check if default has been overridden */
+ if (init_atu != IOP3XX_INIT_ATU_DEFAULT)
+ return init_atu;
+ else
+ return IOP3XX_INIT_ATU_DISABLE;
+}
+
+static void __init iop3xx_atu_debug(void)
+{
+ DBG("PCI: Intel IOP3xx PCI init.\n");
+ DBG("PCI: Outbound memory window 0: PCI 0x%08x%08x\n",
+ *IOP3XX_OUMWTVR0, *IOP3XX_OMWTVR0);
+ DBG("PCI: Outbound memory window 1: PCI 0x%08x%08x\n",
+ *IOP3XX_OUMWTVR1, *IOP3XX_OMWTVR1);
+ DBG("PCI: Outbound IO window: PCI 0x%08x\n",
+ *IOP3XX_OIOWTVR);
+
+ DBG("PCI: Inbound memory window 0: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
+ *IOP3XX_IAUBAR0, *IOP3XX_IABAR0, *IOP3XX_IALR0, *IOP3XX_IATVR0);
+ DBG("PCI: Inbound memory window 1: PCI 0x%08x%08x 0x%08x\n",
+ *IOP3XX_IAUBAR1, *IOP3XX_IABAR1, *IOP3XX_IALR1);
+ DBG("PCI: Inbound memory window 2: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
+ *IOP3XX_IAUBAR2, *IOP3XX_IABAR2, *IOP3XX_IALR2, *IOP3XX_IATVR2);
+ DBG("PCI: Inbound memory window 3: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
+ *IOP3XX_IAUBAR3, *IOP3XX_IABAR3, *IOP3XX_IALR3, *IOP3XX_IATVR3);
+
+ DBG("PCI: Expansion ROM window: PCI 0x%08x%08x 0x%08x -> 0x%08x\n",
+ 0, *IOP3XX_ERBAR, *IOP3XX_ERLR, *IOP3XX_ERTVR);
+
+ DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
+ DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR);
+
+ hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, 0, "imprecise external abort");
+}
+
+/* for platforms that might be host-bus-adapters */
+void __init iop3xx_pci_preinit_cond(void)
+{
+ if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) {
+ iop3xx_atu_disable();
+ iop3xx_atu_setup();
+ iop3xx_atu_debug();
+ }
+}
+
+void __init iop3xx_pci_preinit(void)
+{
+ iop3xx_atu_disable();
+ iop3xx_atu_setup();
+ iop3xx_atu_debug();
+}
+
+/* allow init_atu to be user overridden */
+static int __init iop3xx_init_atu_setup(char *str)
+{
+ init_atu = IOP3XX_INIT_ATU_DEFAULT;
+ if (str) {
+ while (*str != '\0') {
+ switch (*str) {
+ case 'y':
+ case 'Y':
+ init_atu = IOP3XX_INIT_ATU_ENABLE;
+ break;
+ case 'n':
+ case 'N':
+ init_atu = IOP3XX_INIT_ATU_DISABLE;
+ break;
+ case ',':
+ case '=':
+ break;
+ default:
+ printk(KERN_DEBUG "\"%s\" malformed at "
+ "character: \'%c\'",
+ __func__,
+ *str);
+ *(str + 1) = '\0';
+ }
+ str++;
+ }
+ }
+
+ return 1;
+}
+
+__setup("iop3xx_init_atu", iop3xx_init_atu_setup);
+
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
new file mode 100644
index 00000000..a2024b86
--- /dev/null
+++ b/arch/arm/plat-iop/pmu.c
@@ -0,0 +1,40 @@
+/*
+ * PMU IRQ registration for the iop3xx xscale PMU families.
+ * Copyright (C) 2010 Will Deacon, ARM 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/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource pmu_resource = {
+#ifdef CONFIG_ARCH_IOP32X
+ .start = IRQ_IOP32X_CORE_PMU,
+ .end = IRQ_IOP32X_CORE_PMU,
+#endif
+#ifdef CONFIG_ARCH_IOP33X
+ .start = IRQ_IOP33X_CORE_PMU,
+ .end = IRQ_IOP33X_CORE_PMU,
+#endif
+ .flags = IORESOURCE_IRQ,
+};
+
+static struct platform_device pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .resource = &pmu_resource,
+ .num_resources = 1,
+};
+
+static int __init iop3xx_pmu_init(void)
+{
+ platform_device_register(&pmu_device);
+ return 0;
+}
+
+arch_initcall(iop3xx_pmu_init);
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
new file mode 100644
index 00000000..bade586f
--- /dev/null
+++ b/arch/arm/plat-iop/setup.c
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/plat-iop/setup.c
+ *
+ * Author: Nicolas Pitre <nico@fluxnic.net>
+ * Copyright (C) 2001 MontaVista Software, Inc.
+ * Copyright (C) 2004 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/iop3xx.h>
+
+/*
+ * Standard IO mapping for all IOP3xx based systems. Note that
+ * the IOP3xx OCCDR must be mapped uncached and unbuffered.
+ */
+static struct map_desc iop3xx_std_desc[] __initdata = {
+ { /* mem mapped registers */
+ .virtual = IOP3XX_PERIPHERAL_VIRT_BASE,
+ .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE),
+ .length = IOP3XX_PERIPHERAL_SIZE,
+ .type = MT_UNCACHED,
+ }, { /* PCI IO space */
+ .virtual = IOP3XX_PCI_LOWER_IO_VA,
+ .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA),
+ .length = IOP3XX_PCI_IO_WINDOW_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init iop3xx_map_io(void)
+{
+ iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc));
+}
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
new file mode 100644
index 00000000..7cdc5161
--- /dev/null
+++ b/arch/arm/plat-iop/time.c
@@ -0,0 +1,184 @@
+/*
+ * arch/arm/plat-iop/time.c
+ *
+ * Timer code for IOP32x and IOP33x based systems
+ *
+ * Author: Deepak Saxena <dsaxena@mvista.com>
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/sched_clock.h>
+#include <asm/uaccess.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <mach/time.h>
+
+/*
+ * Minimum clocksource/clockevent timer range in seconds
+ */
+#define IOP_MIN_RANGE 4
+
+/*
+ * IOP clocksource (free-running timer 1).
+ */
+static cycle_t notrace iop_clocksource_read(struct clocksource *unused)
+{
+ return 0xffffffffu - read_tcr1();
+}
+
+static struct clocksource iop_clocksource = {
+ .name = "iop_timer1",
+ .rating = 300,
+ .read = iop_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * IOP sched_clock() implementation via its clocksource.
+ */
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = 0xffffffffu - read_tcr1();
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace iop_update_sched_clock(void)
+{
+ u32 cyc = 0xffffffffu - read_tcr1();
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/*
+ * IOP clockevents (interrupting timer 0).
+ */
+static int iop_set_next_event(unsigned long delta,
+ struct clock_event_device *unused)
+{
+ u32 tmr = IOP_TMR_PRIVILEGED | IOP_TMR_RATIO_1_1;
+
+ BUG_ON(delta == 0);
+ write_tmr0(tmr & ~(IOP_TMR_EN | IOP_TMR_RELOAD));
+ write_tcr0(delta);
+ write_tmr0((tmr & ~IOP_TMR_RELOAD) | IOP_TMR_EN);
+
+ return 0;
+}
+
+static unsigned long ticks_per_jiffy;
+
+static void iop_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *unused)
+{
+ u32 tmr = read_tmr0();
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ write_tmr0(tmr & ~IOP_TMR_EN);
+ write_tcr0(ticks_per_jiffy - 1);
+ write_trr0(ticks_per_jiffy - 1);
+ tmr |= (IOP_TMR_RELOAD | IOP_TMR_EN);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* ->set_next_event sets period and enables timer */
+ tmr &= ~(IOP_TMR_RELOAD | IOP_TMR_EN);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ tmr |= IOP_TMR_EN;
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ default:
+ tmr &= ~IOP_TMR_EN;
+ break;
+ }
+
+ write_tmr0(tmr);
+}
+
+static struct clock_event_device iop_clockevent = {
+ .name = "iop_timer0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 300,
+ .set_next_event = iop_set_next_event,
+ .set_mode = iop_set_mode,
+};
+
+static irqreturn_t
+iop_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ write_tisr(1);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction iop_timer_irq = {
+ .name = "IOP Timer Tick",
+ .handler = iop_timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .dev_id = &iop_clockevent,
+};
+
+static unsigned long iop_tick_rate;
+unsigned long get_iop_tick_rate(void)
+{
+ return iop_tick_rate;
+}
+EXPORT_SYMBOL(get_iop_tick_rate);
+
+void __init iop_init_time(unsigned long tick_rate)
+{
+ u32 timer_ctl;
+
+ init_sched_clock(&cd, iop_update_sched_clock, 32, tick_rate);
+
+ ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
+ iop_tick_rate = tick_rate;
+
+ timer_ctl = IOP_TMR_EN | IOP_TMR_PRIVILEGED |
+ IOP_TMR_RELOAD | IOP_TMR_RATIO_1_1;
+
+ /*
+ * Set up interrupting clockevent timer 0.
+ */
+ write_tmr0(timer_ctl & ~IOP_TMR_EN);
+ write_tisr(1);
+ setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
+ clockevents_calc_mult_shift(&iop_clockevent,
+ tick_rate, IOP_MIN_RANGE);
+ iop_clockevent.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &iop_clockevent);
+ iop_clockevent.min_delta_ns =
+ clockevent_delta2ns(0xf, &iop_clockevent);
+ iop_clockevent.cpumask = cpumask_of(0);
+ clockevents_register_device(&iop_clockevent);
+
+ /*
+ * Set up free-running clocksource timer 1.
+ */
+ write_trr1(0xffffffff);
+ write_tcr1(0xffffffff);
+ write_tmr1(timer_ctl);
+ clocksource_register_hz(&iop_clocksource, tick_rate);
+}
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
new file mode 100644
index 00000000..f0ba0726
--- /dev/null
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+
+#include <mach/hardware.h>
+
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR(n) (n + 0x0)
+/* External UART */
+#define UARTA_BASE_ADDR(n) (n + 0x8000)
+#define UARTB_BASE_ADDR(n) (n + 0x10000)
+
+#define BOARD_IO_ADDR(n) (n + 0x20000)
+/* LED switchs */
+#define LED_SWITCH_REG 0x00
+/* buttons */
+#define SWITCH_BUTTONS_REG 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG 0x10
+#define INTR_MASK_REG 0x38
+#define INTR_RESET_REG 0x20
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG 0x40
+#define MAGIC_NUMBER2_REG 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG 0x50
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER3_REG 0x58
+/* module reset register*/
+#define MODULE_RESET_REG 0x60
+/* CPU ID and Personality ID */
+#define MCU_BOARD_ID_REG 0x68
+
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS)
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+#define MXC_MAX_EXP_IO_LINES 16
+
+/* interrupts like external uart , external ethernet etc*/
+#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0)
+#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1)
+#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2)
+#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3)
+#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4)
+
+static void __iomem *brd_io;
+
+static struct resource smsc911x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ } , {
+ .start = EXPIO_INT_ENET,
+ .end = EXPIO_INT_ENET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ /* irq = gpio irq number */
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+ imr_val = __raw_readw(brd_io + INTR_MASK_REG);
+ int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
+
+ expio_irq = MXC_BOARD_IRQ_START;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ if ((int_valid & 1) == 0)
+ continue;
+ generic_handle_irq(expio_irq);
+ }
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * Irq is an expio virtual irq number
+ */
+static void expio_mask_irq(struct irq_data *d)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg |= (1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static void expio_ack_irq(struct irq_data *d)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+
+ __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ expio_mask_irq(d);
+}
+
+static void expio_unmask_irq(struct irq_data *d)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg &= ~(1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .irq_ack = expio_ack_irq,
+ .irq_mask = expio_mask_irq,
+ .irq_unmask = expio_unmask_irq,
+};
+
+int __init mxc_expio_init(u32 base, u32 p_irq)
+{
+ int i;
+
+ brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K);
+ if (brd_io == NULL)
+ return -ENOMEM;
+
+ if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
+ pr_info("3-Stack Debug board not detected\n");
+ iounmap(brd_io);
+ brd_io = NULL;
+ return -ENODEV;
+ }
+
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
+ readw(brd_io + CPLD_CODE_VER_REG));
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq");
+ gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq));
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0, brd_io + INTR_MASK_REG);
+ __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ __raw_writew(0x1F, brd_io + INTR_MASK_REG);
+ for (i = MXC_EXP_IO_BASE;
+ i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) {
+ irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ irq_set_irq_type(p_irq, IRQF_TRIGGER_LOW);
+ irq_set_chained_handler(p_irq, mxc_expio_irq_handler);
+
+ /* Register Lan device on the debugboard */
+ smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
+ smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
+ platform_device_register(&smsc_lan9217_device);
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
new file mode 100755
index 00000000..32408ed9
--- /dev/null
+++ b/arch/arm/plat-mxc/Kconfig
@@ -0,0 +1,173 @@
+if ARCH_MXC
+
+source "arch/arm/plat-mxc/devices/Kconfig"
+
+menu "Freescale MXC Implementations"
+
+config ARCH_MX50_SUPPORTED
+ bool
+
+config ARCH_MX53_SUPPORTED
+ bool
+
+choice
+ prompt "Freescale CPU family:"
+ default ARCH_MX3
+
+config ARCH_MX1
+ bool "MX1-based"
+ help
+ This enables support for systems based on the Freescale i.MX1 family
+
+config ARCH_MX2
+ bool "MX2-based"
+ help
+ This enables support for systems based on the Freescale i.MX2 family
+
+config ARCH_MX25
+ bool "MX25-based"
+ help
+ This enables support for systems based on the Freescale i.MX25 family
+
+config ARCH_MX3
+ bool "MX3-based"
+ help
+ This enables support for systems based on the Freescale i.MX3 family
+
+config ARCH_MX503
+ bool "i.MX50 + i.MX53"
+ select ARCH_MX50_SUPPORTED
+ select ARCH_MX53_SUPPORTED
+ help
+ This enables support for machines using Freescale's i.MX50 and i.MX51
+ processors.
+
+config ARCH_MX51
+ bool "i.MX51"
+ select ARCH_MX51_SUPPORTED
+ help
+ This enables support for systems based on the Freescale i.MX51 family
+
+config ARCH_MX6
+ bool "MX6-based"
+ select CPU_V7
+ help
+ This enable support for systems based on the Freescale i.MX 6 Series family
+
+endchoice
+
+source "arch/arm/mach-imx/Kconfig"
+source "arch/arm/mach-mx5/Kconfig"
+source "arch/arm/mach-mx6/Kconfig"
+
+endmenu
+## Freescale private USB driver support
+# set if we need the 1504 transceiver
+config ISP1504_MXC
+ bool
+ default y
+
+# set if we need the UTMI transceiver
+config UTMI_MXC
+ bool
+ default y
+ depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX37 || ARCH_MX5
+
+config MXC_IRQ_PRIOR
+ bool "Use IRQ priority"
+ help
+ Select this if you want to use prioritized IRQ handling.
+ This feature prevents higher priority ISR to be interrupted
+ by lower priority IRQ even IRQF_DISABLED flag is not set.
+ This may be useful in embedded applications, where are strong
+ requirements for timing.
+ Say N here, unless you have a specialized requirement.
+
+config MXC_TZIC
+ bool
+
+config MXC_AVIC
+ bool
+
+config MXC_PWM
+ tristate "Enable PWM driver"
+ select HAVE_PWM
+ help
+ Enable support for the i.MX PWM controller(s).
+
+config MXC_DEBUG_BOARD
+ bool "Enable MXC debug board(for 3-stack)"
+ help
+ The debug board is an integral part of the MXC 3-stack(PDK)
+ platforms, it can be attached or removed from the peripheral
+ board. On debug board, several debug devices(ethernet, UART,
+ buttons, LEDs and JTAG) are implemented. Between the MCU and
+ these devices, a CPLD is added as a bridge which performs
+ data/address de-multiplexing and decode, signal level shift,
+ interrupt control and various board functions.
+
+config HAVE_EPIT
+ bool
+
+config MXC_REBOOT_MFGMODE
+ bool "Enable reboot to MFG mode function"
+ help
+ Enable this config to perform "reboot download" to enter download mode.
+
+config MXC_REBOOT_ANDROID_CMD
+ bool "Enable reboot to android recovery and android fastboot"
+ help
+ Enable this config to use "reboot fastboot", "reboot recovery" to
+ enter fastboot and recovery mode.
+
+config MXC_USE_EPIT
+ bool "Use EPIT instead of GPT"
+ depends on HAVE_EPIT
+ help
+ Use EPIT as the system timer on systems that have it. Normally you
+ don't have a reason to do so as the EPIT has the same features and
+ uses the same clocks as the GPT. Anyway, on some systems the GPT
+ may be in use for other purposes.
+
+config MXC_ULPI
+ bool
+
+config ARCH_HAS_RNGA
+ bool
+
+config ARCH_HAS_RNGC
+ bool
+
+config IMX_HAVE_IOMUX_V1
+ bool
+
+config ARCH_MXC_IOMUX_V3
+ bool
+
+config ARCH_MXC_AUDMUX_V1
+ bool
+
+config ARCH_MXC_AUDMUX_V2
+ bool
+
+config IRAM_ALLOC
+ bool
+ default y
+ select GENERIC_ALLOCATOR
+
+config CLK_DEBUG
+ bool "clock debug information export to user space"
+ depends on PM_DEBUG && DEBUG_FS
+ default n
+ help
+ export clk debug information to user space
+
+config DMA_ZONE_SIZE
+ int "DMA memory zone size"
+ range 0 184
+ default 24
+ help
+ This is the size in MB for the DMA zone. The DMA zone is used for
+ dedicated memory for large contiguous video buffers
+
+endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
new file mode 100755
index 00000000..1aa17802
--- /dev/null
+++ b/arch/arm/plat-mxc/Makefile
@@ -0,0 +1,40 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o gpio.o time.o devices.o cpu.o system.o irq-common.o usb_common.o usb_wakeup.o fuse.o
+
+# MX51 uses the TZIC interrupt controller, older platforms use AVIC
+obj-$(CONFIG_MXC_TZIC) += tzic.o
+obj-$(CONFIG_MXC_AVIC) += avic.o
+
+obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
+obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
+obj-$(CONFIG_MXC_PWM) += pwm.o
+obj-$(CONFIG_MXC_ULPI) += ulpi.o
+obj-$(CONFIG_MXC_USE_EPIT) += epit.o
+obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
+obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
+obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
+obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += ahci_sata.o
+ifdef CONFIG_SND_IMX_SOC
+obj-y += ssi-fiq.o
+obj-y += ssi-fiq-ksym.o
+endif
+
+obj-y += devices/
+
+obj-$(CONFIG_ARCH_MX5) += dvfs_core.o
+obj-$(CONFIG_ARCH_MX6) += dvfs_core.o
+
+# DVFS-PER support
+obj-$(CONFIG_MXC_DVFS_PER) += dvfs_per.o
+
+# USB support
+obj-$(CONFIG_ISP1504_MXC) += isp1504xc.o
+obj-$(CONFIG_USB) += utmixc.o
+obj-$(CONFIG_USB) += serialxc.o
+obj-$(CONFIG_USB) += usb_hsic_xcvr.o
diff --git a/arch/arm/plat-mxc/ahci_sata.c b/arch/arm/plat-mxc/ahci_sata.c
new file mode 100644
index 00000000..de172a94
--- /dev/null
+++ b/arch/arm/plat-mxc/ahci_sata.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/errno.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <mach/hardware.h>
+#include <mach/ahci_sata.h>
+
+int write_phy_ctl_ack_polling(u32 data, void __iomem *mmio,
+ int max_iterations, u32 exp_val)
+{
+ u32 i, val;
+
+ writel(data, mmio + PORT_PHY_CTL);
+
+ for (i = 0; i < max_iterations + 1; i++) {
+ val = readl(mmio + PORT_PHY_SR);
+ val = (val >> PORT_PHY_STAT_ACK_LOC) & 0x1;
+ if (val == exp_val)
+ return 0;
+ if (i == max_iterations) {
+ pr_err("Wait for CR ACK error!\n");
+ return 1;
+ }
+ usleep_range(100, 200);
+ }
+ return 0;
+}
+
+int sata_phy_cr_addr(u32 addr, void __iomem *mmio)
+{
+ u32 temp_wr_data;
+
+ /* write addr */
+ temp_wr_data = addr;
+ writel(temp_wr_data, mmio + PORT_PHY_CTL);
+
+ /* capture addr */
+ temp_wr_data |= PORT_PHY_CTL_CAP_ADR_LOC;
+
+ /* wait for ack */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 1))
+ return 1;
+
+ /* deassert cap addr */
+ temp_wr_data &= 0xffff;
+
+ /* wait for ack de-assetion */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 0))
+ return 1;
+
+ return 0;
+}
+
+int sata_phy_cr_write(u32 data, void __iomem *mmio)
+{
+ u32 temp_wr_data;
+
+ /* write data */
+ temp_wr_data = data;
+
+ /* capture data */
+ temp_wr_data |= PORT_PHY_CTL_CAP_DAT_LOC;
+
+ /* wait for ack */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 1))
+ return 1;
+
+ /* deassert cap data */
+ temp_wr_data &= 0xffff;
+
+ /* wait for ack de-assetion */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 0))
+ return 1;
+
+ /* assert wr signal */
+ temp_wr_data |= PORT_PHY_CTL_WRITE_LOC;
+
+ /* wait for ack */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 1))
+ return 1;
+
+ /* deassert wr _signal */
+ temp_wr_data = 0x0;
+
+ /* wait for ack de-assetion */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 0))
+ return 1;
+
+ return 0;
+}
+
+int sata_phy_cr_read(u32 *data, void __iomem *mmio)
+{
+ u32 temp_rd_data, temp_wr_data;
+
+ /* assert rd signal */
+ temp_wr_data = PORT_PHY_CTL_READ_LOC;
+
+ /* wait for ack */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 1))
+ return 1;
+
+ /* after got ack return data */
+ temp_rd_data = readl(mmio + PORT_PHY_SR);
+ *data = (temp_rd_data & 0xffff);
+
+ /* deassert rd _signal */
+ temp_wr_data = 0x0 ;
+
+ /* wait for ack de-assetion */
+ if (write_phy_ctl_ack_polling(temp_wr_data, mmio, 100, 0))
+ return 1;
+
+ return 0;
+}
+
+/* AHCI module Initialization, if return 0, initialization is successful. */
+int sata_init(void __iomem *addr, unsigned long timer1ms)
+{
+ u32 tmpdata;
+ int iterations = 20;
+
+ /*
+ * Make sure that SATA PHY is enabled
+ * The PDDQ mode is disabled.
+ */
+ tmpdata = readl(addr + PORT_PHY_CTL);
+ writel(tmpdata & (~PORT_PHY_CTL_PDDQ_LOC), addr + PORT_PHY_CTL);
+
+ /* Reset HBA */
+ writel(HOST_RESET, addr + HOST_CTL);
+
+ tmpdata = 0;
+ while (readl(addr + HOST_CAP) == 0) {
+ tmpdata++;
+ if (tmpdata > 100000) {
+ pr_err("Can't recover from RESET HBA!\n");
+ break;
+ }
+ }
+
+ tmpdata = readl(addr + HOST_CAP);
+ if (!(tmpdata & HOST_CAP_SSS)) {
+ tmpdata |= HOST_CAP_SSS;
+ writel(tmpdata, addr + HOST_CAP);
+ }
+
+ if (!(readl(addr + HOST_PORTS_IMPL) & 0x1))
+ writel((readl(addr + HOST_PORTS_IMPL) | 0x1),
+ addr + HOST_PORTS_IMPL);
+
+ writel(timer1ms, addr + HOST_TIMER1MS);
+
+ /* Release resources when there is no device on the port */
+ do {
+ if ((readl(addr + PORT_SATA_SR) & 0xF) == 0)
+ usleep_range(1000, 2000);
+ else
+ break;
+
+ if (iterations == 0) {
+ pr_info("No sata disk.\n");
+ /* Enter into PDDQ mode, save power */
+ tmpdata = readl(addr + PORT_PHY_CTL);
+ writel(tmpdata | PORT_PHY_CTL_PDDQ_LOC,
+ addr + PORT_PHY_CTL);
+ return -ENODEV;
+ }
+ } while (iterations-- > 0);
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/audmux-v1.c b/arch/arm/plat-mxc/audmux-v1.c
new file mode 100644
index 00000000..1180bef7
--- /dev/null
+++ b/arch/arm/plat-mxc/audmux-v1.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <mach/audmux.h>
+#include <mach/hardware.h>
+
+static void __iomem *audmux_base;
+
+static unsigned char port_mapping[] = {
+ 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
+};
+
+int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
+{
+ if (!audmux_base) {
+ printk("%s: not configured\n", __func__);
+ return -ENOSYS;
+ }
+
+ if (port >= ARRAY_SIZE(port_mapping))
+ return -EINVAL;
+
+ writel(pcr, audmux_base + port_mapping[port]);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
+
+static int mxc_audmux_v1_init(void)
+{
+#ifdef CONFIG_MACH_MX21
+ if (cpu_is_mx21())
+ audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
+ else
+#endif
+#ifdef CONFIG_MACH_MX27
+ if (cpu_is_mx27())
+ audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
+ else
+#endif
+ (void)0;
+
+ return 0;
+}
+
+postcore_initcall(mxc_audmux_v1_init);
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
new file mode 100644
index 00000000..c36ddb34
--- /dev/null
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Initial development of this code was funded by
+ * Phytec Messtechnik GmbH, http://www.phytec.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <mach/audmux.h>
+#include <mach/hardware.h>
+
+static struct clk *audmux_clk;
+static void __iomem *audmux_base;
+
+#define MXC_AUDMUX_V2_PTCR(x) ((x) * 8)
+#define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *audmux_debugfs_root;
+
+static int audmux_open_file(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+/* There is an annoying discontinuity in the SSI numbering with regard
+ * to the Linux number of the devices */
+static const char *audmux_port_string(int port)
+{
+ switch (port) {
+ case MX31_AUDMUX_PORT1_SSI0:
+ return "imx-ssi.0";
+ case MX31_AUDMUX_PORT2_SSI1:
+ return "imx-ssi.1";
+ case MX31_AUDMUX_PORT3_SSI_PINS_3:
+ return "SSI3";
+ case MX31_AUDMUX_PORT4_SSI_PINS_4:
+ return "SSI4";
+ case MX31_AUDMUX_PORT5_SSI_PINS_5:
+ return "SSI5";
+ case MX31_AUDMUX_PORT6_SSI_PINS_6:
+ return "SSI6";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ ssize_t ret;
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ int port = (int)file->private_data;
+ u32 pdcr, ptcr;
+
+ if (!buf)
+ return -ENOMEM;
+
+ if (audmux_clk)
+ clk_enable(audmux_clk);
+
+ ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
+ pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
+
+ if (audmux_clk)
+ clk_disable(audmux_clk);
+
+ ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
+ pdcr, ptcr);
+
+ if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "TxFS output from %s, ",
+ audmux_port_string((ptcr >> 27) & 0x7));
+ else
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "TxFS input, ");
+
+ if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "TxClk output from %s",
+ audmux_port_string((ptcr >> 22) & 0x7));
+ else
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "TxClk input");
+
+ ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
+
+ if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) {
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "Port is symmetric");
+ } else {
+ if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "RxFS output from %s, ",
+ audmux_port_string((ptcr >> 17) & 0x7));
+ else
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "RxFS input, ");
+
+ if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR)
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "RxClk output from %s",
+ audmux_port_string((ptcr >> 12) & 0x7));
+ else
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "RxClk input");
+ }
+
+ ret += snprintf(buf + ret, PAGE_SIZE - ret,
+ "\nData received from %s\n",
+ audmux_port_string((pdcr >> 13) & 0x7));
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations audmux_debugfs_fops = {
+ .open = audmux_open_file,
+ .read = audmux_read_file,
+ .llseek = default_llseek,
+};
+
+static void audmux_debugfs_init(void)
+{
+ int i;
+ char buf[20];
+
+ audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
+ if (!audmux_debugfs_root) {
+ pr_warning("Failed to create AUDMUX debugfs root\n");
+ return;
+ }
+
+ for (i = 1; i < 8; i++) {
+ snprintf(buf, sizeof(buf), "ssi%d", i);
+ if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
+ (void *)i, &audmux_debugfs_fops))
+ pr_warning("Failed to create AUDMUX port %d debugfs file\n",
+ i);
+ }
+}
+#else
+static inline void audmux_debugfs_init(void)
+{
+}
+#endif
+
+int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+ unsigned int pdcr)
+{
+ if (!audmux_base)
+ return -ENOSYS;
+
+ if (audmux_clk)
+ clk_enable(audmux_clk);
+
+ writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
+ writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
+
+ if (audmux_clk)
+ clk_disable(audmux_clk);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
+
+static int mxc_audmux_v2_init(void)
+{
+ int ret = -1;
+
+#if defined(CONFIG_ARCH_MX6)
+ audmux_base = MX6_IO_ADDRESS(MX6Q_AUDMUX_BASE_ADDR);
+ ret = 0;
+#endif
+#if defined(CONFIG_ARCH_MX5)
+ if (cpu_is_mx51()) {
+ audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
+ ret = 0;
+ return ret;
+ }
+#endif
+#if defined(CONFIG_ARCH_MX3)
+ if (cpu_is_mx31())
+ audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
+
+ else if (cpu_is_mx35()) {
+ audmux_clk = clk_get(NULL, "audmux");
+ if (IS_ERR(audmux_clk)) {
+ ret = PTR_ERR(audmux_clk);
+ printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
+ ret);
+ return ret;
+ }
+ audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
+ }
+#endif
+#if defined(CONFIG_SOC_IMX25)
+ if (cpu_is_mx25()) {
+ audmux_clk = clk_get(NULL, "audmux");
+ if (IS_ERR(audmux_clk)) {
+ ret = PTR_ERR(audmux_clk);
+ printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
+ ret);
+ return ret;
+ }
+ audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
+ }
+#endif /* if defined(CONFIG_SOC_IMX25) */
+ audmux_debugfs_init();
+
+ return 0;
+}
+
+postcore_initcall(mxc_audmux_v2_init);
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
new file mode 100644
index 00000000..09e2bd0f
--- /dev/null
+++ b/arch/arm/plat-mxc/avic.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/common.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+
+#include "irq-common.h"
+
+#define AVIC_INTCNTL 0x00 /* int control reg */
+#define AVIC_NIMASK 0x04 /* int mask reg */
+#define AVIC_INTENNUM 0x08 /* int enable number reg */
+#define AVIC_INTDISNUM 0x0C /* int disable number reg */
+#define AVIC_INTENABLEH 0x10 /* int enable reg high */
+#define AVIC_INTENABLEL 0x14 /* int enable reg low */
+#define AVIC_INTTYPEH 0x18 /* int type reg high */
+#define AVIC_INTTYPEL 0x1C /* int type reg low */
+#define AVIC_NIPRIORITY(x) (0x20 + 4 * (7 - (x))) /* int priority */
+#define AVIC_NIVECSR 0x40 /* norm int vector/status */
+#define AVIC_FIVECSR 0x44 /* fast int vector/status */
+#define AVIC_INTSRCH 0x48 /* int source reg high */
+#define AVIC_INTSRCL 0x4C /* int source reg low */
+#define AVIC_INTFRCH 0x50 /* int force reg high */
+#define AVIC_INTFRCL 0x54 /* int force reg low */
+#define AVIC_NIPNDH 0x58 /* norm int pending high */
+#define AVIC_NIPNDL 0x5C /* norm int pending low */
+#define AVIC_FIPNDH 0x60 /* fast int pending high */
+#define AVIC_FIPNDL 0x64 /* fast int pending low */
+
+void __iomem *avic_base;
+
+#ifdef CONFIG_MXC_IRQ_PRIOR
+static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
+{
+ unsigned int temp;
+ unsigned int mask = 0x0F << irq % 8 * 4;
+
+ if (irq >= MXC_INTERNAL_IRQS)
+ return -EINVAL;;
+
+ temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8));
+ temp &= ~mask;
+ temp |= prio & mask;
+
+ __raw_writel(temp, avic_base + AVIC_NIPRIORITY(irq / 8));
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_FIQ
+static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ unsigned int irqt;
+
+ if (irq >= MXC_INTERNAL_IRQS)
+ return -EINVAL;
+
+ if (irq < MXC_INTERNAL_IRQS / 2) {
+ irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq);
+ __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL);
+ } else {
+ irq -= MXC_INTERNAL_IRQS / 2;
+ irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq);
+ __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH);
+ }
+
+ return 0;
+}
+#endif /* CONFIG_FIQ */
+
+/* Disable interrupt number "irq" in the AVIC */
+static void mxc_mask_irq(struct irq_data *d)
+{
+ __raw_writel(d->irq, avic_base + AVIC_INTDISNUM);
+}
+
+/* Enable interrupt number "irq" in the AVIC */
+static void mxc_unmask_irq(struct irq_data *d)
+{
+ __raw_writel(d->irq, avic_base + AVIC_INTENNUM);
+}
+
+static struct mxc_irq_chip mxc_avic_chip = {
+ .base = {
+ .irq_ack = mxc_mask_irq,
+ .irq_mask = mxc_mask_irq,
+ .irq_unmask = mxc_unmask_irq,
+ },
+#ifdef CONFIG_MXC_IRQ_PRIOR
+ .set_priority = avic_irq_set_priority,
+#endif
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = avic_set_irq_fiq,
+#endif
+};
+
+/*
+ * This function initializes the AVIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init mxc_init_irq(void __iomem *irqbase)
+{
+ int i;
+
+ avic_base = irqbase;
+
+ /* put the AVIC into the reset value with
+ * all interrupts disabled
+ */
+ __raw_writel(0, avic_base + AVIC_INTCNTL);
+ __raw_writel(0x1f, avic_base + AVIC_NIMASK);
+
+ /* disable all interrupts */
+ __raw_writel(0, avic_base + AVIC_INTENABLEH);
+ __raw_writel(0, avic_base + AVIC_INTENABLEL);
+
+ /* all IRQ no FIQ */
+ __raw_writel(0, avic_base + AVIC_INTTYPEH);
+ __raw_writel(0, avic_base + AVIC_INTTYPEL);
+ for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+ irq_set_chip_and_handler(i, &mxc_avic_chip.base,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ /* Set default priority value (0) for all IRQ's */
+ for (i = 0; i < 8; i++)
+ __raw_writel(0, avic_base + AVIC_NIPRIORITY(i));
+
+#ifdef CONFIG_FIQ
+ /* Initialize FIQ */
+ init_FIQ();
+#endif
+
+ printk(KERN_INFO "MXC IRQ initialized\n");
+}
+
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
new file mode 100755
index 00000000..93347eb1
--- /dev/null
+++ b/arch/arm/plat-mxc/clock.c
@@ -0,0 +1,437 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/hardirq.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+extern int dvfs_core_is_active;
+extern void bus_freq_update(struct clk *clk, bool flag);
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ if (!clk->usecount) {
+ WARN(1, "clock enable/disable mismatch! clk %s\n", clk->name);
+ return;
+ }
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ /* unsigned long flags; */
+ int ret = 0;
+
+ if (in_interrupt()) {
+ printk(KERN_ERR " clk_enable cannot be called in an interrupt context\n");
+ dump_stack();
+ BUG();
+ }
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if ((clk->flags & AHB_HIGH_SET_POINT) ||
+ (clk->flags & AHB_MED_SET_POINT) ||
+ (clk->flags & AHB_AUDIO_SET_POINT) ||
+ (clk->flags & CPU_FREQ_TRIG_UPDATE))
+ bus_freq_update(clk, true);
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ /* unsigned long flags; */
+
+ if (in_interrupt()) {
+ printk(KERN_ERR " clk_disable cannot be called in an interrupt context\n");
+ dump_stack();
+ BUG();
+ }
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ if ((clk->flags & AHB_HIGH_SET_POINT) ||
+ (clk->flags & AHB_MED_SET_POINT) ||
+ (clk->flags & AHB_AUDIO_SET_POINT) ||
+ (clk->flags & CPU_FREQ_TRIG_UPDATE))
+ bus_freq_update(clk, false);
+}
+
+EXPORT_SYMBOL(clk_disable);
+
+/*!
+ * @brief Function to get the usage count for the requested clock.
+ *
+ * This function returns the reference count for the clock.
+ *
+ * @param clk Handle to clock to disable.
+ *
+ * @return Returns the usage count for the requested clock.
+ */
+int clk_get_usecount(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0;
+
+ return clk->usecount;
+}
+
+EXPORT_SYMBOL(clk_get_usecount);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+
+ if (clk->usecount) {
+ if (in_interrupt()) {
+ printk(KERN_ERR " clk_enable cannot be called in an interrupt context\n");
+ dump_stack();
+ mutex_unlock(&clocks_mutex);
+ BUG();
+ }
+ __clk_enable(parent);
+ }
+
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ if (clk->usecount)
+ __clk_disable(old);
+
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+/*
+ * Get the resulting clock rate from a PLL register value and the input
+ * frequency. PLLs with this register layout can at least be found on
+ * MX1, MX21, MX27 and MX31
+ *
+ * mfi + mfn / (mfd + 1)
+ * f = 2 * f_ref * --------------------
+ * pd + 1
+ */
+unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
+{
+ long long ll;
+ int mfn_abs;
+ unsigned int mfi, mfn, mfd, pd;
+
+ mfi = (reg_val >> 10) & 0xf;
+ mfn = reg_val & 0x3ff;
+ mfd = (reg_val >> 16) & 0x3ff;
+ pd = (reg_val >> 26) & 0xf;
+
+ mfi = mfi <= 5 ? 5 : mfi;
+
+ mfn_abs = mfn;
+
+ /* On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit
+ * 2's complements number
+ */
+ if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
+ mfn_abs = 0x400 - mfn;
+
+ freq *= 2;
+ freq /= pd + 1;
+
+ ll = (unsigned long long)freq * mfn_abs;
+
+ do_div(ll, mfd + 1);
+
+ if (!cpu_is_mx1() && !cpu_is_mx21() && mfn >= 0x200)
+ ll = -ll;
+
+ ll = (freq * mfi) + ll;
+
+ return ll;
+}
+
+#ifdef CONFIG_CLK_DEBUG
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+static int clk_debug_rate_get(void *data, u64 *val)
+{
+ struct clk *clk = data;
+
+ *val = (u64)clk_get_rate(clk);
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(clk_debug_rate_fops, clk_debug_rate_get, NULL,
+ "%llu\n");
+
+
+static struct dentry *clk_root;
+static int clk_debug_register_one(struct clk *clk)
+{
+ int err;
+ struct dentry *d, *child, *child_tmp;
+ struct clk *pa = clk_get_parent(clk);
+
+ if (pa && !IS_ERR(pa))
+ d = debugfs_create_dir(clk->name, pa->dentry);
+ else {
+ if (!clk_root)
+ clk_root = debugfs_create_dir("clock", NULL);
+ if (!clk_root)
+ return -ENOMEM;
+ d = debugfs_create_dir(clk->name, clk_root);
+ }
+
+ if (!d)
+ return -ENOMEM;
+
+ clk->dentry = d;
+
+ d = debugfs_create_u8("usecount", S_IRUGO, clk->dentry,
+ (u8 *)&clk->usecount);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ d = debugfs_create_file("rate", S_IRUGO, clk->dentry, (void *)clk,
+ &clk_debug_rate_fops);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ d = debugfs_create_u32("flags", S_IRUGO, clk->dentry,
+ (u32 *)&clk->flags);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ d = clk->dentry;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(clk->dentry);
+ return err;
+}
+
+struct preinit_clk {
+ struct list_head list;
+ struct clk *clk;
+};
+static LIST_HEAD(preinit_clks);
+static DEFINE_MUTEX(preinit_lock);
+static int init_done;
+
+void clk_debug_register(struct clk *clk)
+{
+ int err;
+ struct clk *pa;
+
+ if (init_done) {
+ pa = clk_get_parent(clk);
+
+ if (pa && !IS_ERR(pa) && !pa->dentry)
+ clk_debug_register(pa);
+
+ if (!clk->dentry) {
+ err = clk_debug_register_one(clk);
+ if (err)
+ return;
+ }
+ } else {
+ struct preinit_clk *p;
+ mutex_lock(&preinit_lock);
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p) {
+ p->clk = clk;
+ list_add(&p->list, &preinit_clks);
+ }
+ mutex_unlock(&preinit_lock);
+ }
+}
+EXPORT_SYMBOL_GPL(clk_debug_register);
+
+static int __init clk_debugfs_init(void)
+{
+ struct preinit_clk *pclk, *tmp;
+
+ init_done = 1;
+
+ mutex_lock(&preinit_lock);
+ list_for_each_entry(pclk, &preinit_clks, list) {
+ clk_debug_register(pclk->clk);
+ }
+
+ list_for_each_entry_safe(pclk, tmp, &preinit_clks, list) {
+ list_del(&pclk->list);
+ kfree(pclk);
+ }
+ mutex_unlock(&preinit_lock);
+ return 0;
+}
+late_initcall(clk_debugfs_init);
+#endif
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
new file mode 100755
index 00000000..eb163abd
--- /dev/null
+++ b/arch/arm/plat-mxc/cpu.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+unsigned int __mxc_cpu_type;
+EXPORT_SYMBOL(__mxc_cpu_type);
+extern int mxc_early_serial_console_init(unsigned long base, struct clk *clk);
+void (*set_num_cpu_op)(int num);
+
+void mxc_set_cpu_type(unsigned int type)
+{
+ __mxc_cpu_type = type;
+}
+
+void imx_print_silicon_rev(const char *cpu, int srev)
+{
+ if (srev == IMX_CHIP_REVISION_UNKNOWN)
+ pr_info("CPU identified as %s, unknown revision\n", cpu);
+ else
+ pr_info("CPU identified as %s, silicon rev %d.%d\n",
+ cpu, (srev >> 4) & 0xf, srev & 0xf);
+}
+
+int mxc_jtag_enabled; /* OFF: 0 (default), ON: 1 */
+int uart_at_24; /* OFF: 0 (default); ON: 1 */
+/*
+ * Here are the JTAG options from the command line. By default JTAG
+ * is OFF which means JTAG is not connected and WFI is enabled
+ *
+ * "on" -- JTAG is connected, so WFI is disabled
+ * "off" -- JTAG is disconnected, so WFI is enabled
+ */
+
+static int __init jtag_wfi_setup(char *p)
+{
+ if (memcmp(p, "on", 2) == 0) {
+ mxc_jtag_enabled = 1;
+ p += 2;
+ } else if (memcmp(p, "off", 3) == 0) {
+ mxc_jtag_enabled = 0;
+ p += 3;
+ }
+ return 0;
+}
+early_param("jtag", jtag_wfi_setup);
+
+
+static int __init setup_debug_uart(char *p)
+{
+ uart_at_24 = 1;
+ return 0;
+}
+
+early_param("debug_uart", setup_debug_uart);
+
+/**
+ * early_console_setup - setup debugging console
+ *
+ * Consoles started here require little enough setup that we can start using
+ * them very early in the boot process, either right after the machine
+ * vector initialization, or even before if the drivers can detect their hw.
+ *
+ * Returns non-zero if a console couldn't be setup.
+ * This function is developed based on
+ * early_console_setup function as defined in arch/ia64/kernel/setup.c
+ */
+void __init early_console_setup(unsigned long base, struct clk *clk)
+{
+#ifdef CONFIG_SERIAL_IMX_CONSOLE
+ mxc_early_serial_console_init(base, clk);
+#endif
+}
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
new file mode 100755
index 00000000..01ba0b3f
--- /dev/null
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * A driver for the Freescale Semiconductor i.MXC CPUfreq module.
+ * The CPUFREQ driver is for controlling CPU frequency. It allows you to change
+ * the CPU clock speed on the fly.
+ */
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/regulator/consumer.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <asm/smp_plat.h>
+#include <asm/cpu.h>
+
+#include <mach/hardware.h>
+#include <mach/clock.h>
+
+#define CLK32_FREQ 32768
+#define NANOSECOND (1000 * 1000 * 1000)
+
+
+static int cpu_freq_khz_min;
+static int cpu_freq_khz_max;
+
+static struct clk *cpu_clk;
+static struct cpufreq_frequency_table *imx_freq_table;
+
+static int cpu_op_nr;
+static struct cpu_op *cpu_op_tbl;
+static u32 pre_suspend_rate;
+static bool cpufreq_suspend;
+static struct mutex set_cpufreq_lock;
+
+extern struct regulator *cpu_regulator;
+extern struct regulator *soc_regulator;
+extern struct regulator *pu_regulator;
+extern int dvfs_core_is_active;
+extern struct cpu_op *(*get_cpu_op)(int *op);
+extern void bus_freq_update(struct clk *clk, bool flag);
+extern void mx6_arm_regulator_bypass(void);
+extern void mx6_soc_pu_regulator_bypass(void);
+
+int set_cpu_freq(int freq)
+{
+ int i, ret = 0;
+ int org_cpu_rate;
+ int gp_volt = 0, org_gp_volt = 0;
+ int soc_volt = 0, org_soc_volt = 0;
+ int pu_volt = 0, org_pu_volt = 0;
+
+ org_cpu_rate = clk_get_rate(cpu_clk);
+ if (org_cpu_rate == freq)
+ return ret;
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ if (freq == cpu_op_tbl[i].cpu_rate) {
+ gp_volt = cpu_op_tbl[i].cpu_voltage;
+ soc_volt = cpu_op_tbl[i].soc_voltage;
+ pu_volt = cpu_op_tbl[i].pu_voltage;
+ }
+ if (org_cpu_rate == cpu_op_tbl[i].cpu_rate) {
+ org_gp_volt = cpu_op_tbl[i].cpu_voltage;
+ org_soc_volt = cpu_op_tbl[i].soc_voltage;
+ org_pu_volt = cpu_op_tbl[i].pu_voltage;
+ }
+ }
+ if (gp_volt == 0)
+ return ret;
+ /*Set the voltage for the GP domain. */
+ if (freq > org_cpu_rate) {
+ /* Check if the bus freq needs to be increased first */
+ bus_freq_update(cpu_clk, true);
+
+ if (!IS_ERR(soc_regulator)) {
+ ret = regulator_set_voltage(soc_regulator, soc_volt,
+ soc_volt);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "COULD NOT SET SOC VOLTAGE!!!!\n");
+ goto err1;
+ }
+ }
+ /*if pu_regulator is enabled, it will be tracked with VDDARM*/
+ if (!IS_ERR(pu_regulator) &&
+ regulator_is_enabled(pu_regulator)) {
+ ret = regulator_set_voltage(pu_regulator, pu_volt,
+ pu_volt);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "COULD NOT SET PU VOLTAGE!!!!\n");
+ goto err2;
+ }
+ }
+ if (!IS_ERR(cpu_regulator))
+ {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT SET GP VOLTAGE!!!!\n");
+ goto err3;
+ }
+ }
+ udelay(50);
+ }
+ ret = clk_set_rate(cpu_clk, freq);
+ if (ret != 0) {
+ printk(KERN_ERR "cannot set CPU clock rate\n");
+ goto err4;
+ }
+
+ if (freq < org_cpu_rate) {
+ if (!IS_ERR(cpu_regulator)) {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT SET GP VOLTAGE!!!!\n");
+ goto err5;
+ }
+ }
+ if (!IS_ERR(soc_regulator)) {
+ ret = regulator_set_voltage(soc_regulator, soc_volt,
+ soc_volt);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "COULD NOT SET SOC VOLTAGE BACK!!!!\n");
+ goto err6;
+ }
+ }
+ /*if pu_regulator is enabled, it will be tracked with VDDARM*/
+ if (!IS_ERR(pu_regulator) &&
+ regulator_is_enabled(pu_regulator)) {
+ ret = regulator_set_voltage(pu_regulator, pu_volt,
+ pu_volt);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "COULD NOT SET PU VOLTAGE!!!!\n");
+ goto err7;
+ }
+ }
+ /* Check if the bus freq can be decreased.*/
+ if (freq == cpu_op_tbl[cpu_op_nr - 1].cpu_rate)
+ bus_freq_update(cpu_clk, false);
+ }
+
+ return ret;
+ /*Restore back if any regulator or clock rate set fail.*/
+err7:
+ ret = regulator_set_voltage(soc_regulator, org_soc_volt,
+ org_soc_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT RESTORE SOC VOLTAGE!!!!\n");
+ goto err7;
+ }
+
+err6:
+ ret = regulator_set_voltage(cpu_regulator, org_gp_volt, org_gp_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT RESTORE GP VOLTAGE!!!!\n");
+ goto err6;
+ }
+
+err5:
+ ret = clk_set_rate(cpu_clk, org_cpu_rate);
+ if (ret != 0) {
+ printk(KERN_ERR "cannot restore CPU clock rate\n");
+ goto err5;
+ }
+ return -1;
+
+err4:
+ ret = regulator_set_voltage(cpu_regulator, org_gp_volt, org_gp_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT RESTORE GP VOLTAGE!!!!\n");
+ goto err4;
+ }
+
+err3:
+ if (!IS_ERR(pu_regulator) &&
+ regulator_is_enabled(pu_regulator)) {
+ ret = regulator_set_voltage(pu_regulator, org_pu_volt, org_pu_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT RESTORE PU VOLTAGE!!!!\n");
+ goto err3;
+ }
+ }
+err2:
+ ret = regulator_set_voltage(soc_regulator, org_soc_volt,
+ org_soc_volt);
+ if (ret < 0) {
+ printk(KERN_ERR "COULD NOT RESTORE SOC VOLTAGE!!!!\n");
+ goto err2;
+ }
+err1:
+ return -1;
+
+}
+
+static int mxc_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu > num_possible_cpus())
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, imx_freq_table);
+}
+
+static unsigned int mxc_get_speed(unsigned int cpu)
+{
+ if (cpu > num_possible_cpus())
+ return 0;
+
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int mxc_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ int freq_Hz;
+ int ret = 0;
+ unsigned int index;
+ int i, num_cpus;
+
+ num_cpus = num_possible_cpus();
+ if (policy->cpu > num_cpus)
+ return 0;
+ if (dvfs_core_is_active) {
+ struct cpufreq_freqs freqs;
+
+ freqs.old = policy->cur;
+ freqs.new = clk_get_rate(cpu_clk) / 1000;
+ freqs.cpu = policy->cpu;
+ freqs.flags = 0;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ pr_debug("DVFS core is active, cannot change FREQ using CPUFREQ\n");
+ return ret;
+ }
+
+ mutex_lock(&set_cpufreq_lock);
+ if (cpufreq_suspend) {
+ mutex_unlock(&set_cpufreq_lock);
+ return ret;
+ }
+ cpufreq_frequency_table_target(policy, imx_freq_table,
+ target_freq, relation, &index);
+ freq_Hz = imx_freq_table[index].frequency * 1000;
+
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+ freqs.new = freq_Hz / 1000;
+ freqs.cpu = policy->cpu;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ ret = set_cpu_freq(freq_Hz);
+ if (ret) {
+ /*restore cpufreq and tell cpufreq core if set fail*/
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+ freqs.new = freqs.old;
+ freqs.cpu = policy->cpu;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ goto Set_finish;
+ }
+#ifdef CONFIG_SMP
+ /* Loops per jiffy is not updated by the CPUFREQ driver for SMP systems.
+ * So update it for all CPUs.
+ */
+
+ for_each_possible_cpu(i)
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
+ freqs.old, freqs.new);
+ /* Update global loops_per_jiffy to cpu0's loops_per_jiffy,
+ * as all CPUs are running at same freq */
+ loops_per_jiffy = per_cpu(cpu_data, 0).loops_per_jiffy;
+#endif
+Set_finish:
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ mutex_unlock(&set_cpufreq_lock);
+
+ return ret;
+}
+
+static int __devinit mxc_cpufreq_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ int i;
+
+ printk(KERN_INFO "i.MXC CPU frequency driver\n");
+
+ if (policy->cpu >= num_possible_cpus())
+ return -EINVAL;
+
+ if (!get_cpu_op)
+ return -EINVAL;
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+
+ cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000;
+ cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000;
+
+ if (imx_freq_table == NULL) {
+ imx_freq_table = kmalloc(
+ sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1),
+ GFP_KERNEL);
+ if (!imx_freq_table) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ for (i = 0; i < cpu_op_nr; i++) {
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+ cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+ cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000;
+ }
+
+ imx_freq_table[i].index = i;
+ imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+ }
+ policy->cur = clk_get_rate(cpu_clk) / 1000;
+ policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min;
+ policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max;
+
+ /* All processors share the same frequency and voltage.
+ * So all frequencies need to be scaled together.
+ */
+ if (is_smp()) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_setall(policy->cpus);
+ }
+
+ /* Manual states, that PLL stabilizes in two CLK32 periods */
+ policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n",
+ __func__, ret);
+ goto err;
+ }
+
+ cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
+ return 0;
+err:
+ kfree(imx_freq_table);
+err1:
+ clk_put(cpu_clk);
+ return ret;
+}
+
+static int mxc_cpufreq_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+
+ if (policy->cpu == 0) {
+ set_cpu_freq(cpu_freq_khz_max * 1000);
+ clk_put(cpu_clk);
+ kfree(imx_freq_table);
+ }
+ return 0;
+}
+
+static struct freq_attr *imx_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+static struct cpufreq_driver mxc_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = mxc_verify_speed,
+ .target = mxc_set_target,
+ .get = mxc_get_speed,
+ .init = mxc_cpufreq_init,
+ .exit = mxc_cpufreq_exit,
+ .name = "imx",
+ .attr = imx_cpufreq_attr,
+};
+
+static int cpufreq_pm_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ unsigned int i;
+ int num_cpus;
+ int ret;
+ struct cpufreq_freqs freqs;
+
+ num_cpus = num_possible_cpus();
+ mutex_lock(&set_cpufreq_lock);
+ if (event == PM_SUSPEND_PREPARE) {
+ pre_suspend_rate = clk_get_rate(cpu_clk);
+ if (pre_suspend_rate != (imx_freq_table[0].frequency * 1000)) {
+ /*notify cpufreq core will raise up cpufreq to highest*/
+ freqs.old = pre_suspend_rate / 1000;
+ freqs.new = imx_freq_table[0].frequency;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ ret = set_cpu_freq(imx_freq_table[0].frequency * 1000);
+ /*restore cpufreq and tell cpufreq core if set fail*/
+ if (ret) {
+ freqs.old = clk_get_rate(cpu_clk)/1000;
+ freqs.new = freqs.old;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ goto Notify_finish;/*if update freq error,return*/
+ }
+#ifdef CONFIG_SMP
+ for_each_possible_cpu(i)
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
+ pre_suspend_rate / 1000, imx_freq_table[0].frequency);
+ loops_per_jiffy = per_cpu(cpu_data, 0).loops_per_jiffy;
+#else
+ loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+ pre_suspend_rate / 1000, imx_freq_table[0].frequency);
+#endif
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ }
+ cpufreq_suspend = true;
+ } else if (event == PM_POST_SUSPEND) {
+ if (clk_get_rate(cpu_clk) != pre_suspend_rate) {
+ /*notify cpufreq core will restore rate before suspend*/
+ freqs.old = imx_freq_table[0].frequency;
+ freqs.new = pre_suspend_rate / 1000;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ ret = set_cpu_freq(pre_suspend_rate);
+ /*restore cpufreq and tell cpufreq core if set fail*/
+ if (ret) {
+ freqs.old = clk_get_rate(cpu_clk)/1000;
+ freqs.new = freqs.old;
+ freqs.flags = 0;
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+ goto Notify_finish;/*if update freq error,return*/
+ }
+#ifdef CONFIG_SMP
+ for_each_possible_cpu(i)
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
+ imx_freq_table[0].frequency, pre_suspend_rate / 1000);
+ loops_per_jiffy = per_cpu(cpu_data, 0).loops_per_jiffy;
+#else
+ loops_per_jiffy = cpufreq_scale(loops_per_jiffy,
+ imx_freq_table[0].frequency, pre_suspend_rate / 1000);
+#endif
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ }
+ cpufreq_suspend = false;
+ }
+ mutex_unlock(&set_cpufreq_lock);
+ return NOTIFY_OK;
+
+Notify_finish:
+ for (i = 0; i < num_cpus; i++) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+ mutex_unlock(&set_cpufreq_lock);
+ return NOTIFY_OK;
+}
+static struct notifier_block imx_cpufreq_pm_notifier = {
+ .notifier_call = cpufreq_pm_notify,
+};
+extern void mx6_cpu_regulator_init(void);
+static int __init mxc_cpufreq_driver_init(void)
+{
+ mx6_cpu_regulator_init();
+ mutex_init(&set_cpufreq_lock);
+ register_pm_notifier(&imx_cpufreq_pm_notifier);
+ return cpufreq_register_driver(&mxc_driver);
+}
+
+static void mxc_cpufreq_driver_exit(void)
+{
+ cpufreq_unregister_driver(&mxc_driver);
+}
+
+module_init(mxc_cpufreq_driver_init);
+module_exit(mxc_cpufreq_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen <yong.shen@linaro.org>");
+MODULE_DESCRIPTION("CPUfreq driver for i.MX");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
new file mode 100644
index 00000000..eee1b609
--- /dev/null
+++ b/arch/arm/plat-mxc/devices.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+int __init mxc_register_device(struct platform_device *pdev, void *data)
+{
+ int ret;
+
+ pdev->dev.platform_data = data;
+
+ ret = platform_device_register(pdev);
+ if (ret)
+ pr_debug("Unable to register platform device '%s': %d\n",
+ pdev->name, ret);
+
+ return ret;
+}
+
+struct platform_device *__init imx_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ if (dmamask)
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
new file mode 100755
index 00000000..2e666bac
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -0,0 +1,190 @@
+config IMX_HAVE_PLATFORM_DMA
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_MLB
+ bool
+
+config IMX_HAVE_PLATFORM_FEC
+ bool
+ default y if ARCH_MX25 || SOC_IMX27 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53
+
+config IMX_HAVE_PLATFORM_FLEXCAN
+ select HAVE_CAN_FLEXCAN if CAN
+ bool
+
+config IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ bool
+
+config IMX_HAVE_PLATFORM_GPIO_KEYS
+ bool
+ default y if SOC_IMX51
+
+config IMX_HAVE_PLATFORM_GPMI_NFC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX21_HCD
+ bool
+
+config IMX_HAVE_PLATFORM_IMX2_WDT
+ bool
+
+config IMX_HAVE_PLATFORM_IMXDI_RTC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SRTC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_CAAM
+ bool
+ default y if SOC_IMX6Q
+
+config IMX_HAVE_PLATFORM_IMX_FB
+ bool
+ select HAVE_FB_IMX
+
+config IMX_HAVE_PLATFORM_IMX_I2C
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_KEYPAD
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SSI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_ESAI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_UART
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_UDC
+ bool
+
+config IMX_HAVE_PLATFORM_IPU_CORE
+ bool
+
+config IMX_HAVE_PLATFORM_MX1_CAMERA
+ bool
+
+config IMX_HAVE_PLATFORM_MX2_CAMERA
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_EHCI
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_MMC
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_NAND
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_PWM
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_RNGA
+ bool
+ select ARCH_HAS_RNGA
+
+config IMX_HAVE_PLATFORM_MXC_RTC
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_W1
+ bool
+
+config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ bool
+
+config IMX_HAVE_PLATFORM_SPI_IMX
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_IPUV3
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_TVE
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_VPU
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_DVFS
+ bool
+
+config IMX_HAVE_PLATFORM_AHCI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_IIM
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_GPU
+ bool
+config IMX_HAVE_PLATFORM_IMX_OCOTP
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_VIIM
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_DCP
+ bool
+
+config IMX_HAVE_PLATFORM_RANDOM_RNGC
+ bool
+
+config IMX_HAVE_PLATFORM_PERFMON
+ bool
+
+config IMX_HAVE_PLATFORM_LDB
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_PXP
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_ELCDIF
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_EPDC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SPDC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_SPDIF
+ bool
+
+config IMX_HAVE_PLATFORM_VIV_GPU
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_HDMI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ bool
+
+config IMX_HAVE_PLATFORM_FSL_OTG
+ bool
+
+config IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_PM
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_ASRC
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_MIPI_DSI
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_VDOA
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_PCIE
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_FSL_CSI
+ bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
new file mode 100755
index 00000000..102eeaaf
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -0,0 +1,70 @@
+obj-$(CONFIG_IMX_HAVE_PLATFORM_DMA) += platform-dma.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_MLB) += platform-mxc_mlb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB2_UDC) += platform-fsl-usb2-udc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_GPMI_NFC) += platform-imx-gpmi-nfc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SRTC) += platform-imx_srtc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SNVS_RTC) += platform-imx_snvs_rtc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_CAAM) += platform-imx-caam.o
+obj-y += platform-imx-dma.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FB) += platform-imx-fb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_KEYPAD) += platform-imx-keypad.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_ESAI) += platform-imx-esai.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UDC) += platform-imx_udc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IPU_CORE) += platform-ipu-core.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MX1_CAMERA) += platform-mx1-camera.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_CAMERA) += platform-mx2-camera.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI) += platform-mxc-ehci.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_MMC) += platform-mxc-mmc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_PWM) += platform-mxc_pwm.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) += platform-mxc_rnga.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_IPUV3) += platform-imx_ipuv3.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_TVE) += platform-imx_tve.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_VPU) += platform-imx_vpu.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_DVFS) += platform-imx_dvfs.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_IIM) += platform-imx-iim.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_GPU) += platform-mxc_gpu.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP) += platform-imx-ocotp.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM) += platform-imx-viim.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_DCP) += platform-imx-dcp.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_RANDOM_RNGC) += platform-imx-rngb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_PERFMON) += platform-imx-perfmon.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_LDB) += platform-imx_ldb.o
+obj-y += platform-imx-scc2.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_PXP) += platform-imx-pxp.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_EPDC) += platform-imx-epdc-fb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDC) += platform-imx-spdc-fb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF) += platform-imx-elcdif-fb.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif-dai.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF) += platform-imx-spdif-audio.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_VIV_GPU) += platform-viv_gpu.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL) += platform-imx-anatop-thermal.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_OTG) += platform-fsl-usb2-otg.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_FSL_USB_WAKEUP) += platform-fsl-usb2-wakeup.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_PM) += platform-imx-pm.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI) += platform-mxc_hdmi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI) += platform-mxc-hdmi-core.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI) += platform-imx-hdmi-soc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI) += platform-imx-hdmi-soc-dai.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_ASRC) += platform-imx-asrc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_DSI) += platform-imx-mipi_dsi.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2) += platform-imx-mipi_csi2.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_VDOA) += platform-imx-vdoa.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_PCIE) += platform-imx-pcie.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_FSL_CSI) += platform-imx-fsl-csi.o
+obj-y += platform-imx-pmu.o
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
new file mode 100755
index 00000000..90d994c2
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_ahci_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _SATA_BASE_ADDR, \
+ .irq = soc ## _INT_SATA, \
+ }
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_ahci_data imx53_ahci_data __initconst =
+ imx_ahci_data_entry_single(MX53);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_ahci_data imx6q_ahci_data __initconst =
+ imx_ahci_data_entry_single(MX6Q);
+#endif
+
+struct platform_device *__init imx_add_ahci(
+ const struct imx_ahci_data *data,
+ const struct ahci_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_SATA))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("ahci", 0 /* -1? */,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-dma.c b/arch/arm/plat-mxc/devices/platform-dma.c
new file mode 100644
index 00000000..7f731954
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-dma.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_dma_res_data imx50_dma_res_data __initconst = {
+ .iobase = MX50_APBHDMA_BASE_ADDR,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_dma_res_data imx6q_dma_res_data __initconst = {
+ .iobase = APBH_DMA_ARB_BASE_ADDR,
+};
+#endif
+
+struct platform_device *__init imx_add_dma(
+ const struct imx_dma_res_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("mxs-dma-apbh", -1,
+ res, ARRAY_SIZE(res), NULL, 0,
+ DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
new file mode 100644
index 00000000..0a03ea9b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ *
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ */
+#include <linux/dma-mapping.h>
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fec_data_entry_single(soc, _devid) \
+ { \
+ .iobase = soc ## _FEC_BASE_ADDR, \
+ .irq = soc ## _INT_FEC, \
+ .devid = _devid, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_fec_data imx25_fec_data __initconst =
+ imx_fec_data_entry_single(MX25, "imx28-fec");
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fec_data imx27_fec_data __initconst =
+ imx_fec_data_entry_single(MX27, "imx28-fec");
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_fec_data imx35_fec_data __initconst =
+ imx_fec_data_entry_single(MX35, "imx28-fec");
+#endif
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_fec_data imx50_fec_data __initconst =
+ imx_fec_data_entry_single(MX50, "fec");
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_fec_data imx51_fec_data __initconst =
+ imx_fec_data_entry_single(MX51, "fec");
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_fec_data imx53_fec_data __initconst =
+ imx_fec_data_entry_single(MX53, "fec");
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_fec_data imx6q_fec_data __initconst =
+ imx_fec_data_entry_single(MX6Q, "enet");
+
+const struct imx_fec_data imx6sl_fec_data __initconst =
+ imx_fec_data_entry_single(MX6DL, "fec");
+#endif
+
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_ENET))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask(data->devid, 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-flexcan.c b/arch/arm/plat-mxc/devices/platform-flexcan.c
new file mode 100644
index 00000000..d660237b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-flexcan.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_flexcan_data_entry_single(soc, _devid, _id, _hwid, _size) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _CAN ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CAN ## _hwid, \
+ }
+
+#define imx_flexcan_data_entry(soc, _devid, _id, _hwid, _size) \
+ [_id] = imx_flexcan_data_entry_single(soc, _devid, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_flexcan_data imx25_flexcan_data[] __initconst = {
+#define imx25_flexcan_data_entry(_id, _hwid) \
+ imx_flexcan_data_entry(MX25, "imx25-flexcan", _id, _hwid, SZ_16K)
+ imx25_flexcan_data_entry(0, 1),
+ imx25_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_flexcan_data imx35_flexcan_data[] __initconst = {
+#define imx35_flexcan_data_entry(_id, _hwid) \
+ imx_flexcan_data_entry(MX35, "imx35-flexcan", _id, _hwid, SZ_16K)
+ imx35_flexcan_data_entry(0, 1),
+ imx35_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_flexcan_data imx6q_flexcan_data[] __initconst = {
+#define imx6q_flexcan_data_entry(_id, _hwid) \
+ imx_flexcan_data_entry(MX6Q, "imx6q-flexcan", _id, _hwid, SZ_16K)
+ imx6q_flexcan_data_entry(0, 1),
+ imx6q_flexcan_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q*/
+
+struct platform_device *__init imx_add_flexcan(
+ const struct imx_flexcan_data *data,
+ const struct flexcan_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device(data->devid, data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c
new file mode 100644
index 00000000..cbb56ff0
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-otg.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Based on Uwe Kleine-Koenig's platform-fsl-usb2-udc.c
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fsl_usb2_otg_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_fsl_usb2_otg_data imx6q_fsl_usb2_otg_data __initconst =
+ imx_fsl_usb2_otg_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_fsl_usb2_otg(
+ const struct imx_fsl_usb2_otg_data *data,
+ const struct fsl_usb2_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ int ret = -ENOMEM;
+ const char *name = "fsl-usb2-otg";
+ int id = -1;
+ unsigned int num_resources = ARRAY_SIZE(res);
+ size_t size_data = sizeof(*pdata);
+ u64 dmamask = DMA_BIT_MASK(32);
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+
+ if (data) {
+ ret = platform_device_add_data(pdev, pdata, size_data);
+ if (ret)
+ goto err;
+ }
+
+ return pdev;
+err:
+ if (dmamask)
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(imx_add_fsl_usb2_otg);
+
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
new file mode 100644
index 00000000..6e65a91c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-udc.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fsl_usb2_udc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USB_OTG_BASE_ADDR, \
+ .irq = soc ## _INT_USB_OTG, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX35);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_fsl_usb2_udc_data imx6q_fsl_usb2_udc_data __initconst =
+ imx_fsl_usb2_udc_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_fsl_usb2_udc(
+ const struct imx_fsl_usb2_udc_data *data,
+ const struct fsl_usb2_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ int ret = -ENOMEM;
+ const char *name = "fsl-usb2-udc";
+ int id = -1;
+ unsigned int num_resources = ARRAY_SIZE(res);
+ size_t size_data = sizeof(*pdata);
+ u64 dmamask = DMA_BIT_MASK(32);
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+
+ if (data) {
+ ret = platform_device_add_data(pdev, pdata, size_data);
+ if (ret)
+ goto err;
+ }
+
+ return pdev;
+
+err:
+ if (dmamask)
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(imx_add_fsl_usb2_udc);
+
diff --git a/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
new file mode 100644
index 00000000..3dacd287
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-fsl-usb2-wakeup.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#define imx_fsl_usb2_wakeup_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .irq_phy = soc ## _INT_USB_PHY ## _id, \
+ .irq_core = soc ## _INT_USB_ ## hs, \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_fsl_usb2_wakeup_data imx6q_fsl_otg_wakeup_data __initconst =
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 0, OTG);
+const struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] __initconst = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1),
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 2, HS2),
+ imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 3, HS3),
+};
+
+const struct imx_fsl_usb2_wakeup_data imx6sl_fsl_hs_wakeup_data[] __initconst = {
+ imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1),
+ imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 2, HS2),
+ imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 3, HS3),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_fsl_usb2_wakeup(
+ const struct imx_fsl_usb2_wakeup_data *data,
+ const struct fsl_usb2_wakeup_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->irq_phy,
+ .end = data->irq_phy,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq_core,
+ .end = data->irq_core,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("usb-wakeup", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+EXPORT_SYMBOL(imx_add_fsl_usb2_wakeup);
diff --git a/arch/arm/plat-mxc/devices/platform-gpio_keys.c b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
new file mode 100644
index 00000000..1c53a532
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-gpio_keys.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_gpio_keys(
+ const struct gpio_keys_platform_data *pdata)
+{
+ return imx_add_platform_device("gpio-keys", -1, NULL,
+ 0, pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-anatop-thermal.c b/arch/arm/plat-mxc/devices/platform-imx-anatop-thermal.c
new file mode 100644
index 00000000..352d0f0c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-anatop-thermal.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_anatop_thermal_imx_data_entry_single(soc) \
+ { \
+ .iobase = ANATOP_BASE_ADDR, \
+ .calibration_addr = OCOTP_BASE_ADDR + 0x4E0, \
+ .irq = MXC_INT_ANATOP_TEMPSNSR \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_anatop_thermal_imx_data imx6q_anatop_thermal_imx_data __initconst =
+ imx_anatop_thermal_imx_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_anatop_thermal_imx(
+ const struct imx_anatop_thermal_imx_data *data,
+ const struct anatop_thermal_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->calibration_addr,
+ .end = data->calibration_addr + SZ_4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("anatop_thermal", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-asrc.c b/arch/arm/plat-mxc/devices/platform-imx-asrc.c
new file mode 100644
index 00000000..c112a9ba
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-asrc.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_asrc_data_entry(soc, _id, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _ASRC ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ASRC, \
+ .dmatx1 = soc ## _DMA_REQ_ASRC## _TX1, \
+ .dmarx1 = soc ## _DMA_REQ_ASRC## _RX1, \
+ .dmatx2 = soc ## _DMA_REQ_ASRC## _TX2, \
+ .dmarx2 = soc ## _DMA_REQ_ASRC## _RX2, \
+ .dmatx3 = soc ## _DMA_REQ_ASRC## _TX3, \
+ .dmarx3 = soc ## _DMA_REQ_ASRC## _RX3, \
+ }
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_asrc_data imx53_imx_asrc_data[] __initconst = {
+#define imx53_imx_asrc_data_entry(_id) \
+ imx_imx_asrc_data_entry(MX53, _id, SZ_4K)
+ imx53_imx_asrc_data_entry(0),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx_asrc_data imx6q_imx_asrc_data[] __initconst = {
+#define imx6q_imx_asrc_data_entry(_id) \
+ imx_imx_asrc_data_entry(MX6Q, _id, SZ_4K)
+ imx6q_imx_asrc_data_entry(0),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_imx_asrc(
+ const struct imx_imx_asrc_data *data,
+ const struct imx_asrc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+#define DMARES(_name) { \
+ .name = #_name, \
+ .start = data->dma ## _name, \
+ .end = data->dma ## _name, \
+ .flags = IORESOURCE_DMA, \
+}
+ DMARES(tx1),
+ DMARES(rx1),
+ DMARES(tx2),
+ DMARES(rx2),
+ DMARES(tx3),
+ DMARES(rx3),
+ };
+
+ return imx_add_platform_device("mxc_asrc", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-caam.c b/arch/arm/plat-mxc/devices/platform-imx-caam.c
new file mode 100644
index 00000000..aaaf501f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-caam.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+/*
+ * security violation interrupt is used as CAAM base _INT_SNVS_SEC
+ * SNVS consolidated = _INT_SNVS
+ * JR0 = MXC_INT_CAAM_INT0_NUM
+ * JR1 = MXC_INT_CAAM_INT1_NUM
+ */
+
+const struct imx_caam_data imx6q_imx_caam_data __initconst = {
+ .iobase_caam = MXC_CAAM_BASE_ADDR,
+ .iobase_caam_sm = CAAM_SECMEM_BASE_ADDR,
+ .iobase_snvs = MX6Q_SNVS_BASE_ADDR,
+ .irq_sec_vio = MXC_INT_SNVS_SEC,
+ .irq_snvs = MX6Q_INT_SNVS,
+ .jr[0].offset_jr = 0x1000,
+ .jr[0].irq_jr = MXC_INT_CAAM_INT0_NUM,
+ .jr[1].offset_jr = 0x2000,
+ .jr[1].irq_jr = MXC_INT_CAAM_INT1_NUM,
+};
+
+struct platform_device *__init imx_add_caam(
+ const struct imx_caam_data *data)
+{
+ u32 res_count = 0;
+ struct resource res[] = {
+ {
+ /* Define base range for entire CAAM register map */
+ .name = "iobase_caam",
+ .start = data->iobase_caam,
+ .end = data->iobase_caam + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define range for secure memory */
+ .name = "iobase_caam_sm",
+ .start = data->iobase_caam_sm,
+ .end = data->iobase_caam_sm + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define range for SNVS */
+ .name = "iobase_snvs",
+ .start = data->iobase_snvs,
+ .end = data->iobase_snvs + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ /* Define interrupt for security violations */
+ .name = "irq_sec_vio",
+ .start = data->irq_sec_vio,
+ .end = data->irq_sec_vio,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ /* Define general SNVS interrupt */
+ .name = "irq_snvs",
+ .start = data->irq_snvs,
+ .end = data->irq_snvs,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "offset_jr0",
+ .start = data->jr[0].offset_jr,
+ .end = data->jr[0].offset_jr,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_jr0",
+ .start = data->jr[0].irq_jr,
+ .end = data->jr[0].irq_jr,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "offset_jr1",
+ .start = data->jr[1].offset_jr,
+ .end = data->jr[1].offset_jr,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_jr1",
+ .start = data->jr[1].irq_jr,
+ .end = data->jr[1].irq_jr,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ res_count = ARRAY_SIZE(res);
+ BUG_ON(!res_count);
+
+ return imx_add_platform_device("caam", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dcp.c b/arch/arm/plat-mxc/devices/platform-imx-dcp.c
new file mode 100755
index 00000000..a77840b9
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-dcp.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_SOC_IMX50
+#define imx_dcp_data_entry_single(soc) \
+{ \
+ .iobase = soc ## _DCP_BASE_ADDR, \
+ .irq1 = soc ## _INT_DCP_CHAN0, \
+ .irq2 = soc ## _INT_DCP_CHAN1_3, \
+}
+
+const struct imx_dcp_data imx50_dcp_data __initconst =
+ imx_dcp_data_entry_single(MX50);
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX6SL
+#define imx_dcp_data_entry_single(soc) \
+{ \
+ .iobase = soc ## _DCP_BASE_ADDR, \
+ .irq1 = soc ## _INT_DCP_CH0, \
+ .irq2 = soc ## _INT_DCP_GEN, \
+}
+
+const struct imx_dcp_data imx6sl_dcp_data __initconst =
+ imx_dcp_data_entry_single(MX6SL);
+#endif /* ifdef CONFIG_SOC_IMX6SL */
+
+struct platform_device *__init imx_add_dcp(
+ const struct imx_dcp_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->irq1,
+ .end = data->irq1,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = data->irq2,
+ .end = data->irq2,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("dcp", 0,
+ res, ARRAY_SIZE(res), NULL, 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
new file mode 100755
index 00000000..e7caaf4c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/sdma.h>
+
+struct imx_imx_sdma_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+ struct sdma_platform_data pdata;
+};
+
+#define imx_imx_sdma_data_entry_single(soc, _sdma_version, _cpu_name, _to_version)\
+ { \
+ .iobase = soc ## _SDMA ## _BASE_ADDR, \
+ .irq = soc ## _INT_SDMA, \
+ .pdata = { \
+ .sdma_version = _sdma_version, \
+ .cpu_name = _cpu_name, \
+ .to_version = _to_version, \
+ }, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+struct imx_imx_sdma_data imx25_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX25, 1, "imx25", 0);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX31
+struct imx_imx_sdma_data imx31_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX31, 1, "imx31", 0);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+struct imx_imx_sdma_data imx35_imx_sdma_data __initdata =
+ imx_imx_sdma_data_entry_single(MX35, 2, "imx35", 0);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+struct imx_imx_sdma_data imx51_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX51, 2, "imx51", 0);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+struct imx_imx_sdma_data imx53_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX53, 2, "imx53", 1);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX6Q
+struct imx_imx_sdma_data imx6q_imx_sdma_data __initconst =
+ imx_imx_sdma_data_entry_single(MX6Q, 2, "imx6q", 1);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+static struct platform_device __init __maybe_unused *imx_add_imx_sdma(
+ const struct imx_imx_sdma_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-sdma", -1,
+ res, ARRAY_SIZE(res),
+ &data->pdata, sizeof(data->pdata));
+}
+
+static struct platform_device __init __maybe_unused *imx_add_imx_dma(void)
+{
+ return imx_add_platform_device("imx-dma", -1, NULL, 0, NULL, 0);
+}
+
+#ifdef CONFIG_SOC_IMX25
+static struct sdma_script_start_addrs addr_imx25_to1 = {
+ .ap_2_ap_addr = 729,
+ .uart_2_mcu_addr = 904,
+ .per_2_app_addr = 1255,
+ .mcu_2_app_addr = 834,
+ .uartsh_2_mcu_addr = 1120,
+ .per_2_shp_addr = 1329,
+ .mcu_2_shp_addr = 1048,
+ .ata_2_mcu_addr = 1560,
+ .mcu_2_ata_addr = 1479,
+ .app_2_per_addr = 1189,
+ .app_2_mcu_addr = 770,
+ .shp_2_per_addr = 1407,
+ .shp_2_mcu_addr = 979,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX31
+static struct sdma_script_start_addrs addr_imx31_to1 = {
+ .per_2_per_addr = 1677,
+};
+
+static struct sdma_script_start_addrs addr_imx31_to2 = {
+ .ap_2_ap_addr = 423,
+ .ap_2_bp_addr = 829,
+ .bp_2_ap_addr = 1029,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX35
+static struct sdma_script_start_addrs addr_imx35_to1 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .uartsh_2_mcu_addr = 1183,
+ .per_2_shp_addr = 1033,
+ .mcu_2_shp_addr = 961,
+ .ata_2_mcu_addr = 1333,
+ .mcu_2_ata_addr = 1252,
+ .app_2_mcu_addr = 683,
+ .shp_2_per_addr = 1111,
+ .shp_2_mcu_addr = 892,
+};
+
+static struct sdma_script_start_addrs addr_imx35_to2 = {
+ .ap_2_ap_addr = 729,
+ .uart_2_mcu_addr = 904,
+ .per_2_app_addr = 1597,
+ .mcu_2_app_addr = 834,
+ .uartsh_2_mcu_addr = 1270,
+ .per_2_shp_addr = 1120,
+ .mcu_2_shp_addr = 1048,
+ .ata_2_mcu_addr = 1429,
+ .mcu_2_ata_addr = 1339,
+ .app_2_per_addr = 1531,
+ .app_2_mcu_addr = 770,
+ .shp_2_per_addr = 1198,
+ .shp_2_mcu_addr = 979,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+static struct sdma_script_start_addrs addr_imx51_to3 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .mcu_2_shp_addr = 961,
+ .ata_2_mcu_addr = 1473,
+ .mcu_2_ata_addr = 1392,
+ .app_2_per_addr = 1033,
+ .app_2_mcu_addr = 683,
+ .shp_2_per_addr = 1251,
+ .shp_2_mcu_addr = 892,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+static struct sdma_script_start_addrs addr_imx53_to1 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .per_2_per_addr = 6331,
+ .uartsh_2_mcu_addr = 1032,
+ .mcu_2_shp_addr = 960,
+ .app_2_mcu_addr = 683,
+ .shp_2_mcu_addr = 891,
+ .spdif_2_mcu_addr = 1100,
+ .mcu_2_spdif_addr = 1134,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+static struct sdma_script_start_addrs addr_imx6q_to1 = {
+ .ap_2_ap_addr = 642,
+ .uart_2_mcu_addr = 817,
+ .mcu_2_app_addr = 747,
+ .per_2_per_addr = 6331,
+ .uartsh_2_mcu_addr = 1032,
+ .mcu_2_shp_addr = 960,
+ .app_2_mcu_addr = 683,
+ .shp_2_mcu_addr = 891,
+ .spdif_2_mcu_addr = 1100,
+ .mcu_2_spdif_addr = 1134,
+ .mcu_2_ssish_addr = 6242,
+ .ssish_2_mcu_addr = 6678,
+};
+#endif
+
+static int __init imxXX_add_imx_dma(void)
+{
+ struct platform_device *ret;
+
+#if defined(CONFIG_SOC_IMX21) || defined(CONFIG_SOC_IMX27)
+ if (cpu_is_mx21() || cpu_is_mx27())
+ ret = imx_add_imx_dma();
+ else
+#endif
+
+#if defined(CONFIG_SOC_IMX25)
+ if (cpu_is_mx25()) {
+ imx25_imx_sdma_data.pdata.script_addrs = &addr_imx25_to1;
+ ret = imx_add_imx_sdma(&imx25_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_SOC_IMX31)
+ if (cpu_is_mx31()) {
+ int to_version = mx31_revision() >> 4;
+ imx31_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx31_imx_sdma_data.pdata.script_addrs =
+ &addr_imx31_to1;
+ else
+ imx31_imx_sdma_data.pdata.script_addrs =
+ &addr_imx31_to2;
+ ret = imx_add_imx_sdma(&imx31_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_SOC_IMX35)
+ if (cpu_is_mx35()) {
+ int to_version = mx35_revision() >> 4;
+ imx35_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx35_imx_sdma_data.pdata.script_addrs =
+ &addr_imx35_to1;
+ else
+ imx35_imx_sdma_data.pdata.script_addrs =
+ &addr_imx35_to2;
+ ret = imx_add_imx_sdma(&imx35_imx_sdma_data);
+ } else
+#endif
+
+#if defined(CONFIG_SOC_IMX51)
+ if (cpu_is_mx51()) {
+ int to_version = mx51_revision() >> 4;
+ imx51_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 3)
+ imx51_imx_sdma_data.pdata.script_addrs =
+ &addr_imx51_to3;
+ ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
+ } else
+#endif
+#if defined(CONFIG_SOC_IMX53)
+ if (cpu_is_mx53()) {
+ int to_version = 1;
+ imx53_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx53_imx_sdma_data.pdata.script_addrs =
+ &addr_imx53_to1;
+ ret = imx_add_imx_sdma(&imx53_imx_sdma_data);
+ } else
+#endif
+#if defined(CONFIG_ARCH_MX6)
+ int to_version = 1;
+ imx6q_imx_sdma_data.pdata.to_version = to_version;
+ if (to_version == 1)
+ imx6q_imx_sdma_data.pdata.script_addrs =
+ &addr_imx6q_to1;
+ ret = imx_add_imx_sdma(&imx6q_imx_sdma_data);
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+#endif
+ ret = ERR_PTR(-ENODEV);
+
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+}
+arch_initcall(imxXX_add_imx_dma);
diff --git a/arch/arm/plat-mxc/devices/platform-imx-elcdif-fb.c b/arch/arm/plat-mxc/devices/platform-imx-elcdif-fb.c
new file mode 100644
index 00000000..62cf9c6d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-elcdif-fb.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_elcdif_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _ELCDIF_BASE_ADDR, \
+ .irq = soc ## _INT_ELCDIF, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF //[
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_elcdif_data imx6dl_elcdif_data __initconst =
+ imx_elcdif_data_entry_single(MX6DL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_imx_elcdif(
+ const struct imx_elcdif_data *data,
+ const struct mxc_fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("mxc_elcdif_fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+#endif //]CONFIG_IMX_HAVE_PLATFORM_IMX_ELCDIF
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c b/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c
new file mode 100644
index 00000000..459e6cc3
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-epdc-fb.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_epdc_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _EPDC_BASE_ADDR, \
+ .irq = soc ## _INT_EPDC, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_epdc_data imx50_epdc_data __initconst =
+ imx_epdc_data_entry_single(MX50, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_epdc_data imx6dl_epdc_data __initconst =
+ imx_epdc_data_entry_single(MX6DL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_imx_epdc(
+ const struct imx_epdc_data *data,
+ const struct imx_epdc_fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_EPDC))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("imx_epdc_fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-esai.c b/arch/arm/plat-mxc/devices/platform-imx-esai.c
new file mode 100644
index 00000000..03bd53ba
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-esai.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx53_esai_data_entry(soc, _id, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = MX53_ESAI_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = MX53_INT_ESAI, \
+ .dmatx = soc ## _DMA_REQ_ESAI ## _TX, \
+ .dmarx = soc ## _DMA_REQ_ESAI ## _RX, \
+ }
+
+#define imx6q_esai_data_entry(soc, _id, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = ESAI1_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = MXC_INT_ESAI, \
+ .dmatx = soc ## _DMA_REQ_ESAI ## _TX, \
+ .dmarx = soc ## _DMA_REQ_ESAI ## _RX, \
+ }
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_esai_data imx53_imx_esai_data[] __initconst = {
+#define imx53_imx_esai_data_entry(_id) \
+ imx53_esai_data_entry(MX53, _id, SZ_4K)
+ imx53_imx_esai_data_entry(0),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx_esai_data imx6q_imx_esai_data[] __initconst = {
+#define imx6q_imx_esai_data_entry(_id) \
+ imx6q_esai_data_entry(MX6Q, _id, SZ_4K)
+ imx6q_imx_esai_data_entry(0),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_imx_esai(
+ const struct imx_imx_esai_data *data,
+ const struct imx_esai_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+#define DMARES(_name) { \
+ .name = #_name, \
+ .start = data->dma ## _name, \
+ .end = data->dma ## _name, \
+ .flags = IORESOURCE_DMA, \
+}
+ DMARES(tx),
+ DMARES(rx),
+ };
+
+ return imx_add_platform_device("imx-esai", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-fb.c b/arch/arm/plat-mxc/devices/platform-imx-fb.c
new file mode 100644
index 00000000..2b0b5e0a
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-fb.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_fb_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _LCDC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_LCDC, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_fb_data imx1_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX1, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_fb_data imx21_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX21, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_fb_data imx25_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX25, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_fb_data imx27_imx_fb_data __initconst =
+ imx_imx_fb_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_imx_fb(
+ const struct imx_imx_fb_data *data,
+ const struct imx_fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("imx-fb", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c b/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c
new file mode 100644
index 00000000..8b6601cc
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-fsl-csi.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_fsl_csi_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _CSI_BASE_ADDR, \
+ .irq = soc ## _INT_CSI, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_fsl_csi_data imx6sl_csi_data __initconst =
+ imx_fsl_csi_data_entry_single(MX6SL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_fsl_csi(
+ const struct imx_fsl_csi_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("fsl_csi", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c b/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c
new file mode 100644
index 00000000..a1e297d5
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/mtd/gpmi-nand.h>
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_SOC_IMX50
+struct platform_device *__init
+imx_add_gpmi(const struct gpmi_nfc_platform_data *platform_data)
+{
+ struct resource res[] = {
+ { /* GPMI */
+ .name = GPMI_NFC_GPMI_REGS_ADDR_RES_NAME,
+ .flags = IORESOURCE_MEM,
+ .start = MX50_GPMI_BASE_ADDR,
+ .end = MX50_GPMI_BASE_ADDR + SZ_8K - 1,
+ }, {
+ .name = GPMI_NFC_GPMI_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MX50_INT_RAWNAND_GPMI,
+ .end = MX50_INT_RAWNAND_GPMI,
+ }, { /* BCH */
+ .name = GPMI_NFC_BCH_REGS_ADDR_RES_NAME,
+ .flags = IORESOURCE_MEM,
+ .start = MX50_BCH_BASE_ADDR,
+ .end = MX50_BCH_BASE_ADDR + SZ_8K - 1,
+ }, {
+ .name = GPMI_NFC_BCH_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MX50_INT_RAWNAND_BCH,
+ .end = MX50_INT_RAWNAND_BCH,
+ }, { /* DMA */
+ .name = GPMI_NFC_DMA_CHANNELS_RES_NAME,
+ .flags = IORESOURCE_DMA,
+ .start = MX50_DMA_CHANNEL_AHB_APBH_GPMI0,
+ .end = MX50_DMA_CHANNEL_AHB_APBH_GPMI7,
+ }, {
+ .name = GPMI_NFC_DMA_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MX50_INT_APBHDMA_CHAN0,
+ .end = MX50_INT_APBHDMA_CHAN7,
+ }, };
+
+ return imx_add_platform_device_dmamask("imx50-gpmi-nfc", 0,
+ res, ARRAY_SIZE(res), platform_data,
+ sizeof(*platform_data), DMA_BIT_MASK(32));
+}
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX6Q
+struct platform_device *__init
+imx_add_gpmi(const struct gpmi_nand_platform_data *platform_data)
+{
+ struct resource res[] = {
+ { /* GPMI */
+ .name = GPMI_NAND_GPMI_REGS_ADDR_RES_NAME,
+ .flags = IORESOURCE_MEM,
+ .start = MX6Q_GPMI_BASE_ADDR,
+ .end = MX6Q_GPMI_BASE_ADDR + SZ_8K - 1,
+ }, {
+ .name = GPMI_NAND_GPMI_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MXC_INT_RAWNAND_GPMI,
+ .end = MXC_INT_RAWNAND_GPMI,
+ }, { /* BCH */
+ .name = GPMI_NAND_BCH_REGS_ADDR_RES_NAME,
+ .flags = IORESOURCE_MEM,
+ .start = MX6Q_BCH_BASE_ADDR,
+ .end = MX6Q_BCH_BASE_ADDR + SZ_8K - 1,
+ }, {
+ .name = GPMI_NAND_BCH_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MXC_INT_RAWNAND_BCH,
+ .end = MXC_INT_RAWNAND_BCH,
+ }, { /* DMA */
+ .name = GPMI_NAND_DMA_CHANNELS_RES_NAME,
+ .flags = IORESOURCE_DMA,
+ .start = MX6Q_DMA_CHANNEL_AHB_APBH_GPMI0,
+ .end = MX6Q_DMA_CHANNEL_AHB_APBH_GPMI7,
+ }, {
+ .name = GPMI_NAND_DMA_INTERRUPT_RES_NAME,
+ .flags = IORESOURCE_IRQ,
+ .start = MXC_INT_APBHDMA_DMA,
+ .end = MXC_INT_APBHDMA_DMA,
+ }, };
+
+ return imx_add_platform_device_dmamask("imx6q-gpmi-nand", 0,
+ res, ARRAY_SIZE(res), platform_data,
+ sizeof(*platform_data), DMA_BIT_MASK(32));
+}
+#endif
diff --git a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c
new file mode 100644
index 00000000..26f4ae71
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc-dai.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_hdmi_soc_data_entry_single(soc) \
+ { \
+ .irq = soc ## _INT_HDMI_TX, \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_hdmi_soc_data imx6q_imx_hdmi_soc_dai_data __initconst =
+ imx_hdmi_soc_data_entry_single(MX6Q);
+#endif
+
+struct platform_device *__init imx_add_hdmi_soc_dai(
+ const struct imx_hdmi_soc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_HDMI))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device("imx-hdmi-soc-dai", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c
new file mode 100644
index 00000000..7be6756c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-hdmi-soc.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_hdmi_soc(void)
+{
+
+ if (!fuse_dev_is_available(MXC_DEV_HDMI))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device("mxc_hdmi_soc", 0,
+ NULL, 0, NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
new file mode 100755
index 00000000..d11f52da
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _I2C ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_I2C ## _hwid, \
+ }
+
+#define imx_imx_i2c_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_imx_i2c_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX1, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst =
+ imx_imx_i2c_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst = {
+#define imx25_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_i2c_data_entry(0, 1),
+ imx25_imx_i2c_data_entry(1, 2),
+ imx25_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst = {
+#define imx27_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_i2c_data_entry(0, 1),
+ imx27_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst = {
+#define imx31_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_i2c_data_entry(0, 1),
+ imx31_imx_i2c_data_entry(1, 2),
+ imx31_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst = {
+#define imx35_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_i2c_data_entry(0, 1),
+ imx35_imx_i2c_data_entry(1, 2),
+ imx35_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_imx_i2c_data imx50_imx_i2c_data[] __initconst = {
+#define imx50_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX50, _id, _hwid, SZ_4K)
+ imx50_imx_i2c_data_entry(0, 1),
+ imx50_imx_i2c_data_entry(1, 2),
+ imx50_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst = {
+#define imx51_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_i2c_data_entry(0, 1),
+ imx51_imx_i2c_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_i2c_data imx53_imx_i2c_data[] __initconst = {
+#define imx53_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX53, _id, _hwid, SZ_4K)
+ imx53_imx_i2c_data_entry(0, 1),
+ imx53_imx_i2c_data_entry(1, 2),
+ imx53_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx_i2c_data imx6q_imx_i2c_data[] __initconst = {
+#define imx6q_imx_i2c_data_entry(_id, _hwid) \
+ imx_imx_i2c_data_entry(MX6Q, _id, _hwid, SZ_4K)
+ imx6q_imx_i2c_data_entry(0, 1),
+ imx6q_imx_i2c_data_entry(1, 2),
+ imx6q_imx_i2c_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
+ const struct imxi2c_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-i2c", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-iim.c b/arch/arm/plat-mxc/devices/platform-imx-iim.c
new file mode 100755
index 00000000..74043ded
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-iim.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx5_iim_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _IIM_BASE_ADDR, \
+ .irq = soc ## _INT_IIM, \
+ }
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_iim_data imx51_imx_iim_data __initconst =
+ imx5_iim_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_iim_data imx53_imx_iim_data __initconst =
+ imx5_iim_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+struct platform_device *__init imx_add_iim(
+ const struct imx_iim_data *data,
+ const struct mxc_iim_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_iim", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-keypad.c b/arch/arm/plat-mxc/devices/platform-imx-keypad.c
new file mode 100644
index 00000000..1a120218
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-keypad.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_keypad_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _KPP_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_KPP, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX21, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_keypad_data imx25_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX25, SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX27, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx_keypad_data imx31_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX31, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx_keypad_data imx35_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX35, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx_keypad_data imx51_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX51, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_imx_keypad_data imx6sl_imx_keypad_data __initconst =
+ imx_imx_keypad_data_entry_single(MX6SL, SZ_16);
+#endif /* ifdef CONFIG_SOC_IMX6SL */
+
+struct platform_device *__init imx_add_imx_keypad(
+ const struct imx_imx_keypad_data *data,
+ const struct matrix_keymap_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-keypad", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-mipi_csi2.c b/arch/arm/plat-mxc/devices/platform-imx-mipi_csi2.c
new file mode 100644
index 00000000..ed8a2fbd
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-mipi_csi2.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mipi_csi2_data_entry_single(soc, _id, size) \
+{ \
+ .id = _id, \
+ .iobase = soc ## _MIPI_CSI2_BASE_ADDR, \
+ .iosize = size, \
+}
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_mipi_csi2_data imx6q_mipi_csi2_data __initconst =
+ imx_mipi_csi2_data_entry_single(MX6Q, 0, SZ_4K);
+#endif
+
+struct platform_device *__init imx_add_mipi_csi2(
+ const struct imx_mipi_csi2_data *data,
+ const struct mipi_csi2_platform_data *pdata) {
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("mxc_mipi_csi2", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-mipi_dsi.c b/arch/arm/plat-mxc/devices/platform-imx-mipi_dsi.c
new file mode 100644
index 00000000..136a8fcc
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-mipi_dsi.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mipi_dsi_data_entry_single(soc, _id, _hwid, size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _MIPI_DSI ## _hwid ## _BASE_ADDR, \
+ .iosize = size, \
+ .irq = soc ## _INT_DSI ## _hwid, \
+ }
+
+#define imx_mipi_dsi_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mipi_dsi_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX6Q
+#define SOC_IOMUXC_BASE_ADDR MX6Q_IOMUXC_BASE_ADDR
+const struct imx_mipi_dsi_data imx6q_mipi_dsi_data __initconst =
+ imx_mipi_dsi_data_entry_single(MX6Q, 0, , SZ_4K);
+#endif
+
+struct platform_device *__init imx_add_mipi_dsi(
+ const struct imx_mipi_dsi_data *data,
+ const struct mipi_dsi_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SOC_IOMUXC_BASE_ADDR,
+ .end = SOC_IOMUXC_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_mipi_dsi", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-ocotp.c b/arch/arm/plat-mxc/devices/platform-imx-ocotp.c
new file mode 100755
index 00000000..055fe337
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-ocotp.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/fsl_devices.h>
+
+#ifdef CONFIG_SOC_IMX50
+#define BANK(a, b, c, d, e, f, g, h) \
+ {\
+ ("HW_OCOTP_"#a), ("HW_OCOTP_"#b), ("HW_OCOTP_"#c), ("HW_OCOTP_"#d), \
+ ("HW_OCOTP_"#e), ("HW_OCOTP_"#f), ("HW_OCOTP_"#g), ("HW_OCOTP_"#h) \
+ }
+
+#define BANKS (5)
+#define BANK_ITEMS (8)
+static const char *bank_reg_desc[BANKS][BANK_ITEMS] = {
+ BANK(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK(MEM0, MEM1, MEM2, MEM3, MEM4, MEM5, GP0, GP1),
+ BANK(SCC0, SCC1, SCC2, SCC3, SCC4, SCC5, SCC6, SCC7),
+ BANK(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK(SJC0, SJC1, MAC0, MAC1, HWCAP0, HWCAP1, HWCAP2, SWCAP),
+};
+
+static const struct mxc_otp_platform_data imx50_otp_platform_data = {
+ .fuse_name = (char **)bank_reg_desc,
+ .clock_name = "ocotp_ctrl_ahb_clk",
+ .fuse_num = BANKS * BANK_ITEMS,
+};
+
+const struct imx_otp_data imx50_otp_data = {
+ .iobase = MX50_OCOTP_CTRL_BASE_ADDR,
+ .pdata = &imx50_otp_platform_data,
+};
+#undef BANK
+#undef BANKS
+#undef BANK_ITEMS
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX6Q
+#define BANK(a, b, c, d, e, f, g, h) \
+ {\
+ ("HW_OCOTP_"#a), ("HW_OCOTP_"#b), ("HW_OCOTP_"#c), ("HW_OCOTP_"#d), \
+ ("HW_OCOTP_"#e), ("HW_OCOTP_"#f), ("HW_OCOTP_"#g), ("HW_OCOTP_"#h) \
+ }
+
+#define BANKS (16)
+#define BANK_ITEMS (8)
+static const char *bank_reg_desc[BANKS][BANK_ITEMS] = {
+ BANK(LOCK, CFG0, CFG1, CFG2, CFG3, CFG4, CFG5, CFG6),
+ BANK(MEM0, MEM1, MEM2, MEM3, MEM4, ANA0, ANA1, ANA2),
+ BANK(OTPMK0, OTPMK1, OTPMK2, OTPMK3, OTPMK4, OTPMK5, OTPMK6, OTPMK7),
+ BANK(SRK0, SRK1, SRK2, SRK3, SRK4, SRK5, SRK6, SRK7),
+ BANK(RESP0, HSJC_RESP1, MAC0, MAC1, HDCP_KSV0, HDCP_KSV1, GP1, GP2),
+ BANK(DTCP_KEY0, DTCP_KEY1, DTCP_KEY2, DTCP_KEY3, DTCP_KEY4, MISC_CONF, FIELD_RETURN, SRK_REVOKE),
+ BANK(HDCP_KEY0, HDCP_KEY1, HDCP_KEY2, HDCP_KEY3, HDCP_KEY4, HDCP_KEY5, HDCP_KEY6, HDCP_KEY7),
+ BANK(HDCP_KEY8, HDCP_KEY9, HDCP_KEY10, HDCP_KEY11, HDCP_KEY12, HDCP_KEY13, HDCP_KEY14, HDCP_KEY15),
+ BANK(HDCP_KEY16, HDCP_KEY17, HDCP_KEY18, HDCP_KEY19, HDCP_KEY20, HDCP_KEY21, HDCP_KEY22, HDCP_KEY23),
+ BANK(HDCP_KEY24, HDCP_KEY25, HDCP_KEY26, HDCP_KEY27, HDCP_KEY28, HDCP_KEY29, HDCP_KEY30, HDCP_KEY31),
+ BANK(HDCP_KEY32, HDCP_KEY33, HDCP_KEY34, HDCP_KEY35, HDCP_KEY36, HDCP_KEY37, HDCP_KEY38, HDCP_KEY39),
+ BANK(HDCP_KEY40, HDCP_KEY41, HDCP_KEY42, HDCP_KEY43, HDCP_KEY44, HDCP_KEY45, HDCP_KEY46, HDCP_KEY47),
+ BANK(HDCP_KEY48, HDCP_KEY49, HDCP_KEY50, HDCP_KEY51, HDCP_KEY52, HDCP_KEY53, HDCP_KEY54, HDCP_KEY55),
+ BANK(HDCP_KEY56, HDCP_KEY57, HDCP_KEY58, HDCP_KEY59, HDCP_KEY60, HDCP_KEY61, HDCP_KEY62, HDCP_KEY63),
+ BANK(HDCP_KEY64, HDCP_KEY65, HDCP_KEY66, HDCP_KEY67, HDCP_KEY68, HDCP_KEY69, HDCP_KEY70, HDCP_KEY71),
+ BANK(CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6, CRC7),
+};
+
+static const struct mxc_otp_platform_data imx6q_otp_platform_data = {
+ .fuse_name = (char **)bank_reg_desc,
+ .clock_name = "iim_clk",
+ .fuse_num = BANKS * BANK_ITEMS,
+};
+
+const struct imx_otp_data imx6q_otp_data = {
+ .iobase = OCOTP_BASE_ADDR,
+ .pdata = (struct mxc_otp_platform_data *)&imx6q_otp_platform_data,
+};
+#undef BANK
+#undef BANKS
+#undef BANK_ITEMS
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+
+struct platform_device *__init imx_add_otp(
+ const struct imx_otp_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+
+ return imx_add_platform_device("imx-ocotp", 0,
+ res, ARRAY_SIZE(res), data->pdata,
+ sizeof(struct mxc_otp_platform_data));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pcie.c b/arch/arm/plat-mxc/devices/platform-imx-pcie.c
new file mode 100644
index 00000000..7e0d630f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-pcie.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_pcie_data_entry_single(soc, _id, _hwid, size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _PCIE ## _hwid ## _BASE_ADDR, \
+ .iosize = size, \
+ .irq = soc ## _INT_PCIE ## _hwid, \
+ }
+
+#define imx_pcie_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_pcie_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX6Q
+#define MX6Q_PCIE_BASE_ADDR (PCIE_ARB_END_ADDR - SZ_16K + 1)
+#define MX6Q_INT_PCIE MXC_INT_PCIE_3
+const struct imx_pcie_data imx6q_pcie_data __initconst =
+ imx_pcie_data_entry_single(MX6Q, 0, , SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_pcie(
+ const struct imx_pcie_data *data,
+ const struct imx_pcie_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_PCIE))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device("imx-pcie", -1,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
new file mode 100644
index 00000000..56e262b3
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/fsl_devices.h>
+#include <mach/iomux-v3.h>
+
+#ifdef CONFIG_SOC_IMX50
+static struct mxs_perfmon_bit_config
+mx50_perfmon_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-CORE" },
+ {.field = (1 << 1), .name = "MID1-DCP" },
+ {.field = (1 << 2), .name = "MID2-PXP" },
+ {.field = (1 << 3), .name = "MID3-USB" },
+ {.field = (1 << 4), .name = "MID4-GPU2D" },
+ {.field = (1 << 5), .name = "MID5-BCH" },
+ {.field = (1 << 6), .name = "MID6-AHB" },
+ {.field = (1 << 7), .name = "MID7-EPDC" },
+ {.field = (1 << 8), .name = "MID8-LCDIF" },
+ {.field = (1 << 9), .name = "MID9-SDMA" },
+ {.field = (1 << 10), .name = "MID10-FEC" },
+ {.field = (1 << 11), .name = "MID11-MSHC" }
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data = {
+ .bit_config_tab = mx50_perfmon_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx50_perfmon_bit_config),
+};
+
+
+const struct imx_perfmon_data imx50_perfmon_data = {
+ .iobase = MX50_PERFMON_BASE_ADDR,
+ .pdata = &mxc_perfmon_data,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+static struct mxs_perfmon_bit_config
+mx6q_perfmon1_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-GPU_3D" },
+ {.field = (1 << 1), .name = "MID1-GPU_2D" },
+ {.field = (1 << 2), .name = "MID2-VDOA" },
+ {.field = (1 << 3), .name = "MID3-Unused" },
+ {.field = (1 << 4), .name = "MID4-OPENVG" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon2_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-IPU1.ld00" },
+ {.field = (1 << 1), .name = "MID1-IPU1.ld01" },
+ {.field = (1 << 2), .name = "MID2-IPU1.ld10" },
+ {.field = (1 << 3), .name = "MID3-IPU1.ld11" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon3_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-CORES" },
+ {.field = (1 << 1), .name = "MID1-L2-BUF" },
+ {.field = (1 << 2), .name = "MID2-Unused" },
+ {.field = (1 << 3), .name = "MID3-L2-EVIC" },
+ {.field = (1 << 4), .name = "MID4-Unused" }
+};
+
+static int init;
+
+static void platform_perfmon_init(void)
+{
+ if (init)
+ return;
+
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0 || cpu_is_mx6dl())
+ /* GPR11 bit[16] must be set for TO1.0(6q & 6dl), it's a bug */
+ mxc_iomux_set_gpr_register(11, 16, 1, 1);
+
+ mxc_iomux_set_gpr_register(11, 0, 1, 1);
+ init = true;
+}
+
+static void platform_perfmon_exit(void)
+{
+ if (!init)
+ return;
+
+ mxc_iomux_set_gpr_register(11, 0, 1, 0);
+ init = false;
+}
+
+struct mxs_platform_perfmon_data mxc_perfmon_data1 = {
+ .bit_config_tab = mx6q_perfmon1_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon1_bit_config),
+ .plt_init = platform_perfmon_init,
+ .plt_exit = platform_perfmon_exit,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data2 = {
+ .bit_config_tab = mx6q_perfmon2_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon2_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data3 = {
+ .bit_config_tab = mx6q_perfmon3_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon3_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+const struct imx_perfmon_data imx6q_perfmon_data[3] = {
+ {
+ .iobase = IP2APB_PERFMON1_BASE_ADDR,
+ .pdata = &mxc_perfmon_data1,
+ },
+ {
+ .iobase = IP2APB_PERFMON2_BASE_ADDR,
+ .pdata = &mxc_perfmon_data2,
+ },
+ {
+ .iobase = IP2APB_PERFMON3_BASE_ADDR,
+ .pdata = &mxc_perfmon_data3,
+ }
+};
+#endif
+
+struct platform_device *__init imx_add_perfmon(
+ const struct imx_perfmon_data *data)
+{
+ static int id;
+
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+
+ return imx_add_platform_device("mxs-perfmon", id++,
+ res, ARRAY_SIZE(res), data->pdata,
+ sizeof(struct mxs_platform_perfmon_data));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pm.c b/arch/arm/plat-mxc/devices/platform-imx-pm.c
new file mode 100644
index 00000000..5b865ad4
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-pm.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_pm_imx_data_entry_single(soc) \
+ { \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_pm_imx_data imx6q_pm_imx_data[] __initconst =
+ imx_pm_imx_data_entry_single(MX6Q);
+#endif
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_pm_imx_data imx6sl_pm_imx_data[] __initconst =
+ imx_pm_imx_data_entry_single(MX6SL);
+#endif
+
+struct platform_device *__init imx_add_pm_imx(
+ const struct imx_pm_imx_data *data,
+ const struct pm_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("imx_pm", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pmu.c b/arch/arm/plat-mxc/devices/platform-imx-pmu.c
new file mode 100644
index 00000000..cf29415d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-pmu.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <asm/pmu.h>
+
+static struct resource mx6_pmu_resources[] = {
+ [0] = {
+ .start = MXC_INT_CHEETAH_PERFORM,
+ .end = MXC_INT_CHEETAH_PERFORM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mx6_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(mx6_pmu_resources),
+ .resource = mx6_pmu_resources,
+};
+
+void __init imx_add_imx_armpmu()
+{
+ platform_device_register(&mx6_pmu_device);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pxp.c b/arch/arm/plat-mxc/devices/platform-imx-pxp.c
new file mode 100644
index 00000000..fed58d09
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-pxp.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_pxp_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _EPXP_BASE_ADDR, \
+ .irq = soc ## _INT_EPXP, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_pxp_data imx50_pxp_data __initconst =
+ imx_pxp_data_entry_single(MX50, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_pxp_data imx6dl_pxp_data __initconst =
+ imx_pxp_data_entry_single(MX6DL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_imx_pxp(
+ const struct imx_pxp_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_PXP))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("imx-pxp", -1,
+ res, ARRAY_SIZE(res), NULL, 0, DMA_BIT_MASK(32));
+}
+
+struct platform_device *__init imx_add_imx_pxp_client()
+{
+ if (!fuse_dev_is_available(MXC_DEV_PXP))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device("imx-pxp-client", -1,
+ NULL, 0, NULL, 0);
+}
+
+struct platform_device *__init imx_add_imx_pxp_v4l2()
+{
+ if (!fuse_dev_is_available(MXC_DEV_PXP))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("pxp-v4l2", -1,
+ NULL, 0, NULL, 0, DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-rngb.c b/arch/arm/plat-mxc/devices/platform-imx-rngb.c
new file mode 100755
index 00000000..9a0a652d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-rngb.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_rngb_data_entry_single(soc) \
+{ \
+ .iobase = soc ## _RNGB_BASE_ADDR, \
+ .irq = soc ## _INT_RNGB, \
+}
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_rngb_data imx50_rngb_data __initconst =
+ imx_rngb_data_entry_single(MX50);
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_rngb_data imx6sl_rngb_data __initconst =
+ imx_rngb_data_entry_single(MX6SL);
+#endif /* ifdef CONFIG_SOC_IMX6SL */
+
+struct platform_device *__init imx_add_rngb(
+ const struct imx_rngb_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("fsl_rngc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-scc2.c b/arch/arm/plat-mxc/devices/platform-imx-scc2.c
new file mode 100644
index 00000000..10e03b66
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-scc2.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/mxc_scc2_driver.h>
+#include <linux/delay.h>
+
+#define imx_scc2_data_entry_single(soc) \
+{ \
+ .iobase = soc ## _SCC_BASE_ADDR, \
+ .ram_start = soc ## _SCC_RAM_BASE_ADDR, \
+ .irq_smn = soc ## _INT_SCC_SMN, \
+ .irq_scm = soc ## _INT_SCC_SCM, \
+}
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_mxc_scc2_data imx51_mxc_scc2_data __initconst =
+ imx_scc2_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_mxc_scc2_data imx53_mxc_scc2_data __initconst =
+ imx_scc2_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#define SCM_RD_DELAY 1000000 /* in nanoseconds */
+#define SEC_TO_NANOSEC 1000000000 /*Second to nanoseconds */
+static __init void mxc_init_scc_iram(struct resource res[])
+{
+ uint32_t reg_value;
+ uint32_t reg_mask = 0;
+ uint8_t *UMID_base;
+ uint32_t *MAP_base;
+ uint8_t i;
+ uint32_t partition_no;
+ uint32_t scc_partno;
+ void *scm_ram_base;
+ void *scc_base;
+ uint32_t ram_partitions, ram_partition_size, ram_size;
+ uint32_t scm_version_register;
+ struct timespec stime;
+ struct timespec curtime;
+ long scm_rd_timeout = 0;
+ long cur_ns = 0;
+ long start_ns = 0;
+
+ scc_base = ioremap((uint32_t) res[0].start, 0x140);
+ if (scc_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP SCC REGS\n");
+ return;
+ }
+
+ scm_version_register = __raw_readl(scc_base + SCM_VERSION_REG);
+ ram_partitions = 1 + ((scm_version_register & SCM_VER_NP_MASK)
+ >> SCM_VER_NP_SHIFT);
+ ram_partition_size = (uint32_t) (1 <<
+ ((scm_version_register & SCM_VER_BPP_MASK)
+ >> SCM_VER_BPP_SHIFT));
+
+ ram_size = (uint32_t)(ram_partitions * ram_partition_size);
+
+ scm_ram_base = ioremap((uint32_t) res[1].start, ram_size);
+
+ if (scm_ram_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP SCC RAM\n");
+ return;
+ }
+
+ /* Wait for any running SCC operations to finish or fail */
+ getnstimeofday(&stime);
+ do {
+ reg_value = __raw_readl(scc_base + SCM_STATUS_REG);
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec > stime.tv_nsec)
+ scm_rd_timeout = curtime.tv_nsec - stime.tv_nsec;
+ else{
+ /*Converted second to nanosecond and add to
+ nsec when current nanosec is less than
+ start time nanosec.*/
+ cur_ns = (curtime.tv_sec * SEC_TO_NANOSEC) +
+ curtime.tv_nsec;
+ start_ns = (stime.tv_sec * SEC_TO_NANOSEC) +
+ stime.tv_nsec;
+ scm_rd_timeout = cur_ns - start_ns;
+ }
+ } while (((reg_value & SCM_STATUS_SRS_MASK) != SCM_STATUS_SRS_READY)
+ && ((reg_value & SCM_STATUS_SRS_MASK) != SCM_STATUS_SRS_FAIL));
+
+ /* Check for failures */
+ if ((reg_value & SCM_STATUS_SRS_MASK) != SCM_STATUS_SRS_READY) {
+ /* Special message for bad secret key fuses */
+ if (reg_value & SCM_STATUS_KST_BAD_KEY)
+ printk(KERN_ERR "INVALID SCC KEY FUSE PATTERN\n");
+ else
+ printk(KERN_ERR "SECURE RAM FAILURE\n");
+
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ return;
+ }
+
+ scm_rd_timeout = 0;
+
+#ifdef CONFIG_ARCH_MX5
+ /* Release all partitions for SCC2 driver on MX53*/
+ if (cpu_is_mx53())
+ scc_partno = 0;
+ /* Release final two partitions for SCC2 driver on MX51 */
+ else
+ scc_partno = ram_partitions -
+ (MX51_SCC_RAM_SIZE / ram_partition_size);
+#else
+ scc_partno = 0;
+#endif
+
+
+ for (partition_no = scc_partno; partition_no < ram_partitions;
+ partition_no++) {
+ reg_value = (((partition_no << SCM_ZCMD_PART_SHIFT) &
+ SCM_ZCMD_PART_MASK) | ((0x03 << SCM_ZCMD_CCMD_SHIFT) &
+ SCM_ZCMD_CCMD_MASK));
+ __raw_writel(reg_value, scc_base + SCM_ZCMD_REG);
+ udelay(1);
+ /* Wait for zeroization to complete */
+ getnstimeofday(&stime);
+ do {
+ reg_value = __raw_readl(scc_base + SCM_STATUS_REG);
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec > stime.tv_nsec)
+ scm_rd_timeout = curtime.tv_nsec -
+ stime.tv_nsec;
+ else {
+ /*Converted second to nanosecond and add to
+ nsec when current nanosec is less than
+ start time nanosec.*/
+ cur_ns = (curtime.tv_sec * SEC_TO_NANOSEC) +
+ curtime.tv_nsec;
+ start_ns = (stime.tv_sec * SEC_TO_NANOSEC) +
+ stime.tv_nsec;
+ scm_rd_timeout = cur_ns - start_ns;
+ }
+ } while (((reg_value & SCM_STATUS_SRS_MASK) !=
+ SCM_STATUS_SRS_READY) && ((reg_value & SCM_STATUS_SRS_MASK) !=
+ SCM_STATUS_SRS_FAIL) && (scm_rd_timeout <= SCM_RD_DELAY));
+
+ if (scm_rd_timeout > SCM_RD_DELAY)
+ printk(KERN_ERR "SCM Status Register Read timeout"
+ "for Partition No:%d", partition_no);
+
+ if ((reg_value & SCM_STATUS_SRS_MASK) != SCM_STATUS_SRS_READY)
+ break;
+ }
+
+ /* 4 partitions on MX53 */
+ if (cpu_is_mx53())
+ reg_mask = 0xFF;
+
+ /*Check all expected partitions released */
+ reg_value = __raw_readl(scc_base + SCM_PART_OWNERS_REG);
+ if ((reg_value & reg_mask) != 0) {
+ printk(KERN_ERR "FAILED TO RELEASE IRAM PARTITION\n");
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ return;
+ }
+
+ /* we are done if this is MX53, since no sharing of IRAM and SCC_RAM */
+ if (cpu_is_mx53())
+ goto exit;
+
+ reg_mask = 0;
+ scm_rd_timeout = 0;
+ /* Allocate remaining partitions for general use */
+ for (partition_no = 0; partition_no < scc_partno; partition_no++) {
+ /* Supervisor mode claims a partition for it's own use
+ by writing zero to SMID register.*/
+ __raw_writel(0, scc_base + (SCM_SMID0_REG + 8 * partition_no));
+
+ /* Wait for any zeroization to complete */
+ getnstimeofday(&stime);
+ do {
+ reg_value = __raw_readl(scc_base + SCM_STATUS_REG);
+ getnstimeofday(&curtime);
+ if (curtime.tv_nsec > stime.tv_nsec)
+ scm_rd_timeout = curtime.tv_nsec -
+ stime.tv_nsec;
+ else{
+ /*Converted second to nanosecond and add to
+ nsec when current nanosec is less than
+ start time nanosec.*/
+ cur_ns = (curtime.tv_sec * SEC_TO_NANOSEC) +
+ curtime.tv_nsec;
+ start_ns = (stime.tv_sec * SEC_TO_NANOSEC) +
+ stime.tv_nsec;
+ scm_rd_timeout = cur_ns - start_ns;
+ }
+ } while (((reg_value & SCM_STATUS_SRS_MASK) !=
+ SCM_STATUS_SRS_READY) && ((reg_value & SCM_STATUS_SRS_MASK) !=
+ SCM_STATUS_SRS_FAIL) && (scm_rd_timeout <= SCM_RD_DELAY));
+
+ if (scm_rd_timeout > SCM_RD_DELAY)
+ printk(KERN_ERR "SCM Status Register Read timeout"
+ "for Partition No:%d", partition_no);
+
+ if ((reg_value & SCM_STATUS_SRS_MASK) != SCM_STATUS_SRS_READY)
+ break;
+ /* Set UMID=0 and permissions for universal data
+ read/write access */
+ MAP_base = scm_ram_base +
+ (uint32_t) (partition_no * ram_partition_size);
+ UMID_base = (uint8_t *) MAP_base + 0x10;
+ for (i = 0; i < 16; i++)
+ UMID_base[i] = 0;
+
+ MAP_base[0] = (SCM_PERM_NO_ZEROIZE | SCM_PERM_HD_SUP_DISABLE |
+ SCM_PERM_HD_READ | SCM_PERM_HD_WRITE |
+ SCM_PERM_HD_EXECUTE | SCM_PERM_TH_READ |
+ SCM_PERM_TH_WRITE);
+ reg_mask |= (3 << (2 * (partition_no)));
+ }
+
+ /* Check all expected partitions allocated */
+ reg_value = __raw_readl(scc_base + SCM_PART_OWNERS_REG);
+ if ((reg_value & reg_mask) != reg_mask) {
+ printk(KERN_ERR "FAILED TO ACQUIRE IRAM PARTITION\n");
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ return;
+ }
+
+exit:
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ printk(KERN_INFO "IRAM READY\n");
+}
+
+
+struct platform_device *__init imx_add_mxc_scc2(
+ const struct imx_mxc_scc2_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->ram_start,
+ .end = data->ram_start + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq_smn,
+ .end = data->irq_smn,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq_scm,
+ .end = data->irq_scm,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ mxc_init_scc_iram(res);
+
+ return imx_add_platform_device("mxc_scc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdc-fb.c b/arch/arm/plat-mxc/devices/platform-imx-spdc-fb.c
new file mode 100644
index 00000000..72010e29
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-spdc-fb.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_spdc_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _SIPIX_BASE_ADDR, \
+ .irq = soc ## _INT_SPDC, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_epdc_data imx6sl_spdc_data __initconst =
+ imx_spdc_data_entry_single(MX6SL, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_imx_spdc(
+ const struct imx_epdc_data *data,
+ const struct imx_spdc_fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("imx_spdc_fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c b/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c
new file mode 100644
index 00000000..4a0cb7bf
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-spdif-audio.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_spdif_audio_device(void)
+{
+ return imx_add_platform_device("imx-spdif-audio-device", 0,
+ NULL, 0, NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c b/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c
new file mode 100644
index 00000000..7e0a97b1
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-spdif-dai.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define MXC_SPDIF_TX_REG 0x2C
+#define MXC_SPDIF_RX_REG 0x14
+
+#define imx_spdif_dai_data_entry(soc) \
+ { \
+ .iobase = soc ## _SPDIF_BASE_ADDR, \
+ .dmatx = soc ## _DMA_REQ_SPDIF_TX, \
+ .dmarx = soc ## _DMA_REQ_SPDIF_RX, \
+ }
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_spdif_dai_data imx51_spdif_dai_data __initconst = {
+ .iobase = MX51_SPDIF_BASE_ADDR,
+ .dmatx = MX51_DMA_REQ_SPDIF,
+ };
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_spdif_dai_data imx53_spdif_dai_data __initconst =
+ imx_spdif_dai_data_entry(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_spdif_dai_data imx6q_spdif_dai_data __initconst =
+ imx_spdif_dai_data_entry(MX6Q);
+#endif /* #ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_spdif_dai(
+ const struct imx_spdif_dai_data *data)
+{
+ struct resource res[] = {
+ {
+ .name = "tx_reg",
+ .start = data->iobase + MXC_SPDIF_TX_REG,
+ .end = data->iobase + MXC_SPDIF_TX_REG,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .name = "rx_reg",
+ .start = data->iobase + MXC_SPDIF_RX_REG,
+ .end = data->iobase + MXC_SPDIF_RX_REG,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .name = "tx",
+ .start = data->dmatx,
+ .end = data->dmatx,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .name = "rx",
+ .start = data->dmarx,
+ .end = data->dmarx,
+ .flags = IORESOURCE_DMA,
+ },
+ };
+
+ return imx_add_platform_device("imx-spdif-dai", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-spdif.c b/arch/arm/plat-mxc/devices/platform-imx-spdif.c
new file mode 100644
index 00000000..90a58899
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-spdif.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx5_spdif_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _SPDIF_BASE_ADDR, \
+ .irq = soc ## _INT_SPDIF, \
+ }
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_spdif_data imx50_imx_spdif_data __initconst =
+ imx5_spdif_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_spdif_data imx51_imx_spdif_data __initconst =
+ imx5_spdif_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_spdif_data imx53_imx_spdif_data __initconst =
+ imx5_spdif_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_spdif_data imx6q_imx_spdif_data __initconst =
+ imx5_spdif_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_spdif(
+ const struct imx_spdif_data *data,
+ const struct mxc_spdif_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + 0x50,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_spdif", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx-ssi.c b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
new file mode 100755
index 00000000..6e62967c
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-ssi.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010-2012 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_ssi_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _SSI ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SSI ## _hwid, \
+ .dmatx0 = soc ## _DMA_REQ_SSI ## _hwid ## _TX0, \
+ .dmarx0 = soc ## _DMA_REQ_SSI ## _hwid ## _RX0, \
+ .dmatx1 = soc ## _DMA_REQ_SSI ## _hwid ## _TX1, \
+ .dmarx1 = soc ## _DMA_REQ_SSI ## _hwid ## _RX1, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst = {
+#define imx21_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_ssi_data_entry(0, 1),
+ imx21_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst = {
+#define imx25_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX25, _id, _hwid, SZ_4K)
+ imx25_imx_ssi_data_entry(0, 1),
+ imx25_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst = {
+#define imx27_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_ssi_data_entry(0, 1),
+ imx27_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst = {
+#define imx31_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_ssi_data_entry(0, 1),
+ imx31_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst = {
+#define imx35_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX35, _id, _hwid, SZ_4K)
+ imx35_imx_ssi_data_entry(0, 1),
+ imx35_imx_ssi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst = {
+#define imx51_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_ssi_data_entry(0, 1),
+ imx51_imx_ssi_data_entry(1, 2),
+ imx51_imx_ssi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_ssi_data imx53_imx_ssi_data[] __initconst = {
+#define imx53_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX53, _id, _hwid, SZ_4K)
+ imx53_imx_ssi_data_entry(0, 1),
+ imx53_imx_ssi_data_entry(1, 2),
+ imx53_imx_ssi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx_ssi_data imx6_imx_ssi_data[] __initconst = {
+#define imx6q_imx_ssi_data_entry(_id, _hwid) \
+ imx_imx_ssi_data_entry(MX6Q, _id, _hwid, SZ_4K)
+ imx6q_imx_ssi_data_entry(0, 1),
+ imx6q_imx_ssi_data_entry(1, 2),
+ imx6q_imx_ssi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+#define DMARES(_name) { \
+ .name = #_name, \
+ .start = data->dma ## _name, \
+ .end = data->dma ## _name, \
+ .flags = IORESOURCE_DMA, \
+}
+ DMARES(tx0),
+ DMARES(rx0),
+ DMARES(tx1),
+ DMARES(rx1),
+ };
+
+ return imx_add_platform_device("imx-ssi", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
new file mode 100644
index 00000000..e76b026b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2009-2012 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_uart_3irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irqrx = soc ## _INT_UART ## _hwid ## RX, \
+ .irqtx = soc ## _INT_UART ## _hwid ## TX, \
+ .irqrts = soc ## _INT_UART ## _hwid ## RTS, \
+ }
+
+#define imx_imx_uart_1irq_data_entry(soc, _id, _hwid, _size) \
+ [_id] = { \
+ .id = _id, \
+ .iobase = soc ## _UART ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_UART ## _hwid, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst = {
+#define imx1_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_3irq_data_entry(MX1, _id, _hwid, 0xd0)
+ imx1_imx_uart_data_entry(0, 1),
+ imx1_imx_uart_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst = {
+#define imx21_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_imx_uart_data_entry(0, 1),
+ imx21_imx_uart_data_entry(1, 2),
+ imx21_imx_uart_data_entry(2, 3),
+ imx21_imx_uart_data_entry(3, 4),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst = {
+#define imx25_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_imx_uart_data_entry(0, 1),
+ imx25_imx_uart_data_entry(1, 2),
+ imx25_imx_uart_data_entry(2, 3),
+ imx25_imx_uart_data_entry(3, 4),
+ imx25_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst = {
+#define imx27_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_imx_uart_data_entry(0, 1),
+ imx27_imx_uart_data_entry(1, 2),
+ imx27_imx_uart_data_entry(2, 3),
+ imx27_imx_uart_data_entry(3, 4),
+ imx27_imx_uart_data_entry(4, 5),
+ imx27_imx_uart_data_entry(5, 6),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst = {
+#define imx31_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_4K)
+ imx31_imx_uart_data_entry(0, 1),
+ imx31_imx_uart_data_entry(1, 2),
+ imx31_imx_uart_data_entry(2, 3),
+ imx31_imx_uart_data_entry(3, 4),
+ imx31_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst = {
+#define imx35_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX31, _id, _hwid, SZ_16K)
+ imx35_imx_uart_data_entry(0, 1),
+ imx35_imx_uart_data_entry(1, 2),
+ imx35_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst = {
+#define imx50_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX50, _id, _hwid, SZ_4K)
+ imx50_imx_uart_data_entry(0, 1),
+ imx50_imx_uart_data_entry(1, 2),
+ imx50_imx_uart_data_entry(2, 3),
+ imx50_imx_uart_data_entry(3, 4),
+ imx50_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst = {
+#define imx51_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX51, _id, _hwid, SZ_4K)
+ imx51_imx_uart_data_entry(0, 1),
+ imx51_imx_uart_data_entry(1, 2),
+ imx51_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst = {
+#define imx53_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX53, _id, _hwid, SZ_4K)
+ imx53_imx_uart_data_entry(0, 1),
+ imx53_imx_uart_data_entry(1, 2),
+ imx53_imx_uart_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx_uart_1irq_data imx6q_imx_uart_data[] __initconst = {
+#define imx6q_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX6Q, _id, _hwid, SZ_4K)
+ imx6q_imx_uart_data_entry(0, 1),
+ imx6q_imx_uart_data_entry(1, 2),
+ imx6q_imx_uart_data_entry(2, 3),
+ imx6q_imx_uart_data_entry(3, 4),
+ imx6q_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_imx_uart_1irq_data imx6sl_imx_uart_data[] __initconst = {
+#define imx6sl_imx_uart_data_entry(_id, _hwid) \
+ imx_imx_uart_1irq_data_entry(MX6SL, _id, _hwid, SZ_4K)
+ imx6sl_imx_uart_data_entry(0, 1),
+ imx6sl_imx_uart_data_entry(1, 2),
+ imx6sl_imx_uart_data_entry(2, 3),
+ imx6sl_imx_uart_data_entry(3, 4),
+ imx6sl_imx_uart_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX6SL */
+
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
+ const struct imxuart_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irqrx,
+ .end = data->irqrx,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irqtx,
+ .end = data->irqtx,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irqrts,
+ .end = data->irqrx,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-uart", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
+ const struct imxuart_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-uart", data->id, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-vdoa.c b/arch/arm/plat-mxc/devices/platform-imx-vdoa.c
new file mode 100644
index 00000000..057fda6b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-vdoa.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_vdoa_data_entry_single(soc, _id, _hwid, size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _VDOA ## _hwid ## _BASE_ADDR, \
+ .iosize = size, \
+ .irq = soc ## _INT_VDOA ## _hwid, \
+ }
+
+#define imx_vdoa_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_vdoa_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX6Q
+#define MX6Q_VDOA_BASE_ADDR VDOA_BASE_ADDR
+#define SOC_VDOA_BASE_ADDR MX6Q_VDOA_BASE_ADDR
+#define MX6Q_INT_VDOA MXC_INT_VDOA
+const struct imx_vdoa_data imx6q_vdoa_data __initconst =
+ imx_vdoa_data_entry_single(MX6Q, 0, , SZ_4K);
+#endif
+
+struct platform_device *__init imx_add_vdoa(
+ const struct imx_vdoa_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_vdoa", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-viim.c b/arch/arm/plat-mxc/devices/platform-imx-viim.c
new file mode 100644
index 00000000..89c611d5
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-viim.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/fsl_devices.h>
+
+#ifdef CONFIG_SOC_IMX51
+#define GPT_REG_BASE_ADDR (MX50_GPT1_BASE_ADDR)
+const struct imx_viim_data imx50_viim_data = {
+ .iobase = MX50_OCOTP_CTRL_BASE_ADDR,
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+#define GPT_REG_BASE_ADDR (GPT_BASE_ADDR)
+const struct imx_viim_data imx6q_viim_data = {
+ .iobase = OCOTP_BASE_ADDR,
+};
+#endif
+
+struct platform_device *__init imx_add_viim(
+ const struct imx_viim_data *data)
+{
+ struct resource res[] = {
+ [0] = {
+ .start = GPT_REG_BASE_ADDR,
+ .end = GPT_REG_BASE_ADDR + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = data->iobase,
+ .end = data->iobase + PAGE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("mxs_viim", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx2-wdt.c b/arch/arm/plat-mxc/devices/platform-imx2-wdt.c
new file mode 100644
index 00000000..53cfb8dd
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx2-wdt.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _WDOG ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_WDOG ## _hwid, \
+ }
+#define imx_imx2_wdt_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_imx2_wdt_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imx2_wdt_data imx25_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX25, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX27, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX31, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst =
+ imx_imx2_wdt_data_entry_single(MX35, 0, , SZ_16K);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_imx2_wdt_data imx51_imx2_wdt_data[] __initconst = {
+#define imx51_imx2_wdt_data_entry(_id, _hwid) \
+ imx_imx2_wdt_data_entry(MX51, _id, _hwid, SZ_16K)
+ imx51_imx2_wdt_data_entry(0, 1),
+ imx51_imx2_wdt_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_imx2_wdt_data imx53_imx2_wdt_data[] __initconst = {
+#define imx53_imx2_wdt_data_entry(_id, _hwid) \
+ imx_imx2_wdt_data_entry(MX53, _id, _hwid, SZ_16K)
+ imx53_imx2_wdt_data_entry(0, 1),
+ imx53_imx2_wdt_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_imx2_wdt_data imx6q_imx2_wdt_data[] __initconst = {
+#define imx6q_imx2_wdt_data_entry(_id, _hwid) \
+ imx_imx2_wdt_data_entry(MX6Q, _id, _hwid, SZ_16K)
+ imx6q_imx2_wdt_data_entry(0, 1),
+ imx6q_imx2_wdt_data_entry(1, 2),
+};
+#endif
+
+struct platform_device *__init imx_add_imx2_wdt(
+ const struct imx_imx2_wdt_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device("imx2-wdt", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx21-hcd.c b/arch/arm/plat-mxc/devices/platform-imx21-hcd.c
new file mode 100644
index 00000000..5770a42f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx21-hcd.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx21_hcd_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _USBOTG_BASE_ADDR, \
+ .irq = soc ## _INT_USBHOST, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_imx21_hcd_data imx21_imx21_hcd_data __initconst =
+ imx_imx21_hcd_data_entry_single(MX21);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+struct platform_device *__init imx_add_imx21_hcd(
+ const struct imx_imx21_hcd_data *data,
+ const struct mx21_usbh_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("imx21-hcd", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_dvfs.c b/arch/arm/plat-mxc/devices/platform-imx_dvfs.c
new file mode 100755
index 00000000..ae62ff9b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_dvfs.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Jason Chen <jason.chen@freescale.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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_dvfs_core_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _DVFSCORE_BASE_ADDR, \
+ .irq = soc ## _INT_GPC1, \
+ }
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_dvfs_core_data imx50_dvfs_core_data __initconst =
+ imx_dvfs_core_data_entry_single(MX50);
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_dvfs_core_data imx51_dvfs_core_data __initconst =
+ imx_dvfs_core_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_dvfs_core_data imx53_dvfs_core_data __initconst =
+ imx_dvfs_core_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_dvfs_core_data imx6q_dvfs_core_data __initconst =
+ imx_dvfs_core_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_dvfs_core(
+ const struct imx_dvfs_core_data *data,
+ const struct mxc_dvfs_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + 4 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx_dvfscore", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_add_busfreq()
+{
+ return imx_add_platform_device("imx_busfreq", 0,
+ NULL, 0, NULL, 0);
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c b/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c
new file mode 100755
index 00000000..c5b4d992
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_ipuv3.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/clk.h>
+
+#define imx5_ipuv3_data_entry_single(soc, size, ipu_init, ipu_pg) \
+ { \
+ .iobase = soc ## _IPU_CTRL_BASE_ADDR, \
+ .irq_err = soc ## _INT_IPU_ERR, \
+ .irq = soc ## _INT_IPU_SYN, \
+ .irq_start = MXC_IPU_IRQ_START, \
+ .iosize = size, \
+ .init = ipu_init, \
+ .pg = ipu_pg, \
+ }
+
+#define imx6_ipuv3_data_entry_single(soc, id, size, ipu_init, ipu_pg) \
+ { \
+ .iobase = soc ## _IPU ## id ## _ARB_BASE_ADDR, \
+ .irq_err = soc ## _INT_IPU ## id ## _ERR, \
+ .irq = soc ## _INT_IPU ## id ## _SYN, \
+ .irq_start = MXC_IPU_IRQ_START, \
+ .iosize = size, \
+ .init = ipu_init, \
+ .pg = ipu_pg, \
+ }
+
+#ifdef CONFIG_SOC_IMX51
+/*
+ * The MIPI HSC unit has been removed from the i.MX51 Reference Manual by
+ * the Freescale marketing division. However this did not remove the
+ * hardware from the chip which still needs to be configured...
+ */
+static int __init ipu_mipi_setup(void)
+{
+ struct clk *hsc_clk;
+ void __iomem *hsc_addr;
+ int ret = 0;
+
+ hsc_addr = ioremap(MX51_MIPI_HSC_BASE_ADDR, PAGE_SIZE);
+ if (!hsc_addr)
+ return -ENOMEM;
+
+ hsc_clk = clk_get_sys(NULL, "mipi_hsp");
+ if (IS_ERR(hsc_clk)) {
+ ret = PTR_ERR(hsc_clk);
+ goto unmap;
+ }
+ clk_enable(hsc_clk);
+
+ /* setup MIPI module to legacy mode */
+ writel(0xF00, hsc_addr);
+
+ /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */
+ writel(readl(hsc_addr + 0x800) | 0x30ff,
+ hsc_addr + 0x800);
+
+ clk_disable(hsc_clk);
+ clk_put(hsc_clk);
+unmap:
+ iounmap(hsc_addr);
+
+ return ret;
+}
+
+int __init mx51_ipuv3_init(int id)
+{
+ int ret = 0;
+ u32 val;
+
+ ret = ipu_mipi_setup();
+
+ /* hard reset the IPU */
+ val = readl(MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
+ val |= 1 << 3;
+ writel(val, MX51_IO_ADDRESS(MX51_SRC_BASE_ADDR));
+
+ return ret;
+}
+
+void mx51_ipuv3_pg(int enable)
+{
+ if (enable) {
+ writel(MXC_PGCR_PCR, MX51_PGC_IPU_PGCR);
+ writel(MXC_PGSR_PSR, MX51_PGC_IPU_PGSR);
+ } else {
+ writel(0x0, MX51_PGC_IPU_PGCR);
+ if (readl(MX51_PGC_IPU_PGSR) & MXC_PGSR_PSR)
+ printk(KERN_DEBUG "power gating successful\n");
+ writel(MXC_PGSR_PSR, MX51_PGC_IPU_PGSR);
+ }
+}
+
+const struct imx_ipuv3_data imx51_ipuv3_data __initconst =
+ imx5_ipuv3_data_entry_single(MX51, SZ_512M,
+ mx51_ipuv3_init, mx51_ipuv3_pg);
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+int __init mx53_ipuv3_init(int id)
+{
+ int ret = 0;
+ u32 val;
+
+ /* hard reset the IPU */
+ val = readl(MX53_IO_ADDRESS(MX53_SRC_BASE_ADDR));
+ val |= 1 << 3;
+ writel(val, MX53_IO_ADDRESS(MX53_SRC_BASE_ADDR));
+
+ return ret;
+}
+
+void mx53_ipuv3_pg(int enable)
+{
+ if (enable) {
+ writel(MXC_PGCR_PCR, MX53_PGC_IPU_PGCR);
+ writel(MXC_PGSR_PSR, MX53_PGC_IPU_PGSR);
+ } else {
+ writel(0x0, MX53_PGC_IPU_PGCR);
+ if (readl(MX53_PGC_IPU_PGSR) & MXC_PGSR_PSR)
+ printk(KERN_DEBUG "power gating successful\n");
+ writel(MXC_PGSR_PSR, MX53_PGC_IPU_PGSR);
+ }
+}
+
+const struct imx_ipuv3_data imx53_ipuv3_data __initconst =
+ imx5_ipuv3_data_entry_single(MX53, SZ_128M,
+ mx53_ipuv3_init, mx53_ipuv3_pg);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+int __init mx6q_ipuv3_init(int id)
+{
+ int ret = 0;
+ u32 val;
+
+ /* hard reset the IPU */
+ val = readl(MX6_IO_ADDRESS(SRC_BASE_ADDR));
+ if (id == 0)
+ val |= 1 << 3;
+ else
+ val |= 1 << 12;
+ writel(val, MX6_IO_ADDRESS(SRC_BASE_ADDR));
+
+ return ret;
+}
+
+void mx6q_ipuv3_pg(int enable)
+{
+ /*TODO*/
+}
+
+const struct imx_ipuv3_data imx6q_ipuv3_data[] __initconst = {
+ imx6_ipuv3_data_entry_single(MX6Q, 1, SZ_4M,
+ mx6q_ipuv3_init, mx6q_ipuv3_pg),
+ imx6_ipuv3_data_entry_single(MX6Q, 2, SZ_4M,
+ mx6q_ipuv3_init, mx6q_ipuv3_pg),
+};
+#endif
+
+struct platform_device *__init imx_add_ipuv3(
+ const int id,
+ const struct imx_ipuv3_data *data,
+ struct imx_ipuv3_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq_err,
+ .end = data->irq_err,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ pdata->init = data->init;
+ pdata->pg = data->pg;
+
+ return imx_add_platform_device_dmamask("imx-ipuv3", id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata),
+ DMA_BIT_MASK(32));
+}
+
+struct platform_device *__init imx_add_ipuv3_fb(
+ const int id,
+ const struct ipuv3_fb_platform_data *pdata)
+{
+ if (pdata->res_size[0] > 0) {
+ struct resource res[] = {
+ {
+ .start = pdata->res_base[0],
+ .end = pdata->res_base[0] + pdata->res_size[0] - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ if (pdata->res_size[1] > 0) {
+ res[1].start = pdata->res_base[1];
+ res[1].end = pdata->res_base[1] +
+ pdata->res_size[1] - 1;
+ }
+
+ return imx_add_platform_device_dmamask("mxc_sdc_fb",
+ id, res, ARRAY_SIZE(res), pdata,
+ sizeof(*pdata), DMA_BIT_MASK(32));
+ } else
+ return imx_add_platform_device_dmamask("mxc_sdc_fb", id,
+ NULL, 0, pdata, sizeof(*pdata),
+ DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_ldb.c b/arch/arm/plat-mxc/devices/platform-imx_ldb.c
new file mode 100644
index 00000000..a0919a7b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_ldb.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <linux/clk.h>
+
+#define imx_ldb_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _IOMUXC_BASE_ADDR, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_ldb_data imx53_ldb_data __initconst =
+ imx_ldb_data_entry_single(MX53, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_ldb_data imx6q_ldb_data __initconst =
+ imx_ldb_data_entry_single(MX6Q, SZ_4K);
+#endif
+
+struct platform_device *__init imx_add_ldb(
+ const struct imx_ldb_data *data,
+ struct fsl_mxc_ldb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("mxc_ldb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx_snvs_rtc.c b/arch/arm/plat-mxc/devices/platform-imx_snvs_rtc.c
new file mode 100644
index 00000000..031a0741
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_snvs_rtc.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_snvs_rtc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _SNVS_BASE_ADDR, \
+ .irq = soc ## _INT_SNVS, \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_snvs_rtc_data imx6q_imx_snvs_rtc_data __initconst =
+ imx_snvs_rtc_data_entry_single(MX6Q);
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_snvs_rtc(
+ const struct imx_snvs_rtc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("snvs_rtc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_srtc.c b/arch/arm/plat-mxc/devices/platform-imx_srtc.c
new file mode 100755
index 00000000..9e4191ec
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_srtc.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_srtc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _SRTC_BASE_ADDR, \
+ .irq = soc ## _INT_SRTC_NTZ, \
+ }
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_srtc_data imx50_imx_srtc_data __initconst =
+ imx_imx_srtc_data_entry_single(MX50);
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_srtc_data imx51_imx_srtc_data __initconst =
+ imx_imx_srtc_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_srtc_data imx53_imx_srtc_data __initconst =
+ imx_imx_srtc_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+struct platform_device *__init imx_add_srtc(
+ const struct imx_srtc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_rtc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_tve.c b/arch/arm/plat-mxc/devices/platform-imx_tve.c
new file mode 100755
index 00000000..6dc23d53
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_tve.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Jason Chen <jason.chen@freescale.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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx5_tve_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _TVE_BASE_ADDR, \
+ .irq = soc ## _INT_TVE, \
+ }
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_tve_data imx51_tve_data __initconst =
+ imx5_tve_data_entry_single(MX51);
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_tve_data imx53_tve_data __initconst =
+ imx5_tve_data_entry_single(MX53);
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+struct platform_device *__init imx_add_tve(
+ const struct imx_tve_data *data,
+ const struct fsl_mxc_tve_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_tve", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imx_udc.c b/arch/arm/plat-mxc/devices/platform-imx_udc.c
new file mode 100644
index 00000000..6fd675df
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_udc.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imx_udc_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _USBD_BASE_ADDR, \
+ .iosize = _size, \
+ .irq0 = soc ## _INT_USBD0, \
+ .irq1 = soc ## _INT_USBD1, \
+ .irq2 = soc ## _INT_USBD2, \
+ .irq3 = soc ## _INT_USBD3, \
+ .irq4 = soc ## _INT_USBD4, \
+ .irq5 = soc ## _INT_USBD5, \
+ .irq6 = soc ## _INT_USBD6, \
+ }
+
+#define imx_imx_udc_data_entry(soc, _size) \
+ [_id] = imx_imx_udc_data_entry_single(soc, _size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_imx_udc_data imx1_imx_udc_data __initconst =
+ imx_imx_udc_data_entry_single(MX1, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+struct platform_device *__init imx_add_imx_udc(
+ const struct imx_imx_udc_data *data,
+ const struct imxusb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq0,
+ .end = data->irq0,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq1,
+ .end = data->irq1,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq2,
+ .end = data->irq2,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq3,
+ .end = data->irq3,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq4,
+ .end = data->irq4,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq5,
+ .end = data->irq5,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq6,
+ .end = data->irq6,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx_udc", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx_vpu.c b/arch/arm/plat-mxc/devices/platform-imx_vpu.c
new file mode 100755
index 00000000..f0295ad1
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx_vpu.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Jason Chen <jason.chen@freescale.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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx5_vpu_data_entry_single(soc, flag, size, vpu_reset, vpu_pg) \
+ { \
+ .iobase = soc ## _VPU_BASE_ADDR, \
+ .irq_ipi = soc ## _INT_VPU, \
+ .iram_enable = flag, \
+ .iram_size = size, \
+ .reset = vpu_reset, \
+ .pg = vpu_pg, \
+ }
+
+#define imx6_vpu_data_entry_single(soc, flag, size, vpu_reset, vpu_pg) \
+ { \
+ .iobase = soc ## _VPU_BASE_ADDR, \
+ .irq_ipi = soc ## _INT_VPU_IPI, \
+ .irq_jpg = soc ## _INT_VPU_JPG, \
+ .iram_enable = flag, \
+ .iram_size = size, \
+ .reset = vpu_reset, \
+ .pg = vpu_pg, \
+ }
+
+#ifdef CONFIG_SOC_IMX51
+void mx51_vpu_reset(void)
+{
+ u32 reg;
+ void __iomem *src_base;
+
+ src_base = ioremap(MX51_SRC_BASE_ADDR, PAGE_SIZE);
+
+ /* mask interrupt due to vpu passed reset */
+ reg = __raw_readl(src_base + 0x18);
+ reg |= 0x02;
+ __raw_writel(reg, src_base + 0x18);
+
+ reg = __raw_readl(src_base);
+ reg |= 0x5; /* warm reset vpu */
+ __raw_writel(reg, src_base);
+ while (__raw_readl(src_base) & 0x04)
+ ;
+
+ iounmap(src_base);
+}
+
+void mx51_vpu_pg(int enable)
+{
+ if (enable) {
+ __raw_writel(MXC_PGCR_PCR, MX51_PGC_VPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MX51_PGC_VPU_PGSR);
+ } else {
+ __raw_writel(0x0, MX51_PGC_VPU_PGCR);
+ if (__raw_readl(MX51_PGC_VPU_PGSR) & MXC_PGSR_PSR)
+ printk(KERN_DEBUG "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MX51_PGC_VPU_PGSR);
+ }
+}
+const struct imx_vpu_data imx51_vpu_data __initconst =
+ imx5_vpu_data_entry_single(MX51,
+ false, 0x14000, mx51_vpu_reset, mx51_vpu_pg);
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+void mx53_vpu_reset(void)
+{
+ u32 reg;
+ void __iomem *src_base;
+
+ src_base = ioremap(MX53_SRC_BASE_ADDR, PAGE_SIZE);
+
+ /* mask interrupt due to vpu passed reset */
+ reg = __raw_readl(src_base + 0x18);
+ reg |= 0x02;
+ __raw_writel(reg, src_base + 0x18);
+
+ reg = __raw_readl(src_base);
+ reg |= 0x5; /* warm reset vpu */
+ __raw_writel(reg, src_base);
+ while (__raw_readl(src_base) & 0x04)
+ ;
+
+ iounmap(src_base);
+}
+
+void mx53_vpu_pg(int enable)
+{
+ if (enable) {
+ __raw_writel(MXC_PGCR_PCR, MX53_PGC_VPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MX53_PGC_VPU_PGSR);
+ } else {
+ __raw_writel(0x0, MX53_PGC_VPU_PGCR);
+ if (__raw_readl(MX53_PGC_VPU_PGSR) & MXC_PGSR_PSR)
+ printk(KERN_DEBUG "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MX53_PGC_VPU_PGSR);
+ }
+}
+
+const struct imx_vpu_data imx53_vpu_data __initconst =
+ imx5_vpu_data_entry_single(MX53,
+ true, 0x14000, mx53_vpu_reset, mx53_vpu_pg);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+void mx6q_vpu_reset(void)
+{
+ u32 reg;
+ void __iomem *src_base;
+
+ src_base = ioremap(SRC_BASE_ADDR, PAGE_SIZE);
+
+ /* mask interrupt due to vpu passed reset */
+ reg = __raw_readl(src_base + 0x18);
+ reg |= 0x02;
+ __raw_writel(reg, src_base + 0x18);
+
+ reg = __raw_readl(src_base);
+ reg |= 0x4; /* warm reset vpu */
+ __raw_writel(reg, src_base);
+ while (__raw_readl(src_base) & 0x04)
+ ;
+
+ iounmap(src_base);
+}
+
+const struct imx_vpu_data imx6q_vpu_data __initconst =
+ imx6_vpu_data_entry_single(MX6Q,
+ true, 0x21000, mx6q_vpu_reset, NULL);
+#endif
+
+struct platform_device *__init imx_add_vpu(
+ const struct imx_vpu_data *data)
+{
+ struct mxc_vpu_platform_data pdata;
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .name = "vpu_regs",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq_ipi,
+ .end = data->irq_ipi,
+ .name = "vpu_ipi_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+#ifdef CONFIG_SOC_IMX6Q
+ {
+ .start = data->irq_jpg,
+ .end = data->irq_jpg,
+ .name = "vpu_jpu_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+ };
+
+ pdata.reset = data->reset;
+ pdata.pg = data->pg;
+ pdata.iram_enable = data->iram_enable;
+ pdata.iram_size = data->iram_size;
+
+ if (!fuse_dev_is_available(MXC_DEV_VPU))
+ return ERR_PTR(-ENODEV);
+
+ if (cpu_is_mx6dl())
+ pdata.iram_enable = false;
+
+ return imx_add_platform_device("mxc_vpu", -1,
+ res, ARRAY_SIZE(res), &pdata, sizeof(pdata));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
new file mode 100644
index 00000000..805336fd
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_imxdi_rtc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _DRYICE_BASE_ADDR, \
+ .irq = soc ## _INT_DRYICE, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_imxdi_rtc_data imx25_imxdi_rtc_data __initconst =
+ imx_imxdi_rtc_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+struct platform_device *__init imx_add_imxdi_rtc(
+ const struct imx_imxdi_rtc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imxdi_rtc", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-ipu-core.c b/arch/arm/plat-mxc/devices/platform-ipu-core.c
new file mode 100644
index 00000000..79d340ae
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-ipu-core.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_ipu_core_entry_single(soc) \
+{ \
+ .iobase = soc ## _IPU_CTRL_BASE_ADDR, \
+ .synirq = soc ## _INT_IPU_SYN, \
+ .errirq = soc ## _INT_IPU_ERR, \
+}
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_ipu_core_data imx31_ipu_core_data __initconst =
+ imx_ipu_core_entry_single(MX31);
+#endif
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_ipu_core_data imx35_ipu_core_data __initconst =
+ imx_ipu_core_entry_single(MX35);
+#endif
+
+static struct platform_device *imx_ipu_coredev __initdata;
+
+struct platform_device *__init imx_add_ipu_core(
+ const struct imx_ipu_core_data *data,
+ const struct ipu_platform_data *pdata)
+{
+ /* The resource order is important! */
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + 0x5f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->iobase + 0x88,
+ .end = data->iobase + 0xb3,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->synirq,
+ .end = data->synirq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->errirq,
+ .end = data->errirq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_ipu_coredev = imx_add_platform_device("ipu-core", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_alloc_mx3_camera(
+ const struct imx_ipu_core_data *data,
+ const struct mx3_camera_pdata *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase + 0x60,
+ .end = data->iobase + 0x87,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ if (IS_ERR_OR_NULL(imx_ipu_coredev))
+ return ERR_PTR(-ENODEV);
+
+ pdev = platform_device_alloc("mx3-camera", 0);
+ if (!pdev)
+ goto err;
+
+ pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ goto err;
+
+ *pdev->dev.dma_mask = DMA_BIT_MASK(32);
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret)
+ goto err;
+
+ if (pdata) {
+ struct mx3_camera_pdata *copied_pdata;
+
+ ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (ret) {
+err:
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(-ENODEV);
+ }
+ copied_pdata = dev_get_platdata(&pdev->dev);
+ copied_pdata->dma_dev = &imx_ipu_coredev->dev;
+ }
+
+ return pdev;
+}
+
+struct platform_device *__init imx_add_mx3_sdc_fb(
+ const struct imx_ipu_core_data *data,
+ struct mx3fb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase + 0xb4,
+ .end = data->iobase + 0x1bf,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ if (IS_ERR_OR_NULL(imx_ipu_coredev))
+ return ERR_PTR(-ENODEV);
+
+ pdata->dma_dev = &imx_ipu_coredev->dev;
+
+ return imx_add_platform_device_dmamask("mx3_sdc_fb", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata),
+ DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mx1-camera.c b/arch/arm/plat-mxc/devices/platform-mx1-camera.c
new file mode 100644
index 00000000..edcc581a
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mx1-camera.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mx1_camera_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _CSI ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_CSI, \
+ }
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_mx1_camera_data imx1_mx1_camera_data __initconst =
+ imx_mx1_camera_data_entry_single(MX1, 10);
+#endif /* ifdef CONFIG_SOC_IMX1 */
+
+struct platform_device *__init imx_add_mx1_camera(
+ const struct imx_mx1_camera_data *data,
+ const struct mx1_camera_pdata *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mx1-camera", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mx2-camera.c b/arch/arm/plat-mxc/devices/platform-mx2-camera.c
new file mode 100644
index 00000000..b3f4828d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mx2-camera.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mx2_camera_data_entry_single(soc) \
+ { \
+ .iobasecsi = soc ## _CSI_BASE_ADDR, \
+ .iosizecsi = SZ_4K, \
+ .irqcsi = soc ## _INT_CSI, \
+ }
+#define imx_mx2_camera_data_entry_single_emma(soc) \
+ { \
+ .iobasecsi = soc ## _CSI_BASE_ADDR, \
+ .iosizecsi = SZ_32, \
+ .irqcsi = soc ## _INT_CSI, \
+ .iobaseemmaprp = soc ## _EMMAPRP_BASE_ADDR, \
+ .iosizeemmaprp = SZ_32, \
+ .irqemmaprp = soc ## _INT_EMMAPRP, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst =
+ imx_mx2_camera_data_entry_single(MX25);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst =
+ imx_mx2_camera_data_entry_single_emma(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+struct platform_device *__init imx_add_mx2_camera(
+ const struct imx_mx2_camera_data *data,
+ const struct mx2_camera_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobasecsi,
+ .end = data->iobasecsi + data->iosizecsi - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irqcsi,
+ .end = data->irqcsi,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->iobaseemmaprp,
+ .end = data->iobaseemmaprp + data->iosizeemmaprp - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irqemmaprp,
+ .end = data->irqemmaprp,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mx2-camera", 0,
+ res, data->iobaseemmaprp ? 4 : 2,
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-ehci.c b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
new file mode 100644
index 00000000..984fa296
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc-ehci.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#define imx_mxc_ehci_data_entry_single(soc, _id, hs) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _USB_ ## hs ## _BASE_ADDR, \
+ .irq = soc ## _INT_USB_ ## hs, \
+ }
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX25, 0, OTG);
+const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX25, 1, HS);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX27, 0, OTG);
+const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX27, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX27, 2, HS2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX31, 0, OTG);
+const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX31, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX31, 2, HS2),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX35, 0, OTG);
+const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX35, 1, HS);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_mxc_ehci_data imx6q_mxc_ehci_otg_data __initconst =
+ imx_mxc_ehci_data_entry_single(MX6Q, 0, OTG);
+const struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX6Q, 2, HS2),
+ imx_mxc_ehci_data_entry_single(MX6Q, 3, HS3),
+};
+
+const struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] __initconst = {
+ imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1),
+ imx_mxc_ehci_data_entry_single(MX6SL, 2, HS2),
+ imx_mxc_ehci_data_entry_single(MX6SL, 3, HS3),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_mxc_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct mxc_usbh_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("mxc-ehci", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+EXPORT_SYMBOL(imx_add_mxc_ehci);
+
+/* FSL internal non-upstream code */
+struct platform_device *__init imx_add_fsl_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct fsl_usb2_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_512 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ int ret = -ENOMEM;
+ const char *name = "fsl-ehci";
+ int id = data->id;
+ unsigned int num_resources = ARRAY_SIZE(res);
+ size_t size_data = sizeof(*pdata);
+ u64 dmamask = DMA_BIT_MASK(32);
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+
+ if (data) {
+ ret = platform_device_add_data(pdev, pdata, size_data);
+ if (ret)
+ goto err;
+ }
+
+ return pdev;
+
+err:
+ if (dmamask)
+ kfree(pdev->dev.dma_mask);
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+
+}
+EXPORT_SYMBOL(imx_add_fsl_ehci);
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c b/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c
new file mode 100644
index 00000000..2c9a32a9
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc-hdmi-core.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx6_mxc_hdmi_core_data_entry_single(soc, size) \
+ { \
+ .iobase = soc ## _HDMI_ARB_BASE_ADDR, \
+ .iosize = size, \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_mxc_hdmi_core_data imx6q_mxc_hdmi_core_data __initconst =
+ imx6_mxc_hdmi_core_data_entry_single(MX6Q, SZ_32K + SZ_4K);
+#endif
+
+struct platform_device *__init imx_add_mxc_hdmi_core(
+ const struct imx_mxc_hdmi_core_data *data,
+ const struct fsl_mxc_hdmi_core_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_HDMI))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("mxc_hdmi_core", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc-mmc.c b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
new file mode 100644
index 00000000..540d3a7d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc-mmc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _SDHC ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_SDHC ## _hwid, \
+ .dmareq = soc ## _DMA_REQ_SDHC ## _hwid, \
+ }
+#define imx_mxc_mmc_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mxc_mmc_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst = {
+#define imx21_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX21, _id, _hwid, SZ_4K)
+ imx21_mxc_mmc_data_entry(0, 1),
+ imx21_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst = {
+#define imx27_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX27, _id, _hwid, SZ_4K)
+ imx27_mxc_mmc_data_entry(0, 1),
+ imx27_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst = {
+#define imx31_mxc_mmc_data_entry(_id, _hwid) \
+ imx_mxc_mmc_data_entry(MX31, _id, _hwid, SZ_16K)
+ imx31_mxc_mmc_data_entry(0, 1),
+ imx31_mxc_mmc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+struct platform_device *__init imx_add_mxc_mmc(
+ const struct imx_mxc_mmc_data *data,
+ const struct imxmmc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->dmareq,
+ .end = data->dmareq,
+ .flags = IORESOURCE_DMA,
+ },
+ };
+ return imx_add_platform_device_dmamask("mxc-mmc", data->id,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_gpu.c b/arch/arm/plat-mxc/devices/platform-mxc_gpu.c
new file mode 100755
index 00000000..06ac1560
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_gpu.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_gpu_entry_3d_2d(soc) \
+ { \
+ .irq_3d = soc ## _INT_GPU, \
+ .irq_2d = soc ## _INT_GPU2_IRQ, \
+ .iobase_3d = soc ## _GPU_BASE_ADDR, \
+ .iobase_2d = soc ## _GPU2D_BASE_ADDR, \
+ .gmem_base = soc ## _GPU_GMEM_BASE_ADDR, \
+ .gmem_size = soc ## _GPU_GMEM_SIZE, \
+ }
+
+#define imx_mxc_gpu_entry_2d(soc) \
+ { \
+ .irq_2d = soc ## _INT_GPU2_IRQ, \
+ .iobase_2d = soc ## _GPU2D_BASE_ADDR, \
+ }
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_gpu_data imx35_gpu_data __initconst =
+ imx_mxc_gpu_entry_2d(MX35);
+#endif
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_mxc_gpu_data imx50_gpu_data __initconst =
+ imx_mxc_gpu_entry_2d(MX50);
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_mxc_gpu_data imx51_gpu_data __initconst =
+ imx_mxc_gpu_entry_3d_2d(MX51);
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_mxc_gpu_data imx53_gpu_data __initconst =
+ imx_mxc_gpu_entry_3d_2d(MX53);
+#endif
+
+struct platform_device *__init imx_add_mxc_gpu(
+ const struct imx_mxc_gpu_data *data,
+ const struct mxc_gpu_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->irq_2d,
+ .end = data->irq_2d,
+ .name = "gpu_2d_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = data->irq_3d,
+ .end = data->irq_3d,
+ .name = "gpu_3d_irq",
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = data->iobase_2d,
+ .end = data->iobase_2d + SZ_4K - 1,
+ .name = "gpu_2d_registers",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->iobase_3d,
+ .end = data->iobase_3d + SZ_128K - 1,
+ .name = "gpu_3d_registers",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = data->gmem_base,
+ .end = data->gmem_base + data->gmem_size - 1,
+ .name = "gpu_graphics_mem",
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("mxc_gpu", 0,
+ res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c b/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c
new file mode 100644
index 00000000..cdbdae49
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_hdmi.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx6_mxc_hdmi_data_entry_single(soc) \
+ { \
+ .irq = soc ## _INT_HDMI_TX, \
+ }
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_mxc_hdmi_data imx6q_mxc_hdmi_data __initconst =
+ imx6_mxc_hdmi_data_entry_single(MX6Q);
+#endif
+
+struct platform_device *__init imx_add_mxc_hdmi(
+ const struct imx_mxc_hdmi_data *data,
+ const struct fsl_mxc_hdmi_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_HDMI))
+ return ERR_PTR(-ENODEV);
+
+ imx_add_platform_device("mxc_hdmi_cec", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+ return imx_add_platform_device_dmamask("mxc_hdmi", -1,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
+
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_mlb.c b/arch/arm/plat-mxc/devices/platform-mxc_mlb.c
new file mode 100644
index 00000000..8925f3ee
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_mlb.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_SOC_IMX53
+struct platform_device *__init imx_add_mlb(
+ const struct mxc_mlb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = MX53_MLB_BASE_ADDR,
+ .end = MX53_MLB_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX53_INT_MLB,
+ .end = MX53_INT_MLB,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device("mxc_mlb", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+
+struct platform_device *__init imx_add_mlb(
+ const struct mxc_mlb_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = MLB_BASE_ADDR,
+ .end = MLB_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_MLB,
+ .end = MXC_INT_MLB,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MXC_INT_MLB_AHB0,
+ .end = MXC_INT_MLB_AHB0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MXC_INT_MLB_AHB1,
+ .end = MXC_INT_MLB_AHB1,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ if (!fuse_dev_is_available(MXC_DEV_MLB))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device("mxc_mlb150", 0,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+#endif
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
new file mode 100644
index 00000000..1568f39f
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_nand_data_entry_single(soc, _size) \
+ { \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#define imx_mxc_nandv3_data_entry_single(soc, _size) \
+ { \
+ .id = -1, \
+ .iobase = soc ## _NFC_BASE_ADDR, \
+ .iosize = _size, \
+ .axibase = soc ## _NFC_AXI_BASE_ADDR, \
+ .irq = soc ## _INT_NFC \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX21, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX25, SZ_8K);
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX27, SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX31, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst =
+ imx_mxc_nand_data_entry_single(MX35, SZ_8K);
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst =
+ imx_mxc_nandv3_data_entry_single(MX51, SZ_16K);
+#endif
+
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata)
+{
+ /* AXI has to come first, that's how the mxc_nand driver expect it */
+ struct resource res[] = {
+ {
+ .start = data->axibase,
+ .end = data->axibase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device("mxc_nand", data->id,
+ res + !data->axibase,
+ ARRAY_SIZE(res) - !data->axibase,
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_pwm.c b/arch/arm/plat-mxc/devices/platform-mxc_pwm.c
new file mode 100755
index 00000000..a8521b97
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_pwm.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _PWM ## _hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_PWM ## _hwid, \
+ }
+#define imx_mxc_pwm_data_entry(soc, _id, _hwid, _size) \
+ [_id] = imx_mxc_pwm_data_entry_single(soc, _id, _hwid, _size)
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_pwm_data imx21_mxc_pwm_data __initconst =
+ imx_mxc_pwm_data_entry_single(MX21, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_mxc_pwm_data imx25_mxc_pwm_data[] __initconst = {
+#define imx25_mxc_pwm_data_entry(_id, _hwid) \
+ imx_mxc_pwm_data_entry(MX25, _id, _hwid, SZ_16K)
+ imx25_mxc_pwm_data_entry(0, 1),
+ imx25_mxc_pwm_data_entry(1, 2),
+ imx25_mxc_pwm_data_entry(2, 3),
+ imx25_mxc_pwm_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_pwm_data imx27_mxc_pwm_data __initconst =
+ imx_mxc_pwm_data_entry_single(MX27, 0, , SZ_4K);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_mxc_pwm_data imx51_mxc_pwm_data[] __initconst = {
+#define imx51_mxc_pwm_data_entry(_id, _hwid) \
+ imx_mxc_pwm_data_entry(MX51, _id, _hwid, SZ_16K)
+ imx51_mxc_pwm_data_entry(0, 1),
+ imx51_mxc_pwm_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_mxc_pwm_data imx53_mxc_pwm_data[] __initconst = {
+#define imx53_mxc_pwm_data_entry(_id, _hwid) \
+ imx_mxc_pwm_data_entry(MX53, _id, _hwid, SZ_16K)
+ imx53_mxc_pwm_data_entry(0, 1),
+ imx53_mxc_pwm_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_mxc_pwm_data imx6q_mxc_pwm_data[] __initconst = {
+#define imx6q_mxc_pwm_data_entry(_id, _hwid) \
+ imx_mxc_pwm_data_entry(MX6Q, _id, _hwid, SZ_16K)
+ imx6q_mxc_pwm_data_entry(0, 1),
+ imx6q_mxc_pwm_data_entry(1, 2),
+ imx6q_mxc_pwm_data_entry(2, 3),
+ imx6q_mxc_pwm_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_mxc_pwm(
+ const struct imx_mxc_pwm_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_pwm", data->id,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_rnga.c b/arch/arm/plat-mxc/devices/platform-mxc_rnga.c
new file mode 100644
index 00000000..b4b7612b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_rnga.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+struct imx_mxc_rnga_data {
+ resource_size_t iobase;
+};
+
+#define imx_mxc_rnga_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _RNGA_BASE_ADDR, \
+ }
+
+#ifdef CONFIG_SOC_IMX31
+static const struct imx_mxc_rnga_data imx31_mxc_rnga_data __initconst =
+ imx_mxc_rnga_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+static struct platform_device *__init imx_add_mxc_rnga(
+ const struct imx_mxc_rnga_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+ return imx_add_platform_device("mxc_rnga", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
+
+static int __init imxXX_add_mxc_rnga(void)
+{
+ struct platform_device *ret;
+
+#if defined(CONFIG_SOC_IMX31)
+ if (cpu_is_mx31())
+ ret = imx_add_mxc_rnga(&imx31_mxc_rnga_data);
+ else
+#endif /* if defined(CONFIG_SOC_IMX31) */
+ ret = ERR_PTR(-ENODEV);
+
+ if (IS_ERR(ret))
+ return PTR_ERR(ret);
+
+ return 0;
+}
+arch_initcall(imxXX_add_mxc_rnga);
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_rtc.c b/arch/arm/plat-mxc/devices/platform-mxc_rtc.c
new file mode 100644
index 00000000..16d0ec4d
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_rtc.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010-2011 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_rtc_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _RTC_BASE_ADDR, \
+ .irq = soc ## _INT_RTC, \
+ }
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_rtc_data imx31_mxc_rtc_data __initconst =
+ imx_mxc_rtc_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+struct platform_device *__init imx_add_mxc_rtc(
+ const struct imx_mxc_rtc_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_rtc", -1,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_w1.c b/arch/arm/plat-mxc/devices/platform-mxc_w1.c
new file mode 100644
index 00000000..96fa5ea9
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_w1.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_w1_data_entry_single(soc) \
+ { \
+ .iobase = soc ## _OWIRE_BASE_ADDR, \
+ }
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_mxc_w1_data imx21_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX21);
+#endif /* ifdef CONFIG_SOC_IMX21 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_mxc_w1_data imx27_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX27);
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_w1_data imx31_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_mxc_w1_data imx35_mxc_w1_data __initconst =
+ imx_mxc_w1_data_entry_single(MX35);
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+struct platform_device *__init imx_add_mxc_w1(
+ const struct imx_mxc_w1_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+
+ return imx_add_platform_device("mxc_w1", 0,
+ res, ARRAY_SIZE(res), NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
new file mode 100755
index 00000000..4aaaecc2
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-sdhci-esdhc-imx.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/esdhc.h>
+
+#define imx_sdhci_esdhc_imx_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_ESDHC ## hwid, \
+ }
+
+#define imx_sdhci_usdhc_imx_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _USDHC ## hwid ## _BASE_ADDR, \
+ .irq = soc ## _INT_USDHC ## hwid, \
+ }
+
+#define imx_sdhci_esdhc_imx_data_entry(soc, id, hwid) \
+ [id] = imx_sdhci_esdhc_imx_data_entry_single(soc, id, hwid)
+
+#define imx_sdhci_usdhc_imx_data_entry(soc, id, hwid) \
+ [id] = imx_sdhci_usdhc_imx_data_entry_single(soc, id, hwid)
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_sdhci_esdhc_imx_data
+imx25_sdhci_esdhc_imx_data[] __initconst = {
+#define imx25_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX25, _id, _hwid)
+ imx25_sdhci_esdhc_imx_data_entry(0, 1),
+ imx25_sdhci_esdhc_imx_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_sdhci_esdhc_imx_data
+imx35_sdhci_esdhc_imx_data[] __initconst = {
+#define imx35_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX35, _id, _hwid)
+ imx35_sdhci_esdhc_imx_data_entry(0, 1),
+ imx35_sdhci_esdhc_imx_data_entry(1, 2),
+ imx35_sdhci_esdhc_imx_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_sdhci_esdhc_imx_data
+imx50_sdhci_esdhc_imx_data[] __initconst = {
+#define imx50_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX50, _id, _hwid)
+ imx50_sdhci_esdhc_imx_data_entry(0, 1),
+ imx50_sdhci_esdhc_imx_data_entry(1, 2),
+ imx50_sdhci_esdhc_imx_data_entry(2, 3),
+ imx50_sdhci_esdhc_imx_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_sdhci_esdhc_imx_data
+imx51_sdhci_esdhc_imx_data[] __initconst = {
+#define imx51_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX51, _id, _hwid)
+ imx51_sdhci_esdhc_imx_data_entry(0, 1),
+ imx51_sdhci_esdhc_imx_data_entry(1, 2),
+ imx51_sdhci_esdhc_imx_data_entry(2, 3),
+ imx51_sdhci_esdhc_imx_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_sdhci_esdhc_imx_data
+imx53_sdhci_esdhc_imx_data[] __initconst = {
+#define imx53_sdhci_esdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_esdhc_imx_data_entry(MX53, _id, _hwid)
+ imx53_sdhci_esdhc_imx_data_entry(0, 1),
+ imx53_sdhci_esdhc_imx_data_entry(1, 2),
+ imx53_sdhci_esdhc_imx_data_entry(2, 3),
+ imx53_sdhci_esdhc_imx_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_sdhci_esdhc_imx_data
+imx6q_sdhci_usdhc_imx_data[] __initconst = {
+#define imx6q_sdhci_usdhc_imx_data_entry(_id, _hwid) \
+ imx_sdhci_usdhc_imx_data_entry(MX6Q, _id, _hwid)
+ imx6q_sdhci_usdhc_imx_data_entry(0, 1),
+ imx6q_sdhci_usdhc_imx_data_entry(1, 2),
+ imx6q_sdhci_usdhc_imx_data_entry(2, 3),
+ imx6q_sdhci_usdhc_imx_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_sdhci_esdhc_imx(
+ const struct imx_sdhci_esdhc_imx_data *data,
+ const struct esdhc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device_dmamask("sdhci-esdhc-imx", data->id, res,
+ ARRAY_SIZE(res), pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c
new file mode 100644
index 00000000..bbe66e1a
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_spi_imx_data_entry_single(soc, type, _devid, _id, hwid, _size) \
+ { \
+ .devid = _devid, \
+ .id = _id, \
+ .iobase = soc ## _ ## type ## hwid ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ ## type ## hwid, \
+ }
+
+#define imx_spi_imx_data_entry(soc, type, devid, id, hwid, size) \
+ [id] = imx_spi_imx_data_entry_single(soc, type, devid, id, hwid, size)
+
+#ifdef CONFIG_SOC_IMX1
+const struct imx_spi_imx_data imx1_cspi_data[] __initconst = {
+#define imx1_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX1, CSPI, "imx1-cspi", _id, _hwid, SZ_4K)
+ imx1_cspi_data_entry(0, 1),
+ imx1_cspi_data_entry(1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX21
+const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {
+#define imx21_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX21, CSPI, "imx21-cspi", _id, _hwid, SZ_4K)
+ imx21_cspi_data_entry(0, 1),
+ imx21_cspi_data_entry(1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX25
+const struct imx_spi_imx_data imx25_cspi_data[] __initconst = {
+#define imx25_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K)
+ imx25_cspi_data_entry(0, 1),
+ imx25_cspi_data_entry(1, 2),
+ imx25_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX25 */
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_spi_imx_data imx27_cspi_data[] __initconst = {
+#define imx27_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX27, CSPI, "imx27-cspi", _id, _hwid, SZ_4K)
+ imx27_cspi_data_entry(0, 1),
+ imx27_cspi_data_entry(1, 2),
+ imx27_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX27 */
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_spi_imx_data imx31_cspi_data[] __initconst = {
+#define imx31_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX31, CSPI, "imx31-cspi", _id, _hwid, SZ_4K)
+ imx31_cspi_data_entry(0, 1),
+ imx31_cspi_data_entry(1, 2),
+ imx31_cspi_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_spi_imx_data imx35_cspi_data[] __initconst = {
+#define imx35_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX35, CSPI, "imx35-cspi", _id, _hwid, SZ_4K)
+ imx35_cspi_data_entry(0, 1),
+ imx35_cspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX35 */
+
+#ifdef CONFIG_SOC_IMX50
+const struct imx_spi_imx_data imx50_cspi_data[] __initconst = {
+#define imx50_cspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX50, CSPI, "imx50-cspi", _id, _hwid, SZ_4K)
+ imx50_cspi_data_entry(1, 1),
+ imx50_cspi_data_entry(2, 2),
+ imx50_cspi_data_entry(3, 3),
+};
+#endif /* ifdef CONFIG_SOC_IMX50 */
+
+#ifdef CONFIG_SOC_IMX51
+const struct imx_spi_imx_data imx51_cspi_data __initconst =
+ imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 2, , SZ_4K);
+
+const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {
+#define imx51_ecspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX51, ECSPI, "imx51-ecspi", _id, _hwid, SZ_4K)
+ imx51_ecspi_data_entry(0, 1),
+ imx51_ecspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX51 */
+
+#ifdef CONFIG_SOC_IMX53
+const struct imx_spi_imx_data imx53_cspi_data __initconst =
+ imx_spi_imx_data_entry_single(MX53, CSPI, "imx53-cspi", 0, , SZ_4K);
+
+const struct imx_spi_imx_data imx53_ecspi_data[] __initconst = {
+#define imx53_ecspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX53, ECSPI, "imx53-ecspi", _id, _hwid, SZ_4K)
+ imx53_ecspi_data_entry(0, 1),
+ imx53_ecspi_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_SOC_IMX53 */
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_spi_imx_data imx6q_ecspi_data[] __initconst = {
+#define imx6q_ecspi_data_entry(_id, _hwid) \
+ imx_spi_imx_data_entry(MX6Q, ECSPI, "imx6q-ecspi", _id, _hwid, SZ_4K)
+ imx6q_ecspi_data_entry(0, 1),
+ imx6q_ecspi_data_entry(1, 2),
+ imx6q_ecspi_data_entry(2, 3),
+ imx6q_ecspi_data_entry(3, 4),
+ imx6q_ecspi_data_entry(4, 5),
+};
+#endif /* ifdef CONFIG_SOC_IMX6Q */
+
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
+ const struct spi_imx_master *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device(data->devid, data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-viv_gpu.c b/arch/arm/plat-mxc/devices/platform-viv_gpu.c
new file mode 100644
index 00000000..52c9b082
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-viv_gpu.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#ifdef CONFIG_ARCH_MX6
+#ifdef CONFIG_SOC_IMX6SL
+const struct imx_viv_gpu_data imx6_gpu_data __initconst = {
+ .phys_baseaddr = MX6SL_MMDC0_ARB_BASE_ADDR,
+ .iobase_3d = 0,
+ .irq_3d = -1,
+ .iobase_2d = MX6SL_GPU_2D_ARB_BASE_ADDR,
+ .irq_2d = MXC_INT_GPU2D_IRQ,
+ .iobase_vg = OPENVG_ARB_BASE_ADDR,
+ .irq_vg = MXC_INT_OPENVG_XAQ2,
+};
+#else
+const struct imx_viv_gpu_data imx6_gpu_data __initconst = {
+ .phys_baseaddr = 0,
+ .iobase_3d = GPU_3D_ARB_BASE_ADDR,
+ .irq_3d = MXC_INT_GPU3D_IRQ,
+ .iobase_2d = GPU_2D_ARB_BASE_ADDR,
+ .irq_2d = MXC_INT_GPU2D_IRQ,
+ .iobase_vg = OPENVG_ARB_BASE_ADDR,
+ .irq_vg = MXC_INT_OPENVG_XAQ2,
+};
+#endif
+#endif
+
+struct platform_device *__init imx_add_viv_gpu(
+ const struct imx_viv_gpu_data *data,
+ const struct viv_gpu_platform_data *pdata)
+{
+ u32 res_count = 0;
+ struct resource res[] = {
+ {
+ .name = "phys_baseaddr",
+ .start = data->phys_baseaddr,
+ .end = data->phys_baseaddr,
+ .flags = IORESOURCE_MEM,
+ }, {
+
+ .name = "iobase_3d",
+ .start = data->iobase_3d,
+ .end = data->iobase_3d + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_3d",
+ .start = data->irq_3d,
+ .end = data->irq_3d,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "iobase_2d",
+ .start = data->iobase_2d,
+ .end = data->iobase_2d + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_2d",
+ .start = data->irq_2d,
+ .end = data->irq_2d,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "iobase_vg",
+ .start = data->iobase_vg,
+ .end = data->iobase_vg + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "irq_vg",
+ .start = data->irq_vg,
+ .end = data->irq_vg,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ res_count = ARRAY_SIZE(res);
+ BUG_ON(!res_count);
+
+ if (!fuse_dev_is_available(MXC_DEV_3D)) {
+ res[1].start = 0;
+ res[1].end = 0;
+ res[2].start = -1;
+ res[2].end = -1;
+ }
+
+ if (!fuse_dev_is_available(MXC_DEV_2D)) {
+ res[3].start = 0;
+ res[3].end = 0;
+ res[4].start = -1;
+ res[4].end = -1;
+ }
+
+ if (!fuse_dev_is_available(MXC_DEV_OVG)) {
+ res[5].start = 0;
+ res[5].end = 0;
+ res[6].start = -1;
+ res[6].end = -1;
+ }
+
+ /* None GPU core exists */
+ if ((res[2].start == -1) &&
+ (res[4].start == -1) &&
+ (res[6].start == -1))
+ return ERR_PTR(-ENODEV);
+
+ return imx_add_platform_device_dmamask("galcore", 0,
+ res, res_count,
+ pdata, sizeof(*pdata),
+ DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
new file mode 100755
index 00000000..f2760dd0
--- /dev/null
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dvfs_core.c
+ *
+ * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module.
+ *
+ * Upon initialization, the DVFS driver initializes the DVFS hardware
+ * sets up driver nodes attaches to the DVFS interrupt and initializes internal
+ * data structures. When the DVFS interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and
+ * changes the CPU voltage according to translation table that is loaded into
+ * the driver.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#if defined(CONFIG_CPU_FREQ)
+#include <linux/cpufreq.h>
+#endif
+#include <asm/cpu.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+
+#define MXC_DVFSTHRS_UPTHR_MASK 0x0FC00000
+#define MXC_DVFSTHRS_UPTHR_OFFSET 22
+#define MXC_DVFSTHRS_DNTHR_MASK 0x003F0000
+#define MXC_DVFSTHRS_DNTHR_OFFSET 16
+#define MXC_DVFSTHRS_PNCTHR_MASK 0x0000003F
+#define MXC_DVFSTHRS_PNCTHR_OFFSET 0
+
+#define MXC_DVFSCOUN_DNCNT_MASK 0x00FF0000
+#define MXC_DVFSCOUN_DNCNT_OFFSET 16
+#define MXC_DVFSCOUN_UPCNT_MASK 0x000000FF
+#define MXC_DVFSCOUN_UPCNT_OFFSET 0
+
+#define MXC_DVFSEMAC_EMAC_MASK 0x000001FF
+#define MXC_DVFSEMAC_EMAC_OFFSET 0
+
+#define MXC_DVFSCNTR_DVFEV 0x10000000
+#define MXC_DVFSCNTR_LBMI 0x08000000
+#define MXC_DVFSCNTR_LBFL 0x06000000
+#define MXC_DVFSCNTR_DVFIS 0x01000000
+#define MXC_DVFSCNTR_FSVAIM 0x00400000
+#define MXC_DVFSCNTR_FSVAI_MASK 0x00300000
+#define MXC_DVFSCNTR_FSVAI_OFFSET 20
+#define MXC_DVFSCNTR_WFIM 0x00080000
+#define MXC_DVFSCNTR_WFIM_OFFSET 19
+#define MXC_DVFSCNTR_MAXF_MASK 0x00040000
+#define MXC_DVFSCNTR_MAXF_OFFSET 18
+#define MXC_DVFSCNTR_MINF_MASK 0x00020000
+#define MXC_DVFSCNTR_MINF_OFFSET 17
+#define MXC_DVFSCNTR_LTBRSR_MASK 0x00000018
+#define MXC_DVFSCNTR_LTBRSR_OFFSET 3
+#define MXC_DVFSCNTR_DVFEN 0x00000001
+
+#define CCM_CDCR_SW_DVFS_EN 0x20
+#define CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER 0x4
+#define CCM_CDHIPR_ARM_PODF_BUSY 0x10000
+
+int cpufreq_trig_needed;
+int dvfs_core_is_active;
+static struct mxc_dvfs_platform_data *dvfs_data;
+static struct device *dvfs_dev;
+static struct cpu_op *cpu_op_tbl;
+static int dvfs_core_resume;
+static int curr_op;
+static int old_op;
+static int dvfs_core_op;
+static int dvfs_config_setpoint;
+
+static int maxf;
+static int minf;
+
+extern void setup_pll(void);
+extern struct regulator *cpu_regulator;
+
+struct timeval core_prev_intr;
+
+void dump_dvfs_core_regs(void);
+void stop_dvfs(void);
+struct dvfs_op *(*get_dvfs_core_op)(int *op);
+
+static struct delayed_work dvfs_core_handler;
+
+/*
+ * Clock structures
+ */
+static struct clk *pll1_sw_clk;
+static struct clk *cpu_clk;
+static struct clk *dvfs_clk;
+
+static int cpu_op_nr;
+extern struct cpu_op *(*get_cpu_op)(int *op);
+
+static inline unsigned long dvfs_cpu_jiffies(unsigned long old, u_int div, u_int mult)
+{
+#if BITS_PER_LONG == 32
+
+ u64 result = ((u64) old) * ((u64) mult);
+ do_div(result, div);
+ return (unsigned long) result;
+
+#elif BITS_PER_LONG == 64
+
+ unsigned long result = old * ((u64) mult);
+ result /= div;
+ return result;
+
+#endif
+}
+
+enum {
+ FSVAI_FREQ_NOCHANGE = 0x0,
+ FSVAI_FREQ_INCREASE,
+ FSVAI_FREQ_DECREASE,
+ FSVAI_FREQ_EMERG,
+};
+
+/*
+ * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add; 2 for after EMA
+ */
+#define DVFS_LTBRSR (2 << MXC_DVFSCNTR_LTBRSR_OFFSET)
+
+static struct dvfs_op *dvfs_core_setpoint;
+extern int low_bus_freq_mode;
+extern int high_bus_freq_mode;
+extern int set_low_bus_freq(void);
+extern int set_high_bus_freq(int high_bus_speed);
+extern int low_freq_bus_used(void);
+extern struct mutex bus_freq_mutex;
+
+DEFINE_SPINLOCK(mxc_dvfs_core_lock);
+
+static void dvfs_load_config(int set_point)
+{
+ u32 reg;
+ reg = 0;
+
+ reg |= dvfs_core_setpoint[set_point].upthr << MXC_DVFSTHRS_UPTHR_OFFSET;
+ reg |= dvfs_core_setpoint[set_point].downthr <<
+ MXC_DVFSTHRS_DNTHR_OFFSET;
+ reg |= dvfs_core_setpoint[set_point].panicthr;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_THRS);
+
+ reg = 0;
+ reg |= dvfs_core_setpoint[set_point].downcnt <<
+ MXC_DVFSCOUN_DNCNT_OFFSET;
+ reg |= dvfs_core_setpoint[set_point].upcnt << MXC_DVFSCOUN_UPCNT_OFFSET;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_COUN);
+
+ /* Set EMAC value */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_EMAC);
+ reg &= ~MXC_DVFSEMAC_EMAC_MASK;
+ reg |= dvfs_core_setpoint[set_point].emac << MXC_DVFSEMAC_EMAC_OFFSET;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_EMAC);
+
+ dvfs_config_setpoint = set_point;
+}
+
+static int mx5_set_cpu_freq(int op)
+{
+ int arm_podf;
+ int podf;
+ int vinc = 0;
+ int ret = 0;
+ int org_cpu_rate;
+ unsigned long rate = 0;
+ int gp_volt = 0;
+ u32 reg;
+ u32 reg1;
+ u32 en_sw_dvfs = 0;
+ unsigned long flags;
+
+ if (cpu_op_tbl[op].pll_rate != cpu_op_tbl[old_op].pll_rate) {
+ org_cpu_rate = clk_get_rate(cpu_clk);
+ rate = cpu_op_tbl[op].cpu_rate;
+
+ if (org_cpu_rate == rate)
+ return ret;
+
+ gp_volt = cpu_op_tbl[op].cpu_voltage;
+ if (gp_volt == 0)
+ return ret;
+
+ /*Set the voltage for the GP domain. */
+ if ((!IS_ERR(cpu_regulator)) && (rate > org_cpu_rate)) {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE\n");
+ return ret;
+ }
+ udelay(dvfs_data->delay_time);
+ }
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+ /* PLL_RELOCK, set ARM_FREQ_SHIFT_DIVIDER */
+ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
+ /* Check if software_dvfs_en bit set */
+ if ((reg & CCM_CDCR_SW_DVFS_EN) != 0)
+ en_sw_dvfs = CCM_CDCR_SW_DVFS_EN;
+ else
+ en_sw_dvfs = 0x0;
+ reg &= ~(CCM_CDCR_SW_DVFS_EN);
+ reg &= 0xFFFFFFFB;
+ __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset);
+
+ setup_pll();
+ /* START the GPC main control FSM */
+ /* set VINC */
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset);
+ reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+
+ if (rate > org_cpu_rate)
+ reg |= 1 << MXC_GPCVCR_VINC_OFFSET;
+
+ reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) |
+ (1 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset);
+
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg &= ~(MXC_GPCCNTR_ADU_MASK | MXC_GPCCNTR_FUPD_MASK);
+ reg |= MXC_GPCCNTR_FUPD;
+ reg |= MXC_GPCCNTR_ADU;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+
+ reg |= MXC_GPCCNTR_STRT;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+ while (__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset)
+ & 0x4000)
+ udelay(10);
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ if ((!IS_ERR(cpu_regulator)) && (rate < org_cpu_rate)) {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "COULD NOT SET GP VOLTAGE!!!!\n");
+ return ret;
+ }
+ udelay(dvfs_data->delay_time);
+ }
+ /* set software_dvfs_en bit back to original setting*/
+ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
+ reg &= ~(CCM_CDCR_SW_DVFS_EN);
+ reg |= en_sw_dvfs;
+ clk_set_rate(cpu_clk, rate);
+ } else {
+ podf = cpu_op_tbl[op].cpu_podf;
+ gp_volt = cpu_op_tbl[op].cpu_voltage;
+
+ /* Change arm_podf only */
+ /* set ARM_FREQ_SHIFT_DIVIDER */
+ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
+
+ /* Check if software_dvfs_en bit set */
+ if ((reg & CCM_CDCR_SW_DVFS_EN) != 0)
+ en_sw_dvfs = CCM_CDCR_SW_DVFS_EN;
+ else
+ en_sw_dvfs = 0x0;
+
+ reg &= ~(CCM_CDCR_SW_DVFS_EN | CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER);
+ reg |= CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER;
+ __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset);
+
+ /* Get ARM_PODF */
+ reg = __raw_readl(ccm_base + dvfs_data->ccm_cacrr_offset);
+ arm_podf = reg & 0x07;
+ if (podf == arm_podf) {
+ printk(KERN_DEBUG
+ "No need to change freq and voltage!!!!\n");
+ return 0;
+ }
+ /* Check if FSVAI indicate freq up */
+ if ((!IS_ERR(cpu_regulator)) && (podf < arm_podf)) {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "COULD NOT SET GP VOLTAGE!!!!\n");
+ return 0;
+ }
+ udelay(dvfs_data->delay_time);
+ vinc = 1;
+ } else {
+ vinc = 0;
+ }
+
+ arm_podf = podf;
+ /* Set ARM_PODF */
+ reg &= 0xFFFFFFF8;
+ reg |= arm_podf;
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+
+ reg1 = __raw_readl(ccm_base + dvfs_data->ccm_cdhipr_offset);
+ while (1) {
+ if ((reg1 & CCM_CDHIPR_ARM_PODF_BUSY) == 0) {
+ __raw_writel(reg,
+ ccm_base + dvfs_data->ccm_cacrr_offset);
+ break;
+ } else {
+ reg1 = __raw_readl(
+ ccm_base + dvfs_data->ccm_cdhipr_offset);
+ printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n");
+ }
+ }
+ /* set VINC */
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_vcr_offset);
+ reg &=
+ ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) |
+ (100 << MXC_GPCVCR_VCNT_OFFSET) |
+ (vinc << MXC_GPCVCR_VINC_OFFSET);
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_vcr_offset);
+
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg &= (~(MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD
+ | MXC_GPCCNTR_STRT));
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg |= MXC_GPCCNTR_ADU | MXC_GPCCNTR_FUPD;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg |= MXC_GPCCNTR_STRT;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+
+ /* Wait for arm podf Enable */
+ while ((__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset) &
+ MXC_GPCCNTR_STRT) == MXC_GPCCNTR_STRT) {
+ printk(KERN_DEBUG "Waiting arm_podf enabled!\n");
+ udelay(10);
+ }
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ if ((!IS_ERR(cpu_regulator)) && (vinc == 0)) {
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "COULD NOT SET GP VOLTAGE\n!!!");
+ return ret;
+ }
+ udelay(dvfs_data->delay_time);
+ }
+
+ /* Clear the ARM_FREQ_SHIFT_DIVIDER and */
+ /* set software_dvfs_en bit back to original setting*/
+ reg = __raw_readl(ccm_base + dvfs_data->ccm_cdcr_offset);
+ reg &= ~(CCM_CDCR_SW_DVFS_EN | CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER);
+ reg |= en_sw_dvfs;
+ __raw_writel(reg, ccm_base + dvfs_data->ccm_cdcr_offset);
+ }
+ return ret;
+}
+
+static int mx6_set_cpu_freq(int op)
+{
+ int ret = 0;
+ int org_cpu_rate;
+ unsigned long rate = 0;
+ int gp_volt = cpu_op_tbl[op].cpu_voltage;
+
+ org_cpu_rate = clk_get_rate(cpu_clk);
+ rate = cpu_op_tbl[op].cpu_rate;
+
+ if (rate == org_cpu_rate)
+ return ret;
+
+ if ((!IS_ERR(cpu_regulator)) && (rate > org_cpu_rate)) {
+ /* Increase voltage first. */
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT INCREASE GP VOLTAGE!!!!\n");
+ return ret;
+ }
+ udelay(dvfs_data->delay_time);
+ }
+ ret = clk_set_rate(cpu_clk, rate);
+ if (ret != 0) {
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+ return ret;
+ }
+
+ if ((!IS_ERR(cpu_regulator)) && (rate < org_cpu_rate)) {
+ /* Increase voltage first. */
+ ret = regulator_set_voltage(cpu_regulator, gp_volt,
+ gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT INCREASE GP VOLTAGE!!!!\n");
+ return ret;
+ }
+ }
+ return ret;
+}
+
+
+static int set_cpu_freq(int op)
+{
+ int ret = 0;
+
+ if (cpu_is_mx6())
+ ret = mx6_set_cpu_freq(op);
+ else
+ ret = mx5_set_cpu_freq(op);
+
+ cpufreq_trig_needed = 1;
+ old_op = op;
+ return ret;
+}
+
+static int start_dvfs(void)
+{
+ u32 reg, cpu_rate;
+ unsigned long flags;
+
+ if (dvfs_core_is_active)
+ return 0;
+
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+
+ clk_enable(dvfs_clk);
+
+ /* get current working point */
+ cpu_rate = clk_get_rate(cpu_clk);
+ curr_op = cpu_op_nr - 1;
+ do {
+ if (cpu_rate <= cpu_op_tbl[curr_op].cpu_rate)
+ break;
+ } while (--curr_op >= 0);
+ old_op = curr_op;
+
+ dvfs_load_config(curr_op);
+
+ if (curr_op == 0)
+ maxf = 1;
+ else
+ maxf = 0;
+ if (curr_op == (cpu_op_nr - 1))
+ minf = 1;
+ else
+ minf = 0;
+
+ /* config reg GPC_CNTR */
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+
+ reg &= ~MXC_GPCCNTR_GPCIRQM;
+ /* GPCIRQ=1, select ARM IRQ */
+ reg |= MXC_GPCCNTR_GPCIRQ_ARM;
+ /* ADU=1, select ARM domain */
+ if (!cpu_is_mx6())
+ reg |= MXC_GPCCNTR_ADU;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+
+ /* Set PREDIV bits */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ reg = (reg & ~(dvfs_data->prediv_mask));
+ reg |= (dvfs_data->prediv_val) << (dvfs_data->prediv_offset);
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
+
+ /* Enable DVFS interrupt */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ /* FSVAIM=0 */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+
+ /* Set MAXF, MINF */
+ reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK
+ | MXC_DVFSCNTR_MINF_MASK));
+ reg |= 1 << MXC_DVFSCNTR_MAXF_OFFSET;
+
+ /* Select ARM domain */
+ reg |= MXC_DVFSCNTR_DVFIS;
+ /* Enable DVFS frequency adjustment interrupt */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+ /* Set load tracking buffer register source */
+ reg = (reg & ~MXC_DVFSCNTR_LTBRSR_MASK);
+ reg |= DVFS_LTBRSR;
+ /* Set DIV3CK */
+ reg = (reg & ~(dvfs_data->div3ck_mask));
+ reg |= (dvfs_data->div3ck_val) << (dvfs_data->div3ck_offset);
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
+
+ /* Enable DVFS */
+ if (cpu_is_mx6()) {
+ unsigned long cpu_wfi = 0;
+ int num_cpus = num_possible_cpus();
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_EMAC);
+ /* Need to enable DVFS tracking for each core that is active */
+ do {
+ if (cpu_active(num_cpus))
+ set_bit(num_cpus, &cpu_wfi);
+ } while (num_cpus--);
+ reg |= cpu_wfi << 9;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_EMAC);
+ } else {
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ reg |= MXC_DVFSCNTR_DVFEN;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ }
+
+ dvfs_core_is_active = 1;
+
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ printk(KERN_DEBUG "DVFS is started\n");
+ return 0;
+}
+
+/*!
+ * This function is called for module initialization.
+ * It sets up the DVFS hardware.
+ * It sets default values for DVFS thresholds and counters. The default
+ * values was chosen from a set of different reasonable values. They was tested
+ * and the default values in the driver gave the best results.
+ * More work should be done to find optimal values.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ *
+ */
+static int init_dvfs_controller(void)
+{
+ /* DVFS loading config */
+ dvfs_load_config(0);
+
+ return 0;
+}
+
+static irqreturn_t dvfs_irq(int irq, void *dev_id)
+{
+ u32 reg;
+
+ /* Check if DVFS0 (ARM) id requesting for freqency/voltage update */
+ if ((__raw_readl(gpc_base + dvfs_data->gpc_cntr_offset)
+ & MXC_GPCCNTR_DVFS0CR) == 0)
+ return IRQ_NONE;
+
+ /* Mask DVFS irq */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSCNTR_FSVAIM;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
+
+ /* Mask GPC1 irq */
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg |= MXC_GPCCNTR_GPCIRQM | 0x1000000;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+
+ schedule_delayed_work(&dvfs_core_handler, 0);
+ return IRQ_HANDLED;
+}
+
+static void dvfs_core_work_handler(struct work_struct *work)
+{
+ u32 fsvai;
+ u32 reg;
+ u32 curr_cpu = 0;
+ int ret = 0;
+ int low_freq_bus_ready = 0;
+ int bus_incr = 0, cpu_dcr = 0;
+ int cpu;
+
+ low_freq_bus_ready = low_freq_bus_used();
+
+ /* Check DVFS frequency adjustment interrupt status */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET;
+ /* Check FSVAI, FSVAI=0 is error */
+ if (fsvai == FSVAI_FREQ_NOCHANGE) {
+ /* Do nothing. Freq change is not required */
+ goto END;
+ }
+ curr_cpu = clk_get_rate(cpu_clk);
+ /* If FSVAI indicate freq down,
+ check arm-clk is not in lowest frequency*/
+ if (fsvai == FSVAI_FREQ_DECREASE) {
+ if (curr_cpu <= cpu_op_tbl[cpu_op_nr - 1].cpu_rate) {
+ minf = 1;
+ mutex_lock(&bus_freq_mutex);
+ if (low_bus_freq_mode) {
+ mutex_unlock(&bus_freq_mutex);
+ goto END;
+ } else
+ mutex_unlock(&bus_freq_mutex);
+ } else {
+ /* freq down */
+ curr_op++;
+ maxf = 0;
+ if (curr_op >= cpu_op_nr) {
+ curr_op = cpu_op_nr - 1;
+ goto END;
+ }
+ cpu_dcr = 1;
+ dvfs_load_config(curr_op);
+ }
+ } else {
+ if (curr_cpu == cpu_op_tbl[0].cpu_rate) {
+ maxf = 1;
+ goto END;
+ } else {
+ mutex_lock(&bus_freq_mutex);
+ if (!high_bus_freq_mode &&
+ dvfs_config_setpoint == (cpu_op_nr + 1)) {
+ /* bump up LP freq first. */
+ bus_incr = 1;
+ dvfs_load_config(cpu_op_nr);
+ } else {
+ /* freq up */
+ curr_op = 0;
+ maxf = 1;
+ minf = 0;
+ dvfs_load_config(0);
+ }
+ mutex_unlock(&bus_freq_mutex);
+ }
+ }
+
+ low_freq_bus_ready = low_freq_bus_used();
+ mutex_lock(&bus_freq_mutex);
+ if ((curr_op == cpu_op_nr - 1) && (!low_bus_freq_mode)
+ && (low_freq_bus_ready) && !bus_incr) {
+ if (!minf)
+ set_cpu_freq(curr_op);
+ /* If dvfs_core_op is greater than cpu_op_nr, it implies
+ * we support LPAPM mode for this platform.
+ */
+ if (dvfs_core_op > cpu_op_nr) {
+ set_low_bus_freq();
+ dvfs_load_config(cpu_op_nr + 1);
+ }
+ mutex_unlock(&bus_freq_mutex);
+ } else {
+ if (!high_bus_freq_mode) {
+ mutex_unlock(&bus_freq_mutex);
+ set_high_bus_freq(1);
+ } else
+ mutex_unlock(&bus_freq_mutex);
+ if (!bus_incr)
+ ret = set_cpu_freq(curr_op);
+ bus_incr = 0;
+ }
+
+END:
+ if (cpufreq_trig_needed == 1) {
+ /*Fix loops-per-jiffy */
+#ifdef CONFIG_SMP
+ for_each_online_cpu(cpu)
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ dvfs_cpu_jiffies(per_cpu(cpu_data, cpu).loops_per_jiffy,
+ curr_cpu / 1000, clk_get_rate(cpu_clk) / 1000);
+#else
+ u32 old_loops_per_jiffy = loops_per_jiffy;
+
+ loops_per_jiffy =
+ dvfs_cpu_jiffies(old_loops_per_jiffy,
+ curr_cpu/1000, clk_get_rate(cpu_clk) / 1000);
+#endif
+#if defined (CONFIG_CPU_FREQ)
+ /* Fix CPU frequency for CPUFREQ. */
+ for (cpu = 0; cpu < num_online_cpus(); cpu++)
+ cpufreq_get(cpu);
+#endif
+ cpufreq_trig_needed = 0;
+ }
+
+ /* Set MAXF, MINF */
+ reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK));
+ reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET;
+ reg |= minf << MXC_DVFSCNTR_MINF_OFFSET;
+
+ /* Enable DVFS interrupt */
+ /* FSVAIM=0 */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+ reg |= FSVAI_FREQ_NOCHANGE;
+ /* LBFL=1 */
+ reg = (reg & ~MXC_DVFSCNTR_LBFL);
+ reg |= MXC_DVFSCNTR_LBFL;
+ __raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
+ /*Unmask GPC1 IRQ */
+ reg = __raw_readl(gpc_base + dvfs_data->gpc_cntr_offset);
+ reg &= ~MXC_GPCCNTR_GPCIRQM;
+ __raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
+
+}
+
+
+/*!
+ * This function disables the DVFS module.
+ */
+void stop_dvfs(void)
+{
+ u32 reg = 0;
+ unsigned long flags;
+ u32 curr_cpu;
+ int cpu;
+#ifndef CONFIG_SMP
+ unsigned long old_loops_per_jiffy;
+#endif
+
+ if (dvfs_core_is_active) {
+
+ /* Mask dvfs irq, disable DVFS */
+ reg = __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_CNTR);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSCNTR_FSVAIM;
+ __raw_writel(reg, dvfs_data->membase
+ + MXC_DVFSCORE_CNTR);
+
+ curr_op = 0;
+ mutex_lock(&bus_freq_mutex);
+ if (!high_bus_freq_mode) {
+ mutex_unlock(&bus_freq_mutex);
+ set_high_bus_freq(1);
+ } else
+ mutex_unlock(&bus_freq_mutex);
+
+ curr_cpu = clk_get_rate(cpu_clk);
+ if (curr_cpu != cpu_op_tbl[curr_op].cpu_rate) {
+ set_cpu_freq(curr_op);
+
+ /*Fix loops-per-jiffy */
+#ifdef CONFIG_SMP
+ for_each_online_cpu(cpu)
+ per_cpu(cpu_data, cpu).loops_per_jiffy =
+ dvfs_cpu_jiffies(per_cpu(cpu_data, cpu).loops_per_jiffy,
+ curr_cpu/1000, clk_get_rate(cpu_clk) / 1000);
+#else
+ old_loops_per_jiffy = loops_per_jiffy;
+
+ loops_per_jiffy =
+ dvfs_cpu_jiffies(old_loops_per_jiffy,
+ curr_cpu/1000, clk_get_rate(cpu_clk) / 1000);
+#endif
+
+#if defined (CONFIG_CPU_FREQ)
+ /* Fix CPU frequency for CPUFREQ. */
+ for (cpu = 0; cpu < num_online_cpus(); cpu++)
+ cpufreq_get(cpu);
+#endif
+ }
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+
+ reg = __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_CNTR);
+ reg = (reg & ~MXC_DVFSCNTR_DVFEN);
+ __raw_writel(reg, dvfs_data->membase
+ + MXC_DVFSCORE_CNTR);
+
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ dvfs_core_is_active = 0;
+
+ clk_disable(dvfs_clk);
+ }
+
+ printk(KERN_DEBUG "DVFS is stopped\n");
+}
+
+void dump_dvfs_core_regs()
+{
+ struct timeval cur;
+ u32 diff = 0;
+ if (core_prev_intr.tv_sec == 0)
+ do_gettimeofday(&core_prev_intr);
+ else {
+ do_gettimeofday(&cur);
+ diff = (cur.tv_sec - core_prev_intr.tv_sec)*1000000
+ + (cur.tv_usec - core_prev_intr.tv_usec);
+ core_prev_intr = cur;
+ }
+ if (diff < 90000)
+ printk(KERN_DEBUG "diff = %d\n", diff);
+
+ printk(KERN_INFO "THRS = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS));
+ printk(KERN_INFO "COUNT = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x04));
+ printk(KERN_INFO "SIG1 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x08));
+ printk(KERN_INFO "SIG0 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x0c));
+ printk(KERN_INFO "GPC0 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x10));
+ printk(KERN_INFO "GPC1 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x14));
+ printk(KERN_INFO "GPBT = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x18));
+ printk(KERN_INFO "EMAC = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x1c));
+ printk(KERN_INFO "CNTR = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x20));
+ printk(KERN_INFO "LTR0_0 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x24));
+ printk(KERN_INFO "LTR0_1 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x28));
+ printk(KERN_INFO "LTR1_0 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x2c));
+ printk(KERN_DEBUG "LTR1_1 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x30));
+ printk(KERN_INFO "PT0 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x34));
+ printk(KERN_INFO "PT1 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x38));
+ printk(KERN_INFO "PT2 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x3c));
+ printk(KERN_INFO "PT3 = 0x%08x\n",
+ __raw_readl(dvfs_data->membase
+ + MXC_DVFSCORE_THRS + 0x40));
+}
+#if 0
+static ssize_t downthreshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", dvfs_core_setpoint[0].downthr);
+}
+
+static ssize_t downthreshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int ret = 0;
+ int val;
+ ret = sscanf(buf, "%u", &val);
+ dvfs_core_setpoint[0].downthr = val;
+
+ return size;
+}
+
+static ssize_t downcount_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%u\n", dvfs_core_setpoint[0].downcnt);
+}
+
+static ssize_t downcount_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int ret = 0;
+ int val;
+ ret = sscanf(buf, "%u", &val);
+ dvfs_core_setpoint[0].downcnt = val;
+
+ return size;
+}
+#endif
+
+static ssize_t dvfs_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (dvfs_core_is_active)
+ return sprintf(buf, "DVFS is enabled\n");
+ else
+ return sprintf(buf, "DVFS is disabled\n");
+}
+
+static ssize_t dvfs_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL) {
+ if (start_dvfs() != 0)
+ printk(KERN_ERR "Failed to start DVFS\n");
+ } else if (strstr(buf, "0") != NULL)
+ stop_dvfs();
+
+ return size;
+}
+
+static ssize_t dvfs_regs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (dvfs_core_is_active)
+ dump_dvfs_core_regs();
+ return 0;
+}
+
+static ssize_t dvfs_regs_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (dvfs_core_is_active)
+ dump_dvfs_core_regs();
+ return 0;
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
+ dvfs_enable_show, dvfs_enable_store);
+static DEVICE_ATTR(show_regs, S_IRUGO, dvfs_regs_show,
+ dvfs_regs_store);
+
+/*!
+ * This is the probe routine for the DVFS driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ */
+static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct resource *res;
+
+ printk(KERN_INFO "mxc_dvfs_core_probe\n");
+ dvfs_dev = &pdev->dev;
+ dvfs_data = pdev->dev.platform_data;
+
+ INIT_DELAYED_WORK(&dvfs_core_handler, dvfs_core_work_handler);
+
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (IS_ERR(pll1_sw_clk)) {
+ printk(KERN_INFO "%s: failed to get pll1_sw_clk\n", __func__);
+ return PTR_ERR(pll1_sw_clk);
+ }
+
+ cpu_clk = clk_get(NULL, dvfs_data->clk1_id);
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+ if (!cpu_is_mx6()) {
+ dvfs_clk = clk_get(NULL, dvfs_data->clk2_id);
+ if (IS_ERR(dvfs_clk)) {
+ printk(KERN_ERR "%s: failed to get dvfs clock\n", __func__);
+ return PTR_ERR(dvfs_clk);
+ }
+ }
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ err = -ENODEV;
+ goto err1;
+ }
+ dvfs_data->membase = ioremap(res->start, res->end - res->start + 1);
+ /*
+ * Request the DVFS interrupt
+ */
+ dvfs_data->irq = platform_get_irq(pdev, 0);
+ if (dvfs_data->irq < 0) {
+ err = dvfs_data->irq;
+ goto err2;
+ }
+
+ /* request the DVFS interrupt */
+ err = request_irq(dvfs_data->irq, dvfs_irq, IRQF_SHARED, "dvfs",
+ dvfs_dev);
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to attach to DVFS interrupt,err = %d",
+ err);
+ goto err2;
+ }
+
+ dvfs_core_setpoint = get_dvfs_core_op(&dvfs_core_op);
+ if (dvfs_core_setpoint == NULL) {
+ printk(KERN_ERR "No dvfs_core working point table defined\n");
+ goto err3;
+ }
+
+ clk_enable(dvfs_clk);
+ err = init_dvfs_controller();
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to initialize DVFS");
+ return err;
+ }
+ clk_disable(dvfs_clk);
+
+ err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr);
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for DVFS");
+ goto err3;
+ }
+
+ err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_show_regs.attr);
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for DVFS");
+ goto err3;
+ }
+
+ /* Set the current working point. */
+ cpu_op_tbl = get_cpu_op(&cpu_op_nr);
+ old_op = 0;
+ curr_op = 0;
+ dvfs_core_resume = 0;
+ cpufreq_trig_needed = 0;
+
+ return err;
+err3:
+ free_irq(dvfs_data->irq, dvfs_dev);
+err2:
+ iounmap(dvfs_data->membase);
+err1:
+ dev_err(&pdev->dev, "Failed to probe DVFS CORE\n");
+ return err;
+}
+
+/*!
+ * This function is called to put DVFS in a low power state.
+ *
+ * @param pdev the device structure
+ * @param state the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_core_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ if (dvfs_core_is_active) {
+ dvfs_core_resume = 1;
+ stop_dvfs();
+ }
+
+ return 0;
+}
+
+/*!
+ * This function is called to resume the MU from a low power state.
+ *
+ * @param dev the device structure
+ * @param level the stage in device suspension process that we want the
+ * device to be put in
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_core_resume(struct platform_device *pdev)
+{
+ if (dvfs_core_resume) {
+ dvfs_core_resume = 0;
+ start_dvfs();
+ }
+
+ return 0;
+}
+
+static struct platform_driver mxc_dvfs_core_driver = {
+ .driver = {
+ .name = "imx_dvfscore",
+ },
+ .probe = mxc_dvfs_core_probe,
+ .suspend = mxc_dvfs_core_suspend,
+ .resume = mxc_dvfs_core_resume,
+};
+
+static int __init dvfs_init(void)
+{
+ if (platform_driver_register(&mxc_dvfs_core_driver) != 0) {
+ printk(KERN_ERR "mxc_dvfs_core_driver register failed\n");
+ return -ENODEV;
+ }
+
+ dvfs_core_is_active = 0;
+ printk(KERN_INFO "DVFS driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit dvfs_cleanup(void)
+{
+ stop_dvfs();
+
+ /* release the DVFS interrupt */
+ free_irq(dvfs_data->irq, dvfs_dev);
+
+ sysfs_remove_file(&dvfs_dev->kobj, &dev_attr_enable.attr);
+ /* Unregister the device structure */
+ platform_driver_unregister(&mxc_dvfs_core_driver);
+
+ iounmap(ccm_base);
+ iounmap(dvfs_data->membase);
+ clk_put(cpu_clk);
+ clk_put(dvfs_clk);
+
+ dvfs_core_is_active = 0;
+ printk(KERN_INFO "DVFS driver module unloaded\n");
+
+}
+
+late_initcall(dvfs_init);
+module_exit(dvfs_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("DVFS driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/dvfs_per.c b/arch/arm/plat-mxc/dvfs_per.c
new file mode 100755
index 00000000..74b10144
--- /dev/null
+++ b/arch/arm/plat-mxc/dvfs_per.c
@@ -0,0 +1,936 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dvfs_per.c
+ *
+ * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module.
+ *
+ * Upon initialization, the DVFS driver initializes the DVFS hardware
+ * sets up driver nodes attaches to the DVFS interrupt and initializes internal
+ * data structures. When the DVFS interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and
+ * changes the CPU voltage according to translation table that is loaded into
+ * the driver.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/sdram_autogating.h>
+#include <mach/clock.h>
+#if defined(CONFIG_ARCH_MX37)
+#include <mach/mxc_dptc.h>
+#endif
+
+/* DVFS PER */
+#define MXC_DVFS_PER_LTR0 0x00
+#define MXC_DVFS_PER_LTR1 0x04
+#define MXC_DVFS_PER_LTR2 0x08
+#define MXC_DVFS_PER_LTR3 0x0C
+#define MXC_DVFS_PER_LTBR0 0x10
+#define MXC_DVFS_PER_LTBR1 0x14
+#define MXC_DVFS_PER_PMCR0 0x18
+#define MXC_DVFS_PER_PMCR1 0x1C
+
+#define DRIVER_NAME "DVFSPER"
+#define DVFS_PER_DEBUG 0
+
+static int dvfs_per_stop;
+static int dvfs_per_low_freq;
+static int dvfs_per_suspended;
+static volatile int freq_increased;
+static int cur_setpoint;
+static struct delayed_work dvfs_per_work;
+static struct clk *dvfs_clk;
+static struct clk *main_bus_clk;
+static struct clk *pll2;
+static struct clk *lpapm;
+static struct clk *cpu_clk;
+static struct clk *axi_b_clk;
+static struct clk *ahb_clk;
+static struct clk *ddr_hf_clk;
+static struct regulator *lp_regulator;
+
+/* Flag used to indicate if dvfs_per is active. */
+static int dvfs_per_is_active;
+static int dvfs_per_is_paused;
+static int ipu_freq_scaled;
+
+struct dvfsper_device *dvfsper_device_data;
+/* DVFS platform data pointer */
+struct mxc_dvfsper_data *dvfsper_plt_data;
+struct timeval prev_intr;
+
+int start_dvfs_per(void);
+void stop_dvfs_per(void);
+int dvfs_per_active(void);
+int dvfs_per_divider_active(void);
+int dvfs_per_pixel_clk_limit(void);
+
+extern int low_bus_freq_mode;
+extern int bus_freq_scaling_is_active;
+
+
+/*!
+ * In case the MXC device has multiple DVFS modules, this structure is used to
+ * store information specific to each DVFS module.
+ */
+struct dvfsper_device {
+ /* DVFS delayed work */
+ struct delayed_work dvfs_work;
+ /* DVFS regulator */
+ struct regulator *dvfs_reg;
+ /* DVFS clock */
+ struct clk *dvfs_clk;
+ /* The interrupt number used by the DVFS device */
+ int irq;
+};
+struct dvfs_wp dvfs_per_setpoint[] = {{33, 7, 33, 20, 40, 0x10},
+ {18, 0, 33, 25, 10, 0x10},
+ /* When LP is at 24MHz */
+ {8, 0, 10, 5, 5, 0x2E},};
+
+enum {
+ FSVAI_FREQ_NOCHANGE = 0x0,
+ FSVAI_FREQ_INCREASE,
+ FSVAI_FREQ_DECREASE,
+ FSVAI_FREQ_EMERG,
+};
+
+#define LOW_BUS_FREQ 24000000
+
+DEFINE_SPINLOCK(mxc_dvfs_per_lock);
+
+static void dvfs_per_load_config(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR0);
+ reg &= ~MXC_DVFSLTR0_UPTHR_MASK;
+ reg &= ~MXC_DVFSLTR0_DNTHR_MASK;
+ reg |= dvfs_per_setpoint[cur_setpoint].upthr <<
+ MXC_DVFSLTR0_UPTHR_OFFSET;
+ reg |= dvfs_per_setpoint[cur_setpoint].downthr <<
+ MXC_DVFSLTR0_DNTHR_OFFSET;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR0);
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR1);
+ reg &= ~MXC_DVFSLTR1_PNCTHR_MASK;
+ reg &= ~MXC_DVFSLTR1_DNCNT_MASK;
+ reg &= ~MXC_DVFSLTR1_UPCNT_MASK;
+ reg |= dvfs_per_setpoint[cur_setpoint].downcnt <<
+ MXC_DVFSLTR1_DNCNT_OFFSET;
+ reg |= dvfs_per_setpoint[cur_setpoint].upcnt <<
+ MXC_DVFSLTR1_UPCNT_OFFSET;
+ reg |= dvfs_per_setpoint[cur_setpoint].panicthr <<
+ MXC_DVFSLTR1_PNCTHR_OFFSET;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR1);
+
+ reg = dvfs_per_setpoint[cur_setpoint].emac <<
+ MXC_DVFSLTR2_EMAC_OFFSET;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR2);
+}
+
+/*!
+ * This function is called for module initialization.
+ * It sets up the DVFS hardware.
+ * It sets default values for DVFS thresholds and counters. The default
+ * values was chosen from a set of different reasonable values. They was tested
+ * and the default values in the driver gave the best results.
+ * More work should be done to find optimal values.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ *
+ */
+static int init_dvfs_per_controller(void)
+{
+ u32 reg;
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR0);
+ /* DIV3CLK */
+ reg &= ~dvfsper_plt_data->div3_mask;
+ reg |= (dvfsper_plt_data->div3_div <<
+ dvfsper_plt_data->div3_offset);
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR0);
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR1);
+ /* Set load tracking buffer register source */
+ reg &= ~MXC_DVFSLTR1_LTBRSR;
+ reg |= MXC_DVFSLTR1_LTBRSR;
+ reg &= ~MXC_DVFSLTR1_LTBRSH;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR1);
+
+ /* Enable all the peripheral signals, but VPU and IPU panic*/
+ __raw_writel(0x30000, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR1);
+ /* Disable weighted load tracking signals */
+ __raw_writel(0, dvfsper_plt_data->membase + MXC_DVFS_PER_LTR3);
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ reg &= ~MXC_DVFSPMCR0_DVFEV;
+ reg |= MXC_DVFSPMCR0_LBMI;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+
+ /* DVFS loading config */
+ dvfs_per_load_config();
+ return 0;
+}
+
+#if DVFS_PER_DEBUG
+static void dump_dvfs_per_regs(void)
+{
+ struct timeval cur;
+ u32 diff = 0;
+ if (prev_intr.tv_sec == 0)
+ do_gettimeofday(&prev_intr);
+ else {
+ do_gettimeofday(&cur);
+ diff = (cur.tv_sec - prev_intr.tv_sec)*1000000
+ + (cur.tv_usec - prev_intr.tv_usec);
+ prev_intr = cur;
+ }
+ if (diff < 90000)
+ printk(KERN_INFO "diff = %d\n", diff);
+
+ printk(KERN_INFO "LTRO = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR0));
+ printk(KERN_INFO "LTR1 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR1));
+ printk(KERN_INFO "LTR2 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR2));
+ printk(KERN_INFO "LTR3 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTR3));
+ printk(KERN_INFO "LBTR0 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTBR0));
+ printk(KERN_INFO "LBTR1 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_LTBR1));
+ printk(KERN_INFO "PMCR0 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0));
+ printk(KERN_INFO "PMCR1 = 0x%08x\n",
+ __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR1));
+}
+#endif
+
+static irqreturn_t dvfs_per_irq(int irq, void *dev_id)
+{
+ u32 reg;
+
+ /* Check if DVFS1 (PER) id requesting for freqency/voltage update */
+ if ((__raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr) &
+ MXC_GPCCNTR_DVFS1CR) == 0)
+ return IRQ_NONE;
+ /* Mask DVFS irq */
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSPMCR0_FSVAIM;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ /* Mask GPC1 irq */
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg |= MXC_GPCCNTR_GPCIRQM | 0x1000000;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ if (reg & MXC_DVFSPMCR0_LBFL) {
+ /* clear LBFL */
+ reg = (reg & ~MXC_DVFSPMCR0_LBFL);
+ reg |= MXC_DVFSPMCR0_LBFL;
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ }
+ schedule_delayed_work(&dvfs_per_work, 0);
+ return IRQ_HANDLED;
+}
+
+static void dvfs_per_handler(struct work_struct *work)
+{
+ u32 fsvai;
+ u32 reg;
+ u32 ret;
+ unsigned long flags;
+ int retry = 20;
+
+ /* Check DVFS frequency adjustment interrupt status */
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ fsvai = (reg & MXC_DVFSPMCR0_FSVAI_MASK) >> MXC_DVFSPMCR0_FSVAI_OFFSET;
+ /* Check FSVAI, FSVAI=0 is error */
+ if (fsvai == FSVAI_FREQ_NOCHANGE) {
+ /* Do nothing. Freq change is not required */
+ goto END;
+ }
+
+#if DVFS_PER_DEBUG
+ dump_dvfs_per_regs();
+#endif
+ /* If FSVAI indicate freq down. */
+ if (fsvai == FSVAI_FREQ_DECREASE) {
+ if (cpu_is_mx51()) {
+ /*Change the DDR freq to 133Mhz. */
+ clk_set_rate(ddr_hf_clk,
+ clk_round_rate(ddr_hf_clk, 133000000));
+ }
+
+#ifndef DVFS_SW_WORKAROUND
+ spin_lock_irqsave(&mxc_dvfs_per_lock, flags);
+ reg = __raw_readl(dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ reg &= ~MXC_DVFSPMCR0_UDCS;
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+
+ /* Set the peripheral divider */
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg &= ~(MXC_GPCCNTR_ADU_MASK | MXC_GPCCNTR_FUPD_MASK);
+ reg |= MXC_GPCCNTR_FUPD;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->gpc_vcr_reg_addr);
+ reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |= (1 << MXC_GPCVCR_VCNTU_OFFSET) |
+ (1 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, dvfsper_plt_data->gpc_vcr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg |= MXC_GPCCNTR_STRT;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ retry = 10;
+ while ((__raw_readl(
+ dvfsper_plt_data->gpc_cntr_reg_addr) & 0x4000)
+ && retry > 0) {
+ udelay(10);
+ retry--;
+ }
+ spin_unlock_irqrestore(&mxc_dvfs_per_lock, flags);
+#else
+ /*Set the frequencies manually */
+ rate = clk_get_rate(axi_b_clk);
+ clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, rate/2));
+
+ rate = clk_get_rate(ahb_clk);
+ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, rate/2));
+#endif
+ dvfs_per_low_freq = 1;
+ if (clk_get_rate(main_bus_clk) == LOW_BUS_FREQ) {
+ cur_setpoint = 2;
+ } else {
+#if defined(CONFIG_ARCH_MX37)
+ dptc_suspend(DPTC_LP_ID);
+#endif
+ cur_setpoint = 1;
+#ifndef DVFS_SW_WORKAROUND
+ clk_set_parent(main_bus_clk, clk_get(NULL, "pll2"));
+#endif
+ }
+#ifndef DVFS_SW_WORKAROUND
+ /* Drop the LP domain voltage */
+ ret = regulator_set_voltage(lp_regulator,
+ dvfsper_plt_data->lp_low,
+ dvfsper_plt_data->lp_low);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET LP VOLTAGE\n");
+ return;
+ }
+ udelay(100);
+#endif
+ dvfs_per_load_config();
+ } else if ((fsvai == FSVAI_FREQ_INCREASE) ||
+ (fsvai == FSVAI_FREQ_EMERG)) {
+#ifndef DVFS_SW_WORKAROUND
+ /* Increase the LP domain voltage first. */
+ ret = regulator_set_voltage(lp_regulator,
+ dvfsper_plt_data->lp_high,
+ dvfsper_plt_data->lp_high);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET LP VOLTAGE\n");
+ return;
+ }
+ udelay(100);
+#endif
+
+#ifndef DVFS_SW_WORKAROUND
+ spin_lock_irqsave(&mxc_dvfs_per_lock, flags);
+ reg = __raw_readl(dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ reg |= MXC_DVFSPMCR0_UDCS;
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg &= ~(MXC_GPCCNTR_ADU_MASK | MXC_GPCCNTR_FUPD_MASK);
+ reg |= MXC_GPCCNTR_FUPD;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->gpc_vcr_reg_addr);
+ reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |= (1 << MXC_GPCVCR_VINC_OFFSET |
+ 1 << MXC_GPCVCR_VCNTU_OFFSET |
+ 1 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, dvfsper_plt_data->gpc_vcr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg &= ~MXC_GPCCNTR_ADU;
+ reg |= MXC_GPCCNTR_STRT;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+ retry = 10;
+ while ((__raw_readl(
+ dvfsper_plt_data->gpc_cntr_reg_addr) & 0x4000)
+ && retry > 0) {
+ udelay(10);
+ retry--;
+ }
+ spin_unlock_irqrestore(&mxc_dvfs_per_lock, flags);
+
+ if (retry < 0)
+ printk(KERN_ERR "****ERROR- DVFS\n");
+#else
+ /*Set the frequencies manually */
+ rate = clk_get_rate(axi_b_clk);
+ clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, 130000000));
+ rate = clk_get_rate(ahb_clk);
+ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, 130000000));
+#endif
+ if (cpu_is_mx51()) {
+ /*Change the DDR freq to 200Mhz. */
+ clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk,
+ 200000000));
+ }
+ dvfs_per_low_freq = 0;
+ if (clk_get_rate(main_bus_clk) == LOW_BUS_FREQ) {
+ cur_setpoint = 2;
+ } else {
+ cur_setpoint = 0;
+#if defined(CONFIG_ARCH_MX37)
+ dptc_resume(DPTC_LP_ID);
+#endif
+#ifndef DVFS_SW_WORKAROUND
+ clk_set_parent(main_bus_clk, clk_get(NULL, "pll2"));
+#endif
+ }
+ dvfs_per_load_config();
+ freq_increased = 1;
+ }
+
+END:
+#if DVFS_PER_DEBUG
+ dump_dvfs_per_regs(void)();
+#endif
+ if (dvfs_per_is_active) {
+ reg = __raw_readl(dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ /* Enable dVFS interrupt */
+ /* FSVAIM=0 */
+ reg &= ~MXC_DVFSPMCR0_FSVAI_MASK;
+ reg |= FSVAI_FREQ_NOCHANGE;
+ reg = (reg & ~MXC_DVFSPMCR0_FSVAIM);
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ /*Unmask GPC1 IRQ */
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg &= ~MXC_GPCCNTR_GPCIRQM;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+ }
+}
+
+static void force_freq_change(void)
+{
+ u32 reg;
+ int retry = 50;
+
+ freq_increased = 0;
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ reg |= MXC_DVFSPMCR0_UDCS;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+
+ if (cpu_is_mx51()) {
+ /*Change the DDR freq to 133Mhz. */
+ clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, 200000000));
+ }
+
+#ifndef DVFS_SW_WORKAROUND
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg |= MXC_GPCCNTR_FUPD;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg = __raw_readl(dvfsper_plt_data->gpc_vcr_reg_addr);
+ reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |= (1 << MXC_GPCVCR_VINC_OFFSET |
+ 1 << MXC_GPCVCR_VCNTU_OFFSET |
+ 20 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, dvfsper_plt_data->gpc_vcr_reg_addr);
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ reg &= ~MXC_GPCCNTR_ADU;
+ reg |= MXC_GPCCNTR_STRT;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+ while ((__raw_readl(
+ dvfsper_plt_data->gpc_cntr_reg_addr) & 0x4000)
+ && retry > 0) {
+ udelay(30);
+ retry--;
+ }
+ freq_increased = 1;
+ if (retry <= 0)
+ printk(KERN_ERR "Cannot stop DVFS-PER\n");
+#else
+ /* Set the frequencies manually */
+ rate = clk_get_rate(axi_b_clk);
+ clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, 130000000));
+ rate = clk_get_rate(ahb_clk);
+ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, 130000000));
+#endif
+ dvfs_per_low_freq = 0;
+
+#ifndef DVFS_SW_WORKAROUND
+ clk_set_parent(main_bus_clk, pll2);
+#endif
+}
+
+static int start(void)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (dvfs_per_is_active || dvfs_per_stop)
+ return 0;
+
+ if (low_bus_freq_mode)
+ return 0;
+
+ if (bus_freq_scaling_is_active) {
+ dvfs_per_is_paused = 1;
+ printk(KERN_INFO "Cannot start DVFS-PER since bus_freq_scaling\
+ is active\n");
+ return 0;
+ }
+
+ if (!dvfs_per_pixel_clk_limit()) {
+ dvfs_per_is_paused = 1;
+ printk(KERN_INFO "Cannot start DVFS-PER since pixel clock is\
+ above 60MHz or divider is not even\n");
+ return 0;
+ }
+
+ stop_sdram_autogating();
+
+ spin_lock_irqsave(&mxc_dvfs_per_lock, flags);
+
+ clk_enable(dvfs_clk);
+
+ cur_setpoint = 0;
+ init_dvfs_per_controller();
+
+ /* config reg GPC_CNTR */
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ /* ADU=0, select PER domain */
+ reg &= ~MXC_GPCCNTR_ADU;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ /* Select ARM domain */
+ reg |= MXC_DVFSPMCR0_DVFIS;
+ /* Set the UDCS bit */
+ reg |= MXC_DVFSPMCR0_UDCS;
+ /* Enable DVFS interrupt */
+ /* FSVAIM=0 */
+ reg &= ~MXC_DVFSPMCR0_FSVAIM;
+ /*Set the FSVAI to no_freq_change */
+ reg &= ~MXC_DVFSPMCR0_FSVAI_MASK;
+ reg |= FSVAI_FREQ_NOCHANGE << MXC_DVFSPMCR0_FSVAI_OFFSET;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+
+ /* config reg GPC_CNTR */
+ reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr);
+ /* GPCIRQ=1, select ARM IRQ */
+ reg |= MXC_GPCCNTR_GPCIRQ_ARM;
+ reg &= ~MXC_GPCCNTR_GPCIRQM;
+ __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr);
+
+ /* Enable DVFS */
+ reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+ reg |= MXC_DVFSPMCR0_DVFEN;
+ __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0);
+
+ dvfs_per_is_active = 1;
+ spin_unlock_irqrestore(&mxc_dvfs_per_lock, flags);
+
+ printk(KERN_DEBUG "DVFS PER is started\n");
+
+ return 0;
+}
+
+/*!
+ * This function disables the DVFS module.
+ */
+static void stop(void)
+{
+ u32 reg = 0;
+ unsigned long flags;
+ u32 ret = 0;
+
+ if (dvfs_per_is_active) {
+ dvfs_per_is_active = 0;
+#ifndef DVFS_SW_WORKAROUND
+ /* Increase the LP domain voltage first. */
+ ret = regulator_set_voltage(
+ lp_regulator, dvfsper_plt_data->lp_high,
+ dvfsper_plt_data->lp_high);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET LP VOLTAGE\n");
+ return;
+ }
+ udelay(100);
+#endif
+
+ spin_lock_irqsave(&mxc_dvfs_per_lock, flags);
+
+ /* Mask dvfs irq, disable DVFS */
+ reg = __raw_readl(dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSPMCR0_FSVAIM;
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+
+ if (cur_setpoint != 0)
+ force_freq_change();
+
+ reg = __raw_readl(dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+ reg = (reg & ~MXC_DVFSPMCR0_DVFEN);
+ __raw_writel(reg, dvfsper_plt_data->membase
+ + MXC_DVFS_PER_PMCR0);
+
+ spin_unlock_irqrestore(&mxc_dvfs_per_lock, flags);
+ clk_disable(dvfs_clk);
+
+ start_sdram_autogating();
+ }
+}
+
+
+int dvfs_per_active()
+{
+ return dvfs_per_is_active;
+}
+
+int dvfs_per_divider_active()
+{
+ return dvfs_per_low_freq;
+}
+
+int dvfs_per_pixel_clk_limit()
+{
+ struct clk *disp0_pixel_clk;
+ struct clk *disp1_pixel_clk;
+ int disp0_rate = 0;
+ int disp1_rate = 0;
+ int div1 = 0;
+ int div2 = 0;
+ int even_div1 = 1;
+ int even_div2 = 1;
+
+ disp0_pixel_clk = clk_get(NULL, "pixel_clk.0");
+ disp1_pixel_clk = clk_get(NULL, "pixel_clk.1");
+
+ if (disp0_pixel_clk != NULL)
+ disp0_rate = clk_get_rate(disp0_pixel_clk);
+
+ if (disp1_pixel_clk != NULL)
+ disp1_rate = clk_get_rate(disp1_pixel_clk);
+
+ /* DVFS-PER will not work if pixel clock divider is odd */
+ if (disp0_rate != 0)
+ div1 = (clk_get_rate(
+ clk_get_parent(disp0_pixel_clk)) * 10) / disp0_rate;
+
+ if ((div1 % 2) || ((div1 / 10) % 2))
+ even_div1 = 0;
+
+ if ((div2 % 2) || ((div2 / 10) % 2))
+ even_div2 = 0;
+
+ if (disp1_rate != 0)
+ div2 = (clk_get_rate(
+ clk_get_parent(disp1_pixel_clk)) * 10) / disp1_rate;
+
+ if (((disp0_rate < DVFS_MAX_PIX_CLK && even_div1) ||
+ !clk_get_usecount(disp0_pixel_clk)) &&
+ ((disp1_rate < DVFS_MAX_PIX_CLK && even_div2) ||
+ !clk_get_usecount(disp1_pixel_clk)))
+ ipu_freq_scaled = 1;
+ else
+ ipu_freq_scaled = 0;
+
+ clk_put(disp0_pixel_clk);
+ clk_put(disp1_pixel_clk);
+
+ return ipu_freq_scaled;
+}
+
+int start_dvfs_per(void)
+{
+ if (dvfs_per_is_paused) {
+ dvfs_per_is_paused = 0;
+ return start();
+ }
+ return 0;
+}
+
+void stop_dvfs_per(void)
+{
+ if (dvfs_per_is_active) {
+ dvfs_per_is_paused = 1;
+ stop();
+ }
+}
+
+/*!
+ * Enable DVFS Peripheral
+ *
+ */
+int dvfs_enable(struct device *dev)
+{
+ if (dvfs_per_is_active)
+ return 0;
+ return start();
+}
+
+static ssize_t dvfsper_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL) {
+ dvfs_per_stop = 0;
+ if (dvfs_enable(dev) != 0)
+ printk(KERN_ERR "Failed to start DVFS\n");
+ } else if (strstr(buf, "0") != NULL) {
+ dvfs_per_stop = 1;
+ stop();
+ }
+ return size;
+}
+
+static ssize_t dvfsper_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int size = 0;
+
+ if (dvfs_per_is_active)
+ size = sprintf(buf, "DVFS PER is enabled\n");
+ else
+ size = sprintf(buf, "DVFS PEr is disabled\n");
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, 0644, dvfsper_status_show, dvfsper_enable_store);
+
+/*!
+ * This is the probe routine for the DVFS PER driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit mxc_dvfsper_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct resource *res;
+ struct mxc_dvfsper_data *dvfsper_data = pdev->dev.platform_data;
+
+ if (dvfsper_data == NULL) {
+ printk(KERN_ERR "DVFS: Pointer to DVFS data is NULL\
+ not started\n");
+ return -1;
+ }
+
+ /* Set driver data */
+ platform_set_drvdata(pdev, dvfsper_device_data);
+
+ dvfsper_plt_data = pdev->dev.platform_data;
+ dvfsper_device_data = kzalloc(sizeof(struct dvfsper_device),
+ GFP_KERNEL);
+ if (!dvfsper_device_data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ ret = -ENODEV;
+ goto err1;
+ }
+ dvfsper_plt_data->membase = ioremap(res->start,
+ res->end - res->start + 1);
+
+ /*
+ * Request the DVFSPER interrupt
+ */
+ dvfsper_device_data->irq = platform_get_irq(pdev, 0);
+ if (dvfsper_device_data->irq < 0) {
+ ret = dvfsper_device_data->irq;
+ goto err1;
+ }
+
+ ret =
+ request_irq(dvfsper_device_data->irq, dvfs_per_irq, IRQF_SHARED,
+ pdev->name, &pdev->dev);
+ if (ret) {
+ printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt\n");
+ goto err1;
+ }
+
+ lp_regulator = regulator_get(NULL, dvfsper_data->reg_id);
+ if (IS_ERR(lp_regulator)) {
+ printk(KERN_ERR "%s: failed to get lp regulator\n", __func__);
+ return PTR_ERR(lp_regulator);
+ }
+
+ INIT_DELAYED_WORK(&dvfs_per_work, dvfs_per_handler);
+
+ main_bus_clk = clk_get(NULL, "main_bus_clk");
+ pll2 = clk_get(NULL, "pll2");
+ lpapm = clk_get(NULL, "lp_apm");
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ ahb_clk = clk_get(NULL, "ahb_clk");
+ axi_b_clk = clk_get(NULL, "axi_b_clk");
+
+ if (cpu_is_mx51())
+ ddr_hf_clk = clk_get(NULL, "ddr_hf_clk");
+
+ dvfsper_device_data->dvfs_clk = clk_get(NULL, dvfsper_data->clk_id);
+ dvfs_clk = dvfsper_device_data->dvfs_clk;
+
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr);
+
+ if (ret) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for dvfs");
+ goto err1;
+ }
+
+ return 0;
+err1:
+ dev_err(&pdev->dev, "Failed to probe DVFS\n");
+ kfree(dvfsper_device_data);
+
+ return ret;
+}
+
+/*!
+ * This function is called to put DVFS in a low power state.
+ *
+ * @param pdev the device structure
+ * @param state the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ if (dvfs_per_is_active) {
+ stop_dvfs_per();
+ dvfs_per_suspended = 1;
+ }
+ return 0;
+}
+
+/*!
+ * This function is called to resume the DVFS from a low power state.
+ *
+ * @param dev the device structure
+ * @param level the stage in device suspension process that we want the
+ * device to be put in
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_resume(struct platform_device *pdev)
+{
+ if (dvfs_per_suspended) {
+ dvfs_per_suspended = 0;
+ return start_dvfs_per();
+ }
+
+ return 0;
+}
+
+static struct platform_driver mxc_dvfsper_driver = {
+ .driver = {
+ .name = "mxc_dvfsper",
+ .owner = THIS_MODULE,
+ },
+ .probe = mxc_dvfsper_probe,
+ .suspend = mxc_dvfs_suspend,
+ .resume = mxc_dvfs_resume,
+};
+
+static int __init dvfs_per_init(void)
+{
+ int err = 0;
+
+ if (platform_driver_register(&mxc_dvfsper_driver) != 0) {
+ printk(KERN_ERR "mxc_dvfsper_driver register failed\n");
+ return -ENODEV;
+ }
+ printk(KERN_INFO "DVFS PER driver module loaded\n");
+
+ return err;
+}
+
+static void __exit dvfs_per_cleanup(void)
+{
+ stop_dvfs_per();
+
+ /* release the DVFS interrupt */
+ free_irq(dvfsper_device_data->irq, NULL);
+
+ clk_put(dvfs_clk);
+ clk_put(main_bus_clk);
+ clk_put(pll2);
+ clk_put(lpapm);
+ clk_put(cpu_clk);
+ clk_put(ahb_clk);
+ clk_put(axi_b_clk);
+ if (cpu_is_mx51())
+ clk_put(ddr_hf_clk);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&mxc_dvfsper_driver);
+}
+
+module_init(dvfs_per_init);
+module_exit(dvfs_per_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("DVFS PERIPHERAL driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
new file mode 100644
index 00000000..d3467f81
--- /dev/null
+++ b/arch/arm/plat-mxc/epit.c
@@ -0,0 +1,225 @@
+/*
+ * linux/arch/arm/plat-mxc/epit.c
+ *
+ * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#define EPITCR 0x00
+#define EPITSR 0x04
+#define EPITLR 0x08
+#define EPITCMPR 0x0c
+#define EPITCNR 0x10
+
+#define EPITCR_EN (1 << 0)
+#define EPITCR_ENMOD (1 << 1)
+#define EPITCR_OCIEN (1 << 2)
+#define EPITCR_RLD (1 << 3)
+#define EPITCR_PRESC(x) (((x) & 0xfff) << 4)
+#define EPITCR_SWR (1 << 16)
+#define EPITCR_IOVW (1 << 17)
+#define EPITCR_DBGEN (1 << 18)
+#define EPITCR_WAITEN (1 << 19)
+#define EPITCR_RES (1 << 20)
+#define EPITCR_STOPEN (1 << 21)
+#define EPITCR_OM_DISCON (0 << 22)
+#define EPITCR_OM_TOGGLE (1 << 22)
+#define EPITCR_OM_CLEAR (2 << 22)
+#define EPITCR_OM_SET (3 << 22)
+#define EPITCR_CLKSRC_OFF (0 << 24)
+#define EPITCR_CLKSRC_PERIPHERAL (1 << 24)
+#define EPITCR_CLKSRC_REF_HIGH (1 << 24)
+#define EPITCR_CLKSRC_REF_LOW (3 << 24)
+
+#define EPITSR_OCIF (1 << 0)
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+static struct clock_event_device clockevent_epit;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void epit_irq_disable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val &= ~EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static inline void epit_irq_enable(void)
+{
+ u32 val;
+
+ val = __raw_readl(timer_base + EPITCR);
+ val |= EPITCR_OCIEN;
+ __raw_writel(val, timer_base + EPITCR);
+}
+
+static void epit_irq_acknowledge(void)
+{
+ __raw_writel(EPITSR_OCIF, timer_base + EPITSR);
+}
+
+static int __init epit_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
+ clocksource_mmio_readl_down);
+}
+
+/* clock event */
+
+static int epit_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long tcmp;
+
+ tcmp = __raw_readl(timer_base + EPITCNR);
+
+ __raw_writel(tcmp - evt, timer_base + EPITCMPR);
+
+ return 0;
+}
+
+static void epit_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call epit_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in GPT module */
+ epit_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+
+ /* Clear pending interrupt */
+ epit_irq_acknowledge();
+ }
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "epit_set_mode: Periodic mode is not "
+ "supported for i.MX EPIT\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * epit_set_next_event(), the core has about 4 minutes
+ * to call epit_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ epit_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_epit;
+
+ epit_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction epit_timer_irq = {
+ .name = "i.MX EPIT Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = epit_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_epit = {
+ .name = "epit",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = epit_set_mode,
+ .set_next_event = epit_set_next_event,
+ .rating = 200,
+};
+
+static int __init epit_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_epit.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_epit.shift);
+ clockevent_epit.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_epit);
+ clockevent_epit.min_delta_ns =
+ clockevent_delta2ns(0x800, &clockevent_epit);
+
+ clockevent_epit.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_epit);
+
+ return 0;
+}
+
+void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialise to a known state (all timers off, and timing reset)
+ */
+ __raw_writel(0x0, timer_base + EPITCR);
+
+ __raw_writel(0xffffffff, timer_base + EPITLR);
+ __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
+ timer_base + EPITCR);
+
+ /* init and register the timer to the framework */
+ epit_clocksource_init(timer_clk);
+ epit_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &epit_timer_irq);
+}
diff --git a/arch/arm/plat-mxc/fuse.c b/arch/arm/plat-mxc/fuse.c
new file mode 100644
index 00000000..1238e76b
--- /dev/null
+++ b/arch/arm/plat-mxc/fuse.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <mach/hardware.h>
+
+#define HW_OCOTP_CFGn(n) (0x00000410 + (n) * 0x10)
+
+/* Note: the names oder is the same as device enum order defined in mxc.h */
+static char *names[] = {
+ "pxp", "ovg", "dsi_csi2", "enet", "mlb",
+ "epdc", "hdmi", "pcie", "sata", "dtcp",
+ "2d", "3d", "vpu", "divx3", "rv",
+ "sorensen",
+};
+
+int fuse_dev_is_available(enum mxc_dev_type dev)
+{
+ u32 uninitialized_var(reg);
+ u32 uninitialized_var(mask);
+ int ret;
+
+ if (!cpu_is_mx6())
+ return 1;
+
+ /* mx6sl is still not supported */
+ if (cpu_is_mx6sl())
+ return 1;
+
+ switch (dev) {
+ case MXC_DEV_PXP:
+ if (cpu_is_mx6q())
+ return 0;
+
+ if (cpu_is_mx6dl()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x80000000;
+ }
+ break;
+ case MXC_DEV_OVG:
+ if (cpu_is_mx6dl())
+ return 0;
+
+ if (cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x40000000;
+ }
+ break;
+ case MXC_DEV_DSI_CSI2:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x10000000;
+ }
+ break;
+ case MXC_DEV_ENET:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x08000000;
+ }
+ break;
+ case MXC_DEV_MLB:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x04000000;
+ }
+ break;
+ case MXC_DEV_EPDC:
+ if (cpu_is_mx6q())
+ return 0;
+
+ if (cpu_is_mx6dl()) {
+ reg = HW_OCOTP_CFGn(2);
+ mask = 0x02000000;
+ }
+ break;
+ case MXC_DEV_HDMI:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000080;
+ }
+ break;
+ case MXC_DEV_PCIE:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000040;
+ }
+ break;
+ case MXC_DEV_SATA:
+ if (cpu_is_mx6dl())
+ return 0;
+
+ if (cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000020;
+ }
+ break;
+ case MXC_DEV_DTCP:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000010;
+ }
+ break;
+ case MXC_DEV_2D:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000008;
+ }
+ break;
+ case MXC_DEV_3D:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000004;
+ }
+ break;
+ case MXC_DEV_VPU:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00008000;
+ }
+ break;
+ case MXC_DEV_DIVX3:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000400;
+ }
+ break;
+ case MXC_DEV_RV:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000200;
+ }
+ break;
+ case MXC_DEV_SORENSEN:
+ if (cpu_is_mx6dl() || cpu_is_mx6q()) {
+ reg = HW_OCOTP_CFGn(3);
+ mask = 0x00000100;
+ }
+ break;
+ default:
+ /* we treat the unkown device is avaiable by default */
+ return 1;
+ }
+
+ ret = readl(MX6_IO_ADDRESS(OCOTP_BASE_ADDR) + reg) & mask;
+ pr_debug("fuse_check: %s is %s\n", names[dev], ret ?
+ "unavailable" : "available");
+
+ return !ret;
+}
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
new file mode 100755
index 00000000..0af29c0c
--- /dev/null
+++ b/arch/arm/plat-mxc/gpio.c
@@ -0,0 +1,377 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+#include <asm/mach/irq.h>
+
+static struct mxc_gpio_port *mxc_gpio_ports;
+static int gpio_table_size;
+
+#define cpu_is_mx1_mx2() (cpu_is_mx1() || cpu_is_mx2())
+
+#define GPIO_DR (cpu_is_mx1_mx2() ? 0x1c : 0x00)
+#define GPIO_GDIR (cpu_is_mx1_mx2() ? 0x00 : 0x04)
+#define GPIO_PSR (cpu_is_mx1_mx2() ? 0x24 : 0x08)
+#define GPIO_ICR1 (cpu_is_mx1_mx2() ? 0x28 : 0x0C)
+#define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10)
+#define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14)
+#define GPIO_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
+
+#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
+#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1)
+#define GPIO_INT_RISE_EDGE (cpu_is_mx1_mx2() ? 0x0 : 0x2)
+#define GPIO_INT_FALL_EDGE (cpu_is_mx1_mx2() ? 0x1 : 0x3)
+#define GPIO_INT_NONE 0x4
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
+{
+ __raw_writel(1 << index, port->base + GPIO_ISR);
+}
+
+static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
+ int enable)
+{
+ u32 l;
+
+ l = __raw_readl(port->base + GPIO_IMR);
+ l = (l & (~(1 << index))) | (!!enable << index);
+ __raw_writel(l, port->base + GPIO_IMR);
+}
+
+static void gpio_ack_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(struct irq_data *d)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(struct irq_data *d, u32 type)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
+ u32 bit, val;
+ int edge;
+ void __iomem *reg = port->base;
+
+ port->both_edges &= ~(1 << (gpio & 31));
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ val = mxc_gpio_get(&port->chip, gpio & 31);
+ if (val) {
+ edge = GPIO_INT_LOW_LEV;
+ pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+ } else {
+ edge = GPIO_INT_HIGH_LEV;
+ pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+ }
+ port->both_edges |= 1 << (gpio & 31);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+ bit = gpio & 0xf;
+ val = __raw_readl(reg) & ~(0x3 << (bit << 1));
+ __raw_writel(val | (edge << (bit << 1)), reg);
+ _clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
+{
+ void __iomem *reg = port->base;
+ u32 bit, val;
+ int edge;
+
+ reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+ bit = gpio & 0xf;
+ val = __raw_readl(reg);
+ edge = (val >> (bit << 1)) & 3;
+ val &= ~(0x3 << (bit << 1));
+ if (edge == GPIO_INT_HIGH_LEV) {
+ edge = GPIO_INT_LOW_LEV;
+ pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
+ } else if (edge == GPIO_INT_LOW_LEV) {
+ edge = GPIO_INT_HIGH_LEV;
+ pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+ } else {
+ pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+ gpio, edge);
+ return;
+ }
+ __raw_writel(val | (edge << (bit << 1)), reg);
+}
+
+/* handle 32 interrupts in one status register */
+static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
+{
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+
+ if (port->both_edges & (1 << irqoffset))
+ mxc_flip_edge(port, irqoffset);
+
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/* MX1 and MX3 has one interrupt *per* gpio port */
+static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxc_gpio_port *port = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
+
+ chained_irq_enter(chip, desc);
+
+ irq_stat = __raw_readl(port->base + GPIO_ISR) &
+ __raw_readl(port->base + GPIO_IMR);
+
+ mxc_gpio_irq_handler(port, irq_stat);
+
+ chained_irq_exit(chip, desc);
+}
+
+/* MX2 has one interrupt *for all* gpio ports */
+static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ int i;
+ u32 irq_msk, irq_stat;
+ struct mxc_gpio_port *port = irq_get_handler_data(irq);
+
+ /* walk through all interrupt status registers */
+ for (i = 0; i < gpio_table_size; i++) {
+ irq_msk = __raw_readl(port[i].base + GPIO_IMR);
+ if (!irq_msk)
+ continue;
+
+ irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk;
+ if (irq_stat)
+ mxc_gpio_irq_handler(&port[i], irq_stat);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(struct irq_data *d, u32 enable)
+{
+ u32 gpio = irq_to_gpio(d->irq);
+ u32 gpio_idx = gpio & 0x1F;
+ struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .name = "GPIO",
+ .irq_ack = gpio_ack_irq,
+ .irq_mask = gpio_mask_irq,
+ .irq_unmask = gpio_unmask_irq,
+ .irq_set_type = gpio_set_irq_type,
+ .irq_set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxc_gpio_port *port =
+ container_of(chip, struct mxc_gpio_port, chip);
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ port->dir = __raw_readl(port->base + GPIO_GDIR);
+ if (dir)
+ port->dir |= (1 << offset);
+ else
+ port->dir &= (~(1 << offset));
+ __raw_writel(port->dir, port->base + GPIO_GDIR);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxc_gpio_port *port =
+ container_of(chip, struct mxc_gpio_port, chip);
+ void __iomem *reg = port->base + GPIO_DR;
+ u32 l;
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
+ __raw_writel(l, reg);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxc_gpio_port *port =
+ container_of(chip, struct mxc_gpio_port, chip);
+ u32 gpio_direction;
+
+ gpio_direction = __raw_readl(port->base + GPIO_GDIR);
+ if (((gpio_direction >> offset) & 1)) /* output mode */
+ return (__raw_readl(port->base + GPIO_DR) >> offset) & 1;
+ else /* input mode */
+ return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
+
+}
+
+static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxc_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxc_gpio_set(chip, offset, value);
+ _set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+/*
+ * This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+int mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
+{
+ int i, j;
+ static bool initialed;
+
+ /* save for local usage */
+ mxc_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ printk(KERN_INFO "MXC GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base + GPIO_IMR);
+ __raw_writel(~0, port[i].base + GPIO_ISR);
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ irq_set_lockdep_class(j, &gpio_lock_class);
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxc_gpio_direction_input;
+ port[i].chip.direction_output = mxc_gpio_direction_output;
+ port[i].chip.get = mxc_gpio_get;
+ port[i].chip.set = mxc_gpio_set;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+ port[i].dir = 0;
+
+ spin_lock_init(&port[i].lock);
+
+ if (!initialed)
+ /* its a serious configuration bug when it fails */
+ BUG_ON(gpiochip_add(&port[i].chip) < 0);
+
+ if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() ||
+ cpu_is_mx51() || cpu_is_mx53() || cpu_is_mx6q() ||
+ cpu_is_mx6dl() || cpu_is_mx6sl()) {
+ /* setup one handler for each entry */
+ irq_set_chained_handler(port[i].irq,
+ mx3_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq, &port[i]);
+ if (port[i].irq_high) {
+ /* setup handler for GPIO 16 to 31 */
+ irq_set_chained_handler(port[i].irq_high,
+ mx3_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq_high,
+ &port[i]);
+ }
+ }
+ }
+ initialed = true;
+ if (cpu_is_mx2()) {
+ /* setup one handler for all GPIO interrupts */
+ irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler);
+ irq_set_handler_data(port[0].irq, port);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
new file mode 100644
index 00000000..a384fdd4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_3DS_DB_H__
+#define __ASM_ARCH_MXC_3DS_DB_H__
+
+extern int __init mxc_expio_init(u32 base, u32 p_irq);
+
+#endif /* __ASM_ARCH_MXC_3DS_DB_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/ahci_sata.h b/arch/arm/plat-mxc/include/mach/ahci_sata.h
new file mode 100755
index 00000000..48b93e55
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ahci_sata.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __PLAT_MXC_AHCI_SATA_H__
+#define __PLAT_MXC_AHCI_SATA_H__
+
+enum {
+ HOST_CAP = 0x00,
+ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
+ HOST_CTL = 0x04, /* global host control */
+ HOST_RESET = (1 << 0), /* reset controller; self-clear */
+ HOST_PORTS_IMPL = 0x0c,
+ HOST_TIMER1MS = 0xe0, /* Timer 1-ms */
+ HOST_VERSIONR = 0xfc, /* host version register*/
+
+ /* Offest used to control the MPLL input clk */
+ PHY_CR_CLOCK_FREQ_OVRD = 0x12,
+ /* Port0 SATA Status */
+ PORT_SATA_SR = 0x128,
+ /* Port0 PHY Control */
+ PORT_PHY_CTL = 0x178,
+ /* PORT_PHY_CTL bits */
+ PORT_PHY_CTL_CAP_ADR_LOC = 0x10000,
+ PORT_PHY_CTL_CAP_DAT_LOC = 0x20000,
+ PORT_PHY_CTL_WRITE_LOC = 0x40000,
+ PORT_PHY_CTL_READ_LOC = 0x80000,
+ PORT_PHY_CTL_PDDQ_LOC = 0x100000,
+ /* Port0 PHY Status */
+ PORT_PHY_SR = 0x17c,
+ /* PORT_PHY_SR */
+ PORT_PHY_STAT_DATA_LOC = 0,
+ PORT_PHY_STAT_ACK_LOC = 18,
+ /* SATA PHY Register */
+ SATA_PHY_CR_CLOCK_CRCMP_LT_LIMIT = 0x0001,
+ SATA_PHY_CR_CLOCK_DAC_CTL = 0x0008,
+ SATA_PHY_CR_CLOCK_RTUNE_CTL = 0x0009,
+ SATA_PHY_CR_CLOCK_ADC_OUT = 0x000A,
+ SATA_PHY_CR_CLOCK_MPLL_TST = 0x0017,
+};
+
+extern int write_phy_ctl_ack_polling(u32 data, void __iomem *mmio,
+ int max_iterations, u32 exp_val);
+extern int sata_phy_cr_addr(u32 addr, void __iomem *mmio);
+extern int sata_phy_cr_write(u32 data, void __iomem *mmio);
+extern int sata_phy_cr_read(u32 *data, void __iomem *mmio);
+extern int sata_init(void __iomem *addr, unsigned long timer1ms);
+#endif /* __PLAT_MXC_AHCI_SATA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/anatop_thermal.h b/arch/arm/plat-mxc/include/mach/anatop_thermal.h
new file mode 100644
index 00000000..7549bc59
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/anatop_thermal.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARCH_IMX_ANATOP_THERMAL_H
+#define __ASM_ARCH_IMX_ANATOP_THERMAL_H
+
+/**
+ * struct anatop_thermal_platform_data - optional platform data for thermal on i.MX
+ *
+ */
+
+struct anatop_thermal_platform_data {
+ char *name;
+};
+#endif /* __ASM_ARCH_IMX_ANATOP_THERMAL_H */
diff --git a/arch/arm/plat-mxc/include/mach/arc_otg.h b/arch/arm/plat-mxc/include/mach/arc_otg.h
new file mode 100755
index 00000000..fdd84503
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/arc_otg.h
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2005-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_ARC_OTG_H__
+#define __ASM_ARCH_MXC_ARC_OTG_H__
+
+#ifdef CONFIG_ARCH_MX3
+extern volatile u32 *mx3_usb_otg_addr;
+#define OTG_BASE_ADDR mx3_usb_otg_addr
+#else
+extern void __iomem *imx_otg_base;
+#define OTG_BASE_ADDR imx_otg_base
+#endif
+
+#define USB_OTGREGS_BASE (OTG_BASE_ADDR + 0x000)
+#define USB_H1REGS_BASE (OTG_BASE_ADDR + 0x200)
+#define USB_H2REGS_BASE (OTG_BASE_ADDR + 0x400)
+#if (defined CONFIG_ARCH_MX5 | defined CONFIG_ARCH_MX6)
+#define USB_H3REGS_BASE (OTG_BASE_ADDR + 0x600)
+#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x800)
+#else
+#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x600)
+#endif
+
+#define USBOTG_REG32(offset) (*((volatile u32 __force *)(USB_OTGREGS_BASE + (offset))))
+#define USBOTG_REG16(offset) (*((volatile u16 __force *)(USB_OTGREGS_BASE + (offset))))
+
+#define USBH1_REG32(offset) (*((volatile u32 __force *)(USB_H1REGS_BASE + (offset))))
+#define USBH1_REG16(offset) (*((volatile u16 __force *)(USB_H1REGS_BASE + (offset))))
+
+#define USBH2_REG32(offset) (*((volatile u32 __force *)(USB_H2REGS_BASE + (offset))))
+#define USBH2_REG16(offset) (*((volatile u16 __force *)(USB_H2REGS_BASE + (offset))))
+
+#define USBH3_REG32(offset) (*((volatile u32 __force *)(USB_H3REGS_BASE + (offset))))
+#define USBH3_REG16(offset) (*((volatile u16 __force *)(USB_H3REGS_BASE + (offset))))
+
+#define USBOTHER_REG(offset) (*((volatile u32 __force *)(USB_OTHERREGS_BASE + (offset))))
+
+/*
+ * OTG registers
+ */
+#define UOG_ID USBOTG_REG32(0x00) /* Host ID */
+#define UOG_HWGENERAL USBOTG_REG32(0x04) /* Host General */
+#define UOG_HWHOST USBOTG_REG32(0x08) /* Host h/w params */
+#define UOG_HWTXBUF USBOTG_REG32(0x10) /* TX buffer h/w params */
+#define UOG_HWRXBUF USBOTG_REG32(0x14) /* RX buffer h/w params */
+#define UOG_CAPLENGTH USBOTG_REG16(0x100) /* Capability register length */
+#define UOG_HCIVERSION USBOTG_REG16(0x102) /* Host Interface version */
+#define UOG_HCSPARAMS USBOTG_REG32(0x104) /* Host control structural params */
+#define UOG_HCCPARAMS USBOTG_REG32(0x108) /* control capability params */
+#define UOG_DCIVERSION USBOTG_REG32(0x120) /* device interface version */
+/* start EHCI registers: */
+#define UOG_USBCMD USBOTG_REG32(0x140) /* USB command register */
+#define UOG_USBSTS USBOTG_REG32(0x144) /* USB status register */
+#define UOG_USBINTR USBOTG_REG32(0x148) /* interrupt enable register */
+#define UOG_FRINDEX USBOTG_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UOG_PERIODICLISTBASE USBOTG_REG32(0x154) /* host crtlr frame list base addr */
+#define UOG_DEVICEADDR USBOTG_REG32(0x154) /* device crtlr device address */
+#define UOG_ASYNCLISTADDR USBOTG_REG32(0x158) /* host ctrlr next async addr */
+#define UOG_EPLISTADDR USBOTG_REG32(0x158) /* device ctrlr endpoint list addr */
+#define UOG_BURSTSIZE USBOTG_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UOG_TXFILLTUNING USBOTG_REG32(0x164) /* TX FIFO fill tuning */
+#define UOG_ULPIVIEW USBOTG_REG32(0x170) /* ULPI viewport */
+#define UOG_CFGFLAG USBOTG_REG32(0x180) /* configflag (supports HS) */
+#define UOG_PORTSC1 USBOTG_REG32(0x184) /* port status and control */
+/* end EHCI registers: */
+#define UOG_OTGSC USBOTG_REG32(0x1a4) /* OTG status and control */
+#define UOG_USBMODE USBOTG_REG32(0x1a8) /* USB device mode */
+#define UOG_ENDPTSETUPSTAT USBOTG_REG32(0x1ac) /* endpoint setup status */
+#define UOG_ENDPTPRIME USBOTG_REG32(0x1b0) /* endpoint initialization */
+#define UOG_ENDPTFLUSH USBOTG_REG32(0x1b4) /* endpoint de-initialize */
+#define UOG_ENDPTSTAT USBOTG_REG32(0x1b8) /* endpoint status */
+#define UOG_ENDPTCOMPLETE USBOTG_REG32(0x1bc) /* endpoint complete */
+#define UOG_EPCTRL0 USBOTG_REG32(0x1c0) /* endpoint control0 */
+#define UOG_EPCTRL1 USBOTG_REG32(0x1c4) /* endpoint control1 */
+#define UOG_EPCTRL2 USBOTG_REG32(0x1c8) /* endpoint control2 */
+#define UOG_EPCTRL3 USBOTG_REG32(0x1cc) /* endpoint control3 */
+#define UOG_EPCTRL4 USBOTG_REG32(0x1d0) /* endpoint control4 */
+#define UOG_EPCTRL5 USBOTG_REG32(0x1d4) /* endpoint control5 */
+#define UOG_EPCTRL6 USBOTG_REG32(0x1d8) /* endpoint control6 */
+#define UOG_EPCTRL7 USBOTG_REG32(0x1dc) /* endpoint control7 */
+
+/*
+ * Host 1 registers
+ */
+#define UH1_ID USBH1_REG32(0x00) /* Host ID */
+#define UH1_HWGENERAL USBH1_REG32(0x04) /* Host General */
+#define UH1_HWHOST USBH1_REG32(0x08) /* Host h/w params */
+#define UH1_HWTXBUF USBH1_REG32(0x10) /* TX buffer h/w params */
+#define UH1_HWRXBUF USBH1_REG32(0x14) /* RX buffer h/w params */
+#define UH1_CAPLENGTH USBH1_REG16(0x100) /* Capability register length */
+#define UH1_HCIVERSION USBH1_REG16(0x102) /* Host Interface version */
+#define UH1_HCSPARAMS USBH1_REG32(0x104) /* Host control structural params */
+#define UH1_HCCPARAMS USBH1_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH1_USBCMD USBH1_REG32(0x140) /* USB command register */
+#define UH1_USBSTS USBH1_REG32(0x144) /* USB status register */
+#define UH1_USBINTR USBH1_REG32(0x148) /* interrupt enable register */
+#define UH1_FRINDEX USBH1_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH1_PERIODICLISTBASE USBH1_REG32(0x154) /* host crtlr frame list base addr */
+#define UH1_ASYNCLISTADDR USBH1_REG32(0x158) /* host ctrlr nest async addr */
+#define UH1_BURSTSIZE USBH1_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH1_TXFILLTUNING USBH1_REG32(0x164) /* TX FIFO fill tuning */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH1_PORTSC1 USBH1_REG32(0x184) /* port status and control */
+/* end EHCI registers: */
+#define UH1_OTGSC USBH1_REG32(0x1a4) /* OTG status and control */
+#define UH1_USBMODE USBH1_REG32(0x1a8) /* USB device mode */
+
+/*
+ * Host 2 registers
+ */
+#define UH2_ID USBH2_REG32(0x00) /* Host ID */
+#define UH2_HWGENERAL USBH2_REG32(0x04) /* Host General */
+#define UH2_HWHOST USBH2_REG32(0x08) /* Host h/w params */
+#define UH2_HWTXBUF USBH2_REG32(0x10) /* TX buffer h/w params */
+#define UH2_HWRXBUF USBH2_REG32(0x14) /* RX buffer h/w params */
+#define UH2_CAPLENGTH USBH2_REG16(0x100) /* Capability register length */
+#define UH2_HCIVERSION USBH2_REG16(0x102) /* Host Interface version */
+#define UH2_HCSPARAMS USBH2_REG32(0x104) /* Host control structural params */
+#define UH2_HCCPARAMS USBH2_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH2_USBCMD USBH2_REG32(0x140) /* USB command register */
+#define UH2_USBSTS USBH2_REG32(0x144) /* USB status register */
+#define UH2_USBINTR USBH2_REG32(0x148) /* interrupt enable register */
+#define UH2_FRINDEX USBH2_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH2_PERIODICLISTBASE USBH2_REG32(0x154) /* host crtlr frame list base addr */
+#define UH2_ASYNCLISTADDR USBH2_REG32(0x158) /* host ctrlr nest async addr */
+#define UH2_BURSTSIZE USBH2_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH2_TXFILLTUNING USBH2_REG32(0x164) /* TX FIFO fill tuning */
+#define UH2_ULPIVIEW USBH2_REG32(0x170) /* ULPI viewport */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH2_PORTSC1 USBH2_REG32(0x184) /* port status and control */
+/* end EHCI registers */
+#define UH2_USBMODE USBH2_REG32(0x1a8) /* USB device mode */
+/*
+ * Host 2 registers
+ */
+#define UH2_ID USBH2_REG32(0x00) /* Host ID */
+#define UH2_HWGENERAL USBH2_REG32(0x04) /* Host General */
+#define UH2_HWHOST USBH2_REG32(0x08) /* Host h/w params */
+#define UH2_HWTXBUF USBH2_REG32(0x10) /* TX buffer h/w params */
+#define UH2_HWRXBUF USBH2_REG32(0x14) /* RX buffer h/w params */
+#define UH2_CAPLENGTH USBH2_REG16(0x100) /* Capability register length */
+#define UH2_HCIVERSION USBH2_REG16(0x102) /* Host Interface version */
+#define UH2_HCSPARAMS USBH2_REG32(0x104) /* Host control structural params */
+#define UH2_HCCPARAMS USBH2_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH2_USBCMD USBH2_REG32(0x140) /* USB command register */
+#define UH2_USBSTS USBH2_REG32(0x144) /* USB status register */
+#define UH2_USBINTR USBH2_REG32(0x148) /* interrupt enable register */
+#define UH2_FRINDEX USBH2_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH2_PERIODICLISTBASE USBH2_REG32(0x154) /* host crtlr frame list base addr */
+#define UH2_ASYNCLISTADDR USBH2_REG32(0x158) /* host ctrlr nest async addr */
+#define UH2_BURSTSIZE USBH2_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH2_TXFILLTUNING USBH2_REG32(0x164) /* TX FIFO fill tuning */
+#define UH2_ULPIVIEW USBH2_REG32(0x170) /* ULPI viewport */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH2_PORTSC1 USBH2_REG32(0x184) /* port status and control */
+/* end EHCI registers */
+#define UH2_USBMODE USBH2_REG32(0x1a8) /* USB device mode */
+/*
+ * Host 2 registers
+ */
+#define UH3_ID USBH3_REG32(0x00) /* Host ID */
+#define UH3_HWGENERAL USBH3_REG32(0x04) /* Host General */
+#define UH3_HWHOST USBH3_REG32(0x08) /* Host h/w params */
+#define UH3_HWTXBUF USBH3_REG32(0x10) /* TX buffer h/w params */
+#define UH3_HWRXBUF USBH3_REG32(0x14) /* RX buffer h/w params */
+#define UH3_CAPLENGTH USBH3_REG16(0x100) /* Capability register length */
+#define UH3_HCIVERSION USBH3_REG16(0x102) /* Host Interface version */
+#define UH3_HCSPARAMS USBH3_REG32(0x104) /* Host control structural params */
+#define UH3_HCCPARAMS USBH3_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH3_USBCMD USBH3_REG32(0x140) /* USB command register */
+#define UH3_USBSTS USBH3_REG32(0x144) /* USB status register */
+#define UH3_USBINTR USBH3_REG32(0x148) /* interrupt enable register */
+#define UH3_FRINDEX USBH3_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH3_PERIODICLISTBASE USBH3_REG32(0x154) /* host crtlr frame list base addr */
+#define UH3_ASYNCLISTADDR USBH3_REG32(0x158) /* host ctrlr nest async addr */
+#define UH3_BURSTSIZE USBH3_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH3_TXFILLTUNING USBH3_REG32(0x164) /* TX FIFO fill tuning */
+#define UH3_ULPIVIEW USBH3_REG32(0x170) /* ULPI viewport */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH3_PORTSC1 USBH3_REG32(0x184) /* port status and control */
+/* end EHCI registers */
+#define UH3_USBMODE USBH3_REG32(0x1a8) /* USB device mode */
+
+/*
+ * other regs (not part of ARC core)
+ */
+#define USBCTRL USBOTHER_REG(0x00) /* USB Control register */
+#define USB_OTG_MIRROR USBOTHER_REG(0x04) /* USB OTG mirror register */
+#define USB_PHY_CTR_FUNC USBOTHER_REG(0x08) /* OTG UTMI PHY Function Control register */
+#define USB_PHY_CTR_FUNC2 USBOTHER_REG(0x0c) /* OTG UTMI PHY Function Control register */
+#define USB_CTRL_1 USBOTHER_REG(0x10) /* USB Cotrol Register 1*/
+#define USBCTRL_HOST2 USBOTHER_REG(0x14) /* USB Cotrol Register 1*/
+#define USBCTRL_HOST3 USBOTHER_REG(0x18) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL0 USBOTHER_REG(0x1c) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL1 USBOTHER_REG(0x20) /* USB Cotrol Register 1*/
+#define USB_CLKONOFF_CTRL USBOTHER_REG(0x24) /* USB Clock on/off Control Register */
+
+/* mx6x other regs */
+#define USB_OTG_CTRL USBOTHER_REG(0x00) /* USB OTG Control register */
+#define USB_H1_CTRL USBOTHER_REG(0x04) /* USB H1 Control register */
+#define USB_H2_CTRL USBOTHER_REG(0x08) /* USB H2 Control register */
+#define USB_H3_CTRL USBOTHER_REG(0x0c) /* USB H3 Control register */
+#define USB_UH2_HSIC_CTRL USBOTHER_REG(0x10) /* USB Host2 HSIC Control Register */
+#define USB_UH3_HSIC_CTRL USBOTHER_REG(0x14) /* USB Host3 HSIC Control Register */
+#define USB_OTG_PHY_CTRL_0 USBOTHER_REG(0x18) /* OTG UTMI PHY Control 0 Register */
+#define USB_H1_PHY_CTRL_0 USBOTHER_REG(0x1c) /* OTG UTMI PHY Control 1 Register */
+#define USB_UH2_HSIC_DLL_CFG1 USBOTHER_REG(0x20) /* USB Host2 HSIC DLL Configuration Register 1 */
+#define USB_UH2_HSIC_DLL_CFG2 USBOTHER_REG(0x24) /* USB Host2 HSIC DLL Configuration Register 2 */
+#define USB_UH2_HSIC_DLL_CFG3 USBOTHER_REG(0x28) /* USB Host2 HSIC DLL Configuration Register 3 */
+#define USB_UH3_HSIC_DLL_CFG1 USBOTHER_REG(0x30) /* USB Host3 HSIC DLL Configuration Register 1 */
+#define USB_UH3_HSIC_DLL_CFG2 USBOTHER_REG(0x34) /* USB Host3 HSIC DLL Configuration Register 2 */
+#define USB_UH3_HSIC_DLL_CFG3 USBOTHER_REG(0x38) /* USB Host3 HSIC DLL Configuration Register 3 */
+/*
+ * register bits
+ */
+
+/* x_PORTSCx */
+#define PORTSC_PTS_MASK (3 << 30) /* parallel xcvr select mask */
+#define PORTSC_PTS_UTMI (0 << 30) /* UTMI/UTMI+ */
+#define PORTSC_PTS_PHILIPS (1 << 30) /* Philips classic */
+#define PORTSC_PTS_ULPI (2 << 30) /* ULPI */
+#define PORTSC_PTS_SERIAL (3 << 30) /* serial */
+#define PORTSC_STS (1 << 29) /* serial xcvr select */
+#define PORTSC_PTW (1 << 28) /* UTMI width */
+#define PORTSC_PORT_SPEED_FULL (0x0<<26)
+#define PORTSC_PORT_SPEED_LOW (0x1<<26)
+#define PORTSC_PORT_SPEED_HIGH (0x2<<26)
+#define PORTSC_PORT_SPEED_UNDEF (0x3<<26)
+#define PORTSC_PORT_SPEED_MASK (0x3<<26)
+#define PORTSC_HSIC_MODE (1 << 25) /* Only for HSIC */
+#define PORTSC_PHCD (1 << 23) /* Low Power Suspend */
+#define PORTSC_WKDC (1 << 21) /* wakeup on discnt*/
+#define PORTSC_WKCN (1 << 20) /* wakeup on connect*/
+#define PORTSC_PORT_POWER (1 << 12) /* port power */
+#define PORTSC_LS_MASK (3 << 10) /* Line State mask */
+#define PORTSC_LS_SE0 (0 << 10) /* SE0 */
+#define PORTSC_LS_K_STATE (1 << 10) /* K-state */
+#define PORTSC_LS_J_STATE (2 << 10) /* J-state */
+#define PORTSC_PORT_RESET (1 << 8) /* Port reset */
+#define PORTSC_PORT_SUSPEND (1 << 7) /* Suspend */
+#define PORTSC_PORT_FORCE_RESUME (1 << 6) /* Force port resume */
+#define PORTSC_OVER_CURRENT_CHG (1 << 5) /* over current change */
+#define PORTSC_OVER_CURRENT_ACT (1 << 4) /* over currrent active */
+#define PORTSC_PORT_EN_DIS_CHANGE (1 << 3) /* port {en,dis}able change */
+#define PORTSC_PORT_ENABLE (1 << 2) /* port enabled */
+#define PORTSC_CONNECT_STATUS_CHANGE (1 << 1) /* connect status change */
+#define PORTSC_CURRENT_CONNECT_STATUS (1 << 0) /* current connect status */
+
+#define PORTSC_W1C_BITS \
+ (PORTSC_CONNECT_STATUS_CHANGE | \
+ PORTSC_PORT_EN_DIS_CHANGE | \
+ PORTSC_OVER_CURRENT_CHG)
+
+/* UOG_OTGSC Register Bits */
+/* control bits: */
+#define OTGSC_CTRL_VBUS_DISCHARGE (1 << 0)
+#define OTGSC_CTRL_VBUS_CHARGE (1 << 1)
+#define OTGSC_CTRL_OTG_TERM (1 << 3) /* controls DM pulldown */
+#define OTGSC_CTRL_DATA_PULSING (1 << 4)
+#define OTGSC_CTRL_USB_ID_PU (1 << 5) /* enable ID pullup */
+/* current status: (R/O) */
+#define OTGSC_STS_USB_ID (1 << 8) /* 0=A-device 1=B-device */
+#define OTGSC_STS_A_VBUS_VALID (1 << 9)
+#define OTGSC_STS_A_SESSION_VALID (1 << 10)
+#define OTGSC_STS_B_SESSION_VALID (1 << 11)
+#define OTGSC_STS_B_SESSION_END (1 << 12)
+#define OTGSC_STS_1ms_TIMER (1 << 13)
+#define OTGSC_STS_DATA_PULSE (1 << 14)
+/* interrupt status: (write to clear) */
+#define OTGSC_IS_MASK (0x7f << 16)
+#define OTGSC_IS_USB_ID (1 << 16)
+#define OTGSC_IS_A_VBUS_VALID (1 << 17)
+#define OTGSC_IS_A_SESSION_VALID (1 << 18)
+#define OTGSC_IS_B_SESSION_VALID (1 << 19)
+#define OTGSC_IS_B_SESSION_END (1 << 20)
+#define OTGSC_IS_1ms_TIMER (1 << 21)
+#define OTGSC_IS_DATA_PULSE (1 << 22)
+/* interrupt enables: */
+#define OTGSC_IE_MASK (0x7f << 24)
+#define OTGSC_IE_USB_ID (1 << 24)
+#define OTGSC_IE_A_VBUS_VALID (1 << 25)
+#define OTGSC_IE_A_SESSION_VALID (1 << 26)
+#define OTGSC_IE_B_SESSION_VALID (1 << 27)
+#define OTGSC_IE_B_SESSION_END (1 << 28)
+#define OTGSC_IE_1ms_TIMER (1 << 29)
+#define OTGSC_IE_DATA_PULSE (1 << 30)
+
+/* UOG_USBSTS bits */
+#define USBSTS_PCI (1 << 2) /* Port Change Detect */
+#define USBSTS_URI (1 << 6) /* USB Reset Received */
+
+/* USBCMD */
+#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
+#define UCMD_RESET (1 << 1) /* controller reset */
+#define UCMD_ITC_NO_THRESHOLD (~(0xff << 16)) /* Interrupt Threshold Control */
+
+#if 1 /* FIXME these here for compatibility between my names and Leo's */
+/* OTG interrupt enable bit masks */
+#define OTGSC_INTERRUPT_ENABLE_BITS_MASK OTGSC_IE_MASK
+#define OTGSC_INTSTS_MASK OTGSC_IS_MASK
+
+/* OTG interrupt status bit masks */
+#define OTGSC_INTERRUPT_STATUS_BITS_MASK OTGSC_IS_MASK
+#endif
+
+/* x_USBMODE */
+#define USBMODE_SLOM (1 << 3) /* setup lockout mode */
+#define USBMODE_ES (1 << 2) /* (big) endian select */
+#define USBMODE_CM_MASK (3 << 0) /* controller mode mask */
+#define USBMODE_CM_HOST (3 << 0) /* host */
+#define USBMODE_CM_DEVICE (2 << 0) /* device */
+#define USBMODE_CM_reserved (1 << 0) /* reserved */
+
+#define HCSPARAMS_PPC (0x1<<4) /* Port Power Control */
+extern enum fsl_usb2_modes get_usb_mode(struct fsl_usb2_platform_data *pdata);
+#ifdef CONFIG_ARCH_MX6
+#include "regs-usbphy-mx6.h"
+#else
+#include "regs-usbphy-others.h"
+#endif
+
+#endif /* __ASM_ARCH_MXC_ARC_OTG_H__ */
+
diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h
new file mode 100644
index 00000000..6fda788e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/audmux.h
@@ -0,0 +1,60 @@
+#ifndef __MACH_AUDMUX_H
+#define __MACH_AUDMUX_H
+
+#define MX27_AUDMUX_HPCR1_SSI0 0
+#define MX27_AUDMUX_HPCR2_SSI1 1
+#define MX27_AUDMUX_HPCR3_SSI_PINS_4 2
+#define MX27_AUDMUX_PPCR1_SSI_PINS_1 3
+#define MX27_AUDMUX_PPCR2_SSI_PINS_2 4
+#define MX27_AUDMUX_PPCR3_SSI_PINS_3 5
+
+#define MX31_AUDMUX_PORT1_SSI0 0
+#define MX31_AUDMUX_PORT2_SSI1 1
+#define MX31_AUDMUX_PORT3_SSI_PINS_3 2
+#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
+#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
+#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
+
+#define MX51_AUDMUX_PORT1_SSI0 0
+#define MX51_AUDMUX_PORT2_SSI1 1
+#define MX51_AUDMUX_PORT3 2
+#define MX51_AUDMUX_PORT4 3
+#define MX51_AUDMUX_PORT5 4
+#define MX51_AUDMUX_PORT6 5
+#define MX51_AUDMUX_PORT7 6
+
+/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
+#define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
+#define MXC_AUDMUX_V1_PCR_INMEN (1 << 8)
+#define MXC_AUDMUX_V1_PCR_TXRXEN (1 << 10)
+#define MXC_AUDMUX_V1_PCR_SYN (1 << 12)
+#define MXC_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13)
+#define MXC_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20)
+#define MXC_AUDMUX_V1_PCR_RCLKDIR (1 << 24)
+#define MXC_AUDMUX_V1_PCR_RFSDIR (1 << 25)
+#define MXC_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26)
+#define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
+#define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31)
+
+/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
+#define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
+#define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
+#define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
+#define MXC_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22)
+#define MXC_AUDMUX_V2_PTCR_RFSDIR (1 << 21)
+#define MXC_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17)
+#define MXC_AUDMUX_V2_PTCR_RCLKDIR (1 << 16)
+#define MXC_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12)
+#define MXC_AUDMUX_V2_PTCR_SYN (1 << 11)
+
+#define MXC_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13)
+#define MXC_AUDMUX_V2_PDCR_TXRXEN (1 << 12)
+#define MXC_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8)
+#define MXC_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff)
+
+int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr);
+
+int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
+ unsigned int pdcr);
+
+#endif /* __MACH_AUDMUX_H */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
new file mode 100644
index 00000000..94b60dd4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+
+#include <mach/hardware.h>
+
+/*
+ * These symbols are used by drivers/net/cs89x0.c.
+ * This is ugly as hell, but we have to provide them until
+ * someone fixed the driver.
+ */
+
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+/* Offsets for the PBC Controller register */
+
+/* Ethernet Controller IO base address */
+#define PBC_CS8900A_IOBASE 0x020000
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
new file mode 100644
index 00000000..0df71bfe
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code for mobots boards,
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
+#define __ASM_ARCH_MXC_BOARD_MX31LILLY_H__
+
+#ifndef __ASSEMBLY__
+
+enum mx31lilly_boards {
+ MX31LILLY_NOBOARD = 0,
+ MX31LILLY_DB = 1,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls the baseboard's init function.
+ */
+
+extern void mx31lilly_db_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31LILLY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
new file mode 100644
index 00000000..c1ad0ae8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code for mobots boards,
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31LITE_H__
+#define __ASM_ARCH_MXC_BOARD_MX31LITE_H__
+
+#ifndef __ASSEMBLY__
+
+enum mx31lite_boards {
+ MX31LITE_NOBOARD = 0,
+ MX31LITE_DB = 1,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls the baseboard's init function.
+ */
+
+extern void mx31lite_db_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31LITE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
new file mode 100644
index 00000000..de145438
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
+#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__
+
+#ifndef __ASSEMBLY__
+
+enum mx31moboard_boards {
+ MX31NOBOARD = 0,
+ MX31DEVBOARD = 1,
+ MX31MARXBOT = 2,
+ MX31SMARTBOT = 3,
+ MX31EYEBOT = 4,
+};
+
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls the baseboard's init function.
+ */
+
+extern void mx31moboard_devboard_init(void);
+extern void mx31moboard_marxbot_init(void);
+extern void mx31moboard_smartbot_init(int board);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/plat-mxc/include/mach/board-pcm038.h
new file mode 100644
index 00000000..6f371e35
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-pcm038.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_PCM038_H__
+#define __ASM_ARCH_MXC_BOARD_PCM038_H__
+
+#ifndef __ASSEMBLY__
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls the baseboard's init function.
+ * TODO: Add your own baseboard init function and call it from
+ * inside pcm038_init().
+ *
+ * This example here is for the development board. Refer pcm970-baseboard.c
+ */
+
+extern void pcm970_baseboard_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_PCM038_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/clkdev.h b/arch/arm/plat-mxc/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
new file mode 100755
index 00000000..e150579e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2005-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_CLOCK_H__
+#define __ASM_ARCH_MXC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+#define CLK_NAME_LEN 32
+struct module;
+
+struct clk {
+#ifdef CONFIG_CLK_DEBUG
+ char name[CLK_NAME_LEN];
+ struct dentry *dentry;
+#endif
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Secondary clock to enable/disable with this clock */
+ struct clk *secondary;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_get_usecount(struct clk *clk);
+
+/* Clock flags */
+#define RATE_PROPAGATES (1 << 0) /* Program children too */
+#define ALWAYS_ENABLED (1 << 1) /* Clock cannot be disabled */
+#define RATE_FIXED (1 << 2) /* Fixed clock rate */
+#define CPU_FREQ_TRIG_UPDATE (1 << 3) /* CPUFREQ trig update */
+#define AHB_HIGH_SET_POINT (1 << 4) /* Requires max AHB clock */
+#define AHB_MED_SET_POINT (1 << 5) /* Requires med AHB clock */
+#define AHB_AUDIO_SET_POINT (1 << 6) /* Requires LOW AHB, but higher DDR clock */
+
+unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
+
+#ifdef CONFIG_CLK_DEBUG
+void clk_debug_register(struct clk *clk);
+#else
+static inline void clk_debug_register(struct clk *clk) {}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
new file mode 100755
index 00000000..3dfc6646
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_COMMON_H__
+#define __ASM_ARCH_MXC_COMMON_H__
+
+struct fec_platform_data;
+struct platform_device;
+struct clk;
+
+extern char *gp_reg_id;
+extern void mx1_map_io(void);
+extern void mx21_map_io(void);
+extern void mx25_map_io(void);
+extern void mx27_map_io(void);
+extern void mx31_map_io(void);
+extern void mx35_map_io(void);
+extern void mx50_map_io(void);
+extern void mx51_map_io(void);
+extern void mx53_map_io(void);
+extern void mx6_map_io(void);
+extern void mxc91231_map_io(void);
+extern void imx1_init_early(void);
+extern void imx21_init_early(void);
+extern void imx25_init_early(void);
+extern void imx27_init_early(void);
+extern void imx31_init_early(void);
+extern void imx35_init_early(void);
+extern void imx50_init_early(void);
+extern void imx51_init_early(void);
+extern void imx53_init_early(void);
+extern void mxc91231_init_early(void);
+extern void mxc_init_irq(void __iomem *);
+extern void tzic_init_irq(void __iomem *);
+extern void mx1_init_irq(void);
+extern void mx21_init_irq(void);
+extern void mx25_init_irq(void);
+extern void mx27_init_irq(void);
+extern void mx31_init_irq(void);
+extern void mx35_init_irq(void);
+extern void mx50_init_irq(void);
+extern void mx51_init_irq(void);
+extern void mx53_init_irq(void);
+extern void mx6_init_irq(void);
+extern void mxc91231_init_irq(void);
+extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
+extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
+extern int mx1_clocks_init(unsigned long fref);
+extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
+extern int mx25_clocks_init(void);
+extern int mx27_clocks_init(unsigned long fref);
+extern int mx31_clocks_init(unsigned long fref);
+extern int mx35_clocks_init(void);
+extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2);
+extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2);
+extern int mx50_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1);
+extern int mx6_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2);
+extern int mx6sl_clocks_init(unsigned long ckil, unsigned long osc,
+ unsigned long ckih1, unsigned long ckih2);
+extern void imx6_init_fec(struct fec_platform_data fec_data);
+extern int mxc91231_clocks_init(unsigned long fref);
+extern int mxc_register_gpios(void);
+extern int mxc_register_device(struct platform_device *pdev, void *data);
+extern void mxc_set_cpu_type(unsigned int type);
+extern void mxc_arch_reset_init(void __iomem *);
+extern void mxc91231_power_off(void);
+extern void mxc91231_arch_reset(int, const char *);
+extern void mxc91231_prepare_idle(void);
+extern void mx51_efikamx_reset(void);
+extern int mx53_revision(void);
+extern int mx50_revision(void);
+extern int mx53_display_revision(void);
+extern int mxs_reset_block(void __iomem *);
+extern void early_console_setup(unsigned long base, struct clk *clk);
+extern void mx6_cpu_regulator_init(void);
+extern int mx6q_sabreauto_init_pfuze100(u32 int_gpio);
+extern int mx6q_sabresd_init_pfuze100(u32 int_gpio);
+extern void imx_print_silicon_rev(const char *cpu, int srev);
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
new file mode 100644
index 00000000..e19086cc
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -0,0 +1,72 @@
+/* arch/arm/mach-imx/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <mach/hardware.h>
+
+#ifdef CONFIG_ARCH_MX1
+#define UART_PADDR MX1_UART1_BASE_ADDR
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX25_UART1_BASE_ADDR
+#endif
+
+#ifdef CONFIG_ARCH_MX2
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX2x_UART1_BASE_ADDR
+#endif
+
+#ifdef CONFIG_ARCH_MX3
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX3x_UART1_BASE_ADDR
+#endif
+
+#ifdef CONFIG_ARCH_MX5
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX51_UART1_BASE_ADDR
+#endif
+
+#ifdef CONFIG_ARCH_MX6Q
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX6Q_UART4_BASE_ADDR
+#endif
+
+#define UART_VADDR IMX_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+ .macro senduart,rd,rx
+ str \rd, [\rx, #0x40] @ TXDATA
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1002: ldr \rd, [\rx, #0x98] @ SR2
+ tst \rd, #1 << 3 @ TXDC
+ beq 1002b @ wait until transmit done
+ .endm
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
new file mode 100755
index 00000000..f6d616d0
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -0,0 +1,702 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+
+struct platform_device *imx_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *imx_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return imx_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
+
+struct imx_dma_res_data {
+ resource_size_t iobase;
+};
+struct platform_device *__init imx_add_dma(const struct imx_dma_res_data *data);
+
+#include <linux/fec.h>
+struct imx_fec_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+ const char *devid;
+};
+struct platform_device *__init imx_add_fec(
+ const struct imx_fec_data *data,
+ const struct fec_platform_data *pdata);
+
+#include <linux/can/platform/flexcan.h>
+struct imx_flexcan_data {
+ const char *devid;
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_flexcan(
+ const struct imx_flexcan_data *data,
+ const struct flexcan_platform_data *pdata);
+
+#include <linux/fsl_devices.h>
+struct platform_device *__init imx_add_mlb(
+ const struct mxc_mlb_platform_data *pdata);
+struct imx_fsl_usb2_udc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fsl_usb2_udc(
+ const struct imx_fsl_usb2_udc_data *data,
+ const struct fsl_usb2_platform_data *pdata);
+
+#include <linux/gpio_keys.h>
+struct platform_device *__init imx_add_gpio_keys(
+ const struct gpio_keys_platform_data *pdata);
+
+#include <mach/mx21-usbhost.h>
+struct imx_imx21_hcd_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx21_hcd(
+ const struct imx_imx21_hcd_data *data,
+ const struct mx21_usbh_platform_data *pdata);
+
+struct imx_imx2_wdt_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx2_wdt(
+ const struct imx_imx2_wdt_data *data);
+
+struct imx_imxdi_rtc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imxdi_rtc(
+ const struct imx_imxdi_rtc_data *data);
+
+struct imx_srtc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_srtc(
+ const struct imx_srtc_data *data);
+
+struct imx_snvs_rtc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_snvs_rtc(
+ const struct imx_snvs_rtc_data *data);
+
+struct imx_caam_jr_data {
+ resource_size_t offset_jr;
+ resource_size_t irq_jr;
+};
+
+struct imx_caam_data {
+ resource_size_t iobase_caam; /* entirety of CAAM register map */
+ resource_size_t iobase_caam_sm; /* base of secure memory */
+ resource_size_t iobase_snvs; /* base of SNVS */
+ resource_size_t irq_sec_vio; /* SNVS security violation */
+ resource_size_t irq_snvs; /* SNVS consolidated (incl. RTC) */
+ struct imx_caam_jr_data jr[4]; /* offset+IRQ for each possible ring */
+};
+
+struct platform_device *__init imx_add_caam(
+ const struct imx_caam_data *data);
+
+#include <mach/imxfb.h>
+struct imx_imx_fb_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_fb(
+ const struct imx_imx_fb_data *data,
+ const struct imx_fb_platform_data *pdata);
+
+#include <mach/i2c.h>
+struct imx_imx_i2c_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_i2c(
+ const struct imx_imx_i2c_data *data,
+ const struct imxi2c_platform_data *pdata);
+
+#include <linux/input/matrix_keypad.h>
+struct imx_imx_keypad_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_keypad(
+ const struct imx_imx_keypad_data *data,
+ const struct matrix_keymap_data *pdata);
+
+#include <mach/ssi.h>
+struct imx_imx_ssi_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmatx0;
+ resource_size_t dmarx0;
+ resource_size_t dmatx1;
+ resource_size_t dmarx1;
+};
+struct platform_device *__init imx_add_imx_ssi(
+ const struct imx_imx_ssi_data *data,
+ const struct imx_ssi_platform_data *pdata);
+
+#include <mach/esai.h>
+struct imx_imx_esai_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmatx;
+ resource_size_t dmarx;
+};
+struct platform_device *__init imx_add_imx_esai(
+ const struct imx_imx_esai_data *data,
+ const struct imx_esai_platform_data *pdata);
+
+#include <mach/imx-uart.h>
+struct imx_imx_uart_3irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irqrx;
+ resource_size_t irqtx;
+ resource_size_t irqrts;
+};
+struct platform_device *__init imx_add_imx_uart_3irq(
+ const struct imx_imx_uart_3irq_data *data,
+ const struct imxuart_platform_data *pdata);
+
+struct imx_imx_uart_1irq_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_uart_1irq(
+ const struct imx_imx_uart_1irq_data *data,
+ const struct imxuart_platform_data *pdata);
+
+#include <mach/usb.h>
+struct imx_imx_udc_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq0;
+ resource_size_t irq1;
+ resource_size_t irq2;
+ resource_size_t irq3;
+ resource_size_t irq4;
+ resource_size_t irq5;
+ resource_size_t irq6;
+};
+struct platform_device *__init imx_add_imx_udc(
+ const struct imx_imx_udc_data *data,
+ const struct imxusb_platform_data *pdata);
+#if 0
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/mx3_camera.h>
+struct imx_ipu_core_data {
+ resource_size_t iobase;
+ resource_size_t synirq;
+ resource_size_t errirq;
+};
+struct platform_device *__init imx_add_ipu_core(
+ const struct imx_ipu_core_data *data,
+ const struct ipu_platform_data *pdata);
+struct platform_device *__init imx_alloc_mx3_camera(
+ const struct imx_ipu_core_data *data,
+ const struct mx3_camera_pdata *pdata);
+struct platform_device *__init imx_add_mx3_sdc_fb(
+ const struct imx_ipu_core_data *data,
+ struct mx3fb_platform_data *pdata);
+#endif
+#include <mach/mx1_camera.h>
+struct imx_mx1_camera_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mx1_camera(
+ const struct imx_mx1_camera_data *data,
+ const struct mx1_camera_pdata *pdata);
+
+#include <mach/mx2_cam.h>
+struct imx_mx2_camera_data {
+ resource_size_t iobasecsi;
+ resource_size_t iosizecsi;
+ resource_size_t irqcsi;
+ resource_size_t iobaseemmaprp;
+ resource_size_t iosizeemmaprp;
+ resource_size_t irqemmaprp;
+};
+struct platform_device *__init imx_add_mx2_camera(
+ const struct imx_mx2_camera_data *data,
+ const struct mx2_camera_platform_data *pdata);
+
+#include <mach/mxc_ehci.h>
+struct imx_mxc_ehci_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct mxc_usbh_platform_data *pdata);
+
+struct platform_device *__init imx_add_fsl_ehci(
+ const struct imx_mxc_ehci_data *data,
+ const struct fsl_usb2_platform_data *pdata);
+
+#include <mach/mmc.h>
+struct imx_mxc_mmc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmareq;
+};
+struct platform_device *__init imx_add_mxc_mmc(
+ const struct imx_mxc_mmc_data *data,
+ const struct imxmmc_platform_data *pdata);
+
+#include <mach/mxc_nand.h>
+struct imx_mxc_nand_data {
+ /*
+ * id is traditionally 0, but -1 is more appropriate. We use -1 for new
+ * machines but don't change existing devices as the nand device usually
+ * appears in the kernel command line to pass its partitioning.
+ */
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t axibase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_nand(
+ const struct imx_mxc_nand_data *data,
+ const struct mxc_nand_platform_data *pdata);
+
+struct imx_mxc_pwm_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_pwm(
+ const struct imx_mxc_pwm_data *data);
+
+/* mxc_rtc */
+struct imx_mxc_rtc_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_rtc(
+ const struct imx_mxc_rtc_data *data);
+
+/* mxc_w1 */
+struct imx_mxc_w1_data {
+ resource_size_t iobase;
+};
+struct platform_device *__init imx_add_mxc_w1(
+ const struct imx_mxc_w1_data *data);
+
+#include <mach/esdhc.h>
+struct imx_sdhci_esdhc_imx_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_sdhci_esdhc_imx(
+ const struct imx_sdhci_esdhc_imx_data *data,
+ const struct esdhc_platform_data *pdata);
+
+#include <mach/spi.h>
+struct imx_spi_imx_data {
+ const char *devid;
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ int irq;
+};
+struct platform_device *__init imx_add_spi_imx(
+ const struct imx_spi_imx_data *data,
+ const struct spi_imx_master *pdata);
+
+#include <mach/ipu-v3.h>
+struct imx_ipuv3_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq_err;
+ resource_size_t irq;
+ unsigned int irq_start;
+ int (*init) (int);
+ void (*pg) (int);
+};
+struct platform_device *__init imx_add_ipuv3(
+ const int id,
+ const struct imx_ipuv3_data *data,
+ struct imx_ipuv3_platform_data *pdata);
+
+struct platform_device *__init imx_add_ipuv3_fb(
+ const int id,
+ const struct ipuv3_fb_platform_data *pdata);
+
+#include <mach/mxc_vpu.h>
+struct imx_vpu_data {
+ resource_size_t iobase;
+ resource_size_t irq_ipi;
+ resource_size_t irq_jpg;
+ bool iram_enable;
+ int iram_size;
+ void (*reset) (void);
+ void (*pg) (int);
+};
+struct platform_device *__init imx_add_vpu(
+ const struct imx_vpu_data *data);
+
+#include <mach/mxc_dvfs.h>
+struct imx_dvfs_core_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_dvfs_core(
+ const struct imx_dvfs_core_data *data,
+ const struct mxc_dvfs_platform_data *pdata);
+
+struct platform_device *__init imx_add_busfreq(void);
+
+#include <linux/fsl_devices.h>
+struct imx_tve_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_tve(
+ const struct imx_tve_data *data,
+ const struct fsl_mxc_tve_platform_data *pdata);
+
+#include <linux/ahci_platform.h>
+struct imx_ahci_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_ahci(
+ const struct imx_ahci_data *data,
+ const struct ahci_platform_data *pdata);
+
+struct imx_iim_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_iim(
+ const struct imx_iim_data *data,
+ const struct mxc_iim_platform_data *pdata);
+
+#include <mach/mxc_gpu.h>
+struct imx_mxc_gpu_data {
+ resource_size_t irq_2d;
+ resource_size_t irq_3d;
+ resource_size_t iobase_2d;
+ resource_size_t iobase_3d;
+ resource_size_t gmem_base;
+ resource_size_t gmem_size;
+};
+
+struct platform_device *__init imx_add_mxc_gpu(
+ const struct imx_mxc_gpu_data *data,
+ const struct mxc_gpu_platform_data *pdata);
+
+struct imx_perfmon_data {
+ resource_size_t iobase;
+ struct mxs_platform_perfmon_data *pdata;
+};
+
+struct platform_device *__init imx_add_perfmon(
+ const struct imx_perfmon_data *data);
+
+struct imx_ldb_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+};
+
+struct platform_device *__init imx_add_ldb(
+ const struct imx_ldb_data *data,
+ struct fsl_mxc_ldb_platform_data *pdata);
+
+struct imx_mxc_scc2_data {
+ resource_size_t iobase;
+ resource_size_t ram_start;
+ resource_size_t irq_smn;
+ resource_size_t irq_scm;
+};
+
+struct platform_device *__init imx_add_mxc_scc2(
+ const struct imx_mxc_scc2_data *data);
+
+struct imx_pxp_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_pxp(
+ const struct imx_pxp_data *data);
+struct platform_device *__init imx_add_imx_pxp_client(void);
+struct platform_device *__init imx_add_imx_pxp_v4l2(void);
+
+#include <linux/fsl_devices.h>
+struct imx_elcdif_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+
+struct platform_device *__init imx_add_imx_elcdif(
+ const struct imx_elcdif_data *data,
+ const struct mxc_fb_platform_data *pdata);
+
+#include <mach/epdc.h>
+struct imx_epdc_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx_epdc(
+ const struct imx_epdc_data *data,
+ const struct imx_epdc_fb_platform_data *pdata);
+
+struct platform_device *__init imx_add_imx_spdc(
+ const struct imx_epdc_data *data,
+ const struct imx_spdc_fb_platform_data *pdata);
+
+struct imx_spdif_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_spdif(
+ const struct imx_spdif_data *data,
+ const struct mxc_spdif_platform_data *pdata);
+
+struct imx_spdif_dai_data {
+ resource_size_t iobase;
+ resource_size_t dmatx;
+ resource_size_t dmarx;
+};
+struct platform_device *__init imx_add_spdif_dai(
+ const struct imx_spdif_dai_data *data);
+
+struct platform_device *__init imx_add_spdif_audio_device(void);
+
+#include <mach/viv_gpu.h>
+struct imx_viv_gpu_data {
+ resource_size_t phys_baseaddr;
+ resource_size_t irq_3d;
+ resource_size_t iobase_3d;
+ resource_size_t irq_2d;
+ resource_size_t iobase_2d;
+ resource_size_t irq_vg;
+ resource_size_t iobase_vg;
+};
+struct platform_device *__init imx_add_viv_gpu(
+ const struct imx_viv_gpu_data *data,
+ const struct viv_gpu_platform_data *pdata);
+
+#include <mach/anatop_thermal.h>
+struct imx_anatop_thermal_imx_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t calibration_addr;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_anatop_thermal_imx(
+ const struct imx_anatop_thermal_imx_data *data,
+ const struct anatop_thermal_platform_data *pdata);
+
+struct imx_otp_data {
+ resource_size_t iobase;
+ struct mxc_otp_platform_data *pdata;
+};
+
+struct platform_device *__init imx_add_otp(
+ const struct imx_otp_data *data);
+
+struct imx_viim_data {
+ resource_size_t iobase;
+};
+
+struct platform_device *__init imx_add_viim(
+ const struct imx_viim_data *data);
+
+struct imx_dcp_data {
+ resource_size_t iobase;
+ resource_size_t irq1;
+ resource_size_t irq2;
+};
+
+
+#include <mach/imx-pm.h>
+struct imx_pm_imx_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_pm_imx(
+ const struct imx_pm_imx_data *data,
+ const struct pm_platform_data *pdata);
+
+#include <mach/mxc_hdmi.h>
+struct imx_mxc_hdmi_data {
+ resource_size_t irq;
+ resource_size_t irq_wakeup;
+};
+
+struct platform_device *__init imx_add_mxc_hdmi(
+ const struct imx_mxc_hdmi_data *data,
+ const struct fsl_mxc_hdmi_platform_data *pdata);
+
+struct imx_mxc_hdmi_core_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+};
+
+struct platform_device *__init imx_add_mxc_hdmi_core(
+ const struct imx_mxc_hdmi_core_data *data,
+ const struct fsl_mxc_hdmi_core_platform_data *pdata);
+
+#include <mach/mxc_asrc.h>
+struct imx_imx_asrc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+ resource_size_t dmatx1;
+ resource_size_t dmarx1;
+ resource_size_t dmatx2;
+ resource_size_t dmarx2;
+ resource_size_t dmatx3;
+ resource_size_t dmarx3;
+};
+struct platform_device *__init imx_add_imx_asrc(
+ const struct imx_imx_asrc_data *data,
+ const struct imx_asrc_platform_data *pdata);
+
+struct imx_hdmi_soc_data {
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_hdmi_soc(void);
+
+struct platform_device *__init imx_add_hdmi_soc_dai(
+ const struct imx_hdmi_soc_data *data);
+
+#include <mach/mipi_dsi.h>
+struct imx_mipi_dsi_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_mipi_dsi(
+ const struct imx_mipi_dsi_data *data,
+ const struct mipi_dsi_platform_data *pdata);
+
+#include <mach/mipi_csi2.h>
+struct imx_mipi_csi2_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+};
+struct platform_device *__init imx_add_mipi_csi2(
+ const struct imx_mipi_csi2_data *data,
+ const struct mipi_csi2_platform_data *pdata);
+
+struct platform_device *__init imx_add_dcp(
+ const struct imx_dcp_data *data);
+
+struct imx_fsl_usb2_otg_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fsl_usb2_otg(
+ const struct imx_fsl_usb2_otg_data *data,
+ const struct fsl_usb2_platform_data *pdata);
+
+struct imx_fsl_usb2_wakeup_data {
+ int id;
+ resource_size_t irq_phy;
+ resource_size_t irq_core;
+};
+struct platform_device *__init imx_add_fsl_usb2_wakeup(
+ const struct imx_fsl_usb2_wakeup_data *data,
+ const struct fsl_usb2_wakeup_platform_data *pdata);
+
+/* gpmi-nand*/
+#include <linux/mtd/gpmi-nand.h>
+struct platform_device *__init imx_add_gpmi(
+ const struct gpmi_nand_platform_data *data);
+
+struct imx_rngb_data {
+ resource_size_t iobase;
+ resource_size_t irq;
+};
+
+struct platform_device *__init imx_add_rngb(
+ const struct imx_rngb_data *data);
+
+struct imx_vdoa_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_vdoa(
+ const struct imx_vdoa_data *data);
+
+#include <mach/pcie.h>
+struct imx_pcie_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+
+struct platform_device *__init imx_add_pcie(
+ const struct imx_pcie_data *data,
+ const struct imx_pcie_platform_data *pdata);
+
+void __init imx_add_imx_armpmu(void);
+
+struct imx_fsl_csi_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_fsl_csi(
+ const struct imx_fsl_csi_data *data);
diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
new file mode 100644
index 00000000..af2edb84
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_DMA_H__
+#define __ASM_ARCH_MXC_DMA_H__
+
+#include <linux/scatterlist.h>
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+
+#define MXC_DMA_DYNAMIC_CHANNEL 255
+
+#define MXC_DMA_DONE 0x0
+#define MXC_DMA_REQUEST_TIMEOUT 0x1
+#define MXC_DMA_TRANSFER_ERROR 0x2
+
+/*
+ * This enumerates peripheral types. Used for SDMA.
+ */
+enum sdma_peripheral_type {
+ IMX_DMATYPE_SSI, /* MCU domain SSI */
+ IMX_DMATYPE_SSI_SP, /* Shared SSI */
+ IMX_DMATYPE_MMC, /* MMC */
+ IMX_DMATYPE_SDHC, /* SDHC */
+ IMX_DMATYPE_UART, /* MCU domain UART */
+ IMX_DMATYPE_UART_SP, /* Shared UART */
+ IMX_DMATYPE_FIRI, /* FIRI */
+ IMX_DMATYPE_CSPI, /* MCU domain CSPI */
+ IMX_DMATYPE_CSPI_SP, /* Shared CSPI */
+ IMX_DMATYPE_SIM, /* SIM */
+ IMX_DMATYPE_ATA, /* ATA */
+ IMX_DMATYPE_CCM, /* CCM */
+ IMX_DMATYPE_EXT, /* External peripheral */
+ IMX_DMATYPE_MSHC, /* Memory Stick Host Controller */
+ IMX_DMATYPE_MSHC_SP, /* Shared Memory Stick Host Controller */
+ IMX_DMATYPE_DSP, /* DSP */
+ IMX_DMATYPE_MEMORY, /* Memory */
+ IMX_DMATYPE_FIFO_MEMORY,/* FIFO type Memory */
+ IMX_DMATYPE_SPDIF, /* SPDIF */
+ IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */
+ IMX_DMATYPE_ASRC, /* ASRC */
+ IMX_DMATYPE_ESAI, /* ESAI */
+ IMX_DMATYPE_HDMI,
+};
+
+enum imx_dma_prio {
+ DMA_PRIO_HIGH = 0,
+ DMA_PRIO_MEDIUM = 1,
+ DMA_PRIO_LOW = 2
+};
+
+struct imx_dma_data {
+ int dma_request; /* DMA request line */
+ int dma_request_p2p;
+ enum sdma_peripheral_type peripheral_type;
+ int priority;
+ void *private;
+};
+
+struct imx_pcm_dma_params {
+ enum sdma_peripheral_type peripheral_type;
+ int dma;
+ unsigned long dma_addr;
+ int burstsize;
+};
+
+static inline int imx_dma_is_ipu(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "ipu-core");
+}
+
+static inline int imx_dma_is_pxp(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "imx-pxp");
+}
+
+static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "imx-sdma") ||
+ !strcmp(dev_name(chan->device->dev), "imx-dma");
+}
+
+struct mxs_dma_data {
+ int chan_irq;
+};
+
+#define MXS_DMA_F_APPEND (1 << 0)
+#define MXS_DMA_F_WAIT4END (1 << 1)
+static inline int mxs_dma_is_apbh(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbh");
+}
+
+static inline int mxs_dma_is_apbx(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "mxs-dma-apbx");
+}
+
+void sdma_set_event_pending(struct dma_chan *chan);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h b/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h
new file mode 100755
index 00000000..560b0564
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file arch-mxc/dvfs_dptc_struct.h
+ *
+ * @brief MXC dvfs & dptc structure definitions file.
+ *
+ * @ingroup PM_MX27 PM_MX31 PM_MXC91321 PM_MXC91311
+ */
+#ifndef __ASM_ARCH_MXC_DVFS_DPTC_STRUCT_H__
+#define __ASM_ARCH_MXC_DVFS_DPTC_STRUCT_H__
+
+#include <linux/semaphore.h>
+#include <mach/pm_api.h>
+
+/*!
+ * Number of entries in the DPTC log buffer
+ */
+#define LOG_ENTRIES 1024
+
+/*!
+ * Log buffer Structure.\n
+ * This structure records the DPTC changes. \n
+ * This structure can be read by the user using the proc file system DPTC read entry.
+ */
+typedef struct {
+ /*!
+ * Index to the head of the log buffer
+ */
+ int head;
+
+ /*!
+ * Index to the tail of the log buffer
+ */
+ int tail;
+
+ /*!
+ * Mutex to allow access to the log buffer
+ */
+ struct semaphore mutex;
+
+ /*!
+ * Array of log buffer entries
+ */
+ dptc_log_entry_s entries[LOG_ENTRIES];
+} dptc_log_s;
+
+/*!
+ * DPTC driver data structure.\n
+ * Holds all driver parameters and data structures.
+ */
+typedef struct {
+ /*!
+ * This variable holds the current frequency index
+ */
+ int current_freq_index;
+
+ /*!
+ * Boolean variable, if TRUE the DPTC module is enabled
+ * if FALSE the DPTC module is disabled
+ */
+ int dptc_is_active;
+
+ /*!
+ * Boolean variable, if TRUE turbo mode enable
+ * if FALSE turbo mode disabled
+ */
+ int turbo_mode_active;
+
+ /*!
+ * Boolean variable, if TRUE the DVFS module is enabled
+ * if FALSE the DPTC module is disabled
+ */
+ int dvfs_is_active;
+
+ /*!
+ * Boolean variable, if TRUE the DPTC module is suspended
+ */
+ int suspended;
+
+ unsigned char rc_state;
+
+ /*!
+ * Pointer to the DVFS & DPTC translation table
+ */
+ dvfs_dptc_tables_s *dvfs_dptc_tables_ptr;
+
+ /*!
+ * The DPTC log buffer
+ */
+ dptc_log_s dptc_log_buffer;
+
+ /*!
+ * The DVFS log buffer
+ */
+ unsigned char *dvfs_log_buffer;
+
+ /*!
+ * The DVFS log buffer physical address (for SDMA)
+ */
+ dma_addr_t dvfs_log_buffer_phys;
+
+#ifdef CONFIG_MXC_DVFS_SDMA
+ /*!
+ * SDMA channel number
+ */
+ int sdma_channel;
+
+ /*!
+ * This holds the previous working point
+ */
+ int prev_wp;
+
+ /*!
+ * Wait entry for predictive DVFS
+ */
+ wait_queue_head_t dvfs_pred_wait;
+#endif
+
+ /*!
+ * This holds the current DVFS mode
+ */
+ unsigned int dvfs_mode;
+
+ /*!
+ * Log buffer read pointer
+ */
+ unsigned char *read_ptr;
+
+ /*
+ * Number of characters in log buffer
+ */
+ int chars_in_buffer;
+} dvfs_dptc_params_s;
+
+/*!
+ * This struct contains the array with values of supported frequencies in Hz
+ */
+typedef struct {
+ /*
+ * Number of supported states
+ */
+ unsigned int num_of_states;
+ /*!
+ * Array of frequencies
+ */
+ unsigned int *freqs;
+} dvfs_states_table;
+
+/*
+ * if not defined define TREU and FALSE values.
+ */
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif /* TRUE */
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
new file mode 100644
index 00000000..927f0d3c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Copyright (C) 2004-2011 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+
+#if defined(CONFIG_ARM_GIC)
+#include <asm/hardware/entry-macro-gic.S>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+#else
+
+#define AVIC_NIMASK 0x04
+
+ @ this macro disables fast irq (not implemented)
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+#ifndef CONFIG_MXC_TZIC
+ ldr \base, =avic_base
+ ldr \base, [\base]
+#ifdef CONFIG_MXC_IRQ_PRIOR
+ ldr r4, [\base, #AVIC_NIMASK]
+#endif
+#elif defined CONFIG_MXC_TZIC
+ ldr \base, =tzic_base
+ ldr \base, [\base]
+#endif /* CONFIG_MXC_TZIC */
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ @ this macro checks which interrupt occurred
+ @ and returns its number in irqnr
+ @ and returns if an interrupt occurred in irqstat
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifndef CONFIG_MXC_TZIC
+ @ Load offset & priority of the highest priority
+ @ interrupt pending from AVIC_NIVECSR
+ ldr \irqstat, [\base, #0x40]
+ @ Shift to get the decoded IRQ number, using ASR so
+ @ 'no interrupt pending' becomes 0xffffffff
+ mov \irqnr, \irqstat, asr #16
+ @ set zero flag if IRQ + 1 == 0
+ adds \tmp, \irqnr, #1
+#ifdef CONFIG_MXC_IRQ_PRIOR
+ bicne \tmp, \irqstat, #0xFFFFFFE0
+ strne \tmp, [\base, #AVIC_NIMASK]
+ streq r4, [\base, #AVIC_NIMASK]
+#endif
+#elif defined CONFIG_MXC_TZIC
+ @ Load offset & priority of the highest priority
+ @ interrupt pending.
+ @ 0x080 is INTSEC0 register
+ @ 0xD80 is HIPND0 register
+ mov \irqnr, #0
+1000: add \irqstat, \base, \irqnr, lsr #3
+ ldr \tmp, [\irqstat, #0xd80]
+ ldr \irqstat, [\irqstat, #0x080]
+ ands \tmp, \tmp, \irqstat
+ bne 1001f
+ add \irqnr, \irqnr, #32
+ cmp \irqnr, #128
+ blo 1000b
+ b 2001f
+1001: mov \irqstat, #1
+1002: tst \tmp, \irqstat
+ bne 2002f
+ movs \tmp, \tmp, lsr #1
+ addne \irqnr, \irqnr, #1
+ bne 1002b
+2001:
+ mov \irqnr, #0
+2002:
+ movs \irqnr, \irqnr
+#endif
+ .endm
+
+ @ irq priority table (not used)
+ .macro irq_prio_table
+ .endm
+#endif
+
diff --git a/arch/arm/plat-mxc/include/mach/epdc.h b/arch/arm/plat-mxc/include/mach/epdc.h
new file mode 100644
index 00000000..36aac882
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/epdc.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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_EPDC_H_
+#define __MACH_EPDC_H_
+
+struct imx_epdc_fb_mode {
+ struct fb_videomode *vmode;
+ int vscan_holdoff;
+ int sdoed_width;
+ int sdoed_delay;
+ int sdoez_width;
+ int sdoez_delay;
+ int gdclk_hp_offs;
+ int gdsp_offs;
+ int gdoe_offs;
+ int gdclk_offs;
+ int num_ce;
+};
+
+struct imx_epdc_fb_platform_data {
+ struct imx_epdc_fb_mode *epdc_mode;
+ int num_modes;
+ int (*get_pins) (void);
+ void (*put_pins) (void);
+ void (*enable_pins) (void);
+ void (*disable_pins) (void);
+};
+
+struct imx_spdc_panel_init_set {
+ bool yoe_pol;
+ bool dual_gate;
+ u8 resolution;
+ bool ud;
+ bool rl;
+ bool data_filter_n;
+ bool power_ready;
+ bool rgbw_mode_enable;
+ bool hburst_len_en;
+};
+
+struct imx_spdc_fb_mode {
+ struct fb_videomode *vmode;
+ struct imx_spdc_panel_init_set *init_set;
+ const char *wave_timing;
+};
+
+struct imx_spdc_fb_platform_data {
+ struct imx_spdc_fb_mode *spdc_mode;
+ int num_modes;
+ int (*get_pins) (void);
+ void (*put_pins) (void);
+ void (*enable_pins) (void);
+ void (*disable_pins) (void);
+};
+
+#endif /* __MACH_EPDC_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/esai.h b/arch/arm/plat-mxc/include/mach/esai.h
new file mode 100644
index 00000000..d77eb154
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/esai.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#ifndef __MACH_ESAI_H
+#define __MACH_ESAI_H
+
+struct imx_esai_platform_data {
+ unsigned int flags;
+#define IMX_ESAI_NET (1 << 0)
+#define IMX_ESAI_SYN (1 << 1)
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
new file mode 100644
index 00000000..10df1856
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Wolfram Sang <w.sang@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef __ASM_ARCH_IMX_ESDHC_H
+#define __ASM_ARCH_IMX_ESDHC_H
+
+enum cd_types {
+ ESDHC_CD_NONE, /* no CD, neither controller nor gpio */
+ ESDHC_CD_CONTROLLER, /* mmc controller internal CD */
+ ESDHC_CD_GPIO, /* external gpio pin for CD */
+ ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */
+ ESDHC_CD_WIFI_PWR, /* wifi host, use wifi pwr pin as CD */
+};
+
+/**
+ * struct esdhc_platform_data - optional platform data for esdhc on i.MX
+ *
+ * strongly recommended for i.MX25/35, not needed for other variants
+ *
+ * @wp_gpio: gpio for write_protect (-EINVAL if unused)
+ * @cd_gpio: gpio for card_detect interrupt (-EINVAL if unused)
+ */
+
+struct esdhc_platform_data {
+ unsigned int wp_gpio;
+ unsigned int cd_gpio;
+ enum cd_types cd_type;
+ unsigned int always_present;
+ unsigned int support_18v;
+ unsigned int support_8bit;
+ unsigned int keep_power_at_suspend;
+ unsigned int delay_line;
+ bool runtime_pm;
+ int (*platform_pad_change)(unsigned int index, int clock);
+};
+#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
new file mode 100644
index 00000000..a21d3313
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/eukrea-baseboards.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on board-pcm038.h which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_EUKREA_BASEBOARDS_H__
+#define __MACH_EUKREA_BASEBOARDS_H__
+
+#ifndef __ASSEMBLY__
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own baseboard init function and call it from
+ * inside eukrea_cpuimx25_init() eukrea_cpuimx27_init()
+ * eukrea_cpuimx35_init() eukrea_cpuimx51_init()
+ * or eukrea_cpuimx51sd_init().
+ *
+ * This example here is for the development board. Refer
+ * mach-mx25/eukrea_mbimxsd-baseboard.c for cpuimx25
+ * mach-imx/eukrea_mbimx27-baseboard.c for cpuimx27
+ * mach-mx3/eukrea_mbimxsd-baseboard.c for cpuimx35
+ * mach-mx5/eukrea_mbimx51-baseboard.c for cpuimx51
+ * mach-mx5/eukrea_mbimxsd-baseboard.c for cpuimx51sd
+ */
+
+extern void eukrea_mbimxsd25_baseboard_init(void);
+extern void eukrea_mbimx27_baseboard_init(void);
+extern void eukrea_mbimxsd35_baseboard_init(void);
+extern void eukrea_mbimx51_baseboard_init(void);
+extern void eukrea_mbimxsd51_baseboard_init(void);
+
+#endif
+
+#endif /* __MACH_EUKREA_BASEBOARDS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/fsl_usb.h b/arch/arm/plat-mxc/include/mach/fsl_usb.h
new file mode 100755
index 00000000..0b47a7d5
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/fsl_usb.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * USB Host side, platform-specific functionality.
+ */
+
+#include <linux/usb/fsl_xcvr.h>
+#include <mach/arc_otg.h>
+
+static void fsl_setup_phy(struct ehci_hcd *ehci,
+ enum fsl_usb2_phy_modes phy_mode,
+ int port_offset);
+
+static inline void fsl_platform_usb_setup(struct ehci_hcd *ehci)
+{
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = ehci_to_hcd(ehci)->self.controller->platform_data;
+ fsl_setup_phy(ehci, pdata->phy_mode, 0);
+}
+
+static inline void fsl_platform_set_host_mode(struct usb_hcd *hcd)
+{
+ unsigned int temp;
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
+
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_host)
+ pdata->xcvr_ops->set_host();
+
+ /* set host mode */
+ temp = readl(hcd->regs + 0x1a8);
+ writel(temp | USBMODE_CM_HOST, hcd->regs + 0x1a8);
+}
+
+/* Needed for enable PP and i2c/serial transceivers */
+static inline void
+fsl_platform_set_vbus_power(struct fsl_usb2_platform_data *pdata, int on)
+{
+ u32 temp;
+
+ /* HCSPARAMS */
+ temp = readl(pdata->regs + 0x104);
+ /* Port Power Control */
+ if (temp & HCSPARAMS_PPC) {
+ temp = readl(pdata->regs + FSL_SOC_USB_PORTSC1);
+ if (on)
+ temp |= PORT_POWER;
+ else
+ temp &= ~PORT_POWER;
+
+ writel(temp, pdata->regs + FSL_SOC_USB_PORTSC1);
+ }
+
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power)
+ pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, on);
+}
+
+/* Set USB AHB burst length for host */
+static inline void fsl_platform_set_ahb_burst(struct usb_hcd *hcd)
+{
+ struct fsl_usb2_platform_data *pdata;
+ unsigned int temp;
+
+ pdata = hcd->self.controller->platform_data;
+ if (pdata->change_ahb_burst) {
+ temp = readl(hcd->regs + FSL_SOC_USB_SBUSCFG);
+ writel((temp & (~(0x7))) | pdata->ahb_burst_mode,
+ hcd->regs + FSL_SOC_USB_SBUSCFG);
+ }
+
+ /* Increase TX fifo threshold for USB+ATA for i.mx35 2.0 */
+ if (cpu_is_mx35() && (imx_cpu_ver() >= IMX_CHIP_REVISION_2_0)) {
+ temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ /* Change TX FIFO threshold to be 0x20 */
+ writel((temp & (~(0x3f << 16))) | (0x20 << 16),
+ hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ }
+
+ /* Increase TX fifo threshold for USB+SD in Hostx */
+ if (cpu_is_mx53() && (strcmp("DR", pdata->name))) {
+ temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ /* Change TX FIFO threshold to be 0x08 */
+ writel((temp & (~(0x3f << 16))) | (0x08 << 16),
+ hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ }
+
+ /* Increase TX fifo threshold for in Hostx */
+ if (cpu_is_mx6()) {
+ temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ /* Change TX FIFO threshold to be 0x08 */
+ writel((temp & (~(0x3f << 16))) | (0x08 << 16),
+ hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ }
+}
diff --git a/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h b/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h
new file mode 100755
index 00000000..53f9b05a
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * USB Gadget side, platform-specific functionality.
+ */
+
+#include <linux/usb/fsl_xcvr.h>
+
+/* Needed for i2c/serial transceivers */
+static inline void
+fsl_platform_set_device_mode(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_device)
+ pdata->xcvr_ops->set_device();
+}
+
+static inline void
+fsl_platform_pullup_enable(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->pullup)
+ pdata->xcvr_ops->pullup(1);
+}
+
+static inline void
+fsl_platform_pullup_disable(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->pullup)
+ pdata->xcvr_ops->pullup(0);
+}
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
new file mode 100644
index 00000000..f008e40f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2007-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_GPIO_H__
+#define __ASM_ARCH_MXC_GPIO_H__
+
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+
+/* There's a off-by-one betweem the gpio bank number and the gpiochip */
+/* range e.g. GPIO_1_5 is gpio 5 under linux */
+#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (MXC_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - MXC_GPIO_IRQ_START)
+
+struct mxc_gpio_port {
+ void __iomem *base;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+ u32 both_edges;
+ spinlock_t lock;
+ u32 dir;
+};
+
+#define DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, _irq_high) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .irq = _irq, \
+ .irq_high = _irq_high, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _GPIO ## _hwid ## _BASE_ADDR), \
+ .virtual_irq_start = MXC_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, _irq) \
+ DEFINE_IMX_GPIO_PORT_IRQ_HIGH(soc, _id, _hwid, _irq, 0)
+#define DEFINE_IMX_GPIO_PORT(soc, _id, _hwid) \
+ DEFINE_IMX_GPIO_PORT_IRQ(soc, _id, _hwid, 0)
+
+int mxc_gpio_init(struct mxc_gpio_port*, int);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/gpmi-nfc.h b/arch/arm/plat-mxc/include/mach/gpmi-nfc.h
new file mode 100644
index 00000000..25fc6053
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/gpmi-nfc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_GPMI_NFC_H
+#define __INCLUDE_GPMI_NFC_H
+
+/* The size of the resource is fixed. */
+#define RES_SIZE 6
+
+/* Resource names for the GPMI NFC driver. */
+#define GPMI_NFC_GPMI_REGS_ADDR_RES_NAME "GPMI NFC GPMI Registers"
+#define GPMI_NFC_GPMI_INTERRUPT_RES_NAME "GPMI NFC GPMI Interrupt"
+#define GPMI_NFC_BCH_REGS_ADDR_RES_NAME "GPMI NFC BCH Registers"
+#define GPMI_NFC_BCH_INTERRUPT_RES_NAME "GPMI NFC BCH Interrupt"
+#define GPMI_NFC_DMA_CHANNELS_RES_NAME "GPMI NFC DMA Channels"
+#define GPMI_NFC_DMA_INTERRUPT_RES_NAME "GPMI NFC DMA Interrupt"
+
+/**
+ * struct gpmi_nfc_platform_data - GPMI NFC driver platform data.
+ *
+ * This structure communicates platform-specific information to the GPMI NFC
+ * driver that can't be expressed as resources.
+ *
+ * @platform_init: A pointer to a function the driver will call to
+ * initialize the platform (e.g., set up the pin mux).
+ * @platform_exit: A pointer to a function the driver will call to
+ * exit the platform (e.g., free pins).
+ * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and
+ * from the NAND Flash device, in nanoseconds.
+ * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and
+ * from the NAND Flash device, in nanoseconds.
+ * @max_chip_count: The maximum number of chips for which the driver
+ * should configure the hardware. This value most
+ * likely reflects the number of pins that are
+ * connected to a NAND Flash device. If this is
+ * greater than the SoC hardware can support, the
+ * driver will print a message and fail to initialize.
+ * @partitions: An optional pointer to an array of partition
+ * descriptions.
+ * @partition_count: The number of elements in the partitions array.
+ */
+struct gpmi_nfc_platform_data {
+ /* SoC hardware information. */
+ int (*platform_init)(void);
+ void (*platform_exit)(void);
+
+ /* NAND Flash information. */
+ unsigned int min_prop_delay_in_ns;
+ unsigned int max_prop_delay_in_ns;
+ unsigned int max_chip_count;
+
+ /* Medium information. */
+ struct mtd_partition *partitions;
+ unsigned partition_count;
+};
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
new file mode 100755
index 00000000..e1c52344
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2004-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#define __ASM_ARCH_MXC_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#define IMX_IO_P2V_MODULE(addr, module) \
+ (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? \
+ (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
+
+/*
+ * This is rather complicated for humans and ugly to verify, but for a machine
+ * it's OK. Still more as it is usually only applied to constants. The upsides
+ * on using this approach are:
+ *
+ * - same mapping on all i.MX machines
+ * - works for assembler, too
+ * - no need to nurture #defines for virtual addresses
+ *
+ * The downside it, it's hard to verify (but I have a script for that).
+ *
+ * Obviously this needs to be injective for each SoC. In general it maps the
+ * whole address space to [0xf4000000, 0xf5ffffff]. So [0xf6000000,0xfeffffff]
+ * is free for per-machine use (e.g. KZM_ARM11_01 uses 64MiB there).
+ *
+ * It applies the following mappings for the different SoCs:
+ *
+ * mx1:
+ * IO 0x00200000+0x100000 -> 0xf4000000+0x100000
+ * mx21:
+ * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
+ * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
+ * X_MEMC 0xdf000000+0x004000 -> 0xf5f00000+0x004000
+ * mx25:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * mx27:
+ * AIPI 0x10000000+0x100000 -> 0xf4400000+0x100000
+ * SAHB1 0x80000000+0x100000 -> 0xf4000000+0x100000
+ * X_MEMC 0xd8000000+0x100000 -> 0xf5c00000+0x100000
+ * mx31:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * mx35:
+ * AIPS1 0x43f00000+0x100000 -> 0xf5300000+0x100000
+ * AIPS2 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AVIC 0x68000000+0x100000 -> 0xf5800000+0x100000
+ * X_MEMC 0xb8000000+0x010000 -> 0xf4c00000+0x010000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * mx50:
+ * TZIC 0x0fffc000+0x004000 -> 0xf4bfc000+0x004000
+ * SPBA0 0x50000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x53f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x63f00000+0x100000 -> 0xf5300000+0x100000
+ * mx51:
+ * IRAM 0x1ffe0000+0x020000 -> 0xf4fe0000+0x020000
+ * DEBUG 0x60000000+0x100000 -> 0xf5000000+0x100000
+ * SPBA0 0x70000000+0x100000 -> 0xf5400000+0x100000
+ * AIPS1 0x73f00000+0x100000 -> 0xf5700000+0x100000
+ * AIPS2 0x83f00000+0x100000 -> 0xf4300000+0x100000
+ */
+#define IMX_IO_P2V(x) ( \
+ 0xf2000000 + \
+ (((x) & 0x50000000) >> 6) + \
+ (((x) & 0x0b000000) >> 4) + \
+ (((x) & 0x000fffff)))
+
+#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
+
+#include <mach/mxc.h>
+
+#ifdef CONFIG_ARCH_MX5
+#include <mach/mx50.h>
+#include <mach/mx51.h>
+#include <mach/mx53.h>
+#endif
+
+#ifdef CONFIG_ARCH_MX6
+#include <mach/mx6.h>
+#endif
+
+#ifdef CONFIG_ARCH_MX3
+#include <mach/mx3x.h>
+#include <mach/mx31.h>
+#include <mach/mx35.h>
+#endif
+
+#ifdef CONFIG_ARCH_MX2
+# include <mach/mx2x.h>
+# ifdef CONFIG_MACH_MX21
+# include <mach/mx21.h>
+# endif
+# ifdef CONFIG_MACH_MX27
+# include <mach/mx27.h>
+# endif
+#endif
+
+#ifdef CONFIG_ARCH_MX1
+# include <mach/mx1.h>
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+# include <mach/mx25.h>
+#endif
+
+#define imx_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+#define pcibios_assign_all_busses() 0
+
+#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/i2c.h b/arch/arm/plat-mxc/include/mach/i2c.h
new file mode 100644
index 00000000..4a5dc5c6
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/i2c.h
@@ -0,0 +1,25 @@
+/*
+ * i2c.h - i.MX I2C driver header file
+ *
+ * Copyright (c) 2008, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __ASM_ARCH_I2C_H_
+#define __ASM_ARCH_I2C_H_
+
+/**
+ * struct imxi2c_platform_data - structure of platform data for MXC I2C driver
+ * @init: Initialise gpio's and other board specific things
+ * @exit: Free everything initialised by @init
+ * @bitrate: Bus speed measured in Hz
+ *
+ **/
+struct imxi2c_platform_data {
+ int (*init)(struct device *dev);
+ void (*exit)(struct device *dev);
+ int bitrate;
+};
+
+#endif /* __ASM_ARCH_I2C_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/iim.h b/arch/arm/plat-mxc/include/mach/iim.h
new file mode 100644
index 00000000..315bffad
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iim.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_IIM_H__
+#define __ASM_ARCH_MXC_IIM_H__
+
+/* Register offsets */
+#define MXC_IIMSTAT 0x0000
+#define MXC_IIMSTATM 0x0004
+#define MXC_IIMERR 0x0008
+#define MXC_IIMEMASK 0x000C
+#define MXC_IIMFCTL 0x0010
+#define MXC_IIMUA 0x0014
+#define MXC_IIMLA 0x0018
+#define MXC_IIMSDAT 0x001C
+#define MXC_IIMPREV 0x0020
+#define MXC_IIMSREV 0x0024
+#define MXC_IIMPRG_P 0x0028
+#define MXC_IIMSCS0 0x002C
+#define MXC_IIMSCS1 0x0030
+#define MXC_IIMSCS2 0x0034
+#define MXC_IIMSCS3 0x0038
+#define MXC_IIMFBAC0 0x0800
+#define MXC_IIMJAC 0x0804
+#define MXC_IIMHWV1 0x0808
+#define MXC_IIMHWV2 0x080C
+#define MXC_IIMHAB0 0x0810
+#define MXC_IIMHAB1 0x0814
+/* Definitions for i.MX27 TO2 */
+#define MXC_IIMMAC 0x0814
+#define MXC_IIMPREV_FUSE 0x0818
+#define MXC_IIMSREV_FUSE 0x081C
+#define MXC_IIMSJC_CHALL_0 0x0820
+#define MXC_IIMSJC_CHALL_7 0x083C
+#define MXC_IIMFB0UC17 0x0840
+#define MXC_IIMFB0UC255 0x0BFC
+#define MXC_IIMFBAC1 0x0C00
+/* Definitions for i.MX27 TO2 */
+#define MXC_IIMSUID 0x0C04
+#define MXC_IIMKEY0 0x0C04
+#define MXC_IIMKEY20 0x0C54
+#define MXC_IIMSJC_RESP_0 0x0C58
+#define MXC_IIMSJC_RESP_7 0x0C74
+#define MXC_IIMFB1UC30 0x0C78
+#define MXC_IIMFB1UC255 0x0FFC
+
+/* Bit definitions */
+
+#define MXC_IIMHWV1_WLOCK (0x1 << 7)
+#define MXC_IIMHWV1_MCU_ENDIAN (0x1 << 6)
+#define MXC_IIMHWV1_DSP_ENDIAN (0x1 << 5)
+#define MXC_IIMHWV1_BOOT_INT (0x1 << 4)
+#define MXC_IIMHWV1_SCC_DISABLE (0x1 << 3)
+#define MXC_IIMHWV1_HANTRO_DISABLE (0x1 << 2)
+#define MXC_IIMHWV1_MEMSTICK_DIS (0x1 << 1)
+
+#define MXC_IIMHWV2_WLOCK (0x1 << 7)
+#define MXC_IIMHWV2_BP_SDMA (0x1 << 6)
+#define MXC_IIMHWV2_SCM_DCM (0x1 << 5)
+
+#endif /* __ASM_ARCH_MXC_IIM_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/imx-pm.h b/arch/arm/plat-mxc/include/mach/imx-pm.h
new file mode 100644
index 00000000..f6d375a4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/imx-pm.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __ASM_ARCH_IMX_PM_H
+#define __ASM_ARCH_IMX_PM_H
+
+/**
+ * struct pm_platform_data - optional platform data for pm on i.MX
+ *
+ */
+
+struct pm_platform_data {
+ char *name;
+ void (*suspend_enter) (void);
+ void (*suspend_exit) (void);
+};
+#endif /* __ASM_ARCH_IMX_PM_H */
diff --git a/arch/arm/plat-mxc/include/mach/imx-uart.h b/arch/arm/plat-mxc/include/mach/imx-uart.h
new file mode 100644
index 00000000..21dcdaf2
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/imx-uart.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef ASMARM_ARCH_UART_H
+#define ASMARM_ARCH_UART_H
+
+#define IMXUART_HAVE_RTSCTS (1<<0)
+#define IMXUART_IRDA (1<<1)
+#define IMXUART_USE_DCEDTE (1<<2)
+#define IMXUART_SDMA (1<<3)
+
+struct imxuart_platform_data {
+ int (*init)(struct platform_device *pdev);
+ void (*exit)(struct platform_device *pdev);
+ unsigned int flags;
+ void (*irda_enable)(int enable);
+ unsigned int irda_inv_rx:1;
+ unsigned int irda_inv_tx:1;
+ unsigned short transceiver_delay;
+ unsigned int dma_req_rx;
+ unsigned int dma_req_tx;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/imx_rfkill.h b/arch/arm/plat-mxc/include/mach/imx_rfkill.h
new file mode 100755
index 00000000..d7263f57
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/imx_rfkill.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef IMX_RFKILL_H
+#define IMX_RFKILL_H
+struct imx_bt_rfkill_platform_data {
+ int (*power_change) (int status);
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h
new file mode 100644
index 00000000..9de8f062
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/imxfb.h
@@ -0,0 +1,84 @@
+/*
+ * This structure describes the machine which we are running on.
+ */
+#ifndef __MACH_IMXFB_H__
+#define __MACH_IMXFB_H__
+
+#include <linux/fb.h>
+
+#define PCR_TFT (1 << 31)
+#define PCR_COLOR (1 << 30)
+#define PCR_PBSIZ_1 (0 << 28)
+#define PCR_PBSIZ_2 (1 << 28)
+#define PCR_PBSIZ_4 (2 << 28)
+#define PCR_PBSIZ_8 (3 << 28)
+#define PCR_BPIX_1 (0 << 25)
+#define PCR_BPIX_2 (1 << 25)
+#define PCR_BPIX_4 (2 << 25)
+#define PCR_BPIX_8 (3 << 25)
+#define PCR_BPIX_12 (4 << 25)
+#define PCR_BPIX_16 (5 << 25)
+#define PCR_BPIX_18 (6 << 25)
+#define PCR_PIXPOL (1 << 24)
+#define PCR_FLMPOL (1 << 23)
+#define PCR_LPPOL (1 << 22)
+#define PCR_CLKPOL (1 << 21)
+#define PCR_OEPOL (1 << 20)
+#define PCR_SCLKIDLE (1 << 19)
+#define PCR_END_SEL (1 << 18)
+#define PCR_END_BYTE_SWAP (1 << 17)
+#define PCR_REV_VS (1 << 16)
+#define PCR_ACD_SEL (1 << 15)
+#define PCR_ACD(x) (((x) & 0x7f) << 8)
+#define PCR_SCLK_SEL (1 << 7)
+#define PCR_SHARP (1 << 6)
+#define PCR_PCD(x) ((x) & 0x3f)
+
+#define PWMR_CLS(x) (((x) & 0x1ff) << 16)
+#define PWMR_LDMSK (1 << 15)
+#define PWMR_SCR1 (1 << 10)
+#define PWMR_SCR0 (1 << 9)
+#define PWMR_CC_EN (1 << 8)
+#define PWMR_PW(x) ((x) & 0xff)
+
+#define LSCR1_PS_RISE_DELAY(x) (((x) & 0x7f) << 26)
+#define LSCR1_CLS_RISE_DELAY(x) (((x) & 0x3f) << 16)
+#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8)
+#define LSCR1_GRAY2(x) (((x) & 0xf) << 4)
+#define LSCR1_GRAY1(x) (((x) & 0xf))
+
+#define DMACR_BURST (1 << 31)
+#define DMACR_HM(x) (((x) & 0xf) << 16)
+#define DMACR_TM(x) ((x) & 0xf)
+
+struct imx_fb_videomode {
+ struct fb_videomode mode;
+ u32 pcr;
+ unsigned char bpp;
+};
+
+struct imx_fb_platform_data {
+ struct imx_fb_videomode *mode;
+ int num_modes;
+
+ u_int cmap_greyscale:1,
+ cmap_inverse:1,
+ cmap_static:1,
+ unused:29;
+
+ u_int pwmr;
+ u_int lscr1;
+ u_int dmacr;
+
+ u_char * fixed_screen_cpu;
+ dma_addr_t fixed_screen_dma;
+
+ int (*init)(struct platform_device *);
+ void (*exit)(struct platform_device *);
+
+ void (*lcd_power)(int);
+ void (*backlight_power)(int);
+};
+
+void set_imx_fb_info(struct imx_fb_platform_data *);
+#endif /* ifndef __MACH_IMXFB_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/io.h b/arch/arm/plat-mxc/include/mach/io.h
new file mode 100644
index 00000000..4347a87d
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/io.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_IO_H__
+#define __ASM_ARCH_MXC_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+#if defined(CONFIG_SOC_IMX31) || defined(CONFIG_SOC_IMX35)
+#include <mach/hardware.h>
+
+#define __arch_ioremap __imx_ioremap
+#define __arch_iounmap __iounmap
+
+#define addr_in_module(addr, mod) \
+ ((unsigned long)(addr) - mod ## _BASE_ADDR < mod ## _SIZE)
+
+static inline void __iomem *
+__imx_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+{
+ if (mtype == MT_DEVICE && (cpu_is_mx31() || cpu_is_mx35())) {
+ /*
+ * Access all peripherals below 0x80000000 as nonshared device
+ * on mx3, but leave l2cc alone. Otherwise cache corruptions
+ * can occur.
+ */
+ if (phys_addr < 0x80000000 &&
+ !addr_in_module(phys_addr, MX3x_L2CC))
+ mtype = MT_DEVICE_NONSHARED;
+ }
+
+ return __arm_ioremap(phys_addr, size, mtype);
+}
+#endif
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
new file mode 100644
index 00000000..6b1507cf
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx1.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_MX1_H__
+#define __MACH_IOMUX_MX1_H__
+
+#include <mach/iomux-v1.h>
+
+#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0)
+#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1)
+#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2)
+#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4)
+#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5)
+#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6)
+#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7)
+#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8)
+#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9)
+#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10)
+#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11)
+#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12)
+#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13)
+#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14)
+#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17)
+#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21)
+#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22)
+#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23)
+#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24)
+#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24)
+#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25)
+#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25)
+#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26)
+#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26)
+#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27)
+#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27)
+#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28)
+#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28)
+#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29)
+#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30)
+#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30)
+#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31)
+#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31)
+#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8)
+#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8)
+#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9)
+#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9)
+#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10)
+#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10)
+#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11)
+#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11)
+#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12)
+#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12)
+#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13)
+#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13)
+#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14)
+#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15)
+#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_AF | GPIO_IN | 16)
+#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17)
+#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18)
+#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19)
+#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20)
+#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21)
+#define PB22_PF_USBD_RCV (GPIO_PORTB | GPIO_PF | 22)
+#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24)
+#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25)
+#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28)
+#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_PF | GPIO_IN | 29)
+#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30)
+#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_PF | GPIO_IN | 31)
+#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3)
+#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4)
+#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6)
+#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_PF | GPIO_IN | 10)
+#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 12)
+#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13)
+#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15)
+#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17)
+#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24)
+#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25)
+#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26)
+#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27)
+#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28)
+#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29)
+#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30)
+#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31)
+#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6)
+#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7)
+#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_AF | GPIO_IN | 7)
+#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7)
+#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8)
+#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8)
+#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8)
+#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9)
+#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9)
+#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9)
+#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10)
+#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10)
+#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10)
+#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11)
+#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12)
+#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13)
+#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14)
+#define PD15_PF_LD0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15)
+#define PD16_PF_LD1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16)
+#define PD17_PF_LD2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_LD3 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_LD4 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_LD5 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_LD6 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_LD7 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_LD8 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23)
+#define PD24_PF_LD9 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
+#define PD25_PF_LD10 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_LD11 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_LD12 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_LD13 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_LD14 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_LD15 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30)
+#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31)
+#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31)
+
+#endif /* ifndef __MACH_IOMUX_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
new file mode 100644
index 00000000..1495dfda
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx21.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_MX21_H__
+#define __MACH_IOMUX_MX21_H__
+
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
+
+/* Primary GPIO pin functions */
+
+#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5)
+#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6)
+#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7)
+#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8)
+#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9)
+#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10)
+#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11)
+#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12)
+#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13)
+#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16)
+#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17)
+#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18)
+#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19)
+#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0)
+#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1)
+#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2)
+#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16)
+
+/* Alternate GPIO pin functions */
+
+#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5)
+#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6)
+#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7)
+#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8)
+#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9)
+#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10)
+#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11)
+#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12)
+#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13)
+#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14)
+#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15)
+#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16)
+#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17)
+#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18)
+#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19)
+#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20)
+#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21)
+#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22)
+#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23)
+#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29)
+#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21)
+#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22)
+#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23)
+#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24)
+#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8)
+#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0)
+#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1)
+#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2)
+#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3)
+#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4)
+#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27)
+
+/* CIN GPIO pin functions */
+
+#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26)
+
+/* AOUT GPIO pin functions */
+
+#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29)
+#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19)
+#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20)
+#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25)
+#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26)
+#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9)
+#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6)
+#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7)
+#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8)
+#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9)
+#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10)
+#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11)
+#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12)
+#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13)
+#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14)
+
+#endif /* ifndef __MACH_IOMUX_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
new file mode 100644
index 00000000..2e5244de
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -0,0 +1,520 @@
+/*
+ * arch/arm/plat-mxc/include/mach/iomux-mx25.h
+ *
+ * Copyright (C) 2009 by Lothar Wassmann <LW@KARO-electronics.de>
+ *
+ * based on arch/arm/mach-mx25/mx25_pins.h
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ * and
+ * arch/arm/plat-mxc/include/mach/iomux-mx35.h
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_IOMUX_MX25_H__
+#define __MACH_IOMUX_MX25_H__
+
+#include <mach/iomux-v3.h>
+
+/*
+ * IOMUX/PAD Bit field definitions
+ */
+
+#define MX25_PAD_A10__A10 IOMUX_PAD(0x000, 0x008, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A10__GPIO_4_0 IOMUX_PAD(0x000, 0x008, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A13__A13 IOMUX_PAD(0x22C, 0x00c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A13__GPIO_4_1 IOMUX_PAD(0x22C, 0x00c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A14__A14 IOMUX_PAD(0x230, 0x010, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A14__GPIO_2_0 IOMUX_PAD(0x230, 0x010, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A15__A15 IOMUX_PAD(0x234, 0x014, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A15__GPIO_2_1 IOMUX_PAD(0x234, 0x014, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A16__A16 IOMUX_PAD(0x000, 0x018, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A16__GPIO_2_2 IOMUX_PAD(0x000, 0x018, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A17__A17 IOMUX_PAD(0x238, 0x01c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A17__GPIO_2_3 IOMUX_PAD(0x238, 0x01c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A18__A18 IOMUX_PAD(0x23c, 0x020, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A18__GPIO_2_4 IOMUX_PAD(0x23c, 0x020, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A18__FEC_COL IOMUX_PAD(0x23c, 0x020, 0x17, 0x504, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A19__A19 IOMUX_PAD(0x240, 0x024, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A19__FEC_RX_ER IOMUX_PAD(0x240, 0x024, 0x17, 0x518, 0, NO_PAD_CTRL)
+#define MX25_PAD_A19__GPIO_2_5 IOMUX_PAD(0x240, 0x024, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A20__A20 IOMUX_PAD(0x244, 0x028, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A20__GPIO_2_6 IOMUX_PAD(0x244, 0x028, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A20__FEC_RDATA2 IOMUX_PAD(0x244, 0x028, 0x17, 0x50c, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A21__A21 IOMUX_PAD(0x248, 0x02c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A21__GPIO_2_7 IOMUX_PAD(0x248, 0x02c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A21__FEC_RDATA3 IOMUX_PAD(0x248, 0x02c, 0x17, 0x510, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A22__A22 IOMUX_PAD(0x000, 0x030, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A22__GPIO_2_8 IOMUX_PAD(0x000, 0x030, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A23__A23 IOMUX_PAD(0x24c, 0x034, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A23__GPIO_2_9 IOMUX_PAD(0x24c, 0x034, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A24__A24 IOMUX_PAD(0x250, 0x038, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A24__GPIO_2_10 IOMUX_PAD(0x250, 0x038, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A24__FEC_RX_CLK IOMUX_PAD(0x250, 0x038, 0x17, 0x514, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_A25__A25 IOMUX_PAD(0x254, 0x03c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A25__GPIO_2_11 IOMUX_PAD(0x254, 0x03c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_A25__FEC_CRS IOMUX_PAD(0x254, 0x03c, 0x17, 0x508, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_EB0__EB0 IOMUX_PAD(0x258, 0x040, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB0__AUD4_TXD IOMUX_PAD(0x258, 0x040, 0x14, 0x464, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB0__GPIO_2_12 IOMUX_PAD(0x258, 0x040, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_EB1__EB1 IOMUX_PAD(0x25c, 0x044, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB1__AUD4_RXD IOMUX_PAD(0x25c, 0x044, 0x14, 0x460, 0, NO_PAD_CTRL)
+#define MX25_PAD_EB1__GPIO_2_13 IOMUX_PAD(0x25c, 0x044, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_OE__OE IOMUX_PAD(0x260, 0x048, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE__AUD4_TXC IOMUX_PAD(0x260, 0x048, 0x14, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE__GPIO_2_14 IOMUX_PAD(0x260, 0x048, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS0__CS0 IOMUX_PAD(0x000, 0x04c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS0__GPIO_4_2 IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS1__CS1 IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS1__NF_CE3 IOMUX_PAD(0x000, 0x050, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS1__GPIO_4_3 IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS4__CS4 IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__NF_CE1 IOMUX_PAD(0x264, 0x054, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__UART5_CTS IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__GPIO_3_20 IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CS5__CS5 IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__NF_CE2 IOMUX_PAD(0x268, 0x058, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__UART5_RTS IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__GPIO_3_21 IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NF_CE0__NF_CE0 IOMUX_PAD(0x26c, 0x05c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NF_CE0__GPIO_3_22 IOMUX_PAD(0x26c, 0x05c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_ECB__ECB IOMUX_PAD(0x270, 0x060, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_ECB__UART5_TXD_MUX IOMUX_PAD(0x270, 0x060, 0x13, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_ECB__GPIO_3_23 IOMUX_PAD(0x270, 0x060, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LBA__LBA IOMUX_PAD(0x274, 0x064, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LBA__UART5_RXD_MUX IOMUX_PAD(0x274, 0x064, 0x13, 0x578, 0, NO_PAD_CTRL)
+#define MX25_PAD_LBA__GPIO_3_24 IOMUX_PAD(0x274, 0x064, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_BCLK__BCLK IOMUX_PAD(0x000, 0x068, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BCLK__GPIO_4_4 IOMUX_PAD(0x000, 0x068, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_RW__RW IOMUX_PAD(0x278, 0x06c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RW__AUD4_TXFS IOMUX_PAD(0x278, 0x06c, 0x14, 0x474, 0, NO_PAD_CTRL)
+#define MX25_PAD_RW__GPIO_3_25 IOMUX_PAD(0x278, 0x06c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFWE_B__NFWE_B IOMUX_PAD(0x000, 0x070, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFWE_B__GPIO_3_26 IOMUX_PAD(0x000, 0x070, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFRE_B__NFRE_B IOMUX_PAD(0x000, 0x074, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFRE_B__GPIO_3_27 IOMUX_PAD(0x000, 0x074, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFALE__NFALE IOMUX_PAD(0x000, 0x078, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFALE__GPIO_3_28 IOMUX_PAD(0x000, 0x078, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFCLE__NFCLE IOMUX_PAD(0x000, 0x07c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFCLE__GPIO_3_29 IOMUX_PAD(0x000, 0x07c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFWP_B__NFWP_B IOMUX_PAD(0x000, 0x080, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_NFWP_B__GPIO_3_30 IOMUX_PAD(0x000, 0x080, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_NFRB__NFRB IOMUX_PAD(0x27c, 0x084, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_NFRB__GPIO_3_31 IOMUX_PAD(0x27c, 0x084, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D15__D15 IOMUX_PAD(0x280, 0x088, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D15__LD16 IOMUX_PAD(0x280, 0x088, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D15__GPIO_4_5 IOMUX_PAD(0x280, 0x088, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D14__D14 IOMUX_PAD(0x284, 0x08c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D14__LD17 IOMUX_PAD(0x284, 0x08c, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D14__GPIO_4_6 IOMUX_PAD(0x284, 0x08c, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D13__D13 IOMUX_PAD(0x288, 0x090, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D13__LD18 IOMUX_PAD(0x288, 0x090, 0x01, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D13__GPIO_4_7 IOMUX_PAD(0x288, 0x090, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D12__D12 IOMUX_PAD(0x28c, 0x094, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D12__GPIO_4_8 IOMUX_PAD(0x28c, 0x094, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D11__D11 IOMUX_PAD(0x290, 0x098, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D11__GPIO_4_9 IOMUX_PAD(0x290, 0x098, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D10__D10 IOMUX_PAD(0x294, 0x09c, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D10__GPIO_4_10 IOMUX_PAD(0x294, 0x09c, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D10__USBOTG_OC IOMUX_PAD(0x294, 0x09c, 0x06, 0x57c, 0, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_D9__D9 IOMUX_PAD(0x298, 0x0a0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D9__GPIO_4_11 IOMUX_PAD(0x298, 0x0a0, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D9__USBH2_PWR IOMUX_PAD(0x298, 0x0a0, 0x06, 0, 0, PAD_CTL_PKE)
+
+#define MX25_PAD_D8__D8 IOMUX_PAD(0x29c, 0x0a4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D8__GPIO_4_12 IOMUX_PAD(0x29c, 0x0a4, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D8__USBH2_OC IOMUX_PAD(0x29c, 0x0a4, 0x06, 0x580, 0, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_D7__D7 IOMUX_PAD(0x2a0, 0x0a8, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D7__GPIO_4_13 IOMUX_PAD(0x2a0, 0x0a8, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D6__D6 IOMUX_PAD(0x2a4, 0x0ac, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D6__GPIO_4_14 IOMUX_PAD(0x2a4, 0x0ac, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D5__D5 IOMUX_PAD(0x2a8, 0x0b0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D5__GPIO_4_15 IOMUX_PAD(0x2a8, 0x0b0, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D4__D4 IOMUX_PAD(0x2ac, 0x0b4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D4__GPIO_4_16 IOMUX_PAD(0x2ac, 0x0b4, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D3__D3 IOMUX_PAD(0x2b0, 0x0b8, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D3__GPIO_4_17 IOMUX_PAD(0x2b0, 0x0b8, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D2__D2 IOMUX_PAD(0x2b4, 0x0bc, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D2__GPIO_4_18 IOMUX_PAD(0x2b4, 0x0bc, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D1__D1 IOMUX_PAD(0x2b8, 0x0c0, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D1__GPIO_4_19 IOMUX_PAD(0x2b8, 0x0c0, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_D0__D0 IOMUX_PAD(0x2bc, 0x0c4, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_D0__GPIO_4_20 IOMUX_PAD(0x2bc, 0x0c4, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD0__LD0 IOMUX_PAD(0x2c0, 0x0c8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD0__CSI_D0 IOMUX_PAD(0x2c0, 0x0c8, 0x12, 0x488, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD0__GPIO_2_15 IOMUX_PAD(0x2c0, 0x0c8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD1__LD1 IOMUX_PAD(0x2c4, 0x0cc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD1__CSI_D1 IOMUX_PAD(0x2c4, 0x0cc, 0x12, 0x48c, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD1__GPIO_2_16 IOMUX_PAD(0x2c4, 0x0cc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD2__LD2 IOMUX_PAD(0x2c8, 0x0d0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD2__GPIO_2_17 IOMUX_PAD(0x2c8, 0x0d0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD3__LD3 IOMUX_PAD(0x2cc, 0x0d4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD3__GPIO_2_18 IOMUX_PAD(0x2cc, 0x0d4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD4__LD4 IOMUX_PAD(0x2d0, 0x0d8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD4__GPIO_2_19 IOMUX_PAD(0x2d0, 0x0d8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD5__LD5 IOMUX_PAD(0x2d4, 0x0dc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD5__GPIO_1_19 IOMUX_PAD(0x2d4, 0x0dc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD6__LD6 IOMUX_PAD(0x2d8, 0x0e0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD6__GPIO_1_20 IOMUX_PAD(0x2d8, 0x0e0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD7__LD7 IOMUX_PAD(0x2dc, 0x0e4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD7__GPIO_1_21 IOMUX_PAD(0x2dc, 0x0e4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD8__LD8 IOMUX_PAD(0x2e0, 0x0e8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD8__FEC_TX_ERR IOMUX_PAD(0x2e0, 0x0e8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD9__LD9 IOMUX_PAD(0x2e4, 0x0ec, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD9__FEC_COL IOMUX_PAD(0x2e4, 0x0ec, 0x15, 0x504, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_LD10__LD10 IOMUX_PAD(0x2e8, 0x0f0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD10__FEC_RX_ER IOMUX_PAD(0x2e8, 0x0f0, 0x15, 0x518, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_LD11__LD11 IOMUX_PAD(0x2ec, 0x0f4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD11__FEC_RDATA2 IOMUX_PAD(0x2ec, 0x0f4, 0x15, 0x50c, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_LD12__LD12 IOMUX_PAD(0x2f0, 0x0f8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD12__FEC_RDATA3 IOMUX_PAD(0x2f0, 0x0f8, 0x15, 0x510, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_LD13__LD13 IOMUX_PAD(0x2f4, 0x0fc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD13__FEC_TDATA2 IOMUX_PAD(0x2f4, 0x0fc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD14__LD14 IOMUX_PAD(0x2f8, 0x100, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD14__FEC_TDATA3 IOMUX_PAD(0x2f8, 0x100, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LD15__LD15 IOMUX_PAD(0x2fc, 0x104, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LD15__FEC_RX_CLK IOMUX_PAD(0x2fc, 0x104, 0x15, 0x514, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_HSYNC__HSYNC IOMUX_PAD(0x300, 0x108, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_HSYNC__GPIO_1_22 IOMUX_PAD(0x300, 0x108, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_VSYNC__VSYNC IOMUX_PAD(0x304, 0x10c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSYNC__GPIO_1_23 IOMUX_PAD(0x304, 0x10c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_LSCLK__LSCLK IOMUX_PAD(0x308, 0x110, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_LSCLK__GPIO_1_24 IOMUX_PAD(0x308, 0x110, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_OE_ACD__OE_ACD IOMUX_PAD(0x30c, 0x114, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CONTRAST__PWM4_PWMO IOMUX_PAD(0x310, 0x118, 0x14, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL)
+
+#define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_PWM__GPIO_1_26 IOMUX_PAD(0x314, 0x11c, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_PWM__USBH2_OC IOMUX_PAD(0x314, 0x11c, 0x16, 0x580, 1, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_CSI_D2__CSI_D2 IOMUX_PAD(0x318, 0x120, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D2__UART5_RXD_MUX IOMUX_PAD(0x318, 0x120, 0x11, 0x578, 1, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D2__GPIO_1_27 IOMUX_PAD(0x318, 0x120, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D3__CSI_D3 IOMUX_PAD(0x31c, 0x124, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D3__GPIO_1_28 IOMUX_PAD(0x31c, 0x124, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D4__CSI_D4 IOMUX_PAD(0x320, 0x128, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D4__UART5_RTS IOMUX_PAD(0x320, 0x128, 0x11, 0x574, 1, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D4__GPIO_1_29 IOMUX_PAD(0x320, 0x128, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D5__CSI_D5 IOMUX_PAD(0x324, 0x12c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D5__GPIO_1_30 IOMUX_PAD(0x324, 0x12c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D6__CSI_D6 IOMUX_PAD(0x328, 0x130, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D6__GPIO_1_31 IOMUX_PAD(0x328, 0x130, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D7__CSI_D7 IOMUX_PAD(0x32c, 0x134, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D7__GPIO_1_6 IOMUX_PAD(0x32c, 0x134, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D8__CSI_D8 IOMUX_PAD(0x330, 0x138, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D8__GPIO_1_7 IOMUX_PAD(0x330, 0x138, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_D9__CSI_D9 IOMUX_PAD(0x334, 0x13c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_D9__GPIO_4_21 IOMUX_PAD(0x334, 0x13c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_MCLK__CSI_MCLK IOMUX_PAD(0x338, 0x140, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_MCLK__GPIO_1_8 IOMUX_PAD(0x338, 0x140, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_VSYNC__CSI_VSYNC IOMUX_PAD(0x33c, 0x144, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_VSYNC__GPIO_1_9 IOMUX_PAD(0x33c, 0x144, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_HSYNC__CSI_HSYNC IOMUX_PAD(0x340, 0x148, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_HSYNC__GPIO_1_10 IOMUX_PAD(0x340, 0x148, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSI_PIXCLK__CSI_PIXCLK IOMUX_PAD(0x344, 0x14c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSI_PIXCLK__GPIO_1_11 IOMUX_PAD(0x344, 0x14c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x348, 0x150, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_I2C1_CLK__GPIO_1_12 IOMUX_PAD(0x348, 0x150, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x34c, 0x154, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_I2C1_DAT__GPIO_1_13 IOMUX_PAD(0x34c, 0x154, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x350, 0x158, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_MOSI__GPIO_1_14 IOMUX_PAD(0x350, 0x158, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x354, 0x15c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_MISO__GPIO_1_15 IOMUX_PAD(0x354, 0x15c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x358, 0x160, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SS0__GPIO_1_16 IOMUX_PAD(0x358, 0x160, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x35c, 0x164, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SS1__GPIO_1_17 IOMUX_PAD(0x35c, 0x164, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x360, 0x168, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CSPI1_SCLK__GPIO_1_18 IOMUX_PAD(0x360, 0x168, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CSPI1_RDY__CSPI1_RDY IOMUX_PAD(0x364, 0x16c, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_CSPI1_RDY__GPIO_2_22 IOMUX_PAD(0x364, 0x16c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x368, 0x170, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN)
+#define MX25_PAD_UART1_RXD__GPIO_4_22 IOMUX_PAD(0x368, 0x170, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x36c, 0x174, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART1_TXD__GPIO_4_23 IOMUX_PAD(0x36c, 0x174, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x370, 0x178, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_UART1_RTS__CSI_D0 IOMUX_PAD(0x370, 0x178, 0x11, 0x488, 1, NO_PAD_CTRL)
+#define MX25_PAD_UART1_RTS__GPIO_4_24 IOMUX_PAD(0x370, 0x178, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x374, 0x17c, 0x10, 0, 0, PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_UART1_CTS__CSI_D1 IOMUX_PAD(0x374, 0x17c, 0x11, 0x48c, 1, NO_PAD_CTRL)
+#define MX25_PAD_UART1_CTS__GPIO_4_25 IOMUX_PAD(0x374, 0x17c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x378, 0x180, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_RXD__GPIO_4_26 IOMUX_PAD(0x378, 0x180, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x37c, 0x184, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_TXD__GPIO_4_27 IOMUX_PAD(0x37c, 0x184, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x380, 0x188, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_RTS__FEC_COL IOMUX_PAD(0x380, 0x188, 0x12, 0x504, 2, NO_PAD_CTRL)
+#define MX25_PAD_UART2_RTS__GPIO_4_28 IOMUX_PAD(0x380, 0x188, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UART2_CTS__FEC_RX_ER IOMUX_PAD(0x384, 0x18c, 0x12, 0x518, 2, NO_PAD_CTRL)
+#define MX25_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x384, 0x18c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UART2_CTS__GPIO_4_29 IOMUX_PAD(0x384, 0x18c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x388, 0x190, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_CMD__FEC_RDATA2 IOMUX_PAD(0x388, 0x190, 0x12, 0x50c, 2, NO_PAD_CTRL)
+#define MX25_PAD_SD1_CMD__GPIO_2_23 IOMUX_PAD(0x388, 0x190, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x38c, 0x194, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_CLK__FEC_RDATA3 IOMUX_PAD(0x38c, 0x194, 0x12, 0x510, 2, NO_PAD_CTRL)
+#define MX25_PAD_SD1_CLK__GPIO_2_24 IOMUX_PAD(0x38c, 0x194, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x390, 0x198, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA0__GPIO_2_25 IOMUX_PAD(0x390, 0x198, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x394, 0x19c, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA1__AUD7_RXD IOMUX_PAD(0x394, 0x19c, 0x13, 0x478, 0, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA1__GPIO_2_26 IOMUX_PAD(0x394, 0x19c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x398, 0x1a0, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA2__FEC_RX_CLK IOMUX_PAD(0x398, 0x1a0, 0x15, 0x514, 2, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA2__GPIO_2_27 IOMUX_PAD(0x398, 0x1a0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x39c, 0x1a4, 0x10, 0, 0, PAD_CTL_PUS_47K_UP)
+#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL)
+#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define KPP_CTL_ROW (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define KPP_CTL_COL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, KPP_CTL_ROW)
+#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, KPP_CTL_ROW)
+#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, KPP_CTL_ROW)
+#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
+#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, KPP_CTL_ROW)
+#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
+#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL0__UART4_RXD_MUX IOMUX_PAD(0x3b0, 0x1b8, 0x11, 0x570, 1, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL0__AUD5_TXD IOMUX_PAD(0x3b0, 0x1b8, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL1__UART4_TXD_MUX IOMUX_PAD(0x3b4, 0x1bc, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL1__AUD5_RXD IOMUX_PAD(0x3b4, 0x1bc, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL2__UART4_RTS IOMUX_PAD(0x3b8, 0x1c0, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL2__AUD5_TXC IOMUX_PAD(0x3b8, 0x1c0, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL3__UART4_CTS IOMUX_PAD(0x3bc, 0x1c4, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL3__AUD5_TXFS IOMUX_PAD(0x3bc, 0x1c4, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_FEC_MDC__AUD4_TXD IOMUX_PAD(0x3c0, 0x1c8, 0x12, 0x464, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_MDC__GPIO_3_5 IOMUX_PAD(0x3c0, 0x1c8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x3c4, 0x1cc, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_FEC_MDIO__AUD4_RXD IOMUX_PAD(0x3c4, 0x1cc, 0x12, 0x460, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_MDIO__GPIO_3_6 IOMUX_PAD(0x3c4, 0x1cc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TDATA0__FEC_TDATA0 IOMUX_PAD(0x3c8, 0x1d0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_FEC_TDATA0__GPIO_3_7 IOMUX_PAD(0x3c8, 0x1d0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TDATA1__FEC_TDATA1 IOMUX_PAD(0x3cc, 0x1d4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_FEC_TDATA1__AUD4_TXFS IOMUX_PAD(0x3cc, 0x1d4, 0x12, 0x474, 1, NO_PAD_CTRL)
+#define MX25_PAD_FEC_TDATA1__GPIO_3_8 IOMUX_PAD(0x3cc, 0x1d4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x3d0, 0x1d8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_FEC_TX_EN__GPIO_3_9 IOMUX_PAD(0x3d0, 0x1d8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RDATA0__FEC_RDATA0 IOMUX_PAD(0x3d4, 0x1dc, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
+#define MX25_PAD_FEC_RDATA0__GPIO_3_10 IOMUX_PAD(0x3d4, 0x1dc, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RDATA1__FEC_RDATA1 IOMUX_PAD(0x3d8, 0x1e0, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
+#define MX25_PAD_FEC_RDATA1__GPIO_3_11 IOMUX_PAD(0x3d8, 0x1e0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x3dc, 0x1e4, 0x10, 0, 0, PAD_CTL_PUS_100K_DOWN | NO_PAD_CTRL)
+#define MX25_PAD_FEC_RX_DV__CAN2_RX IOMUX_PAD(0x3dc, 0x1e4, 0x14, 0x484, 0, PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_FEC_RX_DV__GPIO_3_12 IOMUX_PAD(0x3dc, 0x1e4, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x3e0, 0x1e8, 0x10, 0, 0, PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN)
+#define MX25_PAD_FEC_TX_CLK__GPIO_3_13 IOMUX_PAD(0x3e0, 0x1e8, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_RTCK__RTCK IOMUX_PAD(0x3e4, 0x1ec, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RTCK__OWIRE IOMUX_PAD(0x3e4, 0x1ec, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_RTCK__GPIO_3_14 IOMUX_PAD(0x3e4, 0x1ec, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_DE_B__DE_B IOMUX_PAD(0x3ec, 0x1f0, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_DE_B__GPIO_2_20 IOMUX_PAD(0x3ec, 0x1f0, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_TDO__TDO IOMUX_PAD(0x3e8, 0x000, 0x00, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_GPIO_A__GPIO_A IOMUX_PAD(0x3f0, 0x1f4, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_A__CAN1_TX IOMUX_PAD(0x3f0, 0x1f4, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
+#define MX25_PAD_GPIO_A__USBOTG_PWR IOMUX_PAD(0x3f0, 0x1f4, 0x12, 0, 0, PAD_CTL_PKE)
+
+#define MX25_PAD_GPIO_B__GPIO_B IOMUX_PAD(0x3f4, 0x1f8, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_B__CAN1_RX IOMUX_PAD(0x3f4, 0x1f8, 0x16, 0x480, 1, PAD_CTL_PUS_22K)
+#define MX25_PAD_GPIO_B__USBOTG_OC IOMUX_PAD(0x3f4, 0x1f8, 0x12, 0x57c, 1, PAD_CTL_PUS_100K_UP)
+
+#define MX25_PAD_GPIO_C__GPIO_C IOMUX_PAD(0x3f8, 0x1fc, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_C__CAN2_TX IOMUX_PAD(0x3f8, 0x1fc, 0x16, 0, 0, PAD_CTL_PUS_22K_UP)
+
+#define MX25_PAD_GPIO_D__GPIO_D IOMUX_PAD(0x3fc, 0x200, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__LD16 IOMUX_PAD(0x400, 0x204, 0x02, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_D__CAN2_RX IOMUX_PAD(0x3fc, 0x200, 0x16, 0x484, 1, PAD_CTL_PUS_22K_UP)
+
+#define MX25_PAD_GPIO_E__GPIO_E IOMUX_PAD(0x400, 0x204, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__LD17 IOMUX_PAD(0x404, 0x208, 0x02, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_E__AUD7_TXD IOMUX_PAD(0x400, 0x204, 0x14, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_GPIO_F__GPIO_F IOMUX_PAD(0x404, 0x208, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_GPIO_F__AUD7_TXC IOMUX_PAD(0x404, 0x208, 0x14, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_EXT_ARMCLK__EXT_ARMCLK IOMUX_PAD(0x000, 0x20c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_EXT_ARMCLK__GPIO_3_15 IOMUX_PAD(0x000, 0x20c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_UPLL_BYPCLK__UPLL_BYPCLK IOMUX_PAD(0x000, 0x210, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_UPLL_BYPCLK__GPIO_3_16 IOMUX_PAD(0x000, 0x210, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_VSTBY_REQ__VSTBY_REQ IOMUX_PAD(0x408, 0x214, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_REQ__AUD7_TXFS IOMUX_PAD(0x408, 0x214, 0x14, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_REQ__GPIO_3_17 IOMUX_PAD(0x408, 0x214, 0x15, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_ACK__VSTBY_ACK IOMUX_PAD(0x40c, 0x218, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_VSTBY_ACK__GPIO_3_18 IOMUX_PAD(0x40c, 0x218, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_POWER_FAIL__POWER_FAIL IOMUX_PAD(0x410, 0x21c, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_POWER_FAIL__AUD7_RXD IOMUX_PAD(0x410, 0x21c, 0x14, 0x478, 1, NO_PAD_CTRL)
+#define MX25_PAD_POWER_FAIL__GPIO_3_19 IOMUX_PAD(0x410, 0x21c, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CLKO__CLKO IOMUX_PAD(0x414, 0x220, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CLKO__GPIO_2_21 IOMUX_PAD(0x414, 0x220, 0x15, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_BOOT_MODE0__BOOT_MODE0 IOMUX_PAD(0x000, 0x224, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE0__GPIO_4_30 IOMUX_PAD(0x000, 0x224, 0x05, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE1__BOOT_MODE1 IOMUX_PAD(0x000, 0x228, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_BOOT_MODE1__GPIO_4_31 IOMUX_PAD(0x000, 0x228, 0x05, 0, 0, NO_PAD_CTRL)
+
+#define MX25_PAD_CTL_GRP_DVS_MISC IOMUX_PAD(0x418, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_FEC IOMUX_PAD(0x41c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_JTAG IOMUX_PAD(0x420, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_NFC IOMUX_PAD(0x424, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_CSI IOMUX_PAD(0x428, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_WEIM IOMUX_PAD(0x42c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_DDR IOMUX_PAD(0x430, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_CRM IOMUX_PAD(0x434, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_KPP IOMUX_PAD(0x438, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_SDHC1 IOMUX_PAD(0x43c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_LCD IOMUX_PAD(0x440, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_UART IOMUX_PAD(0x444, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_NFC IOMUX_PAD(0x448, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_CSI IOMUX_PAD(0x44c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DSE_CSPI1 IOMUX_PAD(0x450, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DDRTYPE IOMUX_PAD(0x454, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_SDHC1 IOMUX_PAD(0x458, 0x000, 0, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CTL_GRP_DVS_LCD IOMUX_PAD(0x45c, 0x000, 0, 0, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
new file mode 100644
index 00000000..d9f9a6e3
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx27.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_MX27_H__
+#define __MACH_IOMUX_MX27_H__
+
+#include <mach/iomux-mx2x.h>
+#include <mach/iomux-v1.h>
+
+/* Primary GPIO pin functions */
+
+#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0)
+#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1)
+#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2)
+#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3)
+#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4)
+#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22)
+#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25)
+#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5)
+#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6)
+#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7)
+#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8)
+#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9)
+#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10)
+#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11)
+#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12)
+#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13)
+#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16)
+#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17)
+#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18)
+#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19)
+#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0)
+#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1)
+#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2)
+#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3)
+#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4)
+#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5)
+#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6)
+#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7)
+#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8)
+#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9)
+#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10)
+#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11)
+#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12)
+#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13)
+#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14)
+#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15)
+#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16)
+#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0)
+#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1)
+#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2)
+#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24)
+#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25)
+#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1)
+#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3)
+#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7)
+#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8)
+#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9)
+#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10)
+#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11)
+#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12)
+#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13)
+#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14)
+#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16)
+#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17)
+#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18)
+#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19)
+#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20)
+#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23)
+
+/* Alternate GPIO pin functions */
+
+#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4)
+#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5)
+#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6)
+#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7)
+#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8)
+#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9)
+#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10)
+#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11)
+#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12)
+#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13)
+#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18)
+#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19)
+#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20)
+#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21)
+#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8)
+#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24)
+#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25)
+#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26)
+#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27)
+#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1)
+#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6)
+#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7)
+#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9)
+#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2)
+#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3)
+#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4)
+#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5)
+#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8)
+#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10)
+#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11)
+#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12)
+#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13)
+#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14)
+#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15)
+#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16)
+#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1)
+#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3)
+#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5)
+#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7)
+#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8)
+#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9)
+#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10)
+#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11)
+#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12)
+#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13)
+#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14)
+#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15)
+#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16)
+#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17)
+#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18)
+#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19)
+#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20)
+#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22)
+#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23)
+
+/* AIN GPIO pin functions */
+
+#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14)
+#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15)
+#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0)
+#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1)
+#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2)
+#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3)
+#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9)
+#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16)
+#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27)
+#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23)
+
+/* BIN GPIO pin functions */
+
+#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14)
+
+/* CIN GPIO pin functions */
+
+#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2)
+#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3)
+#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4)
+#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5)
+#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6)
+#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7)
+#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8)
+#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9)
+#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10)
+#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11)
+#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12)
+#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13)
+#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14)
+#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15)
+#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16)
+#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23)
+#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27)
+/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */
+
+/* AOUT GPIO pin functions */
+
+#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14)
+#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4)
+#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5)
+#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6)
+#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7)
+#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10)
+#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11)
+#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12)
+#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13)
+#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14)
+#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15)
+
+/* BOUT GPIO pin functions */
+
+#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17)
+#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18)
+#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19)
+#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28)
+#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29)
+#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30)
+#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31)
+
+#endif /* __MACH_IOMUX_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
new file mode 100644
index 00000000..7a9b20ab
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_MX2x_H__
+#define __MACH_IOMUX_MX2x_H__
+
+/* Primary GPIO pin functions */
+
+#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5)
+#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6)
+#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7)
+#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8)
+#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9)
+#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10)
+#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11)
+#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12)
+#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13)
+#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14)
+#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15)
+#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16)
+#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17)
+#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18)
+#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19)
+#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20)
+#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21)
+#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22)
+#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23)
+#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24)
+#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25)
+#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26)
+#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27)
+#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28)
+#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29)
+#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30)
+#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31)
+#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4)
+#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5)
+#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6)
+#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7)
+#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8)
+#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9)
+#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10)
+#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11)
+#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12)
+#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13)
+#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14)
+#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15)
+#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16)
+#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17)
+#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18)
+#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19)
+#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20)
+#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21)
+#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23)
+#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24)
+#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26)
+#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27)
+#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28)
+#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29)
+#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30)
+#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31)
+#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14)
+#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15)
+#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20)
+#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21)
+#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22)
+#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23)
+#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24)
+#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25)
+#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26)
+#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27)
+#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28)
+#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29)
+#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30)
+#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
+#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
+#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
+#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 23)
+#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
+#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
+#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
+#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
+#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28)
+#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29)
+#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30)
+#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31)
+#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3)
+#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4)
+#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5)
+#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6)
+#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7)
+#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8)
+#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9)
+#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10)
+#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11)
+#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12)
+#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13)
+#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14)
+#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15)
+#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16)
+#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17)
+#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18)
+#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19)
+#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20)
+#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21)
+#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22)
+#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23)
+#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0)
+#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2)
+#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4)
+#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5)
+#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6)
+#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15)
+#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21)
+#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22)
+
+/* Alternate GPIO pin functions */
+
+#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26)
+#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28)
+#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29)
+#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31)
+#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28)
+#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29)
+#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30)
+#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31)
+#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19)
+#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20)
+#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21)
+#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22)
+#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23)
+#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24)
+#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26)
+#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0)
+#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1)
+#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2)
+#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3)
+#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4)
+#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6)
+#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7)
+#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16)
+#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18)
+#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21)
+#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22)
+#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23)
+
+/* AIN GPIO pin functions */
+
+#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6)
+#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7)
+#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8)
+#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0)
+#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11)
+#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13)
+#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15)
+#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17)
+#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19)
+#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21)
+#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22)
+#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24)
+#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25)
+#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26)
+#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27)
+#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6)
+#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7)
+#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8)
+#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9)
+#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25)
+#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26)
+#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27)
+#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28)
+#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29)
+#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30)
+#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31)
+#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5)
+#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6)
+#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7)
+#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8)
+#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9)
+#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10)
+#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11)
+#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12)
+#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13)
+#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5)
+
+/* BIN GPIO pin functions */
+
+#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5)
+
+/* CIN GPIO pin functions */
+
+#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14)
+#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15)
+#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16)
+#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17)
+#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18)
+#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19)
+#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20)
+#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21)
+#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30)
+#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5)
+
+/* AOUT GPIO pin functions */
+
+#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29)
+#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31)
+#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8)
+#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15)
+#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21)
+
+#endif /* ifndef __MACH_IOMUX_MX2x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
new file mode 100644
index 00000000..c92f0b1f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -0,0 +1,750 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_MX3_H__
+#define __MACH_IOMUX_MX3_H__
+
+#include <linux/types.h>
+/*
+ * various IOMUX output functions
+ */
+
+#define IOMUX_OCONFIG_GPIO (0 << 4) /* used as GPIO */
+#define IOMUX_OCONFIG_FUNC (1 << 4) /* used as function */
+#define IOMUX_OCONFIG_ALT1 (2 << 4) /* used as alternate function 1 */
+#define IOMUX_OCONFIG_ALT2 (3 << 4) /* used as alternate function 2 */
+#define IOMUX_OCONFIG_ALT3 (4 << 4) /* used as alternate function 3 */
+#define IOMUX_OCONFIG_ALT4 (5 << 4) /* used as alternate function 4 */
+#define IOMUX_OCONFIG_ALT5 (6 << 4) /* used as alternate function 5 */
+#define IOMUX_OCONFIG_ALT6 (7 << 4) /* used as alternate function 6 */
+#define IOMUX_ICONFIG_NONE 0 /* not configured for input */
+#define IOMUX_ICONFIG_GPIO 1 /* used as GPIO */
+#define IOMUX_ICONFIG_FUNC 2 /* used as function */
+#define IOMUX_ICONFIG_ALT1 4 /* used as alternate function 1 */
+#define IOMUX_ICONFIG_ALT2 8 /* used as alternate function 2 */
+
+#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO)
+#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC)
+#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1)
+#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2)
+
+/*
+ * various IOMUX pad functions
+ */
+enum iomux_pad_config {
+ PAD_CTL_NOLOOPBACK = 0x0 << 9,
+ PAD_CTL_LOOPBACK = 0x1 << 9,
+ PAD_CTL_PKE_NONE = 0x0 << 8,
+ PAD_CTL_PKE_ENABLE = 0x1 << 8,
+ PAD_CTL_PUE_KEEPER = 0x0 << 7,
+ PAD_CTL_PUE_PUD = 0x1 << 7,
+ PAD_CTL_100K_PD = 0x0 << 5,
+ PAD_CTL_100K_PU = 0x1 << 5,
+ PAD_CTL_47K_PU = 0x2 << 5,
+ PAD_CTL_22K_PU = 0x3 << 5,
+ PAD_CTL_HYS_CMOS = 0x0 << 4,
+ PAD_CTL_HYS_SCHMITZ = 0x1 << 4,
+ PAD_CTL_ODE_CMOS = 0x0 << 3,
+ PAD_CTL_ODE_OpenDrain = 0x1 << 3,
+ PAD_CTL_DRV_NORMAL = 0x0 << 1,
+ PAD_CTL_DRV_HIGH = 0x1 << 1,
+ PAD_CTL_DRV_MAX = 0x2 << 1,
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0
+};
+
+/*
+ * various IOMUX general purpose functions
+ */
+enum iomux_gp_func {
+ MUX_PGP_FIRI = 1 << 0,
+ MUX_DDR_MODE = 1 << 1,
+ MUX_PGP_CSPI_BB = 1 << 2,
+ MUX_PGP_ATA_1 = 1 << 3,
+ MUX_PGP_ATA_2 = 1 << 4,
+ MUX_PGP_ATA_3 = 1 << 5,
+ MUX_PGP_ATA_4 = 1 << 6,
+ MUX_PGP_ATA_5 = 1 << 7,
+ MUX_PGP_ATA_6 = 1 << 8,
+ MUX_PGP_ATA_7 = 1 << 9,
+ MUX_PGP_ATA_8 = 1 << 10,
+ MUX_PGP_UH2 = 1 << 11,
+ MUX_SDCTL_CSD0_SEL = 1 << 12,
+ MUX_SDCTL_CSD1_SEL = 1 << 13,
+ MUX_CSPI1_UART3 = 1 << 14,
+ MUX_EXTDMAREQ2_MBX_SEL = 1 << 15,
+ MUX_TAMPER_DETECT_EN = 1 << 16,
+ MUX_PGP_USB_4WIRE = 1 << 17,
+ MUX_PGP_USB_COMMON = 1 << 18,
+ MUX_SDHC_MEMSTICK1 = 1 << 19,
+ MUX_SDHC_MEMSTICK2 = 1 << 20,
+ MUX_PGP_SPLL_BYP = 1 << 21,
+ MUX_PGP_UPLL_BYP = 1 << 22,
+ MUX_PGP_MSHC1_CLK_SEL = 1 << 23,
+ MUX_PGP_MSHC2_CLK_SEL = 1 << 24,
+ MUX_CSPI3_UART5_SEL = 1 << 25,
+ MUX_PGP_ATA_9 = 1 << 26,
+ MUX_PGP_USB_SUSPEND = 1 << 27,
+ MUX_PGP_USB_OTG_LOOPBACK = 1 << 28,
+ MUX_PGP_USB_HS1_LOOPBACK = 1 << 29,
+ MUX_PGP_USB_HS2_LOOPBACK = 1 << 30,
+ MUX_CLKO_DDR_MODE = 1 << 31,
+};
+
+/*
+ * setups a single pin:
+ * - reserves the pin so that it is not claimed by another driver
+ * - setups the iomux according to the configuration
+ * - if the pin is configured as a GPIO, we claim it through kernel gpiolib
+ */
+int mxc_iomux_alloc_pin(unsigned int pin, const char *label);
+/*
+ * setups mutliple pins
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
+ const char *label);
+
+/*
+ * releases a single pin:
+ * - make it available for a future use by another driver
+ * - frees the GPIO if the pin was configured as GPIO
+ * - DOES NOT reconfigure the IOMUX in its reset state
+ */
+void mxc_iomux_release_pin(unsigned int pin);
+/*
+ * releases multiple pins
+ * convenvient way to call the above function with tables
+ */
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count);
+
+/*
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ */
+void mxc_iomux_set_gpr(enum iomux_gp_func, bool en);
+
+/*
+ * This function only configures the iomux hardware.
+ * It is called by the setup functions and should not be called directly anymore.
+ * It is here visible for backward compatibility
+ */
+int mxc_iomux_mode(unsigned int pin_mode);
+
+#define IOMUX_PADNUM_MASK 0x1ff
+#define IOMUX_GPIONUM_SHIFT 9
+#define IOMUX_GPIONUM_MASK (0xff << IOMUX_GPIONUM_SHIFT)
+#define IOMUX_MODE_SHIFT 17
+#define IOMUX_MODE_MASK (0xff << IOMUX_MODE_SHIFT)
+
+#define IOMUX_PIN(gpionum, padnum) \
+ (((gpionum << IOMUX_GPIONUM_SHIFT) & IOMUX_GPIONUM_MASK) | \
+ (padnum & IOMUX_PADNUM_MASK))
+
+#define IOMUX_MODE(pin, mode) (pin | mode << IOMUX_MODE_SHIFT)
+
+#define IOMUX_TO_GPIO(iomux_pin) \
+ ((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT)
+#define IOMUX_TO_IRQ(iomux_pin) \
+ (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \
+ MXC_GPIO_IRQ_START)
+
+/*
+ * This enumeration is constructed based on the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
+ * value is constructed based on the rules described above.
+ */
+
+enum iomux_pins {
+ MX31_PIN_TTM_PAD = IOMUX_PIN(0xff, 0),
+ MX31_PIN_CSPI3_SPI_RDY = IOMUX_PIN(0xff, 1),
+ MX31_PIN_CSPI3_SCLK = IOMUX_PIN(0xff, 2),
+ MX31_PIN_CSPI3_MISO = IOMUX_PIN(0xff, 3),
+ MX31_PIN_CSPI3_MOSI = IOMUX_PIN(0xff, 4),
+ MX31_PIN_CLKSS = IOMUX_PIN(0xff, 5),
+ MX31_PIN_CE_CONTROL = IOMUX_PIN(0xff, 6),
+ MX31_PIN_ATA_RESET_B = IOMUX_PIN(95, 7),
+ MX31_PIN_ATA_DMACK = IOMUX_PIN(94, 8),
+ MX31_PIN_ATA_DIOW = IOMUX_PIN(93, 9),
+ MX31_PIN_ATA_DIOR = IOMUX_PIN(92, 10),
+ MX31_PIN_ATA_CS1 = IOMUX_PIN(91, 11),
+ MX31_PIN_ATA_CS0 = IOMUX_PIN(90, 12),
+ MX31_PIN_SD1_DATA3 = IOMUX_PIN(63, 13),
+ MX31_PIN_SD1_DATA2 = IOMUX_PIN(62, 14),
+ MX31_PIN_SD1_DATA1 = IOMUX_PIN(61, 15),
+ MX31_PIN_SD1_DATA0 = IOMUX_PIN(60, 16),
+ MX31_PIN_SD1_CLK = IOMUX_PIN(59, 17),
+ MX31_PIN_SD1_CMD = IOMUX_PIN(58, 18),
+ MX31_PIN_D3_SPL = IOMUX_PIN(0xff, 19),
+ MX31_PIN_D3_CLS = IOMUX_PIN(0xff, 20),
+ MX31_PIN_D3_REV = IOMUX_PIN(0xff, 21),
+ MX31_PIN_CONTRAST = IOMUX_PIN(0xff, 22),
+ MX31_PIN_VSYNC3 = IOMUX_PIN(0xff, 23),
+ MX31_PIN_READ = IOMUX_PIN(0xff, 24),
+ MX31_PIN_WRITE = IOMUX_PIN(0xff, 25),
+ MX31_PIN_PAR_RS = IOMUX_PIN(0xff, 26),
+ MX31_PIN_SER_RS = IOMUX_PIN(89, 27),
+ MX31_PIN_LCS1 = IOMUX_PIN(88, 28),
+ MX31_PIN_LCS0 = IOMUX_PIN(87, 29),
+ MX31_PIN_SD_D_CLK = IOMUX_PIN(86, 30),
+ MX31_PIN_SD_D_IO = IOMUX_PIN(85, 31),
+ MX31_PIN_SD_D_I = IOMUX_PIN(84, 32),
+ MX31_PIN_DRDY0 = IOMUX_PIN(0xff, 33),
+ MX31_PIN_FPSHIFT = IOMUX_PIN(0xff, 34),
+ MX31_PIN_HSYNC = IOMUX_PIN(0xff, 35),
+ MX31_PIN_VSYNC0 = IOMUX_PIN(0xff, 36),
+ MX31_PIN_LD17 = IOMUX_PIN(0xff, 37),
+ MX31_PIN_LD16 = IOMUX_PIN(0xff, 38),
+ MX31_PIN_LD15 = IOMUX_PIN(0xff, 39),
+ MX31_PIN_LD14 = IOMUX_PIN(0xff, 40),
+ MX31_PIN_LD13 = IOMUX_PIN(0xff, 41),
+ MX31_PIN_LD12 = IOMUX_PIN(0xff, 42),
+ MX31_PIN_LD11 = IOMUX_PIN(0xff, 43),
+ MX31_PIN_LD10 = IOMUX_PIN(0xff, 44),
+ MX31_PIN_LD9 = IOMUX_PIN(0xff, 45),
+ MX31_PIN_LD8 = IOMUX_PIN(0xff, 46),
+ MX31_PIN_LD7 = IOMUX_PIN(0xff, 47),
+ MX31_PIN_LD6 = IOMUX_PIN(0xff, 48),
+ MX31_PIN_LD5 = IOMUX_PIN(0xff, 49),
+ MX31_PIN_LD4 = IOMUX_PIN(0xff, 50),
+ MX31_PIN_LD3 = IOMUX_PIN(0xff, 51),
+ MX31_PIN_LD2 = IOMUX_PIN(0xff, 52),
+ MX31_PIN_LD1 = IOMUX_PIN(0xff, 53),
+ MX31_PIN_LD0 = IOMUX_PIN(0xff, 54),
+ MX31_PIN_USBH2_DATA1 = IOMUX_PIN(0xff, 55),
+ MX31_PIN_USBH2_DATA0 = IOMUX_PIN(0xff, 56),
+ MX31_PIN_USBH2_NXT = IOMUX_PIN(0xff, 57),
+ MX31_PIN_USBH2_STP = IOMUX_PIN(0xff, 58),
+ MX31_PIN_USBH2_DIR = IOMUX_PIN(0xff, 59),
+ MX31_PIN_USBH2_CLK = IOMUX_PIN(0xff, 60),
+ MX31_PIN_USBOTG_DATA7 = IOMUX_PIN(0xff, 61),
+ MX31_PIN_USBOTG_DATA6 = IOMUX_PIN(0xff, 62),
+ MX31_PIN_USBOTG_DATA5 = IOMUX_PIN(0xff, 63),
+ MX31_PIN_USBOTG_DATA4 = IOMUX_PIN(0xff, 64),
+ MX31_PIN_USBOTG_DATA3 = IOMUX_PIN(0xff, 65),
+ MX31_PIN_USBOTG_DATA2 = IOMUX_PIN(0xff, 66),
+ MX31_PIN_USBOTG_DATA1 = IOMUX_PIN(0xff, 67),
+ MX31_PIN_USBOTG_DATA0 = IOMUX_PIN(0xff, 68),
+ MX31_PIN_USBOTG_NXT = IOMUX_PIN(0xff, 69),
+ MX31_PIN_USBOTG_STP = IOMUX_PIN(0xff, 70),
+ MX31_PIN_USBOTG_DIR = IOMUX_PIN(0xff, 71),
+ MX31_PIN_USBOTG_CLK = IOMUX_PIN(0xff, 72),
+ MX31_PIN_USB_BYP = IOMUX_PIN(31, 73),
+ MX31_PIN_USB_OC = IOMUX_PIN(30, 74),
+ MX31_PIN_USB_PWR = IOMUX_PIN(29, 75),
+ MX31_PIN_SJC_MOD = IOMUX_PIN(0xff, 76),
+ MX31_PIN_DE_B = IOMUX_PIN(0xff, 77),
+ MX31_PIN_TRSTB = IOMUX_PIN(0xff, 78),
+ MX31_PIN_TDO = IOMUX_PIN(0xff, 79),
+ MX31_PIN_TDI = IOMUX_PIN(0xff, 80),
+ MX31_PIN_TMS = IOMUX_PIN(0xff, 81),
+ MX31_PIN_TCK = IOMUX_PIN(0xff, 82),
+ MX31_PIN_RTCK = IOMUX_PIN(0xff, 83),
+ MX31_PIN_KEY_COL7 = IOMUX_PIN(57, 84),
+ MX31_PIN_KEY_COL6 = IOMUX_PIN(56, 85),
+ MX31_PIN_KEY_COL5 = IOMUX_PIN(55, 86),
+ MX31_PIN_KEY_COL4 = IOMUX_PIN(54, 87),
+ MX31_PIN_KEY_COL3 = IOMUX_PIN(0xff, 88),
+ MX31_PIN_KEY_COL2 = IOMUX_PIN(0xff, 89),
+ MX31_PIN_KEY_COL1 = IOMUX_PIN(0xff, 90),
+ MX31_PIN_KEY_COL0 = IOMUX_PIN(0xff, 91),
+ MX31_PIN_KEY_ROW7 = IOMUX_PIN(53, 92),
+ MX31_PIN_KEY_ROW6 = IOMUX_PIN(52, 93),
+ MX31_PIN_KEY_ROW5 = IOMUX_PIN(51, 94),
+ MX31_PIN_KEY_ROW4 = IOMUX_PIN(50, 95),
+ MX31_PIN_KEY_ROW3 = IOMUX_PIN(0xff, 96),
+ MX31_PIN_KEY_ROW2 = IOMUX_PIN(0xff, 97),
+ MX31_PIN_KEY_ROW1 = IOMUX_PIN(0xff, 98),
+ MX31_PIN_KEY_ROW0 = IOMUX_PIN(0xff, 99),
+ MX31_PIN_BATT_LINE = IOMUX_PIN(49, 100),
+ MX31_PIN_CTS2 = IOMUX_PIN(0xff, 101),
+ MX31_PIN_RTS2 = IOMUX_PIN(0xff, 102),
+ MX31_PIN_TXD2 = IOMUX_PIN(28, 103),
+ MX31_PIN_RXD2 = IOMUX_PIN(27, 104),
+ MX31_PIN_DTR_DCE2 = IOMUX_PIN(48, 105),
+ MX31_PIN_DCD_DTE1 = IOMUX_PIN(47, 106),
+ MX31_PIN_RI_DTE1 = IOMUX_PIN(46, 107),
+ MX31_PIN_DSR_DTE1 = IOMUX_PIN(45, 108),
+ MX31_PIN_DTR_DTE1 = IOMUX_PIN(44, 109),
+ MX31_PIN_DCD_DCE1 = IOMUX_PIN(43, 110),
+ MX31_PIN_RI_DCE1 = IOMUX_PIN(42, 111),
+ MX31_PIN_DSR_DCE1 = IOMUX_PIN(41, 112),
+ MX31_PIN_DTR_DCE1 = IOMUX_PIN(40, 113),
+ MX31_PIN_CTS1 = IOMUX_PIN(39, 114),
+ MX31_PIN_RTS1 = IOMUX_PIN(38, 115),
+ MX31_PIN_TXD1 = IOMUX_PIN(37, 116),
+ MX31_PIN_RXD1 = IOMUX_PIN(36, 117),
+ MX31_PIN_CSPI2_SPI_RDY = IOMUX_PIN(0xff, 118),
+ MX31_PIN_CSPI2_SCLK = IOMUX_PIN(0xff, 119),
+ MX31_PIN_CSPI2_SS2 = IOMUX_PIN(0xff, 120),
+ MX31_PIN_CSPI2_SS1 = IOMUX_PIN(0xff, 121),
+ MX31_PIN_CSPI2_SS0 = IOMUX_PIN(0xff, 122),
+ MX31_PIN_CSPI2_MISO = IOMUX_PIN(0xff, 123),
+ MX31_PIN_CSPI2_MOSI = IOMUX_PIN(0xff, 124),
+ MX31_PIN_CSPI1_SPI_RDY = IOMUX_PIN(0xff, 125),
+ MX31_PIN_CSPI1_SCLK = IOMUX_PIN(0xff, 126),
+ MX31_PIN_CSPI1_SS2 = IOMUX_PIN(0xff, 127),
+ MX31_PIN_CSPI1_SS1 = IOMUX_PIN(0xff, 128),
+ MX31_PIN_CSPI1_SS0 = IOMUX_PIN(0xff, 129),
+ MX31_PIN_CSPI1_MISO = IOMUX_PIN(0xff, 130),
+ MX31_PIN_CSPI1_MOSI = IOMUX_PIN(0xff, 131),
+ MX31_PIN_SFS6 = IOMUX_PIN(26, 132),
+ MX31_PIN_SCK6 = IOMUX_PIN(25, 133),
+ MX31_PIN_SRXD6 = IOMUX_PIN(24, 134),
+ MX31_PIN_STXD6 = IOMUX_PIN(23, 135),
+ MX31_PIN_SFS5 = IOMUX_PIN(0xff, 136),
+ MX31_PIN_SCK5 = IOMUX_PIN(0xff, 137),
+ MX31_PIN_SRXD5 = IOMUX_PIN(22, 138),
+ MX31_PIN_STXD5 = IOMUX_PIN(21, 139),
+ MX31_PIN_SFS4 = IOMUX_PIN(0xff, 140),
+ MX31_PIN_SCK4 = IOMUX_PIN(0xff, 141),
+ MX31_PIN_SRXD4 = IOMUX_PIN(20, 142),
+ MX31_PIN_STXD4 = IOMUX_PIN(19, 143),
+ MX31_PIN_SFS3 = IOMUX_PIN(0xff, 144),
+ MX31_PIN_SCK3 = IOMUX_PIN(0xff, 145),
+ MX31_PIN_SRXD3 = IOMUX_PIN(18, 146),
+ MX31_PIN_STXD3 = IOMUX_PIN(17, 147),
+ MX31_PIN_I2C_DAT = IOMUX_PIN(0xff, 148),
+ MX31_PIN_I2C_CLK = IOMUX_PIN(0xff, 149),
+ MX31_PIN_CSI_PIXCLK = IOMUX_PIN(83, 150),
+ MX31_PIN_CSI_HSYNC = IOMUX_PIN(82, 151),
+ MX31_PIN_CSI_VSYNC = IOMUX_PIN(81, 152),
+ MX31_PIN_CSI_MCLK = IOMUX_PIN(80, 153),
+ MX31_PIN_CSI_D15 = IOMUX_PIN(79, 154),
+ MX31_PIN_CSI_D14 = IOMUX_PIN(78, 155),
+ MX31_PIN_CSI_D13 = IOMUX_PIN(77, 156),
+ MX31_PIN_CSI_D12 = IOMUX_PIN(76, 157),
+ MX31_PIN_CSI_D11 = IOMUX_PIN(75, 158),
+ MX31_PIN_CSI_D10 = IOMUX_PIN(74, 159),
+ MX31_PIN_CSI_D9 = IOMUX_PIN(73, 160),
+ MX31_PIN_CSI_D8 = IOMUX_PIN(72, 161),
+ MX31_PIN_CSI_D7 = IOMUX_PIN(71, 162),
+ MX31_PIN_CSI_D6 = IOMUX_PIN(70, 163),
+ MX31_PIN_CSI_D5 = IOMUX_PIN(69, 164),
+ MX31_PIN_CSI_D4 = IOMUX_PIN(68, 165),
+ MX31_PIN_M_GRANT = IOMUX_PIN(0xff, 166),
+ MX31_PIN_M_REQUEST = IOMUX_PIN(0xff, 167),
+ MX31_PIN_PC_POE = IOMUX_PIN(0xff, 168),
+ MX31_PIN_PC_RW_B = IOMUX_PIN(0xff, 169),
+ MX31_PIN_IOIS16 = IOMUX_PIN(0xff, 170),
+ MX31_PIN_PC_RST = IOMUX_PIN(0xff, 171),
+ MX31_PIN_PC_BVD2 = IOMUX_PIN(0xff, 172),
+ MX31_PIN_PC_BVD1 = IOMUX_PIN(0xff, 173),
+ MX31_PIN_PC_VS2 = IOMUX_PIN(0xff, 174),
+ MX31_PIN_PC_VS1 = IOMUX_PIN(0xff, 175),
+ MX31_PIN_PC_PWRON = IOMUX_PIN(0xff, 176),
+ MX31_PIN_PC_READY = IOMUX_PIN(0xff, 177),
+ MX31_PIN_PC_WAIT_B = IOMUX_PIN(0xff, 178),
+ MX31_PIN_PC_CD2_B = IOMUX_PIN(0xff, 179),
+ MX31_PIN_PC_CD1_B = IOMUX_PIN(0xff, 180),
+ MX31_PIN_D0 = IOMUX_PIN(0xff, 181),
+ MX31_PIN_D1 = IOMUX_PIN(0xff, 182),
+ MX31_PIN_D2 = IOMUX_PIN(0xff, 183),
+ MX31_PIN_D3 = IOMUX_PIN(0xff, 184),
+ MX31_PIN_D4 = IOMUX_PIN(0xff, 185),
+ MX31_PIN_D5 = IOMUX_PIN(0xff, 186),
+ MX31_PIN_D6 = IOMUX_PIN(0xff, 187),
+ MX31_PIN_D7 = IOMUX_PIN(0xff, 188),
+ MX31_PIN_D8 = IOMUX_PIN(0xff, 189),
+ MX31_PIN_D9 = IOMUX_PIN(0xff, 190),
+ MX31_PIN_D10 = IOMUX_PIN(0xff, 191),
+ MX31_PIN_D11 = IOMUX_PIN(0xff, 192),
+ MX31_PIN_D12 = IOMUX_PIN(0xff, 193),
+ MX31_PIN_D13 = IOMUX_PIN(0xff, 194),
+ MX31_PIN_D14 = IOMUX_PIN(0xff, 195),
+ MX31_PIN_D15 = IOMUX_PIN(0xff, 196),
+ MX31_PIN_NFRB = IOMUX_PIN(16, 197),
+ MX31_PIN_NFCE_B = IOMUX_PIN(15, 198),
+ MX31_PIN_NFWP_B = IOMUX_PIN(14, 199),
+ MX31_PIN_NFCLE = IOMUX_PIN(13, 200),
+ MX31_PIN_NFALE = IOMUX_PIN(12, 201),
+ MX31_PIN_NFRE_B = IOMUX_PIN(11, 202),
+ MX31_PIN_NFWE_B = IOMUX_PIN(10, 203),
+ MX31_PIN_SDQS3 = IOMUX_PIN(0xff, 204),
+ MX31_PIN_SDQS2 = IOMUX_PIN(0xff, 205),
+ MX31_PIN_SDQS1 = IOMUX_PIN(0xff, 206),
+ MX31_PIN_SDQS0 = IOMUX_PIN(0xff, 207),
+ MX31_PIN_SDCLK_B = IOMUX_PIN(0xff, 208),
+ MX31_PIN_SDCLK = IOMUX_PIN(0xff, 209),
+ MX31_PIN_SDCKE1 = IOMUX_PIN(0xff, 210),
+ MX31_PIN_SDCKE0 = IOMUX_PIN(0xff, 211),
+ MX31_PIN_SDWE = IOMUX_PIN(0xff, 212),
+ MX31_PIN_CAS = IOMUX_PIN(0xff, 213),
+ MX31_PIN_RAS = IOMUX_PIN(0xff, 214),
+ MX31_PIN_RW = IOMUX_PIN(0xff, 215),
+ MX31_PIN_BCLK = IOMUX_PIN(0xff, 216),
+ MX31_PIN_LBA = IOMUX_PIN(0xff, 217),
+ MX31_PIN_ECB = IOMUX_PIN(0xff, 218),
+ MX31_PIN_CS5 = IOMUX_PIN(0xff, 219),
+ MX31_PIN_CS4 = IOMUX_PIN(0xff, 220),
+ MX31_PIN_CS3 = IOMUX_PIN(0xff, 221),
+ MX31_PIN_CS2 = IOMUX_PIN(0xff, 222),
+ MX31_PIN_CS1 = IOMUX_PIN(0xff, 223),
+ MX31_PIN_CS0 = IOMUX_PIN(0xff, 224),
+ MX31_PIN_OE = IOMUX_PIN(0xff, 225),
+ MX31_PIN_EB1 = IOMUX_PIN(0xff, 226),
+ MX31_PIN_EB0 = IOMUX_PIN(0xff, 227),
+ MX31_PIN_DQM3 = IOMUX_PIN(0xff, 228),
+ MX31_PIN_DQM2 = IOMUX_PIN(0xff, 229),
+ MX31_PIN_DQM1 = IOMUX_PIN(0xff, 230),
+ MX31_PIN_DQM0 = IOMUX_PIN(0xff, 231),
+ MX31_PIN_SD31 = IOMUX_PIN(0xff, 232),
+ MX31_PIN_SD30 = IOMUX_PIN(0xff, 233),
+ MX31_PIN_SD29 = IOMUX_PIN(0xff, 234),
+ MX31_PIN_SD28 = IOMUX_PIN(0xff, 235),
+ MX31_PIN_SD27 = IOMUX_PIN(0xff, 236),
+ MX31_PIN_SD26 = IOMUX_PIN(0xff, 237),
+ MX31_PIN_SD25 = IOMUX_PIN(0xff, 238),
+ MX31_PIN_SD24 = IOMUX_PIN(0xff, 239),
+ MX31_PIN_SD23 = IOMUX_PIN(0xff, 240),
+ MX31_PIN_SD22 = IOMUX_PIN(0xff, 241),
+ MX31_PIN_SD21 = IOMUX_PIN(0xff, 242),
+ MX31_PIN_SD20 = IOMUX_PIN(0xff, 243),
+ MX31_PIN_SD19 = IOMUX_PIN(0xff, 244),
+ MX31_PIN_SD18 = IOMUX_PIN(0xff, 245),
+ MX31_PIN_SD17 = IOMUX_PIN(0xff, 246),
+ MX31_PIN_SD16 = IOMUX_PIN(0xff, 247),
+ MX31_PIN_SD15 = IOMUX_PIN(0xff, 248),
+ MX31_PIN_SD14 = IOMUX_PIN(0xff, 249),
+ MX31_PIN_SD13 = IOMUX_PIN(0xff, 250),
+ MX31_PIN_SD12 = IOMUX_PIN(0xff, 251),
+ MX31_PIN_SD11 = IOMUX_PIN(0xff, 252),
+ MX31_PIN_SD10 = IOMUX_PIN(0xff, 253),
+ MX31_PIN_SD9 = IOMUX_PIN(0xff, 254),
+ MX31_PIN_SD8 = IOMUX_PIN(0xff, 255),
+ MX31_PIN_SD7 = IOMUX_PIN(0xff, 256),
+ MX31_PIN_SD6 = IOMUX_PIN(0xff, 257),
+ MX31_PIN_SD5 = IOMUX_PIN(0xff, 258),
+ MX31_PIN_SD4 = IOMUX_PIN(0xff, 259),
+ MX31_PIN_SD3 = IOMUX_PIN(0xff, 260),
+ MX31_PIN_SD2 = IOMUX_PIN(0xff, 261),
+ MX31_PIN_SD1 = IOMUX_PIN(0xff, 262),
+ MX31_PIN_SD0 = IOMUX_PIN(0xff, 263),
+ MX31_PIN_SDBA0 = IOMUX_PIN(0xff, 264),
+ MX31_PIN_SDBA1 = IOMUX_PIN(0xff, 265),
+ MX31_PIN_A25 = IOMUX_PIN(0xff, 266),
+ MX31_PIN_A24 = IOMUX_PIN(0xff, 267),
+ MX31_PIN_A23 = IOMUX_PIN(0xff, 268),
+ MX31_PIN_A22 = IOMUX_PIN(0xff, 269),
+ MX31_PIN_A21 = IOMUX_PIN(0xff, 270),
+ MX31_PIN_A20 = IOMUX_PIN(0xff, 271),
+ MX31_PIN_A19 = IOMUX_PIN(0xff, 272),
+ MX31_PIN_A18 = IOMUX_PIN(0xff, 273),
+ MX31_PIN_A17 = IOMUX_PIN(0xff, 274),
+ MX31_PIN_A16 = IOMUX_PIN(0xff, 275),
+ MX31_PIN_A14 = IOMUX_PIN(0xff, 276),
+ MX31_PIN_A15 = IOMUX_PIN(0xff, 277),
+ MX31_PIN_A13 = IOMUX_PIN(0xff, 278),
+ MX31_PIN_A12 = IOMUX_PIN(0xff, 279),
+ MX31_PIN_A11 = IOMUX_PIN(0xff, 280),
+ MX31_PIN_MA10 = IOMUX_PIN(0xff, 281),
+ MX31_PIN_A10 = IOMUX_PIN(0xff, 282),
+ MX31_PIN_A9 = IOMUX_PIN(0xff, 283),
+ MX31_PIN_A8 = IOMUX_PIN(0xff, 284),
+ MX31_PIN_A7 = IOMUX_PIN(0xff, 285),
+ MX31_PIN_A6 = IOMUX_PIN(0xff, 286),
+ MX31_PIN_A5 = IOMUX_PIN(0xff, 287),
+ MX31_PIN_A4 = IOMUX_PIN(0xff, 288),
+ MX31_PIN_A3 = IOMUX_PIN(0xff, 289),
+ MX31_PIN_A2 = IOMUX_PIN(0xff, 290),
+ MX31_PIN_A1 = IOMUX_PIN(0xff, 291),
+ MX31_PIN_A0 = IOMUX_PIN(0xff, 292),
+ MX31_PIN_VPG1 = IOMUX_PIN(0xff, 293),
+ MX31_PIN_VPG0 = IOMUX_PIN(0xff, 294),
+ MX31_PIN_DVFS1 = IOMUX_PIN(0xff, 295),
+ MX31_PIN_DVFS0 = IOMUX_PIN(0xff, 296),
+ MX31_PIN_VSTBY = IOMUX_PIN(0xff, 297),
+ MX31_PIN_POWER_FAIL = IOMUX_PIN(0xff, 298),
+ MX31_PIN_CKIL = IOMUX_PIN(0xff, 299),
+ MX31_PIN_BOOT_MODE4 = IOMUX_PIN(0xff, 300),
+ MX31_PIN_BOOT_MODE3 = IOMUX_PIN(0xff, 301),
+ MX31_PIN_BOOT_MODE2 = IOMUX_PIN(0xff, 302),
+ MX31_PIN_BOOT_MODE1 = IOMUX_PIN(0xff, 303),
+ MX31_PIN_BOOT_MODE0 = IOMUX_PIN(0xff, 304),
+ MX31_PIN_CLKO = IOMUX_PIN(0xff, 305),
+ MX31_PIN_POR_B = IOMUX_PIN(0xff, 306),
+ MX31_PIN_RESET_IN_B = IOMUX_PIN(0xff, 307),
+ MX31_PIN_CKIH = IOMUX_PIN(0xff, 308),
+ MX31_PIN_SIMPD0 = IOMUX_PIN(35, 309),
+ MX31_PIN_SRX0 = IOMUX_PIN(34, 310),
+ MX31_PIN_STX0 = IOMUX_PIN(33, 311),
+ MX31_PIN_SVEN0 = IOMUX_PIN(32, 312),
+ MX31_PIN_SRST0 = IOMUX_PIN(67, 313),
+ MX31_PIN_SCLK0 = IOMUX_PIN(66, 314),
+ MX31_PIN_GPIO3_1 = IOMUX_PIN(65, 315),
+ MX31_PIN_GPIO3_0 = IOMUX_PIN(64, 316),
+ MX31_PIN_GPIO1_6 = IOMUX_PIN( 6, 317),
+ MX31_PIN_GPIO1_5 = IOMUX_PIN( 5, 318),
+ MX31_PIN_GPIO1_4 = IOMUX_PIN( 4, 319),
+ MX31_PIN_GPIO1_3 = IOMUX_PIN( 3, 320),
+ MX31_PIN_GPIO1_2 = IOMUX_PIN( 2, 321),
+ MX31_PIN_GPIO1_1 = IOMUX_PIN( 1, 322),
+ MX31_PIN_GPIO1_0 = IOMUX_PIN( 0, 323),
+ MX31_PIN_PWMO = IOMUX_PIN( 9, 324),
+ MX31_PIN_WATCHDOG_RST = IOMUX_PIN(0xff, 325),
+ MX31_PIN_COMPARE = IOMUX_PIN( 8, 326),
+ MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327),
+};
+
+#define PIN_MAX 327
+#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */
+
+/*
+ * Convenience values for use with mxc_iomux_mode()
+ *
+ * Format here is MX31_PIN_(pin name)__(function)
+ */
+#define MX31_PIN_CSPI3_MOSI__RXD3 IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI3_MISO__TXD3 IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI3_SCLK__RTS3 IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI3_SPI_RDY__CTS3 IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CTS1__CTS1 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RTS1__RTS1 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_TXD1__TXD1 IOMUX_MODE(MX31_PIN_TXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RXD1__RXD1 IOMUX_MODE(MX31_PIN_RXD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DCE1__DCD_DCE1 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RI_DCE1__RI_DCE1 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DSR_DCE1__DSR_DCE1 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DTR_DCE1__DTR_DCE1 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CTS2__CTS2 IOMUX_MODE(MX31_PIN_CTS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RTS2__RTS2 IOMUX_MODE(MX31_PIN_RTS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_TXD2__TXD2 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_RXD2__RXD2 IOMUX_MODE(MX31_PIN_RXD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DTE1__DCD_DTE2 IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_RI_DTE1__RI_DTE2 IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_DSR_DTE1__DSR_DTE2 IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_DTR_DTE1__DTR_DTE2 IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_OCONFIG_ALT3 | IOMUX_ICONFIG_NONE)
+#define MX31_PIN_PC_RST__CTS5 IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_PC_VS2__RTS5 IOMUX_MODE(MX31_PIN_PC_VS2, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_PC_BVD2__TXD5 IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_PC_BVD1__RXD5 IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_CSPI1_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MOSI__SCL IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI2_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_MISO__SDA IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI2_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI2_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI3_MOSI, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI3_MISO, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI3_SCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI3_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI3_SPI_RDY, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_BATT_LINE__OWIRE IOMUX_MODE(MX31_PIN_BATT_LINE, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CS4__CS4 IOMUX_MODE(MX31_PIN_CS4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_DATA3__SD1_DATA3 IOMUX_MODE(MX31_PIN_SD1_DATA3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_DATA2__SD1_DATA2 IOMUX_MODE(MX31_PIN_SD1_DATA2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_DATA1__SD1_DATA1 IOMUX_MODE(MX31_PIN_SD1_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_DATA0__SD1_DATA0 IOMUX_MODE(MX31_PIN_SD1_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_CLK__SD1_CLK IOMUX_MODE(MX31_PIN_SD1_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SD1_CMD__SD1_CMD IOMUX_MODE(MX31_PIN_SD1_CMD, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_ATA_CS0__GPIO3_26 IOMUX_MODE(MX31_PIN_ATA_CS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_CS1__GPIO3_27 IOMUX_MODE(MX31_PIN_ATA_CS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_PC_PWRON__SD2_DATA3 IOMUX_MODE(MX31_PIN_PC_PWRON, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_VS1__SD2_DATA2 IOMUX_MODE(MX31_PIN_PC_VS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_READY__SD2_DATA1 IOMUX_MODE(MX31_PIN_PC_READY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_WAIT_B__SD2_DATA0 IOMUX_MODE(MX31_PIN_PC_WAIT_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD2_B__SD2_CLK IOMUX_MODE(MX31_PIN_PC_CD2_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD1_B__SD2_CMD IOMUX_MODE(MX31_PIN_PC_CD1_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_ATA_DIOR__GPIO3_28 IOMUX_MODE(MX31_PIN_ATA_DIOR, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_DIOW__GPIO3_29 IOMUX_MODE(MX31_PIN_ATA_DIOW, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_LD0__LD0 IOMUX_MODE(MX31_PIN_LD0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD1__LD1 IOMUX_MODE(MX31_PIN_LD1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD2__LD2 IOMUX_MODE(MX31_PIN_LD2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD3__LD3 IOMUX_MODE(MX31_PIN_LD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD4__LD4 IOMUX_MODE(MX31_PIN_LD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD5__LD5 IOMUX_MODE(MX31_PIN_LD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD6__LD6 IOMUX_MODE(MX31_PIN_LD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD7__LD7 IOMUX_MODE(MX31_PIN_LD7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD8__LD8 IOMUX_MODE(MX31_PIN_LD8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD9__LD9 IOMUX_MODE(MX31_PIN_LD9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD10__LD10 IOMUX_MODE(MX31_PIN_LD10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD11__LD11 IOMUX_MODE(MX31_PIN_LD11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD12__LD12 IOMUX_MODE(MX31_PIN_LD12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD13__LD13 IOMUX_MODE(MX31_PIN_LD13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD14__LD14 IOMUX_MODE(MX31_PIN_LD14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD15__LD15 IOMUX_MODE(MX31_PIN_LD15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD16__LD16 IOMUX_MODE(MX31_PIN_LD16, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LD17__LD17 IOMUX_MODE(MX31_PIN_LD17, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_VSYNC3__VSYNC3 IOMUX_MODE(MX31_PIN_VSYNC3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_HSYNC__HSYNC IOMUX_MODE(MX31_PIN_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_FPSHIFT__FPSHIFT IOMUX_MODE(MX31_PIN_FPSHIFT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DRDY0__DRDY0 IOMUX_MODE(MX31_PIN_DRDY0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_REV__D3_REV IOMUX_MODE(MX31_PIN_D3_REV, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CONTRAST__CONTRAST IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_SPL__D3_SPL IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_D3_CLS__D3_CLS IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_LCS0__GPI03_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO1_1__GPIO IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_I2C_CLK__SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI2_SCLK__I2C3_SCL IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D7__CSI_D7 IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D8__CSI_D8 IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D9__CSI_D9 IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D10__CSI_D10 IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D11__CSI_D11 IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D12__CSI_D12 IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D13__CSI_D13 IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D14__CSI_D14 IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D15__CSI_D15 IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_HSYNC__CSI_HSYNC IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_MCLK__CSI_MCLK IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_PIXCLK__CSI_PIXCLK IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_VSYNC__CSI_VSYNC IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSI_D4__GPIO3_4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSI_D5__GPIO3_5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_USBOTG_DATA0__USBOTG_DATA0 IOMUX_MODE(MX31_PIN_USBOTG_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA1__USBOTG_DATA1 IOMUX_MODE(MX31_PIN_USBOTG_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA2__USBOTG_DATA2 IOMUX_MODE(MX31_PIN_USBOTG_DATA2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA3__USBOTG_DATA3 IOMUX_MODE(MX31_PIN_USBOTG_DATA3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA4__USBOTG_DATA4 IOMUX_MODE(MX31_PIN_USBOTG_DATA4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA5__USBOTG_DATA5 IOMUX_MODE(MX31_PIN_USBOTG_DATA5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA6__USBOTG_DATA6 IOMUX_MODE(MX31_PIN_USBOTG_DATA6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DATA7__USBOTG_DATA7 IOMUX_MODE(MX31_PIN_USBOTG_DATA7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_CLK__USBOTG_CLK IOMUX_MODE(MX31_PIN_USBOTG_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_DIR__USBOTG_DIR IOMUX_MODE(MX31_PIN_USBOTG_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_NXT__USBOTG_NXT IOMUX_MODE(MX31_PIN_USBOTG_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBOTG_STP__USBOTG_STP IOMUX_MODE(MX31_PIN_USBOTG_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSPI1_MOSI__USBH1_RXDM IOMUX_MODE(MX31_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_MISO__USBH1_RXDP IOMUX_MODE(MX31_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS0__USBH1_TXDM IOMUX_MODE(MX31_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS1__USBH1_TXDP IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SS2__USBH1_RCV IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SCLK__USBH1_OEB IOMUX_MODE(MX31_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_CSPI1_SPI_RDY__USBH1_FS IOMUX_MODE(MX31_PIN_CSPI1_SPI_RDY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_SFS6__USBH1_SUSPEND IOMUX_MODE(MX31_PIN_SFS6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_NFRE_B__GPIO1_11 IOMUX_MODE(MX31_PIN_NFRE_B, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_NFALE__GPIO1_12 IOMUX_MODE(MX31_PIN_NFALE, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_USBH2_DATA0__USBH2_DATA0 IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DATA1__USBH2_DATA1 IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD3__USBH2_DATA2 IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD3__USBH2_DATA3 IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK3__USBH2_DATA4 IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS3__USBH2_DATA5 IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD6__USBH2_DATA6 IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD6__USBH2_DATA7 IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_CLK__USBH2_CLK IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_DIR__USBH2_DIR IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_NXT__USBH2_NXT IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_USBH2_STP__USBH2_STP IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK6__GPIO1_25 IOMUX_MODE(MX31_PIN_SCK6, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_USB_OC__GPIO1_30 IOMUX_MODE(MX31_PIN_USB_OC, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_I2C_DAT__I2C1_SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_I2C_CLK__I2C1_SCL IOMUX_MODE(MX31_PIN_I2C_CLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2)
+#define MX31_PIN_ATA_CS0__GPIO3_26 IOMUX_MODE(MX31_PIN_ATA_CS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_CS1__GPIO3_27 IOMUX_MODE(MX31_PIN_ATA_CS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_PC_PWRON__SD2_DATA3 IOMUX_MODE(MX31_PIN_PC_PWRON, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_VS1__SD2_DATA2 IOMUX_MODE(MX31_PIN_PC_VS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_READY__SD2_DATA1 IOMUX_MODE(MX31_PIN_PC_READY, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_WAIT_B__SD2_DATA0 IOMUX_MODE(MX31_PIN_PC_WAIT_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD2_B__SD2_CLK IOMUX_MODE(MX31_PIN_PC_CD2_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_PC_CD1_B__SD2_CMD IOMUX_MODE(MX31_PIN_PC_CD1_B, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_ATA_DIOR__GPIO3_28 IOMUX_MODE(MX31_PIN_ATA_DIOR, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_ATA_DIOW__GPIO3_29 IOMUX_MODE(MX31_PIN_ATA_DIOW, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D7__CSI_D7 IOMUX_MODE(MX31_PIN_CSI_D7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D8__CSI_D8 IOMUX_MODE(MX31_PIN_CSI_D8, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D9__CSI_D9 IOMUX_MODE(MX31_PIN_CSI_D9, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D10__CSI_D10 IOMUX_MODE(MX31_PIN_CSI_D10, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D11__CSI_D11 IOMUX_MODE(MX31_PIN_CSI_D11, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D12__CSI_D12 IOMUX_MODE(MX31_PIN_CSI_D12, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D13__CSI_D13 IOMUX_MODE(MX31_PIN_CSI_D13, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D14__CSI_D14 IOMUX_MODE(MX31_PIN_CSI_D14, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_D15__CSI_D15 IOMUX_MODE(MX31_PIN_CSI_D15, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_HSYNC__CSI_HSYNC IOMUX_MODE(MX31_PIN_CSI_HSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_MCLK__CSI_MCLK IOMUX_MODE(MX31_PIN_CSI_MCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_PIXCLK__CSI_PIXCLK IOMUX_MODE(MX31_PIN_CSI_PIXCLK, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_CSI_VSYNC__CSI_VSYNC IOMUX_MODE(MX31_PIN_CSI_VSYNC, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_GPIO3_0__GPIO3_0 IOMUX_MODE(MX31_PIN_GPIO3_0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO3_1__GPIO3_1 IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_TXD2__GPIO1_28 IOMUX_MODE(MX31_PIN_TXD2, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO1_0__GPIO1_0 IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SVEN0__GPIO2_0 IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STX0__GPIO2_1 IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRX0__GPIO2_2 IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SIMPD0__GPIO2_3 IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DTR_DCE1__GPIO2_8 IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DSR_DCE1__GPIO2_9 IOMUX_MODE(MX31_PIN_DSR_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_RI_DCE1__GPIO2_10 IOMUX_MODE(MX31_PIN_RI_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_DCD_DCE1__GPIO2_11 IOMUX_MODE(MX31_PIN_DCD_DCE1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD5__GPIO1_21 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_SRXD5__GPIO1_22 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_GPIO1_3__GPIO1_3 IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CSPI2_SS1__CSPI3_SS1 IOMUX_MODE(MX31_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT1)
+#define MX31_PIN_RTS1__GPIO2_6 IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_CTS1__GPIO2_7 IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_LCS0__GPIO3_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO)
+#define MX31_PIN_STXD4__STXD4 IOMUX_MODE(MX31_PIN_STXD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD4__SRXD4 IOMUX_MODE(MX31_PIN_SRXD4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK4__SCK4 IOMUX_MODE(MX31_PIN_SCK4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS4__SFS4 IOMUX_MODE(MX31_PIN_SFS4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_STXD5__STXD5 IOMUX_MODE(MX31_PIN_STXD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SRXD5__SRXD5 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SCK5__SCK5 IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_SFS5__SFS5 IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW0_KEY_ROW0 IOMUX_MODE(MX31_PIN_KEY_ROW0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW1_KEY_ROW1 IOMUX_MODE(MX31_PIN_KEY_ROW1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW2_KEY_ROW2 IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW3_KEY_ROW3 IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW4_KEY_ROW4 IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW5_KEY_ROW5 IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW6_KEY_ROW6 IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW7_KEY_ROW7 IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL0_KEY_COL0 IOMUX_MODE(MX31_PIN_KEY_COL0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL1_KEY_COL1 IOMUX_MODE(MX31_PIN_KEY_COL1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL2_KEY_COL2 IOMUX_MODE(MX31_PIN_KEY_COL2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL3_KEY_COL3 IOMUX_MODE(MX31_PIN_KEY_COL3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL4_KEY_COL4 IOMUX_MODE(MX31_PIN_KEY_COL4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL5_KEY_COL5 IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL6_KEY_COL6 IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL7_KEY_COL7 IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_FUNC)
+
+
+/*
+ * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0,
+ * cspi2_ss1, cspi1_ss0 cspi1_ss1
+ */
+
+/*
+ * This function configures the pad value for a IOMUX pin.
+ */
+void mxc_iomux_set_pad(enum iomux_pins, u32);
+
+#endif /* ifndef __MACH_IOMUX_MX3_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx35.h b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
new file mode 100644
index 00000000..3117c18b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx35.h
@@ -0,0 +1,1267 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option, NO_PAD_CTRL) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IOMUX_MX35_H__
+#define __MACH_IOMUX_MX35_H__
+
+#include <mach/iomux-v3.h>
+
+/*
+ * The naming convention for the pad modes is MX35_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named
+ * GPIO_<unit>_<num> see also iomux-v3.h
+ */
+
+/* PAD MUX ALT INPSE PATH */
+#define MX35_PAD_CAPTURE__GPT_CAPIN1 IOMUX_PAD(0x328, 0x004, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CAPTURE__GPT_CMPOUT2 IOMUX_PAD(0x328, 0x004, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CAPTURE__CSPI2_SS1 IOMUX_PAD(0x328, 0x004, 2, 0x7f4, 0, NO_PAD_CTRL)
+#define MX35_PAD_CAPTURE__EPIT1_EPITO IOMUX_PAD(0x328, 0x004, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CAPTURE__CCM_CLK32K IOMUX_PAD(0x328, 0x004, 4, 0x7d0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CAPTURE__GPIO1_4 IOMUX_PAD(0x328, 0x004, 5, 0x850, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_COMPARE__GPT_CMPOUT1 IOMUX_PAD(0x32c, 0x008, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_COMPARE__GPT_CAPIN2 IOMUX_PAD(0x32c, 0x008, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_COMPARE__GPT_CMPOUT3 IOMUX_PAD(0x32c, 0x008, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_COMPARE__EPIT2_EPITO IOMUX_PAD(0x32c, 0x008, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_COMPARE__GPIO1_5 IOMUX_PAD(0x32c, 0x008, 5, 0x854, 0, NO_PAD_CTRL)
+#define MX35_PAD_COMPARE__SDMA_EXTDMA_2 IOMUX_PAD(0x32c, 0x008, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_WDOG_RST__WDOG_WDOG_B IOMUX_PAD(0x330, 0x00c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_WDOG_RST__IPU_FLASH_STROBE IOMUX_PAD(0x330, 0x00c, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_WDOG_RST__GPIO1_6 IOMUX_PAD(0x330, 0x00c, 5, 0x858, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x334, 0x010, 0, 0x82c, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_0__CCM_PMIC_RDY IOMUX_PAD(0x334, 0x010, 1, 0x7d4, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_0__OWIRE_LINE IOMUX_PAD(0x334, 0x010, 2, 0x990, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_0__SDMA_EXTDMA_0 IOMUX_PAD(0x334, 0x010, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x338, 0x014, 0, 0x838, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_1__PWM_PWMO IOMUX_PAD(0x338, 0x014, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_1__CSPI1_SS2 IOMUX_PAD(0x338, 0x014, 3, 0x7d8, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_1__SCC_TAMPER_DETECT IOMUX_PAD(0x338, 0x014, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO1_1__SDMA_EXTDMA_1 IOMUX_PAD(0x338, 0x014, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_GPIO2_0__GPIO2_0 IOMUX_PAD(0x33c, 0x018, 0, 0x868, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO2_0__USB_TOP_USBOTG_CLK IOMUX_PAD(0x33c, 0x018, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_GPIO3_0__GPIO3_0 IOMUX_PAD(0x340, 0x01c, 0, 0x8e8, 0, NO_PAD_CTRL)
+#define MX35_PAD_GPIO3_0__USB_TOP_USBH2_CLK IOMUX_PAD(0x340, 0x01c, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RESET_IN_B__CCM_RESET_IN_B IOMUX_PAD(0x344, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_POR_B__CCM_POR_B IOMUX_PAD(0x348, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CLKO__CCM_CLKO IOMUX_PAD(0x34c, 0x020, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CLKO__GPIO1_8 IOMUX_PAD(0x34c, 0x020, 5, 0x860, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_BOOT_MODE0__CCM_BOOT_MODE_0 IOMUX_PAD(0x350, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_BOOT_MODE1__CCM_BOOT_MODE_1 IOMUX_PAD(0x354, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CLK_MODE0__CCM_CLK_MODE_0 IOMUX_PAD(0x358, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CLK_MODE1__CCM_CLK_MODE_1 IOMUX_PAD(0x35c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_POWER_FAIL__CCM_DSM_WAKEUP_INT_26 IOMUX_PAD(0x360, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_VSTBY__CCM_VSTBY IOMUX_PAD(0x364, 0x024, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_VSTBY__GPIO1_7 IOMUX_PAD(0x364, 0x024, 5, 0x85c, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A0__EMI_EIM_DA_L_0 IOMUX_PAD(0x368, 0x028, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A1__EMI_EIM_DA_L_1 IOMUX_PAD(0x36c, 0x02c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A2__EMI_EIM_DA_L_2 IOMUX_PAD(0x370, 0x030, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A3__EMI_EIM_DA_L_3 IOMUX_PAD(0x374, 0x034, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A4__EMI_EIM_DA_L_4 IOMUX_PAD(0x378, 0x038, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A5__EMI_EIM_DA_L_5 IOMUX_PAD(0x37c, 0x03c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A6__EMI_EIM_DA_L_6 IOMUX_PAD(0x380, 0x040, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A7__EMI_EIM_DA_L_7 IOMUX_PAD(0x384, 0x044, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A8__EMI_EIM_DA_H_8 IOMUX_PAD(0x388, 0x048, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A9__EMI_EIM_DA_H_9 IOMUX_PAD(0x38c, 0x04c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A10__EMI_EIM_DA_H_10 IOMUX_PAD(0x390, 0x050, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_MA10__EMI_MA10 IOMUX_PAD(0x394, 0x054, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A11__EMI_EIM_DA_H_11 IOMUX_PAD(0x398, 0x058, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A12__EMI_EIM_DA_H_12 IOMUX_PAD(0x39c, 0x05c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A13__EMI_EIM_DA_H_13 IOMUX_PAD(0x3a0, 0x060, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A14__EMI_EIM_DA_H2_14 IOMUX_PAD(0x3a4, 0x064, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A15__EMI_EIM_DA_H2_15 IOMUX_PAD(0x3a8, 0x068, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A16__EMI_EIM_A_16 IOMUX_PAD(0x3ac, 0x06c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A17__EMI_EIM_A_17 IOMUX_PAD(0x3b0, 0x070, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A18__EMI_EIM_A_18 IOMUX_PAD(0x3b4, 0x074, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A19__EMI_EIM_A_19 IOMUX_PAD(0x3b8, 0x078, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A20__EMI_EIM_A_20 IOMUX_PAD(0x3bc, 0x07c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A21__EMI_EIM_A_21 IOMUX_PAD(0x3c0, 0x080, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A22__EMI_EIM_A_22 IOMUX_PAD(0x3c4, 0x084, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A23__EMI_EIM_A_23 IOMUX_PAD(0x3c8, 0x088, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A24__EMI_EIM_A_24 IOMUX_PAD(0x3cc, 0x08c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_A25__EMI_EIM_A_25 IOMUX_PAD(0x3d0, 0x090, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDBA1__EMI_EIM_SDBA1 IOMUX_PAD(0x3d4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDBA0__EMI_EIM_SDBA0 IOMUX_PAD(0x3d8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD0__EMI_DRAM_D_0 IOMUX_PAD(0x3dc, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1__EMI_DRAM_D_1 IOMUX_PAD(0x3e0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2__EMI_DRAM_D_2 IOMUX_PAD(0x3e4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD3__EMI_DRAM_D_3 IOMUX_PAD(0x3e8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD4__EMI_DRAM_D_4 IOMUX_PAD(0x3ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD5__EMI_DRAM_D_5 IOMUX_PAD(0x3f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD6__EMI_DRAM_D_6 IOMUX_PAD(0x3f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD7__EMI_DRAM_D_7 IOMUX_PAD(0x3f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD8__EMI_DRAM_D_8 IOMUX_PAD(0x3fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD9__EMI_DRAM_D_9 IOMUX_PAD(0x400, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD10__EMI_DRAM_D_10 IOMUX_PAD(0x404, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD11__EMI_DRAM_D_11 IOMUX_PAD(0x408, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD12__EMI_DRAM_D_12 IOMUX_PAD(0x40c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD13__EMI_DRAM_D_13 IOMUX_PAD(0x410, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD14__EMI_DRAM_D_14 IOMUX_PAD(0x414, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD15__EMI_DRAM_D_15 IOMUX_PAD(0x418, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD16__EMI_DRAM_D_16 IOMUX_PAD(0x41c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD17__EMI_DRAM_D_17 IOMUX_PAD(0x420, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD18__EMI_DRAM_D_18 IOMUX_PAD(0x424, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD19__EMI_DRAM_D_19 IOMUX_PAD(0x428, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD20__EMI_DRAM_D_20 IOMUX_PAD(0x42c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD21__EMI_DRAM_D_21 IOMUX_PAD(0x430, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD22__EMI_DRAM_D_22 IOMUX_PAD(0x434, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD23__EMI_DRAM_D_23 IOMUX_PAD(0x438, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD24__EMI_DRAM_D_24 IOMUX_PAD(0x43c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD25__EMI_DRAM_D_25 IOMUX_PAD(0x440, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD26__EMI_DRAM_D_26 IOMUX_PAD(0x444, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD27__EMI_DRAM_D_27 IOMUX_PAD(0x448, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD28__EMI_DRAM_D_28 IOMUX_PAD(0x44c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD29__EMI_DRAM_D_29 IOMUX_PAD(0x450, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD30__EMI_DRAM_D_30 IOMUX_PAD(0x454, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD31__EMI_DRAM_D_31 IOMUX_PAD(0x458, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_DQM0__EMI_DRAM_DQM_0 IOMUX_PAD(0x45c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_DQM1__EMI_DRAM_DQM_1 IOMUX_PAD(0x460, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_DQM2__EMI_DRAM_DQM_2 IOMUX_PAD(0x464, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_DQM3__EMI_DRAM_DQM_3 IOMUX_PAD(0x468, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_EB0__EMI_EIM_EB0_B IOMUX_PAD(0x46c, 0x094, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_EB1__EMI_EIM_EB1_B IOMUX_PAD(0x470, 0x098, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_OE__EMI_EIM_OE IOMUX_PAD(0x474, 0x09c, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS0__EMI_EIM_CS0 IOMUX_PAD(0x478, 0x0a0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS1__EMI_EIM_CS1 IOMUX_PAD(0x47c, 0x0a4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS1__EMI_NANDF_CE3 IOMUX_PAD(0x47c, 0x0a4, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS2__EMI_EIM_CS2 IOMUX_PAD(0x480, 0x0a8, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS3__EMI_EIM_CS3 IOMUX_PAD(0x484, 0x0ac, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS4__EMI_EIM_CS4 IOMUX_PAD(0x488, 0x0b0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS4__EMI_DTACK_B IOMUX_PAD(0x488, 0x0b0, 1, 0x800, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS4__EMI_NANDF_CE1 IOMUX_PAD(0x488, 0x0b0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS4__GPIO1_20 IOMUX_PAD(0x488, 0x0b0, 5, 0x83c, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CS5__EMI_EIM_CS5 IOMUX_PAD(0x48c, 0x0b4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS5__CSPI2_SS2 IOMUX_PAD(0x48c, 0x0b4, 1, 0x7f8, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS5__CSPI1_SS2 IOMUX_PAD(0x48c, 0x0b4, 2, 0x7d8, 1, NO_PAD_CTRL)
+#define MX35_PAD_CS5__EMI_NANDF_CE2 IOMUX_PAD(0x48c, 0x0b4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CS5__GPIO1_21 IOMUX_PAD(0x48c, 0x0b4, 5, 0x840, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NF_CE0__EMI_NANDF_CE0 IOMUX_PAD(0x490, 0x0b8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NF_CE0__GPIO1_22 IOMUX_PAD(0x490, 0x0b8, 5, 0x844, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ECB__EMI_EIM_ECB IOMUX_PAD(0x494, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LBA__EMI_EIM_LBA IOMUX_PAD(0x498, 0x0bc, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_BCLK__EMI_EIM_BCLK IOMUX_PAD(0x49c, 0x0c0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RW__EMI_EIM_RW IOMUX_PAD(0x4a0, 0x0c4, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RAS__EMI_DRAM_RAS IOMUX_PAD(0x4a4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CAS__EMI_DRAM_CAS IOMUX_PAD(0x4a8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDWE__EMI_DRAM_SDWE IOMUX_PAD(0x4ac, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDCKE0__EMI_DRAM_SDCKE_0 IOMUX_PAD(0x4b0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDCKE1__EMI_DRAM_SDCKE_1 IOMUX_PAD(0x4b4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDCLK__EMI_DRAM_SDCLK IOMUX_PAD(0x4b8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDQS0__EMI_DRAM_SDQS_0 IOMUX_PAD(0x4bc, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDQS1__EMI_DRAM_SDQS_1 IOMUX_PAD(0x4c0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDQS2__EMI_DRAM_SDQS_2 IOMUX_PAD(0x4c4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SDQS3__EMI_DRAM_SDQS_3 IOMUX_PAD(0x4c8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFWE_B__EMI_NANDF_WE_B IOMUX_PAD(0x4cc, 0x0c8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWE_B__USB_TOP_USBH2_DATA_3 IOMUX_PAD(0x4cc, 0x0c8, 1, 0x9d8, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWE_B__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x4cc, 0x0c8, 2, 0x924, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWE_B__GPIO2_18 IOMUX_PAD(0x4cc, 0x0c8, 5, 0x88c, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWE_B__ARM11P_TOP_TRACE_0 IOMUX_PAD(0x4cc, 0x0c8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFRE_B__EMI_NANDF_RE_B IOMUX_PAD(0x4d0, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRE_B__USB_TOP_USBH2_DIR IOMUX_PAD(0x4d0, 0x0cc, 1, 0x9ec, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRE_B__IPU_DISPB_BCLK IOMUX_PAD(0x4d0, 0x0cc, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRE_B__GPIO2_19 IOMUX_PAD(0x4d0, 0x0cc, 5, 0x890, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRE_B__ARM11P_TOP_TRACE_1 IOMUX_PAD(0x4d0, 0x0cc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFALE__EMI_NANDF_ALE IOMUX_PAD(0x4d4, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFALE__USB_TOP_USBH2_STP IOMUX_PAD(0x4d4, 0x0d0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFALE__IPU_DISPB_CS0 IOMUX_PAD(0x4d4, 0x0d0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFALE__GPIO2_20 IOMUX_PAD(0x4d4, 0x0d0, 5, 0x898, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFALE__ARM11P_TOP_TRACE_2 IOMUX_PAD(0x4d4, 0x0d0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFCLE__EMI_NANDF_CLE IOMUX_PAD(0x4d8, 0x0d4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFCLE__USB_TOP_USBH2_NXT IOMUX_PAD(0x4d8, 0x0d4, 1, 0x9f0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFCLE__IPU_DISPB_PAR_RS IOMUX_PAD(0x4d8, 0x0d4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFCLE__GPIO2_21 IOMUX_PAD(0x4d8, 0x0d4, 5, 0x89c, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFCLE__ARM11P_TOP_TRACE_3 IOMUX_PAD(0x4d8, 0x0d4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFWP_B__EMI_NANDF_WP_B IOMUX_PAD(0x4dc, 0x0d8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWP_B__USB_TOP_USBH2_DATA_7 IOMUX_PAD(0x4dc, 0x0d8, 1, 0x9e8, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWP_B__IPU_DISPB_WR IOMUX_PAD(0x4dc, 0x0d8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWP_B__GPIO2_22 IOMUX_PAD(0x4dc, 0x0d8, 5, 0x8a0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFWP_B__ARM11P_TOP_TRCTL IOMUX_PAD(0x4dc, 0x0d8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_NFRB__EMI_NANDF_RB IOMUX_PAD(0x4e0, 0x0dc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRB__IPU_DISPB_RD IOMUX_PAD(0x4e0, 0x0dc, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRB__GPIO2_23 IOMUX_PAD(0x4e0, 0x0dc, 5, 0x8a4, 0, NO_PAD_CTRL)
+#define MX35_PAD_NFRB__ARM11P_TOP_TRCLK IOMUX_PAD(0x4e0, 0x0dc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D15__EMI_EIM_D_15 IOMUX_PAD(0x4e4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D14__EMI_EIM_D_14 IOMUX_PAD(0x4e8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D13__EMI_EIM_D_13 IOMUX_PAD(0x4ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D12__EMI_EIM_D_12 IOMUX_PAD(0x4f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D11__EMI_EIM_D_11 IOMUX_PAD(0x4f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D10__EMI_EIM_D_10 IOMUX_PAD(0x4f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D9__EMI_EIM_D_9 IOMUX_PAD(0x4fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D8__EMI_EIM_D_8 IOMUX_PAD(0x500, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D7__EMI_EIM_D_7 IOMUX_PAD(0x504, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D6__EMI_EIM_D_6 IOMUX_PAD(0x508, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D5__EMI_EIM_D_5 IOMUX_PAD(0x50c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D4__EMI_EIM_D_4 IOMUX_PAD(0x510, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3__EMI_EIM_D_3 IOMUX_PAD(0x514, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D2__EMI_EIM_D_2 IOMUX_PAD(0x518, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D1__EMI_EIM_D_1 IOMUX_PAD(0x51c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D0__EMI_EIM_D_0 IOMUX_PAD(0x520, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D8__IPU_CSI_D_8 IOMUX_PAD(0x524, 0x0e0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D8__KPP_COL_0 IOMUX_PAD(0x524, 0x0e0, 1, 0x950, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D8__GPIO1_20 IOMUX_PAD(0x524, 0x0e0, 5, 0x83c, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D8__ARM11P_TOP_EVNTBUS_13 IOMUX_PAD(0x524, 0x0e0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D9__IPU_CSI_D_9 IOMUX_PAD(0x528, 0x0e4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D9__KPP_COL_1 IOMUX_PAD(0x528, 0x0e4, 1, 0x954, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D9__GPIO1_21 IOMUX_PAD(0x528, 0x0e4, 5, 0x840, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D9__ARM11P_TOP_EVNTBUS_14 IOMUX_PAD(0x528, 0x0e4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D10__IPU_CSI_D_10 IOMUX_PAD(0x52c, 0x0e8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D10__KPP_COL_2 IOMUX_PAD(0x52c, 0x0e8, 1, 0x958, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D10__GPIO1_22 IOMUX_PAD(0x52c, 0x0e8, 5, 0x844, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D10__ARM11P_TOP_EVNTBUS_15 IOMUX_PAD(0x52c, 0x0e8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D11__IPU_CSI_D_11 IOMUX_PAD(0x530, 0x0ec, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D11__KPP_COL_3 IOMUX_PAD(0x530, 0x0ec, 1, 0x95c, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D11__GPIO1_23 IOMUX_PAD(0x530, 0x0ec, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D12__IPU_CSI_D_12 IOMUX_PAD(0x534, 0x0f0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D12__KPP_ROW_0 IOMUX_PAD(0x534, 0x0f0, 1, 0x970, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D12__GPIO1_24 IOMUX_PAD(0x534, 0x0f0, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D13__IPU_CSI_D_13 IOMUX_PAD(0x538, 0x0f4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D13__KPP_ROW_1 IOMUX_PAD(0x538, 0x0f4, 1, 0x974, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D13__GPIO1_25 IOMUX_PAD(0x538, 0x0f4, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D14__IPU_CSI_D_14 IOMUX_PAD(0x53c, 0x0f8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D14__KPP_ROW_2 IOMUX_PAD(0x53c, 0x0f8, 1, 0x978, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D14__GPIO1_26 IOMUX_PAD(0x53c, 0x0f8, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_D15__IPU_CSI_D_15 IOMUX_PAD(0x540, 0x0fc, 0, 0x97c, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D15__KPP_ROW_3 IOMUX_PAD(0x540, 0x0fc, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_D15__GPIO1_27 IOMUX_PAD(0x540, 0x0fc, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_MCLK__IPU_CSI_MCLK IOMUX_PAD(0x544, 0x100, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_MCLK__GPIO1_28 IOMUX_PAD(0x544, 0x100, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_VSYNC__IPU_CSI_VSYNC IOMUX_PAD(0x548, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_VSYNC__GPIO1_29 IOMUX_PAD(0x548, 0x104, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_HSYNC__IPU_CSI_HSYNC IOMUX_PAD(0x54c, 0x108, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_HSYNC__GPIO1_30 IOMUX_PAD(0x54c, 0x108, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSI_PIXCLK__IPU_CSI_PIXCLK IOMUX_PAD(0x550, 0x10c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSI_PIXCLK__GPIO1_31 IOMUX_PAD(0x550, 0x10c, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_I2C1_CLK__I2C1_SCL IOMUX_PAD(0x554, 0x110, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C1_CLK__GPIO2_24 IOMUX_PAD(0x554, 0x110, 5, 0x8a8, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C1_CLK__CCM_USB_BYP_CLK IOMUX_PAD(0x554, 0x110, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_I2C1_DAT__I2C1_SDA IOMUX_PAD(0x558, 0x114, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C1_DAT__GPIO2_25 IOMUX_PAD(0x558, 0x114, 5, 0x8ac, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_I2C2_CLK__I2C2_SCL IOMUX_PAD(0x55c, 0x118, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_CLK__CAN1_TXCAN IOMUX_PAD(0x55c, 0x118, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR IOMUX_PAD(0x55c, 0x118, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_CLK__GPIO2_26 IOMUX_PAD(0x55c, 0x118, 5, 0x8b0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_CLK__SDMA_DEBUG_BUS_DEVICE_2 IOMUX_PAD(0x55c, 0x118, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_I2C2_DAT__I2C2_SDA IOMUX_PAD(0x560, 0x11c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_DAT__CAN1_RXCAN IOMUX_PAD(0x560, 0x11c, 1, 0x7c8, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC IOMUX_PAD(0x560, 0x11c, 2, 0x9f4, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_DAT__GPIO2_27 IOMUX_PAD(0x560, 0x11c, 5, 0x8b4, 0, NO_PAD_CTRL)
+#define MX35_PAD_I2C2_DAT__SDMA_DEBUG_BUS_DEVICE_3 IOMUX_PAD(0x560, 0x11c, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_STXD4__AUDMUX_AUD4_TXD IOMUX_PAD(0x564, 0x120, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXD4__GPIO2_28 IOMUX_PAD(0x564, 0x120, 5, 0x8b8, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXD4__ARM11P_TOP_ARM_COREASID0 IOMUX_PAD(0x564, 0x120, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SRXD4__AUDMUX_AUD4_RXD IOMUX_PAD(0x568, 0x124, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SRXD4__GPIO2_29 IOMUX_PAD(0x568, 0x124, 5, 0x8bc, 0, NO_PAD_CTRL)
+#define MX35_PAD_SRXD4__ARM11P_TOP_ARM_COREASID1 IOMUX_PAD(0x568, 0x124, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SCK4__AUDMUX_AUD4_TXC IOMUX_PAD(0x56c, 0x128, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK4__GPIO2_30 IOMUX_PAD(0x56c, 0x128, 5, 0x8c4, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK4__ARM11P_TOP_ARM_COREASID2 IOMUX_PAD(0x56c, 0x128, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS IOMUX_PAD(0x570, 0x12c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXFS4__GPIO2_31 IOMUX_PAD(0x570, 0x12c, 5, 0x8c8, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXFS4__ARM11P_TOP_ARM_COREASID3 IOMUX_PAD(0x570, 0x12c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_STXD5__AUDMUX_AUD5_TXD IOMUX_PAD(0x574, 0x130, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXD5__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x574, 0x130, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXD5__CSPI2_MOSI IOMUX_PAD(0x574, 0x130, 2, 0x7ec, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXD5__GPIO1_0 IOMUX_PAD(0x574, 0x130, 5, 0x82c, 1, NO_PAD_CTRL)
+#define MX35_PAD_STXD5__ARM11P_TOP_ARM_COREASID4 IOMUX_PAD(0x574, 0x130, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SRXD5__AUDMUX_AUD5_RXD IOMUX_PAD(0x578, 0x134, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SRXD5__SPDIF_SPDIF_IN1 IOMUX_PAD(0x578, 0x134, 1, 0x998, 0, NO_PAD_CTRL)
+#define MX35_PAD_SRXD5__CSPI2_MISO IOMUX_PAD(0x578, 0x134, 2, 0x7e8, 0, NO_PAD_CTRL)
+#define MX35_PAD_SRXD5__GPIO1_1 IOMUX_PAD(0x578, 0x134, 5, 0x838, 1, NO_PAD_CTRL)
+#define MX35_PAD_SRXD5__ARM11P_TOP_ARM_COREASID5 IOMUX_PAD(0x578, 0x134, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SCK5__AUDMUX_AUD5_TXC IOMUX_PAD(0x57c, 0x138, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK5__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x57c, 0x138, 1, 0x994, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK5__CSPI2_SCLK IOMUX_PAD(0x57c, 0x138, 2, 0x7e0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK5__GPIO1_2 IOMUX_PAD(0x57c, 0x138, 5, 0x848, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCK5__ARM11P_TOP_ARM_COREASID6 IOMUX_PAD(0x57c, 0x138, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_STXFS5__AUDMUX_AUD5_TXFS IOMUX_PAD(0x580, 0x13c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXFS5__CSPI2_RDY IOMUX_PAD(0x580, 0x13c, 2, 0x7e4, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXFS5__GPIO1_3 IOMUX_PAD(0x580, 0x13c, 5, 0x84c, 0, NO_PAD_CTRL)
+#define MX35_PAD_STXFS5__ARM11P_TOP_ARM_COREASID7 IOMUX_PAD(0x580, 0x13c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SCKR__ESAI_SCKR IOMUX_PAD(0x584, 0x140, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCKR__GPIO1_4 IOMUX_PAD(0x584, 0x140, 5, 0x850, 1, NO_PAD_CTRL)
+#define MX35_PAD_SCKR__ARM11P_TOP_EVNTBUS_10 IOMUX_PAD(0x584, 0x140, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FSR__ESAI_FSR IOMUX_PAD(0x588, 0x144, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FSR__GPIO1_5 IOMUX_PAD(0x588, 0x144, 5, 0x854, 1, NO_PAD_CTRL)
+#define MX35_PAD_FSR__ARM11P_TOP_EVNTBUS_11 IOMUX_PAD(0x588, 0x144, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_HCKR__ESAI_HCKR IOMUX_PAD(0x58c, 0x148, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKR__AUDMUX_AUD5_RXFS IOMUX_PAD(0x58c, 0x148, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKR__CSPI2_SS0 IOMUX_PAD(0x58c, 0x148, 2, 0x7f0, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKR__IPU_FLASH_STROBE IOMUX_PAD(0x58c, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKR__GPIO1_6 IOMUX_PAD(0x58c, 0x148, 5, 0x858, 1, NO_PAD_CTRL)
+#define MX35_PAD_HCKR__ARM11P_TOP_EVNTBUS_12 IOMUX_PAD(0x58c, 0x148, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SCKT__ESAI_SCKT IOMUX_PAD(0x590, 0x14c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCKT__GPIO1_7 IOMUX_PAD(0x590, 0x14c, 5, 0x85c, 1, NO_PAD_CTRL)
+#define MX35_PAD_SCKT__IPU_CSI_D_0 IOMUX_PAD(0x590, 0x14c, 6, 0x930, 0, NO_PAD_CTRL)
+#define MX35_PAD_SCKT__KPP_ROW_2 IOMUX_PAD(0x590, 0x14c, 7, 0x978, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_FST__ESAI_FST IOMUX_PAD(0x594, 0x150, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FST__GPIO1_8 IOMUX_PAD(0x594, 0x150, 5, 0x860, 1, NO_PAD_CTRL)
+#define MX35_PAD_FST__IPU_CSI_D_1 IOMUX_PAD(0x594, 0x150, 6, 0x934, 0, NO_PAD_CTRL)
+#define MX35_PAD_FST__KPP_ROW_3 IOMUX_PAD(0x594, 0x150, 7, 0x97c, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_HCKT__ESAI_HCKT IOMUX_PAD(0x598, 0x154, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKT__AUDMUX_AUD5_RXC IOMUX_PAD(0x598, 0x154, 1, 0x7a8, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKT__GPIO1_9 IOMUX_PAD(0x598, 0x154, 5, 0x864, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKT__IPU_CSI_D_2 IOMUX_PAD(0x598, 0x154, 6, 0x938, 0, NO_PAD_CTRL)
+#define MX35_PAD_HCKT__KPP_COL_3 IOMUX_PAD(0x598, 0x154, 7, 0x95c, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_TX5_RX0__ESAI_TX5_RX0 IOMUX_PAD(0x59c, 0x158, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__AUDMUX_AUD4_RXC IOMUX_PAD(0x59c, 0x158, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__CSPI2_SS2 IOMUX_PAD(0x59c, 0x158, 2, 0x7f8, 1, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__CAN2_TXCAN IOMUX_PAD(0x59c, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__UART2_DTR IOMUX_PAD(0x59c, 0x158, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__GPIO1_10 IOMUX_PAD(0x59c, 0x158, 5, 0x830, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX5_RX0__EMI_M3IF_CHOSEN_MASTER_0 IOMUX_PAD(0x59c, 0x158, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TX4_RX1__ESAI_TX4_RX1 IOMUX_PAD(0x5a0, 0x15c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__AUDMUX_AUD4_RXFS IOMUX_PAD(0x5a0, 0x15c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__CSPI2_SS3 IOMUX_PAD(0x5a0, 0x15c, 2, 0x7fc, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__CAN2_RXCAN IOMUX_PAD(0x5a0, 0x15c, 3, 0x7cc, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__UART2_DSR IOMUX_PAD(0x5a0, 0x15c, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__GPIO1_11 IOMUX_PAD(0x5a0, 0x15c, 5, 0x834, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__IPU_CSI_D_3 IOMUX_PAD(0x5a0, 0x15c, 6, 0x93c, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX4_RX1__KPP_ROW_0 IOMUX_PAD(0x5a0, 0x15c, 7, 0x970, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_TX3_RX2__ESAI_TX3_RX2 IOMUX_PAD(0x5a4, 0x160, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX3_RX2__I2C3_SCL IOMUX_PAD(0x5a4, 0x160, 1, 0x91c, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX3_RX2__EMI_NANDF_CE1 IOMUX_PAD(0x5a4, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX3_RX2__GPIO1_12 IOMUX_PAD(0x5a4, 0x160, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX3_RX2__IPU_CSI_D_4 IOMUX_PAD(0x5a4, 0x160, 6, 0x940, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX3_RX2__KPP_ROW_1 IOMUX_PAD(0x5a4, 0x160, 7, 0x974, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_TX2_RX3__ESAI_TX2_RX3 IOMUX_PAD(0x5a8, 0x164, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX2_RX3__I2C3_SDA IOMUX_PAD(0x5a8, 0x164, 1, 0x920, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX2_RX3__EMI_NANDF_CE2 IOMUX_PAD(0x5a8, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX2_RX3__GPIO1_13 IOMUX_PAD(0x5a8, 0x164, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX2_RX3__IPU_CSI_D_5 IOMUX_PAD(0x5a8, 0x164, 6, 0x944, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX2_RX3__KPP_COL_0 IOMUX_PAD(0x5a8, 0x164, 7, 0x950, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_TX1__ESAI_TX1 IOMUX_PAD(0x5ac, 0x168, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX1__CCM_PMIC_RDY IOMUX_PAD(0x5ac, 0x168, 1, 0x7d4, 1, NO_PAD_CTRL)
+#define MX35_PAD_TX1__CSPI1_SS2 IOMUX_PAD(0x5ac, 0x168, 2, 0x7d8, 2, NO_PAD_CTRL)
+#define MX35_PAD_TX1__EMI_NANDF_CE3 IOMUX_PAD(0x5ac, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX1__UART2_RI IOMUX_PAD(0x5ac, 0x168, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX1__GPIO1_14 IOMUX_PAD(0x5ac, 0x168, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX1__IPU_CSI_D_6 IOMUX_PAD(0x5ac, 0x168, 6, 0x948, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX1__KPP_COL_1 IOMUX_PAD(0x5ac, 0x168, 7, 0x954, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_TX0__ESAI_TX0 IOMUX_PAD(0x5b0, 0x16c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX0__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x5b0, 0x16c, 1, 0x994, 1, NO_PAD_CTRL)
+#define MX35_PAD_TX0__CSPI1_SS3 IOMUX_PAD(0x5b0, 0x16c, 2, 0x7dc, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX0__EMI_DTACK_B IOMUX_PAD(0x5b0, 0x16c, 3, 0x800, 1, NO_PAD_CTRL)
+#define MX35_PAD_TX0__UART2_DCD IOMUX_PAD(0x5b0, 0x16c, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX0__GPIO1_15 IOMUX_PAD(0x5b0, 0x16c, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX0__IPU_CSI_D_7 IOMUX_PAD(0x5b0, 0x16c, 6, 0x94c, 0, NO_PAD_CTRL)
+#define MX35_PAD_TX0__KPP_COL_2 IOMUX_PAD(0x5b0, 0x16c, 7, 0x958, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_MOSI__CSPI1_MOSI IOMUX_PAD(0x5b4, 0x170, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_MOSI__GPIO1_16 IOMUX_PAD(0x5b4, 0x170, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_MOSI__ECT_CTI_TRIG_OUT1_2 IOMUX_PAD(0x5b4, 0x170, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_MISO__CSPI1_MISO IOMUX_PAD(0x5b8, 0x174, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_MISO__GPIO1_17 IOMUX_PAD(0x5b8, 0x174, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_MISO__ECT_CTI_TRIG_OUT1_3 IOMUX_PAD(0x5b8, 0x174, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_SS0__CSPI1_SS0 IOMUX_PAD(0x5bc, 0x178, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS0__OWIRE_LINE IOMUX_PAD(0x5bc, 0x178, 1, 0x990, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS0__CSPI2_SS3 IOMUX_PAD(0x5bc, 0x178, 2, 0x7fc, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS0__GPIO1_18 IOMUX_PAD(0x5bc, 0x178, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS0__ECT_CTI_TRIG_OUT1_4 IOMUX_PAD(0x5bc, 0x178, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_SS1__CSPI1_SS1 IOMUX_PAD(0x5c0, 0x17c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS1__PWM_PWMO IOMUX_PAD(0x5c0, 0x17c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS1__CCM_CLK32K IOMUX_PAD(0x5c0, 0x17c, 2, 0x7d0, 1, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS1__GPIO1_19 IOMUX_PAD(0x5c0, 0x17c, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS1__IPU_DIAGB_29 IOMUX_PAD(0x5c0, 0x17c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SS1__ECT_CTI_TRIG_OUT1_5 IOMUX_PAD(0x5c0, 0x17c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_SCLK__CSPI1_SCLK IOMUX_PAD(0x5c4, 0x180, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SCLK__GPIO3_4 IOMUX_PAD(0x5c4, 0x180, 5, 0x904, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SCLK__IPU_DIAGB_30 IOMUX_PAD(0x5c4, 0x180, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SCLK__EMI_M3IF_CHOSEN_MASTER_1 IOMUX_PAD(0x5c4, 0x180, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CSPI1_SPI_RDY__CSPI1_RDY IOMUX_PAD(0x5c8, 0x184, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SPI_RDY__GPIO3_5 IOMUX_PAD(0x5c8, 0x184, 5, 0x908, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SPI_RDY__IPU_DIAGB_31 IOMUX_PAD(0x5c8, 0x184, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CSPI1_SPI_RDY__EMI_M3IF_CHOSEN_MASTER_2 IOMUX_PAD(0x5c8, 0x184, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RXD1__UART1_RXD_MUX IOMUX_PAD(0x5cc, 0x188, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RXD1__CSPI2_MOSI IOMUX_PAD(0x5cc, 0x188, 1, 0x7ec, 1, NO_PAD_CTRL)
+#define MX35_PAD_RXD1__KPP_COL_4 IOMUX_PAD(0x5cc, 0x188, 4, 0x960, 0, NO_PAD_CTRL)
+#define MX35_PAD_RXD1__GPIO3_6 IOMUX_PAD(0x5cc, 0x188, 5, 0x90c, 0, NO_PAD_CTRL)
+#define MX35_PAD_RXD1__ARM11P_TOP_EVNTBUS_16 IOMUX_PAD(0x5cc, 0x188, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TXD1__UART1_TXD_MUX IOMUX_PAD(0x5d0, 0x18c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TXD1__CSPI2_MISO IOMUX_PAD(0x5d0, 0x18c, 1, 0x7e8, 1, NO_PAD_CTRL)
+#define MX35_PAD_TXD1__KPP_COL_5 IOMUX_PAD(0x5d0, 0x18c, 4, 0x964, 0, NO_PAD_CTRL)
+#define MX35_PAD_TXD1__GPIO3_7 IOMUX_PAD(0x5d0, 0x18c, 5, 0x910, 0, NO_PAD_CTRL)
+#define MX35_PAD_TXD1__ARM11P_TOP_EVNTBUS_17 IOMUX_PAD(0x5d0, 0x18c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RTS1__UART1_RTS IOMUX_PAD(0x5d4, 0x190, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__CSPI2_SCLK IOMUX_PAD(0x5d4, 0x190, 1, 0x7e0, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__I2C3_SCL IOMUX_PAD(0x5d4, 0x190, 2, 0x91c, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__IPU_CSI_D_0 IOMUX_PAD(0x5d4, 0x190, 3, 0x930, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__KPP_COL_6 IOMUX_PAD(0x5d4, 0x190, 4, 0x968, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__GPIO3_8 IOMUX_PAD(0x5d4, 0x190, 5, 0x914, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__EMI_NANDF_CE1 IOMUX_PAD(0x5d4, 0x190, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS1__ARM11P_TOP_EVNTBUS_18 IOMUX_PAD(0x5d4, 0x190, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CTS1__UART1_CTS IOMUX_PAD(0x5d8, 0x194, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__CSPI2_RDY IOMUX_PAD(0x5d8, 0x194, 1, 0x7e4, 1, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__I2C3_SDA IOMUX_PAD(0x5d8, 0x194, 2, 0x920, 1, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__IPU_CSI_D_1 IOMUX_PAD(0x5d8, 0x194, 3, 0x934, 1, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__KPP_COL_7 IOMUX_PAD(0x5d8, 0x194, 4, 0x96c, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__GPIO3_9 IOMUX_PAD(0x5d8, 0x194, 5, 0x918, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__EMI_NANDF_CE2 IOMUX_PAD(0x5d8, 0x194, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS1__ARM11P_TOP_EVNTBUS_19 IOMUX_PAD(0x5d8, 0x194, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RXD2__UART2_RXD_MUX IOMUX_PAD(0x5dc, 0x198, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RXD2__KPP_ROW_4 IOMUX_PAD(0x5dc, 0x198, 4, 0x980, 0, NO_PAD_CTRL)
+#define MX35_PAD_RXD2__GPIO3_10 IOMUX_PAD(0x5dc, 0x198, 5, 0x8ec, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TXD2__UART2_TXD_MUX IOMUX_PAD(0x5e0, 0x19c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_TXD2__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x5e0, 0x19c, 1, 0x994, 2, NO_PAD_CTRL)
+#define MX35_PAD_TXD2__KPP_ROW_5 IOMUX_PAD(0x5e0, 0x19c, 4, 0x984, 0, NO_PAD_CTRL)
+#define MX35_PAD_TXD2__GPIO3_11 IOMUX_PAD(0x5e0, 0x19c, 5, 0x8f0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RTS2__UART2_RTS IOMUX_PAD(0x5e4, 0x1a0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__SPDIF_SPDIF_IN1 IOMUX_PAD(0x5e4, 0x1a0, 1, 0x998, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__CAN2_RXCAN IOMUX_PAD(0x5e4, 0x1a0, 2, 0x7cc, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__IPU_CSI_D_2 IOMUX_PAD(0x5e4, 0x1a0, 3, 0x938, 1, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__KPP_ROW_6 IOMUX_PAD(0x5e4, 0x1a0, 4, 0x988, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__GPIO3_12 IOMUX_PAD(0x5e4, 0x1a0, 5, 0x8f4, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__AUDMUX_AUD5_RXC IOMUX_PAD(0x5e4, 0x1a0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_RTS2__UART3_RXD_MUX IOMUX_PAD(0x5e4, 0x1a0, 7, 0x9a0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CTS2__UART2_CTS IOMUX_PAD(0x5e8, 0x1a4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x5e8, 0x1a4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__CAN2_TXCAN IOMUX_PAD(0x5e8, 0x1a4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__IPU_CSI_D_3 IOMUX_PAD(0x5e8, 0x1a4, 3, 0x93c, 1, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__KPP_ROW_7 IOMUX_PAD(0x5e8, 0x1a4, 4, 0x98c, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__GPIO3_13 IOMUX_PAD(0x5e8, 0x1a4, 5, 0x8f8, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__AUDMUX_AUD5_RXFS IOMUX_PAD(0x5e8, 0x1a4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CTS2__UART3_TXD_MUX IOMUX_PAD(0x5e8, 0x1a4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_RTCK__ARM11P_TOP_RTCK IOMUX_PAD(0x5ec, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TCK__SJC_TCK IOMUX_PAD(0x5f0, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TMS__SJC_TMS IOMUX_PAD(0x5f4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TDI__SJC_TDI IOMUX_PAD(0x5f8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TDO__SJC_TDO IOMUX_PAD(0x5fc, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TRSTB__SJC_TRSTB IOMUX_PAD(0x600, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_DE_B__SJC_DE_B IOMUX_PAD(0x604, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SJC_MOD__SJC_MOD IOMUX_PAD(0x608, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR IOMUX_PAD(0x60c, 0x1a8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_USBOTG_PWR__USB_TOP_USBH2_PWR IOMUX_PAD(0x60c, 0x1a8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_USBOTG_PWR__GPIO3_14 IOMUX_PAD(0x60c, 0x1a8, 5, 0x8fc, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC IOMUX_PAD(0x610, 0x1ac, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_USBOTG_OC__USB_TOP_USBH2_OC IOMUX_PAD(0x610, 0x1ac, 1, 0x9f4, 1, NO_PAD_CTRL)
+#define MX35_PAD_USBOTG_OC__GPIO3_15 IOMUX_PAD(0x610, 0x1ac, 5, 0x900, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD0__IPU_DISPB_DAT_0 IOMUX_PAD(0x614, 0x1b0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD0__GPIO2_0 IOMUX_PAD(0x614, 0x1b0, 5, 0x868, 1, NO_PAD_CTRL)
+#define MX35_PAD_LD0__SDMA_SDMA_DEBUG_PC_0 IOMUX_PAD(0x614, 0x1b0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD1__IPU_DISPB_DAT_1 IOMUX_PAD(0x618, 0x1b4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD1__GPIO2_1 IOMUX_PAD(0x618, 0x1b4, 5, 0x894, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD1__SDMA_SDMA_DEBUG_PC_1 IOMUX_PAD(0x618, 0x1b4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD2__IPU_DISPB_DAT_2 IOMUX_PAD(0x61c, 0x1b8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD2__GPIO2_2 IOMUX_PAD(0x61c, 0x1b8, 5, 0x8c0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD2__SDMA_SDMA_DEBUG_PC_2 IOMUX_PAD(0x61c, 0x1b8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD3__IPU_DISPB_DAT_3 IOMUX_PAD(0x620, 0x1bc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD3__GPIO2_3 IOMUX_PAD(0x620, 0x1bc, 5, 0x8cc, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD3__SDMA_SDMA_DEBUG_PC_3 IOMUX_PAD(0x620, 0x1bc, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD4__IPU_DISPB_DAT_4 IOMUX_PAD(0x624, 0x1c0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD4__GPIO2_4 IOMUX_PAD(0x624, 0x1c0, 5, 0x8d0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD4__SDMA_SDMA_DEBUG_PC_4 IOMUX_PAD(0x624, 0x1c0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD5__IPU_DISPB_DAT_5 IOMUX_PAD(0x628, 0x1c4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD5__GPIO2_5 IOMUX_PAD(0x628, 0x1c4, 5, 0x8d4, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD5__SDMA_SDMA_DEBUG_PC_5 IOMUX_PAD(0x628, 0x1c4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD6__IPU_DISPB_DAT_6 IOMUX_PAD(0x62c, 0x1c8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD6__GPIO2_6 IOMUX_PAD(0x62c, 0x1c8, 5, 0x8d8, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD6__SDMA_SDMA_DEBUG_PC_6 IOMUX_PAD(0x62c, 0x1c8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD7__IPU_DISPB_DAT_7 IOMUX_PAD(0x630, 0x1cc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD7__GPIO2_7 IOMUX_PAD(0x630, 0x1cc, 5, 0x8dc, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD7__SDMA_SDMA_DEBUG_PC_7 IOMUX_PAD(0x630, 0x1cc, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD8__IPU_DISPB_DAT_8 IOMUX_PAD(0x634, 0x1d0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD8__GPIO2_8 IOMUX_PAD(0x634, 0x1d0, 5, 0x8e0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD8__SDMA_SDMA_DEBUG_PC_8 IOMUX_PAD(0x634, 0x1d0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD9__IPU_DISPB_DAT_9 IOMUX_PAD(0x638, 0x1d4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD9__GPIO2_9 IOMUX_PAD(0x638, 0x1d4, 5, 0x8e4, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD9__SDMA_SDMA_DEBUG_PC_9 IOMUX_PAD(0x638, 0x1d4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD10__IPU_DISPB_DAT_10 IOMUX_PAD(0x63c, 0x1d8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD10__GPIO2_10 IOMUX_PAD(0x63c, 0x1d8, 5, 0x86c, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD10__SDMA_SDMA_DEBUG_PC_10 IOMUX_PAD(0x63c, 0x1d8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD11__IPU_DISPB_DAT_11 IOMUX_PAD(0x640, 0x1dc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD11__GPIO2_11 IOMUX_PAD(0x640, 0x1dc, 5, 0x870, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD11__SDMA_SDMA_DEBUG_PC_11 IOMUX_PAD(0x640, 0x1dc, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD11__ARM11P_TOP_TRACE_4 IOMUX_PAD(0x640, 0x1dc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD12__IPU_DISPB_DAT_12 IOMUX_PAD(0x644, 0x1e0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD12__GPIO2_12 IOMUX_PAD(0x644, 0x1e0, 5, 0x874, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD12__SDMA_SDMA_DEBUG_PC_12 IOMUX_PAD(0x644, 0x1e0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD12__ARM11P_TOP_TRACE_5 IOMUX_PAD(0x644, 0x1e0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD13__IPU_DISPB_DAT_13 IOMUX_PAD(0x648, 0x1e4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD13__GPIO2_13 IOMUX_PAD(0x648, 0x1e4, 5, 0x878, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD13__SDMA_SDMA_DEBUG_PC_13 IOMUX_PAD(0x648, 0x1e4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD13__ARM11P_TOP_TRACE_6 IOMUX_PAD(0x648, 0x1e4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD14__IPU_DISPB_DAT_14 IOMUX_PAD(0x64c, 0x1e8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD14__GPIO2_14 IOMUX_PAD(0x64c, 0x1e8, 5, 0x87c, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD14__SDMA_SDMA_DEBUG_EVENT_CHANNEL_0 IOMUX_PAD(0x64c, 0x1e8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD14__ARM11P_TOP_TRACE_7 IOMUX_PAD(0x64c, 0x1e8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD15__IPU_DISPB_DAT_15 IOMUX_PAD(0x650, 0x1ec, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD15__GPIO2_15 IOMUX_PAD(0x650, 0x1ec, 5, 0x880, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD15__SDMA_SDMA_DEBUG_EVENT_CHANNEL_1 IOMUX_PAD(0x650, 0x1ec, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD15__ARM11P_TOP_TRACE_8 IOMUX_PAD(0x650, 0x1ec, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD16__IPU_DISPB_DAT_16 IOMUX_PAD(0x654, 0x1f0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD16__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x654, 0x1f0, 2, 0x928, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD16__GPIO2_16 IOMUX_PAD(0x654, 0x1f0, 5, 0x884, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD16__SDMA_SDMA_DEBUG_EVENT_CHANNEL_2 IOMUX_PAD(0x654, 0x1f0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD16__ARM11P_TOP_TRACE_9 IOMUX_PAD(0x654, 0x1f0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD17__IPU_DISPB_DAT_17 IOMUX_PAD(0x658, 0x1f4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD17__IPU_DISPB_CS2 IOMUX_PAD(0x658, 0x1f4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD17__GPIO2_17 IOMUX_PAD(0x658, 0x1f4, 5, 0x888, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD17__SDMA_SDMA_DEBUG_EVENT_CHANNEL_3 IOMUX_PAD(0x658, 0x1f4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD17__ARM11P_TOP_TRACE_10 IOMUX_PAD(0x658, 0x1f4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD18__IPU_DISPB_DAT_18 IOMUX_PAD(0x65c, 0x1f8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD18__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x65c, 0x1f8, 1, 0x924, 1, NO_PAD_CTRL)
+#define MX35_PAD_LD18__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x65c, 0x1f8, 2, 0x928, 1, NO_PAD_CTRL)
+#define MX35_PAD_LD18__ESDHC3_CMD IOMUX_PAD(0x65c, 0x1f8, 3, 0x818, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD18__USB_TOP_USBOTG_DATA_3 IOMUX_PAD(0x65c, 0x1f8, 4, 0x9b0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD18__GPIO3_24 IOMUX_PAD(0x65c, 0x1f8, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD18__SDMA_SDMA_DEBUG_EVENT_CHANNEL_4 IOMUX_PAD(0x65c, 0x1f8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD18__ARM11P_TOP_TRACE_11 IOMUX_PAD(0x65c, 0x1f8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD19__IPU_DISPB_DAT_19 IOMUX_PAD(0x660, 0x1fc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__IPU_DISPB_BCLK IOMUX_PAD(0x660, 0x1fc, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__IPU_DISPB_CS1 IOMUX_PAD(0x660, 0x1fc, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__ESDHC3_CLK IOMUX_PAD(0x660, 0x1fc, 3, 0x814, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__USB_TOP_USBOTG_DIR IOMUX_PAD(0x660, 0x1fc, 4, 0x9c4, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__GPIO3_25 IOMUX_PAD(0x660, 0x1fc, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__SDMA_SDMA_DEBUG_EVENT_CHANNEL_5 IOMUX_PAD(0x660, 0x1fc, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD19__ARM11P_TOP_TRACE_12 IOMUX_PAD(0x660, 0x1fc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD20__IPU_DISPB_DAT_20 IOMUX_PAD(0x664, 0x200, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__IPU_DISPB_CS0 IOMUX_PAD(0x664, 0x200, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__IPU_DISPB_SD_CLK IOMUX_PAD(0x664, 0x200, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__ESDHC3_DAT0 IOMUX_PAD(0x664, 0x200, 3, 0x81c, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__GPIO3_26 IOMUX_PAD(0x664, 0x200, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__SDMA_SDMA_DEBUG_CORE_STATUS_3 IOMUX_PAD(0x664, 0x200, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD20__ARM11P_TOP_TRACE_13 IOMUX_PAD(0x664, 0x200, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD21__IPU_DISPB_DAT_21 IOMUX_PAD(0x668, 0x204, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__IPU_DISPB_PAR_RS IOMUX_PAD(0x668, 0x204, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__IPU_DISPB_SER_RS IOMUX_PAD(0x668, 0x204, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__ESDHC3_DAT1 IOMUX_PAD(0x668, 0x204, 3, 0x820, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__USB_TOP_USBOTG_STP IOMUX_PAD(0x668, 0x204, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__GPIO3_27 IOMUX_PAD(0x668, 0x204, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__SDMA_DEBUG_EVENT_CHANNEL_SEL IOMUX_PAD(0x668, 0x204, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD21__ARM11P_TOP_TRACE_14 IOMUX_PAD(0x668, 0x204, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD22__IPU_DISPB_DAT_22 IOMUX_PAD(0x66c, 0x208, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__IPU_DISPB_WR IOMUX_PAD(0x66c, 0x208, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__IPU_DISPB_SD_D_I IOMUX_PAD(0x66c, 0x208, 2, 0x92c, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__ESDHC3_DAT2 IOMUX_PAD(0x66c, 0x208, 3, 0x824, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__USB_TOP_USBOTG_NXT IOMUX_PAD(0x66c, 0x208, 4, 0x9c8, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__GPIO3_28 IOMUX_PAD(0x66c, 0x208, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__SDMA_DEBUG_BUS_ERROR IOMUX_PAD(0x66c, 0x208, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD22__ARM11P_TOP_TRCTL IOMUX_PAD(0x66c, 0x208, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_LD23__IPU_DISPB_DAT_23 IOMUX_PAD(0x670, 0x20c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__IPU_DISPB_RD IOMUX_PAD(0x670, 0x20c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__IPU_DISPB_SD_D_IO IOMUX_PAD(0x670, 0x20c, 2, 0x92c, 1, NO_PAD_CTRL)
+#define MX35_PAD_LD23__ESDHC3_DAT3 IOMUX_PAD(0x670, 0x20c, 3, 0x828, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__USB_TOP_USBOTG_DATA_7 IOMUX_PAD(0x670, 0x20c, 4, 0x9c0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__GPIO3_29 IOMUX_PAD(0x670, 0x20c, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__SDMA_DEBUG_MATCHED_DMBUS IOMUX_PAD(0x670, 0x20c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_LD23__ARM11P_TOP_TRCLK IOMUX_PAD(0x670, 0x20c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC IOMUX_PAD(0x674, 0x210, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_HSYNC__IPU_DISPB_SD_D_IO IOMUX_PAD(0x674, 0x210, 2, 0x92c, 2, NO_PAD_CTRL)
+#define MX35_PAD_D3_HSYNC__GPIO3_30 IOMUX_PAD(0x674, 0x210, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_HSYNC__SDMA_DEBUG_RTBUFFER_WRITE IOMUX_PAD(0x674, 0x210, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_HSYNC__ARM11P_TOP_TRACE_15 IOMUX_PAD(0x674, 0x210, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK IOMUX_PAD(0x678, 0x214, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_FPSHIFT__IPU_DISPB_SD_CLK IOMUX_PAD(0x678, 0x214, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_FPSHIFT__GPIO3_31 IOMUX_PAD(0x678, 0x214, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_FPSHIFT__SDMA_SDMA_DEBUG_CORE_STATUS_0 IOMUX_PAD(0x678, 0x214, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_FPSHIFT__ARM11P_TOP_TRACE_16 IOMUX_PAD(0x678, 0x214, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY IOMUX_PAD(0x67c, 0x218, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_DRDY__IPU_DISPB_SD_D_O IOMUX_PAD(0x67c, 0x218, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_DRDY__GPIO1_0 IOMUX_PAD(0x67c, 0x218, 5, 0x82c, 2, NO_PAD_CTRL)
+#define MX35_PAD_D3_DRDY__SDMA_SDMA_DEBUG_CORE_STATUS_1 IOMUX_PAD(0x67c, 0x218, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_DRDY__ARM11P_TOP_TRACE_17 IOMUX_PAD(0x67c, 0x218, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_CONTRAST__IPU_DISPB_CONTR IOMUX_PAD(0x680, 0x21c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CONTRAST__GPIO1_1 IOMUX_PAD(0x680, 0x21c, 5, 0x838, 2, NO_PAD_CTRL)
+#define MX35_PAD_CONTRAST__SDMA_SDMA_DEBUG_CORE_STATUS_2 IOMUX_PAD(0x680, 0x21c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_CONTRAST__ARM11P_TOP_TRACE_18 IOMUX_PAD(0x680, 0x21c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC IOMUX_PAD(0x684, 0x220, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_VSYNC__IPU_DISPB_CS1 IOMUX_PAD(0x684, 0x220, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_VSYNC__GPIO1_2 IOMUX_PAD(0x684, 0x220, 5, 0x848, 1, NO_PAD_CTRL)
+#define MX35_PAD_D3_VSYNC__SDMA_DEBUG_YIELD IOMUX_PAD(0x684, 0x220, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_VSYNC__ARM11P_TOP_TRACE_19 IOMUX_PAD(0x684, 0x220, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_REV__IPU_DISPB_D3_REV IOMUX_PAD(0x688, 0x224, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_REV__IPU_DISPB_SER_RS IOMUX_PAD(0x688, 0x224, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_REV__GPIO1_3 IOMUX_PAD(0x688, 0x224, 5, 0x84c, 1, NO_PAD_CTRL)
+#define MX35_PAD_D3_REV__SDMA_DEBUG_BUS_RWB IOMUX_PAD(0x688, 0x224, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_REV__ARM11P_TOP_TRACE_20 IOMUX_PAD(0x688, 0x224, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_CLS__IPU_DISPB_D3_CLS IOMUX_PAD(0x68c, 0x228, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_CLS__IPU_DISPB_CS2 IOMUX_PAD(0x68c, 0x228, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_CLS__GPIO1_4 IOMUX_PAD(0x68c, 0x228, 5, 0x850, 2, NO_PAD_CTRL)
+#define MX35_PAD_D3_CLS__SDMA_DEBUG_BUS_DEVICE_0 IOMUX_PAD(0x68c, 0x228, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_CLS__ARM11P_TOP_TRACE_21 IOMUX_PAD(0x68c, 0x228, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_D3_SPL__IPU_DISPB_D3_SPL IOMUX_PAD(0x690, 0x22c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_SPL__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x690, 0x22c, 2, 0x928, 2, NO_PAD_CTRL)
+#define MX35_PAD_D3_SPL__GPIO1_5 IOMUX_PAD(0x690, 0x22c, 5, 0x854, 2, NO_PAD_CTRL)
+#define MX35_PAD_D3_SPL__SDMA_DEBUG_BUS_DEVICE_1 IOMUX_PAD(0x690, 0x22c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_D3_SPL__ARM11P_TOP_TRACE_22 IOMUX_PAD(0x690, 0x22c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x694, 0x230, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__MSHC_SCLK IOMUX_PAD(0x694, 0x230, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x694, 0x230, 3, 0x924, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__USB_TOP_USBOTG_DATA_4 IOMUX_PAD(0x694, 0x230, 4, 0x9b4, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__GPIO1_6 IOMUX_PAD(0x694, 0x230, 5, 0x858, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CMD__ARM11P_TOP_TRCTL IOMUX_PAD(0x694, 0x230, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x698, 0x234, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__MSHC_BS IOMUX_PAD(0x698, 0x234, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__IPU_DISPB_BCLK IOMUX_PAD(0x698, 0x234, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__USB_TOP_USBOTG_DATA_5 IOMUX_PAD(0x698, 0x234, 4, 0x9b8, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__GPIO1_7 IOMUX_PAD(0x698, 0x234, 5, 0x85c, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD1_CLK__ARM11P_TOP_TRCLK IOMUX_PAD(0x698, 0x234, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_DATA0__ESDHC1_DAT0 IOMUX_PAD(0x69c, 0x238, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__MSHC_DATA_0 IOMUX_PAD(0x69c, 0x238, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__IPU_DISPB_CS0 IOMUX_PAD(0x69c, 0x238, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__USB_TOP_USBOTG_DATA_6 IOMUX_PAD(0x69c, 0x238, 4, 0x9bc, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__GPIO1_8 IOMUX_PAD(0x69c, 0x238, 5, 0x860, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA0__ARM11P_TOP_TRACE_23 IOMUX_PAD(0x69c, 0x238, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_DATA1__ESDHC1_DAT1 IOMUX_PAD(0x6a0, 0x23c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__MSHC_DATA_1 IOMUX_PAD(0x6a0, 0x23c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__IPU_DISPB_PAR_RS IOMUX_PAD(0x6a0, 0x23c, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__USB_TOP_USBOTG_DATA_0 IOMUX_PAD(0x6a0, 0x23c, 4, 0x9a4, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__GPIO1_9 IOMUX_PAD(0x6a0, 0x23c, 5, 0x864, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA1__ARM11P_TOP_TRACE_24 IOMUX_PAD(0x6a0, 0x23c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_DATA2__ESDHC1_DAT2 IOMUX_PAD(0x6a4, 0x240, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__MSHC_DATA_2 IOMUX_PAD(0x6a4, 0x240, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__IPU_DISPB_WR IOMUX_PAD(0x6a4, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__USB_TOP_USBOTG_DATA_1 IOMUX_PAD(0x6a4, 0x240, 4, 0x9a8, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__GPIO1_10 IOMUX_PAD(0x6a4, 0x240, 5, 0x830, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA2__ARM11P_TOP_TRACE_25 IOMUX_PAD(0x6a4, 0x240, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD1_DATA3__ESDHC1_DAT3 IOMUX_PAD(0x6a8, 0x244, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__MSHC_DATA_3 IOMUX_PAD(0x6a8, 0x244, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__IPU_DISPB_RD IOMUX_PAD(0x6a8, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__USB_TOP_USBOTG_DATA_2 IOMUX_PAD(0x6a8, 0x244, 4, 0x9ac, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__GPIO1_11 IOMUX_PAD(0x6a8, 0x244, 5, 0x834, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD1_DATA3__ARM11P_TOP_TRACE_26 IOMUX_PAD(0x6a8, 0x244, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_CMD__ESDHC2_CMD IOMUX_PAD(0x6ac, 0x248, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__I2C3_SCL IOMUX_PAD(0x6ac, 0x248, 1, 0x91c, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__ESDHC1_DAT4 IOMUX_PAD(0x6ac, 0x248, 2, 0x804, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__IPU_CSI_D_2 IOMUX_PAD(0x6ac, 0x248, 3, 0x938, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__USB_TOP_USBH2_DATA_4 IOMUX_PAD(0x6ac, 0x248, 4, 0x9dc, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__GPIO2_0 IOMUX_PAD(0x6ac, 0x248, 5, 0x868, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x6ac, 0x248, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CMD__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x6ac, 0x248, 7, 0x928, 3, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_CLK__ESDHC2_CLK IOMUX_PAD(0x6b0, 0x24c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__I2C3_SDA IOMUX_PAD(0x6b0, 0x24c, 1, 0x920, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__ESDHC1_DAT5 IOMUX_PAD(0x6b0, 0x24c, 2, 0x808, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__IPU_CSI_D_3 IOMUX_PAD(0x6b0, 0x24c, 3, 0x93c, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__USB_TOP_USBH2_DATA_5 IOMUX_PAD(0x6b0, 0x24c, 4, 0x9e0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__GPIO2_1 IOMUX_PAD(0x6b0, 0x24c, 5, 0x894, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__SPDIF_SPDIF_IN1 IOMUX_PAD(0x6b0, 0x24c, 6, 0x998, 2, NO_PAD_CTRL)
+#define MX35_PAD_SD2_CLK__IPU_DISPB_CS2 IOMUX_PAD(0x6b0, 0x24c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_DATA0__ESDHC2_DAT0 IOMUX_PAD(0x6b4, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__UART3_RXD_MUX IOMUX_PAD(0x6b4, 0x250, 1, 0x9a0, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__ESDHC1_DAT6 IOMUX_PAD(0x6b4, 0x250, 2, 0x80c, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__IPU_CSI_D_4 IOMUX_PAD(0x6b4, 0x250, 3, 0x940, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__USB_TOP_USBH2_DATA_6 IOMUX_PAD(0x6b4, 0x250, 4, 0x9e4, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__GPIO2_2 IOMUX_PAD(0x6b4, 0x250, 5, 0x8c0, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA0__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x6b4, 0x250, 6, 0x994, 3, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_DATA1__ESDHC2_DAT1 IOMUX_PAD(0x6b8, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA1__UART3_TXD_MUX IOMUX_PAD(0x6b8, 0x254, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA1__ESDHC1_DAT7 IOMUX_PAD(0x6b8, 0x254, 2, 0x810, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA1__IPU_CSI_D_5 IOMUX_PAD(0x6b8, 0x254, 3, 0x944, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA1__USB_TOP_USBH2_DATA_0 IOMUX_PAD(0x6b8, 0x254, 4, 0x9cc, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA1__GPIO2_3 IOMUX_PAD(0x6b8, 0x254, 5, 0x8cc, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_DATA2__ESDHC2_DAT2 IOMUX_PAD(0x6bc, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA2__UART3_RTS IOMUX_PAD(0x6bc, 0x258, 1, 0x99c, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA2__CAN1_RXCAN IOMUX_PAD(0x6bc, 0x258, 2, 0x7c8, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA2__IPU_CSI_D_6 IOMUX_PAD(0x6bc, 0x258, 3, 0x948, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA2__USB_TOP_USBH2_DATA_1 IOMUX_PAD(0x6bc, 0x258, 4, 0x9d0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA2__GPIO2_4 IOMUX_PAD(0x6bc, 0x258, 5, 0x8d0, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_SD2_DATA3__ESDHC2_DAT3 IOMUX_PAD(0x6c0, 0x25c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA3__UART3_CTS IOMUX_PAD(0x6c0, 0x25c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA3__CAN1_TXCAN IOMUX_PAD(0x6c0, 0x25c, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA3__IPU_CSI_D_7 IOMUX_PAD(0x6c0, 0x25c, 3, 0x94c, 1, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA3__USB_TOP_USBH2_DATA_2 IOMUX_PAD(0x6c0, 0x25c, 4, 0x9d4, 0, NO_PAD_CTRL)
+#define MX35_PAD_SD2_DATA3__GPIO2_5 IOMUX_PAD(0x6c0, 0x25c, 5, 0x8d4, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_CS0__ATA_CS0 IOMUX_PAD(0x6c4, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS0__CSPI1_SS3 IOMUX_PAD(0x6c4, 0x260, 1, 0x7dc, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS0__IPU_DISPB_CS1 IOMUX_PAD(0x6c4, 0x260, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS0__GPIO2_6 IOMUX_PAD(0x6c4, 0x260, 5, 0x8d8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS0__IPU_DIAGB_0 IOMUX_PAD(0x6c4, 0x260, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS0__ARM11P_TOP_MAX1_HMASTER_0 IOMUX_PAD(0x6c4, 0x260, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_CS1__ATA_CS1 IOMUX_PAD(0x6c8, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS1__IPU_DISPB_CS2 IOMUX_PAD(0x6c8, 0x264, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS1__CSPI2_SS0 IOMUX_PAD(0x6c8, 0x264, 4, 0x7f0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS1__GPIO2_7 IOMUX_PAD(0x6c8, 0x264, 5, 0x8dc, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS1__IPU_DIAGB_1 IOMUX_PAD(0x6c8, 0x264, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_CS1__ARM11P_TOP_MAX1_HMASTER_1 IOMUX_PAD(0x6c8, 0x264, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DIOR__ATA_DIOR IOMUX_PAD(0x6cc, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__ESDHC3_DAT0 IOMUX_PAD(0x6cc, 0x268, 1, 0x81c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__USB_TOP_USBOTG_DIR IOMUX_PAD(0x6cc, 0x268, 2, 0x9c4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__IPU_DISPB_BE0 IOMUX_PAD(0x6cc, 0x268, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__CSPI2_SS1 IOMUX_PAD(0x6cc, 0x268, 4, 0x7f4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__GPIO2_8 IOMUX_PAD(0x6cc, 0x268, 5, 0x8e0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__IPU_DIAGB_2 IOMUX_PAD(0x6cc, 0x268, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOR__ARM11P_TOP_MAX1_HMASTER_2 IOMUX_PAD(0x6cc, 0x268, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DIOW__ATA_DIOW IOMUX_PAD(0x6d0, 0x26c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__ESDHC3_DAT1 IOMUX_PAD(0x6d0, 0x26c, 1, 0x820, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__USB_TOP_USBOTG_STP IOMUX_PAD(0x6d0, 0x26c, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__IPU_DISPB_BE1 IOMUX_PAD(0x6d0, 0x26c, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__CSPI2_MOSI IOMUX_PAD(0x6d0, 0x26c, 4, 0x7ec, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__GPIO2_9 IOMUX_PAD(0x6d0, 0x26c, 5, 0x8e4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__IPU_DIAGB_3 IOMUX_PAD(0x6d0, 0x26c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DIOW__ARM11P_TOP_MAX1_HMASTER_3 IOMUX_PAD(0x6d0, 0x26c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DMACK__ATA_DMACK IOMUX_PAD(0x6d4, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__ESDHC3_DAT2 IOMUX_PAD(0x6d4, 0x270, 1, 0x824, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__USB_TOP_USBOTG_NXT IOMUX_PAD(0x6d4, 0x270, 2, 0x9c8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__CSPI2_MISO IOMUX_PAD(0x6d4, 0x270, 4, 0x7e8, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__GPIO2_10 IOMUX_PAD(0x6d4, 0x270, 5, 0x86c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__IPU_DIAGB_4 IOMUX_PAD(0x6d4, 0x270, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMACK__ARM11P_TOP_MAX0_HMASTER_0 IOMUX_PAD(0x6d4, 0x270, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_RESET_B__ATA_RESET_B IOMUX_PAD(0x6d8, 0x274, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__ESDHC3_DAT3 IOMUX_PAD(0x6d8, 0x274, 1, 0x828, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__USB_TOP_USBOTG_DATA_0 IOMUX_PAD(0x6d8, 0x274, 2, 0x9a4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__IPU_DISPB_SD_D_O IOMUX_PAD(0x6d8, 0x274, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__CSPI2_RDY IOMUX_PAD(0x6d8, 0x274, 4, 0x7e4, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__GPIO2_11 IOMUX_PAD(0x6d8, 0x274, 5, 0x870, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__IPU_DIAGB_5 IOMUX_PAD(0x6d8, 0x274, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_RESET_B__ARM11P_TOP_MAX0_HMASTER_1 IOMUX_PAD(0x6d8, 0x274, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_IORDY__ATA_IORDY IOMUX_PAD(0x6dc, 0x278, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__ESDHC3_DAT4 IOMUX_PAD(0x6dc, 0x278, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__USB_TOP_USBOTG_DATA_1 IOMUX_PAD(0x6dc, 0x278, 2, 0x9a8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__IPU_DISPB_SD_D_IO IOMUX_PAD(0x6dc, 0x278, 3, 0x92c, 3, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__ESDHC2_DAT4 IOMUX_PAD(0x6dc, 0x278, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__GPIO2_12 IOMUX_PAD(0x6dc, 0x278, 5, 0x874, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__IPU_DIAGB_6 IOMUX_PAD(0x6dc, 0x278, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_IORDY__ARM11P_TOP_MAX0_HMASTER_2 IOMUX_PAD(0x6dc, 0x278, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA0__ATA_DATA_0 IOMUX_PAD(0x6e0, 0x27c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__ESDHC3_DAT5 IOMUX_PAD(0x6e0, 0x27c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__USB_TOP_USBOTG_DATA_2 IOMUX_PAD(0x6e0, 0x27c, 2, 0x9ac, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x6e0, 0x27c, 3, 0x928, 4, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__ESDHC2_DAT5 IOMUX_PAD(0x6e0, 0x27c, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__GPIO2_13 IOMUX_PAD(0x6e0, 0x27c, 5, 0x878, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__IPU_DIAGB_7 IOMUX_PAD(0x6e0, 0x27c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA0__ARM11P_TOP_MAX0_HMASTER_3 IOMUX_PAD(0x6e0, 0x27c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA1__ATA_DATA_1 IOMUX_PAD(0x6e4, 0x280, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__ESDHC3_DAT6 IOMUX_PAD(0x6e4, 0x280, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__USB_TOP_USBOTG_DATA_3 IOMUX_PAD(0x6e4, 0x280, 2, 0x9b0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__IPU_DISPB_SD_CLK IOMUX_PAD(0x6e4, 0x280, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__ESDHC2_DAT6 IOMUX_PAD(0x6e4, 0x280, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__GPIO2_14 IOMUX_PAD(0x6e4, 0x280, 5, 0x87c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__IPU_DIAGB_8 IOMUX_PAD(0x6e4, 0x280, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA1__ARM11P_TOP_TRACE_27 IOMUX_PAD(0x6e4, 0x280, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA2__ATA_DATA_2 IOMUX_PAD(0x6e8, 0x284, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__ESDHC3_DAT7 IOMUX_PAD(0x6e8, 0x284, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__USB_TOP_USBOTG_DATA_4 IOMUX_PAD(0x6e8, 0x284, 2, 0x9b4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__IPU_DISPB_SER_RS IOMUX_PAD(0x6e8, 0x284, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__ESDHC2_DAT7 IOMUX_PAD(0x6e8, 0x284, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__GPIO2_15 IOMUX_PAD(0x6e8, 0x284, 5, 0x880, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__IPU_DIAGB_9 IOMUX_PAD(0x6e8, 0x284, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA2__ARM11P_TOP_TRACE_28 IOMUX_PAD(0x6e8, 0x284, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA3__ATA_DATA_3 IOMUX_PAD(0x6ec, 0x288, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__ESDHC3_CLK IOMUX_PAD(0x6ec, 0x288, 1, 0x814, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__USB_TOP_USBOTG_DATA_5 IOMUX_PAD(0x6ec, 0x288, 2, 0x9b8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__CSPI2_SCLK IOMUX_PAD(0x6ec, 0x288, 4, 0x7e0, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__GPIO2_16 IOMUX_PAD(0x6ec, 0x288, 5, 0x884, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__IPU_DIAGB_10 IOMUX_PAD(0x6ec, 0x288, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA3__ARM11P_TOP_TRACE_29 IOMUX_PAD(0x6ec, 0x288, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA4__ATA_DATA_4 IOMUX_PAD(0x6f0, 0x28c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA4__ESDHC3_CMD IOMUX_PAD(0x6f0, 0x28c, 1, 0x818, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA4__USB_TOP_USBOTG_DATA_6 IOMUX_PAD(0x6f0, 0x28c, 2, 0x9bc, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA4__GPIO2_17 IOMUX_PAD(0x6f0, 0x28c, 5, 0x888, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA4__IPU_DIAGB_11 IOMUX_PAD(0x6f0, 0x28c, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA4__ARM11P_TOP_TRACE_30 IOMUX_PAD(0x6f0, 0x28c, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA5__ATA_DATA_5 IOMUX_PAD(0x6f4, 0x290, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA5__USB_TOP_USBOTG_DATA_7 IOMUX_PAD(0x6f4, 0x290, 2, 0x9c0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA5__GPIO2_18 IOMUX_PAD(0x6f4, 0x290, 5, 0x88c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA5__IPU_DIAGB_12 IOMUX_PAD(0x6f4, 0x290, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA5__ARM11P_TOP_TRACE_31 IOMUX_PAD(0x6f4, 0x290, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA6__ATA_DATA_6 IOMUX_PAD(0x6f8, 0x294, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA6__CAN1_TXCAN IOMUX_PAD(0x6f8, 0x294, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA6__UART1_DTR IOMUX_PAD(0x6f8, 0x294, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA6__AUDMUX_AUD6_TXD IOMUX_PAD(0x6f8, 0x294, 3, 0x7b4, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA6__GPIO2_19 IOMUX_PAD(0x6f8, 0x294, 5, 0x890, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA6__IPU_DIAGB_13 IOMUX_PAD(0x6f8, 0x294, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA7__ATA_DATA_7 IOMUX_PAD(0x6fc, 0x298, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA7__CAN1_RXCAN IOMUX_PAD(0x6fc, 0x298, 1, 0x7c8, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA7__UART1_DSR IOMUX_PAD(0x6fc, 0x298, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA7__AUDMUX_AUD6_RXD IOMUX_PAD(0x6fc, 0x298, 3, 0x7b0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA7__GPIO2_20 IOMUX_PAD(0x6fc, 0x298, 5, 0x898, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA7__IPU_DIAGB_14 IOMUX_PAD(0x6fc, 0x298, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA8__ATA_DATA_8 IOMUX_PAD(0x700, 0x29c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA8__UART3_RTS IOMUX_PAD(0x700, 0x29c, 1, 0x99c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA8__UART1_RI IOMUX_PAD(0x700, 0x29c, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA8__AUDMUX_AUD6_TXC IOMUX_PAD(0x700, 0x29c, 3, 0x7c0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA8__GPIO2_21 IOMUX_PAD(0x700, 0x29c, 5, 0x89c, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA8__IPU_DIAGB_15 IOMUX_PAD(0x700, 0x29c, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA9__ATA_DATA_9 IOMUX_PAD(0x704, 0x2a0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA9__UART3_CTS IOMUX_PAD(0x704, 0x2a0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA9__UART1_DCD IOMUX_PAD(0x704, 0x2a0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA9__AUDMUX_AUD6_TXFS IOMUX_PAD(0x704, 0x2a0, 3, 0x7c4, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA9__GPIO2_22 IOMUX_PAD(0x704, 0x2a0, 5, 0x8a0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA9__IPU_DIAGB_16 IOMUX_PAD(0x704, 0x2a0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA10__ATA_DATA_10 IOMUX_PAD(0x708, 0x2a4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA10__UART3_RXD_MUX IOMUX_PAD(0x708, 0x2a4, 1, 0x9a0, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA10__AUDMUX_AUD6_RXC IOMUX_PAD(0x708, 0x2a4, 3, 0x7b8, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA10__GPIO2_23 IOMUX_PAD(0x708, 0x2a4, 5, 0x8a4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA10__IPU_DIAGB_17 IOMUX_PAD(0x708, 0x2a4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA11__ATA_DATA_11 IOMUX_PAD(0x70c, 0x2a8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA11__UART3_TXD_MUX IOMUX_PAD(0x70c, 0x2a8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA11__AUDMUX_AUD6_RXFS IOMUX_PAD(0x70c, 0x2a8, 3, 0x7bc, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA11__GPIO2_24 IOMUX_PAD(0x70c, 0x2a8, 5, 0x8a8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA11__IPU_DIAGB_18 IOMUX_PAD(0x70c, 0x2a8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA12__ATA_DATA_12 IOMUX_PAD(0x710, 0x2ac, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA12__I2C3_SCL IOMUX_PAD(0x710, 0x2ac, 1, 0x91c, 3, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA12__GPIO2_25 IOMUX_PAD(0x710, 0x2ac, 5, 0x8ac, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA12__IPU_DIAGB_19 IOMUX_PAD(0x710, 0x2ac, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA13__ATA_DATA_13 IOMUX_PAD(0x714, 0x2b0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA13__I2C3_SDA IOMUX_PAD(0x714, 0x2b0, 1, 0x920, 3, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA13__GPIO2_26 IOMUX_PAD(0x714, 0x2b0, 5, 0x8b0, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA13__IPU_DIAGB_20 IOMUX_PAD(0x714, 0x2b0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA14__ATA_DATA_14 IOMUX_PAD(0x718, 0x2b4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA14__IPU_CSI_D_0 IOMUX_PAD(0x718, 0x2b4, 1, 0x930, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA14__KPP_ROW_0 IOMUX_PAD(0x718, 0x2b4, 3, 0x970, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA14__GPIO2_27 IOMUX_PAD(0x718, 0x2b4, 5, 0x8b4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA14__IPU_DIAGB_21 IOMUX_PAD(0x718, 0x2b4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DATA15__ATA_DATA_15 IOMUX_PAD(0x71c, 0x2b8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA15__IPU_CSI_D_1 IOMUX_PAD(0x71c, 0x2b8, 1, 0x934, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA15__KPP_ROW_1 IOMUX_PAD(0x71c, 0x2b8, 3, 0x974, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA15__GPIO2_28 IOMUX_PAD(0x71c, 0x2b8, 5, 0x8b8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DATA15__IPU_DIAGB_22 IOMUX_PAD(0x71c, 0x2b8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_INTRQ__ATA_INTRQ IOMUX_PAD(0x720, 0x2bc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_INTRQ__IPU_CSI_D_2 IOMUX_PAD(0x720, 0x2bc, 1, 0x938, 3, NO_PAD_CTRL)
+#define MX35_PAD_ATA_INTRQ__KPP_ROW_2 IOMUX_PAD(0x720, 0x2bc, 3, 0x978, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_INTRQ__GPIO2_29 IOMUX_PAD(0x720, 0x2bc, 5, 0x8bc, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_INTRQ__IPU_DIAGB_23 IOMUX_PAD(0x720, 0x2bc, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_BUFF_EN__ATA_BUFFER_EN IOMUX_PAD(0x724, 0x2c0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_BUFF_EN__IPU_CSI_D_3 IOMUX_PAD(0x724, 0x2c0, 1, 0x93c, 3, NO_PAD_CTRL)
+#define MX35_PAD_ATA_BUFF_EN__KPP_ROW_3 IOMUX_PAD(0x724, 0x2c0, 3, 0x97c, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_BUFF_EN__GPIO2_30 IOMUX_PAD(0x724, 0x2c0, 5, 0x8c4, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_BUFF_EN__IPU_DIAGB_24 IOMUX_PAD(0x724, 0x2c0, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DMARQ__ATA_DMARQ IOMUX_PAD(0x728, 0x2c4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMARQ__IPU_CSI_D_4 IOMUX_PAD(0x728, 0x2c4, 1, 0x940, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMARQ__KPP_COL_0 IOMUX_PAD(0x728, 0x2c4, 3, 0x950, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMARQ__GPIO2_31 IOMUX_PAD(0x728, 0x2c4, 5, 0x8c8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMARQ__IPU_DIAGB_25 IOMUX_PAD(0x728, 0x2c4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DMARQ__ECT_CTI_TRIG_IN1_4 IOMUX_PAD(0x728, 0x2c4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DA0__ATA_DA_0 IOMUX_PAD(0x72c, 0x2c8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA0__IPU_CSI_D_5 IOMUX_PAD(0x72c, 0x2c8, 1, 0x944, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA0__KPP_COL_1 IOMUX_PAD(0x72c, 0x2c8, 3, 0x954, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA0__GPIO3_0 IOMUX_PAD(0x72c, 0x2c8, 5, 0x8e8, 1, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA0__IPU_DIAGB_26 IOMUX_PAD(0x72c, 0x2c8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA0__ECT_CTI_TRIG_IN1_5 IOMUX_PAD(0x72c, 0x2c8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DA1__ATA_DA_1 IOMUX_PAD(0x730, 0x2cc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA1__IPU_CSI_D_6 IOMUX_PAD(0x730, 0x2cc, 1, 0x948, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA1__KPP_COL_2 IOMUX_PAD(0x730, 0x2cc, 3, 0x958, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA1__GPIO3_1 IOMUX_PAD(0x730, 0x2cc, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA1__IPU_DIAGB_27 IOMUX_PAD(0x730, 0x2cc, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA1__ECT_CTI_TRIG_IN1_6 IOMUX_PAD(0x730, 0x2cc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_ATA_DA2__ATA_DA_2 IOMUX_PAD(0x734, 0x2d0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA2__IPU_CSI_D_7 IOMUX_PAD(0x734, 0x2d0, 1, 0x94c, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA2__KPP_COL_3 IOMUX_PAD(0x734, 0x2d0, 3, 0x95c, 2, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA2__GPIO3_2 IOMUX_PAD(0x734, 0x2d0, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA2__IPU_DIAGB_28 IOMUX_PAD(0x734, 0x2d0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_ATA_DA2__ECT_CTI_TRIG_IN1_7 IOMUX_PAD(0x734, 0x2d0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_MLB_CLK__MLB_MLBCLK IOMUX_PAD(0x738, 0x2d4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_MLB_CLK__GPIO3_3 IOMUX_PAD(0x738, 0x2d4, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_MLB_DAT__MLB_MLBDAT IOMUX_PAD(0x73c, 0x2d8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_MLB_DAT__GPIO3_4 IOMUX_PAD(0x73c, 0x2d8, 5, 0x904, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_MLB_SIG__MLB_MLBSIG IOMUX_PAD(0x740, 0x2dc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_MLB_SIG__GPIO3_5 IOMUX_PAD(0x740, 0x2dc, 5, 0x908, 1, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TX_CLK__FEC_TX_CLK IOMUX_PAD(0x744, 0x2e0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__ESDHC1_DAT4 IOMUX_PAD(0x744, 0x2e0, 1, 0x804, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__UART3_RXD_MUX IOMUX_PAD(0x744, 0x2e0, 2, 0x9a0, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__USB_TOP_USBH2_DIR IOMUX_PAD(0x744, 0x2e0, 3, 0x9ec, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__CSPI2_MOSI IOMUX_PAD(0x744, 0x2e0, 4, 0x7ec, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__GPIO3_6 IOMUX_PAD(0x744, 0x2e0, 5, 0x90c, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__IPU_DISPB_D12_VSYNC IOMUX_PAD(0x744, 0x2e0, 6, 0x928, 5, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_CLK__ARM11P_TOP_EVNTBUS_0 IOMUX_PAD(0x744, 0x2e0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RX_CLK__FEC_RX_CLK IOMUX_PAD(0x748, 0x2e4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__ESDHC1_DAT5 IOMUX_PAD(0x748, 0x2e4, 1, 0x808, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__UART3_TXD_MUX IOMUX_PAD(0x748, 0x2e4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__USB_TOP_USBH2_STP IOMUX_PAD(0x748, 0x2e4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__CSPI2_MISO IOMUX_PAD(0x748, 0x2e4, 4, 0x7e8, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__GPIO3_7 IOMUX_PAD(0x748, 0x2e4, 5, 0x910, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__IPU_DISPB_SD_D_I IOMUX_PAD(0x748, 0x2e4, 6, 0x92c, 4, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_CLK__ARM11P_TOP_EVNTBUS_1 IOMUX_PAD(0x748, 0x2e4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RX_DV__FEC_RX_DV IOMUX_PAD(0x74c, 0x2e8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__ESDHC1_DAT6 IOMUX_PAD(0x74c, 0x2e8, 1, 0x80c, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__UART3_RTS IOMUX_PAD(0x74c, 0x2e8, 2, 0x99c, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__USB_TOP_USBH2_NXT IOMUX_PAD(0x74c, 0x2e8, 3, 0x9f0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__CSPI2_SCLK IOMUX_PAD(0x74c, 0x2e8, 4, 0x7e0, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__GPIO3_8 IOMUX_PAD(0x74c, 0x2e8, 5, 0x914, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__IPU_DISPB_SD_CLK IOMUX_PAD(0x74c, 0x2e8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_DV__ARM11P_TOP_EVNTBUS_2 IOMUX_PAD(0x74c, 0x2e8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_COL__FEC_COL IOMUX_PAD(0x750, 0x2ec, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__ESDHC1_DAT7 IOMUX_PAD(0x750, 0x2ec, 1, 0x810, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__UART3_CTS IOMUX_PAD(0x750, 0x2ec, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__USB_TOP_USBH2_DATA_0 IOMUX_PAD(0x750, 0x2ec, 3, 0x9cc, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__CSPI2_RDY IOMUX_PAD(0x750, 0x2ec, 4, 0x7e4, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__GPIO3_9 IOMUX_PAD(0x750, 0x2ec, 5, 0x918, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__IPU_DISPB_SER_RS IOMUX_PAD(0x750, 0x2ec, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_COL__ARM11P_TOP_EVNTBUS_3 IOMUX_PAD(0x750, 0x2ec, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RDATA0__FEC_RDATA_0 IOMUX_PAD(0x754, 0x2f0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__PWM_PWMO IOMUX_PAD(0x754, 0x2f0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__UART3_DTR IOMUX_PAD(0x754, 0x2f0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__USB_TOP_USBH2_DATA_1 IOMUX_PAD(0x754, 0x2f0, 3, 0x9d0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__CSPI2_SS0 IOMUX_PAD(0x754, 0x2f0, 4, 0x7f0, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__GPIO3_10 IOMUX_PAD(0x754, 0x2f0, 5, 0x8ec, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__IPU_DISPB_CS1 IOMUX_PAD(0x754, 0x2f0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA0__ARM11P_TOP_EVNTBUS_4 IOMUX_PAD(0x754, 0x2f0, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TDATA0__FEC_TDATA_0 IOMUX_PAD(0x758, 0x2f4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__SPDIF_SPDIF_OUT1 IOMUX_PAD(0x758, 0x2f4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__UART3_DSR IOMUX_PAD(0x758, 0x2f4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__USB_TOP_USBH2_DATA_2 IOMUX_PAD(0x758, 0x2f4, 3, 0x9d4, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__CSPI2_SS1 IOMUX_PAD(0x758, 0x2f4, 4, 0x7f4, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__GPIO3_11 IOMUX_PAD(0x758, 0x2f4, 5, 0x8f0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__IPU_DISPB_CS0 IOMUX_PAD(0x758, 0x2f4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA0__ARM11P_TOP_EVNTBUS_5 IOMUX_PAD(0x758, 0x2f4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x75c, 0x2f8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__SPDIF_SPDIF_IN1 IOMUX_PAD(0x75c, 0x2f8, 1, 0x998, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__UART3_RI IOMUX_PAD(0x75c, 0x2f8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__USB_TOP_USBH2_DATA_3 IOMUX_PAD(0x75c, 0x2f8, 3, 0x9d8, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__GPIO3_12 IOMUX_PAD(0x75c, 0x2f8, 5, 0x8f4, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__IPU_DISPB_PAR_RS IOMUX_PAD(0x75c, 0x2f8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_EN__ARM11P_TOP_EVNTBUS_6 IOMUX_PAD(0x75c, 0x2f8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x760, 0x2fc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__CAN2_TXCAN IOMUX_PAD(0x760, 0x2fc, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__UART3_DCD IOMUX_PAD(0x760, 0x2fc, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__USB_TOP_USBH2_DATA_4 IOMUX_PAD(0x760, 0x2fc, 3, 0x9dc, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__GPIO3_13 IOMUX_PAD(0x760, 0x2fc, 5, 0x8f8, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__IPU_DISPB_WR IOMUX_PAD(0x760, 0x2fc, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDC__ARM11P_TOP_EVNTBUS_7 IOMUX_PAD(0x760, 0x2fc, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x764, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDIO__CAN2_RXCAN IOMUX_PAD(0x764, 0x300, 1, 0x7cc, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDIO__USB_TOP_USBH2_DATA_5 IOMUX_PAD(0x764, 0x300, 3, 0x9e0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDIO__GPIO3_14 IOMUX_PAD(0x764, 0x300, 5, 0x8fc, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDIO__IPU_DISPB_RD IOMUX_PAD(0x764, 0x300, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_MDIO__ARM11P_TOP_EVNTBUS_8 IOMUX_PAD(0x764, 0x300, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TX_ERR__FEC_TX_ERR IOMUX_PAD(0x768, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__OWIRE_LINE IOMUX_PAD(0x768, 0x304, 1, 0x990, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__SPDIF_SPDIF_EXTCLK IOMUX_PAD(0x768, 0x304, 2, 0x994, 4, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__USB_TOP_USBH2_DATA_6 IOMUX_PAD(0x768, 0x304, 3, 0x9e4, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__GPIO3_15 IOMUX_PAD(0x768, 0x304, 5, 0x900, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__IPU_DISPB_D0_VSYNC IOMUX_PAD(0x768, 0x304, 6, 0x924, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TX_ERR__ARM11P_TOP_EVNTBUS_9 IOMUX_PAD(0x768, 0x304, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RX_ERR__FEC_RX_ERR IOMUX_PAD(0x76c, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_ERR__IPU_CSI_D_0 IOMUX_PAD(0x76c, 0x308, 1, 0x930, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_ERR__USB_TOP_USBH2_DATA_7 IOMUX_PAD(0x76c, 0x308, 3, 0x9e8, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_ERR__KPP_COL_4 IOMUX_PAD(0x76c, 0x308, 4, 0x960, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_ERR__GPIO3_16 IOMUX_PAD(0x76c, 0x308, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RX_ERR__IPU_DISPB_SD_D_IO IOMUX_PAD(0x76c, 0x308, 6, 0x92c, 5, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_CRS__FEC_CRS IOMUX_PAD(0x770, 0x30c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_CRS__IPU_CSI_D_1 IOMUX_PAD(0x770, 0x30c, 1, 0x934, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_CRS__USB_TOP_USBH2_PWR IOMUX_PAD(0x770, 0x30c, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_CRS__KPP_COL_5 IOMUX_PAD(0x770, 0x30c, 4, 0x964, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_CRS__GPIO3_17 IOMUX_PAD(0x770, 0x30c, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_CRS__IPU_FLASH_STROBE IOMUX_PAD(0x770, 0x30c, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RDATA1__FEC_RDATA_1 IOMUX_PAD(0x774, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__IPU_CSI_D_2 IOMUX_PAD(0x774, 0x310, 1, 0x938, 4, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__AUDMUX_AUD6_RXC IOMUX_PAD(0x774, 0x310, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__USB_TOP_USBH2_OC IOMUX_PAD(0x774, 0x310, 3, 0x9f4, 2, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__KPP_COL_6 IOMUX_PAD(0x774, 0x310, 4, 0x968, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__GPIO3_18 IOMUX_PAD(0x774, 0x310, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA1__IPU_DISPB_BE0 IOMUX_PAD(0x774, 0x310, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TDATA1__FEC_TDATA_1 IOMUX_PAD(0x778, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA1__IPU_CSI_D_3 IOMUX_PAD(0x778, 0x314, 1, 0x93c, 4, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA1__AUDMUX_AUD6_RXFS IOMUX_PAD(0x778, 0x314, 2, 0x7bc, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA1__KPP_COL_7 IOMUX_PAD(0x778, 0x314, 4, 0x96c, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA1__GPIO3_19 IOMUX_PAD(0x778, 0x314, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA1__IPU_DISPB_BE1 IOMUX_PAD(0x778, 0x314, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RDATA2__FEC_RDATA_2 IOMUX_PAD(0x77c, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA2__IPU_CSI_D_4 IOMUX_PAD(0x77c, 0x318, 1, 0x940, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA2__AUDMUX_AUD6_TXD IOMUX_PAD(0x77c, 0x318, 2, 0x7b4, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA2__KPP_ROW_4 IOMUX_PAD(0x77c, 0x318, 4, 0x980, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA2__GPIO3_20 IOMUX_PAD(0x77c, 0x318, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TDATA2__FEC_TDATA_2 IOMUX_PAD(0x780, 0x31c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA2__IPU_CSI_D_5 IOMUX_PAD(0x780, 0x31c, 1, 0x944, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA2__AUDMUX_AUD6_RXD IOMUX_PAD(0x780, 0x31c, 2, 0x7b0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA2__KPP_ROW_5 IOMUX_PAD(0x780, 0x31c, 4, 0x984, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA2__GPIO3_21 IOMUX_PAD(0x780, 0x31c, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_RDATA3__FEC_RDATA_3 IOMUX_PAD(0x784, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA3__IPU_CSI_D_6 IOMUX_PAD(0x784, 0x320, 1, 0x948, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA3__AUDMUX_AUD6_TXC IOMUX_PAD(0x784, 0x320, 2, 0x7c0, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA3__KPP_ROW_6 IOMUX_PAD(0x784, 0x320, 4, 0x988, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_RDATA3__GPIO3_22 IOMUX_PAD(0x784, 0x320, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_FEC_TDATA3__FEC_TDATA_3 IOMUX_PAD(0x788, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA3__IPU_CSI_D_7 IOMUX_PAD(0x788, 0x324, 1, 0x94c, 3, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA3__AUDMUX_AUD6_TXFS IOMUX_PAD(0x788, 0x324, 2, 0x7c4, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA3__KPP_ROW_7 IOMUX_PAD(0x788, 0x324, 4, 0x98c, 1, NO_PAD_CTRL)
+#define MX35_PAD_FEC_TDATA3__GPIO3_23 IOMUX_PAD(0x788, 0x324, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_EXT_ARMCLK__CCM_EXT_ARMCLK IOMUX_PAD(0x78c, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX35_PAD_TEST_MODE__TCU_TEST_MODE IOMUX_PAD(0x790, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+
+
+#endif /* __MACH_IOMUX_MX35_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx50.h b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
new file mode 100644
index 00000000..16d26e7e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
@@ -0,0 +1,979 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_IOMUX_MX50_H__
+#define __MACH_IOMUX_MX50_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX50_ELCDIF_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+
+#define MX50_SD_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_UART_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE)
+
+#define MX50_I2C_PAD_CTRL (PAD_CTL_ODE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_HYS)
+
+#define MX50_USB_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP)
+
+#define MX50_FEC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH)
+
+#define MX50_OWIRE_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
+
+#define MX50_KEYPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_CSPI_SS_PAD (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x2CC, 0x20, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL0__GPIO_4_0 IOMUX_PAD(0x2CC, 0x20, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL0__NANDF_CLE IOMUX_PAD(0x2CC, 0x20, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x2D0, 0x24, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW0__GPIO_4_1 IOMUX_PAD(0x2D0, 0x24, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW0__NANDF_ALE IOMUX_PAD(0x2D0, 0x24, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x2D4, 0x28, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL1__GPIO_4_2 IOMUX_PAD(0x2D4, 0x28, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL1__NANDF_CE0 IOMUX_PAD(0x2D4, 0x28, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x2D8, 0x2C, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW1__GPIO_4_3 IOMUX_PAD(0x2D8, 0x2C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW1__NANDF_CE1 IOMUX_PAD(0x2D8, 0x2C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x2DC, 0x30, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_COL2__GPIO_4_4 IOMUX_PAD(0x2DC, 0x30, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL2__NANDF_CE2 IOMUX_PAD(0x2DC, 0x30, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x2E0, 0x34, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW2__GPIO_4_5 IOMUX_PAD(0x2E0, 0x34, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW2__NANDF_CE3 IOMUX_PAD(0x2E0, 0x34, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x2E4, 0x38, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL3__GPIO_4_6 IOMUX_PAD(0x2E4, 0x38, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_COL3__NANDF_READY IOMUX_PAD(0x2E4, 0x38, 2, 0x7b4, 0, PAD_CTL_PKE | \
+ PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_KEY_COL3__SDMA_EXT0 IOMUX_PAD(0x2E4, 0x38, 6, 0x7b8, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x2E8, 0x3C, 0, 0x0, 0, MX50_KEYPAD_CTRL)
+#define MX50_PAD_KEY_ROW3__GPIO_4_7 IOMUX_PAD(0x2E8, 0x3C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_KEY_ROW3__NANDF_DQS IOMUX_PAD(0x2E8, 0x3C, 2, 0x7b0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_KEY_ROW3__SDMA_EXT1 IOMUX_PAD(0x2E8, 0x3C, 6, 0x7bc, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C1_SCL__I2C1_SCL IOMUX_PAD(0x2EC, 0x40, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C1_SCL__GPIO_6_18 IOMUX_PAD(0x2EC, 0x40, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C1_SCL__UART2_TXD IOMUX_PAD(0x2EC, 0x40, 2, 0x0, 0, MX50_UART_PAD_CTRL)
+
+#define MX50_PAD_I2C1_SDA__I2C1_SDA IOMUX_PAD(0x2F0, 0x44, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C1_SDA__GPIO_6_19 IOMUX_PAD(0x2F0, 0x44, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C1_SDA__UART2_RXD IOMUX_PAD(0x2F0, 0x44, 2, 0x7cc, 1, MX50_UART_PAD_CTRL)
+
+#define MX50_PAD_I2C2_SCL__I2C2_SCL IOMUX_PAD(0x2F4, 0x48, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__GPIO_6_20 IOMUX_PAD(0x2F4, 0x48, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__UART2_CTS IOMUX_PAD(0x2F4, 0x48, 2, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C2_SCL__DCDC_OK IOMUX_PAD(0x2F4, 0x48, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C2_SDA__I2C2_SDA IOMUX_PAD(0x2F8, 0x4C, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__GPIO_6_21 IOMUX_PAD(0x2F8, 0x4C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__UART2_RTS IOMUX_PAD(0x2F8, 0x4C, 2, 0x7c8, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_I2C2_SDA__PWRSTABLE IOMUX_PAD(0x2F8, 0x4C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_I2C3_SCL__I2C3_SCL IOMUX_PAD(0x2FC, 0x50, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__GPIO_6_22 IOMUX_PAD(0x2FC, 0x50, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__FEC_MDC IOMUX_PAD(0x2FC, 0x50, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_I2C3_SCL__PMIC_RDY IOMUX_PAD(0x2FC, 0x50, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__GPT_CAPIN1 IOMUX_PAD(0x2FC, 0x50, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SCL__USBOTG_OC IOMUX_PAD(0x2FC, 0x50, 7, 0x7E8, 0, MX50_USB_PAD_CTRL)
+
+#define MX50_PAD_I2C3_SDA__I2C3_SDA IOMUX_PAD(0x300, 0x54, IOMUX_CONFIG_SION, 0x0, 0, \
+ MX50_I2C_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__GPIO_6_23 IOMUX_PAD(0x300, 0x54, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__FEC_MDIO IOMUX_PAD(0x300, 0x54, 2, 0x774, 0, MX50_FEC_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__PWRFAIL_INT IOMUX_PAD(0x300, 0x54, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__ALARM_DEB IOMUX_PAD(0x300, 0x54, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__GPT_CAPIN1 IOMUX_PAD(0x300, 0x54, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_I2C3_SDA__USBOTG_PWR IOMUX_PAD(0x300, 0x54, 7, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_PWM1__PWM1_PWMO IOMUX_PAD(0x304, 0x58, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM1__GPIO_6_24 IOMUX_PAD(0x304, 0x58, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM1__USBOTG_OC IOMUX_PAD(0x304, 0x58, 2, 0x7E8, 1, MX50_USB_PAD_CTRL)
+#define MX50_PAD_PWM1__GPT_CMPOUT1 IOMUX_PAD(0x304, 0x58, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PWM2__PWM2_PWMO IOMUX_PAD(0x308, 0x5C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__GPIO_6_25 IOMUX_PAD(0x308, 0x5C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__USBOTG_PWR IOMUX_PAD(0x308, 0x5C, 2, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+#define MX50_PAD_PWM2__DCDC_PWM IOMUX_PAD(0x308, 0x5C, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__GPT_CMPOUT2 IOMUX_PAD(0x308, 0x5C, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_PWM2__ANY_PU_RST IOMUX_PAD(0x308, 0x5C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_OWIRE__OWIRE IOMUX_PAD(0x30C, 0x60, 0, 0x0, 0, MX50_OWIRE_PAD_CTRL)
+#define MX50_PAD_OWIRE__GPIO_6_26 IOMUX_PAD(0x30C, 0x60, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__USBH1_OC IOMUX_PAD(0x30C, 0x60, 2, 0x0, 0, MX50_USB_PAD_CTRL)
+#define MX50_PAD_OWIRE__SSI_EXT1_CLK IOMUX_PAD(0x30C, 0x60, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__EPDC_PWRIRQ IOMUX_PAD(0x30C, 0x60, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_OWIRE__GPT_CMPOUT3 IOMUX_PAD(0x30C, 0x60, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPITO__EPITO IOMUX_PAD(0x310, 0x64, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__GPIO_6_27 IOMUX_PAD(0x310, 0x64, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__USBH1_PWR IOMUX_PAD(0x310, 0x64, 2, 0x0, 0, \
+ PAD_CTL_PKE | PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EPITO__SSI_EXT2_CLK IOMUX_PAD(0x310, 0x64, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__TOG_EN IOMUX_PAD(0x310, 0x64, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPITO__GPT_CLKIN IOMUX_PAD(0x310, 0x64, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_WDOG__WDOG IOMUX_PAD(0x314, 0x68, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__GPIO_6_28 IOMUX_PAD(0x314, 0x68, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__WDOG_RST IOMUX_PAD(0x314, 0x68, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_WDOG__XTAL32K IOMUX_PAD(0x314, 0x68, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXFS__SSI_TXFS IOMUX_PAD(0x318, 0x6C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXFS__GPIO_6_0 IOMUX_PAD(0x318, 0x6C, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXC__SSI_TXC IOMUX_PAD(0x31C, 0x70, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXC__GPIO_6_1 IOMUX_PAD(0x31C, 0x70, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_TXD__SSI_TXD IOMUX_PAD(0x320, 0x74, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXD__GPIO_6_2 IOMUX_PAD(0x320, 0x74, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_TXD__CSPI_RDY IOMUX_PAD(0x320, 0x74, 4, 0x6e8, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SSI_RXD__SSI_RXD IOMUX_PAD(0x324, 0x78, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXD__GPIO_6_3 IOMUX_PAD(0x324, 0x78, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXD__CSPI_SS3 IOMUX_PAD(0x324, 0x78, 4, 0x6f4, 0, MX50_CSPI_SS_PAD)
+
+#define MX50_PAD_SSI_RXFS__AUD3_RXFS IOMUX_PAD(0x328, 0x7C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__GPIO_6_4 IOMUX_PAD(0x328, 0x7C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__UART5_TXD IOMUX_PAD(0x328, 0x7C, 2, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__WEIM_D6 IOMUX_PAD(0x328, 0x7C, 3, 0x804, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXFS__CSPI_SS2 IOMUX_PAD(0x328, 0x7C, 4, 0x6f0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_SSI_RXFS__FEC_COL IOMUX_PAD(0x328, 0x7C, 5, 0x770, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SSI_RXFS__FEC_MDC IOMUX_PAD(0x328, 0x7C, 6, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_SSI_RXC__AUD3_RXC IOMUX_PAD(0x32C, 0x80, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__GPIO_6_5 IOMUX_PAD(0x32C, 0x80, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__UART5_RXD IOMUX_PAD(0x32C, 0x80, 2, 0x7e4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__WEIM_D7 IOMUX_PAD(0x32C, 0x80, 3, 0x808, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__CSPI_SS1 IOMUX_PAD(0x32C, 0x80, 4, 0x6ec, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_SSI_RXC__FEC_RX_CLK IOMUX_PAD(0x32C, 0x80, 5, 0x780, 0, NO_PAD_CTRL)
+#define MX50_PAD_SSI_RXC__FEC_MDIO IOMUX_PAD(0x32C, 0x80, 6, 0x774, 1, MX50_FEC_PAD_CTRL)
+
+#define MX50_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x330, 0x84, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_TXD__GPIO_6_6 IOMUX_PAD(0x330, 0x84, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x334, 0x88, 0, 0x7c4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RXD__GPIO_6_7 IOMUX_PAD(0x334, 0x88, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x338, 0x8C, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__GPIO_6_8 IOMUX_PAD(0x338, 0x8C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__UART5_TXD IOMUX_PAD(0x338, 0x8C, 2, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__SD4_D4 IOMUX_PAD(0x338, 0x8C, 4, 0x760, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_CTS__SD4_CMD IOMUX_PAD(0x338, 0x8C, 5, 0x74c, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x33C, 0x90, 0, 0x7c0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__GPIO_6_9 IOMUX_PAD(0x33C, 0x90, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__UART5_RXD IOMUX_PAD(0x33C, 0x90, 2, 0x7e4, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_D5 IOMUX_PAD(0x33C, 0x90, 4, 0x764, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART1_RTS__SD4_CLK IOMUX_PAD(0x33C, 0x90, 5, 0x748, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x340, 0x94, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__GPIO_6_10 IOMUX_PAD(0x340, 0x94, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__SD4_D6 IOMUX_PAD(0x340, 0x94, 4, 0x768, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_TXD__SD4_D4 IOMUX_PAD(0x340, 0x94, 5, 0x760, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x344, 0x98, 0, 0x7cc, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__GPIO_6_11 IOMUX_PAD(0x344, 0x98, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__SD4_D7 IOMUX_PAD(0x344, 0x98, 4, 0x76c, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_RXD__SD4_D5 IOMUX_PAD(0x344, 0x98, 5, 0x764, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_CTS__UART2_CTS IOMUX_PAD(0x348, 0x9C, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__GPIO_6_12 IOMUX_PAD(0x348, 0x9C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__SD4_CMD IOMUX_PAD(0x348, 0x9C, 4, 0x74c, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_CTS__SD4_D6 IOMUX_PAD(0x348, 0x9C, 5, 0x768, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART2_RTS__UART2_RTS IOMUX_PAD(0x34C, 0xA0, 0, 0x7c8, 3, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__GPIO_6_13 IOMUX_PAD(0x34C, 0xA0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__SD4_CLK IOMUX_PAD(0x34C, 0xA0, 4, 0x748, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART2_RTS__SD4_D7 IOMUX_PAD(0x34C, 0xA0, 5, 0x76c, 1, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x350, 0xA4, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__GPIO_6_14 IOMUX_PAD(0x350, 0xA4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD1_D4 IOMUX_PAD(0x350, 0xA4, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD4_D0 IOMUX_PAD(0x350, 0xA4, 4, 0x750, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__SD2_WP IOMUX_PAD(0x350, 0xA4, 5, 0x744, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_TXD__WEIM_D12 IOMUX_PAD(0x350, 0xA4, 6, 0x81c, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x354, 0xA8, 0, 0x7d4, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__GPIO_6_15 IOMUX_PAD(0x354, 0xA8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD1_D5 IOMUX_PAD(0x354, 0xA8, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD4_D1 IOMUX_PAD(0x354, 0xA8, 4, 0x754, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__SD2_CD IOMUX_PAD(0x354, 0xA8, 5, 0x740, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART3_RXD__WEIM_D13 IOMUX_PAD(0x354, 0xA8, 6, 0x820, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART4_TXD__UART4_TXD IOMUX_PAD(0x358, 0xAC, 0, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__GPIO_6_16 IOMUX_PAD(0x358, 0xAC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__UART3_CTS IOMUX_PAD(0x358, 0xAC, 2, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD1_D6 IOMUX_PAD(0x358, 0xAC, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD4_D2 IOMUX_PAD(0x358, 0xAC, 4, 0x758, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__SD2_LCTL IOMUX_PAD(0x358, 0xAC, 5, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_TXD__WEIM_D14 IOMUX_PAD(0x358, 0xAC, 6, 0x824, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_UART4_RXD__UART4_RXD IOMUX_PAD(0x35C, 0xB0, 0, 0x7dc, 1, MX50_UART_PAD_CTRL)
+/* Remove the default keeper from this pad (for EPD PMIC intr) */
+#define MX50_PAD_UART4_RXD__GPIO_6_17 IOMUX_PAD(0x35C, 0xB0, 1, 0x0, 0, 0)
+#define MX50_PAD_UART4_RXD__UART3_RTS IOMUX_PAD(0x35C, 0xB0, 2, 0x7d0, 1, MX50_UART_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD1_D7 IOMUX_PAD(0x35C, 0xB0, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD4_D3 IOMUX_PAD(0x35C, 0xB0, 4, 0x75c, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__SD1_LCTL IOMUX_PAD(0x35C, 0xB0, 5, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_UART4_RXD__WEIM_D15 IOMUX_PAD(0x35C, 0xB0, 6, 0x828, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_SCLK__CSPI_SCLK IOMUX_PAD(0x360, 0xB4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_SCLK__GPIO_4_8 IOMUX_PAD(0x360, 0xB4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_MOSI__CSPI_MOSI IOMUX_PAD(0x364, 0xB8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_MOSI__GPIO_4_9 IOMUX_PAD(0x364, 0xB8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_MISO__CSPI_MISO IOMUX_PAD(0x368, 0xBC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_CSPI_MISO__GPIO_4_10 IOMUX_PAD(0x368, 0xBC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_CSPI_SS0__CSPI_SS0 IOMUX_PAD(0x36C, 0xC0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_CSPI_SS0__GPIO_4_11 IOMUX_PAD(0x36C, 0xC0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x370, 0xC4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__GPIO_4_12 IOMUX_PAD(0x370, 0xC4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__CSPI_RDY IOMUX_PAD(0x370, 0xC4, 2, 0x6e8, 1, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__ECSPI2_RDY IOMUX_PAD(0x370, 0xC4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__UART3_RTS IOMUX_PAD(0x370, 0xC4, 4, 0x7d0, 2, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__EPDC_SDCE6 IOMUX_PAD(0x370, 0xC4, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SCLK__WEIM_D8 IOMUX_PAD(0x370, 0xC4, 7, 0x80c, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x374, 0xC8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__GPIO_4_13 IOMUX_PAD(0x374, 0xC8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__CSPI_SS1 IOMUX_PAD(0x374, 0xC8, 2, 0x6ec, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MOSI__ECSPI2_SS1 IOMUX_PAD(0x374, 0xC8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MOSI__UART3_CTS IOMUX_PAD(0x374, 0xC8, 4, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__EPDC_SDCE7 IOMUX_PAD(0x374, 0xC8, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MOSI__WEIM_D9 IOMUX_PAD(0x374, 0xC8, 7, 0x810, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x378, 0xCC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__GPIO_4_14 IOMUX_PAD(0x378, 0xCC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__CSPI_SS2 IOMUX_PAD(0x378, 0xCC, 2, 0x6f0, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MISO__ECSPI2_SS2 IOMUX_PAD(0x378, 0xCC, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_MISO__UART4_RTS IOMUX_PAD(0x378, 0xCC, 4, 0x7d8, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__EPDC_SDCE8 IOMUX_PAD(0x378, 0xCC, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_MISO__WEIM_D10 IOMUX_PAD(0x378, 0xCC, 7, 0x814, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x37C, 0xD0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__GPIO_4_15 IOMUX_PAD(0x37C, 0xD0, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_ECSPI1_SS0__CSPI_SS3 IOMUX_PAD(0x37C, 0xD0, 2, 0x6f4, 1, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__ECSPI2_SS3 IOMUX_PAD(0x37C, 0xD0, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI1_SS0__UART4_CTS IOMUX_PAD(0x37C, 0xD0, 4, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SS0__EPDC_SDCE9 IOMUX_PAD(0x37C, 0xD0, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI1_SS0__WEIM_D11 IOMUX_PAD(0x37C, 0xD0, 7, 0x818, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_SCLK__ECSPI2_SCLK IOMUX_PAD(0x380, 0xD4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__GPIO_4_16 IOMUX_PAD(0x380, 0xD4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_WR IOMUX_PAD(0x380, 0xD4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ECSPI1_RDY IOMUX_PAD(0x380, 0xD4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__UART5_RTS IOMUX_PAD(0x380, 0xD4, 4, 0x7e0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__ELCDIF_DOTCLK IOMUX_PAD(0x380, 0xD4, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__NANDF_CEN4 IOMUX_PAD(0x380, 0xD4, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SCLK__WEIM_D8 IOMUX_PAD(0x380, 0xD4, 7, 0x80c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_MOSI__ECSPI2_MOSI IOMUX_PAD(0x384, 0xD8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__GPIO_4_17 IOMUX_PAD(0x384, 0xD8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_RD IOMUX_PAD(0x384, 0xD8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ECSPI1_SS1 IOMUX_PAD(0x384, 0xD8, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_MOSI__UART5_CTS IOMUX_PAD(0x384, 0xD8, 4, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__ELCDIF_EN IOMUX_PAD(0x384, 0xD8, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__NANDF_CEN5 IOMUX_PAD(0x384, 0xD8, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MOSI__WEIM_D9 IOMUX_PAD(0x384, 0xD8, 7, 0x810, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_MISO__ECSPI2_MISO IOMUX_PAD(0x388, 0xDC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__GPIO_4_18 IOMUX_PAD(0x388, 0xDC, 1, 0x0, 0, PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_RS IOMUX_PAD(0x388, 0xDC, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ECSPI1_SS2 IOMUX_PAD(0x388, 0xDC, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_MISO__UART5_TXD IOMUX_PAD(0x388, 0xDC, 4, 0x0, 0, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__ELCDIF_VSYNC IOMUX_PAD(0x388, 0xDC, 5, 0x73c, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__NANDF_CEN6 IOMUX_PAD(0x388, 0xDC, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_MISO__WEIM_D10 IOMUX_PAD(0x388, 0xDC, 7, 0x814, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_ECSPI2_SS0__ECSPI2_SS0 IOMUX_PAD(0x38C, 0xE0, 0, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_SS0__GPIO_4_19 IOMUX_PAD(0x38C, 0xE0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_CS IOMUX_PAD(0x38C, 0xE0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ECSPI1_SS3 IOMUX_PAD(0x38C, 0xE0, 3, 0x0, 0, MX50_CSPI_SS_PAD)
+#define MX50_PAD_ECSPI2_SS0__UART5_RXD IOMUX_PAD(0x38C, 0xE0, 4, 0x7e4, 5, MX50_UART_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__ELCDIF_HSYNC IOMUX_PAD(0x38C, 0xE0, 5, 0x6f8, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__NANDF_CEN7 IOMUX_PAD(0x38C, 0xE0, 6, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_ECSPI2_SS0__WEIM_D11 IOMUX_PAD(0x38C, 0xE0, 7, 0x818, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x390, 0xE4, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_CLK__GPIO_5_0 IOMUX_PAD(0x390, 0xE4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_CLK__CLKO IOMUX_PAD(0x390, 0xE4, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x394, 0xE8, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_CMD__GPIO_5_1 IOMUX_PAD(0x394, 0xE8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_CMD__CLKO2 IOMUX_PAD(0x394, 0xE8, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D0__SD1_D0 IOMUX_PAD(0x398, 0xEC, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D0__GPIO_5_2 IOMUX_PAD(0x398, 0xEC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D0__PLL1_BYP IOMUX_PAD(0x398, 0xEC, 7, 0x6dc, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D1__SD1_D1 IOMUX_PAD(0x39C, 0xF0, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D1__GPIO_5_3 IOMUX_PAD(0x39C, 0xF0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D1__PLL2_BYP IOMUX_PAD(0x39C, 0xF0, 7, 0x6e0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D2__SD1_D2 IOMUX_PAD(0x3A0, 0xF4, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D2__GPIO_5_4 IOMUX_PAD(0x3A0, 0xF4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD1_D2__PLL3_BYP IOMUX_PAD(0x3A0, 0xF4, 7, 0x6e4, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD1_D3__SD1_D3 IOMUX_PAD(0x3A4, 0xF8, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD1_D3__GPIO_5_5 IOMUX_PAD(0x3A4, 0xF8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x3A8, 0xFC, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CLK__GPIO_5_6 IOMUX_PAD(0x3A8, 0xFC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CLK__MSHC_SCLK IOMUX_PAD(0x3A8, 0xFC, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x3AC, 0x100, IOMUX_CONFIG_SION, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CMD__GPIO_5_7 IOMUX_PAD(0x3AC, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CMD__MSHC_BS IOMUX_PAD(0x3AC, 0x100, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+
+#define MX50_PAD_SD2_D0__SD2_D0 IOMUX_PAD(0x3B0, 0x104, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D0__GPIO_5_8 IOMUX_PAD(0x3B0, 0x104, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D0__MSHC_D0 IOMUX_PAD(0x3B0, 0x104, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D0__KEY_COL4 IOMUX_PAD(0x3B0, 0x104, 3, 0x790, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D1__SD2_D1 IOMUX_PAD(0x3B4, 0x108, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D1__GPIO_5_9 IOMUX_PAD(0x3B4, 0x108, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D1__MSHC_D1 IOMUX_PAD(0x3B4, 0x108, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D1__KEY_ROW4 IOMUX_PAD(0x3B4, 0x108, 3, 0x7a0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D2__SD2_D2 IOMUX_PAD(0x3B8, 0x10C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D2__GPIO_5_10 IOMUX_PAD(0x3B8, 0x10C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D2__MSHC_D2 IOMUX_PAD(0x3B8, 0x10C, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D2__KEY_COL5 IOMUX_PAD(0x3B8, 0x10C, 3, 0x794, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D3__SD2_D3 IOMUX_PAD(0x3BC, 0x110, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D3__GPIO_5_11 IOMUX_PAD(0x3BC, 0x110, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D3__MSHC_D3 IOMUX_PAD(0x3BC, 0x110, 2, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D3__KEY_ROW5 IOMUX_PAD(0x3BC, 0x110, 3, 0x7a4, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D4__SD2_D4 IOMUX_PAD(0x3C0, 0x114, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D4__GPIO_5_12 IOMUX_PAD(0x3C0, 0x114, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__AUD4_RXFS IOMUX_PAD(0x3C0, 0x114, 2, 0x6d0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__KEY_COL6 IOMUX_PAD(0x3C0, 0x114, 3, 0x798, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__WEIM_D0 IOMUX_PAD(0x3C0, 0x114, 4, 0x7ec, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D4__CCM_OUT0 IOMUX_PAD(0x3C0, 0x114, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D5__SD2_D5 IOMUX_PAD(0x3C4, 0x118, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D5__GPIO_5_13 IOMUX_PAD(0x3C4, 0x118, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__AUD4_RXC IOMUX_PAD(0x3C4, 0x118, 2, 0x6cc, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__KEY_ROW6 IOMUX_PAD(0x3C4, 0x118, 3, 0x7a8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__WEIM_D1 IOMUX_PAD(0x3C4, 0x118, 4, 0x7f0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D5__CCM_OUT1 IOMUX_PAD(0x3C4, 0x118, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D6__SD2_D6 IOMUX_PAD(0x3C8, 0x11C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D6__GPIO_5_14 IOMUX_PAD(0x3C8, 0x11C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__AUD4_RXD IOMUX_PAD(0x3C8, 0x11C, 2, 0x6c4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__KEY_COL7 IOMUX_PAD(0x3C8, 0x11C, 3, 0x79c, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__WEIM_D2 IOMUX_PAD(0x3C8, 0x11C, 4, 0x7f4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D6__CCM_OUT2 IOMUX_PAD(0x3C8, 0x11C, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_D7__SD2_D7 IOMUX_PAD(0x3CC, 0x120, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_D7__GPIO_5_15 IOMUX_PAD(0x3CC, 0x120, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__AUD4_TXFS IOMUX_PAD(0x3CC, 0x120, 2, 0x6d8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__KEY_ROW7 IOMUX_PAD(0x3CC, 0x120, 3, 0x7ac, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__WEIM_D3 IOMUX_PAD(0x3CC, 0x120, 4, 0x7f8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_D7__CCM_STOP IOMUX_PAD(0x3CC, 0x120, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_WP__SD2_WP IOMUX_PAD(0x3D0, 0x124, 0, 0x744, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_WP__GPIO_5_16 IOMUX_PAD(0x3D0, 0x124, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__AUD4_TXD IOMUX_PAD(0x3D0, 0x124, 2, 0x6c8, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__WEIM_D4 IOMUX_PAD(0x3D0, 0x124, 4, 0x7fc, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_WP__CCM_WAIT IOMUX_PAD(0x3D0, 0x124, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD2_CD__SD2_CD IOMUX_PAD(0x3D4, 0x128, 0, 0x740, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD2_CD__GPIO_5_17 IOMUX_PAD(0x3D4, 0x128, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__AUD4_TXC IOMUX_PAD(0x3D4, 0x128, 2, 0x6d4, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__WEIM_D5 IOMUX_PAD(0x3D4, 0x128, 4, 0x800, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD2_CD__CCM_REF_EN IOMUX_PAD(0x3D4, 0x128, 7, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_ON_REQ__PMIC_ON_REQ IOMUX_PAD(0x3D8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_STBY_REQ__PMIC_STBY_REQ IOMUX_PAD(0x3DC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_PORT_B__PMIC_PORT_B IOMUX_PAD(0x3E0, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_BOOT_MODE1__PMIC_BOOT_MODE1 IOMUX_PAD(0x3E4, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_RESET_IN_B__PMIC_RESET_IN_B IOMUX_PAD(0x3E8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_BOOT_MODE0__PMIC_BOOT_MODE0 IOMUX_PAD(0x3EC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_TEST_MODE__PMIC_TEST_MODE IOMUX_PAD(0x3F0, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TMS__PMIC_JTAG_TMS IOMUX_PAD(0x3F4, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_MOD__PMIC_JTAG_MOD IOMUX_PAD(0x3F8, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TRSTB__PMIC_JTAG_TRSTB IOMUX_PAD(0x3FC, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TDI__PMIC_JTAG_TDI IOMUX_PAD(0x400, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TCK__PMIC_JTAG_TCK IOMUX_PAD(0x404, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_PMIC_JTAG_TDO__PMIC_JTAG_TDO IOMUX_PAD(0x408, 0, 0, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D0__DISP_D0 IOMUX_PAD(0x40C, 0x12C, 0, 0x6fc, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D0__GPIO_2_0 IOMUX_PAD(0x40C, 0x12C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D0__FEC_TXCLK IOMUX_PAD(0x40C, 0x12C, 2, 0x78c, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+
+#define MX50_PAD_DISP_D1__DISP_D1 IOMUX_PAD(0x410, 0x130, 0, 0x700, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D1__GPIO_2_1 IOMUX_PAD(0x410, 0x130, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D1__FEC_RX_ER IOMUX_PAD(0x410, 0x130, 2, 0x788, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D1__WEIM_A17 IOMUX_PAD(0x410, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D2__DISP_D2 IOMUX_PAD(0x414, 0x134, 0, 0x704, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D2__GPIO_2_2 IOMUX_PAD(0x414, 0x134, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D2__FEC_RX_DV IOMUX_PAD(0x414, 0x134, 2, 0x784, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D2__WEIM_A18 IOMUX_PAD(0x414, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D3__DISP_D3 IOMUX_PAD(0x418, 0x138, 0, 0x708, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D3__GPIO_2_3 IOMUX_PAD(0x418, 0x138, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D3__FEC_RXD1 IOMUX_PAD(0x418, 0x138, 2, 0x77C, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D3__WEIM_A19 IOMUX_PAD(0x418, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D3__FEC_COL IOMUX_PAD(0x418, 0x138, 4, 0x770, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D4__DISP_D4 IOMUX_PAD(0x41C, 0x13C, 0, 0x70c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D4__GPIO_2_4 IOMUX_PAD(0x41C, 0x13C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D4__FEC_RXD0 IOMUX_PAD(0x41C, 0x13C, 2, 0x778, 0, PAD_CTL_HYS | PAD_CTL_PKE)
+#define MX50_PAD_DISP_D4__WEIM_A20 IOMUX_PAD(0x41C, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D5__DISP_D5 IOMUX_PAD(0x420, 0x140, 0, 0x710, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D5__GPIO_2_5 IOMUX_PAD(0x420, 0x140, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D5__FEC_TX_EN IOMUX_PAD(0x420, 0x140, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D5__WEIM_A21 IOMUX_PAD(0x420, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D6__DISP_D6 IOMUX_PAD(0x424, 0x144, 0, 0x714, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D6__GPIO_2_6 IOMUX_PAD(0x424, 0x144, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D6__FEC_TXD1 IOMUX_PAD(0x424, 0x144, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D6__WEIM_A22 IOMUX_PAD(0x424, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D6__FEC_RX_CLK IOMUX_PAD(0x424, 0x144, 4, 0x780, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D7__DISP_D7 IOMUX_PAD(0x428, 0x148, 0, 0x718, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D7__GPIO_2_7 IOMUX_PAD(0x428, 0x148, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D7__FEC_TXD0 IOMUX_PAD(0x428, 0x148, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_DISP_D7__WEIM_A23 IOMUX_PAD(0x428, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+
+
+#define MX50_PAD_DISP_WR__ELCDIF_WR IOMUX_PAD(0x42C, 0x14C, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_WR__GPIO_2_16 IOMUX_PAD(0x42C, 0x14C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_WR__ELCDIF_PIXCLK IOMUX_PAD(0x42C, 0x14C, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_WR__WEIM_A24 IOMUX_PAD(0x42C, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RD__ELCDIF_RD IOMUX_PAD(0x430, 0x150, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RD__GPIO_2_19 IOMUX_PAD(0x430, 0x150, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RD__ELCDIF_EN IOMUX_PAD(0x430, 0x150, 2, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RD__WEIM_A25 IOMUX_PAD(0x430, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RS__ELCDIF_RS IOMUX_PAD(0x434, 0x154, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RS__GPIO_2_17 IOMUX_PAD(0x434, 0x154, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RS__ELCDIF_VSYNC IOMUX_PAD(0x434, 0x154, 2, 0x73c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RS__WEIM_A26 IOMUX_PAD(0x434, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_CS__ELCDIF_CS IOMUX_PAD(0x438, 0x158, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_CS__GPIO_2_21 IOMUX_PAD(0x438, 0x158, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_CS__ELCDIF_HSYNC IOMUX_PAD(0x438, 0x158, 2, 0x6f8, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_CS__WEIM_A27 IOMUX_PAD(0x438, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_CS__WEIM_CS3 IOMUX_PAD(0x438, 0x158, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_BUSY__ELCDIF_HSYNC IOMUX_PAD(0x43C, 0x15C, 0, 0x6f8, 2, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_BUSY__GPIO_2_18 IOMUX_PAD(0x43C, 0x15C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_BUSY__WEIM_CS3 IOMUX_PAD(0x43C, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_RESET__ELCDIF_RST IOMUX_PAD(0x440, 0x160, 0, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_RESET__GPIO_2_20 IOMUX_PAD(0x440, 0x160, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_RESET__WEIM_CS3 IOMUX_PAD(0x440, 0x160, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_CMD__SD3_CMD IOMUX_PAD(0x444, 0x164, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_CMD__GPIO_5_18 IOMUX_PAD(0x444, 0x164, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_CMD__NANDF_WRN IOMUX_PAD(0x444, 0x164, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_CMD__SSP_CMD IOMUX_PAD(0x444, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_CLK__SD3_CLK IOMUX_PAD(0x448, 0x168, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_CLK__GPIO_5_19 IOMUX_PAD(0x448, 0x168, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_CLK__NANDF_RDN IOMUX_PAD(0x448, 0x168, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_CLK__SSP_CLK IOMUX_PAD(0x448, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D0__SD3_D0 IOMUX_PAD(0x44C, 0x16C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D0__GPIO_5_20 IOMUX_PAD(0x44C, 0x16C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D0__NANDF_D4 IOMUX_PAD(0x44C, 0x16C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D0__SSP_D0 IOMUX_PAD(0x44C, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_D0__PLL1_BYP IOMUX_PAD(0x44C, 0x16C, 7, 0x6dc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D1__SD3_D1 IOMUX_PAD(0x450, 0x170, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D1__GPIO_5_21 IOMUX_PAD(0x450, 0x170, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D1__NANDF_D5 IOMUX_PAD(0x450, 0x170, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D1__PLL2_BYP IOMUX_PAD(0x450, 0x170, 7, 0x6e0, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D2__SD3_D2 IOMUX_PAD(0x454, 0x174, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D2__GPIO_5_22 IOMUX_PAD(0x454, 0x174, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D2__NANDF_D6 IOMUX_PAD(0x454, 0x174, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D2__SSP_D2 IOMUX_PAD(0x454, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_D2__PLL3_BYP IOMUX_PAD(0x454, 0x174, 7, 0x6e4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D3__SD3_D3 IOMUX_PAD(0x458, 0x178, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D3__GPIO_5_23 IOMUX_PAD(0x458, 0x178, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D3__NANDF_D7 IOMUX_PAD(0x458, 0x178, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D3__SSP_D3 IOMUX_PAD(0x458, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D4__SD3_D4 IOMUX_PAD(0x45C, 0x17C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D4__GPIO_5_24 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D4__NANDF_D0 IOMUX_PAD(0x45C, 0x17C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D4__SSP_D4 IOMUX_PAD(0x45C, 0x17C, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D5__SD3_D5 IOMUX_PAD(0x460, 0x180, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D5__GPIO_5_25 IOMUX_PAD(0x460, 0x180, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D5__NANDF_D1 IOMUX_PAD(0x460, 0x180, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D5__SSP_D5 IOMUX_PAD(0x460, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D6__SD3_D6 IOMUX_PAD(0x464, 0x184, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D6__GPIO_5_26 IOMUX_PAD(0x464, 0x184, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D6__NANDF_D2 IOMUX_PAD(0x464, 0x184, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D6__SSP_D6 IOMUX_PAD(0x464, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_D7__SD3_D7 IOMUX_PAD(0x468, 0x188, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_D7__GPIO_5_27 IOMUX_PAD(0x468, 0x188, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_D7__NANDF_D3 IOMUX_PAD(0x468, 0x188, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_D7__SSP_D7 IOMUX_PAD(0x468, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_SD3_WP__SD3_WP IOMUX_PAD(0x46C, 0x18C, 0, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_WP__GPIO_5_28 IOMUX_PAD(0x46C, 0x18C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_SD3_WP__NANDF_RESETN IOMUX_PAD(0x46C, 0x18C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_SD3_WP__SSP_CD IOMUX_PAD(0x46C, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_SD3_WP__SD4_LCTL IOMUX_PAD(0x46C, 0x18C, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_SD3_WP__WEIM_CS3 IOMUX_PAD(0x46C, 0x18C, 5, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D8__DISP_D8 IOMUX_PAD(0x470, 0x190, 0, 0x71c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D8__GPIO_2_8 IOMUX_PAD(0x470, 0x190, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__NANDF_CLE IOMUX_PAD(0x470, 0x190, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__SD1_LCTL IOMUX_PAD(0x470, 0x190, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D8__SD4_CMD IOMUX_PAD(0x470, 0x190, 4, 0x74c, 2, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D8__KEY_COL4 IOMUX_PAD(0x470, 0x190, 5, 0x790, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D8__FEC_TX_CLK IOMUX_PAD(0x470, 0x190, 6, 0x78c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D9__DISP_D9 IOMUX_PAD(0x474, 0x194, 0, 0x720, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D9__GPIO_2_9 IOMUX_PAD(0x474, 0x194, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__NANDF_ALE IOMUX_PAD(0x474, 0x194, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__SD2_LCTL IOMUX_PAD(0x474, 0x194, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D9__SD4_CLK IOMUX_PAD(0x474, 0x194, 4, 0x748, 2, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D9__KEY_ROW4 IOMUX_PAD(0x474, 0x194, 5, 0x7a0, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D9__FEC_RX_ER IOMUX_PAD(0x474, 0x194, 6, 0x788, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D10__DISP_D10 IOMUX_PAD(0x478, 0x198, 0, 0x724, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D10__GPIO_2_10 IOMUX_PAD(0x478, 0x198, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__NANDF_CEN0 IOMUX_PAD(0x478, 0x198, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__SD3_LCTL IOMUX_PAD(0x478, 0x198, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D10__SD4_D0 IOMUX_PAD(0x478, 0x198, 4, 0x750, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D10__KEY_COL5 IOMUX_PAD(0x478, 0x198, 5, 0x794, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D10__FEC_RX_DV IOMUX_PAD(0x478, 0x198, 6, 0x784, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D11__DISP_D11 IOMUX_PAD(0x47C, 0x19C, 0, 0x728, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D11__GPIO_2_11 IOMUX_PAD(0x47C, 0x19C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__NANDF_CEN1 IOMUX_PAD(0x47C, 0x19C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__SD4_D1 IOMUX_PAD(0x47C, 0x19C, 4, 0x754, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D11__KEY_ROW5 IOMUX_PAD(0x47C, 0x19C, 5, 0x7a4, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D11__FEC_RDAT1 IOMUX_PAD(0x47C, 0x19C, 6, 0x77c, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D12__DISP_D12 IOMUX_PAD(0x480, 0x1A0, 0, 0x72c, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D12__GPIO_2_12 IOMUX_PAD(0x480, 0x1A0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__NANDF_CEN2 IOMUX_PAD(0x480, 0x1A0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__SD1_CD IOMUX_PAD(0x480, 0x1A0, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D12__SD4_D2 IOMUX_PAD(0x480, 0x1A0, 4, 0x758, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D12__KEY_COL6 IOMUX_PAD(0x480, 0x1A0, 5, 0x798, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D12__FEC_RDAT0 IOMUX_PAD(0x480, 0x1A0, 6, 0x778, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D13__DISP_D13 IOMUX_PAD(0x484, 0x1A4, 0, 0x730, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D13__GPIO_2_13 IOMUX_PAD(0x484, 0x1A4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__NANDF_CEN3 IOMUX_PAD(0x484, 0x1A4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__SD3_CD IOMUX_PAD(0x484, 0x1A4, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D13__SD4_D3 IOMUX_PAD(0x484, 0x1A4, 4, 0x75c, 1, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D13__KEY_ROW6 IOMUX_PAD(0x484, 0x1A4, 5, 0x7a8, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D13__FEC_TX_EN IOMUX_PAD(0x484, 0x1A4, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D14__DISP_D14 IOMUX_PAD(0x488, 0x1A8, 0, 0x734, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D14__GPIO_2_14 IOMUX_PAD(0x488, 0x1A8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__NANDF_RDY0 IOMUX_PAD(0x488, 0x1A8, 2, 0x7b4, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__SD1_WP IOMUX_PAD(0x488, 0x1A8, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D14__SD4_WP IOMUX_PAD(0x488, 0x1A8, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D14__KEY_COL7 IOMUX_PAD(0x488, 0x1A8, 5, 0x79c, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D14__FEC_TDAT1 IOMUX_PAD(0x488, 0x1A8, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_DISP_D15__DISP_D15 IOMUX_PAD(0x48C, 0x1AC, 0, 0x738, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_DISP_D15__GPIO_2_15 IOMUX_PAD(0x48C, 0x1AC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__NANDF_DQS IOMUX_PAD(0x48C, 0x1AC, 2, 0x7b0, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__SD3_RST IOMUX_PAD(0x48C, 0x1AC, 3, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D15__SD4_CD IOMUX_PAD(0x48C, 0x1AC, 4, 0x0, 0, MX50_SD_PAD_CTRL)
+#define MX50_PAD_DISP_D15__KEY_ROW7 IOMUX_PAD(0x48C, 0x1AC, 5, 0x7ac, 1, NO_PAD_CTRL)
+#define MX50_PAD_DISP_D15__FEC_TDAT0 IOMUX_PAD(0x48C, 0x1AC, 6, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D0__EPDC_D0 IOMUX_PAD(0x54C, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__GPIO_3_0 IOMUX_PAD(0x54C, 0x1B0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__WEIM_D0 IOMUX_PAD(0x54C, 0x1B0, 2, 0x7ec, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__ELCDIF_RS IOMUX_PAD(0x54C, 0x1B0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D0__ELCDIF_PIXCLK IOMUX_PAD(0x54C, 0x1B0, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D1__EPDC_D1 IOMUX_PAD(0x550, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__GPIO_3_1 IOMUX_PAD(0x550, 0x1B4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__WEIM_D1 IOMUX_PAD(0x550, 0x1B4, 2, 0x7f0, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__ELCDIF_CS IOMUX_PAD(0x550, 0x1B4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D1__ELCDIF_EN IOMUX_PAD(0x550, 0x1B4, 4, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D2__EPDC_D2 IOMUX_PAD(0x554, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__GPIO_3_2 IOMUX_PAD(0x554, 0x1B8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__WEIM_D2 IOMUX_PAD(0x554, 0x1B8, 2, 0x7f4, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__ELCDIF_WR IOMUX_PAD(0x554, 0x1B8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D2__ELCDIF_VSYNC IOMUX_PAD(0x554, 0x1B8, 4, 0x73c, 2, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D3__EPDC_D3 IOMUX_PAD(0x558, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__GPIO_3_3 IOMUX_PAD(0x558, 0x1BC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__WEIM_D3 IOMUX_PAD(0x558, 0x1BC, 2, 0x7f8, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__ELCDIF_RD IOMUX_PAD(0x558, 0x1BC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D3__ELCDIF_HSYNC IOMUX_PAD(0x558, 0x1BC, 4, 0x6f8, 3, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D4__EPDC_D4 IOMUX_PAD(0x55C, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D4__GPIO_3_4 IOMUX_PAD(0x55C, 0x1C0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D4__WEIM_D4 IOMUX_PAD(0x55C, 0x1C0, 2, 0x7fc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D5__EPDC_D5 IOMUX_PAD(0x560, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D5__GPIO_3_5 IOMUX_PAD(0x560, 0x1C4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D5__WEIM_D5 IOMUX_PAD(0x560, 0x1C4, 2, 0x800, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D6__EPDC_D6 IOMUX_PAD(0x564, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D6__GPIO_3_6 IOMUX_PAD(0x564, 0x1C8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D6__WEIM_D6 IOMUX_PAD(0x564, 0x1C8, 2, 0x804, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D7__EPDC_D7 IOMUX_PAD(0x568, 0x1CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D7__GPIO_3_7 IOMUX_PAD(0x568, 0x1CC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D7__WEIM_D7 IOMUX_PAD(0x568, 0x1CC, 2, 0x808, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D8__EPDC_D8 IOMUX_PAD(0x56C, 0x1D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__GPIO_3_8 IOMUX_PAD(0x56C, 0x1D0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__WEIM_D8 IOMUX_PAD(0x56C, 0x1D0, 2, 0x80c, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D8__ELCDIF_D24 IOMUX_PAD(0x56C, 0x1D0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D9__EPDC_D9 IOMUX_PAD(0x570, 0x1D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__GPIO_3_9 IOMUX_PAD(0x570, 0x1D4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__WEIM_D9 IOMUX_PAD(0x570, 0x1D4, 2, 0x810, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D9__ELCDIF_D25 IOMUX_PAD(0x570, 0x1D4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D10__EPDC_D10 IOMUX_PAD(0x574, 0x1D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__GPIO_3_10 IOMUX_PAD(0x574, 0x1D8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__WEIM_D10 IOMUX_PAD(0x574, 0x1D8, 2, 0x814, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D10__ELCDIF_D26 IOMUX_PAD(0x574, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D11__EPDC_D11 IOMUX_PAD(0x578, 0x1DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__GPIO_3_11 IOMUX_PAD(0x578, 0x1DC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__WEIM_D11 IOMUX_PAD(0x578, 0x1DC, 2, 0x818, 2, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D11__ELCDIF_D27 IOMUX_PAD(0x578, 0x1DC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D12__EPDC_D12 IOMUX_PAD(0x57C, 0x1E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__GPIO_3_12 IOMUX_PAD(0x57C, 0x1E0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__WEIM_D12 IOMUX_PAD(0x57C, 0x1E0, 2, 0x81c, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D12__ELCDIF_D28 IOMUX_PAD(0x57C, 0x1E0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D13__EPDC_D13 IOMUX_PAD(0x580, 0x1E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__GPIO_3_13 IOMUX_PAD(0x580, 0x1E4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__WEIM_D13 IOMUX_PAD(0x580, 0x1E4, 2, 0x820, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D13__ELCDIF_D29 IOMUX_PAD(0x580, 0x1E4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D14__EPDC_D14 IOMUX_PAD(0x584, 0x1E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__GPIO_3_14 IOMUX_PAD(0x584, 0x1E8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__WEIM_D14 IOMUX_PAD(0x584, 0x1E8, 2, 0x824, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__ELCDIF_D30 IOMUX_PAD(0x584, 0x1E8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D14__AUD6_TXD IOMUX_PAD(0x584, 0x1E8, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_D15__EPDC_D15 IOMUX_PAD(0x588, 0x1EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__GPIO_3_15 IOMUX_PAD(0x588, 0x1EC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__WEIM_D15 IOMUX_PAD(0x588, 0x1EC, 2, 0x828, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__ELCDIF_D31 IOMUX_PAD(0x588, 0x1EC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_D15__AUD6_TXC IOMUX_PAD(0x588, 0x1EC, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDCLK__EPDC_GDCLK IOMUX_PAD(0x58C, 0x1F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__GPIO_3_16 IOMUX_PAD(0x58C, 0x1F0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__WEIM_D16 IOMUX_PAD(0x58C, 0x1F0, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__ELCDIF_D16 IOMUX_PAD(0x58C, 0x1F0, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDCLK__AUD6_TXFS IOMUX_PAD(0x58C, 0x1F0, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDSP__EPDC_GDSP IOMUX_PAD(0x590, 0x1F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__GPIO_3_17 IOMUX_PAD(0x590, 0x1F4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__WEIM_D17 IOMUX_PAD(0x590, 0x1F4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__ELCDIF_D17 IOMUX_PAD(0x590, 0x1F4, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDSP__AUD6_RXD IOMUX_PAD(0x590, 0x1F4, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDOE__EPDC_GDOE IOMUX_PAD(0x594, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__GPIO_3_18 IOMUX_PAD(0x594, 0x1F8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__WEIM_D18 IOMUX_PAD(0x594, 0x1F8, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__ELCDIF_D18 IOMUX_PAD(0x594, 0x1F8, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDOE__AUD6_RXC IOMUX_PAD(0x594, 0x1F8, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_GDRL__EPDC_GDRL IOMUX_PAD(0x598, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__GPIO_3_19 IOMUX_PAD(0x598, 0x1FC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__WEIM_D19 IOMUX_PAD(0x598, 0x1FC, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__ELCDIF_D19 IOMUX_PAD(0x598, 0x1FC, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_GDRL__AUD6_RXFS IOMUX_PAD(0x598, 0x1FC, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCLK__EPDC_SDCLK IOMUX_PAD(0x59C, 0x200, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__GPIO_3_20 IOMUX_PAD(0x59C, 0x200, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__WEIM_D20 IOMUX_PAD(0x59C, 0x200, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__ELCDIF_D20 IOMUX_PAD(0x59C, 0x200, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLK__AUD5_TXD IOMUX_PAD(0x59C, 0x200, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOEZ__EPDC_SDOEZ IOMUX_PAD(0x5A0, 0x204, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__GPIO_3_21 IOMUX_PAD(0x5A0, 0x204, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__WEIM_D21 IOMUX_PAD(0x5A0, 0x204, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__ELCDIF_D21 IOMUX_PAD(0x5A0, 0x204, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOEZ__AUD5_TXC IOMUX_PAD(0x5A0, 0x204, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOED__EPDC_SDOED IOMUX_PAD(0x5A4, 0x208, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__GPIO_3_22 IOMUX_PAD(0x5A4, 0x208, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__WEIM_D22 IOMUX_PAD(0x5A4, 0x208, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__ELCDIF_D22 IOMUX_PAD(0x5A4, 0x208, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOED__AUD5_TXFS IOMUX_PAD(0x5A4, 0x208, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDOE__EPDC_SDOE IOMUX_PAD(0x5A8, 0x20C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__GPIO_3_23 IOMUX_PAD(0x5A8, 0x20C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__WEIM_D23 IOMUX_PAD(0x5A8, 0x20C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__ELCDIF_D23 IOMUX_PAD(0x5A8, 0x20C, 3, 0x0, 0, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDOE__AUD5_RXD IOMUX_PAD(0x5A8, 0x20C, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDLE__EPDC_SDLE IOMUX_PAD(0x5AC, 0x210, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__GPIO_3_24 IOMUX_PAD(0x5AC, 0x210, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__WEIM_D24 IOMUX_PAD(0x5AC, 0x210, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__ELCDIF_D8 IOMUX_PAD(0x5AC, 0x210, 3, 0x71c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDLE__AUD5_RXC IOMUX_PAD(0x5AC, 0x210, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCLKN__EPDC_SDCLKN IOMUX_PAD(0x5B0, 0x214, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__GPIO_3_25 IOMUX_PAD(0x5B0, 0x214, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__WEIM_D25 IOMUX_PAD(0x5B0, 0x214, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__ELCDIF_D9 IOMUX_PAD(0x5B0, 0x214, 3, 0x720, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCLKN__AUD5_RXFS IOMUX_PAD(0x5B0, 0x214, 4, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDSHR__EPDC_SDSHR IOMUX_PAD(0x5B4, 0x218, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__GPIO_3_26 IOMUX_PAD(0x5B4, 0x218, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__WEIM_D26 IOMUX_PAD(0x5B4, 0x218, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__ELCDIF_D10 IOMUX_PAD(0x5B4, 0x218, 3, 0x724, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_SDSHR__AUD4_TXD IOMUX_PAD(0x5B4, 0x218, 4, 0x6c8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCOM__EPDC_PWRCOM IOMUX_PAD(0x5B8, 0x21C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__GPIO_3_27 IOMUX_PAD(0x5B8, 0x21C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__WEIM_D27 IOMUX_PAD(0x5B8, 0x21C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__ELCDIF_D11 IOMUX_PAD(0x5B8, 0x21C, 3, 0x728, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCOM__AUD4_TXC IOMUX_PAD(0x5B8, 0x21C, 4, 0x6d4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRSTAT__EPDC_PWRSTAT IOMUX_PAD(0x5BC, 0x220, 0, 0x0, 0, NO_PAD_CTRL)
+/* Remove the default keeper from this pad (for EPD) */
+#define MX50_PAD_EPDC_PWRSTAT__GPIO_3_28 IOMUX_PAD(0x5BC, 0x220, 1, 0x0, 0, 0)
+#define MX50_PAD_EPDC_PWRSTAT__WEIM_D28 IOMUX_PAD(0x5BC, 0x220, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__ELCDIF_D12 IOMUX_PAD(0x5BC, 0x220, 3, 0x72c, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRSTAT__AUD4_TXFS IOMUX_PAD(0x5BC, 0x220, 4, 0x6d8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL0__EPDC_PWRCTRL0 IOMUX_PAD(0x5C0, 0x224, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__GPIO_3_29 IOMUX_PAD(0x5C0, 0x224, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__WEIM_D29 IOMUX_PAD(0x5C0, 0x224, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__ELCDIF_D13 IOMUX_PAD(0x5C0, 0x224, 3, 0x730, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL0__AUD4_RXD IOMUX_PAD(0x5C0, 0x224, 4, 0x6c4, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL1__EPDC_PWRCTRL1 IOMUX_PAD(0x5C4, 0x228, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__GPIO_3_30 IOMUX_PAD(0x5C4, 0x228, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__WEIM_D30 IOMUX_PAD(0x5C4, 0x228, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__ELCDIF_D14 IOMUX_PAD(0x5C4, 0x228, 3, 0x734, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL1__AUD4_RXC IOMUX_PAD(0x5C4, 0x228, 4, 0x6cc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL2__EPDC_PWRCTRL2 IOMUX_PAD(0x5C8, 0x22C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__GPIO_3_31 IOMUX_PAD(0x5C8, 0x22C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__WEIM_D31 IOMUX_PAD(0x5C8, 0x22C, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__ELCDIF_D15 IOMUX_PAD(0x5C8, 0x22C, 3, 0x738, 1, MX50_ELCDIF_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__AUD4_RXFS IOMUX_PAD(0x5C8, 0x22C, 4, 0x6d0, 1, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL2__SDMA_EXT0 IOMUX_PAD(0x5C8, 0x22C, 6, 0x7b8, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_PWRCTRL3__PWRCTRL3 IOMUX_PAD(0x5CC, 0x230, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__GPIO_4_20 IOMUX_PAD(0x5CC, 0x230, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__WEIM_EB2 IOMUX_PAD(0x5CC, 0x230, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_PWRCTRL3__SDMA_EXT1 IOMUX_PAD(0x5CC, 0x230, 6, 0x7bc, 1, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_VCOM0__EPDC_VCOM0 IOMUX_PAD(0x5D0, 0x234, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM0__GPIO_4_21 IOMUX_PAD(0x5D0, 0x234, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM0__WEIM_EB3 IOMUX_PAD(0x5D0, 0x234, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_VCOM1__EPDC_VCOM1 IOMUX_PAD(0x5D4, 0x238, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM1__GPIO_4_22 IOMUX_PAD(0x5D4, 0x238, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_VCOM1__WEIM_CS3 IOMUX_PAD(0x5D4, 0x238, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EPDC_BDR0__EPDC_BDR0 IOMUX_PAD(0x5D8, 0x23C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR0__GPIO_4_23 IOMUX_PAD(0x5D8, 0x23C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR0__ELCDIF_D7 IOMUX_PAD(0x5D8, 0x23C, 3, 0x718, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_BDR1__EPDC_BDR1 IOMUX_PAD(0x5DC, 0x240, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR1__GPIO_4_24 IOMUX_PAD(0x5DC, 0x240, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_BDR1__ELCDIF_D6 IOMUX_PAD(0x5DC, 0x240, 3, 0x714, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE0__EPDC_SDCE0 IOMUX_PAD(0x5E0, 0x244, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE0__GPIO_4_25 IOMUX_PAD(0x5E0, 0x244, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE0__ELCDIF_D5 IOMUX_PAD(0x5E0, 0x244, 3, 0x710, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE1__EPDC_SDCE1 IOMUX_PAD(0x5E4, 0x248, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE1__GPIO_4_26 IOMUX_PAD(0x5E4, 0x248, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE1__ELCDIF_D4 IOMUX_PAD(0x5E4, 0x248, 2, 0x70c, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE2__EPDC_SDCE2 IOMUX_PAD(0x5E8, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE2__GPIO_4_27 IOMUX_PAD(0x5E8, 0x24C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE2__ELCDIF_DAT3 IOMUX_PAD(0x5E8, 0x24C, 3, 0x708, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE3__EPDC_SDCE3 IOMUX_PAD(0x5EC, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE3__GPIO_4_28 IOMUX_PAD(0x5EC, 0x250, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE3__ELCDIF_D2 IOMUX_PAD(0x5EC, 0x250, 3, 0x704, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE4__EPDC_SDCE4 IOMUX_PAD(0x5F0, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE4__GPIO_4_29 IOMUX_PAD(0x5F0, 0x254, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE4__ELCDIF_D1 IOMUX_PAD(0x5F0, 0x254, 3, 0x700, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EPDC_SDCE5__EPDC_SDCE5 IOMUX_PAD(0x5F4, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE5__GPIO_4_30 IOMUX_PAD(0x5F4, 0x258, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EPDC_SDCE5__ELCDIF_D0 IOMUX_PAD(0x5F4, 0x258, 3, 0x6fc, 1, MX50_ELCDIF_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA0__WEIM_A0 IOMUX_PAD(0x5F8, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA0__GPIO_1_0 IOMUX_PAD(0x5F8, 0x25C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA0__KEY_COL4 IOMUX_PAD(0x5f8, 0x25C, 3, 0x790, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA1__WEIM_A1 IOMUX_PAD(0x5FC, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA1__GPIO_1_1 IOMUX_PAD(0x5FC, 0x260, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA1__KEY_ROW4 IOMUX_PAD(0x5fc, 0x260, 3, 0x7a0, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA2__WEIM_A2 IOMUX_PAD(0x600, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA2__GPIO_1_2 IOMUX_PAD(0x600, 0x264, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA2__KEY_COL5 IOMUX_PAD(0x600, 0x264, 3, 0x794, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA3__WEIM_A3 IOMUX_PAD(0x604, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA3__GPIO_1_3 IOMUX_PAD(0x604, 0x268, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA3__KEY_ROW5 IOMUX_PAD(0x604, 0x268, 3, 0x7a4, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA4__WEIM_A4 IOMUX_PAD(0x608, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA4__GPIO_1_4 IOMUX_PAD(0x608, 0x26C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA4__KEY_COL6 IOMUX_PAD(0x608, 0x26C, 3, 0x798, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA5__WEIM_A5 IOMUX_PAD(0x60C, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA5__GPIO_1_5 IOMUX_PAD(0x60C, 0x270, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA5__KEY_ROW6 IOMUX_PAD(0x60C, 0x270, 3, 0x7a8, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA6__WEIM_A6 IOMUX_PAD(0x610, 0x274, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA6__GPIO_1_6 IOMUX_PAD(0x610, 0x274, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA6__KEY_COL7 IOMUX_PAD(0x610, 0x274, 3, 0x79c, 2, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA7__WEIM_A7 IOMUX_PAD(0x614, 0x278, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA7__GPIO_1_7 IOMUX_PAD(0x614, 0x278, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA7__KEY_ROW7 IOMUX_PAD(0x614, 0x278, 3, 0x7ac, 2, MX50_KEYPAD_CTRL)
+
+#define MX50_PAD_EIM_DA8__WEIM_A8 IOMUX_PAD(0x618, 0x27C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA8__GPIO_1_8 IOMUX_PAD(0x618, 0x27C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA8__NANDF_CLE IOMUX_PAD(0x618, 0x27C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA9__WEIM_A9 IOMUX_PAD(0x61C, 0x280, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA9__GPIO_1_9 IOMUX_PAD(0x61C, 0x280, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA9__NANDF_ALE IOMUX_PAD(0x61C, 0x280, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA10__WEIM_A10 IOMUX_PAD(0x620, 0x284, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA10__GPIO_1_10 IOMUX_PAD(0x620, 0x284, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA10__NANDF_CE0 IOMUX_PAD(0x620, 0x284, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA11__WEIM_A11 IOMUX_PAD(0x624, 0x288, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA11__GPIO_1_11 IOMUX_PAD(0x624, 0x288, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA11__NANDF_CE1 IOMUX_PAD(0x624, 0x288, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+
+#define MX50_PAD_EIM_DA12__WEIM_A12 IOMUX_PAD(0x628, 0x28C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA12__GPIO_1_12 IOMUX_PAD(0x628, 0x28C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA12__NANDF_CE2 IOMUX_PAD(0x628, 0x28C, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EIM_DA12__EPDC_SDCE6 IOMUX_PAD(0x628, 0x28C, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA13__WEIM_A13 IOMUX_PAD(0x62C, 0x290, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA13__GPIO_1_13 IOMUX_PAD(0x62C, 0x290, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA13__NANDF_CE3 IOMUX_PAD(0x62C, 0x290, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PIN_EIM_DA13__EPDC_SDCE7 IOMUX_PAD(0x62C, 0x290, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA14__WEIM_A14 IOMUX_PAD(0x630, 0x294, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA14__GPIO_1_14 IOMUX_PAD(0x630, 0x294, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA14__NANDF_READY IOMUX_PAD(0x630, 0x294, 2, 0x7B4, 2, PAD_CTL_PKE | \
+ PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX50_PAD_EIM_DA14__EPDC_SDCE8 IOMUX_PAD(0x630, 0x294, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_DA15__WEIM_A15 IOMUX_PAD(0x634, 0x298, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_DA15__GPIO_1_15 IOMUX_PAD(0x634, 0x298, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PIN_EIM_DA15__NANDF_DQS IOMUX_PAD(0x634, 0x298, 2, 0x7B0, 2, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_EIM_DA15__EPDC_SDCE9 IOMUX_PAD(0x634, 0x298, 3, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS2__WEIM_CS2 IOMUX_PAD(0x638, 0x29C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS2__GPIO_1_16 IOMUX_PAD(0x638, 0x29C, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS2__WEIM_A27 IOMUX_PAD(0x638, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS1__WEIM_CS1 IOMUX_PAD(0x63C, 0x2A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS1__GPIO_1_17 IOMUX_PAD(0x63C, 0x2A0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CS0__WEIM_CS0 IOMUX_PAD(0x640, 0x2A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CS0__GPIO_1_18 IOMUX_PAD(0x640, 0x2A4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_EB0__WEIM_EB0 IOMUX_PAD(0x644, 0x2A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_EB0__GPIO_1_19 IOMUX_PAD(0x644, 0x2A8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_EB1__WEIM_EB1 IOMUX_PAD(0x648, 0x2AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_EB1__GPIO_1_20 IOMUX_PAD(0x648, 0x2AC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_WAIT__WEIM_WAIT IOMUX_PAD(0x64C, 0x2B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_WAIT__GPIO_1_21 IOMUX_PAD(0x64C, 0x2B0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_BCLK__WEIM_BCLK IOMUX_PAD(0x650, 0x2B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_BCLK__GPIO_1_22 IOMUX_PAD(0x650, 0x2B4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_RDY__WEIM_RDY IOMUX_PAD(0x654, 0x2B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_RDY__GPIO_1_23 IOMUX_PAD(0x654, 0x2B8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_OE__WEIM_OE IOMUX_PAD(0x658, 0x2BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_OE__GPIO_1_24 IOMUX_PAD(0x658, 0x2BC, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_RW__WEIM_RW IOMUX_PAD(0x65C, 0x2C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_RW__GPIO_1_25 IOMUX_PAD(0x65C, 0x2C0, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_LBA__WEIM_LBA IOMUX_PAD(0x660, 0x2C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_LBA__GPIO_1_26 IOMUX_PAD(0x660, 0x2C4, 1, 0x0, 0, NO_PAD_CTRL)
+
+#define MX50_PAD_EIM_CRE__WEIM_CRE IOMUX_PAD(0x664, 0x2C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX50_PAD_EIM_CRE__GPIO_1_27 IOMUX_PAD(0x664, 0x2C8, 1, 0x0, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX50_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
new file mode 100644
index 00000000..df6acc06
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -0,0 +1,1567 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX51_H__
+#define __MACH_IOMUX_MX51_H__
+
+#include <mach/iomux-v3.h>
+
+/* Pad control groupings */
+#define MX51_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_HYS | PAD_CTL_SRE_FAST)
+#define MX51_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS)
+#define MX51_ESDHC_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS)
+#define MX51_USBH1_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_HYS | PAD_CTL_PUE)
+#define MX51_ECSPI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_HYS | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
+#define MX51_SDHCI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_PUE | \
+ PAD_CTL_SRE_FAST | PAD_CTL_DVS)
+#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | PAD_CTL_SRE_FAST)
+
+#define MX51_PAD_CTRL_2 (PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_3 (PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_CTRL_4 (PAD_CTL_PKE | PAD_CTL_DVS | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_5 (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+
+/*
+ * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO<unit>_<num>
+ * See also iomux-v3.h
+ */
+
+/* Raw pin modes without pad control */
+/* PAD MUX ALT INPSE PATH PADCTRL */
+#define _MX51_PAD_EIM_D16__AUD4_RXFS IOMUX_PAD(0x3f0, 0x5c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__AUD5_TXD IOMUX_PAD(0x3f0, 0x5c, 7, 0x08d8, 0, 0)
+#define _MX51_PAD_EIM_D16__EIM_D16 IOMUX_PAD(0x3f0, 0x5c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__GPIO2_0 IOMUX_PAD(0x3f0, 0x5c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__I2C1_SDA IOMUX_PAD(0x3f0, 0x5c, 0x14, 0x09b4, 0, 0)
+#define _MX51_PAD_EIM_D16__UART2_CTS IOMUX_PAD(0x3f0, 0x5c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D16__USBH2_DATA0 IOMUX_PAD(0x3f0, 0x5c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__AUD5_RXD IOMUX_PAD(0x3f4, 0x60, 7, 0x08d4, 0, 0)
+#define _MX51_PAD_EIM_D17__EIM_D17 IOMUX_PAD(0x3f4, 0x60, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__GPIO2_1 IOMUX_PAD(0x3f4, 0x60, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__UART2_RXD IOMUX_PAD(0x3f4, 0x60, 3, 0x09ec, 0, 0)
+#define _MX51_PAD_EIM_D17__UART3_CTS IOMUX_PAD(0x3f4, 0x60, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D17__USBH2_DATA1 IOMUX_PAD(0x3f4, 0x60, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__AUD5_TXC IOMUX_PAD(0x3f8, 0x64, 7, 0x08e4, 0, 0)
+#define _MX51_PAD_EIM_D18__EIM_D18 IOMUX_PAD(0x3f8, 0x64, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__GPIO2_2 IOMUX_PAD(0x3f8, 0x64, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__UART2_TXD IOMUX_PAD(0x3f8, 0x64, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D18__UART3_RTS IOMUX_PAD(0x3f8, 0x64, 4, 0x09f0, 1, 0)
+#define _MX51_PAD_EIM_D18__USBH2_DATA2 IOMUX_PAD(0x3f8, 0x64, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__AUD4_RXC IOMUX_PAD(0x3fc, 0x68, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__AUD5_TXFS IOMUX_PAD(0x3fc, 0x68, 7, 0x08e8, 0, 0)
+#define _MX51_PAD_EIM_D19__EIM_D19 IOMUX_PAD(0x3fc, 0x68, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__GPIO2_3 IOMUX_PAD(0x3fc, 0x68, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D19__I2C1_SCL IOMUX_PAD(0x3fc, 0x68, 0x14, 0x09b0, 0, 0)
+#define _MX51_PAD_EIM_D19__UART2_RTS IOMUX_PAD(0x3fc, 0x68, 3, 0x09e8, 1, 0)
+#define _MX51_PAD_EIM_D19__USBH2_DATA3 IOMUX_PAD(0x3fc, 0x68, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__AUD4_TXD IOMUX_PAD(0x400, 0x6c, 5, 0x08c8, 0, 0)
+#define _MX51_PAD_EIM_D20__EIM_D20 IOMUX_PAD(0x400, 0x6c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__GPIO2_4 IOMUX_PAD(0x400, 0x6c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__SRTC_ALARM_DEB IOMUX_PAD(0x400, 0x6c, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D20__USBH2_DATA4 IOMUX_PAD(0x400, 0x6c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__AUD4_RXD IOMUX_PAD(0x404, 0x70, 5, 0x08c4, 0, 0)
+#define _MX51_PAD_EIM_D21__EIM_D21 IOMUX_PAD(0x404, 0x70, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__GPIO2_5 IOMUX_PAD(0x404, 0x70, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__SRTC_ALARM_DEB IOMUX_PAD(0x404, 0x70, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D21__USBH2_DATA5 IOMUX_PAD(0x404, 0x70, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__AUD4_TXC IOMUX_PAD(0x408, 0x74, 5, 0x08cc, 0, 0)
+#define _MX51_PAD_EIM_D22__EIM_D22 IOMUX_PAD(0x408, 0x74, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__GPIO2_6 IOMUX_PAD(0x408, 0x74, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D22__USBH2_DATA6 IOMUX_PAD(0x408, 0x74, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__AUD4_TXFS IOMUX_PAD(0x40c, 0x78, 5, 0x08d0, 0, 0)
+#define _MX51_PAD_EIM_D23__EIM_D23 IOMUX_PAD(0x40c, 0x78, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__GPIO2_7 IOMUX_PAD(0x40c, 0x78, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__SPDIF_OUT1 IOMUX_PAD(0x40c, 0x78, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D23__USBH2_DATA7 IOMUX_PAD(0x40c, 0x78, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__AUD6_RXFS IOMUX_PAD(0x410, 0x7c, 5, 0x08f8, 0, 0)
+#define _MX51_PAD_EIM_D24__EIM_D24 IOMUX_PAD(0x410, 0x7c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__GPIO2_8 IOMUX_PAD(0x410, 0x7c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__I2C2_SDA IOMUX_PAD(0x410, 0x7c, 0x14, 0x09bc, 0, 0)
+#define _MX51_PAD_EIM_D24__UART3_CTS IOMUX_PAD(0x410, 0x7c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D24__USBOTG_DATA0 IOMUX_PAD(0x410, 0x7c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__EIM_D25 IOMUX_PAD(0x414, 0x80, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__KEY_COL6 IOMUX_PAD(0x414, 0x80, 1, 0x09c8, 0, 0)
+#define _MX51_PAD_EIM_D25__UART2_CTS IOMUX_PAD(0x414, 0x80, 4, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D25__UART3_RXD IOMUX_PAD(0x414, 0x80, 3, 0x09f4, 0, 0)
+#define _MX51_PAD_EIM_D25__USBOTG_DATA1 IOMUX_PAD(0x414, 0x80, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__EIM_D26 IOMUX_PAD(0x418, 0x84, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__KEY_COL7 IOMUX_PAD(0x418, 0x84, 1, 0x09cc, 0, 0)
+#define _MX51_PAD_EIM_D26__UART2_RTS IOMUX_PAD(0x418, 0x84, 4, 0x09e8, 3, 0)
+#define _MX51_PAD_EIM_D26__UART3_TXD IOMUX_PAD(0x418, 0x84, 3, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D26__USBOTG_DATA2 IOMUX_PAD(0x418, 0x84, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__AUD6_RXC IOMUX_PAD(0x41c, 0x88, 5, 0x08f4, 0, 0)
+#define _MX51_PAD_EIM_D27__EIM_D27 IOMUX_PAD(0x41c, 0x88, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__GPIO2_9 IOMUX_PAD(0x41c, 0x88, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D27__I2C2_SCL IOMUX_PAD(0x41c, 0x88, 0x14, 0x09b8, 0, 0)
+#define _MX51_PAD_EIM_D27__UART3_RTS IOMUX_PAD(0x41c, 0x88, 3, 0x09f0, 3, 0)
+#define _MX51_PAD_EIM_D27__USBOTG_DATA3 IOMUX_PAD(0x41c, 0x88, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D28__AUD6_TXD IOMUX_PAD(0x420, 0x8c, 5, 0x08f0, 0, 0)
+#define _MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x8c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D28__KEY_ROW4 IOMUX_PAD(0x420, 0x8c, 1, 0x09d0, 0, 0)
+#define _MX51_PAD_EIM_D28__USBOTG_DATA4 IOMUX_PAD(0x420, 0x8c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D29__AUD6_RXD IOMUX_PAD(0x424, 0x90, 5, 0x08ec, 0, 0)
+#define _MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x90, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D29__KEY_ROW5 IOMUX_PAD(0x424, 0x90, 1, 0x09d4, 0, 0)
+#define _MX51_PAD_EIM_D29__USBOTG_DATA5 IOMUX_PAD(0x424, 0x90, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D30__AUD6_TXC IOMUX_PAD(0x428, 0x94, 5, 0x08fc, 0, 0)
+#define _MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x94, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D30__KEY_ROW6 IOMUX_PAD(0x428, 0x94, 1, 0x09d8, 0, 0)
+#define _MX51_PAD_EIM_D30__USBOTG_DATA6 IOMUX_PAD(0x428, 0x94, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D31__AUD6_TXFS IOMUX_PAD(0x42c, 0x98, 5, 0x0900, 0, 0)
+#define _MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42c, 0x98, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_D31__KEY_ROW7 IOMUX_PAD(0x42c, 0x98, 1, 0x09dc, 0, 0)
+#define _MX51_PAD_EIM_D31__USBOTG_DATA7 IOMUX_PAD(0x42c, 0x98, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__EIM_A16 IOMUX_PAD(0x430, 0x9c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__GPIO2_10 IOMUX_PAD(0x430, 0x9c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A16__OSC_FREQ_SEL0 IOMUX_PAD(0x430, 0x9c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__EIM_A17 IOMUX_PAD(0x434, 0xa0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__GPIO2_11 IOMUX_PAD(0x434, 0xa0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A17__OSC_FREQ_SEL1 IOMUX_PAD(0x434, 0xa0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__BOOT_LPB0 IOMUX_PAD(0x438, 0xa4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__EIM_A18 IOMUX_PAD(0x438, 0xa4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A18__GPIO2_12 IOMUX_PAD(0x438, 0xa4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__BOOT_LPB1 IOMUX_PAD(0x43c, 0xa8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__EIM_A19 IOMUX_PAD(0x43c, 0xa8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A19__GPIO2_13 IOMUX_PAD(0x43c, 0xa8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__BOOT_UART_SRC0 IOMUX_PAD(0x440, 0xac, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__EIM_A20 IOMUX_PAD(0x440, 0xac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A20__GPIO2_14 IOMUX_PAD(0x440, 0xac, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__BOOT_UART_SRC1 IOMUX_PAD(0x444, 0xb0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__EIM_A21 IOMUX_PAD(0x444, 0xb0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A21__GPIO2_15 IOMUX_PAD(0x444, 0xb0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A22__EIM_A22 IOMUX_PAD(0x448, 0xb4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A22__GPIO2_16 IOMUX_PAD(0x448, 0xb4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__BOOT_HPN_EN IOMUX_PAD(0x44c, 0xb8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__EIM_A23 IOMUX_PAD(0x44c, 0xb8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A23__GPIO2_17 IOMUX_PAD(0x44c, 0xb8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__EIM_A24 IOMUX_PAD(0x450, 0xbc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__GPIO2_18 IOMUX_PAD(0x450, 0xbc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A24__USBH2_CLK IOMUX_PAD(0x450, 0xbc, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__DISP1_PIN4 IOMUX_PAD(0x454, 0xc0, 6, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__EIM_A25 IOMUX_PAD(0x454, 0xc0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__GPIO2_19 IOMUX_PAD(0x454, 0xc0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A25__USBH2_DIR IOMUX_PAD(0x454, 0xc0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__CSI1_DATA_EN IOMUX_PAD(0x458, 0xc4, 5, 0x09a0, 0, 0)
+#define _MX51_PAD_EIM_A26__DISP2_EXT_CLK IOMUX_PAD(0x458, 0xc4, 6, 0x0908, 0, 0)
+#define _MX51_PAD_EIM_A26__EIM_A26 IOMUX_PAD(0x458, 0xc4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__GPIO2_20 IOMUX_PAD(0x458, 0xc4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A26__USBH2_STP IOMUX_PAD(0x458, 0xc4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__CSI2_DATA_EN IOMUX_PAD(0x45c, 0xc8, 5, 0x099c, 0, 0)
+#define _MX51_PAD_EIM_A27__DISP1_PIN1 IOMUX_PAD(0x45c, 0xc8, 6, 0x09a4, 0, 0)
+#define _MX51_PAD_EIM_A27__EIM_A27 IOMUX_PAD(0x45c, 0xc8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__GPIO2_21 IOMUX_PAD(0x45c, 0xc8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_A27__USBH2_NXT IOMUX_PAD(0x45c, 0xc8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0xcc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0xd0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__AUD5_RXFS IOMUX_PAD(0x468, 0xd4, 6, 0x08e0, 0, 0)
+#define _MX51_PAD_EIM_EB2__CSI1_D2 IOMUX_PAD(0x468, 0xd4, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__EIM_EB2 IOMUX_PAD(0x468, 0xd4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__FEC_MDIO IOMUX_PAD(0x468, 0xd4, 3, 0x0954, 0, 0)
+#define _MX51_PAD_EIM_EB2__GPIO2_22 IOMUX_PAD(0x468, 0xd4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB2__GPT_CMPOUT1 IOMUX_PAD(0x468, 0xd4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__AUD5_RXC IOMUX_PAD(0x46c, 0xd8, 6, 0x08dc, 0, 0)
+#define _MX51_PAD_EIM_EB3__CSI1_D3 IOMUX_PAD(0x46c, 0xd8, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__EIM_EB3 IOMUX_PAD(0x46c, 0xd8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__FEC_RDATA1 IOMUX_PAD(0x46c, 0xd8, 3, 0x095c, 0, 0)
+#define _MX51_PAD_EIM_EB3__GPIO2_23 IOMUX_PAD(0x46c, 0xd8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_EB3__GPT_CMPOUT2 IOMUX_PAD(0x46c, 0xd8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_OE__EIM_OE IOMUX_PAD(0x470, 0xdc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_OE__GPIO2_24 IOMUX_PAD(0x470, 0xdc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS0__EIM_CS0 IOMUX_PAD(0x474, 0xe0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS0__GPIO2_25 IOMUX_PAD(0x474, 0xe0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS1__EIM_CS1 IOMUX_PAD(0x478, 0xe4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS1__GPIO2_26 IOMUX_PAD(0x478, 0xe4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__AUD5_TXD IOMUX_PAD(0x47c, 0xe8, 6, 0x08d8, 1, 0)
+#define _MX51_PAD_EIM_CS2__CSI1_D4 IOMUX_PAD(0x47c, 0xe8, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__EIM_CS2 IOMUX_PAD(0x47c, 0xe8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__FEC_RDATA2 IOMUX_PAD(0x47c, 0xe8, 3, 0x0960, 0, 0)
+#define _MX51_PAD_EIM_CS2__GPIO2_27 IOMUX_PAD(0x47c, 0xe8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS2__USBOTG_STP IOMUX_PAD(0x47c, 0xe8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__AUD5_RXD IOMUX_PAD(0x480, 0xec, 6, 0x08d4, 1, 0)
+#define _MX51_PAD_EIM_CS3__CSI1_D5 IOMUX_PAD(0x480, 0xec, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__EIM_CS3 IOMUX_PAD(0x480, 0xec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__FEC_RDATA3 IOMUX_PAD(0x480, 0xec, 3, 0x0964, 0, 0)
+#define _MX51_PAD_EIM_CS3__GPIO2_28 IOMUX_PAD(0x480, 0xec, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS3__USBOTG_NXT IOMUX_PAD(0x480, 0xec, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__AUD5_TXC IOMUX_PAD(0x484, 0xf0, 6, 0x08e4, 1, 0)
+#define _MX51_PAD_EIM_CS4__CSI1_D6 IOMUX_PAD(0x484, 0xf0, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__EIM_CS4 IOMUX_PAD(0x484, 0xf0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__FEC_RX_ER IOMUX_PAD(0x484, 0xf0, 3, 0x0970, 0, 0)
+#define _MX51_PAD_EIM_CS4__GPIO2_29 IOMUX_PAD(0x484, 0xf0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS4__USBOTG_CLK IOMUX_PAD(0x484, 0xf0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__AUD5_TXFS IOMUX_PAD(0x488, 0xf4, 6, 0x08e8, 1, 0)
+#define _MX51_PAD_EIM_CS5__CSI1_D7 IOMUX_PAD(0x488, 0xf4, 5, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__DISP1_EXT_CLK IOMUX_PAD(0x488, 0xf4, 4, 0x0904, 0, 0)
+#define _MX51_PAD_EIM_CS5__EIM_CS5 IOMUX_PAD(0x488, 0xf4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__FEC_CRS IOMUX_PAD(0x488, 0xf4, 3, 0x0950, 0, 0)
+#define _MX51_PAD_EIM_CS5__GPIO2_30 IOMUX_PAD(0x488, 0xf4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CS5__USBOTG_DIR IOMUX_PAD(0x488, 0xf4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DTACK__EIM_DTACK IOMUX_PAD(0x48c, 0xf8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DTACK__GPIO2_31 IOMUX_PAD(0x48c, 0xf8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_LBA__EIM_LBA IOMUX_PAD(0x494, 0xfc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_LBA__GPIO3_1 IOMUX_PAD(0x494, 0xfc, 1, 0x0978, 0, 0)
+#define _MX51_PAD_EIM_CRE__EIM_CRE IOMUX_PAD(0x4a0, 0x100, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_CRE__GPIO3_2 IOMUX_PAD(0x4a0, 0x100, 1, 0x097c, 0, 0)
+#define _MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4d0, 0x104, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__GPIO3_3 IOMUX_PAD(0x4e4, 0x108, 3, 0x0980, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__NANDF_WE_B IOMUX_PAD(0x4e4, 0x108, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__PATA_DIOW IOMUX_PAD(0x4e4, 0x108, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WE_B__SD3_DATA0 IOMUX_PAD(0x4e4, 0x108, 2, 0x093c, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__GPIO3_4 IOMUX_PAD(0x4e8, 0x10c, 3, 0x0984, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__NANDF_RE_B IOMUX_PAD(0x4e8, 0x10c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__PATA_DIOR IOMUX_PAD(0x4e8, 0x10c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RE_B__SD3_DATA1 IOMUX_PAD(0x4e8, 0x10c, 2, 0x0940, 0, 0)
+#define _MX51_PAD_NANDF_ALE__GPIO3_5 IOMUX_PAD(0x4ec, 0x110, 3, 0x0988, 0, 0)
+#define _MX51_PAD_NANDF_ALE__NANDF_ALE IOMUX_PAD(0x4ec, 0x110, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_ALE__PATA_BUFFER_EN IOMUX_PAD(0x4ec, 0x110, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CLE__GPIO3_6 IOMUX_PAD(0x4f0, 0x114, 3, 0x098c, 0, 0)
+#define _MX51_PAD_NANDF_CLE__NANDF_CLE IOMUX_PAD(0x4f0, 0x114, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CLE__PATA_RESET_B IOMUX_PAD(0x4f0, 0x114, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__GPIO3_7 IOMUX_PAD(0x4f4, 0x118, 3, 0x0990, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__NANDF_WP_B IOMUX_PAD(0x4f4, 0x118, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__PATA_DMACK IOMUX_PAD(0x4f4, 0x118, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_WP_B__SD3_DATA2 IOMUX_PAD(0x4f4, 0x118, 2, 0x0944, 0, 0)
+#define _MX51_PAD_NANDF_RB0__ECSPI2_SS1 IOMUX_PAD(0x4f8, 0x11c, 5, 0x0930, 0, 0)
+#define _MX51_PAD_NANDF_RB0__GPIO3_8 IOMUX_PAD(0x4f8, 0x11c, 3, 0x0994, 0, 0)
+#define _MX51_PAD_NANDF_RB0__NANDF_RB0 IOMUX_PAD(0x4f8, 0x11c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB0__PATA_DMARQ IOMUX_PAD(0x4f8, 0x11c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB0__SD3_DATA3 IOMUX_PAD(0x4f8, 0x11c, 2, 0x0948, 0, 0)
+#define _MX51_PAD_NANDF_RB1__CSPI_MOSI IOMUX_PAD(0x4fc, 0x120, 6, 0x091c, 0, 0)
+#define _MX51_PAD_NANDF_RB1__ECSPI2_RDY IOMUX_PAD(0x4fc, 0x120, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__GPIO3_9 IOMUX_PAD(0x4fc, 0x120, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__NANDF_RB1 IOMUX_PAD(0x4fc, 0x120, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__PATA_IORDY IOMUX_PAD(0x4fc, 0x120, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__DISP2_WAIT IOMUX_PAD(0x500, 0x124, 5, 0x09a8, 0, 0)
+#define _MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x094c, 0, 0)
+#define _MX51_PAD_NANDF_RB2__GPIO3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB2__USBH3_NXT IOMUX_PAD(0x500, 0x124, 6, 0x0a20, 0, 0)
+#define _MX51_PAD_NANDF_RB3__DISP1_WAIT IOMUX_PAD(0x504, 0x128, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__FEC_RX_CLK IOMUX_PAD(0x504, 0x128, 1, 0x0968, 0, 0)
+#define _MX51_PAD_NANDF_RB3__GPIO3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RB3__USBH3_CLK IOMUX_PAD(0x504, 0x128, 6, 0x09f8, 0, 0)
+#define _MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 7, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO_NAND__GPIO_NAND IOMUX_PAD(0x514, 0x12c, 0, 0x0998, 0, 0)
+#define _MX51_PAD_GPIO_NAND__PATA_INTRQ IOMUX_PAD(0x514, 0x12c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS0__GPIO3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS0__NANDF_CS0 IOMUX_PAD(0x518, 0x130, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS1__GPIO3_17 IOMUX_PAD(0x51c, 0x134, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS1__NANDF_CS1 IOMUX_PAD(0x51c, 0x134, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__CSPI_SCLK IOMUX_PAD(0x520, 0x138, 6, 0x0914, 0, 0)
+#define _MX51_PAD_NANDF_CS2__FEC_TX_ER IOMUX_PAD(0x520, 0x138, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__GPIO3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__PATA_CS_0 IOMUX_PAD(0x520, 0x138, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__SD4_CLK IOMUX_PAD(0x520, 0x138, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__GPIO3_19 IOMUX_PAD(0x524, 0x13c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__NANDF_CS3 IOMUX_PAD(0x524, 0x13c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__PATA_CS_1 IOMUX_PAD(0x524, 0x13c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__SD4_DAT0 IOMUX_PAD(0x524, 0x13c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__FEC_TDATA1 IOMUX_PAD(0x528, 0x140, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__GPIO3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__PATA_DA_0 IOMUX_PAD(0x528, 0x140, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__SD4_DAT1 IOMUX_PAD(0x528, 0x140, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS4__USBH3_STP IOMUX_PAD(0x528, 0x140, 7, 0x0a24, 0, 0)
+#define _MX51_PAD_NANDF_CS5__FEC_TDATA2 IOMUX_PAD(0x52c, 0x144, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__GPIO3_21 IOMUX_PAD(0x52c, 0x144, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__NANDF_CS5 IOMUX_PAD(0x52c, 0x144, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__PATA_DA_1 IOMUX_PAD(0x52c, 0x144, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__SD4_DAT2 IOMUX_PAD(0x52c, 0x144, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS5__USBH3_DIR IOMUX_PAD(0x52c, 0x144, 7, 0x0a1c, 0, 0)
+#define _MX51_PAD_NANDF_CS6__CSPI_SS3 IOMUX_PAD(0x530, 0x148, 7, 0x0928, 0, 0)
+#define _MX51_PAD_NANDF_CS6__FEC_TDATA3 IOMUX_PAD(0x530, 0x148, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__GPIO3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__NANDF_CS6 IOMUX_PAD(0x530, 0x148, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__PATA_DA_2 IOMUX_PAD(0x530, 0x148, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS6__SD4_DAT3 IOMUX_PAD(0x530, 0x148, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__FEC_TX_EN IOMUX_PAD(0x534, 0x14c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__GPIO3_23 IOMUX_PAD(0x534, 0x14c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__NANDF_CS7 IOMUX_PAD(0x534, 0x14c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_CS7__SD3_CLK IOMUX_PAD(0x534, 0x14c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 IOMUX_PAD(0x538, 0x150, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x0974, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__GPIO3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 0, 0x0938, 0, 0)
+#define _MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53c, 0x154, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__GPIO3_25 IOMUX_PAD(0x53c, 0x154, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__NANDF_D15 IOMUX_PAD(0x53c, 0x154, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__PATA_DATA15 IOMUX_PAD(0x53c, 0x154, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D15__SD3_DAT7 IOMUX_PAD(0x53c, 0x154, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__ECSPI2_SS3 IOMUX_PAD(0x540, 0x158, 2, 0x0934, 0, 0)
+#define _MX51_PAD_NANDF_D14__GPIO3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__NANDF_D14 IOMUX_PAD(0x540, 0x158, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__PATA_DATA14 IOMUX_PAD(0x540, 0x158, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D14__SD3_DAT6 IOMUX_PAD(0x540, 0x158, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__ECSPI2_SS2 IOMUX_PAD(0x544, 0x15c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__GPIO3_27 IOMUX_PAD(0x544, 0x15c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__NANDF_D13 IOMUX_PAD(0x544, 0x15c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__PATA_DATA13 IOMUX_PAD(0x544, 0x15c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D13__SD3_DAT5 IOMUX_PAD(0x544, 0x15c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__ECSPI2_SS1 IOMUX_PAD(0x548, 0x160, 2, 0x0930, 1, 0)
+#define _MX51_PAD_NANDF_D12__GPIO3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__NANDF_D12 IOMUX_PAD(0x548, 0x160, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__PATA_DATA12 IOMUX_PAD(0x548, 0x160, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D12__SD3_DAT4 IOMUX_PAD(0x548, 0x160, 5, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__FEC_RX_DV IOMUX_PAD(0x54c, 0x164, 2, 0x096c, 0, 0)
+#define _MX51_PAD_NANDF_D11__GPIO3_29 IOMUX_PAD(0x54c, 0x164, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__NANDF_D11 IOMUX_PAD(0x54c, 0x164, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__PATA_DATA11 IOMUX_PAD(0x54c, 0x164, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D11__SD3_DATA3 IOMUX_PAD(0x54c, 0x164, 5, 0x0948, 1, 0)
+#define _MX51_PAD_NANDF_D10__GPIO3_30 IOMUX_PAD(0x550, 0x168, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__NANDF_D10 IOMUX_PAD(0x550, 0x168, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__PATA_DATA10 IOMUX_PAD(0x550, 0x168, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D10__SD3_DATA2 IOMUX_PAD(0x550, 0x168, 5, 0x0944, 1, 0)
+#define _MX51_PAD_NANDF_D9__FEC_RDATA0 IOMUX_PAD(0x554, 0x16c, 0x12, 0x0958, 0, 0)
+#define _MX51_PAD_NANDF_D9__GPIO3_31 IOMUX_PAD(0x554, 0x16c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__NANDF_D9 IOMUX_PAD(0x554, 0x16c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__PATA_DATA9 IOMUX_PAD(0x554, 0x16c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D9__SD3_DATA1 IOMUX_PAD(0x554, 0x16c, 5, 0x0940, 1, 0)
+#define _MX51_PAD_NANDF_D8__FEC_TDATA0 IOMUX_PAD(0x558, 0x170, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__GPIO4_0 IOMUX_PAD(0x558, 0x170, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__NANDF_D8 IOMUX_PAD(0x558, 0x170, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__PATA_DATA8 IOMUX_PAD(0x558, 0x170, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D8__SD3_DATA0 IOMUX_PAD(0x558, 0x170, 5, 0x093c, 1, 0)
+#define _MX51_PAD_NANDF_D7__GPIO4_1 IOMUX_PAD(0x55c, 0x174, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__NANDF_D7 IOMUX_PAD(0x55c, 0x174, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__PATA_DATA7 IOMUX_PAD(0x55c, 0x174, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D7__USBH3_DATA0 IOMUX_PAD(0x55c, 0x174, 5, 0x09fc, 0, 0)
+#define _MX51_PAD_NANDF_D6__GPIO4_2 IOMUX_PAD(0x560, 0x178, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__NANDF_D6 IOMUX_PAD(0x560, 0x178, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__PATA_DATA6 IOMUX_PAD(0x560, 0x178, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__SD4_LCTL IOMUX_PAD(0x560, 0x178, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D6__USBH3_DATA1 IOMUX_PAD(0x560, 0x178, 5, 0x0a00, 0, 0)
+#define _MX51_PAD_NANDF_D5__GPIO4_3 IOMUX_PAD(0x564, 0x17c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__NANDF_D5 IOMUX_PAD(0x564, 0x17c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__PATA_DATA5 IOMUX_PAD(0x564, 0x17c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__SD4_WP IOMUX_PAD(0x564, 0x17c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D5__USBH3_DATA2 IOMUX_PAD(0x564, 0x17c, 5, 0x0a04, 0, 0)
+#define _MX51_PAD_NANDF_D4__GPIO4_4 IOMUX_PAD(0x568, 0x180, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__NANDF_D4 IOMUX_PAD(0x568, 0x180, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__PATA_DATA4 IOMUX_PAD(0x568, 0x180, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__SD4_CD IOMUX_PAD(0x568, 0x180, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D4__USBH3_DATA3 IOMUX_PAD(0x568, 0x180, 5, 0x0a08, 0, 0)
+#define _MX51_PAD_NANDF_D3__GPIO4_5 IOMUX_PAD(0x56c, 0x184, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__NANDF_D3 IOMUX_PAD(0x56c, 0x184, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__PATA_DATA3 IOMUX_PAD(0x56c, 0x184, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__SD4_DAT4 IOMUX_PAD(0x56c, 0x184, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D3__USBH3_DATA4 IOMUX_PAD(0x56c, 0x184, 5, 0x0a0c, 0, 0)
+#define _MX51_PAD_NANDF_D2__GPIO4_6 IOMUX_PAD(0x570, 0x188, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__NANDF_D2 IOMUX_PAD(0x570, 0x188, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__PATA_DATA2 IOMUX_PAD(0x570, 0x188, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__SD4_DAT5 IOMUX_PAD(0x570, 0x188, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D2__USBH3_DATA5 IOMUX_PAD(0x570, 0x188, 5, 0x0a10, 0, 0)
+#define _MX51_PAD_NANDF_D1__GPIO4_7 IOMUX_PAD(0x574, 0x18c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__NANDF_D1 IOMUX_PAD(0x574, 0x18c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__PATA_DATA1 IOMUX_PAD(0x574, 0x18c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__SD4_DAT6 IOMUX_PAD(0x574, 0x18c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D1__USBH3_DATA6 IOMUX_PAD(0x574, 0x18c, 5, 0x0a14, 0, 0)
+#define _MX51_PAD_NANDF_D0__GPIO4_8 IOMUX_PAD(0x578, 0x190, 3, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__NANDF_D0 IOMUX_PAD(0x578, 0x190, 0, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__PATA_DATA0 IOMUX_PAD(0x578, 0x190, 1, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__SD4_DAT7 IOMUX_PAD(0x578, 0x190, 2, 0x0000, 0, 0)
+#define _MX51_PAD_NANDF_D0__USBH3_DATA7 IOMUX_PAD(0x578, 0x190, 5, 0x0a18, 0, 0)
+#define _MX51_PAD_CSI1_D8__CSI1_D8 IOMUX_PAD(0x57c, 0x194, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D8__GPIO3_12 IOMUX_PAD(0x57c, 0x194, 3, 0x0998, 1, 0)
+#define _MX51_PAD_CSI1_D9__CSI1_D9 IOMUX_PAD(0x580, 0x198, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D9__GPIO3_13 IOMUX_PAD(0x580, 0x198, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1a0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58c, 0x1a4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1a8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59c, 0x1b4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5a0, 0x1b8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5a4, 0x1bc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5a8, 0x1c0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5ac, 0x1c4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_VSYNC__GPIO3_14 IOMUX_PAD(0x5ac, 0x1c4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5b0, 0x1c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_HSYNC__GPIO3_15 IOMUX_PAD(0x5b0, 0x1c8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5b4, 0x000, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5b8, 0x000, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D12__CSI2_D12 IOMUX_PAD(0x5bc, 0x1cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D12__GPIO4_9 IOMUX_PAD(0x5bc, 0x1cc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D13__CSI2_D13 IOMUX_PAD(0x5c0, 0x1d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D13__GPIO4_10 IOMUX_PAD(0x5c0, 0x1d0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D14__CSI2_D14 IOMUX_PAD(0x5c4, 0x1d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D15__CSI2_D15 IOMUX_PAD(0x5c8, 0x1d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D16__CSI2_D16 IOMUX_PAD(0x5cc, 0x1dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D17__CSI2_D17 IOMUX_PAD(0x5d0, 0x1e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D18__CSI2_D18 IOMUX_PAD(0x5d4, 0x1e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D18__GPIO4_11 IOMUX_PAD(0x5d4, 0x1e4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D19__CSI2_D19 IOMUX_PAD(0x5d8, 0x1e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_D19__GPIO4_12 IOMUX_PAD(0x5d8, 0x1e8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_VSYNC__CSI2_VSYNC IOMUX_PAD(0x5dc, 0x1ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_VSYNC__GPIO4_13 IOMUX_PAD(0x5dc, 0x1ec, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_HSYNC__CSI2_HSYNC IOMUX_PAD(0x5e0, 0x1f0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_HSYNC__GPIO4_14 IOMUX_PAD(0x5e0, 0x1f0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK IOMUX_PAD(0x5e4, 0x1f4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSI2_PIXCLK__GPIO4_15 IOMUX_PAD(0x5e4, 0x1f4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_CLK__GPIO4_16 IOMUX_PAD(0x5e8, 0x1f8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_CLK__I2C1_CLK IOMUX_PAD(0x5e8, 0x1f8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_DAT__GPIO4_17 IOMUX_PAD(0x5ec, 0x1fc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_I2C1_DAT__I2C1_DAT IOMUX_PAD(0x5ec, 0x1fc, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_TXD__AUD3_TXD IOMUX_PAD(0x5f0, 0x200, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_TXD__GPIO4_18 IOMUX_PAD(0x5f0, 0x200, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__AUD3_RXD IOMUX_PAD(0x5f4, 0x204, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__GPIO4_19 IOMUX_PAD(0x5f4, 0x204, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_RXD__UART3_RXD IOMUX_PAD(0x5f4, 0x204, 1, 0x09f4, 2, 0)
+#define _MX51_PAD_AUD3_BB_CK__AUD3_TXC IOMUX_PAD(0x5f8, 0x208, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_CK__GPIO4_20 IOMUX_PAD(0x5f8, 0x208, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__AUD3_TXFS IOMUX_PAD(0x5fc, 0x20c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__GPIO4_21 IOMUX_PAD(0x5fc, 0x20c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_AUD3_BB_FS__UART3_TXD IOMUX_PAD(0x5fc, 0x20c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI IOMUX_PAD(0x600, 0x210, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__GPIO4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MOSI__I2C1_SDA IOMUX_PAD(0x600, 0x210, 0x11, 0x09b4, 1, 0)
+#define _MX51_PAD_CSPI1_MISO__AUD4_RXD IOMUX_PAD(0x604, 0x214, 1, 0x08c4, 1, 0)
+#define _MX51_PAD_CSPI1_MISO__ECSPI1_MISO IOMUX_PAD(0x604, 0x214, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_MISO__GPIO4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS0__AUD4_TXC IOMUX_PAD(0x608, 0x218, 1, 0x08cc, 1, 0)
+#define _MX51_PAD_CSPI1_SS0__ECSPI1_SS0 IOMUX_PAD(0x608, 0x218, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS0__GPIO4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS1__AUD4_TXD IOMUX_PAD(0x60c, 0x21c, 1, 0x08c8, 1, 0)
+#define _MX51_PAD_CSPI1_SS1__ECSPI1_SS1 IOMUX_PAD(0x60c, 0x21c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SS1__GPIO4_25 IOMUX_PAD(0x60c, 0x21c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_RDY__AUD4_TXFS IOMUX_PAD(0x610, 0x220, 1, 0x08d0, 1, 0)
+#define _MX51_PAD_CSPI1_RDY__ECSPI1_RDY IOMUX_PAD(0x610, 0x220, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_RDY__GPIO4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK IOMUX_PAD(0x614, 0x224, 0, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__GPIO4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0000, 0, 0)
+#define _MX51_PAD_CSPI1_SCLK__I2C1_SCL IOMUX_PAD(0x614, 0x224, 0x11, 0x09b0, 1, 0)
+#define _MX51_PAD_UART1_RXD__GPIO4_28 IOMUX_PAD(0x618, 0x228, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x09e4, 0, 0)
+#define _MX51_PAD_UART1_TXD__GPIO4_29 IOMUX_PAD(0x61c, 0x22c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_TXD__PWM2_PWMO IOMUX_PAD(0x61c, 0x22c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61c, 0x22c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RTS__GPIO4_30 IOMUX_PAD(0x620, 0x230, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, 0, 0x09e0, 0, 0)
+#define _MX51_PAD_UART1_CTS__GPIO4_31 IOMUX_PAD(0x624, 0x234, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__FIRI_TXD IOMUX_PAD(0x628, 0x238, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__GPIO1_20 IOMUX_PAD(0x628, 0x238, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, 0, 0x09ec, 2, 0)
+#define _MX51_PAD_UART2_TXD__FIRI_RXD IOMUX_PAD(0x62c, 0x23c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_TXD__GPIO1_21 IOMUX_PAD(0x62c, 0x23c, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62c, 0x23c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__CSI1_D0 IOMUX_PAD(0x630, 0x240, 2, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__GPIO1_22 IOMUX_PAD(0x630, 0x240, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__UART1_DTR IOMUX_PAD(0x630, 0x240, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x630, 0x240, 1, 0x09f4, 4, 0)
+#define _MX51_PAD_UART3_TXD__CSI1_D1 IOMUX_PAD(0x634, 0x244, 2, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__GPIO1_23 IOMUX_PAD(0x634, 0x244, 3, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__UART1_DSR IOMUX_PAD(0x634, 0x244, 0, 0x0000, 0, 0)
+#define _MX51_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x634, 0x244, 1, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__GPIO1_24 IOMUX_PAD(0x638, 0x248, 3, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__OWIRE_LINE IOMUX_PAD(0x638, 0x248, 0, 0x0000, 0, 0)
+#define _MX51_PAD_OWIRE_LINE__SPDIF_OUT IOMUX_PAD(0x638, 0x248, 6, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63c, 0x24c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64c, 0x25c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL0__PLL1_BYP IOMUX_PAD(0x64c, 0x25c, 7, 0x090c, 0, 0)
+#define _MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL1__PLL2_BYP IOMUX_PAD(0x650, 0x260, 7, 0x0910, 0, 0)
+#define _MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL2__PLL3_BYP IOMUX_PAD(0x654, 0x264, 7, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__I2C2_SCL IOMUX_PAD(0x65c, 0x26c, 0x13, 0x09b8, 1, 0)
+#define _MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65c, 0x26c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__SPDIF_OUT1 IOMUX_PAD(0x65c, 0x26c, 6, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__UART1_RI IOMUX_PAD(0x65c, 0x26c, 1, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL4__UART3_RTS IOMUX_PAD(0x65c, 0x26c, 2, 0x09f0, 4, 0)
+#define _MX51_PAD_KEY_COL5__I2C2_SDA IOMUX_PAD(0x660, 0x270, 0x13, 0x09bc, 1, 0)
+#define _MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL5__UART1_DCD IOMUX_PAD(0x660, 0x270, 1, 0x0000, 0, 0)
+#define _MX51_PAD_KEY_COL5__UART3_CTS IOMUX_PAD(0x660, 0x270, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_CLK__CSPI_SCLK IOMUX_PAD(0x678, 0x278, 1, 0x0914, 1, 0)
+#define _MX51_PAD_USBH1_CLK__GPIO1_25 IOMUX_PAD(0x678, 0x278, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_CLK__I2C2_SCL IOMUX_PAD(0x678, 0x278, 0x15, 0x09b8, 2, 0)
+#define _MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DIR__CSPI_MOSI IOMUX_PAD(0x67c, 0x27c, 1, 0x091c, 1, 0)
+#define _MX51_PAD_USBH1_DIR__GPIO1_26 IOMUX_PAD(0x67c, 0x27c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DIR__I2C2_SDA IOMUX_PAD(0x67c, 0x27c, 0x15, 0x09bc, 2, 0)
+#define _MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67c, 0x27c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__CSPI_RDY IOMUX_PAD(0x680, 0x280, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__GPIO1_27 IOMUX_PAD(0x680, 0x280, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_STP__UART3_RXD IOMUX_PAD(0x680, 0x280, 5, 0x09f4, 6, 0)
+#define _MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__CSPI_MISO IOMUX_PAD(0x684, 0x284, 1, 0x0918, 0, 0)
+#define _MX51_PAD_USBH1_NXT__GPIO1_28 IOMUX_PAD(0x684, 0x284, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__UART3_TXD IOMUX_PAD(0x684, 0x284, 5, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__GPIO1_11 IOMUX_PAD(0x688, 0x288, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__UART2_CTS IOMUX_PAD(0x688, 0x288, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA1__GPIO1_12 IOMUX_PAD(0x68c, 0x28c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA1__UART2_RXD IOMUX_PAD(0x68c, 0x28c, 1, 0x09ec, 4, 0)
+#define _MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68c, 0x28c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA2__GPIO1_13 IOMUX_PAD(0x690, 0x290, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA2__UART2_TXD IOMUX_PAD(0x690, 0x290, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA3__GPIO1_14 IOMUX_PAD(0x694, 0x294, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA3__UART2_RTS IOMUX_PAD(0x694, 0x294, 1, 0x09e8, 5, 0)
+#define _MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__CSPI_SS0 IOMUX_PAD(0x698, 0x298, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__GPIO1_15 IOMUX_PAD(0x698, 0x298, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__CSPI_SS1 IOMUX_PAD(0x69c, 0x29c, 1, 0x0920, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__GPIO1_16 IOMUX_PAD(0x69c, 0x29c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69c, 0x29c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA6__CSPI_SS3 IOMUX_PAD(0x6a0, 0x2a0, 1, 0x0928, 1, 0)
+#define _MX51_PAD_USBH1_DATA6__GPIO1_17 IOMUX_PAD(0x6a0, 0x2a0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6a0, 0x2a0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__ECSPI1_SS3 IOMUX_PAD(0x6a4, 0x2a4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__ECSPI2_SS3 IOMUX_PAD(0x6a4, 0x2a4, 5, 0x0934, 1, 0)
+#define _MX51_PAD_USBH1_DATA7__GPIO1_18 IOMUX_PAD(0x6a4, 0x2a4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6a4, 0x2a4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__DI1_PIN11 IOMUX_PAD(0x6a8, 0x2a8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__ECSPI1_SS2 IOMUX_PAD(0x6a8, 0x2a8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN11__GPIO3_0 IOMUX_PAD(0x6a8, 0x2a8, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN12__DI1_PIN12 IOMUX_PAD(0x6ac, 0x2ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN12__GPIO3_1 IOMUX_PAD(0x6ac, 0x2ac, 4, 0x0978, 1, 0)
+#define _MX51_PAD_DI1_PIN13__DI1_PIN13 IOMUX_PAD(0x6b0, 0x2b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN13__GPIO3_2 IOMUX_PAD(0x6b0, 0x2b0, 4, 0x097c, 1, 0)
+#define _MX51_PAD_DI1_D0_CS__DI1_D0_CS IOMUX_PAD(0x6b4, 0x2b4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D0_CS__GPIO3_3 IOMUX_PAD(0x6b4, 0x2b4, 4, 0x0980, 1, 0)
+#define _MX51_PAD_DI1_D1_CS__DI1_D1_CS IOMUX_PAD(0x6b8, 0x2b8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__DISP1_PIN14 IOMUX_PAD(0x6b8, 0x2b8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__DISP1_PIN5 IOMUX_PAD(0x6b8, 0x2b8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_D1_CS__GPIO3_4 IOMUX_PAD(0x6b8, 0x2b8, 4, 0x0984, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 IOMUX_PAD(0x6bc, 0x2bc, 2, 0x09a4, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN IOMUX_PAD(0x6bc, 0x2bc, 0, 0x09c4, 0, 0)
+#define _MX51_PAD_DISPB2_SER_DIN__GPIO3_5 IOMUX_PAD(0x6bc, 0x2bc, 4, 0x0988, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 IOMUX_PAD(0x6c0, 0x2c0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO IOMUX_PAD(0x6c0, 0x2c0, 0, 0x09c4, 1, 0)
+#define _MX51_PAD_DISPB2_SER_DIO__GPIO3_6 IOMUX_PAD(0x6c0, 0x2c0, 4, 0x098c, 1, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 IOMUX_PAD(0x6c4, 0x2c4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 IOMUX_PAD(0x6c4, 0x2c4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK IOMUX_PAD(0x6c4, 0x2c4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_CLK__GPIO3_7 IOMUX_PAD(0x6c4, 0x2c4, 4, 0x0990, 1, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK IOMUX_PAD(0x6c8, 0x2c8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 IOMUX_PAD(0x6c8, 0x2c8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 IOMUX_PAD(0x6c8, 0x2c8, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS IOMUX_PAD(0x6c8, 0x2c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS IOMUX_PAD(0x6c8, 0x2c8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISPB2_SER_RS__GPIO3_8 IOMUX_PAD(0x6c8, 0x2c8, 4, 0x0994, 1, 0)
+#define _MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6cc, 0x2cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6d0, 0x2d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6d4, 0x2d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6d8, 0x2d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6dc, 0x2dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6e0, 0x2e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT6__BOOT_USB_SRC IOMUX_PAD(0x6e4, 0x2e4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6e4, 0x2e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG IOMUX_PAD(0x6e8, 0x2e8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6e8, 0x2e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT8__BOOT_SRC0 IOMUX_PAD(0x6ec, 0x2ec, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6ec, 0x2ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT9__BOOT_SRC1 IOMUX_PAD(0x6f0, 0x2f0, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6f0, 0x2f0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE IOMUX_PAD(0x6f4, 0x2f4, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6f4, 0x2f4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 IOMUX_PAD(0x6f8, 0x2f8, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6f8, 0x2f8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL IOMUX_PAD(0x6fc, 0x2fc, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6fc, 0x2fc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 IOMUX_PAD(0x700, 0x300, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 IOMUX_PAD(0x704, 0x304, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH IOMUX_PAD(0x708, 0x308, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 IOMUX_PAD(0x70c, 0x30c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70c, 0x30c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 IOMUX_PAD(0x710, 0x310, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 IOMUX_PAD(0x714, 0x314, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP2_PIN11 IOMUX_PAD(0x714, 0x314, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT18__DISP2_PIN5 IOMUX_PAD(0x714, 0x314, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 IOMUX_PAD(0x718, 0x318, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP2_PIN12 IOMUX_PAD(0x718, 0x318, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT19__DISP2_PIN6 IOMUX_PAD(0x718, 0x318, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 IOMUX_PAD(0x71c, 0x31c, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71c, 0x31c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP2_PIN13 IOMUX_PAD(0x71c, 0x31c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT20__DISP2_PIN7 IOMUX_PAD(0x71c, 0x31c, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 IOMUX_PAD(0x720, 0x320, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP2_PIN14 IOMUX_PAD(0x720, 0x320, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT21__DISP2_PIN8 IOMUX_PAD(0x720, 0x320, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 IOMUX_PAD(0x724, 0x324, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP2_D0_CS IOMUX_PAD(0x724, 0x324, 6, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT22__DISP2_DAT16 IOMUX_PAD(0x724, 0x324, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 IOMUX_PAD(0x728, 0x328, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_D1_CS IOMUX_PAD(0x728, 0x328, 6, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_DAT17 IOMUX_PAD(0x728, 0x328, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP1_DAT23__DISP2_SER_CS IOMUX_PAD(0x728, 0x328, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72c, 0x32c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP2__DISP1_SER_CLK IOMUX_PAD(0x740, 0x338, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP2__DISP2_WAIT IOMUX_PAD(0x740, 0x338, 2, 0x09a8, 1, 0)
+#define _MX51_PAD_DI_GP3__CSI1_DATA_EN IOMUX_PAD(0x744, 0x33c, 3, 0x09a0, 1, 0)
+#define _MX51_PAD_DI_GP3__DISP1_SER_DIO IOMUX_PAD(0x744, 0x33c, 0, 0x09c0, 0, 0)
+#define _MX51_PAD_DI_GP3__FEC_TX_ER IOMUX_PAD(0x744, 0x33c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN4__CSI2_DATA_EN IOMUX_PAD(0x748, 0x340, 3, 0x099c, 1, 0)
+#define _MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN4__FEC_CRS IOMUX_PAD(0x748, 0x340, 2, 0x0950, 1, 0)
+#define _MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74c, 0x344, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN2__FEC_MDC IOMUX_PAD(0x74c, 0x344, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_PIN3__FEC_MDIO IOMUX_PAD(0x750, 0x348, 2, 0x0954, 1, 0)
+#define _MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 IOMUX_PAD(0x754, 0x34c, 2, 0x095c, 1, 0)
+#define _MX51_PAD_DI_GP4__DI2_PIN15 IOMUX_PAD(0x758, 0x350, 4, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP4__DISP1_SER_DIN IOMUX_PAD(0x758, 0x350, 0, 0x09c0, 1, 0)
+#define _MX51_PAD_DI_GP4__DISP2_PIN1 IOMUX_PAD(0x758, 0x350, 3, 0x0000, 0, 0)
+#define _MX51_PAD_DI_GP4__FEC_RDATA2 IOMUX_PAD(0x758, 0x350, 2, 0x0960, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75c, 0x354, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT0__FEC_RDATA3 IOMUX_PAD(0x75c, 0x354, 2, 0x0964, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__KEY_COL6 IOMUX_PAD(0x75c, 0x354, 4, 0x09c8, 1, 0)
+#define _MX51_PAD_DISP2_DAT0__UART3_RXD IOMUX_PAD(0x75c, 0x354, 5, 0x09f4, 8, 0)
+#define _MX51_PAD_DISP2_DAT0__USBH3_CLK IOMUX_PAD(0x75c, 0x354, 3, 0x09f8, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT1__FEC_RX_ER IOMUX_PAD(0x760, 0x358, 2, 0x0970, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__KEY_COL7 IOMUX_PAD(0x760, 0x358, 4, 0x09cc, 1, 0)
+#define _MX51_PAD_DISP2_DAT1__UART3_TXD IOMUX_PAD(0x760, 0x358, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT1__USBH3_DIR IOMUX_PAD(0x760, 0x358, 3, 0x0a1c, 1, 0)
+#define _MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76c, 0x364, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__DISP2_DAT6 IOMUX_PAD(0x774, 0x36c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__FEC_TDATA1 IOMUX_PAD(0x774, 0x36c, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT6__KEY_ROW4 IOMUX_PAD(0x774, 0x36c, 4, 0x09d0, 1, 0)
+#define _MX51_PAD_DISP2_DAT6__USBH3_STP IOMUX_PAD(0x774, 0x36c, 3, 0x0a24, 1, 0)
+#define _MX51_PAD_DISP2_DAT7__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__FEC_TDATA2 IOMUX_PAD(0x778, 0x370, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT7__KEY_ROW5 IOMUX_PAD(0x778, 0x370, 4, 0x09d4, 1, 0)
+#define _MX51_PAD_DISP2_DAT7__USBH3_NXT IOMUX_PAD(0x778, 0x370, 3, 0x0a20, 1, 0)
+#define _MX51_PAD_DISP2_DAT8__DISP2_DAT8 IOMUX_PAD(0x77c, 0x374, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__FEC_TDATA3 IOMUX_PAD(0x77c, 0x374, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT8__KEY_ROW6 IOMUX_PAD(0x77c, 0x374, 4, 0x09d8, 1, 0)
+#define _MX51_PAD_DISP2_DAT8__USBH3_DATA0 IOMUX_PAD(0x77c, 0x374, 3, 0x09fc, 1, 0)
+#define _MX51_PAD_DISP2_DAT9__AUD6_RXC IOMUX_PAD(0x780, 0x378, 4, 0x08f4, 1, 0)
+#define _MX51_PAD_DISP2_DAT9__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__FEC_TX_EN IOMUX_PAD(0x780, 0x378, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT9__USBH3_DATA1 IOMUX_PAD(0x780, 0x378, 3, 0x0a00, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT10__DISP2_SER_CS IOMUX_PAD(0x784, 0x37c, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT10__FEC_COL IOMUX_PAD(0x784, 0x37c, 2, 0x094c, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__KEY_ROW7 IOMUX_PAD(0x784, 0x37c, 4, 0x09dc, 1, 0)
+#define _MX51_PAD_DISP2_DAT10__USBH3_DATA2 IOMUX_PAD(0x784, 0x37c, 3, 0x0a04, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__AUD6_TXD IOMUX_PAD(0x788, 0x380, 4, 0x08f0, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x0968, 1, 0)
+#define _MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT11__USBH3_DATA3 IOMUX_PAD(0x788, 0x380, 3, 0x0a08, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__AUD6_RXD IOMUX_PAD(0x78c, 0x384, 4, 0x08ec, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78c, 0x384, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT12__FEC_RX_DV IOMUX_PAD(0x78c, 0x384, 2, 0x096c, 1, 0)
+#define _MX51_PAD_DISP2_DAT12__USBH3_DATA4 IOMUX_PAD(0x78c, 0x384, 3, 0x0a0c, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__AUD6_TXC IOMUX_PAD(0x790, 0x388, 4, 0x08fc, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT13__FEC_TX_CLK IOMUX_PAD(0x790, 0x388, 2, 0x0974, 1, 0)
+#define _MX51_PAD_DISP2_DAT13__USBH3_DATA5 IOMUX_PAD(0x790, 0x388, 3, 0x0a10, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__AUD6_TXFS IOMUX_PAD(0x794, 0x38c, 4, 0x0900, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT14__FEC_RDATA0 IOMUX_PAD(0x794, 0x38c, 2, 0x0958, 1, 0)
+#define _MX51_PAD_DISP2_DAT14__USBH3_DATA6 IOMUX_PAD(0x794, 0x38c, 3, 0x0a14, 1, 0)
+#define _MX51_PAD_DISP2_DAT15__AUD6_RXFS IOMUX_PAD(0x798, 0x390, 4, 0x08f8, 1, 0)
+#define _MX51_PAD_DISP2_DAT15__DISP1_SER_CS IOMUX_PAD(0x798, 0x390, 5, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__FEC_TDATA0 IOMUX_PAD(0x798, 0x390, 2, 0x0000, 0, 0)
+#define _MX51_PAD_DISP2_DAT15__USBH3_DATA7 IOMUX_PAD(0x798, 0x390, 3, 0x0a18, 1, 0)
+#define _MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79c, 0x394, 1, 0x08e0, 1, 0)
+#define _MX51_PAD_SD1_CMD__CSPI_MOSI IOMUX_PAD(0x79c, 0x394, 2, 0x091c, 2, 0)
+#define _MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79c, 0x394, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_CLK__AUD5_RXC IOMUX_PAD(0x7a0, 0x398, 1, 0x08dc, 1, 0)
+#define _MX51_PAD_SD1_CLK__CSPI_SCLK IOMUX_PAD(0x7a0, 0x398, 2, 0x0914, 2, 0)
+#define _MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7a0, 0x398, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7a4, 0x39c, 1, 0x08d8, 2, 0)
+#define _MX51_PAD_SD1_DATA0__CSPI_MISO IOMUX_PAD(0x7a4, 0x39c, 2, 0x0918, 1, 0)
+#define _MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7a4, 0x39c, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x000, 0x01c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x000, 0x020, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x000, 0x024, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x000, 0x028, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA1__AUD5_RXD IOMUX_PAD(0x7a8, 0x3a0, 1, 0x08d4, 2, 0)
+#define _MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7a8, 0x3a0, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x000, 0x02c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x000, 0x030, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x000, 0x034, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x000, 0x038, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA2__AUD5_TXC IOMUX_PAD(0x7ac, 0x3a4, 1, 0x08e4, 2, 0)
+#define _MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7ac, 0x3a4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x000, 0x044, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x000, 0x048, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x000, 0x03c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x000, 0x040, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7b0, 0x3a8, 1, 0x08e8, 2, 0)
+#define _MX51_PAD_SD1_DATA3__CSPI_SS1 IOMUX_PAD(0x7b0, 0x3a8, 2, 0x0920, 1, 0)
+#define _MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7b0, 0x3a8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_0__CSPI_SS2 IOMUX_PAD(0x7b4, 0x3ac, 2, 0x0924, 0, 0)
+#define _MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_0__SD1_CD IOMUX_PAD(0x7b4, 0x3ac, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_1__CSPI_MISO IOMUX_PAD(0x7b8, 0x3b0, 2, 0x0918, 2, 0)
+#define _MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_1__SD1_WP IOMUX_PAD(0x7b8, 0x3b0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x000, 0x04c, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x000, 0x050, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x000, 0x054, 0, 0x0000, 0, 0)
+#define _MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x000, 0x058, 0, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(0x000, 0x3b4, 2, 0x091c, 3, 0)
+#define _MX51_PAD_SD2_CMD__I2C1_SCL IOMUX_PAD(0x7bc, 0x3b4, 0x11, 0x09b0, 2, 0)
+#define _MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7bc, 0x3b4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_CLK__CSPI_SCLK IOMUX_PAD(0x7c0, 0x3b8, 2, 0x0914, 3, 0)
+#define _MX51_PAD_SD2_CLK__I2C1_SDA IOMUX_PAD(0x7c0, 0x3b8, 0x11, 0x09b4, 2, 0)
+#define _MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7c0, 0x3b8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA0__CSPI_MISO IOMUX_PAD(0x7c4, 0x3bc, 2, 0x0918, 3, 0)
+#define _MX51_PAD_SD2_DATA0__SD1_DAT4 IOMUX_PAD(0x7c4, 0x3bc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7c4, 0x3bc, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__SD1_DAT5 IOMUX_PAD(0x7c8, 0x3c0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7c8, 0x3c0, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 2, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__SD1_DAT6 IOMUX_PAD(0x7cc, 0x3c4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7cc, 0x3c4, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA3__CSPI_SS2 IOMUX_PAD(0x7d0, 0x3c8, 2, 0x0924, 1, 0)
+#define _MX51_PAD_SD2_DATA3__SD1_DAT7 IOMUX_PAD(0x7d0, 0x3c8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7d0, 0x3c8, 0x10, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__CCM_OUT_2 IOMUX_PAD(0x7d4, 0x3cc, 5, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_2__I2C2_SCL IOMUX_PAD(0x7d4, 0x3cc, 0x12, 0x09b8, 3, 0)
+#define _MX51_PAD_GPIO1_2__PLL1_BYP IOMUX_PAD(0x7d4, 0x3cc, 7, 0x090c, 1, 0)
+#define _MX51_PAD_GPIO1_2__PWM1_PWMO IOMUX_PAD(0x7d4, 0x3cc, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_3__I2C2_SDA IOMUX_PAD(0x7d8, 0x3d0, 0x12, 0x09bc, 3, 0)
+#define _MX51_PAD_GPIO1_3__PLL2_BYP IOMUX_PAD(0x7d8, 0x3d0, 7, 0x0910, 1, 0)
+#define _MX51_PAD_GPIO1_3__PWM2_PWMO IOMUX_PAD(0x7d8, 0x3d0, 1, 0x0000, 0, 0)
+#define _MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7fc, 0x3d4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B IOMUX_PAD(0x7fc, 0x3d4, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_4__DISP2_EXT_CLK IOMUX_PAD(0x804, 0x3d8, 4, 0x0908, 1, 0)
+#define _MX51_PAD_GPIO1_4__EIM_RDY IOMUX_PAD(0x804, 0x3d8, 3, 0x0938, 1, 0)
+#define _MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_4__WDOG1_WDOG_B IOMUX_PAD(0x804, 0x3d8, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__CSI2_MCLK IOMUX_PAD(0x808, 0x3dc, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__DISP2_PIN16 IOMUX_PAD(0x808, 0x3dc, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_5__WDOG2_WDOG_B IOMUX_PAD(0x808, 0x3dc, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__DISP2_PIN17 IOMUX_PAD(0x80c, 0x3e0, 4, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_6__REF_EN_B IOMUX_PAD(0x80c, 0x3e0, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__CCM_OUT_0 IOMUX_PAD(0x810, 0x3e4, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__SD2_WP IOMUX_PAD(0x810, 0x3e4, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_7__SPDIF_OUT1 IOMUX_PAD(0x810, 0x3e4, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__CSI2_DATA_EN IOMUX_PAD(0x814, 0x3e8, 2, 0x099c, 2, 0)
+#define _MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__SD2_CD IOMUX_PAD(0x814, 0x3e8, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_8__USBH3_PWR IOMUX_PAD(0x814, 0x3e8, 1, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__CCM_OUT_1 IOMUX_PAD(0x818, 0x3ec, 3, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__DISP2_D1_CS IOMUX_PAD(0x818, 0x3ec, 2, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__DISP2_SER_CS IOMUX_PAD(0x818, 0x3ec, 7, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__SD2_LCTL IOMUX_PAD(0x818, 0x3ec, 6, 0x0000, 0, 0)
+#define _MX51_PAD_GPIO1_9__USBH3_OC IOMUX_PAD(0x818, 0x3ec, 1, 0x0000, 0, 0)
+
+/* The same pins as above but with the default pad control values applied */
+#define MX51_PAD_EIM_D16__AUD4_RXFS (_MX51_PAD_EIM_D16__AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__AUD5_TXD (_MX51_PAD_EIM_D16__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__EIM_D16 (_MX51_PAD_EIM_D16__EIM_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__GPIO2_0 (_MX51_PAD_EIM_D16__GPIO2_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D16__I2C1_SDA (_MX51_PAD_EIM_D16__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D16__UART2_CTS (_MX51_PAD_EIM_D16__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D16__USBH2_DATA0 (_MX51_PAD_EIM_D16__USBH2_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__AUD5_RXD (_MX51_PAD_EIM_D17__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__EIM_D17 (_MX51_PAD_EIM_D17__EIM_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__GPIO2_1 (_MX51_PAD_EIM_D17__GPIO2_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D17__UART2_RXD (_MX51_PAD_EIM_D17__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D17__UART3_CTS (_MX51_PAD_EIM_D17__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D17__USBH2_DATA1 (_MX51_PAD_EIM_D17__USBH2_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__AUD5_TXC (_MX51_PAD_EIM_D18__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__EIM_D18 (_MX51_PAD_EIM_D18__EIM_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__GPIO2_2 (_MX51_PAD_EIM_D18__GPIO2_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D18__UART2_TXD (_MX51_PAD_EIM_D18__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D18__UART3_RTS (_MX51_PAD_EIM_D18__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D18__USBH2_DATA2 (_MX51_PAD_EIM_D18__USBH2_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__AUD4_RXC (_MX51_PAD_EIM_D19__AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__AUD5_TXFS (_MX51_PAD_EIM_D19__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__EIM_D19 (_MX51_PAD_EIM_D19__EIM_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__GPIO2_3 (_MX51_PAD_EIM_D19__GPIO2_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D19__I2C1_SCL (_MX51_PAD_EIM_D19__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D19__UART2_RTS (_MX51_PAD_EIM_D19__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D19__USBH2_DATA3 (_MX51_PAD_EIM_D19__USBH2_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__AUD4_TXD (_MX51_PAD_EIM_D20__AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__EIM_D20 (_MX51_PAD_EIM_D20__EIM_D20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__GPIO2_4 (_MX51_PAD_EIM_D20__GPIO2_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__SRTC_ALARM_DEB (_MX51_PAD_EIM_D20__SRTC_ALARM_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D20__USBH2_DATA4 (_MX51_PAD_EIM_D20__USBH2_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__AUD4_RXD (_MX51_PAD_EIM_D21__AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__EIM_D21 (_MX51_PAD_EIM_D21__EIM_D21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__GPIO2_5 (_MX51_PAD_EIM_D21__GPIO2_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__SRTC_ALARM_DEB (_MX51_PAD_EIM_D21__SRTC_ALARM_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D21__USBH2_DATA5 (_MX51_PAD_EIM_D21__USBH2_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__AUD4_TXC (_MX51_PAD_EIM_D22__AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__EIM_D22 (_MX51_PAD_EIM_D22__EIM_D22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__GPIO2_6 (_MX51_PAD_EIM_D22__GPIO2_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D22__USBH2_DATA6 (_MX51_PAD_EIM_D22__USBH2_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__AUD4_TXFS (_MX51_PAD_EIM_D23__AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__EIM_D23 (_MX51_PAD_EIM_D23__EIM_D23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__GPIO2_7 (_MX51_PAD_EIM_D23__GPIO2_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__SPDIF_OUT1 (_MX51_PAD_EIM_D23__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D23__USBH2_DATA7 (_MX51_PAD_EIM_D23__USBH2_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__AUD6_RXFS (_MX51_PAD_EIM_D24__AUD6_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__EIM_D24 (_MX51_PAD_EIM_D24__EIM_D24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__GPIO2_8 (_MX51_PAD_EIM_D24__GPIO2_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D24__I2C2_SDA (_MX51_PAD_EIM_D24__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D24__UART3_CTS (_MX51_PAD_EIM_D24__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D24__USBOTG_DATA0 (_MX51_PAD_EIM_D24__USBOTG_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__EIM_D25 (_MX51_PAD_EIM_D25__EIM_D25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__KEY_COL6 (_MX51_PAD_EIM_D25__KEY_COL6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D25__UART2_CTS (_MX51_PAD_EIM_D25__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D25__UART3_RXD (_MX51_PAD_EIM_D25__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D25__USBOTG_DATA1 (_MX51_PAD_EIM_D25__USBOTG_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__EIM_D26 (_MX51_PAD_EIM_D26__EIM_D26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__KEY_COL7 (_MX51_PAD_EIM_D26__KEY_COL7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D26__UART2_RTS (_MX51_PAD_EIM_D26__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D26__UART3_TXD (_MX51_PAD_EIM_D26__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D26__USBOTG_DATA2 (_MX51_PAD_EIM_D26__USBOTG_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__AUD6_RXC (_MX51_PAD_EIM_D27__AUD6_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__EIM_D27 (_MX51_PAD_EIM_D27__EIM_D27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__GPIO2_9 (_MX51_PAD_EIM_D27__GPIO2_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_D27__I2C2_SCL (_MX51_PAD_EIM_D27__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_EIM_D27__UART3_RTS (_MX51_PAD_EIM_D27__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_EIM_D27__USBOTG_DATA3 (_MX51_PAD_EIM_D27__USBOTG_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__AUD6_TXD (_MX51_PAD_EIM_D28__AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__EIM_D28 (_MX51_PAD_EIM_D28__EIM_D28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__KEY_ROW4 (_MX51_PAD_EIM_D28__KEY_ROW4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D28__USBOTG_DATA4 (_MX51_PAD_EIM_D28__USBOTG_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__AUD6_RXD (_MX51_PAD_EIM_D29__AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__EIM_D29 (_MX51_PAD_EIM_D29__EIM_D29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__KEY_ROW5 (_MX51_PAD_EIM_D29__KEY_ROW5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D29__USBOTG_DATA5 (_MX51_PAD_EIM_D29__USBOTG_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__AUD6_TXC (_MX51_PAD_EIM_D30__AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__EIM_D30 (_MX51_PAD_EIM_D30__EIM_D30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__KEY_ROW6 (_MX51_PAD_EIM_D30__KEY_ROW6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D30__USBOTG_DATA6 (_MX51_PAD_EIM_D30__USBOTG_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__AUD6_TXFS (_MX51_PAD_EIM_D31__AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__EIM_D31 (_MX51_PAD_EIM_D31__EIM_D31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__KEY_ROW7 (_MX51_PAD_EIM_D31__KEY_ROW7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_D31__USBOTG_DATA7 (_MX51_PAD_EIM_D31__USBOTG_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__EIM_A16 (_MX51_PAD_EIM_A16__EIM_A16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__GPIO2_10 (_MX51_PAD_EIM_A16__GPIO2_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A16__OSC_FREQ_SEL0 (_MX51_PAD_EIM_A16__OSC_FREQ_SEL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__EIM_A17 (_MX51_PAD_EIM_A17__EIM_A17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__GPIO2_11 (_MX51_PAD_EIM_A17__GPIO2_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A17__OSC_FREQ_SEL1 (_MX51_PAD_EIM_A17__OSC_FREQ_SEL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__BOOT_LPB0 (_MX51_PAD_EIM_A18__BOOT_LPB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__EIM_A18 (_MX51_PAD_EIM_A18__EIM_A18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A18__GPIO2_12 (_MX51_PAD_EIM_A18__GPIO2_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__BOOT_LPB1 (_MX51_PAD_EIM_A19__BOOT_LPB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__EIM_A19 (_MX51_PAD_EIM_A19__EIM_A19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A19__GPIO2_13 (_MX51_PAD_EIM_A19__GPIO2_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__BOOT_UART_SRC0 (_MX51_PAD_EIM_A20__BOOT_UART_SRC0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__EIM_A20 (_MX51_PAD_EIM_A20__EIM_A20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A20__GPIO2_14 (_MX51_PAD_EIM_A20__GPIO2_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__BOOT_UART_SRC1 (_MX51_PAD_EIM_A21__BOOT_UART_SRC1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__EIM_A21 (_MX51_PAD_EIM_A21__EIM_A21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A21__GPIO2_15 (_MX51_PAD_EIM_A21__GPIO2_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A22__EIM_A22 (_MX51_PAD_EIM_A22__EIM_A22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A22__GPIO2_16 (_MX51_PAD_EIM_A22__GPIO2_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__BOOT_HPN_EN (_MX51_PAD_EIM_A23__BOOT_HPN_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__EIM_A23 (_MX51_PAD_EIM_A23__EIM_A23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A23__GPIO2_17 (_MX51_PAD_EIM_A23__GPIO2_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__EIM_A24 (_MX51_PAD_EIM_A24__EIM_A24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__GPIO2_18 (_MX51_PAD_EIM_A24__GPIO2_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A24__USBH2_CLK (_MX51_PAD_EIM_A24__USBH2_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__DISP1_PIN4 (_MX51_PAD_EIM_A25__DISP1_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__EIM_A25 (_MX51_PAD_EIM_A25__EIM_A25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__GPIO2_19 (_MX51_PAD_EIM_A25__GPIO2_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A25__USBH2_DIR (_MX51_PAD_EIM_A25__USBH2_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__CSI1_DATA_EN (_MX51_PAD_EIM_A26__CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__DISP2_EXT_CLK (_MX51_PAD_EIM_A26__DISP2_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__EIM_A26 (_MX51_PAD_EIM_A26__EIM_A26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__GPIO2_20 (_MX51_PAD_EIM_A26__GPIO2_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A26__USBH2_STP (_MX51_PAD_EIM_A26__USBH2_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__CSI2_DATA_EN (_MX51_PAD_EIM_A27__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__DISP1_PIN1 (_MX51_PAD_EIM_A27__DISP1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__EIM_A27 (_MX51_PAD_EIM_A27__EIM_A27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__GPIO2_21 (_MX51_PAD_EIM_A27__GPIO2_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_A27__USBH2_NXT (_MX51_PAD_EIM_A27__USBH2_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB0__EIM_EB0 (_MX51_PAD_EIM_EB0__EIM_EB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB1__EIM_EB1 (_MX51_PAD_EIM_EB1__EIM_EB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__AUD5_RXFS (_MX51_PAD_EIM_EB2__AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__CSI1_D2 (_MX51_PAD_EIM_EB2__CSI1_D2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__EIM_EB2 (_MX51_PAD_EIM_EB2__EIM_EB2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__FEC_MDIO (_MX51_PAD_EIM_EB2__FEC_MDIO | \
+ MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP | PAD_CTL_PKE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS))
+#define MX51_PAD_EIM_EB2__GPIO2_22 (_MX51_PAD_EIM_EB2__GPIO2_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_EB2__GPT_CMPOUT1 (_MX51_PAD_EIM_EB2__GPT_CMPOUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__AUD5_RXC (_MX51_PAD_EIM_EB3__AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__CSI1_D3 (_MX51_PAD_EIM_EB3__CSI1_D3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__EIM_EB3 (_MX51_PAD_EIM_EB3__EIM_EB3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__FEC_RDATA1 (_MX51_PAD_EIM_EB3__FEC_RDATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__GPIO2_23 (_MX51_PAD_EIM_EB3__GPIO2_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_EB3__GPT_CMPOUT2 (_MX51_PAD_EIM_EB3__GPT_CMPOUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_OE__EIM_OE (_MX51_PAD_EIM_OE__EIM_OE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_OE__GPIO2_24 (_MX51_PAD_EIM_OE__GPIO2_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS0__EIM_CS0 (_MX51_PAD_EIM_CS0__EIM_CS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS0__GPIO2_25 (_MX51_PAD_EIM_CS0__GPIO2_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS1__EIM_CS1 (_MX51_PAD_EIM_CS1__EIM_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS1__GPIO2_26 (_MX51_PAD_EIM_CS1__GPIO2_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__AUD5_TXD (_MX51_PAD_EIM_CS2__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__CSI1_D4 (_MX51_PAD_EIM_CS2__CSI1_D4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__EIM_CS2 (_MX51_PAD_EIM_CS2__EIM_CS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__FEC_RDATA2 (_MX51_PAD_EIM_CS2__FEC_RDATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__GPIO2_27 (_MX51_PAD_EIM_CS2__GPIO2_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS2__USBOTG_STP (_MX51_PAD_EIM_CS2__USBOTG_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__AUD5_RXD (_MX51_PAD_EIM_CS3__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__CSI1_D5 (_MX51_PAD_EIM_CS3__CSI1_D5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__EIM_CS3 (_MX51_PAD_EIM_CS3__EIM_CS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__FEC_RDATA3 (_MX51_PAD_EIM_CS3__FEC_RDATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__GPIO2_28 (_MX51_PAD_EIM_CS3__GPIO2_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS3__USBOTG_NXT (_MX51_PAD_EIM_CS3__USBOTG_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__AUD5_TXC (_MX51_PAD_EIM_CS4__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__CSI1_D6 (_MX51_PAD_EIM_CS4__CSI1_D6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__EIM_CS4 (_MX51_PAD_EIM_CS4__EIM_CS4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__FEC_RX_ER (_MX51_PAD_EIM_CS4__FEC_RX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_EIM_CS4__GPIO2_29 (_MX51_PAD_EIM_CS4__GPIO2_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS4__USBOTG_CLK (_MX51_PAD_EIM_CS4__USBOTG_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__AUD5_TXFS (_MX51_PAD_EIM_CS5__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__CSI1_D7 (_MX51_PAD_EIM_CS5__CSI1_D7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__DISP1_EXT_CLK (_MX51_PAD_EIM_CS5__DISP1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__EIM_CS5 (_MX51_PAD_EIM_CS5__EIM_CS5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__FEC_CRS (_MX51_PAD_EIM_CS5__FEC_CRS | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_EIM_CS5__GPIO2_30 (_MX51_PAD_EIM_CS5__GPIO2_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CS5__USBOTG_DIR (_MX51_PAD_EIM_CS5__USBOTG_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DTACK__EIM_DTACK (_MX51_PAD_EIM_DTACK__EIM_DTACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DTACK__GPIO2_31 (_MX51_PAD_EIM_DTACK__GPIO2_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_LBA__EIM_LBA (_MX51_PAD_EIM_LBA__EIM_LBA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_LBA__GPIO3_1 (_MX51_PAD_EIM_LBA__GPIO3_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_EIM_CRE__EIM_CRE (_MX51_PAD_EIM_CRE__EIM_CRE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_CRE__GPIO3_2 (_MX51_PAD_EIM_CRE__GPIO3_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DRAM_CS1__DRAM_CS1 (_MX51_PAD_DRAM_CS1__DRAM_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__GPIO3_3 (_MX51_PAD_NANDF_WE_B__GPIO3_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__NANDF_WE_B (_MX51_PAD_NANDF_WE_B__NANDF_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__PATA_DIOW (_MX51_PAD_NANDF_WE_B__PATA_DIOW | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WE_B__SD3_DATA0 (_MX51_PAD_NANDF_WE_B__SD3_DATA0 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__GPIO3_4 (_MX51_PAD_NANDF_RE_B__GPIO3_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__NANDF_RE_B (_MX51_PAD_NANDF_RE_B__NANDF_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__PATA_DIOR (_MX51_PAD_NANDF_RE_B__PATA_DIOR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RE_B__SD3_DATA1 (_MX51_PAD_NANDF_RE_B__SD3_DATA1 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__GPIO3_5 (_MX51_PAD_NANDF_ALE__GPIO3_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__NANDF_ALE (_MX51_PAD_NANDF_ALE__NANDF_ALE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_ALE__PATA_BUFFER_EN (_MX51_PAD_NANDF_ALE__PATA_BUFFER_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__GPIO3_6 (_MX51_PAD_NANDF_CLE__GPIO3_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__NANDF_CLE (_MX51_PAD_NANDF_CLE__NANDF_CLE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CLE__PATA_RESET_B (_MX51_PAD_NANDF_CLE__PATA_RESET_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__GPIO3_7 (_MX51_PAD_NANDF_WP_B__GPIO3_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__NANDF_WP_B (_MX51_PAD_NANDF_WP_B__NANDF_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__PATA_DMACK (_MX51_PAD_NANDF_WP_B__PATA_DMACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_WP_B__SD3_DATA2 (_MX51_PAD_NANDF_WP_B__SD3_DATA2 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__ECSPI2_SS1 (_MX51_PAD_NANDF_RB0__ECSPI2_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__GPIO3_8 (_MX51_PAD_NANDF_RB0__GPIO3_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__NANDF_RB0 (_MX51_PAD_NANDF_RB0__NANDF_RB0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__PATA_DMARQ (_MX51_PAD_NANDF_RB0__PATA_DMARQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB0__SD3_DATA3 (_MX51_PAD_NANDF_RB0__SD3_DATA3 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__CSPI_MOSI (_MX51_PAD_NANDF_RB1__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__ECSPI2_RDY (_MX51_PAD_NANDF_RB1__ECSPI2_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__GPIO3_9 (_MX51_PAD_NANDF_RB1__GPIO3_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__NANDF_RB1 (_MX51_PAD_NANDF_RB1__NANDF_RB1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__PATA_IORDY (_MX51_PAD_NANDF_RB1__PATA_IORDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB1__SD4_CMD (_MX51_PAD_NANDF_RB1__SD4_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__DISP2_WAIT (_MX51_PAD_NANDF_RB2__DISP2_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK (_MX51_PAD_NANDF_RB2__ECSPI2_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__FEC_COL (_MX51_PAD_NANDF_RB2__FEC_COL | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_NANDF_RB2__GPIO3_10 (_MX51_PAD_NANDF_RB2__GPIO3_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__NANDF_RB2 (_MX51_PAD_NANDF_RB2__NANDF_RB2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__USBH3_H3_DP (_MX51_PAD_NANDF_RB2__USBH3_H3_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB2__USBH3_NXT (_MX51_PAD_NANDF_RB2__USBH3_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__DISP1_WAIT (_MX51_PAD_NANDF_RB3__DISP1_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO (_MX51_PAD_NANDF_RB3__ECSPI2_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__FEC_RX_CLK (_MX51_PAD_NANDF_RB3__FEC_RX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_2))
+#define MX51_PAD_NANDF_RB3__GPIO3_11 (_MX51_PAD_NANDF_RB3__GPIO3_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__NANDF_RB3 (_MX51_PAD_NANDF_RB3__NANDF_RB3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__USBH3_CLK (_MX51_PAD_NANDF_RB3__USBH3_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RB3__USBH3_H3_DM (_MX51_PAD_NANDF_RB3__USBH3_H3_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO_NAND__GPIO_NAND (_MX51_PAD_GPIO_NAND__GPIO_NAND | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_GPIO_NAND__PATA_INTRQ (_MX51_PAD_GPIO_NAND__PATA_INTRQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS0__GPIO3_16 (_MX51_PAD_NANDF_CS0__GPIO3_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS0__NANDF_CS0 (_MX51_PAD_NANDF_CS0__NANDF_CS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS1__GPIO3_17 (_MX51_PAD_NANDF_CS1__GPIO3_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS1__NANDF_CS1 (_MX51_PAD_NANDF_CS1__NANDF_CS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__CSPI_SCLK (_MX51_PAD_NANDF_CS2__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER (_MX51_PAD_NANDF_CS2__FEC_TX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS2__GPIO3_18 (_MX51_PAD_NANDF_CS2__GPIO3_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__NANDF_CS2 (_MX51_PAD_NANDF_CS2__NANDF_CS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__PATA_CS_0 (_MX51_PAD_NANDF_CS2__PATA_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS2__SD4_CLK (_MX51_PAD_NANDF_CS2__SD4_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_NANDF_CS2__USBH3_H1_DP (_MX51_PAD_NANDF_CS2__USBH3_H1_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__FEC_MDC (_MX51_PAD_NANDF_CS3__FEC_MDC | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS3__GPIO3_19 (_MX51_PAD_NANDF_CS3__GPIO3_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__NANDF_CS3 (_MX51_PAD_NANDF_CS3__NANDF_CS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__PATA_CS_1 (_MX51_PAD_NANDF_CS3__PATA_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__SD4_DAT0 (_MX51_PAD_NANDF_CS3__SD4_DAT0 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS3__USBH3_H1_DM (_MX51_PAD_NANDF_CS3__USBH3_H1_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__FEC_TDATA1 (_MX51_PAD_NANDF_CS4__FEC_TDATA1 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS4__GPIO3_20 (_MX51_PAD_NANDF_CS4__GPIO3_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__NANDF_CS4 (_MX51_PAD_NANDF_CS4__NANDF_CS4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__PATA_DA_0 (_MX51_PAD_NANDF_CS4__PATA_DA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__SD4_DAT1 (_MX51_PAD_NANDF_CS4__SD4_DAT1 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS4__USBH3_STP (_MX51_PAD_NANDF_CS4__USBH3_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__FEC_TDATA2 (_MX51_PAD_NANDF_CS5__FEC_TDATA2 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS5__GPIO3_21 (_MX51_PAD_NANDF_CS5__GPIO3_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__NANDF_CS5 (_MX51_PAD_NANDF_CS5__NANDF_CS5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__PATA_DA_1 (_MX51_PAD_NANDF_CS5__PATA_DA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__SD4_DAT2 (_MX51_PAD_NANDF_CS5__SD4_DAT2 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS5__USBH3_DIR (_MX51_PAD_NANDF_CS5__USBH3_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__CSPI_SS3 (_MX51_PAD_NANDF_CS6__CSPI_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__FEC_TDATA3 (_MX51_PAD_NANDF_CS6__FEC_TDATA3 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS6__GPIO3_22 (_MX51_PAD_NANDF_CS6__GPIO3_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__NANDF_CS6 (_MX51_PAD_NANDF_CS6__NANDF_CS6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__PATA_DA_2 (_MX51_PAD_NANDF_CS6__PATA_DA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS6__SD4_DAT3 (_MX51_PAD_NANDF_CS6__SD4_DAT3 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN (_MX51_PAD_NANDF_CS7__FEC_TX_EN | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_CS7__GPIO3_23 (_MX51_PAD_NANDF_CS7__GPIO3_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__NANDF_CS7 (_MX51_PAD_NANDF_CS7__NANDF_CS7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_CS7__SD3_CLK (_MX51_PAD_NANDF_CS7__SD3_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 (_MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK (_MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_NANDF_RDY_INT__GPIO3_24 (_MX51_PAD_NANDF_RDY_INT__GPIO3_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT (_MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_RDY_INT__SD3_CMD (_MX51_PAD_NANDF_RDY_INT__SD3_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI (_MX51_PAD_NANDF_D15__ECSPI2_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__GPIO3_25 (_MX51_PAD_NANDF_D15__GPIO3_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__NANDF_D15 (_MX51_PAD_NANDF_D15__NANDF_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__PATA_DATA15 (_MX51_PAD_NANDF_D15__PATA_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D15__SD3_DAT7 (_MX51_PAD_NANDF_D15__SD3_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__ECSPI2_SS3 (_MX51_PAD_NANDF_D14__ECSPI2_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__GPIO3_26 (_MX51_PAD_NANDF_D14__GPIO3_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__NANDF_D14 (_MX51_PAD_NANDF_D14__NANDF_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__PATA_DATA14 (_MX51_PAD_NANDF_D14__PATA_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D14__SD3_DAT6 (_MX51_PAD_NANDF_D14__SD3_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__ECSPI2_SS2 (_MX51_PAD_NANDF_D13__ECSPI2_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__GPIO3_27 (_MX51_PAD_NANDF_D13__GPIO3_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__NANDF_D13 (_MX51_PAD_NANDF_D13__NANDF_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__PATA_DATA13 (_MX51_PAD_NANDF_D13__PATA_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D13__SD3_DAT5 (_MX51_PAD_NANDF_D13__SD3_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__ECSPI2_SS1 (_MX51_PAD_NANDF_D12__ECSPI2_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__GPIO3_28 (_MX51_PAD_NANDF_D12__GPIO3_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__NANDF_D12 (_MX51_PAD_NANDF_D12__NANDF_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__PATA_DATA12 (_MX51_PAD_NANDF_D12__PATA_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D12__SD3_DAT4 (_MX51_PAD_NANDF_D12__SD3_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__FEC_RX_DV (_MX51_PAD_NANDF_D11__FEC_RX_DV | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__GPIO3_29 (_MX51_PAD_NANDF_D11__GPIO3_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__NANDF_D11 (_MX51_PAD_NANDF_D11__NANDF_D11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__PATA_DATA11 (_MX51_PAD_NANDF_D11__PATA_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D11__SD3_DATA3 (_MX51_PAD_NANDF_D11__SD3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__GPIO3_30 (_MX51_PAD_NANDF_D10__GPIO3_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__NANDF_D10 (_MX51_PAD_NANDF_D10__NANDF_D10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__PATA_DATA10 (_MX51_PAD_NANDF_D10__PATA_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D10__SD3_DATA2 (_MX51_PAD_NANDF_D10__SD3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__FEC_RDATA0 (_MX51_PAD_NANDF_D9__FEC_RDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_NANDF_D9__GPIO3_31 (_MX51_PAD_NANDF_D9__GPIO3_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__NANDF_D9 (_MX51_PAD_NANDF_D9__NANDF_D9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__PATA_DATA9 (_MX51_PAD_NANDF_D9__PATA_DATA9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D9__SD3_DATA1 (_MX51_PAD_NANDF_D9__SD3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__FEC_TDATA0 (_MX51_PAD_NANDF_D8__FEC_TDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_NANDF_D8__GPIO4_0 (_MX51_PAD_NANDF_D8__GPIO4_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__NANDF_D8 (_MX51_PAD_NANDF_D8__NANDF_D8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__PATA_DATA8 (_MX51_PAD_NANDF_D8__PATA_DATA8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D8__SD3_DATA0 (_MX51_PAD_NANDF_D8__SD3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__GPIO4_1 (_MX51_PAD_NANDF_D7__GPIO4_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__NANDF_D7 (_MX51_PAD_NANDF_D7__NANDF_D7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__PATA_DATA7 (_MX51_PAD_NANDF_D7__PATA_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D7__USBH3_DATA0 (_MX51_PAD_NANDF_D7__USBH3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__GPIO4_2 (_MX51_PAD_NANDF_D6__GPIO4_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__NANDF_D6 (_MX51_PAD_NANDF_D6__NANDF_D6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__PATA_DATA6 (_MX51_PAD_NANDF_D6__PATA_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__SD4_LCTL (_MX51_PAD_NANDF_D6__SD4_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D6__USBH3_DATA1 (_MX51_PAD_NANDF_D6__USBH3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__GPIO4_3 (_MX51_PAD_NANDF_D5__GPIO4_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__NANDF_D5 (_MX51_PAD_NANDF_D5__NANDF_D5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__PATA_DATA5 (_MX51_PAD_NANDF_D5__PATA_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__SD4_WP (_MX51_PAD_NANDF_D5__SD4_WP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D5__USBH3_DATA2 (_MX51_PAD_NANDF_D5__USBH3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__GPIO4_4 (_MX51_PAD_NANDF_D4__GPIO4_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__NANDF_D4 (_MX51_PAD_NANDF_D4__NANDF_D4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__PATA_DATA4 (_MX51_PAD_NANDF_D4__PATA_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__SD4_CD (_MX51_PAD_NANDF_D4__SD4_CD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D4__USBH3_DATA3 (_MX51_PAD_NANDF_D4__USBH3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__GPIO4_5 (_MX51_PAD_NANDF_D3__GPIO4_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__NANDF_D3 (_MX51_PAD_NANDF_D3__NANDF_D3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__PATA_DATA3 (_MX51_PAD_NANDF_D3__PATA_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__SD4_DAT4 (_MX51_PAD_NANDF_D3__SD4_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D3__USBH3_DATA4 (_MX51_PAD_NANDF_D3__USBH3_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__GPIO4_6 (_MX51_PAD_NANDF_D2__GPIO4_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__NANDF_D2 (_MX51_PAD_NANDF_D2__NANDF_D2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__PATA_DATA2 (_MX51_PAD_NANDF_D2__PATA_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__SD4_DAT5 (_MX51_PAD_NANDF_D2__SD4_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D2__USBH3_DATA5 (_MX51_PAD_NANDF_D2__USBH3_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__GPIO4_7 (_MX51_PAD_NANDF_D1__GPIO4_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__NANDF_D1 (_MX51_PAD_NANDF_D1__NANDF_D1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__PATA_DATA1 (_MX51_PAD_NANDF_D1__PATA_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__SD4_DAT6 (_MX51_PAD_NANDF_D1__SD4_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D1__USBH3_DATA6 (_MX51_PAD_NANDF_D1__USBH3_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__GPIO4_8 (_MX51_PAD_NANDF_D0__GPIO4_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__NANDF_D0 (_MX51_PAD_NANDF_D0__NANDF_D0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__PATA_DATA0 (_MX51_PAD_NANDF_D0__PATA_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__SD4_DAT7 (_MX51_PAD_NANDF_D0__SD4_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_NANDF_D0__USBH3_DATA7 (_MX51_PAD_NANDF_D0__USBH3_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D8__CSI1_D8 (_MX51_PAD_CSI1_D8__CSI1_D8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D8__GPIO3_12 (_MX51_PAD_CSI1_D8__GPIO3_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_D9__CSI1_D9 (_MX51_PAD_CSI1_D9__CSI1_D9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D9__GPIO3_13 (_MX51_PAD_CSI1_D9__GPIO3_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_D10__CSI1_D10 (_MX51_PAD_CSI1_D10__CSI1_D10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D11__CSI1_D11 (_MX51_PAD_CSI1_D11__CSI1_D11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D12__CSI1_D12 (_MX51_PAD_CSI1_D12__CSI1_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D13__CSI1_D13 (_MX51_PAD_CSI1_D13__CSI1_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D14__CSI1_D14 (_MX51_PAD_CSI1_D14__CSI1_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D15__CSI1_D15 (_MX51_PAD_CSI1_D15__CSI1_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D16__CSI1_D16 (_MX51_PAD_CSI1_D16__CSI1_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D17__CSI1_D17 (_MX51_PAD_CSI1_D17__CSI1_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D18__CSI1_D18 (_MX51_PAD_CSI1_D18__CSI1_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_D19__CSI1_D19 (_MX51_PAD_CSI1_D19__CSI1_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC (_MX51_PAD_CSI1_VSYNC__CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_VSYNC__GPIO3_14 (_MX51_PAD_CSI1_VSYNC__GPIO3_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC (_MX51_PAD_CSI1_HSYNC__CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_HSYNC__GPIO3_15 (_MX51_PAD_CSI1_HSYNC__GPIO3_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK (_MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK (_MX51_PAD_CSI1_MCLK__CSI1_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D12__CSI2_D12 (_MX51_PAD_CSI2_D12__CSI2_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D12__GPIO4_9 (_MX51_PAD_CSI2_D12__GPIO4_9 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D13__CSI2_D13 (_MX51_PAD_CSI2_D13__CSI2_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D13__GPIO4_10 (_MX51_PAD_CSI2_D13__GPIO4_10 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D14__CSI2_D14 (_MX51_PAD_CSI2_D14__CSI2_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D15__CSI2_D15 (_MX51_PAD_CSI2_D15__CSI2_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D16__CSI2_D16 (_MX51_PAD_CSI2_D16__CSI2_D16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D17__CSI2_D17 (_MX51_PAD_CSI2_D17__CSI2_D17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D18__CSI2_D18 (_MX51_PAD_CSI2_D18__CSI2_D18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D18__GPIO4_11 (_MX51_PAD_CSI2_D18__GPIO4_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_D19__CSI2_D19 (_MX51_PAD_CSI2_D19__CSI2_D19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_D19__GPIO4_12 (_MX51_PAD_CSI2_D19__GPIO4_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC (_MX51_PAD_CSI2_VSYNC__CSI2_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_VSYNC__GPIO4_13 (_MX51_PAD_CSI2_VSYNC__GPIO4_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC (_MX51_PAD_CSI2_HSYNC__CSI2_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_HSYNC__GPIO4_14 (_MX51_PAD_CSI2_HSYNC__GPIO4_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK (_MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSI2_PIXCLK__GPIO4_15 (_MX51_PAD_CSI2_PIXCLK__GPIO4_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_CLK__GPIO4_16 (_MX51_PAD_I2C1_CLK__GPIO4_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_CLK__I2C1_CLK (_MX51_PAD_I2C1_CLK__I2C1_CLK | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_I2C1_DAT__GPIO4_17 (_MX51_PAD_I2C1_DAT__GPIO4_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_I2C1_DAT__I2C1_DAT (_MX51_PAD_I2C1_DAT__I2C1_DAT | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_TXD__AUD3_TXD (_MX51_PAD_AUD3_BB_TXD__AUD3_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_TXD__GPIO4_18 (_MX51_PAD_AUD3_BB_TXD__GPIO4_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__AUD3_RXD (_MX51_PAD_AUD3_BB_RXD__AUD3_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__GPIO4_19 (_MX51_PAD_AUD3_BB_RXD__GPIO4_19 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_RXD__UART3_RXD (_MX51_PAD_AUD3_BB_RXD__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_CK__AUD3_TXC (_MX51_PAD_AUD3_BB_CK__AUD3_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_CK__GPIO4_20 (_MX51_PAD_AUD3_BB_CK__GPIO4_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__AUD3_TXFS (_MX51_PAD_AUD3_BB_FS__AUD3_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__GPIO4_21 (_MX51_PAD_AUD3_BB_FS__GPIO4_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_AUD3_BB_FS__UART3_TXD (_MX51_PAD_AUD3_BB_FS__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI (_MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__GPIO4_22 (_MX51_PAD_CSPI1_MOSI__GPIO4_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_MOSI__I2C1_SDA (_MX51_PAD_CSPI1_MOSI__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__AUD4_RXD (_MX51_PAD_CSPI1_MISO__AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO (_MX51_PAD_CSPI1_MISO__ECSPI1_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_MISO__GPIO4_23 (_MX51_PAD_CSPI1_MISO__GPIO4_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__AUD4_TXC (_MX51_PAD_CSPI1_SS0__AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 (_MX51_PAD_CSPI1_SS0__ECSPI1_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS0__GPIO4_24 (_MX51_PAD_CSPI1_SS0__GPIO4_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__AUD4_TXD (_MX51_PAD_CSPI1_SS1__AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 (_MX51_PAD_CSPI1_SS1__ECSPI1_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SS1__GPIO4_25 (_MX51_PAD_CSPI1_SS1__GPIO4_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__AUD4_TXFS (_MX51_PAD_CSPI1_RDY__AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY (_MX51_PAD_CSPI1_RDY__ECSPI1_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_RDY__GPIO4_26 (_MX51_PAD_CSPI1_RDY__GPIO4_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK (_MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__GPIO4_27 (_MX51_PAD_CSPI1_SCLK__GPIO4_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_CSPI1_SCLK__I2C1_SCL (_MX51_PAD_CSPI1_SCLK__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_UART1_RXD__GPIO4_28 (_MX51_PAD_UART1_RXD__GPIO4_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_RXD__UART1_RXD (_MX51_PAD_UART1_RXD__UART1_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__GPIO4_29 (_MX51_PAD_UART1_TXD__GPIO4_29 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__PWM2_PWMO (_MX51_PAD_UART1_TXD__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART1_TXD__UART1_TXD (_MX51_PAD_UART1_TXD__UART1_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_RTS__GPIO4_30 (_MX51_PAD_UART1_RTS__GPIO4_30 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_RTS__UART1_RTS (_MX51_PAD_UART1_RTS__UART1_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART1_CTS__GPIO4_31 (_MX51_PAD_UART1_CTS__GPIO4_31 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART1_CTS__UART1_CTS (_MX51_PAD_UART1_CTS__UART1_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__FIRI_TXD (_MX51_PAD_UART2_RXD__FIRI_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__GPIO1_20 (_MX51_PAD_UART2_RXD__GPIO1_20 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART2_RXD__UART2_RXD (_MX51_PAD_UART2_RXD__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__FIRI_RXD (_MX51_PAD_UART2_TXD__FIRI_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__GPIO1_21 (_MX51_PAD_UART2_TXD__GPIO1_21 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART2_TXD__UART2_TXD (_MX51_PAD_UART2_TXD__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__CSI1_D0 (_MX51_PAD_UART3_RXD__CSI1_D0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__GPIO1_22 (_MX51_PAD_UART3_RXD__GPIO1_22 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__UART1_DTR (_MX51_PAD_UART3_RXD__UART1_DTR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_RXD__UART3_RXD (_MX51_PAD_UART3_RXD__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__CSI1_D1 (_MX51_PAD_UART3_TXD__CSI1_D1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__GPIO1_23 (_MX51_PAD_UART3_TXD__GPIO1_23 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__UART1_DSR (_MX51_PAD_UART3_TXD__UART1_DSR | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_UART3_TXD__UART3_TXD (_MX51_PAD_UART3_TXD__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__GPIO1_24 (_MX51_PAD_OWIRE_LINE__GPIO1_24 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__OWIRE_LINE (_MX51_PAD_OWIRE_LINE__OWIRE_LINE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_OWIRE_LINE__SPDIF_OUT (_MX51_PAD_OWIRE_LINE__SPDIF_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW0__KEY_ROW0 (_MX51_PAD_KEY_ROW0__KEY_ROW0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW1__KEY_ROW1 (_MX51_PAD_KEY_ROW1__KEY_ROW1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW2__KEY_ROW2 (_MX51_PAD_KEY_ROW2__KEY_ROW2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_ROW3__KEY_ROW3 (_MX51_PAD_KEY_ROW3__KEY_ROW3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL0__KEY_COL0 (_MX51_PAD_KEY_COL0__KEY_COL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL0__PLL1_BYP (_MX51_PAD_KEY_COL0__PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL1__KEY_COL1 (_MX51_PAD_KEY_COL1__KEY_COL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL1__PLL2_BYP (_MX51_PAD_KEY_COL1__PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL2__KEY_COL2 (_MX51_PAD_KEY_COL2__KEY_COL2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL2__PLL3_BYP (_MX51_PAD_KEY_COL2__PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL3__KEY_COL3 (_MX51_PAD_KEY_COL3__KEY_COL3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__I2C2_SCL (_MX51_PAD_KEY_COL4__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__KEY_COL4 (_MX51_PAD_KEY_COL4__KEY_COL4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__SPDIF_OUT1 (_MX51_PAD_KEY_COL4__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__UART1_RI (_MX51_PAD_KEY_COL4__UART1_RI | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL4__UART3_RTS (_MX51_PAD_KEY_COL4__UART3_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__I2C2_SDA (_MX51_PAD_KEY_COL5__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__KEY_COL5 (_MX51_PAD_KEY_COL5__KEY_COL5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__UART1_DCD (_MX51_PAD_KEY_COL5__UART1_DCD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_KEY_COL5__UART3_CTS (_MX51_PAD_KEY_COL5__UART3_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__CSPI_SCLK (_MX51_PAD_USBH1_CLK__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__GPIO1_25 (_MX51_PAD_USBH1_CLK__GPIO1_25 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__I2C2_SCL (_MX51_PAD_USBH1_CLK__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_USBH1_CLK__USBH1_CLK (_MX51_PAD_USBH1_CLK__USBH1_CLK | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__CSPI_MOSI (_MX51_PAD_USBH1_DIR__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__GPIO1_26 (_MX51_PAD_USBH1_DIR__GPIO1_26 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__I2C2_SDA (_MX51_PAD_USBH1_DIR__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_USBH1_DIR__USBH1_DIR (_MX51_PAD_USBH1_DIR__USBH1_DIR | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__CSPI_RDY (_MX51_PAD_USBH1_STP__CSPI_RDY | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__GPIO1_27 (_MX51_PAD_USBH1_STP__GPIO1_27 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__UART3_RXD (_MX51_PAD_USBH1_STP__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_STP__USBH1_STP (_MX51_PAD_USBH1_STP__USBH1_STP | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__CSPI_MISO (_MX51_PAD_USBH1_NXT__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__GPIO1_28 (_MX51_PAD_USBH1_NXT__GPIO1_28 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__UART3_TXD (_MX51_PAD_USBH1_NXT__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_NXT__USBH1_NXT (_MX51_PAD_USBH1_NXT__USBH1_NXT | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__GPIO1_11 (_MX51_PAD_USBH1_DATA0__GPIO1_11 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__UART2_CTS (_MX51_PAD_USBH1_DATA0__UART2_CTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 (_MX51_PAD_USBH1_DATA0__USBH1_DATA0 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__GPIO1_12 (_MX51_PAD_USBH1_DATA1__GPIO1_12 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__UART2_RXD (_MX51_PAD_USBH1_DATA1__UART2_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 (_MX51_PAD_USBH1_DATA1__USBH1_DATA1 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__GPIO1_13 (_MX51_PAD_USBH1_DATA2__GPIO1_13 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__UART2_TXD (_MX51_PAD_USBH1_DATA2__UART2_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 (_MX51_PAD_USBH1_DATA2__USBH1_DATA2 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__GPIO1_14 (_MX51_PAD_USBH1_DATA3__GPIO1_14 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__UART2_RTS (_MX51_PAD_USBH1_DATA3__UART2_RTS | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 (_MX51_PAD_USBH1_DATA3__USBH1_DATA3 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__CSPI_SS0 (_MX51_PAD_USBH1_DATA4__CSPI_SS0 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__GPIO1_15 (_MX51_PAD_USBH1_DATA4__GPIO1_15 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 (_MX51_PAD_USBH1_DATA4__USBH1_DATA4 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__CSPI_SS1 (_MX51_PAD_USBH1_DATA5__CSPI_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__GPIO1_16 (_MX51_PAD_USBH1_DATA5__GPIO1_16 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 (_MX51_PAD_USBH1_DATA5__USBH1_DATA5 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__CSPI_SS3 (_MX51_PAD_USBH1_DATA6__CSPI_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__GPIO1_17 (_MX51_PAD_USBH1_DATA6__GPIO1_17 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 (_MX51_PAD_USBH1_DATA6__USBH1_DATA6 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__ECSPI1_SS3 (_MX51_PAD_USBH1_DATA7__ECSPI1_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__ECSPI2_SS3 (_MX51_PAD_USBH1_DATA7__ECSPI2_SS3 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__GPIO1_18 (_MX51_PAD_USBH1_DATA7__GPIO1_18 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 (_MX51_PAD_USBH1_DATA7__USBH1_DATA7 | MUX_PAD_CTRL(MX51_USBH1_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__DI1_PIN11 (_MX51_PAD_DI1_PIN11__DI1_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__ECSPI1_SS2 (_MX51_PAD_DI1_PIN11__ECSPI1_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_DI1_PIN11__GPIO3_0 (_MX51_PAD_DI1_PIN11__GPIO3_0 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN12__DI1_PIN12 (_MX51_PAD_DI1_PIN12__DI1_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN12__GPIO3_1 (_MX51_PAD_DI1_PIN12__GPIO3_1 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN13__DI1_PIN13 (_MX51_PAD_DI1_PIN13__DI1_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN13__GPIO3_2 (_MX51_PAD_DI1_PIN13__GPIO3_2 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_D0_CS__DI1_D0_CS (_MX51_PAD_DI1_D0_CS__DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D0_CS__GPIO3_3 (_MX51_PAD_DI1_D0_CS__GPIO3_3 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DI1_D1_CS (_MX51_PAD_DI1_D1_CS__DI1_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN14 (_MX51_PAD_DI1_D1_CS__DISP1_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN5 (_MX51_PAD_DI1_D1_CS__DISP1_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_D1_CS__GPIO3_4 (_MX51_PAD_DI1_D1_CS__GPIO3_4 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 (_MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN (_MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIN__GPIO3_5 (_MX51_PAD_DISPB2_SER_DIN__GPIO3_5 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 (_MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO (_MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_DIO__GPIO3_6 (_MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 (_MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 (_MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK (_MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_CLK__GPIO3_7 (_MX51_PAD_DISPB2_SER_CLK__GPIO3_7 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK (_MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 (_MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 (_MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS (_MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS (_MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISPB2_SER_RS__GPIO3_8 (_MX51_PAD_DISPB2_SER_RS__GPIO3_8 | MUX_PAD_CTRL(MX51_GPIO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 (_MX51_PAD_DISP1_DAT0__DISP1_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 (_MX51_PAD_DISP1_DAT1__DISP1_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 (_MX51_PAD_DISP1_DAT2__DISP1_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 (_MX51_PAD_DISP1_DAT3__DISP1_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 (_MX51_PAD_DISP1_DAT4__DISP1_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 (_MX51_PAD_DISP1_DAT5__DISP1_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT6__BOOT_USB_SRC (_MX51_PAD_DISP1_DAT6__BOOT_USB_SRC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 (_MX51_PAD_DISP1_DAT6__DISP1_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG (_MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 (_MX51_PAD_DISP1_DAT7__DISP1_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT8__BOOT_SRC0 (_MX51_PAD_DISP1_DAT8__BOOT_SRC0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 (_MX51_PAD_DISP1_DAT8__DISP1_DAT8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT9__BOOT_SRC1 (_MX51_PAD_DISP1_DAT9__BOOT_SRC1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 (_MX51_PAD_DISP1_DAT9__DISP1_DAT9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE (_MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 (_MX51_PAD_DISP1_DAT10__DISP1_DAT10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 (_MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 (_MX51_PAD_DISP1_DAT11__DISP1_DAT11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL (_MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 (_MX51_PAD_DISP1_DAT12__DISP1_DAT12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 (_MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 (_MX51_PAD_DISP1_DAT13__DISP1_DAT13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 (_MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 (_MX51_PAD_DISP1_DAT14__DISP1_DAT14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH (_MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 (_MX51_PAD_DISP1_DAT15__DISP1_DAT15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 (_MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 (_MX51_PAD_DISP1_DAT16__DISP1_DAT16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 (_MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 (_MX51_PAD_DISP1_DAT17__DISP1_DAT17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 (_MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 (_MX51_PAD_DISP1_DAT18__DISP1_DAT18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN11 (_MX51_PAD_DISP1_DAT18__DISP2_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN5 (_MX51_PAD_DISP1_DAT18__DISP2_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 (_MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 (_MX51_PAD_DISP1_DAT19__DISP1_DAT19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN12 (_MX51_PAD_DISP1_DAT19__DISP2_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN6 (_MX51_PAD_DISP1_DAT19__DISP2_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 (_MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 (_MX51_PAD_DISP1_DAT20__DISP1_DAT20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN13 (_MX51_PAD_DISP1_DAT20__DISP2_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN7 (_MX51_PAD_DISP1_DAT20__DISP2_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 (_MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 (_MX51_PAD_DISP1_DAT21__DISP1_DAT21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN14 (_MX51_PAD_DISP1_DAT21__DISP2_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN8 (_MX51_PAD_DISP1_DAT21__DISP2_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 (_MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 (_MX51_PAD_DISP1_DAT22__DISP1_DAT22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP2_D0_CS (_MX51_PAD_DISP1_DAT22__DISP2_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT22__DISP2_DAT16 (_MX51_PAD_DISP1_DAT22__DISP2_DAT16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 (_MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 (_MX51_PAD_DISP1_DAT23__DISP1_DAT23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_D1_CS (_MX51_PAD_DISP1_DAT23__DISP2_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_DAT17 (_MX51_PAD_DISP1_DAT23__DISP2_DAT17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP1_DAT23__DISP2_SER_CS (_MX51_PAD_DISP1_DAT23__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN3__DI1_PIN3 (_MX51_PAD_DI1_PIN3__DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI1_PIN2__DI1_PIN2 (_MX51_PAD_DI1_PIN2__DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP2__DISP1_SER_CLK (_MX51_PAD_DI_GP2__DISP1_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP2__DISP2_WAIT (_MX51_PAD_DI_GP2__DISP2_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__CSI1_DATA_EN (_MX51_PAD_DI_GP3__CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__DISP1_SER_DIO (_MX51_PAD_DI_GP3__DISP1_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP3__FEC_TX_ER (_MX51_PAD_DI_GP3__FEC_TX_ER | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DI2_PIN4__CSI2_DATA_EN (_MX51_PAD_DI2_PIN4__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN4__DI2_PIN4 (_MX51_PAD_DI2_PIN4__DI2_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN4__FEC_CRS (_MX51_PAD_DI2_PIN4__FEC_CRS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN2__DI2_PIN2 (_MX51_PAD_DI2_PIN2__DI2_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN2__FEC_MDC (_MX51_PAD_DI2_PIN2__FEC_MDC | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DI2_PIN3__DI2_PIN3 (_MX51_PAD_DI2_PIN3__DI2_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_PIN3__FEC_MDIO (_MX51_PAD_DI2_PIN3__FEC_MDIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK (_MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 (_MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DI2_PIN15 (_MX51_PAD_DI_GP4__DI2_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DISP1_SER_DIN (_MX51_PAD_DI_GP4__DISP1_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__DISP2_PIN1 (_MX51_PAD_DI_GP4__DISP2_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DI_GP4__FEC_RDATA2 (_MX51_PAD_DI_GP4__FEC_RDATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 (_MX51_PAD_DISP2_DAT0__DISP2_DAT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 (_MX51_PAD_DISP2_DAT0__FEC_RDATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__KEY_COL6 (_MX51_PAD_DISP2_DAT0__KEY_COL6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__UART3_RXD (_MX51_PAD_DISP2_DAT0__UART3_RXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT0__USBH3_CLK (_MX51_PAD_DISP2_DAT0__USBH3_CLK | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 (_MX51_PAD_DISP2_DAT1__DISP2_DAT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__FEC_RX_ER (_MX51_PAD_DISP2_DAT1__FEC_RX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__KEY_COL7 (_MX51_PAD_DISP2_DAT1__KEY_COL7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__UART3_TXD (_MX51_PAD_DISP2_DAT1__UART3_TXD | MUX_PAD_CTRL(MX51_UART_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT1__USBH3_DIR (_MX51_PAD_DISP2_DAT1__USBH3_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 (_MX51_PAD_DISP2_DAT2__DISP2_DAT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 (_MX51_PAD_DISP2_DAT3__DISP2_DAT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 (_MX51_PAD_DISP2_DAT4__DISP2_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 (_MX51_PAD_DISP2_DAT5__DISP2_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__DISP2_DAT6 (_MX51_PAD_DISP2_DAT6__DISP2_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__FEC_TDATA1 (_MX51_PAD_DISP2_DAT6__FEC_TDATA1 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT6__GPIO1_19 (_MX51_PAD_DISP2_DAT6__GPIO1_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__KEY_ROW4 (_MX51_PAD_DISP2_DAT6__KEY_ROW4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT6__USBH3_STP (_MX51_PAD_DISP2_DAT6__USBH3_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__DISP2_DAT7 (_MX51_PAD_DISP2_DAT7__DISP2_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__FEC_TDATA2 (_MX51_PAD_DISP2_DAT7__FEC_TDATA2 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT7__GPIO1_29 (_MX51_PAD_DISP2_DAT7__GPIO1_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__KEY_ROW5 (_MX51_PAD_DISP2_DAT7__KEY_ROW5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT7__USBH3_NXT (_MX51_PAD_DISP2_DAT7__USBH3_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__DISP2_DAT8 (_MX51_PAD_DISP2_DAT8__DISP2_DAT8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__FEC_TDATA3 (_MX51_PAD_DISP2_DAT8__FEC_TDATA3 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT8__GPIO1_30 (_MX51_PAD_DISP2_DAT8__GPIO1_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__KEY_ROW6 (_MX51_PAD_DISP2_DAT8__KEY_ROW6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT8__USBH3_DATA0 (_MX51_PAD_DISP2_DAT8__USBH3_DATA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__AUD6_RXC (_MX51_PAD_DISP2_DAT9__AUD6_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__DISP2_DAT9 (_MX51_PAD_DISP2_DAT9__DISP2_DAT9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__FEC_TX_EN (_MX51_PAD_DISP2_DAT9__FEC_TX_EN | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT9__GPIO1_31 (_MX51_PAD_DISP2_DAT9__GPIO1_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT9__USBH3_DATA1 (_MX51_PAD_DISP2_DAT9__USBH3_DATA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 (_MX51_PAD_DISP2_DAT10__DISP2_DAT10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__DISP2_SER_CS (_MX51_PAD_DISP2_DAT10__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__FEC_COL (_MX51_PAD_DISP2_DAT10__FEC_COL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__KEY_ROW7 (_MX51_PAD_DISP2_DAT10__KEY_ROW7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT10__USBH3_DATA2 (_MX51_PAD_DISP2_DAT10__USBH3_DATA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__AUD6_TXD (_MX51_PAD_DISP2_DAT11__AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 (_MX51_PAD_DISP2_DAT11__DISP2_DAT11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK (_MX51_PAD_DISP2_DAT11__FEC_RX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__GPIO1_10 (_MX51_PAD_DISP2_DAT11__GPIO1_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT11__USBH3_DATA3 (_MX51_PAD_DISP2_DAT11__USBH3_DATA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__AUD6_RXD (_MX51_PAD_DISP2_DAT12__AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 (_MX51_PAD_DISP2_DAT12__DISP2_DAT12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__FEC_RX_DV (_MX51_PAD_DISP2_DAT12__FEC_RX_DV | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT12__USBH3_DATA4 (_MX51_PAD_DISP2_DAT12__USBH3_DATA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__AUD6_TXC (_MX51_PAD_DISP2_DAT13__AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 (_MX51_PAD_DISP2_DAT13__DISP2_DAT13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT13__FEC_TX_CLK (_MX51_PAD_DISP2_DAT13__FEC_TX_CLK | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_DISP2_DAT13__USBH3_DATA5 (_MX51_PAD_DISP2_DAT13__USBH3_DATA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__AUD6_TXFS (_MX51_PAD_DISP2_DAT14__AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 (_MX51_PAD_DISP2_DAT14__DISP2_DAT14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT14__FEC_RDATA0 (_MX51_PAD_DISP2_DAT14__FEC_RDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_4))
+#define MX51_PAD_DISP2_DAT14__USBH3_DATA6 (_MX51_PAD_DISP2_DAT14__USBH3_DATA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__AUD6_RXFS (_MX51_PAD_DISP2_DAT15__AUD6_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__DISP1_SER_CS (_MX51_PAD_DISP2_DAT15__DISP1_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 (_MX51_PAD_DISP2_DAT15__DISP2_DAT15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_DISP2_DAT15__FEC_TDATA0 (_MX51_PAD_DISP2_DAT15__FEC_TDATA0 | MUX_PAD_CTRL(MX51_PAD_CTRL_5))
+#define MX51_PAD_DISP2_DAT15__USBH3_DATA7 (_MX51_PAD_DISP2_DAT15__USBH3_DATA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__AUD5_RXFS (_MX51_PAD_SD1_CMD__AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__CSPI_MOSI (_MX51_PAD_SD1_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CMD__SD1_CMD (_MX51_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__AUD5_RXC (_MX51_PAD_SD1_CLK__AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__CSPI_SCLK (_MX51_PAD_SD1_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_CLK__SD1_CLK (_MX51_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_SD1_DATA0__AUD5_TXD (_MX51_PAD_SD1_DATA0__AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA0__CSPI_MISO (_MX51_PAD_SD1_DATA0__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 (_MX51_PAD_SD1_DATA0__SD1_DATA0 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_EIM_DA0__EIM_DA0 (_MX51_PAD_EIM_DA0__EIM_DA0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA1__EIM_DA1 (_MX51_PAD_EIM_DA1__EIM_DA1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA2__EIM_DA2 (_MX51_PAD_EIM_DA2__EIM_DA2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA3__EIM_DA3 (_MX51_PAD_EIM_DA3__EIM_DA3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA1__AUD5_RXD (_MX51_PAD_SD1_DATA1__AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 (_MX51_PAD_SD1_DATA1__SD1_DATA1 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_EIM_DA4__EIM_DA4 (_MX51_PAD_EIM_DA4__EIM_DA4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA5__EIM_DA5 (_MX51_PAD_EIM_DA5__EIM_DA5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA6__EIM_DA6 (_MX51_PAD_EIM_DA6__EIM_DA6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA7__EIM_DA7 (_MX51_PAD_EIM_DA7__EIM_DA7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA2__AUD5_TXC (_MX51_PAD_SD1_DATA2__AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 (_MX51_PAD_SD1_DATA2__SD1_DATA2 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_EIM_DA10__EIM_DA10 (_MX51_PAD_EIM_DA10__EIM_DA10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA11__EIM_DA11 (_MX51_PAD_EIM_DA11__EIM_DA11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA8__EIM_DA8 (_MX51_PAD_EIM_DA8__EIM_DA8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA9__EIM_DA9 (_MX51_PAD_EIM_DA9__EIM_DA9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS (_MX51_PAD_SD1_DATA3__AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__CSPI_SS1 (_MX51_PAD_SD1_DATA3__CSPI_SS1 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 (_MX51_PAD_SD1_DATA3__SD1_DATA3 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__CSPI_SS2 (_MX51_PAD_GPIO1_0__CSPI_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__GPIO1_0 (_MX51_PAD_GPIO1_0__GPIO1_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_0__SD1_CD (_MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__CSPI_MISO (_MX51_PAD_GPIO1_1__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__GPIO1_1 (_MX51_PAD_GPIO1_1__GPIO1_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_1__SD1_WP (_MX51_PAD_GPIO1_1__SD1_WP | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_EIM_DA12__EIM_DA12 (_MX51_PAD_EIM_DA12__EIM_DA12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA13__EIM_DA13 (_MX51_PAD_EIM_DA13__EIM_DA13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA14__EIM_DA14 (_MX51_PAD_EIM_DA14__EIM_DA14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_EIM_DA15__EIM_DA15 (_MX51_PAD_EIM_DA15__EIM_DA15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__CSPI_MOSI (_MX51_PAD_SD2_CMD__CSPI_MOSI | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__I2C1_SCL (_MX51_PAD_SD2_CMD__I2C1_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_SD2_CMD__SD2_CMD (_MX51_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__CSPI_SCLK (_MX51_PAD_SD2_CLK__CSPI_SCLK | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__I2C1_SDA (_MX51_PAD_SD2_CLK__I2C1_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_SD2_CLK__SD2_CLK (_MX51_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS))
+#define MX51_PAD_SD2_DATA0__CSPI_MISO (_MX51_PAD_SD2_DATA0__CSPI_MISO | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA0__SD1_DAT4 (_MX51_PAD_SD2_DATA0__SD1_DAT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 (_MX51_PAD_SD2_DATA0__SD2_DATA0 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__SD1_DAT5 (_MX51_PAD_SD2_DATA1__SD1_DAT5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 (_MX51_PAD_SD2_DATA1__SD2_DATA1 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA1__USBH3_H2_DP (_MX51_PAD_SD2_DATA1__USBH3_H2_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__SD1_DAT6 (_MX51_PAD_SD2_DATA2__SD1_DAT6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 (_MX51_PAD_SD2_DATA2__SD2_DATA2 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA2__USBH3_H2_DM (_MX51_PAD_SD2_DATA2__USBH3_H2_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__CSPI_SS2 (_MX51_PAD_SD2_DATA3__CSPI_SS2 | MUX_PAD_CTRL(MX51_ECSPI_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__SD1_DAT7 (_MX51_PAD_SD2_DATA3__SD1_DAT7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 (_MX51_PAD_SD2_DATA3__SD2_DATA3 | MUX_PAD_CTRL(MX51_SDHCI_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__CCM_OUT_2 (_MX51_PAD_GPIO1_2__CCM_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__GPIO1_2 (_MX51_PAD_GPIO1_2__GPIO1_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__I2C2_SCL (_MX51_PAD_GPIO1_2__I2C2_SCL | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__PLL1_BYP (_MX51_PAD_GPIO1_2__PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_2__PWM1_PWMO (_MX51_PAD_GPIO1_2__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__GPIO1_3 (_MX51_PAD_GPIO1_3__GPIO1_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__I2C2_SDA (_MX51_PAD_GPIO1_3__I2C2_SDA | MUX_PAD_CTRL(MX51_I2C_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__PLL2_BYP (_MX51_PAD_GPIO1_3__PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_3__PWM2_PWMO (_MX51_PAD_GPIO1_3__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ (_MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B (_MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__DISP2_EXT_CLK (_MX51_PAD_GPIO1_4__DISP2_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__EIM_RDY (_MX51_PAD_GPIO1_4__EIM_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__GPIO1_4 (_MX51_PAD_GPIO1_4__GPIO1_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_4__WDOG1_WDOG_B (_MX51_PAD_GPIO1_4__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__CSI2_MCLK (_MX51_PAD_GPIO1_5__CSI2_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__DISP2_PIN16 (_MX51_PAD_GPIO1_5__DISP2_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__GPIO1_5 (_MX51_PAD_GPIO1_5__GPIO1_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_5__WDOG2_WDOG_B (_MX51_PAD_GPIO1_5__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__DISP2_PIN17 (_MX51_PAD_GPIO1_6__DISP2_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__GPIO1_6 (_MX51_PAD_GPIO1_6__GPIO1_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_6__REF_EN_B (_MX51_PAD_GPIO1_6__REF_EN_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__CCM_OUT_0 (_MX51_PAD_GPIO1_7__CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__GPIO1_7 (_MX51_PAD_GPIO1_7__GPIO1_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__SD2_WP (_MX51_PAD_GPIO1_7__SD2_WP | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_7__SPDIF_OUT1 (_MX51_PAD_GPIO1_7__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__CSI2_DATA_EN (_MX51_PAD_GPIO1_8__CSI2_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__GPIO1_8 (_MX51_PAD_GPIO1_8__GPIO1_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__SD2_CD (_MX51_PAD_GPIO1_8__SD2_CD | MUX_PAD_CTRL(MX51_ESDHC_PAD_CTRL))
+#define MX51_PAD_GPIO1_8__USBH3_PWR (_MX51_PAD_GPIO1_8__USBH3_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__CCM_OUT_1 (_MX51_PAD_GPIO1_9__CCM_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__DISP2_D1_CS (_MX51_PAD_GPIO1_9__DISP2_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__DISP2_SER_CS (_MX51_PAD_GPIO1_9__DISP2_SER_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__GPIO1_9 (_MX51_PAD_GPIO1_9__GPIO1_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__SD2_LCTL (_MX51_PAD_GPIO1_9__SD2_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX51_PAD_GPIO1_9__USBH3_OC (_MX51_PAD_GPIO1_9__USBH3_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
new file mode 100755
index 00000000..56bade10
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
@@ -0,0 +1,2381 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc..
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_IOMUX_MX53_H__
+#define __MACH_IOMUX_MX53_H__
+
+#include <mach/iomux-v3.h>
+
+/* These 2 defines are for pins that may not have a mux register, but could
+ * have a pad setting register, and vice-versa. */
+#define NON_PAD_I 0x00
+
+#define MX53_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+#define MX53_SDHC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_SRE_FAST)
+#define PAD_CTRL_I2C (PAD_CTL_SRE_FAST | PAD_CTL_ODE | PAD_CTL_PKE | \
+ PAD_CTL_PUE | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP \
+ | PAD_CTL_HYS)
+
+#define _MX53_PAD_GPIO_19__KPP_COL_5 IOMUX_PAD(0x348, 0x20, 0, 0x840, 0, 0)
+#define _MX53_PAD_GPIO_19__GPIO4_5 IOMUX_PAD(0x348, 0x20, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__CCM_CLKO IOMUX_PAD(0x348, 0x20, 2, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__SPDIF_OUT1 IOMUX_PAD(0x348, 0x20, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 IOMUX_PAD(0x348, 0x20, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__ECSPI1_RDY IOMUX_PAD(0x348, 0x20, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__FEC_TDATA_3 IOMUX_PAD(0x348, 0x20, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_19__SRC_INT_BOOT IOMUX_PAD(0x348, 0x20,7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL0__KPP_COL_0 IOMUX_PAD(0x34C, 0x24, o, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL0__GPIO4_6 IOMUX_PAD(0x34C, 0x24, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC IOMUX_PAD(0x34C, 0x24, 2, 0x758, 0, 0)
+#define _MX53_PAD_KEY_COL0__UART4_TXD_MUX IOMUX_PAD(0x34C, 0x24, 4, 0x890, 0, 0)
+#define _MX53_PAD_KEY_COL0__ECSPI1_SCLK IOMUX_PAD(0x34C, 0x24, 5, 0x79C, 0, 0)
+#define _MX53_PAD_KEY_COL0__FEC_RDATA_3 IOMUX_PAD(0x34C, 0x24, 6, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL0__SRC_ANY_PU_RST IOMUX_PAD(0x34C, 0x24, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW0__KPP_ROW_0 IOMUX_PAD(0x350, 0x28, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW0__GPIO4_7 IOMUX_PAD(0x350, 0x28, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD IOMUX_PAD(0x350, 0x28, 2, 0x74C, 0, 0)
+#define _MX53_PAD_KEY_ROW0__UART4_RXD_MUX IOMUX_PAD(0x350, 0x28, 4, 0x890, 1, 0)
+#define _MX53_PAD_KEY_ROW0__ECSPI1_MOSI IOMUX_PAD(0x350, 0x28, 5, 0x7A4, 0, 0)
+#define _MX53_PAD_KEY_ROW0__FEC_TX_ER IOMUX_PAD(0x350, 0x28, 6, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL1__KPP_COL_1 IOMUX_PAD(0x354, 0x2C, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL1__GPIO4_8 IOMUX_PAD(0x354, 0x2C, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS IOMUX_PAD(0x354, 0x2C, 2, 0x75C, 0, 0)
+#define _MX53_PAD_KEY_COL1__UART5_TXD_MUX IOMUX_PAD(0x354, 0x2C, 4, 0x898, 0, 0)
+#define _MX53_PAD_KEY_COL1__ECSPI1_MISO IOMUX_PAD(0x354, 0x2C, 5, 0x7A0, 0, 0)
+#define _MX53_PAD_KEY_COL1__FEC_RX_CLK IOMUX_PAD(0x354, 0x2C, 6, 0x808, 0, 0)
+#define _MX53_PAD_KEY_COL1__USBPHY1_TXREADY IOMUX_PAD(0x354, 0x2C, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW1__KPP_ROW_1 IOMUX_PAD(0x358, 0x30, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW1__GPIO4_9 IOMUX_PAD(0x358, 0x30, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD IOMUX_PAD(0x358, 0x30, 2, 0x748, 0, 0)
+#define _MX53_PAD_KEY_ROW1__UART5_RXD_MUX IOMUX_PAD(0x358, 0x30, 4, 0x898, 1, 0)
+#define _MX53_PAD_KEY_ROW1__ECSPI1_SS0 IOMUX_PAD(0x358, 0x30, 5, 0x7A8, 0, 0)
+#define _MX53_PAD_KEY_ROW1__FEC_COL IOMUX_PAD(0x358, 0x30, 6, 0x800, 0, 0)
+#define _MX53_PAD_KEY_ROW1__USBPHY1_RXVALID IOMUX_PAD(0x358, 0x30, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL2__KPP_COL_2 IOMUX_PAD(0x35C, 0x34, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL2__GPIO4_10 IOMUX_PAD(0x35C, 0x34, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL2__CAN1_TXCAN IOMUX_PAD(0x35C, 0x34, 2, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL2__FEC_MDIO IOMUX_PAD(0x35C, 0x34, 4, 0x804, 0, 0)
+#define _MX53_PAD_KEY_COL2__ECSPI1_SS1 IOMUX_PAD(0x35C, 0x34, 5, 0x7AC, 0, 0)
+#define _MX53_PAD_KEY_COL2__FEC_RDATA_2 IOMUX_PAD(0x35C, 0x34, 6, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE IOMUX_PAD(0x35C, 0x34, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__KPP_ROW_2 IOMUX_PAD(0x360, 0x38, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__GPIO4_11 IOMUX_PAD(0x360, 0x38, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__CAN1_RXCAN IOMUX_PAD(0x360, 0x38, 2, 0x760, 0, 0)
+#define _MX53_PAD_KEY_ROW2__FEC_MDC IOMUX_PAD(0x360, 0x38, 4, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__ECSPI1_SS2 IOMUX_PAD(0x360, 0x38, 5, 0x7B0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__FEC_TDATA_2 IOMUX_PAD(0x360, 0x38, 6, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW2__USBPHY1_RXERROR IOMUX_PAD(0x360, 0x38, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL3__KPP_COL_3 IOMUX_PAD(0x364, 0x3C, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL3__GPIO4_12 IOMUX_PAD(0x364, 0x3C, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL3__USBOH3_H2_DP IOMUX_PAD(0x364, 0x3C, 2, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL3__SPDIF_IN1 IOMUX_PAD(0x364, 0x3C, 3, 0x870, 0, 0)
+#define _MX53_PAD_KEY_COL3__I2C2_SCL IOMUX_PAD(0x364, 0x3C, 4 | IOMUX_CONFIG_SION, 0x81C, 0, 0)
+#define _MX53_PAD_KEY_COL3__ECSPI1_SS3 IOMUX_PAD(0x364, 0x3C, 5, 0x7B4, 0, 0)
+#define _MX53_PAD_KEY_COL3__FEC_CRS IOMUX_PAD(0x364, 0x3C, 6, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK IOMUX_PAD(0x364, 0x3C, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW3__KPP_ROW_3 IOMUX_PAD(0x368, 0x40, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW3__GPIO4_13 IOMUX_PAD(0x368, 0x40, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW3__USBOH3_H2_DM IOMUX_PAD(0x368, 0x40, 2, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK IOMUX_PAD(0x368, 0x40, 3, 0x768, 0, 0)
+#define _MX53_PAD_KEY_ROW3__I2C2_SDA IOMUX_PAD(0x368, 0x40, 4 | IOMUX_CONFIG_SION, 0x820, 0, 0)
+#define _MX53_PAD_KEY_ROW3__OSC32K_32K_OUT IOMUX_PAD(0x368, 0x40, 5, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW3__CCM_PLL4_BYP IOMUX_PAD(0x368, 0x40, 6, 0x77C, 0, 0)
+#define _MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 IOMUX_PAD(0x368, 0x40, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL4__KPP_COL_4 IOMUX_PAD(0x36C, 0x44, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL4__GPIO4_14 IOMUX_PAD(0x36C, 0x44, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL4__CAN2_TXCAN IOMUX_PAD(0x36C, 0x44, 2, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL4__IPU_SISG_4 IOMUX_PAD(0x36C, 0x44, 3, 0x0, 0, 0)
+#define _MX53_PAD_KEY_COL4__UART5_RTS IOMUX_PAD(0x36C, 0x44, 4, 0x894, 0, 0)
+#define _MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC IOMUX_PAD(0x36C, 0x44, 5, 0x89C, 0, 0)
+#define _MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 IOMUX_PAD(0x36C, 0x44, 7, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW4__KPP_ROW_4 IOMUX_PAD(0x370, 0x48, 0, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW4__GPIO4_15 IOMUX_PAD(0x370, 0x48, 1, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW4__CAN2_RXCAN IOMUX_PAD(0x370, 0x48, 2, 0x764, 0, 0)
+#define _MX53_PAD_KEY_ROW4__IPU_SISG_5 IOMUX_PAD(0x370, 0x48, 3, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW4__UART5_CTS IOMUX_PAD(0x370, 0x48, 4, 0x894, 1, 0)
+#define _MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR IOMUX_PAD(0x370, 0x48, 5, 0x0, 0, 0)
+#define _MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID IOMUX_PAD(0x370, 0x48, 7, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK IOMUX_PAD(0x378, 0x4C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__GPIO4_16 IOMUX_PAD(0x378, 0x4C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR IOMUX_PAD(0x378, 0x4C, 2, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 IOMUX_PAD(0x378, 0x4C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 IOMUX_PAD(0x378, 0x4C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID IOMUX_PAD(0x378, 0x4C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 IOMUX_PAD(0x37C, 0x50, 0, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__GPIO4_17 IOMUX_PAD(0x37C, 0x50, 1, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC IOMUX_PAD(0x37C, 0x50, 2, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 IOMUX_PAD(0x37C, 0x50, 5, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 IOMUX_PAD(0x37C, 0x50, 6, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN15__USBPHY1_BVALID IOMUX_PAD(0x37C, 0x50, 7, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 IOMUX_PAD(0x380, 0x54, 0, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__GPIO4_18 IOMUX_PAD(0x380, 0x54, 1, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD IOMUX_PAD(0x380, 0x54, 2, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 IOMUX_PAD(0x380, 0x54, 5, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 IOMUX_PAD(0x380, 0x54, 6, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION IOMUX_PAD(0x380, 0x54, 7, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 IOMUX_PAD(0x384, 0x58, 0, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__GPIO4_19 IOMUX_PAD(0x384, 0x58, 1, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS IOMUX_PAD(0x384, 0x58, 2, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 IOMUX_PAD(0x384, 0x58, 5, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 IOMUX_PAD(0x384, 0x58, 6, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN3__USBPHY1_IDDIG IOMUX_PAD(0x384, 0x58, 7, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 IOMUX_PAD(0x388, 0x5C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__GPIO4_20 IOMUX_PAD(0x388, 0x5C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD IOMUX_PAD(0x388, 0x5C, 2, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__ESDHC1_WP IOMUX_PAD(0x388, 0x5C, 3, 0x7FC, 0, 0)
+#define _MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD IOMUX_PAD(0x388, 0x5C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 IOMUX_PAD(0x388, 0x5C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT IOMUX_PAD(0x388, 0x5C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 IOMUX_PAD(0x38C, 0x60, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__GPIO4_21 IOMUX_PAD(0x38C, 0x60, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__CSPI_SCLK IOMUX_PAD(0x38C, 0x60, 2, 0x780, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 IOMUX_PAD(0x38C, 0x60, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN IOMUX_PAD(0x38C, 0x60, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 IOMUX_PAD(0x38C, 0x60, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY IOMUX_PAD(0x38C, 0x60, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 IOMUX_PAD(0x390, 0x64, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__GPIO4_22 IOMUX_PAD(0x390, 0x64, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__CSPI_MOSI IOMUX_PAD(0x390, 0x64, 2, 0x788, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 IOMUX_PAD(0x390, 0x64, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL IOMUX_PAD(0x390, 0x64, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 IOMUX_PAD(0x390, 0x64, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID IOMUX_PAD(0x390, 0x64, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 IOMUX_PAD(0x394, 0x68, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__GPIO4_23 IOMUX_PAD(0x394, 0x68, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__CSPI_MISO IOMUX_PAD(0x394, 0x68, 2, 0x784, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 IOMUX_PAD(0x394, 0x68, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE IOMUX_PAD(0x394, 0x68, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 IOMUX_PAD(0x394, 0x68, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE IOMUX_PAD(0x394, 0x68, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 IOMUX_PAD(0x398, 0x6C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__GPIO4_24 IOMUX_PAD(0x398, 0x6C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__CSPI_SS0 IOMUX_PAD(0x398, 0x6C, 2, 0x78C, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 IOMUX_PAD(0x398, 0x6C, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR IOMUX_PAD(0x398, 0x6C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 IOMUX_PAD(0x398, 0x6C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR IOMUX_PAD(0x398, 0x6C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 IOMUX_PAD(0x39C, 0x70, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__GPIO4_25 IOMUX_PAD(0x39C, 0x70, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__CSPI_SS1 IOMUX_PAD(0x39C, 0x70, 2, 0x790, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 IOMUX_PAD(0x39C, 0x70, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB IOMUX_PAD(0x39C, 0x70, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 IOMUX_PAD(0x39C, 0x70, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK IOMUX_PAD(0x39C, 0x70, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 IOMUX_PAD(0x3A0, 0x74, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__GPIO4_26 IOMUX_PAD(0x3A0, 0x74, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__CSPI_SS2 IOMUX_PAD(0x3A0, 0x74, 2, 0x794, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 IOMUX_PAD(0x3A0, 0x74, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS IOMUX_PAD(0x3A0, 0x74, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 IOMUX_PAD(0x3A0, 0x74, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 IOMUX_PAD(0x3A0, 0x74, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 IOMUX_PAD(0x3A4, 0x78, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__GPIO4_27 IOMUX_PAD(0x3A4, 0x78, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__CSPI_SS3 IOMUX_PAD(0x3A4, 0x78, 2, 0x798, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 IOMUX_PAD(0x3A4, 0x78, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE IOMUX_PAD(0x3A4, 0x78, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 IOMUX_PAD(0x3A4, 0x78, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 IOMUX_PAD(0x3A4, 0x78, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 IOMUX_PAD(0x3A8, 0x7C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__GPIO4_28 IOMUX_PAD(0x3A8, 0x7C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__CSPI_RDY IOMUX_PAD(0x3A8, 0x7C, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 IOMUX_PAD(0x3A8, 0x7C, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 IOMUX_PAD(0x3A8, 0x7C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 IOMUX_PAD(0x3A8, 0x7C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID IOMUX_PAD(0x3A8, 0x7C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 IOMUX_PAD(0x3AC, 0x80, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__GPIO4_29 IOMUX_PAD(0x3AC, 0x80, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__PWM1_PWMO IOMUX_PAD(0x3AC, 0x80, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B IOMUX_PAD(0x3AC, 0x80, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 IOMUX_PAD(0x3AC, 0x80, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 IOMUX_PAD(0x3AC, 0x80, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT8__USBPHY2_AVALID IOMUX_PAD(0x3AC, 0x80, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 IOMUX_PAD(0x3B0, 0x84, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__GPIO4_30 IOMUX_PAD(0x3B0, 0x84, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__PWM2_PWMO IOMUX_PAD(0x3B0, 0x84, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B IOMUX_PAD(0x3B0, 0x84, 3, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 IOMUX_PAD(0x3B0, 0x84, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 IOMUX_PAD(0x3B0, 0x84, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 IOMUX_PAD(0x3B0, 0x84, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 IOMUX_PAD(0x3B4, 0x88, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__GPIO4_31 IOMUX_PAD(0x3B4, 0x88, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP IOMUX_PAD(0x3B4, 0x88, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 IOMUX_PAD(0x3B4, 0x88, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 IOMUX_PAD(0x3B4, 0x88, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 IOMUX_PAD(0x3B4, 0x88, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 IOMUX_PAD(0x3B8, 0x8C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__GPIO5_5 IOMUX_PAD(0x3B8, 0x8C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT IOMUX_PAD(0x3B8, 0x8C, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 IOMUX_PAD(0x3B8, 0x8C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 IOMUX_PAD(0x3B8, 0x8C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 IOMUX_PAD(0x3B8, 0x8C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 IOMUX_PAD(0x3BC, 0x90, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__GPIO5_6 IOMUX_PAD(0x3BC, 0x90, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK IOMUX_PAD(0x3BC, 0x90, 2, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 IOMUX_PAD(0x3BC, 0x90, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 IOMUX_PAD(0x3BC, 0x90, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 IOMUX_PAD(0x3BC, 0x90, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 IOMUX_PAD(0x3C0, 0x94, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__GPIO5_7 IOMUX_PAD(0x3C0, 0x94, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS IOMUX_PAD(0x3C0, 0x94, 3, 0x754, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 IOMUX_PAD(0x3C0, 0x94, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 IOMUX_PAD(0x3C0, 0x94, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 IOMUX_PAD(0x3C0, 0x94, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 IOMUX_PAD(0x3C4, 0x98, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__GPIO5_8 IOMUX_PAD(0x3C4, 0x98, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC IOMUX_PAD(0x3C4, 0x98, 3, 0x750, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 IOMUX_PAD(0x3C4, 0x98, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 IOMUX_PAD(0x3C4, 0x98, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 IOMUX_PAD(0x3C4, 0x98, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 IOMUX_PAD(0x3C8, 0x9C, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__GPIO5_9 IOMUX_PAD(0x3C8, 0x9C, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__ECSPI1_SS1 IOMUX_PAD(0x3C8, 0x9C, 2, 0x7AC, 1, 0)
+#define _MX53_PAD_DISP0_DAT15__ECSPI2_SS1 IOMUX_PAD(0x3C8, 0x9C, 3, 0x7C8, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 IOMUX_PAD(0x3C8, 0x9C, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 IOMUX_PAD(0x3C8, 0x9C, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 IOMUX_PAD(0x3C8, 0x9C, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 IOMUX_PAD(0x3CC, 0xA0, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__GPIO5_10 IOMUX_PAD(0x3CC, 0xA0, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__ECSPI2_MOSI IOMUX_PAD(0x3CC, 0xA0, 2, 0x7C0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC IOMUX_PAD(0x3CC, 0xA0, 3, 0x758, 1, 0)
+#define _MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 IOMUX_PAD(0x3CC, 0xA0, 4, 0x868, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 IOMUX_PAD(0x3CC, 0xA0, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 IOMUX_PAD(0x3CC, 0xA0, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 IOMUX_PAD(0x3CC, 0xA0, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 IOMUX_PAD(0x3D0, 0xA4, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__GPIO5_11 IOMUX_PAD(0x3D0, 0xA4, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__ECSPI2_MISO IOMUX_PAD(0x3D0, 0xA4, 2, 0x7BC, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD IOMUX_PAD(0x3D0, 0xA4, 3, 0x74C, 1, 0)
+#define _MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 IOMUX_PAD(0x3D0, 0xA4, 4, 0x86C, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 IOMUX_PAD(0x3D0, 0xA4, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 IOMUX_PAD(0x3D0, 0xA4, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 IOMUX_PAD(0x3D4, 0xA8, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__GPIO5_12 IOMUX_PAD(0x3D4, 0xA8, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__ECSPI2_SS0 IOMUX_PAD(0x3D4, 0xA8, 2, 0x7C4, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS IOMUX_PAD(0x3D4, 0xA8, 3, 0x75C, 1, 0)
+#define _MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS IOMUX_PAD(0x3D4, 0xA8, 4, 0x73C, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 IOMUX_PAD(0x3D4, 0xA8, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 IOMUX_PAD(0x3D4, 0xA8, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 IOMUX_PAD(0x3D4, 0xA8, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 IOMUX_PAD(0x3D8, 0xAC, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__GPIO5_13 IOMUX_PAD(0x3D8, 0xAC, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__ECSPI2_SCLK IOMUX_PAD(0x3D8, 0xAC, 2, 0x7B8, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD IOMUX_PAD(0x3D8, 0xAC, 3, 0x748, 1, 0)
+#define _MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC IOMUX_PAD(0x3D8, 0xAC, 4, 0x738, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 IOMUX_PAD(0x3D8, 0xAC, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 IOMUX_PAD(0x3D8, 0xAC, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 IOMUX_PAD(0x3D8, 0xAC, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 IOMUX_PAD(0x3DC, 0xB0, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__GPIO5_14 IOMUX_PAD(0x3DC, 0xB0, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__ECSPI1_SCLK IOMUX_PAD(0x3DC, 0xB0, 2, 0x79C, 1, 0)
+#define _MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC IOMUX_PAD(0x3DC, 0xB0, 3, 0x740, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 IOMUX_PAD(0x3DC, 0xB0, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 IOMUX_PAD(0x3DC, 0xB0, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT20__SATA_PHY_TDI IOMUX_PAD(0x3DC, 0xB0, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 IOMUX_PAD(0x3E0, 0xB4, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__GPIO5_15 IOMUX_PAD(0x3E0, 0xB4, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__ECSPI1_MOSI IOMUX_PAD(0x3E0, 0xB4, 2, 0x7A4, 1, 0)
+#define _MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD IOMUX_PAD(0x3E0, 0xB4, 3, 0x734, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 IOMUX_PAD(0x3E0, 0xB4, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 IOMUX_PAD(0x3E0, 0xB4, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT21__SATA_PHY_TDO IOMUX_PAD(0x3E0, 0xB4, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 IOMUX_PAD(0x3E4, 0xB8, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__GPIO5_16 IOMUX_PAD(0x3E4, 0xB8, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__ECSPI1_MISO IOMUX_PAD(0x3E4, 0xB8, 2, 0x7A0, 1, 0)
+#define _MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS IOMUX_PAD(0x3E4, 0xB8, 3, 0x744, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 IOMUX_PAD(0x3E4, 0xB8, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 IOMUX_PAD(0x3E4, 0xB8, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT22__SATA_PHY_TCK IOMUX_PAD(0x3E4, 0xB8, 7, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 IOMUX_PAD(0x3E8, 0xBC, 0, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__GPIO5_17 IOMUX_PAD(0x3E8, 0xBC, 1, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__ECSPI1_SS0 IOMUX_PAD(0x3E8, 0xBC, 2, 0x7A8, 1, 0)
+#define _MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD IOMUX_PAD(0x3E8, 0xBC, 3, 0x730, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 IOMUX_PAD(0x3E8, 0xBC, 5, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 IOMUX_PAD(0x3E8, 0xBC, 6, 0x0, 0, 0)
+#define _MX53_PAD_DISP0_DAT23__SATA_PHY_TMS IOMUX_PAD(0x3E8, 0xBC, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK IOMUX_PAD(0x3EC, 0xC0, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_PIXCLK__GPIO5_18 IOMUX_PAD(0x3EC, 0xC0, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 IOMUX_PAD(0x3EC, 0xC0, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 IOMUX_PAD(0x3EC, 0xC0, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC IOMUX_PAD(0x3F0, 0xC4, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__GPIO5_19 IOMUX_PAD(0x3F0, 0xC4, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK IOMUX_PAD(0x3F0, 0xC4, 2, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 IOMUX_PAD(0x3F0, 0xC4, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 IOMUX_PAD(0x3F0, 0xC4, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_MCLK__TPIU_TRCTL IOMUX_PAD(0x3F0, 0xC4, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN IOMUX_PAD(0x3F4, 0xC8, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DATA_EN__GPIO5_20 IOMUX_PAD(0x3F4, 0xC8, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 IOMUX_PAD(0x3F4, 0xC8, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 IOMUX_PAD(0x3F4, 0xC8, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK IOMUX_PAD(0x3F4, 0xC8, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC IOMUX_PAD(0x3F8, 0xCC, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_VSYNC__GPIO5_21 IOMUX_PAD(0x3F8, 0xCC, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 IOMUX_PAD(0x3F8, 0xCC, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 IOMUX_PAD(0x3F8, 0xCC, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 IOMUX_PAD(0x3F8, 0xCC, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 IOMUX_PAD(0x3FC, 0xD0, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__GPIO5_22 IOMUX_PAD(0x3FC, 0xD0, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__KPP_COL_5 IOMUX_PAD(0x3FC, 0xD0, 2, 0x840, 1, 0)
+#define _MX53_PAD_CSI0_DAT4__ECSPI1_SCLK IOMUX_PAD(0x3FC, 0xD0, 3, 0x79C, 2, 0)
+#define _MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP IOMUX_PAD(0x3FC, 0xD0, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC IOMUX_PAD(0x3FC, 0xD0, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 IOMUX_PAD(0x3FC, 0xD0, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 IOMUX_PAD(0x3FC, 0xD0, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 IOMUX_PAD(0x400, 0xD4, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__GPIO5_23 IOMUX_PAD(0x400, 0xD4, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__KPP_ROW_5 IOMUX_PAD(0x400, 0xD4, 2, 0x84C, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__ECSPI1_MOSI IOMUX_PAD(0x400, 0xD4, 3, 0x7A4, 2, 0)
+#define _MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT IOMUX_PAD(0x400, 0xD4, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD IOMUX_PAD(0x400, 0xD4, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 IOMUX_PAD(0x400, 0xD4, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 IOMUX_PAD(0x400, 0xD4, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 IOMUX_PAD(0x404, 0xD8, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__GPIO5_24 IOMUX_PAD(0x404, 0xD8, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__KPP_COL_6 IOMUX_PAD(0x404, 0xD8, 2, 0x844, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__ECSPI1_MISO IOMUX_PAD(0x404, 0xD8, 3, 0x7A0, 2, 0)
+#define _MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK IOMUX_PAD(0x404, 0xD8, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS IOMUX_PAD(0x404, 0xD8, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 IOMUX_PAD(0x404, 0xD8, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 IOMUX_PAD(0x404, 0xD8, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 IOMUX_PAD(0x408, 0xDC, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__GPIO5_25 IOMUX_PAD(0x408, 0xDC, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__KPP_ROW_6 IOMUX_PAD(0x408, 0xDC, 2, 0x850, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__ECSPI1_SS0 IOMUX_PAD(0x408, 0xDC, 3, 0x7A8, 2, 0)
+#define _MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR IOMUX_PAD(0x408, 0xDC, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD IOMUX_PAD(0x408, 0xDC, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 IOMUX_PAD(0x408, 0xDC, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 IOMUX_PAD(0x408, 0xDC, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 IOMUX_PAD(0x40C, 0xE0, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__GPIO5_26 IOMUX_PAD(0x40C, 0xE0, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__KPP_COL_7 IOMUX_PAD(0x40C, 0xE0, 2, 0x848, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__ECSPI2_SCLK IOMUX_PAD(0x40C, 0xE0, 3, 0x7B8, 1, 0)
+#define _MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC IOMUX_PAD(0x40C, 0xE0, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__I2C1_SDA IOMUX_PAD(0x40C, 0xE0, 5 | IOMUX_CONFIG_SION, 0x818, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 IOMUX_PAD(0x40C, 0xE0, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 IOMUX_PAD(0x40C, 0xE0, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 IOMUX_PAD(0x410, 0xE4, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__GPIO5_27 IOMUX_PAD(0x410, 0xE4, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__KPP_ROW_7 IOMUX_PAD(0x410, 0xE4, 2, 0x854, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__ECSPI2_MOSI IOMUX_PAD(0x410, 0xE4, 3, 0x7C0, 1, 0)
+#define _MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR IOMUX_PAD(0x410, 0xE4, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__I2C1_SCL IOMUX_PAD(0x410, 0xE4, 5 | IOMUX_CONFIG_SION, 0x814, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 IOMUX_PAD(0x410, 0xE4, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 IOMUX_PAD(0x410, 0xE4, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 IOMUX_PAD(0x414, 0xE8, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__GPIO5_28 IOMUX_PAD(0x414, 0xE8, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__UART1_TXD_MUX IOMUX_PAD(0x414, 0xE8, 2, 0x878, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__ECSPI2_MISO IOMUX_PAD(0x414, 0xE8, 3, 0x7BC, 1, 0)
+#define _MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC IOMUX_PAD(0x414, 0xE8, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 IOMUX_PAD(0x414, 0xE8, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 IOMUX_PAD(0x414, 0xE8, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 IOMUX_PAD(0x414, 0xE8, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 IOMUX_PAD(0x418, 0xEC, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__GPIO5_29 IOMUX_PAD(0x418, 0xEC, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__UART1_RXD_MUX IOMUX_PAD(0x418, 0xEC, 2, 0x878, 1, 0)
+#define _MX53_PAD_CSI0_DAT11__ECSPI2_SS0 IOMUX_PAD(0x418, 0xEC, 3, 0x7C4, 1, 0)
+#define _MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS IOMUX_PAD(0x418, 0xEC, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 IOMUX_PAD(0x418, 0xEC, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 IOMUX_PAD(0x418, 0xEC, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 IOMUX_PAD(0x418, 0xEC, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 IOMUX_PAD(0x41C, 0xF0, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__GPIO5_30 IOMUX_PAD(0x41C, 0xF0, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__UART4_TXD_MUX IOMUX_PAD(0x41C, 0xF0, 2, 0x890, 2, 0)
+#define _MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 IOMUX_PAD(0x41C, 0xF0, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 IOMUX_PAD(0x41C, 0xF0, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 IOMUX_PAD(0x41C, 0xF0, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 IOMUX_PAD(0x41C, 0xF0, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 IOMUX_PAD(0x420, 0xF4, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__GPIO5_31 IOMUX_PAD(0x420, 0xF4, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__UART4_RXD_MUX IOMUX_PAD(0x420, 0xF4, 2, 0x890, 3, 0)
+#define _MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 IOMUX_PAD(0x420, 0xF4, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 IOMUX_PAD(0x420, 0xF4, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 IOMUX_PAD(0x420, 0xF4, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 IOMUX_PAD(0x420, 0xF4, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 IOMUX_PAD(0x424, 0xF8, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__GPIO6_0 IOMUX_PAD(0x424, 0xF8, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__UART5_TXD_MUX IOMUX_PAD(0x424, 0xF8, 2, 0x898, 2, 0)
+#define _MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 IOMUX_PAD(0x424, 0xF8, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 IOMUX_PAD(0x424, 0xF8, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 IOMUX_PAD(0x424, 0xF8, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 IOMUX_PAD(0x424, 0xF8, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 IOMUX_PAD(0x428, 0xFC, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__GPIO6_1 IOMUX_PAD(0x428, 0xFC, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__UART5_RXD_MUX IOMUX_PAD(0x428, 0xFC, 2, 0x898, 3, 0)
+#define _MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 IOMUX_PAD(0x428, 0xFC, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 IOMUX_PAD(0x428, 0xFC, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 IOMUX_PAD(0x428, 0xFC, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 IOMUX_PAD(0x428, 0xFC, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 IOMUX_PAD(0x42C, 0x100, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__GPIO6_2 IOMUX_PAD(0x42C, 0x100, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__UART4_RTS IOMUX_PAD(0x42C, 0x100, 2, 0x88C, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 IOMUX_PAD(0x42C, 0x100, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 IOMUX_PAD(0x42C, 0x100, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 IOMUX_PAD(0x42C, 0x100, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 IOMUX_PAD(0x42C, 0x100, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 IOMUX_PAD(0x430, 0x104, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__GPIO6_3 IOMUX_PAD(0x430, 0x104, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__UART4_CTS IOMUX_PAD(0x430, 0x104, 2, 0x88C, 1, 0)
+#define _MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 IOMUX_PAD(0x430, 0x104, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 IOMUX_PAD(0x430, 0x104, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 IOMUX_PAD(0x430, 0x104, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 IOMUX_PAD(0x430, 0x104, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 IOMUX_PAD(0x434, 0x108, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__GPIO6_4 IOMUX_PAD(0x434, 0x108, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__UART5_RTS IOMUX_PAD(0x434, 0x108, 2, 0x894, 2, 0)
+#define _MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 IOMUX_PAD(0x434, 0x108, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 IOMUX_PAD(0x434, 0x108, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 IOMUX_PAD(0x434, 0x108, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 IOMUX_PAD(0x434, 0x108, 7, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 IOMUX_PAD(0x438, 0x10C, 0, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__GPIO6_5 IOMUX_PAD(0x438, 0x10C, 1, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__UART5_CTS IOMUX_PAD(0x438, 0x10C, 2, 0x894, 3, 0)
+#define _MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 IOMUX_PAD(0x438, 0x10C, 4, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 IOMUX_PAD(0x438, 0x10C, 5, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 IOMUX_PAD(0x438, 0x10C, 6, 0x0, 0, 0)
+#define _MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK IOMUX_PAD(0x438, 0x10C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__EMI_WEIM_A_25 IOMUX_PAD(0x458, 0x110, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__GPIO5_2 IOMUX_PAD(0x458, 0x110, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__ECSPI2_RDY IOMUX_PAD(0x458, 0x110, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__IPU_DI1_PIN12 IOMUX_PAD(0x458, 0x110, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__CSPI_SS1 IOMUX_PAD(0x458, 0x110, 4, 0x790, 1, 0)
+#define _MX53_PAD_EIM_A25__IPU_DI0_D1_CS IOMUX_PAD(0x458, 0x110, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A25__USBPHY1_BISTOK IOMUX_PAD(0x458, 0x110, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 IOMUX_PAD(0x45C, 0x114, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB2__GPIO2_30 IOMUX_PAD(0x45C, 0x114, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK IOMUX_PAD(0x45C, 0x114, 2, 0x76C, 0, 0)
+#define _MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS IOMUX_PAD(0x45C, 0x114, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB2__ECSPI1_SS0 IOMUX_PAD(0x45C, 0x114, 4, 0x7A8, 3, 0)
+#define _MX53_PAD_EIM_EB2__I2C2_SCL IOMUX_PAD(0x45C, 0x114, 5 | IOMUX_CONFIG_SION, 0x81C, 1, 0)
+#define _MX53_PAD_EIM_D16__EMI_WEIM_D_16 IOMUX_PAD(0x460, 0x118, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D16__GPIO3_16 IOMUX_PAD(0x460, 0x118, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D16__IPU_DI0_PIN5 IOMUX_PAD(0x460, 0x118, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK IOMUX_PAD(0x460, 0x118, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D16__ECSPI1_SCLK IOMUX_PAD(0x460, 0x118, 4, 0x79C, 3, 0)
+#define _MX53_PAD_EIM_D16__I2C2_SDA IOMUX_PAD(0x460, 0x118, 5, 0x820, 1, 0)
+#define _MX53_PAD_EIM_D17__EMI_WEIM_D_17 IOMUX_PAD(0x464, 0x11C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D17__GPIO3_17 IOMUX_PAD(0x464, 0x11C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D17__IPU_DI0_PIN6 IOMUX_PAD(0x464, 0x11C, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN IOMUX_PAD(0x464, 0x11C, 3, 0x830, 0, 0)
+#define _MX53_PAD_EIM_D17__ECSPI1_MISO IOMUX_PAD(0x464, 0x11C, 4, 0x7A0, 3, 0)
+#define _MX53_PAD_EIM_D17__I2C3_SCL IOMUX_PAD(0x464, 0x11C, 5, 0x824, 0, 0)
+#define _MX53_PAD_EIM_D18__EMI_WEIM_D_18 IOMUX_PAD(0x468, 0x120, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D18__GPIO3_18 IOMUX_PAD(0x468, 0x120, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D18__IPU_DI0_PIN7 IOMUX_PAD(0x468, 0x120, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO IOMUX_PAD(0x468, 0x120, 3, 0x830, 1, 0)
+#define _MX53_PAD_EIM_D18__ECSPI1_MOSI IOMUX_PAD(0x468, 0x120, 4, 0x7A4, 3, 0)
+#define _MX53_PAD_EIM_D18__I2C3_SDA IOMUX_PAD(0x468, 0x120, 5, 0x828, 0, 0)
+#define _MX53_PAD_EIM_D18__IPU_DI1_D0_CS IOMUX_PAD(0x468, 0x120, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__EMI_WEIM_D_19 IOMUX_PAD(0x46C, 0x124, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__GPIO3_19 IOMUX_PAD(0x46C, 0x124, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__IPU_DI0_PIN8 IOMUX_PAD(0x46C, 0x124, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS IOMUX_PAD(0x46C, 0x124, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__ECSPI1_SS1 IOMUX_PAD(0x46C, 0x124, 4, 0x7AC, 2, 0)
+#define _MX53_PAD_EIM_D19__EPIT1_EPITO IOMUX_PAD(0x46C, 0x124, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D19__UART1_CTS IOMUX_PAD(0x46C, 0x124, 6, 0x874, 0, 0)
+#define _MX53_PAD_EIM_D19__USBOH3_USBH2_OC IOMUX_PAD(0x46C, 0x124, 7, 0x8A4, 0, 0)
+#define _MX53_PAD_EIM_D20__EMI_WEIM_D_20 IOMUX_PAD(0x470, 0x128, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D20__GPIO3_20 IOMUX_PAD(0x470, 0x128, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D20__IPU_DI0_PIN16 IOMUX_PAD(0x470, 0x128, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D20__IPU_SER_DISP0_CS IOMUX_PAD(0x470, 0x128, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D20__CSPI_SS0 IOMUX_PAD(0x470, 0x128, 4, 0x78C, 1, 0)
+#define _MX53_PAD_EIM_D20__EPIT2_EPITO IOMUX_PAD(0x470, 0x128, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D20__UART1_RTS IOMUX_PAD(0x470, 0x128, 6, 0x874, 1, 0)
+#define _MX53_PAD_EIM_D20__USBOH3_USBH2_PWR IOMUX_PAD(0x470, 0x128, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D21__EMI_WEIM_D_21 IOMUX_PAD(0x474, 0x12C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D21__GPIO3_21 IOMUX_PAD(0x474, 0x12C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D21__IPU_DI0_PIN17 IOMUX_PAD(0x474, 0x12C, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK IOMUX_PAD(0x474, 0x12C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D21__CSPI_SCLK IOMUX_PAD(0x474, 0x12C, 4, 0x780, 1, 0)
+#define _MX53_PAD_EIM_D21__I2C1_SCL IOMUX_PAD(0x474, 0x12C, 5, 0x814, 1, 0)
+#define _MX53_PAD_EIM_D21__USBOH3_USBOTG_OC IOMUX_PAD(0x474, 0x12C, 6, 0x89C, 1, 0)
+#define _MX53_PAD_EIM_D22__EMI_WEIM_D_22 IOMUX_PAD(0x478, 0x130, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D22__GPIO3_22 IOMUX_PAD(0x478, 0x130, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D22__IPU_DI0_PIN1 IOMUX_PAD(0x478, 0x130, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN IOMUX_PAD(0x478, 0x130, 3, 0x82C, 0, 0)
+#define _MX53_PAD_EIM_D22__CSPI_MISO IOMUX_PAD(0x478, 0x130, 4, 0x784, 1, 0)
+#define _MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR IOMUX_PAD(0x478, 0x130, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__EMI_WEIM_D_23 IOMUX_PAD(0x47C, 0x134, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__GPIO3_23 IOMUX_PAD(0x47C, 0x134, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__UART3_CTS IOMUX_PAD(0x47C, 0x134, 2, 0, 0, 0)
+#define _MX53_PAD_EIM_D23__UART1_DCD IOMUX_PAD(0x47C, 0x134, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__IPU_DI0_D0_CS IOMUX_PAD(0x47C, 0x134, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__IPU_DI1_PIN2 IOMUX_PAD(0x47C, 0x134, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN IOMUX_PAD(0x47C, 0x134, 6, 0x834, 0, 0)
+#define _MX53_PAD_EIM_D23__IPU_DI1_PIN14 IOMUX_PAD(0x47C, 0x134, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 IOMUX_PAD(0x480, 0x138, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB3__GPIO2_31 IOMUX_PAD(0x480, 0x138, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB3__UART3_RTS IOMUX_PAD(0x480, 0x138, 2, 0x884, 1, 0)
+#define _MX53_PAD_EIM_EB3__UART1_RI IOMUX_PAD(0x480, 0x138, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB3__IPU_DI1_PIN3 IOMUX_PAD(0x480, 0x138, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC IOMUX_PAD(0x480, 0x138, 6, 0x838, 0, 0)
+#define _MX53_PAD_EIM_EB3__IPU_DI1_PIN16 IOMUX_PAD(0x480, 0x138, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D24__EMI_WEIM_D_24 IOMUX_PAD(0x484, 0x13C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D24__GPIO3_24 IOMUX_PAD(0x484, 0x13C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D24__UART3_TXD_MUX IOMUX_PAD(0x484, 0x13C, 2, 0x888, 0, 0)
+#define _MX53_PAD_EIM_D24__ECSPI1_SS2 IOMUX_PAD(0x484, 0x13C, 3, 0x7B0, 1, 0)
+#define _MX53_PAD_EIM_D24__CSPI_SS2 IOMUX_PAD(0x484, 0x13C, 4, 0x794, 1, 0)
+#define _MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS IOMUX_PAD(0x484, 0x13C, 5, 0x754, 1, 0)
+#define _MX53_PAD_EIM_D24__ECSPI2_SS2 IOMUX_PAD(0x484, 0x13C, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D24__UART1_DTR IOMUX_PAD(0x484, 0x13C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D25__EMI_WEIM_D_25 IOMUX_PAD(0x488, 0x140, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D25__GPIO3_25 IOMUX_PAD(0x488, 0x140, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D25__UART3_RXD_MUX IOMUX_PAD(0x488, 0x140, 2, 0x888, 1, 0)
+#define _MX53_PAD_EIM_D25__ECSPI1_SS3 IOMUX_PAD(0x488, 0x140, 3, 0x7B4, 1, 0)
+#define _MX53_PAD_EIM_D25__CSPI_SS3 IOMUX_PAD(0x488, 0x140, 4, 0x798, 1, 0)
+#define _MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC IOMUX_PAD(0x488, 0x140, 5, 0x750, 1, 0)
+#define _MX53_PAD_EIM_D25__ECSPI2_SS3 IOMUX_PAD(0x488, 0x140, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D25__UART1_DSR IOMUX_PAD(0x488, 0x140, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__EMI_WEIM_D_26 IOMUX_PAD(0x48C, 0x144, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__GPIO3_26 IOMUX_PAD(0x48C, 0x144, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__UART2_TXD_MUX IOMUX_PAD(0x48C, 0x144, 2, 0x880, 0, 0)
+#define _MX53_PAD_EIM_D26__FIRI_RXD IOMUX_PAD(0x48C, 0x144, 3, 0x80C, 0, 0)
+#define _MX53_PAD_EIM_D26__IPU_CSI0_D_1 IOMUX_PAD(0x48C, 0x144, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__IPU_DI1_PIN11 IOMUX_PAD(0x48C, 0x144, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__IPU_SISG_2 IOMUX_PAD(0x48C, 0x144, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 IOMUX_PAD(0x48C, 0x144, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__EMI_WEIM_D_27 IOMUX_PAD(0x490, 0x148, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__GPIO3_27 IOMUX_PAD(0x490, 0x148, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__UART2_RXD_MUX IOMUX_PAD(0x490, 0x148, 2, 0x880, 1, 0)
+#define _MX53_PAD_EIM_D27__FIRI_TXD IOMUX_PAD(0x490, 0x148, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__IPU_CSI0_D_0 IOMUX_PAD(0x490, 0x148, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__IPU_DI1_PIN13 IOMUX_PAD(0x490, 0x148, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__IPU_SISG_3 IOMUX_PAD(0x490, 0x148, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 IOMUX_PAD(0x490, 0x148, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D28__EMI_WEIM_D_28 IOMUX_PAD(0x494, 0x14C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D28__GPIO3_28 IOMUX_PAD(0x494, 0x14C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D28__UART2_CTS IOMUX_PAD(0x494, 0x14C, 2, 0x87C, 0, 0)
+#define _MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO IOMUX_PAD(0x494, 0x14C, 3, 0x82C, 1, 0)
+#define _MX53_PAD_EIM_D28__CSPI_MOSI IOMUX_PAD(0x494, 0x14C, 4, 0x788, 1, 0)
+#define _MX53_PAD_EIM_D28__I2C1_SDA IOMUX_PAD(0x494, 0x14C, 5, 0x818, 1, 0)
+#define _MX53_PAD_EIM_D28__IPU_EXT_TRIG IOMUX_PAD(0x494, 0x14C, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D28__IPU_DI0_PIN13 IOMUX_PAD(0x494, 0x14C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D29__EMI_WEIM_D_29 IOMUX_PAD(0x498, 0x150, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D29__GPIO3_29 IOMUX_PAD(0x498, 0x150, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D29__UART2_RTS IOMUX_PAD(0x498, 0x150, 2, 0x87C, 1, 0)
+#define _MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS IOMUX_PAD(0x498, 0x150, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D29__CSPI_SS0 IOMUX_PAD(0x498, 0x150, 4, 0x78C, 2, 0)
+#define _MX53_PAD_EIM_D29__IPU_DI1_PIN15 IOMUX_PAD(0x498, 0x150, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D29__IPU_CSI1_VSYNC IOMUX_PAD(0x498, 0x150, 6, 0x83C, 0, 0)
+#define _MX53_PAD_EIM_D29__IPU_DI0_PIN14 IOMUX_PAD(0x498, 0x150, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__EMI_WEIM_D_30 IOMUX_PAD(0x49C, 0x154, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__GPIO3_30 IOMUX_PAD(0x49C, 0x154, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__UART3_CTS IOMUX_PAD(0x49C, 0x154, 2, 0x884, 2, 0)
+#define _MX53_PAD_EIM_D30__IPU_CSI0_D_3 IOMUX_PAD(0x49C, 0x154, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__IPU_DI0_PIN11 IOMUX_PAD(0x49C, 0x154, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 IOMUX_PAD(0x49C, 0x154, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D30__USBOH3_USBH1_OC IOMUX_PAD(0x49C, 0x154, 6, 0x8A0, 0, 0)
+#define _MX53_PAD_EIM_D30__USBOH3_USBH2_OC IOMUX_PAD(0x49C, 0x154, 7, 0x8A4, 1, 0)
+#define _MX53_PAD_EIM_D31__EMI_WEIM_D_31 IOMUX_PAD(0x4A0, 0x158, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__GPIO3_31 IOMUX_PAD(0x4A0, 0x158, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__UART3_RTS IOMUX_PAD(0x4A0, 0x158, 2, 0x884, 3, 0)
+#define _MX53_PAD_EIM_D31__IPU_CSI0_D_2 IOMUX_PAD(0x4A0, 0x158, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__IPU_DI0_PIN12 IOMUX_PAD(0x4A0, 0x158, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 IOMUX_PAD(0x4A0, 0x158, 5, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__USBOH3_USBH1_PWR IOMUX_PAD(0x4A0, 0x158, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_D31__USBOH3_USBH2_PWR IOMUX_PAD(0x4A0, 0x158, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__EMI_WEIM_A_24 IOMUX_PAD(0x4A8, 0x15C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__GPIO5_4 IOMUX_PAD(0x4A8, 0x15C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 IOMUX_PAD(0x4A8, 0x15C, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__IPU_CSI1_D_19 IOMUX_PAD(0x4A8, 0x15C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__IPU_SISG_2 IOMUX_PAD(0x4A8, 0x15C, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A24__USBPHY2_BVALID IOMUX_PAD(0x4A8, 0x15C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__EMI_WEIM_A_23 IOMUX_PAD(0x4AC, 0x160, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__GPIO6_6 IOMUX_PAD(0x4AC, 0x160, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 IOMUX_PAD(0x4AC, 0x160, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__IPU_CSI1_D_18 IOMUX_PAD(0x4AC, 0x160, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__IPU_SISG_3 IOMUX_PAD(0x4AC, 0x160, 6, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A23__USBPHY2_ENDSESSION IOMUX_PAD(0x4AC, 0x160, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A22__EMI_WEIM_A_22 IOMUX_PAD(0x4B0, 0x164, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A22__GPIO2_16 IOMUX_PAD(0x4B0, 0x164, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 IOMUX_PAD(0x4B0, 0x164, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A22__IPU_CSI1_D_17 IOMUX_PAD(0x4B0, 0x164, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A22__SRC_BT_CFG1_7 IOMUX_PAD(0x4B0, 0x164, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A21__EMI_WEIM_A_21 IOMUX_PAD(0x4B4, 0x168, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A21__GPIO2_17 IOMUX_PAD(0x4B4, 0x168, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 IOMUX_PAD(0x4B4, 0x168, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A21__IPU_CSI1_D_16 IOMUX_PAD(0x4B4, 0x168, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A21__SRC_BT_CFG1_6 IOMUX_PAD(0x4B4, 0x168, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A20__EMI_WEIM_A_20 IOMUX_PAD(0x4B8, 0x16C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A20__GPIO2_18 IOMUX_PAD(0x4B8, 0x16C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 IOMUX_PAD(0x4B8, 0x16C, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A20__IPU_CSI1_D_15 IOMUX_PAD(0x4B8, 0x16C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A20__SRC_BT_CFG1_5 IOMUX_PAD(0x4B8, 0x16C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A19__EMI_WEIM_A_19 IOMUX_PAD(0x4BC, 0x170, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A19__GPIO2_19 IOMUX_PAD(0x4BC, 0x170, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 IOMUX_PAD(0x4BC, 0x170, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A19__IPU_CSI1_D_14 IOMUX_PAD(0x4BC, 0x170, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A19__SRC_BT_CFG1_4 IOMUX_PAD(0x4BC, 0x170, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A18__EMI_WEIM_A_18 IOMUX_PAD(0x4C0, 0x174, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A18__GPIO2_20 IOMUX_PAD(0x4C0, 0x174, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 IOMUX_PAD(0x4C0, 0x174, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A18__IPU_CSI1_D_13 IOMUX_PAD(0x4C0, 0x174, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A18__SRC_BT_CFG1_3 IOMUX_PAD(0x4C0, 0x174, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A17__EMI_WEIM_A_17 IOMUX_PAD(0x4C4, 0x178, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A17__GPIO2_21 IOMUX_PAD(0x4C4, 0x178, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 IOMUX_PAD(0x4C4, 0x178, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A17__IPU_CSI1_D_12 IOMUX_PAD(0x4C4, 0x178, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A17__SRC_BT_CFG1_2 IOMUX_PAD(0x4C4, 0x178, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A16__EMI_WEIM_A_16 IOMUX_PAD(0x4C8, 0x17C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A16__GPIO2_22 IOMUX_PAD(0x4C8, 0x17C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK IOMUX_PAD(0x4C8, 0x17C, 2, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK IOMUX_PAD(0x4C8, 0x17C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_A16__SRC_BT_CFG1_1 IOMUX_PAD(0x4C8, 0x17C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 IOMUX_PAD(0x4CC, 0x180, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS0__GPIO2_23 IOMUX_PAD(0x4CC, 0x180, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS0__ECSPI2_SCLK IOMUX_PAD(0x4CC, 0x180, 2, 0x7B8, 2, 0)
+#define _MX53_PAD_EIM_CS0__IPU_DI1_PIN5 IOMUX_PAD(0x4CC, 0x180, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 IOMUX_PAD(0x4D0, 0x184, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS1__GPIO2_24 IOMUX_PAD(0x4D0, 0x184, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_CS1__ECSPI2_MOSI IOMUX_PAD(0x4D0, 0x184, 2, 0x7C0, 2, 0)
+#define _MX53_PAD_EIM_CS1__IPU_DI1_PIN6 IOMUX_PAD(0x4D0, 0x184, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_OE__EMI_WEIM_OE IOMUX_PAD(0x4D4, 0x188, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_OE__GPIO2_25 IOMUX_PAD(0x4D4, 0x188, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_OE__ECSPI2_MISO IOMUX_PAD(0x4D4, 0x188, 2, 0x7BC, 2, 0)
+#define _MX53_PAD_EIM_OE__IPU_DI1_PIN7 IOMUX_PAD(0x4D4, 0x188, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_OE__USBPHY2_IDDIG IOMUX_PAD(0x4D4, 0x188, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_RW__EMI_WEIM_RW IOMUX_PAD(0x4D8, 0x18C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_RW__GPIO2_26 IOMUX_PAD(0x4D8, 0x18C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_RW__ECSPI2_SS0 IOMUX_PAD(0x4D8, 0x18C, 2, 0x7C4, 2, 0)
+#define _MX53_PAD_EIM_RW__IPU_DI1_PIN8 IOMUX_PAD(0x4D8, 0x18C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT IOMUX_PAD(0x4D8, 0x18C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_LBA__EMI_WEIM_LBA IOMUX_PAD(0x4DC, 0x190, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_LBA__GPIO2_27 IOMUX_PAD(0x4DC, 0x190, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_LBA__ECSPI2_SS1 IOMUX_PAD(0x4DC, 0x190, 2, 0x7C8, 1, 0)
+#define _MX53_PAD_EIM_LBA__IPU_DI1_PIN17 IOMUX_PAD(0x4DC, 0x190, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 IOMUX_PAD(0x4DC, 0x190, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 IOMUX_PAD(0x4E4, 0x194, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB0__GPIO2_28 IOMUX_PAD(0x4E4, 0x194, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 IOMUX_PAD(0x4E4, 0x194, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB0__IPU_CSI1_D_11 IOMUX_PAD(0x4E4, 0x194, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB0__GPC_PMIC_RDY IOMUX_PAD(0x4E4, 0x194, 5, 0x810, 0, 0)
+#define _MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 IOMUX_PAD(0x4E4, 0x194, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 IOMUX_PAD(0x4E8, 0x198, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB1__GPIO2_29 IOMUX_PAD(0x4E8, 0x198, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 IOMUX_PAD(0x4E8, 0x198, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB1__IPU_CSI1_D_10 IOMUX_PAD(0x4E8, 0x198, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 IOMUX_PAD(0x4E8, 0x198, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 IOMUX_PAD(0x4EC, 0x19C, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA0__GPIO3_0 IOMUX_PAD(0x4EC, 0x19C, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 IOMUX_PAD(0x4EC, 0x19C, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA0__IPU_CSI1_D_9 IOMUX_PAD(0x4EC, 0x19C, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 IOMUX_PAD(0x4EC, 0x19C, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 IOMUX_PAD(0x4F0, 0x1A0, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA1__GPIO3_1 IOMUX_PAD(0x4F0, 0x1A0, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 IOMUX_PAD(0x4F0, 0x1A0, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA1__IPU_CSI1_D_8 IOMUX_PAD(0x4F0, 0x1A0, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 IOMUX_PAD(0x4F0, 0x1A0, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 IOMUX_PAD(0x4F4, 0x1A4, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA2__GPIO3_2 IOMUX_PAD(0x4F4, 0x1A4, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 IOMUX_PAD(0x4F4, 0x1A4, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA2__IPU_CSI1_D_7 IOMUX_PAD(0x4F4, 0x1A4, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 IOMUX_PAD(0x4F4, 0x1A4, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 IOMUX_PAD(0x4F8, 0x1A8, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA3__GPIO3_3 IOMUX_PAD(0x4F8, 0x1A8, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 IOMUX_PAD(0x4F8, 0x1A8, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA3__IPU_CSI1_D_6 IOMUX_PAD(0x4F8, 0x1A8, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 IOMUX_PAD(0x4F8, 0x1A8, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 IOMUX_PAD(0x4FC, 0x1AC, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA4__GPIO3_4 IOMUX_PAD(0x4FC, 0x1AC, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 IOMUX_PAD(0x4FC, 0x1AC, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA4__IPU_CSI1_D_5 IOMUX_PAD(0x4FC, 0x1AC, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 IOMUX_PAD(0x4FC, 0x1AC, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 IOMUX_PAD(0x500, 0x1B0, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA5__GPIO3_5 IOMUX_PAD(0x500, 0x1B0, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 IOMUX_PAD(0x500, 0x1B0, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA5__IPU_CSI1_D_4 IOMUX_PAD(0x500, 0x1B0, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 IOMUX_PAD(0x500, 0x1B0, 17, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 IOMUX_PAD(0x504, 0x1B4, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA6__GPIO3_6 IOMUX_PAD(0x504, 0x1B4, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 IOMUX_PAD(0x504, 0x1B4, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA6__IPU_CSI1_D_3 IOMUX_PAD(0x504, 0x1B4, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 IOMUX_PAD(0x504, 0x1B4, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 IOMUX_PAD(0x508, 0x1B8, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA7__GPIO3_7 IOMUX_PAD(0x508, 0x1B8, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 IOMUX_PAD(0x508, 0x1B8, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA7__IPU_CSI1_D_2 IOMUX_PAD(0x508, 0x1B8, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 IOMUX_PAD(0x508, 0x1B8, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 IOMUX_PAD(0x50C, 0x1BC, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA8__GPIO3_8 IOMUX_PAD(0x50C, 0x1BC, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 IOMUX_PAD(0x50C, 0x1BC, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA8__IPU_CSI1_D_1 IOMUX_PAD(0x50C, 0x1BC, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 IOMUX_PAD(0x50C, 0x1BC, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 IOMUX_PAD(0x510, 0x1C0, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA9__GPIO3_9 IOMUX_PAD(0x510, 0x1C0, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 IOMUX_PAD(0x510, 0x1C0, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA9__IPU_CSI1_D_0 IOMUX_PAD(0x510, 0x1C0, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 IOMUX_PAD(0x510, 0x1C0, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 IOMUX_PAD(0x514, 0x1C4, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA10__GPIO3_10 IOMUX_PAD(0x514, 0x1C4, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA10__IPU_DI1_PIN15 IOMUX_PAD(0x514, 0x1C4, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN IOMUX_PAD(0x514, 0x1C4, 4, 0x834, 1, 0)
+#define _MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 IOMUX_PAD(0x514, 0x1C4, 7, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 IOMUX_PAD(0x518, 0x1C8, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA11__GPIO3_11 IOMUX_PAD(0x518, 0x1C8, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA11__IPU_DI1_PIN2 IOMUX_PAD(0x518, 0x1C8, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC IOMUX_PAD(0x518, 0x1C8, 4, 0x838, 1, 0)
+#define _MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 IOMUX_PAD(0x51C, 0x1CC, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA12__GPIO3_12 IOMUX_PAD(0x51C, 0x1CC, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA12__IPU_DI1_PIN3 IOMUX_PAD(0x51C, 0x1CC, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC IOMUX_PAD(0x51C, 0x1CC, 4, 0x83C, 1, 0)
+#define _MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 IOMUX_PAD(0x520, 0x1D0, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA13__GPIO3_13 IOMUX_PAD(0x520, 0x1D0, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA13__IPU_DI1_D0_CS IOMUX_PAD(0x520, 0x1D0, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK IOMUX_PAD(0x520, 0x1D0, 4, 0x76C, 1, 0)
+#define _MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 IOMUX_PAD(0x524, 0x1D4, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA14__GPIO3_14 IOMUX_PAD(0x524, 0x1D4, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA14__IPU_DI1_D1_CS IOMUX_PAD(0x524, 0x1D4, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK IOMUX_PAD(0x524, 0x1D4, 4, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 IOMUX_PAD(0x528, 0x1D8, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA15__GPIO3_15 IOMUX_PAD(0x528, 0x1D8, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA15__IPU_DI1_PIN1 IOMUX_PAD(0x528, 0x1D8, 3, 0x0, 0, 0)
+#define _MX53_PAD_EIM_DA15__IPU_DI1_PIN4 IOMUX_PAD(0x528, 0x1D8, 4, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B IOMUX_PAD(0x52C, 0x1DC, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_WE_B__GPIO6_12 IOMUX_PAD(0x52C, 0x1DC, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B IOMUX_PAD(0x530, 0x1E0, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_RE_B__GPIO6_13 IOMUX_PAD(0x530, 0x1E0, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT IOMUX_PAD(0x534, 0x1E4, 0, 0x0, 0, 0)
+#define _MX53_PAD_EIM_WAIT__GPIO5_0 IOMUX_PAD(0x534, 0x1E4, 1, 0x0, 0, 0)
+#define _MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B IOMUX_PAD(0x534, 0x1E4, 2, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX3_P__GPIO6_22 IOMUX_PAD(NON_PAD_I, 0x1EC, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 IOMUX_PAD(NON_PAD_I, 0x1EC, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX2_P__GPIO6_24 IOMUX_PAD(NON_PAD_I, 0x1F0, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 IOMUX_PAD(NON_PAD_I, 0x1F0, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_CLK_P__GPIO6_26 IOMUX_PAD(NON_PAD_I, 0x1F4, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK IOMUX_PAD(NON_PAD_I, 0x1F4, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX1_P__GPIO6_28 IOMUX_PAD(NON_PAD_I, 0x1F8, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 IOMUX_PAD(NON_PAD_I, 0x1F8, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX0_P__GPIO6_30 IOMUX_PAD(NON_PAD_I, 0x1FC, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 IOMUX_PAD(NON_PAD_I, 0x1FC, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX3_P__GPIO7_22 IOMUX_PAD(NON_PAD_I, 0x200, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 IOMUX_PAD(NON_PAD_I, 0x200, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_CLK_P__GPIO7_24 IOMUX_PAD(NON_PAD_I, 0x204, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK IOMUX_PAD(NON_PAD_I, 0x204, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX2_P__GPIO7_26 IOMUX_PAD(NON_PAD_I, 0x208, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 IOMUX_PAD(NON_PAD_I, 0x208, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX1_P__GPIO7_28 IOMUX_PAD(NON_PAD_I, 0x20C, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 IOMUX_PAD(NON_PAD_I, 0x20C, 1, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX0_P__GPIO7_30 IOMUX_PAD(NON_PAD_I, 0x210, 0, 0x0, 0, 0)
+#define _MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 IOMUX_PAD(NON_PAD_I, 0x210, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_10__GPIO4_0 IOMUX_PAD(0x540, 0x214, 0, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_10__OSC32k_32K_OUT IOMUX_PAD(0x540, 0x214, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_11__GPIO4_1 IOMUX_PAD(0x544, 0x218, 0, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_12__GPIO4_2 IOMUX_PAD(0x548, 0x21C, 0, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_13__GPIO4_3 IOMUX_PAD(0x54C, 0x220, 0, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_14__GPIO4_4 IOMUX_PAD(0x550, 0x224, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CLE__EMI_NANDF_CLE IOMUX_PAD(0x5A0, 0x228, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CLE__GPIO6_7 IOMUX_PAD(0x5A0, 0x228, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 IOMUX_PAD(0x5A0, 0x228, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_ALE__EMI_NANDF_ALE IOMUX_PAD(0x5A4, 0x22C, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_ALE__GPIO6_8 IOMUX_PAD(0x5A4, 0x22C, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 IOMUX_PAD(0x5A4, 0x22C, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B IOMUX_PAD(0x5A8, 0x230, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_WP_B__GPIO6_9 IOMUX_PAD(0x5A8, 0x230, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 IOMUX_PAD(0x5A8, 0x230, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 IOMUX_PAD(0x5AC, 0x234, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_RB0__GPIO6_10 IOMUX_PAD(0x5AC, 0x234, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 IOMUX_PAD(0x5AC, 0x234, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 IOMUX_PAD(0x5B0, 0x238, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS0__GPIO6_11 IOMUX_PAD(0x5B0, 0x238, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 IOMUX_PAD(0x5B0, 0x238, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 IOMUX_PAD(0x5B4, 0x23C, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS1__GPIO6_14 IOMUX_PAD(0x5B4, 0x23C, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS1__MLB_MLBCLK IOMUX_PAD(0x5B4, 0x23C, 6, 0x858, 0, 0)
+#define _MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 IOMUX_PAD(0x5B4, 0x23C, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 IOMUX_PAD(0x5B8, 0x240, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__GPIO6_15 IOMUX_PAD(0x5B8, 0x240, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__IPU_SISG_0 IOMUX_PAD(0x5B8, 0x240, 2, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__ESAI1_TX0 IOMUX_PAD(0x5B8, 0x240, 3, 0x7E4, 0, 0)
+#define _MX53_PAD_NANDF_CS2__EMI_WEIM_CRE IOMUX_PAD(0x5B8, 0x240, 4, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK IOMUX_PAD(0x5B8, 0x240, 5, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS2__MLB_MLBSIG IOMUX_PAD(0x5B8, 0x240, 6, 0x860, 0, 0)
+#define _MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 IOMUX_PAD(0x5B8, 0x240, 7, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 IOMUX_PAD(0x5BC, 0x244, 0, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS3__GPIO6_16 IOMUX_PAD(0x5BC, 0x244, 1, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS3__IPU_SISG_1 IOMUX_PAD(0x5BC, 0x244, 2, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS3__ESAI1_TX1 IOMUX_PAD(0x5BC, 0x244, 3, 0x7E8, 0, 0)
+#define _MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 IOMUX_PAD(0x5BC, 0x244, 4, 0x0, 0, 0)
+#define _MX53_PAD_NANDF_CS3__MLB_MLBDAT IOMUX_PAD(0x5BC, 0x244, 6, 0x85C, 0, 0)
+#define _MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 IOMUX_PAD(0x5BC, 0x244, 7, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDIO__FEC_MDIO IOMUX_PAD(0x5C4, 0x248, 0, 0x804, 1, 0)
+#define _MX53_PAD_FEC_MDIO__GPIO1_22 IOMUX_PAD(0x5C4, 0x248, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDIO__ESAI1_SCKR IOMUX_PAD(0x5C4, 0x248, 2, 0x7DC, 0, 0)
+#define _MX53_PAD_FEC_MDIO__FEC_COL IOMUX_PAD(0x5C4, 0x248, 3, 0x800, 1, 0)
+#define _MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 IOMUX_PAD(0x5C4, 0x248, 4, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 IOMUX_PAD(0x5C4, 0x248, 5, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 IOMUX_PAD(0x5C4, 0x248, 6, 0x0, 0, 0)
+#define _MX53_PAD_FEC_REF_CLK__FEC_TX_CLK IOMUX_PAD(0x5C8, 0x24C, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_REF_CLK__GPIO1_23 IOMUX_PAD(0x5C8, 0x24C, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_REF_CLK__ESAI1_FSR IOMUX_PAD(0x5C8, 0x24C, 2, 0x7CC, 0, 0)
+#define _MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 IOMUX_PAD(0x5C8, 0x24C, 5, 0x0, 0, 0)
+#define _MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 IOMUX_PAD(0x5C8, 0x24C, 6, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RX_ER__FEC_RX_ER IOMUX_PAD(0x5CC, 0x250, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RX_ER__GPIO1_24 IOMUX_PAD(0x5CC, 0x250, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RX_ER__ESAI1_HCKR IOMUX_PAD(0x5CC, 0x250, 2, 0x7D4, 0, 0)
+#define _MX53_PAD_FEC_RX_ER__FEC_RX_CLK IOMUX_PAD(0x5CC, 0x250, 3, 0x808, 1, 0)
+#define _MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 IOMUX_PAD(0x5CC, 0x250, 4, 0x0, 0, 0)
+#define _MX53_PAD_FEC_CRS_DV__FEC_RX_DV IOMUX_PAD(0x5D0, 0x254, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_CRS_DV__GPIO1_25 IOMUX_PAD(0x5D0, 0x254, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_CRS_DV__ESAI1_SCKT IOMUX_PAD(0x5D0, 0x254, 2, 0x7E0, 0, 0)
+#define _MX53_PAD_FEC_RXD1__FEC_RDATA_1 IOMUX_PAD(0x5D4, 0x258, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RXD1__GPIO1_26 IOMUX_PAD(0x5D4, 0x258, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RXD1__ESAI1_FST IOMUX_PAD(0x5D4, 0x258, 2, 0x7D0, 0, 0)
+#define _MX53_PAD_FEC_RXD1__MLB_MLBSIG IOMUX_PAD(0x5D4, 0x258, 3, 0x860, 1, 0)
+#define _MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 IOMUX_PAD(0x5D4, 0x258, 4, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RXD0__FEC_RDATA_0 IOMUX_PAD(0x5D8, 0x25C, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RXD0__GPIO1_27 IOMUX_PAD(0x5D8, 0x25C, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_RXD0__ESAI1_HCKT IOMUX_PAD(0x5D8, 0x25C, 2, 0x7D8, 0, 0)
+#define _MX53_PAD_FEC_RXD0__OSC32k_32K_OUT IOMUX_PAD(0x5D8, 0x25C, 3, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TX_EN__FEC_TX_EN IOMUX_PAD(0x5DC, 0x260, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TX_EN__GPIO1_28 IOMUX_PAD(0x5DC, 0x260, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 IOMUX_PAD(0x5DC, 0x260, 2, 0x7F0, 0, 0)
+#define _MX53_PAD_FEC_TXD1__FEC_TDATA_1 IOMUX_PAD(0x5E0, 0x264, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TXD1__GPIO1_29 IOMUX_PAD(0x5E0, 0x264, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 IOMUX_PAD(0x5E0, 0x264, 2, 0x7EC, 0, 0)
+#define _MX53_PAD_FEC_TXD1__MLB_MLBCLK IOMUX_PAD(0x5E0, 0x264, 3, 0x858, 1, 0)
+#define _MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK IOMUX_PAD(0x5E0, 0x264, 4, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TXD0__FEC_TDATA_0 IOMUX_PAD(0x5E4, 0x268, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TXD0__GPIO1_30 IOMUX_PAD(0x5E4, 0x268, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 IOMUX_PAD(0x5E4, 0x268, 2, 0x7F4, 0, 0)
+#define _MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 IOMUX_PAD(0x5E4, 0x268, 7, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x5E8, 0x26C, 0, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDC__GPIO1_31 IOMUX_PAD(0x5E8, 0x26C, 1, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 IOMUX_PAD(0x5E8, 0x26C, 2, 0x7F8, 0, 0)
+#define _MX53_PAD_FEC_MDC__MLB_MLBDAT IOMUX_PAD(0x5E8, 0x26C, 3, 0x85C, 1, 0)
+#define _MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG IOMUX_PAD(0x5E8, 0x26C, 4, 0x0, 0, 0)
+#define _MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 IOMUX_PAD(0x5E8, 0x26C, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOW__PATA_DIOW IOMUX_PAD(0x5F0, 0x270, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOW__GPIO6_17 IOMUX_PAD(0x5F0, 0x270, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOW__UART1_TXD_MUX IOMUX_PAD(0x5F0, 0x270, 3, 0x878, 2, 0)
+#define _MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 IOMUX_PAD(0x5F0, 0x270, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMACK__PATA_DMACK IOMUX_PAD(0x5F4, 0x274, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMACK__GPIO6_18 IOMUX_PAD(0x5F4, 0x274, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMACK__UART1_RXD_MUX IOMUX_PAD(0x5F4, 0x274, 3, 0x878, 3, 0)
+#define _MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 IOMUX_PAD(0x5F4, 0x274, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMARQ__PATA_DMARQ IOMUX_PAD(0x5F8, 0x278, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMARQ__GPIO7_0 IOMUX_PAD(0x5F8, 0x278, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMARQ__UART2_TXD_MUX IOMUX_PAD(0x5F8, 0x278, 3, 0x880, 2, 0)
+#define _MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 IOMUX_PAD(0x5F8, 0x278, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 IOMUX_PAD(0x5F8, 0x278, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN IOMUX_PAD(0x5FC, 0x27C, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_BUFFER_EN__GPIO7_1 IOMUX_PAD(0x5FC, 0x27C, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX IOMUX_PAD(0x5FC, 0x27C, 3, 0x880, 3, 0)
+#define _MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 IOMUX_PAD(0x5FC, 0x27C, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 IOMUX_PAD(0x5FC, 0x27C, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_INTRQ__PATA_INTRQ IOMUX_PAD(0x600, 0x280, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_INTRQ__GPIO7_2 IOMUX_PAD(0x600, 0x280, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_INTRQ__UART2_CTS IOMUX_PAD(0x600, 0x280, 3, 0x87C, 2, 0)
+#define _MX53_PAD_PATA_INTRQ__CAN1_TXCAN IOMUX_PAD(0x600, 0x280, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 IOMUX_PAD(0x600, 0x280, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 IOMUX_PAD(0x600, 0x280, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOR__PATA_DIOR IOMUX_PAD(0x604, 0x284, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOR__GPIO7_3 IOMUX_PAD(0x604, 0x284, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DIOR__UART2_RTS IOMUX_PAD(0x604, 0x284, 3, 0x87C, 3, 0)
+#define _MX53_PAD_PATA_DIOR__CAN1_RXCAN IOMUX_PAD(0x604, 0x284, 4, 0x760, 1, 0)
+#define _MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 IOMUX_PAD(0x604, 0x284, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B IOMUX_PAD(0x608, 0x288, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_RESET_B__GPIO7_4 IOMUX_PAD(0x608, 0x288, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_RESET_B__ESDHC3_CMD IOMUX_PAD(0x608, 0x288, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_RESET_B__UART1_CTS IOMUX_PAD(0x608, 0x288, 3, 0x874, 2, 0)
+#define _MX53_PAD_PATA_RESET_B__CAN2_TXCAN IOMUX_PAD(0x608, 0x288, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 IOMUX_PAD(0x608, 0x288, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_IORDY__PATA_IORDY IOMUX_PAD(0x60C, 0x28C, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_IORDY__GPIO7_5 IOMUX_PAD(0x60C, 0x28C, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_IORDY__ESDHC3_CLK IOMUX_PAD(0x60C, 0x28C, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_IORDY__UART1_RTS IOMUX_PAD(0x60C, 0x28C, 3, 0x874, 3, 0)
+#define _MX53_PAD_PATA_IORDY__CAN2_RXCAN IOMUX_PAD(0x60C, 0x28C, 4, 0x764, 1, 0)
+#define _MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 IOMUX_PAD(0x60C, 0x28C, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_0__PATA_DA_0 IOMUX_PAD(0x610, 0x290, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_0__GPIO7_6 IOMUX_PAD(0x610, 0x290, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_0__ESDHC3_RST IOMUX_PAD(0x610, 0x290, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_0__OWIRE_LINE IOMUX_PAD(0x610, 0x290, 4, 0x864, 0, 0)
+#define _MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 IOMUX_PAD(0x610, 0x290, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_1__PATA_DA_1 IOMUX_PAD(0x614, 0x294, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_1__GPIO7_7 IOMUX_PAD(0x614, 0x294, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_1__ESDHC4_CMD IOMUX_PAD(0x614, 0x294, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_1__UART3_CTS IOMUX_PAD(0x614, 0x294, 4, 0x884, 4, 0)
+#define _MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 IOMUX_PAD(0x614, 0x294, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_2__PATA_DA_2 IOMUX_PAD(0x618, 0x298, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_2__GPIO7_8 IOMUX_PAD(0x618, 0x298, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_2__ESDHC4_CLK IOMUX_PAD(0x618, 0x298, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DA_2__UART3_RTS IOMUX_PAD(0x618, 0x298, 4, 0x884, 5, 0)
+#define _MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 IOMUX_PAD(0x618, 0x298, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_0__PATA_CS_0 IOMUX_PAD(0x61C, 0x29C, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_0__GPIO7_9 IOMUX_PAD(0x61C, 0x29C, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_0__UART3_TXD_MUX IOMUX_PAD(0x61C, 0x29C, 4, 0x888, 2, 0)
+#define _MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 IOMUX_PAD(0x61C, 0x29C, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_1__PATA_CS_1 IOMUX_PAD(0x620, 0x2A0, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_1__GPIO7_10 IOMUX_PAD(0x620, 0x2A0, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_CS_1__UART3_RXD_MUX IOMUX_PAD(0x620, 0x2A0, 4, 0x888, 3, 0)
+#define _MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 IOMUX_PAD(0x620, 0x2A0, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__PATA_DATA_0 IOMUX_PAD(0x628, 0x2A4, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__GPIO2_0 IOMUX_PAD(0x628, 0x2A4, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 IOMUX_PAD(0x628, 0x2A4, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__ESDHC3_DAT4 IOMUX_PAD(0x628, 0x2A4, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 IOMUX_PAD(0x628, 0x2A4, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 IOMUX_PAD(0x628, 0x2A4, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 IOMUX_PAD(0x628, 0x2A4, 7, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__PATA_DATA_1 IOMUX_PAD(0x62C, 0x2A8, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__GPIO2_1 IOMUX_PAD(0x62C, 0x2A8, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 IOMUX_PAD(0x62C, 0x2A8, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__ESDHC3_DAT5 IOMUX_PAD(0x62C, 0x2A8, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 IOMUX_PAD(0x62C, 0x2A8, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 IOMUX_PAD(0x62C, 0x2A8, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__PATA_DATA_2 IOMUX_PAD(0x630, 0x2AC, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__GPIO2_2 IOMUX_PAD(0x630, 0x2AC, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 IOMUX_PAD(0x630, 0x2AC, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__ESDHC3_DAT6 IOMUX_PAD(0x630, 0x2AC, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 IOMUX_PAD(0x630, 0x2AC, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 IOMUX_PAD(0x630, 0x2AC, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__PATA_DATA_3 IOMUX_PAD(0x634, 0x2B0, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__GPIO2_3 IOMUX_PAD(0x634, 0x2B0, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 IOMUX_PAD(0x634, 0x2B0, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__ESDHC3_DAT7 IOMUX_PAD(0x634, 0x2B0, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 IOMUX_PAD(0x634, 0x2B0, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 IOMUX_PAD(0x634, 0x2B0, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__PATA_DATA_4 IOMUX_PAD(0x638, 0x2B4, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__GPIO2_4 IOMUX_PAD(0x638, 0x2B4, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 IOMUX_PAD(0x638, 0x2B4, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__ESDHC4_DAT4 IOMUX_PAD(0x638, 0x2B4, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 IOMUX_PAD(0x638, 0x2B4, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 IOMUX_PAD(0x638, 0x2B4, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__PATA_DATA_5 IOMUX_PAD(0x63C, 0x2B8, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__GPIO2_5 IOMUX_PAD(0x63C, 0x2B8, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 IOMUX_PAD(0x63C, 0x2B8, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__ESDHC4_DAT5 IOMUX_PAD(0x63C, 0x2B8, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 IOMUX_PAD(0x63C, 0x2B8, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 IOMUX_PAD(0x63C, 0x2B8, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__PATA_DATA_6 IOMUX_PAD(0x640, 0x2BC, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__GPIO2_6 IOMUX_PAD(0x640, 0x2BC, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 IOMUX_PAD(0x640, 0x2BC, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__ESDHC4_DAT6 IOMUX_PAD(0x640, 0x2BC, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 IOMUX_PAD(0x640, 0x2BC, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 IOMUX_PAD(0x640, 0x2BC, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__PATA_DATA_7 IOMUX_PAD(0x644, 0x2C0, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__GPIO2_7 IOMUX_PAD(0x644, 0x2C0, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 IOMUX_PAD(0x644, 0x2C0, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__ESDHC4_DAT7 IOMUX_PAD(0x644, 0x2C0, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 IOMUX_PAD(0x644, 0x2C0, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 IOMUX_PAD(0x644, 0x2C0, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__PATA_DATA_8 IOMUX_PAD(0x648, 0x2C4, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__GPIO2_8 IOMUX_PAD(0x648, 0x2C4, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__ESDHC1_DAT4 IOMUX_PAD(0x648, 0x2C4, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 IOMUX_PAD(0x648, 0x2C4, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__ESDHC3_DAT0 IOMUX_PAD(0x648, 0x2C4, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 IOMUX_PAD(0x648, 0x2C4, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 IOMUX_PAD(0x648, 0x2C4, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__PATA_DATA_9 IOMUX_PAD(0x64C, 0x2C8, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__GPIO2_9 IOMUX_PAD(0x64C, 0x2C8, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__ESDHC1_DAT5 IOMUX_PAD(0x64C, 0x2C8, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 IOMUX_PAD(0x64C, 0x2C8, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__ESDHC3_DAT1 IOMUX_PAD(0x64C, 0x2C8, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 IOMUX_PAD(0x64C, 0x2C8, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 IOMUX_PAD(0x64C, 0x2C8, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__PATA_DATA_10 IOMUX_PAD(0x650, 0x2CC, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__GPIO2_10 IOMUX_PAD(0x650, 0x2CC, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__ESDHC1_DAT6 IOMUX_PAD(0x650, 0x2CC, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 IOMUX_PAD(0x650, 0x2CC, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__ESDHC3_DAT2 IOMUX_PAD(0x650, 0x2CC, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 IOMUX_PAD(0x650, 0x2CC, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 IOMUX_PAD(0x650, 0x2CC, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__PATA_DATA_11 IOMUX_PAD(0x654, 0x2D0, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__GPIO2_11 IOMUX_PAD(0x654, 0x2D0, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__ESDHC1_DAT7 IOMUX_PAD(0x654, 0x2D0, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 IOMUX_PAD(0x654, 0x2D0, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__ESDHC3_DAT3 IOMUX_PAD(0x654, 0x2D0, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 IOMUX_PAD(0x654, 0x2D0, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 IOMUX_PAD(0x654, 0x2D0, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__PATA_DATA_12 IOMUX_PAD(0x658, 0x2D4, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__GPIO2_12 IOMUX_PAD(0x658, 0x2D4, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__ESDHC2_DAT4 IOMUX_PAD(0x658, 0x2D4, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 IOMUX_PAD(0x658, 0x2D4, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__ESDHC4_DAT0 IOMUX_PAD(0x658, 0x2D4, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 IOMUX_PAD(0x658, 0x2D4, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 IOMUX_PAD(0x658, 0x2D4, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__PATA_DATA_13 IOMUX_PAD(0x65C, 0x2D8, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__GPIO2_13 IOMUX_PAD(0x65C, 0x2D8, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__ESDHC2_DAT5 IOMUX_PAD(0x65C, 0x2D8, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 IOMUX_PAD(0x65C, 0x2D8, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__ESDHC4_DAT1 IOMUX_PAD(0x65C, 0x2D8, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 IOMUX_PAD(0x65C, 0x2D8, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 IOMUX_PAD(0x65C, 0x2D8, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__PATA_DATA_14 IOMUX_PAD(0x660, 0x2DC, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__GPIO2_14 IOMUX_PAD(0x660, 0x2DC, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__ESDHC2_DAT6 IOMUX_PAD(0x660, 0x2DC, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 IOMUX_PAD(0x660, 0x2DC, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__ESDHC4_DAT2 IOMUX_PAD(0x660, 0x2DC, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 IOMUX_PAD(0x660, 0x2DC, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 IOMUX_PAD(0x660, 0x2DC, 6, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__PATA_DATA_15 IOMUX_PAD(0x664, 0x2E0, 0, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__GPIO2_15 IOMUX_PAD(0x664, 0x2E0, 1, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__ESDHC2_DAT7 IOMUX_PAD(0x664, 0x2E0, 2, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 IOMUX_PAD(0x664, 0x2E0, 3, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__ESDHC4_DAT3 IOMUX_PAD(0x664, 0x2E0, 4, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 IOMUX_PAD(0x664, 0x2E0, 5, 0x0, 0, 0)
+#define _MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 IOMUX_PAD(0x664, 0x2E0, 6, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA0__ESDHC1_DAT0 IOMUX_PAD(0x66C, 0x2E4, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA0__GPIO1_16 IOMUX_PAD(0x66C, 0x2E4, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA0__GPT_CAPIN1 IOMUX_PAD(0x66C, 0x2E4, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA0__CSPI_MISO IOMUX_PAD(0x66C, 0x2E4, 5, 0x784, 2, 0)
+#define _MX53_PAD_SD1_DATA0__CCM_PLL3_BYP IOMUX_PAD(0x66C, 0x2E4, 7, 0x778, 0, 0)
+#define _MX53_PAD_SD1_DATA1__ESDHC1_DAT1 IOMUX_PAD(0x670, 0x2E8, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA1__GPIO1_17 IOMUX_PAD(0x670, 0x2E8, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA1__GPT_CAPIN2 IOMUX_PAD(0x670, 0x2E8, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA1__CSPI_SS0 IOMUX_PAD(0x670, 0x2E8, 5, 0x78C, 3, 0)
+#define _MX53_PAD_SD1_DATA1__CCM_PLL4_BYP IOMUX_PAD(0x670, 0x2E8, 7, 0x77C, 1, 0)
+#define _MX53_PAD_SD1_CMD__ESDHC1_CMD IOMUX_PAD(0x674, 0x2EC, IOMUX_CONFIG_SION, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CMD__GPIO1_18 IOMUX_PAD(0x674, 0x2EC, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CMD__GPT_CMPOUT1 IOMUX_PAD(0x674, 0x2EC, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CMD__CSPI_MOSI IOMUX_PAD(0x674, 0x2EC, 5, 0x788, 2, 0)
+#define _MX53_PAD_SD1_CMD__CCM_PLL1_BYP IOMUX_PAD(0x674, 0x2EC, 7, 0x770, 0, 0)
+#define _MX53_PAD_SD1_DATA2__ESDHC1_DAT2 IOMUX_PAD(0x678, 0x2F0, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__GPIO1_19 IOMUX_PAD(0x678, 0x2F0, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__GPT_CMPOUT2 IOMUX_PAD(0x678, 0x2F0, 2, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__PWM2_PWMO IOMUX_PAD(0x678, 0x2F0, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__WDOG1_WDOG_B IOMUX_PAD(0x678, 0x2F0, 4, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__CSPI_SS1 IOMUX_PAD(0x678, 0x2F0, 5, 0x790, 2, 0)
+#define _MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB IOMUX_PAD(0x678, 0x2F0, 6, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA2__CCM_PLL2_BYP IOMUX_PAD(0x678, 0x2F0, 7, 0x774, 0, 0)
+#define _MX53_PAD_SD1_CLK__ESDHC1_CLK IOMUX_PAD(0x67C, 0x2F4, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CLK__GPIO1_20 IOMUX_PAD(0x67C, 0x2F4, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CLK__OSC32k_32K_OUT IOMUX_PAD(0x67C, 0x2F4, 2, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CLK__GPT_CLKIN IOMUX_PAD(0x67C, 0x2F4, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_CLK__CSPI_SCLK IOMUX_PAD(0x67C, 0x2F4, 5, 0x780, 2, 0)
+#define _MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 IOMUX_PAD(0x67C, 0x2F4, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__ESDHC1_DAT3 IOMUX_PAD(0x680, 0x2F8, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__GPIO1_21 IOMUX_PAD(0x680, 0x2F8, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__GPT_CMPOUT3 IOMUX_PAD(0x680, 0x2F8, 2, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__PWM1_PWMO IOMUX_PAD(0x680, 0x2F8, 3, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__WDOG2_WDOG_B IOMUX_PAD(0x680, 0x2F8, 4, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__CSPI_SS2 IOMUX_PAD(0x680, 0x2F8, 5, 0x794, 2, 0)
+#define _MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB IOMUX_PAD(0x680, 0x2F8, 6, 0x0, 0, 0)
+#define _MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 IOMUX_PAD(0x680, 0x2F8, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CLK__ESDHC2_CLK IOMUX_PAD(0x688, 0x2FC, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CLK__GPIO1_10 IOMUX_PAD(0x688, 0x2FC, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CLK__KPP_COL_5 IOMUX_PAD(0x688, 0x2FC, 2, 0x840, 2, 0)
+#define _MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS IOMUX_PAD(0x688, 0x2FC, 3, 0x73C, 1, 0)
+#define _MX53_PAD_SD2_CLK__CSPI_SCLK IOMUX_PAD(0x688, 0x2FC, 5, 0x780, 3, 0)
+#define _MX53_PAD_SD2_CLK__SCC_RANDOM_V IOMUX_PAD(0x688, 0x2FC, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CMD__ESDHC2_CMD IOMUX_PAD(0x68C, 0x300, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CMD__GPIO1_11 IOMUX_PAD(0x68C, 0x300, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_CMD__KPP_ROW_5 IOMUX_PAD(0x68C, 0x300, 2, 0x84C, 1, 0)
+#define _MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC IOMUX_PAD(0x68C, 0x300, 3, 0x738, 1, 0)
+#define _MX53_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(0x68C, 0x300, 5, 0x788, 3, 0)
+#define _MX53_PAD_SD2_CMD__SCC_RANDOM IOMUX_PAD(0x68C, 0x300, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA3__ESDHC2_DAT3 IOMUX_PAD(0x690, 0x304, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA3__GPIO1_12 IOMUX_PAD(0x690, 0x304, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA3__KPP_COL_6 IOMUX_PAD(0x690, 0x304, 2, 0x844, 1, 0)
+#define _MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC IOMUX_PAD(0x690, 0x304, 3, 0x740, 1, 0)
+#define _MX53_PAD_SD2_DATA3__CSPI_SS2 IOMUX_PAD(0x690, 0x304, 5, 0x794, 3, 0)
+#define _MX53_PAD_SD2_DATA3__SJC_DONE IOMUX_PAD(0x690, 0x304, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA2__ESDHC2_DAT2 IOMUX_PAD(0x694, 0x308, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA2__GPIO1_13 IOMUX_PAD(0x694, 0x308, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA2__KPP_ROW_6 IOMUX_PAD(0x694, 0x308, 2, 0x850, 1, 0)
+#define _MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD IOMUX_PAD(0x694, 0x308, 3, 0x734, 1, 0)
+#define _MX53_PAD_SD2_DATA2__CSPI_SS1 IOMUX_PAD(0x694, 0x308, 5, 0x790, 3, 0)
+#define _MX53_PAD_SD2_DATA2__SJC_FAIL IOMUX_PAD(0x694, 0x308, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA1__ESDHC2_DAT1 IOMUX_PAD(0x698, 0x30C, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA1__GPIO1_14 IOMUX_PAD(0x698, 0x30C, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA1__KPP_COL_7 IOMUX_PAD(0x698, 0x30C, 2, 0x848, 1, 0)
+#define _MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS IOMUX_PAD(0x698, 0x30C, 3, 0x744, 0, 0)
+#define _MX53_PAD_SD2_DATA1__CSPI_SS0 IOMUX_PAD(0x698, 0x30C, 5, 0x78C, 4, 0)
+#define _MX53_PAD_SD2_DATA1__RTIC_SEC_VIO IOMUX_PAD(0x698, 0x30C, 7, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA0__ESDHC2_DAT0 IOMUX_PAD(0x69C, 0x310, 0, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA0__GPIO1_15 IOMUX_PAD(0x69C, 0x310, 1, 0x0, 0, 0)
+#define _MX53_PAD_SD2_DATA0__KPP_ROW_7 IOMUX_PAD(0x69C, 0x310, 2, 0x854, 1, 0)
+#define _MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD IOMUX_PAD(0x69C, 0x310, 3, 0x730, 1, 0)
+#define _MX53_PAD_SD2_DATA0__CSPI_MISO IOMUX_PAD(0x69C, 0x310, 5, 0x784, 3, 0)
+#define _MX53_PAD_SD2_DATA0__RTIC_DONE_INT IOMUX_PAD(0x69C, 0x310, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__CCM_CLKO IOMUX_PAD(0x6A4, 0x314, 0, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__GPIO1_0 IOMUX_PAD(0x6A4, 0x314, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__KPP_COL_5 IOMUX_PAD(0x6A4, 0x314, 2, 0x840, 3, 0)
+#define _MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK IOMUX_PAD(0x6A4, 0x314, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__EPIT1_EPITO IOMUX_PAD(0x6A4, 0x314, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__SRTC_ALARM_DEB IOMUX_PAD(0x6A4, 0x314, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__USBOH3_USBH1_PWR IOMUX_PAD(0x6A4, 0x314, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_0__CSU_TD IOMUX_PAD(0x6A4, 0x314, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__ESAI1_SCKR IOMUX_PAD(0x6A8, 0x318, 0, 0x7DC, 1, 0)
+#define _MX53_PAD_GPIO_1__GPIO1_1 IOMUX_PAD(0x6A8, 0x318, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__KPP_ROW_5 IOMUX_PAD(0x6A8, 0x318, 2, 0x84C, 2, 0)
+#define _MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK IOMUX_PAD(0x6A8, 0x318, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__PWM2_PWMO IOMUX_PAD(0x6A8, 0x318, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__WDOG2_WDOG_B IOMUX_PAD(0x6A8, 0x318, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__ESDHC1_CD IOMUX_PAD(0x6A8, 0x318, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_1__SRC_TESTER_ACK IOMUX_PAD(0x6A8, 0x318, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_9__ESAI1_FSR IOMUX_PAD(0x6AC, 0x31C, 0, 0x7CC, 1, 0)
+#define _MX53_PAD_GPIO_9__GPIO1_9 IOMUX_PAD(0x6AC, 0x31C, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_9__KPP_COL_6 IOMUX_PAD(0x6AC, 0x31C, 2, 0x844, 2, 0)
+#define _MX53_PAD_GPIO_9__CCM_REF_EN_B IOMUX_PAD(0x6AC, 0x31C, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_9__PWM1_PWMO IOMUX_PAD(0x6AC, 0x31C, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_9__WDOG1_WDOG_B IOMUX_PAD(0x6AC, 0x31C, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_9__ESDHC1_WP IOMUX_PAD(0x6AC, 0x31C, 6, 0x7FC, 1, 0)
+#define _MX53_PAD_GPIO_9__SCC_FAIL_STATE IOMUX_PAD(0x6AC, 0x31C, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_3__ESAI1_HCKR IOMUX_PAD(0x6B0, 0x320, 0, 0x7D4, 1, 0)
+#define _MX53_PAD_GPIO_3__GPIO1_3 IOMUX_PAD(0x6B0, 0x320, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_3__I2C3_SCL IOMUX_PAD(0x6B0, 0x320, 2 | IOMUX_CONFIG_SION, 0x824, 1, 0)
+#define _MX53_PAD_GPIO_3__DPLLIP1_TOG_EN IOMUX_PAD(0x6B0, 0x320, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_3__CCM_CLKO2 IOMUX_PAD(0x6B0, 0x320, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 IOMUX_PAD(0x6B0, 0x320, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_3__USBOH3_USBH1_OC IOMUX_PAD(0x6B0, 0x320, 6, 0x8A0, 1, 0)
+#define _MX53_PAD_GPIO_3__MLB_MLBCLK IOMUX_PAD(0x6B0, 0x320, 7, 0x858, 2, 0)
+#define _MX53_PAD_GPIO_6__ESAI1_SCKT IOMUX_PAD(0x6B4, 0x324, 0, 0x7E0, 1, 0)
+#define _MX53_PAD_GPIO_6__GPIO1_6 IOMUX_PAD(0x6B4, 0x324, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_6__I2C3_SDA IOMUX_PAD(0x6B4, 0x324, 2 | IOMUX_CONFIG_SION, 0x828, 1, 0)
+#define _MX53_PAD_GPIO_6__CCM_CCM_OUT_0 IOMUX_PAD(0x6B4, 0x324, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_6__CSU_CSU_INT_DEB IOMUX_PAD(0x6B4, 0x324, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 IOMUX_PAD(0x6B4, 0x324, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_6__ESDHC2_LCTL IOMUX_PAD(0x6B4, 0x324, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_6__MLB_MLBSIG IOMUX_PAD(0x6B4, 0x324, 7, 0x860, 2, 0)
+#define _MX53_PAD_GPIO_2__ESAI1_FST IOMUX_PAD(0x6B8, 0x328, 0, 0x7D0, 1, 0)
+#define _MX53_PAD_GPIO_2__GPIO1_2 IOMUX_PAD(0x6B8, 0x328, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_2__KPP_ROW_6 IOMUX_PAD(0x6B8, 0x328, 2, 0x850, 2, 0)
+#define _MX53_PAD_GPIO_2__CCM_CCM_OUT_1 IOMUX_PAD(0x6B8, 0x328, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 IOMUX_PAD(0x6B8, 0x328, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 IOMUX_PAD(0x6B8, 0x328, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_2__ESDHC2_WP IOMUX_PAD(0x6B8, 0x328, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_2__MLB_MLBDAT IOMUX_PAD(0x6B8, 0x328, 7, 0x85C, 2, 0)
+#define _MX53_PAD_GPIO_4__ESAI1_HCKT IOMUX_PAD(0x6BC, 0x32C, 0, 0x7D8, 1, 0)
+#define _MX53_PAD_GPIO_4__GPIO1_4 IOMUX_PAD(0x6BC, 0x32C, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_4__KPP_COL_7 IOMUX_PAD(0x6BC, 0x32C, 2, 0x848, 2, 0)
+#define _MX53_PAD_GPIO_4__CCM_CCM_OUT_2 IOMUX_PAD(0x6BC, 0x32C, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 IOMUX_PAD(0x6BC, 0x32C, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 IOMUX_PAD(0x6BC, 0x32C, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_4__ESDHC2_CD IOMUX_PAD(0x6BC, 0x32C, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_4__SCC_SEC_STATE IOMUX_PAD(0x6BC, 0x32C, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_5__ESAI1_TX2_RX3 IOMUX_PAD(0x6C0, 0x330, 0, 0x7EC, 1, 0)
+#define _MX53_PAD_GPIO_5__GPIO1_5 IOMUX_PAD(0x6C0, 0x330, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_5__KPP_ROW_7 IOMUX_PAD(0x6C0, 0x330, 2, 0x854, 2, 0)
+#define _MX53_PAD_GPIO_5__CCM_CLKO IOMUX_PAD(0x6C0, 0x330, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 IOMUX_PAD(0x6C0, 0x330, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 IOMUX_PAD(0x6C0, 0x330, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_5__I2C3_SCL IOMUX_PAD(0x6C0, 0x330, 6, 0x824, 2, 0)
+#define _MX53_PAD_GPIO_5__CCM_PLL1_BYP IOMUX_PAD(0x6C0, 0x330, 7, 0x770, 1, 0)
+#define _MX53_PAD_GPIO_7__ESAI1_TX4_RX1 IOMUX_PAD(0x6C4, 0x334, 0, 0x7F4, 1, 0)
+#define _MX53_PAD_GPIO_7__GPIO1_7 IOMUX_PAD(0x6C4, 0x334, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_7__EPIT1_EPITO IOMUX_PAD(0x6C4, 0x334, 2, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_7__CAN1_TXCAN IOMUX_PAD(0x6C4, 0x334, 3, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_7__UART2_TXD_MUX IOMUX_PAD(0x6C4, 0x334, 4, 0x880, 4, 0)
+#define _MX53_PAD_GPIO_7__FIRI_RXD IOMUX_PAD(0x6C4, 0x334, 5, 0x80C, 1, 0)
+#define _MX53_PAD_GPIO_7__SPDIF_PLOCK IOMUX_PAD(0x6C4, 0x334, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_7__CCM_PLL2_BYP IOMUX_PAD(0x6C4, 0x334, 7, 0x774, 1, 0)
+#define _MX53_PAD_GPIO_8__ESAI1_TX5_RX0 IOMUX_PAD(0x6C8, 0x338, 0, 0x7F8, 1, 0)
+#define _MX53_PAD_GPIO_8__GPIO1_8 IOMUX_PAD(0x6C8, 0x338, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_8__EPIT2_EPITO IOMUX_PAD(0x6C8, 0x338, 2, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_8__CAN1_RXCAN IOMUX_PAD(0x6C8, 0x338, 3, 0x760, 3, 0)
+#define _MX53_PAD_GPIO_8__UART2_RXD_MUX IOMUX_PAD(0x6C8, 0x338, 4, 0x880, 5, 0)
+#define _MX53_PAD_GPIO_8__FIRI_TXD IOMUX_PAD(0x6C8, 0x338, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_8__SPDIF_SRCLK IOMUX_PAD(0x6C8, 0x338, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_8__CCM_PLL3_BYP IOMUX_PAD(0x6C8, 0x338, 7, 0x778, 1, 0)
+#define _MX53_PAD_GPIO_16__ESAI1_TX3_RX2 IOMUX_PAD(0x6CC, 0x33C, 0, 0x7F0, 1, 0)
+#define _MX53_PAD_GPIO_16__GPIO7_11 IOMUX_PAD(0x6CC, 0x33C, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT IOMUX_PAD(0x6CC, 0x33C, 2, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 IOMUX_PAD(0x6CC, 0x33C, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_16__SPDIF_IN1 IOMUX_PAD(0x6CC, 0x33C, 5, 0x870, 1, 0)
+#define _MX53_PAD_GPIO_16__I2C3_SDA IOMUX_PAD(0x6CC, 0x33C, 6 | IOMUX_CONFIG_SION, 0x828, 2, 0)
+#define _MX53_PAD_GPIO_16__SJC_DE_B IOMUX_PAD(0x6CC, 0x33C, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_17__ESAI1_TX0 IOMUX_PAD(0x6D0, 0x340, 0, 0x7E4, 1, 0)
+#define _MX53_PAD_GPIO_17__GPIO7_12 IOMUX_PAD(0x6D0, 0x340, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 IOMUX_PAD(0x6D0, 0x340, 2, 0x868, 1, 0)
+#define _MX53_PAD_GPIO_17__GPC_PMIC_RDY IOMUX_PAD(0x6D0, 0x340, 3, 0x810, 1, 0)
+#define _MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG IOMUX_PAD(0x6D0, 0x340, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_17__SPDIF_OUT1 IOMUX_PAD(0x6D0, 0x340, 5, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_17__IPU_SNOOP2 IOMUX_PAD(0x6D0, 0x340, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_17__SJC_JTAG_ACT IOMUX_PAD(0x6D0, 0x340, 7, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_18__ESAI1_TX1 IOMUX_PAD(0x6D4, 0x344, 0, 0x7E8, 1, 0)
+#define _MX53_PAD_GPIO_18__GPIO7_13 IOMUX_PAD(0x6D4, 0x344, 1, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 IOMUX_PAD(0x6D4, 0x344, 2, 0x86C, 1, 0)
+#define _MX53_PAD_GPIO_18__OWIRE_LINE IOMUX_PAD(0x6D4, 0x344, 3, 0x864, 1, 0)
+#define _MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG IOMUX_PAD(0x6D4, 0x344, 4, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK IOMUX_PAD(0x6D4, 0x344, 5, 0x768, 1, 0)
+#define _MX53_PAD_GPIO_18__ESDHC1_LCTL IOMUX_PAD(0x6D4, 0x344, 6, 0x0, 0, 0)
+#define _MX53_PAD_GPIO_18__SRC_SYSTEM_RST IOMUX_PAD(0x6D4, 0x344, 7, 0x0, 0, 0)
+
+#define MX53_PAD_GPIO_19__KPP_COL_5 (_MX53_PAD_GPIO_19__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__GPIO4_5 (_MX53_PAD_GPIO_19__GPIO4_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__CCM_CLKO (_MX53_PAD_GPIO_19__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__SPDIF_OUT1 (_MX53_PAD_GPIO_19__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 (_MX53_PAD_GPIO_19__RTC_CE_RTC_EXT_TRIG2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__ECSPI1_RDY (_MX53_PAD_GPIO_19__ECSPI1_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__FEC_TDATA_3 (_MX53_PAD_GPIO_19__FEC_TDATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_19__SRC_INT_BOOT (_MX53_PAD_GPIO_19__SRC_INT_BOOT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__KPP_COL_0 (_MX53_PAD_KEY_COL0__KPP_COL_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__GPIO4_6 (_MX53_PAD_KEY_COL0__GPIO4_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC (_MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__UART4_TXD_MUX (_MX53_PAD_KEY_COL0__UART4_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__ECSPI1_SCLK (_MX53_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__FEC_RDATA_3 (_MX53_PAD_KEY_COL0__FEC_RDATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL0__SRC_ANY_PU_RST (_MX53_PAD_KEY_COL0__SRC_ANY_PU_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__KPP_ROW_0 (_MX53_PAD_KEY_ROW0__KPP_ROW_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__GPIO4_7 (_MX53_PAD_KEY_ROW0__GPIO4_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD (_MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__UART4_RXD_MUX (_MX53_PAD_KEY_ROW0__UART4_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__ECSPI1_MOSI (_MX53_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW0__FEC_TX_ER (_MX53_PAD_KEY_ROW0__FEC_TX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__KPP_COL_1 (_MX53_PAD_KEY_COL1__KPP_COL_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__GPIO4_8 (_MX53_PAD_KEY_COL1__GPIO4_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS (_MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__UART5_TXD_MUX (_MX53_PAD_KEY_COL1__UART5_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__ECSPI1_MISO (_MX53_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__FEC_RX_CLK (_MX53_PAD_KEY_COL1__FEC_RX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL1__USBPHY1_TXREADY (_MX53_PAD_KEY_COL1__USBPHY1_TXREADY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__KPP_ROW_1 (_MX53_PAD_KEY_ROW1__KPP_ROW_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__GPIO4_9 (_MX53_PAD_KEY_ROW1__GPIO4_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD (_MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__UART5_RXD_MUX (_MX53_PAD_KEY_ROW1__UART5_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__ECSPI1_SS0 (_MX53_PAD_KEY_ROW1__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__FEC_COL (_MX53_PAD_KEY_ROW1__FEC_COL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW1__USBPHY1_RXVALID (_MX53_PAD_KEY_ROW1__USBPHY1_RXVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__KPP_COL_2 (_MX53_PAD_KEY_COL2__KPP_COL_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__GPIO4_10 (_MX53_PAD_KEY_COL2__GPIO4_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__CAN1_TXCAN (_MX53_PAD_KEY_COL2__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__FEC_MDIO (_MX53_PAD_KEY_COL2__FEC_MDIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__ECSPI1_SS1 (_MX53_PAD_KEY_COL2__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__FEC_RDATA_2 (_MX53_PAD_KEY_COL2__FEC_RDATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE (_MX53_PAD_KEY_COL2__USBPHY1_RXACTIVE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__KPP_ROW_2 (_MX53_PAD_KEY_ROW2__KPP_ROW_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__GPIO4_11 (_MX53_PAD_KEY_ROW2__GPIO4_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__CAN1_RXCAN (_MX53_PAD_KEY_ROW2__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__FEC_MDC (_MX53_PAD_KEY_ROW2__FEC_MDC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__ECSPI1_SS2 (_MX53_PAD_KEY_ROW2__ECSPI1_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__FEC_TDATA_2 (_MX53_PAD_KEY_ROW2__FEC_TDATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW2__USBPHY1_RXERROR (_MX53_PAD_KEY_ROW2__USBPHY1_RXERROR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__KPP_COL_3 (_MX53_PAD_KEY_COL3__KPP_COL_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__GPIO4_12 (_MX53_PAD_KEY_COL3__GPIO4_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__USBOH3_H2_DP (_MX53_PAD_KEY_COL3__USBOH3_H2_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__SPDIF_IN1 (_MX53_PAD_KEY_COL3__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__I2C2_SCL (_MX53_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_KEY_COL3__ECSPI1_SS3 (_MX53_PAD_KEY_COL3__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__FEC_CRS (_MX53_PAD_KEY_COL3__FEC_CRS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK (_MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__KPP_ROW_3 (_MX53_PAD_KEY_ROW3__KPP_ROW_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__GPIO4_13 (_MX53_PAD_KEY_ROW3__GPIO4_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__USBOH3_H2_DM (_MX53_PAD_KEY_ROW3__USBOH3_H2_DM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK (_MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__I2C2_SDA (_MX53_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_KEY_ROW3__OSC32K_32K_OUT (_MX53_PAD_KEY_ROW3__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__CCM_PLL4_BYP (_MX53_PAD_KEY_ROW3__CCM_PLL4_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 (_MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__KPP_COL_4 (_MX53_PAD_KEY_COL4__KPP_COL_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__GPIO4_14 (_MX53_PAD_KEY_COL4__GPIO4_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__CAN2_TXCAN (_MX53_PAD_KEY_COL4__CAN2_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__IPU_SISG_4 (_MX53_PAD_KEY_COL4__IPU_SISG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__UART5_RTS (_MX53_PAD_KEY_COL4__UART5_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC (_MX53_PAD_KEY_COL4__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 (_MX53_PAD_KEY_COL4__USBPHY1_LINESTATE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__KPP_ROW_4 (_MX53_PAD_KEY_ROW4__KPP_ROW_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__GPIO4_15 (_MX53_PAD_KEY_ROW4__GPIO4_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__CAN2_RXCAN (_MX53_PAD_KEY_ROW4__CAN2_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__IPU_SISG_5 (_MX53_PAD_KEY_ROW4__IPU_SISG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__UART5_CTS (_MX53_PAD_KEY_ROW4__UART5_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR (_MX53_PAD_KEY_ROW4__USBOH3_USBOTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID (_MX53_PAD_KEY_ROW4__USBPHY1_VBUSVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK (_MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__GPIO4_16 (_MX53_PAD_DI0_DISP_CLK__GPIO4_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR (_MX53_PAD_DI0_DISP_CLK__USBOH3_USBH2_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 (_MX53_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 (_MX53_PAD_DI0_DISP_CLK__EMI_EMI_DEBUG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID (_MX53_PAD_DI0_DISP_CLK__USBPHY1_AVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 (_MX53_PAD_DI0_PIN15__IPU_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__GPIO4_17 (_MX53_PAD_DI0_PIN15__GPIO4_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC (_MX53_PAD_DI0_PIN15__AUDMUX_AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 (_MX53_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 (_MX53_PAD_DI0_PIN15__EMI_EMI_DEBUG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN15__USBPHY1_BVALID (_MX53_PAD_DI0_PIN15__USBPHY1_BVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 (_MX53_PAD_DI0_PIN2__IPU_DI0_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__GPIO4_18 (_MX53_PAD_DI0_PIN2__GPIO4_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD (_MX53_PAD_DI0_PIN2__AUDMUX_AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 (_MX53_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 (_MX53_PAD_DI0_PIN2__EMI_EMI_DEBUG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION (_MX53_PAD_DI0_PIN2__USBPHY1_ENDSESSION | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 (_MX53_PAD_DI0_PIN3__IPU_DI0_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__GPIO4_19 (_MX53_PAD_DI0_PIN3__GPIO4_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS (_MX53_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 (_MX53_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 (_MX53_PAD_DI0_PIN3__EMI_EMI_DEBUG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN3__USBPHY1_IDDIG (_MX53_PAD_DI0_PIN3__USBPHY1_IDDIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 (_MX53_PAD_DI0_PIN4__IPU_DI0_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__GPIO4_20 (_MX53_PAD_DI0_PIN4__GPIO4_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD (_MX53_PAD_DI0_PIN4__AUDMUX_AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__ESDHC1_WP (_MX53_PAD_DI0_PIN4__ESDHC1_WP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD (_MX53_PAD_DI0_PIN4__SDMA_DEBUG_YIELD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 (_MX53_PAD_DI0_PIN4__EMI_EMI_DEBUG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT (_MX53_PAD_DI0_PIN4__USBPHY1_HOSTDISCONNECT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 (_MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__GPIO4_21 (_MX53_PAD_DISP0_DAT0__GPIO4_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__CSPI_SCLK (_MX53_PAD_DISP0_DAT0__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 (_MX53_PAD_DISP0_DAT0__USBOH3_USBH2_DATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN (_MX53_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 (_MX53_PAD_DISP0_DAT0__EMI_EMI_DEBUG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY (_MX53_PAD_DISP0_DAT0__USBPHY2_TXREADY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 (_MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__GPIO4_22 (_MX53_PAD_DISP0_DAT1__GPIO4_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__CSPI_MOSI (_MX53_PAD_DISP0_DAT1__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 (_MX53_PAD_DISP0_DAT1__USBOH3_USBH2_DATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL (_MX53_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 (_MX53_PAD_DISP0_DAT1__EMI_EMI_DEBUG_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID (_MX53_PAD_DISP0_DAT1__USBPHY2_RXVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 (_MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__GPIO4_23 (_MX53_PAD_DISP0_DAT2__GPIO4_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__CSPI_MISO (_MX53_PAD_DISP0_DAT2__CSPI_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 (_MX53_PAD_DISP0_DAT2__USBOH3_USBH2_DATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE (_MX53_PAD_DISP0_DAT2__SDMA_DEBUG_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 (_MX53_PAD_DISP0_DAT2__EMI_EMI_DEBUG_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE (_MX53_PAD_DISP0_DAT2__USBPHY2_RXACTIVE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 (_MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__GPIO4_24 (_MX53_PAD_DISP0_DAT3__GPIO4_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__CSPI_SS0 (_MX53_PAD_DISP0_DAT3__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 (_MX53_PAD_DISP0_DAT3__USBOH3_USBH2_DATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR (_MX53_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 (_MX53_PAD_DISP0_DAT3__EMI_EMI_DEBUG_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR (_MX53_PAD_DISP0_DAT3__USBPHY2_RXERROR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 (_MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__GPIO4_25 (_MX53_PAD_DISP0_DAT4__GPIO4_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__CSPI_SS1 (_MX53_PAD_DISP0_DAT4__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 (_MX53_PAD_DISP0_DAT4__USBOH3_USBH2_DATA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB (_MX53_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 (_MX53_PAD_DISP0_DAT4__EMI_EMI_DEBUG_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK (_MX53_PAD_DISP0_DAT4__USBPHY2_SIECLOCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 (_MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__GPIO4_26 (_MX53_PAD_DISP0_DAT5__GPIO4_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__CSPI_SS2 (_MX53_PAD_DISP0_DAT5__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 (_MX53_PAD_DISP0_DAT5__USBOH3_USBH2_DATA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS (_MX53_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 (_MX53_PAD_DISP0_DAT5__EMI_EMI_DEBUG_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 (_MX53_PAD_DISP0_DAT5__USBPHY2_LINESTATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 (_MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__GPIO4_27 (_MX53_PAD_DISP0_DAT6__GPIO4_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__CSPI_SS3 (_MX53_PAD_DISP0_DAT6__CSPI_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 (_MX53_PAD_DISP0_DAT6__USBOH3_USBH2_DATA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE (_MX53_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 (_MX53_PAD_DISP0_DAT6__EMI_EMI_DEBUG_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 (_MX53_PAD_DISP0_DAT6__USBPHY2_LINESTATE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 (_MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__GPIO4_28 (_MX53_PAD_DISP0_DAT7__GPIO4_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__CSPI_RDY (_MX53_PAD_DISP0_DAT7__CSPI_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 (_MX53_PAD_DISP0_DAT7__USBOH3_USBH2_DATA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 (_MX53_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 (_MX53_PAD_DISP0_DAT7__EMI_EMI_DEBUG_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID (_MX53_PAD_DISP0_DAT7__USBPHY2_VBUSVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 (_MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__GPIO4_29 (_MX53_PAD_DISP0_DAT8__GPIO4_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__PWM1_PWMO (_MX53_PAD_DISP0_DAT8__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B (_MX53_PAD_DISP0_DAT8__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 (_MX53_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 (_MX53_PAD_DISP0_DAT8__EMI_EMI_DEBUG_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT8__USBPHY2_AVALID (_MX53_PAD_DISP0_DAT8__USBPHY2_AVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 (_MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__GPIO4_30 (_MX53_PAD_DISP0_DAT9__GPIO4_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__PWM2_PWMO (_MX53_PAD_DISP0_DAT9__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B (_MX53_PAD_DISP0_DAT9__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 (_MX53_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 (_MX53_PAD_DISP0_DAT9__EMI_EMI_DEBUG_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 (_MX53_PAD_DISP0_DAT9__USBPHY2_VSTATUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 (_MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__GPIO4_31 (_MX53_PAD_DISP0_DAT10__GPIO4_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP (_MX53_PAD_DISP0_DAT10__USBOH3_USBH2_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 (_MX53_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 (_MX53_PAD_DISP0_DAT10__EMI_EMI_DEBUG_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 (_MX53_PAD_DISP0_DAT10__USBPHY2_VSTATUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 (_MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__GPIO5_5 (_MX53_PAD_DISP0_DAT11__GPIO5_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT (_MX53_PAD_DISP0_DAT11__USBOH3_USBH2_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 (_MX53_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 (_MX53_PAD_DISP0_DAT11__EMI_EMI_DEBUG_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 (_MX53_PAD_DISP0_DAT11__USBPHY2_VSTATUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 (_MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__GPIO5_6 (_MX53_PAD_DISP0_DAT12__GPIO5_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK (_MX53_PAD_DISP0_DAT12__USBOH3_USBH2_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 (_MX53_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 (_MX53_PAD_DISP0_DAT12__EMI_EMI_DEBUG_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 (_MX53_PAD_DISP0_DAT12__USBPHY2_VSTATUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 (_MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__GPIO5_7 (_MX53_PAD_DISP0_DAT13__GPIO5_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS (_MX53_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 (_MX53_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 (_MX53_PAD_DISP0_DAT13__EMI_EMI_DEBUG_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 (_MX53_PAD_DISP0_DAT13__USBPHY2_VSTATUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 (_MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__GPIO5_8 (_MX53_PAD_DISP0_DAT14__GPIO5_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC (_MX53_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 (_MX53_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 (_MX53_PAD_DISP0_DAT14__EMI_EMI_DEBUG_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 (_MX53_PAD_DISP0_DAT14__USBPHY2_VSTATUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 (_MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__GPIO5_9 (_MX53_PAD_DISP0_DAT15__GPIO5_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__ECSPI1_SS1 (_MX53_PAD_DISP0_DAT15__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__ECSPI2_SS1 (_MX53_PAD_DISP0_DAT15__ECSPI2_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 (_MX53_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 (_MX53_PAD_DISP0_DAT15__EMI_EMI_DEBUG_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 (_MX53_PAD_DISP0_DAT15__USBPHY2_VSTATUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 (_MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__GPIO5_10 (_MX53_PAD_DISP0_DAT16__GPIO5_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__ECSPI2_MOSI (_MX53_PAD_DISP0_DAT16__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC (_MX53_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 (_MX53_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 (_MX53_PAD_DISP0_DAT16__SDMA_DEBUG_EVT_CHN_LINES_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 (_MX53_PAD_DISP0_DAT16__EMI_EMI_DEBUG_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 (_MX53_PAD_DISP0_DAT16__USBPHY2_VSTATUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 (_MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__GPIO5_11 (_MX53_PAD_DISP0_DAT17__GPIO5_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__ECSPI2_MISO (_MX53_PAD_DISP0_DAT17__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD (_MX53_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 (_MX53_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 (_MX53_PAD_DISP0_DAT17__SDMA_DEBUG_EVT_CHN_LINES_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 (_MX53_PAD_DISP0_DAT17__EMI_EMI_DEBUG_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 (_MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__GPIO5_12 (_MX53_PAD_DISP0_DAT18__GPIO5_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__ECSPI2_SS0 (_MX53_PAD_DISP0_DAT18__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS (_MX53_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS (_MX53_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 (_MX53_PAD_DISP0_DAT18__SDMA_DEBUG_EVT_CHN_LINES_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 (_MX53_PAD_DISP0_DAT18__EMI_EMI_DEBUG_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 (_MX53_PAD_DISP0_DAT18__EMI_WEIM_CS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 (_MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__GPIO5_13 (_MX53_PAD_DISP0_DAT19__GPIO5_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__ECSPI2_SCLK (_MX53_PAD_DISP0_DAT19__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD (_MX53_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC (_MX53_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 (_MX53_PAD_DISP0_DAT19__SDMA_DEBUG_EVT_CHN_LINES_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 (_MX53_PAD_DISP0_DAT19__EMI_EMI_DEBUG_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 (_MX53_PAD_DISP0_DAT19__EMI_WEIM_CS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 (_MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__GPIO5_14 (_MX53_PAD_DISP0_DAT20__GPIO5_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__ECSPI1_SCLK (_MX53_PAD_DISP0_DAT20__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC (_MX53_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 (_MX53_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 (_MX53_PAD_DISP0_DAT20__EMI_EMI_DEBUG_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT20__SATA_PHY_TDI (_MX53_PAD_DISP0_DAT20__SATA_PHY_TDI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 (_MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__GPIO5_15 (_MX53_PAD_DISP0_DAT21__GPIO5_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__ECSPI1_MOSI (_MX53_PAD_DISP0_DAT21__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD (_MX53_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 (_MX53_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 (_MX53_PAD_DISP0_DAT21__EMI_EMI_DEBUG_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT21__SATA_PHY_TDO (_MX53_PAD_DISP0_DAT21__SATA_PHY_TDO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 (_MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__GPIO5_16 (_MX53_PAD_DISP0_DAT22__GPIO5_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__ECSPI1_MISO (_MX53_PAD_DISP0_DAT22__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS (_MX53_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 (_MX53_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 (_MX53_PAD_DISP0_DAT22__EMI_EMI_DEBUG_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT22__SATA_PHY_TCK (_MX53_PAD_DISP0_DAT22__SATA_PHY_TCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 (_MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__GPIO5_17 (_MX53_PAD_DISP0_DAT23__GPIO5_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__ECSPI1_SS0 (_MX53_PAD_DISP0_DAT23__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD (_MX53_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 (_MX53_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 (_MX53_PAD_DISP0_DAT23__EMI_EMI_DEBUG_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_DISP0_DAT23__SATA_PHY_TMS (_MX53_PAD_DISP0_DAT23__SATA_PHY_TMS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK (_MX53_PAD_CSI0_PIXCLK__IPU_CSI0_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_PIXCLK__GPIO5_18 (_MX53_PAD_CSI0_PIXCLK__GPIO5_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 (_MX53_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 (_MX53_PAD_CSI0_PIXCLK__EMI_EMI_DEBUG_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC (_MX53_PAD_CSI0_MCLK__IPU_CSI0_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__GPIO5_19 (_MX53_PAD_CSI0_MCLK__GPIO5_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK (_MX53_PAD_CSI0_MCLK__CCM_CSI0_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 (_MX53_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 (_MX53_PAD_CSI0_MCLK__EMI_EMI_DEBUG_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_MCLK__TPIU_TRCTL (_MX53_PAD_CSI0_MCLK__TPIU_TRCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN (_MX53_PAD_CSI0_DATA_EN__IPU_CSI0_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DATA_EN__GPIO5_20 (_MX53_PAD_CSI0_DATA_EN__GPIO5_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 (_MX53_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 (_MX53_PAD_CSI0_DATA_EN__EMI_EMI_DEBUG_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK (_MX53_PAD_CSI0_DATA_EN__TPIU_TRCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC (_MX53_PAD_CSI0_VSYNC__IPU_CSI0_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_VSYNC__GPIO5_21 (_MX53_PAD_CSI0_VSYNC__GPIO5_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 (_MX53_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 (_MX53_PAD_CSI0_VSYNC__EMI_EMI_DEBUG_32 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 (_MX53_PAD_CSI0_VSYNC__TPIU_TRACE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 (_MX53_PAD_CSI0_DAT4__IPU_CSI0_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__GPIO5_22 (_MX53_PAD_CSI0_DAT4__GPIO5_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__KPP_COL_5 (_MX53_PAD_CSI0_DAT4__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__ECSPI1_SCLK (_MX53_PAD_CSI0_DAT4__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP (_MX53_PAD_CSI0_DAT4__USBOH3_USBH3_STP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC (_MX53_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 (_MX53_PAD_CSI0_DAT4__EMI_EMI_DEBUG_33 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 (_MX53_PAD_CSI0_DAT4__TPIU_TRACE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 (_MX53_PAD_CSI0_DAT5__IPU_CSI0_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__GPIO5_23 (_MX53_PAD_CSI0_DAT5__GPIO5_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__KPP_ROW_5 (_MX53_PAD_CSI0_DAT5__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__ECSPI1_MOSI (_MX53_PAD_CSI0_DAT5__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT (_MX53_PAD_CSI0_DAT5__USBOH3_USBH3_NXT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD (_MX53_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 (_MX53_PAD_CSI0_DAT5__EMI_EMI_DEBUG_34 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 (_MX53_PAD_CSI0_DAT5__TPIU_TRACE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 (_MX53_PAD_CSI0_DAT6__IPU_CSI0_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__GPIO5_24 (_MX53_PAD_CSI0_DAT6__GPIO5_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__KPP_COL_6 (_MX53_PAD_CSI0_DAT6__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__ECSPI1_MISO (_MX53_PAD_CSI0_DAT6__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK (_MX53_PAD_CSI0_DAT6__USBOH3_USBH3_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS (_MX53_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 (_MX53_PAD_CSI0_DAT6__EMI_EMI_DEBUG_35 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 (_MX53_PAD_CSI0_DAT6__TPIU_TRACE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 (_MX53_PAD_CSI0_DAT7__IPU_CSI0_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__GPIO5_25 (_MX53_PAD_CSI0_DAT7__GPIO5_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__KPP_ROW_6 (_MX53_PAD_CSI0_DAT7__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__ECSPI1_SS0 (_MX53_PAD_CSI0_DAT7__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR (_MX53_PAD_CSI0_DAT7__USBOH3_USBH3_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD (_MX53_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 (_MX53_PAD_CSI0_DAT7__EMI_EMI_DEBUG_36 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 (_MX53_PAD_CSI0_DAT7__TPIU_TRACE_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 (_MX53_PAD_CSI0_DAT8__IPU_CSI0_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__GPIO5_26 (_MX53_PAD_CSI0_DAT8__GPIO5_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__KPP_COL_7 (_MX53_PAD_CSI0_DAT8__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__ECSPI2_SCLK (_MX53_PAD_CSI0_DAT8__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC (_MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__I2C1_SDA (_MX53_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 (_MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 (_MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 (_MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__GPIO5_27 (_MX53_PAD_CSI0_DAT9__GPIO5_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__KPP_ROW_7 (_MX53_PAD_CSI0_DAT9__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__ECSPI2_MOSI (_MX53_PAD_CSI0_DAT9__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR (_MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__I2C1_SCL (_MX53_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 (_MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 (_MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 (_MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__GPIO5_28 (_MX53_PAD_CSI0_DAT10__GPIO5_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__UART1_TXD_MUX (_MX53_PAD_CSI0_DAT10__UART1_TXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__ECSPI2_MISO (_MX53_PAD_CSI0_DAT10__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC (_MX53_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 (_MX53_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 (_MX53_PAD_CSI0_DAT10__EMI_EMI_DEBUG_39 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 (_MX53_PAD_CSI0_DAT10__TPIU_TRACE_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 (_MX53_PAD_CSI0_DAT11__IPU_CSI0_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__GPIO5_29 (_MX53_PAD_CSI0_DAT11__GPIO5_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__UART1_RXD_MUX (_MX53_PAD_CSI0_DAT11__UART1_RXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__ECSPI2_SS0 (_MX53_PAD_CSI0_DAT11__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS (_MX53_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 (_MX53_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 (_MX53_PAD_CSI0_DAT11__EMI_EMI_DEBUG_40 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 (_MX53_PAD_CSI0_DAT11__TPIU_TRACE_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 (_MX53_PAD_CSI0_DAT12__IPU_CSI0_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__GPIO5_30 (_MX53_PAD_CSI0_DAT12__GPIO5_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__UART4_TXD_MUX (_MX53_PAD_CSI0_DAT12__UART4_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 (_MX53_PAD_CSI0_DAT12__USBOH3_USBH3_DATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 (_MX53_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 (_MX53_PAD_CSI0_DAT12__EMI_EMI_DEBUG_41 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 (_MX53_PAD_CSI0_DAT12__TPIU_TRACE_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 (_MX53_PAD_CSI0_DAT13__IPU_CSI0_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__GPIO5_31 (_MX53_PAD_CSI0_DAT13__GPIO5_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__UART4_RXD_MUX (_MX53_PAD_CSI0_DAT13__UART4_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 (_MX53_PAD_CSI0_DAT13__USBOH3_USBH3_DATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 (_MX53_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 (_MX53_PAD_CSI0_DAT13__EMI_EMI_DEBUG_42 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 (_MX53_PAD_CSI0_DAT13__TPIU_TRACE_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 (_MX53_PAD_CSI0_DAT14__IPU_CSI0_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__GPIO6_0 (_MX53_PAD_CSI0_DAT14__GPIO6_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__UART5_TXD_MUX (_MX53_PAD_CSI0_DAT14__UART5_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 (_MX53_PAD_CSI0_DAT14__USBOH3_USBH3_DATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 (_MX53_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 (_MX53_PAD_CSI0_DAT14__EMI_EMI_DEBUG_43 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 (_MX53_PAD_CSI0_DAT14__TPIU_TRACE_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 (_MX53_PAD_CSI0_DAT15__IPU_CSI0_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__GPIO6_1 (_MX53_PAD_CSI0_DAT15__GPIO6_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__UART5_RXD_MUX (_MX53_PAD_CSI0_DAT15__UART5_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 (_MX53_PAD_CSI0_DAT15__USBOH3_USBH3_DATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 (_MX53_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 (_MX53_PAD_CSI0_DAT15__EMI_EMI_DEBUG_44 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 (_MX53_PAD_CSI0_DAT15__TPIU_TRACE_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 (_MX53_PAD_CSI0_DAT16__IPU_CSI0_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__GPIO6_2 (_MX53_PAD_CSI0_DAT16__GPIO6_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__UART4_RTS (_MX53_PAD_CSI0_DAT16__UART4_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 (_MX53_PAD_CSI0_DAT16__USBOH3_USBH3_DATA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 (_MX53_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 (_MX53_PAD_CSI0_DAT16__EMI_EMI_DEBUG_45 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 (_MX53_PAD_CSI0_DAT16__TPIU_TRACE_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 (_MX53_PAD_CSI0_DAT17__IPU_CSI0_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__GPIO6_3 (_MX53_PAD_CSI0_DAT17__GPIO6_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__UART4_CTS (_MX53_PAD_CSI0_DAT17__UART4_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 (_MX53_PAD_CSI0_DAT17__USBOH3_USBH3_DATA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 (_MX53_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 (_MX53_PAD_CSI0_DAT17__EMI_EMI_DEBUG_46 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 (_MX53_PAD_CSI0_DAT17__TPIU_TRACE_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 (_MX53_PAD_CSI0_DAT18__IPU_CSI0_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__GPIO6_4 (_MX53_PAD_CSI0_DAT18__GPIO6_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__UART5_RTS (_MX53_PAD_CSI0_DAT18__UART5_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 (_MX53_PAD_CSI0_DAT18__USBOH3_USBH3_DATA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 (_MX53_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 (_MX53_PAD_CSI0_DAT18__EMI_EMI_DEBUG_47 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 (_MX53_PAD_CSI0_DAT18__TPIU_TRACE_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 (_MX53_PAD_CSI0_DAT19__IPU_CSI0_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__GPIO6_5 (_MX53_PAD_CSI0_DAT19__GPIO6_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__UART5_CTS (_MX53_PAD_CSI0_DAT19__UART5_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 (_MX53_PAD_CSI0_DAT19__USBOH3_USBH3_DATA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 (_MX53_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 (_MX53_PAD_CSI0_DAT19__EMI_EMI_DEBUG_48 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK (_MX53_PAD_CSI0_DAT19__USBPHY2_BISTOK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__EMI_WEIM_A_25 (_MX53_PAD_EIM_A25__EMI_WEIM_A_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__GPIO5_2 (_MX53_PAD_EIM_A25__GPIO5_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__ECSPI2_RDY (_MX53_PAD_EIM_A25__ECSPI2_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__IPU_DI1_PIN12 (_MX53_PAD_EIM_A25__IPU_DI1_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__CSPI_SS1 (_MX53_PAD_EIM_A25__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__IPU_DI0_D1_CS (_MX53_PAD_EIM_A25__IPU_DI0_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A25__USBPHY1_BISTOK (_MX53_PAD_EIM_A25__USBPHY1_BISTOK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 (_MX53_PAD_EIM_EB2__EMI_WEIM_EB_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__GPIO2_30 (_MX53_PAD_EIM_EB2__GPIO2_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK (_MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS (_MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__ECSPI1_SS0 (_MX53_PAD_EIM_EB2__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB2__I2C2_SCL (_MX53_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D16__EMI_WEIM_D_16 (_MX53_PAD_EIM_D16__EMI_WEIM_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D16__GPIO3_16 (_MX53_PAD_EIM_D16__GPIO3_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D16__IPU_DI0_PIN5 (_MX53_PAD_EIM_D16__IPU_DI0_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK (_MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D16__ECSPI1_SCLK (_MX53_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D16__I2C2_SDA (_MX53_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D17__EMI_WEIM_D_17 (_MX53_PAD_EIM_D17__EMI_WEIM_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D17__GPIO3_17 (_MX53_PAD_EIM_D17__GPIO3_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D17__IPU_DI0_PIN6 (_MX53_PAD_EIM_D17__IPU_DI0_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN (_MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D17__ECSPI1_MISO (_MX53_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D17__I2C3_SCL (_MX53_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D18__EMI_WEIM_D_18 (_MX53_PAD_EIM_D18__EMI_WEIM_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D18__GPIO3_18 (_MX53_PAD_EIM_D18__GPIO3_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D18__IPU_DI0_PIN7 (_MX53_PAD_EIM_D18__IPU_DI0_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO (_MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D18__ECSPI1_MOSI (_MX53_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D18__I2C3_SDA (_MX53_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D18__IPU_DI1_D0_CS (_MX53_PAD_EIM_D18__IPU_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__EMI_WEIM_D_19 (_MX53_PAD_EIM_D19__EMI_WEIM_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__GPIO3_19 (_MX53_PAD_EIM_D19__GPIO3_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__IPU_DI0_PIN8 (_MX53_PAD_EIM_D19__IPU_DI0_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS (_MX53_PAD_EIM_D19__IPU_DISPB1_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__ECSPI1_SS1 (_MX53_PAD_EIM_D19__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__EPIT1_EPITO (_MX53_PAD_EIM_D19__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__UART1_CTS (_MX53_PAD_EIM_D19__UART1_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D19__USBOH3_USBH2_OC (_MX53_PAD_EIM_D19__USBOH3_USBH2_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__EMI_WEIM_D_20 (_MX53_PAD_EIM_D20__EMI_WEIM_D_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__GPIO3_20 (_MX53_PAD_EIM_D20__GPIO3_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__IPU_DI0_PIN16 (_MX53_PAD_EIM_D20__IPU_DI0_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__IPU_SER_DISP0_CS (_MX53_PAD_EIM_D20__IPU_SER_DISP0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__CSPI_SS0 (_MX53_PAD_EIM_D20__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__EPIT2_EPITO (_MX53_PAD_EIM_D20__EPIT2_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__UART1_RTS (_MX53_PAD_EIM_D20__UART1_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D20__USBOH3_USBH2_PWR (_MX53_PAD_EIM_D20__USBOH3_USBH2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__EMI_WEIM_D_21 (_MX53_PAD_EIM_D21__EMI_WEIM_D_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__GPIO3_21 (_MX53_PAD_EIM_D21__GPIO3_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__IPU_DI0_PIN17 (_MX53_PAD_EIM_D21__IPU_DI0_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK (_MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__CSPI_SCLK (_MX53_PAD_EIM_D21__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D21__I2C1_SCL (_MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D21__USBOH3_USBOTG_OC (_MX53_PAD_EIM_D21__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__EMI_WEIM_D_22 (_MX53_PAD_EIM_D22__EMI_WEIM_D_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__GPIO3_22 (_MX53_PAD_EIM_D22__GPIO3_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__IPU_DI0_PIN1 (_MX53_PAD_EIM_D22__IPU_DI0_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN (_MX53_PAD_EIM_D22__IPU_DISPB0_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__CSPI_MISO (_MX53_PAD_EIM_D22__CSPI_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR (_MX53_PAD_EIM_D22__USBOH3_USBOTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__EMI_WEIM_D_23 (_MX53_PAD_EIM_D23__EMI_WEIM_D_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__GPIO3_23 (_MX53_PAD_EIM_D23__GPIO3_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__UART3_CTS (_MX53_PAD_EIM_D23__UART3_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__UART1_DCD (_MX53_PAD_EIM_D23__UART1_DCD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__IPU_DI0_D0_CS (_MX53_PAD_EIM_D23__IPU_DI0_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__IPU_DI1_PIN2 (_MX53_PAD_EIM_D23__IPU_DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN (_MX53_PAD_EIM_D23__IPU_CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D23__IPU_DI1_PIN14 (_MX53_PAD_EIM_D23__IPU_DI1_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 (_MX53_PAD_EIM_EB3__EMI_WEIM_EB_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__GPIO2_31 (_MX53_PAD_EIM_EB3__GPIO2_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__UART3_RTS (_MX53_PAD_EIM_EB3__UART3_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__UART1_RI (_MX53_PAD_EIM_EB3__UART1_RI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__IPU_DI1_PIN3 (_MX53_PAD_EIM_EB3__IPU_DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC (_MX53_PAD_EIM_EB3__IPU_CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB3__IPU_DI1_PIN16 (_MX53_PAD_EIM_EB3__IPU_DI1_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__EMI_WEIM_D_24 (_MX53_PAD_EIM_D24__EMI_WEIM_D_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__GPIO3_24 (_MX53_PAD_EIM_D24__GPIO3_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__UART3_TXD_MUX (_MX53_PAD_EIM_D24__UART3_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__ECSPI1_SS2 (_MX53_PAD_EIM_D24__ECSPI1_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__CSPI_SS2 (_MX53_PAD_EIM_D24__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS (_MX53_PAD_EIM_D24__AUDMUX_AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__ECSPI2_SS2 (_MX53_PAD_EIM_D24__ECSPI2_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D24__UART1_DTR (_MX53_PAD_EIM_D24__UART1_DTR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__EMI_WEIM_D_25 (_MX53_PAD_EIM_D25__EMI_WEIM_D_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__GPIO3_25 (_MX53_PAD_EIM_D25__GPIO3_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__UART3_RXD_MUX (_MX53_PAD_EIM_D25__UART3_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__ECSPI1_SS3 (_MX53_PAD_EIM_D25__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__CSPI_SS3 (_MX53_PAD_EIM_D25__CSPI_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC (_MX53_PAD_EIM_D25__AUDMUX_AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__ECSPI2_SS3 (_MX53_PAD_EIM_D25__ECSPI2_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D25__UART1_DSR (_MX53_PAD_EIM_D25__UART1_DSR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__EMI_WEIM_D_26 (_MX53_PAD_EIM_D26__EMI_WEIM_D_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__GPIO3_26 (_MX53_PAD_EIM_D26__GPIO3_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__UART2_TXD_MUX (_MX53_PAD_EIM_D26__UART2_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__FIRI_RXD (_MX53_PAD_EIM_D26__FIRI_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__IPU_CSI0_D_1 (_MX53_PAD_EIM_D26__IPU_CSI0_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__IPU_DI1_PIN11 (_MX53_PAD_EIM_D26__IPU_DI1_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__IPU_SISG_2 (_MX53_PAD_EIM_D26__IPU_SISG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 (_MX53_PAD_EIM_D26__IPU_DISP1_DAT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__EMI_WEIM_D_27 (_MX53_PAD_EIM_D27__EMI_WEIM_D_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__GPIO3_27 (_MX53_PAD_EIM_D27__GPIO3_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__UART2_RXD_MUX (_MX53_PAD_EIM_D27__UART2_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__FIRI_TXD (_MX53_PAD_EIM_D27__FIRI_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__IPU_CSI0_D_0 (_MX53_PAD_EIM_D27__IPU_CSI0_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__IPU_DI1_PIN13 (_MX53_PAD_EIM_D27__IPU_DI1_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__IPU_SISG_3 (_MX53_PAD_EIM_D27__IPU_SISG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 (_MX53_PAD_EIM_D27__IPU_DISP1_DAT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__EMI_WEIM_D_28 (_MX53_PAD_EIM_D28__EMI_WEIM_D_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__GPIO3_28 (_MX53_PAD_EIM_D28__GPIO3_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__UART2_CTS (_MX53_PAD_EIM_D28__UART2_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO (_MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__CSPI_MOSI (_MX53_PAD_EIM_D28__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__I2C1_SDA (_MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_EIM_D28__IPU_EXT_TRIG (_MX53_PAD_EIM_D28__IPU_EXT_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D28__IPU_DI0_PIN13 (_MX53_PAD_EIM_D28__IPU_DI0_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__EMI_WEIM_D_29 (_MX53_PAD_EIM_D29__EMI_WEIM_D_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__GPIO3_29 (_MX53_PAD_EIM_D29__GPIO3_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__UART2_RTS (_MX53_PAD_EIM_D29__UART2_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS (_MX53_PAD_EIM_D29__IPU_DISPB0_SER_RS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__CSPI_SS0 (_MX53_PAD_EIM_D29__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__IPU_DI1_PIN15 (_MX53_PAD_EIM_D29__IPU_DI1_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__IPU_CSI1_VSYNC (_MX53_PAD_EIM_D29__IPU_CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D29__IPU_DI0_PIN14 (_MX53_PAD_EIM_D29__IPU_DI0_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__EMI_WEIM_D_30 (_MX53_PAD_EIM_D30__EMI_WEIM_D_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__GPIO3_30 (_MX53_PAD_EIM_D30__GPIO3_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__UART3_CTS (_MX53_PAD_EIM_D30__UART3_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__IPU_CSI0_D_3 (_MX53_PAD_EIM_D30__IPU_CSI0_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__IPU_DI0_PIN11 (_MX53_PAD_EIM_D30__IPU_DI0_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 (_MX53_PAD_EIM_D30__IPU_DISP1_DAT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__USBOH3_USBH1_OC (_MX53_PAD_EIM_D30__USBOH3_USBH1_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D30__USBOH3_USBH2_OC (_MX53_PAD_EIM_D30__USBOH3_USBH2_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__EMI_WEIM_D_31 (_MX53_PAD_EIM_D31__EMI_WEIM_D_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__GPIO3_31 (_MX53_PAD_EIM_D31__GPIO3_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__UART3_RTS (_MX53_PAD_EIM_D31__UART3_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__IPU_CSI0_D_2 (_MX53_PAD_EIM_D31__IPU_CSI0_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__IPU_DI0_PIN12 (_MX53_PAD_EIM_D31__IPU_DI0_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 (_MX53_PAD_EIM_D31__IPU_DISP1_DAT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__USBOH3_USBH1_PWR (_MX53_PAD_EIM_D31__USBOH3_USBH1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_D31__USBOH3_USBH2_PWR (_MX53_PAD_EIM_D31__USBOH3_USBH2_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__EMI_WEIM_A_24 (_MX53_PAD_EIM_A24__EMI_WEIM_A_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__GPIO5_4 (_MX53_PAD_EIM_A24__GPIO5_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 (_MX53_PAD_EIM_A24__IPU_DISP1_DAT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__IPU_CSI1_D_19 (_MX53_PAD_EIM_A24__IPU_CSI1_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__IPU_SISG_2 (_MX53_PAD_EIM_A24__IPU_SISG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A24__USBPHY2_BVALID (_MX53_PAD_EIM_A24__USBPHY2_BVALID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__EMI_WEIM_A_23 (_MX53_PAD_EIM_A23__EMI_WEIM_A_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__GPIO6_6 (_MX53_PAD_EIM_A23__GPIO6_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 (_MX53_PAD_EIM_A23__IPU_DISP1_DAT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__IPU_CSI1_D_18 (_MX53_PAD_EIM_A23__IPU_CSI1_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__IPU_SISG_3 (_MX53_PAD_EIM_A23__IPU_SISG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A23__USBPHY2_ENDSESSION (_MX53_PAD_EIM_A23__USBPHY2_ENDSESSION | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A22__EMI_WEIM_A_22 (_MX53_PAD_EIM_A22__EMI_WEIM_A_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A22__GPIO2_16 (_MX53_PAD_EIM_A22__GPIO2_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 (_MX53_PAD_EIM_A22__IPU_DISP1_DAT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A22__IPU_CSI1_D_17 (_MX53_PAD_EIM_A22__IPU_CSI1_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A22__SRC_BT_CFG1_7 (_MX53_PAD_EIM_A22__SRC_BT_CFG1_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A21__EMI_WEIM_A_21 (_MX53_PAD_EIM_A21__EMI_WEIM_A_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A21__GPIO2_17 (_MX53_PAD_EIM_A21__GPIO2_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 (_MX53_PAD_EIM_A21__IPU_DISP1_DAT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A21__IPU_CSI1_D_16 (_MX53_PAD_EIM_A21__IPU_CSI1_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A21__SRC_BT_CFG1_6 (_MX53_PAD_EIM_A21__SRC_BT_CFG1_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A20__EMI_WEIM_A_20 (_MX53_PAD_EIM_A20__EMI_WEIM_A_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A20__GPIO2_18 (_MX53_PAD_EIM_A20__GPIO2_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 (_MX53_PAD_EIM_A20__IPU_DISP1_DAT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A20__IPU_CSI1_D_15 (_MX53_PAD_EIM_A20__IPU_CSI1_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A20__SRC_BT_CFG1_5 (_MX53_PAD_EIM_A20__SRC_BT_CFG1_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A19__EMI_WEIM_A_19 (_MX53_PAD_EIM_A19__EMI_WEIM_A_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A19__GPIO2_19 (_MX53_PAD_EIM_A19__GPIO2_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 (_MX53_PAD_EIM_A19__IPU_DISP1_DAT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A19__IPU_CSI1_D_14 (_MX53_PAD_EIM_A19__IPU_CSI1_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A19__SRC_BT_CFG1_4 (_MX53_PAD_EIM_A19__SRC_BT_CFG1_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A18__EMI_WEIM_A_18 (_MX53_PAD_EIM_A18__EMI_WEIM_A_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A18__GPIO2_20 (_MX53_PAD_EIM_A18__GPIO2_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 (_MX53_PAD_EIM_A18__IPU_DISP1_DAT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A18__IPU_CSI1_D_13 (_MX53_PAD_EIM_A18__IPU_CSI1_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A18__SRC_BT_CFG1_3 (_MX53_PAD_EIM_A18__SRC_BT_CFG1_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A17__EMI_WEIM_A_17 (_MX53_PAD_EIM_A17__EMI_WEIM_A_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A17__GPIO2_21 (_MX53_PAD_EIM_A17__GPIO2_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 (_MX53_PAD_EIM_A17__IPU_DISP1_DAT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A17__IPU_CSI1_D_12 (_MX53_PAD_EIM_A17__IPU_CSI1_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A17__SRC_BT_CFG1_2 (_MX53_PAD_EIM_A17__SRC_BT_CFG1_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A16__EMI_WEIM_A_16 (_MX53_PAD_EIM_A16__EMI_WEIM_A_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A16__GPIO2_22 (_MX53_PAD_EIM_A16__GPIO2_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK (_MX53_PAD_EIM_A16__IPU_DI1_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK (_MX53_PAD_EIM_A16__IPU_CSI1_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_A16__SRC_BT_CFG1_1 (_MX53_PAD_EIM_A16__SRC_BT_CFG1_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 (_MX53_PAD_EIM_CS0__EMI_WEIM_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS0__GPIO2_23 (_MX53_PAD_EIM_CS0__GPIO2_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS0__ECSPI2_SCLK (_MX53_PAD_EIM_CS0__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS0__IPU_DI1_PIN5 (_MX53_PAD_EIM_CS0__IPU_DI1_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 (_MX53_PAD_EIM_CS1__EMI_WEIM_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS1__GPIO2_24 (_MX53_PAD_EIM_CS1__GPIO2_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS1__ECSPI2_MOSI (_MX53_PAD_EIM_CS1__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_CS1__IPU_DI1_PIN6 (_MX53_PAD_EIM_CS1__IPU_DI1_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_OE__EMI_WEIM_OE (_MX53_PAD_EIM_OE__EMI_WEIM_OE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_OE__GPIO2_25 (_MX53_PAD_EIM_OE__GPIO2_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_OE__ECSPI2_MISO (_MX53_PAD_EIM_OE__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_OE__IPU_DI1_PIN7 (_MX53_PAD_EIM_OE__IPU_DI1_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_OE__USBPHY2_IDDIG (_MX53_PAD_EIM_OE__USBPHY2_IDDIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_RW__EMI_WEIM_RW (_MX53_PAD_EIM_RW__EMI_WEIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_RW__GPIO2_26 (_MX53_PAD_EIM_RW__GPIO2_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_RW__ECSPI2_SS0 (_MX53_PAD_EIM_RW__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_RW__IPU_DI1_PIN8 (_MX53_PAD_EIM_RW__IPU_DI1_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT (_MX53_PAD_EIM_RW__USBPHY2_HOSTDISCONNECT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_LBA__EMI_WEIM_LBA (_MX53_PAD_EIM_LBA__EMI_WEIM_LBA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_LBA__GPIO2_27 (_MX53_PAD_EIM_LBA__GPIO2_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_LBA__ECSPI2_SS1 (_MX53_PAD_EIM_LBA__ECSPI2_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_LBA__IPU_DI1_PIN17 (_MX53_PAD_EIM_LBA__IPU_DI1_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 (_MX53_PAD_EIM_LBA__SRC_BT_CFG1_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 (_MX53_PAD_EIM_EB0__EMI_WEIM_EB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__GPIO2_28 (_MX53_PAD_EIM_EB0__GPIO2_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 (_MX53_PAD_EIM_EB0__IPU_DISP1_DAT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__IPU_CSI1_D_11 (_MX53_PAD_EIM_EB0__IPU_CSI1_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__GPC_PMIC_RDY (_MX53_PAD_EIM_EB0__GPC_PMIC_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 (_MX53_PAD_EIM_EB0__SRC_BT_CFG2_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 (_MX53_PAD_EIM_EB1__EMI_WEIM_EB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB1__GPIO2_29 (_MX53_PAD_EIM_EB1__GPIO2_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 (_MX53_PAD_EIM_EB1__IPU_DISP1_DAT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB1__IPU_CSI1_D_10 (_MX53_PAD_EIM_EB1__IPU_CSI1_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 (_MX53_PAD_EIM_EB1__SRC_BT_CFG2_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 (_MX53_PAD_EIM_DA0__EMI_NAND_WEIM_DA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA0__GPIO3_0 (_MX53_PAD_EIM_DA0__GPIO3_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 (_MX53_PAD_EIM_DA0__IPU_DISP1_DAT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA0__IPU_CSI1_D_9 (_MX53_PAD_EIM_DA0__IPU_CSI1_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 (_MX53_PAD_EIM_DA0__SRC_BT_CFG2_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 (_MX53_PAD_EIM_DA1__EMI_NAND_WEIM_DA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA1__GPIO3_1 (_MX53_PAD_EIM_DA1__GPIO3_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 (_MX53_PAD_EIM_DA1__IPU_DISP1_DAT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA1__IPU_CSI1_D_8 (_MX53_PAD_EIM_DA1__IPU_CSI1_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 (_MX53_PAD_EIM_DA1__SRC_BT_CFG2_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 (_MX53_PAD_EIM_DA2__EMI_NAND_WEIM_DA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA2__GPIO3_2 (_MX53_PAD_EIM_DA2__GPIO3_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 (_MX53_PAD_EIM_DA2__IPU_DISP1_DAT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA2__IPU_CSI1_D_7 (_MX53_PAD_EIM_DA2__IPU_CSI1_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 (_MX53_PAD_EIM_DA2__SRC_BT_CFG2_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 (_MX53_PAD_EIM_DA3__EMI_NAND_WEIM_DA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA3__GPIO3_3 (_MX53_PAD_EIM_DA3__GPIO3_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 (_MX53_PAD_EIM_DA3__IPU_DISP1_DAT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA3__IPU_CSI1_D_6 (_MX53_PAD_EIM_DA3__IPU_CSI1_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 (_MX53_PAD_EIM_DA3__SRC_BT_CFG2_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 (_MX53_PAD_EIM_DA4__EMI_NAND_WEIM_DA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA4__GPIO3_4 (_MX53_PAD_EIM_DA4__GPIO3_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 (_MX53_PAD_EIM_DA4__IPU_DISP1_DAT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA4__IPU_CSI1_D_5 (_MX53_PAD_EIM_DA4__IPU_CSI1_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 (_MX53_PAD_EIM_DA4__SRC_BT_CFG3_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 (_MX53_PAD_EIM_DA5__EMI_NAND_WEIM_DA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA5__GPIO3_5 (_MX53_PAD_EIM_DA5__GPIO3_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 (_MX53_PAD_EIM_DA5__IPU_DISP1_DAT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA5__IPU_CSI1_D_4 (_MX53_PAD_EIM_DA5__IPU_CSI1_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 (_MX53_PAD_EIM_DA5__SRC_BT_CFG3_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 (_MX53_PAD_EIM_DA6__EMI_NAND_WEIM_DA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA6__GPIO3_6 (_MX53_PAD_EIM_DA6__GPIO3_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 (_MX53_PAD_EIM_DA6__IPU_DISP1_DAT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA6__IPU_CSI1_D_3 (_MX53_PAD_EIM_DA6__IPU_CSI1_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 (_MX53_PAD_EIM_DA6__SRC_BT_CFG3_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 (_MX53_PAD_EIM_DA7__EMI_NAND_WEIM_DA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA7__GPIO3_7 (_MX53_PAD_EIM_DA7__GPIO3_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 (_MX53_PAD_EIM_DA7__IPU_DISP1_DAT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA7__IPU_CSI1_D_2 (_MX53_PAD_EIM_DA7__IPU_CSI1_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 (_MX53_PAD_EIM_DA7__SRC_BT_CFG3_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 (_MX53_PAD_EIM_DA8__EMI_NAND_WEIM_DA_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA8__GPIO3_8 (_MX53_PAD_EIM_DA8__GPIO3_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 (_MX53_PAD_EIM_DA8__IPU_DISP1_DAT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA8__IPU_CSI1_D_1 (_MX53_PAD_EIM_DA8__IPU_CSI1_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 (_MX53_PAD_EIM_DA8__SRC_BT_CFG3_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 (_MX53_PAD_EIM_DA9__EMI_NAND_WEIM_DA_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA9__GPIO3_9 (_MX53_PAD_EIM_DA9__GPIO3_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 (_MX53_PAD_EIM_DA9__IPU_DISP1_DAT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA9__IPU_CSI1_D_0 (_MX53_PAD_EIM_DA9__IPU_CSI1_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 (_MX53_PAD_EIM_DA9__SRC_BT_CFG3_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 (_MX53_PAD_EIM_DA10__EMI_NAND_WEIM_DA_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA10__GPIO3_10 (_MX53_PAD_EIM_DA10__GPIO3_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA10__IPU_DI1_PIN15 (_MX53_PAD_EIM_DA10__IPU_DI1_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN (_MX53_PAD_EIM_DA10__IPU_CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 (_MX53_PAD_EIM_DA10__SRC_BT_CFG3_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 (_MX53_PAD_EIM_DA11__EMI_NAND_WEIM_DA_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA11__GPIO3_11 (_MX53_PAD_EIM_DA11__GPIO3_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA11__IPU_DI1_PIN2 (_MX53_PAD_EIM_DA11__IPU_DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC (_MX53_PAD_EIM_DA11__IPU_CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 (_MX53_PAD_EIM_DA12__EMI_NAND_WEIM_DA_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA12__GPIO3_12 (_MX53_PAD_EIM_DA12__GPIO3_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA12__IPU_DI1_PIN3 (_MX53_PAD_EIM_DA12__IPU_DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC (_MX53_PAD_EIM_DA12__IPU_CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 (_MX53_PAD_EIM_DA13__EMI_NAND_WEIM_DA_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA13__GPIO3_13 (_MX53_PAD_EIM_DA13__GPIO3_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA13__IPU_DI1_D0_CS (_MX53_PAD_EIM_DA13__IPU_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK (_MX53_PAD_EIM_DA13__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 (_MX53_PAD_EIM_DA14__EMI_NAND_WEIM_DA_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA14__GPIO3_14 (_MX53_PAD_EIM_DA14__GPIO3_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA14__IPU_DI1_D1_CS (_MX53_PAD_EIM_DA14__IPU_DI1_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK (_MX53_PAD_EIM_DA14__CCM_DI0_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 (_MX53_PAD_EIM_DA15__EMI_NAND_WEIM_DA_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA15__GPIO3_15 (_MX53_PAD_EIM_DA15__GPIO3_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA15__IPU_DI1_PIN1 (_MX53_PAD_EIM_DA15__IPU_DI1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_DA15__IPU_DI1_PIN4 (_MX53_PAD_EIM_DA15__IPU_DI1_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B (_MX53_PAD_NANDF_WE_B__EMI_NANDF_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_WE_B__GPIO6_12 (_MX53_PAD_NANDF_WE_B__GPIO6_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B (_MX53_PAD_NANDF_RE_B__EMI_NANDF_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_RE_B__GPIO6_13 (_MX53_PAD_NANDF_RE_B__GPIO6_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT (_MX53_PAD_EIM_WAIT__EMI_WEIM_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_WAIT__GPIO5_0 (_MX53_PAD_EIM_WAIT__GPIO5_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B (_MX53_PAD_EIM_WAIT__EMI_WEIM_DTACK_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX3_P__GPIO6_22 (_MX53_PAD_LVDS1_TX3_P__GPIO6_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 (_MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX2_P__GPIO6_24 (_MX53_PAD_LVDS1_TX2_P__GPIO6_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 (_MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_CLK_P__GPIO6_26 (_MX53_PAD_LVDS1_CLK_P__GPIO6_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK (_MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX1_P__GPIO6_28 (_MX53_PAD_LVDS1_TX1_P__GPIO6_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 (_MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX0_P__GPIO6_30 (_MX53_PAD_LVDS1_TX0_P__GPIO6_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 (_MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX3_P__GPIO7_22 (_MX53_PAD_LVDS0_TX3_P__GPIO7_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 (_MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_CLK_P__GPIO7_24 (_MX53_PAD_LVDS0_CLK_P__GPIO7_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK (_MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX2_P__GPIO7_26 (_MX53_PAD_LVDS0_TX2_P__GPIO7_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 (_MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX1_P__GPIO7_28 (_MX53_PAD_LVDS0_TX1_P__GPIO7_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 (_MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX0_P__GPIO7_30 (_MX53_PAD_LVDS0_TX0_P__GPIO7_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 (_MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_10__GPIO4_0 (_MX53_PAD_GPIO_10__GPIO4_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_10__OSC32k_32K_OUT (_MX53_PAD_GPIO_10__OSC32k_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_11__GPIO4_1 (_MX53_PAD_GPIO_11__GPIO4_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_12__GPIO4_2 (_MX53_PAD_GPIO_12__GPIO4_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_13__GPIO4_3 (_MX53_PAD_GPIO_13__GPIO4_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_14__GPIO4_4 (_MX53_PAD_GPIO_14__GPIO4_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CLE__EMI_NANDF_CLE (_MX53_PAD_NANDF_CLE__EMI_NANDF_CLE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CLE__GPIO6_7 (_MX53_PAD_NANDF_CLE__GPIO6_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 (_MX53_PAD_NANDF_CLE__USBPHY1_VSTATUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_ALE__EMI_NANDF_ALE (_MX53_PAD_NANDF_ALE__EMI_NANDF_ALE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_ALE__GPIO6_8 (_MX53_PAD_NANDF_ALE__GPIO6_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 (_MX53_PAD_NANDF_ALE__USBPHY1_VSTATUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B (_MX53_PAD_NANDF_WP_B__EMI_NANDF_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_WP_B__GPIO6_9 (_MX53_PAD_NANDF_WP_B__GPIO6_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 (_MX53_PAD_NANDF_WP_B__USBPHY1_VSTATUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 (_MX53_PAD_NANDF_RB0__EMI_NANDF_RB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_RB0__GPIO6_10 (_MX53_PAD_NANDF_RB0__GPIO6_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 (_MX53_PAD_NANDF_RB0__USBPHY1_VSTATUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 (_MX53_PAD_NANDF_CS0__EMI_NANDF_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS0__GPIO6_11 (_MX53_PAD_NANDF_CS0__GPIO6_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 (_MX53_PAD_NANDF_CS0__USBPHY1_VSTATUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 (_MX53_PAD_NANDF_CS1__EMI_NANDF_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS1__GPIO6_14 (_MX53_PAD_NANDF_CS1__GPIO6_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS1__MLB_MLBCLK (_MX53_PAD_NANDF_CS1__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 (_MX53_PAD_NANDF_CS1__USBPHY1_VSTATUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 (_MX53_PAD_NANDF_CS2__EMI_NANDF_CS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__GPIO6_15 (_MX53_PAD_NANDF_CS2__GPIO6_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__IPU_SISG_0 (_MX53_PAD_NANDF_CS2__IPU_SISG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__ESAI1_TX0 (_MX53_PAD_NANDF_CS2__ESAI1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__EMI_WEIM_CRE (_MX53_PAD_NANDF_CS2__EMI_WEIM_CRE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK (_MX53_PAD_NANDF_CS2__CCM_CSI0_MCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__MLB_MLBSIG (_MX53_PAD_NANDF_CS2__MLB_MLBSIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 (_MX53_PAD_NANDF_CS2__USBPHY1_VSTATUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 (_MX53_PAD_NANDF_CS3__EMI_NANDF_CS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__GPIO6_16 (_MX53_PAD_NANDF_CS3__GPIO6_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__IPU_SISG_1 (_MX53_PAD_NANDF_CS3__IPU_SISG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__ESAI1_TX1 (_MX53_PAD_NANDF_CS3__ESAI1_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 (_MX53_PAD_NANDF_CS3__EMI_WEIM_A_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__MLB_MLBDAT (_MX53_PAD_NANDF_CS3__MLB_MLBDAT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 (_MX53_PAD_NANDF_CS3__USBPHY1_VSTATUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__FEC_MDIO (_MX53_PAD_FEC_MDIO__FEC_MDIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__GPIO1_22 (_MX53_PAD_FEC_MDIO__GPIO1_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__ESAI1_SCKR (_MX53_PAD_FEC_MDIO__ESAI1_SCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__FEC_COL (_MX53_PAD_FEC_MDIO__FEC_COL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 (_MX53_PAD_FEC_MDIO__RTC_CE_RTC_PS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 (_MX53_PAD_FEC_MDIO__SDMA_DEBUG_BUS_DEVICE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 (_MX53_PAD_FEC_MDIO__EMI_EMI_DEBUG_49 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_REF_CLK__FEC_TX_CLK (_MX53_PAD_FEC_REF_CLK__FEC_TX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_REF_CLK__GPIO1_23 (_MX53_PAD_FEC_REF_CLK__GPIO1_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_REF_CLK__ESAI1_FSR (_MX53_PAD_FEC_REF_CLK__ESAI1_FSR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 (_MX53_PAD_FEC_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 (_MX53_PAD_FEC_REF_CLK__EMI_EMI_DEBUG_50 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RX_ER__FEC_RX_ER (_MX53_PAD_FEC_RX_ER__FEC_RX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RX_ER__GPIO1_24 (_MX53_PAD_FEC_RX_ER__GPIO1_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RX_ER__ESAI1_HCKR (_MX53_PAD_FEC_RX_ER__ESAI1_HCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RX_ER__FEC_RX_CLK (_MX53_PAD_FEC_RX_ER__FEC_RX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 (_MX53_PAD_FEC_RX_ER__RTC_CE_RTC_PS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_CRS_DV__FEC_RX_DV (_MX53_PAD_FEC_CRS_DV__FEC_RX_DV | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_CRS_DV__GPIO1_25 (_MX53_PAD_FEC_CRS_DV__GPIO1_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_CRS_DV__ESAI1_SCKT (_MX53_PAD_FEC_CRS_DV__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD1__FEC_RDATA_1 (_MX53_PAD_FEC_RXD1__FEC_RDATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD1__GPIO1_26 (_MX53_PAD_FEC_RXD1__GPIO1_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD1__ESAI1_FST (_MX53_PAD_FEC_RXD1__ESAI1_FST | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD1__MLB_MLBSIG (_MX53_PAD_FEC_RXD1__MLB_MLBSIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 (_MX53_PAD_FEC_RXD1__RTC_CE_RTC_PS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD0__FEC_RDATA_0 (_MX53_PAD_FEC_RXD0__FEC_RDATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD0__GPIO1_27 (_MX53_PAD_FEC_RXD0__GPIO1_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD0__ESAI1_HCKT (_MX53_PAD_FEC_RXD0__ESAI1_HCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_RXD0__OSC32k_32K_OUT (_MX53_PAD_FEC_RXD0__OSC32k_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TX_EN__FEC_TX_EN (_MX53_PAD_FEC_TX_EN__FEC_TX_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TX_EN__GPIO1_28 (_MX53_PAD_FEC_TX_EN__GPIO1_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 (_MX53_PAD_FEC_TX_EN__ESAI1_TX3_RX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD1__FEC_TDATA_1 (_MX53_PAD_FEC_TXD1__FEC_TDATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD1__GPIO1_29 (_MX53_PAD_FEC_TXD1__GPIO1_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 (_MX53_PAD_FEC_TXD1__ESAI1_TX2_RX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD1__MLB_MLBCLK (_MX53_PAD_FEC_TXD1__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK (_MX53_PAD_FEC_TXD1__RTC_CE_RTC_PRSC_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD0__FEC_TDATA_0 (_MX53_PAD_FEC_TXD0__FEC_TDATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD0__GPIO1_30 (_MX53_PAD_FEC_TXD0__GPIO1_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 (_MX53_PAD_FEC_TXD0__ESAI1_TX4_RX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 (_MX53_PAD_FEC_TXD0__USBPHY2_DATAOUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__FEC_MDC (_MX53_PAD_FEC_MDC__FEC_MDC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__GPIO1_31 (_MX53_PAD_FEC_MDC__GPIO1_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 (_MX53_PAD_FEC_MDC__ESAI1_TX5_RX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__MLB_MLBDAT (_MX53_PAD_FEC_MDC__MLB_MLBDAT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG (_MX53_PAD_FEC_MDC__RTC_CE_RTC_ALARM1_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 (_MX53_PAD_FEC_MDC__USBPHY2_DATAOUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOW__PATA_DIOW (_MX53_PAD_PATA_DIOW__PATA_DIOW | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOW__GPIO6_17 (_MX53_PAD_PATA_DIOW__GPIO6_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOW__UART1_TXD_MUX (_MX53_PAD_PATA_DIOW__UART1_TXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 (_MX53_PAD_PATA_DIOW__USBPHY2_DATAOUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMACK__PATA_DMACK (_MX53_PAD_PATA_DMACK__PATA_DMACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMACK__GPIO6_18 (_MX53_PAD_PATA_DMACK__GPIO6_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMACK__UART1_RXD_MUX (_MX53_PAD_PATA_DMACK__UART1_RXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 (_MX53_PAD_PATA_DMACK__USBPHY2_DATAOUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMARQ__PATA_DMARQ (_MX53_PAD_PATA_DMARQ__PATA_DMARQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMARQ__GPIO7_0 (_MX53_PAD_PATA_DMARQ__GPIO7_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMARQ__UART2_TXD_MUX (_MX53_PAD_PATA_DMARQ__UART2_TXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 (_MX53_PAD_PATA_DMARQ__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 (_MX53_PAD_PATA_DMARQ__USBPHY2_DATAOUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN (_MX53_PAD_PATA_BUFFER_EN__PATA_BUFFER_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_BUFFER_EN__GPIO7_1 (_MX53_PAD_PATA_BUFFER_EN__GPIO7_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX (_MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 (_MX53_PAD_PATA_BUFFER_EN__CCM_CCM_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 (_MX53_PAD_PATA_BUFFER_EN__USBPHY2_DATAOUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__PATA_INTRQ (_MX53_PAD_PATA_INTRQ__PATA_INTRQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__GPIO7_2 (_MX53_PAD_PATA_INTRQ__GPIO7_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__UART2_CTS (_MX53_PAD_PATA_INTRQ__UART2_CTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__CAN1_TXCAN (_MX53_PAD_PATA_INTRQ__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 (_MX53_PAD_PATA_INTRQ__CCM_CCM_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 (_MX53_PAD_PATA_INTRQ__USBPHY2_DATAOUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOR__PATA_DIOR (_MX53_PAD_PATA_DIOR__PATA_DIOR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOR__GPIO7_3 (_MX53_PAD_PATA_DIOR__GPIO7_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOR__UART2_RTS (_MX53_PAD_PATA_DIOR__UART2_RTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DIOR__CAN1_RXCAN (_MX53_PAD_PATA_DIOR__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 (_MX53_PAD_PATA_DIOR__USBPHY2_DATAOUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B (_MX53_PAD_PATA_RESET_B__PATA_PATA_RESET_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__GPIO7_4 (_MX53_PAD_PATA_RESET_B__GPIO7_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__ESDHC3_CMD (_MX53_PAD_PATA_RESET_B__ESDHC3_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__UART1_CTS (_MX53_PAD_PATA_RESET_B__UART1_CTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__CAN2_TXCAN (_MX53_PAD_PATA_RESET_B__CAN2_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 (_MX53_PAD_PATA_RESET_B__USBPHY1_DATAOUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__PATA_IORDY (_MX53_PAD_PATA_IORDY__PATA_IORDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__GPIO7_5 (_MX53_PAD_PATA_IORDY__GPIO7_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__ESDHC3_CLK (_MX53_PAD_PATA_IORDY__ESDHC3_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__UART1_RTS (_MX53_PAD_PATA_IORDY__UART1_RTS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__CAN2_RXCAN (_MX53_PAD_PATA_IORDY__CAN2_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 (_MX53_PAD_PATA_IORDY__USBPHY1_DATAOUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_0__PATA_DA_0 (_MX53_PAD_PATA_DA_0__PATA_DA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_0__GPIO7_6 (_MX53_PAD_PATA_DA_0__GPIO7_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_0__ESDHC3_RST (_MX53_PAD_PATA_DA_0__ESDHC3_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_0__OWIRE_LINE (_MX53_PAD_PATA_DA_0__OWIRE_LINE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 (_MX53_PAD_PATA_DA_0__USBPHY1_DATAOUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__PATA_DA_1 (_MX53_PAD_PATA_DA_1__PATA_DA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__GPIO7_7 (_MX53_PAD_PATA_DA_1__GPIO7_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__ESDHC4_CMD (_MX53_PAD_PATA_DA_1__ESDHC4_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__UART3_CTS (_MX53_PAD_PATA_DA_1__UART3_CTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 (_MX53_PAD_PATA_DA_1__USBPHY1_DATAOUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__PATA_DA_2 (_MX53_PAD_PATA_DA_2__PATA_DA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__GPIO7_8 (_MX53_PAD_PATA_DA_2__GPIO7_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__ESDHC4_CLK (_MX53_PAD_PATA_DA_2__ESDHC4_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__UART3_RTS (_MX53_PAD_PATA_DA_2__UART3_RTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 (_MX53_PAD_PATA_DA_2__USBPHY1_DATAOUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_0__PATA_CS_0 (_MX53_PAD_PATA_CS_0__PATA_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_0__GPIO7_9 (_MX53_PAD_PATA_CS_0__GPIO7_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_0__UART3_TXD_MUX (_MX53_PAD_PATA_CS_0__UART3_TXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 (_MX53_PAD_PATA_CS_0__USBPHY1_DATAOUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_1__PATA_CS_1 (_MX53_PAD_PATA_CS_1__PATA_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_1__GPIO7_10 (_MX53_PAD_PATA_CS_1__GPIO7_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_CS_1__UART3_RXD_MUX (_MX53_PAD_PATA_CS_1__UART3_RXD_MUX | MUX_PAD_CTRL(MX53_UART_PAD_CTRL))
+#define MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 (_MX53_PAD_PATA_CS_1__USBPHY1_DATAOUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__PATA_DATA_0 (_MX53_PAD_PATA_DATA0__PATA_DATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__GPIO2_0 (_MX53_PAD_PATA_DATA0__GPIO2_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 (_MX53_PAD_PATA_DATA0__EMI_NANDF_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__ESDHC3_DAT4 (_MX53_PAD_PATA_DATA0__ESDHC3_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 (_MX53_PAD_PATA_DATA0__GPU3d_GPU_DEBUG_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 (_MX53_PAD_PATA_DATA0__IPU_DIAG_BUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 (_MX53_PAD_PATA_DATA0__USBPHY1_DATAOUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__PATA_DATA_1 (_MX53_PAD_PATA_DATA1__PATA_DATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__GPIO2_1 (_MX53_PAD_PATA_DATA1__GPIO2_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 (_MX53_PAD_PATA_DATA1__EMI_NANDF_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__ESDHC3_DAT5 (_MX53_PAD_PATA_DATA1__ESDHC3_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 (_MX53_PAD_PATA_DATA1__GPU3d_GPU_DEBUG_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 (_MX53_PAD_PATA_DATA1__IPU_DIAG_BUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__PATA_DATA_2 (_MX53_PAD_PATA_DATA2__PATA_DATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__GPIO2_2 (_MX53_PAD_PATA_DATA2__GPIO2_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 (_MX53_PAD_PATA_DATA2__EMI_NANDF_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__ESDHC3_DAT6 (_MX53_PAD_PATA_DATA2__ESDHC3_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 (_MX53_PAD_PATA_DATA2__GPU3d_GPU_DEBUG_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 (_MX53_PAD_PATA_DATA2__IPU_DIAG_BUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__PATA_DATA_3 (_MX53_PAD_PATA_DATA3__PATA_DATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__GPIO2_3 (_MX53_PAD_PATA_DATA3__GPIO2_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 (_MX53_PAD_PATA_DATA3__EMI_NANDF_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__ESDHC3_DAT7 (_MX53_PAD_PATA_DATA3__ESDHC3_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 (_MX53_PAD_PATA_DATA3__GPU3d_GPU_DEBUG_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 (_MX53_PAD_PATA_DATA3__IPU_DIAG_BUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__PATA_DATA_4 (_MX53_PAD_PATA_DATA4__PATA_DATA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__GPIO2_4 (_MX53_PAD_PATA_DATA4__GPIO2_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 (_MX53_PAD_PATA_DATA4__EMI_NANDF_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__ESDHC4_DAT4 (_MX53_PAD_PATA_DATA4__ESDHC4_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 (_MX53_PAD_PATA_DATA4__GPU3d_GPU_DEBUG_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 (_MX53_PAD_PATA_DATA4__IPU_DIAG_BUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__PATA_DATA_5 (_MX53_PAD_PATA_DATA5__PATA_DATA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__GPIO2_5 (_MX53_PAD_PATA_DATA5__GPIO2_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 (_MX53_PAD_PATA_DATA5__EMI_NANDF_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__ESDHC4_DAT5 (_MX53_PAD_PATA_DATA5__ESDHC4_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 (_MX53_PAD_PATA_DATA5__GPU3d_GPU_DEBUG_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 (_MX53_PAD_PATA_DATA5__IPU_DIAG_BUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__PATA_DATA_6 (_MX53_PAD_PATA_DATA6__PATA_DATA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__GPIO2_6 (_MX53_PAD_PATA_DATA6__GPIO2_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 (_MX53_PAD_PATA_DATA6__EMI_NANDF_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__ESDHC4_DAT6 (_MX53_PAD_PATA_DATA6__ESDHC4_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 (_MX53_PAD_PATA_DATA6__GPU3d_GPU_DEBUG_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 (_MX53_PAD_PATA_DATA6__IPU_DIAG_BUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__PATA_DATA_7 (_MX53_PAD_PATA_DATA7__PATA_DATA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__GPIO2_7 (_MX53_PAD_PATA_DATA7__GPIO2_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 (_MX53_PAD_PATA_DATA7__EMI_NANDF_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__ESDHC4_DAT7 (_MX53_PAD_PATA_DATA7__ESDHC4_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 (_MX53_PAD_PATA_DATA7__GPU3d_GPU_DEBUG_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 (_MX53_PAD_PATA_DATA7__IPU_DIAG_BUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__PATA_DATA_8 (_MX53_PAD_PATA_DATA8__PATA_DATA_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__GPIO2_8 (_MX53_PAD_PATA_DATA8__GPIO2_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__ESDHC1_DAT4 (_MX53_PAD_PATA_DATA8__ESDHC1_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 (_MX53_PAD_PATA_DATA8__EMI_NANDF_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__ESDHC3_DAT0 (_MX53_PAD_PATA_DATA8__ESDHC3_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 (_MX53_PAD_PATA_DATA8__GPU3d_GPU_DEBUG_OUT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 (_MX53_PAD_PATA_DATA8__IPU_DIAG_BUS_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__PATA_DATA_9 (_MX53_PAD_PATA_DATA9__PATA_DATA_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__GPIO2_9 (_MX53_PAD_PATA_DATA9__GPIO2_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__ESDHC1_DAT5 (_MX53_PAD_PATA_DATA9__ESDHC1_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 (_MX53_PAD_PATA_DATA9__EMI_NANDF_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__ESDHC3_DAT1 (_MX53_PAD_PATA_DATA9__ESDHC3_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 (_MX53_PAD_PATA_DATA9__GPU3d_GPU_DEBUG_OUT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 (_MX53_PAD_PATA_DATA9__IPU_DIAG_BUS_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__PATA_DATA_10 (_MX53_PAD_PATA_DATA10__PATA_DATA_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__GPIO2_10 (_MX53_PAD_PATA_DATA10__GPIO2_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__ESDHC1_DAT6 (_MX53_PAD_PATA_DATA10__ESDHC1_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 (_MX53_PAD_PATA_DATA10__EMI_NANDF_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__ESDHC3_DAT2 (_MX53_PAD_PATA_DATA10__ESDHC3_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 (_MX53_PAD_PATA_DATA10__GPU3d_GPU_DEBUG_OUT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 (_MX53_PAD_PATA_DATA10__IPU_DIAG_BUS_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__PATA_DATA_11 (_MX53_PAD_PATA_DATA11__PATA_DATA_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__GPIO2_11 (_MX53_PAD_PATA_DATA11__GPIO2_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__ESDHC1_DAT7 (_MX53_PAD_PATA_DATA11__ESDHC1_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 (_MX53_PAD_PATA_DATA11__EMI_NANDF_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__ESDHC3_DAT3 (_MX53_PAD_PATA_DATA11__ESDHC3_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 (_MX53_PAD_PATA_DATA11__GPU3d_GPU_DEBUG_OUT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 (_MX53_PAD_PATA_DATA11__IPU_DIAG_BUS_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__PATA_DATA_12 (_MX53_PAD_PATA_DATA12__PATA_DATA_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__GPIO2_12 (_MX53_PAD_PATA_DATA12__GPIO2_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__ESDHC2_DAT4 (_MX53_PAD_PATA_DATA12__ESDHC2_DAT4 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 (_MX53_PAD_PATA_DATA12__EMI_NANDF_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__ESDHC4_DAT0 (_MX53_PAD_PATA_DATA12__ESDHC4_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 (_MX53_PAD_PATA_DATA12__GPU3d_GPU_DEBUG_OUT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 (_MX53_PAD_PATA_DATA12__IPU_DIAG_BUS_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__PATA_DATA_13 (_MX53_PAD_PATA_DATA13__PATA_DATA_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__GPIO2_13 (_MX53_PAD_PATA_DATA13__GPIO2_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__ESDHC2_DAT5 (_MX53_PAD_PATA_DATA13__ESDHC2_DAT5 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 (_MX53_PAD_PATA_DATA13__EMI_NANDF_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__ESDHC4_DAT1 (_MX53_PAD_PATA_DATA13__ESDHC4_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 (_MX53_PAD_PATA_DATA13__GPU3d_GPU_DEBUG_OUT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 (_MX53_PAD_PATA_DATA13__IPU_DIAG_BUS_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__PATA_DATA_14 (_MX53_PAD_PATA_DATA14__PATA_DATA_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__GPIO2_14 (_MX53_PAD_PATA_DATA14__GPIO2_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__ESDHC2_DAT6 (_MX53_PAD_PATA_DATA14__ESDHC2_DAT6 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 (_MX53_PAD_PATA_DATA14__EMI_NANDF_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__ESDHC4_DAT2 (_MX53_PAD_PATA_DATA14__ESDHC4_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 (_MX53_PAD_PATA_DATA14__GPU3d_GPU_DEBUG_OUT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 (_MX53_PAD_PATA_DATA14__IPU_DIAG_BUS_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__PATA_DATA_15 (_MX53_PAD_PATA_DATA15__PATA_DATA_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__GPIO2_15 (_MX53_PAD_PATA_DATA15__GPIO2_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__ESDHC2_DAT7 (_MX53_PAD_PATA_DATA15__ESDHC2_DAT7 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 (_MX53_PAD_PATA_DATA15__EMI_NANDF_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__ESDHC4_DAT3 (_MX53_PAD_PATA_DATA15__ESDHC4_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 (_MX53_PAD_PATA_DATA15__GPU3d_GPU_DEBUG_OUT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 (_MX53_PAD_PATA_DATA15__IPU_DIAG_BUS_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__ESDHC1_DAT0 (_MX53_PAD_SD1_DATA0__ESDHC1_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__GPIO1_16 (_MX53_PAD_SD1_DATA0__GPIO1_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__GPT_CAPIN1 (_MX53_PAD_SD1_DATA0__GPT_CAPIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__CSPI_MISO (_MX53_PAD_SD1_DATA0__CSPI_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA0__CCM_PLL3_BYP (_MX53_PAD_SD1_DATA0__CCM_PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__ESDHC1_DAT1 (_MX53_PAD_SD1_DATA1__ESDHC1_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__GPIO1_17 (_MX53_PAD_SD1_DATA1__GPIO1_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__GPT_CAPIN2 (_MX53_PAD_SD1_DATA1__GPT_CAPIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__CSPI_SS0 (_MX53_PAD_SD1_DATA1__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA1__CCM_PLL4_BYP (_MX53_PAD_SD1_DATA1__CCM_PLL4_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__ESDHC1_CMD (_MX53_PAD_SD1_CMD__ESDHC1_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__GPIO1_18 (_MX53_PAD_SD1_CMD__GPIO1_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__GPT_CMPOUT1 (_MX53_PAD_SD1_CMD__GPT_CMPOUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__CSPI_MOSI (_MX53_PAD_SD1_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CMD__CCM_PLL1_BYP (_MX53_PAD_SD1_CMD__CCM_PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__ESDHC1_DAT2 (_MX53_PAD_SD1_DATA2__ESDHC1_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__GPIO1_19 (_MX53_PAD_SD1_DATA2__GPIO1_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__GPT_CMPOUT2 (_MX53_PAD_SD1_DATA2__GPT_CMPOUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__PWM2_PWMO (_MX53_PAD_SD1_DATA2__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__WDOG1_WDOG_B (_MX53_PAD_SD1_DATA2__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__CSPI_SS1 (_MX53_PAD_SD1_DATA2__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB (_MX53_PAD_SD1_DATA2__WDOG1_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA2__CCM_PLL2_BYP (_MX53_PAD_SD1_DATA2__CCM_PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__ESDHC1_CLK (_MX53_PAD_SD1_CLK__ESDHC1_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__GPIO1_20 (_MX53_PAD_SD1_CLK__GPIO1_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__OSC32k_32K_OUT (_MX53_PAD_SD1_CLK__OSC32k_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__GPT_CLKIN (_MX53_PAD_SD1_CLK__GPT_CLKIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__CSPI_SCLK (_MX53_PAD_SD1_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 (_MX53_PAD_SD1_CLK__SATA_PHY_DTB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__ESDHC1_DAT3 (_MX53_PAD_SD1_DATA3__ESDHC1_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__GPIO1_21 (_MX53_PAD_SD1_DATA3__GPIO1_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__GPT_CMPOUT3 (_MX53_PAD_SD1_DATA3__GPT_CMPOUT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__PWM1_PWMO (_MX53_PAD_SD1_DATA3__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__WDOG2_WDOG_B (_MX53_PAD_SD1_DATA3__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__CSPI_SS2 (_MX53_PAD_SD1_DATA3__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB (_MX53_PAD_SD1_DATA3__WDOG2_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 (_MX53_PAD_SD1_DATA3__SATA_PHY_DTB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__ESDHC2_CLK (_MX53_PAD_SD2_CLK__ESDHC2_CLK | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__GPIO1_10 (_MX53_PAD_SD2_CLK__GPIO1_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__KPP_COL_5 (_MX53_PAD_SD2_CLK__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS (_MX53_PAD_SD2_CLK__AUDMUX_AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__CSPI_SCLK (_MX53_PAD_SD2_CLK__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CLK__SCC_RANDOM_V (_MX53_PAD_SD2_CLK__SCC_RANDOM_V | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__ESDHC2_CMD (_MX53_PAD_SD2_CMD__ESDHC2_CMD | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__GPIO1_11 (_MX53_PAD_SD2_CMD__GPIO1_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__KPP_ROW_5 (_MX53_PAD_SD2_CMD__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC (_MX53_PAD_SD2_CMD__AUDMUX_AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__CSPI_MOSI (_MX53_PAD_SD2_CMD__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_CMD__SCC_RANDOM (_MX53_PAD_SD2_CMD__SCC_RANDOM | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__ESDHC2_DAT3 (_MX53_PAD_SD2_DATA3__ESDHC2_DAT3 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__GPIO1_12 (_MX53_PAD_SD2_DATA3__GPIO1_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__KPP_COL_6 (_MX53_PAD_SD2_DATA3__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC (_MX53_PAD_SD2_DATA3__AUDMUX_AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__CSPI_SS2 (_MX53_PAD_SD2_DATA3__CSPI_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA3__SJC_DONE (_MX53_PAD_SD2_DATA3__SJC_DONE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__ESDHC2_DAT2 (_MX53_PAD_SD2_DATA2__ESDHC2_DAT2 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__GPIO1_13 (_MX53_PAD_SD2_DATA2__GPIO1_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__KPP_ROW_6 (_MX53_PAD_SD2_DATA2__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD (_MX53_PAD_SD2_DATA2__AUDMUX_AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__CSPI_SS1 (_MX53_PAD_SD2_DATA2__CSPI_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA2__SJC_FAIL (_MX53_PAD_SD2_DATA2__SJC_FAIL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__ESDHC2_DAT1 (_MX53_PAD_SD2_DATA1__ESDHC2_DAT1 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__GPIO1_14 (_MX53_PAD_SD2_DATA1__GPIO1_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__KPP_COL_7 (_MX53_PAD_SD2_DATA1__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS (_MX53_PAD_SD2_DATA1__AUDMUX_AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__CSPI_SS0 (_MX53_PAD_SD2_DATA1__CSPI_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA1__RTIC_SEC_VIO (_MX53_PAD_SD2_DATA1__RTIC_SEC_VIO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__ESDHC2_DAT0 (_MX53_PAD_SD2_DATA0__ESDHC2_DAT0 | MUX_PAD_CTRL(MX53_SDHC_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__GPIO1_15 (_MX53_PAD_SD2_DATA0__GPIO1_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__KPP_ROW_7 (_MX53_PAD_SD2_DATA0__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD (_MX53_PAD_SD2_DATA0__AUDMUX_AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__CSPI_MISO (_MX53_PAD_SD2_DATA0__CSPI_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_SD2_DATA0__RTIC_DONE_INT (_MX53_PAD_SD2_DATA0__RTIC_DONE_INT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__CCM_CLKO (_MX53_PAD_GPIO_0__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__GPIO1_0 (_MX53_PAD_GPIO_0__GPIO1_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__KPP_COL_5 (_MX53_PAD_GPIO_0__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK (_MX53_PAD_GPIO_0__CCM_SSI_EXT1_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__EPIT1_EPITO (_MX53_PAD_GPIO_0__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__SRTC_ALARM_DEB (_MX53_PAD_GPIO_0__SRTC_ALARM_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__USBOH3_USBH1_PWR (_MX53_PAD_GPIO_0__USBOH3_USBH1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_0__CSU_TD (_MX53_PAD_GPIO_0__CSU_TD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__ESAI1_SCKR (_MX53_PAD_GPIO_1__ESAI1_SCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__GPIO1_1 (_MX53_PAD_GPIO_1__GPIO1_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__KPP_ROW_5 (_MX53_PAD_GPIO_1__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK (_MX53_PAD_GPIO_1__CCM_SSI_EXT2_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__PWM2_PWMO (_MX53_PAD_GPIO_1__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__WDOG2_WDOG_B (_MX53_PAD_GPIO_1__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__ESDHC1_CD (_MX53_PAD_GPIO_1__ESDHC1_CD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_1__SRC_TESTER_ACK (_MX53_PAD_GPIO_1__SRC_TESTER_ACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__ESAI1_FSR (_MX53_PAD_GPIO_9__ESAI1_FSR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__GPIO1_9 (_MX53_PAD_GPIO_9__GPIO1_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__KPP_COL_6 (_MX53_PAD_GPIO_9__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__CCM_REF_EN_B (_MX53_PAD_GPIO_9__CCM_REF_EN_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__PWM1_PWMO (_MX53_PAD_GPIO_9__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__WDOG1_WDOG_B (_MX53_PAD_GPIO_9__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__ESDHC1_WP (_MX53_PAD_GPIO_9__ESDHC1_WP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_9__SCC_FAIL_STATE (_MX53_PAD_GPIO_9__SCC_FAIL_STATE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__ESAI1_HCKR (_MX53_PAD_GPIO_3__ESAI1_HCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__GPIO1_3 (_MX53_PAD_GPIO_3__GPIO1_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__I2C3_SCL (_MX53_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_GPIO_3__DPLLIP1_TOG_EN (_MX53_PAD_GPIO_3__DPLLIP1_TOG_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__CCM_CLKO2 (_MX53_PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 (_MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__USBOH3_USBH1_OC (_MX53_PAD_GPIO_3__USBOH3_USBH1_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_3__MLB_MLBCLK (_MX53_PAD_GPIO_3__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__ESAI1_SCKT (_MX53_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__GPIO1_6 (_MX53_PAD_GPIO_6__GPIO1_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__I2C3_SDA (_MX53_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_GPIO_6__CCM_CCM_OUT_0 (_MX53_PAD_GPIO_6__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__CSU_CSU_INT_DEB (_MX53_PAD_GPIO_6__CSU_CSU_INT_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 (_MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__ESDHC2_LCTL (_MX53_PAD_GPIO_6__ESDHC2_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_6__MLB_MLBSIG (_MX53_PAD_GPIO_6__MLB_MLBSIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__ESAI1_FST (_MX53_PAD_GPIO_2__ESAI1_FST | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__GPIO1_2 (_MX53_PAD_GPIO_2__GPIO1_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__KPP_ROW_6 (_MX53_PAD_GPIO_2__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__CCM_CCM_OUT_1 (_MX53_PAD_GPIO_2__CCM_CCM_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 (_MX53_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 (_MX53_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__ESDHC2_WP (_MX53_PAD_GPIO_2__ESDHC2_WP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_2__MLB_MLBDAT (_MX53_PAD_GPIO_2__MLB_MLBDAT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__ESAI1_HCKT (_MX53_PAD_GPIO_4__ESAI1_HCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__GPIO1_4 (_MX53_PAD_GPIO_4__GPIO1_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__KPP_COL_7 (_MX53_PAD_GPIO_4__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__CCM_CCM_OUT_2 (_MX53_PAD_GPIO_4__CCM_CCM_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 (_MX53_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 (_MX53_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__ESDHC2_CD (_MX53_PAD_GPIO_4__ESDHC2_CD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_4__SCC_SEC_STATE (_MX53_PAD_GPIO_4__SCC_SEC_STATE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__ESAI1_TX2_RX3 (_MX53_PAD_GPIO_5__ESAI1_TX2_RX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__GPIO1_5 (_MX53_PAD_GPIO_5__GPIO1_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__KPP_ROW_7 (_MX53_PAD_GPIO_5__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__CCM_CLKO (_MX53_PAD_GPIO_5__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 (_MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 (_MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_5__I2C3_SCL (_MX53_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_GPIO_5__CCM_PLL1_BYP (_MX53_PAD_GPIO_5__CCM_PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__ESAI1_TX4_RX1 (_MX53_PAD_GPIO_7__ESAI1_TX4_RX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__GPIO1_7 (_MX53_PAD_GPIO_7__GPIO1_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__EPIT1_EPITO (_MX53_PAD_GPIO_7__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__CAN1_TXCAN (_MX53_PAD_GPIO_7__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__UART2_TXD_MUX (_MX53_PAD_GPIO_7__UART2_TXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__FIRI_RXD (_MX53_PAD_GPIO_7__FIRI_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__SPDIF_PLOCK (_MX53_PAD_GPIO_7__SPDIF_PLOCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_7__CCM_PLL2_BYP (_MX53_PAD_GPIO_7__CCM_PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__ESAI1_TX5_RX0 (_MX53_PAD_GPIO_8__ESAI1_TX5_RX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__GPIO1_8 (_MX53_PAD_GPIO_8__GPIO1_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__EPIT2_EPITO (_MX53_PAD_GPIO_8__EPIT2_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__CAN1_RXCAN (_MX53_PAD_GPIO_8__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__UART2_RXD_MUX (_MX53_PAD_GPIO_8__UART2_RXD_MUX | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__FIRI_TXD (_MX53_PAD_GPIO_8__FIRI_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__SPDIF_SRCLK (_MX53_PAD_GPIO_8__SPDIF_SRCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_8__CCM_PLL3_BYP (_MX53_PAD_GPIO_8__CCM_PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__ESAI1_TX3_RX2 (_MX53_PAD_GPIO_16__ESAI1_TX3_RX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__GPIO7_11 (_MX53_PAD_GPIO_16__GPIO7_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT (_MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 (_MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__SPDIF_IN1 (_MX53_PAD_GPIO_16__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_16__I2C3_SDA (_MX53_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C))
+#define MX53_PAD_GPIO_16__SJC_DE_B (_MX53_PAD_GPIO_16__SJC_DE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__ESAI1_TX0 (_MX53_PAD_GPIO_17__ESAI1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__GPIO7_12 (_MX53_PAD_GPIO_17__GPIO7_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 (_MX53_PAD_GPIO_17__SDMA_EXT_EVENT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__GPC_PMIC_RDY (_MX53_PAD_GPIO_17__GPC_PMIC_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG (_MX53_PAD_GPIO_17__RTC_CE_RTC_FSV_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__SPDIF_OUT1 (_MX53_PAD_GPIO_17__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__IPU_SNOOP2 (_MX53_PAD_GPIO_17__IPU_SNOOP2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_17__SJC_JTAG_ACT (_MX53_PAD_GPIO_17__SJC_JTAG_ACT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__ESAI1_TX1 (_MX53_PAD_GPIO_18__ESAI1_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__GPIO7_13 (_MX53_PAD_GPIO_18__GPIO7_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 (_MX53_PAD_GPIO_18__SDMA_EXT_EVENT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__OWIRE_LINE (_MX53_PAD_GPIO_18__OWIRE_LINE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG (_MX53_PAD_GPIO_18__RTC_CE_RTC_ALARM2_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK (_MX53_PAD_GPIO_18__CCM_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__ESDHC1_LCTL (_MX53_PAD_GPIO_18__ESDHC1_LCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX53_PAD_GPIO_18__SRC_SYSTEM_RST (_MX53_PAD_GPIO_18__SRC_SYSTEM_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#endif /* __MACH_IOMUX_MX53_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h b/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h
new file mode 100644
index 00000000..645b0b50
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h
@@ -0,0 +1,3840 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Auto Generate file, please don't edit it
+ *
+ */
+
+#ifndef __MACH_IOMUX_MX6DL_H__
+#define __MACH_IOMUX_MX6DL_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX6DL_HIGH_DRV PAD_CTL_DSE_120ohm
+#define MX6DL_DISP_PAD_CLT MX6DL_HIGH_DRV
+
+#define MX6DL_CCM_CLK0_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_MLB150_PAD_CTRL (PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) \
+
+#define MX6DL_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_34ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_ENET_REF_CLK_PAD_CTRL (PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
+
+#define MX6DL_I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \
+ PAD_CTL_HYS | PAD_CTL_ODE)
+
+#define MX6DL_ESAI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_USB_HSIC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_WEIM_NOR_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_40ohm | \
+ PAD_CTL_SPEED_MED | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP)
+
+#define MX6DL_ADU_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_PUS_100K_DOWN | \
+ PAD_CTL_HYS | PAD_CTL_SPEED_MED)
+
+#define MX6DL_HDMICEC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_ODE | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_SLOW)
+
+#define MX6DL_GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX6DL_GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | PAD_CTL_SRE_FAST)
+#define MX6DL_GPMI_PAD_CTRL2 (MX6DL_GPMI_PAD_CTRL0 | MX6DL_GPMI_PAD_CTRL1)
+#define MX6DL_SPDIF_OUT_PAD_CTRL (PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
+
+#define ENET_IRQ_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_40ohm | \
+ PAD_CTL_SPEED_MED)
+
+#define MX6DL_PAD_CSI0_DAT10__IPU1_CSI0_D_10 \
+ IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC \
+ IOMUX_PAD(0x0360, 0x004C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__ECSPI2_MISO \
+ IOMUX_PAD(0x0360, 0x004C, 2, 0x07F8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__UART1_TXD \
+ IOMUX_PAD(0x0360, 0x004C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__UART1_RXD \
+ IOMUX_PAD(0x0360, 0x004C, 3, 0x08FC, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 \
+ IOMUX_PAD(0x0360, 0x004C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__GPIO_5_28 \
+ IOMUX_PAD(0x0360, 0x004C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 \
+ IOMUX_PAD(0x0360, 0x004C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__SIMBA_TRACE_7 \
+ IOMUX_PAD(0x0360, 0x004C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT11__IPU1_CSI0_D_11 \
+ IOMUX_PAD(0x0364, 0x0050, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS \
+ IOMUX_PAD(0x0364, 0x0050, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__ECSPI2_SS0 \
+ IOMUX_PAD(0x0364, 0x0050, 2, 0x0800, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__UART1_TXD \
+ IOMUX_PAD(0x0364, 0x0050, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__UART1_RXD \
+ IOMUX_PAD(0x0364, 0x0050, 3, 0x08FC, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 \
+ IOMUX_PAD(0x0364, 0x0050, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__GPIO_5_29 \
+ IOMUX_PAD(0x0364, 0x0050, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 \
+ IOMUX_PAD(0x0364, 0x0050, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__SIMBA_TRACE_8 \
+ IOMUX_PAD(0x0364, 0x0050, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12 \
+ IOMUX_PAD(0x0368, 0x0054, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__WEIM_WEIM_D_8 \
+ IOMUX_PAD(0x0368, 0x0054, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__PCIE_CTRL_DIAG_STATUS_BUS_MUX_16 \
+ IOMUX_PAD(0x0368, 0x0054, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__UART4_TXD \
+ IOMUX_PAD(0x0368, 0x0054, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__UART4_RXD \
+ IOMUX_PAD(0x0368, 0x0054, 3, 0x0914, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 \
+ IOMUX_PAD(0x0368, 0x0054, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__GPIO_5_30 \
+ IOMUX_PAD(0x0368, 0x0054, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 \
+ IOMUX_PAD(0x0368, 0x0054, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__SIMBA_TRACE_9 \
+ IOMUX_PAD(0x0368, 0x0054, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13 \
+ IOMUX_PAD(0x036C, 0x0058, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__WEIM_WEIM_D_9 \
+ IOMUX_PAD(0x036C, 0x0058, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__PCIE_CTRL_DIAG_STATUS_BUS_MUX_17 \
+ IOMUX_PAD(0x036C, 0x0058, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__UART4_TXD \
+ IOMUX_PAD(0x036C, 0x0058, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__UART4_RXD \
+ IOMUX_PAD(0x036C, 0x0058, 3, 0x0914, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 \
+ IOMUX_PAD(0x036C, 0x0058, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__GPIO_5_31 \
+ IOMUX_PAD(0x036C, 0x0058, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 \
+ IOMUX_PAD(0x036C, 0x0058, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__SIMBA_TRACE_10 \
+ IOMUX_PAD(0x036C, 0x0058, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14 \
+ IOMUX_PAD(0x0370, 0x005C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__WEIM_WEIM_D_10 \
+ IOMUX_PAD(0x0370, 0x005C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__PCIE_CTRL_DIAG_STATUS_BUS_MUX_18 \
+ IOMUX_PAD(0x0370, 0x005C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__UART5_TXD \
+ IOMUX_PAD(0x0370, 0x005C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__UART5_RXD \
+ IOMUX_PAD(0x0370, 0x005C, 3, 0x091C, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 \
+ IOMUX_PAD(0x0370, 0x005C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__GPIO_6_0 \
+ IOMUX_PAD(0x0370, 0x005C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 \
+ IOMUX_PAD(0x0370, 0x005C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__SIMBA_TRACE_11 \
+ IOMUX_PAD(0x0370, 0x005C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15 \
+ IOMUX_PAD(0x0374, 0x0060, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__WEIM_WEIM_D_11 \
+ IOMUX_PAD(0x0374, 0x0060, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__PCIE_CTRL_DIAG_STATUS_BUS_MUX_19 \
+ IOMUX_PAD(0x0374, 0x0060, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__UART5_TXD \
+ IOMUX_PAD(0x0374, 0x0060, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__UART5_RXD \
+ IOMUX_PAD(0x0374, 0x0060, 3, 0x091C, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 \
+ IOMUX_PAD(0x0374, 0x0060, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__GPIO_6_1 \
+ IOMUX_PAD(0x0374, 0x0060, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 \
+ IOMUX_PAD(0x0374, 0x0060, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__SIMBA_TRACE_12 \
+ IOMUX_PAD(0x0374, 0x0060, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16 \
+ IOMUX_PAD(0x0378, 0x0064, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__WEIM_WEIM_D_12 \
+ IOMUX_PAD(0x0378, 0x0064, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__PCIE_CTRL_DIAG_STATUS_BUS_MUX_20 \
+ IOMUX_PAD(0x0378, 0x0064, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__UART4_CTS \
+ IOMUX_PAD(0x0378, 0x0064, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__UART4_RTS \
+ IOMUX_PAD(0x0378, 0x0064, 3, 0x0910, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 \
+ IOMUX_PAD(0x0378, 0x0064, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__GPIO_6_2 \
+ IOMUX_PAD(0x0378, 0x0064, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 \
+ IOMUX_PAD(0x0378, 0x0064, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__SIMBA_TRACE_13 \
+ IOMUX_PAD(0x0378, 0x0064, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17 \
+ IOMUX_PAD(0x037C, 0x0068, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__WEIM_WEIM_D_13 \
+ IOMUX_PAD(0x037C, 0x0068, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__PCIE_CTRL_DIAG_STATUS_BUS_MUX_21 \
+ IOMUX_PAD(0x037C, 0x0068, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__UART4_CTS \
+ IOMUX_PAD(0x037C, 0x0068, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__UART4_RTS \
+ IOMUX_PAD(0x037C, 0x0068, 3, 0x0910, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 \
+ IOMUX_PAD(0x037C, 0x0068, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__GPIO_6_3 \
+ IOMUX_PAD(0x037C, 0x0068, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 \
+ IOMUX_PAD(0x037C, 0x0068, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__SIMBA_TRACE_14 \
+ IOMUX_PAD(0x037C, 0x0068, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18 \
+ IOMUX_PAD(0x0380, 0x006C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__WEIM_WEIM_D_14 \
+ IOMUX_PAD(0x0380, 0x006C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__PCIE_CTRL_DIAG_STATUS_BUS_MUX_22 \
+ IOMUX_PAD(0x0380, 0x006C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__UART5_CTS \
+ IOMUX_PAD(0x0380, 0x006C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__UART5_RTS \
+ IOMUX_PAD(0x0380, 0x006C, 3, 0x0918, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 \
+ IOMUX_PAD(0x0380, 0x006C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__GPIO_6_4 \
+ IOMUX_PAD(0x0380, 0x006C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 \
+ IOMUX_PAD(0x0380, 0x006C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__SIMBA_TRACE_15 \
+ IOMUX_PAD(0x0380, 0x006C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19 \
+ IOMUX_PAD(0x0384, 0x0070, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__WEIM_WEIM_D_15 \
+ IOMUX_PAD(0x0384, 0x0070, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__PCIE_CTRL_DIAG_STATUS_BUS_MUX_23 \
+ IOMUX_PAD(0x0384, 0x0070, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__UART5_CTS \
+ IOMUX_PAD(0x0384, 0x0070, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__UART5_RTS \
+ IOMUX_PAD(0x0384, 0x0070, 3, 0x0918, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 \
+ IOMUX_PAD(0x0384, 0x0070, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__GPIO_6_5 \
+ IOMUX_PAD(0x0384, 0x0070, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 \
+ IOMUX_PAD(0x0384, 0x0070, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__ANATOP_ANATOP_TESTO_9 \
+ IOMUX_PAD(0x0384, 0x0070, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT4__IPU1_CSI0_D_4 \
+ IOMUX_PAD(0x0388, 0x0074, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__WEIM_WEIM_D_2 \
+ IOMUX_PAD(0x0388, 0x0074, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__ECSPI1_SCLK \
+ IOMUX_PAD(0x0388, 0x0074, 2, 0x07D8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__KPP_COL_5 \
+ IOMUX_PAD(0x0388, 0x0074, 3, 0x08C0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC \
+ IOMUX_PAD(0x0388, 0x0074, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__GPIO_5_22 \
+ IOMUX_PAD(0x0388, 0x0074, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__MMDC_MMDC_DEBUG_43 \
+ IOMUX_PAD(0x0388, 0x0074, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__SIMBA_TRACE_1 \
+ IOMUX_PAD(0x0388, 0x0074, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT5__IPU1_CSI0_D_5 \
+ IOMUX_PAD(0x038C, 0x0078, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__WEIM_WEIM_D_3 \
+ IOMUX_PAD(0x038C, 0x0078, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__ECSPI1_MOSI \
+ IOMUX_PAD(0x038C, 0x0078, 2, 0x07E0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__KPP_ROW_5 \
+ IOMUX_PAD(0x038C, 0x0078, 3, 0x08CC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD \
+ IOMUX_PAD(0x038C, 0x0078, 4, 0x0000, 0, MX6DL_ADU_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__GPIO_5_23 \
+ IOMUX_PAD(0x038C, 0x0078, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 \
+ IOMUX_PAD(0x038C, 0x0078, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__SIMBA_TRACE_2 \
+ IOMUX_PAD(0x038C, 0x0078, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT6__IPU1_CSI0_D_6 \
+ IOMUX_PAD(0x0390, 0x007C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__WEIM_WEIM_D_4 \
+ IOMUX_PAD(0x0390, 0x007C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__ECSPI1_MISO \
+ IOMUX_PAD(0x0390, 0x007C, 2, 0x07DC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__KPP_COL_6 \
+ IOMUX_PAD(0x0390, 0x007C, 3, 0x08C4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS \
+ IOMUX_PAD(0x0390, 0x007C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__GPIO_5_24 \
+ IOMUX_PAD(0x0390, 0x007C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 \
+ IOMUX_PAD(0x0390, 0x007C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__SIMBA_TRACE_3 \
+ IOMUX_PAD(0x0390, 0x007C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT7__IPU1_CSI0_D_7 \
+ IOMUX_PAD(0x0394, 0x0080, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__WEIM_WEIM_D_5 \
+ IOMUX_PAD(0x0394, 0x0080, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__ECSPI1_SS0 \
+ IOMUX_PAD(0x0394, 0x0080, 2, 0x07E4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__KPP_ROW_6 \
+ IOMUX_PAD(0x0394, 0x0080, 3, 0x08D0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD \
+ IOMUX_PAD(0x0394, 0x0080, 4, 0x0000, 0, MX6DL_ADU_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__GPIO_5_25 \
+ IOMUX_PAD(0x0394, 0x0080, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 \
+ IOMUX_PAD(0x0394, 0x0080, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__SIMBA_TRACE_4 \
+ IOMUX_PAD(0x0394, 0x0080, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT8__IPU1_CSI0_D_8 \
+ IOMUX_PAD(0x0398, 0x0084, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__WEIM_WEIM_D_6 \
+ IOMUX_PAD(0x0398, 0x0084, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__ECSPI2_SCLK \
+ IOMUX_PAD(0x0398, 0x0084, 2, 0x07F4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__KPP_COL_7 \
+ IOMUX_PAD(0x0398, 0x0084, 3, 0x08C8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__I2C1_SDA \
+ IOMUX_PAD(0x0398, 0x0084, 4 | IOMUX_CONFIG_SION, 0x086C, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__GPIO_5_26 \
+ IOMUX_PAD(0x0398, 0x0084, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 \
+ IOMUX_PAD(0x0398, 0x0084, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__SIMBA_TRACE_5 \
+ IOMUX_PAD(0x0398, 0x0084, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT9__IPU1_CSI0_D_9 \
+ IOMUX_PAD(0x039C, 0x0088, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__WEIM_WEIM_D_7 \
+ IOMUX_PAD(0x039C, 0x0088, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__ECSPI2_MOSI \
+ IOMUX_PAD(0x039C, 0x0088, 2, 0x07FC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__KPP_ROW_7 \
+ IOMUX_PAD(0x039C, 0x0088, 3, 0x08D4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__I2C1_SCL \
+ IOMUX_PAD(0x039C, 0x0088, 4 | IOMUX_CONFIG_SION, 0x0868, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__GPIO_5_27 \
+ IOMUX_PAD(0x039C, 0x0088, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 \
+ IOMUX_PAD(0x039C, 0x0088, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__SIMBA_TRACE_6 \
+ IOMUX_PAD(0x039C, 0x0088, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN \
+ IOMUX_PAD(0x03A0, 0x008C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 \
+ IOMUX_PAD(0x03A0, 0x008C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__PCIE_CTRL_DIAG_STATUS_BUS_MUX_14 \
+ IOMUX_PAD(0x03A0, 0x008C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 \
+ IOMUX_PAD(0x03A0, 0x008C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__GPIO_5_20 \
+ IOMUX_PAD(0x03A0, 0x008C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__MMDC_MMDC_DEBUG_31 \
+ IOMUX_PAD(0x03A0, 0x008C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__SIMBA_TRCLK \
+ IOMUX_PAD(0x03A0, 0x008C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC \
+ IOMUX_PAD(0x03A4, 0x0090, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_13 \
+ IOMUX_PAD(0x03A4, 0x0090, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__CCM_CLKO \
+ IOMUX_PAD(0x03A4, 0x0090, 3, 0x0000, 0, MX6DL_CCM_CLK0_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 \
+ IOMUX_PAD(0x03A4, 0x0090, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__GPIO_5_19 \
+ IOMUX_PAD(0x03A4, 0x0090, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 \
+ IOMUX_PAD(0x03A4, 0x0090, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__SIMBA_TRCTL \
+ IOMUX_PAD(0x03A4, 0x0090, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK \
+ IOMUX_PAD(0x03A8, 0x0094, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_12 \
+ IOMUX_PAD(0x03A8, 0x0094, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 \
+ IOMUX_PAD(0x03A8, 0x0094, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__GPIO_5_18 \
+ IOMUX_PAD(0x03A8, 0x0094, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__MMDC_MMDC_DEBUG_29 \
+ IOMUX_PAD(0x03A8, 0x0094, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__SIMBA_EVENTO \
+ IOMUX_PAD(0x03A8, 0x0094, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC \
+ IOMUX_PAD(0x03AC, 0x0098, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 \
+ IOMUX_PAD(0x03AC, 0x0098, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__PCIE_CTRL_DIAG_STATUS_BUS_MUX_15 \
+ IOMUX_PAD(0x03AC, 0x0098, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 \
+ IOMUX_PAD(0x03AC, 0x0098, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__GPIO_5_21 \
+ IOMUX_PAD(0x03AC, 0x0098, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__MMDC_MMDC_DEBUG_32 \
+ IOMUX_PAD(0x03AC, 0x0098, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__SIMBA_TRACE_0 \
+ IOMUX_PAD(0x03AC, 0x0098, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK \
+ IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_DISP_CLK__LCDIF_CLK \
+ IOMUX_PAD(0x03B0, 0x009C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__MIPI_CORE_DPHY_TEST_OUT_28 \
+ IOMUX_PAD(0x03B0, 0x009C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 \
+ IOMUX_PAD(0x03B0, 0x009C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__GPIO_4_16 \
+ IOMUX_PAD(0x03B0, 0x009C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__MMDC_MMDC_DEBUG_0 \
+ IOMUX_PAD(0x03B0, 0x009C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__TPSMP_HDATA_DIR \
+ IOMUX_PAD(0x03B0, 0x009C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__LCDIF_WR_RWN \
+ IOMUX_PAD(0x03B0, 0x009C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15 \
+ IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN15__LCDIF_ENABLE \
+ IOMUX_PAD(0x03B4, 0x00A0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__AUDMUX_AUD6_TXC \
+ IOMUX_PAD(0x03B4, 0x00A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__MIPI_CORE_DPHY_TEST_OUT_29 \
+ IOMUX_PAD(0x03B4, 0x00A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 \
+ IOMUX_PAD(0x03B4, 0x00A0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__GPIO_4_17 \
+ IOMUX_PAD(0x03B4, 0x00A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 \
+ IOMUX_PAD(0x03B4, 0x00A0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__PL301_SIM_MX6DL_PER1_HSIZE_0 \
+ IOMUX_PAD(0x03B4, 0x00A0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__LCDIF_RD_E \
+ IOMUX_PAD(0x03B4, 0x00A0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN2__LCDIF_HSYNC \
+ IOMUX_PAD(0x03B8, 0x00A4, 1, 0x08D8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__AUDMUX_AUD6_TXD \
+ IOMUX_PAD(0x03B8, 0x00A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__MIPI_CORE_DPHY_TEST_OUT_30 \
+ IOMUX_PAD(0x03B8, 0x00A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__GPIO_4_18 \
+ IOMUX_PAD(0x03B8, 0x00A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__MMDC_MMDC_DEBUG_2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__PL301_SIM_MX6DL_PER1_HADDR_9 \
+ IOMUX_PAD(0x03B8, 0x00A4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__LCDIF_RS \
+ IOMUX_PAD(0x03B8, 0x00A4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN3__LCDIF_VSYNC \
+ IOMUX_PAD(0x03BC, 0x00A8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS \
+ IOMUX_PAD(0x03BC, 0x00A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__MIPI_CORE_DPHY_TEST_OUT_31 \
+ IOMUX_PAD(0x03BC, 0x00A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__GPIO_4_19 \
+ IOMUX_PAD(0x03BC, 0x00A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__PL301_SIM_MX6DL_PER1_HADDR_10 \
+ IOMUX_PAD(0x03BC, 0x00A8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__LCDIF_CS \
+ IOMUX_PAD(0x03BC, 0x00A8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN4__IPU1_DI0_PIN4 \
+ IOMUX_PAD(0x03C0, 0x00AC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN4__LCDIF_BUSY \
+ IOMUX_PAD(0x03C0, 0x00AC, 1, 0x08D8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__AUDMUX_AUD6_RXD \
+ IOMUX_PAD(0x03C0, 0x00AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__USDHC1_WP \
+ IOMUX_PAD(0x03C0, 0x00AC, 3, 0x092C, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__SDMA_DEBUG_YIELD \
+ IOMUX_PAD(0x03C0, 0x00AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__GPIO_4_20 \
+ IOMUX_PAD(0x03C0, 0x00AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 \
+ IOMUX_PAD(0x03C0, 0x00AC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__PL301_SIM_MX6DL_PER1_HADDR_11 \
+ IOMUX_PAD(0x03C0, 0x00AC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__LCDIF_RESET \
+ IOMUX_PAD(0x03C0, 0x00AC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT0__LCDIF_DAT_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__ECSPI3_SCLK \
+ IOMUX_PAD(0x03C4, 0x00B0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__USDHC1_USDHC_DEBUG_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN \
+ IOMUX_PAD(0x03C4, 0x00B0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__GPIO_4_21 \
+ IOMUX_PAD(0x03C4, 0x00B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 \
+ IOMUX_PAD(0x03C4, 0x00B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__PL301_SIM_MX6DL_PER1_HSIZE_1 \
+ IOMUX_PAD(0x03C4, 0x00B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT1__LCDIF_DAT_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__ECSPI3_MOSI \
+ IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__USDHC1_USDHC_DEBUG_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL \
+ IOMUX_PAD(0x03C8, 0x00B4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__GPIO_4_22 \
+ IOMUX_PAD(0x03C8, 0x00B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__MMDC_MMDC_DEBUG_6 \
+ IOMUX_PAD(0x03C8, 0x00B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__PL301_SIM_MX6DL_PER1_HADDR_12 \
+ IOMUX_PAD(0x03C8, 0x00B4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 \
+ IOMUX_PAD(0x03CC, 0x00B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__LCDIF_DAT_10 \
+ IOMUX_PAD(0x03CC, 0x00B8, 1, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT10__USDHC1_USDHC_DEBUG_6 \
+ IOMUX_PAD(0x03CC, 0x00B8, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 \
+ IOMUX_PAD(0x03CC, 0x00B8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__GPIO_4_31 \
+ IOMUX_PAD(0x03CC, 0x00B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__MMDC_MMDC_DEBUG_15 \
+ IOMUX_PAD(0x03CC, 0x00B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__PL301_SIM_MX6DL_PER1_HADDR_21 \
+ IOMUX_PAD(0x03CC, 0x00B8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 \
+ IOMUX_PAD(0x03D0, 0x00BC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT11__LCDIF_DAT_11 \
+ IOMUX_PAD(0x03D0, 0x00BC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__USDHC1_USDHC_DEBUG_7 \
+ IOMUX_PAD(0x03D0, 0x00BC, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 \
+ IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__GPIO_5_5 \
+ IOMUX_PAD(0x03D0, 0x00BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__MMDC_MMDC_DEBUG_16 \
+ IOMUX_PAD(0x03D0, 0x00BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__PL301_SIM_MX6DL_PER1_HADDR_22 \
+ IOMUX_PAD(0x03D0, 0x00BC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 \
+ IOMUX_PAD(0x03D4, 0x00C0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT12__LCDIF_DAT_12 \
+ IOMUX_PAD(0x03D4, 0x00C0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 \
+ IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__GPIO_5_6 \
+ IOMUX_PAD(0x03D4, 0x00C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__MMDC_MMDC_DEBUG_17 \
+ IOMUX_PAD(0x03D4, 0x00C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__PL301_SIM_MX6DL_PER1_HADDR_23 \
+ IOMUX_PAD(0x03D4, 0x00C0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 \
+ IOMUX_PAD(0x03D8, 0x00C4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT13__LCDIF_DAT_13 \
+ IOMUX_PAD(0x03D8, 0x00C4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x03D8, 0x00C4, 3, 0x07BC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 \
+ IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__GPIO_5_7 \
+ IOMUX_PAD(0x03D8, 0x00C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__MMDC_MMDC_DEBUG_18 \
+ IOMUX_PAD(0x03D8, 0x00C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__PL301_SIM_MX6DL_PER1_HADDR_24 \
+ IOMUX_PAD(0x03D8, 0x00C4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 \
+ IOMUX_PAD(0x03DC, 0x00C8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT14__LCDIF_DAT_14 \
+ IOMUX_PAD(0x03DC, 0x00C8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x03DC, 0x00C8, 3, 0x07B8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 \
+ IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__GPIO_5_8 \
+ IOMUX_PAD(0x03DC, 0x00C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__MMDC_MMDC_DEBUG_19 \
+ IOMUX_PAD(0x03DC, 0x00C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__PL301_SIM_MX6DL_PER1_HSIZE_2 \
+ IOMUX_PAD(0x03DC, 0x00C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 \
+ IOMUX_PAD(0x03E0, 0x00CC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT15__LCDIF_DAT_15 \
+ IOMUX_PAD(0x03E0, 0x00CC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__ECSPI1_SS1 \
+ IOMUX_PAD(0x03E0, 0x00CC, 2, 0x07E8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__ECSPI2_SS1 \
+ IOMUX_PAD(0x03E0, 0x00CC, 3, 0x0804, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 \
+ IOMUX_PAD(0x03E0, 0x00CC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__GPIO_5_9 \
+ IOMUX_PAD(0x03E0, 0x00CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__MMDC_MMDC_DEBUG_20 \
+ IOMUX_PAD(0x03E0, 0x00CC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__PL301_SIM_MX6DL_PER1_HADDR_25 \
+ IOMUX_PAD(0x03E0, 0x00CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 \
+ IOMUX_PAD(0x03E4, 0x00D0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT16__LCDIF_DAT_16 \
+ IOMUX_PAD(0x03E4, 0x00D0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__ECSPI2_MOSI \
+ IOMUX_PAD(0x03E4, 0x00D0, 2, 0x07FC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x03E4, 0x00D0, 3, 0x07C0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x03E4, 0x00D0, 4, 0x08E8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__GPIO_5_10 \
+ IOMUX_PAD(0x03E4, 0x00D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__MMDC_MMDC_DEBUG_21 \
+ IOMUX_PAD(0x03E4, 0x00D0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__PL301_SIM_MX6DL_PER1_HADDR_26 \
+ IOMUX_PAD(0x03E4, 0x00D0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 \
+ IOMUX_PAD(0x03E8, 0x00D4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT17__LCDIF_DAT_17 \
+ IOMUX_PAD(0x03E8, 0x00D4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__ECSPI2_MISO \
+ IOMUX_PAD(0x03E8, 0x00D4, 2, 0x07F8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x03E8, 0x00D4, 3, 0x07B4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x03E8, 0x00D4, 4, 0x08EC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__GPIO_5_11 \
+ IOMUX_PAD(0x03E8, 0x00D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__MMDC_MMDC_DEBUG_22 \
+ IOMUX_PAD(0x03E8, 0x00D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__PL301_SIM_MX6DL_PER1_HADDR_27 \
+ IOMUX_PAD(0x03E8, 0x00D4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT18__LCDIF_DAT_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__ECSPI2_SS0 \
+ IOMUX_PAD(0x03EC, 0x00D8, 2, 0x0800, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x03EC, 0x00D8, 3, 0x07C4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x03EC, 0x00D8, 4, 0x07A4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__GPIO_5_12 \
+ IOMUX_PAD(0x03EC, 0x00D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__MMDC_MMDC_DEBUG_23 \
+ IOMUX_PAD(0x03EC, 0x00D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x03EC, 0x00D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 \
+ IOMUX_PAD(0x03F0, 0x00DC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT19__LCDIF_DAT_19 \
+ IOMUX_PAD(0x03F0, 0x00DC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__ECSPI2_SCLK \
+ IOMUX_PAD(0x03F0, 0x00DC, 2, 0x07F4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x03F0, 0x00DC, 3, 0x07B0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x03F0, 0x00DC, 4, 0x07A0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__GPIO_5_13 \
+ IOMUX_PAD(0x03F0, 0x00DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__MMDC_MMDC_DEBUG_24 \
+ IOMUX_PAD(0x03F0, 0x00DC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x03F0, 0x00DC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__LCDIF_DAT_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__ECSPI3_MISO \
+ IOMUX_PAD(0x03F4, 0x00E0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__USDHC1_USDHC_DEBUG_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__SDMA_DEBUG_MODE \
+ IOMUX_PAD(0x03F4, 0x00E0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__GPIO_4_23 \
+ IOMUX_PAD(0x03F4, 0x00E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__MMDC_MMDC_DEBUG_7 \
+ IOMUX_PAD(0x03F4, 0x00E0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__PL301_SIM_MX6DL_PER1_HADDR_13 \
+ IOMUX_PAD(0x03F4, 0x00E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT20__LCDIF_DAT_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__ECSPI1_SCLK \
+ IOMUX_PAD(0x03F8, 0x00E4, 2, 0x07D8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x03F8, 0x00E4, 3, 0x07A8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 \
+ IOMUX_PAD(0x03F8, 0x00E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__GPIO_5_14 \
+ IOMUX_PAD(0x03F8, 0x00E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__MMDC_MMDC_DEBUG_25 \
+ IOMUX_PAD(0x03F8, 0x00E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__PL301_SIM_MX6DL_PER1_HADDR_28 \
+ IOMUX_PAD(0x03F8, 0x00E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 \
+ IOMUX_PAD(0x03FC, 0x00E8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT21__LCDIF_DAT_21 \
+ IOMUX_PAD(0x03FC, 0x00E8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__ECSPI1_MOSI \
+ IOMUX_PAD(0x03FC, 0x00E8, 2, 0x07E0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x03FC, 0x00E8, 3, 0x079C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 \
+ IOMUX_PAD(0x03FC, 0x00E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__GPIO_5_15 \
+ IOMUX_PAD(0x03FC, 0x00E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__MMDC_MMDC_DEBUG_26 \
+ IOMUX_PAD(0x03FC, 0x00E8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__PL301_SIM_MX6DL_PER1_HADDR_29 \
+ IOMUX_PAD(0x03FC, 0x00E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 \
+ IOMUX_PAD(0x0400, 0x00EC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT22__LCDIF_DAT_22 \
+ IOMUX_PAD(0x0400, 0x00EC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__ECSPI1_MISO \
+ IOMUX_PAD(0x0400, 0x00EC, 2, 0x07DC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x0400, 0x00EC, 3, 0x07AC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 \
+ IOMUX_PAD(0x0400, 0x00EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__GPIO_5_16 \
+ IOMUX_PAD(0x0400, 0x00EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__MMDC_MMDC_DEBUG_27 \
+ IOMUX_PAD(0x0400, 0x00EC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__PL301_SIM_MX6DL_PER1_HADDR_30 \
+ IOMUX_PAD(0x0400, 0x00EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 \
+ IOMUX_PAD(0x0404, 0x00F0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT23__LCDIF_DAT_23 \
+ IOMUX_PAD(0x0404, 0x00F0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__ECSPI1_SS0 \
+ IOMUX_PAD(0x0404, 0x00F0, 2, 0x07E4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x0404, 0x00F0, 3, 0x0798, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 \
+ IOMUX_PAD(0x0404, 0x00F0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__GPIO_5_17 \
+ IOMUX_PAD(0x0404, 0x00F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__MMDC_MMDC_DEBUG_28 \
+ IOMUX_PAD(0x0404, 0x00F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__PL301_SIM_MX6DL_PER1_HADDR_31 \
+ IOMUX_PAD(0x0404, 0x00F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT3__LCDIF_DAT_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__ECSPI3_SS0 \
+ IOMUX_PAD(0x0408, 0x00F4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__USDHC1_USDHC_DEBUG_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR \
+ IOMUX_PAD(0x0408, 0x00F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__GPIO_4_24 \
+ IOMUX_PAD(0x0408, 0x00F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__MMDC_MMDC_DEBUG_8 \
+ IOMUX_PAD(0x0408, 0x00F4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__PL301_SIM_MX6DL_PER1_HADDR_14 \
+ IOMUX_PAD(0x0408, 0x00F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT4__LCDIF_DAT_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__ECSPI3_SS1 \
+ IOMUX_PAD(0x040C, 0x00F8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__USDHC1_USDHC_DEBUG_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB \
+ IOMUX_PAD(0x040C, 0x00F8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__GPIO_4_25 \
+ IOMUX_PAD(0x040C, 0x00F8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 \
+ IOMUX_PAD(0x040C, 0x00F8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__PL301_SIM_MX6DL_PER1_HADDR_15 \
+ IOMUX_PAD(0x040C, 0x00F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 \
+ IOMUX_PAD(0x0410, 0x00FC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT5__LCDIF_DAT_5 \
+ IOMUX_PAD(0x0410, 0x00FC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__ECSPI3_SS2 \
+ IOMUX_PAD(0x0410, 0x00FC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS \
+ IOMUX_PAD(0x0410, 0x00FC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS \
+ IOMUX_PAD(0x0410, 0x00FC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__GPIO_4_26 \
+ IOMUX_PAD(0x0410, 0x00FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__MMDC_MMDC_DEBUG_10 \
+ IOMUX_PAD(0x0410, 0x00FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__PL301_SIM_MX6DL_PER1_HADDR_16 \
+ IOMUX_PAD(0x0410, 0x00FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 \
+ IOMUX_PAD(0x0414, 0x0100, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT6__LCDIF_DAT_6 \
+ IOMUX_PAD(0x0414, 0x0100, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__ECSPI3_SS3 \
+ IOMUX_PAD(0x0414, 0x0100, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC \
+ IOMUX_PAD(0x0414, 0x0100, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE \
+ IOMUX_PAD(0x0414, 0x0100, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__GPIO_4_27 \
+ IOMUX_PAD(0x0414, 0x0100, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__MMDC_MMDC_DEBUG_11 \
+ IOMUX_PAD(0x0414, 0x0100, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__PL301_SIM_MX6DL_PER1_HADDR_17 \
+ IOMUX_PAD(0x0414, 0x0100, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 \
+ IOMUX_PAD(0x0418, 0x0104, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT7__LCDIF_DAT_7 \
+ IOMUX_PAD(0x0418, 0x0104, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__ECSPI3_RDY \
+ IOMUX_PAD(0x0418, 0x0104, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__USDHC1_USDHC_DEBUG_5 \
+ IOMUX_PAD(0x0418, 0x0104, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 \
+ IOMUX_PAD(0x0418, 0x0104, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__GPIO_4_28 \
+ IOMUX_PAD(0x0418, 0x0104, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__MMDC_MMDC_DEBUG_12 \
+ IOMUX_PAD(0x0418, 0x0104, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__PL301_SIM_MX6DL_PER1_HADDR_18 \
+ IOMUX_PAD(0x0418, 0x0104, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 \
+ IOMUX_PAD(0x041C, 0x0108, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT8__LCDIF_DAT_8 \
+ IOMUX_PAD(0x041C, 0x0108, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__PWM1_PWMO \
+ IOMUX_PAD(0x041C, 0x0108, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__WDOG1_WDOG_B \
+ IOMUX_PAD(0x041C, 0x0108, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 \
+ IOMUX_PAD(0x041C, 0x0108, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__GPIO_4_29 \
+ IOMUX_PAD(0x041C, 0x0108, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__MMDC_MMDC_DEBUG_13 \
+ IOMUX_PAD(0x041C, 0x0108, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__PL301_SIM_MX6DL_PER1_HADDR_19 \
+ IOMUX_PAD(0x041C, 0x0108, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 \
+ IOMUX_PAD(0x0420, 0x010C, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT9__LCDIF_DAT_9 \
+ IOMUX_PAD(0x0420, 0x010C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__PWM2_PWMO \
+ IOMUX_PAD(0x0420, 0x010C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__WDOG2_WDOG_B \
+ IOMUX_PAD(0x0420, 0x010C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 \
+ IOMUX_PAD(0x0420, 0x010C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__GPIO_4_30 \
+ IOMUX_PAD(0x0420, 0x010C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__MMDC_MMDC_DEBUG_14 \
+ IOMUX_PAD(0x0420, 0x010C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__PL301_SIM_MX6DL_PER1_HADDR_20 \
+ IOMUX_PAD(0x0420, 0x010C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A0__MMDC_DRAM_A_0 \
+ IOMUX_PAD(0x0424, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A1__MMDC_DRAM_A_1 \
+ IOMUX_PAD(0x0428, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A10__MMDC_DRAM_A_10 \
+ IOMUX_PAD(0x042C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A11__MMDC_DRAM_A_11 \
+ IOMUX_PAD(0x0430, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A12__MMDC_DRAM_A_12 \
+ IOMUX_PAD(0x0434, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A13__MMDC_DRAM_A_13 \
+ IOMUX_PAD(0x0438, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A14__MMDC_DRAM_A_14 \
+ IOMUX_PAD(0x043C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A15__MMDC_DRAM_A_15 \
+ IOMUX_PAD(0x0440, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A2__MMDC_DRAM_A_2 \
+ IOMUX_PAD(0x0444, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A3__MMDC_DRAM_A_3 \
+ IOMUX_PAD(0x0448, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A4__MMDC_DRAM_A_4 \
+ IOMUX_PAD(0x044C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A5__MMDC_DRAM_A_5 \
+ IOMUX_PAD(0x0450, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A6__MMDC_DRAM_A_6 \
+ IOMUX_PAD(0x0454, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A7__MMDC_DRAM_A_7 \
+ IOMUX_PAD(0x0458, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A8__MMDC_DRAM_A_8 \
+ IOMUX_PAD(0x045C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A9__MMDC_DRAM_A_9 \
+ IOMUX_PAD(0x0460, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CAS__MMDC_DRAM_CAS \
+ IOMUX_PAD(0x0464, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CS0__MMDC_DRAM_CS_0 \
+ IOMUX_PAD(0x0468, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CS1__MMDC_DRAM_CS_1 \
+ IOMUX_PAD(0x046C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D0__MMDC_DRAM_D_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D1__MMDC_DRAM_D_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D10__MMDC_DRAM_D_10 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D11__MMDC_DRAM_D_11 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D12__MMDC_DRAM_D_12 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D13__MMDC_DRAM_D_13 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D14__MMDC_DRAM_D_14 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D15__MMDC_DRAM_D_15 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D16__MMDC_DRAM_D_16 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D17__MMDC_DRAM_D_17 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D18__MMDC_DRAM_D_18 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D19__MMDC_DRAM_D_19 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D2__MMDC_DRAM_D_2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D20__MMDC_DRAM_D_20 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D21__MMDC_DRAM_D_21 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D22__MMDC_DRAM_D_22 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D23__MMDC_DRAM_D_23 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D24__MMDC_DRAM_D_24 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D25__MMDC_DRAM_D_25 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D26__MMDC_DRAM_D_26 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D27__MMDC_DRAM_D_27 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D28__MMDC_DRAM_D_28 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D29__MMDC_DRAM_D_29 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D3__MMDC_DRAM_D_3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D30__MMDC_DRAM_D_30 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D31__MMDC_DRAM_D_31 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D32__MMDC_DRAM_D_32 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D33__MMDC_DRAM_D_33 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D34__MMDC_DRAM_D_34 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D35__MMDC_DRAM_D_35 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D36__MMDC_DRAM_D_36 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D37__MMDC_DRAM_D_37 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D38__MMDC_DRAM_D_38 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D39__MMDC_DRAM_D_39 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D4__MMDC_DRAM_D_4 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D40__MMDC_DRAM_D_40 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D41__MMDC_DRAM_D_41 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D42__MMDC_DRAM_D_42 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D43__MMDC_DRAM_D_43 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D44__MMDC_DRAM_D_44 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D45__MMDC_DRAM_D_45 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D46__MMDC_DRAM_D_46 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D47__MMDC_DRAM_D_47 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D48__MMDC_DRAM_D_48 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D49__MMDC_DRAM_D_49 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D5__MMDC_DRAM_D_5 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D50__MMDC_DRAM_D_50 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D51__MMDC_DRAM_D_51 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D52__MMDC_DRAM_D_52 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D53__MMDC_DRAM_D_53 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D54__MMDC_DRAM_D_54 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D55__MMDC_DRAM_D_55 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D56__MMDC_DRAM_D_56 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D57__MMDC_DRAM_D_57 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D58__MMDC_DRAM_D_58 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D59__MMDC_DRAM_D_59 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D6__MMDC_DRAM_D_6 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D60__MMDC_DRAM_D_60 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D61__MMDC_DRAM_D_61 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D62__MMDC_DRAM_D_62 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D63__MMDC_DRAM_D_63 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D7__MMDC_DRAM_D_7 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D8__MMDC_DRAM_D_8 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D9__MMDC_DRAM_D_9 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 \
+ IOMUX_PAD(0x0470, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 \
+ IOMUX_PAD(0x0474, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 \
+ IOMUX_PAD(0x0478, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 \
+ IOMUX_PAD(0x047C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 \
+ IOMUX_PAD(0x0480, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 \
+ IOMUX_PAD(0x0484, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 \
+ IOMUX_PAD(0x0488, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 \
+ IOMUX_PAD(0x048C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_RAS__MMDC_DRAM_RAS \
+ IOMUX_PAD(0x0490, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_RESET__MMDC_DRAM_RESET \
+ IOMUX_PAD(0x0494, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 \
+ IOMUX_PAD(0x0498, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 \
+ IOMUX_PAD(0x049C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 \
+ IOMUX_PAD(0x04A0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 \
+ IOMUX_PAD(0x04A4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 \
+ IOMUX_PAD(0x04A8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 \
+ IOMUX_PAD(0x04AC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 \
+ IOMUX_PAD(0x04B0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 \
+ IOMUX_PAD(0x04B4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 \
+ IOMUX_PAD(0x04B8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 \
+ IOMUX_PAD(0x04BC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 \
+ IOMUX_PAD(0x04C0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 \
+ IOMUX_PAD(0x04C4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 \
+ IOMUX_PAD(0x04C8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 \
+ IOMUX_PAD(0x04CC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 \
+ IOMUX_PAD(0x04D0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 \
+ IOMUX_PAD(0x04D4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 \
+ IOMUX_PAD(0x04D8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDWE__MMDC_DRAM_SDWE \
+ IOMUX_PAD(0x04DC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A16__WEIM_WEIM_A_16 \
+ IOMUX_PAD(0x04E0, 0x0110, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__IPU1_DI1_DISP_CLK \
+ IOMUX_PAD(0x04E0, 0x0110, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__IPU1_CSI1_PIXCLK \
+ IOMUX_PAD(0x04E0, 0x0110, 2, 0x08B8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__MIPI_CORE_DPHY_TEST_OUT_23 \
+ IOMUX_PAD(0x04E0, 0x0110, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__GPIO_2_22 \
+ IOMUX_PAD(0x04E0, 0x0110, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__TPSMP_HDATA_6 \
+ IOMUX_PAD(0x04E0, 0x0110, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__SRC_BT_CFG_16 \
+ IOMUX_PAD(0x04E0, 0x0110, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__EPDC_SDDO_0 \
+ IOMUX_PAD(0x04E0, 0x0110, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A17__WEIM_WEIM_A_17 \
+ IOMUX_PAD(0x04E4, 0x0114, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__IPU1_DISP1_DAT_12 \
+ IOMUX_PAD(0x04E4, 0x0114, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__IPU1_CSI1_D_12 \
+ IOMUX_PAD(0x04E4, 0x0114, 2, 0x0890, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__MIPI_CORE_DPHY_TEST_OUT_22 \
+ IOMUX_PAD(0x04E4, 0x0114, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__GPIO_2_21 \
+ IOMUX_PAD(0x04E4, 0x0114, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__TPSMP_HDATA_5 \
+ IOMUX_PAD(0x04E4, 0x0114, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__SRC_BT_CFG_17 \
+ IOMUX_PAD(0x04E4, 0x0114, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__EPDC_PWRSTAT \
+ IOMUX_PAD(0x04E4, 0x0114, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A18__WEIM_WEIM_A_18 \
+ IOMUX_PAD(0x04E8, 0x0118, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__IPU1_DISP1_DAT_13 \
+ IOMUX_PAD(0x04E8, 0x0118, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__IPU1_CSI1_D_13 \
+ IOMUX_PAD(0x04E8, 0x0118, 2, 0x0894, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__MIPI_CORE_DPHY_TEST_OUT_21 \
+ IOMUX_PAD(0x04E8, 0x0118, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__GPIO_2_20 \
+ IOMUX_PAD(0x04E8, 0x0118, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__TPSMP_HDATA_4 \
+ IOMUX_PAD(0x04E8, 0x0118, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__SRC_BT_CFG_18 \
+ IOMUX_PAD(0x04E8, 0x0118, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__EPDC_PWRCTRL_0 \
+ IOMUX_PAD(0x04E8, 0x0118, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A19__WEIM_WEIM_A_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__IPU1_DISP1_DAT_14 \
+ IOMUX_PAD(0x04EC, 0x011C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__IPU1_CSI1_D_14 \
+ IOMUX_PAD(0x04EC, 0x011C, 2, 0x0898, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__MIPI_CORE_DPHY_TEST_OUT_20 \
+ IOMUX_PAD(0x04EC, 0x011C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__GPIO_2_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__TPSMP_HDATA_3 \
+ IOMUX_PAD(0x04EC, 0x011C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__SRC_BT_CFG_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__EPDC_PWRCTRL_1 \
+ IOMUX_PAD(0x04EC, 0x011C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A20__WEIM_WEIM_A_20 \
+ IOMUX_PAD(0x04F0, 0x0120, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__IPU1_DISP1_DAT_15 \
+ IOMUX_PAD(0x04F0, 0x0120, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__IPU1_CSI1_D_15 \
+ IOMUX_PAD(0x04F0, 0x0120, 2, 0x089C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__MIPI_CORE_DPHY_TEST_OUT_19 \
+ IOMUX_PAD(0x04F0, 0x0120, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__GPIO_2_18 \
+ IOMUX_PAD(0x04F0, 0x0120, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__TPSMP_HDATA_2 \
+ IOMUX_PAD(0x04F0, 0x0120, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__SRC_BT_CFG_20 \
+ IOMUX_PAD(0x04F0, 0x0120, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__EPDC_PWRCTRL_2 \
+ IOMUX_PAD(0x04F0, 0x0120, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A21__WEIM_WEIM_A_21 \
+ IOMUX_PAD(0x04F4, 0x0124, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__IPU1_DISP1_DAT_16 \
+ IOMUX_PAD(0x04F4, 0x0124, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__IPU1_CSI1_D_16 \
+ IOMUX_PAD(0x04F4, 0x0124, 2, 0x08A0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__MIPI_CORE_DPHY_TEST_OUT_18 \
+ IOMUX_PAD(0x04F4, 0x0124, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__GPIO_2_17 \
+ IOMUX_PAD(0x04F4, 0x0124, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__TPSMP_HDATA_1 \
+ IOMUX_PAD(0x04F4, 0x0124, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__SRC_BT_CFG_21 \
+ IOMUX_PAD(0x04F4, 0x0124, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__EPDC_GDCLK \
+ IOMUX_PAD(0x04F4, 0x0124, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A22__WEIM_WEIM_A_22 \
+ IOMUX_PAD(0x04F8, 0x0128, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__IPU1_DISP1_DAT_17 \
+ IOMUX_PAD(0x04F8, 0x0128, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__IPU1_CSI1_D_17 \
+ IOMUX_PAD(0x04F8, 0x0128, 2, 0x08A4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__GPIO_2_16 \
+ IOMUX_PAD(0x04F8, 0x0128, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__TPSMP_HDATA_0 \
+ IOMUX_PAD(0x04F8, 0x0128, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__SRC_BT_CFG_22 \
+ IOMUX_PAD(0x04F8, 0x0128, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__EPDC_GDSP \
+ IOMUX_PAD(0x04F8, 0x0128, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A23__WEIM_WEIM_A_23 \
+ IOMUX_PAD(0x04FC, 0x012C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_DISP1_DAT_18 \
+ IOMUX_PAD(0x04FC, 0x012C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_CSI1_D_18 \
+ IOMUX_PAD(0x04FC, 0x012C, 2, 0x08A8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_SISG_3 \
+ IOMUX_PAD(0x04FC, 0x012C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__GPIO_6_6 \
+ IOMUX_PAD(0x04FC, 0x012C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__PL301_SIM_MX6DL_PER1_HPROT_3 \
+ IOMUX_PAD(0x04FC, 0x012C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__SRC_BT_CFG_23 \
+ IOMUX_PAD(0x04FC, 0x012C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__EPDC_GDOE \
+ IOMUX_PAD(0x04FC, 0x012C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A24__WEIM_WEIM_A_24 \
+ IOMUX_PAD(0x0500, 0x0130, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_DISP1_DAT_19 \
+ IOMUX_PAD(0x0500, 0x0130, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_CSI1_D_19 \
+ IOMUX_PAD(0x0500, 0x0130, 2, 0x08AC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_SISG_2 \
+ IOMUX_PAD(0x0500, 0x0130, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__GPIO_5_4 \
+ IOMUX_PAD(0x0500, 0x0130, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__PL301_SIM_MX6DL_PER1_HPROT_2 \
+ IOMUX_PAD(0x0500, 0x0130, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__SRC_BT_CFG_24 \
+ IOMUX_PAD(0x0500, 0x0130, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__EPDC_GDRL \
+ IOMUX_PAD(0x0500, 0x0130, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A25__WEIM_WEIM_A_25 \
+ IOMUX_PAD(0x0504, 0x0134, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__ECSPI4_SS1 \
+ IOMUX_PAD(0x0504, 0x0134, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__ECSPI2_RDY \
+ IOMUX_PAD(0x0504, 0x0134, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__IPU1_DI1_PIN12 \
+ IOMUX_PAD(0x0504, 0x0134, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__IPU1_DI0_D1_CS \
+ IOMUX_PAD(0x0504, 0x0134, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__GPIO_5_2 \
+ IOMUX_PAD(0x0504, 0x0134, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x0504, 0x0134, 6, 0x085C, 0, MX6DL_HDMICEC_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__PL301_SIM_MX6DL_PER1_HBURST_0 \
+ IOMUX_PAD(0x0504, 0x0134, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__EPDC_SDDO_15 \
+ IOMUX_PAD(0x0504, 0x0134, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x0504, 0x0134, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_BCLK__WEIM_WEIM_BCLK \
+ IOMUX_PAD(0x0508, 0x0138, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__IPU1_DI1_PIN16 \
+ IOMUX_PAD(0x0508, 0x0138, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__GPIO_6_31 \
+ IOMUX_PAD(0x0508, 0x0138, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__TPSMP_HDATA_31 \
+ IOMUX_PAD(0x0508, 0x0138, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__EPDC_SDCE_9 \
+ IOMUX_PAD(0x0508, 0x0138, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_CS0__WEIM_WEIM_CS_0 \
+ IOMUX_PAD(0x050C, 0x013C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__IPU1_DI1_PIN5 \
+ IOMUX_PAD(0x050C, 0x013C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__ECSPI2_SCLK \
+ IOMUX_PAD(0x050C, 0x013C, 2, 0x07F4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__MIPI_CORE_DPHY_TEST_OUT_24 \
+ IOMUX_PAD(0x050C, 0x013C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__GPIO_2_23 \
+ IOMUX_PAD(0x050C, 0x013C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__TPSMP_HDATA_7 \
+ IOMUX_PAD(0x050C, 0x013C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__EPDC_SDDO_6 \
+ IOMUX_PAD(0x050C, 0x013C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_CS1__WEIM_WEIM_CS_1 \
+ IOMUX_PAD(0x0510, 0x0140, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__IPU1_DI1_PIN6 \
+ IOMUX_PAD(0x0510, 0x0140, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__ECSPI2_MOSI \
+ IOMUX_PAD(0x0510, 0x0140, 2, 0x07FC, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__MIPI_CORE_DPHY_TEST_OUT_25 \
+ IOMUX_PAD(0x0510, 0x0140, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__GPIO_2_24 \
+ IOMUX_PAD(0x0510, 0x0140, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__TPSMP_HDATA_8 \
+ IOMUX_PAD(0x0510, 0x0140, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__EPDC_SDDO_8 \
+ IOMUX_PAD(0x0510, 0x0140, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D16__WEIM_WEIM_D_16 \
+ IOMUX_PAD(0x0514, 0x0144, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__ECSPI1_SCLK \
+ IOMUX_PAD(0x0514, 0x0144, 1, 0x07D8, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__IPU1_DI0_PIN5 \
+ IOMUX_PAD(0x0514, 0x0144, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__IPU1_CSI1_D_18 \
+ IOMUX_PAD(0x0514, 0x0144, 3, 0x08A8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x0514, 0x0144, 4, 0x0864, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__GPIO_3_16 \
+ IOMUX_PAD(0x0514, 0x0144, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__I2C2_SDA \
+ IOMUX_PAD(0x0514, 0x0144, 6 | IOMUX_CONFIG_SION, 0x0874, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__TPSMP_HTRANS_0 \
+ IOMUX_PAD(0x0514, 0x0144, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__EPDC_SDDO_10 \
+ IOMUX_PAD(0x0514, 0x0144, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D17__WEIM_WEIM_D_17 \
+ IOMUX_PAD(0x0518, 0x0148, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__ECSPI1_MISO \
+ IOMUX_PAD(0x0518, 0x0148, 1, 0x07DC, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__IPU1_DI0_PIN6 \
+ IOMUX_PAD(0x0518, 0x0148, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__IPU1_CSI1_PIXCLK \
+ IOMUX_PAD(0x0518, 0x0148, 3, 0x08B8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x0518, 0x0148, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__GPIO_3_17 \
+ IOMUX_PAD(0x0518, 0x0148, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__I2C3_SCL \
+ IOMUX_PAD(0x0518, 0x0148, 6 | IOMUX_CONFIG_SION, 0x0878, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__PL301_SIM_MX6DL_PER1_HBURST_1 \
+ IOMUX_PAD(0x0518, 0x0148, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__EPDC_VCOM_0 \
+ IOMUX_PAD(0x0518, 0x0148, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D18__WEIM_WEIM_D_18 \
+ IOMUX_PAD(0x051C, 0x014C, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__ECSPI1_MOSI \
+ IOMUX_PAD(0x051C, 0x014C, 1, 0x07E0, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_DI0_PIN7 \
+ IOMUX_PAD(0x051C, 0x014C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_CSI1_D_17 \
+ IOMUX_PAD(0x051C, 0x014C, 3, 0x08A4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x051C, 0x014C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__GPIO_3_18 \
+ IOMUX_PAD(0x051C, 0x014C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__I2C3_SDA \
+ IOMUX_PAD(0x051C, 0x014C, 6 | IOMUX_CONFIG_SION, 0x087C, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__PL301_SIM_MX6DL_PER1_HBURST_2 \
+ IOMUX_PAD(0x051C, 0x014C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__EPDC_VCOM_1 \
+ IOMUX_PAD(0x051C, 0x014C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D19__WEIM_WEIM_D_19 \
+ IOMUX_PAD(0x0520, 0x0150, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__ECSPI1_SS1 \
+ IOMUX_PAD(0x0520, 0x0150, 1, 0x07E8, 1, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__IPU1_DI0_PIN8 \
+ IOMUX_PAD(0x0520, 0x0150, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__IPU1_CSI1_D_16 \
+ IOMUX_PAD(0x0520, 0x0150, 3, 0x08A0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__UART1_CTS \
+ IOMUX_PAD(0x0520, 0x0150, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__UART1_RTS \
+ IOMUX_PAD(0x0520, 0x0150, 4, 0x08F8, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__GPIO_3_19 \
+ IOMUX_PAD(0x0520, 0x0150, 5, 0x0000, 0, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__EPIT1_EPITO \
+ IOMUX_PAD(0x0520, 0x0150, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__PL301_SIM_MX6DL_PER1_HRESP \
+ IOMUX_PAD(0x0520, 0x0150, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__EPDC_SDDO_12 \
+ IOMUX_PAD(0x0520, 0x0150, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D20__WEIM_WEIM_D_20 \
+ IOMUX_PAD(0x0524, 0x0154, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__ECSPI4_SS0 \
+ IOMUX_PAD(0x0524, 0x0154, 1, 0x0808, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__IPU1_DI0_PIN16 \
+ IOMUX_PAD(0x0524, 0x0154, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__IPU1_CSI1_D_15 \
+ IOMUX_PAD(0x0524, 0x0154, 3, 0x089C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__UART1_CTS \
+ IOMUX_PAD(0x0524, 0x0154, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__UART1_RTS \
+ IOMUX_PAD(0x0524, 0x0154, 4, 0x08F8, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__GPIO_3_20 \
+ IOMUX_PAD(0x0524, 0x0154, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__EPIT2_EPITO \
+ IOMUX_PAD(0x0524, 0x0154, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__TPSMP_HTRANS_1 \
+ IOMUX_PAD(0x0524, 0x0154, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D21__WEIM_WEIM_D_21 \
+ IOMUX_PAD(0x0528, 0x0158, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__ECSPI4_SCLK \
+ IOMUX_PAD(0x0528, 0x0158, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__IPU1_DI0_PIN17 \
+ IOMUX_PAD(0x0528, 0x0158, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__IPU1_CSI1_D_11 \
+ IOMUX_PAD(0x0528, 0x0158, 3, 0x088C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x0528, 0x0158, 4, 0x0920, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__GPIO_3_21 \
+ IOMUX_PAD(0x0528, 0x0158, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__I2C1_SCL \
+ IOMUX_PAD(0x0528, 0x0158, 6 | IOMUX_CONFIG_SION, 0x0868, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__SPDIF_IN1 \
+ IOMUX_PAD(0x0528, 0x0158, 7, 0x08F0, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D22__WEIM_WEIM_D_22 \
+ IOMUX_PAD(0x052C, 0x015C, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__ECSPI4_MISO \
+ IOMUX_PAD(0x052C, 0x015C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__IPU1_DI0_PIN1 \
+ IOMUX_PAD(0x052C, 0x015C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__IPU1_CSI1_D_10 \
+ IOMUX_PAD(0x052C, 0x015C, 3, 0x0888, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x052C, 0x015C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__GPIO_3_22 \
+ IOMUX_PAD(0x052C, 0x015C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__SPDIF_OUT1 \
+ IOMUX_PAD(0x052C, 0x015C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__PL301_SIM_MX6DL_PER1_HWRITE \
+ IOMUX_PAD(0x052C, 0x015C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__EPDC_SDCE_6 \
+ IOMUX_PAD(0x052C, 0x015C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D23__WEIM_WEIM_D_23 \
+ IOMUX_PAD(0x0530, 0x0160, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI0_D0_CS \
+ IOMUX_PAD(0x0530, 0x0160, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART3_CTS \
+ IOMUX_PAD(0x0530, 0x0160, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART3_RTS \
+ IOMUX_PAD(0x0530, 0x0160, 2, 0x0908, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART1_DCD \
+ IOMUX_PAD(0x0530, 0x0160, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_CSI1_DATA_EN \
+ IOMUX_PAD(0x0530, 0x0160, 4, 0x08B0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__GPIO_3_23 \
+ IOMUX_PAD(0x0530, 0x0160, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x0530, 0x0160, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI1_PIN14 \
+ IOMUX_PAD(0x0530, 0x0160, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__EPDC_SDDO_11 \
+ IOMUX_PAD(0x0530, 0x0160, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D24__WEIM_WEIM_D_24 \
+ IOMUX_PAD(0x0534, 0x0164, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI4_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART3_TXD \
+ IOMUX_PAD(0x0534, 0x0164, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART3_RXD \
+ IOMUX_PAD(0x0534, 0x0164, 2, 0x090C, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI1_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 3, 0x07EC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI2_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__GPIO_3_24 \
+ IOMUX_PAD(0x0534, 0x0164, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x0534, 0x0164, 6, 0x07BC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART1_DTR \
+ IOMUX_PAD(0x0534, 0x0164, 7, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__EPDC_SDCE_7 \
+ IOMUX_PAD(0x0534, 0x0164, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D25__WEIM_WEIM_D_25 \
+ IOMUX_PAD(0x0538, 0x0168, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI4_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART3_TXD \
+ IOMUX_PAD(0x0538, 0x0168, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART3_RXD \
+ IOMUX_PAD(0x0538, 0x0168, 2, 0x090C, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI1_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 3, 0x07F0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI2_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__GPIO_3_25 \
+ IOMUX_PAD(0x0538, 0x0168, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x0538, 0x0168, 6, 0x07B8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART1_DSR \
+ IOMUX_PAD(0x0538, 0x0168, 7, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__EPDC_SDCE_8 \
+ IOMUX_PAD(0x0538, 0x0168, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D26__WEIM_WEIM_D_26 \
+ IOMUX_PAD(0x053C, 0x016C, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_DI1_PIN11 \
+ IOMUX_PAD(0x053C, 0x016C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_CSI0_D_1 \
+ IOMUX_PAD(0x053C, 0x016C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_CSI1_D_14 \
+ IOMUX_PAD(0x053C, 0x016C, 3, 0x0898, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__UART2_TXD \
+ IOMUX_PAD(0x053C, 0x016C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__UART2_RXD \
+ IOMUX_PAD(0x053C, 0x016C, 4, 0x0904, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__GPIO_3_26 \
+ IOMUX_PAD(0x053C, 0x016C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_SISG_2 \
+ IOMUX_PAD(0x053C, 0x016C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_DISP1_DAT_22 \
+ IOMUX_PAD(0x053C, 0x016C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__EPDC_SDOED \
+ IOMUX_PAD(0x053C, 0x016C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D27__WEIM_WEIM_D_27 \
+ IOMUX_PAD(0x0540, 0x0170, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_DI1_PIN13 \
+ IOMUX_PAD(0x0540, 0x0170, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_CSI0_D_0 \
+ IOMUX_PAD(0x0540, 0x0170, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_CSI1_D_13 \
+ IOMUX_PAD(0x0540, 0x0170, 3, 0x0894, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__UART2_TXD \
+ IOMUX_PAD(0x0540, 0x0170, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__UART2_RXD \
+ IOMUX_PAD(0x0540, 0x0170, 4, 0x0904, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__GPIO_3_27 \
+ IOMUX_PAD(0x0540, 0x0170, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_SISG_3 \
+ IOMUX_PAD(0x0540, 0x0170, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_DISP1_DAT_23 \
+ IOMUX_PAD(0x0540, 0x0170, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__EPDC_SDOE \
+ IOMUX_PAD(0x0540, 0x0170, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D28__WEIM_WEIM_D_28 \
+ IOMUX_PAD(0x0544, 0x0174, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__I2C1_SDA \
+ IOMUX_PAD(0x0544, 0x0174, 1 | IOMUX_CONFIG_SION, 0x086C, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__ECSPI4_MOSI \
+ IOMUX_PAD(0x0544, 0x0174, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_CSI1_D_12 \
+ IOMUX_PAD(0x0544, 0x0174, 3, 0x0890, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__UART2_CTS \
+ IOMUX_PAD(0x0544, 0x0174, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__UART2_RTS \
+ IOMUX_PAD(0x0544, 0x0174, 4, 0x0900, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__GPIO_3_28 \
+ IOMUX_PAD(0x0544, 0x0174, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_EXT_TRIG \
+ IOMUX_PAD(0x0544, 0x0174, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_DI0_PIN13 \
+ IOMUX_PAD(0x0544, 0x0174, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__EPDC_PWRCTRL_3 \
+ IOMUX_PAD(0x0544, 0x0174, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D29__WEIM_WEIM_D_29 \
+ IOMUX_PAD(0x0548, 0x0178, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x0548, 0x0178, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__ECSPI4_SS0 \
+ IOMUX_PAD(0x0548, 0x0178, 2, 0x0808, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__UART2_CTS \
+ IOMUX_PAD(0x0548, 0x0178, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__UART2_RTS \
+ IOMUX_PAD(0x0548, 0x0178, 4, 0x0900, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__GPIO_3_29 \
+ IOMUX_PAD(0x0548, 0x0178, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_CSI1_VSYNC \
+ IOMUX_PAD(0x0548, 0x0178, 6, 0x08BC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_DI0_PIN14 \
+ IOMUX_PAD(0x0548, 0x0178, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__EPDC_PWRWAKE \
+ IOMUX_PAD(0x0548, 0x0178, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D30__WEIM_WEIM_D_30 \
+ IOMUX_PAD(0x054C, 0x017C, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_DISP1_DAT_21 \
+ IOMUX_PAD(0x054C, 0x017C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_DI0_PIN11 \
+ IOMUX_PAD(0x054C, 0x017C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_CSI0_D_3 \
+ IOMUX_PAD(0x054C, 0x017C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__UART3_CTS \
+ IOMUX_PAD(0x054C, 0x017C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__UART3_RTS \
+ IOMUX_PAD(0x054C, 0x017C, 4, 0x0908, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__GPIO_3_30 \
+ IOMUX_PAD(0x054C, 0x017C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x054C, 0x017C, 6, 0x0924, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__PL301_SIM_MX6DL_PER1_HPROT_0 \
+ IOMUX_PAD(0x054C, 0x017C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__EPDC_SDOEZ \
+ IOMUX_PAD(0x054C, 0x017C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D31__WEIM_WEIM_D_31 \
+ IOMUX_PAD(0x0550, 0x0180, 0, 0x0000, 0, MX6DL_WEIM_NOR_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_DISP1_DAT_20 \
+ IOMUX_PAD(0x0550, 0x0180, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_DI0_PIN12 \
+ IOMUX_PAD(0x0550, 0x0180, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_CSI0_D_2 \
+ IOMUX_PAD(0x0550, 0x0180, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__UART3_CTS \
+ IOMUX_PAD(0x0550, 0x0180, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__UART3_RTS \
+ IOMUX_PAD(0x0550, 0x0180, 4, 0x0908, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__GPIO_3_31 \
+ IOMUX_PAD(0x0550, 0x0180, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x0550, 0x0180, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__PL301_SIM_MX6DL_PER1_HPROT_1 \
+ IOMUX_PAD(0x0550, 0x0180, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__EPDC_SDCLK \
+ IOMUX_PAD(0x0550, 0x0180, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x0550, 0x0180, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 \
+ IOMUX_PAD(0x0554, 0x0184, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__IPU1_DISP1_DAT_9 \
+ IOMUX_PAD(0x0554, 0x0184, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__IPU1_CSI1_D_9 \
+ IOMUX_PAD(0x0554, 0x0184, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__MIPI_CORE_DPHY_TEST_OUT_2 \
+ IOMUX_PAD(0x0554, 0x0184, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__GPIO_3_0 \
+ IOMUX_PAD(0x0554, 0x0184, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__TPSMP_HDATA_14 \
+ IOMUX_PAD(0x0554, 0x0184, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__SRC_BT_CFG_0 \
+ IOMUX_PAD(0x0554, 0x0184, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__EPDC_SDCLKN \
+ IOMUX_PAD(0x0554, 0x0184, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 \
+ IOMUX_PAD(0x0558, 0x0188, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__IPU1_DISP1_DAT_8 \
+ IOMUX_PAD(0x0558, 0x0188, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__IPU1_CSI1_D_8 \
+ IOMUX_PAD(0x0558, 0x0188, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__MIPI_CORE_DPHY_TEST_OUT_3 \
+ IOMUX_PAD(0x0558, 0x0188, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__ANATOP_USBPHY1_TSTI_TX_LS_MODE \
+ IOMUX_PAD(0x0558, 0x0188, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__GPIO_3_1 \
+ IOMUX_PAD(0x0558, 0x0188, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__TPSMP_HDATA_15 \
+ IOMUX_PAD(0x0558, 0x0188, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__SRC_BT_CFG_1 \
+ IOMUX_PAD(0x0558, 0x0188, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__EPDC_SDLE \
+ IOMUX_PAD(0x0558, 0x0188, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 \
+ IOMUX_PAD(0x055C, 0x018C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x055C, 0x018C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__IPU1_CSI1_DATA_EN \
+ IOMUX_PAD(0x055C, 0x018C, 2, 0x08B0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__MIPI_CORE_DPHY_TEST_OUT_12 \
+ IOMUX_PAD(0x055C, 0x018C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__GPIO_3_10 \
+ IOMUX_PAD(0x055C, 0x018C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__TPSMP_HDATA_24 \
+ IOMUX_PAD(0x055C, 0x018C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__SRC_BT_CFG_10 \
+ IOMUX_PAD(0x055C, 0x018C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__EPDC_SDDO_1 \
+ IOMUX_PAD(0x055C, 0x018C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 \
+ IOMUX_PAD(0x0560, 0x0190, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x0560, 0x0190, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__IPU1_CSI1_HSYNC \
+ IOMUX_PAD(0x0560, 0x0190, 2, 0x08B4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__MIPI_CORE_DPHY_TEST_OUT_13 \
+ IOMUX_PAD(0x0560, 0x0190, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__SDMA_DEBUG_EVT_CHN_LINES_6 \
+ IOMUX_PAD(0x0560, 0x0190, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__GPIO_3_11 \
+ IOMUX_PAD(0x0560, 0x0190, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__TPSMP_HDATA_25 \
+ IOMUX_PAD(0x0560, 0x0190, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__SRC_BT_CFG_11 \
+ IOMUX_PAD(0x0560, 0x0190, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__EPDC_SDDO_3 \
+ IOMUX_PAD(0x0560, 0x0190, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 \
+ IOMUX_PAD(0x0564, 0x0194, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x0564, 0x0194, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__IPU1_CSI1_VSYNC \
+ IOMUX_PAD(0x0564, 0x0194, 2, 0x08BC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__MIPI_CORE_DPHY_TEST_OUT_14 \
+ IOMUX_PAD(0x0564, 0x0194, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_LINES_3 \
+ IOMUX_PAD(0x0564, 0x0194, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__GPIO_3_12 \
+ IOMUX_PAD(0x0564, 0x0194, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__TPSMP_HDATA_26 \
+ IOMUX_PAD(0x0564, 0x0194, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__SRC_BT_CFG_12 \
+ IOMUX_PAD(0x0564, 0x0194, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__EPDC_SDDO_2 \
+ IOMUX_PAD(0x0564, 0x0194, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 \
+ IOMUX_PAD(0x0568, 0x0198, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x0568, 0x0198, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x0568, 0x0198, 2, 0x07D0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__MIPI_CORE_DPHY_TEST_OUT_15 \
+ IOMUX_PAD(0x0568, 0x0198, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_LINES_4 \
+ IOMUX_PAD(0x0568, 0x0198, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__GPIO_3_13 \
+ IOMUX_PAD(0x0568, 0x0198, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__TPSMP_HDATA_27 \
+ IOMUX_PAD(0x0568, 0x0198, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__SRC_BT_CFG_13 \
+ IOMUX_PAD(0x0568, 0x0198, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__EPDC_SDDO_13 \
+ IOMUX_PAD(0x0568, 0x0198, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 \
+ IOMUX_PAD(0x056C, 0x019C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__IPU1_DI1_D1_CS \
+ IOMUX_PAD(0x056C, 0x019C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__CCM_DI0_EXT_CLK \
+ IOMUX_PAD(0x056C, 0x019C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__MIPI_CORE_DPHY_TEST_OUT_16 \
+ IOMUX_PAD(0x056C, 0x019C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_LINES_5 \
+ IOMUX_PAD(0x056C, 0x019C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__GPIO_3_14 \
+ IOMUX_PAD(0x056C, 0x019C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__TPSMP_HDATA_28 \
+ IOMUX_PAD(0x056C, 0x019C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__SRC_BT_CFG_14 \
+ IOMUX_PAD(0x056C, 0x019C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__EPDC_SDDO_14 \
+ IOMUX_PAD(0x056C, 0x019C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__IPU1_DI1_PIN1 \
+ IOMUX_PAD(0x0570, 0x01A0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__IPU1_DI1_PIN4 \
+ IOMUX_PAD(0x0570, 0x01A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__MIPI_CORE_DPHY_TEST_OUT_17 \
+ IOMUX_PAD(0x0570, 0x01A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__GPIO_3_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__TPSMP_HDATA_29 \
+ IOMUX_PAD(0x0570, 0x01A0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__SRC_BT_CFG_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__EPDC_SDDO_9 \
+ IOMUX_PAD(0x0570, 0x01A0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__IPU1_DISP1_DAT_7 \
+ IOMUX_PAD(0x0574, 0x01A4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__IPU1_CSI1_D_7 \
+ IOMUX_PAD(0x0574, 0x01A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__MIPI_CORE_DPHY_TEST_OUT_4 \
+ IOMUX_PAD(0x0574, 0x01A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__ANATOP_USBPHY1_TSTI_TX_HS_MODE \
+ IOMUX_PAD(0x0574, 0x01A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__GPIO_3_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__TPSMP_HDATA_16 \
+ IOMUX_PAD(0x0574, 0x01A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__SRC_BT_CFG_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__EPDC_BDR_0 \
+ IOMUX_PAD(0x0574, 0x01A4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__IPU1_DISP1_DAT_6 \
+ IOMUX_PAD(0x0578, 0x01A8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__IPU1_CSI1_D_6 \
+ IOMUX_PAD(0x0578, 0x01A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__MIPI_CORE_DPHY_TEST_OUT_5 \
+ IOMUX_PAD(0x0578, 0x01A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__ANATOP_USBPHY1_TSTI_TX_HIZ \
+ IOMUX_PAD(0x0578, 0x01A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__GPIO_3_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__TPSMP_HDATA_17 \
+ IOMUX_PAD(0x0578, 0x01A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__SRC_BT_CFG_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__EPDC_BDR_1 \
+ IOMUX_PAD(0x0578, 0x01A8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__IPU1_DISP1_DAT_5 \
+ IOMUX_PAD(0x057C, 0x01AC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__IPU1_CSI1_D_5 \
+ IOMUX_PAD(0x057C, 0x01AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__MIPI_CORE_DPHY_TEST_OUT_6 \
+ IOMUX_PAD(0x057C, 0x01AC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__ANATOP_USBPHY1_TSTI_TX_EN \
+ IOMUX_PAD(0x057C, 0x01AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__GPIO_3_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__TPSMP_HDATA_18 \
+ IOMUX_PAD(0x057C, 0x01AC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__SRC_BT_CFG_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__EPDC_SDCE_0 \
+ IOMUX_PAD(0x057C, 0x01AC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__IPU1_DISP1_DAT_4 \
+ IOMUX_PAD(0x0580, 0x01B0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__IPU1_CSI1_D_4 \
+ IOMUX_PAD(0x0580, 0x01B0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__MIPI_CORE_DPHY_TEST_OUT_7 \
+ IOMUX_PAD(0x0580, 0x01B0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__ANATOP_USBPHY1_TSTI_TX_DP \
+ IOMUX_PAD(0x0580, 0x01B0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__GPIO_3_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__TPSMP_HDATA_19 \
+ IOMUX_PAD(0x0580, 0x01B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__SRC_BT_CFG_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__EPDC_SDCE_1 \
+ IOMUX_PAD(0x0580, 0x01B0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__IPU1_DISP1_DAT_3 \
+ IOMUX_PAD(0x0584, 0x01B4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__IPU1_CSI1_D_3 \
+ IOMUX_PAD(0x0584, 0x01B4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__MIPI_CORE_DPHY_TEST_OUT_8 \
+ IOMUX_PAD(0x0584, 0x01B4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__ANATOP_USBPHY1_TSTI_TX_DN \
+ IOMUX_PAD(0x0584, 0x01B4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__GPIO_3_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__TPSMP_HDATA_20 \
+ IOMUX_PAD(0x0584, 0x01B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__SRC_BT_CFG_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__EPDC_SDCE_2 \
+ IOMUX_PAD(0x0584, 0x01B4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__IPU1_DISP1_DAT_2 \
+ IOMUX_PAD(0x0588, 0x01B8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__IPU1_CSI1_D_2 \
+ IOMUX_PAD(0x0588, 0x01B8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__MIPI_CORE_DPHY_TEST_OUT_9 \
+ IOMUX_PAD(0x0588, 0x01B8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__GPIO_3_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__TPSMP_HDATA_21 \
+ IOMUX_PAD(0x0588, 0x01B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__SRC_BT_CFG_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__EPDC_SDCE_3 \
+ IOMUX_PAD(0x0588, 0x01B8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__IPU1_DISP1_DAT_1 \
+ IOMUX_PAD(0x058C, 0x01BC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__IPU1_CSI1_D_1 \
+ IOMUX_PAD(0x058C, 0x01BC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__MIPI_CORE_DPHY_TEST_OUT_10 \
+ IOMUX_PAD(0x058C, 0x01BC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__GPIO_3_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__TPSMP_HDATA_22 \
+ IOMUX_PAD(0x058C, 0x01BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__SRC_BT_CFG_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__EPDC_SDCE_4 \
+ IOMUX_PAD(0x058C, 0x01BC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__IPU1_DISP1_DAT_0 \
+ IOMUX_PAD(0x0590, 0x01C0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__IPU1_CSI1_D_0 \
+ IOMUX_PAD(0x0590, 0x01C0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__MIPI_CORE_DPHY_TEST_OUT_11 \
+ IOMUX_PAD(0x0590, 0x01C0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__GPIO_3_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__TPSMP_HDATA_23 \
+ IOMUX_PAD(0x0590, 0x01C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__SRC_BT_CFG_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__EPDC_SDCE_5 \
+ IOMUX_PAD(0x0590, 0x01C0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB0__WEIM_WEIM_EB_0 \
+ IOMUX_PAD(0x0594, 0x01C4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__IPU1_DISP1_DAT_11 \
+ IOMUX_PAD(0x0594, 0x01C4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__IPU1_CSI1_D_11 \
+ IOMUX_PAD(0x0594, 0x01C4, 2, 0x088C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__MIPI_CORE_DPHY_TEST_OUT_0 \
+ IOMUX_PAD(0x0594, 0x01C4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0594, 0x01C4, 4, 0x07D4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__GPIO_2_28 \
+ IOMUX_PAD(0x0594, 0x01C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__TPSMP_HDATA_12 \
+ IOMUX_PAD(0x0594, 0x01C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__SRC_BT_CFG_27 \
+ IOMUX_PAD(0x0594, 0x01C4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__EPDC_PWRCOM \
+ IOMUX_PAD(0x0594, 0x01C4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB1__WEIM_WEIM_EB_1 \
+ IOMUX_PAD(0x0598, 0x01C8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__IPU1_DISP1_DAT_10 \
+ IOMUX_PAD(0x0598, 0x01C8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__IPU1_CSI1_D_10 \
+ IOMUX_PAD(0x0598, 0x01C8, 2, 0x0888, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__MIPI_CORE_DPHY_TEST_OUT_1 \
+ IOMUX_PAD(0x0598, 0x01C8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__GPIO_2_29 \
+ IOMUX_PAD(0x0598, 0x01C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__TPSMP_HDATA_13 \
+ IOMUX_PAD(0x0598, 0x01C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__SRC_BT_CFG_28 \
+ IOMUX_PAD(0x0598, 0x01C8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__EPDC_SDSHR \
+ IOMUX_PAD(0x0598, 0x01C8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB2__WEIM_WEIM_EB_2 \
+ IOMUX_PAD(0x059C, 0x01CC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__ECSPI1_SS0 \
+ IOMUX_PAD(0x059C, 0x01CC, 1, 0x07E4, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x059C, 0x01CC, 2, 0x07D0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__IPU1_CSI1_D_19 \
+ IOMUX_PAD(0x059C, 0x01CC, 3, 0x08AC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x059C, 0x01CC, 4, 0x0860, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__GPIO_2_30 \
+ IOMUX_PAD(0x059C, 0x01CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__I2C2_SCL \
+ IOMUX_PAD(0x059C, 0x01CC, 6 | IOMUX_CONFIG_SION, 0x0870, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__SRC_BT_CFG_30 \
+ IOMUX_PAD(0x059C, 0x01CC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__EPDC_SDDO_5 \
+ IOMUX_PAD(0x059C, 0x01CC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB3__WEIM_WEIM_EB_3 \
+ IOMUX_PAD(0x05A0, 0x01D0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__ECSPI4_RDY \
+ IOMUX_PAD(0x05A0, 0x01D0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART3_CTS \
+ IOMUX_PAD(0x05A0, 0x01D0, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART3_RTS \
+ IOMUX_PAD(0x05A0, 0x01D0, 2, 0x0908, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART1_RI \
+ IOMUX_PAD(0x05A0, 0x01D0, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__IPU1_CSI1_HSYNC \
+ IOMUX_PAD(0x05A0, 0x01D0, 4, 0x08B4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__GPIO_2_31 \
+ IOMUX_PAD(0x05A0, 0x01D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x05A0, 0x01D0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__SRC_BT_CFG_31 \
+ IOMUX_PAD(0x05A0, 0x01D0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__EPDC_SDCE_0 \
+ IOMUX_PAD(0x05A0, 0x01D0, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x05A0, 0x01D0, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_LBA__WEIM_WEIM_LBA \
+ IOMUX_PAD(0x05A4, 0x01D4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__IPU1_DI1_PIN17 \
+ IOMUX_PAD(0x05A4, 0x01D4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__ECSPI2_SS1 \
+ IOMUX_PAD(0x05A4, 0x01D4, 2, 0x0804, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__GPIO_2_27 \
+ IOMUX_PAD(0x05A4, 0x01D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__TPSMP_HDATA_11 \
+ IOMUX_PAD(0x05A4, 0x01D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__SRC_BT_CFG_26 \
+ IOMUX_PAD(0x05A4, 0x01D4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__EPDC_SDDO_4 \
+ IOMUX_PAD(0x05A4, 0x01D4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_OE__WEIM_WEIM_OE \
+ IOMUX_PAD(0x05A8, 0x01D8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__IPU1_DI1_PIN7 \
+ IOMUX_PAD(0x05A8, 0x01D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__ECSPI2_MISO \
+ IOMUX_PAD(0x05A8, 0x01D8, 2, 0x07F8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__MIPI_CORE_DPHY_TEST_OUT_26 \
+ IOMUX_PAD(0x05A8, 0x01D8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__GPIO_2_25 \
+ IOMUX_PAD(0x05A8, 0x01D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__TPSMP_HDATA_9 \
+ IOMUX_PAD(0x05A8, 0x01D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__EPDC_PWRIRQ \
+ IOMUX_PAD(0x05A8, 0x01D8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_RW__WEIM_WEIM_RW \
+ IOMUX_PAD(0x05AC, 0x01DC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__IPU1_DI1_PIN8 \
+ IOMUX_PAD(0x05AC, 0x01DC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__ECSPI2_SS0 \
+ IOMUX_PAD(0x05AC, 0x01DC, 2, 0x0800, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__MIPI_CORE_DPHY_TEST_OUT_27 \
+ IOMUX_PAD(0x05AC, 0x01DC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__GPIO_2_26 \
+ IOMUX_PAD(0x05AC, 0x01DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__TPSMP_HDATA_10 \
+ IOMUX_PAD(0x05AC, 0x01DC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__SRC_BT_CFG_29 \
+ IOMUX_PAD(0x05AC, 0x01DC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__EPDC_SDDO_7 \
+ IOMUX_PAD(0x05AC, 0x01DC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_WAIT__WEIM_WEIM_WAIT \
+ IOMUX_PAD(0x05B0, 0x01E0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B \
+ IOMUX_PAD(0x05B0, 0x01E0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__GPIO_5_0 \
+ IOMUX_PAD(0x05B0, 0x01E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__TPSMP_HDATA_30 \
+ IOMUX_PAD(0x05B0, 0x01E0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__SRC_BT_CFG_25 \
+ IOMUX_PAD(0x05B0, 0x01E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_CRS_DV__ENET_RX_EN \
+ IOMUX_PAD(0x05B4, 0x01E4, 1, 0x0828, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__ESAI1_SCKT \
+ IOMUX_PAD(0x05B4, 0x01E4, 2, 0x0840, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x05B4, 0x01E4, 3, 0x08F4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__GPIO_1_25 \
+ IOMUX_PAD(0x05B4, 0x01E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__PHY_TDO \
+ IOMUX_PAD(0x05B4, 0x01E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__ANATOP_USBPHY1_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x05B4, 0x01E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_MDC__MLB_MLBDAT \
+ IOMUX_PAD(0x05B8, 0x01E8, 0, 0x08E0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ENET_MDC \
+ IOMUX_PAD(0x05B8, 0x01E8, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x05B8, 0x01E8, 2, 0x0858, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ENET_1588_EVENT1_IN \
+ IOMUX_PAD(0x05B8, 0x01E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__GPIO_1_31 \
+ IOMUX_PAD(0x05B8, 0x01E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ANATOP_USBPHY2_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x05B8, 0x01E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_MDIO__ENET_MDIO \
+ IOMUX_PAD(0x05BC, 0x01EC, 1, 0x0810, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__ESAI1_SCKR \
+ IOMUX_PAD(0x05BC, 0x01EC, 2, 0x083C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEVICE_3 \
+ IOMUX_PAD(0x05BC, 0x01EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT \
+ IOMUX_PAD(0x05BC, 0x01EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__GPIO_1_22 \
+ IOMUX_PAD(0x05BC, 0x01EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__SPDIF_PLOCK \
+ IOMUX_PAD(0x05BC, 0x01EC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK \
+ IOMUX_PAD(0x05C0, 0x01F0, 1, 0x0000, 0, MX6DL_ENET_REF_CLK_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__ESAI1_FSR \
+ IOMUX_PAD(0x05C0, 0x01F0, 2, 0x082C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 \
+ IOMUX_PAD(0x05C0, 0x01F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__GPIO_1_23 \
+ IOMUX_PAD(0x05C0, 0x01F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__SPDIF_SRCLK \
+ IOMUX_PAD(0x05C0, 0x01F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__ANATOP_USBPHY1_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x05C0, 0x01F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RX_ER__ANATOP_USBOTG_ID \
+ IOMUX_PAD(0x05C4, 0x01F4, 0, 0x0790, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ENET_RX_ER \
+ IOMUX_PAD(0x05C4, 0x01F4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ESAI1_HCKR \
+ IOMUX_PAD(0x05C4, 0x01F4, 2, 0x0834, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__SPDIF_IN1 \
+ IOMUX_PAD(0x05C4, 0x01F4, 3, 0x08F0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT \
+ IOMUX_PAD(0x05C4, 0x01F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__GPIO_1_24 \
+ IOMUX_PAD(0x05C4, 0x01F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__PHY_TDI \
+ IOMUX_PAD(0x05C4, 0x01F4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ANATOP_USBPHY1_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x05C4, 0x01F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RXD0__OSC32K_32K_OUT \
+ IOMUX_PAD(0x05C8, 0x01F8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ENET_RDATA_0 \
+ IOMUX_PAD(0x05C8, 0x01F8, 1, 0x0818, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ESAI1_HCKT \
+ IOMUX_PAD(0x05C8, 0x01F8, 2, 0x0838, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__SPDIF_OUT1 \
+ IOMUX_PAD(0x05C8, 0x01F8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__GPIO_1_27 \
+ IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__PHY_TMS \
+ IOMUX_PAD(0x05C8, 0x01F8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x05C8, 0x01F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RXD1__MLB_MLBSIG \
+ IOMUX_PAD(0x05CC, 0x01FC, 0, 0x08E4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ENET_RDATA_1 \
+ IOMUX_PAD(0x05CC, 0x01FC, 1, 0x081C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ESAI1_FST \
+ IOMUX_PAD(0x05CC, 0x01FC, 2, 0x0830, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT \
+ IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__GPIO_1_26 \
+ IOMUX_PAD(0x05CC, 0x01FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__PHY_TCK \
+ IOMUX_PAD(0x05CC, 0x01FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ANATOP_USBPHY1_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x05CC, 0x01FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TX_EN__ENET_TX_EN \
+ IOMUX_PAD(0x05D0, 0x0200, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x05D0, 0x0200, 2, 0x0850, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__GPIO_1_28 \
+ IOMUX_PAD(0x05D0, 0x0200, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__ANATOP_USBPHY2_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x05D0, 0x0200, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__I2C4_SCL \
+ IOMUX_PAD(0x05D0, 0x0200, 9 | IOMUX_CONFIG_SION, 0x0880, 0, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TXD0__ENET_TDATA_0 \
+ IOMUX_PAD(0x05D4, 0x0204, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x05D4, 0x0204, 2, 0x0854, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__GPIO_1_30 \
+ IOMUX_PAD(0x05D4, 0x0204, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__ANATOP_USBPHY2_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x05D4, 0x0204, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TXD1__MLB_MLBCLK \
+ IOMUX_PAD(0x05D8, 0x0208, 0, 0x08DC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ENET_TDATA_1 \
+ IOMUX_PAD(0x05D8, 0x0208, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x05D8, 0x0208, 2, 0x084C, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ENET_1588_EVENT0_IN \
+ IOMUX_PAD(0x05D8, 0x0208, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__GPIO_1_29 \
+ IOMUX_PAD(0x05D8, 0x0208, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ANATOP_USBPHY2_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x05D8, 0x0208, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__I2C4_SDA \
+ IOMUX_PAD(0x05D8, 0x0208, 9 | IOMUX_CONFIG_SION, 0x0884, 0, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_0__CCM_CLKO \
+ IOMUX_PAD(0x05DC, 0x020C, 0, 0x0000, 0, MX6DL_CCM_CLK0_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__KPP_COL_5 \
+ IOMUX_PAD(0x05DC, 0x020C, 2, 0x08C0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05DC, 0x020C, 3, 0x0794, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__EPIT1_EPITO \
+ IOMUX_PAD(0x05DC, 0x020C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__GPIO_1_0 \
+ IOMUX_PAD(0x05DC, 0x020C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x05DC, 0x020C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__SNVS_HP_WRAPPER_SNVS_VIO_5 \
+ IOMUX_PAD(0x05DC, 0x020C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_1__ESAI1_SCKR \
+ IOMUX_PAD(0x05E0, 0x0210, 0, 0x083C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__WDOG2_WDOG_B \
+ IOMUX_PAD(0x05E0, 0x0210, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__KPP_ROW_5 \
+ IOMUX_PAD(0x05E0, 0x0210, 2, 0x08CC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__USBOTG_ID \
+ IOMUX_PAD(0x05E0, 0x0210, 3, 0x0790, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__PWM2_PWMO \
+ IOMUX_PAD(0x05E0, 0x0210, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__GPIO_1_1 \
+ IOMUX_PAD(0x05E0, 0x0210, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__USDHC1_CD \
+ IOMUX_PAD(0x05E0, 0x0210, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__SRC_TESTER_ACK \
+ IOMUX_PAD(0x05E0, 0x0210, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_16__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x05E4, 0x0214, 0, 0x0850, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__ENET_1588_EVENT2_IN \
+ IOMUX_PAD(0x05E4, 0x0214, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x05E4, 0x0214, 0x12, 0x080C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__USDHC1_LCTL \
+ IOMUX_PAD(0x05E4, 0x0214, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__SPDIF_IN1 \
+ IOMUX_PAD(0x05E4, 0x0214, 4, 0x08F0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__GPIO_7_11 \
+ IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__I2C3_SDA \
+ IOMUX_PAD(0x05E4, 0x0214, 6 | IOMUX_CONFIG_SION, 0x087C, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__SJC_DE_B \
+ IOMUX_PAD(0x05E4, 0x0214, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_17__ESAI1_TX0 \
+ IOMUX_PAD(0x05E8, 0x0218, 0, 0x0844, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__ENET_1588_EVENT3_IN \
+ IOMUX_PAD(0x05E8, 0x0218, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__CCM_PMIC_RDY \
+ IOMUX_PAD(0x05E8, 0x0218, 2, 0x07D4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x05E8, 0x0218, 3, 0x08E8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SPDIF_OUT1 \
+ IOMUX_PAD(0x05E8, 0x0218, 4, 0x0000, 0, MX6DL_SPDIF_OUT_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__GPIO_7_12 \
+ IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SJC_JTAG_ACT \
+ IOMUX_PAD(0x05E8, 0x0218, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_18__ESAI1_TX1 \
+ IOMUX_PAD(0x05EC, 0x021C, 0, 0x0848, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__ENET_RX_CLK \
+ IOMUX_PAD(0x05EC, 0x021C, 1, 0x0814, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__USDHC3_VSELECT \
+ IOMUX_PAD(0x05EC, 0x021C, 2, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x05EC, 0x021C, 3, 0x08EC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05EC, 0x021C, 4, 0x0794, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__GPIO_7_13 \
+ IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SNVS_HP_WRAPPER_SNVS_VIO_5_CTL \
+ IOMUX_PAD(0x05EC, 0x021C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SRC_SYSTEM_RST \
+ IOMUX_PAD(0x05EC, 0x021C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_19__KPP_COL_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 0, 0x08C0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ENET_1588_EVENT0_OUT \
+ IOMUX_PAD(0x05F0, 0x0220, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__SPDIF_OUT1 \
+ IOMUX_PAD(0x05F0, 0x0220, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__CCM_CLKO \
+ IOMUX_PAD(0x05F0, 0x0220, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ECSPI1_RDY \
+ IOMUX_PAD(0x05F0, 0x0220, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__GPIO_4_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ENET_TX_ER \
+ IOMUX_PAD(0x05F0, 0x0220, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__SRC_INT_BOOT \
+ IOMUX_PAD(0x05F0, 0x0220, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_2__ESAI1_FST \
+ IOMUX_PAD(0x05F4, 0x0224, 0, 0x0830, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 \
+ IOMUX_PAD(0x05F4, 0x0224, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__KPP_ROW_6 \
+ IOMUX_PAD(0x05F4, 0x0224, 2, 0x08D0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__CCM_CCM_OUT_1 \
+ IOMUX_PAD(0x05F4, 0x0224, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 \
+ IOMUX_PAD(0x05F4, 0x0224, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__GPIO_1_2 \
+ IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__USDHC2_WP \
+ IOMUX_PAD(0x05F4, 0x0224, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__MLB_MLBDAT \
+ IOMUX_PAD(0x05F4, 0x0224, 7, 0x08E0, 1, MX6DL_MLB150_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_3__ESAI1_HCKR \
+ IOMUX_PAD(0x05F8, 0x0228, 0, 0x0834, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 \
+ IOMUX_PAD(0x05F8, 0x0228, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__I2C3_SCL \
+ IOMUX_PAD(0x05F8, 0x0228, 2 | IOMUX_CONFIG_SION, 0x0878, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x05F8, 0x0228, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__CCM_CLKO2 \
+ IOMUX_PAD(0x05F8, 0x0228, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__GPIO_1_3 \
+ IOMUX_PAD(0x05F8, 0x0228, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x05F8, 0x0228, 6, 0x0924, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__MLB_MLBCLK \
+ IOMUX_PAD(0x05F8, 0x0228, 7, 0x08DC, 1, MX6DL_MLB150_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_4__ESAI1_HCKT \
+ IOMUX_PAD(0x05FC, 0x022C, 0, 0x0838, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 \
+ IOMUX_PAD(0x05FC, 0x022C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__KPP_COL_7 \
+ IOMUX_PAD(0x05FC, 0x022C, 2, 0x08C8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__CCM_CCM_OUT_2 \
+ IOMUX_PAD(0x05FC, 0x022C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 \
+ IOMUX_PAD(0x05FC, 0x022C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__GPIO_1_4 \
+ IOMUX_PAD(0x05FC, 0x022C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__USDHC2_CD \
+ IOMUX_PAD(0x05FC, 0x022C, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__OCOTP_CTRL_WRAPPER_FUSE_LATCHED \
+ IOMUX_PAD(0x05FC, 0x022C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_5__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x0600, 0x0230, 0, 0x084C, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 \
+ IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__KPP_ROW_7 \
+ IOMUX_PAD(0x0600, 0x0230, 2, 0x08D4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__CCM_CLKO \
+ IOMUX_PAD(0x0600, 0x0230, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 \
+ IOMUX_PAD(0x0600, 0x0230, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__GPIO_1_5 \
+ IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__I2C3_SCL \
+ IOMUX_PAD(0x0600, 0x0230, 6 | IOMUX_CONFIG_SION, 0x0878, 2, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__SIMBA_EVENTI \
+ IOMUX_PAD(0x0600, 0x0230, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ IOMUX_PAD(0x0604, 0x0234, 1 | IOMUX_CONFIG_SION, 0x0000, 0, ENET_IRQ_PAD_CTRL)
+#else
+#define MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ IOMUX_PAD(0x0604, 0x0234, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__ESAI1_SCKT \
+ IOMUX_PAD(0x0604, 0x0234, 0, 0x0840, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__I2C3_SDA \
+ IOMUX_PAD(0x0604, 0x0234, 2 | IOMUX_CONFIG_SION, 0x087C, 2, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__CCM_CCM_OUT_0 \
+ IOMUX_PAD(0x0604, 0x0234, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__CSU_CSU_INT_DEB \
+ IOMUX_PAD(0x0604, 0x0234, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__GPIO_1_6 \
+ IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__USDHC2_LCTL \
+ IOMUX_PAD(0x0604, 0x0234, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__MLB_MLBSIG \
+ IOMUX_PAD(0x0604, 0x0234, 7, 0x08E4, 1, MX6DL_MLB150_PAD_CTRL)
+#endif
+
+#define MX6DL_PAD_GPIO_7__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x0608, 0x0238, 0, 0x0854, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__EPIT1_EPITO \
+ IOMUX_PAD(0x0608, 0x0238, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__CAN1_TXCAN \
+ IOMUX_PAD(0x0608, 0x0238, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__UART2_TXD \
+ IOMUX_PAD(0x0608, 0x0238, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__UART2_RXD \
+ IOMUX_PAD(0x0608, 0x0238, 4, 0x0904, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__GPIO_1_7 \
+ IOMUX_PAD(0x0608, 0x0238, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__SPDIF_PLOCK \
+ IOMUX_PAD(0x0608, 0x0238, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__USBOH3_OTGUSB_HOST_MODE \
+ IOMUX_PAD(0x0608, 0x0238, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__I2C4_SCL \
+ IOMUX_PAD(0x0608, 0x0238, 8 | IOMUX_CONFIG_SION, 0x0880, 1, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_8__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x060C, 0x023C, 0, 0x0858, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT \
+ IOMUX_PAD(0x060C, 0x023C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__EPIT2_EPITO \
+ IOMUX_PAD(0x060C, 0x023C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__CAN1_RXCAN \
+ IOMUX_PAD(0x060C, 0x023C, 3, 0x07C8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__UART2_TXD \
+ IOMUX_PAD(0x060C, 0x023C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__UART2_RXD \
+ IOMUX_PAD(0x060C, 0x023C, 4, 0x0904, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__GPIO_1_8 \
+ IOMUX_PAD(0x060C, 0x023C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__SPDIF_SRCLK \
+ IOMUX_PAD(0x060C, 0x023C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__USBOH3_OTGUSB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x060C, 0x023C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__I2C4_SDA \
+ IOMUX_PAD(0x060C, 0x023C, 8 | IOMUX_CONFIG_SION, 0x0884, 1, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_9__ESAI1_FSR \
+ IOMUX_PAD(0x0610, 0x0240, 0, 0x082C, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__WDOG1_WDOG_B \
+ IOMUX_PAD(0x0610, 0x0240, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__KPP_COL_6 \
+ IOMUX_PAD(0x0610, 0x0240, 2, 0x08C4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__CCM_REF_EN_B \
+ IOMUX_PAD(0x0610, 0x0240, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__PWM1_PWMO \
+ IOMUX_PAD(0x0610, 0x0240, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__GPIO_1_9 \
+ IOMUX_PAD(0x0610, 0x0240, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__USDHC1_WP \
+ IOMUX_PAD(0x0610, 0x0240, 6, 0x092C, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__SRC_EARLY_RST \
+ IOMUX_PAD(0x0610, 0x0240, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_MOD__SJC_MOD \
+ IOMUX_PAD(0x0614, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TCK__SJC_TCK \
+ IOMUX_PAD(0x0618, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TDI__SJC_TDI \
+ IOMUX_PAD(0x061C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TDO__SJC_TDO \
+ IOMUX_PAD(0x0620, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TMS__SJC_TMS \
+ IOMUX_PAD(0x0624, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TRSTB__SJC_TRSTB \
+ IOMUX_PAD(0x0628, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL0__ECSPI1_SCLK \
+ IOMUX_PAD(0x062C, 0x0244, 0, 0x07D8, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__ENET_RDATA_3 \
+ IOMUX_PAD(0x062C, 0x0244, 1, 0x0824, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x062C, 0x0244, 2, 0x07C0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__KPP_COL_0 \
+ IOMUX_PAD(0x062C, 0x0244, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__UART4_TXD \
+ IOMUX_PAD(0x062C, 0x0244, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__UART4_RXD \
+ IOMUX_PAD(0x062C, 0x0244, 4, 0x0914, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__GPIO_4_6 \
+ IOMUX_PAD(0x062C, 0x0244, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x062C, 0x0244, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__SRC_ANY_PU_RST \
+ IOMUX_PAD(0x062C, 0x0244, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL1__ECSPI1_MISO \
+ IOMUX_PAD(0x0630, 0x0248, 0, 0x07DC, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__ENET_MDIO \
+ IOMUX_PAD(0x0630, 0x0248, 1, 0x0810, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x0630, 0x0248, 2, 0x07C4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__KPP_COL_1 \
+ IOMUX_PAD(0x0630, 0x0248, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__UART5_TXD \
+ IOMUX_PAD(0x0630, 0x0248, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__UART5_RXD \
+ IOMUX_PAD(0x0630, 0x0248, 4, 0x091C, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__GPIO_4_8 \
+ IOMUX_PAD(0x0630, 0x0248, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__USDHC1_VSELECT \
+ IOMUX_PAD(0x0630, 0x0248, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__PL301_SIM_MX6DL_PER1_HADDR_1 \
+ IOMUX_PAD(0x0630, 0x0248, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL2__ECSPI1_SS1 \
+ IOMUX_PAD(0x0634, 0x024C, 0, 0x07E8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__ENET_RDATA_2 \
+ IOMUX_PAD(0x0634, 0x024C, 1, 0x0820, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__CAN1_TXCAN \
+ IOMUX_PAD(0x0634, 0x024C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__KPP_COL_2 \
+ IOMUX_PAD(0x0634, 0x024C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__ENET_MDC \
+ IOMUX_PAD(0x0634, 0x024C, 4, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__GPIO_4_10 \
+ IOMUX_PAD(0x0634, 0x024C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__USBOH3_H1USB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x0634, 0x024C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__PL301_SIM_MX6DL_PER1_HADDR_3 \
+ IOMUX_PAD(0x0634, 0x024C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL3__ECSPI1_SS3 \
+ IOMUX_PAD(0x0638, 0x0250, 0, 0x07F0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__ENET_CRS \
+ IOMUX_PAD(0x0638, 0x0250, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x0638, 0x0250, 2 | IOMUX_CONFIG_SION, 0x0860, 1, \
+ MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__KPP_COL_3 \
+ IOMUX_PAD(0x0638, 0x0250, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__I2C2_SCL \
+ IOMUX_PAD(0x0638, 0x0250, 4 | IOMUX_CONFIG_SION, 0x0870, 1, \
+ MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__GPIO_4_12 \
+ IOMUX_PAD(0x0638, 0x0250, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__SPDIF_IN1 \
+ IOMUX_PAD(0x0638, 0x0250, 6, 0x08F0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__PL301_SIM_MX6DL_PER1_HADDR_5 \
+ IOMUX_PAD(0x0638, 0x0250, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL4__CAN2_TXCAN \
+ IOMUX_PAD(0x063C, 0x0254, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__IPU1_SISG_4 \
+ IOMUX_PAD(0x063C, 0x0254, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x063C, 0x0254, 2, 0x0920, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__KPP_COL_4 \
+ IOMUX_PAD(0x063C, 0x0254, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__UART5_CTS \
+ IOMUX_PAD(0x063C, 0x0254, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__UART5_RTS \
+ IOMUX_PAD(0x063C, 0x0254, 4, 0x0918, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__GPIO_4_14 \
+ IOMUX_PAD(0x063C, 0x0254, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__MMDC_MMDC_DEBUG_49 \
+ IOMUX_PAD(0x063C, 0x0254, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__PL301_SIM_MX6DL_PER1_HADDR_7 \
+ IOMUX_PAD(0x063C, 0x0254, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW0__ECSPI1_MOSI \
+ IOMUX_PAD(0x0640, 0x0258, 0, 0x07E0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__ENET_TDATA_3 \
+ IOMUX_PAD(0x0640, 0x0258, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x0640, 0x0258, 2, 0x07B4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__KPP_ROW_0 \
+ IOMUX_PAD(0x0640, 0x0258, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__UART4_TXD \
+ IOMUX_PAD(0x0640, 0x0258, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__UART4_RXD \
+ IOMUX_PAD(0x0640, 0x0258, 4, 0x0914, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__GPIO_4_7 \
+ IOMUX_PAD(0x0640, 0x0258, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x0640, 0x0258, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__PL301_SIM_MX6DL_PER1_HADDR_0 \
+ IOMUX_PAD(0x0640, 0x0258, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW1__ECSPI1_SS0 \
+ IOMUX_PAD(0x0644, 0x025C, 0, 0x07E4, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__ENET_COL \
+ IOMUX_PAD(0x0644, 0x025C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x0644, 0x025C, 2, 0x07B0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__KPP_ROW_1 \
+ IOMUX_PAD(0x0644, 0x025C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__UART5_TXD \
+ IOMUX_PAD(0x0644, 0x025C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__UART5_RXD \
+ IOMUX_PAD(0x0644, 0x025C, 4, 0x091C, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__GPIO_4_9 \
+ IOMUX_PAD(0x0644, 0x025C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__USDHC2_VSELECT \
+ IOMUX_PAD(0x0644, 0x025C, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__PL301_SIM_MX6DL_PER1_HADDR_2 \
+ IOMUX_PAD(0x0644, 0x025C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW2__ECSPI1_SS2 \
+ IOMUX_PAD(0x0648, 0x0260, 0, 0x07EC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__ENET_TDATA_2 \
+ IOMUX_PAD(0x0648, 0x0260, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__CAN1_RXCAN \
+ IOMUX_PAD(0x0648, 0x0260, 2, 0x07C8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__KPP_ROW_2 \
+ IOMUX_PAD(0x0648, 0x0260, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__USDHC2_VSELECT \
+ IOMUX_PAD(0x0648, 0x0260, 4, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__GPIO_4_11 \
+ IOMUX_PAD(0x0648, 0x0260, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x0648, 0x0260, 6, 0x085C, 1, MX6DL_HDMICEC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__PL301_SIM_MX6DL_PER1_HADDR_4 \
+ IOMUX_PAD(0x0648, 0x0260, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW3__OSC32K_32K_OUT \
+ IOMUX_PAD(0x064C, 0x0264, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x064C, 0x0264, 1, 0x0794, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x064C, 0x0264, 2 | IOMUX_CONFIG_SION, 0x0864, 1, \
+ MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__KPP_ROW_3 \
+ IOMUX_PAD(0x064C, 0x0264, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__I2C2_SDA \
+ IOMUX_PAD(0x064C, 0x0264, 4 | IOMUX_CONFIG_SION, 0x0874, 1, \
+ MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__GPIO_4_13 \
+ IOMUX_PAD(0x064C, 0x0264, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__USDHC1_VSELECT \
+ IOMUX_PAD(0x064C, 0x0264, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__PL301_SIM_MX6DL_PER1_HADDR_6 \
+ IOMUX_PAD(0x064C, 0x0264, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW4__CAN2_RXCAN \
+ IOMUX_PAD(0x0650, 0x0268, 0, 0x07CC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__IPU1_SISG_5 \
+ IOMUX_PAD(0x0650, 0x0268, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x0650, 0x0268, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__KPP_ROW_4 \
+ IOMUX_PAD(0x0650, 0x0268, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__UART5_CTS \
+ IOMUX_PAD(0x0650, 0x0268, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__UART5_RTS \
+ IOMUX_PAD(0x0650, 0x0268, 4, 0x0918, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__GPIO_4_15 \
+ IOMUX_PAD(0x0650, 0x0268, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__MMDC_MMDC_DEBUG_50 \
+ IOMUX_PAD(0x0650, 0x0268, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__PL301_SIM_MX6DL_PER1_HADDR_8 \
+ IOMUX_PAD(0x0650, 0x0268, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_ALE__RAWNAND_ALE \
+ IOMUX_PAD(0x0654, 0x026C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USDHC4_RST \
+ IOMUX_PAD(0x0654, 0x026C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_0 \
+ IOMUX_PAD(0x0654, 0x026C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USBOH3_UH3_DFD_OUT_12 \
+ IOMUX_PAD(0x0654, 0x026C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USBOH3_UH2_DFD_OUT_12 \
+ IOMUX_PAD(0x0654, 0x026C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__GPIO_6_8 \
+ IOMUX_PAD(0x0654, 0x026C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__MIPI_CORE_DPHY_TEST_IN_24 \
+ IOMUX_PAD(0x0654, 0x026C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USDHC3_CLKI \
+ IOMUX_PAD(0x0654, 0x026C, 8, 0x0934, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CLE__RAWNAND_CLE \
+ IOMUX_PAD(0x0658, 0x0270, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CLE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_31 \
+ IOMUX_PAD(0x0658, 0x0270, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USBOH3_UH3_DFD_OUT_11 \
+ IOMUX_PAD(0x0658, 0x0270, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USBOH3_UH2_DFD_OUT_11 \
+ IOMUX_PAD(0x0658, 0x0270, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__GPIO_6_7 \
+ IOMUX_PAD(0x0658, 0x0270, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__MIPI_CORE_DPHY_TEST_IN_23 \
+ IOMUX_PAD(0x0658, 0x0270, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USDHC3_CLKO \
+ IOMUX_PAD(0x0658, 0x0270, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N \
+ IOMUX_PAD(0x065C, 0x0274, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS0__USBOH3_UH3_DFD_OUT_15 \
+ IOMUX_PAD(0x065C, 0x0274, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__USBOH3_UH2_DFD_OUT_15 \
+ IOMUX_PAD(0x065C, 0x0274, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__GPIO_6_11 \
+ IOMUX_PAD(0x065C, 0x0274, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__USDHC1_CLKO \
+ IOMUX_PAD(0x065C, 0x0274, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N \
+ IOMUX_PAD(0x0660, 0x0278, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS1__USDHC4_VSELECT \
+ IOMUX_PAD(0x0660, 0x0278, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__USDHC3_VSELECT \
+ IOMUX_PAD(0x0660, 0x0278, 2, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_3 \
+ IOMUX_PAD(0x0660, 0x0278, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__GPIO_6_14 \
+ IOMUX_PAD(0x0660, 0x0278, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__PL301_SIM_MX6DL_PER1_HREADYOUT \
+ IOMUX_PAD(0x0660, 0x0278, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__USDHC1_CLKI \
+ IOMUX_PAD(0x0660, 0x0278, 8, 0x0928, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N \
+ IOMUX_PAD(0x0664, 0x027C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS2__IPU1_SISG_0 \
+ IOMUX_PAD(0x0664, 0x027C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__ESAI1_TX0 \
+ IOMUX_PAD(0x0664, 0x027C, 2, 0x0844, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__WEIM_WEIM_CRE \
+ IOMUX_PAD(0x0664, 0x027C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__CCM_CLKO2 \
+ IOMUX_PAD(0x0664, 0x027C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__GPIO_6_15 \
+ IOMUX_PAD(0x0664, 0x027C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__USDHC2_CLKO \
+ IOMUX_PAD(0x0664, 0x027C, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N \
+ IOMUX_PAD(0x0668, 0x0280, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS3__IPU1_SISG_1 \
+ IOMUX_PAD(0x0668, 0x0280, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__ESAI1_TX1 \
+ IOMUX_PAD(0x0668, 0x0280, 2, 0x0848, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__WEIM_WEIM_A_26 \
+ IOMUX_PAD(0x0668, 0x0280, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_4 \
+ IOMUX_PAD(0x0668, 0x0280, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__GPIO_6_16 \
+ IOMUX_PAD(0x0668, 0x0280, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__TPSMP_CLK \
+ IOMUX_PAD(0x0668, 0x0280, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__USDHC2_CLKI \
+ IOMUX_PAD(0x0668, 0x0280, 8, 0x0930, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__I2C4_SDA \
+ IOMUX_PAD(0x0668, 0x0280, 9 | IOMUX_CONFIG_SION, 0x0884, 2, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D0__RAWNAND_D0 \
+ IOMUX_PAD(0x066C, 0x0284, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D0__USDHC1_DAT4 \
+ IOMUX_PAD(0x066C, 0x0284, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__GPU3D_GPU_DEBUG_OUT_0 \
+ IOMUX_PAD(0x066C, 0x0284, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT_16 \
+ IOMUX_PAD(0x066C, 0x0284, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT_16 \
+ IOMUX_PAD(0x066C, 0x0284, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__GPIO_2_0 \
+ IOMUX_PAD(0x066C, 0x0284, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 \
+ IOMUX_PAD(0x066C, 0x0284, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D1__RAWNAND_D1 \
+ IOMUX_PAD(0x0670, 0x0288, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D1__USDHC1_DAT5 \
+ IOMUX_PAD(0x0670, 0x0288, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT_1 \
+ IOMUX_PAD(0x0670, 0x0288, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT_17 \
+ IOMUX_PAD(0x0670, 0x0288, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT_17 \
+ IOMUX_PAD(0x0670, 0x0288, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__GPIO_2_1 \
+ IOMUX_PAD(0x0670, 0x0288, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 \
+ IOMUX_PAD(0x0670, 0x0288, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D2__RAWNAND_D2 \
+ IOMUX_PAD(0x0674, 0x028C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D2__USDHC1_DAT6 \
+ IOMUX_PAD(0x0674, 0x028C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__GPU3D_GPU_DEBUG_OUT_2 \
+ IOMUX_PAD(0x0674, 0x028C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT_18 \
+ IOMUX_PAD(0x0674, 0x028C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT_18 \
+ IOMUX_PAD(0x0674, 0x028C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__GPIO_2_2 \
+ IOMUX_PAD(0x0674, 0x028C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 \
+ IOMUX_PAD(0x0674, 0x028C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D3__RAWNAND_D3 \
+ IOMUX_PAD(0x0678, 0x0290, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D3__USDHC1_DAT7 \
+ IOMUX_PAD(0x0678, 0x0290, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__GPU3D_GPU_DEBUG_OUT_3 \
+ IOMUX_PAD(0x0678, 0x0290, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT_19 \
+ IOMUX_PAD(0x0678, 0x0290, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT_19 \
+ IOMUX_PAD(0x0678, 0x0290, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__GPIO_2_3 \
+ IOMUX_PAD(0x0678, 0x0290, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 \
+ IOMUX_PAD(0x0678, 0x0290, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D4__RAWNAND_D4 \
+ IOMUX_PAD(0x067C, 0x0294, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D4__USDHC2_DAT4 \
+ IOMUX_PAD(0x067C, 0x0294, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__GPU3D_GPU_DEBUG_OUT_4 \
+ IOMUX_PAD(0x067C, 0x0294, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT_20 \
+ IOMUX_PAD(0x067C, 0x0294, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT_20 \
+ IOMUX_PAD(0x067C, 0x0294, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__GPIO_2_4 \
+ IOMUX_PAD(0x067C, 0x0294, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 \
+ IOMUX_PAD(0x067C, 0x0294, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D5__RAWNAND_D5 \
+ IOMUX_PAD(0x0680, 0x0298, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D5__USDHC2_DAT5 \
+ IOMUX_PAD(0x0680, 0x0298, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__GPU3D_GPU_DEBUG_OUT_5 \
+ IOMUX_PAD(0x0680, 0x0298, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT_21 \
+ IOMUX_PAD(0x0680, 0x0298, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT_21 \
+ IOMUX_PAD(0x0680, 0x0298, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__GPIO_2_5 \
+ IOMUX_PAD(0x0680, 0x0298, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 \
+ IOMUX_PAD(0x0680, 0x0298, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D6__RAWNAND_D6 \
+ IOMUX_PAD(0x0684, 0x029C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D6__USDHC2_DAT6 \
+ IOMUX_PAD(0x0684, 0x029C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__GPU3D_GPU_DEBUG_OUT_6 \
+ IOMUX_PAD(0x0684, 0x029C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT_22 \
+ IOMUX_PAD(0x0684, 0x029C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT_22 \
+ IOMUX_PAD(0x0684, 0x029C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__GPIO_2_6 \
+ IOMUX_PAD(0x0684, 0x029C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 \
+ IOMUX_PAD(0x0684, 0x029C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D7__RAWNAND_D7 \
+ IOMUX_PAD(0x0688, 0x02A0, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D7__USDHC2_DAT7 \
+ IOMUX_PAD(0x0688, 0x02A0, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23 \
+ IOMUX_PAD(0x0688, 0x02A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23 \
+ IOMUX_PAD(0x0688, 0x02A0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__GPIO_2_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_RB0__RAWNAND_READY0 \
+ IOMUX_PAD(0x068C, 0x02A4, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL0)
+#define MX6DL_PAD_NANDF_RB0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_2 \
+ IOMUX_PAD(0x068C, 0x02A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USBOH3_UH3_DFD_OUT_14 \
+ IOMUX_PAD(0x068C, 0x02A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USBOH3_UH2_DFD_OUT_14 \
+ IOMUX_PAD(0x068C, 0x02A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__GPIO_6_10 \
+ IOMUX_PAD(0x068C, 0x02A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__MIPI_CORE_DPHY_TEST_OUT_33 \
+ IOMUX_PAD(0x068C, 0x02A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USDHC4_CLKI \
+ IOMUX_PAD(0x068C, 0x02A4, 8, 0x0938, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN \
+ IOMUX_PAD(0x0690, 0x02A8, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_WP_B__PCIE_CTRL_DIAG_STATUS_BUS_MUX_1 \
+ IOMUX_PAD(0x0690, 0x02A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USBOH3_UH3_DFD_OUT_13 \
+ IOMUX_PAD(0x0690, 0x02A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USBOH3_UH2_DFD_OUT_13 \
+ IOMUX_PAD(0x0690, 0x02A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__GPIO_6_9 \
+ IOMUX_PAD(0x0690, 0x02A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__MIPI_CORE_DPHY_TEST_OUT_32 \
+ IOMUX_PAD(0x0690, 0x02A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USDHC4_CLKO \
+ IOMUX_PAD(0x0690, 0x02A8, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__I2C4_SCL \
+ IOMUX_PAD(0x0690, 0x02A8, 9 | IOMUX_CONFIG_SION, 0x0880, 2, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_POR_B__SRC_POR_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RESET_IN_B__SRC_RESET_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD0__MIPI_HSI_CTRL_RX_READY \
+ IOMUX_PAD(0x0694, 0x02AC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0 \
+ IOMUX_PAD(0x0694, 0x02AC, 1, 0x0818, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__GPIO_6_25 \
+ IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__MIPI_CORE_DPHY_TEST_IN_6 \
+ IOMUX_PAD(0x0694, 0x02AC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FLAG \
+ IOMUX_PAD(0x0698, 0x02B0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1 \
+ IOMUX_PAD(0x0698, 0x02B0, 1, 0x081C, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__GPIO_6_27 \
+ IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__MIPI_CORE_DPHY_TEST_IN_8 \
+ IOMUX_PAD(0x0698, 0x02B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__SJC_FAIL \
+ IOMUX_PAD(0x0698, 0x02B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD2__MIPI_HSI_CTRL_TX_DATA \
+ IOMUX_PAD(0x069C, 0x02B4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2 \
+ IOMUX_PAD(0x069C, 0x02B4, 1, 0x0820, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__GPIO_6_28 \
+ IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__MIPI_CORE_DPHY_TEST_IN_9 \
+ IOMUX_PAD(0x069C, 0x02B4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD3__MIPI_HSI_CTRL_TX_WAKE \
+ IOMUX_PAD(0x06A0, 0x02B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3 \
+ IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0824, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__GPIO_6_29 \
+ IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__MIPI_CORE_DPHY_TEST_IN_10 \
+ IOMUX_PAD(0x06A0, 0x02B8, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RX_CTL__USBOH3_H3_DATA \
+ IOMUX_PAD(0x06A4, 0x02BC, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL \
+ IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0828, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24 \
+ IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__MIPI_CORE_DPHY_TEST_IN_5 \
+ IOMUX_PAD(0x06A4, 0x02BC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE \
+ IOMUX_PAD(0x06A8, 0x02C0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START \
+ IOMUX_PAD(0x06A8, 0x02C0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)
+#define MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC \
+ IOMUX_PAD(0x06A8, 0x02C0, 1, 0x0814, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__GPIO_6_30 \
+ IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__MIPI_CORE_DPHY_TEST_IN_11 \
+ IOMUX_PAD(0x06A8, 0x02C0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD0__MIPI_HSI_CTRL_TX_READY \
+ IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0 \
+ IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__GPIO_6_20 \
+ IOMUX_PAD(0x06AC, 0x02C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__MIPI_CORE_DPHY_TEST_IN_1 \
+ IOMUX_PAD(0x06AC, 0x02C4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD1__MIPI_HSI_CTRL_RX_FLAG \
+ IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1 \
+ IOMUX_PAD(0x06B0, 0x02C8, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__GPIO_6_21 \
+ IOMUX_PAD(0x06B0, 0x02C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__MIPI_CORE_DPHY_TEST_IN_2 \
+ IOMUX_PAD(0x06B0, 0x02C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__CCM_PLL3_BYP \
+ IOMUX_PAD(0x06B0, 0x02C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD2__MIPI_HSI_CTRL_RX_DATA \
+ IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2 \
+ IOMUX_PAD(0x06B4, 0x02CC, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__GPIO_6_22 \
+ IOMUX_PAD(0x06B4, 0x02CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__MIPI_CORE_DPHY_TEST_IN_3 \
+ IOMUX_PAD(0x06B4, 0x02CC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__CCM_PLL2_BYP \
+ IOMUX_PAD(0x06B4, 0x02CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD3__MIPI_HSI_CTRL_RX_WAKE \
+ IOMUX_PAD(0x06B8, 0x02D0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3 \
+ IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__GPIO_6_23 \
+ IOMUX_PAD(0x06B8, 0x02D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__MIPI_CORE_DPHY_TEST_IN_4 \
+ IOMUX_PAD(0x06B8, 0x02D0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE \
+ IOMUX_PAD(0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START \
+ IOMUX_PAD(0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)
+#define MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL \
+ IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__GPIO_6_26 \
+ IOMUX_PAD(0x06BC, 0x02D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__MIPI_CORE_DPHY_TEST_IN_7 \
+ IOMUX_PAD(0x06BC, 0x02D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x06BC, 0x02D4, 7, 0x080C, 1, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TXC__USBOH3_H2_DATA \
+ IOMUX_PAD(0x06C0, 0x02D8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC \
+ IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x06C0, 0x02D8, 2, 0x08F4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__GPIO_6_19 \
+ IOMUX_PAD(0x06C0, 0x02D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__MIPI_CORE_DPHY_TEST_IN_0 \
+ IOMUX_PAD(0x06C0, 0x02D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x06C0, 0x02D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_CLK__USDHC1_CLK \
+ IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0928, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__USDHC1_CLK_50MHZ_40OHM \
+ IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0928, 1, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_CLK__OSC32K_32K_OUT \
+ IOMUX_PAD(0x06C4, 0x02DC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__GPT_CLKIN \
+ IOMUX_PAD(0x06C4, 0x02DC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__GPIO_1_20 \
+ IOMUX_PAD(0x06C4, 0x02DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__PHY_DTB_0 \
+ IOMUX_PAD(0x06C4, 0x02DC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_CMD__USDHC1_CMD \
+ IOMUX_PAD(0x06C8, 0x02E0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__USDHC1_CMD_50MHZ_40OHM \
+ IOMUX_PAD(0x06C8, 0x02E0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_CMD__PWM4_PWMO \
+ IOMUX_PAD(0x06C8, 0x02E0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__GPT_CMPOUT1 \
+ IOMUX_PAD(0x06C8, 0x02E0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__GPIO_1_18 \
+ IOMUX_PAD(0x06C8, 0x02E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_5 \
+ IOMUX_PAD(0x06C8, 0x02E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT0__USDHC1_DAT0 \
+ IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM \
+ IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_DAT0__CAAM_WRAPPER_RNG_OSC_OBS \
+ IOMUX_PAD(0x06CC, 0x02E4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__GPT_CAPIN1 \
+ IOMUX_PAD(0x06CC, 0x02E4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_8 \
+ IOMUX_PAD(0x06CC, 0x02E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__GPIO_1_16 \
+ IOMUX_PAD(0x06CC, 0x02E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 \
+ IOMUX_PAD(0x06CC, 0x02E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_7 \
+ IOMUX_PAD(0x06CC, 0x02E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT1__USDHC1_DAT1 \
+ IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM \
+ IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x06D0, 0x02E8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__GPT_CAPIN2 \
+ IOMUX_PAD(0x06D0, 0x02E8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_7 \
+ IOMUX_PAD(0x06D0, 0x02E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__GPIO_1_17 \
+ IOMUX_PAD(0x06D0, 0x02E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 \
+ IOMUX_PAD(0x06D0, 0x02E8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_8 \
+ IOMUX_PAD(0x06D0, 0x02E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT2__USDHC1_DAT2 \
+ IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM \
+ IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_DAT2__GPT_CMPOUT2 \
+ IOMUX_PAD(0x06D4, 0x02EC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__PWM2_PWMO \
+ IOMUX_PAD(0x06D4, 0x02EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__WDOG1_WDOG_B \
+ IOMUX_PAD(0x06D4, 0x02EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__GPIO_1_19 \
+ IOMUX_PAD(0x06D4, 0x02EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x06D4, 0x02EC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_4 \
+ IOMUX_PAD(0x06D4, 0x02EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT3__USDHC1_DAT3 \
+ IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM \
+ IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_50MHZ_40OHM)
+#define MX6DL_PAD_SD1_DAT3__GPT_CMPOUT3 \
+ IOMUX_PAD(0x06D8, 0x02F0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__PWM1_PWMO \
+ IOMUX_PAD(0x06D8, 0x02F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__WDOG2_WDOG_B \
+ IOMUX_PAD(0x06D8, 0x02F0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__GPIO_1_21 \
+ IOMUX_PAD(0x06D8, 0x02F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x06D8, 0x02F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_6 \
+ IOMUX_PAD(0x06D8, 0x02F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_CLK__USDHC2_CLK \
+ IOMUX_PAD(0x06DC, 0x02F4, 0, 0x0930, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__KPP_COL_5 \
+ IOMUX_PAD(0x06DC, 0x02F4, 2, 0x08C0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x06DC, 0x02F4, 3, 0x07A4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_9 \
+ IOMUX_PAD(0x06DC, 0x02F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__GPIO_1_10 \
+ IOMUX_PAD(0x06DC, 0x02F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__PHY_DTB_1 \
+ IOMUX_PAD(0x06DC, 0x02F4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_CMD__USDHC2_CMD \
+ IOMUX_PAD(0x06E0, 0x02F8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__KPP_ROW_5 \
+ IOMUX_PAD(0x06E0, 0x02F8, 2, 0x08CC, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x06E0, 0x02F8, 3, 0x07A0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_10 \
+ IOMUX_PAD(0x06E0, 0x02F8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__GPIO_1_11 \
+ IOMUX_PAD(0x06E0, 0x02F8, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT0__USDHC2_DAT0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x06E4, 0x02FC, 3, 0x0798, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__KPP_ROW_7 \
+ IOMUX_PAD(0x06E4, 0x02FC, 4, 0x08D4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__GPIO_1_15 \
+ IOMUX_PAD(0x06E4, 0x02FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x06E4, 0x02FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_2 \
+ IOMUX_PAD(0x06E4, 0x02FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT1__USDHC2_DAT1 \
+ IOMUX_PAD(0x06E8, 0x0300, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x06E8, 0x0300, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x06E8, 0x0300, 3, 0x07AC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__KPP_COL_7 \
+ IOMUX_PAD(0x06E8, 0x0300, 4, 0x08C8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__GPIO_1_14 \
+ IOMUX_PAD(0x06E8, 0x0300, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__CCM_WAIT \
+ IOMUX_PAD(0x06E8, 0x0300, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0 \
+ IOMUX_PAD(0x06E8, 0x0300, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT2__USDHC2_DAT2 \
+ IOMUX_PAD(0x06EC, 0x0304, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x06EC, 0x0304, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x06EC, 0x0304, 3, 0x079C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__KPP_ROW_6 \
+ IOMUX_PAD(0x06EC, 0x0304, 4, 0x08D0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__GPIO_1_13 \
+ IOMUX_PAD(0x06EC, 0x0304, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__CCM_STOP \
+ IOMUX_PAD(0x06EC, 0x0304, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1 \
+ IOMUX_PAD(0x06EC, 0x0304, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT3__USDHC2_DAT3 \
+ IOMUX_PAD(0x06F0, 0x0308, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__KPP_COL_6 \
+ IOMUX_PAD(0x06F0, 0x0308, 2, 0x08C4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x06F0, 0x0308, 3, 0x07A8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_11 \
+ IOMUX_PAD(0x06F0, 0x0308, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__GPIO_1_12 \
+ IOMUX_PAD(0x06F0, 0x0308, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__SJC_DONE \
+ IOMUX_PAD(0x06F0, 0x0308, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__ANATOP_ANATOP_TESTO_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_100MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_200MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_CLK__UART2_CTS \
+ IOMUX_PAD(0x06F4, 0x030C, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__UART2_RTS \
+ IOMUX_PAD(0x06F4, 0x030C, 1, 0x0900, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__CAN1_RXCAN \
+ IOMUX_PAD(0x06F4, 0x030C, 2, 0x07C8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 \
+ IOMUX_PAD(0x06F4, 0x030C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 \
+ IOMUX_PAD(0x06F4, 0x030C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__GPIO_7_3 \
+ IOMUX_PAD(0x06F4, 0x030C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__MIPI_CORE_DPHY_TEST_IN_17 \
+ IOMUX_PAD(0x06F4, 0x030C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__ANATOP_ANATOP_TESTO_14 \
+ IOMUX_PAD(0x06F4, 0x030C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_100MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_200MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_CMD__UART2_CTS \
+ IOMUX_PAD(0x06F8, 0x0310, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MXSDL_PAD_SD3_CMD__UART2_RTS \
+ IOMUX_PAD(0x06F8, 0x0310, 1, 0x0900, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__CAN1_TXCAN \
+ IOMUX_PAD(0x06F8, 0x0310, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 \
+ IOMUX_PAD(0x06F8, 0x0310, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 \
+ IOMUX_PAD(0x06F8, 0x0310, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__GPIO_7_2 \
+ IOMUX_PAD(0x06F8, 0x0310, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__MIPI_CORE_DPHY_TEST_IN_16 \
+ IOMUX_PAD(0x06F8, 0x0310, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__ANATOP_ANATOP_TESTO_13 \
+ IOMUX_PAD(0x06F8, 0x0310, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_100MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_200MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT0__UART1_CTS \
+ IOMUX_PAD(0x06FC, 0x0314, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__UART1_RTS \
+ IOMUX_PAD(0x06FC, 0x0314, 1, 0x08F8, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__CAN2_TXCAN \
+ IOMUX_PAD(0x06FC, 0x0314, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__GPIO_7_4 \
+ IOMUX_PAD(0x06FC, 0x0314, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__MIPI_CORE_DPHY_TEST_IN_18 \
+ IOMUX_PAD(0x06FC, 0x0314, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__ANATOP_ANATOP_TESTO_15 \
+ IOMUX_PAD(0x06FC, 0x0314, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_100MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_200MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT1__UART1_CTS \
+ IOMUX_PAD(0x0700, 0x0318, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__UART1_RTS \
+ IOMUX_PAD(0x0700, 0x0318, 1, 0x08F8, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__CAN2_RXCAN \
+ IOMUX_PAD(0x0700, 0x0318, 2, 0x07CC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 \
+ IOMUX_PAD(0x0700, 0x0318, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 \
+ IOMUX_PAD(0x0700, 0x0318, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__GPIO_7_5 \
+ IOMUX_PAD(0x0700, 0x0318, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__MIPI_CORE_DPHY_TEST_IN_19 \
+ IOMUX_PAD(0x0700, 0x0318, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__ANATOP_ANATOP_TESTI_0 \
+ IOMUX_PAD(0x0700, 0x0318, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_100MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_200MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT2__PCIE_CTRL_DIAG_STATUS_BUS_MUX_28 \
+ IOMUX_PAD(0x0704, 0x031C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 \
+ IOMUX_PAD(0x0704, 0x031C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 \
+ IOMUX_PAD(0x0704, 0x031C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__GPIO_7_6 \
+ IOMUX_PAD(0x0704, 0x031C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__MIPI_CORE_DPHY_TEST_IN_20 \
+ IOMUX_PAD(0x0704, 0x031C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__ANATOP_ANATOP_TESTI_1 \
+ IOMUX_PAD(0x0704, 0x031C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_100MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_200MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT3__UART3_CTS \
+ IOMUX_PAD(0x0708, 0x0320, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__UART3_RTS \
+ IOMUX_PAD(0x0708, 0x0320, 1, 0x0908, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_29 \
+ IOMUX_PAD(0x0708, 0x0320, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 \
+ IOMUX_PAD(0x0708, 0x0320, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 \
+ IOMUX_PAD(0x0708, 0x0320, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__GPIO_7_7 \
+ IOMUX_PAD(0x0708, 0x0320, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__MIPI_CORE_DPHY_TEST_IN_21 \
+ IOMUX_PAD(0x0708, 0x0320, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__ANATOP_ANATOP_TESTI_2 \
+ IOMUX_PAD(0x0708, 0x0320, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_100MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_200MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT4__UART2_TXD \
+ IOMUX_PAD(0x070C, 0x0324, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__UART2_RXD \
+ IOMUX_PAD(0x070C, 0x0324, 1, 0x0904, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__PCIE_CTRL_DIAG_STATUS_BUS_MUX_27 \
+ IOMUX_PAD(0x070C, 0x0324, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 \
+ IOMUX_PAD(0x070C, 0x0324, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 \
+ IOMUX_PAD(0x070C, 0x0324, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__GPIO_7_1 \
+ IOMUX_PAD(0x070C, 0x0324, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__MIPI_CORE_DPHY_TEST_IN_15 \
+ IOMUX_PAD(0x070C, 0x0324, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__ANATOP_ANATOP_TESTO_12 \
+ IOMUX_PAD(0x070C, 0x0324, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_100MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_200MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT5__UART2_TXD \
+ IOMUX_PAD(0x0710, 0x0328, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__UART2_RXD \
+ IOMUX_PAD(0x0710, 0x0328, 1, 0x0904, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__PCIE_CTRL_DIAG_STATUS_BUS_MUX_26 \
+ IOMUX_PAD(0x0710, 0x0328, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 \
+ IOMUX_PAD(0x0710, 0x0328, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 \
+ IOMUX_PAD(0x0710, 0x0328, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__GPIO_7_0 \
+ IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__MIPI_CORE_DPHY_TEST_IN_14 \
+ IOMUX_PAD(0x0710, 0x0328, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__ANATOP_ANATOP_TESTO_11 \
+ IOMUX_PAD(0x0710, 0x0328, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_100MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_200MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT6__UART1_TXD \
+ IOMUX_PAD(0x0714, 0x032C, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__UART1_RXD \
+ IOMUX_PAD(0x0714, 0x032C, 1, 0x08FC, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__PCIE_CTRL_DIAG_STATUS_BUS_MUX_25 \
+ IOMUX_PAD(0x0714, 0x032C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 \
+ IOMUX_PAD(0x0714, 0x032C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 \
+ IOMUX_PAD(0x0714, 0x032C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__GPIO_6_18 \
+ IOMUX_PAD(0x0714, 0x032C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__MIPI_CORE_DPHY_TEST_IN_13 \
+ IOMUX_PAD(0x0714, 0x032C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__ANATOP_ANATOP_TESTO_10 \
+ IOMUX_PAD(0x0714, 0x032C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_100MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_200MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT7__UART1_TXD \
+ IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__UART1_RXD \
+ IOMUX_PAD(0x0718, 0x0330, 1, 0x08FC, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__PCIE_CTRL_DIAG_STATUS_BUS_MUX_24 \
+ IOMUX_PAD(0x0718, 0x0330, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 \
+ IOMUX_PAD(0x0718, 0x0330, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 \
+ IOMUX_PAD(0x0718, 0x0330, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__GPIO_6_17 \
+ IOMUX_PAD(0x0718, 0x0330, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__MIPI_CORE_DPHY_TEST_IN_12 \
+ IOMUX_PAD(0x0718, 0x0330, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x0718, 0x0330, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_RST__USDHC3_RST \
+ IOMUX_PAD(0x071C, 0x0334, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__UART3_CTS \
+ IOMUX_PAD(0x071C, 0x0334, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__UART3_RTS \
+ IOMUX_PAD(0x071C, 0x0334, 1, 0x0908, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__PCIE_CTRL_DIAG_STATUS_BUS_MUX_30 \
+ IOMUX_PAD(0x071C, 0x0334, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 \
+ IOMUX_PAD(0x071C, 0x0334, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 \
+ IOMUX_PAD(0x071C, 0x0334, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__GPIO_7_8 \
+ IOMUX_PAD(0x071C, 0x0334, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__MIPI_CORE_DPHY_TEST_IN_22 \
+ IOMUX_PAD(0x071C, 0x0334, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 \
+ IOMUX_PAD(0x071C, 0x0334, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_50MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_100MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_200MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_CLK__RAWNAND_WRN \
+ IOMUX_PAD(0x0720, 0x0338, 1, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_SD4_CLK__UART3_TXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__UART3_RXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x090C, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_6 \
+ IOMUX_PAD(0x0720, 0x0338, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__GPIO_7_10 \
+ IOMUX_PAD(0x0720, 0x0338, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_50MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_100MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_200MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_CMD__RAWNAND_RDN \
+ IOMUX_PAD(0x0724, 0x033C, 1, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_SD4_CMD__UART3_TXD \
+ IOMUX_PAD(0x0724, 0x033C, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__UART3_RXD \
+ IOMUX_PAD(0x0724, 0x033C, 2, 0x090C, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_5 \
+ IOMUX_PAD(0x0724, 0x033C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__GPIO_7_9 \
+ IOMUX_PAD(0x0724, 0x033C, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT0__RAWNAND_D8 \
+ IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_100MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_200MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT0__RAWNAND_DQS \
+ IOMUX_PAD(0x0728, 0x0340, 2, 0x0000, 0, MX6DL_GPMI_PAD_CTRL1)
+#define MX6DL_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT_24 \
+ IOMUX_PAD(0x0728, 0x0340, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT_24 \
+ IOMUX_PAD(0x0728, 0x0340, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__GPIO_2_8 \
+ IOMUX_PAD(0x0728, 0x0340, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 \
+ IOMUX_PAD(0x0728, 0x0340, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT1__RAWNAND_D9 \
+ IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_100MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_200MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x072C, 0x0344, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT_25 \
+ IOMUX_PAD(0x072C, 0x0344, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT_25 \
+ IOMUX_PAD(0x072C, 0x0344, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__GPIO_2_9 \
+ IOMUX_PAD(0x072C, 0x0344, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 \
+ IOMUX_PAD(0x072C, 0x0344, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT2__RAWNAND_D10 \
+ IOMUX_PAD(0x0730, 0x0348, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_100MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_200MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT2__PWM4_PWMO \
+ IOMUX_PAD(0x0730, 0x0348, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT_26 \
+ IOMUX_PAD(0x0730, 0x0348, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT_26 \
+ IOMUX_PAD(0x0730, 0x0348, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__GPIO_2_10 \
+ IOMUX_PAD(0x0730, 0x0348, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 \
+ IOMUX_PAD(0x0730, 0x0348, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT3__RAWNAND_D11 \
+ IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_100MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_200MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT_27 \
+ IOMUX_PAD(0x0734, 0x034C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT_27 \
+ IOMUX_PAD(0x0734, 0x034C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__GPIO_2_11 \
+ IOMUX_PAD(0x0734, 0x034C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 \
+ IOMUX_PAD(0x0734, 0x034C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT4__RAWNAND_D12 \
+ IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_100MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_200MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT4__UART2_TXD \
+ IOMUX_PAD(0x0738, 0x0350, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__UART2_RXD \
+ IOMUX_PAD(0x0738, 0x0350, 2, 0x0904, 6, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT_28 \
+ IOMUX_PAD(0x0738, 0x0350, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT_28 \
+ IOMUX_PAD(0x0738, 0x0350, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__GPIO_2_12 \
+ IOMUX_PAD(0x0738, 0x0350, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 \
+ IOMUX_PAD(0x0738, 0x0350, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT5__RAWNAND_D13 \
+ IOMUX_PAD(0x073C, 0x0354, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_100MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_200MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT5__UART2_CTS \
+ IOMUX_PAD(0x073C, 0x0354, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__UART2_RTS \
+ IOMUX_PAD(0x073C, 0x0354, 2, 0x0900, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT_29 \
+ IOMUX_PAD(0x073C, 0x0354, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT_29 \
+ IOMUX_PAD(0x073C, 0x0354, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__GPIO_2_13 \
+ IOMUX_PAD(0x073C, 0x0354, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 \
+ IOMUX_PAD(0x073C, 0x0354, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT6__RAWNAND_D14 \
+ IOMUX_PAD(0x0740, 0x0358, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_100MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_200MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT6__UART2_CTS \
+ IOMUX_PAD(0x0740, 0x0358, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__UART2_RTS \
+ IOMUX_PAD(0x0740, 0x0358, 2, 0x0900, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT_30 \
+ IOMUX_PAD(0x0740, 0x0358, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT_30 \
+ IOMUX_PAD(0x0740, 0x0358, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__GPIO_2_14 \
+ IOMUX_PAD(0x0740, 0x0358, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 \
+ IOMUX_PAD(0x0740, 0x0358, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT7__RAWNAND_D15 \
+ IOMUX_PAD(0x0744, 0x035C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_100MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_200MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT7__UART2_TXD \
+ IOMUX_PAD(0x0744, 0x035C, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__UART2_RXD \
+ IOMUX_PAD(0x0744, 0x035C, 2, 0x0904, 7, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT_31 \
+ IOMUX_PAD(0x0744, 0x035C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT_31 \
+ IOMUX_PAD(0x0744, 0x035C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__GPIO_2_15 \
+ IOMUX_PAD(0x0744, 0x035C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 \
+ IOMUX_PAD(0x0744, 0x035C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#endif /*__MACH_IOMUX_MX6DL_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
new file mode 100644
index 00000000..4e85d81c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
@@ -0,0 +1,7403 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Auto Generate file, please don't edit it
+ *
+ */
+
+#ifndef __MACH_IOMUX_MX6Q_H__
+#define __MACH_IOMUX_MX6Q_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX6Q_CCM_CLK0_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_HIGH_DRV (PAD_CTL_DSE_120ohm)
+
+#define MX6Q_MLB150_PAD_CTRL (PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) \
+
+#define MX6Q_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6Q_ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6Q_ENET_REF_CLK_PAD_CTRL (PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
+
+#define MX6Q_GPIO_16_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6Q_DISP_PAD_CLT MX6Q_HIGH_DRV
+
+#define MX6Q_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+ PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_40ohm | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_HYS | PAD_CTL_SPEED_MED)
+
+#define MX6Q_ESAI_PAD_CTRL (PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
+ PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+
+#define MX6Q_GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX6Q_GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | PAD_CTL_SRE_FAST)
+#define MX6Q_GPMI_PAD_CTRL2 (MX6Q_GPMI_PAD_CTRL0 | MX6Q_GPMI_PAD_CTRL1)
+
+#define MX6Q_SPDIF_OUT_PAD_CTRL (PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
+#define MX6Q_USB_HSIC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm)
+
+#define MX6Q_ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6Q_HDMICEC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_ODE | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_SLOW)
+
+#define MX6Q_ADU_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_PUS_100K_DOWN | \
+ PAD_CTL_HYS | PAD_CTL_SPEED_MED)
+
+#define MX6Q_WEIM_NOR_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_40ohm | \
+ PAD_CTL_SPEED_MED | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP)
+
+#define ENET_IRQ_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_40ohm | \
+ PAD_CTL_SPEED_MED)
+
+#define _MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 \
+ IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 \
+ IOMUX_PAD(0x0360, 0x004C, 1, 0x0834, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x0360, 0x004C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x0360, 0x004C, 3, 0x07C8, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__KPP_COL_7 \
+ IOMUX_PAD(0x0360, 0x004C, 4, 0x08F0, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__GPIO_1_14 \
+ IOMUX_PAD(0x0360, 0x004C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__CCM_WAIT \
+ IOMUX_PAD(0x0360, 0x004C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0 \
+ IOMUX_PAD(0x0360, 0x004C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 \
+ IOMUX_PAD(0x0364, 0x0050, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 \
+ IOMUX_PAD(0x0364, 0x0050, 1, 0x0838, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x0364, 0x0050, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x0364, 0x0050, 3, 0x07B8, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__KPP_ROW_6 \
+ IOMUX_PAD(0x0364, 0x0050, 4, 0x08F8, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__GPIO_1_13 \
+ IOMUX_PAD(0x0364, 0x0050, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__CCM_STOP \
+ IOMUX_PAD(0x0364, 0x0050, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1 \
+ IOMUX_PAD(0x0364, 0x0050, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 \
+ IOMUX_PAD(0x0368, 0x0054, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__ECSPI5_MISO \
+ IOMUX_PAD(0x0368, 0x0054, 1, 0x082C, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x0368, 0x0054, 3, 0x07B4, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__KPP_ROW_7 \
+ IOMUX_PAD(0x0368, 0x0054, 4, 0x08FC, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__GPIO_1_15 \
+ IOMUX_PAD(0x0368, 0x0054, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x0368, 0x0054, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_2 \
+ IOMUX_PAD(0x0368, 0x0054, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA \
+ IOMUX_PAD(0x036C, 0x0058, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC \
+ IOMUX_PAD(0x036C, 0x0058, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x036C, 0x0058, 2, 0x0918, 0, 0)
+#define _MX6Q_PAD_RGMII_TXC__GPIO_6_19 \
+ IOMUX_PAD(0x036C, 0x0058, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_TEST_IN_0 \
+ IOMUX_PAD(0x036C, 0x0058, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TXC__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x036C, 0x0058, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TD0__MIPI_HSI_CTRL_TX_READY \
+ IOMUX_PAD(0x0370, 0x005C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 \
+ IOMUX_PAD(0x0370, 0x005C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD0__GPIO_6_20 \
+ IOMUX_PAD(0x0370, 0x005C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_TEST_IN_1 \
+ IOMUX_PAD(0x0370, 0x005C, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TD1__MIPI_HSI_CTRL_RX_FLAG \
+ IOMUX_PAD(0x0374, 0x0060, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 \
+ IOMUX_PAD(0x0374, 0x0060, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD1__GPIO_6_21 \
+ IOMUX_PAD(0x0374, 0x0060, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_TEST_IN_2 \
+ IOMUX_PAD(0x0374, 0x0060, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP \
+ IOMUX_PAD(0x0374, 0x0060, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TD2__MIPI_HSI_CTRL_RX_DATA \
+ IOMUX_PAD(0x0378, 0x0064, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 \
+ IOMUX_PAD(0x0378, 0x0064, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD2__GPIO_6_22 \
+ IOMUX_PAD(0x0378, 0x0064, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_TEST_IN_3 \
+ IOMUX_PAD(0x0378, 0x0064, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP \
+ IOMUX_PAD(0x0378, 0x0064, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TD3__MIPI_HSI_CTRL_RX_WAKE \
+ IOMUX_PAD(0x037C, 0x0068, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 \
+ IOMUX_PAD(0x037C, 0x0068, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD3__GPIO_6_23 \
+ IOMUX_PAD(0x037C, 0x0068, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_TEST_IN_4 \
+ IOMUX_PAD(0x037C, 0x0068, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA \
+ IOMUX_PAD(0x0380, 0x006C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL \
+ IOMUX_PAD(0x0380, 0x006C, 1, 0x0858, 0, 0)
+#define _MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24 \
+ IOMUX_PAD(0x0380, 0x006C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RX_CTL__MIPI_CORE_DPHY_TEST_IN_5 \
+ IOMUX_PAD(0x0380, 0x006C, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RD0__MIPI_HSI_CTRL_RX_READY \
+ IOMUX_PAD(0x0384, 0x0070, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 \
+ IOMUX_PAD(0x0384, 0x0070, 1, 0x0848, 0, 0)
+#define _MX6Q_PAD_RGMII_RD0__GPIO_6_25 \
+ IOMUX_PAD(0x0384, 0x0070, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_TEST_IN_6 \
+ IOMUX_PAD(0x0384, 0x0070, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE \
+ IOMUX_PAD(0x0388, 0x0074, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL \
+ IOMUX_PAD(0x0388, 0x0074, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26 \
+ IOMUX_PAD(0x0388, 0x0074, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TX_CTL__MIPI_CORE_DPHY_TEST_IN_7 \
+ IOMUX_PAD(0x0388, 0x0074, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_TX_CTL__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x0388, 0x0074, 7, 0x083C, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FLAG \
+ IOMUX_PAD(0x038C, 0x0078, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 \
+ IOMUX_PAD(0x038C, 0x0078, 1, 0x084C, 0, 0)
+#define _MX6Q_PAD_RGMII_RD1__GPIO_6_27 \
+ IOMUX_PAD(0x038C, 0x0078, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD1__MIPI_CORE_DPHY_TEST_IN_8 \
+ IOMUX_PAD(0x038C, 0x0078, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD1__SJC_FAIL \
+ IOMUX_PAD(0x038C, 0x0078, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RD2__MIPI_HSI_CTRL_TX_DATA \
+ IOMUX_PAD(0x0390, 0x007C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 \
+ IOMUX_PAD(0x0390, 0x007C, 1, 0x0850, 0, 0)
+#define _MX6Q_PAD_RGMII_RD2__GPIO_6_28 \
+ IOMUX_PAD(0x0390, 0x007C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_TEST_IN_9 \
+ IOMUX_PAD(0x0390, 0x007C, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RD3__MIPI_HSI_CTRL_TX_WAKE \
+ IOMUX_PAD(0x0394, 0x0080, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 \
+ IOMUX_PAD(0x0394, 0x0080, 1, 0x0854, 0, 0)
+#define _MX6Q_PAD_RGMII_RD3__GPIO_6_29 \
+ IOMUX_PAD(0x0394, 0x0080, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_TEST_IN_10 \
+ IOMUX_PAD(0x0394, 0x0080, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE \
+ IOMUX_PAD(0x0398, 0x0084, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC \
+ IOMUX_PAD(0x0398, 0x0084, 1, 0x0844, 0, 0)
+#define _MX6Q_PAD_RGMII_RXC__GPIO_6_30 \
+ IOMUX_PAD(0x0398, 0x0084, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_TEST_IN_11 \
+ IOMUX_PAD(0x0398, 0x0084, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25 \
+ IOMUX_PAD(0x039C, 0x0088, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__ECSPI4_SS1 \
+ IOMUX_PAD(0x039C, 0x0088, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__ECSPI2_RDY \
+ IOMUX_PAD(0x039C, 0x0088, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 \
+ IOMUX_PAD(0x039C, 0x0088, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS \
+ IOMUX_PAD(0x039C, 0x0088, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__GPIO_5_2 \
+ IOMUX_PAD(0x039C, 0x0088, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x039C, 0x0088, 6, 0x088C, 0, 0)
+#define _MX6Q_PAD_EIM_A25__PL301_MX6QPER1_HBURST_0 \
+ IOMUX_PAD(0x039C, 0x0088, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2 \
+ IOMUX_PAD(0x03A0, 0x008C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__ECSPI1_SS0 \
+ IOMUX_PAD(0x03A0, 0x008C, 1, 0x0800, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x03A0, 0x008C, 2, 0x07EC, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19 \
+ IOMUX_PAD(0x03A0, 0x008C, 3, 0x08D4, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x03A0, 0x008C, 4, 0x0890, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__GPIO_2_30 \
+ IOMUX_PAD(0x03A0, 0x008C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__I2C2_SCL \
+ IOMUX_PAD(0x03A0, 0x008C, 6 | IOMUX_CONFIG_SION, 0x08A0, 0, 0)
+#define _MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30 \
+ IOMUX_PAD(0x03A0, 0x008C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16 \
+ IOMUX_PAD(0x03A4, 0x0090, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D16__ECSPI1_SCLK \
+ IOMUX_PAD(0x03A4, 0x0090, 1, 0x07F4, 0, 0)
+#define _MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5 \
+ IOMUX_PAD(0x03A4, 0x0090, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18 \
+ IOMUX_PAD(0x03A4, 0x0090, 3, 0x08D0, 0, 0)
+#define _MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x03A4, 0x0090, 4, 0x0894, 0, 0)
+#define _MX6Q_PAD_EIM_D16__GPIO_3_16 \
+ IOMUX_PAD(0x03A4, 0x0090, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D16__I2C2_SDA \
+ IOMUX_PAD(0x03A4, 0x0090, 6 | IOMUX_CONFIG_SION, 0x08A4, 0, 0)
+
+#define _MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17 \
+ IOMUX_PAD(0x03A8, 0x0094, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D17__ECSPI1_MISO \
+ IOMUX_PAD(0x03A8, 0x0094, 1, 0x07F8, 0, 0)
+#define _MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6 \
+ IOMUX_PAD(0x03A8, 0x0094, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK \
+ IOMUX_PAD(0x03A8, 0x0094, 3, 0x08E0, 0, 0)
+#define _MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x03A8, 0x0094, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D17__GPIO_3_17 \
+ IOMUX_PAD(0x03A8, 0x0094, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D17__I2C3_SCL \
+ IOMUX_PAD(0x03A8, 0x0094, 6 | IOMUX_CONFIG_SION, 0x08A8, 0, 0)
+#define _MX6Q_PAD_EIM_D17__PL301_MX6QPER1_HBURST_1 \
+ IOMUX_PAD(0x03A8, 0x0094, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18 \
+ IOMUX_PAD(0x03AC, 0x0098, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D18__ECSPI1_MOSI \
+ IOMUX_PAD(0x03AC, 0x0098, 1, 0x07FC, 0, 0)
+#define _MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7 \
+ IOMUX_PAD(0x03AC, 0x0098, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17 \
+ IOMUX_PAD(0x03AC, 0x0098, 3, 0x08CC, 0, 0)
+#define _MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x03AC, 0x0098, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D18__GPIO_3_18 \
+ IOMUX_PAD(0x03AC, 0x0098, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D18__I2C3_SDA \
+ IOMUX_PAD(0x03AC, 0x0098, 6 | IOMUX_CONFIG_SION, 0x08AC, 0, 0)
+#define _MX6Q_PAD_EIM_D18__PL301_MX6QPER1_HBURST_2 \
+ IOMUX_PAD(0x03AC, 0x0098, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19 \
+ IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D19__ECSPI1_SS1 \
+ IOMUX_PAD(0x03B0, 0x009C, 1, 0x0804, 0, 0)
+#define _MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8 \
+ IOMUX_PAD(0x03B0, 0x009C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16 \
+ IOMUX_PAD(0x03B0, 0x009C, 3, 0x08C8, 0, 0)
+#define _MX6Q_PAD_EIM_D19__UART1_CTS \
+ IOMUX_PAD(0x03B0, 0x009C, 4, 0x091C, 0, 0)
+#define _MX6Q_PAD_EIM_D19__GPIO_3_19 \
+ IOMUX_PAD(0x03B0, 0x009C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D19__EPIT1_EPITO \
+ IOMUX_PAD(0x03B0, 0x009C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D19__PL301_MX6QPER1_HRESP \
+ IOMUX_PAD(0x03B0, 0x009C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20 \
+ IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D20__ECSPI4_SS0 \
+ IOMUX_PAD(0x03B4, 0x00A0, 1, 0x0824, 0, 0)
+#define _MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 \
+ IOMUX_PAD(0x03B4, 0x00A0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15 \
+ IOMUX_PAD(0x03B4, 0x00A0, 3, 0x08C4, 0, 0)
+#define _MX6Q_PAD_EIM_D20__UART1_CTS \
+ IOMUX_PAD(0x03B4, 0x00A0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D20__UART1_RTS \
+ IOMUX_PAD(0x03B4, 0x00A0, 4, 0x091C, 1, 0)
+#define _MX6Q_PAD_EIM_D20__GPIO_3_20 \
+ IOMUX_PAD(0x03B4, 0x00A0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D20__EPIT2_EPITO \
+ IOMUX_PAD(0x03B4, 0x00A0, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21 \
+ IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D21__ECSPI4_SCLK \
+ IOMUX_PAD(0x03B8, 0x00A4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 \
+ IOMUX_PAD(0x03B8, 0x00A4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11 \
+ IOMUX_PAD(0x03B8, 0x00A4, 3, 0x08B4, 0, 0)
+#define _MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x03B8, 0x00A4, 4, 0x0944, 0, 0)
+#define _MX6Q_PAD_EIM_D21__GPIO_3_21 \
+ IOMUX_PAD(0x03B8, 0x00A4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D21__I2C1_SCL \
+ IOMUX_PAD(0x03B8, 0x00A4, 6 | IOMUX_CONFIG_SION, 0x0898, 0, 0)
+#define _MX6Q_PAD_EIM_D21__SPDIF_IN1 \
+ IOMUX_PAD(0x03B8, 0x00A4, 7, 0x0914, 0, 0)
+
+#define _MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22 \
+ IOMUX_PAD(0x03BC, 0x00A8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__ECSPI4_MISO \
+ IOMUX_PAD(0x03BC, 0x00A8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1 \
+ IOMUX_PAD(0x03BC, 0x00A8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10 \
+ IOMUX_PAD(0x03BC, 0x00A8, 3, 0x08B0, 0, 0)
+#define _MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x03BC, 0x00A8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__GPIO_3_22 \
+ IOMUX_PAD(0x03BC, 0x00A8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__SPDIF_OUT1 \
+ IOMUX_PAD(0x03BC, 0x00A8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D22__PL301_MX6QPER1_HWRITE \
+ IOMUX_PAD(0x03BC, 0x00A8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23 \
+ IOMUX_PAD(0x03C0, 0x00AC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS \
+ IOMUX_PAD(0x03C0, 0x00AC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D23__UART3_CTS \
+ IOMUX_PAD(0x03C0, 0x00AC, 2, 0x092C, 0, 0)
+#define _MX6Q_PAD_EIM_D23__UART1_DCD \
+ IOMUX_PAD(0x03C0, 0x00AC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN \
+ IOMUX_PAD(0x03C0, 0x00AC, 4, 0x08D8, 0, 0)
+#define _MX6Q_PAD_EIM_D23__GPIO_3_23 \
+ IOMUX_PAD(0x03C0, 0x00AC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x03C0, 0x00AC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 \
+ IOMUX_PAD(0x03C0, 0x00AC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3 \
+ IOMUX_PAD(0x03C4, 0x00B0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__ECSPI4_RDY \
+ IOMUX_PAD(0x03C4, 0x00B0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__UART3_CTS \
+ IOMUX_PAD(0x03C4, 0x00B0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__UART3_RTS \
+ IOMUX_PAD(0x03C4, 0x00B0, 2, 0x092C, 1, 0)
+#define _MX6Q_PAD_EIM_EB3__UART1_RI \
+ IOMUX_PAD(0x03C4, 0x00B0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC \
+ IOMUX_PAD(0x03C4, 0x00B0, 4, 0x08DC, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__GPIO_2_31 \
+ IOMUX_PAD(0x03C4, 0x00B0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x03C4, 0x00B0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31 \
+ IOMUX_PAD(0x03C4, 0x00B0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24 \
+ IOMUX_PAD(0x03C8, 0x00B4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D24__ECSPI4_SS2 \
+ IOMUX_PAD(0x03C8, 0x00B4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D24__UART3_TXD \
+ IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D24__UART3_RXD \
+ IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0930, 0, 0)
+#define _MX6Q_PAD_EIM_D24__ECSPI1_SS2 \
+ IOMUX_PAD(0x03C8, 0x00B4, 3, 0x0808, 0, 0)
+#define _MX6Q_PAD_EIM_D24__ECSPI2_SS2 \
+ IOMUX_PAD(0x03C8, 0x00B4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D24__GPIO_3_24 \
+ IOMUX_PAD(0x03C8, 0x00B4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x03C8, 0x00B4, 6, 0x07D8, 0, 0)
+#define _MX6Q_PAD_EIM_D24__UART1_DTR \
+ IOMUX_PAD(0x03C8, 0x00B4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25 \
+ IOMUX_PAD(0x03CC, 0x00B8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D25__ECSPI4_SS3 \
+ IOMUX_PAD(0x03CC, 0x00B8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D25__UART3_TXD \
+ IOMUX_PAD(0x03CC, 0x00B8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D25__UART3_RXD \
+ IOMUX_PAD(0x03CC, 0x00B8, 2, 0x0930, 1, 0)
+#define _MX6Q_PAD_EIM_D25__ECSPI1_SS3 \
+ IOMUX_PAD(0x03CC, 0x00B8, 3, 0x080C, 0, 0)
+#define _MX6Q_PAD_EIM_D25__ECSPI2_SS3 \
+ IOMUX_PAD(0x03CC, 0x00B8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D25__GPIO_3_25 \
+ IOMUX_PAD(0x03CC, 0x00B8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x03CC, 0x00B8, 6, 0x07D4, 0, 0)
+#define _MX6Q_PAD_EIM_D25__UART1_DSR \
+ IOMUX_PAD(0x03CC, 0x00B8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26 \
+ IOMUX_PAD(0x03D0, 0x00BC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 \
+ IOMUX_PAD(0x03D0, 0x00BC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1 \
+ IOMUX_PAD(0x03D0, 0x00BC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14 \
+ IOMUX_PAD(0x03D0, 0x00BC, 3, 0x08C0, 0, 0)
+#define _MX6Q_PAD_EIM_D26__UART2_TXD \
+ IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__UART2_RXD \
+ IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0928, 0, 0)
+#define _MX6Q_PAD_EIM_D26__GPIO_3_26 \
+ IOMUX_PAD(0x03D0, 0x00BC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__IPU1_SISG_2 \
+ IOMUX_PAD(0x03D0, 0x00BC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22 \
+ IOMUX_PAD(0x03D0, 0x00BC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27 \
+ IOMUX_PAD(0x03D4, 0x00C0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 \
+ IOMUX_PAD(0x03D4, 0x00C0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0 \
+ IOMUX_PAD(0x03D4, 0x00C0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13 \
+ IOMUX_PAD(0x03D4, 0x00C0, 3, 0x08BC, 0, 0)
+#define _MX6Q_PAD_EIM_D27__UART2_TXD \
+ IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__UART2_RXD \
+ IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0928, 1, 0)
+#define _MX6Q_PAD_EIM_D27__GPIO_3_27 \
+ IOMUX_PAD(0x03D4, 0x00C0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__IPU1_SISG_3 \
+ IOMUX_PAD(0x03D4, 0x00C0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23 \
+ IOMUX_PAD(0x03D4, 0x00C0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28 \
+ IOMUX_PAD(0x03D8, 0x00C4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D28__I2C1_SDA \
+ IOMUX_PAD(0x03D8, 0x00C4, 1 | IOMUX_CONFIG_SION, 0x089C, 0, 0)
+#define _MX6Q_PAD_EIM_D28__ECSPI4_MOSI \
+ IOMUX_PAD(0x03D8, 0x00C4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12 \
+ IOMUX_PAD(0x03D8, 0x00C4, 3, 0x08B8, 0, 0)
+#define _MX6Q_PAD_EIM_D28__UART2_CTS \
+ IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D28__UART2_RTS \
+ IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0924, 0, 0)
+#define _MX6Q_PAD_EIM_D28__GPIO_3_28 \
+ IOMUX_PAD(0x03D8, 0x00C4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG \
+ IOMUX_PAD(0x03D8, 0x00C4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 \
+ IOMUX_PAD(0x03D8, 0x00C4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29 \
+ IOMUX_PAD(0x03DC, 0x00C8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x03DC, 0x00C8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D29__ECSPI4_SS0 \
+ IOMUX_PAD(0x03DC, 0x00C8, 2, 0x0824, 1, 0)
+#define _MX6Q_PAD_EIM_D29__UART2_CTS \
+ IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D29__UART2_RTS \
+ IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0924, 1, 0)
+#define _MX6Q_PAD_EIM_D29__GPIO_3_29 \
+ IOMUX_PAD(0x03DC, 0x00C8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC \
+ IOMUX_PAD(0x03DC, 0x00C8, 6, 0x08E4, 0, 0)
+#define _MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 \
+ IOMUX_PAD(0x03DC, 0x00C8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30 \
+ IOMUX_PAD(0x03E0, 0x00CC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21 \
+ IOMUX_PAD(0x03E0, 0x00CC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 \
+ IOMUX_PAD(0x03E0, 0x00CC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3 \
+ IOMUX_PAD(0x03E0, 0x00CC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__UART3_CTS \
+ IOMUX_PAD(0x03E0, 0x00CC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__GPIO_3_30 \
+ IOMUX_PAD(0x03E0, 0x00CC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x03E0, 0x00CC, 6, 0x0948, 0, 0)
+#define _MX6Q_PAD_EIM_D30__PL301_MX6QPER1_HPROT_0 \
+ IOMUX_PAD(0x03E0, 0x00CC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31 \
+ IOMUX_PAD(0x03E4, 0x00D0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20 \
+ IOMUX_PAD(0x03E4, 0x00D0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 \
+ IOMUX_PAD(0x03E4, 0x00D0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2 \
+ IOMUX_PAD(0x03E4, 0x00D0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__UART3_CTS \
+ IOMUX_PAD(0x03E4, 0x00D0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__UART3_RTS \
+ IOMUX_PAD(0x03E4, 0x00D0, 4, 0x092C, 3, 0)
+#define _MX6Q_PAD_EIM_D31__GPIO_3_31 \
+ IOMUX_PAD(0x03E4, 0x00D0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x03E4, 0x00D0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_D31__PL301_MX6QPER1_HPROT_1 \
+ IOMUX_PAD(0x03E4, 0x00D0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24 \
+ IOMUX_PAD(0x03E8, 0x00D4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19 \
+ IOMUX_PAD(0x03E8, 0x00D4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19 \
+ IOMUX_PAD(0x03E8, 0x00D4, 2, 0x08D4, 1, 0)
+#define _MX6Q_PAD_EIM_A24__IPU2_SISG_2 \
+ IOMUX_PAD(0x03E8, 0x00D4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__IPU1_SISG_2 \
+ IOMUX_PAD(0x03E8, 0x00D4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__GPIO_5_4 \
+ IOMUX_PAD(0x03E8, 0x00D4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__PL301_MX6QPER1_HPROT_2 \
+ IOMUX_PAD(0x03E8, 0x00D4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A24__SRC_BT_CFG_24 \
+ IOMUX_PAD(0x03E8, 0x00D4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23 \
+ IOMUX_PAD(0x03EC, 0x00D8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 2, 0x08D0, 1, 0)
+#define _MX6Q_PAD_EIM_A23__IPU2_SISG_3 \
+ IOMUX_PAD(0x03EC, 0x00D8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__IPU1_SISG_3 \
+ IOMUX_PAD(0x03EC, 0x00D8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__GPIO_6_6 \
+ IOMUX_PAD(0x03EC, 0x00D8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__PL301_MX6QPER1_HPROT_3 \
+ IOMUX_PAD(0x03EC, 0x00D8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A23__SRC_BT_CFG_23 \
+ IOMUX_PAD(0x03EC, 0x00D8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22 \
+ IOMUX_PAD(0x03F0, 0x00DC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17 \
+ IOMUX_PAD(0x03F0, 0x00DC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17 \
+ IOMUX_PAD(0x03F0, 0x00DC, 2, 0x08CC, 1, 0)
+#define _MX6Q_PAD_EIM_A22__GPIO_2_16 \
+ IOMUX_PAD(0x03F0, 0x00DC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A22__TPSMP_HDATA_0 \
+ IOMUX_PAD(0x03F0, 0x00DC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A22__SRC_BT_CFG_22 \
+ IOMUX_PAD(0x03F0, 0x00DC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21 \
+ IOMUX_PAD(0x03F4, 0x00E0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16 \
+ IOMUX_PAD(0x03F4, 0x00E0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16 \
+ IOMUX_PAD(0x03F4, 0x00E0, 2, 0x08C8, 1, 0)
+#define _MX6Q_PAD_EIM_A21__RESERVED_RESERVED \
+ IOMUX_PAD(0x03F4, 0x00E0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_TEST_OUT_18 \
+ IOMUX_PAD(0x03F4, 0x00E0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__GPIO_2_17 \
+ IOMUX_PAD(0x03F4, 0x00E0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__TPSMP_HDATA_1 \
+ IOMUX_PAD(0x03F4, 0x00E0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A21__SRC_BT_CFG_21 \
+ IOMUX_PAD(0x03F4, 0x00E0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15 \
+ IOMUX_PAD(0x03F8, 0x00E4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15 \
+ IOMUX_PAD(0x03F8, 0x00E4, 2, 0x08C4, 1, 0)
+#define _MX6Q_PAD_EIM_A20__RESERVED_RESERVED \
+ IOMUX_PAD(0x03F8, 0x00E4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_TEST_OUT_19 \
+ IOMUX_PAD(0x03F8, 0x00E4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__GPIO_2_18 \
+ IOMUX_PAD(0x03F8, 0x00E4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__TPSMP_HDATA_2 \
+ IOMUX_PAD(0x03F8, 0x00E4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A20__SRC_BT_CFG_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19 \
+ IOMUX_PAD(0x03FC, 0x00E8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14 \
+ IOMUX_PAD(0x03FC, 0x00E8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14 \
+ IOMUX_PAD(0x03FC, 0x00E8, 2, 0x08C0, 1, 0)
+#define _MX6Q_PAD_EIM_A19__RESERVED_RESERVED \
+ IOMUX_PAD(0x03FC, 0x00E8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_TEST_OUT_20 \
+ IOMUX_PAD(0x03FC, 0x00E8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__GPIO_2_19 \
+ IOMUX_PAD(0x03FC, 0x00E8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__TPSMP_HDATA_3 \
+ IOMUX_PAD(0x03FC, 0x00E8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A19__SRC_BT_CFG_19 \
+ IOMUX_PAD(0x03FC, 0x00E8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18 \
+ IOMUX_PAD(0x0400, 0x00EC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13 \
+ IOMUX_PAD(0x0400, 0x00EC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13 \
+ IOMUX_PAD(0x0400, 0x00EC, 2, 0x08BC, 1, 0)
+#define _MX6Q_PAD_EIM_A18__RESERVED_RESERVED \
+ IOMUX_PAD(0x0400, 0x00EC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_TEST_OUT_21 \
+ IOMUX_PAD(0x0400, 0x00EC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__GPIO_2_20 \
+ IOMUX_PAD(0x0400, 0x00EC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__TPSMP_HDATA_4 \
+ IOMUX_PAD(0x0400, 0x00EC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A18__SRC_BT_CFG_18 \
+ IOMUX_PAD(0x0400, 0x00EC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17 \
+ IOMUX_PAD(0x0404, 0x00F0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12 \
+ IOMUX_PAD(0x0404, 0x00F0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12 \
+ IOMUX_PAD(0x0404, 0x00F0, 2, 0x08B8, 1, 0)
+#define _MX6Q_PAD_EIM_A17__RESERVED_RESERVED \
+ IOMUX_PAD(0x0404, 0x00F0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_TEST_OUT_22 \
+ IOMUX_PAD(0x0404, 0x00F0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__GPIO_2_21 \
+ IOMUX_PAD(0x0404, 0x00F0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__TPSMP_HDATA_5 \
+ IOMUX_PAD(0x0404, 0x00F0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A17__SRC_BT_CFG_17 \
+ IOMUX_PAD(0x0404, 0x00F0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16 \
+ IOMUX_PAD(0x0408, 0x00F4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK \
+ IOMUX_PAD(0x0408, 0x00F4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK \
+ IOMUX_PAD(0x0408, 0x00F4, 2, 0x08E0, 1, 0)
+#define _MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_TEST_OUT_23 \
+ IOMUX_PAD(0x0408, 0x00F4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A16__GPIO_2_22 \
+ IOMUX_PAD(0x0408, 0x00F4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A16__TPSMP_HDATA_6 \
+ IOMUX_PAD(0x0408, 0x00F4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_A16__SRC_BT_CFG_16 \
+ IOMUX_PAD(0x0408, 0x00F4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0 \
+ IOMUX_PAD(0x040C, 0x00F8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5 \
+ IOMUX_PAD(0x040C, 0x00F8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS0__ECSPI2_SCLK \
+ IOMUX_PAD(0x040C, 0x00F8, 2, 0x0810, 0, 0)
+#define _MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_TEST_OUT_24 \
+ IOMUX_PAD(0x040C, 0x00F8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS0__GPIO_2_23 \
+ IOMUX_PAD(0x040C, 0x00F8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7 \
+ IOMUX_PAD(0x040C, 0x00F8, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1 \
+ IOMUX_PAD(0x0410, 0x00FC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6 \
+ IOMUX_PAD(0x0410, 0x00FC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS1__ECSPI2_MOSI \
+ IOMUX_PAD(0x0410, 0x00FC, 2, 0x0818, 0, 0)
+#define _MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_TEST_OUT_25 \
+ IOMUX_PAD(0x0410, 0x00FC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS1__GPIO_2_24 \
+ IOMUX_PAD(0x0410, 0x00FC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8 \
+ IOMUX_PAD(0x0410, 0x00FC, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_OE__WEIM_WEIM_OE \
+ IOMUX_PAD(0x0414, 0x0100, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7 \
+ IOMUX_PAD(0x0414, 0x0100, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_OE__ECSPI2_MISO \
+ IOMUX_PAD(0x0414, 0x0100, 2, 0x0814, 0, 0)
+#define _MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_TEST_OUT_26 \
+ IOMUX_PAD(0x0414, 0x0100, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_OE__GPIO_2_25 \
+ IOMUX_PAD(0x0414, 0x0100, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_OE__TPSMP_HDATA_9 \
+ IOMUX_PAD(0x0414, 0x0100, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_RW__WEIM_WEIM_RW \
+ IOMUX_PAD(0x0418, 0x0104, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8 \
+ IOMUX_PAD(0x0418, 0x0104, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_RW__ECSPI2_SS0 \
+ IOMUX_PAD(0x0418, 0x0104, 2, 0x081C, 0, 0)
+#define _MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_TEST_OUT_27 \
+ IOMUX_PAD(0x0418, 0x0104, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_RW__GPIO_2_26 \
+ IOMUX_PAD(0x0418, 0x0104, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_RW__TPSMP_HDATA_10 \
+ IOMUX_PAD(0x0418, 0x0104, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_RW__SRC_BT_CFG_29 \
+ IOMUX_PAD(0x0418, 0x0104, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA \
+ IOMUX_PAD(0x041C, 0x0108, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 \
+ IOMUX_PAD(0x041C, 0x0108, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_LBA__ECSPI2_SS1 \
+ IOMUX_PAD(0x041C, 0x0108, 2, 0x0820, 0, 0)
+#define _MX6Q_PAD_EIM_LBA__GPIO_2_27 \
+ IOMUX_PAD(0x041C, 0x0108, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11 \
+ IOMUX_PAD(0x041C, 0x0108, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26 \
+ IOMUX_PAD(0x041C, 0x0108, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0 \
+ IOMUX_PAD(0x0420, 0x010C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11 \
+ IOMUX_PAD(0x0420, 0x010C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11 \
+ IOMUX_PAD(0x0420, 0x010C, 2, 0x08B4, 1, 0)
+#define _MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_TEST_OUT_0 \
+ IOMUX_PAD(0x0420, 0x010C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0420, 0x010C, 4, 0x07F0, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__GPIO_2_28 \
+ IOMUX_PAD(0x0420, 0x010C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12 \
+ IOMUX_PAD(0x0420, 0x010C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27 \
+ IOMUX_PAD(0x0420, 0x010C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1 \
+ IOMUX_PAD(0x0424, 0x0110, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10 \
+ IOMUX_PAD(0x0424, 0x0110, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10 \
+ IOMUX_PAD(0x0424, 0x0110, 2, 0x08B0, 1, 0)
+#define _MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY_TEST_OUT_1 \
+ IOMUX_PAD(0x0424, 0x0110, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB1__GPIO_2_29 \
+ IOMUX_PAD(0x0424, 0x0110, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13 \
+ IOMUX_PAD(0x0424, 0x0110, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28 \
+ IOMUX_PAD(0x0424, 0x0110, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 \
+ IOMUX_PAD(0x0428, 0x0114, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9 \
+ IOMUX_PAD(0x0428, 0x0114, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9 \
+ IOMUX_PAD(0x0428, 0x0114, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY_TEST_OUT_2 \
+ IOMUX_PAD(0x0428, 0x0114, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__GPIO_3_0 \
+ IOMUX_PAD(0x0428, 0x0114, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14 \
+ IOMUX_PAD(0x0428, 0x0114, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0 \
+ IOMUX_PAD(0x0428, 0x0114, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 \
+ IOMUX_PAD(0x042C, 0x0118, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8 \
+ IOMUX_PAD(0x042C, 0x0118, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8 \
+ IOMUX_PAD(0x042C, 0x0118, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_TEST_OUT_3 \
+ IOMUX_PAD(0x042C, 0x0118, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__ANATOP_USBPHY1_TSTI_TX_LS_MODE \
+ IOMUX_PAD(0x042C, 0x0118, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__GPIO_3_1 \
+ IOMUX_PAD(0x042C, 0x0118, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15 \
+ IOMUX_PAD(0x042C, 0x0118, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1 \
+ IOMUX_PAD(0x042C, 0x0118, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 \
+ IOMUX_PAD(0x0430, 0x011C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7 \
+ IOMUX_PAD(0x0430, 0x011C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7 \
+ IOMUX_PAD(0x0430, 0x011C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_TEST_OUT_4 \
+ IOMUX_PAD(0x0430, 0x011C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__ANATOP_USBPHY1_TSTI_TX_HS_MODE \
+ IOMUX_PAD(0x0430, 0x011C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__GPIO_3_2 \
+ IOMUX_PAD(0x0430, 0x011C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16 \
+ IOMUX_PAD(0x0430, 0x011C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2 \
+ IOMUX_PAD(0x0430, 0x011C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 \
+ IOMUX_PAD(0x0434, 0x0120, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6 \
+ IOMUX_PAD(0x0434, 0x0120, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6 \
+ IOMUX_PAD(0x0434, 0x0120, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_TEST_OUT_5 \
+ IOMUX_PAD(0x0434, 0x0120, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__ANATOP_USBPHY1_TSTI_TX_HIZ \
+ IOMUX_PAD(0x0434, 0x0120, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__GPIO_3_3 \
+ IOMUX_PAD(0x0434, 0x0120, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17 \
+ IOMUX_PAD(0x0434, 0x0120, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3 \
+ IOMUX_PAD(0x0434, 0x0120, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 \
+ IOMUX_PAD(0x0438, 0x0124, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5 \
+ IOMUX_PAD(0x0438, 0x0124, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5 \
+ IOMUX_PAD(0x0438, 0x0124, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_TEST_OUT_6 \
+ IOMUX_PAD(0x0438, 0x0124, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TSTI_TX_EN \
+ IOMUX_PAD(0x0438, 0x0124, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__GPIO_3_4 \
+ IOMUX_PAD(0x0438, 0x0124, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18 \
+ IOMUX_PAD(0x0438, 0x0124, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4 \
+ IOMUX_PAD(0x0438, 0x0124, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 \
+ IOMUX_PAD(0x043C, 0x0128, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4 \
+ IOMUX_PAD(0x043C, 0x0128, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4 \
+ IOMUX_PAD(0x043C, 0x0128, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_TEST_OUT_7 \
+ IOMUX_PAD(0x043C, 0x0128, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TSTI_TX_DP \
+ IOMUX_PAD(0x043C, 0x0128, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__GPIO_3_5 \
+ IOMUX_PAD(0x043C, 0x0128, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19 \
+ IOMUX_PAD(0x043C, 0x0128, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5 \
+ IOMUX_PAD(0x043C, 0x0128, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 \
+ IOMUX_PAD(0x0440, 0x012C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3 \
+ IOMUX_PAD(0x0440, 0x012C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3 \
+ IOMUX_PAD(0x0440, 0x012C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_TEST_OUT_8 \
+ IOMUX_PAD(0x0440, 0x012C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TSTI_TX_DN \
+ IOMUX_PAD(0x0440, 0x012C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__GPIO_3_6 \
+ IOMUX_PAD(0x0440, 0x012C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20 \
+ IOMUX_PAD(0x0440, 0x012C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6 \
+ IOMUX_PAD(0x0440, 0x012C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 \
+ IOMUX_PAD(0x0444, 0x0130, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2 \
+ IOMUX_PAD(0x0444, 0x0130, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2 \
+ IOMUX_PAD(0x0444, 0x0130, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_TEST_OUT_9 \
+ IOMUX_PAD(0x0444, 0x0130, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__GPIO_3_7 \
+ IOMUX_PAD(0x0444, 0x0130, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21 \
+ IOMUX_PAD(0x0444, 0x0130, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7 \
+ IOMUX_PAD(0x0444, 0x0130, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 \
+ IOMUX_PAD(0x0448, 0x0134, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1 \
+ IOMUX_PAD(0x0448, 0x0134, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1 \
+ IOMUX_PAD(0x0448, 0x0134, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_TEST_OUT_10 \
+ IOMUX_PAD(0x0448, 0x0134, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__GPIO_3_8 \
+ IOMUX_PAD(0x0448, 0x0134, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22 \
+ IOMUX_PAD(0x0448, 0x0134, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8 \
+ IOMUX_PAD(0x0448, 0x0134, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 \
+ IOMUX_PAD(0x044C, 0x0138, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0 \
+ IOMUX_PAD(0x044C, 0x0138, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0 \
+ IOMUX_PAD(0x044C, 0x0138, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_TEST_OUT_11 \
+ IOMUX_PAD(0x044C, 0x0138, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__GPIO_3_9 \
+ IOMUX_PAD(0x044C, 0x0138, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23 \
+ IOMUX_PAD(0x044C, 0x0138, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9 \
+ IOMUX_PAD(0x044C, 0x0138, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 \
+ IOMUX_PAD(0x0450, 0x013C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x0450, 0x013C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN \
+ IOMUX_PAD(0x0450, 0x013C, 2, 0x08D8, 1, 0)
+#define _MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_TEST_OUT_12 \
+ IOMUX_PAD(0x0450, 0x013C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA10__GPIO_3_10 \
+ IOMUX_PAD(0x0450, 0x013C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24 \
+ IOMUX_PAD(0x0450, 0x013C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10 \
+ IOMUX_PAD(0x0450, 0x013C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 \
+ IOMUX_PAD(0x0454, 0x0140, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x0454, 0x0140, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC \
+ IOMUX_PAD(0x0454, 0x0140, 2, 0x08DC, 1, 0)
+#define _MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_TEST_OUT_13 \
+ IOMUX_PAD(0x0454, 0x0140, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__SDMA_DEBUG_EVT_CHN_LINES_6 \
+ IOMUX_PAD(0x0454, 0x0140, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__GPIO_3_11 \
+ IOMUX_PAD(0x0454, 0x0140, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25 \
+ IOMUX_PAD(0x0454, 0x0140, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11 \
+ IOMUX_PAD(0x0454, 0x0140, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 \
+ IOMUX_PAD(0x0458, 0x0144, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x0458, 0x0144, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC \
+ IOMUX_PAD(0x0458, 0x0144, 2, 0x08E4, 1, 0)
+#define _MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_TEST_OUT_14 \
+ IOMUX_PAD(0x0458, 0x0144, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_LINES_3 \
+ IOMUX_PAD(0x0458, 0x0144, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__GPIO_3_12 \
+ IOMUX_PAD(0x0458, 0x0144, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26 \
+ IOMUX_PAD(0x0458, 0x0144, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12 \
+ IOMUX_PAD(0x0458, 0x0144, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 \
+ IOMUX_PAD(0x045C, 0x0148, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x045C, 0x0148, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x045C, 0x0148, 2, 0x07EC, 1, 0)
+#define _MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_TEST_OUT_15 \
+ IOMUX_PAD(0x045C, 0x0148, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_LINES_4 \
+ IOMUX_PAD(0x045C, 0x0148, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__GPIO_3_13 \
+ IOMUX_PAD(0x045C, 0x0148, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27 \
+ IOMUX_PAD(0x045C, 0x0148, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13 \
+ IOMUX_PAD(0x045C, 0x0148, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 \
+ IOMUX_PAD(0x0460, 0x014C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS \
+ IOMUX_PAD(0x0460, 0x014C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK \
+ IOMUX_PAD(0x0460, 0x014C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_TEST_OUT_16 \
+ IOMUX_PAD(0x0460, 0x014C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_LINES_5 \
+ IOMUX_PAD(0x0460, 0x014C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__GPIO_3_14 \
+ IOMUX_PAD(0x0460, 0x014C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28 \
+ IOMUX_PAD(0x0460, 0x014C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14 \
+ IOMUX_PAD(0x0460, 0x014C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 \
+ IOMUX_PAD(0x0464, 0x0150, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1 \
+ IOMUX_PAD(0x0464, 0x0150, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4 \
+ IOMUX_PAD(0x0464, 0x0150, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_TEST_OUT_17 \
+ IOMUX_PAD(0x0464, 0x0150, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__GPIO_3_15 \
+ IOMUX_PAD(0x0464, 0x0150, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29 \
+ IOMUX_PAD(0x0464, 0x0150, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15 \
+ IOMUX_PAD(0x0464, 0x0150, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT \
+ IOMUX_PAD(0x0468, 0x0154, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B \
+ IOMUX_PAD(0x0468, 0x0154, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_WAIT__GPIO_5_0 \
+ IOMUX_PAD(0x0468, 0x0154, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30 \
+ IOMUX_PAD(0x0468, 0x0154, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25 \
+ IOMUX_PAD(0x0468, 0x0154, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK \
+ IOMUX_PAD(0x046C, 0x0158, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 \
+ IOMUX_PAD(0x046C, 0x0158, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_BCLK__GPIO_6_31 \
+ IOMUX_PAD(0x046C, 0x0158, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31 \
+ IOMUX_PAD(0x046C, 0x0158, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK \
+ IOMUX_PAD(0x0470, 0x015C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK \
+ IOMUX_PAD(0x0470, 0x015C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_DISP_CLK__MIPI_CORE_DPHY_TEST_OUT_28 \
+ IOMUX_PAD(0x0470, 0x015C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 \
+ IOMUX_PAD(0x0470, 0x015C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16 \
+ IOMUX_PAD(0x0470, 0x015C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_DISP_CLK__MMDC_MMDC_DEBUG_0 \
+ IOMUX_PAD(0x0470, 0x015C, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 \
+ IOMUX_PAD(0x0474, 0x0160, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 \
+ IOMUX_PAD(0x0474, 0x0160, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC \
+ IOMUX_PAD(0x0474, 0x0160, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__MIPI_CORE_DPHY_TEST_OUT_29 \
+ IOMUX_PAD(0x0474, 0x0160, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 \
+ IOMUX_PAD(0x0474, 0x0160, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__GPIO_4_17 \
+ IOMUX_PAD(0x0474, 0x0160, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 \
+ IOMUX_PAD(0x0474, 0x0160, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2 \
+ IOMUX_PAD(0x0478, 0x0164, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2 \
+ IOMUX_PAD(0x0478, 0x0164, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD \
+ IOMUX_PAD(0x0478, 0x0164, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__MIPI_CORE_DPHY_TEST_OUT_30 \
+ IOMUX_PAD(0x0478, 0x0164, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 \
+ IOMUX_PAD(0x0478, 0x0164, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__GPIO_4_18 \
+ IOMUX_PAD(0x0478, 0x0164, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__MMDC_MMDC_DEBUG_2 \
+ IOMUX_PAD(0x0478, 0x0164, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN2__PL301_MX6QPER1_HADDR_9 \
+ IOMUX_PAD(0x0478, 0x0164, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3 \
+ IOMUX_PAD(0x047C, 0x0168, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3 \
+ IOMUX_PAD(0x047C, 0x0168, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS \
+ IOMUX_PAD(0x047C, 0x0168, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_TEST_OUT_31 \
+ IOMUX_PAD(0x047C, 0x0168, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 \
+ IOMUX_PAD(0x047C, 0x0168, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__GPIO_4_19 \
+ IOMUX_PAD(0x047C, 0x0168, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 \
+ IOMUX_PAD(0x047C, 0x0168, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN3__PL301_MX6QPER1_HADDR_10 \
+ IOMUX_PAD(0x047C, 0x0168, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4 \
+ IOMUX_PAD(0x0480, 0x016C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4 \
+ IOMUX_PAD(0x0480, 0x016C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD \
+ IOMUX_PAD(0x0480, 0x016C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__USDHC1_WP \
+ IOMUX_PAD(0x0480, 0x016C, 3, 0x094C, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD \
+ IOMUX_PAD(0x0480, 0x016C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__GPIO_4_20 \
+ IOMUX_PAD(0x0480, 0x016C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 \
+ IOMUX_PAD(0x0480, 0x016C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DI0_PIN4__PL301_MX6QPER1_HADDR_11 \
+ IOMUX_PAD(0x0480, 0x016C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 \
+ IOMUX_PAD(0x0484, 0x0170, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0 \
+ IOMUX_PAD(0x0484, 0x0170, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK \
+ IOMUX_PAD(0x0484, 0x0170, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DEBUG_0 \
+ IOMUX_PAD(0x0484, 0x0170, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN \
+ IOMUX_PAD(0x0484, 0x0170, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__GPIO_4_21 \
+ IOMUX_PAD(0x0484, 0x0170, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 \
+ IOMUX_PAD(0x0484, 0x0170, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 \
+ IOMUX_PAD(0x0488, 0x0174, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1 \
+ IOMUX_PAD(0x0488, 0x0174, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI \
+ IOMUX_PAD(0x0488, 0x0174, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DEBUG_1 \
+ IOMUX_PAD(0x0488, 0x0174, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL \
+ IOMUX_PAD(0x0488, 0x0174, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__GPIO_4_22 \
+ IOMUX_PAD(0x0488, 0x0174, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__MMDC_MMDC_DEBUG_6 \
+ IOMUX_PAD(0x0488, 0x0174, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT1__PL301_MX6QPER1_HADDR_12 \
+ IOMUX_PAD(0x0488, 0x0174, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 \
+ IOMUX_PAD(0x048C, 0x0178, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2 \
+ IOMUX_PAD(0x048C, 0x0178, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO \
+ IOMUX_PAD(0x048C, 0x0178, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DEBUG_2 \
+ IOMUX_PAD(0x048C, 0x0178, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE \
+ IOMUX_PAD(0x048C, 0x0178, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__GPIO_4_23 \
+ IOMUX_PAD(0x048C, 0x0178, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__MMDC_MMDC_DEBUG_7 \
+ IOMUX_PAD(0x048C, 0x0178, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT2__PL301_MX6QPER1_HADDR_13 \
+ IOMUX_PAD(0x048C, 0x0178, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 \
+ IOMUX_PAD(0x0490, 0x017C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3 \
+ IOMUX_PAD(0x0490, 0x017C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 \
+ IOMUX_PAD(0x0490, 0x017C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DEBUG_3 \
+ IOMUX_PAD(0x0490, 0x017C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR \
+ IOMUX_PAD(0x0490, 0x017C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__GPIO_4_24 \
+ IOMUX_PAD(0x0490, 0x017C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DEBUG_8 \
+ IOMUX_PAD(0x0490, 0x017C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT3__PL301_MX6QPER1_HADDR_14 \
+ IOMUX_PAD(0x0490, 0x017C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 \
+ IOMUX_PAD(0x0494, 0x0180, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4 \
+ IOMUX_PAD(0x0494, 0x0180, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 \
+ IOMUX_PAD(0x0494, 0x0180, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DEBUG_4 \
+ IOMUX_PAD(0x0494, 0x0180, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB \
+ IOMUX_PAD(0x0494, 0x0180, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__GPIO_4_25 \
+ IOMUX_PAD(0x0494, 0x0180, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 \
+ IOMUX_PAD(0x0494, 0x0180, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT4__PL301_MX6QPER1_HADDR_15 \
+ IOMUX_PAD(0x0494, 0x0180, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 \
+ IOMUX_PAD(0x0498, 0x0184, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5 \
+ IOMUX_PAD(0x0498, 0x0184, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 \
+ IOMUX_PAD(0x0498, 0x0184, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS \
+ IOMUX_PAD(0x0498, 0x0184, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS \
+ IOMUX_PAD(0x0498, 0x0184, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__GPIO_4_26 \
+ IOMUX_PAD(0x0498, 0x0184, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__MMDC_MMDC_DEBUG_10 \
+ IOMUX_PAD(0x0498, 0x0184, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT5__PL301_MX6QPER1_HADDR_16 \
+ IOMUX_PAD(0x0498, 0x0184, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 \
+ IOMUX_PAD(0x049C, 0x0188, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6 \
+ IOMUX_PAD(0x049C, 0x0188, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 \
+ IOMUX_PAD(0x049C, 0x0188, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC \
+ IOMUX_PAD(0x049C, 0x0188, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE \
+ IOMUX_PAD(0x049C, 0x0188, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__GPIO_4_27 \
+ IOMUX_PAD(0x049C, 0x0188, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__MMDC_MMDC_DEBUG_11 \
+ IOMUX_PAD(0x049C, 0x0188, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT6__PL301_MX6QPER1_HADDR_17 \
+ IOMUX_PAD(0x049C, 0x0188, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 \
+ IOMUX_PAD(0x04A0, 0x018C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7 \
+ IOMUX_PAD(0x04A0, 0x018C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY \
+ IOMUX_PAD(0x04A0, 0x018C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DEBUG_5 \
+ IOMUX_PAD(0x04A0, 0x018C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 \
+ IOMUX_PAD(0x04A0, 0x018C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__GPIO_4_28 \
+ IOMUX_PAD(0x04A0, 0x018C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__MMDC_MMDC_DEBUG_12 \
+ IOMUX_PAD(0x04A0, 0x018C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT7__PL301_MX6QPER1_HADDR_18 \
+ IOMUX_PAD(0x04A0, 0x018C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 \
+ IOMUX_PAD(0x04A4, 0x0190, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8 \
+ IOMUX_PAD(0x04A4, 0x0190, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__PWM1_PWMO \
+ IOMUX_PAD(0x04A4, 0x0190, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B \
+ IOMUX_PAD(0x04A4, 0x0190, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 \
+ IOMUX_PAD(0x04A4, 0x0190, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__GPIO_4_29 \
+ IOMUX_PAD(0x04A4, 0x0190, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__MMDC_MMDC_DEBUG_13 \
+ IOMUX_PAD(0x04A4, 0x0190, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT8__PL301_MX6QPER1_HADDR_19 \
+ IOMUX_PAD(0x04A4, 0x0190, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 \
+ IOMUX_PAD(0x04A8, 0x0194, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9 \
+ IOMUX_PAD(0x04A8, 0x0194, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__PWM2_PWMO \
+ IOMUX_PAD(0x04A8, 0x0194, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B \
+ IOMUX_PAD(0x04A8, 0x0194, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 \
+ IOMUX_PAD(0x04A8, 0x0194, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__GPIO_4_30 \
+ IOMUX_PAD(0x04A8, 0x0194, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__MMDC_MMDC_DEBUG_14 \
+ IOMUX_PAD(0x04A8, 0x0194, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT9__PL301_MX6QPER1_HADDR_20 \
+ IOMUX_PAD(0x04A8, 0x0194, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 \
+ IOMUX_PAD(0x04AC, 0x0198, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10 \
+ IOMUX_PAD(0x04AC, 0x0198, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__USDHC1_USDHC_DEBUG_6 \
+ IOMUX_PAD(0x04AC, 0x0198, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 \
+ IOMUX_PAD(0x04AC, 0x0198, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__GPIO_4_31 \
+ IOMUX_PAD(0x04AC, 0x0198, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__MMDC_MMDC_DEBUG_15 \
+ IOMUX_PAD(0x04AC, 0x0198, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT10__PL301_MX6QPER1_HADDR_21 \
+ IOMUX_PAD(0x04AC, 0x0198, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 \
+ IOMUX_PAD(0x04B0, 0x019C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11 \
+ IOMUX_PAD(0x04B0, 0x019C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DEBUG_7 \
+ IOMUX_PAD(0x04B0, 0x019C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 \
+ IOMUX_PAD(0x04B0, 0x019C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__GPIO_5_5 \
+ IOMUX_PAD(0x04B0, 0x019C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__MMDC_MMDC_DEBUG_16 \
+ IOMUX_PAD(0x04B0, 0x019C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT11__PL301_MX6QPER1_HADDR_22 \
+ IOMUX_PAD(0x04B0, 0x019C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 \
+ IOMUX_PAD(0x04B4, 0x01A0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12 \
+ IOMUX_PAD(0x04B4, 0x01A0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED \
+ IOMUX_PAD(0x04B4, 0x01A0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 \
+ IOMUX_PAD(0x04B4, 0x01A0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__GPIO_5_6 \
+ IOMUX_PAD(0x04B4, 0x01A0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__MMDC_MMDC_DEBUG_17 \
+ IOMUX_PAD(0x04B4, 0x01A0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT12__PL301_MX6QPER1_HADDR_23 \
+ IOMUX_PAD(0x04B4, 0x01A0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 \
+ IOMUX_PAD(0x04B8, 0x01A4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13 \
+ IOMUX_PAD(0x04B8, 0x01A4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x04B8, 0x01A4, 3, 0x07D8, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 \
+ IOMUX_PAD(0x04B8, 0x01A4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT13__GPIO_5_7 \
+ IOMUX_PAD(0x04B8, 0x01A4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT13__MMDC_MMDC_DEBUG_18 \
+ IOMUX_PAD(0x04B8, 0x01A4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT13__PL301_MX6QPER1_HADDR_24 \
+ IOMUX_PAD(0x04B8, 0x01A4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 \
+ IOMUX_PAD(0x04BC, 0x01A8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14 \
+ IOMUX_PAD(0x04BC, 0x01A8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x04BC, 0x01A8, 3, 0x07D4, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 \
+ IOMUX_PAD(0x04BC, 0x01A8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT14__GPIO_5_8 \
+ IOMUX_PAD(0x04BC, 0x01A8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT14__MMDC_MMDC_DEBUG_19 \
+ IOMUX_PAD(0x04BC, 0x01A8, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 \
+ IOMUX_PAD(0x04C0, 0x01AC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15 \
+ IOMUX_PAD(0x04C0, 0x01AC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 \
+ IOMUX_PAD(0x04C0, 0x01AC, 2, 0x0804, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 \
+ IOMUX_PAD(0x04C0, 0x01AC, 3, 0x0820, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 \
+ IOMUX_PAD(0x04C0, 0x01AC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT15__GPIO_5_9 \
+ IOMUX_PAD(0x04C0, 0x01AC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT15__MMDC_MMDC_DEBUG_20 \
+ IOMUX_PAD(0x04C0, 0x01AC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT15__PL301_MX6QPER1_HADDR_25 \
+ IOMUX_PAD(0x04C0, 0x01AC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 \
+ IOMUX_PAD(0x04C4, 0x01B0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16 \
+ IOMUX_PAD(0x04C4, 0x01B0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI \
+ IOMUX_PAD(0x04C4, 0x01B0, 2, 0x0818, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x04C4, 0x01B0, 3, 0x07DC, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x04C4, 0x01B0, 4, 0x090C, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__GPIO_5_10 \
+ IOMUX_PAD(0x04C4, 0x01B0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__MMDC_MMDC_DEBUG_21 \
+ IOMUX_PAD(0x04C4, 0x01B0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT16__PL301_MX6QPER1_HADDR_26 \
+ IOMUX_PAD(0x04C4, 0x01B0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 \
+ IOMUX_PAD(0x04C8, 0x01B4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17 \
+ IOMUX_PAD(0x04C8, 0x01B4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO \
+ IOMUX_PAD(0x04C8, 0x01B4, 2, 0x0814, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x04C8, 0x01B4, 3, 0x07D0, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x04C8, 0x01B4, 4, 0x0910, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__GPIO_5_11 \
+ IOMUX_PAD(0x04C8, 0x01B4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__MMDC_MMDC_DEBUG_22 \
+ IOMUX_PAD(0x04C8, 0x01B4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT17__PL301_MX6QPER1_HADDR_27 \
+ IOMUX_PAD(0x04C8, 0x01B4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 \
+ IOMUX_PAD(0x04CC, 0x01B8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18 \
+ IOMUX_PAD(0x04CC, 0x01B8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 \
+ IOMUX_PAD(0x04CC, 0x01B8, 2, 0x081C, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x04CC, 0x01B8, 3, 0x07E0, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x04CC, 0x01B8, 4, 0x07C0, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__GPIO_5_12 \
+ IOMUX_PAD(0x04CC, 0x01B8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__MMDC_MMDC_DEBUG_23 \
+ IOMUX_PAD(0x04CC, 0x01B8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x04CC, 0x01B8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 \
+ IOMUX_PAD(0x04D0, 0x01BC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19 \
+ IOMUX_PAD(0x04D0, 0x01BC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK \
+ IOMUX_PAD(0x04D0, 0x01BC, 2, 0x0810, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x04D0, 0x01BC, 3, 0x07CC, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x04D0, 0x01BC, 4, 0x07BC, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__GPIO_5_13 \
+ IOMUX_PAD(0x04D0, 0x01BC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__MMDC_MMDC_DEBUG_24 \
+ IOMUX_PAD(0x04D0, 0x01BC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x04D0, 0x01BC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 \
+ IOMUX_PAD(0x04D4, 0x01C0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20 \
+ IOMUX_PAD(0x04D4, 0x01C0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK \
+ IOMUX_PAD(0x04D4, 0x01C0, 2, 0x07F4, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x04D4, 0x01C0, 3, 0x07C4, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 \
+ IOMUX_PAD(0x04D4, 0x01C0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__GPIO_5_14 \
+ IOMUX_PAD(0x04D4, 0x01C0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__MMDC_MMDC_DEBUG_25 \
+ IOMUX_PAD(0x04D4, 0x01C0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT20__PL301_MX6QPER1_HADDR_28 \
+ IOMUX_PAD(0x04D4, 0x01C0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 \
+ IOMUX_PAD(0x04D8, 0x01C4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21 \
+ IOMUX_PAD(0x04D8, 0x01C4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI \
+ IOMUX_PAD(0x04D8, 0x01C4, 2, 0x07FC, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x04D8, 0x01C4, 3, 0x07B8, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 \
+ IOMUX_PAD(0x04D8, 0x01C4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT21__GPIO_5_15 \
+ IOMUX_PAD(0x04D8, 0x01C4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT21__MMDC_MMDC_DEBUG_26 \
+ IOMUX_PAD(0x04D8, 0x01C4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT21__PL301_MX6QPER1_HADDR_29 \
+ IOMUX_PAD(0x04D8, 0x01C4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 \
+ IOMUX_PAD(0x04DC, 0x01C8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22 \
+ IOMUX_PAD(0x04DC, 0x01C8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO \
+ IOMUX_PAD(0x04DC, 0x01C8, 2, 0x07F8, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x04DC, 0x01C8, 3, 0x07C8, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 \
+ IOMUX_PAD(0x04DC, 0x01C8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT22__GPIO_5_16 \
+ IOMUX_PAD(0x04DC, 0x01C8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT22__MMDC_MMDC_DEBUG_27 \
+ IOMUX_PAD(0x04DC, 0x01C8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT22__PL301_MX6QPER1_HADDR_30 \
+ IOMUX_PAD(0x04DC, 0x01C8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 \
+ IOMUX_PAD(0x04E0, 0x01CC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23 \
+ IOMUX_PAD(0x04E0, 0x01CC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 \
+ IOMUX_PAD(0x04E0, 0x01CC, 2, 0x0800, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x04E0, 0x01CC, 3, 0x07B4, 1, 0)
+#define _MX6Q_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 \
+ IOMUX_PAD(0x04E0, 0x01CC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT23__GPIO_5_17 \
+ IOMUX_PAD(0x04E0, 0x01CC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT23__MMDC_MMDC_DEBUG_28 \
+ IOMUX_PAD(0x04E0, 0x01CC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_DISP0_DAT23__PL301_MX6QPER1_HADDR_31 \
+ IOMUX_PAD(0x04E0, 0x01CC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED \
+ IOMUX_PAD(0x04E4, 0x01D0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__ENET_MDIO \
+ IOMUX_PAD(0x04E4, 0x01D0, 1, 0x0840, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__ESAI1_SCKR \
+ IOMUX_PAD(0x04E4, 0x01D0, 2, 0x086C, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEVICE_3 \
+ IOMUX_PAD(0x04E4, 0x01D0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT \
+ IOMUX_PAD(0x04E4, 0x01D0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__GPIO_1_22 \
+ IOMUX_PAD(0x04E4, 0x01D0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK \
+ IOMUX_PAD(0x04E4, 0x01D0, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_REF_CLK__RESERVED_RESERVED \
+ IOMUX_PAD(0x04E8, 0x01D4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK \
+ IOMUX_PAD(0x04E8, 0x01D4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR \
+ IOMUX_PAD(0x04E8, 0x01D4, 2, 0x085C, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 \
+ IOMUX_PAD(0x04E8, 0x01D4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__GPIO_1_23 \
+ IOMUX_PAD(0x04E8, 0x01D4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK \
+ IOMUX_PAD(0x04E8, 0x01D4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_REF_CLK__ANATOP_USBPHY1_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x04E8, 0x01D4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID \
+ IOMUX_PAD(0x04EC, 0x01D8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__ENET_RX_ER \
+ IOMUX_PAD(0x04EC, 0x01D8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR \
+ IOMUX_PAD(0x04EC, 0x01D8, 2, 0x0864, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__SPDIF_IN1 \
+ IOMUX_PAD(0x04EC, 0x01D8, 3, 0x0914, 1, 0)
+#define _MX6Q_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT \
+ IOMUX_PAD(0x04EC, 0x01D8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__GPIO_1_24 \
+ IOMUX_PAD(0x04EC, 0x01D8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__PHY_TDI \
+ IOMUX_PAD(0x04EC, 0x01D8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RX_ER__ANATOP_USBPHY1_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x04EC, 0x01D8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_CRS_DV__RESERVED_RESERVED \
+ IOMUX_PAD(0x04F0, 0x01DC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN \
+ IOMUX_PAD(0x04F0, 0x01DC, 1, 0x0858, 1, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT \
+ IOMUX_PAD(0x04F0, 0x01DC, 2, 0x0870, 0, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x04F0, 0x01DC, 3, 0x0918, 1, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__GPIO_1_25 \
+ IOMUX_PAD(0x04F0, 0x01DC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__PHY_TDO \
+ IOMUX_PAD(0x04F0, 0x01DC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_CRS_DV__ANATOP_USBPHY1_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x04F0, 0x01DC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_RXD1__MLB_MLBSIG \
+ IOMUX_PAD(0x04F4, 0x01E0, 0, 0x0908, 0, 0)
+#define _MX6Q_PAD_ENET_RXD1__ENET_RDATA_1 \
+ IOMUX_PAD(0x04F4, 0x01E0, 1, 0x084C, 1, 0)
+#define _MX6Q_PAD_ENET_RXD1__ESAI1_FST \
+ IOMUX_PAD(0x04F4, 0x01E0, 2, 0x0860, 0, 0)
+#define _MX6Q_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT \
+ IOMUX_PAD(0x04F4, 0x01E0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD1__GPIO_1_26 \
+ IOMUX_PAD(0x04F4, 0x01E0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD1__PHY_TCK \
+ IOMUX_PAD(0x04F4, 0x01E0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD1__ANATOP_USBPHY1_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x04F4, 0x01E0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT \
+ IOMUX_PAD(0x04F8, 0x01E4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD0__ENET_RDATA_0 \
+ IOMUX_PAD(0x04F8, 0x01E4, 1, 0x0848, 1, 0)
+#define _MX6Q_PAD_ENET_RXD0__ESAI1_HCKT \
+ IOMUX_PAD(0x04F8, 0x01E4, 2, 0x0868, 0, 0)
+#define _MX6Q_PAD_ENET_RXD0__SPDIF_OUT1 \
+ IOMUX_PAD(0x04F8, 0x01E4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD0__GPIO_1_27 \
+ IOMUX_PAD(0x04F8, 0x01E4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD0__PHY_TMS \
+ IOMUX_PAD(0x04F8, 0x01E4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_RXD0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x04F8, 0x01E4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_TX_EN__RESERVED_RESERVED \
+ IOMUX_PAD(0x04FC, 0x01E8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TX_EN__ENET_TX_EN \
+ IOMUX_PAD(0x04FC, 0x01E8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x04FC, 0x01E8, 2, 0x0880, 0, 0)
+#define _MX6Q_PAD_ENET_TX_EN__GPIO_1_28 \
+ IOMUX_PAD(0x04FC, 0x01E8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI \
+ IOMUX_PAD(0x04FC, 0x01E8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TX_EN__ANATOP_USBPHY2_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x04FC, 0x01E8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_TXD1__MLB_MLBCLK \
+ IOMUX_PAD(0x0500, 0x01EC, 0, 0x0900, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__ENET_TDATA_1 \
+ IOMUX_PAD(0x0500, 0x01EC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x0500, 0x01EC, 2, 0x087C, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN \
+ IOMUX_PAD(0x0500, 0x01EC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__GPIO_1_29 \
+ IOMUX_PAD(0x0500, 0x01EC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO \
+ IOMUX_PAD(0x0500, 0x01EC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD1__ANATOP_USBPHY2_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x0500, 0x01EC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_TXD0__RESERVED_RESERVED \
+ IOMUX_PAD(0x0504, 0x01F0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD0__ENET_TDATA_0 \
+ IOMUX_PAD(0x0504, 0x01F0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x0504, 0x01F0, 2, 0x0884, 0, 0)
+#define _MX6Q_PAD_ENET_TXD0__GPIO_1_30 \
+ IOMUX_PAD(0x0504, 0x01F0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK \
+ IOMUX_PAD(0x0504, 0x01F0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_TXD0__ANATOP_USBPHY2_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x0504, 0x01F0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_ENET_MDC__MLB_MLBDAT \
+ IOMUX_PAD(0x0508, 0x01F4, 0, 0x0904, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__ENET_MDC \
+ IOMUX_PAD(0x0508, 0x01F4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x0508, 0x01F4, 2, 0x0888, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN \
+ IOMUX_PAD(0x0508, 0x01F4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__GPIO_1_31 \
+ IOMUX_PAD(0x0508, 0x01F4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__SATA_PHY_TMS \
+ IOMUX_PAD(0x0508, 0x01F4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_ENET_MDC__ANATOP_USBPHY2_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x0508, 0x01F4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 \
+ IOMUX_PAD(0x050C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 \
+ IOMUX_PAD(0x0510, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 \
+ IOMUX_PAD(0x0514, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 \
+ IOMUX_PAD(0x0518, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 \
+ IOMUX_PAD(0x051C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 \
+ IOMUX_PAD(0x0520, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 \
+ IOMUX_PAD(0x0524, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 \
+ IOMUX_PAD(0x0528, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0 \
+ IOMUX_PAD(0x052C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1 \
+ IOMUX_PAD(0x0530, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2 \
+ IOMUX_PAD(0x0534, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3 \
+ IOMUX_PAD(0x0538, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4 \
+ IOMUX_PAD(0x053C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5 \
+ IOMUX_PAD(0x0540, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6 \
+ IOMUX_PAD(0x0544, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7 \
+ IOMUX_PAD(0x0548, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8 \
+ IOMUX_PAD(0x054C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9 \
+ IOMUX_PAD(0x0550, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10 \
+ IOMUX_PAD(0x0554, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11 \
+ IOMUX_PAD(0x0558, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12 \
+ IOMUX_PAD(0x055C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13 \
+ IOMUX_PAD(0x0560, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14 \
+ IOMUX_PAD(0x0564, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15 \
+ IOMUX_PAD(0x0568, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS \
+ IOMUX_PAD(0x056C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0 \
+ IOMUX_PAD(0x0570, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1 \
+ IOMUX_PAD(0x0574, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS \
+ IOMUX_PAD(0x0578, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET \
+ IOMUX_PAD(0x057C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 \
+ IOMUX_PAD(0x0580, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 \
+ IOMUX_PAD(0x0584, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 \
+ IOMUX_PAD(0x0588, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 \
+ IOMUX_PAD(0x058C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 \
+ IOMUX_PAD(0x0590, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 \
+ IOMUX_PAD(0x0594, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 \
+ IOMUX_PAD(0x0598, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 \
+ IOMUX_PAD(0x059C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 \
+ IOMUX_PAD(0x05A0, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE \
+ IOMUX_PAD(0x05A4, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 \
+ IOMUX_PAD(0x05A8, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 \
+ IOMUX_PAD(0x05AC, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 \
+ IOMUX_PAD(0x05B0, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 \
+ IOMUX_PAD(0x05B4, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 \
+ IOMUX_PAD(0x05B8, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 \
+ IOMUX_PAD(0x05BC, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 \
+ IOMUX_PAD(0x05C0, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 \
+ IOMUX_PAD(0x05C4, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_COL0__ECSPI1_SCLK \
+ IOMUX_PAD(0x05C8, 0x01F8, 0, 0x07F4, 2, 0)
+#define _MX6Q_PAD_KEY_COL0__ENET_RDATA_3 \
+ IOMUX_PAD(0x05C8, 0x01F8, 1, 0x0854, 1, 0)
+#define _MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x05C8, 0x01F8, 2, 0x07DC, 1, 0)
+#define _MX6Q_PAD_KEY_COL0__KPP_COL_0 \
+ IOMUX_PAD(0x05C8, 0x01F8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL0__UART4_TXD \
+ IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL0__UART4_RXD \
+ IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0938, 0, 0)
+#define _MX6Q_PAD_KEY_COL0__GPIO_4_6 \
+ IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x05C8, 0x01F8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST \
+ IOMUX_PAD(0x05C8, 0x01F8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI \
+ IOMUX_PAD(0x05CC, 0x01FC, 0, 0x07FC, 2, 0)
+#define _MX6Q_PAD_KEY_ROW0__ENET_TDATA_3 \
+ IOMUX_PAD(0x05CC, 0x01FC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x05CC, 0x01FC, 2, 0x07D0, 1, 0)
+#define _MX6Q_PAD_KEY_ROW0__KPP_ROW_0 \
+ IOMUX_PAD(0x05CC, 0x01FC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW0__UART4_TXD \
+ IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW0__UART4_RXD \
+ IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0938, 1, 0)
+#define _MX6Q_PAD_KEY_ROW0__GPIO_4_7 \
+ IOMUX_PAD(0x05CC, 0x01FC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x05CC, 0x01FC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW0__PL301_MX6QPER1_HADDR_0 \
+ IOMUX_PAD(0x05CC, 0x01FC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_COL1__ECSPI1_MISO \
+ IOMUX_PAD(0x05D0, 0x0200, 0, 0x07F8, 2, 0)
+#define _MX6Q_PAD_KEY_COL1__ENET_MDIO \
+ IOMUX_PAD(0x05D0, 0x0200, 1, 0x0840, 1, 0)
+#define _MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x05D0, 0x0200, 2, 0x07E0, 1, 0)
+#define _MX6Q_PAD_KEY_COL1__KPP_COL_1 \
+ IOMUX_PAD(0x05D0, 0x0200, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL1__UART5_TXD \
+ IOMUX_PAD(0x05D0, 0x0200, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL1__UART5_RXD \
+ IOMUX_PAD(0x05D0, 0x0200, 4, 0x0940, 0, 0)
+#define _MX6Q_PAD_KEY_COL1__GPIO_4_8 \
+ IOMUX_PAD(0x05D0, 0x0200, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL1__USDHC1_VSELECT \
+ IOMUX_PAD(0x05D0, 0x0200, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL1__PL301_MX6QPER1_HADDR_1 \
+ IOMUX_PAD(0x05D0, 0x0200, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 \
+ IOMUX_PAD(0x05D4, 0x0204, 0, 0x0800, 2, 0)
+#define _MX6Q_PAD_KEY_ROW1__ENET_COL \
+ IOMUX_PAD(0x05D4, 0x0204, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x05D4, 0x0204, 2, 0x07CC, 1, 0)
+#define _MX6Q_PAD_KEY_ROW1__KPP_ROW_1 \
+ IOMUX_PAD(0x05D4, 0x0204, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW1__UART5_TXD \
+ IOMUX_PAD(0x05D4, 0x0204, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW1__UART5_RXD \
+ IOMUX_PAD(0x05D4, 0x0204, 4, 0x0940, 1, 0)
+#define _MX6Q_PAD_KEY_ROW1__GPIO_4_9 \
+ IOMUX_PAD(0x05D4, 0x0204, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT \
+ IOMUX_PAD(0x05D4, 0x0204, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW1__PL301_MX6QPER1_HADDR_2 \
+ IOMUX_PAD(0x05D4, 0x0204, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_COL2__ECSPI1_SS1 \
+ IOMUX_PAD(0x05D8, 0x0208, 0, 0x0804, 2, 0)
+#define _MX6Q_PAD_KEY_COL2__ENET_RDATA_2 \
+ IOMUX_PAD(0x05D8, 0x0208, 1, 0x0850, 1, 0)
+#define _MX6Q_PAD_KEY_COL2__CAN1_TXCAN \
+ IOMUX_PAD(0x05D8, 0x0208, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL2__KPP_COL_2 \
+ IOMUX_PAD(0x05D8, 0x0208, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL2__ENET_MDC \
+ IOMUX_PAD(0x05D8, 0x0208, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL2__GPIO_4_10 \
+ IOMUX_PAD(0x05D8, 0x0208, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL2__USBOH3_H1USB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x05D8, 0x0208, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL2__PL301_MX6QPER1_HADDR_3 \
+ IOMUX_PAD(0x05D8, 0x0208, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 \
+ IOMUX_PAD(0x05DC, 0x020C, 0, 0x0808, 1, 0)
+#define _MX6Q_PAD_KEY_ROW2__ENET_TDATA_2 \
+ IOMUX_PAD(0x05DC, 0x020C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW2__CAN1_RXCAN \
+ IOMUX_PAD(0x05DC, 0x020C, 2, 0x07E4, 0, 0)
+#define _MX6Q_PAD_KEY_ROW2__KPP_ROW_2 \
+ IOMUX_PAD(0x05DC, 0x020C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT \
+ IOMUX_PAD(0x05DC, 0x020C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW2__GPIO_4_11 \
+ IOMUX_PAD(0x05DC, 0x020C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x05DC, 0x020C, 6, 0x088C, 1, 0)
+#define _MX6Q_PAD_KEY_ROW2__PL301_MX6QPER1_HADDR_4 \
+ IOMUX_PAD(0x05DC, 0x020C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_COL3__ECSPI1_SS3 \
+ IOMUX_PAD(0x05E0, 0x0210, 0, 0x080C, 1, 0)
+#define _MX6Q_PAD_KEY_COL3__ENET_CRS \
+ IOMUX_PAD(0x05E0, 0x0210, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x05E0, 0x0210, 2 | IOMUX_CONFIG_SION, 0x0890, 1, 0)
+#define _MX6Q_PAD_KEY_COL3__KPP_COL_3 \
+ IOMUX_PAD(0x05E0, 0x0210, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL3__I2C2_SCL \
+ IOMUX_PAD(0x05E0, 0x0210, 4 | IOMUX_CONFIG_SION, 0x08A0, 1, 0)
+#define _MX6Q_PAD_KEY_COL3__GPIO_4_12 \
+ IOMUX_PAD(0x05E0, 0x0210, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL3__SPDIF_IN1 \
+ IOMUX_PAD(0x05E0, 0x0210, 6, 0x0914, 2, 0)
+#define _MX6Q_PAD_KEY_COL3__PL301_MX6QPER1_HADDR_5 \
+ IOMUX_PAD(0x05E0, 0x0210, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT \
+ IOMUX_PAD(0x05E4, 0x0214, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05E4, 0x0214, 1, 0x07B0, 0, 0)
+#define _MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x05E4, 0x0214, 2 | IOMUX_CONFIG_SION, 0x0894, 1, 0)
+#define _MX6Q_PAD_KEY_ROW3__KPP_ROW_3 \
+ IOMUX_PAD(0x05E4, 0x0214, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW3__I2C2_SDA \
+ IOMUX_PAD(0x05E4, 0x0214, 4 | IOMUX_CONFIG_SION, 0x08A4, 1, 0)
+#define _MX6Q_PAD_KEY_ROW3__GPIO_4_13 \
+ IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT \
+ IOMUX_PAD(0x05E4, 0x0214, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW3__PL301_MX6QPER1_HADDR_6 \
+ IOMUX_PAD(0x05E4, 0x0214, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_COL4__CAN2_TXCAN \
+ IOMUX_PAD(0x05E8, 0x0218, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__IPU1_SISG_4 \
+ IOMUX_PAD(0x05E8, 0x0218, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x05E8, 0x0218, 2, 0x0944, 1, 0)
+#define _MX6Q_PAD_KEY_COL4__KPP_COL_4 \
+ IOMUX_PAD(0x05E8, 0x0218, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__UART5_CTS \
+ IOMUX_PAD(0x05E8, 0x0218, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__UART5_RTS \
+ IOMUX_PAD(0x05E8, 0x0218, 4, 0x093C, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__GPIO_4_14 \
+ IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__MMDC_MMDC_DEBUG_49 \
+ IOMUX_PAD(0x05E8, 0x0218, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_COL4__PL301_MX6QPER1_HADDR_7 \
+ IOMUX_PAD(0x05E8, 0x0218, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_KEY_ROW4__CAN2_RXCAN \
+ IOMUX_PAD(0x05EC, 0x021C, 0, 0x07E8, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__IPU1_SISG_5 \
+ IOMUX_PAD(0x05EC, 0x021C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x05EC, 0x021C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__KPP_ROW_4 \
+ IOMUX_PAD(0x05EC, 0x021C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__UART5_CTS \
+ IOMUX_PAD(0x05EC, 0x021C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__GPIO_4_15 \
+ IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__MMDC_MMDC_DEBUG_50 \
+ IOMUX_PAD(0x05EC, 0x021C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_KEY_ROW4__PL301_MX6QPER1_HADDR_8 \
+ IOMUX_PAD(0x05EC, 0x021C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_0__CCM_CLKO \
+ IOMUX_PAD(0x05F0, 0x0220, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_0__KPP_COL_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 2, 0x08E8, 0, 0)
+#define _MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05F0, 0x0220, 3, 0x07B0, 1, 0)
+#define _MX6Q_PAD_GPIO_0__EPIT1_EPITO \
+ IOMUX_PAD(0x05F0, 0x0220, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_0__GPIO_1_0 \
+ IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x05F0, 0x0220, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_0__SNVS_HP_WRAPPER_SNVS_VIO_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_1__ESAI1_SCKR \
+ IOMUX_PAD(0x05F4, 0x0224, 0, 0x086C, 1, 0)
+#define _MX6Q_PAD_GPIO_1__WDOG2_WDOG_B \
+ IOMUX_PAD(0x05F4, 0x0224, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_1__KPP_ROW_5 \
+ IOMUX_PAD(0x05F4, 0x0224, 2, 0x08F4, 0, 0)
+#define MX6Q_PAD_GPIO_1__USBOTG_ID \
+ IOMUX_PAD(0x05F4, 0x0224, 3, 0x0000, 0, MX6Q_USDHC_PAD_CTRL)
+#define _MX6Q_PAD_GPIO_1__PWM2_PWMO \
+ IOMUX_PAD(0x05F4, 0x0224, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_1__GPIO_1_1 \
+ IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_1__USDHC1_CD \
+ IOMUX_PAD(0x05F4, 0x0224, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_1__SRC_TESTER_ACK \
+ IOMUX_PAD(0x05F4, 0x0224, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_9__ESAI1_FSR \
+ IOMUX_PAD(0x05F8, 0x0228, 0, 0x085C, 1, 0)
+#define _MX6Q_PAD_GPIO_9__WDOG1_WDOG_B \
+ IOMUX_PAD(0x05F8, 0x0228, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_9__KPP_COL_6 \
+ IOMUX_PAD(0x05F8, 0x0228, 2, 0x08EC, 0, 0)
+#define _MX6Q_PAD_GPIO_9__CCM_REF_EN_B \
+ IOMUX_PAD(0x05F8, 0x0228, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_9__PWM1_PWMO \
+ IOMUX_PAD(0x05F8, 0x0228, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_9__GPIO_1_9 \
+ IOMUX_PAD(0x05F8, 0x0228, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_9__USDHC1_WP \
+ IOMUX_PAD(0x05F8, 0x0228, 6, 0x094C, 1, 0)
+#define _MX6Q_PAD_GPIO_9__SRC_EARLY_RST \
+ IOMUX_PAD(0x05F8, 0x0228, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_3__ESAI1_HCKR \
+ IOMUX_PAD(0x05FC, 0x022C, 0, 0x0864, 1, 0)
+#define _MX6Q_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 \
+ IOMUX_PAD(0x05FC, 0x022C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_3__I2C3_SCL \
+ IOMUX_PAD(0x05FC, 0x022C, 2 | IOMUX_CONFIG_SION, 0x08A8, 1, 0)
+#define _MX6Q_PAD_GPIO_3__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x05FC, 0x022C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_3__CCM_CLKO2 \
+ IOMUX_PAD(0x05FC, 0x022C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_3__GPIO_1_3 \
+ IOMUX_PAD(0x05FC, 0x022C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x05FC, 0x022C, 6, 0x0948, 1, 0)
+#define _MX6Q_PAD_GPIO_3__MLB_MLBCLK \
+ IOMUX_PAD(0x05FC, 0x022C, 7, 0x0900, 1, 0)
+
+#define _MX6Q_PAD_GPIO_6__ESAI1_SCKT \
+ IOMUX_PAD(0x0600, 0x0230, 0, 0x0870, 1, 0)
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define _MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ IOMUX_PAD(0x0600, 0x0230, 1 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#else
+#define _MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, 0)
+#endif
+#define _MX6Q_PAD_GPIO_6__I2C3_SDA \
+ IOMUX_PAD(0x0600, 0x0230, 2 | IOMUX_CONFIG_SION, 0x08AC, 1, 0)
+#define _MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 \
+ IOMUX_PAD(0x0600, 0x0230, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB \
+ IOMUX_PAD(0x0600, 0x0230, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_6__GPIO_1_6 \
+ IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_6__USDHC2_LCTL \
+ IOMUX_PAD(0x0600, 0x0230, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_6__MLB_MLBSIG \
+ IOMUX_PAD(0x0600, 0x0230, 7, 0x0908, 1, 0)
+
+#define _MX6Q_PAD_GPIO_2__ESAI1_FST \
+ IOMUX_PAD(0x0604, 0x0234, 0, 0x0860, 1, 0)
+#define _MX6Q_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 \
+ IOMUX_PAD(0x0604, 0x0234, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_2__KPP_ROW_6 \
+ IOMUX_PAD(0x0604, 0x0234, 2, 0x08F8, 1, 0)
+#define _MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1 \
+ IOMUX_PAD(0x0604, 0x0234, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 \
+ IOMUX_PAD(0x0604, 0x0234, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_2__GPIO_1_2 \
+ IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_2__USDHC2_WP \
+ IOMUX_PAD(0x0604, 0x0234, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_2__MLB_MLBDAT \
+ IOMUX_PAD(0x0604, 0x0234, 7, 0x0904, 1, 0)
+
+#define _MX6Q_PAD_GPIO_4__ESAI1_HCKT \
+ IOMUX_PAD(0x0608, 0x0238, 0, 0x0868, 1, 0)
+#define _MX6Q_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 \
+ IOMUX_PAD(0x0608, 0x0238, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_4__KPP_COL_7 \
+ IOMUX_PAD(0x0608, 0x0238, 2, 0x08F0, 1, 0)
+#define _MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2 \
+ IOMUX_PAD(0x0608, 0x0238, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 \
+ IOMUX_PAD(0x0608, 0x0238, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_4__GPIO_1_4 \
+ IOMUX_PAD(0x0608, 0x0238, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_4__USDHC2_CD \
+ IOMUX_PAD(0x0608, 0x0238, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_4__OCOTP_CTRL_WRAPPER_FUSE_LATCHED \
+ IOMUX_PAD(0x0608, 0x0238, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x060C, 0x023C, 0, 0x087C, 1, 0)
+#define _MX6Q_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 \
+ IOMUX_PAD(0x060C, 0x023C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_5__KPP_ROW_7 \
+ IOMUX_PAD(0x060C, 0x023C, 2, 0x08FC, 1, 0)
+#define _MX6Q_PAD_GPIO_5__CCM_CLKO \
+ IOMUX_PAD(0x060C, 0x023C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 \
+ IOMUX_PAD(0x060C, 0x023C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_5__GPIO_1_5 \
+ IOMUX_PAD(0x060C, 0x023C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_5__I2C3_SCL \
+ IOMUX_PAD(0x060C, 0x023C, 6 | IOMUX_CONFIG_SION, 0x08A8, 2, 0)
+#define _MX6Q_PAD_GPIO_5__CHEETAH_EVENTI \
+ IOMUX_PAD(0x060C, 0x023C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x0610, 0x0240, 0, 0x0884, 1, 0)
+#define _MX6Q_PAD_GPIO_7__ECSPI5_RDY \
+ IOMUX_PAD(0x0610, 0x0240, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__EPIT1_EPITO \
+ IOMUX_PAD(0x0610, 0x0240, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__CAN1_TXCAN \
+ IOMUX_PAD(0x0610, 0x0240, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__UART2_TXD \
+ IOMUX_PAD(0x0610, 0x0240, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__UART2_RXD \
+ IOMUX_PAD(0x0610, 0x0240, 4, 0x0928, 2, 0)
+#define _MX6Q_PAD_GPIO_7__GPIO_1_7 \
+ IOMUX_PAD(0x0610, 0x0240, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__SPDIF_PLOCK \
+ IOMUX_PAD(0x0610, 0x0240, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HOST_MODE \
+ IOMUX_PAD(0x0610, 0x0240, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x0614, 0x0244, 0, 0x0888, 1, 0)
+#define _MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT \
+ IOMUX_PAD(0x0614, 0x0244, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_8__EPIT2_EPITO \
+ IOMUX_PAD(0x0614, 0x0244, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_8__CAN1_RXCAN \
+ IOMUX_PAD(0x0614, 0x0244, 3, 0x07E4, 1, 0)
+#define _MX6Q_PAD_GPIO_8__UART2_TXD \
+ IOMUX_PAD(0x0614, 0x0244, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_8__UART2_RXD \
+ IOMUX_PAD(0x0614, 0x0244, 4, 0x0928, 3, 0)
+#define _MX6Q_PAD_GPIO_8__GPIO_1_8 \
+ IOMUX_PAD(0x0614, 0x0244, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_8__SPDIF_SRCLK \
+ IOMUX_PAD(0x0614, 0x0244, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_8__USBOH3_OTGUSB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x0614, 0x0244, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x0618, 0x0248, 0, 0x0880, 1, 0)
+#define _MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN \
+ IOMUX_PAD(0x0618, 0x0248, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x0618, 0x0248, 0x12, 0x083C, 1, 0)
+#define _MX6Q_PAD_GPIO_16__USDHC1_LCTL \
+ IOMUX_PAD(0x0618, 0x0248, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_16__SPDIF_IN1 \
+ IOMUX_PAD(0x0618, 0x0248, 4, 0x0914, 3, 0)
+#define _MX6Q_PAD_GPIO_16__GPIO_7_11 \
+ IOMUX_PAD(0x0618, 0x0248, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_16__I2C3_SDA \
+ IOMUX_PAD(0x0618, 0x0248, 6 | IOMUX_CONFIG_SION, 0x08AC, 2, 0)
+#define _MX6Q_PAD_GPIO_16__SJC_DE_B \
+ IOMUX_PAD(0x0618, 0x0248, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_17__ESAI1_TX0 \
+ IOMUX_PAD(0x061C, 0x024C, 0, 0x0874, 0, 0)
+#define _MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN \
+ IOMUX_PAD(0x061C, 0x024C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_17__CCM_PMIC_RDY \
+ IOMUX_PAD(0x061C, 0x024C, 2, 0x07F0, 1, 0)
+#define _MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x061C, 0x024C, 3, 0x090C, 1, 0)
+#define _MX6Q_PAD_GPIO_17__SPDIF_OUT1 \
+ IOMUX_PAD(0x061C, 0x024C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_17__GPIO_7_12 \
+ IOMUX_PAD(0x061C, 0x024C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_17__SJC_JTAG_ACT \
+ IOMUX_PAD(0x061C, 0x024C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_18__ESAI1_TX1 \
+ IOMUX_PAD(0x0620, 0x0250, 0, 0x0878, 0, 0)
+#define _MX6Q_PAD_GPIO_18__ENET_RX_CLK \
+ IOMUX_PAD(0x0620, 0x0250, 1, 0x0844, 1, 0)
+#define _MX6Q_PAD_GPIO_18__USDHC3_VSELECT \
+ IOMUX_PAD(0x0620, 0x0250, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x0620, 0x0250, 3, 0x0910, 1, 0)
+#define _MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x0620, 0x0250, 4, 0x07B0, 2, 0)
+#define _MX6Q_PAD_GPIO_18__GPIO_7_13 \
+ IOMUX_PAD(0x0620, 0x0250, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_18__SNVS_HP_WRAPPER_SNVS_VIO_5_CTL \
+ IOMUX_PAD(0x0620, 0x0250, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST \
+ IOMUX_PAD(0x0620, 0x0250, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_GPIO_19__KPP_COL_5 \
+ IOMUX_PAD(0x0624, 0x0254, 0, 0x08E8, 1, 0)
+#define _MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT \
+ IOMUX_PAD(0x0624, 0x0254, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__SPDIF_OUT1 \
+ IOMUX_PAD(0x0624, 0x0254, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__CCM_CLKO \
+ IOMUX_PAD(0x0624, 0x0254, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__ECSPI1_RDY \
+ IOMUX_PAD(0x0624, 0x0254, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__GPIO_4_5 \
+ IOMUX_PAD(0x0624, 0x0254, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__ENET_TX_ER \
+ IOMUX_PAD(0x0624, 0x0254, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_GPIO_19__SRC_INT_BOOT \
+ IOMUX_PAD(0x0624, 0x0254, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK \
+ IOMUX_PAD(0x0628, 0x0258, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_12 \
+ IOMUX_PAD(0x0628, 0x0258, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 \
+ IOMUX_PAD(0x0628, 0x0258, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18 \
+ IOMUX_PAD(0x0628, 0x0258, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_PIXCLK__MMDC_MMDC_DEBUG_29 \
+ IOMUX_PAD(0x0628, 0x0258, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO \
+ IOMUX_PAD(0x0628, 0x0258, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC \
+ IOMUX_PAD(0x062C, 0x025C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_13 \
+ IOMUX_PAD(0x062C, 0x025C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__CCM_CLKO \
+ IOMUX_PAD(0x062C, 0x025C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 \
+ IOMUX_PAD(0x062C, 0x025C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__GPIO_5_19 \
+ IOMUX_PAD(0x062C, 0x025C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 \
+ IOMUX_PAD(0x062C, 0x025C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL \
+ IOMUX_PAD(0x062C, 0x025C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN \
+ IOMUX_PAD(0x0630, 0x0260, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 \
+ IOMUX_PAD(0x0630, 0x0260, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_DIAG_STATUS_BUS_MUX_14 \
+ IOMUX_PAD(0x0630, 0x0260, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 \
+ IOMUX_PAD(0x0630, 0x0260, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20 \
+ IOMUX_PAD(0x0630, 0x0260, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__MMDC_MMDC_DEBUG_31 \
+ IOMUX_PAD(0x0630, 0x0260, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK \
+ IOMUX_PAD(0x0630, 0x0260, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC \
+ IOMUX_PAD(0x0634, 0x0264, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 \
+ IOMUX_PAD(0x0634, 0x0264, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_DIAG_STATUS_BUS_MUX_15 \
+ IOMUX_PAD(0x0634, 0x0264, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 \
+ IOMUX_PAD(0x0634, 0x0264, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__GPIO_5_21 \
+ IOMUX_PAD(0x0634, 0x0264, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__MMDC_MMDC_DEBUG_32 \
+ IOMUX_PAD(0x0634, 0x0264, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0 \
+ IOMUX_PAD(0x0634, 0x0264, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4 \
+ IOMUX_PAD(0x0638, 0x0268, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2 \
+ IOMUX_PAD(0x0638, 0x0268, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK \
+ IOMUX_PAD(0x0638, 0x0268, 2, 0x07F4, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT4__KPP_COL_5 \
+ IOMUX_PAD(0x0638, 0x0268, 3, 0x08E8, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC \
+ IOMUX_PAD(0x0638, 0x0268, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT4__GPIO_5_22 \
+ IOMUX_PAD(0x0638, 0x0268, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT4__MMDC_MMDC_DEBUG_43 \
+ IOMUX_PAD(0x0638, 0x0268, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1 \
+ IOMUX_PAD(0x0638, 0x0268, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5 \
+ IOMUX_PAD(0x063C, 0x026C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3 \
+ IOMUX_PAD(0x063C, 0x026C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI \
+ IOMUX_PAD(0x063C, 0x026C, 2, 0x07FC, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT5__KPP_ROW_5 \
+ IOMUX_PAD(0x063C, 0x026C, 3, 0x08F4, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD \
+ IOMUX_PAD(0x063C, 0x026C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT5__GPIO_5_23 \
+ IOMUX_PAD(0x063C, 0x026C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 \
+ IOMUX_PAD(0x063C, 0x026C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2 \
+ IOMUX_PAD(0x063C, 0x026C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6 \
+ IOMUX_PAD(0x0640, 0x0270, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4 \
+ IOMUX_PAD(0x0640, 0x0270, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO \
+ IOMUX_PAD(0x0640, 0x0270, 2, 0x07F8, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT6__KPP_COL_6 \
+ IOMUX_PAD(0x0640, 0x0270, 3, 0x08EC, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS \
+ IOMUX_PAD(0x0640, 0x0270, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT6__GPIO_5_24 \
+ IOMUX_PAD(0x0640, 0x0270, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 \
+ IOMUX_PAD(0x0640, 0x0270, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3 \
+ IOMUX_PAD(0x0640, 0x0270, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7 \
+ IOMUX_PAD(0x0644, 0x0274, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5 \
+ IOMUX_PAD(0x0644, 0x0274, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 \
+ IOMUX_PAD(0x0644, 0x0274, 2, 0x0800, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT7__KPP_ROW_6 \
+ IOMUX_PAD(0x0644, 0x0274, 3, 0x08F8, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD \
+ IOMUX_PAD(0x0644, 0x0274, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT7__GPIO_5_25 \
+ IOMUX_PAD(0x0644, 0x0274, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 \
+ IOMUX_PAD(0x0644, 0x0274, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4 \
+ IOMUX_PAD(0x0644, 0x0274, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8 \
+ IOMUX_PAD(0x0648, 0x0278, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6 \
+ IOMUX_PAD(0x0648, 0x0278, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK \
+ IOMUX_PAD(0x0648, 0x0278, 2, 0x0810, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT8__KPP_COL_7 \
+ IOMUX_PAD(0x0648, 0x0278, 3, 0x08F0, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT8__I2C1_SDA \
+ IOMUX_PAD(0x0648, 0x0278, 4 | IOMUX_CONFIG_SION, 0x089C, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT8__GPIO_5_26 \
+ IOMUX_PAD(0x0648, 0x0278, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 \
+ IOMUX_PAD(0x0648, 0x0278, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5 \
+ IOMUX_PAD(0x0648, 0x0278, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9 \
+ IOMUX_PAD(0x064C, 0x027C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7 \
+ IOMUX_PAD(0x064C, 0x027C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI \
+ IOMUX_PAD(0x064C, 0x027C, 2, 0x0818, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT9__KPP_ROW_7 \
+ IOMUX_PAD(0x064C, 0x027C, 3, 0x08FC, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT9__I2C1_SCL \
+ IOMUX_PAD(0x064C, 0x027C, 4 | IOMUX_CONFIG_SION, 0x0898, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT9__GPIO_5_27 \
+ IOMUX_PAD(0x064C, 0x027C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 \
+ IOMUX_PAD(0x064C, 0x027C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6 \
+ IOMUX_PAD(0x064C, 0x027C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10 \
+ IOMUX_PAD(0x0650, 0x0280, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC \
+ IOMUX_PAD(0x0650, 0x0280, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO \
+ IOMUX_PAD(0x0650, 0x0280, 2, 0x0814, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT10__UART1_TXD \
+ IOMUX_PAD(0x0650, 0x0280, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__UART1_RXD \
+ IOMUX_PAD(0x0650, 0x0280, 3, 0x0920, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 \
+ IOMUX_PAD(0x0650, 0x0280, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__GPIO_5_28 \
+ IOMUX_PAD(0x0650, 0x0280, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 \
+ IOMUX_PAD(0x0650, 0x0280, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7 \
+ IOMUX_PAD(0x0650, 0x0280, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11 \
+ IOMUX_PAD(0x0654, 0x0284, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS \
+ IOMUX_PAD(0x0654, 0x0284, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 \
+ IOMUX_PAD(0x0654, 0x0284, 2, 0x081C, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT11__UART1_TXD \
+ IOMUX_PAD(0x0654, 0x0284, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__UART1_RXD \
+ IOMUX_PAD(0x0654, 0x0284, 3, 0x0920, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 \
+ IOMUX_PAD(0x0654, 0x0284, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__GPIO_5_29 \
+ IOMUX_PAD(0x0654, 0x0284, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 \
+ IOMUX_PAD(0x0654, 0x0284, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8 \
+ IOMUX_PAD(0x0654, 0x0284, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12 \
+ IOMUX_PAD(0x0658, 0x0288, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8 \
+ IOMUX_PAD(0x0658, 0x0288, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_DIAG_STATUS_BUS_MUX_16 \
+ IOMUX_PAD(0x0658, 0x0288, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__UART4_TXD \
+ IOMUX_PAD(0x0658, 0x0288, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__UART4_RXD \
+ IOMUX_PAD(0x0658, 0x0288, 3, 0x0938, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 \
+ IOMUX_PAD(0x0658, 0x0288, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__GPIO_5_30 \
+ IOMUX_PAD(0x0658, 0x0288, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 \
+ IOMUX_PAD(0x0658, 0x0288, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9 \
+ IOMUX_PAD(0x0658, 0x0288, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13 \
+ IOMUX_PAD(0x065C, 0x028C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9 \
+ IOMUX_PAD(0x065C, 0x028C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_DIAG_STATUS_BUS_MUX_17 \
+ IOMUX_PAD(0x065C, 0x028C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__UART4_TXD \
+ IOMUX_PAD(0x065C, 0x028C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__UART4_RXD \
+ IOMUX_PAD(0x065C, 0x028C, 3, 0x0938, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 \
+ IOMUX_PAD(0x065C, 0x028C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__GPIO_5_31 \
+ IOMUX_PAD(0x065C, 0x028C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 \
+ IOMUX_PAD(0x065C, 0x028C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10 \
+ IOMUX_PAD(0x065C, 0x028C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14 \
+ IOMUX_PAD(0x0660, 0x0290, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10 \
+ IOMUX_PAD(0x0660, 0x0290, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_DIAG_STATUS_BUS_MUX_18 \
+ IOMUX_PAD(0x0660, 0x0290, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__UART5_TXD \
+ IOMUX_PAD(0x0660, 0x0290, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__UART5_RXD \
+ IOMUX_PAD(0x0660, 0x0290, 3, 0x0940, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 \
+ IOMUX_PAD(0x0660, 0x0290, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__GPIO_6_0 \
+ IOMUX_PAD(0x0660, 0x0290, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 \
+ IOMUX_PAD(0x0660, 0x0290, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11 \
+ IOMUX_PAD(0x0660, 0x0290, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15 \
+ IOMUX_PAD(0x0664, 0x0294, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11 \
+ IOMUX_PAD(0x0664, 0x0294, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_DIAG_STATUS_BUS_MUX_19 \
+ IOMUX_PAD(0x0664, 0x0294, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__UART5_TXD \
+ IOMUX_PAD(0x0664, 0x0294, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__UART5_RXD \
+ IOMUX_PAD(0x0664, 0x0294, 3, 0x0940, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 \
+ IOMUX_PAD(0x0664, 0x0294, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__GPIO_6_1 \
+ IOMUX_PAD(0x0664, 0x0294, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 \
+ IOMUX_PAD(0x0664, 0x0294, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12 \
+ IOMUX_PAD(0x0664, 0x0294, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16 \
+ IOMUX_PAD(0x0668, 0x0298, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12 \
+ IOMUX_PAD(0x0668, 0x0298, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_DIAG_STATUS_BUS_MUX_20 \
+ IOMUX_PAD(0x0668, 0x0298, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__UART4_CTS \
+ IOMUX_PAD(0x0668, 0x0298, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__UART4_RTS \
+ IOMUX_PAD(0x0668, 0x0298, 3, 0x0934, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 \
+ IOMUX_PAD(0x0668, 0x0298, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__GPIO_6_2 \
+ IOMUX_PAD(0x0668, 0x0298, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 \
+ IOMUX_PAD(0x0668, 0x0298, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13 \
+ IOMUX_PAD(0x0668, 0x0298, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17 \
+ IOMUX_PAD(0x066C, 0x029C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13 \
+ IOMUX_PAD(0x066C, 0x029C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_DIAG_STATUS_BUS_MUX_21 \
+ IOMUX_PAD(0x066C, 0x029C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__UART4_CTS \
+ IOMUX_PAD(0x066C, 0x029C, 3, 0x0934, 1, 0)
+#define _MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 \
+ IOMUX_PAD(0x066C, 0x029C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__GPIO_6_3 \
+ IOMUX_PAD(0x066C, 0x029C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 \
+ IOMUX_PAD(0x066C, 0x029C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14 \
+ IOMUX_PAD(0x066C, 0x029C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18 \
+ IOMUX_PAD(0x0670, 0x02A0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14 \
+ IOMUX_PAD(0x0670, 0x02A0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_DIAG_STATUS_BUS_MUX_22 \
+ IOMUX_PAD(0x0670, 0x02A0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__UART5_CTS \
+ IOMUX_PAD(0x0670, 0x02A0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__UART5_RTS \
+ IOMUX_PAD(0x0670, 0x02A0, 3, 0x093C, 2, 0)
+#define _MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 \
+ IOMUX_PAD(0x0670, 0x02A0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__GPIO_6_4 \
+ IOMUX_PAD(0x0670, 0x02A0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 \
+ IOMUX_PAD(0x0670, 0x02A0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15 \
+ IOMUX_PAD(0x0670, 0x02A0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19 \
+ IOMUX_PAD(0x0674, 0x02A4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15 \
+ IOMUX_PAD(0x0674, 0x02A4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_DIAG_STATUS_BUS_MUX_23 \
+ IOMUX_PAD(0x0674, 0x02A4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__UART5_CTS \
+ IOMUX_PAD(0x0674, 0x02A4, 3, 0x093C, 3, 0)
+#define _MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 \
+ IOMUX_PAD(0x0674, 0x02A4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__GPIO_6_5 \
+ IOMUX_PAD(0x0674, 0x02A4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 \
+ IOMUX_PAD(0x0674, 0x02A4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_CSI0_DAT19__ANATOP_ANATOP_TESTO_9 \
+ IOMUX_PAD(0x0674, 0x02A4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_TMS__SJC_TMS \
+ IOMUX_PAD(0x0678, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_MOD__SJC_MOD \
+ IOMUX_PAD(0x067C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB \
+ IOMUX_PAD(0x0680, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_TDI__SJC_TDI \
+ IOMUX_PAD(0x0684, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_TCK__SJC_TCK \
+ IOMUX_PAD(0x0688, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_JTAG_TDO__SJC_TDO \
+ IOMUX_PAD(0x068C, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_TAMPER__SNVS_LP_WRAPPER_SNVS_TD1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_POR_B__SRC_POR_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_RESET_IN_B__SRC_RESET_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_TEST_MODE__TCU_TEST_MODE \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 \
+ IOMUX_PAD(0x0690, 0x02A8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__UART1_TXD \
+ IOMUX_PAD(0x0690, 0x02A8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__UART1_RXD \
+ IOMUX_PAD(0x0690, 0x02A8, 1, 0x0920, 2, 0)
+#define _MX6Q_PAD_SD3_DAT7__PCIE_CTRL_DIAG_STATUS_BUS_MUX_24 \
+ IOMUX_PAD(0x0690, 0x02A8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 \
+ IOMUX_PAD(0x0690, 0x02A8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 \
+ IOMUX_PAD(0x0690, 0x02A8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__GPIO_6_17 \
+ IOMUX_PAD(0x0690, 0x02A8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_TEST_IN_12 \
+ IOMUX_PAD(0x0690, 0x02A8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT7__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x0690, 0x02A8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 \
+ IOMUX_PAD(0x0694, 0x02AC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__UART1_TXD \
+ IOMUX_PAD(0x0694, 0x02AC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__UART1_RXD \
+ IOMUX_PAD(0x0694, 0x02AC, 1, 0x0920, 3, 0)
+#define _MX6Q_PAD_SD3_DAT6__PCIE_CTRL_DIAG_STATUS_BUS_MUX_25 \
+ IOMUX_PAD(0x0694, 0x02AC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 \
+ IOMUX_PAD(0x0694, 0x02AC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 \
+ IOMUX_PAD(0x0694, 0x02AC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__GPIO_6_18 \
+ IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_TEST_IN_13 \
+ IOMUX_PAD(0x0694, 0x02AC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT6__ANATOP_ANATOP_TESTO_10 \
+ IOMUX_PAD(0x0694, 0x02AC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 \
+ IOMUX_PAD(0x0698, 0x02B0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__UART2_TXD \
+ IOMUX_PAD(0x0698, 0x02B0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__UART2_RXD \
+ IOMUX_PAD(0x0698, 0x02B0, 1, 0x0928, 4, 0)
+#define _MX6Q_PAD_SD3_DAT5__PCIE_CTRL_DIAG_STATUS_BUS_MUX_26 \
+ IOMUX_PAD(0x0698, 0x02B0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 \
+ IOMUX_PAD(0x0698, 0x02B0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 \
+ IOMUX_PAD(0x0698, 0x02B0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__GPIO_7_0 \
+ IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_TEST_IN_14 \
+ IOMUX_PAD(0x0698, 0x02B0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT5__ANATOP_ANATOP_TESTO_11 \
+ IOMUX_PAD(0x0698, 0x02B0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 \
+ IOMUX_PAD(0x069C, 0x02B4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__UART2_TXD \
+ IOMUX_PAD(0x069C, 0x02B4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__UART2_RXD \
+ IOMUX_PAD(0x069C, 0x02B4, 1, 0x0928, 5, 0)
+#define _MX6Q_PAD_SD3_DAT4__PCIE_CTRL_DIAG_STATUS_BUS_MUX_27 \
+ IOMUX_PAD(0x069C, 0x02B4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 \
+ IOMUX_PAD(0x069C, 0x02B4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 \
+ IOMUX_PAD(0x069C, 0x02B4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__GPIO_7_1 \
+ IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_TEST_IN_15 \
+ IOMUX_PAD(0x069C, 0x02B4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT4__ANATOP_ANATOP_TESTO_12 \
+ IOMUX_PAD(0x069C, 0x02B4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_CMD__USDHC3_CMD \
+ IOMUX_PAD(0x06A0, 0x02B8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__UART2_CTS \
+ IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0924, 2, 0)
+#define _MX6Q_PAD_SD3_CMD__CAN1_TXCAN \
+ IOMUX_PAD(0x06A0, 0x02B8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 \
+ IOMUX_PAD(0x06A0, 0x02B8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 \
+ IOMUX_PAD(0x06A0, 0x02B8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__GPIO_7_2 \
+ IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_TEST_IN_16 \
+ IOMUX_PAD(0x06A0, 0x02B8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CMD__ANATOP_ANATOP_TESTO_13 \
+ IOMUX_PAD(0x06A0, 0x02B8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_CLK__USDHC3_CLK \
+ IOMUX_PAD(0x06A4, 0x02BC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__UART2_CTS \
+ IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__UART2_RTS \
+ IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0924, 3, 0)
+#define _MX6Q_PAD_SD3_CLK__CAN1_RXCAN \
+ IOMUX_PAD(0x06A4, 0x02BC, 2, 0x07E4, 2, 0)
+#define _MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 \
+ IOMUX_PAD(0x06A4, 0x02BC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 \
+ IOMUX_PAD(0x06A4, 0x02BC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__GPIO_7_3 \
+ IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_TEST_IN_17 \
+ IOMUX_PAD(0x06A4, 0x02BC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_CLK__ANATOP_ANATOP_TESTO_14 \
+ IOMUX_PAD(0x06A4, 0x02BC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 \
+ IOMUX_PAD(0x06A8, 0x02C0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__UART1_CTS \
+ IOMUX_PAD(0x06A8, 0x02C0, 1, 0x091C, 2, 0)
+#define _MX6Q_PAD_SD3_DAT0__CAN2_TXCAN \
+ IOMUX_PAD(0x06A8, 0x02C0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 \
+ IOMUX_PAD(0x06A8, 0x02C0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 \
+ IOMUX_PAD(0x06A8, 0x02C0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__GPIO_7_4 \
+ IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_TEST_IN_18 \
+ IOMUX_PAD(0x06A8, 0x02C0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT0__ANATOP_ANATOP_TESTO_15 \
+ IOMUX_PAD(0x06A8, 0x02C0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 \
+ IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__UART1_CTS \
+ IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__UART1_RTS \
+ IOMUX_PAD(0x06AC, 0x02C4, 1, 0x091C, 3, 0)
+#define _MX6Q_PAD_SD3_DAT1__CAN2_RXCAN \
+ IOMUX_PAD(0x06AC, 0x02C4, 2, 0x07E8, 1, 0)
+#define _MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 \
+ IOMUX_PAD(0x06AC, 0x02C4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 \
+ IOMUX_PAD(0x06AC, 0x02C4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__GPIO_7_5 \
+ IOMUX_PAD(0x06AC, 0x02C4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_TEST_IN_19 \
+ IOMUX_PAD(0x06AC, 0x02C4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT1__ANATOP_ANATOP_TESTI_0 \
+ IOMUX_PAD(0x06AC, 0x02C4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 \
+ IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__PCIE_CTRL_DIAG_STATUS_BUS_MUX_28 \
+ IOMUX_PAD(0x06B0, 0x02C8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 \
+ IOMUX_PAD(0x06B0, 0x02C8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 \
+ IOMUX_PAD(0x06B0, 0x02C8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__GPIO_7_6 \
+ IOMUX_PAD(0x06B0, 0x02C8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_TEST_IN_20 \
+ IOMUX_PAD(0x06B0, 0x02C8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT2__ANATOP_ANATOP_TESTI_1 \
+ IOMUX_PAD(0x06B0, 0x02C8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 \
+ IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__UART3_CTS \
+ IOMUX_PAD(0x06B4, 0x02CC, 1, 0x092C, 4, 0)
+#define _MX6Q_PAD_SD3_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_29 \
+ IOMUX_PAD(0x06B4, 0x02CC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 \
+ IOMUX_PAD(0x06B4, 0x02CC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 \
+ IOMUX_PAD(0x06B4, 0x02CC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__GPIO_7_7 \
+ IOMUX_PAD(0x06B4, 0x02CC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_TEST_IN_21 \
+ IOMUX_PAD(0x06B4, 0x02CC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_DAT3__ANATOP_ANATOP_TESTI_2 \
+ IOMUX_PAD(0x06B4, 0x02CC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD3_RST__USDHC3_RST \
+ IOMUX_PAD(0x06B8, 0x02D0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__UART3_CTS \
+ IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__UART3_RTS \
+ IOMUX_PAD(0x06B8, 0x02D0, 1, 0x092C, 5, 0)
+#define _MX6Q_PAD_SD3_RST__PCIE_CTRL_DIAG_STATUS_BUS_MUX_30 \
+ IOMUX_PAD(0x06B8, 0x02D0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 \
+ IOMUX_PAD(0x06B8, 0x02D0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 \
+ IOMUX_PAD(0x06B8, 0x02D0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__GPIO_7_8 \
+ IOMUX_PAD(0x06B8, 0x02D0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_TEST_IN_22 \
+ IOMUX_PAD(0x06B8, 0x02D0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 \
+ IOMUX_PAD(0x06B8, 0x02D0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_CLE__RAWNAND_CLE \
+ IOMUX_PAD(0x06BC, 0x02D4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__IPU2_SISG_4 \
+ IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_31 \
+ IOMUX_PAD(0x06BC, 0x02D4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OUT_11 \
+ IOMUX_PAD(0x06BC, 0x02D4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OUT_11 \
+ IOMUX_PAD(0x06BC, 0x02D4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__GPIO_6_7 \
+ IOMUX_PAD(0x06BC, 0x02D4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_TEST_IN_23 \
+ IOMUX_PAD(0x06BC, 0x02D4, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0 \
+ IOMUX_PAD(0x06BC, 0x02D4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_ALE__RAWNAND_ALE \
+ IOMUX_PAD(0x06C0, 0x02D8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__USDHC4_RST \
+ IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_0 \
+ IOMUX_PAD(0x06C0, 0x02D8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OUT_12 \
+ IOMUX_PAD(0x06C0, 0x02D8, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OUT_12 \
+ IOMUX_PAD(0x06C0, 0x02D8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__GPIO_6_8 \
+ IOMUX_PAD(0x06C0, 0x02D8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__MIPI_CORE_DPHY_TEST_IN_24 \
+ IOMUX_PAD(0x06C0, 0x02D8, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1 \
+ IOMUX_PAD(0x06C0, 0x02D8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN \
+ IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5 \
+ IOMUX_PAD(0x06C4, 0x02DC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__PCIE_CTRL_DIAG_STATUS_BUS_MUX_1 \
+ IOMUX_PAD(0x06C4, 0x02DC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFD_OUT_13 \
+ IOMUX_PAD(0x06C4, 0x02DC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFD_OUT_13 \
+ IOMUX_PAD(0x06C4, 0x02DC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__GPIO_6_9 \
+ IOMUX_PAD(0x06C4, 0x02DC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__MIPI_CORE_DPHY_TEST_OUT_32 \
+ IOMUX_PAD(0x06C4, 0x02DC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_WP_B__PL301_MX6QPER1_HSIZE_0 \
+ IOMUX_PAD(0x06C4, 0x02DC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 \
+ IOMUX_PAD(0x06C8, 0x02E0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1 \
+ IOMUX_PAD(0x06C8, 0x02E0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_2 \
+ IOMUX_PAD(0x06C8, 0x02E0, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OUT_14 \
+ IOMUX_PAD(0x06C8, 0x02E0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OUT_14 \
+ IOMUX_PAD(0x06C8, 0x02E0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__GPIO_6_10 \
+ IOMUX_PAD(0x06C8, 0x02E0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__MIPI_CORE_DPHY_TEST_OUT_33 \
+ IOMUX_PAD(0x06C8, 0x02E0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_RB0__PL301_MX6QPER1_HSIZE_1 \
+ IOMUX_PAD(0x06C8, 0x02E0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N \
+ IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OUT_15 \
+ IOMUX_PAD(0x06CC, 0x02E4, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OUT_15 \
+ IOMUX_PAD(0x06CC, 0x02E4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS0__GPIO_6_11 \
+ IOMUX_PAD(0x06CC, 0x02E4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS0__PL301_MX6QPER1_HSIZE_2 \
+ IOMUX_PAD(0x06CC, 0x02E4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N \
+ IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT \
+ IOMUX_PAD(0x06D0, 0x02E8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT \
+ IOMUX_PAD(0x06D0, 0x02E8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_3 \
+ IOMUX_PAD(0x06D0, 0x02E8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS1__GPIO_6_14 \
+ IOMUX_PAD(0x06D0, 0x02E8, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS1__PL301_MX6QPER1_HREADYOUT \
+ IOMUX_PAD(0x06D0, 0x02E8, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N \
+ IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS2__IPU1_SISG_0 \
+ IOMUX_PAD(0x06D4, 0x02EC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS2__ESAI1_TX0 \
+ IOMUX_PAD(0x06D4, 0x02EC, 2, 0x0874, 1, 0)
+#define _MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE \
+ IOMUX_PAD(0x06D4, 0x02EC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS2__CCM_CLKO2 \
+ IOMUX_PAD(0x06D4, 0x02EC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS2__GPIO_6_15 \
+ IOMUX_PAD(0x06D4, 0x02EC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS2__IPU2_SISG_0 \
+ IOMUX_PAD(0x06D4, 0x02EC, 6, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N \
+ IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__IPU1_SISG_1 \
+ IOMUX_PAD(0x06D8, 0x02F0, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__ESAI1_TX1 \
+ IOMUX_PAD(0x06D8, 0x02F0, 2, 0x0878, 1, 0)
+#define _MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26 \
+ IOMUX_PAD(0x06D8, 0x02F0, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_4 \
+ IOMUX_PAD(0x06D8, 0x02F0, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__GPIO_6_16 \
+ IOMUX_PAD(0x06D8, 0x02F0, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__IPU2_SISG_1 \
+ IOMUX_PAD(0x06D8, 0x02F0, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_CS3__TPSMP_CLK \
+ IOMUX_PAD(0x06D8, 0x02F0, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_CMD__USDHC4_CMD \
+ IOMUX_PAD(0x06DC, 0x02F4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CMD__RAWNAND_RDN \
+ IOMUX_PAD(0x06DC, 0x02F4, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CMD__UART3_TXD \
+ IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CMD__UART3_RXD \
+ IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0930, 2, 0)
+#define _MX6Q_PAD_SD4_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_5 \
+ IOMUX_PAD(0x06DC, 0x02F4, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CMD__GPIO_7_9 \
+ IOMUX_PAD(0x06DC, 0x02F4, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR \
+ IOMUX_PAD(0x06DC, 0x02F4, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_CLK__USDHC4_CLK \
+ IOMUX_PAD(0x06E0, 0x02F8, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CLK__RAWNAND_WRN \
+ IOMUX_PAD(0x06E0, 0x02F8, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CLK__UART3_TXD \
+ IOMUX_PAD(0x06E0, 0x02F8, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CLK__UART3_RXD \
+ IOMUX_PAD(0x06E0, 0x02F8, 2, 0x0930, 3, 0)
+#define _MX6Q_PAD_SD4_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_6 \
+ IOMUX_PAD(0x06E0, 0x02F8, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_CLK__GPIO_7_10 \
+ IOMUX_PAD(0x06E0, 0x02F8, 5, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D0__RAWNAND_D0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__USDHC1_DAT4 \
+ IOMUX_PAD(0x06E4, 0x02FC, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__GPU3D_GPU_DEBUG_OUT_0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT_16 \
+ IOMUX_PAD(0x06E4, 0x02FC, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT_16 \
+ IOMUX_PAD(0x06E4, 0x02FC, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__GPIO_2_0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D1__RAWNAND_D1 \
+ IOMUX_PAD(0x06E8, 0x0300, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__USDHC1_DAT5 \
+ IOMUX_PAD(0x06E8, 0x0300, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT_1 \
+ IOMUX_PAD(0x06E8, 0x0300, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT_17 \
+ IOMUX_PAD(0x06E8, 0x0300, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT_17 \
+ IOMUX_PAD(0x06E8, 0x0300, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__GPIO_2_1 \
+ IOMUX_PAD(0x06E8, 0x0300, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 \
+ IOMUX_PAD(0x06E8, 0x0300, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1 \
+ IOMUX_PAD(0x06E8, 0x0300, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D2__RAWNAND_D2 \
+ IOMUX_PAD(0x06EC, 0x0304, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__USDHC1_DAT6 \
+ IOMUX_PAD(0x06EC, 0x0304, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__GPU3D_GPU_DEBUG_OUT_2 \
+ IOMUX_PAD(0x06EC, 0x0304, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT_18 \
+ IOMUX_PAD(0x06EC, 0x0304, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT_18 \
+ IOMUX_PAD(0x06EC, 0x0304, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__GPIO_2_2 \
+ IOMUX_PAD(0x06EC, 0x0304, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 \
+ IOMUX_PAD(0x06EC, 0x0304, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2 \
+ IOMUX_PAD(0x06EC, 0x0304, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D3__RAWNAND_D3 \
+ IOMUX_PAD(0x06F0, 0x0308, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__USDHC1_DAT7 \
+ IOMUX_PAD(0x06F0, 0x0308, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__GPU3D_GPU_DEBUG_OUT_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT_19 \
+ IOMUX_PAD(0x06F0, 0x0308, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT_19 \
+ IOMUX_PAD(0x06F0, 0x0308, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__GPIO_2_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D4__RAWNAND_D4 \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__USDHC2_DAT4 \
+ IOMUX_PAD(0x06F4, 0x030C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__GPU3D_GPU_DEBUG_OUT_4 \
+ IOMUX_PAD(0x06F4, 0x030C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT_20 \
+ IOMUX_PAD(0x06F4, 0x030C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT_20 \
+ IOMUX_PAD(0x06F4, 0x030C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__GPIO_2_4 \
+ IOMUX_PAD(0x06F4, 0x030C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 \
+ IOMUX_PAD(0x06F4, 0x030C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4 \
+ IOMUX_PAD(0x06F4, 0x030C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D5__RAWNAND_D5 \
+ IOMUX_PAD(0x06F8, 0x0310, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__USDHC2_DAT5 \
+ IOMUX_PAD(0x06F8, 0x0310, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__GPU3D_GPU_DEBUG_OUT_5 \
+ IOMUX_PAD(0x06F8, 0x0310, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT_21 \
+ IOMUX_PAD(0x06F8, 0x0310, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT_21 \
+ IOMUX_PAD(0x06F8, 0x0310, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__GPIO_2_5 \
+ IOMUX_PAD(0x06F8, 0x0310, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 \
+ IOMUX_PAD(0x06F8, 0x0310, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5 \
+ IOMUX_PAD(0x06F8, 0x0310, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D6__RAWNAND_D6 \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__USDHC2_DAT6 \
+ IOMUX_PAD(0x06FC, 0x0314, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__GPU3D_GPU_DEBUG_OUT_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT_22 \
+ IOMUX_PAD(0x06FC, 0x0314, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT_22 \
+ IOMUX_PAD(0x06FC, 0x0314, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__GPIO_2_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_NANDF_D7__RAWNAND_D7 \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__USDHC2_DAT7 \
+ IOMUX_PAD(0x0700, 0x0318, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7 \
+ IOMUX_PAD(0x0700, 0x0318, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23 \
+ IOMUX_PAD(0x0700, 0x0318, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23 \
+ IOMUX_PAD(0x0700, 0x0318, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__GPIO_2_7 \
+ IOMUX_PAD(0x0700, 0x0318, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 \
+ IOMUX_PAD(0x0700, 0x0318, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7 \
+ IOMUX_PAD(0x0700, 0x0318, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT0__RAWNAND_D8 \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 \
+ IOMUX_PAD(0x0704, 0x031C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__RAWNAND_DQS \
+ IOMUX_PAD(0x0704, 0x031C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT_24 \
+ IOMUX_PAD(0x0704, 0x031C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT_24 \
+ IOMUX_PAD(0x0704, 0x031C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__GPIO_2_8 \
+ IOMUX_PAD(0x0704, 0x031C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 \
+ IOMUX_PAD(0x0704, 0x031C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8 \
+ IOMUX_PAD(0x0704, 0x031C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT1__RAWNAND_D9 \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 \
+ IOMUX_PAD(0x0708, 0x0320, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x0708, 0x0320, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT_25 \
+ IOMUX_PAD(0x0708, 0x0320, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT_25 \
+ IOMUX_PAD(0x0708, 0x0320, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__GPIO_2_9 \
+ IOMUX_PAD(0x0708, 0x0320, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 \
+ IOMUX_PAD(0x0708, 0x0320, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9 \
+ IOMUX_PAD(0x0708, 0x0320, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT2__RAWNAND_D10 \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 \
+ IOMUX_PAD(0x070C, 0x0324, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__PWM4_PWMO \
+ IOMUX_PAD(0x070C, 0x0324, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT_26 \
+ IOMUX_PAD(0x070C, 0x0324, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT_26 \
+ IOMUX_PAD(0x070C, 0x0324, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__GPIO_2_10 \
+ IOMUX_PAD(0x070C, 0x0324, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 \
+ IOMUX_PAD(0x070C, 0x0324, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10 \
+ IOMUX_PAD(0x070C, 0x0324, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT3__RAWNAND_D11 \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 \
+ IOMUX_PAD(0x0710, 0x0328, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT_27 \
+ IOMUX_PAD(0x0710, 0x0328, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT_27 \
+ IOMUX_PAD(0x0710, 0x0328, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__GPIO_2_11 \
+ IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 \
+ IOMUX_PAD(0x0710, 0x0328, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11 \
+ IOMUX_PAD(0x0710, 0x0328, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT4__RAWNAND_D12 \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 \
+ IOMUX_PAD(0x0714, 0x032C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__UART2_TXD \
+ IOMUX_PAD(0x0714, 0x032C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__UART2_RXD \
+ IOMUX_PAD(0x0714, 0x032C, 2, 0x0928, 6, 0)
+#define _MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT_28 \
+ IOMUX_PAD(0x0714, 0x032C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT_28 \
+ IOMUX_PAD(0x0714, 0x032C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__GPIO_2_12 \
+ IOMUX_PAD(0x0714, 0x032C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 \
+ IOMUX_PAD(0x0714, 0x032C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12 \
+ IOMUX_PAD(0x0714, 0x032C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT5__RAWNAND_D13 \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 \
+ IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__UART2_CTS \
+ IOMUX_PAD(0x0718, 0x0330, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__UART2_RTS \
+ IOMUX_PAD(0x0718, 0x0330, 2, 0x0924, 4, 0)
+#define _MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT_29 \
+ IOMUX_PAD(0x0718, 0x0330, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT_29 \
+ IOMUX_PAD(0x0718, 0x0330, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__GPIO_2_13 \
+ IOMUX_PAD(0x0718, 0x0330, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 \
+ IOMUX_PAD(0x0718, 0x0330, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13 \
+ IOMUX_PAD(0x0718, 0x0330, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT6__RAWNAND_D14 \
+ IOMUX_PAD(0x071C, 0x0334, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 \
+ IOMUX_PAD(0x071C, 0x0334, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__UART2_CTS \
+ IOMUX_PAD(0x071C, 0x0334, 2, 0x0924, 5, 0)
+#define _MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT_30 \
+ IOMUX_PAD(0x071C, 0x0334, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT_30 \
+ IOMUX_PAD(0x071C, 0x0334, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__GPIO_2_14 \
+ IOMUX_PAD(0x071C, 0x0334, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 \
+ IOMUX_PAD(0x071C, 0x0334, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14 \
+ IOMUX_PAD(0x071C, 0x0334, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD4_DAT7__RAWNAND_D15 \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 \
+ IOMUX_PAD(0x0720, 0x0338, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__UART2_TXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__UART2_RXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x0928, 7, 0)
+#define _MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT_31 \
+ IOMUX_PAD(0x0720, 0x0338, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT_31 \
+ IOMUX_PAD(0x0720, 0x0338, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__GPIO_2_15 \
+ IOMUX_PAD(0x0720, 0x0338, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 \
+ IOMUX_PAD(0x0720, 0x0338, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15 \
+ IOMUX_PAD(0x0720, 0x0338, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 \
+ IOMUX_PAD(0x0724, 0x033C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 \
+ IOMUX_PAD(0x0724, 0x033C, 1, 0x0834, 1, 0)
+#define _MX6Q_PAD_SD1_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x0724, 0x033C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__GPT_CAPIN2 \
+ IOMUX_PAD(0x0724, 0x033C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_7 \
+ IOMUX_PAD(0x0724, 0x033C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__GPIO_1_17 \
+ IOMUX_PAD(0x0724, 0x033C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 \
+ IOMUX_PAD(0x0724, 0x033C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_8 \
+ IOMUX_PAD(0x0724, 0x033C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 \
+ IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__ECSPI5_MISO \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x082C, 1, 0)
+#define _MX6Q_PAD_SD1_DAT0__CAAM_WRAPPER_RNG_OSC_OBS \
+ IOMUX_PAD(0x0728, 0x0340, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__GPT_CAPIN1 \
+ IOMUX_PAD(0x0728, 0x0340, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_8 \
+ IOMUX_PAD(0x0728, 0x0340, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__GPIO_1_16 \
+ IOMUX_PAD(0x0728, 0x0340, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 \
+ IOMUX_PAD(0x0728, 0x0340, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_7 \
+ IOMUX_PAD(0x0728, 0x0340, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 \
+ IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3 \
+ IOMUX_PAD(0x072C, 0x0344, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__PWM1_PWMO \
+ IOMUX_PAD(0x072C, 0x0344, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B \
+ IOMUX_PAD(0x072C, 0x0344, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__GPIO_1_21 \
+ IOMUX_PAD(0x072C, 0x0344, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x072C, 0x0344, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_6 \
+ IOMUX_PAD(0x072C, 0x0344, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_CMD__USDHC1_CMD \
+ IOMUX_PAD(0x0730, 0x0348, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CMD__ECSPI5_MOSI \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0830, 0, 0)
+#define _MX6Q_PAD_SD1_CMD__PWM4_PWMO \
+ IOMUX_PAD(0x0730, 0x0348, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CMD__GPT_CMPOUT1 \
+ IOMUX_PAD(0x0730, 0x0348, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CMD__GPIO_1_18 \
+ IOMUX_PAD(0x0730, 0x0348, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_5 \
+ IOMUX_PAD(0x0730, 0x0348, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 \
+ IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0838, 1, 0)
+#define _MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2 \
+ IOMUX_PAD(0x0734, 0x034C, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__PWM2_PWMO \
+ IOMUX_PAD(0x0734, 0x034C, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B \
+ IOMUX_PAD(0x0734, 0x034C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__GPIO_1_19 \
+ IOMUX_PAD(0x0734, 0x034C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x0734, 0x034C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_4 \
+ IOMUX_PAD(0x0734, 0x034C, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD1_CLK__USDHC1_CLK \
+ IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__ECSPI5_SCLK \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0828, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT \
+ IOMUX_PAD(0x0738, 0x0350, 2, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__GPT_CLKIN \
+ IOMUX_PAD(0x0738, 0x0350, 3, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__GPIO_1_20 \
+ IOMUX_PAD(0x0738, 0x0350, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__PHY_DTB_0 \
+ IOMUX_PAD(0x0738, 0x0350, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0 \
+ IOMUX_PAD(0x0738, 0x0350, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD2_CLK__USDHC2_CLK \
+ IOMUX_PAD(0x073C, 0x0354, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CLK__ECSPI5_SCLK \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0828, 1, 0)
+#define _MX6Q_PAD_SD2_CLK__KPP_COL_5 \
+ IOMUX_PAD(0x073C, 0x0354, 2, 0x08E8, 3, 0)
+#define _MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x073C, 0x0354, 3, 0x07C0, 1, 0)
+#define _MX6Q_PAD_SD2_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_9 \
+ IOMUX_PAD(0x073C, 0x0354, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CLK__GPIO_1_10 \
+ IOMUX_PAD(0x073C, 0x0354, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CLK__PHY_DTB_1 \
+ IOMUX_PAD(0x073C, 0x0354, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1 \
+ IOMUX_PAD(0x073C, 0x0354, 7, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD2_CMD__USDHC2_CMD \
+ IOMUX_PAD(0x0740, 0x0358, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CMD__ECSPI5_MOSI \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0830, 1, 0)
+#define _MX6Q_PAD_SD2_CMD__KPP_ROW_5 \
+ IOMUX_PAD(0x0740, 0x0358, 2, 0x08F4, 2, 0)
+#define _MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x0740, 0x0358, 3, 0x07BC, 1, 0)
+#define _MX6Q_PAD_SD2_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_10 \
+ IOMUX_PAD(0x0740, 0x0358, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_CMD__GPIO_1_11 \
+ IOMUX_PAD(0x0740, 0x0358, 5, 0x0000, 0, 0)
+
+#define _MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 \
+ IOMUX_PAD(0x0744, 0x035C, 0, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT3__KPP_COL_6 \
+ IOMUX_PAD(0x0744, 0x035C, 2, 0x08EC, 2, 0)
+#define _MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x0744, 0x035C, 3, 0x07C4, 1, 0)
+#define _MX6Q_PAD_SD2_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_11 \
+ IOMUX_PAD(0x0744, 0x035C, 4, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT3__GPIO_1_12 \
+ IOMUX_PAD(0x0744, 0x035C, 5, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT3__SJC_DONE \
+ IOMUX_PAD(0x0744, 0x035C, 6, 0x0000, 0, 0)
+#define _MX6Q_PAD_SD2_DAT3__ANATOP_ANATOP_TESTO_3 \
+ IOMUX_PAD(0x0744, 0x035C, 7, 0x0000, 0, 0)
+
+
+
+#define MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 \
+ (_MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 \
+ (_MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2 \
+ (_MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS \
+ (_MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__KPP_COL_7 \
+ (_MX6Q_PAD_SD2_DAT1__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__GPIO_1_14 \
+ (_MX6Q_PAD_SD2_DAT1__GPIO_1_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__CCM_WAIT \
+ (_MX6Q_PAD_SD2_DAT1__CCM_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0 \
+ (_MX6Q_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 \
+ (_MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 \
+ (_MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3 \
+ (_MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD \
+ (_MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__KPP_ROW_6 \
+ (_MX6Q_PAD_SD2_DAT2__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__GPIO_1_13 \
+ (_MX6Q_PAD_SD2_DAT2__GPIO_1_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__CCM_STOP \
+ (_MX6Q_PAD_SD2_DAT2__CCM_STOP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1 \
+ (_MX6Q_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 \
+ (_MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__ECSPI5_MISO \
+ (_MX6Q_PAD_SD2_DAT0__ECSPI5_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD \
+ (_MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__KPP_ROW_7 \
+ (_MX6Q_PAD_SD2_DAT0__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__GPIO_1_15 \
+ (_MX6Q_PAD_SD2_DAT0__GPIO_1_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT \
+ (_MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_2 \
+ (_MX6Q_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA \
+ (_MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA | MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC \
+ (_MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK \
+ (_MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TXC__GPIO_6_19 \
+ (_MX6Q_PAD_RGMII_TXC__GPIO_6_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_TEST_IN_0 \
+ (_MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_TEST_IN_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TXC__ANATOP_ANATOP_24M_OUT \
+ (_MX6Q_PAD_RGMII_TXC__ANATOP_ANATOP_24M_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_TD0__MIPI_HSI_CTRL_TX_READY \
+ (_MX6Q_PAD_RGMII_TD0__MIPI_HSI_CTRL_TX_READY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 \
+ (_MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD0__GPIO_6_20 \
+ (_MX6Q_PAD_RGMII_TD0__GPIO_6_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_TEST_IN_1 \
+ (_MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_TEST_IN_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RGMII_TD1__MIPI_HSI_CTRL_RX_FLAG \
+ (_MX6Q_PAD_RGMII_TD1__MIPI_HSI_CTRL_RX_FLAG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 \
+ (_MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD1__GPIO_6_21 \
+ (_MX6Q_PAD_RGMII_TD1__GPIO_6_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_TEST_IN_2 \
+ (_MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_TEST_IN_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP \
+ (_MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_TD2__MIPI_HSI_CTRL_RX_DATA \
+ (_MX6Q_PAD_RGMII_TD2__MIPI_HSI_CTRL_RX_DATA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 \
+ (_MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD2__GPIO_6_22 \
+ (_MX6Q_PAD_RGMII_TD2__GPIO_6_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_TEST_IN_3 \
+ (_MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_TEST_IN_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP \
+ (_MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_TD3__MIPI_HSI_CTRL_RX_WAKE \
+ (_MX6Q_PAD_RGMII_TD3__MIPI_HSI_CTRL_RX_WAKE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 \
+ (_MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD3__GPIO_6_23 \
+ (_MX6Q_PAD_RGMII_TD3__GPIO_6_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_TEST_IN_4 \
+ (_MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_TEST_IN_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA \
+ (_MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA | MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL \
+ (_MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24 \
+ (_MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RX_CTL__MIPI_CORE_DPHY_TEST_IN_5 \
+ (_MX6Q_PAD_RGMII_RX_CTL__MIPI_CORE_DPHY_TEST_IN_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_RD0__MIPI_HSI_CTRL_RX_READY \
+ (_MX6Q_PAD_RGMII_RD0__MIPI_HSI_CTRL_RX_READY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 \
+ (_MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD0__GPIO_6_25 \
+ (_MX6Q_PAD_RGMII_RD0__GPIO_6_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_TEST_IN_6 \
+ (_MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_TEST_IN_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+
+#define MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE \
+ (_MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE | MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START \
+ (_MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE | \
+ MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)\
+ )
+#define MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL \
+ (_MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26 \
+ (_MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TX_CTL__MIPI_CORE_DPHY_TEST_IN_7 \
+ (_MX6Q_PAD_RGMII_TX_CTL__MIPI_CORE_DPHY_TEST_IN_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_TX_CTL__ENET_ANATOP_ETHERNET_REF_OUT \
+ (_MX6Q_PAD_RGMII_TX_CTL__ENET_ANATOP_ETHERNET_REF_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FLAG \
+ (_MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FLAG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 \
+ (_MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD1__GPIO_6_27 \
+ (_MX6Q_PAD_RGMII_RD1__GPIO_6_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD1__MIPI_CORE_DPHY_TEST_IN_8 \
+ (_MX6Q_PAD_RGMII_RD1__MIPI_CORE_DPHY_TEST_IN_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD1__SJC_FAIL \
+ (_MX6Q_PAD_RGMII_RD1__SJC_FAIL | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RGMII_RD2__MIPI_HSI_CTRL_TX_DATA \
+ (_MX6Q_PAD_RGMII_RD2__MIPI_HSI_CTRL_TX_DATA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 \
+ (_MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD2__GPIO_6_28 \
+ (_MX6Q_PAD_RGMII_RD2__GPIO_6_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_TEST_IN_9 \
+ (_MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_TEST_IN_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RGMII_RD3__MIPI_HSI_CTRL_TX_WAKE \
+ (_MX6Q_PAD_RGMII_RD3__MIPI_HSI_CTRL_TX_WAKE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 \
+ (_MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD3__GPIO_6_29 \
+ (_MX6Q_PAD_RGMII_RD3__GPIO_6_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_TEST_IN_10 \
+ (_MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_TEST_IN_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE \
+ (_MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE | MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START \
+ (_MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE | MUX_PAD_CTRL(MX6Q_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP))
+#define MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC \
+ (_MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RXC__GPIO_6_30 \
+ (_MX6Q_PAD_RGMII_RXC__GPIO_6_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_TEST_IN_11 \
+ (_MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_TEST_IN_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25 \
+ (_MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__ECSPI4_SS1 \
+ (_MX6Q_PAD_EIM_A25__ECSPI4_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__ECSPI2_RDY \
+ (_MX6Q_PAD_EIM_A25__ECSPI2_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 \
+ (_MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS \
+ (_MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__GPIO_5_2 \
+ (_MX6Q_PAD_EIM_A25__GPIO_5_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE \
+ (_MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE | MUX_PAD_CTRL(MX6Q_HDMICEC_PAD_CTRL))
+#define MX6Q_PAD_EIM_A25__PL301_MX6QPER1_HBURST_0 \
+ (_MX6Q_PAD_EIM_A25__PL301_MX6QPER1_HBURST_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2 \
+ (_MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__ECSPI1_SS0 \
+ (_MX6Q_PAD_EIM_EB2__ECSPI1_SS0 | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK \
+ (_MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19 \
+ (_MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL \
+ (_MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__GPIO_2_30 \
+ (_MX6Q_PAD_EIM_EB2__GPIO_2_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__I2C2_SCL \
+ (_MX6Q_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30 \
+ (_MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16 \
+ (_MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__ECSPI1_SCLK \
+ (_MX6Q_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5 \
+ (_MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18 \
+ (_MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA \
+ (_MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__GPIO_3_16 \
+ (_MX6Q_PAD_EIM_D16__GPIO_3_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D16__I2C2_SDA \
+ (_MX6Q_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17 \
+ (_MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__ECSPI1_MISO \
+ (_MX6Q_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6 \
+ (_MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK \
+ (_MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT \
+ (_MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__GPIO_3_17 \
+ (_MX6Q_PAD_EIM_D17__GPIO_3_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__I2C3_SCL \
+ (_MX6Q_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D17__PL301_MX6QPER1_HBURST_1 \
+ (_MX6Q_PAD_EIM_D17__PL301_MX6QPER1_HBURST_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18 \
+ (_MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__ECSPI1_MOSI \
+ (_MX6Q_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7 \
+ (_MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17 \
+ (_MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS \
+ (_MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__GPIO_3_18 \
+ (_MX6Q_PAD_EIM_D18__GPIO_3_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__I2C3_SDA \
+ (_MX6Q_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D18__PL301_MX6QPER1_HBURST_2 \
+ (_MX6Q_PAD_EIM_D18__PL301_MX6QPER1_HBURST_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19 \
+ (_MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__ECSPI1_SS1 \
+ (_MX6Q_PAD_EIM_D19__ECSPI1_SS1 | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8 \
+ (_MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16 \
+ (_MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__UART1_CTS \
+ (_MX6Q_PAD_EIM_D19__UART1_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__GPIO_3_19 \
+ (_MX6Q_PAD_EIM_D19__GPIO_3_19 | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__EPIT1_EPITO \
+ (_MX6Q_PAD_EIM_D19__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D19__PL301_MX6QPER1_HRESP \
+ (_MX6Q_PAD_EIM_D19__PL301_MX6QPER1_HRESP | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20 \
+ (_MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__ECSPI4_SS0 \
+ (_MX6Q_PAD_EIM_D20__ECSPI4_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 \
+ (_MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15 \
+ (_MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__UART1_CTS \
+ (_MX6Q_PAD_EIM_D20__UART1_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__UART1_RTS \
+ (_MX6Q_PAD_EIM_D20__UART1_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__GPIO_3_20 \
+ (_MX6Q_PAD_EIM_D20__GPIO_3_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D20__EPIT2_EPITO \
+ (_MX6Q_PAD_EIM_D20__EPIT2_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21 \
+ (_MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__ECSPI4_SCLK \
+ (_MX6Q_PAD_EIM_D21__ECSPI4_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 \
+ (_MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11 \
+ (_MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC \
+ (_MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__GPIO_3_21 \
+ (_MX6Q_PAD_EIM_D21__GPIO_3_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__I2C1_SCL \
+ (_MX6Q_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_EIM_D21__SPDIF_IN1 \
+ (_MX6Q_PAD_EIM_D21__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22 \
+ (_MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__ECSPI4_MISO \
+ (_MX6Q_PAD_EIM_D22__ECSPI4_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1 \
+ (_MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10 \
+ (_MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR \
+ (_MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__GPIO_3_22 \
+ (_MX6Q_PAD_EIM_D22__GPIO_3_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__SPDIF_OUT1 \
+ (_MX6Q_PAD_EIM_D22__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D22__PL301_MX6QPER1_HWRITE \
+ (_MX6Q_PAD_EIM_D22__PL301_MX6QPER1_HWRITE | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23 \
+ (_MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS \
+ (_MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__UART3_CTS \
+ (_MX6Q_PAD_EIM_D23__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__UART1_DCD \
+ (_MX6Q_PAD_EIM_D23__UART1_DCD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN \
+ (_MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__GPIO_3_23 \
+ (_MX6Q_PAD_EIM_D23__GPIO_3_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2 \
+ (_MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 \
+ (_MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3 \
+ (_MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__ECSPI4_RDY \
+ (_MX6Q_PAD_EIM_EB3__ECSPI4_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__UART3_CTS \
+ (_MX6Q_PAD_EIM_EB3__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__UART3_RTS \
+ (_MX6Q_PAD_EIM_EB3__UART3_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__UART1_RI \
+ (_MX6Q_PAD_EIM_EB3__UART1_RI | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC \
+ (_MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__GPIO_2_31 \
+ (_MX6Q_PAD_EIM_EB3__GPIO_2_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3 \
+ (_MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31 \
+ (_MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24 \
+ (_MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__ECSPI4_SS2 \
+ (_MX6Q_PAD_EIM_D24__ECSPI4_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__UART3_TXD \
+ (_MX6Q_PAD_EIM_D24__UART3_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__UART3_RXD \
+ (_MX6Q_PAD_EIM_D24__UART3_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__ECSPI1_SS2 \
+ (_MX6Q_PAD_EIM_D24__ECSPI1_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__ECSPI2_SS2 \
+ (_MX6Q_PAD_EIM_D24__ECSPI2_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__GPIO_3_24 \
+ (_MX6Q_PAD_EIM_D24__GPIO_3_24 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS \
+ (_MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D24__UART1_DTR \
+ (_MX6Q_PAD_EIM_D24__UART1_DTR | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25 \
+ (_MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__ECSPI4_SS3 \
+ (_MX6Q_PAD_EIM_D25__ECSPI4_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__UART3_TXD \
+ (_MX6Q_PAD_EIM_D25__UART3_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__UART3_RXD \
+ (_MX6Q_PAD_EIM_D25__UART3_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__ECSPI1_SS3 \
+ (_MX6Q_PAD_EIM_D25__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__ECSPI2_SS3 \
+ (_MX6Q_PAD_EIM_D25__ECSPI2_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__GPIO_3_25 \
+ (_MX6Q_PAD_EIM_D25__GPIO_3_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC \
+ (_MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D25__UART1_DSR \
+ (_MX6Q_PAD_EIM_D25__UART1_DSR | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26 \
+ (_MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 \
+ (_MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1 \
+ (_MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14 \
+ (_MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__UART2_TXD \
+ (_MX6Q_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__UART2_RXD \
+ (_MX6Q_PAD_EIM_D26__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__GPIO_3_26 \
+ (_MX6Q_PAD_EIM_D26__GPIO_3_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__IPU1_SISG_2 \
+ (_MX6Q_PAD_EIM_D26__IPU1_SISG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22 \
+ (_MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27 \
+ (_MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 \
+ (_MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0 \
+ (_MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13 \
+ (_MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__UART2_TXD \
+ (_MX6Q_PAD_EIM_D27__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__UART2_RXD \
+ (_MX6Q_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__GPIO_3_27 \
+ (_MX6Q_PAD_EIM_D27__GPIO_3_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__IPU1_SISG_3 \
+ (_MX6Q_PAD_EIM_D27__IPU1_SISG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23 \
+ (_MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28 \
+ (_MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__I2C1_SDA \
+ (_MX6Q_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__ECSPI4_MOSI \
+ (_MX6Q_PAD_EIM_D28__ECSPI4_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12 \
+ (_MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__UART2_CTS \
+ (_MX6Q_PAD_EIM_D28__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__UART2_RTS \
+ (_MX6Q_PAD_EIM_D28__UART2_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__GPIO_3_28 \
+ (_MX6Q_PAD_EIM_D28__GPIO_3_28 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG \
+ (_MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 \
+ (_MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29 \
+ (_MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 \
+ (_MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__ECSPI4_SS0 \
+ (_MX6Q_PAD_EIM_D29__ECSPI4_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__UART2_CTS \
+ (_MX6Q_PAD_EIM_D29__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__UART2_RTS \
+ (_MX6Q_PAD_EIM_D29__UART2_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__GPIO_3_29 \
+ (_MX6Q_PAD_EIM_D29__GPIO_3_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC \
+ (_MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 \
+ (_MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30 \
+ (_MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21 \
+ (_MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 \
+ (_MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3 \
+ (_MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__UART3_CTS \
+ (_MX6Q_PAD_EIM_D30__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__GPIO_3_30 \
+ (_MX6Q_PAD_EIM_D30__GPIO_3_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC \
+ (_MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D30__PL301_MX6QPER1_HPROT_0 \
+ (_MX6Q_PAD_EIM_D30__PL301_MX6QPER1_HPROT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31 \
+ (_MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31 | MUX_PAD_CTRL(MX6Q_WEIM_NOR_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20 \
+ (_MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 \
+ (_MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2 \
+ (_MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__UART3_CTS \
+ (_MX6Q_PAD_EIM_D31__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__UART3_RTS \
+ (_MX6Q_PAD_EIM_D31__UART3_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__GPIO_3_31 \
+ (_MX6Q_PAD_EIM_D31__GPIO_3_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR \
+ (_MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_D31__PL301_MX6QPER1_HPROT_1 \
+ (_MX6Q_PAD_EIM_D31__PL301_MX6QPER1_HPROT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24 \
+ (_MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19 \
+ (_MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19 \
+ (_MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__IPU2_SISG_2 \
+ (_MX6Q_PAD_EIM_A24__IPU2_SISG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__IPU1_SISG_2 \
+ (_MX6Q_PAD_EIM_A24__IPU1_SISG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__GPIO_5_4 \
+ (_MX6Q_PAD_EIM_A24__GPIO_5_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__PL301_MX6QPER1_HPROT_2 \
+ (_MX6Q_PAD_EIM_A24__PL301_MX6QPER1_HPROT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A24__SRC_BT_CFG_24 \
+ (_MX6Q_PAD_EIM_A24__SRC_BT_CFG_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23 \
+ (_MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18 \
+ (_MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18 \
+ (_MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__IPU2_SISG_3 \
+ (_MX6Q_PAD_EIM_A23__IPU2_SISG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__IPU1_SISG_3 \
+ (_MX6Q_PAD_EIM_A23__IPU1_SISG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__GPIO_6_6 \
+ (_MX6Q_PAD_EIM_A23__GPIO_6_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__PL301_MX6QPER1_HPROT_3 \
+ (_MX6Q_PAD_EIM_A23__PL301_MX6QPER1_HPROT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A23__SRC_BT_CFG_23 \
+ (_MX6Q_PAD_EIM_A23__SRC_BT_CFG_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22 \
+ (_MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17 \
+ (_MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17 \
+ (_MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A22__GPIO_2_16 \
+ (_MX6Q_PAD_EIM_A22__GPIO_2_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A22__TPSMP_HDATA_0 \
+ (_MX6Q_PAD_EIM_A22__TPSMP_HDATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A22__SRC_BT_CFG_22 \
+ (_MX6Q_PAD_EIM_A22__SRC_BT_CFG_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21 \
+ (_MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16 \
+ (_MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16 \
+ (_MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__RESERVED_RESERVED \
+ (_MX6Q_PAD_EIM_A21__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_TEST_OUT_18 \
+ (_MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_TEST_OUT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__GPIO_2_17 \
+ (_MX6Q_PAD_EIM_A21__GPIO_2_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__TPSMP_HDATA_1 \
+ (_MX6Q_PAD_EIM_A21__TPSMP_HDATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A21__SRC_BT_CFG_21 \
+ (_MX6Q_PAD_EIM_A21__SRC_BT_CFG_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20 \
+ (_MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15 \
+ (_MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15 \
+ (_MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__RESERVED_RESERVED \
+ (_MX6Q_PAD_EIM_A20__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_TEST_OUT_19 \
+ (_MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_TEST_OUT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__GPIO_2_18 \
+ (_MX6Q_PAD_EIM_A20__GPIO_2_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__TPSMP_HDATA_2 \
+ (_MX6Q_PAD_EIM_A20__TPSMP_HDATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A20__SRC_BT_CFG_20 \
+ (_MX6Q_PAD_EIM_A20__SRC_BT_CFG_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19 \
+ (_MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14 \
+ (_MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14 \
+ (_MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__RESERVED_RESERVED \
+ (_MX6Q_PAD_EIM_A19__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_TEST_OUT_20 \
+ (_MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_TEST_OUT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__GPIO_2_19 \
+ (_MX6Q_PAD_EIM_A19__GPIO_2_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__TPSMP_HDATA_3 \
+ (_MX6Q_PAD_EIM_A19__TPSMP_HDATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A19__SRC_BT_CFG_19 \
+ (_MX6Q_PAD_EIM_A19__SRC_BT_CFG_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18 \
+ (_MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13 \
+ (_MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13 \
+ (_MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__RESERVED_RESERVED \
+ (_MX6Q_PAD_EIM_A18__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_TEST_OUT_21 \
+ (_MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_TEST_OUT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__GPIO_2_20 \
+ (_MX6Q_PAD_EIM_A18__GPIO_2_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__TPSMP_HDATA_4 \
+ (_MX6Q_PAD_EIM_A18__TPSMP_HDATA_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A18__SRC_BT_CFG_18 \
+ (_MX6Q_PAD_EIM_A18__SRC_BT_CFG_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17 \
+ (_MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12 \
+ (_MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12 \
+ (_MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__RESERVED_RESERVED \
+ (_MX6Q_PAD_EIM_A17__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_TEST_OUT_22 \
+ (_MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_TEST_OUT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__GPIO_2_21 \
+ (_MX6Q_PAD_EIM_A17__GPIO_2_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__TPSMP_HDATA_5 \
+ (_MX6Q_PAD_EIM_A17__TPSMP_HDATA_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A17__SRC_BT_CFG_17 \
+ (_MX6Q_PAD_EIM_A17__SRC_BT_CFG_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16 \
+ (_MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK \
+ (_MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK \
+ (_MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_TEST_OUT_23 \
+ (_MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_TEST_OUT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__GPIO_2_22 \
+ (_MX6Q_PAD_EIM_A16__GPIO_2_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__TPSMP_HDATA_6 \
+ (_MX6Q_PAD_EIM_A16__TPSMP_HDATA_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_A16__SRC_BT_CFG_16 \
+ (_MX6Q_PAD_EIM_A16__SRC_BT_CFG_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0 \
+ (_MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5 \
+ (_MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS0__ECSPI2_SCLK \
+ (_MX6Q_PAD_EIM_CS0__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_TEST_OUT_24 \
+ (_MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_TEST_OUT_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS0__GPIO_2_23 \
+ (_MX6Q_PAD_EIM_CS0__GPIO_2_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7 \
+ (_MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1 \
+ (_MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6 \
+ (_MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS1__ECSPI2_MOSI \
+ (_MX6Q_PAD_EIM_CS1__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_TEST_OUT_25 \
+ (_MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_TEST_OUT_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS1__GPIO_2_24 \
+ (_MX6Q_PAD_EIM_CS1__GPIO_2_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8 \
+ (_MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_OE__WEIM_WEIM_OE \
+ (_MX6Q_PAD_EIM_OE__WEIM_WEIM_OE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7 \
+ (_MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_OE__ECSPI2_MISO \
+ (_MX6Q_PAD_EIM_OE__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_TEST_OUT_26 \
+ (_MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_TEST_OUT_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_OE__GPIO_2_25 \
+ (_MX6Q_PAD_EIM_OE__GPIO_2_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_OE__TPSMP_HDATA_9 \
+ (_MX6Q_PAD_EIM_OE__TPSMP_HDATA_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_RW__WEIM_WEIM_RW \
+ (_MX6Q_PAD_EIM_RW__WEIM_WEIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8 \
+ (_MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__ECSPI2_SS0 \
+ (_MX6Q_PAD_EIM_RW__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_TEST_OUT_27 \
+ (_MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_TEST_OUT_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__GPIO_2_26 \
+ (_MX6Q_PAD_EIM_RW__GPIO_2_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__TPSMP_HDATA_10 \
+ (_MX6Q_PAD_EIM_RW__TPSMP_HDATA_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_RW__SRC_BT_CFG_29 \
+ (_MX6Q_PAD_EIM_RW__SRC_BT_CFG_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA \
+ (_MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 \
+ (_MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_LBA__ECSPI2_SS1 \
+ (_MX6Q_PAD_EIM_LBA__ECSPI2_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_LBA__GPIO_2_27 \
+ (_MX6Q_PAD_EIM_LBA__GPIO_2_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11 \
+ (_MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26 \
+ (_MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0 \
+ (_MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11 \
+ (_MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11 \
+ (_MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_TEST_OUT_0 \
+ (_MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_TEST_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY \
+ (_MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__GPIO_2_28 \
+ (_MX6Q_PAD_EIM_EB0__GPIO_2_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12 \
+ (_MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27 \
+ (_MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1 \
+ (_MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10 \
+ (_MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10 \
+ (_MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY_TEST_OUT_1 \
+ (_MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY_TEST_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__GPIO_2_29 \
+ (_MX6Q_PAD_EIM_EB1__GPIO_2_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13 \
+ (_MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28 \
+ (_MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 \
+ (_MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9 \
+ (_MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9 \
+ (_MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY_TEST_OUT_2 \
+ (_MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY_TEST_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__GPIO_3_0 \
+ (_MX6Q_PAD_EIM_DA0__GPIO_3_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14 \
+ (_MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0 \
+ (_MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 \
+ (_MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8 \
+ (_MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8 \
+ (_MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_TEST_OUT_3 \
+ (_MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_TEST_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__ANATOP_USBPHY1_TSTI_TX_LS_MODE \
+ (_MX6Q_PAD_EIM_DA1__ANATOP_USBPHY1_TSTI_TX_LS_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__GPIO_3_1 \
+ (_MX6Q_PAD_EIM_DA1__GPIO_3_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15 \
+ (_MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1 \
+ (_MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 \
+ (_MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7 \
+ (_MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7 \
+ (_MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_TEST_OUT_4 \
+ (_MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_TEST_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__ANATOP_USBPHY1_TSTI_TX_HS_MODE \
+ (_MX6Q_PAD_EIM_DA2__ANATOP_USBPHY1_TSTI_TX_HS_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__GPIO_3_2 \
+ (_MX6Q_PAD_EIM_DA2__GPIO_3_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16 \
+ (_MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2 \
+ (_MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 \
+ (_MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6 \
+ (_MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6 \
+ (_MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_TEST_OUT_5 \
+ (_MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_TEST_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__ANATOP_USBPHY1_TSTI_TX_HIZ \
+ (_MX6Q_PAD_EIM_DA3__ANATOP_USBPHY1_TSTI_TX_HIZ | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__GPIO_3_3 \
+ (_MX6Q_PAD_EIM_DA3__GPIO_3_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17 \
+ (_MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3 \
+ (_MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 \
+ (_MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5 \
+ (_MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5 \
+ (_MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_TEST_OUT_6 \
+ (_MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_TEST_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TSTI_TX_EN \
+ (_MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TSTI_TX_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__GPIO_3_4 \
+ (_MX6Q_PAD_EIM_DA4__GPIO_3_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18 \
+ (_MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4 \
+ (_MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 \
+ (_MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4 \
+ (_MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4 \
+ (_MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_TEST_OUT_7 \
+ (_MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_TEST_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TSTI_TX_DP \
+ (_MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TSTI_TX_DP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__GPIO_3_5 \
+ (_MX6Q_PAD_EIM_DA5__GPIO_3_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19 \
+ (_MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5 \
+ (_MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 \
+ (_MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3 \
+ (_MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3 \
+ (_MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_TEST_OUT_8 \
+ (_MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_TEST_OUT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TSTI_TX_DN \
+ (_MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TSTI_TX_DN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__GPIO_3_6 \
+ (_MX6Q_PAD_EIM_DA6__GPIO_3_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20 \
+ (_MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6 \
+ (_MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 \
+ (_MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2 \
+ (_MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2 \
+ (_MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_TEST_OUT_9 \
+ (_MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_TEST_OUT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__GPIO_3_7 \
+ (_MX6Q_PAD_EIM_DA7__GPIO_3_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21 \
+ (_MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7 \
+ (_MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 \
+ (_MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1 \
+ (_MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1 \
+ (_MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_TEST_OUT_10 \
+ (_MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_TEST_OUT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__GPIO_3_8 \
+ (_MX6Q_PAD_EIM_DA8__GPIO_3_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22 \
+ (_MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8 \
+ (_MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 \
+ (_MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0 \
+ (_MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0 \
+ (_MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_TEST_OUT_11 \
+ (_MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_TEST_OUT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__GPIO_3_9 \
+ (_MX6Q_PAD_EIM_DA9__GPIO_3_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23 \
+ (_MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9 \
+ (_MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 \
+ (_MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 \
+ (_MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN \
+ (_MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_TEST_OUT_12 \
+ (_MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_TEST_OUT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__GPIO_3_10 \
+ (_MX6Q_PAD_EIM_DA10__GPIO_3_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24 \
+ (_MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10 \
+ (_MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 \
+ (_MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2 \
+ (_MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC \
+ (_MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_TEST_OUT_13 \
+ (_MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_TEST_OUT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__SDMA_DEBUG_EVT_CHN_LINES_6 \
+ (_MX6Q_PAD_EIM_DA11__SDMA_DEBUG_EVT_CHN_LINES_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__GPIO_3_11 \
+ (_MX6Q_PAD_EIM_DA11__GPIO_3_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25 \
+ (_MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11 \
+ (_MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 \
+ (_MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3 \
+ (_MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC \
+ (_MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_TEST_OUT_14 \
+ (_MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_TEST_OUT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_LINES_3 \
+ (_MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_LINES_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__GPIO_3_12 \
+ (_MX6Q_PAD_EIM_DA12__GPIO_3_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26 \
+ (_MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12 \
+ (_MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 \
+ (_MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS \
+ (_MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK \
+ (_MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_TEST_OUT_15 \
+ (_MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_TEST_OUT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_LINES_4 \
+ (_MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_LINES_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__GPIO_3_13 \
+ (_MX6Q_PAD_EIM_DA13__GPIO_3_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27 \
+ (_MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13 \
+ (_MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 \
+ (_MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS \
+ (_MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK \
+ (_MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_TEST_OUT_16 \
+ (_MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_TEST_OUT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_LINES_5 \
+ (_MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_LINES_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__GPIO_3_14 \
+ (_MX6Q_PAD_EIM_DA14__GPIO_3_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28 \
+ (_MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14 \
+ (_MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 \
+ (_MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1 \
+ (_MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4 \
+ (_MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_TEST_OUT_17 \
+ (_MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_TEST_OUT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__GPIO_3_15 \
+ (_MX6Q_PAD_EIM_DA15__GPIO_3_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29 \
+ (_MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15 \
+ (_MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT \
+ (_MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B \
+ (_MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_WAIT__GPIO_5_0 \
+ (_MX6Q_PAD_EIM_WAIT__GPIO_5_0 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30 \
+ (_MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25 \
+ (_MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK \
+ (_MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 \
+ (_MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_BCLK__GPIO_6_31 \
+ (_MX6Q_PAD_EIM_BCLK__GPIO_6_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31 \
+ (_MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK \
+ (_MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK \
+ (_MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_DISP_CLK__MIPI_CORE_DPHY_TEST_OUT_28 \
+ (_MX6Q_PAD_DI0_DISP_CLK__MIPI_CORE_DPHY_TEST_OUT_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 \
+ (_MX6Q_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16 \
+ (_MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_DISP_CLK__MMDC_MMDC_DEBUG_0 \
+ (_MX6Q_PAD_DI0_DISP_CLK__MMDC_MMDC_DEBUG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 \
+ (_MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 \
+ (_MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC \
+ (_MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN15__MIPI_CORE_DPHY_TEST_OUT_29 \
+ (_MX6Q_PAD_DI0_PIN15__MIPI_CORE_DPHY_TEST_OUT_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 \
+ (_MX6Q_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN15__GPIO_4_17 \
+ (_MX6Q_PAD_DI0_PIN15__GPIO_4_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 \
+ (_MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2 \
+ (_MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2 \
+ (_MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD \
+ (_MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN2__MIPI_CORE_DPHY_TEST_OUT_30 \
+ (_MX6Q_PAD_DI0_PIN2__MIPI_CORE_DPHY_TEST_OUT_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 \
+ (_MX6Q_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN2__GPIO_4_18 \
+ (_MX6Q_PAD_DI0_PIN2__GPIO_4_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN2__MMDC_MMDC_DEBUG_2 \
+ (_MX6Q_PAD_DI0_PIN2__MMDC_MMDC_DEBUG_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN2__PL301_MX6QPER1_HADDR_9 \
+ (_MX6Q_PAD_DI0_PIN2__PL301_MX6QPER1_HADDR_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3 \
+ (_MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3 \
+ (_MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS \
+ (_MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_TEST_OUT_31 \
+ (_MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_TEST_OUT_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 \
+ (_MX6Q_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN3__GPIO_4_19 \
+ (_MX6Q_PAD_DI0_PIN3__GPIO_4_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 \
+ (_MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN3__PL301_MX6QPER1_HADDR_10 \
+ (_MX6Q_PAD_DI0_PIN3__PL301_MX6QPER1_HADDR_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4 \
+ (_MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4 \
+ (_MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD \
+ (_MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__USDHC1_WP \
+ (_MX6Q_PAD_DI0_PIN4__USDHC1_WP | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD \
+ (_MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__GPIO_4_20 \
+ (_MX6Q_PAD_DI0_PIN4__GPIO_4_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 \
+ (_MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DI0_PIN4__PL301_MX6QPER1_HADDR_11 \
+ (_MX6Q_PAD_DI0_PIN4__PL301_MX6QPER1_HADDR_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 \
+ (_MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0 \
+ (_MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK \
+ (_MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DEBUG_0 \
+ (_MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DEBUG_0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN \
+ (_MX6Q_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT0__GPIO_4_21 \
+ (_MX6Q_PAD_DISP0_DAT0__GPIO_4_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 \
+ (_MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 \
+ (_MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1 \
+ (_MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI \
+ (_MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DEBUG_1 \
+ (_MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DEBUG_1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL \
+ (_MX6Q_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT1__GPIO_4_22 \
+ (_MX6Q_PAD_DISP0_DAT1__GPIO_4_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT1__MMDC_MMDC_DEBUG_6 \
+ (_MX6Q_PAD_DISP0_DAT1__MMDC_MMDC_DEBUG_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT1__PL301_MX6QPER1_HADDR_12 \
+ (_MX6Q_PAD_DISP0_DAT1__PL301_MX6QPER1_HADDR_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 \
+ (_MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2 \
+ (_MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO \
+ (_MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DEBUG_2 \
+ (_MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DEBUG_2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE \
+ (_MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT2__GPIO_4_23 \
+ (_MX6Q_PAD_DISP0_DAT2__GPIO_4_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT2__MMDC_MMDC_DEBUG_7 \
+ (_MX6Q_PAD_DISP0_DAT2__MMDC_MMDC_DEBUG_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT2__PL301_MX6QPER1_HADDR_13 \
+ (_MX6Q_PAD_DISP0_DAT2__PL301_MX6QPER1_HADDR_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 \
+ (_MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3 \
+ (_MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 \
+ (_MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DEBUG_3 \
+ (_MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DEBUG_3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR \
+ (_MX6Q_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT3__GPIO_4_24 \
+ (_MX6Q_PAD_DISP0_DAT3__GPIO_4_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DEBUG_8 \
+ (_MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DEBUG_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT3__PL301_MX6QPER1_HADDR_14 \
+ (_MX6Q_PAD_DISP0_DAT3__PL301_MX6QPER1_HADDR_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 \
+ (_MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4 \
+ (_MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 \
+ (_MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DEBUG_4 \
+ (_MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DEBUG_4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB \
+ (_MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT4__GPIO_4_25 \
+ (_MX6Q_PAD_DISP0_DAT4__GPIO_4_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 \
+ (_MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT4__PL301_MX6QPER1_HADDR_15 \
+ (_MX6Q_PAD_DISP0_DAT4__PL301_MX6QPER1_HADDR_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 \
+ (_MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5 \
+ (_MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 \
+ (_MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS \
+ (_MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS \
+ (_MX6Q_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT5__GPIO_4_26 \
+ (_MX6Q_PAD_DISP0_DAT5__GPIO_4_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT5__MMDC_MMDC_DEBUG_10 \
+ (_MX6Q_PAD_DISP0_DAT5__MMDC_MMDC_DEBUG_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT5__PL301_MX6QPER1_HADDR_16 \
+ (_MX6Q_PAD_DISP0_DAT5__PL301_MX6QPER1_HADDR_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 \
+ (_MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6 \
+ (_MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 \
+ (_MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC \
+ (_MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE \
+ (_MX6Q_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT6__GPIO_4_27 \
+ (_MX6Q_PAD_DISP0_DAT6__GPIO_4_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT6__MMDC_MMDC_DEBUG_11 \
+ (_MX6Q_PAD_DISP0_DAT6__MMDC_MMDC_DEBUG_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT6__PL301_MX6QPER1_HADDR_17 \
+ (_MX6Q_PAD_DISP0_DAT6__PL301_MX6QPER1_HADDR_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 \
+ (_MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7 \
+ (_MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY \
+ (_MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DEBUG_5 \
+ (_MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DEBUG_5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 \
+ (_MX6Q_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT7__GPIO_4_28 \
+ (_MX6Q_PAD_DISP0_DAT7__GPIO_4_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT7__MMDC_MMDC_DEBUG_12 \
+ (_MX6Q_PAD_DISP0_DAT7__MMDC_MMDC_DEBUG_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT7__PL301_MX6QPER1_HADDR_18 \
+ (_MX6Q_PAD_DISP0_DAT7__PL301_MX6QPER1_HADDR_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 \
+ (_MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8 \
+ (_MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT8__PWM1_PWMO \
+ (_MX6Q_PAD_DISP0_DAT8__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B \
+ (_MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 \
+ (_MX6Q_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT8__GPIO_4_29 \
+ (_MX6Q_PAD_DISP0_DAT8__GPIO_4_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT8__MMDC_MMDC_DEBUG_13 \
+ (_MX6Q_PAD_DISP0_DAT8__MMDC_MMDC_DEBUG_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT8__PL301_MX6QPER1_HADDR_19 \
+ (_MX6Q_PAD_DISP0_DAT8__PL301_MX6QPER1_HADDR_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 \
+ (_MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9 \
+ (_MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT9__PWM2_PWMO \
+ (_MX6Q_PAD_DISP0_DAT9__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B \
+ (_MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 \
+ (_MX6Q_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT9__GPIO_4_30 \
+ (_MX6Q_PAD_DISP0_DAT9__GPIO_4_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT9__MMDC_MMDC_DEBUG_14 \
+ (_MX6Q_PAD_DISP0_DAT9__MMDC_MMDC_DEBUG_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT9__PL301_MX6QPER1_HADDR_20 \
+ (_MX6Q_PAD_DISP0_DAT9__PL301_MX6QPER1_HADDR_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 \
+ (_MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10 \
+ (_MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT10__USDHC1_USDHC_DEBUG_6 \
+ (_MX6Q_PAD_DISP0_DAT10__USDHC1_USDHC_DEBUG_6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 \
+ (_MX6Q_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT10__GPIO_4_31 \
+ (_MX6Q_PAD_DISP0_DAT10__GPIO_4_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT10__MMDC_MMDC_DEBUG_15 \
+ (_MX6Q_PAD_DISP0_DAT10__MMDC_MMDC_DEBUG_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT10__PL301_MX6QPER1_HADDR_21 \
+ (_MX6Q_PAD_DISP0_DAT10__PL301_MX6QPER1_HADDR_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 \
+ (_MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11 \
+ (_MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DEBUG_7 \
+ (_MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DEBUG_7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 \
+ (_MX6Q_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT11__GPIO_5_5 \
+ (_MX6Q_PAD_DISP0_DAT11__GPIO_5_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT11__MMDC_MMDC_DEBUG_16 \
+ (_MX6Q_PAD_DISP0_DAT11__MMDC_MMDC_DEBUG_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT11__PL301_MX6QPER1_HADDR_22 \
+ (_MX6Q_PAD_DISP0_DAT11__PL301_MX6QPER1_HADDR_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 \
+ (_MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12 \
+ (_MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED \
+ (_MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 \
+ (_MX6Q_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT12__GPIO_5_6 \
+ (_MX6Q_PAD_DISP0_DAT12__GPIO_5_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT12__MMDC_MMDC_DEBUG_17 \
+ (_MX6Q_PAD_DISP0_DAT12__MMDC_MMDC_DEBUG_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT12__PL301_MX6QPER1_HADDR_23 \
+ (_MX6Q_PAD_DISP0_DAT12__PL301_MX6QPER1_HADDR_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 \
+ (_MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13 \
+ (_MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS \
+ (_MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 \
+ (_MX6Q_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT13__GPIO_5_7 \
+ (_MX6Q_PAD_DISP0_DAT13__GPIO_5_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT13__MMDC_MMDC_DEBUG_18 \
+ (_MX6Q_PAD_DISP0_DAT13__MMDC_MMDC_DEBUG_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT13__PL301_MX6QPER1_HADDR_24 \
+ (_MX6Q_PAD_DISP0_DAT13__PL301_MX6QPER1_HADDR_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 \
+ (_MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14 \
+ (_MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC \
+ (_MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 \
+ (_MX6Q_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT14__GPIO_5_8 \
+ (_MX6Q_PAD_DISP0_DAT14__GPIO_5_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT14__MMDC_MMDC_DEBUG_19 \
+ (_MX6Q_PAD_DISP0_DAT14__MMDC_MMDC_DEBUG_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 \
+ (_MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15 \
+ (_MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 \
+ (_MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 \
+ (_MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 \
+ (_MX6Q_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT15__GPIO_5_9 \
+ (_MX6Q_PAD_DISP0_DAT15__GPIO_5_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT15__MMDC_MMDC_DEBUG_20 \
+ (_MX6Q_PAD_DISP0_DAT15__MMDC_MMDC_DEBUG_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT15__PL301_MX6QPER1_HADDR_25 \
+ (_MX6Q_PAD_DISP0_DAT15__PL301_MX6QPER1_HADDR_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 \
+ (_MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16 \
+ (_MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI \
+ (_MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC \
+ (_MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT16__SDMA_SDMA_EXT_EVENT_0 \
+ (_MX6Q_PAD_DISP0_DAT16__SDMA_SDMA_EXT_EVENT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT16__GPIO_5_10 \
+ (_MX6Q_PAD_DISP0_DAT16__GPIO_5_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT16__MMDC_MMDC_DEBUG_21 \
+ (_MX6Q_PAD_DISP0_DAT16__MMDC_MMDC_DEBUG_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT16__PL301_MX6QPER1_HADDR_26 \
+ (_MX6Q_PAD_DISP0_DAT16__PL301_MX6QPER1_HADDR_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 \
+ (_MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17 \
+ (_MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO \
+ (_MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD \
+ (_MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT17__SDMA_SDMA_EXT_EVENT_1 \
+ (_MX6Q_PAD_DISP0_DAT17__SDMA_SDMA_EXT_EVENT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT17__GPIO_5_11 \
+ (_MX6Q_PAD_DISP0_DAT17__GPIO_5_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT17__MMDC_MMDC_DEBUG_22 \
+ (_MX6Q_PAD_DISP0_DAT17__MMDC_MMDC_DEBUG_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT17__PL301_MX6QPER1_HADDR_27 \
+ (_MX6Q_PAD_DISP0_DAT17__PL301_MX6QPER1_HADDR_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 \
+ (_MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18 \
+ (_MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 \
+ (_MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS \
+ (_MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS \
+ (_MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT18__GPIO_5_12 \
+ (_MX6Q_PAD_DISP0_DAT18__GPIO_5_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT18__MMDC_MMDC_DEBUG_23 \
+ (_MX6Q_PAD_DISP0_DAT18__MMDC_MMDC_DEBUG_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 \
+ (_MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 \
+ (_MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19 \
+ (_MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK \
+ (_MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD \
+ (_MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC \
+ (_MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT19__GPIO_5_13 \
+ (_MX6Q_PAD_DISP0_DAT19__GPIO_5_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT19__MMDC_MMDC_DEBUG_24 \
+ (_MX6Q_PAD_DISP0_DAT19__MMDC_MMDC_DEBUG_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 \
+ (_MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 \
+ (_MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20 \
+ (_MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK \
+ (_MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC \
+ (_MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 \
+ (_MX6Q_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT20__GPIO_5_14 \
+ (_MX6Q_PAD_DISP0_DAT20__GPIO_5_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT20__MMDC_MMDC_DEBUG_25 \
+ (_MX6Q_PAD_DISP0_DAT20__MMDC_MMDC_DEBUG_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT20__PL301_MX6QPER1_HADDR_28 \
+ (_MX6Q_PAD_DISP0_DAT20__PL301_MX6QPER1_HADDR_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 \
+ (_MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21 \
+ (_MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI \
+ (_MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD \
+ (_MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 \
+ (_MX6Q_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT21__GPIO_5_15 \
+ (_MX6Q_PAD_DISP0_DAT21__GPIO_5_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT21__MMDC_MMDC_DEBUG_26 \
+ (_MX6Q_PAD_DISP0_DAT21__MMDC_MMDC_DEBUG_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT21__PL301_MX6QPER1_HADDR_29 \
+ (_MX6Q_PAD_DISP0_DAT21__PL301_MX6QPER1_HADDR_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 \
+ (_MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22 \
+ (_MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO \
+ (_MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS \
+ (_MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 \
+ (_MX6Q_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT22__GPIO_5_16 \
+ (_MX6Q_PAD_DISP0_DAT22__GPIO_5_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT22__MMDC_MMDC_DEBUG_27 \
+ (_MX6Q_PAD_DISP0_DAT22__MMDC_MMDC_DEBUG_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT22__PL301_MX6QPER1_HADDR_30 \
+ (_MX6Q_PAD_DISP0_DAT22__PL301_MX6QPER1_HADDR_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 \
+ (_MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23 \
+ (_MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23 | MUX_PAD_CTRL(MX6Q_DISP_PAD_CLT))
+#define MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 \
+ (_MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD \
+ (_MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 \
+ (_MX6Q_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT23__GPIO_5_17 \
+ (_MX6Q_PAD_DISP0_DAT23__GPIO_5_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT23__MMDC_MMDC_DEBUG_28 \
+ (_MX6Q_PAD_DISP0_DAT23__MMDC_MMDC_DEBUG_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_DISP0_DAT23__PL301_MX6QPER1_HADDR_31 \
+ (_MX6Q_PAD_DISP0_DAT23__PL301_MX6QPER1_HADDR_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED \
+ (_MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__ENET_MDIO \
+ (_MX6Q_PAD_ENET_MDIO__ENET_MDIO | \
+ MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__ESAI1_SCKR \
+ (_MX6Q_PAD_ENET_MDIO__ESAI1_SCKR | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEVICE_3 \
+ (_MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEVICE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT \
+ (_MX6Q_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__GPIO_1_22 \
+ (_MX6Q_PAD_ENET_MDIO__GPIO_1_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK \
+ (_MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_REF_CLK__RESERVED_RESERVED \
+ (_MX6Q_PAD_ENET_REF_CLK__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK \
+ (_MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(MX6Q_ENET_REF_CLK_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR \
+ (_MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 \
+ (_MX6Q_PAD_ENET_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__GPIO_1_23 \
+ (_MX6Q_PAD_ENET_REF_CLK__GPIO_1_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK \
+ (_MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_REF_CLK__ANATOP_USBPHY1_TSTO_RX_SQUELCH \
+ (_MX6Q_PAD_ENET_REF_CLK__ANATOP_USBPHY1_TSTO_RX_SQUELCH | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID \
+ (_MX6Q_PAD_ENET_RX_ER__ANATOP_USBOTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__ENET_RX_ER \
+ (_MX6Q_PAD_ENET_RX_ER__ENET_RX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR \
+ (_MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__SPDIF_IN1 \
+ (_MX6Q_PAD_ENET_RX_ER__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT \
+ (_MX6Q_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__GPIO_1_24 \
+ (_MX6Q_PAD_ENET_RX_ER__GPIO_1_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__PHY_TDI \
+ (_MX6Q_PAD_ENET_RX_ER__PHY_TDI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RX_ER__ANATOP_USBPHY1_TSTO_RX_HS_RXD \
+ (_MX6Q_PAD_ENET_RX_ER__ANATOP_USBPHY1_TSTO_RX_HS_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_CRS_DV__RESERVED_RESERVED \
+ (_MX6Q_PAD_ENET_CRS_DV__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN \
+ (_MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT \
+ (_MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__SPDIF_SPDIF_EXTCLK \
+ (_MX6Q_PAD_ENET_CRS_DV__SPDIF_SPDIF_EXTCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__GPIO_1_25 \
+ (_MX6Q_PAD_ENET_CRS_DV__GPIO_1_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__PHY_TDO \
+ (_MX6Q_PAD_ENET_CRS_DV__PHY_TDO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_CRS_DV__ANATOP_USBPHY1_TSTO_RX_FS_RXD \
+ (_MX6Q_PAD_ENET_CRS_DV__ANATOP_USBPHY1_TSTO_RX_FS_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_RXD1__MLB_MLBSIG \
+ (_MX6Q_PAD_ENET_RXD1__MLB_MLBSIG | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__ENET_RDATA_1 \
+ (_MX6Q_PAD_ENET_RXD1__ENET_RDATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__ESAI1_FST \
+ (_MX6Q_PAD_ENET_RXD1__ESAI1_FST | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT \
+ (_MX6Q_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__GPIO_1_26 \
+ (_MX6Q_PAD_ENET_RXD1__GPIO_1_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__PHY_TCK \
+ (_MX6Q_PAD_ENET_RXD1__PHY_TCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD1__ANATOP_USBPHY1_TSTO_RX_DISCON_DET \
+ (_MX6Q_PAD_ENET_RXD1__ANATOP_USBPHY1_TSTO_RX_DISCON_DET | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT \
+ (_MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__ENET_RDATA_0 \
+ (_MX6Q_PAD_ENET_RXD0__ENET_RDATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__ESAI1_HCKT \
+ (_MX6Q_PAD_ENET_RXD0__ESAI1_HCKT | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__SPDIF_OUT1 \
+ (_MX6Q_PAD_ENET_RXD0__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__GPIO_1_27 \
+ (_MX6Q_PAD_ENET_RXD0__GPIO_1_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__PHY_TMS \
+ (_MX6Q_PAD_ENET_RXD0__PHY_TMS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_RXD0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV \
+ (_MX6Q_PAD_ENET_RXD0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_TX_EN__RESERVED_RESERVED \
+ (_MX6Q_PAD_ENET_TX_EN__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TX_EN__ENET_TX_EN \
+ (_MX6Q_PAD_ENET_TX_EN__ENET_TX_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2 \
+ (_MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_TX_EN__GPIO_1_28 \
+ (_MX6Q_PAD_ENET_TX_EN__GPIO_1_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI \
+ (_MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TX_EN__ANATOP_USBPHY2_TSTO_RX_SQUELCH \
+ (_MX6Q_PAD_ENET_TX_EN__ANATOP_USBPHY2_TSTO_RX_SQUELCH | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_TXD1__MLB_MLBCLK \
+ (_MX6Q_PAD_ENET_TXD1__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__ENET_TDATA_1 \
+ (_MX6Q_PAD_ENET_TXD1__ENET_TDATA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3 \
+ (_MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN \
+ (_MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__GPIO_1_29 \
+ (_MX6Q_PAD_ENET_TXD1__GPIO_1_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO \
+ (_MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD1__ANATOP_USBPHY2_TSTO_RX_HS_RXD \
+ (_MX6Q_PAD_ENET_TXD1__ANATOP_USBPHY2_TSTO_RX_HS_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_TXD0__RESERVED_RESERVED \
+ (_MX6Q_PAD_ENET_TXD0__RESERVED_RESERVED | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD0__ENET_TDATA_0 \
+ (_MX6Q_PAD_ENET_TXD0__ENET_TDATA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1 \
+ (_MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD0__GPIO_1_30 \
+ (_MX6Q_PAD_ENET_TXD0__GPIO_1_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK \
+ (_MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_TXD0__ANATOP_USBPHY2_TSTO_RX_FS_RXD \
+ (_MX6Q_PAD_ENET_TXD0__ANATOP_USBPHY2_TSTO_RX_FS_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_ENET_MDC__MLB_MLBDAT \
+ (_MX6Q_PAD_ENET_MDC__MLB_MLBDAT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__ENET_MDC \
+ (_MX6Q_PAD_ENET_MDC__ENET_MDC | \
+ MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0 \
+ (_MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN \
+ (_MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__GPIO_1_31 \
+ (_MX6Q_PAD_ENET_MDC__GPIO_1_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__SATA_PHY_TMS \
+ (_MX6Q_PAD_ENET_MDC__SATA_PHY_TMS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_ENET_MDC__ANATOP_USBPHY2_TSTO_RX_DISCON_DET \
+ (_MX6Q_PAD_ENET_MDC__ANATOP_USBPHY2_TSTO_RX_DISCON_DET | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40 \
+ (_MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41 \
+ (_MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42 \
+ (_MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43 \
+ (_MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44 \
+ (_MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45 \
+ (_MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46 \
+ (_MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47 \
+ (_MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 \
+ (_MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 \
+ (_MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32 \
+ (_MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33 \
+ (_MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34 \
+ (_MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35 \
+ (_MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36 \
+ (_MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37 \
+ (_MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38 \
+ (_MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39 \
+ (_MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 \
+ (_MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 \
+ (_MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24 \
+ (_MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25 \
+ (_MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26 \
+ (_MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27 \
+ (_MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28 \
+ (_MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29 \
+ (_MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 \
+ (_MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30 \
+ (_MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31 \
+ (_MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 \
+ (_MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16 \
+ (_MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17 \
+ (_MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18 \
+ (_MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19 \
+ (_MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20 \
+ (_MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21 \
+ (_MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22 \
+ (_MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 \
+ (_MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23 \
+ (_MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 \
+ (_MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0 \
+ (_MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1 \
+ (_MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2 \
+ (_MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3 \
+ (_MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4 \
+ (_MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5 \
+ (_MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6 \
+ (_MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7 \
+ (_MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8 \
+ (_MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9 \
+ (_MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10 \
+ (_MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11 \
+ (_MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12 \
+ (_MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13 \
+ (_MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14 \
+ (_MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15 \
+ (_MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS \
+ (_MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0 \
+ (_MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1 \
+ (_MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS \
+ (_MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET \
+ (_MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 \
+ (_MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 \
+ (_MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 \
+ (_MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 \
+ (_MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 \
+ (_MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 \
+ (_MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 \
+ (_MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 \
+ (_MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 \
+ (_MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE \
+ (_MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0 \
+ (_MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1 \
+ (_MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2 \
+ (_MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3 \
+ (_MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4 \
+ (_MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5 \
+ (_MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 \
+ (_MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6 \
+ (_MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7 \
+ (_MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 \
+ (_MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8 \
+ (_MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9 \
+ (_MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10 \
+ (_MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11 \
+ (_MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12 \
+ (_MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13 \
+ (_MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14 \
+ (_MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 \
+ (_MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15 \
+ (_MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 \
+ (_MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48 \
+ (_MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49 \
+ (_MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50 \
+ (_MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51 \
+ (_MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52 \
+ (_MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53 \
+ (_MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54 \
+ (_MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55 \
+ (_MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 \
+ (_MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 \
+ (_MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56 \
+ (_MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 \
+ (_MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57 \
+ (_MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58 \
+ (_MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59 \
+ (_MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60 \
+ (_MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 \
+ (_MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61 \
+ (_MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62 \
+ (_MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63 \
+ (_MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK \
+ (_MX6Q_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__ENET_RDATA_3 \
+ (_MX6Q_PAD_KEY_COL0__ENET_RDATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC \
+ (_MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__KPP_COL_0 \
+ (_MX6Q_PAD_KEY_COL0__KPP_COL_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__UART4_TXD \
+ (_MX6Q_PAD_KEY_COL0__UART4_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__UART4_RXD \
+ (_MX6Q_PAD_KEY_COL0__UART4_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__GPIO_4_6 \
+ (_MX6Q_PAD_KEY_COL0__GPIO_4_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT \
+ (_MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST \
+ (_MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI \
+ (_MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__ENET_TDATA_3 \
+ (_MX6Q_PAD_KEY_ROW0__ENET_TDATA_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD \
+ (_MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__KPP_ROW_0 \
+ (_MX6Q_PAD_KEY_ROW0__KPP_ROW_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__UART4_TXD \
+ (_MX6Q_PAD_KEY_ROW0__UART4_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__UART4_RXD \
+ (_MX6Q_PAD_KEY_ROW0__UART4_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__GPIO_4_7 \
+ (_MX6Q_PAD_KEY_ROW0__GPIO_4_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT \
+ (_MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW0__PL301_MX6QPER1_HADDR_0 \
+ (_MX6Q_PAD_KEY_ROW0__PL301_MX6QPER1_HADDR_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_COL1__ECSPI1_MISO \
+ (_MX6Q_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__ENET_MDIO \
+ (_MX6Q_PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS \
+ (_MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__KPP_COL_1 \
+ (_MX6Q_PAD_KEY_COL1__KPP_COL_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__UART5_TXD \
+ (_MX6Q_PAD_KEY_COL1__UART5_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__UART5_RXD \
+ (_MX6Q_PAD_KEY_COL1__UART5_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__GPIO_4_8 \
+ (_MX6Q_PAD_KEY_COL1__GPIO_4_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__USDHC1_VSELECT \
+ (_MX6Q_PAD_KEY_COL1__USDHC1_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL1__PL301_MX6QPER1_HADDR_1 \
+ (_MX6Q_PAD_KEY_COL1__PL301_MX6QPER1_HADDR_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 \
+ (_MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__ENET_COL \
+ (_MX6Q_PAD_KEY_ROW1__ENET_COL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD \
+ (_MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__KPP_ROW_1 \
+ (_MX6Q_PAD_KEY_ROW1__KPP_ROW_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__UART5_TXD \
+ (_MX6Q_PAD_KEY_ROW1__UART5_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__UART5_RXD \
+ (_MX6Q_PAD_KEY_ROW1__UART5_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__GPIO_4_9 \
+ (_MX6Q_PAD_KEY_ROW1__GPIO_4_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT \
+ (_MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW1__PL301_MX6QPER1_HADDR_2 \
+ (_MX6Q_PAD_KEY_ROW1__PL301_MX6QPER1_HADDR_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_COL2__ECSPI1_SS1 \
+ (_MX6Q_PAD_KEY_COL2__ECSPI1_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__ENET_RDATA_2 \
+ (_MX6Q_PAD_KEY_COL2__ENET_RDATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__CAN1_TXCAN \
+ (_MX6Q_PAD_KEY_COL2__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__KPP_COL_2 \
+ (_MX6Q_PAD_KEY_COL2__KPP_COL_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__ENET_MDC \
+ (_MX6Q_PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(MX6Q_ENET_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__GPIO_4_10 \
+ (_MX6Q_PAD_KEY_COL2__GPIO_4_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__USBOH3_H1USB_PWRCTL_WAKEUP \
+ (_MX6Q_PAD_KEY_COL2__USBOH3_H1USB_PWRCTL_WAKEUP | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL2__PL301_MX6QPER1_HADDR_3 \
+ (_MX6Q_PAD_KEY_COL2__PL301_MX6QPER1_HADDR_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 \
+ (_MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__ENET_TDATA_2 \
+ (_MX6Q_PAD_KEY_ROW2__ENET_TDATA_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__CAN1_RXCAN \
+ (_MX6Q_PAD_KEY_ROW2__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__KPP_ROW_2 \
+ (_MX6Q_PAD_KEY_ROW2__KPP_ROW_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT \
+ (_MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__GPIO_4_11 \
+ (_MX6Q_PAD_KEY_ROW2__GPIO_4_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE \
+ (_MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE | MUX_PAD_CTRL(MX6Q_HDMICEC_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW2__PL301_MX6QPER1_HADDR_4 \
+ (_MX6Q_PAD_KEY_ROW2__PL301_MX6QPER1_HADDR_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_COL3__ECSPI1_SS3 \
+ (_MX6Q_PAD_KEY_COL3__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__ENET_CRS \
+ (_MX6Q_PAD_KEY_COL3__ENET_CRS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL \
+ (_MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__KPP_COL_3 \
+ (_MX6Q_PAD_KEY_COL3__KPP_COL_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__I2C2_SCL \
+ (_MX6Q_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__GPIO_4_12 \
+ (_MX6Q_PAD_KEY_COL3__GPIO_4_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__SPDIF_IN1 \
+ (_MX6Q_PAD_KEY_COL3__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL3__PL301_MX6QPER1_HADDR_5 \
+ (_MX6Q_PAD_KEY_COL3__PL301_MX6QPER1_HADDR_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT \
+ (_MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK \
+ (_MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA \
+ (_MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__KPP_ROW_3 \
+ (_MX6Q_PAD_KEY_ROW3__KPP_ROW_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__I2C2_SDA \
+ (_MX6Q_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__GPIO_4_13 \
+ (_MX6Q_PAD_KEY_ROW3__GPIO_4_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT \
+ (_MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW3__PL301_MX6QPER1_HADDR_6 \
+ (_MX6Q_PAD_KEY_ROW3__PL301_MX6QPER1_HADDR_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_COL4__CAN2_TXCAN \
+ (_MX6Q_PAD_KEY_COL4__CAN2_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__IPU1_SISG_4 \
+ (_MX6Q_PAD_KEY_COL4__IPU1_SISG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC \
+ (_MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__KPP_COL_4 \
+ (_MX6Q_PAD_KEY_COL4__KPP_COL_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__UART5_CTS \
+ (_MX6Q_PAD_KEY_COL4__UART5_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__UART5_RTS \
+ (_MX6Q_PAD_KEY_COL4__UART5_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__GPIO_4_14 \
+ (_MX6Q_PAD_KEY_COL4__GPIO_4_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__MMDC_MMDC_DEBUG_49 \
+ (_MX6Q_PAD_KEY_COL4__MMDC_MMDC_DEBUG_49 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_COL4__PL301_MX6QPER1_HADDR_7 \
+ (_MX6Q_PAD_KEY_COL4__PL301_MX6QPER1_HADDR_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_KEY_ROW4__CAN2_RXCAN \
+ (_MX6Q_PAD_KEY_ROW4__CAN2_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__IPU1_SISG_5 \
+ (_MX6Q_PAD_KEY_ROW4__IPU1_SISG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR \
+ (_MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__KPP_ROW_4 \
+ (_MX6Q_PAD_KEY_ROW4__KPP_ROW_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__UART5_CTS \
+ (_MX6Q_PAD_KEY_ROW4__UART5_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__GPIO_4_15 \
+ (_MX6Q_PAD_KEY_ROW4__GPIO_4_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__MMDC_MMDC_DEBUG_50 \
+ (_MX6Q_PAD_KEY_ROW4__MMDC_MMDC_DEBUG_50 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_KEY_ROW4__PL301_MX6QPER1_HADDR_8 \
+ (_MX6Q_PAD_KEY_ROW4__PL301_MX6QPER1_HADDR_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_0__CCM_CLKO \
+ (_MX6Q_PAD_GPIO_0__CCM_CLKO | MUX_PAD_CTRL(MX6Q_CCM_CLK0_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__KPP_COL_5 \
+ (_MX6Q_PAD_GPIO_0__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK \
+ (_MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__EPIT1_EPITO \
+ (_MX6Q_PAD_GPIO_0__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__GPIO_1_0 \
+ (_MX6Q_PAD_GPIO_0__GPIO_1_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR \
+ (_MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_0__SNVS_HP_WRAPPER_SNVS_VIO_5 \
+ (_MX6Q_PAD_GPIO_0__SNVS_HP_WRAPPER_SNVS_VIO_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_1__ESAI1_SCKR \
+ (_MX6Q_PAD_GPIO_1__ESAI1_SCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__WDOG2_WDOG_B \
+ (_MX6Q_PAD_GPIO_1__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__KPP_ROW_5 \
+ (_MX6Q_PAD_GPIO_1__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__PWM2_PWMO \
+ (_MX6Q_PAD_GPIO_1__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__GPIO_1_1 \
+ (_MX6Q_PAD_GPIO_1__GPIO_1_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__USDHC1_CD \
+ (_MX6Q_PAD_GPIO_1__USDHC1_CD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_1__SRC_TESTER_ACK \
+ (_MX6Q_PAD_GPIO_1__SRC_TESTER_ACK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_9__ESAI1_FSR \
+ (_MX6Q_PAD_GPIO_9__ESAI1_FSR | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_GPIO_9__WDOG1_WDOG_B \
+ (_MX6Q_PAD_GPIO_9__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_9__KPP_COL_6 \
+ (_MX6Q_PAD_GPIO_9__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_9__CCM_REF_EN_B \
+ (_MX6Q_PAD_GPIO_9__CCM_REF_EN_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_9__PWM1_PWMO \
+ (_MX6Q_PAD_GPIO_9__PWM1_PWMO | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_GPIO_9__GPIO_1_9 \
+ (_MX6Q_PAD_GPIO_9__GPIO_1_9 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_GPIO_9__USDHC1_WP \
+ (_MX6Q_PAD_GPIO_9__USDHC1_WP | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_9__SRC_EARLY_RST \
+ (_MX6Q_PAD_GPIO_9__SRC_EARLY_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_3__ESAI1_HCKR \
+ (_MX6Q_PAD_GPIO_3__ESAI1_HCKR | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 \
+ (_MX6Q_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__I2C3_SCL \
+ (_MX6Q_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__ANATOP_ANATOP_24M_OUT \
+ (_MX6Q_PAD_GPIO_3__ANATOP_ANATOP_24M_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__CCM_CLKO2 \
+ (_MX6Q_PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__GPIO_1_3 \
+ (_MX6Q_PAD_GPIO_3__GPIO_1_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC \
+ (_MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_3__MLB_MLBCLK \
+ (_MX6Q_PAD_GPIO_3__MLB_MLBCLK | MUX_PAD_CTRL(MX6Q_MLB150_PAD_CTRL))
+
+#ifdef CONFIG_MX6_ENET_IRQ_TO_GPIO
+#define MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ (_MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(ENET_IRQ_PAD_CTRL))
+#else
+#define MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ (_MX6Q_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__ESAI1_SCKT \
+ (_MX6Q_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__GPIO_1_6 \
+ (_MX6Q_PAD_GPIO_6__GPIO_1_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__I2C3_SDA \
+ (_MX6Q_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 \
+ (_MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB \
+ (_MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__USDHC2_LCTL \
+ (_MX6Q_PAD_GPIO_6__USDHC2_LCTL | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_6__MLB_MLBSIG \
+ (_MX6Q_PAD_GPIO_6__MLB_MLBSIG | MUX_PAD_CTRL(MX6Q_MLB150_PAD_CTRL))
+#endif
+
+#define MX6Q_PAD_GPIO_2__ESAI1_FST \
+ (_MX6Q_PAD_GPIO_2__ESAI1_FST | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 \
+ (_MX6Q_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__KPP_ROW_6 \
+ (_MX6Q_PAD_GPIO_2__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1 \
+ (_MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 \
+ (_MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__GPIO_1_2 \
+ (_MX6Q_PAD_GPIO_2__GPIO_1_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__USDHC2_WP \
+ (_MX6Q_PAD_GPIO_2__USDHC2_WP | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_2__MLB_MLBDAT \
+ (_MX6Q_PAD_GPIO_2__MLB_MLBDAT | MUX_PAD_CTRL(MX6Q_MLB150_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_4__ESAI1_HCKT \
+ (_MX6Q_PAD_GPIO_4__ESAI1_HCKT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 \
+ (_MX6Q_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__KPP_COL_7 \
+ (_MX6Q_PAD_GPIO_4__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2 \
+ (_MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 \
+ (_MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__GPIO_1_4 \
+ (_MX6Q_PAD_GPIO_4__GPIO_1_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__USDHC2_CD \
+ (_MX6Q_PAD_GPIO_4__USDHC2_CD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_4__OCOTP_CTRL_WRAPPER_FUSE_LATCHED \
+ (_MX6Q_PAD_GPIO_4__OCOTP_CTRL_WRAPPER_FUSE_LATCHED | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3 \
+ (_MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 \
+ (_MX6Q_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__KPP_ROW_7 \
+ (_MX6Q_PAD_GPIO_5__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__CCM_CLKO \
+ (_MX6Q_PAD_GPIO_5__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 \
+ (_MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__GPIO_1_5 \
+ (_MX6Q_PAD_GPIO_5__GPIO_1_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__I2C3_SCL \
+ (_MX6Q_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_GPIO_5__CHEETAH_EVENTI \
+ (_MX6Q_PAD_GPIO_5__CHEETAH_EVENTI | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1 \
+ (_MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__ECSPI5_RDY \
+ (_MX6Q_PAD_GPIO_7__ECSPI5_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__EPIT1_EPITO \
+ (_MX6Q_PAD_GPIO_7__EPIT1_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__CAN1_TXCAN \
+ (_MX6Q_PAD_GPIO_7__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__UART2_TXD \
+ (_MX6Q_PAD_GPIO_7__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__UART2_RXD \
+ (_MX6Q_PAD_GPIO_7__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__GPIO_1_7 \
+ (_MX6Q_PAD_GPIO_7__GPIO_1_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__SPDIF_PLOCK \
+ (_MX6Q_PAD_GPIO_7__SPDIF_PLOCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HOST_MODE \
+ (_MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HOST_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0 \
+ (_MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT \
+ (_MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__EPIT2_EPITO \
+ (_MX6Q_PAD_GPIO_8__EPIT2_EPITO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__CAN1_RXCAN \
+ (_MX6Q_PAD_GPIO_8__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__UART2_TXD \
+ (_MX6Q_PAD_GPIO_8__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__UART2_RXD \
+ (_MX6Q_PAD_GPIO_8__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__GPIO_1_8 \
+ (_MX6Q_PAD_GPIO_8__GPIO_1_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__SPDIF_SRCLK \
+ (_MX6Q_PAD_GPIO_8__SPDIF_SRCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_8__USBOH3_OTGUSB_PWRCTL_WAKEUP \
+ (_MX6Q_PAD_GPIO_8__USBOH3_OTGUSB_PWRCTL_WAKEUP | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2 \
+ (_MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN \
+ (_MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
+ (_MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT | \
+ MUX_PAD_CTRL(MX6Q_GPIO_16_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__USDHC1_LCTL \
+ (_MX6Q_PAD_GPIO_16__USDHC1_LCTL | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__SPDIF_IN1 \
+ (_MX6Q_PAD_GPIO_16__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__GPIO_7_11 \
+ (_MX6Q_PAD_GPIO_16__GPIO_7_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__I2C3_SDA \
+ (_MX6Q_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_GPIO_16__SJC_DE_B \
+ (_MX6Q_PAD_GPIO_16__SJC_DE_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_17__ESAI1_TX0 \
+ (_MX6Q_PAD_GPIO_17__ESAI1_TX0 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN \
+ (_MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__CCM_PMIC_RDY \
+ (_MX6Q_PAD_GPIO_17__CCM_PMIC_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 \
+ (_MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__SPDIF_OUT1 \
+ (_MX6Q_PAD_GPIO_17__SPDIF_OUT1 | MUX_PAD_CTRL(MX6Q_SPDIF_OUT_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__GPIO_7_12 \
+ (_MX6Q_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_17__SJC_JTAG_ACT \
+ (_MX6Q_PAD_GPIO_17__SJC_JTAG_ACT | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_18__ESAI1_TX1 \
+ (_MX6Q_PAD_GPIO_18__ESAI1_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__ENET_RX_CLK \
+ (_MX6Q_PAD_GPIO_18__ENET_RX_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__USDHC3_VSELECT \
+ (_MX6Q_PAD_GPIO_18__USDHC3_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 \
+ (_MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK \
+ (_MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__GPIO_7_13 \
+ (_MX6Q_PAD_GPIO_18__GPIO_7_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__SNVS_HP_WRAPPER_SNVS_VIO_5_CTL \
+ (_MX6Q_PAD_GPIO_18__SNVS_HP_WRAPPER_SNVS_VIO_5_CTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST \
+ (_MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_GPIO_19__KPP_COL_5 \
+ (_MX6Q_PAD_GPIO_19__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT \
+ (_MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__SPDIF_OUT1 \
+ (_MX6Q_PAD_GPIO_19__SPDIF_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__CCM_CLKO \
+ (_MX6Q_PAD_GPIO_19__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__ECSPI1_RDY \
+ (_MX6Q_PAD_GPIO_19__ECSPI1_RDY | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__GPIO_4_5 \
+ (_MX6Q_PAD_GPIO_19__GPIO_4_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__ENET_TX_ER \
+ (_MX6Q_PAD_GPIO_19__ENET_TX_ER | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_GPIO_19__SRC_INT_BOOT \
+ (_MX6Q_PAD_GPIO_19__SRC_INT_BOOT | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK \
+ (_MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_12 \
+ (_MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 \
+ (_MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18 \
+ (_MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_PIXCLK__MMDC_MMDC_DEBUG_29 \
+ (_MX6Q_PAD_CSI0_PIXCLK__MMDC_MMDC_DEBUG_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO \
+ (_MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC \
+ (_MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_13 \
+ (_MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__CCM_CLKO \
+ (_MX6Q_PAD_CSI0_MCLK__CCM_CLKO | MUX_PAD_CTRL(MX6Q_CCM_CLK0_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 \
+ (_MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__GPIO_5_19 \
+ (_MX6Q_PAD_CSI0_MCLK__GPIO_5_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 \
+ (_MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL \
+ (_MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN \
+ (_MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 \
+ (_MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_DIAG_STATUS_BUS_MUX_14 \
+ (_MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_DIAG_STATUS_BUS_MUX_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 \
+ (_MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20 \
+ (_MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__MMDC_MMDC_DEBUG_31 \
+ (_MX6Q_PAD_CSI0_DATA_EN__MMDC_MMDC_DEBUG_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK \
+ (_MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC \
+ (_MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 \
+ (_MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_DIAG_STATUS_BUS_MUX_15 \
+ (_MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_DIAG_STATUS_BUS_MUX_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 \
+ (_MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__GPIO_5_21 \
+ (_MX6Q_PAD_CSI0_VSYNC__GPIO_5_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__MMDC_MMDC_DEBUG_32 \
+ (_MX6Q_PAD_CSI0_VSYNC__MMDC_MMDC_DEBUG_32 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0 \
+ (_MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4 \
+ (_MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2 \
+ (_MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK \
+ (_MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__KPP_COL_5 \
+ (_MX6Q_PAD_CSI0_DAT4__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC \
+ (_MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__GPIO_5_22 \
+ (_MX6Q_PAD_CSI0_DAT4__GPIO_5_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__MMDC_MMDC_DEBUG_43 \
+ (_MX6Q_PAD_CSI0_DAT4__MMDC_MMDC_DEBUG_43 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1 \
+ (_MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5 \
+ (_MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3 \
+ (_MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI \
+ (_MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__KPP_ROW_5 \
+ (_MX6Q_PAD_CSI0_DAT5__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD \
+ (_MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD | \
+ MUX_PAD_CTRL(MX6Q_ADU_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__GPIO_5_23 \
+ (_MX6Q_PAD_CSI0_DAT5__GPIO_5_23 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 \
+ (_MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2 \
+ (_MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6 \
+ (_MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4 \
+ (_MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO \
+ (_MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__KPP_COL_6 \
+ (_MX6Q_PAD_CSI0_DAT6__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS \
+ (_MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__GPIO_5_24 \
+ (_MX6Q_PAD_CSI0_DAT6__GPIO_5_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 \
+ (_MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3 \
+ (_MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7 \
+ (_MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5 \
+ (_MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 \
+ (_MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__KPP_ROW_6 \
+ (_MX6Q_PAD_CSI0_DAT7__KPP_ROW_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD \
+ (_MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD | \
+ MUX_PAD_CTRL(MX6Q_ADU_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__GPIO_5_25 \
+ (_MX6Q_PAD_CSI0_DAT7__GPIO_5_25 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 \
+ (_MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4 \
+ (_MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8 \
+ (_MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6 \
+ (_MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK \
+ (_MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__KPP_COL_7 \
+ (_MX6Q_PAD_CSI0_DAT8__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__I2C1_SDA \
+ (_MX6Q_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__GPIO_5_26 \
+ (_MX6Q_PAD_CSI0_DAT8__GPIO_5_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 \
+ (_MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5 \
+ (_MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9 \
+ (_MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7 \
+ (_MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI \
+ (_MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__KPP_ROW_7 \
+ (_MX6Q_PAD_CSI0_DAT9__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__I2C1_SCL \
+ (_MX6Q_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(MX6Q_I2C_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__GPIO_5_27 \
+ (_MX6Q_PAD_CSI0_DAT9__GPIO_5_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 \
+ (_MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6 \
+ (_MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10 \
+ (_MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC \
+ (_MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO \
+ (_MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__UART1_TXD \
+ (_MX6Q_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__UART1_RXD \
+ (_MX6Q_PAD_CSI0_DAT10__UART1_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 \
+ (_MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__GPIO_5_28 \
+ (_MX6Q_PAD_CSI0_DAT10__GPIO_5_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 \
+ (_MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7 \
+ (_MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11 \
+ (_MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS \
+ (_MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 \
+ (_MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__UART1_TXD \
+ (_MX6Q_PAD_CSI0_DAT11__UART1_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__UART1_RXD \
+ (_MX6Q_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 \
+ (_MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__GPIO_5_29 \
+ (_MX6Q_PAD_CSI0_DAT11__GPIO_5_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 \
+ (_MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8 \
+ (_MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12 \
+ (_MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8 \
+ (_MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_DIAG_STATUS_BUS_MUX_16 \
+ (_MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_DIAG_STATUS_BUS_MUX_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__UART4_TXD \
+ (_MX6Q_PAD_CSI0_DAT12__UART4_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__UART4_RXD \
+ (_MX6Q_PAD_CSI0_DAT12__UART4_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 \
+ (_MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__GPIO_5_30 \
+ (_MX6Q_PAD_CSI0_DAT12__GPIO_5_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 \
+ (_MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9 \
+ (_MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13 \
+ (_MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9 \
+ (_MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_DIAG_STATUS_BUS_MUX_17 \
+ (_MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_DIAG_STATUS_BUS_MUX_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__UART4_TXD \
+ (_MX6Q_PAD_CSI0_DAT13__UART4_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__UART4_RXD \
+ (_MX6Q_PAD_CSI0_DAT13__UART4_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 \
+ (_MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__GPIO_5_31 \
+ (_MX6Q_PAD_CSI0_DAT13__GPIO_5_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 \
+ (_MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10 \
+ (_MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14 \
+ (_MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10 \
+ (_MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_DIAG_STATUS_BUS_MUX_18 \
+ (_MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_DIAG_STATUS_BUS_MUX_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__UART5_TXD \
+ (_MX6Q_PAD_CSI0_DAT14__UART5_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__UART5_RXD \
+ (_MX6Q_PAD_CSI0_DAT14__UART5_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 \
+ (_MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__GPIO_6_0 \
+ (_MX6Q_PAD_CSI0_DAT14__GPIO_6_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 \
+ (_MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11 \
+ (_MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15 \
+ (_MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11 \
+ (_MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_DIAG_STATUS_BUS_MUX_19 \
+ (_MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_DIAG_STATUS_BUS_MUX_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__UART5_TXD \
+ (_MX6Q_PAD_CSI0_DAT15__UART5_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__UART5_RXD \
+ (_MX6Q_PAD_CSI0_DAT15__UART5_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 \
+ (_MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__GPIO_6_1 \
+ (_MX6Q_PAD_CSI0_DAT15__GPIO_6_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 \
+ (_MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12 \
+ (_MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16 \
+ (_MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12 \
+ (_MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_DIAG_STATUS_BUS_MUX_20 \
+ (_MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_DIAG_STATUS_BUS_MUX_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__UART4_CTS \
+ (_MX6Q_PAD_CSI0_DAT16__UART4_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__UART4_RTS \
+ (_MX6Q_PAD_CSI0_DAT16__UART4_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 \
+ (_MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__GPIO_6_2 \
+ (_MX6Q_PAD_CSI0_DAT16__GPIO_6_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 \
+ (_MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13 \
+ (_MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17 \
+ (_MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13 \
+ (_MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_DIAG_STATUS_BUS_MUX_21 \
+ (_MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_DIAG_STATUS_BUS_MUX_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__UART4_CTS \
+ (_MX6Q_PAD_CSI0_DAT17__UART4_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 \
+ (_MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__GPIO_6_3 \
+ (_MX6Q_PAD_CSI0_DAT17__GPIO_6_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 \
+ (_MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14 \
+ (_MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18 \
+ (_MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14 \
+ (_MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_DIAG_STATUS_BUS_MUX_22 \
+ (_MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_DIAG_STATUS_BUS_MUX_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__UART5_CTS \
+ (_MX6Q_PAD_CSI0_DAT18__UART5_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__UART5_RTS \
+ (_MX6Q_PAD_CSI0_DAT18__UART5_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 \
+ (_MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__GPIO_6_4 \
+ (_MX6Q_PAD_CSI0_DAT18__GPIO_6_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 \
+ (_MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15 \
+ (_MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19 \
+ (_MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15 \
+ (_MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_DIAG_STATUS_BUS_MUX_23 \
+ (_MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_DIAG_STATUS_BUS_MUX_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__UART5_CTS \
+ (_MX6Q_PAD_CSI0_DAT19__UART5_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 \
+ (_MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__GPIO_6_5 \
+ (_MX6Q_PAD_CSI0_DAT19__GPIO_6_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 \
+ (_MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_CSI0_DAT19__ANATOP_ANATOP_TESTO_9 \
+ (_MX6Q_PAD_CSI0_DAT19__ANATOP_ANATOP_TESTO_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_TMS__SJC_TMS \
+ (_MX6Q_PAD_JTAG_TMS__SJC_TMS | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_MOD__SJC_MOD \
+ (_MX6Q_PAD_JTAG_MOD__SJC_MOD | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB \
+ (_MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_TDI__SJC_TDI \
+ (_MX6Q_PAD_JTAG_TDI__SJC_TDI | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_TCK__SJC_TCK \
+ (_MX6Q_PAD_JTAG_TCK__SJC_TCK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_JTAG_TDO__SJC_TDO \
+ (_MX6Q_PAD_JTAG_TDO__SJC_TDO | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 \
+ (_MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 \
+ (_MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK \
+ (_MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 \
+ (_MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 \
+ (_MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 \
+ (_MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK \
+ (_MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 \
+ (_MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 \
+ (_MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 \
+ (_MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_TAMPER__SNVS_LP_WRAPPER_SNVS_TD1 \
+ (_MX6Q_PAD_TAMPER__SNVS_LP_WRAPPER_SNVS_TD1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM \
+ (_MX6Q_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ \
+ (_MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_POR_B__SRC_POR_B \
+ (_MX6Q_PAD_POR_B__SRC_POR_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 \
+ (_MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_RESET_IN_B__SRC_RESET_B \
+ (_MX6Q_PAD_RESET_IN_B__SRC_RESET_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 \
+ (_MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_TEST_MODE__TCU_TEST_MODE \
+ (_MX6Q_PAD_TEST_MODE__TCU_TEST_MODE | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ \
+ (_MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_100MHZ \
+ (_MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_200MHZ \
+ (_MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT7__UART1_TXD \
+ (_MX6Q_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__UART1_RXD \
+ (_MX6Q_PAD_SD3_DAT7__UART1_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__PCIE_CTRL_DIAG_STATUS_BUS_MUX_24 \
+ (_MX6Q_PAD_SD3_DAT7__PCIE_CTRL_DIAG_STATUS_BUS_MUX_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 \
+ (_MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 \
+ (_MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__GPIO_6_17 \
+ (_MX6Q_PAD_SD3_DAT7__GPIO_6_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_TEST_IN_12 \
+ (_MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_TEST_IN_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT7__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV \
+ (_MX6Q_PAD_SD3_DAT7__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ \
+ (_MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_100MHZ \
+ (_MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_200MHZ \
+ (_MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT6__UART1_TXD \
+ (_MX6Q_PAD_SD3_DAT6__UART1_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__UART1_RXD \
+ (_MX6Q_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__PCIE_CTRL_DIAG_STATUS_BUS_MUX_25 \
+ (_MX6Q_PAD_SD3_DAT6__PCIE_CTRL_DIAG_STATUS_BUS_MUX_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 \
+ (_MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 \
+ (_MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__GPIO_6_18 \
+ (_MX6Q_PAD_SD3_DAT6__GPIO_6_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_TEST_IN_13 \
+ (_MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_TEST_IN_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT6__ANATOP_ANATOP_TESTO_10 \
+ (_MX6Q_PAD_SD3_DAT6__ANATOP_ANATOP_TESTO_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ \
+ (_MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_100MHZ \
+ (_MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_200MHZ \
+ (_MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT5__UART2_TXD \
+ (_MX6Q_PAD_SD3_DAT5__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__UART2_RXD \
+ (_MX6Q_PAD_SD3_DAT5__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__PCIE_CTRL_DIAG_STATUS_BUS_MUX_26 \
+ (_MX6Q_PAD_SD3_DAT5__PCIE_CTRL_DIAG_STATUS_BUS_MUX_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 \
+ (_MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 \
+ (_MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__GPIO_7_0 \
+ (_MX6Q_PAD_SD3_DAT5__GPIO_7_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_TEST_IN_14 \
+ (_MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_TEST_IN_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT5__ANATOP_ANATOP_TESTO_11 \
+ (_MX6Q_PAD_SD3_DAT5__ANATOP_ANATOP_TESTO_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ \
+ (_MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_100MHZ \
+ (_MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_200MHZ \
+ (_MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT4__UART2_TXD \
+ (_MX6Q_PAD_SD3_DAT4__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__UART2_RXD \
+ (_MX6Q_PAD_SD3_DAT4__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__PCIE_CTRL_DIAG_STATUS_BUS_MUX_27 \
+ (_MX6Q_PAD_SD3_DAT4__PCIE_CTRL_DIAG_STATUS_BUS_MUX_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 \
+ (_MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 \
+ (_MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__GPIO_7_1 \
+ (_MX6Q_PAD_SD3_DAT4__GPIO_7_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_TEST_IN_15 \
+ (_MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_TEST_IN_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT4__ANATOP_ANATOP_TESTO_12 \
+ (_MX6Q_PAD_SD3_DAT4__ANATOP_ANATOP_TESTO_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ \
+ (_MX6Q_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__USDHC3_CMD_100MHZ \
+ (_MX6Q_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_CMD__USDHC3_CMD_200MHZ \
+ (_MX6Q_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_CMD__UART2_CTS \
+ (_MX6Q_PAD_SD3_CMD__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__CAN1_TXCAN \
+ (_MX6Q_PAD_SD3_CMD__CAN1_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 \
+ (_MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 \
+ (_MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__GPIO_7_2 \
+ (_MX6Q_PAD_SD3_CMD__GPIO_7_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_TEST_IN_16 \
+ (_MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_TEST_IN_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CMD__ANATOP_ANATOP_TESTO_13 \
+ (_MX6Q_PAD_SD3_CMD__ANATOP_ANATOP_TESTO_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ \
+ (_MX6Q_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__USDHC3_CLK_100MHZ \
+ (_MX6Q_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_CLK__USDHC3_CLK_200MHZ \
+ (_MX6Q_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_CLK__UART2_CTS \
+ (_MX6Q_PAD_SD3_CLK__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__UART2_RTS \
+ (_MX6Q_PAD_SD3_CLK__UART2_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__CAN1_RXCAN \
+ (_MX6Q_PAD_SD3_CLK__CAN1_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 \
+ (_MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 \
+ (_MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__GPIO_7_3 \
+ (_MX6Q_PAD_SD3_CLK__GPIO_7_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_TEST_IN_17 \
+ (_MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_TEST_IN_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_CLK__ANATOP_ANATOP_TESTO_14 \
+ (_MX6Q_PAD_SD3_CLK__ANATOP_ANATOP_TESTO_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ \
+ (_MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_100MHZ \
+ (_MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_200MHZ \
+ (_MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT0__UART1_CTS \
+ (_MX6Q_PAD_SD3_DAT0__UART1_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__CAN2_TXCAN \
+ (_MX6Q_PAD_SD3_DAT0__CAN2_TXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 \
+ (_MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 \
+ (_MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__GPIO_7_4 \
+ (_MX6Q_PAD_SD3_DAT0__GPIO_7_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_TEST_IN_18 \
+ (_MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_TEST_IN_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT0__ANATOP_ANATOP_TESTO_15 \
+ (_MX6Q_PAD_SD3_DAT0__ANATOP_ANATOP_TESTO_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ \
+ (_MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_100MHZ \
+ (_MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_200MHZ \
+ (_MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT1__UART1_CTS \
+ (_MX6Q_PAD_SD3_DAT1__UART1_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__UART1_RTS \
+ (_MX6Q_PAD_SD3_DAT1__UART1_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__CAN2_RXCAN \
+ (_MX6Q_PAD_SD3_DAT1__CAN2_RXCAN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 \
+ (_MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 \
+ (_MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__GPIO_7_5 \
+ (_MX6Q_PAD_SD3_DAT1__GPIO_7_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_TEST_IN_19 \
+ (_MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_TEST_IN_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT1__ANATOP_ANATOP_TESTI_0 \
+ (_MX6Q_PAD_SD3_DAT1__ANATOP_ANATOP_TESTI_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ \
+ (_MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_100MHZ \
+ (_MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_200MHZ \
+ (_MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT2__PCIE_CTRL_DIAG_STATUS_BUS_MUX_28 \
+ (_MX6Q_PAD_SD3_DAT2__PCIE_CTRL_DIAG_STATUS_BUS_MUX_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 \
+ (_MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 \
+ (_MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__GPIO_7_6 \
+ (_MX6Q_PAD_SD3_DAT2__GPIO_7_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_TEST_IN_20 \
+ (_MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_TEST_IN_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT2__ANATOP_ANATOP_TESTI_1 \
+ (_MX6Q_PAD_SD3_DAT2__ANATOP_ANATOP_TESTI_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ \
+ (_MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_100MHZ \
+ (_MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_200MHZ \
+ (_MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD3_DAT3__UART3_CTS \
+ (_MX6Q_PAD_SD3_DAT3__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_29 \
+ (_MX6Q_PAD_SD3_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 \
+ (_MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 \
+ (_MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__GPIO_7_7 \
+ (_MX6Q_PAD_SD3_DAT3__GPIO_7_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_TEST_IN_21 \
+ (_MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_TEST_IN_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_DAT3__ANATOP_ANATOP_TESTI_2 \
+ (_MX6Q_PAD_SD3_DAT3__ANATOP_ANATOP_TESTI_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD3_RST__USDHC3_RST \
+ (_MX6Q_PAD_SD3_RST__USDHC3_RST | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__UART3_CTS \
+ (_MX6Q_PAD_SD3_RST__UART3_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__UART3_RTS \
+ (_MX6Q_PAD_SD3_RST__UART3_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__PCIE_CTRL_DIAG_STATUS_BUS_MUX_30 \
+ (_MX6Q_PAD_SD3_RST__PCIE_CTRL_DIAG_STATUS_BUS_MUX_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 \
+ (_MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 \
+ (_MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__GPIO_7_8 \
+ (_MX6Q_PAD_SD3_RST__GPIO_7_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_TEST_IN_22 \
+ (_MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_TEST_IN_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 \
+ (_MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_CLE__RAWNAND_CLE \
+ (_MX6Q_PAD_NANDF_CLE__RAWNAND_CLE | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_CLE__IPU2_SISG_4 \
+ (_MX6Q_PAD_NANDF_CLE__IPU2_SISG_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_31 \
+ (_MX6Q_PAD_NANDF_CLE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OUT_11 \
+ (_MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OUT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OUT_11 \
+ (_MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OUT_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__GPIO_6_7 \
+ (_MX6Q_PAD_NANDF_CLE__GPIO_6_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_TEST_IN_23 \
+ (_MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_TEST_IN_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0 \
+ (_MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_ALE__RAWNAND_ALE \
+ (_MX6Q_PAD_NANDF_ALE__RAWNAND_ALE | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_ALE__USDHC4_RST \
+ (_MX6Q_PAD_NANDF_ALE__USDHC4_RST | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_0 \
+ (_MX6Q_PAD_NANDF_ALE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OUT_12 \
+ (_MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OUT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OUT_12 \
+ (_MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OUT_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__GPIO_6_8 \
+ (_MX6Q_PAD_NANDF_ALE__GPIO_6_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__MIPI_CORE_DPHY_TEST_IN_24 \
+ (_MX6Q_PAD_NANDF_ALE__MIPI_CORE_DPHY_TEST_IN_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1 \
+ (_MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN \
+ (_MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5 \
+ (_MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__PCIE_CTRL_DIAG_STATUS_BUS_MUX_1 \
+ (_MX6Q_PAD_NANDF_WP_B__PCIE_CTRL_DIAG_STATUS_BUS_MUX_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFD_OUT_13 \
+ (_MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFD_OUT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFD_OUT_13 \
+ (_MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFD_OUT_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__GPIO_6_9 \
+ (_MX6Q_PAD_NANDF_WP_B__GPIO_6_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__MIPI_CORE_DPHY_TEST_OUT_32 \
+ (_MX6Q_PAD_NANDF_WP_B__MIPI_CORE_DPHY_TEST_OUT_32 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_WP_B__PL301_MX6QPER1_HSIZE_0 \
+ (_MX6Q_PAD_NANDF_WP_B__PL301_MX6QPER1_HSIZE_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 \
+ (_MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL0))
+#define MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1 \
+ (_MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_2 \
+ (_MX6Q_PAD_NANDF_RB0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OUT_14 \
+ (_MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OUT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OUT_14 \
+ (_MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OUT_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__GPIO_6_10 \
+ (_MX6Q_PAD_NANDF_RB0__GPIO_6_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__MIPI_CORE_DPHY_TEST_OUT_33 \
+ (_MX6Q_PAD_NANDF_RB0__MIPI_CORE_DPHY_TEST_OUT_33 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_RB0__PL301_MX6QPER1_HSIZE_1 \
+ (_MX6Q_PAD_NANDF_RB0__PL301_MX6QPER1_HSIZE_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N \
+ (_MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OUT_15 \
+ (_MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OUT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OUT_15 \
+ (_MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OUT_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS0__GPIO_6_11 \
+ (_MX6Q_PAD_NANDF_CS0__GPIO_6_11 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS0__PL301_MX6QPER1_HSIZE_2 \
+ (_MX6Q_PAD_NANDF_CS0__PL301_MX6QPER1_HSIZE_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N \
+ (_MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT \
+ (_MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT \
+ (_MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_3 \
+ (_MX6Q_PAD_NANDF_CS1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS1__GPIO_6_14 \
+ (_MX6Q_PAD_NANDF_CS1__GPIO_6_14 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS1__PL301_MX6QPER1_HREADYOUT \
+ (_MX6Q_PAD_NANDF_CS1__PL301_MX6QPER1_HREADYOUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N \
+ (_MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_CS2__IPU1_SISG_0 \
+ (_MX6Q_PAD_NANDF_CS2__IPU1_SISG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS2__ESAI1_TX0 \
+ (_MX6Q_PAD_NANDF_CS2__ESAI1_TX0 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE \
+ (_MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS2__CCM_CLKO2 \
+ (_MX6Q_PAD_NANDF_CS2__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS2__GPIO_6_15 \
+ (_MX6Q_PAD_NANDF_CS2__GPIO_6_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS2__IPU2_SISG_0 \
+ (_MX6Q_PAD_NANDF_CS2__IPU2_SISG_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N \
+ (_MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_CS3__IPU1_SISG_1 \
+ (_MX6Q_PAD_NANDF_CS3__IPU1_SISG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__ESAI1_TX1 \
+ (_MX6Q_PAD_NANDF_CS3__ESAI1_TX1 | MUX_PAD_CTRL(MX6Q_ESAI_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26 \
+ (_MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_4 \
+ (_MX6Q_PAD_NANDF_CS3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__GPIO_6_16 \
+ (_MX6Q_PAD_NANDF_CS3__GPIO_6_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__IPU2_SISG_1 \
+ (_MX6Q_PAD_NANDF_CS3__IPU2_SISG_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_CS3__TPSMP_CLK \
+ (_MX6Q_PAD_NANDF_CS3__TPSMP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ \
+ (_MX6Q_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_CMD__USDHC4_CMD_100MHZ \
+ (_MX6Q_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_CMD__USDHC4_CMD_200MHZ \
+ (_MX6Q_PAD_SD4_CMD__USDHC4_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_CMD__RAWNAND_RDN \
+ (_MX6Q_PAD_SD4_CMD__RAWNAND_RDN | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_SD4_CMD__UART3_TXD \
+ (_MX6Q_PAD_SD4_CMD__UART3_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_CMD__UART3_RXD \
+ (_MX6Q_PAD_SD4_CMD__UART3_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_5 \
+ (_MX6Q_PAD_SD4_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_CMD__GPIO_7_9 \
+ (_MX6Q_PAD_SD4_CMD__GPIO_7_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR \
+ (_MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ \
+ (_MX6Q_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_CLK__USDHC4_CLK_100MHZ \
+ (_MX6Q_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_CLK__USDHC4_CLK_200MHZ \
+ (_MX6Q_PAD_SD4_CLK__USDHC4_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_CLK__RAWNAND_WRN \
+ (_MX6Q_PAD_SD4_CLK__RAWNAND_WRN | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_SD4_CLK__UART3_TXD \
+ (_MX6Q_PAD_SD4_CLK__UART3_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_CLK__UART3_RXD \
+ (_MX6Q_PAD_SD4_CLK__UART3_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_6 \
+ (_MX6Q_PAD_SD4_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_CLK__GPIO_7_10 \
+ (_MX6Q_PAD_SD4_CLK__GPIO_7_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D0__RAWNAND_D0 \
+ (_MX6Q_PAD_NANDF_D0__RAWNAND_D0 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D0__USDHC1_DAT4 \
+ (_MX6Q_PAD_NANDF_D0__USDHC1_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__GPU3D_GPU_DEBUG_OUT_0 \
+ (_MX6Q_PAD_NANDF_D0__GPU3D_GPU_DEBUG_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT_16 \
+ (_MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT_16 \
+ (_MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT_16 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__GPIO_2_0 \
+ (_MX6Q_PAD_NANDF_D0__GPIO_2_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 \
+ (_MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0 \
+ (_MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D1__RAWNAND_D1 \
+ (_MX6Q_PAD_NANDF_D1__RAWNAND_D1 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D1__USDHC1_DAT5 \
+ (_MX6Q_PAD_NANDF_D1__USDHC1_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT_1 \
+ (_MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT_17 \
+ (_MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT_17 \
+ (_MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT_17 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__GPIO_2_1 \
+ (_MX6Q_PAD_NANDF_D1__GPIO_2_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 \
+ (_MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1 \
+ (_MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D2__RAWNAND_D2 \
+ (_MX6Q_PAD_NANDF_D2__RAWNAND_D2 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D2__USDHC1_DAT6 \
+ (_MX6Q_PAD_NANDF_D2__USDHC1_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__GPU3D_GPU_DEBUG_OUT_2 \
+ (_MX6Q_PAD_NANDF_D2__GPU3D_GPU_DEBUG_OUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT_18 \
+ (_MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT_18 \
+ (_MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__GPIO_2_2 \
+ (_MX6Q_PAD_NANDF_D2__GPIO_2_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 \
+ (_MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2 \
+ (_MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D3__RAWNAND_D3 \
+ (_MX6Q_PAD_NANDF_D3__RAWNAND_D3 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D3__USDHC1_DAT7 \
+ (_MX6Q_PAD_NANDF_D3__USDHC1_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__GPU3D_GPU_DEBUG_OUT_3 \
+ (_MX6Q_PAD_NANDF_D3__GPU3D_GPU_DEBUG_OUT_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT_19 \
+ (_MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT_19 \
+ (_MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__GPIO_2_3 \
+ (_MX6Q_PAD_NANDF_D3__GPIO_2_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 \
+ (_MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3 \
+ (_MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D4__RAWNAND_D4 \
+ (_MX6Q_PAD_NANDF_D4__RAWNAND_D4 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D4__USDHC2_DAT4 \
+ (_MX6Q_PAD_NANDF_D4__USDHC2_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__GPU3D_GPU_DEBUG_OUT_4 \
+ (_MX6Q_PAD_NANDF_D4__GPU3D_GPU_DEBUG_OUT_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT_20 \
+ (_MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT_20 \
+ (_MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__GPIO_2_4 \
+ (_MX6Q_PAD_NANDF_D4__GPIO_2_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 \
+ (_MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4 \
+ (_MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D5__RAWNAND_D5 \
+ (_MX6Q_PAD_NANDF_D5__RAWNAND_D5 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D5__USDHC2_DAT5 \
+ (_MX6Q_PAD_NANDF_D5__USDHC2_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__GPU3D_GPU_DEBUG_OUT_5 \
+ (_MX6Q_PAD_NANDF_D5__GPU3D_GPU_DEBUG_OUT_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT_21 \
+ (_MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT_21 \
+ (_MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__GPIO_2_5 \
+ (_MX6Q_PAD_NANDF_D5__GPIO_2_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 \
+ (_MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5 \
+ (_MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D6__RAWNAND_D6 \
+ (_MX6Q_PAD_NANDF_D6__RAWNAND_D6 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D6__USDHC2_DAT6 \
+ (_MX6Q_PAD_NANDF_D6__USDHC2_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__GPU3D_GPU_DEBUG_OUT_6 \
+ (_MX6Q_PAD_NANDF_D6__GPU3D_GPU_DEBUG_OUT_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT_22 \
+ (_MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT_22 \
+ (_MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT_22 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__GPIO_2_6 \
+ (_MX6Q_PAD_NANDF_D6__GPIO_2_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 \
+ (_MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6 \
+ (_MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_NANDF_D7__RAWNAND_D7 \
+ (_MX6Q_PAD_NANDF_D7__RAWNAND_D7 | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL2))
+#define MX6Q_PAD_NANDF_D7__USDHC2_DAT7 \
+ (_MX6Q_PAD_NANDF_D7__USDHC2_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7 \
+ (_MX6Q_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23 \
+ (_MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23 \
+ (_MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__GPIO_2_7 \
+ (_MX6Q_PAD_NANDF_D7__GPIO_2_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 \
+ (_MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7 \
+ (_MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT0__RAWNAND_D8 \
+ (_MX6Q_PAD_SD4_DAT0__RAWNAND_D8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ \
+ (_MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_100MHZ \
+ (_MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_200MHZ \
+ (_MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT0__RAWNAND_DQS \
+ (_MX6Q_PAD_SD4_DAT0__RAWNAND_DQS | MUX_PAD_CTRL(MX6Q_GPMI_PAD_CTRL1))
+#define MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT_24 \
+ (_MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT_24 \
+ (_MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT_24 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__GPIO_2_8 \
+ (_MX6Q_PAD_SD4_DAT0__GPIO_2_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 \
+ (_MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8 \
+ (_MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT1__RAWNAND_D9 \
+ (_MX6Q_PAD_SD4_DAT1__RAWNAND_D9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ \
+ (_MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_100MHZ \
+ (_MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_200MHZ \
+ (_MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT1__PWM3_PWMO \
+ (_MX6Q_PAD_SD4_DAT1__PWM3_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT_25 \
+ (_MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT_25 \
+ (_MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT_25 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__GPIO_2_9 \
+ (_MX6Q_PAD_SD4_DAT1__GPIO_2_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 \
+ (_MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9 \
+ (_MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT2__RAWNAND_D10 \
+ (_MX6Q_PAD_SD4_DAT2__RAWNAND_D10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ \
+ (_MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_100MHZ \
+ (_MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_200MHZ \
+ (_MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT2__PWM4_PWMO \
+ (_MX6Q_PAD_SD4_DAT2__PWM4_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT_26 \
+ (_MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT_26 \
+ (_MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT_26 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__GPIO_2_10 \
+ (_MX6Q_PAD_SD4_DAT2__GPIO_2_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 \
+ (_MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10 \
+ (_MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT3__RAWNAND_D11 \
+ (_MX6Q_PAD_SD4_DAT3__RAWNAND_D11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ \
+ (_MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_100MHZ \
+ (_MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_200MHZ \
+ (_MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT_27 \
+ (_MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT_27 \
+ (_MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT_27 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__GPIO_2_11 \
+ (_MX6Q_PAD_SD4_DAT3__GPIO_2_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 \
+ (_MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11 \
+ (_MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT4__RAWNAND_D12 \
+ (_MX6Q_PAD_SD4_DAT4__RAWNAND_D12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ \
+ (_MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_100MHZ \
+ (_MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_200MHZ \
+ (_MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT4__UART2_TXD \
+ (_MX6Q_PAD_SD4_DAT4__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__UART2_RXD \
+ (_MX6Q_PAD_SD4_DAT4__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT_28 \
+ (_MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT_28 \
+ (_MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT_28 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__GPIO_2_12 \
+ (_MX6Q_PAD_SD4_DAT4__GPIO_2_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 \
+ (_MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12 \
+ (_MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT5__RAWNAND_D13 \
+ (_MX6Q_PAD_SD4_DAT5__RAWNAND_D13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ \
+ (_MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_100MHZ \
+ (_MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_200MHZ \
+ (_MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT5__UART2_CTS \
+ (_MX6Q_PAD_SD4_DAT5__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__UART2_RTS \
+ (_MX6Q_PAD_SD4_DAT5__UART2_RTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT_29 \
+ (_MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT_29 \
+ (_MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT_29 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__GPIO_2_13 \
+ (_MX6Q_PAD_SD4_DAT5__GPIO_2_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 \
+ (_MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13 \
+ (_MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT6__RAWNAND_D14 \
+ (_MX6Q_PAD_SD4_DAT6__RAWNAND_D14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ \
+ (_MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_100MHZ \
+ (_MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_200MHZ \
+ (_MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT6__UART2_CTS \
+ (_MX6Q_PAD_SD4_DAT6__UART2_CTS | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT_30 \
+ (_MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT_30 \
+ (_MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT_30 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__GPIO_2_14 \
+ (_MX6Q_PAD_SD4_DAT6__GPIO_2_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 \
+ (_MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14 \
+ (_MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD4_DAT7__RAWNAND_D15 \
+ (_MX6Q_PAD_SD4_DAT7__RAWNAND_D15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ \
+ (_MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_100MHZ \
+ (_MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_100MHZ))
+#define MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_200MHZ \
+ (_MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_200MHZ))
+#define MX6Q_PAD_SD4_DAT7__UART2_TXD \
+ (_MX6Q_PAD_SD4_DAT7__UART2_TXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__UART2_RXD \
+ (_MX6Q_PAD_SD4_DAT7__UART2_RXD | MUX_PAD_CTRL(MX6Q_UART_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT_31 \
+ (_MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT_31 \
+ (_MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT_31 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__GPIO_2_15 \
+ (_MX6Q_PAD_SD4_DAT7__GPIO_2_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 \
+ (_MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15 \
+ (_MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 \
+ (_MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 \
+ (_MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__PWM3_PWMO \
+ (_MX6Q_PAD_SD1_DAT1__PWM3_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__GPT_CAPIN2 \
+ (_MX6Q_PAD_SD1_DAT1__GPT_CAPIN2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_7 \
+ (_MX6Q_PAD_SD1_DAT1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__GPIO_1_17 \
+ (_MX6Q_PAD_SD1_DAT1__GPIO_1_17 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 \
+ (_MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_8 \
+ (_MX6Q_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 \
+ (_MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_DAT0__ECSPI5_MISO \
+ (_MX6Q_PAD_SD1_DAT0__ECSPI5_MISO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__CAAM_WRAPPER_RNG_OSC_OBS \
+ (_MX6Q_PAD_SD1_DAT0__CAAM_WRAPPER_RNG_OSC_OBS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__GPT_CAPIN1 \
+ (_MX6Q_PAD_SD1_DAT0__GPT_CAPIN1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_8 \
+ (_MX6Q_PAD_SD1_DAT0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_8 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__GPIO_1_16 \
+ (_MX6Q_PAD_SD1_DAT0__GPIO_1_16 | MUX_PAD_CTRL(MX6Q_HIGH_DRV))
+#define MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 \
+ (_MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_7 \
+ (_MX6Q_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_7 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 \
+ (_MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 \
+ (_MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3 \
+ (_MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__PWM1_PWMO \
+ (_MX6Q_PAD_SD1_DAT3__PWM1_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B \
+ (_MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__GPIO_1_21 \
+ (_MX6Q_PAD_SD1_DAT3__GPIO_1_21 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB \
+ (_MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_6 \
+ (_MX6Q_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_CMD__USDHC1_CMD \
+ (_MX6Q_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_CMD__USDHC1_CMD_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_CMD__ECSPI5_MOSI \
+ (_MX6Q_PAD_SD1_CMD__ECSPI5_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CMD__PWM4_PWMO \
+ (_MX6Q_PAD_SD1_CMD__PWM4_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CMD__GPT_CMPOUT1 \
+ (_MX6Q_PAD_SD1_CMD__GPT_CMPOUT1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CMD__GPIO_1_18 \
+ (_MX6Q_PAD_SD1_CMD__GPIO_1_18 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_5 \
+ (_MX6Q_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 \
+ (_MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 \
+ (_MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2 \
+ (_MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__PWM2_PWMO \
+ (_MX6Q_PAD_SD1_DAT2__PWM2_PWMO | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B \
+ (_MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__GPIO_1_19 \
+ (_MX6Q_PAD_SD1_DAT2__GPIO_1_19 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB \
+ (_MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_4 \
+ (_MX6Q_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_4 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD1_CLK__USDHC1_CLK \
+ (_MX6Q_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__USDHC1_CLK_50MHZ_40OHM \
+ (_MX6Q_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL_50MHZ_40OHM))
+#define MX6Q_PAD_SD1_CLK__ECSPI5_SCLK \
+ (_MX6Q_PAD_SD1_CLK__ECSPI5_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT \
+ (_MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__GPT_CLKIN \
+ (_MX6Q_PAD_SD1_CLK__GPT_CLKIN | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__GPIO_1_20 \
+ (_MX6Q_PAD_SD1_CLK__GPIO_1_20 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__PHY_DTB_0 \
+ (_MX6Q_PAD_SD1_CLK__PHY_DTB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0 \
+ (_MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD2_CLK__USDHC2_CLK \
+ (_MX6Q_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__ECSPI5_SCLK \
+ (_MX6Q_PAD_SD2_CLK__ECSPI5_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__KPP_COL_5 \
+ (_MX6Q_PAD_SD2_CLK__KPP_COL_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS \
+ (_MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_9 \
+ (_MX6Q_PAD_SD2_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_9 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__GPIO_1_10 \
+ (_MX6Q_PAD_SD2_CLK__GPIO_1_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__PHY_DTB_1 \
+ (_MX6Q_PAD_SD2_CLK__PHY_DTB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1 \
+ (_MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD2_CMD__USDHC2_CMD \
+ (_MX6Q_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_CMD__ECSPI5_MOSI \
+ (_MX6Q_PAD_SD2_CMD__ECSPI5_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CMD__KPP_ROW_5 \
+ (_MX6Q_PAD_SD2_CMD__KPP_ROW_5 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC \
+ (_MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_10 \
+ (_MX6Q_PAD_SD2_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_10 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_CMD__GPIO_1_11 \
+ (_MX6Q_PAD_SD2_CMD__GPIO_1_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#define MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 \
+ (_MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 | MUX_PAD_CTRL(MX6Q_USDHC_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 \
+ (_MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__KPP_COL_6 \
+ (_MX6Q_PAD_SD2_DAT3__KPP_COL_6 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC \
+ (_MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_11 \
+ (_MX6Q_PAD_SD2_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_11 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__GPIO_1_12 \
+ (_MX6Q_PAD_SD2_DAT3__GPIO_1_12 | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__SJC_DONE \
+ (_MX6Q_PAD_SD2_DAT3__SJC_DONE | MUX_PAD_CTRL(NO_PAD_CTRL))
+#define MX6Q_PAD_SD2_DAT3__ANATOP_ANATOP_TESTO_3 \
+ (_MX6Q_PAD_SD2_DAT3__ANATOP_ANATOP_TESTO_3 | MUX_PAD_CTRL(NO_PAD_CTRL))
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h b/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h
new file mode 100755
index 00000000..6f90c66b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6sl.h
@@ -0,0 +1,3117 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Auto Generate file, please don't edit it
+ *
+ */
+
+#ifndef __MACH_IOMUX_MX6SL_H__
+#define __MACH_IOMUX_MX6SL_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX6SL_HIGH_DRV PAD_CTL_DSE_120ohm
+#define MX6SL_DISP_PAD_CLT MX6SL_HIGH_DRV
+
+#define MX6SL_CCM_CLKO_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6SL_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6SL_INTR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+
+#define MX6SL_USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6SL_USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_34ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6SL_USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_34ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6SL_ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6SL_I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \
+ PAD_CTL_HYS | PAD_CTL_ODE)
+
+#define MX6SL_ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6SL_USB_HSIC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6SL_HP_DET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+#define MX6SL_LCDIF_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | \
+ PAD_CTL_PUE | PAD_CTL_PKE | \
+ PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
+
+#define MX6SL_KEYPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_120ohm)
+
+#define MX6SL_TOUCH_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_22K_UP | PAD_CTL_DSE_120ohm)
+
+#define MX6SL_TSPAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP)
+#define MX6SL_ADU_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_PUS_100K_DOWN | \
+ PAD_CTL_HYS | PAD_CTL_SPEED_MED)
+#define MX6SL_CHG_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP)
+#define MX6SL_FLOAT_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm)
+
+#define MX6SL_EPDC_PAD_CTRL \
+ (PAD_CTL_HYS|PAD_CTL_PKE|PAD_CTL_SPEED_MED|PAD_CTL_DSE_40ohm)
+
+#define MX6SL_PAD_AUD_MCLK 0x02A4
+#define MX6SL_PAD_AUD_RXD 0x02AC
+#define MX6SL_PAD_AUD_TXC 0x02B4
+#define MX6SL_PAD_AUD_TXD 0x02B8
+#define MX6SL_PAD_AUD_TXFS 0x02BC
+#define MX6SL_PAD_HSIC_DAT 0x0444
+#define MX6SL_PAD_HSIC_STROBE 0x0448
+
+#define MX6SL_PAD_AUD_MCLK__AUDMUX_AUDIO_CLK_OUT \
+ IOMUX_PAD(0x02A4, 0x004C, 0, 0x0000, 0, MX6SL_ADU_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__PWM4_PWMO \
+ IOMUX_PAD(0x02A4, 0x004C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__ECSPI3_RDY \
+ IOMUX_PAD(0x02A4, 0x004C, 2, 0x06B4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__FEC_MDC \
+ IOMUX_PAD(0x02A4, 0x004C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__WDOG2_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x02A4, 0x004C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__GPIO_1_6 \
+ IOMUX_PAD(0x02A4, 0x004C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__SPDIF_SPDIF_EXT_CLK \
+ IOMUX_PAD(0x02A4, 0x004C, 6, 0x07F4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_MCLK__TPSMP_HDATA_27 \
+ IOMUX_PAD(0x02A4, 0x004C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_RXC__AUDMUX_AUD3_RXC \
+ IOMUX_PAD(0x02A8, 0x0050, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__I2C1_SDA \
+ IOMUX_PAD(0x02A8, 0x0050, 1 | IOMUX_CONFIG_SION, 0x0720, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__UART3_TXD \
+ IOMUX_PAD(0x02A8, 0x0050, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__UART3_RXD \
+ IOMUX_PAD(0x02A8, 0x0050, 2, 0x080C, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__FEC_TX_CLK \
+ IOMUX_PAD(0x02A8, 0x0050, 3, 0x070C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__I2C3_SDA \
+ IOMUX_PAD(0x02A8, 0x0050, 4 | IOMUX_CONFIG_SION, 0x0730, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__GPIO_1_1 \
+ IOMUX_PAD(0x02A8, 0x0050, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__ECSPI3_SS1 \
+ IOMUX_PAD(0x02A8, 0x0050, 6, 0x06C4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXC__PL301_SIM_MX6SL_PER1_HREADYOUT \
+ IOMUX_PAD(0x02A8, 0x0050, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_RXD__AUDMUX_AUD3_RXD \
+ IOMUX_PAD(0x02AC, 0x0054, 0, 0x0000, 0, MX6SL_ADU_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__ECSPI3_MOSI \
+ IOMUX_PAD(0x02AC, 0x0054, 1, 0x06BC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__UART4_TXD \
+ IOMUX_PAD(0x02AC, 0x0054, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__UART4_RXD \
+ IOMUX_PAD(0x02AC, 0x0054, 2, 0x0814, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__FEC_RX_ER \
+ IOMUX_PAD(0x02AC, 0x0054, 3, 0x0708, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__USDHC1_LCTL \
+ IOMUX_PAD(0x02AC, 0x0054, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__GPIO_1_2 \
+ IOMUX_PAD(0x02AC, 0x0054, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__SRC_INT_BOOT \
+ IOMUX_PAD(0x02AC, 0x0054, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXD__PL301_SIM_MX6SL_PER1_HRESP \
+ IOMUX_PAD(0x02AC, 0x0054, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_RXFS__AUDMUX_AUD3_RXFS \
+ IOMUX_PAD(0x02B0, 0x0058, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__I2C1_SCL \
+ IOMUX_PAD(0x02B0, 0x0058, 1 | IOMUX_CONFIG_SION, 0x071C, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__UART3_TXD \
+ IOMUX_PAD(0x02B0, 0x0058, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__UART3_RXD \
+ IOMUX_PAD(0x02B0, 0x0058, 2, 0x080C, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__FEC_MDIO \
+ IOMUX_PAD(0x02B0, 0x0058, 3, 0x06F4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__I2C3_SCL \
+ IOMUX_PAD(0x02B0, 0x0058, 4 | IOMUX_CONFIG_SION, 0x072C, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__GPIO_1_0 \
+ IOMUX_PAD(0x02B0, 0x0058, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__ECSPI3_SS0 \
+ IOMUX_PAD(0x02B0, 0x0058, 6, 0x06C0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_RXFS__PL301_SIM_MX6SL_PER1_HPROT_1 \
+ IOMUX_PAD(0x02B0, 0x0058, 7, 0x07EC, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_TXC__AUDMUX_AUD3_TXC \
+ IOMUX_PAD(0x02B4, 0x005C, 0, 0x0000, 0, MX6SL_ADU_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__ECSPI3_MISO \
+ IOMUX_PAD(0x02B4, 0x005C, 1, 0x06B8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__UART4_TXD \
+ IOMUX_PAD(0x02B4, 0x005C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__UART4_RXD \
+ IOMUX_PAD(0x02B4, 0x005C, 2, 0x0814, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__FEC_RX_DV \
+ IOMUX_PAD(0x02B4, 0x005C, 3, 0x0704, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__USDHC2_LCTL \
+ IOMUX_PAD(0x02B4, 0x005C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__GPIO_1_3 \
+ IOMUX_PAD(0x02B4, 0x005C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__SRC_SYSTEM_RST \
+ IOMUX_PAD(0x02B4, 0x005C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXC__TPSMP_HDATA_24 \
+ IOMUX_PAD(0x02B4, 0x005C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_TXD__AUDMUX_AUD3_TXD \
+ IOMUX_PAD(0x02B8, 0x0060, 0, 0x0000, 0, MX6SL_ADU_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__ECSPI3_SCLK \
+ IOMUX_PAD(0x02B8, 0x0060, 1, 0x06B0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__UART4_CTS \
+ IOMUX_PAD(0x02B8, 0x0060, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__UART4_RTS \
+ IOMUX_PAD(0x02B8, 0x0060, 2, 0x0810, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__FEC_TDATA_0 \
+ IOMUX_PAD(0x02B8, 0x0060, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__USDHC4_LCTL \
+ IOMUX_PAD(0x02B8, 0x0060, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__GPIO_1_5 \
+ IOMUX_PAD(0x02B8, 0x0060, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__ANATOP_ANATOP_TESTI_1 \
+ IOMUX_PAD(0x02B8, 0x0060, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXD__TPSMP_HDATA_26 \
+ IOMUX_PAD(0x02B8, 0x0060, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_AUD_TXFS__AUDMUX_AUD3_TXFS \
+ IOMUX_PAD(0x02BC, 0x0064, 0, 0x0000, 0, MX6SL_ADU_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__PWM3_PWMO \
+ IOMUX_PAD(0x02BC, 0x0064, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__UART4_CTS \
+ IOMUX_PAD(0x02BC, 0x0064, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__UART4_RTS \
+ IOMUX_PAD(0x02BC, 0x0064, 2, 0x0810, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__FEC_RDATA_1 \
+ IOMUX_PAD(0x02BC, 0x0064, 3, 0x06FC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__USDHC3_LCTL \
+ IOMUX_PAD(0x02BC, 0x0064, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__GPIO_1_4 \
+ IOMUX_PAD(0x02BC, 0x0064, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__ANATOP_ANATOP_TESTI_0 \
+ IOMUX_PAD(0x02BC, 0x0064, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_AUD_TXFS__TPSMP_HDATA_25 \
+ IOMUX_PAD(0x02BC, 0x0064, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_BOOT_MODE0__SRC_BOOT_MODE_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_BOOT_MODE1__SRC_BOOT_MODE_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A0__MMDC_DRAM_A_0 \
+ IOMUX_PAD(0x02C0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A1__MMDC_DRAM_A_1 \
+ IOMUX_PAD(0x02C4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A10__MMDC_DRAM_A_10 \
+ IOMUX_PAD(0x02C8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A11__MMDC_DRAM_A_11 \
+ IOMUX_PAD(0x02CC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A12__MMDC_DRAM_A_12 \
+ IOMUX_PAD(0x02D0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A13__MMDC_DRAM_A_13 \
+ IOMUX_PAD(0x02D4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A14__MMDC_DRAM_A_14 \
+ IOMUX_PAD(0x02D8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A15__MMDC_DRAM_A_15 \
+ IOMUX_PAD(0x02DC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A2__MMDC_DRAM_A_2 \
+ IOMUX_PAD(0x02E0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A3__MMDC_DRAM_A_3 \
+ IOMUX_PAD(0x02E4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A4__MMDC_DRAM_A_4 \
+ IOMUX_PAD(0x02E8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A5__MMDC_DRAM_A_5 \
+ IOMUX_PAD(0x02EC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A6__MMDC_DRAM_A_6 \
+ IOMUX_PAD(0x02F0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A7__MMDC_DRAM_A_7 \
+ IOMUX_PAD(0x02F4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A8__MMDC_DRAM_A_8 \
+ IOMUX_PAD(0x02F8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_A9__MMDC_DRAM_A_9 \
+ IOMUX_PAD(0x02FC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_CAS__MMDC_DRAM_CAS \
+ IOMUX_PAD(0x0300, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_CS0__MMDC_DRAM_CS_0 \
+ IOMUX_PAD(0x0304, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_CS1__MMDC_DRAM_CS_1 \
+ IOMUX_PAD(0x0308, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D0__MMDC_DRAM_D_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D1__MMDC_DRAM_D_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D10__MMDC_DRAM_D_10 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D11__MMDC_DRAM_D_11 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D12__MMDC_DRAM_D_12 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D13__MMDC_DRAM_D_13 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D14__MMDC_DRAM_D_14 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D15__MMDC_DRAM_D_15 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D16__MMDC_DRAM_D_16 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D17__MMDC_DRAM_D_17 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D18__MMDC_DRAM_D_18 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D19__MMDC_DRAM_D_19 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D2__MMDC_DRAM_D_2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D20__MMDC_DRAM_D_20 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D21__MMDC_DRAM_D_21 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D22__MMDC_DRAM_D_22 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D23__MMDC_DRAM_D_23 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D24__MMDC_DRAM_D_24 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D25__MMDC_DRAM_D_25 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D26__MMDC_DRAM_D_26 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D27__MMDC_DRAM_D_27 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D28__MMDC_DRAM_D_28 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D29__MMDC_DRAM_D_29 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D3__MMDC_DRAM_D_3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D30__MMDC_DRAM_D_30 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D31__MMDC_DRAM_D_31 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D4__MMDC_DRAM_D_4 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D5__MMDC_DRAM_D_5 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D6__MMDC_DRAM_D_6 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D7__MMDC_DRAM_D_7 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D8__MMDC_DRAM_D_8 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_D9__MMDC_DRAM_D_9 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 \
+ IOMUX_PAD(0x030C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 \
+ IOMUX_PAD(0x0310, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 \
+ IOMUX_PAD(0x0314, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 \
+ IOMUX_PAD(0x0318, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_RAS__MMDC_DRAM_RAS \
+ IOMUX_PAD(0x031C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_RESET__MMDC_DRAM_RESET \
+ IOMUX_PAD(0x0320, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 \
+ IOMUX_PAD(0x0324, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 \
+ IOMUX_PAD(0x0328, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 \
+ IOMUX_PAD(0x032C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 \
+ IOMUX_PAD(0x0330, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 \
+ IOMUX_PAD(0x0334, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 \
+ IOMUX_PAD(0x0338, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 \
+ IOMUX_PAD(0x033C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 \
+ IOMUX_PAD(0x0340, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 \
+ IOMUX_PAD(0x0344, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 \
+ IOMUX_PAD(0x0348, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 \
+ IOMUX_PAD(0x034C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 \
+ IOMUX_PAD(0x0350, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_DRAM_SDWE__MMDC_DRAM_SDWE \
+ IOMUX_PAD(0x0354, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO \
+ IOMUX_PAD(0x0358, 0x0068, 0, 0x0684, 0, MX6SL_ECSPI_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x0358, 0x0068, 1, 0x05F8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__UART5_CTS \
+ IOMUX_PAD(0x0358, 0x0068, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__UART5_RTS \
+ IOMUX_PAD(0x0358, 0x0068, 2, 0x0818, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__EPDC_BDR_0 \
+ IOMUX_PAD(0x0358, 0x0068, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__USDHC2_WP \
+ IOMUX_PAD(0x0358, 0x0068, 4, 0x0834, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__GPIO_4_10 \
+ IOMUX_PAD(0x0358, 0x0068, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__CCM_PLL3_BYP \
+ IOMUX_PAD(0x0358, 0x0068, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MISO__MMDC_MMDC_DEBUG_40 \
+ IOMUX_PAD(0x0358, 0x0068, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI \
+ IOMUX_PAD(0x035C, 0x006C, 0, 0x0688, 0, MX6SL_ECSPI_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x035C, 0x006C, 1, 0x05F4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__UART5_TXD \
+ IOMUX_PAD(0x035C, 0x006C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__UART5_RXD \
+ IOMUX_PAD(0x035C, 0x006C, 2, 0x081C, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__EPDC_VCOM_1 \
+ IOMUX_PAD(0x035C, 0x006C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__USDHC2_VSELECT \
+ IOMUX_PAD(0x035C, 0x006C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__GPIO_4_9 \
+ IOMUX_PAD(0x035C, 0x006C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__CCM_PLL2_BYP \
+ IOMUX_PAD(0x035C, 0x006C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_MOSI__MMDC_MMDC_DEBUG_49 \
+ IOMUX_PAD(0x035C, 0x006C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK \
+ IOMUX_PAD(0x0360, 0x0070, 0, 0x067C, 0, MX6SL_ECSPI_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x0360, 0x0070, 1, 0x05E8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__UART5_TXD \
+ IOMUX_PAD(0x0360, 0x0070, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__UART5_RXD \
+ IOMUX_PAD(0x0360, 0x0070, 2, 0x081C, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__EPDC_VCOM_0 \
+ IOMUX_PAD(0x0360, 0x0070, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__USDHC2_RST \
+ IOMUX_PAD(0x0360, 0x0070, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__GPIO_4_8 \
+ IOMUX_PAD(0x0360, 0x0070, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__USB_USBOTG2_OC \
+ IOMUX_PAD(0x0360, 0x0070, 6, 0x0820, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SCLK__TPSMP_HDATA_18 \
+ IOMUX_PAD(0x0360, 0x0070, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI1_SS0__ECSPI1_SS0 \
+ IOMUX_PAD(0x0364, 0x0074, 0, 0x068C, 0, MX6SL_ECSPI_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x0364, 0x0074, 1, 0x05E4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__UART5_CTS \
+ IOMUX_PAD(0x0364, 0x0074, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__UART5_RTS \
+ IOMUX_PAD(0x0364, 0x0074, 2, 0x0818, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__EPDC_BDR_1 \
+ IOMUX_PAD(0x0364, 0x0074, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__USDHC2_CD \
+ IOMUX_PAD(0x0364, 0x0074, 4, 0x0830, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__GPIO_4_11 \
+ IOMUX_PAD(0x0364, 0x0074, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__USB_USBOTG2_PWR \
+ IOMUX_PAD(0x0364, 0x0074, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI1_SS0__PL301_SIM_MX6SL_PER1_HADDR_23 \
+ IOMUX_PAD(0x0364, 0x0074, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI2_MISO__GPIO_4_14 \
+ IOMUX_PAD(0x0368, 0x0078, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__USB_USBOTG1_OC \
+ IOMUX_PAD(0x0368, 0x0078, 6, 0x0824, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__TPSMP_HDATA_23 \
+ IOMUX_PAD(0x0368, 0x0078, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__ECSPI2_MISO \
+ IOMUX_PAD(0x0368, 0x0078, 0, 0x06A0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x0368, 0x0078, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__UART3_CTS \
+ IOMUX_PAD(0x0368, 0x0078, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__UART3_RTS \
+ IOMUX_PAD(0x0368, 0x0078, 2, 0x0808, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__CSI_MCLK \
+ IOMUX_PAD(0x0368, 0x0078, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MISO__USDHC1_WP \
+ IOMUX_PAD(0x0368, 0x0078, 4, 0x082C, 0, MX6SL_USDHC_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI2_MOSI__ECSPI2_MOSI \
+ IOMUX_PAD(0x036C, 0x007C, 0, 0x06A4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x036C, 0x007C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__UART3_TXD \
+ IOMUX_PAD(0x036C, 0x007C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__UART3_RXD \
+ IOMUX_PAD(0x036C, 0x007C, 2, 0x080C, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__CSI_HSYNC \
+ IOMUX_PAD(0x036C, 0x007C, 3, 0x0670, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__USDHC1_VSELECT \
+ IOMUX_PAD(0x036C, 0x007C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__GPIO_4_13 \
+ IOMUX_PAD(0x036C, 0x007C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__ANATOP_ANATOP_TESTO_1 \
+ IOMUX_PAD(0x036C, 0x007C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_MOSI__TPSMP_HDATA_22 \
+ IOMUX_PAD(0x036C, 0x007C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI2_SCLK__ECSPI2_SCLK \
+ IOMUX_PAD(0x0370, 0x0080, 0, 0x069C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__SPDIF_SPDIF_EXT_CLK \
+ IOMUX_PAD(0x0370, 0x0080, 1, 0x07F4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__UART3_TXD \
+ IOMUX_PAD(0x0370, 0x0080, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__UART3_RXD \
+ IOMUX_PAD(0x0370, 0x0080, 2, 0x080C, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__CSI_PIXCLK \
+ IOMUX_PAD(0x0370, 0x0080, 3, 0x0674, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__USDHC1_RST \
+ IOMUX_PAD(0x0370, 0x0080, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__GPIO_4_12 \
+ IOMUX_PAD(0x0370, 0x0080, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__USB_USBOTG2_OC \
+ IOMUX_PAD(0x0370, 0x0080, 6, 0x0820, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SCLK__TPSMP_HDATA_21 \
+ IOMUX_PAD(0x0370, 0x0080, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_ECSPI2_SS0__ECSPI2_SS0 \
+ IOMUX_PAD(0x0374, 0x0084, 0, 0x06A8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__ECSPI1_SS3 \
+ IOMUX_PAD(0x0374, 0x0084, 1, 0x0698, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__UART3_CTS \
+ IOMUX_PAD(0x0374, 0x0084, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__UART3_RTS \
+ IOMUX_PAD(0x0374, 0x0084, 2, 0x0808, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__CSI_VSYNC \
+ IOMUX_PAD(0x0374, 0x0084, 3, 0x0678, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__USDHC1_CD \
+ IOMUX_PAD(0x0374, 0x0084, 4, 0x0828, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__GPIO_4_15 \
+ IOMUX_PAD(0x0374, 0x0084, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__USB_USBOTG1_PWR \
+ IOMUX_PAD(0x0374, 0x0084, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_ECSPI2_SS0__PL301_SIM_MX6SL_PER1_HADDR_24 \
+ IOMUX_PAD(0x0374, 0x0084, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_BDR0__EPDC_BDR_0 \
+ IOMUX_PAD(0x0378, 0x0088, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__USDHC4_CLK \
+ IOMUX_PAD(0x0378, 0x0088, 1, 0x0850, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__UART3_CTS \
+ IOMUX_PAD(0x0378, 0x0088, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__UART3_RTS \
+ IOMUX_PAD(0x0378, 0x0088, 2, 0x0808, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__WEIM_WEIM_A_26 \
+ IOMUX_PAD(0x0378, 0x0088, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__TCON_RL \
+ IOMUX_PAD(0x0378, 0x0088, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__GPIO_2_5 \
+ IOMUX_PAD(0x0378, 0x0088, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__EPDC_SDCE_7 \
+ IOMUX_PAD(0x0378, 0x0088, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR0__MMDC_MMDC_DEBUG_9 \
+ IOMUX_PAD(0x0378, 0x0088, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_BDR1__EPDC_BDR_1 \
+ IOMUX_PAD(0x037C, 0x008C, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__USDHC4_CMD \
+ IOMUX_PAD(0x037C, 0x008C, 1, 0x0858, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__UART3_CTS \
+ IOMUX_PAD(0x037C, 0x008C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__UART3_RTS \
+ IOMUX_PAD(0x037C, 0x008C, 2, 0x0808, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__WEIM_WEIM_CRE \
+ IOMUX_PAD(0x037C, 0x008C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__TCON_UD \
+ IOMUX_PAD(0x037C, 0x008C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__GPIO_2_6 \
+ IOMUX_PAD(0x037C, 0x008C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__EPDC_SDCE_8 \
+ IOMUX_PAD(0x037C, 0x008C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_BDR1__MMDC_MMDC_DEBUG_8 \
+ IOMUX_PAD(0x037C, 0x008C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D0__EPDC_SDDO_0 \
+ IOMUX_PAD(0x0380, 0x0090, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__ECSPI4_MOSI \
+ IOMUX_PAD(0x0380, 0x0090, 1, 0x06D8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__LCDIF_DAT_24 \
+ IOMUX_PAD(0x0380, 0x0090, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__CSI_D_0 \
+ IOMUX_PAD(0x0380, 0x0090, 3, 0x0630, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__TCON_E_DATA_0 \
+ IOMUX_PAD(0x0380, 0x0090, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__GPIO_1_7 \
+ IOMUX_PAD(0x0380, 0x0090, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__ANATOP_USBPHY1_TSTI_TX_HS_MODE \
+ IOMUX_PAD(0x0380, 0x0090, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D0__OBSERVE_MUX_OUT_0 \
+ IOMUX_PAD(0x0380, 0x0090, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D1__EPDC_SDDO_1 \
+ IOMUX_PAD(0x0384, 0x0094, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__ECSPI4_MISO \
+ IOMUX_PAD(0x0384, 0x0094, 1, 0x06D4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__LCDIF_DAT_25 \
+ IOMUX_PAD(0x0384, 0x0094, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__CSI_D_1 \
+ IOMUX_PAD(0x0384, 0x0094, 3, 0x0634, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__TCON_E_DATA_1 \
+ IOMUX_PAD(0x0384, 0x0094, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__GPIO_1_8 \
+ IOMUX_PAD(0x0384, 0x0094, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__ANATOP_USBPHY1_TSTI_TX_LS_MODE \
+ IOMUX_PAD(0x0384, 0x0094, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D1__OBSERVE_MUX_OUT_1 \
+ IOMUX_PAD(0x0384, 0x0094, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D10__EPDC_SDDO_10 \
+ IOMUX_PAD(0x0388, 0x0098, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__ECSPI3_SS0 \
+ IOMUX_PAD(0x0388, 0x0098, 1, 0x06C0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__EPDC_PWRCTRL_2 \
+ IOMUX_PAD(0x0388, 0x0098, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__WEIM_WEIM_A_18 \
+ IOMUX_PAD(0x0388, 0x0098, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__TCON_E_DATA_10 \
+ IOMUX_PAD(0x0388, 0x0098, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__GPIO_1_17 \
+ IOMUX_PAD(0x0388, 0x0098, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__USDHC4_WP \
+ IOMUX_PAD(0x0388, 0x0098, 6, 0x087C, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D10__MMDC_MMDC_DEBUG_29 \
+ IOMUX_PAD(0x0388, 0x0098, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D11__EPDC_SDDO_11 \
+ IOMUX_PAD(0x038C, 0x009C, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__ECSPI3_SCLK \
+ IOMUX_PAD(0x038C, 0x009C, 1, 0x06B0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__EPDC_PWRCTRL_3 \
+ IOMUX_PAD(0x038C, 0x009C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__WEIM_WEIM_A_19 \
+ IOMUX_PAD(0x038C, 0x009C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__TCON_E_DATA_11 \
+ IOMUX_PAD(0x038C, 0x009C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__GPIO_1_18 \
+ IOMUX_PAD(0x038C, 0x009C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__USDHC4_CD \
+ IOMUX_PAD(0x038C, 0x009C, 6, 0x0854, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D11__MMDC_MMDC_DEBUG_28 \
+ IOMUX_PAD(0x038C, 0x009C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D12__EPDC_SDDO_12 \
+ IOMUX_PAD(0x0390, 0x00A0, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__UART2_TXD \
+ IOMUX_PAD(0x0390, 0x00A0, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__UART2_RXD \
+ IOMUX_PAD(0x0390, 0x00A0, 1, 0x0804, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__EPDC_PWRCOM \
+ IOMUX_PAD(0x0390, 0x00A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__WEIM_WEIM_A_20 \
+ IOMUX_PAD(0x0390, 0x00A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__TCON_E_DATA_12 \
+ IOMUX_PAD(0x0390, 0x00A0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__GPIO_1_19 \
+ IOMUX_PAD(0x0390, 0x00A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__ECSPI3_SS1 \
+ IOMUX_PAD(0x0390, 0x00A0, 6, 0x06C4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D12__MMDC_MMDC_DEBUG_27 \
+ IOMUX_PAD(0x0390, 0x00A0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D13__EPDC_SDDO_13 \
+ IOMUX_PAD(0x0394, 0x00A4, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__UART2_TXD \
+ IOMUX_PAD(0x0394, 0x00A4, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__UART2_RXD \
+ IOMUX_PAD(0x0394, 0x00A4, 1, 0x0804, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__EPDC_PWRIRQ \
+ IOMUX_PAD(0x0394, 0x00A4, 2, 0x06E8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__WEIM_WEIM_A_21 \
+ IOMUX_PAD(0x0394, 0x00A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__TCON_E_DATA_13 \
+ IOMUX_PAD(0x0394, 0x00A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__GPIO_1_20 \
+ IOMUX_PAD(0x0394, 0x00A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__ECSPI3_SS2 \
+ IOMUX_PAD(0x0394, 0x00A4, 6, 0x06C8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D13__MMDC_MMDC_DEBUG_26 \
+ IOMUX_PAD(0x0394, 0x00A4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D14__EPDC_SDDO_14 \
+ IOMUX_PAD(0x0398, 0x00A8, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__UART2_CTS \
+ IOMUX_PAD(0x0398, 0x00A8, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__UART2_RTS \
+ IOMUX_PAD(0x0398, 0x00A8, 1, 0x0800, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__EPDC_PWRSTAT \
+ IOMUX_PAD(0x0398, 0x00A8, 2, 0x06EC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__WEIM_WEIM_A_22 \
+ IOMUX_PAD(0x0398, 0x00A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__TCON_E_DATA_14 \
+ IOMUX_PAD(0x0398, 0x00A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__GPIO_1_21 \
+ IOMUX_PAD(0x0398, 0x00A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__ECSPI3_SS3 \
+ IOMUX_PAD(0x0398, 0x00A8, 6, 0x06CC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D14__MMDC_MMDC_DEBUG_25 \
+ IOMUX_PAD(0x0398, 0x00A8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D15__EPDC_SDDO_15 \
+ IOMUX_PAD(0x039C, 0x00AC, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__UART2_CTS \
+ IOMUX_PAD(0x039C, 0x00AC, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__UART2_RTS \
+ IOMUX_PAD(0x039C, 0x00AC, 1, 0x0800, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__EPDC_PWRWAKE \
+ IOMUX_PAD(0x039C, 0x00AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__WEIM_WEIM_A_23 \
+ IOMUX_PAD(0x039C, 0x00AC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__TCON_E_DATA_15 \
+ IOMUX_PAD(0x039C, 0x00AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__GPIO_1_22 \
+ IOMUX_PAD(0x039C, 0x00AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__ECSPI3_RDY \
+ IOMUX_PAD(0x039C, 0x00AC, 6, 0x06B4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D15__MMDC_MMDC_DEBUG_24 \
+ IOMUX_PAD(0x039C, 0x00AC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D2__EPDC_SDDO_2 \
+ IOMUX_PAD(0x03A0, 0x00B0, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__ECSPI4_SS0 \
+ IOMUX_PAD(0x03A0, 0x00B0, 1, 0x06DC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__LCDIF_DAT_26 \
+ IOMUX_PAD(0x03A0, 0x00B0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__CSI_D_2 \
+ IOMUX_PAD(0x03A0, 0x00B0, 3, 0x0638, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__TCON_E_DATA_2 \
+ IOMUX_PAD(0x03A0, 0x00B0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__GPIO_1_9 \
+ IOMUX_PAD(0x03A0, 0x00B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__ANATOP_USBPHY1_TSTI_TX_DN \
+ IOMUX_PAD(0x03A0, 0x00B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D2__TPSMP_HDATA_28 \
+ IOMUX_PAD(0x03A0, 0x00B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D3__EPDC_SDDO_3 \
+ IOMUX_PAD(0x03A4, 0x00B4, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__ECSPI4_SCLK \
+ IOMUX_PAD(0x03A4, 0x00B4, 1, 0x06D0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__LCDIF_DAT_27 \
+ IOMUX_PAD(0x03A4, 0x00B4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__CSI_D_3 \
+ IOMUX_PAD(0x03A4, 0x00B4, 3, 0x063C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__TCON_E_DATA_3 \
+ IOMUX_PAD(0x03A4, 0x00B4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__GPIO_1_10 \
+ IOMUX_PAD(0x03A4, 0x00B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__ANATOP_USBPHY1_TSTI_TX_DP \
+ IOMUX_PAD(0x03A4, 0x00B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D3__TPSMP_HDATA_29 \
+ IOMUX_PAD(0x03A4, 0x00B4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D4__EPDC_SDDO_4 \
+ IOMUX_PAD(0x03A8, 0x00B8, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__ECSPI4_SS1 \
+ IOMUX_PAD(0x03A8, 0x00B8, 1, 0x06E0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__LCDIF_DAT_28 \
+ IOMUX_PAD(0x03A8, 0x00B8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__CSI_D_4 \
+ IOMUX_PAD(0x03A8, 0x00B8, 3, 0x0640, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__TCON_E_DATA_4 \
+ IOMUX_PAD(0x03A8, 0x00B8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__GPIO_1_11 \
+ IOMUX_PAD(0x03A8, 0x00B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__ANATOP_USBPHY1_TSTI_TX_EN \
+ IOMUX_PAD(0x03A8, 0x00B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D4__TPSMP_HDATA_30 \
+ IOMUX_PAD(0x03A8, 0x00B8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D5__EPDC_SDDO_5 \
+ IOMUX_PAD(0x03AC, 0x00BC, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__ECSPI4_SS2 \
+ IOMUX_PAD(0x03AC, 0x00BC, 1, 0x06E4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__LCDIF_DAT_29 \
+ IOMUX_PAD(0x03AC, 0x00BC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__CSI_D_5 \
+ IOMUX_PAD(0x03AC, 0x00BC, 3, 0x0644, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__TCON_E_DATA_5 \
+ IOMUX_PAD(0x03AC, 0x00BC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__GPIO_1_12 \
+ IOMUX_PAD(0x03AC, 0x00BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__ANATOP_USBPHY1_TSTI_TX_HIZ \
+ IOMUX_PAD(0x03AC, 0x00BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D5__TPSMP_HDATA_31 \
+ IOMUX_PAD(0x03AC, 0x00BC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D6__EPDC_SDDO_6 \
+ IOMUX_PAD(0x03B0, 0x00C0, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__ECSPI4_SS3 \
+ IOMUX_PAD(0x03B0, 0x00C0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__LCDIF_DAT_30 \
+ IOMUX_PAD(0x03B0, 0x00C0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__CSI_D_6 \
+ IOMUX_PAD(0x03B0, 0x00C0, 3, 0x0648, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__TCON_E_DATA_6 \
+ IOMUX_PAD(0x03B0, 0x00C0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__GPIO_1_13 \
+ IOMUX_PAD(0x03B0, 0x00C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__ANATOP_USBPHY2_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x03B0, 0x00C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D6__TPSMP_HDATA_20 \
+ IOMUX_PAD(0x03B0, 0x00C0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D7__EPDC_SDDO_7 \
+ IOMUX_PAD(0x03B4, 0x00C4, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__ECSPI4_RDY \
+ IOMUX_PAD(0x03B4, 0x00C4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__LCDIF_DAT_31 \
+ IOMUX_PAD(0x03B4, 0x00C4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__CSI_D_7 \
+ IOMUX_PAD(0x03B4, 0x00C4, 3, 0x064C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__TCON_E_DATA_7 \
+ IOMUX_PAD(0x03B4, 0x00C4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__GPIO_1_14 \
+ IOMUX_PAD(0x03B4, 0x00C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__ANATOP_USBPHY2_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x03B4, 0x00C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D7__MMDC_MMDC_DEBUG_32 \
+ IOMUX_PAD(0x03B4, 0x00C4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D8__EPDC_SDDO_8 \
+ IOMUX_PAD(0x03B8, 0x00C8, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__ECSPI3_MOSI \
+ IOMUX_PAD(0x03B8, 0x00C8, 1, 0x06BC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__EPDC_PWRCTRL_0 \
+ IOMUX_PAD(0x03B8, 0x00C8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__WEIM_WEIM_A_16 \
+ IOMUX_PAD(0x03B8, 0x00C8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__TCON_E_DATA_8 \
+ IOMUX_PAD(0x03B8, 0x00C8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__GPIO_1_15 \
+ IOMUX_PAD(0x03B8, 0x00C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__USDHC4_RST \
+ IOMUX_PAD(0x03B8, 0x00C8, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D8__MMDC_MMDC_DEBUG_31 \
+ IOMUX_PAD(0x03B8, 0x00C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_D9__EPDC_SDDO_9 \
+ IOMUX_PAD(0x03BC, 0x00CC, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__ECSPI3_MISO \
+ IOMUX_PAD(0x03BC, 0x00CC, 1, 0x06B8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__EPDC_PWRCTRL_1 \
+ IOMUX_PAD(0x03BC, 0x00CC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__WEIM_WEIM_A_17 \
+ IOMUX_PAD(0x03BC, 0x00CC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__TCON_E_DATA_9 \
+ IOMUX_PAD(0x03BC, 0x00CC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__GPIO_1_16 \
+ IOMUX_PAD(0x03BC, 0x00CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__USDHC4_VSELECT \
+ IOMUX_PAD(0x03BC, 0x00CC, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_D9__MMDC_MMDC_DEBUG_30 \
+ IOMUX_PAD(0x03BC, 0x00CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_GDCLK__EPDC_GDCLK \
+ IOMUX_PAD(0x03C0, 0x00D0, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__ECSPI2_SS2 \
+ IOMUX_PAD(0x03C0, 0x00D0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__TCON_YCKR \
+ IOMUX_PAD(0x03C0, 0x00D0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__CSI_PIXCLK \
+ IOMUX_PAD(0x03C0, 0x00D0, 3, 0x0674, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__TCON_YCKL \
+ IOMUX_PAD(0x03C0, 0x00D0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__GPIO_1_31 \
+ IOMUX_PAD(0x03C0, 0x00D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__USDHC2_RST \
+ IOMUX_PAD(0x03C0, 0x00D0, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDCLK__MMDC_MMDC_DEBUG_15 \
+ IOMUX_PAD(0x03C0, 0x00D0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_GDOE__EPDC_GDOE \
+ IOMUX_PAD(0x03C4, 0x00D4, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__ECSPI2_SS3 \
+ IOMUX_PAD(0x03C4, 0x00D4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__TCON_YOER \
+ IOMUX_PAD(0x03C4, 0x00D4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__CSI_HSYNC \
+ IOMUX_PAD(0x03C4, 0x00D4, 3, 0x0670, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__TCON_YOEL \
+ IOMUX_PAD(0x03C4, 0x00D4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__GPIO_2_0 \
+ IOMUX_PAD(0x03C4, 0x00D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__USDHC2_VSELECT \
+ IOMUX_PAD(0x03C4, 0x00D4, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDOE__MMDC_MMDC_DEBUG_14 \
+ IOMUX_PAD(0x03C4, 0x00D4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_GDRL__EPDC_GDRL \
+ IOMUX_PAD(0x03C8, 0x00D8, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__ECSPI2_RDY \
+ IOMUX_PAD(0x03C8, 0x00D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__TCON_YDIOUR \
+ IOMUX_PAD(0x03C8, 0x00D8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__CSI_MCLK \
+ IOMUX_PAD(0x03C8, 0x00D8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__TCON_YDIOUL \
+ IOMUX_PAD(0x03C8, 0x00D8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__GPIO_2_1 \
+ IOMUX_PAD(0x03C8, 0x00D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__USDHC2_WP \
+ IOMUX_PAD(0x03C8, 0x00D8, 6, 0x0834, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDRL__MMDC_MMDC_DEBUG_13 \
+ IOMUX_PAD(0x03C8, 0x00D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_GDSP__EPDC_GDSP \
+ IOMUX_PAD(0x03CC, 0x00DC, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__PWM4_PWMO \
+ IOMUX_PAD(0x03CC, 0x00DC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__TCON_YDIODR \
+ IOMUX_PAD(0x03CC, 0x00DC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__CSI_VSYNC \
+ IOMUX_PAD(0x03CC, 0x00DC, 3, 0x0678, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__TCON_YDIODL \
+ IOMUX_PAD(0x03CC, 0x00DC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__GPIO_2_2 \
+ IOMUX_PAD(0x03CC, 0x00DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__USDHC2_CD \
+ IOMUX_PAD(0x03CC, 0x00DC, 6, 0x0830, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_GDSP__MMDC_MMDC_DEBUG_12 \
+ IOMUX_PAD(0x03CC, 0x00DC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRCOM__EPDC_PWRCOM \
+ IOMUX_PAD(0x03D0, 0x00E0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__USDHC4_DAT0 \
+ IOMUX_PAD(0x03D0, 0x00E0, 1, 0x085C, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__LCDIF_DAT_20 \
+ IOMUX_PAD(0x03D0, 0x00E0, 2, 0x07C8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__WEIM_WEIM_BCLK \
+ IOMUX_PAD(0x03D0, 0x00E0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__ANATOP_USBOTG1_ID \
+ IOMUX_PAD(0x03D0, 0x00E0, 4, 0x05DC, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__GPIO_2_11 \
+ IOMUX_PAD(0x03D0, 0x00E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__USDHC3_RST \
+ IOMUX_PAD(0x03D0, 0x00E0, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCOM__MMDC_MMDC_DEBUG_3 \
+ IOMUX_PAD(0x03D0, 0x00E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRCTRL0__EPDC_PWRCTRL_0 \
+ IOMUX_PAD(0x03D4, 0x00E4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x03D4, 0x00E4, 1, 0x0604, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__LCDIF_DAT_16 \
+ IOMUX_PAD(0x03D4, 0x00E4, 2, 0x07B8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__WEIM_WEIM_RW \
+ IOMUX_PAD(0x03D4, 0x00E4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__TCON_YCKL \
+ IOMUX_PAD(0x03D4, 0x00E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__GPIO_2_7 \
+ IOMUX_PAD(0x03D4, 0x00E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__USDHC4_RST \
+ IOMUX_PAD(0x03D4, 0x00E4, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL0__MMDC_MMDC_DEBUG_7 \
+ IOMUX_PAD(0x03D4, 0x00E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRCTRL1__EPDC_PWRCTRL_1 \
+ IOMUX_PAD(0x03D8, 0x00E8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x03D8, 0x00E8, 1, 0x0610, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__LCDIF_DAT_17 \
+ IOMUX_PAD(0x03D8, 0x00E8, 2, 0x07BC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__WEIM_WEIM_OE \
+ IOMUX_PAD(0x03D8, 0x00E8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__TCON_YOEL \
+ IOMUX_PAD(0x03D8, 0x00E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__GPIO_2_8 \
+ IOMUX_PAD(0x03D8, 0x00E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__USDHC4_VSELECT \
+ IOMUX_PAD(0x03D8, 0x00E8, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL1__MMDC_MMDC_DEBUG_6 \
+ IOMUX_PAD(0x03D8, 0x00E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRCTRL2__EPDC_PWRCTRL_2 \
+ IOMUX_PAD(0x03DC, 0x00EC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x03DC, 0x00EC, 1, 0x0600, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__LCDIF_DAT_18 \
+ IOMUX_PAD(0x03DC, 0x00EC, 2, 0x07C0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__WEIM_WEIM_CS_0 \
+ IOMUX_PAD(0x03DC, 0x00EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__TCON_YDIOUL \
+ IOMUX_PAD(0x03DC, 0x00EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9 \
+ IOMUX_PAD(0x03DC, 0x00EC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__GPIO_2_9_PUINT \
+ IOMUX_PAD(0x03DC, 0x00EC, 5, 0x0000, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX6SL_PAD_EPDC_PWRCTRL2__USDHC4_WP \
+ IOMUX_PAD(0x03DC, 0x00EC, 6, 0x087C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL2__MMDC_MMDC_DEBUG_5 \
+ IOMUX_PAD(0x03DC, 0x00EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRCTRL3__EPDC_PWRCTRL_3 \
+ IOMUX_PAD(0x03E0, 0x00F0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x03E0, 0x00F0, 1, 0x060C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__LCDIF_DAT_19 \
+ IOMUX_PAD(0x03E0, 0x00F0, 2, 0x07C4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__WEIM_WEIM_CS_1 \
+ IOMUX_PAD(0x03E0, 0x00F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__TCON_YDIODL \
+ IOMUX_PAD(0x03E0, 0x00F0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__GPIO_2_10 \
+ IOMUX_PAD(0x03E0, 0x00F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__USDHC4_CD \
+ IOMUX_PAD(0x03E0, 0x00F0, 6, 0x0854, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRCTRL3__MMDC_MMDC_DEBUG_4 \
+ IOMUX_PAD(0x03E0, 0x00F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRINT__EPDC_PWRIRQ \
+ IOMUX_PAD(0x03E4, 0x00F4, 0, 0x06E8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__USDHC4_DAT1 \
+ IOMUX_PAD(0x03E4, 0x00F4, 1, 0x0860, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__LCDIF_DAT_21 \
+ IOMUX_PAD(0x03E4, 0x00F4, 2, 0x07CC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x03E4, 0x00F4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__ANATOP_USBOTG2_ID \
+ IOMUX_PAD(0x03E4, 0x00F4, 4, 0x05E0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__GPIO_2_12 \
+ IOMUX_PAD(0x03E4, 0x00F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__USDHC3_VSELECT \
+ IOMUX_PAD(0x03E4, 0x00F4, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRINT__MMDC_MMDC_DEBUG_2 \
+ IOMUX_PAD(0x03E4, 0x00F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRSTAT__EPDC_PWRSTAT \
+ IOMUX_PAD(0x03E8, 0x00F8, 0, 0x06EC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__USDHC4_DAT2 \
+ IOMUX_PAD(0x03E8, 0x00F8, 1, 0x0864, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__LCDIF_DAT_22 \
+ IOMUX_PAD(0x03E8, 0x00F8, 2, 0x07D0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__WEIM_WEIM_WAIT \
+ IOMUX_PAD(0x03E8, 0x00F8, 3, 0x0884, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__KITTEN_EVENTI \
+ IOMUX_PAD(0x03E8, 0x00F8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13 \
+ IOMUX_PAD(0x03E8, 0x00F8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__GPIO_2_13_PUINT \
+ IOMUX_PAD(0x03E8, 0x00F8, 5, 0x0000, 0, PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX6SL_PAD_EPDC_PWRSTAT__USDHC3_WP \
+ IOMUX_PAD(0x03E8, 0x00F8, 6, 0x084C, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRSTAT__MMDC_MMDC_DEBUG_1 \
+ IOMUX_PAD(0x03E8, 0x00F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_PWRWAKEUP__EPDC_PWRWAKE \
+ IOMUX_PAD(0x03EC, 0x00FC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__USDHC4_DAT3 \
+ IOMUX_PAD(0x03EC, 0x00FC, 1, 0x0868, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__LCDIF_DAT_23 \
+ IOMUX_PAD(0x03EC, 0x00FC, 2, 0x07D4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__WEIM_WEIM_DTACK_B \
+ IOMUX_PAD(0x03EC, 0x00FC, 3, 0x0880, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__KITTEN_EVENTO \
+ IOMUX_PAD(0x03EC, 0x00FC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__GPIO_2_14 \
+ IOMUX_PAD(0x03EC, 0x00FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__USDHC3_CD \
+ IOMUX_PAD(0x03EC, 0x00FC, 6, 0x0838, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_PWRWAKEUP__MMDC_MMDC_DEBUG_0 \
+ IOMUX_PAD(0x03EC, 0x00FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDCE0__EPDC_SDCE_0 \
+ IOMUX_PAD(0x03F0, 0x0100, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__ECSPI2_SS1 \
+ IOMUX_PAD(0x03F0, 0x0100, 1, 0x06AC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__PWM3_PWMO \
+ IOMUX_PAD(0x03F0, 0x0100, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x03F0, 0x0100, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__TCON_YCKR \
+ IOMUX_PAD(0x03F0, 0x0100, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__GPIO_1_27 \
+ IOMUX_PAD(0x03F0, 0x0100, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x03F0, 0x0100, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE0__MMDC_MMDC_DEBUG_19 \
+ IOMUX_PAD(0x03F0, 0x0100, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDCE1__EPDC_SDCE_1 \
+ IOMUX_PAD(0x03F4, 0x0104, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__WDOG2_WDOG_B \
+ IOMUX_PAD(0x03F4, 0x0104, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__PWM4_PWMO \
+ IOMUX_PAD(0x03F4, 0x0104, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__WEIM_WEIM_LBA \
+ IOMUX_PAD(0x03F4, 0x0104, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__TCON_YOER \
+ IOMUX_PAD(0x03F4, 0x0104, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__GPIO_1_28 \
+ IOMUX_PAD(0x03F4, 0x0104, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__ANATOP_USBPHY1_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x03F4, 0x0104, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE1__MMDC_MMDC_DEBUG_18 \
+ IOMUX_PAD(0x03F4, 0x0104, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDCE2__EPDC_SDCE_2 \
+ IOMUX_PAD(0x03F8, 0x0108, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__I2C3_SCL \
+ IOMUX_PAD(0x03F8, 0x0108, 1 | IOMUX_CONFIG_SION, 0x072C, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__PWM1_PWMO \
+ IOMUX_PAD(0x03F8, 0x0108, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__WEIM_WEIM_EB_0 \
+ IOMUX_PAD(0x03F8, 0x0108, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__TCON_YDIOUR \
+ IOMUX_PAD(0x03F8, 0x0108, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__GPIO_1_29 \
+ IOMUX_PAD(0x03F8, 0x0108, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__ANATOP_USBPHY1_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x03F8, 0x0108, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE2__MMDC_MMDC_DEBUG_17 \
+ IOMUX_PAD(0x03F8, 0x0108, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDCE3__EPDC_SDCE_3 \
+ IOMUX_PAD(0x03FC, 0x010C, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__I2C3_SDA \
+ IOMUX_PAD(0x03FC, 0x010C, 1 | IOMUX_CONFIG_SION, 0x0730, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__PWM2_PWMO \
+ IOMUX_PAD(0x03FC, 0x010C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__WEIM_WEIM_EB_1 \
+ IOMUX_PAD(0x03FC, 0x010C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__TCON_YDIODR \
+ IOMUX_PAD(0x03FC, 0x010C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__GPIO_1_30 \
+ IOMUX_PAD(0x03FC, 0x010C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__ANATOP_USBPHY1_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x03FC, 0x010C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCE3__MMDC_MMDC_DEBUG_16 \
+ IOMUX_PAD(0x03FC, 0x010C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDCLK__EPDC_SDCLK \
+ IOMUX_PAD(0x0400, 0x0110, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__ECSPI2_MOSI \
+ IOMUX_PAD(0x0400, 0x0110, 1, 0x06A4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__I2C2_SCL \
+ IOMUX_PAD(0x0400, 0x0110, 2 | IOMUX_CONFIG_SION, 0x0724, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__CSI_D_8 \
+ IOMUX_PAD(0x0400, 0x0110, 3, 0x0650, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__TCON_CL \
+ IOMUX_PAD(0x0400, 0x0110, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__GPIO_1_23 \
+ IOMUX_PAD(0x0400, 0x0110, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__ANATOP_USBPHY2_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x0400, 0x0110, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDCLK__MMDC_MMDC_DEBUG_23 \
+ IOMUX_PAD(0x0400, 0x0110, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDLE__EPDC_SDLE \
+ IOMUX_PAD(0x0404, 0x0114, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__ECSPI2_MISO \
+ IOMUX_PAD(0x0404, 0x0114, 1, 0x06A0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__I2C2_SDA \
+ IOMUX_PAD(0x0404, 0x0114, 2 | IOMUX_CONFIG_SION, 0x0728, 0, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__CSI_D_9 \
+ IOMUX_PAD(0x0404, 0x0114, 3, 0x0654, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__TCON_LD \
+ IOMUX_PAD(0x0404, 0x0114, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__GPIO_1_24 \
+ IOMUX_PAD(0x0404, 0x0114, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__ANATOP_USBPHY2_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x0404, 0x0114, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDLE__MMDC_MMDC_DEBUG_22 \
+ IOMUX_PAD(0x0404, 0x0114, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDOE__EPDC_SDOE \
+ IOMUX_PAD(0x0408, 0x0118, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__ECSPI2_SS0 \
+ IOMUX_PAD(0x0408, 0x0118, 1, 0x06A8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__TCON_XDIOR \
+ IOMUX_PAD(0x0408, 0x0118, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__CSI_D_10 \
+ IOMUX_PAD(0x0408, 0x0118, 3, 0x0658, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__TCON_XDIOL \
+ IOMUX_PAD(0x0408, 0x0118, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__GPIO_1_25 \
+ IOMUX_PAD(0x0408, 0x0118, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x0408, 0x0118, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDOE__MMDC_MMDC_DEBUG_21 \
+ IOMUX_PAD(0x0408, 0x0118, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_SDSHR__EPDC_SDSHR \
+ IOMUX_PAD(0x040C, 0x011C, 0, 0x0000, 0, MX6SL_EPDC_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__ECSPI2_SCLK \
+ IOMUX_PAD(0x040C, 0x011C, 1, 0x069C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__EPDC_SDCE_4 \
+ IOMUX_PAD(0x040C, 0x011C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__CSI_D_11 \
+ IOMUX_PAD(0x040C, 0x011C, 3, 0x065C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__TCON_XDIOR \
+ IOMUX_PAD(0x040C, 0x011C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__GPIO_1_26 \
+ IOMUX_PAD(0x040C, 0x011C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__ANATOP_USBPHY1_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x040C, 0x011C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_SDSHR__MMDC_MMDC_DEBUG_20 \
+ IOMUX_PAD(0x040C, 0x011C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_VCOM0__EPDC_VCOM_0 \
+ IOMUX_PAD(0x0410, 0x0120, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x0410, 0x0120, 1, 0x0608, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__UART3_TXD \
+ IOMUX_PAD(0x0410, 0x0120, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__UART3_RXD \
+ IOMUX_PAD(0x0410, 0x0120, 2, 0x080C, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__WEIM_WEIM_A_24 \
+ IOMUX_PAD(0x0410, 0x0120, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__TCON_VCOM_0 \
+ IOMUX_PAD(0x0410, 0x0120, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__GPIO_2_3 \
+ IOMUX_PAD(0x0410, 0x0120, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__EPDC_SDCE_5 \
+ IOMUX_PAD(0x0410, 0x0120, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM0__MMDC_MMDC_DEBUG_11 \
+ IOMUX_PAD(0x0410, 0x0120, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_EPDC_VCOM1__EPDC_VCOM_1 \
+ IOMUX_PAD(0x0414, 0x0124, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x0414, 0x0124, 1, 0x05FC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__UART3_TXD \
+ IOMUX_PAD(0x0414, 0x0124, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__UART3_RXD \
+ IOMUX_PAD(0x0414, 0x0124, 2, 0x080C, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__WEIM_WEIM_A_25 \
+ IOMUX_PAD(0x0414, 0x0124, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__TCON_VCOM_1 \
+ IOMUX_PAD(0x0414, 0x0124, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__GPIO_2_4 \
+ IOMUX_PAD(0x0414, 0x0124, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__EPDC_SDCE_6 \
+ IOMUX_PAD(0x0414, 0x0124, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_EPDC_VCOM1__MMDC_MMDC_DEBUG_10 \
+ IOMUX_PAD(0x0414, 0x0124, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_CRS_DV__FEC_RX_DV \
+ IOMUX_PAD(0x0418, 0x0128, 0, 0x0704, 1, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__USDHC4_DAT1 \
+ IOMUX_PAD(0x0418, 0x0128, 1, 0x0860, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__AUDMUX_AUD6_TXC \
+ IOMUX_PAD(0x0418, 0x0128, 2, 0x0624, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__ECSPI4_MISO \
+ IOMUX_PAD(0x0418, 0x0128, 3, 0x06D4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__GPT_CMPOUT2 \
+ IOMUX_PAD(0x0418, 0x0128, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__GPIO_4_25 \
+ IOMUX_PAD(0x0418, 0x0128, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__KITTEN_TRACE_31 \
+ IOMUX_PAD(0x0418, 0x0128, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_CRS_DV__PL301_SIM_MX6SL_PER1_HADDR_3 \
+ IOMUX_PAD(0x0418, 0x0128, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_MDC__FEC_MDC \
+ IOMUX_PAD(0x041C, 0x012C, 0, 0x0000, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__USDHC4_DAT4 \
+ IOMUX_PAD(0x041C, 0x012C, 1, 0x086C, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__AUDMUX_AUDIO_CLK_OUT \
+ IOMUX_PAD(0x041C, 0x012C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__USDHC1_RST \
+ IOMUX_PAD(0x041C, 0x012C, 3, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__USDHC3_RST \
+ IOMUX_PAD(0x041C, 0x012C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__GPIO_4_23 \
+ IOMUX_PAD(0x041C, 0x012C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__KITTEN_TRACE_29 \
+ IOMUX_PAD(0x041C, 0x012C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDC__PL301_SIM_MX6SL_PER1_HADDR_8 \
+ IOMUX_PAD(0x041C, 0x012C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_MDIO__FEC_MDIO \
+ IOMUX_PAD(0x0420, 0x0130, 0, 0x06F4, 1, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__USDHC4_CLK \
+ IOMUX_PAD(0x0420, 0x0130, 1, 0x0850, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__AUDMUX_AUD6_RXFS \
+ IOMUX_PAD(0x0420, 0x0130, 2, 0x0620, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__ECSPI4_SS0 \
+ IOMUX_PAD(0x0420, 0x0130, 3, 0x06DC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__GPT_CAPIN1 \
+ IOMUX_PAD(0x0420, 0x0130, 4, 0x0710, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__GPIO_4_20 \
+ IOMUX_PAD(0x0420, 0x0130, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__KITTEN_TRACE_26 \
+ IOMUX_PAD(0x0420, 0x0130, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_MDIO__PL301_SIM_MX6SL_PER1_HADDR_15 \
+ IOMUX_PAD(0x0420, 0x0130, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_REF_CLK__FEC_REF_OUT \
+ IOMUX_PAD(0x0424, 0x0134, 0x10, 0x0000, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__USDHC4_RST \
+ IOMUX_PAD(0x0424, 0x0134, 1, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__WDOG1_WDOG_B \
+ IOMUX_PAD(0x0424, 0x0134, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__PWM4_PWMO \
+ IOMUX_PAD(0x0424, 0x0134, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0424, 0x0134, 4, 0x062C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__GPIO_4_26 \
+ IOMUX_PAD(0x0424, 0x0134, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__GPIO_4_26_PULLHIGH \
+ IOMUX_PAD(0x0424, 0x0134, 5, 0x0000, 0, PAD_CTL_PUS_47K_UP)
+#define MX6SL_PAD_FEC_REF_CLK__SPDIF_SPDIF_EXT_CLK \
+ IOMUX_PAD(0x0424, 0x0134, 6, 0x07F4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_REF_CLK__PL301_SIM_MX6SL_PER1_HADDR_0 \
+ IOMUX_PAD(0x0424, 0x0134, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_RX_ER__GPIO_4_19 \
+ IOMUX_PAD(0x0428, 0x0138, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__KITTEN_TRACE_25 \
+ IOMUX_PAD(0x0428, 0x0138, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__PL301_SIM_MX6SL_PER1_HADDR_5 \
+ IOMUX_PAD(0x0428, 0x0138, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__FEC_RX_ER \
+ IOMUX_PAD(0x0428, 0x0138, 0, 0x0708, 1, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__USDHC4_DAT0 \
+ IOMUX_PAD(0x0428, 0x0138, 1, 0x085C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__AUDMUX_AUD6_RXD \
+ IOMUX_PAD(0x0428, 0x0138, 2, 0x0614, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__ECSPI4_MOSI \
+ IOMUX_PAD(0x0428, 0x0138, 3, 0x06D8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RX_ER__GPT_CMPOUT1 \
+ IOMUX_PAD(0x0428, 0x0138, 4, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_RXD0__FEC_RDATA_0 \
+ IOMUX_PAD(0x042C, 0x013C, 0, 0x06F8, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__USDHC4_DAT5 \
+ IOMUX_PAD(0x042C, 0x013C, 1, 0x0870, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__ANATOP_USBOTG1_ID \
+ IOMUX_PAD(0x042C, 0x013C, 2, 0x05DC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__USDHC1_VSELECT \
+ IOMUX_PAD(0x042C, 0x013C, 3, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__USDHC3_VSELECT \
+ IOMUX_PAD(0x042C, 0x013C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__GPIO_4_17 \
+ IOMUX_PAD(0x042C, 0x013C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__KITTEN_TRACE_24 \
+ IOMUX_PAD(0x042C, 0x013C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD0__PL301_SIM_MX6SL_PER1_HADDR_7 \
+ IOMUX_PAD(0x042C, 0x013C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_RXD1__FEC_RDATA_1 \
+ IOMUX_PAD(0x0430, 0x0140, 0, 0x06FC, 1, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__USDHC4_DAT2 \
+ IOMUX_PAD(0x0430, 0x0140, 1, 0x0864, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__AUDMUX_AUD6_TXFS \
+ IOMUX_PAD(0x0430, 0x0140, 2, 0x0628, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__ECSPI4_SS1 \
+ IOMUX_PAD(0x0430, 0x0140, 3, 0x06E0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__GPT_CMPOUT3 \
+ IOMUX_PAD(0x0430, 0x0140, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__GPIO_4_18 \
+ IOMUX_PAD(0x0430, 0x0140, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__FEC_COL \
+ IOMUX_PAD(0x0430, 0x0140, 6, 0x06F0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_RXD1__PL301_SIM_MX6SL_PER1_HADDR_9 \
+ IOMUX_PAD(0x0430, 0x0140, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_TX_CLK__FEC_TX_CLK \
+ IOMUX_PAD(0x0434, 0x0144, 0, 0x070C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__USDHC4_CMD \
+ IOMUX_PAD(0x0434, 0x0144, 1, 0x0858, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__AUDMUX_AUD6_RXC \
+ IOMUX_PAD(0x0434, 0x0144, 2, 0x061C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__ECSPI4_SCLK \
+ IOMUX_PAD(0x0434, 0x0144, 3, 0x06D0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__GPT_CAPIN2 \
+ IOMUX_PAD(0x0434, 0x0144, 4, 0x0714, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__GPIO_4_21 \
+ IOMUX_PAD(0x0434, 0x0144, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__KITTEN_TRACE_27 \
+ IOMUX_PAD(0x0434, 0x0144, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_CLK__PL301_SIM_MX6SL_PER1_HADDR_4 \
+ IOMUX_PAD(0x0434, 0x0144, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_TX_EN__FEC_TX_EN \
+ IOMUX_PAD(0x0438, 0x0148, 0, 0x0000, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__USDHC4_DAT6 \
+ IOMUX_PAD(0x0438, 0x0148, 1, 0x0874, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__SPDIF_IN1 \
+ IOMUX_PAD(0x0438, 0x0148, 2, 0x07F0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__USDHC1_WP \
+ IOMUX_PAD(0x0438, 0x0148, 3, 0x082C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__USDHC3_WP \
+ IOMUX_PAD(0x0438, 0x0148, 4, 0x084C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__GPIO_4_22 \
+ IOMUX_PAD(0x0438, 0x0148, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__KITTEN_TRACE_28 \
+ IOMUX_PAD(0x0438, 0x0148, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TX_EN__PL301_SIM_MX6SL_PER1_HADDR_1 \
+ IOMUX_PAD(0x0438, 0x0148, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_TXD0__FEC_TDATA_0 \
+ IOMUX_PAD(0x043C, 0x014C, 0, 0x0000, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__USDHC4_DAT3 \
+ IOMUX_PAD(0x043C, 0x014C, 1, 0x0868, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__AUDMUX_AUD6_TXD \
+ IOMUX_PAD(0x043C, 0x014C, 2, 0x0618, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__ECSPI4_SS2 \
+ IOMUX_PAD(0x043C, 0x014C, 3, 0x06E4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__GPT_CLKIN \
+ IOMUX_PAD(0x043C, 0x014C, 4, 0x0718, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__GPIO_4_24 \
+ IOMUX_PAD(0x043C, 0x014C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__KITTEN_TRACE_30 \
+ IOMUX_PAD(0x043C, 0x014C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD0__PL301_SIM_MX6SL_PER1_HADDR_2 \
+ IOMUX_PAD(0x043C, 0x014C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_FEC_TXD1__FEC_TDATA_1 \
+ IOMUX_PAD(0x0440, 0x0150, 0, 0x0000, 0, MX6SL_ENET_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__USDHC4_DAT7 \
+ IOMUX_PAD(0x0440, 0x0150, 1, 0x0878, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__SPDIF_OUT1 \
+ IOMUX_PAD(0x0440, 0x0150, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__USDHC1_CD \
+ IOMUX_PAD(0x0440, 0x0150, 3, 0x0828, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__USDHC3_CD \
+ IOMUX_PAD(0x0440, 0x0150, 4, 0x0838, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__GPIO_4_16 \
+ IOMUX_PAD(0x0440, 0x0150, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__FEC_RX_CLK \
+ IOMUX_PAD(0x0440, 0x0150, 6, 0x0700, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_FEC_TXD1__PL301_SIM_MX6SL_PER1_HADDR_6 \
+ IOMUX_PAD(0x0440, 0x0150, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_HSIC_DAT__USB_H_DATA \
+ IOMUX_PAD(0x0444, 0x0154, 0, 0x0000, 0, MX6SL_USB_HSIC_PAD_CTRL)
+#define MX6SL_PAD_HSIC_DAT__I2C1_SCL \
+ IOMUX_PAD(0x0444, 0x0154, 1 | IOMUX_CONFIG_SION, 0x071C, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_HSIC_DAT__PWM1_PWMO \
+ IOMUX_PAD(0x0444, 0x0154, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_HSIC_DAT__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x0444, 0x0154, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_HSIC_DAT__OSC32K_32K_OUT \
+ IOMUX_PAD(0x0444, 0x0154, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_HSIC_DAT__GPIO_3_19 \
+ IOMUX_PAD(0x0444, 0x0154, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_HSIC_STROBE__USB_H_STROBE \
+ IOMUX_PAD(0x0448, 0x0158, 0, 0x0000, 0, MX6SL_USB_HSIC_PAD_CTRL)
+#define MX6SL_PAD_HSIC_STROBE__USB_H_STROBE_START \
+ IOMUX_PAD(0x0448, 0x0158, 0, 0x0000, 0, MX6SL_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)
+#define MX6SL_PAD_HSIC_STROBE__I2C1_SDA \
+ IOMUX_PAD(0x0448, 0x0158, 1 | IOMUX_CONFIG_SION, 0x0720, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_HSIC_STROBE__PWM2_PWMO \
+ IOMUX_PAD(0x0448, 0x0158, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_HSIC_STROBE__ANATOP_ANATOP_32K_OUT \
+ IOMUX_PAD(0x0448, 0x0158, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_HSIC_STROBE__GPIO_3_20 \
+ IOMUX_PAD(0x0448, 0x0158, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_I2C1_SCL__I2C1_SCL \
+ IOMUX_PAD(0x044C, 0x015C, 0 | IOMUX_CONFIG_SION, 0x071C, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__UART1_CTS \
+ IOMUX_PAD(0x044C, 0x015C, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__UART1_RTS \
+ IOMUX_PAD(0x044C, 0x015C, 1, 0x07F8, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__ECSPI3_SS2 \
+ IOMUX_PAD(0x044C, 0x015C, 2, 0x06C8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__FEC_RDATA_0 \
+ IOMUX_PAD(0x044C, 0x015C, 3, 0x06F8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__USDHC3_RST \
+ IOMUX_PAD(0x044C, 0x015C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__GPIO_3_12 \
+ IOMUX_PAD(0x044C, 0x015C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__ECSPI1_SS1 \
+ IOMUX_PAD(0x044C, 0x015C, 6, 0x0690, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SCL__PL301_SIM_MX6SL_PER1_HSIZE_0 \
+ IOMUX_PAD(0x044C, 0x015C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_I2C1_SDA__I2C1_SDA \
+ IOMUX_PAD(0x0450, 0x0160, 0 | IOMUX_CONFIG_SION, 0x0720, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__UART1_CTS \
+ IOMUX_PAD(0x0450, 0x0160, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__UART1_RTS \
+ IOMUX_PAD(0x0450, 0x0160, 1, 0x07F8, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__ECSPI3_SS3 \
+ IOMUX_PAD(0x0450, 0x0160, 2, 0x06CC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__FEC_TX_EN \
+ IOMUX_PAD(0x0450, 0x0160, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__USDHC3_VSELECT \
+ IOMUX_PAD(0x0450, 0x0160, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__GPIO_3_13 \
+ IOMUX_PAD(0x0450, 0x0160, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__ECSPI1_SS2 \
+ IOMUX_PAD(0x0450, 0x0160, 6, 0x0694, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C1_SDA__PL301_SIM_MX6SL_PER1_HSIZE_1 \
+ IOMUX_PAD(0x0450, 0x0160, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_I2C2_SCL__I2C2_SCL \
+ IOMUX_PAD(0x0454, 0x0164, 0 | IOMUX_CONFIG_SION, 0x0724, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x0454, 0x0164, 1, 0x05F0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__SPDIF_IN1 \
+ IOMUX_PAD(0x0454, 0x0164, 2, 0x07F0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__FEC_TDATA_1 \
+ IOMUX_PAD(0x0454, 0x0164, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__USDHC3_WP \
+ IOMUX_PAD(0x0454, 0x0164, 4, 0x084C, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__GPIO_3_14 \
+ IOMUX_PAD(0x0454, 0x0164, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__ECSPI1_RDY \
+ IOMUX_PAD(0x0454, 0x0164, 6, 0x0680, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SCL__PL301_SIM_MX6SL_PER1_HSIZE_2 \
+ IOMUX_PAD(0x0454, 0x0164, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_I2C2_SDA__I2C2_SDA \
+ IOMUX_PAD(0x0458, 0x0168, 0 | IOMUX_CONFIG_SION, 0x0728, 1, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x0458, 0x0168, 1, 0x05EC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__SPDIF_OUT1 \
+ IOMUX_PAD(0x0458, 0x0168, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__FEC_REF_OUT \
+ IOMUX_PAD(0x0458, 0x0168, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__USDHC3_CD \
+ IOMUX_PAD(0x0458, 0x0168, 4, 0x0838, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__GPIO_3_15 \
+ IOMUX_PAD(0x0458, 0x0168, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__ANATOP_ANATOP_TESTO_0 \
+ IOMUX_PAD(0x0458, 0x0168, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_I2C2_SDA__PL301_SIM_MX6SL_PER1_HWRITE \
+ IOMUX_PAD(0x0458, 0x0168, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_MOD__SJC_MOD \
+ IOMUX_PAD(0x045C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_TCK__SJC_TCK \
+ IOMUX_PAD(0x0460, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_TDI__SJC_TDI \
+ IOMUX_PAD(0x0464, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_TDO__SJC_TDO \
+ IOMUX_PAD(0x0468, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_TMS__SJC_TMS \
+ IOMUX_PAD(0x046C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_JTAG_TRSTB__SJC_TRSTB \
+ IOMUX_PAD(0x0470, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL0__KPP_COL_0 \
+ IOMUX_PAD(0x0474, 0x016C, 0, 0x0734, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__I2C2_SCL \
+ IOMUX_PAD(0x0474, 0x016C, 1 | IOMUX_CONFIG_SION, 0x0724, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__LCDIF_DAT_0 \
+ IOMUX_PAD(0x0474, 0x016C, 2, 0x0778, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__WEIM_WEIM_DA_A_0 \
+ IOMUX_PAD(0x0474, 0x016C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__USDHC1_CD \
+ IOMUX_PAD(0x0474, 0x016C, 4, 0x0828, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__GPIO_3_24 \
+ IOMUX_PAD(0x0474, 0x016C, 5, 0x0000, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__MSHC_SCLK \
+ IOMUX_PAD(0x0474, 0x016C, 6, 0x07E8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL0__TPSMP_HDATA_0 \
+ IOMUX_PAD(0x0474, 0x016C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL1__KPP_COL_1 \
+ IOMUX_PAD(0x0478, 0x0170, 0, 0x0738, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__ECSPI4_MOSI \
+ IOMUX_PAD(0x0478, 0x0170, 1, 0x06D8, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__LCDIF_DAT_2 \
+ IOMUX_PAD(0x0478, 0x0170, 2, 0x0780, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__WEIM_WEIM_DA_A_2 \
+ IOMUX_PAD(0x0478, 0x0170, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__USDHC3_DAT4 \
+ IOMUX_PAD(0x0478, 0x0170, 4, 0x083C, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__GPIO_3_26 \
+ IOMUX_PAD(0x0478, 0x0170, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_KEY_COL1__MSHC_DATA_0 \
+ IOMUX_PAD(0x0478, 0x0170, 6, 0x07D8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL1__TPSMP_HDATA_2 \
+ IOMUX_PAD(0x0478, 0x0170, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL2__KPP_COL_2 \
+ IOMUX_PAD(0x047C, 0x0174, 0, 0x073C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__ECSPI4_SS0 \
+ IOMUX_PAD(0x047C, 0x0174, 1, 0x06DC, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__LCDIF_DAT_4 \
+ IOMUX_PAD(0x047C, 0x0174, 2, 0x0788, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__WEIM_WEIM_DA_A_4 \
+ IOMUX_PAD(0x047C, 0x0174, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__USDHC3_DAT6 \
+ IOMUX_PAD(0x047C, 0x0174, 4, 0x0844, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__GPIO_3_28 \
+ IOMUX_PAD(0x047C, 0x0174, 5, 0x0000, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__MSHC_DATA_2 \
+ IOMUX_PAD(0x047C, 0x0174, 6, 0x07E0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL2__TPSMP_HDATA_4 \
+ IOMUX_PAD(0x047C, 0x0174, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL3__KPP_COL_3 \
+ IOMUX_PAD(0x0480, 0x0178, 0, 0x0740, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__AUDMUX_AUD6_RXFS \
+ IOMUX_PAD(0x0480, 0x0178, 1, 0x0620, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__LCDIF_DAT_6 \
+ IOMUX_PAD(0x0480, 0x0178, 2, 0x0790, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__WEIM_WEIM_DA_A_6 \
+ IOMUX_PAD(0x0480, 0x0178, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__USDHC4_DAT6 \
+ IOMUX_PAD(0x0480, 0x0178, 4, 0x0874, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__GPIO_3_30 \
+ IOMUX_PAD(0x0480, 0x0178, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__USDHC1_RST \
+ IOMUX_PAD(0x0480, 0x0178, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL3__TPSMP_HDATA_6 \
+ IOMUX_PAD(0x0480, 0x0178, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL4__KPP_COL_4 \
+ IOMUX_PAD(0x0484, 0x017C, 0, 0x0744, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__AUDMUX_AUD6_RXD \
+ IOMUX_PAD(0x0484, 0x017C, 1, 0x0614, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__LCDIF_DAT_8 \
+ IOMUX_PAD(0x0484, 0x017C, 2, 0x0798, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__WEIM_WEIM_DA_A_8 \
+ IOMUX_PAD(0x0484, 0x017C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__USDHC4_CLK \
+ IOMUX_PAD(0x0484, 0x017C, 4, 0x0850, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__GPIO_4_0 \
+ IOMUX_PAD(0x0484, 0x017C, 5, 0x0000, 0, MX6SL_TOUCH_CTRL)
+#define MX6SL_PAD_KEY_COL4__USB_USBOTG1_PWR \
+ IOMUX_PAD(0x0484, 0x017C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL4__TPSMP_HDATA_8 \
+ IOMUX_PAD(0x0484, 0x017C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL5__KPP_COL_5 \
+ IOMUX_PAD(0x0488, 0x0180, 0, 0x0748, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__AUDMUX_AUD6_TXFS \
+ IOMUX_PAD(0x0488, 0x0180, 1, 0x0628, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__LCDIF_DAT_10 \
+ IOMUX_PAD(0x0488, 0x0180, 2, 0x07A0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__WEIM_WEIM_DA_A_10 \
+ IOMUX_PAD(0x0488, 0x0180, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__USDHC4_DAT0 \
+ IOMUX_PAD(0x0488, 0x0180, 4, 0x085C, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__GPIO_4_2 \
+ IOMUX_PAD(0x0488, 0x0180, 5, 0x0000, 0, MX6SL_TOUCH_CTRL)
+#define MX6SL_PAD_KEY_COL5__USB_USBOTG2_PWR \
+ IOMUX_PAD(0x0488, 0x0180, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL5__TPSMP_HDATA_10 \
+ IOMUX_PAD(0x0488, 0x0180, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL6__KPP_COL_6 \
+ IOMUX_PAD(0x048C, 0x0184, 0, 0x074C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__UART4_TXD \
+ IOMUX_PAD(0x048C, 0x0184, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__UART4_RXD \
+ IOMUX_PAD(0x048C, 0x0184, 1, 0x0814, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__LCDIF_DAT_12 \
+ IOMUX_PAD(0x048C, 0x0184, 2, 0x07A8, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__WEIM_WEIM_DA_A_12 \
+ IOMUX_PAD(0x048C, 0x0184, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__USDHC4_DAT2 \
+ IOMUX_PAD(0x048C, 0x0184, 4, 0x0864, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__GPIO_4_4 \
+ IOMUX_PAD(0x048C, 0x0184, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_KEY_COL6__USDHC3_RST \
+ IOMUX_PAD(0x048C, 0x0184, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL6__TPSMP_HDATA_12 \
+ IOMUX_PAD(0x048C, 0x0184, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_COL7__KPP_COL_7 \
+ IOMUX_PAD(0x0490, 0x0188, 0, 0x0750, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__UART4_CTS \
+ IOMUX_PAD(0x0490, 0x0188, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__UART4_RTS \
+ IOMUX_PAD(0x0490, 0x0188, 1, 0x0810, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__LCDIF_DAT_14 \
+ IOMUX_PAD(0x0490, 0x0188, 2, 0x07B0, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__WEIM_WEIM_DA_A_14 \
+ IOMUX_PAD(0x0490, 0x0188, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__USDHC4_DAT4 \
+ IOMUX_PAD(0x0490, 0x0188, 4, 0x086C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__GPIO_4_6 \
+ IOMUX_PAD(0x0490, 0x0188, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_KEY_COL7__USDHC1_WP \
+ IOMUX_PAD(0x0490, 0x0188, 6, 0x082C, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_COL7__TPSMP_HDATA_14 \
+ IOMUX_PAD(0x0490, 0x0188, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW0__KPP_ROW_0 \
+ IOMUX_PAD(0x0494, 0x018C, 0, 0x0754, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__I2C2_SDA \
+ IOMUX_PAD(0x0494, 0x018C, 1 | IOMUX_CONFIG_SION, 0x0728, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__LCDIF_DAT_1 \
+ IOMUX_PAD(0x0494, 0x018C, 2, 0x077C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__WEIM_WEIM_DA_A_1 \
+ IOMUX_PAD(0x0494, 0x018C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__USDHC1_WP \
+ IOMUX_PAD(0x0494, 0x018C, 4, 0x082C, 3, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__GPIO_3_25 \
+ IOMUX_PAD(0x0494, 0x018C, 5, 0x0000, 0, (PAD_CTL_HYS|PAD_CTL_PKE))
+#define MX6SL_PAD_KEY_ROW0__MSHC_BS \
+ IOMUX_PAD(0x0494, 0x018C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW0__TPSMP_HDATA_1 \
+ IOMUX_PAD(0x0494, 0x018C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW1__KPP_ROW_1 \
+ IOMUX_PAD(0x0498, 0x0190, 0, 0x0758, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__ECSPI4_MISO \
+ IOMUX_PAD(0x0498, 0x0190, 1, 0x06D4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__LCDIF_DAT_3 \
+ IOMUX_PAD(0x0498, 0x0190, 2, 0x0784, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__WEIM_WEIM_DA_A_3 \
+ IOMUX_PAD(0x0498, 0x0190, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__USDHC3_DAT5 \
+ IOMUX_PAD(0x0498, 0x0190, 4, 0x0840, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__GPIO_3_27 \
+ IOMUX_PAD(0x0498, 0x0190, 5, 0x0000, 0, (PAD_CTL_HYS|PAD_CTL_PKE))
+#define MX6SL_PAD_KEY_ROW1__MSHC_DATA_1 \
+ IOMUX_PAD(0x0498, 0x0190, 6, 0x07DC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW1__TPSMP_HDATA_3 \
+ IOMUX_PAD(0x0498, 0x0190, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW2__KPP_ROW_2 \
+ IOMUX_PAD(0x049C, 0x0194, 0, 0x075C, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__ECSPI4_SCLK \
+ IOMUX_PAD(0x049C, 0x0194, 1, 0x06D0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__LCDIF_DAT_5 \
+ IOMUX_PAD(0x049C, 0x0194, 2, 0x078C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__WEIM_WEIM_DA_A_5 \
+ IOMUX_PAD(0x049C, 0x0194, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__USDHC3_DAT7 \
+ IOMUX_PAD(0x049C, 0x0194, 4, 0x0848, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__GPIO_3_29 \
+ IOMUX_PAD(0x049C, 0x0194, 5, 0x0000, 0, (PAD_CTL_HYS|PAD_CTL_PKE))
+#define MX6SL_PAD_KEY_ROW2__MSHC_DATA_3 \
+ IOMUX_PAD(0x049C, 0x0194, 6, 0x07E4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW2__TPSMP_HDATA_5 \
+ IOMUX_PAD(0x049C, 0x0194, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW3__KPP_ROW_3 \
+ IOMUX_PAD(0x04A0, 0x0198, 0, 0x0760, 0, MX6SL_KEYPAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__AUDMUX_AUD6_RXC \
+ IOMUX_PAD(0x04A0, 0x0198, 1, 0x061C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__LCDIF_DAT_7 \
+ IOMUX_PAD(0x04A0, 0x0198, 2, 0x0794, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__WEIM_WEIM_DA_A_7 \
+ IOMUX_PAD(0x04A0, 0x0198, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__USDHC4_DAT7 \
+ IOMUX_PAD(0x04A0, 0x0198, 4, 0x0878, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__GPIO_3_31 \
+ IOMUX_PAD(0x04A0, 0x0198, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__USDHC1_VSELECT \
+ IOMUX_PAD(0x04A0, 0x0198, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW3__TPSMP_HDATA_7 \
+ IOMUX_PAD(0x04A0, 0x0198, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW4__KPP_ROW_4 \
+ IOMUX_PAD(0x04A4, 0x019C, 0, 0x0764, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__AUDMUX_AUD6_TXC \
+ IOMUX_PAD(0x04A4, 0x019C, 1, 0x0624, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__LCDIF_DAT_9 \
+ IOMUX_PAD(0x04A4, 0x019C, 2, 0x079C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__WEIM_WEIM_DA_A_9 \
+ IOMUX_PAD(0x04A4, 0x019C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__USDHC4_CMD \
+ IOMUX_PAD(0x04A4, 0x019C, 4, 0x0858, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__GPIO_4_1 \
+ IOMUX_PAD(0x04A4, 0x019C, 5, 0x0000, 0, MX6SL_INTR_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__USB_USBOTG1_OC \
+ IOMUX_PAD(0x04A4, 0x019C, 6, 0x0824, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW4__TPSMP_HDATA_9 \
+ IOMUX_PAD(0x04A4, 0x019C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW5__KPP_ROW_5 \
+ IOMUX_PAD(0x04A8, 0x01A0, 0, 0x0768, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__AUDMUX_AUD6_TXD \
+ IOMUX_PAD(0x04A8, 0x01A0, 1, 0x0618, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__LCDIF_DAT_11 \
+ IOMUX_PAD(0x04A8, 0x01A0, 2, 0x07A4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__WEIM_WEIM_DA_A_11 \
+ IOMUX_PAD(0x04A8, 0x01A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__USDHC4_DAT1 \
+ IOMUX_PAD(0x04A8, 0x01A0, 4, 0x0860, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__GPIO_4_3 \
+ IOMUX_PAD(0x04A8, 0x01A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__USB_USBOTG2_OC \
+ IOMUX_PAD(0x04A8, 0x01A0, 6, 0x0820, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW5__TPSMP_HDATA_11 \
+ IOMUX_PAD(0x04A8, 0x01A0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW6__KPP_ROW_6 \
+ IOMUX_PAD(0x04AC, 0x01A4, 0, 0x076C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__UART4_TXD \
+ IOMUX_PAD(0x04AC, 0x01A4, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__UART4_RXD \
+ IOMUX_PAD(0x04AC, 0x01A4, 1, 0x0814, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__LCDIF_DAT_13 \
+ IOMUX_PAD(0x04AC, 0x01A4, 2, 0x07AC, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__WEIM_WEIM_DA_A_13 \
+ IOMUX_PAD(0x04AC, 0x01A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__USDHC4_DAT3 \
+ IOMUX_PAD(0x04AC, 0x01A4, 4, 0x0868, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__GPIO_4_5 \
+ IOMUX_PAD(0x04AC, 0x01A4, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_KEY_ROW6__USDHC3_VSELECT \
+ IOMUX_PAD(0x04AC, 0x01A4, 6, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW6__TPSMP_HDATA_13 \
+ IOMUX_PAD(0x04AC, 0x01A4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_KEY_ROW7__KPP_ROW_7 \
+ IOMUX_PAD(0x04B0, 0x01A8, 0, 0x0770, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__UART4_CTS \
+ IOMUX_PAD(0x04B0, 0x01A8, 1, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__UART4_RTS \
+ IOMUX_PAD(0x04B0, 0x01A8, 1, 0x0810, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__LCDIF_DAT_15 \
+ IOMUX_PAD(0x04B0, 0x01A8, 2, 0x07B4, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__WEIM_WEIM_DA_A_15 \
+ IOMUX_PAD(0x04B0, 0x01A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__USDHC4_DAT5 \
+ IOMUX_PAD(0x04B0, 0x01A8, 4, 0x0870, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__GPIO_4_7 \
+ IOMUX_PAD(0x04B0, 0x01A8, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_KEY_ROW7__USDHC1_CD \
+ IOMUX_PAD(0x04B0, 0x01A8, 6, 0x0828, 3, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_KEY_ROW7__TPSMP_HDATA_15 \
+ IOMUX_PAD(0x04B0, 0x01A8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_CLK__LCDIF_CLK \
+ IOMUX_PAD(0x04B4, 0x01AC, 0, 0x0000, 0, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__USDHC4_DAT4 \
+ IOMUX_PAD(0x04B4, 0x01AC, 1, 0x086C, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__LCDIF_WR_RWN \
+ IOMUX_PAD(0x04B4, 0x01AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__WEIM_WEIM_RW \
+ IOMUX_PAD(0x04B4, 0x01AC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__PWM4_PWMO \
+ IOMUX_PAD(0x04B4, 0x01AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__GPIO_2_15 \
+ IOMUX_PAD(0x04B4, 0x01AC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__SRC_EARLY_RST \
+ IOMUX_PAD(0x04B4, 0x01AC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_CLK__TPSMP_HTRANS_0 \
+ IOMUX_PAD(0x04B4, 0x01AC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT0__LCDIF_DAT_0 \
+ IOMUX_PAD(0x04B8, 0x01B0, 0, 0x0778, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__ECSPI1_MOSI \
+ IOMUX_PAD(0x04B8, 0x01B0, 1, 0x0688, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__ANATOP_USBOTG2_ID \
+ IOMUX_PAD(0x04B8, 0x01B0, 2, 0x05E0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__PWM1_PWMO \
+ IOMUX_PAD(0x04B8, 0x01B0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__UART5_DTR \
+ IOMUX_PAD(0x04B8, 0x01B0, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__GPIO_2_20 \
+ IOMUX_PAD(0x04B8, 0x01B0, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__KITTEN_TRACE_0 \
+ IOMUX_PAD(0x04B8, 0x01B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT0__SRC_BT_CFG_0 \
+ IOMUX_PAD(0x04B8, 0x01B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT1__LCDIF_DAT_1 \
+ IOMUX_PAD(0x04BC, 0x01B4, 0, 0x077C, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__ECSPI1_MISO \
+ IOMUX_PAD(0x04BC, 0x01B4, 1, 0x0684, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__ANATOP_USBOTG1_ID \
+ IOMUX_PAD(0x04BC, 0x01B4, 2, 0x05DC, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__PWM2_PWMO \
+ IOMUX_PAD(0x04BC, 0x01B4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x04BC, 0x01B4, 4, 0x05F0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__GPIO_2_21 \
+ IOMUX_PAD(0x04BC, 0x01B4, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__KITTEN_TRACE_1 \
+ IOMUX_PAD(0x04BC, 0x01B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT1__SRC_BT_CFG_1 \
+ IOMUX_PAD(0x04BC, 0x01B4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT10__LCDIF_DAT_10 \
+ IOMUX_PAD(0x04C0, 0x01B8, 0, 0x07A0, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__KPP_COL_1 \
+ IOMUX_PAD(0x04C0, 0x01B8, 1, 0x0738, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__CSI_D_7 \
+ IOMUX_PAD(0x04C0, 0x01B8, 2, 0x064C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__WEIM_WEIM_D_4 \
+ IOMUX_PAD(0x04C0, 0x01B8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__ECSPI2_MISO \
+ IOMUX_PAD(0x04C0, 0x01B8, 4, 0x06A0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__GPIO_2_30 \
+ IOMUX_PAD(0x04C0, 0x01B8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__KITTEN_TRACE_10 \
+ IOMUX_PAD(0x04C0, 0x01B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT10__SRC_BT_CFG_10 \
+ IOMUX_PAD(0x04C0, 0x01B8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT11__LCDIF_DAT_11 \
+ IOMUX_PAD(0x04C4, 0x01BC, 0, 0x07A4, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__KPP_ROW_1 \
+ IOMUX_PAD(0x04C4, 0x01BC, 1, 0x0758, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__CSI_D_6 \
+ IOMUX_PAD(0x04C4, 0x01BC, 2, 0x0648, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__WEIM_WEIM_D_5 \
+ IOMUX_PAD(0x04C4, 0x01BC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__ECSPI2_SS1 \
+ IOMUX_PAD(0x04C4, 0x01BC, 4, 0x06AC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__GPIO_2_31 \
+ IOMUX_PAD(0x04C4, 0x01BC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__KITTEN_TRACE_11 \
+ IOMUX_PAD(0x04C4, 0x01BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT11__SRC_BT_CFG_11 \
+ IOMUX_PAD(0x04C4, 0x01BC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT12__LCDIF_DAT_12 \
+ IOMUX_PAD(0x04C8, 0x01C0, 0, 0x07A8, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__KPP_COL_2 \
+ IOMUX_PAD(0x04C8, 0x01C0, 1, 0x073C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__CSI_D_5 \
+ IOMUX_PAD(0x04C8, 0x01C0, 2, 0x0644, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__WEIM_WEIM_D_6 \
+ IOMUX_PAD(0x04C8, 0x01C0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__UART5_CTS \
+ IOMUX_PAD(0x04C8, 0x01C0, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__UART5_RTS \
+ IOMUX_PAD(0x04C8, 0x01C0, 4, 0x0818, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__GPIO_3_0 \
+ IOMUX_PAD(0x04C8, 0x01C0, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__KITTEN_TRACE_12 \
+ IOMUX_PAD(0x04C8, 0x01C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT12__SRC_BT_CFG_12 \
+ IOMUX_PAD(0x04C8, 0x01C0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT13__LCDIF_DAT_13 \
+ IOMUX_PAD(0x04CC, 0x01C4, 0, 0x07AC, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__KPP_ROW_2 \
+ IOMUX_PAD(0x04CC, 0x01C4, 1, 0x075C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__CSI_D_4 \
+ IOMUX_PAD(0x04CC, 0x01C4, 2, 0x0640, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__WEIM_WEIM_D_7 \
+ IOMUX_PAD(0x04CC, 0x01C4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__UART5_CTS \
+ IOMUX_PAD(0x04CC, 0x01C4, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__UART5_RTS \
+ IOMUX_PAD(0x04CC, 0x01C4, 4, 0x0818, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__GPIO_3_1 \
+ IOMUX_PAD(0x04CC, 0x01C4, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__KITTEN_TRACE_13 \
+ IOMUX_PAD(0x04CC, 0x01C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT13__SRC_BT_CFG_13 \
+ IOMUX_PAD(0x04CC, 0x01C4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT14__LCDIF_DAT_14 \
+ IOMUX_PAD(0x04D0, 0x01C8, 0, 0x07B0, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__KPP_COL_3 \
+ IOMUX_PAD(0x04D0, 0x01C8, 1, 0x0740, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__CSI_D_3 \
+ IOMUX_PAD(0x04D0, 0x01C8, 2, 0x063C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__WEIM_WEIM_D_8 \
+ IOMUX_PAD(0x04D0, 0x01C8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__UART5_TXD \
+ IOMUX_PAD(0x04D0, 0x01C8, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__UART5_RXD \
+ IOMUX_PAD(0x04D0, 0x01C8, 4, 0x081C, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__GPIO_3_2 \
+ IOMUX_PAD(0x04D0, 0x01C8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__KITTEN_TRACE_14 \
+ IOMUX_PAD(0x04D0, 0x01C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT14__SRC_BT_CFG_14 \
+ IOMUX_PAD(0x04D0, 0x01C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT15__LCDIF_DAT_15 \
+ IOMUX_PAD(0x04D4, 0x01CC, 0, 0x07B4, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__KPP_ROW_3 \
+ IOMUX_PAD(0x04D4, 0x01CC, 1, 0x0760, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__CSI_D_2 \
+ IOMUX_PAD(0x04D4, 0x01CC, 2, 0x0638, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__WEIM_WEIM_D_9 \
+ IOMUX_PAD(0x04D4, 0x01CC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__UART5_TXD \
+ IOMUX_PAD(0x04D4, 0x01CC, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__UART5_RXD \
+ IOMUX_PAD(0x04D4, 0x01CC, 4, 0x081C, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__GPIO_3_3 \
+ IOMUX_PAD(0x04D4, 0x01CC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__KITTEN_TRACE_15 \
+ IOMUX_PAD(0x04D4, 0x01CC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT15__SRC_BT_CFG_15 \
+ IOMUX_PAD(0x04D4, 0x01CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT16__LCDIF_DAT_16 \
+ IOMUX_PAD(0x04D8, 0x01D0, 0, 0x07B8, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__KPP_COL_4 \
+ IOMUX_PAD(0x04D8, 0x01D0, 1, 0x0744, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__CSI_D_1 \
+ IOMUX_PAD(0x04D8, 0x01D0, 2, 0x0634, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__WEIM_WEIM_D_10 \
+ IOMUX_PAD(0x04D8, 0x01D0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__I2C2_SCL \
+ IOMUX_PAD(0x04D8, 0x01D0, 4 | IOMUX_CONFIG_SION, 0x0724, 3, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__GPIO_3_4 \
+ IOMUX_PAD(0x04D8, 0x01D0, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__KITTEN_TRACE_16 \
+ IOMUX_PAD(0x04D8, 0x01D0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT16__SRC_BT_CFG_24 \
+ IOMUX_PAD(0x04D8, 0x01D0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT17__LCDIF_DAT_17 \
+ IOMUX_PAD(0x04DC, 0x01D4, 0, 0x07BC, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__KPP_ROW_4 \
+ IOMUX_PAD(0x04DC, 0x01D4, 1, 0x0764, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__CSI_D_0 \
+ IOMUX_PAD(0x04DC, 0x01D4, 2, 0x0630, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__WEIM_WEIM_D_11 \
+ IOMUX_PAD(0x04DC, 0x01D4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__I2C2_SDA \
+ IOMUX_PAD(0x04DC, 0x01D4, 4 | IOMUX_CONFIG_SION, 0x0728, 3, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__GPIO_3_5 \
+ IOMUX_PAD(0x04DC, 0x01D4, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__KITTEN_TRACE_17 \
+ IOMUX_PAD(0x04DC, 0x01D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT17__SRC_BT_CFG_25 \
+ IOMUX_PAD(0x04DC, 0x01D4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT18__LCDIF_DAT_18 \
+ IOMUX_PAD(0x04E0, 0x01D8, 0, 0x07C0, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__KPP_COL_5 \
+ IOMUX_PAD(0x04E0, 0x01D8, 1, 0x0748, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__CSI_D_15 \
+ IOMUX_PAD(0x04E0, 0x01D8, 2, 0x066C, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__WEIM_WEIM_D_12 \
+ IOMUX_PAD(0x04E0, 0x01D8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__GPT_CAPIN1 \
+ IOMUX_PAD(0x04E0, 0x01D8, 4, 0x0710, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__GPIO_3_6 \
+ IOMUX_PAD(0x04E0, 0x01D8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__KITTEN_TRACE_18 \
+ IOMUX_PAD(0x04E0, 0x01D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT18__SRC_BT_CFG_26 \
+ IOMUX_PAD(0x04E0, 0x01D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT19__LCDIF_DAT_19 \
+ IOMUX_PAD(0x04E4, 0x01DC, 0, 0x07C4, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__KPP_ROW_5 \
+ IOMUX_PAD(0x04E4, 0x01DC, 1, 0x0768, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__CSI_D_14 \
+ IOMUX_PAD(0x04E4, 0x01DC, 2, 0x0668, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__WEIM_WEIM_D_13 \
+ IOMUX_PAD(0x04E4, 0x01DC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__GPT_CAPIN2 \
+ IOMUX_PAD(0x04E4, 0x01DC, 4, 0x0714, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__GPIO_3_7 \
+ IOMUX_PAD(0x04E4, 0x01DC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__KITTEN_TRACE_19 \
+ IOMUX_PAD(0x04E4, 0x01DC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT19__SRC_BT_CFG_27 \
+ IOMUX_PAD(0x04E4, 0x01DC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT2__LCDIF_DAT_2 \
+ IOMUX_PAD(0x04E8, 0x01E0, 0, 0x0780, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__ECSPI1_SS0 \
+ IOMUX_PAD(0x04E8, 0x01E0, 1, 0x068C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__EPIT2_EPITO \
+ IOMUX_PAD(0x04E8, 0x01E0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__PWM3_PWMO \
+ IOMUX_PAD(0x04E8, 0x01E0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x04E8, 0x01E0, 4, 0x05EC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__GPIO_2_22 \
+ IOMUX_PAD(0x04E8, 0x01E0, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__KITTEN_TRACE_2 \
+ IOMUX_PAD(0x04E8, 0x01E0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT2__SRC_BT_CFG_2 \
+ IOMUX_PAD(0x04E8, 0x01E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT20__LCDIF_DAT_20 \
+ IOMUX_PAD(0x04EC, 0x01E4, 0, 0x07C8, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__KPP_COL_6 \
+ IOMUX_PAD(0x04EC, 0x01E4, 1, 0x074C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__CSI_D_13 \
+ IOMUX_PAD(0x04EC, 0x01E4, 2, 0x0664, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__WEIM_WEIM_D_14 \
+ IOMUX_PAD(0x04EC, 0x01E4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__GPT_CMPOUT1 \
+ IOMUX_PAD(0x04EC, 0x01E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__GPIO_3_8 \
+ IOMUX_PAD(0x04EC, 0x01E4, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__KITTEN_TRACE_20 \
+ IOMUX_PAD(0x04EC, 0x01E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT20__SRC_BT_CFG_28 \
+ IOMUX_PAD(0x04EC, 0x01E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT21__LCDIF_DAT_21 \
+ IOMUX_PAD(0x04F0, 0x01E8, 0, 0x07CC, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__KPP_ROW_6 \
+ IOMUX_PAD(0x04F0, 0x01E8, 1, 0x076C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__CSI_D_12 \
+ IOMUX_PAD(0x04F0, 0x01E8, 2, 0x0660, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__WEIM_WEIM_D_15 \
+ IOMUX_PAD(0x04F0, 0x01E8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__GPT_CMPOUT2 \
+ IOMUX_PAD(0x04F0, 0x01E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__GPIO_3_9 \
+ IOMUX_PAD(0x04F0, 0x01E8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__KITTEN_TRACE_21 \
+ IOMUX_PAD(0x04F0, 0x01E8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT21__SRC_BT_CFG_29 \
+ IOMUX_PAD(0x04F0, 0x01E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT22__LCDIF_DAT_22 \
+ IOMUX_PAD(0x04F4, 0x01EC, 0, 0x07D0, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__KPP_COL_7 \
+ IOMUX_PAD(0x04F4, 0x01EC, 1, 0x0750, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__CSI_D_11 \
+ IOMUX_PAD(0x04F4, 0x01EC, 2, 0x065C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__WEIM_WEIM_EB_3 \
+ IOMUX_PAD(0x04F4, 0x01EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__GPT_CMPOUT3 \
+ IOMUX_PAD(0x04F4, 0x01EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__GPIO_3_10 \
+ IOMUX_PAD(0x04F4, 0x01EC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__KITTEN_TRACE_22 \
+ IOMUX_PAD(0x04F4, 0x01EC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT22__SRC_BT_CFG_30 \
+ IOMUX_PAD(0x04F4, 0x01EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT23__LCDIF_DAT_23 \
+ IOMUX_PAD(0x04F8, 0x01F0, 0, 0x07D4, 1, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__KPP_ROW_7 \
+ IOMUX_PAD(0x04F8, 0x01F0, 1, 0x0770, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__CSI_D_10 \
+ IOMUX_PAD(0x04F8, 0x01F0, 2, 0x0658, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__WEIM_WEIM_EB_2 \
+ IOMUX_PAD(0x04F8, 0x01F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__GPT_CLKIN \
+ IOMUX_PAD(0x04F8, 0x01F0, 4, 0x0718, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__GPIO_3_11 \
+ IOMUX_PAD(0x04F8, 0x01F0, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__KITTEN_TRACE_23 \
+ IOMUX_PAD(0x04F8, 0x01F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT23__SRC_BT_CFG_31 \
+ IOMUX_PAD(0x04F8, 0x01F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT3__LCDIF_DAT_3 \
+ IOMUX_PAD(0x04FC, 0x01F4, 0, 0x0784, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__ECSPI1_SCLK \
+ IOMUX_PAD(0x04FC, 0x01F4, 1, 0x067C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__UART5_DSR \
+ IOMUX_PAD(0x04FC, 0x01F4, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__PWM4_PWMO \
+ IOMUX_PAD(0x04FC, 0x01F4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x04FC, 0x01F4, 4, 0x05E4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__GPIO_2_23 \
+ IOMUX_PAD(0x04FC, 0x01F4, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__KITTEN_TRACE_3 \
+ IOMUX_PAD(0x04FC, 0x01F4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT3__SRC_BT_CFG_3 \
+ IOMUX_PAD(0x04FC, 0x01F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT4__LCDIF_DAT_4 \
+ IOMUX_PAD(0x0500, 0x01F8, 0, 0x0788, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__ECSPI1_SS1 \
+ IOMUX_PAD(0x0500, 0x01F8, 1, 0x0690, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__CSI_VSYNC \
+ IOMUX_PAD(0x0500, 0x01F8, 2, 0x0678, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__WDOG2_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x0500, 0x01F8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x0500, 0x01F8, 4, 0x05F4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__GPIO_2_24 \
+ IOMUX_PAD(0x0500, 0x01F8, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__KITTEN_TRACE_4 \
+ IOMUX_PAD(0x0500, 0x01F8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT4__SRC_BT_CFG_4 \
+ IOMUX_PAD(0x0500, 0x01F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT5__LCDIF_DAT_5 \
+ IOMUX_PAD(0x0504, 0x01FC, 0, 0x078C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__ECSPI1_SS2 \
+ IOMUX_PAD(0x0504, 0x01FC, 1, 0x0694, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__CSI_HSYNC \
+ IOMUX_PAD(0x0504, 0x01FC, 2, 0x0670, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x0504, 0x01FC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x0504, 0x01FC, 4, 0x05F8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__GPIO_2_25 \
+ IOMUX_PAD(0x0504, 0x01FC, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__KITTEN_TRACE_5 \
+ IOMUX_PAD(0x0504, 0x01FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT5__SRC_BT_CFG_5 \
+ IOMUX_PAD(0x0504, 0x01FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT6__LCDIF_DAT_6 \
+ IOMUX_PAD(0x0508, 0x0200, 0, 0x0790, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__ECSPI1_SS3 \
+ IOMUX_PAD(0x0508, 0x0200, 1, 0x0698, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__CSI_PIXCLK \
+ IOMUX_PAD(0x0508, 0x0200, 2, 0x0674, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__WEIM_WEIM_D_0 \
+ IOMUX_PAD(0x0508, 0x0200, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x0508, 0x0200, 4, 0x05E8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__GPIO_2_26 \
+ IOMUX_PAD(0x0508, 0x0200, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__KITTEN_TRACE_6 \
+ IOMUX_PAD(0x0508, 0x0200, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT6__SRC_BT_CFG_6 \
+ IOMUX_PAD(0x0508, 0x0200, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT7__LCDIF_DAT_7 \
+ IOMUX_PAD(0x050C, 0x0204, 0, 0x0794, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__ECSPI1_RDY \
+ IOMUX_PAD(0x050C, 0x0204, 1, 0x0680, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__CSI_MCLK \
+ IOMUX_PAD(0x050C, 0x0204, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__WEIM_WEIM_D_1 \
+ IOMUX_PAD(0x050C, 0x0204, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__AUDMUX_AUDIO_CLK_OUT \
+ IOMUX_PAD(0x050C, 0x0204, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__GPIO_2_27 \
+ IOMUX_PAD(0x050C, 0x0204, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__KITTEN_TRACE_7 \
+ IOMUX_PAD(0x050C, 0x0204, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT7__SRC_BT_CFG_7 \
+ IOMUX_PAD(0x050C, 0x0204, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT8__LCDIF_DAT_8 \
+ IOMUX_PAD(0x0510, 0x0208, 0, 0x0798, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__KPP_COL_0 \
+ IOMUX_PAD(0x0510, 0x0208, 1, 0x0734, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__CSI_D_9 \
+ IOMUX_PAD(0x0510, 0x0208, 2, 0x0654, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__WEIM_WEIM_D_2 \
+ IOMUX_PAD(0x0510, 0x0208, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__ECSPI2_SCLK \
+ IOMUX_PAD(0x0510, 0x0208, 4, 0x069C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__GPIO_2_28 \
+ IOMUX_PAD(0x0510, 0x0208, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__KITTEN_TRACE_8 \
+ IOMUX_PAD(0x0510, 0x0208, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT8__SRC_BT_CFG_8 \
+ IOMUX_PAD(0x0510, 0x0208, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_DAT9__LCDIF_DAT_9 \
+ IOMUX_PAD(0x0514, 0x020C, 0, 0x079C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__KPP_ROW_0 \
+ IOMUX_PAD(0x0514, 0x020C, 1, 0x0754, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__CSI_D_8 \
+ IOMUX_PAD(0x0514, 0x020C, 2, 0x0650, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__WEIM_WEIM_D_3 \
+ IOMUX_PAD(0x0514, 0x020C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__ECSPI2_MOSI \
+ IOMUX_PAD(0x0514, 0x020C, 4, 0x06A4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__GPIO_2_29 \
+ IOMUX_PAD(0x0514, 0x020C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__KITTEN_TRACE_9 \
+ IOMUX_PAD(0x0514, 0x020C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_DAT9__SRC_BT_CFG_9 \
+ IOMUX_PAD(0x0514, 0x020C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_ENABLE__LCDIF_ENABLE \
+ IOMUX_PAD(0x0518, 0x0210, 0, 0x0000, 0, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__USDHC4_DAT5 \
+ IOMUX_PAD(0x0518, 0x0210, 1, 0x0870, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__LCDIF_RD_E \
+ IOMUX_PAD(0x0518, 0x0210, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__WEIM_WEIM_OE \
+ IOMUX_PAD(0x0518, 0x0210, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__UART2_TXD \
+ IOMUX_PAD(0x0518, 0x0210, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__UART2_RXD \
+ IOMUX_PAD(0x0518, 0x0210, 4, 0x0804, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__GPIO_2_16 \
+ IOMUX_PAD(0x0518, 0x0210, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__OCOTP_CTRL_WRAPPER_FUSE_LATCHED \
+ IOMUX_PAD(0x0518, 0x0210, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_ENABLE__TPSMP_HTRANS_1 \
+ IOMUX_PAD(0x0518, 0x0210, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_HSYNC__LCDIF_HSYNC \
+ IOMUX_PAD(0x051C, 0x0214, 0, 0x0774, 0, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__USDHC4_DAT6 \
+ IOMUX_PAD(0x051C, 0x0214, 1, 0x0874, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__LCDIF_CS \
+ IOMUX_PAD(0x051C, 0x0214, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__WEIM_WEIM_CS_0 \
+ IOMUX_PAD(0x051C, 0x0214, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__UART2_TXD \
+ IOMUX_PAD(0x051C, 0x0214, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__UART2_RXD \
+ IOMUX_PAD(0x051C, 0x0214, 4, 0x0804, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__GPIO_2_17 \
+ IOMUX_PAD(0x051C, 0x0214, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__KITTEN_TRCLK \
+ IOMUX_PAD(0x051C, 0x0214, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_HSYNC__TPSMP_HDATA_16 \
+ IOMUX_PAD(0x051C, 0x0214, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_RESET__LCDIF_RESET \
+ IOMUX_PAD(0x0520, 0x0218, 0, 0x0000, 0, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__WEIM_WEIM_DTACK_B \
+ IOMUX_PAD(0x0520, 0x0218, 1, 0x0880, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__LCDIF_BUSY \
+ IOMUX_PAD(0x0520, 0x0218, 2, 0x0774, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__WEIM_WEIM_WAIT \
+ IOMUX_PAD(0x0520, 0x0218, 3, 0x0884, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__UART2_CTS \
+ IOMUX_PAD(0x0520, 0x0218, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__UART2_RTS \
+ IOMUX_PAD(0x0520, 0x0218, 4, 0x0800, 2, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__GPIO_2_19 \
+ IOMUX_PAD(0x0520, 0x0218, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0520, 0x0218, 6, 0x062C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_RESET__TPSMP_HDATA_DIR \
+ IOMUX_PAD(0x0520, 0x0218, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_LCD_VSYNC__LCDIF_VSYNC \
+ IOMUX_PAD(0x0524, 0x021C, 0, 0x0000, 0, MX6SL_LCDIF_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__USDHC4_DAT7 \
+ IOMUX_PAD(0x0524, 0x021C, 1, 0x0878, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__LCDIF_RS \
+ IOMUX_PAD(0x0524, 0x021C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__WEIM_WEIM_CS_1 \
+ IOMUX_PAD(0x0524, 0x021C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__UART2_CTS \
+ IOMUX_PAD(0x0524, 0x021C, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__UART2_RTS \
+ IOMUX_PAD(0x0524, 0x021C, 4, 0x0800, 3, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__GPIO_2_18 \
+ IOMUX_PAD(0x0524, 0x021C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__KITTEN_TRCTL \
+ IOMUX_PAD(0x0524, 0x021C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_LCD_VSYNC__TPSMP_HDATA_17 \
+ IOMUX_PAD(0x0524, 0x021C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_POR_B__SRC_POR_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_PWM1__PWM1_PWMO \
+ IOMUX_PAD(0x0528, 0x0220, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__CCM_CLKO \
+ IOMUX_PAD(0x0528, 0x0220, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__AUDMUX_AUDIO_CLK_OUT \
+ IOMUX_PAD(0x0528, 0x0220, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__FEC_REF_OUT \
+ IOMUX_PAD(0x0528, 0x0220, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__CSI_MCLK \
+ IOMUX_PAD(0x0528, 0x0220, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__GPIO_3_23 \
+ IOMUX_PAD(0x0528, 0x0220, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__EPIT1_EPITO \
+ IOMUX_PAD(0x0528, 0x0220, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_PWM1__OBSERVE_MUX_OUT_4 \
+ IOMUX_PAD(0x0528, 0x0220, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_REF_CLK_24M__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x052C, 0x0224, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__I2C3_SCL \
+ IOMUX_PAD(0x052C, 0x0224, 1 | IOMUX_CONFIG_SION, 0x072C, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__PWM3_PWMO \
+ IOMUX_PAD(0x052C, 0x0224, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__ANATOP_USBOTG2_ID \
+ IOMUX_PAD(0x052C, 0x0224, 3, 0x05E0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__CCM_PMIC_RDY \
+ IOMUX_PAD(0x052C, 0x0224, 4, 0x062C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__GPIO_3_21 \
+ IOMUX_PAD(0x052C, 0x0224, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__USDHC3_WP \
+ IOMUX_PAD(0x052C, 0x0224, 6, 0x084C, 3, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_24M__TPSMP_HDATA_19 \
+ IOMUX_PAD(0x052C, 0x0224, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_REF_CLK_32K__ANATOP_ANATOP_32K_OUT \
+ IOMUX_PAD(0x0530, 0x0228, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__I2C3_SDA \
+ IOMUX_PAD(0x0530, 0x0228, 1 | IOMUX_CONFIG_SION, 0x0730, 2, MX6SL_I2C_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__PWM4_PWMO \
+ IOMUX_PAD(0x0530, 0x0228, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__ANATOP_USBOTG1_ID \
+ IOMUX_PAD(0x0530, 0x0228, 3, 0x05DC, 3, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__USDHC1_LCTL \
+ IOMUX_PAD(0x0530, 0x0228, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__GPIO_3_22 \
+ IOMUX_PAD(0x0530, 0x0228, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__USDHC3_CD \
+ IOMUX_PAD(0x0530, 0x0228, 6, 0x0838, 3, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_REF_CLK_32K__OBSERVE_MUX_OUT_3 \
+ IOMUX_PAD(0x0530, 0x0228, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_RESET_IN_B__SRC_RESET_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_50MHZ \
+ IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_100MHZ \
+ IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_CLK__USDHC1_CLK_200MHZ \
+ IOMUX_PAD(0x0534, 0x022C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_CLK__FEC_MDIO \
+ IOMUX_PAD(0x0534, 0x022C, 1, 0x06F4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__KPP_COL_0 \
+ IOMUX_PAD(0x0534, 0x022C, 2, 0x0734, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__EPDC_SDCE_4 \
+ IOMUX_PAD(0x0534, 0x022C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__MSHC_SCLK \
+ IOMUX_PAD(0x0534, 0x022C, 4, 0x07E8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__GPIO_5_15 \
+ IOMUX_PAD(0x0534, 0x022C, 5, 0x0000, 0, MX6SL_CHG_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__ANATOP_ANATOP_TESTO_2 \
+ IOMUX_PAD(0x0534, 0x022C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CLK__PL301_SIM_MX6SL_PER1_HADDR_25 \
+ IOMUX_PAD(0x0534, 0x022C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_50MHZ \
+ IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_100MHZ \
+ IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_CMD__USDHC1_CMD_200MHZ \
+ IOMUX_PAD(0x0538, 0x0230, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_CMD__FEC_TX_CLK \
+ IOMUX_PAD(0x0538, 0x0230, 1, 0x070C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__KPP_ROW_0 \
+ IOMUX_PAD(0x0538, 0x0230, 2, 0x0754, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__EPDC_SDCE_5 \
+ IOMUX_PAD(0x0538, 0x0230, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__MSHC_BS \
+ IOMUX_PAD(0x0538, 0x0230, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__GPIO_5_14 \
+ IOMUX_PAD(0x0538, 0x0230, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_3 \
+ IOMUX_PAD(0x0538, 0x0230, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_CMD__PL301_SIM_MX6SL_PER1_HADDR_26 \
+ IOMUX_PAD(0x0538, 0x0230, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_50MHZ \
+ IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_100MHZ \
+ IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT0__USDHC1_DAT0_200MHZ \
+ IOMUX_PAD(0x053C, 0x0234, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT0__FEC_RX_ER \
+ IOMUX_PAD(0x053C, 0x0234, 1, 0x0708, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__KPP_COL_1 \
+ IOMUX_PAD(0x053C, 0x0234, 2, 0x0738, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__EPDC_SDCE_6 \
+ IOMUX_PAD(0x053C, 0x0234, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__MSHC_DATA_0 \
+ IOMUX_PAD(0x053C, 0x0234, 4, 0x07D8, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__GPIO_5_11 \
+ IOMUX_PAD(0x053C, 0x0234, 5, 0x0000, 0, MX6SL_CHG_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_4 \
+ IOMUX_PAD(0x053C, 0x0234, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT0__PL301_SIM_MX6SL_PER1_HADDR_27 \
+ IOMUX_PAD(0x053C, 0x0234, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_50MHZ \
+ IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_100MHZ \
+ IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT1__USDHC1_DAT1_200MHZ \
+ IOMUX_PAD(0x0540, 0x0238, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT1__FEC_RX_DV \
+ IOMUX_PAD(0x0540, 0x0238, 1, 0x0704, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__KPP_ROW_1 \
+ IOMUX_PAD(0x0540, 0x0238, 2, 0x0758, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__EPDC_SDCE_7 \
+ IOMUX_PAD(0x0540, 0x0238, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__MSHC_DATA_1 \
+ IOMUX_PAD(0x0540, 0x0238, 4, 0x07DC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__GPIO_5_8 \
+ IOMUX_PAD(0x0540, 0x0238, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_5 \
+ IOMUX_PAD(0x0540, 0x0238, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT1__PL301_SIM_MX6SL_PER1_HADDR_28 \
+ IOMUX_PAD(0x0540, 0x0238, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_50MHZ \
+ IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_100MHZ \
+ IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT2__USDHC1_DAT2_200MHZ \
+ IOMUX_PAD(0x0544, 0x023C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT2__FEC_RDATA_1 \
+ IOMUX_PAD(0x0544, 0x023C, 1, 0x06FC, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__KPP_COL_2 \
+ IOMUX_PAD(0x0544, 0x023C, 2, 0x073C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__EPDC_SDCE_8 \
+ IOMUX_PAD(0x0544, 0x023C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__MSHC_DATA_2 \
+ IOMUX_PAD(0x0544, 0x023C, 4, 0x07E0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__GPIO_5_13 \
+ IOMUX_PAD(0x0544, 0x023C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__GPIO_5_13_PULLHIGH \
+ IOMUX_PAD(0x0544, 0x023C, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_6 \
+ IOMUX_PAD(0x0544, 0x023C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT2__PL301_SIM_MX6SL_PER1_HADDR_29 \
+ IOMUX_PAD(0x0544, 0x023C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_50MHZ \
+ IOMUX_PAD(0x0548, 0x0240, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_100MHZ \
+ IOMUX_PAD(0x0548, 0x0240, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT3__USDHC1_DAT3_200MHZ \
+ IOMUX_PAD(0x0548, 0x0240, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT3__FEC_TDATA_0 \
+ IOMUX_PAD(0x0548, 0x0240, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__KPP_ROW_2 \
+ IOMUX_PAD(0x0548, 0x0240, 2, 0x075C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__EPDC_SDCE_9 \
+ IOMUX_PAD(0x0548, 0x0240, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__MSHC_DATA_3 \
+ IOMUX_PAD(0x0548, 0x0240, 4, 0x07E4, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__GPIO_5_6 \
+ IOMUX_PAD(0x0548, 0x0240, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_7 \
+ IOMUX_PAD(0x0548, 0x0240, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT3__PL301_SIM_MX6SL_PER1_HADDR_30 \
+ IOMUX_PAD(0x0548, 0x0240, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_50MHZ \
+ IOMUX_PAD(0x054C, 0x0244, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_100MHZ \
+ IOMUX_PAD(0x054C, 0x0244, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT4__USDHC1_DAT4_200MHZ \
+ IOMUX_PAD(0x054C, 0x0244, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT4__FEC_MDC \
+ IOMUX_PAD(0x054C, 0x0244, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__KPP_COL_3 \
+ IOMUX_PAD(0x054C, 0x0244, 2, 0x0740, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__EPDC_SDCLKN \
+ IOMUX_PAD(0x054C, 0x0244, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__UART4_TXD \
+ IOMUX_PAD(0x054C, 0x0244, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__UART4_RXD \
+ IOMUX_PAD(0x054C, 0x0244, 4, 0x0814, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__GPIO_5_12 \
+ IOMUX_PAD(0x054C, 0x0244, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__ANATOP_ANATOP_TESTO_8 \
+ IOMUX_PAD(0x054C, 0x0244, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT4__PL301_SIM_MX6SL_PER1_HADDR_31 \
+ IOMUX_PAD(0x054C, 0x0244, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_50MHZ \
+ IOMUX_PAD(0x0550, 0x0248, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_100MHZ \
+ IOMUX_PAD(0x0550, 0x0248, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT5__USDHC1_DAT5_200MHZ \
+ IOMUX_PAD(0x0550, 0x0248, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT5__FEC_RDATA_0 \
+ IOMUX_PAD(0x0550, 0x0248, 1, 0x06F8, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__KPP_ROW_3 \
+ IOMUX_PAD(0x0550, 0x0248, 2, 0x0760, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__EPDC_SDOED \
+ IOMUX_PAD(0x0550, 0x0248, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__UART4_TXD \
+ IOMUX_PAD(0x0550, 0x0248, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__UART4_RXD \
+ IOMUX_PAD(0x0550, 0x0248, 4, 0x0814, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__GPIO_5_9 \
+ IOMUX_PAD(0x0550, 0x0248, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__ANATOP_ANATOP_TESTO_9 \
+ IOMUX_PAD(0x0550, 0x0248, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT5__PL301_SIM_MX6SL_PER1_HPROT_3 \
+ IOMUX_PAD(0x0550, 0x0248, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_50MHZ \
+ IOMUX_PAD(0x0554, 0x024C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_100MHZ \
+ IOMUX_PAD(0x0554, 0x024C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT6__USDHC1_DAT6_200MHZ \
+ IOMUX_PAD(0x0554, 0x024C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT6__FEC_TX_EN \
+ IOMUX_PAD(0x0554, 0x024C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__KPP_COL_4 \
+ IOMUX_PAD(0x0554, 0x024C, 2, 0x0744, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__EPDC_SDOEZ \
+ IOMUX_PAD(0x0554, 0x024C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__UART4_CTS \
+ IOMUX_PAD(0x0554, 0x024C, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__UART4_RTS \
+ IOMUX_PAD(0x0554, 0x024C, 4, 0x0810, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__GPIO_5_7 \
+ IOMUX_PAD(0x0554, 0x024C, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__ANATOP_ANATOP_TESTO_10 \
+ IOMUX_PAD(0x0554, 0x024C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT6__PL301_SIM_MX6SL_PER1_HPROT_2 \
+ IOMUX_PAD(0x0554, 0x024C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_50MHZ \
+ IOMUX_PAD(0x0558, 0x0250, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_100MHZ \
+ IOMUX_PAD(0x0558, 0x0250, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD1_DAT7__USDHC1_DAT7_200MHZ \
+ IOMUX_PAD(0x0558, 0x0250, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD1_DAT7__FEC_TDATA_1 \
+ IOMUX_PAD(0x0558, 0x0250, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__KPP_ROW_4 \
+ IOMUX_PAD(0x0558, 0x0250, 2, 0x0764, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0558, 0x0250, 3, 0x062C, 3, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__UART4_CTS \
+ IOMUX_PAD(0x0558, 0x0250, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__UART4_RTS \
+ IOMUX_PAD(0x0558, 0x0250, 4, 0x0810, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__GPIO_5_10 \
+ IOMUX_PAD(0x0558, 0x0250, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__GPIO_5_10_OUPUT \
+ IOMUX_PAD(0x0558, 0x0250, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__ANATOP_ANATOP_TESTO_11 \
+ IOMUX_PAD(0x0558, 0x0250, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD1_DAT7__PL301_SIM_MX6SL_PER1_HMASTLOCK \
+ IOMUX_PAD(0x0558, 0x0250, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_CLK__USDHC2_CLK_50MHZ \
+ IOMUX_PAD(0x055C, 0x0254, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__USDHC2_CLK_100MHZ \
+ IOMUX_PAD(0x055C, 0x0254, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_CLK__USDHC2_CLK_200MHZ \
+ IOMUX_PAD(0x055C, 0x0254, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_CLK__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x055C, 0x0254, 1, 0x05F0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__ECSPI3_SCLK \
+ IOMUX_PAD(0x055C, 0x0254, 2, 0x06B0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__CSI_D_0 \
+ IOMUX_PAD(0x055C, 0x0254, 3, 0x0630, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__OSC32K_32K_OUT \
+ IOMUX_PAD(0x055C, 0x0254, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__GPIO_5_5 \
+ IOMUX_PAD(0x055C, 0x0254, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__ANATOP_ANATOP_TESTO_13 \
+ IOMUX_PAD(0x055C, 0x0254, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CLK__PL301_SIM_MX6SL_PER1_HPROT_1 \
+ IOMUX_PAD(0x055C, 0x0254, 7, 0x07EC, 1, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_CMD__USDHC2_CMD_50MHZ \
+ IOMUX_PAD(0x0560, 0x0258, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__USDHC2_CMD_100MHZ \
+ IOMUX_PAD(0x0560, 0x0258, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_CMD__USDHC2_CMD_200MHZ \
+ IOMUX_PAD(0x0560, 0x0258, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_CMD__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x0560, 0x0258, 1, 0x05EC, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__ECSPI3_SS0 \
+ IOMUX_PAD(0x0560, 0x0258, 2, 0x06C0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__CSI_D_1 \
+ IOMUX_PAD(0x0560, 0x0258, 3, 0x0634, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__EPIT1_EPITO \
+ IOMUX_PAD(0x0560, 0x0258, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__GPIO_5_4 \
+ IOMUX_PAD(0x0560, 0x0258, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__ANATOP_ANATOP_TESTO_14 \
+ IOMUX_PAD(0x0560, 0x0258, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_CMD__PL301_SIM_MX6SL_PER1_HADDR_21 \
+ IOMUX_PAD(0x0560, 0x0258, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_50MHZ \
+ IOMUX_PAD(0x0564, 0x025C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_100MHZ \
+ IOMUX_PAD(0x0564, 0x025C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT0__USDHC2_DAT0_200MHZ \
+ IOMUX_PAD(0x0564, 0x025C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT0__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x0564, 0x025C, 1, 0x05E4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__ECSPI3_MOSI \
+ IOMUX_PAD(0x0564, 0x025C, 2, 0x06BC, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__CSI_D_2 \
+ IOMUX_PAD(0x0564, 0x025C, 3, 0x0638, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__UART5_CTS \
+ IOMUX_PAD(0x0564, 0x025C, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__UART5_RTS \
+ IOMUX_PAD(0x0564, 0x025C, 4, 0x0818, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__GPIO_5_1 \
+ IOMUX_PAD(0x0564, 0x025C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_15 \
+ IOMUX_PAD(0x0564, 0x025C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT0__PL301_SIM_MX6SL_PER1_HPROT_0 \
+ IOMUX_PAD(0x0564, 0x025C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_50MHZ \
+ IOMUX_PAD(0x0568, 0x0260, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_100MHZ \
+ IOMUX_PAD(0x0568, 0x0260, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT1__USDHC2_DAT1_200MHZ \
+ IOMUX_PAD(0x0568, 0x0260, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT1__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x0568, 0x0260, 1, 0x05F4, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__ECSPI3_MISO \
+ IOMUX_PAD(0x0568, 0x0260, 2, 0x06B8, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__CSI_D_3 \
+ IOMUX_PAD(0x0568, 0x0260, 3, 0x063C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__UART5_CTS \
+ IOMUX_PAD(0x0568, 0x0260, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__UART5_RTS \
+ IOMUX_PAD(0x0568, 0x0260, 4, 0x0818, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__GPIO_4_30 \
+ IOMUX_PAD(0x0568, 0x0260, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__MMDC_MMDC_DEBUG_39 \
+ IOMUX_PAD(0x0568, 0x0260, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT1__PL301_SIM_MX6SL_PER1_HBURST_1 \
+ IOMUX_PAD(0x0568, 0x0260, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_50MHZ \
+ IOMUX_PAD(0x056C, 0x0264, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_100MHZ \
+ IOMUX_PAD(0x056C, 0x0264, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT2__USDHC2_DAT2_200MHZ \
+ IOMUX_PAD(0x056C, 0x0264, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT2__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x056C, 0x0264, 1, 0x05F8, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__FEC_COL \
+ IOMUX_PAD(0x056C, 0x0264, 2, 0x06F0, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__CSI_D_4 \
+ IOMUX_PAD(0x056C, 0x0264, 3, 0x0640, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__UART5_TXD \
+ IOMUX_PAD(0x056C, 0x0264, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__UART5_RXD \
+ IOMUX_PAD(0x056C, 0x0264, 4, 0x081C, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__GPIO_5_3 \
+ IOMUX_PAD(0x056C, 0x0264, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__MMDC_MMDC_DEBUG_38 \
+ IOMUX_PAD(0x056C, 0x0264, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT2__PL301_SIM_MX6SL_PER1_HADDR_22 \
+ IOMUX_PAD(0x056C, 0x0264, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_50MHZ \
+ IOMUX_PAD(0x0570, 0x0268, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_100MHZ \
+ IOMUX_PAD(0x0570, 0x0268, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT3__USDHC2_DAT3_200MHZ \
+ IOMUX_PAD(0x0570, 0x0268, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT3__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x0570, 0x0268, 1, 0x05E8, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__FEC_RX_CLK \
+ IOMUX_PAD(0x0570, 0x0268, 2, 0x0700, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__CSI_D_5 \
+ IOMUX_PAD(0x0570, 0x0268, 3, 0x0644, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__UART5_TXD \
+ IOMUX_PAD(0x0570, 0x0268, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__UART5_RXD \
+ IOMUX_PAD(0x0570, 0x0268, 4, 0x081C, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__GPIO_4_28 \
+ IOMUX_PAD(0x0570, 0x0268, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__MMDC_MMDC_DEBUG_37 \
+ IOMUX_PAD(0x0570, 0x0268, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT3__PL301_SIM_MX6SL_PER1_HBURST_0 \
+ IOMUX_PAD(0x0570, 0x0268, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT4__USDHC2_DAT4_50MHZ \
+ IOMUX_PAD(0x0574, 0x026C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__USDHC2_DAT4_100MHZ \
+ IOMUX_PAD(0x0574, 0x026C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT4__USDHC2_DAT4_200MHZ \
+ IOMUX_PAD(0x0574, 0x026C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT4__USDHC3_DAT4 \
+ IOMUX_PAD(0x0574, 0x026C, 1, 0x083C, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__UART2_TXD \
+ IOMUX_PAD(0x0574, 0x026C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__UART2_RXD \
+ IOMUX_PAD(0x0574, 0x026C, 2, 0x0804, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__CSI_D_6 \
+ IOMUX_PAD(0x0574, 0x026C, 3, 0x0648, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__SPDIF_OUT1 \
+ IOMUX_PAD(0x0574, 0x026C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__GPIO_5_2 \
+ IOMUX_PAD(0x0574, 0x026C, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__MMDC_MMDC_DEBUG_36 \
+ IOMUX_PAD(0x0574, 0x026C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT4__PL301_SIM_MX6SL_PER1_HADDR_10 \
+ IOMUX_PAD(0x0574, 0x026C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT5__USDHC2_DAT5_50MHZ \
+ IOMUX_PAD(0x0578, 0x0270, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__USDHC2_DAT5_100MHZ \
+ IOMUX_PAD(0x0578, 0x0270, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT5__USDHC2_DAT5_200MHZ \
+ IOMUX_PAD(0x0578, 0x0270, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT5__USDHC3_DAT5 \
+ IOMUX_PAD(0x0578, 0x0270, 1, 0x0840, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__UART2_TXD \
+ IOMUX_PAD(0x0578, 0x0270, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__UART2_RXD \
+ IOMUX_PAD(0x0578, 0x0270, 2, 0x0804, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__CSI_D_7 \
+ IOMUX_PAD(0x0578, 0x0270, 3, 0x064C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__SPDIF_IN1 \
+ IOMUX_PAD(0x0578, 0x0270, 4, 0x07F0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__GPIO_4_31 \
+ IOMUX_PAD(0x0578, 0x0270, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__GPIO_4_31_INPUT \
+ IOMUX_PAD(0x0578, 0x0270, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_SD2_DAT5__MMDC_MMDC_DEBUG_35 \
+ IOMUX_PAD(0x0578, 0x0270, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT5__PL301_SIM_MX6SL_PER1_HADDR_20 \
+ IOMUX_PAD(0x0578, 0x0270, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT6__USDHC2_DAT6_50MHZ \
+ IOMUX_PAD(0x057C, 0x0274, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__USDHC2_DAT6_100MHZ \
+ IOMUX_PAD(0x057C, 0x0274, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT6__USDHC2_DAT6_200MHZ \
+ IOMUX_PAD(0x057C, 0x0274, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT6__USDHC3_DAT6 \
+ IOMUX_PAD(0x057C, 0x0274, 1, 0x0844, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__UART2_CTS \
+ IOMUX_PAD(0x057C, 0x0274, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__UART2_RTS \
+ IOMUX_PAD(0x057C, 0x0274, 2, 0x0800, 4, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__CSI_D_8 \
+ IOMUX_PAD(0x057C, 0x0274, 3, 0x0650, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__USDHC2_WP \
+ IOMUX_PAD(0x057C, 0x0274, 4, 0x0834, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__GPIO_4_29 \
+ IOMUX_PAD(0x057C, 0x0274, 5, 0x0000, 0, NO_PAD_I)
+#define MX6SL_PAD_SD2_DAT6__GPIO_4_29_OUTPUT \
+ IOMUX_PAD(0x057C, 0x0274, 5, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__MMDC_MMDC_DEBUG_34 \
+ IOMUX_PAD(0x057C, 0x0274, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT6__PL301_SIM_MX6SL_PER1_HADDR_19 \
+ IOMUX_PAD(0x057C, 0x0274, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_DAT7__USDHC2_DAT7_50MHZ \
+ IOMUX_PAD(0x0580, 0x0278, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__USDHC2_DAT7_100MHZ \
+ IOMUX_PAD(0x0580, 0x0278, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD2_DAT7__USDHC2_DAT7_200MHZ \
+ IOMUX_PAD(0x0580, 0x0278, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD2_DAT7__USDHC3_DAT7 \
+ IOMUX_PAD(0x0580, 0x0278, 1, 0x0848, 1, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__UART2_CTS \
+ IOMUX_PAD(0x0580, 0x0278, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__UART2_RTS \
+ IOMUX_PAD(0x0580, 0x0278, 2, 0x0800, 5, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__CSI_D_9 \
+ IOMUX_PAD(0x0580, 0x0278, 3, 0x0654, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__USDHC2_CD \
+ IOMUX_PAD(0x0580, 0x0278, 4, 0x0830, 2, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__GPIO_5_0 \
+ IOMUX_PAD(0x0580, 0x0278, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__MMDC_MMDC_DEBUG_33 \
+ IOMUX_PAD(0x0580, 0x0278, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_DAT7__PL301_SIM_MX6SL_PER1_HADDR_16 \
+ IOMUX_PAD(0x0580, 0x0278, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD2_RST__USDHC2_RST \
+ IOMUX_PAD(0x0584, 0x027C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__FEC_REF_OUT \
+ IOMUX_PAD(0x0584, 0x027C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__WDOG2_WDOG_B \
+ IOMUX_PAD(0x0584, 0x027C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__SPDIF_OUT1 \
+ IOMUX_PAD(0x0584, 0x027C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__CSI_MCLK \
+ IOMUX_PAD(0x0584, 0x027C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__GPIO_4_27 \
+ IOMUX_PAD(0x0584, 0x027C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL/*NO_PAD_CTRL*/)
+#define MX6SL_PAD_SD2_RST__ANATOP_ANATOP_TESTO_12 \
+ IOMUX_PAD(0x0584, 0x027C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD2_RST__PL301_SIM_MX6SL_PER1_HBURST_2 \
+ IOMUX_PAD(0x0584, 0x027C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_CLK__USDHC3_CLK_50MHZ \
+ IOMUX_PAD(0x0588, 0x0280, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__USDHC3_CLK_100MHZ \
+ IOMUX_PAD(0x0588, 0x0280, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_CLK__USDHC3_CLK_200MHZ \
+ IOMUX_PAD(0x0588, 0x0280, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_CLK__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x0588, 0x0280, 1, 0x0608, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__KPP_COL_5 \
+ IOMUX_PAD(0x0588, 0x0280, 2, 0x0748, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__CSI_D_10 \
+ IOMUX_PAD(0x0588, 0x0280, 3, 0x0658, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__WDOG1_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x0588, 0x0280, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__GPIO_5_18 \
+ IOMUX_PAD(0x0588, 0x0280, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__USB_USBOTG1_PWR \
+ IOMUX_PAD(0x0588, 0x0280, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CLK__PL301_SIM_MX6SL_PER1_HADDR_13 \
+ IOMUX_PAD(0x0588, 0x0280, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_CMD__USDHC3_CMD_50MHZ \
+ IOMUX_PAD(0x058C, 0x0284, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__USDHC3_CMD_100MHZ \
+ IOMUX_PAD(0x058C, 0x0284, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_CMD__USDHC3_CMD_200MHZ \
+ IOMUX_PAD(0x058C, 0x0284, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_CMD__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x058C, 0x0284, 1, 0x0604, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__KPP_ROW_5 \
+ IOMUX_PAD(0x058C, 0x0284, 2, 0x0768, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__CSI_D_11 \
+ IOMUX_PAD(0x058C, 0x0284, 3, 0x065C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__ANATOP_USBOTG2_ID \
+ IOMUX_PAD(0x058C, 0x0284, 4, 0x05E0, 3, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__GPIO_5_21 \
+ IOMUX_PAD(0x058C, 0x0284, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__USB_USBOTG2_PWR \
+ IOMUX_PAD(0x058C, 0x0284, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_CMD__PL301_SIM_MX6SL_PER1_HADDR_18 \
+ IOMUX_PAD(0x058C, 0x0284, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ \
+ IOMUX_PAD(0x0590, 0x0288, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_100MHZ \
+ IOMUX_PAD(0x0590, 0x0288, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_DAT0__USDHC3_DAT0_200MHZ \
+ IOMUX_PAD(0x0590, 0x0288, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_DAT0__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x0590, 0x0288, 1, 0x05FC, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__KPP_COL_6 \
+ IOMUX_PAD(0x0590, 0x0288, 2, 0x074C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__CSI_D_12 \
+ IOMUX_PAD(0x0590, 0x0288, 3, 0x0660, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__ANATOP_USBOTG1_ID \
+ IOMUX_PAD(0x0590, 0x0288, 4, 0x05DC, 4, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__GPIO_5_19 \
+ IOMUX_PAD(0x0590, 0x0288, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__SJC_JTAG_ACT \
+ IOMUX_PAD(0x0590, 0x0288, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT0__PL301_SIM_MX6SL_PER1_HADDR_11 \
+ IOMUX_PAD(0x0590, 0x0288, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ \
+ IOMUX_PAD(0x0594, 0x028C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_100MHZ \
+ IOMUX_PAD(0x0594, 0x028C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_DAT1__USDHC3_DAT1_200MHZ \
+ IOMUX_PAD(0x0594, 0x028C, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_DAT1__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x0594, 0x028C, 1, 0x060C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__KPP_ROW_6 \
+ IOMUX_PAD(0x0594, 0x028C, 2, 0x076C, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__CSI_D_13 \
+ IOMUX_PAD(0x0594, 0x028C, 3, 0x0664, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__USDHC1_VSELECT \
+ IOMUX_PAD(0x0594, 0x028C, 4, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__GPIO_5_20 \
+ IOMUX_PAD(0x0594, 0x028C, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__SJC_DE_B \
+ IOMUX_PAD(0x0594, 0x028C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT1__PL301_SIM_MX6SL_PER1_HADDR_17 \
+ IOMUX_PAD(0x0594, 0x028C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ \
+ IOMUX_PAD(0x0598, 0x0290, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_100MHZ \
+ IOMUX_PAD(0x0598, 0x0290, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_DAT2__USDHC3_DAT2_200MHZ \
+ IOMUX_PAD(0x0598, 0x0290, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_DAT2__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x0598, 0x0290, 1, 0x0610, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__KPP_COL_7 \
+ IOMUX_PAD(0x0598, 0x0290, 2, 0x0750, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__CSI_D_14 \
+ IOMUX_PAD(0x0598, 0x0290, 3, 0x0668, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__EPIT1_EPITO \
+ IOMUX_PAD(0x0598, 0x0290, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__GPIO_5_16 \
+ IOMUX_PAD(0x0598, 0x0290, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__USB_USBOTG2_OC \
+ IOMUX_PAD(0x0598, 0x0290, 6, 0x0820, 3, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT2__PL301_SIM_MX6SL_PER1_HADDR_14 \
+ IOMUX_PAD(0x0598, 0x0290, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ \
+ IOMUX_PAD(0x059C, 0x0294, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_100MHZ \
+ IOMUX_PAD(0x059C, 0x0294, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_100MHZ)
+#define MX6SL_PAD_SD3_DAT3__USDHC3_DAT3_200MHZ \
+ IOMUX_PAD(0x059C, 0x0294, 0, 0x0000, 0, MX6SL_USDHC_PAD_CTRL_200MHZ)
+#define MX6SL_PAD_SD3_DAT3__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x059C, 0x0294, 1, 0x0600, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__KPP_ROW_7 \
+ IOMUX_PAD(0x059C, 0x0294, 2, 0x0770, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__CSI_D_15 \
+ IOMUX_PAD(0x059C, 0x0294, 3, 0x066C, 1, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__EPIT2_EPITO \
+ IOMUX_PAD(0x059C, 0x0294, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__GPIO_5_17 \
+ IOMUX_PAD(0x059C, 0x0294, 5, 0x0000, 0, MX6SL_FLOAT_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__USB_USBOTG1_OC \
+ IOMUX_PAD(0x059C, 0x0294, 6, 0x0824, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_SD3_DAT3__PL301_SIM_MX6SL_PER1_HADDR_12 \
+ IOMUX_PAD(0x059C, 0x0294, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_TAMPER__SNVS_LP_WRAPPER_SNVS_TD1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_TEST_MODE__TCU_TEST_MODE \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_UART1_RXD__UART1_TXD \
+ IOMUX_PAD(0x05A0, 0x0298, 0, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__UART1_RXD \
+ IOMUX_PAD(0x05A0, 0x0298, 0, 0x07FC, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__PWM1_PWMO \
+ IOMUX_PAD(0x05A0, 0x0298, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__UART4_TXD \
+ IOMUX_PAD(0x05A0, 0x0298, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__UART4_RXD \
+ IOMUX_PAD(0x05A0, 0x0298, 2, 0x0814, 6, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__FEC_COL \
+ IOMUX_PAD(0x05A0, 0x0298, 3, 0x06F0, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__UART5_TXD \
+ IOMUX_PAD(0x05A0, 0x0298, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__UART5_RXD \
+ IOMUX_PAD(0x05A0, 0x0298, 4, 0x081C, 6, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__GPIO_3_16 \
+ IOMUX_PAD(0x05A0, 0x0298, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__ANATOP_ANATOP_TESTI_2 \
+ IOMUX_PAD(0x05A0, 0x0298, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_RXD__TPSMP_CLK \
+ IOMUX_PAD(0x05A0, 0x0298, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6SL_PAD_UART1_TXD__UART1_TXD \
+ IOMUX_PAD(0x05A4, 0x029C, 0, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART1_RXD \
+ IOMUX_PAD(0x05A4, 0x029C, 0, 0x07FC, 1, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__PWM2_PWMO \
+ IOMUX_PAD(0x05A4, 0x029C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART4_TXD \
+ IOMUX_PAD(0x05A4, 0x029C, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART4_RXD \
+ IOMUX_PAD(0x05A4, 0x029C, 2, 0x0814, 7, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__FEC_RX_CLK \
+ IOMUX_PAD(0x05A4, 0x029C, 3, 0x0700, 2, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART5_TXD \
+ IOMUX_PAD(0x05A4, 0x029C, 4, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART5_RXD \
+ IOMUX_PAD(0x05A4, 0x029C, 4, 0x081C, 7, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__GPIO_3_17 \
+ IOMUX_PAD(0x05A4, 0x029C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__ANATOP_ANATOP_TESTI_3 \
+ IOMUX_PAD(0x05A4, 0x029C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_UART1_TXD__UART5_DCD \
+ IOMUX_PAD(0x05A4, 0x029C, 7, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+
+#define MX6SL_PAD_WDOG_B__WDOG1_WDOG_B \
+ IOMUX_PAD(0x05A8, 0x02A0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_WDOG_B__WDOG1_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x05A8, 0x02A0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_WDOG_B__UART5_RI \
+ IOMUX_PAD(0x05A8, 0x02A0, 2, 0x0000, 0, MX6SL_UART_PAD_CTRL)
+#define MX6SL_PAD_WDOG_B__GPIO_3_18 \
+ IOMUX_PAD(0x05A8, 0x02A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6SL_PAD_WDOG_B__OBSERVE_MUX_OUT_2 \
+ IOMUX_PAD(0x05A8, 0x02A0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX6SL_H__*/
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h
new file mode 100644
index 00000000..c07d3021
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Holger Schurig <hs4233@mail.mn-solutions.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#ifndef __MACH_IOMUX_V1_H__
+#define __MACH_IOMUX_V1_H__
+
+/*
+* GPIO Module and I/O Multiplexer
+* x = 0..3 for reg_A, reg_B, reg_C, reg_D
+*/
+#define MXC_DDIR(x) (0x00 + ((x) << 8))
+#define MXC_OCR1(x) (0x04 + ((x) << 8))
+#define MXC_OCR2(x) (0x08 + ((x) << 8))
+#define MXC_ICONFA1(x) (0x0c + ((x) << 8))
+#define MXC_ICONFA2(x) (0x10 + ((x) << 8))
+#define MXC_ICONFB1(x) (0x14 + ((x) << 8))
+#define MXC_ICONFB2(x) (0x18 + ((x) << 8))
+#define MXC_DR(x) (0x1c + ((x) << 8))
+#define MXC_GIUS(x) (0x20 + ((x) << 8))
+#define MXC_SSR(x) (0x24 + ((x) << 8))
+#define MXC_ICR1(x) (0x28 + ((x) << 8))
+#define MXC_ICR2(x) (0x2c + ((x) << 8))
+#define MXC_IMR(x) (0x30 + ((x) << 8))
+#define MXC_ISR(x) (0x34 + ((x) << 8))
+#define MXC_GPR(x) (0x38 + ((x) << 8))
+#define MXC_SWR(x) (0x3c + ((x) << 8))
+#define MXC_PUEN(x) (0x40 + ((x) << 8))
+
+#define MX1_NUM_GPIO_PORT 4
+#define MX21_NUM_GPIO_PORT 6
+#define MX27_NUM_GPIO_PORT 6
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
+#define GPIO_OUT (1 << 8)
+#define GPIO_IN (0 << 8)
+#define GPIO_PUEN (1 << 9)
+
+#define GPIO_PF (1 << 10)
+#define GPIO_AF (1 << 11)
+
+#define GPIO_OCR_SHIFT 12
+#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT)
+#define GPIO_AIN (0 << GPIO_OCR_SHIFT)
+#define GPIO_BIN (1 << GPIO_OCR_SHIFT)
+#define GPIO_CIN (2 << GPIO_OCR_SHIFT)
+#define GPIO_GPIO (3 << GPIO_OCR_SHIFT)
+
+#define GPIO_AOUT_SHIFT 14
+#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT)
+#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT)
+
+#define GPIO_BOUT_SHIFT 16
+#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT)
+#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT)
+
+/* decode irq number to use with IMR(x), ISR(x) and friends */
+#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
+
+#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x)
+#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x)
+#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x)
+#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x)
+#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x)
+#define IRQ_GPIOF(x) (IRQ_GPIOE(32) + x)
+
+extern int mxc_gpio_mode(int gpio_mode);
+extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+ const char *label);
+extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count);
+
+extern int __init imx_iomuxv1_init(void __iomem *base, int numports);
+
+#endif /* __MACH_IOMUX_V1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
new file mode 100644
index 00000000..55350c5b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IOMUX_V3_H__
+#define __MACH_IOMUX_V3_H__
+
+/*
+ * build IOMUX_PAD structure
+ *
+ * This iomux scheme is based around pads, which are the physical balls
+ * on the processor.
+ *
+ * - Each pad has a pad control register (IOMUXC_SW_PAD_CTRL_x) which controls
+ * things like driving strength and pullup/pulldown.
+ * - Each pad can have but not necessarily does have an output routing register
+ * (IOMUXC_SW_MUX_CTL_PAD_x).
+ * - Each pad can have but not necessarily does have an input routing register
+ * (IOMUXC_x_SELECT_INPUT)
+ *
+ * The three register sets do not have a fixed offset to each other,
+ * hence we order this table by pad control registers (which all pads
+ * have) and put the optional i/o routing registers into additional
+ * fields.
+ *
+ * The naming convention for the pad modes is MX35_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named
+ * GPIO_<unit>_<num>
+ *
+ * IOMUX/PAD Bit field definitions
+ *
+ * MUX_CTRL_OFS: 0..11 (12)
+ * PAD_CTRL_OFS: 12..23 (12)
+ * SEL_INPUT_OFS: 24..35 (12)
+ * MUX_MODE + SION: 36..40 (5)
+ * PAD_CTRL + NO_PAD_CTRL: 41..58 (18)
+ * SEL_INP: 59..62 (4)
+ * reserved: 63 (1)
+*/
+
+typedef u64 iomux_v3_cfg_t;
+
+#define MUX_CTRL_OFS_SHIFT 0
+#define MUX_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_CTRL_OFS_SHIFT)
+#define MUX_PAD_CTRL_OFS_SHIFT 12
+#define MUX_PAD_CTRL_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_PAD_CTRL_OFS_SHIFT)
+#define MUX_SEL_INPUT_OFS_SHIFT 24
+#define MUX_SEL_INPUT_OFS_MASK ((iomux_v3_cfg_t)0xfff << MUX_SEL_INPUT_OFS_SHIFT)
+
+#define MUX_MODE_SHIFT 36
+#define MUX_MODE_MASK ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT)
+#define MUX_PAD_CTRL_SHIFT 41
+//#define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x3ffff << MUX_PAD_CTRL_SHIFT)
+#define MUX_PAD_CTRL_MASK ((iomux_v3_cfg_t)0x43ffff << MUX_PAD_CTRL_SHIFT)
+#define MUX_SEL_INPUT_SHIFT 59
+#define MUX_SEL_INPUT_MASK ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT)
+
+#define MUX_PAD_CTRL(x) ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
+
+#define IOMUX_PAD(_pad_ctrl_ofs, _mux_ctrl_ofs, _mux_mode, _sel_input_ofs, \
+ _sel_input, _pad_ctrl) \
+ (((iomux_v3_cfg_t)(_mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_mux_mode) << MUX_MODE_SHIFT) | \
+ ((iomux_v3_cfg_t)(_pad_ctrl_ofs) << MUX_PAD_CTRL_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_pad_ctrl) << MUX_PAD_CTRL_SHIFT) | \
+ ((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \
+ ((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT))
+
+#define NEW_PAD_CTRL(cfg, pad) (((cfg) & ~MUX_PAD_CTRL_MASK) | \
+ MUX_PAD_CTRL(pad))
+/*
+ * Use to set PAD control
+ */
+#define NO_PAD_CTRL (1 << 17)
+#define NO_PAD_I 0
+#define NO_MUX_I 0
+#ifdef CONFIG_SOC_IMX6Q
+#define PAD_CTL_LVE (1 << 22)
+#define PAD_CTL_LVE_MASK (1 << 22)
+#define PAD_CTL_DDR_SEL_LPDDR2 (2 << 18)
+#define PAD_CTL_DDR_SEL_DDR3 (3 << 18)
+#define PAD_CTL_DDR_SEL_MASK (3 << 18)
+#define PAD_CTL_HYS (1 << 16)
+
+#define PAD_CTL_PUS_100K_DOWN (0 << 14)
+#define PAD_CTL_PUS_47K_UP (1 << 14)
+#define PAD_CTL_PUS_100K_UP (2 << 14)
+#define PAD_CTL_PUS_22K_UP (3 << 14)
+
+#define PAD_CTL_PUE (1 << 13)
+#define PAD_CTL_PKE (1 << 12)
+#define PAD_CTL_ODE (1 << 11)
+
+#define PAD_CTL_SPEED_LOW (1 << 6)
+#define PAD_CTL_SPEED_MED (2 << 6)
+#define PAD_CTL_SPEED_HIGH (3 << 6)
+
+#define PAD_CTL_DSE_DISABLE (0 << 3)
+#define PAD_CTL_DSE_240ohm (1 << 3)
+#define PAD_CTL_DSE_120ohm (2 << 3)
+#define PAD_CTL_DSE_80ohm (3 << 3)
+#define PAD_CTL_DSE_60ohm (4 << 3)
+#define PAD_CTL_DSE_48ohm (5 << 3)
+#define PAD_CTL_DSE_40ohm (6 << 3)
+#define PAD_CTL_DSE_34ohm (7 << 3)
+
+#define PAD_CTL_SRE_FAST (1 << 0)
+#define PAD_CTL_SRE_SLOW (0 << 0)
+
+#else
+#define PAD_CTL_DVS (1 << 13)
+#define PAD_CTL_HYS (1 << 8)
+
+#define PAD_CTL_PKE (1 << 7)
+#define PAD_CTL_PUE (1 << 6 | PAD_CTL_PKE)
+#define PAD_CTL_PUS_100K_DOWN (0 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_47K_UP (1 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP (2 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP (3 << 4 | PAD_CTL_PUE)
+
+#define PAD_CTL_ODE (1 << 3)
+
+#define PAD_CTL_DSE_LOW (0 << 1)
+#define PAD_CTL_DSE_MED (1 << 1)
+#define PAD_CTL_DSE_HIGH (2 << 1)
+#define PAD_CTL_DSE_MAX (3 << 1)
+
+#define PAD_CTL_SRE_FAST (1 << 0)
+#define PAD_CTL_SRE_SLOW (0 << 0)
+#endif
+#define IOMUX_CONFIG_SION (0x1 << 4)
+
+#define MX51_NUM_GPIO_PORT 4
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
+/*
+ * read/write a single pad in the iomuxer
+ */
+int mxc_iomux_v3_get_pad(iomux_v3_cfg_t *pad);
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
+
+/*
+ * read/write mutliple pads
+ * convenient way to call the above function with tables
+ */
+ int mxc_iomux_v3_get_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count);
+int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base);
+
+/*
+ * Set bits for general purpose registers
+ */
+void mxc_iomux_set_gpr_register(int group, int start_bit, int num_bits, int value);
+
+/*
+ * Set special bits for iomux registers, such as LVE bit, DDR_SEL bits
+ */
+void mxc_iomux_set_specialbits_register(u32 pad_addr, u32 value, u32 mask);
+
+#endif /* __MACH_IOMUX_V3_H__*/
+
diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h
new file mode 100644
index 00000000..3d226d7e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Uwe Kleine-Koenig, Pengutronix
+ *
+ * This program is free software; you can 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_IOMUX_H__
+#define __MACH_IOMUX_H__
+
+/* This file will go away, please include mach/iomux-mx... directly */
+
+#ifdef CONFIG_ARCH_MX1
+#include <mach/iomux-mx1.h>
+#endif
+#ifdef CONFIG_ARCH_MX2
+#include <mach/iomux-mx2x.h>
+#ifdef CONFIG_MACH_MX21
+#include <mach/iomux-mx21.h>
+#endif
+#ifdef CONFIG_MACH_MX27
+#include <mach/iomux-mx27.h>
+#endif
+#endif
+
+#endif /* __MACH_IOMUX_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/ipu-v3.h b/arch/arm/plat-mxc/include/mach/ipu-v3.h
new file mode 100755
index 00000000..e2265d40
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ipu-v3.h
@@ -0,0 +1,765 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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_IPU_V3_H_
+#define __MACH_IPU_V3_H_
+
+#include <linux/ipu.h>
+
+/* IPU Driver channels definitions. */
+/* Note these are different from IDMA channels */
+#define IPU_MAX_CH 32
+#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
+ ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
+#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
+#define IPU_CHAN_ID(ch) (ch >> 24)
+#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
+#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
+#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
+#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
+#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
+#define NO_DMA 0x3F
+#define ALT 1
+/*!
+ * Enumeration of IPU logical channels. An IPU logical channel is defined as a
+ * combination of an input (memory to IPU), output (IPU to memory), and/or
+ * secondary input IDMA channels and in some cases an Image Converter task.
+ * Some channels consist of only an input or output.
+ */
+typedef enum {
+ CHAN_NONE = -1,
+ MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
+ MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
+ MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
+
+ MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
+ MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
+ MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
+
+ MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
+ MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
+ MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
+ MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
+
+ MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
+ MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
+ MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
+ MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
+
+ DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+ DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+
+ CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
+ CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
+ CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
+ CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
+
+ CSI_MEM = CSI_MEM0,
+
+ CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
+ CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
+
+ /* for vdi mem->vdi->ic->mem , add graphics plane and alpha*/
+ MEM_VDI_PRP_VF_MEM_P = _MAKE_CHAN(21, 8, 14, 17, 21),
+ MEM_VDI_PRP_VF_MEM = _MAKE_CHAN(22, 9, 14, 17, 21),
+ MEM_VDI_PRP_VF_MEM_N = _MAKE_CHAN(23, 10, 14, 17, 21),
+
+ /* for vdi mem->vdi->mem */
+ MEM_VDI_MEM_P = _MAKE_CHAN(24, 8, NO_DMA, NO_DMA, 5),
+ MEM_VDI_MEM = _MAKE_CHAN(25, 9, NO_DMA, NO_DMA, 5),
+ MEM_VDI_MEM_N = _MAKE_CHAN(26, 10, NO_DMA, NO_DMA, 5),
+
+ /* fake channel for vdoa to link with IPU */
+ MEM_VDOA_MEM = _MAKE_CHAN(27, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+
+ MEM_PP_ADC = CHAN_NONE,
+ ADC_SYS2 = CHAN_NONE,
+
+} ipu_channel_t;
+
+/*!
+ * Enumeration of types of buffers for a logical channel.
+ */
+typedef enum {
+ IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
+ IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
+ IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
+ IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
+ IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
+ IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
+} ipu_buffer_t;
+
+#define IPU_PANEL_SERIAL 1
+#define IPU_PANEL_PARALLEL 2
+
+/*!
+ * Enumeration of ADC channel operation mode.
+ */
+typedef enum {
+ Disable,
+ WriteTemplateNonSeq,
+ ReadTemplateNonSeq,
+ WriteTemplateUnCon,
+ ReadTemplateUnCon,
+ WriteDataWithRS,
+ WriteDataWoRS,
+ WriteCmd
+} mcu_mode_t;
+
+/*!
+ * Enumeration of ADC channel addressing mode.
+ */
+typedef enum {
+ FullWoBE,
+ FullWithBE,
+ XY
+} display_addressing_t;
+
+/*!
+ * Union of initialization parameters for a logical channel.
+ */
+typedef union {
+ struct {
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ bool interlaced;
+ } csi_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ } csi_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ } mem_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ } mem_rot_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ ipu_motion_sel motion_sel;
+ enum v4l2_field field_fmt;
+ uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
+ } csi_prp_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } csi_prp_vf_adc;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ ipu_motion_sel motion_sel;
+ enum v4l2_field field_fmt;
+ } mem_prp_vf_mem;
+ struct {
+ uint32_t temp;
+ } mem_prp_vf_adc;
+ struct {
+ uint32_t temp;
+ } mem_rot_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ } mem_pp_mem;
+ struct {
+ uint32_t temp;
+ } mem_rot_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } mem_pp_adc;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ } mem_dc_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_fg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ bool alpha_chan_en;
+ } mem_dp_bg_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_bg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ bool alpha_chan_en;
+ } mem_dp_fg_sync;
+ struct {
+ uint32_t di;
+ } direct_async;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys1;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys2;
+} ipu_channel_params_t;
+
+/*
+ * IPU_IRQF_ONESHOT - Interrupt is not reenabled after the irq handler finished.
+ */
+#define IPU_IRQF_NONE 0x00000000
+#define IPU_IRQF_ONESHOT 0x00000001
+
+/*!
+ * Enumeration of IPU interrupt sources.
+ */
+enum ipu_irq_line {
+ IPU_IRQ_CSI0_OUT_EOF = 0,
+ IPU_IRQ_CSI1_OUT_EOF = 1,
+ IPU_IRQ_CSI2_OUT_EOF = 2,
+ IPU_IRQ_CSI3_OUT_EOF = 3,
+ IPU_IRQ_VDIC_OUT_EOF = 5,
+ IPU_IRQ_VDI_P_IN_EOF = 8,
+ IPU_IRQ_VDI_C_IN_EOF = 9,
+ IPU_IRQ_VDI_N_IN_EOF = 10,
+ IPU_IRQ_PP_IN_EOF = 11,
+ IPU_IRQ_PRP_IN_EOF = 12,
+ IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
+ IPU_IRQ_PP_GRAPH_IN_EOF = 15,
+ IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
+ IPU_IRQ_PP_ALPHA_IN_EOF = 18,
+ IPU_IRQ_PRP_ENC_OUT_EOF = 20,
+ IPU_IRQ_PRP_VF_OUT_EOF = 21,
+ IPU_IRQ_PP_OUT_EOF = 22,
+ IPU_IRQ_BG_SYNC_EOF = 23,
+ IPU_IRQ_BG_ASYNC_EOF = 24,
+ IPU_IRQ_FG_SYNC_EOF = 27,
+ IPU_IRQ_DC_SYNC_EOF = 28,
+ IPU_IRQ_FG_ASYNC_EOF = 29,
+ IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
+
+ IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
+ IPU_IRQ_DC_READ_EOF = 40,
+ IPU_IRQ_DC_ASYNC_EOF = 41,
+ IPU_IRQ_DC_CMD1_EOF = 42,
+ IPU_IRQ_DC_CMD2_EOF = 43,
+ IPU_IRQ_DC_MASK_EOF = 44,
+ IPU_IRQ_PRP_ENC_ROT_IN_EOF = 45,
+ IPU_IRQ_PRP_VF_ROT_IN_EOF = 46,
+ IPU_IRQ_PP_ROT_IN_EOF = 47,
+ IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 48,
+ IPU_IRQ_PRP_VF_ROT_OUT_EOF = 49,
+ IPU_IRQ_PP_ROT_OUT_EOF = 50,
+ IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
+ IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
+
+ IPU_IRQ_BG_SYNC_NFACK = 64 + 23,
+ IPU_IRQ_FG_SYNC_NFACK = 64 + 27,
+ IPU_IRQ_DC_SYNC_NFACK = 64 + 28,
+
+ IPU_IRQ_DP_SF_START = 448 + 2,
+ IPU_IRQ_DP_SF_END = 448 + 3,
+ IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
+ IPU_IRQ_DC_FC_0 = 448 + 8,
+ IPU_IRQ_DC_FC_1 = 448 + 9,
+ IPU_IRQ_DC_FC_2 = 448 + 10,
+ IPU_IRQ_DC_FC_3 = 448 + 11,
+ IPU_IRQ_DC_FC_4 = 448 + 12,
+ IPU_IRQ_DC_FC_6 = 448 + 13,
+ IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
+ IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
+
+ IPU_IRQ_COUNT
+};
+
+/*!
+ * Bitfield of Display Interface signal polarities.
+ */
+typedef struct {
+ unsigned datamask_en:1;
+ unsigned int_clk:1;
+ unsigned interlaced:1;
+ unsigned odd_field_first:1;
+ unsigned clksel_en:1;
+ unsigned clkidle_en:1;
+ unsigned data_pol:1; /* true = inverted */
+ unsigned clk_pol:1; /* true = rising edge */
+ unsigned enable_pol:1;
+ unsigned Hsync_pol:1; /* true = active high */
+ unsigned Vsync_pol:1;
+} ipu_di_signal_cfg_t;
+
+/*!
+ * Bitfield of CSI signal polarities and modes.
+ */
+
+typedef struct {
+ unsigned data_width:4;
+ unsigned clk_mode:3;
+ unsigned ext_vsync:1;
+ unsigned Vsync_pol:1;
+ unsigned Hsync_pol:1;
+ unsigned pixclk_pol:1;
+ unsigned data_pol:1;
+ unsigned sens_clksrc:1;
+ unsigned pack_tight:1;
+ unsigned force_eof:1;
+ unsigned data_en_pol:1;
+ unsigned data_fmt;
+ unsigned csi;
+ unsigned mclk;
+} ipu_csi_signal_cfg_t;
+
+/*!
+ * Enumeration of CSI data bus widths.
+ */
+enum {
+ IPU_CSI_DATA_WIDTH_4 = 0,
+ IPU_CSI_DATA_WIDTH_8 = 1,
+ IPU_CSI_DATA_WIDTH_10 = 3,
+ IPU_CSI_DATA_WIDTH_16 = 9,
+};
+
+/*!
+ * Enumeration of CSI clock modes.
+ */
+enum {
+ IPU_CSI_CLK_MODE_GATED_CLK,
+ IPU_CSI_CLK_MODE_NONGATED_CLK,
+ IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
+ IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
+};
+
+enum {
+ IPU_CSI_MIPI_DI0,
+ IPU_CSI_MIPI_DI1,
+ IPU_CSI_MIPI_DI2,
+ IPU_CSI_MIPI_DI3,
+};
+
+typedef enum {
+ RGB,
+ YCbCr,
+ YUV
+} ipu_color_space_t;
+
+/*!
+ * Enumeration of ADC vertical sync mode.
+ */
+typedef enum {
+ VsyncNone,
+ VsyncInternal,
+ VsyncCSI,
+ VsyncExternal
+} vsync_t;
+
+typedef enum {
+ DAT,
+ CMD
+} cmddata_t;
+
+/*!
+ * Enumeration of ADC display update mode.
+ */
+typedef enum {
+ IPU_ADC_REFRESH_NONE,
+ IPU_ADC_AUTO_REFRESH,
+ IPU_ADC_AUTO_REFRESH_SNOOP,
+ IPU_ADC_SNOOPING,
+} ipu_adc_update_mode_t;
+
+/*!
+ * Enumeration of ADC display interface types (serial or parallel).
+ */
+enum {
+ IPU_ADC_IFC_MODE_SYS80_TYPE1,
+ IPU_ADC_IFC_MODE_SYS80_TYPE2,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE1,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE2,
+ IPU_ADC_IFC_MODE_3WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_4WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
+};
+
+enum {
+ IPU_ADC_IFC_WIDTH_8,
+ IPU_ADC_IFC_WIDTH_16,
+};
+
+/*!
+ * Enumeration of ADC display interface burst mode.
+ */
+enum {
+ IPU_ADC_BURST_WCS,
+ IPU_ADC_BURST_WBLCK,
+ IPU_ADC_BURST_NONE,
+ IPU_ADC_BURST_SERIAL,
+};
+
+/*!
+ * Enumeration of ADC display interface RW signal timing modes.
+ */
+enum {
+ IPU_ADC_SER_NO_RW,
+ IPU_ADC_SER_RW_BEFORE_RS,
+ IPU_ADC_SER_RW_AFTER_RS,
+};
+
+/*!
+ * Bitfield of ADC signal polarities and modes.
+ */
+typedef struct {
+ unsigned data_pol:1;
+ unsigned clk_pol:1;
+ unsigned cs_pol:1;
+ unsigned rs_pol:1;
+ unsigned addr_pol:1;
+ unsigned read_pol:1;
+ unsigned write_pol:1;
+ unsigned Vsync_pol:1;
+ unsigned burst_pol:1;
+ unsigned burst_mode:2;
+ unsigned ifc_mode:3;
+ unsigned ifc_width:5;
+ unsigned ser_preamble_len:4;
+ unsigned ser_preamble:8;
+ unsigned ser_rw_mode:2;
+} ipu_adc_sig_cfg_t;
+
+/*!
+ * Enumeration of ADC template commands.
+ */
+enum {
+ RD_DATA,
+ RD_ACK,
+ RD_WAIT,
+ WR_XADDR,
+ WR_YADDR,
+ WR_ADDR,
+ WR_CMND,
+ WR_DATA,
+};
+
+/*!
+ * Enumeration of ADC template command flow control.
+ */
+enum {
+ SINGLE_STEP,
+ PAUSE,
+ STOP,
+};
+
+
+/*Define template constants*/
+#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
+#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
+
+/*!
+ * Define to create ADC template command entry.
+ */
+#define ipu_adc_template_gen(oc, rs, fc, dat) (((rs) << 29) | ((fc) << 27) | \
+ ((oc) << 24) | (dat))
+
+typedef struct {
+ u32 reg;
+ u32 value;
+} ipu_lpmc_reg_t;
+
+#define IPU_LPMC_REG_READ 0x80000000L
+
+#define CSI_MCLK_VF 1
+#define CSI_MCLK_ENC 2
+#define CSI_MCLK_RAW 4
+#define CSI_MCLK_I2C 8
+
+struct ipu_soc;
+/* Common IPU API */
+struct ipu_soc *ipu_get_soc(int id);
+int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel_params_t *params);
+void ipu_uninit_channel(struct ipu_soc *ipu, ipu_channel_t channel);
+void ipu_disable_hsp_clk(struct ipu_soc *ipu);
+
+static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
+{
+#ifdef CONFIG_MXC_IPU_V3D
+ return (rot < IPU_ROTATE_HORIZ_FLIP);
+#else
+ return (rot < IPU_ROTATE_90_RIGHT);
+#endif
+}
+
+int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ ipu_rotate_mode_t rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
+ dma_addr_t phyaddr_2,
+ uint32_t u_offset, uint32_t v_offset);
+
+int32_t ipu_update_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum, dma_addr_t phyaddr);
+
+int32_t ipu_update_channel_offset(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ uint32_t u, uint32_t v,
+ uint32_t vertical_offset, uint32_t horizontal_offset);
+
+int32_t ipu_select_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t bufNum);
+int32_t ipu_select_multi_vdi_buffer(struct ipu_soc *ipu, uint32_t bufNum);
+
+int32_t ipu_link_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
+int32_t ipu_unlink_channels(struct ipu_soc *ipu, ipu_channel_t src_ch, ipu_channel_t dest_ch);
+
+int32_t ipu_is_channel_busy(struct ipu_soc *ipu, ipu_channel_t channel);
+int32_t ipu_check_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum);
+void ipu_clear_buffer_ready(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum);
+uint32_t ipu_get_cur_buffer_idx(struct ipu_soc *ipu, ipu_channel_t channel, ipu_buffer_t type);
+int32_t ipu_enable_channel(struct ipu_soc *ipu, ipu_channel_t channel);
+int32_t ipu_disable_channel(struct ipu_soc *ipu, ipu_channel_t channel, bool wait_for_stop);
+int32_t ipu_swap_channel(struct ipu_soc *ipu, ipu_channel_t from_ch, ipu_channel_t to_ch);
+uint32_t ipu_channel_status(struct ipu_soc *ipu, ipu_channel_t channel);
+
+int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi);
+int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi);
+
+int ipu_lowpwr_display_enable(void);
+int ipu_lowpwr_display_disable(void);
+
+int ipu_enable_irq(struct ipu_soc *ipu, uint32_t irq);
+void ipu_disable_irq(struct ipu_soc *ipu, uint32_t irq);
+void ipu_clear_irq(struct ipu_soc *ipu, uint32_t irq);
+int ipu_request_irq(struct ipu_soc *ipu, uint32_t irq,
+ irqreturn_t(*handler) (int, void *),
+ uint32_t irq_flags, const char *devname, void *dev_id);
+void ipu_free_irq(struct ipu_soc *ipu, uint32_t irq, void *dev_id);
+bool ipu_get_irq_status(struct ipu_soc *ipu, uint32_t irq);
+void ipu_set_csc_coefficients(struct ipu_soc *ipu, ipu_channel_t channel, int32_t param[][3]);
+int32_t ipu_set_channel_bandmode(struct ipu_soc *ipu, ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t band_height);
+
+/* two stripe calculations */
+struct stripe_param{
+ unsigned int input_width; /* width of the input stripe */
+ unsigned int output_width; /* width of the output stripe */
+ unsigned int input_column; /* the first column on the input stripe */
+ unsigned int output_column; /* the first column on the output stripe */
+ unsigned int idr;
+ /* inverse downisizing ratio parameter; expressed as a power of 2 */
+ unsigned int irr;
+ /* inverse resizing ratio parameter; expressed as a multiple of 2^-13 */
+};
+int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
+ unsigned int output_frame_width,
+ const unsigned int maximal_stripe_width,
+ const unsigned long long cirr,
+ const unsigned int equal_stripes,
+ u32 input_pixelformat,
+ u32 output_pixelformat,
+ struct stripe_param *left,
+ struct stripe_param *right);
+
+/* SDC API */
+int32_t ipu_init_sync_panel(struct ipu_soc *ipu, int disp,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
+
+void ipu_uninit_sync_panel(struct ipu_soc *ipu, int disp);
+
+int32_t ipu_disp_set_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t x_pos,
+ int16_t y_pos);
+int32_t ipu_disp_get_window_pos(struct ipu_soc *ipu, ipu_channel_t channel, int16_t *x_pos,
+ int16_t *y_pos);
+int32_t ipu_disp_set_global_alpha(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ uint8_t alpha);
+int32_t ipu_disp_set_color_key(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ uint32_t colorKey);
+int32_t ipu_disp_set_gamma_correction(struct ipu_soc *ipu, ipu_channel_t channel, bool enable,
+ int constk[], int slopek[]);
+
+int ipu_init_async_panel(struct ipu_soc *ipu, int disp, int type, uint32_t cycle_time,
+ uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
+void ipu_disp_direct_write(struct ipu_soc *ipu, ipu_channel_t channel, u32 value, u32 offset);
+void ipu_reset_disp_panel(struct ipu_soc *ipu);
+
+/* CMOS Sensor Interface API */
+int32_t ipu_csi_init_interface(struct ipu_soc *ipu, uint16_t width, uint16_t height,
+ uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
+
+int32_t ipu_csi_get_sensor_protocol(struct ipu_soc *ipu, uint32_t csi);
+
+int32_t ipu_csi_enable_mclk(struct ipu_soc *ipu, int src, bool flag, bool wait);
+
+static inline int32_t ipu_csi_enable_mclk_if(struct ipu_soc *ipu, int src, uint32_t csi,
+ bool flag, bool wait)
+{
+ return ipu_csi_enable_mclk(ipu, csi, flag, wait);
+}
+
+int ipu_csi_read_mclk_flag(void);
+
+void ipu_csi_flash_strobe(bool flag);
+
+void ipu_csi_get_window_size(struct ipu_soc *ipu, uint32_t *width, uint32_t *height, uint32_t csi);
+
+void ipu_csi_set_window_size(struct ipu_soc *ipu, uint32_t width, uint32_t height, uint32_t csi);
+
+void ipu_csi_set_window_pos(struct ipu_soc *ipu, uint32_t left, uint32_t top, uint32_t csi);
+
+uint32_t bytes_per_pixel(uint32_t fmt);
+
+struct ipuv3_fb_platform_data {
+ char disp_dev[32];
+ u32 interface_pix_fmt;
+ char *mode_str;
+ int default_bpp;
+ bool int_clk;
+
+ /* reserved mem */
+ resource_size_t res_base[2];
+ resource_size_t res_size[2];
+
+ /*
+ * Late init to avoid display channel being
+ * re-initialized as we've probably setup the
+ * channel in bootloader.
+ */
+ bool late_init;
+};
+
+struct imx_ipuv3_platform_data {
+ int rev;
+ int (*init) (int);
+ void (*pg) (int);
+
+ char *csi_clk[2];
+
+ /*
+ * Bypass reset to avoid display channel being
+ * stopped by probe since it may starts to work
+ * in bootloader.
+ */
+ bool bypass_reset;
+};
+
+#endif /* __MACH_IPU_V3_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/arch/arm/plat-mxc/include/mach/ipu.h
new file mode 100644
index 00000000..a9221f1c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ipu.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * Copyright (C) 2005-2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _IPU_H_
+#define _IPU_H_
+
+#include <linux/types.h>
+#include <linux/dmaengine.h>
+
+/* IPU DMA Controller channel definitions. */
+enum ipu_channel {
+ IDMAC_IC_0 = 0, /* IC (encoding task) to memory */
+ IDMAC_IC_1 = 1, /* IC (viewfinder task) to memory */
+ IDMAC_ADC_0 = 1,
+ IDMAC_IC_2 = 2,
+ IDMAC_ADC_1 = 2,
+ IDMAC_IC_3 = 3,
+ IDMAC_IC_4 = 4,
+ IDMAC_IC_5 = 5,
+ IDMAC_IC_6 = 6,
+ IDMAC_IC_7 = 7, /* IC (sensor data) to memory */
+ IDMAC_IC_8 = 8,
+ IDMAC_IC_9 = 9,
+ IDMAC_IC_10 = 10,
+ IDMAC_IC_11 = 11,
+ IDMAC_IC_12 = 12,
+ IDMAC_IC_13 = 13,
+ IDMAC_SDC_0 = 14, /* Background synchronous display data */
+ IDMAC_SDC_1 = 15, /* Foreground data (overlay) */
+ IDMAC_SDC_2 = 16,
+ IDMAC_SDC_3 = 17,
+ IDMAC_ADC_2 = 18,
+ IDMAC_ADC_3 = 19,
+ IDMAC_ADC_4 = 20,
+ IDMAC_ADC_5 = 21,
+ IDMAC_ADC_6 = 22,
+ IDMAC_ADC_7 = 23,
+ IDMAC_PF_0 = 24,
+ IDMAC_PF_1 = 25,
+ IDMAC_PF_2 = 26,
+ IDMAC_PF_3 = 27,
+ IDMAC_PF_4 = 28,
+ IDMAC_PF_5 = 29,
+ IDMAC_PF_6 = 30,
+ IDMAC_PF_7 = 31,
+};
+
+/* Order significant! */
+enum ipu_channel_status {
+ IPU_CHANNEL_FREE,
+ IPU_CHANNEL_INITIALIZED,
+ IPU_CHANNEL_READY,
+ IPU_CHANNEL_ENABLED,
+};
+
+#define IPU_CHANNELS_NUM 32
+
+enum pixel_fmt {
+ /* 1 byte */
+ IPU_PIX_FMT_GENERIC,
+ IPU_PIX_FMT_RGB332,
+ IPU_PIX_FMT_YUV420P,
+ IPU_PIX_FMT_YUV422P,
+ IPU_PIX_FMT_YUV420P2,
+ IPU_PIX_FMT_YVU422P,
+ /* 2 bytes */
+ IPU_PIX_FMT_RGB565,
+ IPU_PIX_FMT_RGB666,
+ IPU_PIX_FMT_BGR666,
+ IPU_PIX_FMT_YUYV,
+ IPU_PIX_FMT_UYVY,
+ /* 3 bytes */
+ IPU_PIX_FMT_RGB24,
+ IPU_PIX_FMT_BGR24,
+ /* 4 bytes */
+ IPU_PIX_FMT_GENERIC_32,
+ IPU_PIX_FMT_RGB32,
+ IPU_PIX_FMT_BGR32,
+ IPU_PIX_FMT_ABGR32,
+ IPU_PIX_FMT_BGRA32,
+ IPU_PIX_FMT_RGBA32,
+};
+
+enum ipu_color_space {
+ IPU_COLORSPACE_RGB,
+ IPU_COLORSPACE_YCBCR,
+ IPU_COLORSPACE_YUV
+};
+
+/*
+ * Enumeration of IPU rotation modes
+ */
+enum ipu_rotate_mode {
+ /* Note the enum values correspond to BAM value */
+ IPU_ROTATE_NONE = 0,
+ IPU_ROTATE_VERT_FLIP = 1,
+ IPU_ROTATE_HORIZ_FLIP = 2,
+ IPU_ROTATE_180 = 3,
+ IPU_ROTATE_90_RIGHT = 4,
+ IPU_ROTATE_90_RIGHT_VFLIP = 5,
+ IPU_ROTATE_90_RIGHT_HFLIP = 6,
+ IPU_ROTATE_90_LEFT = 7,
+};
+
+struct ipu_platform_data {
+ unsigned int irq_base;
+};
+
+/*
+ * Enumeration of DI ports for ADC.
+ */
+enum display_port {
+ DISP0,
+ DISP1,
+ DISP2,
+ DISP3
+};
+
+struct idmac_video_param {
+ unsigned short in_width;
+ unsigned short in_height;
+ uint32_t in_pixel_fmt;
+ unsigned short out_width;
+ unsigned short out_height;
+ uint32_t out_pixel_fmt;
+ unsigned short out_stride;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ enum display_port disp;
+ unsigned short out_left;
+ unsigned short out_top;
+};
+
+/*
+ * Union of initialization parameters for a logical channel. So far only video
+ * parameters are used.
+ */
+union ipu_channel_param {
+ struct idmac_video_param video;
+};
+
+struct idmac_tx_desc {
+ struct dma_async_tx_descriptor txd;
+ struct scatterlist *sg; /* scatterlist for this */
+ unsigned int sg_len; /* tx-descriptor. */
+ struct list_head list;
+};
+
+struct idmac_channel {
+ struct dma_chan dma_chan;
+ dma_cookie_t completed; /* last completed cookie */
+ union ipu_channel_param params;
+ enum ipu_channel link; /* input channel, linked to the output */
+ enum ipu_channel_status status;
+ void *client; /* Only one client per channel */
+ unsigned int n_tx_desc;
+ struct idmac_tx_desc *desc; /* allocated tx-descriptors */
+ struct scatterlist *sg[2]; /* scatterlist elements in buffer-0 and -1 */
+ struct list_head free_list; /* free tx-descriptors */
+ struct list_head queue; /* queued tx-descriptors */
+ spinlock_t lock; /* protects sg[0,1], queue */
+ struct mutex chan_mutex; /* protects status, cookie, free_list */
+ bool sec_chan_en;
+ int active_buffer;
+ unsigned int eof_irq;
+ char eof_name[16]; /* EOF IRQ name for request_irq() */
+};
+
+#define to_tx_desc(tx) container_of(tx, struct idmac_tx_desc, txd)
+#define to_idmac_chan(c) container_of(c, struct idmac_channel, dma_chan)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/iram.h b/arch/arm/plat-mxc/include/mach/iram.h
new file mode 100644
index 00000000..022690c3
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iram.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/errno.h>
+
+#ifdef CONFIG_IRAM_ALLOC
+
+int __init iram_init(unsigned long base, unsigned long size);
+void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr);
+void iram_free(unsigned long dma_addr, unsigned int size);
+
+#else
+
+static inline int __init iram_init(unsigned long base, unsigned long size)
+{
+ return -ENOMEM;
+}
+
+static inline void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr)
+{
+ return NULL;
+}
+
+static inline void iram_free(unsigned long base, unsigned long size) {}
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
new file mode 100644
index 00000000..62282a95
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_IRQS_H__
+#define __ASM_ARCH_MXC_IRQS_H__
+
+/*
+ * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
+ */
+#ifdef CONFIG_MXC_TZIC
+#define MXC_INTERNAL_IRQS 128
+#elif defined CONFIG_ARM_GIC
+/* assuem 256 is enough for GIC */
+#define MXC_INTERNAL_IRQS 256
+#else
+#define MXC_INTERNAL_IRQS 64
+#endif
+
+#define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
+
+/* these are ordered by size to support multi-SoC kernels */
+#if defined CONFIG_SOC_IMX53
+#define MXC_GPIO_IRQS (32 * 7)
+#elif defined CONFIG_ARCH_MX2
+#define MXC_GPIO_IRQS (32 * 6)
+#elif defined CONFIG_SOC_IMX50
+#define MXC_GPIO_IRQS (32 * 6)
+#elif defined CONFIG_ARCH_MX1
+#define MXC_GPIO_IRQS (32 * 4)
+#elif defined CONFIG_ARCH_MX25
+#define MXC_GPIO_IRQS (32 * 4)
+#elif defined CONFIG_SOC_IMX51
+#define MXC_GPIO_IRQS (32 * 4)
+#elif defined CONFIG_ARCH_MX3
+#define MXC_GPIO_IRQS (32 * 3)
+#elif defined CONFIG_ARCH_MX6
+#define MXC_GPIO_IRQS (32 * 7)
+#endif
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXC_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXC_BOARD_IRQ_START (MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
+
+#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
+#define MXC_BOARD_IRQS 80
+#else
+#define MXC_BOARD_IRQS 16
+#endif
+
+#define MXC_IPU_IRQ_START (MXC_BOARD_IRQ_START + MXC_BOARD_IRQS)
+
+#ifdef CONFIG_MX3_IPU_IRQS
+#define MX3_IPU_IRQS CONFIG_MX3_IPU_IRQS
+#else
+#define MX3_IPU_IRQS 0
+#endif
+
+#ifdef CONFIG_ARCH_MX5
+#define MX5_IPU_IRQS (32*15)
+#else
+#define MX5_IPU_IRQS 0
+#endif
+
+#ifdef CONFIG_ARCH_MX6
+#define MX6_MSI_IRQS 128
+#else
+#define MX6_MSI_IRQS 0
+#endif
+
+#define IRQ_IMX_MSI_0 (MXC_IPU_IRQ_START + MX3_IPU_IRQS + MX5_IPU_IRQS)
+#define NR_IRQS (IRQ_IMX_MSI_0 + MX6_MSI_IRQS)
+
+extern int imx_irq_set_priority(unsigned char irq, unsigned char prio);
+
+/* all normal IRQs can be FIQs */
+#define FIQ_START 0
+/* switch between IRQ and FIQ */
+extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type);
+
+#endif /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
new file mode 100755
index 00000000..350ae0f9
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MXC_MEMORY_H__
+#define __ASM_ARCH_MXC_MEMORY_H__
+
+#include <asm/sizes.h>
+#include <asm/page.h>
+
+#define MX1_PHYS_OFFSET UL(0x08000000)
+#define MX21_PHYS_OFFSET UL(0xc0000000)
+#define MX25_PHYS_OFFSET UL(0x80000000)
+#define MX27_PHYS_OFFSET UL(0xa0000000)
+#define MX3x_PHYS_OFFSET UL(0x80000000)
+#define MX50_PHYS_OFFSET UL(0x70000000)
+#define MX51_PHYS_OFFSET UL(0x90000000)
+#define MX53_PHYS_OFFSET UL(0x70000000)
+#define MX6_PHYS_OFFSET UL(0x10000000)
+#define MX6SL_PHYS_OFFSET UL(0x80000000)
+
+#if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
+# if defined CONFIG_ARCH_MX1
+# define PLAT_PHYS_OFFSET MX1_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX21
+# define PLAT_PHYS_OFFSET MX21_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX25
+# define PLAT_PHYS_OFFSET MX25_PHYS_OFFSET
+# elif defined CONFIG_MACH_MX27
+# define PLAT_PHYS_OFFSET MX27_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX3
+# define PLAT_PHYS_OFFSET MX3x_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX50
+# define PLAT_PHYS_OFFSET MX50_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX51
+# define PLAT_PHYS_OFFSET MX51_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX53
+# define PLAT_PHYS_OFFSET MX53_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX50
+# define PLAT_PHYS_OFFSET MX50_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX6
+# define PLAT_PHYS_OFFSET MX6_PHYS_OFFSET
+# endif
+#endif
+
+#if defined(CONFIG_MX3_VIDEO)
+/*
+ * Increase size of DMA-consistent memory region.
+ * This is required for mx3 camera driver to capture at least two QXGA frames.
+ */
+#define CONSISTENT_DMA_SIZE SZ_8M
+
+#elif defined(CONFIG_MX1_VIDEO) || defined(CONFIG_VIDEO_MX2_HOSTSUPPORT)
+/*
+ * Increase size of DMA-consistent memory region.
+ * This is required for i.MX camera driver to capture at least four VGA frames.
+ */
+#define CONSISTENT_DMA_SIZE SZ_4M
+#else
+
+#ifndef CONFIG_ZONE_DMA
+#define CONSISTENT_DMA_SIZE (64 * SZ_1M)
+#elif defined(CONFIG_ARCH_MX5) || defined(CONFIG_ARCH_MX6)
+#define ARM_DMA_ZONE_SIZE (184 * SZ_1M)
+#define CONSISTENT_DMA_SIZE ARM_DMA_ZONE_SIZE
+#else
+#define CONSISTENT_DMA_SIZE (32 * SZ_1M)
+#endif
+
+#endif /* CONFIG_MX1_VIDEO || CONFIG_VIDEO_MX2_HOSTSUPPORT */
+
+
+#endif /* __ASM_ARCH_MXC_MEMORY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mipi_csi2.h b/arch/arm/plat-mxc/include/mach/mipi_csi2.h
new file mode 100644
index 00000000..7679027a
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mipi_csi2.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_MIPI_CSI2_H
+#define __INCLUDE_MIPI_CSI2_H
+
+/* mipi csi2 register */
+#define CSI2_VERSION 0x000
+#define CSI2_N_LANES (0x004/4)
+#define CSI2_PHY_SHUTDOWNZ (0x008/4)
+#define CSI2_DPHY_RSTZ (0x00c/4)
+#define CSI2_RESETN (0x010/4)
+#define CSI2_PHY_STATE (0x014/4)
+#define CSI2_DATA_IDS_1 (0x018/4)
+#define CSI2_DATA_IDS_2 (0x01c/4)
+#define CSI2_ERR1 (0x020/4)
+#define CSI2_ERR2 (0x024/4)
+#define CSI2_MSK1 (0x028/4)
+#define CSI2_MSK2 (0x02c/4)
+#define CSI2_PHY_TST_CTRL0 (0x030/4)
+#define CSI2_PHY_TST_CTRL1 (0x034/4)
+#define CSI2_SFT_RESET (0xf00/4)
+
+/* mipi data type */
+#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
+#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
+#define MIPI_DT_YUV422 0x1e /* UYVY... */
+#define MIPI_DT_RGB444 0x20
+#define MIPI_DT_RGB555 0x21
+#define MIPI_DT_RGB565 0x22
+#define MIPI_DT_RGB666 0x23
+#define MIPI_DT_RGB888 0x24
+#define MIPI_DT_RAW6 0x28
+#define MIPI_DT_RAW7 0x29
+#define MIPI_DT_RAW8 0x2a
+#define MIPI_DT_RAW10 0x2b
+#define MIPI_DT_RAW12 0x2c
+#define MIPI_DT_RAW14 0x2d
+
+
+struct mipi_csi2_info;
+/* mipi csi2 API */
+struct mipi_csi2_info *mipi_csi2_get_info(void);
+
+bool mipi_csi2_enable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_disable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_get_status(struct mipi_csi2_info *info);
+
+int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
+ unsigned int datatype);
+
+unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info);
+
+unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info);
+
+int mipi_csi2_pixelclk_enable(struct mipi_csi2_info *info);
+
+void mipi_csi2_pixelclk_disable(struct mipi_csi2_info *info);
+
+int mipi_csi2_reset(struct mipi_csi2_info *info);
+
+/**
+ * struct mipi_csi2_platform_data - MIPI CSI2 driver platform data.
+ *
+ * This structure communicates platform-specific information to the
+ * MIPI CSI2 driver that can't be expressed as resources.
+ *
+ * @ipu_id: the id of IPUs on which this MIPI CSI2 works
+ *
+ * @csi_id: the id of IPU CSI interfaces
+ *
+ * @v_channel: mipi virtual channel num
+ *
+ * @lanes: mipi lanes
+ *
+ * @init: A pointer to a function the driver will call to
+ * initialize the platform (e.g., set up the pin mux).
+ * @exit: A pointer to a function the driver will call to
+ * exit the platform (e.g., free pins).
+ */
+struct mipi_csi2_platform_data {
+ int ipu_id;
+ unsigned int csi_id;
+ unsigned int v_channel;
+ unsigned int lanes;
+ char *dphy_clk;
+ char *pixel_clk;
+ int (*init)(struct platform_device *);
+ void (*exit)(struct platform_device *);
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mipi_dsi.h b/arch/arm/plat-mxc/include/mach/mipi_dsi.h
new file mode 100644
index 00000000..0dd1f083
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mipi_dsi.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __INCLUDE_MIPI_DSI_H
+#define __INCLUDE_MIPI_DSI_H
+
+#define MIPI_DSI_VERSION (0x000)
+#define MIPI_DSI_PWR_UP (0x004)
+#define MIPI_DSI_CLKMGR_CFG (0x008)
+#define MIPI_DSI_DPI_CFG (0x00c)
+#define MIPI_DSI_DBI_CFG (0x010)
+#define MIPI_DSI_DBIS_CMDSIZE (0x014)
+#define MIPI_DSI_PCKHDL_CFG (0x018)
+#define MIPI_DSI_VID_MODE_CFG (0x01c)
+#define MIPI_DSI_VID_PKT_CFG (0x020)
+#define MIPI_DSI_CMD_MODE_CFG (0x024)
+#define MIPI_DSI_TMR_LINE_CFG (0x028)
+#define MIPI_DSI_VTIMING_CFG (0x02c)
+#define MIPI_DSI_PHY_TMR_CFG (0x030)
+#define MIPI_DSI_GEN_HDR (0x034)
+#define MIPI_DSI_GEN_PLD_DATA (0x038)
+#define MIPI_DSI_CMD_PKT_STATUS (0x03c)
+#define MIPI_DSI_TO_CNT_CFG (0x040)
+#define MIPI_DSI_ERROR_ST0 (0x044)
+#define MIPI_DSI_ERROR_ST1 (0x048)
+#define MIPI_DSI_ERROR_MSK0 (0x04c)
+#define MIPI_DSI_ERROR_MSK1 (0x050)
+#define MIPI_DSI_PHY_RSTZ (0x054)
+#define MIPI_DSI_PHY_IF_CFG (0x058)
+#define MIPI_DSI_PHY_IF_CTRL (0x05c)
+#define MIPI_DSI_PHY_STATUS (0x060)
+#define MIPI_DSI_PHY_TST_CTRL0 (0x064)
+#define MIPI_DSI_PHY_TST_CTRL1 (0x068)
+
+#define DSI_PWRUP_RESET (0x0 << 0)
+#define DSI_PWRUP_POWERUP (0x1 << 0)
+
+#define DSI_DPI_CFG_VID_SHIFT (0)
+#define DSI_DPI_CFG_VID_MASK (0x3)
+#define DSI_DPI_CFG_COLORCODE_SHIFT (2)
+#define DSI_DPI_CFG_COLORCODE_MASK (0x7)
+#define DSI_DPI_CFG_DATAEN_ACT_LOW (0x1 << 5)
+#define DSI_DPI_CFG_DATAEN_ACT_HIGH (0x0 << 5)
+#define DSI_DPI_CFG_VSYNC_ACT_LOW (0x1 << 6)
+#define DSI_DPI_CFG_VSYNC_ACT_HIGH (0x0 << 6)
+#define DSI_DPI_CFG_HSYNC_ACT_LOW (0x1 << 7)
+#define DSI_DPI_CFG_HSYNC_ACT_HIGH (0x0 << 7)
+#define DSI_DPI_CFG_SHUTD_ACT_LOW (0x1 << 8)
+#define DSI_DPI_CFG_SHUTD_ACT_HIGH (0x0 << 8)
+#define DSI_DPI_CFG_COLORMODE_ACT_LOW (0x1 << 9)
+#define DSI_DPI_CFG_COLORMODE_ACT_HIGH (0x0 << 9)
+#define DSI_DPI_CFG_EN18LOOSELY (0x1 << 10)
+
+#define DSI_PCKHDL_CFG_EN_EOTP_TX (0x1 << 0)
+#define DSI_PCKHDL_CFG_EN_EOTP_RX (0x1 << 1)
+#define DSI_PCKHDL_CFG_EN_BTA (0x1 << 2)
+#define DSI_PCKHDL_CFG_EN_ECC_RX (0x1 << 3)
+#define DSI_PCKHDL_CFG_EN_CRC_RX (0x1 << 4)
+#define DSI_PCKHDL_CFG_GEN_VID_RX_MASK (0x3)
+#define DSI_PCKHDL_CFG_GEN_VID_RX_SHIFT (5)
+
+#define DSI_VID_MODE_CFG_EN (0x1 << 0)
+#define DSI_VID_MODE_CFG_EN_BURSTMODE (0x3 << 1)
+#define DSI_VID_MODE_CFG_TYPE_MASK (0x3)
+#define DSI_VID_MODE_CFG_TYPE_SHIFT (1)
+#define DSI_VID_MODE_CFG_EN_LP_VSA (0x1 << 3)
+#define DSI_VID_MODE_CFG_EN_LP_VBP (0x1 << 4)
+#define DSI_VID_MODE_CFG_EN_LP_VFP (0x1 << 5)
+#define DSI_VID_MODE_CFG_EN_LP_VACT (0x1 << 6)
+#define DSI_VID_MODE_CFG_EN_LP_HBP (0x1 << 7)
+#define DSI_VID_MODE_CFG_EN_LP_HFP (0x1 << 8)
+#define DSI_VID_MODE_CFG_EN_MULTI_PKT (0x1 << 9)
+#define DSI_VID_MODE_CFG_EN_NULL_PKT (0x1 << 10)
+#define DSI_VID_MODE_CFG_EN_FRAME_ACK (0x1 << 11)
+#define DSI_VID_MODE_CFG_EN_LP_MODE (DSI_VID_MODE_CFG_EN_LP_VSA | \
+ DSI_VID_MODE_CFG_EN_LP_VBP | \
+ DSI_VID_MODE_CFG_EN_LP_VFP | \
+ DSI_VID_MODE_CFG_EN_LP_HFP | \
+ DSI_VID_MODE_CFG_EN_LP_HBP | \
+ DSI_VID_MODE_CFG_EN_LP_VACT)
+
+
+
+#define DSI_VID_PKT_CFG_VID_PKT_SZ_MASK (0x7ff)
+#define DSI_VID_PKT_CFG_VID_PKT_SZ_SHIFT (0)
+#define DSI_VID_PKT_CFG_NUM_CHUNKS_MASK (0x3ff)
+#define DSI_VID_PKT_CFG_NUM_CHUNKS_SHIFT (11)
+#define DSI_VID_PKT_CFG_NULL_PKT_SZ_MASK (0x3ff)
+#define DSI_VID_PKT_CFG_NULL_PKT_SZ_SHIFT (21)
+
+#define MIPI_DSI_CMD_MODE_CFG_EN_LOWPOWER (0x1FFF)
+#define MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE (0x1 << 0)
+
+#define DSI_TME_LINE_CFG_HSA_TIME_MASK (0x1ff)
+#define DSI_TME_LINE_CFG_HSA_TIME_SHIFT (0)
+#define DSI_TME_LINE_CFG_HBP_TIME_MASK (0x1ff)
+#define DSI_TME_LINE_CFG_HBP_TIME_SHIFT (9)
+#define DSI_TME_LINE_CFG_HLINE_TIME_MASK (0x3fff)
+#define DSI_TME_LINE_CFG_HLINE_TIME_SHIFT (18)
+
+#define DSI_VTIMING_CFG_VSA_LINES_MASK (0xf)
+#define DSI_VTIMING_CFG_VSA_LINES_SHIFT (0)
+#define DSI_VTIMING_CFG_VBP_LINES_MASK (0x3f)
+#define DSI_VTIMING_CFG_VBP_LINES_SHIFT (4)
+#define DSI_VTIMING_CFG_VFP_LINES_MASK (0x3f)
+#define DSI_VTIMING_CFG_VFP_LINES_SHIFT (10)
+#define DSI_VTIMING_CFG_V_ACT_LINES_MASK (0x7ff)
+#define DSI_VTIMING_CFG_V_ACT_LINES_SHIFT (16)
+
+#define DSI_PHY_TMR_CFG_BTA_TIME_MASK (0xfff)
+#define DSI_PHY_TMR_CFG_BTA_TIME_SHIFT (0)
+#define DSI_PHY_TMR_CFG_LP2HS_TIME_MASK (0xff)
+#define DSI_PHY_TMR_CFG_LP2HS_TIME_SHIFT (12)
+#define DSI_PHY_TMR_CFG_HS2LP_TIME_MASK (0xff)
+#define DSI_PHY_TMR_CFG_HS2LP_TIME_SHIFT (20)
+
+#define DSI_PHY_IF_CFG_N_LANES_MASK (0x3)
+#define DSI_PHY_IF_CFG_N_LANES_SHIFT (0)
+#define DSI_PHY_IF_CFG_WAIT_TIME_MASK (0xff)
+#define DSI_PHY_IF_CFG_WAIT_TIME_SHIFT (2)
+
+#define DSI_PHY_RSTZ_EN_CLK (0x1 << 2)
+#define DSI_PHY_RSTZ_DISABLE_RST (0x1 << 1)
+#define DSI_PHY_RSTZ_DISABLE_SHUTDOWN (0x1 << 0)
+#define DSI_PHY_RSTZ_RST (0x0)
+
+#define DSI_PHY_STATUS_LOCK (0x1 << 0)
+#define DSI_PHY_STATUS_STOPSTATE_CLK_LANE (0x1 << 2)
+
+#define DSI_GEN_HDR_TYPE_MASK (0xff)
+#define DSI_GEN_HDR_TYPE_SHIFT (0)
+#define DSI_GEN_HDR_DATA_MASK (0xffff)
+#define DSI_GEN_HDR_DATA_SHIFT (8)
+
+#define DSI_CMD_PKT_STATUS_GEN_CMD_EMPTY (0x1 << 0)
+#define DSI_CMD_PKT_STATUS_GEN_CMD_FULL (0x1 << 1)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_W_EMPTY (0x1 << 2)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_W_FULL (0x1 << 3)
+#define DSI_CMD_PKT_STATUS_GEN_PLD_R_EMPTY (0x1 << 4)
+#define DSI_CMD_PKT_STATUS_GEN_RD_CMD_BUSY (0x1 << 6)
+
+#define DSI_ERROR_MSK0_ALL_MASK (0x1fffff)
+#define DSI_ERROR_MSK1_ALL_MASK (0x3ffff)
+
+#define DSI_PHY_IF_CTRL_RESET (0x0)
+#define DSI_PHY_IF_CTRL_TX_REQ_CLK_HS (0x1 << 0)
+#define DSI_PHY_IF_CTRL_TX_REQ_CLK_ULPS (0x1 << 1)
+#define DSI_PHY_IF_CTRL_TX_EXIT_CLK_ULPS (0x1 << 2)
+#define DSI_PHY_IF_CTRL_TX_REQ_DATA_ULPS (0x1 << 3)
+#define DSI_PHY_IF_CTRL_TX_EXIT_DATA_ULPS (0x1 << 4)
+#define DSI_PHY_IF_CTRL_TX_TRIG_MASK (0xF)
+#define DSI_PHY_IF_CTRL_TX_TRIG_SHIFT (5)
+
+#define DSI_PHY_CLK_INIT_COMMAND (0x44)
+#define DSI_GEN_PLD_DATA_BUF_SIZE (0x4)
+/**
+ * struct mipi_dsi_platform_data - MIPI DSI driver platform data.
+ *
+ * This structure communicates platform-specific information to the MIPI DSI
+ * driver that can't be expressed as resources.
+ *
+ * @ipu_id: the id of IPUs on which this MIPI DSI works
+ *
+ * @disp_id: the id of IPU display interfaces
+ *
+ * @lcd_panel: the supported mipi LCD panel string
+ *
+ * @init: A pointer to a function the driver will call to
+ * initialize the platform (e.g., set up the pin mux).
+ * @exit: A pointer to a function the driver will call to
+ * exit the platform (e.g., free pins).
+ * @io_regulator: io regulator name for MIPI DSI display module
+ *
+ * @core_regulator: core regulator name for MIPI DSI display module
+ *
+ * @analog_regulator: analog regulator name for MIPI DSI display module
+ *
+ * @io_volt: io regulator voltage for MIPI DSI display module
+ *
+ * @core_volt: core regulator voltage for MIPI DSI display module
+ *
+ * @analog_volt: analog regulator voltage for MIPI DSI display module
+ *
+ * @reset: A pointer to a function the driver will call to
+ * reset the MIPI DSI display module
+ * @lcd_power: A pointer to a function the drvier will call to
+ * configure the power of MIPI LCD panel
+ * @backlight_power: A pointer to a function the drvier will call to
+ * configure the power of MIPI LCD backlight
+ */
+struct mipi_dsi_platform_data {
+ /* SoC hardware information. */
+ int ipu_id;
+ int disp_id;
+ char *lcd_panel;
+ int (*init)(struct platform_device *);
+ void (*exit)(struct platform_device *);
+
+ /* board related information. */
+ char *io_regulator;
+ char *core_regulator;
+ char *analog_regulator;
+ int io_volt;
+ int core_volt;
+ int analog_volt;
+ void (*reset) (void);
+ void (*lcd_power)(int);
+ void (*backlight_power)(int);
+};
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mmc.h b/arch/arm/plat-mxc/include/mach/mmc.h
new file mode 100644
index 00000000..29115f40
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mmc.h
@@ -0,0 +1,39 @@
+#ifndef ASMARM_ARCH_MMC_H
+#define ASMARM_ARCH_MMC_H
+
+#include <linux/mmc/host.h>
+
+struct device;
+
+/* board specific SDHC data, optional.
+ * If not present, a writable card with 3,3V is assumed.
+ */
+struct imxmmc_platform_data {
+ /* Return values for the get_ro callback should be:
+ * 0 for a read/write card
+ * 1 for a read-only card
+ * -ENOSYS when not supported (equal to NULL callback)
+ * or a negative errno value when something bad happened
+ */
+ int (*get_ro)(struct device *);
+
+ /* board specific hook to (de)initialize the SD slot.
+ * The board code can call 'handler' on a card detection
+ * change giving data as argument.
+ */
+ int (*init)(struct device *dev, irq_handler_t handler, void *data);
+ void (*exit)(struct device *dev, void *data);
+
+ /* available voltages. If not given, assume
+ * MMC_VDD_32_33 | MMC_VDD_33_34
+ */
+ unsigned int ocr_avail;
+
+ /* adjust slot voltage */
+ void (*setpower)(struct device *, unsigned int vdd);
+
+ /* enable card detect using DAT3 */
+ int dat3_card_detect;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
new file mode 100644
index 00000000..97b19e78
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 1997,1998 Russell King
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can 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_MX1_H__
+#define __MACH_MX1_H__
+
+#include <mach/vmalloc.h>
+
+/*
+ * Memory map
+ */
+#define MX1_IO_BASE_ADDR 0x00200000
+#define MX1_IO_SIZE SZ_1M
+
+#define MX1_CS0_PHYS 0x10000000
+#define MX1_CS0_SIZE 0x02000000
+
+#define MX1_CS1_PHYS 0x12000000
+#define MX1_CS1_SIZE 0x01000000
+
+#define MX1_CS2_PHYS 0x13000000
+#define MX1_CS2_SIZE 0x01000000
+
+#define MX1_CS3_PHYS 0x14000000
+#define MX1_CS3_SIZE 0x01000000
+
+#define MX1_CS4_PHYS 0x15000000
+#define MX1_CS4_SIZE 0x01000000
+
+#define MX1_CS5_PHYS 0x16000000
+#define MX1_CS5_SIZE 0x01000000
+
+/*
+ * Register BASEs, based on OFFSETs
+ */
+#define MX1_AIPI1_BASE_ADDR (0x00000 + MX1_IO_BASE_ADDR)
+#define MX1_WDT_BASE_ADDR (0x01000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM1_BASE_ADDR (0x02000 + MX1_IO_BASE_ADDR)
+#define MX1_TIM2_BASE_ADDR (0x03000 + MX1_IO_BASE_ADDR)
+#define MX1_RTC_BASE_ADDR (0x04000 + MX1_IO_BASE_ADDR)
+#define MX1_LCDC_BASE_ADDR (0x05000 + MX1_IO_BASE_ADDR)
+#define MX1_UART1_BASE_ADDR (0x06000 + MX1_IO_BASE_ADDR)
+#define MX1_UART2_BASE_ADDR (0x07000 + MX1_IO_BASE_ADDR)
+#define MX1_PWM_BASE_ADDR (0x08000 + MX1_IO_BASE_ADDR)
+#define MX1_DMA_BASE_ADDR (0x09000 + MX1_IO_BASE_ADDR)
+#define MX1_AIPI2_BASE_ADDR (0x10000 + MX1_IO_BASE_ADDR)
+#define MX1_SIM_BASE_ADDR (0x11000 + MX1_IO_BASE_ADDR)
+#define MX1_USBD_BASE_ADDR (0x12000 + MX1_IO_BASE_ADDR)
+#define MX1_CSPI1_BASE_ADDR (0x13000 + MX1_IO_BASE_ADDR)
+#define MX1_MMC_BASE_ADDR (0x14000 + MX1_IO_BASE_ADDR)
+#define MX1_ASP_BASE_ADDR (0x15000 + MX1_IO_BASE_ADDR)
+#define MX1_BTA_BASE_ADDR (0x16000 + MX1_IO_BASE_ADDR)
+#define MX1_I2C_BASE_ADDR (0x17000 + MX1_IO_BASE_ADDR)
+#define MX1_SSI_BASE_ADDR (0x18000 + MX1_IO_BASE_ADDR)
+#define MX1_CSPI2_BASE_ADDR (0x19000 + MX1_IO_BASE_ADDR)
+#define MX1_MSHC_BASE_ADDR (0x1A000 + MX1_IO_BASE_ADDR)
+#define MX1_CCM_BASE_ADDR (0x1B000 + MX1_IO_BASE_ADDR)
+#define MX1_SCM_BASE_ADDR (0x1B804 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO_BASE_ADDR (0x1C000 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO1_BASE_ADDR (0x1C000 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO2_BASE_ADDR (0x1C100 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO3_BASE_ADDR (0x1C200 + MX1_IO_BASE_ADDR)
+#define MX1_GPIO4_BASE_ADDR (0x1C300 + MX1_IO_BASE_ADDR)
+#define MX1_EIM_BASE_ADDR (0x20000 + MX1_IO_BASE_ADDR)
+#define MX1_SDRAMC_BASE_ADDR (0x21000 + MX1_IO_BASE_ADDR)
+#define MX1_MMA_BASE_ADDR (0x22000 + MX1_IO_BASE_ADDR)
+#define MX1_AVIC_BASE_ADDR (0x23000 + MX1_IO_BASE_ADDR)
+#define MX1_CSI_BASE_ADDR (0x24000 + MX1_IO_BASE_ADDR)
+
+/* macro to get at IO space when running virtually */
+#define MX1_IO_P2V(x) IMX_IO_P2V(x)
+#define MX1_IO_ADDRESS(x) IOMEM(MX1_IO_P2V(x))
+
+/* fixed interrput numbers */
+#define MX1_INT_SOFTINT 0
+#define MX1_INT_CSI 6
+#define MX1_DSPA_MAC_INT 7
+#define MX1_DSPA_INT 8
+#define MX1_COMP_INT 9
+#define MX1_MSHC_XINT 10
+#define MX1_GPIO_INT_PORTA 11
+#define MX1_GPIO_INT_PORTB 12
+#define MX1_GPIO_INT_PORTC 13
+#define MX1_INT_LCDC 14
+#define MX1_SIM_INT 15
+#define MX1_SIM_DATA_INT 16
+#define MX1_RTC_INT 17
+#define MX1_RTC_SAMINT 18
+#define MX1_INT_UART2PFERR 19
+#define MX1_INT_UART2RTS 20
+#define MX1_INT_UART2DTR 21
+#define MX1_INT_UART2UARTC 22
+#define MX1_INT_UART2TX 23
+#define MX1_INT_UART2RX 24
+#define MX1_INT_UART1PFERR 25
+#define MX1_INT_UART1RTS 26
+#define MX1_INT_UART1DTR 27
+#define MX1_INT_UART1UARTC 28
+#define MX1_INT_UART1TX 29
+#define MX1_INT_UART1RX 30
+#define MX1_VOICE_DAC_INT 31
+#define MX1_VOICE_ADC_INT 32
+#define MX1_PEN_DATA_INT 33
+#define MX1_PWM_INT 34
+#define MX1_SDHC_INT 35
+#define MX1_INT_I2C 39
+#define MX1_INT_CSPI2 40
+#define MX1_INT_CSPI1 41
+#define MX1_SSI_TX_INT 42
+#define MX1_SSI_TX_ERR_INT 43
+#define MX1_SSI_RX_INT 44
+#define MX1_SSI_RX_ERR_INT 45
+#define MX1_TOUCH_INT 46
+#define MX1_INT_USBD0 47
+#define MX1_INT_USBD1 48
+#define MX1_INT_USBD2 49
+#define MX1_INT_USBD3 50
+#define MX1_INT_USBD4 51
+#define MX1_INT_USBD5 52
+#define MX1_INT_USBD6 53
+#define MX1_BTSYS_INT 55
+#define MX1_BTTIM_INT 56
+#define MX1_BTWUI_INT 57
+#define MX1_TIM2_INT 58
+#define MX1_TIM1_INT 59
+#define MX1_DMA_ERR 60
+#define MX1_DMA_INT 61
+#define MX1_GPIO_INT_PORTD 62
+#define MX1_WDT_INT 63
+
+/* DMA */
+#define MX1_DMA_REQ_UART3_T 2
+#define MX1_DMA_REQ_UART3_R 3
+#define MX1_DMA_REQ_SSI2_T 4
+#define MX1_DMA_REQ_SSI2_R 5
+#define MX1_DMA_REQ_CSI_STAT 6
+#define MX1_DMA_REQ_CSI_R 7
+#define MX1_DMA_REQ_MSHC 8
+#define MX1_DMA_REQ_DSPA_DCT_DOUT 9
+#define MX1_DMA_REQ_DSPA_DCT_DIN 10
+#define MX1_DMA_REQ_DSPA_MAC 11
+#define MX1_DMA_REQ_EXT 12
+#define MX1_DMA_REQ_SDHC 13
+#define MX1_DMA_REQ_SPI1_R 14
+#define MX1_DMA_REQ_SPI1_T 15
+#define MX1_DMA_REQ_SSI_T 16
+#define MX1_DMA_REQ_SSI_R 17
+#define MX1_DMA_REQ_ASP_DAC 18
+#define MX1_DMA_REQ_ASP_ADC 19
+#define MX1_DMA_REQ_USP_EP(x) (20 + (x))
+#define MX1_DMA_REQ_SPI2_R 26
+#define MX1_DMA_REQ_SPI2_T 27
+#define MX1_DMA_REQ_UART2_T 28
+#define MX1_DMA_REQ_UART2_R 29
+#define MX1_DMA_REQ_UART1_T 30
+#define MX1_DMA_REQ_UART1_R 31
+
+/*
+ * This doesn't depend on IMX_NEEDS_DEPRECATED_SYMBOLS
+ * to not break drivers/usb/gadget/imx_udc. Should go
+ * away after this driver uses the new name.
+ */
+#define USBD_INT0 MX1_INT_USBD0
+
+#endif /* ifndef __MACH_MX1_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx1_camera.h b/arch/arm/plat-mxc/include/mach/mx1_camera.h
new file mode 100644
index 00000000..4fd6c703
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx1_camera.h
@@ -0,0 +1,35 @@
+/*
+ * mx1_camera.h - i.MX1/i.MXL camera driver header file
+ *
+ * Copyright (c) 2008, Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (C) 2009, Darius Augulis <augulis.darius@gmail.com>
+ *
+ * Based on PXA camera.h file:
+ * Copyright (C) 2003, Intel Corporation
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_CAMERA_H_
+#define __ASM_ARCH_CAMERA_H_
+
+#define MX1_CAMERA_DATA_HIGH 1
+#define MX1_CAMERA_PCLK_RISING 2
+#define MX1_CAMERA_VSYNC_HIGH 4
+
+extern unsigned char mx1_camera_sof_fiq_start, mx1_camera_sof_fiq_end;
+
+/**
+ * struct mx1_camera_pdata - i.MX1/i.MXL camera platform data
+ * @mclk_10khz: master clock frequency in 10kHz units
+ * @flags: MX1 camera platform flags
+ */
+struct mx1_camera_pdata {
+ unsigned long mclk_10khz;
+ unsigned long flags;
+};
+
+#endif /* __ASM_ARCH_CAMERA_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/mx21-usbhost.h b/arch/arm/plat-mxc/include/mach/mx21-usbhost.h
new file mode 100644
index 00000000..22d0b596
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx21-usbhost.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Martin Fuzzey <mfuzzey@gmail.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.
+ */
+
+#ifndef __ASM_ARCH_MX21_USBH
+#define __ASM_ARCH_MX21_USBH
+
+enum mx21_usbh_xcvr {
+ /* Values below as used by hardware (HWMODE register) */
+ MX21_USBXCVR_TXDIF_RXDIF = 0,
+ MX21_USBXCVR_TXDIF_RXSE = 1,
+ MX21_USBXCVR_TXSE_RXDIF = 2,
+ MX21_USBXCVR_TXSE_RXSE = 3,
+};
+
+struct mx21_usbh_platform_data {
+ enum mx21_usbh_xcvr host_xcvr; /* tranceiver mode host 1,2 ports */
+ enum mx21_usbh_xcvr otg_xcvr; /* tranceiver mode otg (as host) port */
+ u16 enable_host1:1,
+ enable_host2:1,
+ enable_otg_host:1, /* enable "OTG" port (as host) */
+ host1_xcverless:1, /* traceiverless host1 port */
+ host1_txenoe:1, /* output enable host1 transmit enable */
+ otg_ext_xcvr:1, /* external tranceiver for OTG port */
+ unused:10;
+};
+
+#endif /* __ASM_ARCH_MX21_USBH */
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
new file mode 100644
index 00000000..6cd049eb
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Holger Schurig, hs4233@mail.mn-solutions.de
+ *
+ * This contains i.MX21-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MX21_H__
+#define __MACH_MX21_H__
+
+#define MX21_AIPI_BASE_ADDR 0x10000000
+#define MX21_AIPI_SIZE SZ_1M
+#define MX21_DMA_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x01000)
+#define MX21_WDOG_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x02000)
+#define MX21_GPT1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x03000)
+#define MX21_GPT2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x04000)
+#define MX21_GPT3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x05000)
+#define MX21_PWM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x06000)
+#define MX21_RTC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x07000)
+#define MX21_KPP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x08000)
+#define MX21_OWIRE_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x09000)
+#define MX21_UART1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0a000)
+#define MX21_UART2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0b000)
+#define MX21_UART3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0c000)
+#define MX21_UART4_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0d000)
+#define MX21_CSPI1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0e000)
+#define MX21_CSPI2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x0f000)
+#define MX21_SSI1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x10000)
+#define MX21_SSI2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x11000)
+#define MX21_I2C_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x12000)
+#define MX21_SDHC1_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x13000)
+#define MX21_SDHC2_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x14000)
+#define MX21_GPIO_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x15000)
+#define MX21_GPIO1_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x000)
+#define MX21_GPIO2_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x100)
+#define MX21_GPIO3_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x200)
+#define MX21_GPIO4_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x300)
+#define MX21_GPIO5_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x400)
+#define MX21_GPIO6_BASE_ADDR (MX21_GPIO_BASE_ADDR + 0x500)
+#define MX21_AUDMUX_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x16000)
+#define MX21_CSPI3_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x17000)
+#define MX21_LCDC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x21000)
+#define MX21_SLCDC_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x22000)
+#define MX21_USBOTG_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x24000)
+#define MX21_EMMA_PP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x26000)
+#define MX21_EMMA_PRP_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x26400)
+#define MX21_CCM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x27000)
+#define MX21_SYSCTRL_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x27800)
+#define MX21_JAM_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x3e000)
+#define MX21_MAX_BASE_ADDR (MX21_AIPI_BASE_ADDR + 0x3f000)
+
+#define MX21_AVIC_BASE_ADDR 0x10040000
+
+#define MX21_SAHB1_BASE_ADDR 0x80000000
+#define MX21_SAHB1_SIZE SZ_1M
+#define MX21_CSI_BASE_ADDR (MX2x_SAHB1_BASE_ADDR + 0x0000)
+
+/* Memory regions and CS */
+#define MX21_SDRAM_BASE_ADDR 0xc0000000
+#define MX21_CSD1_BASE_ADDR 0xc4000000
+
+#define MX21_CS0_BASE_ADDR 0xc8000000
+#define MX21_CS1_BASE_ADDR 0xcc000000
+#define MX21_CS2_BASE_ADDR 0xd0000000
+#define MX21_CS3_BASE_ADDR 0xd1000000
+#define MX21_CS4_BASE_ADDR 0xd2000000
+#define MX21_PCMCIA_MEM_BASE_ADDR 0xd4000000
+#define MX21_CS5_BASE_ADDR 0xdd000000
+
+/* NAND, SDRAM, WEIM etc controllers */
+#define MX21_X_MEMC_BASE_ADDR 0xdf000000
+#define MX21_X_MEMC_SIZE SZ_256K
+
+#define MX21_SDRAMC_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x0000)
+#define MX21_EIM_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x1000)
+#define MX21_PCMCIA_CTL_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x2000)
+#define MX21_NFC_BASE_ADDR (MX21_X_MEMC_BASE_ADDR + 0x3000)
+
+#define MX21_IRAM_BASE_ADDR 0xffffe800 /* internal ram */
+
+#define MX21_IO_P2V(x) IMX_IO_P2V(x)
+#define MX21_IO_ADDRESS(x) IOMEM(MX21_IO_P2V(x))
+
+/* fixed interrupt numbers */
+#define MX21_INT_CSPI3 6
+#define MX21_INT_GPIO 8
+#define MX21_INT_FIRI 9
+#define MX21_INT_SDHC2 10
+#define MX21_INT_SDHC1 11
+#define MX21_INT_I2C 12
+#define MX21_INT_SSI2 13
+#define MX21_INT_SSI1 14
+#define MX21_INT_CSPI2 15
+#define MX21_INT_CSPI1 16
+#define MX21_INT_UART4 17
+#define MX21_INT_UART3 18
+#define MX21_INT_UART2 19
+#define MX21_INT_UART1 20
+#define MX21_INT_KPP 21
+#define MX21_INT_RTC 22
+#define MX21_INT_PWM 23
+#define MX21_INT_GPT3 24
+#define MX21_INT_GPT2 25
+#define MX21_INT_GPT1 26
+#define MX21_INT_WDOG 27
+#define MX21_INT_PCMCIA 28
+#define MX21_INT_NFC 29
+#define MX21_INT_BMI 30
+#define MX21_INT_CSI 31
+#define MX21_INT_DMACH0 32
+#define MX21_INT_DMACH1 33
+#define MX21_INT_DMACH2 34
+#define MX21_INT_DMACH3 35
+#define MX21_INT_DMACH4 36
+#define MX21_INT_DMACH5 37
+#define MX21_INT_DMACH6 38
+#define MX21_INT_DMACH7 39
+#define MX21_INT_DMACH8 40
+#define MX21_INT_DMACH9 41
+#define MX21_INT_DMACH10 42
+#define MX21_INT_DMACH11 43
+#define MX21_INT_DMACH12 44
+#define MX21_INT_DMACH13 45
+#define MX21_INT_DMACH14 46
+#define MX21_INT_DMACH15 47
+#define MX21_INT_EMMAENC 49
+#define MX21_INT_EMMADEC 50
+#define MX21_INT_EMMAPRP 51
+#define MX21_INT_EMMAPP 52
+#define MX21_INT_USBWKUP 53
+#define MX21_INT_USBDMA 54
+#define MX21_INT_USBHOST 55
+#define MX21_INT_USBFUNC 56
+#define MX21_INT_USBMNP 57
+#define MX21_INT_USBCTRL 58
+#define MX21_INT_SLCDC 60
+#define MX21_INT_LCDC 61
+
+/* fixed DMA request numbers */
+#define MX21_DMA_REQ_CSPI3_RX 1
+#define MX21_DMA_REQ_CSPI3_TX 2
+#define MX21_DMA_REQ_EXT 3
+#define MX21_DMA_REQ_FIRI_RX 4
+#define MX21_DMA_REQ_SDHC2 6
+#define MX21_DMA_REQ_SDHC1 7
+#define MX21_DMA_REQ_SSI2_RX0 8
+#define MX21_DMA_REQ_SSI2_TX0 9
+#define MX21_DMA_REQ_SSI2_RX1 10
+#define MX21_DMA_REQ_SSI2_TX1 11
+#define MX21_DMA_REQ_SSI1_RX0 12
+#define MX21_DMA_REQ_SSI1_TX0 13
+#define MX21_DMA_REQ_SSI1_RX1 14
+#define MX21_DMA_REQ_SSI1_TX1 15
+#define MX21_DMA_REQ_CSPI2_RX 16
+#define MX21_DMA_REQ_CSPI2_TX 17
+#define MX21_DMA_REQ_CSPI1_RX 18
+#define MX21_DMA_REQ_CSPI1_TX 19
+#define MX21_DMA_REQ_UART4_RX 20
+#define MX21_DMA_REQ_UART4_TX 21
+#define MX21_DMA_REQ_UART3_RX 22
+#define MX21_DMA_REQ_UART3_TX 23
+#define MX21_DMA_REQ_UART2_RX 24
+#define MX21_DMA_REQ_UART2_TX 25
+#define MX21_DMA_REQ_UART1_RX 26
+#define MX21_DMA_REQ_UART1_TX 27
+#define MX21_DMA_REQ_BMI_TX 28
+#define MX21_DMA_REQ_BMI_RX 29
+#define MX21_DMA_REQ_CSI_STAT 30
+#define MX21_DMA_REQ_CSI_RX 31
+
+#endif /* ifndef __MACH_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
new file mode 100644
index 00000000..087cd7ac
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -0,0 +1,107 @@
+#ifndef __MACH_MX25_H__
+#define __MACH_MX25_H__
+
+#define MX25_AIPS1_BASE_ADDR 0x43f00000
+#define MX25_AIPS1_SIZE SZ_1M
+#define MX25_AIPS2_BASE_ADDR 0x53f00000
+#define MX25_AIPS2_SIZE SZ_1M
+#define MX25_AVIC_BASE_ADDR 0x68000000
+#define MX25_AVIC_SIZE SZ_1M
+
+#define MX25_I2C1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x80000)
+#define MX25_I2C3_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x84000)
+#define MX25_CAN1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x88000)
+#define MX25_CAN2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x8c000)
+#define MX25_I2C2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x98000)
+#define MX25_CSPI1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xa4000)
+#define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000)
+
+#define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
+#define MX25_GPT1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x90000)
+#define MX25_GPIO4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x9c000)
+#define MX25_PWM2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa0000)
+#define MX25_GPIO3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa4000)
+#define MX25_PWM3_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xa8000)
+#define MX25_PWM4_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xc8000)
+#define MX25_GPIO1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xcc000)
+#define MX25_GPIO2_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xd0000)
+#define MX25_WDOG_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xdc000)
+#define MX25_PWM1_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0xe0000)
+
+#define MX25_UART1_BASE_ADDR 0x43f90000
+#define MX25_UART2_BASE_ADDR 0x43f94000
+#define MX25_AUDMUX_BASE_ADDR 0x43fb0000
+#define MX25_UART3_BASE_ADDR 0x5000c000
+#define MX25_UART4_BASE_ADDR 0x50008000
+#define MX25_UART5_BASE_ADDR 0x5002c000
+
+#define MX25_CSPI3_BASE_ADDR 0x50004000
+#define MX25_CSPI2_BASE_ADDR 0x50010000
+#define MX25_FEC_BASE_ADDR 0x50038000
+#define MX25_SSI2_BASE_ADDR 0x50014000
+#define MX25_SSI1_BASE_ADDR 0x50034000
+#define MX25_NFC_BASE_ADDR 0xbb000000
+#define MX25_DRYICE_BASE_ADDR 0x53ffc000
+#define MX25_ESDHC1_BASE_ADDR 0x53fb4000
+#define MX25_ESDHC2_BASE_ADDR 0x53fb8000
+#define MX25_LCDC_BASE_ADDR 0x53fbc000
+#define MX25_KPP_BASE_ADDR 0x43fa8000
+#define MX25_SDMA_BASE_ADDR 0x53fd4000
+#define MX25_USB_BASE_ADDR 0x53ff4000
+#define MX25_USB_OTG_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0000)
+/*
+ * The reference manual (IMX25RM, Rev. 1, 06/2009) specifies an offset of 0x200
+ * for the host controller. Early documentation drafts specified 0x400 and
+ * Freescale internal sources confirm only the latter value to work.
+ */
+#define MX25_USB_HS_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0400)
+#define MX25_CSI_BASE_ADDR 0x53ff8000
+
+#define MX25_IO_P2V(x) IMX_IO_P2V(x)
+#define MX25_IO_ADDRESS(x) IOMEM(MX25_IO_P2V(x))
+
+#define MX25_INT_CSPI3 0
+#define MX25_INT_I2C1 3
+#define MX25_INT_I2C2 4
+#define MX25_INT_UART4 5
+#define MX25_INT_ESDHC2 8
+#define MX25_INT_ESDHC1 9
+#define MX25_INT_I2C3 10
+#define MX25_INT_SSI2 11
+#define MX25_INT_SSI1 12
+#define MX25_INT_CSPI2 13
+#define MX25_INT_CSPI1 14
+#define MX25_INT_GPIO3 16
+#define MX25_INT_CSI 17
+#define MX25_INT_UART3 18
+#define MX25_INT_GPIO4 23
+#define MX25_INT_KPP 24
+#define MX25_INT_DRYICE 25
+#define MX25_INT_PWM1 26
+#define MX25_INT_UART2 32
+#define MX25_INT_NFC 33
+#define MX25_INT_SDMA 34
+#define MX25_INT_USB_HS 35
+#define MX25_INT_PWM2 36
+#define MX25_INT_USB_OTG 37
+#define MX25_INT_LCDC 39
+#define MX25_INT_UART5 40
+#define MX25_INT_PWM3 41
+#define MX25_INT_PWM4 42
+#define MX25_INT_CAN1 43
+#define MX25_INT_CAN2 44
+#define MX25_INT_UART1 45
+#define MX25_INT_GPIO2 51
+#define MX25_INT_GPIO1 52
+#define MX25_INT_FEC 57
+
+#define MX25_DMA_REQ_SSI2_RX1 22
+#define MX25_DMA_REQ_SSI2_TX1 23
+#define MX25_DMA_REQ_SSI2_RX0 24
+#define MX25_DMA_REQ_SSI2_TX0 25
+#define MX25_DMA_REQ_SSI1_RX1 26
+#define MX25_DMA_REQ_SSI1_TX1 27
+#define MX25_DMA_REQ_SSI1_RX0 28
+#define MX25_DMA_REQ_SSI1_TX0 29
+
+#endif /* ifndef __MACH_MX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
new file mode 100644
index 00000000..1dc1c522
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This contains i.MX27-specific hardware definitions. For those
+ * hardware pieces that are common between i.MX21 and i.MX27, have a
+ * look at mx2x.h.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MX27_H__
+#define __MACH_MX27_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+#define MX27_AIPI_BASE_ADDR 0x10000000
+#define MX27_AIPI_SIZE SZ_1M
+#define MX27_DMA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x01000)
+#define MX27_WDOG_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x02000)
+#define MX27_GPT1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x03000)
+#define MX27_GPT2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x04000)
+#define MX27_GPT3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x05000)
+#define MX27_PWM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x06000)
+#define MX27_RTC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x07000)
+#define MX27_KPP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x08000)
+#define MX27_OWIRE_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x09000)
+#define MX27_UART1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0a000)
+#define MX27_UART2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0b000)
+#define MX27_UART3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0c000)
+#define MX27_UART4_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0d000)
+#define MX27_CSPI1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0e000)
+#define MX27_CSPI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0f000)
+#define MX27_SSI1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x10000)
+#define MX27_SSI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x11000)
+#define MX27_I2C1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x12000)
+#define MX27_SDHC1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x13000)
+#define MX27_SDHC2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x14000)
+#define MX27_GPIO_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x15000)
+#define MX27_GPIO1_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x000)
+#define MX27_GPIO2_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x100)
+#define MX27_GPIO3_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x200)
+#define MX27_GPIO4_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x300)
+#define MX27_GPIO5_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x400)
+#define MX27_GPIO6_BASE_ADDR (MX27_GPIO_BASE_ADDR + 0x500)
+#define MX27_AUDMUX_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x16000)
+#define MX27_CSPI3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x17000)
+#define MX27_MSHC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x18000)
+#define MX27_GPT4_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x19000)
+#define MX27_GPT5_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1a000)
+#define MX27_UART5_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1b000)
+#define MX27_UART6_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1c000)
+#define MX27_I2C2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1d000)
+#define MX27_SDHC3_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1e000)
+#define MX27_GPT6_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x1f000)
+#define MX27_LCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x21000)
+#define MX27_SLCDC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x22000)
+#define MX27_VPU_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x23000)
+#define MX27_USB_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x24000)
+#define MX27_USB_OTG_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0000)
+#define MX27_USB_HS1_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0200)
+#define MX27_USB_HS2_BASE_ADDR (MX27_USB_BASE_ADDR + 0x0400)
+#define MX27_SAHARA_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x25000)
+#define MX27_EMMAPP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26000)
+#define MX27_EMMAPRP_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x26400)
+#define MX27_CCM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27000)
+#define MX27_SYSCTRL_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x27800)
+#define MX27_IIM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x28000)
+#define MX27_RTIC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2a000)
+#define MX27_FEC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2b000)
+#define MX27_SCC_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x2c000)
+#define MX27_ETB_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3b000)
+#define MX27_ETB_RAM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3c000)
+#define MX27_JAM_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3e000)
+#define MX27_MAX_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x3f000)
+
+#define MX27_AVIC_BASE_ADDR 0x10040000
+
+/* ROM patch */
+#define MX27_ROMP_BASE_ADDR 0x10041000
+
+#define MX27_SAHB1_BASE_ADDR 0x80000000
+#define MX27_SAHB1_SIZE SZ_1M
+#define MX27_CSI_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x0000)
+#define MX27_ATA_BASE_ADDR (MX27_SAHB1_BASE_ADDR + 0x1000)
+
+/* Memory regions and CS */
+#define MX27_SDRAM_BASE_ADDR 0xa0000000
+#define MX27_CSD1_BASE_ADDR 0xb0000000
+
+#define MX27_CS0_BASE_ADDR 0xc0000000
+#define MX27_CS1_BASE_ADDR 0xc8000000
+#define MX27_CS2_BASE_ADDR 0xd0000000
+#define MX27_CS3_BASE_ADDR 0xd2000000
+#define MX27_CS4_BASE_ADDR 0xd4000000
+#define MX27_CS5_BASE_ADDR 0xd6000000
+
+/* NAND, SDRAM, WEIM, M3IF, EMI controllers */
+#define MX27_X_MEMC_BASE_ADDR 0xd8000000
+#define MX27_X_MEMC_SIZE SZ_1M
+#define MX27_NFC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR)
+#define MX27_SDRAMC_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x1000)
+#define MX27_WEIM_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x2000)
+#define MX27_M3IF_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x3000)
+#define MX27_PCMCIA_CTL_BASE_ADDR (MX27_X_MEMC_BASE_ADDR + 0x4000)
+
+#define MX27_WEIM_CSCRx_BASE_ADDR(cs) (MX27_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX27_WEIM_CSCRxU(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX27_WEIM_CSCRxL(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX27_WEIM_CSCRxA(cs) (MX27_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
+#define MX27_PCMCIA_MEM_BASE_ADDR 0xdc000000
+
+/* IRAM */
+#define MX27_IRAM_BASE_ADDR 0xffff4c00 /* internal ram */
+
+#define MX27_IO_P2V(x) IMX_IO_P2V(x)
+#define MX27_IO_ADDRESS(x) IOMEM(MX27_IO_P2V(x))
+
+#ifndef __ASSEMBLER__
+static inline void mx27_setup_weimcs(size_t cs,
+ unsigned upper, unsigned lower, unsigned addional)
+{
+ __raw_writel(upper, MX27_IO_ADDRESS(MX27_WEIM_CSCRxU(cs)));
+ __raw_writel(lower, MX27_IO_ADDRESS(MX27_WEIM_CSCRxL(cs)));
+ __raw_writel(addional, MX27_IO_ADDRESS(MX27_WEIM_CSCRxA(cs)));
+}
+#endif
+
+/* fixed interrupt numbers */
+#define MX27_INT_I2C2 1
+#define MX27_INT_GPT6 2
+#define MX27_INT_GPT5 3
+#define MX27_INT_GPT4 4
+#define MX27_INT_RTIC 5
+#define MX27_INT_CSPI3 6
+#define MX27_INT_SDHC 7
+#define MX27_INT_GPIO 8
+#define MX27_INT_SDHC3 9
+#define MX27_INT_SDHC2 10
+#define MX27_INT_SDHC1 11
+#define MX27_INT_I2C1 12
+#define MX27_INT_SSI2 13
+#define MX27_INT_SSI1 14
+#define MX27_INT_CSPI2 15
+#define MX27_INT_CSPI1 16
+#define MX27_INT_UART4 17
+#define MX27_INT_UART3 18
+#define MX27_INT_UART2 19
+#define MX27_INT_UART1 20
+#define MX27_INT_KPP 21
+#define MX27_INT_RTC 22
+#define MX27_INT_PWM 23
+#define MX27_INT_GPT3 24
+#define MX27_INT_GPT2 25
+#define MX27_INT_GPT1 26
+#define MX27_INT_WDOG 27
+#define MX27_INT_PCMCIA 28
+#define MX27_INT_NFC 29
+#define MX27_INT_ATA 30
+#define MX27_INT_CSI 31
+#define MX27_INT_DMACH0 32
+#define MX27_INT_DMACH1 33
+#define MX27_INT_DMACH2 34
+#define MX27_INT_DMACH3 35
+#define MX27_INT_DMACH4 36
+#define MX27_INT_DMACH5 37
+#define MX27_INT_DMACH6 38
+#define MX27_INT_DMACH7 39
+#define MX27_INT_DMACH8 40
+#define MX27_INT_DMACH9 41
+#define MX27_INT_DMACH10 42
+#define MX27_INT_DMACH11 43
+#define MX27_INT_DMACH12 44
+#define MX27_INT_DMACH13 45
+#define MX27_INT_DMACH14 46
+#define MX27_INT_DMACH15 47
+#define MX27_INT_UART6 48
+#define MX27_INT_UART5 49
+#define MX27_INT_FEC 50
+#define MX27_INT_EMMAPRP 51
+#define MX27_INT_EMMAPP 52
+#define MX27_INT_VPU 53
+#define MX27_INT_USB_HS1 54
+#define MX27_INT_USB_HS2 55
+#define MX27_INT_USB_OTG 56
+#define MX27_INT_SCC_SMN 57
+#define MX27_INT_SCC_SCM 58
+#define MX27_INT_SAHARA 59
+#define MX27_INT_SLCDC 60
+#define MX27_INT_LCDC 61
+#define MX27_INT_IIM 62
+#define MX27_INT_CCM 63
+
+/* fixed DMA request numbers */
+#define MX27_DMA_REQ_CSPI3_RX 1
+#define MX27_DMA_REQ_CSPI3_TX 2
+#define MX27_DMA_REQ_EXT 3
+#define MX27_DMA_REQ_MSHC 4
+#define MX27_DMA_REQ_SDHC2 6
+#define MX27_DMA_REQ_SDHC1 7
+#define MX27_DMA_REQ_SSI2_RX0 8
+#define MX27_DMA_REQ_SSI2_TX0 9
+#define MX27_DMA_REQ_SSI2_RX1 10
+#define MX27_DMA_REQ_SSI2_TX1 11
+#define MX27_DMA_REQ_SSI1_RX0 12
+#define MX27_DMA_REQ_SSI1_TX0 13
+#define MX27_DMA_REQ_SSI1_RX1 14
+#define MX27_DMA_REQ_SSI1_TX1 15
+#define MX27_DMA_REQ_CSPI2_RX 16
+#define MX27_DMA_REQ_CSPI2_TX 17
+#define MX27_DMA_REQ_CSPI1_RX 18
+#define MX27_DMA_REQ_CSPI1_TX 19
+#define MX27_DMA_REQ_UART4_RX 20
+#define MX27_DMA_REQ_UART4_TX 21
+#define MX27_DMA_REQ_UART3_RX 22
+#define MX27_DMA_REQ_UART3_TX 23
+#define MX27_DMA_REQ_UART2_RX 24
+#define MX27_DMA_REQ_UART2_TX 25
+#define MX27_DMA_REQ_UART1_RX 26
+#define MX27_DMA_REQ_UART1_TX 27
+#define MX27_DMA_REQ_ATA_TX 28
+#define MX27_DMA_REQ_ATA_RCV 29
+#define MX27_DMA_REQ_CSI_STAT 30
+#define MX27_DMA_REQ_CSI_RX 31
+#define MX27_DMA_REQ_UART5_TX 32
+#define MX27_DMA_REQ_UART5_RX 33
+#define MX27_DMA_REQ_UART6_TX 34
+#define MX27_DMA_REQ_UART6_RX 35
+#define MX27_DMA_REQ_SDHC3 36
+#define MX27_DMA_REQ_NFC 37
+
+#ifndef __ASSEMBLY__
+extern int mx27_revision(void);
+#endif
+
+#endif /* ifndef __MACH_MX27_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx2_cam.h b/arch/arm/plat-mxc/include/mach/mx2_cam.h
new file mode 100644
index 00000000..3c080a32
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx2_cam.h
@@ -0,0 +1,46 @@
+/*
+ * mx2-cam.h - i.MX27/i.MX25 camera driver header file
+ *
+ * Copyright (C) 2003, Intel Corporation
+ * Copyright (C) 2008, Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2010, Baruch Siach <baruch@tkos.co.il>
+ *
+ * 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.
+ */
+
+#ifndef __MACH_MX2_CAM_H_
+#define __MACH_MX2_CAM_H_
+
+#define MX2_CAMERA_SWAP16 (1 << 0)
+#define MX2_CAMERA_EXT_VSYNC (1 << 1)
+#define MX2_CAMERA_CCIR (1 << 2)
+#define MX2_CAMERA_CCIR_INTERLACE (1 << 3)
+#define MX2_CAMERA_HSYNC_HIGH (1 << 4)
+#define MX2_CAMERA_GATED_CLOCK (1 << 5)
+#define MX2_CAMERA_INV_DATA (1 << 6)
+#define MX2_CAMERA_PCLK_SAMPLE_RISING (1 << 7)
+#define MX2_CAMERA_PACK_DIR_MSB (1 << 8)
+
+/**
+ * struct mx2_camera_platform_data - optional platform data for mx2_camera
+ * @flags: any combination of MX2_CAMERA_*
+ * @clk: clock rate of the csi block / 2
+ */
+struct mx2_camera_platform_data {
+ unsigned long flags;
+ unsigned long clk;
+};
+
+#endif /* __MACH_MX2_CAM_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h
new file mode 100644
index 00000000..6d07839f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx2x.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * This contains hardware definitions that are common between i.MX21 and
+ * i.MX27.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MX2x_H__
+#define __MACH_MX2x_H__
+
+/* The following addresses are common between i.MX21 and i.MX27 */
+
+/* Register offsets */
+#define MX2x_AIPI_BASE_ADDR 0x10000000
+#define MX2x_AIPI_SIZE SZ_1M
+#define MX2x_DMA_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x01000)
+#define MX2x_WDOG_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x02000)
+#define MX2x_GPT1_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x03000)
+#define MX2x_GPT2_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x04000)
+#define MX2x_GPT3_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x05000)
+#define MX2x_PWM_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x06000)
+#define MX2x_RTC_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x07000)
+#define MX2x_KPP_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x08000)
+#define MX2x_OWIRE_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x09000)
+#define MX2x_UART1_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0a000)
+#define MX2x_UART2_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0b000)
+#define MX2x_UART3_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0c000)
+#define MX2x_UART4_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0d000)
+#define MX2x_CSPI1_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0e000)
+#define MX2x_CSPI2_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x0f000)
+#define MX2x_SSI1_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x10000)
+#define MX2x_SSI2_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x11000)
+#define MX2x_I2C_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x12000)
+#define MX2x_SDHC1_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x13000)
+#define MX2x_SDHC2_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x14000)
+#define MX2x_GPIO_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x15000)
+#define MX2x_AUDMUX_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x16000)
+#define MX2x_CSPI3_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x17000)
+#define MX2x_LCDC_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x21000)
+#define MX2x_SLCDC_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x22000)
+#define MX2x_USBOTG_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x24000)
+#define MX2x_EMMA_PP_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x26000)
+#define MX2x_EMMA_PRP_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x26400)
+#define MX2x_CCM_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x27000)
+#define MX2x_SYSCTRL_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x27800)
+#define MX2x_JAM_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x3e000)
+#define MX2x_MAX_BASE_ADDR (MX2x_AIPI_BASE_ADDR + 0x3f000)
+
+#define MX2x_AVIC_BASE_ADDR 0x10040000
+
+#define MX2x_SAHB1_BASE_ADDR 0x80000000
+#define MX2x_SAHB1_SIZE SZ_1M
+#define MX2x_CSI_BASE_ADDR (MX2x_SAHB1_BASE_ADDR + 0x0000)
+
+/* fixed interrupt numbers */
+#define MX2x_INT_CSPI3 6
+#define MX2x_INT_GPIO 8
+#define MX2x_INT_SDHC2 10
+#define MX2x_INT_SDHC1 11
+#define MX2x_INT_I2C 12
+#define MX2x_INT_SSI2 13
+#define MX2x_INT_SSI1 14
+#define MX2x_INT_CSPI2 15
+#define MX2x_INT_CSPI1 16
+#define MX2x_INT_UART4 17
+#define MX2x_INT_UART3 18
+#define MX2x_INT_UART2 19
+#define MX2x_INT_UART1 20
+#define MX2x_INT_KPP 21
+#define MX2x_INT_RTC 22
+#define MX2x_INT_PWM 23
+#define MX2x_INT_GPT3 24
+#define MX2x_INT_GPT2 25
+#define MX2x_INT_GPT1 26
+#define MX2x_INT_WDOG 27
+#define MX2x_INT_PCMCIA 28
+#define MX2x_INT_NANDFC 29
+#define MX2x_INT_CSI 31
+#define MX2x_INT_DMACH0 32
+#define MX2x_INT_DMACH1 33
+#define MX2x_INT_DMACH2 34
+#define MX2x_INT_DMACH3 35
+#define MX2x_INT_DMACH4 36
+#define MX2x_INT_DMACH5 37
+#define MX2x_INT_DMACH6 38
+#define MX2x_INT_DMACH7 39
+#define MX2x_INT_DMACH8 40
+#define MX2x_INT_DMACH9 41
+#define MX2x_INT_DMACH10 42
+#define MX2x_INT_DMACH11 43
+#define MX2x_INT_DMACH12 44
+#define MX2x_INT_DMACH13 45
+#define MX2x_INT_DMACH14 46
+#define MX2x_INT_DMACH15 47
+#define MX2x_INT_EMMAPRP 51
+#define MX2x_INT_EMMAPP 52
+#define MX2x_INT_SLCDC 60
+#define MX2x_INT_LCDC 61
+
+/* fixed DMA request numbers */
+#define MX2x_DMA_REQ_CSPI3_RX 1
+#define MX2x_DMA_REQ_CSPI3_TX 2
+#define MX2x_DMA_REQ_EXT 3
+#define MX2x_DMA_REQ_SDHC2 6
+#define MX2x_DMA_REQ_SDHC1 7
+#define MX2x_DMA_REQ_SSI2_RX0 8
+#define MX2x_DMA_REQ_SSI2_TX0 9
+#define MX2x_DMA_REQ_SSI2_RX1 10
+#define MX2x_DMA_REQ_SSI2_TX1 11
+#define MX2x_DMA_REQ_SSI1_RX0 12
+#define MX2x_DMA_REQ_SSI1_TX0 13
+#define MX2x_DMA_REQ_SSI1_RX1 14
+#define MX2x_DMA_REQ_SSI1_TX1 15
+#define MX2x_DMA_REQ_CSPI2_RX 16
+#define MX2x_DMA_REQ_CSPI2_TX 17
+#define MX2x_DMA_REQ_CSPI1_RX 18
+#define MX2x_DMA_REQ_CSPI1_TX 19
+#define MX2x_DMA_REQ_UART4_RX 20
+#define MX2x_DMA_REQ_UART4_TX 21
+#define MX2x_DMA_REQ_UART3_RX 22
+#define MX2x_DMA_REQ_UART3_TX 23
+#define MX2x_DMA_REQ_UART2_RX 24
+#define MX2x_DMA_REQ_UART2_TX 25
+#define MX2x_DMA_REQ_UART1_RX 26
+#define MX2x_DMA_REQ_UART1_TX 27
+#define MX2x_DMA_REQ_CSI_STAT 30
+#define MX2x_DMA_REQ_CSI_RX 31
+
+#endif /* ifndef __MACH_MX2x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
new file mode 100644
index 00000000..79e7fc01
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -0,0 +1,206 @@
+#ifndef __MACH_MX31_H__
+#define __MACH_MX31_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * IRAM
+ */
+#define MX31_IRAM_BASE_ADDR 0x1ffc0000 /* internal ram */
+#define MX31_IRAM_SIZE SZ_16K
+
+#define MX31_L2CC_BASE_ADDR 0x30000000
+#define MX31_L2CC_SIZE SZ_1M
+
+#define MX31_AIPS1_BASE_ADDR 0x43f00000
+#define MX31_AIPS1_SIZE SZ_1M
+#define MX31_MAX_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x04000)
+#define MX31_EVTMON_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x08000)
+#define MX31_CLKCTL_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x0c000)
+#define MX31_ETB_SLOT4_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x10000)
+#define MX31_ETB_SLOT5_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x14000)
+#define MX31_ECT_CTIO_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x18000)
+#define MX31_I2C1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x80000)
+#define MX31_I2C3_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x84000)
+#define MX31_USB_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000)
+#define MX31_USB_OTG_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0000)
+#define MX31_USB_HS1_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0200)
+#define MX31_USB_HS2_BASE_ADDR (MX31_USB_BASE_ADDR + 0x0400)
+#define MX31_ATA_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x8c000)
+#define MX31_UART1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x90000)
+#define MX31_UART2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x94000)
+#define MX31_I2C2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x98000)
+#define MX31_OWIRE_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x9c000)
+#define MX31_SSI1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa0000)
+#define MX31_CSPI1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa4000)
+#define MX31_KPP_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xa8000)
+#define MX31_IOMUXC_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xac000)
+#define MX31_UART4_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb0000)
+#define MX31_UART5_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb4000)
+#define MX31_ECT_IP1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xb8000)
+#define MX31_ECT_IP2_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0xbc000)
+
+#define MX31_SPBA0_BASE_ADDR 0x50000000
+#define MX31_SPBA0_SIZE SZ_1M
+#define MX31_SDHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x04000)
+#define MX31_SDHC2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x08000)
+#define MX31_UART3_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x0c000)
+#define MX31_CSPI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x10000)
+#define MX31_SSI2_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x14000)
+#define MX31_SIM1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x18000)
+#define MX31_IIM_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x1c000)
+#define MX31_ATA_DMA_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x20000)
+#define MX31_MSHC1_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x24000)
+#define MX31_SPBA_CTRL_BASE_ADDR (MX31_SPBA0_BASE_ADDR + 0x3c000)
+
+#define MX31_AIPS2_BASE_ADDR 0x53f00000
+#define MX31_AIPS2_SIZE SZ_1M
+#define MX31_CCM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x80000)
+#define MX31_CSPI3_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x84000)
+#define MX31_FIRI_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x8c000)
+#define MX31_GPT1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x90000)
+#define MX31_EPIT1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x94000)
+#define MX31_EPIT2_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0x98000)
+#define MX31_GPIO3_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xa4000)
+#define MX31_SCC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xac000)
+#define MX31_SCM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xae000)
+#define MX31_SMN_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xaf000)
+#define MX31_RNGA_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xb0000)
+#define MX31_IPU_CTRL_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc0000)
+#define MX31_AUDMUX_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc4000)
+#define MX31_MPEG4_ENC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xc8000)
+#define MX31_GPIO1_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xcc000)
+#define MX31_GPIO2_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd0000)
+#define MX31_SDMA_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd4000)
+#define MX31_RTC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xd8000)
+#define MX31_WDOG_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xdc000)
+#define MX31_PWM_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xe0000)
+#define MX31_RTIC_BASE_ADDR (MX31_AIPS2_BASE_ADDR + 0xec000)
+
+#define MX31_ROMP_BASE_ADDR 0x60000000
+#define MX31_ROMP_BASE_ADDR_VIRT 0xfc500000
+#define MX31_ROMP_SIZE SZ_1M
+
+#define MX31_AVIC_BASE_ADDR 0x68000000
+#define MX31_AVIC_SIZE SZ_1M
+
+#define MX31_IPU_MEM_BASE_ADDR 0x70000000
+#define MX31_CSD0_BASE_ADDR 0x80000000
+#define MX31_CSD1_BASE_ADDR 0x90000000
+
+#define MX31_CS0_BASE_ADDR 0xa0000000
+#define MX31_CS1_BASE_ADDR 0xa8000000
+#define MX31_CS2_BASE_ADDR 0xb0000000
+#define MX31_CS3_BASE_ADDR 0xb2000000
+
+#define MX31_CS4_BASE_ADDR 0xb4000000
+#define MX31_CS4_BASE_ADDR_VIRT 0xf6000000
+#define MX31_CS4_SIZE SZ_32M
+
+#define MX31_CS5_BASE_ADDR 0xb6000000
+#define MX31_CS5_BASE_ADDR_VIRT 0xf8000000
+#define MX31_CS5_SIZE SZ_32M
+
+#define MX31_X_MEMC_BASE_ADDR 0xb8000000
+#define MX31_X_MEMC_SIZE SZ_64K
+#define MX31_NFC_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x0000)
+#define MX31_ESDCTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x1000)
+#define MX31_WEIM_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x2000)
+#define MX31_M3IF_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x3000)
+#define MX31_EMI_CTL_BASE_ADDR (MX31_X_MEMC_BASE_ADDR + 0x4000)
+#define MX31_PCMCIA_CTL_BASE_ADDR MX31_EMI_CTL_BASE_ADDR
+
+#define MX31_WEIM_CSCRx_BASE_ADDR(cs) (MX31_WEIM_BASE_ADDR + (cs) * 0x10)
+#define MX31_WEIM_CSCRxU(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs))
+#define MX31_WEIM_CSCRxL(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x4)
+#define MX31_WEIM_CSCRxA(cs) (MX31_WEIM_CSCRx_BASE_ADDR(cs) + 0x8)
+
+#define MX31_PCMCIA_MEM_BASE_ADDR 0xbc000000
+
+#define MX31_IO_P2V(x) IMX_IO_P2V(x)
+#define MX31_IO_ADDRESS(x) IOMEM(MX31_IO_P2V(x))
+
+#ifndef __ASSEMBLER__
+static inline void mx31_setup_weimcs(size_t cs,
+ unsigned upper, unsigned lower, unsigned addional)
+{
+ __raw_writel(upper, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(cs)));
+ __raw_writel(lower, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(cs)));
+ __raw_writel(addional, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(cs)));
+}
+#endif
+
+#define MX31_INT_I2C3 3
+#define MX31_INT_I2C2 4
+#define MX31_INT_MPEG4_ENCODER 5
+#define MX31_INT_RTIC 6
+#define MX31_INT_FIRI 7
+#define MX31_INT_SDHC2 8
+#define MX31_INT_SDHC1 9
+#define MX31_INT_I2C1 10
+#define MX31_INT_SSI2 11
+#define MX31_INT_SSI1 12
+#define MX31_INT_CSPI2 13
+#define MX31_INT_CSPI1 14
+#define MX31_INT_ATA 15
+#define MX31_INT_MBX 16
+#define MX31_INT_CSPI3 17
+#define MX31_INT_UART3 18
+#define MX31_INT_IIM 19
+#define MX31_INT_SIM2 20
+#define MX31_INT_SIM1 21
+#define MX31_INT_RNGA 22
+#define MX31_INT_EVTMON 23
+#define MX31_INT_KPP 24
+#define MX31_INT_RTC 25
+#define MX31_INT_PWM 26
+#define MX31_INT_EPIT2 27
+#define MX31_INT_EPIT1 28
+#define MX31_INT_GPT 29
+#define MX31_INT_POWER_FAIL 30
+#define MX31_INT_CCM_DVFS 31
+#define MX31_INT_UART2 32
+#define MX31_INT_NFC 33
+#define MX31_INT_SDMA 34
+#define MX31_INT_USB_HS1 35
+#define MX31_INT_USB_HS2 36
+#define MX31_INT_USB_OTG 37
+#define MX31_INT_MSHC1 39
+#define MX31_INT_MSHC2 40
+#define MX31_INT_IPU_ERR 41
+#define MX31_INT_IPU_SYN 42
+#define MX31_INT_UART1 45
+#define MX31_INT_UART4 46
+#define MX31_INT_UART5 47
+#define MX31_INT_ECT 48
+#define MX31_INT_SCC_SCM 49
+#define MX31_INT_SCC_SMN 50
+#define MX31_INT_GPIO2 51
+#define MX31_INT_GPIO1 52
+#define MX31_INT_CCM 53
+#define MX31_INT_PCMCIA 54
+#define MX31_INT_WDOG 55
+#define MX31_INT_GPIO3 56
+#define MX31_INT_EXT_POWER 58
+#define MX31_INT_EXT_TEMPER 59
+#define MX31_INT_EXT_SENSOR60 60
+#define MX31_INT_EXT_SENSOR61 61
+#define MX31_INT_EXT_WDOG 62
+#define MX31_INT_EXT_TV 63
+
+#define MX31_DMA_REQ_SDHC1 20
+#define MX31_DMA_REQ_SDHC2 21
+#define MX31_DMA_REQ_SSI2_RX1 22
+#define MX31_DMA_REQ_SSI2_TX1 23
+#define MX31_DMA_REQ_SSI2_RX0 24
+#define MX31_DMA_REQ_SSI2_TX0 25
+#define MX31_DMA_REQ_SSI1_RX1 26
+#define MX31_DMA_REQ_SSI1_TX1 27
+#define MX31_DMA_REQ_SSI1_RX0 28
+#define MX31_DMA_REQ_SSI1_TX0 29
+
+#define MX31_PROD_SIGNATURE 0x1 /* For MX31 */
+
+#endif /* ifndef __MACH_MX31_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
new file mode 100644
index 00000000..d13dbfee
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -0,0 +1,189 @@
+#ifndef __MACH_MX35_H__
+#define __MACH_MX35_H__
+
+/*
+ * IRAM
+ */
+#define MX35_IRAM_BASE_ADDR 0x10000000 /* internal ram */
+#define MX35_IRAM_SIZE SZ_128K
+
+#define MX35_L2CC_BASE_ADDR 0x30000000
+#define MX35_L2CC_SIZE SZ_1M
+
+#define MX35_AIPS1_BASE_ADDR 0x43f00000
+#define MX35_AIPS1_SIZE SZ_1M
+#define MX35_MAX_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x04000)
+#define MX35_EVTMON_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x08000)
+#define MX35_CLKCTL_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x0c000)
+#define MX35_ETB_SLOT4_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x10000)
+#define MX35_ETB_SLOT5_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x14000)
+#define MX35_ECT_CTIO_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x18000)
+#define MX35_I2C1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x80000)
+#define MX35_I2C3_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x84000)
+#define MX35_UART1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x90000)
+#define MX35_UART2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x94000)
+#define MX35_I2C2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x98000)
+#define MX35_OWIRE_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x9c000)
+#define MX35_SSI1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa0000)
+#define MX35_CSPI1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa4000)
+#define MX35_KPP_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xa8000)
+#define MX35_IOMUXC_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xac000)
+#define MX35_ECT_IP1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xb8000)
+#define MX35_ECT_IP2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0xbc000)
+
+#define MX35_SPBA0_BASE_ADDR 0x50000000
+#define MX35_SPBA0_SIZE SZ_1M
+#define MX35_UART3_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x0c000)
+#define MX35_CSPI2_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x10000)
+#define MX35_SSI2_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x14000)
+#define MX35_ATA_DMA_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x20000)
+#define MX35_MSHC1_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x24000)
+#define MX35_FEC_BASE_ADDR 0x50038000
+#define MX35_SPBA_CTRL_BASE_ADDR (MX35_SPBA0_BASE_ADDR + 0x3c000)
+
+#define MX35_AIPS2_BASE_ADDR 0x53f00000
+#define MX35_AIPS2_SIZE SZ_1M
+#define MX35_CCM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x80000)
+#define MX35_GPT1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x90000)
+#define MX35_EPIT1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x94000)
+#define MX35_EPIT2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0x98000)
+#define MX35_GPIO3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xa4000)
+#define MX35_SCC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xac000)
+#define MX35_RNGA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb0000)
+#define MX35_ESDHC1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb4000)
+#define MX35_ESDHC2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xb8000)
+#define MX35_ESDHC3_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xbc000)
+#define MX35_IPU_CTRL_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc0000)
+#define MX35_AUDMUX_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xc4000)
+#define MX35_GPIO1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xcc000)
+#define MX35_GPIO2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd0000)
+#define MX35_SDMA_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd4000)
+#define MX35_RTC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xd8000)
+#define MX35_WDOG_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xdc000)
+#define MX35_PWM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe0000)
+#define MX35_CAN1_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe4000)
+#define MX35_CAN2_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xe8000)
+#define MX35_RTIC_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xec000)
+#define MX35_IIM_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf0000)
+#define MX35_USB_BASE_ADDR (MX35_AIPS2_BASE_ADDR + 0xf4000)
+#define MX35_USB_OTG_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0000)
+/*
+ * The Reference Manual (IMX35RM, Rev. 2, 3/2009) claims an offset of 0x200 for
+ * HS. When host support was implemented only a preliminary document was
+ * available, which told 0x400. This works fine.
+ */
+#define MX35_USB_HS_BASE_ADDR (MX35_USB_BASE_ADDR + 0x0400)
+
+#define MX35_ROMP_BASE_ADDR 0x60000000
+#define MX35_ROMP_SIZE SZ_1M
+
+#define MX35_AVIC_BASE_ADDR 0x68000000
+#define MX35_AVIC_SIZE SZ_1M
+
+/*
+ * Memory regions and CS
+ */
+#define MX35_IPU_MEM_BASE_ADDR 0x70000000
+#define MX35_CSD0_BASE_ADDR 0x80000000
+#define MX35_CSD1_BASE_ADDR 0x90000000
+
+#define MX35_CS0_BASE_ADDR 0xa0000000
+#define MX35_CS1_BASE_ADDR 0xa8000000
+#define MX35_CS2_BASE_ADDR 0xb0000000
+#define MX35_CS3_BASE_ADDR 0xb2000000
+
+#define MX35_CS4_BASE_ADDR 0xb4000000
+#define MX35_CS4_BASE_ADDR_VIRT 0xf6000000
+#define MX35_CS4_SIZE SZ_32M
+
+#define MX35_CS5_BASE_ADDR 0xb6000000
+#define MX35_CS5_BASE_ADDR_VIRT 0xf8000000
+#define MX35_CS5_SIZE SZ_32M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define MX35_X_MEMC_BASE_ADDR 0xb8000000
+#define MX35_X_MEMC_SIZE SZ_64K
+#define MX35_ESDCTL_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x1000)
+#define MX35_WEIM_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x2000)
+#define MX35_M3IF_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x3000)
+#define MX35_EMI_CTL_BASE_ADDR (MX35_X_MEMC_BASE_ADDR + 0x4000)
+#define MX35_PCMCIA_CTL_BASE_ADDR MX35_EMI_CTL_BASE_ADDR
+
+#define MX35_NFC_BASE_ADDR 0xbb000000
+#define MX35_PCMCIA_MEM_BASE_ADDR 0xbc000000
+
+#define MX35_IO_P2V(x) IMX_IO_P2V(x)
+#define MX35_IO_ADDRESS(x) IOMEM(MX35_IO_P2V(x))
+
+/*
+ * Interrupt numbers
+ */
+#define MX35_INT_OWIRE 2
+#define MX35_INT_I2C3 3
+#define MX35_INT_I2C2 4
+#define MX35_INT_RTIC 6
+#define MX35_INT_ESDHC1 7
+#define MX35_INT_ESDHC2 8
+#define MX35_INT_ESDHC3 9
+#define MX35_INT_I2C1 10
+#define MX35_INT_SSI1 11
+#define MX35_INT_SSI2 12
+#define MX35_INT_CSPI2 13
+#define MX35_INT_CSPI1 14
+#define MX35_INT_ATA 15
+#define MX35_INT_GPU2D 16
+#define MX35_INT_ASRC 17
+#define MX35_INT_UART3 18
+#define MX35_INT_IIM 19
+#define MX35_INT_RNGA 22
+#define MX35_INT_EVTMON 23
+#define MX35_INT_KPP 24
+#define MX35_INT_RTC 25
+#define MX35_INT_PWM 26
+#define MX35_INT_EPIT2 27
+#define MX35_INT_EPIT1 28
+#define MX35_INT_GPT 29
+#define MX35_INT_POWER_FAIL 30
+#define MX35_INT_UART2 32
+#define MX35_INT_NFC 33
+#define MX35_INT_SDMA 34
+#define MX35_INT_USB_HS 35
+#define MX35_INT_USB_OTG 37
+#define MX35_INT_MSHC1 39
+#define MX35_INT_ESAI 40
+#define MX35_INT_IPU_ERR 41
+#define MX35_INT_IPU_SYN 42
+#define MX35_INT_CAN1 43
+#define MX35_INT_CAN2 44
+#define MX35_INT_UART1 45
+#define MX35_INT_MLB 46
+#define MX35_INT_SPDIF 47
+#define MX35_INT_ECT 48
+#define MX35_INT_SCC_SCM 49
+#define MX35_INT_SCC_SMN 50
+#define MX35_INT_GPIO2 51
+#define MX35_INT_GPIO1 52
+#define MX35_INT_WDOG 55
+#define MX35_INT_GPIO3 56
+#define MX35_INT_FEC 57
+#define MX35_INT_EXT_POWER 58
+#define MX35_INT_EXT_TEMPER 59
+#define MX35_INT_EXT_SENSOR60 60
+#define MX35_INT_EXT_SENSOR61 61
+#define MX35_INT_EXT_WDOG 62
+#define MX35_INT_EXT_TV 63
+
+#define MX35_DMA_REQ_SSI2_RX1 22
+#define MX35_DMA_REQ_SSI2_TX1 23
+#define MX35_DMA_REQ_SSI2_RX0 24
+#define MX35_DMA_REQ_SSI2_TX0 25
+#define MX35_DMA_REQ_SSI1_RX1 26
+#define MX35_DMA_REQ_SSI1_TX1 27
+#define MX35_DMA_REQ_SSI1_RX0 28
+#define MX35_DMA_REQ_SSI1_TX0 29
+
+#define MX35_PROD_SIGNATURE 0x1 /* For MX31 */
+
+#endif /* ifndef __MACH_MX35_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx3_camera.h b/arch/arm/plat-mxc/include/mach/mx3_camera.h
new file mode 100644
index 00000000..f226ee37
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx3_camera.h
@@ -0,0 +1,48 @@
+/*
+ * mx3_camera.h - i.MX3x camera driver header file
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _MX3_CAMERA_H_
+#define _MX3_CAMERA_H_
+
+#include <linux/device.h>
+
+#define MX3_CAMERA_CLK_SRC 1
+#define MX3_CAMERA_EXT_VSYNC 2
+#define MX3_CAMERA_DP 4
+#define MX3_CAMERA_PCP 8
+#define MX3_CAMERA_HSP 0x10
+#define MX3_CAMERA_VSP 0x20
+#define MX3_CAMERA_DATAWIDTH_4 0x40
+#define MX3_CAMERA_DATAWIDTH_8 0x80
+#define MX3_CAMERA_DATAWIDTH_10 0x100
+#define MX3_CAMERA_DATAWIDTH_15 0x200
+
+#define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \
+ MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15)
+
+/**
+ * struct mx3_camera_pdata - i.MX3x camera platform data
+ * @flags: MX3_CAMERA_* flags
+ * @mclk_10khz: master clock frequency in 10kHz units
+ * @dma_dev: IPU DMA device to match against in channel allocation
+ */
+struct mx3_camera_pdata {
+ unsigned long flags;
+ unsigned long mclk_10khz;
+ struct device *dma_dev;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx3fb.h b/arch/arm/plat-mxc/include/mach/mx3fb.h
new file mode 100644
index 00000000..ac24c5c4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx3fb.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MX3FB_H__
+#define __ASM_ARCH_MX3FB_H__
+
+#include <linux/device.h>
+#include <linux/fb.h>
+
+/* Proprietary FB_SYNC_ flags */
+#define FB_SYNC_OE_ACT_HIGH 0x80000000
+#define FB_SYNC_CLK_INVERT 0x40000000
+#define FB_SYNC_DATA_INVERT 0x20000000
+#define FB_SYNC_CLK_IDLE_EN 0x10000000
+#define FB_SYNC_SHARP_MODE 0x08000000
+#define FB_SYNC_SWAP_RGB 0x04000000
+#define FB_SYNC_CLK_SEL_EN 0x02000000
+
+/**
+ * struct mx3fb_platform_data - mx3fb platform data
+ *
+ * @dma_dev: pointer to the dma-device, used for dma-slave connection
+ * @mode: pointer to a platform-provided per mxc_register_fb() videomode
+ */
+struct mx3fb_platform_data {
+ struct device *dma_dev;
+ const char *name;
+ const struct fb_videomode *mode;
+ int num_modes;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h
new file mode 100644
index 00000000..388a407d
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx3x.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MX3x_H__
+#define __MACH_MX3x_H__
+
+/*
+ * MX31 memory map:
+ *
+ * Virt Phys Size What
+ * ---------------------------------------------------------------------------
+ * FC000000 43F00000 1M AIPS 1
+ * FC100000 50000000 1M SPBA
+ * FC200000 53F00000 1M AIPS 2
+ * FC500000 60000000 128M ROMPATCH
+ * FC400000 68000000 128M AVIC
+ * 70000000 256M IPU (MAX M2)
+ * 80000000 256M CSD0 SDRAM/DDR
+ * 90000000 256M CSD1 SDRAM/DDR
+ * A0000000 128M CS0 Flash
+ * A8000000 128M CS1 Flash
+ * B0000000 32M CS2
+ * B2000000 32M CS3
+ * F4000000 B4000000 32M CS4
+ * B6000000 32M CS5
+ * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers
+ * C0000000 64M PCMCIA/CF
+ */
+
+/*
+ * L2CC
+ */
+#define MX3x_L2CC_BASE_ADDR 0x30000000
+#define MX3x_L2CC_SIZE SZ_1M
+
+/*
+ * AIPS 1
+ */
+#define MX3x_AIPS1_BASE_ADDR 0x43f00000
+#define MX3x_AIPS1_SIZE SZ_1M
+#define MX3x_MAX_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x04000)
+#define MX3x_EVTMON_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x08000)
+#define MX3x_CLKCTL_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x0c000)
+#define MX3x_ETB_SLOT4_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x10000)
+#define MX3x_ETB_SLOT5_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x14000)
+#define MX3x_ECT_CTIO_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x18000)
+#define MX3x_I2C_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x80000)
+#define MX3x_I2C3_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x84000)
+#define MX3x_UART1_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x90000)
+#define MX3x_UART2_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x94000)
+#define MX3x_I2C2_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x98000)
+#define MX3x_OWIRE_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0x9c000)
+#define MX3x_SSI1_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xa0000)
+#define MX3x_CSPI1_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xa4000)
+#define MX3x_KPP_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xa8000)
+#define MX3x_IOMUXC_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xac000)
+#define MX3x_ECT_IP1_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xb8000)
+#define MX3x_ECT_IP2_BASE_ADDR (MX3x_AIPS1_BASE_ADDR + 0xbc000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX3x_SPBA0_BASE_ADDR 0x50000000
+#define MX3x_SPBA0_SIZE SZ_1M
+#define MX3x_UART3_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x0c000)
+#define MX3x_CSPI2_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x10000)
+#define MX3x_SSI2_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x14000)
+#define MX3x_ATA_DMA_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x20000)
+#define MX3x_MSHC1_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x24000)
+#define MX3x_SPBA_CTRL_BASE_ADDR (MX3x_SPBA0_BASE_ADDR + 0x3c000)
+
+/*
+ * AIPS 2
+ */
+#define MX3x_AIPS2_BASE_ADDR 0x53f00000
+#define MX3x_AIPS2_SIZE SZ_1M
+#define MX3x_CCM_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x80000)
+#define MX3x_GPT1_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x90000)
+#define MX3x_EPIT1_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x94000)
+#define MX3x_EPIT2_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0x98000)
+#define MX3x_GPIO3_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xa4000)
+#define MX3x_SCC_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xac000)
+#define MX3x_RNGA_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xb0000)
+#define MX3x_IPU_CTRL_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xc0000)
+#define MX3x_AUDMUX_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xc4000)
+#define MX3x_GPIO1_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xcc000)
+#define MX3x_GPIO2_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xd0000)
+#define MX3x_SDMA_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xd4000)
+#define MX3x_RTC_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xd8000)
+#define MX3x_WDOG_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xdc000)
+#define MX3x_PWM_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xe0000)
+#define MX3x_RTIC_BASE_ADDR (MX3x_AIPS2_BASE_ADDR + 0xec000)
+
+/*
+ * ROMP and AVIC
+ */
+#define MX3x_ROMP_BASE_ADDR 0x60000000
+#define MX3x_ROMP_SIZE SZ_1M
+
+#define MX3x_AVIC_BASE_ADDR 0x68000000
+#define MX3x_AVIC_SIZE SZ_1M
+
+/*
+ * Memory regions and CS
+ */
+#define MX3x_IPU_MEM_BASE_ADDR 0x70000000
+#define MX3x_CSD0_BASE_ADDR 0x80000000
+#define MX3x_CSD1_BASE_ADDR 0x90000000
+
+#define MX3x_CS0_BASE_ADDR 0xa0000000
+#define MX3x_CS1_BASE_ADDR 0xa8000000
+#define MX3x_CS2_BASE_ADDR 0xb0000000
+#define MX3x_CS3_BASE_ADDR 0xb2000000
+
+#define MX3x_CS4_BASE_ADDR 0xb4000000
+#define MX3x_CS4_BASE_ADDR_VIRT 0xf6000000
+#define MX3x_CS4_SIZE SZ_32M
+
+#define MX3x_CS5_BASE_ADDR 0xb6000000
+#define MX3x_CS5_BASE_ADDR_VIRT 0xf8000000
+#define MX3x_CS5_SIZE SZ_32M
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define MX3x_X_MEMC_BASE_ADDR 0xb8000000
+#define MX3x_X_MEMC_SIZE SZ_64K
+#define MX3x_ESDCTL_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x1000)
+#define MX3x_WEIM_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x2000)
+#define MX3x_M3IF_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x3000)
+#define MX3x_EMI_CTL_BASE_ADDR (MX3x_X_MEMC_BASE_ADDR + 0x4000)
+#define MX3x_PCMCIA_CTL_BASE_ADDR MX3x_EMI_CTL_BASE_ADDR
+
+#define MX3x_PCMCIA_MEM_BASE_ADDR 0xbc000000
+
+/*
+ * Interrupt numbers
+ */
+#define MX3x_INT_I2C3 3
+#define MX3x_INT_I2C2 4
+#define MX3x_INT_RTIC 6
+#define MX3x_INT_I2C 10
+#define MX3x_INT_CSPI2 13
+#define MX3x_INT_CSPI1 14
+#define MX3x_INT_ATA 15
+#define MX3x_INT_UART3 18
+#define MX3x_INT_IIM 19
+#define MX3x_INT_RNGA 22
+#define MX3x_INT_EVTMON 23
+#define MX3x_INT_KPP 24
+#define MX3x_INT_RTC 25
+#define MX3x_INT_PWM 26
+#define MX3x_INT_EPIT2 27
+#define MX3x_INT_EPIT1 28
+#define MX3x_INT_GPT 29
+#define MX3x_INT_POWER_FAIL 30
+#define MX3x_INT_UART2 32
+#define MX3x_INT_NANDFC 33
+#define MX3x_INT_SDMA 34
+#define MX3x_INT_MSHC1 39
+#define MX3x_INT_IPU_ERR 41
+#define MX3x_INT_IPU_SYN 42
+#define MX3x_INT_UART1 45
+#define MX3x_INT_ECT 48
+#define MX3x_INT_SCC_SCM 49
+#define MX3x_INT_SCC_SMN 50
+#define MX3x_INT_GPIO2 51
+#define MX3x_INT_GPIO1 52
+#define MX3x_INT_WDOG 55
+#define MX3x_INT_GPIO3 56
+#define MX3x_INT_EXT_POWER 58
+#define MX3x_INT_EXT_TEMPER 59
+#define MX3x_INT_EXT_SENSOR60 60
+#define MX3x_INT_EXT_SENSOR61 61
+#define MX3x_INT_EXT_WDOG 62
+#define MX3x_INT_EXT_TV 63
+
+#define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */
+
+/* Mandatory defines used globally */
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern unsigned int mx31_cpu_rev;
+extern void mx31_read_cpu_rev(void);
+
+static inline int mx31_revision(void)
+{
+ return mx31_cpu_rev;
+}
+
+extern unsigned int mx35_cpu_rev;
+extern void mx35_read_cpu_rev(void);
+
+static inline int mx35_revision(void)
+{
+ return mx35_cpu_rev;
+}
+#endif
+
+#endif /* ifndef __MACH_MX3x_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/plat-mxc/include/mach/mx50.h
new file mode 100755
index 00000000..ec37ab16
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx50.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX50_H__
+#define __MACH_MX50_H__
+
+/*
+ * IROM
+ */
+#define MX50_IROM_BASE_ADDR 0x0
+#define MX50_IROM_SIZE SZ_64K
+
+/* TZIC */
+#define MX50_TZIC_BASE_ADDR 0x0fffc000
+#define MX50_TZIC_SIZE SZ_16K
+
+/*
+ * IRAM
+ */
+#define MX50_IRAM_BASE_ADDR 0xf8000000 /* internal ram */
+#define MX50_IRAM_PARTITIONS 16
+#define MX50_IRAM_SIZE (MX50_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * Databahn
+ */
+#define MX50_DATABAHN_BASE_ADDR 0x14000000
+#define DATABAHN_CTL_REG19 0x4c
+#define DATABAHN_CTL_REG20 0x50
+#define DATABAHN_CTL_REG21 0x54
+#define DATABAHN_CTL_REG22 0x58
+#define DATABAHN_CTL_REG23 0x5c
+#define DATABAHN_CTL_REG42 0xa8
+#define DATABAHN_CTL_REG43 0xac
+#define DATABAHN_CTL_REG55 0xdc
+#define DATABAHN_CTL_REG63 0xFC
+#define DATABAHN_CTL_REG73 0x124
+#define DATABAHN_CTL_REG74 0x128
+#define DATABAHN_CTL_REG75 0x12C
+#define DATABAHN_CTL_REG83 0x14C
+#define LOWPOWER_CONTROL_MASK 0x1F
+#define LOWPOWER_AUTOENABLE_MASK 0x1F
+#define LOWPOWER_EXTERNAL_CNT_MASK (0xFFFF << 16)
+#define LOWPOWER_EXTERNAL_CNT_OFFSET 16
+#define LOWPOWER_INTERNAL_CNT_MASK (0xFFFF << 8)
+#define LOWPOWER_INTERNAL_CNT_OFFSET 8
+#define LOWPOWER_REFRESH_ENABLE_MASK (3 << 16)
+#define LOWPOWER_REFRESH_ENABLE_OFFSET 16
+#define LOWPOWER_REFRESH_HOLD_MASK 0xFFFF
+#define LOWPOWER_REFRESH_HOLD_OFFSET 0
+#define MX50_LPDDR2 (0x5 << 8)
+#define MX50_MDDR (0x1 << 8)
+
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX50_GPU2D_BASE_ADDR 0x20000000
+
+#define MX50_DEBUG_BASE_ADDR 0x40000000
+#define MX50_DEBUG_SIZE SZ_1M
+#define MX50_ETB_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00001000)
+#define MX50_ETM_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00002000)
+#define MX50_TPIU_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00003000)
+#define MX50_CTI0_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00004000)
+#define MX50_CTI1_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00005000)
+#define MX50_CTI2_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00006000)
+#define MX50_CTI3_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00007000)
+#define MX50_CORTEX_DBG_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x00008000)
+
+#define MX50_APBHDMA_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01000000)
+#define MX50_OCOTP_CTRL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01002000)
+#define MX50_DIGCTL_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01004000)
+#define MX50_GPMI_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01006000)
+#define MX50_BCH_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01008000)
+#define MX50_ELCDIF_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100a000)
+#define MX50_EPXP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100c000)
+#define MX50_DCP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x0100e000)
+#define MX50_EPDC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01010000)
+#define MX50_QOSC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01012000)
+#define MX50_PERFMON_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01014000)
+#define MX50_SSP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01016000)
+#define MX50_ANATOP_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x01018000)
+#define MX50_NIC_BASE_ADDR (MX50_DEBUG_BASE_ADDR + 0x08000000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX50_SPBA0_BASE_ADDR 0x50000000
+#define MX50_SPBA0_SIZE SZ_1M
+
+#define MX50_ESDHC1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00004000)
+#define MX50_ESDHC2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00008000)
+#define MX50_UART3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x0000c000)
+#define MX50_CSPI1_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00010000)
+#define MX50_SSI2_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00014000)
+#define MX50_ESDHC3_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00020000)
+#define MX50_ESDHC4_BASE_ADDR (MX50_SPBA0_BASE_ADDR + 0x00024000)
+
+/*
+ * AIPS 1
+ */
+#define MX50_AIPS1_BASE_ADDR 0x53f00000
+#define MX50_AIPS1_SIZE SZ_1M
+
+#define MX50_OTG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00080000)
+#define MX50_GPIO1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00084000)
+#define MX50_GPIO2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00088000)
+#define MX50_GPIO3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x0008c000)
+#define MX50_GPIO4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00090000)
+#define MX50_KPP_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00094000)
+#define MX50_WDOG_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x00098000)
+#define MX50_GPT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a0000)
+#define MX50_SRTC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a4000)
+#define MX50_IOMUXC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000a8000)
+#define MX50_EPIT1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ac000)
+#define MX50_PWM1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b4000)
+#define MX50_PWM2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000b8000)
+#define MX50_UART1_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000bc000)
+#define MX50_UART2_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000c0000)
+#define MX50_SRC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d0000)
+#define MX50_CCM_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d4000)
+#define MX50_GPC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000d8000)
+#define MX50_GPIO5_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000dc000)
+#define MX50_GPIO6_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000e0000)
+#define MX50_I2C3_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000ec000)
+#define MX50_UART4_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f0000)
+
+#define MX50_MSHC_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f4000)
+#define MX50_RNGB_BASE_ADDR (MX50_AIPS1_BASE_ADDR + 0x000f8000)
+#define MX50_DVFSCORE_BASE_ADDR (MX50_GPC_BASE_ADDR + 0x180)
+
+/* GPC offsets */
+#define MXC_GPC_CNTR_OFFSET 0x0
+#define MXC_GPC_PGR_OFFSET 0x4
+#define MXC_GPC_VCR_OFFSET 0x8
+
+/*
+ * AIPS 2
+ */
+#define MX50_AIPS2_BASE_ADDR 0x63f00000
+#define MX50_AIPS2_SIZE SZ_1M
+
+#define MX50_PLL1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00080000)
+#define MX50_PLL2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00084000)
+#define MX50_PLL3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00088000)
+#define MX50_UART5_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00090000)
+#define MX50_AHBMAX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x00094000)
+#define MX50_ARM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a0000)
+#define MX50_OWIRE_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000a4000)
+#define MX50_CSPI2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ac000)
+#define MX50_SDMA_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b0000)
+#define MX50_ROMCP_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000b8000)
+#define MX50_CSPI3_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c0000)
+#define MX50_I2C2_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c4000)
+#define MX50_I2C1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000c8000)
+#define MX50_SSI1_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000cc000)
+#define MX50_AUDMUX_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d0000)
+#define MX50_WEIM_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000d8000)
+#define MX50_FEC_BASE_ADDR (MX50_AIPS2_BASE_ADDR + 0x000ec000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX50_CSD0_BASE_ADDR 0x70000000
+#define MX50_CSD1_BASE_ADDR 0xb0000000
+#define MX50_CS0_BASE_ADDR 0xf0000000
+
+#define MX50_IO_P2V(x) IMX_IO_P2V(x)
+#define MX50_IO_ADDRESS(x) IOMEM(MX50_IO_P2V(x))
+
+/*
+ * defines for SPBA modules
+ */
+#define MX50_SPBA_SDHC1 0x04
+#define MX50_SPBA_SDHC2 0x08
+#define MX50_SPBA_UART3 0x0c
+#define MX50_SPBA_CSPI1 0x10
+#define MX50_SPBA_SSI2 0x14
+#define MX50_SPBA_SDHC3 0x20
+#define MX50_SPBA_SDHC4 0x24
+#define MX50_SPBA_SPDIF 0x28
+#define MX50_SPBA_ATA 0x30
+#define MX50_SPBA_SLIM 0x34
+#define MX50_SPBA_HSI2C 0x38
+#define MX50_SPBA_CTRL 0x3c
+
+/*
+ * DMA request assignments
+ */
+#define MX50_DMA_REQ_GPC 1
+#define MX50_DMA_REQ_ATA_UART4_RX 2
+#define MX50_DMA_REQ_ATA_UART4_TX 3
+#define MX50_DMA_REQ_CSPI1_RX 6
+#define MX50_DMA_REQ_CSPI1_TX 7
+#define MX50_DMA_REQ_CSPI2_RX 8
+#define MX50_DMA_REQ_CSPI2_TX 9
+#define MX50_DMA_REQ_I2C3_SDHC3 10
+#define MX50_DMA_REQ_SDHC4 11
+#define MX50_DMA_REQ_UART2_FIRI_RX 12
+#define MX50_DMA_REQ_UART2_FIRI_TX 13
+#define MX50_DMA_REQ_EXT0 14
+#define MX50_DMA_REQ_EXT1 15
+#define MX50_DMA_REQ_UART5_RX 16
+#define MX50_DMA_REQ_UART5_TX 17
+#define MX50_DMA_REQ_UART1_RX 18
+#define MX50_DMA_REQ_UART1_TX 19
+#define MX50_DMA_REQ_I2C1_SDHC1 20
+#define MX50_DMA_REQ_I2C2_SDHC2 21
+#define MX50_DMA_REQ_SSI2_RX2 22
+#define MX50_DMA_REQ_SSI2_TX2 23
+#define MX50_DMA_REQ_SSI2_RX1 24
+#define MX50_DMA_REQ_SSI2_TX1 25
+#define MX50_DMA_REQ_SSI1_RX2 26
+#define MX50_DMA_REQ_SSI1_TX2 27
+#define MX50_DMA_REQ_SSI1_RX1 28
+#define MX50_DMA_REQ_SSI1_TX1 29
+#define MX50_DMA_REQ_CSPI_RX 38
+#define MX50_DMA_REQ_CSPI_TX 39
+#define MX50_DMA_REQ_UART3_RX 42
+#define MX50_DMA_REQ_UART3_TX 43
+
+/*
+ * Interrupt numbers
+ */
+#define MX50_INT_ESDHC1 1
+#define MX50_INT_ESDHC2 2
+#define MX50_INT_ESDHC3 3
+#define MX50_INT_ESDHC4 4
+#define MX50_INT_DAP 5
+#define MX50_INT_SDMA 6
+#define MX50_INT_IOMUX 7
+#define MX50_INT_UART4 13
+#define MX50_INT_USB_H1 14
+#define MX50_INT_USB_OTG 18
+#define MX50_INT_DATABAHN 19
+#define MX50_INT_ELCDIF 20
+#define MX50_INT_EPXP 21
+#define MX50_INT_SRTC_NTZ 24
+#define MX50_INT_SRTC_TZ 25
+#define MX50_INT_EPDC 27
+#define MX50_INT_NIC 28
+#define MX50_INT_SSI1 29
+#define MX50_INT_SSI2 30
+#define MX50_INT_UART1 31
+#define MX50_INT_UART2 32
+#define MX50_INT_UART3 33
+#define MX50_INT_RESV34 34
+#define MX50_INT_RESV35 35
+/* eCSPI interrupts */
+#define MX50_INT_CSPI1 36
+#define MX50_INT_CSPI2 37
+/* CSPI interrupt */
+#define MX50_INT_CSPI3 38
+#define MX50_INT_GPT 39
+#define MX50_INT_EPIT1 40
+#define MX50_INT_GPIO1_INT7 42
+#define MX50_INT_GPIO1_INT6 43
+#define MX50_INT_GPIO1_INT5 44
+#define MX50_INT_GPIO1_INT4 45
+#define MX50_INT_GPIO1_INT3 46
+#define MX50_INT_GPIO1_INT2 47
+#define MX50_INT_GPIO1_INT1 48
+#define MX50_INT_GPIO1_INT0 49
+#define MX50_INT_GPIO1_LOW 50
+#define MX50_INT_GPIO1_HIGH 51
+#define MX50_INT_GPIO2_LOW 52
+#define MX50_INT_GPIO2_HIGH 53
+#define MX50_INT_GPIO3_LOW 54
+#define MX50_INT_GPIO3_HIGH 55
+#define MX50_INT_GPIO4_LOW 56
+#define MX50_INT_GPIO4_HIGH 57
+#define MX50_INT_WDOG1 58
+#define MX50_INT_KPP 60
+#define MX50_INT_PWM1 61
+#define MX50_INT_I2C1 62
+#define MX50_INT_I2C2 63
+#define MX50_INT_I2C3 64
+#define MX50_INT_RESV65 65
+#define MX50_INT_DCDC 66
+#define MX50_INT_THERMAL_ALARM 67
+#define MX50_INT_ANA3 68
+#define MX50_INT_ANA4 69
+#define MX50_INT_CCM1 71
+#define MX50_INT_CCM2 72
+#define MX50_INT_GPC1 73
+#define MX50_INT_GPC2 74
+#define MX50_INT_SRC 75
+#define MX50_INT_NM 76
+#define MX50_INT_PMU 77
+#define MX50_INT_CTI_IRQ 78
+#define MX50_INT_CTI1_TG0 79
+#define MX50_INT_CTI1_TG1 80
+#define MX50_INT_GPU2_IRQ 84
+#define MX50_INT_GPU2_BUSY 85
+#define MX50_INT_UART5 86
+#define MX50_INT_FEC 87
+#define MX50_INT_OWIRE 88
+#define MX50_INT_CTI1_TG2 89
+#define MX50_INT_SJC 90
+#define MX50_INT_DCP_CHAN1_3 91
+#define MX50_INT_DCP_CHAN0 92
+#define MX50_INT_PWM2 94
+#define MX50_INT_RNGB 97
+#define MX50_INT_CTI1_TG3 98
+#define MX50_INT_RAWNAND_BCH 100
+#define MX50_INT_RAWNAND_GPMI 102
+#define MX50_INT_GPIO5_LOW 103
+#define MX50_INT_GPIO5_HIGH 104
+#define MX50_INT_GPIO6_LOW 105
+#define MX50_INT_GPIO6_HIGH 106
+#define MX50_INT_MSHC 109
+#define MX50_INT_APBHDMA_CHAN0 110
+#define MX50_INT_APBHDMA_CHAN1 111
+#define MX50_INT_APBHDMA_CHAN2 112
+#define MX50_INT_APBHDMA_CHAN3 113
+#define MX50_INT_APBHDMA_CHAN4 114
+#define MX50_INT_APBHDMA_CHAN5 115
+#define MX50_INT_APBHDMA_CHAN6 116
+#define MX50_INT_APBHDMA_CHAN7 117
+
+/* DMA */
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI0 0
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI1 1
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI2 2
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI3 3
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI4 4
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI5 5
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI6 6
+#define MX50_DMA_CHANNEL_AHB_APBH_GPMI7 7
+#define MX50_DMA_CHANNEL_AHB_APBH_SSP 8
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx50_revision(void);
+#endif
+
+#endif /* ifndef __MACH_MX50_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
new file mode 100755
index 00000000..9db86a19
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -0,0 +1,382 @@
+#ifndef __MACH_MX51_H__
+#define __MACH_MX51_H__
+
+/*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR 0x0
+#define MX51_IROM_SIZE SZ_64K
+
+/*
+ * IRAM
+ */
+#define MX51_IRAM_BASE_ADDR 0x1ffe0000 /* internal ram */
+#define MX51_IRAM_PARTITIONS 16
+#define MX51_IRAM_SIZE (MX51_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * SCC RAM: shares IRAM space
+ */
+#define MX51_SCC_RAM_BASE_ADDR MX51_IRAM_BASE_ADDR
+
+#if defined(CONFIG_MXC_SECURITY_SCC2) \
+ || defined(CONFIG_MXC_SECURITY_SCC2_MODULE)
+#define MX51_SCC_RAM_SIZE SZ_16K /* 2 partitions of 8 KB from IRAM */
+#else
+#define MX51_SCC_RAM_SIZE 0
+#endif
+
+#define MX51_GPU_GMEM_BASE_ADDR 0x20000000
+#define MX51_GPU_GMEM_SIZE SZ_128K
+#define MX51_GPU_BASE_ADDR 0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR 0x40000000
+
+#define MX51_DEBUG_BASE_ADDR 0x60000000
+#define MX51_DEBUG_SIZE SZ_1M
+
+#define MX51_ETB_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x01000)
+#define MX51_ETM_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x02000)
+#define MX51_TPIU_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x03000)
+#define MX51_CTI0_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x04000)
+#define MX51_CTI1_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x05000)
+#define MX51_CTI2_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x06000)
+#define MX51_CTI3_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x07000)
+#define MX51_CORTEX_DBG_BASE_ADDR (MX51_DEBUG_BASE_ADDR + 0x08000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX51_SPBA0_BASE_ADDR 0x70000000
+#define MX51_SPBA0_SIZE SZ_1M
+
+#define MX51_ESDHC1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x04000)
+#define MX51_ESDHC2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x08000)
+#define MX51_UART3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x0c000)
+#define MX51_ECSPI1_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x10000)
+#define MX51_SSI2_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x14000)
+#define MX51_ESDHC3_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x20000)
+#define MX51_ESDHC4_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x24000)
+#define MX51_SPDIF_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x28000)
+#define MX51_ATA_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x30000)
+#define MX51_SLIM_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x34000)
+#define MX51_HSI2C_DMA_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x38000)
+#define MX51_SPBA_CTRL_BASE_ADDR (MX51_SPBA0_BASE_ADDR + 0x3c000)
+
+/*
+ * AIPS 1
+ */
+#define MX51_AIPS1_BASE_ADDR 0x73f00000
+#define MX51_AIPS1_SIZE SZ_1M
+
+#define MX51_OTG_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x80000)
+#define MX51_GPIO1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x84000)
+#define MX51_GPIO2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x88000)
+#define MX51_GPIO3_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x8c000)
+#define MX51_GPIO4_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x90000)
+#define MX51_KPP_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x94000)
+#define MX51_WDOG1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x98000)
+#define MX51_WDOG2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0x9c000)
+#define MX51_GPT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa0000)
+#define MX51_SRTC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa4000)
+#define MX51_IOMUXC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xa8000)
+#define MX51_EPIT1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xac000)
+#define MX51_EPIT2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb0000)
+#define MX51_PWM1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb4000)
+#define MX51_PWM2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xb8000)
+#define MX51_UART1_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xbc000)
+#define MX51_UART2_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xc0000)
+#define MX51_SRC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd0000)
+#define MX51_CCM_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd4000)
+#define MX51_GPC_BASE_ADDR (MX51_AIPS1_BASE_ADDR + 0xd8000)
+#define MX51_DVFSCORE_BASE_ADDR (MX51_GPC_BASE_ADDR + 0x180)
+
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR 0x83f00000
+#define MX51_AIPS2_SIZE SZ_1M
+
+#define MX51_PLL1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x80000)
+#define MX51_PLL2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x84000)
+#define MX51_PLL3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x88000)
+#define MX51_AHBMAX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x94000)
+#define MX51_IIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x98000)
+#define MX51_CSU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0x9c000)
+#define MX51_ARM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa0000)
+#define MX51_OWIRE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa4000)
+#define MX51_FIRI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xa8000)
+#define MX51_ECSPI2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xac000)
+#define MX51_SDMA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb0000)
+#define MX51_SCC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb4000)
+#define MX51_ROMCP_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xb8000)
+#define MX51_RTIC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xbc000)
+#define MX51_CSPI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc0000)
+#define MX51_I2C2_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc4000)
+#define MX51_I2C1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xc8000)
+#define MX51_SSI1_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xcc000)
+#define MX51_AUDMUX_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd0000)
+#define MX51_M4IF_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd8000)
+#define MX51_ESDCTL_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xd9000)
+#define MX51_WEIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xda000)
+#define MX51_NFC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdb000)
+#define MX51_EMI_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdbf00)
+#define MX51_MIPI_HSC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xdc000)
+#define MX51_ATA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe0000)
+#define MX51_SIM_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe4000)
+#define MX51_SSI3_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xe8000)
+#define MX51_FEC_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xec000)
+#define MX51_TVE_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf0000)
+#define MX51_VPU_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf4000)
+#define MX51_SAHARA_BASE_ADDR (MX51_AIPS2_BASE_ADDR + 0xf8000)
+
+#define MX51_CSD0_BASE_ADDR 0x90000000
+#define MX51_CSD1_BASE_ADDR 0xa0000000
+#define MX51_CS0_BASE_ADDR 0xb0000000
+#define MX51_CS1_BASE_ADDR 0xb8000000
+#define MX51_CS2_BASE_ADDR 0xc0000000
+#define MX51_CS3_BASE_ADDR 0xc8000000
+#define MX51_CS4_BASE_ADDR 0xcc000000
+#define MX51_CS5_BASE_ADDR 0xce000000
+
+/*
+ * NFC
+ */
+#define MX51_NFC_AXI_BASE_ADDR 0xcfff0000 /* NAND flash AXI */
+#define MX51_NFC_AXI_SIZE SZ_64K
+
+#define MX51_GPU2D_BASE_ADDR 0xd0000000
+#define MX51_TZIC_BASE_ADDR 0xe0000000
+
+#define MX51_IO_P2V(x) IMX_IO_P2V(x)
+#define MX51_IO_ADDRESS(x) IOMEM(MX51_IO_P2V(x))
+
+/* PGC */
+#define MX51_GPC_BASE (MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR))
+#define MX51_PGC_IPU_BASE (MX51_GPC_BASE + 0x220)
+#define MX51_PGC_VPU_BASE (MX51_GPC_BASE + 0x240)
+#define MX51_PGC_GPU_BASE (MX51_GPC_BASE + 0x260)
+#define MX51_PGC_IPU_PGCR (MX51_PGC_IPU_BASE + 0x0)
+#define MX51_PGC_IPU_PGSR (MX51_PGC_IPU_BASE + 0xC)
+#define MX51_PGC_VPU_PGCR (MX51_PGC_VPU_BASE + 0x0)
+#define MX51_PGC_VPU_PGSR (MX51_PGC_VPU_BASE + 0xC)
+#define MX51_PGC_GPU_PGCR (MX51_PGC_GPU_BASE + 0x0)
+#define MX51_PGC_GPU_PGSR (MX51_PGC_GPU_BASE + 0xC)
+
+/*
+ * defines for SPBA modules
+ */
+#define MX51_SPBA_SDHC1 0x04
+#define MX51_SPBA_SDHC2 0x08
+#define MX51_SPBA_UART3 0x0c
+#define MX51_SPBA_CSPI1 0x10
+#define MX51_SPBA_SSI2 0x14
+#define MX51_SPBA_SDHC3 0x20
+#define MX51_SPBA_SDHC4 0x24
+#define MX51_SPBA_SPDIF 0x28
+#define MX51_SPBA_ATA 0x30
+#define MX51_SPBA_SLIM 0x34
+#define MX51_SPBA_HSI2C 0x38
+#define MX51_SPBA_CTRL 0x3c
+
+/*
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MX51_MXC_DMA_CHANNEL_IRAM 30
+#define MX51_MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX (MX51_MXC_DMA_CHANNEL_IRAM + 1)
+#else /*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif /*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+
+#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
+
+/*
+ * DMA request assignments
+ */
+#define MX51_DMA_REQ_VPU 0
+#define MX51_DMA_REQ_GPC 1
+#define MX51_DMA_REQ_ATA_RX 2
+#define MX51_DMA_REQ_ATA_TX 3
+#define MX51_DMA_REQ_ATA_TX_END 4
+#define MX51_DMA_REQ_SLIM_B 5
+#define MX51_DMA_REQ_CSPI1_RX 6
+#define MX51_DMA_REQ_CSPI1_TX 7
+#define MX51_DMA_REQ_CSPI2_RX 8
+#define MX51_DMA_REQ_CSPI2_TX 9
+#define MX51_DMA_REQ_HS_I2C_TX 10
+#define MX51_DMA_REQ_HS_I2C_RX 11
+#define MX51_DMA_REQ_FIRI_RX 12
+#define MX51_DMA_REQ_FIRI_TX 13
+#define MX51_DMA_REQ_EXTREQ1 14
+#define MX51_DMA_REQ_GPU 15
+#define MX51_DMA_REQ_UART2_RX 16
+#define MX51_DMA_REQ_UART2_TX 17
+#define MX51_DMA_REQ_UART1_RX 18
+#define MX51_DMA_REQ_UART1_TX 19
+#define MX51_DMA_REQ_SDHC1 20
+#define MX51_DMA_REQ_SDHC2 21
+#define MX51_DMA_REQ_SSI2_RX1 22
+#define MX51_DMA_REQ_SSI2_TX1 23
+#define MX51_DMA_REQ_SSI2_RX0 24
+#define MX51_DMA_REQ_SSI2_TX0 25
+#define MX51_DMA_REQ_SSI1_RX1 26
+#define MX51_DMA_REQ_SSI1_TX1 27
+#define MX51_DMA_REQ_SSI1_RX0 28
+#define MX51_DMA_REQ_SSI1_TX0 29
+#define MX51_DMA_REQ_EMI_RD 30
+#define MX51_DMA_REQ_CTI2_0 31
+#define MX51_DMA_REQ_EMI_WR 32
+#define MX51_DMA_REQ_CTI2_1 33
+#define MX51_DMA_REQ_EPIT2 34
+#define MX51_DMA_REQ_SSI3_RX1 35
+#define MX51_DMA_REQ_IPU 36
+#define MX51_DMA_REQ_SSI3_TX1 37
+#define MX51_DMA_REQ_CSPI_RX 38
+#define MX51_DMA_REQ_CSPI_TX 39
+#define MX51_DMA_REQ_SDHC3 40
+#define MX51_DMA_REQ_SDHC4 41
+#define MX51_DMA_REQ_SLIM_B_TX 42
+#define MX51_DMA_REQ_UART3_RX 43
+#define MX51_DMA_REQ_UART3_TX 44
+#define MX51_DMA_REQ_SPDIF 45
+#define MX51_DMA_REQ_SSI3_RX0 46
+#define MX51_DMA_REQ_SSI3_TX0 47
+
+/*
+ * Interrupt numbers
+ */
+#define MX51_MXC_INT_BASE 0
+#define MX51_MXC_INT_RESV0 0
+#define MX51_INT_ESDHC1 1
+#define MX51_INT_ESDHC2 2
+#define MX51_INT_ESDHC3 3
+#define MX51_INT_ESDHC4 4
+#define MX51_MXC_INT_RESV5 5
+#define MX51_INT_SDMA 6
+#define MX51_MXC_INT_IOMUX 7
+#define MX51_INT_NFC 8
+#define MX51_INT_VPU 9
+#define MX51_INT_IPU_ERR 10
+#define MX51_INT_IPU_SYN 11
+#define MX51_INT_GPU 12
+#define MX51_MXC_INT_RESV13 13
+#define MX51_MXC_INT_USB_H1 14
+#define MX51_MXC_INT_EMI 15
+#define MX51_MXC_INT_USB_H2 16
+#define MX51_MXC_INT_USB_H3 17
+#define MX51_MXC_INT_USB_OTG 18
+#define MX51_MXC_INT_SAHARA_H0 19
+#define MX51_MXC_INT_SAHARA_H1 20
+#define MX51_INT_SCC_SMN 21
+#define MX51_INT_SCC_STZ 22
+#define MX51_INT_SCC_SCM 23
+#define MX51_INT_SRTC_NTZ 24
+#define MX51_INT_SRTC_TZ 25
+#define MX51_MXC_INT_RTIC 26
+#define MX51_MXC_INT_CSU 27
+#define MX51_MXC_INT_SLIM_B 28
+#define MX51_INT_SSI1 29
+#define MX51_INT_SSI2 30
+#define MX51_INT_UART1 31
+#define MX51_INT_UART2 32
+#define MX51_INT_UART3 33
+#define MX51_MXC_INT_RESV34 34
+#define MX51_MXC_INT_RESV35 35
+#define MX51_INT_ECSPI1 36
+#define MX51_INT_ECSPI2 37
+#define MX51_INT_CSPI 38
+#define MX51_MXC_INT_GPT 39
+#define MX51_MXC_INT_EPIT1 40
+#define MX51_MXC_INT_EPIT2 41
+#define MX51_MXC_INT_GPIO1_INT7 42
+#define MX51_MXC_INT_GPIO1_INT6 43
+#define MX51_MXC_INT_GPIO1_INT5 44
+#define MX51_MXC_INT_GPIO1_INT4 45
+#define MX51_MXC_INT_GPIO1_INT3 46
+#define MX51_MXC_INT_GPIO1_INT2 47
+#define MX51_MXC_INT_GPIO1_INT1 48
+#define MX51_MXC_INT_GPIO1_INT0 49
+#define MX51_MXC_INT_GPIO1_LOW 50
+#define MX51_MXC_INT_GPIO1_HIGH 51
+#define MX51_MXC_INT_GPIO2_LOW 52
+#define MX51_MXC_INT_GPIO2_HIGH 53
+#define MX51_MXC_INT_GPIO3_LOW 54
+#define MX51_MXC_INT_GPIO3_HIGH 55
+#define MX51_MXC_INT_GPIO4_LOW 56
+#define MX51_MXC_INT_GPIO4_HIGH 57
+#define MX51_MXC_INT_WDOG1 58
+#define MX51_MXC_INT_WDOG2 59
+#define MX51_INT_KPP 60
+#define MX51_INT_PWM1 61
+#define MX51_INT_I2C1 62
+#define MX51_INT_I2C2 63
+#define MX51_MXC_INT_HS_I2C 64
+#define MX51_MXC_INT_RESV65 65
+#define MX51_MXC_INT_RESV66 66
+#define MX51_MXC_INT_SIM_IPB 67
+#define MX51_MXC_INT_SIM_DAT 68
+#define MX51_INT_IIM 69
+#define MX51_MXC_INT_ATA 70
+#define MX51_MXC_INT_CCM1 71
+#define MX51_MXC_INT_CCM2 72
+#define MX51_INT_GPC1 73
+#define MX51_INT_GPC2 74
+#define MX51_MXC_INT_SRC 75
+#define MX51_MXC_INT_NM 76
+#define MX51_MXC_INT_PMU 77
+#define MX51_MXC_INT_CTI_IRQ 78
+#define MX51_MXC_INT_CTI1_TG0 79
+#define MX51_MXC_INT_CTI1_TG1 80
+#define MX51_MXC_INT_MCG_ERR 81
+#define MX51_MXC_INT_MCG_TMR 82
+#define MX51_MXC_INT_MCG_FUNC 83
+#define MX51_INT_GPU2_IRQ 84
+#define MX51_MXC_INT_GPU2_BUSY 85
+#define MX51_MXC_INT_RESV86 86
+#define MX51_INT_FEC 87
+#define MX51_MXC_INT_OWIRE 88
+#define MX51_MXC_INT_CTI1_TG2 89
+#define MX51_MXC_INT_SJC 90
+#define MX51_INT_SPDIF 91
+#define MX51_INT_TVE 92
+#define MX51_MXC_INT_FIRI 93
+#define MX51_INT_PWM2 94
+#define MX51_MXC_INT_SLIM_EXP 95
+#define MX51_INT_SSI3 96
+#define MX51_MXC_INT_EMI_BOOT 97
+#define MX51_MXC_INT_CTI1_TG3 98
+#define MX51_MXC_INT_SMC_RX 99
+#define MX51_MXC_INT_VPU_IDLE 100
+#define MX51_MXC_INT_EMI_NFC 101
+#define MX51_MXC_INT_GPU_IDLE 102
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx51_revision(void);
+extern void mx51_display_revision(void);
+#endif
+
+/* tape-out 1 defines */
+#define MX51_TZIC_BASE_ADDR_TO1 0x8fffc000
+
+#endif /* ifndef __MACH_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx53.h b/arch/arm/plat-mxc/include/mach/mx53.h
new file mode 100755
index 00000000..1bcddd63
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx53.h
@@ -0,0 +1,392 @@
+#ifndef __MACH_MX53_H__
+#define __MACH_MX53_H__
+
+/*
+ * IROM
+ */
+#define MX53_IROM_BASE_ADDR 0x0
+#define MX53_IROM_SIZE SZ_64K
+
+/* TZIC */
+#define MX53_TZIC_BASE_ADDR 0x0FFFC000
+
+/*
+ * AHCI SATA
+ */
+#define MX53_SATA_BASE_ADDR 0x10000000
+
+/*
+ * NFC
+ */
+#define MX53_NFC_AXI_BASE_ADDR 0xF7FF0000 /* NAND flash AXI */
+#define MX53_NFC_AXI_SIZE SZ_64K
+
+/*
+ * IRAM
+ */
+#define MX53_IRAM_BASE_ADDR 0xF8000000 /* internal ram */
+#define MX53_IRAM_PARTITIONS 16
+#define MX53_IRAM_SIZE (MX53_IRAM_PARTITIONS * SZ_8K) /* 128KB */
+
+/*
+ * SCC RAM
+ */
+#define MX53_SCC_RAM_BASE_ADDR 0x07000000
+#define MX53_SCC_RAM_PARTITIONS 4
+ /* 16 KB */
+#define MX53_SCC_RAM_SIZE (MX53_SCC_RAM_PARTITIONS * SZ_4K)
+
+#ifdef CONFIG_MXC_VPU_IRAM
+#define VPU_IRAM_SIZE 0x14000
+#else
+#define VPU_IRAM_SIZE 0
+#endif
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX53_IPU_CTRL_BASE_ADDR 0x18000000
+#define MX53_GPU2D_BASE_ADDR 0x20000000
+#define MX53_GPU_BASE_ADDR 0x30000000
+#define MX53_GPU_GMEM_BASE_ADDR 0xF8020000
+#define MX53_GPU_GMEM_SIZE SZ_256K
+
+#define MX53_DEBUG_BASE_ADDR 0x40000000
+#define MX53_DEBUG_SIZE SZ_1M
+#define MX53_ETB_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00001000)
+#define MX53_ETM_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00002000)
+#define MX53_TPIU_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00003000)
+#define MX53_CTI0_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00004000)
+#define MX53_CTI1_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00005000)
+#define MX53_CTI2_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00006000)
+#define MX53_CTI3_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00007000)
+#define MX53_CORTEX_DBG_BASE_ADDR (MX53_DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX53_SPBA0_BASE_ADDR 0x50000000
+#define MX53_SPBA0_SIZE SZ_1M
+
+#define MX53_ESDHC1_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00004000)
+#define MX53_ESDHC2_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00008000)
+#define MX53_UART3_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0000C000)
+#define MX53_ECSPI1_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00010000)
+#define MX53_SSI2_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00014000)
+#define MX53_ESAI_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00018000)
+#define MX53_ESDHC3_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00020000)
+#define MX53_ESDHC4_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00024000)
+#define MX53_SPDIF_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00028000)
+#define MX53_ASRC_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0002C000)
+#define MX53_ATA_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00030000)
+#define MX53_SLIM_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00034000)
+#define MX53_HSI2C_DMA_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x00038000)
+#define MX53_SPBA_CTRL_BASE_ADDR (MX53_SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * AIPS 1
+ */
+#define MX53_AIPS1_BASE_ADDR 0x53F00000
+#define MX53_AIPS1_SIZE SZ_1M
+
+#define MX53_OTG_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00080000)
+#define MX53_GPIO1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00084000)
+#define MX53_GPIO2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00088000)
+#define MX53_GPIO3_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX53_GPIO4_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00090000)
+#define MX53_KPP_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00094000)
+#define MX53_WDOG1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x00098000)
+#define MX53_WDOG2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX53_GPT1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX53_SRTC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX53_IOMUXC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX53_EPIT1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX53_EPIT2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX53_PWM1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX53_PWM2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX53_UART1_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX53_UART2_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX53_SRC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX53_CCM_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX53_GPC_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000D8000)
+#define MX53_GPIO5_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000DC000)
+#define MX53_GPIO6_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E0000)
+#define MX53_GPIO7_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E4000)
+#define MX53_ATA_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000E8000)
+#define MX53_I2C3_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000EC000)
+#define MX53_UART4_BASE_ADDR (MX53_AIPS1_BASE_ADDR + 0x000F0000)
+#define MX53_DVFSCORE_BASE_ADDR (MX53_GPC_BASE_ADDR + 0x180)
+
+/*
+ * AIPS 2
+ */
+#define MX53_AIPS2_BASE_ADDR 0x63F00000
+#define MX53_AIPS2_SIZE SZ_1M
+
+#define MX53_PLL1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00080000)
+#define MX53_PLL2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00084000)
+#define MX53_PLL3_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00088000)
+#define MX53_PLL4_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x0008C000)
+#define MX53_UART5_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00090000)
+#define MX53_AHBMAX_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00094000)
+#define MX53_IIM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x00098000)
+#define MX53_CSU_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX53_ARM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX53_OWIRE_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX53_FIRI_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX53_ECSPI2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX53_SDMA_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX53_SCC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX53_ROMCP_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX53_RTIC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX53_CSPI_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX53_I2C2_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX53_I2C1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX53_SSI1_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX53_AUDMUX_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX53_RTC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D4000)
+#define MX53_M4IF_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX53_ESDCTL_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX53_WEIM_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX53_NFC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX53_EMI_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX53_MIPI_HSC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX53_MLB_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX53_SSI3_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX53_FEC_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX53_TVE_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX53_VPU_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX53_SAHARA_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000F8000)
+#define MX53_PTP_BASE_ADDR (MX53_AIPS2_BASE_ADDR + 0x000FC000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX53_CSD0_BASE_ADDR 0x90000000
+#define MX53_CSD1_BASE_ADDR 0xA0000000
+#define MX53_CS0_BASE_ADDR 0xF0000000
+#define MX53_CS1_BASE_ADDR 0xF4000000
+#define MX53_CS2_BASE_ADDR 0xC0000000
+#define MX53_CS3_BASE_ADDR 0xC8000000
+#define MX53_CS4_BASE_ADDR 0xCC000000
+#define MX53_CS5_BASE_ADDR 0xCE000000
+
+#define MX53_IO_P2V(x) IMX_IO_P2V(x)
+#define MX53_IO_ADDRESS(x) IOMEM(MX53_IO_P2V(x))
+
+/* PGC */
+#define MX53_GPC_BASE (MX53_IO_ADDRESS(MX53_GPC_BASE_ADDR))
+#define MX53_PGC_IPU_BASE (MX53_GPC_BASE + 0x220)
+#define MX53_PGC_VPU_BASE (MX53_GPC_BASE + 0x240)
+#define MX53_PGC_GPU_BASE (MX53_GPC_BASE + 0x260)
+#define MX53_PGC_IPU_PGCR (MX53_PGC_IPU_BASE + 0x0)
+#define MX53_PGC_IPU_PGSR (MX53_PGC_IPU_BASE + 0xC)
+#define MX53_PGC_VPU_PGCR (MX53_PGC_VPU_BASE + 0x0)
+#define MX53_PGC_VPU_PGSR (MX53_PGC_VPU_BASE + 0xC)
+#define MX53_PGC_GPU_PGCR (MX53_PGC_GPU_BASE + 0x0)
+#define MX53_PGC_GPU_PGSR (MX53_PGC_GPU_BASE + 0xC)
+
+/*
+ * defines for SPBA modules
+ */
+#define MX53_SPBA_SDHC1 0x04
+#define MX53_SPBA_SDHC2 0x08
+#define MX53_SPBA_UART3 0x0C
+#define MX53_SPBA_CSPI1 0x10
+#define MX53_SPBA_SSI2 0x14
+#define MX53_SPBA_SDHC3 0x20
+#define MX53_SPBA_SDHC4 0x24
+#define MX53_SPBA_SPDIF 0x28
+#define MX53_SPBA_ATA 0x30
+#define MX53_SPBA_SLIM 0x34
+#define MX53_SPBA_HSI2C 0x38
+#define MX53_SPBA_CTRL 0x3C
+
+/*
+ * DMA request assignments
+ */
+#define MX53_DMA_REQ_SSI3_TX0 47
+#define MX53_DMA_REQ_SSI3_RX0 46
+#define MX53_DMA_REQ_SSI3_TX1 45
+#define MX53_DMA_REQ_SSI3_RX1 44
+#define MX53_DMA_REQ_UART3_TX 43
+#define MX53_DMA_REQ_UART3_RX 42
+#define MX53_DMA_REQ_ESAI_TX 41
+#define MX53_DMA_REQ_ESAI_RX 40
+#define MX53_DMA_REQ_CSPI_TX 39
+#define MX53_DMA_REQ_CSPI_RX 38
+#define MX53_DMA_REQ_ASRC_DMA6 37
+#define MX53_DMA_REQ_ASRC_DMA5 36
+#define MX53_DMA_REQ_ASRC_DMA4 35
+#define MX53_DMA_REQ_ASRC_DMA3 34
+#define MX53_DMA_REQ_ASRC_DMA2 33
+#define MX53_DMA_REQ_ASRC_DMA1 32
+#define MX53_DMA_REQ_EMI_WR 31
+#define MX53_DMA_REQ_EMI_RD 30
+#define MX53_DMA_REQ_SSI1_TX0 29
+#define MX53_DMA_REQ_SSI1_RX0 28
+#define MX53_DMA_REQ_SSI1_TX1 27
+#define MX53_DMA_REQ_SSI1_RX1 26
+#define MX53_DMA_REQ_SSI2_TX0 25
+#define MX53_DMA_REQ_SSI2_RX0 24
+#define MX53_DMA_REQ_SSI2_TX1 23
+#define MX53_DMA_REQ_SSI2_RX1 22
+#define MX53_DMA_REQ_I2C2_SDHC2 21
+#define MX53_DMA_REQ_I2C1_SDHC1 20
+#define MX53_DMA_REQ_UART1_TX 19
+#define MX53_DMA_REQ_UART1_RX 18
+#define MX53_DMA_REQ_UART5_TX 17
+#define MX53_DMA_REQ_UART5_RX 16
+#define MX53_DMA_REQ_SPDIF_TX 15
+#define MX53_DMA_REQ_SPDIF_RX 14
+#define MX53_DMA_REQ_UART2_FIRI_TX 13
+#define MX53_DMA_REQ_UART2_FIRI_RX 12
+#define MX53_DMA_REQ_SDHC4 11
+#define MX53_DMA_REQ_I2C3_SDHC3 10
+#define MX53_DMA_REQ_CSPI2_TX 9
+#define MX53_DMA_REQ_CSPI2_RX 8
+#define MX53_DMA_REQ_CSPI1_TX 7
+#define MX53_DMA_REQ_CSPI1_RX 6
+#define MX53_DMA_REQ_IPU 5
+#define MX53_DMA_REQ_ATA_TX_END 4
+#define MX53_DMA_REQ_ATA_UART4_TX 3
+#define MX53_DMA_REQ_ATA_UART4_RX 2
+#define MX53_DMA_REQ_GPC 1
+#define MX53_DMA_REQ_VPU 0
+
+/*
+ * Interrupt numbers
+ */
+#define MX53_INT_RESV0 0
+#define MX53_INT_ESDHC1 1
+#define MX53_INT_ESDHC2 2
+#define MX53_INT_ESDHC3 3
+#define MX53_INT_ESDHC4 4
+#define MX53_INT_RESV5 5
+#define MX53_INT_SDMA 6
+#define MX53_INT_IOMUX 7
+#define MX53_INT_NFC 8
+#define MX53_INT_VPU 9
+#define MX53_INT_IPU_ERR 10
+#define MX53_INT_IPU_SYN 11
+#define MX53_INT_GPU 12
+#define MX53_INT_RESV13 13
+#define MX53_INT_USB_H1 14
+#define MX53_INT_EMI 15
+#define MX53_INT_USB_H2 16
+#define MX53_INT_USB_H3 17
+#define MX53_INT_USB_OTG 18
+#define MX53_INT_SAHARA_H0 19
+#define MX53_INT_SAHARA_H1 20
+#define MX53_INT_SCC_SMN 21
+#define MX53_INT_SCC_STZ 22
+#define MX53_INT_SCC_SCM 23
+#define MX53_INT_SRTC_NTZ 24
+#define MX53_INT_SRTC_TZ 25
+#define MX53_INT_RTIC 26
+#define MX53_INT_CSU 27
+#define MX53_INT_SATA 28
+#define MX53_INT_SSI1 29
+#define MX53_INT_SSI2 30
+#define MX53_INT_UART1 31
+#define MX53_INT_UART2 32
+#define MX53_INT_UART3 33
+#define MX53_INT_RESV34 34
+#define MX53_INT_RESV35 35
+#define MX53_INT_ECSPI1 36
+#define MX53_INT_ECSPI2 37
+#define MX53_INT_CSPI 38
+#define MX53_INT_GPT 39
+#define MX53_INT_EPIT1 40
+#define MX53_INT_EPIT2 41
+#define MX53_INT_GPIO1_INT7 42
+#define MX53_INT_GPIO1_INT6 43
+#define MX53_INT_GPIO1_INT5 44
+#define MX53_INT_GPIO1_INT4 45
+#define MX53_INT_GPIO1_INT3 46
+#define MX53_INT_GPIO1_INT2 47
+#define MX53_INT_GPIO1_INT1 48
+#define MX53_INT_GPIO1_INT0 49
+#define MX53_INT_GPIO1_LOW 50
+#define MX53_INT_GPIO1_HIGH 51
+#define MX53_INT_GPIO2_LOW 52
+#define MX53_INT_GPIO2_HIGH 53
+#define MX53_INT_GPIO3_LOW 54
+#define MX53_INT_GPIO3_HIGH 55
+#define MX53_INT_GPIO4_LOW 56
+#define MX53_INT_GPIO4_HIGH 57
+#define MX53_INT_WDOG1 58
+#define MX53_INT_WDOG2 59
+#define MX53_INT_KPP 60
+#define MX53_INT_PWM1 61
+#define MX53_INT_I2C1 62
+#define MX53_INT_I2C2 63
+#define MX53_INT_I2C3 64
+#define MX53_INT_RESV65 65
+#define MX53_INT_RESV66 66
+#define MX53_INT_SPDIF 67
+#define MX53_INT_SIM_DAT 68
+#define MX53_INT_IIM 69
+#define MX53_INT_ATA 70
+#define MX53_INT_CCM1 71
+#define MX53_INT_CCM2 72
+#define MX53_INT_GPC1 73
+#define MX53_INT_GPC2 74
+#define MX53_INT_SRC 75
+#define MX53_INT_NM 76
+#define MX53_INT_PMU 77
+#define MX53_INT_CTI_IRQ 78
+#define MX53_INT_CTI1_TG0 79
+#define MX53_INT_CTI1_TG1 80
+#define MX53_INT_ESAI 81
+#define MX53_INT_CAN1 82
+#define MX53_INT_CAN2 83
+#define MX53_INT_GPU2_IRQ 84
+#define MX53_INT_GPU2_BUSY 85
+#define MX53_INT_RESV86 86
+#define MX53_INT_FEC 87
+#define MX53_INT_OWIRE 88
+#define MX53_INT_CTI1_TG2 89
+#define MX53_INT_SJC 90
+#define MX53_INT_TVE 92
+#define MX53_INT_FIRI 93
+#define MX53_INT_PWM2 94
+#define MX53_INT_SLIM_EXP 95
+#define MX53_INT_SSI3 96
+#define MX53_INT_EMI_BOOT 97
+#define MX53_INT_CTI1_TG3 98
+#define MX53_INT_SMC_RX 99
+#define MX53_INT_VPU_IDLE 100
+#define MX53_INT_EMI_NFC 101
+#define MX53_INT_GPU_IDLE 102
+#define MX53_INT_GPIO5_LOW 103
+#define MX53_INT_GPIO5_HIGH 104
+#define MX53_INT_GPIO6_LOW 105
+#define MX53_INT_GPIO6_HIGH 106
+#define MX53_INT_GPIO7_LOW 107
+#define MX53_INT_GPIO7_HIGH 108
+
+/* silicon revisions specific to i.MX53 */
+#define MX53_CHIP_REV_1_0 0x10
+#define MX53_CHIP_REV_1_1 0x11
+#define MX53_CHIP_REV_1_2 0x12
+#define MX53_CHIP_REV_1_3 0x13
+#define MX53_CHIP_REV_2_0 0x20
+#define MX53_CHIP_REV_2_1 0x21
+#define MX53_CHIP_REV_2_2 0x22
+#define MX53_CHIP_REV_2_3 0x23
+#define MX53_CHIP_REV_3_0 0x30
+#define MX53_CHIP_REV_3_1 0x31
+#define MX53_CHIP_REV_3_2 0x32
+
+/*!
+ * IIM bank info
+ */
+#define MXC_IIM_MX51_BANK_START_ADDR 0x0800
+#define MXC_IIM_MX51_BANK_END_ADDR 0x147c
+#define MXC_IIM_MX53_BANK_START_ADDR 0x0800
+#define MXC_IIM_MX53_BANK_END_ADDR 0x183c
+#define MXC_IIM_MX53_BANK_AREA_1_OFFSET 0xc00
+#define MXC_IIM_MX53_MAC_ADDR_OFFSET 0x24
+
+#endif /* ifndef __MACH_MX53_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx6.h b/arch/arm/plat-mxc/include/mach/mx6.h
new file mode 100644
index 00000000..50c2d5a7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx6.h
@@ -0,0 +1,594 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_MX6_H__
+#define __ASM_ARCH_MXC_MX6_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * @file arch-mxc/mx6.h
+ * @brief This file contains register definitions.
+ *
+ * @ingroup MSL_MX6
+ */
+
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*!
+ * This option is used to set or clear the RXDMUXSEL bit in control reg 3.
+ * Certain platforms need this bit to be set in order to receive Irda data.
+ */
+#define MXC_UART_IR_RXDMUX 0x0004
+/*!
+ * This option is used to set or clear the RXDMUXSEL bit in control reg 3.
+ * Certain platforms need this bit to be set in order to receive UART data.
+ */
+#define MXC_UART_RXDMUX 0x0004
+
+/*!
+ * The maximum frequency that the pixel clock can be at so as to
+ * activate DVFS-PER.
+ */
+#define DVFS_MAX_PIX_CLK 54000000
+
+/* IROM
+ */
+#define IROM_BASE_ADDR 0x0
+#define IROM_SIZE SZ_64K
+
+/* CPU Memory Map */
+#define MMDC0_ARB_BASE_ADDR 0x10000000
+#define MMDC0_ARB_END_ADDR 0x7FFFFFFF
+#define MMDC1_ARB_BASE_ADDR 0x80000000
+#define MMDC1_ARB_END_ADDR 0xFFFFFFFF
+#define MX6SL_MMDC0_ARB_BASE_ADDR 0x80000000 /* only MX6SL */
+#define MX6SL_MMDC0_ARB_END_ADDR 0xFFFFFFFF
+#define OCRAM_ARB_BASE_ADDR 0x00900000
+#define OCRAM_ARB_END_ADDR 0x009FFFFF
+#define IRAM_BASE_ADDR OCRAM_ARB_BASE_ADDR
+#define PCIE_ARB_BASE_ADDR 0x01000000
+#define PCIE_ARB_END_ADDR 0x01FFFFFF
+
+/*
+ * IRAM page table setup.
+ * The size defined here includes the code size plus the memory
+ * needed to store DDR IOMUX pad settings and the ARM SRPG registers.
+ */
+#define MX6_IRAM_TLB_BASE_ADDR IRAM_BASE_ADDR
+#define MX6_IRAM_TLB_SIZE SZ_16K
+#define TT_ATTRIB_NON_CACHEABLE_1M 0x802
+#define MX6Q_IRAM_BASE_ADDR (IRAM_BASE_ADDR + MX6_IRAM_TLB_SIZE)
+#define MX6_SUSPEND_IRAM_CODE IRAM_BASE_ADDR
+#define MX6_SUSPEND_CODE_SIZE 0x1400
+#define MX6_DDR_FREQ_IRAM_CODE (MX6_SUSPEND_IRAM_CODE + MX6_SUSPEND_CODE_SIZE)
+#define MX6SL_DDR_FREQ_CODE_SIZE 0x500
+#define MX6SL_WFI_IRAM_CODE (MX6_DDR_FREQ_IRAM_CODE + MX6SL_DDR_FREQ_CODE_SIZE)
+#define MX6SL_WFI_IRAM_CODE_SIZE SZ_8K - MX6_SUSPEND_CODE_SIZE - MX6SL_DDR_FREQ_CODE_SIZE
+
+/* The last 4K is for cpu hotplug to workaround wdog issue*/
+#define MX6Q_IRAM_SIZE (SZ_256K - SZ_4K)
+#define MX6DL_MX6SL_IRAM_SIZE (SZ_128K - SZ_4K - MX6_IRAM_TLB_SIZE)
+
+/* Blocks connected via pl301periph */
+#define ROMCP_ARB_BASE_ADDR 0x00000000
+#define ROMCP_ARB_END_ADDR 0x000FFFFF
+#define BOOT_ROM_BASE_ADDR ROMCP_ARB_BASE_ADDR
+#define CAAM_SECMEM_BASE_ADDR 0x00100000
+#define CAAM_SECMEM_END_ADDR 0x00103FFF
+#define APBH_DMA_ARB_BASE_ADDR 0x00110000
+#define APBH_DMA_ARB_END_ADDR 0x00117FFF
+#define MX6Q_HDMI_ARB_BASE_ADDR 0x00120000
+#define MX6Q_HDMI_ARB_END_ADDR 0x00128FFF
+#define GPU_3D_ARB_BASE_ADDR 0x00130000
+#define GPU_3D_ARB_END_ADDR 0x00133FFF
+#define GPU_2D_ARB_BASE_ADDR 0x00134000
+#define GPU_2D_ARB_END_ADDR 0x00137FFF
+#define MX6SL_GPU_2D_ARB_BASE_ADDR 0x02200000 /* MX6SL */
+#define MX6SL_GPU_2D_ARB_END_ADDR 0x02203FFF /* MX6SL */
+#define DTCP_ARB_BASE_ADDR 0x00138000
+#define DTCP_ARB_END_ADDR 0x0013BFFF
+
+/* GPV - PL301 configuration ports */
+#define GPV0_BASE_ADDR 0x00B00000
+#define GPV1_BASE_ADDR 0x00C00000
+#define GPV2_BASE_ADDR 0x00200000
+#define MX6SL_GPV2_BASE_ADDR 0x00D00000 /* GPV0-2 for MX6SL */
+#define GPV3_BASE_ADDR 0x00300000
+#define GPV4_BASE_ADDR 0x00800000
+
+#define AIPS1_ARB_BASE_ADDR 0x02000000
+#define AIPS1_ARB_END_ADDR 0x020FFFFF
+#define AIPS2_ARB_BASE_ADDR 0x02100000
+#define AIPS2_ARB_END_ADDR 0x021FFFFF
+#define MX6Q_SATA_BASE_ADDR 0x02200000
+#define MX6Q_SATA_ARB_END_ADDR 0x02203FFF
+#define OPENVG_ARB_BASE_ADDR 0x02204000
+#define OPENVG_ARB_END_ADDR 0x02207FFF
+#define HSI_ARB_BASE_ADDR 0x02208000
+#define HSI_ARB_END_ADDR 0x0220BFFF
+#define MX6Q_IPU1_ARB_BASE_ADDR 0x02400000
+#define MX6Q_IPU1_ARB_END_ADDR 0x027FFFFF
+#define MX6Q_IPU2_ARB_BASE_ADDR 0x02800000
+#define MX6Q_IPU2_ARB_END_ADDR 0x02BFFFFF
+#define WEIM_ARB_BASE_ADDR 0x08000000
+#define WEIM_ARB_END_ADDR 0x0FFFFFFF
+
+/* Legacy Defines */
+#define CSD0_DDR_BASE_ADDR MMDC0_ARB_BASE_ADDR
+#define CSD1_DDR_BASE_ADDR MMDC1_ARB_BASE_ADDR
+#define CS0_BASE_ADDR WEIM_ARB_BASE_ADDR
+#define NAND_FLASH_BASE_ADDR APBH_DMA_ARB_BASE_ADDR
+#define MX6Q_GPMI_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x02000)
+#define MX6Q_BCH_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x04000)
+
+/* Defines for Blocks connected via AIPS (SkyBlue) */
+#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
+#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
+
+/* slots 0,7 of SDMA reserved, therefore left unused in IPMUX3 */
+#define MX6Q_SPDIF_BASE_ADDR (ATZ1_BASE_ADDR + 0x04000) /* slot 1 */
+#define MX6Q_ECSPI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x08000) /* slot 2 */
+#define MX6Q_ECSPI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x0C000) /* slot 3 */
+#define MX6Q_ECSPI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x10000) /* slot 4 */
+#define MX6Q_ECSPI4_BASE_ADDR (ATZ1_BASE_ADDR + 0x14000) /* slot 5 */
+#define MX6Q_ECSPI5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000) /* slot 6 */
+#define MX6SL_UART5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000) /* MX6SL */
+#define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* slot 8 */
+#define ESAI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* slot 9 */
+#define MX6SL_UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* MX6SL */
+#define MX6SL_UART2_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* MX6SL */
+#define MX6Q_SSI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000) /* slot 10 */
+#define MX6Q_SSI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000) /* slot 11 */
+#define MX6Q_SSI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x30000) /* slot 12 */
+#define MX6Q_ASRC_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000) /* slot 13 */
+#define MX6SL_UART3_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000) /* MX6SL */
+#define MX6SL_UART4_BASE_ADDR (ATZ1_BASE_ADDR + 0x38000) /* MX6SL */
+#define SPBA_BASE_ADDR (ATZ1_BASE_ADDR + 0x3C000) /* slot 15 */
+#define MX6Q_VPU_BASE_ADDR (ATZ1_BASE_ADDR + 0x40000) /* slot 33,
+ global en[1], til 0x7BFFF */
+
+/* ATZ#1- On Platform */
+#define AIPS1_ON_BASE_ADDR (ATZ1_BASE_ADDR + 0x7C000)
+
+/* ATZ#1- Off Platform */
+#define AIPS1_OFF_BASE_ADDR (ATZ1_BASE_ADDR + 0x80000)
+
+#define MX6Q_PWM1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x0000)
+#define MX6Q_PWM2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4000)
+#define MX6Q_PWM3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x8000)
+#define MX6Q_PWM4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0xC000)
+#define MX6Q_CAN1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
+#define MX6SL_DBGMON_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
+#define MX6Q_CAN2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
+#define MX6SL_QOSC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
+#define GPT_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x18000)
+#define GPIO1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x1C000)
+#define GPIO2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x20000)
+#define GPIO3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x24000)
+#define GPIO4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x28000)
+#define GPIO5_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x2C000)
+#define GPIO6_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x30000)
+#define GPIO7_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x34000)
+#define MX6SL_KPP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x38000)
+#define MX6Q_WDOG1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x3C000)
+#define MX6Q_WDOG2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x40000)
+#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
+#define ANATOP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x48000)
+#define USB_PHY0_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x49000)
+#define USB_PHY1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4a000)
+#define MX6Q_SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
+#define EPIT1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x50000)
+#define EPIT2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x54000)
+#define SRC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x58000)
+#define GPC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x5C000)
+#define MX6Q_IOMUXC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x60000)
+#define DCIC1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define MX6SL_CSI_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define DCIC2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define MX6SL_SIPIX_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define MX6Q_SDMA_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define MX6DL_EPXP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x70000)
+#define MX6DL_EPDC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x74000)
+#define MX6DL_ELCDIF_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x78000)
+#define MX6SL_DCP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x7C000)
+#define MX6Q_DVFSCORE_BASE_ADDR (GPC_BASE_ADDR + 0x180)
+
+/* ATZ#2- On Platform */
+#define AIPS2_ON_BASE_ADDR (ATZ2_BASE_ADDR + 0x7C000)
+
+/* ATZ#2- Off Platform */
+#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)
+
+/* ATZ#2 - Global enable (0) */
+#define CAAM_BASE_ADDR ATZ2_BASE_ADDR
+#define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)
+
+/* ARM Cortex A9 MPCore Platform */
+#define MX6Q_A9_PLATFRM_BASE (ARM_BASE_ADDR + 0x20000)
+
+/* ARM Cortex A9 PTM */
+#define MX6Q_PTM0_BASE_ADDR 0x0215C000
+#define MX6Q_PTM1_BASE_ADDR 0x0215D000
+#define MX6Q_PTM2_BASE_ADDR 0x0215E000
+#define MX6Q_PTM3_BASE_ADDR 0x0215F000
+#define MX6Q_FUNNEL_BASE_ADDR 0x02144000
+#define MX6Q_ETB_BASE_ADDR 0x02141000
+
+#define MX6Q_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
+#define MX6Q_USB_OTG_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
+#define MX6Q_USB_HS1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4200)
+#define MX6Q_USB_HS2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4400)
+#define MX6Q_USB_HS3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4600)
+#define MX6SL_USB_HS1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4200)
+#define MX6SL_USB_HS2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4400)
+#define MX6SL_USB_HS3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4600)
+#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0x8000)
+#define MLB_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0xC000)
+#define MX6SL_MSHC_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0xC000)
+
+#define MXC_CAAM_BASE_ADDR (AIPS2_ARB_BASE_ADDR + 0x00000)
+
+#define MX6Q_USDHC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x10000)
+#define MX6Q_USDHC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x14000)
+#define MX6Q_USDHC3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x18000)
+#define MX6Q_USDHC4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x1C000)
+#define MX6Q_I2C1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x20000)
+#define MX6Q_I2C2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x24000)
+#define MX6Q_I2C3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x28000)
+#define MX6SL_I2C4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x78000)
+#define ROMCP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x2C000)
+#define MMDC_P0_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x30000)
+#define MMDC_P1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define MX6SL_RNGB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define WEIM_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x38000)
+#define OCOTP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x3C000)
+#define CSU_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x40000)
+#define IP2APB_PERFMON1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x44000)
+#define IP2APB_PERFMON2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x48000)
+#define IP2APB_PERFMON3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4C000)
+#define IP2APB_TZASC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x50000)
+#define IP2APB_TZASC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define MX6Q_AUDMUX_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x58000)
+#define MIPI_CSI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define MIPI_DSI_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define VDOA_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define UART2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x68000)
+#define UART3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x6C000)
+#define UART4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x70000)
+#define UART5_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define MX6DL_I2C4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x78000)
+
+/* Cortex-A9 MPCore private memory region */
+#define ARM_PERIPHBASE 0x00A00000
+#define SCU_BASE_ADDR ARM_PERIPHBASE
+#define LOCAL_TWD_ADDR (SCU_BASE_ADDR + 0x600)
+#define IC_INTERFACES_BASE_ADDR (ARM_PERIPHBASE + 0x0100)
+#define GLOBAL_TIMER_BASE_ADDR (ARM_PERIPHBASE + 0x0200)
+#define PRIVATE_TIMERS_WD_BASE_ADDR (ARM_PERIPHBASE + 0x0600)
+#define IC_DISTRIBUTOR_BASE_ADDR (ARM_PERIPHBASE + 0x1000)
+#define L2_BASE_ADDR (ARM_PERIPHBASE + 0x2000)
+
+
+#define MX6Q_UART1_BASE_ADDR UART1_BASE_ADDR
+#define MX6Q_UART2_BASE_ADDR UART2_BASE_ADDR
+#define MX6Q_UART3_BASE_ADDR UART3_BASE_ADDR
+#define MX6Q_UART4_BASE_ADDR UART4_BASE_ADDR
+#define MX6Q_UART5_BASE_ADDR UART5_BASE_ADDR
+
+#define MX6Q_FEC_BASE_ADDR ENET_BASE_ADDR
+#define MX6DL_FEC_BASE_ADDR ENET_BASE_ADDR
+#define MX6Q_MIPI_DSI_BASE_ADDR MIPI_DSI_BASE_ADDR
+#define MX6Q_MIPI_CSI2_BASE_ADDR MIPI_CSI2_BASE_ADDR
+
+/* define virtual address */
+#define PERIPBASE_VIRT 0xF2000000
+#define BOOT_ROM_BASE_ADDR_VIRT (PERIPBASE_VIRT + BOOT_ROM_BASE_ADDR)
+#define AIPS1_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS1_ARB_BASE_ADDR)
+#define AIPS2_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS2_ARB_BASE_ADDR)
+#define ARM_PERIPHBASE_VIRT (PERIPBASE_VIRT + ARM_PERIPHBASE)
+#define IRAM_BASE_ADDR_VIRT (PERIPBASE_VIRT + IRAM_BASE_ADDR)
+#define L2_BASE_ADDR_VIRT (PERIPBASE_VIRT + L2_BASE_ADDR)
+#define ROMCP_SIZE SZ_1M
+#define AIPS1_SIZE SZ_1M
+#define AIPS2_SIZE SZ_1M
+#define ARM_PERIPHBASE_SIZE (SZ_8K + SZ_4K)
+#define IRAM_VIRT_SIZE SZ_1M
+
+#define SRC_GPR9 0x40
+#define SRC_GPR10 0x44
+
+#define SNVS_LPGPR 0x68
+
+/* GPC offsets */
+#define MXC_GPC_CNTR_OFFSET 0x0
+
+#define MX6_IO_ADDRESS(x) (void __force __iomem *)((x) + PERIPBASE_VIRT)
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (((((x) >= (unsigned long)AIPS1_ARB_BASE_ADDR) && \
+ ((x) <= (unsigned long)AIPS2_ARB_END_ADDR)) || \
+ ((x) >= (unsigned long)ARM_PERIPHBASE && \
+ ((x) <= (unsigned long)(ARM_PERIPHBASE + ARM_PERIPHBASE_SIZE)))) ? \
+ MX6_IO_ADDRESS(x) : (void __force __iomem *)0xDEADBEEF)
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_START 32
+#define MXC_INT_GPR 32
+#define MXC_INT_CHEETAH_CSYSPWRUPREQ 33
+#define MX6Q_INT_SDMA 34
+#define MX6Q_INT_VPU_JPG 35
+#define MX6DL_INT_MSHC 35
+#define MXC_INT_INTERRUPT_36_NUM 36
+#define MX6Q_INT_IPU1_ERR 37
+#define MX6SL_INT_RNGB 37
+#define MX6Q_INT_IPU1_SYN 38
+#define MX6SL_INT_SPDC 38
+#define MX6Q_INT_IPU2_ERR 39
+#define MX6DL_INT_CSI 39
+#define MX6SL_INT_CSI 39
+#define MX6Q_INT_IPU2_SYN 40
+#define MXC_INT_GPU3D_IRQ 41
+#define MXC_INT_GPU2D_IRQ 42
+#define MXC_INT_OPENVG_XAQ2 43
+#define MX6Q_INT_VPU_IPI 44
+#define MXC_INT_APBHDMA_DMA 45
+#define MXC_INT_WEIM 46
+#define MXC_INT_RAWNAND_BCH 47
+#define MXC_INT_RAWNAND_GPMI 48
+#define MXC_INT_DTCP 49
+#define MXC_INT_VDOA 50
+#define MX6Q_INT_SNVS 51
+#define MXC_INT_SNVS_SEC 52
+#define MXC_INT_CSU 53
+#define MX6Q_INT_USDHC1 54
+#define MX6Q_INT_USDHC2 55
+#define MX6Q_INT_USDHC3 56
+#define MX6Q_INT_USDHC4 57
+#define MXC_INT_UART1_ANDED 58
+#define MXC_INT_UART2_ANDED 59
+#define MXC_INT_UART3_ANDED 60
+#define MXC_INT_UART4_ANDED 61
+#define MXC_INT_UART5_ANDED 62
+#define MX6Q_INT_ECSPI1 63
+#define MX6Q_INT_ECSPI2 64
+#define MX6Q_INT_ECSPI3 65
+#define MX6Q_INT_ECSPI4 66
+#define MX6Q_INT_ECSPI5 67
+#define MX6DL_INT_I2C4 67
+#define MX6Q_INT_I2C1 68
+#define MX6Q_INT_I2C2 69
+#define MX6Q_INT_I2C3 70
+#define MX6Q_INT_SATA 71
+#define MX6DL_INT_ELCDIF 71
+#define MX6Q_INT_USB_HS1 72
+#define MX6SL_INT_USB_HS1 74
+#define MX6Q_INT_USB_HS2 73
+#define MX6SL_INT_USB_HS2 72
+#define MX6Q_INT_USB_HS3 74
+#define MX6SL_INT_USB_HS3 73
+#define MX6Q_INT_USB_OTG 75
+#define MX6Q_INT_USB_PHY0 76
+#define MX6Q_INT_USB_PHY1 77
+#define MX6SL_INT_USB_PHY0 76
+#define MX6SL_INT_USB_PHY1 77
+/*
+ * MX6Q_INT_USB_PHY2, MX6Q_INT_USB_PHY3 are dummy interrupts
+ * In order to compile pass for platform device's definition
+ */
+#define MX6Q_INT_USB_PHY2 73
+#define MX6Q_INT_USB_PHY3 74
+#define MX6SL_INT_USB_PHY2 72
+#define MX6SL_INT_USB_PHY3 73
+#define MX6Q_INT_SSI1 78
+#define MX6Q_INT_SSI2 79
+#define MX6Q_INT_SSI3 80
+#define MXC_INT_ANATOP_TEMPSNSR 81
+#define MX6Q_INT_ASRC 82
+#define MXC_INT_ESAI 83
+#define MX6Q_INT_SPDIF 84
+#define MXC_INT_MLB 85
+#define MXC_INT_ANATOP_ANA1 86
+#define MXDL_INT_PMU 86
+#define MXC_INT_GPT 87
+#define MXC_INT_EPIT1 88
+#define MXC_INT_EPIT2 89
+#define MXC_INT_GPIO1_INT7_NUM 90
+#define MXC_INT_GPIO1_INT6_NUM 91
+#define MXC_INT_GPIO1_INT5_NUM 92
+#define MXC_INT_GPIO1_INT4_NUM 93
+#define MXC_INT_GPIO1_INT3_NUM 94
+#define MXC_INT_GPIO1_INT2_NUM 95
+#define MXC_INT_GPIO1_INT1_NUM 96
+#define MXC_INT_GPIO1_INT0_NUM 97
+#define MXC_INT_GPIO1_INT15_0_NUM 98
+#define MXC_INT_GPIO1_INT31_16_NUM 99
+#define MXC_INT_GPIO2_INT15_0_NUM 100
+#define MXC_INT_GPIO2_INT31_16_NUM 101
+#define MXC_INT_GPIO3_INT15_0_NUM 102
+#define MXC_INT_GPIO3_INT31_16_NUM 103
+#define MXC_INT_GPIO4_INT15_0_NUM 104
+#define MXC_INT_GPIO4_INT31_16_NUM 105
+#define MXC_INT_GPIO5_INT15_0_NUM 106
+#define MXC_INT_GPIO5_INT31_16_NUM 107
+#define MXC_INT_GPIO6_INT15_0_NUM 108
+#define MXC_INT_GPIO6_INT31_16_NUM 109
+#define MXC_INT_GPIO7_INT15_0_NUM 110
+#define MXC_INT_GPIO7_INT31_16_NUM 111
+#define MX6Q_INT_WDOG1 112
+#define MX6Q_INT_WDOG2 113
+#define MXC_INT_KPP 114
+#define MX6SL_INT_KPP 114
+#define MX6Q_INT_PWM1 115
+#define MX6Q_INT_PWM2 116
+#define MX6Q_INT_PWM3 117
+#define MX6Q_INT_PWM4 118
+#define MXC_INT_CCM_INT1_NUM 119
+#define MXC_INT_CCM_INT2_NUM 120
+#define MX6Q_INT_GPC1 121
+#define MXC_INT_GPC_INT2_NUM 122
+#define MXC_INT_SRC 123
+#define MXC_INT_CHEETAH_L2 124
+#define MXC_INT_CHEETAH_PARITY 125
+#define MXC_INT_CHEETAH_PERFORM 126
+#define MXC_INT_CHEETAH_TRIGGER 127
+#define MXC_INT_SRC_CPU_WDOG 128
+#define MX6DL_INT_EPDC 129
+#define MX6DL_INT_EPXP 130
+#define MXC_INT_INTERRUPT_131_NUM 131
+#define MX6SL_INT_DCP_GEN 131
+#define MX6SL_INT_DCP_CH0 132
+#define MX6SL_INT_DCP_SEC 133
+#define MXC_INT_CSI_INTR1 132
+#define MXC_INT_CSI_INTR2 133
+#define MXC_INT_DSI 134
+#define MXC_INT_HSI 135
+#define MXC_INT_SJC 136
+#define MXC_INT_CAAM_INT0_NUM 137
+#define MXC_INT_CAAM_INT1_NUM 138
+#define MXC_INT_INTERRUPT_139_NUM 139
+#define MXC_INT_TZASC1 140
+#define MXC_INT_TZASC2 141
+#define MX6Q_INT_CAN1 142
+#define MX6Q_INT_CAN2 143
+#define MX6Q_INT_PERFMON1 144
+#define MX6Q_INT_PERFMON2 145
+#define MX6Q_INT_PERFMON3 146
+#define MX6DL_INT_FEC 146
+#define MX6Q_INT_HDMI_TX 147
+#define MX6Q_INT_HDMI_TX_WAKEUP 148
+#define MXC_INT_MLB_AHB0 149
+#define MXC_INT_ENET1 150
+#define MXC_INT_ENET2 151
+#define MXC_INT_PCIE_0 152
+#define MXC_INT_PCIE_1 153
+#define MXC_INT_PCIE_2 154
+#define MXC_INT_PCIE_3 155
+#define MXC_INT_DCIC1 156
+#define MXC_INT_DCIC2 157
+#define MXC_INT_MLB_AHB1 158
+#define MXC_INT_ANATOP_ANA2 159
+#define MXC_INT_END 159
+
+#define MX6Q_INT_UART1 MXC_INT_UART1_ANDED
+#define MX6Q_INT_UART2 MXC_INT_UART2_ANDED
+#define MX6Q_INT_UART3 MXC_INT_UART3_ANDED
+#define MX6Q_INT_UART4 MXC_INT_UART4_ANDED
+#define MX6Q_INT_UART5 MXC_INT_UART5_ANDED
+#define MX6SL_INT_UART1 MXC_INT_UART1_ANDED
+#define MX6SL_INT_UART2 MXC_INT_UART2_ANDED
+#define MX6SL_INT_UART3 MXC_INT_UART3_ANDED
+#define MX6SL_INT_UART4 MXC_INT_UART4_ANDED
+#define MX6SL_INT_UART5 MXC_INT_UART5_ANDED
+#define MX6Q_INT_FEC MXC_INT_ENET1
+#define MX6Q_INT_DSI MXC_INT_DSI
+
+#define IRQ_LOCALTIMER 29
+
+/* APBH-DMA */
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI0 0
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI1 1
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI2 2
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI3 3
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI4 4
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI5 5
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI6 6
+#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI7 7
+
+/*
+ * DMA request assignments
+ */
+#define MX6Q_DMA_REQ_VPU 0
+#define MX6Q_DMA_REQ_GPC 1
+#define MX6Q_DMA_REQ_IPU1 2
+#define MX6Q_DMA_REQ_EXT_DMA_REQ_0 2
+#define MX6Q_DMA_REQ_CSPI1_RX 3
+#define MX6Q_DMA_REQ_I2C3_A 3
+#define MX6Q_DMA_REQ_CSPI1_TX 4
+#define MX6Q_DMA_REQ_I2C2_A 4
+#define MX6Q_DMA_REQ_CSPI2_RX 5
+#define MX6Q_DMA_REQ_I2C1_A 5
+#define MX6Q_DMA_REQ_CSPI2_TX 6
+#define MX6Q_DMA_REQ_CSPI3_RX 7
+#define MX6Q_DMA_REQ_CSPI3_TX 8
+#define MX6Q_DMA_REQ_CSPI4_RX 9
+#define MX6Q_DMA_REQ_EPIT2 9
+#define MX6Q_DMA_REQ_CSPI4_TX 10
+#define MX6Q_DMA_REQ_I2C1_B 10
+#define MX6Q_DMA_REQ_CSPI5_RX 11
+#define MX6Q_DMA_REQ_CSPI5_TX 12
+#define MX6Q_DMA_REQ_GPT 13
+#define MX6Q_DMA_REQ_SPDIF_RX 14
+#define MX6Q_DMA_REQ_EXT_DMA_REQ_1 14
+#define MX6Q_DMA_REQ_SPDIF_TX 15
+#define MX6Q_DMA_REQ_EPIT1 16
+#define MX6Q_DMA_REQ_ASRC_RX1 17
+#define MX6Q_DMA_REQ_ASRC_RX2 18
+#define MX6Q_DMA_REQ_ASRC_RX3 19
+#define MX6Q_DMA_REQ_ASRC_TX1 20
+#define MX6Q_DMA_REQ_ASRC_TX2 21
+#define MX6Q_DMA_REQ_ASRC_TX3 22
+#define MX6Q_DMA_REQ_ESAI_RX 23
+#define MX6Q_DMA_REQ_I2C3_B 23
+#define MX6Q_DMA_REQ_ESAI_TX 24
+#define MX6Q_DMA_REQ_UART1_RX 25
+#define MX6Q_DMA_REQ_UART1_TX 26
+#define MX6Q_DMA_REQ_UART2_RX 27
+#define MX6Q_DMA_REQ_UART2_TX 28
+#define MX6Q_DMA_REQ_UART3_RX 29
+#define MX6Q_DMA_REQ_UART3_TX 30
+#define MX6Q_DMA_REQ_UART4_RX 31
+#define MX6Q_DMA_REQ_UART4_TX 32
+#define MX6Q_DMA_REQ_UART5_RX 33
+#define MX6Q_DMA_REQ_UART5_TX 34
+#define MX6Q_DMA_REQ_SSI1_RX1 35
+#define MX6Q_DMA_REQ_SSI1_TX1 36
+#define MX6Q_DMA_REQ_SSI1_RX0 37
+#define MX6Q_DMA_REQ_SSI1_TX0 38
+#define MX6Q_DMA_REQ_SSI2_RX1 39
+#define MX6Q_DMA_REQ_SSI2_TX1 40
+#define MX6Q_DMA_REQ_SSI2_RX0 41
+#define MX6Q_DMA_REQ_SSI2_TX0 42
+#define MX6Q_DMA_REQ_SSI3_RX1 43
+#define MX6Q_DMA_REQ_SSI3_TX1 44
+#define MX6Q_DMA_REQ_SSI3_RX0 45
+#define MX6Q_DMA_REQ_SSI3_TX0 46
+#define MX6Q_DMA_REQ_DTCP 47
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx6q_revision(void);
+extern int mx6dl_revision(void);
+extern int mx6sl_revision(void);
+#endif
+
+#endif /* __ASM_ARCH_MXC_MX6_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
new file mode 100755
index 00000000..75b99aff
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2004-2007, 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_H__
+#define __ASM_ARCH_MXC_H__
+
+#include <linux/types.h>
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+#define MXC_CPU_MX1 1
+#define MXC_CPU_MX21 21
+#define MXC_CPU_MX25 25
+#define MXC_CPU_MX27 27
+#define MXC_CPU_MX31 31
+#define MXC_CPU_MX35 35
+#define MXC_CPU_MX37 37
+#define MXC_CPU_MX50 50
+#define MXC_CPU_MX51 51
+#define MXC_CPU_MX53 53
+#define MXC_CPU_MX6Q 63
+#define MXC_CPU_MX6DL 61
+#define MXC_CPU_MX6SL 60
+
+#define IMX_CHIP_REVISION_1_0 0x10
+#define IMX_CHIP_REVISION_1_1 0x11
+#define IMX_CHIP_REVISION_1_2 0x12
+#define IMX_CHIP_REVISION_1_3 0x13
+#define IMX_CHIP_REVISION_2_0 0x20
+#define IMX_CHIP_REVISION_2_1 0x21
+#define IMX_CHIP_REVISION_2_2 0x22
+#define IMX_CHIP_REVISION_2_3 0x23
+#define IMX_CHIP_REVISION_3_0 0x30
+#define IMX_CHIP_REVISION_3_1 0x31
+#define IMX_CHIP_REVISION_3_2 0x32
+#define IMX_CHIP_REVISION_3_3 0x33
+#define IMX_CHIP_REVISION_UNKNOWN 0xff
+
+#define IMX_CHIP_REVISION_1_0_STRING "1.0"
+#define IMX_CHIP_REVISION_1_1_STRING "1.1"
+#define IMX_CHIP_REVISION_1_2_STRING "1.2"
+#define IMX_CHIP_REVISION_1_3_STRING "1.3"
+#define IMX_CHIP_REVISION_2_0_STRING "2.0"
+#define IMX_CHIP_REVISION_2_1_STRING "2.1"
+#define IMX_CHIP_REVISION_2_2_STRING "2.2"
+#define IMX_CHIP_REVISION_2_3_STRING "2.3"
+#define IMX_CHIP_REVISION_3_0_STRING "3.0"
+#define IMX_CHIP_REVISION_3_1_STRING "3.1"
+#define IMX_CHIP_REVISION_3_2_STRING "3.2"
+#define IMX_CHIP_REVISION_3_3_STRING "3.3"
+#define IMX_CHIP_REVISION_UNKNOWN_STRING "unknown"
+#define IMX_BOARD_REV_1 0x000
+#define IMX_BOARD_REV_2 0x100
+#define IMX_BOARD_REV_3 0x200
+#define IMX_BOARD_REV_4 0x300
+
+#ifndef __ASSEMBLY__
+extern unsigned int system_rev;
+#define board_is_rev(rev) (((system_rev & 0x0F00) == rev) ? 1 : 0)
+#define imx_cpu_ver() (system_rev & 0xFF)
+
+#endif
+
+#ifdef CONFIG_ARCH_MX5
+#define board_is_mx53_loco_mc34708() (cpu_is_mx53() && \
+ (board_is_rev(IMX_BOARD_REV_2) || board_is_rev(IMX_BOARD_REV_4)))
+#define board_is_mx53_arm2() (cpu_is_mx53() && board_is_rev(IMX_BOARD_REV_2))
+#define board_is_mx53_evk_a() (cpu_is_mx53() && board_is_rev(IMX_BOARD_REV_1))
+#define board_is_mx53_evk_b() (cpu_is_mx53() && board_is_rev(IMX_BOARD_REV_3))
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+#define board_is_mx6q_arm2() (cpu_is_mx6q() && \
+ board_is_rev(IMX_BOARD_REV_1))
+#define board_is_mx6q_sabre_lite() (cpu_is_mx6q() && \
+ board_is_rev(IMX_BOARD_REV_2))
+#define board_is_mx6q_sabre_auto() (cpu_is_mx6q() && \
+ board_is_rev(IMX_BOARD_REV_3))
+#define board_is_mx6sl_evk() (cpu_is_mx6sl() && \
+ board_is_rev(IMX_BOARD_REV_3))
+
+#define board_is_mx6_unknown() \
+ board_is_rev(IMX_BOARD_REV_1)
+#define board_is_mx6_reva() \
+ board_is_rev(IMX_BOARD_REV_2)
+#define board_is_mx6_revb() \
+ board_is_rev(IMX_BOARD_REV_3)
+#define board_is_mx6_revc() \
+ board_is_rev(IMX_BOARD_REV_4)
+#endif
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxc_cpu_type;
+#endif
+
+#ifdef CONFIG_ARCH_MX1
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX1
+# endif
+# define cpu_is_mx1() (mxc_cpu_type == MXC_CPU_MX1)
+#else
+# define cpu_is_mx1() (0)
+#endif
+
+#ifdef CONFIG_MACH_MX21
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX21
+# endif
+# define cpu_is_mx21() (mxc_cpu_type == MXC_CPU_MX21)
+#else
+# define cpu_is_mx21() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX25
+# endif
+# define cpu_is_mx25() (mxc_cpu_type == MXC_CPU_MX25)
+#else
+# define cpu_is_mx25() (0)
+#endif
+
+#ifdef CONFIG_MACH_MX27
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX27
+# endif
+# define cpu_is_mx27() (mxc_cpu_type == MXC_CPU_MX27)
+#else
+# define cpu_is_mx27() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX31
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX31
+# endif
+# define cpu_is_mx31() (mxc_cpu_type == MXC_CPU_MX31)
+#else
+# define cpu_is_mx31() (0)
+#endif
+
+# define cpu_is_mx32() (0)
+
+#ifdef CONFIG_SOC_IMX35
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX35
+# endif
+# define cpu_is_mx35() (mxc_cpu_type == MXC_CPU_MX35)
+#else
+# define cpu_is_mx35() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX37
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX37
+# endif
+# define cpu_is_mx37() (mxc_cpu_type == MXC_CPU_MX37)
+#else
+# define cpu_is_mx37() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX50
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX50
+# endif
+# define cpu_is_mx50() (mxc_cpu_type == MXC_CPU_MX50)
+#else
+# define cpu_is_mx50() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX51
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX51
+# endif
+# define cpu_is_mx51() (mxc_cpu_type == MXC_CPU_MX51)
+#else
+# define cpu_is_mx51() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX53
+# ifdef mxc_cpu_type
+# undef mxc_cpu_type
+# define mxc_cpu_type __mxc_cpu_type
+# else
+# define mxc_cpu_type MXC_CPU_MX53
+# endif
+# define cpu_is_mx53() (mxc_cpu_type == MXC_CPU_MX53)
+#else
+# define cpu_is_mx53() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+# define mxc_cpu_type __mxc_cpu_type
+# define cpu_is_mx6q() (mxc_cpu_type == MXC_CPU_MX6Q)
+# define cpu_is_mx6dl() (mxc_cpu_type == MXC_CPU_MX6DL)
+# define cpu_is_mx6sl() (mxc_cpu_type == MXC_CPU_MX6SL)
+#else
+# define cpu_is_mx6q() (0)
+# define cpu_is_mx6dl() (0)
+# define cpu_is_mx6sl() (0)
+#endif
+
+#ifndef __ASSEMBLY__
+
+struct cpu_op {
+ u32 pll_reg;
+ u32 pll_rate;
+ u32 pll_lpm_rate;
+ u32 cpu_rate;
+ u32 pdr0_reg;
+ u32 pdf;
+ u32 mfi;
+ u32 mfd;
+ u32 mfn;
+ u32 pu_voltage;
+ u32 soc_voltage;
+ u32 cpu_voltage;
+ u32 cpu_podf;
+};
+
+enum mxc_cpu_pwr_mode {
+ WAIT_CLOCKED, /* wfi only */
+ WAIT_UNCLOCKED, /* WAIT */
+ WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
+ STOP_XTAL_ON, /* STOP + SRPG + XTAL_ON*/
+ STOP_POWER_OFF, /* STOP + XTAL_OFF */
+ ARM_POWER_OFF, /* STOP + SRPG + ARM power off */
+};
+
+int tzic_enable_wake(int is_idle);
+
+extern void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+extern int tzic_enable_wake(int is_idle);
+
+/* available disableable devices in fuse */
+enum mxc_dev_type {
+ MXC_DEV_PXP,
+ MXC_DEV_OVG,
+ MXC_DEV_DSI_CSI2,
+ MXC_DEV_ENET,
+ MXC_DEV_MLB,
+ MXC_DEV_EPDC,
+ MXC_DEV_HDMI,
+ MXC_DEV_PCIE,
+ MXC_DEV_SATA,
+ MXC_DEV_DTCP,
+ MXC_DEV_2D,
+ MXC_DEV_3D,
+ MXC_DEV_VPU,
+ MXC_DEV_DIVX3,
+ MXC_DEV_RV,
+ MXC_DEV_SORENSEN,
+};
+extern int fuse_dev_is_available(enum mxc_dev_type dev);
+
+#endif
+
+#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
+/* These are deprecated, use mx[23][157]_setup_weimcs instead. */
+#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10))
+#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x4))
+#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR + n * 0x10 + 0x8))
+#endif
+
+#define cpu_is_mx5() (cpu_is_mx51() || cpu_is_mx53() || cpu_is_mx50())
+#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
+#define cpu_is_mx6() (cpu_is_mx6q() || cpu_is_mx6dl() || cpu_is_mx6sl())
+
+#define MXC_PGCR_PCR 1
+#define MXC_SRPGCR_PCR 1
+#define MXC_EMPGCR_PCR 1
+#define MXC_PGSR_PSR 1
+#endif /* __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
new file mode 100755
index 00000000..765190fe
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * - Platform specific register memory map
+ *
+ * Copyright 2005-2007 Motorola, 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.
+ */
+#ifndef __MACH_MXC91231_H__
+#define __MACH_MXC91231_H__
+
+/*
+ * L2CC
+ */
+#define MXC91231_L2CC_BASE_ADDR 0x30000000
+#define MXC91231_L2CC_SIZE SZ_64K
+
+/*
+ * AIPS 1
+ */
+#define MXC91231_AIPS1_BASE_ADDR 0x43F00000
+#define MXC91231_AIPS1_SIZE SZ_1M
+
+#define MXC91231_AIPS1_CTRL_BASE_ADDR MXC91231_AIPS1_BASE_ADDR
+#define MXC91231_MAX_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x04000)
+#define MXC91231_EVTMON_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x08000)
+#define MXC91231_CLKCTL_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x0C000)
+#define MXC91231_ETB_SLOT4_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x10000)
+#define MXC91231_ETB_SLOT5_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x14000)
+#define MXC91231_ECT_CTIO_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x18000)
+#define MXC91231_I2C_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x80000)
+#define MXC91231_MU_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x88000)
+#define MXC91231_UART1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x90000)
+#define MXC91231_UART2_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x94000)
+#define MXC91231_DSM_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x98000)
+#define MXC91231_OWIRE_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0x9C000)
+#define MXC91231_SSI1_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA0000)
+#define MXC91231_KPP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xA8000)
+#define MXC91231_IOMUX_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xAC000)
+#define MXC91231_CTI_AP_BASE_ADDR (MXC91231_AIPS1_BASE_ADDR + 0xB8000)
+
+/*
+ * AIPS 2
+ */
+#define MXC91231_AIPS2_BASE_ADDR 0x53F00000
+#define MXC91231_AIPS2_SIZE SZ_1M
+
+#define MXC91231_GEMK_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x8C000)
+#define MXC91231_GPT1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x90000)
+#define MXC91231_EPIT1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0x94000)
+#define MXC91231_SCC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xAC000)
+#define MXC91231_RNGA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xB0000)
+#define MXC91231_IPU_CTRL_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC0000)
+#define MXC91231_AUDMUX_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC4000)
+#define MXC91231_EDIO_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xC8000)
+#define MXC91231_GPIO1_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xCC000)
+#define MXC91231_GPIO2_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD0000)
+#define MXC91231_SDMA_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD4000)
+#define MXC91231_RTC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xD8000)
+#define MXC91231_WDOG1_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xDC000)
+#define MXC91231_PWM_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE0000)
+#define MXC91231_GPIO3_AP_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE4000)
+#define MXC91231_WDOG2_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xE8000)
+#define MXC91231_RTIC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xEC000)
+#define MXC91231_LPMC_BASE_ADDR (MXC91231_AIPS2_BASE_ADDR + 0xF0000)
+
+/*
+ * SPBA global module 0
+ */
+#define MXC91231_SPBA0_BASE_ADDR 0x50000000
+#define MXC91231_SPBA0_SIZE SZ_1M
+
+#define MXC91231_MMC_SDHC1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x04000)
+#define MXC91231_MMC_SDHC2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x08000)
+#define MXC91231_UART3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x0C000)
+#define MXC91231_CSPI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x10000)
+#define MXC91231_SSI2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x14000)
+#define MXC91231_SIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x18000)
+#define MXC91231_IIM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x1C000)
+#define MXC91231_CTI_SDMA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x20000)
+#define MXC91231_USBOTG_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x24000)
+#define MXC91231_USBOTG_DATA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x28000)
+#define MXC91231_CSPI1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x30000)
+#define MXC91231_SPBA_CTRL_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x3C000)
+#define MXC91231_IOMUX_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x40000)
+#define MXC91231_CRM_COM_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x44000)
+#define MXC91231_CRM_AP_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x48000)
+#define MXC91231_PLL0_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x4C000)
+#define MXC91231_PLL1_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x50000)
+#define MXC91231_PLL2_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x54000)
+#define MXC91231_GPIO4_SH_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x58000)
+#define MXC91231_HAC_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000)
+#define MXC91231_SAHARA_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x5C000)
+#define MXC91231_PLL3_BASE_ADDR (MXC91231_SPBA0_BASE_ADDR + 0x60000)
+
+/*
+ * SPBA global module 1
+ */
+#define MXC91231_SPBA1_BASE_ADDR 0x52000000
+#define MXC91231_SPBA1_SIZE SZ_1M
+
+#define MXC91231_MQSPI_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x34000)
+#define MXC91231_EL1T_BASE_ADDR (MXC91231_SPBA1_BASE_ADDR + 0x38000)
+
+/*!
+ * Defines for SPBA modules
+ */
+#define MXC91231_SPBA_SDHC1 0x04
+#define MXC91231_SPBA_SDHC2 0x08
+#define MXC91231_SPBA_UART3 0x0C
+#define MXC91231_SPBA_CSPI2 0x10
+#define MXC91231_SPBA_SSI2 0x14
+#define MXC91231_SPBA_SIM 0x18
+#define MXC91231_SPBA_IIM 0x1C
+#define MXC91231_SPBA_CTI_SDMA 0x20
+#define MXC91231_SPBA_USBOTG_CTRL_REGS 0x24
+#define MXC91231_SPBA_USBOTG_DATA_REGS 0x28
+#define MXC91231_SPBA_CSPI1 0x30
+#define MXC91231_SPBA_MQSPI 0x34
+#define MXC91231_SPBA_EL1T 0x38
+#define MXC91231_SPBA_IOMUX 0x40
+#define MXC91231_SPBA_CRM_COM 0x44
+#define MXC91231_SPBA_CRM_AP 0x48
+#define MXC91231_SPBA_PLL0 0x4C
+#define MXC91231_SPBA_PLL1 0x50
+#define MXC91231_SPBA_PLL2 0x54
+#define MXC91231_SPBA_GPIO4 0x58
+#define MXC91231_SPBA_SAHARA 0x5C
+
+/*
+ * ROMP and AVIC
+ */
+#define MXC91231_ROMP_BASE_ADDR 0x60000000
+#define MXC91231_ROMP_SIZE SZ_64K
+
+#define MXC91231_AVIC_BASE_ADDR 0x68000000
+#define MXC91231_AVIC_SIZE SZ_64K
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define MXC91231_X_MEMC_BASE_ADDR 0xB8000000
+#define MXC91231_X_MEMC_SIZE SZ_64K
+
+#define MXC91231_NFC_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x0000)
+#define MXC91231_ESDCTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x1000)
+#define MXC91231_WEIM_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x2000)
+#define MXC91231_M3IF_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x3000)
+#define MXC91231_EMI_CTL_BASE_ADDR (MXC91231_X_MEMC_BASE_ADDR + 0x4000)
+
+/*
+ * Memory regions and CS
+ * CPLD is connected on CS4
+ * CS5 is TP1021 or it is not connected
+ * */
+#define MXC91231_FB_RAM_BASE_ADDR 0x78000000
+#define MXC91231_FB_RAM_SIZE SZ_256K
+#define MXC91231_CSD0_BASE_ADDR 0x80000000
+#define MXC91231_CSD1_BASE_ADDR 0x90000000
+#define MXC91231_CS0_BASE_ADDR 0xA0000000
+#define MXC91231_CS1_BASE_ADDR 0xA8000000
+#define MXC91231_CS2_BASE_ADDR 0xB0000000
+#define MXC91231_CS3_BASE_ADDR 0xB2000000
+#define MXC91231_CS4_BASE_ADDR 0xB4000000
+#define MXC91231_CS5_BASE_ADDR 0xB6000000
+
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address.
+ */
+#define MXC91231_IO_P2V(x) IMX_IO_P2V(x)
+#define MXC91231_IO_ADDRESS(x) IOMEM(MXC91231_IO_P2V(x))
+
+/*
+ * Interrupt numbers
+ */
+#define MXC91231_INT_GPIO3 0
+#define MXC91231_INT_EL1T_CI 1
+#define MXC91231_INT_EL1T_RFCI 2
+#define MXC91231_INT_EL1T_RFI 3
+#define MXC91231_INT_EL1T_MCU 4
+#define MXC91231_INT_EL1T_IPI 5
+#define MXC91231_INT_MU_GEN 6
+#define MXC91231_INT_GPIO4 7
+#define MXC91231_INT_MMC_SDHC2 8
+#define MXC91231_INT_MMC_SDHC1 9
+#define MXC91231_INT_I2C 10
+#define MXC91231_INT_SSI2 11
+#define MXC91231_INT_SSI1 12
+#define MXC91231_INT_CSPI2 13
+#define MXC91231_INT_CSPI1 14
+#define MXC91231_INT_RTIC 15
+#define MXC91231_INT_SAHARA 15
+#define MXC91231_INT_HAC 15
+#define MXC91231_INT_UART3_RX 16
+#define MXC91231_INT_UART3_TX 17
+#define MXC91231_INT_UART3_MINT 18
+#define MXC91231_INT_ECT 19
+#define MXC91231_INT_SIM_IPB 20
+#define MXC91231_INT_SIM_DATA 21
+#define MXC91231_INT_RNGA 22
+#define MXC91231_INT_DSM_AP 23
+#define MXC91231_INT_KPP 24
+#define MXC91231_INT_RTC 25
+#define MXC91231_INT_PWM 26
+#define MXC91231_INT_GEMK_AP 27
+#define MXC91231_INT_EPIT 28
+#define MXC91231_INT_GPT 29
+#define MXC91231_INT_UART2_RX 30
+#define MXC91231_INT_UART2_TX 31
+#define MXC91231_INT_UART2_MINT 32
+#define MXC91231_INT_NANDFC 33
+#define MXC91231_INT_SDMA 34
+#define MXC91231_INT_USB_WAKEUP 35
+#define MXC91231_INT_USB_SOF 36
+#define MXC91231_INT_PMU_EVTMON 37
+#define MXC91231_INT_USB_FUNC 38
+#define MXC91231_INT_USB_DMA 39
+#define MXC91231_INT_USB_CTRL 40
+#define MXC91231_INT_IPU_ERR 41
+#define MXC91231_INT_IPU_SYN 42
+#define MXC91231_INT_UART1_RX 43
+#define MXC91231_INT_UART1_TX 44
+#define MXC91231_INT_UART1_MINT 45
+#define MXC91231_INT_IIM 46
+#define MXC91231_INT_MU_RX_OR 47
+#define MXC91231_INT_MU_TX_OR 48
+#define MXC91231_INT_SCC_SCM 49
+#define MXC91231_INT_SCC_SMN 50
+#define MXC91231_INT_GPIO2 51
+#define MXC91231_INT_GPIO1 52
+#define MXC91231_INT_MQSPI1 53
+#define MXC91231_INT_MQSPI2 54
+#define MXC91231_INT_WDOG2 55
+#define MXC91231_INT_EXT_INT7 56
+#define MXC91231_INT_EXT_INT6 57
+#define MXC91231_INT_EXT_INT5 58
+#define MXC91231_INT_EXT_INT4 59
+#define MXC91231_INT_EXT_INT3 60
+#define MXC91231_INT_EXT_INT2 61
+#define MXC91231_INT_EXT_INT1 62
+#define MXC91231_INT_EXT_INT0 63
+
+#define MXC91231_MAX_INT_LINES 63
+#define MXC91231_MAX_EXT_LINES 8
+
+#endif /* __MACH_MXC91231_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_asrc.h b/arch/arm/plat-mxc/include/mach/mxc_asrc.h
new file mode 100644
index 00000000..1b73c477
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_asrc.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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_ASRC_H
+#define __MACH_ASRC_H
+
+struct imx_asrc_platform_data {
+ struct clk *asrc_core_clk;
+ struct clk *asrc_audio_clk;
+ unsigned int channel_bits;
+ int clk_map_ver;
+};
+
+#endif /* __MACH_ASRC_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/mxc_dvfs.h b/arch/arm/plat-mxc/include/mach/mxc_dvfs.h
new file mode 100755
index 00000000..64639ae8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_dvfs.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup DVFS Dynamic Voltage and Frequency Scaling (DVFS) Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_dvfs.h
+ *
+ * @brief This file contains the DVFS configuration structure definition.
+ *
+ *
+ * @ingroup DVFS
+ */
+
+#ifndef __ASM_ARCH_MXC_DVFS_H__
+#define __ASM_ARCH_MXC_DVFS_H__
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+
+extern void __iomem *gpc_base;
+extern void __iomem *ccm_base;
+
+#define MXC_GPCCNTR_GPCIRQ2M (1 << 25)
+#define MXC_GPCCNTR_GPCIRQ2 (1 << 24)
+#define MXC_GPCCNTR_GPCIRQM (1 << 21)
+#define MXC_GPCCNTR_GPCIRQ_ARM (1 << 20)
+#define MXC_GPCCNTR_GPCIRQ_SDMA (0 << 20)
+#define MXC_GPCCNTR_DVFS0CR (1 << 16)
+#define MXC_GPCCNTR_DVFS1CR (1 << 17)
+#define MXC_GPCCNTR_ADU_MASK 0x8000
+#define MXC_GPCCNTR_ADU (1 << 15)
+#define MXC_GPCCNTR_STRT (1 << 14)
+#define MXC_GPCCNTR_FUPD_MASK 0x2000
+#define MXC_GPCCNTR_FUPD (1 << 13)
+#define MXC_GPCCNTR_HTRI_MASK 0x0000000F
+#define MXC_GPCCNTR_HTRI_OFFSET 0
+
+#define MXC_GPCVCR_VINC_MASK 0x00020000
+#define MXC_GPCVCR_VINC_OFFSET 17
+#define MXC_GPCVCR_VCNTU_MASK 0x00010000
+#define MXC_GPCVCR_VCNTU_OFFSET 16
+#define MXC_GPCVCR_VCNT_MASK 0x00007FFF
+#define MXC_GPCVCR_VCNT_OFFSET 0
+
+/* DVFS-PER */
+#define MXC_DVFSPER_PMCR0_UDCS (1 << 27)
+#define MXC_DVFSPER_PMCR0_UDCS_MASK 0x8000000
+#define MXC_DVFSPER_PMCR0_ENABLE_MASK 0x10
+#define MXC_DVFSPER_PMCR0_ENABLE (1 << 4)
+
+#define MXC_DVFSLTR0_UPTHR_MASK 0x0FC00000
+#define MXC_DVFSLTR0_UPTHR_OFFSET 22
+#define MXC_DVFSLTR0_DNTHR_MASK 0x003F0000
+#define MXC_DVFSLTR0_DNTHR_OFFSET 16
+
+#define MXC_DVFSLTR1_PNCTHR_MASK 0x0000003F
+#define MXC_DVFSLTR1_PNCTHR_OFFSET 0
+#define MXC_DVFSLTR1_DNCNT_MASK 0x003FC000
+#define MXC_DVFSLTR1_DNCNT_OFFSET 14
+#define MXC_DVFSLTR1_UPCNT_MASK 0x00003FC0
+#define MXC_DVFSLTR1_UPCNT_OFFSET 6
+#define MXC_DVFSLTR1_LTBRSR 0x800000
+#define MXC_DVFSLTR1_LTBRSH 0x400000
+
+#define MXC_DVFSLTR2_EMAC_MASK 0x000001FF
+#define MXC_DVFSLTR2_EMAC_OFFSET 0
+
+#define MXC_DVFSPMCR0_UDCS 0x8000000
+#define MXC_DVFSPMCR0_DVFEV 0x800000
+#define MXC_DVFSPMCR0_DVFIS 0x400000
+#define MXC_DVFSPMCR0_LBMI 0x200000
+#define MXC_DVFSPMCR0_LBFL 0x100000
+#define MXC_DVFSPMCR0_LBFC_MASK 0xC0000
+#define MXC_DVFSPMCR0_LBFC_OFFSET 18
+#define MXC_DVFSPMCR0_FSVAIM 0x00008000
+#define MXC_DVFSPMCR0_FSVAI_MASK 0x00006000
+#define MXC_DVFSPMCR0_FSVAI_OFFSET 13
+#define MXC_DVFSPMCR0_WFIM 0x00000400
+#define MXC_DVFSPMCR0_WFIM_OFFSET 10
+#define MXC_DVFSPMCR0_DVFEN 0x00000010
+
+#define MXC_DVFSPMCR1_P1INM 0x00100000
+#define MXC_DVFSPMCR1_P1ISM 0x00080000
+#define MXC_DVFSPMCR1_P1IFM 0x00040000
+#define MXC_DVFSPMCR1_P4PM 0x00020000
+#define MXC_DVFSPMCR1_P2PM 0x00010000
+
+/* DVFS CORE register offsets*/
+#define MXC_DVFSCORE_THRS 0x00
+#define MXC_DVFSCORE_COUN 0x04
+#define MXC_DVFSCORE_SIG1 0x08
+#define MXC_DVFSCORE_SIG0 0x0C
+#define MXC_DVFSCORE_GPC0 0x10
+#define MXC_DVFSCORE_GPC1 0x14
+#define MXC_DVFSCORE_GPBT 0x18
+#define MXC_DVFSCORE_EMAC 0x1C
+#define MXC_DVFSCORE_CNTR 0x20
+#define MXC_DVFSCORE_LTR0_0 0x24
+#define MXC_DVFSCORE_LTR0_1 0x28
+#define MXC_DVFSCORE_LTR1_0 0x2C
+#define MXC_DVFSCORE_LTR1_1 0x30
+#define MXC_DVFSCORE_PT0 0x34
+#define MXC_DVFSCORE_PT1 0x38
+#define MXC_DVFSCORE_PT2 0x3C
+#define MXC_DVFSCORE_PT3 0x40
+
+/*
+ * DVFS structure
+ */
+struct dvfs_op {
+ int upthr;
+ int downthr;
+ int panicthr;
+ int upcnt;
+ int downcnt;
+ int emac;
+};
+
+struct mxc_dvfs_platform_data {
+ /** Supply voltage regulator name string */
+ char *reg_id;
+ /*vdd_soc regulator name string*/
+ char *soc_id;
+ /*vdd_pu regulator name string*/
+ char *pu_id;
+ /* CPU clock name string */
+ char *clk1_id;
+ /* DVFS clock name string */
+ char *clk2_id;
+ /* The base address of the DVFS core */
+ void __iomem *membase;
+ /* The interrupt number used by the DVFS core */
+ int irq;
+ /* GPC control reg offset */
+ int gpc_cntr_offset;
+ /* GPC voltage counter reg offset */
+ int gpc_vcr_offset;
+ /* CCM DVFS control reg offset */
+ int ccm_cdcr_offset;
+ /* CCM ARM clock root reg offset */
+ int ccm_cacrr_offset;
+ /* CCM divider handshake in-progress reg offset */
+ int ccm_cdhipr_offset;
+ /* PREDIV mask */
+ u32 prediv_mask;
+ /* PREDIV offset */
+ int prediv_offset;
+ /* PREDIV value */
+ int prediv_val;
+ /* DIV3CK mask */
+ u32 div3ck_mask;
+ /* DIV3CK offset */
+ int div3ck_offset;
+ /* DIV3CK value */
+ int div3ck_val;
+ /* EMAC value */
+ int emac_val;
+ /* Frequency increase threshold. Increase frequency change request
+ will be sent if DVFS counter value will be more than this value */
+ int upthr_val;
+ /* Frequency decrease threshold. Decrease frequency change request
+ will be sent if DVFS counter value will be less than this value */
+ int dnthr_val;
+ /* Panic threshold. Panic frequency change request
+ will be sent if DVFS counter value will be more than this value */
+ int pncthr_val;
+ /* The amount of times the up threshold should be exceeded
+ before DVFS will trigger frequency increase request */
+ int upcnt_val;
+ /* The amount of times the down threshold should be exceeded
+ before DVFS will trigger frequency decrease request */
+ int dncnt_val;
+ /* Delay time in us */
+ int delay_time;
+};
+
+/*!
+ * This structure is used to define the dvfs controller's platform
+ * data. It includes the regulator name string and DVFS clock name string.
+ */
+struct mxc_dvfsper_data {
+ /** Regulator name string */
+ char *reg_id;
+ /* DVFS clock name string */
+ char *clk_id;
+ /* The base address of the DVFS per */
+ void __iomem *membase;
+ /* GPC control reg address */
+ void __iomem *gpc_cntr_reg_addr;
+ /* GPC VCR reg address */
+ void __iomem *gpc_vcr_reg_addr;
+ /* DVFS enable bit */
+ u32 dvfs_enable_bit;
+ /* DVFS ADU bit */
+ int gpc_adu;
+ /* VAI mask */
+ u32 vai_mask;
+ /* VAI offset */
+ int vai_offset;
+ /* Mask DVFS interrupt */
+ u32 irq_mask;
+ /* Div3 clock offset. */
+ u32 div3_offset;
+ /*div3 clock mask. */
+ u32 div3_mask;
+ /*div3 clock divider */
+ u32 div3_div;
+ /* LP voltage - high setpoint*/
+ u32 lp_high;
+ /* LP voltage - low setpoint*/
+ u32 lp_low;
+};
+
+/*!
+ * This structure is used to define the platform data of bus freq
+ * driver. It includes the regulator name strings.
+ */
+struct mxc_regulator_platform_data {
+ /* VDDGP regulator name */
+ char *cpu_reg_id;
+ /* VCC regulator name */
+ char *vcc_reg_id;
+};
+
+#if defined(CONFIG_MXC_DVFS_PER)
+extern int start_dvfs_per(void);
+extern void stop_dvfs_per(void);
+extern int dvfs_per_active(void);
+extern int dvfs_per_divider_active(void);
+extern int dvfs_per_pixel_clk_limit(void);
+#else
+static inline int start_dvfs_per(void)
+{
+ return 0;
+}
+
+static inline void stop_dvfs_per(void)
+{
+}
+
+static inline int dvfs_per_active(void)
+{
+ return 0;
+}
+
+static inline int dvfs_per_divider_active(void)
+{
+ return 0;
+}
+
+static inline int dvfs_per_pixel_clk_limit(void)
+{
+ return 0;
+}
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_DVFS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_edid.h b/arch/arm/plat-mxc/include/mach/mxc_edid.h
new file mode 100755
index 00000000..38bad6b7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_edid.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_edid.h
+ *
+ * @brief MXC EDID tools
+ *
+ * @ingroup Framebuffer
+ */
+
+#ifndef MXC_EDID_H
+#define MXC_EDID_H
+
+#include <linux/fb.h>
+
+#define FB_VMODE_ASPECT_4_3 0x10
+#define FB_VMODE_ASPECT_16_9 0x20
+#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
+
+enum cea_audio_coding_types {
+ AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
+ AUDIO_CODING_TYPE_LPCM = 1,
+ AUDIO_CODING_TYPE_AC3 = 2,
+ AUDIO_CODING_TYPE_MPEG1 = 3,
+ AUDIO_CODING_TYPE_MP3 = 4,
+ AUDIO_CODING_TYPE_MPEG2 = 5,
+ AUDIO_CODING_TYPE_AACLC = 6,
+ AUDIO_CODING_TYPE_DTS = 7,
+ AUDIO_CODING_TYPE_ATRAC = 8,
+ AUDIO_CODING_TYPE_SACD = 9,
+ AUDIO_CODING_TYPE_EAC3 = 10,
+ AUDIO_CODING_TYPE_DTS_HD = 11,
+ AUDIO_CODING_TYPE_MLP = 12,
+ AUDIO_CODING_TYPE_DST = 13,
+ AUDIO_CODING_TYPE_WMAPRO = 14,
+ AUDIO_CODING_TYPE_RESERVED = 15,
+};
+
+struct mxc_hdmi_3d_format {
+ unsigned char vic_order_2d;
+ unsigned char struct_3d;
+ unsigned char detail_3d;
+ unsigned char reserved;
+};
+
+struct mxc_edid_cfg {
+ bool cea_underscan;
+ bool cea_basicaudio;
+ bool cea_ycbcr444;
+ bool cea_ycbcr422;
+ bool hdmi_cap;
+
+ /*VSD*/
+ bool vsd_support_ai;
+ bool vsd_dc_48bit;
+ bool vsd_dc_36bit;
+ bool vsd_dc_30bit;
+ bool vsd_dc_y444;
+ bool vsd_dvi_dual;
+
+ bool vsd_cnc0;
+ bool vsd_cnc1;
+ bool vsd_cnc2;
+ bool vsd_cnc3;
+
+ u8 vsd_video_latency;
+ u8 vsd_audio_latency;
+ u8 vsd_I_video_latency;
+ u8 vsd_I_audio_latency;
+
+ u8 physical_address[4];
+ u8 hdmi_vic[64];
+ struct mxc_hdmi_3d_format hdmi_3d_format[64];
+ u16 hdmi_3d_mask_all;
+ u16 hdmi_3d_struct_all;
+ u32 vsd_max_tmdsclk_rate;
+
+ u8 max_channels;
+ u8 sample_sizes;
+ u8 sample_rates;
+ u8 speaker_alloc;
+};
+
+int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
+int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
+int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
+ unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
+int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
+ struct fb_monspecs *specs);
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
new file mode 100644
index 00000000..2c159dc2
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -0,0 +1,57 @@
+#ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H
+#define __INCLUDE_ASM_ARCH_MXC_EHCI_H
+
+/* values for portsc field */
+#define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23)
+#define MXC_EHCI_FORCE_FS (1 << 24)
+#define MXC_EHCI_UTMI_8BIT (0 << 28)
+#define MXC_EHCI_UTMI_16BIT (1 << 28)
+#define MXC_EHCI_SERIAL (1 << 29)
+#define MXC_EHCI_MODE_UTMI (0 << 30)
+#define MXC_EHCI_MODE_PHILIPS (1 << 30)
+#define MXC_EHCI_MODE_ULPI (2 << 30)
+#define MXC_EHCI_MODE_SERIAL (3 << 30)
+
+/* values for flags field */
+#define MXC_EHCI_INTERFACE_DIFF_UNI (0 << 0)
+#define MXC_EHCI_INTERFACE_DIFF_BI (1 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_UNI (2 << 0)
+#define MXC_EHCI_INTERFACE_SINGLE_BI (3 << 0)
+#define MXC_EHCI_INTERFACE_MASK (0xf)
+
+#define MXC_EHCI_POWER_PINS_ENABLED (1 << 5)
+#define MXC_EHCI_TTL_ENABLED (1 << 6)
+
+#define MXC_EHCI_INTERNAL_PHY (1 << 7)
+#define MXC_EHCI_IPPUE_DOWN (1 << 8)
+#define MXC_EHCI_IPPUE_UP (1 << 9)
+#define MXC_EHCI_WAKEUP_ENABLED (1 << 10)
+#define MXC_EHCI_ITC_NO_THRESHOLD (1 << 11)
+
+#define MXC_USBCTRL_OFFSET 0
+#define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8
+#define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc
+#define MXC_USBH2CTRL_OFFSET 0x14
+
+#define MX5_USBOTHER_REGS_OFFSET 0x800
+
+/* USB_PHY_CTRL_FUNC2*/
+#define MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK 0x3
+#define MX5_USB_UTMI_PHYCTRL1_PLLDIV_SHIFT 0
+
+struct mxc_usbh_platform_data {
+ int (*init)(struct platform_device *pdev);
+ int (*exit)(struct platform_device *pdev);
+
+ unsigned int portsc;
+ struct otg_transceiver *otg;
+};
+
+int mx51_initialize_usb_hw(int port, unsigned int flags);
+int mx25_initialize_usb_hw(int port, unsigned int flags);
+int mx31_initialize_usb_hw(int port, unsigned int flags);
+int mx35_initialize_usb_hw(int port, unsigned int flags);
+int mx27_initialize_usb_hw(int port, unsigned int flags);
+
+#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/mxc_gpu.h b/arch/arm/plat-mxc/include/mach/mxc_gpu.h
new file mode 100644
index 00000000..a43d6ec9
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_gpu.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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_MXC_GPU_H_
+#define __MACH_MXC_GPU_H_
+
+struct mxc_gpu_platform_data {
+ int z160_revision;
+ resource_size_t reserved_mem_base;
+ resource_size_t reserved_mem_size;
+};
+
+#endif /* __MACH_MXC_GPU_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_hdmi.h b/arch/arm/plat-mxc/include/mach/mxc_hdmi.h
new file mode 100644
index 00000000..94f76380
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_hdmi.h
@@ -0,0 +1,1095 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MXC_HDMI_H__
+#define __MXC_HDMI_H__
+
+/*
+ * Hdmi controller registers
+ */
+
+/* Identification Registers */
+#define HDMI_DESIGN_ID 0x0000
+#define HDMI_REVISION_ID 0x0001
+#define HDMI_PRODUCT_ID0 0x0002
+#define HDMI_PRODUCT_ID1 0x0003
+#define HDMI_CONFIG0_ID 0x0004
+#define HDMI_CONFIG1_ID 0x0005
+#define HDMI_CONFIG2_ID 0x0006
+#define HDMI_CONFIG3_ID 0x0007
+
+/* Interrupt Registers */
+#define HDMI_IH_FC_STAT0 0x0100
+#define HDMI_IH_FC_STAT1 0x0101
+#define HDMI_IH_FC_STAT2 0x0102
+#define HDMI_IH_AS_STAT0 0x0103
+#define HDMI_IH_PHY_STAT0 0x0104
+#define HDMI_IH_I2CM_STAT0 0x0105
+#define HDMI_IH_CEC_STAT0 0x0106
+#define HDMI_IH_VP_STAT0 0x0107
+#define HDMI_IH_I2CMPHY_STAT0 0x0108
+#define HDMI_IH_AHBDMAAUD_STAT0 0x0109
+
+#define HDMI_IH_MUTE_FC_STAT0 0x0180
+#define HDMI_IH_MUTE_FC_STAT1 0x0181
+#define HDMI_IH_MUTE_FC_STAT2 0x0182
+#define HDMI_IH_MUTE_AS_STAT0 0x0183
+#define HDMI_IH_MUTE_PHY_STAT0 0x0184
+#define HDMI_IH_MUTE_I2CM_STAT0 0x0185
+#define HDMI_IH_MUTE_CEC_STAT0 0x0186
+#define HDMI_IH_MUTE_VP_STAT0 0x0187
+#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188
+#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189
+#define HDMI_IH_MUTE 0x01FF
+
+/* Video Sample Registers */
+#define HDMI_TX_INVID0 0x0200
+#define HDMI_TX_INSTUFFING 0x0201
+#define HDMI_TX_GYDATA0 0x0202
+#define HDMI_TX_GYDATA1 0x0203
+#define HDMI_TX_RCRDATA0 0x0204
+#define HDMI_TX_RCRDATA1 0x0205
+#define HDMI_TX_BCBDATA0 0x0206
+#define HDMI_TX_BCBDATA1 0x0207
+
+/* Video Packetizer Registers */
+#define HDMI_VP_STATUS 0x0800
+#define HDMI_VP_PR_CD 0x0801
+#define HDMI_VP_STUFF 0x0802
+#define HDMI_VP_REMAP 0x0803
+#define HDMI_VP_CONF 0x0804
+#define HDMI_VP_STAT 0x0805
+#define HDMI_VP_INT 0x0806
+#define HDMI_VP_MASK 0x0807
+#define HDMI_VP_POL 0x0808
+
+/* Frame Composer Registers */
+#define HDMI_FC_INVIDCONF 0x1000
+#define HDMI_FC_INHACTV0 0x1001
+#define HDMI_FC_INHACTV1 0x1002
+#define HDMI_FC_INHBLANK0 0x1003
+#define HDMI_FC_INHBLANK1 0x1004
+#define HDMI_FC_INVACTV0 0x1005
+#define HDMI_FC_INVACTV1 0x1006
+#define HDMI_FC_INVBLANK 0x1007
+#define HDMI_FC_HSYNCINDELAY0 0x1008
+#define HDMI_FC_HSYNCINDELAY1 0x1009
+#define HDMI_FC_HSYNCINWIDTH0 0x100A
+#define HDMI_FC_HSYNCINWIDTH1 0x100B
+#define HDMI_FC_VSYNCINDELAY 0x100C
+#define HDMI_FC_VSYNCINWIDTH 0x100D
+#define HDMI_FC_INFREQ0 0x100E
+#define HDMI_FC_INFREQ1 0x100F
+#define HDMI_FC_INFREQ2 0x1010
+#define HDMI_FC_CTRLDUR 0x1011
+#define HDMI_FC_EXCTRLDUR 0x1012
+#define HDMI_FC_EXCTRLSPAC 0x1013
+#define HDMI_FC_CH0PREAM 0x1014
+#define HDMI_FC_CH1PREAM 0x1015
+#define HDMI_FC_CH2PREAM 0x1016
+#define HDMI_FC_AVICONF3 0x1017
+#define HDMI_FC_GCP 0x1018
+#define HDMI_FC_AVICONF0 0x1019
+#define HDMI_FC_AVICONF1 0x101A
+#define HDMI_FC_AVICONF2 0x101B
+#define HDMI_FC_AVIVID 0x101C
+#define HDMI_FC_AVIETB0 0x101D
+#define HDMI_FC_AVIETB1 0x101E
+#define HDMI_FC_AVISBB0 0x101F
+#define HDMI_FC_AVISBB1 0x1020
+#define HDMI_FC_AVIELB0 0x1021
+#define HDMI_FC_AVIELB1 0x1022
+#define HDMI_FC_AVISRB0 0x1023
+#define HDMI_FC_AVISRB1 0x1024
+#define HDMI_FC_AUDICONF0 0x1025
+#define HDMI_FC_AUDICONF1 0x1026
+#define HDMI_FC_AUDICONF2 0x1027
+#define HDMI_FC_AUDICONF3 0x1028
+#define HDMI_FC_VSDIEEEID0 0x1029
+#define HDMI_FC_VSDSIZE 0x102A
+#define HDMI_FC_VSDIEEEID1 0x1030
+#define HDMI_FC_VSDIEEEID2 0x1031
+#define HDMI_FC_VSDPAYLOAD0 0x1032
+#define HDMI_FC_VSDPAYLOAD1 0x1033
+#define HDMI_FC_VSDPAYLOAD2 0x1034
+#define HDMI_FC_VSDPAYLOAD3 0x1035
+#define HDMI_FC_VSDPAYLOAD4 0x1036
+#define HDMI_FC_VSDPAYLOAD5 0x1037
+#define HDMI_FC_VSDPAYLOAD6 0x1038
+#define HDMI_FC_VSDPAYLOAD7 0x1039
+#define HDMI_FC_VSDPAYLOAD8 0x103A
+#define HDMI_FC_VSDPAYLOAD9 0x103B
+#define HDMI_FC_VSDPAYLOAD10 0x103C
+#define HDMI_FC_VSDPAYLOAD11 0x103D
+#define HDMI_FC_VSDPAYLOAD12 0x103E
+#define HDMI_FC_VSDPAYLOAD13 0x103F
+#define HDMI_FC_VSDPAYLOAD14 0x1040
+#define HDMI_FC_VSDPAYLOAD15 0x1041
+#define HDMI_FC_VSDPAYLOAD16 0x1042
+#define HDMI_FC_VSDPAYLOAD17 0x1043
+#define HDMI_FC_VSDPAYLOAD18 0x1044
+#define HDMI_FC_VSDPAYLOAD19 0x1045
+#define HDMI_FC_VSDPAYLOAD20 0x1046
+#define HDMI_FC_VSDPAYLOAD21 0x1047
+#define HDMI_FC_VSDPAYLOAD22 0x1048
+#define HDMI_FC_VSDPAYLOAD23 0x1049
+#define HDMI_FC_SPDVENDORNAME0 0x104A
+#define HDMI_FC_SPDVENDORNAME1 0x104B
+#define HDMI_FC_SPDVENDORNAME2 0x104C
+#define HDMI_FC_SPDVENDORNAME3 0x104D
+#define HDMI_FC_SPDVENDORNAME4 0x104E
+#define HDMI_FC_SPDVENDORNAME5 0x104F
+#define HDMI_FC_SPDVENDORNAME6 0x1050
+#define HDMI_FC_SPDVENDORNAME7 0x1051
+#define HDMI_FC_SDPPRODUCTNAME0 0x1052
+#define HDMI_FC_SDPPRODUCTNAME1 0x1053
+#define HDMI_FC_SDPPRODUCTNAME2 0x1054
+#define HDMI_FC_SDPPRODUCTNAME3 0x1055
+#define HDMI_FC_SDPPRODUCTNAME4 0x1056
+#define HDMI_FC_SDPPRODUCTNAME5 0x1057
+#define HDMI_FC_SDPPRODUCTNAME6 0x1058
+#define HDMI_FC_SDPPRODUCTNAME7 0x1059
+#define HDMI_FC_SDPPRODUCTNAME8 0x105A
+#define HDMI_FC_SDPPRODUCTNAME9 0x105B
+#define HDMI_FC_SDPPRODUCTNAME10 0x105C
+#define HDMI_FC_SDPPRODUCTNAME11 0x105D
+#define HDMI_FC_SDPPRODUCTNAME12 0x105E
+#define HDMI_FC_SDPPRODUCTNAME13 0x105F
+#define HDMI_FC_SDPPRODUCTNAME14 0x1060
+#define HDMI_FC_SPDPRODUCTNAME15 0x1061
+#define HDMI_FC_SPDDEVICEINF 0x1062
+#define HDMI_FC_AUDSCONF 0x1063
+#define HDMI_FC_AUDSSTAT 0x1064
+#define HDMI_FC_DATACH0FILL 0x1070
+#define HDMI_FC_DATACH1FILL 0x1071
+#define HDMI_FC_DATACH2FILL 0x1072
+#define HDMI_FC_CTRLQHIGH 0x1073
+#define HDMI_FC_CTRLQLOW 0x1074
+#define HDMI_FC_ACP0 0x1075
+#define HDMI_FC_ACP28 0x1076
+#define HDMI_FC_ACP27 0x1077
+#define HDMI_FC_ACP26 0x1078
+#define HDMI_FC_ACP25 0x1079
+#define HDMI_FC_ACP24 0x107A
+#define HDMI_FC_ACP23 0x107B
+#define HDMI_FC_ACP22 0x107C
+#define HDMI_FC_ACP21 0x107D
+#define HDMI_FC_ACP20 0x107E
+#define HDMI_FC_ACP19 0x107F
+#define HDMI_FC_ACP18 0x1080
+#define HDMI_FC_ACP17 0x1081
+#define HDMI_FC_ACP16 0x1082
+#define HDMI_FC_ACP15 0x1083
+#define HDMI_FC_ACP14 0x1084
+#define HDMI_FC_ACP13 0x1085
+#define HDMI_FC_ACP12 0x1086
+#define HDMI_FC_ACP11 0x1087
+#define HDMI_FC_ACP10 0x1088
+#define HDMI_FC_ACP9 0x1089
+#define HDMI_FC_ACP8 0x108A
+#define HDMI_FC_ACP7 0x108B
+#define HDMI_FC_ACP6 0x108C
+#define HDMI_FC_ACP5 0x108D
+#define HDMI_FC_ACP4 0x108E
+#define HDMI_FC_ACP3 0x108F
+#define HDMI_FC_ACP2 0x1090
+#define HDMI_FC_ACP1 0x1091
+#define HDMI_FC_ISCR1_0 0x1092
+#define HDMI_FC_ISCR1_16 0x1093
+#define HDMI_FC_ISCR1_15 0x1094
+#define HDMI_FC_ISCR1_14 0x1095
+#define HDMI_FC_ISCR1_13 0x1096
+#define HDMI_FC_ISCR1_12 0x1097
+#define HDMI_FC_ISCR1_11 0x1098
+#define HDMI_FC_ISCR1_10 0x1099
+#define HDMI_FC_ISCR1_9 0x109A
+#define HDMI_FC_ISCR1_8 0x109B
+#define HDMI_FC_ISCR1_7 0x109C
+#define HDMI_FC_ISCR1_6 0x109D
+#define HDMI_FC_ISCR1_5 0x109E
+#define HDMI_FC_ISCR1_4 0x109F
+#define HDMI_FC_ISCR1_3 0x10A0
+#define HDMI_FC_ISCR1_2 0x10A1
+#define HDMI_FC_ISCR1_1 0x10A2
+#define HDMI_FC_ISCR2_15 0x10A3
+#define HDMI_FC_ISCR2_14 0x10A4
+#define HDMI_FC_ISCR2_13 0x10A5
+#define HDMI_FC_ISCR2_12 0x10A6
+#define HDMI_FC_ISCR2_11 0x10A7
+#define HDMI_FC_ISCR2_10 0x10A8
+#define HDMI_FC_ISCR2_9 0x10A9
+#define HDMI_FC_ISCR2_8 0x10AA
+#define HDMI_FC_ISCR2_7 0x10AB
+#define HDMI_FC_ISCR2_6 0x10AC
+#define HDMI_FC_ISCR2_5 0x10AD
+#define HDMI_FC_ISCR2_4 0x10AE
+#define HDMI_FC_ISCR2_3 0x10AF
+#define HDMI_FC_ISCR2_2 0x10B0
+#define HDMI_FC_ISCR2_1 0x10B1
+#define HDMI_FC_ISCR2_0 0x10B2
+#define HDMI_FC_DATAUTO0 0x10B3
+#define HDMI_FC_DATAUTO1 0x10B4
+#define HDMI_FC_DATAUTO2 0x10B5
+#define HDMI_FC_DATMAN 0x10B6
+#define HDMI_FC_DATAUTO3 0x10B7
+#define HDMI_FC_RDRB0 0x10B8
+#define HDMI_FC_RDRB1 0x10B9
+#define HDMI_FC_RDRB2 0x10BA
+#define HDMI_FC_RDRB3 0x10BB
+#define HDMI_FC_RDRB4 0x10BC
+#define HDMI_FC_RDRB5 0x10BD
+#define HDMI_FC_RDRB6 0x10BE
+#define HDMI_FC_RDRB7 0x10BF
+#define HDMI_FC_STAT0 0x10D0
+#define HDMI_FC_INT0 0x10D1
+#define HDMI_FC_MASK0 0x10D2
+#define HDMI_FC_POL0 0x10D3
+#define HDMI_FC_STAT1 0x10D4
+#define HDMI_FC_INT1 0x10D5
+#define HDMI_FC_MASK1 0x10D6
+#define HDMI_FC_POL1 0x10D7
+#define HDMI_FC_STAT2 0x10D8
+#define HDMI_FC_INT2 0x10D9
+#define HDMI_FC_MASK2 0x10DA
+#define HDMI_FC_POL2 0x10DB
+#define HDMI_FC_PRCONF 0x10E0
+
+#define HDMI_FC_GMD_STAT 0x1100
+#define HDMI_FC_GMD_EN 0x1101
+#define HDMI_FC_GMD_UP 0x1102
+#define HDMI_FC_GMD_CONF 0x1103
+#define HDMI_FC_GMD_HB 0x1104
+#define HDMI_FC_GMD_PB0 0x1105
+#define HDMI_FC_GMD_PB1 0x1106
+#define HDMI_FC_GMD_PB2 0x1107
+#define HDMI_FC_GMD_PB3 0x1108
+#define HDMI_FC_GMD_PB4 0x1109
+#define HDMI_FC_GMD_PB5 0x110A
+#define HDMI_FC_GMD_PB6 0x110B
+#define HDMI_FC_GMD_PB7 0x110C
+#define HDMI_FC_GMD_PB8 0x110D
+#define HDMI_FC_GMD_PB9 0x110E
+#define HDMI_FC_GMD_PB10 0x110F
+#define HDMI_FC_GMD_PB11 0x1110
+#define HDMI_FC_GMD_PB12 0x1111
+#define HDMI_FC_GMD_PB13 0x1112
+#define HDMI_FC_GMD_PB14 0x1113
+#define HDMI_FC_GMD_PB15 0x1114
+#define HDMI_FC_GMD_PB16 0x1115
+#define HDMI_FC_GMD_PB17 0x1116
+#define HDMI_FC_GMD_PB18 0x1117
+#define HDMI_FC_GMD_PB19 0x1118
+#define HDMI_FC_GMD_PB20 0x1119
+#define HDMI_FC_GMD_PB21 0x111A
+#define HDMI_FC_GMD_PB22 0x111B
+#define HDMI_FC_GMD_PB23 0x111C
+#define HDMI_FC_GMD_PB24 0x111D
+#define HDMI_FC_GMD_PB25 0x111E
+#define HDMI_FC_GMD_PB26 0x111F
+#define HDMI_FC_GMD_PB27 0x1120
+
+#define HDMI_FC_DBGFORCE 0x1200
+#define HDMI_FC_DBGAUD0CH0 0x1201
+#define HDMI_FC_DBGAUD1CH0 0x1202
+#define HDMI_FC_DBGAUD2CH0 0x1203
+#define HDMI_FC_DBGAUD0CH1 0x1204
+#define HDMI_FC_DBGAUD1CH1 0x1205
+#define HDMI_FC_DBGAUD2CH1 0x1206
+#define HDMI_FC_DBGAUD0CH2 0x1207
+#define HDMI_FC_DBGAUD1CH2 0x1208
+#define HDMI_FC_DBGAUD2CH2 0x1209
+#define HDMI_FC_DBGAUD0CH3 0x120A
+#define HDMI_FC_DBGAUD1CH3 0x120B
+#define HDMI_FC_DBGAUD2CH3 0x120C
+#define HDMI_FC_DBGAUD0CH4 0x120D
+#define HDMI_FC_DBGAUD1CH4 0x120E
+#define HDMI_FC_DBGAUD2CH4 0x120F
+#define HDMI_FC_DBGAUD0CH5 0x1210
+#define HDMI_FC_DBGAUD1CH5 0x1211
+#define HDMI_FC_DBGAUD2CH5 0x1212
+#define HDMI_FC_DBGAUD0CH6 0x1213
+#define HDMI_FC_DBGAUD1CH6 0x1214
+#define HDMI_FC_DBGAUD2CH6 0x1215
+#define HDMI_FC_DBGAUD0CH7 0x1216
+#define HDMI_FC_DBGAUD1CH7 0x1217
+#define HDMI_FC_DBGAUD2CH7 0x1218
+#define HDMI_FC_DBGTMDS0 0x1219
+#define HDMI_FC_DBGTMDS1 0x121A
+#define HDMI_FC_DBGTMDS2 0x121B
+
+/* HDMI Source PHY Registers */
+#define HDMI_PHY_CONF0 0x3000
+#define HDMI_PHY_TST0 0x3001
+#define HDMI_PHY_TST1 0x3002
+#define HDMI_PHY_TST2 0x3003
+#define HDMI_PHY_STAT0 0x3004
+#define HDMI_PHY_INT0 0x3005
+#define HDMI_PHY_MASK0 0x3006
+#define HDMI_PHY_POL0 0x3007
+
+/* HDMI Master PHY Registers */
+#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020
+#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021
+#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022
+#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023
+#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024
+#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025
+#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
+#define HDMI_PHY_I2CM_INT_ADDR 0x3027
+#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028
+#define HDMI_PHY_I2CM_DIV_ADDR 0x3029
+#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032
+
+/* Audio Sampler Registers */
+#define HDMI_AUD_CONF0 0x3100
+#define HDMI_AUD_CONF1 0x3101
+#define HDMI_AUD_INT 0x3102
+#define HDMI_AUD_CONF2 0x3103
+#define HDMI_AUD_N1 0x3200
+#define HDMI_AUD_N2 0x3201
+#define HDMI_AUD_N3 0x3202
+#define HDMI_AUD_CTS1 0x3203
+#define HDMI_AUD_CTS2 0x3204
+#define HDMI_AUD_CTS3 0x3205
+#define HDMI_AUD_INPUTCLKFS 0x3206
+#define HDMI_AUD_SPDIFINT 0x3302
+#define HDMI_AUD_CONF0_HBR 0x3400
+#define HDMI_AUD_HBR_STATUS 0x3401
+#define HDMI_AUD_HBR_INT 0x3402
+#define HDMI_AUD_HBR_POL 0x3403
+#define HDMI_AUD_HBR_MASK 0x3404
+
+/* Generic Parallel Audio Interface Registers */
+/* Not used as GPAUD interface is not enabled in hw */
+#define HDMI_GP_CONF0 0x3500
+#define HDMI_GP_CONF1 0x3501
+#define HDMI_GP_CONF2 0x3502
+#define HDMI_GP_STAT 0x3503
+#define HDMI_GP_INT 0x3504
+#define HDMI_GP_MASK 0x3505
+#define HDMI_GP_POL 0x3506
+
+/* Audio DMA Registers */
+#define HDMI_AHB_DMA_CONF0 0x3600
+#define HDMI_AHB_DMA_START 0x3601
+#define HDMI_AHB_DMA_STOP 0x3602
+#define HDMI_AHB_DMA_THRSLD 0x3603
+#define HDMI_AHB_DMA_STRADDR0 0x3604
+#define HDMI_AHB_DMA_STRADDR1 0x3605
+#define HDMI_AHB_DMA_STRADDR2 0x3606
+#define HDMI_AHB_DMA_STRADDR3 0x3607
+#define HDMI_AHB_DMA_STPADDR0 0x3608
+#define HDMI_AHB_DMA_STPADDR1 0x3609
+#define HDMI_AHB_DMA_STPADDR2 0x360a
+#define HDMI_AHB_DMA_STPADDR3 0x360b
+#define HDMI_AHB_DMA_BSTADDR0 0x360c
+#define HDMI_AHB_DMA_BSTADDR1 0x360d
+#define HDMI_AHB_DMA_BSTADDR2 0x360e
+#define HDMI_AHB_DMA_BSTADDR3 0x360f
+#define HDMI_AHB_DMA_MBLENGTH0 0x3610
+#define HDMI_AHB_DMA_MBLENGTH1 0x3611
+#define HDMI_AHB_DMA_STAT 0x3612
+#define HDMI_AHB_DMA_INT 0x3613
+#define HDMI_AHB_DMA_MASK 0x3614
+#define HDMI_AHB_DMA_POL 0x3615
+#define HDMI_AHB_DMA_CONF1 0x3616
+#define HDMI_AHB_DMA_BUFFSTAT 0x3617
+#define HDMI_AHB_DMA_BUFFINT 0x3618
+#define HDMI_AHB_DMA_BUFFMASK 0x3619
+#define HDMI_AHB_DMA_BUFFPOL 0x361a
+
+/* Main Controller Registers */
+#define HDMI_MC_SFRDIV 0x4000
+#define HDMI_MC_CLKDIS 0x4001
+#define HDMI_MC_SWRSTZ 0x4002
+#define HDMI_MC_OPCTRL 0x4003
+#define HDMI_MC_FLOWCTRL 0x4004
+#define HDMI_MC_PHYRSTZ 0x4005
+#define HDMI_MC_LOCKONCLOCK 0x4006
+#define HDMI_MC_HEACPHY_RST 0x4007
+
+/* Color Space Converter Registers */
+#define HDMI_CSC_CFG 0x4100
+#define HDMI_CSC_SCALE 0x4101
+#define HDMI_CSC_COEF_A1_MSB 0x4102
+#define HDMI_CSC_COEF_A1_LSB 0x4103
+#define HDMI_CSC_COEF_A2_MSB 0x4104
+#define HDMI_CSC_COEF_A2_LSB 0x4105
+#define HDMI_CSC_COEF_A3_MSB 0x4106
+#define HDMI_CSC_COEF_A3_LSB 0x4107
+#define HDMI_CSC_COEF_A4_MSB 0x4108
+#define HDMI_CSC_COEF_A4_LSB 0x4109
+#define HDMI_CSC_COEF_B1_MSB 0x410A
+#define HDMI_CSC_COEF_B1_LSB 0x410B
+#define HDMI_CSC_COEF_B2_MSB 0x410C
+#define HDMI_CSC_COEF_B2_LSB 0x410D
+#define HDMI_CSC_COEF_B3_MSB 0x410E
+#define HDMI_CSC_COEF_B3_LSB 0x410F
+#define HDMI_CSC_COEF_B4_MSB 0x4110
+#define HDMI_CSC_COEF_B4_LSB 0x4111
+#define HDMI_CSC_COEF_C1_MSB 0x4112
+#define HDMI_CSC_COEF_C1_LSB 0x4113
+#define HDMI_CSC_COEF_C2_MSB 0x4114
+#define HDMI_CSC_COEF_C2_LSB 0x4115
+#define HDMI_CSC_COEF_C3_MSB 0x4116
+#define HDMI_CSC_COEF_C3_LSB 0x4117
+#define HDMI_CSC_COEF_C4_MSB 0x4118
+#define HDMI_CSC_COEF_C4_LSB 0x4119
+
+/* HDCP Encryption Engine Registers */
+#define HDMI_A_HDCPCFG0 0x5000
+#define HDMI_A_HDCPCFG1 0x5001
+#define HDMI_A_HDCPOBS0 0x5002
+#define HDMI_A_HDCPOBS1 0x5003
+#define HDMI_A_HDCPOBS2 0x5004
+#define HDMI_A_HDCPOBS3 0x5005
+#define HDMI_A_APIINTCLR 0x5006
+#define HDMI_A_APIINTSTAT 0x5007
+#define HDMI_A_APIINTMSK 0x5008
+#define HDMI_A_VIDPOLCFG 0x5009
+#define HDMI_A_OESSWCFG 0x500A
+#define HDMI_A_TIMER1SETUP0 0x500B
+#define HDMI_A_TIMER1SETUP1 0x500C
+#define HDMI_A_TIMER2SETUP0 0x500D
+#define HDMI_A_TIMER2SETUP1 0x500E
+#define HDMI_A_100MSCFG 0x500F
+#define HDMI_A_2SCFG0 0x5010
+#define HDMI_A_2SCFG1 0x5011
+#define HDMI_A_5SCFG0 0x5012
+#define HDMI_A_5SCFG1 0x5013
+#define HDMI_A_SRMVERLSB 0x5014
+#define HDMI_A_SRMVERMSB 0x5015
+#define HDMI_A_SRMCTRL 0x5016
+#define HDMI_A_SFRSETUP 0x5017
+#define HDMI_A_I2CHSETUP 0x5018
+#define HDMI_A_INTSETUP 0x5019
+#define HDMI_A_PRESETUP 0x501A
+#define HDMI_A_SRM_BASE 0x5020
+
+/* CEC Engine Registers */
+#define HDMI_CEC_CTRL 0x7D00
+#define HDMI_CEC_STAT 0x7D01
+#define HDMI_CEC_MASK 0x7D02
+#define HDMI_CEC_POLARITY 0x7D03
+#define HDMI_CEC_INT 0x7D04
+#define HDMI_CEC_ADDR_L 0x7D05
+#define HDMI_CEC_ADDR_H 0x7D06
+#define HDMI_CEC_TX_CNT 0x7D07
+#define HDMI_CEC_RX_CNT 0x7D08
+#define HDMI_CEC_TX_DATA0 0x7D10
+#define HDMI_CEC_TX_DATA1 0x7D11
+#define HDMI_CEC_TX_DATA2 0x7D12
+#define HDMI_CEC_TX_DATA3 0x7D13
+#define HDMI_CEC_TX_DATA4 0x7D14
+#define HDMI_CEC_TX_DATA5 0x7D15
+#define HDMI_CEC_TX_DATA6 0x7D16
+#define HDMI_CEC_TX_DATA7 0x7D17
+#define HDMI_CEC_TX_DATA8 0x7D18
+#define HDMI_CEC_TX_DATA9 0x7D19
+#define HDMI_CEC_TX_DATA10 0x7D1a
+#define HDMI_CEC_TX_DATA11 0x7D1b
+#define HDMI_CEC_TX_DATA12 0x7D1c
+#define HDMI_CEC_TX_DATA13 0x7D1d
+#define HDMI_CEC_TX_DATA14 0x7D1e
+#define HDMI_CEC_TX_DATA15 0x7D1f
+#define HDMI_CEC_RX_DATA0 0x7D20
+#define HDMI_CEC_RX_DATA1 0x7D21
+#define HDMI_CEC_RX_DATA2 0x7D22
+#define HDMI_CEC_RX_DATA3 0x7D23
+#define HDMI_CEC_RX_DATA4 0x7D24
+#define HDMI_CEC_RX_DATA5 0x7D25
+#define HDMI_CEC_RX_DATA6 0x7D26
+#define HDMI_CEC_RX_DATA7 0x7D27
+#define HDMI_CEC_RX_DATA8 0x7D28
+#define HDMI_CEC_RX_DATA9 0x7D29
+#define HDMI_CEC_RX_DATA10 0x7D2a
+#define HDMI_CEC_RX_DATA11 0x7D2b
+#define HDMI_CEC_RX_DATA12 0x7D2c
+#define HDMI_CEC_RX_DATA13 0x7D2d
+#define HDMI_CEC_RX_DATA14 0x7D2e
+#define HDMI_CEC_RX_DATA15 0x7D2f
+#define HDMI_CEC_LOCK 0x7D30
+#define HDMI_CEC_WKUPCTRL 0x7D31
+
+/* I2C Master Registers (E-DDC) */
+#define HDMI_I2CM_SLAVE 0x7E00
+#define HDMI_I2CM_ADDRESS 0x7E01
+#define HDMI_I2CM_DATAO 0x7E02
+#define HDMI_I2CM_DATAI 0x7E03
+#define HDMI_I2CM_OPERATION 0x7E04
+#define HDMI_I2CM_INT 0x7E05
+#define HDMI_I2CM_CTLINT 0x7E06
+#define HDMI_I2CM_DIV 0x7E07
+#define HDMI_I2CM_SEGADDR 0x7E08
+#define HDMI_I2CM_SOFTRSTZ 0x7E09
+#define HDMI_I2CM_SEGPTR 0x7E0A
+#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B
+#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C
+#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D
+#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E
+#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F
+#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10
+#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11
+#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12
+
+/* Random Number Generator Registers (RNG) */
+#define HDMI_RNG_BASE 0x8000
+
+
+/*
+ * Register field definitions
+ */
+enum {
+/* IH_FC_INT2 field values */
+ HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_FC_STAT2 field values */
+ HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_PHY_STAT0 field values */
+ HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
+ HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
+ HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
+ HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
+ HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
+ HDMI_IH_PHY_STAT0_HPD = 0x1,
+
+/* IH_CEC_STAT0 field values */
+ HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
+ HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
+ HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
+ HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
+ HDMI_IH_CEC_STAT0_NACK = 0x4,
+ HDMI_IH_CEC_STAT0_EOM = 0x2,
+ HDMI_IH_CEC_STAT0_DONE = 0x1,
+
+
+/* IH_MUTE_I2CMPHY_STAT0 field values */
+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
+ HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
+
+/* IH_PHY_STAT0 field values */
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
+ HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
+ HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
+ HDMI_IH_MUTE_PHY_STAT0_HPD = 0x1,
+
+/* IH_AHBDMAAUD_STAT0 field values */
+ HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
+ HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
+ HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
+ HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
+ HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+ HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE_FC_STAT2 field values */
+ HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_MUTE_AHBDMAAUD_STAT0 field values */
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+ HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE field values */
+ HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
+ HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
+
+/* TX_INVID0 field values */
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
+ HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
+ HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
+ HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
+
+/* TX_INSTUFFING field values */
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
+ HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
+ HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
+ HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
+
+/* VP_PR_CD field values */
+ HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
+ HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
+ HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
+
+/* VP_STUFF field values */
+ HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
+ HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
+ HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
+ HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
+ HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
+ HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
+ HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
+ HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
+ HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
+ HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
+ HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
+ HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
+ HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
+
+/* VP_CONF field values */
+ HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
+ HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
+ HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
+ HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
+ HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_PR_EN_MASK = 0x10,
+ HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
+ HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
+ HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
+ HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
+ HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
+ HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
+ HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
+ HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
+ HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
+
+/* VP_REMAP field values */
+ HDMI_VP_REMAP_MASK = 0x3,
+ HDMI_VP_REMAP_YCC422_24bit = 0x2,
+ HDMI_VP_REMAP_YCC422_20bit = 0x1,
+ HDMI_VP_REMAP_YCC422_16bit = 0x0,
+
+/* FC_INVIDCONF field values */
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80,
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80,
+ HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
+ HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
+ HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
+ HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
+ HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
+ HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
+ HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
+ HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
+ HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
+
+/* FC_AUDICONF0 field values */
+ HDMI_FC_AUDICONF0_CC_OFFSET = 4,
+ HDMI_FC_AUDICONF0_CC_MASK = 0x70,
+ HDMI_FC_AUDICONF0_CT_OFFSET = 0,
+ HDMI_FC_AUDICONF0_CT_MASK = 0xF,
+
+/* FC_AUDICONF1 field values */
+ HDMI_FC_AUDICONF1_SS_OFFSET = 3,
+ HDMI_FC_AUDICONF1_SS_MASK = 0x18,
+ HDMI_FC_AUDICONF1_SF_OFFSET = 0,
+ HDMI_FC_AUDICONF1_SF_MASK = 0x7,
+
+/* FC_AUDICONF3 field values */
+ HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
+ HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
+ HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
+ HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
+ HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
+ HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
+
+/* FC_AUDSCHNLS0 field values */
+ HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
+
+/* FC_AUDSCHNLS3-6 field values */
+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
+
+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
+
+/* HDMI_FC_AUDSCHNLS7 field values */
+ HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
+
+/* HDMI_FC_AUDSCHNLS8 field values */
+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
+ HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
+ HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
+
+/* FC_AUDSCONF field values */
+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
+ HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
+ HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
+
+/* FC_STAT2 field values */
+ HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_INT2 field values */
+ HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_MASK2 field values */
+ HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
+ HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
+ HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_PRCONF field values */
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
+ HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
+ HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
+
+/* FC_AVICONF0-FC_AVICONF3 field values */
+ HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
+ HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
+ HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
+ HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
+ HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
+ HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
+ HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
+ HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
+ HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
+ HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
+ HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
+ HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
+ HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
+
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
+ HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
+ HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
+ HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
+ HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
+ HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
+ HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
+ HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
+
+ HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
+ HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
+ HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
+ HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
+ HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
+ HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
+ HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
+ HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
+ HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
+ HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
+ HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
+ HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
+ HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
+
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
+ HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
+ HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
+ HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
+ HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
+
+/* FC_DBGFORCE field values */
+ HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
+ HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
+
+/* PHY_CONF0 field values */
+ HDMI_PHY_CONF0_PDZ_MASK = 0x80,
+ HDMI_PHY_CONF0_PDZ_OFFSET = 7,
+ HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
+ HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
+ HDMI_PHY_CONF0_SPARECTRL = 0x20,
+ HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
+ HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
+ HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
+ HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
+ HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
+ HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
+ HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
+ HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
+
+/* PHY_TST0 field values */
+ HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
+ HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
+ HDMI_PHY_TST0_TSTEN_MASK = 0x10,
+ HDMI_PHY_TST0_TSTEN_OFFSET = 4,
+ HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
+ HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
+
+/* PHY_STAT0 field values */
+ HDMI_PHY_RX_SENSE3 = 0x80,
+ HDMI_PHY_RX_SENSE2 = 0x40,
+ HDMI_PHY_RX_SENSE1 = 0x20,
+ HDMI_PHY_RX_SENSE0 = 0x10,
+ HDMI_PHY_HPD = 0x02,
+ HDMI_PHY_TX_PHY_LOCK = 0x01,
+
+/* PHY_I2CM_SLAVE_ADDR field values */
+ HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
+ HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
+
+/* PHY_I2CM_OPERATION_ADDR field values */
+ HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
+ HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
+
+/* HDMI_PHY_I2CM_INT_ADDR */
+ HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
+ HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
+
+/* HDMI_PHY_I2CM_CTLINT_ADDR */
+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
+ HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
+ HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
+
+/* AUD_CTS3 field values */
+ HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
+ HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
+ HDMI_AUD_CTS3_N_SHIFT_1 = 0,
+ HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
+ HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
+ HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
+ HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
+ HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
+ /* note that the CTS3 MANUAL bit has been removed
+ from our part. Can't set it, will read as 0. */
+ HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
+ HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
+
+/* AHB_DMA_CONF0 field values */
+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
+ HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
+ HDMI_AHB_DMA_CONF0_HBR = 0x10,
+ HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
+ HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
+ HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
+ HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
+ HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
+ HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
+ HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
+ HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
+
+/* HDMI_AHB_DMA_START field values */
+ HDMI_AHB_DMA_START_START_OFFSET = 0,
+ HDMI_AHB_DMA_START_START_MASK = 0x01,
+
+/* HDMI_AHB_DMA_STOP field values */
+ HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
+ HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
+
+/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
+ HDMI_AHB_DMA_DONE = 0x80,
+ HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
+ HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
+ HDMI_AHB_DMA_ERROR = 0x10,
+ HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
+ HDMI_AHB_DMA_FIFO_FULL = 0x02,
+ HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
+
+/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT, AHB_DMA_BUFFMASK, AHB_DMA_BUFFPOL field values */
+ HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
+ HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
+
+/* MC_CLKDIS field values */
+ HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
+ HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
+ HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
+ HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
+ HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
+ HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
+ HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
+
+/* MC_SWRSTZ field values */
+ HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
+
+/* MC_FLOWCTRL field values */
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
+ HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
+
+/* MC_PHYRSTZ field values */
+ HDMI_MC_PHYRSTZ_ASSERT = 0x0,
+ HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
+
+/* MC_HEACPHY_RST field values */
+ HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
+ HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
+
+/* CSC_CFG field values */
+ HDMI_CSC_CFG_INTMODE_MASK = 0x30,
+ HDMI_CSC_CFG_INTMODE_OFFSET = 4,
+ HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
+ HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
+ HDMI_CSC_CFG_DECMODE_MASK = 0x3,
+ HDMI_CSC_CFG_DECMODE_OFFSET = 0,
+ HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
+ HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
+
+/* CSC_SCALE field values */
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
+ HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
+ HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
+
+/* A_HDCPCFG0 field values */
+ HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80,
+ HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80,
+ HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00,
+ HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40,
+ HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40,
+ HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00,
+ HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20,
+ HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20,
+ HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00,
+ HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10,
+ HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10,
+ HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00,
+ HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8,
+ HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8,
+ HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0,
+ HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4,
+ HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4,
+ HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0,
+ HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2,
+ HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2,
+ HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0,
+ HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1,
+ HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1,
+ HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0,
+
+/* A_HDCPCFG1 field values */
+ HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8,
+ HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8,
+ HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0,
+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4,
+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4,
+ HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0,
+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2,
+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2,
+ HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0,
+ HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1,
+ HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0,
+
+/* A_VIDPOLCFG field values */
+ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60,
+ HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5,
+ HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10,
+ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10,
+ HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0,
+ HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8,
+ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8,
+ HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0,
+ HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2,
+ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
+ HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
+
+
+/* I2CM_OPERATION field values */
+ HDMI_I2CM_OPERATION_WRITE = 0x10,
+ HDMI_I2CM_OPERATION_READ_EXT = 0x2,
+ HDMI_I2CM_OPERATION_READ = 0x1,
+
+/* HDMI_I2CM_INT */
+ HDMI_I2CM_INT_DONE_POL = 0x08,
+ HDMI_I2CM_INT_DONE_MASK = 0x04,
+
+/* HDMI_I2CM_CTLINT */
+ HDMI_I2CM_CTLINT_NAC_POL = 0x80,
+ HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
+ HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
+ HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
+
+};
+
+/* IOCTL commands */
+#define HDMI_IOC_MAGIC 'H'
+
+#define HDMI_IOC_GET_RESOURCE _IO(HDMI_IOC_MAGIC, 0)
+#define HDMI_IOC_GET_CPU_TYPE _IO(HDMI_IOC_MAGIC, 1)
+
+
+#endif /* __MXC_HDMI_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h
new file mode 100644
index 00000000..6bb96ef1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_NAND_H
+#define __ASM_ARCH_NAND_H
+
+#include <linux/mtd/partitions.h>
+
+struct mxc_nand_platform_data {
+ unsigned int width; /* data bus width in bytes */
+ unsigned int hw_ecc:1; /* 0 if suppress hardware ECC */
+ unsigned int flash_bbt:1; /* set to 1 to use a flash based bbt */
+ struct mtd_partition *parts; /* partition table */
+ int nr_parts; /* size of parts */
+};
+#endif /* __ASM_ARCH_NAND_H */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_uart.h b/arch/arm/plat-mxc/include/mach/mxc_uart.h
new file mode 100644
index 00000000..689aaadf
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_uart.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup UART Universal Asynchronous Receiver Transmitter (UART) Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_uart.h
+ *
+ * @brief This file contains the UART configuration structure definition.
+ *
+ *
+ * @ingroup UART
+ */
+
+#ifndef __ASM_ARCH_MXC_UART_H__
+#define __ASM_ARCH_MXC_UART_H__
+
+#ifdef __KERNEL__
+
+#include <linux/serial_core.h>
+
+/*
+ * The modes of the UART ports
+ */
+#define MODE_DTE 0
+#define MODE_DCE 1
+/*
+ * Is the UART configured to be a IR port
+ */
+#define IRDA 0
+#define NO_IRDA 1
+
+/*!
+ * This structure is used to store the the physical and virtual
+ * addresses of the UART DMA receive buffer.
+ */
+typedef struct {
+ /*!
+ * DMA Receive buffer virtual address
+ */
+ char *rx_buf;
+ /*!
+ * DMA Receive buffer physical address
+ */
+ dma_addr_t rx_handle;
+} mxc_uart_rxdmamap;
+
+/*!
+ * This structure is a way for the low level driver to define their own
+ * \b uart_port structure. This structure includes the core \b uart_port
+ * structure that is provided by Linux as an element and has other
+ * elements that are specifically required by this low-level driver.
+ */
+typedef struct {
+ /*!
+ * The port structure holds all the information about the UART
+ * port like base address, and so on.
+ */
+ struct uart_port port;
+ /*!
+ * Flag to determine if the interrupts are muxed.
+ */
+ int ints_muxed;
+ /*!
+ * Array that holds the receive and master interrupt numbers
+ * when the interrupts are not muxed.
+ */
+ int irqs[2];
+ /*!
+ * Flag to determine the DTE/DCE mode.
+ */
+ int mode;
+ /*!
+ * Flag to hold the IR mode of the port.
+ */
+ int ir_mode;
+ /*!
+ * Flag to enable/disable the UART port.
+ */
+ int enabled;
+ /*!
+ * Flag to indicate if we wish to use hardware-driven hardware
+ * flow control.
+ */
+ int hardware_flow;
+ /*!
+ * Holds the threshold value at which the CTS line is deasserted in
+ * case we use hardware-driven hardware flow control.
+ */
+ unsigned int cts_threshold;
+ /*!
+ * Flag to enable/disable DMA data transfer.
+ */
+ int dma_enabled;
+ /*!
+ * Holds the DMA receive buffer size.
+ */
+ int dma_rxbuf_size;
+ /*!
+ * DMA Receive buffers information
+ */
+ mxc_uart_rxdmamap *rx_dmamap;
+ /*!
+ * DMA RX buffer id
+ */
+ int dma_rxbuf_id;
+ /*!
+ * DMA Transmit buffer virtual address
+ */
+ char *tx_buf;
+ /*!
+ * DMA Transmit buffer physical address
+ */
+ dma_addr_t tx_handle;
+ /*!
+ * Holds the RxFIFO threshold value.
+ */
+ unsigned int rx_threshold;
+ /*!
+ * Holds the TxFIFO threshold value.
+ */
+ unsigned int tx_threshold;
+ /*!
+ * Information whether this is a shared UART
+ */
+ unsigned int shared;
+ /*!
+ * Clock id for UART clock
+ */
+ struct clk *clk;
+ /*!
+ * Information whether RXDMUXSEL must be set or not for IR port
+ */
+ int rxd_mux;
+ int ir_tx_inv;
+ int ir_rx_inv;
+} uart_mxc_port;
+
+/* Address offsets of the UART registers */
+#define MXC_UARTURXD 0x000 /* Receive reg */
+#define MXC_UARTUTXD 0x040 /* Transmitter reg */
+#define MXC_UARTUCR1 0x080 /* Control reg 1 */
+#define MXC_UARTUCR2 0x084 /* Control reg 2 */
+#define MXC_UARTUCR3 0x088 /* Control reg 3 */
+#define MXC_UARTUCR4 0x08C /* Control reg 4 */
+#define MXC_UARTUFCR 0x090 /* FIFO control reg */
+#define MXC_UARTUSR1 0x094 /* Status reg 1 */
+#define MXC_UARTUSR2 0x098 /* Status reg 2 */
+#define MXC_UARTUESC 0x09C /* Escape character reg */
+#define MXC_UARTUTIM 0x0A0 /* Escape timer reg */
+#define MXC_UARTUBIR 0x0A4 /* BRM incremental reg */
+#define MXC_UARTUBMR 0x0A8 /* BRM modulator reg */
+#define MXC_UARTUBRC 0x0AC /* Baud rate count reg */
+#define MXC_UARTONEMS 0x0B0 /* One millisecond reg */
+#define MXC_UARTUTS 0x0B4 /* Test reg */
+#define MXC_UARTUMCR 0x0B8 /* RS485 Mode control */
+
+/* Bit definations of UCR1 */
+#define MXC_UARTUCR1_ADEN 0x8000
+#define MXC_UARTUCR1_ADBR 0x4000
+#define MXC_UARTUCR1_TRDYEN 0x2000
+#define MXC_UARTUCR1_IDEN 0x1000
+#define MXC_UARTUCR1_RRDYEN 0x0200
+#define MXC_UARTUCR1_RXDMAEN 0x0100
+#define MXC_UARTUCR1_IREN 0x0080
+#define MXC_UARTUCR1_TXMPTYEN 0x0040
+#define MXC_UARTUCR1_RTSDEN 0x0020
+#define MXC_UARTUCR1_SNDBRK 0x0010
+#define MXC_UARTUCR1_TXDMAEN 0x0008
+#define MXC_UARTUCR1_ATDMAEN 0x0004
+#define MXC_UARTUCR1_DOZE 0x0002
+#define MXC_UARTUCR1_UARTEN 0x0001
+
+/* Bit definations of UCR2 */
+#define MXC_UARTUCR2_ESCI 0x8000
+#define MXC_UARTUCR2_IRTS 0x4000
+#define MXC_UARTUCR2_CTSC 0x2000
+#define MXC_UARTUCR2_CTS 0x1000
+#define MXC_UARTUCR2_PREN 0x0100
+#define MXC_UARTUCR2_PROE 0x0080
+#define MXC_UARTUCR2_STPB 0x0040
+#define MXC_UARTUCR2_WS 0x0020
+#define MXC_UARTUCR2_RTSEN 0x0010
+#define MXC_UARTUCR2_ATEN 0x0008
+#define MXC_UARTUCR2_TXEN 0x0004
+#define MXC_UARTUCR2_RXEN 0x0002
+#define MXC_UARTUCR2_SRST 0x0001
+
+/* Bit definations of UCR3 */
+#define MXC_UARTUCR3_DTREN 0x2000
+#define MXC_UARTUCR3_PARERREN 0x1000
+#define MXC_UARTUCR3_FRAERREN 0x0800
+#define MXC_UARTUCR3_DSR 0x0400
+#define MXC_UARTUCR3_DCD 0x0200
+#define MXC_UARTUCR3_RI 0x0100
+#define MXC_UARTUCR3_RXDSEN 0x0040
+#define MXC_UARTUCR3_AWAKEN 0x0010
+#define MXC_UARTUCR3_DTRDEN 0x0008
+#define MXC_UARTUCR3_RXDMUXSEL 0x0004
+#define MXC_UARTUCR3_INVT 0x0002
+
+/* Bit definations of UCR4 */
+#define MXC_UARTUCR4_CTSTL_OFFSET 10
+#define MXC_UARTUCR4_CTSTL_MASK (0x3F << 10)
+#define MXC_UARTUCR4_INVR 0x0200
+#define MXC_UARTUCR4_ENIRI 0x0100
+#define MXC_UARTUCR4_REF16 0x0040
+#define MXC_UARTUCR4_IRSC 0x0020
+#define MXC_UARTUCR4_TCEN 0x0008
+#define MXC_UARTUCR4_OREN 0x0002
+#define MXC_UARTUCR4_DREN 0x0001
+
+/* Bit definations of UFCR */
+#define MXC_UARTUFCR_RFDIV 0x0200 /* Ref freq div is set to 2 */
+#define MXC_UARTUFCR_RFDIV_OFFSET 7
+#define MXC_UARTUFCR_RFDIV_MASK (0x7 << 7)
+#define MXC_UARTUFCR_TXTL_OFFSET 10
+#define MXC_UARTUFCR_DCEDTE 0x0040
+
+/* Bit definations of URXD */
+#define MXC_UARTURXD_ERR 0x4000
+#define MXC_UARTURXD_OVRRUN 0x2000
+#define MXC_UARTURXD_FRMERR 0x1000
+#define MXC_UARTURXD_BRK 0x0800
+#define MXC_UARTURXD_PRERR 0x0400
+
+/* Bit definations of USR1 */
+#define MXC_UARTUSR1_PARITYERR 0x8000
+#define MXC_UARTUSR1_RTSS 0x4000
+#define MXC_UARTUSR1_TRDY 0x2000
+#define MXC_UARTUSR1_RTSD 0x1000
+#define MXC_UARTUSR1_FRAMERR 0x0400
+#define MXC_UARTUSR1_RRDY 0x0200
+#define MXC_UARTUSR1_AGTIM 0x0100
+#define MXC_UARTUSR1_DTRD 0x0080
+#define MXC_UARTUSR1_AWAKE 0x0010
+
+/* Bit definations of USR2 */
+#define MXC_UARTUSR2_TXFE 0x4000
+#define MXC_UARTUSR2_IDLE 0x1000
+#define MXC_UARTUSR2_RIDELT 0x0400
+#define MXC_UARTUSR2_RIIN 0x0200
+#define MXC_UARTUSR2_DCDDELT 0x0040
+#define MXC_UARTUSR2_DCDIN 0x0020
+#define MXC_UARTUSR2_TXDC 0x0008
+#define MXC_UARTUSR2_ORE 0x0002
+#define MXC_UARTUSR2_RDR 0x0001
+#define MXC_UARTUSR2_BRCD 0x0004
+
+/* Bit definations of UTS */
+#define MXC_UARTUTS_LOOP 0x1000
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_UART_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_vpu.h b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
new file mode 100755
index 00000000..688e3aab
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup VPU Video Processor Unit Driver
+ */
+
+/*!
+ * @file plat-mxc/include/mach/mxc_vpu.h
+ *
+ * @brief VPU system initialization and file operation definition
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __ASM_ARCH_MXC_VPU_H__
+#define __ASM_ARCH_MXC_VPU_H__
+
+#include <linux/fs.h>
+
+struct mxc_vpu_platform_data {
+ bool iram_enable;
+ int iram_size;
+ void (*reset) (void);
+ void (*pg) (int);
+};
+
+struct vpu_mem_desc {
+ u32 size;
+ dma_addr_t phy_addr;
+ u32 cpu_addr; /* cpu address to free the dma mem */
+ u32 virt_uaddr; /* virtual user space address */
+};
+
+#define VPU_IOC_MAGIC 'V'
+
+#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
+#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
+#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
+#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
+#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
+#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
+#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
+#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
+#define VPU_IOC_REQ_VSHARE_MEM _IO(VPU_IOC_MAGIC, 9)
+#define VPU_IOC_SYS_SW_RESET _IO(VPU_IOC_MAGIC, 11)
+#define VPU_IOC_GET_SHARE_MEM _IO(VPU_IOC_MAGIC, 12)
+#define VPU_IOC_QUERY_BITWORK_MEM _IO(VPU_IOC_MAGIC, 13)
+#define VPU_IOC_SET_BITWORK_MEM _IO(VPU_IOC_MAGIC, 14)
+#define VPU_IOC_PHYMEM_CHECK _IO(VPU_IOC_MAGIC, 15)
+
+#define BIT_CODE_RUN 0x000
+#define BIT_CODE_DOWN 0x004
+#define BIT_INT_CLEAR 0x00C
+#define BIT_INT_STATUS 0x010
+#define BIT_CUR_PC 0x018
+#define BIT_INT_REASON 0x174
+
+#define MJPEG_PIC_STATUS_REG 0x3004
+#define MBC_SET_SUBBLK_EN 0x4A0
+
+#define BIT_WORK_CTRL_BUF_BASE 0x100
+#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
+#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
+#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
+#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
+#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
+#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
+#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
+
+#ifndef CONFIG_ARCH_MX6
+#define BIT_RESET_CTRL 0x11C
+#else
+#define BIT_RESET_CTRL 0x128
+#endif
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_RD_PTR_BASE 0x120
+#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
+#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
+#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
+
+#define BIT_BUSY_FLAG 0x160
+#define BIT_RUN_COMMAND 0x164
+#define BIT_INT_ENABLE 0x170
+
+#define BITVAL_PIC_RUN 8
+
+#define VPU_SLEEP_REG_VALUE 10
+#define VPU_WAKE_REG_VALUE 11
+
+int vl2cc_init(u32 vl2cc_hw_base);
+void vl2cc_enable(void);
+void vl2cc_flush(void);
+void vl2cc_disable(void);
+void vl2cc_cleanup(void);
+
+int vl2cc_init(u32 vl2cc_hw_base);
+void vl2cc_enable(void);
+void vl2cc_flush(void);
+void vl2cc_disable(void);
+void vl2cc_cleanup(void);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxs.h b/arch/arm/plat-mxc/include/mach/mxs.h
new file mode 100644
index 00000000..3d67fed1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxs.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+
+/*
+ * MXS CPU types
+ */
+#define cpu_is_mx23() ( \
+ machine_is_mx23evk() || \
+ 0)
+#define cpu_is_mx28() ( \
+ machine_is_mx28evk() || \
+ machine_is_tx28() || \
+ 0)
+
+#if 0
+/*
+ * IO addresses common to MXS-based
+ */
+#define MXS_IO_BASE_ADDR 0x80000000
+#define MXS_IO_SIZE SZ_1M
+
+#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
+#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
+#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
+#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
+#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
+#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
+#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
+#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
+#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
+#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
+#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
+#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
+#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
+#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
+#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
+#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
+#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
+#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
+#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
+#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
+#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
+#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
+#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
+#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
+#endif
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf50fffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 7) + \
+ (((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+#ifndef __ASSEMBLER__
+static inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_SET_ADDR);
+}
+
+static inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
+
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
+#endif
+
+#endif /* __MACH_MXS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pcie.h b/arch/arm/plat-mxc/include/mach/pcie.h
new file mode 100644
index 00000000..177410d8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pcie.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __ASM_ARCH_IMX_PCIE_H
+#define __ASM_ARCH_IMX_PCIE_H
+
+/**
+ * struct imx_pcie_platform_data - optional platform data for pcie on i.MX
+ *
+ * @pcie_pwr_en: used for enable/disable pcie power (-EINVAL if unused)
+ * @pcie_rst: used for reset pcie ep (-EINVAL if unused)
+ * @pcie_wake_up: used for wake up (-EINVAL if unused)
+ * @pcie_dis: used for disable pcie ep (-EINVAL if unused)
+ */
+
+struct imx_pcie_platform_data {
+ unsigned int pcie_pwr_en;
+ unsigned int pcie_rst;
+ unsigned int pcie_wake_up;
+ unsigned int pcie_dis;
+ unsigned int type_ep; /* 1 EP, 0 RC */
+};
+#endif /* __ASM_ARCH_IMX_PCIE_H */
diff --git a/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h b/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h
new file mode 100644
index 00000000..473d16c4
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h
@@ -0,0 +1,480 @@
+/*
+ * Freescale USBPHY Register Definitions
+ *
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.2
+ * Template revision: 1.3
+ */
+
+#ifndef __ARCH_ARM___USBPHY_H
+#define __ARCH_ARM___USBPHY_H
+
+
+#define HW_USBPHY_PWD (0x00000000)
+#define HW_USBPHY_PWD_SET (0x00000004)
+#define HW_USBPHY_PWD_CLR (0x00000008)
+#define HW_USBPHY_PWD_TOG (0x0000000c)
+
+#define BP_USBPHY_PWD_RSVD2 21
+#define BM_USBPHY_PWD_RSVD2 0xFFE00000
+#define BF_USBPHY_PWD_RSVD2(v) \
+ (((v) << 21) & BM_USBPHY_PWD_RSVD2)
+#define BM_USBPHY_PWD_RXPWDRX 0x00100000
+#define BM_USBPHY_PWD_RXPWDDIFF 0x00080000
+#define BM_USBPHY_PWD_RXPWD1PT1 0x00040000
+#define BM_USBPHY_PWD_RXPWDENV 0x00020000
+#define BP_USBPHY_PWD_RSVD1 13
+#define BM_USBPHY_PWD_RSVD1 0x0001E000
+#define BF_USBPHY_PWD_RSVD1(v) \
+ (((v) << 13) & BM_USBPHY_PWD_RSVD1)
+#define BM_USBPHY_PWD_TXPWDV2I 0x00001000
+#define BM_USBPHY_PWD_TXPWDIBIAS 0x00000800
+#define BM_USBPHY_PWD_TXPWDFS 0x00000400
+#define BP_USBPHY_PWD_RSVD0 0
+#define BM_USBPHY_PWD_RSVD0 0x000003FF
+#define BF_USBPHY_PWD_RSVD0(v) \
+ (((v) << 0) & BM_USBPHY_PWD_RSVD0)
+
+#define HW_USBPHY_TX (0x00000010)
+#define HW_USBPHY_TX_SET (0x00000014)
+#define HW_USBPHY_TX_CLR (0x00000018)
+#define HW_USBPHY_TX_TOG (0x0000001c)
+
+#define BP_USBPHY_TX_RSVD5 29
+#define BM_USBPHY_TX_RSVD5 0xE0000000
+#define BF_USBPHY_TX_RSVD5(v) \
+ (((v) << 29) & BM_USBPHY_TX_RSVD5)
+#define BP_USBPHY_TX_USBPHY_TX_EDGECTRL 26
+#define BM_USBPHY_TX_USBPHY_TX_EDGECTRL 0x1C000000
+#define BF_USBPHY_TX_USBPHY_TX_EDGECTRL(v) \
+ (((v) << 26) & BM_USBPHY_TX_USBPHY_TX_EDGECTRL)
+#define BM_USBPHY_TX_USBPHY_TX_SYNC_INVERT 0x02000000
+#define BM_USBPHY_TX_USBPHY_TX_SYNC_MUX 0x01000000
+#define BP_USBPHY_TX_RSVD4 22
+#define BM_USBPHY_TX_RSVD4 0x00C00000
+#define BF_USBPHY_TX_RSVD4(v) \
+ (((v) << 22) & BM_USBPHY_TX_RSVD4)
+#define BM_USBPHY_TX_TXENCAL45DP 0x00200000
+#define BM_USBPHY_TX_RSVD3 0x00100000
+#define BP_USBPHY_TX_TXCAL45DP 16
+#define BM_USBPHY_TX_TXCAL45DP 0x000F0000
+#define BF_USBPHY_TX_TXCAL45DP(v) \
+ (((v) << 16) & BM_USBPHY_TX_TXCAL45DP)
+#define BP_USBPHY_TX_RSVD2 14
+#define BM_USBPHY_TX_RSVD2 0x0000C000
+#define BF_USBPHY_TX_RSVD2(v) \
+ (((v) << 14) & BM_USBPHY_TX_RSVD2)
+#define BM_USBPHY_TX_TXENCAL45DN 0x00002000
+#define BM_USBPHY_TX_RSVD1 0x00001000
+#define BP_USBPHY_TX_TXCAL45DN 8
+#define BM_USBPHY_TX_TXCAL45DN 0x00000F00
+#define BF_USBPHY_TX_TXCAL45DN(v) \
+ (((v) << 8) & BM_USBPHY_TX_TXCAL45DN)
+#define BP_USBPHY_TX_RSVD0 4
+#define BM_USBPHY_TX_RSVD0 0x000000F0
+#define BF_USBPHY_TX_RSVD0(v) \
+ (((v) << 4) & BM_USBPHY_TX_RSVD0)
+#define BP_USBPHY_TX_D_CAL 0
+#define BM_USBPHY_TX_D_CAL 0x0000000F
+#define BF_USBPHY_TX_D_CAL(v) \
+ (((v) << 0) & BM_USBPHY_TX_D_CAL)
+
+#define HW_USBPHY_RX (0x00000020)
+#define HW_USBPHY_RX_SET (0x00000024)
+#define HW_USBPHY_RX_CLR (0x00000028)
+#define HW_USBPHY_RX_TOG (0x0000002c)
+
+#define BP_USBPHY_RX_RSVD2 23
+#define BM_USBPHY_RX_RSVD2 0xFF800000
+#define BF_USBPHY_RX_RSVD2(v) \
+ (((v) << 23) & BM_USBPHY_RX_RSVD2)
+#define BM_USBPHY_RX_RXDBYPASS 0x00400000
+#define BP_USBPHY_RX_RSVD1 7
+#define BM_USBPHY_RX_RSVD1 0x003FFF80
+#define BF_USBPHY_RX_RSVD1(v) \
+ (((v) << 7) & BM_USBPHY_RX_RSVD1)
+#define BP_USBPHY_RX_DISCONADJ 4
+#define BM_USBPHY_RX_DISCONADJ 0x00000070
+#define BF_USBPHY_RX_DISCONADJ(v) \
+ (((v) << 4) & BM_USBPHY_RX_DISCONADJ)
+#define BM_USBPHY_RX_RSVD0 0x00000008
+#define BP_USBPHY_RX_ENVADJ 0
+#define BM_USBPHY_RX_ENVADJ 0x00000007
+#define BF_USBPHY_RX_ENVADJ(v) \
+ (((v) << 0) & BM_USBPHY_RX_ENVADJ)
+
+#define HW_USBPHY_CTRL (0x00000030)
+#define HW_USBPHY_CTRL_SET (0x00000034)
+#define HW_USBPHY_CTRL_CLR (0x00000038)
+#define HW_USBPHY_CTRL_TOG (0x0000003c)
+
+#define BM_USBPHY_CTRL_SFTRST 0x80000000
+#define BM_USBPHY_CTRL_CLKGATE 0x40000000
+#define BM_USBPHY_CTRL_UTMI_SUSPENDM 0x20000000
+#define BM_USBPHY_CTRL_HOST_FORCE_LS_SE0 0x10000000
+#define BM_USBPHY_CTRL_OTG_ID_VALUE 0x08000000
+#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS 0x04000000
+#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE 0x02000000
+#define BM_USBPHY_CTRL_FSDLL_RST_EN 0x01000000
+#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP 0x00800000
+#define BM_USBPHY_CTRL_ENIDCHG_WKUP 0x00400000
+#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP 0x00200000
+#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD 0x00100000
+#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE 0x00080000
+#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL 0x00040000
+#define BM_USBPHY_CTRL_WAKEUP_IRQ 0x00020000
+#define BM_USBPHY_CTRL_ENIRQWAKEUP 0x00010000
+#define BM_USBPHY_CTRL_ENUTMILEVEL3 0x00008000
+#define BM_USBPHY_CTRL_ENUTMILEVEL2 0x00004000
+#define BM_USBPHY_CTRL_DATA_ON_LRADC 0x00002000
+#define BM_USBPHY_CTRL_DEVPLUGIN_IRQ 0x00001000
+#define BM_USBPHY_CTRL_ENIRQDEVPLUGIN 0x00000800
+#define BM_USBPHY_CTRL_RESUME_IRQ 0x00000400
+#define BM_USBPHY_CTRL_ENIRQRESUMEDETECT 0x00000200
+#define BM_USBPHY_CTRL_RESUMEIRQSTICKY 0x00000100
+#define BM_USBPHY_CTRL_ENOTGIDDETECT 0x00000080
+#define BM_USBPHY_CTRL_OTG_ID_CHG_IRQ 0x00000040
+#define BM_USBPHY_CTRL_DEVPLUGIN_POLARITY 0x00000020
+#define BM_USBPHY_CTRL_ENDEVPLUGINDETECT 0x00000010
+#define BM_USBPHY_CTRL_HOSTDISCONDETECT_IRQ 0x00000008
+#define BM_USBPHY_CTRL_ENIRQHOSTDISCON 0x00000004
+#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT 0x00000002
+#define BM_USBPHY_CTRL_ENOTG_ID_CHG_IRQ 0x00000001
+
+#define HW_USBPHY_STATUS (0x00000040)
+
+#define BP_USBPHY_STATUS_RSVD4 11
+#define BM_USBPHY_STATUS_RSVD4 0xFFFFF800
+#define BF_USBPHY_STATUS_RSVD4(v) \
+ (((v) << 11) & BM_USBPHY_STATUS_RSVD4)
+#define BM_USBPHY_STATUS_RESUME_STATUS 0x00000400
+#define BM_USBPHY_STATUS_RSVD3 0x00000200
+#define BM_USBPHY_STATUS_OTGID_STATUS 0x00000100
+#define BM_USBPHY_STATUS_RSVD2 0x00000080
+#define BM_USBPHY_STATUS_DEVPLUGIN_STATUS 0x00000040
+#define BP_USBPHY_STATUS_RSVD1 4
+#define BM_USBPHY_STATUS_RSVD1 0x00000030
+#define BF_USBPHY_STATUS_RSVD1(v) \
+ (((v) << 4) & BM_USBPHY_STATUS_RSVD1)
+#define BM_USBPHY_STATUS_HOSTDISCONDETECT_STATUS 0x00000008
+#define BP_USBPHY_STATUS_RSVD0 0
+#define BM_USBPHY_STATUS_RSVD0 0x00000007
+#define BF_USBPHY_STATUS_RSVD0(v) \
+ (((v) << 0) & BM_USBPHY_STATUS_RSVD0)
+
+#define HW_USBPHY_DEBUG (0x00000050)
+#define HW_USBPHY_DEBUG_SET (0x00000054)
+#define HW_USBPHY_DEBUG_CLR (0x00000058)
+#define HW_USBPHY_DEBUG_TOG (0x0000005c)
+
+#define BM_USBPHY_DEBUG_RSVD3 0x80000000
+#define BM_USBPHY_DEBUG_CLKGATE 0x40000000
+#define BM_USBPHY_DEBUG_HOST_RESUME_DEBUG 0x20000000
+#define BP_USBPHY_DEBUG_SQUELCHRESETLENGTH 25
+#define BM_USBPHY_DEBUG_SQUELCHRESETLENGTH 0x1E000000
+#define BF_USBPHY_DEBUG_SQUELCHRESETLENGTH(v) \
+ (((v) << 25) & BM_USBPHY_DEBUG_SQUELCHRESETLENGTH)
+#define BM_USBPHY_DEBUG_ENSQUELCHRESET 0x01000000
+#define BP_USBPHY_DEBUG_RSVD2 21
+#define BM_USBPHY_DEBUG_RSVD2 0x00E00000
+#define BF_USBPHY_DEBUG_RSVD2(v) \
+ (((v) << 21) & BM_USBPHY_DEBUG_RSVD2)
+#define BP_USBPHY_DEBUG_SQUELCHRESETCOUNT 16
+#define BM_USBPHY_DEBUG_SQUELCHRESETCOUNT 0x001F0000
+#define BF_USBPHY_DEBUG_SQUELCHRESETCOUNT(v) \
+ (((v) << 16) & BM_USBPHY_DEBUG_SQUELCHRESETCOUNT)
+#define BP_USBPHY_DEBUG_RSVD1 13
+#define BM_USBPHY_DEBUG_RSVD1 0x0000E000
+#define BF_USBPHY_DEBUG_RSVD1(v) \
+ (((v) << 13) & BM_USBPHY_DEBUG_RSVD1)
+#define BM_USBPHY_DEBUG_ENTX2RXCOUNT 0x00001000
+#define BP_USBPHY_DEBUG_TX2RXCOUNT 8
+#define BM_USBPHY_DEBUG_TX2RXCOUNT 0x00000F00
+#define BF_USBPHY_DEBUG_TX2RXCOUNT(v) \
+ (((v) << 8) & BM_USBPHY_DEBUG_TX2RXCOUNT)
+#define BP_USBPHY_DEBUG_RSVD0 6
+#define BM_USBPHY_DEBUG_RSVD0 0x000000C0
+#define BF_USBPHY_DEBUG_RSVD0(v) \
+ (((v) << 6) & BM_USBPHY_DEBUG_RSVD0)
+#define BP_USBPHY_DEBUG_ENHSTPULLDOWN 4
+#define BM_USBPHY_DEBUG_ENHSTPULLDOWN 0x00000030
+#define BF_USBPHY_DEBUG_ENHSTPULLDOWN(v) \
+ (((v) << 4) & BM_USBPHY_DEBUG_ENHSTPULLDOWN)
+#define BP_USBPHY_DEBUG_HSTPULLDOWN 2
+#define BM_USBPHY_DEBUG_HSTPULLDOWN 0x0000000C
+#define BF_USBPHY_DEBUG_HSTPULLDOWN(v) \
+ (((v) << 2) & BM_USBPHY_DEBUG_HSTPULLDOWN)
+#define BM_USBPHY_DEBUG_DEBUG_INTERFACE_HOLD 0x00000002
+#define BM_USBPHY_DEBUG_OTGIDPIOLOCK 0x00000001
+
+#define HW_USBPHY_DEBUG0_STATUS (0x00000060)
+
+#define BP_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT 26
+#define BM_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT 0xFC000000
+#define BF_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT(v) \
+ (((v) << 26) & BM_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT)
+#define BP_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT 16
+#define BM_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT 0x03FF0000
+#define BF_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT(v) \
+ (((v) << 16) & BM_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT)
+#define BP_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT 0
+#define BM_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT 0x0000FFFF
+#define BF_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT(v) \
+ (((v) << 0) & BM_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT)
+
+#define HW_USBPHY_DEBUG1 (0x00000070)
+#define HW_USBPHY_DEBUG1_SET (0x00000074)
+#define HW_USBPHY_DEBUG1_CLR (0x00000078)
+#define HW_USBPHY_DEBUG1_TOG (0x0000007c)
+
+#define BP_USBPHY_DEBUG1_RSVD1 15
+#define BM_USBPHY_DEBUG1_RSVD1 0xFFFF8000
+#define BF_USBPHY_DEBUG1_RSVD1(v) \
+ (((v) << 15) & BM_USBPHY_DEBUG1_RSVD1)
+#define BP_USBPHY_DEBUG1_ENTAILADJVD 13
+#define BM_USBPHY_DEBUG1_ENTAILADJVD 0x00006000
+#define BF_USBPHY_DEBUG1_ENTAILADJVD(v) \
+ (((v) << 13) & BM_USBPHY_DEBUG1_ENTAILADJVD)
+#define BM_USBPHY_DEBUG1_ENTX2TX 0x00001000
+#define BP_USBPHY_DEBUG1_RSVD0 4
+#define BM_USBPHY_DEBUG1_RSVD0 0x00000FF0
+#define BF_USBPHY_DEBUG1_RSVD0(v) \
+ (((v) << 4) & BM_USBPHY_DEBUG1_RSVD0)
+#define BP_USBPHY_DEBUG1_DBG_ADDRESS 0
+#define BM_USBPHY_DEBUG1_DBG_ADDRESS 0x0000000F
+#define BF_USBPHY_DEBUG1_DBG_ADDRESS(v) \
+ (((v) << 0) & BM_USBPHY_DEBUG1_DBG_ADDRESS)
+
+#define HW_USBPHY_VERSION (0x00000080)
+
+#define BP_USBPHY_VERSION_MAJOR 24
+#define BM_USBPHY_VERSION_MAJOR 0xFF000000
+#define BF_USBPHY_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_USBPHY_VERSION_MAJOR)
+#define BP_USBPHY_VERSION_MINOR 16
+#define BM_USBPHY_VERSION_MINOR 0x00FF0000
+#define BF_USBPHY_VERSION_MINOR(v) \
+ (((v) << 16) & BM_USBPHY_VERSION_MINOR)
+#define BP_USBPHY_VERSION_STEP 0
+#define BM_USBPHY_VERSION_STEP 0x0000FFFF
+#define BF_USBPHY_VERSION_STEP(v) \
+ (((v) << 0) & BM_USBPHY_VERSION_STEP)
+
+#define HW_USBPHY_IP (0x00000090)
+#define HW_USBPHY_IP_SET (0x00000094)
+#define HW_USBPHY_IP_CLR (0x00000098)
+#define HW_USBPHY_IP_TOG (0x0000009c)
+
+#define BP_USBPHY_IP_RSVD1 25
+#define BM_USBPHY_IP_RSVD1 0xFE000000
+#define BF_USBPHY_IP_RSVD1(v) \
+ (((v) << 25) & BM_USBPHY_IP_RSVD1)
+#define BP_USBPHY_IP_DIV_SEL 23
+#define BM_USBPHY_IP_DIV_SEL 0x01800000
+#define BF_USBPHY_IP_DIV_SEL(v) \
+ (((v) << 23) & BM_USBPHY_IP_DIV_SEL)
+#define BV_USBPHY_IP_DIV_SEL__DEFAULT 0x0
+#define BV_USBPHY_IP_DIV_SEL__LOWER 0x1
+#define BV_USBPHY_IP_DIV_SEL__LOWEST 0x2
+#define BV_USBPHY_IP_DIV_SEL__UNDEFINED 0x3
+#define BP_USBPHY_IP_LFR_SEL 21
+#define BM_USBPHY_IP_LFR_SEL 0x00600000
+#define BF_USBPHY_IP_LFR_SEL(v) \
+ (((v) << 21) & BM_USBPHY_IP_LFR_SEL)
+#define BV_USBPHY_IP_LFR_SEL__DEFAULT 0x0
+#define BV_USBPHY_IP_LFR_SEL__TIMES_2 0x1
+#define BV_USBPHY_IP_LFR_SEL__TIMES_05 0x2
+#define BV_USBPHY_IP_LFR_SEL__UNDEFINED 0x3
+#define BP_USBPHY_IP_CP_SEL 19
+#define BM_USBPHY_IP_CP_SEL 0x00180000
+#define BF_USBPHY_IP_CP_SEL(v) \
+ (((v) << 19) & BM_USBPHY_IP_CP_SEL)
+#define BV_USBPHY_IP_CP_SEL__DEFAULT 0x0
+#define BV_USBPHY_IP_CP_SEL__TIMES_2 0x1
+#define BV_USBPHY_IP_CP_SEL__TIMES_05 0x2
+#define BV_USBPHY_IP_CP_SEL__UNDEFINED 0x3
+#define BM_USBPHY_IP_TSTI_TX_DP 0x00040000
+#define BM_USBPHY_IP_TSTI_TX_DM 0x00020000
+#define BM_USBPHY_IP_ANALOG_TESTMODE 0x00010000
+#define BP_USBPHY_IP_RSVD0 3
+#define BM_USBPHY_IP_RSVD0 0x0000FFF8
+#define BF_USBPHY_IP_RSVD0(v) \
+ (((v) << 3) & BM_USBPHY_IP_RSVD0)
+#define BM_USBPHY_IP_EN_USB_CLKS 0x00000004
+#define BM_USBPHY_IP_PLL_LOCKED 0x00000002
+#define BM_USBPHY_IP_PLL_POWER 0x00000001
+
+/* The register definition for usbphy which includes at usb core's register set
+ * (from USB_CORE_BASE + 0x800)
+ */
+#define USB_CTRL USBOTHER_REG(0x00) /* USB OTG Control register */
+#define USB_H1_CTRL USBOTHER_REG(0x04) /* USB H1 Control register */
+#define USB_H2_CTRL USBOTHER_REG(0x08) /* USB H2 Control register */
+#define USB_H3_CTRL USBOTHER_REG(0x0c) /* USB H3 Control register */
+#define USB_UH2_HSIC_CTRL USBOTHER_REG(0x10) /* USB Host2 HSIC Control Register */
+#define USB_UH3_HSIC_CTRL USBOTHER_REG(0x14) /* USB Host3 HSIC Control Register */
+#define USB_OTG_PHY_CTRL_0 USBOTHER_REG(0x18) /* OTG UTMI PHY Control 0 Register */
+#define USB_H1_PHY_CTRL_0 USBOTHER_REG(0x1c) /* OTG UTMI PHY Control 1 Register */
+#define USB_UH2_HSIC_DLL_CFG1 USBOTHER_REG(0x20) /* USB Host2 HSIC DLL Configuration Register 1 */
+#define USB_UH2_HSIC_DLL_CFG2 USBOTHER_REG(0x24) /* USB Host2 HSIC DLL Configuration Register 2 */
+#define USB_UH2_HSIC_DLL_CFG3 USBOTHER_REG(0x28) /* USB Host2 HSIC DLL Configuration Register 3 */
+#define USB_UH3_HSIC_DLL_CFG1 USBOTHER_REG(0x30) /* USB Host3 HSIC DLL Configuration Register 1 */
+#define USB_UH3_HSIC_DLL_CFG2 USBOTHER_REG(0x34) /* USB Host3 HSIC DLL Configuration Register 2 */
+#define USB_UH3_HSIC_DLL_CFG3 USBOTHER_REG(0x38) /* USB Host3 HSIC DLL Configuration Register 3 */
+
+/*
+ * register bits
+ */
+
+/* USBCTRL */
+#define UCTRL_OSIC_MASK (3 << 29) /* OTG Serial Interface Config: */
+#define UCTRL_OSIC_DU6 (0 << 29) /* Differential/unidirectional 6 wire */
+#define UCTRL_OSIC_DB4 (1 << 29) /* Differential/bidirectional 4 wire */
+#define UCTRL_OSIC_SU6 (2 << 29) /* single-ended/unidirectional 6 wire */
+#define UCTRL_OSIC_SB3 (3 << 29) /* single-ended/bidirectional 3 wire */
+#define UCTRL_OUIE (1 << 28) /* OTG ULPI intr enable */
+#define UCTRL_OBPVAL_RXDP (1 << 26) /* OTG RxDp status in bypass mode */
+#define UCTRL_OBPVAL_RXDM (1 << 25) /* OTG RxDm status in bypass mode */
+#define UCTRL_OPM (1 << 24) /* OTG power mask */
+#define UCTRL_O_PWR_POL (1 << 24) /* OTG power pin polarity */
+#define UCTRL_H2WIR (1 << 17) /* HOST2 wakeup intr request received */
+#define UCTRL_H2SIC_MASK (3 << 21) /* HOST2 Serial Interface Config: */
+#define UCTRL_H2SIC_DU6 (0 << 21) /* Differential/unidirectional 6 wire */
+#define UCTRL_H2SIC_DB4 (1 << 21) /* Differential/bidirectional 4 wire */
+#define UCTRL_H2SIC_SU6 (2 << 21) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H2SIC_SB3 (3 << 21) /* single-ended/bidirectional 3 wire */
+#define UCTRL_H2UIE (1 << 8) /* HOST2 ULPI intr enable */
+#define UCTRL_H2WIE (1 << 7) /* HOST2 wakeup intr enable */
+#define UCTRL_H2PP 0 /* Power Polarity for uh2 */
+#define UCTRL_H2PM (1 << 4) /* HOST2 power mask */
+#define UCTRL_H2OVBWK_EN (1 << 6) /* OTG VBUS Wakeup Enable */
+#define UCTRL_H2OIDWK_EN (1 << 5) /* OTG ID Wakeup Enable */
+
+#define UCTRL_H1WIR (1 << 15) /* HOST1 wakeup intr request received */
+#define UCTRL_H1SIC_MASK (3 << 13) /* HOST1 Serial Interface Config: */
+#define UCTRL_H1SIC_DU6 (0 << 13) /* Differential/unidirectional 6 wire */
+#define UCTRL_H1SIC_DB4 (1 << 13) /* Differential/bidirectional 4 wire */
+#define UCTRL_H1SIC_SU6 (2 << 13) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H1SIC_SB3 (3 << 13) /* single-ended/bidirectional 3 wire */
+#define UCTRL_OLOCKD (1 << 13) /* otg lock disable */
+#define UCTRL_H2LOCKD (1 << 12) /* HOST2 lock disable */
+#define UCTRL_H1UIE (1 << 12) /* Host1 ULPI interrupt enable */
+
+#define UCTRL_PP (1 << 11) /* power polarity bit */
+#define UCTRL_H1WIE (1 << 11) /* HOST1 wakeup intr enable */
+#define UCTRL_H1BPVAL_RXDP (1 << 10) /* HOST1 RxDp status in bypass mode */
+#define UCTRL_XCSO (1 << 10) /* Xcvr Clock Select for OTG port */
+#define UCTRL_H1BPVAL_RXDM (1 << 9) /* HOST1 RxDm status in bypass mode */
+#define UCTRL_XCSH2 (1 << 9) /* Xcvr Clock Select for Host port */
+#define UCTRL_H1PM (1 << 8) /* HOST1 power mask */
+#define UCTRL_IP_PULIDP (1 << 8) /* Ipp_Puimpel_Pullup_Dp */
+
+#define UCTRL_IP_PUE_UP (1 << 7) /* ipp_pue_pullup_dp */
+#define UCTRL_IP_PUE_DOWN (1 << 6) /* ipp_pue_pulldwn_dpdm */
+#define UCTRL_H2DT (1 << 5) /* HOST2 TLL disabled */
+#define UCTRL_H1DT (1 << 4) /* HOST1 TLL disabled */
+#define UCTRL_USBTE (1 << 4) /* USBT Transceiver enable */
+#define UCTRL_OCPOL (1 << 3) /* OverCurrent Polarity */
+#define UCTRL_OCE (1 << 2) /* OverCurrent Enable */
+#define UCTRL_H2OCPOL (1 << 2) /* OverCurrent Polarity of Host2 */
+#define UCTRL_H2OCS (1 << 1) /* Host OverCurrent State */
+#define UCTRL_BPE (1 << 0) /* bypass mode enable */
+#define UCTRL_OTD (1 << 0) /* OTG TLL Disable */
+#define UCTRL_OOCS (1 << 0) /* OTG OverCurrent State */
+
+/* OTG_MIRROR */
+#define OTGM_SESEND (1 << 4) /* B device session end */
+#define OTGM_VBUSVAL (1 << 3) /* Vbus valid */
+#define OTGM_BSESVLD (1 << 2) /* B session Valid */
+#define OTGM_ASESVLD (1 << 1) /* A session Valid */
+#define OTGM_IDIDG (1 << 0) /* OTG ID pin status */
+ /* 1=high: Operate as B-device */
+ /* 0=low : Operate as A-device */
+
+/* USB_PHY_CTRL_FUNC */
+/* PHY control0 Register Bit Masks */
+#define USB_UTMI_PHYCTRL_CONF2 (1 << 26)
+
+#define USB_UTMI_PHYCTRL_UTMI_ENABLE (1 << 24)
+#define USB_UTMI_PHYCTRL_CHGRDETEN (1 << 24) /* Enable Charger Detector */
+#define USB_UTMI_PHYCTRL_CHGRDETON (1 << 23) /* Charger Detector Power On Control */
+#define USB_UTMI_PHYCTRL_OC_POL (1 << 9) /* OTG Polarity of Overcurrent */
+#define USB_UTMI_PHYCTRL_OC_DIS (1 << 8) /* OTG Disable Overcurrent Event */
+#define USB_UH1_OC_DIS (1 << 5) /* UH1 Disable Overcurrent Event */
+#define USB_UH1_OC_POL (1 << 6) /* UH1 Polarity of OC,Low active */
+/* USB_PHY_CTRL_FUNC2*/
+#define USB_UTMI_PHYCTRL2_PLLDIV_MASK 0x3
+#define USB_UTMI_PHYCTRL2_PLLDIV_SHIFT 0
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_MASK 0x3
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_SHIFT 19
+
+/* USB_CTRL_1 */
+#define USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+#define USB_CTRL_UH2_EXT_CLK_EN (1 << 26)
+#define USB_CTRL_UH2_CLK_FROM_ULPI_PHY (1 << 2)
+/* ULPIVIEW register bits */
+#define ULPIVW_OFF (0x170)
+#define ULPIVW_WU (1 << 31) /* Wakeup */
+#define ULPIVW_RUN (1 << 30) /* read/write run */
+#define ULPIVW_WRITE (1 << 29) /* 0=read 1=write */
+#define ULPIVW_SS (1 << 27) /* SyncState */
+#define ULPIVW_PORT_MASK 0x07 /* Port field */
+#define ULPIVW_PORT_SHIFT 24
+#define ULPIVW_ADDR_MASK 0xFF /* data address field */
+#define ULPIVW_ADDR_SHIFT 16
+#define ULPIVW_RDATA_MASK 0xFF /* read data field */
+#define ULPIVW_RDATA_SHIFT 8
+#define ULPIVW_WDATA_MASK 0xFF /* write data field */
+#define ULPIVW_WDATA_SHIFT 0
+
+/* USB Clock on/off Control Register */
+#define OTG_AHBCLK_OFF (0x1<<17) /* 1: OFF */
+#define H1_AHBCLK_OFF (0x1<<18) /* 1: OFF */
+
+/* mx6q's register bit begins*/
+
+/* OTG CTRL - H3 CTRL */
+#define UCTRL_OWIR (1 << 31) /* OTG wakeup intr request received */
+/* bit 18 - bit 30 is reserved at mx6q */
+#define UCTRL_WKUP_VBUS_EN (1 << 17) /* OTG wake-up on VBUS change enable */
+#define UCTRL_WKUP_ID_EN (1 << 16) /* OTG wake-up on ID change enable */
+#define UCTRL_WKUP_SW (1 << 15) /* OTG Software Wake-up */
+#define UCTRL_WKUP_SW_EN (1 << 14) /* OTG Software Wake-up enable */
+#define UCTRL_UTMI_ON_CLOCK (1 << 13) /* Force OTG UTMI PHY clock output on even if suspend mode */
+#define UCTRL_SUSPENDM (1 << 12) /* Force OTG UTMI PHY Suspend */
+#define UCTRL_RESET (1 << 11) /* Force OTG UTMI PHY Reset */
+#define UCTRL_OWIE (1 << 10) /* OTG wakeup intr request received */
+#define UCTRL_PM (1 << 9) /* OTG Power Mask */
+#define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
+#define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
+/* bit 0 - bit 6 is reserved at mx6q */
+
+/* Host2/3 HSIC Ctrl */
+#define CLK_VLD (1 << 31) /* Indicating whether HSIC clock is valid */
+#define HSIC_DEV_CONN (1 << 21) /* set after device connected */
+#define HSIC_EN (1 << 12) /* HSIC enable */
+#define HSIC_CLK_ON (1 << 11) /* Force HSIC module 480M clock on,
+ * even when in Host is in suspend mode
+ */
+/* OTG/HOST1 Phy Ctrl */
+#define PHY_UTMI_CLK_VLD (1 << 31) /* Indicating whether OTG UTMI PHY Clock Valida */
+
+#define NOP_XCVR (0xffffffff) /* Indicate it is no usb phy */
+#endif /* __ARCH_ARM___USBPHY_H */
diff --git a/arch/arm/plat-mxc/include/mach/regs-usbphy-others.h b/arch/arm/plat-mxc/include/mach/regs-usbphy-others.h
new file mode 100644
index 00000000..7d8d1ff6
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/regs-usbphy-others.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_USB_PHY_OTHERS_H__
+#define __ASM_ARCH_MXC_USB_PHY_OTHERS_H__
+
+/*
+ * This file describes the registers of chipidea's phy
+ * This file can be used for i.MX1x, i.MX21. i.MX25. i.MX3x. i.MX5x.
+ */
+
+#define USBCTRL USBOTHER_REG(0x00) /* USB Control register */
+#define USB_OTG_MIRROR USBOTHER_REG(0x04) /* USB OTG mirror register */
+#define USB_PHY_CTR_FUNC USBOTHER_REG(0x08) /* OTG UTMI PHY Function Control register */
+#define USB_PHY_CTR_FUNC2 USBOTHER_REG(0x0c) /* OTG UTMI PHY Function Control register */
+#define USB_CTRL_1 USBOTHER_REG(0x10) /* USB Cotrol Register 1*/
+#define USBCTRL_HOST2 USBOTHER_REG(0x14) /* USB Cotrol Register 1*/
+#define USBCTRL_HOST3 USBOTHER_REG(0x18) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL0 USBOTHER_REG(0x1c) /* USB Cotrol Register 1*/
+#define USBH1_PHY_CTRL1 USBOTHER_REG(0x20) /* USB Cotrol Register 1*/
+#define USB_CLKONOFF_CTRL USBOTHER_REG(0x24) /* USB Clock on/off Control Register */
+
+/*
+ * register bits
+ */
+
+/* USBCTRL */
+#define UCTRL_OWIR (1 << 31) /* OTG wakeup intr request received */
+#define UCTRL_OSIC_MASK (3 << 29) /* OTG Serial Interface Config: */
+#define UCTRL_OSIC_DU6 (0 << 29) /* Differential/unidirectional 6 wire */
+#define UCTRL_OSIC_DB4 (1 << 29) /* Differential/bidirectional 4 wire */
+#define UCTRL_OSIC_SU6 (2 << 29) /* single-ended/unidirectional 6 wire */
+#define UCTRL_OSIC_SB3 (3 << 29) /* single-ended/bidirectional 3 wire */
+#define UCTRL_OUIE (1 << 28) /* OTG ULPI intr enable */
+#define UCTRL_OWIE (1 << 27) /* OTG wakeup intr enable */
+#define UCTRL_OBPVAL_RXDP (1 << 26) /* OTG RxDp status in bypass mode */
+#define UCTRL_OBPVAL_RXDM (1 << 25) /* OTG RxDm status in bypass mode */
+#define UCTRL_OPM (1 << 24) /* OTG power mask */
+#define UCTRL_O_PWR_POL (1 << 24) /* OTG power pin polarity */
+#ifdef CONFIG_ARCH_MX5
+#define UCTRL_H2WIR (1 << 17) /* HOST2 wakeup intr request received */
+#else
+#define UCTRL_H2WIR (1 << 23) /* HOST2 wakeup intr request received */
+#endif
+#define UCTRL_H2SIC_MASK (3 << 21) /* HOST2 Serial Interface Config: */
+#define UCTRL_H2SIC_DU6 (0 << 21) /* Differential/unidirectional 6 wire */
+#define UCTRL_H2SIC_DB4 (1 << 21) /* Differential/bidirectional 4 wire */
+#define UCTRL_H2SIC_SU6 (2 << 21) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H2SIC_SB3 (3 << 21) /* single-ended/bidirectional 3 wire */
+
+#ifdef CONFIG_ARCH_MX5
+#define UCTRL_H2UIE (1 << 8) /* HOST2 ULPI intr enable */
+#define UCTRL_H2WIE (1 << 7) /* HOST2 wakeup intr enable */
+#define UCTRL_H2PP 0 /* Power Polarity for uh2 */
+#define UCTRL_H2PM (1 << 4) /* HOST2 power mask */
+#else
+#define UCTRL_H2UIE (1 << 20) /* HOST2 ULPI intr enable */
+#define UCTRL_H2WIE (1 << 19) /* HOST2 wakeup intr enable */
+#define UCTRL_H2PP (1 << 18) /* Power Polarity for uh2 */
+#define UCTRL_H2PM (1 << 16) /* HOST2 power mask */
+#endif
+#define UCTRL_H2OVBWK_EN (1 << 6) /* OTG VBUS Wakeup Enable */
+#define UCTRL_H2OIDWK_EN (1 << 5) /* OTG ID Wakeup Enable */
+
+#define UCTRL_H1WIR (1 << 15) /* HOST1 wakeup intr request received */
+#define UCTRL_H1SIC_MASK (3 << 13) /* HOST1 Serial Interface Config: */
+#define UCTRL_H1SIC_DU6 (0 << 13) /* Differential/unidirectional 6 wire */
+#define UCTRL_H1SIC_DB4 (1 << 13) /* Differential/bidirectional 4 wire */
+#define UCTRL_H1SIC_SU6 (2 << 13) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H1SIC_SB3 (3 << 13) /* single-ended/bidirectional 3 wire */
+#define UCTRL_OLOCKD (1 << 13) /* otg lock disable */
+#define UCTRL_H2LOCKD (1 << 12) /* HOST2 lock disable */
+#define UCTRL_H1UIE (1 << 12) /* Host1 ULPI interrupt enable */
+
+#if defined(CONFIG_ARCH_MX37)
+/* VBUS wakeup enable, UTMI only */
+#define UCTRL_VBUS_WKUP_EN (1 << 12)
+#elif defined(CONFIG_ARCH_MX25) || defined(CONFIG_ARCH_MX35)
+#define UCTRL_VBUS_WKUP_EN (1 << 15)
+#endif
+
+#define UCTRL_PP (1 << 11) /* power polarity bit */
+#define UCTRL_H1WIE (1 << 11) /* HOST1 wakeup intr enable */
+#define UCTRL_H1BPVAL_RXDP (1 << 10) /* HOST1 RxDp status in bypass mode */
+#define UCTRL_XCSO (1 << 10) /* Xcvr Clock Select for OTG port */
+#define UCTRL_H1BPVAL_RXDM (1 << 9) /* HOST1 RxDm status in bypass mode */
+#define UCTRL_XCSH2 (1 << 9) /* Xcvr Clock Select for Host port */
+#define UCTRL_H1PM (1 << 8) /* HOST1 power mask */
+#define UCTRL_IP_PULIDP (1 << 8) /* Ipp_Puimpel_Pullup_Dp */
+
+#define UCTRL_IP_PUE_UP (1 << 7) /* ipp_pue_pullup_dp */
+#define UCTRL_IP_PUE_DOWN (1 << 6) /* ipp_pue_pulldwn_dpdm */
+#define UCTRL_H2DT (1 << 5) /* HOST2 TLL disabled */
+#define UCTRL_H1DT (1 << 4) /* HOST1 TLL disabled */
+#define UCTRL_USBTE (1 << 4) /* USBT Transceiver enable */
+#define UCTRL_OCPOL (1 << 3) /* OverCurrent Polarity */
+#define UCTRL_OCE (1 << 2) /* OverCurrent Enable */
+#define UCTRL_H2OCPOL (1 << 2) /* OverCurrent Polarity of Host2 */
+#define UCTRL_H2OCS (1 << 1) /* Host OverCurrent State */
+#define UCTRL_BPE (1 << 0) /* bypass mode enable */
+#define UCTRL_OTD (1 << 0) /* OTG TLL Disable */
+#define UCTRL_OOCS (1 << 0) /* OTG OverCurrent State */
+
+/* OTG_MIRROR */
+#define OTGM_SESEND (1 << 4) /* B device session end */
+#define OTGM_VBUSVAL (1 << 3) /* Vbus valid */
+#define OTGM_BSESVLD (1 << 2) /* B session Valid */
+#define OTGM_ASESVLD (1 << 1) /* A session Valid */
+#define OTGM_IDIDG (1 << 0) /* OTG ID pin status */
+ /* 1=high: Operate as B-device */
+ /* 0=low : Operate as A-device */
+
+/* USB_PHY_CTRL_FUNC */
+/* PHY control0 Register Bit Masks */
+#define USB_UTMI_PHYCTRL_CONF2 (1 << 26)
+
+#define USB_UTMI_PHYCTRL_UTMI_ENABLE (1 << 24)
+#define USB_UTMI_PHYCTRL_CHGRDETEN (1 << 24) /* Enable Charger Detector */
+#define USB_UTMI_PHYCTRL_CHGRDETON (1 << 23) /* Charger Detector Power On Control */
+#define USB_UTMI_PHYCTRL_OC_POL (1 << 9) /* OTG Polarity of Overcurrent */
+#define USB_UTMI_PHYCTRL_OC_DIS (1 << 8) /* OTG Disable Overcurrent Event */
+#define USB_UH1_OC_DIS (1 << 5) /* UH1 Disable Overcurrent Event */
+#define USB_UH1_OC_POL (1 << 6) /* UH1 Polarity of OC,Low active */
+/* USB_PHY_CTRL_FUNC2*/
+#define USB_UTMI_PHYCTRL2_PLLDIV_MASK 0x3
+#define USB_UTMI_PHYCTRL2_PLLDIV_SHIFT 0
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_MASK 0x3
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_SHIFT 19
+
+/* USB_CTRL_1 */
+#define USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+#define USB_CTRL_UH2_EXT_CLK_EN (1 << 26)
+#define USB_CTRL_UH2_CLK_FROM_ULPI_PHY (1 << 2)
+/* ULPIVIEW register bits */
+#define ULPIVW_OFF (0x170)
+#define ULPIVW_WU (1 << 31) /* Wakeup */
+#define ULPIVW_RUN (1 << 30) /* read/write run */
+#define ULPIVW_WRITE (1 << 29) /* 0=read 1=write */
+#define ULPIVW_SS (1 << 27) /* SyncState */
+#define ULPIVW_PORT_MASK 0x07 /* Port field */
+#define ULPIVW_PORT_SHIFT 24
+#define ULPIVW_ADDR_MASK 0xFF /* data address field */
+#define ULPIVW_ADDR_SHIFT 16
+#define ULPIVW_RDATA_MASK 0xFF /* read data field */
+#define ULPIVW_RDATA_SHIFT 8
+#define ULPIVW_WDATA_MASK 0xFF /* write data field */
+#define ULPIVW_WDATA_SHIFT 0
+
+/* USB Clock on/off Control Register */
+#define OTG_AHBCLK_OFF (0x1<<17) /* 1: OFF */
+#define H1_AHBCLK_OFF (0x1<<18) /* 1: OFF */
+#endif /* __ASM_ARCH_MXC_USB_PHY_OTHERS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h
new file mode 100644
index 00000000..cee7fe49
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/sdma.h
@@ -0,0 +1,66 @@
+#ifndef __MACH_MXC_SDMA_H__
+#define __MACH_MXC_SDMA_H__
+
+/**
+ * struct sdma_script_start_addrs - SDMA script start pointers
+ *
+ * start addresses of the different functions in the physical
+ * address space of the SDMA engine.
+ */
+struct sdma_script_start_addrs {
+ s32 ap_2_ap_addr;
+ s32 ap_2_bp_addr;
+ s32 ap_2_ap_fixed_addr;
+ s32 bp_2_ap_addr;
+ s32 loopback_on_dsp_side_addr;
+ s32 mcu_interrupt_only_addr;
+ s32 firi_2_per_addr;
+ s32 firi_2_mcu_addr;
+ s32 per_2_firi_addr;
+ s32 mcu_2_firi_addr;
+ s32 uart_2_per_addr;
+ s32 uart_2_mcu_addr;
+ s32 per_2_app_addr;
+ s32 mcu_2_app_addr;
+ s32 per_2_per_addr;
+ s32 uartsh_2_per_addr;
+ s32 uartsh_2_mcu_addr;
+ s32 per_2_shp_addr;
+ s32 mcu_2_shp_addr;
+ s32 ata_2_mcu_addr;
+ s32 mcu_2_ata_addr;
+ s32 app_2_per_addr;
+ s32 app_2_mcu_addr;
+ s32 shp_2_per_addr;
+ s32 shp_2_mcu_addr;
+ s32 mshc_2_mcu_addr;
+ s32 mcu_2_mshc_addr;
+ s32 spdif_2_mcu_addr;
+ s32 mcu_2_spdif_addr;
+ s32 asrc_2_mcu_addr;
+ s32 ext_mem_2_ipu_addr;
+ s32 descrambler_addr;
+ s32 dptc_dvfs_addr;
+ s32 utra_addr;
+ s32 ram_code_start_addr;
+ s32 mcu_2_ssish_addr;
+ s32 ssish_2_mcu_addr;
+ s32 hdmi_dma_addr;
+};
+
+/**
+ * struct sdma_platform_data - platform specific data for SDMA engine
+ *
+ * @sdma_version The version of this SDMA engine
+ * @cpu_name used to generate the firmware name
+ * @to_version CPU Tape out version
+ * @script_addrs SDMA scripts addresses in SDMA ROM
+ */
+struct sdma_platform_data {
+ int sdma_version;
+ char *cpu_name;
+ int to_version;
+ struct sdma_script_start_addrs *script_addrs;
+};
+
+#endif /* __MACH_MXC_SDMA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/sdram_autogating.h b/arch/arm/plat-mxc/include/mach/sdram_autogating.h
new file mode 100755
index 00000000..e102add8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/sdram_autogating.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup DVFS Dynamic Voltage and Frequency Scaling (DVFS) Driver
+ */
+
+/*!
+ * @file arch-mxc/sdram_autogating.h
+ *
+ * @brief This file contains the SDRAM autogating function prototypes
+ *
+ *
+ * @ingroup PM
+ */
+
+#ifndef __ASM_ARCH_SDRAM_AUTOGATING_H__
+#define __ASM_ARCH_SDRAM_AUTOGATING_H__
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+
+
+#ifdef CONFIG_ARCH_MX5
+extern void start_sdram_autogating(void);
+extern void stop_sdram_autogating(void);
+extern int sdram_autogating_active(void);
+#else
+static inline void start_sdram_autogating(void)
+{}
+
+static inline void stop_sdram_autogating(void)
+{}
+
+static inline int sdram_autogating_active(void)
+{
+ return 0;
+}
+#endif
+
+#endif /*__KERNEL__ */
+#endif /* __ASM_ARCH_MXC_DVFS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/smp.h b/arch/arm/plat-mxc/include/mach/smp.h
new file mode 100644
index 00000000..fcc42535
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/smp.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef FSL_ARCH_SMP_H
+#define FSL_ARCH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+/* Needed for secondary core boot */
+extern void mx6_secondary_startup(void);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/spi.h b/arch/arm/plat-mxc/include/mach/spi.h
new file mode 100644
index 00000000..08be445e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/spi.h
@@ -0,0 +1,27 @@
+
+#ifndef __MACH_SPI_H_
+#define __MACH_SPI_H_
+
+/*
+ * struct spi_imx_master - device.platform_data for SPI controller devices.
+ * @chipselect: Array of chipselects for this master. Numbers >= 0 mean gpio
+ * pins, numbers < 0 mean internal CSPI chipselects according
+ * to MXC_SPI_CS(). Normally you want to use gpio based chip
+ * selects as the CSPI module tries to be intelligent about
+ * when to assert the chipselect: The CSPI module deasserts the
+ * chipselect once it runs out of input data. The other problem
+ * is that it is not possible to mix between high active and low
+ * active chipselects on one single bus using the internal
+ * chipselects. Unfortunately Freescale decided to put some
+ * chipselects on dedicated pins which are not usable as gpios,
+ * so we have to support the internal chipselects.
+ * @num_chipselect: ARRAY_SIZE(chipselect)
+ */
+struct spi_imx_master {
+ int *chipselect;
+ int num_chipselect;
+};
+
+#define MXC_SPI_CS(no) ((no) - 32)
+
+#endif /* __MACH_SPI_H_*/
diff --git a/arch/arm/plat-mxc/include/mach/ssi.h b/arch/arm/plat-mxc/include/mach/ssi.h
new file mode 100644
index 00000000..63f3c280
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ssi.h
@@ -0,0 +1,21 @@
+#ifndef __MACH_SSI_H
+#define __MACH_SSI_H
+
+struct snd_ac97;
+
+extern unsigned char imx_ssi_fiq_start, imx_ssi_fiq_end;
+extern unsigned long imx_ssi_fiq_base, imx_ssi_fiq_tx_buffer, imx_ssi_fiq_rx_buffer;
+
+struct imx_ssi_platform_data {
+ unsigned int flags;
+#define IMX_SSI_DMA (1 << 0)
+#define IMX_SSI_USE_AC97 (1 << 1)
+#define IMX_SSI_NET (1 << 2)
+#define IMX_SSI_SYN (1 << 3)
+#define IMX_SSI_USE_I2S_SLAVE (1 << 4)
+ void (*ac97_reset) (struct snd_ac97 *ac97);
+ void (*ac97_warm_reset)(struct snd_ac97 *ac97);
+};
+
+#endif /* __MACH_SSI_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
new file mode 100755
index 00000000..649a97ce
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_MXC_SYSTEM_H__
+#define __ASM_ARCH_MXC_SYSTEM_H__
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define LDO_MODE_DEFAULT 0
+#define LDO_MODE_BYPASSED 1
+#define LDO_MODE_ENABLED 2
+extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+
+void arch_idle(void);
+
+void arch_reset(char mode, const char *cmd);
+
+#ifdef CONFIG_MXC_REBOOT_MFGMODE
+void do_switch_mfgmode(void);
+void mxc_clear_mfgmode(void);
+#else
+#define do_switch_mfgmode() do {} while (0)
+#define mxc_clear_mfgmode() do {} while (0)
+#endif
+
+#ifdef CONFIG_MXC_REBOOT_ANDROID_CMD
+void do_switch_recovery(void);
+void do_switch_fastboot(void);
+#else
+#define do_switch_recovery() do {} while (0)
+#define do_switch_fastboot() do {} while (0)
+#endif
+
+#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
new file mode 100644
index 00000000..695063bd
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2004-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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_MXC_TIMEX_H__
+#define __ASM_ARCH_MXC_TIMEX_H__
+
+#if defined CONFIG_ARCH_MX1
+#define CLOCK_TICK_RATE 16000000
+#elif defined CONFIG_ARCH_MX2
+#define CLOCK_TICK_RATE 13300000
+#elif defined CONFIG_ARCH_MX3
+#define CLOCK_TICK_RATE 16625000
+#elif defined CONFIG_ARCH_MX25
+#define CLOCK_TICK_RATE 16000000
+#elif defined CONFIG_ARCH_MX5
+#define CLOCK_TICK_RATE 8000000
+#elif defined CONFIG_ARCH_MX6
+#define CLOCK_TICK_RATE 8000000
+#endif
+
+#endif /* __ASM_ARCH_MXC_TIMEX_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/ulpi.h b/arch/arm/plat-mxc/include/mach/ulpi.h
new file mode 100644
index 00000000..f9161c96
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ulpi.h
@@ -0,0 +1,16 @@
+#ifndef __MACH_ULPI_H
+#define __MACH_ULPI_H
+
+#ifdef CONFIG_USB_ULPI
+struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags);
+#else
+static inline struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags)
+{
+ return NULL;
+}
+#endif
+
+extern struct otg_io_access_ops mxc_ulpi_access_ops;
+
+#endif /* __MACH_ULPI_H */
+
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
new file mode 100644
index 00000000..92e777e1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -0,0 +1,145 @@
+/*
+ * arch/arm/plat-mxc/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@minirl.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.
+ */
+#ifndef __ASM_ARCH_MXC_UNCOMPRESS_H__
+#define __ASM_ARCH_MXC_UNCOMPRESS_H__
+
+#define __MXC_BOOT_UNCOMPRESS
+
+#include <asm/mach-types.h>
+
+unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define USR2 0x98
+#define USR2_TXFE (1<<14)
+#define TXR 0x40
+#define UCR1 0x80
+#define UCR1_UARTEN 1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+static void putc(int ch)
+{
+ if (!uart_base)
+ return;
+ if (!(UART(UCR1) & UCR1_UARTEN))
+ return;
+
+ while (!(UART(USR2) & USR2_TXFE))
+ barrier();
+
+ UART(TXR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX1_UART1_BASE_ADDR 0x00206000
+#define MX25_UART1_BASE_ADDR 0x43f90000
+#define MX2X_UART1_BASE_ADDR 0x1000a000
+#define MX3X_UART1_BASE_ADDR 0x43F90000
+#define MX3X_UART2_BASE_ADDR 0x43F94000
+#define MX3X_UART5_BASE_ADDR 0x43FB4000
+#define MX51_UART1_BASE_ADDR 0x73fbc000
+#define MX50_UART1_BASE_ADDR 0x53fbc000
+#define MX53_UART1_BASE_ADDR 0x53fbc000
+#define MX6Q_UART4_BASE_ADDR 0x021f0000
+#define MX6Q_UART2_BASE_ADDR 0x021e8000
+#define MX6Q_UART1_BASE_ADDR 0x02020000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX1ADS:
+ case MACH_TYPE_SCB9328:
+ uart_base = MX1_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX25_3DS:
+ uart_base = MX25_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_IMX27LITE:
+ case MACH_TYPE_MX27_3DS:
+ case MACH_TYPE_MX27ADS:
+ case MACH_TYPE_PCM038:
+ case MACH_TYPE_MX21ADS:
+ case MACH_TYPE_PCA100:
+ case MACH_TYPE_MXT_TD60:
+ case MACH_TYPE_IMX27IPCAM:
+ uart_base = MX2X_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX31LITE:
+ case MACH_TYPE_ARMADILLO5X0:
+ case MACH_TYPE_MX31MOBOARD:
+ case MACH_TYPE_QONG:
+ case MACH_TYPE_MX31_3DS:
+ case MACH_TYPE_PCM037:
+ case MACH_TYPE_MX31ADS:
+ case MACH_TYPE_MX35_3DS:
+ case MACH_TYPE_PCM043:
+ case MACH_TYPE_LILLY1131:
+ case MACH_TYPE_VPR200:
+ uart_base = MX3X_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MAGX_ZN5:
+ uart_base = MX3X_UART2_BASE_ADDR;
+ break;
+ case MACH_TYPE_BUG:
+ uart_base = MX3X_UART5_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX51_BABBAGE:
+ case MACH_TYPE_EUKREA_CPUIMX51SD:
+ case MACH_TYPE_MX51_3DS:
+ uart_base = MX51_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX50_RDP:
+ uart_base = MX50_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX53_EVK:
+ case MACH_TYPE_MX53_LOCO:
+ case MACH_TYPE_MX53_SMD:
+ uart_base = MX53_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX6Q_ARM2:
+ uart_base = MX6Q_UART4_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX6Q_SABRELITE:
+ uart_base = MX6Q_UART2_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX6Q_SABRESD:
+ uart_base = MX6Q_UART1_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX6Q_SABREAUTO:
+ uart_base = MX6Q_UART4_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __ASM_ARCH_MXC_UNCOMPRESS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/usb.h b/arch/arm/plat-mxc/include/mach/usb.h
new file mode 100644
index 00000000..be273371
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/usb.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.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.
+ */
+
+#ifndef __ASM_ARCH_MXC_USB
+#define __ASM_ARCH_MXC_USB
+
+struct imxusb_platform_data {
+ int (*init)(struct device *);
+ void (*exit)(struct device *);
+};
+
+#endif /* __ASM_ARCH_MXC_USB */
diff --git a/arch/arm/plat-mxc/include/mach/viv_gpu.h b/arch/arm/plat-mxc/include/mach/viv_gpu.h
new file mode 100644
index 00000000..f3136cec
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/viv_gpu.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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_VIV_GPU_H_
+#define __MACH_VIV_GPU_H_
+
+struct viv_gpu_platform_data {
+ resource_size_t reserved_mem_base;
+ resource_size_t reserved_mem_size;
+};
+
+#endif /* __MACH_VIV_GPU_H_ */
diff --git a/arch/arm/plat-mxc/include/mach/vmalloc.h b/arch/arm/plat-mxc/include/mach/vmalloc.h
new file mode 100644
index 00000000..44ea15a8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_MXC_VMALLOC_H__
+#define __ASM_ARCH_MXC_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf2000000UL
+
+#endif /* __ASM_ARCH_MXC_VMALLOC_H__ */
diff --git a/arch/arm/plat-mxc/iomux-v1.c b/arch/arm/plat-mxc/iomux-v1.c
new file mode 100644
index 00000000..3238c10d
--- /dev/null
+++ b/arch/arm/plat-mxc/iomux-v1.c
@@ -0,0 +1,220 @@
+/*
+ * arch/arm/plat-mxc/iomux-v1.c
+ *
+ * Copyright (C) 2004 Sascha Hauer, Synertronixx GmbH
+ * Copyright (C) 2009 Uwe Kleine-Koenig, Pengutronix
+ *
+ * Common code for i.MX1, i.MX21 and i.MX27
+ *
+ * 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.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <mach/iomux-v1.h>
+
+static void __iomem *imx_iomuxv1_baseaddr;
+static unsigned imx_iomuxv1_numports;
+
+static inline unsigned long imx_iomuxv1_readl(unsigned offset)
+{
+ return __raw_readl(imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset)
+{
+ __raw_writel(val, imx_iomuxv1_baseaddr + offset);
+}
+
+static inline void imx_iomuxv1_rmwl(unsigned offset,
+ unsigned long mask, unsigned long value)
+{
+ unsigned long reg = imx_iomuxv1_readl(offset);
+
+ reg &= ~mask;
+ reg |= value;
+
+ imx_iomuxv1_writel(reg, offset);
+}
+
+static inline void imx_iomuxv1_set_puen(
+ unsigned int port, unsigned int pin, int on)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_PUEN(port), mask, on ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ddir(
+ unsigned int port, unsigned int pin, int out)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_DDIR(port), mask, out ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gpr(
+ unsigned int port, unsigned int pin, int af)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_GPR(port), mask, af ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_gius(
+ unsigned int port, unsigned int pin, int inuse)
+{
+ unsigned long mask = 1 << pin;
+
+ imx_iomuxv1_rmwl(MXC_GIUS(port), mask, inuse ? mask : 0);
+}
+
+static inline void imx_iomuxv1_set_ocr(
+ unsigned int port, unsigned int pin, unsigned int ocr)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = ocr << shift;
+ unsigned long offset = pin < 16 ? MXC_OCR1(port) : MXC_OCR2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfa(
+ unsigned int port, unsigned int pin, unsigned int aout)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = aout << shift;
+ unsigned long offset = pin < 16 ? MXC_ICONFA1(port) : MXC_ICONFA2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+static inline void imx_iomuxv1_set_iconfb(
+ unsigned int port, unsigned int pin, unsigned int bout)
+{
+ unsigned long shift = (pin & 0xf) << 1;
+ unsigned long mask = 3 << shift;
+ unsigned long value = bout << shift;
+ unsigned long offset = pin < 16 ? MXC_ICONFB1(port) : MXC_ICONFB2(port);
+
+ imx_iomuxv1_rmwl(offset, mask, value);
+}
+
+int mxc_gpio_mode(int gpio_mode)
+{
+ unsigned int pin = gpio_mode & GPIO_PIN_MASK;
+ unsigned int port = (gpio_mode & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
+ unsigned int ocr = (gpio_mode & GPIO_OCR_MASK) >> GPIO_OCR_SHIFT;
+ unsigned int aout = (gpio_mode >> GPIO_AOUT_SHIFT) & 3;
+ unsigned int bout = (gpio_mode >> GPIO_BOUT_SHIFT) & 3;
+
+ if (port >= imx_iomuxv1_numports)
+ return -EINVAL;
+
+ /* Pullup enable */
+ imx_iomuxv1_set_puen(port, pin, gpio_mode & GPIO_PUEN);
+
+ /* Data direction */
+ imx_iomuxv1_set_ddir(port, pin, gpio_mode & GPIO_OUT);
+
+ /* Primary / alternate function */
+ imx_iomuxv1_set_gpr(port, pin, gpio_mode & GPIO_AF);
+
+ /* use as gpio? */
+ imx_iomuxv1_set_gius(port, pin, !(gpio_mode & (GPIO_PF | GPIO_AF)));
+
+ imx_iomuxv1_set_ocr(port, pin, ocr);
+
+ imx_iomuxv1_set_iconfa(port, pin, aout);
+
+ imx_iomuxv1_set_iconfb(port, pin, bout);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_gpio_mode);
+
+static int imx_iomuxv1_setup_multiple(const int *list, unsigned count)
+{
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; ++i) {
+ ret = mxc_gpio_mode(list[i]);
+
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count,
+ const char *label)
+{
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; ++i) {
+ unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+ ret = gpio_request(gpio, label);
+ if (ret)
+ goto err_gpio_request;
+ }
+
+ ret = imx_iomuxv1_setup_multiple(pin_list, count);
+ if (ret)
+ goto err_setup;
+
+ return 0;
+
+err_setup:
+ BUG_ON(i != count);
+
+err_gpio_request:
+ mxc_gpio_release_multiple_pins(pin_list, i);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_gpio_setup_multiple_pins);
+
+void mxc_gpio_release_multiple_pins(const int *pin_list, int count)
+{
+ size_t i;
+
+ for (i = 0; i < count; ++i) {
+ unsigned gpio = pin_list[i] & (GPIO_PIN_MASK | GPIO_PORT_MASK);
+
+ gpio_free(gpio);
+ }
+}
+EXPORT_SYMBOL(mxc_gpio_release_multiple_pins);
+
+int __init imx_iomuxv1_init(void __iomem *base, int numports)
+{
+ imx_iomuxv1_baseaddr = base;
+ imx_iomuxv1_numports = numports;
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/iomux-v3.c b/arch/arm/plat-mxc/iomux-v3.c
new file mode 100644
index 00000000..b88208c1
--- /dev/null
+++ b/arch/arm/plat-mxc/iomux-v3.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2004-2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ * <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+#include <mach/iomux-v3.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
+{
+ u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+ u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+ u32 sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+ u32 sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+ u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+ u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+
+ if (mux_ctrl_ofs)
+ __raw_writel(mux_mode, base + mux_ctrl_ofs);
+
+ if (sel_input_ofs)
+ __raw_writel(sel_input, base + sel_input_ofs);
+
+ if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+ __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
+
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_v3_setup_pad);
+
+/*
+ * Read a single pad in the iomuxer
+ */
+int mxc_iomux_v3_get_pad(iomux_v3_cfg_t *pad)
+{
+ u32 mux_ctrl_ofs = (*pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+ u32 pad_ctrl_ofs = (*pad & MUX_PAD_CTRL_OFS_MASK)
+ >> MUX_PAD_CTRL_OFS_SHIFT;
+ u32 sel_input_ofs = (*pad & MUX_SEL_INPUT_OFS_MASK)
+ >> MUX_SEL_INPUT_OFS_SHIFT;
+ u32 mux_mode = 0;
+ u32 sel_input = 0;
+ u32 pad_ctrl = 0;
+ iomux_v3_cfg_t pad_info = 0;
+
+ mux_mode = __raw_readl(base + mux_ctrl_ofs) & 0xFF;
+ pad_ctrl = __raw_readl(base + pad_ctrl_ofs) & 0x1FFFF;
+ sel_input = __raw_readl(base + sel_input_ofs) & 0x7;
+
+ pad_info = (((iomux_v3_cfg_t)mux_mode << MUX_MODE_SHIFT) | \
+ ((iomux_v3_cfg_t)pad_ctrl << MUX_PAD_CTRL_SHIFT) | \
+ ((iomux_v3_cfg_t)sel_input << MUX_SEL_INPUT_SHIFT));
+
+ *pad &= ~(MUX_MODE_MASK | MUX_PAD_CTRL_MASK | MUX_SEL_INPUT_MASK);
+ *pad |= pad_info;
+
+ return 0;
+}
+
+
+int mxc_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count)
+{
+ iomux_v3_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxc_iomux_v3_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_v3_setup_multiple_pads);
+
+/*
+ * Read multiple pads in the iomuxer
+ */
+int mxc_iomux_v3_get_multiple_pads(iomux_v3_cfg_t *pad_list, unsigned count)
+{
+ iomux_v3_cfg_t *p = pad_list;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ mxc_iomux_v3_get_pad(p);
+ p++;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_v3_get_multiple_pads);
+
+void mxc_iomux_set_gpr_register(int group, int start_bit, int num_bits, int value)
+{
+ int i = 0;
+ u32 reg;
+ reg = __raw_readl(base + group * 4);
+ while (num_bits) {
+ reg &= ~(1<<(start_bit + i));
+ i++;
+ num_bits--;
+ }
+ reg |= (value << start_bit);
+ __raw_writel(reg, base + group * 4);
+}
+EXPORT_SYMBOL(mxc_iomux_set_gpr_register);
+void mxc_iomux_set_specialbits_register(u32 pad_addr, u32 value, u32 mask)
+{
+ u32 reg;
+ reg = __raw_readl(base + pad_addr);
+ reg &= ~mask;
+ reg |= value;
+ __raw_writel(reg, base + pad_addr);
+}
+EXPORT_SYMBOL(mxc_iomux_set_specialbits_register);
+
+void mxc_iomux_v3_init(void __iomem *iomux_v3_base)
+{
+ base = iomux_v3_base;
+}
diff --git a/arch/arm/plat-mxc/iram_alloc.c b/arch/arm/plat-mxc/iram_alloc.c
new file mode 100644
index 00000000..074c3869
--- /dev/null
+++ b/arch/arm/plat-mxc/iram_alloc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/genalloc.h>
+#include <mach/iram.h>
+
+static unsigned long iram_phys_base;
+static void __iomem *iram_virt_base;
+static struct gen_pool *iram_pool;
+
+static inline void __iomem *iram_phys_to_virt(unsigned long p)
+{
+ return iram_virt_base + (p - iram_phys_base);
+}
+
+void __iomem *iram_alloc(unsigned int size, unsigned long *dma_addr)
+{
+ if (!iram_pool)
+ return NULL;
+
+ *dma_addr = gen_pool_alloc(iram_pool, size);
+ pr_debug("iram alloc - %dB@0x%lX\n", size, *dma_addr);
+ if (!*dma_addr)
+ return NULL;
+ return iram_phys_to_virt(*dma_addr);
+}
+EXPORT_SYMBOL(iram_alloc);
+
+void iram_free(unsigned long addr, unsigned int size)
+{
+ if (!iram_pool)
+ return;
+
+ gen_pool_free(iram_pool, addr, size);
+}
+EXPORT_SYMBOL(iram_free);
+
+int __init iram_init(unsigned long base, unsigned long size)
+{
+ iram_phys_base = base;
+
+ iram_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!iram_pool)
+ return -ENOMEM;
+
+ gen_pool_add(iram_pool, base, size, -1);
+ iram_virt_base = ioremap(iram_phys_base, size);
+ if (!iram_virt_base)
+ return -EIO;
+
+ pr_debug("i.MX IRAM pool: %ld KB@0x%p\n", size / 1024, iram_virt_base);
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/irq-common.c b/arch/arm/plat-mxc/irq-common.c
new file mode 100644
index 00000000..e1c6eff7
--- /dev/null
+++ b/arch/arm/plat-mxc/irq-common.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) BitBox Ltd 2010
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+
+#include "irq-common.h"
+
+int imx_irq_set_priority(unsigned char irq, unsigned char prio)
+{
+ struct mxc_irq_chip *chip;
+ struct irq_chip *base;
+ int ret;
+
+ ret = -ENOSYS;
+
+ base = irq_get_chip(irq);
+ if (base) {
+ chip = container_of(base, struct mxc_irq_chip, base);
+ if (chip->set_priority)
+ ret = chip->set_priority(irq, prio);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(imx_irq_set_priority);
+
+int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ struct mxc_irq_chip *chip;
+ struct irq_chip *base;
+ int ret;
+
+ ret = -ENOSYS;
+
+ base = irq_get_chip(irq);
+ if (base) {
+ chip = container_of(base, struct mxc_irq_chip, base);
+ if (chip->set_irq_fiq)
+ ret = chip->set_irq_fiq(irq, type);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_set_irq_fiq);
diff --git a/arch/arm/plat-mxc/irq-common.h b/arch/arm/plat-mxc/irq-common.h
new file mode 100644
index 00000000..7203543f
--- /dev/null
+++ b/arch/arm/plat-mxc/irq-common.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) BitBox Ltd 2010
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __PLAT_MXC_IRQ_COMMON_H__
+#define __PLAT_MXC_IRQ_COMMON_H__
+
+struct mxc_irq_chip
+{
+ struct irq_chip base;
+ int (*set_priority)(unsigned char irq, unsigned char prio);
+ int (*set_irq_fiq)(unsigned int irq, unsigned int type);
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/isp1504xc.c b/arch/arm/plat-mxc/isp1504xc.c
new file mode 100755
index 00000000..8fd7bf2d
--- /dev/null
+++ b/arch/arm/plat-mxc/isp1504xc.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/delay.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+
+/* ISP 1504 register addresses */
+#define ISP1504_VID_LOW 0x00 /* Vendor ID low */
+#define ISP1504_VID_HIGH 0x01 /* Vendor ID high */
+#define ISP1504_PID_LOW 0x02 /* Product ID low */
+#define ISP1504_PID_HIGH 0x03 /* Product ID high */
+#define ISP1504_FUNC 0x04 /* Function Control */
+#define ISP1504_ITFCTL 0x07 /* Interface Control */
+#define ISP1504_OTGCTL 0x0A /* OTG Control */
+
+/* add to above register address to access Set/Clear functions */
+#define ISP1504_REG_SET 0x01
+#define ISP1504_REG_CLEAR 0x02
+
+/* 1504 OTG Control Register bits */
+#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
+#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
+#define DRV_VBUS (1 << 5) /* Drive Vbus */
+#define CHRG_VBUS (1 << 4) /* Charge Vbus */
+#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
+#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
+#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
+#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */
+
+/* 1504 OTG Function Control Register bits */
+#define SUSPENDM (1 << 6) /* places the PHY into
+ low-power mode */
+#define DRV_RESET (1 << 5) /* Active HIGH transceiver
+ reset */
+
+/*!
+ * read ULPI register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param reg register to read
+ * @param view the ULPI VIEWPORT register address
+ * @return return isp1504 register value
+ */
+static u8 isp1504_read(int reg, volatile u32 *view)
+{
+ u32 data;
+
+ /* make sure interface is running */
+ if (!(__raw_readl(view) && ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+ do { /* wait for wakeup */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_WU);
+ }
+
+ /* read the register */
+ __raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view);
+
+ do { /* wait for completion */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_RUN);
+
+ return (u8) (data >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
+}
+
+/*!
+ * set bits into OTG ISP1504 register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param bits set value
+ * @param reg which register
+ * @param view the ULPI VIEWPORT register address
+ */
+static void isp1504_set(u8 bits, int reg, volatile u32 *view)
+{
+ u32 data;
+
+ /* make sure interface is running */
+ if (!(__raw_readl(view) && ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+ do { /* wait for wakeup */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_WU);
+ }
+
+ __raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
+ ((reg + ISP1504_REG_SET) << ULPIVW_ADDR_SHIFT) |
+ ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
+ view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+/*!
+ * clear bits in OTG ISP1504 register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param bits bits to clear
+ * @param reg in this register
+ * @param view the ULPI VIEWPORT register address
+ */
+static void isp1504_clear(u8 bits, int reg, volatile u32 *view)
+{
+ __raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
+ ((reg + ISP1504_REG_CLEAR) << ULPIVW_ADDR_SHIFT) |
+ ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
+ view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+
+static void isp1508_fix(u32 *view)
+{
+ /* Set bits IND_PASS_THRU and IND_COMPL */
+ isp1504_set(0x60, ISP1504_ITFCTL, view);
+
+ /* Set bit USE_EXT_VBUS_IND */
+ isp1504_set(USE_EXT_VBUS_IND, ISP1504_OTGCTL, view);
+}
+
+/*!
+ * set vbus power
+ *
+ * @param view viewport register
+ * @param on power on or off
+ */
+static void isp1504_set_vbus_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ u32 *view = pdata->regs + ULPIVW_OFF;
+
+ pr_debug("real %s(on=%d) view=0x%p\n", __FUNCTION__, on, view);
+
+ pr_debug("ULPI Vendor ID 0x%x Product ID 0x%x\n",
+ (isp1504_read(ISP1504_VID_HIGH, view) << 8) |
+ isp1504_read(ISP1504_VID_LOW, view),
+ (isp1504_read(ISP1504_PID_HIGH, view) << 8) |
+ isp1504_read(ISP1504_PID_LOW, view));
+
+ pr_debug("OTG Control before=0x%x\n",
+ isp1504_read(ISP1504_OTGCTL, view));
+
+ if (on) {
+ isp1504_set(DRV_VBUS_EXT | /* enable external Vbus */
+ DRV_VBUS | /* enable internal Vbus */
+ USE_EXT_VBUS_IND | /* use external indicator */
+ CHRG_VBUS, /* charge Vbus */
+ ISP1504_OTGCTL, view);
+
+ } else {
+ isp1508_fix(view);
+
+ isp1504_clear(DRV_VBUS_EXT | /* disable external Vbus */
+ DRV_VBUS, /* disable internal Vbus */
+ ISP1504_OTGCTL, view);
+
+ isp1504_set(USE_EXT_VBUS_IND | /* use external indicator */
+ DISCHRG_VBUS, /* discharge Vbus */
+ ISP1504_OTGCTL, view);
+ }
+
+ pr_debug("OTG Control after = 0x%x\n",
+ isp1504_read(ISP1504_OTGCTL, view));
+}
+
+/*!
+ * set remote wakeup
+ *
+ * @param view viewport register
+ */
+static void isp1504_set_remote_wakeup(u32 *view)
+{
+ __raw_writel(~ULPIVW_WRITE & __raw_readl(view), view);
+ __raw_writel((1 << ULPIVW_PORT_SHIFT) | __raw_readl(view), view);
+ __raw_writel(ULPIVW_RUN | __raw_readl(view), view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+static void isp1504_init(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s:\n", __FUNCTION__);
+}
+
+static void isp1504_uninit(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s:\n", __FUNCTION__);
+}
+
+static void isp1504_suspend(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s\n", __func__);
+
+ /* send suspend command */
+ isp1504_clear(SUSPENDM, ISP1504_FUNC, &UOG_ULPIVIEW);
+ pr_debug("%s.\n", __func__);
+}
+
+/*!
+ * Set the 1504 transceiver to the proper mode for testing purposes.
+ *
+ * @param view the ULPI VIEWPORT register address
+ * @param test_mode Set the 1504 transceiver to disable bit stuffing and NRZI
+ */
+ static void isp1504_set_test_mode(u32 *view, enum usb_test_mode test_mode)
+{
+ if (test_mode == USB_TEST_J || test_mode == USB_TEST_K) {
+ printk(KERN_INFO "udc: disable bit stuffing and NRZI\n");
+ /* Disable bit-stuffing and NRZI encoding. */
+ isp1504_set(0x10, 0x04, view);
+ }
+}
+
+static struct fsl_xcvr_ops isp1504_ops = {
+ .name = "isp1504",
+ .xcvr_type = PORTSC_PTS_ULPI,
+ .init = isp1504_init,
+ .uninit = isp1504_uninit,
+ .suspend = isp1504_suspend,
+ .set_vbus_power = isp1504_set_vbus_power,
+ .set_remote_wakeup = isp1504_set_remote_wakeup,
+ .set_test_mode = isp1504_set_test_mode,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+extern int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init isp1504xc_init(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ fsl_usb_xcvr_register(&isp1504_ops);
+
+ /* suspend isp1504 */
+ if (fsl_usb_xcvr_suspend(&isp1504_ops))
+ pr_debug("%s: failed to suspend isp1504\n", __func__);
+
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit isp1504xc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&isp1504_ops);
+}
+
+subsys_initcall(isp1504xc_init);
+module_exit(isp1504xc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("isp1504 xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
new file mode 100755
index 00000000..eb490571
--- /dev/null
+++ b/arch/arm/plat-mxc/pwm.c
@@ -0,0 +1,343 @@
+/*
+ * simple driver for PWM (Pulse Width Modulator) 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.
+ *
+ * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
+ * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+#include <linux/fsl_devices.h>
+#include <mach/hardware.h>
+
+
+/* i.MX1 and i.MX21 share the same PWM function block: */
+
+#define MX1_PWMC 0x00 /* PWM Control Register */
+#define MX1_PWMS 0x04 /* PWM Sample Register */
+#define MX1_PWMP 0x08 /* PWM Period Register */
+
+
+/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
+
+#define MX3_PWMCR 0x00 /* PWM Control Register */
+#define MX3_PWMSAR 0x0C /* PWM Sample Register */
+#define MX3_PWMPR 0x10 /* PWM Period Register */
+#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)
+#define MX3_PWMCR_DOZEEN (1 << 24)
+#define MX3_PWMCR_WAITEN (1 << 23)
+#define MX3_PWMCR_DBGEN (1 << 22)
+#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
+#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
+#define MX3_PWMCR_SWR (1 << 3)
+#define MX3_PWMCR_EN (1 << 0)
+
+#define MX3_PWMCR_STOPEN (1 << 25)
+#define MX3_PWMCR_DOZEEN (1 << 24)
+#define MX3_PWMCR_WAITEN (1 << 23)
+#define MX3_PWMCR_DBGEN (1 << 22)
+#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
+#define MX3_PWMCR_CLKSRC_IPG_32k (3 << 16)
+
+struct pwm_device {
+ struct list_head node;
+ struct platform_device *pdev;
+
+ const char *label;
+ struct clk *clk;
+
+ int clk_enabled;
+ void __iomem *mmio_base;
+
+ unsigned int use_count;
+ unsigned int pwm_id;
+ int pwmo_invert;
+ void (*enable_pwm_pad)(void);
+ void (*disable_pwm_pad)(void);
+};
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+ if (!(cpu_is_mx1() || cpu_is_mx21())) {
+ unsigned long long c;
+ unsigned long period_cycles, duty_cycles, prescale;
+ u32 cr;
+
+ if (pwm->pwmo_invert)
+ duty_ns = period_ns - duty_ns;
+
+ c = clk_get_rate(pwm->clk);
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ prescale = period_cycles / 0x10000 + 1;
+
+ period_cycles /= prescale;
+ c = (unsigned long long)period_cycles * duty_ns;
+ do_div(c, period_ns);
+ duty_cycles = c;
+
+ /*
+ * according to imx pwm RM, the real period value should be
+ * PERIOD value in PWMPR plus 2.
+ */
+ if (period_cycles > 2)
+ period_cycles -= 2;
+ else
+ period_cycles = 0;
+
+ writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
+ writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
+
+ cr = MX3_PWMCR_PRESCALER(prescale) |
+ MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEEN |
+ MX3_PWMCR_WAITEN | MX3_PWMCR_DBGEN;
+
+ if (cpu_is_mx25())
+ cr |= MX3_PWMCR_CLKSRC_IPG;
+ else
+ cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
+
+ writel(cr, pwm->mmio_base + MX3_PWMCR);
+ } else if (cpu_is_mx1() || cpu_is_mx21()) {
+ /* The PWM subsystem allows for exact frequencies. However,
+ * I cannot connect a scope on my device to the PWM line and
+ * thus cannot provide the program the PWM controller
+ * exactly. Instead, I'm relying on the fact that the
+ * Bootloader (u-boot or WinCE+haret) has programmed the PWM
+ * function group already. So I'll just modify the PWM sample
+ * register to follow the ratio of duty_ns vs. period_ns
+ * accordingly.
+ *
+ * This is good enough for programming the brightness of
+ * the LCD backlight.
+ *
+ * The real implementation would divide PERCLK[0] first by
+ * both the prescaler (/1 .. /128) and then by CLKSEL
+ * (/2 .. /16).
+ */
+ u32 max = readl(pwm->mmio_base + MX1_PWMP);
+ u32 p;
+ if (pwm->pwmo_invert)
+ duty_ns = period_ns - duty_ns;
+ p = max * duty_ns / period_ns;
+ writel(max - p, pwm->mmio_base + MX1_PWMS);
+ } else {
+ BUG();
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ unsigned long reg;
+ int rc = 0;
+
+ if (!pwm->clk_enabled) {
+ rc = clk_enable(pwm->clk);
+ if (!rc)
+ pwm->clk_enabled = 1;
+ }
+
+ reg = readl(pwm->mmio_base + MX3_PWMCR);
+ reg |= MX3_PWMCR_EN;
+ writel(reg, pwm->mmio_base + MX3_PWMCR);
+
+ if (pwm->enable_pwm_pad)
+ pwm->enable_pwm_pad();
+
+ return rc;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ if (pwm->disable_pwm_pad)
+ pwm->disable_pwm_pad();
+
+ writel(MX3_PWMCR_SWR, pwm->mmio_base + MX3_PWMCR);
+ while (readl(pwm->mmio_base + MX3_PWMCR) & MX3_PWMCR_SWR)
+ ;
+
+ if (pwm->clk_enabled) {
+ clk_disable(pwm->clk);
+ pwm->clk_enabled = 0;
+ }
+}
+EXPORT_SYMBOL(pwm_disable);
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, node) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count++;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ pr_warning("PWM device already freed\n");
+
+ mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static int __devinit mxc_pwm_probe(struct platform_device *pdev)
+{
+ struct pwm_device *pwm;
+ struct resource *r;
+ struct mxc_pwm_platform_data *plat_data = pdev->dev.platform_data;
+ int ret = 0;
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ pwm->clk = clk_get(&pdev->dev, "pwm");
+
+ if (IS_ERR(pwm->clk)) {
+ ret = PTR_ERR(pwm->clk);
+ goto err_free;
+ }
+
+ pwm->clk_enabled = 0;
+
+ pwm->use_count = 0;
+ pwm->pwm_id = pdev->id;
+ pwm->pdev = pdev;
+ if (plat_data != NULL) {
+ pwm->pwmo_invert = plat_data->pwmo_invert;
+ pwm->enable_pwm_pad = plat_data->enable_pwm_pad;
+ pwm->disable_pwm_pad = plat_data->disable_pwm_pad;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+
+ r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ ret = -EBUSY;
+ goto err_free_clk;
+ }
+
+ pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ if (pwm->mmio_base == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap() registers\n");
+ ret = -ENODEV;
+ goto err_free_mem;
+ }
+
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->node, &pwm_list);
+ mutex_unlock(&pwm_lock);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+err_free_mem:
+ release_mem_region(r->start, r->end - r->start + 1);
+err_free_clk:
+ clk_put(pwm->clk);
+err_free:
+ kfree(pwm);
+ return ret;
+}
+
+static int __devexit mxc_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm;
+ struct resource *r;
+
+ pwm = platform_get_drvdata(pdev);
+ if (pwm == NULL)
+ return -ENODEV;
+
+ mutex_lock(&pwm_lock);
+ list_del(&pwm->node);
+ mutex_unlock(&pwm_lock);
+
+ iounmap(pwm->mmio_base);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, r->end - r->start + 1);
+
+ clk_put(pwm->clk);
+
+ kfree(pwm);
+ return 0;
+}
+
+static struct platform_driver mxc_pwm_driver = {
+ .driver = {
+ .name = "mxc_pwm",
+ },
+ .probe = mxc_pwm_probe,
+ .remove = __devexit_p(mxc_pwm_remove),
+};
+
+static int __init mxc_pwm_init(void)
+{
+ return platform_driver_register(&mxc_pwm_driver);
+}
+arch_initcall(mxc_pwm_init);
+
+static void __exit mxc_pwm_exit(void)
+{
+ platform_driver_unregister(&mxc_pwm_driver);
+}
+module_exit(mxc_pwm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/arch/arm/plat-mxc/serialxc.c b/arch/arm/plat-mxc/serialxc.c
new file mode 100755
index 00000000..a3eeef96
--- /dev/null
+++ b/arch/arm/plat-mxc/serialxc.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+
+static void usb_serial_init(struct fsl_xcvr_ops *this)
+{
+}
+
+static void usb_serial_uninit(struct fsl_xcvr_ops *this)
+{
+}
+
+static struct fsl_xcvr_ops serial_ops = {
+ .name = "serial",
+ .xcvr_type = PORTSC_PTS_SERIAL,
+ .init = usb_serial_init,
+ .uninit = usb_serial_uninit,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init serialxc_init(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ fsl_usb_xcvr_register(&serial_ops);
+
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit serialxc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&serial_ops);
+}
+
+subsys_initcall(serialxc_init);
+module_exit(serialxc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("serial xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/ssi-fiq-ksym.c b/arch/arm/plat-mxc/ssi-fiq-ksym.c
new file mode 100644
index 00000000..b5fad454
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq-ksym.c
@@ -0,0 +1,20 @@
+/*
+ * Exported ksyms for the SSI FIQ handler
+ *
+ * Copyright (C) 2009, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+
+#include <mach/ssi.h>
+
+EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer);
+EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer);
+EXPORT_SYMBOL(imx_ssi_fiq_start);
+EXPORT_SYMBOL(imx_ssi_fiq_end);
+EXPORT_SYMBOL(imx_ssi_fiq_base);
+
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
new file mode 100644
index 00000000..8397a2dd
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
+ * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
+ */
+
+#define SSI_STX0 0x00
+#define SSI_SRX0 0x08
+#define SSI_SISR 0x14
+#define SSI_SIER 0x18
+#define SSI_SACNT 0x38
+
+#define SSI_SACNT_AC97EN (1 << 0)
+
+#define SSI_SIER_TFE0_EN (1 << 0)
+#define SSI_SISR_TFE0 (1 << 0)
+#define SSI_SISR_RFF0 (1 << 2)
+#define SSI_SIER_RFF0_EN (1 << 2)
+
+ .text
+ .global imx_ssi_fiq_start
+ .global imx_ssi_fiq_end
+ .global imx_ssi_fiq_base
+ .global imx_ssi_fiq_rx_buffer
+ .global imx_ssi_fiq_tx_buffer
+
+imx_ssi_fiq_start:
+ ldr r12, imx_ssi_fiq_base
+
+ /* TX */
+ ldr r11, imx_ssi_fiq_tx_buffer
+
+ /* shall we send? */
+ ldr r13, [r12, #SSI_SIER]
+ tst r13, #SSI_SIER_TFE0_EN
+ beq 1f
+
+ /* TX FIFO empty? */
+ ldr r13, [r12, #SSI_SISR]
+ tst r13, #SSI_SISR_TFE0
+ beq 1f
+
+ mov r10, #0x10000
+ sub r10, #1
+ and r10, r10, r8 /* r10: current buffer offset */
+
+ add r11, r11, r10
+
+ ldrh r13, [r11]
+ strh r13, [r12, #SSI_STX0]
+
+ ldrh r13, [r11, #2]
+ strh r13, [r12, #SSI_STX0]
+
+ ldrh r13, [r11, #4]
+ strh r13, [r12, #SSI_STX0]
+
+ ldrh r13, [r11, #6]
+ strh r13, [r12, #SSI_STX0]
+
+ add r10, #8
+ lsr r13, r8, #16 /* r13: buffer size */
+ cmp r10, r13
+ lslgt r8, r13, #16
+ addle r8, #8
+1:
+ /* RX */
+
+ /* shall we receive? */
+ ldr r13, [r12, #SSI_SIER]
+ tst r13, #SSI_SIER_RFF0_EN
+ beq 1f
+
+ /* RX FIFO full? */
+ ldr r13, [r12, #SSI_SISR]
+ tst r13, #SSI_SISR_RFF0
+ beq 1f
+
+ ldr r11, imx_ssi_fiq_rx_buffer
+
+ mov r10, #0x10000
+ sub r10, #1
+ and r10, r10, r9 /* r10: current buffer offset */
+
+ add r11, r11, r10
+
+ ldr r13, [r12, #SSI_SACNT]
+ tst r13, #SSI_SACNT_AC97EN
+
+ ldr r13, [r12, #SSI_SRX0]
+ strh r13, [r11]
+
+ ldr r13, [r12, #SSI_SRX0]
+ strh r13, [r11, #2]
+
+ /* dummy read to skip slot 12 */
+ ldrne r13, [r12, #SSI_SRX0]
+
+ ldr r13, [r12, #SSI_SRX0]
+ strh r13, [r11, #4]
+
+ ldr r13, [r12, #SSI_SRX0]
+ strh r13, [r11, #6]
+
+ /* dummy read to skip slot 12 */
+ ldrne r13, [r12, #SSI_SRX0]
+
+ add r10, #8
+ lsr r13, r9, #16 /* r13: buffer size */
+ cmp r10, r13
+ lslgt r9, r13, #16
+ addle r9, #8
+
+1:
+ @ return from FIQ
+ subs pc, lr, #4
+
+ .align
+imx_ssi_fiq_base:
+ .word 0x0
+imx_ssi_fiq_rx_buffer:
+ .word 0x0
+imx_ssi_fiq_tx_buffer:
+ .word 0x0
+imx_ssi_fiq_end:
+
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
new file mode 100644
index 00000000..e216f687
--- /dev/null
+++ b/arch/arm/plat-mxc/system.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2012 Freescale Semiconductor, Inc.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/system.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#ifdef CONFIG_SMP
+#include <linux/smp.h>
+#endif
+#include <asm/mach-types.h>
+
+static void __iomem *wdog_base;
+extern u32 enable_ldo_mode;
+
+
+static void arch_reset_special_mode(char mode, const char *cmd)
+{
+ if (strcmp(cmd, "download") == 0)
+ do_switch_mfgmode();
+ else if (strcmp(cmd, "recovery") == 0)
+ do_switch_recovery();
+ else if (strcmp(cmd, "fastboot") == 0)
+ do_switch_fastboot();
+}
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ unsigned int wcr_enable;
+
+ arch_reset_special_mode(mode, cmd);
+
+#ifdef CONFIG_ARCH_MX6
+ /* wait for reset to assert... */
+ if (enable_ldo_mode == LDO_MODE_BYPASSED) {
+ /*On Sabresd board use WDOG2 to reset external PMIC, so here do
+ * more WDOG2 reset.*/
+ wcr_enable = 0x14;
+ __raw_writew(wcr_enable, IO_ADDRESS(MX6Q_WDOG2_BASE_ADDR));
+ __raw_writew(wcr_enable, IO_ADDRESS(MX6Q_WDOG2_BASE_ADDR));
+ } else
+ wcr_enable = (1 << 2);
+ __raw_writew(wcr_enable, wdog_base);
+ /* errata TKT039676, SRS bit may be missed when
+ SRC sample it, need to write the wdog controller
+ twice to avoid it */
+ __raw_writew(wcr_enable, wdog_base);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+ return;
+#endif
+
+#ifdef CONFIG_MACH_MX51_EFIKAMX
+ if (machine_is_mx51_efikamx()) {
+ mx51_efikamx_reset();
+ return;
+ }
+#endif
+
+ if (cpu_is_mx1()) {
+ wcr_enable = (1 << 0);
+ } else {
+ struct clk *clk;
+
+ clk = clk_get_sys("imx2-wdt.0", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+ wcr_enable = (1 << 2);
+ }
+
+ /* Assert SRS signal */
+ __raw_writew(wcr_enable, wdog_base);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* we'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+void mxc_arch_reset_init(void __iomem *base)
+{
+ wdog_base = base;
+}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
new file mode 100644
index 00000000..08504b3e
--- /dev/null
+++ b/arch/arm/plat-mxc/time.c
@@ -0,0 +1,343 @@
+/*
+ * linux/arch/arm/plat-mxc/time.c
+ *
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/sched_clock.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timer hardware on Freescale MXC hardware.
+ * Version 1: MX1/MXL, MX21, MX27.
+ * Version 2: MX25, MX31, MX35, MX37, MX51
+ */
+
+/* defines common for all i.MX */
+#define MXC_TCTL 0x00
+#define MXC_TCTL_TEN (1 << 0) /* Enable module */
+#define MXC_TPRER 0x04
+
+/* MX1, MX21, MX27 */
+#define MX1_2_TCTL_CLK_PCLK1 (1 << 1)
+#define MX1_2_TCTL_IRQEN (1 << 4)
+#define MX1_2_TCTL_FRR (1 << 8)
+#define MX1_2_TCMP 0x08
+#define MX1_2_TCN 0x10
+#define MX1_2_TSTAT 0x14
+
+/* MX21, MX27 */
+#define MX2_TSTAT_CAPT (1 << 1)
+#define MX2_TSTAT_COMP (1 << 0)
+
+/* MX31, MX35, MX25, MX5 */
+#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
+#define V2_TCTL_CLK_IPG (1 << 6)
+#define V2_TCTL_CLK_PER (2 << 6)
+#define V2_TCTL_CLK_OSC_DIV8 (5 << 6)
+#define V2_TCTL_CLK_OSC (7 << 6)
+#define V2_TCTL_FRR (1 << 9)
+#define V2_TCTL_ENABLE24M (1 << 10)
+#define V2_TPRER_PRE24M_DIV8 7
+#define V2_TPRER_PRE24M_MASK 0xF
+#define V2_TPRER_PRE24M_OFFSET 12
+#define V2_IR 0x0c
+#define V2_TSTAT 0x08
+#define V2_TSTAT_OF1 (1 << 0)
+#define V2_TCN 0x24
+#define V2_TCMP 0x10
+
+#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#define timer_is_v2() (!timer_is_v1())
+
+static struct clock_event_device clockevent_mxc;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void gpt_irq_disable(void)
+{
+ unsigned int tmp;
+
+ if (timer_is_v2())
+ __raw_writel(0, timer_base + V2_IR);
+ else {
+ tmp = __raw_readl(timer_base + MXC_TCTL);
+ __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
+ }
+}
+
+static inline void gpt_irq_enable(void)
+{
+ if (timer_is_v2())
+ __raw_writel(1<<0, timer_base + V2_IR);
+ else {
+ __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
+ timer_base + MXC_TCTL);
+ }
+}
+
+static void gpt_irq_acknowledge(void)
+{
+ if (timer_is_v1()) {
+ if (cpu_is_mx1())
+ __raw_writel(0, timer_base + MX1_2_TSTAT);
+ else
+ __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
+ timer_base + MX1_2_TSTAT);
+ } else if (timer_is_v2())
+ __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
+}
+
+static void __iomem *sched_clock_reg;
+
+static DEFINE_CLOCK_DATA(cd);
+unsigned long long notrace sched_clock(void)
+{
+ cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
+
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mxc_update_sched_clock(void)
+{
+ cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static int __init mxc_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+ void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
+
+ sched_clock_reg = reg;
+
+ init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
+ return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
+ clocksource_mmio_readl_up);
+}
+
+/* clock event */
+
+static int mx1_2_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long tcmp;
+
+ tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt;
+
+ __raw_writel(tcmp, timer_base + MX1_2_TCMP);
+
+ return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ?
+ -ETIME : 0;
+}
+
+static int v2_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long tcmp;
+
+ tcmp = __raw_readl(timer_base + V2_TCN) + evt;
+
+ __raw_writel(tcmp, timer_base + V2_TCMP);
+
+ return evt < 0x7fffffff &&
+ (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
+ -ETIME : 0;
+}
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call mxc_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in GPT module */
+ gpt_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+ if (timer_is_v2())
+ __raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
+ timer_base + V2_TCMP);
+ else
+ __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
+ timer_base + MX1_2_TCMP);
+
+ /* Clear pending interrupt */
+ gpt_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n",
+ clock_event_mode_label[clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR"mxc_set_mode: Periodic mode is not "
+ "supported for i.MX\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * mxc_set_next_event(), the core has about 4 minutes
+ * to call mxc_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ gpt_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mxc;
+ uint32_t tstat;
+
+ if (timer_is_v2())
+ tstat = __raw_readl(timer_base + V2_TSTAT);
+ else
+ tstat = __raw_readl(timer_base + MX1_2_TSTAT);
+
+ gpt_irq_acknowledge();
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxc_timer_irq = {
+ .name = "i.MX Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxc_timer_interrupt,
+};
+
+static struct clock_event_device clockevent_mxc = {
+ .name = "mxc_timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxc_set_mode,
+ .set_next_event = mx1_2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxc_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timer_is_v2())
+ clockevent_mxc.set_next_event = v2_set_next_event;
+
+ clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
+ clockevent_mxc.shift);
+ clockevent_mxc.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_mxc);
+ clockevent_mxc.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_mxc);
+
+ clockevent_mxc.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clockevent_mxc);
+
+ return 0;
+}
+
+void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
+{
+ uint32_t tctl_val;
+ u32 reg;
+
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialise to a known state (all timers off, and timing reset)
+ */
+
+ __raw_writel(0, timer_base + MXC_TCTL);
+ __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
+
+ if (timer_is_v2()) {
+ if (cpu_is_mx5() || cpu_is_mx6sl() ||
+ mx6q_revision() == IMX_CHIP_REVISION_1_0)
+ tctl_val = V2_TCTL_CLK_PER | V2_TCTL_FRR |
+ V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ else {
+ tctl_val = V2_TCTL_CLK_OSC_DIV8 | V2_TCTL_FRR |
+ V2_TCTL_WAITEN | MXC_TCTL_TEN;
+ if (!cpu_is_mx6q()) {
+ reg = __raw_readl(timer_base + MXC_TPRER);
+ reg |= (V2_TPRER_PRE24M_DIV8 <<
+ V2_TPRER_PRE24M_OFFSET);
+ __raw_writel(reg, timer_base + MXC_TPRER);
+ /* Enable the 24MHz input clock. */
+ tctl_val |= V2_TCTL_ENABLE24M;
+ }
+ }
+ } else
+ tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
+
+ __raw_writel(tctl_val, timer_base + MXC_TCTL);
+
+ /* init and register the timer to the framework */
+ mxc_clocksource_init(timer_clk);
+ mxc_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxc_timer_irq);
+}
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
new file mode 100644
index 00000000..57f9395f
--- /dev/null
+++ b/arch/arm/plat-mxc/tzic.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C)2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include "irq-common.h"
+
+/*
+ *****************************************
+ * TZIC Registers *
+ *****************************************
+ */
+
+#define TZIC_INTCNTL 0x0000 /* Control register */
+#define TZIC_INTTYPE 0x0004 /* Controller Type register */
+#define TZIC_IMPID 0x0008 /* Distributor Implementer Identification */
+#define TZIC_PRIOMASK 0x000C /* Priority Mask Reg */
+#define TZIC_SYNCCTRL 0x0010 /* Synchronizer Control register */
+#define TZIC_DSMINT 0x0014 /* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0(i) (0x0080 + ((i) << 2)) /* Interrupt Security Reg 0 */
+#define TZIC_ENSET0(i) (0x0100 + ((i) << 2)) /* Enable Set Reg 0 */
+#define TZIC_ENCLEAR0(i) (0x0180 + ((i) << 2)) /* Enable Clear Reg 0 */
+#define TZIC_SRCSET0 0x0200 /* Source Set Register 0 */
+#define TZIC_SRCCLAR0 0x0280 /* Source Clear Register 0 */
+#define TZIC_PRIORITY0 0x0400 /* Priority Register 0 */
+#define TZIC_PND0 0x0D00 /* Pending Register 0 */
+#define TZIC_HIPND0 0x0D80 /* High Priority Pending Register */
+#define TZIC_WAKEUP0(i) (0x0E00 + ((i) << 2)) /* Wakeup Config Register */
+#define TZIC_SWINT 0x0F00 /* Software Interrupt Rigger Register */
+#define TZIC_ID0 0x0FD0 /* Indentification Register 0 */
+
+void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
+
+#ifdef CONFIG_FIQ
+static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
+{
+ unsigned int index, mask, value;
+
+ index = irq >> 5;
+ if (unlikely(index >= 4))
+ return -EINVAL;
+ mask = 1U << (irq & 0x1F);
+
+ value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask;
+ if (type)
+ value &= ~mask;
+ __raw_writel(value, tzic_base + TZIC_INTSEC0(index));
+
+ return 0;
+}
+#endif
+
+/**
+ * tzic_mask_irq() - Disable interrupt source "d" in the TZIC
+ *
+ * @param d interrupt source
+ */
+static void tzic_mask_irq(struct irq_data *d)
+{
+ int index, off;
+
+ index = d->irq >> 5;
+ off = d->irq & 0x1F;
+ __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0(index));
+}
+
+/**
+ * tzic_unmask_irq() - Enable interrupt source "d" in the TZIC
+ *
+ * @param d interrupt source
+ */
+static void tzic_unmask_irq(struct irq_data *d)
+{
+ int index, off;
+
+ index = d->irq >> 5;
+ off = d->irq & 0x1F;
+ __raw_writel(1 << off, tzic_base + TZIC_ENSET0(index));
+}
+
+static unsigned int wakeup_intr[4];
+
+/**
+ * tzic_set_wake_irq() - Set interrupt source "d" in the TZIC as a wake-up source.
+ *
+ * @param d interrupt source
+ * @param enable enable as wake-up if equal to non-zero
+ * disble as wake-up if equal to zero
+ *
+ * @return This function returns 0 on success.
+ */
+static int tzic_set_wake_irq(struct irq_data *d, unsigned int enable)
+{
+ unsigned int index, off;
+
+ index = d->irq >> 5;
+ off = d->irq & 0x1F;
+
+ if (index > 3)
+ return -EINVAL;
+
+ if (enable)
+ wakeup_intr[index] |= (1 << off);
+ else
+ wakeup_intr[index] &= ~(1 << off);
+
+ return 0;
+}
+
+static struct mxc_irq_chip mxc_tzic_chip = {
+ .base = {
+ .name = "MXC_TZIC",
+ .irq_ack = tzic_mask_irq,
+ .irq_mask = tzic_mask_irq,
+ .irq_unmask = tzic_unmask_irq,
+ .irq_set_wake = tzic_set_wake_irq,
+ },
+#ifdef CONFIG_FIQ
+ .set_irq_fiq = tzic_set_irq_fiq,
+#endif
+};
+
+/*
+ * This function initializes the TZIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init tzic_init_irq(void __iomem *irqbase)
+{
+ int i;
+
+ tzic_base = irqbase;
+ /* put the TZIC into the reset value with
+ * all interrupts disabled
+ */
+ i = __raw_readl(tzic_base + TZIC_INTCNTL);
+
+ __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
+ __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
+ __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
+
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i));
+
+ /* disable all interrupts */
+ for (i = 0; i < 4; i++)
+ __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i));
+
+ /* all IRQ no FIQ Warning :: No selection */
+
+ for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+ irq_set_chip_and_handler(i, &mxc_tzic_chip.base,
+ handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+#ifdef CONFIG_FIQ
+ /* Initialize FIQ */
+ init_FIQ();
+#endif
+
+ pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
+}
+
+/**
+ * tzic_enable_wake() - enable wakeup interrupt
+ *
+ * @param is_idle 1 if called in idle loop (ENSET0 register);
+ * 0 to be used when called from low power entry
+ * @return 0 if successful; non-zero otherwise
+ */
+int tzic_enable_wake(int is_idle)
+{
+ unsigned int i, v;
+
+ __raw_writel(1, tzic_base + TZIC_DSMINT);
+ if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
+ return -EAGAIN;
+
+ for (i = 0; i < 4; i++) {
+ v = is_idle ? __raw_readl(tzic_base + TZIC_ENSET0(i)) :
+ wakeup_intr[i];
+ __raw_writel(v, tzic_base + TZIC_WAKEUP0(i));
+ }
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/ulpi.c b/arch/arm/plat-mxc/ulpi.c
new file mode 100644
index 00000000..477e45be
--- /dev/null
+++ b/arch/arm/plat-mxc/ulpi.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+ * Copyright 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <mach/ulpi.h>
+
+/* ULPIVIEW register bits */
+#define ULPIVW_WU (1 << 31) /* Wakeup */
+#define ULPIVW_RUN (1 << 30) /* read/write run */
+#define ULPIVW_WRITE (1 << 29) /* 0 = read 1 = write */
+#define ULPIVW_SS (1 << 27) /* SyncState */
+#define ULPIVW_PORT_MASK 0x07 /* Port field */
+#define ULPIVW_PORT_SHIFT 24
+#define ULPIVW_ADDR_MASK 0xff /* data address field */
+#define ULPIVW_ADDR_SHIFT 16
+#define ULPIVW_RDATA_MASK 0xff /* read data field */
+#define ULPIVW_RDATA_SHIFT 8
+#define ULPIVW_WDATA_MASK 0xff /* write data field */
+#define ULPIVW_WDATA_SHIFT 0
+
+static int ulpi_poll(void __iomem *view, u32 bit)
+{
+ int timeout = 10000;
+
+ while (timeout--) {
+ u32 data = __raw_readl(view);
+
+ if (!(data & bit))
+ return 0;
+
+ cpu_relax();
+ };
+
+ printk(KERN_WARNING "timeout polling for ULPI device\n");
+
+ return -ETIMEDOUT;
+}
+
+static int ulpi_read(struct otg_transceiver *otg, u32 reg)
+{
+ int ret;
+ void __iomem *view = otg->io_priv;
+
+ /* make sure interface is running */
+ if (!(__raw_readl(view) & ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+
+ /* wait for wakeup */
+ ret = ulpi_poll(view, ULPIVW_WU);
+ if (ret)
+ return ret;
+ }
+
+ /* read the register */
+ __raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view);
+
+ /* wait for completion */
+ ret = ulpi_poll(view, ULPIVW_RUN);
+ if (ret)
+ return ret;
+
+ return (__raw_readl(view) >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
+}
+
+static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
+{
+ int ret;
+ void __iomem *view = otg->io_priv;
+
+ /* make sure the interface is running */
+ if (!(__raw_readl(view) & ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+ /* wait for wakeup */
+ ret = ulpi_poll(view, ULPIVW_WU);
+ if (ret)
+ return ret;
+ }
+
+ __raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
+ (reg << ULPIVW_ADDR_SHIFT) |
+ ((val & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)), view);
+
+ /* wait for completion */
+ return ulpi_poll(view, ULPIVW_RUN);
+}
+
+struct otg_io_access_ops mxc_ulpi_access_ops = {
+ .read = ulpi_read,
+ .write = ulpi_write,
+};
+EXPORT_SYMBOL_GPL(mxc_ulpi_access_ops);
+
+struct otg_transceiver *imx_otg_ulpi_create(unsigned int flags)
+{
+ return otg_ulpi_create(&mxc_ulpi_access_ops, flags);
+}
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
new file mode 100755
index 00000000..855e6722
--- /dev/null
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -0,0 +1,972 @@
+/*
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*!
+ *@defgroup USB ARC OTG USB Driver
+ */
+
+/*!
+ * @file usb_common.c
+ *
+ * @brief platform related part of usb driver.
+ * @ingroup USB
+ */
+
+/*!
+ *Include files
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/fsl_xcvr.h>
+#include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <asm/mach-types.h>
+#include <mach/arc_otg.h>
+#include <mach/hardware.h>
+#include <mach/mxc.h>
+typedef void (*driver_vbus_func)(bool);
+
+void __iomem *imx_otg_base;
+static driver_vbus_func s_h1_driver_vbus;
+static driver_vbus_func s_otg_driver_vbus;
+
+EXPORT_SYMBOL(imx_otg_base);
+
+#define MXC_NUMBER_USB_TRANSCEIVER 6
+struct fsl_xcvr_ops *g_xc_ops[MXC_NUMBER_USB_TRANSCEIVER] = { NULL };
+
+bool usb_icbug_swfix_need(void)
+{
+ if (cpu_is_mx6sl())
+ return false;
+ else if ((mx6q_revision() > IMX_CHIP_REVISION_1_1))
+ return false;
+ else if ((mx6dl_revision() > IMX_CHIP_REVISION_1_0))
+ return false;
+ return true;
+}
+EXPORT_SYMBOL(usb_icbug_swfix_need);
+
+void mx6_set_host1_vbus_func(driver_vbus_func driver_vbus)
+{
+ s_h1_driver_vbus = driver_vbus;
+}
+
+void mx6_get_host1_vbus_func(driver_vbus_func *driver_vbus)
+{
+ *driver_vbus = s_h1_driver_vbus;
+}
+EXPORT_SYMBOL(mx6_get_host1_vbus_func);
+
+void mx6_set_otghost_vbus_func(driver_vbus_func driver_vbus)
+{
+ s_otg_driver_vbus = driver_vbus;
+}
+
+void mx6_get_otghost_vbus_func(driver_vbus_func *driver_vbus)
+{
+ *driver_vbus = s_otg_driver_vbus;
+}
+EXPORT_SYMBOL(mx6_get_otghost_vbus_func);
+
+
+enum fsl_usb2_modes get_usb_mode(struct fsl_usb2_platform_data *pdata)
+{
+ enum fsl_usb2_modes mode;
+ mode = FSL_USB_UNKNOWN;
+
+ if (!strcmp("DR", pdata->name)) {
+ if ((UOG_USBMODE & 0x3) == 0x2)
+ mode = FSL_USB_DR_DEVICE;
+ else if ((UOG_USBMODE & 0x3) == 0x3)
+ mode = FSL_USB_DR_HOST;
+ } else if (!strcmp("Host 1", pdata->name))
+ mode = FSL_USB_MPH_HOST1;
+ else if (!strcmp("Host 2", pdata->name))
+ mode = FSL_USB_MPH_HOST2;
+
+ if (mode == FSL_USB_UNKNOWN)
+ printk(KERN_ERR "unknow usb mode,name is %s\n", pdata->name);
+ return mode;
+}
+
+static struct clk *usb_clk;
+static struct clk *usb_ahb_clk;
+
+
+/*
+ * make sure USB_CLK is running at 60 MHz +/- 1000 Hz
+ */
+static int fsl_check_usbclk(void)
+{
+ unsigned long freq;
+
+ usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
+ if (clk_enable(usb_ahb_clk)) {
+ if (cpu_is_mx6())
+ return 0; /* there is no ahb clock at mx6 */
+ printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n");
+ return -EINVAL;
+ }
+ clk_put(usb_ahb_clk);
+
+ usb_clk = clk_get(NULL, "usb_clk");
+ if (clk_enable(usb_clk)) {
+ if (cpu_is_mx6())
+ return 0; /* there is usb_clk at mx6 */
+ printk(KERN_ERR "clk_enable(usb_clk) failed\n");
+ return -EINVAL;
+ }
+ freq = clk_get_rate(usb_clk);
+ clk_put(usb_clk);
+ if ((freq < 59999000) || (freq > 60001000)) {
+ printk(KERN_ERR "USB_CLK=%lu, should be 60MHz\n", freq);
+ return -1;
+ }
+
+ return 0;
+}
+
+void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (g_xc_ops[i] == NULL) {
+ g_xc_ops[i] = xcvr_ops;
+ return;
+ }
+ }
+
+ pr_debug("Failed %s\n", __func__);
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_register);
+
+void fsl_platform_set_test_mode (struct fsl_usb2_platform_data *pdata, enum usb_test_mode mode)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_test_mode)
+ pdata->xcvr_ops->set_test_mode((u32 *)(pdata->regs + ULPIVW_OFF), mode);
+}
+EXPORT_SYMBOL(fsl_platform_set_test_mode);
+
+void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (g_xc_ops[i] && (g_xc_ops[i] == xcvr_ops)) {
+ g_xc_ops[i] = NULL;
+ return;
+ }
+ }
+
+ pr_debug("Failed %s\n", __func__);
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_unregister);
+
+static struct fsl_xcvr_ops *fsl_usb_get_xcvr(char *name)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ if (name == NULL) {
+ printk(KERN_ERR "get_xcvr(): No tranceiver name\n");
+ return NULL;
+ }
+
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (g_xc_ops[i] && (strcmp(g_xc_ops[i]->name, name) == 0)) {
+ return g_xc_ops[i];
+ }
+ }
+ pr_debug("Failed %s\n", __func__);
+ return NULL;
+}
+
+/* The dmamask must be set for EHCI to work */
+static u64 ehci_dmamask = ~(u32) 0;
+
+/*!
+ * Register an instance of a USB host platform device.
+ *
+ * @param res: resource pointer
+ * @param n_res: number of resources
+ * @param config: config pointer
+ *
+ * @return newly-registered platform_device
+ *
+ * The USB controller supports 3 host interfaces, and the
+ * kernel can be configured to support some number of them.
+ * Each supported host interface is registered as an instance
+ * of the "fsl-ehci" device. Call this function multiple times
+ * to register each host interface.
+ */
+static int usb_mxc_instance_id;
+__init struct platform_device *host_pdev_register(struct resource *res, int n_res,
+ struct fsl_usb2_platform_data *config)
+{
+ struct platform_device *pdev;
+ int rc;
+
+ pr_debug("register host res=0x%p, size=%d\n", res, n_res);
+
+ pdev = platform_device_register_simple("fsl-ehci",
+ usb_mxc_instance_id, res, n_res);
+ if (IS_ERR(pdev)) {
+ pr_debug("can't register %s Host, %ld\n",
+ config->name, PTR_ERR(pdev));
+ return NULL;
+ }
+
+ pdev->dev.coherent_dma_mask = 0xffffffff;
+ pdev->dev.dma_mask = &ehci_dmamask;
+
+ /*
+ * platform_device_add_data() makes a copy of
+ * the platform_data passed in. That makes it
+ * impossible to share the same config struct for
+ * all OTG devices (host,gadget,otg). So, just
+ * set the platorm_data pointer ourselves.
+ */
+ rc = platform_device_add_data(pdev, config,
+ sizeof(struct fsl_usb2_platform_data));
+ if (rc) {
+ platform_device_unregister(pdev);
+ return NULL;
+ }
+
+ printk(KERN_INFO "usb: %s host (%s) registered\n", config->name,
+ config->transceiver);
+ pr_debug("pdev=0x%p dev=0x%p resources=0x%p pdata=0x%p\n",
+ pdev, &pdev->dev, pdev->resource, pdev->dev.platform_data);
+
+ usb_mxc_instance_id++;
+
+ return pdev;
+}
+
+static void usbh1_set_serial_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+ USBCTRL &= ~(UCTRL_H1SIC_MASK | UCTRL_BPE); /* disable bypass mode */
+ USBCTRL |= UCTRL_H1SIC_SU6 | /* single-ended / unidir. */
+ UCTRL_H1WIE | UCTRL_H1DT | /* disable H1 TLL */
+ UCTRL_H1PM; /* power mask */
+}
+
+static void usbh1_set_ulpi_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while (UH1_USBCMD & UCMD_RESET)
+ ;
+
+ /* Select the clock from external PHY */
+ USB_CTRL_1 |= USB_CTRL_UH1_EXT_CLK_EN;
+
+ /* select ULPI PHY PTS=2 */
+ UH1_PORTSC1 = (UH1_PORTSC1 & ~PORTSC_PTS_MASK) | PORTSC_PTS_ULPI;
+
+ USBCTRL &= ~UCTRL_H1WIE; /* HOST1 wakeup intr disable */
+ USBCTRL &= ~UCTRL_H1UIE; /* Host1 ULPI interrupt disable */
+ USBCTRL |= UCTRL_H1PM; /* HOST1 power mask */
+ USB_PHY_CTR_FUNC |= USB_UH1_OC_DIS; /* OC is not used */
+
+ /* Interrupt Threshold Control:Immediate (no threshold) */
+ UH1_USBCMD &= UCMD_ITC_NO_THRESHOLD;
+
+ UH1_USBCMD |= UCMD_RESET; /* reset the controller */
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+
+static void usbh1_set_utmi_xcvr(void)
+{
+ u32 tmp;
+
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while ((UH1_USBCMD) & (UCMD_RESET))
+ ;
+
+ /* For OC and PWR, it is board level setting
+ * The default setting is for mx53 evk
+ */
+ USBCTRL &= ~UCTRL_H1PM; /* Host1 Power Mask */
+ USBCTRL &= ~UCTRL_H1WIE; /* Host1 Wakeup Intr Disable */
+ USB_PHY_CTR_FUNC |= USB_UH1_OC_DIS; /* Over current disable */
+
+ if (cpu_is_mx50()) {
+ USBCTRL |= UCTRL_H1PM; /* Host1 Power Mask */
+ USB_PHY_CTR_FUNC &= ~USB_UH1_OC_DIS; /* Over current enable */
+ /* Over current polarity low active */
+ USB_PHY_CTR_FUNC |= USB_UH1_OC_POL;
+ }
+ /* set UTMI xcvr */
+ tmp = UH1_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_UTMI;
+ UH1_PORTSC1 = tmp;
+
+ /* Set the PHY clock to 24MHz */
+ USBH1_PHY_CTRL1 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
+ USBH1_PHY_CTRL1 |= 0x01;
+
+ /* Workaround an IC issue for ehci driver:
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTW with 0
+ * means 8 bits tranceiver width, here change
+ * it back to be 16 bits and do PHY diable and
+ * then enable.
+ */
+ UH1_PORTSC1 |= PORTSC_PTW;
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while ((UH1_USBCMD) & (UCMD_RESET))
+ ;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for UTMI tranceivers */
+ clk_disable(usb_clk);
+}
+
+static void usbh2_set_ulpi_xcvr(void)
+{
+ u32 tmp;
+
+ pr_debug("%s\n", __func__);
+
+ UH2_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH2_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH2_USBCMD |= UCMD_RESET;
+ while (UH2_USBCMD & UCMD_RESET)
+
+ USBCTRL_HOST2 &= ~(UCTRL_H2SIC_MASK | UCTRL_BPE);
+ USBCTRL_HOST2 &= ~UCTRL_H2WIE; /* wakeup intr enable */
+ USBCTRL_HOST2 &= ~UCTRL_H2UIE; /* ULPI intr enable */
+ USB_CTRL_1 |= USB_CTRL_UH2_EXT_CLK_EN;
+ if (cpu_is_mx53())
+ USB_CTRL_1 |= USB_CTRL_UH2_CLK_FROM_ULPI_PHY;
+ if (cpu_is_mx51())/* not tested */
+ USBCTRL_HOST2 |= (1 << 12);
+ /* must set ULPI phy before turning off clock */
+ tmp = UH2_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_ULPI;
+ UH2_PORTSC1 = tmp;
+ if (cpu_is_mx53()) {
+ /* turn off the internal 60MHZ clk */
+ USB_CLKONOFF_CTRL |= (1 << 21);
+ }
+ UH2_USBCMD |= UCMD_RESET; /* reset the controller */
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+
+static void usbh2_set_serial_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* Stop then Reset */
+ UH2_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH2_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UH2_USBCMD |= UCMD_RESET;
+ while (UH2_USBCMD & UCMD_RESET)
+ ;
+
+ USBCTRL &= ~(UCTRL_H2SIC_MASK); /* Disable bypass mode */
+ USBCTRL &= ~(UCTRL_H2PM); /* Power Mask */
+ USBCTRL &= ~UCTRL_H2OCPOL; /* OverCurrent Polarity is Low Active */
+ USBCTRL &= ~UCTRL_H2WIE; /* Wakeup intr disable */
+ USBCTRL |= UCTRL_IP_PUE_DOWN | /* ipp_pue_pulldwn_dpdm */
+ UCTRL_USBTE | /* USBT is enabled */
+ UCTRL_H2DT; /* Disable H2 TLL */
+
+ if (cpu_is_mx25()) {
+ /*
+ * USBH2_PWR and USBH2_OC are active high.
+ * Must force xcvr clock to "internal" so that
+ * we can write to PTS field after it's been
+ * cleared by ehci_turn_off_all_ports().
+ */
+ USBCTRL |= UCTRL_H2PP | UCTRL_H2OCPOL | UCTRL_XCSH2;
+ /* Disable Host2 bus Lock */
+ USBCTRL |= UCTRL_H2LOCKD;
+ }
+
+ USBCTRL &= ~(UCTRL_PP);
+ UH2_PORTSC1 = (UH2_PORTSC1 & (~PORTSC_PTS_MASK)) | PORTSC_PTS_SERIAL;
+
+ if (UH2_HCSPARAMS & HCSPARAMS_PPC)
+ UH2_PORTSC1 |= PORTSC_PORT_POWER;
+
+ /* Reset controller before set host mode */
+ UH2_USBCMD |= UCMD_RESET;
+ while (UH2_USBCMD & UCMD_RESET)
+ ;
+
+ msleep(100);
+}
+
+/*!
+ * Register remote wakeup by this usb controller
+ *
+ * @param pdev: platform_device for this usb controller
+ *
+ * @return 0 or negative error code in case not supportted.
+ */
+static int usb_register_remote_wakeup(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct resource *res;
+ int irq;
+
+ pr_debug("%s: pdev=0x%p \n", __func__, pdev);
+ if (!(pdata->wake_up_enable))
+ return -ECANCELED;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev,
+ "Found HC with no IRQ. Check %s setup!\n",
+ dev_name(&pdev->dev));
+ return -ENODEV;
+ }
+ irq = res->start;
+ device_set_wakeup_capable(&pdev->dev, true);
+ enable_irq_wake(irq);
+
+ return 0;
+}
+
+int fsl_usb_host_init(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_xcvr_ops *xops;
+
+ pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata);
+
+ xops = fsl_usb_get_xcvr(pdata->transceiver);
+ if (!xops) {
+ printk(KERN_ERR "%s transceiver ops missing\n", pdata->name);
+ return -EINVAL;
+ }
+ pdata->xcvr_ops = xops;
+ pdata->xcvr_type = xops->xcvr_type;
+ pdata->pdev = pdev;
+
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+
+ pr_debug("%s: grab pins\n", __func__);
+ if (pdata->gpio_usb_active && pdata->gpio_usb_active())
+ return -EINVAL;
+
+ if (cpu_is_mx50())
+ /* Turn on AHB CLK for H1*/
+ USB_CLKONOFF_CTRL &= ~H1_AHBCLK_OFF;
+
+ /* enable board power supply for xcvr */
+ if (pdata->xcvr_pwr) {
+ if (pdata->xcvr_pwr->regu1)
+ regulator_enable(pdata->xcvr_pwr->regu1);
+ if (pdata->xcvr_pwr->regu2)
+ regulator_enable(pdata->xcvr_pwr->regu2);
+ }
+
+ if (xops->init)
+ xops->init(xops);
+
+ if (usb_register_remote_wakeup(pdev))
+ pr_debug("%s port is not a wakeup source.\n", pdata->name);
+ if (!(cpu_is_mx6())) {
+ if (xops->xcvr_type == PORTSC_PTS_SERIAL) {
+ if (cpu_is_mx35()) {
+ usbh2_set_serial_xcvr();
+ /* Close the internal 60Mhz */
+ USBCTRL &= ~UCTRL_XCSH2;
+ } else if (cpu_is_mx25())
+ usbh2_set_serial_xcvr();
+ else
+ usbh1_set_serial_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_ULPI) {
+ if (!strcmp("Host 1", pdata->name))
+ usbh1_set_ulpi_xcvr();
+ if (!strcmp("Host 2", pdata->name))
+ usbh2_set_ulpi_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_UTMI) {
+ usbh1_set_utmi_xcvr();
+ }
+ } else {
+#ifdef CONFIG_ARCH_MX6
+ if (!strcmp("Host 1", pdata->name)) {
+ if (machine_is_mx6q_arm2())
+ USB_H1_CTRL &= ~UCTRL_OVER_CUR_POL;
+ else if (machine_is_mx6q_sabrelite())
+ USB_H1_CTRL |= UCTRL_OVER_CUR_POL;
+ USB_H1_CTRL |= UCTRL_OVER_CUR_DIS;
+ }
+#endif
+ }
+
+ pr_debug("%s: %s success\n", __func__, pdata->name);
+ return 0;
+}
+EXPORT_SYMBOL(fsl_usb_host_init);
+
+void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata)
+{
+ pr_debug("%s\n", __func__);
+
+ if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
+ pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+
+ pdata->regs = NULL;
+
+ if (pdata->gpio_usb_inactive)
+ pdata->gpio_usb_inactive();
+ if (pdata->xcvr_type == PORTSC_PTS_SERIAL) {
+ /* Workaround an IC issue for ehci driver.
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTS with 0
+ * means UTMI interface, so here force the Host2
+ * port use the internal 60Mhz.
+ */
+ if (cpu_is_mx35())
+ USBCTRL |= UCTRL_XCSH2;
+ clk_disable(usb_clk);
+ }
+
+ /* disable board power supply for xcvr */
+ if (pdata->xcvr_pwr) {
+ if (pdata->xcvr_pwr->regu1)
+ regulator_disable(pdata->xcvr_pwr->regu1);
+ if (pdata->xcvr_pwr->regu2)
+ regulator_disable(pdata->xcvr_pwr->regu2);
+ }
+
+ clk_disable(usb_ahb_clk);
+}
+EXPORT_SYMBOL(fsl_usb_host_uninit);
+
+static void otg_set_serial_xcvr(void)
+{
+ pr_debug("%s\n", __func__);
+}
+
+void otg_set_serial_host(void)
+{
+ pr_debug("%s\n", __func__);
+ /* set USBCTRL for host operation
+ * disable: bypass mode,
+ * set: single-ended/unidir/6 wire, OTG wakeup intr enable,
+ * power mask
+ */
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+
+#if defined(CONFIG_MXC_USB_SB3)
+ USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_SU6)
+ USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_DB4)
+ USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM;
+#else
+ USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM;
+#endif
+
+ USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_ASESVLD; /* 0xa */
+}
+EXPORT_SYMBOL(otg_set_serial_host);
+
+void otg_set_serial_peripheral(void)
+{
+ /* set USBCTRL for device operation
+ * disable: bypass mode
+ * set: differential/unidir/6 wire, OTG wakeup intr enable,
+ * power mask
+ */
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+
+#if defined(CONFIG_MXC_USB_SB3)
+ USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_SU6)
+ USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_DB4)
+ USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM;
+#else
+ USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM;
+#endif
+
+ USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_BSESVLD | OTGM_IDIDG; /* oxd */
+}
+EXPORT_SYMBOL(otg_set_serial_peripheral);
+
+static void otg_set_ulpi_xcvr(void)
+{
+ u32 tmp;
+
+ pr_debug("%s\n", __func__);
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+ USBCTRL |= UCTRL_OUIE | /* ULPI intr enable */
+ UCTRL_OWIE | /* OTG wakeup intr enable */
+ UCTRL_OPM; /* power mask */
+
+ /* must set ULPI phy before turning off clock */
+ tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_ULPI;
+ UOG_PORTSC1 = tmp;
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ UOG_USBCMD |= UCMD_RESET;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+
+int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops)
+{
+ if (!machine_is_mx31_3ds())
+ return -ECANCELED;
+
+ if (xcvr_ops->xcvr_type == PORTSC_PTS_ULPI) {
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+ clk_enable(usb_clk);
+
+ otg_set_ulpi_xcvr();
+
+ if (xcvr_ops->suspend)
+ /* suspend transceiver */
+ xcvr_ops->suspend(xcvr_ops);
+
+ clk_disable(usb_clk);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_suspend);
+
+static void otg_set_utmi_xcvr(void)
+{
+ u32 tmp;
+
+ /* Stop then Reset */
+ UOG_USBCMD &= ~UCMD_RUN_STOP;
+ while (UOG_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UOG_USBCMD |= UCMD_RESET;
+ while ((UOG_USBCMD) & (UCMD_RESET))
+ ;
+
+ if (cpu_is_mx53())
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS;
+
+ if (cpu_is_mx51()) {
+ if (machine_is_mx51_3ds()) {
+ /* OTG Polarity of Overcurrent is Low active */
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_POL;
+ /* Enable OTG Overcurrent Event */
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_OC_DIS;
+ } else {
+ /* BBG is not using OC */
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS;
+ }
+ } else if (cpu_is_mx25()) {
+ USBCTRL |= UCTRL_OCPOL;
+ USBCTRL &= ~UCTRL_PP;
+ } else if (cpu_is_mx50()) {
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS;
+ } else {
+ /* USBOTG_PWR low active */
+ USBCTRL &= ~UCTRL_PP;
+ /* OverCurrent Polarity is Low Active */
+ USBCTRL &= ~UCTRL_OCPOL;
+
+ if (cpu_is_mx35() && (imx_cpu_ver() < IMX_CHIP_REVISION_2_0))
+ /* OTG Lock Disable */
+ USBCTRL |= UCTRL_OLOCKD;
+ }
+
+ if (cpu_is_mx51())
+ USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */
+
+ USBCTRL &= ~UCTRL_OWIE; /* OTG Wakeup Intr Disable */
+
+ /* set UTMI xcvr */
+ tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_UTMI;
+ UOG_PORTSC1 = tmp;
+
+ if (cpu_is_mx51()) {
+ /* Set the PHY clock to 19.2MHz */
+ USB_PHY_CTR_FUNC2 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
+ USB_PHY_CTR_FUNC2 |= 0x01;
+ }
+
+ /* Workaround an IC issue for ehci driver:
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTW with 0
+ * means 8 bits tranceiver width, here change
+ * it back to be 16 bits and do PHY diable and
+ * then enable.
+ */
+ UOG_PORTSC1 |= PORTSC_PTW;
+
+ if (cpu_is_mx35() || cpu_is_mx25()) {
+ /* Enable UTMI interface in PHY control Reg */
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_UTMI_ENABLE;
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_UTMI_ENABLE;
+ }
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ /* Stop then Reset */
+ UOG_USBCMD &= ~UCMD_RUN_STOP;
+ while (UOG_USBCMD & UCMD_RUN_STOP)
+ ;
+
+ UOG_USBCMD |= UCMD_RESET;
+ while ((UOG_USBCMD) & (UCMD_RESET))
+ ;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ if (cpu_is_mx37()) {
+ /* fix USB PHY Power Gating leakage issue for i.MX37 */
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CHGRDETON;
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CHGRDETEN;
+ }
+
+ /* Turn off the usbpll for UTMI tranceivers */
+ clk_disable(usb_clk);
+}
+
+static int mxc_otg_used;
+
+int usbotg_init(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_xcvr_ops *xops;
+
+ pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata);
+
+ xops = fsl_usb_get_xcvr(pdata->transceiver);
+ if (!xops) {
+ printk(KERN_ERR "DR transceiver ops missing\n");
+ return -EINVAL;
+ }
+ pdata->xcvr_ops = xops;
+ pdata->xcvr_type = xops->xcvr_type;
+ pdata->pdev = pdev;
+
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+ if (!mxc_otg_used) {
+ if (cpu_is_mx50())
+ /* Turn on AHB CLK for OTG*/
+ USB_CLKONOFF_CTRL &= ~OTG_AHBCLK_OFF;
+
+ pr_debug("%s: grab pins\n", __func__);
+ if (pdata->gpio_usb_active && pdata->gpio_usb_active())
+ return -EINVAL;
+ if (xops->init)
+ xops->init(xops);
+ if (!(cpu_is_mx6())) {
+ UOG_PORTSC1 = UOG_PORTSC1 & ~PORTSC_PHCD;
+
+
+ if (xops->xcvr_type == PORTSC_PTS_SERIAL) {
+ if (pdata->operating_mode == FSL_USB2_DR_HOST) {
+ otg_set_serial_host();
+ /* need reset */
+ UOG_USBCMD |= UCMD_RESET;
+ msleep(100);
+ } else if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
+ otg_set_serial_peripheral();
+ otg_set_serial_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_ULPI) {
+ otg_set_ulpi_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_UTMI) {
+ otg_set_utmi_xcvr();
+ }
+ } else {
+#ifdef CONFIG_ARCH_MX6
+ if (machine_is_mx6q_arm2())
+ USB_OTG_CTRL &= ~UCTRL_OVER_CUR_POL;
+ else if (machine_is_mx6q_sabrelite())
+ USB_OTG_CTRL |= UCTRL_OVER_CUR_POL;
+ USB_OTG_CTRL |= UCTRL_OVER_CUR_DIS;
+#endif
+ }
+ }
+
+ if (usb_register_remote_wakeup(pdev))
+ pr_debug("DR is not a wakeup source.\n");
+
+ mxc_otg_used++;
+ pr_debug("%s: success\n", __func__);
+ return 0;
+}
+EXPORT_SYMBOL(usbotg_init);
+
+void usbotg_uninit(struct fsl_usb2_platform_data *pdata)
+{
+ pr_debug("%s\n", __func__);
+
+ mxc_otg_used--;
+ if (!mxc_otg_used) {
+ if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
+ pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+
+ pdata->regs = NULL;
+
+ if (machine_is_mx31_3ds()) {
+ if (pdata->xcvr_ops && pdata->xcvr_ops->suspend)
+ pdata->xcvr_ops->suspend(pdata->xcvr_ops);
+ clk_disable(usb_clk);
+ }
+ msleep(1);
+ UOG_PORTSC1 = UOG_PORTSC1 | PORTSC_PHCD;
+ if (pdata->gpio_usb_inactive)
+ pdata->gpio_usb_inactive();
+ if (pdata->xcvr_type == PORTSC_PTS_SERIAL)
+ clk_disable(usb_clk);
+ clk_disable(usb_ahb_clk);
+ }
+}
+EXPORT_SYMBOL(usbotg_uninit);
+
+/*
+ * This function is used to debounce the reading value for id/vbus at
+ * the register of otgsc
+ */
+void usb_debounce_id_vbus(void)
+{
+ msleep(3);
+}
+EXPORT_SYMBOL(usb_debounce_id_vbus);
+
+int usb_event_is_otg_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ return (USBCTRL & UCTRL_OWIR) ? true : false;
+}
+EXPORT_SYMBOL(usb_event_is_otg_wakeup);
+
+#ifdef CONFIG_ARCH_MX6
+/* enable/disable high-speed disconnect detector of phy ctrl */
+void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata,
+ bool enable)
+{
+ u32 usb_phy_ctrl_dcdt = 0;
+ /* for HSIC, we do not need to enable disconnect detection */
+ if (pdata->phy_mode == FSL_USB2_PHY_HSIC)
+ return;
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
+}
+EXPORT_SYMBOL(fsl_platform_set_usb_phy_dis);
+#endif
+
+void usb_host_set_wakeup(struct device *wkup_dev, bool para)
+{
+ struct fsl_usb2_platform_data *pdata = wkup_dev->platform_data;
+ if (pdata->wake_up_enable)
+ pdata->wake_up_enable(pdata, para);
+}
+EXPORT_SYMBOL(usb_host_set_wakeup);
diff --git a/arch/arm/plat-mxc/usb_hsic_xcvr.c b/arch/arm/plat-mxc/usb_hsic_xcvr.c
new file mode 100644
index 00000000..9dbbdc46
--- /dev/null
+++ b/arch/arm/plat-mxc/usb_hsic_xcvr.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ * For HSIC, there is no usb phy, so the operation at this file is noop
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/pmic_external.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+
+static struct fsl_xcvr_ops hsic_xcvr_ops = {
+ .name = "hsic_xcvr",
+ .xcvr_type = PORTSC_HSIC_MODE,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init hsic_xcvr_init(void)
+{
+ fsl_usb_xcvr_register(&hsic_xcvr_ops);
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit hsic_xcvr_exit(void)
+{
+ fsl_usb_xcvr_unregister(&hsic_xcvr_ops);
+}
+
+subsys_initcall(hsic_xcvr_init);
+module_exit(hsic_xcvr_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("nop xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/usb_wakeup.c b/arch/arm/plat-mxc/usb_wakeup.c
new file mode 100755
index 00000000..c0fc70ec
--- /dev/null
+++ b/arch/arm/plat-mxc/usb_wakeup.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/fsl_devices.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/arc_otg.h>
+
+struct wakeup_ctrl {
+ int wakeup_irq;
+ int usb_irq;
+ bool thread_close;
+ struct fsl_usb2_wakeup_platform_data *pdata;
+ struct task_struct *thread;
+ struct completion event;
+};
+
+extern int usb_event_is_otg_wakeup(struct fsl_usb2_platform_data *pdata);
+extern void usb_debounce_id_vbus(void);
+
+static void wakeup_clk_gate(struct fsl_usb2_wakeup_platform_data *pdata, bool on)
+{
+ if (pdata->usb_clock_for_pm)
+ pdata->usb_clock_for_pm(on);
+}
+static bool phy_in_lowpower_mode(struct fsl_usb2_platform_data *pdata)
+{
+ unsigned long flags;
+ bool ret = true;
+
+ spin_lock_irqsave(&pdata->lock, flags);
+
+ if (!pdata->lowpower)
+ ret = false;
+
+ spin_unlock_irqrestore(&pdata->lock, flags);
+
+ return ret;
+}
+
+static bool usb2_is_in_lowpower(struct wakeup_ctrl *ctrl)
+{
+ int i;
+ struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;
+ /* all the usb module related the wakeup is in lowpower mode */
+ for (i = 0; i < 3; i++) {
+ if (pdata->usb_pdata[i] && pdata->usb_pdata[i]->phy_lowpower_suspend) {
+ if (!phy_in_lowpower_mode(pdata->usb_pdata[i]))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void delay_process_wakeup(struct wakeup_ctrl *ctrl)
+{
+ int i;
+ struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;
+ disable_irq_nosync(ctrl->wakeup_irq);
+ if ((ctrl->usb_irq > 0) && (ctrl->wakeup_irq != ctrl->usb_irq))
+ disable_irq_nosync(ctrl->usb_irq);
+
+ for (i = 0; i < 3; i++) {
+ if (pdata->usb_pdata[i]) {
+ pdata->usb_pdata[i]->irq_delay = 1;
+ }
+ }
+
+ pdata->usb_wakeup_is_pending = true;
+ complete(&ctrl->event);
+}
+
+static irqreturn_t usb_wakeup_handler(int irq, void *_dev)
+{
+ struct wakeup_ctrl *ctrl = (struct wakeup_ctrl *)_dev;
+ irqreturn_t ret = IRQ_NONE;
+ if (usb2_is_in_lowpower(ctrl)) {
+ pr_debug("usb wakeup is here\n");
+ delay_process_wakeup(ctrl);
+ ret = IRQ_HANDLED;
+ }
+ return ret;
+}
+
+static enum usb_wakeup_event is_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->is_wakeup_event)
+ return pdata->is_wakeup_event(pdata);
+ else
+ return WAKEUP_EVENT_INVALID;
+}
+
+static void wakeup_event_handler(struct wakeup_ctrl *ctrl)
+{
+ struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;
+ int already_waked = 0;
+ enum usb_wakeup_event wakeup_evt;
+ int i;
+
+ wakeup_clk_gate(ctrl->pdata, true);
+
+ for (i = 0; i < 3; i++) {
+ struct fsl_usb2_platform_data *usb_pdata = pdata->usb_pdata[i];
+ if (usb_pdata) {
+ /* In order to get the real id/vbus value */
+ if (usb_event_is_otg_wakeup(usb_pdata))
+ usb_debounce_id_vbus();
+
+ usb_pdata->irq_delay = 0;
+ wakeup_evt = is_wakeup(usb_pdata);
+ usb_pdata->wakeup_event = wakeup_evt;
+ if (wakeup_evt != WAKEUP_EVENT_INVALID) {
+ if (usb2_is_in_lowpower(ctrl))
+ if (usb_pdata->usb_clock_for_pm)
+ usb_pdata->usb_clock_for_pm(true);
+ usb_pdata->lowpower = 0;
+ already_waked = 1;
+ if (usb_pdata->wakeup_handler) {
+ usb_pdata->wakeup_handler(usb_pdata);
+ }
+ }
+ }
+ }
+
+ /* If nothing to wakeup, clear wakeup event */
+ if ((already_waked == 0) && pdata->usb_wakeup_exhandle) {
+#if 1
+ struct fsl_usb2_wakeup_platform_data *pdata = ctrl->pdata;
+ /* all the usb module related the wakeup is in lowpower mode */
+ for (i = 0; i < 3; i++) {
+ if (pdata->usb_pdata[i] && pdata->usb_pdata[i]->phy_lowpower_suspend) {
+ printk(KERN_EMERG "usb_phy[%d] lowpower_mode = %d\n",
+ i, phy_in_lowpower_mode(pdata->usb_pdata[i]));
+ }
+ }
+#endif
+ pdata->usb_wakeup_exhandle();
+ }
+
+ wakeup_clk_gate(ctrl->pdata, false);
+ pdata->usb_wakeup_is_pending = false;
+ wake_up(&pdata->wq);
+}
+
+static int wakeup_event_thread(void *param)
+{
+ struct wakeup_ctrl *ctrl = (struct wakeup_ctrl *)param;
+ struct sched_param sch_param = {.sched_priority = 1};
+ u32 timeout = 0;
+
+ sched_setscheduler(current, SCHED_RR, &sch_param);
+ while (1) {
+ wait_for_completion_interruptible(&ctrl->event);
+ if (ctrl->thread_close) {
+ while (!kthread_should_stop() && (timeout < 1000)) {
+ timeout++;
+ msleep(1);
+ }
+ break;
+ }
+ wakeup_event_handler(ctrl);
+ enable_irq(ctrl->wakeup_irq);
+ if ((ctrl->usb_irq > 0) && (ctrl->wakeup_irq != ctrl->usb_irq))
+ enable_irq(ctrl->usb_irq);
+ }
+ return 0;
+}
+
+static int wakeup_dev_probe(struct platform_device *pdev)
+{
+ struct fsl_usb2_wakeup_platform_data *pdata;
+ struct wakeup_ctrl *ctrl = NULL;
+ int status;
+ unsigned long interrupt_flag;
+
+ printk(KERN_INFO "IMX usb wakeup probe\n");
+
+ if (!pdev || !pdev->dev.platform_data)
+ return -ENODEV;
+ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+ if (!ctrl)
+ return -ENOMEM;
+ pdata = pdev->dev.platform_data;
+ ctrl->pdata = pdata;
+ init_waitqueue_head(&pdata->wq);
+ pdata->usb_wakeup_is_pending = false;
+
+ init_completion(&ctrl->event);
+ /* Currently, both mx5x and mx6q uses usb controller's irq
+ * as wakeup irq.
+ */
+ ctrl->wakeup_irq = platform_get_irq(pdev, 1);
+ ctrl->usb_irq = platform_get_irq(pdev, 1);
+ pdata->wakeup_irq = ctrl->wakeup_irq;
+ pdata->usb_irq = ctrl->usb_irq;
+ ctrl->thread_close = false;
+ if (ctrl->wakeup_irq != ctrl->usb_irq)
+ interrupt_flag = IRQF_DISABLED;
+ else
+ interrupt_flag = IRQF_SHARED;
+ status = request_irq(ctrl->wakeup_irq, usb_wakeup_handler, interrupt_flag, "usb_wakeup", (void *)ctrl);
+ if (status)
+ goto error1;
+
+ ctrl->thread = kthread_run(wakeup_event_thread, (void *)ctrl, "usb_wakeup thread");
+ status = IS_ERR(ctrl->thread) ? -1 : 0;
+ if (status)
+ goto error2;
+ platform_set_drvdata(pdev, ctrl);
+
+ printk(KERN_DEBUG "the wakeup pdata is 0x%p\n", pdata);
+ return 0;
+error2:
+ free_irq(ctrl->wakeup_irq, (void *)ctrl);
+error1:
+ kfree(ctrl);
+ return status;
+}
+
+static int wakeup_dev_exit(struct platform_device *pdev)
+{
+ struct wakeup_ctrl *wctrl = platform_get_drvdata(pdev);
+
+ wctrl->thread_close = true;
+ complete(&wctrl->event);
+ kthread_stop(wctrl->thread);
+ free_irq(wctrl->wakeup_irq, (void *)wctrl);
+ kfree(wctrl);
+
+ return 0;
+}
+static struct platform_driver wakeup_d = {
+ .probe = wakeup_dev_probe,
+ .remove = wakeup_dev_exit,
+ .driver = {
+ .name = "usb-wakeup",
+ },
+};
+
+static int __init wakeup_dev_init(void)
+{
+ return platform_driver_register(&wakeup_d);
+}
+static void __exit wakeup_dev_uninit(void)
+{
+ platform_driver_unregister(&wakeup_d);
+}
+
+subsys_initcall(wakeup_dev_init);
+module_exit(wakeup_dev_uninit);
+
diff --git a/arch/arm/plat-mxc/utmixc.c b/arch/arm/plat-mxc/utmixc.c
new file mode 100755
index 00000000..227943ba
--- /dev/null
+++ b/arch/arm/plat-mxc/utmixc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/pmic_external.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+
+static void usb_utmi_init(struct fsl_xcvr_ops *this)
+{
+#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892)
+ if (machine_is_mx51_3ds()) {
+ unsigned int value;
+
+ /* VUSBIN */
+ pmic_read_reg(REG_USB1, &value, 0xffffff);
+ value |= 0x1;
+ value |= (0x1 << 3);
+ pmic_write_reg(REG_USB1, value, 0xffffff);
+ }
+#endif
+}
+
+static void usb_utmi_uninit(struct fsl_xcvr_ops *this)
+{
+}
+
+/*!
+ * set vbus power
+ *
+ * @param view viewport register
+ * @param on power on or off
+ */
+static void set_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ pr_debug("real %s(on=%d) pdata=0x%p\n", __func__, on, pdata);
+ if (pdata && pdata->platform_driver_vbus)
+ pdata->platform_driver_vbus(on);
+}
+
+static struct fsl_xcvr_ops utmi_ops = {
+ .name = "utmi",
+ .xcvr_type = PORTSC_PTS_UTMI,
+ .init = usb_utmi_init,
+ .uninit = usb_utmi_uninit,
+ .set_vbus_power = set_power,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init utmixc_init(void)
+{
+ fsl_usb_xcvr_register(&utmi_ops);
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit utmixc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&utmi_ops);
+}
+
+subsys_initcall(utmixc_init);
+module_exit(utmixc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("utmi xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
new file mode 100644
index 00000000..ce659015
--- /dev/null
+++ b/arch/arm/plat-nomadik/Kconfig
@@ -0,0 +1,24 @@
+# We keep common IP's here for Nomadik and other similar
+# familiy of processors from ST-Ericsson. At the moment we have
+# just MTU, others to follow soon.
+
+config PLAT_NOMADIK
+ bool
+ depends on ARCH_NOMADIK || ARCH_U8500
+ select CLKSRC_MMIO
+ default y
+ help
+ Common platform code for Nomadik and other ST-Ericsson
+ platforms.
+
+if PLAT_NOMADIK
+
+config HAS_MTU
+ bool
+ select HAVE_SCHED_CLOCK
+ help
+ Support for Multi Timer Unit. MTU provides access
+ to multiple interrupt generating programmable
+ 32-bit free running decrementing counters.
+
+endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
new file mode 100644
index 00000000..37c7cdd0
--- /dev/null
+++ b/arch/arm/plat-nomadik/Makefile
@@ -0,0 +1,5 @@
+# arch/arm/plat-nomadik/Makefile
+# Copyright 2009 ST-Ericsson
+# Licensed under GPLv2
+
+obj-$(CONFIG_HAS_MTU) += timer.o
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
new file mode 100644
index 00000000..d5d7e651
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -0,0 +1,96 @@
+/*
+ * Structures and registers for GPIO access in the Nomadik SoC
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Author: Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *
+ * This program is free software; you can 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_GPIO_H
+#define __ASM_PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+/*
+ * These currently cause a function call to happen, they may be optimized
+ * if needed by adding cpu-specific defines to identify blocks
+ * (see mach-pxa/include/mach/gpio.h as an example using GPLR etc)
+ */
+#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
+
+/*
+ * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving
+ * the "gpio" namespace for generic and cross-machine functions
+ */
+
+/* Register in the logic block */
+#define NMK_GPIO_DAT 0x00
+#define NMK_GPIO_DATS 0x04
+#define NMK_GPIO_DATC 0x08
+#define NMK_GPIO_PDIS 0x0c
+#define NMK_GPIO_DIR 0x10
+#define NMK_GPIO_DIRS 0x14
+#define NMK_GPIO_DIRC 0x18
+#define NMK_GPIO_SLPC 0x1c
+#define NMK_GPIO_AFSLA 0x20
+#define NMK_GPIO_AFSLB 0x24
+
+#define NMK_GPIO_RIMSC 0x40
+#define NMK_GPIO_FIMSC 0x44
+#define NMK_GPIO_IS 0x48
+#define NMK_GPIO_IC 0x4c
+#define NMK_GPIO_RWIMSC 0x50
+#define NMK_GPIO_FWIMSC 0x54
+#define NMK_GPIO_WKS 0x58
+
+/* Alternate functions: function C is set in hw by setting both A and B */
+#define NMK_GPIO_ALT_GPIO 0
+#define NMK_GPIO_ALT_A 1
+#define NMK_GPIO_ALT_B 2
+#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+
+/* Pull up/down values */
+enum nmk_gpio_pull {
+ NMK_GPIO_PULL_NONE,
+ NMK_GPIO_PULL_UP,
+ NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+ NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_NOCHANGE,
+ NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE,
+};
+
+extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
+extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
+extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
+extern int nmk_gpio_get_mode(int gpio);
+
+extern void nmk_gpio_wakeups_suspend(void);
+extern void nmk_gpio_wakeups_resume(void);
+
+extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+struct nmk_gpio_platform_data {
+ char *name;
+ int first_gpio;
+ int first_irq;
+ int num_gpio;
+ u32 (*get_secondary_status)(unsigned int bank);
+ void (*set_ioforce)(bool enable);
+ bool supports_sleepmode;
+};
+
+#endif /* __ASM_PLAT_GPIO_H */
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h
new file mode 100644
index 00000000..8ba70ffc
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/i2c.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can 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_I2C_H
+#define __PLAT_I2C_H
+
+enum i2c_freq_mode {
+ I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
+ I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
+ I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
+ I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
+};
+
+/**
+ * struct nmk_i2c_controller - client specific controller configuration
+ * @clk_freq: clock frequency for the operation mode
+ * @slsu: Slave data setup time in ns.
+ * The needed setup time for three modes of operation
+ * are 250ns, 100ns and 10ns respectively thus leading
+ * to the values of 14, 6, 2 for a 48 MHz i2c clk
+ * @tft: Tx FIFO Threshold in bytes
+ * @rft: Rx FIFO Threshold in bytes
+ * @timeout Slave response timeout(ms)
+ * @sm: speed mode
+ */
+struct nmk_i2c_controller {
+ unsigned long clk_freq;
+ unsigned short slsu;
+ unsigned char tft;
+ unsigned char rft;
+ int timeout;
+ enum i2c_freq_mode sm;
+};
+
+#endif /* __PLAT_I2C_H */
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
new file mode 100644
index 00000000..65704a3d
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -0,0 +1,54 @@
+#ifndef __PLAT_MTU_H
+#define __PLAT_MTU_H
+
+/*
+ * Guaranteed runtime conversion range in seconds for
+ * the clocksource and clockevent.
+ */
+#define MTU_MIN_RANGE 4
+
+/* should be set by the platform code */
+extern void __iomem *mtu_base;
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC 0x00 /* Interrupt mask set/clear */
+#define MTU_RIS 0x04 /* Raw interrupt status */
+#define MTU_MIS 0x08 /* Masked interrupt status */
+#define MTU_ICR 0x0C /* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x) (0x10 + 0x10 * (x) + 0x00) /* Load value */
+#define MTU_VAL(x) (0x10 + 0x10 * (x) + 0x04) /* Current value */
+#define MTU_CR(x) (0x10 + 0x10 * (x) + 0x08) /* Control reg */
+#define MTU_BGLR(x) (0x10 + 0x10 * (x) + 0x0c) /* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA 0x80
+#define MTU_CRn_PERIODIC 0x40 /* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK 0x0c
+#define MTU_CRn_PRESCALE_1 0x00
+#define MTU_CRn_PRESCALE_16 0x04
+#define MTU_CRn_PRESCALE_256 0x08
+#define MTU_CRn_32BITS 0x02
+#define MTU_CRn_ONESHOT 0x01 /* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR 0xff0
+#define MTU_ITOP 0xff4
+
+#define MTU_PERIPH_ID0 0xfe0
+#define MTU_PERIPH_ID1 0xfe4
+#define MTU_PERIPH_ID2 0xfe8
+#define MTU_PERIPH_ID3 0xfeC
+
+#define MTU_PCELL0 0xff0
+#define MTU_PCELL1 0xff4
+#define MTU_PCELL2 0xff8
+#define MTU_PCELL3 0xffC
+
+#endif /* __PLAT_MTU_H */
+
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
new file mode 100644
index 00000000..05a3936a
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ *
+ * Based on arch/arm/mach-pxa/include/mach/mfp.h:
+ * Copyright (C) 2007 Marvell International Ltd.
+ * eric miao <eric.miao@marvell.com>
+ */
+
+#ifndef __PLAT_PINCFG_H
+#define __PLAT_PINCFG_H
+
+/*
+ * pin configurations are represented by 32-bit integers:
+ *
+ * bit 0.. 8 - Pin Number (512 Pins Maximum)
+ * bit 9..10 - Alternate Function Selection
+ * bit 11..12 - Pull up/down state
+ * bit 13 - Sleep mode behaviour
+ * bit 14 - Direction
+ * bit 15 - Value (if output)
+ * bit 16..18 - SLPM pull up/down state
+ * bit 19..20 - SLPM direction
+ * bit 21..22 - SLPM Value (if output)
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * PIN_CFG_DEFAULT - default config (0):
+ * pull up/down = disabled
+ * sleep mode = input/wakeup
+ * direction = input
+ * value = low
+ * SLPM direction = same as normal
+ * SLPM pull = same as normal
+ * SLPM value = same as normal
+ *
+ * PIN_CFG - default config with alternate function
+ * PIN_CFG_PULL - default config with alternate function and pull up/down
+ */
+
+typedef unsigned long pin_cfg_t;
+
+#define PIN_NUM_MASK 0x1ff
+#define PIN_NUM(x) ((x) & PIN_NUM_MASK)
+
+#define PIN_ALT_SHIFT 9
+#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT)
+#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
+#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
+#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
+#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
+#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
+
+#define PIN_PULL_SHIFT 11
+#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT)
+#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
+#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
+#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
+#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
+
+#define PIN_SLPM_SHIFT 13
+#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
+#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
+#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+/* These two replace the above in DB8500v2+ */
+#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT)
+#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT)
+
+#define PIN_DIR_SHIFT 14
+#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT)
+#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT)
+#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT)
+#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT)
+
+#define PIN_VAL_SHIFT 15
+#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT)
+#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT)
+#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT)
+#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT)
+
+#define PIN_SLPM_PULL_SHIFT 16
+#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL(x) \
+ (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_NONE \
+ ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_UP \
+ ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT)
+#define PIN_SLPM_PULL_DOWN \
+ ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT)
+
+#define PIN_SLPM_DIR_SHIFT 19
+#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR(x) \
+ (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT)
+#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT)
+
+#define PIN_SLPM_VAL_SHIFT 21
+#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL(x) \
+ (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT)
+#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT)
+
+/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */
+#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN)
+#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP)
+#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE)
+#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW)
+#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH)
+
+#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN)
+#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP)
+#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE)
+#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW)
+#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH)
+
+#define PIN_CFG_DEFAULT (0)
+
+#define PIN_CFG(num, alt) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt))
+
+#define PIN_CFG_INPUT(num, alt, pull) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull))
+
+#define PIN_CFG_OUTPUT(num, alt, val) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val))
+
+#define PIN_CFG_PULL(num, alt, pull) \
+ ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
+ (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
+
+extern int nmk_config_pin(pin_cfg_t cfg, bool sleep);
+extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
+extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num);
+
+#endif
diff --git a/arch/arm/plat-nomadik/include/plat/ske.h b/arch/arm/plat-nomadik/include/plat/ske.h
new file mode 100644
index 00000000..31382fbc
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/ske.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Naveen Kumar Gaddipati <naveen.gaddipati@stericsson.com>
+ *
+ * ux500 Scroll key and Keypad Encoder (SKE) header
+ */
+
+#ifndef __SKE_H
+#define __SKE_H
+
+#include <linux/input/matrix_keypad.h>
+
+/* register definitions for SKE peripheral */
+#define SKE_CR 0x00
+#define SKE_VAL0 0x04
+#define SKE_VAL1 0x08
+#define SKE_DBCR 0x0C
+#define SKE_IMSC 0x10
+#define SKE_RIS 0x14
+#define SKE_MIS 0x18
+#define SKE_ICR 0x1C
+
+/*
+ * Keypad module
+ */
+
+/**
+ * struct keypad_platform_data - structure for platform specific data
+ * @init: pointer to keypad init function
+ * @exit: pointer to keypad deinitialisation function
+ * @keymap_data: matrix scan code table for keycodes
+ * @krow: maximum number of rows
+ * @kcol: maximum number of columns
+ * @debounce_ms: platform specific debounce time
+ * @no_autorepeat: flag for auto repetition
+ * @wakeup_enable: allow waking up the system
+ */
+struct ske_keypad_platform_data {
+ int (*init)(void);
+ int (*exit)(void);
+ const struct matrix_keymap_data *keymap_data;
+ u8 krow;
+ u8 kcol;
+ u8 debounce_ms;
+ bool no_autorepeat;
+ bool wakeup_enable;
+};
+#endif /*__SKE_KPD_H*/
diff --git a/arch/arm/plat-nomadik/include/plat/ste_dma40.h b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
new file mode 100644
index 00000000..38b041a4
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/ste_dma40.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2007-2010
+ * Author: Per Forlin <per.forlin@stericsson.com> for ST-Ericsson
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+
+#ifndef STE_DMA40_H
+#define STE_DMA40_H
+
+#include <linux/dmaengine.h>
+#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+
+/*
+ * Maxium size for a single dma descriptor
+ * Size is limited to 16 bits.
+ * Size is in the units of addr-widths (1,2,4,8 bytes)
+ * Larger transfers will be split up to multiple linked desc
+ */
+#define STEDMA40_MAX_SEG_SIZE 0xFFFF
+
+/* dev types for memcpy */
+#define STEDMA40_DEV_DST_MEMORY (-1)
+#define STEDMA40_DEV_SRC_MEMORY (-1)
+
+enum stedma40_mode {
+ STEDMA40_MODE_LOGICAL = 0,
+ STEDMA40_MODE_PHYSICAL,
+ STEDMA40_MODE_OPERATION,
+};
+
+enum stedma40_mode_opt {
+ STEDMA40_PCHAN_BASIC_MODE = 0,
+ STEDMA40_LCHAN_SRC_LOG_DST_LOG = 0,
+ STEDMA40_PCHAN_MODULO_MODE,
+ STEDMA40_PCHAN_DOUBLE_DST_MODE,
+ STEDMA40_LCHAN_SRC_PHY_DST_LOG,
+ STEDMA40_LCHAN_SRC_LOG_DST_PHY,
+};
+
+#define STEDMA40_ESIZE_8_BIT 0x0
+#define STEDMA40_ESIZE_16_BIT 0x1
+#define STEDMA40_ESIZE_32_BIT 0x2
+#define STEDMA40_ESIZE_64_BIT 0x3
+
+/* The value 4 indicates that PEN-reg shall be set to 0 */
+#define STEDMA40_PSIZE_PHY_1 0x4
+#define STEDMA40_PSIZE_PHY_2 0x0
+#define STEDMA40_PSIZE_PHY_4 0x1
+#define STEDMA40_PSIZE_PHY_8 0x2
+#define STEDMA40_PSIZE_PHY_16 0x3
+
+/*
+ * The number of elements differ in logical and
+ * physical mode
+ */
+#define STEDMA40_PSIZE_LOG_1 STEDMA40_PSIZE_PHY_2
+#define STEDMA40_PSIZE_LOG_4 STEDMA40_PSIZE_PHY_4
+#define STEDMA40_PSIZE_LOG_8 STEDMA40_PSIZE_PHY_8
+#define STEDMA40_PSIZE_LOG_16 STEDMA40_PSIZE_PHY_16
+
+/* Maximum number of possible physical channels */
+#define STEDMA40_MAX_PHYS 32
+
+enum stedma40_flow_ctrl {
+ STEDMA40_NO_FLOW_CTRL,
+ STEDMA40_FLOW_CTRL,
+};
+
+enum stedma40_periph_data_width {
+ STEDMA40_BYTE_WIDTH = STEDMA40_ESIZE_8_BIT,
+ STEDMA40_HALFWORD_WIDTH = STEDMA40_ESIZE_16_BIT,
+ STEDMA40_WORD_WIDTH = STEDMA40_ESIZE_32_BIT,
+ STEDMA40_DOUBLEWORD_WIDTH = STEDMA40_ESIZE_64_BIT
+};
+
+enum stedma40_xfer_dir {
+ STEDMA40_MEM_TO_MEM = 1,
+ STEDMA40_MEM_TO_PERIPH,
+ STEDMA40_PERIPH_TO_MEM,
+ STEDMA40_PERIPH_TO_PERIPH
+};
+
+
+/**
+ * struct stedma40_chan_cfg - dst/src channel configuration
+ *
+ * @big_endian: true if the src/dst should be read as big endian
+ * @data_width: Data width of the src/dst hardware
+ * @p_size: Burst size
+ * @flow_ctrl: Flow control on/off.
+ */
+struct stedma40_half_channel_info {
+ bool big_endian;
+ enum stedma40_periph_data_width data_width;
+ int psize;
+ enum stedma40_flow_ctrl flow_ctrl;
+};
+
+/**
+ * struct stedma40_chan_cfg - Structure to be filled by client drivers.
+ *
+ * @dir: MEM 2 MEM, PERIPH 2 MEM , MEM 2 PERIPH, PERIPH 2 PERIPH
+ * @high_priority: true if high-priority
+ * @realtime: true if realtime mode is to be enabled. Only available on DMA40
+ * version 3+, i.e DB8500v2+
+ * @mode: channel mode: physical, logical, or operation
+ * @mode_opt: options for the chosen channel mode
+ * @src_dev_type: Src device type
+ * @dst_dev_type: Dst device type
+ * @src_info: Parameters for dst half channel
+ * @dst_info: Parameters for dst half channel
+ *
+ *
+ * This structure has to be filled by the client drivers.
+ * It is recommended to do all dma configurations for clients in the machine.
+ *
+ */
+struct stedma40_chan_cfg {
+ enum stedma40_xfer_dir dir;
+ bool high_priority;
+ bool realtime;
+ enum stedma40_mode mode;
+ enum stedma40_mode_opt mode_opt;
+ int src_dev_type;
+ int dst_dev_type;
+ struct stedma40_half_channel_info src_info;
+ struct stedma40_half_channel_info dst_info;
+};
+
+/**
+ * struct stedma40_platform_data - Configuration struct for the dma device.
+ *
+ * @dev_len: length of dev_tx and dev_rx
+ * @dev_tx: mapping between destination event line and io address
+ * @dev_rx: mapping between source event line and io address
+ * @memcpy: list of memcpy event lines
+ * @memcpy_len: length of memcpy
+ * @memcpy_conf_phy: default configuration of physical channel memcpy
+ * @memcpy_conf_log: default configuration of logical channel memcpy
+ * @disabled_channels: A vector, ending with -1, that marks physical channels
+ * that are for different reasons not available for the driver.
+ */
+struct stedma40_platform_data {
+ u32 dev_len;
+ const dma_addr_t *dev_tx;
+ const dma_addr_t *dev_rx;
+ int *memcpy;
+ u32 memcpy_len;
+ struct stedma40_chan_cfg *memcpy_conf_phy;
+ struct stedma40_chan_cfg *memcpy_conf_log;
+ int disabled_channels[STEDMA40_MAX_PHYS];
+};
+
+#ifdef CONFIG_STE_DMA40
+
+/**
+ * stedma40_filter() - Provides stedma40_chan_cfg to the
+ * ste_dma40 dma driver via the dmaengine framework.
+ * does some checking of what's provided.
+ *
+ * Never directly called by client. It used by dmaengine.
+ * @chan: dmaengine handle.
+ * @data: Must be of type: struct stedma40_chan_cfg and is
+ * the configuration of the framework.
+ *
+ *
+ */
+
+bool stedma40_filter(struct dma_chan *chan, void *data);
+
+/**
+ * stedma40_slave_mem() - Transfers a raw data buffer to or from a slave
+ * (=device)
+ *
+ * @chan: dmaengine handle
+ * @addr: source or destination physicall address.
+ * @size: bytes to transfer
+ * @direction: direction of transfer
+ * @flags: is actually enum dma_ctrl_flags. See dmaengine.h
+ */
+
+static inline struct
+dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
+ dma_addr_t addr,
+ unsigned int size,
+ enum dma_transfer_direction direction,
+ unsigned long flags)
+{
+ struct scatterlist sg;
+ sg_init_table(&sg, 1);
+ sg.dma_address = addr;
+ sg.length = size;
+
+ return chan->device->device_prep_slave_sg(chan, &sg, 1,
+ direction, flags);
+}
+
+#else
+static inline bool stedma40_filter(struct dma_chan *chan, void *data)
+{
+ return false;
+}
+
+static inline struct
+dma_async_tx_descriptor *stedma40_slave_mem(struct dma_chan *chan,
+ dma_addr_t addr,
+ unsigned int size,
+ enum dma_transfer_direction direction,
+ unsigned long flags)
+{
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
new file mode 100644
index 00000000..ef74e157
--- /dev/null
+++ b/arch/arm/plat-nomadik/timer.c
@@ -0,0 +1,174 @@
+/*
+ * linux/arch/arm/plat-nomadik/timer.c
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2010 Alessandro Rubini
+ * Copyright (C) 2010 Linus Walleij for ST-Ericsson
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
+
+#include <plat/mtu.h>
+
+void __iomem *mtu_base; /* Assigned by machine code */
+
+/*
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc;
+
+ if (unlikely(!mtu_base))
+ return 0;
+
+ cyc = -readl(mtu_base + MTU_VAL(0));
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace nomadik_update_sched_clock(void)
+{
+ u32 cyc = -readl(mtu_base + MTU_VAL(0));
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/* Clockevent device: use one-shot mode */
+static void nmdk_clkevt_mode(enum clock_event_mode mode,
+ struct clock_event_device *dev)
+{
+ u32 cr;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_err("%s: periodic mode not supported\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /* Load highest value, enable device, enable interrupts */
+ cr = readl(mtu_base + MTU_CR(1));
+ writel(0, mtu_base + MTU_LR(1));
+ writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1));
+ writel(1 << 1, mtu_base + MTU_IMSC);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ /* disable irq */
+ writel(0, mtu_base + MTU_IMSC);
+ /* disable timer */
+ cr = readl(mtu_base + MTU_CR(1));
+ cr &= ~MTU_CRn_ENA;
+ writel(cr, mtu_base + MTU_CR(1));
+ /* load some high default value */
+ writel(0xffffffff, mtu_base + MTU_LR(1));
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
+{
+ /* writing the value has immediate effect */
+ writel(evt, mtu_base + MTU_LR(1));
+ return 0;
+}
+
+static struct clock_event_device nmdk_clkevt = {
+ .name = "mtu_1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_mode = nmdk_clkevt_mode,
+ .set_next_event = nmdk_clkevt_next,
+};
+
+/*
+ * IRQ Handler for timer 1 of the MTU block.
+ */
+static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evdev = dev_id;
+
+ writel(1 << 1, mtu_base + MTU_ICR); /* Interrupt clear reg */
+ evdev->event_handler(evdev);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction nmdk_timer_irq = {
+ .name = "Nomadik Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = nmdk_timer_interrupt,
+ .dev_id = &nmdk_clkevt,
+};
+
+void __init nmdk_timer_init(void)
+{
+ unsigned long rate;
+ struct clk *clk0;
+ u32 cr = MTU_CRn_32BITS;
+
+ clk0 = clk_get_sys("mtu0", NULL);
+ BUG_ON(IS_ERR(clk0));
+
+ clk_enable(clk0);
+
+ /*
+ * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
+ * for ux500.
+ * Use a divide-by-16 counter if the tick rate is more than 32MHz.
+ * At 32 MHz, the timer (with 32 bit counter) can be programmed
+ * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer
+ * with 16 gives too low timer resolution.
+ */
+ rate = clk_get_rate(clk0);
+ if (rate > 32000000) {
+ rate /= 16;
+ cr |= MTU_CRn_PRESCALE_16;
+ } else {
+ cr |= MTU_CRn_PRESCALE_1;
+ }
+
+ /* Timer 0 is the free running clocksource */
+ writel(cr, mtu_base + MTU_CR(0));
+ writel(0, mtu_base + MTU_LR(0));
+ writel(0, mtu_base + MTU_BGLR(0));
+ writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+
+ if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
+ rate, 200, 32, clocksource_mmio_readl_down))
+ pr_err("timer: failed to initialize clock source %s\n",
+ "mtu_0");
+
+ init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
+
+ /* Timer 1 is used for events */
+
+ clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
+
+ writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
+
+ nmdk_clkevt.max_delta_ns =
+ clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
+ nmdk_clkevt.min_delta_ns =
+ clockevent_delta2ns(0x00000002, &nmdk_clkevt);
+ nmdk_clkevt.cpumask = cpumask_of(0);
+
+ /* Register irq and clockevents */
+ setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+ clockevents_register_device(&nmdk_clkevt);
+}
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
new file mode 100644
index 00000000..49a4c752
--- /dev/null
+++ b/arch/arm/plat-omap/Kconfig
@@ -0,0 +1,224 @@
+if ARCH_OMAP
+
+menu "TI OMAP Common Features"
+
+config ARCH_OMAP_OTG
+ bool
+
+choice
+ prompt "OMAP System Type"
+ default ARCH_OMAP2PLUS
+
+config ARCH_OMAP1
+ bool "TI OMAP1"
+ select CLKDEV_LOOKUP
+ select CLKSRC_MMIO
+ help
+ "Systems based on omap7xx, omap15xx or omap16xx"
+
+config ARCH_OMAP2PLUS
+ bool "TI OMAP2/3/4"
+ select CLKDEV_LOOKUP
+ select GENERIC_IRQ_CHIP
+ select OMAP_DM_TIMER
+ help
+ "Systems based on OMAP2, OMAP3 or OMAP4"
+
+endchoice
+
+comment "OMAP Feature Selections"
+
+config OMAP_DEBUG_DEVICES
+ bool
+ help
+ For debug cards on TI reference boards.
+
+config OMAP_DEBUG_LEDS
+ bool
+ depends on OMAP_DEBUG_DEVICES
+ default y if LEDS_CLASS
+
+config OMAP_SMARTREFLEX
+ bool "SmartReflex support"
+ depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
+ help
+ Say Y if you want to enable SmartReflex.
+
+ SmartReflex can perform continuous dynamic voltage
+ scaling around the nominal operating point voltage
+ according to silicon characteristics and operating
+ conditions. Enabling SmartReflex reduces power
+ consumption.
+
+ Please note, that by default SmartReflex is only
+ initialized. To enable the automatic voltage
+ compensation for vdd mpu and vdd core from user space,
+ user must write 1 to
+ /debug/voltage/vdd_<X>/smartreflex/autocomp,
+ where X is mpu or core for OMAP3.
+ Optionally autocompensation can be enabled in the kernel
+ by default during system init via the enable_on_init flag
+ which an be passed as platform data to the smartreflex driver.
+
+config OMAP_SMARTREFLEX_CLASS3
+ bool "Class 3 mode of Smartreflex Implementation"
+ depends on OMAP_SMARTREFLEX && TWL4030_CORE
+ help
+ Say Y to enable Class 3 implementation of Smartreflex
+
+ Class 3 implementation of Smartreflex employs continuous hardware
+ voltage calibration.
+
+config OMAP_RESET_CLOCKS
+ bool "Reset unused clocks during boot"
+ depends on ARCH_OMAP
+ help
+ Say Y if you want to reset unused clocks during boot.
+ This option saves power, but assumes all drivers are
+ using the clock framework. Broken drivers that do not
+ yet use clock framework may not work with this option.
+ If you are booting from another operating system, you
+ probably do not want this option enabled until your
+ device drivers work properly.
+
+config OMAP_MUX
+ bool "OMAP multiplexing support"
+ depends on ARCH_OMAP
+ default y
+ help
+ Pin multiplexing support for OMAP boards. If your bootloader
+ sets the multiplexing correctly, say N. Otherwise, or if unsure,
+ say Y.
+
+config OMAP_MUX_DEBUG
+ bool "Multiplexing debug output"
+ depends on OMAP_MUX
+ help
+ Makes the multiplexing functions print out a lot of debug info.
+ This is useful if you want to find out the correct values of the
+ multiplexing registers.
+
+config OMAP_MUX_WARNINGS
+ bool "Warn about pins the bootloader didn't set up"
+ depends on OMAP_MUX
+ default y
+ help
+ Choose Y here to warn whenever driver initialization logic needs
+ to change the pin multiplexing setup. When there are no warnings
+ printed, it's safe to deselect OMAP_MUX for your product.
+
+config OMAP_MCBSP
+ bool "McBSP support"
+ depends on ARCH_OMAP
+ default y
+ help
+ Say Y here if you want support for the OMAP Multichannel
+ Buffered Serial Port.
+
+config OMAP_MBOX_FWK
+ tristate "Mailbox framework support"
+ depends on ARCH_OMAP
+ help
+ Say Y here if you want to use OMAP Mailbox framework support for
+ DSP, IVA1.0 and IVA2 in OMAP1/2/3.
+
+config OMAP_MBOX_KFIFO_SIZE
+ int "Mailbox kfifo default buffer size (bytes)"
+ depends on OMAP_MBOX_FWK
+ default 256
+ help
+ Specify the default size of mailbox's kfifo buffers (bytes).
+ This can also be changed at runtime (via the mbox_kfifo_size
+ module parameter).
+
+config OMAP_IOMMU
+ tristate
+
+config OMAP_IOMMU_DEBUG
+ tristate "Export OMAP IOMMU internals in DebugFS"
+ depends on OMAP_IOMMU && DEBUG_FS
+ help
+ Select this to see extensive information about
+ the internal state of OMAP IOMMU in debugfs.
+
+ Say N unless you know you need this.
+
+config OMAP_IOMMU_IVA2
+ bool
+
+config OMAP_MPU_TIMER
+ bool "Use mpu timer"
+ depends on ARCH_OMAP1
+ help
+ Select this option if you want to use the OMAP mpu timer. This
+ timer provides more intra-tick resolution than the 32KHz timer,
+ but consumes more power.
+
+config OMAP_32K_TIMER
+ bool "Use 32KHz timer"
+ depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+ default y if (ARCH_OMAP16XX || ARCH_OMAP2PLUS)
+ help
+ Select this option if you want to enable the OMAP 32KHz timer.
+ This timer saves power compared to the OMAP_MPU_TIMER, and has
+ support for no tick during idle. The 32KHz timer provides less
+ intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
+ currently only available for OMAP16XX, 24XX, 34XX and OMAP4.
+
+config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+ bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
+ depends on ARCH_OMAP3 && PM
+ default n
+ help
+ Without this option, L2 Auxiliary control register contents are
+ lost during off-mode entry on HS/EMU devices. This feature
+ requires support from PPA / boot-loader in HS/EMU devices, which
+ currently does not exist by default.
+
+config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
+ int "Service ID for the support routine to set L2 AUX control"
+ depends on OMAP3_L2_AUX_SECURE_SAVE_RESTORE
+ default 43
+ help
+ PPA routine service ID for setting L2 auxiliary control register.
+
+config OMAP_32K_TIMER_HZ
+ int "Kernel internal timer frequency for 32KHz timer"
+ range 32 1024
+ depends on OMAP_32K_TIMER
+ default "128"
+ help
+ Kernel internal timer frequency should be a divisor of 32768,
+ such as 64 or 128.
+
+config OMAP_DM_TIMER
+ bool "Use dual-mode timer"
+ depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+ help
+ Select this option if you want to use OMAP Dual-Mode timers.
+
+config OMAP_SERIAL_WAKE
+ bool "Enable wake-up events for serial ports"
+ depends on ARCH_OMAP1 && OMAP_MUX
+ default y
+ help
+ Select this option if you want to have your system wake up
+ to data on the serial RX line. This allows you to wake the
+ system from serial console.
+
+choice
+ prompt "OMAP PM layer selection"
+ depends on ARCH_OMAP
+ default OMAP_PM_NOOP
+
+config OMAP_PM_NONE
+ bool "No PM layer"
+
+config OMAP_PM_NOOP
+ bool "No-op/debug PM layer"
+
+endchoice
+
+endmenu
+
+endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
new file mode 100644
index 00000000..f0233e6a
--- /dev/null
+++ b/arch/arm/plat-omap/Makefile
@@ -0,0 +1,34 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := common.o sram.o clock.o devices.o dma.o mux.o \
+ usb.o fb.o io.o counter_32k.o
+obj-m :=
+obj-n :=
+obj- :=
+
+# OCPI interconnect support for 1710, 1610 and 5912
+obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
+
+# omap_device support (OMAP2+ only at the moment)
+obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
+obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
+
+obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
+obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
+
+obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
+obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
+obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
+obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
+i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
+obj-y += $(i2c-omap-m) $(i2c-omap-y)
+
+# OMAP mailbox framework
+obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
+
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
new file mode 100644
index 00000000..c9122dd6
--- /dev/null
+++ b/arch/arm/plat-omap/clock.c
@@ -0,0 +1,561 @@
+/*
+ * linux/arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2008 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ *
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.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/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static struct clk_functions *arch_clock;
+
+/*
+ * Standard clock functions defined in include/linux/clk.h
+ */
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ int ret;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (!arch_clock || !arch_clock->clk_enable)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = arch_clock->clk_enable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ if (!arch_clock || !arch_clock->clk_disable)
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->usecount == 0) {
+ pr_err("Trying disable clock %s with 0 usecount\n",
+ clk->name);
+ WARN_ON(1);
+ goto out;
+ }
+
+ arch_clock->clk_disable(clk);
+
+out:
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long flags;
+ unsigned long ret;
+
+ if (clk == NULL || IS_ERR(clk))
+ return 0;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = clk->rate;
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/*
+ * Optional clock functions defined in include/linux/clk.h
+ */
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ long ret;
+
+ if (clk == NULL || IS_ERR(clk))
+ return 0;
+
+ if (!arch_clock || !arch_clock->clk_round_rate)
+ return 0;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = arch_clock->clk_round_rate(clk, rate);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ if (!arch_clock || !arch_clock->clk_set_rate)
+ return ret;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ ret = arch_clock->clk_set_rate(clk, rate);
+ if (ret == 0)
+ propagate_rate(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
+ return ret;
+
+ if (!arch_clock || !arch_clock->clk_set_parent)
+ return ret;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->usecount == 0) {
+ ret = arch_clock->clk_set_parent(clk, parent);
+ if (ret == 0)
+ propagate_rate(clk);
+ } else
+ ret = -EBUSY;
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+/*
+ * OMAP specific clock functions shared between omap1 and omap2
+ */
+
+int __initdata mpurate;
+
+/*
+ * By default we use the rate set by the bootloader.
+ * You can override this with mpurate= cmdline option.
+ */
+static int __init omap_clk_setup(char *str)
+{
+ get_option(&str, &mpurate);
+
+ if (!mpurate)
+ return 1;
+
+ if (mpurate < 1000)
+ mpurate *= 1000000;
+
+ return 1;
+}
+__setup("mpurate=", omap_clk_setup);
+
+/* Used for clocks that always have same value as the parent clock */
+unsigned long followparent_recalc(struct clk *clk)
+{
+ return clk->parent->rate;
+}
+
+/*
+ * Used for clocks that have the same value as the parent clock,
+ * divided by some factor
+ */
+unsigned long omap_fixed_divisor_recalc(struct clk *clk)
+{
+ WARN_ON(!clk->fixed_div);
+
+ return clk->parent->rate / clk->fixed_div;
+}
+
+void clk_reparent(struct clk *child, struct clk *parent)
+{
+ list_del_init(&child->sibling);
+ if (parent)
+ list_add(&child->sibling, &parent->children);
+ child->parent = parent;
+
+ /* now do the debugfs renaming to reattach the child
+ to the proper parent */
+}
+
+/* Propagate rate to children */
+void propagate_rate(struct clk *tclk)
+{
+ struct clk *clkp;
+
+ list_for_each_entry(clkp, &tclk->children, sibling) {
+ if (clkp->recalc)
+ clkp->rate = clkp->recalc(clkp);
+ propagate_rate(clkp);
+ }
+}
+
+static LIST_HEAD(root_clks);
+
+/**
+ * recalculate_root_clocks - recalculate and propagate all root clocks
+ *
+ * Recalculates all root clocks (clocks with no parent), which if the
+ * clock's .recalc is set correctly, should also propagate their rates.
+ * Called at init.
+ */
+void recalculate_root_clocks(void)
+{
+ struct clk *clkp;
+
+ list_for_each_entry(clkp, &root_clks, sibling) {
+ if (clkp->recalc)
+ clkp->rate = clkp->recalc(clkp);
+ propagate_rate(clkp);
+ }
+}
+
+/**
+ * clk_preinit - initialize any fields in the struct clk before clk init
+ * @clk: struct clk * to initialize
+ *
+ * Initialize any struct clk fields needed before normal clk initialization
+ * can run. No return value.
+ */
+void clk_preinit(struct clk *clk)
+{
+ INIT_LIST_HEAD(&clk->children);
+}
+
+int clk_register(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ /*
+ * trap out already registered clocks
+ */
+ if (clk->node.next || clk->node.prev)
+ return 0;
+
+ mutex_lock(&clocks_mutex);
+ if (clk->parent)
+ list_add(&clk->sibling, &clk->parent->children);
+ else
+ list_add(&clk->sibling, &root_clks);
+
+ list_add(&clk->node, &clocks);
+ if (clk->init)
+ clk->init(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ list_del(&clk->sibling);
+ list_del(&clk->node);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+void clk_enable_init_clocks(void)
+{
+ struct clk *clkp;
+
+ list_for_each_entry(clkp, &clocks, node) {
+ if (clkp->flags & ENABLE_ON_INIT)
+ clk_enable(clkp);
+ }
+}
+
+/**
+ * omap_clk_get_by_name - locate OMAP struct clk by its name
+ * @name: name of the struct clk to locate
+ *
+ * Locate an OMAP struct clk by its name. Assumes that struct clk
+ * names are unique. Returns NULL if not found or a pointer to the
+ * struct clk if found.
+ */
+struct clk *omap_clk_get_by_name(const char *name)
+{
+ struct clk *c;
+ struct clk *ret = NULL;
+
+ mutex_lock(&clocks_mutex);
+
+ list_for_each_entry(c, &clocks, node) {
+ if (!strcmp(c->name, name)) {
+ ret = c;
+ break;
+ }
+ }
+
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+
+int omap_clk_enable_autoidle_all(void)
+{
+ struct clk *c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+
+ list_for_each_entry(c, &clocks, node)
+ if (c->ops->allow_idle)
+ c->ops->allow_idle(c);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+
+int omap_clk_disable_autoidle_all(void)
+{
+ struct clk *c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+
+ list_for_each_entry(c, &clocks, node)
+ if (c->ops->deny_idle)
+ c->ops->deny_idle(c);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+
+/*
+ * Low level helpers
+ */
+static int clkll_enable_null(struct clk *clk)
+{
+ return 0;
+}
+
+static void clkll_disable_null(struct clk *clk)
+{
+}
+
+const struct clkops clkops_null = {
+ .enable = clkll_enable_null,
+ .disable = clkll_disable_null,
+};
+
+/*
+ * Dummy clock
+ *
+ * Used for clock aliases that are needed on some OMAPs, but not others
+ */
+struct clk dummy_ck = {
+ .name = "dummy",
+ .ops = &clkops_null,
+};
+
+#ifdef CONFIG_CPU_FREQ
+void clk_init_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ unsigned long flags;
+
+ if (!arch_clock || !arch_clock->clk_init_cpufreq_table)
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ arch_clock->clk_init_cpufreq_table(table);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+
+void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table)
+{
+ unsigned long flags;
+
+ if (!arch_clock || !arch_clock->clk_exit_cpufreq_table)
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ arch_clock->clk_exit_cpufreq_table(table);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+#endif
+
+/*
+ *
+ */
+
+#ifdef CONFIG_OMAP_RESET_CLOCKS
+/*
+ * Disable any unused clocks left on by the bootloader
+ */
+static int __init clk_disable_unused(void)
+{
+ struct clk *ck;
+ unsigned long flags;
+
+ if (!arch_clock || !arch_clock->clk_disable_unused)
+ return 0;
+
+ pr_info("clock: disabling unused clocks to save power\n");
+ list_for_each_entry(ck, &clocks, node) {
+ if (ck->ops == &clkops_null)
+ continue;
+
+ if (ck->usecount > 0 || !ck->enable_reg)
+ continue;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ arch_clock->clk_disable_unused(ck);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+ }
+
+ return 0;
+}
+late_initcall(clk_disable_unused);
+late_initcall(omap_clk_enable_autoidle_all);
+#endif
+
+int __init clk_init(struct clk_functions * custom_clocks)
+{
+ if (!custom_clocks) {
+ pr_err("No custom clock functions registered\n");
+ BUG();
+ }
+
+ arch_clock = custom_clocks;
+
+ return 0;
+}
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+static struct dentry *clk_debugfs_root;
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ int err;
+ struct dentry *d, *child, *child_tmp;
+ struct clk *pa = c->parent;
+ char s[255];
+ char *p = s;
+
+ p += sprintf(p, "%s", c->name);
+ d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+ if (!d)
+ return -ENOMEM;
+ c->dent = d;
+
+ d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ 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);
+ return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clocks, node) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+late_initcall(clk_debugfs_init);
+
+#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
new file mode 100644
index 00000000..d9f10a31
--- /dev/null
+++ b/arch/arm/plat-omap/common.c
@@ -0,0 +1,68 @@
+/*
+ * linux/arch/arm/plat-omap/common.c
+ *
+ * Code common to all OMAP machines.
+ * The file is created by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/omapfb.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/vram.h>
+#include <plat/dsp.h>
+
+
+#define NO_LENGTH_CHECK 0xffffffff
+
+struct omap_board_config_kernel *omap_board_config __initdata;
+int omap_board_config_size;
+
+static const void *__init get_config(u16 tag, size_t len,
+ int skip, size_t *len_out)
+{
+ struct omap_board_config_kernel *kinfo = NULL;
+ int i;
+
+ /* Try to find the config from the board-specific structures
+ * in the kernel. */
+ for (i = 0; i < omap_board_config_size; i++) {
+ if (omap_board_config[i].tag == tag) {
+ if (skip == 0) {
+ kinfo = &omap_board_config[i];
+ break;
+ } else {
+ skip--;
+ }
+ }
+ }
+ if (kinfo == NULL)
+ return NULL;
+ return kinfo->data;
+}
+
+const void *__init __omap_get_config(u16 tag, size_t len, int nr)
+{
+ return get_config(tag, len, nr, NULL);
+}
+
+const void *__init omap_get_var_config(u16 tag, size_t *len)
+{
+ return get_config(tag, NO_LENGTH_CHECK, 0, len);
+}
+
+void __init omap_reserve(void)
+{
+ omapfb_reserve_sdram_memblock();
+ omap_vram_reserve_sdram_memblock();
+ omap_dsp_reserve_sdram_memblock();
+}
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
new file mode 100644
index 00000000..f7fed608
--- /dev/null
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -0,0 +1,207 @@
+/*
+ * OMAP 32ksynctimer/counter_32k-related code
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Copyright (C) 2010 Nokia Corporation
+ * Tony Lindgren <tony@atomide.com>
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * NOTE: This timer is not the same timer as the old OMAP1 MPU timer.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/sched.h>
+
+#include <asm/sched_clock.h>
+
+#include <plat/common.h>
+#include <plat/board.h>
+
+#include <plat/clock.h>
+
+
+/*
+ * 32KHz clocksource ... always available, on pretty most chips except
+ * OMAP 730 and 1510. Other timers could be used as clocksources, with
+ * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
+ * but systems won't necessarily want to spend resources that way.
+ */
+
+#define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410
+
+#include <linux/clocksource.h>
+
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
+#ifdef CONFIG_ARCH_OMAP16XX
+static cycle_t notrace omap16xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
+}
+#else
+#define omap16xx_32k_read NULL
+#endif
+
+#ifdef CONFIG_SOC_OMAP2420
+static cycle_t notrace omap2420_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap2420_32k_read NULL
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+static cycle_t notrace omap2430_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap2430_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static cycle_t notrace omap34xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap34xx_32k_read NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+static cycle_t notrace omap44xx_32k_read(struct clocksource *cs)
+{
+ return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
+}
+#else
+#define omap44xx_32k_read NULL
+#endif
+
+/*
+ * Kernel assumes that sched_clock can be called early but may not have
+ * things ready yet.
+ */
+static cycle_t notrace omap_32k_read_dummy(struct clocksource *cs)
+{
+ return 0;
+}
+
+static struct clocksource clocksource_32k = {
+ .name = "32k_counter",
+ .rating = 250,
+ .read = omap_32k_read_dummy,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 32768, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 30us and a wrap period of about 36hrs.
+ */
+#define SC_MULT 4000000000u
+#define SC_SHIFT 17
+
+static inline unsigned long long notrace _omap_32k_sched_clock(void)
+{
+ u32 cyc = clocksource_32k.read(&clocksource_32k);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
+}
+
+#ifndef CONFIG_OMAP_MPU_TIMER
+unsigned long long notrace sched_clock(void)
+{
+ return _omap_32k_sched_clock();
+}
+#else
+unsigned long long notrace omap_32k_sched_clock(void)
+{
+ return _omap_32k_sched_clock();
+}
+#endif
+
+static void notrace omap_update_sched_clock(void)
+{
+ u32 cyc = clocksource_32k.read(&clocksource_32k);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+/**
+ * read_persistent_clock - Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer. Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+static struct timespec persistent_ts;
+static cycles_t cycles, last_cycles;
+void read_persistent_clock(struct timespec *ts)
+{
+ unsigned long long nsecs;
+ cycles_t delta;
+ struct timespec *tsp = &persistent_ts;
+
+ last_cycles = cycles;
+ cycles = clocksource_32k.read(&clocksource_32k);
+ delta = cycles - last_cycles;
+
+ nsecs = clocksource_cyc2ns(delta,
+ clocksource_32k.mult, clocksource_32k.shift);
+
+ timespec_add_ns(tsp, nsecs);
+ *ts = *tsp;
+}
+
+int __init omap_init_clocksource_32k(void)
+{
+ static char err[] __initdata = KERN_ERR
+ "%s: can't register clocksource!\n";
+
+ if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
+ struct clk *sync_32k_ick;
+
+ if (cpu_is_omap16xx())
+ clocksource_32k.read = omap16xx_32k_read;
+ else if (cpu_is_omap2420())
+ clocksource_32k.read = omap2420_32k_read;
+ else if (cpu_is_omap2430())
+ clocksource_32k.read = omap2430_32k_read;
+ else if (cpu_is_omap34xx())
+ clocksource_32k.read = omap34xx_32k_read;
+ else if (cpu_is_omap44xx())
+ clocksource_32k.read = omap44xx_32k_read;
+ else
+ return -ENODEV;
+
+ sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
+ if (!IS_ERR(sync_32k_ick))
+ clk_enable(sync_32k_ick);
+
+ offset_32k = clocksource_32k.read(&clocksource_32k);
+
+ if (clocksource_register_hz(&clocksource_32k, 32768))
+ printk(err, clocksource_32k.name);
+
+ init_fixed_sched_clock(&cd, omap_update_sched_clock, 32,
+ 32768, SC_MULT, SC_SHIFT);
+ }
+ return 0;
+}
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
new file mode 100644
index 00000000..da4f68db
--- /dev/null
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -0,0 +1,171 @@
+/*
+ * linux/arch/arm/plat-omap/cpu-omap.c
+ *
+ * CPU frequency scaling for OMAP
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * This program is free software; you can 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/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <plat/clock.h>
+#include <asm/system.h>
+
+#define VERY_HI_RATE 900000000
+
+static struct cpufreq_frequency_table *freq_table;
+
+#ifdef CONFIG_ARCH_OMAP1
+#define MPU_CLK "mpu"
+#else
+#define MPU_CLK "virt_prcm_set"
+#endif
+
+static struct clk *mpu_clk;
+
+/* TODO: Add support for SDRAM timing changes */
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ int ret = 0;
+
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
+ freqs.old = omap_getspeed(0);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
+ freqs.old, freqs.new);
+#endif
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+
+ mpu_clk = clk_get(NULL, MPU_CLK);
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
+
+ clk_init_cpufreq_table(&freq_table);
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ clk_exit_cpufreq_table(&freq_table);
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&omap_driver);
+}
+
+arch_initcall(omap_cpufreq_init);
+
+/*
+ * if ever we want to remove this, upon cleanup call:
+ *
+ * cpufreq_unregister_driver()
+ * cpufreq_frequency_table_put_attr()
+ */
+
diff --git a/arch/arm/plat-omap/debug-devices.c b/arch/arm/plat-omap/debug-devices.c
new file mode 100644
index 00000000..923c9621
--- /dev/null
+++ b/arch/arm/plat-omap/debug-devices.c
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/plat-omap/debug-devices.c
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Modified from mach-omap2/board-h4.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/smc91x.h>
+
+#include <mach/hardware.h>
+
+#include <plat/board.h>
+#include <mach/gpio.h>
+
+
+/* Many OMAP development platforms reuse the same "debug board"; these
+ * platforms include H2, H3, H4, and Perseus2.
+ */
+
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+ .leda = RPC_LED_100_10,
+ .ledb = RPC_LED_TX_RX,
+};
+
+static struct resource smc91x_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+ },
+};
+
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = -1,
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+
+static struct resource led_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device led_device = {
+ .name = "omap_dbg_led",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(led_resources),
+ .resource = led_resources,
+};
+
+static struct platform_device *debug_devices[] __initdata = {
+ &smc91x_device,
+ &led_device,
+ /* ps2 kbd + mouse ports */
+ /* 4 extra uarts */
+ /* 6 input dip switches */
+ /* 8 output pins */
+};
+
+int __init debug_card_init(u32 addr, unsigned gpio)
+{
+ int status;
+
+ smc91x_resources[0].start = addr + 0x300;
+ smc91x_resources[0].end = addr + 0x30f;
+
+ smc91x_resources[1].start = gpio_to_irq(gpio);
+ smc91x_resources[1].end = gpio_to_irq(gpio);
+
+ status = gpio_request(gpio, "SMC91x irq");
+ if (status < 0) {
+ printk(KERN_ERR "GPIO%d unavailable for smc91x IRQ\n", gpio);
+ return status;
+ }
+ gpio_direction_input(gpio);
+
+ led_resources[0].start = addr;
+ led_resources[0].end = addr + SZ_4K - 1;
+
+ return platform_add_devices(debug_devices, ARRAY_SIZE(debug_devices));
+}
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
new file mode 100644
index 00000000..fc05b102
--- /dev/null
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -0,0 +1,317 @@
+/*
+ * linux/arch/arm/plat-omap/debug-leds.c
+ *
+ * Copyright 2003 by Texas Instruments Incorporated
+ *
+ * This program is free software; you can 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/platform_device.h>
+#include <linux/leds.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <plat/fpga.h>
+#include <mach/gpio.h>
+
+
+/* Many OMAP development platforms reuse the same "debug board"; these
+ * platforms include H2, H3, H4, and Perseus2. There are 16 LEDs on the
+ * debug board (all green), accessed through FPGA registers.
+ *
+ * The "surfer" expansion board and H2 sample board also have two-color
+ * green+red LEDs (in parallel), used here for timer and idle indicators
+ * in preference to the ones on the debug board, for a "Disco LED" effect.
+ *
+ * This driver exports either the original ARM LED API, the new generic
+ * one, or both.
+ */
+
+static spinlock_t lock;
+static struct h2p2_dbg_fpga __iomem *fpga;
+static u16 led_state, hw_led_state;
+
+
+#ifdef CONFIG_OMAP_DEBUG_LEDS
+#define new_led_api() 1
+#else
+#define new_led_api() 0
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/* original ARM debug LED API:
+ * - timer and idle leds (some boards use non-FPGA leds here);
+ * - up to 4 generic leds, easily accessed in-kernel (any context)
+ */
+
+#define GPIO_LED_RED 3
+#define GPIO_LED_GREEN OMAP_MPUIO(4)
+
+#define LED_STATE_ENABLED 0x01
+#define LED_STATE_CLAIMED 0x02
+#define LED_TIMER_ON 0x04
+
+#define GPIO_IDLE GPIO_LED_GREEN
+#define GPIO_TIMER GPIO_LED_RED
+
+static void h2p2_dbg_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+
+ if (!(led_state & LED_STATE_ENABLED) && evt != led_start)
+ goto done;
+
+ switch (evt) {
+ case led_start:
+ if (fpga)
+ led_state |= LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ case led_halted:
+ /* all leds off during suspend or shutdown */
+
+ if (!(machine_is_omap_perseus2() || machine_is_omap_h4())) {
+ gpio_set_value(GPIO_TIMER, 0);
+ gpio_set_value(GPIO_IDLE, 0);
+ }
+
+ __raw_writew(~0, &fpga->leds);
+ led_state &= ~LED_STATE_ENABLED;
+ goto done;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ led_state ^= LED_TIMER_ON;
+
+ if (machine_is_omap_perseus2() || machine_is_omap_h4())
+ hw_led_state ^= H2P2_DBG_FPGA_P2_LED_TIMER;
+ else {
+ gpio_set_value(GPIO_TIMER,
+ led_state & LED_TIMER_ON);
+ goto done;
+ }
+
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ /* LED lit iff busy */
+ case led_idle_start:
+ if (machine_is_omap_perseus2() || machine_is_omap_h4())
+ hw_led_state &= ~H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ gpio_set_value(GPIO_IDLE, 1);
+ goto done;
+ }
+
+ break;
+
+ case led_idle_end:
+ if (machine_is_omap_perseus2() || machine_is_omap_h4())
+ hw_led_state |= H2P2_DBG_FPGA_P2_LED_IDLE;
+ else {
+ gpio_set_value(GPIO_IDLE, 0);
+ goto done;
+ }
+
+ break;
+#endif
+
+ case led_green_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_GREEN;
+ break;
+ case led_green_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN;
+ break;
+
+ case led_amber_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_AMBER;
+ break;
+ case led_amber_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER;
+ break;
+
+ case led_red_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_RED;
+ break;
+ case led_red_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_RED;
+ break;
+
+ case led_blue_on:
+ hw_led_state |= H2P2_DBG_FPGA_LED_BLUE;
+ break;
+ case led_blue_off:
+ hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE;
+ break;
+
+ default:
+ break;
+ }
+
+
+ /*
+ * Actually burn the LEDs
+ */
+ if (led_state & LED_STATE_ENABLED)
+ __raw_writew(~hw_led_state, &fpga->leds);
+
+done:
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* "new" LED API
+ * - with syfs access and generic triggering
+ * - not readily accessible to in-kernel drivers
+ */
+
+struct dbg_led {
+ struct led_classdev cdev;
+ u16 mask;
+};
+
+static struct dbg_led dbg_leds[] = {
+ /* REVISIT at least H2 uses different timer & cpu leds... */
+#ifndef CONFIG_LEDS_TIMER
+ { .mask = 1 << 0, .cdev.name = "d4:green",
+ .cdev.default_trigger = "heartbeat", },
+#endif
+#ifndef CONFIG_LEDS_CPU
+ { .mask = 1 << 1, .cdev.name = "d5:green", }, /* !idle */
+#endif
+ { .mask = 1 << 2, .cdev.name = "d6:green", },
+ { .mask = 1 << 3, .cdev.name = "d7:green", },
+
+ { .mask = 1 << 4, .cdev.name = "d8:green", },
+ { .mask = 1 << 5, .cdev.name = "d9:green", },
+ { .mask = 1 << 6, .cdev.name = "d10:green", },
+ { .mask = 1 << 7, .cdev.name = "d11:green", },
+
+ { .mask = 1 << 8, .cdev.name = "d12:green", },
+ { .mask = 1 << 9, .cdev.name = "d13:green", },
+ { .mask = 1 << 10, .cdev.name = "d14:green", },
+ { .mask = 1 << 11, .cdev.name = "d15:green", },
+
+#ifndef CONFIG_LEDS
+ { .mask = 1 << 12, .cdev.name = "d16:green", },
+ { .mask = 1 << 13, .cdev.name = "d17:green", },
+ { .mask = 1 << 14, .cdev.name = "d18:green", },
+ { .mask = 1 << 15, .cdev.name = "d19:green", },
+#endif
+};
+
+static void
+fpga_led_set(struct led_classdev *cdev, enum led_brightness value)
+{
+ struct dbg_led *led = container_of(cdev, struct dbg_led, cdev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&lock, flags);
+ if (value == LED_OFF)
+ hw_led_state &= ~led->mask;
+ else
+ hw_led_state |= led->mask;
+ __raw_writew(~hw_led_state, &fpga->leds);
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static void __init newled_init(struct device *dev)
+{
+ unsigned i;
+ struct dbg_led *led;
+ int status;
+
+ for (i = 0, led = dbg_leds; i < ARRAY_SIZE(dbg_leds); i++, led++) {
+ led->cdev.brightness_set = fpga_led_set;
+ status = led_classdev_register(dev, &led->cdev);
+ if (status < 0)
+ break;
+ }
+ return;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int /* __init */ fpga_probe(struct platform_device *pdev)
+{
+ struct resource *iomem;
+
+ spin_lock_init(&lock);
+
+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!iomem)
+ return -ENODEV;
+
+ fpga = ioremap(iomem->start, H2P2_DBG_FPGA_SIZE);
+ __raw_writew(~0, &fpga->leds);
+
+#ifdef CONFIG_LEDS
+ leds_event = h2p2_dbg_leds_event;
+ leds_event(led_start);
+#endif
+
+ if (new_led_api()) {
+ newled_init(&pdev->dev);
+ }
+
+ return 0;
+}
+
+static int fpga_suspend_noirq(struct device *dev)
+{
+ __raw_writew(~0, &fpga->leds);
+ return 0;
+}
+
+static int fpga_resume_noirq(struct device *dev)
+{
+ __raw_writew(~hw_led_state, &fpga->leds);
+ return 0;
+}
+
+static const struct dev_pm_ops fpga_dev_pm_ops = {
+ .suspend_noirq = fpga_suspend_noirq,
+ .resume_noirq = fpga_resume_noirq,
+};
+
+static struct platform_driver led_driver = {
+ .driver.name = "omap_dbg_led",
+ .driver.pm = &fpga_dev_pm_ops,
+ .probe = fpga_probe,
+};
+
+static int __init fpga_init(void)
+{
+ if (machine_is_omap_h4()
+ || machine_is_omap_h3()
+ || machine_is_omap_h2()
+ || machine_is_omap_perseus2()
+ )
+ return platform_driver_register(&led_driver);
+ return 0;
+}
+fs_initcall(fpga_init);
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
new file mode 100644
index 00000000..ea28f98d
--- /dev/null
+++ b/arch/arm/plat-omap/devices.c
@@ -0,0 +1,298 @@
+/*
+ * linux/arch/arm/plat-omap/devices.c
+ *
+ * Common platform device setup/initialization for OMAP1 and OMAP2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/memblock.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+
+#include <plat/tc.h>
+#include <plat/board.h>
+#include <plat/mmc.h>
+#include <mach/gpio.h>
+#include <plat/menelaus.h>
+#include <plat/mcbsp.h>
+#include <plat/omap44xx.h>
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
+
+static struct platform_device **omap_mcbsp_devices;
+
+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
+ struct omap_mcbsp_platform_data *config, int size)
+{
+ int i;
+
+ omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
+ GFP_KERNEL);
+ if (!omap_mcbsp_devices) {
+ printk(KERN_ERR "Could not register McBSP devices\n");
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ struct platform_device *new_mcbsp;
+ int ret;
+
+ new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
+ if (!new_mcbsp)
+ continue;
+ platform_device_add_resources(new_mcbsp, &res[i * res_count],
+ res_count);
+ new_mcbsp->dev.platform_data = &config[i];
+ ret = platform_device_add(new_mcbsp);
+ if (ret) {
+ platform_device_put(new_mcbsp);
+ continue;
+ }
+ omap_mcbsp_devices[i] = new_mcbsp;
+ }
+}
+
+#else
+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
+ struct omap_mcbsp_platform_data *config, int size)
+{ }
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
+ defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
+
+static struct resource mcpdm_resources[] = {
+ {
+ .name = "mcpdm_mem",
+ .start = OMAP44XX_MCPDM_BASE,
+ .end = OMAP44XX_MCPDM_BASE + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "mcpdm_irq",
+ .start = OMAP44XX_IRQ_MCPDM,
+ .end = OMAP44XX_IRQ_MCPDM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap_mcpdm_device = {
+ .name = "omap-mcpdm",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mcpdm_resources),
+ .resource = mcpdm_resources,
+};
+
+static void omap_init_mcpdm(void)
+{
+ (void) platform_device_register(&omap_mcpdm_device);
+}
+#else
+static inline void omap_init_mcpdm(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+#define OMAP_MMC_NR_RES 2
+
+/*
+ * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
+ */
+int __init omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ struct omap_mmc_platform_data *data)
+{
+ struct platform_device *pdev;
+ struct resource res[OMAP_MMC_NR_RES];
+ int ret;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ return -ENOMEM;
+
+ memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret == 0)
+ ret = platform_device_add_data(pdev, data, sizeof(*data));
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto fail;
+
+ /* return device handle to board setup code */
+ data->dev = &pdev->dev;
+ return 0;
+
+fail:
+ platform_device_put(pdev);
+ return ret;
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_HW_RANDOM_OMAP) || defined(CONFIG_HW_RANDOM_OMAP_MODULE)
+
+#ifdef CONFIG_ARCH_OMAP2
+#define OMAP_RNG_BASE 0x480A0000
+#else
+#define OMAP_RNG_BASE 0xfffe5000
+#endif
+
+static struct resource rng_resources[] = {
+ {
+ .start = OMAP_RNG_BASE,
+ .end = OMAP_RNG_BASE + 0x4f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_rng_device = {
+ .name = "omap_rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rng_resources),
+ .resource = rng_resources,
+};
+
+static void omap_init_rng(void)
+{
+ (void) platform_device_register(&omap_rng_device);
+}
+#else
+static inline void omap_init_rng(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* Numbering for the SPI-capable controllers when used for SPI:
+ * spi = 1
+ * uwire = 2
+ * mmc1..2 = 3..4
+ * mcbsp1..3 = 5..7
+ */
+
+#if defined(CONFIG_SPI_OMAP_UWIRE) || defined(CONFIG_SPI_OMAP_UWIRE_MODULE)
+
+#define OMAP_UWIRE_BASE 0xfffb3000
+
+static struct resource uwire_resources[] = {
+ {
+ .start = OMAP_UWIRE_BASE,
+ .end = OMAP_UWIRE_BASE + 0x20,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap_uwire_device = {
+ .name = "omap_uwire",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(uwire_resources),
+ .resource = uwire_resources,
+};
+
+static void omap_init_uwire(void)
+{
+ /* FIXME define and use a boot tag; not all boards will be hooking
+ * up devices to the microwire controller, and multi-board configs
+ * mean that CONFIG_SPI_OMAP_UWIRE may be configured anyway...
+ */
+
+ /* board-specific code must configure chipselects (only a few
+ * are normally used) and SCLK/SDI/SDO (each has two choices).
+ */
+ (void) platform_device_register(&omap_uwire_device);
+}
+#else
+static inline void omap_init_uwire(void) {}
+#endif
+
+#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
+
+static phys_addr_t omap_dsp_phys_mempool_base;
+
+void __init omap_dsp_reserve_sdram_memblock(void)
+{
+ phys_addr_t size = CONFIG_TIDSPBRIDGE_MEMPOOL_SIZE;
+ phys_addr_t paddr;
+
+ if (!size)
+ return;
+
+ paddr = memblock_alloc(size, SZ_1M);
+ if (!paddr) {
+ pr_err("%s: failed to reserve %x bytes\n",
+ __func__, size);
+ return;
+ }
+ memblock_free(paddr, size);
+ memblock_remove(paddr, size);
+
+ omap_dsp_phys_mempool_base = paddr;
+}
+
+phys_addr_t omap_dsp_get_mempool_base(void)
+{
+ return omap_dsp_phys_mempool_base;
+}
+EXPORT_SYMBOL(omap_dsp_get_mempool_base);
+#endif
+
+/*
+ * This gets called after board-specific INIT_MACHINE, and initializes most
+ * on-chip peripherals accessible on this board (except for few like USB):
+ *
+ * (a) Does any "standard config" pin muxing needed. Board-specific
+ * code will have muxed GPIO pins and done "nonstandard" setup;
+ * that code could live in the boot loader.
+ * (b) Populating board-specific platform_data with the data drivers
+ * rely on to handle wiring variations.
+ * (c) Creating platform devices as meaningful on this board and
+ * with this kernel configuration.
+ *
+ * Claiming GPIOs, and setting their direction and initial values, is the
+ * responsibility of the device drivers. So is responding to probe().
+ *
+ * Board-specific knowledge like creating devices or pin setup is to be
+ * kept out of drivers as much as possible. In particular, pin setup
+ * may be handled by the boot loader, and drivers should expect it will
+ * normally have been done by the time they're probed.
+ */
+static int __init omap_init_devices(void)
+{
+ /* please keep these calls, and their implementations above,
+ * in alphabetical order so they're easier to sort through.
+ */
+ omap_init_rng();
+ omap_init_mcpdm();
+ omap_init_uwire();
+ return 0;
+}
+arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
new file mode 100644
index 00000000..c22217c2
--- /dev/null
+++ b/arch/arm/plat-omap/dma.c
@@ -0,0 +1,2143 @@
+/*
+ * linux/arch/arm/plat-omap/dma.c
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
+ * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
+ * Graphics DMA and LCD DMA graphics tranformations
+ * by Imre Deak <imre.deak@nokia.com>
+ * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
+ * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
+ * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Support functions for the OMAP internal DMA channels.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Converted DMA library into DMA platform driver.
+ * - G, Manjunath Kondaiah <manjugk@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <plat/dma.h>
+
+#include <plat/tc.h>
+
+#undef DEBUG
+
+#ifndef CONFIG_ARCH_OMAP1
+enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED,
+ DMA_CH_QUEUED, DMA_CH_NOTSTARTED, DMA_CH_PAUSED, DMA_CH_LINK_ENABLED
+};
+
+enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
+#endif
+
+#define OMAP_DMA_ACTIVE 0x01
+#define OMAP2_DMA_CSR_CLEAR_MASK 0xffffffff
+
+#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
+
+static struct omap_system_dma_plat_info *p;
+static struct omap_dma_dev_attr *d;
+
+static int enable_1510_mode;
+static u32 errata;
+
+static struct omap_dma_global_context_registers {
+ u32 dma_irqenable_l0;
+ u32 dma_ocp_sysconfig;
+ u32 dma_gcr;
+} omap_dma_global_context;
+
+struct dma_link_info {
+ int *linked_dmach_q;
+ int no_of_lchs_linked;
+
+ int q_count;
+ int q_tail;
+ int q_head;
+
+ int chain_state;
+ int chain_mode;
+
+};
+
+static struct dma_link_info *dma_linked_lch;
+
+#ifndef CONFIG_ARCH_OMAP1
+
+/* Chain handling macros */
+#define OMAP_DMA_CHAIN_QINIT(chain_id) \
+ do { \
+ dma_linked_lch[chain_id].q_head = \
+ dma_linked_lch[chain_id].q_tail = \
+ dma_linked_lch[chain_id].q_count = 0; \
+ } while (0)
+#define OMAP_DMA_CHAIN_QFULL(chain_id) \
+ (dma_linked_lch[chain_id].no_of_lchs_linked == \
+ dma_linked_lch[chain_id].q_count)
+#define OMAP_DMA_CHAIN_QLAST(chain_id) \
+ do { \
+ ((dma_linked_lch[chain_id].no_of_lchs_linked-1) == \
+ dma_linked_lch[chain_id].q_count) \
+ } while (0)
+#define OMAP_DMA_CHAIN_QEMPTY(chain_id) \
+ (0 == dma_linked_lch[chain_id].q_count)
+#define __OMAP_DMA_CHAIN_INCQ(end) \
+ ((end) = ((end)+1) % dma_linked_lch[chain_id].no_of_lchs_linked)
+#define OMAP_DMA_CHAIN_INCQHEAD(chain_id) \
+ do { \
+ __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_head); \
+ dma_linked_lch[chain_id].q_count--; \
+ } while (0)
+
+#define OMAP_DMA_CHAIN_INCQTAIL(chain_id) \
+ do { \
+ __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_tail); \
+ dma_linked_lch[chain_id].q_count++; \
+ } while (0)
+#endif
+
+static int dma_lch_count;
+static int dma_chan_count;
+static int omap_dma_reserve_channels;
+
+static spinlock_t dma_chan_lock;
+static struct omap_dma_lch *dma_chan;
+
+static inline void disable_lnk(int lch);
+static void omap_disable_channel_irq(int lch);
+static inline void omap_enable_channel_irq(int lch);
+
+#define REVISIT_24XX() printk(KERN_ERR "FIXME: no %s on 24xx\n", \
+ __func__);
+
+#ifdef CONFIG_ARCH_OMAP15XX
+/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
+static int omap_dma_in_1510_mode(void)
+{
+ return enable_1510_mode;
+}
+#else
+#define omap_dma_in_1510_mode() 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1
+static inline int get_gdma_dev(int req)
+{
+ u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
+ int shift = ((req - 1) % 5) * 6;
+
+ return ((omap_readl(reg) >> shift) & 0x3f) + 1;
+}
+
+static inline void set_gdma_dev(int req, int dev)
+{
+ u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
+ int shift = ((req - 1) % 5) * 6;
+ u32 l;
+
+ l = omap_readl(reg);
+ l &= ~(0x3f << shift);
+ l |= (dev - 1) << shift;
+ omap_writel(l, reg);
+}
+#else
+#define set_gdma_dev(req, dev) do {} while (0)
+#endif
+
+void omap_set_dma_priority(int lch, int dst_port, int priority)
+{
+ unsigned long reg;
+ u32 l;
+
+ if (cpu_class_is_omap1()) {
+ switch (dst_port) {
+ case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
+ reg = OMAP_TC_OCPT1_PRIOR;
+ break;
+ case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
+ reg = OMAP_TC_OCPT2_PRIOR;
+ break;
+ case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
+ reg = OMAP_TC_EMIFF_PRIOR;
+ break;
+ case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
+ reg = OMAP_TC_EMIFS_PRIOR;
+ break;
+ default:
+ BUG();
+ return;
+ }
+ l = omap_readl(reg);
+ l &= ~(0xf << 8);
+ l |= (priority & 0xf) << 8;
+ omap_writel(l, reg);
+ }
+
+ if (cpu_class_is_omap2()) {
+ u32 ccr;
+
+ ccr = p->dma_read(CCR, lch);
+ if (priority)
+ ccr |= (1 << 6);
+ else
+ ccr &= ~(1 << 6);
+ p->dma_write(ccr, CCR, lch);
+ }
+}
+EXPORT_SYMBOL(omap_set_dma_priority);
+
+void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
+ int frame_count, int sync_mode,
+ int dma_trigger, int src_or_dst_synch)
+{
+ u32 l;
+
+ l = p->dma_read(CSDP, lch);
+ l &= ~0x03;
+ l |= data_type;
+ p->dma_write(l, CSDP, lch);
+
+ if (cpu_class_is_omap1()) {
+ u16 ccr;
+
+ ccr = p->dma_read(CCR, lch);
+ ccr &= ~(1 << 5);
+ if (sync_mode == OMAP_DMA_SYNC_FRAME)
+ ccr |= 1 << 5;
+ p->dma_write(ccr, CCR, lch);
+
+ ccr = p->dma_read(CCR2, lch);
+ ccr &= ~(1 << 2);
+ if (sync_mode == OMAP_DMA_SYNC_BLOCK)
+ ccr |= 1 << 2;
+ p->dma_write(ccr, CCR2, lch);
+ }
+
+ if (cpu_class_is_omap2() && dma_trigger) {
+ u32 val;
+
+ val = p->dma_read(CCR, lch);
+
+ /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
+ val &= ~((1 << 23) | (3 << 19) | 0x1f);
+ val |= (dma_trigger & ~0x1f) << 14;
+ val |= dma_trigger & 0x1f;
+
+ if (sync_mode & OMAP_DMA_SYNC_FRAME)
+ val |= 1 << 5;
+ else
+ val &= ~(1 << 5);
+
+ if (sync_mode & OMAP_DMA_SYNC_BLOCK)
+ val |= 1 << 18;
+ else
+ val &= ~(1 << 18);
+
+ if (src_or_dst_synch == OMAP_DMA_DST_SYNC_PREFETCH) {
+ val &= ~(1 << 24); /* dest synch */
+ val |= (1 << 23); /* Prefetch */
+ } else if (src_or_dst_synch) {
+ val |= 1 << 24; /* source synch */
+ } else {
+ val &= ~(1 << 24); /* dest synch */
+ }
+ p->dma_write(val, CCR, lch);
+ }
+
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_transfer_params);
+
+void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
+{
+ BUG_ON(omap_dma_in_1510_mode());
+
+ if (cpu_class_is_omap1()) {
+ u16 w;
+
+ w = p->dma_read(CCR2, lch);
+ w &= ~0x03;
+
+ switch (mode) {
+ case OMAP_DMA_CONSTANT_FILL:
+ w |= 0x01;
+ break;
+ case OMAP_DMA_TRANSPARENT_COPY:
+ w |= 0x02;
+ break;
+ case OMAP_DMA_COLOR_DIS:
+ break;
+ default:
+ BUG();
+ }
+ p->dma_write(w, CCR2, lch);
+
+ w = p->dma_read(LCH_CTRL, lch);
+ w &= ~0x0f;
+ /* Default is channel type 2D */
+ if (mode) {
+ p->dma_write(color, COLOR, lch);
+ w |= 1; /* Channel type G */
+ }
+ p->dma_write(w, LCH_CTRL, lch);
+ }
+
+ if (cpu_class_is_omap2()) {
+ u32 val;
+
+ val = p->dma_read(CCR, lch);
+ val &= ~((1 << 17) | (1 << 16));
+
+ switch (mode) {
+ case OMAP_DMA_CONSTANT_FILL:
+ val |= 1 << 16;
+ break;
+ case OMAP_DMA_TRANSPARENT_COPY:
+ val |= 1 << 17;
+ break;
+ case OMAP_DMA_COLOR_DIS:
+ break;
+ default:
+ BUG();
+ }
+ p->dma_write(val, CCR, lch);
+
+ color &= 0xffffff;
+ p->dma_write(color, COLOR, lch);
+ }
+}
+EXPORT_SYMBOL(omap_set_dma_color_mode);
+
+void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
+{
+ if (cpu_class_is_omap2()) {
+ u32 csdp;
+
+ csdp = p->dma_read(CSDP, lch);
+ csdp &= ~(0x3 << 16);
+ csdp |= (mode << 16);
+ p->dma_write(csdp, CSDP, lch);
+ }
+}
+EXPORT_SYMBOL(omap_set_dma_write_mode);
+
+void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
+{
+ if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
+ u32 l;
+
+ l = p->dma_read(LCH_CTRL, lch);
+ l &= ~0x7;
+ l |= mode;
+ p->dma_write(l, LCH_CTRL, lch);
+ }
+}
+EXPORT_SYMBOL(omap_set_dma_channel_mode);
+
+/* Note that src_port is only for omap1 */
+void omap_set_dma_src_params(int lch, int src_port, int src_amode,
+ unsigned long src_start,
+ int src_ei, int src_fi)
+{
+ u32 l;
+
+ if (cpu_class_is_omap1()) {
+ u16 w;
+
+ w = p->dma_read(CSDP, lch);
+ w &= ~(0x1f << 2);
+ w |= src_port << 2;
+ p->dma_write(w, CSDP, lch);
+ }
+
+ l = p->dma_read(CCR, lch);
+ l &= ~(0x03 << 12);
+ l |= src_amode << 12;
+ p->dma_write(l, CCR, lch);
+
+ p->dma_write(src_start, CSSA, lch);
+
+ p->dma_write(src_ei, CSEI, lch);
+ p->dma_write(src_fi, CSFI, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_src_params);
+
+void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
+{
+ omap_set_dma_transfer_params(lch, params->data_type,
+ params->elem_count, params->frame_count,
+ params->sync_mode, params->trigger,
+ params->src_or_dst_synch);
+ omap_set_dma_src_params(lch, params->src_port,
+ params->src_amode, params->src_start,
+ params->src_ei, params->src_fi);
+
+ omap_set_dma_dest_params(lch, params->dst_port,
+ params->dst_amode, params->dst_start,
+ params->dst_ei, params->dst_fi);
+ if (params->read_prio || params->write_prio)
+ omap_dma_set_prio_lch(lch, params->read_prio,
+ params->write_prio);
+}
+EXPORT_SYMBOL(omap_set_dma_params);
+
+void omap_set_dma_src_index(int lch, int eidx, int fidx)
+{
+ if (cpu_class_is_omap2())
+ return;
+
+ p->dma_write(eidx, CSEI, lch);
+ p->dma_write(fidx, CSFI, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_src_index);
+
+void omap_set_dma_src_data_pack(int lch, int enable)
+{
+ u32 l;
+
+ l = p->dma_read(CSDP, lch);
+ l &= ~(1 << 6);
+ if (enable)
+ l |= (1 << 6);
+ p->dma_write(l, CSDP, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_src_data_pack);
+
+void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
+{
+ unsigned int burst = 0;
+ u32 l;
+
+ l = p->dma_read(CSDP, lch);
+ l &= ~(0x03 << 7);
+
+ switch (burst_mode) {
+ case OMAP_DMA_DATA_BURST_DIS:
+ break;
+ case OMAP_DMA_DATA_BURST_4:
+ if (cpu_class_is_omap2())
+ burst = 0x1;
+ else
+ burst = 0x2;
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ if (cpu_class_is_omap2()) {
+ burst = 0x2;
+ break;
+ }
+ /*
+ * not supported by current hardware on OMAP1
+ * w |= (0x03 << 7);
+ * fall through
+ */
+ case OMAP_DMA_DATA_BURST_16:
+ if (cpu_class_is_omap2()) {
+ burst = 0x3;
+ break;
+ }
+ /*
+ * OMAP1 don't support burst 16
+ * fall through
+ */
+ default:
+ BUG();
+ }
+
+ l |= (burst << 7);
+ p->dma_write(l, CSDP, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
+
+/* Note that dest_port is only for OMAP1 */
+void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
+ unsigned long dest_start,
+ int dst_ei, int dst_fi)
+{
+ u32 l;
+
+ if (cpu_class_is_omap1()) {
+ l = p->dma_read(CSDP, lch);
+ l &= ~(0x1f << 9);
+ l |= dest_port << 9;
+ p->dma_write(l, CSDP, lch);
+ }
+
+ l = p->dma_read(CCR, lch);
+ l &= ~(0x03 << 14);
+ l |= dest_amode << 14;
+ p->dma_write(l, CCR, lch);
+
+ p->dma_write(dest_start, CDSA, lch);
+
+ p->dma_write(dst_ei, CDEI, lch);
+ p->dma_write(dst_fi, CDFI, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_dest_params);
+
+void omap_set_dma_dest_index(int lch, int eidx, int fidx)
+{
+ if (cpu_class_is_omap2())
+ return;
+
+ p->dma_write(eidx, CDEI, lch);
+ p->dma_write(fidx, CDFI, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_dest_index);
+
+void omap_set_dma_dest_data_pack(int lch, int enable)
+{
+ u32 l;
+
+ l = p->dma_read(CSDP, lch);
+ l &= ~(1 << 13);
+ if (enable)
+ l |= 1 << 13;
+ p->dma_write(l, CSDP, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
+
+void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
+{
+ unsigned int burst = 0;
+ u32 l;
+
+ l = p->dma_read(CSDP, lch);
+ l &= ~(0x03 << 14);
+
+ switch (burst_mode) {
+ case OMAP_DMA_DATA_BURST_DIS:
+ break;
+ case OMAP_DMA_DATA_BURST_4:
+ if (cpu_class_is_omap2())
+ burst = 0x1;
+ else
+ burst = 0x2;
+ break;
+ case OMAP_DMA_DATA_BURST_8:
+ if (cpu_class_is_omap2())
+ burst = 0x2;
+ else
+ burst = 0x3;
+ break;
+ case OMAP_DMA_DATA_BURST_16:
+ if (cpu_class_is_omap2()) {
+ burst = 0x3;
+ break;
+ }
+ /*
+ * OMAP1 don't support burst 16
+ * fall through
+ */
+ default:
+ printk(KERN_ERR "Invalid DMA burst mode\n");
+ BUG();
+ return;
+ }
+ l |= (burst << 14);
+ p->dma_write(l, CSDP, lch);
+}
+EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
+
+static inline void omap_enable_channel_irq(int lch)
+{
+ u32 status;
+
+ /* Clear CSR */
+ if (cpu_class_is_omap1())
+ status = p->dma_read(CSR, lch);
+ else if (cpu_class_is_omap2())
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
+
+ /* Enable some nice interrupts. */
+ p->dma_write(dma_chan[lch].enabled_irqs, CICR, lch);
+}
+
+static void omap_disable_channel_irq(int lch)
+{
+ if (cpu_class_is_omap2())
+ p->dma_write(0, CICR, lch);
+}
+
+void omap_enable_dma_irq(int lch, u16 bits)
+{
+ dma_chan[lch].enabled_irqs |= bits;
+}
+EXPORT_SYMBOL(omap_enable_dma_irq);
+
+void omap_disable_dma_irq(int lch, u16 bits)
+{
+ dma_chan[lch].enabled_irqs &= ~bits;
+}
+EXPORT_SYMBOL(omap_disable_dma_irq);
+
+static inline void enable_lnk(int lch)
+{
+ u32 l;
+
+ l = p->dma_read(CLNK_CTRL, lch);
+
+ if (cpu_class_is_omap1())
+ l &= ~(1 << 14);
+
+ /* Set the ENABLE_LNK bits */
+ if (dma_chan[lch].next_lch != -1)
+ l = dma_chan[lch].next_lch | (1 << 15);
+
+#ifndef CONFIG_ARCH_OMAP1
+ if (cpu_class_is_omap2())
+ if (dma_chan[lch].next_linked_ch != -1)
+ l = dma_chan[lch].next_linked_ch | (1 << 15);
+#endif
+
+ p->dma_write(l, CLNK_CTRL, lch);
+}
+
+static inline void disable_lnk(int lch)
+{
+ u32 l;
+
+ l = p->dma_read(CLNK_CTRL, lch);
+
+ /* Disable interrupts */
+ if (cpu_class_is_omap1()) {
+ p->dma_write(0, CICR, lch);
+ /* Set the STOP_LNK bit */
+ l |= 1 << 14;
+ }
+
+ if (cpu_class_is_omap2()) {
+ omap_disable_channel_irq(lch);
+ /* Clear the ENABLE_LNK bit */
+ l &= ~(1 << 15);
+ }
+
+ p->dma_write(l, CLNK_CTRL, lch);
+ dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+}
+
+static inline void omap2_enable_irq_lch(int lch)
+{
+ u32 val;
+ unsigned long flags;
+
+ if (!cpu_class_is_omap2())
+ return;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ val = p->dma_read(IRQENABLE_L0, lch);
+ val |= 1 << lch;
+ p->dma_write(val, IRQENABLE_L0, lch);
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+}
+
+static inline void omap2_disable_irq_lch(int lch)
+{
+ u32 val;
+ unsigned long flags;
+
+ if (!cpu_class_is_omap2())
+ return;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ val = p->dma_read(IRQENABLE_L0, lch);
+ val &= ~(1 << lch);
+ p->dma_write(val, IRQENABLE_L0, lch);
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+}
+
+int omap_request_dma(int dev_id, const char *dev_name,
+ void (*callback)(int lch, u16 ch_status, void *data),
+ void *data, int *dma_ch_out)
+{
+ int ch, free_ch = -1;
+ unsigned long flags;
+ struct omap_dma_lch *chan;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ for (ch = 0; ch < dma_chan_count; ch++) {
+ if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
+ free_ch = ch;
+ if (dev_id == 0)
+ break;
+ }
+ }
+ if (free_ch == -1) {
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+ return -EBUSY;
+ }
+ chan = dma_chan + free_ch;
+ chan->dev_id = dev_id;
+
+ if (p->clear_lch_regs)
+ p->clear_lch_regs(free_ch);
+
+ if (cpu_class_is_omap2())
+ omap_clear_dma(free_ch);
+
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+ chan->dev_name = dev_name;
+ chan->callback = callback;
+ chan->data = data;
+ chan->flags = 0;
+
+#ifndef CONFIG_ARCH_OMAP1
+ if (cpu_class_is_omap2()) {
+ chan->chain_id = -1;
+ chan->next_linked_ch = -1;
+ }
+#endif
+
+ chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
+
+ if (cpu_class_is_omap1())
+ chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
+ else if (cpu_class_is_omap2())
+ chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
+ OMAP2_DMA_TRANS_ERR_IRQ;
+
+ if (cpu_is_omap16xx()) {
+ /* If the sync device is set, configure it dynamically. */
+ if (dev_id != 0) {
+ set_gdma_dev(free_ch + 1, dev_id);
+ dev_id = free_ch + 1;
+ }
+ /*
+ * Disable the 1510 compatibility mode and set the sync device
+ * id.
+ */
+ p->dma_write(dev_id | (1 << 10), CCR, free_ch);
+ } else if (cpu_is_omap7xx() || cpu_is_omap15xx()) {
+ p->dma_write(dev_id, CCR, free_ch);
+ }
+
+ if (cpu_class_is_omap2()) {
+ omap2_enable_irq_lch(free_ch);
+ omap_enable_channel_irq(free_ch);
+ /* Clear the CSR register and IRQ status register */
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, free_ch);
+ p->dma_write(1 << free_ch, IRQSTATUS_L0, 0);
+ }
+
+ *dma_ch_out = free_ch;
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_request_dma);
+
+void omap_free_dma(int lch)
+{
+ unsigned long flags;
+
+ if (dma_chan[lch].dev_id == -1) {
+ pr_err("omap_dma: trying to free unallocated DMA channel %d\n",
+ lch);
+ return;
+ }
+
+ if (cpu_class_is_omap1()) {
+ /* Disable all DMA interrupts for the channel. */
+ p->dma_write(0, CICR, lch);
+ /* Make sure the DMA transfer is stopped. */
+ p->dma_write(0, CCR, lch);
+ }
+
+ if (cpu_class_is_omap2()) {
+ omap2_disable_irq_lch(lch);
+
+ /* Clear the CSR register and IRQ status register */
+ p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
+ p->dma_write(1 << lch, IRQSTATUS_L0, lch);
+
+ /* Disable all DMA interrupts for the channel. */
+ p->dma_write(0, CICR, lch);
+
+ /* Make sure the DMA transfer is stopped. */
+ p->dma_write(0, CCR, lch);
+ omap_clear_dma(lch);
+ }
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ dma_chan[lch].dev_id = -1;
+ dma_chan[lch].next_lch = -1;
+ dma_chan[lch].callback = NULL;
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+}
+EXPORT_SYMBOL(omap_free_dma);
+
+/**
+ * @brief omap_dma_set_global_params : Set global priority settings for dma
+ *
+ * @param arb_rate
+ * @param max_fifo_depth
+ * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM
+ * DMA_THREAD_RESERVE_ONET
+ * DMA_THREAD_RESERVE_TWOT
+ * DMA_THREAD_RESERVE_THREET
+ */
+void
+omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
+{
+ u32 reg;
+
+ if (!cpu_class_is_omap2()) {
+ printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __func__);
+ return;
+ }
+
+ if (max_fifo_depth == 0)
+ max_fifo_depth = 1;
+ if (arb_rate == 0)
+ arb_rate = 1;
+
+ reg = 0xff & max_fifo_depth;
+ reg |= (0x3 & tparams) << 12;
+ reg |= (arb_rate & 0xff) << 16;
+
+ p->dma_write(reg, GCR, 0);
+}
+EXPORT_SYMBOL(omap_dma_set_global_params);
+
+/**
+ * @brief omap_dma_set_prio_lch : Set channel wise priority settings
+ *
+ * @param lch
+ * @param read_prio - Read priority
+ * @param write_prio - Write priority
+ * Both of the above can be set with one of the following values :
+ * DMA_CH_PRIO_HIGH/DMA_CH_PRIO_LOW
+ */
+int
+omap_dma_set_prio_lch(int lch, unsigned char read_prio,
+ unsigned char write_prio)
+{
+ u32 l;
+
+ if (unlikely((lch < 0 || lch >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid channel id\n");
+ return -EINVAL;
+ }
+ l = p->dma_read(CCR, lch);
+ l &= ~((1 << 6) | (1 << 26));
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
+ l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
+ else
+ l |= ((read_prio & 0x1) << 6);
+
+ p->dma_write(l, CCR, lch);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_dma_set_prio_lch);
+
+/*
+ * Clears any DMA state so the DMA engine is ready to restart with new buffers
+ * through omap_start_dma(). Any buffers in flight are discarded.
+ */
+void omap_clear_dma(int lch)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ p->clear_dma(lch);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(omap_clear_dma);
+
+void omap_start_dma(int lch)
+{
+ u32 l;
+
+ /*
+ * The CPC/CDAC register needs to be initialized to zero
+ * before starting dma transfer.
+ */
+ if (cpu_is_omap15xx())
+ p->dma_write(0, CPC, lch);
+ else
+ p->dma_write(0, CDAC, lch);
+
+ if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+ int next_lch, cur_lch;
+ char dma_chan_link_map[dma_lch_count];
+
+ dma_chan_link_map[lch] = 1;
+ /* Set the link register of the first channel */
+ enable_lnk(lch);
+
+ memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+ cur_lch = dma_chan[lch].next_lch;
+ do {
+ next_lch = dma_chan[cur_lch].next_lch;
+
+ /* The loop case: we've been here already */
+ if (dma_chan_link_map[cur_lch])
+ break;
+ /* Mark the current channel */
+ dma_chan_link_map[cur_lch] = 1;
+
+ enable_lnk(cur_lch);
+ omap_enable_channel_irq(cur_lch);
+
+ cur_lch = next_lch;
+ } while (next_lch != -1);
+ } else if (IS_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS))
+ p->dma_write(lch, CLNK_CTRL, lch);
+
+ omap_enable_channel_irq(lch);
+
+ l = p->dma_read(CCR, lch);
+
+ if (IS_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING))
+ l |= OMAP_DMA_CCR_BUFFERING_DISABLE;
+ l |= OMAP_DMA_CCR_EN;
+
+ p->dma_write(l, CCR, lch);
+
+ dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+}
+EXPORT_SYMBOL(omap_start_dma);
+
+void omap_stop_dma(int lch)
+{
+ u32 l;
+
+ /* Disable all interrupts on the channel */
+ if (cpu_class_is_omap1())
+ p->dma_write(0, CICR, lch);
+
+ l = p->dma_read(CCR, lch);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i541) &&
+ (l & OMAP_DMA_CCR_SEL_SRC_DST_SYNC)) {
+ int i = 0;
+ u32 sys_cf;
+
+ /* Configure No-Standby */
+ l = p->dma_read(OCP_SYSCONFIG, lch);
+ sys_cf = l;
+ l &= ~DMA_SYSCONFIG_MIDLEMODE_MASK;
+ l |= DMA_SYSCONFIG_MIDLEMODE(DMA_IDLEMODE_NO_IDLE);
+ p->dma_write(l , OCP_SYSCONFIG, 0);
+
+ l = p->dma_read(CCR, lch);
+ l &= ~OMAP_DMA_CCR_EN;
+ p->dma_write(l, CCR, lch);
+
+ /* Wait for sDMA FIFO drain */
+ l = p->dma_read(CCR, lch);
+ while (i < 100 && (l & (OMAP_DMA_CCR_RD_ACTIVE |
+ OMAP_DMA_CCR_WR_ACTIVE))) {
+ udelay(5);
+ i++;
+ l = p->dma_read(CCR, lch);
+ }
+ if (i >= 100)
+ printk(KERN_ERR "DMA drain did not complete on "
+ "lch %d\n", lch);
+ /* Restore OCP_SYSCONFIG */
+ p->dma_write(sys_cf, OCP_SYSCONFIG, lch);
+ } else {
+ l &= ~OMAP_DMA_CCR_EN;
+ p->dma_write(l, CCR, lch);
+ }
+
+ if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
+ int next_lch, cur_lch = lch;
+ char dma_chan_link_map[dma_lch_count];
+
+ memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
+ do {
+ /* The loop case: we've been here already */
+ if (dma_chan_link_map[cur_lch])
+ break;
+ /* Mark the current channel */
+ dma_chan_link_map[cur_lch] = 1;
+
+ disable_lnk(cur_lch);
+
+ next_lch = dma_chan[cur_lch].next_lch;
+ cur_lch = next_lch;
+ } while (next_lch != -1);
+ }
+
+ dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
+}
+EXPORT_SYMBOL(omap_stop_dma);
+
+/*
+ * Allows changing the DMA callback function or data. This may be needed if
+ * the driver shares a single DMA channel for multiple dma triggers.
+ */
+int omap_set_dma_callback(int lch,
+ void (*callback)(int lch, u16 ch_status, void *data),
+ void *data)
+{
+ unsigned long flags;
+
+ if (lch < 0)
+ return -ENODEV;
+
+ spin_lock_irqsave(&dma_chan_lock, flags);
+ if (dma_chan[lch].dev_id == -1) {
+ printk(KERN_ERR "DMA callback for not set for free channel\n");
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+ return -EINVAL;
+ }
+ dma_chan[lch].callback = callback;
+ dma_chan[lch].data = data;
+ spin_unlock_irqrestore(&dma_chan_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_set_dma_callback);
+
+/*
+ * Returns current physical source address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CSSA_L register overflow between the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_src_pos(int lch)
+{
+ dma_addr_t offset = 0;
+
+ if (cpu_is_omap15xx())
+ offset = p->dma_read(CPC, lch);
+ else
+ offset = p->dma_read(CSAC, lch);
+
+ if (IS_DMA_ERRATA(DMA_ERRATA_3_3) && offset == 0)
+ offset = p->dma_read(CSAC, lch);
+
+ if (cpu_class_is_omap1())
+ offset |= (p->dma_read(CSSA, lch) & 0xFFFF0000);
+
+ return offset;
+}
+EXPORT_SYMBOL(omap_get_dma_src_pos);
+
+/*
+ * Returns current physical destination address for the given DMA channel.
+ * If the channel is running the caller must disable interrupts prior calling
+ * this function and process the returned value before re-enabling interrupt to
+ * prevent races with the interrupt handler. Note that in continuous mode there
+ * is a chance for CDSA_L register overflow between the two reads resulting
+ * in incorrect return value.
+ */
+dma_addr_t omap_get_dma_dst_pos(int lch)
+{
+ dma_addr_t offset = 0;
+
+ if (cpu_is_omap15xx())
+ offset = p->dma_read(CPC, lch);
+ else
+ offset = p->dma_read(CDAC, lch);
+
+ /*
+ * omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is
+ * read before the DMA controller finished disabling the channel.
+ */
+ if (!cpu_is_omap15xx() && offset == 0)
+ offset = p->dma_read(CDAC, lch);
+
+ if (cpu_class_is_omap1())
+ offset |= (p->dma_read(CDSA, lch) & 0xFFFF0000);
+
+ return offset;
+}
+EXPORT_SYMBOL(omap_get_dma_dst_pos);
+
+int omap_get_dma_active_status(int lch)
+{
+ return (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN) != 0;
+}
+EXPORT_SYMBOL(omap_get_dma_active_status);
+
+int omap_dma_running(void)
+{
+ int lch;
+
+ if (cpu_class_is_omap1())
+ if (omap_lcd_dma_running())
+ return 1;
+
+ for (lch = 0; lch < dma_chan_count; lch++)
+ if (p->dma_read(CCR, lch) & OMAP_DMA_CCR_EN)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * lch_queue DMA will start right after lch_head one is finished.
+ * For this DMA link to start, you still need to start (see omap_start_dma)
+ * the first one. That will fire up the entire queue.
+ */
+void omap_dma_link_lch(int lch_head, int lch_queue)
+{
+ if (omap_dma_in_1510_mode()) {
+ if (lch_head == lch_queue) {
+ p->dma_write(p->dma_read(CCR, lch_head) | (3 << 8),
+ CCR, lch_head);
+ return;
+ }
+ printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
+ BUG();
+ return;
+ }
+
+ if ((dma_chan[lch_head].dev_id == -1) ||
+ (dma_chan[lch_queue].dev_id == -1)) {
+ printk(KERN_ERR "omap_dma: trying to link "
+ "non requested channels\n");
+ dump_stack();
+ }
+
+ dma_chan[lch_head].next_lch = lch_queue;
+}
+EXPORT_SYMBOL(omap_dma_link_lch);
+
+/*
+ * Once the DMA queue is stopped, we can destroy it.
+ */
+void omap_dma_unlink_lch(int lch_head, int lch_queue)
+{
+ if (omap_dma_in_1510_mode()) {
+ if (lch_head == lch_queue) {
+ p->dma_write(p->dma_read(CCR, lch_head) & ~(3 << 8),
+ CCR, lch_head);
+ return;
+ }
+ printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
+ BUG();
+ return;
+ }
+
+ if (dma_chan[lch_head].next_lch != lch_queue ||
+ dma_chan[lch_head].next_lch == -1) {
+ printk(KERN_ERR "omap_dma: trying to unlink "
+ "non linked channels\n");
+ dump_stack();
+ }
+
+ if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
+ (dma_chan[lch_queue].flags & OMAP_DMA_ACTIVE)) {
+ printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
+ "before unlinking\n");
+ dump_stack();
+ }
+
+ dma_chan[lch_head].next_lch = -1;
+}
+EXPORT_SYMBOL(omap_dma_unlink_lch);
+
+#ifndef CONFIG_ARCH_OMAP1
+/* Create chain of DMA channesls */
+static void create_dma_lch_chain(int lch_head, int lch_queue)
+{
+ u32 l;
+
+ /* Check if this is the first link in chain */
+ if (dma_chan[lch_head].next_linked_ch == -1) {
+ dma_chan[lch_head].next_linked_ch = lch_queue;
+ dma_chan[lch_head].prev_linked_ch = lch_queue;
+ dma_chan[lch_queue].next_linked_ch = lch_head;
+ dma_chan[lch_queue].prev_linked_ch = lch_head;
+ }
+
+ /* a link exists, link the new channel in circular chain */
+ else {
+ dma_chan[lch_queue].next_linked_ch =
+ dma_chan[lch_head].next_linked_ch;
+ dma_chan[lch_queue].prev_linked_ch = lch_head;
+ dma_chan[lch_head].next_linked_ch = lch_queue;
+ dma_chan[dma_chan[lch_queue].next_linked_ch].prev_linked_ch =
+ lch_queue;
+ }
+
+ l = p->dma_read(CLNK_CTRL, lch_head);
+ l &= ~(0x1f);
+ l |= lch_queue;
+ p->dma_write(l, CLNK_CTRL, lch_head);
+
+ l = p->dma_read(CLNK_CTRL, lch_queue);
+ l &= ~(0x1f);
+ l |= (dma_chan[lch_queue].next_linked_ch);
+ p->dma_write(l, CLNK_CTRL, lch_queue);
+}
+
+/**
+ * @brief omap_request_dma_chain : Request a chain of DMA channels
+ *
+ * @param dev_id - Device id using the dma channel
+ * @param dev_name - Device name
+ * @param callback - Call back function
+ * @chain_id -
+ * @no_of_chans - Number of channels requested
+ * @chain_mode - Dynamic or static chaining : OMAP_DMA_STATIC_CHAIN
+ * OMAP_DMA_DYNAMIC_CHAIN
+ * @params - Channel parameters
+ *
+ * @return - Success : 0
+ * Failure: -EINVAL/-ENOMEM
+ */
+int omap_request_dma_chain(int dev_id, const char *dev_name,
+ void (*callback) (int lch, u16 ch_status,
+ void *data),
+ int *chain_id, int no_of_chans, int chain_mode,
+ struct omap_dma_channel_params params)
+{
+ int *channels;
+ int i, err;
+
+ /* Is the chain mode valid ? */
+ if (chain_mode != OMAP_DMA_STATIC_CHAIN
+ && chain_mode != OMAP_DMA_DYNAMIC_CHAIN) {
+ printk(KERN_ERR "Invalid chain mode requested\n");
+ return -EINVAL;
+ }
+
+ if (unlikely((no_of_chans < 1
+ || no_of_chans > dma_lch_count))) {
+ printk(KERN_ERR "Invalid Number of channels requested\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Allocate a queue to maintain the status of the channels
+ * in the chain
+ */
+ channels = kmalloc(sizeof(*channels) * no_of_chans, GFP_KERNEL);
+ if (channels == NULL) {
+ printk(KERN_ERR "omap_dma: No memory for channel queue\n");
+ return -ENOMEM;
+ }
+
+ /* request and reserve DMA channels for the chain */
+ for (i = 0; i < no_of_chans; i++) {
+ err = omap_request_dma(dev_id, dev_name,
+ callback, NULL, &channels[i]);
+ if (err < 0) {
+ int j;
+ for (j = 0; j < i; j++)
+ omap_free_dma(channels[j]);
+ kfree(channels);
+ printk(KERN_ERR "omap_dma: Request failed %d\n", err);
+ return err;
+ }
+ dma_chan[channels[i]].prev_linked_ch = -1;
+ dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
+
+ /*
+ * Allowing client drivers to set common parameters now,
+ * so that later only relevant (src_start, dest_start
+ * and element count) can be set
+ */
+ omap_set_dma_params(channels[i], &params);
+ }
+
+ *chain_id = channels[0];
+ dma_linked_lch[*chain_id].linked_dmach_q = channels;
+ dma_linked_lch[*chain_id].chain_mode = chain_mode;
+ dma_linked_lch[*chain_id].chain_state = DMA_CHAIN_NOTSTARTED;
+ dma_linked_lch[*chain_id].no_of_lchs_linked = no_of_chans;
+
+ for (i = 0; i < no_of_chans; i++)
+ dma_chan[channels[i]].chain_id = *chain_id;
+
+ /* Reset the Queue pointers */
+ OMAP_DMA_CHAIN_QINIT(*chain_id);
+
+ /* Set up the chain */
+ if (no_of_chans == 1)
+ create_dma_lch_chain(channels[0], channels[0]);
+ else {
+ for (i = 0; i < (no_of_chans - 1); i++)
+ create_dma_lch_chain(channels[i], channels[i + 1]);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_request_dma_chain);
+
+/**
+ * @brief omap_modify_dma_chain_param : Modify the chain's params - Modify the
+ * params after setting it. Dont do this while dma is running!!
+ *
+ * @param chain_id - Chained logical channel id.
+ * @param params
+ *
+ * @return - Success : 0
+ * Failure : -EINVAL
+ */
+int omap_modify_dma_chain_params(int chain_id,
+ struct omap_dma_channel_params params)
+{
+ int *channels;
+ u32 i;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0
+ || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
+ /*
+ * Allowing client drivers to set common parameters now,
+ * so that later only relevant (src_start, dest_start
+ * and element count) can be set
+ */
+ omap_set_dma_params(channels[i], &params);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_modify_dma_chain_params);
+
+/**
+ * @brief omap_free_dma_chain - Free all the logical channels in a chain.
+ *
+ * @param chain_id
+ *
+ * @return - Success : 0
+ * Failure : -EINVAL
+ */
+int omap_free_dma_chain(int chain_id)
+{
+ int *channels;
+ u32 i;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+ for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
+ dma_chan[channels[i]].next_linked_ch = -1;
+ dma_chan[channels[i]].prev_linked_ch = -1;
+ dma_chan[channels[i]].chain_id = -1;
+ dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
+ omap_free_dma(channels[i]);
+ }
+
+ kfree(channels);
+
+ dma_linked_lch[chain_id].linked_dmach_q = NULL;
+ dma_linked_lch[chain_id].chain_mode = -1;
+ dma_linked_lch[chain_id].chain_state = -1;
+
+ return (0);
+}
+EXPORT_SYMBOL(omap_free_dma_chain);
+
+/**
+ * @brief omap_dma_chain_status - Check if the chain is in
+ * active / inactive state.
+ * @param chain_id
+ *
+ * @return - Success : OMAP_DMA_CHAIN_ACTIVE/OMAP_DMA_CHAIN_INACTIVE
+ * Failure : -EINVAL
+ */
+int omap_dma_chain_status(int chain_id)
+{
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+ pr_debug("CHAINID=%d, qcnt=%d\n", chain_id,
+ dma_linked_lch[chain_id].q_count);
+
+ if (OMAP_DMA_CHAIN_QEMPTY(chain_id))
+ return OMAP_DMA_CHAIN_INACTIVE;
+
+ return OMAP_DMA_CHAIN_ACTIVE;
+}
+EXPORT_SYMBOL(omap_dma_chain_status);
+
+/**
+ * @brief omap_dma_chain_a_transfer - Get a free channel from a chain,
+ * set the params and start the transfer.
+ *
+ * @param chain_id
+ * @param src_start - buffer start address
+ * @param dest_start - Dest address
+ * @param elem_count
+ * @param frame_count
+ * @param callbk_data - channel callback parameter data.
+ *
+ * @return - Success : 0
+ * Failure: -EINVAL/-EBUSY
+ */
+int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
+ int elem_count, int frame_count, void *callbk_data)
+{
+ int *channels;
+ u32 l, lch;
+ int start_dma = 0;
+
+ /*
+ * if buffer size is less than 1 then there is
+ * no use of starting the chain
+ */
+ if (elem_count < 1) {
+ printk(KERN_ERR "Invalid buffer size\n");
+ return -EINVAL;
+ }
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0
+ || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exist\n");
+ return -EINVAL;
+ }
+
+ /* Check if all the channels in chain are in use */
+ if (OMAP_DMA_CHAIN_QFULL(chain_id))
+ return -EBUSY;
+
+ /* Frame count may be negative in case of indexed transfers */
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ /* Get a free channel */
+ lch = channels[dma_linked_lch[chain_id].q_tail];
+
+ /* Store the callback data */
+ dma_chan[lch].data = callbk_data;
+
+ /* Increment the q_tail */
+ OMAP_DMA_CHAIN_INCQTAIL(chain_id);
+
+ /* Set the params to the free channel */
+ if (src_start != 0)
+ p->dma_write(src_start, CSSA, lch);
+ if (dest_start != 0)
+ p->dma_write(dest_start, CDSA, lch);
+
+ /* Write the buffer size */
+ p->dma_write(elem_count, CEN, lch);
+ p->dma_write(frame_count, CFN, lch);
+
+ /*
+ * If the chain is dynamically linked,
+ * then we may have to start the chain if its not active
+ */
+ if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) {
+
+ /*
+ * In Dynamic chain, if the chain is not started,
+ * queue the channel
+ */
+ if (dma_linked_lch[chain_id].chain_state ==
+ DMA_CHAIN_NOTSTARTED) {
+ /* Enable the link in previous channel */
+ if (dma_chan[dma_chan[lch].prev_linked_ch].state ==
+ DMA_CH_QUEUED)
+ enable_lnk(dma_chan[lch].prev_linked_ch);
+ dma_chan[lch].state = DMA_CH_QUEUED;
+ }
+
+ /*
+ * Chain is already started, make sure its active,
+ * if not then start the chain
+ */
+ else {
+ start_dma = 1;
+
+ if (dma_chan[dma_chan[lch].prev_linked_ch].state ==
+ DMA_CH_STARTED) {
+ enable_lnk(dma_chan[lch].prev_linked_ch);
+ dma_chan[lch].state = DMA_CH_QUEUED;
+ start_dma = 0;
+ if (0 == ((1 << 7) & p->dma_read(
+ CCR, dma_chan[lch].prev_linked_ch))) {
+ disable_lnk(dma_chan[lch].
+ prev_linked_ch);
+ pr_debug("\n prev ch is stopped\n");
+ start_dma = 1;
+ }
+ }
+
+ else if (dma_chan[dma_chan[lch].prev_linked_ch].state
+ == DMA_CH_QUEUED) {
+ enable_lnk(dma_chan[lch].prev_linked_ch);
+ dma_chan[lch].state = DMA_CH_QUEUED;
+ start_dma = 0;
+ }
+ omap_enable_channel_irq(lch);
+
+ l = p->dma_read(CCR, lch);
+
+ if ((0 == (l & (1 << 24))))
+ l &= ~(1 << 25);
+ else
+ l |= (1 << 25);
+ if (start_dma == 1) {
+ if (0 == (l & (1 << 7))) {
+ l |= (1 << 7);
+ dma_chan[lch].state = DMA_CH_STARTED;
+ pr_debug("starting %d\n", lch);
+ p->dma_write(l, CCR, lch);
+ } else
+ start_dma = 0;
+ } else {
+ if (0 == (l & (1 << 7)))
+ p->dma_write(l, CCR, lch);
+ }
+ dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_dma_chain_a_transfer);
+
+/**
+ * @brief omap_start_dma_chain_transfers - Start the chain
+ *
+ * @param chain_id
+ *
+ * @return - Success : 0
+ * Failure : -EINVAL/-EBUSY
+ */
+int omap_start_dma_chain_transfers(int chain_id)
+{
+ int *channels;
+ u32 l, i;
+
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ if (dma_linked_lch[channels[0]].chain_state == DMA_CHAIN_STARTED) {
+ printk(KERN_ERR "Chain is already started\n");
+ return -EBUSY;
+ }
+
+ if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_STATIC_CHAIN) {
+ for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked;
+ i++) {
+ enable_lnk(channels[i]);
+ omap_enable_channel_irq(channels[i]);
+ }
+ } else {
+ omap_enable_channel_irq(channels[0]);
+ }
+
+ l = p->dma_read(CCR, channels[0]);
+ l |= (1 << 7);
+ dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
+ dma_chan[channels[0]].state = DMA_CH_STARTED;
+
+ if ((0 == (l & (1 << 24))))
+ l &= ~(1 << 25);
+ else
+ l |= (1 << 25);
+ p->dma_write(l, CCR, channels[0]);
+
+ dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_start_dma_chain_transfers);
+
+/**
+ * @brief omap_stop_dma_chain_transfers - Stop the dma transfer of a chain.
+ *
+ * @param chain_id
+ *
+ * @return - Success : 0
+ * Failure : EINVAL
+ */
+int omap_stop_dma_chain_transfers(int chain_id)
+{
+ int *channels;
+ u32 l, i;
+ u32 sys_cf = 0;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88)) {
+ sys_cf = p->dma_read(OCP_SYSCONFIG, 0);
+ l = sys_cf;
+ /* Middle mode reg set no Standby */
+ l &= ~((1 << 12)|(1 << 13));
+ p->dma_write(l, OCP_SYSCONFIG, 0);
+ }
+
+ for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
+
+ /* Stop the Channel transmission */
+ l = p->dma_read(CCR, channels[i]);
+ l &= ~(1 << 7);
+ p->dma_write(l, CCR, channels[i]);
+
+ /* Disable the link in all the channels */
+ disable_lnk(channels[i]);
+ dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
+
+ }
+ dma_linked_lch[chain_id].chain_state = DMA_CHAIN_NOTSTARTED;
+
+ /* Reset the Queue pointers */
+ OMAP_DMA_CHAIN_QINIT(chain_id);
+
+ if (IS_DMA_ERRATA(DMA_ERRATA_i88))
+ p->dma_write(sys_cf, OCP_SYSCONFIG, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_stop_dma_chain_transfers);
+
+/* Get the index of the ongoing DMA in chain */
+/**
+ * @brief omap_get_dma_chain_index - Get the element and frame index
+ * of the ongoing DMA in chain
+ *
+ * @param chain_id
+ * @param ei - Element index
+ * @param fi - Frame index
+ *
+ * @return - Success : 0
+ * Failure : -EINVAL
+ */
+int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
+{
+ int lch;
+ int *channels;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+ if ((!ei) || (!fi))
+ return -EINVAL;
+
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ /* Get the current channel */
+ lch = channels[dma_linked_lch[chain_id].q_head];
+
+ *ei = p->dma_read(CCEN, lch);
+ *fi = p->dma_read(CCFN, lch);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_get_dma_chain_index);
+
+/**
+ * @brief omap_get_dma_chain_dst_pos - Get the destination position of the
+ * ongoing DMA in chain
+ *
+ * @param chain_id
+ *
+ * @return - Success : Destination position
+ * Failure : -EINVAL
+ */
+int omap_get_dma_chain_dst_pos(int chain_id)
+{
+ int lch;
+ int *channels;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ /* Get the current channel */
+ lch = channels[dma_linked_lch[chain_id].q_head];
+
+ return p->dma_read(CDAC, lch);
+}
+EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
+
+/**
+ * @brief omap_get_dma_chain_src_pos - Get the source position
+ * of the ongoing DMA in chain
+ * @param chain_id
+ *
+ * @return - Success : Destination position
+ * Failure : -EINVAL
+ */
+int omap_get_dma_chain_src_pos(int chain_id)
+{
+ int lch;
+ int *channels;
+
+ /* Check for input params */
+ if (unlikely((chain_id < 0 || chain_id >= dma_lch_count))) {
+ printk(KERN_ERR "Invalid chain id\n");
+ return -EINVAL;
+ }
+
+ /* Check if the chain exists */
+ if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
+ printk(KERN_ERR "Chain doesn't exists\n");
+ return -EINVAL;
+ }
+
+ channels = dma_linked_lch[chain_id].linked_dmach_q;
+
+ /* Get the current channel */
+ lch = channels[dma_linked_lch[chain_id].q_head];
+
+ return p->dma_read(CSAC, lch);
+}
+EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
+#endif /* ifndef CONFIG_ARCH_OMAP1 */
+
+/*----------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1
+
+static int omap1_dma_handle_ch(int ch)
+{
+ u32 csr;
+
+ if (enable_1510_mode && ch >= 6) {
+ csr = dma_chan[ch].saved_csr;
+ dma_chan[ch].saved_csr = 0;
+ } else
+ csr = p->dma_read(CSR, ch);
+ if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
+ dma_chan[ch + 6].saved_csr = csr >> 7;
+ csr &= 0x7f;
+ }
+ if ((csr & 0x3f) == 0)
+ return 0;
+ if (unlikely(dma_chan[ch].dev_id == -1)) {
+ printk(KERN_WARNING "Spurious interrupt from DMA channel "
+ "%d (CSR %04x)\n", ch, csr);
+ return 0;
+ }
+ if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
+ printk(KERN_WARNING "DMA timeout with device %d\n",
+ dma_chan[ch].dev_id);
+ if (unlikely(csr & OMAP_DMA_DROP_IRQ))
+ printk(KERN_WARNING "DMA synchronization event drop occurred "
+ "with device %d\n", dma_chan[ch].dev_id);
+ if (likely(csr & OMAP_DMA_BLOCK_IRQ))
+ dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
+ if (likely(dma_chan[ch].callback != NULL))
+ dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
+
+ return 1;
+}
+
+static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
+{
+ int ch = ((int) dev_id) - 1;
+ int handled = 0;
+
+ for (;;) {
+ int handled_now = 0;
+
+ handled_now += omap1_dma_handle_ch(ch);
+ if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
+ handled_now += omap1_dma_handle_ch(ch + 6);
+ if (!handled_now)
+ break;
+ handled += handled_now;
+ }
+
+ return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+#else
+#define omap1_dma_irq_handler NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+static int omap2_dma_handle_ch(int ch)
+{
+ u32 status = p->dma_read(CSR, ch);
+
+ if (!status) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n",
+ ch);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
+ return 0;
+ }
+ if (unlikely(dma_chan[ch].dev_id == -1)) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "IRQ %04x for non-allocated DMA"
+ "channel %d\n", status, ch);
+ return 0;
+ }
+ if (unlikely(status & OMAP_DMA_DROP_IRQ))
+ printk(KERN_INFO
+ "DMA synchronization event drop occurred with device "
+ "%d\n", dma_chan[ch].dev_id);
+ if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
+ printk(KERN_INFO "DMA transaction error with device %d\n",
+ dma_chan[ch].dev_id);
+ if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
+ u32 ccr;
+
+ ccr = p->dma_read(CCR, ch);
+ ccr &= ~OMAP_DMA_CCR_EN;
+ p->dma_write(ccr, CCR, ch);
+ dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
+ }
+ }
+ if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ))
+ printk(KERN_INFO "DMA secure error with device %d\n",
+ dma_chan[ch].dev_id);
+ if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ))
+ printk(KERN_INFO "DMA misaligned error with device %d\n",
+ dma_chan[ch].dev_id);
+
+ p->dma_write(status, CSR, ch);
+ p->dma_write(1 << ch, IRQSTATUS_L0, ch);
+ /* read back the register to flush the write */
+ p->dma_read(IRQSTATUS_L0, ch);
+
+ /* If the ch is not chained then chain_id will be -1 */
+ if (dma_chan[ch].chain_id != -1) {
+ int chain_id = dma_chan[ch].chain_id;
+ dma_chan[ch].state = DMA_CH_NOTSTARTED;
+ if (p->dma_read(CLNK_CTRL, ch) & (1 << 15))
+ dma_chan[dma_chan[ch].next_linked_ch].state =
+ DMA_CH_STARTED;
+ if (dma_linked_lch[chain_id].chain_mode ==
+ OMAP_DMA_DYNAMIC_CHAIN)
+ disable_lnk(ch);
+
+ if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
+ OMAP_DMA_CHAIN_INCQHEAD(chain_id);
+
+ status = p->dma_read(CSR, ch);
+ p->dma_write(status, CSR, ch);
+ }
+
+ if (likely(dma_chan[ch].callback != NULL))
+ dma_chan[ch].callback(ch, status, dma_chan[ch].data);
+
+ return 0;
+}
+
+/* STATUS register count is from 1-32 while our is 0-31 */
+static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
+{
+ u32 val, enable_reg;
+ int i;
+
+ val = p->dma_read(IRQSTATUS_L0, 0);
+ if (val == 0) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING "Spurious DMA IRQ\n");
+ return IRQ_HANDLED;
+ }
+ enable_reg = p->dma_read(IRQENABLE_L0, 0);
+ val &= enable_reg; /* Dispatch only relevant interrupts */
+ for (i = 0; i < dma_lch_count && val != 0; i++) {
+ if (val & 1)
+ omap2_dma_handle_ch(i);
+ val >>= 1;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction omap24xx_dma_irq = {
+ .name = "DMA",
+ .handler = omap2_dma_irq_handler,
+ .flags = IRQF_DISABLED
+};
+
+#else
+static struct irqaction omap24xx_dma_irq;
+#endif
+
+/*----------------------------------------------------------------------------*/
+
+void omap_dma_global_context_save(void)
+{
+ omap_dma_global_context.dma_irqenable_l0 =
+ p->dma_read(IRQENABLE_L0, 0);
+ omap_dma_global_context.dma_ocp_sysconfig =
+ p->dma_read(OCP_SYSCONFIG, 0);
+ omap_dma_global_context.dma_gcr = p->dma_read(GCR, 0);
+}
+
+void omap_dma_global_context_restore(void)
+{
+ int ch;
+
+ p->dma_write(omap_dma_global_context.dma_gcr, GCR, 0);
+ p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
+ OCP_SYSCONFIG, 0);
+ p->dma_write(omap_dma_global_context.dma_irqenable_l0,
+ IRQENABLE_L0, 0);
+
+ if (IS_DMA_ERRATA(DMA_ROMCODE_BUG))
+ p->dma_write(0x3 , IRQSTATUS_L0, 0);
+
+ for (ch = 0; ch < dma_chan_count; ch++)
+ if (dma_chan[ch].dev_id != -1)
+ omap_clear_dma(ch);
+}
+
+static int __devinit omap_system_dma_probe(struct platform_device *pdev)
+{
+ int ch, ret = 0;
+ int dma_irq;
+ char irq_name[4];
+ int irq_rel;
+
+ p = pdev->dev.platform_data;
+ if (!p) {
+ dev_err(&pdev->dev, "%s: System DMA initialized without"
+ "platform data\n", __func__);
+ return -EINVAL;
+ }
+
+ d = p->dma_attr;
+ errata = p->errata;
+
+ if ((d->dev_caps & RESERVE_CHANNEL) && omap_dma_reserve_channels
+ && (omap_dma_reserve_channels <= dma_lch_count))
+ d->lch_count = omap_dma_reserve_channels;
+
+ dma_lch_count = d->lch_count;
+ dma_chan_count = dma_lch_count;
+ dma_chan = d->chan;
+ enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;
+
+ if (cpu_class_is_omap2()) {
+ dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
+ dma_lch_count, GFP_KERNEL);
+ if (!dma_linked_lch) {
+ ret = -ENOMEM;
+ goto exit_dma_lch_fail;
+ }
+ }
+
+ spin_lock_init(&dma_chan_lock);
+ for (ch = 0; ch < dma_chan_count; ch++) {
+ omap_clear_dma(ch);
+ if (cpu_class_is_omap2())
+ omap2_disable_irq_lch(ch);
+
+ dma_chan[ch].dev_id = -1;
+ dma_chan[ch].next_lch = -1;
+
+ if (ch >= 6 && enable_1510_mode)
+ continue;
+
+ if (cpu_class_is_omap1()) {
+ /*
+ * request_irq() doesn't like dev_id (ie. ch) being
+ * zero, so we have to kludge around this.
+ */
+ sprintf(&irq_name[0], "%d", ch);
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+
+ if (dma_irq < 0) {
+ ret = dma_irq;
+ goto exit_dma_irq_fail;
+ }
+
+ /* INT_DMA_LCD is handled in lcd_dma.c */
+ if (dma_irq == INT_DMA_LCD)
+ continue;
+
+ ret = request_irq(dma_irq,
+ omap1_dma_irq_handler, 0, "DMA",
+ (void *) (ch + 1));
+ if (ret != 0)
+ goto exit_dma_irq_fail;
+ }
+ }
+
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx())
+ omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
+ DMA_DEFAULT_FIFO_DEPTH, 0);
+
+ if (cpu_class_is_omap2()) {
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ if (dma_irq < 0) {
+ dev_err(&pdev->dev, "failed: request IRQ %d", dma_irq);
+ goto exit_dma_lch_fail;
+ }
+ ret = setup_irq(dma_irq, &omap24xx_dma_irq);
+ if (ret) {
+ dev_err(&pdev->dev, "set_up failed for IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ goto exit_dma_lch_fail;
+ }
+ }
+
+ /* reserve dma channels 0 and 1 in high security devices */
+ if (cpu_is_omap34xx() &&
+ (omap_type() != OMAP2_DEVICE_TYPE_GP)) {
+ printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+ "HS ROM code\n");
+ dma_chan[0].dev_id = 0;
+ dma_chan[1].dev_id = 1;
+ }
+ p->show_dma_caps();
+ return 0;
+
+exit_dma_irq_fail:
+ dev_err(&pdev->dev, "unable to request IRQ %d"
+ "for DMA (error %d)\n", dma_irq, ret);
+ for (irq_rel = 0; irq_rel < ch; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+
+exit_dma_lch_fail:
+ kfree(p);
+ kfree(d);
+ kfree(dma_chan);
+ return ret;
+}
+
+static int __devexit omap_system_dma_remove(struct platform_device *pdev)
+{
+ int dma_irq;
+
+ if (cpu_class_is_omap2()) {
+ char irq_name[4];
+ strcpy(irq_name, "0");
+ dma_irq = platform_get_irq_byname(pdev, irq_name);
+ remove_irq(dma_irq, &omap24xx_dma_irq);
+ } else {
+ int irq_rel = 0;
+ for ( ; irq_rel < dma_chan_count; irq_rel++) {
+ dma_irq = platform_get_irq(pdev, irq_rel);
+ free_irq(dma_irq, (void *)(irq_rel + 1));
+ }
+ }
+ kfree(p);
+ kfree(d);
+ kfree(dma_chan);
+ return 0;
+}
+
+static struct platform_driver omap_system_dma_driver = {
+ .probe = omap_system_dma_probe,
+ .remove = omap_system_dma_remove,
+ .driver = {
+ .name = "omap_dma_system"
+ },
+};
+
+static int __init omap_system_dma_init(void)
+{
+ return platform_driver_register(&omap_system_dma_driver);
+}
+arch_initcall(omap_system_dma_init);
+
+static void __exit omap_system_dma_exit(void)
+{
+ platform_driver_unregister(&omap_system_dma_driver);
+}
+
+MODULE_DESCRIPTION("OMAP SYSTEM DMA DRIVER");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
+
+/*
+ * Reserve the omap SDMA channels using cmdline bootarg
+ * "omap_dma_reserve_ch=". The valid range is 1 to 32
+ */
+static int __init omap_dma_cmdline_reserve_ch(char *str)
+{
+ if (get_option(&str, &omap_dma_reserve_channels) != 1)
+ omap_dma_reserve_channels = 0;
+ return 1;
+}
+
+__setup("omap_dma_reserve_ch=", omap_dma_cmdline_reserve_ch);
+
+
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
new file mode 100644
index 00000000..ee9f6ebb
--- /dev/null
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -0,0 +1,797 @@
+/*
+ * linux/arch/arm/plat-omap/dmtimer.c
+ *
+ * OMAP Dual-Mode Timers
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * OMAP2 support by Juha Yrjola
+ * API improvements and OMAP2 clock framework support by Timo Teras
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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/init.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/hardware.h>
+#include <plat/dmtimer.h>
+#include <mach/irqs.h>
+
+/* register offsets */
+#define _OMAP_TIMER_ID_OFFSET 0x00
+#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10
+#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14
+#define _OMAP_TIMER_STAT_OFFSET 0x18
+#define _OMAP_TIMER_INT_EN_OFFSET 0x1c
+#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20
+#define _OMAP_TIMER_CTRL_OFFSET 0x24
+#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
+#define OMAP_TIMER_CTRL_CAPTMODE (1 << 13)
+#define OMAP_TIMER_CTRL_PT (1 << 12)
+#define OMAP_TIMER_CTRL_TCM_LOWTOHIGH (0x1 << 8)
+#define OMAP_TIMER_CTRL_TCM_HIGHTOLOW (0x2 << 8)
+#define OMAP_TIMER_CTRL_TCM_BOTHEDGES (0x3 << 8)
+#define OMAP_TIMER_CTRL_SCPWM (1 << 7)
+#define OMAP_TIMER_CTRL_CE (1 << 6) /* compare enable */
+#define OMAP_TIMER_CTRL_PRE (1 << 5) /* prescaler enable */
+#define OMAP_TIMER_CTRL_PTV_SHIFT 2 /* prescaler value shift */
+#define OMAP_TIMER_CTRL_POSTED (1 << 2)
+#define OMAP_TIMER_CTRL_AR (1 << 1) /* auto-reload enable */
+#define OMAP_TIMER_CTRL_ST (1 << 0) /* start timer */
+#define _OMAP_TIMER_COUNTER_OFFSET 0x28
+#define _OMAP_TIMER_LOAD_OFFSET 0x2c
+#define _OMAP_TIMER_TRIGGER_OFFSET 0x30
+#define _OMAP_TIMER_WRITE_PEND_OFFSET 0x34
+#define WP_NONE 0 /* no write pending bit */
+#define WP_TCLR (1 << 0)
+#define WP_TCRR (1 << 1)
+#define WP_TLDR (1 << 2)
+#define WP_TTGR (1 << 3)
+#define WP_TMAR (1 << 4)
+#define WP_TPIR (1 << 5)
+#define WP_TNIR (1 << 6)
+#define WP_TCVR (1 << 7)
+#define WP_TOCR (1 << 8)
+#define WP_TOWR (1 << 9)
+#define _OMAP_TIMER_MATCH_OFFSET 0x38
+#define _OMAP_TIMER_CAPTURE_OFFSET 0x3c
+#define _OMAP_TIMER_IF_CTRL_OFFSET 0x40
+#define _OMAP_TIMER_CAPTURE2_OFFSET 0x44 /* TCAR2, 34xx only */
+#define _OMAP_TIMER_TICK_POS_OFFSET 0x48 /* TPIR, 34xx only */
+#define _OMAP_TIMER_TICK_NEG_OFFSET 0x4c /* TNIR, 34xx only */
+#define _OMAP_TIMER_TICK_COUNT_OFFSET 0x50 /* TCVR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET 0x54 /* TOCR, 34xx only */
+#define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58 /* TOWR, 34xx only */
+
+/* register offsets with the write pending bit encoded */
+#define WPSHIFT 16
+
+#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CTRL_REG (_OMAP_TIMER_CTRL_OFFSET \
+ | (WP_TCLR << WPSHIFT))
+
+#define OMAP_TIMER_COUNTER_REG (_OMAP_TIMER_COUNTER_OFFSET \
+ | (WP_TCRR << WPSHIFT))
+
+#define OMAP_TIMER_LOAD_REG (_OMAP_TIMER_LOAD_OFFSET \
+ | (WP_TLDR << WPSHIFT))
+
+#define OMAP_TIMER_TRIGGER_REG (_OMAP_TIMER_TRIGGER_OFFSET \
+ | (WP_TTGR << WPSHIFT))
+
+#define OMAP_TIMER_WRITE_PEND_REG (_OMAP_TIMER_WRITE_PEND_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_MATCH_REG (_OMAP_TIMER_MATCH_OFFSET \
+ | (WP_TMAR << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE_REG (_OMAP_TIMER_CAPTURE_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_IF_CTRL_REG (_OMAP_TIMER_IF_CTRL_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_CAPTURE2_REG (_OMAP_TIMER_CAPTURE2_OFFSET \
+ | (WP_NONE << WPSHIFT))
+
+#define OMAP_TIMER_TICK_POS_REG (_OMAP_TIMER_TICK_POS_OFFSET \
+ | (WP_TPIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_NEG_REG (_OMAP_TIMER_TICK_NEG_OFFSET \
+ | (WP_TNIR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_COUNT_REG (_OMAP_TIMER_TICK_COUNT_OFFSET \
+ | (WP_TCVR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_SET_REG \
+ (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
+
+#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
+ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
+
+struct omap_dm_timer {
+ unsigned long phys_base;
+ int irq;
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ struct clk *iclk, *fclk;
+#endif
+ void __iomem *io_base;
+ unsigned reserved:1;
+ unsigned enabled:1;
+ unsigned posted:1;
+};
+
+static int dm_timer_count;
+
+#ifdef CONFIG_ARCH_OMAP1
+static struct omap_dm_timer omap1_dm_timers[] = {
+ { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
+ { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
+ { .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 },
+ { .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 },
+ { .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 },
+ { .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 },
+ { .phys_base = 0xfffb7400, .irq = INT_1610_GPTIMER7 },
+ { .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 },
+};
+
+static const int omap1_dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
+
+#else
+#define omap1_dm_timers NULL
+#define omap1_dm_timer_count 0
+#endif /* CONFIG_ARCH_OMAP1 */
+
+#ifdef CONFIG_ARCH_OMAP2
+static struct omap_dm_timer omap2_dm_timers[] = {
+ { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
+ { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
+ { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
+ { .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
+ { .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
+ { .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
+ { .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
+ { .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
+ { .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
+ { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
+ { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
+ { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
+};
+
+static const char *omap2_dm_source_names[] __initdata = {
+ "sys_ck",
+ "func_32k_ck",
+ "alt_ck",
+ NULL
+};
+
+static struct clk *omap2_dm_source_clocks[3];
+static const int omap2_dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
+
+#else
+#define omap2_dm_timers NULL
+#define omap2_dm_timer_count 0
+#define omap2_dm_source_names NULL
+#define omap2_dm_source_clocks NULL
+#endif /* CONFIG_ARCH_OMAP2 */
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap_dm_timer omap3_dm_timers[] = {
+ { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
+ { .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
+ { .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 },
+ { .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 },
+ { .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 },
+ { .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 },
+ { .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 },
+ { .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 },
+ { .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
+ { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
+ { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
+ { .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
+};
+
+static const char *omap3_dm_source_names[] __initdata = {
+ "sys_ck",
+ "omap_32k_fck",
+ NULL
+};
+
+static struct clk *omap3_dm_source_clocks[2];
+static const int omap3_dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
+
+#else
+#define omap3_dm_timers NULL
+#define omap3_dm_timer_count 0
+#define omap3_dm_source_names NULL
+#define omap3_dm_source_clocks NULL
+#endif /* CONFIG_ARCH_OMAP3 */
+
+#ifdef CONFIG_ARCH_OMAP4
+static struct omap_dm_timer omap4_dm_timers[] = {
+ { .phys_base = 0x4a318000, .irq = OMAP44XX_IRQ_GPT1 },
+ { .phys_base = 0x48032000, .irq = OMAP44XX_IRQ_GPT2 },
+ { .phys_base = 0x48034000, .irq = OMAP44XX_IRQ_GPT3 },
+ { .phys_base = 0x48036000, .irq = OMAP44XX_IRQ_GPT4 },
+ { .phys_base = 0x40138000, .irq = OMAP44XX_IRQ_GPT5 },
+ { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT6 },
+ { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT7 },
+ { .phys_base = 0x4013e000, .irq = OMAP44XX_IRQ_GPT8 },
+ { .phys_base = 0x4803e000, .irq = OMAP44XX_IRQ_GPT9 },
+ { .phys_base = 0x48086000, .irq = OMAP44XX_IRQ_GPT10 },
+ { .phys_base = 0x48088000, .irq = OMAP44XX_IRQ_GPT11 },
+ { .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 },
+};
+static const char *omap4_dm_source_names[] __initdata = {
+ "sys_clkin_ck",
+ "sys_32k_ck",
+ NULL
+};
+static struct clk *omap4_dm_source_clocks[2];
+static const int omap4_dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
+
+#else
+#define omap4_dm_timers NULL
+#define omap4_dm_timer_count 0
+#define omap4_dm_source_names NULL
+#define omap4_dm_source_clocks NULL
+#endif /* CONFIG_ARCH_OMAP4 */
+
+static struct omap_dm_timer *dm_timers;
+static const char **dm_source_names;
+static struct clk **dm_source_clocks;
+
+static spinlock_t dm_timer_lock;
+
+/*
+ * Reads timer registers in posted and non-posted mode. The posted mode bit
+ * is encoded in reg. Note that in posted mode write pending bit must be
+ * checked. Otherwise a read of a non completed write will produce an error.
+ */
+static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
+{
+ if (timer->posted)
+ while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+ & (reg >> WPSHIFT))
+ cpu_relax();
+ return readl(timer->io_base + (reg & 0xff));
+}
+
+/*
+ * Writes timer registers in posted and non-posted mode. The posted mode bit
+ * is encoded in reg. Note that in posted mode the write pending bit must be
+ * checked. Otherwise a write on a register which has a pending write will be
+ * lost.
+ */
+static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
+ u32 value)
+{
+ if (timer->posted)
+ while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
+ & (reg >> WPSHIFT))
+ cpu_relax();
+ writel(value, timer->io_base + (reg & 0xff));
+}
+
+static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
+{
+ int c;
+
+ c = 0;
+ while (!(omap_dm_timer_read_reg(timer, OMAP_TIMER_SYS_STAT_REG) & 1)) {
+ c++;
+ if (c > 100000) {
+ printk(KERN_ERR "Timer failed to reset\n");
+ return;
+ }
+ }
+}
+
+static void omap_dm_timer_reset(struct omap_dm_timer *timer)
+{
+ u32 l;
+
+ if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
+ omap_dm_timer_wait_for_reset(timer);
+ }
+ omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG);
+ l |= 0x02 << 3; /* Set to smart-idle mode */
+ l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
+
+ /* Enable autoidle on OMAP2 / OMAP3 */
+ if (cpu_is_omap24xx() || cpu_is_omap34xx())
+ l |= 0x1 << 0;
+
+ /*
+ * Enable wake-up on OMAP2 CPUs.
+ */
+ if (cpu_class_is_omap2())
+ l |= 1 << 2;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l);
+
+ /* Match hardware reset default of posted mode */
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ OMAP_TIMER_CTRL_POSTED);
+ timer->posted = 1;
+}
+
+static void omap_dm_timer_prepare(struct omap_dm_timer *timer)
+{
+ omap_dm_timer_enable(timer);
+ omap_dm_timer_reset(timer);
+}
+
+struct omap_dm_timer *omap_dm_timer_request(void)
+{
+ struct omap_dm_timer *timer = NULL;
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ for (i = 0; i < dm_timer_count; i++) {
+ if (dm_timers[i].reserved)
+ continue;
+
+ timer = &dm_timers[i];
+ timer->reserved = 1;
+ break;
+ }
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ if (timer != NULL)
+ omap_dm_timer_prepare(timer);
+
+ return timer;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request);
+
+struct omap_dm_timer *omap_dm_timer_request_specific(int id)
+{
+ struct omap_dm_timer *timer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) {
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+ printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n",
+ __FILE__, __LINE__, __func__, id);
+ dump_stack();
+ return NULL;
+ }
+
+ timer = &dm_timers[id-1];
+ timer->reserved = 1;
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ omap_dm_timer_prepare(timer);
+
+ return timer;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
+
+void omap_dm_timer_free(struct omap_dm_timer *timer)
+{
+ omap_dm_timer_enable(timer);
+ omap_dm_timer_reset(timer);
+ omap_dm_timer_disable(timer);
+
+ WARN_ON(!timer->reserved);
+ timer->reserved = 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_free);
+
+void omap_dm_timer_enable(struct omap_dm_timer *timer)
+{
+ if (timer->enabled)
+ return;
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ if (cpu_class_is_omap2()) {
+ clk_enable(timer->fclk);
+ clk_enable(timer->iclk);
+ }
+#endif
+
+ timer->enabled = 1;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
+
+void omap_dm_timer_disable(struct omap_dm_timer *timer)
+{
+ if (!timer->enabled)
+ return;
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ if (cpu_class_is_omap2()) {
+ clk_disable(timer->iclk);
+ clk_disable(timer->fclk);
+ }
+#endif
+
+ timer->enabled = 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
+
+int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
+{
+ return timer->irq;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
+
+#if defined(CONFIG_ARCH_OMAP1)
+
+/**
+ * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
+ * @inputmask: current value of idlect mask
+ */
+__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
+{
+ int i;
+
+ /* If ARMXOR cannot be idled this function call is unnecessary */
+ if (!(inputmask & (1 << 1)))
+ return inputmask;
+
+ /* If any active timer is using ARMXOR return modified mask */
+ for (i = 0; i < dm_timer_count; i++) {
+ u32 l;
+
+ l = omap_dm_timer_read_reg(&dm_timers[i], OMAP_TIMER_CTRL_REG);
+ if (l & OMAP_TIMER_CTRL_ST) {
+ if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
+ inputmask &= ~(1 << 1);
+ else
+ inputmask &= ~(1 << 2);
+ }
+ }
+
+ return inputmask;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
+
+#else
+
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+{
+ return timer->fclk;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
+
+__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
+{
+ BUG();
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
+
+#endif
+
+void omap_dm_timer_trigger(struct omap_dm_timer *timer)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
+
+void omap_dm_timer_start(struct omap_dm_timer *timer)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (!(l & OMAP_TIMER_CTRL_ST)) {
+ l |= OMAP_TIMER_CTRL_ST;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+ }
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_start);
+
+void omap_dm_timer_stop(struct omap_dm_timer *timer)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (l & OMAP_TIMER_CTRL_ST) {
+ l &= ~0x1;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ /* Readback to make sure write has completed */
+ omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ /*
+ * Wait for functional clock period x 3.5 to make sure that
+ * timer is stopped
+ */
+ udelay(3500000 / clk_get_rate(timer->fclk) + 1);
+#endif
+ }
+ /* Ack possibly pending interrupt */
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG,
+ OMAP_TIMER_INT_OVERFLOW);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
+
+#ifdef CONFIG_ARCH_OMAP1
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+ int n = (timer - dm_timers) << 1;
+ u32 l;
+
+ l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+ l |= source << n;
+ omap_writel(l, MOD_CONF_CTRL_1);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
+
+#else
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
+{
+ int ret = -EINVAL;
+
+ if (source < 0 || source >= 3)
+ return -EINVAL;
+
+ clk_disable(timer->fclk);
+ ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
+ clk_enable(timer->fclk);
+
+ /*
+ * When the functional clock disappears, too quick writes seem
+ * to cause an abort. XXX Is this still necessary?
+ */
+ __delay(300000);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
+
+#endif
+
+void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+ unsigned int load)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (autoreload)
+ l |= OMAP_TIMER_CTRL_AR;
+ else
+ l &= ~OMAP_TIMER_CTRL_AR;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
+
+/* Optimized set_load which removes costly spin wait in timer_start */
+void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
+ unsigned int load)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (autoreload) {
+ l |= OMAP_TIMER_CTRL_AR;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
+ } else {
+ l &= ~OMAP_TIMER_CTRL_AR;
+ }
+ l |= OMAP_TIMER_CTRL_ST;
+
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, load);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
+
+void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+ unsigned int match)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ if (enable)
+ l |= OMAP_TIMER_CTRL_CE;
+ else
+ l &= ~OMAP_TIMER_CTRL_CE;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
+
+void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+ int toggle, int trigger)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
+ OMAP_TIMER_CTRL_PT | (0x03 << 10));
+ if (def_on)
+ l |= OMAP_TIMER_CTRL_SCPWM;
+ if (toggle)
+ l |= OMAP_TIMER_CTRL_PT;
+ l |= trigger << 10;
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
+
+void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+{
+ u32 l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
+ l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
+ if (prescaler >= 0x00 && prescaler <= 0x07) {
+ l |= OMAP_TIMER_CTRL_PRE;
+ l |= prescaler << 2;
+ }
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
+
+void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+ unsigned int value)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
+{
+ unsigned int l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
+
+ return l;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
+
+void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, value);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
+
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
+{
+ unsigned int l;
+
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG);
+
+ return l;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
+
+void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
+
+int omap_dm_timers_active(void)
+{
+ int i;
+
+ for (i = 0; i < dm_timer_count; i++) {
+ struct omap_dm_timer *timer;
+
+ timer = &dm_timers[i];
+
+ if (!timer->enabled)
+ continue;
+
+ if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
+ OMAP_TIMER_CTRL_ST) {
+ return 1;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(omap_dm_timers_active);
+
+int __init omap_dm_timer_init(void)
+{
+ struct omap_dm_timer *timer;
+ int i, map_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
+
+ if (!(cpu_is_omap16xx() || cpu_class_is_omap2()))
+ return -ENODEV;
+
+ spin_lock_init(&dm_timer_lock);
+
+ if (cpu_class_is_omap1()) {
+ dm_timers = omap1_dm_timers;
+ dm_timer_count = omap1_dm_timer_count;
+ map_size = SZ_2K;
+ } else if (cpu_is_omap24xx()) {
+ dm_timers = omap2_dm_timers;
+ dm_timer_count = omap2_dm_timer_count;
+ dm_source_names = omap2_dm_source_names;
+ dm_source_clocks = omap2_dm_source_clocks;
+ } else if (cpu_is_omap34xx()) {
+ dm_timers = omap3_dm_timers;
+ dm_timer_count = omap3_dm_timer_count;
+ dm_source_names = omap3_dm_source_names;
+ dm_source_clocks = omap3_dm_source_clocks;
+ } else if (cpu_is_omap44xx()) {
+ dm_timers = omap4_dm_timers;
+ dm_timer_count = omap4_dm_timer_count;
+ dm_source_names = omap4_dm_source_names;
+ dm_source_clocks = omap4_dm_source_clocks;
+ }
+
+ if (cpu_class_is_omap2())
+ for (i = 0; dm_source_names[i] != NULL; i++)
+ dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
+
+ if (cpu_is_omap243x())
+ dm_timers[0].phys_base = 0x49018000;
+
+ for (i = 0; i < dm_timer_count; i++) {
+ timer = &dm_timers[i];
+
+ /* Static mapping, never released */
+ timer->io_base = ioremap(timer->phys_base, map_size);
+ BUG_ON(!timer->io_base);
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ if (cpu_class_is_omap2()) {
+ char clk_name[16];
+ sprintf(clk_name, "gpt%d_ick", i + 1);
+ timer->iclk = clk_get(NULL, clk_name);
+ sprintf(clk_name, "gpt%d_fck", i + 1);
+ timer->fclk = clk_get(NULL, clk_name);
+ }
+#endif
+ }
+
+ return 0;
+}
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
new file mode 100644
index 00000000..c9e5d729
--- /dev/null
+++ b/arch/arm/plat-omap/fb.c
@@ -0,0 +1,421 @@
+/*
+ * File: arch/arm/plat-omap/fb.c
+ *
+ * Framebuffer device registration for TI OMAP platforms
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/memblock.h>
+#include <linux/io.h>
+#include <linux/omapfb.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/sram.h>
+
+#include "fb.h"
+
+#if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
+
+static struct omapfb_platform_data omapfb_config;
+static int config_invalid;
+static int configured_regions;
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+
+static struct platform_device omap_fb_device = {
+ .name = "omapfb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &omap_fb_dma_mask,
+ .coherent_dma_mask = ~(u32)0,
+ .platform_data = &omapfb_config,
+ },
+ .num_resources = 0,
+};
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
+static inline int ranges_overlap(unsigned long start1, unsigned long size1,
+ unsigned long start2, unsigned long size2)
+{
+ return (start1 >= start2 && start1 < start2 + size2) ||
+ (start2 >= start1 && start2 < start1 + size1);
+}
+
+static inline int range_included(unsigned long start1, unsigned long size1,
+ unsigned long start2, unsigned long size2)
+{
+ return start1 >= start2 && start1 + size1 <= start2 + size2;
+}
+
+
+/* Check if there is an overlapping region. */
+static int fbmem_region_reserved(unsigned long start, size_t size)
+{
+ struct omapfb_mem_region *rg;
+ int i;
+
+ rg = &omapfb_config.mem_desc.region[0];
+ for (i = 0; i < OMAPFB_PLANE_NUM; i++, rg++) {
+ if (!rg->paddr)
+ /* Empty slot. */
+ continue;
+ if (ranges_overlap(start, size, rg->paddr, rg->size))
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Get the region_idx`th region from board config/ATAG and convert it to
+ * our internal format.
+ */
+static int __init get_fbmem_region(int region_idx, struct omapfb_mem_region *rg)
+{
+ const struct omap_fbmem_config *conf;
+ u32 paddr;
+
+ conf = omap_get_nr_config(OMAP_TAG_FBMEM,
+ struct omap_fbmem_config, region_idx);
+ if (conf == NULL)
+ return -ENOENT;
+
+ paddr = conf->start;
+ /*
+ * Low bits encode the page allocation mode, if high bits
+ * are zero. Otherwise we need a page aligned fixed
+ * address.
+ */
+ memset(rg, 0, sizeof(*rg));
+ rg->type = paddr & ~PAGE_MASK;
+ rg->paddr = paddr & PAGE_MASK;
+ rg->size = PAGE_ALIGN(conf->size);
+ return 0;
+}
+
+static int set_fbmem_region_type(struct omapfb_mem_region *rg, int mem_type,
+ unsigned long mem_start,
+ unsigned long mem_size)
+{
+ /*
+ * Check if the configuration specifies the type explicitly.
+ * type = 0 && paddr = 0, a default don't care case maps to
+ * the SDRAM type.
+ */
+ if (rg->type || !rg->paddr)
+ return 0;
+ if (ranges_overlap(rg->paddr, rg->size, mem_start, mem_size)) {
+ rg->type = mem_type;
+ return 0;
+ }
+ /* Can't determine it. */
+ return -1;
+}
+
+static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
+ unsigned long start_avail, unsigned size_avail)
+{
+ unsigned long paddr = rg->paddr;
+ size_t size = rg->size;
+
+ if (rg->type > OMAPFB_MEMTYPE_MAX) {
+ printk(KERN_ERR
+ "Invalid start address for FB region %d\n", region_idx);
+ return -EINVAL;
+ }
+
+ if (!rg->size) {
+ printk(KERN_ERR "Zero size for FB region %d\n", region_idx);
+ return -EINVAL;
+ }
+
+ if (!paddr)
+ /* Allocate this dynamically, leave paddr 0 for now. */
+ return 0;
+
+ /*
+ * Fixed region for the given RAM range. Check if it's already
+ * reserved by the FB code or someone else.
+ */
+ if (fbmem_region_reserved(paddr, size) ||
+ !range_included(paddr, size, start_avail, size_avail)) {
+ printk(KERN_ERR "Trying to use reserved memory "
+ "for FB region %d\n", region_idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int valid_sdram(unsigned long addr, unsigned long size)
+{
+ return memblock_is_region_memory(addr, size);
+}
+
+static int reserve_sdram(unsigned long addr, unsigned long size)
+{
+ if (memblock_is_region_reserved(addr, size))
+ return -EBUSY;
+ if (memblock_reserve(addr, size))
+ return -ENOMEM;
+ return 0;
+}
+
+/*
+ * Called from map_io. We need to call to this early enough so that we
+ * can reserve the fixed SDRAM regions before VM could get hold of them.
+ */
+void __init omapfb_reserve_sdram_memblock(void)
+{
+ unsigned long reserved = 0;
+ int i;
+
+ if (config_invalid)
+ return;
+
+ for (i = 0; ; i++) {
+ struct omapfb_mem_region rg;
+
+ if (get_fbmem_region(i, &rg) < 0)
+ break;
+
+ if (i == OMAPFB_PLANE_NUM) {
+ pr_err("Extraneous FB mem configuration entries\n");
+ config_invalid = 1;
+ return;
+ }
+
+ /* Check if it's our memory type. */
+ if (rg.type != OMAPFB_MEMTYPE_SDRAM)
+ continue;
+
+ /* Check if the region falls within SDRAM */
+ if (rg.paddr && !valid_sdram(rg.paddr, rg.size))
+ continue;
+
+ if (rg.size == 0) {
+ pr_err("Zero size for FB region %d\n", i);
+ config_invalid = 1;
+ return;
+ }
+
+ if (rg.paddr) {
+ if (reserve_sdram(rg.paddr, rg.size)) {
+ pr_err("Trying to use reserved memory for FB region %d\n",
+ i);
+ config_invalid = 1;
+ return;
+ }
+ reserved += rg.size;
+ }
+
+ if (omapfb_config.mem_desc.region[i].size) {
+ pr_err("FB region %d already set\n", i);
+ config_invalid = 1;
+ return;
+ }
+
+ omapfb_config.mem_desc.region[i] = rg;
+ configured_regions++;
+ }
+ omapfb_config.mem_desc.region_cnt = i;
+ if (reserved)
+ pr_info("Reserving %lu bytes SDRAM for frame buffer\n",
+ reserved);
+}
+
+/*
+ * Called at sram init time, before anything is pushed to the SRAM stack.
+ * Because of the stack scheme, we will allocate everything from the
+ * start of the lowest address region to the end of SRAM. This will also
+ * include padding for page alignment and possible holes between regions.
+ *
+ * As opposed to the SDRAM case, we'll also do any dynamic allocations at
+ * this point, since the driver built as a module would have problem with
+ * freeing / reallocating the regions.
+ */
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long pstart_avail,
+ unsigned long size_avail)
+{
+ struct omapfb_mem_region rg;
+ unsigned long pend_avail;
+ unsigned long reserved;
+ int i;
+
+ if (config_invalid)
+ return 0;
+
+ reserved = 0;
+ pend_avail = pstart_avail + size_avail;
+ for (i = 0; ; i++) {
+ if (get_fbmem_region(i, &rg) < 0)
+ break;
+ if (i == OMAPFB_PLANE_NUM) {
+ printk(KERN_ERR
+ "Extraneous FB mem configuration entries\n");
+ config_invalid = 1;
+ return 0;
+ }
+
+ /* Check if it's our memory type. */
+ if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SRAM,
+ sram_pstart, sram_size) < 0 ||
+ (rg.type != OMAPFB_MEMTYPE_SRAM))
+ continue;
+ BUG_ON(omapfb_config.mem_desc.region[i].size);
+
+ if (check_fbmem_region(i, &rg, pstart_avail, size_avail) < 0) {
+ config_invalid = 1;
+ return 0;
+ }
+
+ if (!rg.paddr) {
+ /* Dynamic allocation */
+ if ((size_avail & PAGE_MASK) < rg.size) {
+ printk("Not enough SRAM for FB region %d\n",
+ i);
+ config_invalid = 1;
+ return 0;
+ }
+ size_avail = (size_avail - rg.size) & PAGE_MASK;
+ rg.paddr = pstart_avail + size_avail;
+ }
+ /* Reserve everything above the start of the region. */
+ if (pend_avail - rg.paddr > reserved)
+ reserved = pend_avail - rg.paddr;
+ size_avail = pend_avail - reserved - pstart_avail;
+
+ /*
+ * We have a kernel mapping for this already, so the
+ * driver won't have to make one.
+ */
+ rg.vaddr = (void *)(sram_vstart + rg.paddr - sram_pstart);
+ omapfb_config.mem_desc.region[i] = rg;
+ configured_regions++;
+ }
+ omapfb_config.mem_desc.region_cnt = i;
+ if (reserved)
+ pr_info("Reserving %lu bytes SRAM for frame buffer\n",
+ reserved);
+ return reserved;
+}
+
+void omapfb_set_ctrl_platform_data(void *data)
+{
+ omapfb_config.ctrl_platform_data = data;
+}
+
+static int __init omap_init_fb(void)
+{
+ const struct omap_lcd_config *conf;
+
+ if (config_invalid)
+ return 0;
+ if (configured_regions != omapfb_config.mem_desc.region_cnt) {
+ printk(KERN_ERR "Invalid FB mem configuration entries\n");
+ return 0;
+ }
+ conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
+ if (conf == NULL) {
+ if (configured_regions)
+ /* FB mem config, but no LCD config? */
+ printk(KERN_ERR "Missing LCD configuration\n");
+ return 0;
+ }
+ omapfb_config.lcd = *conf;
+
+ return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
+
+#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
+
+static u64 omap_fb_dma_mask = ~(u32)0;
+static struct omapfb_platform_data omapfb_config;
+
+static struct platform_device omap_fb_device = {
+ .name = "omapfb",
+ .id = -1,
+ .dev = {
+ .dma_mask = &omap_fb_dma_mask,
+ .coherent_dma_mask = ~(u32)0,
+ .platform_data = &omapfb_config,
+ },
+ .num_resources = 0,
+};
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+ omapfb_config = *data;
+}
+
+static int __init omap_init_fb(void)
+{
+ return platform_device_register(&omap_fb_device);
+}
+
+arch_initcall(omap_init_fb);
+
+void omapfb_reserve_sdram_memblock(void)
+{
+}
+
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long start_avail,
+ unsigned long size_avail)
+{
+ return 0;
+}
+
+#else
+
+void omapfb_set_platform_data(struct omapfb_platform_data *data)
+{
+}
+
+void omapfb_reserve_sdram_memblock(void)
+{
+}
+
+unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long start_avail,
+ unsigned long size_avail)
+{
+ return 0;
+}
+
+#endif
diff --git a/arch/arm/plat-omap/fb.h b/arch/arm/plat-omap/fb.h
new file mode 100644
index 00000000..d765d0bd
--- /dev/null
+++ b/arch/arm/plat-omap/fb.h
@@ -0,0 +1,10 @@
+#ifndef __PLAT_OMAP_FB_H__
+#define __PLAT_OMAP_FB_H__
+
+extern unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long pstart_avail,
+ unsigned long size_avail);
+
+#endif /* __PLAT_OMAP_FB_H__ */
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
new file mode 100644
index 00000000..3341ca47
--- /dev/null
+++ b/arch/arm/plat-omap/i2c.c
@@ -0,0 +1,262 @@
+/*
+ * linux/arch/arm/plat-omap/i2c.c
+ *
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * Contact: Jarkko Nikula <jhnikula@gmail.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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-omap.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <mach/irqs.h>
+#include <plat/mux.h>
+#include <plat/i2c.h>
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+#define OMAP_I2C_SIZE 0x3f
+#define OMAP1_I2C_BASE 0xfffb3800
+
+static const char name[] = "omap_i2c";
+
+#define I2C_RESOURCE_BUILDER(base, irq) \
+ { \
+ .start = (base), \
+ .end = (base) + OMAP_I2C_SIZE, \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = (irq), \
+ .flags = IORESOURCE_IRQ, \
+ },
+
+static struct resource i2c_resources[][2] = {
+ { I2C_RESOURCE_BUILDER(0, 0) },
+};
+
+#define I2C_DEV_BUILDER(bus_id, res, data) \
+ { \
+ .id = (bus_id), \
+ .name = name, \
+ .num_resources = ARRAY_SIZE(res), \
+ .resource = (res), \
+ .dev = { \
+ .platform_data = (data), \
+ }, \
+ }
+
+#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16
+#define OMAP_I2C_MAX_CONTROLLERS 4
+static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS];
+static struct platform_device omap_i2c_devices[] = {
+ I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]),
+};
+
+#define OMAP_I2C_CMDLINE_SETUP (BIT(31))
+
+static int __init omap_i2c_nr_ports(void)
+{
+ int ports = 0;
+
+ if (cpu_class_is_omap1())
+ ports = 1;
+ else if (cpu_is_omap24xx())
+ ports = 2;
+ else if (cpu_is_omap34xx())
+ ports = 3;
+ else if (cpu_is_omap44xx())
+ ports = 4;
+
+ return ports;
+}
+
+static inline int omap1_i2c_add_bus(int bus_id)
+{
+ struct platform_device *pdev;
+ struct omap_i2c_bus_platform_data *pdata;
+ struct resource *res;
+
+ omap1_i2c_mux_pins(bus_id);
+
+ pdev = &omap_i2c_devices[bus_id - 1];
+ res = pdev->resource;
+ res[0].start = OMAP1_I2C_BASE;
+ res[0].end = res[0].start + OMAP_I2C_SIZE;
+ res[1].start = INT_I2C;
+ pdata = &i2c_pdata[bus_id - 1];
+
+ return platform_device_register(pdev);
+}
+
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+ omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
+static struct omap_device_pm_latency omap_i2c_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ int l;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
+ struct omap_i2c_bus_platform_data *pdata;
+
+ omap2_i2c_mux_pins(bus_id);
+
+ l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id);
+ WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN,
+ "String buffer overflow in I2C%d device setup\n", bus_id);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name);
+ return -EEXIST;
+ }
+
+ pdata = &i2c_pdata[bus_id - 1];
+ /*
+ * When waiting for completion of a i2c transfer, we need to
+ * set a wake up latency constraint for the MPU. This is to
+ * ensure quick enough wakeup from idle, when transfer
+ * completes.
+ * Only omap3 has support for constraints
+ */
+ if (cpu_is_omap34xx())
+ pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+ od = omap_device_build(name, bus_id, oh, pdata,
+ sizeof(struct omap_i2c_bus_platform_data),
+ omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
+ WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
+
+ return PTR_ERR(od);
+}
+#else
+static inline int omap2_i2c_add_bus(int bus_id)
+{
+ return 0;
+}
+#endif
+
+static int __init omap_i2c_add_bus(int bus_id)
+{
+ if (cpu_class_is_omap1())
+ return omap1_i2c_add_bus(bus_id);
+ else
+ return omap2_i2c_add_bus(bus_id);
+}
+
+/**
+ * omap_i2c_bus_setup - Process command line options for the I2C bus speed
+ * @str: String of options
+ *
+ * This function allow to override the default I2C bus speed for given I2C
+ * bus with a command line option.
+ *
+ * Format: i2c_bus=bus_id,clkrate (in kHz)
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int __init omap_i2c_bus_setup(char *str)
+{
+ int ports;
+ int ints[3];
+
+ ports = omap_i2c_nr_ports();
+ get_options(str, 3, ints);
+ if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports)
+ return 0;
+ i2c_pdata[ints[1] - 1].clkrate = ints[2];
+ i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP;
+
+ return 1;
+}
+__setup("i2c_bus=", omap_i2c_bus_setup);
+
+/*
+ * Register busses defined in command line but that are not registered with
+ * omap_register_i2c_bus from board initialization code.
+ */
+static int __init omap_register_i2c_bus_cmdline(void)
+{
+ int i, err = 0;
+
+ for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++)
+ if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) {
+ i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
+ err = omap_i2c_add_bus(i + 1);
+ if (err)
+ goto out;
+ }
+
+out:
+ return err;
+}
+subsys_initcall(omap_register_i2c_bus_cmdline);
+
+/**
+ * omap_register_i2c_bus - register I2C bus with device descriptors
+ * @bus_id: bus id counting from number 1
+ * @clkrate: clock rate of the bus in kHz
+ * @info: pointer into I2C device descriptor table or NULL
+ * @len: number of descriptors in the table
+ *
+ * Returns 0 on success or an error code.
+ */
+int __init omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len)
+{
+ int err;
+
+ BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports());
+
+ if (info) {
+ err = i2c_register_board_info(bus_id, info, len);
+ if (err)
+ return err;
+ }
+
+ if (!i2c_pdata[bus_id - 1].clkrate)
+ i2c_pdata[bus_id - 1].clkrate = clkrate;
+
+ i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP;
+
+ return omap_i2c_add_bus(bus_id);
+}
diff --git a/arch/arm/plat-omap/include/plat/blizzard.h b/arch/arm/plat-omap/include/plat/blizzard.h
new file mode 100644
index 00000000..56e7f2e7
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/blizzard.h
@@ -0,0 +1,12 @@
+#ifndef _BLIZZARD_H
+#define _BLIZZARD_H
+
+struct blizzard_platform_data {
+ void (*power_up)(struct device *dev);
+ void (*power_down)(struct device *dev);
+ unsigned long (*get_clock_rate)(struct device *dev);
+
+ unsigned te_connected:1;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/board-ams-delta.h b/arch/arm/plat-omap/include/plat/board-ams-delta.h
new file mode 100644
index 00000000..51b102dc
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/board-ams-delta.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-ams-delta.h
+ *
+ * Copyright (C) 2006 Jonathan McDowell <noodles@earth.li>
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_ARCH_OMAP_AMS_DELTA_H
+#define __ASM_ARCH_OMAP_AMS_DELTA_H
+
+#if defined (CONFIG_MACH_AMS_DELTA)
+
+#define AMS_DELTA_LATCH1_PHYS 0x01000000
+#define AMS_DELTA_LATCH1_VIRT 0xEA000000
+#define AMS_DELTA_MODEM_PHYS 0x04000000
+#define AMS_DELTA_MODEM_VIRT 0xEB000000
+#define AMS_DELTA_LATCH2_PHYS 0x08000000
+#define AMS_DELTA_LATCH2_VIRT 0xEC000000
+
+#define AMS_DELTA_LATCH1_LED_CAMERA 0x01
+#define AMS_DELTA_LATCH1_LED_ADVERT 0x02
+#define AMS_DELTA_LATCH1_LED_EMAIL 0x04
+#define AMS_DELTA_LATCH1_LED_HANDSFREE 0x08
+#define AMS_DELTA_LATCH1_LED_VOICEMAIL 0x10
+#define AMS_DELTA_LATCH1_LED_VOICE 0x20
+
+#define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001
+#define AMS_DELTA_LATCH2_LCD_NDISP 0x0002
+#define AMS_DELTA_LATCH2_NAND_NCE 0x0004
+#define AMS_DELTA_LATCH2_NAND_NRE 0x0008
+#define AMS_DELTA_LATCH2_NAND_NWP 0x0010
+#define AMS_DELTA_LATCH2_NAND_NWE 0x0020
+#define AMS_DELTA_LATCH2_NAND_ALE 0x0040
+#define AMS_DELTA_LATCH2_NAND_CLE 0x0080
+#define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100
+#define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200
+#define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400
+#define AMD_DELTA_LATCH2_SCARD_CMDVCC 0x0800
+#define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000
+#define AMS_DELTA_LATCH2_MODEM_CODEC 0x2000
+
+#define AMS_DELTA_GPIO_PIN_KEYBRD_DATA 0
+#define AMS_DELTA_GPIO_PIN_KEYBRD_CLK 1
+#define AMS_DELTA_GPIO_PIN_MODEM_IRQ 2
+#define AMS_DELTA_GPIO_PIN_HOOK_SWITCH 4
+#define AMS_DELTA_GPIO_PIN_SCARD_NOFF 6
+#define AMS_DELTA_GPIO_PIN_SCARD_IO 7
+#define AMS_DELTA_GPIO_PIN_CONFIG 11
+#define AMS_DELTA_GPIO_PIN_NAND_RB 12
+
+#ifndef __ASSEMBLY__
+void ams_delta_latch1_write(u8 mask, u8 value);
+void ams_delta_latch2_write(u16 mask, u16 value);
+#endif
+
+#endif /* CONFIG_MACH_AMS_DELTA */
+
+#endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */
diff --git a/arch/arm/plat-omap/include/plat/board-sx1.h b/arch/arm/plat-omap/include/plat/board-sx1.h
new file mode 100644
index 00000000..355adbda
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/board-sx1.h
@@ -0,0 +1,52 @@
+/*
+ * Siemens SX1 board definitions
+ *
+ * Copyright: Vovan888 at gmail com
+ *
+ * This package is free software; you can 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef __ASM_ARCH_SX1_I2C_CHIPS_H
+#define __ASM_ARCH_SX1_I2C_CHIPS_H
+
+#define SOFIA_MAX_LIGHT_VAL 0x2B
+
+#define SOFIA_I2C_ADDR 0x32
+/* Sofia reg 3 bits masks */
+#define SOFIA_POWER1_REG 0x03
+
+#define SOFIA_USB_POWER 0x01
+#define SOFIA_MMC_POWER 0x04
+#define SOFIA_BLUETOOTH_POWER 0x08
+#define SOFIA_MMILIGHT_POWER 0x20
+
+#define SOFIA_POWER2_REG 0x04
+#define SOFIA_BACKLIGHT_REG 0x06
+#define SOFIA_KEYLIGHT_REG 0x07
+#define SOFIA_DIMMING_REG 0x09
+
+
+/* Function Prototypes for SX1 devices control on I2C bus */
+
+int sx1_setbacklight(u8 backlight);
+int sx1_getbacklight(u8 *backlight);
+int sx1_setkeylight(u8 keylight);
+int sx1_getkeylight(u8 *keylight);
+
+int sx1_setmmipower(u8 onoff);
+int sx1_setusbpower(u8 onoff);
+int sx1_i2c_read_byte(u8 devaddr, u8 regoffset, u8 *value);
+int sx1_i2c_write_byte(u8 devaddr, u8 regoffset, u8 value);
+
+/* MMC prototypes */
+
+extern void sx1_mmc_init(void);
+extern void sx1_mmc_slot_cover_handler(void *arg, int state);
+
+#endif /* __ASM_ARCH_SX1_I2C_CHIPS_H */
diff --git a/arch/arm/plat-omap/include/plat/board-voiceblue.h b/arch/arm/plat-omap/include/plat/board-voiceblue.h
new file mode 100644
index 00000000..27916b21
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/board-voiceblue.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz>
+ *
+ * Hardware definitions for OMAP5910 based VoiceBlue 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.
+ */
+
+#ifndef __ASM_ARCH_VOICEBLUE_H
+#define __ASM_ARCH_VOICEBLUE_H
+
+extern void voiceblue_wdt_enable(void);
+extern void voiceblue_wdt_disable(void);
+extern void voiceblue_wdt_ping(void);
+
+#endif /* __ASM_ARCH_VOICEBLUE_H */
+
diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h
new file mode 100644
index 00000000..97126dfd
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/board.h
@@ -0,0 +1,176 @@
+/*
+ * arch/arm/plat-omap/include/mach/board.h
+ *
+ * Information structures for board-specific data
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ */
+
+#ifndef _OMAP_BOARD_H
+#define _OMAP_BOARD_H
+
+#include <linux/types.h>
+
+#include <plat/gpio-switch.h>
+
+/*
+ * OMAP35x EVM revision
+ * Run time detection of EVM revision is done by reading Ethernet
+ * PHY ID -
+ * GEN_1 = 0x01150000
+ * GEN_2 = 0x92200000
+ */
+enum {
+ OMAP3EVM_BOARD_GEN_1 = 0, /* EVM Rev between A - D */
+ OMAP3EVM_BOARD_GEN_2, /* EVM Rev >= Rev E */
+};
+
+/* Different peripheral ids */
+#define OMAP_TAG_CLOCK 0x4f01
+#define OMAP_TAG_LCD 0x4f05
+#define OMAP_TAG_GPIO_SWITCH 0x4f06
+#define OMAP_TAG_FBMEM 0x4f08
+#define OMAP_TAG_STI_CONSOLE 0x4f09
+#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
+
+#define OMAP_TAG_BOOT_REASON 0x4f80
+#define OMAP_TAG_FLASH_PART 0x4f81
+#define OMAP_TAG_VERSION_STR 0x4f82
+
+struct omap_clock_config {
+ /* 0 for 12 MHz, 1 for 13 MHz and 2 for 19.2 MHz */
+ u8 system_clock_type;
+};
+
+struct omap_serial_console_config {
+ u8 console_uart;
+ u32 console_speed;
+};
+
+struct omap_sti_console_config {
+ unsigned enable:1;
+ u8 channel;
+};
+
+struct omap_camera_sensor_config {
+ u16 reset_gpio;
+ int (*power_on)(void * data);
+ int (*power_off)(void * data);
+};
+
+struct omap_usb_config {
+ /* Configure drivers according to the connectors on your board:
+ * - "A" connector (rectagular)
+ * ... for host/OHCI use, set "register_host".
+ * - "B" connector (squarish) or "Mini-B"
+ * ... for device/gadget use, set "register_dev".
+ * - "Mini-AB" connector (very similar to Mini-B)
+ * ... for OTG use as device OR host, initialize "otg"
+ */
+ unsigned register_host:1;
+ unsigned register_dev:1;
+ u8 otg; /* port number, 1-based: usb1 == 2 */
+
+ u8 hmc_mode;
+
+ /* implicitly true if otg: host supports remote wakeup? */
+ u8 rwc;
+
+ /* signaling pins used to talk to transceiver on usbN:
+ * 0 == usbN unused
+ * 2 == usb0-only, using internal transceiver
+ * 3 == 3 wire bidirectional
+ * 4 == 4 wire bidirectional
+ * 6 == 6 wire unidirectional (or TLL)
+ */
+ u8 pins[3];
+
+ struct platform_device *udc_device;
+ struct platform_device *ohci_device;
+ struct platform_device *otg_device;
+
+ u32 (*usb0_init)(unsigned nwires, unsigned is_device);
+ u32 (*usb1_init)(unsigned nwires);
+ u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup);
+};
+
+struct omap_lcd_config {
+ char panel_name[16];
+ char ctrl_name[16];
+ s16 nreset_gpio;
+ u8 data_lines;
+};
+
+struct device;
+struct fb_info;
+struct omap_backlight_config {
+ int default_intensity;
+ int (*set_power)(struct device *dev, int state);
+};
+
+struct omap_fbmem_config {
+ u32 start;
+ u32 size;
+};
+
+struct omap_pwm_led_platform_data {
+ const char *name;
+ int intensity_timer;
+ int blink_timer;
+ void (*set_power)(struct omap_pwm_led_platform_data *self, int on_off);
+};
+
+struct omap_uart_config {
+ /* Bit field of UARTs present; bit 0 --> UART1 */
+ unsigned int enabled_uarts;
+};
+
+
+struct omap_flash_part_config {
+ char part_table[0];
+};
+
+struct omap_boot_reason_config {
+ char reason_str[12];
+};
+
+struct omap_version_config {
+ char component[12];
+ char version[12];
+};
+
+struct omap_board_config_entry {
+ u16 tag;
+ u16 len;
+ u8 data[0];
+};
+
+struct omap_board_config_kernel {
+ u16 tag;
+ const void *data;
+};
+
+extern const void *__init __omap_get_config(u16 tag, size_t len, int nr);
+
+#define omap_get_config(tag, type) \
+ ((const type *) __omap_get_config((tag), sizeof(type), 0))
+#define omap_get_nr_config(tag, type, nr) \
+ ((const type *) __omap_get_config((tag), sizeof(type), (nr)))
+
+extern const void *__init omap_get_var_config(u16 tag, size_t *len);
+
+extern struct omap_board_config_kernel *omap_board_config;
+extern int omap_board_config_size;
+
+
+/* for TI reference platforms sharing the same debug card */
+extern int debug_card_init(u32 addr, unsigned gpio);
+
+/* OMAP3EVM revision */
+#if defined(CONFIG_MACH_OMAP3EVM)
+u8 get_omap3_evm_rev(void);
+#else
+#define get_omap3_evm_rev() (-EINVAL)
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/clkdev.h b/arch/arm/plat-omap/include/plat/clkdev.h
new file mode 100644
index 00000000..730c49d1
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/clkdev.h
@@ -0,0 +1,13 @@
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h
new file mode 100644
index 00000000..f1899a3e
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h
@@ -0,0 +1,50 @@
+/*
+ * clkdev <-> OMAP integration
+ *
+ * Russell King <linux@arm.linux.org.uk>
+ *
+ */
+
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_CLKDEV_OMAP_H
+
+#include <linux/clkdev.h>
+
+struct omap_clk {
+ u16 cpu;
+ struct clk_lookup lk;
+};
+
+#define CLK(dev, con, ck, cp) \
+ { \
+ .cpu = cp, \
+ .lk = { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }, \
+ }
+
+/* Platform flags for the clkdev-OMAP integration code */
+#define CK_310 (1 << 0)
+#define CK_7XX (1 << 1) /* 7xx, 850 */
+#define CK_1510 (1 << 2)
+#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
+#define CK_242X (1 << 4)
+#define CK_243X (1 << 5) /* 243x, 253x */
+#define CK_3430ES1 (1 << 6) /* 34xxES1 only */
+#define CK_3430ES2PLUS (1 << 7) /* 34xxES2, ES3, non-Sitara 35xx only */
+#define CK_3505 (1 << 8)
+#define CK_3517 (1 << 9)
+#define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */
+#define CK_443X (1 << 11)
+#define CK_TI816X (1 << 12)
+
+
+#define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS)
+#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */
+#define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX)
+
+
+#endif
+
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
new file mode 100644
index 00000000..006e599c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -0,0 +1,314 @@
+/*
+ * OMAP clock: data structure definitions, function prototypes, shared macros
+ *
+ * Copyright (C) 2004-2005, 2008-2010 Nokia Corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_OMAP_CLOCK_H
+#define __ARCH_ARM_OMAP_CLOCK_H
+
+#include <linux/list.h>
+
+struct module;
+struct clk;
+struct clockdomain;
+
+/**
+ * struct clkops - some clock function pointers
+ * @enable: fn ptr that enables the current clock in hardware
+ * @disable: fn ptr that enables the current clock in hardware
+ * @find_idlest: function returning the IDLEST register for the clock's IP blk
+ * @find_companion: function returning the "companion" clk reg for the clock
+ * @allow_idle: fn ptr that enables autoidle for the current clock in hardware
+ * @deny_idle: fn ptr that disables autoidle for the current clock in hardware
+ *
+ * A "companion" clk is an accompanying clock to the one being queried
+ * that must be enabled for the IP module connected to the clock to
+ * become accessible by the hardware. Neither @find_idlest nor
+ * @find_companion should be needed; that information is IP
+ * block-specific; the hwmod code has been created to handle this, but
+ * until hwmod data is ready and drivers have been converted to use PM
+ * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
+ * @find_companion must, unfortunately, remain.
+ */
+struct clkops {
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ void (*find_idlest)(struct clk *, void __iomem **,
+ u8 *, u8 *);
+ void (*find_companion)(struct clk *, void __iomem **,
+ u8 *);
+ void (*allow_idle)(struct clk *);
+ void (*deny_idle)(struct clk *);
+};
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+/* struct clksel_rate.flags possibilities */
+#define RATE_IN_242X (1 << 0)
+#define RATE_IN_243X (1 << 1)
+#define RATE_IN_3430ES1 (1 << 2) /* 3430ES1 rates only */
+#define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */
+#define RATE_IN_36XX (1 << 4)
+#define RATE_IN_4430 (1 << 5)
+#define RATE_IN_TI816X (1 << 6)
+
+#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
+#define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS)
+#define RATE_IN_3XXX (RATE_IN_34XX | RATE_IN_36XX)
+
+/* RATE_IN_3430ES2PLUS_36XX includes 34xx/35xx with ES >=2, and all 36xx/37xx */
+#define RATE_IN_3430ES2PLUS_36XX (RATE_IN_3430ES2PLUS | RATE_IN_36XX)
+
+
+/**
+ * struct clksel_rate - register bitfield values corresponding to clk divisors
+ * @val: register bitfield value (shifted to bit 0)
+ * @div: clock divisor corresponding to @val
+ * @flags: (see "struct clksel_rate.flags possibilities" above)
+ *
+ * @val should match the value of a read from struct clk.clksel_reg
+ * AND'ed with struct clk.clksel_mask, shifted right to bit 0.
+ *
+ * @div is the divisor that should be applied to the parent clock's rate
+ * to produce the current clock's rate.
+ *
+ * XXX @flags probably should be replaced with an struct omap_chip.
+ */
+struct clksel_rate {
+ u32 val;
+ u8 div;
+ u8 flags;
+};
+
+/**
+ * struct clksel - available parent clocks, and a pointer to their divisors
+ * @parent: struct clk * to a possible parent clock
+ * @rates: available divisors for this parent clock
+ *
+ * A struct clksel is always associated with one or more struct clks
+ * and one or more struct clksel_rates.
+ */
+struct clksel {
+ struct clk *parent;
+ const struct clksel_rate *rates;
+};
+
+/**
+ * struct dpll_data - DPLL registers and integration data
+ * @mult_div1_reg: register containing the DPLL M and N bitfields
+ * @mult_mask: mask of the DPLL M bitfield in @mult_div1_reg
+ * @div1_mask: mask of the DPLL N bitfield in @mult_div1_reg
+ * @clk_bypass: struct clk pointer to the clock's bypass clock input
+ * @clk_ref: struct clk pointer to the clock's reference clock input
+ * @control_reg: register containing the DPLL mode bitfield
+ * @enable_mask: mask of the DPLL mode bitfield in @control_reg
+ * @last_rounded_rate: cache of the last rate result of omap2_dpll_round_rate()
+ * @last_rounded_m: cache of the last M result of omap2_dpll_round_rate()
+ * @max_multiplier: maximum valid non-bypass multiplier value (actual)
+ * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate()
+ * @min_divider: minimum valid non-bypass divider value (actual)
+ * @max_divider: maximum valid non-bypass divider value (actual)
+ * @modes: possible values of @enable_mask
+ * @autoidle_reg: register containing the DPLL autoidle mode bitfield
+ * @idlest_reg: register containing the DPLL idle status bitfield
+ * @autoidle_mask: mask of the DPLL autoidle mode bitfield in @autoidle_reg
+ * @freqsel_mask: mask of the DPLL jitter correction bitfield in @control_reg
+ * @idlest_mask: mask of the DPLL idle status bitfield in @idlest_reg
+ * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg
+ * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs
+ * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs
+ * @flags: DPLL type/features (see below)
+ *
+ * Possible values for @flags:
+ * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs)
+ *
+ * @freqsel_mask is only used on the OMAP34xx family and AM35xx.
+ *
+ * XXX Some DPLLs have multiple bypass inputs, so it's not technically
+ * correct to only have one @clk_bypass pointer.
+ *
+ * XXX The runtime-variable fields (@last_rounded_rate, @last_rounded_m,
+ * @last_rounded_n) should be separated from the runtime-fixed fields
+ * and placed into a different structure, so that the runtime-fixed data
+ * can be placed into read-only space.
+ */
+struct dpll_data {
+ void __iomem *mult_div1_reg;
+ u32 mult_mask;
+ u32 div1_mask;
+ struct clk *clk_bypass;
+ struct clk *clk_ref;
+ void __iomem *control_reg;
+ u32 enable_mask;
+ unsigned long last_rounded_rate;
+ u16 last_rounded_m;
+ u16 max_multiplier;
+ u8 last_rounded_n;
+ u8 min_divider;
+ u8 max_divider;
+ u8 modes;
+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
+ void __iomem *autoidle_reg;
+ void __iomem *idlest_reg;
+ u32 autoidle_mask;
+ u32 freqsel_mask;
+ u32 idlest_mask;
+ u32 dco_mask;
+ u32 sddiv_mask;
+ u8 auto_recal_bit;
+ u8 recal_en_bit;
+ u8 recal_st_bit;
+ u8 flags;
+# endif
+};
+
+#endif
+
+/*
+ * struct clk.flags possibilities
+ *
+ * XXX document the rest of the clock flags here
+ *
+ * CLOCK_CLKOUTX2: (OMAP4 only) DPLL CLKOUT and CLKOUTX2 GATE_CTRL
+ * bits share the same register. This flag allows the
+ * omap4_dpllmx*() code to determine which GATE_CTRL bit field
+ * should be used. This is a temporary solution - a better approach
+ * would be to associate clock type-specific data with the clock,
+ * similar to the struct dpll_data approach.
+ */
+#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
+#define CLOCK_IDLE_CONTROL (1 << 1)
+#define CLOCK_NO_IDLE_PARENT (1 << 2)
+#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
+#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
+#define CLOCK_CLKOUTX2 (1 << 5)
+
+/**
+ * struct clk - OMAP struct clk
+ * @node: list_head connecting this clock into the full clock list
+ * @ops: struct clkops * for this clock
+ * @name: the name of the clock in the hardware (used in hwmod data and debug)
+ * @parent: pointer to this clock's parent struct clk
+ * @children: list_head connecting to the child clks' @sibling list_heads
+ * @sibling: list_head connecting this clk to its parent clk's @children
+ * @rate: current clock rate
+ * @enable_reg: register to write to enable the clock (see @enable_bit)
+ * @recalc: fn ptr that returns the clock's current rate
+ * @set_rate: fn ptr that can change the clock's current rate
+ * @round_rate: fn ptr that can round the clock's current rate
+ * @init: fn ptr to do clock-specific initialization
+ * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
+ * @usecount: number of users that have requested this clock to be enabled
+ * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
+ * @flags: see "struct clk.flags possibilities" above
+ * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
+ * @clksel: for clksel clks, pointer to struct clksel for this clock
+ * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
+ * @clkdm_name: clockdomain name that this clock is contained in
+ * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
+ * @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
+ * @src_offset: bitshift for source selection bitfield (OMAP1 only)
+ *
+ * XXX @rate_offset, @src_offset should probably be removed and OMAP1
+ * clock code converted to use clksel.
+ *
+ * XXX @usecount is poorly named. It should be "enable_count" or
+ * something similar. "users" in the description refers to kernel
+ * code (core code or drivers) that have called clk_enable() and not
+ * yet called clk_disable(); the usecount of parent clocks is also
+ * incremented by the clock code when clk_enable() is called on child
+ * clocks and decremented by the clock code when clk_disable() is
+ * called on child clocks.
+ *
+ * XXX @clkdm, @usecount, @children, @sibling should be marked for
+ * internal use only.
+ *
+ * @children and @sibling are used to optimize parent-to-child clock
+ * tree traversals. (child-to-parent traversals use @parent.)
+ *
+ * XXX The notion of the clock's current rate probably needs to be
+ * separated from the clock's target rate.
+ */
+struct clk {
+ struct list_head node;
+ const struct clkops *ops;
+ const char *name;
+ struct clk *parent;
+ struct list_head children;
+ struct list_head sibling; /* node for children */
+ unsigned long rate;
+ void __iomem *enable_reg;
+ unsigned long (*recalc)(struct clk *);
+ int (*set_rate)(struct clk *, unsigned long);
+ long (*round_rate)(struct clk *, unsigned long);
+ void (*init)(struct clk *);
+ u8 enable_bit;
+ s8 usecount;
+ u8 fixed_div;
+ u8 flags;
+#ifdef CONFIG_ARCH_OMAP2PLUS
+ void __iomem *clksel_reg;
+ u32 clksel_mask;
+ const struct clksel *clksel;
+ struct dpll_data *dpll_data;
+ const char *clkdm_name;
+ struct clockdomain *clkdm;
+#else
+ u8 rate_offset;
+ u8 src_offset;
+#endif
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+#endif
+};
+
+struct cpufreq_frequency_table;
+
+struct clk_functions {
+ int (*clk_enable)(struct clk *clk);
+ void (*clk_disable)(struct clk *clk);
+ long (*clk_round_rate)(struct clk *clk, unsigned long rate);
+ int (*clk_set_rate)(struct clk *clk, unsigned long rate);
+ int (*clk_set_parent)(struct clk *clk, struct clk *parent);
+ void (*clk_allow_idle)(struct clk *clk);
+ void (*clk_deny_idle)(struct clk *clk);
+ void (*clk_disable_unused)(struct clk *clk);
+#ifdef CONFIG_CPU_FREQ
+ void (*clk_init_cpufreq_table)(struct cpufreq_frequency_table **);
+ void (*clk_exit_cpufreq_table)(struct cpufreq_frequency_table **);
+#endif
+};
+
+extern int mpurate;
+
+extern int clk_init(struct clk_functions *custom_clocks);
+extern void clk_preinit(struct clk *clk);
+extern int clk_register(struct clk *clk);
+extern void clk_reparent(struct clk *child, struct clk *parent);
+extern void clk_unregister(struct clk *clk);
+extern void propagate_rate(struct clk *clk);
+extern void recalculate_root_clocks(void);
+extern unsigned long followparent_recalc(struct clk *clk);
+extern void clk_enable_init_clocks(void);
+unsigned long omap_fixed_divisor_recalc(struct clk *clk);
+#ifdef CONFIG_CPU_FREQ
+extern void clk_init_cpufreq_table(struct cpufreq_frequency_table **table);
+extern void clk_exit_cpufreq_table(struct cpufreq_frequency_table **table);
+#endif
+extern struct clk *omap_clk_get_by_name(const char *name);
+extern int omap_clk_enable_autoidle_all(void);
+extern int omap_clk_disable_autoidle_all(void);
+
+extern const struct clkops clkops_null;
+
+extern struct clk dummy_ck;
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
new file mode 100644
index 00000000..5288130b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -0,0 +1,100 @@
+/*
+ * arch/arm/plat-omap/include/mach/common.h
+ *
+ * Header for code common to all OMAP machines.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
+#define __ARCH_ARM_MACH_OMAP_COMMON_H
+
+#include <linux/delay.h>
+
+#include <plat/i2c.h>
+
+struct sys_timer;
+
+extern void omap_map_common_io(void);
+extern struct sys_timer omap_timer;
+extern bool omap_32k_timer_init(void);
+extern int __init omap_init_clocksource_32k(void);
+extern unsigned long long notrace omap_32k_sched_clock(void);
+
+extern void omap_reserve(void);
+
+/*
+ * IO bases for various OMAP processors
+ * Except the tap base, rest all the io bases
+ * listed are physical addresses.
+ */
+struct omap_globals {
+ u32 class; /* OMAP class to detect */
+ void __iomem *tap; /* Control module ID code */
+ unsigned long sdrc; /* SDRAM Controller */
+ unsigned long sms; /* SDRAM Memory Scheduler */
+ unsigned long ctrl; /* System Control Module */
+ unsigned long ctrl_pad; /* PAD Control Module */
+ unsigned long prm; /* Power and Reset Management */
+ unsigned long cm; /* Clock Management */
+ unsigned long cm2;
+};
+
+void omap2_set_globals_242x(void);
+void omap2_set_globals_243x(void);
+void omap2_set_globals_3xxx(void);
+void omap2_set_globals_443x(void);
+void omap2_set_globals_ti816x(void);
+
+/* These get called from omap2_set_globals_xxxx(), do not call these */
+void omap2_set_globals_tap(struct omap_globals *);
+void omap2_set_globals_sdrc(struct omap_globals *);
+void omap2_set_globals_control(struct omap_globals *);
+void omap2_set_globals_prcm(struct omap_globals *);
+
+void omap3_map_io(void);
+
+/**
+ * omap_test_timeout - busy-loop, testing a condition
+ * @cond: condition to test until it evaluates to true
+ * @timeout: maximum number of microseconds in the timeout
+ * @index: loop index (integer)
+ *
+ * Loop waiting for @cond to become true or until at least @timeout
+ * microseconds have passed. To use, define some integer @index in the
+ * calling code. After running, if @index == @timeout, then the loop has
+ * timed out.
+ */
+#define omap_test_timeout(cond, timeout, index) \
+({ \
+ for (index = 0; index < timeout; index++) { \
+ if (cond) \
+ break; \
+ udelay(1); \
+ } \
+})
+
+extern struct device *omap2_get_mpuss_device(void);
+extern struct device *omap2_get_iva_device(void);
+extern struct device *omap2_get_l3_device(void);
+extern struct device *omap4_get_dsp_device(void);
+
+#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
new file mode 100644
index 00000000..8198bb6c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -0,0 +1,497 @@
+/*
+ * arch/arm/plat-omap/include/mach/cpu.h
+ *
+ * OMAP cpu type detection
+ *
+ * Copyright (C) 2004, 2008 Nokia Corporation
+ *
+ * Copyright (C) 2009-11 Texas Instruments.
+ *
+ * Written by Tony Lindgren <tony.lindgren@nokia.com>
+ *
+ * Added OMAP4 specific defines - Santosh Shilimkar<santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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 __ASM_ARCH_OMAP_CPU_H
+#define __ASM_ARCH_OMAP_CPU_H
+
+#include <linux/bitops.h>
+#include <plat/multi.h>
+
+/*
+ * Omap device type i.e. EMU/HS/TST/GP/BAD
+ */
+#define OMAP2_DEVICE_TYPE_TEST 0
+#define OMAP2_DEVICE_TYPE_EMU 1
+#define OMAP2_DEVICE_TYPE_SEC 2
+#define OMAP2_DEVICE_TYPE_GP 3
+#define OMAP2_DEVICE_TYPE_BAD 4
+
+int omap_type(void);
+
+struct omap_chip_id {
+ u16 oc;
+ u8 type;
+};
+
+#define OMAP_CHIP_INIT(x) { .oc = x }
+
+/*
+ * omap_rev bits:
+ * CPU id bits (0730, 1510, 1710, 2422...) [31:16]
+ * CPU revision (See _REV_ defined in cpu.h) [15:08]
+ * CPU class bits (15xx, 16xx, 24xx, 34xx...) [07:00]
+ */
+unsigned int omap_rev(void);
+
+/*
+ * Define CPU revision bits
+ *
+ * Verbose meaning of the revision bits may be different for a silicon
+ * family. This difference can be handled separately.
+ */
+#define OMAP_REVBITS_00 0x00
+#define OMAP_REVBITS_01 0x01
+#define OMAP_REVBITS_02 0x02
+#define OMAP_REVBITS_03 0x03
+#define OMAP_REVBITS_04 0x04
+#define OMAP_REVBITS_05 0x05
+
+/*
+ * Get the CPU revision for OMAP devices
+ */
+#define GET_OMAP_REVISION() ((omap_rev() >> 8) & 0xff)
+
+/*
+ * Macros to group OMAP into cpu classes.
+ * These can be used in most places.
+ * cpu_is_omap7xx(): True for OMAP730, OMAP850
+ * cpu_is_omap15xx(): True for OMAP1510, OMAP5910 and OMAP310
+ * cpu_is_omap16xx(): True for OMAP1610, OMAP5912 and OMAP1710
+ * cpu_is_omap24xx(): True for OMAP2420, OMAP2422, OMAP2423, OMAP2430
+ * cpu_is_omap242x(): True for OMAP2420, OMAP2422, OMAP2423
+ * cpu_is_omap243x(): True for OMAP2430
+ * cpu_is_omap343x(): True for OMAP3430
+ * cpu_is_omap443x(): True for OMAP4430
+ */
+#define GET_OMAP_CLASS (omap_rev() & 0xff)
+
+#define IS_OMAP_CLASS(class, id) \
+static inline int is_omap ##class (void) \
+{ \
+ return (GET_OMAP_CLASS == (id)) ? 1 : 0; \
+}
+
+#define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff)
+
+#define IS_OMAP_SUBCLASS(subclass, id) \
+static inline int is_omap ##subclass (void) \
+{ \
+ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
+}
+
+#define IS_TI_SUBCLASS(subclass, id) \
+static inline int is_ti ##subclass (void) \
+{ \
+ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \
+}
+
+IS_OMAP_CLASS(7xx, 0x07)
+IS_OMAP_CLASS(15xx, 0x15)
+IS_OMAP_CLASS(16xx, 0x16)
+IS_OMAP_CLASS(24xx, 0x24)
+IS_OMAP_CLASS(34xx, 0x34)
+IS_OMAP_CLASS(44xx, 0x44)
+
+IS_OMAP_SUBCLASS(242x, 0x242)
+IS_OMAP_SUBCLASS(243x, 0x243)
+IS_OMAP_SUBCLASS(343x, 0x343)
+IS_OMAP_SUBCLASS(363x, 0x363)
+IS_OMAP_SUBCLASS(443x, 0x443)
+
+IS_TI_SUBCLASS(816x, 0x816)
+
+#define cpu_is_omap7xx() 0
+#define cpu_is_omap15xx() 0
+#define cpu_is_omap16xx() 0
+#define cpu_is_omap24xx() 0
+#define cpu_is_omap242x() 0
+#define cpu_is_omap243x() 0
+#define cpu_is_omap34xx() 0
+#define cpu_is_omap343x() 0
+#define cpu_is_ti816x() 0
+#define cpu_is_omap44xx() 0
+#define cpu_is_omap443x() 0
+
+#if defined(MULTI_OMAP1)
+# if defined(CONFIG_ARCH_OMAP730)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() is_omap7xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() is_omap7xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP15XX)
+# undef cpu_is_omap15xx
+# define cpu_is_omap15xx() is_omap15xx()
+# endif
+# if defined(CONFIG_ARCH_OMAP16XX)
+# undef cpu_is_omap16xx
+# define cpu_is_omap16xx() is_omap16xx()
+# endif
+#else
+# if defined(CONFIG_ARCH_OMAP730)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() 1
+# endif
+# if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap7xx
+# define cpu_is_omap7xx() 1
+# endif
+# if defined(CONFIG_ARCH_OMAP15XX)
+# undef cpu_is_omap15xx
+# define cpu_is_omap15xx() 1
+# endif
+# if defined(CONFIG_ARCH_OMAP16XX)
+# undef cpu_is_omap16xx
+# define cpu_is_omap16xx() 1
+# endif
+#endif
+
+#if defined(MULTI_OMAP2)
+# if defined(CONFIG_ARCH_OMAP2)
+# undef cpu_is_omap24xx
+# define cpu_is_omap24xx() is_omap24xx()
+# endif
+# if defined (CONFIG_SOC_OMAP2420)
+# undef cpu_is_omap242x
+# define cpu_is_omap242x() is_omap242x()
+# endif
+# if defined (CONFIG_SOC_OMAP2430)
+# undef cpu_is_omap243x
+# define cpu_is_omap243x() is_omap243x()
+# endif
+# if defined(CONFIG_ARCH_OMAP3)
+# undef cpu_is_omap34xx
+# undef cpu_is_omap343x
+# define cpu_is_omap34xx() is_omap34xx()
+# define cpu_is_omap343x() is_omap343x()
+# endif
+#else
+# if defined(CONFIG_ARCH_OMAP2)
+# undef cpu_is_omap24xx
+# define cpu_is_omap24xx() 1
+# endif
+# if defined(CONFIG_SOC_OMAP2420)
+# undef cpu_is_omap242x
+# define cpu_is_omap242x() 1
+# endif
+# if defined(CONFIG_SOC_OMAP2430)
+# undef cpu_is_omap243x
+# define cpu_is_omap243x() 1
+# endif
+# if defined(CONFIG_ARCH_OMAP3)
+# undef cpu_is_omap34xx
+# define cpu_is_omap34xx() 1
+# endif
+# if defined(CONFIG_SOC_OMAP3430)
+# undef cpu_is_omap343x
+# define cpu_is_omap343x() 1
+# endif
+#endif
+
+/*
+ * Macros to detect individual cpu types.
+ * These are only rarely needed.
+ * cpu_is_omap330(): True for OMAP330
+ * cpu_is_omap730(): True for OMAP730
+ * cpu_is_omap850(): True for OMAP850
+ * cpu_is_omap1510(): True for OMAP1510
+ * cpu_is_omap1610(): True for OMAP1610
+ * cpu_is_omap1611(): True for OMAP1611
+ * cpu_is_omap5912(): True for OMAP5912
+ * cpu_is_omap1621(): True for OMAP1621
+ * cpu_is_omap1710(): True for OMAP1710
+ * cpu_is_omap2420(): True for OMAP2420
+ * cpu_is_omap2422(): True for OMAP2422
+ * cpu_is_omap2423(): True for OMAP2423
+ * cpu_is_omap2430(): True for OMAP2430
+ * cpu_is_omap3430(): True for OMAP3430
+ * cpu_is_omap4430(): True for OMAP4430
+ * cpu_is_omap3505(): True for OMAP3505
+ * cpu_is_omap3517(): True for OMAP3517
+ */
+#define GET_OMAP_TYPE ((omap_rev() >> 16) & 0xffff)
+
+#define IS_OMAP_TYPE(type, id) \
+static inline int is_omap ##type (void) \
+{ \
+ return (GET_OMAP_TYPE == (id)) ? 1 : 0; \
+}
+
+IS_OMAP_TYPE(310, 0x0310)
+IS_OMAP_TYPE(730, 0x0730)
+IS_OMAP_TYPE(850, 0x0850)
+IS_OMAP_TYPE(1510, 0x1510)
+IS_OMAP_TYPE(1610, 0x1610)
+IS_OMAP_TYPE(1611, 0x1611)
+IS_OMAP_TYPE(5912, 0x1611)
+IS_OMAP_TYPE(1621, 0x1621)
+IS_OMAP_TYPE(1710, 0x1710)
+IS_OMAP_TYPE(2420, 0x2420)
+IS_OMAP_TYPE(2422, 0x2422)
+IS_OMAP_TYPE(2423, 0x2423)
+IS_OMAP_TYPE(2430, 0x2430)
+IS_OMAP_TYPE(3430, 0x3430)
+IS_OMAP_TYPE(3505, 0x3505)
+IS_OMAP_TYPE(3517, 0x3517)
+
+#define cpu_is_omap310() 0
+#define cpu_is_omap730() 0
+#define cpu_is_omap850() 0
+#define cpu_is_omap1510() 0
+#define cpu_is_omap1610() 0
+#define cpu_is_omap5912() 0
+#define cpu_is_omap1611() 0
+#define cpu_is_omap1621() 0
+#define cpu_is_omap1710() 0
+#define cpu_is_omap2420() 0
+#define cpu_is_omap2422() 0
+#define cpu_is_omap2423() 0
+#define cpu_is_omap2430() 0
+#define cpu_is_omap3503() 0
+#define cpu_is_omap3515() 0
+#define cpu_is_omap3525() 0
+#define cpu_is_omap3530() 0
+#define cpu_is_omap3505() 0
+#define cpu_is_omap3517() 0
+#define cpu_is_omap3430() 0
+#define cpu_is_omap4430() 0
+#define cpu_is_omap3630() 0
+
+/*
+ * Whether we have MULTI_OMAP1 or not, we still need to distinguish
+ * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
+ */
+
+#if defined(CONFIG_ARCH_OMAP730)
+# undef cpu_is_omap730
+# define cpu_is_omap730() is_omap730()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP850)
+# undef cpu_is_omap850
+# define cpu_is_omap850() is_omap850()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP15XX)
+# undef cpu_is_omap310
+# undef cpu_is_omap1510
+# define cpu_is_omap310() is_omap310()
+# define cpu_is_omap1510() is_omap1510()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP16XX)
+# undef cpu_is_omap1610
+# undef cpu_is_omap1611
+# undef cpu_is_omap5912
+# undef cpu_is_omap1621
+# undef cpu_is_omap1710
+# define cpu_is_omap1610() is_omap1610()
+# define cpu_is_omap1611() is_omap1611()
+# define cpu_is_omap5912() is_omap5912()
+# define cpu_is_omap1621() is_omap1621()
+# define cpu_is_omap1710() is_omap1710()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2)
+# undef cpu_is_omap2420
+# undef cpu_is_omap2422
+# undef cpu_is_omap2423
+# undef cpu_is_omap2430
+# define cpu_is_omap2420() is_omap2420()
+# define cpu_is_omap2422() is_omap2422()
+# define cpu_is_omap2423() is_omap2423()
+# define cpu_is_omap2430() is_omap2430()
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+# undef cpu_is_omap3430
+# undef cpu_is_omap3503
+# undef cpu_is_omap3515
+# undef cpu_is_omap3525
+# undef cpu_is_omap3530
+# undef cpu_is_omap3505
+# undef cpu_is_omap3517
+# undef cpu_is_ti816x
+# define cpu_is_omap3430() is_omap3430()
+# define cpu_is_omap3503() (cpu_is_omap3430() && \
+ (!omap3_has_iva()) && \
+ (!omap3_has_sgx()))
+# define cpu_is_omap3515() (cpu_is_omap3430() && \
+ (!omap3_has_iva()) && \
+ (omap3_has_sgx()))
+# define cpu_is_omap3525() (cpu_is_omap3430() && \
+ (!omap3_has_sgx()) && \
+ (omap3_has_iva()))
+# define cpu_is_omap3530() (cpu_is_omap3430())
+# define cpu_is_omap3505() is_omap3505()
+# define cpu_is_omap3517() is_omap3517()
+# undef cpu_is_omap3630
+# define cpu_is_omap3630() is_omap363x()
+# define cpu_is_ti816x() is_ti816x()
+#endif
+
+# if defined(CONFIG_ARCH_OMAP4)
+# undef cpu_is_omap44xx
+# undef cpu_is_omap443x
+# define cpu_is_omap44xx() is_omap44xx()
+# define cpu_is_omap443x() is_omap443x()
+# endif
+
+/* Macros to detect if we have OMAP1 or OMAP2 */
+#define cpu_class_is_omap1() (cpu_is_omap7xx() || cpu_is_omap15xx() || \
+ cpu_is_omap16xx())
+#define cpu_class_is_omap2() (cpu_is_omap24xx() || cpu_is_omap34xx() || \
+ cpu_is_omap44xx())
+
+/* Various silicon revisions for omap2 */
+#define OMAP242X_CLASS 0x24200024
+#define OMAP2420_REV_ES1_0 OMAP242X_CLASS
+#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (OMAP_REVBITS_01 << 8))
+
+#define OMAP243X_CLASS 0x24300024
+#define OMAP2430_REV_ES1_0 OMAP243X_CLASS
+
+#define OMAP343X_CLASS 0x34300034
+#define OMAP3430_REV_ES1_0 OMAP343X_CLASS
+#define OMAP3430_REV_ES2_0 (OMAP343X_CLASS | (OMAP_REVBITS_01 << 8))
+#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (OMAP_REVBITS_02 << 8))
+#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (OMAP_REVBITS_03 << 8))
+#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (OMAP_REVBITS_04 << 8))
+#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (OMAP_REVBITS_05 << 8))
+
+#define OMAP363X_CLASS 0x36300034
+#define OMAP3630_REV_ES1_0 OMAP363X_CLASS
+#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (OMAP_REVBITS_01 << 8))
+#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (OMAP_REVBITS_02 << 8))
+
+#define OMAP35XX_CLASS 0x35000034
+#define OMAP3503_REV(v) (OMAP35XX_CLASS | (0x3503 << 16) | (v << 8))
+#define OMAP3515_REV(v) (OMAP35XX_CLASS | (0x3515 << 16) | (v << 8))
+#define OMAP3525_REV(v) (OMAP35XX_CLASS | (0x3525 << 16) | (v << 8))
+#define OMAP3530_REV(v) (OMAP35XX_CLASS | (0x3530 << 16) | (v << 8))
+#define OMAP3505_REV(v) (OMAP35XX_CLASS | (0x3505 << 16) | (v << 8))
+#define OMAP3517_REV(v) (OMAP35XX_CLASS | (0x3517 << 16) | (v << 8))
+
+#define TI816X_CLASS 0x81600034
+#define TI8168_REV_ES1_0 TI816X_CLASS
+#define TI8168_REV_ES1_1 (TI816X_CLASS | (OMAP_REVBITS_01 << 8))
+
+#define OMAP443X_CLASS 0x44300044
+#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8))
+#define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8))
+#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8))
+#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8))
+
+/*
+ * omap_chip bits
+ *
+ * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
+ * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates
+ * something that is only valid on that particular ES revision.
+ *
+ * These bits may be ORed together to indicate structures that are
+ * available on multiple chip types.
+ *
+ * To test whether a particular structure matches the current OMAP chip type,
+ * use omap_chip_is().
+ *
+ */
+#define CHIP_IS_OMAP2420 (1 << 0)
+#define CHIP_IS_OMAP2430 (1 << 1)
+#define CHIP_IS_OMAP3430 (1 << 2)
+#define CHIP_IS_OMAP3430ES1 (1 << 3)
+#define CHIP_IS_OMAP3430ES2 (1 << 4)
+#define CHIP_IS_OMAP3430ES3_0 (1 << 5)
+#define CHIP_IS_OMAP3430ES3_1 (1 << 6)
+#define CHIP_IS_OMAP3630ES1 (1 << 7)
+#define CHIP_IS_OMAP4430ES1 (1 << 8)
+#define CHIP_IS_OMAP3630ES1_1 (1 << 9)
+#define CHIP_IS_OMAP3630ES1_2 (1 << 10)
+#define CHIP_IS_OMAP4430ES2 (1 << 11)
+#define CHIP_IS_OMAP4430ES2_1 (1 << 12)
+#define CHIP_IS_OMAP4430ES2_2 (1 << 13)
+#define CHIP_IS_TI816X (1 << 14)
+
+#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
+
+#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \
+ CHIP_IS_OMAP4430ES2 | \
+ CHIP_IS_OMAP4430ES2_1 | \
+ CHIP_IS_OMAP4430ES2_2)
+
+/*
+ * "GE" here represents "greater than or equal to" in terms of ES
+ * levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
+ * chips at ES2 and beyond, but not, for example, any OMAP lines after
+ * OMAP3.
+ */
+#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \
+ CHIP_IS_OMAP3430ES3_0 | \
+ CHIP_GE_OMAP3430ES3_1)
+#define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1 | \
+ CHIP_IS_OMAP3630ES1 | \
+ CHIP_GE_OMAP3630ES1_1)
+#define CHIP_GE_OMAP3630ES1_1 (CHIP_IS_OMAP3630ES1_1 | \
+ CHIP_IS_OMAP3630ES1_2)
+
+int omap_chip_is(struct omap_chip_id oci);
+void omap2_check_revision(void);
+
+/*
+ * Runtime detection of OMAP3 features
+ */
+extern u32 omap3_features;
+
+#define OMAP3_HAS_L2CACHE BIT(0)
+#define OMAP3_HAS_IVA BIT(1)
+#define OMAP3_HAS_SGX BIT(2)
+#define OMAP3_HAS_NEON BIT(3)
+#define OMAP3_HAS_ISP BIT(4)
+#define OMAP3_HAS_192MHZ_CLK BIT(5)
+#define OMAP3_HAS_IO_WAKEUP BIT(6)
+#define OMAP3_HAS_SDRC BIT(7)
+
+#define OMAP3_HAS_FEATURE(feat,flag) \
+static inline unsigned int omap3_has_ ##feat(void) \
+{ \
+ return (omap3_features & OMAP3_HAS_ ##flag); \
+} \
+
+OMAP3_HAS_FEATURE(l2cache, L2CACHE)
+OMAP3_HAS_FEATURE(sgx, SGX)
+OMAP3_HAS_FEATURE(iva, IVA)
+OMAP3_HAS_FEATURE(neon, NEON)
+OMAP3_HAS_FEATURE(isp, ISP)
+OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
+OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
+OMAP3_HAS_FEATURE(sdrc, SDRC)
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/dma-44xx.h b/arch/arm/plat-omap/include/plat/dma-44xx.h
new file mode 100644
index 00000000..1f767cb2
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dma-44xx.h
@@ -0,0 +1,147 @@
+/*
+ * OMAP4 SDMA channel definitions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2010 Nokia Corporation
+ *
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ * Paul Walmsley (paul@pwsan.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP44XX_DMA_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP44XX_DMA_H
+
+#define OMAP44XX_DMA_SYS_REQ0 2
+#define OMAP44XX_DMA_SYS_REQ1 3
+#define OMAP44XX_DMA_GPMC 4
+#define OMAP44XX_DMA_DSS_DISPC_REQ 6
+#define OMAP44XX_DMA_SYS_REQ2 7
+#define OMAP44XX_DMA_MCASP1_AXEVT 8
+#define OMAP44XX_DMA_ISS_REQ1 9
+#define OMAP44XX_DMA_ISS_REQ2 10
+#define OMAP44XX_DMA_MCASP1_AREVT 11
+#define OMAP44XX_DMA_ISS_REQ3 12
+#define OMAP44XX_DMA_ISS_REQ4 13
+#define OMAP44XX_DMA_DSS_RFBI_REQ 14
+#define OMAP44XX_DMA_SPI3_TX0 15
+#define OMAP44XX_DMA_SPI3_RX0 16
+#define OMAP44XX_DMA_MCBSP2_TX 17
+#define OMAP44XX_DMA_MCBSP2_RX 18
+#define OMAP44XX_DMA_MCBSP3_TX 19
+#define OMAP44XX_DMA_MCBSP3_RX 20
+#define OMAP44XX_DMA_C2C_SSCM_GPO0 21
+#define OMAP44XX_DMA_C2C_SSCM_GPO1 22
+#define OMAP44XX_DMA_SPI3_TX1 23
+#define OMAP44XX_DMA_SPI3_RX1 24
+#define OMAP44XX_DMA_I2C3_TX 25
+#define OMAP44XX_DMA_I2C3_RX 26
+#define OMAP44XX_DMA_I2C1_TX 27
+#define OMAP44XX_DMA_I2C1_RX 28
+#define OMAP44XX_DMA_I2C2_TX 29
+#define OMAP44XX_DMA_I2C2_RX 30
+#define OMAP44XX_DMA_MCBSP4_TX 31
+#define OMAP44XX_DMA_MCBSP4_RX 32
+#define OMAP44XX_DMA_MCBSP1_TX 33
+#define OMAP44XX_DMA_MCBSP1_RX 34
+#define OMAP44XX_DMA_SPI1_TX0 35
+#define OMAP44XX_DMA_SPI1_RX0 36
+#define OMAP44XX_DMA_SPI1_TX1 37
+#define OMAP44XX_DMA_SPI1_RX1 38
+#define OMAP44XX_DMA_SPI1_TX2 39
+#define OMAP44XX_DMA_SPI1_RX2 40
+#define OMAP44XX_DMA_SPI1_TX3 41
+#define OMAP44XX_DMA_SPI1_RX3 42
+#define OMAP44XX_DMA_SPI2_TX0 43
+#define OMAP44XX_DMA_SPI2_RX0 44
+#define OMAP44XX_DMA_SPI2_TX1 45
+#define OMAP44XX_DMA_SPI2_RX1 46
+#define OMAP44XX_DMA_MMC2_TX 47
+#define OMAP44XX_DMA_MMC2_RX 48
+#define OMAP44XX_DMA_UART1_TX 49
+#define OMAP44XX_DMA_UART1_RX 50
+#define OMAP44XX_DMA_UART2_TX 51
+#define OMAP44XX_DMA_UART2_RX 52
+#define OMAP44XX_DMA_UART3_TX 53
+#define OMAP44XX_DMA_UART3_RX 54
+#define OMAP44XX_DMA_UART4_TX 55
+#define OMAP44XX_DMA_UART4_RX 56
+#define OMAP44XX_DMA_MMC4_TX 57
+#define OMAP44XX_DMA_MMC4_RX 58
+#define OMAP44XX_DMA_MMC5_TX 59
+#define OMAP44XX_DMA_MMC5_RX 60
+#define OMAP44XX_DMA_MMC1_TX 61
+#define OMAP44XX_DMA_MMC1_RX 62
+#define OMAP44XX_DMA_SYS_REQ3 64
+#define OMAP44XX_DMA_MCPDM_UP 65
+#define OMAP44XX_DMA_MCPDM_DL 66
+#define OMAP44XX_DMA_DMIC_REQ 67
+#define OMAP44XX_DMA_C2C_SSCM_GPO2 68
+#define OMAP44XX_DMA_C2C_SSCM_GPO3 69
+#define OMAP44XX_DMA_SPI4_TX0 70
+#define OMAP44XX_DMA_SPI4_RX0 71
+#define OMAP44XX_DMA_DSS_DSI1_REQ0 72
+#define OMAP44XX_DMA_DSS_DSI1_REQ1 73
+#define OMAP44XX_DMA_DSS_DSI1_REQ2 74
+#define OMAP44XX_DMA_DSS_DSI1_REQ3 75
+#define OMAP44XX_DMA_DSS_HDMI_REQ 76
+#define OMAP44XX_DMA_MMC3_TX 77
+#define OMAP44XX_DMA_MMC3_RX 78
+#define OMAP44XX_DMA_USIM_TX 79
+#define OMAP44XX_DMA_USIM_RX 80
+#define OMAP44XX_DMA_DSS_DSI2_REQ0 81
+#define OMAP44XX_DMA_DSS_DSI2_REQ1 82
+#define OMAP44XX_DMA_DSS_DSI2_REQ2 83
+#define OMAP44XX_DMA_DSS_DSI2_REQ3 84
+#define OMAP44XX_DMA_SLIMBUS1_TX0 85
+#define OMAP44XX_DMA_SLIMBUS1_TX1 86
+#define OMAP44XX_DMA_SLIMBUS1_TX2 87
+#define OMAP44XX_DMA_SLIMBUS1_TX3 88
+#define OMAP44XX_DMA_SLIMBUS1_RX0 89
+#define OMAP44XX_DMA_SLIMBUS1_RX1 90
+#define OMAP44XX_DMA_SLIMBUS1_RX2 91
+#define OMAP44XX_DMA_SLIMBUS1_RX3 92
+#define OMAP44XX_DMA_SLIMBUS2_TX0 93
+#define OMAP44XX_DMA_SLIMBUS2_TX1 94
+#define OMAP44XX_DMA_SLIMBUS2_TX2 95
+#define OMAP44XX_DMA_SLIMBUS2_TX3 96
+#define OMAP44XX_DMA_SLIMBUS2_RX0 97
+#define OMAP44XX_DMA_SLIMBUS2_RX1 98
+#define OMAP44XX_DMA_SLIMBUS2_RX2 99
+#define OMAP44XX_DMA_SLIMBUS2_RX3 100
+#define OMAP44XX_DMA_ABE_REQ_0 101
+#define OMAP44XX_DMA_ABE_REQ_1 102
+#define OMAP44XX_DMA_ABE_REQ_2 103
+#define OMAP44XX_DMA_ABE_REQ_3 104
+#define OMAP44XX_DMA_ABE_REQ_4 105
+#define OMAP44XX_DMA_ABE_REQ_5 106
+#define OMAP44XX_DMA_ABE_REQ_6 107
+#define OMAP44XX_DMA_ABE_REQ_7 108
+#define OMAP44XX_DMA_AES1_P_CTX_IN_REQ 109
+#define OMAP44XX_DMA_AES1_P_DATA_IN_REQ 110
+#define OMAP44XX_DMA_AES1_P_DATA_OUT_REQ 111
+#define OMAP44XX_DMA_AES2_P_CTX_IN_REQ 112
+#define OMAP44XX_DMA_AES2_P_DATA_IN_REQ 113
+#define OMAP44XX_DMA_AES2_P_DATA_OUT_REQ 114
+#define OMAP44XX_DMA_DES_P_CTX_IN_REQ 115
+#define OMAP44XX_DMA_DES_P_DATA_IN_REQ 116
+#define OMAP44XX_DMA_DES_P_DATA_OUT_REQ 117
+#define OMAP44XX_DMA_SHA2_CTXIN_P 118
+#define OMAP44XX_DMA_SHA2_DIN_P 119
+#define OMAP44XX_DMA_SHA2_CTXOUT_P 120
+#define OMAP44XX_DMA_AES1_P_CONTEXT_OUT_REQ 121
+#define OMAP44XX_DMA_AES2_P_CONTEXT_OUT_REQ 122
+#define OMAP44XX_DMA_I2C4_TX 124
+#define OMAP44XX_DMA_I2C4_RX 125
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
new file mode 100644
index 00000000..d1c916fc
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -0,0 +1,533 @@
+/*
+ * arch/arm/plat-omap/include/mach/dma.h
+ *
+ * Copyright (C) 2003 Nokia Corporation
+ * Author: Juha Yrjölä <juha.yrjola@nokia.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 __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#include <linux/platform_device.h>
+
+/*
+ * TODO: These dma channel defines should go away once all
+ * the omap drivers hwmod adapted.
+ */
+
+/* Move omap4 specific defines to dma-44xx.h */
+#include "dma-44xx.h"
+
+/* DMA channels for omap1 */
+#define OMAP_DMA_NO_DEVICE 0
+#define OMAP_DMA_MCSI1_TX 1
+#define OMAP_DMA_MCSI1_RX 2
+#define OMAP_DMA_I2C_RX 3
+#define OMAP_DMA_I2C_TX 4
+#define OMAP_DMA_EXT_NDMA_REQ 5
+#define OMAP_DMA_EXT_NDMA_REQ2 6
+#define OMAP_DMA_UWIRE_TX 7
+#define OMAP_DMA_MCBSP1_TX 8
+#define OMAP_DMA_MCBSP1_RX 9
+#define OMAP_DMA_MCBSP3_TX 10
+#define OMAP_DMA_MCBSP3_RX 11
+#define OMAP_DMA_UART1_TX 12
+#define OMAP_DMA_UART1_RX 13
+#define OMAP_DMA_UART2_TX 14
+#define OMAP_DMA_UART2_RX 15
+#define OMAP_DMA_MCBSP2_TX 16
+#define OMAP_DMA_MCBSP2_RX 17
+#define OMAP_DMA_UART3_TX 18
+#define OMAP_DMA_UART3_RX 19
+#define OMAP_DMA_CAMERA_IF_RX 20
+#define OMAP_DMA_MMC_TX 21
+#define OMAP_DMA_MMC_RX 22
+#define OMAP_DMA_NAND 23
+#define OMAP_DMA_IRQ_LCD_LINE 24
+#define OMAP_DMA_MEMORY_STICK 25
+#define OMAP_DMA_USB_W2FC_RX0 26
+#define OMAP_DMA_USB_W2FC_RX1 27
+#define OMAP_DMA_USB_W2FC_RX2 28
+#define OMAP_DMA_USB_W2FC_TX0 29
+#define OMAP_DMA_USB_W2FC_TX1 30
+#define OMAP_DMA_USB_W2FC_TX2 31
+
+/* These are only for 1610 */
+#define OMAP_DMA_CRYPTO_DES_IN 32
+#define OMAP_DMA_SPI_TX 33
+#define OMAP_DMA_SPI_RX 34
+#define OMAP_DMA_CRYPTO_HASH 35
+#define OMAP_DMA_CCP_ATTN 36
+#define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37
+#define OMAP_DMA_CMT_APE_TX_CHAN_0 38
+#define OMAP_DMA_CMT_APE_RV_CHAN_0 39
+#define OMAP_DMA_CMT_APE_TX_CHAN_1 40
+#define OMAP_DMA_CMT_APE_RV_CHAN_1 41
+#define OMAP_DMA_CMT_APE_TX_CHAN_2 42
+#define OMAP_DMA_CMT_APE_RV_CHAN_2 43
+#define OMAP_DMA_CMT_APE_TX_CHAN_3 44
+#define OMAP_DMA_CMT_APE_RV_CHAN_3 45
+#define OMAP_DMA_CMT_APE_TX_CHAN_4 46
+#define OMAP_DMA_CMT_APE_RV_CHAN_4 47
+#define OMAP_DMA_CMT_APE_TX_CHAN_5 48
+#define OMAP_DMA_CMT_APE_RV_CHAN_5 49
+#define OMAP_DMA_CMT_APE_TX_CHAN_6 50
+#define OMAP_DMA_CMT_APE_RV_CHAN_6 51
+#define OMAP_DMA_CMT_APE_TX_CHAN_7 52
+#define OMAP_DMA_CMT_APE_RV_CHAN_7 53
+#define OMAP_DMA_MMC2_TX 54
+#define OMAP_DMA_MMC2_RX 55
+#define OMAP_DMA_CRYPTO_DES_OUT 56
+
+/* DMA channels for 24xx */
+#define OMAP24XX_DMA_NO_DEVICE 0
+#define OMAP24XX_DMA_XTI_DMA 1 /* S_DMA_0 */
+#define OMAP24XX_DMA_EXT_DMAREQ0 2 /* S_DMA_1 */
+#define OMAP24XX_DMA_EXT_DMAREQ1 3 /* S_DMA_2 */
+#define OMAP24XX_DMA_GPMC 4 /* S_DMA_3 */
+#define OMAP24XX_DMA_GFX 5 /* S_DMA_4 */
+#define OMAP24XX_DMA_DSS 6 /* S_DMA_5 */
+#define OMAP242X_DMA_VLYNQ_TX 7 /* S_DMA_6 */
+#define OMAP24XX_DMA_EXT_DMAREQ2 7 /* S_DMA_6 */
+#define OMAP24XX_DMA_CWT 8 /* S_DMA_7 */
+#define OMAP24XX_DMA_AES_TX 9 /* S_DMA_8 */
+#define OMAP24XX_DMA_AES_RX 10 /* S_DMA_9 */
+#define OMAP24XX_DMA_DES_TX 11 /* S_DMA_10 */
+#define OMAP24XX_DMA_DES_RX 12 /* S_DMA_11 */
+#define OMAP24XX_DMA_SHA1MD5_RX 13 /* S_DMA_12 */
+#define OMAP34XX_DMA_SHA2MD5_RX 13 /* S_DMA_12 */
+#define OMAP242X_DMA_EXT_DMAREQ2 14 /* S_DMA_13 */
+#define OMAP242X_DMA_EXT_DMAREQ3 15 /* S_DMA_14 */
+#define OMAP242X_DMA_EXT_DMAREQ4 16 /* S_DMA_15 */
+#define OMAP242X_DMA_EAC_AC_RD 17 /* S_DMA_16 */
+#define OMAP242X_DMA_EAC_AC_WR 18 /* S_DMA_17 */
+#define OMAP242X_DMA_EAC_MD_UL_RD 19 /* S_DMA_18 */
+#define OMAP242X_DMA_EAC_MD_UL_WR 20 /* S_DMA_19 */
+#define OMAP242X_DMA_EAC_MD_DL_RD 21 /* S_DMA_20 */
+#define OMAP242X_DMA_EAC_MD_DL_WR 22 /* S_DMA_21 */
+#define OMAP242X_DMA_EAC_BT_UL_RD 23 /* S_DMA_22 */
+#define OMAP242X_DMA_EAC_BT_UL_WR 24 /* S_DMA_23 */
+#define OMAP242X_DMA_EAC_BT_DL_RD 25 /* S_DMA_24 */
+#define OMAP242X_DMA_EAC_BT_DL_WR 26 /* S_DMA_25 */
+#define OMAP243X_DMA_EXT_DMAREQ3 14 /* S_DMA_13 */
+#define OMAP24XX_DMA_SPI3_TX0 15 /* S_DMA_14 */
+#define OMAP24XX_DMA_SPI3_RX0 16 /* S_DMA_15 */
+#define OMAP24XX_DMA_MCBSP3_TX 17 /* S_DMA_16 */
+#define OMAP24XX_DMA_MCBSP3_RX 18 /* S_DMA_17 */
+#define OMAP24XX_DMA_MCBSP4_TX 19 /* S_DMA_18 */
+#define OMAP24XX_DMA_MCBSP4_RX 20 /* S_DMA_19 */
+#define OMAP24XX_DMA_MCBSP5_TX 21 /* S_DMA_20 */
+#define OMAP24XX_DMA_MCBSP5_RX 22 /* S_DMA_21 */
+#define OMAP24XX_DMA_SPI3_TX1 23 /* S_DMA_22 */
+#define OMAP24XX_DMA_SPI3_RX1 24 /* S_DMA_23 */
+#define OMAP243X_DMA_EXT_DMAREQ4 25 /* S_DMA_24 */
+#define OMAP243X_DMA_EXT_DMAREQ5 26 /* S_DMA_25 */
+#define OMAP34XX_DMA_I2C3_TX 25 /* S_DMA_24 */
+#define OMAP34XX_DMA_I2C3_RX 26 /* S_DMA_25 */
+#define OMAP24XX_DMA_I2C1_TX 27 /* S_DMA_26 */
+#define OMAP24XX_DMA_I2C1_RX 28 /* S_DMA_27 */
+#define OMAP24XX_DMA_I2C2_TX 29 /* S_DMA_28 */
+#define OMAP24XX_DMA_I2C2_RX 30 /* S_DMA_29 */
+#define OMAP24XX_DMA_MCBSP1_TX 31 /* S_DMA_30 */
+#define OMAP24XX_DMA_MCBSP1_RX 32 /* S_DMA_31 */
+#define OMAP24XX_DMA_MCBSP2_TX 33 /* S_DMA_32 */
+#define OMAP24XX_DMA_MCBSP2_RX 34 /* S_DMA_33 */
+#define OMAP24XX_DMA_SPI1_TX0 35 /* S_DMA_34 */
+#define OMAP24XX_DMA_SPI1_RX0 36 /* S_DMA_35 */
+#define OMAP24XX_DMA_SPI1_TX1 37 /* S_DMA_36 */
+#define OMAP24XX_DMA_SPI1_RX1 38 /* S_DMA_37 */
+#define OMAP24XX_DMA_SPI1_TX2 39 /* S_DMA_38 */
+#define OMAP24XX_DMA_SPI1_RX2 40 /* S_DMA_39 */
+#define OMAP24XX_DMA_SPI1_TX3 41 /* S_DMA_40 */
+#define OMAP24XX_DMA_SPI1_RX3 42 /* S_DMA_41 */
+#define OMAP24XX_DMA_SPI2_TX0 43 /* S_DMA_42 */
+#define OMAP24XX_DMA_SPI2_RX0 44 /* S_DMA_43 */
+#define OMAP24XX_DMA_SPI2_TX1 45 /* S_DMA_44 */
+#define OMAP24XX_DMA_SPI2_RX1 46 /* S_DMA_45 */
+#define OMAP24XX_DMA_MMC2_TX 47 /* S_DMA_46 */
+#define OMAP24XX_DMA_MMC2_RX 48 /* S_DMA_47 */
+#define OMAP24XX_DMA_UART1_TX 49 /* S_DMA_48 */
+#define OMAP24XX_DMA_UART1_RX 50 /* S_DMA_49 */
+#define OMAP24XX_DMA_UART2_TX 51 /* S_DMA_50 */
+#define OMAP24XX_DMA_UART2_RX 52 /* S_DMA_51 */
+#define OMAP24XX_DMA_UART3_TX 53 /* S_DMA_52 */
+#define OMAP24XX_DMA_UART3_RX 54 /* S_DMA_53 */
+#define OMAP24XX_DMA_USB_W2FC_TX0 55 /* S_DMA_54 */
+#define OMAP24XX_DMA_USB_W2FC_RX0 56 /* S_DMA_55 */
+#define OMAP24XX_DMA_USB_W2FC_TX1 57 /* S_DMA_56 */
+#define OMAP24XX_DMA_USB_W2FC_RX1 58 /* S_DMA_57 */
+#define OMAP24XX_DMA_USB_W2FC_TX2 59 /* S_DMA_58 */
+#define OMAP24XX_DMA_USB_W2FC_RX2 60 /* S_DMA_59 */
+#define OMAP24XX_DMA_MMC1_TX 61 /* S_DMA_60 */
+#define OMAP24XX_DMA_MMC1_RX 62 /* S_DMA_61 */
+#define OMAP24XX_DMA_MS 63 /* S_DMA_62 */
+#define OMAP242X_DMA_EXT_DMAREQ5 64 /* S_DMA_63 */
+#define OMAP243X_DMA_EXT_DMAREQ6 64 /* S_DMA_63 */
+#define OMAP34XX_DMA_EXT_DMAREQ3 64 /* S_DMA_63 */
+#define OMAP34XX_DMA_AES2_TX 65 /* S_DMA_64 */
+#define OMAP34XX_DMA_AES2_RX 66 /* S_DMA_65 */
+#define OMAP34XX_DMA_DES2_TX 67 /* S_DMA_66 */
+#define OMAP34XX_DMA_DES2_RX 68 /* S_DMA_67 */
+#define OMAP34XX_DMA_SHA1MD5_RX 69 /* S_DMA_68 */
+#define OMAP34XX_DMA_SPI4_TX0 70 /* S_DMA_69 */
+#define OMAP34XX_DMA_SPI4_RX0 71 /* S_DMA_70 */
+#define OMAP34XX_DSS_DMA0 72 /* S_DMA_71 */
+#define OMAP34XX_DSS_DMA1 73 /* S_DMA_72 */
+#define OMAP34XX_DSS_DMA2 74 /* S_DMA_73 */
+#define OMAP34XX_DSS_DMA3 75 /* S_DMA_74 */
+#define OMAP34XX_DMA_MMC3_TX 77 /* S_DMA_76 */
+#define OMAP34XX_DMA_MMC3_RX 78 /* S_DMA_77 */
+#define OMAP34XX_DMA_USIM_TX 79 /* S_DMA_78 */
+#define OMAP34XX_DMA_USIM_RX 80 /* S_DMA_79 */
+
+#define OMAP36XX_DMA_UART4_TX 81 /* S_DMA_80 */
+#define OMAP36XX_DMA_UART4_RX 82 /* S_DMA_81 */
+/*----------------------------------------------------------------------------*/
+
+#define OMAP1_DMA_TOUT_IRQ (1 << 0)
+#define OMAP_DMA_DROP_IRQ (1 << 1)
+#define OMAP_DMA_HALF_IRQ (1 << 2)
+#define OMAP_DMA_FRAME_IRQ (1 << 3)
+#define OMAP_DMA_LAST_IRQ (1 << 4)
+#define OMAP_DMA_BLOCK_IRQ (1 << 5)
+#define OMAP1_DMA_SYNC_IRQ (1 << 6)
+#define OMAP2_DMA_PKT_IRQ (1 << 7)
+#define OMAP2_DMA_TRANS_ERR_IRQ (1 << 8)
+#define OMAP2_DMA_SECURE_ERR_IRQ (1 << 9)
+#define OMAP2_DMA_SUPERVISOR_ERR_IRQ (1 << 10)
+#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
+
+#define OMAP_DMA_CCR_EN (1 << 7)
+#define OMAP_DMA_CCR_RD_ACTIVE (1 << 9)
+#define OMAP_DMA_CCR_WR_ACTIVE (1 << 10)
+#define OMAP_DMA_CCR_SEL_SRC_DST_SYNC (1 << 24)
+#define OMAP_DMA_CCR_BUFFERING_DISABLE (1 << 25)
+
+#define OMAP_DMA_DATA_TYPE_S8 0x00
+#define OMAP_DMA_DATA_TYPE_S16 0x01
+#define OMAP_DMA_DATA_TYPE_S32 0x02
+
+#define OMAP_DMA_SYNC_ELEMENT 0x00
+#define OMAP_DMA_SYNC_FRAME 0x01
+#define OMAP_DMA_SYNC_BLOCK 0x02
+#define OMAP_DMA_SYNC_PACKET 0x03
+
+#define OMAP_DMA_DST_SYNC_PREFETCH 0x02
+#define OMAP_DMA_SRC_SYNC 0x01
+#define OMAP_DMA_DST_SYNC 0x00
+
+#define OMAP_DMA_PORT_EMIFF 0x00
+#define OMAP_DMA_PORT_EMIFS 0x01
+#define OMAP_DMA_PORT_OCP_T1 0x02
+#define OMAP_DMA_PORT_TIPB 0x03
+#define OMAP_DMA_PORT_OCP_T2 0x04
+#define OMAP_DMA_PORT_MPUI 0x05
+
+#define OMAP_DMA_AMODE_CONSTANT 0x00
+#define OMAP_DMA_AMODE_POST_INC 0x01
+#define OMAP_DMA_AMODE_SINGLE_IDX 0x02
+#define OMAP_DMA_AMODE_DOUBLE_IDX 0x03
+
+#define DMA_DEFAULT_FIFO_DEPTH 0x10
+#define DMA_DEFAULT_ARB_RATE 0x01
+/* Pass THREAD_RESERVE ORed with THREAD_FIFO for tparams */
+#define DMA_THREAD_RESERVE_NORM (0x00 << 12) /* Def */
+#define DMA_THREAD_RESERVE_ONET (0x01 << 12)
+#define DMA_THREAD_RESERVE_TWOT (0x02 << 12)
+#define DMA_THREAD_RESERVE_THREET (0x03 << 12)
+#define DMA_THREAD_FIFO_NONE (0x00 << 14) /* Def */
+#define DMA_THREAD_FIFO_75 (0x01 << 14)
+#define DMA_THREAD_FIFO_25 (0x02 << 14)
+#define DMA_THREAD_FIFO_50 (0x03 << 14)
+
+/* DMA4_OCP_SYSCONFIG bits */
+#define DMA_SYSCONFIG_MIDLEMODE_MASK (3 << 12)
+#define DMA_SYSCONFIG_CLOCKACTIVITY_MASK (3 << 8)
+#define DMA_SYSCONFIG_EMUFREE (1 << 5)
+#define DMA_SYSCONFIG_SIDLEMODE_MASK (3 << 3)
+#define DMA_SYSCONFIG_SOFTRESET (1 << 2)
+#define DMA_SYSCONFIG_AUTOIDLE (1 << 0)
+
+#define DMA_SYSCONFIG_MIDLEMODE(n) ((n) << 12)
+#define DMA_SYSCONFIG_SIDLEMODE(n) ((n) << 3)
+
+#define DMA_IDLEMODE_SMARTIDLE 0x2
+#define DMA_IDLEMODE_NO_IDLE 0x1
+#define DMA_IDLEMODE_FORCE_IDLE 0x0
+
+/* Chaining modes*/
+#ifndef CONFIG_ARCH_OMAP1
+#define OMAP_DMA_STATIC_CHAIN 0x1
+#define OMAP_DMA_DYNAMIC_CHAIN 0x2
+#define OMAP_DMA_CHAIN_ACTIVE 0x1
+#define OMAP_DMA_CHAIN_INACTIVE 0x0
+#endif
+
+#define DMA_CH_PRIO_HIGH 0x1
+#define DMA_CH_PRIO_LOW 0x0 /* Def */
+
+/* Errata handling */
+#define IS_DMA_ERRATA(id) (errata & (id))
+#define SET_DMA_ERRATA(id) (errata |= (id))
+
+#define DMA_ERRATA_IFRAME_BUFFERING BIT(0x0)
+#define DMA_ERRATA_PARALLEL_CHANNELS BIT(0x1)
+#define DMA_ERRATA_i378 BIT(0x2)
+#define DMA_ERRATA_i541 BIT(0x3)
+#define DMA_ERRATA_i88 BIT(0x4)
+#define DMA_ERRATA_3_3 BIT(0x5)
+#define DMA_ROMCODE_BUG BIT(0x6)
+
+/* Attributes for OMAP DMA Contrller */
+#define DMA_LINKED_LCH BIT(0x0)
+#define GLOBAL_PRIORITY BIT(0x1)
+#define RESERVE_CHANNEL BIT(0x2)
+#define IS_CSSA_32 BIT(0x3)
+#define IS_CDSA_32 BIT(0x4)
+#define IS_RW_PRIORITY BIT(0x5)
+#define ENABLE_1510_MODE BIT(0x6)
+#define SRC_PORT BIT(0x7)
+#define DST_PORT BIT(0x8)
+#define SRC_INDEX BIT(0x9)
+#define DST_INDEX BIT(0xA)
+#define IS_BURST_ONLY4 BIT(0xB)
+#define CLEAR_CSR_ON_READ BIT(0xC)
+#define IS_WORD_16 BIT(0xD)
+
+enum omap_reg_offsets {
+
+GCR, GSCR, GRST1, HW_ID,
+PCH2_ID, PCH0_ID, PCH1_ID, PCHG_ID,
+PCHD_ID, CAPS_0, CAPS_1, CAPS_2,
+CAPS_3, CAPS_4, PCH2_SR, PCH0_SR,
+PCH1_SR, PCHD_SR, REVISION, IRQSTATUS_L0,
+IRQSTATUS_L1, IRQSTATUS_L2, IRQSTATUS_L3, IRQENABLE_L0,
+IRQENABLE_L1, IRQENABLE_L2, IRQENABLE_L3, SYSSTATUS,
+OCP_SYSCONFIG,
+
+/* omap1+ specific */
+CPC, CCR2, LCH_CTRL,
+
+/* Common registers for all omap's */
+CSDP, CCR, CICR, CSR,
+CEN, CFN, CSFI, CSEI,
+CSAC, CDAC, CDEI,
+CDFI, CLNK_CTRL,
+
+/* Channel specific registers */
+CSSA, CDSA, COLOR,
+CCEN, CCFN,
+
+/* omap3630 and omap4 specific */
+CDP, CNDP, CCDN,
+
+};
+
+enum omap_dma_burst_mode {
+ OMAP_DMA_DATA_BURST_DIS = 0,
+ OMAP_DMA_DATA_BURST_4,
+ OMAP_DMA_DATA_BURST_8,
+ OMAP_DMA_DATA_BURST_16,
+};
+
+enum end_type {
+ OMAP_DMA_LITTLE_ENDIAN = 0,
+ OMAP_DMA_BIG_ENDIAN
+};
+
+enum omap_dma_color_mode {
+ OMAP_DMA_COLOR_DIS = 0,
+ OMAP_DMA_CONSTANT_FILL,
+ OMAP_DMA_TRANSPARENT_COPY
+};
+
+enum omap_dma_write_mode {
+ OMAP_DMA_WRITE_NON_POSTED = 0,
+ OMAP_DMA_WRITE_POSTED,
+ OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
+enum omap_dma_channel_mode {
+ OMAP_DMA_LCH_2D = 0,
+ OMAP_DMA_LCH_G,
+ OMAP_DMA_LCH_P,
+ OMAP_DMA_LCH_PD
+};
+
+struct omap_dma_channel_params {
+ int data_type; /* data type 8,16,32 */
+ int elem_count; /* number of elements in a frame */
+ int frame_count; /* number of frames in a element */
+
+ int src_port; /* Only on OMAP1 REVISIT: Is this needed? */
+ int src_amode; /* constant, post increment, indexed,
+ double indexed */
+ unsigned long src_start; /* source address : physical */
+ int src_ei; /* source element index */
+ int src_fi; /* source frame index */
+
+ int dst_port; /* Only on OMAP1 REVISIT: Is this needed? */
+ int dst_amode; /* constant, post increment, indexed,
+ double indexed */
+ unsigned long dst_start; /* source address : physical */
+ int dst_ei; /* source element index */
+ int dst_fi; /* source frame index */
+
+ int trigger; /* trigger attached if the channel is
+ synchronized */
+ int sync_mode; /* sycn on element, frame , block or packet */
+ int src_or_dst_synch; /* source synch(1) or destination synch(0) */
+
+ int ie; /* interrupt enabled */
+
+ unsigned char read_prio;/* read priority */
+ unsigned char write_prio;/* write priority */
+
+#ifndef CONFIG_ARCH_OMAP1
+ enum omap_dma_burst_mode burst_mode; /* Burst mode 4/8/16 words */
+#endif
+};
+
+struct omap_dma_lch {
+ int next_lch;
+ int dev_id;
+ u16 saved_csr;
+ u16 enabled_irqs;
+ const char *dev_name;
+ void (*callback)(int lch, u16 ch_status, void *data);
+ void *data;
+ long flags;
+ /* required for Dynamic chaining */
+ int prev_linked_ch;
+ int next_linked_ch;
+ int state;
+ int chain_id;
+ int status;
+};
+
+struct omap_dma_dev_attr {
+ u32 dev_caps;
+ u16 lch_count;
+ u16 chan_count;
+ struct omap_dma_lch *chan;
+};
+
+/* System DMA platform data structure */
+struct omap_system_dma_plat_info {
+ struct omap_dma_dev_attr *dma_attr;
+ u32 errata;
+ void (*disable_irq_lch)(int lch);
+ void (*show_dma_caps)(void);
+ void (*clear_lch_regs)(int lch);
+ void (*clear_dma)(int lch);
+ void (*dma_write)(u32 val, int reg, int lch);
+ u32 (*dma_read)(int reg, int lch);
+};
+
+extern void omap_set_dma_priority(int lch, int dst_port, int priority);
+extern int omap_request_dma(int dev_id, const char *dev_name,
+ void (*callback)(int lch, u16 ch_status, void *data),
+ void *data, int *dma_ch);
+extern void omap_enable_dma_irq(int ch, u16 irq_bits);
+extern void omap_disable_dma_irq(int ch, u16 irq_bits);
+extern void omap_free_dma(int ch);
+extern void omap_start_dma(int lch);
+extern void omap_stop_dma(int lch);
+extern void omap_set_dma_transfer_params(int lch, int data_type,
+ int elem_count, int frame_count,
+ int sync_mode,
+ int dma_trigger, int src_or_dst_synch);
+extern void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode,
+ u32 color);
+extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
+extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
+
+extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
+ unsigned long src_start,
+ int src_ei, int src_fi);
+extern void omap_set_dma_src_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_src_data_pack(int lch, int enable);
+extern void omap_set_dma_src_burst_mode(int lch,
+ enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
+ unsigned long dest_start,
+ int dst_ei, int dst_fi);
+extern void omap_set_dma_dest_index(int lch, int eidx, int fidx);
+extern void omap_set_dma_dest_data_pack(int lch, int enable);
+extern void omap_set_dma_dest_burst_mode(int lch,
+ enum omap_dma_burst_mode burst_mode);
+
+extern void omap_set_dma_params(int lch,
+ struct omap_dma_channel_params *params);
+
+extern void omap_dma_link_lch(int lch_head, int lch_queue);
+extern void omap_dma_unlink_lch(int lch_head, int lch_queue);
+
+extern int omap_set_dma_callback(int lch,
+ void (*callback)(int lch, u16 ch_status, void *data),
+ void *data);
+extern dma_addr_t omap_get_dma_src_pos(int lch);
+extern dma_addr_t omap_get_dma_dst_pos(int lch);
+extern void omap_clear_dma(int lch);
+extern int omap_get_dma_active_status(int lch);
+extern int omap_dma_running(void);
+extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
+ int tparams);
+extern int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
+ unsigned char write_prio);
+extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype);
+extern void omap_set_dma_src_endian_type(int lch, enum end_type etype);
+extern int omap_get_dma_index(int lch, int *ei, int *fi);
+
+void omap_dma_global_context_save(void);
+void omap_dma_global_context_restore(void);
+
+extern void omap_dma_disable_irq(int lch);
+
+/* Chaining APIs */
+#ifndef CONFIG_ARCH_OMAP1
+extern int omap_request_dma_chain(int dev_id, const char *dev_name,
+ void (*callback) (int lch, u16 ch_status,
+ void *data),
+ int *chain_id, int no_of_chans,
+ int chain_mode,
+ struct omap_dma_channel_params params);
+extern int omap_free_dma_chain(int chain_id);
+extern int omap_dma_chain_a_transfer(int chain_id, int src_start,
+ int dest_start, int elem_count,
+ int frame_count, void *callbk_data);
+extern int omap_start_dma_chain_transfers(int chain_id);
+extern int omap_stop_dma_chain_transfers(int chain_id);
+extern int omap_get_dma_chain_index(int chain_id, int *ei, int *fi);
+extern int omap_get_dma_chain_dst_pos(int chain_id);
+extern int omap_get_dma_chain_src_pos(int chain_id);
+
+extern int omap_modify_dma_chain_params(int chain_id,
+ struct omap_dma_channel_params params);
+extern int omap_dma_chain_status(int chain_id);
+#endif
+
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_FB_OMAP)
+#include <mach/lcd_dma.h>
+#else
+static inline int omap_lcd_dma_running(void)
+{
+ return 0;
+}
+#endif
+
+#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
new file mode 100644
index 00000000..d6c70d2f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -0,0 +1,97 @@
+/*
+ * arch/arm/plat-omap/include/mach/dmtimer.h
+ *
+ * OMAP Dual-Mode Timers
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Platform device conversion and hwmod support.
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
+ * PWM and clock framwork support by Timo Teras.
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_DMTIMER_H
+#define __ASM_ARCH_DMTIMER_H
+
+/* clock sources */
+#define OMAP_TIMER_SRC_SYS_CLK 0x00
+#define OMAP_TIMER_SRC_32_KHZ 0x01
+#define OMAP_TIMER_SRC_EXT_CLK 0x02
+
+/* timer interrupt enable bits */
+#define OMAP_TIMER_INT_CAPTURE (1 << 2)
+#define OMAP_TIMER_INT_OVERFLOW (1 << 1)
+#define OMAP_TIMER_INT_MATCH (1 << 0)
+
+/* trigger types */
+#define OMAP_TIMER_TRIGGER_NONE 0x00
+#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
+#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
+
+/*
+ * IP revision identifier so that Highlander IP
+ * in OMAP4 can be distinguished.
+ */
+#define OMAP_TIMER_IP_VERSION_1 0x1
+struct omap_dm_timer;
+extern struct omap_dm_timer *gptimer_wakeup;
+extern struct sys_timer omap_timer;
+struct clk;
+
+int omap_dm_timer_init(void);
+
+struct omap_dm_timer *omap_dm_timer_request(void);
+struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
+void omap_dm_timer_free(struct omap_dm_timer *timer);
+void omap_dm_timer_enable(struct omap_dm_timer *timer);
+void omap_dm_timer_disable(struct omap_dm_timer *timer);
+
+int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
+
+u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
+
+void omap_dm_timer_trigger(struct omap_dm_timer *timer);
+void omap_dm_timer_start(struct omap_dm_timer *timer);
+void omap_dm_timer_stop(struct omap_dm_timer *timer);
+
+int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
+void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
+void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
+void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+
+void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+
+unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
+void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
+void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
+
+int omap_dm_timers_active(void);
+
+
+#endif /* __ASM_ARCH_DMTIMER_H */
diff --git a/arch/arm/plat-omap/include/plat/dsp.h b/arch/arm/plat-omap/include/plat/dsp.h
new file mode 100644
index 00000000..9c604b39
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dsp.h
@@ -0,0 +1,31 @@
+#ifndef __OMAP_DSP_H__
+#define __OMAP_DSP_H__
+
+#include <linux/types.h>
+
+struct omap_dsp_platform_data {
+ void (*dsp_set_min_opp) (u8 opp_id);
+ u8 (*dsp_get_opp) (void);
+ void (*cpu_set_freq) (unsigned long f);
+ unsigned long (*cpu_get_freq) (void);
+ unsigned long mpu_speed[6];
+
+ /* functions to write and read PRCM registers */
+ void (*dsp_prm_write)(u32, s16 , u16);
+ u32 (*dsp_prm_read)(s16 , u16);
+ u32 (*dsp_prm_rmw_bits)(u32, u32, s16, s16);
+ void (*dsp_cm_write)(u32, s16 , u16);
+ u32 (*dsp_cm_read)(s16 , u16);
+ u32 (*dsp_cm_rmw_bits)(u32, u32, s16, s16);
+
+ phys_addr_t phys_mempool_base;
+ phys_addr_t phys_mempool_size;
+};
+
+#if defined(CONFIG_TIDSPBRIDGE) || defined(CONFIG_TIDSPBRIDGE_MODULE)
+extern void omap_dsp_reserve_sdram_memblock(void);
+#else
+static inline void omap_dsp_reserve_sdram_memblock(void) { }
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/flash.h b/arch/arm/plat-omap/include/plat/flash.h
new file mode 100644
index 00000000..0d88499b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/flash.h
@@ -0,0 +1,17 @@
+/*
+ * Flash support for OMAP1
+ *
+ * This program is free software; you can 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 __OMAP_FLASH_H
+#define __OMAP_FLASH_H
+
+#include <linux/mtd/map.h>
+
+struct platform_device;
+extern void omap1_set_vpp(struct platform_device *pdev, int enable);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/fpga.h b/arch/arm/plat-omap/include/plat/fpga.h
new file mode 100644
index 00000000..bd3c6324
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/fpga.h
@@ -0,0 +1,193 @@
+/*
+ * arch/arm/plat-omap/include/mach/fpga.h
+ *
+ * Interrupt handler for OMAP-1510 FPGA
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Copyright (C) 2002 MontaVista Software, Inc.
+ *
+ * Separated FPGA interrupts from innovator1510.c and cleaned up for 2.6
+ * Copyright (C) 2004 Nokia Corporation by Tony Lindrgen <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_OMAP_FPGA_H
+#define __ASM_ARCH_OMAP_FPGA_H
+
+extern void omap1510_fpga_init_irq(void);
+
+#define fpga_read(reg) __raw_readb(reg)
+#define fpga_write(val, reg) __raw_writeb(val, reg)
+
+/*
+ * ---------------------------------------------------------------------------
+ * H2/P2 Debug board FPGA
+ * ---------------------------------------------------------------------------
+ */
+/* maps in the FPGA registers and the ETHR registers */
+#define H2P2_DBG_FPGA_BASE 0xE8000000 /* VA */
+#define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */
+#define H2P2_DBG_FPGA_START 0x04000000 /* PA */
+
+#define H2P2_DBG_FPGA_ETHR_START (H2P2_DBG_FPGA_START + 0x300)
+#define H2P2_DBG_FPGA_FPGA_REV IOMEM(H2P2_DBG_FPGA_BASE + 0x10) /* FPGA Revision */
+#define H2P2_DBG_FPGA_BOARD_REV IOMEM(H2P2_DBG_FPGA_BASE + 0x12) /* Board Revision */
+#define H2P2_DBG_FPGA_GPIO IOMEM(H2P2_DBG_FPGA_BASE + 0x14) /* GPIO outputs */
+#define H2P2_DBG_FPGA_LEDS IOMEM(H2P2_DBG_FPGA_BASE + 0x16) /* LEDs outputs */
+#define H2P2_DBG_FPGA_MISC_INPUTS IOMEM(H2P2_DBG_FPGA_BASE + 0x18) /* Misc inputs */
+#define H2P2_DBG_FPGA_LAN_STATUS IOMEM(H2P2_DBG_FPGA_BASE + 0x1A) /* LAN Status line */
+#define H2P2_DBG_FPGA_LAN_RESET IOMEM(H2P2_DBG_FPGA_BASE + 0x1C) /* LAN Reset line */
+
+/* NOTE: most boards don't have a static mapping for the FPGA ... */
+struct h2p2_dbg_fpga {
+ /* offset 0x00 */
+ u16 smc91x[8];
+ /* offset 0x10 */
+ u16 fpga_rev;
+ u16 board_rev;
+ u16 gpio_outputs;
+ u16 leds;
+ /* offset 0x18 */
+ u16 misc_inputs;
+ u16 lan_status;
+ u16 lan_reset;
+ u16 reserved0;
+ /* offset 0x20 */
+ u16 ps2_data;
+ u16 ps2_ctrl;
+ /* plus also 4 rs232 ports ... */
+};
+
+/* LEDs definition on debug board (16 LEDs, all physically green) */
+#define H2P2_DBG_FPGA_LED_GREEN (1 << 15)
+#define H2P2_DBG_FPGA_LED_AMBER (1 << 14)
+#define H2P2_DBG_FPGA_LED_RED (1 << 13)
+#define H2P2_DBG_FPGA_LED_BLUE (1 << 12)
+/* cpu0 load-meter LEDs */
+#define H2P2_DBG_FPGA_LOAD_METER (1 << 0) // A bit of fun on our board ...
+#define H2P2_DBG_FPGA_LOAD_METER_SIZE 11
+#define H2P2_DBG_FPGA_LOAD_METER_MASK ((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
+
+#define H2P2_DBG_FPGA_P2_LED_TIMER (1 << 0)
+#define H2P2_DBG_FPGA_P2_LED_IDLE (1 << 1)
+
+/*
+ * ---------------------------------------------------------------------------
+ * OMAP-1510 FPGA
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP1510_FPGA_BASE 0xE8000000 /* VA */
+#define OMAP1510_FPGA_SIZE SZ_4K
+#define OMAP1510_FPGA_START 0x08000000 /* PA */
+
+/* Revision */
+#define OMAP1510_FPGA_REV_LOW IOMEM(OMAP1510_FPGA_BASE + 0x0)
+#define OMAP1510_FPGA_REV_HIGH IOMEM(OMAP1510_FPGA_BASE + 0x1)
+
+#define OMAP1510_FPGA_LCD_PANEL_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x2)
+#define OMAP1510_FPGA_LED_DIGIT IOMEM(OMAP1510_FPGA_BASE + 0x3)
+#define INNOVATOR_FPGA_HID_SPI IOMEM(OMAP1510_FPGA_BASE + 0x4)
+#define OMAP1510_FPGA_POWER IOMEM(OMAP1510_FPGA_BASE + 0x5)
+
+/* Interrupt status */
+#define OMAP1510_FPGA_ISR_LO IOMEM(OMAP1510_FPGA_BASE + 0x6)
+#define OMAP1510_FPGA_ISR_HI IOMEM(OMAP1510_FPGA_BASE + 0x7)
+
+/* Interrupt mask */
+#define OMAP1510_FPGA_IMR_LO IOMEM(OMAP1510_FPGA_BASE + 0x8)
+#define OMAP1510_FPGA_IMR_HI IOMEM(OMAP1510_FPGA_BASE + 0x9)
+
+/* Reset registers */
+#define OMAP1510_FPGA_HOST_RESET IOMEM(OMAP1510_FPGA_BASE + 0xa)
+#define OMAP1510_FPGA_RST IOMEM(OMAP1510_FPGA_BASE + 0xb)
+
+#define OMAP1510_FPGA_AUDIO IOMEM(OMAP1510_FPGA_BASE + 0xc)
+#define OMAP1510_FPGA_DIP IOMEM(OMAP1510_FPGA_BASE + 0xe)
+#define OMAP1510_FPGA_FPGA_IO IOMEM(OMAP1510_FPGA_BASE + 0xf)
+#define OMAP1510_FPGA_UART1 IOMEM(OMAP1510_FPGA_BASE + 0x14)
+#define OMAP1510_FPGA_UART2 IOMEM(OMAP1510_FPGA_BASE + 0x15)
+#define OMAP1510_FPGA_OMAP1510_STATUS IOMEM(OMAP1510_FPGA_BASE + 0x16)
+#define OMAP1510_FPGA_BOARD_REV IOMEM(OMAP1510_FPGA_BASE + 0x18)
+#define OMAP1510P1_PPT_DATA IOMEM(OMAP1510_FPGA_BASE + 0x100)
+#define OMAP1510P1_PPT_STATUS IOMEM(OMAP1510_FPGA_BASE + 0x101)
+#define OMAP1510P1_PPT_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x102)
+
+#define OMAP1510_FPGA_TOUCHSCREEN IOMEM(OMAP1510_FPGA_BASE + 0x204)
+
+#define INNOVATOR_FPGA_INFO IOMEM(OMAP1510_FPGA_BASE + 0x205)
+#define INNOVATOR_FPGA_LCD_BRIGHT_LO IOMEM(OMAP1510_FPGA_BASE + 0x206)
+#define INNOVATOR_FPGA_LCD_BRIGHT_HI IOMEM(OMAP1510_FPGA_BASE + 0x207)
+#define INNOVATOR_FPGA_LED_GRN_LO IOMEM(OMAP1510_FPGA_BASE + 0x208)
+#define INNOVATOR_FPGA_LED_GRN_HI IOMEM(OMAP1510_FPGA_BASE + 0x209)
+#define INNOVATOR_FPGA_LED_RED_LO IOMEM(OMAP1510_FPGA_BASE + 0x20a)
+#define INNOVATOR_FPGA_LED_RED_HI IOMEM(OMAP1510_FPGA_BASE + 0x20b)
+#define INNOVATOR_FPGA_CAM_USB_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x20c)
+#define INNOVATOR_FPGA_EXP_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x20d)
+#define INNOVATOR_FPGA_ISR2 IOMEM(OMAP1510_FPGA_BASE + 0x20e)
+#define INNOVATOR_FPGA_IMR2 IOMEM(OMAP1510_FPGA_BASE + 0x210)
+
+#define OMAP1510_FPGA_ETHR_START (OMAP1510_FPGA_START + 0x300)
+
+/*
+ * Power up Giga UART driver, turn on HID clock.
+ * Turn off BT power, since we're not using it and it
+ * draws power.
+ */
+#define OMAP1510_FPGA_RESET_VALUE 0x42
+
+#define OMAP1510_FPGA_PCR_IF_PD0 (1 << 7)
+#define OMAP1510_FPGA_PCR_COM2_EN (1 << 6)
+#define OMAP1510_FPGA_PCR_COM1_EN (1 << 5)
+#define OMAP1510_FPGA_PCR_EXP_PD0 (1 << 4)
+#define OMAP1510_FPGA_PCR_EXP_PD1 (1 << 3)
+#define OMAP1510_FPGA_PCR_48MHZ_CLK (1 << 2)
+#define OMAP1510_FPGA_PCR_4MHZ_CLK (1 << 1)
+#define OMAP1510_FPGA_PCR_RSRVD_BIT0 (1 << 0)
+
+/*
+ * Innovator/OMAP1510 FPGA HID register bit definitions
+ */
+#define OMAP1510_FPGA_HID_SCLK (1<<0) /* output */
+#define OMAP1510_FPGA_HID_MOSI (1<<1) /* output */
+#define OMAP1510_FPGA_HID_nSS (1<<2) /* output 0/1 chip idle/select */
+#define OMAP1510_FPGA_HID_nHSUS (1<<3) /* output 0/1 host active/suspended */
+#define OMAP1510_FPGA_HID_MISO (1<<4) /* input */
+#define OMAP1510_FPGA_HID_ATN (1<<5) /* input 0/1 chip idle/ATN */
+#define OMAP1510_FPGA_HID_rsrvd (1<<6)
+#define OMAP1510_FPGA_HID_RESETn (1<<7) /* output - 0/1 USAR reset/run */
+
+/* The FPGA IRQ is cascaded through GPIO_13 */
+#define OMAP1510_INT_FPGA (IH_GPIO_BASE + 13)
+
+/* IRQ Numbers for interrupts muxed through the FPGA */
+#define OMAP1510_INT_FPGA_ATN (OMAP_FPGA_IRQ_BASE + 0)
+#define OMAP1510_INT_FPGA_ACK (OMAP_FPGA_IRQ_BASE + 1)
+#define OMAP1510_INT_FPGA2 (OMAP_FPGA_IRQ_BASE + 2)
+#define OMAP1510_INT_FPGA3 (OMAP_FPGA_IRQ_BASE + 3)
+#define OMAP1510_INT_FPGA4 (OMAP_FPGA_IRQ_BASE + 4)
+#define OMAP1510_INT_FPGA5 (OMAP_FPGA_IRQ_BASE + 5)
+#define OMAP1510_INT_FPGA6 (OMAP_FPGA_IRQ_BASE + 6)
+#define OMAP1510_INT_FPGA7 (OMAP_FPGA_IRQ_BASE + 7)
+#define OMAP1510_INT_FPGA8 (OMAP_FPGA_IRQ_BASE + 8)
+#define OMAP1510_INT_FPGA9 (OMAP_FPGA_IRQ_BASE + 9)
+#define OMAP1510_INT_FPGA10 (OMAP_FPGA_IRQ_BASE + 10)
+#define OMAP1510_INT_FPGA11 (OMAP_FPGA_IRQ_BASE + 11)
+#define OMAP1510_INT_FPGA12 (OMAP_FPGA_IRQ_BASE + 12)
+#define OMAP1510_INT_ETHER (OMAP_FPGA_IRQ_BASE + 13)
+#define OMAP1510_INT_FPGAUART1 (OMAP_FPGA_IRQ_BASE + 14)
+#define OMAP1510_INT_FPGAUART2 (OMAP_FPGA_IRQ_BASE + 15)
+#define OMAP1510_INT_FPGA_TS (OMAP_FPGA_IRQ_BASE + 16)
+#define OMAP1510_INT_FPGA17 (OMAP_FPGA_IRQ_BASE + 17)
+#define OMAP1510_INT_FPGA_CAM (OMAP_FPGA_IRQ_BASE + 18)
+#define OMAP1510_INT_FPGA_RTC_A (OMAP_FPGA_IRQ_BASE + 19)
+#define OMAP1510_INT_FPGA_RTC_B (OMAP_FPGA_IRQ_BASE + 20)
+#define OMAP1510_INT_FPGA_CD (OMAP_FPGA_IRQ_BASE + 21)
+#define OMAP1510_INT_FPGA22 (OMAP_FPGA_IRQ_BASE + 22)
+#define OMAP1510_INT_FPGA23 (OMAP_FPGA_IRQ_BASE + 23)
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpio-switch.h b/arch/arm/plat-omap/include/plat/gpio-switch.h
new file mode 100644
index 00000000..10da0e07
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpio-switch.h
@@ -0,0 +1,54 @@
+/*
+ * GPIO switch definitions
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_OMAP_GPIO_SWITCH_H
+#define __ASM_ARCH_OMAP_GPIO_SWITCH_H
+
+#include <linux/types.h>
+
+/* Cover:
+ * high -> closed
+ * low -> open
+ * Connection:
+ * high -> connected
+ * low -> disconnected
+ * Activity:
+ * high -> active
+ * low -> inactive
+ *
+ */
+#define OMAP_GPIO_SWITCH_TYPE_COVER 0x0000
+#define OMAP_GPIO_SWITCH_TYPE_CONNECTION 0x0001
+#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY 0x0002
+#define OMAP_GPIO_SWITCH_FLAG_INVERTED 0x0001
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT 0x0002
+
+struct omap_gpio_switch {
+ const char *name;
+ s16 gpio;
+ unsigned flags:4;
+ unsigned type:4;
+
+ /* Time in ms to debounce when transitioning from
+ * inactive state to active state. */
+ u16 debounce_rising;
+ /* Same for transition from active to inactive state. */
+ u16 debounce_falling;
+
+ /* notify board-specific code about state changes */
+ void (* notify)(void *data, int state);
+ void *notify_data;
+};
+
+/* Call at init time only */
+extern void omap_register_gpio_switches(const struct omap_gpio_switch *tbl,
+ int count);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpio.h b/arch/arm/plat-omap/include/plat/gpio.h
new file mode 100644
index 00000000..ec97e00c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpio.h
@@ -0,0 +1,242 @@
+/*
+ * arch/arm/plat-omap/include/mach/gpio.h
+ *
+ * OMAP GPIO handling defines and functions
+ *
+ * Copyright (C) 2003-2005 Nokia Corporation
+ *
+ * Written by Juha Yrjölä <juha.yrjola@nokia.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 __ASM_ARCH_OMAP_GPIO_H
+#define __ASM_ARCH_OMAP_GPIO_H
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/irqs.h>
+
+#define OMAP1_MPUIO_BASE 0xfffb5000
+
+/*
+ * These are the omap15xx/16xx offsets. The omap7xx offset are
+ * OMAP_MPUIO_ / 2 offsets below.
+ */
+#define OMAP_MPUIO_INPUT_LATCH 0x00
+#define OMAP_MPUIO_OUTPUT 0x04
+#define OMAP_MPUIO_IO_CNTL 0x08
+#define OMAP_MPUIO_KBR_LATCH 0x10
+#define OMAP_MPUIO_KBC 0x14
+#define OMAP_MPUIO_GPIO_EVENT_MODE 0x18
+#define OMAP_MPUIO_GPIO_INT_EDGE 0x1c
+#define OMAP_MPUIO_KBD_INT 0x20
+#define OMAP_MPUIO_GPIO_INT 0x24
+#define OMAP_MPUIO_KBD_MASKIT 0x28
+#define OMAP_MPUIO_GPIO_MASKIT 0x2c
+#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
+#define OMAP_MPUIO_LATCH 0x34
+
+#define OMAP34XX_NR_GPIOS 6
+
+/*
+ * OMAP1510 GPIO registers
+ */
+#define OMAP1510_GPIO_DATA_INPUT 0x00
+#define OMAP1510_GPIO_DATA_OUTPUT 0x04
+#define OMAP1510_GPIO_DIR_CONTROL 0x08
+#define OMAP1510_GPIO_INT_CONTROL 0x0c
+#define OMAP1510_GPIO_INT_MASK 0x10
+#define OMAP1510_GPIO_INT_STATUS 0x14
+#define OMAP1510_GPIO_PIN_CONTROL 0x18
+
+#define OMAP1510_IH_GPIO_BASE 64
+
+/*
+ * OMAP1610 specific GPIO registers
+ */
+#define OMAP1610_GPIO_REVISION 0x0000
+#define OMAP1610_GPIO_SYSCONFIG 0x0010
+#define OMAP1610_GPIO_SYSSTATUS 0x0014
+#define OMAP1610_GPIO_IRQSTATUS1 0x0018
+#define OMAP1610_GPIO_IRQENABLE1 0x001c
+#define OMAP1610_GPIO_WAKEUPENABLE 0x0028
+#define OMAP1610_GPIO_DATAIN 0x002c
+#define OMAP1610_GPIO_DATAOUT 0x0030
+#define OMAP1610_GPIO_DIRECTION 0x0034
+#define OMAP1610_GPIO_EDGE_CTRL1 0x0038
+#define OMAP1610_GPIO_EDGE_CTRL2 0x003c
+#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
+#define OMAP1610_GPIO_CLEAR_WAKEUPENA 0x00a8
+#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
+#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
+#define OMAP1610_GPIO_SET_WAKEUPENA 0x00e8
+#define OMAP1610_GPIO_SET_DATAOUT 0x00f0
+
+/*
+ * OMAP7XX specific GPIO registers
+ */
+#define OMAP7XX_GPIO_DATA_INPUT 0x00
+#define OMAP7XX_GPIO_DATA_OUTPUT 0x04
+#define OMAP7XX_GPIO_DIR_CONTROL 0x08
+#define OMAP7XX_GPIO_INT_CONTROL 0x0c
+#define OMAP7XX_GPIO_INT_MASK 0x10
+#define OMAP7XX_GPIO_INT_STATUS 0x14
+
+/*
+ * omap2+ specific GPIO registers
+ */
+#define OMAP24XX_GPIO_REVISION 0x0000
+#define OMAP24XX_GPIO_IRQSTATUS1 0x0018
+#define OMAP24XX_GPIO_IRQSTATUS2 0x0028
+#define OMAP24XX_GPIO_IRQENABLE2 0x002c
+#define OMAP24XX_GPIO_IRQENABLE1 0x001c
+#define OMAP24XX_GPIO_WAKE_EN 0x0020
+#define OMAP24XX_GPIO_CTRL 0x0030
+#define OMAP24XX_GPIO_OE 0x0034
+#define OMAP24XX_GPIO_DATAIN 0x0038
+#define OMAP24XX_GPIO_DATAOUT 0x003c
+#define OMAP24XX_GPIO_LEVELDETECT0 0x0040
+#define OMAP24XX_GPIO_LEVELDETECT1 0x0044
+#define OMAP24XX_GPIO_RISINGDETECT 0x0048
+#define OMAP24XX_GPIO_FALLINGDETECT 0x004c
+#define OMAP24XX_GPIO_DEBOUNCE_EN 0x0050
+#define OMAP24XX_GPIO_DEBOUNCE_VAL 0x0054
+#define OMAP24XX_GPIO_CLEARIRQENABLE1 0x0060
+#define OMAP24XX_GPIO_SETIRQENABLE1 0x0064
+#define OMAP24XX_GPIO_CLEARWKUENA 0x0080
+#define OMAP24XX_GPIO_SETWKUENA 0x0084
+#define OMAP24XX_GPIO_CLEARDATAOUT 0x0090
+#define OMAP24XX_GPIO_SETDATAOUT 0x0094
+
+#define OMAP4_GPIO_REVISION 0x0000
+#define OMAP4_GPIO_EOI 0x0020
+#define OMAP4_GPIO_IRQSTATUSRAW0 0x0024
+#define OMAP4_GPIO_IRQSTATUSRAW1 0x0028
+#define OMAP4_GPIO_IRQSTATUS0 0x002c
+#define OMAP4_GPIO_IRQSTATUS1 0x0030
+#define OMAP4_GPIO_IRQSTATUSSET0 0x0034
+#define OMAP4_GPIO_IRQSTATUSSET1 0x0038
+#define OMAP4_GPIO_IRQSTATUSCLR0 0x003c
+#define OMAP4_GPIO_IRQSTATUSCLR1 0x0040
+#define OMAP4_GPIO_IRQWAKEN0 0x0044
+#define OMAP4_GPIO_IRQWAKEN1 0x0048
+#define OMAP4_GPIO_IRQENABLE1 0x011c
+#define OMAP4_GPIO_WAKE_EN 0x0120
+#define OMAP4_GPIO_IRQSTATUS2 0x0128
+#define OMAP4_GPIO_IRQENABLE2 0x012c
+#define OMAP4_GPIO_CTRL 0x0130
+#define OMAP4_GPIO_OE 0x0134
+#define OMAP4_GPIO_DATAIN 0x0138
+#define OMAP4_GPIO_DATAOUT 0x013c
+#define OMAP4_GPIO_LEVELDETECT0 0x0140
+#define OMAP4_GPIO_LEVELDETECT1 0x0144
+#define OMAP4_GPIO_RISINGDETECT 0x0148
+#define OMAP4_GPIO_FALLINGDETECT 0x014c
+#define OMAP4_GPIO_DEBOUNCENABLE 0x0150
+#define OMAP4_GPIO_DEBOUNCINGTIME 0x0154
+#define OMAP4_GPIO_CLEARIRQENABLE1 0x0160
+#define OMAP4_GPIO_SETIRQENABLE1 0x0164
+#define OMAP4_GPIO_CLEARWKUENA 0x0180
+#define OMAP4_GPIO_SETWKUENA 0x0184
+#define OMAP4_GPIO_CLEARDATAOUT 0x0190
+#define OMAP4_GPIO_SETDATAOUT 0x0194
+
+#define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr))
+#define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
+
+#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ? \
+ IH_MPUIO_BASE + ((nr) & 0x0f) : \
+ IH_GPIO_BASE + (nr))
+
+#define METHOD_MPUIO 0
+#define METHOD_GPIO_1510 1
+#define METHOD_GPIO_1610 2
+#define METHOD_GPIO_7XX 3
+#define METHOD_GPIO_24XX 5
+#define METHOD_GPIO_44XX 6
+
+struct omap_gpio_dev_attr {
+ int bank_width; /* GPIO bank width */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+struct omap_gpio_platform_data {
+ u16 virtual_irq_start;
+ int bank_type;
+ int bank_width; /* GPIO bank width */
+ int bank_stride; /* Only needed for omap1 MPUIO */
+ bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
+};
+
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+extern int gpio_bank_count;
+
+extern void omap2_gpio_prepare_for_idle(int off_mode);
+extern void omap2_gpio_resume_after_idle(void);
+extern void omap_set_gpio_debounce(int gpio, int enable);
+extern void omap_set_gpio_debounce_time(int gpio, int enable);
+extern void omap_gpio_save_context(void);
+extern void omap_gpio_restore_context(void);
+/*-------------------------------------------------------------------------*/
+
+/* Wrappers for "new style" GPIO calls, using the new infrastructure
+ * which lets us plug in FPGA, I2C, and other implementations.
+ * *
+ * The original OMAP-specific calls should eventually be removed.
+ */
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ __gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned gpio)
+{
+ return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned gpio)
+{
+ return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned irq)
+{
+ int tmp;
+
+ /* omap1 SOC mpuio */
+ if (cpu_class_is_omap1() && (irq < (IH_MPUIO_BASE + 16)))
+ return (irq - IH_MPUIO_BASE) + OMAP_MAX_GPIO_LINES;
+
+ /* SOC gpio */
+ tmp = irq - IH_GPIO_BASE;
+ if (tmp < OMAP_MAX_GPIO_LINES)
+ return tmp;
+
+ /* we don't supply reverse mappings for non-SOC gpios */
+ return -EIO;
+}
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpmc-smc91x.h b/arch/arm/plat-omap/include/plat/gpmc-smc91x.h
new file mode 100644
index 00000000..b64fbee4
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpmc-smc91x.h
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/plat-omap/include/mach/gpmc-smc91x.h
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_OMAP_GPMC_SMC91X_H__
+
+#define GPMC_TIMINGS_SMC91C96 (1 << 4)
+#define GPMC_MUX_ADD_DATA (1 << 5) /* GPMC_CONFIG1_MUXADDDATA */
+#define GPMC_READ_MON (1 << 6) /* GPMC_CONFIG1_WAIT_READ_MON */
+#define GPMC_WRITE_MON (1 << 7) /* GPMC_CONFIG1_WAIT_WRITE_MON */
+
+struct omap_smc91x_platform_data {
+ int cs;
+ int gpio_irq;
+ int gpio_pwrdwn;
+ int gpio_reset;
+ int wait_pin; /* Optional GPMC_CONFIG1_WAITPINSELECT */
+ u32 flags;
+ int (*retime)(void);
+};
+
+#if defined(CONFIG_SMC91X) || \
+ defined(CONFIG_SMC91X_MODULE)
+
+extern void gpmc_smc91x_init(struct omap_smc91x_platform_data *d);
+
+#else
+
+#define board_smc91x_data NULL
+
+static inline void gpmc_smc91x_init(struct omap_smc91x_platform_data *d)
+{
+}
+
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
new file mode 100644
index 00000000..ea6c9c88
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
+ *
+ * Copyright (C) 2009 Li-Pro.Net
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * Modified from arch/arm/plat-omap/include/plat/gpmc-smc91x.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__
+
+struct omap_smsc911x_platform_data {
+ int id;
+ int cs;
+ int gpio_irq;
+ int gpio_reset;
+ u32 flags;
+};
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+
+extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
+
+#else
+
+static inline void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d)
+{
+}
+
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
new file mode 100644
index 00000000..1527929b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -0,0 +1,160 @@
+/*
+ * General-Purpose Memory Controller for OMAP2
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OMAP2_GPMC_H
+#define __OMAP2_GPMC_H
+
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM 8
+
+#define GPMC_CS_CONFIG1 0x00
+#define GPMC_CS_CONFIG2 0x04
+#define GPMC_CS_CONFIG3 0x08
+#define GPMC_CS_CONFIG4 0x0c
+#define GPMC_CS_CONFIG5 0x10
+#define GPMC_CS_CONFIG6 0x14
+#define GPMC_CS_CONFIG7 0x18
+#define GPMC_CS_NAND_COMMAND 0x1c
+#define GPMC_CS_NAND_ADDRESS 0x20
+#define GPMC_CS_NAND_DATA 0x24
+
+/* Control Commands */
+#define GPMC_CONFIG_RDY_BSY 0x00000001
+#define GPMC_CONFIG_DEV_SIZE 0x00000002
+#define GPMC_CONFIG_DEV_TYPE 0x00000003
+#define GPMC_SET_IRQ_STATUS 0x00000004
+#define GPMC_CONFIG_WP 0x00000005
+
+#define GPMC_GET_IRQ_STATUS 0x00000006
+#define GPMC_PREFETCH_FIFO_CNT 0x00000007 /* bytes available in FIFO for r/w */
+#define GPMC_PREFETCH_COUNT 0x00000008 /* remaining bytes to be read/write*/
+#define GPMC_STATUS_BUFFER 0x00000009 /* 1: buffer is available to write */
+
+#define GPMC_NAND_COMMAND 0x0000000a
+#define GPMC_NAND_ADDRESS 0x0000000b
+#define GPMC_NAND_DATA 0x0000000c
+
+#define GPMC_ENABLE_IRQ 0x0000000d
+
+/* ECC commands */
+#define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */
+#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */
+#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
+#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
+#define GPMC_CONFIG1_READTYPE_SYNC (1 << 29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25)
+#define GPMC_CONFIG1_PAGE_LEN(val) ((val & 3) << 23)
+#define GPMC_CONFIG1_WAIT_READ_MON (1 << 22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON (1 << 21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val & 3) << 18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val) ((val & 3) << 16)
+#define GPMC_CONFIG1_DEVICESIZE(val) ((val & 3) << 12)
+#define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_MUXADDDATA (1 << 9)
+#define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4)
+#define GPMC_CONFIG1_FCLK_DIV(val) (val & 3)
+#define GPMC_CONFIG1_FCLK_DIV2 (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3 (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3))
+#define GPMC_CONFIG7_CSVALID (1 << 6)
+
+#define GPMC_DEVICETYPE_NOR 0
+#define GPMC_DEVICETYPE_NAND 2
+#define GPMC_CONFIG_WRITEPROTECT 0x00000010
+#define GPMC_STATUS_BUFF_EMPTY 0x00000001
+#define WR_RD_PIN_MONITORING 0x00600000
+#define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F)
+#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff)
+#define GPMC_IRQ_FIFOEVENTENABLE 0x01
+#define GPMC_IRQ_COUNT_EVENT 0x02
+
+#define PREFETCH_FIFOTHRESHOLD_MAX 0x40
+#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8)
+
+enum omap_ecc {
+ /* 1-bit ecc: stored at end of spare area */
+ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */
+ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */
+ /* 1-bit ecc: stored at beginning of spare area as romcode */
+ OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */
+};
+
+/*
+ * Note that all values in this struct are in nanoseconds except sync_clk
+ * (which is in picoseconds), while the register values are in gpmc_fck cycles.
+ */
+struct gpmc_timings {
+ /* Minimum clock period for synchronous mode (in picoseconds) */
+ u32 sync_clk;
+
+ /* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
+ u16 cs_on; /* Assertion time */
+ u16 cs_rd_off; /* Read deassertion time */
+ u16 cs_wr_off; /* Write deassertion time */
+
+ /* ADV signal timings corresponding to GPMC_CONFIG3 */
+ u16 adv_on; /* Assertion time */
+ u16 adv_rd_off; /* Read deassertion time */
+ u16 adv_wr_off; /* Write deassertion time */
+
+ /* WE signals timings corresponding to GPMC_CONFIG4 */
+ u16 we_on; /* WE assertion time */
+ u16 we_off; /* WE deassertion time */
+
+ /* OE signals timings corresponding to GPMC_CONFIG4 */
+ u16 oe_on; /* OE assertion time */
+ u16 oe_off; /* OE deassertion time */
+
+ /* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
+ u16 page_burst_access; /* Multiple access word delay */
+ u16 access; /* Start-cycle to first data valid delay */
+ u16 rd_cycle; /* Total read cycle time */
+ u16 wr_cycle; /* Total write cycle time */
+
+ /* The following are only on OMAP3430 */
+ u16 wr_access; /* WRACCESSTIME */
+ u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
+};
+
+extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ps_to_ticks(unsigned int time_ps);
+extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
+extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
+extern unsigned long gpmc_get_fclk_period(void);
+
+extern void gpmc_cs_write_reg(int cs, int idx, u32 val);
+extern u32 gpmc_cs_read_reg(int cs, int idx);
+extern int gpmc_cs_calc_divider(int cs, unsigned int sync_clk);
+extern int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t);
+extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
+extern void gpmc_cs_free(int cs);
+extern int gpmc_cs_set_reserved(int cs, int reserved);
+extern int gpmc_cs_reserved(int cs);
+extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode,
+ unsigned int u32_count, int is_write);
+extern int gpmc_prefetch_reset(int cs);
+extern void omap3_gpmc_save_context(void);
+extern void omap3_gpmc_restore_context(void);
+extern int gpmc_read_status(int cmd);
+extern int gpmc_cs_configure(int cs, int cmd, int wval);
+extern int gpmc_nand_read(int cs, int cmd);
+extern int gpmc_nand_write(int cs, int cmd, int wval);
+
+int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size);
+int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code);
+#endif
diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h
new file mode 100644
index 00000000..e87efe14
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/hardware.h
@@ -0,0 +1,291 @@
+/*
+ * arch/arm/plat-omap/include/mach/hardware.h
+ *
+ * Hardware definitions for TI OMAP processors and boards
+ *
+ * NOTE: Please put device driver specific defines into a separate header
+ * file for each driver.
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ * and Dirk Behme <dirk.behme@de.bosch.com>
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_HARDWARE_H
+#define __ASM_ARCH_OMAP_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#include <plat/cpu.h>
+#endif
+#include <plat/serial.h>
+
+/*
+ * ---------------------------------------------------------------------------
+ * Common definitions for all OMAP processors
+ * NOTE: Put all processor or board specific parts to the special header
+ * files.
+ * ---------------------------------------------------------------------------
+ */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Timers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_MPU_TIMER1_BASE (0xfffec500)
+#define OMAP_MPU_TIMER2_BASE (0xfffec600)
+#define OMAP_MPU_TIMER3_BASE (0xfffec700)
+#define MPU_TIMER_FREE (1 << 6)
+#define MPU_TIMER_CLOCK_ENABLE (1 << 5)
+#define MPU_TIMER_AR (1 << 1)
+#define MPU_TIMER_ST (1 << 0)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE (0xfffece00)
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+#define CK_RATEF 1
+#define CK_IDLEF 2
+#define CK_ENABLEF 4
+#define CK_SELECTF 8
+#define SETARM_IDLE_SHIFT
+
+/* DPLL control registers */
+#define DPLL_CTL (0xfffecf00)
+
+/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
+#define DSP_CONFIG_REG_BASE IOMEM(0xe1008000)
+#define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0)
+#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4)
+#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8)
+#define DSP_RSTCT2 (DSP_CONFIG_REG_BASE + 0x14)
+
+/*
+ * ---------------------------------------------------------------------------
+ * UPLD
+ * ---------------------------------------------------------------------------
+ */
+#define ULPD_REG_BASE (0xfffe0800)
+#define ULPD_IT_STATUS (ULPD_REG_BASE + 0x14)
+#define ULPD_SETUP_ANALOG_CELL_3 (ULPD_REG_BASE + 0x24)
+#define ULPD_CLOCK_CTRL (ULPD_REG_BASE + 0x30)
+# define DIS_USB_PVCI_CLK (1 << 5) /* no USB/FAC synch */
+# define USB_MCLK_EN (1 << 4) /* enable W4_USB_CLKO */
+#define ULPD_SOFT_REQ (ULPD_REG_BASE + 0x34)
+# define SOFT_UDC_REQ (1 << 4)
+# define SOFT_USB_CLK_REQ (1 << 3)
+# define SOFT_DPLL_REQ (1 << 0)
+#define ULPD_DPLL_CTRL (ULPD_REG_BASE + 0x3c)
+#define ULPD_STATUS_REQ (ULPD_REG_BASE + 0x40)
+#define ULPD_APLL_CTRL (ULPD_REG_BASE + 0x4c)
+#define ULPD_POWER_CTRL (ULPD_REG_BASE + 0x50)
+#define ULPD_SOFT_DISABLE_REQ_REG (ULPD_REG_BASE + 0x68)
+# define DIS_MMC2_DPLL_REQ (1 << 11)
+# define DIS_MMC1_DPLL_REQ (1 << 10)
+# define DIS_UART3_DPLL_REQ (1 << 9)
+# define DIS_UART2_DPLL_REQ (1 << 8)
+# define DIS_UART1_DPLL_REQ (1 << 7)
+# define DIS_USB_HOST_DPLL_REQ (1 << 6)
+#define ULPD_SDW_CLK_DIV_CTRL_SEL (ULPD_REG_BASE + 0x74)
+#define ULPD_CAM_CLK_CTRL (ULPD_REG_BASE + 0x7c)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Watchdog timer
+ * ---------------------------------------------------------------------------
+ */
+
+/* Watchdog timer within the OMAP3.2 gigacell */
+#define OMAP_MPU_WATCHDOG_BASE (0xfffec800)
+#define OMAP_WDT_TIMER (OMAP_MPU_WATCHDOG_BASE + 0x0)
+#define OMAP_WDT_LOAD_TIM (OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_READ_TIM (OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_TIMER_MODE (OMAP_MPU_WATCHDOG_BASE + 0x8)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#ifdef CONFIG_ARCH_OMAP1
+
+/*
+ * XXX: These probably want to be moved to arch/arm/mach-omap/omap1/irq.c
+ * or something similar.. -- PFM.
+ */
+
+#define OMAP_IH1_BASE 0xfffecb00
+#define OMAP_IH2_BASE 0xfffe0000
+
+#define OMAP_IH1_ITR (OMAP_IH1_BASE + 0x00)
+#define OMAP_IH1_MIR (OMAP_IH1_BASE + 0x04)
+#define OMAP_IH1_SIR_IRQ (OMAP_IH1_BASE + 0x10)
+#define OMAP_IH1_SIR_FIQ (OMAP_IH1_BASE + 0x14)
+#define OMAP_IH1_CONTROL (OMAP_IH1_BASE + 0x18)
+#define OMAP_IH1_ILR0 (OMAP_IH1_BASE + 0x1c)
+#define OMAP_IH1_ISR (OMAP_IH1_BASE + 0x9c)
+
+#define OMAP_IH2_ITR (OMAP_IH2_BASE + 0x00)
+#define OMAP_IH2_MIR (OMAP_IH2_BASE + 0x04)
+#define OMAP_IH2_SIR_IRQ (OMAP_IH2_BASE + 0x10)
+#define OMAP_IH2_SIR_FIQ (OMAP_IH2_BASE + 0x14)
+#define OMAP_IH2_CONTROL (OMAP_IH2_BASE + 0x18)
+#define OMAP_IH2_ILR0 (OMAP_IH2_BASE + 0x1c)
+#define OMAP_IH2_ISR (OMAP_IH2_BASE + 0x9c)
+
+#define IRQ_ITR_REG_OFFSET 0x00
+#define IRQ_MIR_REG_OFFSET 0x04
+#define IRQ_SIR_IRQ_REG_OFFSET 0x10
+#define IRQ_SIR_FIQ_REG_OFFSET 0x14
+#define IRQ_CONTROL_REG_OFFSET 0x18
+#define IRQ_ISR_REG_OFFSET 0x9c
+#define IRQ_ILR0_REG_OFFSET 0x1c
+#define IRQ_GMR_REG_OFFSET 0xa0
+
+#endif
+
+/*
+ * ----------------------------------------------------------------------------
+ * System control registers
+ * ----------------------------------------------------------------------------
+ */
+#define MOD_CONF_CTRL_0 0xfffe1080
+#define MOD_CONF_CTRL_1 0xfffe1110
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pin multiplexing registers
+ * ----------------------------------------------------------------------------
+ */
+#define FUNC_MUX_CTRL_0 0xfffe1000
+#define FUNC_MUX_CTRL_1 0xfffe1004
+#define FUNC_MUX_CTRL_2 0xfffe1008
+#define COMP_MODE_CTRL_0 0xfffe100c
+#define FUNC_MUX_CTRL_3 0xfffe1010
+#define FUNC_MUX_CTRL_4 0xfffe1014
+#define FUNC_MUX_CTRL_5 0xfffe1018
+#define FUNC_MUX_CTRL_6 0xfffe101C
+#define FUNC_MUX_CTRL_7 0xfffe1020
+#define FUNC_MUX_CTRL_8 0xfffe1024
+#define FUNC_MUX_CTRL_9 0xfffe1028
+#define FUNC_MUX_CTRL_A 0xfffe102C
+#define FUNC_MUX_CTRL_B 0xfffe1030
+#define FUNC_MUX_CTRL_C 0xfffe1034
+#define FUNC_MUX_CTRL_D 0xfffe1038
+#define PULL_DWN_CTRL_0 0xfffe1040
+#define PULL_DWN_CTRL_1 0xfffe1044
+#define PULL_DWN_CTRL_2 0xfffe1048
+#define PULL_DWN_CTRL_3 0xfffe104c
+#define PULL_DWN_CTRL_4 0xfffe10ac
+
+/* OMAP-1610 specific multiplexing registers */
+#define FUNC_MUX_CTRL_E 0xfffe1090
+#define FUNC_MUX_CTRL_F 0xfffe1094
+#define FUNC_MUX_CTRL_10 0xfffe1098
+#define FUNC_MUX_CTRL_11 0xfffe109c
+#define FUNC_MUX_CTRL_12 0xfffe10a0
+#define PU_PD_SEL_0 0xfffe10b4
+#define PU_PD_SEL_1 0xfffe10b8
+#define PU_PD_SEL_2 0xfffe10bc
+#define PU_PD_SEL_3 0xfffe10c0
+#define PU_PD_SEL_4 0xfffe10c4
+
+/* Timer32K for 1610 and 1710*/
+#define OMAP_TIMER32K_BASE 0xFFFBC400
+
+/*
+ * ---------------------------------------------------------------------------
+ * TIPB bus interface
+ * ---------------------------------------------------------------------------
+ */
+#define TIPB_PUBLIC_CNTL_BASE 0xfffed300
+#define MPU_PUBLIC_TIPB_CNTL (TIPB_PUBLIC_CNTL_BASE + 0x8)
+#define TIPB_PRIVATE_CNTL_BASE 0xfffeca00
+#define MPU_PRIVATE_TIPB_CNTL (TIPB_PRIVATE_CNTL_BASE + 0x8)
+
+/*
+ * ----------------------------------------------------------------------------
+ * MPUI interface
+ * ----------------------------------------------------------------------------
+ */
+#define MPUI_BASE (0xfffec900)
+#define MPUI_CTRL (MPUI_BASE + 0x0)
+#define MPUI_DEBUG_ADDR (MPUI_BASE + 0x4)
+#define MPUI_DEBUG_DATA (MPUI_BASE + 0x8)
+#define MPUI_DEBUG_FLAG (MPUI_BASE + 0xc)
+#define MPUI_STATUS_REG (MPUI_BASE + 0x10)
+#define MPUI_DSP_STATUS (MPUI_BASE + 0x14)
+#define MPUI_DSP_BOOT_CONFIG (MPUI_BASE + 0x18)
+#define MPUI_DSP_API_CONFIG (MPUI_BASE + 0x1c)
+
+/*
+ * ----------------------------------------------------------------------------
+ * LED Pulse Generator
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_LPG1_BASE 0xfffbd000
+#define OMAP_LPG2_BASE 0xfffbd800
+#define OMAP_LPG1_LCR (OMAP_LPG1_BASE + 0x00)
+#define OMAP_LPG1_PMR (OMAP_LPG1_BASE + 0x04)
+#define OMAP_LPG2_LCR (OMAP_LPG2_BASE + 0x00)
+#define OMAP_LPG2_PMR (OMAP_LPG2_BASE + 0x04)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pulse-Width Light
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP_PWL_BASE 0xfffb5800
+#define OMAP_PWL_ENABLE (OMAP_PWL_BASE + 0x00)
+#define OMAP_PWL_CLK_ENABLE (OMAP_PWL_BASE + 0x04)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Processor specific defines
+ * ---------------------------------------------------------------------------
+ */
+
+#include <plat/omap7xx.h>
+#include <plat/omap1510.h>
+#include <plat/omap16xx.h>
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+#include <plat/omap44xx.h>
+#include <plat/ti816x.h>
+
+#endif /* __ASM_ARCH_OMAP_HARDWARE_H */
diff --git a/arch/arm/plat-omap/include/plat/hwa742.h b/arch/arm/plat-omap/include/plat/hwa742.h
new file mode 100644
index 00000000..886248d3
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/hwa742.h
@@ -0,0 +1,8 @@
+#ifndef _HWA742_H
+#define _HWA742_H
+
+struct hwa742_platform_data {
+ unsigned te_connected:1;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h
new file mode 100644
index 00000000..878d632c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/i2c.h
@@ -0,0 +1,55 @@
+/*
+ * Helper module for board specific I2C bus registration
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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
+ *
+ */
+#ifndef __ASM__ARCH_OMAP_I2C_H
+#define __ASM__ARCH_OMAP_I2C_H
+
+#include <linux/i2c.h>
+
+#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len);
+#else
+static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
+ struct i2c_board_info const *info,
+ unsigned len)
+{
+ return 0;
+}
+#endif
+
+/**
+ * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod
+ * @fifo_depth: total controller FIFO size (in bytes)
+ * @flags: differences in hardware support capability
+ *
+ * @fifo_depth represents what exists on the hardware, not what is
+ * actually configured at runtime by the device driver.
+ */
+struct omap_i2c_dev_attr {
+ u8 fifo_depth;
+ u8 flags;
+};
+
+void __init omap1_i2c_mux_pins(int bus_id);
+void __init omap2_i2c_mux_pins(int bus_id);
+
+#endif /* __ASM__ARCH_OMAP_I2C_H */
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
new file mode 100644
index 00000000..d72ec85c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -0,0 +1,314 @@
+/*
+ * arch/arm/plat-omap/include/mach/io.h
+ *
+ * IO definitions for TI OMAP processors and boards
+ *
+ * Copied from arch/arm/mach-sa1100/include/mach/io.h
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ * Modifications:
+ * 06-12-1997 RMK Created.
+ * 07-04-1999 RMK Major cleanup
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <mach/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+/*
+ * ----------------------------------------------------------------------------
+ * I/O mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x) (x)
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
+#endif
+
+#define OMAP1_IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
+#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET)
+
+#define OMAP2_L3_IO_OFFSET 0x90000000
+#define OMAP2_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L3_IO_OFFSET) /* L3 */
+
+
+#define OMAP2_L4_IO_OFFSET 0xb2000000
+#define OMAP2_L4_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_L4_IO_OFFSET) /* L4 */
+
+#define OMAP4_L3_IO_OFFSET 0xb4000000
+#define OMAP4_L3_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_IO_OFFSET) /* L3 */
+
+#define OMAP4_L3_PER_IO_OFFSET 0xb1100000
+#define OMAP4_L3_PER_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_L3_PER_IO_OFFSET)
+
+#define OMAP4_GPMC_IO_OFFSET 0xa9000000
+#define OMAP4_GPMC_IO_ADDRESS(pa) IOMEM((pa) + OMAP4_GPMC_IO_OFFSET)
+
+#define OMAP2_EMU_IO_OFFSET 0xaa800000 /* Emulation */
+#define OMAP2_EMU_IO_ADDRESS(pa) IOMEM((pa) + OMAP2_EMU_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap1 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+#define OMAP1_IO_PHYS 0xFFFB0000
+#define OMAP1_IO_SIZE 0x40000
+#define OMAP1_IO_VIRT (OMAP1_IO_PHYS - OMAP1_IO_OFFSET)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap2 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP2 */
+#define L3_24XX_PHYS L3_24XX_BASE /* 0x68000000 --> 0xf8000000*/
+#define L3_24XX_VIRT (L3_24XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_24XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */
+#define L4_24XX_PHYS L4_24XX_BASE /* 0x48000000 --> 0xfa000000 */
+#define L4_24XX_VIRT (L4_24XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */
+
+#define L4_WK_243X_PHYS L4_WK_243X_BASE /* 0x49000000 --> 0xfb000000 */
+#define L4_WK_243X_VIRT (L4_WK_243X_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_WK_243X_SIZE SZ_1M
+#define OMAP243X_GPMC_PHYS OMAP243X_GPMC_BASE
+#define OMAP243X_GPMC_VIRT (OMAP243X_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+ /* 0x6e000000 --> 0xfe000000 */
+#define OMAP243X_GPMC_SIZE SZ_1M
+#define OMAP243X_SDRC_PHYS OMAP243X_SDRC_BASE
+ /* 0x6D000000 --> 0xfd000000 */
+#define OMAP243X_SDRC_VIRT (OMAP243X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SDRC_SIZE SZ_1M
+#define OMAP243X_SMS_PHYS OMAP243X_SMS_BASE
+ /* 0x6c000000 --> 0xfc000000 */
+#define OMAP243X_SMS_VIRT (OMAP243X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP243X_SMS_SIZE SZ_1M
+
+/* 2420 IVA */
+#define DSP_MEM_2420_PHYS OMAP2420_DSP_MEM_BASE
+ /* 0x58000000 --> 0xfc100000 */
+#define DSP_MEM_2420_VIRT 0xfc100000
+#define DSP_MEM_2420_SIZE 0x28000
+#define DSP_IPI_2420_PHYS OMAP2420_DSP_IPI_BASE
+ /* 0x59000000 --> 0xfc128000 */
+#define DSP_IPI_2420_VIRT 0xfc128000
+#define DSP_IPI_2420_SIZE SZ_4K
+#define DSP_MMU_2420_PHYS OMAP2420_DSP_MMU_BASE
+ /* 0x5a000000 --> 0xfc129000 */
+#define DSP_MMU_2420_VIRT 0xfc129000
+#define DSP_MMU_2420_SIZE SZ_4K
+
+/* 2430 IVA2.1 - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap3 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP3 */
+#define L3_34XX_PHYS L3_34XX_BASE /* 0x68000000 --> 0xf8000000 */
+#define L3_34XX_VIRT (L3_34XX_PHYS + OMAP2_L3_IO_OFFSET)
+#define L3_34XX_SIZE SZ_1M /* 44kB of 128MB used, want 1MB sect */
+
+#define L4_34XX_PHYS L4_34XX_BASE /* 0x48000000 --> 0xfa000000 */
+#define L4_34XX_VIRT (L4_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_34XX_SIZE SZ_4M /* 1MB of 128MB used, want 1MB sect */
+
+/*
+ * Need to look at the Size 4M for L4.
+ * VPOM3430 was not working for Int controller
+ */
+
+#define L4_PER_34XX_PHYS L4_PER_34XX_BASE
+ /* 0x49000000 --> 0xfb000000 */
+#define L4_PER_34XX_VIRT (L4_PER_34XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_34XX_SIZE SZ_1M
+
+#define L4_EMU_34XX_PHYS L4_EMU_34XX_BASE
+ /* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_34XX_VIRT (L4_EMU_34XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_34XX_SIZE SZ_8M
+
+#define OMAP34XX_GPMC_PHYS OMAP34XX_GPMC_BASE
+ /* 0x6e000000 --> 0xfe000000 */
+#define OMAP34XX_GPMC_VIRT (OMAP34XX_GPMC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP34XX_GPMC_SIZE SZ_1M
+
+#define OMAP343X_SMS_PHYS OMAP343X_SMS_BASE
+ /* 0x6c000000 --> 0xfc000000 */
+#define OMAP343X_SMS_VIRT (OMAP343X_SMS_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SMS_SIZE SZ_1M
+
+#define OMAP343X_SDRC_PHYS OMAP343X_SDRC_BASE
+ /* 0x6D000000 --> 0xfd000000 */
+#define OMAP343X_SDRC_VIRT (OMAP343X_SDRC_PHYS + OMAP2_L3_IO_OFFSET)
+#define OMAP343X_SDRC_SIZE SZ_1M
+
+/* 3430 IVA - currently unmapped */
+
+/*
+ * ----------------------------------------------------------------------------
+ * Omap4 specific IO mapping
+ * ----------------------------------------------------------------------------
+ */
+
+/* We map both L3 and L4 on OMAP4 */
+#define L3_44XX_PHYS L3_44XX_BASE /* 0x44000000 --> 0xf8000000 */
+#define L3_44XX_VIRT (L3_44XX_PHYS + OMAP4_L3_IO_OFFSET)
+#define L3_44XX_SIZE SZ_1M
+
+#define L4_44XX_PHYS L4_44XX_BASE /* 0x4a000000 --> 0xfc000000 */
+#define L4_44XX_VIRT (L4_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_44XX_SIZE SZ_4M
+
+#define L4_PER_44XX_PHYS L4_PER_44XX_BASE
+ /* 0x48000000 --> 0xfa000000 */
+#define L4_PER_44XX_VIRT (L4_PER_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_PER_44XX_SIZE SZ_4M
+
+#define L4_ABE_44XX_PHYS L4_ABE_44XX_BASE
+ /* 0x49000000 --> 0xfb000000 */
+#define L4_ABE_44XX_VIRT (L4_ABE_44XX_PHYS + OMAP2_L4_IO_OFFSET)
+#define L4_ABE_44XX_SIZE SZ_1M
+
+#define L4_EMU_44XX_PHYS L4_EMU_44XX_BASE
+ /* 0x54000000 --> 0xfe800000 */
+#define L4_EMU_44XX_VIRT (L4_EMU_44XX_PHYS + OMAP2_EMU_IO_OFFSET)
+#define L4_EMU_44XX_SIZE SZ_8M
+
+#define OMAP44XX_GPMC_PHYS OMAP44XX_GPMC_BASE
+ /* 0x50000000 --> 0xf9000000 */
+#define OMAP44XX_GPMC_VIRT (OMAP44XX_GPMC_PHYS + OMAP4_GPMC_IO_OFFSET)
+#define OMAP44XX_GPMC_SIZE SZ_1M
+
+
+#define OMAP44XX_EMIF1_PHYS OMAP44XX_EMIF1_BASE
+ /* 0x4c000000 --> 0xfd100000 */
+#define OMAP44XX_EMIF1_VIRT (OMAP44XX_EMIF1_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_EMIF1_SIZE SZ_1M
+
+#define OMAP44XX_EMIF2_PHYS OMAP44XX_EMIF2_BASE
+ /* 0x4d000000 --> 0xfd200000 */
+#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF2_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_EMIF2_SIZE SZ_1M
+
+#define OMAP44XX_DMM_PHYS OMAP44XX_DMM_BASE
+ /* 0x4e000000 --> 0xfd300000 */
+#define OMAP44XX_DMM_VIRT (OMAP44XX_DMM_PHYS + OMAP4_L3_PER_IO_OFFSET)
+#define OMAP44XX_DMM_SIZE SZ_1M
+/*
+ * ----------------------------------------------------------------------------
+ * Omap specific register access
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef __ASSEMBLER__
+
+/*
+ * NOTE: Please use ioremap + __raw_read/write where possible instead of these
+ */
+
+extern u8 omap_readb(u32 pa);
+extern u16 omap_readw(u32 pa);
+extern u32 omap_readl(u32 pa);
+extern void omap_writeb(u8 v, u32 pa);
+extern void omap_writew(u16 v, u32 pa);
+extern void omap_writel(u32 v, u32 pa);
+
+struct omap_sdrc_params;
+
+extern void omap1_map_common_io(void);
+extern void omap1_init_common_hw(void);
+
+#ifdef CONFIG_SOC_OMAP2420
+extern void omap242x_map_common_io(void);
+#else
+static inline void omap242x_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+extern void omap243x_map_common_io(void);
+#else
+static inline void omap243x_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+extern void omap34xx_map_common_io(void);
+#else
+static inline void omap34xx_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAPTI816X
+extern void omapti816x_map_common_io(void);
+#else
+static inline void omapti816x_map_common_io(void)
+{
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP4
+extern void omap44xx_map_common_io(void);
+#else
+static inline void omap44xx_map_common_io(void)
+{
+}
+#endif
+
+extern void omap2_init_common_infrastructure(void);
+extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1);
+
+#define __arch_ioremap omap_ioremap
+#define __arch_iounmap omap_iounmap
+
+void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
+void omap_iounmap(volatile void __iomem *addr);
+
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
new file mode 100644
index 00000000..174f1b9c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -0,0 +1,189 @@
+/*
+ * omap iommu: main structures
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_IOMMU_H
+#define __MACH_IOMMU_H
+
+struct iotlb_entry {
+ u32 da;
+ u32 pa;
+ u32 pgsz, prsvd, valid;
+ union {
+ u16 ap;
+ struct {
+ u32 endian, elsz, mixed;
+ };
+ };
+};
+
+struct iommu {
+ const char *name;
+ struct module *owner;
+ struct clk *clk;
+ void __iomem *regbase;
+ struct device *dev;
+ void *isr_priv;
+
+ unsigned int refcount;
+ struct mutex iommu_lock; /* global for this whole object */
+
+ /*
+ * We don't change iopgd for a situation like pgd for a task,
+ * but share it globally for each iommu.
+ */
+ u32 *iopgd;
+ spinlock_t page_table_lock; /* protect iopgd */
+
+ int nr_tlb_entries;
+
+ struct list_head mmap;
+ struct mutex mmap_lock; /* protect mmap */
+
+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv);
+
+ void *ctx; /* iommu context: registres saved area */
+ u32 da_start;
+ u32 da_end;
+};
+
+struct cr_regs {
+ union {
+ struct {
+ u16 cam_l;
+ u16 cam_h;
+ };
+ u32 cam;
+ };
+ union {
+ struct {
+ u16 ram_l;
+ u16 ram_h;
+ };
+ u32 ram;
+ };
+};
+
+struct iotlb_lock {
+ short base;
+ short vict;
+};
+
+/* architecture specific functions */
+struct iommu_functions {
+ unsigned long version;
+
+ int (*enable)(struct iommu *obj);
+ void (*disable)(struct iommu *obj);
+ void (*set_twl)(struct iommu *obj, bool on);
+ u32 (*fault_isr)(struct iommu *obj, u32 *ra);
+
+ void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
+ void (*tlb_load_cr)(struct iommu *obj, struct cr_regs *cr);
+
+ struct cr_regs *(*alloc_cr)(struct iommu *obj, struct iotlb_entry *e);
+ int (*cr_valid)(struct cr_regs *cr);
+ u32 (*cr_to_virt)(struct cr_regs *cr);
+ void (*cr_to_e)(struct cr_regs *cr, struct iotlb_entry *e);
+ ssize_t (*dump_cr)(struct iommu *obj, struct cr_regs *cr, char *buf);
+
+ u32 (*get_pte_attr)(struct iotlb_entry *e);
+
+ void (*save_ctx)(struct iommu *obj);
+ void (*restore_ctx)(struct iommu *obj);
+ ssize_t (*dump_ctx)(struct iommu *obj, char *buf, ssize_t len);
+};
+
+struct iommu_platform_data {
+ const char *name;
+ const char *clk_name;
+ const int nr_tlb_entries;
+ u32 da_start;
+ u32 da_end;
+};
+
+/* IOMMU errors */
+#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0)
+#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1)
+#define OMAP_IOMMU_ERR_EMU_MISS (1 << 2)
+#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3)
+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4)
+
+#if defined(CONFIG_ARCH_OMAP1)
+#error "iommu for this processor not implemented yet"
+#else
+#include <plat/iommu2.h>
+#endif
+
+/*
+ * utilities for super page(16MB, 1MB, 64KB and 4KB)
+ */
+
+#define iopgsz_max(bytes) \
+ (((bytes) >= SZ_16M) ? SZ_16M : \
+ ((bytes) >= SZ_1M) ? SZ_1M : \
+ ((bytes) >= SZ_64K) ? SZ_64K : \
+ ((bytes) >= SZ_4K) ? SZ_4K : 0)
+
+#define bytes_to_iopgsz(bytes) \
+ (((bytes) == SZ_16M) ? MMU_CAM_PGSZ_16M : \
+ ((bytes) == SZ_1M) ? MMU_CAM_PGSZ_1M : \
+ ((bytes) == SZ_64K) ? MMU_CAM_PGSZ_64K : \
+ ((bytes) == SZ_4K) ? MMU_CAM_PGSZ_4K : -1)
+
+#define iopgsz_to_bytes(iopgsz) \
+ (((iopgsz) == MMU_CAM_PGSZ_16M) ? SZ_16M : \
+ ((iopgsz) == MMU_CAM_PGSZ_1M) ? SZ_1M : \
+ ((iopgsz) == MMU_CAM_PGSZ_64K) ? SZ_64K : \
+ ((iopgsz) == MMU_CAM_PGSZ_4K) ? SZ_4K : 0)
+
+#define iopgsz_ok(bytes) (bytes_to_iopgsz(bytes) >= 0)
+
+/*
+ * global functions
+ */
+extern u32 iommu_arch_version(void);
+
+extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
+extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
+
+extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
+extern void iommu_set_twl(struct iommu *obj, bool on);
+extern void flush_iotlb_page(struct iommu *obj, u32 da);
+extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
+extern void flush_iotlb_all(struct iommu *obj);
+
+extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e);
+extern void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd,
+ u32 **ppte);
+extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova);
+
+extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end);
+extern struct iommu *iommu_get(const char *name);
+extern void iommu_put(struct iommu *obj);
+extern int iommu_set_isr(const char *name,
+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
+ void *priv),
+ void *isr_priv);
+
+extern void iommu_save_ctx(struct iommu *obj);
+extern void iommu_restore_ctx(struct iommu *obj);
+
+extern int install_iommu_arch(const struct iommu_functions *ops);
+extern void uninstall_iommu_arch(const struct iommu_functions *ops);
+
+extern int foreach_iommu_device(void *data,
+ int (*fn)(struct device *, void *));
+
+extern ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t len);
+extern size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t len);
+
+#endif /* __MACH_IOMMU_H */
diff --git a/arch/arm/plat-omap/include/plat/iommu2.h b/arch/arm/plat-omap/include/plat/iommu2.h
new file mode 100644
index 00000000..10ad05f4
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/iommu2.h
@@ -0,0 +1,96 @@
+/*
+ * omap iommu: omap2 architecture specific definitions
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_IOMMU2_H
+#define __MACH_IOMMU2_H
+
+#include <linux/io.h>
+
+/*
+ * MMU Register offsets
+ */
+#define MMU_REVISION 0x00
+#define MMU_SYSCONFIG 0x10
+#define MMU_SYSSTATUS 0x14
+#define MMU_IRQSTATUS 0x18
+#define MMU_IRQENABLE 0x1c
+#define MMU_WALKING_ST 0x40
+#define MMU_CNTL 0x44
+#define MMU_FAULT_AD 0x48
+#define MMU_TTB 0x4c
+#define MMU_LOCK 0x50
+#define MMU_LD_TLB 0x54
+#define MMU_CAM 0x58
+#define MMU_RAM 0x5c
+#define MMU_GFLUSH 0x60
+#define MMU_FLUSH_ENTRY 0x64
+#define MMU_READ_CAM 0x68
+#define MMU_READ_RAM 0x6c
+#define MMU_EMU_FAULT_AD 0x70
+
+#define MMU_REG_SIZE 256
+
+/*
+ * MMU Register bit definitions
+ */
+#define MMU_LOCK_BASE_SHIFT 10
+#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
+#define MMU_LOCK_BASE(x) \
+ ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
+
+#define MMU_LOCK_VICT_SHIFT 4
+#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
+#define MMU_LOCK_VICT(x) \
+ ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
+
+#define MMU_CAM_VATAG_SHIFT 12
+#define MMU_CAM_VATAG_MASK \
+ ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
+#define MMU_CAM_P (1 << 3)
+#define MMU_CAM_V (1 << 2)
+#define MMU_CAM_PGSZ_MASK 3
+#define MMU_CAM_PGSZ_1M (0 << 0)
+#define MMU_CAM_PGSZ_64K (1 << 0)
+#define MMU_CAM_PGSZ_4K (2 << 0)
+#define MMU_CAM_PGSZ_16M (3 << 0)
+
+#define MMU_RAM_PADDR_SHIFT 12
+#define MMU_RAM_PADDR_MASK \
+ ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
+#define MMU_RAM_ENDIAN_SHIFT 9
+#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ELSZ_SHIFT 7
+#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_MIXED_SHIFT 6
+#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
+#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
+
+/*
+ * register accessors
+ */
+static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
+{
+ return __raw_readl(obj->regbase + offs);
+}
+
+static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
+{
+ __raw_writel(val, obj->regbase + offs);
+}
+
+#endif /* __MACH_IOMMU2_H */
diff --git a/arch/arm/plat-omap/include/plat/iovmm.h b/arch/arm/plat-omap/include/plat/iovmm.h
new file mode 100644
index 00000000..e992b965
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/iovmm.h
@@ -0,0 +1,89 @@
+/*
+ * omap iommu: simple virtual address space management
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __IOMMU_MMAP_H
+#define __IOMMU_MMAP_H
+
+struct iovm_struct {
+ struct iommu *iommu; /* iommu object which this belongs to */
+ u32 da_start; /* area definition */
+ u32 da_end;
+ u32 flags; /* IOVMF_: see below */
+ struct list_head list; /* linked in ascending order */
+ const struct sg_table *sgt; /* keep 'page' <-> 'da' mapping */
+ void *va; /* mpu side mapped address */
+};
+
+/*
+ * IOVMF_FLAGS: attribute for iommu virtual memory area(iovma)
+ *
+ * lower 16 bit is used for h/w and upper 16 bit is for s/w.
+ */
+#define IOVMF_SW_SHIFT 16
+
+/*
+ * iovma: h/w flags derived from cam and ram attribute
+ */
+#define IOVMF_CAM_MASK (~((1 << 10) - 1))
+#define IOVMF_RAM_MASK (~IOVMF_CAM_MASK)
+
+#define IOVMF_PGSZ_MASK (3 << 0)
+#define IOVMF_PGSZ_1M MMU_CAM_PGSZ_1M
+#define IOVMF_PGSZ_64K MMU_CAM_PGSZ_64K
+#define IOVMF_PGSZ_4K MMU_CAM_PGSZ_4K
+#define IOVMF_PGSZ_16M MMU_CAM_PGSZ_16M
+
+#define IOVMF_ENDIAN_MASK (1 << 9)
+#define IOVMF_ENDIAN_BIG MMU_RAM_ENDIAN_BIG
+#define IOVMF_ENDIAN_LITTLE MMU_RAM_ENDIAN_LITTLE
+
+#define IOVMF_ELSZ_MASK (3 << 7)
+#define IOVMF_ELSZ_8 MMU_RAM_ELSZ_8
+#define IOVMF_ELSZ_16 MMU_RAM_ELSZ_16
+#define IOVMF_ELSZ_32 MMU_RAM_ELSZ_32
+#define IOVMF_ELSZ_NONE MMU_RAM_ELSZ_NONE
+
+#define IOVMF_MIXED_MASK (1 << 6)
+#define IOVMF_MIXED MMU_RAM_MIXED
+
+/*
+ * iovma: s/w flags, used for mapping and umapping internally.
+ */
+#define IOVMF_MMIO (1 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC (2 << IOVMF_SW_SHIFT)
+#define IOVMF_ALLOC_MASK (3 << IOVMF_SW_SHIFT)
+
+/* "superpages" is supported just with physically linear pages */
+#define IOVMF_DISCONT (1 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR (2 << (2 + IOVMF_SW_SHIFT))
+#define IOVMF_LINEAR_MASK (3 << (2 + IOVMF_SW_SHIFT))
+
+#define IOVMF_DA_FIXED (1 << (4 + IOVMF_SW_SHIFT))
+
+
+extern struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da);
+extern u32 iommu_vmap(struct iommu *obj, u32 da,
+ const struct sg_table *sgt, u32 flags);
+extern struct sg_table *iommu_vunmap(struct iommu *obj, u32 da);
+extern u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes,
+ u32 flags);
+extern void iommu_vfree(struct iommu *obj, const u32 da);
+extern u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
+ u32 flags);
+extern void iommu_kunmap(struct iommu *obj, u32 da);
+extern u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes,
+ u32 flags);
+extern void iommu_kfree(struct iommu *obj, u32 da);
+
+extern void *da_to_va(struct iommu *obj, u32 da);
+
+#endif /* __IOMMU_MMAP_H */
diff --git a/arch/arm/plat-omap/include/plat/irda.h b/arch/arm/plat-omap/include/plat/irda.h
new file mode 100644
index 00000000..40f60339
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/irda.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/plat-omap/include/mach/irda.h
+ *
+ * Copyright (C) 2005-2006 Komal Shah <komal_shah802003@yahoo.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 ASMARM_ARCH_IRDA_H
+#define ASMARM_ARCH_IRDA_H
+
+/* board specific transceiver capabilities */
+
+#define IR_SEL 1 /* Selects IrDA */
+#define IR_SIRMODE 2
+#define IR_FIRMODE 4
+#define IR_MIRMODE 8
+
+struct omap_irda_config {
+ int transceiver_cap;
+ int (*transceiver_mode)(struct device *dev, int mode);
+ int (*select_irda)(struct device *dev, int state);
+ int rx_channel;
+ int tx_channel;
+ unsigned long dest_start;
+ unsigned long src_start;
+ int tx_trigger;
+ int rx_trigger;
+ int mode;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/irqs-44xx.h b/arch/arm/plat-omap/include/plat/irqs-44xx.h
new file mode 100644
index 00000000..518322c8
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/irqs-44xx.h
@@ -0,0 +1,144 @@
+/*
+ * OMAP4 Interrupt lines definitions
+ *
+ * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ *
+ * Santosh Shilimkar (santosh.shilimkar@ti.com)
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This file is automatically generated from the OMAP hardware databases.
+ * We respectfully ask that any modifications to this file be coordinated
+ * with the public linux-omap@vger.kernel.org mailing list and the
+ * authors above to ensure that the autogeneration scripts are kept
+ * up-to-date with the file contents.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_OMAP44XX_IRQS_H
+#define __ARCH_ARM_MACH_OMAP2_OMAP44XX_IRQS_H
+
+/* OMAP44XX IRQs numbers definitions */
+#define OMAP44XX_IRQ_LOCALTIMER 29
+#define OMAP44XX_IRQ_LOCALWDT 30
+
+#define OMAP44XX_IRQ_GIC_START 32
+
+#define OMAP44XX_IRQ_PL310 (0 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CTI0 (1 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CTI1 (2 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ELM (4 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SYS_1N (7 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SECURITY_EVENTS (8 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_L3_DBG (9 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_L3_APP (10 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_PRCM (11 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_0 (12 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_1 (13 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_2 (14 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SDMA_3 (15 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP4 (16 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP1 (17 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_MCU (18 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_CORE (19 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPMC (20 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GFX (21 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP2 (22 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCBSP3 (23 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ISS_5 (24 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DISPC (25 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MAIL_U0 (26 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_C2C_SSCM_0 (27 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_TESLA_MMU (28 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO1 (29 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO2 (30 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO3 (31 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO4 (32 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO5 (33 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPIO6 (34 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_USIM (35 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_WDT3 (36 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT1 (37 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT2 (38 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT3 (39 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT4 (40 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT5 (41 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT6 (42 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT7 (43 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT8 (44 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT9 (45 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT10 (46 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT11 (47 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI4 (48 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SHA1_S (49 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FPKA_SINTREQUEST_S (50 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SHA1_P (51 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_RNG (52 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DSI1 (53 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C1 (56 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C2 (57 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HDQ (58 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC5 (59 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C3 (61 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_I2C4 (62 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES2_S (63 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES2_P (64 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI1 (65 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI2 (66 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_P1 (67 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_P2 (68 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FDIF_3 (69 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART4 (70 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HSI_DMA (71 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART1 (72 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART2 (73 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UART3 (74 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_PBIAS (75 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_OHCI (76 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EHCI (77 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_TLL (78 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES1_S (79 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_WDT2 (80 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DES_S (81 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DES_P (82 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC1 (83 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_DSI2 (84 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_AES1_P (85 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC2 (86 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MPU_ICR (87 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_C2C_SSCM_1 (88 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FSUSB (89 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_FSUSB_SMI (90 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SPI3 (91 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HS_USB_MC_N (92 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_HS_USB_DMA_N (93 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC3 (94 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_GPT12 (95 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MMC4 (96 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SLIMBUS1 (97 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SLIMBUS2 (98 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_ABE (99 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DUCATI_MMU (100 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DSS_HDMI (101 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SR_IVA (102 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POSYNCITRPEND_1 (103 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POSYNCITRPEND_0 (104 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_IVA_HD_POMBINTRPEND_0 (107 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCASP1_AR (108 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCASP1_AX (109 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EMIF4_1 (110 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_EMIF4_2 (111 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_MCPDM (112 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DMM (113 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_DMIC (114 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_0 (115 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_1 (116 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_2 (117 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_CDMA_3 (118 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_SYS_2N (119 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_KBD_CTL (120 + OMAP44XX_IRQ_GIC_START)
+#define OMAP44XX_IRQ_UNIPRO1 (124 + OMAP44XX_IRQ_GIC_START)
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/irqs.h b/arch/arm/plat-omap/include/plat/irqs.h
new file mode 100644
index 00000000..5a25098e
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/irqs.h
@@ -0,0 +1,446 @@
+/*
+ * arch/arm/plat-omap/include/mach/irqs.h
+ *
+ * Copyright (C) Greg Lonnon 2001
+ * Updated for OMAP-1610 by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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
+ *
+ * NOTE: The interrupt vectors for the OMAP-1509, OMAP-1510, and OMAP-1610
+ * are different.
+ */
+
+#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
+#define __ASM_ARCH_OMAP15XX_IRQS_H
+
+/* All OMAP4 specific defines are moved to irqs-44xx.h */
+#include "irqs-44xx.h"
+
+/*
+ * IRQ numbers for interrupt handler 1
+ *
+ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
+ *
+ */
+#define INT_CAMERA 1
+#define INT_FIQ 3
+#define INT_RTDX 6
+#define INT_DSP_MMU_ABORT 7
+#define INT_HOST 8
+#define INT_ABORT 9
+#define INT_BRIDGE_PRIV 13
+#define INT_GPIO_BANK1 14
+#define INT_UART3 15
+#define INT_TIMER3 16
+#define INT_DMA_CH0_6 19
+#define INT_DMA_CH1_7 20
+#define INT_DMA_CH2_8 21
+#define INT_DMA_CH3 22
+#define INT_DMA_CH4 23
+#define INT_DMA_CH5 24
+#define INT_DMA_LCD 25
+#define INT_TIMER1 26
+#define INT_WD_TIMER 27
+#define INT_BRIDGE_PUB 28
+#define INT_TIMER2 30
+#define INT_LCD_CTRL 31
+
+/*
+ * OMAP-1510 specific IRQ numbers for interrupt handler 1
+ */
+#define INT_1510_IH2_IRQ 0
+#define INT_1510_RES2 2
+#define INT_1510_SPI_TX 4
+#define INT_1510_SPI_RX 5
+#define INT_1510_DSP_MAILBOX1 10
+#define INT_1510_DSP_MAILBOX2 11
+#define INT_1510_RES12 12
+#define INT_1510_LB_MMU 17
+#define INT_1510_RES18 18
+#define INT_1510_LOCAL_BUS 29
+
+/*
+ * OMAP-1610 specific IRQ numbers for interrupt handler 1
+ */
+#define INT_1610_IH2_IRQ INT_1510_IH2_IRQ
+#define INT_1610_IH2_FIQ 2
+#define INT_1610_McBSP2_TX 4
+#define INT_1610_McBSP2_RX 5
+#define INT_1610_DSP_MAILBOX1 10
+#define INT_1610_DSP_MAILBOX2 11
+#define INT_1610_LCD_LINE 12
+#define INT_1610_GPTIMER1 17
+#define INT_1610_GPTIMER2 18
+#define INT_1610_SSR_FIFO_0 29
+
+/*
+ * OMAP-7xx specific IRQ numbers for interrupt handler 1
+ */
+#define INT_7XX_IH2_FIQ 0
+#define INT_7XX_IH2_IRQ 1
+#define INT_7XX_USB_NON_ISO 2
+#define INT_7XX_USB_ISO 3
+#define INT_7XX_ICR 4
+#define INT_7XX_EAC 5
+#define INT_7XX_GPIO_BANK1 6
+#define INT_7XX_GPIO_BANK2 7
+#define INT_7XX_GPIO_BANK3 8
+#define INT_7XX_McBSP2TX 10
+#define INT_7XX_McBSP2RX 11
+#define INT_7XX_McBSP2RX_OVF 12
+#define INT_7XX_LCD_LINE 14
+#define INT_7XX_GSM_PROTECT 15
+#define INT_7XX_TIMER3 16
+#define INT_7XX_GPIO_BANK5 17
+#define INT_7XX_GPIO_BANK6 18
+#define INT_7XX_SPGIO_WR 29
+
+/*
+ * IRQ numbers for interrupt handler 2
+ *
+ * NOTE: See also the OMAP-1510 and 1610 specific IRQ numbers below
+ */
+#define IH2_BASE 32
+
+#define INT_KEYBOARD (1 + IH2_BASE)
+#define INT_uWireTX (2 + IH2_BASE)
+#define INT_uWireRX (3 + IH2_BASE)
+#define INT_I2C (4 + IH2_BASE)
+#define INT_MPUIO (5 + IH2_BASE)
+#define INT_USB_HHC_1 (6 + IH2_BASE)
+#define INT_McBSP3TX (10 + IH2_BASE)
+#define INT_McBSP3RX (11 + IH2_BASE)
+#define INT_McBSP1TX (12 + IH2_BASE)
+#define INT_McBSP1RX (13 + IH2_BASE)
+#define INT_UART1 (14 + IH2_BASE)
+#define INT_UART2 (15 + IH2_BASE)
+#define INT_BT_MCSI1TX (16 + IH2_BASE)
+#define INT_BT_MCSI1RX (17 + IH2_BASE)
+#define INT_SOSSI_MATCH (19 + IH2_BASE)
+#define INT_USB_W2FC (20 + IH2_BASE)
+#define INT_1WIRE (21 + IH2_BASE)
+#define INT_OS_TIMER (22 + IH2_BASE)
+#define INT_MMC (23 + IH2_BASE)
+#define INT_GAUGE_32K (24 + IH2_BASE)
+#define INT_RTC_TIMER (25 + IH2_BASE)
+#define INT_RTC_ALARM (26 + IH2_BASE)
+#define INT_MEM_STICK (27 + IH2_BASE)
+
+/*
+ * OMAP-1510 specific IRQ numbers for interrupt handler 2
+ */
+#define INT_1510_DSP_MMU (28 + IH2_BASE)
+#define INT_1510_COM_SPI_RO (31 + IH2_BASE)
+
+/*
+ * OMAP-1610 specific IRQ numbers for interrupt handler 2
+ */
+#define INT_1610_FAC (0 + IH2_BASE)
+#define INT_1610_USB_HHC_2 (7 + IH2_BASE)
+#define INT_1610_USB_OTG (8 + IH2_BASE)
+#define INT_1610_SoSSI (9 + IH2_BASE)
+#define INT_1610_SoSSI_MATCH (19 + IH2_BASE)
+#define INT_1610_DSP_MMU (28 + IH2_BASE)
+#define INT_1610_McBSP2RX_OF (31 + IH2_BASE)
+#define INT_1610_STI (32 + IH2_BASE)
+#define INT_1610_STI_WAKEUP (33 + IH2_BASE)
+#define INT_1610_GPTIMER3 (34 + IH2_BASE)
+#define INT_1610_GPTIMER4 (35 + IH2_BASE)
+#define INT_1610_GPTIMER5 (36 + IH2_BASE)
+#define INT_1610_GPTIMER6 (37 + IH2_BASE)
+#define INT_1610_GPTIMER7 (38 + IH2_BASE)
+#define INT_1610_GPTIMER8 (39 + IH2_BASE)
+#define INT_1610_GPIO_BANK2 (40 + IH2_BASE)
+#define INT_1610_GPIO_BANK3 (41 + IH2_BASE)
+#define INT_1610_MMC2 (42 + IH2_BASE)
+#define INT_1610_CF (43 + IH2_BASE)
+#define INT_1610_WAKE_UP_REQ (46 + IH2_BASE)
+#define INT_1610_GPIO_BANK4 (48 + IH2_BASE)
+#define INT_1610_SPI (49 + IH2_BASE)
+#define INT_1610_DMA_CH6 (53 + IH2_BASE)
+#define INT_1610_DMA_CH7 (54 + IH2_BASE)
+#define INT_1610_DMA_CH8 (55 + IH2_BASE)
+#define INT_1610_DMA_CH9 (56 + IH2_BASE)
+#define INT_1610_DMA_CH10 (57 + IH2_BASE)
+#define INT_1610_DMA_CH11 (58 + IH2_BASE)
+#define INT_1610_DMA_CH12 (59 + IH2_BASE)
+#define INT_1610_DMA_CH13 (60 + IH2_BASE)
+#define INT_1610_DMA_CH14 (61 + IH2_BASE)
+#define INT_1610_DMA_CH15 (62 + IH2_BASE)
+#define INT_1610_NAND (63 + IH2_BASE)
+#define INT_1610_SHA1MD5 (91 + IH2_BASE)
+
+/*
+ * OMAP-7xx specific IRQ numbers for interrupt handler 2
+ */
+#define INT_7XX_HW_ERRORS (0 + IH2_BASE)
+#define INT_7XX_NFIQ_PWR_FAIL (1 + IH2_BASE)
+#define INT_7XX_CFCD (2 + IH2_BASE)
+#define INT_7XX_CFIREQ (3 + IH2_BASE)
+#define INT_7XX_I2C (4 + IH2_BASE)
+#define INT_7XX_PCC (5 + IH2_BASE)
+#define INT_7XX_MPU_EXT_NIRQ (6 + IH2_BASE)
+#define INT_7XX_SPI_100K_1 (7 + IH2_BASE)
+#define INT_7XX_SYREN_SPI (8 + IH2_BASE)
+#define INT_7XX_VLYNQ (9 + IH2_BASE)
+#define INT_7XX_GPIO_BANK4 (10 + IH2_BASE)
+#define INT_7XX_McBSP1TX (11 + IH2_BASE)
+#define INT_7XX_McBSP1RX (12 + IH2_BASE)
+#define INT_7XX_McBSP1RX_OF (13 + IH2_BASE)
+#define INT_7XX_UART_MODEM_IRDA_2 (14 + IH2_BASE)
+#define INT_7XX_UART_MODEM_1 (15 + IH2_BASE)
+#define INT_7XX_MCSI (16 + IH2_BASE)
+#define INT_7XX_uWireTX (17 + IH2_BASE)
+#define INT_7XX_uWireRX (18 + IH2_BASE)
+#define INT_7XX_SMC_CD (19 + IH2_BASE)
+#define INT_7XX_SMC_IREQ (20 + IH2_BASE)
+#define INT_7XX_HDQ_1WIRE (21 + IH2_BASE)
+#define INT_7XX_TIMER32K (22 + IH2_BASE)
+#define INT_7XX_MMC_SDIO (23 + IH2_BASE)
+#define INT_7XX_UPLD (24 + IH2_BASE)
+#define INT_7XX_USB_HHC_1 (27 + IH2_BASE)
+#define INT_7XX_USB_HHC_2 (28 + IH2_BASE)
+#define INT_7XX_USB_GENI (29 + IH2_BASE)
+#define INT_7XX_USB_OTG (30 + IH2_BASE)
+#define INT_7XX_CAMERA_IF (31 + IH2_BASE)
+#define INT_7XX_RNG (32 + IH2_BASE)
+#define INT_7XX_DUAL_MODE_TIMER (33 + IH2_BASE)
+#define INT_7XX_DBB_RF_EN (34 + IH2_BASE)
+#define INT_7XX_MPUIO_KEYPAD (35 + IH2_BASE)
+#define INT_7XX_SHA1_MD5 (36 + IH2_BASE)
+#define INT_7XX_SPI_100K_2 (37 + IH2_BASE)
+#define INT_7XX_RNG_IDLE (38 + IH2_BASE)
+#define INT_7XX_MPUIO (39 + IH2_BASE)
+#define INT_7XX_LLPC_LCD_CTRL_CAN_BE_OFF (40 + IH2_BASE)
+#define INT_7XX_LLPC_OE_FALLING (41 + IH2_BASE)
+#define INT_7XX_LLPC_OE_RISING (42 + IH2_BASE)
+#define INT_7XX_LLPC_VSYNC (43 + IH2_BASE)
+#define INT_7XX_WAKE_UP_REQ (46 + IH2_BASE)
+#define INT_7XX_DMA_CH6 (53 + IH2_BASE)
+#define INT_7XX_DMA_CH7 (54 + IH2_BASE)
+#define INT_7XX_DMA_CH8 (55 + IH2_BASE)
+#define INT_7XX_DMA_CH9 (56 + IH2_BASE)
+#define INT_7XX_DMA_CH10 (57 + IH2_BASE)
+#define INT_7XX_DMA_CH11 (58 + IH2_BASE)
+#define INT_7XX_DMA_CH12 (59 + IH2_BASE)
+#define INT_7XX_DMA_CH13 (60 + IH2_BASE)
+#define INT_7XX_DMA_CH14 (61 + IH2_BASE)
+#define INT_7XX_DMA_CH15 (62 + IH2_BASE)
+#define INT_7XX_NAND (63 + IH2_BASE)
+
+#define INT_24XX_SYS_NIRQ 7
+#define INT_24XX_SDMA_IRQ0 12
+#define INT_24XX_SDMA_IRQ1 13
+#define INT_24XX_SDMA_IRQ2 14
+#define INT_24XX_SDMA_IRQ3 15
+#define INT_24XX_CAM_IRQ 24
+#define INT_24XX_DSS_IRQ 25
+#define INT_24XX_MAIL_U0_MPU 26
+#define INT_24XX_DSP_UMA 27
+#define INT_24XX_DSP_MMU 28
+#define INT_24XX_GPIO_BANK1 29
+#define INT_24XX_GPIO_BANK2 30
+#define INT_24XX_GPIO_BANK3 31
+#define INT_24XX_GPIO_BANK4 32
+#define INT_24XX_GPIO_BANK5 33
+#define INT_24XX_MAIL_U3_MPU 34
+#define INT_24XX_GPTIMER1 37
+#define INT_24XX_GPTIMER2 38
+#define INT_24XX_GPTIMER3 39
+#define INT_24XX_GPTIMER4 40
+#define INT_24XX_GPTIMER5 41
+#define INT_24XX_GPTIMER6 42
+#define INT_24XX_GPTIMER7 43
+#define INT_24XX_GPTIMER8 44
+#define INT_24XX_GPTIMER9 45
+#define INT_24XX_GPTIMER10 46
+#define INT_24XX_GPTIMER11 47
+#define INT_24XX_GPTIMER12 48
+#define INT_24XX_SHA1MD5 51
+#define INT_24XX_MCBSP4_IRQ_TX 54
+#define INT_24XX_MCBSP4_IRQ_RX 55
+#define INT_24XX_I2C1_IRQ 56
+#define INT_24XX_I2C2_IRQ 57
+#define INT_24XX_HDQ_IRQ 58
+#define INT_24XX_MCBSP1_IRQ_TX 59
+#define INT_24XX_MCBSP1_IRQ_RX 60
+#define INT_24XX_MCBSP2_IRQ_TX 62
+#define INT_24XX_MCBSP2_IRQ_RX 63
+#define INT_24XX_SPI1_IRQ 65
+#define INT_24XX_SPI2_IRQ 66
+#define INT_24XX_UART1_IRQ 72
+#define INT_24XX_UART2_IRQ 73
+#define INT_24XX_UART3_IRQ 74
+#define INT_24XX_USB_IRQ_GEN 75
+#define INT_24XX_USB_IRQ_NISO 76
+#define INT_24XX_USB_IRQ_ISO 77
+#define INT_24XX_USB_IRQ_HGEN 78
+#define INT_24XX_USB_IRQ_HSOF 79
+#define INT_24XX_USB_IRQ_OTG 80
+#define INT_24XX_MCBSP5_IRQ_TX 81
+#define INT_24XX_MCBSP5_IRQ_RX 82
+#define INT_24XX_MMC_IRQ 83
+#define INT_24XX_MMC2_IRQ 86
+#define INT_24XX_MCBSP3_IRQ_TX 89
+#define INT_24XX_MCBSP3_IRQ_RX 90
+#define INT_24XX_SPI3_IRQ 91
+
+#define INT_243X_MCBSP2_IRQ 16
+#define INT_243X_MCBSP3_IRQ 17
+#define INT_243X_MCBSP4_IRQ 18
+#define INT_243X_MCBSP5_IRQ 19
+#define INT_243X_MCBSP1_IRQ 64
+#define INT_243X_HS_USB_MC 92
+#define INT_243X_HS_USB_DMA 93
+#define INT_243X_CARKIT_IRQ 94
+
+#define INT_34XX_BENCH_MPU_EMUL 3
+#define INT_34XX_ST_MCBSP2_IRQ 4
+#define INT_34XX_ST_MCBSP3_IRQ 5
+#define INT_34XX_SSM_ABORT_IRQ 6
+#define INT_34XX_SYS_NIRQ 7
+#define INT_34XX_D2D_FW_IRQ 8
+#define INT_34XX_L3_DBG_IRQ 9
+#define INT_34XX_L3_APP_IRQ 10
+#define INT_34XX_PRCM_MPU_IRQ 11
+#define INT_34XX_MCBSP1_IRQ 16
+#define INT_34XX_MCBSP2_IRQ 17
+#define INT_34XX_GPMC_IRQ 20
+#define INT_34XX_MCBSP3_IRQ 22
+#define INT_34XX_MCBSP4_IRQ 23
+#define INT_34XX_CAM_IRQ 24
+#define INT_34XX_MCBSP5_IRQ 27
+#define INT_34XX_GPIO_BANK1 29
+#define INT_34XX_GPIO_BANK2 30
+#define INT_34XX_GPIO_BANK3 31
+#define INT_34XX_GPIO_BANK4 32
+#define INT_34XX_GPIO_BANK5 33
+#define INT_34XX_GPIO_BANK6 34
+#define INT_34XX_USIM_IRQ 35
+#define INT_34XX_WDT3_IRQ 36
+#define INT_34XX_SPI4_IRQ 48
+#define INT_34XX_SHA1MD52_IRQ 49
+#define INT_34XX_FPKA_READY_IRQ 50
+#define INT_34XX_SHA1MD51_IRQ 51
+#define INT_34XX_RNG_IRQ 52
+#define INT_34XX_I2C3_IRQ 61
+#define INT_34XX_FPKA_ERROR_IRQ 64
+#define INT_34XX_PBIAS_IRQ 75
+#define INT_34XX_OHCI_IRQ 76
+#define INT_34XX_EHCI_IRQ 77
+#define INT_34XX_TLL_IRQ 78
+#define INT_34XX_PARTHASH_IRQ 79
+#define INT_34XX_MMC3_IRQ 94
+#define INT_34XX_GPT12_IRQ 95
+
+#define INT_36XX_UART4_IRQ 80
+
+#define INT_35XX_HECC0_IRQ 24
+#define INT_35XX_HECC1_IRQ 28
+#define INT_35XX_EMAC_C0_RXTHRESH_IRQ 67
+#define INT_35XX_EMAC_C0_RX_PULSE_IRQ 68
+#define INT_35XX_EMAC_C0_TX_PULSE_IRQ 69
+#define INT_35XX_EMAC_C0_MISC_PULSE_IRQ 70
+#define INT_35XX_USBOTG_IRQ 71
+#define INT_35XX_CCDC_VD0_IRQ 88
+#define INT_35XX_CCDC_VD1_IRQ 92
+#define INT_35XX_CCDC_VD2_IRQ 93
+
+/* Max. 128 level 2 IRQs (OMAP1610), 192 GPIOs (OMAP730/850) and
+ * 16 MPUIO lines */
+#define OMAP_MAX_GPIO_LINES 192
+#define IH_GPIO_BASE (128 + IH2_BASE)
+#define IH_MPUIO_BASE (OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
+#define OMAP_IRQ_END (IH_MPUIO_BASE + 16)
+
+/* External FPGA handles interrupts on Innovator boards */
+#define OMAP_FPGA_IRQ_BASE (OMAP_IRQ_END)
+#ifdef CONFIG_MACH_OMAP_INNOVATOR
+#define OMAP_FPGA_NR_IRQS 24
+#else
+#define OMAP_FPGA_NR_IRQS 0
+#endif
+#define OMAP_FPGA_IRQ_END (OMAP_FPGA_IRQ_BASE + OMAP_FPGA_NR_IRQS)
+
+/* External TWL4030 can handle interrupts on 2430 and 34xx boards */
+#define TWL4030_IRQ_BASE (OMAP_FPGA_IRQ_END)
+#ifdef CONFIG_TWL4030_CORE
+#define TWL4030_BASE_NR_IRQS 8
+#define TWL4030_PWR_NR_IRQS 8
+#else
+#define TWL4030_BASE_NR_IRQS 0
+#define TWL4030_PWR_NR_IRQS 0
+#endif
+#define TWL4030_IRQ_END (TWL4030_IRQ_BASE + TWL4030_BASE_NR_IRQS)
+#define TWL4030_PWR_IRQ_BASE TWL4030_IRQ_END
+#define TWL4030_PWR_IRQ_END (TWL4030_PWR_IRQ_BASE + TWL4030_PWR_NR_IRQS)
+
+/* External TWL4030 gpio interrupts are optional */
+#define TWL4030_GPIO_IRQ_BASE TWL4030_PWR_IRQ_END
+#ifdef CONFIG_GPIO_TWL4030
+#define TWL4030_GPIO_NR_IRQS 18
+#else
+#define TWL4030_GPIO_NR_IRQS 0
+#endif
+#define TWL4030_GPIO_IRQ_END (TWL4030_GPIO_IRQ_BASE + TWL4030_GPIO_NR_IRQS)
+
+#define TWL6030_IRQ_BASE (OMAP_FPGA_IRQ_END)
+#ifdef CONFIG_TWL4030_CORE
+#define TWL6030_BASE_NR_IRQS 20
+#else
+#define TWL6030_BASE_NR_IRQS 0
+#endif
+#define TWL6030_IRQ_END (TWL6030_IRQ_BASE + TWL6030_BASE_NR_IRQS)
+
+/* Total number of interrupts depends on the enabled blocks above */
+#if (TWL4030_GPIO_IRQ_END > TWL6030_IRQ_END)
+#define TWL_IRQ_END TWL4030_GPIO_IRQ_END
+#else
+#define TWL_IRQ_END TWL6030_IRQ_END
+#endif
+
+/* GPMC related */
+#define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END)
+#define OMAP_GPMC_NR_IRQS 8
+#define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS)
+
+
+#define NR_IRQS OMAP_GPMC_IRQ_END
+
+#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
+
+#define INTCPS_NR_MIR_REGS 3
+#define INTCPS_NR_IRQS 96
+
+#ifndef __ASSEMBLY__
+extern void omap_init_irq(void);
+extern int omap_irq_pending(void);
+void omap_intc_save_context(void);
+void omap_intc_restore_context(void);
+void omap3_intc_suspend(void);
+void omap3_intc_prepare_idle(void);
+void omap3_intc_resume_idle(void);
+#endif
+
+#include <mach/hardware.h>
+
+#ifdef CONFIG_FIQ
+#define FIQ_START 1024
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/keypad.h b/arch/arm/plat-omap/include/plat/keypad.h
new file mode 100644
index 00000000..793ce9d5
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/keypad.h
@@ -0,0 +1,50 @@
+/*
+ * arch/arm/plat-omap/include/mach/keypad.h
+ *
+ * Copyright (C) 2006 Komal Shah <komal_shah802003@yahoo.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 ASMARM_ARCH_KEYPAD_H
+#define ASMARM_ARCH_KEYPAD_H
+
+#ifndef CONFIG_ARCH_OMAP1
+#warning Please update the board to use matrix-keypad driver
+#endif
+#include <linux/input/matrix_keypad.h>
+
+struct omap_kp_platform_data {
+ int rows;
+ int cols;
+ const struct matrix_keymap_data *keymap_data;
+ bool rep;
+ unsigned long delay;
+ bool dbounce;
+ /* specific to OMAP242x*/
+ unsigned int *row_gpios;
+ unsigned int *col_gpios;
+};
+
+/* Group (0..3) -- when multiple keys are pressed, only the
+ * keys pressed in the same group are considered as pressed. This is
+ * in order to workaround certain crappy HW designs that produce ghost
+ * keypresses. Two free bits, not used by neither row/col nor keynum,
+ * must be available for use as group bits. The below GROUP_SHIFT
+ * macro definition is based on some prior knowledge of the
+ * matrix_keypad defined KEY() macro internals.
+ */
+#define GROUP_SHIFT 14
+#define GROUP_0 (0 << GROUP_SHIFT)
+#define GROUP_1 (1 << GROUP_SHIFT)
+#define GROUP_2 (2 << GROUP_SHIFT)
+#define GROUP_3 (3 << GROUP_SHIFT)
+#define GROUP_MASK GROUP_3
+#if KEY_MAX & GROUP_MASK
+#error Group bits in conflict with keynum bits
+#endif
+
+
+#endif
+
diff --git a/arch/arm/plat-omap/include/plat/l3_2xxx.h b/arch/arm/plat-omap/include/plat/l3_2xxx.h
new file mode 100644
index 00000000..b8b56413
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l3_2xxx.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * 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 __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H
+
+/* L3 CONNIDs */
+/* Display Sub system (DSS) */
+#define OMAP2_L3_CORE_FW_CONNID_DSS 8
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l3_3xxx.h b/arch/arm/plat-omap/include/plat/l3_3xxx.h
new file mode 100644
index 00000000..cde1938c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l3_3xxx.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * 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 __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H
+
+/* L3 Initiator IDs */
+/* Display Sub system (DSS) */
+#define OMAP3_L3_CORE_FW_INIT_ID_DSS 29
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l4_2xxx.h b/arch/arm/plat-omap/include/plat/l4_2xxx.h
new file mode 100644
index 00000000..3f39cf8a
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l4_2xxx.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * 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 __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H
+
+/* L4 CORE */
+/* Display Sub system (DSS) */
+#define OMAP2420_L4_CORE_FW_DSS_CORE_REGION 28
+#define OMAP2420_L4_CORE_FW_DSS_DISPC_REGION 29
+#define OMAP2420_L4_CORE_FW_DSS_RFBI_REGION 30
+#define OMAP2420_L4_CORE_FW_DSS_VENC_REGION 31
+#define OMAP2420_L4_CORE_FW_DSS_TA_REGION 32
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h
new file mode 100644
index 00000000..881a858b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * 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 __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H
+
+/* L4 CORE */
+#define OMAP3_L4_CORE_FW_I2C1_REGION 21
+#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22
+#define OMAP3_L4_CORE_FW_I2C2_REGION 23
+#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24
+#define OMAP3_L4_CORE_FW_I2C3_REGION 73
+#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74
+
+/* Display Sub system (DSS) */
+#define OMAP3_L4_CORE_FW_DSS_PROT_GROUP 2
+
+#define OMAP3_L4_CORE_FW_DSS_DSI_REGION 104
+#define OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION 3
+#define OMAP3_L4_CORE_FW_DSS_CORE_REGION 4
+#define OMAP3_L4_CORE_FW_DSS_DISPC_REGION 4
+#define OMAP3_L4_CORE_FW_DSS_RFBI_REGION 5
+#define OMAP3_L4_CORE_FW_DSS_VENC_REGION 6
+#define OMAP3_L4_CORE_FW_DSS_TA_REGION 7
+#endif
diff --git a/arch/arm/plat-omap/include/plat/lcd_mipid.h b/arch/arm/plat-omap/include/plat/lcd_mipid.h
new file mode 100644
index 00000000..8e52c657
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/lcd_mipid.h
@@ -0,0 +1,29 @@
+#ifndef __LCD_MIPID_H
+#define __LCD_MIPID_H
+
+enum mipid_test_num {
+ MIPID_TEST_RGB_LINES,
+};
+
+enum mipid_test_result {
+ MIPID_TEST_SUCCESS,
+ MIPID_TEST_INVALID,
+ MIPID_TEST_FAILED,
+};
+
+#ifdef __KERNEL__
+
+struct mipid_platform_data {
+ int nreset_gpio;
+ int data_lines;
+
+ void (*shutdown)(struct mipid_platform_data *pdata);
+ void (*set_bklight_level)(struct mipid_platform_data *pdata,
+ int level);
+ int (*get_bklight_level)(struct mipid_platform_data *pdata);
+ int (*get_bklight_max)(struct mipid_platform_data *pdata);
+};
+
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/led.h b/arch/arm/plat-omap/include/plat/led.h
new file mode 100644
index 00000000..25e451e7
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/led.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-omap/include/mach/led.h
+ *
+ * Copyright (C) 2006 Samsung Electronics
+ * Kyungmin Park <kyungmin.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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASMARM_ARCH_LED_H
+#define ASMARM_ARCH_LED_H
+
+struct omap_led_config {
+ struct led_classdev cdev;
+ s16 gpio;
+};
+
+struct omap_led_platform_data {
+ s16 nr_leds;
+ struct omap_led_config *leds;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h
new file mode 100644
index 00000000..cc3921e9
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -0,0 +1,105 @@
+/* mailbox.h */
+
+#ifndef MAILBOX_H
+#define MAILBOX_H
+
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kfifo.h>
+
+typedef u32 mbox_msg_t;
+struct omap_mbox;
+
+typedef int __bitwise omap_mbox_irq_t;
+#define IRQ_TX ((__force omap_mbox_irq_t) 1)
+#define IRQ_RX ((__force omap_mbox_irq_t) 2)
+
+typedef int __bitwise omap_mbox_type_t;
+#define OMAP_MBOX_TYPE1 ((__force omap_mbox_type_t) 1)
+#define OMAP_MBOX_TYPE2 ((__force omap_mbox_type_t) 2)
+
+struct omap_mbox_ops {
+ omap_mbox_type_t type;
+ int (*startup)(struct omap_mbox *mbox);
+ void (*shutdown)(struct omap_mbox *mbox);
+ /* fifo */
+ mbox_msg_t (*fifo_read)(struct omap_mbox *mbox);
+ void (*fifo_write)(struct omap_mbox *mbox, mbox_msg_t msg);
+ int (*fifo_empty)(struct omap_mbox *mbox);
+ int (*fifo_full)(struct omap_mbox *mbox);
+ /* irq */
+ void (*enable_irq)(struct omap_mbox *mbox,
+ omap_mbox_irq_t irq);
+ void (*disable_irq)(struct omap_mbox *mbox,
+ omap_mbox_irq_t irq);
+ void (*ack_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+ int (*is_irq)(struct omap_mbox *mbox, omap_mbox_irq_t irq);
+ /* ctx */
+ void (*save_ctx)(struct omap_mbox *mbox);
+ void (*restore_ctx)(struct omap_mbox *mbox);
+};
+
+struct omap_mbox_queue {
+ spinlock_t lock;
+ struct kfifo fifo;
+ struct work_struct work;
+ struct tasklet_struct tasklet;
+ struct omap_mbox *mbox;
+ bool full;
+};
+
+struct omap_mbox {
+ char *name;
+ unsigned int irq;
+ struct omap_mbox_queue *txq, *rxq;
+ struct omap_mbox_ops *ops;
+ struct device *dev;
+ void *priv;
+ int use_count;
+ struct blocking_notifier_head notifier;
+};
+
+int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
+void omap_mbox_init_seq(struct omap_mbox *);
+
+struct omap_mbox *omap_mbox_get(const char *, struct notifier_block *nb);
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb);
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **);
+int omap_mbox_unregister(void);
+
+static inline void omap_mbox_save_ctx(struct omap_mbox *mbox)
+{
+ if (!mbox->ops->save_ctx) {
+ dev_err(mbox->dev, "%s:\tno save\n", __func__);
+ return;
+ }
+
+ mbox->ops->save_ctx(mbox);
+}
+
+static inline void omap_mbox_restore_ctx(struct omap_mbox *mbox)
+{
+ if (!mbox->ops->restore_ctx) {
+ dev_err(mbox->dev, "%s:\tno restore\n", __func__);
+ return;
+ }
+
+ mbox->ops->restore_ctx(mbox);
+}
+
+static inline void omap_mbox_enable_irq(struct omap_mbox *mbox,
+ omap_mbox_irq_t irq)
+{
+ mbox->ops->enable_irq(mbox, irq);
+}
+
+static inline void omap_mbox_disable_irq(struct omap_mbox *mbox,
+ omap_mbox_irq_t irq)
+{
+ mbox->ops->disable_irq(mbox, irq);
+}
+
+#endif /* MAILBOX_H */
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
new file mode 100644
index 00000000..f8f690ab
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -0,0 +1,545 @@
+/*
+ * arch/arm/plat-omap/include/mach/mcbsp.h
+ *
+ * Defines for Multi-Channel Buffered Serial Port
+ *
+ * Copyright (C) 2002 RidgeRun, Inc.
+ * Author: Steve Johnson
+ *
+ * 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 __ASM_ARCH_OMAP_MCBSP_H
+#define __ASM_ARCH_OMAP_MCBSP_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+#include <plat/clock.h>
+
+/* macro for building platform_device for McBSP ports */
+#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
+static struct platform_device omap_mcbsp##port_nr = { \
+ .name = "omap-mcbsp-dai", \
+ .id = OMAP_MCBSP##port_nr, \
+}
+
+#define MCBSP_CONFIG_TYPE2 0x2
+#define MCBSP_CONFIG_TYPE3 0x3
+#define MCBSP_CONFIG_TYPE4 0x4
+
+#define OMAP7XX_MCBSP1_BASE 0xfffb1000
+#define OMAP7XX_MCBSP2_BASE 0xfffb1800
+
+#define OMAP1510_MCBSP1_BASE 0xe1011800
+#define OMAP1510_MCBSP2_BASE 0xfffb1000
+#define OMAP1510_MCBSP3_BASE 0xe1017000
+
+#define OMAP1610_MCBSP1_BASE 0xe1011800
+#define OMAP1610_MCBSP2_BASE 0xfffb1000
+#define OMAP1610_MCBSP3_BASE 0xe1017000
+
+#ifdef CONFIG_ARCH_OMAP1
+
+#define OMAP_MCBSP_REG_DRR2 0x00
+#define OMAP_MCBSP_REG_DRR1 0x02
+#define OMAP_MCBSP_REG_DXR2 0x04
+#define OMAP_MCBSP_REG_DXR1 0x06
+#define OMAP_MCBSP_REG_DRR 0x02
+#define OMAP_MCBSP_REG_DXR 0x06
+#define OMAP_MCBSP_REG_SPCR2 0x08
+#define OMAP_MCBSP_REG_SPCR1 0x0a
+#define OMAP_MCBSP_REG_RCR2 0x0c
+#define OMAP_MCBSP_REG_RCR1 0x0e
+#define OMAP_MCBSP_REG_XCR2 0x10
+#define OMAP_MCBSP_REG_XCR1 0x12
+#define OMAP_MCBSP_REG_SRGR2 0x14
+#define OMAP_MCBSP_REG_SRGR1 0x16
+#define OMAP_MCBSP_REG_MCR2 0x18
+#define OMAP_MCBSP_REG_MCR1 0x1a
+#define OMAP_MCBSP_REG_RCERA 0x1c
+#define OMAP_MCBSP_REG_RCERB 0x1e
+#define OMAP_MCBSP_REG_XCERA 0x20
+#define OMAP_MCBSP_REG_XCERB 0x22
+#define OMAP_MCBSP_REG_PCR0 0x24
+#define OMAP_MCBSP_REG_RCERC 0x26
+#define OMAP_MCBSP_REG_RCERD 0x28
+#define OMAP_MCBSP_REG_XCERC 0x2A
+#define OMAP_MCBSP_REG_XCERD 0x2C
+#define OMAP_MCBSP_REG_RCERE 0x2E
+#define OMAP_MCBSP_REG_RCERF 0x30
+#define OMAP_MCBSP_REG_XCERE 0x32
+#define OMAP_MCBSP_REG_XCERF 0x34
+#define OMAP_MCBSP_REG_RCERG 0x36
+#define OMAP_MCBSP_REG_RCERH 0x38
+#define OMAP_MCBSP_REG_XCERG 0x3A
+#define OMAP_MCBSP_REG_XCERH 0x3C
+
+/* Dummy defines, these are not available on omap1 */
+#define OMAP_MCBSP_REG_XCCR 0x00
+#define OMAP_MCBSP_REG_RCCR 0x00
+
+#else
+
+#define OMAP_MCBSP_REG_DRR2 0x00
+#define OMAP_MCBSP_REG_DRR1 0x04
+#define OMAP_MCBSP_REG_DXR2 0x08
+#define OMAP_MCBSP_REG_DXR1 0x0C
+#define OMAP_MCBSP_REG_DRR 0x00
+#define OMAP_MCBSP_REG_DXR 0x08
+#define OMAP_MCBSP_REG_SPCR2 0x10
+#define OMAP_MCBSP_REG_SPCR1 0x14
+#define OMAP_MCBSP_REG_RCR2 0x18
+#define OMAP_MCBSP_REG_RCR1 0x1C
+#define OMAP_MCBSP_REG_XCR2 0x20
+#define OMAP_MCBSP_REG_XCR1 0x24
+#define OMAP_MCBSP_REG_SRGR2 0x28
+#define OMAP_MCBSP_REG_SRGR1 0x2C
+#define OMAP_MCBSP_REG_MCR2 0x30
+#define OMAP_MCBSP_REG_MCR1 0x34
+#define OMAP_MCBSP_REG_RCERA 0x38
+#define OMAP_MCBSP_REG_RCERB 0x3C
+#define OMAP_MCBSP_REG_XCERA 0x40
+#define OMAP_MCBSP_REG_XCERB 0x44
+#define OMAP_MCBSP_REG_PCR0 0x48
+#define OMAP_MCBSP_REG_RCERC 0x4C
+#define OMAP_MCBSP_REG_RCERD 0x50
+#define OMAP_MCBSP_REG_XCERC 0x54
+#define OMAP_MCBSP_REG_XCERD 0x58
+#define OMAP_MCBSP_REG_RCERE 0x5C
+#define OMAP_MCBSP_REG_RCERF 0x60
+#define OMAP_MCBSP_REG_XCERE 0x64
+#define OMAP_MCBSP_REG_XCERF 0x68
+#define OMAP_MCBSP_REG_RCERG 0x6C
+#define OMAP_MCBSP_REG_RCERH 0x70
+#define OMAP_MCBSP_REG_XCERG 0x74
+#define OMAP_MCBSP_REG_XCERH 0x78
+#define OMAP_MCBSP_REG_SYSCON 0x8C
+#define OMAP_MCBSP_REG_THRSH2 0x90
+#define OMAP_MCBSP_REG_THRSH1 0x94
+#define OMAP_MCBSP_REG_IRQST 0xA0
+#define OMAP_MCBSP_REG_IRQEN 0xA4
+#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
+#define OMAP_MCBSP_REG_XCCR 0xAC
+#define OMAP_MCBSP_REG_RCCR 0xB0
+#define OMAP_MCBSP_REG_XBUFFSTAT 0xB4
+#define OMAP_MCBSP_REG_RBUFFSTAT 0xB8
+#define OMAP_MCBSP_REG_SSELCR 0xBC
+
+#define OMAP_ST_REG_REV 0x00
+#define OMAP_ST_REG_SYSCONFIG 0x10
+#define OMAP_ST_REG_IRQSTATUS 0x18
+#define OMAP_ST_REG_IRQENABLE 0x1C
+#define OMAP_ST_REG_SGAINCR 0x24
+#define OMAP_ST_REG_SFIRCR 0x28
+#define OMAP_ST_REG_SSELCR 0x2C
+
+#endif
+
+/************************** McBSP SPCR1 bit definitions ***********************/
+#define RRST 0x0001
+#define RRDY 0x0002
+#define RFULL 0x0004
+#define RSYNC_ERR 0x0008
+#define RINTM(value) ((value)<<4) /* bits 4:5 */
+#define ABIS 0x0040
+#define DXENA 0x0080
+#define CLKSTP(value) ((value)<<11) /* bits 11:12 */
+#define RJUST(value) ((value)<<13) /* bits 13:14 */
+#define ALB 0x8000
+#define DLB 0x8000
+
+/************************** McBSP SPCR2 bit definitions ***********************/
+#define XRST 0x0001
+#define XRDY 0x0002
+#define XEMPTY 0x0004
+#define XSYNC_ERR 0x0008
+#define XINTM(value) ((value)<<4) /* bits 4:5 */
+#define GRST 0x0040
+#define FRST 0x0080
+#define SOFT 0x0100
+#define FREE 0x0200
+
+/************************** McBSP PCR bit definitions *************************/
+#define CLKRP 0x0001
+#define CLKXP 0x0002
+#define FSRP 0x0004
+#define FSXP 0x0008
+#define DR_STAT 0x0010
+#define DX_STAT 0x0020
+#define CLKS_STAT 0x0040
+#define SCLKME 0x0080
+#define CLKRM 0x0100
+#define CLKXM 0x0200
+#define FSRM 0x0400
+#define FSXM 0x0800
+#define RIOEN 0x1000
+#define XIOEN 0x2000
+#define IDLE_EN 0x4000
+
+/************************** McBSP RCR1 bit definitions ************************/
+#define RWDLEN1(value) ((value)<<5) /* Bits 5:7 */
+#define RFRLEN1(value) ((value)<<8) /* Bits 8:14 */
+
+/************************** McBSP XCR1 bit definitions ************************/
+#define XWDLEN1(value) ((value)<<5) /* Bits 5:7 */
+#define XFRLEN1(value) ((value)<<8) /* Bits 8:14 */
+
+/*************************** McBSP RCR2 bit definitions ***********************/
+#define RDATDLY(value) (value) /* Bits 0:1 */
+#define RFIG 0x0004
+#define RCOMPAND(value) ((value)<<3) /* Bits 3:4 */
+#define RWDLEN2(value) ((value)<<5) /* Bits 5:7 */
+#define RFRLEN2(value) ((value)<<8) /* Bits 8:14 */
+#define RPHASE 0x8000
+
+/*************************** McBSP XCR2 bit definitions ***********************/
+#define XDATDLY(value) (value) /* Bits 0:1 */
+#define XFIG 0x0004
+#define XCOMPAND(value) ((value)<<3) /* Bits 3:4 */
+#define XWDLEN2(value) ((value)<<5) /* Bits 5:7 */
+#define XFRLEN2(value) ((value)<<8) /* Bits 8:14 */
+#define XPHASE 0x8000
+
+/************************* McBSP SRGR1 bit definitions ************************/
+#define CLKGDV(value) (value) /* Bits 0:7 */
+#define FWID(value) ((value)<<8) /* Bits 8:15 */
+
+/************************* McBSP SRGR2 bit definitions ************************/
+#define FPER(value) (value) /* Bits 0:11 */
+#define FSGM 0x1000
+#define CLKSM 0x2000
+#define CLKSP 0x4000
+#define GSYNC 0x8000
+
+/************************* McBSP MCR1 bit definitions *************************/
+#define RMCM 0x0001
+#define RCBLK(value) ((value)<<2) /* Bits 2:4 */
+#define RPABLK(value) ((value)<<5) /* Bits 5:6 */
+#define RPBBLK(value) ((value)<<7) /* Bits 7:8 */
+
+/************************* McBSP MCR2 bit definitions *************************/
+#define XMCM(value) (value) /* Bits 0:1 */
+#define XCBLK(value) ((value)<<2) /* Bits 2:4 */
+#define XPABLK(value) ((value)<<5) /* Bits 5:6 */
+#define XPBBLK(value) ((value)<<7) /* Bits 7:8 */
+
+/*********************** McBSP XCCR bit definitions *************************/
+#define EXTCLKGATE 0x8000
+#define PPCONNECT 0x4000
+#define DXENDLY(value) ((value)<<12) /* Bits 12:13 */
+#define XFULL_CYCLE 0x0800
+#define DILB 0x0020
+#define XDMAEN 0x0008
+#define XDISABLE 0x0001
+
+/********************** McBSP RCCR bit definitions *************************/
+#define RFULL_CYCLE 0x0800
+#define RDMAEN 0x0008
+#define RDISABLE 0x0001
+
+/********************** McBSP SYSCONFIG bit definitions ********************/
+#define CLOCKACTIVITY(value) ((value)<<8)
+#define SIDLEMODE(value) ((value)<<3)
+#define ENAWAKEUP 0x0004
+#define SOFTRST 0x0002
+
+/********************** McBSP SSELCR bit definitions ***********************/
+#define SIDETONEEN 0x0400
+
+/********************** McBSP Sidetone SYSCONFIG bit definitions ***********/
+#define ST_AUTOIDLE 0x0001
+
+/********************** McBSP Sidetone SGAINCR bit definitions *************/
+#define ST_CH1GAIN(value) ((value<<16)) /* Bits 16:31 */
+#define ST_CH0GAIN(value) (value) /* Bits 0:15 */
+
+/********************** McBSP Sidetone SFIRCR bit definitions **************/
+#define ST_FIRCOEFF(value) (value) /* Bits 0:15 */
+
+/********************** McBSP Sidetone SSELCR bit definitions **************/
+#define ST_COEFFWRDONE 0x0004
+#define ST_COEFFWREN 0x0002
+#define ST_SIDETONEEN 0x0001
+
+/********************** McBSP DMA operating modes **************************/
+#define MCBSP_DMA_MODE_ELEMENT 0
+#define MCBSP_DMA_MODE_THRESHOLD 1
+#define MCBSP_DMA_MODE_FRAME 2
+
+/********************** McBSP WAKEUPEN bit definitions *********************/
+#define XEMPTYEOFEN 0x4000
+#define XRDYEN 0x0400
+#define XEOFEN 0x0200
+#define XFSXEN 0x0100
+#define XSYNCERREN 0x0080
+#define RRDYEN 0x0008
+#define REOFEN 0x0004
+#define RFSREN 0x0002
+#define RSYNCERREN 0x0001
+
+/* CLKR signal muxing options */
+#define CLKR_SRC_CLKR 0
+#define CLKR_SRC_CLKX 1
+
+/* FSR signal muxing options */
+#define FSR_SRC_FSR 0
+#define FSR_SRC_FSX 1
+
+/* McBSP functional clock sources */
+#define MCBSP_CLKS_PRCM_SRC 0
+#define MCBSP_CLKS_PAD_SRC 1
+
+/* we don't do multichannel for now */
+struct omap_mcbsp_reg_cfg {
+ u16 spcr2;
+ u16 spcr1;
+ u16 rcr2;
+ u16 rcr1;
+ u16 xcr2;
+ u16 xcr1;
+ u16 srgr2;
+ u16 srgr1;
+ u16 mcr2;
+ u16 mcr1;
+ u16 pcr0;
+ u16 rcerc;
+ u16 rcerd;
+ u16 xcerc;
+ u16 xcerd;
+ u16 rcere;
+ u16 rcerf;
+ u16 xcere;
+ u16 xcerf;
+ u16 rcerg;
+ u16 rcerh;
+ u16 xcerg;
+ u16 xcerh;
+ u16 xccr;
+ u16 rccr;
+};
+
+typedef enum {
+ OMAP_MCBSP1 = 0,
+ OMAP_MCBSP2,
+ OMAP_MCBSP3,
+ OMAP_MCBSP4,
+ OMAP_MCBSP5
+} omap_mcbsp_id;
+
+typedef int __bitwise omap_mcbsp_io_type_t;
+#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
+#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
+
+typedef enum {
+ OMAP_MCBSP_WORD_8 = 0,
+ OMAP_MCBSP_WORD_12,
+ OMAP_MCBSP_WORD_16,
+ OMAP_MCBSP_WORD_20,
+ OMAP_MCBSP_WORD_24,
+ OMAP_MCBSP_WORD_32,
+} omap_mcbsp_word_length;
+
+typedef enum {
+ OMAP_MCBSP_CLK_RISING = 0,
+ OMAP_MCBSP_CLK_FALLING,
+} omap_mcbsp_clk_polarity;
+
+typedef enum {
+ OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
+ OMAP_MCBSP_FS_ACTIVE_LOW,
+} omap_mcbsp_fs_polarity;
+
+typedef enum {
+ OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
+ OMAP_MCBSP_CLK_STP_MODE_DELAY,
+} omap_mcbsp_clk_stp_mode;
+
+
+/******* SPI specific mode **********/
+typedef enum {
+ OMAP_MCBSP_SPI_MASTER = 0,
+ OMAP_MCBSP_SPI_SLAVE,
+} omap_mcbsp_spi_mode;
+
+struct omap_mcbsp_spi_cfg {
+ omap_mcbsp_spi_mode spi_mode;
+ omap_mcbsp_clk_polarity rx_clock_polarity;
+ omap_mcbsp_clk_polarity tx_clock_polarity;
+ omap_mcbsp_fs_polarity fsx_polarity;
+ u8 clk_div;
+ omap_mcbsp_clk_stp_mode clk_stp_mode;
+ omap_mcbsp_word_length word_length;
+};
+
+/* Platform specific configuration */
+struct omap_mcbsp_ops {
+ void (*request)(unsigned int);
+ void (*free)(unsigned int);
+ int (*set_clks_src)(u8, u8);
+};
+
+struct omap_mcbsp_platform_data {
+ unsigned long phys_base;
+ u8 dma_rx_sync, dma_tx_sync;
+ u16 rx_irq, tx_irq;
+ struct omap_mcbsp_ops *ops;
+#ifdef CONFIG_ARCH_OMAP3
+ /* Sidetone block for McBSP 2 and 3 */
+ unsigned long phys_base_st;
+#endif
+ u16 buffer_size;
+ unsigned int mcbsp_config_type;
+};
+
+struct omap_mcbsp_st_data {
+ void __iomem *io_base_st;
+ bool running;
+ bool enabled;
+ s16 taps[128]; /* Sidetone filter coefficients */
+ int nr_taps; /* Number of filter coefficients in use */
+ s16 ch0gain;
+ s16 ch1gain;
+};
+
+struct omap_mcbsp {
+ struct device *dev;
+ unsigned long phys_base;
+ unsigned long phys_dma_base;
+ void __iomem *io_base;
+ u8 id;
+ u8 free;
+ omap_mcbsp_word_length rx_word_length;
+ omap_mcbsp_word_length tx_word_length;
+
+ omap_mcbsp_io_type_t io_type; /* IRQ or poll */
+ /* IRQ based TX/RX */
+ int rx_irq;
+ int tx_irq;
+
+ /* DMA stuff */
+ u8 dma_rx_sync;
+ short dma_rx_lch;
+ u8 dma_tx_sync;
+ short dma_tx_lch;
+
+ /* Completion queues */
+ struct completion tx_irq_completion;
+ struct completion rx_irq_completion;
+ struct completion tx_dma_completion;
+ struct completion rx_dma_completion;
+
+ /* Protect the field .free, while checking if the mcbsp is in use */
+ spinlock_t lock;
+ struct omap_mcbsp_platform_data *pdata;
+ struct clk *fclk;
+#ifdef CONFIG_ARCH_OMAP3
+ struct omap_mcbsp_st_data *st_data;
+ int dma_op_mode;
+ u16 max_tx_thres;
+ u16 max_rx_thres;
+#endif
+ void *reg_cache;
+ unsigned int mcbsp_config_type;
+};
+
+/**
+ * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod
+ * @sidetone: name of the sidetone device
+ */
+struct omap_mcbsp_dev_attr {
+ const char *sidetone;
+};
+
+extern struct omap_mcbsp **mcbsp_ptr;
+extern int omap_mcbsp_count, omap_mcbsp_cache_size;
+
+#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
+#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
+
+int omap_mcbsp_init(void);
+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
+ struct omap_mcbsp_platform_data *config, int size);
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
+#ifdef CONFIG_ARCH_OMAP3
+void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
+void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
+u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
+u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
+u16 omap_mcbsp_get_fifo_size(unsigned int id);
+u16 omap_mcbsp_get_tx_delay(unsigned int id);
+u16 omap_mcbsp_get_rx_delay(unsigned int id);
+int omap_mcbsp_get_dma_op_mode(unsigned int id);
+#else
+static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
+{ }
+static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
+{ }
+static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
+static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
+static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; }
+static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; }
+static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; }
+static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
+#endif
+int omap_mcbsp_request(unsigned int id);
+void omap_mcbsp_free(unsigned int id);
+void omap_mcbsp_start(unsigned int id, int tx, int rx);
+void omap_mcbsp_stop(unsigned int id, int tx, int rx);
+void omap_mcbsp_xmit_word(unsigned int id, u32 word);
+u32 omap_mcbsp_recv_word(unsigned int id);
+
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length);
+int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
+
+
+/* McBSP functional clock source changing function */
+extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
+/* SPI specific API */
+void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
+
+/* Polled read/write functions */
+int omap_mcbsp_pollread(unsigned int id, u16 * buf);
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
+
+/* McBSP signal muxing API */
+void omap2_mcbsp1_mux_clkr_src(u8 mux);
+void omap2_mcbsp1_mux_fsr_src(u8 mux);
+
+int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream);
+int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream);
+
+#ifdef CONFIG_ARCH_OMAP3
+/* Sidetone specific API */
+int omap_st_set_chgain(unsigned int id, int channel, s16 chgain);
+int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain);
+int omap_st_enable(unsigned int id);
+int omap_st_disable(unsigned int id);
+int omap_st_is_enabled(unsigned int id);
+#else
+static inline int omap_st_set_chgain(unsigned int id, int channel,
+ s16 chgain) { return 0; }
+static inline int omap_st_get_chgain(unsigned int id, int channel,
+ s16 *chgain) { return 0; }
+static inline int omap_st_enable(unsigned int id) { return 0; }
+static inline int omap_st_disable(unsigned int id) { return 0; }
+static inline int omap_st_is_enabled(unsigned int id) { return 0; }
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mcspi.h b/arch/arm/plat-omap/include/plat/mcspi.h
new file mode 100644
index 00000000..3d51b181
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mcspi.h
@@ -0,0 +1,26 @@
+#ifndef _OMAP2_MCSPI_H
+#define _OMAP2_MCSPI_H
+
+#define OMAP2_MCSPI_REV 0
+#define OMAP3_MCSPI_REV 1
+#define OMAP4_MCSPI_REV 2
+
+#define OMAP4_MCSPI_REG_OFFSET 0x100
+
+struct omap2_mcspi_platform_config {
+ unsigned short num_cs;
+ unsigned int regs_offset;
+};
+
+struct omap2_mcspi_dev_attr {
+ unsigned short num_chipselect;
+};
+
+struct omap2_mcspi_device_config {
+ unsigned turbo_mode:1;
+
+ /* Do we want one channel enabled at the same time? */
+ unsigned single_channel:1;
+};
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h
new file mode 100644
index 00000000..e6720aa2
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/memory.h
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/plat-omap/include/mach/memory.h
+ *
+ * Memory map for OMAP-1510 and 1610
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * This file was derived from arch/arm/mach-intergrator/include/mach/memory.h
+ * Copyright (C) 1999 ARM Limited
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#if defined(CONFIG_ARCH_OMAP1)
+#define PLAT_PHYS_OFFSET UL(0x10000000)
+#else
+#define PLAT_PHYS_OFFSET UL(0x80000000)
+#endif
+
+/*
+ * Bus address is physical address, except for OMAP-1510 Local Bus.
+ * OMAP-1510 bus address is translated into a Local Bus address if the
+ * OMAP bus type is lbus. We do the address translation based on the
+ * device overriding the defaults used in the dma-mapping API.
+ * Note that the is_lbus_device() test is not very efficient on 1510
+ * because of the strncmp().
+ */
+#ifdef CONFIG_ARCH_OMAP15XX
+
+/*
+ * OMAP-1510 Local Bus address offset
+ */
+#define OMAP1510_LB_OFFSET UL(0x30000000)
+
+#define virt_to_lbus(x) ((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET)
+#define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET)
+#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev_name(dev), "ohci", 4) == 0))
+
+#define __arch_pfn_to_dma(dev, pfn) \
+ ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
+ if (is_lbus_device(dev)) \
+ __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
+ __dma; })
+
+#define __arch_dma_to_pfn(dev, addr) \
+ ({ dma_addr_t __dma = addr; \
+ if (is_lbus_device(dev)) \
+ __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \
+ __phys_to_pfn(__dma); \
+ })
+
+#define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \
+ lbus_to_virt(addr) : \
+ __phys_to_virt(addr)); })
+
+#define __arch_virt_to_dma(dev, addr) ({ unsigned long __addr = (unsigned long)(addr); \
+ (dma_addr_t) (is_lbus_device(dev) ? \
+ virt_to_lbus(__addr) : \
+ __virt_to_phys(__addr)); })
+
+#endif /* CONFIG_ARCH_OMAP15XX */
+
+/* Override the ARM default */
+#ifdef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
+
+#if (CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE == 0)
+#undef CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE
+#define CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE 2
+#endif
+
+#define CONSISTENT_DMA_SIZE \
+ (((CONFIG_FB_OMAP_CONSISTENT_DMA_SIZE + 1) & ~1) * 1024 * 1024)
+
+#endif
+
+#endif
+
diff --git a/arch/arm/plat-omap/include/plat/menelaus.h b/arch/arm/plat-omap/include/plat/menelaus.h
new file mode 100644
index 00000000..4a970ec6
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/menelaus.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/plat-omap/include/mach/menelaus.h
+ *
+ * Functions to access Menelaus power management chip
+ */
+
+#ifndef __ASM_ARCH_MENELAUS_H
+#define __ASM_ARCH_MENELAUS_H
+
+struct device;
+
+struct menelaus_platform_data {
+ int (* late_init)(struct device *dev);
+};
+
+extern int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
+ void *data);
+extern void menelaus_unregister_mmc_callback(void);
+extern int menelaus_set_mmc_opendrain(int slot, int enable);
+extern int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_on);
+
+extern int menelaus_set_vmem(unsigned int mV);
+extern int menelaus_set_vio(unsigned int mV);
+extern int menelaus_set_vmmc(unsigned int mV);
+extern int menelaus_set_vaux(unsigned int mV);
+extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
+extern int menelaus_set_slot_sel(int enable);
+extern int menelaus_get_slot_pin_states(void);
+extern int menelaus_set_vcore_sw(unsigned int mV);
+extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
+
+#define EN_VPLL_SLEEP (1 << 7)
+#define EN_VMMC_SLEEP (1 << 6)
+#define EN_VAUX_SLEEP (1 << 5)
+#define EN_VIO_SLEEP (1 << 4)
+#define EN_VMEM_SLEEP (1 << 3)
+#define EN_DC3_SLEEP (1 << 2)
+#define EN_DC2_SLEEP (1 << 1)
+#define EN_VC_SLEEP (1 << 0)
+
+extern int menelaus_set_regulator_sleep(int enable, u32 val);
+
+#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_MENELAUS)
+#define omap_has_menelaus() 1
+#else
+#define omap_has_menelaus() 0
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
new file mode 100644
index 00000000..c7b87418
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -0,0 +1,182 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __OMAP2_MMC_H
+#define __OMAP2_MMC_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mmc/host.h>
+
+#include <plat/board.h>
+
+#define OMAP15XX_NR_MMC 1
+#define OMAP16XX_NR_MMC 2
+#define OMAP1_MMC_SIZE 0x080
+#define OMAP1_MMC1_BASE 0xfffb7800
+#define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */
+
+#define OMAP24XX_NR_MMC 2
+#define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE
+#define OMAP2_MMC1_BASE 0x4809c000
+
+#define OMAP4_MMC_REG_OFFSET 0x100
+
+#define OMAP_MMC_MAX_SLOTS 2
+
+#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(1)
+
+struct omap_mmc_dev_attr {
+ u8 flags;
+};
+
+struct omap_mmc_platform_data {
+ /* back-link to device */
+ struct device *dev;
+
+ /* number of slots per controller */
+ unsigned nr_slots:2;
+
+ /* set if your board has components or wiring that limits the
+ * maximum frequency on the MMC bus */
+ unsigned int max_freq;
+
+ /* switch the bus to a new slot */
+ int (*switch_slot)(struct device *dev, int slot);
+ /* initialize board-specific MMC functionality, can be NULL if
+ * not supported */
+ int (*init)(struct device *dev);
+ void (*cleanup)(struct device *dev);
+ void (*shutdown)(struct device *dev);
+
+ /* To handle board related suspend/resume functionality for MMC */
+ int (*suspend)(struct device *dev, int slot);
+ int (*resume)(struct device *dev, int slot);
+
+ /* Return context loss count due to PM states changing */
+ int (*get_context_loss_count)(struct device *dev);
+
+ u64 dma_mask;
+
+ /* Integrating attributes from the omap_hwmod layer */
+ u8 controller_flags;
+
+ /* Register offset deviation */
+ u16 reg_offset;
+
+ struct omap_mmc_slot_data {
+
+ /*
+ * 4/8 wires and any additional host capabilities
+ * need to OR'd all capabilities (ref. linux/mmc/host.h)
+ */
+ u8 wires; /* Used for the MMC driver on omap1 and 2420 */
+ u32 caps; /* Used for the MMC driver on 2430 and later */
+
+ /*
+ * nomux means "standard" muxing is wrong on this board, and
+ * that board-specific code handled it before common init logic.
+ */
+ unsigned nomux:1;
+
+ /* switch pin can be for card detect (default) or card cover */
+ unsigned cover:1;
+
+ /* use the internal clock */
+ unsigned internal_clock:1;
+
+ /* nonremovable e.g. eMMC */
+ unsigned nonremovable:1;
+
+ /* Try to sleep or power off when possible */
+ unsigned power_saving:1;
+
+ /* If using power_saving and the MMC power is not to go off */
+ unsigned no_off:1;
+
+ /* eMMC does not handle power off when not in sleep state */
+ unsigned no_regulator_off_init:1;
+
+ /* Regulator off remapped to sleep */
+ unsigned vcc_aux_disable_is_sleep:1;
+
+ /* we can put the features above into this variable */
+#define HSMMC_HAS_PBIAS (1 << 0)
+#define HSMMC_HAS_UPDATED_RESET (1 << 1)
+ unsigned features;
+
+ int switch_pin; /* gpio (card detect) */
+ int gpio_wp; /* gpio (write protect) */
+
+ int (*set_bus_mode)(struct device *dev, int slot, int bus_mode);
+ int (*set_power)(struct device *dev, int slot,
+ int power_on, int vdd);
+ int (*get_ro)(struct device *dev, int slot);
+ int (*set_sleep)(struct device *dev, int slot, int sleep,
+ int vdd, int cardsleep);
+ void (*remux)(struct device *dev, int slot, int power_on);
+ /* Call back before enabling / disabling regulators */
+ void (*before_set_reg)(struct device *dev, int slot,
+ int power_on, int vdd);
+ /* Call back after enabling / disabling regulators */
+ void (*after_set_reg)(struct device *dev, int slot,
+ int power_on, int vdd);
+ /* if we have special card, init it using this callback */
+ void (*init_card)(struct mmc_card *card);
+
+ /* return MMC cover switch state, can be NULL if not supported.
+ *
+ * possible return values:
+ * 0 - closed
+ * 1 - open
+ */
+ int (*get_cover_state)(struct device *dev, int slot);
+
+ const char *name;
+ u32 ocr_mask;
+
+ /* Card detection IRQs */
+ int card_detect_irq;
+ int (*card_detect)(struct device *dev, int slot);
+
+ unsigned int ban_openended:1;
+
+ } slots[OMAP_MMC_MAX_SLOTS];
+};
+
+/* called from board-specific card detection service routine */
+extern void omap_mmc_notify_cover_event(struct device *dev, int slot,
+ int is_closed);
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+ defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers);
+void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data);
+int omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ struct omap_mmc_platform_data *data);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+ int nr_controllers)
+{
+}
+static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)
+{
+}
+static inline int omap_mmc_add(const char *name, int id, unsigned long base,
+ unsigned long size, unsigned int irq,
+ struct omap_mmc_platform_data *data)
+{
+ return 0;
+}
+
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/multi.h b/arch/arm/plat-omap/include/plat/multi.h
new file mode 100644
index 00000000..999ffba2
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/multi.h
@@ -0,0 +1,102 @@
+/*
+ * Support for compiling in multiple OMAP processors
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __PLAT_OMAP_MULTI_H
+#define __PLAT_OMAP_MULTI_H
+
+/*
+ * Test if multicore OMAP support is needed
+ */
+#undef MULTI_OMAP1
+#undef MULTI_OMAP2
+#undef OMAP_NAME
+
+#ifdef CONFIG_ARCH_OMAP730
+# ifdef OMAP_NAME
+# undef MULTI_OMAP1
+# define MULTI_OMAP1
+# else
+# define OMAP_NAME omap730
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP850
+# ifdef OMAP_NAME
+# undef MULTI_OMAP1
+# define MULTI_OMAP1
+# else
+# define OMAP_NAME omap850
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+# ifdef OMAP_NAME
+# undef MULTI_OMAP1
+# define MULTI_OMAP1
+# else
+# define OMAP_NAME omap1510
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+# ifdef OMAP_NAME
+# undef MULTI_OMAP1
+# define MULTI_OMAP1
+# else
+# define OMAP_NAME omap16xx
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP2PLUS
+# if (defined(OMAP_NAME) || defined(MULTI_OMAP1))
+# error "OMAP1 and OMAP2PLUS can't be selected at the same time"
+# endif
+#endif
+#ifdef CONFIG_SOC_OMAP2420
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME omap2420
+# endif
+#endif
+#ifdef CONFIG_SOC_OMAP2430
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME omap2430
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME omap3
+# endif
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+# ifdef OMAP_NAME
+# undef MULTI_OMAP2
+# define MULTI_OMAP2
+# else
+# define OMAP_NAME omap4
+# endif
+#endif
+
+#endif /* __PLAT_OMAP_MULTI_H */
diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h
new file mode 100644
index 00000000..aeba7179
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/mux.h
@@ -0,0 +1,454 @@
+/*
+ * arch/arm/plat-omap/include/mach/mux.h
+ *
+ * Table of the Omap register configurations for the FUNC_MUX and
+ * PULL_DWN combinations.
+ *
+ * Copyright (C) 2004 - 2008 Texas Instruments Inc.
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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
+ *
+ * NOTE: Please use the following naming style for new pin entries.
+ * For example, W8_1610_MMC2_DAT0, where:
+ * - W8 = ball
+ * - 1610 = 1510 or 1610, none if common for both 1510 and 1610
+ * - MMC2_DAT0 = function
+ */
+
+#ifndef __ASM_ARCH_MUX_H
+#define __ASM_ARCH_MUX_H
+
+#define PU_PD_SEL_NA 0 /* No pu_pd reg available */
+#define PULL_DWN_CTRL_NA 0 /* No pull-down control needed */
+
+#ifdef CONFIG_OMAP_MUX_DEBUG
+#define MUX_REG(reg, mode_offset, mode) .mux_reg_name = "FUNC_MUX_CTRL_"#reg, \
+ .mux_reg = FUNC_MUX_CTRL_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG(reg, bit, status) .pull_name = "PULL_DWN_CTRL_"#reg, \
+ .pull_reg = PULL_DWN_CTRL_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
+#define PU_PD_REG(reg, status) .pu_pd_name = "PU_PD_SEL_"#reg, \
+ .pu_pd_reg = PU_PD_SEL_##reg, \
+ .pu_pd_val = status,
+
+#define MUX_REG_7XX(reg, mode_offset, mode) .mux_reg_name = "OMAP7XX_IO_CONF_"#reg, \
+ .mux_reg = OMAP7XX_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_7XX(reg, bit, status) .pull_name = "OMAP7XX_IO_CONF_"#reg, \
+ .pull_reg = OMAP7XX_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
+#else
+
+#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG(reg, bit, status) .pull_reg = PULL_DWN_CTRL_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
+#define PU_PD_REG(reg, status) .pu_pd_reg = PU_PD_SEL_##reg, \
+ .pu_pd_val = status,
+
+#define MUX_REG_7XX(reg, mode_offset, mode) \
+ .mux_reg = OMAP7XX_IO_CONF_##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode,
+
+#define PULL_REG_7XX(reg, bit, status) .pull_reg = OMAP7XX_IO_CONF_##reg, \
+ .pull_bit = bit, \
+ .pull_val = status,
+
+#endif /* CONFIG_OMAP_MUX_DEBUG */
+
+#define MUX_CFG(desc, mux_reg, mode_offset, mode, \
+ pull_reg, pull_bit, pull_status, \
+ pu_pd_reg, pu_pd_status, debug_status) \
+{ \
+ .name = desc, \
+ .debug = debug_status, \
+ MUX_REG(mux_reg, mode_offset, mode) \
+ PULL_REG(pull_reg, pull_bit, pull_status) \
+ PU_PD_REG(pu_pd_reg, pu_pd_status) \
+},
+
+
+/*
+ * OMAP730/850 has a slightly different config for the pin mux.
+ * - config regs are the OMAP7XX_IO_CONF_x regs (see omap730.h) regs and
+ * not the FUNC_MUX_CTRL_x regs from hardware.h
+ * - for pull-up/down, only has one enable bit which is is in the same register
+ * as mux config
+ */
+#define MUX_CFG_7XX(desc, mux_reg, mode_offset, mode, \
+ pull_bit, pull_status, debug_status)\
+{ \
+ .name = desc, \
+ .debug = debug_status, \
+ MUX_REG_7XX(mux_reg, mode_offset, mode) \
+ PULL_REG_7XX(mux_reg, pull_bit, pull_status) \
+ PU_PD_REG(NA, 0) \
+},
+
+struct pin_config {
+ char *name;
+ const unsigned int mux_reg;
+ unsigned char debug;
+
+ const unsigned char mask_offset;
+ const unsigned char mask;
+
+ const char *pull_name;
+ const unsigned int pull_reg;
+ const unsigned char pull_val;
+ const unsigned char pull_bit;
+
+ const char *pu_pd_name;
+ const unsigned int pu_pd_reg;
+ const unsigned char pu_pd_val;
+
+#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
+ const char *mux_reg_name;
+#endif
+
+};
+
+enum omap7xx_index {
+ /* OMAP 730 keyboard */
+ E2_7XX_KBR0,
+ J7_7XX_KBR1,
+ E1_7XX_KBR2,
+ F3_7XX_KBR3,
+ D2_7XX_KBR4,
+ C2_7XX_KBC0,
+ D3_7XX_KBC1,
+ E4_7XX_KBC2,
+ F4_7XX_KBC3,
+ E3_7XX_KBC4,
+
+ /* USB */
+ AA17_7XX_USB_DM,
+ W16_7XX_USB_PU_EN,
+ W17_7XX_USB_VBUSI,
+ W18_7XX_USB_DMCK_OUT,
+ W19_7XX_USB_DCRST,
+
+ /* MMC */
+ MMC_7XX_CMD,
+ MMC_7XX_CLK,
+ MMC_7XX_DAT0,
+
+ /* I2C */
+ I2C_7XX_SCL,
+ I2C_7XX_SDA,
+
+ /* SPI */
+ SPI_7XX_1,
+ SPI_7XX_2,
+ SPI_7XX_3,
+ SPI_7XX_4,
+ SPI_7XX_5,
+ SPI_7XX_6,
+
+ /* UART */
+ UART_7XX_1,
+ UART_7XX_2,
+};
+
+enum omap1xxx_index {
+ /* UART1 (BT_UART_GATING)*/
+ UART1_TX = 0,
+ UART1_RTS,
+
+ /* UART2 (COM_UART_GATING)*/
+ UART2_TX,
+ UART2_RX,
+ UART2_CTS,
+ UART2_RTS,
+
+ /* UART3 (GIGA_UART_GATING) */
+ UART3_TX,
+ UART3_RX,
+ UART3_CTS,
+ UART3_RTS,
+ UART3_CLKREQ,
+ UART3_BCLK, /* 12MHz clock out */
+ Y15_1610_UART3_RTS,
+
+ /* PWT & PWL */
+ PWT,
+ PWL,
+
+ /* USB master generic */
+ R18_USB_VBUS,
+ R18_1510_USB_GPIO0,
+ W4_USB_PUEN,
+ W4_USB_CLKO,
+ W4_USB_HIGHZ,
+ W4_GPIO58,
+
+ /* USB1 master */
+ USB1_SUSP,
+ USB1_SEO,
+ W13_1610_USB1_SE0,
+ USB1_TXEN,
+ USB1_TXD,
+ USB1_VP,
+ USB1_VM,
+ USB1_RCV,
+ USB1_SPEED,
+ R13_1610_USB1_SPEED,
+ R13_1710_USB1_SE0,
+
+ /* USB2 master */
+ USB2_SUSP,
+ USB2_VP,
+ USB2_TXEN,
+ USB2_VM,
+ USB2_RCV,
+ USB2_SEO,
+ USB2_TXD,
+
+ /* OMAP-1510 GPIO */
+ R18_1510_GPIO0,
+ R19_1510_GPIO1,
+ M14_1510_GPIO2,
+
+ /* OMAP1610 GPIO */
+ P18_1610_GPIO3,
+ Y15_1610_GPIO17,
+
+ /* OMAP-1710 GPIO */
+ R18_1710_GPIO0,
+ V2_1710_GPIO10,
+ N21_1710_GPIO14,
+ W15_1710_GPIO40,
+
+ /* MPUIO */
+ MPUIO2,
+ N15_1610_MPUIO2,
+ MPUIO4,
+ MPUIO5,
+ T20_1610_MPUIO5,
+ W11_1610_MPUIO6,
+ V10_1610_MPUIO7,
+ W11_1610_MPUIO9,
+ V10_1610_MPUIO10,
+ W10_1610_MPUIO11,
+ E20_1610_MPUIO13,
+ U20_1610_MPUIO14,
+ E19_1610_MPUIO15,
+
+ /* MCBSP2 */
+ MCBSP2_CLKR,
+ MCBSP2_CLKX,
+ MCBSP2_DR,
+ MCBSP2_DX,
+ MCBSP2_FSR,
+ MCBSP2_FSX,
+
+ /* MCBSP3 */
+ MCBSP3_CLKX,
+
+ /* Misc ballouts */
+ BALLOUT_V8_ARMIO3,
+ N20_HDQ,
+
+ /* OMAP-1610 MMC2 */
+ W8_1610_MMC2_DAT0,
+ V8_1610_MMC2_DAT1,
+ W15_1610_MMC2_DAT2,
+ R10_1610_MMC2_DAT3,
+ Y10_1610_MMC2_CLK,
+ Y8_1610_MMC2_CMD,
+ V9_1610_MMC2_CMDDIR,
+ V5_1610_MMC2_DATDIR0,
+ W19_1610_MMC2_DATDIR1,
+ R18_1610_MMC2_CLKIN,
+
+ /* OMAP-1610 External Trace Interface */
+ M19_1610_ETM_PSTAT0,
+ L15_1610_ETM_PSTAT1,
+ L18_1610_ETM_PSTAT2,
+ L19_1610_ETM_D0,
+ J19_1610_ETM_D6,
+ J18_1610_ETM_D7,
+
+ /* OMAP16XX GPIO */
+ P20_1610_GPIO4,
+ V9_1610_GPIO7,
+ W8_1610_GPIO9,
+ N20_1610_GPIO11,
+ N19_1610_GPIO13,
+ P10_1610_GPIO22,
+ V5_1610_GPIO24,
+ AA20_1610_GPIO_41,
+ W19_1610_GPIO48,
+ M7_1610_GPIO62,
+ V14_16XX_GPIO37,
+ R9_16XX_GPIO18,
+ L14_16XX_GPIO49,
+
+ /* OMAP-1610 uWire */
+ V19_1610_UWIRE_SCLK,
+ U18_1610_UWIRE_SDI,
+ W21_1610_UWIRE_SDO,
+ N14_1610_UWIRE_CS0,
+ P15_1610_UWIRE_CS3,
+ N15_1610_UWIRE_CS1,
+
+ /* OMAP-1610 SPI */
+ U19_1610_SPIF_SCK,
+ U18_1610_SPIF_DIN,
+ P20_1610_SPIF_DIN,
+ W21_1610_SPIF_DOUT,
+ R18_1610_SPIF_DOUT,
+ N14_1610_SPIF_CS0,
+ N15_1610_SPIF_CS1,
+ T19_1610_SPIF_CS2,
+ P15_1610_SPIF_CS3,
+
+ /* OMAP-1610 Flash */
+ L3_1610_FLASH_CS2B_OE,
+ M8_1610_FLASH_CS2B_WE,
+
+ /* First MMC */
+ MMC_CMD,
+ MMC_DAT1,
+ MMC_DAT2,
+ MMC_DAT0,
+ MMC_CLK,
+ MMC_DAT3,
+
+ /* OMAP-1710 MMC CMDDIR and DATDIR0 */
+ M15_1710_MMC_CLKI,
+ P19_1710_MMC_CMDDIR,
+ P20_1710_MMC_DATDIR0,
+
+ /* OMAP-1610 USB0 alternate pin configuration */
+ W9_USB0_TXEN,
+ AA9_USB0_VP,
+ Y5_USB0_RCV,
+ R9_USB0_VM,
+ V6_USB0_TXD,
+ W5_USB0_SE0,
+ V9_USB0_SPEED,
+ V9_USB0_SUSP,
+
+ /* USB2 */
+ W9_USB2_TXEN,
+ AA9_USB2_VP,
+ Y5_USB2_RCV,
+ R9_USB2_VM,
+ V6_USB2_TXD,
+ W5_USB2_SE0,
+
+ /* 16XX UART */
+ R13_1610_UART1_TX,
+ V14_16XX_UART1_RX,
+ R14_1610_UART1_CTS,
+ AA15_1610_UART1_RTS,
+ R9_16XX_UART2_RX,
+ L14_16XX_UART3_RX,
+
+ /* I2C OMAP-1610 */
+ I2C_SCL,
+ I2C_SDA,
+
+ /* Keypad */
+ F18_1610_KBC0,
+ D20_1610_KBC1,
+ D19_1610_KBC2,
+ E18_1610_KBC3,
+ C21_1610_KBC4,
+ G18_1610_KBR0,
+ F19_1610_KBR1,
+ H14_1610_KBR2,
+ E20_1610_KBR3,
+ E19_1610_KBR4,
+ N19_1610_KBR5,
+
+ /* Power management */
+ T20_1610_LOW_PWR,
+
+ /* MCLK Settings */
+ V5_1710_MCLK_ON,
+ V5_1710_MCLK_OFF,
+ R10_1610_MCLK_ON,
+ R10_1610_MCLK_OFF,
+
+ /* CompactFlash controller */
+ P11_1610_CF_CD2,
+ R11_1610_CF_IOIS16,
+ V10_1610_CF_IREQ,
+ W10_1610_CF_RESET,
+ W11_1610_CF_CD1,
+
+ /* parallel camera */
+ J15_1610_CAM_LCLK,
+ J18_1610_CAM_D7,
+ J19_1610_CAM_D6,
+ J14_1610_CAM_D5,
+ K18_1610_CAM_D4,
+ K19_1610_CAM_D3,
+ K15_1610_CAM_D2,
+ K14_1610_CAM_D1,
+ L19_1610_CAM_D0,
+ L18_1610_CAM_VS,
+ L15_1610_CAM_HS,
+ M19_1610_CAM_RSTZ,
+ Y15_1610_CAM_OUTCLK,
+
+ /* serial camera */
+ H19_1610_CAM_EXCLK,
+ Y12_1610_CCP_CLKP,
+ W13_1610_CCP_CLKM,
+ W14_1610_CCP_DATAP,
+ Y14_1610_CCP_DATAM,
+
+};
+
+struct omap_mux_cfg {
+ struct pin_config *pins;
+ unsigned long size;
+ int (*cfg_reg)(const struct pin_config *cfg);
+};
+
+#ifdef CONFIG_OMAP_MUX
+/* setup pin muxing in Linux */
+extern int omap1_mux_init(void);
+extern int omap_mux_register(struct omap_mux_cfg *);
+extern int omap_cfg_reg(unsigned long reg_cfg);
+#else
+/* boot loader does it all (no warnings from CONFIG_OMAP_MUX_WARNINGS) */
+static inline int omap1_mux_init(void) { return 0; }
+static inline int omap_cfg_reg(unsigned long reg_cfg) { return 0; }
+#endif
+
+extern int omap2_mux_init(void);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h
new file mode 100644
index 00000000..d86d1ecf
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/nand.h
@@ -0,0 +1,48 @@
+/*
+ * arch/arm/plat-omap/include/mach/nand.h
+ *
+ * Copyright (C) 2006 Micron Technology Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <plat/gpmc.h>
+#include <linux/mtd/partitions.h>
+
+enum nand_io {
+ NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */
+ NAND_OMAP_POLLED, /* polled mode, without prefetch */
+ NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */
+ NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */
+};
+
+struct omap_nand_platform_data {
+ unsigned int options;
+ int cs;
+ int gpio_irq;
+ struct mtd_partition *parts;
+ struct gpmc_timings *gpmc_t;
+ int nr_parts;
+ int (*nand_setup)(void);
+ int (*dev_ready)(struct omap_nand_platform_data *);
+ int dma_channel;
+ int gpmc_irq;
+ enum nand_io xfer_type;
+ unsigned long phys_base;
+ int devsize;
+ enum omap_ecc ecc_opt;
+};
+
+/* minimum size for IO mapping */
+#define NAND_IO_SIZE 4
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+extern int gpmc_nand_init(struct omap_nand_platform_data *d);
+#else
+static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
+{
+ return 0;
+}
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap-alsa.h b/arch/arm/plat-omap/include/plat/omap-alsa.h
new file mode 100644
index 00000000..b53055b3
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-alsa.h
@@ -0,0 +1,123 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap-alsa.h
+ *
+ * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
+ *
+ * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Written by Daniel Petrini, David Cohen, Anderson Briglia
+ * {daniel.petrini, david.cohen, anderson.briglia}@indt.org.br
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ *
+ * History
+ * -------
+ *
+ * 2005/07/25 INdT-10LE Kernel Team - Alsa driver for omap osk,
+ * original version based in sa1100 driver
+ * and omap oss driver.
+ */
+
+#ifndef __OMAP_ALSA_H
+#define __OMAP_ALSA_H
+
+#include <plat/dma.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <plat/mcbsp.h>
+#include <linux/platform_device.h>
+
+#define DMA_BUF_SIZE (1024 * 8)
+
+/*
+ * Buffer management for alsa and dma
+ */
+struct audio_stream {
+ char *id; /* identification string */
+ int stream_id; /* numeric identification */
+ int dma_dev; /* dma number of that device */
+ int *lch; /* Chain of channels this stream is linked to */
+ char started; /* to store if the chain was started or not */
+ int dma_q_head; /* DMA Channel Q Head */
+ int dma_q_tail; /* DMA Channel Q Tail */
+ char dma_q_count; /* DMA Channel Q Count */
+ int active:1; /* we are using this stream for transfer now */
+ int period; /* current transfer period */
+ int periods; /* current count of periods registerd in the DMA engine */
+ spinlock_t dma_lock; /* for locking in DMA operations */
+ struct snd_pcm_substream *stream; /* the pcm stream */
+ unsigned linked:1; /* dma channels linked */
+ int offset; /* store start position of the last period in the alsa buffer */
+ int (*hw_start)(void); /* interface to start HW interface, e.g. McBSP */
+ int (*hw_stop)(void); /* interface to stop HW interface, e.g. McBSP */
+};
+
+/*
+ * Alsa card structure for aic23
+ */
+struct snd_card_omap_codec {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ long samplerate;
+ struct audio_stream s[2]; /* playback & capture */
+};
+
+/* Codec specific information and function pointers.
+ * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
+ * are responsible for defining the function pointers.
+ */
+struct omap_alsa_codec_config {
+ char *name;
+ struct omap_mcbsp_reg_cfg *mcbsp_regs_alsa;
+ struct snd_pcm_hw_constraint_list *hw_constraints_rates;
+ struct snd_pcm_hardware *snd_omap_alsa_playback;
+ struct snd_pcm_hardware *snd_omap_alsa_capture;
+ void (*codec_configure_dev)(void);
+ void (*codec_set_samplerate)(long);
+ void (*codec_clock_setup)(void);
+ int (*codec_clock_on)(void);
+ int (*codec_clock_off)(void);
+ int (*get_default_samplerate)(void);
+};
+
+/*********** Mixer function prototypes *************************/
+int snd_omap_mixer(struct snd_card_omap_codec *);
+void snd_omap_init_mixer(void);
+
+#ifdef CONFIG_PM
+void snd_omap_suspend_mixer(void);
+void snd_omap_resume_mixer(void);
+#endif
+
+int snd_omap_alsa_post_probe(struct platform_device *pdev, struct omap_alsa_codec_config *config);
+int snd_omap_alsa_remove(struct platform_device *pdev);
+#ifdef CONFIG_PM
+int snd_omap_alsa_suspend(struct platform_device *pdev, pm_message_t state);
+int snd_omap_alsa_resume(struct platform_device *pdev);
+#else
+#define snd_omap_alsa_suspend NULL
+#define snd_omap_alsa_resume NULL
+#endif
+
+void callback_omap_alsa_sound_dma(void *);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
new file mode 100644
index 00000000..c0a75205
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -0,0 +1,360 @@
+/*
+ * omap-pm.h - OMAP power management interface
+ *
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order): Karthik Dasu, Jouni
+ * Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
+ * Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
+ * Richard Woodruff
+ */
+
+#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
+#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
+
+#include <linux/device.h>
+#include <linux/cpufreq.h>
+#include <linux/clk.h>
+#include <linux/opp.h>
+
+/*
+ * agent_id values for use with omap_pm_set_min_bus_tput():
+ *
+ * OCP_INITIATOR_AGENT is only valid for devices that can act as
+ * initiators -- it represents the device's L3 interconnect
+ * connection. OCP_TARGET_AGENT represents the device's L4
+ * interconnect connection.
+ */
+#define OCP_TARGET_AGENT 1
+#define OCP_INITIATOR_AGENT 2
+
+/**
+ * omap_pm_if_early_init - OMAP PM init code called before clock fw init
+ * @mpu_opp_table: array ptr to struct omap_opp for MPU
+ * @dsp_opp_table: array ptr to struct omap_opp for DSP
+ * @l3_opp_table : array ptr to struct omap_opp for CORE
+ *
+ * Initialize anything that must be configured before the clock
+ * framework starts. The "_if_" is to avoid name collisions with the
+ * PM idle-loop code.
+ */
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_early_init() 0
+#else
+int __init omap_pm_if_early_init(void);
+#endif
+
+/**
+ * omap_pm_if_init - OMAP PM init code called after clock fw init
+ *
+ * The main initialization code. OPP tables are passed in here. The
+ * "_if_" is to avoid name collisions with the PM idle-loop code.
+ */
+#ifdef CONFIG_OMAP_PM_NONE
+#define omap_pm_if_init() 0
+#else
+int __init omap_pm_if_init(void);
+#endif
+
+/**
+ * omap_pm_if_exit - OMAP PM exit code
+ *
+ * Exit code; currently unused. The "_if_" is to avoid name
+ * collisions with the PM idle-loop code.
+ */
+void omap_pm_if_exit(void);
+
+/*
+ * Device-driver-originated constraints (via board-*.c files, platform_data)
+ */
+
+
+/**
+ * omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
+ * @dev: struct device * requesting the constraint
+ * @t: maximum MPU wakeup latency in microseconds
+ *
+ * Request that the maximum interrupt latency for the MPU to be no
+ * greater than @t microseconds. "Interrupt latency" in this case is
+ * defined as the elapsed time from the occurrence of a hardware or
+ * timer interrupt to the time when the device driver's interrupt
+ * service routine has been entered by the MPU.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the MPU powerdomain into, and
+ * possibly the CORE powerdomain as well, since interrupt handling
+ * code currently runs from SDRAM. Advanced PM or board*.c code may
+ * also configure interrupt controller priorities, OCP bus priorities,
+ * CPU speed(s), etc.
+ *
+ * This function will not affect device wakeup latency, e.g., time
+ * elapsed from when a device driver enables a hardware device with
+ * clk_enable(), to when the device is ready for register access or
+ * other use. To control this device wakeup latency, use
+ * omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
+ * previous t value. To remove the latency target for the MPU, call
+ * with t = -1.
+ *
+ * XXX This constraint will be deprecated soon in favor of the more
+ * general omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
+ * @dev: struct device * requesting the constraint
+ * @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
+ * @r: minimum throughput (in KiB/s)
+ *
+ * Request that the minimum data throughput on the OCP interconnect
+ * attached to device @dev interconnect agent @tbus_id be no less
+ * than @r KiB/s.
+ *
+ * It is expected that the OMAP PM or bus code will use this
+ * information to set the interconnect clock to run at the lowest
+ * possible speed that satisfies all current system users. The PM or
+ * bus code will adjust the estimate based on its model of the bus, so
+ * device driver authors should attempt to specify an accurate
+ * quantity for their device use case, and let the PM or bus code
+ * overestimate the numbers as necessary to handle request/response
+ * latency, other competing users on the system, etc. On OMAP2/3, if
+ * a driver requests a minimum L4 interconnect speed constraint, the
+ * code will also need to add an minimum L3 interconnect speed
+ * constraint,
+ *
+ * Multiple calls to omap_pm_set_min_bus_tput() will replace the
+ * previous rate value for this device. To remove the interconnect
+ * throughput restriction for this device, call with r = 0.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+
+
+/**
+ * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
+ * @req_dev: struct device * requesting the constraint, or NULL if none
+ * @dev: struct device * to set the constraint one
+ * @t: maximum device wakeup latency in microseconds
+ *
+ * Request that the maximum amount of time necessary for a device @dev
+ * to become accessible after its clocks are enabled should be no
+ * greater than @t microseconds. Specifically, this represents the
+ * time from when a device driver enables device clocks with
+ * clk_enable(), to when the register reads and writes on the device
+ * will succeed. This function should be called before clk_disable()
+ * is called, since the power state transition decision may be made
+ * during clk_disable().
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the powerdomain enclosing this
+ * device into.
+ *
+ * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device. To remove the
+ * wakeup latency restriction for this device, call with t = -1.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t);
+
+
+/**
+ * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
+ * @dev: struct device *
+ * @t: maximum DMA transfer start latency in microseconds
+ *
+ * Request that the maximum system DMA transfer start latency for this
+ * device 'dev' should be no greater than 't' microseconds. "DMA
+ * transfer start latency" here is defined as the elapsed time from
+ * when a device (e.g., McBSP) requests that a system DMA transfer
+ * start or continue, to the time at which data starts to flow into
+ * that device from the system DMA controller.
+ *
+ * It is intended that underlying PM code will use this information to
+ * determine what power state to put the CORE powerdomain into.
+ *
+ * Since system DMA transfers may not involve the MPU, this function
+ * will not affect MPU wakeup latency. Use set_max_cpu_lat() to do
+ * so. Similarly, this function will not affect device wakeup latency
+ * -- use set_max_dev_wakeup_lat() to affect that.
+ *
+ * Multiple calls to set_max_sdma_lat() will replace the previous t
+ * value for this device. To remove the maximum DMA latency for this
+ * device, call with t = -1.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
+
+/**
+ * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
+ * @dev: struct device * requesting the constraint
+ * @clk: struct clk * to set the minimum rate constraint on
+ * @r: minimum rate in Hz
+ *
+ * Request that the minimum clock rate on the device @dev's clk @clk
+ * be no less than @r Hz.
+ *
+ * It is expected that the OMAP PM code will use this information to
+ * find an OPP or clock setting that will satisfy this clock rate
+ * constraint, along with any other applicable system constraints on
+ * the clock rate or corresponding voltage, etc.
+ *
+ * omap_pm_set_min_clk_rate() differs from the clock code's
+ * clk_set_rate() in that it considers other constraints before taking
+ * any hardware action, and may change a system OPP rather than just a
+ * clock rate. clk_set_rate() is intended to be a low-level
+ * interface.
+ *
+ * omap_pm_set_min_clk_rate() is easily open to abuse. A better API
+ * would be something like "omap_pm_set_min_dev_performance()";
+ * however, there is no easily-generalizable concept of performance
+ * that applies to all devices. Only a device (and possibly the
+ * device subsystem) has both the subsystem-specific knowledge, and
+ * the hardware IP block-specific knowledge, to translate a constraint
+ * on "touchscreen sampling accuracy" or "number of pixels or polygons
+ * rendered per second" to a clock rate. This translation can be
+ * dependent on the hardware IP block's revision, or firmware version,
+ * and the driver is the only code on the system that has this
+ * information and can know how to translate that into a clock rate.
+ *
+ * The intended use-case for this function is for userspace or other
+ * kernel code to communicate a particular performance requirement to
+ * a subsystem; then for the subsystem to communicate that requirement
+ * to something that is meaningful to the device driver; then for the
+ * device driver to convert that requirement to a clock rate, and to
+ * then call omap_pm_set_min_clk_rate().
+ *
+ * Users of this function (such as device drivers) should not simply
+ * call this function with some high clock rate to ensure "high
+ * performance." Rather, the device driver should take a performance
+ * constraint from its subsystem, such as "render at least X polygons
+ * per second," and use some formula or table to convert that into a
+ * clock rate constraint given the hardware type and hardware
+ * revision. Device drivers or subsystems should not assume that they
+ * know how to make a power/performance tradeoff - some device use
+ * cases may tolerate a lower-fidelity device function for lower power
+ * consumption; others may demand a higher-fidelity device function,
+ * no matter what the power consumption.
+ *
+ * Multiple calls to omap_pm_set_min_clk_rate() will replace the
+ * previous rate value for the device @dev. To remove the minimum clock
+ * rate constraint for the device, call with r = 0.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+/**
+ * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
+ *
+ * Intended for use by DSPBridge. Returns an array of OPP->DSP clock
+ * frequency entries. The final item in the array should have .rate =
+ * .opp_id = 0.
+ */
+const struct omap_opp *omap_pm_dsp_get_opp_table(void);
+
+/**
+ * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
+ * @opp_id: target DSP OPP ID
+ *
+ * Set a minimum OPP ID for the DSP. This is intended to be called
+ * only from the DSP Bridge MPU-side driver. Unfortunately, the only
+ * information that code receives from the DSP/BIOS load estimator is the
+ * target OPP ID; hence, this interface. No return value.
+ */
+void omap_pm_dsp_set_min_opp(u8 opp_id);
+
+/**
+ * omap_pm_dsp_get_opp - report the current DSP OPP ID
+ *
+ * Report the current OPP for the DSP. Since on OMAP3, the DSP and
+ * MPU share a single voltage domain, the OPP ID returned back may
+ * represent a higher DSP speed than the OPP requested via
+ * omap_pm_dsp_set_min_opp().
+ *
+ * Returns the current VDD1 OPP ID, or 0 upon error.
+ */
+u8 omap_pm_dsp_get_opp(void);
+
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+/**
+ * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
+ *
+ * Provide a frequency table usable by CPUFreq for the current chip/board.
+ * Returns a pointer to a struct cpufreq_frequency_table array or NULL
+ * upon error.
+ */
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
+
+/**
+ * omap_pm_cpu_set_freq - set the current minimum MPU frequency
+ * @f: MPU frequency in Hz
+ *
+ * Set the current minimum CPU frequency. The actual CPU frequency
+ * used could end up higher if the DSP requested a higher OPP.
+ * Intended to be called by plat-omap/cpu_omap.c:omap_target(). No
+ * return value.
+ */
+void omap_pm_cpu_set_freq(unsigned long f);
+
+/**
+ * omap_pm_cpu_get_freq - report the current CPU frequency
+ *
+ * Returns the current MPU frequency, or 0 upon error.
+ */
+unsigned long omap_pm_cpu_get_freq(void);
+
+
+/*
+ * Device context loss tracking
+ */
+
+/**
+ * omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
+ * @dev: struct device *
+ *
+ * This function returns the number of times that the device @dev has
+ * lost its internal context. This generally occurs on a powerdomain
+ * transition to OFF. Drivers use this as an optimization to avoid restoring
+ * context if the device hasn't lost it. To use, drivers should initially
+ * call this in their context save functions and store the result. Early in
+ * the driver's context restore function, the driver should call this function
+ * again, and compare the result to the stored counter. If they differ, the
+ * driver must restore device context. If the number of context losses
+ * exceeds the maximum positive integer, the function will wrap to 0 and
+ * continue counting. Returns the number of context losses for this device,
+ * or zero upon error.
+ */
+u32 omap_pm_get_dev_context_loss_count(struct device *dev);
+
+void omap_pm_enable_off_mode(void);
+void omap_pm_disable_off_mode(void);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
new file mode 100644
index 00000000..2682043f
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -0,0 +1,116 @@
+/*
+ * Driver for OMAP-UART controller.
+ * Based on drivers/serial/8250.c
+ *
+ * Copyright (C) 2010 Texas Instruments.
+ *
+ * Authors:
+ * Govindraj R <govindraj.raja@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __OMAP_SERIAL_H__
+#define __OMAP_SERIAL_H__
+
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <plat/mux.h>
+
+#define DRIVER_NAME "omap_uart"
+
+/*
+ * Use tty device name as ttyO, [O -> OMAP]
+ * in bootargs we specify as console=ttyO0 if uart1
+ * is used as console uart.
+ */
+#define OMAP_SERIAL_NAME "ttyO"
+
+#define OMAP_MODE13X_SPEED 230400
+
+/* WER = 0x7F
+ * Enable module level wakeup in WER reg
+ */
+#define OMAP_UART_WER_MOD_WKUP 0X7F
+
+/* Enable XON/XOFF flow control on output */
+#define OMAP_UART_SW_TX 0x04
+
+/* Enable XON/XOFF flow control on input */
+#define OMAP_UART_SW_RX 0x04
+
+#define OMAP_UART_SYSC_RESET 0X07
+#define OMAP_UART_TCR_TRIG 0X0F
+#define OMAP_UART_SW_CLR 0XF0
+#define OMAP_UART_FIFO_CLR 0X06
+
+#define OMAP_UART_DMA_CH_FREE -1
+
+#define RX_TIMEOUT (3 * HZ)
+#define OMAP_MAX_HSUART_PORTS 4
+
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+
+struct omap_uart_port_info {
+ bool dma_enabled; /* To specify DMA Mode */
+ unsigned int uartclk; /* UART clock rate */
+ void __iomem *membase; /* ioremap cookie or NULL */
+ resource_size_t mapbase; /* resource base */
+ unsigned long irqflags; /* request_irq flags */
+ upf_t flags; /* UPF_* flags */
+};
+
+struct uart_omap_dma {
+ u8 uart_dma_tx;
+ u8 uart_dma_rx;
+ int rx_dma_channel;
+ int tx_dma_channel;
+ dma_addr_t rx_buf_dma_phys;
+ dma_addr_t tx_buf_dma_phys;
+ unsigned int uart_base;
+ /*
+ * Buffer for rx dma.It is not required for tx because the buffer
+ * comes from port structure.
+ */
+ unsigned char *rx_buf;
+ unsigned int prev_rx_dma_pos;
+ int tx_buf_size;
+ int tx_dma_used;
+ int rx_dma_used;
+ spinlock_t tx_lock;
+ spinlock_t rx_lock;
+ /* timer to poll activity on rx dma */
+ struct timer_list rx_timer;
+ int rx_buf_size;
+ int rx_timeout;
+};
+
+struct uart_omap_port {
+ struct uart_port port;
+ struct uart_omap_dma uart_dma;
+ struct platform_device *pdev;
+
+ unsigned char ier;
+ unsigned char lcr;
+ unsigned char mcr;
+ unsigned char fcr;
+ unsigned char efr;
+
+ int use_dma;
+ /*
+ * Some bits in registers are cleared on a read, so they must
+ * be saved whenever the register is read but the bits will not
+ * be immediately processed.
+ */
+ unsigned int lsr_break_flag;
+ unsigned char msr_saved_flags;
+ char name[20];
+ unsigned long port_activity;
+};
+
+#endif /* __OMAP_SERIAL_H__ */
diff --git a/arch/arm/plat-omap/include/plat/omap1510.h b/arch/arm/plat-omap/include/plat/omap1510.h
new file mode 100644
index 00000000..d2400466
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap1510.h
@@ -0,0 +1,50 @@
+/* arch/arm/plat-omap/include/mach/omap1510.h
+ *
+ * Hardware definitions for TI OMAP1510 processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP15XX_H
+#define __ASM_ARCH_OMAP15XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP1510_DSP_BASE 0xE0000000
+#define OMAP1510_DSP_SIZE 0x28000
+#define OMAP1510_DSP_START 0xE0000000
+
+#define OMAP1510_DSPREG_BASE 0xE1000000
+#define OMAP1510_DSPREG_SIZE SZ_128K
+#define OMAP1510_DSPREG_START 0xE1000000
+
+#define OMAP1510_DSP_MMU_BASE (0xfffed200)
+
+#endif /* __ASM_ARCH_OMAP15XX_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap16xx.h b/arch/arm/plat-omap/include/plat/omap16xx.h
new file mode 100644
index 00000000..e69e1d85
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap16xx.h
@@ -0,0 +1,202 @@
+/* arch/arm/plat-omap/include/mach/omap16xx.h
+ *
+ * Hardware definitions for TI OMAP1610/5912/1710 processors.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP16XX_H
+#define __ASM_ARCH_OMAP16XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP16XX_DSP_BASE 0xE0000000
+#define OMAP16XX_DSP_SIZE 0x28000
+#define OMAP16XX_DSP_START 0xE0000000
+
+#define OMAP16XX_DSPREG_BASE 0xE1000000
+#define OMAP16XX_DSPREG_SIZE SZ_128K
+#define OMAP16XX_DSPREG_START 0xE1000000
+
+#define OMAP16XX_SEC_BASE 0xFFFE4000
+#define OMAP16XX_SEC_DES (OMAP16XX_SEC_BASE + 0x0000)
+#define OMAP16XX_SEC_SHA1MD5 (OMAP16XX_SEC_BASE + 0x0800)
+#define OMAP16XX_SEC_RNG (OMAP16XX_SEC_BASE + 0x1000)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Interrupts
+ * ---------------------------------------------------------------------------
+ */
+#define OMAP_IH2_0_BASE (0xfffe0000)
+#define OMAP_IH2_1_BASE (0xfffe0100)
+#define OMAP_IH2_2_BASE (0xfffe0200)
+#define OMAP_IH2_3_BASE (0xfffe0300)
+
+#define OMAP_IH2_0_ITR (OMAP_IH2_0_BASE + 0x00)
+#define OMAP_IH2_0_MIR (OMAP_IH2_0_BASE + 0x04)
+#define OMAP_IH2_0_SIR_IRQ (OMAP_IH2_0_BASE + 0x10)
+#define OMAP_IH2_0_SIR_FIQ (OMAP_IH2_0_BASE + 0x14)
+#define OMAP_IH2_0_CONTROL (OMAP_IH2_0_BASE + 0x18)
+#define OMAP_IH2_0_ILR0 (OMAP_IH2_0_BASE + 0x1c)
+#define OMAP_IH2_0_ISR (OMAP_IH2_0_BASE + 0x9c)
+
+#define OMAP_IH2_1_ITR (OMAP_IH2_1_BASE + 0x00)
+#define OMAP_IH2_1_MIR (OMAP_IH2_1_BASE + 0x04)
+#define OMAP_IH2_1_SIR_IRQ (OMAP_IH2_1_BASE + 0x10)
+#define OMAP_IH2_1_SIR_FIQ (OMAP_IH2_1_BASE + 0x14)
+#define OMAP_IH2_1_CONTROL (OMAP_IH2_1_BASE + 0x18)
+#define OMAP_IH2_1_ILR1 (OMAP_IH2_1_BASE + 0x1c)
+#define OMAP_IH2_1_ISR (OMAP_IH2_1_BASE + 0x9c)
+
+#define OMAP_IH2_2_ITR (OMAP_IH2_2_BASE + 0x00)
+#define OMAP_IH2_2_MIR (OMAP_IH2_2_BASE + 0x04)
+#define OMAP_IH2_2_SIR_IRQ (OMAP_IH2_2_BASE + 0x10)
+#define OMAP_IH2_2_SIR_FIQ (OMAP_IH2_2_BASE + 0x14)
+#define OMAP_IH2_2_CONTROL (OMAP_IH2_2_BASE + 0x18)
+#define OMAP_IH2_2_ILR2 (OMAP_IH2_2_BASE + 0x1c)
+#define OMAP_IH2_2_ISR (OMAP_IH2_2_BASE + 0x9c)
+
+#define OMAP_IH2_3_ITR (OMAP_IH2_3_BASE + 0x00)
+#define OMAP_IH2_3_MIR (OMAP_IH2_3_BASE + 0x04)
+#define OMAP_IH2_3_SIR_IRQ (OMAP_IH2_3_BASE + 0x10)
+#define OMAP_IH2_3_SIR_FIQ (OMAP_IH2_3_BASE + 0x14)
+#define OMAP_IH2_3_CONTROL (OMAP_IH2_3_BASE + 0x18)
+#define OMAP_IH2_3_ILR3 (OMAP_IH2_3_BASE + 0x1c)
+#define OMAP_IH2_3_ISR (OMAP_IH2_3_BASE + 0x9c)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP16XX_ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+/*
+ * ----------------------------------------------------------------------------
+ * Pin configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV6 (1 << 8)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV7 (1 << 9)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV8 (1 << 10)
+#define OMAP16XX_CONF_VOLTAGE_VDDSHV9 (1 << 11)
+#define OMAP16XX_SUBLVDS_CONF_VALID (1 << 13)
+
+/*
+ * ----------------------------------------------------------------------------
+ * System control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP1610_RESET_CONTROL 0xfffe1140
+
+/*
+ * ---------------------------------------------------------------------------
+ * TIPB bus interface
+ * ---------------------------------------------------------------------------
+ */
+#define TIPB_SWITCH_BASE (0xfffbc800)
+#define OMAP16XX_MMCSD2_SSW_MPU_CONF (TIPB_SWITCH_BASE + 0x160)
+
+/* UART3 Registers Mapping through MPU bus */
+#define UART3_RHR (OMAP1_UART3_BASE + 0)
+#define UART3_THR (OMAP1_UART3_BASE + 0)
+#define UART3_DLL (OMAP1_UART3_BASE + 0)
+#define UART3_IER (OMAP1_UART3_BASE + 4)
+#define UART3_DLH (OMAP1_UART3_BASE + 4)
+#define UART3_IIR (OMAP1_UART3_BASE + 8)
+#define UART3_FCR (OMAP1_UART3_BASE + 8)
+#define UART3_EFR (OMAP1_UART3_BASE + 8)
+#define UART3_LCR (OMAP1_UART3_BASE + 0x0C)
+#define UART3_MCR (OMAP1_UART3_BASE + 0x10)
+#define UART3_XON1_ADDR1 (OMAP1_UART3_BASE + 0x10)
+#define UART3_XON2_ADDR2 (OMAP1_UART3_BASE + 0x14)
+#define UART3_LSR (OMAP1_UART3_BASE + 0x14)
+#define UART3_TCR (OMAP1_UART3_BASE + 0x18)
+#define UART3_MSR (OMAP1_UART3_BASE + 0x18)
+#define UART3_XOFF1 (OMAP1_UART3_BASE + 0x18)
+#define UART3_XOFF2 (OMAP1_UART3_BASE + 0x1C)
+#define UART3_SPR (OMAP1_UART3_BASE + 0x1C)
+#define UART3_TLR (OMAP1_UART3_BASE + 0x1C)
+#define UART3_MDR1 (OMAP1_UART3_BASE + 0x20)
+#define UART3_MDR2 (OMAP1_UART3_BASE + 0x24)
+#define UART3_SFLSR (OMAP1_UART3_BASE + 0x28)
+#define UART3_TXFLL (OMAP1_UART3_BASE + 0x28)
+#define UART3_RESUME (OMAP1_UART3_BASE + 0x2C)
+#define UART3_TXFLH (OMAP1_UART3_BASE + 0x2C)
+#define UART3_SFREGL (OMAP1_UART3_BASE + 0x30)
+#define UART3_RXFLL (OMAP1_UART3_BASE + 0x30)
+#define UART3_SFREGH (OMAP1_UART3_BASE + 0x34)
+#define UART3_RXFLH (OMAP1_UART3_BASE + 0x34)
+#define UART3_BLR (OMAP1_UART3_BASE + 0x38)
+#define UART3_ACREG (OMAP1_UART3_BASE + 0x3C)
+#define UART3_DIV16 (OMAP1_UART3_BASE + 0x3C)
+#define UART3_SCR (OMAP1_UART3_BASE + 0x40)
+#define UART3_SSR (OMAP1_UART3_BASE + 0x44)
+#define UART3_EBLR (OMAP1_UART3_BASE + 0x48)
+#define UART3_OSC_12M_SEL (OMAP1_UART3_BASE + 0x4C)
+#define UART3_MVR (OMAP1_UART3_BASE + 0x50)
+
+/*
+ * ---------------------------------------------------------------------------
+ * Watchdog timer
+ * ---------------------------------------------------------------------------
+ */
+
+/* 32-bit Watchdog timer in OMAP 16XX */
+#define OMAP_16XX_WATCHDOG_BASE (0xfffeb000)
+#define OMAP_16XX_WIDR (OMAP_16XX_WATCHDOG_BASE + 0x00)
+#define OMAP_16XX_WD_SYSCONFIG (OMAP_16XX_WATCHDOG_BASE + 0x10)
+#define OMAP_16XX_WD_SYSSTATUS (OMAP_16XX_WATCHDOG_BASE + 0x14)
+#define OMAP_16XX_WCLR (OMAP_16XX_WATCHDOG_BASE + 0x24)
+#define OMAP_16XX_WCRR (OMAP_16XX_WATCHDOG_BASE + 0x28)
+#define OMAP_16XX_WLDR (OMAP_16XX_WATCHDOG_BASE + 0x2c)
+#define OMAP_16XX_WTGR (OMAP_16XX_WATCHDOG_BASE + 0x30)
+#define OMAP_16XX_WWPS (OMAP_16XX_WATCHDOG_BASE + 0x34)
+#define OMAP_16XX_WSPR (OMAP_16XX_WATCHDOG_BASE + 0x48)
+
+#define WCLR_PRE_SHIFT 5
+#define WCLR_PTV_SHIFT 2
+
+#define WWPS_W_PEND_WSPR (1 << 4)
+#define WWPS_W_PEND_WTGR (1 << 3)
+#define WWPS_W_PEND_WLDR (1 << 2)
+#define WWPS_W_PEND_WCRR (1 << 1)
+#define WWPS_W_PEND_WCLR (1 << 0)
+
+#define WSPR_ENABLE_0 (0x0000bbbb)
+#define WSPR_ENABLE_1 (0x00004444)
+#define WSPR_DISABLE_0 (0x0000aaaa)
+#define WSPR_DISABLE_1 (0x00005555)
+
+#define OMAP16XX_DSP_MMU_BASE (0xfffed200)
+#define OMAP16XX_MAILBOX_BASE (0xfffcf000)
+
+#endif /* __ASM_ARCH_OMAP16XX_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap24xx.h b/arch/arm/plat-omap/include/plat/omap24xx.h
new file mode 100644
index 00000000..92df9e27
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap24xx.h
@@ -0,0 +1,89 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap24xx.h
+ *
+ * This file contains the processor specific definitions
+ * of the TI OMAP24XX.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_OMAP2_H
+#define __ASM_ARCH_OMAP2_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers. Note also that some of these defines are needed
+ * for omap1 to compile without adding ifdefs.
+ */
+
+#define L4_24XX_BASE 0x48000000
+#define L4_WK_243X_BASE 0x49000000
+#define L3_24XX_BASE 0x68000000
+
+/* interrupt controller */
+#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
+#define OMAP24XX_IVA_INTC_BASE 0x40000000
+
+#define OMAP242X_CTRL_BASE L4_24XX_BASE
+#define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
+#define OMAP2420_PRCM_BASE (L4_24XX_BASE + 0x8000)
+#define OMAP2420_CM_BASE (L4_24XX_BASE + 0x8000)
+#define OMAP2420_PRM_BASE OMAP2420_CM_BASE
+#define OMAP2420_SDRC_BASE (L3_24XX_BASE + 0x9000)
+#define OMAP2420_SMS_BASE 0x68008000
+#define OMAP2420_GPMC_BASE 0x6800a000
+
+#define OMAP2430_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000)
+#define OMAP2430_PRCM_BASE (L4_WK_243X_BASE + 0x6000)
+#define OMAP2430_CM_BASE (L4_WK_243X_BASE + 0x6000)
+#define OMAP2430_PRM_BASE OMAP2430_CM_BASE
+
+#define OMAP243X_SMS_BASE 0x6C000000
+#define OMAP243X_SDRC_BASE 0x6D000000
+#define OMAP243X_GPMC_BASE 0x6E000000
+#define OMAP243X_SCM_BASE (L4_WK_243X_BASE + 0x2000)
+#define OMAP243X_CTRL_BASE OMAP243X_SCM_BASE
+#define OMAP243X_HS_BASE (L4_24XX_BASE + 0x000ac000)
+
+/* DSP SS */
+#define OMAP2420_DSP_BASE 0x58000000
+#define OMAP2420_DSP_MEM_BASE (OMAP2420_DSP_BASE + 0x0)
+#define OMAP2420_DSP_IPI_BASE (OMAP2420_DSP_BASE + 0x1000000)
+#define OMAP2420_DSP_MMU_BASE (OMAP2420_DSP_BASE + 0x2000000)
+
+#define OMAP243X_DSP_BASE 0x5C000000
+#define OMAP243X_DSP_MEM_BASE (OMAP243X_DSP_BASE + 0x0)
+#define OMAP243X_DSP_MMU_BASE (OMAP243X_DSP_BASE + 0x1000000)
+
+/* Mailbox */
+#define OMAP24XX_MAILBOX_BASE (L4_24XX_BASE + 0x94000)
+
+/* Camera */
+#define OMAP24XX_CAMERA_BASE (L4_24XX_BASE + 0x52000)
+
+/* Security */
+#define OMAP24XX_SEC_BASE (L4_24XX_BASE + 0xA0000)
+#define OMAP24XX_SEC_RNG_BASE (OMAP24XX_SEC_BASE + 0x0000)
+#define OMAP24XX_SEC_DES_BASE (OMAP24XX_SEC_BASE + 0x2000)
+#define OMAP24XX_SEC_SHA1MD5_BASE (OMAP24XX_SEC_BASE + 0x4000)
+#define OMAP24XX_SEC_AES_BASE (OMAP24XX_SEC_BASE + 0x6000)
+#define OMAP24XX_SEC_PKA_BASE (OMAP24XX_SEC_BASE + 0x8000)
+
+#endif /* __ASM_ARCH_OMAP2_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
new file mode 100644
index 00000000..b9e85886
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -0,0 +1,99 @@
+/*
+ * arch/arm/plat-omap/include/mach/omap34xx.h
+ *
+ * This file contains the processor specific definitions of the TI OMAP34XX.
+ *
+ * Copyright (C) 2007 Texas Instruments.
+ * Copyright (C) 2007 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_OMAP3_H
+#define __ASM_ARCH_OMAP3_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+
+#define L4_34XX_BASE 0x48000000
+#define L4_WK_34XX_BASE 0x48300000
+#define L4_PER_34XX_BASE 0x49000000
+#define L4_EMU_34XX_BASE 0x54000000
+#define L3_34XX_BASE 0x68000000
+
+#define OMAP3430_32KSYNCT_BASE 0x48320000
+#define OMAP3430_CM_BASE 0x48004800
+#define OMAP3430_PRM_BASE 0x48306800
+#define OMAP343X_SMS_BASE 0x6C000000
+#define OMAP343X_SDRC_BASE 0x6D000000
+#define OMAP34XX_GPMC_BASE 0x6E000000
+#define OMAP343X_SCM_BASE 0x48002000
+#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE
+
+#define OMAP34XX_IC_BASE 0x48200000
+
+#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100)
+#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400)
+#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600)
+#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00)
+#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00)
+#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00)
+#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
+#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
+#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_CSI2A_REGS1_BASE (OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSIPHY2_BASE (OMAP3430_ISP_BASE + 0x1970)
+#define OMAP3630_ISP_CSI2A_REGS2_BASE (OMAP3430_ISP_BASE + 0x19C0)
+#define OMAP3630_ISP_CSI2C_REGS1_BASE (OMAP3430_ISP_BASE + 0x1C00)
+#define OMAP3630_ISP_CSIPHY1_BASE (OMAP3430_ISP_BASE + 0x1D70)
+#define OMAP3630_ISP_CSI2C_REGS2_BASE (OMAP3430_ISP_BASE + 0x1DC0)
+
+#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
+#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
+#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF)
+#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7)
+#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047)
+#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F)
+#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F)
+#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
+#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
+#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
+#define OMAP3430_ISP_CSI2A_REGS1_END (OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
+#define OMAP3430_ISP_CSIPHY2_END (OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
+#define OMAP3630_ISP_CSI2A_REGS2_END (OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
+#define OMAP3630_ISP_CSI2C_REGS1_END (OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
+#define OMAP3630_ISP_CSIPHY1_END (OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
+#define OMAP3630_ISP_CSI2C_REGS2_END (OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
+
+#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
+#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
+#define OMAP34XX_UHH_CONFIG_BASE (L4_34XX_BASE + 0x64000)
+#define OMAP34XX_OHCI_BASE (L4_34XX_BASE + 0x64400)
+#define OMAP34XX_EHCI_BASE (L4_34XX_BASE + 0x64800)
+#define OMAP34XX_SR1_BASE 0x480C9000
+#define OMAP34XX_SR2_BASE 0x480CB000
+
+#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
+
+/* Security */
+#define OMAP34XX_SEC_BASE (L4_34XX_BASE + 0xA0000)
+#define OMAP34XX_SEC_SHA1MD5_BASE (OMAP34XX_SEC_BASE + 0x23000)
+#define OMAP34XX_SEC_AES_BASE (OMAP34XX_SEC_BASE + 0x25000)
+
+#endif /* __ASM_ARCH_OMAP3_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap4-keypad.h b/arch/arm/plat-omap/include/plat/omap4-keypad.h
new file mode 100644
index 00000000..2b1d9bc1
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap4-keypad.h
@@ -0,0 +1,14 @@
+#ifndef ARCH_ARM_PLAT_OMAP4_KEYPAD_H
+#define ARCH_ARM_PLAT_OMAP4_KEYPAD_H
+
+#include <linux/input/matrix_keypad.h>
+
+struct omap4_keypad_platform_data {
+ const struct matrix_keymap_data *keymap_data;
+
+ u8 rows;
+ u8 cols;
+};
+
+extern int omap4_keyboard_init(struct omap4_keypad_platform_data *);
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
new file mode 100644
index 00000000..ea2b8a63
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -0,0 +1,61 @@
+/*:
+ * Address mappings and base address for OMAP4 interconnects
+ * and peripherals.
+ *
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_OMAP44XX_H
+#define __ASM_ARCH_OMAP44XX_H
+
+/*
+ * Please place only base defines here and put the rest in device
+ * specific headers.
+ */
+#define L4_44XX_BASE 0x4a000000
+#define L4_WK_44XX_BASE 0x4a300000
+#define L4_PER_44XX_BASE 0x48000000
+#define L4_EMU_44XX_BASE 0x54000000
+#define L3_44XX_BASE 0x44000000
+#define OMAP44XX_EMIF1_BASE 0x4c000000
+#define OMAP44XX_EMIF2_BASE 0x4d000000
+#define OMAP44XX_DMM_BASE 0x4e000000
+#define OMAP4430_32KSYNCT_BASE 0x4a304000
+#define OMAP4430_CM1_BASE 0x4a004000
+#define OMAP4430_CM_BASE OMAP4430_CM1_BASE
+#define OMAP4430_CM2_BASE 0x4a008000
+#define OMAP4430_PRM_BASE 0x4a306000
+#define OMAP4430_PRCM_MPU_BASE 0x48243000
+#define OMAP44XX_GPMC_BASE 0x50000000
+#define OMAP443X_SCM_BASE 0x4a002000
+#define OMAP443X_CTRL_BASE 0x4a100000
+#define OMAP44XX_IC_BASE 0x48200000
+#define OMAP44XX_IVA_INTC_BASE 0x40000000
+#define IRQ_SIR_IRQ 0x0040
+#define OMAP44XX_GIC_DIST_BASE 0x48241000
+#define OMAP44XX_GIC_CPU_BASE 0x48240100
+#define OMAP44XX_SCU_BASE 0x48240000
+#define OMAP44XX_LOCAL_TWD_BASE 0x48240600
+#define OMAP44XX_L2CACHE_BASE 0x48242000
+#define OMAP44XX_WKUPGEN_BASE 0x48281000
+#define OMAP44XX_MCPDM_BASE 0x40132000
+#define OMAP44XX_MCPDM_L3_BASE 0x49032000
+
+#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)
+#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
+
+#define OMAP4_MMU1_BASE 0x55082000
+#define OMAP4_MMU2_BASE 0x4A066000
+
+#define OMAP44XX_USBTLL_BASE (L4_44XX_BASE + 0x62000)
+#define OMAP44XX_UHH_CONFIG_BASE (L4_44XX_BASE + 0x64000)
+#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800)
+#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00)
+
+#endif /* __ASM_ARCH_OMAP44XX_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap730.h b/arch/arm/plat-omap/include/plat/omap730.h
new file mode 100644
index 00000000..14272bc1
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap730.h
@@ -0,0 +1,102 @@
+/* arch/arm/plat-omap/include/mach/omap730.h
+ *
+ * Hardware definitions for TI OMAP730 processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP730_H
+#define __ASM_ARCH_OMAP730_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP730_DSP_BASE 0xE0000000
+#define OMAP730_DSP_SIZE 0x50000
+#define OMAP730_DSP_START 0xE0000000
+
+#define OMAP730_DSPREG_BASE 0xE1000000
+#define OMAP730_DSPREG_SIZE SZ_128K
+#define OMAP730_DSPREG_START 0xE1000000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_CONFIG_BASE 0xfffe1000
+#define OMAP730_IO_CONF_0 0xfffe1070
+#define OMAP730_IO_CONF_1 0xfffe1074
+#define OMAP730_IO_CONF_2 0xfffe1078
+#define OMAP730_IO_CONF_3 0xfffe107c
+#define OMAP730_IO_CONF_4 0xfffe1080
+#define OMAP730_IO_CONF_5 0xfffe1084
+#define OMAP730_IO_CONF_6 0xfffe1088
+#define OMAP730_IO_CONF_7 0xfffe108c
+#define OMAP730_IO_CONF_8 0xfffe1090
+#define OMAP730_IO_CONF_9 0xfffe1094
+#define OMAP730_IO_CONF_10 0xfffe1098
+#define OMAP730_IO_CONF_11 0xfffe109c
+#define OMAP730_IO_CONF_12 0xfffe10a0
+#define OMAP730_IO_CONF_13 0xfffe10a4
+
+#define OMAP730_MODE_1 0xfffe1010
+#define OMAP730_MODE_2 0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP730_MODE2_OFFSET 0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_FLASH_CFG_0 0xfffecc10
+#define OMAP730_FLASH_ACFG_0 0xfffecc50
+#define OMAP730_FLASH_CFG_1 0xfffecc14
+#define OMAP730_FLASH_ACFG_1 0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_ICR_BASE 0xfffbb800
+#define OMAP730_DSP_M_CTL 0xfffbb804
+#define OMAP730_DSP_MMU_BASE 0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP730 PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP730_PCC_UPLD_CTRL_BASE (0xfffe0900)
+#define OMAP730_PCC_UPLD_CTRL (OMAP730_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /* __ASM_ARCH_OMAP730_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap7xx.h b/arch/arm/plat-omap/include/plat/omap7xx.h
new file mode 100644
index 00000000..48e4757e
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap7xx.h
@@ -0,0 +1,107 @@
+/* arch/arm/plat-omap/include/mach/omap7xx.h
+ *
+ * Hardware definitions for TI OMAP7XX processor.
+ *
+ * Cleanup for Linux-2.6 by Dirk Behme <dirk.behme@de.bosch.com>
+ * Adapted for omap850 by Zebediah C. McClure <zmc@lurian.net>
+ * Adapted for omap7xx by Alistair Buxton <a.j.buxton@gmail.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP7XX_H
+#define __ASM_ARCH_OMAP7XX_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP7XX_DSP_BASE 0xE0000000
+#define OMAP7XX_DSP_SIZE 0x50000
+#define OMAP7XX_DSP_START 0xE0000000
+
+#define OMAP7XX_DSPREG_BASE 0xE1000000
+#define OMAP7XX_DSPREG_SIZE SZ_128K
+#define OMAP7XX_DSPREG_START 0xE1000000
+
+#define OMAP7XX_SPI1_BASE 0xfffc0800
+#define OMAP7XX_SPI2_BASE 0xfffc1000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_CONFIG_BASE 0xfffe1000
+#define OMAP7XX_IO_CONF_0 0xfffe1070
+#define OMAP7XX_IO_CONF_1 0xfffe1074
+#define OMAP7XX_IO_CONF_2 0xfffe1078
+#define OMAP7XX_IO_CONF_3 0xfffe107c
+#define OMAP7XX_IO_CONF_4 0xfffe1080
+#define OMAP7XX_IO_CONF_5 0xfffe1084
+#define OMAP7XX_IO_CONF_6 0xfffe1088
+#define OMAP7XX_IO_CONF_7 0xfffe108c
+#define OMAP7XX_IO_CONF_8 0xfffe1090
+#define OMAP7XX_IO_CONF_9 0xfffe1094
+#define OMAP7XX_IO_CONF_10 0xfffe1098
+#define OMAP7XX_IO_CONF_11 0xfffe109c
+#define OMAP7XX_IO_CONF_12 0xfffe10a0
+#define OMAP7XX_IO_CONF_13 0xfffe10a4
+
+#define OMAP7XX_MODE_1 0xfffe1010
+#define OMAP7XX_MODE_2 0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP7XX_MODE2_OFFSET 0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_FLASH_CFG_0 0xfffecc10
+#define OMAP7XX_FLASH_ACFG_0 0xfffecc50
+#define OMAP7XX_FLASH_CFG_1 0xfffecc14
+#define OMAP7XX_FLASH_ACFG_1 0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_ICR_BASE 0xfffbb800
+#define OMAP7XX_DSP_M_CTL 0xfffbb804
+#define OMAP7XX_DSP_MMU_BASE 0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP7XX PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP7XX_PCC_UPLD_CTRL_BASE (0xfffe0900)
+#define OMAP7XX_PCC_UPLD_CTRL (OMAP7XX_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /* __ASM_ARCH_OMAP7XX_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap850.h b/arch/arm/plat-omap/include/plat/omap850.h
new file mode 100644
index 00000000..c33f6798
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap850.h
@@ -0,0 +1,102 @@
+/* arch/arm/plat-omap/include/mach/omap850.h
+ *
+ * Hardware definitions for TI OMAP850 processor.
+ *
+ * Derived from omap730.h by Zebediah C. McClure <zmc@lurian.net>
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP850_H
+#define __ASM_ARCH_OMAP850_H
+
+/*
+ * ----------------------------------------------------------------------------
+ * Base addresses
+ * ----------------------------------------------------------------------------
+ */
+
+/* Syntax: XX_BASE = Virtual base address, XX_START = Physical base address */
+
+#define OMAP850_DSP_BASE 0xE0000000
+#define OMAP850_DSP_SIZE 0x50000
+#define OMAP850_DSP_START 0xE0000000
+
+#define OMAP850_DSPREG_BASE 0xE1000000
+#define OMAP850_DSPREG_SIZE SZ_128K
+#define OMAP850_DSPREG_START 0xE1000000
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 specific configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_CONFIG_BASE 0xfffe1000
+#define OMAP850_IO_CONF_0 0xfffe1070
+#define OMAP850_IO_CONF_1 0xfffe1074
+#define OMAP850_IO_CONF_2 0xfffe1078
+#define OMAP850_IO_CONF_3 0xfffe107c
+#define OMAP850_IO_CONF_4 0xfffe1080
+#define OMAP850_IO_CONF_5 0xfffe1084
+#define OMAP850_IO_CONF_6 0xfffe1088
+#define OMAP850_IO_CONF_7 0xfffe108c
+#define OMAP850_IO_CONF_8 0xfffe1090
+#define OMAP850_IO_CONF_9 0xfffe1094
+#define OMAP850_IO_CONF_10 0xfffe1098
+#define OMAP850_IO_CONF_11 0xfffe109c
+#define OMAP850_IO_CONF_12 0xfffe10a0
+#define OMAP850_IO_CONF_13 0xfffe10a4
+
+#define OMAP850_MODE_1 0xfffe1010
+#define OMAP850_MODE_2 0xfffe1014
+
+/* CSMI specials: in terms of base + offset */
+#define OMAP850_MODE2_OFFSET 0x14
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 traffic controller configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_FLASH_CFG_0 0xfffecc10
+#define OMAP850_FLASH_ACFG_0 0xfffecc50
+#define OMAP850_FLASH_CFG_1 0xfffecc14
+#define OMAP850_FLASH_ACFG_1 0xfffecc54
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 DSP control registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_ICR_BASE 0xfffbb800
+#define OMAP850_DSP_M_CTL 0xfffbb804
+#define OMAP850_DSP_MMU_BASE 0xfffed200
+
+/*
+ * ----------------------------------------------------------------------------
+ * OMAP850 PCC_UPLD configuration registers
+ * ----------------------------------------------------------------------------
+ */
+#define OMAP850_PCC_UPLD_CTRL_BASE (0xfffe0900)
+#define OMAP850_PCC_UPLD_CTRL (OMAP850_PCC_UPLD_CTRL_BASE + 0x00)
+
+#endif /* __ASM_ARCH_OMAP850_H */
+
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
new file mode 100644
index 00000000..e4c349ff
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -0,0 +1,153 @@
+/*
+ * omap_device headers
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Developed in collaboration with (alphabetical order): Benoit
+ * Cousson, Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram
+ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
+ * Woodruff
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Eventually this type of functionality should either be
+ * a) implemented via arch-specific pointers in platform_device
+ * or
+ * b) implemented as a proper omap_bus/omap_device in Linux, no more
+ * platform_device
+ *
+ * omap_device differs from omap_hwmod in that it includes external
+ * (e.g., board- and system-level) integration details. omap_hwmod
+ * stores hardware data that is invariant for a given OMAP chip.
+ *
+ * To do:
+ * - GPIO integration
+ * - regulator integration
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <plat/omap_hwmod.h>
+
+extern struct device omap_device_parent;
+
+/* omap_device._state values */
+#define OMAP_DEVICE_STATE_UNKNOWN 0
+#define OMAP_DEVICE_STATE_ENABLED 1
+#define OMAP_DEVICE_STATE_IDLE 2
+#define OMAP_DEVICE_STATE_SHUTDOWN 3
+
+/**
+ * struct omap_device - omap_device wrapper for platform_devices
+ * @pdev: platform_device
+ * @hwmods: (one .. many per omap_device)
+ * @hwmods_cnt: ARRAY_SIZE() of @hwmods
+ * @pm_lats: ptr to an omap_device_pm_latency table
+ * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
+ * @pm_lat_level: array index of the last odpl entry executed - -1 if never
+ * @dev_wakeup_lat: dev wakeup latency in nanoseconds
+ * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM
+ * @_state: one of OMAP_DEVICE_STATE_* (see above)
+ * @flags: device flags
+ *
+ * Integrates omap_hwmod data into Linux platform_device.
+ *
+ * Field names beginning with underscores are for the internal use of
+ * the omap_device code.
+ *
+ */
+struct omap_device {
+ struct platform_device pdev;
+ struct omap_hwmod **hwmods;
+ struct omap_device_pm_latency *pm_lats;
+ u32 dev_wakeup_lat;
+ u32 _dev_wakeup_lat_limit;
+ u8 pm_lats_cnt;
+ s8 pm_lat_level;
+ u8 hwmods_cnt;
+ u8 _state;
+};
+
+/* Device driver interface (call via platform_data fn ptrs) */
+
+int omap_device_enable(struct platform_device *pdev);
+int omap_device_idle(struct platform_device *pdev);
+int omap_device_shutdown(struct platform_device *pdev);
+
+/* Core code interface */
+
+int omap_device_count_resources(struct omap_device *od);
+int omap_device_fill_resources(struct omap_device *od, struct resource *res);
+
+struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+ struct omap_hwmod *oh, void *pdata,
+ int pdata_len,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt, int is_early_device);
+
+struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+ struct omap_hwmod **oh, int oh_cnt,
+ void *pdata, int pdata_len,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt, int is_early_device);
+
+int omap_device_register(struct omap_device *od);
+int omap_early_device_register(struct omap_device *od);
+
+void __iomem *omap_device_get_rt_va(struct omap_device *od);
+
+/* OMAP PM interface */
+int omap_device_align_pm_lat(struct platform_device *pdev,
+ u32 new_wakeup_lat_limit);
+struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+u32 omap_device_get_context_loss_count(struct platform_device *pdev);
+
+/* Other */
+
+int omap_device_idle_hwmods(struct omap_device *od);
+int omap_device_enable_hwmods(struct omap_device *od);
+
+int omap_device_disable_clocks(struct omap_device *od);
+int omap_device_enable_clocks(struct omap_device *od);
+
+
+/*
+ * Entries should be kept in latency order ascending
+ *
+ * deact_lat is the maximum number of microseconds required to complete
+ * deactivate_func() at the device's slowest OPP.
+ *
+ * act_lat is the maximum number of microseconds required to complete
+ * activate_func() at the device's slowest OPP.
+ *
+ * This will result in some suboptimal power management decisions at fast
+ * OPPs, but avoids having to recompute all device power management decisions
+ * if the system shifts from a fast OPP to a slow OPP (in order to meet
+ * latency requirements).
+ *
+ * XXX should deactivate_func/activate_func() take platform_device pointers
+ * rather than omap_device pointers?
+ */
+struct omap_device_pm_latency {
+ u32 deactivate_lat;
+ u32 deactivate_lat_worst;
+ int (*deactivate_func)(struct omap_device *od);
+ u32 activate_lat;
+ u32 activate_lat_worst;
+ int (*activate_func)(struct omap_device *od);
+ u32 flags;
+};
+
+#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
+
+/* Get omap_device pointer from platform_device pointer */
+#define to_omap_device(x) container_of((x), struct omap_device, pdev)
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
new file mode 100644
index 00000000..1adea9c6
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -0,0 +1,614 @@
+/*
+ * omap_hwmod macros, structures
+ *
+ * Copyright (C) 2009-2011 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Created in collaboration with (alphabetical order): Benoît Cousson,
+ * Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
+ * Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These headers and macros are used to define OMAP on-chip module
+ * data and their integration with other OMAP modules and Linux.
+ * Copious documentation and references can also be found in the
+ * omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this
+ * writing).
+ *
+ * To do:
+ * - add interconnect error log structures
+ * - add pinmuxing
+ * - init_conn_id_bit (CONNID_BIT_VECTOR)
+ * - implement default hwmod SMS/SDRC flags?
+ * - move Linux-specific data ("non-ROM data") out
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+#include <linux/spinlock.h>
+#include <plat/cpu.h>
+
+struct omap_device;
+
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
+extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
+
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant
+ * with the original PRCM protocol defined for OMAP2420
+ */
+#define SYSC_TYPE1_MIDLEMODE_SHIFT 12
+#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
+#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8
+#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
+#define SYSC_TYPE1_SIDLEMODE_SHIFT 3
+#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
+#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2
+#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
+#define SYSC_TYPE1_SOFTRESET_SHIFT 1
+#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
+#define SYSC_TYPE1_AUTOIDLE_SHIFT 0
+#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT)
+
+/*
+ * OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant
+ * with the new PRCM protocol defined for new OMAP4 IPs.
+ */
+#define SYSC_TYPE2_SOFTRESET_SHIFT 0
+#define SYSC_TYPE2_SOFTRESET_MASK (1 << SYSC_TYPE2_SOFTRESET_SHIFT)
+#define SYSC_TYPE2_SIDLEMODE_SHIFT 2
+#define SYSC_TYPE2_SIDLEMODE_MASK (0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT)
+#define SYSC_TYPE2_MIDLEMODE_SHIFT 4
+#define SYSC_TYPE2_MIDLEMODE_MASK (0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT)
+
+/* OCP SYSSTATUS bit shifts/masks */
+#define SYSS_RESETDONE_SHIFT 0
+#define SYSS_RESETDONE_MASK (1 << SYSS_RESETDONE_SHIFT)
+
+/* Master standby/slave idle mode flags */
+#define HWMOD_IDLEMODE_FORCE (1 << 0)
+#define HWMOD_IDLEMODE_NO (1 << 1)
+#define HWMOD_IDLEMODE_SMART (1 << 2)
+/* Slave idle mode flag only */
+#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
+
+/**
+ * struct omap_hwmod_mux_info - hwmod specific mux configuration
+ * @pads: array of omap_device_pad entries
+ * @nr_pads: number of omap_device_pad entries
+ *
+ * Note that this is currently built during init as needed.
+ */
+struct omap_hwmod_mux_info {
+ int nr_pads;
+ struct omap_device_pad *pads;
+ int nr_pads_dynamic;
+ struct omap_device_pad **pads_dynamic;
+ bool enabled;
+};
+
+/**
+ * struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
+ * @name: name of the IRQ channel (module local name)
+ * @irq_ch: IRQ channel ID
+ *
+ * @name should be something short, e.g., "tx" or "rx". It is for use
+ * by platform_get_resource_byname(). It is defined locally to the
+ * hwmod.
+ */
+struct omap_hwmod_irq_info {
+ const char *name;
+ u16 irq;
+};
+
+/**
+ * struct omap_hwmod_dma_info - DMA channels used by the hwmod
+ * @name: name of the DMA channel (module local name)
+ * @dma_req: DMA request ID
+ *
+ * @name should be something short, e.g., "tx" or "rx". It is for use
+ * by platform_get_resource_byname(). It is defined locally to the
+ * hwmod.
+ */
+struct omap_hwmod_dma_info {
+ const char *name;
+ u16 dma_req;
+};
+
+/**
+ * struct omap_hwmod_rst_info - IPs reset lines use by hwmod
+ * @name: name of the reset line (module local name)
+ * @rst_shift: Offset of the reset bit
+ * @st_shift: Offset of the reset status bit (OMAP2/3 only)
+ *
+ * @name should be something short, e.g., "cpu0" or "rst". It is defined
+ * locally to the hwmod.
+ */
+struct omap_hwmod_rst_info {
+ const char *name;
+ u8 rst_shift;
+ u8 st_shift;
+};
+
+/**
+ * struct omap_hwmod_opt_clk - optional clocks used by this hwmod
+ * @role: "sys", "32k", "tv", etc -- for use in clk_get()
+ * @clk: opt clock: OMAP clock name
+ * @_clk: pointer to the struct clk (filled in at runtime)
+ *
+ * The module's interface clock and main functional clock should not
+ * be added as optional clocks.
+ */
+struct omap_hwmod_opt_clk {
+ const char *role;
+ const char *clk;
+ struct clk *_clk;
+};
+
+
+/* omap_hwmod_omap2_firewall.flags bits */
+#define OMAP_FIREWALL_L3 (1 << 0)
+#define OMAP_FIREWALL_L4 (1 << 1)
+
+/**
+ * struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
+ * @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
+ * @l4_fw_region: L4 firewall region ID
+ * @l4_prot_group: L4 protection group ID
+ * @flags: (see omap_hwmod_omap2_firewall.flags macros above)
+ */
+struct omap_hwmod_omap2_firewall {
+ u8 l3_perm_bit;
+ u8 l4_fw_region;
+ u8 l4_prot_group;
+ u8 flags;
+};
+
+
+/*
+ * omap_hwmod_addr_space.flags bits
+ *
+ * ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
+ * ADDR_TYPE_RT: Address space contains module register target data.
+ */
+#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */
+#define ADDR_TYPE_RT (1 << 1)
+
+/**
+ * struct omap_hwmod_addr_space - address space handled by the hwmod
+ * @name: name of the address space
+ * @pa_start: starting physical address
+ * @pa_end: ending physical address
+ * @flags: (see omap_hwmod_addr_space.flags macros above)
+ *
+ * Address space doesn't necessarily follow physical interconnect
+ * structure. GPMC is one example.
+ */
+struct omap_hwmod_addr_space {
+ const char *name;
+ u32 pa_start;
+ u32 pa_end;
+ u8 flags;
+};
+
+
+/*
+ * omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
+ * interface to interact with the hwmod. Used to add sleep dependencies
+ * when the module is enabled or disabled.
+ */
+#define OCP_USER_MPU (1 << 0)
+#define OCP_USER_SDMA (1 << 1)
+
+/* omap_hwmod_ocp_if.flags bits */
+#define OCPIF_SWSUP_IDLE (1 << 0)
+#define OCPIF_CAN_BURST (1 << 1)
+
+/**
+ * struct omap_hwmod_ocp_if - OCP interface data
+ * @master: struct omap_hwmod that initiates OCP transactions on this link
+ * @slave: struct omap_hwmod that responds to OCP transactions on this link
+ * @addr: address space associated with this link
+ * @clk: interface clock: OMAP clock name
+ * @_clk: pointer to the interface struct clk (filled in at runtime)
+ * @fw: interface firewall data
+ * @addr_cnt: ARRAY_SIZE(@addr)
+ * @width: OCP data width
+ * @user: initiators using this interface (see OCP_USER_* macros above)
+ * @flags: OCP interface flags (see OCPIF_* macros above)
+ *
+ * It may also be useful to add a tag_cnt field for OCP2.x devices.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod_ocp_if {
+ struct omap_hwmod *master;
+ struct omap_hwmod *slave;
+ struct omap_hwmod_addr_space *addr;
+ const char *clk;
+ struct clk *_clk;
+ union {
+ struct omap_hwmod_omap2_firewall omap2;
+ } fw;
+ u8 addr_cnt;
+ u8 width;
+ u8 user;
+ u8 flags;
+};
+
+
+/* Macros for use in struct omap_hwmod_sysconfig */
+
+/* Flags for use in omap_hwmod_sysconfig.idlemodes */
+#define MASTER_STANDBY_SHIFT 4
+#define SLAVE_IDLE_SHIFT 0
+#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
+#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
+#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT)
+#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
+#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
+
+/* omap_hwmod_sysconfig.sysc_flags capability flags */
+#define SYSC_HAS_AUTOIDLE (1 << 0)
+#define SYSC_HAS_SOFTRESET (1 << 1)
+#define SYSC_HAS_ENAWAKEUP (1 << 2)
+#define SYSC_HAS_EMUFREE (1 << 3)
+#define SYSC_HAS_CLOCKACTIVITY (1 << 4)
+#define SYSC_HAS_SIDLEMODE (1 << 5)
+#define SYSC_HAS_MIDLEMODE (1 << 6)
+#define SYSS_HAS_RESET_STATUS (1 << 7)
+#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
+#define SYSC_HAS_RESET_STATUS (1 << 9)
+
+/* omap_hwmod_sysconfig.clockact flags */
+#define CLOCKACT_TEST_BOTH 0x0
+#define CLOCKACT_TEST_MAIN 0x1
+#define CLOCKACT_TEST_ICLK 0x2
+#define CLOCKACT_TEST_NONE 0x3
+
+/**
+ * struct omap_hwmod_sysc_fields - hwmod OCP_SYSCONFIG register field offsets.
+ * @midle_shift: Offset of the midle bit
+ * @clkact_shift: Offset of the clockactivity bit
+ * @sidle_shift: Offset of the sidle bit
+ * @enwkup_shift: Offset of the enawakeup bit
+ * @srst_shift: Offset of the softreset bit
+ * @autoidle_shift: Offset of the autoidle bit
+ */
+struct omap_hwmod_sysc_fields {
+ u8 midle_shift;
+ u8 clkact_shift;
+ u8 sidle_shift;
+ u8 enwkup_shift;
+ u8 srst_shift;
+ u8 autoidle_shift;
+};
+
+/**
+ * struct omap_hwmod_class_sysconfig - hwmod class OCP_SYS* data
+ * @rev_offs: IP block revision register offset (from module base addr)
+ * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
+ * @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
+ * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
+ * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
+ * @clockact: the default value of the module CLOCKACTIVITY bits
+ *
+ * @clockact describes to the module which clocks are likely to be
+ * disabled when the PRCM issues its idle request to the module. Some
+ * modules have separate clockdomains for the interface clock and main
+ * functional clock, and can check whether they should acknowledge the
+ * idle request based on the internal module functionality that has
+ * been associated with the clocks marked in @clockact. This field is
+ * only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
+ *
+ * @sysc_fields: structure containing the offset positions of various bits in
+ * SYSCONFIG register. This can be populated using omap_hwmod_sysc_type1 or
+ * omap_hwmod_sysc_type2 defined in omap_hwmod_common_data.c depending on
+ * whether the device ip is compliant with the original PRCM protocol
+ * defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs.
+ * If the device follows a different scheme for the sysconfig register ,
+ * then this field has to be populated with the correct offset structure.
+ */
+struct omap_hwmod_class_sysconfig {
+ u16 rev_offs;
+ u16 sysc_offs;
+ u16 syss_offs;
+ u16 sysc_flags;
+ u8 idlemodes;
+ u8 clockact;
+ struct omap_hwmod_sysc_fields *sysc_fields;
+};
+
+/**
+ * struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
+ * @module_offs: PRCM submodule offset from the start of the PRM/CM
+ * @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
+ * @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
+ * @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
+ * @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
+ * @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
+ *
+ * @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
+ * WKEN, GRPSEL registers. In an ideal world, no extra information
+ * would be needed for IDLEST information, but alas, there are some
+ * exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
+ * are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
+ */
+struct omap_hwmod_omap2_prcm {
+ s16 module_offs;
+ u8 prcm_reg_id;
+ u8 module_bit;
+ u8 idlest_reg_id;
+ u8 idlest_idle_bit;
+ u8 idlest_stdby_bit;
+};
+
+
+/**
+ * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
+ * @clkctrl_reg: PRCM address of the clock control register
+ * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM
+ * @submodule_wkdep_bit: bit shift of the WKDEP range
+ */
+struct omap_hwmod_omap4_prcm {
+ void __iomem *clkctrl_reg;
+ void __iomem *rstctrl_reg;
+ u8 submodule_wkdep_bit;
+};
+
+
+/*
+ * omap_hwmod.flags definitions
+ *
+ * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
+ * of idle, rather than relying on module smart-idle
+ * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out
+ * of standby, rather than relying on module smart-standby
+ * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
+ * SDRAM controller, etc. XXX probably belongs outside the main hwmod file
+ * XXX Should be HWMOD_SETUP_NO_RESET
+ * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
+ * controller, etc. XXX probably belongs outside the main hwmod file
+ * XXX Should be HWMOD_SETUP_NO_IDLE
+ * HWMOD_NO_OCP_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
+ * when module is enabled, rather than the default, which is to
+ * enable autoidle
+ * HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
+ * HWMOD_NO_IDLEST: this module does not have idle status - this is the case
+ * only for few initiator modules on OMAP2 & 3.
+ * HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
+ * This is needed for devices like DSS that require optional clocks enabled
+ * in order to complete the reset. Optional clocks will be disabled
+ * again after the reset.
+ * HWMOD_16BIT_REG: Module has 16bit registers
+ */
+#define HWMOD_SWSUP_SIDLE (1 << 0)
+#define HWMOD_SWSUP_MSTANDBY (1 << 1)
+#define HWMOD_INIT_NO_RESET (1 << 2)
+#define HWMOD_INIT_NO_IDLE (1 << 3)
+#define HWMOD_NO_OCP_AUTOIDLE (1 << 4)
+#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5)
+#define HWMOD_NO_IDLEST (1 << 6)
+#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
+#define HWMOD_16BIT_REG (1 << 8)
+
+/*
+ * omap_hwmod._int_flags definitions
+ * These are for internal use only and are managed by the omap_hwmod code.
+ *
+ * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
+ * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
+ * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
+ */
+#define _HWMOD_NO_MPU_PORT (1 << 0)
+#define _HWMOD_WAKEUP_ENABLED (1 << 1)
+#define _HWMOD_SYSCONFIG_LOADED (1 << 2)
+
+/*
+ * omap_hwmod._state definitions
+ *
+ * INITIALIZED: reset (optionally), initialized, enabled, disabled
+ * (optionally)
+ *
+ *
+ */
+#define _HWMOD_STATE_UNKNOWN 0
+#define _HWMOD_STATE_REGISTERED 1
+#define _HWMOD_STATE_CLKS_INITED 2
+#define _HWMOD_STATE_INITIALIZED 3
+#define _HWMOD_STATE_ENABLED 4
+#define _HWMOD_STATE_IDLE 5
+#define _HWMOD_STATE_DISABLED 6
+
+/**
+ * struct omap_hwmod_class - the type of an IP block
+ * @name: name of the hwmod_class
+ * @sysc: device SYSCONFIG/SYSSTATUS register data
+ * @rev: revision of the IP class
+ * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
+ * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
+ *
+ * Represent the class of a OMAP hardware "modules" (e.g. timer,
+ * smartreflex, gpio, uart...)
+ *
+ * @pre_shutdown is a function that will be run immediately before
+ * hwmod clocks are disabled, etc. It is intended for use for hwmods
+ * like the MPU watchdog, which cannot be disabled with the standard
+ * omap_hwmod_shutdown(). The function should return 0 upon success,
+ * or some negative error upon failure. Returning an error will cause
+ * omap_hwmod_shutdown() to abort the device shutdown and return an
+ * error.
+ *
+ * If @reset is defined, then the function it points to will be
+ * executed in place of the standard hwmod _reset() code in
+ * mach-omap2/omap_hwmod.c. This is needed for IP blocks which have
+ * unusual reset sequences - usually processor IP blocks like the IVA.
+ */
+struct omap_hwmod_class {
+ const char *name;
+ struct omap_hwmod_class_sysconfig *sysc;
+ u32 rev;
+ int (*pre_shutdown)(struct omap_hwmod *oh);
+ int (*reset)(struct omap_hwmod *oh);
+};
+
+/**
+ * struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
+ * @name: name of the hwmod
+ * @class: struct omap_hwmod_class * to the class of this hwmod
+ * @od: struct omap_device currently associated with this hwmod (internal use)
+ * @mpu_irqs: ptr to an array of MPU IRQs (see also mpu_irqs_cnt)
+ * @sdma_reqs: ptr to an array of System DMA request IDs (see sdma_reqs_cnt)
+ * @prcm: PRCM data pertaining to this hwmod
+ * @main_clk: main clock: OMAP clock name
+ * @_clk: pointer to the main struct clk (filled in at runtime)
+ * @opt_clks: other device clocks that drivers can request (0..*)
+ * @vdd_name: voltage domain name
+ * @voltdm: pointer to voltage domain (filled in at runtime)
+ * @masters: ptr to array of OCP ifs that this hwmod can initiate on
+ * @slaves: ptr to array of OCP ifs that this hwmod can respond on
+ * @dev_attr: arbitrary device attributes that can be passed to the driver
+ * @_sysc_cache: internal-use hwmod flags
+ * @_mpu_rt_va: cached register target start address (internal use)
+ * @_mpu_port_index: cached MPU register target slave ID (internal use)
+ * @mpu_irqs_cnt: number of @mpu_irqs
+ * @sdma_reqs_cnt: number of @sdma_reqs
+ * @opt_clks_cnt: number of @opt_clks
+ * @master_cnt: number of @master entries
+ * @slaves_cnt: number of @slave entries
+ * @response_lat: device OCP response latency (in interface clock cycles)
+ * @_int_flags: internal-use hwmod flags
+ * @_state: internal-use hwmod state
+ * @_postsetup_state: internal-use state to leave the hwmod in after _setup()
+ * @flags: hwmod flags (documented below)
+ * @omap_chip: OMAP chips this hwmod is present on
+ * @_lock: spinlock serializing operations on this hwmod
+ * @node: list node for hwmod list (internal use)
+ *
+ * @main_clk refers to this module's "main clock," which for our
+ * purposes is defined as "the functional clock needed for register
+ * accesses to complete." Modules may not have a main clock if the
+ * interface clock also serves as a main clock.
+ *
+ * Parameter names beginning with an underscore are managed internally by
+ * the omap_hwmod code and should not be set during initialization.
+ */
+struct omap_hwmod {
+ const char *name;
+ struct omap_hwmod_class *class;
+ struct omap_device *od;
+ struct omap_hwmod_mux_info *mux;
+ struct omap_hwmod_irq_info *mpu_irqs;
+ struct omap_hwmod_dma_info *sdma_reqs;
+ struct omap_hwmod_rst_info *rst_lines;
+ union {
+ struct omap_hwmod_omap2_prcm omap2;
+ struct omap_hwmod_omap4_prcm omap4;
+ } prcm;
+ const char *main_clk;
+ struct clk *_clk;
+ struct omap_hwmod_opt_clk *opt_clks;
+ char *vdd_name;
+ struct voltagedomain *voltdm;
+ struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
+ struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
+ void *dev_attr;
+ u32 _sysc_cache;
+ void __iomem *_mpu_rt_va;
+ spinlock_t _lock;
+ struct list_head node;
+ u16 flags;
+ u8 _mpu_port_index;
+ u8 response_lat;
+ u8 mpu_irqs_cnt;
+ u8 sdma_reqs_cnt;
+ u8 rst_lines_cnt;
+ u8 opt_clks_cnt;
+ u8 masters_cnt;
+ u8 slaves_cnt;
+ u8 hwmods_cnt;
+ u8 _int_flags;
+ u8 _state;
+ u8 _postsetup_state;
+ const struct omap_chip_id omap_chip;
+};
+
+int omap_hwmod_register(struct omap_hwmod **ohs);
+struct omap_hwmod *omap_hwmod_lookup(const char *name);
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+ void *data);
+
+int __init omap_hwmod_setup_one(const char *name);
+
+int omap_hwmod_enable(struct omap_hwmod *oh);
+int _omap_hwmod_enable(struct omap_hwmod *oh);
+int omap_hwmod_idle(struct omap_hwmod *oh);
+int _omap_hwmod_idle(struct omap_hwmod *oh);
+int omap_hwmod_shutdown(struct omap_hwmod *oh);
+
+int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
+int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
+int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
+
+int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
+int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
+
+int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode);
+int omap_hwmod_set_ocp_autoidle(struct omap_hwmod *oh, u8 autoidle);
+
+int omap_hwmod_reset(struct omap_hwmod *oh);
+void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
+
+void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
+u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
+
+int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
+
+struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
+
+int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
+ struct omap_hwmod *init_oh);
+int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
+ struct omap_hwmod *init_oh);
+
+int omap_hwmod_set_clockact_both(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_main(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_iclk(struct omap_hwmod *oh);
+int omap_hwmod_set_clockact_none(struct omap_hwmod *oh);
+
+int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
+int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
+
+int omap_hwmod_for_each_by_class(const char *classname,
+ int (*fn)(struct omap_hwmod *oh,
+ void *user),
+ void *user);
+
+int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
+u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
+
+int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
+
+/*
+ * Chip variant-specific hwmod init routines - XXX should be converted
+ * to use initcalls once the initial boot ordering is straightened out
+ */
+extern int omap2420_hwmod_init(void);
+extern int omap2430_hwmod_init(void);
+extern int omap3xxx_hwmod_init(void);
+extern int omap44xx_hwmod_init(void);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/onenand.h b/arch/arm/plat-omap/include/plat/onenand.h
new file mode 100644
index 00000000..2858667d
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/onenand.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/plat-omap/include/mach/onenand.h
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Juha Yrjola
+ *
+ * This program is free software; you can 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/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#define ONENAND_SYNC_READ (1 << 0)
+#define ONENAND_SYNC_READWRITE (1 << 1)
+
+struct onenand_freq_info {
+ u16 maf_id;
+ u16 dev_id;
+ u16 ver_id;
+};
+
+struct omap_onenand_platform_data {
+ int cs;
+ int gpio_irq;
+ struct mtd_partition *parts;
+ int nr_parts;
+ int (*onenand_setup)(void __iomem *, int *freq_ptr);
+ int (*get_freq)(const struct onenand_freq_info *freq_info,
+ bool *clk_dep);
+ int dma_channel;
+ u8 flags;
+ u8 regulator_can_sleep;
+ u8 skip_initial_unlocking;
+};
+
+#define ONENAND_MAX_PARTITIONS 8
+
+#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
+
+extern void gpmc_onenand_init(struct omap_onenand_platform_data *d);
+
+#else
+
+#define board_onenand_data NULL
+
+static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d)
+{
+}
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/param.h b/arch/arm/plat-omap/include/plat/param.h
new file mode 100644
index 00000000..1eb4dc32
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/param.h
@@ -0,0 +1,8 @@
+/*
+ * arch/arm/plat-omap/include/mach/param.h
+ *
+ */
+
+#ifdef CONFIG_OMAP_32K_TIMER_HZ
+#define HZ CONFIG_OMAP_32K_TIMER_HZ
+#endif
diff --git a/arch/arm/plat-omap/include/plat/prcm.h b/arch/arm/plat-omap/include/plat/prcm.h
new file mode 100644
index 00000000..267f43bb
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/prcm.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/plat-omap/include/mach/prcm.h
+ *
+ * Access definations for use in OMAP24XX clock and power management
+ *
+ * Copyright (C) 2005 Texas Instruments, 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
+ *
+ * XXX This file is deprecated. The PRCM is an OMAP2+-only subsystem,
+ * so this file doesn't belong in plat-omap/include/plat. Please
+ * do not add anything new to this file.
+ */
+
+#ifndef __ASM_ARM_ARCH_OMAP_PRCM_H
+#define __ASM_ARM_ARCH_OMAP_PRCM_H
+
+u32 omap_prcm_get_reset_sources(void);
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest,
+ const char *name);
+
+#endif
+
+
+
diff --git a/arch/arm/plat-omap/include/plat/sdrc.h b/arch/arm/plat-omap/include/plat/sdrc.h
new file mode 100644
index 00000000..925b12b5
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/sdrc.h
@@ -0,0 +1,165 @@
+#ifndef ____ASM_ARCH_SDRC_H
+#define ____ASM_ARCH_SDRC_H
+
+/*
+ * OMAP2/3 SDRC/SMS register definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Tony Lindgren
+ * Paul Walmsley
+ * Richard Woodruff
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <mach/io.h>
+
+/* SDRC register offsets - read/write with sdrc_{read,write}_reg() */
+
+#define SDRC_SYSCONFIG 0x010
+#define SDRC_CS_CFG 0x040
+#define SDRC_SHARING 0x044
+#define SDRC_ERR_TYPE 0x04C
+#define SDRC_DLLA_CTRL 0x060
+#define SDRC_DLLA_STATUS 0x064
+#define SDRC_DLLB_CTRL 0x068
+#define SDRC_DLLB_STATUS 0x06C
+#define SDRC_POWER 0x070
+#define SDRC_MCFG_0 0x080
+#define SDRC_MR_0 0x084
+#define SDRC_EMR2_0 0x08c
+#define SDRC_ACTIM_CTRL_A_0 0x09c
+#define SDRC_ACTIM_CTRL_B_0 0x0a0
+#define SDRC_RFR_CTRL_0 0x0a4
+#define SDRC_MANUAL_0 0x0a8
+#define SDRC_MCFG_1 0x0B0
+#define SDRC_MR_1 0x0B4
+#define SDRC_EMR2_1 0x0BC
+#define SDRC_ACTIM_CTRL_A_1 0x0C4
+#define SDRC_ACTIM_CTRL_B_1 0x0C8
+#define SDRC_RFR_CTRL_1 0x0D4
+#define SDRC_MANUAL_1 0x0D8
+
+#define SDRC_POWER_AUTOCOUNT_SHIFT 8
+#define SDRC_POWER_AUTOCOUNT_MASK (0xffff << SDRC_POWER_AUTOCOUNT_SHIFT)
+#define SDRC_POWER_CLKCTRL_SHIFT 4
+#define SDRC_POWER_CLKCTRL_MASK (0x3 << SDRC_POWER_CLKCTRL_SHIFT)
+#define SDRC_SELF_REFRESH_ON_AUTOCOUNT (0x2 << SDRC_POWER_CLKCTRL_SHIFT)
+
+/*
+ * These values represent the number of memory clock cycles between
+ * autorefresh initiation. They assume 1 refresh per 64 ms (JEDEC), 8192
+ * rows per device, and include a subtraction of a 50 cycle window in the
+ * event that the autorefresh command is delayed due to other SDRC activity.
+ * The '| 1' sets the ARE field to send one autorefresh when the autorefresh
+ * counter reaches 0.
+ *
+ * These represent optimal values for common parts, it won't work for all.
+ * As long as you scale down, most parameters are still work, they just
+ * become sub-optimal. The RFR value goes in the opposite direction. If you
+ * don't adjust it down as your clock period increases the refresh interval
+ * will not be met. Setting all parameters for complete worst case may work,
+ * but may cut memory performance by 2x. Due to errata the DLLs need to be
+ * unlocked and their value needs run time calibration. A dynamic call is
+ * need for that as no single right value exists acorss production samples.
+ *
+ * Only the FULL speed values are given. Current code is such that rate
+ * changes must be made at DPLLoutx2. The actual value adjustment for low
+ * frequency operation will be handled by omap_set_performance()
+ *
+ * By having the boot loader boot up in the fastest L4 speed available likely
+ * will result in something which you can switch between.
+ */
+#define SDRC_RFR_CTRL_165MHz (0x00044c00 | 1)
+#define SDRC_RFR_CTRL_133MHz (0x0003de00 | 1)
+#define SDRC_RFR_CTRL_100MHz (0x0002da01 | 1)
+#define SDRC_RFR_CTRL_110MHz (0x0002da01 | 1) /* Need to calc */
+#define SDRC_RFR_CTRL_BYPASS (0x00005000 | 1) /* Need to calc */
+
+
+/*
+ * SMS register access
+ */
+
+#define OMAP242X_SMS_REGADDR(reg) \
+ (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg) \
+ (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg) \
+ (void __iomem *)OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+
+/* SMS register offsets - read/write with sms_{read,write}_reg() */
+
+#define SMS_SYSCONFIG 0x010
+#define SMS_ROT_CONTROL(context) (0x180 + 0x10 * context)
+#define SMS_ROT_SIZE(context) (0x184 + 0x10 * context)
+#define SMS_ROT_PHYSICAL_BA(context) (0x188 + 0x10 * context)
+/* REVISIT: fill in other SMS registers here */
+
+
+#ifndef __ASSEMBLER__
+
+/**
+ * struct omap_sdrc_params - SDRC parameters for a given SDRC clock rate
+ * @rate: SDRC clock rate (in Hz)
+ * @actim_ctrla: Value to program to SDRC_ACTIM_CTRLA for this rate
+ * @actim_ctrlb: Value to program to SDRC_ACTIM_CTRLB for this rate
+ * @rfr_ctrl: Value to program to SDRC_RFR_CTRL for this rate
+ * @mr: Value to program to SDRC_MR for this rate
+ *
+ * This structure holds a pre-computed set of register values for the
+ * SDRC for a given SDRC clock rate and SDRAM chip. These are
+ * intended to be pre-computed and specified in an array in the board-*.c
+ * files. The structure is keyed off the 'rate' field.
+ */
+struct omap_sdrc_params {
+ unsigned long rate;
+ u32 actim_ctrla;
+ u32 actim_ctrlb;
+ u32 rfr_ctrl;
+ u32 mr;
+};
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+void omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1);
+#else
+static inline void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+ struct omap_sdrc_params *sdrc_cs1) {};
+#endif
+
+int omap2_sdrc_get_params(unsigned long r,
+ struct omap_sdrc_params **sdrc_cs0,
+ struct omap_sdrc_params **sdrc_cs1);
+void omap2_sms_save_context(void);
+void omap2_sms_restore_context(void);
+
+void omap2_sms_write_rot_control(u32 val, unsigned ctx);
+void omap2_sms_write_rot_size(u32 val, unsigned ctx);
+void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx);
+
+#ifdef CONFIG_ARCH_OMAP2
+
+struct memory_timings {
+ u32 m_type; /* ddr = 1, sdr = 0 */
+ u32 dll_mode; /* use lock mode = 1, unlock mode = 0 */
+ u32 slow_dll_ctrl; /* unlock mode, dll value for slow speed */
+ u32 fast_dll_ctrl; /* unlock mode, dll value for fast speed */
+ u32 base_cs; /* base chip select to use for calculations */
+};
+
+extern void omap2xxx_sdrc_init_params(u32 force_lock_to_unlock_mode);
+struct omap_sdrc_params *rx51_get_sdram_timings(void);
+
+u32 omap2xxx_sdrc_dll_is_unlocked(void);
+u32 omap2xxx_sdrc_reprogram(u32 level, u32 force);
+
+#endif /* CONFIG_ARCH_OMAP2 */
+
+#endif /* __ASSEMBLER__ */
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
new file mode 100644
index 00000000..2723f916
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/plat-omap/include/mach/serial.h
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Addded OMAP4 support- Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#include <linux/init.h>
+
+/*
+ * Memory entry used for the DEBUG_LL UART configuration. See also
+ * uncompress.h and debug-macro.S.
+ *
+ * Note that using a memory location for storing the UART configuration
+ * has at least two limitations:
+ *
+ * 1. Kernel uncompress code cannot overlap OMAP_UART_INFO as the
+ * uncompress code could then partially overwrite itself
+ * 2. We assume printascii is called at least once before paging_init,
+ * and addruart has a chance to read OMAP_UART_INFO
+ */
+#define OMAP_UART_INFO (PLAT_PHYS_OFFSET + 0x3ffc)
+
+/* OMAP1 serial ports */
+#define OMAP1_UART1_BASE 0xfffb0000
+#define OMAP1_UART2_BASE 0xfffb0800
+#define OMAP1_UART3_BASE 0xfffb9800
+
+/* OMAP2 serial ports */
+#define OMAP2_UART1_BASE 0x4806a000
+#define OMAP2_UART2_BASE 0x4806c000
+#define OMAP2_UART3_BASE 0x4806e000
+
+/* OMAP3 serial ports */
+#define OMAP3_UART1_BASE OMAP2_UART1_BASE
+#define OMAP3_UART2_BASE OMAP2_UART2_BASE
+#define OMAP3_UART3_BASE 0x49020000
+#define OMAP3_UART4_BASE 0x49042000 /* Only on 36xx */
+
+/* OMAP4 serial ports */
+#define OMAP4_UART1_BASE OMAP2_UART1_BASE
+#define OMAP4_UART2_BASE OMAP2_UART2_BASE
+#define OMAP4_UART3_BASE 0x48020000
+#define OMAP4_UART4_BASE 0x4806e000
+
+/* TI816X serial ports */
+#define TI816X_UART1_BASE 0x48020000
+#define TI816X_UART2_BASE 0x48022000
+#define TI816X_UART3_BASE 0x48024000
+
+/* External port on Zoom2/3 */
+#define ZOOM_UART_BASE 0x10000000
+#define ZOOM_UART_VIRT 0xfa400000
+
+#define OMAP_PORT_SHIFT 2
+#define OMAP7XX_PORT_SHIFT 0
+#define ZOOM_PORT_SHIFT 1
+
+#define OMAP1510_BASE_BAUD (12000000/16)
+#define OMAP16XX_BASE_BAUD (48000000/16)
+#define OMAP24XX_BASE_BAUD (48000000/16)
+
+/*
+ * DEBUG_LL port encoding stored into the UART1 scratchpad register by
+ * decomp_setup in uncompress.h
+ */
+#define OMAP1UART1 11
+#define OMAP1UART2 12
+#define OMAP1UART3 13
+#define OMAP2UART1 21
+#define OMAP2UART2 22
+#define OMAP2UART3 23
+#define OMAP3UART1 OMAP2UART1
+#define OMAP3UART2 OMAP2UART2
+#define OMAP3UART3 33
+#define OMAP3UART4 34 /* Only on 36xx */
+#define OMAP4UART1 OMAP2UART1
+#define OMAP4UART2 OMAP2UART2
+#define OMAP4UART3 43
+#define OMAP4UART4 44
+#define TI816XUART1 81
+#define TI816XUART2 82
+#define TI816XUART3 83
+#define ZOOM_UART 95 /* Only on zoom2/3 */
+
+/* This is only used by 8250.c for omap1510 */
+#define is_omap_port(pt) ({int __ret = 0; \
+ if ((pt)->port.mapbase == OMAP1_UART1_BASE || \
+ (pt)->port.mapbase == OMAP1_UART2_BASE || \
+ (pt)->port.mapbase == OMAP1_UART3_BASE) \
+ __ret = 1; \
+ __ret; \
+ })
+
+#ifndef __ASSEMBLER__
+
+struct omap_board_data;
+
+extern void omap_serial_init(void);
+extern void omap_serial_init_port(struct omap_board_data *bdata);
+extern int omap_uart_can_sleep(void);
+extern void omap_uart_check_wakeup(void);
+extern void omap_uart_prepare_suspend(void);
+extern void omap_uart_prepare_idle(int num);
+extern void omap_uart_resume_idle(int num);
+extern void omap_uart_enable_irqs(int enable);
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
new file mode 100644
index 00000000..f500fc34
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -0,0 +1,100 @@
+/*
+ * arch/arm/plat-omap/include/mach/sram.h
+ *
+ * Interface for functions that need to be run in internal SRAM
+ *
+ * This program is free software; you can 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_OMAP_SRAM_H
+#define __ARCH_ARM_OMAP_SRAM_H
+
+#ifndef __ASSEMBLY__
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ \
+ typeof(&(funcp)) _res = NULL; \
+ void *_sram_address = omap_sram_push_address(size); \
+ if (_sram_address) \
+ _res = fncpy(_sram_address, &(funcp), size); \
+ _res; \
+})
+
+extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
+
+extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+extern u32 omap3_configure_core_dpll(
+ u32 m2, u32 unlock_dll, u32 f, u32 inc,
+ u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+ u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+ u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+ u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+extern void omap3_sram_restore_context(void);
+
+/* Do not use these */
+extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap1_sram_reprogram_clock_sz;
+
+extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
+extern unsigned long omap24xx_sram_reprogram_clock_sz;
+
+extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern unsigned long omap242x_sram_ddr_init_sz;
+
+extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+ int bypass);
+extern unsigned long omap242x_sram_set_prcm_sz;
+
+extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern unsigned long omap242x_sram_reprogram_sdrc_sz;
+
+
+extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+extern unsigned long omap243x_sram_ddr_init_sz;
+
+extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val,
+ int bypass);
+extern unsigned long omap243x_sram_set_prcm_sz;
+
+extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+extern unsigned long omap243x_sram_reprogram_sdrc_sz;
+
+extern u32 omap3_sram_configure_core_dpll(
+ u32 m2, u32 unlock_dll, u32 f, u32 inc,
+ u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+ u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+ u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+ u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+extern unsigned long omap3_sram_configure_core_dpll_sz;
+
+#ifdef CONFIG_PM
+extern void omap_push_sram_idle(void);
+#else
+static inline void omap_push_sram_idle(void) {}
+#endif /* CONFIG_PM */
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * OMAP2+: define the SRAM PA addresses.
+ * Used by the SRAM management code and the idle sleep code.
+ */
+#define OMAP2_SRAM_PA 0x40200000
+#define OMAP3_SRAM_PA 0x40200000
+#define OMAP4_SRAM_PA 0x40300000
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h
new file mode 100644
index 00000000..c5fa9e92
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/system.h
@@ -0,0 +1,17 @@
+/*
+ * Copied from arch/arm/mach-sa1100/include/mach/system.h
+ * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
+ */
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <asm/proc-fns.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+extern void (*arch_reset)(char, const char *);
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/tc.h b/arch/arm/plat-omap/include/plat/tc.h
new file mode 100644
index 00000000..d2fcd789
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/tc.h
@@ -0,0 +1,106 @@
+/*
+ * arch/arm/plat-omap/include/mach/tc.h
+ *
+ * OMAP Traffic Controller
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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 __ASM_ARCH_TC_H
+#define __ASM_ARCH_TC_H
+
+#define TCMIF_BASE 0xfffecc00
+#define OMAP_TC_OCPT1_PRIOR (TCMIF_BASE + 0x00)
+#define OMAP_TC_EMIFS_PRIOR (TCMIF_BASE + 0x04)
+#define OMAP_TC_EMIFF_PRIOR (TCMIF_BASE + 0x08)
+#define EMIFS_CONFIG (TCMIF_BASE + 0x0c)
+#define EMIFS_CS0_CONFIG (TCMIF_BASE + 0x10)
+#define EMIFS_CS1_CONFIG (TCMIF_BASE + 0x14)
+#define EMIFS_CS2_CONFIG (TCMIF_BASE + 0x18)
+#define EMIFS_CS3_CONFIG (TCMIF_BASE + 0x1c)
+#define EMIFF_SDRAM_CONFIG (TCMIF_BASE + 0x20)
+#define EMIFF_MRS (TCMIF_BASE + 0x24)
+#define TC_TIMEOUT1 (TCMIF_BASE + 0x28)
+#define TC_TIMEOUT2 (TCMIF_BASE + 0x2c)
+#define TC_TIMEOUT3 (TCMIF_BASE + 0x30)
+#define TC_ENDIANISM (TCMIF_BASE + 0x34)
+#define EMIFF_SDRAM_CONFIG_2 (TCMIF_BASE + 0x3c)
+#define EMIF_CFG_DYNAMIC_WS (TCMIF_BASE + 0x40)
+#define EMIFS_ACS0 (TCMIF_BASE + 0x50)
+#define EMIFS_ACS1 (TCMIF_BASE + 0x54)
+#define EMIFS_ACS2 (TCMIF_BASE + 0x58)
+#define EMIFS_ACS3 (TCMIF_BASE + 0x5c)
+#define OMAP_TC_OCPT2_PRIOR (TCMIF_BASE + 0xd0)
+
+/* external EMIFS chipselect regions */
+#define OMAP_CS0_PHYS 0x00000000
+#define OMAP_CS0_SIZE SZ_64M
+
+#define OMAP_CS1_PHYS 0x04000000
+#define OMAP_CS1_SIZE SZ_64M
+
+#define OMAP_CS1A_PHYS OMAP_CS1_PHYS
+#define OMAP_CS1A_SIZE SZ_32M
+
+#define OMAP_CS1B_PHYS (OMAP_CS1A_PHYS + OMAP_CS1A_SIZE)
+#define OMAP_CS1B_SIZE SZ_32M
+
+#define OMAP_CS2_PHYS 0x08000000
+#define OMAP_CS2_SIZE SZ_64M
+
+#define OMAP_CS2A_PHYS OMAP_CS2_PHYS
+#define OMAP_CS2A_SIZE SZ_32M
+
+#define OMAP_CS2B_PHYS (OMAP_CS2A_PHYS + OMAP_CS2A_SIZE)
+#define OMAP_CS2B_SIZE SZ_32M
+
+#define OMAP_CS3_PHYS 0x0c000000
+#define OMAP_CS3_SIZE SZ_64M
+
+#ifndef __ASSEMBLER__
+
+/* EMIF Slow Interface Configuration Register */
+#define OMAP_EMIFS_CONFIG_FR (1 << 4)
+#define OMAP_EMIFS_CONFIG_PDE (1 << 3)
+#define OMAP_EMIFS_CONFIG_PWD_EN (1 << 2)
+#define OMAP_EMIFS_CONFIG_BM (1 << 1)
+#define OMAP_EMIFS_CONFIG_WP (1 << 0)
+
+#define EMIFS_CCS(n) (EMIFS_CS0_CONFIG + (4 * (n)))
+#define EMIFS_ACS(n) (EMIFS_ACS0 + (4 * (n)))
+
+/* Almost all documentation for chip and board memory maps assumes
+ * BM is clear. Most devel boards have a switch to control booting
+ * from NOR flash (using external chipselect 3) rather than mask ROM,
+ * which uses BM to interchange the physical CS0 and CS3 addresses.
+ */
+static inline u32 omap_cs0_phys(void)
+{
+ return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+ ? OMAP_CS3_PHYS : 0;
+}
+
+static inline u32 omap_cs3_phys(void)
+{
+ return (omap_readl(EMIFS_CONFIG) & OMAP_EMIFS_CONFIG_BM)
+ ? 0 : OMAP_CS3_PHYS;
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __ASM_ARCH_TC_H */
diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti816x.h
new file mode 100644
index 00000000..50510f5d
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/ti816x.h
@@ -0,0 +1,27 @@
+/*
+ * This file contains the address data for various TI816X modules.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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 __ASM_ARCH_TI816X_H
+#define __ASM_ARCH_TI816X_H
+
+#define L4_SLOW_TI816X_BASE 0x48000000
+
+#define TI816X_SCM_BASE 0x48140000
+#define TI816X_CTRL_BASE TI816X_SCM_BASE
+#define TI816X_PRCM_BASE 0x48180000
+
+#define TI816X_ARM_INTC_BASE 0x48200000
+
+#endif /* __ASM_ARCH_TI816X_H */
diff --git a/arch/arm/plat-omap/include/plat/timex.h b/arch/arm/plat-omap/include/plat/timex.h
new file mode 100644
index 00000000..6d35767b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/timex.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/plat-omap/include/mach/timex.h
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.
+ */
+
+#if !defined(__ASM_ARCH_OMAP_TIMEX_H)
+#define __ASM_ARCH_OMAP_TIMEX_H
+
+/*
+ * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer,
+ * and that's why the CLOCK_TICK_RATE is not 32768.
+ */
+#ifdef CONFIG_OMAP_32K_TIMER
+#define CLOCK_TICK_RATE (CONFIG_OMAP_32K_TIMER_HZ)
+#else
+#define CLOCK_TICK_RATE (HZ * 100000UL)
+#endif
+
+#endif /* __ASM_ARCH_OMAP_TIMEX_H */
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
new file mode 100644
index 00000000..ac4b60d9
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -0,0 +1,183 @@
+/*
+ * arch/arm/plat-omap/include/mach/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Initially based on:
+ * linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Rewritten by:
+ * Author: <source@mvista.com>
+ * 2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+
+#include <plat/serial.h>
+
+#define MDR1_MODE_MASK 0x07
+
+volatile u8 *uart_base;
+int uart_shift;
+
+/*
+ * Store the DEBUG_LL uart number into memory.
+ * See also debug-macro.S, and serial.c for related code.
+ */
+static void set_omap_uart_info(unsigned char port)
+{
+ *(volatile u32 *)OMAP_UART_INFO = port;
+}
+
+static void putc(int c)
+{
+ if (!uart_base)
+ return;
+
+ /* Check for UART 16x mode */
+ if ((uart_base[UART_OMAP_MDR1 << uart_shift] & MDR1_MODE_MASK) != 0)
+ return;
+
+ while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE))
+ barrier();
+ uart_base[UART_TX << uart_shift] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * Macros to configure UART1 and debug UART
+ */
+#define _DEBUG_LL_ENTRY(mach, dbg_uart, dbg_shft, dbg_id) \
+ if (machine_is_##mach()) { \
+ uart_base = (volatile u8 *)(dbg_uart); \
+ uart_shift = (dbg_shft); \
+ port = (dbg_id); \
+ set_omap_uart_info(port); \
+ break; \
+ }
+
+#define DEBUG_LL_OMAP7XX(p, mach) \
+ _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, \
+ OMAP1UART##p)
+
+#define DEBUG_LL_OMAP1(p, mach) \
+ _DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, \
+ OMAP1UART##p)
+
+#define DEBUG_LL_OMAP2(p, mach) \
+ _DEBUG_LL_ENTRY(mach, OMAP2_UART##p##_BASE, OMAP_PORT_SHIFT, \
+ OMAP2UART##p)
+
+#define DEBUG_LL_OMAP3(p, mach) \
+ _DEBUG_LL_ENTRY(mach, OMAP3_UART##p##_BASE, OMAP_PORT_SHIFT, \
+ OMAP3UART##p)
+
+#define DEBUG_LL_OMAP4(p, mach) \
+ _DEBUG_LL_ENTRY(mach, OMAP4_UART##p##_BASE, OMAP_PORT_SHIFT, \
+ OMAP4UART##p)
+
+/* Zoom2/3 shift is different for UART1 and external port */
+#define DEBUG_LL_ZOOM(mach) \
+ _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART)
+
+#define DEBUG_LL_TI816X(p, mach) \
+ _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \
+ TI816XUART##p)
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ int port = 0;
+
+ /*
+ * Initialize the port based on the machine ID from the bootloader.
+ * Note that we're using macros here instead of switch statement
+ * as machine_is functions are optimized out for the boards that
+ * are not selected.
+ */
+ do {
+ /* omap7xx/8xx based boards using UART1 with shift 0 */
+ DEBUG_LL_OMAP7XX(1, herald);
+ DEBUG_LL_OMAP7XX(1, omap_perseus2);
+
+ /* omap15xx/16xx based boards using UART1 */
+ DEBUG_LL_OMAP1(1, ams_delta);
+ DEBUG_LL_OMAP1(1, nokia770);
+ DEBUG_LL_OMAP1(1, omap_h2);
+ DEBUG_LL_OMAP1(1, omap_h3);
+ DEBUG_LL_OMAP1(1, omap_innovator);
+ DEBUG_LL_OMAP1(1, omap_osk);
+ DEBUG_LL_OMAP1(1, omap_palmte);
+ DEBUG_LL_OMAP1(1, omap_palmz71);
+
+ /* omap15xx/16xx based boards using UART2 */
+ DEBUG_LL_OMAP1(2, omap_palmtt);
+
+ /* omap15xx/16xx based boards using UART3 */
+ DEBUG_LL_OMAP1(3, sx1);
+
+ /* omap2 based boards using UART1 */
+ DEBUG_LL_OMAP2(1, omap_2430sdp);
+ DEBUG_LL_OMAP2(1, omap_apollon);
+ DEBUG_LL_OMAP2(1, omap_h4);
+
+ /* omap2 based boards using UART3 */
+ DEBUG_LL_OMAP2(3, nokia_n800);
+ DEBUG_LL_OMAP2(3, nokia_n810);
+ DEBUG_LL_OMAP2(3, nokia_n810_wimax);
+
+ /* omap3 based boards using UART1 */
+ DEBUG_LL_OMAP2(1, omap3evm);
+ DEBUG_LL_OMAP3(1, omap_3430sdp);
+ DEBUG_LL_OMAP3(1, omap_3630sdp);
+ DEBUG_LL_OMAP3(1, omap3530_lv_som);
+ DEBUG_LL_OMAP3(1, omap3_torpedo);
+
+ /* omap3 based boards using UART3 */
+ DEBUG_LL_OMAP3(3, cm_t35);
+ DEBUG_LL_OMAP3(3, cm_t3517);
+ DEBUG_LL_OMAP3(3, craneboard);
+ DEBUG_LL_OMAP3(3, devkit8000);
+ DEBUG_LL_OMAP3(3, igep0020);
+ DEBUG_LL_OMAP3(3, igep0030);
+ DEBUG_LL_OMAP3(3, nokia_rm680);
+ DEBUG_LL_OMAP3(3, nokia_rx51);
+ DEBUG_LL_OMAP3(3, omap3517evm);
+ DEBUG_LL_OMAP3(3, omap3_beagle);
+ DEBUG_LL_OMAP3(3, omap3_pandora);
+ DEBUG_LL_OMAP3(3, omap_ldp);
+ DEBUG_LL_OMAP3(3, overo);
+ DEBUG_LL_OMAP3(3, touchbook);
+
+ /* omap4 based boards using UART3 */
+ DEBUG_LL_OMAP4(3, omap_4430sdp);
+ DEBUG_LL_OMAP4(3, omap4_panda);
+
+ /* zoom2/3 external uart */
+ DEBUG_LL_ZOOM(omap_zoom2);
+ DEBUG_LL_ZOOM(omap_zoom3);
+
+ /* TI8168 base boards using UART3 */
+ DEBUG_LL_TI816X(3, ti8168evm);
+
+ } while (0);
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_wdog()
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
new file mode 100644
index 00000000..17d3c939
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -0,0 +1,296 @@
+// include/asm-arm/mach-omap/usb.h
+
+#ifndef __ASM_ARCH_OMAP_USB_H
+#define __ASM_ARCH_OMAP_USB_H
+
+#include <linux/usb/musb.h>
+#include <plat/board.h>
+
+#define OMAP3_HS_USB_PORTS 3
+
+enum usbhs_omap_port_mode {
+ OMAP_USBHS_PORT_MODE_UNUSED,
+ OMAP_EHCI_PORT_MODE_PHY,
+ OMAP_EHCI_PORT_MODE_TLL,
+ OMAP_EHCI_PORT_MODE_HSIC,
+ OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0,
+ OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM,
+ OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0,
+ OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM,
+ OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0,
+ OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM,
+ OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0,
+ OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM,
+ OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0,
+ OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM
+};
+
+struct usbhs_omap_board_data {
+ enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
+
+ /* have to be valid if phy_reset is true and portx is in phy mode */
+ int reset_gpio_port[OMAP3_HS_USB_PORTS];
+
+ /* Set this to true for ES2.x silicon */
+ unsigned es2_compatibility:1;
+
+ unsigned phy_reset:1;
+
+ /*
+ * Regulators for USB PHYs.
+ * Each PHY can have a separate regulator.
+ */
+ struct regulator *regulator[OMAP3_HS_USB_PORTS];
+};
+
+struct ehci_hcd_omap_platform_data {
+ enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
+ int reset_gpio_port[OMAP3_HS_USB_PORTS];
+ struct regulator *regulator[OMAP3_HS_USB_PORTS];
+ unsigned phy_reset:1;
+};
+
+struct ohci_hcd_omap_platform_data {
+ enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
+ unsigned es2_compatibility:1;
+};
+
+struct usbhs_omap_platform_data {
+ enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS];
+
+ struct ehci_hcd_omap_platform_data *ehci_data;
+ struct ohci_hcd_omap_platform_data *ohci_data;
+};
+/*-------------------------------------------------------------------------*/
+
+#define OMAP1_OTG_BASE 0xfffb0400
+#define OMAP1_UDC_BASE 0xfffb4000
+#define OMAP1_OHCI_BASE 0xfffba000
+
+#define OMAP2_OHCI_BASE 0x4805e000
+#define OMAP2_UDC_BASE 0x4805e200
+#define OMAP2_OTG_BASE 0x4805e300
+
+#ifdef CONFIG_ARCH_OMAP1
+
+#define OTG_BASE OMAP1_OTG_BASE
+#define UDC_BASE OMAP1_UDC_BASE
+#define OMAP_OHCI_BASE OMAP1_OHCI_BASE
+
+#else
+
+#define OTG_BASE OMAP2_OTG_BASE
+#define UDC_BASE OMAP2_UDC_BASE
+#define OMAP_OHCI_BASE OMAP2_OHCI_BASE
+
+struct omap_musb_board_data {
+ u8 interface_type;
+ u8 mode;
+ u16 power;
+ unsigned extvbus:1;
+ void (*set_phy_power)(u8 on);
+ void (*clear_irq)(void);
+ void (*set_mode)(u8 mode);
+ void (*reset)(void);
+};
+
+enum musb_interface {MUSB_INTERFACE_ULPI, MUSB_INTERFACE_UTMI};
+
+extern void usb_musb_init(struct omap_musb_board_data *board_data);
+
+extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
+
+extern int omap_usbhs_enable(struct device *dev);
+extern void omap_usbhs_disable(struct device *dev);
+
+extern int omap4430_phy_power(struct device *dev, int ID, int on);
+extern int omap4430_phy_set_clk(struct device *dev, int on);
+extern int omap4430_phy_init(struct device *dev);
+extern int omap4430_phy_exit(struct device *dev);
+extern int omap4430_phy_suspend(struct device *dev, int suspend);
+#endif
+
+extern void am35x_musb_reset(void);
+extern void am35x_musb_phy_power(u8 on);
+extern void am35x_musb_clear_irq(void);
+extern void am35x_set_mode(u8 musb_mode);
+
+/*
+ * FIXME correct answer depends on hmc_mode,
+ * as does (on omap1) any nonzero value for config->otg port number
+ */
+#ifdef CONFIG_USB_GADGET_OMAP
+#define is_usb0_device(config) 1
+#else
+#define is_usb0_device(config) 0
+#endif
+
+void omap_otg_init(struct omap_usb_config *config);
+
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
+void omap1_usb_init(struct omap_usb_config *pdata);
+#else
+static inline void omap1_usb_init(struct omap_usb_config *pdata)
+{
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE)
+void omap2_usbfs_init(struct omap_usb_config *pdata);
+#else
+static inline void omap2_usbfs_init(struct omap_usb_config *pdata)
+{
+}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * OTG and transceiver registers, for OMAPs starting with ARM926
+ */
+#define OTG_REV (OTG_BASE + 0x00)
+#define OTG_SYSCON_1 (OTG_BASE + 0x04)
+# define USB2_TRX_MODE(w) (((w)>>24)&0x07)
+# define USB1_TRX_MODE(w) (((w)>>20)&0x07)
+# define USB0_TRX_MODE(w) (((w)>>16)&0x07)
+# define OTG_IDLE_EN (1 << 15)
+# define HST_IDLE_EN (1 << 14)
+# define DEV_IDLE_EN (1 << 13)
+# define OTG_RESET_DONE (1 << 2)
+# define OTG_SOFT_RESET (1 << 1)
+#define OTG_SYSCON_2 (OTG_BASE + 0x08)
+# define OTG_EN (1 << 31)
+# define USBX_SYNCHRO (1 << 30)
+# define OTG_MST16 (1 << 29)
+# define SRP_GPDATA (1 << 28)
+# define SRP_GPDVBUS (1 << 27)
+# define SRP_GPUVBUS(w) (((w)>>24)&0x07)
+# define A_WAIT_VRISE(w) (((w)>>20)&0x07)
+# define B_ASE_BRST(w) (((w)>>16)&0x07)
+# define SRP_DPW (1 << 14)
+# define SRP_DATA (1 << 13)
+# define SRP_VBUS (1 << 12)
+# define OTG_PADEN (1 << 10)
+# define HMC_PADEN (1 << 9)
+# define UHOST_EN (1 << 8)
+# define HMC_TLLSPEED (1 << 7)
+# define HMC_TLLATTACH (1 << 6)
+# define OTG_HMC(w) (((w)>>0)&0x3f)
+#define OTG_CTRL (OTG_BASE + 0x0c)
+# define OTG_USB2_EN (1 << 29)
+# define OTG_USB2_DP (1 << 28)
+# define OTG_USB2_DM (1 << 27)
+# define OTG_USB1_EN (1 << 26)
+# define OTG_USB1_DP (1 << 25)
+# define OTG_USB1_DM (1 << 24)
+# define OTG_USB0_EN (1 << 23)
+# define OTG_USB0_DP (1 << 22)
+# define OTG_USB0_DM (1 << 21)
+# define OTG_ASESSVLD (1 << 20)
+# define OTG_BSESSEND (1 << 19)
+# define OTG_BSESSVLD (1 << 18)
+# define OTG_VBUSVLD (1 << 17)
+# define OTG_ID (1 << 16)
+# define OTG_DRIVER_SEL (1 << 15)
+# define OTG_A_SETB_HNPEN (1 << 12)
+# define OTG_A_BUSREQ (1 << 11)
+# define OTG_B_HNPEN (1 << 9)
+# define OTG_B_BUSREQ (1 << 8)
+# define OTG_BUSDROP (1 << 7)
+# define OTG_PULLDOWN (1 << 5)
+# define OTG_PULLUP (1 << 4)
+# define OTG_DRV_VBUS (1 << 3)
+# define OTG_PD_VBUS (1 << 2)
+# define OTG_PU_VBUS (1 << 1)
+# define OTG_PU_ID (1 << 0)
+#define OTG_IRQ_EN (OTG_BASE + 0x10) /* 16-bit */
+# define DRIVER_SWITCH (1 << 15)
+# define A_VBUS_ERR (1 << 13)
+# define A_REQ_TMROUT (1 << 12)
+# define A_SRP_DETECT (1 << 11)
+# define B_HNP_FAIL (1 << 10)
+# define B_SRP_TMROUT (1 << 9)
+# define B_SRP_DONE (1 << 8)
+# define B_SRP_STARTED (1 << 7)
+# define OPRT_CHG (1 << 0)
+#define OTG_IRQ_SRC (OTG_BASE + 0x14) /* 16-bit */
+ // same bits as in IRQ_EN
+#define OTG_OUTCTRL (OTG_BASE + 0x18) /* 16-bit */
+# define OTGVPD (1 << 14)
+# define OTGVPU (1 << 13)
+# define OTGPUID (1 << 12)
+# define USB2VDR (1 << 10)
+# define USB2PDEN (1 << 9)
+# define USB2PUEN (1 << 8)
+# define USB1VDR (1 << 6)
+# define USB1PDEN (1 << 5)
+# define USB1PUEN (1 << 4)
+# define USB0VDR (1 << 2)
+# define USB0PDEN (1 << 1)
+# define USB0PUEN (1 << 0)
+#define OTG_TEST (OTG_BASE + 0x20) /* 16-bit */
+#define OTG_VENDOR_CODE (OTG_BASE + 0xfc) /* 16-bit */
+
+/*-------------------------------------------------------------------------*/
+
+/* OMAP1 */
+#define USB_TRANSCEIVER_CTRL (0xfffe1000 + 0x0064)
+# define CONF_USB2_UNI_R (1 << 8)
+# define CONF_USB1_UNI_R (1 << 7)
+# define CONF_USB_PORT0_R(x) (((x)>>4)&0x7)
+# define CONF_USB0_ISOLATE_R (1 << 3)
+# define CONF_USB_PWRDN_DM_R (1 << 2)
+# define CONF_USB_PWRDN_DP_R (1 << 1)
+
+/* OMAP2 */
+# define USB_UNIDIR 0x0
+# define USB_UNIDIR_TLL 0x1
+# define USB_BIDIR 0x2
+# define USB_BIDIR_TLL 0x3
+# define USBTXWRMODEI(port, x) ((x) << (22 - (port * 2)))
+# define USBT2TLL5PI (1 << 17)
+# define USB0PUENACTLOI (1 << 16)
+# define USBSTANDBYCTRL (1 << 15)
+/* AM35x */
+/* USB 2.0 PHY Control */
+#define CONF2_PHY_GPIOMODE (1 << 23)
+#define CONF2_OTGMODE (3 << 14)
+#define CONF2_NO_OVERRIDE (0 << 14)
+#define CONF2_FORCE_HOST (1 << 14)
+#define CONF2_FORCE_DEVICE (2 << 14)
+#define CONF2_FORCE_HOST_VBUS_LOW (3 << 14)
+#define CONF2_SESENDEN (1 << 13)
+#define CONF2_VBDTCTEN (1 << 12)
+#define CONF2_REFFREQ_24MHZ (2 << 8)
+#define CONF2_REFFREQ_26MHZ (7 << 8)
+#define CONF2_REFFREQ_13MHZ (6 << 8)
+#define CONF2_REFFREQ (0xf << 8)
+#define CONF2_PHYCLKGD (1 << 7)
+#define CONF2_VBUSSENSE (1 << 6)
+#define CONF2_PHY_PLLON (1 << 5)
+#define CONF2_RESET (1 << 4)
+#define CONF2_PHYPWRDN (1 << 3)
+#define CONF2_OTGPWRDN (1 << 2)
+#define CONF2_DATPOL (1 << 1)
+
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB)
+u32 omap1_usb0_init(unsigned nwires, unsigned is_device);
+u32 omap1_usb1_init(unsigned nwires);
+u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup);
+#else
+static inline u32 omap1_usb0_init(unsigned nwires, unsigned is_device)
+{
+ return 0;
+}
+static inline u32 omap1_usb1_init(unsigned nwires)
+{
+ return 0;
+
+}
+static inline u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ return 0;
+}
+#endif
+
+#endif /* __ASM_ARCH_OMAP_USB_H */
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
new file mode 100644
index 00000000..0aa4ecd1
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -0,0 +1,62 @@
+/*
+ * VRAM manager for OMAP
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 __OMAP_VRAM_H__
+#define __OMAP_VRAM_H__
+
+#include <linux/types.h>
+
+#define OMAP_VRAM_MEMTYPE_SDRAM 0
+#define OMAP_VRAM_MEMTYPE_SRAM 1
+#define OMAP_VRAM_MEMTYPE_MAX 1
+
+extern int omap_vram_add_region(unsigned long paddr, size_t size);
+extern int omap_vram_free(unsigned long paddr, size_t size);
+extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
+extern int omap_vram_reserve(unsigned long paddr, size_t size);
+extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
+ unsigned long *largest_free_block);
+
+#ifdef CONFIG_OMAP2_VRAM
+extern void omap_vram_set_sdram_vram(u32 size, u32 start);
+extern void omap_vram_set_sram_vram(u32 size, u32 start);
+
+extern void omap_vram_reserve_sdram_memblock(void);
+extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long pstart_avail,
+ unsigned long size_avail);
+#else
+static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
+static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
+
+static inline void omap_vram_reserve_sdram_memblock(void) { }
+static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
+ unsigned long sram_vstart,
+ unsigned long sram_size,
+ unsigned long pstart_avail,
+ unsigned long size_avail)
+{
+ return 0;
+}
+#endif
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/vrfb.h b/arch/arm/plat-omap/include/plat/vrfb.h
new file mode 100644
index 00000000..3792bdea
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/vrfb.h
@@ -0,0 +1,66 @@
+/*
+ * VRFB Rotation Engine
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT 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 __OMAP_VRFB_H__
+#define __OMAP_VRFB_H__
+
+#define OMAP_VRFB_LINE_LEN 2048
+
+struct vrfb {
+ u8 context;
+ void __iomem *vaddr[4];
+ unsigned long paddr[4];
+ u16 xres;
+ u16 yres;
+ u16 xoffset;
+ u16 yoffset;
+ u8 bytespp;
+ bool yuv_mode;
+};
+
+#ifdef CONFIG_OMAP2_VRFB
+extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
+extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
+ u8 bytespp);
+extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp);
+extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp);
+extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+ u16 width, u16 height,
+ unsigned bytespp, bool yuv_mode);
+extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot);
+extern void omap_vrfb_restore_context(void);
+
+#else
+static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; }
+static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {}
+static inline void omap_vrfb_adjust_size(u16 *width, u16 *height,
+ u8 bytespp) {}
+static inline u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp)
+ { return 0; }
+static inline u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp)
+ { return 0; }
+static inline void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
+ u16 width, u16 height, unsigned bytespp, bool yuv_mode) {}
+static inline int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot)
+ { return 0; }
+static inline void omap_vrfb_restore_context(void) {}
+#endif
+#endif /* __VRFB_H */
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
new file mode 100644
index 00000000..f1ecfa9f
--- /dev/null
+++ b/arch/arm/plat-omap/io.c
@@ -0,0 +1,141 @@
+/*
+ * Common io.c file
+ * This file is created by Russell King <rmk+kernel@arm.linux.org.uk>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#include <plat/omap7xx.h>
+#include <plat/omap1510.h>
+#include <plat/omap16xx.h>
+#include <plat/omap24xx.h>
+#include <plat/omap34xx.h>
+#include <plat/omap44xx.h>
+
+#define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz)))
+#define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst)))
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+#ifdef CONFIG_ARCH_OMAP1
+ if (cpu_class_is_omap1()) {
+ if (BETWEEN(p, OMAP1_IO_PHYS, OMAP1_IO_SIZE))
+ return XLATE(p, OMAP1_IO_PHYS, OMAP1_IO_VIRT);
+ }
+ if (cpu_is_omap7xx()) {
+ if (BETWEEN(p, OMAP7XX_DSP_BASE, OMAP7XX_DSP_SIZE))
+ return XLATE(p, OMAP7XX_DSP_BASE, OMAP7XX_DSP_START);
+
+ if (BETWEEN(p, OMAP7XX_DSPREG_BASE, OMAP7XX_DSPREG_SIZE))
+ return XLATE(p, OMAP7XX_DSPREG_BASE,
+ OMAP7XX_DSPREG_START);
+ }
+ if (cpu_is_omap15xx()) {
+ if (BETWEEN(p, OMAP1510_DSP_BASE, OMAP1510_DSP_SIZE))
+ return XLATE(p, OMAP1510_DSP_BASE, OMAP1510_DSP_START);
+
+ if (BETWEEN(p, OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_SIZE))
+ return XLATE(p, OMAP1510_DSPREG_BASE,
+ OMAP1510_DSPREG_START);
+ }
+ if (cpu_is_omap16xx()) {
+ if (BETWEEN(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_SIZE))
+ return XLATE(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_START);
+
+ if (BETWEEN(p, OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_SIZE))
+ return XLATE(p, OMAP16XX_DSPREG_BASE,
+ OMAP16XX_DSPREG_START);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+ if (cpu_is_omap24xx()) {
+ if (BETWEEN(p, L3_24XX_PHYS, L3_24XX_SIZE))
+ return XLATE(p, L3_24XX_PHYS, L3_24XX_VIRT);
+ if (BETWEEN(p, L4_24XX_PHYS, L4_24XX_SIZE))
+ return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT);
+ }
+ if (cpu_is_omap2420()) {
+ if (BETWEEN(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_SIZE))
+ return XLATE(p, DSP_MEM_2420_PHYS, DSP_MEM_2420_VIRT);
+ if (BETWEEN(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE))
+ return XLATE(p, DSP_IPI_2420_PHYS, DSP_IPI_2420_SIZE);
+ if (BETWEEN(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_SIZE))
+ return XLATE(p, DSP_MMU_2420_PHYS, DSP_MMU_2420_VIRT);
+ }
+ if (cpu_is_omap2430()) {
+ if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE))
+ return XLATE(p, L4_WK_243X_PHYS, L4_WK_243X_VIRT);
+ if (BETWEEN(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_SIZE))
+ return XLATE(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_VIRT);
+ if (BETWEEN(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_SIZE))
+ return XLATE(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_VIRT);
+ if (BETWEEN(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_SIZE))
+ return XLATE(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_VIRT);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ if (cpu_is_ti816x()) {
+ if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE))
+ return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT);
+ } else if (cpu_is_omap34xx()) {
+ if (BETWEEN(p, L3_34XX_PHYS, L3_34XX_SIZE))
+ return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT);
+ if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE))
+ return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT);
+ if (BETWEEN(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_SIZE))
+ return XLATE(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_VIRT);
+ if (BETWEEN(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_SIZE))
+ return XLATE(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_VIRT);
+ if (BETWEEN(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_SIZE))
+ return XLATE(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_VIRT);
+ if (BETWEEN(p, L4_PER_34XX_PHYS, L4_PER_34XX_SIZE))
+ return XLATE(p, L4_PER_34XX_PHYS, L4_PER_34XX_VIRT);
+ if (BETWEEN(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_SIZE))
+ return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+ if (cpu_is_omap44xx()) {
+ if (BETWEEN(p, L3_44XX_PHYS, L3_44XX_SIZE))
+ return XLATE(p, L3_44XX_PHYS, L3_44XX_VIRT);
+ if (BETWEEN(p, L4_44XX_PHYS, L4_44XX_SIZE))
+ return XLATE(p, L4_44XX_PHYS, L4_44XX_VIRT);
+ if (BETWEEN(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_SIZE))
+ return XLATE(p, OMAP44XX_GPMC_PHYS, OMAP44XX_GPMC_VIRT);
+ if (BETWEEN(p, OMAP44XX_EMIF1_PHYS, OMAP44XX_EMIF1_SIZE))
+ return XLATE(p, OMAP44XX_EMIF1_PHYS, \
+ OMAP44XX_EMIF1_VIRT);
+ if (BETWEEN(p, OMAP44XX_EMIF2_PHYS, OMAP44XX_EMIF2_SIZE))
+ return XLATE(p, OMAP44XX_EMIF2_PHYS, \
+ OMAP44XX_EMIF2_VIRT);
+ if (BETWEEN(p, OMAP44XX_DMM_PHYS, OMAP44XX_DMM_SIZE))
+ return XLATE(p, OMAP44XX_DMM_PHYS, OMAP44XX_DMM_VIRT);
+ if (BETWEEN(p, L4_PER_44XX_PHYS, L4_PER_44XX_SIZE))
+ return XLATE(p, L4_PER_44XX_PHYS, L4_PER_44XX_VIRT);
+ if (BETWEEN(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_SIZE))
+ return XLATE(p, L4_EMU_44XX_PHYS, L4_EMU_44XX_VIRT);
+ }
+#endif
+ return __arm_ioremap_caller(p, size, type, __builtin_return_address(0));
+}
+EXPORT_SYMBOL(omap_ioremap);
+
+void omap_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(omap_iounmap);
diff --git a/arch/arm/plat-omap/iommu-debug.c b/arch/arm/plat-omap/iommu-debug.c
new file mode 100644
index 00000000..f07cf2f0
--- /dev/null
+++ b/arch/arm/plat-omap/iommu-debug.c
@@ -0,0 +1,418 @@
+/*
+ * omap iommu: debugfs interface
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
+
+#include "iopgtable.h"
+
+#define MAXCOLUMN 100 /* for short messages */
+
+static DEFINE_MUTEX(iommu_debug_lock);
+
+static struct dentry *iommu_debug_root;
+
+static ssize_t debug_read_ver(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ u32 ver = iommu_arch_version();
+ char buf[MAXCOLUMN], *p = buf;
+
+ p += sprintf(p, "H/W version: %d.%d\n", (ver >> 4) & 0xf , ver & 0xf);
+
+ return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+}
+
+static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p, *buf;
+ ssize_t bytes;
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ mutex_lock(&iommu_debug_lock);
+
+ bytes = iommu_dump_ctx(obj, p, count);
+ bytes = simple_read_from_buffer(userbuf, count, ppos, buf, bytes);
+
+ mutex_unlock(&iommu_debug_lock);
+ kfree(buf);
+
+ return bytes;
+}
+
+static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p, *buf;
+ ssize_t bytes, rest;
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ mutex_lock(&iommu_debug_lock);
+
+ p += sprintf(p, "%8s %8s\n", "cam:", "ram:");
+ p += sprintf(p, "-----------------------------------------\n");
+ rest = count - (p - buf);
+ p += dump_tlb_entries(obj, p, rest);
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+ mutex_unlock(&iommu_debug_lock);
+ kfree(buf);
+
+ return bytes;
+}
+
+static ssize_t debug_write_pagetable(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *ppos)
+{
+ struct iotlb_entry e;
+ struct cr_regs cr;
+ int err;
+ struct iommu *obj = file->private_data;
+ char buf[MAXCOLUMN], *p = buf;
+
+ count = min(count, sizeof(buf));
+
+ mutex_lock(&iommu_debug_lock);
+ if (copy_from_user(p, userbuf, count)) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EFAULT;
+ }
+
+ sscanf(p, "%x %x", &cr.cam, &cr.ram);
+ if (!cr.cam || !cr.ram) {
+ mutex_unlock(&iommu_debug_lock);
+ return -EINVAL;
+ }
+
+ iotlb_cr_to_e(&cr, &e);
+ err = iopgtable_store_entry(obj, &e);
+ if (err)
+ dev_err(obj->dev, "%s: fail to store cr\n", __func__);
+
+ mutex_unlock(&iommu_debug_lock);
+ return count;
+}
+
+#define dump_ioptable_entry_one(lv, da, val) \
+ ({ \
+ int __err = 0; \
+ ssize_t bytes; \
+ const int maxcol = 22; \
+ const char *str = "%d: %08x %08x\n"; \
+ bytes = snprintf(p, maxcol, str, lv, da, val); \
+ p += bytes; \
+ len -= bytes; \
+ if (len < maxcol) \
+ __err = -ENOMEM; \
+ __err; \
+ })
+
+static ssize_t dump_ioptable(struct iommu *obj, char *buf, ssize_t len)
+{
+ int i;
+ u32 *iopgd;
+ char *p = buf;
+
+ spin_lock(&obj->page_table_lock);
+
+ iopgd = iopgd_offset(obj, 0);
+ for (i = 0; i < PTRS_PER_IOPGD; i++, iopgd++) {
+ int j, err;
+ u32 *iopte;
+ u32 da;
+
+ if (!*iopgd)
+ continue;
+
+ if (!(*iopgd & IOPGD_TABLE)) {
+ da = i << IOPGD_SHIFT;
+
+ err = dump_ioptable_entry_one(1, da, *iopgd);
+ if (err)
+ goto out;
+ continue;
+ }
+
+ iopte = iopte_offset(iopgd, 0);
+
+ for (j = 0; j < PTRS_PER_IOPTE; j++, iopte++) {
+ if (!*iopte)
+ continue;
+
+ da = (i << IOPGD_SHIFT) + (j << IOPTE_SHIFT);
+ err = dump_ioptable_entry_one(2, da, *iopgd);
+ if (err)
+ goto out;
+ }
+ }
+out:
+ spin_unlock(&obj->page_table_lock);
+
+ return p - buf;
+}
+
+static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p, *buf;
+ size_t bytes;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ p += sprintf(p, "L: %8s %8s\n", "da:", "pa:");
+ p += sprintf(p, "-----------------------------------------\n");
+
+ mutex_lock(&iommu_debug_lock);
+
+ bytes = PAGE_SIZE - (p - buf);
+ p += dump_ioptable(obj, p, bytes);
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+ mutex_unlock(&iommu_debug_lock);
+ free_page((unsigned long)buf);
+
+ return bytes;
+}
+
+static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p, *buf;
+ struct iovm_struct *tmp;
+ int uninitialized_var(i);
+ ssize_t bytes;
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ p += sprintf(p, "%-3s %-8s %-8s %6s %8s\n",
+ "No", "start", "end", "size", "flags");
+ p += sprintf(p, "-------------------------------------------------\n");
+
+ mutex_lock(&iommu_debug_lock);
+
+ list_for_each_entry(tmp, &obj->mmap, list) {
+ size_t len;
+ const char *str = "%3d %08x-%08x %6x %8x\n";
+ const int maxcol = 39;
+
+ len = tmp->da_end - tmp->da_start;
+ p += snprintf(p, maxcol, str,
+ i, tmp->da_start, tmp->da_end, len, tmp->flags);
+
+ if (PAGE_SIZE - (p - buf) < maxcol)
+ break;
+ i++;
+ }
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+
+ mutex_unlock(&iommu_debug_lock);
+ free_page((unsigned long)buf);
+
+ return bytes;
+}
+
+static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ char *p, *buf;
+ struct iovm_struct *area;
+ ssize_t bytes;
+
+ count = min_t(ssize_t, count, PAGE_SIZE);
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ mutex_lock(&iommu_debug_lock);
+
+ area = find_iovm_area(obj, (u32)ppos);
+ if (IS_ERR(area)) {
+ bytes = -EINVAL;
+ goto err_out;
+ }
+ memcpy(p, area->va, count);
+ p += count;
+
+ bytes = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
+err_out:
+ mutex_unlock(&iommu_debug_lock);
+ free_page((unsigned long)buf);
+
+ return bytes;
+}
+
+static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct iommu *obj = file->private_data;
+ struct iovm_struct *area;
+ char *p, *buf;
+
+ count = min_t(size_t, count, PAGE_SIZE);
+
+ buf = (char *)__get_free_page(GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ p = buf;
+
+ mutex_lock(&iommu_debug_lock);
+
+ if (copy_from_user(p, userbuf, count)) {
+ count = -EFAULT;
+ goto err_out;
+ }
+
+ area = find_iovm_area(obj, (u32)ppos);
+ if (IS_ERR(area)) {
+ count = -EINVAL;
+ goto err_out;
+ }
+ memcpy(area->va, p, count);
+err_out:
+ mutex_unlock(&iommu_debug_lock);
+ free_page((unsigned long)buf);
+
+ return count;
+}
+
+static int debug_open_generic(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+#define DEBUG_FOPS(name) \
+ static const struct file_operations debug_##name##_fops = { \
+ .open = debug_open_generic, \
+ .read = debug_read_##name, \
+ .write = debug_write_##name, \
+ .llseek = generic_file_llseek, \
+ };
+
+#define DEBUG_FOPS_RO(name) \
+ static const struct file_operations debug_##name##_fops = { \
+ .open = debug_open_generic, \
+ .read = debug_read_##name, \
+ .llseek = generic_file_llseek, \
+ };
+
+DEBUG_FOPS_RO(ver);
+DEBUG_FOPS_RO(regs);
+DEBUG_FOPS_RO(tlb);
+DEBUG_FOPS(pagetable);
+DEBUG_FOPS_RO(mmap);
+DEBUG_FOPS(mem);
+
+#define __DEBUG_ADD_FILE(attr, mode) \
+ { \
+ struct dentry *dent; \
+ dent = debugfs_create_file(#attr, mode, parent, \
+ obj, &debug_##attr##_fops); \
+ if (!dent) \
+ return -ENOMEM; \
+ }
+
+#define DEBUG_ADD_FILE(name) __DEBUG_ADD_FILE(name, 600)
+#define DEBUG_ADD_FILE_RO(name) __DEBUG_ADD_FILE(name, 400)
+
+static int iommu_debug_register(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct iommu *obj = platform_get_drvdata(pdev);
+ struct dentry *d, *parent;
+
+ if (!obj || !obj->dev)
+ return -EINVAL;
+
+ d = debugfs_create_dir(obj->name, iommu_debug_root);
+ if (!d)
+ return -ENOMEM;
+ parent = d;
+
+ d = debugfs_create_u8("nr_tlb_entries", 400, parent,
+ (u8 *)&obj->nr_tlb_entries);
+ if (!d)
+ return -ENOMEM;
+
+ DEBUG_ADD_FILE_RO(ver);
+ DEBUG_ADD_FILE_RO(regs);
+ DEBUG_ADD_FILE_RO(tlb);
+ DEBUG_ADD_FILE(pagetable);
+ DEBUG_ADD_FILE_RO(mmap);
+ DEBUG_ADD_FILE(mem);
+
+ return 0;
+}
+
+static int __init iommu_debug_init(void)
+{
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("iommu", NULL);
+ if (!d)
+ return -ENOMEM;
+ iommu_debug_root = d;
+
+ err = foreach_iommu_device(d, iommu_debug_register);
+ if (err)
+ goto err_out;
+ return 0;
+
+err_out:
+ debugfs_remove_recursive(iommu_debug_root);
+ return err;
+}
+module_init(iommu_debug_init)
+
+static void __exit iommu_debugfs_exit(void)
+{
+ debugfs_remove_recursive(iommu_debug_root);
+}
+module_exit(iommu_debugfs_exit)
+
+MODULE_DESCRIPTION("omap iommu: debugfs interface");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
new file mode 100644
index 00000000..34fc31ee
--- /dev/null
+++ b/arch/arm/plat-omap/iommu.c
@@ -0,0 +1,1102 @@
+/*
+ * omap iommu: tlb and pagetable primitives
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
+ * Paul Mundt and Toshihiro Kobayashi
+ *
+ * This program is free software; you can 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/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <asm/cacheflush.h>
+
+#include <plat/iommu.h>
+
+#include "iopgtable.h"
+
+#define for_each_iotlb_cr(obj, n, __i, cr) \
+ for (__i = 0; \
+ (__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \
+ __i++)
+
+/* accommodate the difference between omap1 and omap2/3 */
+static const struct iommu_functions *arch_iommu;
+
+static struct platform_driver omap_iommu_driver;
+static struct kmem_cache *iopte_cachep;
+
+/**
+ * install_iommu_arch - Install archtecure specific iommu functions
+ * @ops: a pointer to architecture specific iommu functions
+ *
+ * There are several kind of iommu algorithm(tlb, pagetable) among
+ * omap series. This interface installs such an iommu algorighm.
+ **/
+int install_iommu_arch(const struct iommu_functions *ops)
+{
+ if (arch_iommu)
+ return -EBUSY;
+
+ arch_iommu = ops;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(install_iommu_arch);
+
+/**
+ * uninstall_iommu_arch - Uninstall archtecure specific iommu functions
+ * @ops: a pointer to architecture specific iommu functions
+ *
+ * This interface uninstalls the iommu algorighm installed previously.
+ **/
+void uninstall_iommu_arch(const struct iommu_functions *ops)
+{
+ if (arch_iommu != ops)
+ pr_err("%s: not your arch\n", __func__);
+
+ arch_iommu = NULL;
+}
+EXPORT_SYMBOL_GPL(uninstall_iommu_arch);
+
+/**
+ * iommu_save_ctx - Save registers for pm off-mode support
+ * @obj: target iommu
+ **/
+void iommu_save_ctx(struct iommu *obj)
+{
+ arch_iommu->save_ctx(obj);
+}
+EXPORT_SYMBOL_GPL(iommu_save_ctx);
+
+/**
+ * iommu_restore_ctx - Restore registers for pm off-mode support
+ * @obj: target iommu
+ **/
+void iommu_restore_ctx(struct iommu *obj)
+{
+ arch_iommu->restore_ctx(obj);
+}
+EXPORT_SYMBOL_GPL(iommu_restore_ctx);
+
+/**
+ * iommu_arch_version - Return running iommu arch version
+ **/
+u32 iommu_arch_version(void)
+{
+ return arch_iommu->version;
+}
+EXPORT_SYMBOL_GPL(iommu_arch_version);
+
+static int iommu_enable(struct iommu *obj)
+{
+ int err;
+
+ if (!obj)
+ return -EINVAL;
+
+ if (!arch_iommu)
+ return -ENODEV;
+
+ clk_enable(obj->clk);
+
+ err = arch_iommu->enable(obj);
+
+ clk_disable(obj->clk);
+ return err;
+}
+
+static void iommu_disable(struct iommu *obj)
+{
+ if (!obj)
+ return;
+
+ clk_enable(obj->clk);
+
+ arch_iommu->disable(obj);
+
+ clk_disable(obj->clk);
+}
+
+/*
+ * TLB operations
+ */
+void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
+{
+ BUG_ON(!cr || !e);
+
+ arch_iommu->cr_to_e(cr, e);
+}
+EXPORT_SYMBOL_GPL(iotlb_cr_to_e);
+
+static inline int iotlb_cr_valid(struct cr_regs *cr)
+{
+ if (!cr)
+ return -EINVAL;
+
+ return arch_iommu->cr_valid(cr);
+}
+
+static inline struct cr_regs *iotlb_alloc_cr(struct iommu *obj,
+ struct iotlb_entry *e)
+{
+ if (!e)
+ return NULL;
+
+ return arch_iommu->alloc_cr(obj, e);
+}
+
+u32 iotlb_cr_to_virt(struct cr_regs *cr)
+{
+ return arch_iommu->cr_to_virt(cr);
+}
+EXPORT_SYMBOL_GPL(iotlb_cr_to_virt);
+
+static u32 get_iopte_attr(struct iotlb_entry *e)
+{
+ return arch_iommu->get_pte_attr(e);
+}
+
+static u32 iommu_report_fault(struct iommu *obj, u32 *da)
+{
+ return arch_iommu->fault_isr(obj, da);
+}
+
+static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l)
+{
+ u32 val;
+
+ val = iommu_read_reg(obj, MMU_LOCK);
+
+ l->base = MMU_LOCK_BASE(val);
+ l->vict = MMU_LOCK_VICT(val);
+
+}
+
+static void iotlb_lock_set(struct iommu *obj, struct iotlb_lock *l)
+{
+ u32 val;
+
+ val = (l->base << MMU_LOCK_BASE_SHIFT);
+ val |= (l->vict << MMU_LOCK_VICT_SHIFT);
+
+ iommu_write_reg(obj, val, MMU_LOCK);
+}
+
+static void iotlb_read_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ arch_iommu->tlb_read_cr(obj, cr);
+}
+
+static void iotlb_load_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ arch_iommu->tlb_load_cr(obj, cr);
+
+ iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
+ iommu_write_reg(obj, 1, MMU_LD_TLB);
+}
+
+/**
+ * iotlb_dump_cr - Dump an iommu tlb entry into buf
+ * @obj: target iommu
+ * @cr: contents of cam and ram register
+ * @buf: output buffer
+ **/
+static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
+ char *buf)
+{
+ BUG_ON(!cr || !buf);
+
+ return arch_iommu->dump_cr(obj, cr, buf);
+}
+
+/* only used in iotlb iteration for-loop */
+static struct cr_regs __iotlb_read_cr(struct iommu *obj, int n)
+{
+ struct cr_regs cr;
+ struct iotlb_lock l;
+
+ iotlb_lock_get(obj, &l);
+ l.vict = n;
+ iotlb_lock_set(obj, &l);
+ iotlb_read_cr(obj, &cr);
+
+ return cr;
+}
+
+/**
+ * load_iotlb_entry - Set an iommu tlb entry
+ * @obj: target iommu
+ * @e: an iommu tlb entry info
+ **/
+int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
+{
+ int err = 0;
+ struct iotlb_lock l;
+ struct cr_regs *cr;
+
+ if (!obj || !obj->nr_tlb_entries || !e)
+ return -EINVAL;
+
+ clk_enable(obj->clk);
+
+ iotlb_lock_get(obj, &l);
+ if (l.base == obj->nr_tlb_entries) {
+ dev_warn(obj->dev, "%s: preserve entries full\n", __func__);
+ err = -EBUSY;
+ goto out;
+ }
+ if (!e->prsvd) {
+ int i;
+ struct cr_regs tmp;
+
+ for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, tmp)
+ if (!iotlb_cr_valid(&tmp))
+ break;
+
+ if (i == obj->nr_tlb_entries) {
+ dev_dbg(obj->dev, "%s: full: no entry\n", __func__);
+ err = -EBUSY;
+ goto out;
+ }
+
+ iotlb_lock_get(obj, &l);
+ } else {
+ l.vict = l.base;
+ iotlb_lock_set(obj, &l);
+ }
+
+ cr = iotlb_alloc_cr(obj, e);
+ if (IS_ERR(cr)) {
+ clk_disable(obj->clk);
+ return PTR_ERR(cr);
+ }
+
+ iotlb_load_cr(obj, cr);
+ kfree(cr);
+
+ if (e->prsvd)
+ l.base++;
+ /* increment victim for next tlb load */
+ if (++l.vict == obj->nr_tlb_entries)
+ l.vict = l.base;
+ iotlb_lock_set(obj, &l);
+out:
+ clk_disable(obj->clk);
+ return err;
+}
+EXPORT_SYMBOL_GPL(load_iotlb_entry);
+
+/**
+ * flush_iotlb_page - Clear an iommu tlb entry
+ * @obj: target iommu
+ * @da: iommu device virtual address
+ *
+ * Clear an iommu tlb entry which includes 'da' address.
+ **/
+void flush_iotlb_page(struct iommu *obj, u32 da)
+{
+ int i;
+ struct cr_regs cr;
+
+ clk_enable(obj->clk);
+
+ for_each_iotlb_cr(obj, obj->nr_tlb_entries, i, cr) {
+ u32 start;
+ size_t bytes;
+
+ if (!iotlb_cr_valid(&cr))
+ continue;
+
+ start = iotlb_cr_to_virt(&cr);
+ bytes = iopgsz_to_bytes(cr.cam & 3);
+
+ if ((start <= da) && (da < start + bytes)) {
+ dev_dbg(obj->dev, "%s: %08x<=%08x(%x)\n",
+ __func__, start, da, bytes);
+ iotlb_load_cr(obj, &cr);
+ iommu_write_reg(obj, 1, MMU_FLUSH_ENTRY);
+ }
+ }
+ clk_disable(obj->clk);
+
+ if (i == obj->nr_tlb_entries)
+ dev_dbg(obj->dev, "%s: no page for %08x\n", __func__, da);
+}
+EXPORT_SYMBOL_GPL(flush_iotlb_page);
+
+/**
+ * flush_iotlb_range - Clear an iommu tlb entries
+ * @obj: target iommu
+ * @start: iommu device virtual address(start)
+ * @end: iommu device virtual address(end)
+ *
+ * Clear an iommu tlb entry which includes 'da' address.
+ **/
+void flush_iotlb_range(struct iommu *obj, u32 start, u32 end)
+{
+ u32 da = start;
+
+ while (da < end) {
+ flush_iotlb_page(obj, da);
+ /* FIXME: Optimize for multiple page size */
+ da += IOPTE_SIZE;
+ }
+}
+EXPORT_SYMBOL_GPL(flush_iotlb_range);
+
+/**
+ * flush_iotlb_all - Clear all iommu tlb entries
+ * @obj: target iommu
+ **/
+void flush_iotlb_all(struct iommu *obj)
+{
+ struct iotlb_lock l;
+
+ clk_enable(obj->clk);
+
+ l.base = 0;
+ l.vict = 0;
+ iotlb_lock_set(obj, &l);
+
+ iommu_write_reg(obj, 1, MMU_GFLUSH);
+
+ clk_disable(obj->clk);
+}
+EXPORT_SYMBOL_GPL(flush_iotlb_all);
+
+/**
+ * iommu_set_twl - enable/disable table walking logic
+ * @obj: target iommu
+ * @on: enable/disable
+ *
+ * Function used to enable/disable TWL. If one wants to work
+ * exclusively with locked TLB entries and receive notifications
+ * for TLB miss then call this function to disable TWL.
+ */
+void iommu_set_twl(struct iommu *obj, bool on)
+{
+ clk_enable(obj->clk);
+ arch_iommu->set_twl(obj, on);
+ clk_disable(obj->clk);
+}
+EXPORT_SYMBOL_GPL(iommu_set_twl);
+
+#if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
+
+ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes)
+{
+ if (!obj || !buf)
+ return -EINVAL;
+
+ clk_enable(obj->clk);
+
+ bytes = arch_iommu->dump_ctx(obj, buf, bytes);
+
+ clk_disable(obj->clk);
+
+ return bytes;
+}
+EXPORT_SYMBOL_GPL(iommu_dump_ctx);
+
+static int __dump_tlb_entries(struct iommu *obj, struct cr_regs *crs, int num)
+{
+ int i;
+ struct iotlb_lock saved;
+ struct cr_regs tmp;
+ struct cr_regs *p = crs;
+
+ clk_enable(obj->clk);
+ iotlb_lock_get(obj, &saved);
+
+ for_each_iotlb_cr(obj, num, i, tmp) {
+ if (!iotlb_cr_valid(&tmp))
+ continue;
+ *p++ = tmp;
+ }
+
+ iotlb_lock_set(obj, &saved);
+ clk_disable(obj->clk);
+
+ return p - crs;
+}
+
+/**
+ * dump_tlb_entries - dump cr arrays to given buffer
+ * @obj: target iommu
+ * @buf: output buffer
+ **/
+size_t dump_tlb_entries(struct iommu *obj, char *buf, ssize_t bytes)
+{
+ int i, num;
+ struct cr_regs *cr;
+ char *p = buf;
+
+ num = bytes / sizeof(*cr);
+ num = min(obj->nr_tlb_entries, num);
+
+ cr = kcalloc(num, sizeof(*cr), GFP_KERNEL);
+ if (!cr)
+ return 0;
+
+ num = __dump_tlb_entries(obj, cr, num);
+ for (i = 0; i < num; i++)
+ p += iotlb_dump_cr(obj, cr + i, p);
+ kfree(cr);
+
+ return p - buf;
+}
+EXPORT_SYMBOL_GPL(dump_tlb_entries);
+
+int foreach_iommu_device(void *data, int (*fn)(struct device *, void *))
+{
+ return driver_for_each_device(&omap_iommu_driver.driver,
+ NULL, data, fn);
+}
+EXPORT_SYMBOL_GPL(foreach_iommu_device);
+
+#endif /* CONFIG_OMAP_IOMMU_DEBUG_MODULE */
+
+/*
+ * H/W pagetable operations
+ */
+static void flush_iopgd_range(u32 *first, u32 *last)
+{
+ /* FIXME: L2 cache should be taken care of if it exists */
+ do {
+ asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pgd"
+ : : "r" (first));
+ first += L1_CACHE_BYTES / sizeof(*first);
+ } while (first <= last);
+}
+
+static void flush_iopte_range(u32 *first, u32 *last)
+{
+ /* FIXME: L2 cache should be taken care of if it exists */
+ do {
+ asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pte"
+ : : "r" (first));
+ first += L1_CACHE_BYTES / sizeof(*first);
+ } while (first <= last);
+}
+
+static void iopte_free(u32 *iopte)
+{
+ /* Note: freed iopte's must be clean ready for re-use */
+ kmem_cache_free(iopte_cachep, iopte);
+}
+
+static u32 *iopte_alloc(struct iommu *obj, u32 *iopgd, u32 da)
+{
+ u32 *iopte;
+
+ /* a table has already existed */
+ if (*iopgd)
+ goto pte_ready;
+
+ /*
+ * do the allocation outside the page table lock
+ */
+ spin_unlock(&obj->page_table_lock);
+ iopte = kmem_cache_zalloc(iopte_cachep, GFP_KERNEL);
+ spin_lock(&obj->page_table_lock);
+
+ if (!*iopgd) {
+ if (!iopte)
+ return ERR_PTR(-ENOMEM);
+
+ *iopgd = virt_to_phys(iopte) | IOPGD_TABLE;
+ flush_iopgd_range(iopgd, iopgd);
+
+ dev_vdbg(obj->dev, "%s: a new pte:%p\n", __func__, iopte);
+ } else {
+ /* We raced, free the reduniovant table */
+ iopte_free(iopte);
+ }
+
+pte_ready:
+ iopte = iopte_offset(iopgd, da);
+
+ dev_vdbg(obj->dev,
+ "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n",
+ __func__, da, iopgd, *iopgd, iopte, *iopte);
+
+ return iopte;
+}
+
+static int iopgd_alloc_section(struct iommu *obj, u32 da, u32 pa, u32 prot)
+{
+ u32 *iopgd = iopgd_offset(obj, da);
+
+ if ((da | pa) & ~IOSECTION_MASK) {
+ dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n",
+ __func__, da, pa, IOSECTION_SIZE);
+ return -EINVAL;
+ }
+
+ *iopgd = (pa & IOSECTION_MASK) | prot | IOPGD_SECTION;
+ flush_iopgd_range(iopgd, iopgd);
+ return 0;
+}
+
+static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot)
+{
+ u32 *iopgd = iopgd_offset(obj, da);
+ int i;
+
+ if ((da | pa) & ~IOSUPER_MASK) {
+ dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n",
+ __func__, da, pa, IOSUPER_SIZE);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 16; i++)
+ *(iopgd + i) = (pa & IOSUPER_MASK) | prot | IOPGD_SUPER;
+ flush_iopgd_range(iopgd, iopgd + 15);
+ return 0;
+}
+
+static int iopte_alloc_page(struct iommu *obj, u32 da, u32 pa, u32 prot)
+{
+ u32 *iopgd = iopgd_offset(obj, da);
+ u32 *iopte = iopte_alloc(obj, iopgd, da);
+
+ if (IS_ERR(iopte))
+ return PTR_ERR(iopte);
+
+ *iopte = (pa & IOPAGE_MASK) | prot | IOPTE_SMALL;
+ flush_iopte_range(iopte, iopte);
+
+ dev_vdbg(obj->dev, "%s: da:%08x pa:%08x pte:%p *pte:%08x\n",
+ __func__, da, pa, iopte, *iopte);
+
+ return 0;
+}
+
+static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot)
+{
+ u32 *iopgd = iopgd_offset(obj, da);
+ u32 *iopte = iopte_alloc(obj, iopgd, da);
+ int i;
+
+ if ((da | pa) & ~IOLARGE_MASK) {
+ dev_err(obj->dev, "%s: %08x:%08x should aligned on %08lx\n",
+ __func__, da, pa, IOLARGE_SIZE);
+ return -EINVAL;
+ }
+
+ if (IS_ERR(iopte))
+ return PTR_ERR(iopte);
+
+ for (i = 0; i < 16; i++)
+ *(iopte + i) = (pa & IOLARGE_MASK) | prot | IOPTE_LARGE;
+ flush_iopte_range(iopte, iopte + 15);
+ return 0;
+}
+
+static int iopgtable_store_entry_core(struct iommu *obj, struct iotlb_entry *e)
+{
+ int (*fn)(struct iommu *, u32, u32, u32);
+ u32 prot;
+ int err;
+
+ if (!obj || !e)
+ return -EINVAL;
+
+ switch (e->pgsz) {
+ case MMU_CAM_PGSZ_16M:
+ fn = iopgd_alloc_super;
+ break;
+ case MMU_CAM_PGSZ_1M:
+ fn = iopgd_alloc_section;
+ break;
+ case MMU_CAM_PGSZ_64K:
+ fn = iopte_alloc_large;
+ break;
+ case MMU_CAM_PGSZ_4K:
+ fn = iopte_alloc_page;
+ break;
+ default:
+ fn = NULL;
+ BUG();
+ break;
+ }
+
+ prot = get_iopte_attr(e);
+
+ spin_lock(&obj->page_table_lock);
+ err = fn(obj, e->da, e->pa, prot);
+ spin_unlock(&obj->page_table_lock);
+
+ return err;
+}
+
+/**
+ * iopgtable_store_entry - Make an iommu pte entry
+ * @obj: target iommu
+ * @e: an iommu tlb entry info
+ **/
+int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e)
+{
+ int err;
+
+ flush_iotlb_page(obj, e->da);
+ err = iopgtable_store_entry_core(obj, e);
+#ifdef PREFETCH_IOTLB
+ if (!err)
+ load_iotlb_entry(obj, e);
+#endif
+ return err;
+}
+EXPORT_SYMBOL_GPL(iopgtable_store_entry);
+
+/**
+ * iopgtable_lookup_entry - Lookup an iommu pte entry
+ * @obj: target iommu
+ * @da: iommu device virtual address
+ * @ppgd: iommu pgd entry pointer to be returned
+ * @ppte: iommu pte entry pointer to be returned
+ **/
+void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte)
+{
+ u32 *iopgd, *iopte = NULL;
+
+ iopgd = iopgd_offset(obj, da);
+ if (!*iopgd)
+ goto out;
+
+ if (iopgd_is_table(*iopgd))
+ iopte = iopte_offset(iopgd, da);
+out:
+ *ppgd = iopgd;
+ *ppte = iopte;
+}
+EXPORT_SYMBOL_GPL(iopgtable_lookup_entry);
+
+static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da)
+{
+ size_t bytes;
+ u32 *iopgd = iopgd_offset(obj, da);
+ int nent = 1;
+
+ if (!*iopgd)
+ return 0;
+
+ if (iopgd_is_table(*iopgd)) {
+ int i;
+ u32 *iopte = iopte_offset(iopgd, da);
+
+ bytes = IOPTE_SIZE;
+ if (*iopte & IOPTE_LARGE) {
+ nent *= 16;
+ /* rewind to the 1st entry */
+ iopte = iopte_offset(iopgd, (da & IOLARGE_MASK));
+ }
+ bytes *= nent;
+ memset(iopte, 0, nent * sizeof(*iopte));
+ flush_iopte_range(iopte, iopte + (nent - 1) * sizeof(*iopte));
+
+ /*
+ * do table walk to check if this table is necessary or not
+ */
+ iopte = iopte_offset(iopgd, 0);
+ for (i = 0; i < PTRS_PER_IOPTE; i++)
+ if (iopte[i])
+ goto out;
+
+ iopte_free(iopte);
+ nent = 1; /* for the next L1 entry */
+ } else {
+ bytes = IOPGD_SIZE;
+ if ((*iopgd & IOPGD_SUPER) == IOPGD_SUPER) {
+ nent *= 16;
+ /* rewind to the 1st entry */
+ iopgd = iopgd_offset(obj, (da & IOSUPER_MASK));
+ }
+ bytes *= nent;
+ }
+ memset(iopgd, 0, nent * sizeof(*iopgd));
+ flush_iopgd_range(iopgd, iopgd + (nent - 1) * sizeof(*iopgd));
+out:
+ return bytes;
+}
+
+/**
+ * iopgtable_clear_entry - Remove an iommu pte entry
+ * @obj: target iommu
+ * @da: iommu device virtual address
+ **/
+size_t iopgtable_clear_entry(struct iommu *obj, u32 da)
+{
+ size_t bytes;
+
+ spin_lock(&obj->page_table_lock);
+
+ bytes = iopgtable_clear_entry_core(obj, da);
+ flush_iotlb_page(obj, da);
+
+ spin_unlock(&obj->page_table_lock);
+
+ return bytes;
+}
+EXPORT_SYMBOL_GPL(iopgtable_clear_entry);
+
+static void iopgtable_clear_entry_all(struct iommu *obj)
+{
+ int i;
+
+ spin_lock(&obj->page_table_lock);
+
+ for (i = 0; i < PTRS_PER_IOPGD; i++) {
+ u32 da;
+ u32 *iopgd;
+
+ da = i << IOPGD_SHIFT;
+ iopgd = iopgd_offset(obj, da);
+
+ if (!*iopgd)
+ continue;
+
+ if (iopgd_is_table(*iopgd))
+ iopte_free(iopte_offset(iopgd, 0));
+
+ *iopgd = 0;
+ flush_iopgd_range(iopgd, iopgd);
+ }
+
+ flush_iotlb_all(obj);
+
+ spin_unlock(&obj->page_table_lock);
+}
+
+/*
+ * Device IOMMU generic operations
+ */
+static irqreturn_t iommu_fault_handler(int irq, void *data)
+{
+ u32 da, errs;
+ u32 *iopgd, *iopte;
+ struct iommu *obj = data;
+
+ if (!obj->refcount)
+ return IRQ_NONE;
+
+ clk_enable(obj->clk);
+ errs = iommu_report_fault(obj, &da);
+ clk_disable(obj->clk);
+ if (errs == 0)
+ return IRQ_HANDLED;
+
+ /* Fault callback or TLB/PTE Dynamic loading */
+ if (obj->isr && !obj->isr(obj, da, errs, obj->isr_priv))
+ return IRQ_HANDLED;
+
+ iommu_disable(obj);
+
+ iopgd = iopgd_offset(obj, da);
+
+ if (!iopgd_is_table(*iopgd)) {
+ dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p "
+ "*pgd:px%08x\n", obj->name, errs, da, iopgd, *iopgd);
+ return IRQ_NONE;
+ }
+
+ iopte = iopte_offset(iopgd, da);
+
+ dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x "
+ "pte:0x%p *pte:0x%08x\n", obj->name, errs, da, iopgd, *iopgd,
+ iopte, *iopte);
+
+ return IRQ_NONE;
+}
+
+static int device_match_by_alias(struct device *dev, void *data)
+{
+ struct iommu *obj = to_iommu(dev);
+ const char *name = data;
+
+ pr_debug("%s: %s %s\n", __func__, obj->name, name);
+
+ return strcmp(obj->name, name) == 0;
+}
+
+/**
+ * iommu_set_da_range - Set a valid device address range
+ * @obj: target iommu
+ * @start Start of valid range
+ * @end End of valid range
+ **/
+int iommu_set_da_range(struct iommu *obj, u32 start, u32 end)
+{
+
+ if (!obj)
+ return -EFAULT;
+
+ if (end < start || !PAGE_ALIGN(start | end))
+ return -EINVAL;
+
+ obj->da_start = start;
+ obj->da_end = end;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_set_da_range);
+
+/**
+ * iommu_get - Get iommu handler
+ * @name: target iommu name
+ **/
+struct iommu *iommu_get(const char *name)
+{
+ int err = -ENOMEM;
+ struct device *dev;
+ struct iommu *obj;
+
+ dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
+ device_match_by_alias);
+ if (!dev)
+ return ERR_PTR(-ENODEV);
+
+ obj = to_iommu(dev);
+
+ mutex_lock(&obj->iommu_lock);
+
+ if (obj->refcount++ == 0) {
+ err = iommu_enable(obj);
+ if (err)
+ goto err_enable;
+ flush_iotlb_all(obj);
+ }
+
+ if (!try_module_get(obj->owner))
+ goto err_module;
+
+ mutex_unlock(&obj->iommu_lock);
+
+ dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
+ return obj;
+
+err_module:
+ if (obj->refcount == 1)
+ iommu_disable(obj);
+err_enable:
+ obj->refcount--;
+ mutex_unlock(&obj->iommu_lock);
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL_GPL(iommu_get);
+
+/**
+ * iommu_put - Put back iommu handler
+ * @obj: target iommu
+ **/
+void iommu_put(struct iommu *obj)
+{
+ if (!obj || IS_ERR(obj))
+ return;
+
+ mutex_lock(&obj->iommu_lock);
+
+ if (--obj->refcount == 0)
+ iommu_disable(obj);
+
+ module_put(obj->owner);
+
+ mutex_unlock(&obj->iommu_lock);
+
+ dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
+}
+EXPORT_SYMBOL_GPL(iommu_put);
+
+int iommu_set_isr(const char *name,
+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
+ void *priv),
+ void *isr_priv)
+{
+ struct device *dev;
+ struct iommu *obj;
+
+ dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name,
+ device_match_by_alias);
+ if (!dev)
+ return -ENODEV;
+
+ obj = to_iommu(dev);
+ mutex_lock(&obj->iommu_lock);
+ if (obj->refcount != 0) {
+ mutex_unlock(&obj->iommu_lock);
+ return -EBUSY;
+ }
+ obj->isr = isr;
+ obj->isr_priv = isr_priv;
+ mutex_unlock(&obj->iommu_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(iommu_set_isr);
+
+/*
+ * OMAP Device MMU(IOMMU) detection
+ */
+static int __devinit omap_iommu_probe(struct platform_device *pdev)
+{
+ int err = -ENODEV;
+ void *p;
+ int irq;
+ struct iommu *obj;
+ struct resource *res;
+ struct iommu_platform_data *pdata = pdev->dev.platform_data;
+
+ if (pdev->num_resources != 2)
+ return -EINVAL;
+
+ obj = kzalloc(sizeof(*obj) + MMU_REG_SIZE, GFP_KERNEL);
+ if (!obj)
+ return -ENOMEM;
+
+ obj->clk = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(obj->clk))
+ goto err_clk;
+
+ obj->nr_tlb_entries = pdata->nr_tlb_entries;
+ obj->name = pdata->name;
+ obj->dev = &pdev->dev;
+ obj->ctx = (void *)obj + sizeof(*obj);
+ obj->da_start = pdata->da_start;
+ obj->da_end = pdata->da_end;
+
+ mutex_init(&obj->iommu_lock);
+ mutex_init(&obj->mmap_lock);
+ spin_lock_init(&obj->page_table_lock);
+ INIT_LIST_HEAD(&obj->mmap);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -ENODEV;
+ goto err_mem;
+ }
+
+ res = request_mem_region(res->start, resource_size(res),
+ dev_name(&pdev->dev));
+ if (!res) {
+ err = -EIO;
+ goto err_mem;
+ }
+
+ obj->regbase = ioremap(res->start, resource_size(res));
+ if (!obj->regbase) {
+ err = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ err = -ENODEV;
+ goto err_irq;
+ }
+ err = request_irq(irq, iommu_fault_handler, IRQF_SHARED,
+ dev_name(&pdev->dev), obj);
+ if (err < 0)
+ goto err_irq;
+ platform_set_drvdata(pdev, obj);
+
+ p = (void *)__get_free_pages(GFP_KERNEL, get_order(IOPGD_TABLE_SIZE));
+ if (!p) {
+ err = -ENOMEM;
+ goto err_pgd;
+ }
+ memset(p, 0, IOPGD_TABLE_SIZE);
+ clean_dcache_area(p, IOPGD_TABLE_SIZE);
+ obj->iopgd = p;
+
+ BUG_ON(!IS_ALIGNED((unsigned long)obj->iopgd, IOPGD_TABLE_SIZE));
+
+ dev_info(&pdev->dev, "%s registered\n", obj->name);
+ return 0;
+
+err_pgd:
+ free_irq(irq, obj);
+err_irq:
+ iounmap(obj->regbase);
+err_ioremap:
+ release_mem_region(res->start, resource_size(res));
+err_mem:
+ clk_put(obj->clk);
+err_clk:
+ kfree(obj);
+ return err;
+}
+
+static int __devexit omap_iommu_remove(struct platform_device *pdev)
+{
+ int irq;
+ struct resource *res;
+ struct iommu *obj = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ iopgtable_clear_entry_all(obj);
+ free_pages((unsigned long)obj->iopgd, get_order(IOPGD_TABLE_SIZE));
+
+ irq = platform_get_irq(pdev, 0);
+ free_irq(irq, obj);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+ iounmap(obj->regbase);
+
+ clk_put(obj->clk);
+ dev_info(&pdev->dev, "%s removed\n", obj->name);
+ kfree(obj);
+ return 0;
+}
+
+static struct platform_driver omap_iommu_driver = {
+ .probe = omap_iommu_probe,
+ .remove = __devexit_p(omap_iommu_remove),
+ .driver = {
+ .name = "omap-iommu",
+ },
+};
+
+static void iopte_cachep_ctor(void *iopte)
+{
+ clean_dcache_area(iopte, IOPTE_TABLE_SIZE);
+}
+
+static int __init omap_iommu_init(void)
+{
+ struct kmem_cache *p;
+ const unsigned long flags = SLAB_HWCACHE_ALIGN;
+ size_t align = 1 << 10; /* L2 pagetable alignement */
+
+ p = kmem_cache_create("iopte_cache", IOPTE_TABLE_SIZE, align, flags,
+ iopte_cachep_ctor);
+ if (!p)
+ return -ENOMEM;
+ iopte_cachep = p;
+
+ return platform_driver_register(&omap_iommu_driver);
+}
+module_init(omap_iommu_init);
+
+static void __exit omap_iommu_exit(void)
+{
+ kmem_cache_destroy(iopte_cachep);
+
+ platform_driver_unregister(&omap_iommu_driver);
+}
+module_exit(omap_iommu_exit);
+
+MODULE_DESCRIPTION("omap iommu: tlb and pagetable primitives");
+MODULE_ALIAS("platform:omap-iommu");
+MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/iopgtable.h b/arch/arm/plat-omap/iopgtable.h
new file mode 100644
index 00000000..c3e93bb0
--- /dev/null
+++ b/arch/arm/plat-omap/iopgtable.h
@@ -0,0 +1,102 @@
+/*
+ * omap iommu: pagetable definitions
+ *
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_OMAP_IOMMU_H
+#define __PLAT_OMAP_IOMMU_H
+
+/*
+ * "L2 table" address mask and size definitions.
+ */
+#define IOPGD_SHIFT 20
+#define IOPGD_SIZE (1UL << IOPGD_SHIFT)
+#define IOPGD_MASK (~(IOPGD_SIZE - 1))
+
+/*
+ * "section" address mask and size definitions.
+ */
+#define IOSECTION_SHIFT 20
+#define IOSECTION_SIZE (1UL << IOSECTION_SHIFT)
+#define IOSECTION_MASK (~(IOSECTION_SIZE - 1))
+
+/*
+ * "supersection" address mask and size definitions.
+ */
+#define IOSUPER_SHIFT 24
+#define IOSUPER_SIZE (1UL << IOSUPER_SHIFT)
+#define IOSUPER_MASK (~(IOSUPER_SIZE - 1))
+
+#define PTRS_PER_IOPGD (1UL << (32 - IOPGD_SHIFT))
+#define IOPGD_TABLE_SIZE (PTRS_PER_IOPGD * sizeof(u32))
+
+/*
+ * "small page" address mask and size definitions.
+ */
+#define IOPTE_SHIFT 12
+#define IOPTE_SIZE (1UL << IOPTE_SHIFT)
+#define IOPTE_MASK (~(IOPTE_SIZE - 1))
+
+/*
+ * "large page" address mask and size definitions.
+ */
+#define IOLARGE_SHIFT 16
+#define IOLARGE_SIZE (1UL << IOLARGE_SHIFT)
+#define IOLARGE_MASK (~(IOLARGE_SIZE - 1))
+
+#define PTRS_PER_IOPTE (1UL << (IOPGD_SHIFT - IOPTE_SHIFT))
+#define IOPTE_TABLE_SIZE (PTRS_PER_IOPTE * sizeof(u32))
+
+#define IOPAGE_MASK IOPTE_MASK
+
+/*
+ * some descriptor attributes.
+ */
+#define IOPGD_TABLE (1 << 0)
+#define IOPGD_SECTION (2 << 0)
+#define IOPGD_SUPER (1 << 18 | 2 << 0)
+
+#define iopgd_is_table(x) (((x) & 3) == IOPGD_TABLE)
+
+#define IOPTE_SMALL (2 << 0)
+#define IOPTE_LARGE (1 << 0)
+
+/* to find an entry in a page-table-directory */
+#define iopgd_index(da) (((da) >> IOPGD_SHIFT) & (PTRS_PER_IOPGD - 1))
+#define iopgd_offset(obj, da) ((obj)->iopgd + iopgd_index(da))
+
+#define iopgd_page_paddr(iopgd) (*iopgd & ~((1 << 10) - 1))
+#define iopgd_page_vaddr(iopgd) ((u32 *)phys_to_virt(iopgd_page_paddr(iopgd)))
+
+/* to find an entry in the second-level page table. */
+#define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
+#define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da))
+
+static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
+ u32 flags)
+{
+ memset(e, 0, sizeof(*e));
+
+ e->da = da;
+ e->pa = pa;
+ e->valid = 1;
+ /* FIXME: add OMAP1 support */
+ e->pgsz = flags & MMU_CAM_PGSZ_MASK;
+ e->endian = flags & MMU_RAM_ENDIAN_MASK;
+ e->elsz = flags & MMU_RAM_ELSZ_MASK;
+ e->mixed = flags & MMU_RAM_MIXED_MASK;
+
+ return iopgsz_to_bytes(e->pgsz);
+}
+
+#define to_iommu(dev) \
+ (struct iommu *)platform_get_drvdata(to_platform_device(dev))
+
+#endif /* __PLAT_OMAP_IOMMU_H */
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
new file mode 100644
index 00000000..83a37c54
--- /dev/null
+++ b/arch/arm/plat-omap/iovmm.c
@@ -0,0 +1,907 @@
+/*
+ * omap iommu: simple virtual address space management
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cacheflush.h>
+#include <asm/mach/map.h>
+
+#include <plat/iommu.h>
+#include <plat/iovmm.h>
+
+#include "iopgtable.h"
+
+/*
+ * A device driver needs to create address mappings between:
+ *
+ * - iommu/device address
+ * - physical address
+ * - mpu virtual address
+ *
+ * There are 4 possible patterns for them:
+ *
+ * |iova/ mapping iommu_ page
+ * | da pa va (d)-(p)-(v) function type
+ * ---------------------------------------------------------------------------
+ * 1 | c c c 1 - 1 - 1 _kmap() / _kunmap() s
+ * 2 | c c,a c 1 - 1 - 1 _kmalloc()/ _kfree() s
+ * 3 | c d c 1 - n - 1 _vmap() / _vunmap() s
+ * 4 | c d,a c 1 - n - 1 _vmalloc()/ _vfree() n*
+ *
+ *
+ * 'iova': device iommu virtual address
+ * 'da': alias of 'iova'
+ * 'pa': physical address
+ * 'va': mpu virtual address
+ *
+ * 'c': contiguous memory area
+ * 'd': discontiguous memory area
+ * 'a': anonymous memory allocation
+ * '()': optional feature
+ *
+ * 'n': a normal page(4KB) size is used.
+ * 's': multiple iommu superpage(16MB, 1MB, 64KB, 4KB) size is used.
+ *
+ * '*': not yet, but feasible.
+ */
+
+static struct kmem_cache *iovm_area_cachep;
+
+/* return total bytes of sg buffers */
+static size_t sgtable_len(const struct sg_table *sgt)
+{
+ unsigned int i, total = 0;
+ struct scatterlist *sg;
+
+ if (!sgt)
+ return 0;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ size_t bytes;
+
+ bytes = sg_dma_len(sg);
+
+ if (!iopgsz_ok(bytes)) {
+ pr_err("%s: sg[%d] not iommu pagesize(%x)\n",
+ __func__, i, bytes);
+ return 0;
+ }
+
+ total += bytes;
+ }
+
+ return total;
+}
+#define sgtable_ok(x) (!!sgtable_len(x))
+
+static unsigned max_alignment(u32 addr)
+{
+ int i;
+ unsigned pagesize[] = { SZ_16M, SZ_1M, SZ_64K, SZ_4K, };
+ for (i = 0; i < ARRAY_SIZE(pagesize) && addr & (pagesize[i] - 1); i++)
+ ;
+ return (i < ARRAY_SIZE(pagesize)) ? pagesize[i] : 0;
+}
+
+/*
+ * calculate the optimal number sg elements from total bytes based on
+ * iommu superpages
+ */
+static unsigned sgtable_nents(size_t bytes, u32 da, u32 pa)
+{
+ unsigned nr_entries = 0, ent_sz;
+
+ if (!IS_ALIGNED(bytes, PAGE_SIZE)) {
+ pr_err("%s: wrong size %08x\n", __func__, bytes);
+ return 0;
+ }
+
+ while (bytes) {
+ ent_sz = max_alignment(da | pa);
+ ent_sz = min_t(unsigned, ent_sz, iopgsz_max(bytes));
+ nr_entries++;
+ da += ent_sz;
+ pa += ent_sz;
+ bytes -= ent_sz;
+ }
+
+ return nr_entries;
+}
+
+/* allocate and initialize sg_table header(a kind of 'superblock') */
+static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags,
+ u32 da, u32 pa)
+{
+ unsigned int nr_entries;
+ int err;
+ struct sg_table *sgt;
+
+ if (!bytes)
+ return ERR_PTR(-EINVAL);
+
+ if (!IS_ALIGNED(bytes, PAGE_SIZE))
+ return ERR_PTR(-EINVAL);
+
+ if (flags & IOVMF_LINEAR) {
+ nr_entries = sgtable_nents(bytes, da, pa);
+ if (!nr_entries)
+ return ERR_PTR(-EINVAL);
+ } else
+ nr_entries = bytes / PAGE_SIZE;
+
+ sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt)
+ return ERR_PTR(-ENOMEM);
+
+ err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL);
+ if (err) {
+ kfree(sgt);
+ return ERR_PTR(err);
+ }
+
+ pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries);
+
+ return sgt;
+}
+
+/* free sg_table header(a kind of superblock) */
+static void sgtable_free(struct sg_table *sgt)
+{
+ if (!sgt)
+ return;
+
+ sg_free_table(sgt);
+ kfree(sgt);
+
+ pr_debug("%s: sgt:%p\n", __func__, sgt);
+}
+
+/* map 'sglist' to a contiguous mpu virtual area and return 'va' */
+static void *vmap_sg(const struct sg_table *sgt)
+{
+ u32 va;
+ size_t total;
+ unsigned int i;
+ struct scatterlist *sg;
+ struct vm_struct *new;
+ const struct mem_type *mtype;
+
+ mtype = get_mem_type(MT_DEVICE);
+ if (!mtype)
+ return ERR_PTR(-EINVAL);
+
+ total = sgtable_len(sgt);
+ if (!total)
+ return ERR_PTR(-EINVAL);
+
+ new = __get_vm_area(total, VM_IOREMAP, VMALLOC_START, VMALLOC_END);
+ if (!new)
+ return ERR_PTR(-ENOMEM);
+ va = (u32)new->addr;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ size_t bytes;
+ u32 pa;
+ int err;
+
+ pa = sg_phys(sg);
+ bytes = sg_dma_len(sg);
+
+ BUG_ON(bytes != PAGE_SIZE);
+
+ err = ioremap_page(va, pa, mtype);
+ if (err)
+ goto err_out;
+
+ va += bytes;
+ }
+
+ flush_cache_vmap((unsigned long)new->addr,
+ (unsigned long)(new->addr + total));
+ return new->addr;
+
+err_out:
+ WARN_ON(1); /* FIXME: cleanup some mpu mappings */
+ vunmap(new->addr);
+ return ERR_PTR(-EAGAIN);
+}
+
+static inline void vunmap_sg(const void *va)
+{
+ vunmap(va);
+}
+
+static struct iovm_struct *__find_iovm_area(struct iommu *obj, const u32 da)
+{
+ struct iovm_struct *tmp;
+
+ list_for_each_entry(tmp, &obj->mmap, list) {
+ if ((da >= tmp->da_start) && (da < tmp->da_end)) {
+ size_t len;
+
+ len = tmp->da_end - tmp->da_start;
+
+ dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n",
+ __func__, tmp->da_start, da, tmp->da_end, len,
+ tmp->flags);
+
+ return tmp;
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * find_iovm_area - find iovma which includes @da
+ * @da: iommu device virtual address
+ *
+ * Find the existing iovma starting at @da
+ */
+struct iovm_struct *find_iovm_area(struct iommu *obj, u32 da)
+{
+ struct iovm_struct *area;
+
+ mutex_lock(&obj->mmap_lock);
+ area = __find_iovm_area(obj, da);
+ mutex_unlock(&obj->mmap_lock);
+
+ return area;
+}
+EXPORT_SYMBOL_GPL(find_iovm_area);
+
+/*
+ * This finds the hole(area) which fits the requested address and len
+ * in iovmas mmap, and returns the new allocated iovma.
+ */
+static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
+ size_t bytes, u32 flags)
+{
+ struct iovm_struct *new, *tmp;
+ u32 start, prev_end, alignment;
+
+ if (!obj || !bytes)
+ return ERR_PTR(-EINVAL);
+
+ start = da;
+ alignment = PAGE_SIZE;
+
+ if (~flags & IOVMF_DA_FIXED) {
+ /* Don't map address 0 */
+ start = obj->da_start ? obj->da_start : alignment;
+
+ if (flags & IOVMF_LINEAR)
+ alignment = iopgsz_max(bytes);
+ start = roundup(start, alignment);
+ } else if (start < obj->da_start || start > obj->da_end ||
+ obj->da_end - start < bytes) {
+ return ERR_PTR(-EINVAL);
+ }
+
+ tmp = NULL;
+ if (list_empty(&obj->mmap))
+ goto found;
+
+ prev_end = 0;
+ list_for_each_entry(tmp, &obj->mmap, list) {
+
+ if (prev_end > start)
+ break;
+
+ if (tmp->da_start > start && (tmp->da_start - start) >= bytes)
+ goto found;
+
+ if (tmp->da_end >= start && ~flags & IOVMF_DA_FIXED)
+ start = roundup(tmp->da_end + 1, alignment);
+
+ prev_end = tmp->da_end;
+ }
+
+ if ((start >= prev_end) && (obj->da_end - start >= bytes))
+ goto found;
+
+ dev_dbg(obj->dev, "%s: no space to fit %08x(%x) flags: %08x\n",
+ __func__, da, bytes, flags);
+
+ return ERR_PTR(-EINVAL);
+
+found:
+ new = kmem_cache_zalloc(iovm_area_cachep, GFP_KERNEL);
+ if (!new)
+ return ERR_PTR(-ENOMEM);
+
+ new->iommu = obj;
+ new->da_start = start;
+ new->da_end = start + bytes;
+ new->flags = flags;
+
+ /*
+ * keep ascending order of iovmas
+ */
+ if (tmp)
+ list_add_tail(&new->list, &tmp->list);
+ else
+ list_add(&new->list, &obj->mmap);
+
+ dev_dbg(obj->dev, "%s: found %08x-%08x-%08x(%x) %08x\n",
+ __func__, new->da_start, start, new->da_end, bytes, flags);
+
+ return new;
+}
+
+static void free_iovm_area(struct iommu *obj, struct iovm_struct *area)
+{
+ size_t bytes;
+
+ BUG_ON(!obj || !area);
+
+ bytes = area->da_end - area->da_start;
+
+ dev_dbg(obj->dev, "%s: %08x-%08x(%x) %08x\n",
+ __func__, area->da_start, area->da_end, bytes, area->flags);
+
+ list_del(&area->list);
+ kmem_cache_free(iovm_area_cachep, area);
+}
+
+/**
+ * da_to_va - convert (d) to (v)
+ * @obj: objective iommu
+ * @da: iommu device virtual address
+ * @va: mpu virtual address
+ *
+ * Returns mpu virtual addr which corresponds to a given device virtual addr
+ */
+void *da_to_va(struct iommu *obj, u32 da)
+{
+ void *va = NULL;
+ struct iovm_struct *area;
+
+ mutex_lock(&obj->mmap_lock);
+
+ area = __find_iovm_area(obj, da);
+ if (!area) {
+ dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
+ goto out;
+ }
+ va = area->va;
+out:
+ mutex_unlock(&obj->mmap_lock);
+
+ return va;
+}
+EXPORT_SYMBOL_GPL(da_to_va);
+
+static void sgtable_fill_vmalloc(struct sg_table *sgt, void *_va)
+{
+ unsigned int i;
+ struct scatterlist *sg;
+ void *va = _va;
+ void *va_end;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ struct page *pg;
+ const size_t bytes = PAGE_SIZE;
+
+ /*
+ * iommu 'superpage' isn't supported with 'iommu_vmalloc()'
+ */
+ pg = vmalloc_to_page(va);
+ BUG_ON(!pg);
+ sg_set_page(sg, pg, bytes, 0);
+
+ va += bytes;
+ }
+
+ va_end = _va + PAGE_SIZE * i;
+}
+
+static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
+{
+ /*
+ * Actually this is not necessary at all, just exists for
+ * consistency of the code readability.
+ */
+ BUG_ON(!sgt);
+}
+
+static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da,
+ size_t len)
+{
+ unsigned int i;
+ struct scatterlist *sg;
+ void *va;
+
+ va = phys_to_virt(pa);
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ unsigned bytes;
+
+ bytes = max_alignment(da | pa);
+ bytes = min_t(unsigned, bytes, iopgsz_max(len));
+
+ BUG_ON(!iopgsz_ok(bytes));
+
+ sg_set_buf(sg, phys_to_virt(pa), bytes);
+ /*
+ * 'pa' is cotinuous(linear).
+ */
+ pa += bytes;
+ da += bytes;
+ len -= bytes;
+ }
+ BUG_ON(len);
+}
+
+static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
+{
+ /*
+ * Actually this is not necessary at all, just exists for
+ * consistency of the code readability
+ */
+ BUG_ON(!sgt);
+}
+
+/* create 'da' <-> 'pa' mapping from 'sgt' */
+static int map_iovm_area(struct iommu *obj, struct iovm_struct *new,
+ const struct sg_table *sgt, u32 flags)
+{
+ int err;
+ unsigned int i, j;
+ struct scatterlist *sg;
+ u32 da = new->da_start;
+
+ if (!obj || !sgt)
+ return -EINVAL;
+
+ BUG_ON(!sgtable_ok(sgt));
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+ u32 pa;
+ int pgsz;
+ size_t bytes;
+ struct iotlb_entry e;
+
+ pa = sg_phys(sg);
+ bytes = sg_dma_len(sg);
+
+ flags &= ~IOVMF_PGSZ_MASK;
+ pgsz = bytes_to_iopgsz(bytes);
+ if (pgsz < 0)
+ goto err_out;
+ flags |= pgsz;
+
+ pr_debug("%s: [%d] %08x %08x(%x)\n", __func__,
+ i, da, pa, bytes);
+
+ iotlb_init_entry(&e, da, pa, flags);
+ err = iopgtable_store_entry(obj, &e);
+ if (err)
+ goto err_out;
+
+ da += bytes;
+ }
+ return 0;
+
+err_out:
+ da = new->da_start;
+
+ for_each_sg(sgt->sgl, sg, i, j) {
+ size_t bytes;
+
+ bytes = iopgtable_clear_entry(obj, da);
+
+ BUG_ON(!iopgsz_ok(bytes));
+
+ da += bytes;
+ }
+ return err;
+}
+
+/* release 'da' <-> 'pa' mapping */
+static void unmap_iovm_area(struct iommu *obj, struct iovm_struct *area)
+{
+ u32 start;
+ size_t total = area->da_end - area->da_start;
+
+ BUG_ON((!total) || !IS_ALIGNED(total, PAGE_SIZE));
+
+ start = area->da_start;
+ while (total > 0) {
+ size_t bytes;
+
+ bytes = iopgtable_clear_entry(obj, start);
+ if (bytes == 0)
+ bytes = PAGE_SIZE;
+ else
+ dev_dbg(obj->dev, "%s: unmap %08x(%x) %08x\n",
+ __func__, start, bytes, area->flags);
+
+ BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE));
+
+ total -= bytes;
+ start += bytes;
+ }
+ BUG_ON(total);
+}
+
+/* template function for all unmapping */
+static struct sg_table *unmap_vm_area(struct iommu *obj, const u32 da,
+ void (*fn)(const void *), u32 flags)
+{
+ struct sg_table *sgt = NULL;
+ struct iovm_struct *area;
+
+ if (!IS_ALIGNED(da, PAGE_SIZE)) {
+ dev_err(obj->dev, "%s: alignment err(%08x)\n", __func__, da);
+ return NULL;
+ }
+
+ mutex_lock(&obj->mmap_lock);
+
+ area = __find_iovm_area(obj, da);
+ if (!area) {
+ dev_dbg(obj->dev, "%s: no da area(%08x)\n", __func__, da);
+ goto out;
+ }
+
+ if ((area->flags & flags) != flags) {
+ dev_err(obj->dev, "%s: wrong flags(%08x)\n", __func__,
+ area->flags);
+ goto out;
+ }
+ sgt = (struct sg_table *)area->sgt;
+
+ unmap_iovm_area(obj, area);
+
+ fn(area->va);
+
+ dev_dbg(obj->dev, "%s: %08x-%08x-%08x(%x) %08x\n", __func__,
+ area->da_start, da, area->da_end,
+ area->da_end - area->da_start, area->flags);
+
+ free_iovm_area(obj, area);
+out:
+ mutex_unlock(&obj->mmap_lock);
+
+ return sgt;
+}
+
+static u32 map_iommu_region(struct iommu *obj, u32 da,
+ const struct sg_table *sgt, void *va, size_t bytes, u32 flags)
+{
+ int err = -ENOMEM;
+ struct iovm_struct *new;
+
+ mutex_lock(&obj->mmap_lock);
+
+ new = alloc_iovm_area(obj, da, bytes, flags);
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ goto err_alloc_iovma;
+ }
+ new->va = va;
+ new->sgt = sgt;
+
+ if (map_iovm_area(obj, new, sgt, new->flags))
+ goto err_map;
+
+ mutex_unlock(&obj->mmap_lock);
+
+ dev_dbg(obj->dev, "%s: da:%08x(%x) flags:%08x va:%p\n",
+ __func__, new->da_start, bytes, new->flags, va);
+
+ return new->da_start;
+
+err_map:
+ free_iovm_area(obj, new);
+err_alloc_iovma:
+ mutex_unlock(&obj->mmap_lock);
+ return err;
+}
+
+static inline u32 __iommu_vmap(struct iommu *obj, u32 da,
+ const struct sg_table *sgt, void *va, size_t bytes, u32 flags)
+{
+ return map_iommu_region(obj, da, sgt, va, bytes, flags);
+}
+
+/**
+ * iommu_vmap - (d)-(p)-(v) address mapper
+ * @obj: objective iommu
+ * @sgt: address of scatter gather table
+ * @flags: iovma and page property
+ *
+ * Creates 1-n-1 mapping with given @sgt and returns @da.
+ * All @sgt element must be io page size aligned.
+ */
+u32 iommu_vmap(struct iommu *obj, u32 da, const struct sg_table *sgt,
+ u32 flags)
+{
+ size_t bytes;
+ void *va = NULL;
+
+ if (!obj || !obj->dev || !sgt)
+ return -EINVAL;
+
+ bytes = sgtable_len(sgt);
+ if (!bytes)
+ return -EINVAL;
+ bytes = PAGE_ALIGN(bytes);
+
+ if (flags & IOVMF_MMIO) {
+ va = vmap_sg(sgt);
+ if (IS_ERR(va))
+ return PTR_ERR(va);
+ }
+
+ flags |= IOVMF_DISCONT;
+ flags |= IOVMF_MMIO;
+
+ da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
+ if (IS_ERR_VALUE(da))
+ vunmap_sg(va);
+
+ return da;
+}
+EXPORT_SYMBOL_GPL(iommu_vmap);
+
+/**
+ * iommu_vunmap - release virtual mapping obtained by 'iommu_vmap()'
+ * @obj: objective iommu
+ * @da: iommu device virtual address
+ *
+ * Free the iommu virtually contiguous memory area starting at
+ * @da, which was returned by 'iommu_vmap()'.
+ */
+struct sg_table *iommu_vunmap(struct iommu *obj, u32 da)
+{
+ struct sg_table *sgt;
+ /*
+ * 'sgt' is allocated before 'iommu_vmalloc()' is called.
+ * Just returns 'sgt' to the caller to free
+ */
+ sgt = unmap_vm_area(obj, da, vunmap_sg, IOVMF_DISCONT | IOVMF_MMIO);
+ if (!sgt)
+ dev_dbg(obj->dev, "%s: No sgt\n", __func__);
+ return sgt;
+}
+EXPORT_SYMBOL_GPL(iommu_vunmap);
+
+/**
+ * iommu_vmalloc - (d)-(p)-(v) address allocator and mapper
+ * @obj: objective iommu
+ * @da: contiguous iommu virtual memory
+ * @bytes: allocation size
+ * @flags: iovma and page property
+ *
+ * Allocate @bytes linearly and creates 1-n-1 mapping and returns
+ * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set.
+ */
+u32 iommu_vmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
+{
+ void *va;
+ struct sg_table *sgt;
+
+ if (!obj || !obj->dev || !bytes)
+ return -EINVAL;
+
+ bytes = PAGE_ALIGN(bytes);
+
+ va = vmalloc(bytes);
+ if (!va)
+ return -ENOMEM;
+
+ flags |= IOVMF_DISCONT;
+ flags |= IOVMF_ALLOC;
+
+ sgt = sgtable_alloc(bytes, flags, da, 0);
+ if (IS_ERR(sgt)) {
+ da = PTR_ERR(sgt);
+ goto err_sgt_alloc;
+ }
+ sgtable_fill_vmalloc(sgt, va);
+
+ da = __iommu_vmap(obj, da, sgt, va, bytes, flags);
+ if (IS_ERR_VALUE(da))
+ goto err_iommu_vmap;
+
+ return da;
+
+err_iommu_vmap:
+ sgtable_drain_vmalloc(sgt);
+ sgtable_free(sgt);
+err_sgt_alloc:
+ vfree(va);
+ return da;
+}
+EXPORT_SYMBOL_GPL(iommu_vmalloc);
+
+/**
+ * iommu_vfree - release memory allocated by 'iommu_vmalloc()'
+ * @obj: objective iommu
+ * @da: iommu device virtual address
+ *
+ * Frees the iommu virtually continuous memory area starting at
+ * @da, as obtained from 'iommu_vmalloc()'.
+ */
+void iommu_vfree(struct iommu *obj, const u32 da)
+{
+ struct sg_table *sgt;
+
+ sgt = unmap_vm_area(obj, da, vfree, IOVMF_DISCONT | IOVMF_ALLOC);
+ if (!sgt)
+ dev_dbg(obj->dev, "%s: No sgt\n", __func__);
+ sgtable_free(sgt);
+}
+EXPORT_SYMBOL_GPL(iommu_vfree);
+
+static u32 __iommu_kmap(struct iommu *obj, u32 da, u32 pa, void *va,
+ size_t bytes, u32 flags)
+{
+ struct sg_table *sgt;
+
+ sgt = sgtable_alloc(bytes, flags, da, pa);
+ if (IS_ERR(sgt))
+ return PTR_ERR(sgt);
+
+ sgtable_fill_kmalloc(sgt, pa, da, bytes);
+
+ da = map_iommu_region(obj, da, sgt, va, bytes, flags);
+ if (IS_ERR_VALUE(da)) {
+ sgtable_drain_kmalloc(sgt);
+ sgtable_free(sgt);
+ }
+
+ return da;
+}
+
+/**
+ * iommu_kmap - (d)-(p)-(v) address mapper
+ * @obj: objective iommu
+ * @da: contiguous iommu virtual memory
+ * @pa: contiguous physical memory
+ * @flags: iovma and page property
+ *
+ * Creates 1-1-1 mapping and returns @da again, which can be
+ * adjusted if 'IOVMF_DA_FIXED' is not set.
+ */
+u32 iommu_kmap(struct iommu *obj, u32 da, u32 pa, size_t bytes,
+ u32 flags)
+{
+ void *va;
+
+ if (!obj || !obj->dev || !bytes)
+ return -EINVAL;
+
+ bytes = PAGE_ALIGN(bytes);
+
+ va = ioremap(pa, bytes);
+ if (!va)
+ return -ENOMEM;
+
+ flags |= IOVMF_LINEAR;
+ flags |= IOVMF_MMIO;
+
+ da = __iommu_kmap(obj, da, pa, va, bytes, flags);
+ if (IS_ERR_VALUE(da))
+ iounmap(va);
+
+ return da;
+}
+EXPORT_SYMBOL_GPL(iommu_kmap);
+
+/**
+ * iommu_kunmap - release virtual mapping obtained by 'iommu_kmap()'
+ * @obj: objective iommu
+ * @da: iommu device virtual address
+ *
+ * Frees the iommu virtually contiguous memory area starting at
+ * @da, which was passed to and was returned by'iommu_kmap()'.
+ */
+void iommu_kunmap(struct iommu *obj, u32 da)
+{
+ struct sg_table *sgt;
+ typedef void (*func_t)(const void *);
+
+ sgt = unmap_vm_area(obj, da, (func_t)iounmap,
+ IOVMF_LINEAR | IOVMF_MMIO);
+ if (!sgt)
+ dev_dbg(obj->dev, "%s: No sgt\n", __func__);
+ sgtable_free(sgt);
+}
+EXPORT_SYMBOL_GPL(iommu_kunmap);
+
+/**
+ * iommu_kmalloc - (d)-(p)-(v) address allocator and mapper
+ * @obj: objective iommu
+ * @da: contiguous iommu virtual memory
+ * @bytes: bytes for allocation
+ * @flags: iovma and page property
+ *
+ * Allocate @bytes linearly and creates 1-1-1 mapping and returns
+ * @da again, which might be adjusted if 'IOVMF_DA_FIXED' is not set.
+ */
+u32 iommu_kmalloc(struct iommu *obj, u32 da, size_t bytes, u32 flags)
+{
+ void *va;
+ u32 pa;
+
+ if (!obj || !obj->dev || !bytes)
+ return -EINVAL;
+
+ bytes = PAGE_ALIGN(bytes);
+
+ va = kmalloc(bytes, GFP_KERNEL | GFP_DMA);
+ if (!va)
+ return -ENOMEM;
+ pa = virt_to_phys(va);
+
+ flags |= IOVMF_LINEAR;
+ flags |= IOVMF_ALLOC;
+
+ da = __iommu_kmap(obj, da, pa, va, bytes, flags);
+ if (IS_ERR_VALUE(da))
+ kfree(va);
+
+ return da;
+}
+EXPORT_SYMBOL_GPL(iommu_kmalloc);
+
+/**
+ * iommu_kfree - release virtual mapping obtained by 'iommu_kmalloc()'
+ * @obj: objective iommu
+ * @da: iommu device virtual address
+ *
+ * Frees the iommu virtually contiguous memory area starting at
+ * @da, which was passed to and was returned by'iommu_kmalloc()'.
+ */
+void iommu_kfree(struct iommu *obj, u32 da)
+{
+ struct sg_table *sgt;
+
+ sgt = unmap_vm_area(obj, da, kfree, IOVMF_LINEAR | IOVMF_ALLOC);
+ if (!sgt)
+ dev_dbg(obj->dev, "%s: No sgt\n", __func__);
+ sgtable_free(sgt);
+}
+EXPORT_SYMBOL_GPL(iommu_kfree);
+
+
+static int __init iovmm_init(void)
+{
+ const unsigned long flags = SLAB_HWCACHE_ALIGN;
+ struct kmem_cache *p;
+
+ p = kmem_cache_create("iovm_area_cache", sizeof(struct iovm_struct), 0,
+ flags, NULL);
+ if (!p)
+ return -ENOMEM;
+ iovm_area_cachep = p;
+
+ return 0;
+}
+module_init(iovmm_init);
+
+static void __exit iovmm_exit(void)
+{
+ kmem_cache_destroy(iovm_area_cachep);
+}
+module_exit(iovmm_exit);
+
+MODULE_DESCRIPTION("omap iommu: simple virtual address space management");
+MODULE_AUTHOR("Hiroshi DOYU <Hiroshi.DOYU@nokia.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
new file mode 100644
index 00000000..69ddc9f7
--- /dev/null
+++ b/arch/arm/plat-omap/mailbox.c
@@ -0,0 +1,429 @@
+/*
+ * OMAP mailbox driver
+ *
+ * Copyright (C) 2006-2009 Nokia Corporation. All rights reserved.
+ *
+ * Contact: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/kfifo.h>
+#include <linux/err.h>
+#include <linux/notifier.h>
+
+#include <plat/mailbox.h>
+
+static struct omap_mbox **mboxes;
+
+static int mbox_configured;
+static DEFINE_MUTEX(mbox_configured_lock);
+
+static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE;
+module_param(mbox_kfifo_size, uint, S_IRUGO);
+MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)");
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_read(mbox);
+}
+static inline void mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ mbox->ops->fifo_write(mbox, msg);
+}
+static inline int mbox_fifo_empty(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_empty(mbox);
+}
+static inline int mbox_fifo_full(struct omap_mbox *mbox)
+{
+ return mbox->ops->fifo_full(mbox);
+}
+
+/* Mailbox IRQ handle functions */
+static inline void ack_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ if (mbox->ops->ack_irq)
+ mbox->ops->ack_irq(mbox, irq);
+}
+static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq)
+{
+ return mbox->ops->is_irq(mbox, irq);
+}
+
+/*
+ * message sender
+ */
+static int __mbox_poll_for_space(struct omap_mbox *mbox)
+{
+ int ret = 0, i = 1000;
+
+ while (mbox_fifo_full(mbox)) {
+ if (mbox->ops->type == OMAP_MBOX_TYPE2)
+ return -1;
+ if (--i == 0)
+ return -1;
+ udelay(1);
+ }
+ return ret;
+}
+
+int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+ struct omap_mbox_queue *mq = mbox->txq;
+ int ret = 0, len;
+
+ spin_lock_bh(&mq->lock);
+
+ if (kfifo_avail(&mq->fifo) < sizeof(msg)) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (kfifo_is_empty(&mq->fifo) && !__mbox_poll_for_space(mbox)) {
+ mbox_fifo_write(mbox, msg);
+ goto out;
+ }
+
+ len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+ WARN_ON(len != sizeof(msg));
+
+ tasklet_schedule(&mbox->txq->tasklet);
+
+out:
+ spin_unlock_bh(&mq->lock);
+ return ret;
+}
+EXPORT_SYMBOL(omap_mbox_msg_send);
+
+static void mbox_tx_tasklet(unsigned long tx_data)
+{
+ struct omap_mbox *mbox = (struct omap_mbox *)tx_data;
+ struct omap_mbox_queue *mq = mbox->txq;
+ mbox_msg_t msg;
+ int ret;
+
+ while (kfifo_len(&mq->fifo)) {
+ if (__mbox_poll_for_space(mbox)) {
+ omap_mbox_enable_irq(mbox, IRQ_TX);
+ break;
+ }
+
+ ret = kfifo_out(&mq->fifo, (unsigned char *)&msg,
+ sizeof(msg));
+ WARN_ON(ret != sizeof(msg));
+
+ mbox_fifo_write(mbox, msg);
+ }
+}
+
+/*
+ * Message receiver(workqueue)
+ */
+static void mbox_rx_work(struct work_struct *work)
+{
+ struct omap_mbox_queue *mq =
+ container_of(work, struct omap_mbox_queue, work);
+ mbox_msg_t msg;
+ int len;
+
+ while (kfifo_len(&mq->fifo) >= sizeof(msg)) {
+ len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+ WARN_ON(len != sizeof(msg));
+
+ blocking_notifier_call_chain(&mq->mbox->notifier, len,
+ (void *)msg);
+ spin_lock_irq(&mq->lock);
+ if (mq->full) {
+ mq->full = false;
+ omap_mbox_enable_irq(mq->mbox, IRQ_RX);
+ }
+ spin_unlock_irq(&mq->lock);
+ }
+}
+
+/*
+ * Mailbox interrupt handler
+ */
+static void __mbox_tx_interrupt(struct omap_mbox *mbox)
+{
+ omap_mbox_disable_irq(mbox, IRQ_TX);
+ ack_mbox_irq(mbox, IRQ_TX);
+ tasklet_schedule(&mbox->txq->tasklet);
+}
+
+static void __mbox_rx_interrupt(struct omap_mbox *mbox)
+{
+ struct omap_mbox_queue *mq = mbox->rxq;
+ mbox_msg_t msg;
+ int len;
+
+ while (!mbox_fifo_empty(mbox)) {
+ if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) {
+ omap_mbox_disable_irq(mbox, IRQ_RX);
+ mq->full = true;
+ goto nomem;
+ }
+
+ msg = mbox_fifo_read(mbox);
+
+ len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg));
+ WARN_ON(len != sizeof(msg));
+
+ if (mbox->ops->type == OMAP_MBOX_TYPE1)
+ break;
+ }
+
+ /* no more messages in the fifo. clear IRQ source. */
+ ack_mbox_irq(mbox, IRQ_RX);
+nomem:
+ schedule_work(&mbox->rxq->work);
+}
+
+static irqreturn_t mbox_interrupt(int irq, void *p)
+{
+ struct omap_mbox *mbox = p;
+
+ if (is_mbox_irq(mbox, IRQ_TX))
+ __mbox_tx_interrupt(mbox);
+
+ if (is_mbox_irq(mbox, IRQ_RX))
+ __mbox_rx_interrupt(mbox);
+
+ return IRQ_HANDLED;
+}
+
+static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox,
+ void (*work) (struct work_struct *),
+ void (*tasklet)(unsigned long))
+{
+ struct omap_mbox_queue *mq;
+
+ mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL);
+ if (!mq)
+ return NULL;
+
+ spin_lock_init(&mq->lock);
+
+ if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL))
+ goto error;
+
+ if (work)
+ INIT_WORK(&mq->work, work);
+
+ if (tasklet)
+ tasklet_init(&mq->tasklet, tasklet, (unsigned long)mbox);
+ return mq;
+error:
+ kfree(mq);
+ return NULL;
+}
+
+static void mbox_queue_free(struct omap_mbox_queue *q)
+{
+ kfifo_free(&q->fifo);
+ kfree(q);
+}
+
+static int omap_mbox_startup(struct omap_mbox *mbox)
+{
+ int ret = 0;
+ struct omap_mbox_queue *mq;
+
+ mutex_lock(&mbox_configured_lock);
+ if (!mbox_configured++) {
+ if (likely(mbox->ops->startup)) {
+ ret = mbox->ops->startup(mbox);
+ if (unlikely(ret))
+ goto fail_startup;
+ } else
+ goto fail_startup;
+ }
+
+ if (!mbox->use_count++) {
+ ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED,
+ mbox->name, mbox);
+ if (unlikely(ret)) {
+ pr_err("failed to register mailbox interrupt:%d\n",
+ ret);
+ goto fail_request_irq;
+ }
+ mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_txq;
+ }
+ mbox->txq = mq;
+
+ mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL);
+ if (!mq) {
+ ret = -ENOMEM;
+ goto fail_alloc_rxq;
+ }
+ mbox->rxq = mq;
+ mq->mbox = mbox;
+ }
+ mutex_unlock(&mbox_configured_lock);
+ return 0;
+
+fail_alloc_rxq:
+ mbox_queue_free(mbox->txq);
+fail_alloc_txq:
+ free_irq(mbox->irq, mbox);
+fail_request_irq:
+ if (mbox->ops->shutdown)
+ mbox->ops->shutdown(mbox);
+ mbox->use_count--;
+fail_startup:
+ mbox_configured--;
+ mutex_unlock(&mbox_configured_lock);
+ return ret;
+}
+
+static void omap_mbox_fini(struct omap_mbox *mbox)
+{
+ mutex_lock(&mbox_configured_lock);
+
+ if (!--mbox->use_count) {
+ free_irq(mbox->irq, mbox);
+ tasklet_kill(&mbox->txq->tasklet);
+ flush_work_sync(&mbox->rxq->work);
+ mbox_queue_free(mbox->txq);
+ mbox_queue_free(mbox->rxq);
+ }
+
+ if (likely(mbox->ops->shutdown)) {
+ if (!--mbox_configured)
+ mbox->ops->shutdown(mbox);
+ }
+
+ mutex_unlock(&mbox_configured_lock);
+}
+
+struct omap_mbox *omap_mbox_get(const char *name, struct notifier_block *nb)
+{
+ struct omap_mbox *_mbox, *mbox = NULL;
+ int i, ret;
+
+ if (!mboxes)
+ return ERR_PTR(-EINVAL);
+
+ for (i = 0; (_mbox = mboxes[i]); i++) {
+ if (!strcmp(_mbox->name, name)) {
+ mbox = _mbox;
+ break;
+ }
+ }
+
+ if (!mbox)
+ return ERR_PTR(-ENOENT);
+
+ ret = omap_mbox_startup(mbox);
+ if (ret)
+ return ERR_PTR(-ENODEV);
+
+ if (nb)
+ blocking_notifier_chain_register(&mbox->notifier, nb);
+
+ return mbox;
+}
+EXPORT_SYMBOL(omap_mbox_get);
+
+void omap_mbox_put(struct omap_mbox *mbox, struct notifier_block *nb)
+{
+ blocking_notifier_chain_unregister(&mbox->notifier, nb);
+ omap_mbox_fini(mbox);
+}
+EXPORT_SYMBOL(omap_mbox_put);
+
+static struct class omap_mbox_class = { .name = "mbox", };
+
+int omap_mbox_register(struct device *parent, struct omap_mbox **list)
+{
+ int ret;
+ int i;
+
+ mboxes = list;
+ if (!mboxes)
+ return -EINVAL;
+
+ for (i = 0; mboxes[i]; i++) {
+ struct omap_mbox *mbox = mboxes[i];
+ mbox->dev = device_create(&omap_mbox_class,
+ parent, 0, mbox, "%s", mbox->name);
+ if (IS_ERR(mbox->dev)) {
+ ret = PTR_ERR(mbox->dev);
+ goto err_out;
+ }
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&mbox->notifier);
+ }
+ return 0;
+
+err_out:
+ while (i--)
+ device_unregister(mboxes[i]->dev);
+ return ret;
+}
+EXPORT_SYMBOL(omap_mbox_register);
+
+int omap_mbox_unregister(void)
+{
+ int i;
+
+ if (!mboxes)
+ return -EINVAL;
+
+ for (i = 0; mboxes[i]; i++)
+ device_unregister(mboxes[i]->dev);
+ mboxes = NULL;
+ return 0;
+}
+EXPORT_SYMBOL(omap_mbox_unregister);
+
+static int __init omap_mbox_init(void)
+{
+ int err;
+
+ err = class_register(&omap_mbox_class);
+ if (err)
+ return err;
+
+ /* kfifo size sanity check: alignment and minimal size */
+ mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t));
+ mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size,
+ sizeof(mbox_msg_t));
+
+ return 0;
+}
+subsys_initcall(omap_mbox_init);
+
+static void __exit omap_mbox_exit(void)
+{
+ class_unregister(&omap_mbox_class);
+}
+module_exit(omap_mbox_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging");
+MODULE_AUTHOR("Toshihiro Kobayashi");
+MODULE_AUTHOR("Hiroshi DOYU");
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
new file mode 100644
index 00000000..5587acf0
--- /dev/null
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -0,0 +1,1952 @@
+/*
+ * linux/arch/arm/plat-omap/mcbsp.c
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Multichannel mode not supported.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <plat/dma.h>
+#include <plat/mcbsp.h>
+#include <plat/omap_device.h>
+#include <linux/pm_runtime.h>
+
+/* XXX These "sideways" includes are a sign that something is wrong */
+#include "../mach-omap2/cm2xxx_3xxx.h"
+#include "../mach-omap2/cm-regbits-34xx.h"
+
+struct omap_mcbsp **mcbsp_ptr;
+int omap_mcbsp_count, omap_mcbsp_cache_size;
+
+static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
+{
+ if (cpu_class_is_omap1()) {
+ ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
+ __raw_writew((u16)val, mcbsp->io_base + reg);
+ } else if (cpu_is_omap2420()) {
+ ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
+ __raw_writew((u16)val, mcbsp->io_base + reg);
+ } else {
+ ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
+ __raw_writel(val, mcbsp->io_base + reg);
+ }
+}
+
+static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
+{
+ if (cpu_class_is_omap1()) {
+ return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+ ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
+ } else if (cpu_is_omap2420()) {
+ return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
+ ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+ } else {
+ return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
+ ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+ }
+}
+
+#ifdef CONFIG_ARCH_OMAP3
+static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
+{
+ __raw_writel(val, mcbsp->st_data->io_base_st + reg);
+}
+
+static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
+{
+ return __raw_readl(mcbsp->st_data->io_base_st + reg);
+}
+#endif
+
+#define MCBSP_READ(mcbsp, reg) \
+ omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
+#define MCBSP_WRITE(mcbsp, reg, val) \
+ omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val)
+#define MCBSP_READ_CACHE(mcbsp, reg) \
+ omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
+
+#define MCBSP_ST_READ(mcbsp, reg) \
+ omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
+#define MCBSP_ST_WRITE(mcbsp, reg, val) \
+ omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val)
+
+static void omap_mcbsp_dump_reg(u8 id)
+{
+ struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
+
+ dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
+ dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, DRR2));
+ dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, DRR1));
+ dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, DXR2));
+ dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, DXR1));
+ dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, SPCR2));
+ dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, SPCR1));
+ dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, RCR2));
+ dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, RCR1));
+ dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, XCR2));
+ dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, XCR1));
+ dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
+ MCBSP_READ(mcbsp, SRGR2));
+ dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
+ MCBSP_READ(mcbsp, SRGR1));
+ dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
+ MCBSP_READ(mcbsp, PCR0));
+ dev_dbg(mcbsp->dev, "***********************\n");
+}
+
+static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
+{
+ struct omap_mcbsp *mcbsp_tx = dev_id;
+ u16 irqst_spcr2;
+
+ irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2);
+ dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2);
+
+ if (irqst_spcr2 & XSYNC_ERR) {
+ dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n",
+ irqst_spcr2);
+ /* Writing zero to XSYNC_ERR clears the IRQ */
+ MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2));
+ } else {
+ complete(&mcbsp_tx->tx_irq_completion);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id)
+{
+ struct omap_mcbsp *mcbsp_rx = dev_id;
+ u16 irqst_spcr1;
+
+ irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1);
+ dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1);
+
+ if (irqst_spcr1 & RSYNC_ERR) {
+ dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n",
+ irqst_spcr1);
+ /* Writing zero to RSYNC_ERR clears the IRQ */
+ MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1));
+ } else {
+ complete(&mcbsp_rx->rx_irq_completion);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
+{
+ struct omap_mcbsp *mcbsp_dma_tx = data;
+
+ dev_dbg(mcbsp_dma_tx->dev, "TX DMA callback : 0x%x\n",
+ MCBSP_READ(mcbsp_dma_tx, SPCR2));
+
+ /* We can free the channels */
+ omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
+ mcbsp_dma_tx->dma_tx_lch = -1;
+
+ complete(&mcbsp_dma_tx->tx_dma_completion);
+}
+
+static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
+{
+ struct omap_mcbsp *mcbsp_dma_rx = data;
+
+ dev_dbg(mcbsp_dma_rx->dev, "RX DMA callback : 0x%x\n",
+ MCBSP_READ(mcbsp_dma_rx, SPCR2));
+
+ /* We can free the channels */
+ omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
+ mcbsp_dma_rx->dma_rx_lch = -1;
+
+ complete(&mcbsp_dma_rx->rx_dma_completion);
+}
+
+/*
+ * omap_mcbsp_config simply write a config to the
+ * appropriate McBSP.
+ * You either call this function or set the McBSP registers
+ * by yourself before calling omap_mcbsp_start().
+ */
+void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
+ mcbsp->id, mcbsp->phys_base);
+
+ /* We write the given config */
+ MCBSP_WRITE(mcbsp, SPCR2, config->spcr2);
+ MCBSP_WRITE(mcbsp, SPCR1, config->spcr1);
+ MCBSP_WRITE(mcbsp, RCR2, config->rcr2);
+ MCBSP_WRITE(mcbsp, RCR1, config->rcr1);
+ MCBSP_WRITE(mcbsp, XCR2, config->xcr2);
+ MCBSP_WRITE(mcbsp, XCR1, config->xcr1);
+ MCBSP_WRITE(mcbsp, SRGR2, config->srgr2);
+ MCBSP_WRITE(mcbsp, SRGR1, config->srgr1);
+ MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
+ MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
+ MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ MCBSP_WRITE(mcbsp, XCCR, config->xccr);
+ MCBSP_WRITE(mcbsp, RCCR, config->rccr);
+ }
+}
+EXPORT_SYMBOL(omap_mcbsp_config);
+
+/**
+ * omap_mcbsp_dma_params - returns the dma channel number
+ * @id - mcbsp id
+ * @stream - indicates the direction of data flow (rx or tx)
+ *
+ * Returns the dma channel number for the rx channel or tx channel
+ * based on the value of @stream for the requested mcbsp given by @id
+ */
+int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (stream)
+ return mcbsp->dma_rx_sync;
+ else
+ return mcbsp->dma_tx_sync;
+}
+EXPORT_SYMBOL(omap_mcbsp_dma_ch_params);
+
+/**
+ * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register
+ * @id - mcbsp id
+ * @stream - indicates the direction of data flow (rx or tx)
+ *
+ * Returns the address of mcbsp data transmit register or data receive register
+ * to be used by DMA for transferring/receiving data based on the value of
+ * @stream for the requested mcbsp given by @id
+ */
+int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream)
+{
+ struct omap_mcbsp *mcbsp;
+ int data_reg;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ data_reg = mcbsp->phys_dma_base;
+
+ if (mcbsp->mcbsp_config_type < MCBSP_CONFIG_TYPE2) {
+ if (stream)
+ data_reg += OMAP_MCBSP_REG_DRR1;
+ else
+ data_reg += OMAP_MCBSP_REG_DXR1;
+ } else {
+ if (stream)
+ data_reg += OMAP_MCBSP_REG_DRR;
+ else
+ data_reg += OMAP_MCBSP_REG_DXR;
+ }
+
+ return data_reg;
+}
+EXPORT_SYMBOL(omap_mcbsp_dma_reg_params);
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap_device *find_omap_device_by_dev(struct device *dev)
+{
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ return container_of(pdev, struct omap_device, pdev);
+}
+
+static void omap_st_on(struct omap_mcbsp *mcbsp)
+{
+ unsigned int w;
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+
+ /*
+ * Sidetone uses McBSP ICLK - which must not idle when sidetones
+ * are enabled or sidetones start sounding ugly.
+ */
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w &= ~(1 << (mcbsp->id - 2));
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+
+ /* Enable McBSP Sidetone */
+ w = MCBSP_READ(mcbsp, SSELCR);
+ MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
+
+ /* Enable Sidetone from Sidetone Core */
+ w = MCBSP_ST_READ(mcbsp, SSELCR);
+ MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
+}
+
+static void omap_st_off(struct omap_mcbsp *mcbsp)
+{
+ unsigned int w;
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+
+ w = MCBSP_ST_READ(mcbsp, SSELCR);
+ MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
+
+ w = MCBSP_READ(mcbsp, SSELCR);
+ MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
+
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ w |= 1 << (mcbsp->id - 2);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+}
+
+static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
+{
+ u16 val, i;
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+
+ val = MCBSP_ST_READ(mcbsp, SSELCR);
+
+ if (val & ST_COEFFWREN)
+ MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
+
+ MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN);
+
+ for (i = 0; i < 128; i++)
+ MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]);
+
+ i = 0;
+
+ val = MCBSP_ST_READ(mcbsp, SSELCR);
+ while (!(val & ST_COEFFWRDONE) && (++i < 1000))
+ val = MCBSP_ST_READ(mcbsp, SSELCR);
+
+ MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN));
+
+ if (i == 1000)
+ dev_err(mcbsp->dev, "McBSP FIR load error!\n");
+}
+
+static void omap_st_chgain(struct omap_mcbsp *mcbsp)
+{
+ u16 w;
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+
+ w = MCBSP_ST_READ(mcbsp, SSELCR);
+
+ MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \
+ ST_CH1GAIN(st_data->ch1gain));
+}
+
+int omap_st_set_chgain(unsigned int id, int channel, s16 chgain)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_st_data *st_data;
+ int ret = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ st_data = mcbsp->st_data;
+
+ if (!st_data)
+ return -ENOENT;
+
+ spin_lock_irq(&mcbsp->lock);
+ if (channel == 0)
+ st_data->ch0gain = chgain;
+ else if (channel == 1)
+ st_data->ch1gain = chgain;
+ else
+ ret = -EINVAL;
+
+ if (st_data->enabled)
+ omap_st_chgain(mcbsp);
+ spin_unlock_irq(&mcbsp->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_st_set_chgain);
+
+int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_st_data *st_data;
+ int ret = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ st_data = mcbsp->st_data;
+
+ if (!st_data)
+ return -ENOENT;
+
+ spin_lock_irq(&mcbsp->lock);
+ if (channel == 0)
+ *chgain = st_data->ch0gain;
+ else if (channel == 1)
+ *chgain = st_data->ch1gain;
+ else
+ ret = -EINVAL;
+ spin_unlock_irq(&mcbsp->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_st_get_chgain);
+
+static int omap_st_start(struct omap_mcbsp *mcbsp)
+{
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+ if (st_data && st_data->enabled && !st_data->running) {
+ omap_st_fir_write(mcbsp, st_data->taps);
+ omap_st_chgain(mcbsp);
+
+ if (!mcbsp->free) {
+ omap_st_on(mcbsp);
+ st_data->running = 1;
+ }
+ }
+
+ return 0;
+}
+
+int omap_st_enable(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_st_data *st_data;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ st_data = mcbsp->st_data;
+
+ if (!st_data)
+ return -ENODEV;
+
+ spin_lock_irq(&mcbsp->lock);
+ st_data->enabled = 1;
+ omap_st_start(mcbsp);
+ spin_unlock_irq(&mcbsp->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_st_enable);
+
+static int omap_st_stop(struct omap_mcbsp *mcbsp)
+{
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+ if (st_data && st_data->running) {
+ if (!mcbsp->free) {
+ omap_st_off(mcbsp);
+ st_data->running = 0;
+ }
+ }
+
+ return 0;
+}
+
+int omap_st_disable(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_st_data *st_data;
+ int ret = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ st_data = mcbsp->st_data;
+
+ if (!st_data)
+ return -ENODEV;
+
+ spin_lock_irq(&mcbsp->lock);
+ omap_st_stop(mcbsp);
+ st_data->enabled = 0;
+ spin_unlock_irq(&mcbsp->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_st_disable);
+
+int omap_st_is_enabled(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_st_data *st_data;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ st_data = mcbsp->st_data;
+
+ if (!st_data)
+ return -ENODEV;
+
+
+ return st_data->enabled;
+}
+EXPORT_SYMBOL(omap_st_is_enabled);
+
+/*
+ * omap_mcbsp_set_rx_threshold configures the transmit threshold in words.
+ * The threshold parameter is 1 based, and it is converted (threshold - 1)
+ * for the THRSH2 register.
+ */
+void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
+ return;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (threshold && threshold <= mcbsp->max_tx_thres)
+ MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
+}
+EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
+
+/*
+ * omap_mcbsp_set_rx_threshold configures the receive threshold in words.
+ * The threshold parameter is 1 based, and it is converted (threshold - 1)
+ * for the THRSH1 register.
+ */
+void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
+ return;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (threshold && threshold <= mcbsp->max_rx_thres)
+ MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
+}
+EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
+
+/*
+ * omap_mcbsp_get_max_tx_thres just return the current configured
+ * maximum threshold for transmission
+ */
+u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ return mcbsp->max_tx_thres;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
+
+/*
+ * omap_mcbsp_get_max_rx_thres just return the current configured
+ * maximum threshold for reception
+ */
+u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ return mcbsp->max_rx_thres;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
+
+u16 omap_mcbsp_get_fifo_size(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ return mcbsp->pdata->buffer_size;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_fifo_size);
+
+/*
+ * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO
+ */
+u16 omap_mcbsp_get_tx_delay(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ u16 buffstat;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ /* Returns the number of free locations in the buffer */
+ buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
+
+ /* Number of slots are different in McBSP ports */
+ return mcbsp->pdata->buffer_size - buffstat;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_tx_delay);
+
+/*
+ * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO
+ * to reach the threshold value (when the DMA will be triggered to read it)
+ */
+u16 omap_mcbsp_get_rx_delay(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ u16 buffstat, threshold;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ /* Returns the number of used locations in the buffer */
+ buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
+ /* RX threshold */
+ threshold = MCBSP_READ(mcbsp, THRSH1);
+
+ /* Return the number of location till we reach the threshold limit */
+ if (threshold <= buffstat)
+ return 0;
+ else
+ return threshold - buffstat;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_rx_delay);
+
+/*
+ * omap_mcbsp_get_dma_op_mode just return the current configured
+ * operating mode for the mcbsp channel
+ */
+int omap_mcbsp_get_dma_op_mode(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ int dma_op_mode;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ dma_op_mode = mcbsp->dma_op_mode;
+
+ return dma_op_mode;
+}
+EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
+
+static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
+{
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+ /*
+ * Enable wakup behavior, smart idle and all wakeups
+ * REVISIT: some wakeups may be unnecessary
+ */
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
+ }
+}
+
+static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
+{
+ struct omap_device *od;
+
+ od = find_omap_device_by_dev(mcbsp->dev);
+
+ /*
+ * Disable wakup behavior, smart idle and all wakeups
+ */
+ if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ /*
+ * HW bug workaround - If no_idle mode is taken, we need to
+ * go to smart_idle before going to always_idle, or the
+ * device will not hit retention anymore.
+ */
+
+ MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
+ }
+}
+#else
+static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
+static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
+static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
+static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
+#endif
+
+/*
+ * We can choose between IRQ based or polled IO.
+ * This needs to be called before omap_mcbsp_request().
+ */
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ spin_lock(&mcbsp->lock);
+
+ if (!mcbsp->free) {
+ dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+ mcbsp->id);
+ spin_unlock(&mcbsp->lock);
+ return -EINVAL;
+ }
+
+ mcbsp->io_type = io_type;
+
+ spin_unlock(&mcbsp->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_set_io_type);
+
+int omap_mcbsp_request(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ void *reg_cache;
+ int err;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ reg_cache = kzalloc(omap_mcbsp_cache_size, GFP_KERNEL);
+ if (!reg_cache) {
+ return -ENOMEM;
+ }
+
+ spin_lock(&mcbsp->lock);
+ if (!mcbsp->free) {
+ dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+ mcbsp->id);
+ err = -EBUSY;
+ goto err_kfree;
+ }
+
+ mcbsp->free = false;
+ mcbsp->reg_cache = reg_cache;
+ spin_unlock(&mcbsp->lock);
+
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+ mcbsp->pdata->ops->request(id);
+
+ pm_runtime_get_sync(mcbsp->dev);
+
+ /* Do procedure specific to omap34xx arch, if applicable */
+ omap34xx_mcbsp_request(mcbsp);
+
+ /*
+ * Make sure that transmitter, receiver and sample-rate generator are
+ * not running before activating IRQs.
+ */
+ MCBSP_WRITE(mcbsp, SPCR1, 0);
+ MCBSP_WRITE(mcbsp, SPCR2, 0);
+
+ if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
+ /* We need to get IRQs here */
+ init_completion(&mcbsp->tx_irq_completion);
+ err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
+ 0, "McBSP", (void *)mcbsp);
+ if (err != 0) {
+ dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
+ "for McBSP%d\n", mcbsp->tx_irq,
+ mcbsp->id);
+ goto err_clk_disable;
+ }
+
+ if (mcbsp->rx_irq) {
+ init_completion(&mcbsp->rx_irq_completion);
+ err = request_irq(mcbsp->rx_irq,
+ omap_mcbsp_rx_irq_handler,
+ 0, "McBSP", (void *)mcbsp);
+ if (err != 0) {
+ dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
+ "for McBSP%d\n", mcbsp->rx_irq,
+ mcbsp->id);
+ goto err_free_irq;
+ }
+ }
+ }
+
+ return 0;
+err_free_irq:
+ free_irq(mcbsp->tx_irq, (void *)mcbsp);
+err_clk_disable:
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
+ mcbsp->pdata->ops->free(id);
+
+ /* Do procedure specific to omap34xx arch, if applicable */
+ omap34xx_mcbsp_free(mcbsp);
+
+ pm_runtime_put_sync(mcbsp->dev);
+
+ spin_lock(&mcbsp->lock);
+ mcbsp->free = true;
+ mcbsp->reg_cache = NULL;
+err_kfree:
+ spin_unlock(&mcbsp->lock);
+ kfree(reg_cache);
+
+ return err;
+}
+EXPORT_SYMBOL(omap_mcbsp_request);
+
+void omap_mcbsp_free(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ void *reg_cache;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
+ mcbsp->pdata->ops->free(id);
+
+ /* Do procedure specific to omap34xx arch, if applicable */
+ omap34xx_mcbsp_free(mcbsp);
+
+ pm_runtime_put_sync(mcbsp->dev);
+
+ if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
+ /* Free IRQs */
+ if (mcbsp->rx_irq)
+ free_irq(mcbsp->rx_irq, (void *)mcbsp);
+ free_irq(mcbsp->tx_irq, (void *)mcbsp);
+ }
+
+ reg_cache = mcbsp->reg_cache;
+
+ spin_lock(&mcbsp->lock);
+ if (mcbsp->free)
+ dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id);
+ else
+ mcbsp->free = true;
+ mcbsp->reg_cache = NULL;
+ spin_unlock(&mcbsp->lock);
+
+ if (reg_cache)
+ kfree(reg_cache);
+}
+EXPORT_SYMBOL(omap_mcbsp_free);
+
+/*
+ * Here we start the McBSP, by enabling transmitter, receiver or both.
+ * If no transmitter or receiver is active prior calling, then sample-rate
+ * generator and frame sync are started.
+ */
+void omap_mcbsp_start(unsigned int id, int tx, int rx)
+{
+ struct omap_mcbsp *mcbsp;
+ int enable_srg = 0;
+ u16 w;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (cpu_is_omap34xx())
+ omap_st_start(mcbsp);
+
+ mcbsp->rx_word_length = (MCBSP_READ_CACHE(mcbsp, RCR1) >> 5) & 0x7;
+ mcbsp->tx_word_length = (MCBSP_READ_CACHE(mcbsp, XCR1) >> 5) & 0x7;
+
+ /* Only enable SRG, if McBSP is master */
+ w = MCBSP_READ_CACHE(mcbsp, PCR0);
+ if (w & (FSXM | FSRM | CLKXM | CLKRM))
+ enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+ MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
+
+ if (enable_srg) {
+ /* Start the sample generator */
+ w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+ MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6));
+ }
+
+ /* Enable transmitter and receiver */
+ tx &= 1;
+ w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+ MCBSP_WRITE(mcbsp, SPCR2, w | tx);
+
+ rx &= 1;
+ w = MCBSP_READ_CACHE(mcbsp, SPCR1);
+ MCBSP_WRITE(mcbsp, SPCR1, w | rx);
+
+ /*
+ * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
+ * REVISIT: 100us may give enough time for two CLKSRG, however
+ * due to some unknown PM related, clock gating etc. reason it
+ * is now at 500us.
+ */
+ udelay(500);
+
+ if (enable_srg) {
+ /* Start frame sync */
+ w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+ MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
+ }
+
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ /* Release the transmitter and receiver */
+ w = MCBSP_READ_CACHE(mcbsp, XCCR);
+ w &= ~(tx ? XDISABLE : 0);
+ MCBSP_WRITE(mcbsp, XCCR, w);
+ w = MCBSP_READ_CACHE(mcbsp, RCCR);
+ w &= ~(rx ? RDISABLE : 0);
+ MCBSP_WRITE(mcbsp, RCCR, w);
+ }
+
+ /* Dump McBSP Regs */
+ omap_mcbsp_dump_reg(id);
+}
+EXPORT_SYMBOL(omap_mcbsp_start);
+
+void omap_mcbsp_stop(unsigned int id, int tx, int rx)
+{
+ struct omap_mcbsp *mcbsp;
+ int idle;
+ u16 w;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ /* Reset transmitter */
+ tx &= 1;
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ w = MCBSP_READ_CACHE(mcbsp, XCCR);
+ w |= (tx ? XDISABLE : 0);
+ MCBSP_WRITE(mcbsp, XCCR, w);
+ }
+ w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+ MCBSP_WRITE(mcbsp, SPCR2, w & ~tx);
+
+ /* Reset receiver */
+ rx &= 1;
+ if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ w = MCBSP_READ_CACHE(mcbsp, RCCR);
+ w |= (rx ? RDISABLE : 0);
+ MCBSP_WRITE(mcbsp, RCCR, w);
+ }
+ w = MCBSP_READ_CACHE(mcbsp, SPCR1);
+ MCBSP_WRITE(mcbsp, SPCR1, w & ~rx);
+
+ idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) |
+ MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1);
+
+ if (idle) {
+ /* Reset the sample rate generator */
+ w = MCBSP_READ_CACHE(mcbsp, SPCR2);
+ MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
+ }
+
+ if (cpu_is_omap34xx())
+ omap_st_stop(mcbsp);
+}
+EXPORT_SYMBOL(omap_mcbsp_stop);
+
+/* polled mcbsp i/o operations */
+int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ MCBSP_WRITE(mcbsp, DXR1, buf);
+ /* if frame sync error - clear the error */
+ if (MCBSP_READ(mcbsp, SPCR2) & XSYNC_ERR) {
+ /* clear error */
+ MCBSP_WRITE(mcbsp, SPCR2, MCBSP_READ_CACHE(mcbsp, SPCR2));
+ /* resend */
+ return -1;
+ } else {
+ /* wait for transmit confirmation */
+ int attemps = 0;
+ while (!(MCBSP_READ(mcbsp, SPCR2) & XRDY)) {
+ if (attemps++ > 1000) {
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) &
+ (~XRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) |
+ (XRST));
+ udelay(10);
+ dev_err(mcbsp->dev, "Could not write to"
+ " McBSP%d Register\n", mcbsp->id);
+ return -2;
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_pollwrite);
+
+int omap_mcbsp_pollread(unsigned int id, u16 *buf)
+{
+ struct omap_mcbsp *mcbsp;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ /* if frame sync error - clear the error */
+ if (MCBSP_READ(mcbsp, SPCR1) & RSYNC_ERR) {
+ /* clear error */
+ MCBSP_WRITE(mcbsp, SPCR1, MCBSP_READ_CACHE(mcbsp, SPCR1));
+ /* resend */
+ return -1;
+ } else {
+ /* wait for receive confirmation */
+ int attemps = 0;
+ while (!(MCBSP_READ(mcbsp, SPCR1) & RRDY)) {
+ if (attemps++ > 1000) {
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) &
+ (~RRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) |
+ (RRST));
+ udelay(10);
+ dev_err(mcbsp->dev, "Could not read from"
+ " McBSP%d Register\n", mcbsp->id);
+ return -2;
+ }
+ }
+ }
+ *buf = MCBSP_READ(mcbsp, DRR1);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_pollread);
+
+/*
+ * IRQ based word transmission.
+ */
+void omap_mcbsp_xmit_word(unsigned int id, u32 word)
+{
+ struct omap_mcbsp *mcbsp;
+ omap_mcbsp_word_length word_length;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+ word_length = mcbsp->tx_word_length;
+
+ wait_for_completion(&mcbsp->tx_irq_completion);
+
+ if (word_length > OMAP_MCBSP_WORD_16)
+ MCBSP_WRITE(mcbsp, DXR2, word >> 16);
+ MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
+}
+EXPORT_SYMBOL(omap_mcbsp_xmit_word);
+
+u32 omap_mcbsp_recv_word(unsigned int id)
+{
+ struct omap_mcbsp *mcbsp;
+ u16 word_lsb, word_msb = 0;
+ omap_mcbsp_word_length word_length;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ word_length = mcbsp->rx_word_length;
+
+ wait_for_completion(&mcbsp->rx_irq_completion);
+
+ if (word_length > OMAP_MCBSP_WORD_16)
+ word_msb = MCBSP_READ(mcbsp, DRR2);
+ word_lsb = MCBSP_READ(mcbsp, DRR1);
+
+ return (word_lsb | (word_msb << 16));
+}
+EXPORT_SYMBOL(omap_mcbsp_recv_word);
+
+int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
+{
+ struct omap_mcbsp *mcbsp;
+ omap_mcbsp_word_length tx_word_length;
+ omap_mcbsp_word_length rx_word_length;
+ u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+ tx_word_length = mcbsp->tx_word_length;
+ rx_word_length = mcbsp->rx_word_length;
+
+ if (tx_word_length != rx_word_length)
+ return -EINVAL;
+
+ /* First we wait for the transmitter to be ready */
+ spcr2 = MCBSP_READ(mcbsp, SPCR2);
+ while (!(spcr2 & XRDY)) {
+ spcr2 = MCBSP_READ(mcbsp, SPCR2);
+ if (attempts++ > 1000) {
+ /* We must reset the transmitter */
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
+ udelay(10);
+ dev_err(mcbsp->dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp->id);
+ return -EAGAIN;
+ }
+ }
+
+ /* Now we can push the data */
+ if (tx_word_length > OMAP_MCBSP_WORD_16)
+ MCBSP_WRITE(mcbsp, DXR2, word >> 16);
+ MCBSP_WRITE(mcbsp, DXR1, word & 0xffff);
+
+ /* We wait for the receiver to be ready */
+ spcr1 = MCBSP_READ(mcbsp, SPCR1);
+ while (!(spcr1 & RRDY)) {
+ spcr1 = MCBSP_READ(mcbsp, SPCR1);
+ if (attempts++ > 1000) {
+ /* We must reset the receiver */
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
+ udelay(10);
+ dev_err(mcbsp->dev, "McBSP%d receiver not "
+ "ready\n", mcbsp->id);
+ return -EAGAIN;
+ }
+ }
+
+ /* Receiver is ready, let's read the dummy data */
+ if (rx_word_length > OMAP_MCBSP_WORD_16)
+ word_msb = MCBSP_READ(mcbsp, DRR2);
+ word_lsb = MCBSP_READ(mcbsp, DRR1);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
+
+int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
+{
+ struct omap_mcbsp *mcbsp;
+ u32 clock_word = 0;
+ omap_mcbsp_word_length tx_word_length;
+ omap_mcbsp_word_length rx_word_length;
+ u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ tx_word_length = mcbsp->tx_word_length;
+ rx_word_length = mcbsp->rx_word_length;
+
+ if (tx_word_length != rx_word_length)
+ return -EINVAL;
+
+ /* First we wait for the transmitter to be ready */
+ spcr2 = MCBSP_READ(mcbsp, SPCR2);
+ while (!(spcr2 & XRDY)) {
+ spcr2 = MCBSP_READ(mcbsp, SPCR2);
+ if (attempts++ > 1000) {
+ /* We must reset the transmitter */
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) & (~XRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR2,
+ MCBSP_READ_CACHE(mcbsp, SPCR2) | XRST);
+ udelay(10);
+ dev_err(mcbsp->dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp->id);
+ return -EAGAIN;
+ }
+ }
+
+ /* We first need to enable the bus clock */
+ if (tx_word_length > OMAP_MCBSP_WORD_16)
+ MCBSP_WRITE(mcbsp, DXR2, clock_word >> 16);
+ MCBSP_WRITE(mcbsp, DXR1, clock_word & 0xffff);
+
+ /* We wait for the receiver to be ready */
+ spcr1 = MCBSP_READ(mcbsp, SPCR1);
+ while (!(spcr1 & RRDY)) {
+ spcr1 = MCBSP_READ(mcbsp, SPCR1);
+ if (attempts++ > 1000) {
+ /* We must reset the receiver */
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) & (~RRST));
+ udelay(10);
+ MCBSP_WRITE(mcbsp, SPCR1,
+ MCBSP_READ_CACHE(mcbsp, SPCR1) | RRST);
+ udelay(10);
+ dev_err(mcbsp->dev, "McBSP%d receiver not "
+ "ready\n", mcbsp->id);
+ return -EAGAIN;
+ }
+ }
+
+ /* Receiver is ready, there is something for us */
+ if (rx_word_length > OMAP_MCBSP_WORD_16)
+ word_msb = MCBSP_READ(mcbsp, DRR2);
+ word_lsb = MCBSP_READ(mcbsp, DRR1);
+
+ word[0] = (word_lsb | (word_msb << 16));
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
+
+/*
+ * Simple DMA based buffer rx/tx routines.
+ * Nothing fancy, just a single buffer tx/rx through DMA.
+ * The DMA resources are released once the transfer is done.
+ * For anything fancier, you should use your own customized DMA
+ * routines and callbacks.
+ */
+int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
+ unsigned int length)
+{
+ struct omap_mcbsp *mcbsp;
+ int dma_tx_ch;
+ int src_port = 0;
+ int dest_port = 0;
+ int sync_dev = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
+ omap_mcbsp_tx_dma_callback,
+ mcbsp,
+ &dma_tx_ch)) {
+ dev_err(mcbsp->dev, " Unable to request DMA channel for "
+ "McBSP%d TX. Trying IRQ based TX\n",
+ mcbsp->id);
+ return -EAGAIN;
+ }
+ mcbsp->dma_tx_lch = dma_tx_ch;
+
+ dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
+ dma_tx_ch);
+
+ init_completion(&mcbsp->tx_dma_completion);
+
+ if (cpu_class_is_omap1()) {
+ src_port = OMAP_DMA_PORT_TIPB;
+ dest_port = OMAP_DMA_PORT_EMIFF;
+ }
+ if (cpu_class_is_omap2())
+ sync_dev = mcbsp->dma_tx_sync;
+
+ omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
+ OMAP_DMA_DATA_TYPE_S16,
+ length >> 1, 1,
+ OMAP_DMA_SYNC_ELEMENT,
+ sync_dev, 0);
+
+ omap_set_dma_dest_params(mcbsp->dma_tx_lch,
+ src_port,
+ OMAP_DMA_AMODE_CONSTANT,
+ mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
+ 0, 0);
+
+ omap_set_dma_src_params(mcbsp->dma_tx_lch,
+ dest_port,
+ OMAP_DMA_AMODE_POST_INC,
+ buffer,
+ 0, 0);
+
+ omap_start_dma(mcbsp->dma_tx_lch);
+ wait_for_completion(&mcbsp->tx_dma_completion);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
+
+int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
+ unsigned int length)
+{
+ struct omap_mcbsp *mcbsp;
+ int dma_rx_ch;
+ int src_port = 0;
+ int dest_port = 0;
+ int sync_dev = 0;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return -ENODEV;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
+ omap_mcbsp_rx_dma_callback,
+ mcbsp,
+ &dma_rx_ch)) {
+ dev_err(mcbsp->dev, "Unable to request DMA channel for "
+ "McBSP%d RX. Trying IRQ based RX\n",
+ mcbsp->id);
+ return -EAGAIN;
+ }
+ mcbsp->dma_rx_lch = dma_rx_ch;
+
+ dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
+ dma_rx_ch);
+
+ init_completion(&mcbsp->rx_dma_completion);
+
+ if (cpu_class_is_omap1()) {
+ src_port = OMAP_DMA_PORT_TIPB;
+ dest_port = OMAP_DMA_PORT_EMIFF;
+ }
+ if (cpu_class_is_omap2())
+ sync_dev = mcbsp->dma_rx_sync;
+
+ omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
+ OMAP_DMA_DATA_TYPE_S16,
+ length >> 1, 1,
+ OMAP_DMA_SYNC_ELEMENT,
+ sync_dev, 0);
+
+ omap_set_dma_src_params(mcbsp->dma_rx_lch,
+ src_port,
+ OMAP_DMA_AMODE_CONSTANT,
+ mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
+ 0, 0);
+
+ omap_set_dma_dest_params(mcbsp->dma_rx_lch,
+ dest_port,
+ OMAP_DMA_AMODE_POST_INC,
+ buffer,
+ 0, 0);
+
+ omap_start_dma(mcbsp->dma_rx_lch);
+ wait_for_completion(&mcbsp->rx_dma_completion);
+
+ return 0;
+}
+EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
+
+/*
+ * SPI wrapper.
+ * Since SPI setup is much simpler than the generic McBSP one,
+ * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
+ * Once this is done, you can call omap_mcbsp_start().
+ */
+void omap_mcbsp_set_spi_mode(unsigned int id,
+ const struct omap_mcbsp_spi_cfg *spi_cfg)
+{
+ struct omap_mcbsp *mcbsp;
+ struct omap_mcbsp_reg_cfg mcbsp_cfg;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
+ return;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
+
+ /* SPI has only one frame */
+ mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
+ mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
+
+ /* Clock stop mode */
+ if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
+ mcbsp_cfg.spcr1 |= (1 << 12);
+ else
+ mcbsp_cfg.spcr1 |= (3 << 11);
+
+ /* Set clock parities */
+ if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+ mcbsp_cfg.pcr0 |= CLKRP;
+ else
+ mcbsp_cfg.pcr0 &= ~CLKRP;
+
+ if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
+ mcbsp_cfg.pcr0 &= ~CLKXP;
+ else
+ mcbsp_cfg.pcr0 |= CLKXP;
+
+ /* Set SCLKME to 0 and CLKSM to 1 */
+ mcbsp_cfg.pcr0 &= ~SCLKME;
+ mcbsp_cfg.srgr2 |= CLKSM;
+
+ /* Set FSXP */
+ if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
+ mcbsp_cfg.pcr0 &= ~FSXP;
+ else
+ mcbsp_cfg.pcr0 |= FSXP;
+
+ if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
+ mcbsp_cfg.pcr0 |= CLKXM;
+ mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div - 1);
+ mcbsp_cfg.pcr0 |= FSXM;
+ mcbsp_cfg.srgr2 &= ~FSGM;
+ mcbsp_cfg.xcr2 |= XDATDLY(1);
+ mcbsp_cfg.rcr2 |= RDATDLY(1);
+ } else {
+ mcbsp_cfg.pcr0 &= ~CLKXM;
+ mcbsp_cfg.srgr1 |= CLKGDV(1);
+ mcbsp_cfg.pcr0 &= ~FSXM;
+ mcbsp_cfg.xcr2 &= ~XDATDLY(3);
+ mcbsp_cfg.rcr2 &= ~RDATDLY(3);
+ }
+
+ mcbsp_cfg.xcr2 &= ~XPHASE;
+ mcbsp_cfg.rcr2 &= ~RPHASE;
+
+ omap_mcbsp_config(id, &mcbsp_cfg);
+}
+EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
+
+#ifdef CONFIG_ARCH_OMAP3
+#define max_thres(m) (mcbsp->pdata->buffer_size)
+#define valid_threshold(m, val) ((val) <= max_thres(m))
+#define THRESHOLD_PROP_BUILDER(prop) \
+static ssize_t prop##_show(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
+ \
+ return sprintf(buf, "%u\n", mcbsp->prop); \
+} \
+ \
+static ssize_t prop##_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t size) \
+{ \
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
+ unsigned long val; \
+ int status; \
+ \
+ status = strict_strtoul(buf, 0, &val); \
+ if (status) \
+ return status; \
+ \
+ if (!valid_threshold(mcbsp, val)) \
+ return -EDOM; \
+ \
+ mcbsp->prop = val; \
+ return size; \
+} \
+ \
+static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
+
+THRESHOLD_PROP_BUILDER(max_tx_thres);
+THRESHOLD_PROP_BUILDER(max_rx_thres);
+
+static const char *dma_op_modes[] = {
+ "element", "threshold", "frame",
+};
+
+static ssize_t dma_op_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+ int dma_op_mode, i = 0;
+ ssize_t len = 0;
+ const char * const *s;
+
+ dma_op_mode = mcbsp->dma_op_mode;
+
+ for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
+ if (dma_op_mode == i)
+ len += sprintf(buf + len, "[%s] ", *s);
+ else
+ len += sprintf(buf + len, "%s ", *s);
+ }
+ len += sprintf(buf + len, "\n");
+
+ return len;
+}
+
+static ssize_t dma_op_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+ const char * const *s;
+ int i = 0;
+
+ for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
+ if (sysfs_streq(buf, *s))
+ break;
+
+ if (i == ARRAY_SIZE(dma_op_modes))
+ return -EINVAL;
+
+ spin_lock_irq(&mcbsp->lock);
+ if (!mcbsp->free) {
+ size = -EBUSY;
+ goto unlock;
+ }
+ mcbsp->dma_op_mode = i;
+
+unlock:
+ spin_unlock_irq(&mcbsp->lock);
+
+ return size;
+}
+
+static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
+
+static ssize_t st_taps_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+ ssize_t status = 0;
+ int i;
+
+ spin_lock_irq(&mcbsp->lock);
+ for (i = 0; i < st_data->nr_taps; i++)
+ status += sprintf(&buf[status], (i ? ", %d" : "%d"),
+ st_data->taps[i]);
+ if (i)
+ status += sprintf(&buf[status], "\n");
+ spin_unlock_irq(&mcbsp->lock);
+
+ return status;
+}
+
+static ssize_t st_taps_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+ int val, tmp, status, i = 0;
+
+ spin_lock_irq(&mcbsp->lock);
+ memset(st_data->taps, 0, sizeof(st_data->taps));
+ st_data->nr_taps = 0;
+
+ do {
+ status = sscanf(buf, "%d%n", &val, &tmp);
+ if (status < 0 || status == 0) {
+ size = -EINVAL;
+ goto out;
+ }
+ if (val < -32768 || val > 32767) {
+ size = -EINVAL;
+ goto out;
+ }
+ st_data->taps[i++] = val;
+ buf += tmp;
+ if (*buf != ',')
+ break;
+ buf++;
+ } while (1);
+
+ st_data->nr_taps = i;
+
+out:
+ spin_unlock_irq(&mcbsp->lock);
+
+ return size;
+}
+
+static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
+
+static const struct attribute *additional_attrs[] = {
+ &dev_attr_max_tx_thres.attr,
+ &dev_attr_max_rx_thres.attr,
+ &dev_attr_dma_op_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group additional_attr_group = {
+ .attrs = (struct attribute **)additional_attrs,
+};
+
+static inline int __devinit omap_additional_add(struct device *dev)
+{
+ return sysfs_create_group(&dev->kobj, &additional_attr_group);
+}
+
+static inline void __devexit omap_additional_remove(struct device *dev)
+{
+ sysfs_remove_group(&dev->kobj, &additional_attr_group);
+}
+
+static const struct attribute *sidetone_attrs[] = {
+ &dev_attr_st_taps.attr,
+ NULL,
+};
+
+static const struct attribute_group sidetone_attr_group = {
+ .attrs = (struct attribute **)sidetone_attrs,
+};
+
+static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
+{
+ struct platform_device *pdev;
+ struct resource *res;
+ struct omap_mcbsp_st_data *st_data;
+ int err;
+
+ st_data = kzalloc(sizeof(*mcbsp->st_data), GFP_KERNEL);
+ if (!st_data) {
+ err = -ENOMEM;
+ goto err1;
+ }
+
+ pdev = container_of(mcbsp->dev, struct platform_device, dev);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
+ st_data->io_base_st = ioremap(res->start, resource_size(res));
+ if (!st_data->io_base_st) {
+ err = -ENOMEM;
+ goto err2;
+ }
+
+ err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+ if (err)
+ goto err3;
+
+ mcbsp->st_data = st_data;
+ return 0;
+
+err3:
+ iounmap(st_data->io_base_st);
+err2:
+ kfree(st_data);
+err1:
+ return err;
+
+}
+
+static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
+{
+ struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
+
+ if (st_data) {
+ sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+ iounmap(st_data->io_base_st);
+ kfree(st_data);
+ }
+}
+
+static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
+{
+ mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+ if (cpu_is_omap34xx()) {
+ /*
+ * Initially configure the maximum thresholds to a safe value.
+ * The McBSP FIFO usage with these values should not go under
+ * 16 locations.
+ * If the whole FIFO without safety buffer is used, than there
+ * is a possibility that the DMA will be not able to push the
+ * new data on time, causing channel shifts in runtime.
+ */
+ mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
+ mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
+ /*
+ * REVISIT: Set dmap_op_mode to THRESHOLD as default
+ * for mcbsp2 instances.
+ */
+ if (omap_additional_add(mcbsp->dev))
+ dev_warn(mcbsp->dev,
+ "Unable to create additional controls\n");
+
+ if (mcbsp->id == 2 || mcbsp->id == 3)
+ if (omap_st_add(mcbsp))
+ dev_warn(mcbsp->dev,
+ "Unable to create sidetone controls\n");
+
+ } else {
+ mcbsp->max_tx_thres = -EINVAL;
+ mcbsp->max_rx_thres = -EINVAL;
+ }
+}
+
+static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
+{
+ if (cpu_is_omap34xx()) {
+ omap_additional_remove(mcbsp->dev);
+
+ if (mcbsp->id == 2 || mcbsp->id == 3)
+ omap_st_remove(mcbsp);
+ }
+}
+#else
+static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
+static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
+#endif /* CONFIG_ARCH_OMAP3 */
+
+/*
+ * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
+ * 730 has only 2 McBSP, and both of them are MPU peripherals.
+ */
+static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
+{
+ struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_mcbsp *mcbsp;
+ int id = pdev->id - 1;
+ struct resource *res;
+ int ret = 0;
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "McBSP device initialized without"
+ "platform data\n");
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
+
+ if (id >= omap_mcbsp_count) {
+ dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
+ if (!mcbsp) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ spin_lock_init(&mcbsp->lock);
+ mcbsp->id = id + 1;
+ mcbsp->free = true;
+ mcbsp->dma_tx_lch = -1;
+ mcbsp->dma_rx_lch = -1;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+ if (!res) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory"
+ "resource\n", __func__, pdev->id);
+ ret = -ENOMEM;
+ goto exit;
+ }
+ }
+ mcbsp->phys_base = res->start;
+ omap_mcbsp_cache_size = resource_size(res);
+ mcbsp->io_base = ioremap(res->start, resource_size(res));
+ if (!mcbsp->io_base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
+ if (!res)
+ mcbsp->phys_dma_base = mcbsp->phys_base;
+ else
+ mcbsp->phys_dma_base = res->start;
+
+ /* Default I/O is IRQ based */
+ mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
+
+ mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx");
+ mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx");
+
+ /* From OMAP4 there will be a single irq line */
+ if (mcbsp->tx_irq == -ENXIO)
+ mcbsp->tx_irq = platform_get_irq(pdev, 0);
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+ if (!res) {
+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid rx DMA channel\n",
+ __func__, pdev->id);
+ ret = -ENODEV;
+ goto err_res;
+ }
+ mcbsp->dma_rx_sync = res->start;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+ if (!res) {
+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid tx DMA channel\n",
+ __func__, pdev->id);
+ ret = -ENODEV;
+ goto err_res;
+ }
+ mcbsp->dma_tx_sync = res->start;
+
+ mcbsp->fclk = clk_get(&pdev->dev, "fck");
+ if (IS_ERR(mcbsp->fclk)) {
+ ret = PTR_ERR(mcbsp->fclk);
+ dev_err(&pdev->dev, "unable to get fck: %d\n", ret);
+ goto err_res;
+ }
+
+ mcbsp->pdata = pdata;
+ mcbsp->dev = &pdev->dev;
+ mcbsp_ptr[id] = mcbsp;
+ mcbsp->mcbsp_config_type = pdata->mcbsp_config_type;
+ platform_set_drvdata(pdev, mcbsp);
+ pm_runtime_enable(mcbsp->dev);
+
+ /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
+ omap34xx_device_init(mcbsp);
+
+ return 0;
+
+err_res:
+ iounmap(mcbsp->io_base);
+err_ioremap:
+ kfree(mcbsp);
+exit:
+ return ret;
+}
+
+static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
+{
+ struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
+
+ platform_set_drvdata(pdev, NULL);
+ if (mcbsp) {
+
+ if (mcbsp->pdata && mcbsp->pdata->ops &&
+ mcbsp->pdata->ops->free)
+ mcbsp->pdata->ops->free(mcbsp->id);
+
+ omap34xx_device_exit(mcbsp);
+
+ clk_put(mcbsp->fclk);
+
+ iounmap(mcbsp->io_base);
+ kfree(mcbsp);
+ }
+
+ return 0;
+}
+
+static struct platform_driver omap_mcbsp_driver = {
+ .probe = omap_mcbsp_probe,
+ .remove = __devexit_p(omap_mcbsp_remove),
+ .driver = {
+ .name = "omap-mcbsp",
+ },
+};
+
+int __init omap_mcbsp_init(void)
+{
+ /* Register the McBSP driver */
+ return platform_driver_register(&omap_mcbsp_driver);
+}
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
new file mode 100644
index 00000000..0d4aa0d5
--- /dev/null
+++ b/arch/arm/plat-omap/mux.c
@@ -0,0 +1,87 @@
+/*
+ * linux/arch/arm/plat-omap/mux.c
+ *
+ * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
+ *
+ * Copyright (C) 2003 - 2008 Nokia Corporation
+ *
+ * Written by Tony Lindgren
+ *
+ * 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/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <linux/spinlock.h>
+#include <plat/mux.h>
+
+#ifdef CONFIG_OMAP_MUX
+
+static struct omap_mux_cfg *mux_cfg;
+
+int __init omap_mux_register(struct omap_mux_cfg *arch_mux_cfg)
+{
+ if (!arch_mux_cfg || !arch_mux_cfg->pins || arch_mux_cfg->size == 0
+ || !arch_mux_cfg->cfg_reg) {
+ printk(KERN_ERR "Invalid pin table\n");
+ return -EINVAL;
+ }
+
+ mux_cfg = arch_mux_cfg;
+
+ return 0;
+}
+
+/*
+ * Sets the Omap MUX and PULL_DWN registers based on the table
+ */
+int __init_or_module omap_cfg_reg(const unsigned long index)
+{
+ struct pin_config *reg;
+
+ if (!cpu_class_is_omap1()) {
+ printk(KERN_ERR "mux: Broken omap_cfg_reg(%lu) entry\n",
+ index);
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ if (mux_cfg == NULL) {
+ printk(KERN_ERR "Pin mux table not initialized\n");
+ return -ENODEV;
+ }
+
+ if (index >= mux_cfg->size) {
+ printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
+ index, mux_cfg->size);
+ dump_stack();
+ return -ENODEV;
+ }
+
+ reg = (struct pin_config *)&mux_cfg->pins[index];
+
+ if (!mux_cfg->cfg_reg)
+ return -ENODEV;
+
+ return mux_cfg->cfg_reg(reg);
+}
+EXPORT_SYMBOL(omap_cfg_reg);
+#else
+#define omap_mux_init() do {} while(0)
+#define omap_cfg_reg(x) do {} while(0)
+#endif /* CONFIG_OMAP_MUX */
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
new file mode 100644
index 00000000..ebe0c73c
--- /dev/null
+++ b/arch/arm/plat-omap/ocpi.c
@@ -0,0 +1,109 @@
+/*
+ * linux/arch/arm/plat-omap/ocpi.c
+ *
+ * Minimal OCP bus support for omap16xx
+ *
+ * Copyright (C) 2003 - 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Modified for clock framework by Paul Mundt <paul.mundt@nokia.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/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+#define OCPI_BASE 0xfffec320
+#define OCPI_FAULT (OCPI_BASE + 0x00)
+#define OCPI_CMD_FAULT (OCPI_BASE + 0x04)
+#define OCPI_SINT0 (OCPI_BASE + 0x08)
+#define OCPI_TABORT (OCPI_BASE + 0x0c)
+#define OCPI_SINT1 (OCPI_BASE + 0x10)
+#define OCPI_PROT (OCPI_BASE + 0x14)
+#define OCPI_SEC (OCPI_BASE + 0x18)
+
+/* USB OHCI OCPI access error registers */
+#define HOSTUEADDR 0xfffba0e0
+#define HOSTUESTATUS 0xfffba0e4
+
+static struct clk *ocpi_ck;
+
+/*
+ * Enables device access to OMAP buses via the OCPI bridge
+ * FIXME: Add locking
+ */
+int ocpi_enable(void)
+{
+ unsigned int val;
+
+ if (!cpu_is_omap16xx())
+ return -ENODEV;
+
+ /* Enable access for OHCI in OCPI */
+ val = omap_readl(OCPI_PROT);
+ val &= ~0xff;
+ //val &= (1 << 0); /* Allow access only to EMIFS */
+ omap_writel(val, OCPI_PROT);
+
+ val = omap_readl(OCPI_SEC);
+ val &= ~0xff;
+ omap_writel(val, OCPI_SEC);
+
+ return 0;
+}
+EXPORT_SYMBOL(ocpi_enable);
+
+static int __init omap_ocpi_init(void)
+{
+ if (!cpu_is_omap16xx())
+ return -ENODEV;
+
+ ocpi_ck = clk_get(NULL, "l3_ocpi_ck");
+ if (IS_ERR(ocpi_ck))
+ return PTR_ERR(ocpi_ck);
+
+ clk_enable(ocpi_ck);
+ ocpi_enable();
+ printk("OMAP OCPI interconnect driver loaded\n");
+
+ return 0;
+}
+
+static void __exit omap_ocpi_exit(void)
+{
+ /* REVISIT: Disable OCPI */
+
+ if (!cpu_is_omap16xx())
+ return;
+
+ clk_disable(ocpi_ck);
+ clk_put(ocpi_ck);
+}
+
+MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
+MODULE_DESCRIPTION("OMAP OCPI bus controller module");
+MODULE_LICENSE("GPL");
+module_init(omap_ocpi_init);
+module_exit(omap_ocpi_exit);
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
new file mode 100644
index 00000000..b0471bb2
--- /dev/null
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -0,0 +1,363 @@
+/*
+ * omap-pm-noop.c - OMAP power management interface - dummy version
+ *
+ * This code implements the OMAP power management interface to
+ * drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for
+ * debug/demonstration use, as it does nothing but printk() whenever a
+ * function is called (when DEBUG is defined, below)
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2009 Nokia Corporation
+ * Paul Walmsley
+ *
+ * Interface developed by (in alphabetical order):
+ * Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
+ * Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
+ */
+
+#undef DEBUG
+
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+/* Interface documentation is in mach/omap-pm.h */
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+
+static bool off_mode_enabled;
+static u32 dummy_context_loss_counter;
+
+/*
+ * Device-driver-originated constraints (via board-*.c files)
+ */
+
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+{
+ if (!dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max MPU wakeup latency constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add max MPU wakeup latency constraint: "
+ "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+ /*
+ * For current Linux, this needs to map the MPU to a
+ * powerdomain, then go through the list of current max lat
+ * constraints on the MPU and find the smallest. If
+ * the latency constraint has changed, the code should
+ * recompute the state to enter for the next powerdomain
+ * state.
+ *
+ * TI CDP code can call constraint_set here.
+ */
+
+ return 0;
+}
+
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+{
+ if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
+ agent_id != OCP_TARGET_AGENT)) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (r == 0)
+ pr_debug("OMAP PM: remove min bus tput constraint: "
+ "dev %s for agent_id %d\n", dev_name(dev), agent_id);
+ else
+ pr_debug("OMAP PM: add min bus tput constraint: "
+ "dev %s for agent_id %d: rate %ld KiB\n",
+ dev_name(dev), agent_id, r);
+
+ /*
+ * This code should model the interconnect and compute the
+ * required clock frequency, convert that to a VDD2 OPP ID, then
+ * set the VDD2 OPP appropriately.
+ *
+ * TI CDP code can call constraint_set here on the VDD2 OPP.
+ */
+
+ return 0;
+}
+
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t)
+{
+ if (!req_dev || !dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max device latency constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add max device latency constraint: "
+ "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+ /*
+ * For current Linux, this needs to map the device to a
+ * powerdomain, then go through the list of current max lat
+ * constraints on that powerdomain and find the smallest. If
+ * the latency constraint has changed, the code should
+ * recompute the state to enter for the next powerdomain
+ * state. Conceivably, this code should also determine
+ * whether to actually disable the device clocks or not,
+ * depending on how long it takes to re-enable the clocks.
+ *
+ * TI CDP code can call constraint_set here.
+ */
+
+ return 0;
+}
+
+int omap_pm_set_max_sdma_lat(struct device *dev, long t)
+{
+ if (!dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ };
+
+ if (t == -1)
+ pr_debug("OMAP PM: remove max DMA latency constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add max DMA latency constraint: "
+ "dev %s, t = %ld usec\n", dev_name(dev), t);
+
+ /*
+ * For current Linux PM QOS params, this code should scan the
+ * list of maximum CPU and DMA latencies and select the
+ * smallest, then set cpu_dma_latency pm_qos_param
+ * accordingly.
+ *
+ * For future Linux PM QOS params, with separate CPU and DMA
+ * latency params, this code should just set the dma_latency param.
+ *
+ * TI CDP code can call constraint_set here.
+ */
+
+ return 0;
+}
+
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+ if (!dev || !c || r < 0) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ }
+
+ if (r == 0)
+ pr_debug("OMAP PM: remove min clk rate constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add min clk rate constraint: "
+ "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+ /*
+ * Code in a real implementation should keep track of these
+ * constraints on the clock, and determine the highest minimum
+ * clock rate. It should iterate over each OPP and determine
+ * whether the OPP will result in a clock rate that would
+ * satisfy this constraint (and any other PM constraint in effect
+ * at that time). Once it finds the lowest-voltage OPP that
+ * meets those conditions, it should switch to it, or return
+ * an error if the code is not capable of doing so.
+ */
+
+ return 0;
+}
+
+/*
+ * DSP Bridge-specific constraints
+ */
+
+const struct omap_opp *omap_pm_dsp_get_opp_table(void)
+{
+ pr_debug("OMAP PM: DSP request for OPP table\n");
+
+ /*
+ * Return DSP frequency table here: The final item in the
+ * array should have .rate = .opp_id = 0.
+ */
+
+ return NULL;
+}
+
+void omap_pm_dsp_set_min_opp(u8 opp_id)
+{
+ if (opp_id == 0) {
+ WARN_ON(1);
+ return;
+ }
+
+ pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
+
+ /*
+ *
+ * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
+ * can just test to see which is higher, the CPU's desired OPP
+ * ID or the DSP's desired OPP ID, and use whichever is
+ * highest.
+ *
+ * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
+ * rate is keyed on MPU speed, not the OPP ID. So we need to
+ * map the OPP ID to the MPU speed for use with clk_set_rate()
+ * if it is higher than the current OPP clock rate.
+ *
+ */
+}
+
+
+u8 omap_pm_dsp_get_opp(void)
+{
+ pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
+
+ /*
+ * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
+ *
+ * CDP12.14+:
+ * Call clk_get_rate() on the OPP custom clock, map that to an
+ * OPP ID using the tables defined in board-*.c/chip-*.c files.
+ */
+
+ return 0;
+}
+
+/*
+ * CPUFreq-originated constraint
+ *
+ * In the future, this should be handled by custom OPP clocktype
+ * functions.
+ */
+
+struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
+{
+ pr_debug("OMAP PM: CPUFreq request for frequency table\n");
+
+ /*
+ * Return CPUFreq frequency table here: loop over
+ * all VDD1 clkrates, pull out the mpu_ck frequencies, build
+ * table
+ */
+
+ return NULL;
+}
+
+void omap_pm_cpu_set_freq(unsigned long f)
+{
+ if (f == 0) {
+ WARN_ON(1);
+ return;
+ }
+
+ pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
+ f);
+
+ /*
+ * For l-o dev tree, determine whether MPU freq or DSP OPP id
+ * freq is higher. Find the OPP ID corresponding to the
+ * higher frequency. Call clk_round_rate() and clk_set_rate()
+ * on the OPP custom clock.
+ *
+ * CDP should just be able to set the VDD1 OPP clock rate here.
+ */
+}
+
+unsigned long omap_pm_cpu_get_freq(void)
+{
+ pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
+
+ /*
+ * Call clk_get_rate() on the mpu_ck.
+ */
+
+ return 0;
+}
+
+/**
+ * omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been enabled.
+ */
+void omap_pm_enable_off_mode(void)
+{
+ off_mode_enabled = true;
+}
+
+/**
+ * omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
+ *
+ * Intended for use only by OMAP PM core code to notify this layer
+ * that off mode has been disabled.
+ */
+void omap_pm_disable_off_mode(void)
+{
+ off_mode_enabled = false;
+}
+
+/*
+ * Device context loss tracking
+ */
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ u32 count;
+
+ if (WARN_ON(!dev))
+ return 0;
+
+ if (dev->parent == &omap_device_parent) {
+ count = omap_device_get_context_loss_count(pdev);
+ } else {
+ WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
+ dev_name(dev));
+ if (off_mode_enabled)
+ dummy_context_loss_counter++;
+ count = dummy_context_loss_counter;
+ }
+
+ pr_debug("OMAP PM: context loss count for dev %s = %d\n",
+ dev_name(dev), count);
+
+ return count;
+}
+
+#else
+
+u32 omap_pm_get_dev_context_loss_count(struct device *dev)
+{
+ return dummy_context_loss_counter;
+}
+
+#endif
+
+/* Should be called before clk framework init */
+int __init omap_pm_if_early_init(void)
+{
+ return 0;
+}
+
+/* Must be called after clock framework is initialized */
+int __init omap_pm_if_init(void)
+{
+ return 0;
+}
+
+void omap_pm_if_exit(void)
+{
+ /* Deallocate CPUFreq frequency table here */
+}
+
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
new file mode 100644
index 00000000..49fc0df0
--- /dev/null
+++ b/arch/arm/plat-omap/omap_device.c
@@ -0,0 +1,867 @@
+/*
+ * omap_device implementation
+ *
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Paul Walmsley, Kevin Hilman
+ *
+ * Developed in collaboration with (alphabetical order): Benoit
+ * Cousson, Thara Gopinath, Tony Lindgren, Rajendra Nayak, Vikram
+ * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard
+ * Woodruff
+ *
+ * This program is free software; you can 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 code provides a consistent interface for OMAP device drivers
+ * to control power management and interconnect properties of their
+ * devices.
+ *
+ * In the medium- to long-term, this code should either be
+ * a) implemented via arch-specific pointers in platform_data
+ * or
+ * b) implemented as a proper omap_bus/omap_device in Linux, no more
+ * platform_data func pointers
+ *
+ *
+ * Guidelines for usage by driver authors:
+ *
+ * 1. These functions are intended to be used by device drivers via
+ * function pointers in struct platform_data. As an example,
+ * omap_device_enable() should be passed to the driver as
+ *
+ * struct foo_driver_platform_data {
+ * ...
+ * int (*device_enable)(struct platform_device *pdev);
+ * ...
+ * }
+ *
+ * Note that the generic "device_enable" name is used, rather than
+ * "omap_device_enable". This is so other architectures can pass in their
+ * own enable/disable functions here.
+ *
+ * This should be populated during device setup:
+ *
+ * ...
+ * pdata->device_enable = omap_device_enable;
+ * ...
+ *
+ * 2. Drivers should first check to ensure the function pointer is not null
+ * before calling it, as in:
+ *
+ * if (pdata->device_enable)
+ * pdata->device_enable(pdev);
+ *
+ * This allows other architectures that don't use similar device_enable()/
+ * device_shutdown() functions to execute normally.
+ *
+ * ...
+ *
+ * Suggested usage by device drivers:
+ *
+ * During device initialization:
+ * device_enable()
+ *
+ * During device idle:
+ * (save remaining device context if necessary)
+ * device_idle();
+ *
+ * During device resume:
+ * device_enable();
+ * (restore context if necessary)
+ *
+ * During device shutdown:
+ * device_shutdown()
+ * (device must be reinitialized at this point to use it again)
+ *
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/pm_runtime.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap_hwmod.h>
+#include <plat/clock.h>
+
+/* These parameters are passed to _omap_device_{de,}activate() */
+#define USE_WAKEUP_LAT 0
+#define IGNORE_WAKEUP_LAT 1
+
+/* Private functions */
+
+/**
+ * _omap_device_activate - increase device readiness
+ * @od: struct omap_device *
+ * @ignore_lat: increase to latency target (0) or full readiness (1)?
+ *
+ * Increase readiness of omap_device @od (thus decreasing device
+ * wakeup latency, but consuming more power). If @ignore_lat is
+ * IGNORE_WAKEUP_LAT, make the omap_device fully active. Otherwise,
+ * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
+ * latency is greater than the requested maximum wakeup latency, step
+ * backwards in the omap_device_pm_latency table to ensure the
+ * device's maximum wakeup latency is less than or equal to the
+ * requested maximum wakeup latency. Returns 0.
+ */
+static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
+{
+ struct timespec a, b, c;
+
+ pr_debug("omap_device: %s: activating\n", od->pdev.name);
+
+ while (od->pm_lat_level > 0) {
+ struct omap_device_pm_latency *odpl;
+ unsigned long long act_lat = 0;
+
+ od->pm_lat_level--;
+
+ odpl = od->pm_lats + od->pm_lat_level;
+
+ if (!ignore_lat &&
+ (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit))
+ break;
+
+ read_persistent_clock(&a);
+
+ /* XXX check return code */
+ odpl->activate_func(od);
+
+ read_persistent_clock(&b);
+
+ c = timespec_sub(b, a);
+ act_lat = timespec_to_ns(&c);
+
+ pr_debug("omap_device: %s: pm_lat %d: activate: elapsed time "
+ "%llu nsec\n", od->pdev.name, od->pm_lat_level,
+ act_lat);
+
+ if (act_lat > odpl->activate_lat) {
+ odpl->activate_lat_worst = act_lat;
+ if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
+ odpl->activate_lat = act_lat;
+ pr_warning("omap_device: %s.%d: new worst case "
+ "activate latency %d: %llu\n",
+ od->pdev.name, od->pdev.id,
+ od->pm_lat_level, act_lat);
+ } else
+ pr_warning("omap_device: %s.%d: activate "
+ "latency %d higher than exptected. "
+ "(%llu > %d)\n",
+ od->pdev.name, od->pdev.id,
+ od->pm_lat_level, act_lat,
+ odpl->activate_lat);
+ }
+
+ od->dev_wakeup_lat -= odpl->activate_lat;
+ }
+
+ return 0;
+}
+
+/**
+ * _omap_device_deactivate - decrease device readiness
+ * @od: struct omap_device *
+ * @ignore_lat: decrease to latency target (0) or full inactivity (1)?
+ *
+ * Decrease readiness of omap_device @od (thus increasing device
+ * wakeup latency, but conserving power). If @ignore_lat is
+ * IGNORE_WAKEUP_LAT, make the omap_device fully inactive. Otherwise,
+ * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup
+ * latency is less than the requested maximum wakeup latency, step
+ * forwards in the omap_device_pm_latency table to ensure the device's
+ * maximum wakeup latency is less than or equal to the requested
+ * maximum wakeup latency. Returns 0.
+ */
+static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
+{
+ struct timespec a, b, c;
+
+ pr_debug("omap_device: %s: deactivating\n", od->pdev.name);
+
+ while (od->pm_lat_level < od->pm_lats_cnt) {
+ struct omap_device_pm_latency *odpl;
+ unsigned long long deact_lat = 0;
+
+ odpl = od->pm_lats + od->pm_lat_level;
+
+ if (!ignore_lat &&
+ ((od->dev_wakeup_lat + odpl->activate_lat) >
+ od->_dev_wakeup_lat_limit))
+ break;
+
+ read_persistent_clock(&a);
+
+ /* XXX check return code */
+ odpl->deactivate_func(od);
+
+ read_persistent_clock(&b);
+
+ c = timespec_sub(b, a);
+ deact_lat = timespec_to_ns(&c);
+
+ pr_debug("omap_device: %s: pm_lat %d: deactivate: elapsed time "
+ "%llu nsec\n", od->pdev.name, od->pm_lat_level,
+ deact_lat);
+
+ if (deact_lat > odpl->deactivate_lat) {
+ odpl->deactivate_lat_worst = deact_lat;
+ if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
+ odpl->deactivate_lat = deact_lat;
+ pr_warning("omap_device: %s.%d: new worst case "
+ "deactivate latency %d: %llu\n",
+ od->pdev.name, od->pdev.id,
+ od->pm_lat_level, deact_lat);
+ } else
+ pr_warning("omap_device: %s.%d: deactivate "
+ "latency %d higher than exptected. "
+ "(%llu > %d)\n",
+ od->pdev.name, od->pdev.id,
+ od->pm_lat_level, deact_lat,
+ odpl->deactivate_lat);
+ }
+
+
+ od->dev_wakeup_lat += odpl->activate_lat;
+
+ od->pm_lat_level++;
+ }
+
+ return 0;
+}
+
+static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
+{
+ return container_of(pdev, struct omap_device, pdev);
+}
+
+/**
+ * _add_optional_clock_clkdev - Add clkdev entry for hwmod optional clocks
+ * @od: struct omap_device *od
+ *
+ * For every optional clock present per hwmod per omap_device, this function
+ * adds an entry in the clkdev table of the form <dev-id=dev_name, con-id=role>
+ * if it does not exist already.
+ *
+ * The function is called from inside omap_device_build_ss(), after
+ * omap_device_register.
+ *
+ * This allows drivers to get a pointer to its optional clocks based on its role
+ * by calling clk_get(<dev*>, <role>).
+ *
+ * No return value.
+ */
+static void _add_optional_clock_clkdev(struct omap_device *od,
+ struct omap_hwmod *oh)
+{
+ int i;
+
+ for (i = 0; i < oh->opt_clks_cnt; i++) {
+ struct omap_hwmod_opt_clk *oc;
+ struct clk *r;
+ struct clk_lookup *l;
+
+ oc = &oh->opt_clks[i];
+
+ if (!oc->_clk)
+ continue;
+
+ r = clk_get_sys(dev_name(&od->pdev.dev), oc->role);
+ if (!IS_ERR(r))
+ continue; /* clkdev entry exists */
+
+ r = omap_clk_get_by_name((char *)oc->clk);
+ if (IS_ERR(r)) {
+ pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
+ dev_name(&od->pdev.dev), oc->clk);
+ continue;
+ }
+
+ l = clkdev_alloc(r, oc->role, dev_name(&od->pdev.dev));
+ if (!l) {
+ pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
+ dev_name(&od->pdev.dev), oc->role);
+ return;
+ }
+ clkdev_add(l);
+ }
+}
+
+
+/* Public functions for use by core code */
+
+/**
+ * omap_device_get_context_loss_count - get lost context count
+ * @od: struct omap_device *
+ *
+ * Using the primary hwmod, query the context loss count for this
+ * device.
+ *
+ * Callers should consider context for this device lost any time this
+ * function returns a value different than the value the caller got
+ * the last time it called this function.
+ *
+ * If any hwmods exist for the omap_device assoiated with @pdev,
+ * return the context loss counter for that hwmod, otherwise return
+ * zero.
+ */
+u32 omap_device_get_context_loss_count(struct platform_device *pdev)
+{
+ struct omap_device *od;
+ u32 ret = 0;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->hwmods_cnt)
+ ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
+
+ return ret;
+}
+
+/**
+ * omap_device_count_resources - count number of struct resource entries needed
+ * @od: struct omap_device *
+ *
+ * Count the number of struct resource entries needed for this
+ * omap_device @od. Used by omap_device_build_ss() to determine how
+ * much memory to allocate before calling
+ * omap_device_fill_resources(). Returns the count.
+ */
+int omap_device_count_resources(struct omap_device *od)
+{
+ int c = 0;
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ c += omap_hwmod_count_resources(od->hwmods[i]);
+
+ pr_debug("omap_device: %s: counted %d total resources across %d "
+ "hwmods\n", od->pdev.name, c, od->hwmods_cnt);
+
+ return c;
+}
+
+/**
+ * omap_device_fill_resources - fill in array of struct resource
+ * @od: struct omap_device *
+ * @res: pointer to an array of struct resource to be filled in
+ *
+ * Populate one or more empty struct resource pointed to by @res with
+ * the resource data for this omap_device @od. Used by
+ * omap_device_build_ss() after calling omap_device_count_resources().
+ * Ideally this function would not be needed at all. If omap_device
+ * replaces platform_device, then we can specify our own
+ * get_resource()/ get_irq()/etc functions that use the underlying
+ * omap_hwmod information. Or if platform_device is extended to use
+ * subarchitecture-specific function pointers, the various
+ * platform_device functions can simply call omap_device internal
+ * functions to get device resources. Hacking around the existing
+ * platform_device code wastes memory. Returns 0.
+ */
+int omap_device_fill_resources(struct omap_device *od, struct resource *res)
+{
+ int c = 0;
+ int i, r;
+
+ for (i = 0; i < od->hwmods_cnt; i++) {
+ r = omap_hwmod_fill_resources(od->hwmods[i], res);
+ res += r;
+ c += r;
+ }
+
+ return 0;
+}
+
+/**
+ * omap_device_build - build and register an omap_device with one omap_hwmod
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for building and registering a single
+ * omap_device record, which in turn builds and registers a
+ * platform_device record. See omap_device_build_ss() for more
+ * information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
+ * passes along the return value of omap_device_build_ss().
+ */
+struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+ struct omap_hwmod *oh, void *pdata,
+ int pdata_len,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt, int is_early_device)
+{
+ struct omap_hwmod *ohs[] = { oh };
+
+ if (!oh)
+ return ERR_PTR(-EINVAL);
+
+ return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata,
+ pdata_len, pm_lats, pm_lats_cnt,
+ is_early_device);
+}
+
+/**
+ * omap_device_build_ss - build and register an omap_device with multiple hwmods
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Convenience function for building and registering an omap_device
+ * subsystem record. Subsystem records consist of multiple
+ * omap_hwmods. This function in turn builds and registers a
+ * platform_device record. Returns an ERR_PTR() on error, or passes
+ * along the return value of omap_device_register().
+ */
+struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+ struct omap_hwmod **ohs, int oh_cnt,
+ void *pdata, int pdata_len,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt, int is_early_device)
+{
+ int ret = -ENOMEM;
+ struct omap_device *od;
+ char *pdev_name2;
+ struct resource *res = NULL;
+ int i, res_count;
+ struct omap_hwmod **hwmods;
+
+ if (!ohs || oh_cnt == 0 || !pdev_name)
+ return ERR_PTR(-EINVAL);
+
+ if (!pdata && pdata_len > 0)
+ return ERR_PTR(-EINVAL);
+
+ pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name,
+ oh_cnt);
+
+ od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
+ if (!od)
+ return ERR_PTR(-ENOMEM);
+
+ od->hwmods_cnt = oh_cnt;
+
+ hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt,
+ GFP_KERNEL);
+ if (!hwmods)
+ goto odbs_exit1;
+
+ memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt);
+ od->hwmods = hwmods;
+
+ pdev_name2 = kzalloc(strlen(pdev_name) + 1, GFP_KERNEL);
+ if (!pdev_name2)
+ goto odbs_exit2;
+ strcpy(pdev_name2, pdev_name);
+
+ od->pdev.name = pdev_name2;
+ od->pdev.id = pdev_id;
+
+ res_count = omap_device_count_resources(od);
+ if (res_count > 0) {
+ res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+ if (!res)
+ goto odbs_exit3;
+ }
+ omap_device_fill_resources(od, res);
+
+ od->pdev.num_resources = res_count;
+ od->pdev.resource = res;
+
+ ret = platform_device_add_data(&od->pdev, pdata, pdata_len);
+ if (ret)
+ goto odbs_exit4;
+
+ od->pm_lats = pm_lats;
+ od->pm_lats_cnt = pm_lats_cnt;
+
+ if (is_early_device)
+ ret = omap_early_device_register(od);
+ else
+ ret = omap_device_register(od);
+
+ for (i = 0; i < oh_cnt; i++) {
+ hwmods[i]->od = od;
+ _add_optional_clock_clkdev(od, hwmods[i]);
+ }
+
+ if (ret)
+ goto odbs_exit4;
+
+ return od;
+
+odbs_exit4:
+ kfree(res);
+odbs_exit3:
+ kfree(pdev_name2);
+odbs_exit2:
+ kfree(hwmods);
+odbs_exit1:
+ kfree(od);
+
+ pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
+
+ return ERR_PTR(ret);
+}
+
+/**
+ * omap_early_device_register - register an omap_device as an early platform
+ * device.
+ * @od: struct omap_device * to register
+ *
+ * Register the omap_device structure. This currently just calls
+ * platform_early_add_device() on the underlying platform_device.
+ * Returns 0 by default.
+ */
+int omap_early_device_register(struct omap_device *od)
+{
+ struct platform_device *devices[1];
+
+ devices[0] = &(od->pdev);
+ early_platform_add_devices(devices, 1);
+ return 0;
+}
+
+static int _od_runtime_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int ret;
+
+ ret = pm_generic_runtime_suspend(dev);
+
+ if (!ret)
+ omap_device_idle(pdev);
+
+ return ret;
+}
+
+static int _od_runtime_idle(struct device *dev)
+{
+ return pm_generic_runtime_idle(dev);
+}
+
+static int _od_runtime_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ omap_device_enable(pdev);
+
+ return pm_generic_runtime_resume(dev);
+}
+
+static struct dev_power_domain omap_device_power_domain = {
+ .ops = {
+ .runtime_suspend = _od_runtime_suspend,
+ .runtime_idle = _od_runtime_idle,
+ .runtime_resume = _od_runtime_resume,
+ USE_PLATFORM_PM_SLEEP_OPS
+ }
+};
+
+/**
+ * omap_device_register - register an omap_device with one omap_hwmod
+ * @od: struct omap_device * to register
+ *
+ * Register the omap_device structure. This currently just calls
+ * platform_device_register() on the underlying platform_device.
+ * Returns the return value of platform_device_register().
+ */
+int omap_device_register(struct omap_device *od)
+{
+ pr_debug("omap_device: %s: registering\n", od->pdev.name);
+
+ od->pdev.dev.parent = &omap_device_parent;
+ od->pdev.dev.pwr_domain = &omap_device_power_domain;
+ return platform_device_register(&od->pdev);
+}
+
+
+/* Public functions for use by device drivers through struct platform_data */
+
+/**
+ * omap_device_enable - fully activate an omap_device
+ * @od: struct omap_device * to activate
+ *
+ * Do whatever is necessary for the hwmods underlying omap_device @od
+ * to be accessible and ready to operate. This generally involves
+ * enabling clocks, setting SYSCONFIG registers; and in the future may
+ * involve remuxing pins. Device drivers should call this function
+ * (through platform_data function pointers) where they would normally
+ * enable clocks, etc. Returns -EINVAL if called when the omap_device
+ * is already enabled, or passes along the return value of
+ * _omap_device_activate().
+ */
+int omap_device_enable(struct platform_device *pdev)
+{
+ int ret;
+ struct omap_device *od;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+ WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+ od->pdev.name, od->pdev.id, __func__, od->_state);
+ return -EINVAL;
+ }
+
+ /* Enable everything if we're enabling this device from scratch */
+ if (od->_state == OMAP_DEVICE_STATE_UNKNOWN)
+ od->pm_lat_level = od->pm_lats_cnt;
+
+ ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT);
+
+ od->dev_wakeup_lat = 0;
+ od->_dev_wakeup_lat_limit = UINT_MAX;
+ od->_state = OMAP_DEVICE_STATE_ENABLED;
+
+ return ret;
+}
+
+/**
+ * omap_device_idle - idle an omap_device
+ * @od: struct omap_device * to idle
+ *
+ * Idle omap_device @od by calling as many .deactivate_func() entries
+ * in the omap_device's pm_lats table as is possible without exceeding
+ * the device's maximum wakeup latency limit, pm_lat_limit. Device
+ * drivers should call this function (through platform_data function
+ * pointers) where they would normally disable clocks after operations
+ * complete, etc.. Returns -EINVAL if the omap_device is not
+ * currently enabled, or passes along the return value of
+ * _omap_device_deactivate().
+ */
+int omap_device_idle(struct platform_device *pdev)
+{
+ int ret;
+ struct omap_device *od;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
+ WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+ od->pdev.name, od->pdev.id, __func__, od->_state);
+ return -EINVAL;
+ }
+
+ ret = _omap_device_deactivate(od, USE_WAKEUP_LAT);
+
+ od->_state = OMAP_DEVICE_STATE_IDLE;
+
+ return ret;
+}
+
+/**
+ * omap_device_shutdown - shut down an omap_device
+ * @od: struct omap_device * to shut down
+ *
+ * Shut down omap_device @od by calling all .deactivate_func() entries
+ * in the omap_device's pm_lats table and then shutting down all of
+ * the underlying omap_hwmods. Used when a device is being "removed"
+ * or a device driver is being unloaded. Returns -EINVAL if the
+ * omap_device is not currently enabled or idle, or passes along the
+ * return value of _omap_device_deactivate().
+ */
+int omap_device_shutdown(struct platform_device *pdev)
+{
+ int ret, i;
+ struct omap_device *od;
+
+ od = _find_by_pdev(pdev);
+
+ if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
+ od->_state != OMAP_DEVICE_STATE_IDLE) {
+ WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
+ od->pdev.name, od->pdev.id, __func__, od->_state);
+ return -EINVAL;
+ }
+
+ ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT);
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_shutdown(od->hwmods[i]);
+
+ od->_state = OMAP_DEVICE_STATE_SHUTDOWN;
+
+ return ret;
+}
+
+/**
+ * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim
+ * @od: struct omap_device *
+ *
+ * When a device's maximum wakeup latency limit changes, call some of
+ * the .activate_func or .deactivate_func function pointers in the
+ * omap_device's pm_lats array to ensure that the device's maximum
+ * wakeup latency is less than or equal to the new latency limit.
+ * Intended to be called by OMAP PM code whenever a device's maximum
+ * wakeup latency limit changes (e.g., via
+ * omap_pm_set_dev_wakeup_lat()). Returns 0 if nothing needs to be
+ * done (e.g., if the omap_device is not currently idle, or if the
+ * wakeup latency is already current with the new limit) or passes
+ * along the return value of _omap_device_deactivate() or
+ * _omap_device_activate().
+ */
+int omap_device_align_pm_lat(struct platform_device *pdev,
+ u32 new_wakeup_lat_limit)
+{
+ int ret = -EINVAL;
+ struct omap_device *od;
+
+ od = _find_by_pdev(pdev);
+
+ if (new_wakeup_lat_limit == od->dev_wakeup_lat)
+ return 0;
+
+ od->_dev_wakeup_lat_limit = new_wakeup_lat_limit;
+
+ if (od->_state != OMAP_DEVICE_STATE_IDLE)
+ return 0;
+ else if (new_wakeup_lat_limit > od->dev_wakeup_lat)
+ ret = _omap_device_deactivate(od, USE_WAKEUP_LAT);
+ else if (new_wakeup_lat_limit < od->dev_wakeup_lat)
+ ret = _omap_device_activate(od, USE_WAKEUP_LAT);
+
+ return ret;
+}
+
+/**
+ * omap_device_get_pwrdm - return the powerdomain * associated with @od
+ * @od: struct omap_device *
+ *
+ * Return the powerdomain associated with the first underlying
+ * omap_hwmod for this omap_device. Intended for use by core OMAP PM
+ * code. Returns NULL on error or a struct powerdomain * upon
+ * success.
+ */
+struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
+{
+ /*
+ * XXX Assumes that all omap_hwmod powerdomains are identical.
+ * This may not necessarily be true. There should be a sanity
+ * check in here to WARN() if any difference appears.
+ */
+ if (!od->hwmods_cnt)
+ return NULL;
+
+ return omap_hwmod_get_pwrdm(od->hwmods[0]);
+}
+
+/**
+ * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
+ * @od: struct omap_device *
+ *
+ * Return the MPU's virtual address for the base of the hwmod, from
+ * the ioremap() that the hwmod code does. Only valid if there is one
+ * hwmod associated with this device. Returns NULL if there are zero
+ * or more than one hwmods associated with this omap_device;
+ * otherwise, passes along the return value from
+ * omap_hwmod_get_mpu_rt_va().
+ */
+void __iomem *omap_device_get_rt_va(struct omap_device *od)
+{
+ if (od->hwmods_cnt != 1)
+ return NULL;
+
+ return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
+}
+
+/*
+ * Public functions intended for use in omap_device_pm_latency
+ * .activate_func and .deactivate_func function pointers
+ */
+
+/**
+ * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods
+ * @od: struct omap_device *od
+ *
+ * Enable all underlying hwmods. Returns 0.
+ */
+int omap_device_enable_hwmods(struct omap_device *od)
+{
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_enable(od->hwmods[i]);
+
+ /* XXX pass along return value here? */
+ return 0;
+}
+
+/**
+ * omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods
+ * @od: struct omap_device *od
+ *
+ * Idle all underlying hwmods. Returns 0.
+ */
+int omap_device_idle_hwmods(struct omap_device *od)
+{
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_idle(od->hwmods[i]);
+
+ /* XXX pass along return value here? */
+ return 0;
+}
+
+/**
+ * omap_device_disable_clocks - disable all main and interface clocks
+ * @od: struct omap_device *od
+ *
+ * Disable the main functional clock and interface clock for all of the
+ * omap_hwmods associated with the omap_device. Returns 0.
+ */
+int omap_device_disable_clocks(struct omap_device *od)
+{
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_disable_clocks(od->hwmods[i]);
+
+ /* XXX pass along return value here? */
+ return 0;
+}
+
+/**
+ * omap_device_enable_clocks - enable all main and interface clocks
+ * @od: struct omap_device *od
+ *
+ * Enable the main functional clock and interface clock for all of the
+ * omap_hwmods associated with the omap_device. Returns 0.
+ */
+int omap_device_enable_clocks(struct omap_device *od)
+{
+ int i;
+
+ for (i = 0; i < od->hwmods_cnt; i++)
+ omap_hwmod_enable_clocks(od->hwmods[i]);
+
+ /* XXX pass along return value here? */
+ return 0;
+}
+
+struct device omap_device_parent = {
+ .init_name = "omap",
+ .parent = &platform_bus,
+};
+
+static int __init omap_device_init(void)
+{
+ return device_register(&omap_device_parent);
+}
+core_initcall(omap_device_init);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
new file mode 100644
index 00000000..6af3d0b1
--- /dev/null
+++ b/arch/arm/plat-omap/sram.c
@@ -0,0 +1,427 @@
+/*
+ * linux/arch/arm/plat-omap/sram.c
+ *
+ * OMAP SRAM detection and management
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/omapfb.h>
+
+#include <asm/tlb.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach/map.h>
+
+#include <plat/sram.h>
+#include <plat/board.h>
+#include <plat/cpu.h>
+#include <plat/vram.h>
+
+#include "sram.h"
+#include "fb.h"
+
+/* XXX These "sideways" includes are a sign that something is wrong */
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+# include "../mach-omap2/prm2xxx_3xxx.h"
+# include "../mach-omap2/sdrc.h"
+#endif
+
+#define OMAP1_SRAM_PA 0x20000000
+#define OMAP1_SRAM_VA VMALLOC_END
+#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
+#define OMAP2_SRAM_VA 0xfe400000
+#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800)
+#define OMAP3_SRAM_VA 0xfe400000
+#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
+#define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000)
+#define OMAP4_SRAM_VA 0xfe400000
+#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
+#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000)
+
+#if defined(CONFIG_ARCH_OMAP2PLUS)
+#define SRAM_BOOTLOADER_SZ 0x00
+#else
+#define SRAM_BOOTLOADER_SZ 0x80
+#endif
+
+#define OMAP24XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68005048)
+#define OMAP24XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68005050)
+#define OMAP24XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68005058)
+
+#define OMAP34XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68012848)
+#define OMAP34XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68012850)
+#define OMAP34XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68012858)
+#define OMAP34XX_VA_ADDR_MATCH2 OMAP2_L3_IO_ADDRESS(0x68012880)
+#define OMAP34XX_VA_SMS_RG_ATT0 OMAP2_L3_IO_ADDRESS(0x6C000048)
+
+#define GP_DEVICE 0x300
+
+#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
+
+static unsigned long omap_sram_start;
+static unsigned long omap_sram_base;
+static unsigned long omap_sram_size;
+static unsigned long omap_sram_ceil;
+
+/*
+ * Depending on the target RAMFS firewall setup, the public usable amount of
+ * SRAM varies. The default accessible size for all device types is 2k. A GP
+ * device allows ARM11 but not other initiators for full size. This
+ * functionality seems ok until some nice security API happens.
+ */
+static int is_sram_locked(void)
+{
+ if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
+ /* RAMFW: R/W access to all initiators for all qualifier sets */
+ if (cpu_is_omap242x()) {
+ __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
+ __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */
+ __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
+ }
+ if (cpu_is_omap34xx()) {
+ __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
+ __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */
+ __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
+ __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2);
+ __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
+ }
+ return 0;
+ } else
+ return 1; /* assume locked with no PPA or security driver */
+}
+
+/*
+ * The amount of SRAM depends on the core type.
+ * Note that we cannot try to test for SRAM here because writes
+ * to secure SRAM will hang the system. Also the SRAM is not
+ * yet mapped at this point.
+ */
+static void __init omap_detect_sram(void)
+{
+ unsigned long reserved;
+
+ if (cpu_class_is_omap2()) {
+ if (is_sram_locked()) {
+ if (cpu_is_omap34xx()) {
+ omap_sram_base = OMAP3_SRAM_PUB_VA;
+ omap_sram_start = OMAP3_SRAM_PUB_PA;
+ if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
+ (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
+ omap_sram_size = 0x7000; /* 28K */
+ } else {
+ omap_sram_size = 0x8000; /* 32K */
+ }
+ } else if (cpu_is_omap44xx()) {
+ omap_sram_base = OMAP4_SRAM_PUB_VA;
+ omap_sram_start = OMAP4_SRAM_PUB_PA;
+ omap_sram_size = 0xa000; /* 40K */
+ } else {
+ omap_sram_base = OMAP2_SRAM_PUB_VA;
+ omap_sram_start = OMAP2_SRAM_PUB_PA;
+ omap_sram_size = 0x800; /* 2K */
+ }
+ } else {
+ if (cpu_is_omap34xx()) {
+ omap_sram_base = OMAP3_SRAM_VA;
+ omap_sram_start = OMAP3_SRAM_PA;
+ omap_sram_size = 0x10000; /* 64K */
+ } else if (cpu_is_omap44xx()) {
+ omap_sram_base = OMAP4_SRAM_VA;
+ omap_sram_start = OMAP4_SRAM_PA;
+ omap_sram_size = 0xe000; /* 56K */
+ } else {
+ omap_sram_base = OMAP2_SRAM_VA;
+ omap_sram_start = OMAP2_SRAM_PA;
+ if (cpu_is_omap242x())
+ omap_sram_size = 0xa0000; /* 640K */
+ else if (cpu_is_omap243x())
+ omap_sram_size = 0x10000; /* 64K */
+ }
+ }
+ } else {
+ omap_sram_base = OMAP1_SRAM_VA;
+ omap_sram_start = OMAP1_SRAM_PA;
+
+ if (cpu_is_omap7xx())
+ omap_sram_size = 0x32000; /* 200K */
+ else if (cpu_is_omap15xx())
+ omap_sram_size = 0x30000; /* 192K */
+ else if (cpu_is_omap1610() || cpu_is_omap1621() ||
+ cpu_is_omap1710())
+ omap_sram_size = 0x4000; /* 16K */
+ else if (cpu_is_omap1611())
+ omap_sram_size = SZ_256K;
+ else {
+ pr_err("Could not detect SRAM size\n");
+ omap_sram_size = 0x4000;
+ }
+ }
+ reserved = omapfb_reserve_sram(omap_sram_start, omap_sram_base,
+ omap_sram_size,
+ omap_sram_start + SRAM_BOOTLOADER_SZ,
+ omap_sram_size - SRAM_BOOTLOADER_SZ);
+ omap_sram_size -= reserved;
+
+ reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base,
+ omap_sram_size,
+ omap_sram_start + SRAM_BOOTLOADER_SZ,
+ omap_sram_size - SRAM_BOOTLOADER_SZ);
+ omap_sram_size -= reserved;
+
+ omap_sram_ceil = omap_sram_base + omap_sram_size;
+}
+
+static struct map_desc omap_sram_io_desc[] __initdata = {
+ { /* .length gets filled in at runtime */
+ .virtual = OMAP1_SRAM_VA,
+ .pfn = __phys_to_pfn(OMAP1_SRAM_PA),
+ .type = MT_MEMORY
+ }
+};
+
+/*
+ * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
+ */
+static void __init omap_map_sram(void)
+{
+ unsigned long base;
+
+ if (omap_sram_size == 0)
+ return;
+
+ if (cpu_is_omap34xx()) {
+ /*
+ * SRAM must be marked as non-cached on OMAP3 since the
+ * CORE DPLL M2 divider change code (in SRAM) runs with the
+ * SDRAM controller disabled, and if it is marked cached,
+ * the ARM may attempt to write cache lines back to SDRAM
+ * which will cause the system to hang.
+ */
+ omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED;
+ }
+
+ omap_sram_io_desc[0].virtual = omap_sram_base;
+ base = omap_sram_start;
+ base = ROUND_DOWN(base, PAGE_SIZE);
+ omap_sram_io_desc[0].pfn = __phys_to_pfn(base);
+ omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE);
+ iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
+
+ pr_info("SRAM: Mapped pa 0x%08llx to va 0x%08lx size: 0x%lx\n",
+ (long long) __pfn_to_phys(omap_sram_io_desc[0].pfn),
+ omap_sram_io_desc[0].virtual,
+ omap_sram_io_desc[0].length);
+
+ /*
+ * Normally devicemaps_init() would flush caches and tlb after
+ * mdesc->map_io(), but since we're called from map_io(), we
+ * must do it here.
+ */
+ local_flush_tlb_all();
+ flush_cache_all();
+
+ /*
+ * Looks like we need to preserve some bootloader code at the
+ * beginning of SRAM for jumping to flash for reboot to work...
+ */
+ memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0,
+ omap_sram_size - SRAM_BOOTLOADER_SZ);
+}
+
+/*
+ * Memory allocator for SRAM: calculates the new ceiling address
+ * for pushing a function using the fncpy API.
+ *
+ * Note that fncpy requires the returned address to be aligned
+ * to an 8-byte boundary.
+ */
+void *omap_sram_push_address(unsigned long size)
+{
+ if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
+ pr_err("Not enough space in SRAM\n");
+ return NULL;
+ }
+
+ omap_sram_ceil -= size;
+ omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
+
+ return (void *)omap_sram_ceil;
+}
+
+#ifdef CONFIG_ARCH_OMAP1
+
+static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
+
+void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
+{
+ BUG_ON(!_omap_sram_reprogram_clock);
+ _omap_sram_reprogram_clock(dpllctl, ckctl);
+}
+
+static int __init omap1_sram_init(void)
+{
+ _omap_sram_reprogram_clock =
+ omap_sram_push(omap1_sram_reprogram_clock,
+ omap1_sram_reprogram_clock_sz);
+
+ return 0;
+}
+
+#else
+#define omap1_sram_init() do {} while (0)
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2)
+
+static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock);
+
+void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock)
+{
+ BUG_ON(!_omap2_sram_ddr_init);
+ _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
+ base_cs, force_unlock);
+}
+
+static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
+ u32 mem_type);
+
+void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
+{
+ BUG_ON(!_omap2_sram_reprogram_sdrc);
+ _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
+}
+
+static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+
+u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
+{
+ BUG_ON(!_omap2_set_prcm);
+ return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2420
+static int __init omap242x_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
+ omap242x_sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc,
+ omap242x_sram_reprogram_sdrc_sz);
+
+ _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm,
+ omap242x_sram_set_prcm_sz);
+
+ return 0;
+}
+#else
+static inline int omap242x_sram_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_SOC_OMAP2430
+static int __init omap243x_sram_init(void)
+{
+ _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
+ omap243x_sram_ddr_init_sz);
+
+ _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc,
+ omap243x_sram_reprogram_sdrc_sz);
+
+ _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm,
+ omap243x_sram_set_prcm_sz);
+
+ return 0;
+}
+#else
+static inline int omap243x_sram_init(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+
+static u32 (*_omap3_sram_configure_core_dpll)(
+ u32 m2, u32 unlock_dll, u32 f, u32 inc,
+ u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+ u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+ u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+ u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+
+u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
+ u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+ u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+ u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+ u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1)
+{
+ BUG_ON(!_omap3_sram_configure_core_dpll);
+ return _omap3_sram_configure_core_dpll(
+ m2, unlock_dll, f, inc,
+ sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0,
+ sdrc_actim_ctrl_b_0, sdrc_mr_0,
+ sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1,
+ sdrc_actim_ctrl_b_1, sdrc_mr_1);
+}
+
+#ifdef CONFIG_PM
+void omap3_sram_restore_context(void)
+{
+ omap_sram_ceil = omap_sram_base + omap_sram_size;
+
+ _omap3_sram_configure_core_dpll =
+ omap_sram_push(omap3_sram_configure_core_dpll,
+ omap3_sram_configure_core_dpll_sz);
+ omap_push_sram_idle();
+}
+#endif /* CONFIG_PM */
+
+static int __init omap34xx_sram_init(void)
+{
+ _omap3_sram_configure_core_dpll =
+ omap_sram_push(omap3_sram_configure_core_dpll,
+ omap3_sram_configure_core_dpll_sz);
+ omap_push_sram_idle();
+ return 0;
+}
+#else
+static inline int omap34xx_sram_init(void)
+{
+ return 0;
+}
+#endif
+
+int __init omap_sram_init(void)
+{
+ omap_detect_sram();
+ omap_map_sram();
+
+ if (!(cpu_class_is_omap2()))
+ omap1_sram_init();
+ else if (cpu_is_omap242x())
+ omap242x_sram_init();
+ else if (cpu_is_omap2430())
+ omap243x_sram_init();
+ else if (cpu_is_omap34xx())
+ omap34xx_sram_init();
+
+ return 0;
+}
diff --git a/arch/arm/plat-omap/sram.h b/arch/arm/plat-omap/sram.h
new file mode 100644
index 00000000..29b43ef9
--- /dev/null
+++ b/arch/arm/plat-omap/sram.h
@@ -0,0 +1,6 @@
+#ifndef __PLAT_OMAP_SRAM_H__
+#define __PLAT_OMAP_SRAM_H__
+
+extern int __init omap_sram_init(void);
+
+#endif /* __PLAT_OMAP_SRAM_H__ */
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
new file mode 100644
index 00000000..f3570884
--- /dev/null
+++ b/arch/arm/plat-omap/usb.c
@@ -0,0 +1,143 @@
+ /*
+ * arch/arm/plat-omap/usb.c -- platform level USB initialization
+ *
+ * Copyright (C) 2004 Texas Instruments, 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
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <plat/usb.h>
+#include <plat/board.h>
+
+#ifdef CONFIG_ARCH_OMAP_OTG
+
+void __init
+omap_otg_init(struct omap_usb_config *config)
+{
+ u32 syscon;
+ int status;
+ int alt_pingroup = 0;
+
+ /* NOTE: no bus or clock setup (yet?) */
+
+ syscon = omap_readl(OTG_SYSCON_1) & 0xffff;
+ if (!(syscon & OTG_RESET_DONE))
+ pr_debug("USB resets not complete?\n");
+
+ //omap_writew(0, OTG_IRQ_EN);
+
+ /* pin muxing and transceiver pinouts */
+ if (config->pins[0] > 2) /* alt pingroup 2 */
+ alt_pingroup = 1;
+ syscon |= config->usb0_init(config->pins[0], is_usb0_device(config));
+ syscon |= config->usb1_init(config->pins[1]);
+ syscon |= config->usb2_init(config->pins[2], alt_pingroup);
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
+ omap_writel(syscon, OTG_SYSCON_1);
+
+ syscon = config->hmc_mode;
+ syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
+#ifdef CONFIG_USB_OTG
+ if (config->otg)
+ syscon |= OTG_EN;
+#endif
+ if (cpu_class_is_omap1())
+ pr_debug("USB_TRANSCEIVER_CTRL = %03x\n",
+ omap_readl(USB_TRANSCEIVER_CTRL));
+ pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2));
+ omap_writel(syscon, OTG_SYSCON_2);
+
+ printk("USB: hmc %d", config->hmc_mode);
+ if (!alt_pingroup)
+ printk(", usb2 alt %d wires", config->pins[2]);
+ else if (config->pins[0])
+ printk(", usb0 %d wires%s", config->pins[0],
+ is_usb0_device(config) ? " (dev)" : "");
+ if (config->pins[1])
+ printk(", usb1 %d wires", config->pins[1]);
+ if (!alt_pingroup && config->pins[2])
+ printk(", usb2 %d wires", config->pins[2]);
+ if (config->otg)
+ printk(", Mini-AB on usb%d", config->otg - 1);
+ printk("\n");
+
+ if (cpu_class_is_omap1()) {
+ u16 w;
+
+ /* leave USB clocks/controllers off until needed */
+ w = omap_readw(ULPD_SOFT_REQ);
+ w &= ~SOFT_USB_CLK_REQ;
+ omap_writew(w, ULPD_SOFT_REQ);
+
+ w = omap_readw(ULPD_CLOCK_CTRL);
+ w &= ~USB_MCLK_EN;
+ w |= DIS_USB_PVCI_CLK;
+ omap_writew(w, ULPD_CLOCK_CTRL);
+ }
+ syscon = omap_readl(OTG_SYSCON_1);
+ syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ if (config->otg || config->register_dev) {
+ struct platform_device *udc_device = config->udc_device;
+
+ syscon &= ~DEV_IDLE_EN;
+ udc_device->dev.platform_data = config;
+ status = platform_device_register(udc_device);
+ if (status)
+ pr_debug("can't register UDC device, %d\n", status);
+ }
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ if (config->otg || config->register_host) {
+ struct platform_device *ohci_device = config->ohci_device;
+
+ syscon &= ~HST_IDLE_EN;
+ ohci_device->dev.platform_data = config;
+ status = platform_device_register(ohci_device);
+ if (status)
+ pr_debug("can't register OHCI device, %d\n", status);
+ }
+#endif
+
+#ifdef CONFIG_USB_OTG
+ if (config->otg) {
+ struct platform_device *otg_device = config->otg_device;
+
+ syscon &= ~OTG_IDLE_EN;
+ otg_device->dev.platform_data = config;
+ status = platform_device_register(otg_device);
+ if (status)
+ pr_debug("can't register OTG device, %d\n", status);
+ }
+#endif
+ pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
+ omap_writel(syscon, OTG_SYSCON_1);
+
+ status = 0;
+}
+
+#else
+void omap_otg_init(struct omap_usb_config *config) {}
+#endif
diff --git a/arch/arm/plat-orion/Makefile b/arch/arm/plat-orion/Makefile
new file mode 100644
index 00000000..95a5fc53
--- /dev/null
+++ b/arch/arm/plat-orion/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux kernel.
+#
+
+obj-y := irq.o pcie.o time.o common.o mpp.o
+obj-m :=
+obj-n :=
+obj- :=
+
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c
new file mode 100644
index 00000000..11dce87c
--- /dev/null
+++ b/arch/arm/plat-orion/common.c
@@ -0,0 +1,956 @@
+/*
+ * arch/arm/plat-orion/common.c
+ *
+ * Marvell Orion SoC common setup code used by multiple mach-/common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <net/dsa.h>
+#include <linux/spi/orion_spi.h>
+#include <plat/orion_wdt.h>
+#include <plat/mv_xor.h>
+#include <plat/ehci-orion.h>
+
+/* Fill in the resources structure and link it into the platform
+ device structure. There is always a memory region, and nearly
+ always an interrupt.*/
+static void fill_resources(struct platform_device *device,
+ struct resource *resources,
+ resource_size_t mapbase,
+ resource_size_t size,
+ unsigned int irq)
+{
+ device->resource = resources;
+ device->num_resources = 1;
+ resources[0].flags = IORESOURCE_MEM;
+ resources[0].start = mapbase;
+ resources[0].end = mapbase + size;
+
+ if (irq != NO_IRQ) {
+ device->num_resources++;
+ resources[1].flags = IORESOURCE_IRQ;
+ resources[1].start = irq;
+ resources[1].end = irq;
+ }
+}
+
+/*****************************************************************************
+ * UART
+ ****************************************************************************/
+static void __init uart_complete(
+ struct platform_device *orion_uart,
+ struct plat_serial8250_port *data,
+ struct resource *resources,
+ unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk)
+{
+ data->mapbase = mapbase;
+ data->membase = (void __iomem *)membase;
+ data->irq = irq;
+ data->uartclk = uartclk;
+ orion_uart->dev.platform_data = data;
+
+ fill_resources(orion_uart, resources, mapbase, 0xff, irq);
+ platform_device_register(orion_uart);
+}
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart0_data[] = {
+ {
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ }, {
+ },
+};
+
+static struct resource orion_uart0_resources[2];
+
+static struct platform_device orion_uart0 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+};
+
+void __init orion_uart0_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk)
+{
+ uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
+ membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart1_data[] = {
+ {
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ }, {
+ },
+};
+
+static struct resource orion_uart1_resources[2];
+
+static struct platform_device orion_uart1 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+};
+
+void __init orion_uart1_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk)
+{
+ uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
+ membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart2_data[] = {
+ {
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ }, {
+ },
+};
+
+static struct resource orion_uart2_resources[2];
+
+static struct platform_device orion_uart2 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+};
+
+void __init orion_uart2_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk)
+{
+ uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources,
+ membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart3_data[] = {
+ {
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ }, {
+ },
+};
+
+static struct resource orion_uart3_resources[2];
+
+static struct platform_device orion_uart3 = {
+ .name = "serial8250",
+ .id = 3,
+};
+
+void __init orion_uart3_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk)
+{
+ uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources,
+ membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static struct resource orion_rtc_resource[2];
+
+void __init orion_rtc_init(unsigned long mapbase,
+ unsigned long irq)
+{
+ orion_rtc_resource[0].start = mapbase;
+ orion_rtc_resource[0].end = mapbase + SZ_32 - 1;
+ orion_rtc_resource[0].flags = IORESOURCE_MEM;
+ orion_rtc_resource[1].start = irq;
+ orion_rtc_resource[1].end = irq;
+ orion_rtc_resource[1].flags = IORESOURCE_IRQ;
+
+ platform_device_register_simple("rtc-mv", -1, orion_rtc_resource, 2);
+}
+
+/*****************************************************************************
+ * GE
+ ****************************************************************************/
+static __init void ge_complete(
+ struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
+ struct mbus_dram_target_info *mbus_dram_info, int tclk,
+ struct resource *orion_ge_resource, unsigned long irq,
+ struct platform_device *orion_ge_shared,
+ struct mv643xx_eth_platform_data *eth_data,
+ struct platform_device *orion_ge)
+{
+ orion_ge_shared_data->dram = mbus_dram_info;
+ orion_ge_shared_data->t_clk = tclk;
+ orion_ge_resource->start = irq;
+ orion_ge_resource->end = irq;
+ eth_data->shared = orion_ge_shared;
+ orion_ge->dev.platform_data = eth_data;
+
+ platform_device_register(orion_ge_shared);
+ platform_device_register(orion_ge);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
+
+static struct resource orion_ge00_shared_resources[] = {
+ {
+ .name = "ge00 base",
+ }, {
+ .name = "ge00 err irq",
+ },
+};
+
+static struct platform_device orion_ge00_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &orion_ge00_shared_data,
+ },
+};
+
+static struct resource orion_ge00_resources[] = {
+ {
+ .name = "ge00 irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion_ge00 = {
+ .name = MV643XX_ETH_NAME,
+ .id = 0,
+ .num_resources = 1,
+ .resource = orion_ge00_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk)
+{
+ fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, irq_err);
+ ge_complete(&orion_ge00_shared_data, mbus_dram_info, tclk,
+ orion_ge00_resources, irq, &orion_ge00_shared,
+ eth_data, &orion_ge00);
+}
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = {
+ .shared_smi = &orion_ge00_shared,
+};
+
+static struct resource orion_ge01_shared_resources[] = {
+ {
+ .name = "ge01 base",
+ }, {
+ .name = "ge01 err irq",
+ },
+};
+
+static struct platform_device orion_ge01_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_ge01_shared_data,
+ },
+};
+
+static struct resource orion_ge01_resources[] = {
+ {
+ .name = "ge01 irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion_ge01 = {
+ .name = MV643XX_ETH_NAME,
+ .id = 1,
+ .num_resources = 1,
+ .resource = orion_ge01_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk)
+{
+ fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, irq_err);
+ ge_complete(&orion_ge01_shared_data, mbus_dram_info, tclk,
+ orion_ge01_resources, irq, &orion_ge01_shared,
+ eth_data, &orion_ge01);
+}
+
+/*****************************************************************************
+ * GE10
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = {
+ .shared_smi = &orion_ge00_shared,
+};
+
+static struct resource orion_ge10_shared_resources[] = {
+ {
+ .name = "ge10 base",
+ }, {
+ .name = "ge10 err irq",
+ },
+};
+
+static struct platform_device orion_ge10_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_ge10_shared_data,
+ },
+};
+
+static struct resource orion_ge10_resources[] = {
+ {
+ .name = "ge10 irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion_ge10 = {
+ .name = MV643XX_ETH_NAME,
+ .id = 1,
+ .num_resources = 2,
+ .resource = orion_ge10_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk)
+{
+ fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, irq_err);
+ ge_complete(&orion_ge10_shared_data, mbus_dram_info, tclk,
+ orion_ge10_resources, irq, &orion_ge10_shared,
+ eth_data, &orion_ge10);
+}
+
+/*****************************************************************************
+ * GE11
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = {
+ .shared_smi = &orion_ge00_shared,
+};
+
+static struct resource orion_ge11_shared_resources[] = {
+ {
+ .name = "ge11 base",
+ }, {
+ .name = "ge11 err irq",
+ },
+};
+
+static struct platform_device orion_ge11_shared = {
+ .name = MV643XX_ETH_SHARED_NAME,
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_ge11_shared_data,
+ },
+};
+
+static struct resource orion_ge11_resources[] = {
+ {
+ .name = "ge11 irq",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion_ge11 = {
+ .name = MV643XX_ETH_NAME,
+ .id = 1,
+ .num_resources = 2,
+ .resource = orion_ge11_resources,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk)
+{
+ fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
+ mapbase + 0x2000, SZ_16K - 1, irq_err);
+ ge_complete(&orion_ge11_shared_data, mbus_dram_info, tclk,
+ orion_ge11_resources, irq, &orion_ge11_shared,
+ eth_data, &orion_ge11);
+}
+
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+static struct resource orion_switch_resources[] = {
+ {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion_switch_device = {
+ .name = "dsa",
+ .id = 0,
+ .num_resources = 0,
+ .resource = orion_switch_resources,
+};
+
+void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
+{
+ int i;
+
+ if (irq != NO_IRQ) {
+ orion_switch_resources[0].start = irq;
+ orion_switch_resources[0].end = irq;
+ orion_switch_device.num_resources = 1;
+ }
+
+ d->netdev = &orion_ge00.dev;
+ for (i = 0; i < d->nr_chips; i++)
+ d->chip[i].mii_bus = &orion_ge00_shared.dev;
+ orion_switch_device.dev.platform_data = d;
+
+ platform_device_register(&orion_switch_device);
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
+ .freq_n = 3,
+ .timeout = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_resources[2];
+
+static struct platform_device orion_i2c = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &orion_i2c_pdata,
+ },
+};
+
+static struct mv64xxx_i2c_pdata orion_i2c_1_pdata = {
+ .freq_n = 3,
+ .timeout = 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_1_resources[2];
+
+static struct platform_device orion_i2c_1 = {
+ .name = MV64XXX_I2C_CTLR_NAME,
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_i2c_1_pdata,
+ },
+};
+
+void __init orion_i2c_init(unsigned long mapbase,
+ unsigned long irq,
+ unsigned long freq_m)
+{
+ orion_i2c_pdata.freq_m = freq_m;
+ fill_resources(&orion_i2c, orion_i2c_resources, mapbase,
+ SZ_32 - 1, irq);
+ platform_device_register(&orion_i2c);
+}
+
+void __init orion_i2c_1_init(unsigned long mapbase,
+ unsigned long irq,
+ unsigned long freq_m)
+{
+ orion_i2c_1_pdata.freq_m = freq_m;
+ fill_resources(&orion_i2c_1, orion_i2c_1_resources, mapbase,
+ SZ_32 - 1, irq);
+ platform_device_register(&orion_i2c_1);
+}
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+static struct orion_spi_info orion_spi_plat_data;
+static struct resource orion_spi_resources;
+
+static struct platform_device orion_spi = {
+ .name = "orion_spi",
+ .id = 0,
+ .dev = {
+ .platform_data = &orion_spi_plat_data,
+ },
+};
+
+static struct orion_spi_info orion_spi_1_plat_data;
+static struct resource orion_spi_1_resources;
+
+static struct platform_device orion_spi_1 = {
+ .name = "orion_spi",
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_spi_1_plat_data,
+ },
+};
+
+/* Note: The SPI silicon core does have interrupts. However the
+ * current Linux software driver does not use interrupts. */
+
+void __init orion_spi_init(unsigned long mapbase,
+ unsigned long tclk)
+{
+ orion_spi_plat_data.tclk = tclk;
+ fill_resources(&orion_spi, &orion_spi_resources,
+ mapbase, SZ_512 - 1, NO_IRQ);
+ platform_device_register(&orion_spi);
+}
+
+void __init orion_spi_1_init(unsigned long mapbase,
+ unsigned long tclk)
+{
+ orion_spi_1_plat_data.tclk = tclk;
+ fill_resources(&orion_spi_1, &orion_spi_1_resources,
+ mapbase, SZ_512 - 1, NO_IRQ);
+ platform_device_register(&orion_spi_1);
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct orion_wdt_platform_data orion_wdt_data;
+
+static struct platform_device orion_wdt_device = {
+ .name = "orion_wdt",
+ .id = -1,
+ .dev = {
+ .platform_data = &orion_wdt_data,
+ },
+ .num_resources = 0,
+};
+
+void __init orion_wdt_init(unsigned long tclk)
+{
+ orion_wdt_data.tclk = tclk;
+ platform_device_register(&orion_wdt_device);
+}
+
+/*****************************************************************************
+ * XOR
+ ****************************************************************************/
+static struct mv_xor_platform_shared_data orion_xor_shared_data;
+
+static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
+
+void __init orion_xor_init_channels(
+ struct mv_xor_platform_data *orion_xor0_data,
+ struct platform_device *orion_xor0_channel,
+ struct mv_xor_platform_data *orion_xor1_data,
+ struct platform_device *orion_xor1_channel)
+{
+ /*
+ * two engines can't do memset simultaneously, this limitation
+ * satisfied by removing memset support from one of the engines.
+ */
+ dma_cap_set(DMA_MEMCPY, orion_xor0_data->cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor0_data->cap_mask);
+ platform_device_register(orion_xor0_channel);
+
+ dma_cap_set(DMA_MEMCPY, orion_xor1_data->cap_mask);
+ dma_cap_set(DMA_MEMSET, orion_xor1_data->cap_mask);
+ dma_cap_set(DMA_XOR, orion_xor1_data->cap_mask);
+ platform_device_register(orion_xor1_channel);
+}
+
+/*****************************************************************************
+ * XOR0
+ ****************************************************************************/
+static struct resource orion_xor0_shared_resources[] = {
+ {
+ .name = "xor 0 low",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "xor 0 high",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device orion_xor0_shared = {
+ .name = MV_XOR_SHARED_NAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &orion_xor_shared_data,
+ },
+ .num_resources = ARRAY_SIZE(orion_xor0_shared_resources),
+ .resource = orion_xor0_shared_resources,
+};
+
+static struct resource orion_xor00_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion_xor00_data = {
+ .shared = &orion_xor0_shared,
+ .hw_id = 0,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion_xor00_channel = {
+ .name = MV_XOR_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(orion_xor00_resources),
+ .resource = orion_xor00_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor00_data,
+ },
+};
+
+static struct resource orion_xor01_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion_xor01_data = {
+ .shared = &orion_xor0_shared,
+ .hw_id = 1,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion_xor01_channel = {
+ .name = MV_XOR_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(orion_xor01_resources),
+ .resource = orion_xor01_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor01_data,
+ },
+};
+
+void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase_low,
+ unsigned long mapbase_high,
+ unsigned long irq_0,
+ unsigned long irq_1)
+{
+ orion_xor_shared_data.dram = mbus_dram_info;
+
+ orion_xor0_shared_resources[0].start = mapbase_low;
+ orion_xor0_shared_resources[0].end = mapbase_low + 0xff;
+ orion_xor0_shared_resources[1].start = mapbase_high;
+ orion_xor0_shared_resources[1].end = mapbase_high + 0xff;
+
+ orion_xor00_resources[0].start = irq_0;
+ orion_xor00_resources[0].end = irq_0;
+ orion_xor01_resources[0].start = irq_1;
+ orion_xor01_resources[0].end = irq_1;
+
+ platform_device_register(&orion_xor0_shared);
+
+ orion_xor_init_channels(&orion_xor00_data, &orion_xor00_channel,
+ &orion_xor01_data, &orion_xor01_channel);
+}
+
+/*****************************************************************************
+ * XOR1
+ ****************************************************************************/
+static struct resource orion_xor1_shared_resources[] = {
+ {
+ .name = "xor 1 low",
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "xor 1 high",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device orion_xor1_shared = {
+ .name = MV_XOR_SHARED_NAME,
+ .id = 1,
+ .dev = {
+ .platform_data = &orion_xor_shared_data,
+ },
+ .num_resources = ARRAY_SIZE(orion_xor1_shared_resources),
+ .resource = orion_xor1_shared_resources,
+};
+
+static struct resource orion_xor10_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion_xor10_data = {
+ .shared = &orion_xor1_shared,
+ .hw_id = 0,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion_xor10_channel = {
+ .name = MV_XOR_NAME,
+ .id = 2,
+ .num_resources = ARRAY_SIZE(orion_xor10_resources),
+ .resource = orion_xor10_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor10_data,
+ },
+};
+
+static struct resource orion_xor11_resources[] = {
+ [0] = {
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion_xor11_data = {
+ .shared = &orion_xor1_shared,
+ .hw_id = 1,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion_xor11_channel = {
+ .name = MV_XOR_NAME,
+ .id = 3,
+ .num_resources = ARRAY_SIZE(orion_xor11_resources),
+ .resource = orion_xor11_resources,
+ .dev = {
+ .dma_mask = &orion_xor_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(64),
+ .platform_data = &orion_xor11_data,
+ },
+};
+
+void __init orion_xor1_init(unsigned long mapbase_low,
+ unsigned long mapbase_high,
+ unsigned long irq_0,
+ unsigned long irq_1)
+{
+ orion_xor1_shared_resources[0].start = mapbase_low;
+ orion_xor1_shared_resources[0].end = mapbase_low + 0xff;
+ orion_xor1_shared_resources[1].start = mapbase_high;
+ orion_xor1_shared_resources[1].end = mapbase_high + 0xff;
+
+ orion_xor10_resources[0].start = irq_0;
+ orion_xor10_resources[0].end = irq_0;
+ orion_xor11_resources[0].start = irq_1;
+ orion_xor11_resources[0].end = irq_1;
+
+ platform_device_register(&orion_xor1_shared);
+
+ orion_xor_init_channels(&orion_xor10_data, &orion_xor10_channel,
+ &orion_xor11_data, &orion_xor11_channel);
+}
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+static struct orion_ehci_data orion_ehci_data;
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+static struct resource orion_ehci_resources[2];
+
+static struct platform_device orion_ehci = {
+ .name = "orion-ehci",
+ .id = 0,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &orion_ehci_data,
+ },
+};
+
+void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ enum orion_ehci_phy_ver phy_version)
+{
+ orion_ehci_data.dram = mbus_dram_info;
+ orion_ehci_data.phy_version = phy_version;
+ fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1,
+ irq);
+
+ platform_device_register(&orion_ehci);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource orion_ehci_1_resources[2];
+
+static struct platform_device orion_ehci_1 = {
+ .name = "orion-ehci",
+ .id = 1,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &orion_ehci_data,
+ },
+};
+
+void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq)
+{
+ orion_ehci_data.dram = mbus_dram_info;
+ fill_resources(&orion_ehci_1, orion_ehci_1_resources,
+ mapbase, SZ_4K - 1, irq);
+
+ platform_device_register(&orion_ehci_1);
+}
+
+/*****************************************************************************
+ * EHCI2
+ ****************************************************************************/
+static struct resource orion_ehci_2_resources[2];
+
+static struct platform_device orion_ehci_2 = {
+ .name = "orion-ehci",
+ .id = 2,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &orion_ehci_data,
+ },
+};
+
+void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq)
+{
+ orion_ehci_data.dram = mbus_dram_info;
+ fill_resources(&orion_ehci_2, orion_ehci_2_resources,
+ mapbase, SZ_4K - 1, irq);
+
+ platform_device_register(&orion_ehci_2);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct resource orion_sata_resources[2] = {
+ {
+ .name = "sata base",
+ }, {
+ .name = "sata irq",
+ },
+};
+
+static struct platform_device orion_sata = {
+ .name = "sata_mv",
+ .id = 0,
+ .dev = {
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq)
+{
+ sata_data->dram = mbus_dram_info;
+ orion_sata.dev.platform_data = sata_data;
+ fill_resources(&orion_sata, orion_sata_resources,
+ mapbase, 0x5000 - 1, irq);
+
+ platform_device_register(&orion_sata);
+}
+
+/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+static struct resource orion_crypto_resources[] = {
+ {
+ .name = "regs",
+ }, {
+ .name = "crypto interrupt",
+ }, {
+ .name = "sram",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device orion_crypto = {
+ .name = "mv_crypto",
+ .id = -1,
+};
+
+void __init orion_crypto_init(unsigned long mapbase,
+ unsigned long srambase,
+ unsigned long sram_size,
+ unsigned long irq)
+{
+ fill_resources(&orion_crypto, orion_crypto_resources,
+ mapbase, 0xffff, irq);
+ orion_crypto.num_resources = 3;
+ orion_crypto_resources[2].start = srambase;
+ orion_crypto_resources[2].end = srambase + sram_size - 1;
+
+ platform_device_register(&orion_crypto);
+}
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
new file mode 100644
index 00000000..41ab97eb
--- /dev/null
+++ b/arch/arm/plat-orion/gpio.c
@@ -0,0 +1,477 @@
+/*
+ * arch/arm/plat-orion/gpio.c
+ *
+ * Marvell Orion SoC GPIO handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+/*
+ * GPIO unit register offsets.
+ */
+#define GPIO_OUT_OFF 0x0000
+#define GPIO_IO_CONF_OFF 0x0004
+#define GPIO_BLINK_EN_OFF 0x0008
+#define GPIO_IN_POL_OFF 0x000c
+#define GPIO_DATA_IN_OFF 0x0010
+#define GPIO_EDGE_CAUSE_OFF 0x0014
+#define GPIO_EDGE_MASK_OFF 0x0018
+#define GPIO_LEVEL_MASK_OFF 0x001c
+
+struct orion_gpio_chip {
+ struct gpio_chip chip;
+ spinlock_t lock;
+ void __iomem *base;
+ unsigned long valid_input;
+ unsigned long valid_output;
+ int mask_offset;
+ int secondary_irq_base;
+};
+
+static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_OUT_OFF;
+}
+
+static void __iomem *GPIO_IO_CONF(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_IO_CONF_OFF;
+}
+
+static void __iomem *GPIO_BLINK_EN(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_BLINK_EN_OFF;
+}
+
+static void __iomem *GPIO_IN_POL(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_IN_POL_OFF;
+}
+
+static void __iomem *GPIO_DATA_IN(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_DATA_IN_OFF;
+}
+
+static void __iomem *GPIO_EDGE_CAUSE(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + GPIO_EDGE_CAUSE_OFF;
+}
+
+static void __iomem *GPIO_EDGE_MASK(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + ochip->mask_offset + GPIO_EDGE_MASK_OFF;
+}
+
+static void __iomem *GPIO_LEVEL_MASK(struct orion_gpio_chip *ochip)
+{
+ return ochip->base + ochip->mask_offset + GPIO_LEVEL_MASK_OFF;
+}
+
+
+static struct orion_gpio_chip orion_gpio_chips[2];
+static int orion_gpio_chip_count;
+
+static inline void
+__set_direction(struct orion_gpio_chip *ochip, unsigned pin, int input)
+{
+ u32 u;
+
+ u = readl(GPIO_IO_CONF(ochip));
+ if (input)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel(u, GPIO_IO_CONF(ochip));
+}
+
+static void __set_level(struct orion_gpio_chip *ochip, unsigned pin, int high)
+{
+ u32 u;
+
+ u = readl(GPIO_OUT(ochip));
+ if (high)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel(u, GPIO_OUT(ochip));
+}
+
+static inline void
+__set_blinking(struct orion_gpio_chip *ochip, unsigned pin, int blink)
+{
+ u32 u;
+
+ u = readl(GPIO_BLINK_EN(ochip));
+ if (blink)
+ u |= 1 << pin;
+ else
+ u &= ~(1 << pin);
+ writel(u, GPIO_BLINK_EN(ochip));
+}
+
+static inline int
+orion_gpio_is_valid(struct orion_gpio_chip *ochip, unsigned pin, int mode)
+{
+ if (pin >= ochip->chip.ngpio)
+ goto err_out;
+
+ if ((mode & GPIO_INPUT_OK) && !test_bit(pin, &ochip->valid_input))
+ goto err_out;
+
+ if ((mode & GPIO_OUTPUT_OK) && !test_bit(pin, &ochip->valid_output))
+ goto err_out;
+
+ return 1;
+
+err_out:
+ pr_debug("%s: invalid GPIO %d\n", __func__, pin);
+ return false;
+}
+
+/*
+ * GENERIC_GPIO primitives.
+ */
+static int orion_gpio_request(struct gpio_chip *chip, unsigned pin)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+
+ if (orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK) ||
+ orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
+ return 0;
+
+ return -EINVAL;
+}
+
+static int orion_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ unsigned long flags;
+
+ if (!orion_gpio_is_valid(ochip, pin, GPIO_INPUT_OK))
+ return -EINVAL;
+
+ spin_lock_irqsave(&ochip->lock, flags);
+ __set_direction(ochip, pin, 1);
+ spin_unlock_irqrestore(&ochip->lock, flags);
+
+ return 0;
+}
+
+static int orion_gpio_get(struct gpio_chip *chip, unsigned pin)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ int val;
+
+ if (readl(GPIO_IO_CONF(ochip)) & (1 << pin)) {
+ val = readl(GPIO_DATA_IN(ochip)) ^ readl(GPIO_IN_POL(ochip));
+ } else {
+ val = readl(GPIO_OUT(ochip));
+ }
+
+ return (val >> pin) & 1;
+}
+
+static int
+orion_gpio_direction_output(struct gpio_chip *chip, unsigned pin, int value)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ unsigned long flags;
+
+ if (!orion_gpio_is_valid(ochip, pin, GPIO_OUTPUT_OK))
+ return -EINVAL;
+
+ spin_lock_irqsave(&ochip->lock, flags);
+ __set_blinking(ochip, pin, 0);
+ __set_level(ochip, pin, value);
+ __set_direction(ochip, pin, 0);
+ spin_unlock_irqrestore(&ochip->lock, flags);
+
+ return 0;
+}
+
+static void orion_gpio_set(struct gpio_chip *chip, unsigned pin, int value)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ochip->lock, flags);
+ __set_level(ochip, pin, value);
+ spin_unlock_irqrestore(&ochip->lock, flags);
+}
+
+static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
+{
+ struct orion_gpio_chip *ochip =
+ container_of(chip, struct orion_gpio_chip, chip);
+
+ return ochip->secondary_irq_base + pin;
+}
+
+
+/*
+ * Orion-specific GPIO API extensions.
+ */
+static struct orion_gpio_chip *orion_gpio_chip_find(int pin)
+{
+ int i;
+
+ for (i = 0; i < orion_gpio_chip_count; i++) {
+ struct orion_gpio_chip *ochip = orion_gpio_chips + i;
+ struct gpio_chip *chip = &ochip->chip;
+
+ if (pin >= chip->base && pin < chip->base + chip->ngpio)
+ return ochip;
+ }
+
+ return NULL;
+}
+
+void __init orion_gpio_set_unused(unsigned pin)
+{
+ struct orion_gpio_chip *ochip = orion_gpio_chip_find(pin);
+
+ if (ochip == NULL)
+ return;
+
+ pin -= ochip->chip.base;
+
+ /* Configure as output, drive low. */
+ __set_level(ochip, pin, 0);
+ __set_direction(ochip, pin, 0);
+}
+
+void __init orion_gpio_set_valid(unsigned pin, int mode)
+{
+ struct orion_gpio_chip *ochip = orion_gpio_chip_find(pin);
+
+ if (ochip == NULL)
+ return;
+
+ pin -= ochip->chip.base;
+
+ if (mode == 1)
+ mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
+
+ if (mode & GPIO_INPUT_OK)
+ __set_bit(pin, &ochip->valid_input);
+ else
+ __clear_bit(pin, &ochip->valid_input);
+
+ if (mode & GPIO_OUTPUT_OK)
+ __set_bit(pin, &ochip->valid_output);
+ else
+ __clear_bit(pin, &ochip->valid_output);
+}
+
+void orion_gpio_set_blink(unsigned pin, int blink)
+{
+ struct orion_gpio_chip *ochip = orion_gpio_chip_find(pin);
+ unsigned long flags;
+
+ if (ochip == NULL)
+ return;
+
+ spin_lock_irqsave(&ochip->lock, flags);
+ __set_level(ochip, pin, 0);
+ __set_blinking(ochip, pin, blink);
+ spin_unlock_irqrestore(&ochip->lock, flags);
+}
+EXPORT_SYMBOL(orion_gpio_set_blink);
+
+
+/*****************************************************************************
+ * Orion GPIO IRQ
+ *
+ * GPIO_IN_POL register controls whether GPIO_DATA_IN will hold the same
+ * value of the line or the opposite value.
+ *
+ * Level IRQ handlers: DATA_IN is used directly as cause register.
+ * Interrupt are masked by LEVEL_MASK registers.
+ * Edge IRQ handlers: Change in DATA_IN are latched in EDGE_CAUSE.
+ * Interrupt are masked by EDGE_MASK registers.
+ * Both-edge handlers: Similar to regular Edge handlers, but also swaps
+ * the polarity to catch the next line transaction.
+ * This is a race condition that might not perfectly
+ * work on some use cases.
+ *
+ * Every eight GPIO lines are grouped (OR'ed) before going up to main
+ * cause register.
+ *
+ * EDGE cause mask
+ * data-in /--------| |-----| |----\
+ * -----| |----- ---- to main cause reg
+ * X \----------------| |----/
+ * polarity LEVEL mask
+ *
+ ****************************************************************************/
+
+static int gpio_irq_set_type(struct irq_data *d, u32 type)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct irq_chip_type *ct = irq_data_get_chip_type(d);
+ struct orion_gpio_chip *ochip = gc->private;
+ int pin;
+ u32 u;
+
+ pin = d->irq - gc->irq_base;
+
+ u = readl(GPIO_IO_CONF(ochip)) & (1 << pin);
+ if (!u) {
+ printk(KERN_ERR "orion gpio_irq_set_type failed "
+ "(irq %d, pin %d).\n", d->irq, pin);
+ return -EINVAL;
+ }
+
+ type &= IRQ_TYPE_SENSE_MASK;
+ if (type == IRQ_TYPE_NONE)
+ return -EINVAL;
+
+ /* Check if we need to change chip and handler */
+ if (!(ct->type & type))
+ if (irq_setup_alt_chip(d, type))
+ return -EINVAL;
+
+ /*
+ * Configure interrupt polarity.
+ */
+ if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH) {
+ u = readl(GPIO_IN_POL(ochip));
+ u &= ~(1 << pin);
+ writel(u, GPIO_IN_POL(ochip));
+ } else if (type == IRQ_TYPE_EDGE_FALLING || type == IRQ_TYPE_LEVEL_LOW) {
+ u = readl(GPIO_IN_POL(ochip));
+ u |= 1 << pin;
+ writel(u, GPIO_IN_POL(ochip));
+ } else if (type == IRQ_TYPE_EDGE_BOTH) {
+ u32 v;
+
+ v = readl(GPIO_IN_POL(ochip)) ^ readl(GPIO_DATA_IN(ochip));
+
+ /*
+ * set initial polarity based on current input level
+ */
+ u = readl(GPIO_IN_POL(ochip));
+ if (v & (1 << pin))
+ u |= 1 << pin; /* falling */
+ else
+ u &= ~(1 << pin); /* rising */
+ writel(u, GPIO_IN_POL(ochip));
+ }
+
+ return 0;
+}
+
+void __init orion_gpio_init(int gpio_base, int ngpio,
+ u32 base, int mask_offset, int secondary_irq_base)
+{
+ struct orion_gpio_chip *ochip;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips))
+ return;
+
+ ochip = orion_gpio_chips + orion_gpio_chip_count;
+ ochip->chip.label = "orion_gpio";
+ ochip->chip.request = orion_gpio_request;
+ ochip->chip.direction_input = orion_gpio_direction_input;
+ ochip->chip.get = orion_gpio_get;
+ ochip->chip.direction_output = orion_gpio_direction_output;
+ ochip->chip.set = orion_gpio_set;
+ ochip->chip.to_irq = orion_gpio_to_irq;
+ ochip->chip.base = gpio_base;
+ ochip->chip.ngpio = ngpio;
+ ochip->chip.can_sleep = 0;
+ spin_lock_init(&ochip->lock);
+ ochip->base = (void __iomem *)base;
+ ochip->valid_input = 0;
+ ochip->valid_output = 0;
+ ochip->mask_offset = mask_offset;
+ ochip->secondary_irq_base = secondary_irq_base;
+
+ gpiochip_add(&ochip->chip);
+
+ orion_gpio_chip_count++;
+
+ /*
+ * Mask and clear GPIO interrupts.
+ */
+ writel(0, GPIO_EDGE_CAUSE(ochip));
+ writel(0, GPIO_EDGE_MASK(ochip));
+ writel(0, GPIO_LEVEL_MASK(ochip));
+
+ gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base,
+ ochip->base, handle_level_irq);
+ gc->private = ochip;
+
+ ct = gc->chip_types;
+ ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF;
+ ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_set_type = gpio_irq_set_type;
+
+ ct++;
+ ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF;
+ ct->regs.ack = GPIO_EDGE_CAUSE_OFF;
+ ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ ct->chip.irq_ack = irq_gc_ack_clr_bit;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_set_type = gpio_irq_set_type;
+ ct->handler = handle_edge_irq;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
+}
+
+void orion_gpio_irq_handler(int pinoff)
+{
+ struct orion_gpio_chip *ochip;
+ u32 cause, type;
+ int i;
+
+ ochip = orion_gpio_chip_find(pinoff);
+ if (ochip == NULL)
+ return;
+
+ cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip));
+ cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip));
+
+ for (i = 0; i < ochip->chip.ngpio; i++) {
+ int irq;
+
+ irq = ochip->secondary_irq_base + i;
+
+ if (!(cause & (1 << i)))
+ continue;
+
+ type = irqd_get_trigger_type(irq_get_irq_data(irq));
+ if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ /* Swap polarity (race with GPIO line) */
+ u32 polarity;
+
+ polarity = readl(GPIO_IN_POL(ochip));
+ polarity ^= 1 << i;
+ writel(polarity, GPIO_IN_POL(ochip));
+ }
+ generic_handle_irq(irq);
+ }
+}
diff --git a/arch/arm/plat-orion/include/plat/audio.h b/arch/arm/plat-orion/include/plat/audio.h
new file mode 100644
index 00000000..9cf1f781
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/audio.h
@@ -0,0 +1,11 @@
+#ifndef __PLAT_AUDIO_H
+#define __PLAT_AUDIO_H
+
+#include <linux/mbus.h>
+
+struct kirkwood_asoc_platform_data {
+ u32 tclk;
+ struct mbus_dram_target_info *dram;
+ int burst;
+};
+#endif
diff --git a/arch/arm/plat-orion/include/plat/cache-feroceon-l2.h b/arch/arm/plat-orion/include/plat/cache-feroceon-l2.h
new file mode 100644
index 00000000..06f982d5
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/cache-feroceon-l2.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/plat-orion/include/plat/cache-feroceon-l2.h
+ *
+ * Copyright (C) 2008 Marvell Semiconductor
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+extern void __init feroceon_l2_init(int l2_wt_override);
diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h
new file mode 100644
index 00000000..a2c0e31c
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/common.h
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/plat-orion/include/plat/common.h
+ *
+ * Marvell Orion SoC common setup code used by different mach-/common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_COMMON_H
+#include <linux/mv643xx_eth.h>
+
+struct dsa_platform_data;
+
+void __init orion_uart0_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk);
+
+void __init orion_uart1_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk);
+
+void __init orion_uart2_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk);
+
+void __init orion_uart3_init(unsigned int membase,
+ resource_size_t mapbase,
+ unsigned int irq,
+ unsigned int uartclk);
+
+void __init orion_rtc_init(unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk);
+
+void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk);
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk);
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ unsigned long irq_err,
+ int tclk);
+
+void __init orion_ge00_switch_init(struct dsa_platform_data *d,
+ int irq);
+void __init orion_i2c_init(unsigned long mapbase,
+ unsigned long irq,
+ unsigned long freq_m);
+
+void __init orion_i2c_1_init(unsigned long mapbase,
+ unsigned long irq,
+ unsigned long freq_m);
+
+void __init orion_spi_init(unsigned long mapbase,
+ unsigned long tclk);
+
+void __init orion_spi_1_init(unsigned long mapbase,
+ unsigned long tclk);
+
+void __init orion_wdt_init(unsigned long tclk);
+
+void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase_low,
+ unsigned long mapbase_high,
+ unsigned long irq_0,
+ unsigned long irq_1);
+
+void __init orion_xor1_init(unsigned long mapbase_low,
+ unsigned long mapbase_high,
+ unsigned long irq_0,
+ unsigned long irq_1);
+
+void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq,
+ enum orion_ehci_phy_ver phy_version);
+
+void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
+ struct mbus_dram_target_info *mbus_dram_info,
+ unsigned long mapbase,
+ unsigned long irq);
+
+void __init orion_crypto_init(unsigned long mapbase,
+ unsigned long srambase,
+ unsigned long sram_size,
+ unsigned long irq);
+#endif
diff --git a/arch/arm/plat-orion/include/plat/ehci-orion.h b/arch/arm/plat-orion/include/plat/ehci-orion.h
new file mode 100644
index 00000000..4ec668e7
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/ehci-orion.h
@@ -0,0 +1,27 @@
+/*
+ * arch/arm/plat-orion/include/plat/ehci-orion.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_EHCI_ORION_H
+#define __PLAT_EHCI_ORION_H
+
+#include <linux/mbus.h>
+
+enum orion_ehci_phy_ver {
+ EHCI_PHY_ORION,
+ EHCI_PHY_DD,
+ EHCI_PHY_KW,
+ EHCI_PHY_NA,
+};
+
+struct orion_ehci_data {
+ struct mbus_dram_target_info *dram;
+ enum orion_ehci_phy_ver phy_version;
+};
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h
new file mode 100644
index 00000000..3075b9fd
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/gpio.h
@@ -0,0 +1,45 @@
+/*
+ * arch/arm/plat-orion/include/plat/gpio.h
+ *
+ * Marvell Orion SoC GPIO handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+#include <linux/init.h>
+#include <asm-generic/gpio.h>
+
+/*
+ * GENERIC_GPIO primitives.
+ */
+#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
+
+/*
+ * Orion-specific GPIO API extensions.
+ */
+void orion_gpio_set_unused(unsigned pin);
+void orion_gpio_set_blink(unsigned pin, int blink);
+
+#define GPIO_INPUT_OK (1 << 0)
+#define GPIO_OUTPUT_OK (1 << 1)
+void orion_gpio_set_valid(unsigned pin, int mode);
+
+/* Initialize gpiolib. */
+void __init orion_gpio_init(int gpio_base, int ngpio,
+ u32 base, int mask_offset, int secondary_irq_base);
+
+/*
+ * GPIO interrupt handling.
+ */
+void orion_gpio_irq_handler(int irqoff);
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/irq.h b/arch/arm/plat-orion/include/plat/irq.h
new file mode 100644
index 00000000..f05eeab9
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/irq.h
@@ -0,0 +1,17 @@
+/*
+ * arch/arm/plat-orion/include/plat/irq.h
+ *
+ * Marvell Orion SoC IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_IRQ_H
+#define __PLAT_IRQ_H
+
+void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr);
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/mpp.h b/arch/arm/plat-orion/include/plat/mpp.h
new file mode 100644
index 00000000..723adce9
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/mpp.h
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-orion/include/plat/mpp.h
+ *
+ * Marvell Orion SoC MPP handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_MPP_H
+#define __PLAT_MPP_H
+
+#define MPP_NUM(x) ((x) & 0xff)
+#define MPP_SEL(x) (((x) >> 8) & 0xf)
+
+/* This is the generic MPP macro, without any variant information.
+ Each machine architecture is expected to extend this with further
+ bit fields indicating which MPP configurations are valid for a
+ specific variant. */
+
+#define GENERIC_MPP(_num, _sel, _in, _out) ( \
+ /* MPP number */ ((_num) & 0xff) | \
+ /* MPP select value */ (((_sel) & 0xf) << 8) | \
+ /* may be input signal */ ((!!(_in)) << 12) | \
+ /* may be output signal */ ((!!(_out)) << 13))
+
+#define MPP_INPUT_MASK GENERIC_MPP(0, 0x0, 1, 0)
+#define MPP_OUTPUT_MASK GENERIC_MPP(0, 0x0, 0, 1)
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+ unsigned int mpp_max, unsigned int dev_bus);
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/mv_xor.h b/arch/arm/plat-orion/include/plat/mv_xor.h
new file mode 100644
index 00000000..bd5f3bdb
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/mv_xor.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/plat-orion/include/plat/mv_xor.h
+ *
+ * Marvell XOR platform device data definition file.
+ */
+
+#ifndef __PLAT_MV_XOR_H
+#define __PLAT_MV_XOR_H
+
+#include <linux/dmaengine.h>
+#include <linux/mbus.h>
+
+#define MV_XOR_SHARED_NAME "mv_xor_shared"
+#define MV_XOR_NAME "mv_xor"
+
+struct mbus_dram_target_info;
+
+struct mv_xor_platform_shared_data {
+ struct mbus_dram_target_info *dram;
+};
+
+struct mv_xor_platform_data {
+ struct platform_device *shared;
+ int hw_id;
+ dma_cap_mask_t cap_mask;
+ size_t pool_size;
+};
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/mvsdio.h b/arch/arm/plat-orion/include/plat/mvsdio.h
new file mode 100644
index 00000000..14ca8867
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/mvsdio.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/plat-orion/include/plat/mvsdio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __MACH_MVSDIO_H
+#define __MACH_MVSDIO_H
+
+#include <linux/mbus.h>
+
+struct mvsdio_platform_data {
+ struct mbus_dram_target_info *dram;
+ unsigned int clock;
+ int gpio_card_detect;
+ int gpio_write_protect;
+};
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/orion_nand.h b/arch/arm/plat-orion/include/plat/orion_nand.h
new file mode 100644
index 00000000..9f3c1808
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/orion_nand.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/plat-orion/include/plat/orion_nand.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_ORION_NAND_H
+#define __PLAT_ORION_NAND_H
+
+/*
+ * Device bus NAND private data
+ */
+struct orion_nand_data {
+ struct mtd_partition *parts;
+ int (*dev_ready)(struct mtd_info *mtd);
+ u32 nr_parts;
+ u8 ale; /* address line number connected to ALE */
+ u8 cle; /* address line number connected to CLE */
+ u8 width; /* buswidth */
+ u8 chip_delay;
+};
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/orion_wdt.h b/arch/arm/plat-orion/include/plat/orion_wdt.h
new file mode 100644
index 00000000..665c362a
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/orion_wdt.h
@@ -0,0 +1,18 @@
+/*
+ * arch/arm/plat-orion/include/plat/orion_wdt.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_ORION_WDT_H
+#define __PLAT_ORION_WDT_H
+
+struct orion_wdt_platform_data {
+ u32 tclk; /* no <linux/clk.h> support yet */
+};
+
+
+#endif
+
diff --git a/arch/arm/plat-orion/include/plat/pcie.h b/arch/arm/plat-orion/include/plat/pcie.h
new file mode 100644
index 00000000..cc99163e
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/pcie.h
@@ -0,0 +1,35 @@
+/*
+ * arch/arm/plat-orion/include/plat/pcie.h
+ *
+ * Marvell Orion SoC PCIe handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_PCIE_H
+#define __PLAT_PCIE_H
+
+struct pci_bus;
+
+u32 orion_pcie_dev_id(void __iomem *base);
+u32 orion_pcie_rev(void __iomem *base);
+int orion_pcie_link_up(void __iomem *base);
+int orion_pcie_x4_mode(void __iomem *base);
+int orion_pcie_get_local_bus_nr(void __iomem *base);
+void orion_pcie_set_local_bus_nr(void __iomem *base, int nr);
+void orion_pcie_reset(void __iomem *base);
+void orion_pcie_setup(void __iomem *base,
+ struct mbus_dram_target_info *dram);
+int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val);
+int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val);
+int orion_pcie_rd_conf_wa(void __iomem *wa_base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val);
+int orion_pcie_wr_conf(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 val);
+
+
+#endif
diff --git a/arch/arm/plat-orion/include/plat/time.h b/arch/arm/plat-orion/include/plat/time.h
new file mode 100644
index 00000000..4d5f1f6e
--- /dev/null
+++ b/arch/arm/plat-orion/include/plat/time.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-orion/include/plat/time.h
+ *
+ * Marvell Orion SoC time handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_TIME_H
+#define __PLAT_TIME_H
+
+void orion_time_set_base(u32 timer_base);
+
+void orion_time_init(u32 bridge_base, u32 bridge_timer1_clr_mask,
+ unsigned int irq, unsigned int tclk);
+
+
+#endif
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
new file mode 100644
index 00000000..2d5b9c1e
--- /dev/null
+++ b/arch/arm/plat-orion/irq.c
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-orion/irq.c
+ *
+ * Marvell Orion SoC IRQ handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <plat/irq.h>
+
+void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ /*
+ * Mask all interrupts initially.
+ */
+ writel(0, maskaddr);
+
+ gc = irq_alloc_generic_chip("orion_irq", 1, irq_start, maskaddr,
+ handle_level_irq);
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
+}
diff --git a/arch/arm/plat-orion/mpp.c b/arch/arm/plat-orion/mpp.c
new file mode 100644
index 00000000..3b1e17bd
--- /dev/null
+++ b/arch/arm/plat-orion/mpp.c
@@ -0,0 +1,77 @@
+/*
+ * arch/arm/plat-orion/mpp.c
+ *
+ * MPP functions for Marvell orion SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <plat/mpp.h>
+
+/* Address of the ith MPP control register */
+static __init unsigned long mpp_ctrl_addr(unsigned int i,
+ unsigned long dev_bus)
+{
+ return dev_bus + (i) * 4;
+}
+
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+ unsigned int mpp_max, unsigned int dev_bus)
+{
+ unsigned int mpp_nr_regs = (1 + mpp_max/8);
+ u32 mpp_ctrl[mpp_nr_regs];
+ int i;
+
+ printk(KERN_DEBUG "initial MPP regs:");
+ for (i = 0; i < mpp_nr_regs; i++) {
+ mpp_ctrl[i] = readl(mpp_ctrl_addr(i, dev_bus));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+
+ for ( ; *mpp_list; mpp_list++) {
+ unsigned int num = MPP_NUM(*mpp_list);
+ unsigned int sel = MPP_SEL(*mpp_list);
+ int shift, gpio_mode;
+
+ if (num > mpp_max) {
+ printk(KERN_ERR "orion_mpp_conf: invalid MPP "
+ "number (%u)\n", num);
+ continue;
+ }
+ if (variant_mask & !(*mpp_list & variant_mask)) {
+ printk(KERN_WARNING
+ "orion_mpp_conf: requested MPP%u config "
+ "unavailable on this hardware\n", num);
+ continue;
+ }
+
+ shift = (num & 7) << 2;
+ mpp_ctrl[num / 8] &= ~(0xf << shift);
+ mpp_ctrl[num / 8] |= sel << shift;
+
+ gpio_mode = 0;
+ if (*mpp_list & MPP_INPUT_MASK)
+ gpio_mode |= GPIO_INPUT_OK;
+ if (*mpp_list & MPP_OUTPUT_MASK)
+ gpio_mode |= GPIO_OUTPUT_OK;
+
+ orion_gpio_set_valid(num, gpio_mode);
+ }
+
+ printk(KERN_DEBUG " final MPP regs:");
+ for (i = 0; i < mpp_nr_regs; i++) {
+ writel(mpp_ctrl[i], mpp_ctrl_addr(i, dev_bus));
+ printk(" %08x", mpp_ctrl[i]);
+ }
+ printk("\n");
+}
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c
new file mode 100644
index 00000000..af2d733c
--- /dev/null
+++ b/arch/arm/plat-orion/pcie.c
@@ -0,0 +1,286 @@
+/*
+ * arch/arm/plat-orion/pcie.c
+ *
+ * Marvell Orion SoC PCIe handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mbus.h>
+#include <asm/mach/pci.h>
+#include <plat/pcie.h>
+#include <linux/delay.h>
+
+/*
+ * PCIe unit register offsets.
+ */
+#define PCIE_DEV_ID_OFF 0x0000
+#define PCIE_CMD_OFF 0x0004
+#define PCIE_DEV_REV_OFF 0x0008
+#define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
+#define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
+#define PCIE_HEADER_LOG_4_OFF 0x0128
+#define PCIE_BAR_CTRL_OFF(n) (0x1804 + ((n - 1) * 4))
+#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
+#define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
+#define PCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
+#define PCIE_WIN5_CTRL_OFF 0x1880
+#define PCIE_WIN5_BASE_OFF 0x1884
+#define PCIE_WIN5_REMAP_OFF 0x188c
+#define PCIE_CONF_ADDR_OFF 0x18f8
+#define PCIE_CONF_ADDR_EN 0x80000000
+#define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc))
+#define PCIE_CONF_BUS(b) (((b) & 0xff) << 16)
+#define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11)
+#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8)
+#define PCIE_CONF_DATA_OFF 0x18fc
+#define PCIE_MASK_OFF 0x1910
+#define PCIE_CTRL_OFF 0x1a00
+#define PCIE_CTRL_X1_MODE 0x0001
+#define PCIE_STAT_OFF 0x1a04
+#define PCIE_STAT_DEV_OFFS 20
+#define PCIE_STAT_DEV_MASK 0x1f
+#define PCIE_STAT_BUS_OFFS 8
+#define PCIE_STAT_BUS_MASK 0xff
+#define PCIE_STAT_LINK_DOWN 1
+#define PCIE_DEBUG_CTRL 0x1a60
+#define PCIE_DEBUG_SOFT_RESET (1<<20)
+
+
+u32 __init orion_pcie_dev_id(void __iomem *base)
+{
+ return readl(base + PCIE_DEV_ID_OFF) >> 16;
+}
+
+u32 __init orion_pcie_rev(void __iomem *base)
+{
+ return readl(base + PCIE_DEV_REV_OFF) & 0xff;
+}
+
+int orion_pcie_link_up(void __iomem *base)
+{
+ return !(readl(base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN);
+}
+
+int __init orion_pcie_x4_mode(void __iomem *base)
+{
+ return !(readl(base + PCIE_CTRL_OFF) & PCIE_CTRL_X1_MODE);
+}
+
+int orion_pcie_get_local_bus_nr(void __iomem *base)
+{
+ u32 stat = readl(base + PCIE_STAT_OFF);
+
+ return (stat >> PCIE_STAT_BUS_OFFS) & PCIE_STAT_BUS_MASK;
+}
+
+void __init orion_pcie_set_local_bus_nr(void __iomem *base, int nr)
+{
+ u32 stat;
+
+ stat = readl(base + PCIE_STAT_OFF);
+ stat &= ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_OFFS);
+ stat |= nr << PCIE_STAT_BUS_OFFS;
+ writel(stat, base + PCIE_STAT_OFF);
+}
+
+void __init orion_pcie_reset(void __iomem *base)
+{
+ u32 reg;
+ int i;
+
+ /*
+ * MV-S104860-U0, Rev. C:
+ * PCI Express Unit Soft Reset
+ * When set, generates an internal reset in the PCI Express unit.
+ * This bit should be cleared after the link is re-established.
+ */
+ reg = readl(base + PCIE_DEBUG_CTRL);
+ reg |= PCIE_DEBUG_SOFT_RESET;
+ writel(reg, base + PCIE_DEBUG_CTRL);
+
+ for (i = 0; i < 20; i++) {
+ mdelay(10);
+
+ if (orion_pcie_link_up(base))
+ break;
+ }
+
+ reg &= ~(PCIE_DEBUG_SOFT_RESET);
+ writel(reg, base + PCIE_DEBUG_CTRL);
+}
+
+/*
+ * Setup PCIE BARs and Address Decode Wins:
+ * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
+ * WIN[0-3] -> DRAM bank[0-3]
+ */
+static void __init orion_pcie_setup_wins(void __iomem *base,
+ struct mbus_dram_target_info *dram)
+{
+ u32 size;
+ int i;
+
+ /*
+ * First, disable and clear BARs and windows.
+ */
+ for (i = 1; i <= 2; i++) {
+ writel(0, base + PCIE_BAR_CTRL_OFF(i));
+ writel(0, base + PCIE_BAR_LO_OFF(i));
+ writel(0, base + PCIE_BAR_HI_OFF(i));
+ }
+
+ for (i = 0; i < 5; i++) {
+ writel(0, base + PCIE_WIN04_CTRL_OFF(i));
+ writel(0, base + PCIE_WIN04_BASE_OFF(i));
+ writel(0, base + PCIE_WIN04_REMAP_OFF(i));
+ }
+
+ writel(0, base + PCIE_WIN5_CTRL_OFF);
+ writel(0, base + PCIE_WIN5_BASE_OFF);
+ writel(0, base + PCIE_WIN5_REMAP_OFF);
+
+ /*
+ * Setup windows for DDR banks. Count total DDR size on the fly.
+ */
+ size = 0;
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+
+ writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i));
+ writel(0, base + PCIE_WIN04_REMAP_OFF(i));
+ writel(((cs->size - 1) & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ base + PCIE_WIN04_CTRL_OFF(i));
+
+ size += cs->size;
+ }
+
+ /*
+ * Round up 'size' to the nearest power of two.
+ */
+ if ((size & (size - 1)) != 0)
+ size = 1 << fls(size);
+
+ /*
+ * Setup BAR[1] to all DRAM banks.
+ */
+ writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1));
+ writel(0, base + PCIE_BAR_HI_OFF(1));
+ writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1));
+}
+
+void __init orion_pcie_setup(void __iomem *base,
+ struct mbus_dram_target_info *dram)
+{
+ u16 cmd;
+ u32 mask;
+
+ /*
+ * Point PCIe unit MBUS decode windows to DRAM space.
+ */
+ orion_pcie_setup_wins(base, dram);
+
+ /*
+ * Master + slave enable.
+ */
+ cmd = readw(base + PCIE_CMD_OFF);
+ cmd |= PCI_COMMAND_IO;
+ cmd |= PCI_COMMAND_MEMORY;
+ cmd |= PCI_COMMAND_MASTER;
+ writew(cmd, base + PCIE_CMD_OFF);
+
+ /*
+ * Enable interrupt lines A-D.
+ */
+ mask = readl(base + PCIE_MASK_OFF);
+ mask |= 0x0f000000;
+ writel(mask, base + PCIE_MASK_OFF);
+}
+
+int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val)
+{
+ writel(PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+ PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
+ base + PCIE_CONF_ADDR_OFF);
+
+ *val = readl(base + PCIE_CONF_DATA_OFF);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val)
+{
+ writel(PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+ PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
+ base + PCIE_CONF_ADDR_OFF);
+
+ *val = readl(base + PCIE_CONF_DATA_OFF);
+
+ if (bus->number != orion_pcie_get_local_bus_nr(base) ||
+ PCI_FUNC(devfn) != 0)
+ *val = readl(base + PCIE_HEADER_LOG_4_OFF);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int orion_pcie_rd_conf_wa(void __iomem *wa_base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 *val)
+{
+ *val = readl(wa_base + (PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+ PCIE_CONF_REG(where)));
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int orion_pcie_wr_conf(void __iomem *base, struct pci_bus *bus,
+ u32 devfn, int where, int size, u32 val)
+{
+ int ret = PCIBIOS_SUCCESSFUL;
+
+ writel(PCIE_CONF_BUS(bus->number) |
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) |
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) |
+ PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN,
+ base + PCIE_CONF_ADDR_OFF);
+
+ if (size == 4) {
+ writel(val, base + PCIE_CONF_DATA_OFF);
+ } else if (size == 2) {
+ writew(val, base + PCIE_CONF_DATA_OFF + (where & 3));
+ } else if (size == 1) {
+ writeb(val, base + PCIE_CONF_DATA_OFF + (where & 3));
+ } else {
+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ return ret;
+}
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
new file mode 100644
index 00000000..69a61367
--- /dev/null
+++ b/arch/arm/plat-orion/time.c
@@ -0,0 +1,244 @@
+/*
+ * arch/arm/plat-orion/time.c
+ *
+ * Marvell Orion SoC timer handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * Timer 0 is used as free-running clocksource, while timer 1 is
+ * used as clock_event_device.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/sched_clock.h>
+
+/*
+ * MBus bridge block registers.
+ */
+#define BRIDGE_CAUSE_OFF 0x0110
+#define BRIDGE_MASK_OFF 0x0114
+#define BRIDGE_INT_TIMER0 0x0002
+#define BRIDGE_INT_TIMER1 0x0004
+
+
+/*
+ * Timer block registers.
+ */
+#define TIMER_CTRL_OFF 0x0000
+#define TIMER0_EN 0x0001
+#define TIMER0_RELOAD_EN 0x0002
+#define TIMER1_EN 0x0004
+#define TIMER1_RELOAD_EN 0x0008
+#define TIMER0_RELOAD_OFF 0x0010
+#define TIMER0_VAL_OFF 0x0014
+#define TIMER1_RELOAD_OFF 0x0018
+#define TIMER1_VAL_OFF 0x001c
+
+
+/*
+ * SoC-specific data.
+ */
+static void __iomem *bridge_base;
+static u32 bridge_timer1_clr_mask;
+static void __iomem *timer_base;
+
+
+/*
+ * Number of timer ticks per jiffy.
+ */
+static u32 ticks_per_jiffy;
+
+
+/*
+ * Orion's sched_clock implementation. It has a resolution of
+ * at least 7.5ns (133MHz TCLK).
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+
+static void notrace orion_update_sched_clock(void)
+{
+ u32 cyc = ~readl(timer_base + TIMER0_VAL_OFF);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void __init setup_sched_clock(unsigned long tclk)
+{
+ init_sched_clock(&cd, orion_update_sched_clock, 32, tclk);
+}
+
+/*
+ * Clockevent handling.
+ */
+static int
+orion_clkevt_next_event(unsigned long delta, struct clock_event_device *dev)
+{
+ unsigned long flags;
+ u32 u;
+
+ if (delta == 0)
+ return -ETIME;
+
+ local_irq_save(flags);
+
+ /*
+ * Clear and enable clockevent timer interrupt.
+ */
+ writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
+
+ u = readl(bridge_base + BRIDGE_MASK_OFF);
+ u |= BRIDGE_INT_TIMER1;
+ writel(u, bridge_base + BRIDGE_MASK_OFF);
+
+ /*
+ * Setup new clockevent timer value.
+ */
+ writel(delta, timer_base + TIMER1_VAL_OFF);
+
+ /*
+ * Enable the timer.
+ */
+ u = readl(timer_base + TIMER_CTRL_OFF);
+ u = (u & ~TIMER1_RELOAD_EN) | TIMER1_EN;
+ writel(u, timer_base + TIMER_CTRL_OFF);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static void
+orion_clkevt_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+{
+ unsigned long flags;
+ u32 u;
+
+ local_irq_save(flags);
+ if (mode == CLOCK_EVT_MODE_PERIODIC) {
+ /*
+ * Setup timer to fire at 1/HZ intervals.
+ */
+ writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD_OFF);
+ writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL_OFF);
+
+ /*
+ * Enable timer interrupt.
+ */
+ u = readl(bridge_base + BRIDGE_MASK_OFF);
+ writel(u | BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
+
+ /*
+ * Enable timer.
+ */
+ u = readl(timer_base + TIMER_CTRL_OFF);
+ writel(u | TIMER1_EN | TIMER1_RELOAD_EN,
+ timer_base + TIMER_CTRL_OFF);
+ } else {
+ /*
+ * Disable timer.
+ */
+ u = readl(timer_base + TIMER_CTRL_OFF);
+ writel(u & ~TIMER1_EN, timer_base + TIMER_CTRL_OFF);
+
+ /*
+ * Disable timer interrupt.
+ */
+ u = readl(bridge_base + BRIDGE_MASK_OFF);
+ writel(u & ~BRIDGE_INT_TIMER1, bridge_base + BRIDGE_MASK_OFF);
+
+ /*
+ * ACK pending timer interrupt.
+ */
+ writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
+
+ }
+ local_irq_restore(flags);
+}
+
+static struct clock_event_device orion_clkevt = {
+ .name = "orion_tick",
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .shift = 32,
+ .rating = 300,
+ .set_next_event = orion_clkevt_next_event,
+ .set_mode = orion_clkevt_mode,
+};
+
+static irqreturn_t orion_timer_interrupt(int irq, void *dev_id)
+{
+ /*
+ * ACK timer interrupt and call event handler.
+ */
+ writel(bridge_timer1_clr_mask, bridge_base + BRIDGE_CAUSE_OFF);
+ orion_clkevt.event_handler(&orion_clkevt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction orion_timer_irq = {
+ .name = "orion_tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = orion_timer_interrupt
+};
+
+void __init
+orion_time_set_base(u32 _timer_base)
+{
+ timer_base = (void __iomem *)_timer_base;
+}
+
+void __init
+orion_time_init(u32 _bridge_base, u32 _bridge_timer1_clr_mask,
+ unsigned int irq, unsigned int tclk)
+{
+ u32 u;
+
+ /*
+ * Set SoC-specific data.
+ */
+ bridge_base = (void __iomem *)_bridge_base;
+ bridge_timer1_clr_mask = _bridge_timer1_clr_mask;
+
+ ticks_per_jiffy = (tclk + HZ/2) / HZ;
+
+ /*
+ * Set scale and timer for sched_clock.
+ */
+ setup_sched_clock(tclk);
+
+ /*
+ * Setup free-running clocksource timer (interrupts
+ * disabled).
+ */
+ writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
+ writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
+ u = readl(bridge_base + BRIDGE_MASK_OFF);
+ writel(u & ~BRIDGE_INT_TIMER0, bridge_base + BRIDGE_MASK_OFF);
+ u = readl(timer_base + TIMER_CTRL_OFF);
+ writel(u | TIMER0_EN | TIMER0_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
+ clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, "orion_clocksource",
+ tclk, 300, 32, clocksource_mmio_readl_down);
+
+ /*
+ * Setup clockevent timer (interrupt-driven).
+ */
+ setup_irq(irq, &orion_timer_irq);
+ orion_clkevt.mult = div_sc(tclk, NSEC_PER_SEC, orion_clkevt.shift);
+ orion_clkevt.max_delta_ns = clockevent_delta2ns(0xfffffffe, &orion_clkevt);
+ orion_clkevt.min_delta_ns = clockevent_delta2ns(1, &orion_clkevt);
+ orion_clkevt.cpumask = cpumask_of(0);
+ clockevents_register_device(&orion_clkevt);
+}
diff --git a/arch/arm/plat-pxa/Kconfig b/arch/arm/plat-pxa/Kconfig
new file mode 100644
index 00000000..da53395a
--- /dev/null
+++ b/arch/arm/plat-pxa/Kconfig
@@ -0,0 +1,8 @@
+if PLAT_PXA
+
+config PXA_SSP
+ tristate
+ help
+ Enable support for PXA2xx SSP ports
+
+endif
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
new file mode 100644
index 00000000..3aca5ba0
--- /dev/null
+++ b/arch/arm/plat-pxa/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for code common across different PXA processor families
+#
+
+obj-y := dma.o
+
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
+obj-$(CONFIG_PXA3xx) += mfp.o
+obj-$(CONFIG_PXA95x) += mfp.o
+obj-$(CONFIG_ARCH_MMP) += mfp.o
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
+obj-$(CONFIG_PXA_SSP) += ssp.o
diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c
new file mode 100644
index 00000000..2d3c19d7
--- /dev/null
+++ b/arch/arm/plat-pxa/dma.c
@@ -0,0 +1,392 @@
+/*
+ * linux/arch/arm/plat-pxa/dma.c
+ *
+ * PXA DMA registration and IRQ dispatching
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/memory.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+
+#define DMA_DEBUG_NAME "pxa_dma"
+#define DMA_MAX_REQUESTERS 64
+
+struct dma_channel {
+ char *name;
+ pxa_dma_prio prio;
+ void (*irq_handler)(int, void *);
+ void *data;
+ spinlock_t lock;
+};
+
+static struct dma_channel *dma_channels;
+static int num_dma_channels;
+
+/*
+ * Debug fs
+ */
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+
+static struct dentry *dbgfs_root, *dbgfs_state, **dbgfs_chan;
+
+static int dbg_show_requester_chan(struct seq_file *s, void *p)
+{
+ int pos = 0;
+ int chan = (int)s->private;
+ int i;
+ u32 drcmr;
+
+ pos += seq_printf(s, "DMA channel %d requesters list :\n", chan);
+ for (i = 0; i < DMA_MAX_REQUESTERS; i++) {
+ drcmr = DRCMR(i);
+ if ((drcmr & DRCMR_CHLNUM) == chan)
+ pos += seq_printf(s, "\tRequester %d (MAPVLD=%d)\n", i,
+ !!(drcmr & DRCMR_MAPVLD));
+ }
+ return pos;
+}
+
+static inline int dbg_burst_from_dcmd(u32 dcmd)
+{
+ int burst = (dcmd >> 16) & 0x3;
+
+ return burst ? 4 << burst : 0;
+}
+
+static int is_phys_valid(unsigned long addr)
+{
+ return pfn_valid(__phys_to_pfn(addr));
+}
+
+#define DCSR_STR(flag) (dcsr & DCSR_##flag ? #flag" " : "")
+#define DCMD_STR(flag) (dcmd & DCMD_##flag ? #flag" " : "")
+
+static int dbg_show_descriptors(struct seq_file *s, void *p)
+{
+ int pos = 0;
+ int chan = (int)s->private;
+ int i, max_show = 20, burst, width;
+ u32 dcmd;
+ unsigned long phys_desc;
+ struct pxa_dma_desc *desc;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dma_channels[chan].lock, flags);
+ phys_desc = DDADR(chan);
+
+ pos += seq_printf(s, "DMA channel %d descriptors :\n", chan);
+ pos += seq_printf(s, "[%03d] First descriptor unknown\n", 0);
+ for (i = 1; i < max_show && is_phys_valid(phys_desc); i++) {
+ desc = phys_to_virt(phys_desc);
+ dcmd = desc->dcmd;
+ burst = dbg_burst_from_dcmd(dcmd);
+ width = (1 << ((dcmd >> 14) & 0x3)) >> 1;
+
+ pos += seq_printf(s, "[%03d] Desc at %08lx(virt %p)\n",
+ i, phys_desc, desc);
+ pos += seq_printf(s, "\tDDADR = %08x\n", desc->ddadr);
+ pos += seq_printf(s, "\tDSADR = %08x\n", desc->dsadr);
+ pos += seq_printf(s, "\tDTADR = %08x\n", desc->dtadr);
+ pos += seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d"
+ " width=%d len=%d)\n",
+ dcmd,
+ DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
+ DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
+ DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
+ DCMD_STR(ENDIAN), burst, width,
+ dcmd & DCMD_LENGTH);
+ phys_desc = desc->ddadr;
+ }
+ if (i == max_show)
+ pos += seq_printf(s, "[%03d] Desc at %08lx ... max display reached\n",
+ i, phys_desc);
+ else
+ pos += seq_printf(s, "[%03d] Desc at %08lx is %s\n",
+ i, phys_desc, phys_desc == DDADR_STOP ?
+ "DDADR_STOP" : "invalid");
+
+ spin_unlock_irqrestore(&dma_channels[chan].lock, flags);
+ return pos;
+}
+
+static int dbg_show_chan_state(struct seq_file *s, void *p)
+{
+ int pos = 0;
+ int chan = (int)s->private;
+ u32 dcsr, dcmd;
+ int burst, width;
+ static char *str_prio[] = { "high", "normal", "low" };
+
+ dcsr = DCSR(chan);
+ dcmd = DCMD(chan);
+ burst = dbg_burst_from_dcmd(dcmd);
+ width = (1 << ((dcmd >> 14) & 0x3)) >> 1;
+
+ pos += seq_printf(s, "DMA channel %d\n", chan);
+ pos += seq_printf(s, "\tPriority : %s\n",
+ str_prio[dma_channels[chan].prio]);
+ pos += seq_printf(s, "\tUnaligned transfer bit: %s\n",
+ DALGN & (1 << chan) ? "yes" : "no");
+ pos += seq_printf(s, "\tDCSR = %08x (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
+ dcsr, DCSR_STR(RUN), DCSR_STR(NODESC),
+ DCSR_STR(STOPIRQEN), DCSR_STR(EORIRQEN),
+ DCSR_STR(EORJMPEN), DCSR_STR(EORSTOPEN),
+ DCSR_STR(SETCMPST), DCSR_STR(CLRCMPST),
+ DCSR_STR(CMPST), DCSR_STR(EORINTR), DCSR_STR(REQPEND),
+ DCSR_STR(STOPSTATE), DCSR_STR(ENDINTR),
+ DCSR_STR(STARTINTR), DCSR_STR(BUSERR));
+
+ pos += seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d"
+ " len=%d)\n",
+ dcmd,
+ DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
+ DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
+ DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
+ DCMD_STR(ENDIAN), burst, width, dcmd & DCMD_LENGTH);
+ pos += seq_printf(s, "\tDSADR = %08x\n", DSADR(chan));
+ pos += seq_printf(s, "\tDTADR = %08x\n", DTADR(chan));
+ pos += seq_printf(s, "\tDDADR = %08x\n", DDADR(chan));
+ return pos;
+}
+
+static int dbg_show_state(struct seq_file *s, void *p)
+{
+ int pos = 0;
+
+ /* basic device status */
+ pos += seq_printf(s, "DMA engine status\n");
+ pos += seq_printf(s, "\tChannel number: %d\n", num_dma_channels);
+
+ return pos;
+}
+
+#define DBGFS_FUNC_DECL(name) \
+static int dbg_open_##name(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, dbg_show_##name, inode->i_private); \
+} \
+static const struct file_operations dbg_fops_##name = { \
+ .owner = THIS_MODULE, \
+ .open = dbg_open_##name, \
+ .llseek = seq_lseek, \
+ .read = seq_read, \
+ .release = single_release, \
+}
+
+DBGFS_FUNC_DECL(state);
+DBGFS_FUNC_DECL(chan_state);
+DBGFS_FUNC_DECL(descriptors);
+DBGFS_FUNC_DECL(requester_chan);
+
+static struct dentry *pxa_dma_dbg_alloc_chan(int ch, struct dentry *chandir)
+{
+ char chan_name[11];
+ struct dentry *chan, *chan_state = NULL, *chan_descr = NULL;
+ struct dentry *chan_reqs = NULL;
+ void *dt;
+
+ scnprintf(chan_name, sizeof(chan_name), "%d", ch);
+ chan = debugfs_create_dir(chan_name, chandir);
+ dt = (void *)ch;
+
+ if (chan)
+ chan_state = debugfs_create_file("state", 0400, chan, dt,
+ &dbg_fops_chan_state);
+ if (chan_state)
+ chan_descr = debugfs_create_file("descriptors", 0400, chan, dt,
+ &dbg_fops_descriptors);
+ if (chan_descr)
+ chan_reqs = debugfs_create_file("requesters", 0400, chan, dt,
+ &dbg_fops_requester_chan);
+ if (!chan_reqs)
+ goto err_state;
+
+ return chan;
+
+err_state:
+ debugfs_remove_recursive(chan);
+ return NULL;
+}
+
+static void pxa_dma_init_debugfs(void)
+{
+ int i;
+ struct dentry *chandir;
+
+ dbgfs_root = debugfs_create_dir(DMA_DEBUG_NAME, NULL);
+ if (IS_ERR(dbgfs_root) || !dbgfs_root)
+ goto err_root;
+
+ dbgfs_state = debugfs_create_file("state", 0400, dbgfs_root, NULL,
+ &dbg_fops_state);
+ if (!dbgfs_state)
+ goto err_state;
+
+ dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels,
+ GFP_KERNEL);
+ if (!dbgfs_chan)
+ goto err_alloc;
+
+ chandir = debugfs_create_dir("channels", dbgfs_root);
+ if (!chandir)
+ goto err_chandir;
+
+ for (i = 0; i < num_dma_channels; i++) {
+ dbgfs_chan[i] = pxa_dma_dbg_alloc_chan(i, chandir);
+ if (!dbgfs_chan[i])
+ goto err_chans;
+ }
+
+ return;
+err_chans:
+err_chandir:
+ kfree(dbgfs_chan);
+err_alloc:
+err_state:
+ debugfs_remove_recursive(dbgfs_root);
+err_root:
+ pr_err("pxa_dma: debugfs is not available\n");
+}
+
+static void __exit pxa_dma_cleanup_debugfs(void)
+{
+ debugfs_remove_recursive(dbgfs_root);
+}
+#else
+static inline void pxa_dma_init_debugfs(void) {}
+static inline void pxa_dma_cleanup_debugfs(void) {}
+#endif
+
+int pxa_request_dma (char *name, pxa_dma_prio prio,
+ void (*irq_handler)(int, void *),
+ void *data)
+{
+ unsigned long flags;
+ int i, found = 0;
+
+ /* basic sanity checks */
+ if (!name || !irq_handler)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ do {
+ /* try grabbing a DMA channel with the requested priority */
+ for (i = 0; i < num_dma_channels; i++) {
+ if ((dma_channels[i].prio == prio) &&
+ !dma_channels[i].name) {
+ found = 1;
+ break;
+ }
+ }
+ /* if requested prio group is full, try a hier priority */
+ } while (!found && prio--);
+
+ if (found) {
+ DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+ dma_channels[i].name = name;
+ dma_channels[i].irq_handler = irq_handler;
+ dma_channels[i].data = data;
+ } else {
+ printk (KERN_WARNING "No more available DMA channels for %s\n", name);
+ i = -ENODEV;
+ }
+
+ local_irq_restore(flags);
+ return i;
+}
+EXPORT_SYMBOL(pxa_request_dma);
+
+void pxa_free_dma (int dma_ch)
+{
+ unsigned long flags;
+
+ if (!dma_channels[dma_ch].name) {
+ printk (KERN_CRIT
+ "%s: trying to free channel %d which is already freed\n",
+ __func__, dma_ch);
+ return;
+ }
+
+ local_irq_save(flags);
+ DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+ dma_channels[dma_ch].name = NULL;
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(pxa_free_dma);
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+ int i, dint = DINT;
+ struct dma_channel *channel;
+
+ while (dint) {
+ i = __ffs(dint);
+ dint &= (dint - 1);
+ channel = &dma_channels[i];
+ if (channel->name && channel->irq_handler) {
+ channel->irq_handler(i, channel->data);
+ } else {
+ /*
+ * IRQ for an unregistered DMA channel:
+ * let's clear the interrupts and disable it.
+ */
+ printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
+ DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+int __init pxa_init_dma(int irq, int num_ch)
+{
+ int i, ret;
+
+ dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
+ if (dma_channels == NULL)
+ return -ENOMEM;
+
+ /* dma channel priorities on pxa2xx processors:
+ * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
+ * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
+ * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
+ */
+ for (i = 0; i < num_ch; i++) {
+ DCSR(i) = 0;
+ dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
+ spin_lock_init(&dma_channels[i].lock);
+ }
+
+ ret = request_irq(irq, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
+ if (ret) {
+ printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
+ kfree(dma_channels);
+ return ret;
+ }
+ num_dma_channels = num_ch;
+
+ pxa_dma_init_debugfs();
+
+ return 0;
+}
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c
new file mode 100644
index 00000000..a11dc367
--- /dev/null
+++ b/arch/arm/plat-pxa/gpio.c
@@ -0,0 +1,338 @@
+/*
+ * linux/arch/arm/plat-pxa/gpio.c
+ *
+ * Generic PXA GPIO handling
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+
+#include <mach/gpio.h>
+
+int pxa_last_gpio;
+
+struct pxa_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *regbase;
+ char label[10];
+
+ unsigned long irq_mask;
+ unsigned long irq_edge_rise;
+ unsigned long irq_edge_fall;
+
+#ifdef CONFIG_PM
+ unsigned long saved_gplr;
+ unsigned long saved_gpdr;
+ unsigned long saved_grer;
+ unsigned long saved_gfer;
+#endif
+};
+
+static DEFINE_SPINLOCK(gpio_lock);
+static struct pxa_gpio_chip *pxa_gpio_chips;
+
+#define for_each_gpio_chip(i, c) \
+ for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
+
+static inline void __iomem *gpio_chip_base(struct gpio_chip *c)
+{
+ return container_of(c, struct pxa_gpio_chip, chip)->regbase;
+}
+
+static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio)
+{
+ return &pxa_gpio_chips[gpio_to_bank(gpio)];
+}
+
+static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ void __iomem *base = gpio_chip_base(chip);
+ uint32_t value, mask = 1 << offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ value = __raw_readl(base + GPDR_OFFSET);
+ if (__gpio_is_inverted(chip->base + offset))
+ value |= mask;
+ else
+ value &= ~mask;
+ __raw_writel(value, base + GPDR_OFFSET);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ return 0;
+}
+
+static int pxa_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ void __iomem *base = gpio_chip_base(chip);
+ uint32_t tmp, mask = 1 << offset;
+ unsigned long flags;
+
+ __raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET));
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ tmp = __raw_readl(base + GPDR_OFFSET);
+ if (__gpio_is_inverted(chip->base + offset))
+ tmp &= ~mask;
+ else
+ tmp |= mask;
+ __raw_writel(tmp, base + GPDR_OFFSET);
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ return 0;
+}
+
+static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset);
+}
+
+static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ __raw_writel(1 << offset, gpio_chip_base(chip) +
+ (value ? GPSR_OFFSET : GPCR_OFFSET));
+}
+
+static int __init pxa_init_gpio_chip(int gpio_end)
+{
+ int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+ struct pxa_gpio_chip *chips;
+
+ chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
+ if (chips == NULL) {
+ pr_err("%s: failed to allocate GPIO chips\n", __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) {
+ struct gpio_chip *c = &chips[i].chip;
+
+ sprintf(chips[i].label, "gpio-%d", i);
+ chips[i].regbase = (void __iomem *)GPIO_BANK(i);
+
+ c->base = gpio;
+ c->label = chips[i].label;
+
+ c->direction_input = pxa_gpio_direction_input;
+ c->direction_output = pxa_gpio_direction_output;
+ c->get = pxa_gpio_get;
+ c->set = pxa_gpio_set;
+
+ /* number of GPIOs on last bank may be less than 32 */
+ c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32;
+ gpiochip_add(c);
+ }
+ pxa_gpio_chips = chips;
+ return 0;
+}
+
+/* Update only those GRERx and GFERx edge detection register bits if those
+ * bits are set in c->irq_mask
+ */
+static inline void update_edge_detect(struct pxa_gpio_chip *c)
+{
+ uint32_t grer, gfer;
+
+ grer = __raw_readl(c->regbase + GRER_OFFSET) & ~c->irq_mask;
+ gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~c->irq_mask;
+ grer |= c->irq_edge_rise & c->irq_mask;
+ gfer |= c->irq_edge_fall & c->irq_mask;
+ __raw_writel(grer, c->regbase + GRER_OFFSET);
+ __raw_writel(gfer, c->regbase + GFER_OFFSET);
+}
+
+static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type)
+{
+ struct pxa_gpio_chip *c;
+ int gpio = irq_to_gpio(d->irq);
+ unsigned long gpdr, mask = GPIO_bit(gpio);
+
+ c = gpio_to_pxachip(gpio);
+
+ if (type == IRQ_TYPE_PROBE) {
+ /* Don't mess with enabled GPIOs using preconfigured edges or
+ * GPIOs set to alternate function or to output during probe
+ */
+ if ((c->irq_edge_rise | c->irq_edge_fall) & GPIO_bit(gpio))
+ return 0;
+
+ if (__gpio_is_occupied(gpio))
+ return 0;
+
+ type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+ }
+
+ gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+
+ if (__gpio_is_inverted(gpio))
+ __raw_writel(gpdr | mask, c->regbase + GPDR_OFFSET);
+ else
+ __raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET);
+
+ if (type & IRQ_TYPE_EDGE_RISING)
+ c->irq_edge_rise |= mask;
+ else
+ c->irq_edge_rise &= ~mask;
+
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ c->irq_edge_fall |= mask;
+ else
+ c->irq_edge_fall &= ~mask;
+
+ update_edge_detect(c);
+
+ pr_debug("%s: IRQ%d (GPIO%d) - edge%s%s\n", __func__, d->irq, gpio,
+ ((type & IRQ_TYPE_EDGE_RISING) ? " rising" : ""),
+ ((type & IRQ_TYPE_EDGE_FALLING) ? " falling" : ""));
+ return 0;
+}
+
+static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct pxa_gpio_chip *c;
+ int loop, gpio, gpio_base, n;
+ unsigned long gedr;
+
+ do {
+ loop = 0;
+ for_each_gpio_chip(gpio, c) {
+ gpio_base = c->chip.base;
+
+ gedr = __raw_readl(c->regbase + GEDR_OFFSET);
+ gedr = gedr & c->irq_mask;
+ __raw_writel(gedr, c->regbase + GEDR_OFFSET);
+
+ n = find_first_bit(&gedr, BITS_PER_LONG);
+ while (n < BITS_PER_LONG) {
+ loop = 1;
+
+ generic_handle_irq(gpio_to_irq(gpio_base + n));
+ n = find_next_bit(&gedr, BITS_PER_LONG, n + 1);
+ }
+ }
+ } while (loop);
+}
+
+static void pxa_ack_muxed_gpio(struct irq_data *d)
+{
+ int gpio = irq_to_gpio(d->irq);
+ struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+
+ __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET);
+}
+
+static void pxa_mask_muxed_gpio(struct irq_data *d)
+{
+ int gpio = irq_to_gpio(d->irq);
+ struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+ uint32_t grer, gfer;
+
+ c->irq_mask &= ~GPIO_bit(gpio);
+
+ grer = __raw_readl(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio);
+ gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio);
+ __raw_writel(grer, c->regbase + GRER_OFFSET);
+ __raw_writel(gfer, c->regbase + GFER_OFFSET);
+}
+
+static void pxa_unmask_muxed_gpio(struct irq_data *d)
+{
+ int gpio = irq_to_gpio(d->irq);
+ struct pxa_gpio_chip *c = gpio_to_pxachip(gpio);
+
+ c->irq_mask |= GPIO_bit(gpio);
+ update_edge_detect(c);
+}
+
+static struct irq_chip pxa_muxed_gpio_chip = {
+ .name = "GPIO",
+ .irq_ack = pxa_ack_muxed_gpio,
+ .irq_mask = pxa_mask_muxed_gpio,
+ .irq_unmask = pxa_unmask_muxed_gpio,
+ .irq_set_type = pxa_gpio_irq_type,
+};
+
+void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
+{
+ struct pxa_gpio_chip *c;
+ int gpio, irq;
+
+ pxa_last_gpio = end;
+
+ /* Initialize GPIO chips */
+ pxa_init_gpio_chip(end);
+
+ /* clear all GPIO edge detects */
+ for_each_gpio_chip(gpio, c) {
+ __raw_writel(0, c->regbase + GFER_OFFSET);
+ __raw_writel(0, c->regbase + GRER_OFFSET);
+ __raw_writel(~0,c->regbase + GEDR_OFFSET);
+ }
+
+ for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) {
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+
+ /* Install handler for GPIO>=2 edge detect interrupts */
+ irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler);
+ pxa_muxed_gpio_chip.irq_set_wake = fn;
+}
+
+#ifdef CONFIG_PM
+static int pxa_gpio_suspend(void)
+{
+ struct pxa_gpio_chip *c;
+ int gpio;
+
+ for_each_gpio_chip(gpio, c) {
+ c->saved_gplr = __raw_readl(c->regbase + GPLR_OFFSET);
+ c->saved_gpdr = __raw_readl(c->regbase + GPDR_OFFSET);
+ c->saved_grer = __raw_readl(c->regbase + GRER_OFFSET);
+ c->saved_gfer = __raw_readl(c->regbase + GFER_OFFSET);
+
+ /* Clear GPIO transition detect bits */
+ __raw_writel(0xffffffff, c->regbase + GEDR_OFFSET);
+ }
+ return 0;
+}
+
+static void pxa_gpio_resume(void)
+{
+ struct pxa_gpio_chip *c;
+ int gpio;
+
+ for_each_gpio_chip(gpio, c) {
+ /* restore level with set/clear */
+ __raw_writel( c->saved_gplr, c->regbase + GPSR_OFFSET);
+ __raw_writel(~c->saved_gplr, c->regbase + GPCR_OFFSET);
+
+ __raw_writel(c->saved_grer, c->regbase + GRER_OFFSET);
+ __raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET);
+ __raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET);
+ }
+}
+#else
+#define pxa_gpio_suspend NULL
+#define pxa_gpio_resume NULL
+#endif
+
+struct syscore_ops pxa_gpio_syscore_ops = {
+ .suspend = pxa_gpio_suspend,
+ .resume = pxa_gpio_resume,
+};
diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h
new file mode 100644
index 00000000..a7b91dc0
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/dma.h
@@ -0,0 +1,85 @@
+#ifndef __PLAT_DMA_H
+#define __PLAT_DMA_H
+
+#define DMAC_REG(x) (*((volatile u32 *)(DMAC_REGS_VIRT + (x))))
+
+#define DCSR(n) DMAC_REG((n) << 2)
+#define DALGN DMAC_REG(0x00a0) /* DMA Alignment Register */
+#define DINT DMAC_REG(0x00f0) /* DMA Interrupt Register */
+#define DDADR(n) DMAC_REG(0x0200 + ((n) << 4))
+#define DSADR(n) DMAC_REG(0x0204 + ((n) << 4))
+#define DTADR(n) DMAC_REG(0x0208 + ((n) << 4))
+#define DCMD(n) DMAC_REG(0x020c + ((n) << 4))
+#define DRCMR(n) DMAC_REG((((n) < 64) ? 0x0100 : 0x1100) + \
+ (((n) & 0x3f) << 2))
+
+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN (1 << 28) /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN (1 << 27) /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN (1 << 26) /* STOP on an EOR */
+#define DCSR_SETCMPST (1 << 25) /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST (1 << 24) /* Clear Descriptor Compare Status */
+#define DCSR_CMPST (1 << 10) /* The Descriptor Compare Status */
+#define DCSR_EORINTR (1 << 9) /* The end of Receive */
+
+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
+#define DRCMR_CHLNUM 0x1f /* mask for Channel Number (read / write) */
+
+#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
+#define DDADR_STOP (1 << 0) /* Stop (read / write) */
+
+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
+
+/*
+ * Descriptor structure for PXA's DMA engine
+ * Note: this structure must always be aligned to a 16-byte boundary.
+ */
+
+typedef struct pxa_dma_desc {
+ volatile u32 ddadr; /* Points to the next descriptor + flags */
+ volatile u32 dsadr; /* DSADR value for the current transfer */
+ volatile u32 dtadr; /* DTADR value for the current transfer */
+ volatile u32 dcmd; /* DCMD value for the current transfer */
+} pxa_dma_desc;
+
+typedef enum {
+ DMA_PRIO_HIGH = 0,
+ DMA_PRIO_MEDIUM = 1,
+ DMA_PRIO_LOW = 2
+} pxa_dma_prio;
+
+/*
+ * DMA registration
+ */
+
+int __init pxa_init_dma(int irq, int num_ch);
+
+int pxa_request_dma (char *name,
+ pxa_dma_prio prio,
+ void (*irq_handler)(int, void *),
+ void *data);
+
+void pxa_free_dma (int dma_ch);
+
+#endif /* __PLAT_DMA_H */
diff --git a/arch/arm/plat-pxa/include/plat/gpio.h b/arch/arm/plat-pxa/include/plat/gpio.h
new file mode 100644
index 00000000..1ddd2b97
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/gpio.h
@@ -0,0 +1,64 @@
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+struct irq_data;
+
+/*
+ * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
+ * one set of registers. The register offsets are organized below:
+ *
+ * GPLR GPDR GPSR GPCR GRER GFER GEDR
+ * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048
+ * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C
+ * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050
+ *
+ * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148
+ * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C
+ * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150
+ *
+ * NOTE:
+ * BANK 3 is only available on PXA27x and later processors.
+ * BANK 4 and 5 are only available on PXA935
+ */
+
+#define GPIO_BANK(n) (GPIO_REGS_VIRT + BANK_OFF(n))
+
+#define GPLR_OFFSET 0x00
+#define GPDR_OFFSET 0x0C
+#define GPSR_OFFSET 0x18
+#define GPCR_OFFSET 0x24
+#define GRER_OFFSET 0x30
+#define GFER_OFFSET 0x3C
+#define GEDR_OFFSET 0x48
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
+ return GPLR(gpio) & GPIO_bit(gpio);
+ else
+ return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
+ if (value)
+ GPSR(gpio) = GPIO_bit(gpio);
+ else
+ GPCR(gpio) = GPIO_bit(gpio);
+ } else
+ __gpio_set_value(gpio, value);
+}
+
+#define gpio_cansleep __gpio_cansleep
+
+/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
+ * Those cases currently cause holes in the GPIO number space, the
+ * actual number of the last GPIO is recorded by 'pxa_last_gpio'.
+ */
+extern int pxa_last_gpio;
+
+typedef int (*set_wake_t)(struct irq_data *d, unsigned int on);
+
+extern void pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn);
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-pxa/include/plat/mfp.h b/arch/arm/plat-pxa/include/plat/mfp.h
new file mode 100644
index 00000000..89e68e07
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/mfp.h
@@ -0,0 +1,475 @@
+/*
+ * arch/arm/plat-pxa/include/plat/mfp.h
+ *
+ * Common Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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_MFP_H
+#define __ASM_PLAT_MFP_H
+
+#define mfp_to_gpio(m) ((m) % 256)
+
+/* list of all the configurable MFP pins */
+enum {
+ MFP_PIN_INVALID = -1,
+
+ MFP_PIN_GPIO0 = 0,
+ MFP_PIN_GPIO1,
+ MFP_PIN_GPIO2,
+ MFP_PIN_GPIO3,
+ MFP_PIN_GPIO4,
+ MFP_PIN_GPIO5,
+ MFP_PIN_GPIO6,
+ MFP_PIN_GPIO7,
+ MFP_PIN_GPIO8,
+ MFP_PIN_GPIO9,
+ MFP_PIN_GPIO10,
+ MFP_PIN_GPIO11,
+ MFP_PIN_GPIO12,
+ MFP_PIN_GPIO13,
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO16,
+ MFP_PIN_GPIO17,
+ MFP_PIN_GPIO18,
+ MFP_PIN_GPIO19,
+ MFP_PIN_GPIO20,
+ MFP_PIN_GPIO21,
+ MFP_PIN_GPIO22,
+ MFP_PIN_GPIO23,
+ MFP_PIN_GPIO24,
+ MFP_PIN_GPIO25,
+ MFP_PIN_GPIO26,
+ MFP_PIN_GPIO27,
+ MFP_PIN_GPIO28,
+ MFP_PIN_GPIO29,
+ MFP_PIN_GPIO30,
+ MFP_PIN_GPIO31,
+ MFP_PIN_GPIO32,
+ MFP_PIN_GPIO33,
+ MFP_PIN_GPIO34,
+ MFP_PIN_GPIO35,
+ MFP_PIN_GPIO36,
+ MFP_PIN_GPIO37,
+ MFP_PIN_GPIO38,
+ MFP_PIN_GPIO39,
+ MFP_PIN_GPIO40,
+ MFP_PIN_GPIO41,
+ MFP_PIN_GPIO42,
+ MFP_PIN_GPIO43,
+ MFP_PIN_GPIO44,
+ MFP_PIN_GPIO45,
+ MFP_PIN_GPIO46,
+ MFP_PIN_GPIO47,
+ MFP_PIN_GPIO48,
+ MFP_PIN_GPIO49,
+ MFP_PIN_GPIO50,
+ MFP_PIN_GPIO51,
+ MFP_PIN_GPIO52,
+ MFP_PIN_GPIO53,
+ MFP_PIN_GPIO54,
+ MFP_PIN_GPIO55,
+ MFP_PIN_GPIO56,
+ MFP_PIN_GPIO57,
+ MFP_PIN_GPIO58,
+ MFP_PIN_GPIO59,
+ MFP_PIN_GPIO60,
+ MFP_PIN_GPIO61,
+ MFP_PIN_GPIO62,
+ MFP_PIN_GPIO63,
+ MFP_PIN_GPIO64,
+ MFP_PIN_GPIO65,
+ MFP_PIN_GPIO66,
+ MFP_PIN_GPIO67,
+ MFP_PIN_GPIO68,
+ MFP_PIN_GPIO69,
+ MFP_PIN_GPIO70,
+ MFP_PIN_GPIO71,
+ MFP_PIN_GPIO72,
+ MFP_PIN_GPIO73,
+ MFP_PIN_GPIO74,
+ MFP_PIN_GPIO75,
+ MFP_PIN_GPIO76,
+ MFP_PIN_GPIO77,
+ MFP_PIN_GPIO78,
+ MFP_PIN_GPIO79,
+ MFP_PIN_GPIO80,
+ MFP_PIN_GPIO81,
+ MFP_PIN_GPIO82,
+ MFP_PIN_GPIO83,
+ MFP_PIN_GPIO84,
+ MFP_PIN_GPIO85,
+ MFP_PIN_GPIO86,
+ MFP_PIN_GPIO87,
+ MFP_PIN_GPIO88,
+ MFP_PIN_GPIO89,
+ MFP_PIN_GPIO90,
+ MFP_PIN_GPIO91,
+ MFP_PIN_GPIO92,
+ MFP_PIN_GPIO93,
+ MFP_PIN_GPIO94,
+ MFP_PIN_GPIO95,
+ MFP_PIN_GPIO96,
+ MFP_PIN_GPIO97,
+ MFP_PIN_GPIO98,
+ MFP_PIN_GPIO99,
+ MFP_PIN_GPIO100,
+ MFP_PIN_GPIO101,
+ MFP_PIN_GPIO102,
+ MFP_PIN_GPIO103,
+ MFP_PIN_GPIO104,
+ MFP_PIN_GPIO105,
+ MFP_PIN_GPIO106,
+ MFP_PIN_GPIO107,
+ MFP_PIN_GPIO108,
+ MFP_PIN_GPIO109,
+ MFP_PIN_GPIO110,
+ MFP_PIN_GPIO111,
+ MFP_PIN_GPIO112,
+ MFP_PIN_GPIO113,
+ MFP_PIN_GPIO114,
+ MFP_PIN_GPIO115,
+ MFP_PIN_GPIO116,
+ MFP_PIN_GPIO117,
+ MFP_PIN_GPIO118,
+ MFP_PIN_GPIO119,
+ MFP_PIN_GPIO120,
+ MFP_PIN_GPIO121,
+ MFP_PIN_GPIO122,
+ MFP_PIN_GPIO123,
+ MFP_PIN_GPIO124,
+ MFP_PIN_GPIO125,
+ MFP_PIN_GPIO126,
+ MFP_PIN_GPIO127,
+
+ MFP_PIN_GPIO128,
+ MFP_PIN_GPIO129,
+ MFP_PIN_GPIO130,
+ MFP_PIN_GPIO131,
+ MFP_PIN_GPIO132,
+ MFP_PIN_GPIO133,
+ MFP_PIN_GPIO134,
+ MFP_PIN_GPIO135,
+ MFP_PIN_GPIO136,
+ MFP_PIN_GPIO137,
+ MFP_PIN_GPIO138,
+ MFP_PIN_GPIO139,
+ MFP_PIN_GPIO140,
+ MFP_PIN_GPIO141,
+ MFP_PIN_GPIO142,
+ MFP_PIN_GPIO143,
+ MFP_PIN_GPIO144,
+ MFP_PIN_GPIO145,
+ MFP_PIN_GPIO146,
+ MFP_PIN_GPIO147,
+ MFP_PIN_GPIO148,
+ MFP_PIN_GPIO149,
+ MFP_PIN_GPIO150,
+ MFP_PIN_GPIO151,
+ MFP_PIN_GPIO152,
+ MFP_PIN_GPIO153,
+ MFP_PIN_GPIO154,
+ MFP_PIN_GPIO155,
+ MFP_PIN_GPIO156,
+ MFP_PIN_GPIO157,
+ MFP_PIN_GPIO158,
+ MFP_PIN_GPIO159,
+ MFP_PIN_GPIO160,
+ MFP_PIN_GPIO161,
+ MFP_PIN_GPIO162,
+ MFP_PIN_GPIO163,
+ MFP_PIN_GPIO164,
+ MFP_PIN_GPIO165,
+ MFP_PIN_GPIO166,
+ MFP_PIN_GPIO167,
+ MFP_PIN_GPIO168,
+ MFP_PIN_GPIO169,
+ MFP_PIN_GPIO170,
+ MFP_PIN_GPIO171,
+ MFP_PIN_GPIO172,
+ MFP_PIN_GPIO173,
+ MFP_PIN_GPIO174,
+ MFP_PIN_GPIO175,
+ MFP_PIN_GPIO176,
+ MFP_PIN_GPIO177,
+ MFP_PIN_GPIO178,
+ MFP_PIN_GPIO179,
+ MFP_PIN_GPIO180,
+ MFP_PIN_GPIO181,
+ MFP_PIN_GPIO182,
+ MFP_PIN_GPIO183,
+ MFP_PIN_GPIO184,
+ MFP_PIN_GPIO185,
+ MFP_PIN_GPIO186,
+ MFP_PIN_GPIO187,
+ MFP_PIN_GPIO188,
+ MFP_PIN_GPIO189,
+ MFP_PIN_GPIO190,
+ MFP_PIN_GPIO191,
+
+ MFP_PIN_GPIO255 = 255,
+
+ MFP_PIN_GPIO0_2,
+ MFP_PIN_GPIO1_2,
+ MFP_PIN_GPIO2_2,
+ MFP_PIN_GPIO3_2,
+ MFP_PIN_GPIO4_2,
+ MFP_PIN_GPIO5_2,
+ MFP_PIN_GPIO6_2,
+ MFP_PIN_GPIO7_2,
+ MFP_PIN_GPIO8_2,
+ MFP_PIN_GPIO9_2,
+ MFP_PIN_GPIO10_2,
+ MFP_PIN_GPIO11_2,
+ MFP_PIN_GPIO12_2,
+ MFP_PIN_GPIO13_2,
+ MFP_PIN_GPIO14_2,
+ MFP_PIN_GPIO15_2,
+ MFP_PIN_GPIO16_2,
+ MFP_PIN_GPIO17_2,
+
+ MFP_PIN_ULPI_STP,
+ MFP_PIN_ULPI_NXT,
+ MFP_PIN_ULPI_DIR,
+
+ MFP_PIN_nXCVREN,
+ MFP_PIN_DF_CLE_nOE,
+ MFP_PIN_DF_nADV1_ALE,
+ MFP_PIN_DF_SCLK_E,
+ MFP_PIN_DF_SCLK_S,
+ MFP_PIN_nBE0,
+ MFP_PIN_nBE1,
+ MFP_PIN_DF_nADV2_ALE,
+ MFP_PIN_DF_INT_RnB,
+ MFP_PIN_DF_nCS0,
+ MFP_PIN_DF_nCS1,
+ MFP_PIN_nLUA,
+ MFP_PIN_nLLA,
+ MFP_PIN_DF_nWE,
+ MFP_PIN_DF_ALE_nWE,
+ MFP_PIN_DF_nRE_nOE,
+ MFP_PIN_DF_ADDR0,
+ MFP_PIN_DF_ADDR1,
+ MFP_PIN_DF_ADDR2,
+ MFP_PIN_DF_ADDR3,
+ MFP_PIN_DF_IO0,
+ MFP_PIN_DF_IO1,
+ MFP_PIN_DF_IO2,
+ MFP_PIN_DF_IO3,
+ MFP_PIN_DF_IO4,
+ MFP_PIN_DF_IO5,
+ MFP_PIN_DF_IO6,
+ MFP_PIN_DF_IO7,
+ MFP_PIN_DF_IO8,
+ MFP_PIN_DF_IO9,
+ MFP_PIN_DF_IO10,
+ MFP_PIN_DF_IO11,
+ MFP_PIN_DF_IO12,
+ MFP_PIN_DF_IO13,
+ MFP_PIN_DF_IO14,
+ MFP_PIN_DF_IO15,
+ MFP_PIN_DF_nCS0_SM_nCS2,
+ MFP_PIN_DF_nCS1_SM_nCS3,
+ MFP_PIN_SM_nCS0,
+ MFP_PIN_SM_nCS1,
+ MFP_PIN_DF_WEn,
+ MFP_PIN_DF_REn,
+ MFP_PIN_DF_CLE_SM_OEn,
+ MFP_PIN_DF_ALE_SM_WEn,
+ MFP_PIN_DF_RDY0,
+ MFP_PIN_DF_RDY1,
+
+ MFP_PIN_SM_SCLK,
+ MFP_PIN_SM_BE0,
+ MFP_PIN_SM_BE1,
+ MFP_PIN_SM_ADV,
+ MFP_PIN_SM_ADVMUX,
+ MFP_PIN_SM_RDY,
+
+ MFP_PIN_MMC1_DAT7,
+ MFP_PIN_MMC1_DAT6,
+ MFP_PIN_MMC1_DAT5,
+ MFP_PIN_MMC1_DAT4,
+ MFP_PIN_MMC1_DAT3,
+ MFP_PIN_MMC1_DAT2,
+ MFP_PIN_MMC1_DAT1,
+ MFP_PIN_MMC1_DAT0,
+ MFP_PIN_MMC1_CMD,
+ MFP_PIN_MMC1_CLK,
+ MFP_PIN_MMC1_CD,
+ MFP_PIN_MMC1_WP,
+
+ /* additional pins on PXA930 */
+ MFP_PIN_GSIM_UIO,
+ MFP_PIN_GSIM_UCLK,
+ MFP_PIN_GSIM_UDET,
+ MFP_PIN_GSIM_nURST,
+ MFP_PIN_PMIC_INT,
+ MFP_PIN_RDY,
+
+ /* additional pins on MMP2 */
+ MFP_PIN_TWSI1_SCL,
+ MFP_PIN_TWSI1_SDA,
+ MFP_PIN_TWSI4_SCL,
+ MFP_PIN_TWSI4_SDA,
+ MFP_PIN_CLK_REQ,
+
+ MFP_PIN_MAX,
+};
+
+/*
+ * a possible MFP configuration is represented by a 32-bit integer
+ *
+ * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum)
+ * bit 10..12 - Alternate Function Selection
+ * bit 13..15 - Drive Strength
+ * bit 16..18 - Low Power Mode State
+ * bit 19..20 - Low Power Mode Edge Detection
+ * bit 21..22 - Run Mode Pull State
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * MFP_CFG_DEFAULT - default MFP configuration value, with
+ * alternate function = 0,
+ * drive strength = fast 3mA (MFP_DS03X)
+ * low power mode = default
+ * edge detection = none
+ *
+ * MFP_CFG - default MFPR value with alternate function
+ * MFP_CFG_DRV - default MFPR value with alternate function and
+ * pin drive strength
+ * MFP_CFG_LPM - default MFPR value with alternate function and
+ * low power mode
+ * MFP_CFG_X - default MFPR value with alternate function,
+ * pin drive strength and low power mode
+ */
+
+typedef unsigned long mfp_cfg_t;
+
+#define MFP_PIN(x) ((x) & 0x3ff)
+
+#define MFP_AF0 (0x0 << 10)
+#define MFP_AF1 (0x1 << 10)
+#define MFP_AF2 (0x2 << 10)
+#define MFP_AF3 (0x3 << 10)
+#define MFP_AF4 (0x4 << 10)
+#define MFP_AF5 (0x5 << 10)
+#define MFP_AF6 (0x6 << 10)
+#define MFP_AF7 (0x7 << 10)
+#define MFP_AF_MASK (0x7 << 10)
+#define MFP_AF(x) (((x) >> 10) & 0x7)
+
+#define MFP_DS01X (0x0 << 13)
+#define MFP_DS02X (0x1 << 13)
+#define MFP_DS03X (0x2 << 13)
+#define MFP_DS04X (0x3 << 13)
+#define MFP_DS06X (0x4 << 13)
+#define MFP_DS08X (0x5 << 13)
+#define MFP_DS10X (0x6 << 13)
+#define MFP_DS13X (0x7 << 13)
+#define MFP_DS_MASK (0x7 << 13)
+#define MFP_DS(x) (((x) >> 13) & 0x7)
+
+#define MFP_LPM_DEFAULT (0x0 << 16)
+#define MFP_LPM_DRIVE_LOW (0x1 << 16)
+#define MFP_LPM_DRIVE_HIGH (0x2 << 16)
+#define MFP_LPM_PULL_LOW (0x3 << 16)
+#define MFP_LPM_PULL_HIGH (0x4 << 16)
+#define MFP_LPM_FLOAT (0x5 << 16)
+#define MFP_LPM_INPUT (0x6 << 16)
+#define MFP_LPM_STATE_MASK (0x7 << 16)
+#define MFP_LPM_STATE(x) (((x) >> 16) & 0x7)
+
+#define MFP_LPM_EDGE_NONE (0x0 << 19)
+#define MFP_LPM_EDGE_RISE (0x1 << 19)
+#define MFP_LPM_EDGE_FALL (0x2 << 19)
+#define MFP_LPM_EDGE_BOTH (0x3 << 19)
+#define MFP_LPM_EDGE_MASK (0x3 << 19)
+#define MFP_LPM_EDGE(x) (((x) >> 19) & 0x3)
+
+#define MFP_PULL_NONE (0x0 << 21)
+#define MFP_PULL_LOW (0x1 << 21)
+#define MFP_PULL_HIGH (0x2 << 21)
+#define MFP_PULL_BOTH (0x3 << 21)
+#define MFP_PULL_FLOAT (0x4 << 21)
+#define MFP_PULL_MASK (0x7 << 21)
+#define MFP_PULL(x) (((x) >> 21) & 0x7)
+
+#define MFP_CFG_DEFAULT (MFP_AF0 | MFP_DS03X | MFP_LPM_DEFAULT |\
+ MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
+
+#define MFP_CFG(pin, af) \
+ ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
+
+#define MFP_CFG_LPM(pin, af, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
+
+#define MFP_CFG_X(pin, af, drv, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x) || defined(CONFIG_ARCH_MMP)
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by mfp_init()
+ *
+ * mfp_init_base() - accepts a virtual base for all MFPR registers and
+ * initialize the MFP table to a default state
+ *
+ * mfp_init_addr() - accepts a table of "mfp_addr_map" structure, which
+ * represents a range of MFP pins from "start" to "end", with the offset
+ * beginning at "offset", to define a single pin, let "end" = -1.
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR() to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct mfp_addr_map {
+ unsigned int start;
+ unsigned int end;
+ unsigned long offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+ { MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+ { MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
+
+void __init mfp_init_base(unsigned long mfpr_base);
+void __init mfp_init_addr(struct mfp_addr_map *map);
+
+/*
+ * mfp_{read, write}() - for direct read/write access to the MFPR register
+ * mfp_config() - for configuring a group of MFPR registers
+ * mfp_config_lpm() - configuring all low power MFPR registers for suspend
+ * mfp_config_run() - configuring all run time MFPR registers after resume
+ */
+unsigned long mfp_read(int mfp);
+void mfp_write(int mfp, unsigned long mfpr_val);
+void mfp_config(unsigned long *mfp_cfgs, int num);
+void mfp_config_run(void);
+void mfp_config_lpm(void);
+#endif /* CONFIG_PXA3xx || CONFIG_PXA95x || CONFIG_ARCH_MMP */
+
+#endif /* __ASM_PLAT_MFP_H */
diff --git a/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
new file mode 100644
index 00000000..abcc36eb
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/pxa27x_keypad.h
@@ -0,0 +1,69 @@
+#ifndef __ASM_ARCH_PXA27x_KEYPAD_H
+#define __ASM_ARCH_PXA27x_KEYPAD_H
+
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+
+#define MAX_MATRIX_KEY_ROWS (8)
+#define MAX_MATRIX_KEY_COLS (8)
+#define MATRIX_ROW_SHIFT (3)
+#define MAX_DIRECT_KEY_NUM (8)
+
+/* pxa3xx keypad platform specific parameters
+ *
+ * NOTE:
+ * 1. direct_key_num indicates the number of keys in the direct keypad
+ * _plus_ the number of rotary-encoder sensor inputs, this can be
+ * left as 0 if only rotary encoders are enabled, the driver will
+ * automatically calculate this
+ *
+ * 2. direct_key_map is the key code map for the direct keys, if rotary
+ * encoder(s) are enabled, direct key 0/1(2/3) will be ignored
+ *
+ * 3. rotary can be either interpreted as a relative input event (e.g.
+ * REL_WHEEL/REL_HWHEEL) or specific keys (e.g. UP/DOWN/LEFT/RIGHT)
+ *
+ * 4. matrix key and direct key will use the same debounce_interval by
+ * default, which should be sufficient in most cases
+ *
+ * pxa168 keypad platform specific parameter
+ *
+ * NOTE:
+ * clear_wakeup_event callback is a workaround required to clear the
+ * keypad interrupt. The keypad wake must be cleared in addition to
+ * reading the MI/DI bits in the KPC register.
+ */
+struct pxa27x_keypad_platform_data {
+
+ /* code map for the matrix keys */
+ unsigned int matrix_key_rows;
+ unsigned int matrix_key_cols;
+ unsigned int *matrix_key_map;
+ int matrix_key_map_size;
+
+ /* direct keys */
+ int direct_key_num;
+ unsigned int direct_key_map[MAX_DIRECT_KEY_NUM];
+
+ /* rotary encoders 0 */
+ int enable_rotary0;
+ int rotary0_rel_code;
+ int rotary0_up_key;
+ int rotary0_down_key;
+
+ /* rotary encoders 1 */
+ int enable_rotary1;
+ int rotary1_rel_code;
+ int rotary1_up_key;
+ int rotary1_down_key;
+
+ /* key debounce interval */
+ unsigned int debounce_interval;
+
+ /* clear wakeup event requirement for pxa168 */
+ void (*clear_wakeup_event)(void);
+};
+
+extern void pxa_set_keypad_info(struct pxa27x_keypad_platform_data *info);
+
+#endif /* __ASM_ARCH_PXA27x_KEYPAD_H */
diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
new file mode 100644
index 00000000..442301fe
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
@@ -0,0 +1,63 @@
+#ifndef __ASM_ARCH_PXA3XX_NAND_H
+#define __ASM_ARCH_PXA3XX_NAND_H
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+struct pxa3xx_nand_timing {
+ unsigned int tCH; /* Enable signal hold time */
+ unsigned int tCS; /* Enable signal setup time */
+ unsigned int tWH; /* ND_nWE high duration */
+ unsigned int tWP; /* ND_nWE pulse time */
+ unsigned int tRH; /* ND_nRE high duration */
+ unsigned int tRP; /* ND_nRE pulse width */
+ unsigned int tR; /* ND_nWE high to ND_nRE low for read */
+ unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */
+ unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
+};
+
+struct pxa3xx_nand_cmdset {
+ uint16_t read1;
+ uint16_t read2;
+ uint16_t program;
+ uint16_t read_status;
+ uint16_t read_id;
+ uint16_t erase;
+ uint16_t reset;
+ uint16_t lock;
+ uint16_t unlock;
+ uint16_t lock_status;
+};
+
+struct pxa3xx_nand_flash {
+ char *name;
+ uint32_t chip_id;
+ unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */
+ unsigned int page_size; /* Page size in bytes (PAGE_SZ) */
+ unsigned int flash_width; /* Width of Flash memory (DWIDTH_M) */
+ unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */
+ unsigned int num_blocks; /* Number of physical blocks in Flash */
+
+ struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
+};
+
+struct pxa3xx_nand_platform_data {
+
+ /* the data flash bus is shared between the Static Memory
+ * Controller and the Data Flash Controller, the arbiter
+ * controls the ownership of the bus
+ */
+ int enable_arbiter;
+
+ /* allow platform code to keep OBM/bootloader defined NFC config */
+ int keep_config;
+
+ const struct mtd_partition *parts;
+ unsigned int nr_parts;
+
+ const struct pxa3xx_nand_flash * flash;
+ size_t num_flash;
+};
+
+extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
+#endif /* __ASM_ARCH_PXA3XX_NAND_H */
diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h
new file mode 100644
index 00000000..1ab332e3
--- /dev/null
+++ b/arch/arm/plat-pxa/include/plat/sdhci.h
@@ -0,0 +1,35 @@
+/* linux/arch/arm/plat-pxa/include/plat/sdhci.h
+ *
+ * Copyright 2010 Marvell
+ * Zhangfei Gao <zhangfei.gao@marvell.com>
+ *
+ * PXA Platform - SDHCI platform data definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PLAT_PXA_SDHCI_H
+#define __PLAT_PXA_SDHCI_H
+
+/* pxa specific flag */
+/* Require clock free running */
+#define PXA_FLAG_DISABLE_CLOCK_GATING (1<<0)
+
+/* Board design supports 8-bit data on SD/SDIO BUS */
+#define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (1<<2)
+
+/*
+ * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI
+ * @max_speed: the maximum speed supported
+ * @quirks: quirks of specific device
+ * @flags: flags for platform requirement
+ */
+struct sdhci_pxa_platdata {
+ unsigned int max_speed;
+ unsigned int quirks;
+ unsigned int flags;
+};
+
+#endif /* __PLAT_PXA_SDHCI_H */
diff --git a/arch/arm/plat-pxa/mfp.c b/arch/arm/plat-pxa/mfp.c
new file mode 100644
index 00000000..be12eadc
--- /dev/null
+++ b/arch/arm/plat-pxa/mfp.c
@@ -0,0 +1,285 @@
+/*
+ * linux/arch/arm/plat-pxa/mfp.c
+ *
+ * Multi-Function Pin Support
+ *
+ * Copyright (C) 2007 Marvell Internation Ltd.
+ *
+ * 2007-08-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can 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 <plat/mfp.h>
+
+#define MFPR_SIZE (PAGE_SIZE)
+
+/* MFPR register bit definitions */
+#define MFPR_PULL_SEL (0x1 << 15)
+#define MFPR_PULLUP_EN (0x1 << 14)
+#define MFPR_PULLDOWN_EN (0x1 << 13)
+#define MFPR_SLEEP_SEL (0x1 << 9)
+#define MFPR_SLEEP_OE_N (0x1 << 7)
+#define MFPR_EDGE_CLEAR (0x1 << 6)
+#define MFPR_EDGE_FALL_EN (0x1 << 5)
+#define MFPR_EDGE_RISE_EN (0x1 << 4)
+
+#define MFPR_SLEEP_DATA(x) ((x) << 8)
+#define MFPR_DRIVE(x) (((x) & 0x7) << 10)
+#define MFPR_AF_SEL(x) (((x) & 0x7) << 0)
+
+#define MFPR_EDGE_NONE (0)
+#define MFPR_EDGE_RISE (MFPR_EDGE_RISE_EN)
+#define MFPR_EDGE_FALL (MFPR_EDGE_FALL_EN)
+#define MFPR_EDGE_BOTH (MFPR_EDGE_RISE | MFPR_EDGE_FALL)
+
+/*
+ * Table that determines the low power modes outputs, with actual settings
+ * used in parentheses for don't-care values. Except for the float output,
+ * the configured driven and pulled levels match, so if there is a need for
+ * non-LPM pulled output, the same configuration could probably be used.
+ *
+ * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel
+ * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15)
+ *
+ * Input 0 X(0) X(0) X(0) 0
+ * Drive 0 0 0 0 X(1) 0
+ * Drive 1 0 1 X(1) 0 0
+ * Pull hi (1) 1 X(1) 1 0 0
+ * Pull lo (0) 1 X(0) 0 1 0
+ * Z (float) 1 X(0) 0 0 0
+ */
+#define MFPR_LPM_INPUT (0)
+#define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN)
+#define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN)
+#define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N)
+#define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N)
+#define MFPR_LPM_MASK (0xe080)
+
+/*
+ * The pullup and pulldown state of the MFP pin at run mode is by default
+ * determined by the selected alternate function. In case that some buggy
+ * devices need to override this default behavior, the definitions below
+ * indicates the setting of corresponding MFPR bits
+ *
+ * Definition pull_sel pullup_en pulldown_en
+ * MFPR_PULL_NONE 0 0 0
+ * MFPR_PULL_LOW 1 0 1
+ * MFPR_PULL_HIGH 1 1 0
+ * MFPR_PULL_BOTH 1 1 1
+ * MFPR_PULL_FLOAT 1 0 0
+ */
+#define MFPR_PULL_NONE (0)
+#define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN)
+#define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN)
+#define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN)
+#define MFPR_PULL_FLOAT (MFPR_PULL_SEL)
+
+/* mfp_spin_lock is used to ensure that MFP register configuration
+ * (most likely a read-modify-write operation) is atomic, and that
+ * mfp_table[] is consistent
+ */
+static DEFINE_SPINLOCK(mfp_spin_lock);
+
+static void __iomem *mfpr_mmio_base;
+
+struct mfp_pin {
+ unsigned long config; /* -1 for not configured */
+ unsigned long mfpr_off; /* MFPRxx Register offset */
+ unsigned long mfpr_run; /* Run-Mode Register Value */
+ unsigned long mfpr_lpm; /* Low Power Mode Register Value */
+};
+
+static struct mfp_pin mfp_table[MFP_PIN_MAX];
+
+/* mapping of MFP_LPM_* definitions to MFPR_LPM_* register bits */
+static const unsigned long mfpr_lpm[] = {
+ MFPR_LPM_INPUT,
+ MFPR_LPM_DRIVE_LOW,
+ MFPR_LPM_DRIVE_HIGH,
+ MFPR_LPM_PULL_LOW,
+ MFPR_LPM_PULL_HIGH,
+ MFPR_LPM_FLOAT,
+ MFPR_LPM_INPUT,
+};
+
+/* mapping of MFP_PULL_* definitions to MFPR_PULL_* register bits */
+static const unsigned long mfpr_pull[] = {
+ MFPR_PULL_NONE,
+ MFPR_PULL_LOW,
+ MFPR_PULL_HIGH,
+ MFPR_PULL_BOTH,
+ MFPR_PULL_FLOAT,
+};
+
+/* mapping of MFP_LPM_EDGE_* definitions to MFPR_EDGE_* register bits */
+static const unsigned long mfpr_edge[] = {
+ MFPR_EDGE_NONE,
+ MFPR_EDGE_RISE,
+ MFPR_EDGE_FALL,
+ MFPR_EDGE_BOTH,
+};
+
+#define mfpr_readl(off) \
+ __raw_readl(mfpr_mmio_base + (off))
+
+#define mfpr_writel(off, val) \
+ __raw_writel(val, mfpr_mmio_base + (off))
+
+#define mfp_configured(p) ((p)->config != -1)
+
+/*
+ * perform a read-back of any valid MFPR register to make sure the
+ * previous writings are finished
+ */
+static unsigned long mfpr_off_readback;
+#define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + mfpr_off_readback)
+
+static inline void __mfp_config_run(struct mfp_pin *p)
+{
+ if (mfp_configured(p))
+ mfpr_writel(p->mfpr_off, p->mfpr_run);
+}
+
+static inline void __mfp_config_lpm(struct mfp_pin *p)
+{
+ if (mfp_configured(p)) {
+ unsigned long mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR;
+ if (mfpr_clr != p->mfpr_run)
+ mfpr_writel(p->mfpr_off, mfpr_clr);
+ if (p->mfpr_lpm != mfpr_clr)
+ mfpr_writel(p->mfpr_off, p->mfpr_lpm);
+ }
+}
+
+void mfp_config(unsigned long *mfp_cfgs, int num)
+{
+ unsigned long flags;
+ int i;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ for (i = 0; i < num; i++, mfp_cfgs++) {
+ unsigned long tmp, c = *mfp_cfgs;
+ struct mfp_pin *p;
+ int pin, af, drv, lpm, edge, pull;
+
+ pin = MFP_PIN(c);
+ BUG_ON(pin >= MFP_PIN_MAX);
+ p = &mfp_table[pin];
+
+ af = MFP_AF(c);
+ drv = MFP_DS(c);
+ lpm = MFP_LPM_STATE(c);
+ edge = MFP_LPM_EDGE(c);
+ pull = MFP_PULL(c);
+
+ /* run-mode pull settings will conflict with MFPR bits of
+ * low power mode state, calculate mfpr_run and mfpr_lpm
+ * individually if pull != MFP_PULL_NONE
+ */
+ tmp = MFPR_AF_SEL(af) | MFPR_DRIVE(drv);
+
+ if (likely(pull == MFP_PULL_NONE)) {
+ p->mfpr_run = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+ p->mfpr_lpm = p->mfpr_run;
+ } else {
+ p->mfpr_lpm = tmp | mfpr_lpm[lpm] | mfpr_edge[edge];
+ p->mfpr_run = tmp | mfpr_pull[pull];
+ }
+
+ p->config = c; __mfp_config_run(p);
+ }
+
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+unsigned long mfp_read(int mfp)
+{
+ unsigned long val, flags;
+
+ BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ val = mfpr_readl(mfp_table[mfp].mfpr_off);
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+
+ return val;
+}
+
+void mfp_write(int mfp, unsigned long val)
+{
+ unsigned long flags;
+
+ BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+ mfpr_writel(mfp_table[mfp].mfpr_off, val);
+ mfpr_sync();
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void __init mfp_init_base(unsigned long mfpr_base)
+{
+ int i;
+
+ /* initialize the table with default - unconfigured */
+ for (i = 0; i < ARRAY_SIZE(mfp_table); i++)
+ mfp_table[i].config = -1;
+
+ mfpr_mmio_base = (void __iomem *)mfpr_base;
+}
+
+void __init mfp_init_addr(struct mfp_addr_map *map)
+{
+ struct mfp_addr_map *p;
+ unsigned long offset, flags;
+ int i;
+
+ spin_lock_irqsave(&mfp_spin_lock, flags);
+
+ /* mfp offset for readback */
+ mfpr_off_readback = map[0].offset;
+
+ for (p = map; p->start != MFP_PIN_INVALID; p++) {
+ offset = p->offset;
+ i = p->start;
+
+ do {
+ mfp_table[i].mfpr_off = offset;
+ mfp_table[i].mfpr_run = 0;
+ mfp_table[i].mfpr_lpm = 0;
+ offset += 4; i++;
+ } while ((i <= p->end) && (p->end != -1));
+ }
+
+ spin_unlock_irqrestore(&mfp_spin_lock, flags);
+}
+
+void mfp_config_lpm(void)
+{
+ struct mfp_pin *p = &mfp_table[0];
+ int pin;
+
+ for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+ __mfp_config_lpm(p);
+}
+
+void mfp_config_run(void)
+{
+ struct mfp_pin *p = &mfp_table[0];
+ int pin;
+
+ for (pin = 0; pin < ARRAY_SIZE(mfp_table); pin++, p++)
+ __mfp_config_run(p);
+}
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
new file mode 100644
index 00000000..ef32686f
--- /dev/null
+++ b/arch/arm/plat-pxa/pwm.c
@@ -0,0 +1,304 @@
+/*
+ * linux/arch/arm/mach-pxa/pwm.c
+ *
+ * simple driver for PWM (Pulse Width Modulator) 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.
+ *
+ * 2008-02-13 initial version
+ * eric miao <eric.miao@marvell.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <asm/div64.h>
+
+#define HAS_SECONDARY_PWM 0x10
+#define PWM_ID_BASE(d) ((d) & 0xf)
+
+static const struct platform_device_id pwm_id_table[] = {
+ /* PWM has_secondary_pwm? */
+ { "pxa25x-pwm", 0 },
+ { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
+ { "pxa168-pwm", 1 },
+ { "pxa910-pwm", 1 },
+ { },
+};
+MODULE_DEVICE_TABLE(platform, pwm_id_table);
+
+/* PWM registers and bits definitions */
+#define PWMCR (0x00)
+#define PWMDCR (0x04)
+#define PWMPCR (0x08)
+
+#define PWMCR_SD (1 << 6)
+#define PWMDCR_FD (1 << 10)
+
+struct pwm_device {
+ struct list_head node;
+ struct pwm_device *secondary;
+ struct platform_device *pdev;
+
+ const char *label;
+ struct clk *clk;
+ int clk_enabled;
+ void __iomem *mmio_base;
+
+ unsigned int use_count;
+ unsigned int pwm_id;
+};
+
+/*
+ * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
+ * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+ */
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long long c;
+ unsigned long period_cycles, prescale, pv, dc;
+
+ if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+ return -EINVAL;
+
+ c = clk_get_rate(pwm->clk);
+ c = c * period_ns;
+ do_div(c, 1000000000);
+ period_cycles = c;
+
+ if (period_cycles < 1)
+ period_cycles = 1;
+ prescale = (period_cycles - 1) / 1024;
+ pv = period_cycles / (prescale + 1) - 1;
+
+ if (prescale > 63)
+ return -EINVAL;
+
+ if (duty_ns == period_ns)
+ dc = PWMDCR_FD;
+ else
+ dc = (pv + 1) * duty_ns / period_ns;
+
+ /* NOTE: the clock to PWM has to be enabled first
+ * before writing to the registers
+ */
+ clk_enable(pwm->clk);
+ __raw_writel(prescale, pwm->mmio_base + PWMCR);
+ __raw_writel(dc, pwm->mmio_base + PWMDCR);
+ __raw_writel(pv, pwm->mmio_base + PWMPCR);
+ clk_disable(pwm->clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ int rc = 0;
+
+ if (!pwm->clk_enabled) {
+ rc = clk_enable(pwm->clk);
+ if (!rc)
+ pwm->clk_enabled = 1;
+ }
+ return rc;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ if (pwm->clk_enabled) {
+ clk_disable(pwm->clk);
+ pwm->clk_enabled = 0;
+ }
+}
+EXPORT_SYMBOL(pwm_disable);
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, node) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count++;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ pr_warning("PWM device already freed\n");
+
+ mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static inline void __add_pwm(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->node, &pwm_list);
+ mutex_unlock(&pwm_lock);
+}
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
+ struct pwm_device *pwm, *secondary = NULL;
+ struct resource *r;
+ int ret = 0;
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ pwm->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(pwm->clk)) {
+ ret = PTR_ERR(pwm->clk);
+ goto err_free;
+ }
+ pwm->clk_enabled = 0;
+
+ pwm->use_count = 0;
+ pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
+ pwm->pdev = pdev;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
+ if (r == NULL) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ ret = -EBUSY;
+ goto err_free_clk;
+ }
+
+ pwm->mmio_base = ioremap(r->start, resource_size(r));
+ if (pwm->mmio_base == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap() registers\n");
+ ret = -ENODEV;
+ goto err_free_mem;
+ }
+
+ if (id->driver_data & HAS_SECONDARY_PWM) {
+ secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (secondary == NULL) {
+ ret = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ *secondary = *pwm;
+ pwm->secondary = secondary;
+
+ /* registers for the second PWM has offset of 0x10 */
+ secondary->mmio_base = pwm->mmio_base + 0x10;
+ secondary->pwm_id = pdev->id + 2;
+ }
+
+ __add_pwm(pwm);
+ if (secondary)
+ __add_pwm(secondary);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+err_free_mem:
+ release_mem_region(r->start, resource_size(r));
+err_free_clk:
+ clk_put(pwm->clk);
+err_free:
+ kfree(pwm);
+ return ret;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm;
+ struct resource *r;
+
+ pwm = platform_get_drvdata(pdev);
+ if (pwm == NULL)
+ return -ENODEV;
+
+ mutex_lock(&pwm_lock);
+
+ if (pwm->secondary) {
+ list_del(&pwm->secondary->node);
+ kfree(pwm->secondary);
+ }
+
+ list_del(&pwm->node);
+ mutex_unlock(&pwm_lock);
+
+ iounmap(pwm->mmio_base);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_put(pwm->clk);
+ kfree(pwm);
+ return 0;
+}
+
+static struct platform_driver pwm_driver = {
+ .driver = {
+ .name = "pxa25x-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = pwm_probe,
+ .remove = __devexit_p(pwm_remove),
+ .id_table = pwm_id_table,
+};
+
+static int __init pwm_init(void)
+{
+ return platform_driver_register(&pwm_driver);
+}
+arch_initcall(pwm_init);
+
+static void __exit pwm_exit(void)
+{
+ platform_driver_unregister(&pwm_driver);
+}
+module_exit(pwm_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
new file mode 100644
index 00000000..58b79809
--- /dev/null
+++ b/arch/arm/plat-pxa/ssp.c
@@ -0,0 +1,224 @@
+/*
+ * linux/arch/arm/mach-pxa/ssp.c
+ *
+ * based on linux/arch/arm/mach-sa1100/ssp.c by Russell King
+ *
+ * Copyright (C) 2003 Russell King.
+ * Copyright (C) 2003 Wolfson Microelectronics PLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * PXA2xx SSP driver. This provides the generic core for simple
+ * IO-based SSP applications and allows easy port setup for DMA access.
+ *
+ * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/spi/pxa2xx_spi.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+
+static DEFINE_MUTEX(ssp_lock);
+static LIST_HEAD(ssp_list);
+
+struct ssp_device *pxa_ssp_request(int port, const char *label)
+{
+ struct ssp_device *ssp = NULL;
+
+ mutex_lock(&ssp_lock);
+
+ list_for_each_entry(ssp, &ssp_list, node) {
+ if (ssp->port_id == port && ssp->use_count == 0) {
+ ssp->use_count++;
+ ssp->label = label;
+ break;
+ }
+ }
+
+ mutex_unlock(&ssp_lock);
+
+ if (&ssp->node == &ssp_list)
+ return NULL;
+
+ return ssp;
+}
+EXPORT_SYMBOL(pxa_ssp_request);
+
+void pxa_ssp_free(struct ssp_device *ssp)
+{
+ mutex_lock(&ssp_lock);
+ if (ssp->use_count) {
+ ssp->use_count--;
+ ssp->label = NULL;
+ } else
+ dev_err(&ssp->pdev->dev, "device already free\n");
+ mutex_unlock(&ssp_lock);
+}
+EXPORT_SYMBOL(pxa_ssp_free);
+
+static int __devinit pxa_ssp_probe(struct platform_device *pdev)
+{
+ const struct platform_device_id *id = platform_get_device_id(pdev);
+ struct resource *res;
+ struct ssp_device *ssp;
+ int ret = 0;
+
+ ssp = kzalloc(sizeof(struct ssp_device), GFP_KERNEL);
+ if (ssp == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory");
+ return -ENOMEM;
+ }
+ ssp->pdev = pdev;
+
+ ssp->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(ssp->clk)) {
+ ret = PTR_ERR(ssp->clk);
+ goto err_free;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no SSP RX DRCMR defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+ ssp->drcmr_rx = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no SSP TX DRCMR defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+ ssp->drcmr_tx = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ ret = -ENODEV;
+ goto err_free_clk;
+ }
+
+ res = request_mem_region(res->start, resource_size(res),
+ pdev->name);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "failed to request memory resource\n");
+ ret = -EBUSY;
+ goto err_free_clk;
+ }
+
+ ssp->phys_base = res->start;
+
+ ssp->mmio_base = ioremap(res->start, resource_size(res));
+ if (ssp->mmio_base == NULL) {
+ dev_err(&pdev->dev, "failed to ioremap() registers\n");
+ ret = -ENODEV;
+ goto err_free_mem;
+ }
+
+ ssp->irq = platform_get_irq(pdev, 0);
+ if (ssp->irq < 0) {
+ dev_err(&pdev->dev, "no IRQ resource defined\n");
+ ret = -ENODEV;
+ goto err_free_io;
+ }
+
+ /* PXA2xx/3xx SSP ports starts from 1 and the internal pdev->id
+ * starts from 0, do a translation here
+ */
+ ssp->port_id = pdev->id + 1;
+ ssp->use_count = 0;
+ ssp->type = (int)id->driver_data;
+
+ mutex_lock(&ssp_lock);
+ list_add(&ssp->node, &ssp_list);
+ mutex_unlock(&ssp_lock);
+
+ platform_set_drvdata(pdev, ssp);
+ return 0;
+
+err_free_io:
+ iounmap(ssp->mmio_base);
+err_free_mem:
+ release_mem_region(res->start, resource_size(res));
+err_free_clk:
+ clk_put(ssp->clk);
+err_free:
+ kfree(ssp);
+ return ret;
+}
+
+static int __devexit pxa_ssp_remove(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct ssp_device *ssp;
+
+ ssp = platform_get_drvdata(pdev);
+ if (ssp == NULL)
+ return -ENODEV;
+
+ iounmap(ssp->mmio_base);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+ clk_put(ssp->clk);
+
+ mutex_lock(&ssp_lock);
+ list_del(&ssp->node);
+ mutex_unlock(&ssp_lock);
+
+ kfree(ssp);
+ return 0;
+}
+
+static const struct platform_device_id ssp_id_table[] = {
+ { "pxa25x-ssp", PXA25x_SSP },
+ { "pxa25x-nssp", PXA25x_NSSP },
+ { "pxa27x-ssp", PXA27x_SSP },
+ { "pxa168-ssp", PXA168_SSP },
+ { },
+};
+
+static struct platform_driver pxa_ssp_driver = {
+ .probe = pxa_ssp_probe,
+ .remove = __devexit_p(pxa_ssp_remove),
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "pxa2xx-ssp",
+ },
+ .id_table = ssp_id_table,
+};
+
+static int __init pxa_ssp_init(void)
+{
+ return platform_driver_register(&pxa_ssp_driver);
+}
+
+static void __exit pxa_ssp_exit(void)
+{
+ platform_driver_unregister(&pxa_ssp_driver);
+}
+
+arch_initcall(pxa_ssp_init);
+module_exit(pxa_ssp_exit);
+
+MODULE_DESCRIPTION("PXA SSP driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
new file mode 100644
index 00000000..d9c4096e
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -0,0 +1,166 @@
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_S3C24XX
+ bool
+ depends on ARCH_S3C2410 || ARCH_S3C24A0
+ default y
+ select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
+ select S3C_DEV_NAND
+ select S3C_GPIO_CFG_S3C24XX
+ help
+ Base platform code for any Samsung S3C24XX device
+
+if PLAT_S3C24XX
+
+# low-level serial option nodes
+
+config CPU_LLSERIAL_S3C2410_ONLY
+ bool
+ default y if CPU_LLSERIAL_S3C2410 && !CPU_LLSERIAL_S3C2440
+
+config CPU_LLSERIAL_S3C2440_ONLY
+ bool
+ default y if CPU_LLSERIAL_S3C2440 && !CPU_LLSERIAL_S3C2410
+
+config CPU_LLSERIAL_S3C2410
+ bool
+ help
+ Selected if there is an S3C2410 (or register compatible) serial
+ low-level implementation needed
+
+config CPU_LLSERIAL_S3C2440
+ bool
+ help
+ Selected if there is an S3C2440 (or register compatible) serial
+ low-level implementation needed
+
+# code that is shared between a number of the s3c24xx implementations
+
+config S3C2410_CLOCK
+ bool
+ help
+ Clock code for the S3C2410, and similar processors which
+ is currently includes the S3C2410, S3C2440, S3C2442.
+
+config S3C2443_CLOCK
+ bool
+ help
+ Clock code for the S3C2443 and similar processors, which includes
+ the S3C2416 and S3C2450.
+
+config S3C24XX_DCLK
+ bool
+ help
+ Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
+
+# gpio configurations
+
+config S3C24XX_GPIO_EXTRA
+ int
+ default 128 if S3C24XX_GPIO_EXTRA128
+ default 64 if S3C24XX_GPIO_EXTRA64
+ default 16 if ARCH_H1940
+ default 0
+
+config S3C24XX_GPIO_EXTRA64
+ bool
+ help
+ Add an extra 64 gpio numbers to the available GPIO pool. This is
+ available for boards that need extra gpios for external devices.
+
+config S3C24XX_GPIO_EXTRA128
+ bool
+ help
+ Add an extra 128 gpio numbers to the available GPIO pool. This is
+ available for boards that need extra gpios for external devices.
+
+config PM_SIMTEC
+ bool
+ help
+ Common power management code for systems that are
+ compatible with the Simtec style of power management
+
+config S3C2410_DMA
+ bool "S3C2410 DMA support"
+ depends on ARCH_S3C2410
+ select S3C_DMA
+ help
+ S3C2410 DMA support. This is needed for drivers like sound which
+ use the S3C2410's DMA system to move data to and from the
+ peripheral blocks.
+
+config S3C2410_DMA_DEBUG
+ bool "S3C2410 DMA support debug"
+ depends on ARCH_S3C2410 && S3C2410_DMA
+ help
+ Enable debugging output for the DMA code. This option sends info
+ to the kernel log, at priority KERN_DEBUG.
+
+# SPI default pin configuration code
+
+config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13
+ bool
+ help
+ SPI GPIO configuration code for BUS0 when connected to
+ GPE11, GPE12 and GPE13.
+
+config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7
+ bool
+ help
+ SPI GPIO configuration code for BUS 1 when connected to
+ GPG5, GPG6 and GPG7.
+
+config S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10
+ bool
+ help
+ SPI GPIO configuration code for BUS 1 when connected to
+ GPD8, GPD9 and GPD10.
+
+# common code for s3c24xx based machines, such as the SMDKs.
+
+# cpu frequency items common between s3c2410 and s3c2440/s3c2442
+
+config S3C2410_IOTIMING
+ bool
+ depends on CPU_FREQ_S3C24XX
+ help
+ Internal node to select io timing code that is common to the s3c2410
+ and s3c2440/s3c2442 cpu frequency support.
+
+config S3C2410_CPUFREQ_UTILS
+ bool
+ depends on CPU_FREQ_S3C24XX
+ help
+ Internal node to select timing code that is common to the s3c2410
+ and s3c2440/s3c244 cpu frequency support.
+
+# cpu frequency support common to s3c2412, s3c2413 and s3c2442
+
+config S3C2412_IOTIMING
+ bool
+ depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443)
+ help
+ Intel node to select io timing code that is common to the s3c2412
+ and the s3c2443.
+
+config MACH_SMDK
+ bool
+ help
+ Common machine code for SMDK2410 and SMDK2440
+
+config S3C24XX_SIMTEC_AUDIO
+ bool
+ depends on (ARCH_BAST || MACH_VR1000 || MACH_OSIRIS || MACH_ANUBIS)
+ default y
+ help
+ Add audio devices for common Simtec S3C24XX boards
+
+config S3C2410_SETUP_TS
+ bool
+ help
+ Compile in platform device definition for Samsung TouchScreen.
+
+endif
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
new file mode 100644
index 00000000..0291bd6e
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -0,0 +1,52 @@
+# arch/arm/plat-s3c24xx/Makefile
+#
+# Copyright 2007 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n :=
+obj- :=
+
+
+# Core files
+
+obj-y += cpu.o
+obj-y += irq.o
+obj-y += devs.o
+obj-y += gpio.o
+obj-y += gpiolib.o
+obj-y += clock.o
+obj-$(CONFIG_S3C24XX_DCLK) += clock-dclk.o
+
+obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpu-freq.o
+obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
+
+# Architecture dependent builds
+
+obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
+obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o
+obj-$(CONFIG_S3C2410_DMA) += dma.o
+obj-$(CONFIG_S3C2410_IOTIMING) += s3c2410-iotiming.o
+obj-$(CONFIG_S3C2412_IOTIMING) += s3c2412-iotiming.o
+obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += s3c2410-cpufreq-utils.o
+
+# device specific setup and/or initialisation
+obj-$(CONFIG_ARCH_S3C2410) += setup-i2c.o
+obj-$(CONFIG_S3C2410_SETUP_TS) += setup-ts.o
+
+# SPI gpio central GPIO functions
+
+obj-$(CONFIG_S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13) += spi-bus0-gpe11_12_13.o
+obj-$(CONFIG_S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7) += spi-bus1-gpg5_6_7.o
+obj-$(CONFIG_S3C24XX_SPI_BUS1_GPD8_GPD9_GPD10) += spi-bus1-gpd8_9_10.o
+
+# machine common support
+
+obj-$(CONFIG_MACH_SMDK) += common-smdk.o
+obj-$(CONFIG_S3C24XX_SIMTEC_AUDIO) += simtec-audio.o
diff --git a/arch/arm/plat-s3c24xx/clock-dclk.c b/arch/arm/plat-s3c24xx/clock-dclk.c
new file mode 100644
index 00000000..cf97caaf
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/clock-dclk.c
@@ -0,0 +1,200 @@
+/* linux/arch/arm/plat-s3c24xx/clock-dclk.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C24XX - definitions for DCLK and CLKOUT registers
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+/* clocks that could be registered by external code */
+
+static int s3c24xx_dclk_enable(struct clk *clk, int enable)
+{
+ unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+ if (enable)
+ dclkcon |= clk->ctrlbit;
+ else
+ dclkcon &= ~clk->ctrlbit;
+
+ __raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+ return 0;
+}
+
+static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
+{
+ unsigned long dclkcon;
+ unsigned int uclk;
+
+ if (parent == &clk_upll)
+ uclk = 1;
+ else if (parent == &clk_p)
+ uclk = 0;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ dclkcon = __raw_readl(S3C24XX_DCLKCON);
+
+ if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
+ if (uclk)
+ dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
+ else
+ dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
+ } else {
+ if (uclk)
+ dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
+ else
+ dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
+ }
+
+ __raw_writel(dclkcon, S3C24XX_DCLKCON);
+
+ return 0;
+}
+static unsigned long s3c24xx_calc_div(struct clk *clk, unsigned long rate)
+{
+ unsigned long div;
+
+ if ((rate == 0) || !clk->parent)
+ return 0;
+
+ div = clk_get_rate(clk->parent) / rate;
+ if (div < 2)
+ div = 2;
+ else if (div > 16)
+ div = 16;
+
+ return div;
+}
+
+static unsigned long s3c24xx_round_dclk_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long div = s3c24xx_calc_div(clk, rate);
+
+ if (div == 0)
+ return 0;
+
+ return clk_get_rate(clk->parent) / div;
+}
+
+static int s3c24xx_set_dclk_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long mask, data, div = s3c24xx_calc_div(clk, rate);
+
+ if (div == 0)
+ return -EINVAL;
+
+ if (clk == &s3c24xx_dclk0) {
+ mask = S3C2410_DCLKCON_DCLK0_DIV_MASK |
+ S3C2410_DCLKCON_DCLK0_CMP_MASK;
+ data = S3C2410_DCLKCON_DCLK0_DIV(div) |
+ S3C2410_DCLKCON_DCLK0_CMP((div + 1) / 2);
+ } else if (clk == &s3c24xx_dclk1) {
+ mask = S3C2410_DCLKCON_DCLK1_DIV_MASK |
+ S3C2410_DCLKCON_DCLK1_CMP_MASK;
+ data = S3C2410_DCLKCON_DCLK1_DIV(div) |
+ S3C2410_DCLKCON_DCLK1_CMP((div + 1) / 2);
+ } else
+ return -EINVAL;
+
+ clk->rate = clk_get_rate(clk->parent) / div;
+ __raw_writel(((__raw_readl(S3C24XX_DCLKCON) & ~mask) | data),
+ S3C24XX_DCLKCON);
+ return clk->rate;
+}
+static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
+{
+ unsigned long mask;
+ unsigned long source;
+
+ /* calculate the MISCCR setting for the clock */
+
+ if (parent == &clk_mpll)
+ source = S3C2410_MISCCR_CLK0_MPLL;
+ else if (parent == &clk_upll)
+ source = S3C2410_MISCCR_CLK0_UPLL;
+ else if (parent == &clk_f)
+ source = S3C2410_MISCCR_CLK0_FCLK;
+ else if (parent == &clk_h)
+ source = S3C2410_MISCCR_CLK0_HCLK;
+ else if (parent == &clk_p)
+ source = S3C2410_MISCCR_CLK0_PCLK;
+ else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
+ source = S3C2410_MISCCR_CLK0_DCLK0;
+ else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
+ source = S3C2410_MISCCR_CLK0_DCLK0;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ if (clk == &s3c24xx_clkout0)
+ mask = S3C2410_MISCCR_CLK0_MASK;
+ else {
+ source <<= 4;
+ mask = S3C2410_MISCCR_CLK1_MASK;
+ }
+
+ s3c2410_modify_misccr(mask, source);
+ return 0;
+}
+
+/* external clock definitions */
+
+static struct clk_ops dclk_ops = {
+ .set_parent = s3c24xx_dclk_setparent,
+ .set_rate = s3c24xx_set_dclk_rate,
+ .round_rate = s3c24xx_round_dclk_rate,
+};
+
+struct clk s3c24xx_dclk0 = {
+ .name = "dclk0",
+ .id = -1,
+ .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
+ .enable = s3c24xx_dclk_enable,
+ .ops = &dclk_ops,
+};
+
+struct clk s3c24xx_dclk1 = {
+ .name = "dclk1",
+ .id = -1,
+ .ctrlbit = S3C2410_DCLKCON_DCLK1EN,
+ .enable = s3c24xx_dclk_enable,
+ .ops = &dclk_ops,
+};
+
+static struct clk_ops clkout_ops = {
+ .set_parent = s3c24xx_clkout_setparent,
+};
+
+struct clk s3c24xx_clkout0 = {
+ .name = "clkout0",
+ .id = -1,
+ .ops = &clkout_ops,
+};
+
+struct clk s3c24xx_clkout1 = {
+ .name = "clkout1",
+ .id = -1,
+ .ops = &clkout_ops,
+};
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
new file mode 100644
index 00000000..931d26d1
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -0,0 +1,59 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ ** Copyright (C) 2004 ARM Limited.
+ ** Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/pll.h>
+
+/* initialise all the clocks */
+
+void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
+ unsigned long hclk,
+ unsigned long pclk)
+{
+ clk_upll.rate = s3c24xx_get_pll(__raw_readl(S3C2410_UPLLCON),
+ clk_xtal.rate);
+
+ clk_mpll.rate = fclk;
+ clk_h.rate = hclk;
+ clk_p.rate = pclk;
+ clk_f.rate = fclk;
+}
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
new file mode 100644
index 00000000..bcc43f34
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -0,0 +1,207 @@
+/* linux/arch/arm/plat-s3c24xx/common-smdk.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/sysdev.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/leds-gpio.h>
+
+#include <plat/nand.h>
+
+#include <plat/common-smdk.h>
+#include <plat/gpio-cfg.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
+
+/* LED devices */
+
+static struct s3c24xx_led_platdata smdk_pdata_led4 = {
+ .gpio = S3C2410_GPF(4),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led4",
+ .def_trigger = "timer",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led5 = {
+ .gpio = S3C2410_GPF(5),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led5",
+ .def_trigger = "nand-disk",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led6 = {
+ .gpio = S3C2410_GPF(6),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led6",
+};
+
+static struct s3c24xx_led_platdata smdk_pdata_led7 = {
+ .gpio = S3C2410_GPF(7),
+ .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
+ .name = "led7",
+};
+
+static struct platform_device smdk_led4 = {
+ .name = "s3c24xx_led",
+ .id = 0,
+ .dev = {
+ .platform_data = &smdk_pdata_led4,
+ },
+};
+
+static struct platform_device smdk_led5 = {
+ .name = "s3c24xx_led",
+ .id = 1,
+ .dev = {
+ .platform_data = &smdk_pdata_led5,
+ },
+};
+
+static struct platform_device smdk_led6 = {
+ .name = "s3c24xx_led",
+ .id = 2,
+ .dev = {
+ .platform_data = &smdk_pdata_led6,
+ },
+};
+
+static struct platform_device smdk_led7 = {
+ .name = "s3c24xx_led",
+ .id = 3,
+ .dev = {
+ .platform_data = &smdk_pdata_led7,
+ },
+};
+
+/* NAND parititon from 2.4.18-swl5 */
+
+static struct mtd_partition smdk_default_nand_part[] = {
+ [0] = {
+ .name = "Boot Agent",
+ .size = SZ_16K,
+ .offset = 0,
+ },
+ [1] = {
+ .name = "S3C2410 flash partition 1",
+ .offset = 0,
+ .size = SZ_2M,
+ },
+ [2] = {
+ .name = "S3C2410 flash partition 2",
+ .offset = SZ_4M,
+ .size = SZ_4M,
+ },
+ [3] = {
+ .name = "S3C2410 flash partition 3",
+ .offset = SZ_8M,
+ .size = SZ_2M,
+ },
+ [4] = {
+ .name = "S3C2410 flash partition 4",
+ .offset = SZ_1M * 10,
+ .size = SZ_4M,
+ },
+ [5] = {
+ .name = "S3C2410 flash partition 5",
+ .offset = SZ_1M * 14,
+ .size = SZ_1M * 10,
+ },
+ [6] = {
+ .name = "S3C2410 flash partition 6",
+ .offset = SZ_1M * 24,
+ .size = SZ_1M * 24,
+ },
+ [7] = {
+ .name = "S3C2410 flash partition 7",
+ .offset = SZ_1M * 48,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+static struct s3c2410_nand_set smdk_nand_sets[] = {
+ [0] = {
+ .name = "NAND",
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(smdk_default_nand_part),
+ .partitions = smdk_default_nand_part,
+ },
+};
+
+/* choose a set of timings which should suit most 512Mbit
+ * chips and beyond.
+*/
+
+static struct s3c2410_platform_nand smdk_nand_info = {
+ .tacls = 20,
+ .twrph0 = 60,
+ .twrph1 = 20,
+ .nr_sets = ARRAY_SIZE(smdk_nand_sets),
+ .sets = smdk_nand_sets,
+};
+
+/* devices we initialise */
+
+static struct platform_device __initdata *smdk_devs[] = {
+ &s3c_device_nand,
+ &smdk_led4,
+ &smdk_led5,
+ &smdk_led6,
+ &smdk_led7,
+};
+
+void __init smdk_machine_init(void)
+{
+ /* Configure the LEDs (even if we have no LED support)*/
+
+ s3c_gpio_cfgpin(S3C2410_GPF(4), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(5), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(6), S3C2410_GPIO_OUTPUT);
+ s3c_gpio_cfgpin(S3C2410_GPF(7), S3C2410_GPIO_OUTPUT);
+
+ s3c2410_gpio_setpin(S3C2410_GPF(4), 1);
+ s3c2410_gpio_setpin(S3C2410_GPF(5), 1);
+ s3c2410_gpio_setpin(S3C2410_GPF(6), 1);
+ s3c2410_gpio_setpin(S3C2410_GPF(7), 1);
+
+ if (machine_is_smdk2443())
+ smdk_nand_info.twrph0 = 50;
+
+ s3c_nand_set_platdata(&smdk_nand_info);
+
+ platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));
+
+ s3c_pm_init();
+}
diff --git a/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
new file mode 100644
index 00000000..a9276667
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
@@ -0,0 +1,199 @@
+/* linux/arch/arm/plat-s3c24xx/cpu-freq-debugfs.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - debugfs status support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/err.h>
+
+#include <plat/cpu-freq-core.h>
+
+static struct dentry *dbgfs_root;
+static struct dentry *dbgfs_file_io;
+static struct dentry *dbgfs_file_info;
+static struct dentry *dbgfs_file_board;
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+static void show_max(struct seq_file *seq, struct s3c_freq *f)
+{
+ seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
+ f->fclk, f->hclk, f->pclk, f->armclk);
+}
+
+static int board_show(struct seq_file *seq, void *p)
+{
+ struct s3c_cpufreq_config *cfg;
+ struct s3c_cpufreq_board *brd;
+
+ cfg = s3c_cpufreq_getconfig();
+ if (!cfg) {
+ seq_printf(seq, "no configuration registered\n");
+ return 0;
+ }
+
+ brd = cfg->board;
+ if (!brd) {
+ seq_printf(seq, "no board definition set?\n");
+ return 0;
+ }
+
+ seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
+ seq_printf(seq, "auto_io=%u\n", brd->auto_io);
+ seq_printf(seq, "need_io=%u\n", brd->need_io);
+
+ show_max(seq, &brd->max);
+
+
+ return 0;
+}
+
+static int fops_board_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, board_show, NULL);
+}
+
+static const struct file_operations fops_board = {
+ .open = fops_board_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int info_show(struct seq_file *seq, void *p)
+{
+ struct s3c_cpufreq_config *cfg;
+
+ cfg = s3c_cpufreq_getconfig();
+ if (!cfg) {
+ seq_printf(seq, "no configuration registered\n");
+ return 0;
+ }
+
+ seq_printf(seq, " FCLK %ld Hz\n", cfg->freq.fclk);
+ seq_printf(seq, " HCLK %ld Hz (%lu.%lu ns)\n",
+ cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
+ seq_printf(seq, " PCLK %ld Hz\n", cfg->freq.hclk);
+ seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
+ seq_printf(seq, "\n");
+
+ show_max(seq, &cfg->max);
+
+ seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
+ cfg->divs.h_divisor, cfg->divs.p_divisor,
+ cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
+ seq_printf(seq, "\n");
+
+ seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
+
+ return 0;
+}
+
+static int fops_info_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, info_show, NULL);
+}
+
+static const struct file_operations fops_info = {
+ .open = fops_info_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int io_show(struct seq_file *seq, void *p)
+{
+ void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
+ struct s3c_cpufreq_config *cfg;
+ struct s3c_iotimings *iot;
+ union s3c_iobank *iob;
+ int bank;
+
+ cfg = s3c_cpufreq_getconfig();
+ if (!cfg) {
+ seq_printf(seq, "no configuration registered\n");
+ return 0;
+ }
+
+ show_bank = cfg->info->debug_io_show;
+ if (!show_bank) {
+ seq_printf(seq, "no code to show bank timing\n");
+ return 0;
+ }
+
+ iot = s3c_cpufreq_getiotimings();
+ if (!iot) {
+ seq_printf(seq, "no io timings registered\n");
+ return 0;
+ }
+
+ seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ iob = &iot->bank[bank];
+
+ seq_printf(seq, "bank %d: ", bank);
+
+ if (!iob->io_2410) {
+ seq_printf(seq, "nothing set\n");
+ continue;
+ }
+
+ show_bank(seq, cfg, iob);
+ }
+
+ return 0;
+}
+
+static int fops_io_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, io_show, NULL);
+}
+
+static const struct file_operations fops_io = {
+ .open = fops_io_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+
+static int __init s3c_freq_debugfs_init(void)
+{
+ dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
+ if (IS_ERR(dbgfs_root)) {
+ printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
+ return PTR_ERR(dbgfs_root);
+ }
+
+ dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
+ NULL, &fops_io);
+
+ dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
+ NULL, &fops_info);
+
+ dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
+ NULL, &fops_board);
+
+ return 0;
+}
+
+late_initcall(s3c_freq_debugfs_init);
+
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c
new file mode 100644
index 00000000..b3d3d027
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu-freq.c
@@ -0,0 +1,716 @@
+/* linux/arch/arm/plat-s3c24xx/cpu-freq.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/cpu.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu-freq-core.h>
+
+#include <mach/regs-clock.h>
+
+/* note, cpufreq support deals in kHz, no Hz */
+
+static struct cpufreq_driver s3c24xx_driver;
+static struct s3c_cpufreq_config cpu_cur;
+static struct s3c_iotimings s3c24xx_iotiming;
+static struct cpufreq_frequency_table *pll_reg;
+static unsigned int last_target = ~0;
+static unsigned int ftab_size;
+static struct cpufreq_frequency_table *ftab;
+
+static struct clk *_clk_mpll;
+static struct clk *_clk_xtal;
+static struct clk *clk_fclk;
+static struct clk *clk_hclk;
+static struct clk *clk_pclk;
+static struct clk *clk_arm;
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
+{
+ return &cpu_cur;
+}
+
+struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
+{
+ return &s3c24xx_iotiming;
+}
+#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
+
+static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
+{
+ unsigned long fclk, pclk, hclk, armclk;
+
+ cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
+ cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
+ cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
+ cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
+
+ cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
+ cfg->pll.frequency = fclk;
+
+ cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+
+ cfg->divs.h_divisor = fclk / hclk;
+ cfg->divs.p_divisor = fclk / pclk;
+}
+
+static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
+{
+ unsigned long pll = cfg->pll.frequency;
+
+ cfg->freq.fclk = pll;
+ cfg->freq.hclk = pll / cfg->divs.h_divisor;
+ cfg->freq.pclk = pll / cfg->divs.p_divisor;
+
+ /* convert hclk into 10ths of nanoseconds for io calcs */
+ cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
+}
+
+static inline int closer(unsigned int target, unsigned int n, unsigned int c)
+{
+ int diff_cur = abs(target - c);
+ int diff_new = abs(target - n);
+
+ return (diff_new < diff_cur);
+}
+
+static void s3c_cpufreq_show(const char *pfx,
+ struct s3c_cpufreq_config *cfg)
+{
+ s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
+ pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
+ cfg->freq.hclk, cfg->divs.h_divisor,
+ cfg->freq.pclk, cfg->divs.p_divisor);
+}
+
+/* functions to wrapper the driver info calls to do the cpu specific work */
+
+static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
+{
+ if (cfg->info->set_iotiming)
+ (cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
+}
+
+static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
+{
+ if (cfg->info->calc_iotiming)
+ return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
+
+ return 0;
+}
+
+static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ (cfg->info->set_refresh)(cfg);
+}
+
+static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
+{
+ (cfg->info->set_divs)(cfg);
+}
+
+static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
+{
+ return (cfg->info->calc_divs)(cfg);
+}
+
+static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
+{
+ (cfg->info->set_fvco)(cfg);
+}
+
+static inline void s3c_cpufreq_resume_clocks(void)
+{
+ cpu_cur.info->resume_clocks();
+}
+
+static inline void s3c_cpufreq_updateclk(struct clk *clk,
+ unsigned int freq)
+{
+ clk_set_rate(clk, freq);
+}
+
+static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ struct cpufreq_frequency_table *pll)
+{
+ struct s3c_cpufreq_freqs freqs;
+ struct s3c_cpufreq_config cpu_new;
+ unsigned long flags;
+
+ cpu_new = cpu_cur; /* copy new from current */
+
+ s3c_cpufreq_show("cur", &cpu_cur);
+
+ /* TODO - check for DMA currently outstanding */
+
+ cpu_new.pll = pll ? *pll : cpu_cur.pll;
+
+ if (pll)
+ freqs.pll_changing = 1;
+
+ /* update our frequencies */
+
+ cpu_new.freq.armclk = target_freq;
+ cpu_new.freq.fclk = cpu_new.pll.frequency;
+
+ if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
+ printk(KERN_ERR "no divisors for %d\n", target_freq);
+ goto err_notpossible;
+ }
+
+ s3c_freq_dbg("%s: got divs\n", __func__);
+
+ s3c_cpufreq_calc(&cpu_new);
+
+ s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
+
+ if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
+ if (s3c_cpufreq_calcio(&cpu_new) < 0) {
+ printk(KERN_ERR "%s: no IO timings\n", __func__);
+ goto err_notpossible;
+ }
+ }
+
+ s3c_cpufreq_show("new", &cpu_new);
+
+ /* setup our cpufreq parameters */
+
+ freqs.old = cpu_cur.freq;
+ freqs.new = cpu_new.freq;
+
+ freqs.freqs.cpu = 0;
+ freqs.freqs.old = cpu_cur.freq.armclk / 1000;
+ freqs.freqs.new = cpu_new.freq.armclk / 1000;
+
+ /* update f/h/p clock settings before we issue the change
+ * notification, so that drivers do not need to do anything
+ * special if they want to recalculate on CPUFREQ_PRECHANGE. */
+
+ s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
+ s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
+ s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
+ s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
+
+ /* start the frequency change */
+
+ if (policy)
+ cpufreq_notify_transition(&freqs.freqs, CPUFREQ_PRECHANGE);
+
+ /* If hclk is staying the same, then we do not need to
+ * re-write the IO or the refresh timings whilst we are changing
+ * speed. */
+
+ local_irq_save(flags);
+
+ /* is our memory clock slowing down? */
+ if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
+ s3c_cpufreq_setrefresh(&cpu_new);
+ s3c_cpufreq_setio(&cpu_new);
+ }
+
+ if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
+ /* not changing PLL, just set the divisors */
+
+ s3c_cpufreq_setdivs(&cpu_new);
+ } else {
+ if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
+ /* slow the cpu down, then set divisors */
+
+ s3c_cpufreq_setfvco(&cpu_new);
+ s3c_cpufreq_setdivs(&cpu_new);
+ } else {
+ /* set the divisors, then speed up */
+
+ s3c_cpufreq_setdivs(&cpu_new);
+ s3c_cpufreq_setfvco(&cpu_new);
+ }
+ }
+
+ /* did our memory clock speed up */
+ if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
+ s3c_cpufreq_setrefresh(&cpu_new);
+ s3c_cpufreq_setio(&cpu_new);
+ }
+
+ /* update our current settings */
+ cpu_cur = cpu_new;
+
+ local_irq_restore(flags);
+
+ /* notify everyone we've done this */
+ if (policy)
+ cpufreq_notify_transition(&freqs.freqs, CPUFREQ_POSTCHANGE);
+
+ s3c_freq_dbg("%s: finished\n", __func__);
+ return 0;
+
+ err_notpossible:
+ printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+ return -EINVAL;
+}
+
+/* s3c_cpufreq_target
+ *
+ * called by the cpufreq core to adjust the frequency that the CPU
+ * is currently running at.
+ */
+
+static int s3c_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_frequency_table *pll;
+ unsigned int index;
+
+ /* avoid repeated calls which cause a needless amout of duplicated
+ * logging output (and CPU time as the calculation process is
+ * done) */
+ if (target_freq == last_target)
+ return 0;
+
+ last_target = target_freq;
+
+ s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
+ __func__, policy, target_freq, relation);
+
+ if (ftab) {
+ if (cpufreq_frequency_table_target(policy, ftab,
+ target_freq, relation,
+ &index)) {
+ s3c_freq_dbg("%s: table failed\n", __func__);
+ return -EINVAL;
+ }
+
+ s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
+ target_freq, index, ftab[index].frequency);
+ target_freq = ftab[index].frequency;
+ }
+
+ target_freq *= 1000; /* convert target to Hz */
+
+ /* find the settings for our new frequency */
+
+ if (!pll_reg || cpu_cur.lock_pll) {
+ /* either we've not got any PLL values, or we've locked
+ * to the current one. */
+ pll = NULL;
+ } else {
+ struct cpufreq_policy tmp_policy;
+ int ret;
+
+ /* we keep the cpu pll table in Hz, to ensure we get an
+ * accurate value for the PLL output. */
+
+ tmp_policy.min = policy->min * 1000;
+ tmp_policy.max = policy->max * 1000;
+ tmp_policy.cpu = policy->cpu;
+
+ /* cpufreq_frequency_table_target uses a pointer to 'index'
+ * which is the number of the table entry, not the value of
+ * the table entry's index field. */
+
+ ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
+ target_freq, relation,
+ &index);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: no PLL available\n", __func__);
+ goto err_notpossible;
+ }
+
+ pll = pll_reg + index;
+
+ s3c_freq_dbg("%s: target %u => %u\n",
+ __func__, target_freq, pll->frequency);
+
+ target_freq = pll->frequency;
+ }
+
+ return s3c_cpufreq_settarget(policy, target_freq, pll);
+
+ err_notpossible:
+ printk(KERN_ERR "no compatible settings for %d\n", target_freq);
+ return -EINVAL;
+}
+
+static unsigned int s3c_cpufreq_get(unsigned int cpu)
+{
+ return clk_get_rate(clk_arm) / 1000;
+}
+
+struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
+{
+ struct clk *clk;
+
+ clk = clk_get(dev, name);
+ if (IS_ERR(clk))
+ printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
+
+ return clk;
+}
+
+static int s3c_cpufreq_init(struct cpufreq_policy *policy)
+{
+ printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = s3c_cpufreq_get(0);
+ policy->min = policy->cpuinfo.min_freq = 0;
+ policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ /* feed the latency information from the cpu driver */
+ policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+ if (ftab)
+ cpufreq_frequency_table_cpuinfo(policy, ftab);
+
+ return 0;
+}
+
+static __init int s3c_cpufreq_initclks(void)
+{
+ _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
+ _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
+ clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
+ clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
+ clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
+ clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
+
+ if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
+ IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
+ printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
+ return -ENOENT;
+ }
+
+ printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
+ clk_get_rate(clk_fclk) / 1000,
+ clk_get_rate(clk_hclk) / 1000,
+ clk_get_rate(clk_pclk) / 1000,
+ clk_get_rate(clk_arm) / 1000);
+
+ return 0;
+}
+
+static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static struct cpufreq_frequency_table suspend_pll;
+static unsigned int suspend_freq;
+
+static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
+{
+ suspend_pll.frequency = clk_get_rate(_clk_mpll);
+ suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
+ suspend_freq = s3c_cpufreq_get(0) * 1000;
+
+ return 0;
+}
+
+static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
+{
+ int ret;
+
+ s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
+
+ last_target = ~0; /* invalidate last_target setting */
+
+ /* first, find out what speed we resumed at. */
+ s3c_cpufreq_resume_clocks();
+
+ /* whilst we will be called later on, we try and re-set the
+ * cpu frequencies as soon as possible so that we do not end
+ * up resuming devices and then immediately having to re-set
+ * a number of settings once these devices have restarted.
+ *
+ * as a note, it is expected devices are not used until they
+ * have been un-suspended and at that time they should have
+ * used the updated clock settings.
+ */
+
+ ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+#else
+#define s3c_cpufreq_resume NULL
+#define s3c_cpufreq_suspend NULL
+#endif
+
+static struct cpufreq_driver s3c24xx_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = s3c_cpufreq_verify,
+ .target = s3c_cpufreq_target,
+ .get = s3c_cpufreq_get,
+ .init = s3c_cpufreq_init,
+ .suspend = s3c_cpufreq_suspend,
+ .resume = s3c_cpufreq_resume,
+ .name = "s3c24xx",
+};
+
+
+int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
+{
+ if (!info || !info->name) {
+ printk(KERN_ERR "%s: failed to pass valid information\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
+ info->name);
+
+ /* check our driver info has valid data */
+
+ BUG_ON(info->set_refresh == NULL);
+ BUG_ON(info->set_divs == NULL);
+ BUG_ON(info->calc_divs == NULL);
+
+ /* info->set_fvco is optional, depending on whether there
+ * is a need to set the clock code. */
+
+ cpu_cur.info = info;
+
+ /* Note, driver registering should probably update locktime */
+
+ return 0;
+}
+
+int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+ struct s3c_cpufreq_board *ours;
+
+ if (!board) {
+ printk(KERN_INFO "%s: no board data\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Copy the board information so that each board can make this
+ * initdata. */
+
+ ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
+ if (ours == NULL) {
+ printk(KERN_ERR "%s: no memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ *ours = *board;
+ cpu_cur.board = ours;
+
+ return 0;
+}
+
+int __init s3c_cpufreq_auto_io(void)
+{
+ int ret;
+
+ if (!cpu_cur.info->get_iotiming) {
+ printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
+ return -ENOENT;
+ }
+
+ printk(KERN_INFO "%s: working out IO settings\n", __func__);
+
+ ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
+ if (ret)
+ printk(KERN_ERR "%s: failed to get timings\n", __func__);
+
+ return ret;
+}
+
+/* if one or is zero, then return the other, otherwise return the min */
+#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
+
+/**
+ * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
+ * @dst: The destination structure
+ * @a: One argument.
+ * @b: The other argument.
+ *
+ * Create a minimum of each frequency entry in the 'struct s3c_freq',
+ * unless the entry is zero when it is ignored and the non-zero argument
+ * used.
+ */
+static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
+ struct s3c_freq *a, struct s3c_freq *b)
+{
+ dst->fclk = do_min(a->fclk, b->fclk);
+ dst->hclk = do_min(a->hclk, b->hclk);
+ dst->pclk = do_min(a->pclk, b->pclk);
+ dst->armclk = do_min(a->armclk, b->armclk);
+}
+
+static inline u32 calc_locktime(u32 freq, u32 time_us)
+{
+ u32 result;
+
+ result = freq * time_us;
+ result = DIV_ROUND_UP(result, 1000 * 1000);
+
+ return result;
+}
+
+static void s3c_cpufreq_update_loctkime(void)
+{
+ unsigned int bits = cpu_cur.info->locktime_bits;
+ u32 rate = (u32)clk_get_rate(_clk_xtal);
+ u32 val;
+
+ if (bits == 0) {
+ WARN_ON(1);
+ return;
+ }
+
+ val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
+ val |= calc_locktime(rate, cpu_cur.info->locktime_m);
+
+ printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
+ __raw_writel(val, S3C2410_LOCKTIME);
+}
+
+static int s3c_cpufreq_build_freq(void)
+{
+ int size, ret;
+
+ if (!cpu_cur.info->calc_freqtable)
+ return -EINVAL;
+
+ kfree(ftab);
+ ftab = NULL;
+
+ size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
+ size++;
+
+ ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
+ if (!ftab) {
+ printk(KERN_ERR "%s: no memory for tables\n", __func__);
+ return -ENOMEM;
+ }
+
+ ftab_size = size;
+
+ ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
+ s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
+
+ return 0;
+}
+
+static int __init s3c_cpufreq_initcall(void)
+{
+ int ret = 0;
+
+ if (cpu_cur.info && cpu_cur.board) {
+ ret = s3c_cpufreq_initclks();
+ if (ret)
+ goto out;
+
+ /* get current settings */
+ s3c_cpufreq_getcur(&cpu_cur);
+ s3c_cpufreq_show("cur", &cpu_cur);
+
+ if (cpu_cur.board->auto_io) {
+ ret = s3c_cpufreq_auto_io();
+ if (ret) {
+ printk(KERN_ERR "%s: failed to get io timing\n",
+ __func__);
+ goto out;
+ }
+ }
+
+ if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
+ printk(KERN_ERR "%s: no IO support registered\n",
+ __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!cpu_cur.info->need_pll)
+ cpu_cur.lock_pll = 1;
+
+ s3c_cpufreq_update_loctkime();
+
+ s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
+ &cpu_cur.info->max);
+
+ if (cpu_cur.info->calc_freqtable)
+ s3c_cpufreq_build_freq();
+
+ ret = cpufreq_register_driver(&s3c24xx_driver);
+ }
+
+ out:
+ return ret;
+}
+
+late_initcall(s3c_cpufreq_initcall);
+
+/**
+ * s3c_plltab_register - register CPU PLL table.
+ * @plls: The list of PLL entries.
+ * @plls_no: The size of the PLL entries @plls.
+ *
+ * Register the given set of PLLs with the system.
+ */
+int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
+ unsigned int plls_no)
+{
+ struct cpufreq_frequency_table *vals;
+ unsigned int size;
+
+ size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
+
+ vals = kmalloc(size, GFP_KERNEL);
+ if (vals) {
+ memcpy(vals, plls, size);
+ pll_reg = vals;
+
+ /* write a terminating entry, we don't store it in the
+ * table that is stored in the kernel */
+ vals += plls_no;
+ vals->frequency = CPUFREQ_TABLE_END;
+
+ printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
+ } else
+ printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
+
+ return vals ? 0 : -ENOMEM;
+}
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
new file mode 100644
index 00000000..4a10c0f6
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -0,0 +1,248 @@
+/* linux/arch/arm/plat-s3c24xx/cpu.c
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/system-reset.h>
+
+#include <mach/regs-gpio.h>
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s3c2400.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/s3c2416.h>
+#include <plat/s3c244x.h>
+#include <plat/s3c2443.h>
+
+/* table of supported CPUs */
+
+static const char name_s3c2400[] = "S3C2400";
+static const char name_s3c2410[] = "S3C2410";
+static const char name_s3c2412[] = "S3C2412";
+static const char name_s3c2416[] = "S3C2416/S3C2450";
+static const char name_s3c2440[] = "S3C2440";
+static const char name_s3c2442[] = "S3C2442";
+static const char name_s3c2442b[] = "S3C2442B";
+static const char name_s3c2443[] = "S3C2443";
+static const char name_s3c2410a[] = "S3C2410A";
+static const char name_s3c2440a[] = "S3C2440A";
+
+static struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x32410000,
+ .idmask = 0xffffffff,
+ .map_io = s3c2410_map_io,
+ .init_clocks = s3c2410_init_clocks,
+ .init_uarts = s3c2410_init_uarts,
+ .init = s3c2410_init,
+ .name = name_s3c2410
+ },
+ {
+ .idcode = 0x32410002,
+ .idmask = 0xffffffff,
+ .map_io = s3c2410_map_io,
+ .init_clocks = s3c2410_init_clocks,
+ .init_uarts = s3c2410_init_uarts,
+ .init = s3c2410a_init,
+ .name = name_s3c2410a
+ },
+ {
+ .idcode = 0x32440000,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440
+ },
+ {
+ .idcode = 0x32440001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2440_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2440_init,
+ .name = name_s3c2440a
+ },
+ {
+ .idcode = 0x32440aaa,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442
+ },
+ {
+ .idcode = 0x32440aab,
+ .idmask = 0xffffffff,
+ .map_io = s3c2442_map_io,
+ .init_clocks = s3c244x_init_clocks,
+ .init_uarts = s3c244x_init_uarts,
+ .init = s3c2442_init,
+ .name = name_s3c2442b
+ },
+ {
+ .idcode = 0x32412001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2412_map_io,
+ .init_clocks = s3c2412_init_clocks,
+ .init_uarts = s3c2412_init_uarts,
+ .init = s3c2412_init,
+ .name = name_s3c2412,
+ },
+ { /* a newer version of the s3c2412 */
+ .idcode = 0x32412003,
+ .idmask = 0xffffffff,
+ .map_io = s3c2412_map_io,
+ .init_clocks = s3c2412_init_clocks,
+ .init_uarts = s3c2412_init_uarts,
+ .init = s3c2412_init,
+ .name = name_s3c2412,
+ },
+ { /* a strange version of the s3c2416 */
+ .idcode = 0x32450003,
+ .idmask = 0xffffffff,
+ .map_io = s3c2416_map_io,
+ .init_clocks = s3c2416_init_clocks,
+ .init_uarts = s3c2416_init_uarts,
+ .init = s3c2416_init,
+ .name = name_s3c2416,
+ },
+ {
+ .idcode = 0x32443001,
+ .idmask = 0xffffffff,
+ .map_io = s3c2443_map_io,
+ .init_clocks = s3c2443_init_clocks,
+ .init_uarts = s3c2443_init_uarts,
+ .init = s3c2443_init,
+ .name = name_s3c2443,
+ },
+ {
+ .idcode = 0x0, /* S3C2400 doesn't have an idcode */
+ .idmask = 0xffffffff,
+ .map_io = s3c2400_map_io,
+ .init_clocks = s3c2400_init_clocks,
+ .init_uarts = s3c2400_init_uarts,
+ .init = s3c2400_init,
+ .name = name_s3c2400
+ },
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s3c_iodesc[] __initdata = {
+ IODESC_ENT(GPIO),
+ IODESC_ENT(IRQ),
+ IODESC_ENT(MEMCTRL),
+ IODESC_ENT(UART)
+};
+
+/* read cpu identificaiton code */
+
+static unsigned long s3c24xx_read_idcode_v5(void)
+{
+#if defined(CONFIG_CPU_S3C2416)
+ /* s3c2416 is v5, with S3C24XX_GSTATUS1 instead of S3C2412_GSTATUS1 */
+
+ u32 gs = __raw_readl(S3C24XX_GSTATUS1);
+
+ /* test for s3c2416 or similar device */
+ if ((gs >> 16) == 0x3245)
+ return gs;
+#endif
+
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+ return __raw_readl(S3C2412_GSTATUS1);
+#else
+ return 1UL; /* don't look like an 2400 */
+#endif
+}
+
+static unsigned long s3c24xx_read_idcode_v4(void)
+{
+#ifndef CONFIG_CPU_S3C2400
+ return __raw_readl(S3C2410_GSTATUS1);
+#else
+ return 0UL;
+#endif
+}
+
+/* Hook for arm_pm_restart to ensure we execute the reset code
+ * with the caches enabled. It seems at least the S3C2440 has a problem
+ * resetting if there is bus activity interrupted by the reset.
+ */
+static void s3c24xx_pm_restart(char mode, const char *cmd)
+{
+ if (mode != 's') {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __cpuc_flush_kern_all();
+ __cpuc_flush_user_all();
+
+ arch_reset(mode, cmd);
+ local_irq_restore(flags);
+ }
+
+ /* fallback, or unhandled */
+ arm_machine_restart(mode, 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();
+ } else {
+ idcode = s3c24xx_read_idcode_v4();
+ }
+
+ arm_pm_restart = s3c24xx_pm_restart;
+
+ s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
+}
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
new file mode 100644
index 00000000..73667994
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -0,0 +1,552 @@
+/* linux/arch/arm/plat-s3c24xx/devs.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX 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/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <mach/fb.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <mach/irqs.h>
+#include <asm/irq.h>
+
+#include <plat/regs-serial.h>
+#include <plat/udc.h>
+#include <plat/mci.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/regs-spi.h>
+#include <plat/ts.h>
+
+/* Serial port registrations */
+
+static struct resource s3c2410_uart0_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART0,
+ .end = S3C2410_PA_UART0 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX0,
+ .end = IRQ_S3CUART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c2410_uart1_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART1,
+ .end = S3C2410_PA_UART1 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX1,
+ .end = IRQ_S3CUART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c2410_uart2_resource[] = {
+ [0] = {
+ .start = S3C2410_PA_UART2,
+ .end = S3C2410_PA_UART2 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX2,
+ .end = IRQ_S3CUART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s3c2410_uart3_resource[] = {
+ [0] = {
+ .start = S3C2443_PA_UART3,
+ .end = S3C2443_PA_UART3 + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3CUART_RX3,
+ .end = IRQ_S3CUART_ERR3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s3c2410_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart0_resource),
+ },
+ [1] = {
+ .resources = s3c2410_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart1_resource),
+ },
+ [2] = {
+ .resources = s3c2410_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart2_resource),
+ },
+ [3] = {
+ .resources = s3c2410_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s3c2410_uart3_resource),
+ },
+};
+
+/* LCD Controller */
+
+static struct resource s3c_lcd_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_LCD,
+ .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD,
+ .end = IRQ_LCD,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_lcd = {
+ .name = "s3c2410-lcd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_lcd_resource),
+ .resource = s3c_lcd_resource,
+ .dev = {
+ .dma_mask = &s3c_device_lcd_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_lcd);
+
+void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
+{
+ struct s3c2410fb_mach_info *npd;
+
+ npd = kmemdup(pd, sizeof(*npd), GFP_KERNEL);
+ if (npd) {
+ s3c_device_lcd.dev.platform_data = npd;
+ npd->displays = kmemdup(pd->displays,
+ sizeof(struct s3c2410fb_display) * npd->num_displays,
+ GFP_KERNEL);
+ if (!npd->displays)
+ printk(KERN_ERR "no memory for LCD display data\n");
+ } else {
+ printk(KERN_ERR "no memory for LCD platform data\n");
+ }
+}
+
+/* Touchscreen */
+
+static struct resource s3c_ts_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_ADC,
+ .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+
+};
+
+struct platform_device s3c_device_ts = {
+ .name = "s3c2410-ts",
+ .id = -1,
+ .dev.parent = &s3c_device_adc.dev,
+ .num_resources = ARRAY_SIZE(s3c_ts_resource),
+ .resource = s3c_ts_resource,
+};
+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;
+}
+
+/* USB Device (Gadget)*/
+
+static struct resource s3c_usbgadget_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_USBDEV,
+ .end = S3C24XX_PA_USBDEV + S3C24XX_SZ_USBDEV - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBD,
+ .end = IRQ_USBD,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_usbgadget = {
+ .name = "s3c2410-usbgadget",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usbgadget_resource),
+ .resource = s3c_usbgadget_resource,
+};
+
+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");
+ }
+}
+
+/* USB High Speed 2.0 Device (Gadget) */
+static struct resource s3c_hsudc_resource[] = {
+ [0] = {
+ .start = S3C2416_PA_HSUDC,
+ .end = S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBD,
+ .end = IRQ_USBD,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c_device_usb_hsudc = {
+ .name = "s3c-hsudc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_hsudc_resource),
+ .resource = s3c_hsudc_resource,
+ .dev = {
+ .dma_mask = &s3c_hsudc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+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");
+ }
+}
+
+/* IIS */
+
+static struct resource s3c_iis_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_IIS,
+ .end = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static u64 s3c_device_iis_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_iis = {
+ .name = "s3c24xx-iis",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_iis_resource),
+ .resource = s3c_iis_resource,
+ .dev = {
+ .dma_mask = &s3c_device_iis_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_iis);
+
+/* RTC */
+
+static struct resource s3c_rtc_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_RTC,
+ .end = S3C24XX_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC,
+ .end = IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_TICK,
+ .end = IRQ_TICK,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c2410-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_rtc);
+
+/* ADC */
+
+static struct resource s3c_adc_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_ADC,
+ .end = S3C24XX_PA_ADC + S3C24XX_SZ_ADC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "s3c24xx-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
+
+/* SDI */
+
+static struct resource s3c_sdi_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_SDI,
+ .end = S3C24XX_PA_SDI + S3C24XX_SZ_SDI - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SDI,
+ .end = IRQ_SDI,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+struct platform_device s3c_device_sdi = {
+ .name = "s3c2410-sdi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_sdi_resource),
+ .resource = s3c_sdi_resource,
+};
+
+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;
+}
+
+
+/* SPI (0) */
+
+static struct resource s3c_spi0_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_SPI,
+ .end = S3C24XX_PA_SPI + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPI0,
+ .end = IRQ_SPI0,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+static u64 s3c_device_spi0_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_spi0 = {
+ .name = "s3c2410-spi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_spi0_resource),
+ .resource = s3c_spi0_resource,
+ .dev = {
+ .dma_mask = &s3c_device_spi0_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_spi0);
+
+/* SPI (1) */
+
+static struct resource s3c_spi1_resource[] = {
+ [0] = {
+ .start = S3C24XX_PA_SPI + S3C2410_SPI1,
+ .end = S3C24XX_PA_SPI + S3C2410_SPI1 + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_SPI1,
+ .end = IRQ_SPI1,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+static u64 s3c_device_spi1_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_spi1 = {
+ .name = "s3c2410-spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_spi1_resource),
+ .resource = s3c_spi1_resource,
+ .dev = {
+ .dma_mask = &s3c_device_spi1_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_spi1);
+
+#ifdef CONFIG_CPU_S3C2440
+
+/* Camif Controller */
+
+static struct resource s3c_camif_resource[] = {
+ [0] = {
+ .start = S3C2440_PA_CAMIF,
+ .end = S3C2440_PA_CAMIF + S3C2440_SZ_CAMIF - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CAM,
+ .end = IRQ_CAM,
+ .flags = IORESOURCE_IRQ,
+ }
+
+};
+
+static u64 s3c_device_camif_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_camif = {
+ .name = "s3c2440-camif",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_camif_resource),
+ .resource = s3c_camif_resource,
+ .dev = {
+ .dma_mask = &s3c_device_camif_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_camif);
+
+/* AC97 */
+
+static struct resource s3c_ac97_resource[] = {
+ [0] = {
+ .start = S3C2440_PA_AC97,
+ .end = S3C2440_PA_AC97 + S3C2440_SZ_AC97 -1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S3C244x_AC97,
+ .end = IRQ_S3C244x_AC97,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "PCM out",
+ .start = DMACH_PCM_OUT,
+ .end = DMACH_PCM_OUT,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .name = "PCM in",
+ .start = DMACH_PCM_IN,
+ .end = DMACH_PCM_IN,
+ .flags = IORESOURCE_DMA,
+ },
+ [4] = {
+ .name = "Mic in",
+ .start = DMACH_MIC_IN,
+ .end = DMACH_MIC_IN,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static u64 s3c_device_audio_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_ac97 = {
+ .name = "samsung-ac97",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_ac97_resource),
+ .resource = s3c_ac97_resource,
+ .dev = {
+ .dma_mask = &s3c_device_audio_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_ac97);
+
+/* ASoC I2S */
+
+struct platform_device s3c2412_device_iis = {
+ .name = "s3c2412-iis",
+ .id = -1,
+ .dev = {
+ .dma_mask = &s3c_device_audio_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c2412_device_iis);
+
+#endif // CONFIG_CPU_S32440
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
new file mode 100644
index 00000000..0719f49d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -0,0 +1,1470 @@
+/* linux/arch/arm/plat-s3c24xx/dma.c
+ *
+ * Copyright 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 DMA core
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+#define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/syscore_ops.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <mach/map.h>
+
+#include <plat/dma-s3c24xx.h>
+#include <plat/regs-dma.h>
+
+/* io map for dma */
+static void __iomem *dma_base;
+static struct kmem_cache *dma_kmem;
+
+static int dma_channels;
+
+static struct s3c24xx_dma_selection dma_sel;
+
+
+/* debugging functions */
+
+#define BUF_MAGIC (0xcafebabe)
+
+#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
+
+#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
+
+#if 1
+#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
+#else
+static inline void
+dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
+{
+ pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
+ writel(val, dma_regaddr(chan, reg));
+}
+#endif
+
+#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
+
+/* captured register state for debug */
+
+struct s3c2410_dma_regstate {
+ unsigned long dcsrc;
+ unsigned long disrc;
+ unsigned long dstat;
+ unsigned long dcon;
+ unsigned long dmsktrig;
+};
+
+#ifdef CONFIG_S3C2410_DMA_DEBUG
+
+/* dmadbg_showregs
+ *
+ * simple debug routine to print the current state of the dma registers
+*/
+
+static void
+dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
+{
+ regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+ regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
+ regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
+ regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
+ regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+}
+
+static void
+dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
+ struct s3c2410_dma_regstate *regs)
+{
+ printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
+ chan->number, fname, line,
+ regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
+ regs->dcon);
+}
+
+static void
+dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+ struct s3c2410_dma_regstate state;
+
+ dmadbg_capture(chan, &state);
+
+ printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
+ chan->number, fname, line, chan->load_state,
+ chan->curr, chan->next, chan->end);
+
+ dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
+{
+ struct s3c2410_dma_regstate state;
+
+ dmadbg_capture(chan, &state);
+ dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+#define dbg_showregs(chan) dmadbg_showregs(__func__, __LINE__, (chan))
+#define dbg_showchan(chan) dmadbg_showchan(__func__, __LINE__, (chan))
+#else
+#define dbg_showregs(chan) do { } while(0)
+#define dbg_showchan(chan) do { } while(0)
+#endif /* CONFIG_S3C2410_DMA_DEBUG */
+
+/* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+*/
+
+static void
+s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
+{
+ if (stats == NULL)
+ return;
+
+ if (val > stats->timeout_longest)
+ stats->timeout_longest = val;
+ if (val < stats->timeout_shortest)
+ stats->timeout_shortest = val;
+
+ stats->timeout_avg += val;
+}
+
+/* s3c2410_dma_waitforload
+ *
+ * wait for the DMA engine to load a buffer, and update the state accordingly
+*/
+
+static int
+s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
+{
+ int timeout = chan->load_timeout;
+ int took;
+
+ if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
+ printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
+ return 0;
+ }
+
+ if (chan->stats != NULL)
+ chan->stats->loads++;
+
+ while (--timeout > 0) {
+ if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
+ took = chan->load_timeout - timeout;
+
+ s3c2410_dma_stats_timeout(chan->stats, took);
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1LOADED:
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
+ }
+
+ return 1;
+ }
+ }
+
+ if (chan->stats != NULL) {
+ chan->stats->timeout_failed++;
+ }
+
+ return 0;
+}
+
+/* s3c2410_dma_loadbuffer
+ *
+ * load a buffer, and update the channel state
+*/
+
+static inline int
+s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
+ struct s3c2410_dma_buf *buf)
+{
+ unsigned long reload;
+
+ if (buf == NULL) {
+ dmawarn("buffer is NULL\n");
+ return -EINVAL;
+ }
+
+ pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
+ buf, (unsigned long)buf->data, buf->size);
+
+ /* check the state of the channel before we do anything */
+
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+ dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
+ }
+
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
+ dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
+ }
+
+ /* it would seem sensible if we are the last buffer to not bother
+ * with the auto-reload bit, so that the DMA engine will not try
+ * and load another transfer after this one has finished...
+ */
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ pr_debug("load_state is none, checking for noreload (next=%p)\n",
+ buf->next);
+ reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
+ } else {
+ //pr_debug("load_state is %d => autoreload\n", chan->load_state);
+ reload = S3C2410_DCON_AUTORELOAD;
+ }
+
+ if ((buf->data & 0xf0000000) != 0x30000000) {
+ dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+ }
+
+ writel(buf->data, chan->addr_reg);
+
+ dma_wrreg(chan, S3C2410_DMA_DCON,
+ chan->dcon | reload | (buf->size/chan->xfer_unit));
+
+ chan->next = buf->next;
+
+ /* update the state of the channel */
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_NONE:
+ chan->load_state = S3C2410_DMALOAD_1LOADED;
+ break;
+
+ case S3C2410_DMALOAD_1RUNNING:
+ chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
+ break;
+
+ default:
+ dmawarn("dmaload: unknown state %d in loadbuffer\n",
+ chan->load_state);
+ break;
+ }
+
+ return 0;
+}
+
+/* s3c2410_dma_call_op
+ *
+ * small routine to call the op routine with the given op if it has been
+ * registered
+*/
+
+static void
+s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
+{
+ if (chan->op_fn != NULL) {
+ (chan->op_fn)(chan, op);
+ }
+}
+
+/* s3c2410_dma_buffdone
+ *
+ * small wrapper to check if callback routine needs to be called, and
+ * if so, call it
+*/
+
+static inline void
+s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
+ enum s3c2410_dma_buffresult result)
+{
+#if 0
+ pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
+ chan->callback_fn, buf, buf->id, buf->size, result);
+#endif
+
+ if (chan->callback_fn != NULL) {
+ (chan->callback_fn)(chan, buf->id, buf->size, result);
+ }
+}
+
+/* s3c2410_dma_start
+ *
+ * start a dma channel going
+*/
+
+static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
+{
+ unsigned long tmp;
+ unsigned long flags;
+
+ pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
+
+ local_irq_save(flags);
+
+ if (chan->state == S3C2410_DMA_RUNNING) {
+ pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
+ local_irq_restore(flags);
+ return 0;
+ }
+
+ chan->state = S3C2410_DMA_RUNNING;
+
+ /* check wether there is anything to load, and if not, see
+ * if we can find anything to load
+ */
+
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ if (chan->next == NULL) {
+ printk(KERN_ERR "dma%d: channel has nothing loaded\n",
+ chan->number);
+ chan->state = S3C2410_DMA_IDLE;
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ dbg_showchan(chan);
+
+ /* enable the channel */
+
+ if (!chan->irq_enabled) {
+ enable_irq(chan->irq);
+ chan->irq_enabled = 1;
+ }
+
+ /* start the channel going */
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+ tmp &= ~S3C2410_DMASKTRIG_STOP;
+ tmp |= S3C2410_DMASKTRIG_ON;
+ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+ pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
+
+#if 0
+ /* the dma buffer loads should take care of clearing the AUTO
+ * reloading feature */
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp &= ~S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+ s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
+
+ dbg_showchan(chan);
+
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __func__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+/* s3c2410_dma_canload
+ *
+ * work out if we can queue another buffer into the DMA engine
+*/
+
+static int
+s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
+{
+ if (chan->load_state == S3C2410_DMALOAD_NONE ||
+ chan->load_state == S3C2410_DMALOAD_1RUNNING)
+ return 1;
+
+ return 0;
+}
+
+/* s3c2410_dma_enqueue
+ *
+ * queue an given buffer for dma transfer.
+ *
+ * id the device driver's id information for this buffer
+ * data the physical address of the buffer data
+ * size the size of the buffer in bytes
+ *
+ * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
+ * is checked, and if set, the channel is started. If this flag isn't set,
+ * then an error will be returned.
+ *
+ * It is possible to queue more than one DMA buffer onto a channel at
+ * once, and the code will deal with the re-loading of the next buffer
+ * when necessary.
+*/
+
+int s3c2410_dma_enqueue(unsigned int channel, void *id,
+ dma_addr_t data, int size)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ struct s3c2410_dma_buf *buf;
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: id=%p, data=%08x, size=%d\n",
+ __func__, id, (unsigned int)data, size);
+
+ buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
+ if (buf == NULL) {
+ pr_debug("%s: out of memory (%ld alloc)\n",
+ __func__, (long)sizeof(*buf));
+ return -ENOMEM;
+ }
+
+ //pr_debug("%s: new buffer %p\n", __func__, buf);
+ //dbg_showchan(chan);
+
+ buf->next = NULL;
+ buf->data = buf->ptr = data;
+ buf->size = size;
+ buf->id = id;
+ buf->magic = BUF_MAGIC;
+
+ local_irq_save(flags);
+
+ if (chan->curr == NULL) {
+ /* we've got nothing loaded... */
+ pr_debug("%s: buffer %p queued onto empty channel\n",
+ __func__, buf);
+
+ chan->curr = buf;
+ chan->end = buf;
+ chan->next = NULL;
+ } else {
+ pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
+ chan->number, __func__, buf);
+
+ if (chan->end == NULL)
+ pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
+ chan->number, __func__, chan);
+
+ chan->end->next = buf;
+ chan->end = buf;
+ }
+
+ /* if necessary, update the next buffer field */
+ if (chan->next == NULL)
+ chan->next = buf;
+
+ /* check to see if we can load a buffer */
+ if (chan->state == S3C2410_DMA_RUNNING) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ printk(KERN_ERR "dma%d: loadbuffer:"
+ "timeout loading buffer\n",
+ chan->number);
+ dbg_showchan(chan);
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+ }
+
+ while (s3c2410_dma_canload(chan) && chan->next != NULL) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ } else if (chan->state == S3C2410_DMA_IDLE) {
+ if (chan->flags & S3C2410_DMAF_AUTOSTART) {
+ s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+ S3C2410_DMAOP_START);
+ }
+ }
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+static inline void
+s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
+{
+ int magicok = (buf->magic == BUF_MAGIC);
+
+ buf->magic = -1;
+
+ if (magicok) {
+ kmem_cache_free(dma_kmem, buf);
+ } else {
+ printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
+ }
+}
+
+/* s3c2410_dma_lastxfer
+ *
+ * called when the system is out of buffers, to ensure that the channel
+ * is prepared for shutdown.
+*/
+
+static inline void
+s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
+{
+#if 0
+ pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
+ chan->number, chan->load_state);
+#endif
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_NONE:
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ /* flag error? */
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+ chan->number, __func__);
+ return;
+ }
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ /* I believe in this case we do not have anything to do
+ * until the next buffer comes along, and we turn off the
+ * reload */
+ return;
+
+ default:
+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
+ chan->number, chan->load_state);
+ return;
+
+ }
+
+ /* hopefully this'll shut the damned thing up after the transfer... */
+ dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
+}
+
+
+#define dmadbg2(x...)
+
+static irqreturn_t
+s3c2410_dma_irq(int irq, void *devpw)
+{
+ struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
+ struct s3c2410_dma_buf *buf;
+
+ buf = chan->curr;
+
+ dbg_showchan(chan);
+
+ /* modify the channel state */
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1RUNNING:
+ /* TODO - if we are running only one buffer, we probably
+ * want to reload here, and then worry about the buffer
+ * callback */
+
+ chan->load_state = S3C2410_DMALOAD_NONE;
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ /* iirc, we should go back to NONE loaded here, we
+ * had a buffer, and it was never verified as being
+ * loaded.
+ */
+
+ chan->load_state = S3C2410_DMALOAD_NONE;
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ /* we'll worry about checking to see if another buffer is
+ * ready after we've called back the owner. This should
+ * ensure we do not wait around too long for the DMA
+ * engine to start the next transfer
+ */
+
+ chan->load_state = S3C2410_DMALOAD_1LOADED;
+ break;
+
+ case S3C2410_DMALOAD_NONE:
+ printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
+ chan->number);
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
+ chan->number, chan->load_state);
+ break;
+ }
+
+ if (buf != NULL) {
+ /* update the chain to make sure that if we load any more
+ * buffers when we call the callback function, things should
+ * work properly */
+
+ chan->curr = buf->next;
+ buf->next = NULL;
+
+ if (buf->magic != BUF_MAGIC) {
+ printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
+ chan->number, __func__, buf);
+ return IRQ_HANDLED;
+ }
+
+ s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
+
+ /* free resouces */
+ s3c2410_dma_freebuf(buf);
+ } else {
+ }
+
+ /* only reload if the channel is still running... our buffer done
+ * routine may have altered the state by requesting the dma channel
+ * to stop or shutdown... */
+
+ /* todo: check that when the channel is shut-down from inside this
+ * function, we cope with unsetting reload, etc */
+
+ if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
+ unsigned long flags;
+
+ switch (chan->load_state) {
+ case S3C2410_DMALOAD_1RUNNING:
+ /* don't need to do anything for this state */
+ break;
+
+ case S3C2410_DMALOAD_NONE:
+ /* can load buffer immediately */
+ break;
+
+ case S3C2410_DMALOAD_1LOADED:
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ /* flag error? */
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+ chan->number, __func__);
+ return IRQ_HANDLED;
+ }
+
+ break;
+
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ goto no_load;
+
+ default:
+ printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
+ chan->number, chan->load_state);
+ return IRQ_HANDLED;
+ }
+
+ local_irq_save(flags);
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ local_irq_restore(flags);
+ } else {
+ s3c2410_dma_lastxfer(chan);
+
+ /* see if we can stop this channel.. */
+ if (chan->load_state == S3C2410_DMALOAD_NONE) {
+ pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
+ chan->number, jiffies);
+ s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
+ S3C2410_DMAOP_STOP);
+ }
+ }
+
+ no_load:
+ return IRQ_HANDLED;
+}
+
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
+
+/* s3c2410_request_dma
+ *
+ * get control of an dma channel
+*/
+
+int s3c2410_dma_request(enum dma_ch channel,
+ struct s3c2410_dma_client *client,
+ void *dev)
+{
+ struct s3c2410_dma_chan *chan;
+ unsigned long flags;
+ int err;
+
+ pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
+ channel, client->name, dev);
+
+ local_irq_save(flags);
+
+ chan = s3c2410_dma_map_channel(channel);
+ if (chan == NULL) {
+ local_irq_restore(flags);
+ return -EBUSY;
+ }
+
+ dbg_showchan(chan);
+
+ chan->client = client;
+ chan->in_use = 1;
+
+ if (!chan->irq_claimed) {
+ pr_debug("dma%d: %s : requesting irq %d\n",
+ channel, __func__, chan->irq);
+
+ chan->irq_claimed = 1;
+ local_irq_restore(flags);
+
+ err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
+ client->name, (void *)chan);
+
+ local_irq_save(flags);
+
+ if (err) {
+ chan->in_use = 0;
+ chan->irq_claimed = 0;
+ local_irq_restore(flags);
+
+ printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
+ client->name, chan->irq, chan->number);
+ return err;
+ }
+
+ chan->irq_enabled = 1;
+ }
+
+ local_irq_restore(flags);
+
+ /* need to setup */
+
+ pr_debug("%s: channel initialised, %p\n", __func__, chan);
+
+ return chan->number | DMACH_LOW_LEVEL;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+/* s3c2410_dma_free
+ *
+ * release the given channel back to the system, will stop and flush
+ * any outstanding transfers, and ensure the channel is ready for the
+ * next claimant.
+ *
+ * Note, although a warning is currently printed if the freeing client
+ * info is not the same as the registrant's client info, the free is still
+ * allowed to go through.
+*/
+
+int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned long flags;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ local_irq_save(flags);
+
+ if (chan->client != client) {
+ printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
+ channel, chan->client, client);
+ }
+
+ /* sort out stopping and freeing the channel */
+
+ if (chan->state != S3C2410_DMA_IDLE) {
+ pr_debug("%s: need to stop dma channel %p\n",
+ __func__, chan);
+
+ /* possibly flush the channel */
+ s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
+ }
+
+ chan->client = NULL;
+ chan->in_use = 0;
+
+ if (chan->irq_claimed)
+ free_irq(chan->irq, (void *)chan);
+
+ chan->irq_claimed = 0;
+
+ if (!(channel & DMACH_LOW_LEVEL))
+ s3c_dma_chan_map[channel] = NULL;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
+{
+ unsigned long flags;
+ unsigned long tmp;
+
+ pr_debug("%s:\n", __func__);
+
+ dbg_showchan(chan);
+
+ local_irq_save(flags);
+
+ s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+ tmp |= S3C2410_DMASKTRIG_STOP;
+ //tmp &= ~S3C2410_DMASKTRIG_ON;
+ dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
+
+#if 0
+ /* should also clear interrupts, according to WinCE BSP */
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp |= S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+#endif
+
+ /* should stop do this, or should we wait for flush? */
+ chan->state = S3C2410_DMA_IDLE;
+ chan->load_state = S3C2410_DMALOAD_NONE;
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
+{
+ unsigned long tmp;
+ unsigned int timeout = 0x10000;
+
+ while (timeout-- > 0) {
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+ if (!(tmp & S3C2410_DMASKTRIG_ON))
+ return;
+ }
+
+ pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
+/* s3c2410_dma_flush
+ *
+ * stop the channel, and remove all current and pending transfers
+*/
+
+static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
+{
+ struct s3c2410_dma_buf *buf, *next;
+ unsigned long flags;
+
+ pr_debug("%s: chan %p (%d)\n", __func__, chan, chan->number);
+
+ dbg_showchan(chan);
+
+ local_irq_save(flags);
+
+ if (chan->state != S3C2410_DMA_IDLE) {
+ pr_debug("%s: stopping channel...\n", __func__ );
+ s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
+ }
+
+ buf = chan->curr;
+ if (buf == NULL)
+ buf = chan->next;
+
+ chan->curr = chan->next = chan->end = NULL;
+
+ if (buf != NULL) {
+ for ( ; buf != NULL; buf = next) {
+ next = buf->next;
+
+ pr_debug("%s: free buffer %p, next %p\n",
+ __func__, buf, buf->next);
+
+ s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
+ s3c2410_dma_freebuf(buf);
+ }
+ }
+
+ dbg_showregs(chan);
+
+ s3c2410_dma_waitforstop(chan);
+
+#if 0
+ /* should also clear interrupts, according to WinCE BSP */
+ {
+ unsigned long tmp;
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp |= S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+ }
+#endif
+
+ dbg_showregs(chan);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ dbg_showchan(chan);
+
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __func__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
+ local_irq_restore(flags);
+
+ return 0;
+
+}
+
+int
+s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ return s3c2410_dma_start(chan);
+
+ case S3C2410_DMAOP_STOP:
+ return s3c2410_dma_dostop(chan);
+
+ case S3C2410_DMAOP_PAUSE:
+ case S3C2410_DMAOP_RESUME:
+ return -ENOENT;
+
+ case S3C2410_DMAOP_FLUSH:
+ return s3c2410_dma_flush(chan);
+
+ case S3C2410_DMAOP_STARTED:
+ return s3c2410_dma_started(chan);
+
+ case S3C2410_DMAOP_TIMEOUT:
+ return 0;
+
+ }
+
+ return -ENOENT; /* unknown, don't bother */
+}
+
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+/* DMA configuration for each channel
+ *
+ * DISRCC -> source of the DMA (AHB,APB)
+ * DISRC -> source address of the DMA
+ * DIDSTC -> destination of the DMA (AHB,APD)
+ * DIDST -> destination address of the DMA
+*/
+
+/* s3c2410_dma_config
+ *
+ * xfersize: size of unit in bytes (1,2,4)
+*/
+
+int s3c2410_dma_config(enum dma_ch channel,
+ int xferunit)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned int dcon;
+
+ pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ dcon = chan->dcon & dma_sel.dcon_mask;
+ pr_debug("%s: dcon is %08x\n", __func__, dcon);
+
+ switch (chan->req_ch) {
+ case DMACH_I2S_IN:
+ case DMACH_I2S_OUT:
+ case DMACH_PCM_IN:
+ case DMACH_PCM_OUT:
+ case DMACH_MIC_IN:
+ default:
+ dcon |= S3C2410_DCON_HANDSHAKE;
+ dcon |= S3C2410_DCON_SYNC_PCLK;
+ break;
+
+ case DMACH_SDI:
+ /* note, ensure if need HANDSHAKE or not */
+ dcon |= S3C2410_DCON_SYNC_PCLK;
+ break;
+
+ case DMACH_XD0:
+ case DMACH_XD1:
+ dcon |= S3C2410_DCON_HANDSHAKE;
+ dcon |= S3C2410_DCON_SYNC_HCLK;
+ break;
+ }
+
+ switch (xferunit) {
+ case 1:
+ dcon |= S3C2410_DCON_BYTE;
+ break;
+
+ case 2:
+ dcon |= S3C2410_DCON_HALFWORD;
+ break;
+
+ case 4:
+ dcon |= S3C2410_DCON_WORD;
+ break;
+
+ default:
+ pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
+ return -EINVAL;
+ }
+
+ dcon |= S3C2410_DCON_HWTRIG;
+ dcon |= S3C2410_DCON_INTREQ;
+
+ pr_debug("%s: dcon now %08x\n", __func__, dcon);
+
+ chan->dcon = dcon;
+ chan->xfer_unit = xferunit;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the dma source/destination hardware type and address
+ *
+ * source: S3C2410_DMASRC_HW: source is hardware
+ * S3C2410_DMASRC_MEM: source is memory
+ *
+ * devaddr: physical address of the source
+*/
+
+int s3c2410_dma_devconfig(enum dma_ch channel,
+ enum s3c2410_dmasrc source,
+ unsigned long devaddr)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned int hwcfg;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: source=%d, devaddr=%08lx\n",
+ __func__, (int)source, devaddr);
+
+ chan->source = source;
+ chan->dev_addr = devaddr;
+
+ switch (chan->req_ch) {
+ case DMACH_XD0:
+ case DMACH_XD1:
+ hwcfg = 0; /* AHB */
+ break;
+
+ default:
+ hwcfg = S3C2410_DISRCC_APB;
+ }
+
+ /* always assume our peripheral desintation is a fixed
+ * address in memory. */
+ hwcfg |= S3C2410_DISRCC_INC;
+
+ switch (source) {
+ case S3C2410_DMASRC_HW:
+ /* source is hardware */
+ pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
+ __func__, devaddr, hwcfg);
+ dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
+ dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
+ dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
+
+ chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
+ break;
+
+ case S3C2410_DMASRC_MEM:
+ /* source is memory */
+ pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
+ __func__, devaddr, hwcfg);
+ dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
+ dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
+ dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
+
+ chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
+ break;
+
+ default:
+ printk(KERN_ERR "dma%d: invalid source type (%d)\n",
+ channel, source);
+
+ return -EINVAL;
+ }
+
+ if (dma_sel.direction != NULL)
+ (dma_sel.direction)(chan, chan->map, source);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+/* s3c2410_dma_getposition
+ *
+ * returns the current transfer points for the dma source and destination
+*/
+
+int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ if (src != NULL)
+ *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
+
+ if (dst != NULL)
+ *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+/* system core operations */
+
+#ifdef CONFIG_PM
+
+static void s3c2410_dma_suspend_chan(struct s3c2410_dma_chan *cp)
+{
+ printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
+
+ if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
+ /* the dma channel is still working, which is probably
+ * a bad thing to do over suspend/resume. We stop the
+ * channel and assume that the client is either going to
+ * retry after resume, or that it is broken.
+ */
+
+ printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
+ cp->number);
+
+ s3c2410_dma_dostop(cp);
+ }
+}
+
+static int s3c2410_dma_suspend(void)
+{
+ struct s3c2410_dma_chan *cp = s3c2410_chans;
+ int channel;
+
+ for (channel = 0; channel < dma_channels; cp++, channel++)
+ s3c2410_dma_suspend_chan(cp);
+
+ return 0;
+}
+
+static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
+{
+ unsigned int no = cp->number | DMACH_LOW_LEVEL;
+
+ /* restore channel's hardware configuration */
+
+ if (!cp->in_use)
+ return;
+
+ printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
+
+ s3c2410_dma_config(no, cp->xfer_unit);
+ s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
+
+ /* re-select the dma source for this channel */
+
+ if (cp->map != NULL)
+ dma_sel.select(cp, cp->map);
+}
+
+static void s3c2410_dma_resume(void)
+{
+ struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1;
+ int channel;
+
+ for (channel = dma_channels - 1; channel >= 0; cp--, channel--)
+ s3c2410_dma_resume_chan(cp);
+}
+
+#else
+#define s3c2410_dma_suspend NULL
+#define s3c2410_dma_resume NULL
+#endif /* CONFIG_PM */
+
+struct syscore_ops dma_syscore_ops = {
+ .suspend = s3c2410_dma_suspend,
+ .resume = s3c2410_dma_resume,
+};
+
+/* kmem cache implementation */
+
+static void s3c2410_dma_cache_ctor(void *p)
+{
+ memset(p, 0, sizeof(struct s3c2410_dma_buf));
+}
+
+/* initialisation code */
+
+static int __init s3c24xx_dma_syscore_init(void)
+{
+ register_syscore_ops(&dma_syscore_ops);
+
+ return 0;
+}
+
+late_initcall(s3c24xx_dma_syscore_init);
+
+int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+ unsigned int stride)
+{
+ struct s3c2410_dma_chan *cp;
+ int channel;
+ int ret;
+
+ printk("S3C24XX DMA Driver, Copyright 2003-2006 Simtec Electronics\n");
+
+ dma_channels = channels;
+
+ dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
+ if (dma_base == NULL) {
+ printk(KERN_ERR "dma failed to remap register block\n");
+ return -ENOMEM;
+ }
+
+ dma_kmem = kmem_cache_create("dma_desc",
+ sizeof(struct s3c2410_dma_buf), 0,
+ SLAB_HWCACHE_ALIGN,
+ s3c2410_dma_cache_ctor);
+
+ if (dma_kmem == NULL) {
+ printk(KERN_ERR "dma failed to make kmem cache\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (channel = 0; channel < channels; channel++) {
+ cp = &s3c2410_chans[channel];
+
+ memset(cp, 0, sizeof(struct s3c2410_dma_chan));
+
+ /* dma channel irqs are in order.. */
+ cp->number = channel;
+ cp->irq = channel + irq;
+ cp->regs = dma_base + (channel * stride);
+
+ /* point current stats somewhere */
+ cp->stats = &cp->stats_store;
+ cp->stats_store.timeout_shortest = LONG_MAX;
+
+ /* basic channel configuration */
+
+ cp->load_timeout = 1<<18;
+
+ printk("DMA channel %d at %p, irq %d\n",
+ cp->number, cp->regs, cp->irq);
+ }
+
+ return 0;
+
+ err:
+ kmem_cache_destroy(dma_kmem);
+ iounmap(dma_base);
+ dma_base = NULL;
+ return ret;
+}
+
+int __init s3c2410_dma_init(void)
+{
+ return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
+}
+
+static inline int is_channel_valid(unsigned int channel)
+{
+ return (channel & DMA_CH_VALID);
+}
+
+static struct s3c24xx_dma_order *dma_order;
+
+
+/* s3c2410_dma_map_channel()
+ *
+ * turn the virtual channel number into a real, and un-used hardware
+ * channel.
+ *
+ * first, try the dma ordering given to us by either the relevant
+ * dma code, or the board. Then just find the first usable free
+ * channel
+*/
+
+static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
+{
+ struct s3c24xx_dma_order_ch *ord = NULL;
+ struct s3c24xx_dma_map *ch_map;
+ struct s3c2410_dma_chan *dmach;
+ int ch;
+
+ if (dma_sel.map == NULL || channel > dma_sel.map_size)
+ return NULL;
+
+ ch_map = dma_sel.map + channel;
+
+ /* first, try the board mapping */
+
+ if (dma_order) {
+ ord = &dma_order->channels[channel];
+
+ for (ch = 0; ch < dma_channels; ch++) {
+ int tmp;
+ if (!is_channel_valid(ord->list[ch]))
+ continue;
+
+ tmp = ord->list[ch] & ~DMA_CH_VALID;
+ if (s3c2410_chans[tmp].in_use == 0) {
+ ch = tmp;
+ goto found;
+ }
+ }
+
+ if (ord->flags & DMA_CH_NEVER)
+ return NULL;
+ }
+
+ /* second, search the channel map for first free */
+
+ for (ch = 0; ch < dma_channels; ch++) {
+ if (!is_channel_valid(ch_map->channels[ch]))
+ continue;
+
+ if (s3c2410_chans[ch].in_use == 0) {
+ printk("mapped channel %d to %d\n", channel, ch);
+ break;
+ }
+ }
+
+ if (ch >= dma_channels)
+ return NULL;
+
+ /* update our channel mapping */
+
+ found:
+ dmach = &s3c2410_chans[ch];
+ dmach->map = ch_map;
+ dmach->req_ch = channel;
+ s3c_dma_chan_map[channel] = dmach;
+
+ /* select the channel */
+
+ (dma_sel.select)(dmach, ch_map);
+
+ return dmach;
+}
+
+static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
+{
+ return 0;
+}
+
+int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
+{
+ struct s3c24xx_dma_map *nmap;
+ size_t map_sz = sizeof(*nmap) * sel->map_size;
+ int ptr;
+
+ nmap = kmalloc(map_sz, GFP_KERNEL);
+ if (nmap == NULL)
+ return -ENOMEM;
+
+ memcpy(nmap, sel->map, map_sz);
+ memcpy(&dma_sel, sel, sizeof(*sel));
+
+ dma_sel.map = nmap;
+
+ for (ptr = 0; ptr < sel->map_size; ptr++)
+ s3c24xx_dma_check_entry(nmap+ptr, ptr);
+
+ return 0;
+}
+
+int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
+{
+ struct s3c24xx_dma_order *nord = dma_order;
+
+ if (nord == NULL)
+ nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
+
+ if (nord == NULL) {
+ printk(KERN_ERR "no memory to store dma channel order\n");
+ return -ENOMEM;
+ }
+
+ dma_order = nord;
+ memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
new file mode 100644
index 00000000..2f3d7c08
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -0,0 +1,96 @@
+/* linux/arch/arm/plat-s3c24xx/gpio.c
+ *
+ * Copyright (c) 2004-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX GPIO support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio-fns.h>
+#include <asm/irq.h>
+
+#include <mach/regs-gpio.h>
+
+#include <plat/gpio-core.h>
+
+/* gpiolib wrappers until these are totally eliminated */
+
+void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
+{
+ int ret;
+
+ WARN_ON(to); /* should be none of these left */
+
+ if (!to) {
+ /* if pull is enabled, try first with up, and if that
+ * fails, try using down */
+
+ ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP);
+ if (ret)
+ s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN);
+ } else {
+ s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE);
+ }
+}
+EXPORT_SYMBOL(s3c2410_gpio_pullup);
+
+void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
+{
+ /* do this via gpiolib until all users removed */
+
+ gpio_request(pin, "temporary");
+ gpio_set_value(pin, to);
+ gpio_free(pin);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_setpin);
+
+unsigned int s3c2410_gpio_getpin(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long offs = pin - chip->chip.base;
+
+ return __raw_readl(chip->base + 0x04) & (1<< offs);
+}
+
+EXPORT_SYMBOL(s3c2410_gpio_getpin);
+
+unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
+{
+ unsigned long flags;
+ unsigned long misccr;
+
+ local_irq_save(flags);
+ misccr = __raw_readl(S3C24XX_MISCCR);
+ misccr &= ~clear;
+ misccr ^= change;
+ __raw_writel(misccr, S3C24XX_MISCCR);
+ local_irq_restore(flags);
+
+ return misccr;
+}
+
+EXPORT_SYMBOL(s3c2410_modify_misccr);
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c
new file mode 100644
index 00000000..243b6411
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/gpiolib.c
@@ -0,0 +1,229 @@
+/* linux/arch/arm/plat-s3c24xx/gpiolib.c
+ *
+ * Copyright (c) 2008-2010 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <plat/pm.h>
+
+#include <mach/regs-gpio.h>
+
+static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
+{
+ return -EINVAL;
+}
+
+static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ local_irq_save(flags);
+
+ con = __raw_readl(base + 0x00);
+ dat = __raw_readl(base + 0x04);
+
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+
+ __raw_writel(dat, base + 0x04);
+
+ con &= ~(1 << offset);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ local_irq_restore(flags);
+ return 0;
+}
+
+static int s3c24xx_gpiolib_bankf_toirq(struct gpio_chip *chip, unsigned offset)
+{
+ if (offset < 4)
+ return IRQ_EINT0 + offset;
+
+ if (offset < 8)
+ return IRQ_EINT4 + offset - 4;
+
+ return -EINVAL;
+}
+
+static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = {
+ .set_config = s3c_gpio_setcfg_s3c24xx_a,
+ .get_config = s3c_gpio_getcfg_s3c24xx_a,
+};
+
+struct s3c_gpio_cfg s3c24xx_gpiocfg_default = {
+ .set_config = s3c_gpio_setcfg_s3c24xx,
+ .get_config = s3c_gpio_getcfg_s3c24xx,
+};
+
+struct s3c_gpio_chip s3c24xx_gpios[] = {
+ [0] = {
+ .base = S3C2410_GPACON,
+ .pm = __gpio_pm(&s3c_gpio_pm_1bit),
+ .config = &s3c24xx_gpiocfg_banka,
+ .chip = {
+ .base = S3C2410_GPA(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOA",
+ .ngpio = 24,
+ .direction_input = s3c24xx_gpiolib_banka_input,
+ .direction_output = s3c24xx_gpiolib_banka_output,
+ },
+ },
+ [1] = {
+ .base = S3C2410_GPBCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPB(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOB",
+ .ngpio = 16,
+ },
+ },
+ [2] = {
+ .base = S3C2410_GPCCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPC(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOC",
+ .ngpio = 16,
+ },
+ },
+ [3] = {
+ .base = S3C2410_GPDCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPD(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOD",
+ .ngpio = 16,
+ },
+ },
+ [4] = {
+ .base = S3C2410_GPECON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPE(0),
+ .label = "GPIOE",
+ .owner = THIS_MODULE,
+ .ngpio = 16,
+ },
+ },
+ [5] = {
+ .base = S3C2410_GPFCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPF(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOF",
+ .ngpio = 8,
+ .to_irq = s3c24xx_gpiolib_bankf_toirq,
+ },
+ },
+ [6] = {
+ .base = S3C2410_GPGCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .irq_base = IRQ_EINT8,
+ .chip = {
+ .base = S3C2410_GPG(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOG",
+ .ngpio = 16,
+ .to_irq = samsung_gpiolib_to_irq,
+ },
+ }, {
+ .base = S3C2410_GPHCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPH(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOH",
+ .ngpio = 11,
+ },
+ },
+ /* GPIOS for the S3C2443 and later devices. */
+ {
+ .base = S3C2440_GPJCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPJ(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOJ",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPKCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPK(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOK",
+ .ngpio = 16,
+ },
+ }, {
+ .base = S3C2443_GPLCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPL(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOL",
+ .ngpio = 15,
+ },
+ }, {
+ .base = S3C2443_GPMCON,
+ .pm = __gpio_pm(&s3c_gpio_pm_2bit),
+ .chip = {
+ .base = S3C2410_GPM(0),
+ .owner = THIS_MODULE,
+ .label = "GPIOM",
+ .ngpio = 2,
+ },
+ },
+};
+
+
+static __init int s3c24xx_gpiolib_init(void)
+{
+ struct s3c_gpio_chip *chip = s3c24xx_gpios;
+ int gpn;
+
+ for (gpn = 0; gpn < ARRAY_SIZE(s3c24xx_gpios); gpn++, chip++) {
+ if (!chip->config)
+ chip->config = &s3c24xx_gpiocfg_default;
+
+ s3c_gpiolib_add(chip);
+ }
+
+ return 0;
+}
+
+core_initcall(s3c24xx_gpiolib_init);
diff --git a/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h b/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
new file mode 100644
index 00000000..a087de21
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
@@ -0,0 +1,55 @@
+/* linux/arch/arm/plat-s3c24xx/include/mach/pwm-clock.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - pwm clock and timer support
+ */
+
+/**
+ * pwm_cfg_src_is_tclk() - return whether the given mux config is a tclk
+ * @cfg: The timer TCFG1 register bits shifted down to 0.
+ *
+ * Return true if the given configuration from TCFG1 is a TCLK instead
+ * any of the TDIV clocks.
+ */
+static inline int pwm_cfg_src_is_tclk(unsigned long tcfg)
+{
+ return tcfg == S3C2410_TCFG1_MUX_TCLK;
+}
+
+/**
+ * tcfg_to_divisor() - convert tcfg1 setting to a divisor
+ * @tcfg1: The tcfg1 setting, shifted down.
+ *
+ * Get the divisor value for the given tcfg1 setting. We assume the
+ * caller has already checked to see if this is not a TCLK source.
+ */
+static inline unsigned long tcfg_to_divisor(unsigned long tcfg1)
+{
+ return 1 << (1 + tcfg1);
+}
+
+/**
+ * pwm_tdiv_has_div1() - does the tdiv setting have a /1
+ *
+ * Return true if we have a /1 in the tdiv setting.
+ */
+static inline unsigned int pwm_tdiv_has_div1(void)
+{
+ return 0;
+}
+
+/**
+ * pwm_tdiv_div_bits() - calculate TCFG1 divisor value.
+ * @div: The divisor to calculate the bit information for.
+ *
+ * Turn a divisor into the necessary bit field for TCFG1.
+ */
+static inline unsigned long pwm_tdiv_div_bits(unsigned int div)
+{
+ return ilog2(div) - 1;
+}
+
+#define S3C_TCFG1_MUX_TCLK S3C2410_TCFG1_MUX_TCLK
diff --git a/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h b/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
new file mode 100644
index 00000000..de5e88fd
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
@@ -0,0 +1,37 @@
+/* arch/arm/plat-s3c24xx/include/plat/audio-simtec.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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.
+ *
+ * Simtec Audio support.
+*/
+
+/**
+ * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
+ * @use_mpllin: Select codec clock from MPLLin
+ * @output_cdclk: Need to output CDCLK to the codec
+ * @have_mic: Set if we have a MIC socket
+ * @have_lout: Set if we have a LineOut socket
+ * @amp_gpio: GPIO pin to enable the AMP
+ * @amp_gain: Option GPIO to control AMP gain
+ */
+struct s3c24xx_audio_simtec_pdata {
+ unsigned int use_mpllin:1;
+ unsigned int output_cdclk:1;
+
+ unsigned int have_mic:1;
+ unsigned int have_lout:1;
+
+ int amp_gpio;
+ int amp_gain[2];
+
+ void (*startup)(void);
+};
+
+extern int simtec_audio_add(const char *codec_name, bool has_lr_routing,
+ struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c24xx/include/plat/common-smdk.h b/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
new file mode 100644
index 00000000..58d9094c
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
@@ -0,0 +1,15 @@
+/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void smdk_machine_init(void);
diff --git a/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
new file mode 100644
index 00000000..d623235a
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu-freq-core.h
@@ -0,0 +1,287 @@
+/* arch/arm/plat-s3c/include/plat/cpu-freq.h
+ *
+ * Copyright (c) 2006-2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - core 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 <plat/cpu-freq.h>
+
+struct seq_file;
+
+#define MAX_BANKS (8)
+#define S3C2412_MAX_IO (8)
+
+/**
+ * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
+ * @bankcon: The cached version of settings in this structure.
+ * @tacp:
+ * @tacs: Time from address valid to nCS asserted.
+ * @tcos: Time from nCS asserted to nOE or nWE asserted.
+ * @tacc: Time that nOE or nWE is asserted.
+ * @tcoh: Time nCS is held after nOE or nWE are released.
+ * @tcah: Time address is held for after
+ * @nwait_en: Whether nWAIT is enabled for this bank.
+ *
+ * This structure represents the IO timings for a S3C2410 style IO bank
+ * used by the CPU frequency support if it needs to change the settings
+ * of the IO.
+ */
+struct s3c2410_iobank_timing {
+ unsigned long bankcon;
+ unsigned int tacp;
+ unsigned int tacs;
+ unsigned int tcos;
+ unsigned int tacc;
+ unsigned int tcoh; /* nCS hold afrer nOE/nWE */
+ unsigned int tcah; /* Address hold after nCS */
+ unsigned char nwait_en; /* nWait enabled for bank. */
+};
+
+/**
+ * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
+ * @idcy: The idle cycle time between transactions.
+ * @wstrd: nCS release to end of read cycle.
+ * @wstwr: nCS release to end of write cycle.
+ * @wstoen: nCS assertion to nOE assertion time.
+ * @wstwen: nCS assertion to nWE assertion time.
+ * @wstbrd: Burst ready delay.
+ * @smbidcyr: Register cache for smbidcyr value.
+ * @smbwstrd: Register cache for smbwstrd value.
+ * @smbwstwr: Register cache for smbwstwr value.
+ * @smbwstoen: Register cache for smbwstoen value.
+ * @smbwstwen: Register cache for smbwstwen value.
+ * @smbwstbrd: Register cache for smbwstbrd value.
+ *
+ * Timing information for a IO bank on an S3C2412 or similar system which
+ * uses a PL093 block.
+ */
+struct s3c2412_iobank_timing {
+ unsigned int idcy;
+ unsigned int wstrd;
+ unsigned int wstwr;
+ unsigned int wstoen;
+ unsigned int wstwen;
+ unsigned int wstbrd;
+
+ /* register cache */
+ unsigned char smbidcyr;
+ unsigned char smbwstrd;
+ unsigned char smbwstwr;
+ unsigned char smbwstoen;
+ unsigned char smbwstwen;
+ unsigned char smbwstbrd;
+};
+
+union s3c_iobank {
+ struct s3c2410_iobank_timing *io_2410;
+ struct s3c2412_iobank_timing *io_2412;
+};
+
+/**
+ * struct s3c_iotimings - Chip IO timings holder
+ * @bank: The timings for each IO bank.
+ */
+struct s3c_iotimings {
+ union s3c_iobank bank[MAX_BANKS];
+};
+
+/**
+ * struct s3c_plltab - PLL table information.
+ * @vals: List of PLL values.
+ * @size: Size of the PLL table @vals.
+ */
+struct s3c_plltab {
+ struct s3c_pllval *vals;
+ int size;
+};
+
+/**
+ * struct s3c_cpufreq_config - current cpu frequency configuration
+ * @freq: The current settings for the core clocks.
+ * @max: Maxium settings, derived from core, board and user settings.
+ * @pll: The PLL table entry for the current PLL settings.
+ * @divs: The divisor settings for the core clocks.
+ * @info: The current core driver information.
+ * @board: The information for the board we are running on.
+ * @lock_pll: Set if the PLL settings cannot be changed.
+ *
+ * This is for the core drivers that need to know information about
+ * the current settings and values. It should not be needed by any
+ * device drivers.
+*/
+struct s3c_cpufreq_config {
+ struct s3c_freq freq;
+ struct s3c_freq max;
+ struct cpufreq_frequency_table pll;
+ struct s3c_clkdivs divs;
+ struct s3c_cpufreq_info *info; /* for core, not drivers */
+ struct s3c_cpufreq_board *board;
+
+ unsigned int lock_pll:1;
+};
+
+/**
+ * struct s3c_cpufreq_info - Information for the CPU frequency driver.
+ * @name: The name of this implementation.
+ * @max: The maximum frequencies for the system.
+ * @latency: Transition latency to give to cpufreq.
+ * @locktime_m: The lock-time in uS for the MPLL.
+ * @locktime_u: The lock-time in uS for the UPLL.
+ * @locttime_bits: The number of bits each LOCKTIME field.
+ * @need_pll: Set if this driver needs to change the PLL values to achieve
+ * any frequency changes. This is really only need by devices like the
+ * S3C2410 where there is no or limited divider between the PLL and the
+ * ARMCLK.
+ * @resume_clocks: Update the clocks on resume.
+ * @get_iotiming: Get the current IO timing data, mainly for use at start.
+ * @set_iotiming: Update the IO timings from the cached copies calculated
+ * from the @calc_iotiming entry when changing the frequency.
+ * @calc_iotiming: Calculate and update the cached copies of the IO timings
+ * from the newly calculated frequencies.
+ * @calc_freqtable: Calculate (fill in) the given frequency table from the
+ * current frequency configuration. If the table passed in is NULL,
+ * then the return is the number of elements to be filled for allocation
+ * of the table.
+ * @set_refresh: Set the memory refresh configuration.
+ * @set_fvco: Set the PLL frequencies.
+ * @set_divs: Update the clock divisors.
+ * @calc_divs: Calculate the clock divisors.
+ */
+struct s3c_cpufreq_info {
+ const char *name;
+ struct s3c_freq max;
+
+ unsigned int latency;
+
+ unsigned int locktime_m;
+ unsigned int locktime_u;
+ unsigned char locktime_bits;
+
+ unsigned int need_pll:1;
+
+ /* driver routines */
+
+ void (*resume_clocks)(void);
+
+ int (*get_iotiming)(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+ void (*set_iotiming)(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+ int (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+ int (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
+ struct cpufreq_frequency_table *t,
+ size_t table_size);
+
+ void (*debug_io_show)(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob);
+
+ void (*set_refresh)(struct s3c_cpufreq_config *cfg);
+ void (*set_fvco)(struct s3c_cpufreq_config *cfg);
+ void (*set_divs)(struct s3c_cpufreq_config *cfg);
+ int (*calc_divs)(struct s3c_cpufreq_config *cfg);
+};
+
+extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
+
+extern int s3c_plltab_register(struct cpufreq_frequency_table *plls, unsigned int plls_no);
+
+/* exports and utilities for debugfs */
+extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
+extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
+
+extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob);
+
+extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
+#define s3c_cpufreq_debugfs_call(x) x
+#else
+#define s3c_cpufreq_debugfs_call(x) NULL
+#endif
+
+/* Useful utility functions. */
+
+extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
+
+/* S3C2410 and compatible exported functions */
+
+extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
+extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
+
+#ifdef CONFIG_S3C2410_IOTIMING
+extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot);
+
+extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot);
+#else
+#define s3c2410_iotiming_calc NULL
+#define s3c2410_iotiming_get NULL
+#define s3c2410_iotiming_set NULL
+#endif /* CONFIG_S3C2410_IOTIMING */
+
+/* S3C2412 compatible routines */
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings);
+
+extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot);
+
+extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot);
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG
+#define s3c_freq_dbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */
+
+#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG
+#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
+#else
+#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
+#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */
+
+static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
+ int index, size_t table_size,
+ unsigned int freq)
+{
+ if (index < 0)
+ return index;
+
+ if (table) {
+ if (index >= table_size)
+ return -ENOMEM;
+
+ s3c_freq_dbg("%s: { %d = %u kHz }\n",
+ __func__, index, freq);
+
+ table[index].index = index;
+ table[index].frequency = freq;
+ }
+
+ return index + 1;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/fiq.h b/arch/arm/plat-s3c24xx/include/plat/fiq.h
new file mode 100644
index 00000000..8521b837
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/fiq.h
@@ -0,0 +1,13 @@
+/* linux/include/asm-arm/plat-s3c24xx/fiq.h
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU FIQ 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.
+*/
+
+extern int s3c24xx_set_fiq(unsigned int irq, bool on);
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
new file mode 100644
index 00000000..ec087d60
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -0,0 +1,115 @@
+/* linux/include/asm-arm/plat-s3c24xx/irq.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX CPU IRQ 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 <mach/hardware.h>
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
+
+#define irqdbf(x...)
+#define irqdbf2(x...)
+
+#define EXTINT_OFF (IRQ_EINT4 - 4)
+
+/* these are exported for arch/arm/mach-* usage */
+extern struct irq_chip s3c_irq_level_chip;
+extern struct irq_chip s3c_irq_chip;
+
+static inline void
+s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit,
+ int subcheck)
+{
+ unsigned long mask;
+ unsigned long submask;
+
+ submask = __raw_readl(S3C2410_INTSUBMSK);
+ mask = __raw_readl(S3C2410_INTMSK);
+
+ submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
+
+ /* check to see if we need to mask the parent IRQ */
+
+ if ((submask & subcheck) == subcheck) {
+ __raw_writel(mask | parentbit, S3C2410_INTMSK);
+ }
+
+ /* write back masks */
+ __raw_writel(submask, S3C2410_INTSUBMSK);
+
+}
+
+static inline void
+s3c_irqsub_unmask(unsigned int irqno, unsigned int parentbit)
+{
+ unsigned long mask;
+ unsigned long submask;
+
+ submask = __raw_readl(S3C2410_INTSUBMSK);
+ mask = __raw_readl(S3C2410_INTMSK);
+
+ submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
+ mask &= ~parentbit;
+
+ /* write back masks */
+ __raw_writel(submask, S3C2410_INTSUBMSK);
+ __raw_writel(mask, S3C2410_INTMSK);
+}
+
+
+static inline void
+s3c_irqsub_maskack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+ unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+ s3c_irqsub_mask(irqno, parentmask, group);
+
+ __raw_writel(bit, S3C2410_SUBSRCPND);
+
+ /* only ack parent if we've got all the irqs (seems we must
+ * ack, all and hope that the irq system retriggers ok when
+ * the interrupt goes off again)
+ */
+
+ if (1) {
+ __raw_writel(parentmask, S3C2410_SRCPND);
+ __raw_writel(parentmask, S3C2410_INTPND);
+ }
+}
+
+static inline void
+s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
+{
+ unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
+
+ __raw_writel(bit, S3C2410_SUBSRCPND);
+
+ /* only ack parent if we've got all the irqs (seems we must
+ * ack, all and hope that the irq system retriggers ok when
+ * the interrupt goes off again)
+ */
+
+ if (1) {
+ __raw_writel(parentmask, S3C2410_SRCPND);
+ __raw_writel(parentmask, S3C2410_INTPND);
+ }
+}
+
+/* exported for use in arch/arm/mach-s3c2410 */
+
+#ifdef CONFIG_PM
+extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
+#else
+#define s3c_irq_wake NULL
+#endif
+
+extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-s3c24xx/include/plat/map.h b/arch/arm/plat-s3c24xx/include/plat/map.h
new file mode 100644
index 00000000..bd534d32
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/map.h
@@ -0,0 +1,100 @@
+/* linux/include/asm-arm/plat-s3c24xx/map.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX - 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_PLAT_S3C24XX_MAP_H
+#define __ASM_PLAT_S3C24XX_MAP_H
+
+/* interrupt controller is the first thing we put in, to make
+ * the assembly code for the irq detection easier
+ */
+#define S3C24XX_VA_IRQ S3C_VA_IRQ
+#define S3C2410_PA_IRQ (0x4A000000)
+#define S3C24XX_SZ_IRQ SZ_1M
+
+/* memory controller registers */
+#define S3C24XX_VA_MEMCTRL S3C_VA_MEM
+#define S3C2410_PA_MEMCTRL (0x48000000)
+#define S3C24XX_SZ_MEMCTRL SZ_1M
+
+/* UARTs */
+#define S3C24XX_VA_UART S3C_VA_UART
+#define S3C2410_PA_UART (0x50000000)
+#define S3C24XX_SZ_UART SZ_1M
+#define S3C_UART_OFFSET (0x4000)
+
+#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET)))
+
+/* Timers */
+#define S3C24XX_VA_TIMER S3C_VA_TIMER
+#define S3C2410_PA_TIMER (0x51000000)
+#define S3C24XX_SZ_TIMER SZ_1M
+
+/* Clock and Power management */
+#define S3C24XX_VA_CLKPWR S3C_VA_SYS
+#define S3C24XX_SZ_CLKPWR SZ_1M
+
+/* USB Device port */
+#define S3C2410_PA_USBDEV (0x52000000)
+#define S3C24XX_SZ_USBDEV SZ_1M
+
+/* Watchdog */
+#define S3C24XX_VA_WATCHDOG S3C_VA_WATCHDOG
+#define S3C2410_PA_WATCHDOG (0x53000000)
+#define S3C24XX_SZ_WATCHDOG SZ_1M
+
+/* Standard size definitions for peripheral blocks. */
+
+#define S3C24XX_SZ_IIS SZ_1M
+#define S3C24XX_SZ_ADC SZ_1M
+#define S3C24XX_SZ_SPI SZ_1M
+#define S3C24XX_SZ_SDI SZ_1M
+#define S3C24XX_SZ_NAND SZ_1M
+
+/* GPIO ports */
+
+/* the calculation for the VA of this must ensure that
+ * it is the same distance apart from the UART in the
+ * phsyical address space, as the initial mapping for the IO
+ * is done as a 1:1 mapping. This puts it (currently) at
+ * 0xFA800000, which is not in the way of any current mapping
+ * by the base system.
+*/
+
+#define S3C2410_PA_GPIO (0x56000000)
+#define S3C24XX_VA_GPIO ((S3C24XX_PA_GPIO - S3C24XX_PA_UART) + S3C24XX_VA_UART)
+#define S3C24XX_SZ_GPIO SZ_1M
+
+
+/* ISA style IO, for each machine to sort out mappings for, if it
+ * implements it. We reserve two 16M regions for ISA.
+ */
+
+#define S3C24XX_VA_ISA_WORD S3C2410_ADDR(0x02000000)
+#define S3C24XX_VA_ISA_BYTE S3C2410_ADDR(0x03000000)
+
+/* deal with the registers that move under the 2412/2413 */
+
+#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
+#ifndef __ASSEMBLY__
+extern void __iomem *s3c24xx_va_gpio2;
+#endif
+#ifdef CONFIG_CPU_S3C2412_ONLY
+#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10)
+#else
+#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
+#endif
+#else
+#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
+#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
+#endif
+
+#endif /* __ASM_PLAT_S3C24XX_MAP_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
new file mode 100644
index 00000000..2ac2b21e
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/mci.h
@@ -0,0 +1,52 @@
+#ifndef _ARCH_MCI_H
+#define _ARCH_MCI_H
+
+/**
+ * struct s3c24xx_mci_pdata - sd/mmc controller platform data
+ * @no_wprotect: Set this to indicate there is no write-protect switch.
+ * @no_detect: Set this if there is no detect switch.
+ * @wprotect_invert: Invert the default sense of the write protect switch.
+ * @detect_invert: Invert the default sense of the write protect switch.
+ * @use_dma: Set to allow the use of DMA.
+ * @gpio_detect: GPIO number for the card detect line.
+ * @gpio_wprotect: GPIO number for the write protect line.
+ * @ocr_avail: The mask of the available power states, non-zero to use.
+ * @set_power: Callback to control the power mode.
+ *
+ * The @gpio_detect is used for card detection when @no_wprotect is unset,
+ * and the default sense is that 0 returned from gpio_get_value() means
+ * that a card is inserted. If @detect_invert is set, then the value from
+ * gpio_get_value() is inverted, which makes 1 mean card inserted.
+ *
+ * The driver will use @gpio_wprotect to signal whether the card is write
+ * protected if @no_wprotect is not set. A 0 returned from gpio_get_value()
+ * means the card is read/write, and 1 means read-only. The @wprotect_invert
+ * will invert the value returned from gpio_get_value().
+ *
+ * Card power is set by @ocr_availa, using MCC_VDD_ constants if it is set
+ * to a non-zero value, otherwise the default of 3.2-3.4V is used.
+ */
+struct s3c24xx_mci_pdata {
+ unsigned int no_wprotect : 1;
+ unsigned int no_detect : 1;
+ unsigned int wprotect_invert : 1;
+ unsigned int detect_invert : 1; /* set => detect active high. */
+ unsigned int use_dma : 1;
+
+ unsigned int gpio_detect;
+ unsigned int gpio_wprotect;
+ unsigned long ocr_avail;
+ void (*set_power)(unsigned char power_mode,
+ unsigned short vdd);
+};
+
+/**
+ * s3c24xx_mci_set_platdata - set platform data for mmc/sdi device
+ * @pdata: The platform data
+ *
+ * Copy the platform data supplied by @pdata so that this can be marked
+ * __initdata.
+ */
+extern void s3c24xx_mci_set_platdata(struct s3c24xx_mci_pdata *pdata);
+
+#endif /* _ARCH_NCI_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/pll.h b/arch/arm/plat-s3c24xx/include/plat/pll.h
new file mode 100644
index 00000000..005729a1
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/pll.h
@@ -0,0 +1,62 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/pll.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24xx - common pll registers and code
+ */
+
+#define S3C24XX_PLLCON_MDIVSHIFT 12
+#define S3C24XX_PLLCON_PDIVSHIFT 4
+#define S3C24XX_PLLCON_SDIVSHIFT 0
+#define S3C24XX_PLLCON_MDIVMASK ((1<<(1+(19-12)))-1)
+#define S3C24XX_PLLCON_PDIVMASK ((1<<5)-1)
+#define S3C24XX_PLLCON_SDIVMASK 3
+
+#include <asm/div64.h>
+
+static inline unsigned int
+s3c24xx_get_pll(unsigned int pllval, unsigned int baseclk)
+{
+ unsigned int mdiv, pdiv, sdiv;
+ uint64_t fvco;
+
+ mdiv = pllval >> S3C24XX_PLLCON_MDIVSHIFT;
+ pdiv = pllval >> S3C24XX_PLLCON_PDIVSHIFT;
+ sdiv = pllval >> S3C24XX_PLLCON_SDIVSHIFT;
+
+ mdiv &= S3C24XX_PLLCON_MDIVMASK;
+ pdiv &= S3C24XX_PLLCON_PDIVMASK;
+ sdiv &= S3C24XX_PLLCON_SDIVMASK;
+
+ fvco = (uint64_t)baseclk * (mdiv + 8);
+ do_div(fvco, (pdiv + 2) << sdiv);
+
+ return (unsigned int)fvco;
+}
+
+#define S3C2416_PLL_M_SHIFT (14)
+#define S3C2416_PLL_P_SHIFT (5)
+#define S3C2416_PLL_S_MASK (7)
+#define S3C2416_PLL_M_MASK ((1 << 10) - 1)
+#define S3C2416_PLL_P_MASK (63)
+
+static inline unsigned int
+s3c2416_get_pll(unsigned int pllval, unsigned int baseclk)
+{
+ unsigned int m, p, s;
+ uint64_t fvco;
+
+ m = pllval >> S3C2416_PLL_M_SHIFT;
+ p = pllval >> S3C2416_PLL_P_SHIFT;
+
+ s = pllval & S3C2416_PLL_S_MASK;
+ m &= S3C2416_PLL_M_MASK;
+ p &= S3C2416_PLL_P_MASK;
+
+ fvco = (uint64_t)baseclk * m;
+ do_div(fvco, (p << s));
+
+ return (unsigned int)fvco;
+}
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-dma.h b/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
new file mode 100644
index 00000000..1b0f4c36
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
@@ -0,0 +1,145 @@
+/* arch/arm/mach-s3c2410/include/mach/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA 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.
+*/
+
+/* DMA Register definitions */
+
+#define S3C2410_DMA_DISRC (0x00)
+#define S3C2410_DMA_DISRCC (0x04)
+#define S3C2410_DMA_DIDST (0x08)
+#define S3C2410_DMA_DIDSTC (0x0C)
+#define S3C2410_DMA_DCON (0x10)
+#define S3C2410_DMA_DSTAT (0x14)
+#define S3C2410_DMA_DCSRC (0x18)
+#define S3C2410_DMA_DCDST (0x1C)
+#define S3C2410_DMA_DMASKTRIG (0x20)
+#define S3C2412_DMA_DMAREQSEL (0x24)
+#define S3C2443_DMA_DMAREQSEL (0x24)
+
+#define S3C2410_DISRCC_INC (1<<0)
+#define S3C2410_DISRCC_APB (1<<1)
+
+#define S3C2410_DMASKTRIG_STOP (1<<2)
+#define S3C2410_DMASKTRIG_ON (1<<1)
+#define S3C2410_DMASKTRIG_SWTRIG (1<<0)
+
+#define S3C2410_DCON_DEMAND (0<<31)
+#define S3C2410_DCON_HANDSHAKE (1<<31)
+#define S3C2410_DCON_SYNC_PCLK (0<<30)
+#define S3C2410_DCON_SYNC_HCLK (1<<30)
+
+#define S3C2410_DCON_INTREQ (1<<29)
+
+#define S3C2410_DCON_CH0_XDREQ0 (0<<24)
+#define S3C2410_DCON_CH0_UART0 (1<<24)
+#define S3C2410_DCON_CH0_SDI (2<<24)
+#define S3C2410_DCON_CH0_TIMER (3<<24)
+#define S3C2410_DCON_CH0_USBEP1 (4<<24)
+
+#define S3C2410_DCON_CH1_XDREQ1 (0<<24)
+#define S3C2410_DCON_CH1_UART1 (1<<24)
+#define S3C2410_DCON_CH1_I2SSDI (2<<24)
+#define S3C2410_DCON_CH1_SPI (3<<24)
+#define S3C2410_DCON_CH1_USBEP2 (4<<24)
+
+#define S3C2410_DCON_CH2_I2SSDO (0<<24)
+#define S3C2410_DCON_CH2_I2SSDI (1<<24)
+#define S3C2410_DCON_CH2_SDI (2<<24)
+#define S3C2410_DCON_CH2_TIMER (3<<24)
+#define S3C2410_DCON_CH2_USBEP3 (4<<24)
+
+#define S3C2410_DCON_CH3_UART2 (0<<24)
+#define S3C2410_DCON_CH3_SDI (1<<24)
+#define S3C2410_DCON_CH3_SPI (2<<24)
+#define S3C2410_DCON_CH3_TIMER (3<<24)
+#define S3C2410_DCON_CH3_USBEP4 (4<<24)
+
+#define S3C2410_DCON_SRCSHIFT (24)
+#define S3C2410_DCON_SRCMASK (7<<24)
+
+#define S3C2410_DCON_BYTE (0<<20)
+#define S3C2410_DCON_HALFWORD (1<<20)
+#define S3C2410_DCON_WORD (2<<20)
+
+#define S3C2410_DCON_AUTORELOAD (0<<22)
+#define S3C2410_DCON_NORELOAD (1<<22)
+#define S3C2410_DCON_HWTRIG (1<<23)
+
+#ifdef CONFIG_CPU_S3C2440
+#define S3C2440_DIDSTC_CHKINT (1<<2)
+
+#define S3C2440_DCON_CH0_I2SSDO (5<<24)
+#define S3C2440_DCON_CH0_PCMIN (6<<24)
+
+#define S3C2440_DCON_CH1_PCMOUT (5<<24)
+#define S3C2440_DCON_CH1_SDI (6<<24)
+
+#define S3C2440_DCON_CH2_PCMIN (5<<24)
+#define S3C2440_DCON_CH2_MICIN (6<<24)
+
+#define S3C2440_DCON_CH3_MICIN (5<<24)
+#define S3C2440_DCON_CH3_PCMOUT (6<<24)
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+
+#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1)
+
+#define S3C2412_DMAREQSEL_HW (1)
+
+#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0)
+#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1)
+#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2)
+#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3)
+#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4)
+#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5)
+#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9)
+#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10)
+#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13)
+#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14)
+#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15)
+#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16)
+#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17)
+#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18)
+#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19)
+#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20)
+#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21)
+#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
+#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
+#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
+
+#endif
+
+#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1)
+
+#define S3C2443_DMAREQSEL_HW (1)
+
+#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
+#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
+#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
+#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
+#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
+#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
+#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
+#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
+#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
+#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
+#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
+#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
+#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
+#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
+#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
+#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
+#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
+#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
+#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
+#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
+#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-iis.h b/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
new file mode 100644
index 00000000..a6f1d5df
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/regs-iis.h
@@ -0,0 +1,77 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-iis.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 IIS register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_IIS_H
+#define __ASM_ARCH_REGS_IIS_H
+
+#define S3C2410_IISCON (0x00)
+
+#define S3C2410_IISCON_LRINDEX (1<<8)
+#define S3C2410_IISCON_TXFIFORDY (1<<7)
+#define S3C2410_IISCON_RXFIFORDY (1<<6)
+#define S3C2410_IISCON_TXDMAEN (1<<5)
+#define S3C2410_IISCON_RXDMAEN (1<<4)
+#define S3C2410_IISCON_TXIDLE (1<<3)
+#define S3C2410_IISCON_RXIDLE (1<<2)
+#define S3C2410_IISCON_PSCEN (1<<1)
+#define S3C2410_IISCON_IISEN (1<<0)
+
+#define S3C2410_IISMOD (0x04)
+
+#define S3C2440_IISMOD_MPLL (1<<9)
+#define S3C2410_IISMOD_SLAVE (1<<8)
+#define S3C2410_IISMOD_NOXFER (0<<6)
+#define S3C2410_IISMOD_RXMODE (1<<6)
+#define S3C2410_IISMOD_TXMODE (2<<6)
+#define S3C2410_IISMOD_TXRXMODE (3<<6)
+#define S3C2410_IISMOD_LR_LLOW (0<<5)
+#define S3C2410_IISMOD_LR_RLOW (1<<5)
+#define S3C2410_IISMOD_IIS (0<<4)
+#define S3C2410_IISMOD_MSB (1<<4)
+#define S3C2410_IISMOD_8BIT (0<<3)
+#define S3C2410_IISMOD_16BIT (1<<3)
+#define S3C2410_IISMOD_BITMASK (1<<3)
+#define S3C2410_IISMOD_256FS (0<<2)
+#define S3C2410_IISMOD_384FS (1<<2)
+#define S3C2410_IISMOD_16FS (0<<0)
+#define S3C2410_IISMOD_32FS (1<<0)
+#define S3C2410_IISMOD_48FS (2<<0)
+#define S3C2410_IISMOD_FS_MASK (3<<0)
+
+#define S3C2410_IISPSR (0x08)
+#define S3C2410_IISPSR_INTMASK (31<<5)
+#define S3C2410_IISPSR_INTSHIFT (5)
+#define S3C2410_IISPSR_EXTMASK (31<<0)
+#define S3C2410_IISPSR_EXTSHFIT (0)
+
+#define S3C2410_IISFCON (0x0c)
+
+#define S3C2410_IISFCON_TXDMA (1<<15)
+#define S3C2410_IISFCON_RXDMA (1<<14)
+#define S3C2410_IISFCON_TXENABLE (1<<13)
+#define S3C2410_IISFCON_RXENABLE (1<<12)
+#define S3C2410_IISFCON_TXMASK (0x3f << 6)
+#define S3C2410_IISFCON_TXSHIFT (6)
+#define S3C2410_IISFCON_RXMASK (0x3f)
+#define S3C2410_IISFCON_RXSHIFT (0)
+
+#define S3C2400_IISFCON_TXDMA (1<<11)
+#define S3C2400_IISFCON_RXDMA (1<<10)
+#define S3C2400_IISFCON_TXENABLE (1<<9)
+#define S3C2400_IISFCON_RXENABLE (1<<8)
+#define S3C2400_IISFCON_TXMASK (0x07 << 4)
+#define S3C2400_IISFCON_TXSHIFT (4)
+#define S3C2400_IISFCON_RXMASK (0x07)
+#define S3C2400_IISFCON_RXSHIFT (0)
+
+#define S3C2410_IISFIFO (0x10)
+#endif /* __ASM_ARCH_REGS_IIS_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-spi.h b/arch/arm/plat-s3c24xx/include/plat/regs-spi.h
new file mode 100644
index 00000000..2b35479e
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/regs-spi.h
@@ -0,0 +1,82 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-spi.h
+ *
+ * Copyright (c) 2004 Fetron GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 SPI register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_SPI_H
+#define __ASM_ARCH_REGS_SPI_H
+
+#define S3C2410_SPI1 (0x20)
+#define S3C2412_SPI1 (0x100)
+
+#define S3C2410_SPCON (0x00)
+
+#define S3C2412_SPCON_RXFIFO_RB2 (0<<14)
+#define S3C2412_SPCON_RXFIFO_RB4 (1<<14)
+#define S3C2412_SPCON_RXFIFO_RB12 (2<<14)
+#define S3C2412_SPCON_RXFIFO_RB14 (3<<14)
+#define S3C2412_SPCON_TXFIFO_RB2 (0<<12)
+#define S3C2412_SPCON_TXFIFO_RB4 (1<<12)
+#define S3C2412_SPCON_TXFIFO_RB12 (2<<12)
+#define S3C2412_SPCON_TXFIFO_RB14 (3<<12)
+#define S3C2412_SPCON_RXFIFO_RESET (1<<11) /* RxFIFO reset */
+#define S3C2412_SPCON_TXFIFO_RESET (1<<10) /* TxFIFO reset */
+#define S3C2412_SPCON_RXFIFO_EN (1<<9) /* RxFIFO Enable */
+#define S3C2412_SPCON_TXFIFO_EN (1<<8) /* TxFIFO Enable */
+
+#define S3C2412_SPCON_DIRC_RX (1<<7)
+
+#define S3C2410_SPCON_SMOD_DMA (2<<5) /* DMA mode */
+#define S3C2410_SPCON_SMOD_INT (1<<5) /* interrupt mode */
+#define S3C2410_SPCON_SMOD_POLL (0<<5) /* polling mode */
+#define S3C2410_SPCON_ENSCK (1<<4) /* Enable SCK */
+#define S3C2410_SPCON_MSTR (1<<3) /* Master/Slave select
+ 0: slave, 1: master */
+#define S3C2410_SPCON_CPOL_HIGH (1<<2) /* Clock polarity select */
+#define S3C2410_SPCON_CPOL_LOW (0<<2) /* Clock polarity select */
+
+#define S3C2410_SPCON_CPHA_FMTB (1<<1) /* Clock Phase Select */
+#define S3C2410_SPCON_CPHA_FMTA (0<<1) /* Clock Phase Select */
+
+#define S3C2410_SPCON_TAGD (1<<0) /* Tx auto garbage data mode */
+
+
+#define S3C2410_SPSTA (0x04)
+
+#define S3C2412_SPSTA_RXFIFO_AE (1<<11)
+#define S3C2412_SPSTA_TXFIFO_AE (1<<10)
+#define S3C2412_SPSTA_RXFIFO_ERROR (1<<9)
+#define S3C2412_SPSTA_TXFIFO_ERROR (1<<8)
+#define S3C2412_SPSTA_RXFIFO_FIFO (1<<7)
+#define S3C2412_SPSTA_RXFIFO_EMPTY (1<<6)
+#define S3C2412_SPSTA_TXFIFO_NFULL (1<<5)
+#define S3C2412_SPSTA_TXFIFO_EMPTY (1<<4)
+
+#define S3C2410_SPSTA_DCOL (1<<2) /* Data Collision Error */
+#define S3C2410_SPSTA_MULD (1<<1) /* Multi Master Error */
+#define S3C2410_SPSTA_READY (1<<0) /* Data Tx/Rx ready */
+#define S3C2412_SPSTA_READY_ORG (1<<3)
+
+#define S3C2410_SPPIN (0x08)
+
+#define S3C2410_SPPIN_ENMUL (1<<2) /* Multi Master Error detect */
+#define S3C2410_SPPIN_RESERVED (1<<1)
+#define S3C2400_SPPIN_nCS (1<<1) /* SPI Card Select */
+#define S3C2410_SPPIN_KEEP (1<<0) /* Master Out keep */
+
+#define S3C2410_SPPRE (0x0C)
+#define S3C2410_SPTDAT (0x10)
+#define S3C2410_SPRDAT (0x14)
+
+#define S3C2412_TXFIFO (0x18)
+#define S3C2412_RXFIFO (0x18)
+#define S3C2412_SPFIC (0x24)
+
+
+#endif /* __ASM_ARCH_REGS_SPI_H */
diff --git a/arch/arm/plat-s3c24xx/include/plat/regs-udc.h b/arch/arm/plat-s3c24xx/include/plat/regs-udc.h
new file mode 100644
index 00000000..f0dd4a41
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/regs-udc.h
@@ -0,0 +1,153 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-udc.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_UDC_H
+#define __ASM_ARCH_REGS_UDC_H
+
+#define S3C2410_USBDREG(x) (x)
+
+#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140)
+#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144)
+#define S3C2410_UDC_EP_INT_REG S3C2410_USBDREG(0x0148)
+
+#define S3C2410_UDC_USB_INT_REG S3C2410_USBDREG(0x0158)
+#define S3C2410_UDC_EP_INT_EN_REG S3C2410_USBDREG(0x015c)
+
+#define S3C2410_UDC_USB_INT_EN_REG S3C2410_USBDREG(0x016c)
+
+#define S3C2410_UDC_FRAME_NUM1_REG S3C2410_USBDREG(0x0170)
+#define S3C2410_UDC_FRAME_NUM2_REG S3C2410_USBDREG(0x0174)
+
+#define S3C2410_UDC_EP0_FIFO_REG S3C2410_USBDREG(0x01c0)
+#define S3C2410_UDC_EP1_FIFO_REG S3C2410_USBDREG(0x01c4)
+#define S3C2410_UDC_EP2_FIFO_REG S3C2410_USBDREG(0x01c8)
+#define S3C2410_UDC_EP3_FIFO_REG S3C2410_USBDREG(0x01cc)
+#define S3C2410_UDC_EP4_FIFO_REG S3C2410_USBDREG(0x01d0)
+
+#define S3C2410_UDC_EP1_DMA_CON S3C2410_USBDREG(0x0200)
+#define S3C2410_UDC_EP1_DMA_UNIT S3C2410_USBDREG(0x0204)
+#define S3C2410_UDC_EP1_DMA_FIFO S3C2410_USBDREG(0x0208)
+#define S3C2410_UDC_EP1_DMA_TTC_L S3C2410_USBDREG(0x020c)
+#define S3C2410_UDC_EP1_DMA_TTC_M S3C2410_USBDREG(0x0210)
+#define S3C2410_UDC_EP1_DMA_TTC_H S3C2410_USBDREG(0x0214)
+
+#define S3C2410_UDC_EP2_DMA_CON S3C2410_USBDREG(0x0218)
+#define S3C2410_UDC_EP2_DMA_UNIT S3C2410_USBDREG(0x021c)
+#define S3C2410_UDC_EP2_DMA_FIFO S3C2410_USBDREG(0x0220)
+#define S3C2410_UDC_EP2_DMA_TTC_L S3C2410_USBDREG(0x0224)
+#define S3C2410_UDC_EP2_DMA_TTC_M S3C2410_USBDREG(0x0228)
+#define S3C2410_UDC_EP2_DMA_TTC_H S3C2410_USBDREG(0x022c)
+
+#define S3C2410_UDC_EP3_DMA_CON S3C2410_USBDREG(0x0240)
+#define S3C2410_UDC_EP3_DMA_UNIT S3C2410_USBDREG(0x0244)
+#define S3C2410_UDC_EP3_DMA_FIFO S3C2410_USBDREG(0x0248)
+#define S3C2410_UDC_EP3_DMA_TTC_L S3C2410_USBDREG(0x024c)
+#define S3C2410_UDC_EP3_DMA_TTC_M S3C2410_USBDREG(0x0250)
+#define S3C2410_UDC_EP3_DMA_TTC_H S3C2410_USBDREG(0x0254)
+
+#define S3C2410_UDC_EP4_DMA_CON S3C2410_USBDREG(0x0258)
+#define S3C2410_UDC_EP4_DMA_UNIT S3C2410_USBDREG(0x025c)
+#define S3C2410_UDC_EP4_DMA_FIFO S3C2410_USBDREG(0x0260)
+#define S3C2410_UDC_EP4_DMA_TTC_L S3C2410_USBDREG(0x0264)
+#define S3C2410_UDC_EP4_DMA_TTC_M S3C2410_USBDREG(0x0268)
+#define S3C2410_UDC_EP4_DMA_TTC_H S3C2410_USBDREG(0x026c)
+
+#define S3C2410_UDC_INDEX_REG S3C2410_USBDREG(0x0178)
+
+/* indexed registers */
+
+#define S3C2410_UDC_MAXP_REG S3C2410_USBDREG(0x0180)
+
+#define S3C2410_UDC_EP0_CSR_REG S3C2410_USBDREG(0x0184)
+
+#define S3C2410_UDC_IN_CSR1_REG S3C2410_USBDREG(0x0184)
+#define S3C2410_UDC_IN_CSR2_REG S3C2410_USBDREG(0x0188)
+
+#define S3C2410_UDC_OUT_CSR1_REG S3C2410_USBDREG(0x0190)
+#define S3C2410_UDC_OUT_CSR2_REG S3C2410_USBDREG(0x0194)
+#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198)
+#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c)
+
+#define S3C2410_UDC_FUNCADDR_UPDATE (1<<7)
+
+#define S3C2410_UDC_PWR_ISOUP (1<<7) // R/W
+#define S3C2410_UDC_PWR_RESET (1<<3) // R
+#define S3C2410_UDC_PWR_RESUME (1<<2) // R/W
+#define S3C2410_UDC_PWR_SUSPEND (1<<1) // R
+#define S3C2410_UDC_PWR_ENSUSPEND (1<<0) // R/W
+
+#define S3C2410_UDC_PWR_DEFAULT 0x00
+
+#define S3C2410_UDC_INT_EP4 (1<<4) // R/W (clear only)
+#define S3C2410_UDC_INT_EP3 (1<<3) // R/W (clear only)
+#define S3C2410_UDC_INT_EP2 (1<<2) // R/W (clear only)
+#define S3C2410_UDC_INT_EP1 (1<<1) // R/W (clear only)
+#define S3C2410_UDC_INT_EP0 (1<<0) // R/W (clear only)
+
+#define S3C2410_UDC_USBINT_RESET (1<<2) // R/W (clear only)
+#define S3C2410_UDC_USBINT_RESUME (1<<1) // R/W (clear only)
+#define S3C2410_UDC_USBINT_SUSPEND (1<<0) // R/W (clear only)
+
+#define S3C2410_UDC_INTE_EP4 (1<<4) // R/W
+#define S3C2410_UDC_INTE_EP3 (1<<3) // R/W
+#define S3C2410_UDC_INTE_EP2 (1<<2) // R/W
+#define S3C2410_UDC_INTE_EP1 (1<<1) // R/W
+#define S3C2410_UDC_INTE_EP0 (1<<0) // R/W
+
+#define S3C2410_UDC_USBINTE_RESET (1<<2) // R/W
+#define S3C2410_UDC_USBINTE_SUSPEND (1<<0) // R/W
+
+
+#define S3C2410_UDC_INDEX_EP0 (0x00)
+#define S3C2410_UDC_INDEX_EP1 (0x01) // ??
+#define S3C2410_UDC_INDEX_EP2 (0x02) // ??
+#define S3C2410_UDC_INDEX_EP3 (0x03) // ??
+#define S3C2410_UDC_INDEX_EP4 (0x04) // ??
+
+#define S3C2410_UDC_ICSR1_CLRDT (1<<6) // R/W
+#define S3C2410_UDC_ICSR1_SENTSTL (1<<5) // R/W (clear only)
+#define S3C2410_UDC_ICSR1_SENDSTL (1<<4) // R/W
+#define S3C2410_UDC_ICSR1_FFLUSH (1<<3) // W (set only)
+#define S3C2410_UDC_ICSR1_UNDRUN (1<<2) // R/W (clear only)
+#define S3C2410_UDC_ICSR1_PKTRDY (1<<0) // R/W (set only)
+
+#define S3C2410_UDC_ICSR2_AUTOSET (1<<7) // R/W
+#define S3C2410_UDC_ICSR2_ISO (1<<6) // R/W
+#define S3C2410_UDC_ICSR2_MODEIN (1<<5) // R/W
+#define S3C2410_UDC_ICSR2_DMAIEN (1<<4) // R/W
+
+#define S3C2410_UDC_OCSR1_CLRDT (1<<7) // R/W
+#define S3C2410_UDC_OCSR1_SENTSTL (1<<6) // R/W (clear only)
+#define S3C2410_UDC_OCSR1_SENDSTL (1<<5) // R/W
+#define S3C2410_UDC_OCSR1_FFLUSH (1<<4) // R/W
+#define S3C2410_UDC_OCSR1_DERROR (1<<3) // R
+#define S3C2410_UDC_OCSR1_OVRRUN (1<<2) // R/W (clear only)
+#define S3C2410_UDC_OCSR1_PKTRDY (1<<0) // R/W (clear only)
+
+#define S3C2410_UDC_OCSR2_AUTOCLR (1<<7) // R/W
+#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W
+#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W
+
+#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0)
+#define S3C2410_UDC_EP0_CSR_IPKRDY (1<<1)
+#define S3C2410_UDC_EP0_CSR_SENTSTL (1<<2)
+#define S3C2410_UDC_EP0_CSR_DE (1<<3)
+#define S3C2410_UDC_EP0_CSR_SE (1<<4)
+#define S3C2410_UDC_EP0_CSR_SENDSTL (1<<5)
+#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1<<6)
+#define S3C2410_UDC_EP0_CSR_SSE (1<<7)
+
+#define S3C2410_UDC_MAXP_8 (1<<0)
+#define S3C2410_UDC_MAXP_16 (1<<1)
+#define S3C2410_UDC_MAXP_32 (1<<2)
+#define S3C2410_UDC_MAXP_64 (1<<3)
+
+
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2400.h b/arch/arm/plat-s3c24xx/include/plat/s3c2400.h
new file mode 100644
index 00000000..b3feaea5
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2400.h
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2400 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.
+ *
+ * Modifications:
+ * 09-Fev-2006 LCVR First version, based on s3c2410.h
+*/
+
+#ifdef CONFIG_CPU_S3C2400
+
+extern int s3c2400_init(void);
+
+extern void s3c2400_map_io(void);
+
+extern void s3c2400_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2400_init_clocks(int xtal);
+
+#else
+#define s3c2400_init_clocks NULL
+#define s3c2400_init_uarts NULL
+#define s3c2400_map_io NULL
+#define s3c2400_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
new file mode 100644
index 00000000..82ab4aad
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
@@ -0,0 +1,33 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 machine directory
+ *
+ * This program is free software; you can 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_S3C2410
+
+extern int s3c2410_init(void);
+extern int s3c2410a_init(void);
+
+extern void s3c2410_map_io(void);
+
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2410_init_clocks(int xtal);
+
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#define s3c2410a_init NULL
+#endif
+
+extern int s3c2410_baseclk_add(void);
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2412.h b/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
new file mode 100644
index 00000000..bb15d3b6
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2412 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2412
+
+extern int s3c2412_init(void);
+
+extern void s3c2412_map_io(void);
+
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2412_init_clocks(int xtal);
+
+extern int s3c2412_baseclk_add(void);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2416.h b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
new file mode 100644
index 00000000..dc3c0907
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2416.h
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
+ *
+ * Header file for s3c2416 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2416
+
+struct s3c2410_uartcfg;
+
+extern int s3c2416_init(void);
+
+extern void s3c2416_map_io(void);
+
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2416_init_clocks(int xtal);
+
+extern int s3c2416_baseclk_add(void);
+
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
new file mode 100644
index 00000000..a19715fe
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
@@ -0,0 +1,51 @@
+/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2443 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.
+*/
+
+#ifdef CONFIG_CPU_S3C2443
+
+struct s3c2410_uartcfg;
+
+extern int s3c2443_init(void);
+
+extern void s3c2443_map_io(void);
+
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c2443_init_clocks(int xtal);
+
+extern int s3c2443_baseclk_add(void);
+
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
+
+/* common code used by s3c2443 and others.
+ * note, not to be used outside of arch/arm/mach-s3c* */
+
+struct clk; /* some files don't need clk.h otherwise */
+
+typedef unsigned int (*pll_fn)(unsigned int reg, unsigned int base);
+typedef unsigned int (*fdiv_fn)(unsigned long clkcon0);
+
+extern void s3c2443_common_setup_clocks(pll_fn get_mpll, fdiv_fn fdiv);
+extern void s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, fdiv_fn fdiv);
+
+extern int s3c2443_clkcon_enable_h(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_p(struct clk *clk, int enable);
+extern int s3c2443_clkcon_enable_s(struct clk *clk, int enable);
+
+extern struct clksrc_clk clk_epllref;
+extern struct clksrc_clk clk_esysclk;
+extern struct clksrc_clk clk_msysclk;
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
new file mode 100644
index 00000000..89e8d0a2
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-s3c24xx/include/plat/s3c244x.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C2440 and S3C2442 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.
+*/
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+
+extern void s3c244x_map_io(void);
+
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c244x_init_clocks(int xtal);
+
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern int s3c2440_init(void);
+
+extern void s3c2440_map_io(void);
+#else
+#define s3c2440_init NULL
+#define s3c2440_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern int s3c2442_init(void);
+
+extern void s3c2442_map_io(void);
+#else
+#define s3c2442_init NULL
+#define s3c2442_map_io NULL
+#endif
diff --git a/arch/arm/plat-s3c24xx/include/plat/udc.h b/arch/arm/plat-s3c24xx/include/plat/udc.h
new file mode 100644
index 00000000..f6388424
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/include/plat/udc.h
@@ -0,0 +1,57 @@
+/* arch/arm/mach-s3c2410/include/mach/udc.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * Changelog:
+ * 14-Mar-2005 RTP Created file
+ * 02-Aug-2005 RTP File rename
+ * 07-Sep-2005 BJD Minor cleanups, changed cmd to enum
+ * 18-Jan-2007 HMW Add per-platform vbus_draw function
+*/
+
+#ifndef __ASM_ARM_ARCH_UDC_H
+#define __ASM_ARM_ARCH_UDC_H
+
+enum s3c2410_udc_cmd_e {
+ S3C2410_UDC_P_ENABLE = 1, /* Pull-up enable */
+ S3C2410_UDC_P_DISABLE = 2, /* Pull-up disable */
+ S3C2410_UDC_P_RESET = 3, /* UDC reset, in case of */
+};
+
+struct s3c2410_udc_mach_info {
+ void (*udc_command)(enum s3c2410_udc_cmd_e);
+ void (*vbus_draw)(unsigned int ma);
+
+ unsigned int pullup_pin;
+ unsigned int pullup_pin_inverted;
+
+ unsigned int vbus_pin;
+ unsigned char vbus_pin_inverted;
+};
+
+extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
+
+/**
+ * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
+ * @epnum: Number of endpoints to be instantiated by the controller driver.
+ * @gpio_init: Platform specific USB related GPIO initialization.
+ * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
+ *
+ * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
+ * controllers.
+ */
+struct s3c24xx_hsudc_platdata {
+ unsigned int epnum;
+ void (*gpio_init)(void);
+ void (*gpio_uninit)(void);
+};
+
+extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
+
+#endif /* __ASM_ARM_ARCH_UDC_H */
diff --git a/arch/arm/plat-s3c24xx/irq-pm.c b/arch/arm/plat-s3c24xx/irq-pm.c
new file mode 100644
index 00000000..0efb2e28
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/irq-pm.c
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-s3c24xx/irq-om.c
+ *
+ * Copyright (c) 2003-2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C24XX - IRQ PM code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+#include <asm/irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
+unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long irqbit = 1 << (data->irq - IRQ_EINT0);
+
+ if (!(s3c_irqwake_intallow & irqbit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", data->irq);
+
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+
+ return 0;
+}
+
+static struct sleep_save irq_save[] = {
+ SAVE_ITEM(S3C2410_INTMSK),
+ SAVE_ITEM(S3C2410_INTSUBMSK),
+};
+
+/* the extint values move between the s3c2410/s3c2440 and the s3c2412
+ * so we use an array to hold them, and to calculate the address of
+ * the register at run-time
+*/
+
+static unsigned long save_extint[3];
+static unsigned long save_eintflt[4];
+static unsigned long save_eintmask;
+
+int s3c24xx_irq_suspend(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
+ save_eintmask = __raw_readl(S3C24XX_EINTMASK);
+
+ return 0;
+}
+
+void s3c24xx_irq_resume(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(save_extint); i++)
+ __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
+
+ for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
+ __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
+
+ s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
+ __raw_writel(save_eintmask, S3C24XX_EINTMASK);
+}
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
new file mode 100644
index 00000000..fc8c5f89
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -0,0 +1,676 @@
+/* linux/arch/arm/plat-s3c24xx/irq.c
+ *
+ * Copyright (c) 2003-2004 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+#include <plat/regs-irqtype.h>
+
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
+
+static void
+s3c_irq_mask(struct irq_data *data)
+{
+ unsigned int irqno = data->irq - IRQ_EINT0;
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ mask |= 1UL << irqno;
+ __raw_writel(mask, S3C2410_INTMSK);
+}
+
+static inline void
+s3c_irq_ack(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+static inline void
+s3c_irq_maskack(struct irq_data *data)
+{
+ unsigned long bitval = 1UL << (data->irq - IRQ_EINT0);
+ unsigned long mask;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ __raw_writel(mask|bitval, S3C2410_INTMSK);
+
+ __raw_writel(bitval, S3C2410_SRCPND);
+ __raw_writel(bitval, S3C2410_INTPND);
+}
+
+
+static void
+s3c_irq_unmask(struct irq_data *data)
+{
+ unsigned int irqno = data->irq;
+ unsigned long mask;
+
+ if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
+ irqdbf2("s3c_irq_unmask %d\n", irqno);
+
+ irqno -= IRQ_EINT0;
+
+ mask = __raw_readl(S3C2410_INTMSK);
+ mask &= ~(1UL << irqno);
+ __raw_writel(mask, S3C2410_INTMSK);
+}
+
+struct irq_chip s3c_irq_level_chip = {
+ .name = "s3c-level",
+ .irq_ack = s3c_irq_maskack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake
+};
+
+struct irq_chip s3c_irq_chip = {
+ .name = "s3c",
+ .irq_ack = s3c_irq_ack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake
+};
+
+static void
+s3c_irqext_mask(struct irq_data *data)
+{
+ unsigned int irqno = data->irq - EXTINT_OFF;
+ unsigned long mask;
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+ mask |= ( 1UL << irqno);
+ __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+static void
+s3c_irqext_ack(struct irq_data *data)
+{
+ unsigned long req;
+ unsigned long bit;
+ unsigned long mask;
+
+ bit = 1UL << (data->irq - EXTINT_OFF);
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+
+ __raw_writel(bit, S3C24XX_EINTPEND);
+
+ req = __raw_readl(S3C24XX_EINTPEND);
+ req &= ~mask;
+
+ /* not sure if we should be acking the parent irq... */
+
+ if (data->irq <= IRQ_EINT7) {
+ if ((req & 0xf0) == 0)
+ s3c_irq_ack(irq_get_irq_data(IRQ_EINT4t7));
+ } else {
+ if ((req >> 8) == 0)
+ s3c_irq_ack(irq_get_irq_data(IRQ_EINT8t23));
+ }
+}
+
+static void
+s3c_irqext_unmask(struct irq_data *data)
+{
+ unsigned int irqno = data->irq - EXTINT_OFF;
+ unsigned long mask;
+
+ mask = __raw_readl(S3C24XX_EINTMASK);
+ mask &= ~(1UL << irqno);
+ __raw_writel(mask, S3C24XX_EINTMASK);
+}
+
+int
+s3c_irqext_type(struct irq_data *data, unsigned int type)
+{
+ void __iomem *extint_reg;
+ void __iomem *gpcon_reg;
+ unsigned long gpcon_offset, extint_offset;
+ unsigned long newvalue = 0, value;
+
+ if ((data->irq >= IRQ_EINT0) && (data->irq <= IRQ_EINT3)) {
+ gpcon_reg = S3C2410_GPFCON;
+ extint_reg = S3C24XX_EXTINT0;
+ gpcon_offset = (data->irq - IRQ_EINT0) * 2;
+ extint_offset = (data->irq - IRQ_EINT0) * 4;
+ } else if ((data->irq >= IRQ_EINT4) && (data->irq <= IRQ_EINT7)) {
+ gpcon_reg = S3C2410_GPFCON;
+ extint_reg = S3C24XX_EXTINT0;
+ gpcon_offset = (data->irq - (EXTINT_OFF)) * 2;
+ extint_offset = (data->irq - (EXTINT_OFF)) * 4;
+ } else if ((data->irq >= IRQ_EINT8) && (data->irq <= IRQ_EINT15)) {
+ gpcon_reg = S3C2410_GPGCON;
+ extint_reg = S3C24XX_EXTINT1;
+ gpcon_offset = (data->irq - IRQ_EINT8) * 2;
+ extint_offset = (data->irq - IRQ_EINT8) * 4;
+ } else if ((data->irq >= IRQ_EINT16) && (data->irq <= IRQ_EINT23)) {
+ gpcon_reg = S3C2410_GPGCON;
+ extint_reg = S3C24XX_EXTINT2;
+ gpcon_offset = (data->irq - IRQ_EINT8) * 2;
+ extint_offset = (data->irq - IRQ_EINT16) * 4;
+ } else {
+ return -1;
+ }
+
+ /* Set the GPIO to external interrupt mode */
+ value = __raw_readl(gpcon_reg);
+ value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
+ __raw_writel(value, gpcon_reg);
+
+ /* Set the external interrupt to pointed trigger type */
+ switch (type)
+ {
+ case IRQ_TYPE_NONE:
+ printk(KERN_WARNING "No edge setting!\n");
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S3C2410_EXTINT_RISEEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S3C2410_EXTINT_FALLEDGE;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S3C2410_EXTINT_BOTHEDGE;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S3C2410_EXTINT_LOWLEV;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S3C2410_EXTINT_HILEV;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -1;
+ }
+
+ value = __raw_readl(extint_reg);
+ value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
+ __raw_writel(value, extint_reg);
+
+ return 0;
+}
+
+static struct irq_chip s3c_irqext_chip = {
+ .name = "s3c-ext",
+ .irq_mask = s3c_irqext_mask,
+ .irq_unmask = s3c_irqext_unmask,
+ .irq_ack = s3c_irqext_ack,
+ .irq_set_type = s3c_irqext_type,
+ .irq_set_wake = s3c_irqext_wake
+};
+
+static struct irq_chip s3c_irq_eint0t4 = {
+ .name = "s3c-ext0",
+ .irq_ack = s3c_irq_ack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+ .irq_set_wake = s3c_irq_wake,
+ .irq_set_type = s3c_irqext_type,
+};
+
+/* mask values for the parent registers for each of the interrupt types */
+
+#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
+#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
+#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
+#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
+
+
+/* UART0 */
+
+static void
+s3c_irq_uart0_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_UART0, 7);
+}
+
+static void
+s3c_irq_uart0_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_UART0);
+}
+
+static void
+s3c_irq_uart0_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_UART0, 7);
+}
+
+static struct irq_chip s3c_irq_uart0 = {
+ .name = "s3c-uart0",
+ .irq_mask = s3c_irq_uart0_mask,
+ .irq_unmask = s3c_irq_uart0_unmask,
+ .irq_ack = s3c_irq_uart0_ack,
+};
+
+/* UART1 */
+
+static void
+s3c_irq_uart1_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_UART1, 7 << 3);
+}
+
+static void
+s3c_irq_uart1_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_UART1);
+}
+
+static void
+s3c_irq_uart1_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_UART1, 7 << 3);
+}
+
+static struct irq_chip s3c_irq_uart1 = {
+ .name = "s3c-uart1",
+ .irq_mask = s3c_irq_uart1_mask,
+ .irq_unmask = s3c_irq_uart1_unmask,
+ .irq_ack = s3c_irq_uart1_ack,
+};
+
+/* UART2 */
+
+static void
+s3c_irq_uart2_mask(struct irq_data *data)
+{
+ s3c_irqsub_mask(data->irq, INTMSK_UART2, 7 << 6);
+}
+
+static void
+s3c_irq_uart2_unmask(struct irq_data *data)
+{
+ s3c_irqsub_unmask(data->irq, INTMSK_UART2);
+}
+
+static void
+s3c_irq_uart2_ack(struct irq_data *data)
+{
+ s3c_irqsub_maskack(data->irq, INTMSK_UART2, 7 << 6);
+}
+
+static struct irq_chip s3c_irq_uart2 = {
+ .name = "s3c-uart2",
+ .irq_mask = s3c_irq_uart2_mask,
+ .irq_unmask = s3c_irq_uart2_unmask,
+ .irq_ack = s3c_irq_uart2_ack,
+};
+
+/* ADC and Touchscreen */
+
+static void
+s3c_irq_adc_mask(struct irq_data *d)
+{
+ s3c_irqsub_mask(d->irq, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static void
+s3c_irq_adc_unmask(struct irq_data *d)
+{
+ s3c_irqsub_unmask(d->irq, INTMSK_ADCPARENT);
+}
+
+static void
+s3c_irq_adc_ack(struct irq_data *d)
+{
+ s3c_irqsub_ack(d->irq, INTMSK_ADCPARENT, 3 << 9);
+}
+
+static struct irq_chip s3c_irq_adc = {
+ .name = "s3c-adc",
+ .irq_mask = s3c_irq_adc_mask,
+ .irq_unmask = s3c_irq_adc_unmask,
+ .irq_ack = s3c_irq_adc_ack,
+};
+
+/* irq demux for adc */
+static void s3c_irq_demux_adc(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned int subsrc, submsk;
+ unsigned int offset = 9;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ subsrc &= ~submsk;
+ subsrc >>= offset;
+ subsrc &= 3;
+
+ if (subsrc != 0) {
+ if (subsrc & 1) {
+ generic_handle_irq(IRQ_TC);
+ }
+ if (subsrc & 2) {
+ generic_handle_irq(IRQ_ADC);
+ }
+ }
+}
+
+static void s3c_irq_demux_uart(unsigned int start)
+{
+ unsigned int subsrc, submsk;
+ unsigned int offset = start - IRQ_S3CUART_RX0;
+
+ /* read the current pending interrupts, and the mask
+ * for what it is available */
+
+ subsrc = __raw_readl(S3C2410_SUBSRCPND);
+ submsk = __raw_readl(S3C2410_INTSUBMSK);
+
+ irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
+ start, offset, subsrc, submsk);
+
+ subsrc &= ~submsk;
+ subsrc >>= offset;
+ subsrc &= 7;
+
+ if (subsrc != 0) {
+ if (subsrc & 1)
+ generic_handle_irq(start);
+
+ if (subsrc & 2)
+ generic_handle_irq(start+1);
+
+ if (subsrc & 4)
+ generic_handle_irq(start+2);
+ }
+}
+
+/* uart demux entry points */
+
+static void
+s3c_irq_demux_uart0(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX0);
+}
+
+static void
+s3c_irq_demux_uart1(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX1);
+}
+
+static void
+s3c_irq_demux_uart2(unsigned int irq,
+ struct irq_desc *desc)
+{
+ irq = irq;
+ s3c_irq_demux_uart(IRQ_S3CUART_RX2);
+}
+
+static void
+s3c_irq_demux_extint8(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+ unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+ eintpnd &= ~eintmsk;
+ eintpnd &= ~0xff; /* ignore lower irqs */
+
+ /* we may as well handle all the pending IRQs here */
+
+ while (eintpnd) {
+ irq = __ffs(eintpnd);
+ eintpnd &= ~(1<<irq);
+
+ irq += (IRQ_EINT4 - 4);
+ generic_handle_irq(irq);
+ }
+
+}
+
+static void
+s3c_irq_demux_extint4t7(unsigned int irq,
+ struct irq_desc *desc)
+{
+ unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
+ unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
+
+ eintpnd &= ~eintmsk;
+ eintpnd &= 0xff; /* only lower irqs */
+
+ /* we may as well handle all the pending IRQs here */
+
+ while (eintpnd) {
+ irq = __ffs(eintpnd);
+ eintpnd &= ~(1<<irq);
+
+ irq += (IRQ_EINT4 - 4);
+
+ generic_handle_irq(irq);
+ }
+}
+
+#ifdef CONFIG_FIQ
+/**
+ * s3c24xx_set_fiq - set the FIQ routing
+ * @irq: IRQ number to route to FIQ on processor.
+ * @on: Whether to route @irq to the FIQ, or to remove the FIQ routing.
+ *
+ * Change the state of the IRQ to FIQ routing depending on @irq and @on. If
+ * @on is true, the @irq is checked to see if it can be routed and the
+ * interrupt controller updated to route the IRQ. If @on is false, the FIQ
+ * routing is cleared, regardless of which @irq is specified.
+ */
+int s3c24xx_set_fiq(unsigned int irq, bool on)
+{
+ u32 intmod;
+ unsigned offs;
+
+ if (on) {
+ offs = irq - FIQ_START;
+ if (offs > 31)
+ return -EINVAL;
+
+ intmod = 1 << offs;
+ } else {
+ intmod = 0;
+ }
+
+ __raw_writel(intmod, S3C2410_INTMOD);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(s3c24xx_set_fiq);
+#endif
+
+
+/* s3c24xx_init_irq
+ *
+ * Initialise S3C2410 IRQ system
+*/
+
+void __init s3c24xx_init_irq(void)
+{
+ unsigned long pend;
+ unsigned long last;
+ int irqno;
+ int i;
+
+#ifdef CONFIG_FIQ
+ init_FIQ();
+#endif
+
+ irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
+
+ /* first, clear all interrupts pending... */
+
+ last = 0;
+ for (i = 0; i < 4; i++) {
+ pend = __raw_readl(S3C24XX_EINTPEND);
+
+ if (pend == 0 || pend == last)
+ break;
+
+ __raw_writel(pend, S3C24XX_EINTPEND);
+ printk("irq: clearing pending ext status %08x\n", (int)pend);
+ last = pend;
+ }
+
+ last = 0;
+ for (i = 0; i < 4; i++) {
+ pend = __raw_readl(S3C2410_INTPND);
+
+ if (pend == 0 || pend == last)
+ break;
+
+ __raw_writel(pend, S3C2410_SRCPND);
+ __raw_writel(pend, S3C2410_INTPND);
+ printk("irq: clearing pending status %08x\n", (int)pend);
+ last = pend;
+ }
+
+ last = 0;
+ for (i = 0; i < 4; i++) {
+ pend = __raw_readl(S3C2410_SUBSRCPND);
+
+ if (pend == 0 || pend == last)
+ break;
+
+ printk("irq: clearing subpending status %08x\n", (int)pend);
+ __raw_writel(pend, S3C2410_SUBSRCPND);
+ last = pend;
+ }
+
+ /* register the main interrupts */
+
+ irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
+
+ for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
+ /* set all the s3c2410 internal irqs */
+
+ switch (irqno) {
+ /* deal with the special IRQs (cascaded) */
+
+ case IRQ_EINT4t7:
+ case IRQ_EINT8t23:
+ case IRQ_UART0:
+ case IRQ_UART1:
+ case IRQ_UART2:
+ case IRQ_ADCPARENT:
+ irq_set_chip_and_handler(irqno, &s3c_irq_level_chip,
+ handle_level_irq);
+ break;
+
+ case IRQ_RESERVED6:
+ case IRQ_RESERVED24:
+ /* no IRQ here */
+ break;
+
+ default:
+ //irqdbf("registering irq %d (s3c irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_chip,
+ handle_edge_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+ }
+
+ /* setup the cascade irq handlers */
+
+ irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+ irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
+
+ irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
+ irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
+ irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
+ irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
+
+ /* external interrupts */
+
+ for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
+ irqdbf("registering irq %d (ext int)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,
+ handle_edge_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
+ irqdbf("registering irq %d (extended s3c irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irqext_chip,
+ handle_edge_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ /* register the uart interrupts */
+
+ irqdbf("s3c2410: registering external interrupts\n");
+
+ for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
+ irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart0,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
+ irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart1,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
+ irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart2,
+ handle_level_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
+ irqdbf("registering irq %d (s3c adc irq)\n", irqno);
+ irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq);
+ set_irq_flags(irqno, IRQF_VALID);
+ }
+
+ irqdbf("s3c2410: registered interrupt handlers\n");
+}
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+ .suspend = s3c24xx_irq_suspend,
+ .resume = s3c24xx_irq_resume,
+};
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
new file mode 100644
index 00000000..663b280d
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -0,0 +1,67 @@
+/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
+ *
+ * Copyright 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * http://armlinux.simtec.co.uk/
+ *
+ * Power Management helpers for Simtec S3C24XX implementations
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/sysdev.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+
+#include <asm/mach-types.h>
+
+#include <plat/pm.h>
+
+#define COPYRIGHT ", Copyright 2005 Simtec Electronics"
+
+/* pm_simtec_init
+ *
+ * enable the power management functions
+*/
+
+static __init int pm_simtec_init(void)
+{
+ unsigned long gstatus4;
+
+ /* check which machine we are running on */
+
+ if (!machine_is_bast() && !machine_is_vr1000() &&
+ !machine_is_anubis() && !machine_is_osiris() &&
+ !machine_is_aml_m5900())
+ return 0;
+
+ printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
+
+ gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30;
+ gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28;
+ gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK);
+
+ __raw_writel(gstatus4, S3C2410_GSTATUS4);
+
+ return s3c_pm_init();
+}
+
+arch_initcall(pm_simtec_init);
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
new file mode 100644
index 00000000..60627e63
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -0,0 +1,149 @@
+/* linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Power Manager (Suspend-To-RAM) support
+ *
+ * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
+ *
+ * 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
+ *
+ * Parts based on arch/arm/mach-pxa/pm.c
+ *
+ * Thanks to Dimitry Andric for debugging
+*/
+
+#include <linux/init.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-irq.h>
+
+#include <asm/mach/time.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/pm.h>
+
+#define PFX "s3c24xx-pm: "
+
+static struct sleep_save core_save[] = {
+ SAVE_ITEM(S3C2410_LOCKTIME),
+ SAVE_ITEM(S3C2410_CLKCON),
+
+ /* we restore the timings here, with the proviso that the board
+ * brings the system up in an slower, or equal frequency setting
+ * to the original system.
+ *
+ * if we cannot guarantee this, then things are going to go very
+ * wrong here, as we modify the refresh and both pll settings.
+ */
+
+ SAVE_ITEM(S3C2410_BWSCON),
+ SAVE_ITEM(S3C2410_BANKCON0),
+ SAVE_ITEM(S3C2410_BANKCON1),
+ SAVE_ITEM(S3C2410_BANKCON2),
+ SAVE_ITEM(S3C2410_BANKCON3),
+ SAVE_ITEM(S3C2410_BANKCON4),
+ SAVE_ITEM(S3C2410_BANKCON5),
+
+#ifndef CONFIG_CPU_FREQ
+ SAVE_ITEM(S3C2410_CLKDIVN),
+ SAVE_ITEM(S3C2410_MPLLCON),
+ SAVE_ITEM(S3C2410_REFRESH),
+#endif
+ SAVE_ITEM(S3C2410_UPLLCON),
+ SAVE_ITEM(S3C2410_CLKSLOW),
+};
+
+static struct sleep_save misc_save[] = {
+ SAVE_ITEM(S3C2410_DCLKCON),
+};
+
+/* s3c_pm_check_resume_pin
+ *
+ * check to see if the pin is configured correctly for sleep mode, and
+ * make any necessary adjustments if it is not
+*/
+
+static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
+{
+ unsigned long irqstate;
+ unsigned long pinstate;
+ int irq = gpio_to_irq(pin);
+
+ if (irqoffs < 4)
+ irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
+ else
+ irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
+
+ pinstate = s3c_gpio_getcfg(pin);
+
+ if (!irqstate) {
+ if (pinstate == S3C2410_GPIO_IRQ)
+ S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
+ } else {
+ if (pinstate == S3C2410_GPIO_IRQ) {
+ S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
+ s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
+ }
+ }
+}
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+ int pin;
+
+ /* for each of the external interrupts (EINT0..EINT15) we
+ * need to check wether it is an external interrupt source,
+ * and then configure it as an input if it is not
+ */
+
+ for (pin = S3C2410_GPF(0); pin <= S3C2410_GPF(7); pin++) {
+ s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF(0));
+ }
+
+ for (pin = S3C2410_GPG(0); pin <= S3C2410_GPG(7); pin++) {
+ s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG(0))+8);
+ }
+}
+
+
+void s3c_pm_restore_core(void)
+{
+ s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+ s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+}
+
+void s3c_pm_save_core(void)
+{
+ s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+ s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
+}
+
diff --git a/arch/arm/plat-s3c24xx/s3c2410-clock.c b/arch/arm/plat-s3c24xx/s3c2410-clock.c
new file mode 100644
index 00000000..9ecc5d91
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-clock.c
@@ -0,0 +1,268 @@
+/* linux/arch/arm/mach-s3c2410/clock.c
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410,S3C2440,S3C2442 Clock control support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/sysdev.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+int s3c2410_clkcon_enable(struct clk *clk, int enable)
+{
+ unsigned int clocks = clk->ctrlbit;
+ unsigned long clkcon;
+
+ clkcon = __raw_readl(S3C2410_CLKCON);
+
+ if (enable)
+ clkcon |= clocks;
+ else
+ clkcon &= ~clocks;
+
+ /* ensure none of the special function bits set */
+ clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
+
+ __raw_writel(clkcon, S3C2410_CLKCON);
+
+ return 0;
+}
+
+static int s3c2410_upll_enable(struct clk *clk, int enable)
+{
+ unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+ unsigned long orig = clkslow;
+
+ if (enable)
+ clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
+ else
+ clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
+
+ __raw_writel(clkslow, S3C2410_CLKSLOW);
+
+ /* if we started the UPLL, then allow to settle */
+
+ if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
+ udelay(200);
+
+ return 0;
+}
+
+/* standard clock definitions */
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_NAND,
+ }, {
+ .name = "sdi",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_SDI,
+ }, {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_ADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_IIC,
+ }, {
+ .name = "iis",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_IIS,
+ }, {
+ .name = "spi",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_SPI,
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_LCDC,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_USBH,
+ }, {
+ .name = "usb-device",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_USBD,
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_PWMT,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_UART2,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2410_clkcon_enable,
+ .ctrlbit = S3C2410_CLKCON_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = 0,
+ }, {
+ .name = "usb-bus-host",
+ .id = -1,
+ .parent = &clk_usb_bus,
+ }, {
+ .name = "usb-bus-gadget",
+ .id = -1,
+ .parent = &clk_usb_bus,
+ },
+};
+
+/* s3c2410_baseclk_add()
+ *
+ * Add all the clocks used by the s3c2410 or compatible CPUs
+ * such as the S3C2440 and S3C2442.
+ *
+ * We cannot use a system device as we are needed before any
+ * of the init-calls that initialise the devices are actually
+ * done.
+*/
+
+int __init s3c2410_baseclk_add(void)
+{
+ unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
+ unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
+ struct clk *clkp;
+ struct clk *xtal;
+ int ret;
+ int ptr;
+
+ clk_upll.enable = s3c2410_upll_enable;
+
+ if (s3c24xx_register_clock(&clk_usb_bus) < 0)
+ printk(KERN_ERR "failed to register usb bus clock\n");
+
+ /* register clocks from clock array */
+
+ clkp = init_clocks;
+ for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
+ /* ensure that we note the clock state */
+
+ clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
+
+ ret = s3c24xx_register_clock(clkp);
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+
+ /* We must be careful disabling the clocks we are not intending to
+ * be using at boot time, as subsystems such as the LCD which do
+ * their own DMA requests to the bus can cause the system to lockup
+ * if they where in the middle of requesting bus access.
+ *
+ * Disabling the LCD clock if the LCD is active is very dangerous,
+ * and therefore the bootloader should be careful to not enable
+ * the LCD clock if it is not needed.
+ */
+
+ /* install (and disable) the clocks we do not need immediately */
+
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+ /* show the clock-slow value */
+
+ xtal = clk_get(NULL, "xtal");
+
+ printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
+ print_mhz(clk_get_rate(xtal) /
+ ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
+ (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
+ (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
+ (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
+
+ s3c_pwmclk_init();
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
new file mode 100644
index 00000000..43ea8019
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
@@ -0,0 +1,64 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2410-cpufreq-utils.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442
+ *
+ * This program is free software; you can 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/cpufreq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+/**
+ * s3c2410_cpufreq_setrefresh - set SDRAM refresh value
+ * @cfg: The frequency configuration
+ *
+ * Set the SDRAM refresh value appropriately for the configured
+ * frequency.
+ */
+void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ struct s3c_cpufreq_board *board = cfg->board;
+ unsigned long refresh;
+ unsigned long refval;
+
+ /* Reduce both the refresh time (in ns) and the frequency (in MHz)
+ * down to ensure that we do not overflow 32 bit numbers.
+ *
+ * This should work for HCLK up to 133MHz and refresh period up
+ * to 30usec.
+ */
+
+ refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+ refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
+ refresh = (1 << 11) + 1 - refresh;
+
+ s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh);
+
+ refval = __raw_readl(S3C2410_REFRESH);
+ refval &= ~((1 << 12) - 1);
+ refval |= refresh;
+ __raw_writel(refval, S3C2410_REFRESH);
+}
+
+/**
+ * s3c2410_set_fvco - set the PLL value
+ * @cfg: The frequency configuration
+ */
+void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
+{
+ __raw_writel(cfg->pll.index, S3C2410_MPLLCON);
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2410-iotiming.c b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
new file mode 100644
index 00000000..b1908e56
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
@@ -0,0 +1,478 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2410-iotiming.c
+ *
+ * Copyright (c) 2006-2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX CPU Frequency scaling - IO timing for S3C2410/S3C2440/S3C2442
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#include <mach/map.h>
+#include <mach/regs-mem.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu-freq-core.h>
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2410_print_timing - print bank timing data for debug purposes
+ * @pfx: The prefix to put on the output
+ * @timings: The timing inforamtion to print.
+*/
+static void s3c2410_print_timing(const char *pfx,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2410_iobank_timing *bt;
+ int bank;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = timings->bank[bank].io_2410;
+ if (!bt)
+ continue;
+
+ printk(KERN_DEBUG "%s %d: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, "
+ "Tcoh=%d.%d, Tcah=%d.%d\n", pfx, bank,
+ print_ns(bt->tacs),
+ print_ns(bt->tcos),
+ print_ns(bt->tacc),
+ print_ns(bt->tcoh),
+ print_ns(bt->tcah));
+ }
+}
+
+/**
+ * bank_reg - convert bank number to pointer to the control register.
+ * @bank: The IO bank number.
+ */
+static inline void __iomem *bank_reg(unsigned int bank)
+{
+ return S3C2410_BANKCON0 + (bank << 2);
+}
+
+/**
+ * bank_is_io - test whether bank is used for IO
+ * @bankcon: The bank control register.
+ *
+ * This is a simplistic test to see if any BANKCON[x] is not an IO
+ * bank. It currently does not take into account whether BWSCON has
+ * an illegal width-setting in it, or if the pin connected to nCS[x]
+ * is actually being handled as a chip-select.
+ */
+static inline int bank_is_io(unsigned long bankcon)
+{
+ return !(bankcon & S3C2410_BANKCON_SDRAM);
+}
+
+/**
+ * to_div - convert cycle time to divisor
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ *
+ * Convert the given cycle time into the divisor to use to obtain it from
+ * HCLK.
+*/
+static inline unsigned int to_div(unsigned int cyc, unsigned int hclk_tns)
+{
+ if (cyc == 0)
+ return 0;
+
+ return DIV_ROUND_UP(cyc, hclk_tns);
+}
+
+/**
+ * calc_0124 - calculate divisor control for divisors that do /0, /1. /2 and /4
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ * @shift: The shift to get to the control bits.
+ *
+ * Calculate the divisor, and turn it into the correct control bits to
+ * set in the result, @v.
+ */
+static unsigned int calc_0124(unsigned int cyc, unsigned long hclk_tns,
+ unsigned long *v, int shift)
+{
+ unsigned int div = to_div(cyc, hclk_tns);
+ unsigned long val;
+
+ s3c_freq_iodbg("%s: cyc=%d, hclk=%lu, shift=%d => div %d\n",
+ __func__, cyc, hclk_tns, shift, div);
+
+ switch (div) {
+ case 0:
+ val = 0;
+ break;
+ case 1:
+ val = 1;
+ break;
+ case 2:
+ val = 2;
+ break;
+ case 3:
+ case 4:
+ val = 3;
+ break;
+ default:
+ return -1;
+ }
+
+ *v |= val << shift;
+ return 0;
+}
+
+int calc_tacp(unsigned int cyc, unsigned long hclk, unsigned long *v)
+{
+ /* Currently no support for Tacp calculations. */
+ return 0;
+}
+
+/**
+ * calc_tacc - calculate divisor control for tacc.
+ * @cyc: The cycle time, in 10ths of nanoseconds.
+ * @nwait_en: IS nWAIT enabled for this bank.
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @v: Pointer to register to alter.
+ *
+ * Calculate the divisor control for tACC, taking into account whether
+ * the bank has nWAIT enabled. The result is used to modify the value
+ * pointed to by @v.
+*/
+static int calc_tacc(unsigned int cyc, int nwait_en,
+ unsigned long hclk_tns, unsigned long *v)
+{
+ unsigned int div = to_div(cyc, hclk_tns);
+ unsigned long val;
+
+ s3c_freq_iodbg("%s: cyc=%u, nwait=%d, hclk=%lu => div=%u\n",
+ __func__, cyc, nwait_en, hclk_tns, div);
+
+ /* if nWait enabled on an bank, Tacc must be at-least 4 cycles. */
+ if (nwait_en && div < 4)
+ div = 4;
+
+ switch (div) {
+ case 0:
+ val = 0;
+ break;
+
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ val = div - 1;
+ break;
+
+ case 5:
+ case 6:
+ val = 4;
+ break;
+
+ case 7:
+ case 8:
+ val = 5;
+ break;
+
+ case 9:
+ case 10:
+ val = 6;
+ break;
+
+ case 11:
+ case 12:
+ case 13:
+ case 14:
+ val = 7;
+ break;
+
+ default:
+ return -1;
+ }
+
+ *v |= val << 8;
+ return 0;
+}
+
+/**
+ * s3c2410_calc_bank - calculate bank timing infromation
+ * @cfg: The configuration we need to calculate for.
+ * @bt: The bank timing information.
+ *
+ * Given the cycle timine for a bank @bt, calculate the new BANKCON
+ * setting for the @cfg timing. This updates the timing information
+ * ready for the cpu frequency change.
+ */
+static int s3c2410_calc_bank(struct s3c_cpufreq_config *cfg,
+ struct s3c2410_iobank_timing *bt)
+{
+ unsigned long hclk = cfg->freq.hclk_tns;
+ unsigned long res;
+ int ret;
+
+ res = bt->bankcon;
+ res &= (S3C2410_BANKCON_SDRAM | S3C2410_BANKCON_PMC16);
+
+ /* tacp: 2,3,4,5 */
+ /* tcah: 0,1,2,4 */
+ /* tcoh: 0,1,2,4 */
+ /* tacc: 1,2,3,4,6,7,10,14 (>4 for nwait) */
+ /* tcos: 0,1,2,4 */
+ /* tacs: 0,1,2,4 */
+
+ ret = calc_0124(bt->tacs, hclk, &res, S3C2410_BANKCON_Tacs_SHIFT);
+ ret |= calc_0124(bt->tcos, hclk, &res, S3C2410_BANKCON_Tcos_SHIFT);
+ ret |= calc_0124(bt->tcah, hclk, &res, S3C2410_BANKCON_Tcah_SHIFT);
+ ret |= calc_0124(bt->tcoh, hclk, &res, S3C2410_BANKCON_Tcoh_SHIFT);
+
+ if (ret)
+ return -EINVAL;
+
+ ret |= calc_tacp(bt->tacp, hclk, &res);
+ ret |= calc_tacc(bt->tacc, bt->nwait_en, hclk, &res);
+
+ if (ret)
+ return -EINVAL;
+
+ bt->bankcon = res;
+ return 0;
+}
+
+static unsigned int tacc_tab[] = {
+ [0] = 1,
+ [1] = 2,
+ [2] = 3,
+ [3] = 4,
+ [4] = 6,
+ [5] = 9,
+ [6] = 10,
+ [7] = 14,
+};
+
+/**
+ * get_tacc - turn tACC value into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_tacc(unsigned long hclk_tns,
+ unsigned long val)
+{
+ val &= 7;
+ return hclk_tns * tacc_tab[val];
+}
+
+/**
+ * get_0124 - turn 0/1/2/4 divider into cycle time
+ * @hclk_tns: The cycle time for HCLK, in 10ths of nanoseconds.
+ * @val: The bank timing register value, shifed down.
+ */
+static unsigned int get_0124(unsigned long hclk_tns,
+ unsigned long val)
+{
+ val &= 3;
+ return hclk_tns * ((val == 3) ? 4 : val);
+}
+
+/**
+ * s3c2410_iotiming_getbank - turn BANKCON into cycle time information
+ * @cfg: The frequency configuration
+ * @bt: The bank timing to fill in (uses cached BANKCON)
+ *
+ * Given the BANKCON setting in @bt and the current frequency settings
+ * in @cfg, update the cycle timing information.
+ */
+void s3c2410_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+ struct s3c2410_iobank_timing *bt)
+{
+ unsigned long bankcon = bt->bankcon;
+ unsigned long hclk = cfg->freq.hclk_tns;
+
+ bt->tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+ bt->tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+ bt->tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+ bt->tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+ bt->tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+}
+
+/**
+ * s3c2410_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+ */
+void s3c2410_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob)
+{
+ struct s3c2410_iobank_timing *bt = iob->io_2410;
+ unsigned long bankcon = bt->bankcon;
+ unsigned long hclk = cfg->freq.hclk_tns;
+ unsigned int tacs;
+ unsigned int tcos;
+ unsigned int tacc;
+ unsigned int tcoh;
+ unsigned int tcah;
+
+ seq_printf(seq, "BANKCON=0x%08lx\n", bankcon);
+
+ tcah = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcah_SHIFT);
+ tcoh = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcoh_SHIFT);
+ tcos = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tcos_SHIFT);
+ tacs = get_0124(hclk, bankcon >> S3C2410_BANKCON_Tacs_SHIFT);
+ tacc = get_tacc(hclk, bankcon >> S3C2410_BANKCON_Tacc_SHIFT);
+
+ seq_printf(seq,
+ "\tRead: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+ print_ns(bt->tacs),
+ print_ns(bt->tcos),
+ print_ns(bt->tacc),
+ print_ns(bt->tcoh),
+ print_ns(bt->tcah));
+
+ seq_printf(seq,
+ "\t Set: Tacs=%d.%d, Tcos=%d.%d, Tacc=%d.%d, Tcoh=%d.%d, Tcah=%d.%d\n",
+ print_ns(tacs),
+ print_ns(tcos),
+ print_ns(tacc),
+ print_ns(tcoh),
+ print_ns(tcah));
+}
+
+/**
+ * s3c2410_iotiming_calc - Calculate bank timing for frequency change.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to fill out.
+ *
+ * Calculate the new values for the banks in @iot based on the new
+ * frequency information in @cfg. This is then used by s3c2410_iotiming_set()
+ * to update the timing when necessary.
+ */
+int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2410_iobank_timing *bt;
+ unsigned long bankcon;
+ int bank;
+ int ret;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bankcon = __raw_readl(bank_reg(bank));
+ bt = iot->bank[bank].io_2410;
+
+ if (!bt)
+ continue;
+
+ bt->bankcon = bankcon;
+
+ ret = s3c2410_calc_bank(cfg, bt);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+ __func__, bank);
+ goto err;
+ }
+
+ s3c_freq_iodbg("%s: bank %d: con=%08lx\n",
+ __func__, bank, bt->bankcon);
+ }
+
+ return 0;
+ err:
+ return ret;
+}
+
+/**
+ * s3c2410_iotiming_set - set the IO timings from the given setup.
+ * @cfg: The frequency configuration
+ * @iot: The IO timing information to use.
+ *
+ * Set all the currently used IO bank timing information generated
+ * by s3c2410_iotiming_calc() once the core has validated that all
+ * the new values are within permitted bounds.
+ */
+void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2410_iobank_timing *bt;
+ int bank;
+
+ /* set the io timings from the specifier */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2410;
+ if (!bt)
+ continue;
+
+ __raw_writel(bt->bankcon, bank_reg(bank));
+ }
+}
+
+/**
+ * s3c2410_iotiming_get - Get the timing information from current registers.
+ * @cfg: The frequency configuration
+ * @timings: The IO timing information to fill out.
+ *
+ * Calculate the @timings timing information from the current frequency
+ * information in @cfg, and the new frequency configur
+ * through all the IO banks, reading the state and then updating @iot
+ * as necessary.
+ *
+ * This is used at the moment on initialisation to get the current
+ * configuration so that boards do not have to carry their own setup
+ * if the timings are correct on initialisation.
+ */
+
+int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2410_iobank_timing *bt;
+ unsigned long bankcon;
+ unsigned long bwscon;
+ int bank;
+
+ bwscon = __raw_readl(S3C2410_BWSCON);
+
+ /* look through all banks to see what is currently set. */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bankcon = __raw_readl(bank_reg(bank));
+
+ if (!bank_is_io(bankcon))
+ continue;
+
+ s3c_freq_iodbg("%s: bank %d: con %08lx\n",
+ __func__, bank, bankcon);
+
+ bt = kzalloc(sizeof(struct s3c2410_iobank_timing), GFP_KERNEL);
+ if (!bt) {
+ printk(KERN_ERR "%s: no memory for bank\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* find out in nWait is enabled for bank. */
+
+ if (bank != 0) {
+ unsigned long tmp = S3C2410_BWSCON_GET(bwscon, bank);
+ if (tmp & S3C2410_BWSCON_WS)
+ bt->nwait_en = 1;
+ }
+
+ timings->bank[bank].io_2410 = bt;
+ bt->bankcon = bankcon;
+
+ s3c2410_iotiming_getbank(cfg, bt);
+ }
+
+ s3c2410_print_timing("get", timings);
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2412-iotiming.c b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
new file mode 100644
index 00000000..0b46d389
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
@@ -0,0 +1,286 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2412-iotiming.c
+ *
+ * Copyright (c) 2006-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2412/S3C2443 (PL093 based) IO timing support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/seq_file.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <linux/amba/pl093.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/regs-s3c2412-mem.h>
+
+#include <plat/cpu.h>
+#include <plat/cpu-freq-core.h>
+#include <plat/clock.h>
+
+#define print_ns(x) ((x) / 10), ((x) % 10)
+
+/**
+ * s3c2412_print_timing - print timing infromation via printk.
+ * @pfx: The prefix to print each line with.
+ * @iot: The IO timing information
+ */
+static void s3c2412_print_timing(const char *pfx, struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ unsigned int bank;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ printk(KERN_DEBUG "%s: %d: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+ "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n", pfx, bank,
+ print_ns(bt->idcy),
+ print_ns(bt->wstrd),
+ print_ns(bt->wstwr),
+ print_ns(bt->wstoen),
+ print_ns(bt->wstwen),
+ print_ns(bt->wstbrd));
+ }
+}
+
+/**
+ * to_div - turn a cycle length into a divisor setting.
+ * @cyc_tns: The cycle time in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ */
+static inline unsigned int to_div(unsigned int cyc_tns, unsigned int clk_tns)
+{
+ return cyc_tns ? DIV_ROUND_UP(cyc_tns, clk_tns) : 0;
+}
+
+/**
+ * calc_timing - calculate timing divisor value and check in range.
+ * @hwtm: The hardware timing in 10ths of nanoseconds.
+ * @clk_tns: The clock period in 10ths of nanoseconds.
+ * @err: Pointer to err variable to update in event of failure.
+ */
+static unsigned int calc_timing(unsigned int hwtm, unsigned int clk_tns,
+ unsigned int *err)
+{
+ unsigned int ret = to_div(hwtm, clk_tns);
+
+ if (ret > 0xf)
+ *err = -EINVAL;
+
+ return ret;
+}
+
+/**
+ * s3c2412_calc_bank - calculate the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @bt: The bank timing.
+ */
+static int s3c2412_calc_bank(struct s3c_cpufreq_config *cfg,
+ struct s3c2412_iobank_timing *bt)
+{
+ unsigned int hclk = cfg->freq.hclk_tns;
+ int err = 0;
+
+ bt->smbidcyr = calc_timing(bt->idcy, hclk, &err);
+ bt->smbwstrd = calc_timing(bt->wstrd, hclk, &err);
+ bt->smbwstwr = calc_timing(bt->wstwr, hclk, &err);
+ bt->smbwstoen = calc_timing(bt->wstoen, hclk, &err);
+ bt->smbwstwen = calc_timing(bt->wstwen, hclk, &err);
+ bt->smbwstbrd = calc_timing(bt->wstbrd, hclk, &err);
+
+ return err;
+}
+
+/**
+ * s3c2412_iotiming_debugfs - debugfs show io bank timing information
+ * @seq: The seq_file to write output to using seq_printf().
+ * @cfg: The current configuration.
+ * @iob: The IO bank information to decode.
+*/
+void s3c2412_iotiming_debugfs(struct seq_file *seq,
+ struct s3c_cpufreq_config *cfg,
+ union s3c_iobank *iob)
+{
+ struct s3c2412_iobank_timing *bt = iob->io_2412;
+
+ seq_printf(seq,
+ "\tRead: idcy=%d.%d wstrd=%d.%d wstwr=%d,%d"
+ "wstoen=%d.%d wstwen=%d.%d wstbrd=%d.%d\n",
+ print_ns(bt->idcy),
+ print_ns(bt->wstrd),
+ print_ns(bt->wstwr),
+ print_ns(bt->wstoen),
+ print_ns(bt->wstwen),
+ print_ns(bt->wstbrd));
+}
+
+/**
+ * s3c2412_iotiming_calc - calculate all the bank divisor settings.
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Calculate the timing information for all the banks that are
+ * configured as IO, using s3c2412_calc_bank().
+ */
+int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ int bank;
+ int ret;
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ ret = s3c2412_calc_bank(cfg, bt);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot calculate bank %d io\n",
+ __func__, bank);
+ goto err;
+ }
+ }
+
+ return 0;
+ err:
+ return ret;
+}
+
+/**
+ * s3c2412_iotiming_set - set the timing information
+ * @cfg: The current frequency configuration.
+ * @iot: The bank timing information.
+ *
+ * Set the IO bank information from the details calculated earlier from
+ * calling s3c2412_iotiming_calc().
+ */
+void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *iot)
+{
+ struct s3c2412_iobank_timing *bt;
+ void __iomem *regs;
+ int bank;
+
+ /* set the io timings from the specifier */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ bt = iot->bank[bank].io_2412;
+ if (!bt)
+ continue;
+
+ regs = S3C2412_SSMC_BANK(bank);
+
+ __raw_writel(bt->smbidcyr, regs + SMBIDCYR);
+ __raw_writel(bt->smbwstrd, regs + SMBWSTRDR);
+ __raw_writel(bt->smbwstwr, regs + SMBWSTWRR);
+ __raw_writel(bt->smbwstoen, regs + SMBWSTOENR);
+ __raw_writel(bt->smbwstwen, regs + SMBWSTWENR);
+ __raw_writel(bt->smbwstbrd, regs + SMBWSTBRDR);
+ }
+}
+
+static inline unsigned int s3c2412_decode_timing(unsigned int clock, u32 reg)
+{
+ return (reg & 0xf) * clock;
+}
+
+static void s3c2412_iotiming_getbank(struct s3c_cpufreq_config *cfg,
+ struct s3c2412_iobank_timing *bt,
+ unsigned int bank)
+{
+ unsigned long clk = cfg->freq.hclk_tns; /* ssmc clock??? */
+ void __iomem *regs = S3C2412_SSMC_BANK(bank);
+
+ bt->idcy = s3c2412_decode_timing(clk, __raw_readl(regs + SMBIDCYR));
+ bt->wstrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTRDR));
+ bt->wstoen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTOENR));
+ bt->wstwen = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTWENR));
+ bt->wstbrd = s3c2412_decode_timing(clk, __raw_readl(regs + SMBWSTBRDR));
+}
+
+/**
+ * bank_is_io - return true if bank is (possibly) IO.
+ * @bank: The bank number.
+ * @bankcfg: The value of S3C2412_EBI_BANKCFG.
+ */
+static inline bool bank_is_io(unsigned int bank, u32 bankcfg)
+{
+ if (bank < 2)
+ return true;
+
+ return !(bankcfg & (1 << bank));
+}
+
+int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
+ struct s3c_iotimings *timings)
+{
+ struct s3c2412_iobank_timing *bt;
+ u32 bankcfg = __raw_readl(S3C2412_EBI_BANKCFG);
+ unsigned int bank;
+
+ /* look through all banks to see what is currently set. */
+
+ for (bank = 0; bank < MAX_BANKS; bank++) {
+ if (!bank_is_io(bank, bankcfg))
+ continue;
+
+ bt = kzalloc(sizeof(struct s3c2412_iobank_timing), GFP_KERNEL);
+ if (!bt) {
+ printk(KERN_ERR "%s: no memory for bank\n", __func__);
+ return -ENOMEM;
+ }
+
+ timings->bank[bank].io_2412 = bt;
+ s3c2412_iotiming_getbank(cfg, bt, bank);
+ }
+
+ s3c2412_print_timing("get", timings);
+ return 0;
+}
+
+/* this is in here as it is so small, it doesn't currently warrant a file
+ * to itself. We expect that any s3c24xx needing this is going to also
+ * need the iotiming support.
+ */
+void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
+{
+ struct s3c_cpufreq_board *board = cfg->board;
+ u32 refresh;
+
+ WARN_ON(board == NULL);
+
+ /* Reduce both the refresh time (in ns) and the frequency (in MHz)
+ * down to ensure that we do not overflow 32 bit numbers.
+ *
+ * This should work for HCLK up to 133MHz and refresh period up
+ * to 30usec.
+ */
+
+ refresh = (cfg->freq.hclk / 100) * (board->refresh / 10);
+ refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */
+ refresh &= ((1 << 16) - 1);
+
+ s3c_freq_dbg("%s: refresh value %u\n", __func__, (unsigned int)refresh);
+
+ __raw_writel(refresh, S3C2412_REFRESH);
+}
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
new file mode 100644
index 00000000..82f2d4a3
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -0,0 +1,472 @@
+/* linux/arch/arm/plat-s3c24xx/s3c2443-clock.c
+ *
+ * Copyright (c) 2007, 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2443 Clock control suport - common code
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <mach/regs-s3c2443-clock.h>
+
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu.h>
+
+#include <plat/cpu-freq.h>
+
+
+static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
+{
+ u32 ctrlbit = clk->ctrlbit;
+ u32 con = __raw_readl(reg);
+
+ if (enable)
+ con |= ctrlbit;
+ else
+ con &= ~ctrlbit;
+
+ __raw_writel(con, reg);
+ return 0;
+}
+
+int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
+}
+
+int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
+{
+ return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
+}
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+struct clk clk_mpllref = {
+ .name = "mpllref",
+ .parent = &clk_xtal,
+ .id = -1,
+};
+
+static struct clk *clk_epllref_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpllref,
+ [2] = &clk_xtal,
+ [3] = &clk_ext,
+};
+
+struct clksrc_clk clk_epllref = {
+ .clk = {
+ .name = "epllref",
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_epllref_sources,
+ .nr_sources = ARRAY_SIZE(clk_epllref_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
+};
+
+/* esysclk
+ *
+ * this is sourced from either the EPLL or the EPLLref clock
+*/
+
+static struct clk *clk_sysclk_sources[] = {
+ [0] = &clk_epllref.clk,
+ [1] = &clk_epll,
+};
+
+struct clksrc_clk clk_esysclk = {
+ .clk = {
+ .name = "esysclk",
+ .parent = &clk_epll,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_sysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
+};
+
+static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long div = __raw_readl(S3C2443_CLKDIV0);
+
+ div &= S3C2443_CLKDIV0_EXTDIV_MASK;
+ div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
+
+ return parent_rate / (div + 1);
+}
+
+static struct clk clk_mdivclk = {
+ .name = "mdivclk",
+ .parent = &clk_mpllref,
+ .id = -1,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_getrate_mdivclk,
+ },
+};
+
+static struct clk *clk_msysclk_sources[] = {
+ [0] = &clk_mpllref,
+ [1] = &clk_mpll,
+ [2] = &clk_mdivclk,
+ [3] = &clk_mpllref,
+};
+
+struct clksrc_clk clk_msysclk = {
+ .clk = {
+ .name = "msysclk",
+ .parent = &clk_xtal,
+ .id = -1,
+ },
+ .sources = &(struct clksrc_sources) {
+ .sources = clk_msysclk_sources,
+ .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
+ },
+ .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
+};
+
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+ unsigned long rate = clk_get_rate(clk->parent);
+ unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+ clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+ clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+ return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+ .name = "prediv",
+ .id = -1,
+ .parent = &clk_msysclk.clk,
+ .ops = &(struct clk_ops) {
+ .get_rate = s3c2443_prediv_getrate,
+ },
+};
+
+/* usbhost
+ *
+ * usb host bus-clock, usually 48MHz to provide USB bus clock timing
+*/
+
+static struct clksrc_clk clk_usb_bus_host = {
+ .clk = {
+ .name = "usb-bus-host-parent",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_USBHOST,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
+};
+
+/* common clksrc clocks */
+
+static struct clksrc_clk clksrc_clks[] = {
+ {
+ /* ART baud-rate clock sourced from esysclk via a divisor */
+ .clk = {
+ .name = "uartclk",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
+ }, {
+ /* camera interface bus-clock, divided down from esysclk */
+ .clk = {
+ .name = "camif-upll", /* same as 2440 name */
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_CAMCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
+ }, {
+ .clk = {
+ .name = "display-if",
+ .id = -1,
+ .parent = &clk_esysclk.clk,
+ .ctrlbit = S3C2443_SCLKCON_DISPCLK,
+ .enable = s3c2443_clkcon_enable_s,
+ },
+ .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
+ },
+};
+
+
+static struct clk init_clocks_off[] = {
+ {
+ .name = "adc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_ADC,
+ }, {
+ .name = "i2c",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_IIC,
+ }
+};
+
+static struct clk init_clocks[] = {
+ {
+ .name = "dma",
+ .id = 0,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA0,
+ }, {
+ .name = "dma",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA1,
+ }, {
+ .name = "dma",
+ .id = 2,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA2,
+ }, {
+ .name = "dma",
+ .id = 3,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA3,
+ }, {
+ .name = "dma",
+ .id = 4,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA4,
+ }, {
+ .name = "dma",
+ .id = 5,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_DMA5,
+ }, {
+ .name = "hsmmc",
+ .id = 1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_HSMMC,
+ }, {
+ .name = "gpio",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_GPIO,
+ }, {
+ .name = "usb-host",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_USBH,
+ }, {
+ .name = "usb-device",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_USBD,
+ }, {
+ .name = "lcd",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_LCDC,
+
+ }, {
+ .name = "timers",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_PWMT,
+ }, {
+ .name = "cfc",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_CFC,
+ }, {
+ .name = "ssmc",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c2443_clkcon_enable_h,
+ .ctrlbit = S3C2443_HCLKCON_SSMC,
+ }, {
+ .name = "uart",
+ .id = 0,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART0,
+ }, {
+ .name = "uart",
+ .id = 1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART1,
+ }, {
+ .name = "uart",
+ .id = 2,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART2,
+ }, {
+ .name = "uart",
+ .id = 3,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_UART3,
+ }, {
+ .name = "rtc",
+ .id = -1,
+ .parent = &clk_p,
+ .enable = s3c2443_clkcon_enable_p,
+ .ctrlbit = S3C2443_PCLKCON_RTC,
+ }, {
+ .name = "watchdog",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C2443_PCLKCON_WDT,
+ }, {
+ .name = "ac97",
+ .id = -1,
+ .parent = &clk_p,
+ .ctrlbit = S3C2443_PCLKCON_AC97,
+ }, {
+ .name = "nand",
+ .id = -1,
+ .parent = &clk_h,
+ }, {
+ .name = "usb-bus-host",
+ .id = -1,
+ .parent = &clk_usb_bus_host.clk,
+ }
+};
+
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
+{
+ clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
+
+ return clkcon0 + 1;
+}
+
+/* EPLLCON compatible enough to get on/off information */
+
+void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll,
+ fdiv_fn get_fdiv)
+{
+ unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
+ unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
+ unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+ struct clk *xtal_clk;
+ unsigned long xtal;
+ unsigned long pll;
+ unsigned long fclk;
+ unsigned long hclk;
+ unsigned long pclk;
+ int ptr;
+
+ xtal_clk = clk_get(NULL, "xtal");
+ xtal = clk_get_rate(xtal_clk);
+ clk_put(xtal_clk);
+
+ pll = get_mpll(mpllcon, xtal);
+ clk_msysclk.clk.rate = pll;
+
+ fclk = pll / get_fdiv(clkdiv0);
+ hclk = s3c2443_prediv_getrate(&clk_prediv);
+ hclk /= s3c2443_get_hdiv(clkdiv0);
+ pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+
+ s3c24xx_setup_clocks(fclk, hclk, pclk);
+
+ printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
+ (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+ print_mhz(pll), print_mhz(fclk),
+ print_mhz(hclk), print_mhz(pclk));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
+ s3c_set_clksrc(&clksrc_clks[ptr], true);
+
+ /* ensure usb bus clock is within correct rate of 48MHz */
+
+ if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
+ printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
+ clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
+ }
+
+ printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
+ (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
+ print_mhz(clk_get_rate(&clk_epll)),
+ print_mhz(clk_get_rate(&clk_usb_bus)));
+}
+
+static struct clk *clks[] __initdata = {
+ &clk_prediv,
+ &clk_mpllref,
+ &clk_mdivclk,
+ &clk_ext,
+ &clk_epll,
+ &clk_usb_bus,
+};
+
+static struct clksrc_clk *clksrcs[] __initdata = {
+ &clk_usb_bus_host,
+ &clk_epllref,
+ &clk_esysclk,
+ &clk_msysclk,
+};
+
+void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
+ fdiv_fn get_fdiv)
+{
+ int ptr;
+
+ /* s3c2443 parents h and p clocks from prediv */
+ clk_h.parent = &clk_prediv;
+ clk_p.parent = &clk_prediv;
+
+ clk_usb_bus.parent = &clk_usb_bus_host.clk;
+ clk_epll.parent = &clk_epllref.clk;
+
+ s3c24xx_register_baseclocks(xtal);
+ s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
+
+ for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+ s3c_register_clksrc(clksrcs[ptr], 1);
+
+ s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
+ s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
+
+ /* See s3c2443/etc notes on disabling clocks at init time */
+ s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+ s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
+
+ s3c2443_common_setup_clocks(get_mpll, get_fdiv);
+}
diff --git a/arch/arm/plat-s3c24xx/setup-i2c.c b/arch/arm/plat-s3c24xx/setup-i2c.c
new file mode 100644
index 00000000..9e90a7cb
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/setup-i2c.c
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-s3c24xx/setup-i2c.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Base setup for i2c 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/gpio.h>
+
+struct platform_device;
+
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+void s3c_i2c0_cfg_gpio(struct platform_device *dev)
+{
+ s3c_gpio_cfgpin(S3C2410_GPE(15), S3C2410_GPE15_IICSDA);
+ s3c_gpio_cfgpin(S3C2410_GPE(14), S3C2410_GPE14_IICSCL);
+}
diff --git a/arch/arm/plat-s3c24xx/setup-ts.c b/arch/arm/plat-s3c24xx/setup-ts.c
new file mode 100644
index 00000000..ed263866
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/setup-ts.c
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s3c24xx/setup-ts.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Based on S3C24XX setup for i2c 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/gpio.h>
+
+struct platform_device; /* don't need the contents */
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+/**
+ * s3c24xx_ts_cfg_gpio - configure gpio for s3c2410 systems
+ *
+ * Configure the GPIO for the S3C2410 system, where we have external FETs
+ * connected to the device (later systems such as the S3C2440 integrate
+ * these into the device).
+ */
+void s3c24xx_ts_cfg_gpio(struct platform_device *dev)
+{
+ s3c2410_gpio_cfgpin(S3C2410_GPG(12), S3C2410_GPG12_XMON);
+ s3c2410_gpio_cfgpin(S3C2410_GPG(13), S3C2410_GPG13_nXPON);
+ s3c2410_gpio_cfgpin(S3C2410_GPG(14), S3C2410_GPG14_YMON);
+ s3c2410_gpio_cfgpin(S3C2410_GPG(15), S3C2410_GPG15_nYPON);
+}
diff --git a/arch/arm/plat-s3c24xx/simtec-audio.c b/arch/arm/plat-s3c24xx/simtec-audio.c
new file mode 100644
index 00000000..6bc832e0
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/simtec-audio.c
@@ -0,0 +1,77 @@
+/* linux/arch/arm/plat-s3c24xx/simtec-audio.c
+ *
+ * Copyright (c) 2009 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Audio setup for various Simtec S3C24XX implementations
+ *
+ * This program is free software; you can 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/init.h>
+#include <linux/device.h>
+#include <linux/io.h>
+
+#include <mach/bast-map.h>
+#include <mach/bast-irq.h>
+#include <mach/bast-cpld.h>
+
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/audio-simtec.h>
+#include <plat/devs.h>
+
+/* platform ops for audio */
+
+static void simtec_audio_startup_lrroute(void)
+{
+ unsigned int tmp;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ tmp = __raw_readb(BAST_VA_CTRL1);
+ tmp &= ~BAST_CPLD_CTRL1_LRMASK;
+ tmp |= BAST_CPLD_CTRL1_LRCDAC;
+ __raw_writeb(tmp, BAST_VA_CTRL1);
+
+ local_irq_restore(flags);
+}
+
+static struct s3c24xx_audio_simtec_pdata simtec_audio_platdata;
+static char our_name[32];
+
+static struct platform_device simtec_audio_dev = {
+ .name = our_name,
+ .id = -1,
+ .dev = {
+ .parent = &s3c_device_iis.dev,
+ .platform_data = &simtec_audio_platdata,
+ },
+};
+
+int __init simtec_audio_add(const char *name, bool has_lr_routing,
+ struct s3c24xx_audio_simtec_pdata *spd)
+{
+ if (!name)
+ name = "tlv320aic23";
+
+ snprintf(our_name, sizeof(our_name)-1, "s3c24xx-simtec-%s", name);
+
+ /* copy platform data so the source can be __initdata */
+ if (spd)
+ simtec_audio_platdata = *spd;
+
+ if (has_lr_routing)
+ simtec_audio_platdata.startup = simtec_audio_startup_lrroute;
+
+ platform_device_register(&s3c_device_iis);
+ platform_device_register(&simtec_audio_dev);
+ return 0;
+}
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
new file mode 100644
index 00000000..fd7032f8
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -0,0 +1,109 @@
+/* linux/arch/arm/plat-s3c24xx/sleep.S
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 Power Manager (Suspend-To-RAM) support
+ *
+ * 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 <mach/hardware.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-mem.h>
+#include <plat/regs-serial.h>
+
+/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
+ * reset the UART configuration, only enable if you really need this!
+*/
+//#define CONFIG_DEBUG_RESUME
+
+ .text
+
+ /* s3c_cpu_save
+ *
+ * entry:
+ * r1 = v:p offset
+ */
+
+ENTRY(s3c_cpu_save)
+ stmfd sp!, { r4 - r12, lr }
+ ldr r3, =resume_with_mmu
+ bl cpu_suspend
+
+ @@ jump to final code to send system to sleep
+ ldr r0, =pm_cpu_sleep
+ @@ldr pc, [ r0 ]
+ ldr r0, [ r0 ]
+ mov pc, r0
+
+ @@ return to the caller, after having the MMU
+ @@ turned on, this restores the last bits from the
+ @@ stack
+resume_with_mmu:
+ ldmfd sp!, { r4 - 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
+
+ /* s3c_cpu_resume
+ *
+ * resume code entry for bootloader to call
+ */
+
+ENTRY(s3c_cpu_resume)
+ mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
+ msr cpsr_c, r0
+
+ @@ load UART to allow us to print the two characters for
+ @@ resume debug
+
+ mov r2, #S3C24XX_PA_UART & 0xff000000
+ orr r2, r2, #S3C24XX_PA_UART & 0xff000
+
+#if 0
+ /* SMDK2440 LED set */
+ mov r14, #S3C24XX_PA_GPIO
+ ldr r12, [ r14, #0x54 ]
+ bic r12, r12, #3<<4
+ orr r12, r12, #1<<7
+ str r12, [ r14, #0x54 ]
+#endif
+
+#ifdef CONFIG_DEBUG_RESUME
+ mov r3, #'L'
+ strb r3, [ r2, #S3C2410_UTXH ]
+1001:
+ ldrb r14, [ r3, #S3C2410_UTRSTAT ]
+ tst r14, #S3C2410_UTRSTAT_TXE
+ beq 1001b
+#endif /* CONFIG_DEBUG_RESUME */
+
+ b cpu_resume
diff --git a/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
new file mode 100644
index 00000000..704175b0
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpe11_12_13.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX SPI - gpio configuration for bus 0 on gpe11,12,13
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <mach/spi.h>
+#include <mach/regs-gpio.h>
+
+void s3c24xx_spi_gpiocfg_bus0_gpe11_12_13(struct s3c2410_spi_info *spi,
+ int enable)
+{
+ if (enable) {
+ s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPE13_SPICLK0);
+ s3c_gpio_cfgpin(S3C2410_GPE(12), S3C2410_GPE12_SPIMOSI0);
+ s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPE11_SPIMISO0);
+ s3c2410_gpio_pullup(S3C2410_GPE(11), 0);
+ s3c2410_gpio_pullup(S3C2410_GPE(13), 0);
+ } else {
+ s3c_gpio_cfgpin(S3C2410_GPE(13), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPE(11), S3C2410_GPIO_INPUT);
+ s3c_gpio_setpull(S3C2410_GPE(11), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPE(12), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPE(13), S3C_GPIO_PULL_NONE);
+ }
+}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
new file mode 100644
index 00000000..72457afd
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpd8_9_10.c
@@ -0,0 +1,38 @@
+/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpd8_9_10.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX SPI - gpio configuration for bus 1 on gpd8,9,10
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <mach/spi.h>
+#include <mach/regs-gpio.h>
+
+void s3c24xx_spi_gpiocfg_bus1_gpd8_9_10(struct s3c2410_spi_info *spi,
+ int enable)
+{
+
+ printk(KERN_INFO "%s(%d)\n", __func__, enable);
+ if (enable) {
+ s3c_gpio_cfgpin(S3C2410_GPD(10), S3C2440_GPD10_SPICLK1);
+ s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2440_GPD9_SPIMOSI1);
+ s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2440_GPD8_SPIMISO1);
+ s3c2410_gpio_pullup(S3C2410_GPD(10), 0);
+ s3c2410_gpio_pullup(S3C2410_GPD(9), 0);
+ } else {
+ s3c_gpio_cfgpin(S3C2410_GPD(8), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPD(9), S3C2410_GPIO_INPUT);
+ s3c_gpio_setpull(S3C2410_GPD(10), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPD(9), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPD(8), S3C_GPIO_PULL_NONE);
+ }
+}
diff --git a/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
new file mode 100644
index 00000000..c3972b64
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/spi-bus1-gpg5_6_7.c
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-s3c24xx/spi-bus0-gpg5_6_7.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX SPI - gpio configuration for bus 1 on gpg5,6,7
+ *
+ * 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <mach/spi.h>
+#include <mach/regs-gpio.h>
+
+void s3c24xx_spi_gpiocfg_bus1_gpg5_6_7(struct s3c2410_spi_info *spi,
+ int enable)
+{
+ if (enable) {
+ s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPG7_SPICLK1);
+ s3c_gpio_cfgpin(S3C2410_GPG(6), S3C2410_GPG6_SPIMOSI1);
+ s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPG5_SPIMISO1);
+ s3c2410_gpio_pullup(S3C2410_GPG(5), 0);
+ s3c2410_gpio_pullup(S3C2410_GPG(6), 0);
+ } else {
+ s3c_gpio_cfgpin(S3C2410_GPG(7), S3C2410_GPIO_INPUT);
+ s3c_gpio_cfgpin(S3C2410_GPG(5), S3C2410_GPIO_INPUT);
+ s3c_gpio_setpull(S3C2410_GPG(5), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPG(6), S3C_GPIO_PULL_NONE);
+ s3c_gpio_setpull(S3C2410_GPG(7), S3C_GPIO_PULL_NONE);
+ }
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
new file mode 100644
index 00000000..e98f5c5c
--- /dev/null
+++ b/arch/arm/plat-s5p/Kconfig
@@ -0,0 +1,96 @@
+# arch/arm/plat-s5p/Kconfig
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+config PLAT_S5P
+ bool
+ depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
+ default y
+ select ARM_VIC if !ARCH_EXYNOS4
+ select ARM_GIC if ARCH_EXYNOS4
+ select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
+ select S3C_GPIO_TRACK
+ select S5P_GPIO_DRVSTR
+ select SAMSUNG_GPIOLIB_4BIT
+ select S3C_GPIO_CFG_S3C64XX
+ select S3C_GPIO_PULL_UPDOWN
+ select S3C_GPIO_CFG_S3C24XX
+ select PLAT_SAMSUNG
+ select SAMSUNG_CLKSRC
+ select SAMSUNG_IRQ_VIC_TIMER
+ select SAMSUNG_IRQ_UART
+ help
+ Base platform code for Samsung's S5P series SoC.
+
+config S5P_EXT_INT
+ bool
+ help
+ Use the external interrupts (other than GPIO interrupts.)
+ Note: Do not choose this for S5P6440 and S5P6450.
+
+config S5P_GPIO_INT
+ bool
+ help
+ Common code for the GPIO interrupts (other than external interrupts.)
+
+config S5P_HRT
+ bool
+ help
+ Use the High Resolution timer support
+
+comment "System MMU"
+
+config S5P_SYSTEM_MMU
+ bool "S5P SYSTEM MMU"
+ depends on ARCH_EXYNOS4
+ help
+ Say Y here if you want to enable System MMU
+
+config S5P_DEV_FIMC0
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 0
+
+config S5P_DEV_FIMC1
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 1
+
+config S5P_DEV_FIMC2
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 2
+
+config S5P_DEV_FIMC3
+ bool
+ help
+ Compile in platform device definitions for FIMC controller 3
+
+config S5P_DEV_ONENAND
+ bool
+ help
+ Compile in platform device definition for OneNAND controller
+
+config S5P_DEV_CSIS0
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 0
+
+config S5P_DEV_CSIS1
+ bool
+ help
+ Compile in platform device definitions for MIPI-CSIS channel 1
+
+config S5P_DEV_USB_EHCI
+ bool
+ help
+ Compile in platform device definition for USB EHCI
+
+config S5P_SETUP_MIPIPHY
+ bool
+ help
+ Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
new file mode 100644
index 00000000..e234cc4d
--- /dev/null
+++ b/arch/arm/plat-s5p/Makefile
@@ -0,0 +1,37 @@
+# arch/arm/plat-s5p/Makefile
+#
+# Copyright (c) 2009 Samsung Electronics Co., Ltd.
+# http://www.samsung.com/
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n := dummy.o
+obj- :=
+
+# Core files
+
+obj-y += dev-pmu.o
+obj-y += dev-uart.o
+obj-y += cpu.o
+obj-y += clock.o
+obj-y += irq.o
+obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
+obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
+obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_S5P_HRT) += s5p-time.o
+
+# devices
+
+obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
+obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
+obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
+obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.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_USB_EHCI) += dev-ehci.o
+obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
new file mode 100644
index 00000000..8d081d96
--- /dev/null
+++ b/arch/arm/plat-s5p/clock.c
@@ -0,0 +1,193 @@
+/* linux/arch/arm/plat-s5p/clock.c
+ *
+ * Copyright 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Common clock support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+
+#include <mach/regs-clock.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/s5p-clock.h>
+
+/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
+ * clk_ext_xtal_mux.
+*/
+struct clk clk_ext_xtal_mux = {
+ .name = "ext_xtal",
+ .id = -1,
+};
+
+struct clk clk_xusbxti = {
+ .name = "xusbxti",
+ .id = -1,
+};
+
+struct clk s5p_clk_27m = {
+ .name = "clk_27m",
+ .id = -1,
+ .rate = 27000000,
+};
+
+/* 48MHz USB Phy clock output */
+struct clk clk_48m = {
+ .name = "clk_48m",
+ .id = -1,
+ .rate = 48000000,
+};
+
+/* APLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_apll = {
+ .name = "fout_apll",
+ .id = -1,
+};
+
+/* MPLL clock output
+ * No need .ctrlbit, this is always on
+*/
+struct clk clk_fout_mpll = {
+ .name = "fout_mpll",
+ .id = -1,
+};
+
+/* EPLL clock output */
+struct clk clk_fout_epll = {
+ .name = "fout_epll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* DPLL clock output */
+struct clk clk_fout_dpll = {
+ .name = "fout_dpll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* VPLL clock output */
+struct clk clk_fout_vpll = {
+ .name = "fout_vpll",
+ .id = -1,
+ .ctrlbit = (1 << 31),
+};
+
+/* Possible clock sources for APLL Mux */
+static struct clk *clk_src_apll_list[] = {
+ [0] = &clk_fin_apll,
+ [1] = &clk_fout_apll,
+};
+
+struct clksrc_sources clk_src_apll = {
+ .sources = clk_src_apll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_apll_list),
+};
+
+/* Possible clock sources for MPLL Mux */
+static struct clk *clk_src_mpll_list[] = {
+ [0] = &clk_fin_mpll,
+ [1] = &clk_fout_mpll,
+};
+
+struct clksrc_sources clk_src_mpll = {
+ .sources = clk_src_mpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
+};
+
+/* Possible clock sources for EPLL Mux */
+static struct clk *clk_src_epll_list[] = {
+ [0] = &clk_fin_epll,
+ [1] = &clk_fout_epll,
+};
+
+struct clksrc_sources clk_src_epll = {
+ .sources = clk_src_epll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_epll_list),
+};
+
+/* Possible clock sources for DPLL Mux */
+static struct clk *clk_src_dpll_list[] = {
+ [0] = &clk_fin_dpll,
+ [1] = &clk_fout_dpll,
+};
+
+struct clksrc_sources clk_src_dpll = {
+ .sources = clk_src_dpll_list,
+ .nr_sources = ARRAY_SIZE(clk_src_dpll_list),
+};
+
+struct clk clk_vpll = {
+ .name = "vpll",
+ .id = -1,
+};
+
+int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ u32 con;
+
+ con = __raw_readl(reg);
+ con = enable ? (con | ctrlbit) : (con & ~ctrlbit);
+ __raw_writel(con, reg);
+ return 0;
+}
+
+int s5p_epll_enable(struct clk *clk, int enable)
+{
+ unsigned int ctrlbit = clk->ctrlbit;
+ unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
+
+ if (enable)
+ __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
+ else
+ __raw_writel(epll_con, S5P_EPLL_CON);
+
+ return 0;
+}
+
+unsigned long s5p_epll_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+
+static struct clk *s5p_clks[] __initdata = {
+ &clk_ext_xtal_mux,
+ &clk_48m,
+ &s5p_clk_27m,
+ &clk_fout_apll,
+ &clk_fout_mpll,
+ &clk_fout_epll,
+ &clk_fout_dpll,
+ &clk_fout_vpll,
+ &clk_vpll,
+ &clk_xusbxti,
+};
+
+void __init s5p_register_clocks(unsigned long xtal_freq)
+{
+ int ret;
+
+ clk_ext_xtal_mux.rate = xtal_freq;
+
+ ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks));
+ if (ret > 0)
+ printk(KERN_ERR "Failed to register s5p clocks\n");
+}
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
new file mode 100644
index 00000000..bbc2aa74
--- /dev/null
+++ b/arch/arm/plat-s5p/cpu.c
@@ -0,0 +1,126 @@
+/* linux/arch/arm/plat-s5p/cpu.c
+ *
+ * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P 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/init.h>
+#include <linux/module.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/cpu.h>
+#include <plat/s5p6440.h>
+#include <plat/s5p6450.h>
+#include <plat/s5pc100.h>
+#include <plat/s5pv210.h>
+#include <plat/exynos4.h>
+
+/* table of supported CPUs */
+
+static const char name_s5p6440[] = "S5P6440";
+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 struct cpu_table cpu_ids[] __initdata = {
+ {
+ .idcode = 0x56440100,
+ .idmask = 0xfffff000,
+ .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,
+ .map_io = s5p6450_map_io,
+ .init_clocks = s5p6450_init_clocks,
+ .init_uarts = s5p6450_init_uarts,
+ .init = s5p64x0_init,
+ .name = name_s5p6450,
+ }, {
+ .idcode = 0x43100000,
+ .idmask = 0xfffff000,
+ .map_io = s5pc100_map_io,
+ .init_clocks = s5pc100_init_clocks,
+ .init_uarts = s5pc100_init_uarts,
+ .init = s5pc100_init,
+ .name = name_s5pc100,
+ }, {
+ .idcode = 0x43110000,
+ .idmask = 0xfffff000,
+ .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,
+ .map_io = exynos4_map_io,
+ .init_clocks = exynos4_init_clocks,
+ .init_uarts = exynos4_init_uarts,
+ .init = exynos4_init,
+ .name = name_exynos4210,
+ },
+};
+
+/* minimal IO mapping */
+
+static struct map_desc s5p_iodesc[] __initdata = {
+ {
+ .virtual = (unsigned long)S5P_VA_CHIPID,
+ .pfn = __phys_to_pfn(S5P_PA_CHIPID),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_SYS,
+ .pfn = __phys_to_pfn(S5P_PA_SYSCON),
+ .length = SZ_64K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_TIMER,
+ .pfn = __phys_to_pfn(S5P_PA_TIMER),
+ .length = SZ_16K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S3C_VA_WATCHDOG,
+ .pfn = __phys_to_pfn(S3C_PA_WDT),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ }, {
+ .virtual = (unsigned long)S5P_VA_SROMC,
+ .pfn = __phys_to_pfn(S5P_PA_SROMC),
+ .length = SZ_4K,
+ .type = MT_DEVICE,
+ },
+};
+
+/* read cpu identification code */
+
+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));
+}
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
new file mode 100644
index 00000000..e3aabef5
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series device definition for MIPI-CSIS channel 0
+ *
+ * This program is free software; you can 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_mipi_csis0_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS0,
+ .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPI_CSIS0,
+ .end = IRQ_MIPI_CSIS0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s5p_device_mipi_csis0 = {
+ .name = "s5p-mipi-csis",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
+ .resource = s5p_mipi_csis0_resource,
+};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
new file mode 100644
index 00000000..08b91b58
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series device definition for MIPI-CSIS channel 1
+ *
+ * This program is free software; you can 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_mipi_csis1_resource[] = {
+ [0] = {
+ .start = S5P_PA_MIPI_CSIS1,
+ .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MIPI_CSIS1,
+ .end = IRQ_MIPI_CSIS1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_mipi_csis1 = {
+ .name = "s5p-mipi-csis",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
+ .resource = s5p_mipi_csis1_resource,
+};
diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c
new file mode 100644
index 00000000..94080fff
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-ehci.c
@@ -0,0 +1,57 @@
+/*
+ * 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/platform_device.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/ehci.h>
+#include <plat/usb-phy.h>
+
+/* USB EHCI Host Controller registration */
+static struct resource s5p_ehci_resource[] = {
+ [0] = {
+ .start = S5P_PA_EHCI,
+ .end = S5P_PA_EHCI + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USB_HOST,
+ .end = IRQ_USB_HOST,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s5p_device_ehci_dmamask = 0xffffffffUL;
+
+struct platform_device s5p_device_ehci = {
+ .name = "s5p-ehci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_ehci_resource),
+ .resource = s5p_ehci_resource,
+ .dev = {
+ .dma_mask = &s5p_device_ehci_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
+{
+ struct s5p_ehci_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
+ &s5p_device_ehci);
+
+ 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-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
new file mode 100644
index 00000000..608770fc
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc0.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s5p/dev-fimc0.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMC0 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_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,
+ },
+};
+
+static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimc0 = {
+ .name = "s5p-fimc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s5p_fimc0_resource),
+ .resource = s5p_fimc0_resource,
+ .dev = {
+ .dma_mask = &s5p_fimc0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
new file mode 100644
index 00000000..76e3a97a
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc1.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s5p/dev-fimc1.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMC1 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_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,
+ },
+};
+
+static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimc1 = {
+ .name = "s5p-fimc",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s5p_fimc1_resource),
+ .resource = s5p_fimc1_resource,
+ .dev = {
+ .dma_mask = &s5p_fimc1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
new file mode 100644
index 00000000..24d29816
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc2.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s5p/dev-fimc2.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMC2 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_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,
+ },
+};
+
+static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimc2 = {
+ .name = "s5p-fimc",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s5p_fimc2_resource),
+ .resource = s5p_fimc2_resource,
+ .dev = {
+ .dma_mask = &s5p_fimc2_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c
new file mode 100644
index 00000000..ef31beca
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc3.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s5p/dev-fimc3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMC3 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_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,
+ },
+};
+
+static u64 s5p_fimc3_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimc3 = {
+ .name = "s5p-fimc",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s5p_fimc3_resource),
+ .resource = s5p_fimc3_resource,
+ .dev = {
+ .dma_mask = &s5p_fimc3_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-s5p/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c
new file mode 100644
index 00000000..20336c8f
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-onenand.c
@@ -0,0 +1,45 @@
+/* linux/arch/arm/plat-s5p/dev-onenand.c
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2008-2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5P series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s5p_onenand_resources[] = {
+ [0] = {
+ .start = S5P_PA_ONENAND,
+ .end = S5P_PA_ONENAND + SZ_128K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S5P_PA_ONENAND_DMA,
+ .end = S5P_PA_ONENAND_DMA + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_ONENAND_AUDI,
+ .end = IRQ_ONENAND_AUDI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s5p_device_onenand = {
+ .name = "s5pc110-onenand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s5p_onenand_resources),
+ .resource = s5p_onenand_resources,
+};
diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c
new file mode 100644
index 00000000..a08576da
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-pmu.c
@@ -0,0 +1,36 @@
+/*
+ * linux/arch/arm/plat-s5p/dev-pmu.c
+ *
+ * Copyright (C) 2010 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/platform_device.h>
+#include <asm/pmu.h>
+#include <mach/irqs.h>
+
+static struct resource s5p_pmu_resource = {
+ .start = IRQ_PMU,
+ .end = IRQ_PMU,
+ .flags = IORESOURCE_IRQ,
+};
+
+struct platform_device s5p_device_pmu = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = 1,
+ .resource = &s5p_pmu_resource,
+};
+
+static int __init s5p_pmu_init(void)
+{
+ platform_device_register(&s5p_device_pmu);
+ return 0;
+}
+arch_initcall(s5p_pmu_init);
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
new file mode 100644
index 00000000..afaf87fd
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-uart.c
@@ -0,0 +1,197 @@
+/* linux/arch/arm/plat-s5p/dev-uart.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Base S5P UART 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/types.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+ /* Serial port registrations */
+
+static struct resource s5p_uart0_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART0,
+ .end = S5P_PA_UART0 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX0,
+ .end = IRQ_S5P_UART_RX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX0,
+ .end = IRQ_S5P_UART_TX0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR0,
+ .end = IRQ_S5P_UART_ERR0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource s5p_uart1_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART1,
+ .end = S5P_PA_UART1 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX1,
+ .end = IRQ_S5P_UART_RX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX1,
+ .end = IRQ_S5P_UART_TX1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR1,
+ .end = IRQ_S5P_UART_ERR1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s5p_uart2_resource[] = {
+ [0] = {
+ .start = S5P_PA_UART2,
+ .end = S5P_PA_UART2 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX2,
+ .end = IRQ_S5P_UART_RX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX2,
+ .end = IRQ_S5P_UART_TX2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR2,
+ .end = IRQ_S5P_UART_ERR2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource s5p_uart3_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [0] = {
+ .start = S5P_PA_UART3,
+ .end = S5P_PA_UART3 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX3,
+ .end = IRQ_S5P_UART_RX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX3,
+ .end = IRQ_S5P_UART_TX3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR3,
+ .end = IRQ_S5P_UART_ERR3,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+static struct resource s5p_uart4_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
+ [0] = {
+ .start = S5P_PA_UART4,
+ .end = S5P_PA_UART4 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX4,
+ .end = IRQ_S5P_UART_RX4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX4,
+ .end = IRQ_S5P_UART_TX4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR4,
+ .end = IRQ_S5P_UART_ERR4,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+static struct resource s5p_uart5_resource[] = {
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
+ [0] = {
+ .start = S5P_PA_UART5,
+ .end = S5P_PA_UART5 + S5P_SZ_UART - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_S5P_UART_RX5,
+ .end = IRQ_S5P_UART_RX5,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_S5P_UART_TX5,
+ .end = IRQ_S5P_UART_TX5,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_S5P_UART_ERR5,
+ .end = IRQ_S5P_UART_ERR5,
+ .flags = IORESOURCE_IRQ,
+ },
+#endif
+};
+
+struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
+ [0] = {
+ .resources = s5p_uart0_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart0_resource),
+ },
+ [1] = {
+ .resources = s5p_uart1_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart1_resource),
+ },
+ [2] = {
+ .resources = s5p_uart2_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart2_resource),
+ },
+ [3] = {
+ .resources = s5p_uart3_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart3_resource),
+ },
+ [4] = {
+ .resources = s5p_uart4_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart4_resource),
+ },
+ [5] = {
+ .resources = s5p_uart5_resource,
+ .nr_resources = ARRAY_SIZE(s5p_uart5_resource),
+ },
+};
diff --git a/arch/arm/plat-s5p/include/plat/camport.h b/arch/arm/plat-s5p/include/plat/camport.h
new file mode 100644
index 00000000..71688c8b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/camport.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series camera interface 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.
+ */
+
+#ifndef PLAT_S5P_CAMPORT_H_
+#define PLAT_S5P_CAMPORT_H_ __FILE__
+
+enum s5p_camport_id {
+ S5P_CAMPORT_A,
+ S5P_CAMPORT_B,
+};
+
+/*
+ * The helper functions to configure GPIO for the camera parallel bus.
+ * The camera port can be multiplexed with any FIMC entity, even multiple
+ * FIMC entities are allowed to be attached to a single port simultaneously.
+ * These functions are to be used in the board setup code.
+ */
+int s5pv210_fimc_setup_gpio(enum s5p_camport_id id);
+int exynos4_fimc_setup_gpio(enum s5p_camport_id id);
+
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h
new file mode 100644
index 00000000..6ae6810c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/ehci.h
@@ -0,0 +1,21 @@
+/*
+ * 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_EHCI_H
+#define __PLAT_S5P_EHCI_H
+
+struct s5p_ehci_platdata {
+ int (*phy_init)(struct platform_device *pdev, int type);
+ int (*phy_exit)(struct platform_device *pdev, int type);
+};
+
+extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+
+#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
new file mode 100644
index 00000000..907caab5
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -0,0 +1,34 @@
+/* linux/arch/arm/plat-s5p/include/plat/exynos4.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for exynos4 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 EXYNOS4 related SoCs */
+
+extern void exynos4_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
+
+extern int exynos4_init(void);
+extern void exynos4_init_irq(void);
+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
+
+#else
+#define exynos4_init_clocks NULL
+#define exynos4_init_uarts NULL
+#define exynos4_map_io NULL
+#define exynos4_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
new file mode 100644
index 00000000..ba9121c6
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -0,0 +1,115 @@
+/* linux/arch/arm/plat-s5p/include/plat/irqs.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P Common IRQ 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_PLAT_S5P_IRQS_H
+#define __ASM_PLAT_S5P_IRQS_H __FILE__
+
+/* we keep the first set of CPU IRQs out of the range of
+ * the ISA space, so that the PC104 has them to itself
+ * and we don't end up having to do horrible things to the
+ * standard ISA drivers....
+ *
+ * note, since we're using the VICs, our start must be a
+ * mulitple of 32 to allow the common code to work
+ */
+
+#define S5P_IRQ_OFFSET (32)
+
+#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET)
+
+#define S5P_VIC0_BASE S5P_IRQ(0)
+#define S5P_VIC1_BASE S5P_IRQ(32)
+#define S5P_VIC2_BASE S5P_IRQ(64)
+#define S5P_VIC3_BASE S5P_IRQ(96)
+
+#define VIC_BASE(x) (S5P_VIC0_BASE + ((x)*32))
+
+#define IRQ_VIC0_BASE S5P_VIC0_BASE
+#define IRQ_VIC1_BASE S5P_VIC1_BASE
+#define IRQ_VIC2_BASE S5P_VIC2_BASE
+
+/* UART interrupts, each UART has 4 intterupts per channel so
+ * use the space between the ISA and S3C main interrupts. Note, these
+ * are not in the same order as the S3C24XX series! */
+
+#define IRQ_S5P_UART_BASE0 (16)
+#define IRQ_S5P_UART_BASE1 (20)
+#define IRQ_S5P_UART_BASE2 (24)
+#define IRQ_S5P_UART_BASE3 (28)
+
+#define UART_IRQ_RXD (0)
+#define UART_IRQ_ERR (1)
+#define UART_IRQ_TXD (2)
+
+#define IRQ_S5P_UART_RX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR0 (IRQ_S5P_UART_BASE0 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR1 (IRQ_S5P_UART_BASE1 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR2 (IRQ_S5P_UART_BASE2 + UART_IRQ_ERR)
+
+#define IRQ_S5P_UART_RX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_RXD)
+#define IRQ_S5P_UART_TX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_TXD)
+#define IRQ_S5P_UART_ERR3 (IRQ_S5P_UART_BASE3 + UART_IRQ_ERR)
+
+/* S3C compatibilty defines */
+#define IRQ_S3CUART_RX0 IRQ_S5P_UART_RX0
+#define IRQ_S3CUART_RX1 IRQ_S5P_UART_RX1
+#define IRQ_S3CUART_RX2 IRQ_S5P_UART_RX2
+#define IRQ_S3CUART_RX3 IRQ_S5P_UART_RX3
+
+/* VIC based IRQs */
+
+#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x))
+#define S5P_IRQ_VIC1(x) (S5P_VIC1_BASE + (x))
+#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
+#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
+
+#define S5P_TIMER_IRQ(x) (11 + (x))
+
+#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
+#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
+#define IRQ_TIMER2 S5P_TIMER_IRQ(2)
+#define IRQ_TIMER3 S5P_TIMER_IRQ(3)
+#define IRQ_TIMER4 S5P_TIMER_IRQ(4)
+
+#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
+ : ((x) - 16 + S5P_EINT_BASE2))
+
+#define EINT_OFFSET(irq) ((irq) < S5P_EINT_BASE2 ? \
+ ((irq) - S5P_EINT_BASE1) : \
+ ((irq) + 16 - S5P_EINT_BASE2))
+
+#define IRQ_EINT_BIT(x) EINT_OFFSET(x)
+
+/* Typically only a few gpio chips require gpio interrupt support.
+ To avoid memory waste irq descriptors are allocated only for
+ S5P_GPIOINT_GROUP_COUNT chips, each with total number of
+ S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
+ to any gpio chip with the s5p_register_gpio_interrupt() function */
+#define S5P_GPIOINT_GROUP_COUNT 4
+#define S5P_GPIOINT_GROUP_SIZE 8
+#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
+
+/* IRQ types common for all s5p platforms */
+#define S5P_IRQ_TYPE_LEVEL_LOW (0x00)
+#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01)
+#define S5P_IRQ_TYPE_EDGE_FALLING (0x02)
+#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
+#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
+
+#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
new file mode 100644
index 00000000..d973d396
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -0,0 +1,60 @@
+/* linux/arch/arm/plat-s5p/include/plat/map-s5p.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - 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_PLAT_MAP_S5P_H
+#define __ASM_PLAT_MAP_S5P_H __FILE__
+
+#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
+#define S5P_VA_CMU S3C_ADDR(0x02100000)
+#define S5P_VA_PMU S3C_ADDR(0x02180000)
+#define S5P_VA_GPIO S3C_ADDR(0x02200000)
+#define S5P_VA_GPIO1 S5P_VA_GPIO
+#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
+#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
+
+#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
+#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
+#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
+#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
+
+#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
+#define S5P_VA_L2CC S3C_ADDR(0x02600000)
+
+#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000)
+#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
+
+#define S5P_VA_COREPERI_BASE S3C_ADDR(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 S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
+
+#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
+#define VA_VIC0 VA_VIC(0)
+#define VA_VIC1 VA_VIC(1)
+#define VA_VIC2 VA_VIC(2)
+#define VA_VIC3 VA_VIC(3)
+
+#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
+#define S5P_VA_UART0 S5P_VA_UART(0)
+#define S5P_VA_UART1 S5P_VA_UART(1)
+#define S5P_VA_UART2 S5P_VA_UART(2)
+#define S5P_VA_UART3 S5P_VA_UART(3)
+
+#ifndef S3C_UART_OFFSET
+#define S3C_UART_OFFSET (0x400)
+#endif
+
+#endif /* __ASM_PLAT_MAP_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-s5p/include/plat/mipi_csis.h
new file mode 100644
index 00000000..9bd254c5
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mipi_csis.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P series MIPI CSI slave 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_MIPI_CSIS_H_
+#define PLAT_S5P_MIPI_CSIS_H_ __FILE__
+
+struct platform_device;
+
+/**
+ * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver
+ * @clk_rate: bus clock frequency
+ * @lanes: number of data lanes used
+ * @alignment: data alignment in bits
+ * @hs_settle: HS-RX settle time
+ * @fixed_phy_vdd: false to enable external D-PHY regulator management in the
+ * driver or true in case this regulator has no enable function
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct s5p_platform_mipi_csis {
+ unsigned long clk_rate;
+ u8 lanes;
+ u8 alignment;
+ u8 hs_settle;
+ bool fixed_phy_vdd;
+ int (*phy_enable)(struct platform_device *pdev, bool on);
+};
+
+/**
+ * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
+ * @pdev: MIPI-CSIS platform device
+ * @on: true to enable D-PHY and deassert its reset
+ * false to disable D-PHY
+ */
+int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
+
+#endif /* PLAT_S5P_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
new file mode 100644
index 00000000..bf28fade
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -0,0 +1,153 @@
+/* arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P PLL code
+ *
+ * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define PLL45XX_MDIV_MASK (0x3FF)
+#define PLL45XX_PDIV_MASK (0x3F)
+#define PLL45XX_SDIV_MASK (0x7)
+#define PLL45XX_MDIV_SHIFT (16)
+#define PLL45XX_PDIV_SHIFT (8)
+#define PLL45XX_SDIV_SHIFT (0)
+
+#include <asm/div64.h>
+
+enum pll45xx_type_t {
+ pll_4500,
+ pll_4502,
+ pll_4508
+};
+
+static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+ enum pll45xx_type_t pll_type)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+ if (pll_type == pll_4508)
+ sdiv = sdiv - 1;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
+
+#define PLL46XX_KDIV_MASK (0xFFFF)
+#define PLL4650C_KDIV_MASK (0xFFF)
+#define PLL46XX_MDIV_MASK (0x1FF)
+#define PLL46XX_PDIV_MASK (0x3F)
+#define PLL46XX_SDIV_MASK (0x7)
+#define PLL46XX_MDIV_SHIFT (16)
+#define PLL46XX_PDIV_SHIFT (8)
+#define PLL46XX_SDIV_SHIFT (0)
+
+enum pll46xx_type_t {
+ pll_4600,
+ pll_4650,
+ pll_4650c,
+};
+
+static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
+ u32 pll_con0, u32 pll_con1,
+ enum pll46xx_type_t pll_type)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ 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;
+ else
+ kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
+ tmp = baseclk;
+
+ if (pll_type == pll_4600) {
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+ } else {
+ tmp *= (mdiv << 10) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 10;
+ }
+
+ return result;
+}
+
+#define PLL90XX_MDIV_MASK (0xFF)
+#define PLL90XX_PDIV_MASK (0x3F)
+#define PLL90XX_SDIV_MASK (0x7)
+#define PLL90XX_KDIV_MASK (0xffff)
+#define PLL90XX_MDIV_SHIFT (16)
+#define PLL90XX_PDIV_SHIFT (8)
+#define PLL90XX_SDIV_SHIFT (0)
+#define PLL90XX_KDIV_SHIFT (0)
+
+static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
+ u32 pll_con, u32 pll_conk)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
+ kdiv = pll_conk & PLL90XX_KDIV_MASK;
+
+ /* We need to multiple baseclk by mdiv (the integer part) and kdiv
+ * which is in 2^16ths, so shift mdiv up (does not overflow) and
+ * add kdiv before multiplying. The use of tmp is to avoid any
+ * overflows before shifting bac down into result when multipling
+ * by the mdiv and kdiv pair.
+ */
+
+ tmp = baseclk;
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
+
+#define PLL65XX_MDIV_MASK (0x3FF)
+#define PLL65XX_PDIV_MASK (0x3F)
+#define PLL65XX_SDIV_MASK (0x7)
+#define PLL65XX_MDIV_SHIFT (16)
+#define PLL65XX_PDIV_SHIFT (8)
+#define PLL65XX_SDIV_SHIFT (0)
+
+static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
+{
+ u32 mdiv, pdiv, sdiv;
+ u64 fvco = baseclk;
+
+ mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
+ pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
+ sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+
+ fvco *= mdiv;
+ do_div(fvco, (pdiv << sdiv));
+
+ return (unsigned long)fvco;
+}
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
new file mode 100644
index 00000000..f121ab5e
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P SROMC register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_REGS_SROM_H
+#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
+
+#include <mach/map.h>
+
+#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
+
+#define S5P_SROM_BW S5P_SROMREG(0x0)
+#define S5P_SROM_BC0 S5P_SROMREG(0x4)
+#define S5P_SROM_BC1 S5P_SROMREG(0x8)
+#define S5P_SROM_BC2 S5P_SROMREG(0xc)
+#define S5P_SROM_BC3 S5P_SROMREG(0x10)
+#define S5P_SROM_BC4 S5P_SROMREG(0x14)
+#define S5P_SROM_BC5 S5P_SROMREG(0x18)
+
+/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
+
+#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
+#define S5P_SROM_BW__ADDRMODE__SHIFT 1
+#define S5P_SROM_BW__WAITENABLE__SHIFT 2
+#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
+
+#define S5P_SROM_BW__CS_MASK 0xf
+
+#define S5P_SROM_BW__NCS0__SHIFT 0
+#define S5P_SROM_BW__NCS1__SHIFT 4
+#define S5P_SROM_BW__NCS2__SHIFT 8
+#define S5P_SROM_BW__NCS3__SHIFT 12
+#define S5P_SROM_BW__NCS4__SHIFT 16
+#define S5P_SROM_BW__NCS5__SHIFT 20
+
+/* applies to same to BCS0 - BCS3 */
+
+#define S5P_SROM_BCX__PMC__SHIFT 0
+#define S5P_SROM_BCX__TACP__SHIFT 4
+#define S5P_SROM_BCX__TCAH__SHIFT 8
+#define S5P_SROM_BCX__TCOH__SHIFT 12
+#define S5P_SROM_BCX__TACC__SHIFT 16
+#define S5P_SROM_BCX__TCOS__SHIFT 24
+#define S5P_SROM_BCX__TACS__SHIFT 28
+
+#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/include/plat/reset.h b/arch/arm/plat-s5p/include/plat/reset.h
new file mode 100644
index 00000000..335e9781
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/reset.h
@@ -0,0 +1,16 @@
+/* linux/arch/arm/plat-s5p/include/plat/reset.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.
+*/
+
+#ifndef __ASM_PLAT_S5P_RESET_H
+#define __ASM_PLAT_S5P_RESET_H __FILE__
+
+extern void (*s5p_reset_hook)(void);
+
+#endif /* __ASM_PLAT_S5P_RESET_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
new file mode 100644
index 00000000..2b6dcff8
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -0,0 +1,50 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
+ *
+ * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for s5p 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_PLAT_S5P_CLOCK_H
+#define __ASM_PLAT_S5P_CLOCK_H __FILE__
+
+#include <linux/clk.h>
+
+#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
+
+#define clk_fin_apll clk_ext_xtal_mux
+#define clk_fin_mpll clk_ext_xtal_mux
+#define clk_fin_epll clk_ext_xtal_mux
+#define clk_fin_dpll clk_ext_xtal_mux
+#define clk_fin_vpll clk_ext_xtal_mux
+#define clk_fin_hpll clk_ext_xtal_mux
+
+extern struct clk clk_ext_xtal_mux;
+extern struct clk clk_xusbxti;
+extern struct clk clk_48m;
+extern struct clk s5p_clk_27m;
+extern struct clk clk_fout_apll;
+extern struct clk clk_fout_mpll;
+extern struct clk clk_fout_epll;
+extern struct clk clk_fout_dpll;
+extern struct clk clk_fout_vpll;
+extern struct clk clk_arm;
+extern struct clk clk_vpll;
+
+extern struct clksrc_sources clk_src_apll;
+extern struct clksrc_sources clk_src_mpll;
+extern struct clksrc_sources clk_src_epll;
+extern struct clksrc_sources clk_src_dpll;
+
+extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
+
+/* Common EPLL operations for S5P platform */
+extern int s5p_epll_enable(struct clk *clk, int enable);
+extern unsigned long s5p_epll_get_rate(struct clk *clk);
+
+#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
new file mode 100644
index 00000000..575e8810
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p time 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_PLAT_S5P_TIME_H
+#define __ASM_PLAT_S5P_TIME_H __FILE__
+
+/* S5P HR-Timer Clock mode */
+enum s5p_timer_mode {
+ S5P_PWM0,
+ S5P_PWM1,
+ S5P_PWM2,
+ S5P_PWM3,
+ S5P_PWM4,
+};
+
+struct s5p_timer_source {
+ unsigned int event_id;
+ unsigned int source_id;
+};
+
+/* Be able to sleep for atleast 4 seconds (usually more) */
+#define S5PTIMER_MIN_RANGE 4
+
+#define TCNT_MAX 0xffffffff
+#define NON_PERIODIC 0
+#define PERIODIC 1
+
+extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
+ enum s5p_timer_mode source);
+extern struct sys_timer s5p_timer;
+#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
new file mode 100644
index 00000000..528585d2
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -0,0 +1,36 @@
+/* arch/arm/plat-s5p/include/plat/s5p6440.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5p6440 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 S5P6440 related SoCs */
+
+extern void s5p6440_register_clocks(void);
+extern void s5p6440_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6440
+
+extern int s5p64x0_init(void);
+extern void s5p6440_init_irq(void);
+extern void s5p6440_map_io(void);
+extern void s5p6440_init_clocks(int xtal);
+
+extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6440_init_clocks NULL
+#define s5p6440_init_uarts NULL
+#define s5p6440_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6440 timer */
+
+extern struct sys_timer s5p6440_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h
new file mode 100644
index 00000000..640a41c2
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6450.h
@@ -0,0 +1,36 @@
+/* arch/arm/plat-s5p/include/plat/s5p6450.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Header file for s5p6450 cpu support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Common init code for S5P6450 related SoCs */
+
+extern void s5p6450_register_clocks(void);
+extern void s5p6450_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5P6450
+
+extern int s5p64x0_init(void);
+extern void s5p6450_init_irq(void);
+extern void s5p6450_map_io(void);
+extern void s5p6450_init_clocks(int xtal);
+
+extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+#else
+#define s5p6450_init_clocks NULL
+#define s5p6450_init_uarts NULL
+#define s5p6450_map_io NULL
+#define s5p64x0_init NULL
+#endif
+
+/* S5P6450 timer */
+
+extern struct sys_timer s5p6450_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-s5p/include/plat/s5pc100.h
new file mode 100644
index 00000000..5f6099dd
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pc100.h
@@ -0,0 +1,33 @@
+/* arch/arm/plat-s5p/include/plat/s5pc100.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5pc100 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 S5PC100 related SoCs */
+
+extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pc100_register_clocks(void);
+extern void s5pc100_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PC100
+
+extern int s5pc100_init(void);
+extern void s5pc100_init_irq(void);
+extern void s5pc100_map_io(void);
+extern void s5pc100_init_clocks(int xtal);
+
+#define s5pc100_init_uarts s5pc100_common_init_uarts
+
+#else
+#define s5pc100_init_clocks NULL
+#define s5pc100_init_uarts NULL
+#define s5pc100_map_io NULL
+#define s5pc100_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
new file mode 100644
index 00000000..6c93a0c7
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -0,0 +1,33 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for s5pv210 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 S5PV210 related SoCs */
+
+extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s5pv210_register_clocks(void);
+extern void s5pv210_setup_clocks(void);
+
+#ifdef CONFIG_CPU_S5PV210
+
+extern int s5pv210_init(void);
+extern void s5pv210_init_irq(void);
+extern void s5pv210_map_io(void);
+extern void s5pv210_init_clocks(int xtal);
+
+#define s5pv210_init_uarts s5pv210_common_init_uarts
+
+#else
+#define s5pv210_init_clocks NULL
+#define s5pv210_init_uarts NULL
+#define s5pv210_map_io NULL
+#define s5pv210_init NULL
+#endif
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
new file mode 100644
index 00000000..bf5283c2
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/sysmmu.h
@@ -0,0 +1,95 @@
+/* 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
new file mode 100644
index 00000000..f307f34e
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/system-reset.h
@@ -0,0 +1,31 @@
+/* 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/watchdog-reset.h>
+
+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();
+}
diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h
new file mode 100644
index 00000000..6dd6bcfc
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/usb-phy.h
@@ -0,0 +1,22 @@
+/*
+ * 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_PHY_H
+#define __PLAT_S5P_USB_PHY_H
+
+enum s5p_usb_phy_type {
+ S5P_USB_PHY_DEVICE,
+ S5P_USB_PHY_HOST,
+};
+
+extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+
+#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
new file mode 100644
index 00000000..b5bb7749
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -0,0 +1,219 @@
+/* linux/arch/arm/plat-s5p/irq-eint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P - IRQ EINT support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/sysdev.h>
+#include <linux/gpio.h>
+
+#include <asm/hardware/vic.h>
+
+#include <plat/regs-irqtype.h>
+
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+
+static inline void s5p_irq_eint_mask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask |= eint_irq_to_bit(data->irq);
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+}
+
+static void s5p_irq_eint_unmask(struct irq_data *data)
+{
+ u32 mask;
+
+ mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+ mask &= ~(eint_irq_to_bit(data->irq));
+ __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
+}
+
+static inline void s5p_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 s5p_irq_eint_maskack(struct irq_data *data)
+{
+ /* compiler should in-line these */
+ s5p_irq_eint_mask(data);
+ s5p_irq_eint_ack(data);
+}
+
+static int s5p_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;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ newvalue = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+
+ default:
+ printk(KERN_ERR "No such irq type %d", type);
+ return -EINVAL;
+ }
+
+ shift = (offs & 0x7) * 4;
+ mask = 0x7 << shift;
+
+ ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
+ ctrl &= ~mask;
+ ctrl |= newvalue << shift;
+ __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
+
+ if ((0 <= offs) && (offs < 8))
+ s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
+
+ else if ((8 <= offs) && (offs < 16))
+ s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
+
+ else if ((16 <= offs) && (offs < 24))
+ s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
+
+ else if ((24 <= offs) && (offs < 32))
+ s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
+
+ else
+ printk(KERN_ERR "No such irq number %d", offs);
+
+ return 0;
+}
+
+static struct irq_chip s5p_irq_eint = {
+ .name = "s5p-eint",
+ .irq_mask = s5p_irq_eint_mask,
+ .irq_unmask = s5p_irq_eint_unmask,
+ .irq_mask_ack = s5p_irq_eint_maskack,
+ .irq_ack = s5p_irq_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
+#ifdef CONFIG_PM
+ .irq_set_wake = s3c_irqext_wake,
+#endif
+};
+
+/* s5p_irq_demux_eint
+ *
+ * This function demuxes the IRQ from the group0 external interrupts,
+ * from EINTs 16 to 31. It is designed to be inlined into the specific
+ * handler s5p_irq_demux_eintX_Y.
+ *
+ * Each EINT pend/mask registers handle eight of them.
+ */
+static inline void 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;
+
+ status &= ~mask;
+ status &= 0xff;
+
+ while (status) {
+ irq = fls(status) - 1;
+ generic_handle_irq(irq + start);
+ status &= ~(1 << irq);
+ }
+}
+
+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));
+}
+
+static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(data);
+
+ s5p_irq_eint_mask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
+}
+
+static void s5p_irq_vic_eint_unmask(struct irq_data *data)
+{
+ void __iomem *base = irq_data_get_irq_chip_data(data);
+
+ s5p_irq_eint_unmask(data);
+ writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
+}
+
+static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
+{
+ __raw_writel(eint_irq_to_bit(data->irq),
+ S5P_EINT_PEND(EINT_REG_NR(data->irq)));
+}
+
+static void s5p_irq_vic_eint_maskack(struct irq_data *data)
+{
+ s5p_irq_vic_eint_mask(data);
+ s5p_irq_vic_eint_ack(data);
+}
+
+static struct irq_chip s5p_irq_vic_eint = {
+ .name = "s5p_vic_eint",
+ .irq_mask = s5p_irq_vic_eint_mask,
+ .irq_unmask = s5p_irq_vic_eint_unmask,
+ .irq_mask_ack = s5p_irq_vic_eint_maskack,
+ .irq_ack = s5p_irq_vic_eint_ack,
+ .irq_set_type = s5p_irq_eint_set_type,
+#ifdef CONFIG_PM
+ .irq_set_wake = s3c_irqext_wake,
+#endif
+};
+
+int __init s5p_init_irq_eint(void)
+{
+ int irq;
+
+ for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++)
+ irq_set_chip(irq, &s5p_irq_vic_eint);
+
+ for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
+ irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31);
+ return 0;
+}
+
+arch_initcall(s5p_init_irq_eint);
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
new file mode 100644
index 00000000..327ab9f6
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -0,0 +1,209 @@
+/* linux/arch/arm/plat-s5p/irq-gpioint.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * Author: Kyungmin Park <kyungmin.park@samsung.com>
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <mach/map.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+
+#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
+
+#define CON_OFFSET 0x700
+#define MASK_OFFSET 0x900
+#define PEND_OFFSET 0xA00
+#define REG_OFFSET(x) ((x) << 2)
+
+struct s5p_gpioint_bank {
+ struct list_head list;
+ int start;
+ int nr_groups;
+ int irq;
+ struct s3c_gpio_chip **chips;
+ void (*handler)(unsigned int, struct irq_desc *);
+};
+
+LIST_HEAD(banks);
+
+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;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ type = S5P_IRQ_TYPE_EDGE_RISING;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ type = S5P_IRQ_TYPE_EDGE_FALLING;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ type = S5P_IRQ_TYPE_EDGE_BOTH;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ type = S5P_IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ type = S5P_IRQ_TYPE_LEVEL_LOW;
+ break;
+ case IRQ_TYPE_NONE:
+ default:
+ printk(KERN_WARNING "No irq type\n");
+ return -EINVAL;
+ }
+
+ gc->type_cache &= ~(0x7 << shift);
+ gc->type_cache |= type << shift;
+ writel(gc->type_cache, gc->reg_base + ct->regs.type);
+ 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;
+
+ 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 (!pend)
+ continue;
+
+ mask_offset = REG_OFFSET(group);
+ mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
+ pend &= ~mask;
+
+ while (pend) {
+ int offset = fls(pend) - 1;
+ int real_irq = chip->irq_base + offset;
+ generic_handle_irq(real_irq);
+ pend &= ~BIT(offset);
+ }
+ }
+}
+
+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 irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
+ return -ENOMEM;
+
+ list_for_each_entry(bank, &banks, list) {
+ if (group >= bank->start &&
+ group < bank->start + bank->nr_groups)
+ break;
+ }
+ if (!bank)
+ return -EINVAL;
+
+ if (!bank->handler) {
+ bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
+ bank->nr_groups, GFP_KERNEL);
+ if (!bank->chips)
+ return -ENOMEM;
+
+ irq_set_chained_handler(bank->irq, s5p_gpioint_handler);
+ irq_set_handler_data(bank->irq, bank);
+ bank->handler = s5p_gpioint_handler;
+ printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
+ bank->irq);
+ }
+
+ /*
+ * chained GPIO irq has been successfully registered, allocate new gpio
+ * int group and assign irq nubmers
+ */
+ chip->irq_base = S5P_GPIOINT_BASE +
+ used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
+ used_gpioint_groups++;
+
+ bank->chips[group - bank->start] = chip;
+
+ gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
+ (void __iomem *)GPIO_BASE(chip),
+ handle_level_irq);
+ if (!gc)
+ return -ENOMEM;
+ 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);
+ irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
+ IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+ return 0;
+}
+
+int __init s5p_register_gpio_interrupt(int pin)
+{
+ struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
+ int offset, group;
+ int ret;
+
+ if (!my_chip)
+ return -EINVAL;
+
+ offset = pin - my_chip->chip.base;
+ group = my_chip->group;
+
+ /* check if the group has been already registered */
+ if (my_chip->irq_base)
+ return my_chip->irq_base + offset;
+
+ /* register gpio group */
+ ret = s5p_gpioint_add(my_chip);
+ if (ret == 0) {
+ my_chip->chip.to_irq = samsung_gpiolib_to_irq;
+ printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
+ group);
+ return my_chip->irq_base + offset;
+ }
+ return ret;
+}
+
+int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
+{
+ struct s5p_gpioint_bank *bank;
+
+ bank = kzalloc(sizeof(*bank), GFP_KERNEL);
+ if (!bank)
+ return -ENOMEM;
+
+ bank->start = start;
+ bank->nr_groups = nr_groups;
+ bank->irq = chain_irq;
+
+ list_add_tail(&bank->list, &banks);
+ return 0;
+}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
new file mode 100644
index 00000000..327acb3a
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -0,0 +1,90 @@
+/* linux/arch/arm/plat-s5p/irq-pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Based on arch/arm/plat-s3c24xx/irq-pm.c,
+ * Copyright (c) 2003,2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+
+#include <plat/cpu.h>
+#include <plat/irqs.h>
+#include <plat/pm.h>
+#include <mach/map.h>
+
+#include <mach/regs-gpio.h>
+#include <mach/regs-irq.h>
+
+/* state for IRQs over sleep */
+
+/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
+ * as wakeup sources
+ *
+ * set bit to 1 in allow bitfield to enable the wakeup settings on it
+*/
+
+unsigned long s3c_irqwake_intallow = 0x00000006L;
+unsigned long s3c_irqwake_eintallow = 0xffffffffL;
+
+int s3c_irq_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long irqbit;
+
+ switch (data->irq) {
+ case IRQ_RTC_TIC:
+ case IRQ_RTC_ALARM:
+ irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
+ if (!state)
+ s3c_irqwake_intmask |= irqbit;
+ else
+ s3c_irqwake_intmask &= ~irqbit;
+ break;
+ default:
+ return -ENOENT;
+ }
+ return 0;
+}
+
+static struct sleep_save eint_save[] = {
+ SAVE_ITEM(S5P_EINT_CON(0)),
+ SAVE_ITEM(S5P_EINT_CON(1)),
+ SAVE_ITEM(S5P_EINT_CON(2)),
+ SAVE_ITEM(S5P_EINT_CON(3)),
+
+ SAVE_ITEM(S5P_EINT_FLTCON(0)),
+ SAVE_ITEM(S5P_EINT_FLTCON(1)),
+ SAVE_ITEM(S5P_EINT_FLTCON(2)),
+ SAVE_ITEM(S5P_EINT_FLTCON(3)),
+ SAVE_ITEM(S5P_EINT_FLTCON(4)),
+ SAVE_ITEM(S5P_EINT_FLTCON(5)),
+ SAVE_ITEM(S5P_EINT_FLTCON(6)),
+ SAVE_ITEM(S5P_EINT_FLTCON(7)),
+
+ SAVE_ITEM(S5P_EINT_MASK(0)),
+ SAVE_ITEM(S5P_EINT_MASK(1)),
+ SAVE_ITEM(S5P_EINT_MASK(2)),
+ SAVE_ITEM(S5P_EINT_MASK(3)),
+};
+
+int s3c24xx_irq_suspend(void)
+{
+ s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
+
+ return 0;
+}
+
+void s3c24xx_irq_resume(void)
+{
+ s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
+}
+
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
new file mode 100644
index 00000000..a97c0895
--- /dev/null
+++ b/arch/arm/plat-s5p/irq.c
@@ -0,0 +1,70 @@
+/* arch/arm/plat-s5p/irq.c
+ *
+ * Copyright (c) 2009 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Interrupt handling
+ *
+ * This program is free software; you can 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 <asm/hardware/vic.h>
+
+#include <linux/serial_core.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/irq-uart.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.
+ */
+static struct s3c_uart_irq uart_irqs[] = {
+ [0] = {
+ .regs = S5P_VA_UART0,
+ .base_irq = IRQ_S5P_UART_BASE0,
+ .parent_irq = IRQ_UART0,
+ },
+ [1] = {
+ .regs = S5P_VA_UART1,
+ .base_irq = IRQ_S5P_UART_BASE1,
+ .parent_irq = IRQ_UART1,
+ },
+ [2] = {
+ .regs = S5P_VA_UART2,
+ .base_irq = IRQ_S5P_UART_BASE2,
+ .parent_irq = IRQ_UART2,
+ },
+#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
+ [3] = {
+ .regs = S5P_VA_UART3,
+ .base_irq = IRQ_S5P_UART_BASE3,
+ .parent_irq = IRQ_UART3,
+ },
+#endif
+};
+
+void __init s5p_init_irq(u32 *vic, u32 num_vic)
+{
+#ifdef CONFIG_ARM_VIC
+ int irq;
+
+ /* initialize the VICs */
+ for (irq = 0; irq < num_vic; irq++)
+ vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
+#endif
+
+ s3c_init_vic_timer_irq(5, IRQ_TIMER0);
+
+ s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
+}
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
new file mode 100644
index 00000000..d15dc47b
--- /dev/null
+++ b/arch/arm/plat-s5p/pm.c
@@ -0,0 +1,41 @@
+/* linux/arch/arm/plat-s5p/pm.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5P Power Manager (Suspend-To-RAM) support
+ *
+ * Based on arch/arm/plat-s3c24xx/pm.c
+ * Copyright (c) 2004,2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/suspend.h>
+#include <plat/pm.h>
+
+#define PFX "s5p pm: "
+
+/* s3c_pm_configure_extint
+ *
+ * configure all external interrupt pins
+*/
+
+void s3c_pm_configure_extint(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_restore_core(void)
+{
+ /* nothing here yet */
+}
+
+void s3c_pm_save_core(void)
+{
+ /* nothing here yet */
+}
+
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
new file mode 100644
index 00000000..612934c4
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p-time.c
@@ -0,0 +1,424 @@
+/* linux/arch/arm/plat-s5p/s5p-time.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P - Common hr-timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * 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 <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/sched_clock.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+#include <plat/s5p-time.h>
+
+static struct clk *tin_event;
+static struct clk *tin_source;
+static struct clk *tdiv_event;
+static struct clk *tdiv_source;
+static struct clk *timerclk;
+static struct s5p_timer_source timer_source;
+static unsigned long clock_count_per_tick;
+static void s5p_timer_resume(void);
+
+static void s5p_time_stop(enum s5p_timer_mode mode)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon &= ~S3C2410_TCON_T0START;
+ break;
+
+ case S5P_PWM1:
+ tcon &= ~S3C2410_TCON_T1START;
+ break;
+
+ case S5P_PWM2:
+ tcon &= ~S3C2410_TCON_T2START;
+ break;
+
+ case S5P_PWM3:
+ tcon &= ~S3C2410_TCON_T3START;
+ break;
+
+ case S5P_PWM4:
+ tcon &= ~S3C2410_TCON_T4START;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ tcnt--;
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon &= ~(0x0f << 0);
+ tcon |= S3C2410_TCON_T0MANUALUPD;
+ break;
+
+ case S5P_PWM1:
+ tcon &= ~(0x0f << 8);
+ tcon |= S3C2410_TCON_T1MANUALUPD;
+ break;
+
+ case S5P_PWM2:
+ tcon &= ~(0x0f << 12);
+ tcon |= S3C2410_TCON_T2MANUALUPD;
+ break;
+
+ case S5P_PWM3:
+ tcon &= ~(0x0f << 16);
+ tcon |= S3C2410_TCON_T3MANUALUPD;
+ break;
+
+ case S5P_PWM4:
+ tcon &= ~(0x07 << 20);
+ tcon |= S3C2410_TCON_T4MANUALUPD;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+
+ __raw_writel(tcnt, S3C2410_TCNTB(mode));
+ __raw_writel(tcnt, S3C2410_TCMPB(mode));
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
+{
+ unsigned long tcon;
+
+ tcon = __raw_readl(S3C2410_TCON);
+
+ switch (mode) {
+ case S5P_PWM0:
+ tcon |= S3C2410_TCON_T0START;
+ tcon &= ~S3C2410_TCON_T0MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T0RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T0RELOAD;
+ break;
+
+ case S5P_PWM1:
+ tcon |= S3C2410_TCON_T1START;
+ tcon &= ~S3C2410_TCON_T1MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T1RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T1RELOAD;
+ break;
+
+ case S5P_PWM2:
+ tcon |= S3C2410_TCON_T2START;
+ tcon &= ~S3C2410_TCON_T2MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T2RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T2RELOAD;
+ break;
+
+ case S5P_PWM3:
+ tcon |= S3C2410_TCON_T3START;
+ tcon &= ~S3C2410_TCON_T3MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T3RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T3RELOAD;
+ break;
+
+ case S5P_PWM4:
+ tcon |= S3C2410_TCON_T4START;
+ tcon &= ~S3C2410_TCON_T4MANUALUPD;
+
+ if (periodic)
+ tcon |= S3C2410_TCON_T4RELOAD;
+ else
+ tcon &= ~S3C2410_TCON_T4RELOAD;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", mode);
+ break;
+ }
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static int s5p_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ s5p_time_setup(timer_source.event_id, cycles);
+ s5p_time_start(timer_source.event_id, NON_PERIODIC);
+
+ return 0;
+}
+
+static void s5p_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ s5p_time_stop(timer_source.event_id);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+ s5p_time_start(timer_source.event_id, PERIODIC);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
+ s5p_timer_resume();
+ break;
+ }
+}
+
+static void s5p_timer_resume(void)
+{
+ /* event timer restart */
+ s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+ s5p_time_start(timer_source.event_id, PERIODIC);
+
+ /* source timer restart */
+ s5p_time_setup(timer_source.source_id, TCNT_MAX);
+ s5p_time_start(timer_source.source_id, PERIODIC);
+}
+
+void __init s5p_set_timer_source(enum s5p_timer_mode event,
+ enum s5p_timer_mode source)
+{
+ s3c_device_timer[event].dev.bus = &platform_bus_type;
+ s3c_device_timer[source].dev.bus = &platform_bus_type;
+
+ timer_source.event_id = event;
+ timer_source.source_id = source;
+}
+
+static struct clock_event_device time_event_device = {
+ .name = "s5p_event_timer",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 200,
+ .set_next_event = s5p_set_next_event,
+ .set_mode = s5p_set_mode,
+};
+
+static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction s5p_clock_event_irq = {
+ .name = "s5p_time_irq",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = s5p_clock_event_isr,
+ .dev_id = &time_event_device,
+};
+
+static void __init s5p_clockevent_init(void)
+{
+ unsigned long pclk;
+ unsigned long clock_rate;
+ unsigned int irq_number;
+ struct clk *tscaler;
+
+ pclk = clk_get_rate(timerclk);
+
+ tscaler = clk_get_parent(tdiv_event);
+
+ clk_set_rate(tscaler, pclk / 2);
+ clk_set_rate(tdiv_event, pclk / 2);
+ clk_set_parent(tin_event, tdiv_event);
+
+ clock_rate = clk_get_rate(tin_event);
+ clock_count_per_tick = clock_rate / HZ;
+
+ clockevents_calc_mult_shift(&time_event_device,
+ clock_rate, S5PTIMER_MIN_RANGE);
+ time_event_device.max_delta_ns =
+ clockevent_delta2ns(-1, &time_event_device);
+ time_event_device.min_delta_ns =
+ clockevent_delta2ns(1, &time_event_device);
+
+ time_event_device.cpumask = cpumask_of(0);
+ clockevents_register_device(&time_event_device);
+
+ irq_number = timer_source.event_id + IRQ_TIMER0;
+ setup_irq(irq_number, &s5p_clock_event_irq);
+}
+
+static void __iomem *s5p_timer_reg(void)
+{
+ unsigned long offset = 0;
+
+ switch (timer_source.source_id) {
+ case S5P_PWM0:
+ case S5P_PWM1:
+ case S5P_PWM2:
+ case S5P_PWM3:
+ offset = (timer_source.source_id * 0x0c) + 0x14;
+ break;
+
+ case S5P_PWM4:
+ offset = 0x40;
+ break;
+
+ default:
+ printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+ return NULL;
+ }
+
+ return S3C_TIMERREG(offset);
+}
+
+static cycle_t s5p_timer_read(struct clocksource *cs)
+{
+ void __iomem *reg = s5p_timer_reg();
+
+ return (cycle_t) (reg ? ~__raw_readl(reg) : 0);
+}
+
+/*
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by U300 implementation.)
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ void __iomem *reg = s5p_timer_reg();
+
+ if (!reg)
+ return 0;
+
+ return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
+}
+
+static void notrace s5p_update_sched_clock(void)
+{
+ void __iomem *reg = s5p_timer_reg();
+
+ if (!reg)
+ return;
+
+ update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
+}
+
+struct clocksource time_clocksource = {
+ .name = "s5p_clocksource_timer",
+ .rating = 250,
+ .read = s5p_timer_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init s5p_clocksource_init(void)
+{
+ unsigned long pclk;
+ unsigned long clock_rate;
+
+ pclk = clk_get_rate(timerclk);
+
+ clk_set_rate(tdiv_source, pclk / 2);
+ clk_set_parent(tin_source, tdiv_source);
+
+ clock_rate = clk_get_rate(tin_source);
+
+ s5p_time_setup(timer_source.source_id, TCNT_MAX);
+ s5p_time_start(timer_source.source_id, PERIODIC);
+
+ init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
+
+ if (clocksource_register_hz(&time_clocksource, clock_rate))
+ panic("%s: can't register clocksource\n", time_clocksource.name);
+}
+
+static void __init s5p_timer_resources(void)
+{
+
+ unsigned long event_id = timer_source.event_id;
+ unsigned long source_id = timer_source.source_id;
+
+ timerclk = clk_get(NULL, "timers");
+ if (IS_ERR(timerclk))
+ panic("failed to get timers clock for timer");
+
+ clk_enable(timerclk);
+
+ tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
+ if (IS_ERR(tin_event))
+ panic("failed to get pwm-tin clock for event timer");
+
+ tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
+ if (IS_ERR(tdiv_event))
+ panic("failed to get pwm-tdiv clock for event timer");
+
+ clk_enable(tin_event);
+
+ tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
+ if (IS_ERR(tin_source))
+ panic("failed to get pwm-tin clock for source timer");
+
+ tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
+ if (IS_ERR(tdiv_source))
+ panic("failed to get pwm-tdiv clock for source timer");
+
+ clk_enable(tin_source);
+}
+
+static void __init s5p_timer_init(void)
+{
+ s5p_timer_resources();
+ s5p_clockevent_init();
+ s5p_clocksource_init();
+}
+
+struct sys_timer s5p_timer = {
+ .init = s5p_timer_init,
+};
diff --git a/arch/arm/plat-s5p/setup-mipiphy.c b/arch/arm/plat-s5p/setup-mipiphy.c
new file mode 100644
index 00000000..683c466c
--- /dev/null
+++ b/arch/arm/plat-s5p/setup-mipiphy.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/spinlock.h>
+#include <mach/regs-clock.h>
+
+static int __s5p_mipi_phy_control(struct platform_device *pdev,
+ bool on, u32 reset)
+{
+ static DEFINE_SPINLOCK(lock);
+ void __iomem *addr;
+ unsigned long flags;
+ int pid;
+ u32 cfg;
+
+ if (!pdev)
+ return -EINVAL;
+
+ pid = (pdev->id == -1) ? 0 : pdev->id;
+
+ if (pid != 0 && pid != 1)
+ return -EINVAL;
+
+ addr = S5P_MIPI_DPHY_CONTROL(pid);
+
+ spin_lock_irqsave(&lock, flags);
+
+ cfg = __raw_readl(addr);
+ cfg = on ? (cfg | reset) : (cfg & ~reset);
+ __raw_writel(cfg, addr);
+
+ if (on) {
+ cfg |= S5P_MIPI_DPHY_ENABLE;
+ } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
+ S5P_MIPI_DPHY_MRESETN) & ~reset)) {
+ cfg &= ~S5P_MIPI_DPHY_ENABLE;
+ }
+
+ __raw_writel(cfg, addr);
+ spin_unlock_irqrestore(&lock, flags);
+
+ return 0;
+}
+
+int s5p_csis_phy_enable(struct platform_device *pdev, bool on)
+{
+ return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN);
+}
+
+int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
+{
+ return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN);
+}
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
new file mode 100644
index 00000000..54f5eddc
--- /dev/null
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -0,0 +1,312 @@
+/* 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
new file mode 100644
index 00000000..4d79519d
--- /dev/null
+++ b/arch/arm/plat-samsung/Kconfig
@@ -0,0 +1,364 @@
+# arch/arm/plat-samsung/Kconfig
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+config PLAT_SAMSUNG
+ bool
+ depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P
+ select NO_IOPORT
+ select GENERIC_IRQ_CHIP
+ default y
+ help
+ Base platform code for all Samsung SoC based systems
+
+if PLAT_SAMSUNG
+
+# boot configurations
+
+comment "Boot options"
+
+config S3C_BOOT_WATCHDOG
+ bool "S3C Initialisation watchdog"
+ depends on S3C2410_WATCHDOG
+ help
+ Say y to enable the watchdog during the kernel decompression
+ stage. If the kernel fails to uncompress, then the watchdog
+ will trigger a reset and the system should restart.
+
+config S3C_BOOT_ERROR_RESET
+ bool "S3C Reboot on decompression error"
+ help
+ Say y here to use the watchdog to reset the system if the
+ kernel decompressor detects an error during decompression.
+
+config S3C_BOOT_UART_FORCE_FIFO
+ bool "Force UART FIFO on during boot process"
+ default y
+ help
+ Say Y here to force the UART FIFOs on during the kernel
+ uncompressor
+
+
+config S3C_LOWLEVEL_UART_PORT
+ int "S3C UART to use for low-level messages"
+ default 0
+ help
+ Choice of which UART port to use for the low-level messages,
+ such as the `Uncompressing...` at start time. The value of
+ this configuration should be between zero and two. The port
+ must have been initialised by the boot-loader before use.
+
+# clock options
+
+config SAMSUNG_CLKSRC
+ bool
+ help
+ Select the clock code for the clksrc implementation
+ used by newer systems such as the S3C64XX.
+
+# options for IRQ support
+
+config SAMSUNG_IRQ_VIC_TIMER
+ bool
+ help
+ Internal configuration to build the VIC timer interrupt code.
+
+config SAMSUNG_IRQ_UART
+ bool
+ help
+ Internal configuration to build the IRQ UART demux code.
+
+# options for gpio configuration support
+
+config SAMSUNG_GPIOLIB_4BIT
+ bool
+ help
+ GPIOlib file contains the 4 bit modification functions for gpio
+ configuration. GPIOlib shall be compiled only for S3C64XX and S5P
+ series of processors.
+
+config S3C_GPIO_CFG_S3C24XX
+ bool
+ help
+ Internal configuration to enable S3C24XX style GPIO configuration
+ functions.
+
+config S3C_GPIO_CFG_S3C64XX
+ bool
+ help
+ Internal configuration to enable S3C64XX style GPIO configuration
+ functions.
+
+config S3C_GPIO_PULL_UPDOWN
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_S3C2443
+ bool
+ select S3C_GPIO_PULL_UPDOWN
+ help
+ Internal configuration to enable the correct GPIO pull helper for S3C2443-style GPIO
+
+config S3C_GPIO_PULL_DOWN
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config S3C_GPIO_PULL_UP
+ bool
+ help
+ Internal configuration to enable the correct GPIO pull helper
+
+config S5P_GPIO_DRVSTR
+ bool
+ help
+ Internal configuration to get and set correct GPIO driver strength
+ helper
+
+config SAMSUNG_GPIO_EXTRA
+ int "Number of additional GPIO pins"
+ default 0
+ help
+ Use additional GPIO space in addition to the GPIO's the SOC
+ provides. This allows expanding the GPIO space for use with
+ GPIO expanders.
+
+config S3C_GPIO_SPACE
+ int "Space between gpio banks"
+ default 0
+ help
+ Add a number of spare GPIO entries between each bank for debugging
+ purposes. This allows any problems where an counter overflows from
+ one bank to another to be caught, at the expense of using a little
+ more memory.
+
+config S3C_GPIO_TRACK
+ bool
+ help
+ Internal configuration option to enable the s3c specific gpio
+ chip tracking if the platform requires it.
+
+# ADC driver
+
+config S3C_ADC
+ bool "ADC common driver support"
+ help
+ 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.
+
+# device definitions to compile in
+
+config S3C_DEV_HSMMC
+ bool
+ help
+ Compile in platform device definitions for HSMMC code
+
+config S3C_DEV_HSMMC1
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 1
+
+config S3C_DEV_HSMMC2
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 2
+
+config S3C_DEV_HSMMC3
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 3
+
+config S3C_DEV_HWMON
+ bool
+ help
+ Compile in platform device definitions for HWMON
+
+config S3C_DEV_I2C1
+ bool
+ help
+ Compile in platform device definitions for I2C channel 1
+
+config S3C_DEV_I2C2
+ bool
+ help
+ Compile in platform device definitions for I2C channel 2
+
+config S3C_DEV_I2C3
+ bool
+ help
+ Compile in platform device definition for I2C controller 3
+
+config S3C_DEV_I2C4
+ bool
+ help
+ Compile in platform device definition for I2C controller 4
+
+config S3C_DEV_I2C5
+ bool
+ help
+ Compile in platform device definition for I2C controller 5
+
+config S3C_DEV_I2C6
+ bool
+ help
+ Compile in platform device definition for I2C controller 6
+
+config S3C_DEV_I2C7
+ bool
+ help
+ Compile in platform device definition for I2C controller 7
+
+config S3C_DEV_FB
+ bool
+ help
+ Compile in platform device definition for framebuffer
+
+config S3C_DEV_USB_HOST
+ bool
+ help
+ Compile in platform device definition for USB host.
+
+config S3C_DEV_USB_HSOTG
+ bool
+ help
+ Compile in platform device definition for USB high-speed OtG
+
+config S3C_DEV_WDT
+ bool
+ default y if ARCH_S3C2410
+ help
+ Complie in platform device definition for Watchdog Timer
+
+config S3C_DEV_NAND
+ bool
+ help
+ Compile in platform device definition for NAND controller
+
+config S3C_DEV_ONENAND
+ bool
+ help
+ Compile in platform device definition for OneNAND controller
+
+config S3C_DEV_RTC
+ bool
+ help
+ Complie in platform device definition for RTC
+
+config SAMSUNG_DEV_ADC
+ bool
+ help
+ Compile in platform device definition for ADC controller
+
+config SAMSUNG_DEV_IDE
+ bool
+ help
+ Compile in platform device definitions for IDE
+
+config S3C64XX_DEV_SPI
+ bool
+ help
+ Compile in platform device definitions for S3C64XX's type
+ SPI controllers.
+
+config SAMSUNG_DEV_TS
+ bool
+ help
+ Common in platform device definitions for touchscreen device
+
+config SAMSUNG_DEV_KEYPAD
+ bool
+ help
+ Compile in platform device definitions for keypad
+
+config SAMSUNG_DEV_PWM
+ bool
+ default y if ARCH_S3C2410
+ help
+ Compile in platform device definition for PWM Timer
+
+config S3C24XX_PWM
+ bool "PWM device support"
+ select HAVE_PWM
+ help
+ Support for exporting the PWM timer blocks via the pwm device
+ system
+
+# DMA
+
+config S3C_DMA
+ bool
+ help
+ Internal configuration for S3C DMA core
+
+config S3C_PL330_DMA
+ bool
+ select PL330
+ help
+ S3C DMA API Driver for PL330 DMAC.
+
+comment "Power management"
+
+config SAMSUNG_PM_DEBUG
+ bool "S3C2410 PM Suspend debug"
+ depends on PM
+ help
+ Say Y here if you want verbose debugging from the PM Suspend and
+ Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+ for more information.
+
+config S3C_PM_DEBUG_LED_SMDK
+ bool "SMDK LED suspend/resume debugging"
+ depends on PM && (MACH_SMDK6410)
+ help
+ Say Y here to enable the use of the SMDK LEDs on the baseboard
+ for debugging of the state of the suspend and resume process.
+
+ Note, this currently only works for S3C64XX based SMDK boards.
+
+config SAMSUNG_PM_CHECK
+ bool "S3C2410 PM Suspend Memory CRC"
+ depends on PM && CRC32
+ help
+ Enable the PM code's memory area checksum over sleep. This option
+ will generate CRCs of all blocks of memory, and store them before
+ going to sleep. The blocks are then checked on resume for any
+ errors.
+
+ Note, this can take several seconds depending on memory size
+ and CPU speed.
+
+ See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config SAMSUNG_PM_CHECK_CHUNKSIZE
+ int "S3C2410 PM Suspend CRC Chunksize (KiB)"
+ depends on PM && SAMSUNG_PM_CHECK
+ default 64
+ help
+ Set the chunksize in Kilobytes of the CRC for checking memory
+ corruption over suspend and resume. A smaller value will mean that
+ the CRC data block will take more memory, but wil identify any
+ faults with better precision.
+
+ See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
+
+config SAMSUNG_WAKEMASK
+ bool
+ depends on PM
+ help
+ Compile support for wakeup-mask controls found on the S3C6400
+ and above. This code allows a set of interrupt to wakeup-mask
+ mappings. See <plat/wakeup-mask.h>
+
+comment "Power Domain"
+
+config SAMSUNG_PD
+ bool "Samsung Power Domain"
+ depends on PM_RUNTIME
+ help
+ Say Y here if you want to control Power Domain by Runtime PM.
+
+endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
new file mode 100644
index 00000000..53eb15b0
--- /dev/null
+++ b/arch/arm/plat-samsung/Makefile
@@ -0,0 +1,83 @@
+# arch/arm/plat-s3c64xx/Makefile
+#
+# Copyright 2009 Simtec Electronics
+#
+# Licensed under GPLv2
+
+obj-y :=
+obj-m :=
+obj-n := dummy.o
+obj- :=
+
+# Objects we always build independent of SoC choice
+
+obj-y += init.o
+obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET) += time.o
+obj-y += clock.o
+obj-y += pwm-clock.o
+obj-y += gpio.o
+obj-y += gpio-config.o
+obj-y += dev-asocdma.o
+
+obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o
+
+obj-$(CONFIG_SAMSUNG_IRQ_UART) += irq-uart.o
+obj-$(CONFIG_SAMSUNG_IRQ_VIC_TIMER) += irq-vic-timer.o
+
+# ADC
+
+obj-$(CONFIG_S3C_ADC) += adc.o
+
+# devices
+
+obj-y += platformdata.o
+
+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_S3C_DEV_HWMON) += dev-hwmon.o
+obj-y += dev-i2c0.o
+obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
+obj-$(CONFIG_S3C_DEV_I2C2) += dev-i2c2.o
+obj-$(CONFIG_S3C_DEV_I2C3) += dev-i2c3.o
+obj-$(CONFIG_S3C_DEV_I2C4) += dev-i2c4.o
+obj-$(CONFIG_S3C_DEV_I2C5) += dev-i2c5.o
+obj-$(CONFIG_S3C_DEV_I2C6) += dev-i2c6.o
+obj-$(CONFIG_S3C_DEV_I2C7) += dev-i2c7.o
+obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
+obj-y += dev-uart.o
+obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
+obj-$(CONFIG_S3C_DEV_USB_HSOTG) += dev-usb-hsotg.o
+obj-$(CONFIG_S3C_DEV_WDT) += dev-wdt.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
+
+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_KEYPAD) += dev-keypad.o
+obj-$(CONFIG_SAMSUNG_DEV_PWM) += dev-pwm.o
+
+# DMA support
+
+obj-$(CONFIG_S3C_DMA) += dma.o
+
+obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
+
+# PM support
+
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_PM) += pm-gpio.o
+obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
+
+obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
+
+# PD support
+
+obj-$(CONFIG_SAMSUNG_PD) += pd.o
+
+# PWM support
+
+obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
new file mode 100644
index 00000000..e8f2be2d
--- /dev/null
+++ b/arch/arm/plat-samsung/adc.c
@@ -0,0 +1,488 @@
+/* arch/arm/plat-samsung/adc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * Samsung ADC device core
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+
+#include <plat/regs-adc.h>
+#include <plat/adc.h>
+
+/* This driver is designed to control the usage of the ADC block between
+ * the touchscreen and any other drivers that may need to use it, such as
+ * the hwmon driver.
+ *
+ * Priority will be given to the touchscreen driver, but as this itself is
+ * rate limited it should not starve other requests which are processed in
+ * order that they are received.
+ *
+ * Each user registers to get a client block which uniquely identifies it
+ * and stores information such as the necessary functions to callback when
+ * action is required.
+ */
+
+enum s3c_cpu_type {
+ TYPE_S3C24XX,
+ TYPE_S3C64XX
+};
+
+struct s3c_adc_client {
+ struct platform_device *pdev;
+ struct list_head pend;
+ wait_queue_head_t *wait;
+
+ 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);
+};
+
+struct adc_device {
+ struct platform_device *pdev;
+ struct platform_device *owner;
+ struct clk *clk;
+ struct s3c_adc_client *cur;
+ struct s3c_adc_client *ts_pend;
+ void __iomem *regs;
+ spinlock_t lock;
+
+ unsigned int prescale;
+
+ int irq;
+};
+
+static struct adc_device *adc_dev;
+
+static LIST_HEAD(adc_pending); /* protected by adc_device.lock */
+
+#define adc_dbg(_adc, msg...) dev_dbg(&(_adc)->pdev->dev, msg)
+
+static inline void s3c_adc_convert(struct adc_device *adc)
+{
+ unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+ con |= S3C2410_ADCCON_ENABLE_START;
+ writel(con, adc->regs + S3C2410_ADCCON);
+}
+
+static inline void s3c_adc_select(struct adc_device *adc,
+ struct s3c_adc_client *client)
+{
+ unsigned con = readl(adc->regs + S3C2410_ADCCON);
+
+ 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);
+
+ 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",
+ 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;
+
+ if (!next && !list_empty(&adc_pending)) {
+ next = list_first_entry(&adc_pending,
+ struct s3c_adc_client, pend);
+ list_del(&next->pend);
+ } else
+ adc->ts_pend = NULL;
+
+ if (next) {
+ adc_dbg(adc, "new client is %p\n", next);
+ adc->cur = next;
+ s3c_adc_select(adc, next);
+ s3c_adc_convert(adc);
+ s3c_adc_dbgshow(adc);
+ }
+}
+
+int s3c_adc_start(struct s3c_adc_client *client,
+ unsigned int channel, unsigned int nr_samples)
+{
+ struct adc_device *adc = adc_dev;
+ unsigned long flags;
+
+ if (!adc) {
+ printk(KERN_ERR "%s: failed to find adc\n", __func__);
+ return -EINVAL;
+ }
+
+ if (client->is_ts && adc->ts_pend)
+ return -EAGAIN;
+
+ spin_lock_irqsave(&adc->lock, flags);
+
+ client->channel = channel;
+ client->nr_samples = nr_samples;
+
+ if (client->is_ts)
+ adc->ts_pend = client;
+ else
+ list_add_tail(&client->pend, &adc_pending);
+
+ if (!adc->cur)
+ s3c_adc_try(adc);
+
+ spin_unlock_irqrestore(&adc->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_start);
+
+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_read(struct s3c_adc_client *client, unsigned int ch)
+{
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
+ int ret;
+
+ client->convert_cb = s3c_convert_done;
+ client->wait = &wake;
+ client->result = -1;
+
+ ret = s3c_adc_start(client, ch, 1);
+ if (ret < 0)
+ goto err;
+
+ ret = wait_event_timeout(wake, client->result >= 0, HZ / 2);
+ if (client->result < 0) {
+ ret = -ETIMEDOUT;
+ goto err;
+ }
+
+ client->convert_cb = NULL;
+ return client->result;
+
+err:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(s3c_adc_read);
+
+static void s3c_adc_default_select(struct s3c_adc_client *client,
+ unsigned select)
+{
+}
+
+struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev,
+ void (*select)(struct s3c_adc_client *client,
+ unsigned int selected),
+ void (*conv)(struct s3c_adc_client *client,
+ unsigned d0, unsigned d1,
+ unsigned *samples_left),
+ unsigned int is_ts)
+{
+ struct s3c_adc_client *client;
+
+ WARN_ON(!pdev);
+
+ if (!select)
+ select = s3c_adc_default_select;
+
+ if (!pdev)
+ return ERR_PTR(-EINVAL);
+
+ client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL);
+ if (!client) {
+ dev_err(&pdev->dev, "no memory for adc client\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ client->pdev = pdev;
+ client->is_ts = is_ts;
+ client->select_cb = select;
+ client->convert_cb = conv;
+
+ return client;
+}
+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);
+ kfree(client);
+}
+EXPORT_SYMBOL_GPL(s3c_adc_release);
+
+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;
+
+ if (!client) {
+ 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);
+ adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1);
+
+ client->nr_samples--;
+
+ if (cpu == TYPE_S3C64XX) {
+ /* S3C64XX ADC resolution is 12-bit */
+ data0 &= 0xfff;
+ data1 &= 0xfff;
+ } else {
+ data0 &= 0x3ff;
+ data1 &= 0x3ff;
+ }
+
+ 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);
+ s3c_adc_convert(adc);
+ } else {
+ spin_lock(&adc->lock);
+ (client->select_cb)(client, 0);
+ adc->cur = NULL;
+
+ s3c_adc_try(adc);
+ spin_unlock(&adc->lock);
+ }
+
+exit:
+ if (cpu == TYPE_S3C64XX) {
+ /* Clear ADC interrupt */
+ writel(0, adc->regs + S3C64XX_ADCCLRINT);
+ }
+ return IRQ_HANDLED;
+}
+
+static int s3c_adc_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct adc_device *adc;
+ struct resource *regs;
+ int ret;
+ unsigned tmp;
+
+ adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);
+ if (adc == NULL) {
+ dev_err(dev, "failed to allocate adc_device\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&adc->lock);
+
+ 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)) {
+ dev_err(dev, "failed to get adc clock\n");
+ ret = PTR_ERR(adc->clk);
+ goto err_irq;
+ }
+
+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!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) {
+ dev_err(dev, "failed to map registers\n");
+ ret = -ENXIO;
+ goto err_clk;
+ }
+
+ clk_enable(adc->clk);
+
+ tmp = adc->prescale | S3C2410_ADCCON_PRSCEN;
+ if (platform_get_device_id(pdev)->driver_data == TYPE_S3C64XX) {
+ /* Enable 12-bit ADC resolution */
+ tmp |= S3C64XX_ADCCON_RESSEL;
+ }
+ writel(tmp, adc->regs + S3C2410_ADCCON);
+
+ dev_info(dev, "attached adc driver\n");
+
+ platform_set_drvdata(pdev, adc);
+ adc_dev = adc;
+
+ return 0;
+
+ err_clk:
+ clk_put(adc->clk);
+
+ err_irq:
+ free_irq(adc->irq, adc);
+
+ err_alloc:
+ kfree(adc);
+ return ret;
+}
+
+static int __devexit s3c_adc_remove(struct platform_device *pdev)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+
+ iounmap(adc->regs);
+ free_irq(adc->irq, adc);
+ clk_disable(adc->clk);
+ clk_put(adc->clk);
+ kfree(adc);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+ unsigned long flags;
+ u32 con;
+
+ spin_lock_irqsave(&adc->lock, flags);
+
+ con = readl(adc->regs + S3C2410_ADCCON);
+ con |= S3C2410_ADCCON_STDBM;
+ writel(con, adc->regs + S3C2410_ADCCON);
+
+ disable_irq(adc->irq);
+ spin_unlock_irqrestore(&adc->lock, flags);
+ clk_disable(adc->clk);
+
+ return 0;
+}
+
+static int s3c_adc_resume(struct platform_device *pdev)
+{
+ struct adc_device *adc = platform_get_drvdata(pdev);
+
+ clk_enable(adc->clk);
+ enable_irq(adc->irq);
+
+ writel(adc->prescale | S3C2410_ADCCON_PRSCEN,
+ adc->regs + S3C2410_ADCCON);
+
+ return 0;
+}
+
+#else
+#define s3c_adc_suspend NULL
+#define s3c_adc_resume NULL
+#endif
+
+static struct platform_device_id s3c_adc_driver_ids[] = {
+ {
+ .name = "s3c24xx-adc",
+ .driver_data = TYPE_S3C24XX,
+ }, {
+ .name = "s3c64xx-adc",
+ .driver_data = TYPE_S3C64XX,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, s3c_adc_driver_ids);
+
+static struct platform_driver s3c_adc_driver = {
+ .id_table = s3c_adc_driver_ids,
+ .driver = {
+ .name = "s3c-adc",
+ .owner = THIS_MODULE,
+ },
+ .probe = s3c_adc_probe,
+ .remove = __devexit_p(s3c_adc_remove),
+ .suspend = s3c_adc_suspend,
+ .resume = s3c_adc_resume,
+};
+
+static int __init adc_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&s3c_adc_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add adc driver\n", __func__);
+
+ return ret;
+}
+
+arch_initcall(adc_init);
diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c
new file mode 100644
index 00000000..ae8b8507
--- /dev/null
+++ b/arch/arm/plat-samsung/clock-clksrc.c
@@ -0,0 +1,212 @@
+/* linux/arch/arm/plat-samsung/clock-clksrc.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu-freq.h>
+
+static inline struct clksrc_clk *to_clksrc(struct clk *clk)
+{
+ return container_of(clk, struct clksrc_clk, clk);
+}
+
+static inline u32 bit_mask(u32 shift, u32 nr_bits)
+{
+ u32 mask = 0xffffffff >> (32 - nr_bits);
+
+ return mask << shift;
+}
+
+static unsigned long s3c_getrate_clksrc(struct clk *clk)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ unsigned long rate = clk_get_rate(clk->parent);
+ u32 clkdiv = __raw_readl(sclk->reg_div.reg);
+ u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+
+ clkdiv &= mask;
+ clkdiv >>= sclk->reg_div.shift;
+ clkdiv++;
+
+ rate /= clkdiv;
+ return rate;
+}
+
+static int s3c_setrate_clksrc(struct clk *clk, unsigned long rate)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ void __iomem *reg = sclk->reg_div.reg;
+ unsigned int div;
+ u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+ u32 val;
+
+ rate = clk_round_rate(clk, rate);
+ div = clk_get_rate(clk->parent) / rate;
+ if (div > (1 << sclk->reg_div.size))
+ return -EINVAL;
+
+ val = __raw_readl(reg);
+ val &= ~mask;
+ val |= (div - 1) << sclk->reg_div.shift;
+ __raw_writel(val, reg);
+
+ return 0;
+}
+
+static int s3c_setparent_clksrc(struct clk *clk, struct clk *parent)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ struct clksrc_sources *srcs = sclk->sources;
+ u32 clksrc = __raw_readl(sclk->reg_src.reg);
+ u32 mask = bit_mask(sclk->reg_src.shift, sclk->reg_src.size);
+ int src_nr = -1;
+ int ptr;
+
+ for (ptr = 0; ptr < srcs->nr_sources; ptr++)
+ if (srcs->sources[ptr] == parent) {
+ src_nr = ptr;
+ break;
+ }
+
+ if (src_nr >= 0) {
+ clk->parent = parent;
+
+ clksrc &= ~mask;
+ clksrc |= src_nr << sclk->reg_src.shift;
+
+ __raw_writel(clksrc, sclk->reg_src.reg);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static unsigned long s3c_roundrate_clksrc(struct clk *clk,
+ unsigned long rate)
+{
+ struct clksrc_clk *sclk = to_clksrc(clk);
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ int max_div = 1 << sclk->reg_div.size;
+ int div;
+
+ if (rate >= parent_rate)
+ rate = parent_rate;
+ else {
+ div = parent_rate / rate;
+ if (parent_rate % rate)
+ div++;
+
+ if (div == 0)
+ div = 1;
+ if (div > max_div)
+ div = max_div;
+
+ rate = parent_rate / div;
+ }
+
+ return rate;
+}
+
+/* Clock initialisation code */
+
+void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk, bool announce)
+{
+ struct clksrc_sources *srcs = clk->sources;
+ u32 mask = bit_mask(clk->reg_src.shift, clk->reg_src.size);
+ u32 clksrc;
+
+ if (!clk->reg_src.reg) {
+ if (!clk->clk.parent)
+ printk(KERN_ERR "%s: no parent clock specified\n",
+ clk->clk.name);
+ return;
+ }
+
+ clksrc = __raw_readl(clk->reg_src.reg);
+ clksrc &= mask;
+ clksrc >>= clk->reg_src.shift;
+
+ if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
+ printk(KERN_ERR "%s: bad source %d\n",
+ clk->clk.name, clksrc);
+ return;
+ }
+
+ clk->clk.parent = srcs->sources[clksrc];
+
+ if (announce)
+ printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
+ clk->clk.name, clk->clk.parent->name, clksrc,
+ clk_get_rate(&clk->clk));
+}
+
+static struct clk_ops clksrc_ops = {
+ .set_parent = s3c_setparent_clksrc,
+ .get_rate = s3c_getrate_clksrc,
+ .set_rate = s3c_setrate_clksrc,
+ .round_rate = s3c_roundrate_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nodiv = {
+ .set_parent = s3c_setparent_clksrc,
+};
+
+static struct clk_ops clksrc_ops_nosrc = {
+ .get_rate = s3c_getrate_clksrc,
+ .set_rate = s3c_setrate_clksrc,
+ .round_rate = s3c_roundrate_clksrc,
+};
+
+void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size)
+{
+ int ret;
+
+ for (; size > 0; size--, clksrc++) {
+ if (!clksrc->reg_div.reg && !clksrc->reg_src.reg)
+ printk(KERN_ERR "%s: clock %s has no registers set\n",
+ __func__, clksrc->clk.name);
+
+ /* fill in the default functions */
+
+ if (!clksrc->clk.ops) {
+ if (!clksrc->reg_div.reg)
+ clksrc->clk.ops = &clksrc_ops_nodiv;
+ else if (!clksrc->reg_src.reg)
+ clksrc->clk.ops = &clksrc_ops_nosrc;
+ else
+ clksrc->clk.ops = &clksrc_ops;
+ }
+
+ /* setup the clocksource, but do not announce it
+ * as it may be re-set by the setup routines
+ * called after the rest of the clocks have been
+ * registered
+ */
+ s3c_set_clksrc(clksrc, false);
+
+ ret = s3c24xx_register_clock(&clksrc->clk);
+
+ if (ret < 0) {
+ printk(KERN_ERR "%s: failed to register %s (%d)\n",
+ __func__, clksrc->clk.name, ret);
+ }
+ }
+}
diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c
new file mode 100644
index 00000000..77289282
--- /dev/null
+++ b/arch/arm/plat-samsung/clock.c
@@ -0,0 +1,541 @@
+/* linux/arch/arm/plat-s3c24xx/clock.c
+ *
+ * Copyright 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C24XX Core clock control support
+ *
+ * Based on, and code from linux/arch/arm/mach-versatile/clock.c
+ **
+ ** Copyright (C) 2004 ARM Limited.
+ ** Written by Deep Blue Solutions Limited.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/sysdev.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#if defined(CONFIG_DEBUG_FS)
+#include <linux/debugfs.h>
+#endif
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+
+#include <plat/cpu-freq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#include <linux/serial_core.h>
+#include <plat/regs-serial.h> /* for s3c24xx_uart_devs */
+
+/* clock information */
+
+static LIST_HEAD(clocks);
+
+/* We originally used an mutex here, but some contexts (see resume)
+ * are calling functions such as clk_set_parent() with IRQs disabled
+ * causing an BUG to be triggered.
+ */
+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)
+{
+ struct platform_device **pdev = s3c24xx_uart_devs;
+ int i;
+ for (i = 0; i < ARRAY_SIZE(s3c24xx_uart_devs); i++, pdev++)
+ if (*pdev && dev == &(*pdev)->dev)
+ return 1;
+ return 0;
+}
+
+/*
+ * Serial drivers call get_clock() very early, before platform bus
+ * has been set up, this requires a special check to let them get
+ * a proper clock
+ */
+
+static int dev_is_platform_device(struct device *dev)
+{
+ return dev->bus == &platform_bus_type ||
+ (dev->bus == NULL && dev_is_s3c_uart(dev));
+}
+
+/* Clock API calls */
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+ 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;
+}
+
+void clk_put(struct clk *clk)
+{
+ module_put(clk->owner);
+}
+
+int clk_enable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return -EINVAL;
+
+ clk_enable(clk->parent);
+
+ spin_lock(&clocks_lock);
+
+ if ((clk->usage++) == 0)
+ (clk->enable)(clk, 1);
+
+ spin_unlock(&clocks_lock);
+ return 0;
+}
+
+void clk_disable(struct clk *clk)
+{
+ if (IS_ERR(clk) || clk == NULL)
+ return;
+
+ spin_lock(&clocks_lock);
+
+ if ((--clk->usage) == 0)
+ (clk->enable)(clk, 0);
+
+ spin_unlock(&clocks_lock);
+ clk_disable(clk->parent);
+}
+
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (IS_ERR(clk))
+ return 0;
+
+ if (clk->rate != 0)
+ return clk->rate;
+
+ if (clk->ops != NULL && clk->ops->get_rate != NULL)
+ return (clk->ops->get_rate)(clk);
+
+ if (clk->parent != NULL)
+ return clk_get_rate(clk->parent);
+
+ return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate)
+ return (clk->ops->round_rate)(clk, rate);
+
+ return rate;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ /* We do not default just do a clk->rate = rate as
+ * the clock may have been made this way by choice.
+ */
+
+ WARN_ON(clk->ops == NULL);
+ WARN_ON(clk->ops && clk->ops->set_rate == NULL);
+
+ if (clk->ops == NULL || clk->ops->set_rate == NULL)
+ return -EINVAL;
+
+ spin_lock(&clocks_lock);
+ ret = (clk->ops->set_rate)(clk, rate);
+ spin_unlock(&clocks_lock);
+
+ return ret;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+ return clk->parent;
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = 0;
+
+ if (IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock(&clocks_lock);
+
+ if (clk->ops && clk->ops->set_parent)
+ ret = (clk->ops->set_parent)(clk, parent);
+
+ spin_unlock(&clocks_lock);
+
+ return ret;
+}
+
+EXPORT_SYMBOL(clk_get);
+EXPORT_SYMBOL(clk_put);
+EXPORT_SYMBOL(clk_enable);
+EXPORT_SYMBOL(clk_disable);
+EXPORT_SYMBOL(clk_get_rate);
+EXPORT_SYMBOL(clk_round_rate);
+EXPORT_SYMBOL(clk_set_rate);
+EXPORT_SYMBOL(clk_get_parent);
+EXPORT_SYMBOL(clk_set_parent);
+
+/* base clocks */
+
+int clk_default_setrate(struct clk *clk, unsigned long rate)
+{
+ clk->rate = rate;
+ return 0;
+}
+
+struct clk_ops clk_ops_def_setrate = {
+ .set_rate = clk_default_setrate,
+};
+
+struct clk clk_xtal = {
+ .name = "xtal",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_ext = {
+ .name = "ext",
+ .id = -1,
+};
+
+struct clk clk_epll = {
+ .name = "epll",
+ .id = -1,
+};
+
+struct clk clk_mpll = {
+ .name = "mpll",
+ .id = -1,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_upll = {
+ .name = "upll",
+ .id = -1,
+ .parent = NULL,
+ .ctrlbit = 0,
+};
+
+struct clk clk_f = {
+ .name = "fclk",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_mpll,
+ .ctrlbit = 0,
+};
+
+struct clk clk_h = {
+ .name = "hclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_p = {
+ .name = "pclk",
+ .id = -1,
+ .rate = 0,
+ .parent = NULL,
+ .ctrlbit = 0,
+ .ops = &clk_ops_def_setrate,
+};
+
+struct clk clk_usb_bus = {
+ .name = "usb-bus",
+ .id = -1,
+ .rate = 0,
+ .parent = &clk_upll,
+};
+
+
+struct clk s3c24xx_uclk = {
+ .name = "uclk",
+ .id = -1,
+};
+
+/* initialise the clock system */
+
+/**
+ * s3c24xx_register_clock() - register a clock
+ * @clk: The clock to register
+ *
+ * Add the specified clock to the list of clocks known by the system.
+ */
+int s3c24xx_register_clock(struct clk *clk)
+{
+ if (clk->enable == NULL)
+ clk->enable = clk_null_enable;
+
+ /* add to the list of available clocks */
+
+ /* 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);
+
+ return 0;
+}
+
+/**
+ * s3c24xx_register_clocks() - register an array of clock pointers
+ * @clks: Pointer to an array of struct clk pointers
+ * @nr_clks: The number of clocks in the @clks array.
+ *
+ * Call s3c24xx_register_clock() for all the clock pointers contained
+ * in the @clks list. Returns the number of failures.
+ */
+int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
+{
+ int fails = 0;
+
+ for (; nr_clks > 0; nr_clks--, clks++) {
+ if (s3c24xx_register_clock(*clks) < 0) {
+ struct clk *clk = *clks;
+ printk(KERN_ERR "%s: failed to register %p: %s\n",
+ __func__, clk, clk->name);
+ fails++;
+ }
+ }
+
+ return fails;
+}
+
+/**
+ * s3c_register_clocks() - register an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * Call s3c24xx_register_clock() on the @clkp array given, printing an
+ * error if it fails to register the clock (unlikely).
+ */
+void __init s3c_register_clocks(struct clk *clkp, int nr_clks)
+{
+ int ret;
+
+ for (; nr_clks > 0; nr_clks--, clkp++) {
+ ret = s3c24xx_register_clock(clkp);
+
+ if (ret < 0) {
+ printk(KERN_ERR "Failed to register clock %s (%d)\n",
+ clkp->name, ret);
+ }
+ }
+}
+
+/**
+ * s3c_disable_clocks() - disable an array of clocks
+ * @clkp: Pointer to the first clock in the array.
+ * @nr_clks: Number of clocks to register.
+ *
+ * for internal use only at initialisation time. disable the clocks in the
+ * @clkp array.
+ */
+
+void __init s3c_disable_clocks(struct clk *clkp, int nr_clks)
+{
+ for (; nr_clks > 0; nr_clks--, clkp++)
+ (clkp->enable)(clkp, 0);
+}
+
+/* initialise all the clocks */
+
+int __init s3c24xx_register_baseclocks(unsigned long xtal)
+{
+ printk(KERN_INFO "S3C24XX Clocks, Copyright 2004 Simtec Electronics\n");
+
+ clk_xtal.rate = xtal;
+
+ /* register our clocks */
+
+ if (s3c24xx_register_clock(&clk_xtal) < 0)
+ printk(KERN_ERR "failed to register master xtal\n");
+
+ if (s3c24xx_register_clock(&clk_mpll) < 0)
+ printk(KERN_ERR "failed to register mpll clock\n");
+
+ if (s3c24xx_register_clock(&clk_upll) < 0)
+ printk(KERN_ERR "failed to register upll clock\n");
+
+ if (s3c24xx_register_clock(&clk_f) < 0)
+ printk(KERN_ERR "failed to register cpu fclk\n");
+
+ if (s3c24xx_register_clock(&clk_h) < 0)
+ printk(KERN_ERR "failed to register cpu hclk\n");
+
+ if (s3c24xx_register_clock(&clk_p) < 0)
+ printk(KERN_ERR "failed to register cpu pclk\n");
+
+ return 0;
+}
+
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+/* debugfs support to trace clock tree hierarchy and attributes */
+
+static struct dentry *clk_debugfs_root;
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ int err;
+ struct dentry *d, *child, *child_tmp;
+ 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);
+
+ d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+ if (!d)
+ return -ENOMEM;
+
+ c->dent = d;
+
+ d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usage);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ 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);
+ return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clocks, list) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+late_initcall(clk_debugfs_init);
+
+#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
diff --git a/arch/arm/plat-samsung/dev-adc.c b/arch/arm/plat-samsung/dev-adc.c
new file mode 100644
index 00000000..9d903d40
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-adc.c
@@ -0,0 +1,46 @@
+/* linux/arch/arm/plat-samsung/dev-adc.c
+ *
+ * Copyright 2010 Maurus Cuelenaere
+ *
+ * S3C64xx series device definition for ADC 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/adc.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_adc_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_ADC,
+ .end = SAMSUNG_PA_ADC + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_ADC,
+ .end = IRQ_ADC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_adc = {
+ .name = "samsung-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_adc_resource),
+ .resource = s3c_adc_resource,
+};
diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c
new file mode 100644
index 00000000..a068c4f4
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-asocdma.c
@@ -0,0 +1,25 @@
+/* linux/arch/arm/plat-samsung/dev-asocdma.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 <plat/devs.h>
+
+static u64 audio_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device samsung_asoc_dma = {
+ .name = "samsung-audio",
+ .id = -1,
+ .dev = {
+ .dma_mask = &audio_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ }
+};
+EXPORT_SYMBOL(samsung_asoc_dma);
diff --git a/arch/arm/plat-samsung/dev-fb.c b/arch/arm/plat-samsung/dev-fb.c
new file mode 100644
index 00000000..bf60204c
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-fb.c
@@ -0,0 +1,73 @@
+/* linux/arch/arm/plat-s3c/dev-fb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for framebuffer 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 <linux/fb.h>
+#include <linux/gfp.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/fb.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_fb_resource[] = {
+ [0] = {
+ .start = S3C_PA_FB,
+ .end = S3C_PA_FB + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_LCD_VSYNC,
+ .end = IRQ_LCD_VSYNC,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_LCD_FIFO,
+ .end = IRQ_LCD_FIFO,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = IRQ_LCD_SYSTEM,
+ .end = IRQ_LCD_SYSTEM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_fb = {
+ .name = "s3c-fb",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_fb_resource),
+ .resource = s3c_fb_resource,
+ .dev.dma_mask = &s3c_device_fb.dev.coherent_dma_mask,
+ .dev.coherent_dma_mask = 0xffffffffUL,
+};
+
+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;
+}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
new file mode 100644
index 00000000..db7a65c7
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -0,0 +1,79 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for hsmmc 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/sdhci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define S3C_SZ_HSMMC (0x1000)
+
+static struct resource s3c_hsmmc_resource[] = {
+ [0] = {
+ .start = S3C_PA_HSMMC0,
+ .end = S3C_PA_HSMMC0 + S3C_SZ_HSMMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_HSMMC0,
+ .end = IRQ_HSMMC0,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc0 = {
+ .name = "s3c-sdhci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_hsmmc_resource),
+ .resource = s3c_hsmmc_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_hsmmc0_def_platdata,
+ },
+};
+
+void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ struct s3c_sdhci_platdata *set = &s3c_hsmmc0_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;
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
+}
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
new file mode 100644
index 00000000..2497321f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -0,0 +1,79 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc1.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for hsmmc device 1
+ *
+ * This program is free software; you can 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/sdhci.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+#define S3C_SZ_HSMMC (0x1000)
+
+static struct resource s3c_hsmmc1_resource[] = {
+ [0] = {
+ .start = S3C_PA_HSMMC1,
+ .end = S3C_PA_HSMMC1 + S3C_SZ_HSMMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_HSMMC1,
+ .end = IRQ_HSMMC1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc1_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc1 = {
+ .name = "s3c-sdhci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource),
+ .resource = s3c_hsmmc1_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc1_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_hsmmc1_def_platdata,
+ },
+};
+
+void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ struct s3c_sdhci_platdata *set = &s3c_hsmmc1_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;
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
+}
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
new file mode 100644
index 00000000..f60aedba
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -0,0 +1,80 @@
+/* linux/arch/arm/plat-s3c/dev-hsmmc2.c
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * Copyright (c) 2009 Maurus Cuelenaere
+ *
+ * Based on arch/arm/plat-s3c/dev-hsmmc1.c
+ * original file Copyright (c) 2008 Simtec Electronics
+ *
+ * S3C series device definition for hsmmc device 2
+ *
+ * This program is free software; you can 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/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC (0x1000)
+
+static struct resource s3c_hsmmc2_resource[] = {
+ [0] = {
+ .start = S3C_PA_HSMMC2,
+ .end = S3C_PA_HSMMC2 + S3C_SZ_HSMMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_HSMMC2,
+ .end = IRQ_HSMMC2,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc2_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc2 = {
+ .name = "s3c-sdhci",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource),
+ .resource = s3c_hsmmc2_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc2_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_hsmmc2_def_platdata,
+ },
+};
+
+void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ struct s3c_sdhci_platdata *set = &s3c_hsmmc2_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;
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
+}
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
new file mode 100644
index 00000000..ede776f2
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -0,0 +1,83 @@
+/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * 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
+ *
+ * Samsung device definition for hsmmc device 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC (0x1000)
+
+static struct resource s3c_hsmmc3_resource[] = {
+ [0] = {
+ .start = S3C_PA_HSMMC3,
+ .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_HSMMC3,
+ .end = IRQ_HSMMC3,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+ .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL,
+};
+
+struct platform_device s3c_device_hsmmc3 = {
+ .name = "s3c-sdhci",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
+ .resource = s3c_hsmmc3_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc3_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_hsmmc3_def_platdata,
+ },
+};
+
+void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ struct s3c_sdhci_platdata *set = &s3c_hsmmc3_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;
+
+ if (pd->max_width)
+ set->max_width = pd->max_width;
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+ if (pd->host_caps)
+ set->host_caps |= pd->host_caps;
+ if (pd->clk_type)
+ set->clk_type = pd->clk_type;
+}
diff --git a/arch/arm/plat-samsung/dev-hwmon.c b/arch/arm/plat-samsung/dev-hwmon.c
new file mode 100644
index 00000000..b3ffb958
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hwmon.c
@@ -0,0 +1,42 @@
+/* linux/arch/arm/plat-samsung/dev-hwmon.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Adapted for HWMON by Maurus Cuelenaere
+ *
+ * Samsung series device definition for HWMON
+ *
+ * This program is free software; you can 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 <plat/devs.h>
+#include <plat/hwmon.h>
+
+struct platform_device s3c_device_hwmon = {
+ .name = "s3c-hwmon",
+ .id = -1,
+ .dev.parent = &s3c_device_adc.dev,
+};
+
+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;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c0.c b/arch/arm/plat-samsung/dev-i2c0.c
new file mode 100644
index 00000000..3a601c16
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c0.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/plat-s3c/dev-i2c0.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC,
+ .end = S3C_PA_IIC + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC,
+ .end = IRQ_IIC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c0 = {
+ .name = "s3c2410-i2c",
+#ifdef CONFIG_S3C_DEV_I2C1
+ .id = 0,
+#else
+ .id = -1,
+#endif
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data0 __initdata = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data0;
+
+ 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;
+
+ s3c_device_i2c0.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c1.c b/arch/arm/plat-samsung/dev-i2c1.c
new file mode 100644
index 00000000..858ee2a0
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c1.c
@@ -0,0 +1,69 @@
+/* linux/arch/arm/plat-s3c/dev-i2c1.c
+ *
+ * Copyright 2008-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for i2c device 1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC1,
+ .end = S3C_PA_IIC1 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC1,
+ .end = IRQ_IIC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c1 = {
+ .name = "s3c2410-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .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;
+
+ 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;
+
+ s3c_device_i2c1.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c2.c b/arch/arm/plat-samsung/dev-i2c2.c
new file mode 100644
index 00000000..ff4ba69b
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c2.c
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s3c/dev-i2c2.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C series device definition for i2c device 2
+ *
+ * Based on plat-samsung/dev-i2c0.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC2,
+ .end = S3C_PA_IIC2 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC2,
+ .end = IRQ_IIC2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c2 = {
+ .name = "s3c2410-i2c",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .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;
+
+ 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;
+
+ s3c_device_i2c2.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c3.c b/arch/arm/plat-samsung/dev-i2c3.c
new file mode 100644
index 00000000..8586a100
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c3.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC3,
+ .end = S3C_PA_IIC3 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC3,
+ .end = IRQ_IIC3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c3 = {
+ .name = "s3c2440-i2c",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data3 __initdata = {
+ .flags = 0,
+ .bus_num = 3,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data3;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c3_cfg_gpio;
+
+ s3c_device_i2c3.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c4.c b/arch/arm/plat-samsung/dev-i2c4.c
new file mode 100644
index 00000000..df2159e2
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c4.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c4.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC4,
+ .end = S3C_PA_IIC4 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC4,
+ .end = IRQ_IIC4,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c4 = {
+ .name = "s3c2440-i2c",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data4 __initdata = {
+ .flags = 0,
+ .bus_num = 4,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data4;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c4_cfg_gpio;
+
+ s3c_device_i2c4.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c5.c b/arch/arm/plat-samsung/dev-i2c5.c
new file mode 100644
index 00000000..0499c2c3
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c5.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC5,
+ .end = S3C_PA_IIC5 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC5,
+ .end = IRQ_IIC5,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c5 = {
+ .name = "s3c2440-i2c",
+ .id = 5,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data5 __initdata = {
+ .flags = 0,
+ .bus_num = 5,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data5;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c5_cfg_gpio;
+
+ s3c_device_i2c5.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c6.c b/arch/arm/plat-samsung/dev-i2c6.c
new file mode 100644
index 00000000..40831089
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c6.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c6.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 6
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC6,
+ .end = S3C_PA_IIC6 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC6,
+ .end = IRQ_IIC6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c6 = {
+ .name = "s3c2440-i2c",
+ .id = 6,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data6 __initdata = {
+ .flags = 0,
+ .bus_num = 6,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data6;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c6_cfg_gpio;
+
+ s3c_device_i2c6.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-i2c7.c b/arch/arm/plat-samsung/dev-i2c7.c
new file mode 100644
index 00000000..1182451d
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-i2c7.c
@@ -0,0 +1,68 @@
+/* linux/arch/arm/plat-samsung/dev-i2c7.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S5P series device definition for i2c device 7
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/regs-iic.h>
+#include <plat/iic.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+
+static struct resource s3c_i2c_resource[] = {
+ [0] = {
+ .start = S3C_PA_IIC7,
+ .end = S3C_PA_IIC7 + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_IIC7,
+ .end = IRQ_IIC7,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_i2c7 = {
+ .name = "s3c2440-i2c",
+ .id = 7,
+ .num_resources = ARRAY_SIZE(s3c_i2c_resource),
+ .resource = s3c_i2c_resource,
+};
+
+static struct s3c2410_platform_i2c default_i2c_data7 __initdata = {
+ .flags = 0,
+ .bus_num = 7,
+ .slave_addr = 0x10,
+ .frequency = 100*1000,
+ .sda_delay = 100,
+};
+
+void __init s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *pd)
+{
+ struct s3c2410_platform_i2c *npd;
+
+ if (!pd)
+ pd = &default_i2c_data7;
+
+ npd = kmemdup(pd, sizeof(struct s3c2410_platform_i2c), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else if (!npd->cfg_gpio)
+ npd->cfg_gpio = s3c_i2c7_cfg_gpio;
+
+ s3c_device_i2c7.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
new file mode 100644
index 00000000..b4979827
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ide.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-samsung/dev-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA device 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.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+#include <plat/ata.h>
+#include <plat/devs.h>
+
+static struct resource s3c_cfcon_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_CFCON,
+ .end = SAMSUNG_PA_CFCON + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CFCON,
+ .end = IRQ_CFCON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_cfcon = {
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
+ .resource = s3c_cfcon_resource,
+};
+
+void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
+{
+ s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
+ &s3c_device_cfcon);
+}
diff --git a/arch/arm/plat-samsung/dev-keypad.c b/arch/arm/plat-samsung/dev-keypad.c
new file mode 100644
index 00000000..677c2d73
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-keypad.c
@@ -0,0 +1,50 @@
+/*
+ * linux/arch/arm/plat-samsung/dev-keypad.c
+ *
+ * Copyright (C) 2010 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/platform_device.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/keypad.h>
+
+static struct resource samsung_keypad_resources[] = {
+ [0] = {
+ .start = SAMSUNG_PA_KEYPAD,
+ .end = SAMSUNG_PA_KEYPAD + 0x20 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_KEYPAD,
+ .end = IRQ_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device samsung_device_keypad = {
+ .name = "samsung-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(samsung_keypad_resources),
+ .resource = samsung_keypad_resources,
+};
+
+void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd)
+{
+ struct samsung_keypad_platdata *npd;
+
+ npd = s3c_set_platdata(pd, sizeof(struct samsung_keypad_platdata),
+ &samsung_device_keypad);
+
+ if (!npd->cfg_gpio)
+ npd->cfg_gpio = samsung_keypad_cfg_gpio;
+}
diff --git a/arch/arm/plat-samsung/dev-nand.c b/arch/arm/plat-samsung/dev-nand.c
new file mode 100644
index 00000000..6927ae8f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-nand.c
@@ -0,0 +1,128 @@
+/*
+ * S3C series device definition for nand 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/gfp.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/nand.h>
+
+static struct resource s3c_nand_resource[] = {
+ [0] = {
+ .start = S3C_PA_NAND,
+ .end = S3C_PA_NAND + SZ_1M,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+struct platform_device s3c_device_nand = {
+ .name = "s3c2410-nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_nand_resource),
+ .resource = s3c_nand_resource,
+};
+
+EXPORT_SYMBOL(s3c_device_nand);
+
+/**
+ * s3c_nand_copy_set() - copy nand set data
+ * @set: The new structure, directly copied from the old.
+ *
+ * Copy all the fields from the NAND set field from what is probably __initdata
+ * to new kernel memory. The code returns 0 if the copy happened correctly or
+ * an error code for the calling function to display.
+ *
+ * Note, we currently do not try and look to see if we've already copied the
+ * data in a previous set.
+ */
+static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set)
+{
+ void *ptr;
+ int size;
+
+ size = sizeof(struct mtd_partition) * set->nr_partitions;
+ if (size) {
+ ptr = kmemdup(set->partitions, size, GFP_KERNEL);
+ set->partitions = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ if (set->nr_map && set->nr_chips) {
+ size = sizeof(int) * set->nr_chips;
+ ptr = kmemdup(set->nr_map, size, GFP_KERNEL);
+ set->nr_map = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ if (set->ecc_layout) {
+ ptr = kmemdup(set->ecc_layout,
+ sizeof(struct nand_ecclayout), GFP_KERNEL);
+ set->ecc_layout = ptr;
+
+ if (!ptr)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void __init s3c_nand_set_platdata(struct s3c2410_platform_nand *nand)
+{
+ struct s3c2410_platform_nand *npd;
+ int size;
+ int ret;
+
+ /* note, if we get a failure in allocation, we simply drop out of the
+ * function. If there is so little memory available at initialisation
+ * 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__);
+ return;
+ }
+
+ /* now see if we need to copy any of the nand set data */
+
+ size = sizeof(struct s3c2410_nand_set) * npd->nr_sets;
+ if (size) {
+ struct s3c2410_nand_set *from = npd->sets;
+ struct s3c2410_nand_set *to;
+ int i;
+
+ to = kmemdup(from, size, GFP_KERNEL);
+ npd->sets = to; /* set, even if we failed */
+
+ if (!to) {
+ printk(KERN_ERR "%s: no memory for sets\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < npd->nr_sets; i++) {
+ ret = s3c_nand_copy_set(to);
+ if (ret) {
+ printk(KERN_ERR "%s: failed to copy set %d\n",
+ __func__, i);
+ return;
+ }
+ to++;
+ }
+ }
+
+ s3c_device_nand.dev.platform_data = npd;
+}
diff --git a/arch/arm/plat-samsung/dev-onenand.c b/arch/arm/plat-samsung/dev-onenand.c
new file mode 100644
index 00000000..f54ae71f
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-onenand.c
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/plat-samsung/dev-onenand.c
+ *
+ * Copyright (c) 2008-2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S3C64XX/S5PC100 series device definition for OneNAND devices
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+static struct resource s3c_onenand_resources[] = {
+ [0] = {
+ .start = S3C_PA_ONENAND,
+ .end = S3C_PA_ONENAND + 0x400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = S3C_PA_ONENAND_BUF,
+ .end = S3C_PA_ONENAND_BUF + S3C_SZ_ONENAND_BUF - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = IRQ_ONENAND,
+ .end = IRQ_ONENAND,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_onenand = {
+ .name = "samsung-onenand",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_onenand_resources),
+ .resource = s3c_onenand_resources,
+};
diff --git a/arch/arm/plat-samsung/dev-pwm.c b/arch/arm/plat-samsung/dev-pwm.c
new file mode 100644
index 00000000..dab47b0e
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-pwm.c
@@ -0,0 +1,53 @@
+/* linux/arch/arm/plat-samsung/dev-pwm.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series device definition for the PWM timer
+ *
+ * This program is free software; you can 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/irqs.h>
+
+#include <plat/devs.h>
+
+#define TIMER_RESOURCE_SIZE (1)
+
+#define TIMER_RESOURCE(_tmr, _irq) \
+ (struct resource [TIMER_RESOURCE_SIZE]) { \
+ [0] = { \
+ .start = _irq, \
+ .end = _irq, \
+ .flags = IORESOURCE_IRQ \
+ } \
+ }
+
+#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
+ .name = "s3c24xx-pwm", \
+ .id = _tmr_no, \
+ .num_resources = TIMER_RESOURCE_SIZE, \
+ .resource = TIMER_RESOURCE(_tmr_no, _irq), \
+
+/*
+ * since we already have an static mapping for the timer,
+ * we do not bother setting any IO resource for the base.
+ */
+
+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) },
+};
+EXPORT_SYMBOL(s3c_device_timer);
diff --git a/arch/arm/plat-samsung/dev-rtc.c b/arch/arm/plat-samsung/dev-rtc.c
new file mode 100644
index 00000000..bf4e2267
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-rtc.c
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-samsung/dev-rtc.c
+ *
+ * Copyright 2009 by Maurus Cuelenaere <mcuelenaere@gmail.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/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_rtc_resource[] = {
+ [0] = {
+ .start = S3C_PA_RTC,
+ .end = S3C_PA_RTC + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_RTC_ALARM,
+ .end = IRQ_RTC_ALARM,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = IRQ_RTC_TIC,
+ .end = IRQ_RTC_TIC,
+ .flags = IORESOURCE_IRQ
+ }
+};
+
+struct platform_device s3c_device_rtc = {
+ .name = "s3c64xx-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_rtc_resource),
+ .resource = s3c_rtc_resource,
+};
+EXPORT_SYMBOL(s3c_device_rtc);
diff --git a/arch/arm/plat-samsung/dev-ts.c b/arch/arm/plat-samsung/dev-ts.c
new file mode 100644
index 00000000..3e4bd814
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ts.c
@@ -0,0 +1,60 @@
+/* linux/arch/arm/mach-s3c64xx/dev-ts.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_ADC,
+ .end = SAMSUNG_PA_ADC + SZ_256 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TC,
+ .end = IRQ_TC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_ts = {
+ .name = "s3c64xx-ts",
+ .id = -1,
+ .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;
+}
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
new file mode 100644
index 00000000..59281054
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -0,0 +1,46 @@
+/* linux/arch/arm/plat-samsung/dev-uart.c
+ * originally from arch/arm/plat-s3c24xx/devs.c
+ *x
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Base S3C24XX 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/kernel.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+
+/* uart devices */
+
+static struct platform_device s3c24xx_uart_device0 = {
+ .id = 0,
+};
+
+static struct platform_device s3c24xx_uart_device1 = {
+ .id = 1,
+};
+
+static struct platform_device s3c24xx_uart_device2 = {
+ .id = 2,
+};
+
+static struct platform_device s3c24xx_uart_device3 = {
+ .id = 3,
+};
+
+struct platform_device *s3c24xx_uart_src[4] = {
+ &s3c24xx_uart_device0,
+ &s3c24xx_uart_device1,
+ &s3c24xx_uart_device2,
+ &s3c24xx_uart_device3,
+};
+
+struct platform_device *s3c24xx_uart_devs[4] = {
+};
diff --git a/arch/arm/plat-samsung/dev-usb-hsotg.c b/arch/arm/plat-samsung/dev-usb-hsotg.c
new file mode 100644
index 00000000..33a844ab
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb-hsotg.c
@@ -0,0 +1,48 @@
+/* linux/arch/arm/plat-s3c/dev-usb-hsotg.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB high-speed UDC/OtG block
+ *
+ * This program is free software; you can 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 <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_usb_hsotg_resources[] = {
+ [0] = {
+ .start = S3C_PA_USB_HSOTG,
+ .end = S3C_PA_USB_HSOTG + 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_OTG,
+ .end = IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 s3c_hsotg_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c_device_usb_hsotg = {
+ .name = "s3c-hsotg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources),
+ .resource = s3c_usb_hsotg_resources,
+ .dev = {
+ .dma_mask = &s3c_hsotg_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
diff --git a/arch/arm/plat-samsung/dev-usb.c b/arch/arm/plat-samsung/dev-usb.c
new file mode 100644
index 00000000..0e0a3bf5
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-usb.c
@@ -0,0 +1,70 @@
+/* linux/arch/arm/plat-s3c/dev-usb.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series device definition for USB host
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+#include <plat/usb-control.h>
+
+static struct resource s3c_usb_resource[] = {
+ [0] = {
+ .start = S3C_PA_USBHOST,
+ .end = S3C_PA_USBHOST + 0x100 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_USBH,
+ .end = IRQ_USBH,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_usb_dmamask = 0xffffffffUL;
+
+struct platform_device s3c_device_ohci = {
+ .name = "s3c2410-ohci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_usb_resource),
+ .resource = s3c_usb_resource,
+ .dev = {
+ .dma_mask = &s3c_device_usb_dmamask,
+ .coherent_dma_mask = 0xffffffffUL
+ }
+};
+
+EXPORT_SYMBOL(s3c_device_ohci);
+
+/**
+ * s3c_ohci_set_platdata - initialise OHCI device platform data
+ * @info: The platform data.
+ *
+ * This call copies the @info passed in and sets the device .platform_data
+ * field to that copy. The @info is copied so that the original can be marked
+ * __initdata.
+ */
+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;
+}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
new file mode 100644
index 00000000..019b5b8c
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -0,0 +1,40 @@
+/* linux/arch/arm/plat-samsung/dev-wdt.c
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C series device definition for the watchdog timer
+ *
+ * This program is free software; you can 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/irqs.h>
+#include <mach/map.h>
+
+#include <plat/devs.h>
+
+static struct resource s3c_wdt_resource[] = {
+ [0] = {
+ .start = S3C_PA_WDT,
+ .end = S3C_PA_WDT + SZ_1K,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_WDT,
+ .end = IRQ_WDT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+struct platform_device s3c_device_wdt = {
+ .name = "s3c2410-wdt",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(s3c_wdt_resource),
+ .resource = s3c_wdt_resource,
+};
+EXPORT_SYMBOL(s3c_device_wdt);
diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c
new file mode 100644
index 00000000..6143aa14
--- /dev/null
+++ b/arch/arm/plat-samsung/dma.c
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/dma.c
+ *
+ * Copyright (c) 2003-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C DMA core
+ *
+ * This program is free software; you can 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 s3c2410_dma_buf;
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+
+#include <mach/dma.h>
+#include <mach/irqs.h>
+
+/* dma channel state information */
+struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
+
+/* s3c_dma_lookup_channel
+ *
+ * change the dma channel number given into a real dma channel id
+*/
+
+struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
+{
+ if (channel & DMACH_LOW_LEVEL)
+ return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+ else
+ return s3c_dma_chan_map[channel];
+}
+
+/* do we need to protect the settings of the fields from
+ * irq?
+*/
+
+int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
+
+ chan->op_fn = rtn;
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+
+int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
+
+ chan->callback_fn = rtn;
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags)
+{
+ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+
+ chan->flags = flags;
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
new file mode 100644
index 00000000..1c0b0401
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -0,0 +1,431 @@
+/* linux/arch/arm/plat-s3c/gpio-config.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008-2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO configuration core
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/io.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ int ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ s3c_gpio_lock(chip, flags);
+ ret = s3c_gpio_do_setcfg(chip, offset, config);
+ s3c_gpio_unlock(chip, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_cfgpin);
+
+int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+ unsigned int cfg)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
+
+int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+ unsigned int cfg, s3c_gpio_pull_t pull)
+{
+ int ret;
+
+ for (; nr > 0; nr--, start++) {
+ s3c_gpio_setpull(start, pull);
+ ret = s3c_gpio_cfgpin(start, cfg);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
+
+unsigned s3c_gpio_getcfg(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ unsigned ret = 0;
+ int offset;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ s3c_gpio_lock(chip, flags);
+ ret = s3c_gpio_do_getcfg(chip, offset);
+ s3c_gpio_unlock(chip, flags);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_getcfg);
+
+
+int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset, ret;
+
+ if (!chip)
+ return -EINVAL;
+
+ offset = pin - chip->chip.base;
+
+ s3c_gpio_lock(chip, flags);
+ ret = s3c_gpio_do_setpull(chip, offset, pull);
+ s3c_gpio_unlock(chip, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c_gpio_setpull);
+
+s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned long flags;
+ int offset;
+ u32 pup = 0;
+
+ if (chip) {
+ offset = pin - chip->chip.base;
+
+ s3c_gpio_lock(chip, flags);
+ pup = s3c_gpio_do_getpull(chip, offset);
+ s3c_gpio_unlock(chip, flags);
+ }
+
+ return (__force s3c_gpio_pull_t)pup;
+}
+EXPORT_SYMBOL(s3c_gpio_getpull);
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
+int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off;
+ u32 con;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+
+ /* Map output to 0, and SFN2 to 1 */
+ cfg -= 1;
+ if (cfg > 1)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x1 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off;
+ con &= 1;
+ con++;
+
+ return S3C_GPIO_SFN(con);
+}
+
+int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = off * 2;
+ u32 con;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ if (cfg > 3)
+ return -EINVAL;
+
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0x3 << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ u32 con;
+
+ con = __raw_readl(chip->base);
+ con >>= off * 2;
+ con &= 3;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
+#endif
+
+#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
+int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ if (s3c_gpio_is_cfg_special(cfg)) {
+ cfg &= 0xf;
+ cfg <<= shift;
+ }
+
+ con = __raw_readl(reg);
+ con &= ~(0xf << shift);
+ con |= cfg;
+ __raw_writel(con, reg);
+
+ return 0;
+}
+
+unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base;
+ unsigned int shift = (off & 7) * 4;
+ u32 con;
+
+ if (off < 8 && chip->chip.ngpio > 8)
+ reg -= 4;
+
+ con = __raw_readl(reg);
+ con >>= shift;
+ con &= 0xf;
+
+ /* this conversion works for IN and OUT as well as special mode */
+ return S3C_GPIO_SPECIAL(con);
+}
+
+#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
+int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup;
+
+ pup = __raw_readl(reg);
+ pup &= ~(3 << shift);
+ pup |= pull << shift;
+ __raw_writel(pup, reg);
+
+ return 0;
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ void __iomem *reg = chip->base + 0x08;
+ int shift = off * 2;
+ u32 pup = __raw_readl(reg);
+
+ pup >>= shift;
+ pup &= 0x3;
+ return (__force s3c_gpio_pull_t)pup;
+}
+
+#ifdef CONFIG_S3C_GPIO_PULL_S3C2443
+int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ switch (pull) {
+ case S3C_GPIO_PULL_NONE:
+ pull = 0x01;
+ break;
+ case S3C_GPIO_PULL_UP:
+ pull = 0x00;
+ break;
+ case S3C_GPIO_PULL_DOWN:
+ pull = 0x02;
+ break;
+ }
+ return s3c_gpio_setpull_updown(chip, off, pull);
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ s3c_gpio_pull_t pull;
+
+ pull = s3c_gpio_getpull_updown(chip, off);
+
+ switch (pull) {
+ case 0x00:
+ pull = S3C_GPIO_PULL_UP;
+ break;
+ case 0x01:
+ case 0x03:
+ pull = S3C_GPIO_PULL_NONE;
+ break;
+ case 0x02:
+ pull = S3C_GPIO_PULL_DOWN;
+ break;
+ }
+
+ return pull;
+}
+#endif
+#endif
+
+#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
+static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull,
+ s3c_gpio_pull_t updown)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ if (pull == updown)
+ pup &= ~(1 << off);
+ else if (pull == S3C_GPIO_PULL_NONE)
+ pup |= (1 << off);
+ else
+ return -EINVAL;
+
+ __raw_writel(pup, reg);
+ return 0;
+}
+
+static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t updown)
+{
+ void __iomem *reg = chip->base + 0x08;
+ u32 pup = __raw_readl(reg);
+
+ pup &= (1 << off);
+ return pup ? S3C_GPIO_PULL_NONE : updown;
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */
+
+#ifdef CONFIG_S3C_GPIO_PULL_UP
+s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
+}
+
+int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
+}
+#endif /* CONFIG_S3C_GPIO_PULL_UP */
+
+#ifdef CONFIG_S3C_GPIO_PULL_DOWN
+s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
+}
+
+int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
+}
+#endif /* CONFIG_S3C_GPIO_PULL_DOWN */
+
+#ifdef CONFIG_S5P_GPIO_DRVSTR
+s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin)
+{
+ struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
+ unsigned int off;
+ void __iomem *reg;
+ int shift;
+ u32 drvstr;
+
+ if (!chip)
+ return -EINVAL;
+
+ off = pin - chip->chip.base;
+ shift = off * 2;
+ reg = chip->base + 0x0C;
+
+ drvstr = __raw_readl(reg);
+ drvstr = drvstr >> shift;
+ drvstr &= 0x3;
+
+ return (__force s5p_gpio_drvstr_t)drvstr;
+}
+EXPORT_SYMBOL(s5p_gpio_get_drvstr);
+
+int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr)
+{
+ 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 + 0x0C;
+
+ tmp = __raw_readl(reg);
+ tmp &= ~(0x3 << shift);
+ tmp |= drvstr << shift;
+
+ __raw_writel(tmp, reg);
+
+ return 0;
+}
+EXPORT_SYMBOL(s5p_gpio_set_drvstr);
+#endif /* CONFIG_S5P_GPIO_DRVSTR */
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
new file mode 100644
index 00000000..7743c4b8
--- /dev/null
+++ b/arch/arm/plat-samsung/gpio.c
@@ -0,0 +1,167 @@
+/* linux/arch/arm/plat-s3c/gpio.c
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO core
+ *
+ * This program is free software; you can 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/io.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+
+#include <plat/gpio-core.h>
+
+#ifdef CONFIG_S3C_GPIO_TRACK
+struct s3c_gpio_chip *s3c_gpios[S3C_GPIO_END];
+
+static __init void s3c_gpiolib_track(struct s3c_gpio_chip *chip)
+{
+ unsigned int gpn;
+ int i;
+
+ gpn = chip->chip.base;
+ for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
+ BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
+ s3c_gpios[gpn] = chip;
+ }
+}
+#endif /* CONFIG_S3C_GPIO_TRACK */
+
+/* Default routines for controlling GPIO, based on the original S3C24XX
+ * GPIO functions which deal with the case where each gpio bank of the
+ * chip is as following:
+ *
+ * base + 0x00: Control register, 2 bits per gpio
+ * gpio n: 2 bits starting at (2*n)
+ * 00 = input, 01 = output, others mean special-function
+ * base + 0x04: Data register, 1 bit per gpio
+ * bit n: data bit n
+*/
+
+static int s3c_gpiolib_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long con;
+
+ s3c_gpio_lock(ourchip, flags);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+
+ __raw_writel(con, base + 0x00);
+
+ s3c_gpio_unlock(ourchip, flags);
+ return 0;
+}
+
+static int s3c_gpiolib_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+ unsigned long con;
+
+ s3c_gpio_lock(ourchip, flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ con = __raw_readl(base + 0x00);
+ con &= ~(3 << (offset * 2));
+ con |= 1 << (offset * 2);
+
+ __raw_writel(con, base + 0x00);
+ __raw_writel(dat, base + 0x04);
+
+ s3c_gpio_unlock(ourchip, flags);
+ return 0;
+}
+
+static void s3c_gpiolib_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ void __iomem *base = ourchip->base;
+ unsigned long flags;
+ unsigned long dat;
+
+ s3c_gpio_lock(ourchip, flags);
+
+ dat = __raw_readl(base + 0x04);
+ dat &= ~(1 << offset);
+ if (value)
+ dat |= 1 << offset;
+ __raw_writel(dat, base + 0x04);
+
+ s3c_gpio_unlock(ourchip, flags);
+}
+
+static int s3c_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct s3c_gpio_chip *ourchip = to_s3c_gpio(chip);
+ unsigned long val;
+
+ val = __raw_readl(ourchip->base + 0x04);
+ val >>= offset;
+ val &= 1;
+
+ return val;
+}
+
+__init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
+{
+ struct gpio_chip *gc = &chip->chip;
+ int ret;
+
+ BUG_ON(!chip->base);
+ BUG_ON(!gc->label);
+ BUG_ON(!gc->ngpio);
+
+ spin_lock_init(&chip->lock);
+
+ if (!gc->direction_input)
+ gc->direction_input = s3c_gpiolib_input;
+ if (!gc->direction_output)
+ gc->direction_output = s3c_gpiolib_output;
+ if (!gc->set)
+ gc->set = s3c_gpiolib_set;
+ if (!gc->get)
+ gc->get = s3c_gpiolib_get;
+
+#ifdef CONFIG_PM
+ if (chip->pm != NULL) {
+ if (!chip->pm->save || !chip->pm->resume)
+ printk(KERN_ERR "gpio: %s has missing PM functions\n",
+ gc->label);
+ } else
+ printk(KERN_ERR "gpio: %s has no PM function\n", gc->label);
+#endif
+
+ /* gpiochip_add() prints own failure message on error. */
+ ret = gpiochip_add(gc);
+ if (ret >= 0)
+ s3c_gpiolib_track(chip);
+}
+
+int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
+{
+ struct s3c_gpio_chip *s3c_chip = container_of(chip,
+ struct s3c_gpio_chip, chip);
+
+ return s3c_chip->irq_base + offset;
+}
diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h
new file mode 100644
index 00000000..a281568d
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/adc-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung ADC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ADC_CORE_H
+#define __ASM_PLAT_ADC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_adc_setname(char *name)
+{
+#ifdef CONFIG_SAMSUNG_DEV_ADC
+ s3c_device_adc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_ADC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/adc.h b/arch/arm/plat-samsung/include/plat/adc.h
new file mode 100644
index 00000000..b258a08d
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc.h
@@ -0,0 +1,35 @@
+/* arch/arm/plat-samsung/include/plat/adc.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C ADC driver information
+ *
+ * This program is free software; you can 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_ADC_H
+#define __ASM_PLAT_ADC_H __FILE__
+
+struct s3c_adc_client;
+
+extern int s3c_adc_start(struct s3c_adc_client *client,
+ unsigned int channel, unsigned int nr_samples);
+
+extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch);
+
+extern struct s3c_adc_client *
+ s3c_adc_register(struct platform_device *pdev,
+ void (*select)(struct s3c_adc_client *client,
+ unsigned selected),
+ void (*conv)(struct s3c_adc_client *client,
+ unsigned d0, unsigned d1,
+ unsigned *samples_left),
+ unsigned int is_ts);
+
+extern void s3c_adc_release(struct s3c_adc_client *client);
+
+#endif /* __ASM_PLAT_ADC_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata-core.h b/arch/arm/plat-samsung/include/plat/ata-core.h
new file mode 100644
index 00000000..f5a4ec71
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/ata-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ATA_CORE_H
+#define __ASM_PLAT_ATA_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+*/
+
+/* re-define device name depending on support. */
+static inline void s3c_cfcon_setname(char *name)
+{
+#ifdef CONFIG_SAMSUNG_DEV_IDE
+ s3c_device_cfcon.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_ATA_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h
new file mode 100644
index 00000000..2a3855a8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-samsung/include/plat/ata.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA platform_device info
+ *
+ * This program is free software; you can 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_ATA_H
+#define __ASM_PLAT_ATA_H __FILE__
+
+/**
+ * struct s3c_ide_platdata - S3C IDE driver platform data.
+ * @setup_gpio: Setup the external GPIO pins to the right state for data
+ * transfer in true-ide mode.
+ */
+struct s3c_ide_platdata {
+ void (*setup_gpio)(void);
+};
+
+/*
+ * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver.
+ * @pdata: Platform data for IDE driver.
+ */
+extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata);
+
+/* architecture-specific IDE configuration */
+extern void s3c64xx_ide_setup_gpio(void);
+extern void s5pc100_ide_setup_gpio(void);
+extern void s5pv210_ide_setup_gpio(void);
+
+#endif /*__ASM_PLAT_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h
new file mode 100644
index 00000000..a0826ed2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/audio.h
@@ -0,0 +1,58 @@
+/* arch/arm/plat-samsung/include/plat/audio.h
+ *
+ * Copyright (c) 2009 Samsung Electronics Co. Ltd
+ * Author: 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.
+ */
+
+/* The machine init code calls s3c*_ac97_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for AC97 pins
+ */
+#define S3C64XX_AC97_GPD 0
+#define S3C64XX_AC97_GPE 1
+extern void s3c64xx_ac97_setup_gpio(int);
+
+/*
+ * The machine init code calls s5p*_spdif_setup_gpio with
+ * one of these defines in order to select appropriate bank
+ * of GPIO for S/PDIF pins
+ */
+#define S5PC100_SPDIF_GPD 0
+#define S5PC100_SPDIF_GPG3 1
+extern void s5pc100_spdif_setup_gpio(int);
+
+struct samsung_i2s {
+/* If the Primary DAI has 5.1 Channels */
+#define QUIRK_PRI_6CHAN (1 << 0)
+/* If the I2S block has a Stereo Overlay Channel */
+#define QUIRK_SEC_DAI (1 << 1)
+/*
+ * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit)
+ * The Machine driver must provide suitably set clock to the I2S block.
+ */
+#define QUIRK_NO_MUXPSR (1 << 2)
+#define QUIRK_NEED_RSTCLR (1 << 3)
+ /* Quirks of the I2S controller */
+ u32 quirks;
+
+ /*
+ * Array of clock names that can be used to generate I2S signals.
+ * Also corresponds to clocks of I2SMOD[10]
+ */
+ const char **src_clk;
+};
+
+/**
+ * struct s3c_audio_pdata - common platform data for audio device drivers
+ * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode
+ */
+struct s3c_audio_pdata {
+ int (*cfg_gpio)(struct platform_device *);
+ union {
+ struct samsung_i2s i2s;
+ } type;
+};
diff --git a/arch/arm/plat-samsung/include/plat/clock-clksrc.h b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
new file mode 100644
index 00000000..50a8ca7c
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
@@ -0,0 +1,83 @@
+/* linux/arch/arm/plat-samsung/include/plat/clock-clksrc.h
+ *
+ * Parts taken from arch/arm/plat-s3c64xx/clock.c
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Harald Welte
+ *
+ * This program is free software; you can 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 clksrc_sources - list of sources for a given clock
+ * @sources: array of pointers to clocks
+ * @nr_sources: The size of @sources
+ */
+struct clksrc_sources {
+ unsigned int nr_sources;
+ struct clk **sources;
+};
+
+/**
+ * struct clksrc_reg - register definition for clock control bits
+ * @reg: pointer to the register in virtual memory.
+ * @shift: the shift in bits to where the bitfield is.
+ * @size: the size in bits of the bitfield.
+ *
+ * This specifies the size and position of the bits we are interested
+ * in within the register specified by @reg.
+ */
+struct clksrc_reg {
+ void __iomem *reg;
+ unsigned short shift;
+ unsigned short size;
+};
+
+/**
+ * struct clksrc_clk - class of clock for newer style samsung devices.
+ * @clk: the standard clock representation
+ * @sources: the sources for this clock
+ * @reg_src: the register definition for selecting the clock's source
+ * @reg_div: the register definition for the clock's output divisor
+ *
+ * This clock implements the features required by the newer SoCs where
+ * the standard clock block provides an input mux and a post-mux divisor
+ * to provide the periperhal's clock.
+ *
+ * The array of @sources provides the mapping of mux position to the
+ * clock, and @reg_src shows the code where to modify to change the mux
+ * position. The @reg_div defines how to change the divider settings on
+ * the output.
+ */
+struct clksrc_clk {
+ struct clk clk;
+ struct clksrc_sources *sources;
+
+ struct clksrc_reg reg_src;
+ struct clksrc_reg reg_div;
+};
+
+/**
+ * s3c_set_clksrc() - setup the clock from the register settings
+ * @clk: The clock to setup.
+ * @announce: true to announce the setting to printk().
+ *
+ * Setup the clock from the current register settings, for when the
+ * kernel boots or if it is resuming from a possibly unknown state.
+ */
+extern void s3c_set_clksrc(struct clksrc_clk *clk, bool announce);
+
+/**
+ * s3c_register_clksrc() register clocks from an array of clksrc clocks
+ * @srcs: The array of clocks to register
+ * @size: The size of the @srcs array.
+ *
+ * Initialise and register the array of clocks described by @srcs.
+ */
+extern void s3c_register_clksrc(struct clksrc_clk *srcs, int size);
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
new file mode 100644
index 00000000..983c578b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -0,0 +1,120 @@
+/* linux/arch/arm/plat-s3c/include/plat/clock.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * http://www.simtec.co.uk/products/SWLINUX/
+ * Written by 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/spinlock.h>
+
+struct clk;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fields again. We leave
+ * enable in struct clk.
+ *
+ * Adding an extra layer of indirection into the process should
+ * not be a problem as it is unlikely these operations are going
+ * to need to be called quickly.
+ */
+struct clk_ops {
+ int (*set_rate)(struct clk *c, unsigned long rate);
+ unsigned long (*get_rate)(struct clk *c);
+ unsigned long (*round_rate)(struct clk *c, unsigned long rate);
+ int (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+struct clk {
+ struct list_head list;
+ struct module *owner;
+ struct clk *parent;
+ const char *name;
+ int id;
+ int usage;
+ unsigned long rate;
+ unsigned long ctrlbit;
+
+ struct clk_ops *ops;
+ int (*enable)(struct clk *, int enable);
+#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
+ struct dentry *dent; /* For visible tree hierarchy */
+#endif
+};
+
+/* other clocks which may be registered by board support */
+
+extern struct clk s3c24xx_dclk0;
+extern struct clk s3c24xx_dclk1;
+extern struct clk s3c24xx_clkout0;
+extern struct clk s3c24xx_clkout1;
+extern struct clk s3c24xx_uclk;
+
+extern struct clk clk_usb_bus;
+
+/* core clock support */
+
+extern struct clk clk_f;
+extern struct clk clk_h;
+extern struct clk clk_p;
+extern struct clk clk_mpll;
+extern struct clk clk_upll;
+extern struct clk clk_epll;
+extern struct clk clk_xtal;
+extern struct clk clk_ext;
+
+/* S3C64XX specific clocks */
+extern struct clk clk_h2;
+extern struct clk clk_27m;
+extern struct clk clk_48m;
+extern struct clk clk_xusbxti;
+
+extern int clk_default_setrate(struct clk *clk, unsigned long rate);
+extern struct clk_ops clk_ops_def_setrate;
+
+/* exports for arch/arm/mach-s3c2410
+ *
+ * Please DO NOT use these outside of arch/arm/mach-s3c2410
+*/
+
+extern spinlock_t clocks_lock;
+
+extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
+
+extern int s3c24xx_register_clock(struct clk *clk);
+extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
+
+extern void s3c_register_clocks(struct clk *clk, int nr_clks);
+extern void s3c_disable_clocks(struct clk *clkp, int nr_clks);
+
+extern int s3c24xx_register_baseclocks(unsigned long xtal);
+
+extern void s5p_register_clocks(unsigned long xtal_freq);
+
+extern void s3c24xx_setup_clocks(unsigned long fclk,
+ unsigned long hclk,
+ unsigned long pclk);
+
+extern void s3c2410_setup_clocks(void);
+extern void s3c2412_setup_clocks(void);
+extern void s3c244x_setup_clocks(void);
+extern void s3c2443_setup_clocks(void);
+
+/* S3C64XX specific functions and clocks */
+
+extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
+
+/* Init for pwm clock code */
+
+extern void s3c_pwmclk_init(void);
+
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq.h b/arch/arm/plat-samsung/include/plat/cpu-freq.h
new file mode 100644
index 00000000..80c4a809
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq.h
@@ -0,0 +1,145 @@
+/* arch/arm/plat-samsung/include/plat/cpu-freq.h
+ *
+ * Copyright (c) 2006-2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C CPU frequency scaling support - driver and 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/cpufreq.h>
+
+struct s3c_cpufreq_info;
+struct s3c_cpufreq_board;
+struct s3c_iotimings;
+
+/**
+ * struct s3c_freq - frequency information (mainly for core drivers)
+ * @fclk: The FCLK frequency in Hz.
+ * @armclk: The ARMCLK frequency in Hz.
+ * @hclk_tns: HCLK cycle time in 10ths of nano-seconds.
+ * @hclk: The HCLK frequency in Hz.
+ * @pclk: The PCLK frequency in Hz.
+ *
+ * This contains the frequency information about the current configuration
+ * mainly for the core drivers to ensure we do not end up passing about
+ * a large number of parameters.
+ *
+ * The @hclk_tns field is a useful cache for the parts of the drivers that
+ * need to calculate IO timings and suchlike.
+ */
+struct s3c_freq {
+ unsigned long fclk;
+ unsigned long armclk;
+ unsigned long hclk_tns; /* in 10ths of ns */
+ unsigned long hclk;
+ unsigned long pclk;
+};
+
+/**
+ * struct s3c_cpufreq_freqs - s3c cpufreq notification information.
+ * @freqs: The cpufreq setting information.
+ * @old: The old clock settings.
+ * @new: The new clock settings.
+ * @pll_changing: Set if the PLL is changing.
+ *
+ * Wrapper 'struct cpufreq_freqs' so that any drivers receiving the
+ * notification can use this information that is not provided by just
+ * having the core frequency alone.
+ *
+ * The pll_changing flag is used to indicate if the PLL itself is
+ * being set during this change. This is important as the clocks
+ * will temporarily be set to the XTAL clock during this time, so
+ * drivers may want to close down their output during this time.
+ *
+ * Note, this is not being used by any current drivers and therefore
+ * may be removed in the future.
+ */
+struct s3c_cpufreq_freqs {
+ struct cpufreq_freqs freqs;
+ struct s3c_freq old;
+ struct s3c_freq new;
+
+ unsigned int pll_changing:1;
+};
+
+#define to_s3c_cpufreq(_cf) container_of(_cf, struct s3c_cpufreq_freqs, freqs)
+
+/**
+ * struct s3c_clkdivs - clock divisor information
+ * @p_divisor: Divisor from FCLK to PCLK.
+ * @h_divisor: Divisor from FCLK to HCLK.
+ * @arm_divisor: Divisor from FCLK to ARMCLK (not all CPUs).
+ * @dvs: Non-zero if using DVS mode for ARMCLK.
+ *
+ * Divisor settings for the core clocks.
+ */
+struct s3c_clkdivs {
+ int p_divisor;
+ int h_divisor;
+ int arm_divisor;
+ unsigned char dvs;
+};
+
+#define PLLVAL(_m, _p, _s) (((_m) << 12) | ((_p) << 4) | (_s))
+
+/**
+ * struct s3c_pllval - PLL value entry.
+ * @freq: The frequency for this entry in Hz.
+ * @pll_reg: The PLL register setting for this PLL value.
+ */
+struct s3c_pllval {
+ unsigned long freq;
+ unsigned long pll_reg;
+};
+
+/**
+ * struct s3c_cpufreq_board - per-board cpu frequency informatin
+ * @refresh: The SDRAM refresh period in nanoseconds.
+ * @auto_io: Set if the IO timing settings should be generated from the
+ * initialisation time hardware registers.
+ * @need_io: Set if the board has external IO on any of the chipselect
+ * lines that will require the hardware timing registers to be
+ * updated on a clock change.
+ * @max: The maxium frequency limits for the system. Any field that
+ * is left at zero will use the CPU's settings.
+ *
+ * This contains the board specific settings that affect how the CPU
+ * drivers chose settings. These include the memory refresh and IO
+ * timing information.
+ *
+ * Registration depends on the driver being used, the ARMCLK only
+ * implementation does not currently need this but the older style
+ * driver requires this to be available.
+ */
+struct s3c_cpufreq_board {
+ unsigned int refresh;
+ unsigned int auto_io:1; /* automatically init io timings. */
+ unsigned int need_io:1; /* set if needs io timing support. */
+
+ /* any non-zero field in here is taken as an upper limit. */
+ struct s3c_freq max; /* frequency limits */
+};
+
+/* Things depending on frequency scaling. */
+#ifdef CONFIG_CPU_FREQ_S3C
+#define __init_or_cpufreq
+#else
+#define __init_or_cpufreq __init
+#endif
+
+/* Board functions */
+
+#ifdef CONFIG_CPU_FREQ_S3C
+extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
+#else
+
+static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
+{
+ return 0;
+}
+#endif /* CONFIG_CPU_FREQ_S3C */
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
new file mode 100644
index 00000000..c0a5741b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -0,0 +1,94 @@
+/* linux/arch/arm/plat-samsung/include/plat/cpu.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for S3C24XX 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.
+*/
+
+/* todo - fix when rmk changes iodescs to use `void __iomem *` */
+
+#ifndef __SAMSUNG_PLAT_CPU_H
+#define __SAMSUNG_PLAT_CPU_H
+
+#define IODESC_ENT(x) { (unsigned long)S3C24XX_VA_##x, __phys_to_pfn(S3C24XX_PA_##x), S3C24XX_SZ_##x, MT_DEVICE }
+
+#ifndef MHZ
+#define MHZ (1000*1000)
+#endif
+
+#define print_mhz(m) ((m) / MHZ), (((m) / 1000) % 1000)
+
+/* forward declaration */
+struct s3c24xx_uart_resources;
+struct platform_device;
+struct s3c2410_uartcfg;
+struct map_desc;
+
+/* per-cpu initialisation function table. */
+
+struct cpu_table {
+ unsigned long idcode;
+ unsigned long idmask;
+ void (*map_io)(void);
+ void (*init_uarts)(struct s3c2410_uartcfg *cfg, int no);
+ void (*init_clocks)(int xtal);
+ int (*init)(void);
+ const char *name;
+};
+
+extern void s3c_init_cpu(unsigned long idcode,
+ struct cpu_table *cpus, unsigned int cputab_size);
+
+/* core initialisation functions */
+
+extern void s3c24xx_init_irq(void);
+extern void s3c64xx_init_irq(u32 vic0, u32 vic1);
+extern void s5p_init_irq(u32 *vic, u32 num_vic);
+
+extern void s3c24xx_init_io(struct map_desc *mach_desc, int size);
+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_uarts(struct s3c2410_uartcfg *cfg, int no);
+
+extern void s3c24xx_init_clocks(int xtal);
+
+extern void s3c24xx_init_uartdevs(char *name,
+ struct s3c24xx_uart_resources *res,
+ struct s3c2410_uartcfg *cfg, int no);
+
+/* timer for 2410/2440 */
+
+struct sys_timer;
+extern struct sys_timer s3c24xx_timer;
+
+extern struct syscore_ops s3c2410_pm_syscore_ops;
+extern struct syscore_ops s3c2412_pm_syscore_ops;
+extern struct syscore_ops s3c2416_pm_syscore_ops;
+extern struct syscore_ops s3c244x_pm_syscore_ops;
+extern struct syscore_ops s3c64xx_irq_syscore_ops;
+
+/* system device classes */
+
+extern struct sysdev_class s3c2410_sysclass;
+extern struct sysdev_class s3c2410a_sysclass;
+extern struct sysdev_class s3c2412_sysclass;
+extern struct sysdev_class s3c2416_sysclass;
+extern struct sysdev_class s3c2440_sysclass;
+extern struct sysdev_class s3c2442_sysclass;
+extern struct sysdev_class s3c2443_sysclass;
+extern struct sysdev_class s3c6410_sysclass;
+extern struct sysdev_class s3c64xx_sysclass;
+extern struct sysdev_class s5p64x0_sysclass;
+extern struct sysdev_class s5pv210_sysclass;
+extern struct sysdev_class exynos4_sysclass;
+
+extern void (*s5pc1xx_idle)(void);
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/debug-macro.S b/arch/arm/plat-samsung/include/plat/debug-macro.S
new file mode 100644
index 00000000..207e2753
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/debug-macro.S
@@ -0,0 +1,87 @@
+/* arch/arm/plat-samsung/include/plat/debug-macro.S
+ *
+ * Copyright 2005, 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * 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 <plat/regs-serial.h>
+
+/* The S5PV210/S5PC110 implementations are as belows. */
+
+ .macro fifo_level_s5pv210 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ and \rd, \rd, #S5PV210_UFSTAT_TXMASK
+ .endm
+
+ .macro fifo_full_s5pv210 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ tst \rd, #S5PV210_UFSTAT_TXFULL
+ .endm
+
+/* The S3C2440 implementations are used by default as they are the
+ * most widely re-used */
+
+ .macro fifo_level_s3c2440 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ and \rd, \rd, #S3C2440_UFSTAT_TXMASK
+ .endm
+
+#ifndef fifo_level
+#define fifo_level fifo_level_s3c2440
+#endif
+
+ .macro fifo_full_s3c2440 rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFSTAT ]
+ tst \rd, #S3C2440_UFSTAT_TXFULL
+ .endm
+
+#ifndef fifo_full
+#define fifo_full fifo_full_s3c2440
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, # S3C2410_UTXH ]
+ .endm
+
+ .macro busyuart, rd, rx
+ ldr \rd, [ \rx, # S3C2410_UFCON ]
+ tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
+ beq 1001f @
+ @ FIFO enabled...
+1003:
+ fifo_full \rd, \rx
+ bne 1003b
+ b 1002f
+
+1001:
+ @ busy waiting for non fifo
+ ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
+ tst \rd, #S3C2410_UTRSTAT_TXFE
+ beq 1001b
+
+1002: @ exit busyuart
+ .endm
+
+ .macro waituart,rd,rx
+ ldr \rd, [ \rx, # S3C2410_UFCON ]
+ tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled?
+ beq 1001f @
+ @ FIFO enabled...
+1003:
+ fifo_level \rd, \rx
+ teq \rd, #0
+ bne 1003b
+ b 1002f
+1001:
+ @ idle waiting for non fifo
+ ldr \rd, [ \rx, # S3C2410_UTRSTAT ]
+ tst \rd, #S3C2410_UTRSTAT_TXFE
+ beq 1001b
+
+1002: @ exit busyuart
+ .endm
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
new file mode 100644
index 00000000..e3b31c26
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -0,0 +1,167 @@
+/* arch/arm/plat-samsung/include/plat/devs.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for s3c2410 standard platform 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.
+*/
+
+#ifndef __PLAT_DEVS_H
+#define __PLAT_DEVS_H __FILE__
+
+#include <linux/platform_device.h>
+
+struct s3c24xx_uart_resources {
+ struct resource *resources;
+ unsigned long nr_resources;
+};
+
+extern struct s3c24xx_uart_resources s3c2410_uart_resources[];
+extern struct s3c24xx_uart_resources s3c64xx_uart_resources[];
+extern struct s3c24xx_uart_resources s5p_uart_resources[];
+
+extern struct platform_device *s3c24xx_uart_devs[];
+extern struct platform_device *s3c24xx_uart_src[];
+
+extern struct platform_device s3c_device_timer[];
+
+extern struct platform_device s3c64xx_device_iis0;
+extern struct platform_device s3c64xx_device_iis1;
+extern struct platform_device s3c64xx_device_iisv4;
+
+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 s3c64xx_device_pcm0;
+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_fb;
+extern struct platform_device s3c_device_ohci;
+extern struct platform_device s3c_device_lcd;
+extern struct platform_device s3c_device_wdt;
+extern struct platform_device s3c_device_i2c0;
+extern struct platform_device s3c_device_i2c1;
+extern struct platform_device s3c_device_i2c2;
+extern struct platform_device s3c_device_i2c3;
+extern struct platform_device s3c_device_i2c4;
+extern struct platform_device s3c_device_i2c5;
+extern struct platform_device s3c_device_i2c6;
+extern struct platform_device s3c_device_i2c7;
+extern struct platform_device s3c_device_rtc;
+extern struct platform_device s3c_device_adc;
+extern struct platform_device s3c_device_sdi;
+extern struct platform_device s3c_device_iis;
+extern struct platform_device s3c_device_hwmon;
+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_cfcon;
+
+extern struct platform_device s3c_device_spi0;
+extern struct platform_device s3c_device_spi1;
+
+extern struct platform_device s5pc100_device_spi0;
+extern struct platform_device s5pc100_device_spi1;
+extern struct platform_device s5pc100_device_spi2;
+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 s3c_device_hwmon;
+
+extern struct platform_device s3c_device_nand;
+extern struct platform_device s3c_device_onenand;
+extern struct platform_device s3c64xx_device_onenand1;
+extern struct platform_device 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 s5pv210_device_ac97;
+extern struct platform_device s5pv210_device_pcm0;
+extern struct platform_device s5pv210_device_pcm1;
+extern struct platform_device s5pv210_device_pcm2;
+extern struct platform_device s5pv210_device_iis0;
+extern struct platform_device s5pv210_device_iis1;
+extern struct platform_device s5pv210_device_iis2;
+extern struct platform_device s5pv210_device_spdif;
+
+extern struct platform_device 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 exynos4_device_pd[];
+extern struct platform_device exynos4_device_ahci;
+
+extern struct platform_device s5p6440_device_pcm;
+extern struct platform_device s5p6440_device_iis;
+
+extern struct platform_device s5p6450_device_iis0;
+extern struct platform_device s5p6450_device_iis1;
+extern struct platform_device s5p6450_device_iis2;
+extern struct platform_device s5p6450_device_pcm0;
+
+extern struct platform_device s5pc100_device_ac97;
+extern struct platform_device s5pc100_device_pcm0;
+extern struct platform_device s5pc100_device_pcm1;
+extern struct platform_device s5pc100_device_iis0;
+extern struct platform_device s5pc100_device_iis1;
+extern struct platform_device s5pc100_device_iis2;
+extern struct platform_device s5pc100_device_spdif;
+
+extern struct platform_device samsung_device_keypad;
+
+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;
+
+extern struct platform_device s5p_device_mipi_csis0;
+extern struct platform_device s5p_device_mipi_csis1;
+
+extern struct platform_device s5p_device_ehci;
+
+extern struct platform_device exynos4_device_sysmmu;
+
+/* s3c2440 specific devices */
+
+#ifdef CONFIG_CPU_S3C2440
+
+extern struct platform_device s3c_device_camif;
+extern struct platform_device s3c_device_ac97;
+
+#endif
+
+/**
+ * s3c_set_platdata() - helper for setting platform data
+ * @pd: The default platform data for this device.
+ * @pdsize: The size of the platform data.
+ * @pdev: Pointer to the device to fill in.
+ *
+ * This helper replaces a number of calls that copy and then set the
+ * platform data of the device.
+ */
+extern void *s3c_set_platdata(void *pd, size_t pdsize,
+ struct platform_device *pdev);
+
+#endif /* __PLAT_DEVS_H */
diff --git a/arch/arm/plat-samsung/include/plat/dma-core.h b/arch/arm/plat-samsung/include/plat/dma-core.h
new file mode 100644
index 00000000..32ff2a92
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma-core.h
@@ -0,0 +1,22 @@
+/* arch/arm/plat-s3c/include/plat/dma.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung S3C DMA core 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.
+*/
+
+extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
+
+extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
+
+/* the currently allocated channel information */
+extern struct s3c2410_dma_chan s3c2410_chans[];
+
+
diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
new file mode 100644
index 00000000..336d5ac0
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
@@ -0,0 +1,84 @@
+/* linux/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+ *
+ * Copyright (C) 2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C24XX DMA support - per SoC 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 <plat/dma-core.h>
+
+extern struct sysdev_class dma_sysclass;
+extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
+
+#define DMA_CH_VALID (1<<31)
+#define DMA_CH_NEVER (1<<30)
+
+struct s3c24xx_dma_addr {
+ unsigned long from;
+ unsigned long to;
+};
+
+/* struct s3c24xx_dma_map
+ *
+ * this holds the mapping information for the channel selected
+ * to be connected to the specified device
+*/
+
+struct s3c24xx_dma_map {
+ const char *name;
+ struct s3c24xx_dma_addr hw_addr;
+
+ unsigned long channels[S3C_DMA_CHANNELS];
+ unsigned long channels_rx[S3C_DMA_CHANNELS];
+};
+
+struct s3c24xx_dma_selection {
+ struct s3c24xx_dma_map *map;
+ unsigned long map_size;
+ unsigned long dcon_mask;
+
+ void (*select)(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map);
+
+ void (*direction)(struct s3c2410_dma_chan *chan,
+ struct s3c24xx_dma_map *map,
+ enum s3c2410_dmasrc dir);
+};
+
+extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+
+/* struct s3c24xx_dma_order_ch
+ *
+ * channel map for one of the `enum dma_ch` dma channels. the list
+ * entry contains a set of low-level channel numbers, orred with
+ * DMA_CH_VALID, which are checked in the order in the array.
+*/
+
+struct s3c24xx_dma_order_ch {
+ unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
+ unsigned int flags; /* flags */
+};
+
+/* struct s3c24xx_dma_order
+ *
+ * information provided by either the core or the board to give the
+ * dma system a hint on how to allocate channels
+*/
+
+struct s3c24xx_dma_order {
+ struct s3c24xx_dma_order_ch channels[DMACH_MAX];
+};
+
+extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+
+/* DMA init code, called from the cpu support code */
+
+extern int s3c2410_dma_init(void);
+
+extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+ unsigned int stride);
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
new file mode 100644
index 00000000..8c273b7a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/dma.h
@@ -0,0 +1,128 @@
+/* arch/arm/plat-samsung/include/plat/dma.h
+ *
+ * Copyright (C) 2003-2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Samsung S3C DMA 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.
+*/
+
+enum s3c2410_dma_buffresult {
+ S3C2410_RES_OK,
+ S3C2410_RES_ERR,
+ S3C2410_RES_ABORT
+};
+
+enum s3c2410_dmasrc {
+ S3C2410_DMASRC_HW, /* source is memory */
+ S3C2410_DMASRC_MEM /* source is hardware */
+};
+
+/* enum s3c2410_chan_op
+ *
+ * operation codes passed to the DMA code by the user, and also used
+ * to inform the current channel owner of any changes to the system state
+*/
+
+enum s3c2410_chan_op {
+ S3C2410_DMAOP_START,
+ S3C2410_DMAOP_STOP,
+ S3C2410_DMAOP_PAUSE,
+ S3C2410_DMAOP_RESUME,
+ S3C2410_DMAOP_FLUSH,
+ S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
+ S3C2410_DMAOP_STARTED, /* indicate channel started */
+};
+
+struct s3c2410_dma_client {
+ char *name;
+};
+
+struct s3c2410_dma_chan;
+enum dma_ch;
+
+/* s3c2410_dma_cbfn_t
+ *
+ * buffer callback routine type
+*/
+
+typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
+ void *buf, int size,
+ enum s3c2410_dma_buffresult result);
+
+typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
+ enum s3c2410_chan_op );
+
+
+
+/* s3c2410_dma_request
+ *
+ * request a dma channel exclusivley
+*/
+
+extern int s3c2410_dma_request(enum dma_ch channel,
+ struct s3c2410_dma_client *, void *dev);
+
+
+/* s3c2410_dma_ctrl
+ *
+ * change the state of the dma channel
+*/
+
+extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op);
+
+/* s3c2410_dma_setflags
+ *
+ * set the channel's flags to a given state
+*/
+
+extern int s3c2410_dma_setflags(enum dma_ch channel,
+ unsigned int flags);
+
+/* s3c2410_dma_free
+ *
+ * free the dma channel (will also abort any outstanding operations)
+*/
+
+extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
+
+/* s3c2410_dma_enqueue
+ *
+ * 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(enum dma_ch channel, void *id,
+ dma_addr_t data, int size);
+
+/* s3c2410_dma_config
+ *
+ * configure the dma channel
+*/
+
+extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
+
+/* s3c2410_dma_devconfig
+ *
+ * configure the device we're talking to
+*/
+
+extern int s3c2410_dma_devconfig(enum dma_ch channel,
+ enum s3c2410_dmasrc source, unsigned long devaddr);
+
+/* s3c2410_dma_getposition
+ *
+ * get the position that the dma transfer is currently at
+*/
+
+extern int s3c2410_dma_getposition(enum dma_ch channel,
+ dma_addr_t *src, dma_addr_t *dest);
+
+extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
+extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn);
+
+
diff --git a/arch/arm/plat-samsung/include/plat/fb-core.h b/arch/arm/plat-samsung/include/plat/fb-core.h
new file mode 100644
index 00000000..bca383ef
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb-core.h
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/plat-samsung/include/plat/fb-core.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * Pawel Osciak <p.osciak@samsung.com>
+ *
+ * Samsung framebuffer 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 __ASM_PLAT_FB_CORE_H
+#define __ASM_PLAT_FB_CORE_H __FILE__
+
+/*
+ * These functions 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_fb_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_FB
+ s3c_device_fb.name = name;
+#endif
+}
+
+#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
new file mode 100644
index 00000000..cb3ca3ad
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fb.h
@@ -0,0 +1,97 @@
+/* arch/arm/plat-samsung/include/plat/fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - FB 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_FB_H
+#define __PLAT_S3C_FB_H __FILE__
+
+/* 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
+ * set to the maximum of any version of the hardware can do is safe.
+ */
+#define S3C_FB_MAX_WIN (5)
+
+/**
+ * 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.
+ */
+struct s3c_fb_pd_win {
+ struct fb_videomode win_mode;
+
+ unsigned short default_bpp;
+ unsigned short max_bpp;
+ unsigned short virtual_x;
+ unsigned short virtual_y;
+};
+
+/**
+ * struct s3c_fb_platdata - S3C driver platform specific information
+ * @setup_gpio: Setup the external GPIO pins to the right state to transfer
+ * the data from the display system to the connected display
+ * device.
+ * @default_win: default window layer number to be used for UI layer.
+ * @vidcon0: The base vidcon0 values to control the panel data format.
+ * @vidcon1: The base vidcon1 values to control the panel data output.
+ * @win: The setup data for each hardware window, or NULL for unused.
+ * @display_mode: The LCD output display mode.
+ *
+ * The platform data supplies the video driver with all the information
+ * it requires to work with the display(s) attached to the machine. It
+ * controls the initial mode, the number of display windows (0 is always
+ * the base framebuffer) that are initialised etc.
+ *
+ */
+struct s3c_fb_platdata {
+ void (*setup_gpio)(void);
+
+ struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN];
+
+ u32 default_win;
+
+ u32 vidcon0;
+ u32 vidcon1;
+};
+
+/**
+ * s3c_fb_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 s3c_fb_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.
+ */
+extern void s3c64xx_fb_gpio_setup_24bpp(void);
+
+/**
+ * s5pc100_fb_gpio_setup_24bpp() - S5PC100 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pc100_fb_gpio_setup_24bpp(void);
+
+/**
+ * s5pv210_fb_gpio_setup_24bpp() - S5PV210/S5PC110 setup function for 24bpp LCD
+ *
+ * Initialise the GPIO for an 24bpp LCD display on the RGB interface.
+ */
+extern void s5pv210_fb_gpio_setup_24bpp(void);
+
+#endif /* __PLAT_S3C_FB_H */
diff --git a/arch/arm/plat-samsung/include/plat/fimc-core.h b/arch/arm/plat-samsung/include/plat/fimc-core.h
new file mode 100644
index 00000000..945a99d5
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/fimc-core.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/plat-samsung/include/plat/fimc-core.h
+ *
+ * Copyright 2010 Samsung Electronics Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * Samsung camera interface 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 __ASM_PLAT_FIMC_CORE_H
+#define __ASM_PLAT_FIMC_CORE_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 s3c_fimc_setname(int id, char *name)
+{
+ switch (id) {
+#ifdef CONFIG_S5P_DEV_FIMC0
+ case 0:
+ s5p_device_fimc0.name = name;
+ break;
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC1
+ case 1:
+ s5p_device_fimc1.name = name;
+ break;
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC2
+ case 2:
+ s5p_device_fimc2.name = name;
+ break;
+#endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+ case 3:
+ s5p_device_fimc3.name = name;
+ break;
+#endif
+ }
+}
+
+#endif /* __ASM_PLAT_FIMC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
new file mode 100644
index 00000000..3ad83865
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -0,0 +1,251 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg-helper.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin configuration 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.
+*/
+
+/* This is meant for core cpu support, machine or other driver files
+ * should not be including this header.
+ */
+
+#ifndef __PLAT_GPIO_CFG_HELPERS_H
+#define __PLAT_GPIO_CFG_HELPERS_H __FILE__
+
+/* As a note, all gpio configuration functions are entered exclusively, either
+ * with the relevant lock held or the system prevented from doing anything else
+ * by disabling interrupts.
+*/
+
+static inline int s3c_gpio_do_setcfg(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int config)
+{
+ return (chip->config->set_config)(chip, off, config);
+}
+
+static inline unsigned s3c_gpio_do_getcfg(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return (chip->config->get_config)(chip, off);
+}
+
+static inline int s3c_gpio_do_setpull(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ return (chip->config->set_pull)(chip, off, pull);
+}
+
+static inline s3c_gpio_pull_t s3c_gpio_do_getpull(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ return chip->config->get_pull(chip, off);
+}
+
+/**
+ * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has two bits of configuration per gpio, which have the following
+ * functions:
+ * 00 = input
+ * 01 = output
+ * 1x = special function
+*/
+extern int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+/**
+ * s3c_gpio_getcfg_s3c24xx - S3C24XX style GPIO configuration read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx(). Will return a value whicg
+ * could be directly passed back to s3c_gpio_setcfg_s3c24xx(), from the
+ * S3C_GPIO_SPECIAL() macro.
+ */
+unsigned int s3c_gpio_getcfg_s3c24xx(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_setcfg_s3c24xx_a - S3C24XX style GPIO configuration (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register
+ * has one bit of configuration for the gpio, where setting the bit
+ * means the pin is in special function mode and unset means output.
+*/
+extern int s3c_gpio_setcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+
+/**
+ * s3c_gpio_getcfg_s3c24xx_a - S3C24XX style GPIO configuration read (Bank A)
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c24xx_a() turning an GPIO into a usable
+ * GPIO configuration value.
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ * @sa s3c_gpio_getcfg_s3c64xx_4bit
+ */
+extern unsigned s3c_gpio_getcfg_s3c24xx_a(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @cfg: The configuration value to set.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of functions for
+ * each case.
+*/
+extern int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off, unsigned int cfg);
+
+
+/**
+ * s3c_gpio_getcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config read.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ *
+ * The reverse of s3c_gpio_setcfg_s3c64xx_4bit(), turning a gpio configuration
+ * register setting into a value the software can use, such as could be passed
+ * to s3c_gpio_setcfg_s3c64xx_4bit().
+ *
+ * @sa s3c_gpio_getcfg_s3c24xx
+ */
+extern unsigned s3c_gpio_getcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/* Pull-{up,down} resistor controls.
+ *
+ * S3C2410,S3C2440,S3C24A0 = Pull-UP,
+ * S3C2412,S3C2413 = Pull-Down
+ * S3C6400,S3C6410 = Pull-Both [None,Down,Up,Undef]
+ * S3C2443 = Pull-Both [not same as S3C6400]
+ */
+
+/**
+ * s3c_gpio_setpull_1up() - Pull configuration for choice of up or none.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-up resistor.
+ */
+extern int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_1down() - Pull configuration for choice of down or none
+ * @chip: The gpio chip that is being configured
+ * @off: The offset for the GPIO being configured
+ * @param: pull: The pull mode being requested
+ *
+ * This is a helper function for the case where we have GPIOs with one
+ * bit configuring the presence of a pull-down resistor.
+ */
+extern int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_setpull_upown() - Pull configuration for choice of up, down or none
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ * 00 = No pull resistor connected
+ * 01 = Pull-up resistor connected
+ * 10 = Pull-down resistor connected
+ */
+extern int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+
+/**
+ * s3c_gpio_getpull_updown() - Get configuration for choice of up, down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_getpull_1up() - Get configuration for choice of up or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-up resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1up.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_getpull_1down() - Get configuration for choice of down or none
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-down resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_1down.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+/**
+ * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a helper function for the case where we have GPIOs with two
+ * bits configuring the presence of a pull resistor, in the following
+ * order:
+ * 00 = Pull-up resistor connected
+ * 10 = Pull-down resistor connected
+ * x1 = No pull up resistor
+ */
+extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull_s3c2443() - Get configuration for s3c2443 pull resistors
+ * @chip: The gpio chip that the GPIO pin belongs to.
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This helper function reads the state of the pull-{up,down} resistor for the
+ * given GPIO in the same case as s3c_gpio_setpull_upown.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
+#endif /* __PLAT_GPIO_CFG_HELPERS_H */
+
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
new file mode 100644
index 00000000..1762dcb4
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h
@@ -0,0 +1,244 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO pin 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.
+*/
+
+/* This file contains the necessary definitions to get the basic gpio
+ * pin configuration done such as setting a pin to input or output or
+ * changing the pull-{up,down} configurations.
+ */
+
+/* Note, this interface is being added to the s3c64xx arch first and will
+ * be added to the s3c24xx systems later.
+ */
+
+#ifndef __PLAT_GPIO_CFG_H
+#define __PLAT_GPIO_CFG_H __FILE__
+
+typedef unsigned int __bitwise__ s3c_gpio_pull_t;
+typedef unsigned int __bitwise__ s5p_gpio_drvstr_t;
+
+/* forward declaration if gpio-core.h hasn't been included */
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_cfg GPIO configuration
+ * @cfg_eint: Configuration setting when used for external interrupt source
+ * @get_pull: Read the current pull configuration for the GPIO
+ * @set_pull: Set the current pull configuraiton for the GPIO
+ * @set_config: Set the current configuration for the GPIO
+ * @get_config: Read the current configuration for the GPIO
+ *
+ * Each chip can have more than one type of GPIO bank available and some
+ * have different capabilites even when they have the same control register
+ * layouts. Provide an point to vector control routine and provide any
+ * per-bank configuration information that other systems such as the
+ * external interrupt code will need.
+ *
+ * @sa s3c_gpio_cfgpin
+ * @sa s3c_gpio_getcfg
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_getpull
+ */
+struct s3c_gpio_cfg {
+ unsigned int cfg_eint;
+
+ s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);
+ int (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,
+ s3c_gpio_pull_t pull);
+
+ unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);
+ int (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,
+ unsigned config);
+};
+
+#define S3C_GPIO_SPECIAL_MARK (0xfffffff0)
+#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))
+
+/* Defines for generic pin configurations */
+#define S3C_GPIO_INPUT (S3C_GPIO_SPECIAL(0))
+#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))
+#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))
+
+#define s3c_gpio_is_cfg_special(_cfg) \
+ (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)
+
+/**
+ * s3c_gpio_cfgpin() - Change the GPIO function of a pin.
+ * @pin pin The pin number to configure.
+ * @to to The configuration for the pin's function.
+ *
+ * Configure which function is actually connected to the external
+ * pin, such as an gpio input, output or some form of special function
+ * connected to an internal peripheral block.
+ *
+ * The @to parameter can be one of the generic S3C_GPIO_INPUT, S3C_GPIO_OUTPUT
+ * or S3C_GPIO_SFN() to indicate one of the possible values that the helper
+ * will then generate the correct bit mask and shift for the configuration.
+ *
+ * If a bank of GPIOs all needs to be set to special-function 2, then
+ * the following code will work:
+ *
+ * for (gpio = start; gpio < end; gpio++)
+ * s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ *
+ * The @to parameter can also be a specific value already shifted to the
+ * correct position in the control register, although these are discouraged
+ * in newer kernels and are only being kept for compatibility.
+ */
+extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);
+
+/**
+ * s3c_gpio_getcfg - Read the current function for a GPIO pin
+ * @pin: The pin to read the configuration value for.
+ *
+ * Read the configuration state of the given @pin, returning a value that
+ * could be passed back to s3c_gpio_cfgpin().
+ *
+ * @sa s3c_gpio_cfgpin
+ */
+extern unsigned s3c_gpio_getcfg(unsigned int pin);
+
+/**
+ * s3c_gpio_cfgpin_range() - Change the GPIO function for configuring pin range
+ * @start: The pin number to start at
+ * @nr: The number of pins to configure from @start.
+ * @cfg: The configuration for the pin's function
+ *
+ * Call s3c_gpio_cfgpin() for the @nr pins starting at @start.
+ *
+ * @sa s3c_gpio_cfgpin.
+ */
+extern int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
+ unsigned int cfg);
+
+/* Define values for the pull-{up,down} available for each gpio pin.
+ *
+ * These values control the state of the weak pull-{up,down} resistors
+ * 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
+ * used to whether the particular mode is available.
+ */
+#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)
+
+/**
+ * s3c_gpio_setpull() - set the state of a gpio pin pull resistor
+ * @pin: The pin number to configure the pull resistor.
+ * @pull: The configuration for the pull resistor.
+ *
+ * This function sets the state 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.
+ *
+ * @pull is one of S3C_GPIO_PULL_NONE, S3C_GPIO_PULL_DOWN or S3C_GPIO_PULL_UP.
+*/
+extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull() - get the pull resistor state of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the pull resistor value for the specified pin.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
+
+/* configure `all` aspects of an gpio */
+
+/**
+ * s3c_gpio_cfgall_range() - configure range of gpio functtion and pull.
+ * @start: The gpio number to start at.
+ * @nr: The number of gpio to configure from @start.
+ * @cfg: The configuration to use
+ * @pull: The pull setting to use.
+ *
+ * Run s3c_gpio_cfgpin() and s3c_gpio_setpull() over the gpio range starting
+ * @gpio and running for @size.
+ *
+ * @sa s3c_gpio_cfgpin
+ * @sa s3c_gpio_setpull
+ * @sa s3c_gpio_cfgpin_range
+ */
+extern int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
+ unsigned int cfg, s3c_gpio_pull_t pull);
+
+static inline int s3c_gpio_cfgrange_nopull(unsigned int pin, unsigned int size,
+ unsigned int cfg)
+{
+ return s3c_gpio_cfgall_range(pin, size, cfg, S3C_GPIO_PULL_NONE);
+}
+
+/* Define values for the drvstr available for each gpio pin.
+ *
+ * These values control the value of the output signal driver strength,
+ * configurable on most pins on the S5P series.
+ */
+#define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x0)
+#define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x2)
+#define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x1)
+#define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x3)
+
+/**
+ * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin
+ * @pin: The pin number to get the settings for
+ *
+ * Read the driver streght value for the specified pin.
+*/
+extern s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin);
+
+/**
+ * s3c_gpio_set_drvstr() - set the driver streght value of a gpio pin
+ * @pin: The pin number to configure the driver streght value
+ * @drvstr: The new value of the driver strength
+ *
+ * This function sets the driver strength value for the specified pin.
+ * It will return 0 if successful, or a negative error code if the pin
+ * cannot support the requested setting.
+*/
+extern int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr);
+
+/**
+ * s5p_register_gpio_interrupt() - register interrupt support for a gpio group
+ * @pin: The pin number from the group to be registered
+ *
+ * This function registers gpio interrupt support for the group that the
+ * specified pin belongs to.
+ *
+ * The total number of gpio pins is quite large ob s5p series. Registering
+ * irq support for all of them would be a resource waste. Because of that the
+ * interrupt support for standard gpio pins is registered dynamically.
+ *
+ * It will return the irq number of the interrupt that has been registered
+ * or -ENOMEM if no more gpio interrupts can be registered. It is allowed
+ * to call this function more than once for the same gpio group (the group
+ * will be registered only once).
+ */
+extern int s5p_register_gpio_interrupt(int pin);
+
+/** s5p_register_gpioint_bank() - add gpio bank for further gpio interrupt
+ * registration (see s5p_register_gpio_interrupt function)
+ * @chain_irq: chained irq number for the gpio int handler for this bank
+ * @start: start gpio group number of this bank
+ * @nr_groups: number of gpio groups handled by this bank
+ *
+ * This functions registers initial information about gpio banks that
+ * can be later used by the s5p_register_gpio_interrupt() function to
+ * enable support for gpio interrupt for particular gpio group.
+ */
+#ifdef CONFIG_S5P_GPIO_INT
+extern int s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups);
+#else
+#define s5p_register_gpioint_bank(chain_irq, start, nr_groups) do { } while (0)
+#endif
+
+#endif /* __PLAT_GPIO_CFG_H */
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
new file mode 100644
index 00000000..8cad4cf1
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -0,0 +1,171 @@
+/* linux/arch/arm/plat-s3c/include/plat/gpio-core.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - GPIO core
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#define GPIOCON_OFF (0x00)
+#define GPIODAT_OFF (0x04)
+
+#define con_4bit_shift(__off) ((__off) * 4)
+
+/* Define the core gpiolib support functions that the s3c platforms may
+ * need to extend or change depending on the hardware and the s3c chip
+ * selected at build or found at run time.
+ *
+ * These definitions are not intended for driver inclusion, there is
+ * nothing here that should not live outside the platform and core
+ * specific code.
+*/
+
+struct s3c_gpio_chip;
+
+/**
+ * struct s3c_gpio_pm - power management (suspend/resume) information
+ * @save: Routine to save the state of the GPIO block
+ * @resume: Routine to resume the GPIO block.
+ */
+struct s3c_gpio_pm {
+ void (*save)(struct s3c_gpio_chip *chip);
+ void (*resume)(struct s3c_gpio_chip *chip);
+};
+
+struct s3c_gpio_cfg;
+
+/**
+ * struct s3c_gpio_chip - wrapper for specific implementation of gpio
+ * @chip: The chip structure to be exported via gpiolib.
+ * @base: The base pointer to the gpio configuration registers.
+ * @group: The group register number for gpio interrupt support.
+ * @irq_base: The base irq number.
+ * @config: special function and pull-resistor control information.
+ * @lock: Lock for exclusive access to this gpio bank.
+ * @pm_save: Save information for suspend/resume support.
+ *
+ * This wrapper provides the necessary information for the Samsung
+ * specific gpios being registered with gpiolib.
+ *
+ * The lock protects each gpio bank from multiple access of the shared
+ * configuration registers, or from reading of data whilst another thread
+ * is writing to the register set.
+ *
+ * Each chip has its own lock to avoid any contention between different
+ * CPU cores trying to get one lock for different GPIO banks, where each
+ * bank of GPIO has its own register space and configuration registers.
+ */
+struct s3c_gpio_chip {
+ struct gpio_chip chip;
+ struct s3c_gpio_cfg *config;
+ struct s3c_gpio_pm *pm;
+ void __iomem *base;
+ int irq_base;
+ int group;
+ spinlock_t lock;
+#ifdef CONFIG_PM
+ u32 pm_save[4];
+#endif
+};
+
+static inline struct s3c_gpio_chip *to_s3c_gpio(struct gpio_chip *gpc)
+{
+ return container_of(gpc, struct s3c_gpio_chip, chip);
+}
+
+/** s3c_gpiolib_add() - add the s3c specific version of a gpio_chip.
+ * @chip: The chip to register
+ *
+ * This is a wrapper to gpiochip_add() that takes our specific gpio chip
+ * information and makes the necessary alterations for the platform and
+ * notes the information for use with the configuration systems and any
+ * other parts of the system.
+ */
+extern void s3c_gpiolib_add(struct s3c_gpio_chip *chip);
+
+/* CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
+ * for use with the configuration calls, and other parts of the s3c gpiolib
+ * support code.
+ *
+ * Not all s3c support code will need this, as some configurations of cpu
+ * may only support one or two different configuration options and have an
+ * easy gpio to s3c_gpio_chip mapping function. If this is the case, then
+ * the machine support file should provide its own s3c_gpiolib_getchip()
+ * and any other necessary functions.
+ */
+
+/**
+ * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
+ * @chip: The gpio chip that is being configured.
+ * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
+ *
+ * This helper deal with the GPIO cases where the control register has 4 bits
+ * of control per GPIO, generally in the form of:
+ * 0000 = Input
+ * 0001 = Output
+ * others = Special functions (dependent on bank)
+ *
+ * Note, since the code to deal with the case where there are two control
+ * registers instead of one, we do not have a separate set of function
+ * (samsung_gpiolib_add_4bit2_chips)for each case.
+ */
+extern void samsung_gpiolib_add_4bit_chips(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,
+ int nr_chips);
+
+extern void samsung_gpiolib_add_4bit(struct s3c_gpio_chip *chip);
+extern void samsung_gpiolib_add_4bit2(struct s3c_gpio_chip *chip);
+
+
+/**
+ * samsung_gpiolib_to_irq - convert gpio pin to irq number
+ * @chip: The gpio chip that the pin belongs to.
+ * @offset: The offset of the pin in the chip.
+ *
+ * This helper returns the irq number calculated from the chip->irq_base and
+ * the provided offset.
+ */
+extern int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset);
+
+/* exported for core SoC support to change */
+extern struct s3c_gpio_cfg s3c24xx_gpiocfg_default;
+
+#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)
+{
+ return (chip < S3C_GPIO_END) ? s3c_gpios[chip] : NULL;
+}
+#else
+/* machine specific code should provide s3c_gpiolib_getchip */
+
+#include <mach/gpio-track.h>
+
+static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
+#endif
+
+#ifdef CONFIG_PM
+extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
+extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
+#define __gpio_pm(x) x
+#else
+#define s3c_gpio_pm_1bit NULL
+#define s3c_gpio_pm_2bit NULL
+#define s3c_gpio_pm_4bit NULL
+#define __gpio_pm(x) NULL
+
+#endif /* CONFIG_PM */
+
+/* locking wrappers to deal with multiple access to the same gpio bank */
+#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
+#define s3c_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl)
diff --git a/arch/arm/plat-samsung/include/plat/hwmon.h b/arch/arm/plat-samsung/include/plat/hwmon.h
new file mode 100644
index 00000000..c167e442
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/hwmon.h
@@ -0,0 +1,51 @@
+/* linux/arch/arm/plat-s3c/include/plat/hwmon.h
+ *
+ * Copyright 2005 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C - HWMon interface for ADC
+ *
+ * This program is free software; you can 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_ADC_HWMON_H
+#define __ASM_ARCH_ADC_HWMON_H __FILE__
+
+/**
+ * s3c_hwmon_chcfg - channel configuration
+ * @name: The name to give this channel.
+ * @mult: Multiply the ADC value read by this.
+ * @div: Divide the value from the ADC by this.
+ *
+ * The value read from the ADC is converted to a value that
+ * hwmon expects (mV) by result = (value_read * @mult) / @div.
+ */
+struct s3c_hwmon_chcfg {
+ const char *name;
+ unsigned int mult;
+ unsigned int div;
+};
+
+/**
+ * s3c_hwmon_pdata - HWMON platform data
+ * @in: One configuration for each possible channel used.
+ */
+struct s3c_hwmon_pdata {
+ struct s3c_hwmon_chcfg *in[8];
+};
+
+/**
+ * s3c_hwmon_set_platdata - Set platform data for S3C HWMON device
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use with the S3C HWMON device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void __init s3c_hwmon_set_platdata(struct s3c_hwmon_pdata *pd);
+
+#endif /* __ASM_ARCH_ADC_HWMON_H */
+
diff --git a/arch/arm/plat-samsung/include/plat/iic-core.h b/arch/arm/plat-samsung/include/plat/iic-core.h
new file mode 100644
index 00000000..f182669b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/iic-core.h
@@ -0,0 +1,42 @@
+/* arch/arm/mach-s3c2410/include/mach/iic-core.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - I2C Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_IIC_CORE_H
+#define __ASM_ARCH_IIC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_i2c0_setname(char *name)
+{
+ /* currently this device is always compiled in */
+ s3c_device_i2c0.name = name;
+}
+
+static inline void s3c_i2c1_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_I2C1
+ s3c_device_i2c1.name = name;
+#endif
+}
+
+static inline void s3c_i2c2_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_I2C2
+ s3c_device_i2c2.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/iic.h b/arch/arm/plat-samsung/include/plat/iic.h
new file mode 100644
index 00000000..1543da8f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/iic.h
@@ -0,0 +1,74 @@
+/* arch/arm/plat-s3c/include/plat/iic.h
+ *
+ * Copyright 2004-2009 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - I2C Controller platform_device info
+ *
+ * This program is free software; you can 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_IIC_H
+#define __ASM_ARCH_IIC_H __FILE__
+
+#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */
+
+/**
+ * struct s3c2410_platform_i2c - Platform data for s3c I2C.
+ * @bus_num: The bus number to use (if possible).
+ * @flags: Any flags for the I2C bus (E.g. S3C_IICFLK_FILTER).
+ * @slave_addr: The I2C address for the slave device (if enabled).
+ * @frequency: The desired frequency in Hz of the bus. This is
+ * guaranteed to not be exceeded. If the caller does
+ * not care, use zero and the driver will select a
+ * useful default.
+ * @sda_delay: The delay (in ns) applied to SDA edges.
+ * @cfg_gpio: A callback to configure the pins for I2C operation.
+ */
+struct s3c2410_platform_i2c {
+ int bus_num;
+ unsigned int flags;
+ unsigned int slave_addr;
+ unsigned long frequency;
+ unsigned int sda_delay;
+
+ void (*cfg_gpio)(struct platform_device *dev);
+};
+
+/**
+ * s3c_i2c0_set_platdata - set platform data for i2c0 device
+ * @i2c: The platform data to set, or NULL for default data.
+ *
+ * Register the given platform data for use with the i2c0 device. This
+ * call copies the platform data, so the caller can use __initdata for
+ * their copy.
+ *
+ * This call will set cfg_gpio if is null to the default platform
+ * implementation.
+ *
+ * Any user of s3c_device_i2c0 should call this, even if it is with
+ * NULL to ensure that the device is given the default platform data
+ * as the driver will no longer carry defaults.
+ */
+extern void s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c2_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c3_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c4_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c5_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c6_set_platdata(struct s3c2410_platform_i2c *i2c);
+extern void s3c_i2c7_set_platdata(struct s3c2410_platform_i2c *i2c);
+
+/* defined by architecture to configure gpio */
+extern void s3c_i2c0_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c1_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c2_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c3_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c4_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c5_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c6_cfg_gpio(struct platform_device *dev);
+extern void s3c_i2c7_cfg_gpio(struct platform_device *dev);
+
+#endif /* __ASM_ARCH_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/irq-uart.h b/arch/arm/plat-samsung/include/plat/irq-uart.h
new file mode 100644
index 00000000..a9331e49
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/irq-uart.h
@@ -0,0 +1,20 @@
+/* arch/arm/plat-samsung/include/plat/irq-uart.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC UART IRQ demux for S3C64XX and later
+ *
+ * This program is free software; you can 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 s3c_uart_irq {
+ void __iomem *regs;
+ unsigned int base_irq;
+ unsigned int parent_irq;
+};
+
+extern void s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs);
+
diff --git a/arch/arm/plat-samsung/include/plat/irq-vic-timer.h b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
new file mode 100644
index 00000000..5b9c42fd
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
@@ -0,0 +1,13 @@
+/* arch/arm/plat-samsung/include/plat/irq-vic-timer.h
+ *
+ * Copyright (c) 2010 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * Header file for Samsung SoC IRQ VIC timer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
diff --git a/arch/arm/plat-samsung/include/plat/keypad-core.h b/arch/arm/plat-samsung/include/plat/keypad-core.h
new file mode 100644
index 00000000..d513e1b3
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/keypad-core.h
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/plat-samsung/include/plat/keypad-core.h
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * Samsung keypad controller core function
+ *
+ * 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_KEYPAD_CORE_H
+#define __ASM_ARCH_KEYPAD_CORE_H
+
+/* These function 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 samsung_keypad_setname(char *name)
+{
+#ifdef CONFIG_SAMSUNG_DEV_KEYPAD
+ samsung_device_keypad.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_KEYPAD_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/keypad.h b/arch/arm/plat-samsung/include/plat/keypad.h
new file mode 100644
index 00000000..b59a6483
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/keypad.h
@@ -0,0 +1,56 @@
+/*
+ * Samsung Platform - Keypad platform data definitions
+ *
+ * Copyright (C) 2010 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_SAMSUNG_KEYPAD_H
+#define __PLAT_SAMSUNG_KEYPAD_H
+
+#include <linux/input/matrix_keypad.h>
+
+#define SAMSUNG_MAX_ROWS 8
+#define SAMSUNG_MAX_COLS 8
+
+/**
+ * struct samsung_keypad_platdata - Platform device data for Samsung Keypad.
+ * @keymap_data: pointer to &matrix_keymap_data.
+ * @rows: number of keypad row supported.
+ * @cols: number of keypad col supported.
+ * @no_autorepeat: disable key autorepeat.
+ * @wakeup: controls whether the device should be set up as wakeup source.
+ * @cfg_gpio: configure the GPIO.
+ *
+ * Initialisation data specific to either the machine or the platform
+ * for the device driver to use or call-back when configuring gpio.
+ */
+struct samsung_keypad_platdata {
+ const struct matrix_keymap_data *keymap_data;
+ unsigned int rows;
+ unsigned int cols;
+ bool no_autorepeat;
+ bool wakeup;
+
+ void (*cfg_gpio)(unsigned int rows, unsigned int cols);
+};
+
+/**
+ * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use with Samsung Keypad device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd);
+
+/* defined by architecture to configure gpio. */
+extern void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols);
+
+#endif /* __PLAT_SAMSUNG_KEYPAD_H */
diff --git a/arch/arm/plat-samsung/include/plat/map-base.h b/arch/arm/plat-samsung/include/plat/map-base.h
new file mode 100644
index 00000000..3ffac4d2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/map-base.h
@@ -0,0 +1,46 @@
+/* linux/include/asm-arm/plat-s3c/map.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - Memory map definitions (virtual addresses)
+ *
+ * This program is free software; you can 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_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.
+ *
+ * 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
+
+#ifndef __ASSEMBLY__
+#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE + (x))
+#else
+#define S3C_ADDR(x) (S3C_ADDR_BASE + (x))
+#endif
+
+#define S3C_VA_IRQ S3C_ADDR(0x00000000) /* irq controller(s) */
+#define S3C_VA_SYS S3C_ADDR(0x00100000) /* system control */
+#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_UART S3C_ADDR(0x01000000) /* UART */
+
+/* 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.
+ */
+#define S3C_ADDR_CPU(x) S3C_ADDR(0x00500000 + (x))
+
+#endif /* __ASM_PLAT_MAP_H */
diff --git a/arch/arm/plat-samsung/include/plat/nand-core.h b/arch/arm/plat-samsung/include/plat/nand-core.h
new file mode 100644
index 00000000..6de20789
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand-core.h
@@ -0,0 +1,28 @@
+/* arch/arm/plat-samsung/include/plat/nand-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C - Nand Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_NAND_CORE_H
+#define __ASM_ARCH_NAND_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_nand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_NAND
+ s3c_device_nand.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_NAND_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/nand.h b/arch/arm/plat-samsung/include/plat/nand.h
new file mode 100644
index 00000000..b64115fa
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/nand.h
@@ -0,0 +1,67 @@
+/* arch/arm/mach-s3c2410/include/mach/nand.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - NAND device controller platform_device info
+ *
+ * This program is free software; you can 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 s3c2410_nand_set - define a set of one or more nand chips
+ * @disable_ecc: Entirely disable ECC - Dangerous
+ * @flash_bbt: Openmoko u-boot can create a Bad Block Table
+ * Setting this flag will allow the kernel to
+ * look for it at boot time and also skip the NAND
+ * scan.
+ * @options: Default value to set into 'struct nand_chip' options.
+ * @nr_chips: Number of chips in this set
+ * @nr_partitions: Number of partitions pointed to by @partitions
+ * @name: Name of set (optional)
+ * @nr_map: Map for low-layer logical to physical chip numbers (option)
+ * @partitions: The mtd partition list
+ *
+ * define a set of one or more nand chips registered with an unique mtd. Also
+ * allows to pass flag to the underlying NAND layer. 'disable_ecc' will trigger
+ * a warning at boot time.
+ */
+struct s3c2410_nand_set {
+ unsigned int disable_ecc:1;
+ unsigned int flash_bbt:1;
+
+ unsigned int options;
+ int nr_chips;
+ int nr_partitions;
+ char *name;
+ int *nr_map;
+ struct mtd_partition *partitions;
+ struct nand_ecclayout *ecc_layout;
+};
+
+struct s3c2410_platform_nand {
+ /* timing information for controller, all times in nanoseconds */
+
+ int tacls; /* time for active CLE/ALE to nWE/nOE */
+ int twrph0; /* active time for nWE/nOE */
+ int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */
+
+ unsigned int ignore_unset_ecc:1;
+
+ int nr_sets;
+ struct s3c2410_nand_set *sets;
+
+ void (*select_chip)(struct s3c2410_nand_set *,
+ int chip);
+};
+
+/**
+ * s3c_nand_set_platdata() - register NAND platform data.
+ * @nand: The NAND platform data to register with s3c_device_nand.
+ *
+ * This function copies the given NAND platform data, @nand and registers
+ * it with the s3c_device_nand. This allows @nand to be __initdata.
+*/
+extern void s3c_nand_set_platdata(struct s3c2410_platform_nand *nand);
diff --git a/arch/arm/plat-samsung/include/plat/onenand-core.h b/arch/arm/plat-samsung/include/plat/onenand-core.h
new file mode 100644
index 00000000..7701cb70
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/onenand-core.h
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/plat-samsung/onenand-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Samsung OneNAD Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_ONENAND_CORE_H
+#define __ASM_ARCH_ONENAND_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_onenand_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_ONENAND
+ s3c_device_onenand.name = name;
+#endif
+}
+
+static inline void s3c64xx_onenand1_setname(char *name)
+{
+#ifdef CONFIG_S3C64XX_DEV_ONENAND1
+ s3c64xx_device_onenand1.name = name;
+#endif
+}
+
+#endif /* __ASM_ARCH_ONENAND_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h
new file mode 100644
index 00000000..abb4bc32
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pd.h
@@ -0,0 +1,30 @@
+/* linux/arch/arm/plat-samsung/include/plat/pd.h
+ *
+ * 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.
+*/
+
+#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 {
+ PD_MFC,
+ PD_G3D,
+ PD_LCD0,
+ PD_LCD1,
+ PD_TV,
+ PD_CAM,
+ PD_GPS
+};
+
+#endif /* __ASM_PLAT_SAMSUNG_PD_H */
diff --git a/arch/arm/plat-samsung/include/plat/pll6553x.h b/arch/arm/plat-samsung/include/plat/pll6553x.h
new file mode 100644
index 00000000..b8b7e1d8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pll6553x.h
@@ -0,0 +1,51 @@
+/* arch/arm/plat-samsung/include/plat/pll6553x.h
+ * partially from arch/arm/mach-s3c64xx/include/mach/pll.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung PLL6553x PLL code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* S3C6400 and compatible (S3C2416, etc.) EPLL code */
+
+#define PLL6553X_MDIV_MASK ((1 << (23-16)) - 1)
+#define PLL6553X_PDIV_MASK ((1 << (13-8)) - 1)
+#define PLL6553X_SDIV_MASK ((1 << (2-0)) - 1)
+#define PLL6553X_MDIV_SHIFT (16)
+#define PLL6553X_PDIV_SHIFT (8)
+#define PLL6553X_SDIV_SHIFT (0)
+#define PLL6553X_KDIV_MASK (0xffff)
+
+static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
+ u32 pll0, u32 pll1)
+{
+ unsigned long result;
+ u32 mdiv, pdiv, sdiv, kdiv;
+ u64 tmp;
+
+ mdiv = (pll0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+ pdiv = (pll0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+ sdiv = (pll0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+ kdiv = pll1 & PLL6553X_KDIV_MASK;
+
+ /* We need to multiple baseclk by mdiv (the integer part) and kdiv
+ * which is in 2^16ths, so shift mdiv up (does not overflow) and
+ * add kdiv before multiplying. The use of tmp is to avoid any
+ * overflows before shifting bac down into result when multipling
+ * by the mdiv and kdiv pair.
+ */
+
+ tmp = baseclk;
+ tmp *= (mdiv << 16) + kdiv;
+ do_div(tmp, (pdiv << sdiv));
+ result = tmp >> 16;
+
+ return result;
+}
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
new file mode 100644
index 00000000..7fb6f6be
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -0,0 +1,185 @@
+/* arch/arm/plat-samsung/include/plat/pm.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Written by 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.
+*/
+
+/* s3c_pm_init
+ *
+ * called from board at initialisation time to setup the power
+ * management
+*/
+
+#include <linux/irq.h>
+
+struct sys_device;
+
+#ifdef CONFIG_PM
+
+extern __init int s3c_pm_init(void);
+
+#else
+
+static inline int s3c_pm_init(void)
+{
+ return 0;
+}
+#endif
+
+/* configuration for the IRQ mask over sleep */
+extern unsigned long s3c_irqwake_intmask;
+extern unsigned long s3c_irqwake_eintmask;
+
+/* IRQ masks for IRQs allowed to go to sleep (see irq.c) */
+extern unsigned long s3c_irqwake_intallow;
+extern unsigned long s3c_irqwake_eintallow;
+
+/* per-cpu sleep functions */
+
+extern void (*pm_cpu_prep)(void);
+extern void (*pm_cpu_sleep)(void);
+
+/* Flags for PM Control */
+
+extern unsigned long s3c_pm_flags;
+
+extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */
+
+/* from sleep.S */
+
+extern int s3c_cpu_save(unsigned long *saveblk, long);
+extern void s3c_cpu_resume(void);
+
+extern void s3c2410_cpu_suspend(void);
+
+/* sleep save info */
+
+/**
+ * struct sleep_save - save information for shared peripherals.
+ * @reg: Pointer to the register to save.
+ * @val: Holder for the value saved from reg.
+ *
+ * This describes a list of registers which is used by the pm core and
+ * other subsystem to save and restore register values over suspend.
+ */
+struct sleep_save {
+ void __iomem *reg;
+ unsigned long val;
+};
+
+#define SAVE_ITEM(x) \
+ { .reg = (x) }
+
+/**
+ * struct pm_uart_save - save block for core UART
+ * @ulcon: Save value for S3C2410_ULCON
+ * @ucon: Save value for S3C2410_UCON
+ * @ufcon: Save value for S3C2410_UFCON
+ * @umcon: Save value for S3C2410_UMCON
+ * @ubrdiv: Save value for S3C2410_UBRDIV
+ *
+ * Save block for UART registers to be held over sleep and restored if they
+ * are needed (say by debug).
+*/
+struct pm_uart_save {
+ u32 ulcon;
+ u32 ucon;
+ u32 ufcon;
+ u32 umcon;
+ u32 ubrdiv;
+ u32 udivslot;
+};
+
+/* helper functions to save/restore lists of registers. */
+
+extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
+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_irqext_wake(struct irq_data *data, unsigned int state);
+extern int s3c24xx_irq_suspend(void);
+extern void s3c24xx_irq_resume(void);
+#else
+#define s3c_irqext_wake NULL
+#define s3c24xx_irq_suspend NULL
+#define s3c24xx_irq_resume NULL
+#endif
+
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
+/* PM debug functions */
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+/**
+ * s3c_pm_dbg() - low level debug function for use in suspend/resume.
+ * @msg: The message to print.
+ *
+ * This function is used mainly to debug the resume process before the system
+ * can rely on printk/console output. It uses the low-level debugging output
+ * routine printascii() to do its work.
+ */
+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)
+#endif
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+/**
+ * s3c_pm_debug_smdkled() - Debug PM suspend/resume via SMDK Board LEDs
+ * @set: set bits for the state of the LEDs
+ * @clear: clear bits for the state of the LEDs.
+ */
+extern void s3c_pm_debug_smdkled(u32 set, u32 clear);
+
+#else
+static inline void s3c_pm_debug_smdkled(u32 set, u32 clear) { }
+#endif /* CONFIG_S3C_PM_DEBUG_LED_SMDK */
+
+/* suspend memory checking */
+
+#ifdef CONFIG_SAMSUNG_PM_CHECK
+extern void s3c_pm_check_prepare(void);
+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)
+#endif
+
+/**
+ * s3c_pm_configure_extint() - ensure pins are correctly set for IRQ
+ *
+ * Setup all the necessary GPIO pins for waking the system on external
+ * interrupt.
+ */
+extern void s3c_pm_configure_extint(void);
+
+/**
+ * s3c_pm_restore_gpios() - restore the state of the gpios after sleep.
+ *
+ * Restore the state of the GPIO pins after sleep, which may involve ensuring
+ * that we do not glitch the state of the pins from that the bootloader's
+ * resume code has done.
+*/
+extern void s3c_pm_restore_gpios(void);
+
+/**
+ * s3c_pm_save_gpios() - save the state of the GPIOs for restoring after sleep.
+ *
+ * Save the GPIO states for resotration on resume. See s3c_pm_restore_gpios().
+ */
+extern void s3c_pm_save_gpios(void);
+
+extern void s3c_pm_save_core(void);
+extern void s3c_pm_restore_core(void);
diff --git a/arch/arm/plat-samsung/include/plat/regs-ac97.h b/arch/arm/plat-samsung/include/plat/regs-ac97.h
new file mode 100644
index 00000000..c3878f7a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-ac97.h
@@ -0,0 +1,67 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h
+ *
+ * Copyright (c) 2006 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2440 AC97 Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_AC97_H
+#define __ASM_ARCH_REGS_AC97_H __FILE__
+
+#define S3C_AC97_GLBCTRL (0x00)
+
+#define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22)
+#define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21)
+#define S3C_AC97_GLBCTRL_PCMINORIE (1<<20)
+#define S3C_AC97_GLBCTRL_MICINORIE (1<<19)
+#define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18)
+#define S3C_AC97_GLBCTRL_PCMINTIE (1<<17)
+#define S3C_AC97_GLBCTRL_MICINTIE (1<<16)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12)
+#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12)
+#define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10)
+#define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10)
+#define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8)
+#define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8)
+#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3)
+#define S3C_AC97_GLBCTRL_ACLINKON (1<<2)
+#define S3C_AC97_GLBCTRL_WARMRESET (1<<1)
+#define S3C_AC97_GLBCTRL_COLDRESET (1<<0)
+
+#define S3C_AC97_GLBSTAT (0x04)
+
+#define S3C_AC97_GLBSTAT_CODECREADY (1<<22)
+#define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21)
+#define S3C_AC97_GLBSTAT_PCMINORI (1<<20)
+#define S3C_AC97_GLBSTAT_MICINORI (1<<19)
+#define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18)
+#define S3C_AC97_GLBSTAT_PCMINTI (1<<17)
+#define S3C_AC97_GLBSTAT_MICINTI (1<<16)
+#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0)
+#define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0)
+
+#define S3C_AC97_CODEC_CMD (0x08)
+
+#define S3C_AC97_CODEC_CMD_READ (1<<23)
+
+#define S3C_AC97_STAT (0x0c)
+#define S3C_AC97_PCM_ADDR (0x10)
+#define S3C_AC97_PCM_DATA (0x18)
+#define S3C_AC97_MIC_DATA (0x1C)
+
+#endif /* __ASM_ARCH_REGS_AC97_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-adc.h b/arch/arm/plat-samsung/include/plat/regs-adc.h
new file mode 100644
index 00000000..7554c4fc
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-adc.h
@@ -0,0 +1,64 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-adc.h
+ *
+ * Copyright (c) 2004 Shannon Holland <holland@loser.net>
+ *
+ * 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.
+ *
+ * S3C2410 ADC registers
+*/
+
+#ifndef __ASM_ARCH_REGS_ADC_H
+#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
+
+#define S3C2410_ADCREG(x) (x)
+
+#define S3C2410_ADCCON S3C2410_ADCREG(0x00)
+#define S3C2410_ADCTSC S3C2410_ADCREG(0x04)
+#define S3C2410_ADCDLY S3C2410_ADCREG(0x08)
+#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
+#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
+#define S3C64XX_ADCUPDN S3C2410_ADCREG(0x14)
+#define S3C64XX_ADCCLRINT S3C2410_ADCREG(0x18)
+#define S3C64XX_ADCCLRINTPNDNUP S3C2410_ADCREG(0x20)
+
+
+/* ADCCON Register Bits */
+#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 S3C2410_ADCCON_MUXMASK (0x7<<3)
+#define S3C2410_ADCCON_STDBM (1<<2)
+#define S3C2410_ADCCON_READ_START (1<<1)
+#define S3C2410_ADCCON_ENABLE_START (1<<0)
+#define S3C2410_ADCCON_STARTMASK (0x3<<0)
+
+
+/* ADCTSC Register Bits */
+#define S3C2410_ADCTSC_YM_SEN (1<<7)
+#define S3C2410_ADCTSC_YP_SEN (1<<6)
+#define S3C2410_ADCTSC_XM_SEN (1<<5)
+#define S3C2410_ADCTSC_XP_SEN (1<<4)
+#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
+#define S3C2410_ADCTSC_AUTO_PST (1<<2)
+#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
+
+/* ADCDAT0 Bits */
+#define S3C2410_ADCDAT0_UPDOWN (1<<15)
+#define S3C2410_ADCDAT0_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT0_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF)
+
+/* ADCDAT1 Bits */
+#define S3C2410_ADCDAT1_UPDOWN (1<<15)
+#define S3C2410_ADCDAT1_AUTO_PST (1<<14)
+#define S3C2410_ADCDAT1_XY_PST (0x3<<12)
+#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF)
+
+#endif /* __ASM_ARCH_REGS_ADC_H */
+
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-ata.h b/arch/arm/plat-samsung/include/plat/regs-ata.h
new file mode 100644
index 00000000..f5df92fd
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-ata.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/plat-samsung/include/plat/regs-ata.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA 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_PLAT_REGS_ATA_H
+#define __ASM_PLAT_REGS_ATA_H __FILE__
+
+#define S3C_CFATA_REG(x) (x)
+
+#define S3C_CFATA_MUX S3C_CFATA_REG(0x0)
+
+#define S3C_ATA_CTRL S3C_CFATA_REG(0x0)
+#define S3C_ATA_STATUS S3C_CFATA_REG(0x4)
+#define S3C_ATA_CMD S3C_CFATA_REG(0x8)
+#define S3C_ATA_SWRST S3C_CFATA_REG(0xc)
+#define S3C_ATA_IRQ S3C_CFATA_REG(0x10)
+#define S3C_ATA_IRQ_MSK S3C_CFATA_REG(0x14)
+#define S3C_ATA_CFG S3C_CFATA_REG(0x18)
+
+#define S3C_ATA_MDMA_TIME S3C_CFATA_REG(0x28)
+#define S3C_ATA_PIO_TIME S3C_CFATA_REG(0x2c)
+#define S3C_ATA_UDMA_TIME S3C_CFATA_REG(0x30)
+#define S3C_ATA_XFR_NUM S3C_CFATA_REG(0x34)
+#define S3C_ATA_XFR_CNT S3C_CFATA_REG(0x38)
+#define S3C_ATA_TBUF_START S3C_CFATA_REG(0x3c)
+#define S3C_ATA_TBUF_SIZE S3C_CFATA_REG(0x40)
+#define S3C_ATA_SBUF_START S3C_CFATA_REG(0x44)
+#define S3C_ATA_SBUF_SIZE S3C_CFATA_REG(0x48)
+#define S3C_ATA_CADR_TBUF S3C_CFATA_REG(0x4c)
+#define S3C_ATA_CADR_SBUF S3C_CFATA_REG(0x50)
+#define S3C_ATA_PIO_DTR S3C_CFATA_REG(0x54)
+#define S3C_ATA_PIO_FED S3C_CFATA_REG(0x58)
+#define S3C_ATA_PIO_SCR S3C_CFATA_REG(0x5c)
+#define S3C_ATA_PIO_LLR S3C_CFATA_REG(0x60)
+#define S3C_ATA_PIO_LMR S3C_CFATA_REG(0x64)
+#define S3C_ATA_PIO_LHR S3C_CFATA_REG(0x68)
+#define S3C_ATA_PIO_DVR S3C_CFATA_REG(0x6c)
+#define S3C_ATA_PIO_CSD S3C_CFATA_REG(0x70)
+#define S3C_ATA_PIO_DAD S3C_CFATA_REG(0x74)
+#define S3C_ATA_PIO_READY S3C_CFATA_REG(0x78)
+#define S3C_ATA_PIO_RDATA S3C_CFATA_REG(0x7c)
+
+#define S3C_CFATA_MUX_TRUEIDE 0x01
+
+#define S3C_ATA_CFG_SWAP 0x40
+#define S3C_ATA_CFG_IORDYEN 0x02
+
+#endif /* __ASM_PLAT_REGS_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
new file mode 100644
index 00000000..4c3647f8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
@@ -0,0 +1,159 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C64XX - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards and specifically the S3C64XX series
+ * S3C6400 and S3C6410.
+ *
+ * The file contains the cpu specific items which change between whichever
+ * architecture is selected. See <plat/regs-fb.h> for the core definitions
+ * that are the same.
+ *
+ * This program is free software; you can 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 the core definitions here, in case we really do need to
+ * override them at a later date.
+*/
+
+#include <plat/regs-fb.h>
+
+#define S3C_FB_MAX_WIN (5) /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN (1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0 (0x10)
+#define VIDTCON1 (0x14)
+#define VIDTCON2 (0x18)
+
+/* Window position controls */
+
+#define WINCON(_win) (0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_BASE (0x40)
+
+#define VIDINTCON0 (0x130)
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK (0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT (26)
+#define WINCONx_CSCWIDTH_WIDE (0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW (0x3 << 26)
+
+#define WINCONx_ENLOCAL (1 << 22)
+#define WINCONx_BUFSTATUS (1 << 21)
+#define WINCONx_BUFSEL (1 << 20)
+#define WINCONx_BUFAUTOEN (1 << 19)
+#define WINCONx_YCbCr (1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF (1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF (1 << 23)
+#define WINCON2_BLD_PIX (1 << 6)
+
+#define WINCON2_ALPHA_SEL (1 << 1)
+#define WINCON2_BPPMODE_MASK (0xf << 2)
+#define WINCON2_BPPMODE_SHIFT (2)
+#define WINCON2_BPPMODE_1BPP (0x0 << 2)
+#define WINCON2_BPPMODE_2BPP (0x1 << 2)
+#define WINCON2_BPPMODE_4BPP (0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232 (0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define WINCON3_BLD_PIX (1 << 6)
+
+#define WINCON3_ALPHA_SEL (1 << 1)
+#define WINCON3_BPPMODE_MASK (0xf << 2)
+#define WINCON3_BPPMODE_SHIFT (2)
+#define WINCON3_BPPMODE_1BPP (0x0 << 2)
+#define WINCON3_BPPMODE_2BPP (0x1 << 2)
+#define WINCON3_BPPMODE_4BPP (0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888 (0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2 (0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3 (0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4 (0x40 << 5)
+
+#define DITHMODE (0x170)
+#define WINxMAP(_win) (0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK (0x3 << 5)
+#define DITHMODE_R_POS_SHIFT (5)
+#define DITHMODE_R_POS_8BIT (0x0 << 5)
+#define DITHMODE_R_POS_6BIT (0x1 << 5)
+#define DITHMODE_R_POS_5BIT (0x2 << 5)
+
+#define DITHMODE_G_POS_MASK (0x3 << 3)
+#define DITHMODE_G_POS_SHIFT (3)
+#define DITHMODE_G_POS_8BIT (0x0 << 3)
+#define DITHMODE_G_POS_6BIT (0x1 << 3)
+#define DITHMODE_G_POS_5BIT (0x2 << 3)
+
+#define DITHMODE_B_POS_MASK (0x3 << 1)
+#define DITHMODE_B_POS_SHIFT (1)
+#define DITHMODE_B_POS_8BIT (0x0 << 1)
+#define DITHMODE_B_POS_6BIT (0x1 << 1)
+#define DITHMODE_B_POS_5BIT (0x2 << 1)
+
+#define DITHMODE_DITH_EN (1 << 0)
+
+#define WPALCON (0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555 (1 << 8)
+#define WPALCON_W3PAL_16BPP_A555 (1 << 7)
+#define WPALCON_W2PAL_16BPP_A555 (1 << 6)
+
+
+/* Notes on per-window bpp settings
+ *
+ * Value Win0 Win1 Win2 Win3 Win 4
+ * 0000 1(P) 1(P) 1(P) 1(P) 1(P)
+ * 0001 2(P) 2(P) 2(P) 2(P) 2(P)
+ * 0010 4(P) 4(P) 4(P) 4(P) -none-
+ * 0011 8(P) 8(P) -none- -none- -none-
+ * 0100 -none- 8(A232) 8(A232) -none- -none-
+ * 0101 16(565) 16(565) 16(565) 16(565) 16(565)
+ * 0110 -none- 16(A555) 16(A555) 16(A555) 16(A555)
+ * 0111 16(I555) 16(I565) 16(I555) 16(I555) 16(I555)
+ * 1000 18(666) 18(666) 18(666) 18(666) 18(666)
+ * 1001 -none- 18(A665) 18(A665) 18(A665) 16(A665)
+ * 1010 -none- 19(A666) 19(A666) 19(A666) 19(A666)
+ * 1011 24(888) 24(888) 24(888) 24(888) 24(888)
+ * 1100 -none- 24(A887) 24(A887) 24(A887) 24(A887)
+ * 1101 -none- 25(A888) 25(A888) 25(A888) 25(A888)
+ * 1110 -none- -none- -none- -none- -none-
+ * 1111 -none- -none- -none- -none- -none-
+*/
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h
new file mode 100644
index 00000000..8f39aa5b
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-fb.h
@@ -0,0 +1,386 @@
+/* arch/arm/plat-samsung/include/plat/regs-fb.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - new-style framebuffer register definitions
+ *
+ * This is the register set for the new style framebuffer interface
+ * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
+ * S3C64XX series such as the S3C6400 and S3C6410.
+ *
+ * The file does not contain the cpu specific items which are based on
+ * whichever architecture is selected, it only contains the core of the
+ * register set. See <mach/regs-fb.h> to get the specifics.
+ *
+ * Note, we changed to using regs-fb.h as it avoids any clashes with
+ * the original regs-lcd.h so out of the way of regs-lcd.h as well as
+ * indicating the newer block is much more than just an LCD interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/* Please do not include this file directly, use <mach/regs-fb.h> to
+ * ensure all the localised SoC support is included as necessary.
+*/
+
+/* VIDCON0 */
+
+#define VIDCON0 (0x00)
+#define VIDCON0_INTERLACE (1 << 29)
+#define VIDCON0_VIDOUT_MASK (0x3 << 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_L1_DATA_MASK (0x7 << 23)
+#define VIDCON0_L1_DATA_SHIFT (23)
+#define VIDCON0_L1_DATA_16BPP (0x0 << 23)
+#define VIDCON0_L1_DATA_18BPP16 (0x1 << 23)
+#define VIDCON0_L1_DATA_18BPP9 (0x2 << 23)
+#define VIDCON0_L1_DATA_24BPP (0x3 << 23)
+#define VIDCON0_L1_DATA_18BPP (0x4 << 23)
+#define VIDCON0_L1_DATA_16BPP8 (0x5 << 23)
+
+#define VIDCON0_L0_DATA_MASK (0x7 << 20)
+#define VIDCON0_L0_DATA_SHIFT (20)
+#define VIDCON0_L0_DATA_16BPP (0x0 << 20)
+#define VIDCON0_L0_DATA_18BPP16 (0x1 << 20)
+#define VIDCON0_L0_DATA_18BPP9 (0x2 << 20)
+#define VIDCON0_L0_DATA_24BPP (0x3 << 20)
+#define VIDCON0_L0_DATA_18BPP (0x4 << 20)
+#define VIDCON0_L0_DATA_16BPP8 (0x5 << 20)
+
+#define VIDCON0_PNRMODE_MASK (0x3 << 17)
+#define VIDCON0_PNRMODE_SHIFT (17)
+#define VIDCON0_PNRMODE_RGB (0x0 << 17)
+#define VIDCON0_PNRMODE_BGR (0x1 << 17)
+#define VIDCON0_PNRMODE_SERIAL_RGB (0x2 << 17)
+#define VIDCON0_PNRMODE_SERIAL_BGR (0x3 << 17)
+
+#define VIDCON0_CLKVALUP (1 << 16)
+#define VIDCON0_CLKVAL_F_MASK (0xff << 6)
+#define VIDCON0_CLKVAL_F_SHIFT (6)
+#define VIDCON0_CLKVAL_F_LIMIT (0xff)
+#define VIDCON0_CLKVAL_F(_x) ((_x) << 6)
+#define VIDCON0_VLCKFREE (1 << 5)
+#define VIDCON0_CLKDIR (1 << 4)
+
+#define VIDCON0_CLKSEL_MASK (0x3 << 2)
+#define VIDCON0_CLKSEL_SHIFT (2)
+#define VIDCON0_CLKSEL_HCLK (0x0 << 2)
+#define VIDCON0_CLKSEL_LCD (0x1 << 2)
+#define VIDCON0_CLKSEL_27M (0x3 << 2)
+
+#define VIDCON0_ENVID (1 << 1)
+#define VIDCON0_ENVID_F (1 << 0)
+
+#define VIDCON1 (0x04)
+#define VIDCON1_LINECNT_MASK (0x7ff << 16)
+#define VIDCON1_LINECNT_SHIFT (16)
+#define VIDCON1_LINECNT_GET(_v) (((_v) >> 16) & 0x7ff)
+#define VIDCON1_VSTATUS_MASK (0x3 << 13)
+#define VIDCON1_VSTATUS_SHIFT (13)
+#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_INV_VCLK (1 << 7)
+#define VIDCON1_INV_HSYNC (1 << 6)
+#define VIDCON1_INV_VSYNC (1 << 5)
+#define VIDCON1_INV_VDEN (1 << 4)
+
+/* 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)
+
+/* PRTCON (S3C6410, S5PC100)
+ * Might not be present in the S3C6410 documentation,
+ * but tests prove it's there almost for sure; shouldn't hurt in any case.
+ */
+#define PRTCON (0x0c)
+#define PRTCON_PROTECT (1 << 11)
+
+/* VIDTCON0 */
+
+#define VIDTCON0_VBPDE_MASK (0xff << 24)
+#define VIDTCON0_VBPDE_SHIFT (24)
+#define VIDTCON0_VBPDE_LIMIT (0xff)
+#define VIDTCON0_VBPDE(_x) ((_x) << 24)
+
+#define VIDTCON0_VBPD_MASK (0xff << 16)
+#define VIDTCON0_VBPD_SHIFT (16)
+#define VIDTCON0_VBPD_LIMIT (0xff)
+#define VIDTCON0_VBPD(_x) ((_x) << 16)
+
+#define VIDTCON0_VFPD_MASK (0xff << 8)
+#define VIDTCON0_VFPD_SHIFT (8)
+#define VIDTCON0_VFPD_LIMIT (0xff)
+#define VIDTCON0_VFPD(_x) ((_x) << 8)
+
+#define VIDTCON0_VSPW_MASK (0xff << 0)
+#define VIDTCON0_VSPW_SHIFT (0)
+#define VIDTCON0_VSPW_LIMIT (0xff)
+#define VIDTCON0_VSPW(_x) ((_x) << 0)
+
+/* VIDTCON1 */
+
+#define VIDTCON1_VFPDE_MASK (0xff << 24)
+#define VIDTCON1_VFPDE_SHIFT (24)
+#define VIDTCON1_VFPDE_LIMIT (0xff)
+#define VIDTCON1_VFPDE(_x) ((_x) << 24)
+
+#define VIDTCON1_HBPD_MASK (0xff << 16)
+#define VIDTCON1_HBPD_SHIFT (16)
+#define VIDTCON1_HBPD_LIMIT (0xff)
+#define VIDTCON1_HBPD(_x) ((_x) << 16)
+
+#define VIDTCON1_HFPD_MASK (0xff << 8)
+#define VIDTCON1_HFPD_SHIFT (8)
+#define VIDTCON1_HFPD_LIMIT (0xff)
+#define VIDTCON1_HFPD(_x) ((_x) << 8)
+
+#define VIDTCON1_HSPW_MASK (0xff << 0)
+#define VIDTCON1_HSPW_SHIFT (0)
+#define VIDTCON1_HSPW_LIMIT (0xff)
+#define VIDTCON1_HSPW(_x) ((_x) << 0)
+
+#define VIDTCON2 (0x18)
+#define VIDTCON2_LINEVAL_MASK (0x7ff << 11)
+#define VIDTCON2_LINEVAL_SHIFT (11)
+#define VIDTCON2_LINEVAL_LIMIT (0x7ff)
+#define VIDTCON2_LINEVAL(_x) ((_x) << 11)
+
+#define VIDTCON2_HOZVAL_MASK (0x7ff << 0)
+#define VIDTCON2_HOZVAL_SHIFT (0)
+#define VIDTCON2_HOZVAL_LIMIT (0x7ff)
+#define VIDTCON2_HOZVAL(_x) ((_x) << 0)
+
+/* WINCONx */
+
+
+#define WINCONx_BITSWP (1 << 18)
+#define WINCONx_BYTSWP (1 << 17)
+#define WINCONx_HAWSWP (1 << 16)
+#define WINCONx_WSWP (1 << 15)
+#define WINCONx_BURSTLEN_MASK (0x3 << 9)
+#define WINCONx_BURSTLEN_SHIFT (9)
+#define WINCONx_BURSTLEN_16WORD (0x0 << 9)
+#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
+#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
+
+#define WINCONx_ENWIN (1 << 0)
+#define WINCON0_BPPMODE_MASK (0xf << 2)
+#define WINCON0_BPPMODE_SHIFT (2)
+#define WINCON0_BPPMODE_1BPP (0x0 << 2)
+#define WINCON0_BPPMODE_2BPP (0x1 << 2)
+#define WINCON0_BPPMODE_4BPP (0x2 << 2)
+#define WINCON0_BPPMODE_8BPP_PALETTE (0x3 << 2)
+#define WINCON0_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON0_BPPMODE_16BPP_1555 (0x7 << 2)
+#define WINCON0_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
+
+#define WINCON1_BLD_PIX (1 << 6)
+
+#define WINCON1_ALPHA_SEL (1 << 1)
+#define WINCON1_BPPMODE_MASK (0xf << 2)
+#define WINCON1_BPPMODE_SHIFT (2)
+#define WINCON1_BPPMODE_1BPP (0x0 << 2)
+#define WINCON1_BPPMODE_2BPP (0x1 << 2)
+#define WINCON1_BPPMODE_4BPP (0x2 << 2)
+#define WINCON1_BPPMODE_8BPP_PALETTE (0x3 << 2)
+#define WINCON1_BPPMODE_8BPP_1232 (0x4 << 2)
+#define WINCON1_BPPMODE_16BPP_565 (0x5 << 2)
+#define WINCON1_BPPMODE_16BPP_A1555 (0x6 << 2)
+#define WINCON1_BPPMODE_16BPP_I1555 (0x7 << 2)
+#define WINCON1_BPPMODE_18BPP_666 (0x8 << 2)
+#define WINCON1_BPPMODE_18BPP_A1665 (0x9 << 2)
+#define WINCON1_BPPMODE_19BPP_A1666 (0xa << 2)
+#define WINCON1_BPPMODE_24BPP_888 (0xb << 2)
+#define WINCON1_BPPMODE_24BPP_A1887 (0xc << 2)
+#define WINCON1_BPPMODE_25BPP_A1888 (0xd << 2)
+#define WINCON1_BPPMODE_28BPP_A4888 (0xd << 2)
+
+/* S5PV210 */
+#define SHADOWCON (0x34)
+#define SHADOWCON_WINx_PROTECT(_win) (1 << (10 + (_win)))
+/* DMA channels (all windows) */
+#define SHADOWCON_CHx_ENABLE(_win) (1 << (_win))
+/* Local input channels (windows 0-2) */
+#define SHADOWCON_CHx_LOCAL_ENABLE(_win) (1 << (5 + (_win)))
+
+#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_Y_MASK (0x7ff << 0)
+#define VIDOSDxA_TOPLEFT_Y_SHIFT (0)
+#define VIDOSDxA_TOPLEFT_Y_LIMIT (0x7ff)
+#define VIDOSDxA_TOPLEFT_Y(_x) ((_x) << 0)
+
+#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_Y_MASK (0x7ff << 0)
+#define VIDOSDxB_BOTRIGHT_Y_SHIFT (0)
+#define VIDOSDxB_BOTRIGHT_Y_LIMIT (0x7ff)
+#define VIDOSDxB_BOTRIGHT_Y(_x) ((_x) << 0)
+
+/* For VIDOSD[1..4]C */
+#define VIDISD14C_ALPHA0_R(_x) ((_x) << 20)
+#define VIDISD14C_ALPHA0_G_MASK (0xf << 16)
+#define VIDISD14C_ALPHA0_G_SHIFT (16)
+#define VIDISD14C_ALPHA0_G_LIMIT (0xf)
+#define VIDISD14C_ALPHA0_G(_x) ((_x) << 16)
+#define VIDISD14C_ALPHA0_B_MASK (0xf << 12)
+#define VIDISD14C_ALPHA0_B_SHIFT (12)
+#define VIDISD14C_ALPHA0_B_LIMIT (0xf)
+#define VIDISD14C_ALPHA0_B(_x) ((_x) << 12)
+#define VIDISD14C_ALPHA1_R_MASK (0xf << 8)
+#define VIDISD14C_ALPHA1_R_SHIFT (8)
+#define VIDISD14C_ALPHA1_R_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_R(_x) ((_x) << 8)
+#define VIDISD14C_ALPHA1_G_MASK (0xf << 4)
+#define VIDISD14C_ALPHA1_G_SHIFT (4)
+#define VIDISD14C_ALPHA1_G_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_G(_x) ((_x) << 4)
+#define VIDISD14C_ALPHA1_B_MASK (0xf << 0)
+#define VIDISD14C_ALPHA1_B_SHIFT (0)
+#define VIDISD14C_ALPHA1_B_LIMIT (0xf)
+#define VIDISD14C_ALPHA1_B(_x) ((_x) << 0)
+
+/* Video buffer addresses */
+#define VIDW_BUF_START(_buff) (0xA0 + ((_buff) * 8))
+#define VIDW_BUF_START1(_buff) (0xA4 + ((_buff) * 8))
+#define VIDW_BUF_END(_buff) (0xD0 + ((_buff) * 8))
+#define VIDW_BUF_END1(_buff) (0xD4 + ((_buff) * 8))
+#define VIDW_BUF_SIZE(_buff) (0x100 + ((_buff) * 4))
+
+#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_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)
+
+/* Interrupt controls and status */
+
+#define VIDINTCON0_FIFOINTERVAL_MASK (0x3f << 20)
+#define VIDINTCON0_FIFOINTERVAL_SHIFT (20)
+#define VIDINTCON0_FIFOINTERVAL_LIMIT (0x3f)
+#define VIDINTCON0_FIFOINTERVAL(_x) ((_x) << 20)
+
+#define VIDINTCON0_INT_SYSMAINCON (1 << 19)
+#define VIDINTCON0_INT_SYSSUBCON (1 << 18)
+#define VIDINTCON0_INT_I80IFDONE (1 << 17)
+
+#define VIDINTCON0_FRAMESEL0_MASK (0x3 << 15)
+#define VIDINTCON0_FRAMESEL0_SHIFT (15)
+#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
+#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
+#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
+#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
+
+#define VIDINTCON0_FRAMESEL1 (1 << 13)
+#define VIDINTCON0_FRAMESEL1_MASK (0x3 << 13)
+#define VIDINTCON0_FRAMESEL1_NONE (0x0 << 13)
+#define VIDINTCON0_FRAMESEL1_BACKPORCH (0x1 << 13)
+#define VIDINTCON0_FRAMESEL1_VSYNC (0x2 << 13)
+#define VIDINTCON0_FRAMESEL1_FRONTPORCH (0x3 << 13)
+
+#define VIDINTCON0_INT_FRAME (1 << 12)
+#define VIDINTCON0_FIFIOSEL_MASK (0x7f << 5)
+#define VIDINTCON0_FIFIOSEL_SHIFT (5)
+#define VIDINTCON0_FIFIOSEL_WINDOW0 (0x1 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW1 (0x2 << 5)
+
+#define VIDINTCON0_FIFOLEVEL_MASK (0x7 << 2)
+#define VIDINTCON0_FIFOLEVEL_SHIFT (2)
+#define VIDINTCON0_FIFOLEVEL_TO25PC (0x0 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO50PC (0x1 << 2)
+#define VIDINTCON0_FIFOLEVEL_TO75PC (0x2 << 2)
+#define VIDINTCON0_FIFOLEVEL_EMPTY (0x3 << 2)
+#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 2)
+
+#define VIDINTCON0_INT_FIFO_MASK (0x3 << 0)
+#define VIDINTCON0_INT_FIFO_SHIFT (0)
+#define VIDINTCON0_INT_ENABLE (1 << 0)
+
+#define VIDINTCON1 (0x134)
+#define VIDINTCON1_INT_I180 (1 << 2)
+#define VIDINTCON1_INT_FRAME (1 << 1)
+#define VIDINTCON1_INT_FIFO (1 << 0)
+
+/* Window colour-key control registers */
+#define WKEYCON (0x140) /* 6410,V210 */
+
+#define WKEYCON0 (0x00)
+#define WKEYCON1 (0x04)
+
+#define WxKEYCON0_KEYBL_EN (1 << 26)
+#define WxKEYCON0_KEYEN_F (1 << 25)
+#define WxKEYCON0_DIRCON (1 << 24)
+#define WxKEYCON0_COMPKEY_MASK (0xffffff << 0)
+#define WxKEYCON0_COMPKEY_SHIFT (0)
+#define WxKEYCON0_COMPKEY_LIMIT (0xffffff)
+#define WxKEYCON0_COMPKEY(_x) ((_x) << 0)
+#define WxKEYCON1_COLVAL_MASK (0xffffff << 0)
+#define WxKEYCON1_COLVAL_SHIFT (0)
+#define WxKEYCON1_COLVAL_LIMIT (0xffffff)
+#define WxKEYCON1_COLVAL(_x) ((_x) << 0)
+
+
+/* Window blanking (MAP) */
+
+#define WINxMAP_MAP (1 << 24)
+#define WINxMAP_MAP_COLOUR_MASK (0xffffff << 0)
+#define WINxMAP_MAP_COLOUR_SHIFT (0)
+#define WINxMAP_MAP_COLOUR_LIMIT (0xffffff)
+#define WINxMAP_MAP_COLOUR(_x) ((_x) << 0)
+
+#define WPALCON_PAL_UPDATE (1 << 9)
+#define WPALCON_W1PAL_MASK (0x7 << 3)
+#define WPALCON_W1PAL_SHIFT (3)
+#define WPALCON_W1PAL_25BPP_A888 (0x0 << 3)
+#define WPALCON_W1PAL_24BPP (0x1 << 3)
+#define WPALCON_W1PAL_19BPP_A666 (0x2 << 3)
+#define WPALCON_W1PAL_18BPP_A665 (0x3 << 3)
+#define WPALCON_W1PAL_18BPP (0x4 << 3)
+#define WPALCON_W1PAL_16BPP_A555 (0x5 << 3)
+#define WPALCON_W1PAL_16BPP_565 (0x6 << 3)
+
+#define WPALCON_W0PAL_MASK (0x7 << 0)
+#define WPALCON_W0PAL_SHIFT (0)
+#define WPALCON_W0PAL_25BPP_A888 (0x0 << 0)
+#define WPALCON_W0PAL_24BPP (0x1 << 0)
+#define WPALCON_W0PAL_19BPP_A666 (0x2 << 0)
+#define WPALCON_W0PAL_18BPP_A665 (0x3 << 0)
+#define WPALCON_W0PAL_18BPP (0x4 << 0)
+#define WPALCON_W0PAL_16BPP_A555 (0x5 << 0)
+#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-iic.h b/arch/arm/plat-samsung/include/plat/regs-iic.h
new file mode 100644
index 00000000..2f7c17de
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-iic.h
@@ -0,0 +1,56 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-iic.h
+ *
+ * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 I2C Controller
+*/
+
+#ifndef __ASM_ARCH_REGS_IIC_H
+#define __ASM_ARCH_REGS_IIC_H __FILE__
+
+/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */
+
+#define S3C2410_IICREG(x) (x)
+
+#define S3C2410_IICCON S3C2410_IICREG(0x00)
+#define S3C2410_IICSTAT S3C2410_IICREG(0x04)
+#define S3C2410_IICADD S3C2410_IICREG(0x08)
+#define S3C2410_IICDS S3C2410_IICREG(0x0C)
+#define S3C2440_IICLC S3C2410_IICREG(0x10)
+
+#define S3C2410_IICCON_ACKEN (1<<7)
+#define S3C2410_IICCON_TXDIV_16 (0<<6)
+#define S3C2410_IICCON_TXDIV_512 (1<<6)
+#define S3C2410_IICCON_IRQEN (1<<5)
+#define S3C2410_IICCON_IRQPEND (1<<4)
+#define S3C2410_IICCON_SCALE(x) ((x)&15)
+#define S3C2410_IICCON_SCALEMASK (0xf)
+
+#define S3C2410_IICSTAT_MASTER_RX (2<<6)
+#define S3C2410_IICSTAT_MASTER_TX (3<<6)
+#define S3C2410_IICSTAT_SLAVE_RX (0<<6)
+#define S3C2410_IICSTAT_SLAVE_TX (1<<6)
+#define S3C2410_IICSTAT_MODEMASK (3<<6)
+
+#define S3C2410_IICSTAT_START (1<<5)
+#define S3C2410_IICSTAT_BUSBUSY (1<<5)
+#define S3C2410_IICSTAT_TXRXEN (1<<4)
+#define S3C2410_IICSTAT_ARBITR (1<<3)
+#define S3C2410_IICSTAT_ASSLAVE (1<<2)
+#define S3C2410_IICSTAT_ADDR0 (1<<1)
+#define S3C2410_IICSTAT_LASTBIT (1<<0)
+
+#define S3C2410_IICLC_SDA_DELAY0 (0 << 0)
+#define S3C2410_IICLC_SDA_DELAY5 (1 << 0)
+#define S3C2410_IICLC_SDA_DELAY10 (2 << 0)
+#define S3C2410_IICLC_SDA_DELAY15 (3 << 0)
+#define S3C2410_IICLC_SDA_DELAY_MASK (3 << 0)
+
+#define S3C2410_IICLC_FILTER_ON (1<<2)
+
+#endif /* __ASM_ARCH_REGS_IIC_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-irqtype.h b/arch/arm/plat-samsung/include/plat/regs-irqtype.h
new file mode 100644
index 00000000..c63cd3fc
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-irqtype.h
@@ -0,0 +1,21 @@
+/* arch/arm/plat-s3c/include/plat/regs-irqtype.h
+ *
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C - IRQ detection types.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* values for S3C2410_EXTINT0/1/2 and other cpus in the series, including
+ * the S3C64XX
+*/
+#define S3C2410_EXTINT_LOWLEV (0x00)
+#define S3C2410_EXTINT_HILEV (0x01)
+#define S3C2410_EXTINT_FALLEDGE (0x02)
+#define S3C2410_EXTINT_RISEEDGE (0x04)
+#define S3C2410_EXTINT_BOTHEDGE (0x06)
diff --git a/arch/arm/plat-samsung/include/plat/regs-nand.h b/arch/arm/plat-samsung/include/plat/regs-nand.h
new file mode 100644
index 00000000..238efea7
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-nand.h
@@ -0,0 +1,123 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-nand.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 NAND register definitions
+*/
+
+#ifndef __ASM_ARM_REGS_NAND
+#define __ASM_ARM_REGS_NAND
+
+
+#define S3C2410_NFREG(x) (x)
+
+#define S3C2410_NFCONF S3C2410_NFREG(0x00)
+#define S3C2410_NFCMD S3C2410_NFREG(0x04)
+#define S3C2410_NFADDR S3C2410_NFREG(0x08)
+#define S3C2410_NFDATA S3C2410_NFREG(0x0C)
+#define S3C2410_NFSTAT S3C2410_NFREG(0x10)
+#define S3C2410_NFECC S3C2410_NFREG(0x14)
+
+#define S3C2440_NFCONT S3C2410_NFREG(0x04)
+#define S3C2440_NFCMD S3C2410_NFREG(0x08)
+#define S3C2440_NFADDR S3C2410_NFREG(0x0C)
+#define S3C2440_NFDATA S3C2410_NFREG(0x10)
+#define S3C2440_NFECCD0 S3C2410_NFREG(0x14)
+#define S3C2440_NFECCD1 S3C2410_NFREG(0x18)
+#define S3C2440_NFECCD S3C2410_NFREG(0x1C)
+#define S3C2440_NFSTAT S3C2410_NFREG(0x20)
+#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)
+#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)
+#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C)
+#define S3C2440_NFMECC1 S3C2410_NFREG(0x30)
+#define S3C2440_NFSECC S3C2410_NFREG(0x34)
+#define S3C2440_NFSBLK S3C2410_NFREG(0x38)
+#define S3C2440_NFEBLK S3C2410_NFREG(0x3C)
+
+#define S3C2412_NFSBLK S3C2410_NFREG(0x20)
+#define S3C2412_NFEBLK S3C2410_NFREG(0x24)
+#define S3C2412_NFSTAT S3C2410_NFREG(0x28)
+#define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C)
+#define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30)
+#define S3C2412_NFMECC0 S3C2410_NFREG(0x34)
+#define S3C2412_NFMECC1 S3C2410_NFREG(0x38)
+#define S3C2412_NFSECC S3C2410_NFREG(0x3C)
+
+#define S3C2410_NFCONF_EN (1<<15)
+#define S3C2410_NFCONF_512BYTE (1<<14)
+#define S3C2410_NFCONF_4STEP (1<<13)
+#define S3C2410_NFCONF_INITECC (1<<12)
+#define S3C2410_NFCONF_nFCE (1<<11)
+#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
+#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
+#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
+
+#define S3C2410_NFSTAT_BUSY (1<<0)
+
+#define S3C2440_NFCONF_BUSWIDTH_8 (0<<0)
+#define S3C2440_NFCONF_BUSWIDTH_16 (1<<0)
+#define S3C2440_NFCONF_ADVFLASH (1<<3)
+#define S3C2440_NFCONF_TACLS(x) ((x)<<12)
+#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)
+#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)
+
+#define S3C2440_NFCONT_LOCKTIGHT (1<<13)
+#define S3C2440_NFCONT_SOFTLOCK (1<<12)
+#define S3C2440_NFCONT_ILLEGALACC_EN (1<<10)
+#define S3C2440_NFCONT_RNBINT_EN (1<<9)
+#define S3C2440_NFCONT_RN_FALLING (1<<8)
+#define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6)
+#define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5)
+#define S3C2440_NFCONT_INITECC (1<<4)
+#define S3C2440_NFCONT_nFCE (1<<1)
+#define S3C2440_NFCONT_ENABLE (1<<0)
+
+#define S3C2440_NFSTAT_READY (1<<0)
+#define S3C2440_NFSTAT_nCE (1<<1)
+#define S3C2440_NFSTAT_RnB_CHANGE (1<<2)
+#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3)
+
+#define S3C2412_NFCONF_NANDBOOT (1<<31)
+#define S3C2412_NFCONF_ECCCLKCON (1<<30)
+#define S3C2412_NFCONF_ECC_MLC (1<<24)
+#define S3C2412_NFCONF_TACLS_MASK (7<<12) /* 1 extra bit of Tacls */
+
+#define S3C2412_NFCONT_ECC4_DIRWR (1<<18)
+#define S3C2412_NFCONT_LOCKTIGHT (1<<17)
+#define S3C2412_NFCONT_SOFTLOCK (1<<16)
+#define S3C2412_NFCONT_ECC4_ENCINT (1<<13)
+#define S3C2412_NFCONT_ECC4_DECINT (1<<12)
+#define S3C2412_NFCONT_MAIN_ECC_LOCK (1<<7)
+#define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5)
+#define S3C2412_NFCONT_nFCE1 (1<<2)
+#define S3C2412_NFCONT_nFCE0 (1<<1)
+
+#define S3C2412_NFSTAT_ECC_ENCDONE (1<<7)
+#define S3C2412_NFSTAT_ECC_DECDONE (1<<6)
+#define S3C2412_NFSTAT_ILLEGAL_ACCESS (1<<5)
+#define S3C2412_NFSTAT_RnB_CHANGE (1<<4)
+#define S3C2412_NFSTAT_nFCE1 (1<<3)
+#define S3C2412_NFSTAT_nFCE0 (1<<2)
+#define S3C2412_NFSTAT_Res1 (1<<1)
+#define S3C2412_NFSTAT_READY (1<<0)
+
+#define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf)
+#define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7)
+#define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff)
+#define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7)
+#define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3)
+#define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3)
+#define S3C2412_NFECCERR_NONE (0)
+#define S3C2412_NFECCERR_1BIT (1)
+#define S3C2412_NFECCERR_MULTIBIT (2)
+#define S3C2412_NFECCERR_ECCAREA (3)
+
+
+
+#endif /* __ASM_ARM_REGS_NAND */
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-onenand.h b/arch/arm/plat-samsung/include/plat/regs-onenand.h
new file mode 100644
index 00000000..930ea8b8
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-onenand.h
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/arm/plat-s3c/include/plat/regs-onenand.h
+ *
+ * Copyright (C) 2008-2010 Samsung Electronics
+ * Kyungmin Park <kyungmin.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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __SAMSUNG_ONENAND_H__
+#define __SAMSUNG_ONENAND_H__
+
+#include <mach/hardware.h>
+
+/*
+ * OneNAND Controller
+ */
+#define MEM_CFG_OFFSET 0x0000
+#define BURST_LEN_OFFSET 0x0010
+#define MEM_RESET_OFFSET 0x0020
+#define INT_ERR_STAT_OFFSET 0x0030
+#define INT_ERR_MASK_OFFSET 0x0040
+#define INT_ERR_ACK_OFFSET 0x0050
+#define ECC_ERR_STAT_OFFSET 0x0060
+#define MANUFACT_ID_OFFSET 0x0070
+#define DEVICE_ID_OFFSET 0x0080
+#define DATA_BUF_SIZE_OFFSET 0x0090
+#define BOOT_BUF_SIZE_OFFSET 0x00A0
+#define BUF_AMOUNT_OFFSET 0x00B0
+#define TECH_OFFSET 0x00C0
+#define FBA_WIDTH_OFFSET 0x00D0
+#define FPA_WIDTH_OFFSET 0x00E0
+#define FSA_WIDTH_OFFSET 0x00F0
+#define TRANS_SPARE_OFFSET 0x0140
+#define DBS_DFS_WIDTH_OFFSET 0x0160
+#define INT_PIN_ENABLE_OFFSET 0x01A0
+#define ACC_CLOCK_OFFSET 0x01C0
+#define FLASH_VER_ID_OFFSET 0x01F0
+#define FLASH_AUX_CNTRL_OFFSET 0x0300 /* s3c64xx only */
+
+#define ONENAND_MEM_RESET_HOT 0x3
+#define ONENAND_MEM_RESET_COLD 0x2
+#define ONENAND_MEM_RESET_WARM 0x1
+
+#define CACHE_OP_ERR (1 << 13)
+#define RST_CMP (1 << 12)
+#define RDY_ACT (1 << 11)
+#define INT_ACT (1 << 10)
+#define UNSUP_CMD (1 << 9)
+#define LOCKED_BLK (1 << 8)
+#define BLK_RW_CMP (1 << 7)
+#define ERS_CMP (1 << 6)
+#define PGM_CMP (1 << 5)
+#define LOAD_CMP (1 << 4)
+#define ERS_FAIL (1 << 3)
+#define PGM_FAIL (1 << 2)
+#define INT_TO (1 << 1)
+#define LD_FAIL_ECC_ERR (1 << 0)
+
+#define TSRF (1 << 0)
+
+#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
new file mode 100644
index 00000000..30b7cc14
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -0,0 +1,68 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-rtc.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Internal RTC register definition
+*/
+
+#ifndef __ASM_ARCH_REGS_RTC_H
+#define __ASM_ARCH_REGS_RTC_H __FILE__
+
+#define S3C2410_RTCREG(x) (x)
+#define S3C2410_INTP S3C2410_RTCREG(0x30)
+#define S3C2410_INTP_ALM (1 << 1)
+#define S3C2410_INTP_TIC (1 << 0)
+
+#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
+#define S3C2410_RTCCON_RTCEN (1<<0)
+#define S3C2410_RTCCON_CLKSEL (1<<1)
+#define S3C2410_RTCCON_CNTSEL (1<<2)
+#define S3C2410_RTCCON_CLKRST (1<<3)
+#define S3C64XX_RTCCON_TICEN (1<<8)
+
+#define S3C64XX_RTCCON_TICMSK (0xF<<7)
+#define S3C64XX_RTCCON_TICSHT (7)
+
+#define S3C2410_TICNT S3C2410_RTCREG(0x44)
+#define S3C2410_TICNT_ENABLE (1<<7)
+
+#define S3C2410_RTCALM S3C2410_RTCREG(0x50)
+#define S3C2410_RTCALM_ALMEN (1<<6)
+#define S3C2410_RTCALM_YEAREN (1<<5)
+#define S3C2410_RTCALM_MONEN (1<<4)
+#define S3C2410_RTCALM_DAYEN (1<<3)
+#define S3C2410_RTCALM_HOUREN (1<<2)
+#define S3C2410_RTCALM_MINEN (1<<1)
+#define S3C2410_RTCALM_SECEN (1<<0)
+
+#define S3C2410_RTCALM_ALL \
+ S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
+ S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
+ S3C2410_RTCALM_SECEN
+
+
+#define S3C2410_ALMSEC S3C2410_RTCREG(0x54)
+#define S3C2410_ALMMIN S3C2410_RTCREG(0x58)
+#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c)
+
+#define S3C2410_ALMDATE S3C2410_RTCREG(0x60)
+#define S3C2410_ALMMON S3C2410_RTCREG(0x64)
+#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68)
+
+#define S3C2410_RTCRST S3C2410_RTCREG(0x6c)
+
+#define S3C2410_RTCSEC S3C2410_RTCREG(0x70)
+#define S3C2410_RTCMIN S3C2410_RTCREG(0x74)
+#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78)
+#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c)
+#define S3C2410_RTCDAY S3C2410_RTCREG(0x80)
+#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
+#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
+
+
+#endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-sdhci.h b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
new file mode 100644
index 00000000..e34049ad
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-sdhci.h
@@ -0,0 +1,87 @@
+/* linux/arch/arm/plat-s3c/include/plat/regs-sdhci.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (HSMMC) 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_S3C_SDHCI_REGS_H
+#define __PLAT_S3C_SDHCI_REGS_H __FILE__
+
+#define S3C_SDHCI_CONTROL2 (0x80)
+#define S3C_SDHCI_CONTROL3 (0x84)
+#define S3C64XX_SDHCI_CONTROL4 (0x8C)
+
+#define S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR (1 << 31)
+#define S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK (1 << 30)
+#define S3C_SDHCI_CTRL2_CDINVRXD3 (1 << 29)
+#define S3C_SDHCI_CTRL2_SLCARDOUT (1 << 28)
+
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_MASK (0xf << 24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL_SHIFT (24)
+#define S3C_SDHCI_CTRL2_FLTCLKSEL(_x) ((_x) << 24)
+
+#define S3C_SDHCI_CTRL2_LVLDAT_MASK (0xff << 16)
+#define S3C_SDHCI_CTRL2_LVLDAT_SHIFT (16)
+#define S3C_SDHCI_CTRL2_LVLDAT(_x) ((_x) << 16)
+
+#define S3C_SDHCI_CTRL2_ENFBCLKTX (1 << 15)
+#define S3C_SDHCI_CTRL2_ENFBCLKRX (1 << 14)
+#define S3C_SDHCI_CTRL2_SDCDSEL (1 << 13)
+#define S3C_SDHCI_CTRL2_SDSIGPC (1 << 12)
+#define S3C_SDHCI_CTRL2_ENBUSYCHKTXSTART (1 << 11)
+
+#define S3C_SDHCI_CTRL2_DFCNT_MASK (0x3 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_SHIFT (9)
+#define S3C_SDHCI_CTRL2_DFCNT_NONE (0x0 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_4SDCLK (0x1 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_16SDCLK (0x2 << 9)
+#define S3C_SDHCI_CTRL2_DFCNT_64SDCLK (0x3 << 9)
+
+#define S3C_SDHCI_CTRL2_ENCLKOUTHOLD (1 << 8)
+#define S3C_SDHCI_CTRL2_RWAITMODE (1 << 7)
+#define S3C_SDHCI_CTRL2_DISBUFRD (1 << 6)
+#define S3C_SDHCI_CTRL2_SELBASECLK_MASK (0x3 << 4)
+#define S3C_SDHCI_CTRL2_SELBASECLK_SHIFT (4)
+#define S3C_SDHCI_CTRL2_PWRSYNC (1 << 3)
+#define S3C_SDHCI_CTRL2_ENCLKOUTMSKCON (1 << 1)
+#define S3C_SDHCI_CTRL2_HWINITFIN (1 << 0)
+
+#define S3C_SDHCI_CTRL3_FCSEL3 (1 << 31)
+#define S3C_SDHCI_CTRL3_FCSEL2 (1 << 23)
+#define S3C_SDHCI_CTRL3_FCSEL1 (1 << 15)
+#define S3C_SDHCI_CTRL3_FCSEL0 (1 << 7)
+
+#define S3C_SDHCI_CTRL3_FIA3_MASK (0x7f << 24)
+#define S3C_SDHCI_CTRL3_FIA3_SHIFT (24)
+#define S3C_SDHCI_CTRL3_FIA3(_x) ((_x) << 24)
+
+#define S3C_SDHCI_CTRL3_FIA2_MASK (0x7f << 16)
+#define S3C_SDHCI_CTRL3_FIA2_SHIFT (16)
+#define S3C_SDHCI_CTRL3_FIA2(_x) ((_x) << 16)
+
+#define S3C_SDHCI_CTRL3_FIA1_MASK (0x7f << 8)
+#define S3C_SDHCI_CTRL3_FIA1_SHIFT (8)
+#define S3C_SDHCI_CTRL3_FIA1(_x) ((_x) << 8)
+
+#define S3C_SDHCI_CTRL3_FIA0_MASK (0x7f << 0)
+#define S3C_SDHCI_CTRL3_FIA0_SHIFT (0)
+#define S3C_SDHCI_CTRL3_FIA0(_x) ((_x) << 0)
+
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_MASK (0x3 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_SHIFT (16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_2mA (0x0 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_4mA (0x1 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_7mA (0x2 << 16)
+#define S3C64XX_SDHCI_CONTROL4_DRIVE_9mA (0x3 << 16)
+
+#define S3C64XX_SDHCI_CONTROL4_BUSY (1)
+
+#endif /* __PLAT_S3C_SDHCI_REGS_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
new file mode 100644
index 00000000..116edfe1
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -0,0 +1,285 @@
+/* arch/arm/plat-samsung/include/plat/regs-serial.h
+ *
+ * From linux/include/asm-arm/hardware/serial_s3c2410.h
+ *
+ * Internal header file for Samsung S3C2410 serial ports (UART0-2)
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk)
+ *
+ * Adapted from:
+ *
+ * Internal header file for MX1ADS serial ports (UART1 & 2)
+ *
+ * Copyright (C) 2002 Shane Nay (shane@minirl.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 __ASM_ARM_REGS_SERIAL_H
+#define __ASM_ARM_REGS_SERIAL_H
+
+#define S3C24XX_VA_UART0 (S3C_VA_UART)
+#define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 )
+#define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 )
+#define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 )
+
+#define S3C2410_PA_UART0 (S3C24XX_PA_UART)
+#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 )
+#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 )
+#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 )
+
+#define S3C2410_URXH (0x24)
+#define S3C2410_UTXH (0x20)
+#define S3C2410_ULCON (0x00)
+#define S3C2410_UCON (0x04)
+#define S3C2410_UFCON (0x08)
+#define S3C2410_UMCON (0x0C)
+#define S3C2410_UBRDIV (0x28)
+#define S3C2410_UTRSTAT (0x10)
+#define S3C2410_UERSTAT (0x14)
+#define S3C2410_UFSTAT (0x18)
+#define S3C2410_UMSTAT (0x1C)
+
+#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
+
+#define S3C2410_LCON_CS5 (0x0)
+#define S3C2410_LCON_CS6 (0x1)
+#define S3C2410_LCON_CS7 (0x2)
+#define S3C2410_LCON_CS8 (0x3)
+#define S3C2410_LCON_CSMASK (0x3)
+
+#define S3C2410_LCON_PNONE (0x0)
+#define S3C2410_LCON_PEVEN (0x5 << 3)
+#define S3C2410_LCON_PODD (0x4 << 3)
+#define S3C2410_LCON_PMASK (0x7 << 3)
+
+#define S3C2410_LCON_STOPB (1<<2)
+#define S3C2410_LCON_IRM (1<<6)
+
+#define S3C2440_UCON_CLKMASK (3<<10)
+#define S3C2440_UCON_PCLK (0<<10)
+#define S3C2440_UCON_UCLK (1<<10)
+#define S3C2440_UCON_PCLK2 (2<<10)
+#define S3C2440_UCON_FCLK (3<<10)
+#define S3C2443_UCON_EPLL (3<<10)
+
+#define S3C6400_UCON_CLKMASK (3<<10)
+#define S3C6400_UCON_PCLK (0<<10)
+#define S3C6400_UCON_PCLK2 (2<<10)
+#define S3C6400_UCON_UCLK0 (1<<10)
+#define S3C6400_UCON_UCLK1 (3<<10)
+
+#define S3C2440_UCON2_FCLK_EN (1<<15)
+#define S3C2440_UCON0_DIVMASK (15 << 12)
+#define S3C2440_UCON1_DIVMASK (15 << 12)
+#define S3C2440_UCON2_DIVMASK (7 << 12)
+#define S3C2440_UCON_DIVSHIFT (12)
+
+#define S3C2412_UCON_CLKMASK (3<<10)
+#define S3C2412_UCON_UCLK (1<<10)
+#define S3C2412_UCON_USYSCLK (3<<10)
+#define S3C2412_UCON_PCLK (0<<10)
+#define S3C2412_UCON_PCLK2 (2<<10)
+
+#define S3C2410_UCON_UCLK (1<<10)
+#define S3C2410_UCON_SBREAK (1<<4)
+
+#define S3C2410_UCON_TXILEVEL (1<<9)
+#define S3C2410_UCON_RXILEVEL (1<<8)
+#define S3C2410_UCON_TXIRQMODE (1<<2)
+#define S3C2410_UCON_RXIRQMODE (1<<0)
+#define S3C2410_UCON_RXFIFO_TOI (1<<7)
+#define S3C2443_UCON_RXERR_IRQEN (1<<6)
+#define S3C2443_UCON_LOOPBACK (1<<5)
+
+#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
+ S3C2410_UCON_RXILEVEL | \
+ S3C2410_UCON_TXIRQMODE | \
+ S3C2410_UCON_RXIRQMODE | \
+ S3C2410_UCON_RXFIFO_TOI)
+
+#define S3C2410_UFCON_FIFOMODE (1<<0)
+#define S3C2410_UFCON_TXTRIG0 (0<<6)
+#define S3C2410_UFCON_RXTRIG8 (1<<4)
+#define S3C2410_UFCON_RXTRIG12 (2<<4)
+
+/* S3C2440 FIFO trigger levels */
+#define S3C2440_UFCON_RXTRIG1 (0<<4)
+#define S3C2440_UFCON_RXTRIG8 (1<<4)
+#define S3C2440_UFCON_RXTRIG16 (2<<4)
+#define S3C2440_UFCON_RXTRIG32 (3<<4)
+
+#define S3C2440_UFCON_TXTRIG0 (0<<6)
+#define S3C2440_UFCON_TXTRIG16 (1<<6)
+#define S3C2440_UFCON_TXTRIG32 (2<<6)
+#define S3C2440_UFCON_TXTRIG48 (3<<6)
+
+#define S3C2410_UFCON_RESETBOTH (3<<1)
+#define S3C2410_UFCON_RESETTX (1<<2)
+#define S3C2410_UFCON_RESETRX (1<<1)
+
+#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
+ S3C2410_UFCON_TXTRIG0 | \
+ S3C2410_UFCON_RXTRIG8 )
+
+#define S3C2410_UMCOM_AFC (1<<4)
+#define S3C2410_UMCOM_RTS_LOW (1<<0)
+
+#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */
+#define S3C2412_UMCON_AFC_56 (1<<5)
+#define S3C2412_UMCON_AFC_48 (2<<5)
+#define S3C2412_UMCON_AFC_40 (3<<5)
+#define S3C2412_UMCON_AFC_32 (4<<5)
+#define S3C2412_UMCON_AFC_24 (5<<5)
+#define S3C2412_UMCON_AFC_16 (6<<5)
+#define S3C2412_UMCON_AFC_8 (7<<5)
+
+#define S3C2410_UFSTAT_TXFULL (1<<9)
+#define S3C2410_UFSTAT_RXFULL (1<<8)
+#define S3C2410_UFSTAT_TXMASK (15<<4)
+#define S3C2410_UFSTAT_TXSHIFT (4)
+#define S3C2410_UFSTAT_RXMASK (15<<0)
+#define S3C2410_UFSTAT_RXSHIFT (0)
+
+/* UFSTAT S3C24A0 */
+#define S3C24A0_UFSTAT_TXFULL (1 << 14)
+#define S3C24A0_UFSTAT_RXFULL (1 << 6)
+#define S3C24A0_UFSTAT_TXMASK (63 << 8)
+#define S3C24A0_UFSTAT_TXSHIFT (8)
+#define S3C24A0_UFSTAT_RXMASK (63)
+#define S3C24A0_UFSTAT_RXSHIFT (0)
+
+/* UFSTAT S3C2443 same as S3C2440 */
+#define S3C2440_UFSTAT_TXFULL (1<<14)
+#define S3C2440_UFSTAT_RXFULL (1<<6)
+#define S3C2440_UFSTAT_TXSHIFT (8)
+#define S3C2440_UFSTAT_RXSHIFT (0)
+#define S3C2440_UFSTAT_TXMASK (63<<8)
+#define S3C2440_UFSTAT_RXMASK (63)
+
+#define S3C2410_UTRSTAT_TXE (1<<2)
+#define S3C2410_UTRSTAT_TXFE (1<<1)
+#define S3C2410_UTRSTAT_RXDR (1<<0)
+
+#define S3C2410_UERSTAT_OVERRUN (1<<0)
+#define S3C2410_UERSTAT_FRAME (1<<2)
+#define S3C2410_UERSTAT_BREAK (1<<3)
+#define S3C2443_UERSTAT_PARITY (1<<1)
+
+#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \
+ S3C2410_UERSTAT_FRAME | \
+ S3C2410_UERSTAT_BREAK)
+
+#define S3C2410_UMSTAT_CTS (1<<0)
+#define S3C2410_UMSTAT_DeltaCTS (1<<2)
+
+#define S3C2443_DIVSLOT (0x2C)
+
+/* S3C64XX interrupt registers. */
+#define S3C64XX_UINTP 0x30
+#define S3C64XX_UINTSP 0x34
+#define S3C64XX_UINTM 0x38
+
+/* Following are specific to S5PV210 */
+#define S5PV210_UCON_CLKMASK (1<<10)
+#define S5PV210_UCON_PCLK (0<<10)
+#define S5PV210_UCON_UCLK (1<<10)
+
+#define S5PV210_UFCON_TXTRIG0 (0<<8)
+#define S5PV210_UFCON_TXTRIG4 (1<<8)
+#define S5PV210_UFCON_TXTRIG8 (2<<8)
+#define S5PV210_UFCON_TXTRIG16 (3<<8)
+#define S5PV210_UFCON_TXTRIG32 (4<<8)
+#define S5PV210_UFCON_TXTRIG64 (5<<8)
+#define S5PV210_UFCON_TXTRIG128 (6<<8)
+#define S5PV210_UFCON_TXTRIG256 (7<<8)
+
+#define S5PV210_UFCON_RXTRIG1 (0<<4)
+#define S5PV210_UFCON_RXTRIG4 (1<<4)
+#define S5PV210_UFCON_RXTRIG8 (2<<4)
+#define S5PV210_UFCON_RXTRIG16 (3<<4)
+#define S5PV210_UFCON_RXTRIG32 (4<<4)
+#define S5PV210_UFCON_RXTRIG64 (5<<4)
+#define S5PV210_UFCON_RXTRIG128 (6<<4)
+#define S5PV210_UFCON_RXTRIG256 (7<<4)
+
+#define S5PV210_UFSTAT_TXFULL (1<<24)
+#define S5PV210_UFSTAT_RXFULL (1<<8)
+#define S5PV210_UFSTAT_TXMASK (255<<16)
+#define S5PV210_UFSTAT_TXSHIFT (16)
+#define S5PV210_UFSTAT_RXMASK (255<<0)
+#define S5PV210_UFSTAT_RXSHIFT (0)
+
+#define NO_NEED_CHECK_CLKSRC 1
+
+#ifndef __ASSEMBLY__
+
+/* struct s3c24xx_uart_clksrc
+ *
+ * this structure defines a named clock source that can be used for the
+ * uart, so that the best clock can be selected for the requested baud
+ * rate.
+ *
+ * min_baud and max_baud define the range of baud-rates this clock is
+ * acceptable for, if they are both zero, it is assumed any baud rate that
+ * can be generated from this clock will be used.
+ *
+ * divisor gives the divisor from the clock to the one seen by the uart
+*/
+
+struct s3c24xx_uart_clksrc {
+ const char *name;
+ unsigned int divisor;
+ unsigned int min_baud;
+ unsigned int max_baud;
+};
+
+/* configuration structure for per-machine configurations for the
+ * serial port
+ *
+ * the pointer is setup by the machine specific initialisation from the
+ * arch/arm/mach-s3c2410/ directory.
+*/
+
+struct s3c2410_uartcfg {
+ unsigned char hwport; /* hardware port number */
+ unsigned char unused;
+ unsigned short flags;
+ upf_t uart_flags; /* default uart flags */
+
+ unsigned int has_fracval;
+
+ unsigned long ucon; /* value of ucon for port */
+ unsigned long ulcon; /* value of ulcon for port */
+ unsigned long ufcon; /* value of ufcon for port */
+
+ struct s3c24xx_uart_clksrc *clocks;
+ unsigned int clocks_size;
+};
+
+/* s3c24xx_uart_devs
+ *
+ * this is exported from the core as we cannot use driver_register(),
+ * or platform_add_device() before the console_initcall()
+*/
+
+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-timer.h b/arch/arm/plat-samsung/include/plat/regs-timer.h
new file mode 100644
index 00000000..d097d92f
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-timer.h
@@ -0,0 +1,124 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-timer.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Timer configuration
+*/
+
+#ifndef __ASM_ARCH_REGS_TIMER_H
+#define __ASM_ARCH_REGS_TIMER_H
+
+#define S3C_TIMERREG(x) (S3C_VA_TIMER + (x))
+#define S3C_TIMERREG2(tmr,reg) S3C_TIMERREG((reg)+0x0c+((tmr)*0x0c))
+
+#define S3C2410_TCFG0 S3C_TIMERREG(0x00)
+#define S3C2410_TCFG1 S3C_TIMERREG(0x04)
+#define S3C2410_TCON S3C_TIMERREG(0x08)
+
+#define S3C64XX_TINT_CSTAT S3C_TIMERREG(0x44)
+
+#define S3C2410_TCFG_PRESCALER0_MASK (255<<0)
+#define S3C2410_TCFG_PRESCALER1_MASK (255<<8)
+#define S3C2410_TCFG_PRESCALER1_SHIFT (8)
+#define S3C2410_TCFG_DEADZONE_MASK (255<<16)
+#define S3C2410_TCFG_DEADZONE_SHIFT (16)
+
+#define S3C2410_TCFG1_MUX4_DIV2 (0<<16)
+#define S3C2410_TCFG1_MUX4_DIV4 (1<<16)
+#define S3C2410_TCFG1_MUX4_DIV8 (2<<16)
+#define S3C2410_TCFG1_MUX4_DIV16 (3<<16)
+#define S3C2410_TCFG1_MUX4_TCLK1 (4<<16)
+#define S3C2410_TCFG1_MUX4_MASK (15<<16)
+#define S3C2410_TCFG1_MUX4_SHIFT (16)
+
+#define S3C2410_TCFG1_MUX3_DIV2 (0<<12)
+#define S3C2410_TCFG1_MUX3_DIV4 (1<<12)
+#define S3C2410_TCFG1_MUX3_DIV8 (2<<12)
+#define S3C2410_TCFG1_MUX3_DIV16 (3<<12)
+#define S3C2410_TCFG1_MUX3_TCLK1 (4<<12)
+#define S3C2410_TCFG1_MUX3_MASK (15<<12)
+
+
+#define S3C2410_TCFG1_MUX2_DIV2 (0<<8)
+#define S3C2410_TCFG1_MUX2_DIV4 (1<<8)
+#define S3C2410_TCFG1_MUX2_DIV8 (2<<8)
+#define S3C2410_TCFG1_MUX2_DIV16 (3<<8)
+#define S3C2410_TCFG1_MUX2_TCLK1 (4<<8)
+#define S3C2410_TCFG1_MUX2_MASK (15<<8)
+
+
+#define S3C2410_TCFG1_MUX1_DIV2 (0<<4)
+#define S3C2410_TCFG1_MUX1_DIV4 (1<<4)
+#define S3C2410_TCFG1_MUX1_DIV8 (2<<4)
+#define S3C2410_TCFG1_MUX1_DIV16 (3<<4)
+#define S3C2410_TCFG1_MUX1_TCLK0 (4<<4)
+#define S3C2410_TCFG1_MUX1_MASK (15<<4)
+
+#define S3C2410_TCFG1_MUX0_DIV2 (0<<0)
+#define S3C2410_TCFG1_MUX0_DIV4 (1<<0)
+#define S3C2410_TCFG1_MUX0_DIV8 (2<<0)
+#define S3C2410_TCFG1_MUX0_DIV16 (3<<0)
+#define S3C2410_TCFG1_MUX0_TCLK0 (4<<0)
+#define S3C2410_TCFG1_MUX0_MASK (15<<0)
+
+#define S3C2410_TCFG1_MUX_DIV2 (0<<0)
+#define S3C2410_TCFG1_MUX_DIV4 (1<<0)
+#define S3C2410_TCFG1_MUX_DIV8 (2<<0)
+#define S3C2410_TCFG1_MUX_DIV16 (3<<0)
+#define S3C2410_TCFG1_MUX_TCLK (4<<0)
+#define S3C2410_TCFG1_MUX_MASK (15<<0)
+
+#define S3C64XX_TCFG1_MUX_DIV1 (0<<0)
+#define S3C64XX_TCFG1_MUX_DIV2 (1<<0)
+#define S3C64XX_TCFG1_MUX_DIV4 (2<<0)
+#define S3C64XX_TCFG1_MUX_DIV8 (3<<0)
+#define S3C64XX_TCFG1_MUX_DIV16 (4<<0)
+#define S3C64XX_TCFG1_MUX_TCLK (5<<0) /* 3 sets of TCLK */
+#define S3C64XX_TCFG1_MUX_MASK (15<<0)
+
+#define S3C2410_TCFG1_SHIFT(x) ((x) * 4)
+
+/* for each timer, we have an count buffer, an compare buffer and
+ * an observation buffer
+*/
+
+/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
+
+#define S3C2410_TCNTB(tmr) S3C_TIMERREG2(tmr, 0x00)
+#define S3C2410_TCMPB(tmr) S3C_TIMERREG2(tmr, 0x04)
+#define S3C2410_TCNTO(tmr) S3C_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
+
+#define S3C2410_TCON_T4RELOAD (1<<22)
+#define S3C2410_TCON_T4MANUALUPD (1<<21)
+#define S3C2410_TCON_T4START (1<<20)
+
+#define S3C2410_TCON_T3RELOAD (1<<19)
+#define S3C2410_TCON_T3INVERT (1<<18)
+#define S3C2410_TCON_T3MANUALUPD (1<<17)
+#define S3C2410_TCON_T3START (1<<16)
+
+#define S3C2410_TCON_T2RELOAD (1<<15)
+#define S3C2410_TCON_T2INVERT (1<<14)
+#define S3C2410_TCON_T2MANUALUPD (1<<13)
+#define S3C2410_TCON_T2START (1<<12)
+
+#define S3C2410_TCON_T1RELOAD (1<<11)
+#define S3C2410_TCON_T1INVERT (1<<10)
+#define S3C2410_TCON_T1MANUALUPD (1<<9)
+#define S3C2410_TCON_T1START (1<<8)
+
+#define S3C2410_TCON_T0DEADZONE (1<<4)
+#define S3C2410_TCON_T0RELOAD (1<<3)
+#define S3C2410_TCON_T0INVERT (1<<2)
+#define S3C2410_TCON_T0MANUALUPD (1<<1)
+#define S3C2410_TCON_T0START (1<<0)
+
+#endif /* __ASM_ARCH_REGS_TIMER_H */
+
+
+
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
new file mode 100644
index 00000000..a111ad87
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg-phy.h
@@ -0,0 +1,50 @@
+/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg-phy.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB2.0 Highspeed/OtG device 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.
+*/
+
+/* Note, this is a separate header file as some of the clock framework
+ * needs to touch this if the clk_48m is used as the USB OHCI or other
+ * peripheral source.
+*/
+
+#ifndef __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H
+#define __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H __FILE__
+
+/* S3C64XX_PA_USB_HSPHY */
+
+#define S3C_HSOTG_PHYREG(x) ((x) + S3C_VA_USB_HSPHY)
+
+#define S3C_PHYPWR S3C_HSOTG_PHYREG(0x00)
+#define SRC_PHYPWR_OTG_DISABLE (1 << 4)
+#define SRC_PHYPWR_ANALOG_POWERDOWN (1 << 3)
+#define SRC_PHYPWR_FORCE_SUSPEND (1 << 1)
+
+#define S3C_PHYCLK S3C_HSOTG_PHYREG(0x04)
+#define S3C_PHYCLK_MODE_USB11 (1 << 6)
+#define S3C_PHYCLK_EXT_OSC (1 << 5)
+#define S3C_PHYCLK_CLK_FORCE (1 << 4)
+#define S3C_PHYCLK_ID_PULL (1 << 2)
+#define S3C_PHYCLK_CLKSEL_MASK (0x3 << 0)
+#define S3C_PHYCLK_CLKSEL_SHIFT (0)
+#define S3C_PHYCLK_CLKSEL_48M (0x0 << 0)
+#define S3C_PHYCLK_CLKSEL_12M (0x2 << 0)
+#define S3C_PHYCLK_CLKSEL_24M (0x3 << 0)
+
+#define S3C_RSTCON S3C_HSOTG_PHYREG(0x08)
+#define S3C_RSTCON_PHYCLK (1 << 2)
+#define S3C_RSTCON_HCLK (1 << 2)
+#define S3C_RSTCON_PHY (1 << 0)
+
+#define S3C_PHYTUNE S3C_HSOTG_PHYREG(0x20)
+
+#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_PHY_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
new file mode 100644
index 00000000..dc90f5ed
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-usb-hsotg.h
@@ -0,0 +1,379 @@
+/* arch/arm/plat-s3c/include/plat/regs-usb-hsotg.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB2.0 Highspeed/OtG device block 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_S3C64XX_REGS_USB_HSOTG_H
+#define __PLAT_S3C64XX_REGS_USB_HSOTG_H __FILE__
+
+#define S3C_HSOTG_REG(x) (x)
+
+#define S3C_GOTGCTL S3C_HSOTG_REG(0x000)
+#define S3C_GOTGCTL_BSESVLD (1 << 19)
+#define S3C_GOTGCTL_ASESVLD (1 << 18)
+#define S3C_GOTGCTL_DBNC_SHORT (1 << 17)
+#define S3C_GOTGCTL_CONID_B (1 << 16)
+#define S3C_GOTGCTL_DEVHNPEN (1 << 11)
+#define S3C_GOTGCTL_HSSETHNPEN (1 << 10)
+#define S3C_GOTGCTL_HNPREQ (1 << 9)
+#define S3C_GOTGCTL_HSTNEGSCS (1 << 8)
+#define S3C_GOTGCTL_SESREQ (1 << 1)
+#define S3C_GOTGCTL_SESREQSCS (1 << 0)
+
+#define S3C_GOTGINT S3C_HSOTG_REG(0x004)
+#define S3C_GOTGINT_DbnceDone (1 << 19)
+#define S3C_GOTGINT_ADevTOUTChg (1 << 18)
+#define S3C_GOTGINT_HstNegDet (1 << 17)
+#define S3C_GOTGINT_HstnegSucStsChng (1 << 9)
+#define S3C_GOTGINT_SesReqSucStsChng (1 << 8)
+#define S3C_GOTGINT_SesEndDet (1 << 2)
+
+#define S3C_GAHBCFG S3C_HSOTG_REG(0x008)
+#define S3C_GAHBCFG_PTxFEmpLvl (1 << 8)
+#define S3C_GAHBCFG_NPTxFEmpLvl (1 << 7)
+#define S3C_GAHBCFG_DMAEn (1 << 5)
+#define S3C_GAHBCFG_HBstLen_MASK (0xf << 1)
+#define S3C_GAHBCFG_HBstLen_SHIFT (1)
+#define S3C_GAHBCFG_HBstLen_Single (0x0 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr (0x1 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr4 (0x3 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr8 (0x5 << 1)
+#define S3C_GAHBCFG_HBstLen_Incr16 (0x7 << 1)
+#define S3C_GAHBCFG_GlblIntrEn (1 << 0)
+
+#define S3C_GUSBCFG S3C_HSOTG_REG(0x00C)
+#define S3C_GUSBCFG_PHYLPClkSel (1 << 15)
+#define S3C_GUSBCFG_HNPCap (1 << 9)
+#define S3C_GUSBCFG_SRPCap (1 << 8)
+#define S3C_GUSBCFG_PHYIf16 (1 << 3)
+#define S3C_GUSBCFG_TOutCal_MASK (0x7 << 0)
+#define S3C_GUSBCFG_TOutCal_SHIFT (0)
+#define S3C_GUSBCFG_TOutCal_LIMIT (0x7)
+#define S3C_GUSBCFG_TOutCal(_x) ((_x) << 0)
+
+#define S3C_GRSTCTL S3C_HSOTG_REG(0x010)
+
+#define S3C_GRSTCTL_AHBIdle (1 << 31)
+#define S3C_GRSTCTL_DMAReq (1 << 30)
+#define S3C_GRSTCTL_TxFNum_MASK (0x1f << 6)
+#define S3C_GRSTCTL_TxFNum_SHIFT (6)
+#define S3C_GRSTCTL_TxFNum_LIMIT (0x1f)
+#define S3C_GRSTCTL_TxFNum(_x) ((_x) << 6)
+#define S3C_GRSTCTL_TxFFlsh (1 << 5)
+#define S3C_GRSTCTL_RxFFlsh (1 << 4)
+#define S3C_GRSTCTL_INTknQFlsh (1 << 3)
+#define S3C_GRSTCTL_FrmCntrRst (1 << 2)
+#define S3C_GRSTCTL_HSftRst (1 << 1)
+#define S3C_GRSTCTL_CSftRst (1 << 0)
+
+#define S3C_GINTSTS S3C_HSOTG_REG(0x014)
+#define S3C_GINTMSK S3C_HSOTG_REG(0x018)
+
+#define S3C_GINTSTS_WkUpInt (1 << 31)
+#define S3C_GINTSTS_SessReqInt (1 << 30)
+#define S3C_GINTSTS_DisconnInt (1 << 29)
+#define S3C_GINTSTS_ConIDStsChng (1 << 28)
+#define S3C_GINTSTS_PTxFEmp (1 << 26)
+#define S3C_GINTSTS_HChInt (1 << 25)
+#define S3C_GINTSTS_PrtInt (1 << 24)
+#define S3C_GINTSTS_FetSusp (1 << 22)
+#define S3C_GINTSTS_incompIP (1 << 21)
+#define S3C_GINTSTS_IncomplSOIN (1 << 20)
+#define S3C_GINTSTS_OEPInt (1 << 19)
+#define S3C_GINTSTS_IEPInt (1 << 18)
+#define S3C_GINTSTS_EPMis (1 << 17)
+#define S3C_GINTSTS_EOPF (1 << 15)
+#define S3C_GINTSTS_ISOutDrop (1 << 14)
+#define S3C_GINTSTS_EnumDone (1 << 13)
+#define S3C_GINTSTS_USBRst (1 << 12)
+#define S3C_GINTSTS_USBSusp (1 << 11)
+#define S3C_GINTSTS_ErlySusp (1 << 10)
+#define S3C_GINTSTS_GOUTNakEff (1 << 7)
+#define S3C_GINTSTS_GINNakEff (1 << 6)
+#define S3C_GINTSTS_NPTxFEmp (1 << 5)
+#define S3C_GINTSTS_RxFLvl (1 << 4)
+#define S3C_GINTSTS_SOF (1 << 3)
+#define S3C_GINTSTS_OTGInt (1 << 2)
+#define S3C_GINTSTS_ModeMis (1 << 1)
+#define S3C_GINTSTS_CurMod_Host (1 << 0)
+
+#define S3C_GRXSTSR S3C_HSOTG_REG(0x01C)
+#define S3C_GRXSTSP S3C_HSOTG_REG(0x020)
+
+#define S3C_GRXSTS_FN_MASK (0x7f << 25)
+#define S3C_GRXSTS_FN_SHIFT (25)
+
+#define S3C_GRXSTS_PktSts_MASK (0xf << 17)
+#define S3C_GRXSTS_PktSts_SHIFT (17)
+#define S3C_GRXSTS_PktSts_GlobalOutNAK (0x1 << 17)
+#define S3C_GRXSTS_PktSts_OutRX (0x2 << 17)
+#define S3C_GRXSTS_PktSts_OutDone (0x3 << 17)
+#define S3C_GRXSTS_PktSts_SetupDone (0x4 << 17)
+#define S3C_GRXSTS_PktSts_SetupRX (0x6 << 17)
+
+#define S3C_GRXSTS_DPID_MASK (0x3 << 15)
+#define S3C_GRXSTS_DPID_SHIFT (15)
+#define S3C_GRXSTS_ByteCnt_MASK (0x7ff << 4)
+#define S3C_GRXSTS_ByteCnt_SHIFT (4)
+#define S3C_GRXSTS_EPNum_MASK (0xf << 0)
+#define S3C_GRXSTS_EPNum_SHIFT (0)
+
+#define S3C_GRXFSIZ S3C_HSOTG_REG(0x024)
+
+#define S3C_GNPTXFSIZ S3C_HSOTG_REG(0x028)
+
+#define S3C_GNPTXFSIZ_NPTxFDep_MASK (0xffff << 16)
+#define S3C_GNPTXFSIZ_NPTxFDep_SHIFT (16)
+#define S3C_GNPTXFSIZ_NPTxFDep_LIMIT (0xffff)
+#define S3C_GNPTXFSIZ_NPTxFDep(_x) ((_x) << 16)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_MASK (0xffff << 0)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_SHIFT (0)
+#define S3C_GNPTXFSIZ_NPTxFStAddr_LIMIT (0xffff)
+#define S3C_GNPTXFSIZ_NPTxFStAddr(_x) ((_x) << 0)
+
+#define S3C_GNPTXSTS S3C_HSOTG_REG(0x02C)
+
+#define S3C_GNPTXSTS_NPtxQTop_MASK (0x7f << 24)
+#define S3C_GNPTXSTS_NPtxQTop_SHIFT (24)
+
+#define S3C_GNPTXSTS_NPTxQSpcAvail_MASK (0xff << 16)
+#define S3C_GNPTXSTS_NPTxQSpcAvail_SHIFT (16)
+#define S3C_GNPTXSTS_NPTxQSpcAvail_GET(_v) (((_v) >> 16) & 0xff)
+
+#define S3C_GNPTXSTS_NPTxFSpcAvail_MASK (0xffff << 0)
+#define S3C_GNPTXSTS_NPTxFSpcAvail_SHIFT (0)
+#define S3C_GNPTXSTS_NPTxFSpcAvail_GET(_v) (((_v) >> 0) & 0xffff)
+
+
+#define S3C_HPTXFSIZ S3C_HSOTG_REG(0x100)
+
+#define S3C_DPTXFSIZn(_a) S3C_HSOTG_REG(0x104 + (((_a) - 1) * 4))
+
+#define S3C_DPTXFSIZn_DPTxFSize_MASK (0xffff << 16)
+#define S3C_DPTXFSIZn_DPTxFSize_SHIFT (16)
+#define S3C_DPTXFSIZn_DPTxFSize_GET(_v) (((_v) >> 16) & 0xffff)
+#define S3C_DPTXFSIZn_DPTxFSize_LIMIT (0xffff)
+#define S3C_DPTXFSIZn_DPTxFSize(_x) ((_x) << 16)
+
+#define S3C_DPTXFSIZn_DPTxFStAddr_MASK (0xffff << 0)
+#define S3C_DPTXFSIZn_DPTxFStAddr_SHIFT (0)
+
+/* Device mode registers */
+#define S3C_DCFG S3C_HSOTG_REG(0x800)
+
+#define S3C_DCFG_EPMisCnt_MASK (0x1f << 18)
+#define S3C_DCFG_EPMisCnt_SHIFT (18)
+#define S3C_DCFG_EPMisCnt_LIMIT (0x1f)
+#define S3C_DCFG_EPMisCnt(_x) ((_x) << 18)
+
+#define S3C_DCFG_PerFrInt_MASK (0x3 << 11)
+#define S3C_DCFG_PerFrInt_SHIFT (11)
+#define S3C_DCFG_PerFrInt_LIMIT (0x3)
+#define S3C_DCFG_PerFrInt(_x) ((_x) << 11)
+
+#define S3C_DCFG_DevAddr_MASK (0x7f << 4)
+#define S3C_DCFG_DevAddr_SHIFT (4)
+#define S3C_DCFG_DevAddr_LIMIT (0x7f)
+#define S3C_DCFG_DevAddr(_x) ((_x) << 4)
+
+#define S3C_DCFG_NZStsOUTHShk (1 << 2)
+
+#define S3C_DCFG_DevSpd_MASK (0x3 << 0)
+#define S3C_DCFG_DevSpd_SHIFT (0)
+#define S3C_DCFG_DevSpd_HS (0x0 << 0)
+#define S3C_DCFG_DevSpd_FS (0x1 << 0)
+#define S3C_DCFG_DevSpd_LS (0x2 << 0)
+#define S3C_DCFG_DevSpd_FS48 (0x3 << 0)
+
+#define S3C_DCTL S3C_HSOTG_REG(0x804)
+
+#define S3C_DCTL_PWROnPrgDone (1 << 11)
+#define S3C_DCTL_CGOUTNak (1 << 10)
+#define S3C_DCTL_SGOUTNak (1 << 9)
+#define S3C_DCTL_CGNPInNAK (1 << 8)
+#define S3C_DCTL_SGNPInNAK (1 << 7)
+#define S3C_DCTL_TstCtl_MASK (0x7 << 4)
+#define S3C_DCTL_TstCtl_SHIFT (4)
+#define S3C_DCTL_GOUTNakSts (1 << 3)
+#define S3C_DCTL_GNPINNakSts (1 << 2)
+#define S3C_DCTL_SftDiscon (1 << 1)
+#define S3C_DCTL_RmtWkUpSig (1 << 0)
+
+#define S3C_DSTS S3C_HSOTG_REG(0x808)
+
+#define S3C_DSTS_SOFFN_MASK (0x3fff << 8)
+#define S3C_DSTS_SOFFN_SHIFT (8)
+#define S3C_DSTS_SOFFN_LIMIT (0x3fff)
+#define S3C_DSTS_SOFFN(_x) ((_x) << 8)
+#define S3C_DSTS_ErraticErr (1 << 3)
+#define S3C_DSTS_EnumSpd_MASK (0x3 << 1)
+#define S3C_DSTS_EnumSpd_SHIFT (1)
+#define S3C_DSTS_EnumSpd_HS (0x0 << 1)
+#define S3C_DSTS_EnumSpd_FS (0x1 << 1)
+#define S3C_DSTS_EnumSpd_LS (0x2 << 1)
+#define S3C_DSTS_EnumSpd_FS48 (0x3 << 1)
+
+#define S3C_DSTS_SuspSts (1 << 0)
+
+#define S3C_DIEPMSK S3C_HSOTG_REG(0x810)
+
+#define S3C_DIEPMSK_TxFIFOEmpty (1 << 7)
+#define S3C_DIEPMSK_INEPNakEffMsk (1 << 6)
+#define S3C_DIEPMSK_INTknEPMisMsk (1 << 5)
+#define S3C_DIEPMSK_INTknTXFEmpMsk (1 << 4)
+#define S3C_DIEPMSK_TimeOUTMsk (1 << 3)
+#define S3C_DIEPMSK_AHBErrMsk (1 << 2)
+#define S3C_DIEPMSK_EPDisbldMsk (1 << 1)
+#define S3C_DIEPMSK_XferComplMsk (1 << 0)
+
+#define S3C_DOEPMSK S3C_HSOTG_REG(0x814)
+
+#define S3C_DOEPMSK_Back2BackSetup (1 << 6)
+#define S3C_DOEPMSK_OUTTknEPdisMsk (1 << 4)
+#define S3C_DOEPMSK_SetupMsk (1 << 3)
+#define S3C_DOEPMSK_AHBErrMsk (1 << 2)
+#define S3C_DOEPMSK_EPDisbldMsk (1 << 1)
+#define S3C_DOEPMSK_XferComplMsk (1 << 0)
+
+#define S3C_DAINT S3C_HSOTG_REG(0x818)
+#define S3C_DAINTMSK S3C_HSOTG_REG(0x81C)
+
+#define S3C_DAINT_OutEP_SHIFT (16)
+#define S3C_DAINT_OutEP(x) (1 << ((x) + 16))
+#define S3C_DAINT_InEP(x) (1 << (x))
+
+#define S3C_DTKNQR1 S3C_HSOTG_REG(0x820)
+#define S3C_DTKNQR2 S3C_HSOTG_REG(0x824)
+#define S3C_DTKNQR3 S3C_HSOTG_REG(0x830)
+#define S3C_DTKNQR4 S3C_HSOTG_REG(0x834)
+
+#define S3C_DVBUSDIS S3C_HSOTG_REG(0x828)
+#define S3C_DVBUSPULSE S3C_HSOTG_REG(0x82C)
+
+#define S3C_DIEPCTL0 S3C_HSOTG_REG(0x900)
+#define S3C_DOEPCTL0 S3C_HSOTG_REG(0xB00)
+#define S3C_DIEPCTL(_a) S3C_HSOTG_REG(0x900 + ((_a) * 0x20))
+#define S3C_DOEPCTL(_a) S3C_HSOTG_REG(0xB00 + ((_a) * 0x20))
+
+/* EP0 specialness:
+ * bits[29..28] - reserved (no SetD0PID, SetD1PID)
+ * bits[25..22] - should always be zero, this isn't a periodic endpoint
+ * bits[10..0] - MPS setting differenct for EP0
+*/
+#define S3C_D0EPCTL_MPS_MASK (0x3 << 0)
+#define S3C_D0EPCTL_MPS_SHIFT (0)
+#define S3C_D0EPCTL_MPS_64 (0x0 << 0)
+#define S3C_D0EPCTL_MPS_32 (0x1 << 0)
+#define S3C_D0EPCTL_MPS_16 (0x2 << 0)
+#define S3C_D0EPCTL_MPS_8 (0x3 << 0)
+
+#define S3C_DxEPCTL_EPEna (1 << 31)
+#define S3C_DxEPCTL_EPDis (1 << 30)
+#define S3C_DxEPCTL_SetD1PID (1 << 29)
+#define S3C_DxEPCTL_SetOddFr (1 << 29)
+#define S3C_DxEPCTL_SetD0PID (1 << 28)
+#define S3C_DxEPCTL_SetEvenFr (1 << 28)
+#define S3C_DxEPCTL_SNAK (1 << 27)
+#define S3C_DxEPCTL_CNAK (1 << 26)
+#define S3C_DxEPCTL_TxFNum_MASK (0xf << 22)
+#define S3C_DxEPCTL_TxFNum_SHIFT (22)
+#define S3C_DxEPCTL_TxFNum_LIMIT (0xf)
+#define S3C_DxEPCTL_TxFNum(_x) ((_x) << 22)
+
+#define S3C_DxEPCTL_Stall (1 << 21)
+#define S3C_DxEPCTL_Snp (1 << 20)
+#define S3C_DxEPCTL_EPType_MASK (0x3 << 18)
+#define S3C_DxEPCTL_EPType_SHIFT (18)
+#define S3C_DxEPCTL_EPType_Control (0x0 << 18)
+#define S3C_DxEPCTL_EPType_Iso (0x1 << 18)
+#define S3C_DxEPCTL_EPType_Bulk (0x2 << 18)
+#define S3C_DxEPCTL_EPType_Intterupt (0x3 << 18)
+
+#define S3C_DxEPCTL_NAKsts (1 << 17)
+#define S3C_DxEPCTL_DPID (1 << 16)
+#define S3C_DxEPCTL_EOFrNum (1 << 16)
+#define S3C_DxEPCTL_USBActEp (1 << 15)
+#define S3C_DxEPCTL_NextEp_MASK (0xf << 11)
+#define S3C_DxEPCTL_NextEp_SHIFT (11)
+#define S3C_DxEPCTL_NextEp_LIMIT (0xf)
+#define S3C_DxEPCTL_NextEp(_x) ((_x) << 11)
+
+#define S3C_DxEPCTL_MPS_MASK (0x7ff << 0)
+#define S3C_DxEPCTL_MPS_SHIFT (0)
+#define S3C_DxEPCTL_MPS_LIMIT (0x7ff)
+#define S3C_DxEPCTL_MPS(_x) ((_x) << 0)
+
+#define S3C_DIEPINT(_a) S3C_HSOTG_REG(0x908 + ((_a) * 0x20))
+#define S3C_DOEPINT(_a) S3C_HSOTG_REG(0xB08 + ((_a) * 0x20))
+
+#define S3C_DxEPINT_INEPNakEff (1 << 6)
+#define S3C_DxEPINT_Back2BackSetup (1 << 6)
+#define S3C_DxEPINT_INTknEPMis (1 << 5)
+#define S3C_DxEPINT_INTknTXFEmp (1 << 4)
+#define S3C_DxEPINT_OUTTknEPdis (1 << 4)
+#define S3C_DxEPINT_Timeout (1 << 3)
+#define S3C_DxEPINT_Setup (1 << 3)
+#define S3C_DxEPINT_AHBErr (1 << 2)
+#define S3C_DxEPINT_EPDisbld (1 << 1)
+#define S3C_DxEPINT_XferCompl (1 << 0)
+
+#define S3C_DIEPTSIZ0 S3C_HSOTG_REG(0x910)
+
+#define S3C_DIEPTSIZ0_PktCnt_MASK (0x3 << 19)
+#define S3C_DIEPTSIZ0_PktCnt_SHIFT (19)
+#define S3C_DIEPTSIZ0_PktCnt_LIMIT (0x3)
+#define S3C_DIEPTSIZ0_PktCnt(_x) ((_x) << 19)
+
+#define S3C_DIEPTSIZ0_XferSize_MASK (0x7f << 0)
+#define S3C_DIEPTSIZ0_XferSize_SHIFT (0)
+#define S3C_DIEPTSIZ0_XferSize_LIMIT (0x7f)
+#define S3C_DIEPTSIZ0_XferSize(_x) ((_x) << 0)
+
+
+#define DOEPTSIZ0 S3C_HSOTG_REG(0xB10)
+#define S3C_DOEPTSIZ0_SUPCnt_MASK (0x3 << 29)
+#define S3C_DOEPTSIZ0_SUPCnt_SHIFT (29)
+#define S3C_DOEPTSIZ0_SUPCnt_LIMIT (0x3)
+#define S3C_DOEPTSIZ0_SUPCnt(_x) ((_x) << 29)
+
+#define S3C_DOEPTSIZ0_PktCnt (1 << 19)
+#define S3C_DOEPTSIZ0_XferSize_MASK (0x7f << 0)
+#define S3C_DOEPTSIZ0_XferSize_SHIFT (0)
+
+#define S3C_DIEPTSIZ(_a) S3C_HSOTG_REG(0x910 + ((_a) * 0x20))
+#define S3C_DOEPTSIZ(_a) S3C_HSOTG_REG(0xB10 + ((_a) * 0x20))
+
+#define S3C_DxEPTSIZ_MC_MASK (0x3 << 29)
+#define S3C_DxEPTSIZ_MC_SHIFT (29)
+#define S3C_DxEPTSIZ_MC_LIMIT (0x3)
+#define S3C_DxEPTSIZ_MC(_x) ((_x) << 29)
+
+#define S3C_DxEPTSIZ_PktCnt_MASK (0x3ff << 19)
+#define S3C_DxEPTSIZ_PktCnt_SHIFT (19)
+#define S3C_DxEPTSIZ_PktCnt_GET(_v) (((_v) >> 19) & 0x3ff)
+#define S3C_DxEPTSIZ_PktCnt_LIMIT (0x3ff)
+#define S3C_DxEPTSIZ_PktCnt(_x) ((_x) << 19)
+
+#define S3C_DxEPTSIZ_XferSize_MASK (0x7ffff << 0)
+#define S3C_DxEPTSIZ_XferSize_SHIFT (0)
+#define S3C_DxEPTSIZ_XferSize_GET(_v) (((_v) >> 0) & 0x7ffff)
+#define S3C_DxEPTSIZ_XferSize_LIMIT (0x7ffff)
+#define S3C_DxEPTSIZ_XferSize(_x) ((_x) << 0)
+
+
+#define S3C_DIEPDMA(_a) S3C_HSOTG_REG(0x914 + ((_a) * 0x20))
+#define S3C_DOEPDMA(_a) S3C_HSOTG_REG(0xB14 + ((_a) * 0x20))
+#define S3C_DTXFSTS(_a) S3C_HSOTG_REG(0x918 + ((_a) * 0x20))
+
+#define S3C_EPFIFO(_a) S3C_HSOTG_REG(0x1000 + ((_a) * 0x1000))
+
+#endif /* __PLAT_S3C64XX_REGS_USB_HSOTG_H */
diff --git a/arch/arm/plat-samsung/include/plat/regs-watchdog.h b/arch/arm/plat-samsung/include/plat/regs-watchdog.h
new file mode 100644
index 00000000..49384924
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-watchdog.h
@@ -0,0 +1,41 @@
+/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h
+ *
+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
+ * http://www.simtec.co.uk/products/SWLINUX/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2410 Watchdog timer control
+*/
+
+
+#ifndef __ASM_ARCH_REGS_WATCHDOG_H
+#define __ASM_ARCH_REGS_WATCHDOG_H
+
+#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG)
+
+#define S3C2410_WTCON S3C_WDOGREG(0x00)
+#define S3C2410_WTDAT S3C_WDOGREG(0x04)
+#define S3C2410_WTCNT S3C_WDOGREG(0x08)
+
+/* the watchdog can either generate a reset pulse, or an
+ * interrupt.
+ */
+
+#define S3C2410_WTCON_RSTEN (0x01)
+#define S3C2410_WTCON_INTEN (1<<2)
+#define S3C2410_WTCON_ENABLE (1<<5)
+
+#define S3C2410_WTCON_DIV16 (0<<3)
+#define S3C2410_WTCON_DIV32 (1<<3)
+#define S3C2410_WTCON_DIV64 (2<<3)
+#define S3C2410_WTCON_DIV128 (3<<3)
+
+#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
+#define S3C2410_WTCON_PRESCALE_MASK (0xff00)
+
+#endif /* __ASM_ARCH_REGS_WATCHDOG_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
new file mode 100644
index 00000000..81074421
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-dma-pl330.h
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+
+#ifndef __S3C_DMA_PL330_H_
+#define __S3C_DMA_PL330_H_
+
+#define S3C2410_DMAF_AUTOSTART (1 << 0)
+#define S3C2410_DMAF_CIRCULAR (1 << 1)
+
+/*
+ * PL330 can assign any channel to communicate with
+ * any of the peripherals attched to the DMAC.
+ * For the sake of consistency across client drivers,
+ * We keep the channel names unchanged and only add
+ * missing peripherals are added.
+ * Order is not important since S3C PL330 API driver
+ * use these just as IDs.
+ */
+enum dma_ch {
+ DMACH_UART0_RX,
+ DMACH_UART0_TX,
+ DMACH_UART1_RX,
+ DMACH_UART1_TX,
+ DMACH_UART2_RX,
+ DMACH_UART2_TX,
+ DMACH_UART3_RX,
+ DMACH_UART3_TX,
+ DMACH_UART4_RX,
+ DMACH_UART4_TX,
+ DMACH_UART5_RX,
+ DMACH_UART5_TX,
+ DMACH_USI_RX,
+ DMACH_USI_TX,
+ DMACH_IRDA,
+ DMACH_I2S0_RX,
+ DMACH_I2S0_TX,
+ DMACH_I2S0S_TX,
+ DMACH_I2S1_RX,
+ DMACH_I2S1_TX,
+ DMACH_I2S2_RX,
+ DMACH_I2S2_TX,
+ DMACH_SPI0_RX,
+ DMACH_SPI0_TX,
+ DMACH_SPI1_RX,
+ DMACH_SPI1_TX,
+ DMACH_SPI2_RX,
+ DMACH_SPI2_TX,
+ DMACH_AC97_MICIN,
+ DMACH_AC97_PCMIN,
+ DMACH_AC97_PCMOUT,
+ DMACH_EXTERNAL,
+ DMACH_PWM,
+ DMACH_SPDIF,
+ DMACH_HSI_RX,
+ DMACH_HSI_TX,
+ DMACH_PCM0_TX,
+ DMACH_PCM0_RX,
+ DMACH_PCM1_TX,
+ DMACH_PCM1_RX,
+ DMACH_PCM2_TX,
+ DMACH_PCM2_RX,
+ DMACH_MSM_REQ3,
+ DMACH_MSM_REQ2,
+ DMACH_MSM_REQ1,
+ DMACH_MSM_REQ0,
+ DMACH_SLIMBUS0_RX,
+ DMACH_SLIMBUS0_TX,
+ DMACH_SLIMBUS0AUX_RX,
+ DMACH_SLIMBUS0AUX_TX,
+ DMACH_SLIMBUS1_RX,
+ DMACH_SLIMBUS1_TX,
+ DMACH_SLIMBUS2_RX,
+ DMACH_SLIMBUS2_TX,
+ DMACH_SLIMBUS3_RX,
+ DMACH_SLIMBUS3_TX,
+ DMACH_SLIMBUS4_RX,
+ DMACH_SLIMBUS4_TX,
+ DMACH_SLIMBUS5_RX,
+ DMACH_SLIMBUS5_TX,
+ /* END Marker, also used to denote a reserved channel */
+ DMACH_MAX,
+};
+
+static inline bool s3c_dma_has_circular(void)
+{
+ return true;
+}
+
+#include <plat/dma.h>
+
+#endif /* __S3C_DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
new file mode 100644
index 00000000..bf5e2a9d
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.h
@@ -0,0 +1,32 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c-pl330-pdata.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __S3C_PL330_PDATA_H
+#define __S3C_PL330_PDATA_H
+
+#include <plat/s3c-dma-pl330.h>
+
+/*
+ * Every PL330 DMAC has max 32 peripheral interfaces,
+ * of which some may be not be really used in your
+ * DMAC's configuration.
+ * Populate this array of 32 peri i/fs with relevant
+ * channel IDs for used peri i/f and DMACH_MAX for
+ * those unused.
+ *
+ * The platforms just need to provide this info
+ * to the S3C DMA API driver for PL330.
+ */
+struct s3c_pl330_platdata {
+ enum dma_ch peri[32];
+};
+
+#endif /* __S3C_PL330_PDATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
new file mode 100644
index 00000000..4c16fa36
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
@@ -0,0 +1,75 @@
+/* linux/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
+ *
+ * Copyright (C) 2009 Samsung Electronics 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 __S3C64XX_PLAT_SPI_H
+#define __S3C64XX_PLAT_SPI_H
+
+/**
+ * struct s3c64xx_spi_csinfo - ChipSelect description
+ * @fb_delay: Slave specific feedback delay.
+ * Refer to FB_CLK_SEL register definition in SPI chapter.
+ * @line: Custom 'identity' of the CS line.
+ * @set_level: CS line control.
+ *
+ * This is per SPI-Slave Chipselect information.
+ * Allocate and initialize one in machine init code and make the
+ * spi_board_info.controller_data point to it.
+ */
+struct s3c64xx_spi_csinfo {
+ u8 fb_delay;
+ unsigned line;
+ void (*set_level)(unsigned line_id, int lvl);
+};
+
+/**
+ * struct s3c64xx_spi_info - SPI Controller defining structure
+ * @src_clk_nr: Clock source index for the CLK_CFG[SPI_CLKSEL] field.
+ * @src_clk_name: Platform name of the corresponding clock.
+ * @clk_from_cmu: If the SPI clock/prescalar control block is present
+ * by the platform's clock-management-unit and not in SPI controller.
+ * @num_cs: Number of CS this controller emulates.
+ * @cfg_gpio: Configure pins for this SPI controller.
+ * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6
+ * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number
+ * @high_speed: If the controller supports HIGH_SPEED_EN bit
+ * @tx_st_done: Depends on tx fifo_lvl field
+ */
+struct s3c64xx_spi_info {
+ int src_clk_nr;
+ char *src_clk_name;
+ bool clk_from_cmu;
+
+ int num_cs;
+
+ int (*cfg_gpio)(struct platform_device *pdev);
+
+ /* Following two fields are for future compatibility */
+ int fifo_lvl_mask;
+ int rx_lvl_offset;
+ int high_speed;
+ int tx_st_done;
+};
+
+/**
+ * s3c64xx_spi_set_info - SPI Controller configure callback by the board
+ * initialization code.
+ * @cntrlr: SPI controller number the configuration is for.
+ * @src_clk_nr: Clock the SPI controller is to use to generate SPI clocks.
+ * @num_cs: Number of elements in the 'cs' array.
+ *
+ * Call this from machine init code for each SPI Controller that
+ * has some chips attached to it.
+ */
+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);
+
+#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
new file mode 100644
index 00000000..058e0965
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -0,0 +1,393 @@
+/* linux/arch/arm/plat-samsung/include/plat/sdhci.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Platform - SDHCI (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_SDHCI_H
+#define __PLAT_S3C_SDHCI_H __FILE__
+
+struct platform_device;
+struct mmc_host;
+struct mmc_card;
+struct mmc_ios;
+
+enum cd_types {
+ S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */
+ S3C_SDHCI_CD_EXTERNAL, /* use external callback */
+ S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */
+ S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */
+ S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
+};
+
+enum clk_types {
+ S3C_SDHCI_CLK_DIV_INTERNAL, /* use mmc internal clock divider */
+ S3C_SDHCI_CLK_DIV_EXTERNAL, /* use external clock divider */
+};
+
+/**
+ * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
+ * @max_width: The maximum number of data bits supported.
+ * @host_caps: Standard MMC host capabilities bit field.
+ * @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @clk_type: Type of clock divider method (see clk_types enum above)
+ * @ext_cd_init: Initialize external card detect subsystem. Called on
+ * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
+ * notify_func argument is a callback to the sdhci-s3c driver
+ * 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
+ * sdhci-s3c driver remove when cd_type == S3C_SDHCI_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_SDHCI_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 dependent 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_sdhci_platdata {
+ unsigned int max_width;
+ unsigned int host_caps;
+ enum cd_types cd_type;
+ enum clk_types clk_type;
+
+ char **clocks; /* set of clock sources */
+
+ int ext_cd_gpio;
+ bool ext_cd_gpio_invert;
+ 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_card)(struct platform_device *dev,
+ void __iomem *regbase,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+};
+
+/**
+ * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
+ * @pd: Platform data to register to device.
+ *
+ * Register the given platform data for use withe S3C SDHCI device.
+ * The call will copy the platform data, so the board definitions can
+ * make the structure itself __initdata.
+ */
+extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci3_set_platdata(struct s3c_sdhci_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_sdhci_platdata s3c_hsmmc0_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata;
+
+/* Helper function availability */
+
+extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
+extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
+extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
+extern void 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);
+
+/* S3C2416 SDHCI setup */
+
+#ifdef CONFIG_S3C2416_SETUP_SDHCI
+extern char *s3c2416_hsmmc_clksrcs[4];
+
+extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s3c2416_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
+#endif /* CONFIG_S3C_DEV_HSMMC */
+}
+
+static inline void s3c2416_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
+#endif /* CONFIG_S3C_DEV_HSMMC1 */
+}
+
+#else
+static inline void s3c2416_default_sdhci0(void) { }
+static inline void s3c2416_default_sdhci1(void) { }
+
+#endif /* CONFIG_S3C2416_SETUP_SDHCI */
+/* S3C64XX SDHCI setup */
+
+#ifdef CONFIG_S3C64XX_SETUP_SDHCI
+extern char *s3c64xx_hsmmc_clksrcs[4];
+
+extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s3c6400_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s3c6400_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s3c6400_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
+#endif
+}
+
+extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s3c6410_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s3c6410_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s3c6410_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void s3c6410_default_sdhci0(void) { }
+static inline void s3c6410_default_sdhci1(void) { }
+static inline void s3c6410_default_sdhci2(void) { }
+static inline void s3c6400_default_sdhci0(void) { }
+static inline void s3c6400_default_sdhci1(void) { }
+static inline void s3c6400_default_sdhci2(void) { }
+
+#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
+
+/* S5PC100 SDHCI setup */
+
+#ifdef CONFIG_S5PC100_SETUP_SDHCI
+extern char *s5pc100_hsmmc_clksrcs[4];
+
+extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s5pc100_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+#endif
+}
+
+static inline void s5pc100_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+#endif
+}
+
+static inline void s5pc100_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
+#endif
+}
+
+#else
+static inline void s5pc100_default_sdhci0(void) { }
+static inline void s5pc100_default_sdhci1(void) { }
+static inline void s5pc100_default_sdhci2(void) { }
+
+#endif /* CONFIG_S5PC100_SETUP_SDHCI */
+
+/* S5PV210 SDHCI setup */
+
+#ifdef CONFIG_S5PV210_SETUP_SDHCI
+extern char *s5pv210_hsmmc_clksrcs[4];
+
+extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
+ void __iomem *r,
+ struct mmc_ios *ios,
+ struct mmc_card *card);
+
+static inline void s5pv210_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv210_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv210_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void s5pv210_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void s5pv210_default_sdhci0(void) { }
+static inline void s5pv210_default_sdhci1(void) { }
+static inline void s5pv210_default_sdhci2(void) { }
+static inline void s5pv210_default_sdhci3(void) { }
+
+#endif /* CONFIG_S5PV210_SETUP_SDHCI */
+
+/* EXYNOS4 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 exynos4_default_sdhci0(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_hsmmc0_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc0_def_platdata.cfg_gpio = exynos4_setup_sdhci0_cfg_gpio;
+ s3c_hsmmc0_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos4_default_sdhci1(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_hsmmc1_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc1_def_platdata.cfg_gpio = exynos4_setup_sdhci1_cfg_gpio;
+ s3c_hsmmc1_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos4_default_sdhci2(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_hsmmc2_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc2_def_platdata.cfg_gpio = exynos4_setup_sdhci2_cfg_gpio;
+ s3c_hsmmc2_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+static inline void exynos4_default_sdhci3(void)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_hsmmc3_def_platdata.clocks = exynos4_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = exynos4_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = exynos4_setup_sdhci_cfg_card;
+#endif
+}
+
+#else
+static inline void exynos4_default_sdhci0(void) { }
+static inline void exynos4_default_sdhci1(void) { }
+static inline void exynos4_default_sdhci2(void) { }
+static inline void exynos4_default_sdhci3(void) { }
+
+#endif /* CONFIG_EXYNOS4_SETUP_SDHCI */
+
+#endif /* __PLAT_S3C_SDHCI_H */
diff --git a/arch/arm/plat-samsung/include/plat/ts.h b/arch/arm/plat-samsung/include/plat/ts.h
new file mode 100644
index 00000000..26fdb22e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ts.h
@@ -0,0 +1,25 @@
+/* arch/arm/plat-samsung/include/plat/ts.h
+ *
+ * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
+ *
+ * This program is free software; you can 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_TS_H
+#define __ASM_ARM_TS_H
+
+struct s3c2410_ts_mach_info {
+ int delay;
+ int presc;
+ int oversampling_shift;
+ void (*cfg_gpio)(struct platform_device *dev);
+};
+
+extern void s3c24xx_ts_set_platdata(struct s3c2410_ts_mach_info *);
+
+/* defined by architecture to configure gpio */
+extern void s3c24xx_ts_cfg_gpio(struct platform_device *dev);
+
+#endif /* __ASM_ARM_TS_H */
diff --git a/arch/arm/plat-samsung/include/plat/udc-hs.h b/arch/arm/plat-samsung/include/plat/udc-hs.h
new file mode 100644
index 00000000..a22a4f2e
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/udc-hs.h
@@ -0,0 +1,29 @@
+/* arch/arm/plat-s3c/include/plat/udc-hs.h
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C USB2.0 High-speed / OtG platform information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+enum s3c_hsotg_dmamode {
+ S3C_HSOTG_DMA_NONE, /* do not use DMA at-all */
+ S3C_HSOTG_DMA_ONLY, /* always use DMA */
+ S3C_HSOTG_DMA_DRV, /* DMA is chosen by driver */
+};
+
+/**
+ * struct s3c_hsotg_plat - platform data for high-speed otg/udc
+ * @dma: Whether to use DMA or not.
+ * @is_osc: The clock source is an oscillator, not a crystal
+ */
+struct s3c_hsotg_plat {
+ enum s3c_hsotg_dmamode dma;
+ unsigned int is_osc : 1;
+};
diff --git a/arch/arm/plat-samsung/include/plat/uncompress.h b/arch/arm/plat-samsung/include/plat/uncompress.h
new file mode 100644
index 00000000..ee48e12a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/uncompress.h
@@ -0,0 +1,184 @@
+/* arch/arm/plat-samsung/include/plat/uncompress.h
+ *
+ * Copyright 2003, 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - uncompress code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_UNCOMPRESS_H
+#define __ASM_PLAT_UNCOMPRESS_H
+
+typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
+
+/* uart setup */
+
+unsigned int fifo_mask;
+unsigned int fifo_max;
+
+/* forward declerations */
+
+static void arch_detect_cpu(void);
+
+/* defines for UART registers */
+
+#include <plat/regs-serial.h>
+#include <plat/regs-watchdog.h>
+
+/* working in physical space... */
+#undef S3C2410_WDOGREG
+#define S3C2410_WDOGREG(x) ((S3C24XX_PA_WATCHDOG + (x)))
+
+/* how many bytes we allow into the FIFO at a time in FIFO mode */
+#define FIFO_MAX (14)
+
+#define uart_base S3C_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT)
+
+static __inline__ void
+uart_wr(unsigned int reg, unsigned int val)
+{
+ volatile unsigned int *ptr;
+
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ *ptr = val;
+}
+
+static __inline__ unsigned int
+uart_rd(unsigned int reg)
+{
+ volatile unsigned int *ptr;
+
+ ptr = (volatile unsigned int *)(reg + uart_base);
+ return *ptr;
+}
+
+/* we can deal with the case the UARTs are being run
+ * in FIFO mode, so that we don't hold up our execution
+ * waiting for tx to happen...
+*/
+
+static void putc(int ch)
+{
+ if (uart_rd(S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE) {
+ int level;
+
+ while (1) {
+ level = uart_rd(S3C2410_UFSTAT);
+ level &= fifo_mask;
+
+ if (level < fifo_max)
+ break;
+ }
+
+ } else {
+ /* not using fifos */
+
+ while ((uart_rd(S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE) != S3C2410_UTRSTAT_TXE)
+ barrier();
+ }
+
+ /* write byte to transmission register */
+ uart_wr(S3C2410_UTXH, ch);
+}
+
+static inline void flush(void)
+{
+}
+
+#define __raw_writel(d, ad) \
+ do { \
+ *((volatile unsigned int __force *)(ad)) = (d); \
+ } while (0)
+
+/* CONFIG_S3C_BOOT_WATCHDOG
+ *
+ * Simple boot-time watchdog setup, to reboot the system if there is
+ * any problem with the boot process
+*/
+
+#ifdef CONFIG_S3C_BOOT_WATCHDOG
+
+#define WDOG_COUNT (0xff00)
+
+static inline void arch_decomp_wdog(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+}
+
+static void arch_decomp_wdog_start(void)
+{
+ __raw_writel(WDOG_COUNT, S3C2410_WTDAT);
+ __raw_writel(WDOG_COUNT, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x80), S3C2410_WTCON);
+}
+
+#else
+#define arch_decomp_wdog_start()
+#define arch_decomp_wdog()
+#endif
+
+#ifdef CONFIG_S3C_BOOT_ERROR_RESET
+
+static void arch_decomp_error(const char *x)
+{
+ putstr("\n\n");
+ putstr(x);
+ putstr("\n\n -- System resetting\n");
+
+ __raw_writel(0x4000, S3C2410_WTDAT);
+ __raw_writel(0x4000, S3C2410_WTCNT);
+ __raw_writel(S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128 | S3C2410_WTCON_RSTEN | S3C2410_WTCON_PRESCALE(0x40), S3C2410_WTCON);
+
+ while(1);
+}
+
+#define arch_error arch_decomp_error
+#endif
+
+#ifdef CONFIG_S3C_BOOT_UART_FORCE_FIFO
+static inline void arch_enable_uart_fifo(void)
+{
+ u32 fifocon = uart_rd(S3C2410_UFCON);
+
+ if (!(fifocon & S3C2410_UFCON_FIFOMODE)) {
+ fifocon |= S3C2410_UFCON_RESETBOTH;
+ uart_wr(S3C2410_UFCON, fifocon);
+
+ /* wait for fifo reset to complete */
+ while (1) {
+ fifocon = uart_rd(S3C2410_UFCON);
+ if (!(fifocon & S3C2410_UFCON_RESETBOTH))
+ break;
+ }
+ }
+}
+#else
+#define arch_enable_uart_fifo() do { } while(0)
+#endif
+
+
+static void
+arch_decomp_setup(void)
+{
+ /* we may need to setup the uart(s) here if we are not running
+ * on an BAST... the BAST will have left the uarts configured
+ * after calling linux.
+ */
+
+ arch_detect_cpu();
+ arch_decomp_wdog_start();
+
+ /* Enable the UART FIFOs if they where not enabled and our
+ * configuration says we should turn them on.
+ */
+
+ arch_enable_uart_fifo();
+}
+
+
+#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-samsung/include/plat/usb-control.h b/arch/arm/plat-samsung/include/plat/usb-control.h
new file mode 100644
index 00000000..7fa1fbef
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/usb-control.h
@@ -0,0 +1,43 @@
+/* arch/arm/plat-samsung/include/plat/usb-control.h
+ *
+ * Copyright (c) 2004 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C - USB host port information
+ *
+ * This program is free software; you can 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_USBCONTROL_H
+#define __ASM_ARCH_USBCONTROL_H
+
+#define S3C_HCDFLG_USED (1)
+
+struct s3c2410_hcd_port {
+ unsigned char flags;
+ unsigned char power;
+ unsigned char oc_status;
+ unsigned char oc_changed;
+};
+
+struct s3c2410_hcd_info {
+ struct usb_hcd *hcd;
+ struct s3c2410_hcd_port port[2];
+
+ void (*power_control)(int port, int to);
+ void (*enable_oc)(struct s3c2410_hcd_info *, int on);
+ void (*report_oc)(struct s3c2410_hcd_info *, int ports);
+};
+
+static void inline s3c2410_usb_report_oc(struct s3c2410_hcd_info *info, int ports)
+{
+ if (info->report_oc != NULL) {
+ (info->report_oc)(info, ports);
+ }
+}
+
+extern void s3c_ohci_set_platdata(struct s3c2410_hcd_info *info);
+
+#endif /*__ASM_ARCH_USBCONTROL_H */
diff --git a/arch/arm/plat-samsung/include/plat/wakeup-mask.h b/arch/arm/plat-samsung/include/plat/wakeup-mask.h
new file mode 100644
index 00000000..43e4acd2
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/wakeup-mask.h
@@ -0,0 +1,44 @@
+/* arch/arm/plat-samsung/include/plat/wakeup-mask.h
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Support for wakeup mask interrupts on newer SoCs
+ *
+ * This program is free software; you can 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_WAKEUP_MASK_H
+#define __PLAT_WAKEUP_MASK_H __file__
+
+/* if no irq yet defined, but still want to mask */
+#define NO_WAKEUP_IRQ (0x90000000)
+
+/**
+ * struct samsung_wakeup_mask - wakeup mask information
+ * @irq: The interrupt associated with this wakeup.
+ * @bit: The bit, as a (1 << bitno) controlling this source.
+ */
+struct samsung_wakeup_mask {
+ unsigned int irq;
+ u32 bit;
+};
+
+/**
+ * samsung_sync_wakemask - sync wakeup mask information for pm
+ * @reg: The register that is used.
+ * @masks: The list of masks to use.
+ * @nr_masks: The number of entries pointed to buy @masks.
+ *
+ * Synchronise the wakeup mask information at suspend time from the list
+ * of interrupts and control bits in @masks. We do this at suspend time
+ * as overriding the relevant irq chips is harder and the register is only
+ * required to be correct before we enter sleep.
+ */
+extern void samsung_sync_wakemask(void __iomem *reg,
+ struct samsung_wakeup_mask *masks,
+ int nr_masks);
+
+#endif /* __PLAT_WAKEUP_MASK_H */
diff --git a/arch/arm/plat-samsung/include/plat/watchdog-reset.h b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
new file mode 100644
index 00000000..54b762ac
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/watchdog-reset.h
@@ -0,0 +1,49 @@
+/* arch/arm/plat-s3c/include/plat/watchdog-reset.h
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - System define for arch_reset() 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.
+*/
+
+#include <plat/regs-watchdog.h>
+#include <mach/map.h>
+
+#include <linux/clk.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__);
+
+ /* put initial values into count and data */
+ __raw_writel(0x80, S3C2410_WTCNT);
+ __raw_writel(0x80, S3C2410_WTDAT);
+
+ /* set the watchdog to go and reset... */
+ __raw_writel(S3C2410_WTCON_ENABLE|S3C2410_WTCON_DIV16|S3C2410_WTCON_RSTEN |
+ S3C2410_WTCON_PRESCALE(0x20), S3C2410_WTCON);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ printk(KERN_ERR "Watchdog reset failed to assert reset\n");
+
+ /* delay to allow the serial port to show the message */
+ mdelay(50);
+}
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
new file mode 100644
index 00000000..79d10fca
--- /dev/null
+++ b/arch/arm/plat-samsung/init.c
@@ -0,0 +1,160 @@
+/* linux/arch/arm/plat-s3c/init.c
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series CPU initialisation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+
+#include <mach/hardware.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+
+#include <plat/regs-serial.h>
+
+static struct cpu_table *cpu;
+
+static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
+ struct cpu_table *tab,
+ unsigned int count)
+{
+ for (; count != 0; count--, tab++) {
+ if ((idcode & tab->idmask) == (tab->idcode & tab->idmask))
+ return tab;
+ }
+
+ return NULL;
+}
+
+void __init s3c_init_cpu(unsigned long idcode,
+ struct cpu_table *cputab, unsigned int cputab_size)
+{
+ cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
+
+ if (cpu == NULL) {
+ printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
+ panic("Unknown S3C24XX CPU");
+ }
+
+ printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
+
+ if (cpu->map_io == NULL || cpu->init == NULL) {
+ printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
+ panic("Unsupported Samsung CPU");
+ }
+
+ cpu->map_io();
+}
+
+/* s3c24xx_init_clocks
+ *
+ * Initialise the clock subsystem and associated information from the
+ * given master crystal value.
+ *
+ * xtal = 0 -> use default PLL crystal value (normally 12MHz)
+ * != 0 -> PLL crystal value in Hz
+*/
+
+void __init s3c24xx_init_clocks(int xtal)
+{
+ if (xtal == 0)
+ xtal = 12*1000*1000;
+
+ if (cpu == NULL)
+ panic("s3c24xx_init_clocks: no cpu setup?\n");
+
+ if (cpu->init_clocks == NULL)
+ panic("s3c24xx_init_clocks: cpu has no clock init\n");
+ else
+ (cpu->init_clocks)(xtal);
+}
+
+/* uart management */
+
+static int nr_uarts __initdata = 0;
+
+static struct s3c2410_uartcfg uart_cfgs[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+/* s3c24xx_init_uartdevs
+ *
+ * copy the specified platform data and configuration into our central
+ * set of devices, before the data is thrown away after the init process.
+ *
+ * This also fills in the array passed to the serial driver for the
+ * early initialisation of the console.
+*/
+
+void __init s3c24xx_init_uartdevs(char *name,
+ struct s3c24xx_uart_resources *res,
+ struct s3c2410_uartcfg *cfg, int no)
+{
+ struct platform_device *platdev;
+ struct s3c2410_uartcfg *cfgptr = uart_cfgs;
+ struct s3c24xx_uart_resources *resp;
+ int uart;
+
+ memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
+
+ for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
+ platdev = s3c24xx_uart_src[cfgptr->hwport];
+
+ resp = res + cfgptr->hwport;
+
+ s3c24xx_uart_devs[uart] = platdev;
+
+ platdev->name = name;
+ platdev->resource = resp->resources;
+ platdev->num_resources = resp->nr_resources;
+
+ platdev->dev.platform_data = cfgptr;
+ }
+
+ nr_uarts = no;
+}
+
+void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
+{
+ if (cpu == NULL)
+ return;
+
+ if (cpu->init_uarts == NULL) {
+ printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
+ } else
+ (cpu->init_uarts)(cfg, no);
+}
+
+static int __init s3c_arch_init(void)
+{
+ int ret;
+
+ // do the correct init for cpu
+
+ if (cpu == NULL)
+ panic("s3c_arch_init: NULL cpu\n");
+
+ ret = (cpu->init)();
+ if (ret != 0)
+ return ret;
+
+ ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
+ return ret;
+}
+
+arch_initcall(s3c_arch_init);
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
new file mode 100644
index 00000000..657405c4
--- /dev/null
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -0,0 +1,89 @@
+/* arch/arm/plat-samsung/irq-uart.c
+ * originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung- UART Interrupt handling
+ *
+ * This program is free software; you can 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/serial_core.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <plat/irq-uart.h>
+#include <plat/regs-serial.h>
+#include <plat/cpu.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.
+ */
+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;
+
+ if (pend & (1 << 0))
+ generic_handle_irq(base);
+ if (pend & (1 << 1))
+ generic_handle_irq(base + 1);
+ if (pend & (1 << 2))
+ generic_handle_irq(base + 2);
+ if (pend & (1 << 3))
+ generic_handle_irq(base + 3);
+}
+
+static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
+{
+ void __iomem *reg_base = uirq->regs;
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ /* mask all interrupts at the start. */
+ __raw_writel(0xf, reg_base + S3C64XX_UINTM);
+
+ gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base,
+ handle_level_irq);
+
+ if (!gc) {
+ pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
+ __func__, uirq->base_irq);
+ return;
+ }
+
+ 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->regs.ack = S3C64XX_UINTP;
+ ct->regs.mask = S3C64XX_UINTM;
+ irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+
+ irq_set_handler_data(uirq->parent_irq, uirq);
+ irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
+}
+
+/**
+ * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing
+ * @irq: The interrupt data for registering
+ * @nr_irqs: The number of interrupt descriptions in @irq.
+ *
+ * Register the UART interrupts specified by @irq including the demuxing
+ * routines. This supports the S3C6400 and newer style of devices.
+ */
+void __init s3c_init_uart_irqs(struct s3c_uart_irq *irq, unsigned int nr_irqs)
+{
+ for (; nr_irqs > 0; nr_irqs--, irq++)
+ s3c_init_uart_irq(irq);
+}
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
new file mode 100644
index 00000000..f714d060
--- /dev/null
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -0,0 +1,77 @@
+/* arch/arm/plat-samsung/irq-vic-timer.c
+ * originally part of arch/arm/plat-s3c64xx/irq.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C64XX - Interrupt handling
+ *
+ * This program is free software; you can 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/map.h>
+#include <plat/irq-vic-timer.h>
+#include <plat/regs-timer.h>
+
+static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
+{
+ generic_handle_irq((int)desc->irq_data.handler_data);
+}
+
+/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
+static void s3c_irq_timer_ack(struct irq_data *d)
+{
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ u32 mask = (1 << 5) << (d->irq - gc->irq_base);
+
+ irq_reg_writel(mask | gc->mask_cache, gc->reg_base);
+}
+
+/**
+ * s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
+ * @num: Number of timers to initialize
+ * @timer_irq: Base IRQ number to be used for the timers.
+ *
+ * Register the necessary IRQ chaining and support for the timer IRQs
+ * chained of the VIC.
+ */
+void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
+{
+ unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+ IRQ_TIMER3_VIC, IRQ_TIMER4_VIC };
+ struct irq_chip_generic *s3c_tgc;
+ struct irq_chip_type *ct;
+ unsigned int i;
+
+ s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
+ S3C64XX_TINT_CSTAT, handle_level_irq);
+
+ if (!s3c_tgc) {
+ pr_err("%s: irq_alloc_generic_chip for IRQ %d failed\n",
+ __func__, timer_irq);
+ return;
+ }
+
+ ct = s3c_tgc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_ack = s3c_irq_timer_ack;
+ irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+ IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+ /* Clear the upper bits of the mask_cache*/
+ s3c_tgc->mask_cache &= 0x1f;
+
+ for (i = 0; i < num; i++, timer_irq++) {
+ irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer);
+ irq_set_handler_data(pirq[i], (void *)timer_irq);
+ }
+}
diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c
new file mode 100644
index 00000000..efe1d564
--- /dev/null
+++ b/arch/arm/plat-samsung/pd.c
@@ -0,0 +1,95 @@
+/* linux/arch/arm/plat-samsung/pd.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung 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/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+
+#include <plat/pd.h>
+
+static int samsung_pd_probe(struct platform_device *pdev)
+{
+ struct samsung_pd_info *pdata = pdev->dev.platform_data;
+ struct device *dev = &pdev->dev;
+
+ if (!pdata) {
+ dev_err(dev, "no device data specified\n");
+ return -ENOENT;
+ }
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ dev_info(dev, "power domain registered\n");
+ return 0;
+}
+
+static int __devexit samsung_pd_remove(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ pm_runtime_disable(dev);
+ return 0;
+}
+
+static int samsung_pd_runtime_suspend(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->disable)
+ ret = pdata->disable(dev);
+
+ dev_dbg(dev, "suspended\n");
+ return ret;
+}
+
+static int samsung_pd_runtime_resume(struct device *dev)
+{
+ struct samsung_pd_info *pdata = dev->platform_data;
+ int ret = 0;
+
+ if (pdata->enable)
+ ret = pdata->enable(dev);
+
+ dev_dbg(dev, "resumed\n");
+ return ret;
+}
+
+static const struct dev_pm_ops samsung_pd_pm_ops = {
+ .runtime_suspend = samsung_pd_runtime_suspend,
+ .runtime_resume = samsung_pd_runtime_resume,
+};
+
+static struct platform_driver samsung_pd_driver = {
+ .driver = {
+ .name = "samsung-pd",
+ .owner = THIS_MODULE,
+ .pm = &samsung_pd_pm_ops,
+ },
+ .probe = samsung_pd_probe,
+ .remove = __devexit_p(samsung_pd_remove),
+};
+
+static int __init samsung_pd_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&samsung_pd_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add PD driver\n", __func__);
+
+ return ret;
+}
+arch_initcall(samsung_pd_init);
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
new file mode 100644
index 00000000..7cf2e1e3
--- /dev/null
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-samsung/platformdata.c
+ *
+ * Copyright 2010 Ben Dooks <ben-linux <at> fluff.org>
+ *
+ * Helper for platform data setting
+ *
+ * This program is free software; you can 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 <plat/devs.h>
+
+void __init *s3c_set_platdata(void *pd, size_t pdsize,
+ struct platform_device *pdev)
+{
+ void *npd;
+
+ if (!pd) {
+ /* too early to use dev_name(), may not be registered */
+ printk(KERN_ERR "%s: no platform data supplied\n", pdev->name);
+ return NULL;
+ }
+
+ npd = kmemdup(pd, pdsize, GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: cannot clone platform data\n", pdev->name);
+ return NULL;
+ }
+
+ pdev->dev.platform_data = npd;
+ return npd;
+}
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
new file mode 100644
index 00000000..6b733faf
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-check.c
@@ -0,0 +1,237 @@
+/* linux/arch/arm/plat-s3c/pm-check.c
+ * originally in linux/arch/arm/plat-s3c24xx/pm.c
+ *
+ * Copyright (c) 2004-2008 Simtec Electronics
+ * http://armlinux.simtec.co.uk
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C Power Mangament - suspend/resume memory corruptiuon check.
+ *
+ * This program is free software; you can 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/suspend.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+
+#include <plat/pm.h>
+
+#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
+#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value
+#endif
+
+/* suspend checking code...
+ *
+ * this next area does a set of crc checks over all the installed
+ * memory, so the system can verify if the resume was ok.
+ *
+ * CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
+ * increasing it will mean that the area corrupted will be less easy to spot,
+ * and reducing the size will cause the CRC save area to grow
+*/
+
+#define CHECK_CHUNKSIZE (CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE * 1024)
+
+static u32 crc_size; /* size needed for the crc block */
+static u32 *crcs; /* allocated over suspend/resume */
+
+typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
+
+/* s3c_pm_run_res
+ *
+ * go through the given resource list, and look for system ram
+*/
+
+static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
+{
+ while (ptr != NULL) {
+ if (ptr->child != NULL)
+ s3c_pm_run_res(ptr->child, fn, arg);
+
+ if ((ptr->flags & IORESOURCE_MEM) &&
+ strcmp(ptr->name, "System RAM") == 0) {
+ S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
+ (unsigned long)ptr->start,
+ (unsigned long)ptr->end);
+ arg = (fn)(ptr, arg);
+ }
+
+ ptr = ptr->sibling;
+ }
+}
+
+static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg)
+{
+ s3c_pm_run_res(&iomem_resource, fn, arg);
+}
+
+static u32 *s3c_pm_countram(struct resource *res, u32 *val)
+{
+ u32 size = (u32)(res->end - res->start)+1;
+
+ size += CHECK_CHUNKSIZE-1;
+ size /= CHECK_CHUNKSIZE;
+
+ S3C_PMDBG("Area %08lx..%08lx, %d blocks\n",
+ (unsigned long)res->start, (unsigned long)res->end, size);
+
+ *val += size * sizeof(u32);
+ return val;
+}
+
+/* s3c_pm_prepare_check
+ *
+ * prepare the necessary information for creating the CRCs. This
+ * must be done before the final save, as it will require memory
+ * allocating, and thus touching bits of the kernel we do not
+ * know about.
+*/
+
+void s3c_pm_check_prepare(void)
+{
+ crc_size = 0;
+
+ s3c_pm_run_sysram(s3c_pm_countram, &crc_size);
+
+ S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size);
+
+ crcs = kmalloc(crc_size+4, GFP_KERNEL);
+ if (crcs == NULL)
+ printk(KERN_ERR "Cannot allocated CRC save area\n");
+}
+
+static u32 *s3c_pm_makecheck(struct resource *res, u32 *val)
+{
+ unsigned long addr, left;
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ *val = crc32_le(~0, phys_to_virt(addr), left);
+ val++;
+ }
+
+ return val;
+}
+
+/* s3c_pm_check_store
+ *
+ * compute the CRC values for the memory blocks before the final
+ * sleep.
+*/
+
+void s3c_pm_check_store(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_makecheck, crcs);
+}
+
+/* in_region
+ *
+ * return TRUE if the area defined by ptr..ptr+size contains the
+ * what..what+whatsz
+*/
+
+static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
+{
+ if ((what+whatsz) < ptr)
+ return 0;
+
+ if (what > (ptr+size))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * s3c_pm_runcheck() - helper to check a resource on restore.
+ * @res: The resource to check
+ * @vak: Pointer to list of CRC32 values to check.
+ *
+ * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this
+ * function runs the given memory resource checking it against the stored
+ * CRC to ensure that memory is restored. The function tries to skip as
+ * many of the areas used during the suspend process.
+ */
+static u32 *s3c_pm_runcheck(struct resource *res, u32 *val)
+{
+ unsigned long addr;
+ unsigned long left;
+ void *stkpage;
+ void *ptr;
+ u32 calc;
+
+ stkpage = (void *)((u32)&calc & ~PAGE_MASK);
+
+ for (addr = res->start; addr < res->end;
+ addr += CHECK_CHUNKSIZE) {
+ left = res->end - addr;
+
+ if (left > CHECK_CHUNKSIZE)
+ left = CHECK_CHUNKSIZE;
+
+ ptr = phys_to_virt(addr);
+
+ if (in_region(ptr, left, stkpage, 4096)) {
+ S3C_PMDBG("skipping %08lx, has stack in\n", addr);
+ goto skip_check;
+ }
+
+ if (in_region(ptr, left, crcs, crc_size)) {
+ S3C_PMDBG("skipping %08lx, has crc block in\n", addr);
+ goto skip_check;
+ }
+
+ /* calculate and check the checksum */
+
+ calc = crc32_le(~0, ptr, left);
+ if (calc != *val) {
+ printk(KERN_ERR "Restore CRC error at "
+ "%08lx (%08x vs %08x)\n", addr, calc, *val);
+
+ S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n",
+ addr, calc, *val);
+ }
+
+ skip_check:
+ val++;
+ }
+
+ return val;
+}
+
+/**
+ * s3c_pm_check_restore() - memory check called on resume
+ *
+ * check the CRCs after the restore event and free the memory used
+ * to hold them
+*/
+void s3c_pm_check_restore(void)
+{
+ if (crcs != NULL)
+ s3c_pm_run_sysram(s3c_pm_runcheck, crcs);
+}
+
+/**
+ * s3c_pm_check_cleanup() - free memory resources
+ *
+ * Free the resources that where allocated by the suspend
+ * memory check code. We do this separately from the
+ * s3c_pm_check_restore() function as we cannot call any
+ * functions that might sleep during that resume.
+ */
+void s3c_pm_check_cleanup(void)
+{
+ kfree(crcs);
+ crcs = NULL;
+}
+
diff --git a/arch/arm/plat-samsung/pm-gpio.c b/arch/arm/plat-samsung/pm-gpio.c
new file mode 100644
index 00000000..96528200
--- /dev/null
+++ b/arch/arm/plat-samsung/pm-gpio.c
@@ -0,0 +1,384 @@
+
+/* linux/arch/arm/plat-s3c/pm-gpio.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C series GPIO PM code
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/sysdev.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/pm.h>
+
+/* PM GPIO helpers */
+
+#define OFFS_CON (0x00)
+#define OFFS_DAT (0x04)
+#define OFFS_UP (0x08)
+
+static void s3c_gpio_pm_1bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+}
+
+static void s3c_gpio_pm_1bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon;
+
+ /* GPACON only has one bit per control / data and no PULLUPs.
+ * GPACON[x] = 0 => Output, 1 => SFN */
+
+ /* first set all SFN bits to SFN */
+
+ gpcon = old_gpcon | gps_gpcon;
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* now set all the other bits */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_1bit = {
+ .save = s3c_gpio_pm_1bit_save,
+ .resume = s3c_gpio_pm_1bit_resume,
+};
+
+static void s3c_gpio_pm_2bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[0] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_UP);
+}
+
+/* Test whether the given masked+shifted bits of an GPIO configuration
+ * are one of the SFN (special function) modes. */
+
+static inline int is_sfn(unsigned long con)
+{
+ return con >= 2;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an input */
+
+static inline int is_in(unsigned long con)
+{
+ return con == 0;
+}
+
+/* Test if the given masked+shifted GPIO configuration is an output */
+
+static inline int is_out(unsigned long con)
+{
+ return con == 1;
+}
+
+/**
+ * s3c_gpio_pm_2bit_resume() - restore the given GPIO bank
+ * @chip: The chip information to resume.
+ *
+ * Restore one of the GPIO banks that was saved during suspend. This is
+ * not as simple as once thought, due to the possibility of glitches
+ * from the order that the CON and DAT registers are set in.
+ *
+ * The three states the pin can be are {IN,OUT,SFN} which gives us 9
+ * combinations of changes to check. Three of these, if the pin stays
+ * in the same configuration can be discounted. This leaves us with
+ * the following:
+ *
+ * { IN => OUT } Change DAT first
+ * { IN => SFN } Change CON first
+ * { OUT => SFN } Change CON first, so new data will not glitch
+ * { OUT => IN } Change CON first, so new data will not glitch
+ * { SFN => IN } Change CON first
+ * { SFN => OUT } Change DAT first, so new data will not glitch [1]
+ *
+ * We do not currently deal with the UP registers as these control
+ * weak resistors, so a small delay in change should not need to bring
+ * these into the calculations.
+ *
+ * [1] this assumes that writing to a pin DAT whilst in SFN will set the
+ * state for when it is next output.
+ */
+static void s3c_gpio_pm_2bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon = __raw_readl(base + OFFS_CON);
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpcon = chip->pm_save[0];
+ u32 gps_gpdat = chip->pm_save[1];
+ u32 gpcon, old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ /* restore GPIO pull-up settings */
+ __raw_writel(chip->pm_save[2], base + OFFS_UP);
+
+ /* Create a change_mask of all the items that need to have
+ * their CON value changed before their DAT value, so that
+ * we minimise the work between the two settings.
+ */
+
+ for (nr = 0, mask = 0x03; nr < 32; nr += 2, mask <<= 2) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+
+ /* Write the new CON settings */
+
+ gpcon = old_gpcon & ~change_mask;
+ gpcon |= gps_gpcon & change_mask;
+
+ __raw_writel(gpcon, base + OFFS_CON);
+
+ /* Now change any items that require DAT,CON */
+
+ __raw_writel(gps_gpdat, base + OFFS_DAT);
+ __raw_writel(gps_gpcon, base + OFFS_CON);
+
+ S3C_PMDBG("%s: CON %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon, gps_gpcon, old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_2bit = {
+ .save = s3c_gpio_pm_2bit_save,
+ .resume = s3c_gpio_pm_2bit_resume,
+};
+
+#if defined(CONFIG_ARCH_S3C64XX) || defined(CONFIG_PLAT_S5P)
+static void s3c_gpio_pm_4bit_save(struct s3c_gpio_chip *chip)
+{
+ chip->pm_save[1] = __raw_readl(chip->base + OFFS_CON);
+ chip->pm_save[2] = __raw_readl(chip->base + OFFS_DAT);
+ chip->pm_save[3] = __raw_readl(chip->base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8)
+ chip->pm_save[0] = __raw_readl(chip->base - 4);
+}
+
+static u32 s3c_gpio_pm_4bit_mask(u32 old_gpcon, u32 gps_gpcon)
+{
+ u32 old, new, mask;
+ u32 change_mask = 0x0;
+ int nr;
+
+ for (nr = 0, mask = 0x0f; nr < 16; nr += 4, mask <<= 4) {
+ old = (old_gpcon & mask) >> nr;
+ new = (gps_gpcon & mask) >> nr;
+
+ /* If there is no change, then skip */
+
+ if (old == new)
+ continue;
+
+ /* If both are special function, then skip */
+
+ if (is_sfn(old) && is_sfn(new))
+ continue;
+
+ /* Change is IN => OUT, do not change now */
+
+ if (is_in(old) && is_out(new))
+ continue;
+
+ /* Change is SFN => OUT, do not change now */
+
+ if (is_sfn(old) && is_out(new))
+ continue;
+
+ /* We should now be at the case of IN=>SFN,
+ * OUT=>SFN, OUT=>IN, SFN=>IN. */
+
+ change_mask |= mask;
+ }
+
+ return change_mask;
+}
+
+static void s3c_gpio_pm_4bit_con(struct s3c_gpio_chip *chip, int index)
+{
+ void __iomem *con = chip->base + (index * 4);
+ u32 old_gpcon = __raw_readl(con);
+ u32 gps_gpcon = chip->pm_save[index + 1];
+ u32 gpcon, mask;
+
+ mask = s3c_gpio_pm_4bit_mask(old_gpcon, gps_gpcon);
+
+ gpcon = old_gpcon & ~mask;
+ gpcon |= gps_gpcon & mask;
+
+ __raw_writel(gpcon, con);
+}
+
+static void s3c_gpio_pm_4bit_resume(struct s3c_gpio_chip *chip)
+{
+ void __iomem *base = chip->base;
+ u32 old_gpcon[2];
+ u32 old_gpdat = __raw_readl(base + OFFS_DAT);
+ u32 gps_gpdat = chip->pm_save[2];
+
+ /* First, modify the CON settings */
+
+ old_gpcon[0] = 0;
+ old_gpcon[1] = __raw_readl(base + OFFS_CON);
+
+ s3c_gpio_pm_4bit_con(chip, 0);
+ if (chip->chip.ngpio > 8) {
+ old_gpcon[0] = __raw_readl(base - 4);
+ s3c_gpio_pm_4bit_con(chip, -1);
+ }
+
+ /* Now change the configurations that require DAT,CON */
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[1], base + OFFS_CON);
+ if (chip->chip.ngpio > 8)
+ __raw_writel(chip->pm_save[0], base - 4);
+
+ __raw_writel(chip->pm_save[2], base + OFFS_DAT);
+ __raw_writel(chip->pm_save[3], base + OFFS_UP);
+
+ if (chip->chip.ngpio > 8) {
+ S3C_PMDBG("%s: CON4 %08x,%08x => %08x,%08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[0], old_gpcon[1],
+ __raw_readl(base - 4),
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+ } else
+ S3C_PMDBG("%s: CON4 %08x => %08x, DAT %08x => %08x\n",
+ chip->chip.label, old_gpcon[1],
+ __raw_readl(base + OFFS_CON),
+ old_gpdat, gps_gpdat);
+}
+
+struct s3c_gpio_pm s3c_gpio_pm_4bit = {
+ .save = s3c_gpio_pm_4bit_save,
+ .resume = s3c_gpio_pm_4bit_resume,
+};
+#endif /* CONFIG_ARCH_S3C64XX || CONFIG_PLAT_S5P */
+
+/**
+ * s3c_pm_save_gpio() - save gpio chip data for suspend
+ * @ourchip: The chip for suspend.
+ */
+static void s3c_pm_save_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->save == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->save(ourchip);
+}
+
+/**
+ * s3c_pm_save_gpios() - Save the state of the GPIO banks.
+ *
+ * For all the GPIO banks, save the state of each one ready for going
+ * into a suspend mode.
+ */
+void s3c_pm_save_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip) {
+ gpio_nr++;
+ continue;
+ }
+
+ s3c_pm_save_gpio(ourchip);
+
+ S3C_PMDBG("%s: save %08x,%08x,%08x,%08x\n",
+ ourchip->chip.label,
+ ourchip->pm_save[0],
+ ourchip->pm_save[1],
+ ourchip->pm_save[2],
+ ourchip->pm_save[3]);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
+
+/**
+ * s3c_pm_resume_gpio() - restore gpio chip data after suspend
+ * @ourchip: The suspended chip.
+ */
+static void s3c_pm_resume_gpio(struct s3c_gpio_chip *ourchip)
+{
+ struct s3c_gpio_pm *pm = ourchip->pm;
+
+ if (pm == NULL || pm->resume == NULL)
+ S3C_PMDBG("%s: no pm for %s\n", __func__, ourchip->chip.label);
+ else
+ pm->resume(ourchip);
+}
+
+void s3c_pm_restore_gpios(void)
+{
+ struct s3c_gpio_chip *ourchip;
+ unsigned int gpio_nr;
+
+ for (gpio_nr = 0; gpio_nr < S3C_GPIO_END;) {
+ ourchip = s3c_gpiolib_getchip(gpio_nr);
+ if (!ourchip) {
+ gpio_nr++;
+ continue;
+ }
+
+ s3c_pm_resume_gpio(ourchip);
+
+ gpio_nr += ourchip->chip.ngpio;
+ gpio_nr += CONFIG_S3C_GPIO_SPACE;
+ }
+}
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c
new file mode 100644
index 00000000..5c0a440d
--- /dev/null
+++ b/arch/arm/plat-samsung/pm.c
@@ -0,0 +1,365 @@
+/* linux/arch/arm/plat-s3c/pm.c
+ *
+ * Copyright 2008 Openmoko, Inc.
+ * Copyright 2004-2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * S3C common power management (suspend to ram) 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/suspend.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/serial_core.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+#include <mach/map.h>
+
+#include <plat/regs-serial.h>
+#include <mach/regs-clock.h>
+#include <mach/regs-irq.h>
+#include <asm/irq.h>
+
+#include <plat/pm.h>
+#include <mach/pm-core.h>
+
+/* for external use */
+
+unsigned long s3c_pm_flags;
+
+/* Debug code:
+ *
+ * This code supports debug output to the low level UARTs for use on
+ * resume before the console layer is available.
+*/
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+extern void printascii(const char *);
+
+void s3c_pm_dbg(const char *fmt, ...)
+{
+ va_list va;
+ char buff[256];
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ printascii(buff);
+}
+
+static inline void s3c_pm_debug_init(void)
+{
+ /* restart uart clocks so we can use them to output */
+ s3c_pm_debug_init_uart();
+}
+
+#else
+#define s3c_pm_debug_init() do { } while(0)
+
+#endif /* CONFIG_SAMSUNG_PM_DEBUG */
+
+/* Save the UART configurations if we are configured for debug. */
+
+unsigned char pm_uart_udivslot;
+
+#ifdef CONFIG_SAMSUNG_PM_DEBUG
+
+struct pm_uart_save uart_save[CONFIG_SERIAL_SAMSUNG_UARTS];
+
+static void s3c_pm_save_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ save->ulcon = __raw_readl(regs + S3C2410_ULCON);
+ save->ucon = __raw_readl(regs + S3C2410_UCON);
+ save->ufcon = __raw_readl(regs + S3C2410_UFCON);
+ save->umcon = __raw_readl(regs + S3C2410_UMCON);
+ save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
+
+ S3C_PMDBG("UART[%d]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
+ uart, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
+}
+
+static void s3c_pm_save_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_save_uart(uart, save);
+}
+
+static void s3c_pm_restore_uart(unsigned int uart, struct pm_uart_save *save)
+{
+ void __iomem *regs = S3C_VA_UARTx(uart);
+
+ s3c_pm_arch_update_uart(regs, save);
+
+ __raw_writel(save->ulcon, regs + S3C2410_ULCON);
+ __raw_writel(save->ucon, regs + S3C2410_UCON);
+ __raw_writel(save->ufcon, regs + S3C2410_UFCON);
+ __raw_writel(save->umcon, regs + S3C2410_UMCON);
+ __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
+
+ if (pm_uart_udivslot)
+ __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
+}
+
+static void s3c_pm_restore_uarts(void)
+{
+ struct pm_uart_save *save = uart_save;
+ unsigned int uart;
+
+ for (uart = 0; uart < CONFIG_SERIAL_SAMSUNG_UARTS; uart++, save++)
+ s3c_pm_restore_uart(uart, save);
+}
+#else
+static void s3c_pm_save_uarts(void) { }
+static void s3c_pm_restore_uarts(void) { }
+#endif
+
+/* The IRQ ext-int code goes here, it is too small to currently bother
+ * with its own file. */
+
+unsigned long s3c_irqwake_intmask = 0xffffffffL;
+unsigned long s3c_irqwake_eintmask = 0xffffffffL;
+
+int s3c_irqext_wake(struct irq_data *data, unsigned int state)
+{
+ unsigned long bit = 1L << IRQ_EINT_BIT(data->irq);
+
+ if (!(s3c_irqwake_eintallow & bit))
+ return -ENOENT;
+
+ printk(KERN_INFO "wake %s for irq %d\n",
+ state ? "enabled" : "disabled", data->irq);
+
+ if (!state)
+ s3c_irqwake_eintmask |= bit;
+ else
+ s3c_irqwake_eintmask &= ~bit;
+
+ return 0;
+}
+
+/* helper functions to save and restore register state */
+
+/**
+ * s3c_pm_do_save() - save a set of registers for restoration on resume.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Run through the list of registers given, saving their contents in the
+ * array for later restoration when we wakeup.
+ */
+void s3c_pm_do_save(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++) {
+ ptr->val = __raw_readl(ptr->reg);
+ S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val);
+ }
+}
+
+/**
+ * s3c_pm_do_restore() - restore register values from the save list.
+ * @ptr: Pointer to an array of registers.
+ * @count: Size of the ptr array.
+ *
+ * Restore the register values saved from s3c_pm_do_save().
+ *
+ * Note, we do not use S3C_PMDBG() in here, as the system may not have
+ * restore the UARTs state yet
+*/
+
+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",
+ ptr->reg, ptr->val, __raw_readl(ptr->reg));
+
+ __raw_writel(ptr->val, ptr->reg);
+ }
+}
+
+/**
+ * s3c_pm_do_restore_core() - early restore register values from save list.
+ *
+ * This is similar to s3c_pm_do_restore() except we try and minimise the
+ * side effects of the function in case registers that hardware might need
+ * to work has been restored.
+ *
+ * WARNING: Do not put any debug in here that may effect memory or use
+ * peripherals, as things may be changing!
+*/
+
+void s3c_pm_do_restore_core(struct sleep_save *ptr, int count)
+{
+ for (; count > 0; count--, ptr++)
+ __raw_writel(ptr->val, ptr->reg);
+}
+
+/* s3c2410_pm_show_resume_irqs
+ *
+ * print any IRQs asserted at resume time (ie, we woke from)
+*/
+static void __maybe_unused s3c_pm_show_resume_irqs(int start,
+ unsigned long which,
+ unsigned long mask)
+{
+ int i;
+
+ which &= ~mask;
+
+ for (i = 0; i <= 31; 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);
+
+#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
+
+/* s3c_pm_enter
+ *
+ * central control for sleep/resume process
+*/
+
+static int s3c_pm_enter(suspend_state_t state)
+{
+ /* ensure the debug is initialised (if enabled) */
+
+ s3c_pm_debug_init();
+
+ S3C_PMDBG("%s(%d)\n", __func__, state);
+
+ if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
+ printk(KERN_ERR "%s: error: no cpu sleep function\n", __func__);
+ return -EINVAL;
+ }
+
+ /* check if we have anything to wake-up with... bad things seem
+ * to happen if you suspend with no wakeup (system will often
+ * require a full power-cycle)
+ */
+
+ if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
+ !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
+ printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
+ printk(KERN_ERR "%s: Aborting sleep\n", __func__);
+ return -EINVAL;
+ }
+
+ /* save all necessary core registers not covered by the drivers */
+
+ s3c_pm_save_gpios();
+ s3c_pm_save_uarts();
+ s3c_pm_save_core();
+
+ /* set the irq configuration for wake */
+
+ s3c_pm_configure_extint();
+
+ S3C_PMDBG("sleep: irq wakeup masks: %08lx,%08lx\n",
+ s3c_irqwake_intmask, s3c_irqwake_eintmask);
+
+ s3c_pm_arch_prepare_irqs();
+
+ /* call cpu specific preparation */
+
+ pm_cpu_prep();
+
+ /* flush cache back to ram */
+
+ flush_cache_all();
+
+ s3c_pm_check_store();
+
+ /* send the cpu to sleep... */
+
+ s3c_pm_arch_stop_clocks();
+
+ /* 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. */
+
+ 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_debug_init();
+
+ /* check what irq (if any) restored the system */
+
+ s3c_pm_arch_show_resume_irqs();
+
+ S3C_PMDBG("%s: post sleep, preparing to return\n", __func__);
+
+ /* LEDs should now be 1110 */
+ s3c_pm_debug_smdkled(1 << 1, 0);
+
+ s3c_pm_check_restore();
+
+ /* ok, let's return from sleep */
+
+ S3C_PMDBG("S3C PM Resume (post-restore)\n");
+ return 0;
+}
+
+static int s3c_pm_prepare(void)
+{
+ /* prepare check area if configured */
+
+ s3c_pm_check_prepare();
+ return 0;
+}
+
+static void s3c_pm_finish(void)
+{
+ s3c_pm_check_cleanup();
+}
+
+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,
+};
+
+/* s3c_pm_init
+ *
+ * Attach the power management functions. This should be called
+ * from the board specific initialisation if the board supports
+ * it.
+*/
+
+int __init s3c_pm_init(void)
+{
+ printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");
+
+ suspend_set_ops(&s3c_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/plat-samsung/pwm-clock.c b/arch/arm/plat-samsung/pwm-clock.c
new file mode 100644
index 00000000..46c9381e
--- /dev/null
+++ b/arch/arm/plat-samsung/pwm-clock.c
@@ -0,0 +1,455 @@
+/* linux/arch/arm/plat-s3c24xx/pwm-clock.c
+ *
+ * Copyright (c) 2007 Simtec Electronics
+ * Copyright (c) 2007, 2008 Ben Dooks
+ * Ben Dooks <ben-linux@fluff.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/log2.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/map.h>
+#include <asm/irq.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+#include <plat/regs-timer.h>
+#include <mach/pwm-clock.h>
+
+/* Each of the timers 0 through 5 go through the following
+ * clock tree, with the inputs depending on the timers.
+ *
+ * pclk ---- [ prescaler 0 ] -+---> timer 0
+ * +---> timer 1
+ *
+ * pclk ---- [ prescaler 1 ] -+---> timer 2
+ * +---> timer 3
+ * \---> timer 4
+ *
+ * Which are fed into the timers as so:
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 0
+ * tclk 0 ------------------------------/
+ *
+ * prescaled 0 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 1
+ * tclk 0 ------------------------------/
+ *
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 2
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8,16 ] ---\
+ * [mux] -> timer 3
+ * tclk 1 ------------------------------/
+ *
+ * prescaled 1 ---- [ div 2,4,8, 16 ] --\
+ * [mux] -> timer 4
+ * tclk 1 ------------------------------/
+ *
+ * Since the mux and the divider are tied together in the
+ * same register space, it is impossible to set the parent
+ * and the rate at the same time. To avoid this, we add an
+ * intermediate 'prescaled-and-divided' clock to select
+ * as the parent for the timer input clock called tdiv.
+ *
+ * prescaled clk --> pwm-tdiv ---\
+ * [ mux ] --> timer X
+ * tclk -------------------------/
+*/
+
+static struct clk clk_timer_scaler[];
+
+static unsigned long clk_pwm_scaler_get_rate(struct clk *clk)
+{
+ unsigned long tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ if (clk == &clk_timer_scaler[1]) {
+ tcfg0 &= S3C2410_TCFG_PRESCALER1_MASK;
+ tcfg0 >>= S3C2410_TCFG_PRESCALER1_SHIFT;
+ } else {
+ tcfg0 &= S3C2410_TCFG_PRESCALER0_MASK;
+ }
+
+ return clk_get_rate(clk->parent) / (tcfg0 + 1);
+}
+
+static unsigned long clk_pwm_scaler_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long divisor = parent_rate / rate;
+
+ if (divisor > 256)
+ divisor = 256;
+ else if (divisor < 2)
+ divisor = 2;
+
+ return parent_rate / divisor;
+}
+
+static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long round = clk_pwm_scaler_round_rate(clk, rate);
+ unsigned long tcfg0;
+ unsigned long divisor;
+ unsigned long flags;
+
+ divisor = clk_get_rate(clk->parent) / round;
+ divisor--;
+
+ local_irq_save(flags);
+ tcfg0 = __raw_readl(S3C2410_TCFG0);
+
+ if (clk == &clk_timer_scaler[1]) {
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK;
+ tcfg0 |= divisor << S3C2410_TCFG_PRESCALER1_SHIFT;
+ } else {
+ tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK;
+ tcfg0 |= divisor;
+ }
+
+ __raw_writel(tcfg0, S3C2410_TCFG0);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk_ops clk_pwm_scaler_ops = {
+ .get_rate = clk_pwm_scaler_get_rate,
+ .set_rate = clk_pwm_scaler_set_rate,
+ .round_rate = clk_pwm_scaler_round_rate,
+};
+
+static struct clk clk_timer_scaler[] = {
+ [0] = {
+ .name = "pwm-scaler0",
+ .id = -1,
+ .ops = &clk_pwm_scaler_ops,
+ },
+ [1] = {
+ .name = "pwm-scaler1",
+ .id = -1,
+ .ops = &clk_pwm_scaler_ops,
+ },
+};
+
+static struct clk clk_timer_tclk[] = {
+ [0] = {
+ .name = "pwm-tclk0",
+ .id = -1,
+ },
+ [1] = {
+ .name = "pwm-tclk1",
+ .id = -1,
+ },
+};
+
+struct pwm_tdiv_clk {
+ struct clk clk;
+ unsigned int divisor;
+};
+
+static inline struct pwm_tdiv_clk *to_tdiv(struct clk *clk)
+{
+ return container_of(clk, struct pwm_tdiv_clk, clk);
+}
+
+static unsigned long clk_pwm_tdiv_get_rate(struct clk *clk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (pwm_cfg_src_is_tclk(tcfg1))
+ divisor = to_tdiv(clk)->divisor;
+ else
+ divisor = tcfg_to_divisor(tcfg1);
+
+ return clk_get_rate(clk->parent) / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ unsigned long parent_rate;
+ unsigned long divisor;
+
+ parent_rate = clk_get_rate(clk->parent);
+ divisor = parent_rate / rate;
+
+ if (divisor <= 1 && pwm_tdiv_has_div1())
+ divisor = 1;
+ else if (divisor <= 2)
+ divisor = 2;
+ else if (divisor <= 4)
+ divisor = 4;
+ else if (divisor <= 8)
+ divisor = 8;
+ else
+ divisor = 16;
+
+ return parent_rate / divisor;
+}
+
+static unsigned long clk_pwm_tdiv_bits(struct pwm_tdiv_clk *divclk)
+{
+ return pwm_tdiv_div_bits(divclk->divisor);
+}
+
+static void clk_pwm_tdiv_update(struct pwm_tdiv_clk *divclk)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long bits = clk_pwm_tdiv_bits(divclk);
+ unsigned long flags;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(divclk->clk.id);
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ tcfg1 |= bits << shift;
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+}
+
+static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
+{
+ struct pwm_tdiv_clk *divclk = to_tdiv(clk);
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned long parent_rate = clk_get_rate(clk->parent);
+ unsigned long divisor;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(clk->id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ rate = clk_round_rate(clk, rate);
+ divisor = parent_rate / rate;
+
+ if (divisor > 16)
+ return -EINVAL;
+
+ divclk->divisor = divisor;
+
+ /* Update the current MUX settings if we are currently
+ * selected as the clock source for this clock. */
+
+ if (!pwm_cfg_src_is_tclk(tcfg1))
+ clk_pwm_tdiv_update(divclk);
+
+ return 0;
+}
+
+static struct clk_ops clk_tdiv_ops = {
+ .get_rate = clk_pwm_tdiv_get_rate,
+ .set_rate = clk_pwm_tdiv_set_rate,
+ .round_rate = clk_pwm_tdiv_round_rate,
+};
+
+static struct pwm_tdiv_clk clk_timer_tdiv[] = {
+ [0] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[0],
+ },
+ },
+ [1] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[0],
+ }
+ },
+ [2] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+ [3] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+ [4] = {
+ .clk = {
+ .name = "pwm-tdiv",
+ .ops = &clk_tdiv_ops,
+ .parent = &clk_timer_scaler[1],
+ },
+ },
+};
+
+static int __init clk_pwm_tdiv_register(unsigned int id)
+{
+ struct pwm_tdiv_clk *divclk = &clk_timer_tdiv[id];
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ divclk->clk.id = id;
+ divclk->divisor = tcfg_to_divisor(tcfg1);
+
+ return s3c24xx_register_clock(&divclk->clk);
+}
+
+static inline struct clk *s3c24xx_pwmclk_tclk(unsigned int id)
+{
+ return (id >= 2) ? &clk_timer_tclk[1] : &clk_timer_tclk[0];
+}
+
+static inline struct clk *s3c24xx_pwmclk_tdiv(unsigned int id)
+{
+ return &clk_timer_tdiv[id].clk;
+}
+
+static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned int id = clk->id;
+ unsigned long tcfg1;
+ unsigned long flags;
+ unsigned long bits;
+ unsigned long shift = S3C2410_TCFG1_SHIFT(id);
+
+ if (parent == s3c24xx_pwmclk_tclk(id))
+ bits = S3C_TCFG1_MUX_TCLK << shift;
+ else if (parent == s3c24xx_pwmclk_tdiv(id))
+ bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
+ else
+ return -EINVAL;
+
+ clk->parent = parent;
+
+ local_irq_save(flags);
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~(S3C2410_TCFG1_MUX_MASK << shift);
+ __raw_writel(tcfg1 | bits, S3C2410_TCFG1);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static struct clk_ops clk_tin_ops = {
+ .set_parent = clk_pwm_tin_set_parent,
+};
+
+static struct clk clk_tin[] = {
+ [0] = {
+ .name = "pwm-tin",
+ .id = 0,
+ .ops = &clk_tin_ops,
+ },
+ [1] = {
+ .name = "pwm-tin",
+ .id = 1,
+ .ops = &clk_tin_ops,
+ },
+ [2] = {
+ .name = "pwm-tin",
+ .id = 2,
+ .ops = &clk_tin_ops,
+ },
+ [3] = {
+ .name = "pwm-tin",
+ .id = 3,
+ .ops = &clk_tin_ops,
+ },
+ [4] = {
+ .name = "pwm-tin",
+ .id = 4,
+ .ops = &clk_tin_ops,
+ },
+};
+
+static __init int clk_pwm_tin_register(struct clk *pwm)
+{
+ unsigned long tcfg1 = __raw_readl(S3C2410_TCFG1);
+ unsigned int id = pwm->id;
+
+ struct clk *parent;
+ int ret;
+
+ ret = s3c24xx_register_clock(pwm);
+ if (ret < 0)
+ return ret;
+
+ tcfg1 >>= S3C2410_TCFG1_SHIFT(id);
+ tcfg1 &= S3C2410_TCFG1_MUX_MASK;
+
+ if (pwm_cfg_src_is_tclk(tcfg1))
+ parent = s3c24xx_pwmclk_tclk(id);
+ else
+ parent = s3c24xx_pwmclk_tdiv(id);
+
+ return clk_set_parent(pwm, parent);
+}
+
+/**
+ * s3c_pwmclk_init() - initialise pwm clocks
+ *
+ * Initialise and register the clocks which provide the inputs for the
+ * pwm timer blocks.
+ *
+ * Note, this call is required by the time core, so must be called after
+ * the base clocks are added and before any of the initcalls are run.
+ */
+__init void s3c_pwmclk_init(void)
+{
+ struct clk *clk_timers;
+ unsigned int clk;
+ int ret;
+
+ clk_timers = clk_get(NULL, "timers");
+ if (IS_ERR(clk_timers)) {
+ printk(KERN_ERR "%s: no parent clock\n", __func__);
+ return;
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_scaler); clk++)
+ clk_timer_scaler[clk].parent = clk_timers;
+
+ s3c_register_clocks(clk_timer_scaler, ARRAY_SIZE(clk_timer_scaler));
+ s3c_register_clocks(clk_timer_tclk, ARRAY_SIZE(clk_timer_tclk));
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_timer_tdiv); clk++) {
+ ret = clk_pwm_tdiv_register(clk);
+
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tdiv clock\n", clk);
+ return;
+ }
+ }
+
+ for (clk = 0; clk < ARRAY_SIZE(clk_tin); clk++) {
+ ret = clk_pwm_tin_register(&clk_tin[clk]);
+ if (ret < 0) {
+ printk(KERN_ERR "error adding pwm%d tin clock\n", clk);
+ return;
+ }
+ }
+}
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
new file mode 100644
index 00000000..f37457c5
--- /dev/null
+++ b/arch/arm/plat-samsung/pwm.c
@@ -0,0 +1,413 @@
+/* arch/arm/plat-s3c/pwm.c
+ *
+ * Copyright (c) 2007 Ben Dooks
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
+ *
+ * S3C series PWM device core
+ *
+ * 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.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <mach/map.h>
+
+#include <plat/regs-timer.h>
+
+struct pwm_device {
+ struct list_head list;
+ struct platform_device *pdev;
+
+ struct clk *clk_div;
+ struct clk *clk;
+ const char *label;
+
+ unsigned int period_ns;
+ unsigned int duty_ns;
+
+ unsigned char tcon_base;
+ unsigned char running;
+ unsigned char use_count;
+ unsigned char pwm_id;
+};
+
+#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
+
+static struct clk *clk_scaler[2];
+
+static inline int pwm_is_tdiv(struct pwm_device *pwm)
+{
+ return clk_get_parent(pwm->clk) == pwm->clk_div;
+}
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+ struct pwm_device *pwm;
+ int found = 0;
+
+ mutex_lock(&pwm_lock);
+
+ list_for_each_entry(pwm, &pwm_list, list) {
+ if (pwm->pwm_id == pwm_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ if (pwm->use_count == 0) {
+ pwm->use_count = 1;
+ pwm->label = label;
+ } else
+ pwm = ERR_PTR(-EBUSY);
+ } else
+ pwm = ERR_PTR(-ENOENT);
+
+ mutex_unlock(&pwm_lock);
+ return pwm;
+}
+
+EXPORT_SYMBOL(pwm_request);
+
+
+void pwm_free(struct pwm_device *pwm)
+{
+ mutex_lock(&pwm_lock);
+
+ if (pwm->use_count) {
+ pwm->use_count--;
+ pwm->label = NULL;
+ } else
+ printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
+
+ mutex_unlock(&pwm_lock);
+}
+
+EXPORT_SYMBOL(pwm_free);
+
+#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
+#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
+#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
+#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
+
+int pwm_enable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon |= pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 1;
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+ unsigned long flags;
+ unsigned long tcon;
+
+ local_irq_save(flags);
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcon &= ~pwm_tcon_start(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ pwm->running = 0;
+}
+
+EXPORT_SYMBOL(pwm_disable);
+
+static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
+{
+ unsigned long tin_parent_rate;
+ unsigned int div;
+
+ tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
+ pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
+
+ for (div = 2; div <= 16; div *= 2) {
+ if ((tin_parent_rate / (div << 16)) < freq)
+ return tin_parent_rate / div;
+ }
+
+ return tin_parent_rate / 16;
+}
+
+#define NS_IN_HZ (1000000000UL)
+
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+ unsigned long tin_rate;
+ unsigned long tin_ns;
+ unsigned long period;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned long tcnt;
+ long tcmp;
+
+ /* We currently avoid using 64bit arithmetic by using the
+ * fact that anything faster than 1Hz is easily representable
+ * by 32bits. */
+
+ if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
+ return -ERANGE;
+
+ if (duty_ns > period_ns)
+ return -EINVAL;
+
+ if (period_ns == pwm->period_ns &&
+ duty_ns == pwm->duty_ns)
+ return 0;
+
+ /* The TCMP and TCNT can be read without a lock, they're not
+ * shared between the timers. */
+
+ tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
+ tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
+
+ period = NS_IN_HZ / period_ns;
+
+ pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
+ duty_ns, period_ns, period);
+
+ /* Check to see if we are changing the clock rate of the PWM */
+
+ if (pwm->period_ns != period_ns) {
+ if (pwm_is_tdiv(pwm)) {
+ tin_rate = pwm_calc_tin(pwm, period);
+ clk_set_rate(pwm->clk_div, tin_rate);
+ } else
+ tin_rate = clk_get_rate(pwm->clk);
+
+ pwm->period_ns = period_ns;
+
+ pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
+
+ tin_ns = NS_IN_HZ / tin_rate;
+ tcnt = period_ns / tin_ns;
+ } else
+ tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
+
+ /* Note, counters count down */
+
+ tcmp = duty_ns / tin_ns;
+ tcmp = tcnt - tcmp;
+ /* the pwm hw only checks the compare register after a decrement,
+ so the pin never toggles if tcmp = tcnt */
+ if (tcmp == tcnt)
+ tcmp--;
+
+ pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
+
+ if (tcmp < 0)
+ tcmp = 0;
+
+ /* Update the PWM register block. */
+
+ local_irq_save(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_manulupdate(pwm);
+ tcon |= pwm_tcon_autoreload(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ tcon &= ~pwm_tcon_manulupdate(pwm);
+ __raw_writel(tcon, S3C2410_TCON);
+
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(pwm_config);
+
+static int pwm_register(struct pwm_device *pwm)
+{
+ pwm->duty_ns = -1;
+ pwm->period_ns = -1;
+
+ mutex_lock(&pwm_lock);
+ list_add_tail(&pwm->list, &pwm_list);
+ mutex_unlock(&pwm_lock);
+
+ return 0;
+}
+
+static int s3c_pwm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct pwm_device *pwm;
+ unsigned long flags;
+ unsigned long tcon;
+ unsigned int id = pdev->id;
+ int ret;
+
+ if (id == 4) {
+ dev_err(dev, "TIMER4 is currently not supported\n");
+ return -ENXIO;
+ }
+
+ pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+ if (pwm == NULL) {
+ dev_err(dev, "failed to allocate pwm_device\n");
+ return -ENOMEM;
+ }
+
+ pwm->pdev = pdev;
+ pwm->pwm_id = id;
+
+ /* calculate base of control bits in TCON */
+ pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
+
+ pwm->clk = clk_get(dev, "pwm-tin");
+ if (IS_ERR(pwm->clk)) {
+ dev_err(dev, "failed to get pwm tin clk\n");
+ ret = PTR_ERR(pwm->clk);
+ goto err_alloc;
+ }
+
+ pwm->clk_div = clk_get(dev, "pwm-tdiv");
+ if (IS_ERR(pwm->clk_div)) {
+ dev_err(dev, "failed to get pwm tdiv clk\n");
+ ret = PTR_ERR(pwm->clk_div);
+ 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");
+ goto err_clk_tdiv;
+ }
+
+ pwm_dbg(pwm, "config bits %02x\n",
+ (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
+
+ dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
+ clk_get_rate(pwm->clk),
+ clk_get_rate(pwm->clk_div),
+ pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
+
+ platform_set_drvdata(pdev, pwm);
+ return 0;
+
+ err_clk_tdiv:
+ clk_put(pwm->clk_div);
+
+ err_clk_tin:
+ clk_put(pwm->clk);
+
+ err_alloc:
+ kfree(pwm);
+ return ret;
+}
+
+static int __devexit s3c_pwm_remove(struct platform_device *pdev)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+ clk_put(pwm->clk_div);
+ clk_put(pwm->clk);
+ kfree(pwm);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct pwm_device *pwm = platform_get_drvdata(pdev);
+
+ /* No one preserve these values during suspend so reset them
+ * Otherwise driver leaves PWM unconfigured if same values
+ * passed to pwm_config
+ */
+ pwm->period_ns = 0;
+ pwm->duty_ns = 0;
+
+ 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);
+
+ return 0;
+}
+
+#else
+#define s3c_pwm_suspend NULL
+#define s3c_pwm_resume NULL
+#endif
+
+static struct platform_driver s3c_pwm_driver = {
+ .driver = {
+ .name = "s3c24xx-pwm",
+ .owner = THIS_MODULE,
+ },
+ .probe = s3c_pwm_probe,
+ .remove = __devexit_p(s3c_pwm_remove),
+ .suspend = s3c_pwm_suspend,
+ .resume = s3c_pwm_resume,
+};
+
+static int __init pwm_init(void)
+{
+ int ret;
+
+ clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
+ clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
+
+ if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
+ printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = platform_driver_register(&s3c_pwm_driver);
+ if (ret)
+ printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
+
+ return ret;
+}
+
+arch_initcall(pwm_init);
diff --git a/arch/arm/plat-samsung/s3c-pl330.c b/arch/arm/plat-samsung/s3c-pl330.c
new file mode 100644
index 00000000..f85638c6
--- /dev/null
+++ b/arch/arm/plat-samsung/s3c-pl330.c
@@ -0,0 +1,1244 @@
+/* linux/arch/arm/plat-samsung/s3c-pl330.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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/hardware/pl330.h>
+
+#include <plat/s3c-pl330-pdata.h>
+
+/**
+ * struct s3c_pl330_dmac - Logical representation of a PL330 DMAC.
+ * @busy_chan: Number of channels currently busy.
+ * @peri: List of IDs of peripherals this DMAC can work with.
+ * @node: To attach to the global list of DMACs.
+ * @pi: PL330 configuration info for the DMAC.
+ * @kmcache: Pool to quickly allocate xfers for all channels in the dmac.
+ * @clk: Pointer of DMAC operation clock.
+ */
+struct s3c_pl330_dmac {
+ unsigned busy_chan;
+ enum dma_ch *peri;
+ struct list_head node;
+ struct pl330_info *pi;
+ struct kmem_cache *kmcache;
+ struct clk *clk;
+};
+
+/**
+ * struct s3c_pl330_xfer - A request submitted by S3C DMA clients.
+ * @token: Xfer ID provided by the client.
+ * @node: To attach to the list of xfers on a channel.
+ * @px: Xfer for PL330 core.
+ * @chan: Owner channel of this xfer.
+ */
+struct s3c_pl330_xfer {
+ void *token;
+ struct list_head node;
+ struct pl330_xfer px;
+ struct s3c_pl330_chan *chan;
+};
+
+/**
+ * struct s3c_pl330_chan - Logical channel to communicate with
+ * a Physical peripheral.
+ * @pl330_chan_id: Token of a hardware channel thread of PL330 DMAC.
+ * NULL if the channel is available to be acquired.
+ * @id: ID of the peripheral that this channel can communicate with.
+ * @options: Options specified by the client.
+ * @sdaddr: Address provided via s3c2410_dma_devconfig.
+ * @node: To attach to the global list of channels.
+ * @lrq: Pointer to the last submitted pl330_req to PL330 core.
+ * @xfer_list: To manage list of xfers enqueued.
+ * @req: Two requests to communicate with the PL330 engine.
+ * @callback_fn: Callback function to the client.
+ * @rqcfg: Channel configuration for the xfers.
+ * @xfer_head: Pointer to the xfer to be next executed.
+ * @dmac: Pointer to the DMAC that manages this channel, NULL if the
+ * channel is available to be acquired.
+ * @client: Client of this channel. NULL if the
+ * channel is available to be acquired.
+ */
+struct s3c_pl330_chan {
+ void *pl330_chan_id;
+ enum dma_ch id;
+ unsigned int options;
+ unsigned long sdaddr;
+ struct list_head node;
+ struct pl330_req *lrq;
+ struct list_head xfer_list;
+ struct pl330_req req[2];
+ s3c2410_dma_cbfn_t callback_fn;
+ struct pl330_reqcfg rqcfg;
+ struct s3c_pl330_xfer *xfer_head;
+ struct s3c_pl330_dmac *dmac;
+ struct s3c2410_dma_client *client;
+};
+
+/* All DMACs in the platform */
+static LIST_HEAD(dmac_list);
+
+/* All channels to peripherals in the platform */
+static LIST_HEAD(chan_list);
+
+/*
+ * Since we add resources(DMACs and Channels) to the global pool,
+ * we need to guard access to the resources using a global lock
+ */
+static DEFINE_SPINLOCK(res_lock);
+
+/* Returns the channel with ID 'id' in the chan_list */
+static struct s3c_pl330_chan *id_to_chan(const enum dma_ch id)
+{
+ struct s3c_pl330_chan *ch;
+
+ list_for_each_entry(ch, &chan_list, node)
+ if (ch->id == id)
+ return ch;
+
+ return NULL;
+}
+
+/* Allocate a new channel with ID 'id' and add to chan_list */
+static void chan_add(const enum dma_ch id)
+{
+ struct s3c_pl330_chan *ch = id_to_chan(id);
+
+ /* Return if the channel already exists */
+ if (ch)
+ return;
+
+ ch = kmalloc(sizeof(*ch), GFP_KERNEL);
+ /* Return silently to work with other channels */
+ if (!ch)
+ return;
+
+ ch->id = id;
+ ch->dmac = NULL;
+
+ list_add_tail(&ch->node, &chan_list);
+}
+
+/* If the channel is not yet acquired by any client */
+static bool chan_free(struct s3c_pl330_chan *ch)
+{
+ if (!ch)
+ return false;
+
+ /* Channel points to some DMAC only when it's acquired */
+ return ch->dmac ? false : true;
+}
+
+/*
+ * Returns 0 is peripheral i/f is invalid or not present on the dmac.
+ * Index + 1, otherwise.
+ */
+static unsigned iface_of_dmac(struct s3c_pl330_dmac *dmac, enum dma_ch ch_id)
+{
+ enum dma_ch *id = dmac->peri;
+ int i;
+
+ /* Discount invalid markers */
+ if (ch_id == DMACH_MAX)
+ return 0;
+
+ for (i = 0; i < PL330_MAX_PERI; i++)
+ if (id[i] == ch_id)
+ return i + 1;
+
+ return 0;
+}
+
+/* If all channel threads of the DMAC are busy */
+static inline bool dmac_busy(struct s3c_pl330_dmac *dmac)
+{
+ struct pl330_info *pi = dmac->pi;
+
+ return (dmac->busy_chan < pi->pcfg.num_chan) ? false : true;
+}
+
+/*
+ * Returns the number of free channels that
+ * can be handled by this dmac only.
+ */
+static unsigned ch_onlyby_dmac(struct s3c_pl330_dmac *dmac)
+{
+ enum dma_ch *id = dmac->peri;
+ struct s3c_pl330_dmac *d;
+ struct s3c_pl330_chan *ch;
+ unsigned found, count = 0;
+ enum dma_ch p;
+ int i;
+
+ for (i = 0; i < PL330_MAX_PERI; i++) {
+ p = id[i];
+ ch = id_to_chan(p);
+
+ if (p == DMACH_MAX || !chan_free(ch))
+ continue;
+
+ found = 0;
+ list_for_each_entry(d, &dmac_list, node) {
+ if (d != dmac && iface_of_dmac(d, ch->id)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ count++;
+ }
+
+ return count;
+}
+
+/*
+ * Measure of suitability of 'dmac' handling 'ch'
+ *
+ * 0 indicates 'dmac' can not handle 'ch' either
+ * because it is not supported by the hardware or
+ * because all dmac channels are currently busy.
+ *
+ * >0 vlaue indicates 'dmac' has the capability.
+ * The bigger the value the more suitable the dmac.
+ */
+#define MAX_SUIT UINT_MAX
+#define MIN_SUIT 0
+
+static unsigned suitablility(struct s3c_pl330_dmac *dmac,
+ struct s3c_pl330_chan *ch)
+{
+ struct pl330_info *pi = dmac->pi;
+ enum dma_ch *id = dmac->peri;
+ struct s3c_pl330_dmac *d;
+ unsigned s;
+ int i;
+
+ s = MIN_SUIT;
+ /* If all the DMAC channel threads are busy */
+ if (dmac_busy(dmac))
+ return s;
+
+ for (i = 0; i < PL330_MAX_PERI; i++)
+ if (id[i] == ch->id)
+ break;
+
+ /* If the 'dmac' can't talk to 'ch' */
+ if (i == PL330_MAX_PERI)
+ return s;
+
+ s = MAX_SUIT;
+ list_for_each_entry(d, &dmac_list, node) {
+ /*
+ * If some other dmac can talk to this
+ * peri and has some channel free.
+ */
+ if (d != dmac && iface_of_dmac(d, ch->id) && !dmac_busy(d)) {
+ s = 0;
+ break;
+ }
+ }
+ if (s)
+ return s;
+
+ s = 100;
+
+ /* Good if free chans are more, bad otherwise */
+ s += (pi->pcfg.num_chan - dmac->busy_chan) - ch_onlyby_dmac(dmac);
+
+ return s;
+}
+
+/* More than one DMAC may have capability to transfer data with the
+ * peripheral. This function assigns most suitable DMAC to manage the
+ * channel and hence communicate with the peripheral.
+ */
+static struct s3c_pl330_dmac *map_chan_to_dmac(struct s3c_pl330_chan *ch)
+{
+ struct s3c_pl330_dmac *d, *dmac = NULL;
+ unsigned sn, sl = MIN_SUIT;
+
+ list_for_each_entry(d, &dmac_list, node) {
+ sn = suitablility(d, ch);
+
+ if (sn == MAX_SUIT)
+ return d;
+
+ if (sn > sl)
+ dmac = d;
+ }
+
+ return dmac;
+}
+
+/* Acquire the channel for peripheral 'id' */
+static struct s3c_pl330_chan *chan_acquire(const enum dma_ch id)
+{
+ struct s3c_pl330_chan *ch = id_to_chan(id);
+ struct s3c_pl330_dmac *dmac;
+
+ /* If the channel doesn't exist or is already acquired */
+ if (!ch || !chan_free(ch)) {
+ ch = NULL;
+ goto acq_exit;
+ }
+
+ dmac = map_chan_to_dmac(ch);
+ /* If couldn't map */
+ if (!dmac) {
+ ch = NULL;
+ goto acq_exit;
+ }
+
+ dmac->busy_chan++;
+ ch->dmac = dmac;
+
+acq_exit:
+ return ch;
+}
+
+/* Delete xfer from the queue */
+static inline void del_from_queue(struct s3c_pl330_xfer *xfer)
+{
+ struct s3c_pl330_xfer *t;
+ struct s3c_pl330_chan *ch;
+ int found;
+
+ if (!xfer)
+ return;
+
+ ch = xfer->chan;
+
+ /* Make sure xfer is in the queue */
+ found = 0;
+ list_for_each_entry(t, &ch->xfer_list, node)
+ if (t == xfer) {
+ found = 1;
+ break;
+ }
+
+ if (!found)
+ return;
+
+ /* If xfer is last entry in the queue */
+ if (xfer->node.next == &ch->xfer_list)
+ t = list_entry(ch->xfer_list.next,
+ struct s3c_pl330_xfer, node);
+ else
+ t = list_entry(xfer->node.next,
+ struct s3c_pl330_xfer, node);
+
+ /* If there was only one node left */
+ if (t == xfer)
+ ch->xfer_head = NULL;
+ else if (ch->xfer_head == xfer)
+ ch->xfer_head = t;
+
+ list_del(&xfer->node);
+}
+
+/* Provides pointer to the next xfer in the queue.
+ * If CIRCULAR option is set, the list is left intact,
+ * otherwise the xfer is removed from the list.
+ * Forced delete 'pluck' can be set to override the CIRCULAR option.
+ */
+static struct s3c_pl330_xfer *get_from_queue(struct s3c_pl330_chan *ch,
+ int pluck)
+{
+ struct s3c_pl330_xfer *xfer = ch->xfer_head;
+
+ if (!xfer)
+ return NULL;
+
+ /* If xfer is last entry in the queue */
+ if (xfer->node.next == &ch->xfer_list)
+ ch->xfer_head = list_entry(ch->xfer_list.next,
+ struct s3c_pl330_xfer, node);
+ else
+ ch->xfer_head = list_entry(xfer->node.next,
+ struct s3c_pl330_xfer, node);
+
+ if (pluck || !(ch->options & S3C2410_DMAF_CIRCULAR))
+ del_from_queue(xfer);
+
+ return xfer;
+}
+
+static inline void add_to_queue(struct s3c_pl330_chan *ch,
+ struct s3c_pl330_xfer *xfer, int front)
+{
+ struct pl330_xfer *xt;
+
+ /* If queue empty */
+ if (ch->xfer_head == NULL)
+ ch->xfer_head = xfer;
+
+ xt = &ch->xfer_head->px;
+ /* If the head already submitted (CIRCULAR head) */
+ if (ch->options & S3C2410_DMAF_CIRCULAR &&
+ (xt == ch->req[0].x || xt == ch->req[1].x))
+ ch->xfer_head = xfer;
+
+ /* If this is a resubmission, it should go at the head */
+ if (front) {
+ ch->xfer_head = xfer;
+ list_add(&xfer->node, &ch->xfer_list);
+ } else {
+ list_add_tail(&xfer->node, &ch->xfer_list);
+ }
+}
+
+static inline void _finish_off(struct s3c_pl330_xfer *xfer,
+ enum s3c2410_dma_buffresult res, int ffree)
+{
+ struct s3c_pl330_chan *ch;
+
+ if (!xfer)
+ return;
+
+ ch = xfer->chan;
+
+ /* Do callback */
+ if (ch->callback_fn)
+ ch->callback_fn(NULL, xfer->token, xfer->px.bytes, res);
+
+ /* Force Free or if buffer is not needed anymore */
+ if (ffree || !(ch->options & S3C2410_DMAF_CIRCULAR))
+ kmem_cache_free(ch->dmac->kmcache, xfer);
+}
+
+static inline int s3c_pl330_submit(struct s3c_pl330_chan *ch,
+ struct pl330_req *r)
+{
+ struct s3c_pl330_xfer *xfer;
+ int ret = 0;
+
+ /* If already submitted */
+ if (r->x)
+ return 0;
+
+ xfer = get_from_queue(ch, 0);
+ if (xfer) {
+ r->x = &xfer->px;
+
+ /* Use max bandwidth for M<->M xfers */
+ if (r->rqtype == MEMTOMEM) {
+ struct pl330_info *pi = xfer->chan->dmac->pi;
+ int burst = 1 << ch->rqcfg.brst_size;
+ u32 bytes = r->x->bytes;
+ int bl;
+
+ bl = pi->pcfg.data_bus_width / 8;
+ bl *= pi->pcfg.data_buf_dep;
+ bl /= burst;
+
+ /* src/dst_burst_len can't be more than 16 */
+ if (bl > 16)
+ bl = 16;
+
+ while (bl > 1) {
+ if (!(bytes % (bl * burst)))
+ break;
+ bl--;
+ }
+
+ ch->rqcfg.brst_len = bl;
+ } else {
+ ch->rqcfg.brst_len = 1;
+ }
+
+ ret = pl330_submit_req(ch->pl330_chan_id, r);
+
+ /* If submission was successful */
+ if (!ret) {
+ ch->lrq = r; /* latest submitted req */
+ return 0;
+ }
+
+ r->x = NULL;
+
+ /* If both of the PL330 ping-pong buffers filled */
+ if (ret == -EAGAIN) {
+ dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+ __func__, __LINE__);
+ /* Queue back again */
+ add_to_queue(ch, xfer, 1);
+ ret = 0;
+ } else {
+ dev_err(ch->dmac->pi->dev, "%s:%d!\n",
+ __func__, __LINE__);
+ _finish_off(xfer, S3C2410_RES_ERR, 0);
+ }
+ }
+
+ return ret;
+}
+
+static void s3c_pl330_rq(struct s3c_pl330_chan *ch,
+ struct pl330_req *r, enum pl330_op_err err)
+{
+ unsigned long flags;
+ struct s3c_pl330_xfer *xfer;
+ struct pl330_xfer *xl = r->x;
+ enum s3c2410_dma_buffresult res;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ r->x = NULL;
+
+ s3c_pl330_submit(ch, r);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ /* Map result to S3C DMA API */
+ if (err == PL330_ERR_NONE)
+ res = S3C2410_RES_OK;
+ else if (err == PL330_ERR_ABORT)
+ res = S3C2410_RES_ABORT;
+ else
+ 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);
+ } else {
+ dev_info(ch->dmac->pi->dev, "%s:%d No Xfer?!\n",
+ __func__, __LINE__);
+ }
+}
+
+static void s3c_pl330_rq0(void *token, enum pl330_op_err err)
+{
+ struct pl330_req *r = token;
+ struct s3c_pl330_chan *ch = container_of(r,
+ struct s3c_pl330_chan, req[0]);
+ s3c_pl330_rq(ch, r, err);
+}
+
+static void s3c_pl330_rq1(void *token, enum pl330_op_err err)
+{
+ struct pl330_req *r = token;
+ struct s3c_pl330_chan *ch = container_of(r,
+ struct s3c_pl330_chan, req[1]);
+ s3c_pl330_rq(ch, r, err);
+}
+
+/* Release an acquired channel */
+static void chan_release(struct s3c_pl330_chan *ch)
+{
+ struct s3c_pl330_dmac *dmac;
+
+ if (chan_free(ch))
+ return;
+
+ dmac = ch->dmac;
+ ch->dmac = NULL;
+ dmac->busy_chan--;
+}
+
+int s3c2410_dma_ctrl(enum dma_ch id, enum s3c2410_chan_op op)
+{
+ struct s3c_pl330_xfer *xfer;
+ enum pl330_chan_op pl330op;
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int idx, ret;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch)) {
+ ret = -EINVAL;
+ goto ctrl_exit;
+ }
+
+ switch (op) {
+ case S3C2410_DMAOP_START:
+ /* Make sure both reqs are enqueued */
+ idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+ s3c_pl330_submit(ch, &ch->req[idx]);
+ s3c_pl330_submit(ch, &ch->req[1 - idx]);
+ pl330op = PL330_OP_START;
+ break;
+
+ case S3C2410_DMAOP_STOP:
+ pl330op = PL330_OP_ABORT;
+ break;
+
+ case S3C2410_DMAOP_FLUSH:
+ pl330op = PL330_OP_FLUSH;
+ break;
+
+ case S3C2410_DMAOP_PAUSE:
+ case S3C2410_DMAOP_RESUME:
+ case S3C2410_DMAOP_TIMEOUT:
+ case S3C2410_DMAOP_STARTED:
+ spin_unlock_irqrestore(&res_lock, flags);
+ return 0;
+
+ default:
+ spin_unlock_irqrestore(&res_lock, flags);
+ return -EINVAL;
+ }
+
+ ret = pl330_chan_ctrl(ch->pl330_chan_id, pl330op);
+
+ if (pl330op == PL330_OP_START) {
+ spin_unlock_irqrestore(&res_lock, flags);
+ return ret;
+ }
+
+ idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+ /* Abort the current xfer */
+ if (ch->req[idx].x) {
+ xfer = container_of(ch->req[idx].x,
+ struct s3c_pl330_xfer, px);
+
+ /* Drop xfer during FLUSH */
+ if (pl330op == PL330_OP_FLUSH)
+ del_from_queue(xfer);
+
+ ch->req[idx].x = NULL;
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT,
+ pl330op == PL330_OP_FLUSH ? 1 : 0);
+ spin_lock_irqsave(&res_lock, flags);
+ }
+
+ /* Flush the whole queue */
+ if (pl330op == PL330_OP_FLUSH) {
+
+ if (ch->req[1 - idx].x) {
+ xfer = container_of(ch->req[1 - idx].x,
+ struct s3c_pl330_xfer, px);
+
+ del_from_queue(xfer);
+
+ ch->req[1 - idx].x = NULL;
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT, 1);
+ spin_lock_irqsave(&res_lock, flags);
+ }
+
+ /* Finish off the remaining in the queue */
+ xfer = ch->xfer_head;
+ while (xfer) {
+
+ del_from_queue(xfer);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT, 1);
+ spin_lock_irqsave(&res_lock, flags);
+
+ xfer = ch->xfer_head;
+ }
+ }
+
+ctrl_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_ctrl);
+
+int s3c2410_dma_enqueue(enum dma_ch id, void *token,
+ dma_addr_t addr, int size)
+{
+ struct s3c_pl330_chan *ch;
+ struct s3c_pl330_xfer *xfer;
+ unsigned long flags;
+ int idx, ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ /* Error if invalid or free channel */
+ if (!ch || chan_free(ch)) {
+ ret = -EINVAL;
+ goto enq_exit;
+ }
+
+ /* Error if size is unaligned */
+ if (ch->rqcfg.brst_size && size % (1 << ch->rqcfg.brst_size)) {
+ ret = -EINVAL;
+ goto enq_exit;
+ }
+
+ xfer = kmem_cache_alloc(ch->dmac->kmcache, GFP_ATOMIC);
+ if (!xfer) {
+ ret = -ENOMEM;
+ goto enq_exit;
+ }
+
+ xfer->token = token;
+ xfer->chan = ch;
+ xfer->px.bytes = size;
+ xfer->px.next = NULL; /* Single request */
+
+ /* For S3C DMA API, direction is always fixed for all xfers */
+ if (ch->req[0].rqtype == MEMTODEV) {
+ xfer->px.src_addr = addr;
+ xfer->px.dst_addr = ch->sdaddr;
+ } else {
+ xfer->px.src_addr = ch->sdaddr;
+ xfer->px.dst_addr = addr;
+ }
+
+ add_to_queue(ch, xfer, 0);
+
+ /* Try submitting on either request */
+ idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+ if (!ch->req[idx].x)
+ s3c_pl330_submit(ch, &ch->req[idx]);
+ else
+ s3c_pl330_submit(ch, &ch->req[1 - idx]);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ if (ch->options & S3C2410_DMAF_AUTOSTART)
+ s3c2410_dma_ctrl(id, S3C2410_DMAOP_START);
+
+ return 0;
+
+enq_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_enqueue);
+
+int s3c2410_dma_request(enum dma_ch id,
+ struct s3c2410_dma_client *client,
+ void *dev)
+{
+ struct s3c_pl330_dmac *dmac;
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = chan_acquire(id);
+ if (!ch) {
+ ret = -EBUSY;
+ goto req_exit;
+ }
+
+ dmac = ch->dmac;
+
+ ch->pl330_chan_id = pl330_request_channel(dmac->pi);
+ if (!ch->pl330_chan_id) {
+ chan_release(ch);
+ ret = -EBUSY;
+ goto req_exit;
+ }
+
+ ch->client = client;
+ ch->options = 0; /* Clear any option */
+ ch->callback_fn = NULL; /* Clear any callback */
+ ch->lrq = NULL;
+
+ ch->rqcfg.brst_size = 2; /* Default word size */
+ ch->rqcfg.swap = SWAP_NO;
+ ch->rqcfg.scctl = SCCTRL0; /* Noncacheable and nonbufferable */
+ ch->rqcfg.dcctl = DCCTRL0; /* Noncacheable and nonbufferable */
+ ch->rqcfg.privileged = 0;
+ ch->rqcfg.insnaccess = 0;
+
+ /* Set invalid direction */
+ ch->req[0].rqtype = DEVTODEV;
+ ch->req[1].rqtype = ch->req[0].rqtype;
+
+ ch->req[0].cfg = &ch->rqcfg;
+ ch->req[1].cfg = ch->req[0].cfg;
+
+ ch->req[0].peri = iface_of_dmac(dmac, id) - 1; /* Original index */
+ ch->req[1].peri = ch->req[0].peri;
+
+ ch->req[0].token = &ch->req[0];
+ ch->req[0].xfer_cb = s3c_pl330_rq0;
+ ch->req[1].token = &ch->req[1];
+ ch->req[1].xfer_cb = s3c_pl330_rq1;
+
+ ch->req[0].x = NULL;
+ ch->req[1].x = NULL;
+
+ /* Reset xfer list */
+ INIT_LIST_HEAD(&ch->xfer_list);
+ ch->xfer_head = NULL;
+
+req_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_request);
+
+int s3c2410_dma_free(enum dma_ch id, struct s3c2410_dma_client *client)
+{
+ struct s3c_pl330_chan *ch;
+ struct s3c_pl330_xfer *xfer;
+ unsigned long flags;
+ int ret = 0;
+ unsigned idx;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch))
+ goto free_exit;
+
+ /* Refuse if someone else wanted to free the channel */
+ if (ch->client != client) {
+ ret = -EBUSY;
+ goto free_exit;
+ }
+
+ /* Stop any active xfer, Flushe the queue and do callbacks */
+ pl330_chan_ctrl(ch->pl330_chan_id, PL330_OP_FLUSH);
+
+ /* Abort the submitted requests */
+ idx = (ch->lrq == &ch->req[0]) ? 1 : 0;
+
+ if (ch->req[idx].x) {
+ xfer = container_of(ch->req[idx].x,
+ struct s3c_pl330_xfer, px);
+
+ ch->req[idx].x = NULL;
+ del_from_queue(xfer);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT, 1);
+ spin_lock_irqsave(&res_lock, flags);
+ }
+
+ if (ch->req[1 - idx].x) {
+ xfer = container_of(ch->req[1 - idx].x,
+ struct s3c_pl330_xfer, px);
+
+ ch->req[1 - idx].x = NULL;
+ del_from_queue(xfer);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT, 1);
+ spin_lock_irqsave(&res_lock, flags);
+ }
+
+ /* Pluck and Abort the queued requests in order */
+ do {
+ xfer = get_from_queue(ch, 1);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+ _finish_off(xfer, S3C2410_RES_ABORT, 1);
+ spin_lock_irqsave(&res_lock, flags);
+ } while (xfer);
+
+ ch->client = NULL;
+
+ pl330_release_channel(ch->pl330_chan_id);
+
+ ch->pl330_chan_id = NULL;
+
+ chan_release(ch);
+
+free_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_free);
+
+int s3c2410_dma_config(enum dma_ch id, int xferunit)
+{
+ struct s3c_pl330_chan *ch;
+ struct pl330_info *pi;
+ unsigned long flags;
+ int i, dbwidth, ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch)) {
+ ret = -EINVAL;
+ goto cfg_exit;
+ }
+
+ pi = ch->dmac->pi;
+ dbwidth = pi->pcfg.data_bus_width / 8;
+
+ /* Max size of xfer can be pcfg.data_bus_width */
+ if (xferunit > dbwidth) {
+ ret = -EINVAL;
+ goto cfg_exit;
+ }
+
+ i = 0;
+ while (xferunit != (1 << i))
+ i++;
+
+ /* If valid value */
+ if (xferunit == (1 << i))
+ ch->rqcfg.brst_size = i;
+ else
+ ret = -EINVAL;
+
+cfg_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_config);
+
+/* Options that are supported by this driver */
+#define S3C_PL330_FLAGS (S3C2410_DMAF_CIRCULAR | S3C2410_DMAF_AUTOSTART)
+
+int s3c2410_dma_setflags(enum dma_ch id, unsigned int options)
+{
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch) || options & ~(S3C_PL330_FLAGS))
+ ret = -EINVAL;
+ else
+ ch->options = options;
+
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_setflags);
+
+int s3c2410_dma_set_buffdone_fn(enum dma_ch id, s3c2410_dma_cbfn_t rtn)
+{
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch))
+ ret = -EINVAL;
+ else
+ ch->callback_fn = rtn;
+
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
+
+int s3c2410_dma_devconfig(enum dma_ch id, enum s3c2410_dmasrc source,
+ unsigned long address)
+{
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ ch = id_to_chan(id);
+
+ if (!ch || chan_free(ch)) {
+ ret = -EINVAL;
+ goto devcfg_exit;
+ }
+
+ switch (source) {
+ case S3C2410_DMASRC_HW: /* P->M */
+ ch->req[0].rqtype = DEVTOMEM;
+ ch->req[1].rqtype = DEVTOMEM;
+ ch->rqcfg.src_inc = 0;
+ ch->rqcfg.dst_inc = 1;
+ break;
+ case S3C2410_DMASRC_MEM: /* M->P */
+ ch->req[0].rqtype = MEMTODEV;
+ ch->req[1].rqtype = MEMTODEV;
+ ch->rqcfg.src_inc = 1;
+ ch->rqcfg.dst_inc = 0;
+ break;
+ default:
+ ret = -EINVAL;
+ goto devcfg_exit;
+ }
+
+ ch->sdaddr = address;
+
+devcfg_exit:
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+int s3c2410_dma_getposition(enum dma_ch id, dma_addr_t *src, dma_addr_t *dst)
+{
+ struct s3c_pl330_chan *ch = id_to_chan(id);
+ struct pl330_chanstatus status;
+ int ret;
+
+ if (!ch || chan_free(ch))
+ return -EINVAL;
+
+ ret = pl330_chan_status(ch->pl330_chan_id, &status);
+ if (ret < 0)
+ return ret;
+
+ *src = status.src_addr;
+ *dst = status.dst_addr;
+
+ return 0;
+}
+EXPORT_SYMBOL(s3c2410_dma_getposition);
+
+static irqreturn_t pl330_irq_handler(int irq, void *data)
+{
+ if (pl330_update(data))
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
+static int pl330_probe(struct platform_device *pdev)
+{
+ struct s3c_pl330_dmac *s3c_pl330_dmac;
+ struct s3c_pl330_platdata *pl330pd;
+ struct pl330_info *pl330_info;
+ struct resource *res;
+ int i, ret, irq;
+
+ pl330pd = pdev->dev.platform_data;
+
+ /* Can't do without the list of _32_ peripherals */
+ if (!pl330pd || !pl330pd->peri) {
+ dev_err(&pdev->dev, "platform data missing!\n");
+ return -ENODEV;
+ }
+
+ pl330_info = kzalloc(sizeof(*pl330_info), GFP_KERNEL);
+ if (!pl330_info)
+ return -ENOMEM;
+
+ pl330_info->pl330_data = NULL;
+ pl330_info->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENODEV;
+ goto probe_err1;
+ }
+
+ request_mem_region(res->start, resource_size(res), pdev->name);
+
+ pl330_info->base = ioremap(res->start, resource_size(res));
+ if (!pl330_info->base) {
+ ret = -ENXIO;
+ goto probe_err2;
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = irq;
+ goto probe_err3;
+ }
+
+ ret = request_irq(irq, pl330_irq_handler, 0,
+ dev_name(&pdev->dev), pl330_info);
+ if (ret)
+ goto probe_err4;
+
+ /* Allocate a new DMAC */
+ s3c_pl330_dmac = kmalloc(sizeof(*s3c_pl330_dmac), GFP_KERNEL);
+ if (!s3c_pl330_dmac) {
+ ret = -ENOMEM;
+ goto probe_err5;
+ }
+
+ /* Get operation clock and enable it */
+ s3c_pl330_dmac->clk = clk_get(&pdev->dev, "pdma");
+ if (IS_ERR(s3c_pl330_dmac->clk)) {
+ dev_err(&pdev->dev, "Cannot get operation clock.\n");
+ ret = -EINVAL;
+ goto probe_err6;
+ }
+ clk_enable(s3c_pl330_dmac->clk);
+
+ ret = pl330_add(pl330_info);
+ if (ret)
+ goto probe_err7;
+
+ /* Hook the info */
+ s3c_pl330_dmac->pi = pl330_info;
+
+ /* No busy channels */
+ s3c_pl330_dmac->busy_chan = 0;
+
+ s3c_pl330_dmac->kmcache = kmem_cache_create(dev_name(&pdev->dev),
+ sizeof(struct s3c_pl330_xfer), 0, 0, NULL);
+
+ if (!s3c_pl330_dmac->kmcache) {
+ ret = -ENOMEM;
+ goto probe_err8;
+ }
+
+ /* Get the list of peripherals */
+ s3c_pl330_dmac->peri = pl330pd->peri;
+
+ /* Attach to the list of DMACs */
+ list_add_tail(&s3c_pl330_dmac->node, &dmac_list);
+
+ /* Create a channel for each peripheral in the DMAC
+ * that is, if it doesn't already exist
+ */
+ for (i = 0; i < PL330_MAX_PERI; i++)
+ if (s3c_pl330_dmac->peri[i] != DMACH_MAX)
+ chan_add(s3c_pl330_dmac->peri[i]);
+
+ printk(KERN_INFO
+ "Loaded driver for PL330 DMAC-%d %s\n", pdev->id, pdev->name);
+ printk(KERN_INFO
+ "\tDBUFF-%ux%ubytes Num_Chans-%u Num_Peri-%u Num_Events-%u\n",
+ pl330_info->pcfg.data_buf_dep,
+ pl330_info->pcfg.data_bus_width / 8, pl330_info->pcfg.num_chan,
+ pl330_info->pcfg.num_peri, pl330_info->pcfg.num_events);
+
+ return 0;
+
+probe_err8:
+ pl330_del(pl330_info);
+probe_err7:
+ clk_disable(s3c_pl330_dmac->clk);
+ clk_put(s3c_pl330_dmac->clk);
+probe_err6:
+ kfree(s3c_pl330_dmac);
+probe_err5:
+ free_irq(irq, pl330_info);
+probe_err4:
+probe_err3:
+ iounmap(pl330_info->base);
+probe_err2:
+ release_mem_region(res->start, resource_size(res));
+probe_err1:
+ kfree(pl330_info);
+
+ return ret;
+}
+
+static int pl330_remove(struct platform_device *pdev)
+{
+ struct s3c_pl330_dmac *dmac, *d;
+ struct s3c_pl330_chan *ch;
+ unsigned long flags;
+ int del, found;
+
+ if (!pdev->dev.platform_data)
+ return -EINVAL;
+
+ spin_lock_irqsave(&res_lock, flags);
+
+ found = 0;
+ list_for_each_entry(d, &dmac_list, node)
+ if (d->pi->dev == &pdev->dev) {
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ spin_unlock_irqrestore(&res_lock, flags);
+ return 0;
+ }
+
+ dmac = d;
+
+ /* Remove all Channels that are managed only by this DMAC */
+ list_for_each_entry(ch, &chan_list, node) {
+
+ /* Only channels that are handled by this DMAC */
+ if (iface_of_dmac(dmac, ch->id))
+ del = 1;
+ else
+ continue;
+
+ /* Don't remove if some other DMAC has it too */
+ list_for_each_entry(d, &dmac_list, node)
+ if (d != dmac && iface_of_dmac(d, ch->id)) {
+ del = 0;
+ break;
+ }
+
+ if (del) {
+ spin_unlock_irqrestore(&res_lock, flags);
+ s3c2410_dma_free(ch->id, ch->client);
+ spin_lock_irqsave(&res_lock, flags);
+ list_del(&ch->node);
+ kfree(ch);
+ }
+ }
+
+ /* Disable operation clock */
+ clk_disable(dmac->clk);
+ clk_put(dmac->clk);
+
+ /* Remove the DMAC */
+ list_del(&dmac->node);
+ kfree(dmac);
+
+ spin_unlock_irqrestore(&res_lock, flags);
+
+ return 0;
+}
+
+static struct platform_driver pl330_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-pl330",
+ },
+ .probe = pl330_probe,
+ .remove = pl330_remove,
+};
+
+static int __init pl330_init(void)
+{
+ return platform_driver_register(&pl330_driver);
+}
+module_init(pl330_init);
+
+static void __exit pl330_exit(void)
+{
+ platform_driver_unregister(&pl330_driver);
+ return;
+}
+module_exit(pl330_exit);
+
+MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>");
+MODULE_DESCRIPTION("Driver for PL330 DMA Controller");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
new file mode 100644
index 00000000..2231d80a
--- /dev/null
+++ b/arch/arm/plat-samsung/time.c
@@ -0,0 +1,285 @@
+/* linux/arch/arm/plat-samsung/time.c
+ *
+ * Copyright (C) 2003-2005 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 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/sched.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <asm/system.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+
+#include <asm/irq.h>
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <mach/regs-irq.h>
+#include <asm/mach/time.h>
+#include <mach/tick.h>
+
+#include <plat/clock.h>
+#include <plat/cpu.h>
+
+static unsigned long timer_startval;
+static unsigned long timer_usec_ticks;
+
+#ifndef TICK_MAX
+#define TICK_MAX (0xffff)
+#endif
+
+#define TIMER_USEC_SHIFT 16
+
+/* we use the shifted arithmetic to work out the ratio of timer ticks
+ * to usecs, as often the peripheral clock is not a nice even multiple
+ * of 1MHz.
+ *
+ * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
+ * for the current HZ value of 200 without producing overflows.
+ *
+ * Original patch by Dimitry Andric, updated by Ben Dooks
+*/
+
+
+/* timer_mask_usec_ticks
+ *
+ * given a clock and divisor, make the value to pass into timer_ticks_to_usec
+ * to scale the ticks into usecs
+*/
+
+static inline unsigned long
+timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
+{
+ unsigned long den = pclk / 1000;
+
+ return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
+}
+
+/* timer_ticks_to_usec
+ *
+ * convert timer ticks to usec.
+*/
+
+static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
+{
+ unsigned long res;
+
+ res = ticks * timer_usec_ticks;
+ res += 1 << (TIMER_USEC_SHIFT - 4); /* round up slightly */
+
+ return res >> TIMER_USEC_SHIFT;
+}
+
+/***
+ * Returns microsecond since last clock interrupt. Note that interrupts
+ * will have been disabled by do_gettimeoffset()
+ * IRQs are disabled before entering here from do_gettimeofday()
+ */
+
+static unsigned long s3c2410_gettimeoffset (void)
+{
+ unsigned long tdone;
+ unsigned long tval;
+
+ /* work out how many ticks have gone since last timer interrupt */
+
+ tval = __raw_readl(S3C2410_TCNTO(4));
+ tdone = timer_startval - tval;
+
+ /* check to see if there is an interrupt pending */
+
+ if (s3c24xx_ostimer_pending()) {
+ /* re-read the timer, and try and fix up for the missed
+ * interrupt. Note, the interrupt may go off before the
+ * timer has re-loaded from wrapping.
+ */
+
+ tval = __raw_readl(S3C2410_TCNTO(4));
+ tdone = timer_startval - tval;
+
+ if (tval != 0)
+ tdone += timer_startval;
+ }
+
+ return timer_ticks_to_usec(tdone);
+}
+
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t
+s3c2410_timer_interrupt(int irq, void *dev_id)
+{
+ timer_tick();
+ return IRQ_HANDLED;
+}
+
+static struct irqaction s3c2410_timer_irq = {
+ .name = "S3C2410 Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = s3c2410_timer_interrupt,
+};
+
+#define use_tclk1_12() ( \
+ machine_is_bast() || \
+ machine_is_vr1000() || \
+ machine_is_anubis() || \
+ machine_is_osiris())
+
+static struct clk *tin;
+static struct clk *tdiv;
+static struct clk *timerclk;
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ *
+ * Currently we only use timer4, as it is the only timer which has no
+ * other function that can be exploited externally
+ */
+static void s3c2410_timer_setup (void)
+{
+ unsigned long tcon;
+ unsigned long tcnt;
+ unsigned long tcfg1;
+ unsigned long tcfg0;
+
+ tcnt = TICK_MAX; /* default value for tcnt */
+
+ /* configure the system for whichever machine is in use */
+
+ if (use_tclk1_12()) {
+ /* timer is at 12MHz, scaler is 1 */
+ timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
+ tcnt = 12000000 / HZ;
+
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+ tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
+ tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+ } else {
+ unsigned long pclk;
+ struct clk *tscaler;
+
+ /* for the h1940 (and others), we use the pclk from the core
+ * to generate the timer values. since values around 50 to
+ * 70MHz are not values we can directly generate the timer
+ * value from, we need to pre-scale and divide before using it.
+ *
+ * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
+ * (8.45 ticks per usec)
+ */
+
+ pclk = clk_get_rate(timerclk);
+
+ /* configure clock tick */
+
+ timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
+
+ tscaler = clk_get_parent(tdiv);
+
+ clk_set_rate(tscaler, pclk / 3);
+ clk_set_rate(tdiv, pclk / 6);
+ clk_set_parent(tin, tdiv);
+
+ tcnt = clk_get_rate(tin) / HZ;
+ }
+
+ tcon = __raw_readl(S3C2410_TCON);
+ tcfg0 = __raw_readl(S3C2410_TCFG0);
+ tcfg1 = __raw_readl(S3C2410_TCFG1);
+
+ /* timers reload after counting zero, so reduce the count by 1 */
+
+ tcnt--;
+
+ printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
+ tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
+
+ /* check to see if timer is within 16bit range... */
+ if (tcnt > TICK_MAX) {
+ panic("setup_timer: HZ is too small, cannot configure timer!");
+ return;
+ }
+
+ __raw_writel(tcfg1, S3C2410_TCFG1);
+ __raw_writel(tcfg0, S3C2410_TCFG0);
+
+ timer_startval = tcnt;
+ __raw_writel(tcnt, S3C2410_TCNTB(4));
+
+ /* ensure timer is stopped... */
+
+ tcon &= ~(7<<20);
+ tcon |= S3C2410_TCON_T4RELOAD;
+ tcon |= S3C2410_TCON_T4MANUALUPD;
+
+ __raw_writel(tcon, S3C2410_TCON);
+ __raw_writel(tcnt, S3C2410_TCNTB(4));
+ __raw_writel(tcnt, S3C2410_TCMPB(4));
+
+ /* start the timer running */
+ tcon |= S3C2410_TCON_T4START;
+ tcon &= ~S3C2410_TCON_T4MANUALUPD;
+ __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void __init s3c2410_timer_resources(void)
+{
+ struct platform_device tmpdev;
+
+ tmpdev.dev.bus = &platform_bus_type;
+ tmpdev.id = 4;
+
+ timerclk = clk_get(NULL, "timers");
+ if (IS_ERR(timerclk))
+ panic("failed to get clock for system timer");
+
+ clk_enable(timerclk);
+
+ if (!use_tclk1_12()) {
+ tin = clk_get(&tmpdev.dev, "pwm-tin");
+ if (IS_ERR(tin))
+ panic("failed to get pwm-tin clock for system timer");
+
+ tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
+ if (IS_ERR(tdiv))
+ panic("failed to get pwm-tdiv clock for system timer");
+ }
+
+ clk_enable(tin);
+}
+
+static void __init s3c2410_timer_init(void)
+{
+ s3c2410_timer_resources();
+ s3c2410_timer_setup();
+ setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
+}
+
+struct sys_timer s3c24xx_timer = {
+ .init = s3c2410_timer_init,
+ .offset = s3c2410_gettimeoffset,
+ .resume = s3c2410_timer_setup
+};
diff --git a/arch/arm/plat-samsung/wakeup-mask.c b/arch/arm/plat-samsung/wakeup-mask.c
new file mode 100644
index 00000000..dc814037
--- /dev/null
+++ b/arch/arm/plat-samsung/wakeup-mask.c
@@ -0,0 +1,47 @@
+/* arch/arm/plat-samsung/wakeup-mask.c
+ *
+ * Copyright 2010 Ben Dooks <ben-linux@fluff.org>
+ *
+ * Support for wakeup mask interrupts on newer SoCs
+ *
+ * This program is free software; you can 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/spinlock.h>
+#include <linux/sysdev.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <plat/wakeup-mask.h>
+#include <plat/pm.h>
+
+void samsung_sync_wakemask(void __iomem *reg,
+ struct samsung_wakeup_mask *mask, int nr_mask)
+{
+ struct irq_data *data;
+ u32 val;
+
+ val = __raw_readl(reg);
+
+ for (; nr_mask > 0; nr_mask--, mask++) {
+ if (mask->irq == NO_WAKEUP_IRQ) {
+ val |= mask->bit;
+ continue;
+ }
+
+ data = irq_get_irq_data(mask->irq);
+
+ /* bit of a liberty to read this directly from irq_data. */
+ if (irqd_is_wakeup_set(data))
+ val &= ~mask->bit;
+ else
+ val |= mask->bit;
+ }
+
+ printk(KERN_INFO "wakemask %08x => %08x\n", __raw_readl(reg), val);
+ __raw_writel(val, reg);
+}
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig
new file mode 100644
index 00000000..1bb3dbce
--- /dev/null
+++ b/arch/arm/plat-spear/Kconfig
@@ -0,0 +1,31 @@
+#
+# SPEAr Platform configuration file
+#
+
+if PLAT_SPEAR
+
+choice
+ prompt "ST SPEAr Family"
+ default ARCH_SPEAR3XX
+
+config ARCH_SPEAR3XX
+ bool "SPEAr3XX"
+ select ARM_VIC
+ select CPU_ARM926T
+ help
+ Supports for ARM's SPEAR3XX family
+
+config ARCH_SPEAR6XX
+ bool "SPEAr6XX"
+ select ARM_VIC
+ select CPU_ARM926T
+ help
+ Supports for ARM's SPEAR6XX family
+
+endchoice
+
+# Adding SPEAr machine specific configuration files
+source "arch/arm/mach-spear3xx/Kconfig"
+source "arch/arm/mach-spear6xx/Kconfig"
+
+endif
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile
new file mode 100644
index 00000000..b4f340b8
--- /dev/null
+++ b/arch/arm/plat-spear/Makefile
@@ -0,0 +1,8 @@
+#
+# SPEAr Platform specific Makefile
+#
+
+# Common support
+obj-y := clock.o time.o
+
+obj-$(CONFIG_ARCH_SPEAR3XX) += shirq.o padmux.o
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c
new file mode 100644
index 00000000..6fa474cb
--- /dev/null
+++ b/arch/arm/plat-spear/clock.c
@@ -0,0 +1,1008 @@
+/*
+ * arch/arm/plat-spear/clock.c
+ *
+ * Clock framework for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/bug.h>
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <plat/clock.h>
+
+static DEFINE_SPINLOCK(clocks_lock);
+static LIST_HEAD(root_clks);
+#ifdef CONFIG_DEBUG_FS
+static LIST_HEAD(clocks);
+#endif
+
+static void propagate_rate(struct clk *, int on_init);
+#ifdef CONFIG_DEBUG_FS
+static int clk_debugfs_reparent(struct clk *);
+#endif
+
+static int generic_clk_enable(struct clk *clk)
+{
+ unsigned int val;
+
+ if (!clk->en_reg)
+ return -EFAULT;
+
+ val = readl(clk->en_reg);
+ if (unlikely(clk->flags & RESET_TO_ENABLE))
+ val &= ~(1 << clk->en_reg_bit);
+ else
+ val |= 1 << clk->en_reg_bit;
+
+ writel(val, clk->en_reg);
+
+ return 0;
+}
+
+static void generic_clk_disable(struct clk *clk)
+{
+ unsigned int val;
+
+ if (!clk->en_reg)
+ return;
+
+ val = readl(clk->en_reg);
+ if (unlikely(clk->flags & RESET_TO_ENABLE))
+ val |= 1 << clk->en_reg_bit;
+ else
+ val &= ~(1 << clk->en_reg_bit);
+
+ writel(val, clk->en_reg);
+}
+
+/* generic clk ops */
+static struct clkops generic_clkops = {
+ .enable = generic_clk_enable,
+ .disable = generic_clk_disable,
+};
+
+/* returns current programmed clocks clock info structure */
+static struct pclk_info *pclk_info_get(struct clk *clk)
+{
+ unsigned int val, i;
+ struct pclk_info *info = NULL;
+
+ val = (readl(clk->pclk_sel->pclk_sel_reg) >> clk->pclk_sel_shift)
+ & clk->pclk_sel->pclk_sel_mask;
+
+ for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+ if (clk->pclk_sel->pclk_info[i].pclk_val == val)
+ info = &clk->pclk_sel->pclk_info[i];
+ }
+
+ return info;
+}
+
+/*
+ * Set Update pclk, and pclk_info of clk and add clock sibling node to current
+ * parents children list
+ */
+static void clk_reparent(struct clk *clk, struct pclk_info *pclk_info)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ list_del(&clk->sibling);
+ list_add(&clk->sibling, &pclk_info->pclk->children);
+
+ clk->pclk = pclk_info->pclk;
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+#ifdef CONFIG_DEBUG_FS
+ clk_debugfs_reparent(clk);
+#endif
+}
+
+static void do_clk_disable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ if (!clk->usage_count) {
+ WARN_ON(1);
+ return;
+ }
+
+ clk->usage_count--;
+
+ if (clk->usage_count == 0) {
+ /*
+ * Surely, there are no active childrens or direct users
+ * of this clock
+ */
+ if (clk->pclk)
+ do_clk_disable(clk->pclk);
+
+ if (clk->ops && clk->ops->disable)
+ clk->ops->disable(clk);
+ }
+}
+
+static int do_clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk)
+ return -EFAULT;
+
+ if (clk->usage_count == 0) {
+ if (clk->pclk) {
+ ret = do_clk_enable(clk->pclk);
+ if (ret)
+ goto err;
+ }
+ if (clk->ops && clk->ops->enable) {
+ ret = clk->ops->enable(clk);
+ if (ret) {
+ if (clk->pclk)
+ do_clk_disable(clk->pclk);
+ goto err;
+ }
+ }
+ /*
+ * Since the clock is going to be used for the first
+ * time please reclac
+ */
+ if (clk->recalc) {
+ ret = clk->recalc(clk);
+ if (ret)
+ goto err;
+ }
+ }
+ clk->usage_count++;
+err:
+ return ret;
+}
+
+/*
+ * clk_enable - inform the system when the clock source should be running.
+ * @clk: clock source
+ *
+ * If the clock can not be enabled/disabled, this should return success.
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ ret = do_clk_enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/*
+ * clk_disable - inform the system when the clock source is no longer required.
+ * @clk: clock source
+ *
+ * Inform the system that a clock source is no longer required by
+ * a driver and may be shut down.
+ *
+ * Implementation detail: if the clock source is shared between
+ * multiple drivers, clk_enable() calls must be balanced by the
+ * same number of clk_disable() calls for the clock source to be
+ * disabled.
+ */
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ do_clk_disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/**
+ * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
+ * This is only valid once the clock source has been enabled.
+ * @clk: clock source
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ unsigned long flags, rate;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ rate = clk->rate;
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ return rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/**
+ * clk_set_parent - set the parent clock source for this clock
+ * @clk: clock source
+ * @parent: parent clock source
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int i, found = 0, val = 0;
+ unsigned long flags;
+
+ if (!clk || !parent)
+ return -EFAULT;
+ if (clk->pclk == parent)
+ return 0;
+ if (!clk->pclk_sel)
+ return -EPERM;
+
+ /* check if requested parent is in clk parent list */
+ for (i = 0; i < clk->pclk_sel->pclk_count; i++) {
+ if (clk->pclk_sel->pclk_info[i].pclk == parent) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found)
+ return -EINVAL;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ /* reflect parent change in hardware */
+ val = readl(clk->pclk_sel->pclk_sel_reg);
+ val &= ~(clk->pclk_sel->pclk_sel_mask << clk->pclk_sel_shift);
+ val |= clk->pclk_sel->pclk_info[i].pclk_val << clk->pclk_sel_shift;
+ writel(val, clk->pclk_sel->pclk_sel_reg);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ /* reflect parent change in software */
+ clk_reparent(clk, &clk->pclk_sel->pclk_info[i]);
+
+ propagate_rate(clk, 0);
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/**
+ * clk_set_rate - set the clock rate for a clock source
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ *
+ * Returns success (0) or negative errno.
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!clk || !rate)
+ return -EFAULT;
+
+ if (clk->set_rate) {
+ spin_lock_irqsave(&clocks_lock, flags);
+ ret = clk->set_rate(clk, rate);
+ if (!ret)
+ /* if successful -> propagate */
+ propagate_rate(clk, 0);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ } else if (clk->pclk) {
+ u32 mult = clk->div_factor ? clk->div_factor : 1;
+ ret = clk_set_rate(clk->pclk, mult * rate);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* registers clock in platform clock framework */
+void clk_register(struct clk_lookup *cl)
+{
+ struct clk *clk;
+ unsigned long flags;
+
+ if (!cl || !cl->clk)
+ return;
+ clk = cl->clk;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+
+ INIT_LIST_HEAD(&clk->children);
+ if (clk->flags & ALWAYS_ENABLED)
+ clk->ops = NULL;
+ else if (!clk->ops)
+ clk->ops = &generic_clkops;
+
+ /* root clock don't have any parents */
+ if (!clk->pclk && !clk->pclk_sel) {
+ list_add(&clk->sibling, &root_clks);
+ } else if (clk->pclk && !clk->pclk_sel) {
+ /* add clocks with only one parent to parent's children list */
+ list_add(&clk->sibling, &clk->pclk->children);
+ } else {
+ /* clocks with more than one parent */
+ struct pclk_info *pclk_info;
+
+ pclk_info = pclk_info_get(clk);
+ if (!pclk_info) {
+ pr_err("CLKDEV: invalid pclk info of clk with"
+ " %s dev_id and %s con_id\n",
+ cl->dev_id, cl->con_id);
+ } else {
+ clk->pclk = pclk_info->pclk;
+ list_add(&clk->sibling, &pclk_info->pclk->children);
+ }
+ }
+
+ spin_unlock_irqrestore(&clocks_lock, flags);
+
+ /* debugfs specific */
+#ifdef CONFIG_DEBUG_FS
+ list_add(&clk->node, &clocks);
+ clk->cl = cl;
+#endif
+
+ /* add clock to arm clockdev framework */
+ clkdev_add(cl);
+}
+
+/**
+ * propagate_rate - recalculate and propagate all clocks to children
+ * @pclk: parent clock required to be propogated
+ * @on_init: flag for enabling clocks which are ENABLED_ON_INIT.
+ *
+ * Recalculates all children clocks
+ */
+void propagate_rate(struct clk *pclk, int on_init)
+{
+ struct clk *clk, *_temp;
+ int ret = 0;
+
+ list_for_each_entry_safe(clk, _temp, &pclk->children, sibling) {
+ if (clk->recalc) {
+ ret = clk->recalc(clk);
+ /*
+ * recalc will return error if clk out is not programmed
+ * In this case configure default rate.
+ */
+ if (ret && clk->set_rate)
+ clk->set_rate(clk, 0);
+ }
+ propagate_rate(clk, on_init);
+
+ if (!on_init)
+ continue;
+
+ /* Enable clks enabled on init, in software view */
+ if (clk->flags & ENABLED_ON_INIT)
+ do_clk_enable(clk);
+ }
+}
+
+/**
+ * round_rate_index - return closest programmable rate index in rate_config tbl
+ * @clk: ptr to clock structure
+ * @drate: desired rate
+ * @rate: final rate will be returned in this variable only.
+ *
+ * Finds index in rate_config for highest clk rate which is less than
+ * requested rate. If there is no clk rate lesser than requested rate then
+ * -EINVAL is returned. This routine assumes that rate_config is written
+ * in incrementing order of clk rates.
+ * If drate passed is zero then default rate is programmed.
+ */
+static int
+round_rate_index(struct clk *clk, unsigned long drate, unsigned long *rate)
+{
+ unsigned long tmp = 0, prev_rate = 0;
+ int index;
+
+ if (!clk->calc_rate)
+ return -EFAULT;
+
+ if (!drate)
+ return -EINVAL;
+
+ /*
+ * This loops ends on two conditions:
+ * - as soon as clk is found with rate greater than requested rate.
+ * - if all clks in rate_config are smaller than requested rate.
+ */
+ for (index = 0; index < clk->rate_config.count; index++) {
+ prev_rate = tmp;
+ tmp = clk->calc_rate(clk, index);
+ if (drate < tmp) {
+ index--;
+ break;
+ }
+ }
+ /* return if can't find suitable clock */
+ if (index < 0) {
+ index = -EINVAL;
+ *rate = 0;
+ } else if (index == clk->rate_config.count) {
+ /* program with highest clk rate possible */
+ index = clk->rate_config.count - 1;
+ *rate = tmp;
+ } else
+ *rate = prev_rate;
+
+ return index;
+}
+
+/**
+ * clk_round_rate - adjust a rate to the exact rate a clock can provide
+ * @clk: clock source
+ * @rate: desired clock rate in Hz
+ *
+ * Returns rounded clock rate in Hz, or negative errno.
+ */
+long clk_round_rate(struct clk *clk, unsigned long drate)
+{
+ long rate = 0;
+ int index;
+
+ /*
+ * propagate call to parent who supports calc_rate. Similar approach is
+ * used in clk_set_rate.
+ */
+ if (!clk->calc_rate) {
+ u32 mult;
+ if (!clk->pclk)
+ return clk->rate;
+
+ mult = clk->div_factor ? clk->div_factor : 1;
+ return clk_round_rate(clk->pclk, mult * drate) / mult;
+ }
+
+ index = round_rate_index(clk, drate, &rate);
+ if (index >= 0)
+ return rate;
+ else
+ return index;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/*All below functions are called with lock held */
+
+/*
+ * Calculates pll clk rate for specific value of mode, m, n and p
+ *
+ * In normal mode
+ * rate = (2 * M[15:8] * Fin)/(N * 2^P)
+ *
+ * In Dithered mode
+ * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
+ */
+unsigned long pll_calc_rate(struct clk *clk, int index)
+{
+ unsigned long rate = clk->pclk->rate;
+ struct pll_rate_tbl *tbls = clk->rate_config.tbls;
+ unsigned int mode;
+
+ mode = tbls[index].mode ? 256 : 1;
+ return (((2 * rate / 10000) * tbls[index].m) /
+ (mode * tbls[index].n * (1 << tbls[index].p))) * 10000;
+}
+
+/*
+ * calculates current programmed rate of pll1
+ *
+ * In normal mode
+ * rate = (2 * M[15:8] * Fin)/(N * 2^P)
+ *
+ * In Dithered mode
+ * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P)
+ */
+int pll_clk_recalc(struct clk *clk)
+{
+ struct pll_clk_config *config = clk->private_data;
+ unsigned int num = 2, den = 0, val, mode = 0;
+
+ mode = (readl(config->mode_reg) >> config->masks->mode_shift) &
+ config->masks->mode_mask;
+
+ val = readl(config->cfg_reg);
+ /* calculate denominator */
+ den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask;
+ den = 1 << den;
+ den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask;
+
+ /* calculate numerator & denominator */
+ if (!mode) {
+ /* Normal mode */
+ num *= (val >> config->masks->norm_fdbk_m_shift) &
+ config->masks->norm_fdbk_m_mask;
+ } else {
+ /* Dithered mode */
+ num *= (val >> config->masks->dith_fdbk_m_shift) &
+ config->masks->dith_fdbk_m_mask;
+ den *= 256;
+ }
+
+ if (!den)
+ return -EINVAL;
+
+ clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+ return 0;
+}
+
+/*
+ * Configures new clock rate of pll
+ */
+int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+ struct pll_rate_tbl *tbls = clk->rate_config.tbls;
+ struct pll_clk_config *config = clk->private_data;
+ unsigned long val, rate;
+ int i;
+
+ i = round_rate_index(clk, desired_rate, &rate);
+ if (i < 0)
+ return i;
+
+ val = readl(config->mode_reg) &
+ ~(config->masks->mode_mask << config->masks->mode_shift);
+ val |= (tbls[i].mode & config->masks->mode_mask) <<
+ config->masks->mode_shift;
+ writel(val, config->mode_reg);
+
+ val = readl(config->cfg_reg) &
+ ~(config->masks->div_p_mask << config->masks->div_p_shift);
+ val |= (tbls[i].p & config->masks->div_p_mask) <<
+ config->masks->div_p_shift;
+ val &= ~(config->masks->div_n_mask << config->masks->div_n_shift);
+ val |= (tbls[i].n & config->masks->div_n_mask) <<
+ config->masks->div_n_shift;
+ val &= ~(config->masks->dith_fdbk_m_mask <<
+ config->masks->dith_fdbk_m_shift);
+ if (tbls[i].mode)
+ val |= (tbls[i].m & config->masks->dith_fdbk_m_mask) <<
+ config->masks->dith_fdbk_m_shift;
+ else
+ val |= (tbls[i].m & config->masks->norm_fdbk_m_mask) <<
+ config->masks->norm_fdbk_m_shift;
+
+ writel(val, config->cfg_reg);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+/*
+ * Calculates ahb, apb clk rate for specific value of div
+ */
+unsigned long bus_calc_rate(struct clk *clk, int index)
+{
+ unsigned long rate = clk->pclk->rate;
+ struct bus_rate_tbl *tbls = clk->rate_config.tbls;
+
+ return rate / (tbls[index].div + 1);
+}
+
+/* calculates current programmed rate of ahb or apb bus */
+int bus_clk_recalc(struct clk *clk)
+{
+ struct bus_clk_config *config = clk->private_data;
+ unsigned int div;
+
+ div = ((readl(config->reg) >> config->masks->shift) &
+ config->masks->mask) + 1;
+
+ if (!div)
+ return -EINVAL;
+
+ clk->rate = (unsigned long)clk->pclk->rate / div;
+ return 0;
+}
+
+/* Configures new clock rate of AHB OR APB bus */
+int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+ struct bus_rate_tbl *tbls = clk->rate_config.tbls;
+ struct bus_clk_config *config = clk->private_data;
+ unsigned long val, rate;
+ int i;
+
+ i = round_rate_index(clk, desired_rate, &rate);
+ if (i < 0)
+ return i;
+
+ val = readl(config->reg) &
+ ~(config->masks->mask << config->masks->shift);
+ val |= (tbls[i].div & config->masks->mask) << config->masks->shift;
+ writel(val, config->reg);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+/*
+ * gives rate for different values of eq, x and y
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2 EQ1
+ * Fout2 = Fin * X/Y EQ2
+ */
+unsigned long aux_calc_rate(struct clk *clk, int index)
+{
+ unsigned long rate = clk->pclk->rate;
+ struct aux_rate_tbl *tbls = clk->rate_config.tbls;
+ u8 eq = tbls[index].eq ? 1 : 2;
+
+ return (((rate/10000) * tbls[index].xscale) /
+ (tbls[index].yscale * eq)) * 10000;
+}
+
+/*
+ * calculates current programmed rate of auxiliary synthesizers
+ * used by: UART, FIRDA
+ *
+ * Fout from synthesizer can be given from two equations:
+ * Fout1 = (Fin * X/Y)/2
+ * Fout2 = Fin * X/Y
+ *
+ * Selection of eqn 1 or 2 is programmed in register
+ */
+int aux_clk_recalc(struct clk *clk)
+{
+ struct aux_clk_config *config = clk->private_data;
+ unsigned int num = 1, den = 1, val, eqn;
+
+ val = readl(config->synth_reg);
+
+ eqn = (val >> config->masks->eq_sel_shift) &
+ config->masks->eq_sel_mask;
+ if (eqn == config->masks->eq1_mask)
+ den *= 2;
+
+ /* calculate numerator */
+ num = (val >> config->masks->xscale_sel_shift) &
+ config->masks->xscale_sel_mask;
+
+ /* calculate denominator */
+ den *= (val >> config->masks->yscale_sel_shift) &
+ config->masks->yscale_sel_mask;
+
+ if (!den)
+ return -EINVAL;
+
+ clk->rate = (((clk->pclk->rate/10000) * num) / den) * 10000;
+ return 0;
+}
+
+/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
+int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+ struct aux_rate_tbl *tbls = clk->rate_config.tbls;
+ struct aux_clk_config *config = clk->private_data;
+ unsigned long val, rate;
+ int i;
+
+ i = round_rate_index(clk, desired_rate, &rate);
+ if (i < 0)
+ return i;
+
+ val = readl(config->synth_reg) &
+ ~(config->masks->eq_sel_mask << config->masks->eq_sel_shift);
+ val |= (tbls[i].eq & config->masks->eq_sel_mask) <<
+ config->masks->eq_sel_shift;
+ val &= ~(config->masks->xscale_sel_mask <<
+ config->masks->xscale_sel_shift);
+ val |= (tbls[i].xscale & config->masks->xscale_sel_mask) <<
+ config->masks->xscale_sel_shift;
+ val &= ~(config->masks->yscale_sel_mask <<
+ config->masks->yscale_sel_shift);
+ val |= (tbls[i].yscale & config->masks->yscale_sel_mask) <<
+ config->masks->yscale_sel_shift;
+ writel(val, config->synth_reg);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+/*
+ * Calculates gpt clk rate for different values of mscale and nscale
+ *
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+unsigned long gpt_calc_rate(struct clk *clk, int index)
+{
+ unsigned long rate = clk->pclk->rate;
+ struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
+
+ return rate / ((1 << (tbls[index].nscale + 1)) *
+ (tbls[index].mscale + 1));
+}
+
+/*
+ * calculates current programmed rate of gpt synthesizers
+ * Fout from synthesizer can be given from below equations:
+ * Fout= Fin/((2 ^ (N+1)) * (M+1))
+ */
+int gpt_clk_recalc(struct clk *clk)
+{
+ struct gpt_clk_config *config = clk->private_data;
+ unsigned int div = 1, val;
+
+ val = readl(config->synth_reg);
+ div += (val >> config->masks->mscale_sel_shift) &
+ config->masks->mscale_sel_mask;
+ div *= 1 << (((val >> config->masks->nscale_sel_shift) &
+ config->masks->nscale_sel_mask) + 1);
+
+ if (!div)
+ return -EINVAL;
+
+ clk->rate = (unsigned long)clk->pclk->rate / div;
+ return 0;
+}
+
+/* Configures new clock rate of gptiliary synthesizers used by: UART, FIRDA*/
+int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+ struct gpt_rate_tbl *tbls = clk->rate_config.tbls;
+ struct gpt_clk_config *config = clk->private_data;
+ unsigned long val, rate;
+ int i;
+
+ i = round_rate_index(clk, desired_rate, &rate);
+ if (i < 0)
+ return i;
+
+ val = readl(config->synth_reg) & ~(config->masks->mscale_sel_mask <<
+ config->masks->mscale_sel_shift);
+ val |= (tbls[i].mscale & config->masks->mscale_sel_mask) <<
+ config->masks->mscale_sel_shift;
+ val &= ~(config->masks->nscale_sel_mask <<
+ config->masks->nscale_sel_shift);
+ val |= (tbls[i].nscale & config->masks->nscale_sel_mask) <<
+ config->masks->nscale_sel_shift;
+ writel(val, config->synth_reg);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+/*
+ * Calculates clcd clk rate for different values of div
+ *
+ * Fout from synthesizer can be given from below equation:
+ * Fout= Fin/2*div (division factor)
+ * div is 17 bits:-
+ * 0-13 (fractional part)
+ * 14-16 (integer part)
+ * To calculate Fout we left shift val by 14 bits and divide Fin by
+ * complete div (including fractional part) and then right shift the
+ * result by 14 places.
+ */
+unsigned long clcd_calc_rate(struct clk *clk, int index)
+{
+ unsigned long rate = clk->pclk->rate;
+ struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
+
+ rate /= 1000;
+ rate <<= 12;
+ rate /= (2 * tbls[index].div);
+ rate >>= 12;
+ rate *= 1000;
+
+ return rate;
+}
+
+/*
+ * calculates current programmed rate of clcd synthesizer
+ * Fout from synthesizer can be given from below equation:
+ * Fout= Fin/2*div (division factor)
+ * div is 17 bits:-
+ * 0-13 (fractional part)
+ * 14-16 (integer part)
+ * To calculate Fout we left shift val by 14 bits and divide Fin by
+ * complete div (including fractional part) and then right shift the
+ * result by 14 places.
+ */
+int clcd_clk_recalc(struct clk *clk)
+{
+ struct clcd_clk_config *config = clk->private_data;
+ unsigned int div = 1;
+ unsigned long prate;
+ unsigned int val;
+
+ val = readl(config->synth_reg);
+ div = (val >> config->masks->div_factor_shift) &
+ config->masks->div_factor_mask;
+
+ if (!div)
+ return -EINVAL;
+
+ prate = clk->pclk->rate / 1000; /* first level division, make it KHz */
+
+ clk->rate = (((unsigned long)prate << 12) / (2 * div)) >> 12;
+ clk->rate *= 1000;
+ return 0;
+}
+
+/* Configures new clock rate of auxiliary synthesizers used by: UART, FIRDA*/
+int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate)
+{
+ struct clcd_rate_tbl *tbls = clk->rate_config.tbls;
+ struct clcd_clk_config *config = clk->private_data;
+ unsigned long val, rate;
+ int i;
+
+ i = round_rate_index(clk, desired_rate, &rate);
+ if (i < 0)
+ return i;
+
+ val = readl(config->synth_reg) & ~(config->masks->div_factor_mask <<
+ config->masks->div_factor_shift);
+ val |= (tbls[i].div & config->masks->div_factor_mask) <<
+ config->masks->div_factor_shift;
+ writel(val, config->synth_reg);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+/*
+ * Used for clocks that always have value as the parent clock divided by a
+ * fixed divisor
+ */
+int follow_parent(struct clk *clk)
+{
+ unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor;
+
+ clk->rate = clk->pclk->rate/div_factor;
+ return 0;
+}
+
+/**
+ * recalc_root_clocks - recalculate and propagate all root clocks
+ *
+ * Recalculates all root clocks (clocks with no parent), which if the
+ * clock's .recalc is set correctly, should also propagate their rates.
+ */
+void recalc_root_clocks(void)
+{
+ struct clk *pclk;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&clocks_lock, flags);
+ list_for_each_entry(pclk, &root_clks, sibling) {
+ if (pclk->recalc) {
+ ret = pclk->recalc(pclk);
+ /*
+ * recalc will return error if clk out is not programmed
+ * In this case configure default clock.
+ */
+ if (ret && pclk->set_rate)
+ pclk->set_rate(pclk, 0);
+ }
+ propagate_rate(pclk, 1);
+ /* Enable clks enabled on init, in software view */
+ if (pclk->flags & ENABLED_ON_INIT)
+ do_clk_enable(pclk);
+ }
+ spin_unlock_irqrestore(&clocks_lock, flags);
+}
+
+void __init clk_init(void)
+{
+ recalc_root_clocks();
+}
+
+#ifdef CONFIG_DEBUG_FS
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+static struct dentry *clk_debugfs_root;
+static int clk_debugfs_register_one(struct clk *c)
+{
+ int err;
+ struct dentry *d, *child;
+ struct clk *pa = c->pclk;
+ char s[255];
+ char *p = s;
+
+ if (c) {
+ if (c->cl->con_id)
+ p += sprintf(p, "%s", c->cl->con_id);
+ if (c->cl->dev_id)
+ p += sprintf(p, "%s", c->cl->dev_id);
+ }
+ d = debugfs_create_dir(s, pa ? pa->dent : clk_debugfs_root);
+ if (!d)
+ return -ENOMEM;
+ c->dent = d;
+
+ d = debugfs_create_u32("usage_count", S_IRUGO, c->dent,
+ (u32 *)&c->usage_count);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+ return 0;
+
+err_out:
+ d = c->dent;
+ list_for_each_entry(child, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(c->dent);
+ return err;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->pclk;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ list_for_each_entry(c, &clocks, node) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+late_initcall(clk_debugfs_init);
+
+static int clk_debugfs_reparent(struct clk *c)
+{
+ debugfs_remove(c->dent);
+ return clk_debugfs_register_one(c);
+}
+#endif /* CONFIG_DEBUG_FS */
diff --git a/arch/arm/plat-spear/include/plat/clkdev.h b/arch/arm/plat-spear/include/plat/clkdev.h
new file mode 100644
index 00000000..a2d0112f
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/clkdev.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/clkdev.h
+ *
+ * Clock Dev framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_CLKDEV_H
+#define __PLAT_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif /* __PLAT_CLKDEV_H */
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h
new file mode 100644
index 00000000..0062bafe
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/clock.h
@@ -0,0 +1,249 @@
+/*
+ * arch/arm/plat-spear/include/plat/clock.h
+ *
+ * Clock framework definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_CLOCK_H
+#define __PLAT_CLOCK_H
+
+#include <linux/list.h>
+#include <linux/clkdev.h>
+#include <linux/types.h>
+
+/* clk structure flags */
+#define ALWAYS_ENABLED (1 << 0) /* clock always enabled */
+#define RESET_TO_ENABLE (1 << 1) /* reset register bit to enable clk */
+#define ENABLED_ON_INIT (1 << 2) /* clocks enabled at init */
+
+/**
+ * struct clkops - clock operations
+ * @enable: pointer to clock enable function
+ * @disable: pointer to clock disable function
+ */
+struct clkops {
+ int (*enable) (struct clk *);
+ void (*disable) (struct clk *);
+};
+
+/**
+ * struct pclk_info - parents info
+ * @pclk: pointer to parent clk
+ * @pclk_val: value to be written for selecting this parent
+ */
+struct pclk_info {
+ struct clk *pclk;
+ u8 pclk_val;
+};
+
+/**
+ * struct pclk_sel - parents selection configuration
+ * @pclk_info: pointer to array of parent clock info
+ * @pclk_count: number of parents
+ * @pclk_sel_reg: register for selecting a parent
+ * @pclk_sel_mask: mask for selecting parent (can be used to clear bits also)
+ */
+struct pclk_sel {
+ struct pclk_info *pclk_info;
+ u8 pclk_count;
+ void __iomem *pclk_sel_reg;
+ unsigned int pclk_sel_mask;
+};
+
+/**
+ * struct rate_config - clk rate configurations
+ * @tbls: array of device specific clk rate tables, in ascending order of rates
+ * @count: size of tbls array
+ * @default_index: default setting when originally disabled
+ */
+struct rate_config {
+ void *tbls;
+ u8 count;
+ u8 default_index;
+};
+
+/**
+ * struct clk - clock structure
+ * @usage_count: num of users who enabled this clock
+ * @flags: flags for clock properties
+ * @rate: programmed clock rate in Hz
+ * @en_reg: clk enable/disable reg
+ * @en_reg_bit: clk enable/disable bit
+ * @ops: clk enable/disable ops - generic_clkops selected if NULL
+ * @recalc: pointer to clock rate recalculate function
+ * @set_rate: pointer to clock set rate function
+ * @calc_rate: pointer to clock get rate function for index
+ * @rate_config: rate configuration information, used by set_rate
+ * @div_factor: division factor to parent clock.
+ * @pclk: current parent clk
+ * @pclk_sel: pointer to parent selection structure
+ * @pclk_sel_shift: register shift for selecting parent of this clock
+ * @children: list for childrens or this clock
+ * @sibling: node for list of clocks having same parents
+ * @private_data: clock specific private data
+ * @node: list to maintain clocks linearly
+ * @cl: clocklook up associated with this clock
+ * @dent: object for debugfs
+ */
+struct clk {
+ unsigned int usage_count;
+ unsigned int flags;
+ unsigned long rate;
+ void __iomem *en_reg;
+ u8 en_reg_bit;
+ const struct clkops *ops;
+ int (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *, unsigned long rate);
+ unsigned long (*calc_rate)(struct clk *, int index);
+ struct rate_config rate_config;
+ unsigned int div_factor;
+
+ struct clk *pclk;
+ struct pclk_sel *pclk_sel;
+ unsigned int pclk_sel_shift;
+
+ struct list_head children;
+ struct list_head sibling;
+ void *private_data;
+#ifdef CONFIG_DEBUG_FS
+ struct list_head node;
+ struct clk_lookup *cl;
+ struct dentry *dent;
+#endif
+};
+
+/* pll configuration structure */
+struct pll_clk_masks {
+ u32 mode_mask;
+ u32 mode_shift;
+
+ u32 norm_fdbk_m_mask;
+ u32 norm_fdbk_m_shift;
+ u32 dith_fdbk_m_mask;
+ u32 dith_fdbk_m_shift;
+ u32 div_p_mask;
+ u32 div_p_shift;
+ u32 div_n_mask;
+ u32 div_n_shift;
+};
+
+struct pll_clk_config {
+ void __iomem *mode_reg;
+ void __iomem *cfg_reg;
+ struct pll_clk_masks *masks;
+};
+
+/* pll clk rate config structure */
+struct pll_rate_tbl {
+ u8 mode;
+ u16 m;
+ u8 n;
+ u8 p;
+};
+
+/* ahb and apb bus configuration structure */
+struct bus_clk_masks {
+ u32 mask;
+ u32 shift;
+};
+
+struct bus_clk_config {
+ void __iomem *reg;
+ struct bus_clk_masks *masks;
+};
+
+/* ahb and apb clk bus rate config structure */
+struct bus_rate_tbl {
+ u8 div;
+};
+
+/* Aux clk configuration structure: applicable to UART and FIRDA */
+struct aux_clk_masks {
+ u32 eq_sel_mask;
+ u32 eq_sel_shift;
+ u32 eq1_mask;
+ u32 eq2_mask;
+ u32 xscale_sel_mask;
+ u32 xscale_sel_shift;
+ u32 yscale_sel_mask;
+ u32 yscale_sel_shift;
+};
+
+struct aux_clk_config {
+ void __iomem *synth_reg;
+ struct aux_clk_masks *masks;
+};
+
+/* aux clk rate config structure */
+struct aux_rate_tbl {
+ u16 xscale;
+ u16 yscale;
+ u8 eq;
+};
+
+/* GPT clk configuration structure */
+struct gpt_clk_masks {
+ u32 mscale_sel_mask;
+ u32 mscale_sel_shift;
+ u32 nscale_sel_mask;
+ u32 nscale_sel_shift;
+};
+
+struct gpt_clk_config {
+ void __iomem *synth_reg;
+ struct gpt_clk_masks *masks;
+};
+
+/* gpt clk rate config structure */
+struct gpt_rate_tbl {
+ u16 mscale;
+ u16 nscale;
+};
+
+/* clcd clk configuration structure */
+struct clcd_synth_masks {
+ u32 div_factor_mask;
+ u32 div_factor_shift;
+};
+
+struct clcd_clk_config {
+ void __iomem *synth_reg;
+ struct clcd_synth_masks *masks;
+};
+
+/* clcd clk rate config structure */
+struct clcd_rate_tbl {
+ u16 div;
+};
+
+/* platform specific clock functions */
+void __init clk_init(void);
+void clk_register(struct clk_lookup *cl);
+void recalc_root_clocks(void);
+
+/* clock recalc & set rate functions */
+int follow_parent(struct clk *clk);
+unsigned long pll_calc_rate(struct clk *clk, int index);
+int pll_clk_recalc(struct clk *clk);
+int pll_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long bus_calc_rate(struct clk *clk, int index);
+int bus_clk_recalc(struct clk *clk);
+int bus_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long gpt_calc_rate(struct clk *clk, int index);
+int gpt_clk_recalc(struct clk *clk);
+int gpt_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long aux_calc_rate(struct clk *clk, int index);
+int aux_clk_recalc(struct clk *clk);
+int aux_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+unsigned long clcd_calc_rate(struct clk *clk, int index);
+int clcd_clk_recalc(struct clk *clk);
+int clcd_clk_set_rate(struct clk *clk, unsigned long desired_rate);
+
+#endif /* __PLAT_CLOCK_H */
diff --git a/arch/arm/plat-spear/include/plat/debug-macro.S b/arch/arm/plat-spear/include/plat/debug-macro.S
new file mode 100644
index 00000000..8501bbf2
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/debug-macro.S
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/plat-spear/include/plat/debug-macro.S
+ *
+ * Debugging macro include header for spear platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/amba/serial.h>
+#include <mach/hardware.h>
+
+ .macro addruart, rp, rv
+ mov \rp, #SPEAR_DBG_UART_BASE @ Physical base
+ mov \rv, #VA_SPEAR_DBG_UART_BASE @ Virtual base
+ .endm
+
+ .macro senduart, rd, rx
+ strb \rd, [\rx, #UART01x_DR] @ ASC_TX_BUFFER
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER
+ tst \rd, #UART01x_FR_TXFF @ TX_FULL
+ bne 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002: ldr \rd, [\rx, #UART01x_FR] @ FLAG REGISTER
+ tst \rd, #UART011_FR_TXFE @ TX_EMPTY
+ beq 1002b
+ .endm
diff --git a/arch/arm/plat-spear/include/plat/gpio.h b/arch/arm/plat-spear/include/plat/gpio.h
new file mode 100644
index 00000000..b857c912
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/gpio.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-spear/include/plat/gpio.h
+ *
+ * GPIO macros for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#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
+
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/plat-spear/include/plat/hardware.h b/arch/arm/plat-spear/include/plat/hardware.h
new file mode 100644
index 00000000..66d67722
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/hardware.h
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/plat-spear/include/plat/hardware.h
+ *
+ * Hardware definitions for SPEAr
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_HARDWARE_H
+#define __PLAT_HARDWARE_H
+
+#ifndef __ASSEMBLY__
+#define IOMEM(x) ((void __iomem __force *)(x))
+#else
+#define IOMEM(x) (x)
+#endif
+
+#endif /* __PLAT_HARDWARE_H */
diff --git a/arch/arm/plat-spear/include/plat/io.h b/arch/arm/plat-spear/include/plat/io.h
new file mode 100644
index 00000000..4d4ba822
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/io.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/plat-spear/include/plat/io.h
+ *
+ * IO definitions for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_IO_H
+#define __PLAT_IO_H
+
+#define IO_SPACE_LIMIT 0xFFFFFFFF
+
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif /* __PLAT_IO_H */
diff --git a/arch/arm/plat-spear/include/plat/keyboard.h b/arch/arm/plat-spear/include/plat/keyboard.h
new file mode 100644
index 00000000..68b5394f
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/keyboard.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2010 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_KEYBOARD_H
+#define __PLAT_KEYBOARD_H
+
+#include <linux/bitops.h>
+#include <linux/input.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/types.h>
+
+#define DECLARE_KEYMAP(_name) \
+int _name[] = { \
+ KEY(0, 0, KEY_ESC), \
+ KEY(0, 1, KEY_1), \
+ KEY(0, 2, KEY_2), \
+ KEY(0, 3, KEY_3), \
+ KEY(0, 4, KEY_4), \
+ KEY(0, 5, KEY_5), \
+ KEY(0, 6, KEY_6), \
+ KEY(0, 7, KEY_7), \
+ KEY(0, 8, KEY_8), \
+ KEY(1, 0, KEY_9), \
+ KEY(1, 1, KEY_MINUS), \
+ KEY(1, 2, KEY_EQUAL), \
+ KEY(1, 3, KEY_BACKSPACE), \
+ KEY(1, 4, KEY_TAB), \
+ KEY(1, 5, KEY_Q), \
+ KEY(1, 6, KEY_W), \
+ KEY(1, 7, KEY_E), \
+ KEY(1, 8, KEY_R), \
+ KEY(2, 0, KEY_T), \
+ KEY(2, 1, KEY_Y), \
+ KEY(2, 2, KEY_U), \
+ KEY(2, 3, KEY_I), \
+ KEY(2, 4, KEY_O), \
+ KEY(2, 5, KEY_P), \
+ KEY(2, 6, KEY_LEFTBRACE), \
+ KEY(2, 7, KEY_RIGHTBRACE), \
+ KEY(2, 8, KEY_ENTER), \
+ KEY(3, 0, KEY_LEFTCTRL), \
+ KEY(3, 1, KEY_A), \
+ KEY(3, 2, KEY_S), \
+ KEY(3, 3, KEY_D), \
+ KEY(3, 4, KEY_F), \
+ KEY(3, 5, KEY_G), \
+ KEY(3, 6, KEY_H), \
+ KEY(3, 7, KEY_J), \
+ KEY(3, 8, KEY_K), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(4, 0, KEY_L), \
+ KEY(4, 1, KEY_SEMICOLON), \
+ KEY(4, 2, KEY_APOSTROPHE), \
+ KEY(4, 3, KEY_GRAVE), \
+ KEY(4, 4, KEY_LEFTSHIFT), \
+ KEY(4, 5, KEY_BACKSLASH), \
+ KEY(4, 6, KEY_Z), \
+ KEY(4, 7, KEY_X), \
+ KEY(4, 8, KEY_C), \
+ KEY(5, 0, KEY_V), \
+ KEY(5, 1, KEY_B), \
+ KEY(5, 2, KEY_N), \
+ KEY(5, 3, KEY_M), \
+ KEY(5, 4, KEY_COMMA), \
+ KEY(5, 5, KEY_DOT), \
+ KEY(5, 6, KEY_SLASH), \
+ KEY(5, 7, KEY_RIGHTSHIFT), \
+ KEY(5, 8, KEY_KPASTERISK), \
+ KEY(6, 0, KEY_LEFTALT), \
+ KEY(6, 1, KEY_SPACE), \
+ KEY(6, 2, KEY_CAPSLOCK), \
+ KEY(6, 3, KEY_F1), \
+ KEY(6, 4, KEY_F2), \
+ KEY(6, 5, KEY_F3), \
+ KEY(6, 6, KEY_F4), \
+ KEY(6, 7, KEY_F5), \
+ KEY(6, 8, KEY_F6), \
+ KEY(7, 0, KEY_F7), \
+ KEY(7, 1, KEY_F8), \
+ KEY(7, 2, KEY_F9), \
+ KEY(7, 3, KEY_F10), \
+ KEY(7, 4, KEY_NUMLOCK), \
+ KEY(7, 5, KEY_SCROLLLOCK), \
+ KEY(7, 6, KEY_KP7), \
+ KEY(7, 7, KEY_KP8), \
+ KEY(7, 8, KEY_KP9), \
+ KEY(8, 0, KEY_KPMINUS), \
+ KEY(8, 1, KEY_KP4), \
+ KEY(8, 2, KEY_KP5), \
+ KEY(8, 3, KEY_KP6), \
+ KEY(8, 4, KEY_KPPLUS), \
+ KEY(8, 5, KEY_KP1), \
+ KEY(8, 6, KEY_KP2), \
+ KEY(8, 7, KEY_KP3), \
+ KEY(8, 8, KEY_KP0), \
+}
+
+/**
+ * struct kbd_platform_data - spear keyboard platform data
+ * keymap: pointer to keymap data (table and size)
+ * rep: enables key autorepeat
+ *
+ * This structure is supposed to be used by platform code to supply
+ * keymaps to drivers that implement keyboards.
+ */
+struct kbd_platform_data {
+ const struct matrix_keymap_data *keymap;
+ bool rep;
+};
+
+/* This function is used to set platform data field of pdev->dev */
+static inline void
+kbd_set_plat_data(struct platform_device *pdev, struct kbd_platform_data *data)
+{
+ pdev->dev.platform_data = data;
+}
+
+#endif /* __PLAT_KEYBOARD_H */
diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h
new file mode 100644
index 00000000..7e3599e1
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/memory.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-spear/include/plat/memory.h
+ *
+ * Memory map for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_MEMORY_H
+#define __PLAT_MEMORY_H
+
+/* Physical DRAM offset */
+#define PLAT_PHYS_OFFSET UL(0x00000000)
+
+#endif /* __PLAT_MEMORY_H */
diff --git a/arch/arm/plat-spear/include/plat/padmux.h b/arch/arm/plat-spear/include/plat/padmux.h
new file mode 100644
index 00000000..877f3adc
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/padmux.h
@@ -0,0 +1,92 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.h
+ *
+ * SPEAr platform specific gpio pads muxing file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_PADMUX_H
+#define __PLAT_PADMUX_H
+
+#include <linux/types.h>
+
+/*
+ * struct pmx_reg: configuration structure for mode reg and mux reg
+ *
+ * offset: offset of mode reg
+ * mask: mask of mode reg
+ */
+struct pmx_reg {
+ u32 offset;
+ u32 mask;
+};
+
+/*
+ * struct pmx_dev_mode: configuration structure every group of modes of a device
+ *
+ * ids: all modes for this configuration
+ * mask: mask for supported mode
+ */
+struct pmx_dev_mode {
+ u32 ids;
+ u32 mask;
+};
+
+/*
+ * struct pmx_mode: mode definition structure
+ *
+ * name: mode name
+ * mask: mode mask
+ */
+struct pmx_mode {
+ char *name;
+ u32 id;
+ u32 mask;
+};
+
+/*
+ * struct pmx_dev: device definition structure
+ *
+ * name: device name
+ * modes: device configuration array for different modes supported
+ * mode_count: size of modes array
+ * is_active: is peripheral active/enabled
+ * enb_on_reset: if 1, mask bits to be cleared in reg otherwise to be set in reg
+ */
+struct pmx_dev {
+ char *name;
+ struct pmx_dev_mode *modes;
+ u8 mode_count;
+ bool is_active;
+ bool enb_on_reset;
+};
+
+/*
+ * struct pmx_driver: driver definition structure
+ *
+ * mode: mode to be set
+ * devs: array of pointer to pmx devices
+ * devs_count: ARRAY_SIZE of devs
+ * base: base address of soc config registers
+ * mode_reg: structure of mode config register
+ * mux_reg: structure of device mux config register
+ */
+struct pmx_driver {
+ struct pmx_mode *mode;
+ struct pmx_dev **devs;
+ u8 devs_count;
+ u32 *base;
+ struct pmx_reg mode_reg;
+ struct pmx_reg mux_reg;
+};
+
+/* pmx functions */
+int pmx_register(struct pmx_driver *driver);
+
+#endif /* __PLAT_PADMUX_H */
diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h
new file mode 100644
index 00000000..03ed8b58
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/shirq.h
@@ -0,0 +1,73 @@
+/*
+ * arch/arm/plat-spear/include/plat/shirq.h
+ *
+ * SPEAr platform shared irq layer header file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_SHIRQ_H
+#define __PLAT_SHIRQ_H
+
+#include <linux/irq.h>
+#include <linux/types.h>
+
+/*
+ * struct shirq_dev_config: shared irq device configuration
+ *
+ * virq: virtual irq number of device
+ * enb_mask: enable mask of device
+ * status_mask: status mask of device
+ * clear_mask: clear mask of device
+ */
+struct shirq_dev_config {
+ u32 virq;
+ u32 enb_mask;
+ u32 status_mask;
+ u32 clear_mask;
+};
+
+/*
+ * struct shirq_regs: shared irq register configuration
+ *
+ * base: base address of shared irq register
+ * enb_reg: enable register offset
+ * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt
+ * status_reg: status register offset
+ * status_reg_mask: status register valid mask
+ * clear_reg: clear register offset
+ * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt
+ */
+struct shirq_regs {
+ void __iomem *base;
+ u32 enb_reg;
+ u32 reset_to_enb;
+ u32 status_reg;
+ u32 status_reg_mask;
+ u32 clear_reg;
+ u32 reset_to_clear;
+};
+
+/*
+ * struct spear_shirq: shared irq structure
+ *
+ * irq: hardware irq number
+ * dev_config: array of device config structures which are using "irq" line
+ * dev_count: size of dev_config array
+ * regs: register configuration for shared irq block
+ */
+struct spear_shirq {
+ u32 irq;
+ struct shirq_dev_config *dev_config;
+ u32 dev_count;
+ struct shirq_regs regs;
+};
+
+int spear_shirq_register(struct spear_shirq *shirq);
+
+#endif /* __PLAT_SHIRQ_H */
diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h
new file mode 100644
index 00000000..a235fa0c
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/system.h
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/plat-spear/include/plat/system.h
+ *
+ * SPEAr platform specific architecture functions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_SYSTEM_H
+#define __PLAT_SYSTEM_H
+
+#include <linux/io.h>
+#include <asm/hardware/sp810.h>
+#include <mach/hardware.h>
+
+static inline void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks
+ */
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ if (mode == 's') {
+ /* software reset, Jump into ROM at address 0 */
+ cpu_reset(0);
+ } else {
+ /* hardware reset, Use on-chip reset capability */
+ sysctl_soft_reset((void __iomem *)VA_SPEAR_SYS_CTRL_BASE);
+ }
+}
+
+#endif /* __PLAT_SYSTEM_H */
diff --git a/arch/arm/plat-spear/include/plat/timex.h b/arch/arm/plat-spear/include/plat/timex.h
new file mode 100644
index 00000000..914d09dd
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/timex.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/timex.h
+ *
+ * SPEAr platform specific timex definitions
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_TIMEX_H
+#define __PLAT_TIMEX_H
+
+#define CLOCK_TICK_RATE 48000000
+
+#endif /* __PLAT_TIMEX_H */
diff --git a/arch/arm/plat-spear/include/plat/uncompress.h b/arch/arm/plat-spear/include/plat/uncompress.h
new file mode 100644
index 00000000..1bf84527
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/uncompress.h
@@ -0,0 +1,43 @@
+/*
+ * arch/arm/plat-spear/include/plat/uncompress.h
+ *
+ * Serial port stubs for kernel decompress status messages
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/amba/serial.h>
+#include <mach/hardware.h>
+
+#ifndef __PLAT_UNCOMPRESS_H
+#define __PLAT_UNCOMPRESS_H
+/*
+ * This does not append a newline
+ */
+static inline void putc(int c)
+{
+ void __iomem *base = (void __iomem *)SPEAR_DBG_UART_BASE;
+
+ while (readl_relaxed(base + UART01x_FR) & UART01x_FR_TXFF)
+ barrier();
+
+ writel_relaxed(c, base + UART01x_DR);
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
+
+#endif /* __PLAT_UNCOMPRESS_H */
diff --git a/arch/arm/plat-spear/include/plat/vmalloc.h b/arch/arm/plat-spear/include/plat/vmalloc.h
new file mode 100644
index 00000000..8c8b24d0
--- /dev/null
+++ b/arch/arm/plat-spear/include/plat/vmalloc.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/plat-spear/include/plat/vmalloc.h
+ *
+ * Defining Vmalloc area for SPEAr platform
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_VMALLOC_H
+#define __PLAT_VMALLOC_H
+
+#define VMALLOC_END 0xF0000000UL
+
+#endif /* __PLAT_VMALLOC_H */
diff --git a/arch/arm/plat-spear/padmux.c b/arch/arm/plat-spear/padmux.c
new file mode 100644
index 00000000..555eec6d
--- /dev/null
+++ b/arch/arm/plat-spear/padmux.c
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/plat-spear/include/plat/padmux.c
+ *
+ * SPEAr platform specific gpio pads muxing source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <plat/padmux.h>
+
+/*
+ * struct pmx: pmx definition structure
+ *
+ * base: base address of configuration registers
+ * mode_reg: mode configurations
+ * mux_reg: muxing configurations
+ * active_mode: pointer to current active mode
+ */
+struct pmx {
+ u32 base;
+ struct pmx_reg mode_reg;
+ struct pmx_reg mux_reg;
+ struct pmx_mode *active_mode;
+};
+
+static struct pmx *pmx;
+
+/**
+ * pmx_mode_set - Enables an multiplexing mode
+ * @mode - pointer to pmx mode
+ *
+ * It will set mode of operation in hardware.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_mode_set(struct pmx_mode *mode)
+{
+ u32 val;
+
+ if (!mode->name)
+ return -EFAULT;
+
+ pmx->active_mode = mode;
+
+ val = readl(pmx->base + pmx->mode_reg.offset);
+ val &= ~pmx->mode_reg.mask;
+ val |= mode->mask & pmx->mode_reg.mask;
+ writel(val, pmx->base + pmx->mode_reg.offset);
+
+ return 0;
+}
+
+/**
+ * pmx_devs_enable - Enables list of devices
+ * @devs - pointer to pmx device array
+ * @count - number of devices to enable
+ *
+ * It will enable pads for all required peripherals once and only once.
+ * If peripheral is not supported by current mode then request is rejected.
+ * Conflicts between peripherals are not handled and peripherals will be
+ * enabled in the order they are present in pmx_dev array.
+ * In case of conflicts last peripheral enabled will be present.
+ * Returns -ve on Err otherwise 0
+ */
+static int pmx_devs_enable(struct pmx_dev **devs, u8 count)
+{
+ u32 val, i, mask;
+
+ if (!count)
+ return -EINVAL;
+
+ val = readl(pmx->base + pmx->mux_reg.offset);
+ for (i = 0; i < count; i++) {
+ u8 j = 0;
+
+ if (!devs[i]->name || !devs[i]->modes) {
+ printk(KERN_ERR "padmux: dev name or modes is null\n");
+ continue;
+ }
+ /* check if peripheral exists in active mode */
+ if (pmx->active_mode) {
+ bool found = false;
+ for (j = 0; j < devs[i]->mode_count; j++) {
+ if (devs[i]->modes[j].ids &
+ pmx->active_mode->id) {
+ found = true;
+ break;
+ }
+ }
+ if (found == false) {
+ printk(KERN_ERR "%s device not available in %s"\
+ "mode\n", devs[i]->name,
+ pmx->active_mode->name);
+ continue;
+ }
+ }
+
+ /* enable peripheral */
+ mask = devs[i]->modes[j].mask & pmx->mux_reg.mask;
+ if (devs[i]->enb_on_reset)
+ val &= ~mask;
+ else
+ val |= mask;
+
+ devs[i]->is_active = true;
+ }
+ writel(val, pmx->base + pmx->mux_reg.offset);
+ kfree(pmx);
+
+ /* this will ensure that multiplexing can't be changed now */
+ pmx = (struct pmx *)-1;
+
+ return 0;
+}
+
+/**
+ * pmx_register - registers a platform requesting pad mux feature
+ * @driver - pointer to driver structure containing driver specific parameters
+ *
+ * Also this must be called only once. This will allocate memory for pmx
+ * structure, will call pmx_mode_set, will call pmx_devs_enable.
+ * Returns -ve on Err otherwise 0
+ */
+int pmx_register(struct pmx_driver *driver)
+{
+ int ret = 0;
+
+ if (pmx)
+ return -EPERM;
+ if (!driver->base || !driver->devs)
+ return -EFAULT;
+
+ pmx = kzalloc(sizeof(*pmx), GFP_KERNEL);
+ if (!pmx)
+ return -ENOMEM;
+
+ pmx->base = (u32)driver->base;
+ pmx->mode_reg.offset = driver->mode_reg.offset;
+ pmx->mode_reg.mask = driver->mode_reg.mask;
+ pmx->mux_reg.offset = driver->mux_reg.offset;
+ pmx->mux_reg.mask = driver->mux_reg.mask;
+
+ /* choose mode to enable */
+ if (driver->mode) {
+ ret = pmx_mode_set(driver->mode);
+ if (ret)
+ goto pmx_fail;
+ }
+ ret = pmx_devs_enable(driver->devs, driver->devs_count);
+ if (ret)
+ goto pmx_fail;
+
+ return 0;
+
+pmx_fail:
+ return ret;
+}
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c
new file mode 100644
index 00000000..961fb726
--- /dev/null
+++ b/arch/arm/plat-spear/shirq.c
@@ -0,0 +1,118 @@
+/*
+ * arch/arm/plat-spear/shirq.c
+ *
+ * SPEAr platform shared irq layer source file
+ *
+ * Copyright (C) 2009 ST Microelectronics
+ * Viresh Kumar<viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <plat/shirq.h>
+
+struct spear_shirq *shirq;
+static DEFINE_SPINLOCK(lock);
+
+static void shirq_irq_mask(struct irq_data *d)
+{
+ struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
+ u32 val, id = d->irq - shirq->dev_config[0].virq;
+ unsigned long flags;
+
+ if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+ return;
+
+ spin_lock_irqsave(&lock, flags);
+ val = readl(shirq->regs.base + shirq->regs.enb_reg);
+ if (shirq->regs.reset_to_enb)
+ val |= shirq->dev_config[id].enb_mask;
+ else
+ val &= ~(shirq->dev_config[id].enb_mask);
+ writel(val, shirq->regs.base + shirq->regs.enb_reg);
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static void shirq_irq_unmask(struct irq_data *d)
+{
+ struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
+ u32 val, id = d->irq - shirq->dev_config[0].virq;
+ unsigned long flags;
+
+ if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+ return;
+
+ spin_lock_irqsave(&lock, flags);
+ val = readl(shirq->regs.base + shirq->regs.enb_reg);
+ if (shirq->regs.reset_to_enb)
+ val &= ~(shirq->dev_config[id].enb_mask);
+ else
+ val |= shirq->dev_config[id].enb_mask;
+ writel(val, shirq->regs.base + shirq->regs.enb_reg);
+ spin_unlock_irqrestore(&lock, flags);
+}
+
+static struct irq_chip shirq_chip = {
+ .name = "spear_shirq",
+ .irq_ack = shirq_irq_mask,
+ .irq_mask = shirq_irq_mask,
+ .irq_unmask = shirq_irq_unmask,
+};
+
+static void shirq_handler(unsigned irq, struct irq_desc *desc)
+{
+ u32 i, val, mask;
+ struct spear_shirq *shirq = irq_get_handler_data(irq);
+
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+ while ((val = readl(shirq->regs.base + shirq->regs.status_reg) &
+ shirq->regs.status_reg_mask)) {
+ for (i = 0; (i < shirq->dev_count) && val; i++) {
+ if (!(shirq->dev_config[i].status_mask & val))
+ continue;
+
+ generic_handle_irq(shirq->dev_config[i].virq);
+
+ /* clear interrupt */
+ val &= ~shirq->dev_config[i].status_mask;
+ if ((shirq->regs.clear_reg == -1) ||
+ shirq->dev_config[i].clear_mask == -1)
+ continue;
+ mask = readl(shirq->regs.base + shirq->regs.clear_reg);
+ if (shirq->regs.reset_to_clear)
+ mask &= ~shirq->dev_config[i].clear_mask;
+ else
+ mask |= shirq->dev_config[i].clear_mask;
+ writel(mask, shirq->regs.base + shirq->regs.clear_reg);
+ }
+ }
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+}
+
+int spear_shirq_register(struct spear_shirq *shirq)
+{
+ int i;
+
+ if (!shirq || !shirq->dev_config || !shirq->regs.base)
+ return -EFAULT;
+
+ if (!shirq->dev_count)
+ return -EINVAL;
+
+ irq_set_chained_handler(shirq->irq, shirq_handler);
+ for (i = 0; i < shirq->dev_count; i++) {
+ irq_set_chip_and_handler(shirq->dev_config[i].virq,
+ &shirq_chip, handle_simple_irq);
+ set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID);
+ irq_set_chip_data(shirq->dev_config[i].virq, shirq);
+ }
+
+ irq_set_handler_data(shirq->irq, shirq);
+ return 0;
+}
diff --git a/arch/arm/plat-spear/time.c b/arch/arm/plat-spear/time.c
new file mode 100644
index 00000000..0c77e429
--- /dev/null
+++ b/arch/arm/plat-spear/time.c
@@ -0,0 +1,237 @@
+/*
+ * arch/arm/plat-spear/time.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Shiraz Hashim<shiraz.hashim@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/irq.h>
+#include <asm/mach/time.h>
+#include <mach/generic.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+/*
+ * We would use TIMER0 and TIMER1 as clockevent and clocksource.
+ * Timer0 and Timer1 both belong to same gpt block in cpu subbsystem. Further
+ * they share same functional clock. Any change in one's functional clock will
+ * also affect other timer.
+ */
+
+#define CLKEVT 0 /* gpt0, channel0 as clockevent */
+#define CLKSRC 1 /* gpt0, channel1 as clocksource */
+
+/* Register offsets, x is channel number */
+#define CR(x) ((x) * 0x80 + 0x80)
+#define IR(x) ((x) * 0x80 + 0x84)
+#define LOAD(x) ((x) * 0x80 + 0x88)
+#define COUNT(x) ((x) * 0x80 + 0x8C)
+
+/* Reg bit definitions */
+#define CTRL_INT_ENABLE 0x0100
+#define CTRL_ENABLE 0x0020
+#define CTRL_ONE_SHOT 0x0010
+
+#define CTRL_PRESCALER1 0x0
+#define CTRL_PRESCALER2 0x1
+#define CTRL_PRESCALER4 0x2
+#define CTRL_PRESCALER8 0x3
+#define CTRL_PRESCALER16 0x4
+#define CTRL_PRESCALER32 0x5
+#define CTRL_PRESCALER64 0x6
+#define CTRL_PRESCALER128 0x7
+#define CTRL_PRESCALER256 0x8
+
+#define INT_STATUS 0x1
+
+/*
+ * Minimum clocksource/clockevent timer range in seconds
+ */
+#define SPEAR_MIN_RANGE 4
+
+static __iomem void *gpt_base;
+static struct clk *gpt_clk;
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk_event_dev);
+static int clockevent_next_event(unsigned long evt,
+ struct clock_event_device *clk_event_dev);
+
+static void spear_clocksource_init(void)
+{
+ u32 tick_rate;
+ u16 val;
+
+ /* program the prescaler (/256)*/
+ writew(CTRL_PRESCALER256, gpt_base + CR(CLKSRC));
+
+ /* find out actual clock driving Timer */
+ tick_rate = clk_get_rate(gpt_clk);
+ tick_rate >>= CTRL_PRESCALER256;
+
+ writew(0xFFFF, gpt_base + LOAD(CLKSRC));
+
+ val = readw(gpt_base + CR(CLKSRC));
+ val &= ~CTRL_ONE_SHOT; /* autoreload mode */
+ val |= CTRL_ENABLE ;
+ writew(val, gpt_base + CR(CLKSRC));
+
+ /* register the clocksource */
+ clocksource_mmio_init(gpt_base + COUNT(CLKSRC), "tmr1", tick_rate,
+ 200, 16, clocksource_mmio_readw_up);
+}
+
+static struct clock_event_device clkevt = {
+ .name = "tmr0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .set_mode = clockevent_set_mode,
+ .set_next_event = clockevent_next_event,
+ .shift = 0, /* to be computed */
+};
+
+static void clockevent_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk_event_dev)
+{
+ u32 period;
+ u16 val;
+
+ /* stop the timer */
+ val = readw(gpt_base + CR(CLKEVT));
+ val &= ~CTRL_ENABLE;
+ writew(val, gpt_base + CR(CLKEVT));
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ period = clk_get_rate(gpt_clk) / HZ;
+ period >>= CTRL_PRESCALER16;
+ writew(period, gpt_base + LOAD(CLKEVT));
+
+ val = readw(gpt_base + CR(CLKEVT));
+ val &= ~CTRL_ONE_SHOT;
+ val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+ writew(val, gpt_base + CR(CLKEVT));
+
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ val = readw(gpt_base + CR(CLKEVT));
+ val |= CTRL_ONE_SHOT;
+ writew(val, gpt_base + CR(CLKEVT));
+
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+
+ break;
+ default:
+ pr_err("Invalid mode requested\n");
+ break;
+ }
+}
+
+static int clockevent_next_event(unsigned long cycles,
+ struct clock_event_device *clk_event_dev)
+{
+ u16 val;
+
+ writew(cycles, gpt_base + LOAD(CLKEVT));
+
+ val = readw(gpt_base + CR(CLKEVT));
+ val |= CTRL_ENABLE | CTRL_INT_ENABLE;
+ writew(val, gpt_base + CR(CLKEVT));
+
+ return 0;
+}
+
+static irqreturn_t spear_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clkevt;
+
+ writew(INT_STATUS, gpt_base + IR(CLKEVT));
+
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction spear_timer_irq = {
+ .name = "timer",
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .handler = spear_timer_interrupt
+};
+
+static void __init spear_clockevent_init(void)
+{
+ u32 tick_rate;
+
+ /* program the prescaler */
+ writew(CTRL_PRESCALER16, gpt_base + CR(CLKEVT));
+
+ tick_rate = clk_get_rate(gpt_clk);
+ tick_rate >>= CTRL_PRESCALER16;
+
+ clockevents_calc_mult_shift(&clkevt, tick_rate, SPEAR_MIN_RANGE);
+
+ clkevt.max_delta_ns = clockevent_delta2ns(0xfff0,
+ &clkevt);
+ clkevt.min_delta_ns = clockevent_delta2ns(3, &clkevt);
+
+ clkevt.cpumask = cpumask_of(0);
+
+ clockevents_register_device(&clkevt);
+
+ setup_irq(SPEAR_GPT0_CHAN0_IRQ, &spear_timer_irq);
+}
+
+void __init spear_setup_timer(void)
+{
+ int ret;
+
+ if (!request_mem_region(SPEAR_GPT0_BASE, SZ_1K, "gpt0")) {
+ pr_err("%s:cannot get IO addr\n", __func__);
+ return;
+ }
+
+ gpt_base = (void __iomem *)ioremap(SPEAR_GPT0_BASE, SZ_1K);
+ if (!gpt_base) {
+ pr_err("%s:ioremap failed for gpt\n", __func__);
+ goto err_mem;
+ }
+
+ gpt_clk = clk_get_sys("gpt0", NULL);
+ if (!gpt_clk) {
+ pr_err("%s:couldn't get clk for gpt\n", __func__);
+ goto err_iomap;
+ }
+
+ ret = clk_enable(gpt_clk);
+ if (ret < 0) {
+ pr_err("%s:couldn't enable gpt clock\n", __func__);
+ goto err_clk;
+ }
+
+ spear_clockevent_init();
+ spear_clocksource_init();
+
+ return;
+
+err_clk:
+ clk_put(gpt_clk);
+err_iomap:
+ iounmap(gpt_base);
+err_mem:
+ release_mem_region(SPEAR_GPT0_BASE, SZ_1K);
+}
diff --git a/arch/arm/plat-tcc/Kconfig b/arch/arm/plat-tcc/Kconfig
new file mode 100644
index 00000000..1bf49957
--- /dev/null
+++ b/arch/arm/plat-tcc/Kconfig
@@ -0,0 +1,20 @@
+if ARCH_TCC_926
+
+menu "Telechips ARM926-based CPUs"
+
+choice
+ prompt "Telechips CPU type:"
+ default ARCH_TCC8K
+
+config ARCH_TCC8K
+ bool TCC8000
+ select USB_ARCH_HAS_OHCI
+ help
+ Support for Telechips TCC8000 systems
+
+endchoice
+
+source "arch/arm/mach-tcc8k/Kconfig"
+
+endmenu
+endif
diff --git a/arch/arm/plat-tcc/Makefile b/arch/arm/plat-tcc/Makefile
new file mode 100644
index 00000000..eceabc86
--- /dev/null
+++ b/arch/arm/plat-tcc/Makefile
@@ -0,0 +1,3 @@
+# "Telechips Platform Common Modules"
+
+obj-y := clock.o system.o
diff --git a/arch/arm/plat-tcc/clock.c b/arch/arm/plat-tcc/clock.c
new file mode 100644
index 00000000..f3ced10d
--- /dev/null
+++ b/arch/arm/plat-tcc/clock.c
@@ -0,0 +1,179 @@
+/*
+ * Clock framework for Telechips SoCs
+ * Based on arch/arm/plat-mxc/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2010 Hans J. Koch, hjk@linutronix.de
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ BUG_ON(clk->refcount == 0);
+
+ if (!(--clk->refcount) && clk->disable) {
+ /* Unconditionally disable the clock in hardware */
+ clk->disable(clk);
+ /* recursively disable parents */
+ if (clk->parent)
+ __clk_disable(clk->parent);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk->refcount++ == 0 && clk->enable) {
+ if (clk->parent)
+ ret = __clk_enable(clk->parent);
+ if (ret)
+ return ret;
+ else
+ return clk->enable(clk);
+ }
+
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (!clk)
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (!clk)
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (!clk)
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (!clk)
+ return 0;
+ if (!clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_rate || !rate)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct clk *old;
+ int ret = -EINVAL;
+
+ if (!clk)
+ return ret;
+ if (!clk->set_parent || !parent)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ old = clk->parent;
+ if (clk->refcount)
+ __clk_enable(parent);
+ ret = clk->set_parent(clk, parent);
+ if (ret)
+ old = parent;
+ if (clk->refcount)
+ __clk_disable(old);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ if (!clk)
+ return NULL;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL_GPL(clk_get_parent);
diff --git a/arch/arm/plat-tcc/include/mach/clkdev.h b/arch/arm/plat-tcc/include/mach/clkdev.h
new file mode 100644
index 00000000..04b37a89
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/clock.h b/arch/arm/plat-tcc/include/mach/clock.h
new file mode 100644
index 00000000..a12f58ad
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/clock.h
@@ -0,0 +1,48 @@
+/*
+ * Low level clock header file for Telechips TCC architecture
+ * (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_TCC_CLOCK_H__
+#define __ASM_ARCH_TCC_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+
+struct clk {
+ struct clk *parent;
+ /* id number of a root clock, 0 for normal clocks */
+ int root_id;
+ /* Reference count of clock enable/disable */
+ int refcount;
+ /* Address of associated BCLKCTRx register. Must be set. */
+ void __iomem *bclkctr;
+ /* Bit position for BCLKCTRx. Must be set. */
+ int bclk_shift;
+ /* Address of ACLKxxx register, if any. */
+ void __iomem *aclkreg;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-tcc/include/mach/debug-macro.S b/arch/arm/plat-tcc/include/mach/debug-macro.S
new file mode 100644
index 00000000..7662f736
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/debug-macro.S
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+ .macro addruart, rp, rv
+ moveq \rp, #0x90000000 @ physical base address
+ movne \rv, #0xF1000000 @ virtual base
+ orr \rp, \rp, #0x00007000 @ UART0
+ orr \rv, \rv, #0x00007000 @ UART0
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #0x44]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001:
+ ldr \rd, [\rx, #0x14]
+ tst \rd, #0x20
+
+ beq 1001b
+ .endm
diff --git a/arch/arm/plat-tcc/include/mach/entry-macro.S b/arch/arm/plat-tcc/include/mach/entry-macro.S
new file mode 100644
index 00000000..748f401e
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/entry-macro.S
@@ -0,0 +1,68 @@
+/*
+ * include/asm-arm/arch-tcc83x/entry-macro.S
+ *
+ * Author : <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: Low-level IRQ helper macros for Telechips-based platforms
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ ldr \base, =0xF2003000 @ base address of PIC registers
+
+ @@ read MREQ register of PIC0
+
+ mov \irqnr, #0
+ ldr \irqstat, [\base, #0x00000014 ] @ lower 32 interrupts
+ cmp \irqstat, #0
+ bne 1001f
+
+ @@ read MREQ register of PIC1
+
+ ldr \irqstat, [\base, #0x00000094] @ upper 32 interrupts
+ cmp \irqstat, #0
+ beq 1002f
+ mov \irqnr, #0x20
+
+1001:
+ movs \tmp, \irqstat, lsl #16
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #16
+
+ movs \tmp, \irqstat, lsl #8
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #8
+
+ movs \tmp, \irqstat, lsl #4
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #4
+
+ movs \tmp, \irqstat, lsl #2
+ movne \irqstat, \tmp
+ addeq \irqnr, \irqnr, #2
+
+ movs \tmp, \irqstat, lsl #1
+ addeq \irqnr, \irqnr, #1
+ orrs \base, \base, #1
+1002:
+ @@ exit here, Z flag unset if IRQ
+
+ .endm
diff --git a/arch/arm/plat-tcc/include/mach/hardware.h b/arch/arm/plat-tcc/include/mach/hardware.h
new file mode 100644
index 00000000..e70d126c
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/hardware.h
@@ -0,0 +1,43 @@
+/*
+ * Author: RidgeRun, Inc. Greg Lonnon <glonnon@ridgerun.com>
+ * Reorganized for Linux-2.6 by Tony Lindgren <tony@atomide.com>
+ * and Dirk Behme <dirk.behme@de.bosch.com>
+ * Rewritten by: <linux@telechips.com>
+ * Description: Hardware definitions for TCC8300 processors and boards
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Modifications for mainline (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Pulic License version 2.
+ */
+
+#ifndef __ASM_ARCH_TCC_HARDWARE_H
+#define __ASM_ARCH_TCC_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#endif
+#include <mach/io.h>
+
+/*
+ * ----------------------------------------------------------------------------
+ * Clocks
+ * ----------------------------------------------------------------------------
+ */
+#define CLKGEN_REG_BASE 0xfffece00
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+/* DPLL control registers */
+#define DPLL_CTL 0xfffecf00
+
+#endif /* __ASM_ARCH_TCC_HARDWARE_H */
diff --git a/arch/arm/plat-tcc/include/mach/io.h b/arch/arm/plat-tcc/include/mach/io.h
new file mode 100644
index 00000000..3e911d3e
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/io.h
@@ -0,0 +1,23 @@
+/*
+ * IO definitions for TCC8000 processors and boards
+ *
+ * Copyright (C) 1997-1999 Russell King
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GNU Public License version 2.
+ */
+
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a) __typesafe_io(a)
+#define __mem_pci(a) (a)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/irqs.h b/arch/arm/plat-tcc/include/mach/irqs.h
new file mode 100644
index 00000000..da863894
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/irqs.h
@@ -0,0 +1,83 @@
+/*
+ * IRQ definitions for TCC8xxx
+ *
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_TCC_IRQS_H
+#define __ASM_ARCH_TCC_IRQS_H
+
+#define NR_IRQS 64
+
+/* PIC0 interrupts */
+#define INT_ADMA1 0
+#define INT_BDMA 1
+#define INT_ADMA0 2
+#define INT_GDMA1 3
+#define INT_I2S0RX 4
+#define INT_I2S0TX 5
+#define INT_TC 6
+#define INT_UART0 7
+#define INT_USBD 8
+#define INT_SPI0TX 9
+#define INT_UDMA 10
+#define INT_LIRQ 11
+#define INT_GDMA2 12
+#define INT_GDMA0 13
+#define INT_TC32 14
+#define INT_LCD 15
+#define INT_ADC 16
+#define INT_I2C 17
+#define INT_RTCP 18
+#define INT_RTCA 19
+#define INT_NFC 20
+#define INT_SD0 21
+#define INT_GSB0 22
+#define INT_PK 23
+#define INT_USBH0 24
+#define INT_USBH1 25
+#define INT_G2D 26
+#define INT_ECC 27
+#define INT_SPI0RX 28
+#define INT_UART1 29
+#define INT_MSCL 30
+#define INT_GSB1 31
+/* PIC1 interrupts */
+#define INT_E0 32
+#define INT_E1 33
+#define INT_E2 34
+#define INT_E3 35
+#define INT_E4 36
+#define INT_E5 37
+#define INT_E6 38
+#define INT_E7 39
+#define INT_UART2 40
+#define INT_UART3 41
+#define INT_SPI1TX 42
+#define INT_SPI1RX 43
+#define INT_GSB2 44
+#define INT_SPDIF 45
+#define INT_CDIF 46
+#define INT_VBON 47
+#define INT_VBOFF 48
+#define INT_SD1 49
+#define INT_UART4 50
+#define INT_GDMA3 51
+#define INT_I2S1RX 52
+#define INT_I2S1TX 53
+#define INT_CAN0 54
+#define INT_CAN1 55
+#define INT_GSB3 56
+#define INT_KRST 57
+#define INT_UNUSED 58
+#define INT_SD0D3 59
+#define INT_SD1D3 60
+#define INT_GPS0 61
+#define INT_GPS1 62
+#define INT_GPS2 63
+
+#endif /* ASM_ARCH_TCC_IRQS_H */
diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h
new file mode 100644
index 00000000..28a6e0cd
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/memory.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Copyright (C) 2008-2009 Telechips
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PLAT_PHYS_OFFSET UL(0x20000000)
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/system.h b/arch/arm/plat-tcc/include/mach/system.h
new file mode 100644
index 00000000..909e6035
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/system.h
@@ -0,0 +1,31 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ * Description: LINUX SYSTEM FUNCTIONS for TCC83x
+ *
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+extern void plat_tcc_reboot(void);
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ plat_tcc_reboot();
+}
+
+#endif
diff --git a/arch/arm/plat-tcc/include/mach/tcc8k-regs.h b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
new file mode 100644
index 00000000..1d942829
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/tcc8k-regs.h
@@ -0,0 +1,807 @@
+/*
+ * Telechips TCC8000 register definitions
+ *
+ * (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPLv2.
+ */
+
+#ifndef TCC8K_REGS_H
+#define TCC8K_REGS_H
+
+#include <linux/types.h>
+
+#define EXT_SDRAM_BASE 0x20000000
+#define INT_SRAM_BASE 0x30000000
+#define INT_SRAM_SIZE SZ_32K
+#define CS0_BASE 0x40000000
+#define CS1_BASE 0x50000000
+#define CS1_SIZE SZ_64K
+#define CS2_BASE 0x60000000
+#define CS3_BASE 0x70000000
+#define AHB_PERI_BASE 0x80000000
+#define AHB_PERI_SIZE SZ_64K
+#define APB0_PERI_BASE 0x90000000
+#define APB0_PERI_SIZE SZ_128K
+#define APB1_PERI_BASE 0x98000000
+#define APB1_PERI_SIZE SZ_128K
+#define DATA_TCM_BASE 0xa0000000
+#define DATA_TCM_SIZE SZ_8K
+#define EXT_MEM_CTRL_BASE 0xf0000000
+#define EXT_MEM_CTRL_SIZE SZ_4K
+
+#define CS1_BASE_VIRT (void __iomem *)0xf7000000
+#define AHB_PERI_BASE_VIRT (void __iomem *)0xf4000000
+#define APB0_PERI_BASE_VIRT (void __iomem *)0xf1000000
+#define APB1_PERI_BASE_VIRT (void __iomem *)0xf2000000
+#define EXT_MEM_CTRL_BASE_VIRT (void __iomem *)0xf3000000
+#define INT_SRAM_BASE_VIRT (void __iomem *)0xf5000000
+#define DATA_TCM_BASE_VIRT (void __iomem *)0xf6000000
+
+#define __REG(x) (*((volatile u32 *)(x)))
+
+/* USB Device Controller Registers */
+#define UDC_BASE (AHB_PERI_BASE_VIRT + 0x8000)
+#define UDC_BASE_PHYS (AHB_PERI_BASE + 0x8000)
+
+#define UDC_IR_OFFS 0x00
+#define UDC_EIR_OFFS 0x04
+#define UDC_EIER_OFFS 0x08
+#define UDC_FAR_OFFS 0x0c
+#define UDC_FNR_OFFS 0x10
+#define UDC_EDR_OFFS 0x14
+#define UDC_RT_OFFS 0x18
+#define UDC_SSR_OFFS 0x1c
+#define UDC_SCR_OFFS 0x20
+#define UDC_EP0SR_OFFS 0x24
+#define UDC_EP0CR_OFFS 0x28
+
+#define UDC_ESR_OFFS 0x2c
+#define UDC_ECR_OFFS 0x30
+#define UDC_BRCR_OFFS 0x34
+#define UDC_BWCR_OFFS 0x38
+#define UDC_MPR_OFFS 0x3c
+#define UDC_DCR_OFFS 0x40
+#define UDC_DTCR_OFFS 0x44
+#define UDC_DFCR_OFFS 0x48
+#define UDC_DTTCR1_OFFS 0x4c
+#define UDC_DTTCR2_OFFS 0x50
+#define UDC_ESR2_OFFS 0x54
+
+#define UDC_SCR2_OFFS 0x58
+#define UDC_EP0BUF_OFFS 0x60
+#define UDC_EP1BUF_OFFS 0x64
+#define UDC_EP2BUF_OFFS 0x68
+#define UDC_EP3BUF_OFFS 0x6c
+#define UDC_PLICR_OFFS 0xa0
+#define UDC_PCR_OFFS 0xa4
+
+#define UDC_UPCR0_OFFS 0xc8
+#define UDC_UPCR1_OFFS 0xcc
+#define UDC_UPCR2_OFFS 0xd0
+#define UDC_UPCR3_OFFS 0xd4
+
+/* Bits in UDC_EIR */
+#define UDC_EIR_EP0I (1 << 0)
+#define UDC_EIR_EP1I (1 << 1)
+#define UDC_EIR_EP2I (1 << 2)
+#define UDC_EIR_EP3I (1 << 3)
+#define UDC_EIR_EPI_MASK 0x0f
+
+/* Bits in UDC_EIER */
+#define UDC_EIER_EP0IE (1 << 0)
+#define UDC_EIER_EP1IE (1 << 1)
+#define UDC_EIER_EP2IE (1 << 2)
+#define UDC_EIER_EP3IE (1 << 3)
+
+/* Bits in UDC_FNR */
+#define UDC_FNR_FN_MASK 0x7ff
+#define UDC_FNR_SM (1 << 13)
+#define UDC_FNR_FTL (1 << 14)
+
+/* Bits in UDC_SSR */
+#define UDC_SSR_HFRES (1 << 0)
+#define UDC_SSR_HFSUSP (1 << 1)
+#define UDC_SSR_HFRM (1 << 2)
+#define UDC_SSR_SDE (1 << 3)
+#define UDC_SSR_HSP (1 << 4)
+#define UDC_SSR_DM (1 << 5)
+#define UDC_SSR_DP (1 << 6)
+#define UDC_SSR_TBM (1 << 7)
+#define UDC_SSR_VBON (1 << 8)
+#define UDC_SSR_VBOFF (1 << 9)
+#define UDC_SSR_EOERR (1 << 10)
+#define UDC_SSR_DCERR (1 << 11)
+#define UDC_SSR_TCERR (1 << 12)
+#define UDC_SSR_BSERR (1 << 13)
+#define UDC_SSR_TMERR (1 << 14)
+#define UDC_SSR_BAERR (1 << 15)
+
+/* Bits in UDC_SCR */
+#define UDC_SCR_HRESE (1 << 0)
+#define UDC_SCR_HSSPE (1 << 1)
+#define UDC_SCR_RRDE (1 << 5)
+#define UDC_SCR_SPDEN (1 << 6)
+#define UDC_SCR_DIEN (1 << 12)
+
+/* Bits in UDC_EP0SR */
+#define UDC_EP0SR_RSR (1 << 0)
+#define UDC_EP0SR_TST (1 << 1)
+#define UDC_EP0SR_SHT (1 << 4)
+#define UDC_EP0SR_LWO (1 << 6)
+
+/* Bits in UDC_EP0CR */
+#define UDC_EP0CR_ESS (1 << 1)
+
+/* Bits in UDC_ESR */
+#define UDC_ESR_RPS (1 << 0)
+#define UDC_ESR_TPS (1 << 1)
+#define UDC_ESR_LWO (1 << 4)
+#define UDC_ESR_FFS (1 << 6)
+
+/* Bits in UDC_ECR */
+#define UDC_ECR_ESS (1 << 1)
+#define UDC_ECR_CDP (1 << 2)
+
+#define UDC_ECR_FLUSH (1 << 6)
+#define UDC_ECR_DUEN (1 << 7)
+
+/* Bits in UDC_UPCR0 */
+#define UDC_UPCR0_VBD (1 << 1)
+#define UDC_UPCR0_VBDS (1 << 6)
+#define UDC_UPCR0_RCD_12 (0x0 << 9)
+#define UDC_UPCR0_RCD_24 (0x1 << 9)
+#define UDC_UPCR0_RCD_48 (0x2 << 9)
+#define UDC_UPCR0_RCS_EXT (0x1 << 11)
+#define UDC_UPCR0_RCS_XTAL (0x0 << 11)
+
+/* Bits in UDC_UPCR1 */
+#define UDC_UPCR1_CDT(x) ((x) << 0)
+#define UDC_UPCR1_OTGT(x) ((x) << 3)
+#define UDC_UPCR1_SQRXT(x) ((x) << 8)
+#define UDC_UPCR1_TXFSLST(x) ((x) << 12)
+
+/* Bits in UDC_UPCR2 */
+#define UDC_UPCR2_TP (1 << 0)
+#define UDC_UPCR2_TXRT(x) ((x) << 2)
+#define UDC_UPCR2_TXVRT(x) ((x) << 5)
+#define UDC_UPCR2_OPMODE(x) ((x) << 9)
+#define UDC_UPCR2_XCVRSEL(x) ((x) << 12)
+#define UDC_UPCR2_TM (1 << 14)
+
+/* USB Host Controller registers */
+#define USBH0_BASE (AHB_PERI_BASE_VIRT + 0xb000)
+#define USBH1_BASE (AHB_PERI_BASE_VIRT + 0xb800)
+
+#define OHCI_INT_ENABLE_OFFS 0x10
+
+#define RH_DESCRIPTOR_A_OFFS 0x48
+#define RH_DESCRIPTOR_B_OFFS 0x4c
+
+#define USBHTCFG0_OFFS 0x100
+#define USBHHCFG0_OFFS 0x104
+#define USBHHCFG1_OFFS 0x104
+
+/* DMA controller registers */
+#define DMAC0_BASE (AHB_PERI_BASE + 0x4000)
+#define DMAC1_BASE (AHB_PERI_BASE + 0xa000)
+#define DMAC2_BASE (AHB_PERI_BASE + 0x4800)
+#define DMAC3_BASE (AHB_PERI_BASE + 0xa800)
+
+#define DMAC_CH_OFFSET(ch) (ch * 0x30)
+
+#define ST_SADR_OFFS 0x00
+#define SPARAM_OFFS 0x04
+#define C_SADR_OFFS 0x0c
+#define ST_DADR_OFFS 0x10
+#define DPARAM_OFFS 0x14
+#define C_DADR_OFFS 0x1c
+#define HCOUNT_OFFS 0x20
+#define CHCTRL_OFFS 0x24
+#define RPTCTRL_OFFS 0x28
+#define EXTREQ_A_OFFS 0x2c
+
+/* Bits in CHCTRL register */
+#define CHCTRL_EN (1 << 0)
+
+#define CHCTRL_IEN (1 << 2)
+#define CHCTRL_FLAG (1 << 3)
+#define CHCTRL_WSIZE8 (0 << 4)
+#define CHCTRL_WSIZE16 (1 << 4)
+#define CHCTRL_WSIZE32 (2 << 4)
+
+#define CHCTRL_BSIZE1 (0 << 6)
+#define CHCTRL_BSIZE2 (1 << 6)
+#define CHCTRL_BSIZE4 (2 << 6)
+#define CHCTRL_BSIZE8 (3 << 6)
+
+#define CHCTRL_TYPE_SINGLE_E (0 << 8)
+#define CHCTRL_TYPE_HW (1 << 8)
+#define CHCTRL_TYPE_SW (2 << 8)
+#define CHCTRL_TYPE_SINGLE_L (3 << 8)
+
+#define CHCTRL_BST (1 << 10)
+
+/* Use DMA controller 0, channel 2 for USB */
+#define USB_DMA_BASE (DMAC0_BASE + DMAC_CH_OFFSET(2))
+
+/* NAND flash controller registers */
+#define NFC_BASE (AHB_PERI_BASE_VIRT + 0xd000)
+#define NFC_BASE_PHYS (AHB_PERI_BASE + 0xd000)
+
+#define NFC_CMD_OFFS 0x00
+#define NFC_LADDR_OFFS 0x04
+#define NFC_BADDR_OFFS 0x08
+#define NFC_SADDR_OFFS 0x0c
+#define NFC_WDATA_OFFS 0x10
+#define NFC_LDATA_OFFS 0x20
+#define NFC_SDATA_OFFS 0x40
+#define NFC_CTRL_OFFS 0x50
+#define NFC_PSTART_OFFS 0x54
+#define NFC_RSTART_OFFS 0x58
+#define NFC_DSIZE_OFFS 0x5c
+#define NFC_IREQ_OFFS 0x60
+#define NFC_RST_OFFS 0x64
+#define NFC_CTRL1_OFFS 0x68
+#define NFC_MDATA_OFFS 0x70
+
+#define NFC_WDATA_PHYS_ADDR (NFC_BASE_PHYS + NFC_WDATA_OFFS)
+
+/* Bits in NFC_CTRL */
+#define NFC_CTRL_BHLD_MASK (0xf << 0)
+#define NFC_CTRL_BPW_MASK (0xf << 4)
+#define NFC_CTRL_BSTP_MASK (0xf << 8)
+#define NFC_CTRL_CADDR_MASK (0x7 << 12)
+#define NFC_CTRL_CADDR_1 (0x0 << 12)
+#define NFC_CTRL_CADDR_2 (0x1 << 12)
+#define NFC_CTRL_CADDR_3 (0x2 << 12)
+#define NFC_CTRL_CADDR_4 (0x3 << 12)
+#define NFC_CTRL_CADDR_5 (0x4 << 12)
+#define NFC_CTRL_MSK (1 << 15)
+#define NFC_CTRL_PSIZE256 (0 << 16)
+#define NFC_CTRL_PSIZE512 (1 << 16)
+#define NFC_CTRL_PSIZE1024 (2 << 16)
+#define NFC_CTRL_PSIZE2048 (3 << 16)
+#define NFC_CTRL_PSIZE4096 (4 << 16)
+#define NFC_CTRL_PSIZE_MASK (7 << 16)
+#define NFC_CTRL_BSIZE1 (0 << 19)
+#define NFC_CTRL_BSIZE2 (1 << 19)
+#define NFC_CTRL_BSIZE4 (2 << 19)
+#define NFC_CTRL_BSIZE8 (3 << 19)
+#define NFC_CTRL_BSIZE_MASK (3 << 19)
+#define NFC_CTRL_RDY (1 << 21)
+#define NFC_CTRL_CS0SEL (1 << 22)
+#define NFC_CTRL_CS1SEL (1 << 23)
+#define NFC_CTRL_CS2SEL (1 << 24)
+#define NFC_CTRL_CS3SEL (1 << 25)
+#define NFC_CTRL_CSMASK (0xf << 22)
+#define NFC_CTRL_BW (1 << 26)
+#define NFC_CTRL_FS (1 << 27)
+#define NFC_CTRL_DEN (1 << 28)
+#define NFC_CTRL_READ_IEN (1 << 29)
+#define NFC_CTRL_PROG_IEN (1 << 30)
+#define NFC_CTRL_RDY_IEN (1 << 31)
+
+/* Bits in NFC_IREQ */
+#define NFC_IREQ_IRQ0 (1 << 0)
+#define NFC_IREQ_IRQ1 (1 << 1)
+#define NFC_IREQ_IRQ2 (1 << 2)
+
+#define NFC_IREQ_FLAG0 (1 << 4)
+#define NFC_IREQ_FLAG1 (1 << 5)
+#define NFC_IREQ_FLAG2 (1 << 6)
+
+/* MMC controller registers */
+#define MMC0_BASE (AHB_PERI_BASE_VIRT + 0xe000)
+#define MMC1_BASE (AHB_PERI_BASE_VIRT + 0xe800)
+
+/* UART base addresses */
+
+#define UART0_BASE (APB0_PERI_BASE_VIRT + 0x07000)
+#define UART0_BASE_PHYS (APB0_PERI_BASE + 0x07000)
+#define UART1_BASE (APB0_PERI_BASE_VIRT + 0x08000)
+#define UART1_BASE_PHYS (APB0_PERI_BASE + 0x08000)
+#define UART2_BASE (APB0_PERI_BASE_VIRT + 0x09000)
+#define UART2_BASE_PHYS (APB0_PERI_BASE + 0x09000)
+#define UART3_BASE (APB0_PERI_BASE_VIRT + 0x0a000)
+#define UART3_BASE_PHYS (APB0_PERI_BASE + 0x0a000)
+#define UART4_BASE (APB0_PERI_BASE_VIRT + 0x15000)
+#define UART4_BASE_PHYS (APB0_PERI_BASE + 0x15000)
+
+#define UART_BASE UART0_BASE
+#define UART_BASE_PHYS UART0_BASE_PHYS
+
+/* ECC controller */
+#define ECC_CTR_BASE (APB0_PERI_BASE_VIRT + 0xd000)
+
+#define ECC_CTRL_OFFS 0x00
+#define ECC_BASE_OFFS 0x04
+#define ECC_MASK_OFFS 0x08
+#define ECC_CLEAR_OFFS 0x0c
+#define ECC4_0_OFFS 0x10
+#define ECC4_1_OFFS 0x14
+
+#define ECC_EADDR0_OFFS 0x50
+
+#define ECC_ERRNUM_OFFS 0x90
+#define ECC_IREQ_OFFS 0x94
+
+/* Bits in ECC_CTRL */
+#define ECC_CTRL_ECC4_DIEN (1 << 28)
+#define ECC_CTRL_ECC8_DIEN (1 << 29)
+#define ECC_CTRL_ECC12_DIEN (1 << 30)
+#define ECC_CTRL_ECC_DISABLE 0x0
+#define ECC_CTRL_ECC_SLC_ENC 0x8
+#define ECC_CTRL_ECC_SLC_DEC 0x9
+#define ECC_CTRL_ECC4_ENC 0xa
+#define ECC_CTRL_ECC4_DEC 0xb
+#define ECC_CTRL_ECC8_ENC 0xc
+#define ECC_CTRL_ECC8_DEC 0xd
+#define ECC_CTRL_ECC12_ENC 0xe
+#define ECC_CTRL_ECC12_DEC 0xf
+
+/* Bits in ECC_IREQ */
+#define ECC_IREQ_E4DI (1 << 4)
+
+#define ECC_IREQ_E4DF (1 << 20)
+#define ECC_IREQ_E4EF (1 << 21)
+
+/* Interrupt controller */
+
+#define PIC0_BASE (APB1_PERI_BASE_VIRT + 0x3000)
+#define PIC0_BASE_PHYS (APB1_PERI_BASE + 0x3000)
+
+#define PIC0_IEN_OFFS 0x00
+#define PIC0_CREQ_OFFS 0x04
+#define PIC0_IREQ_OFFS 0x08
+#define PIC0_IRQSEL_OFFS 0x0c
+#define PIC0_SRC_OFFS 0x10
+#define PIC0_MREQ_OFFS 0x14
+#define PIC0_TSTREQ_OFFS 0x18
+#define PIC0_POL_OFFS 0x1c
+#define PIC0_IRQ_OFFS 0x20
+#define PIC0_FIQ_OFFS 0x24
+#define PIC0_MIRQ_OFFS 0x28
+#define PIC0_MFIQ_OFFS 0x2c
+#define PIC0_TMODE_OFFS 0x30
+#define PIC0_SYNC_OFFS 0x34
+#define PIC0_WKUP_OFFS 0x38
+#define PIC0_TMODEA_OFFS 0x3c
+#define PIC0_INTOEN_OFFS 0x40
+#define PIC0_MEN0_OFFS 0x44
+#define PIC0_MEN_OFFS 0x48
+
+#define PIC0_IEN __REG(PIC0_BASE + PIC0_IEN_OFFS)
+#define PIC0_IEN_PHYS __REG(PIC0_BASE_PHYS + PIC0_IEN_OFFS)
+#define PIC0_CREQ __REG(PIC0_BASE + PIC0_CREQ_OFFS)
+#define PIC0_CREQ_PHYS __REG(PIC0_BASE_PHYS + PIC0_CREQ_OFFS)
+#define PIC0_IREQ __REG(PIC0_BASE + PIC0_IREQ_OFFS)
+#define PIC0_IRQSEL __REG(PIC0_BASE + PIC0_IRQSEL_OFFS)
+#define PIC0_IRQSEL_PHYS __REG(PIC0_BASE_PHYS + PIC0_IRQSEL_OFFS)
+#define PIC0_SRC __REG(PIC0_BASE + PIC0_SRC_OFFS)
+#define PIC0_MREQ __REG(PIC0_BASE + PIC0_MREQ_OFFS)
+#define PIC0_TSTREQ __REG(PIC0_BASE + PIC0_TSTREQ_OFFS)
+#define PIC0_POL __REG(PIC0_BASE + PIC0_POL_OFFS)
+#define PIC0_IRQ __REG(PIC0_BASE + PIC0_IRQ_OFFS)
+#define PIC0_FIQ __REG(PIC0_BASE + PIC0_FIQ_OFFS)
+#define PIC0_MIRQ __REG(PIC0_BASE + PIC0_MIRQ_OFFS)
+#define PIC0_MFIQ __REG(PIC0_BASE + PIC0_MFIQ_OFFS)
+#define PIC0_TMODE __REG(PIC0_BASE + PIC0_TMODE_OFFS)
+#define PIC0_TMODE_PHYS __REG(PIC0_BASE_PHYS + PIC0_TMODE_OFFS)
+#define PIC0_SYNC __REG(PIC0_BASE + PIC0_SYNC_OFFS)
+#define PIC0_WKUP __REG(PIC0_BASE + PIC0_WKUP_OFFS)
+#define PIC0_TMODEA __REG(PIC0_BASE + PIC0_TMODEA_OFFS)
+#define PIC0_INTOEN __REG(PIC0_BASE + PIC0_INTOEN_OFFS)
+#define PIC0_MEN0 __REG(PIC0_BASE + PIC0_MEN0_OFFS)
+#define PIC0_MEN __REG(PIC0_BASE + PIC0_MEN_OFFS)
+
+#define PIC1_BASE (APB1_PERI_BASE_VIRT + 0x3080)
+
+#define PIC1_IEN_OFFS 0x00
+#define PIC1_CREQ_OFFS 0x04
+#define PIC1_IREQ_OFFS 0x08
+#define PIC1_IRQSEL_OFFS 0x0c
+#define PIC1_SRC_OFFS 0x10
+#define PIC1_MREQ_OFFS 0x14
+#define PIC1_TSTREQ_OFFS 0x18
+#define PIC1_POL_OFFS 0x1c
+#define PIC1_IRQ_OFFS 0x20
+#define PIC1_FIQ_OFFS 0x24
+#define PIC1_MIRQ_OFFS 0x28
+#define PIC1_MFIQ_OFFS 0x2c
+#define PIC1_TMODE_OFFS 0x30
+#define PIC1_SYNC_OFFS 0x34
+#define PIC1_WKUP_OFFS 0x38
+#define PIC1_TMODEA_OFFS 0x3c
+#define PIC1_INTOEN_OFFS 0x40
+#define PIC1_MEN1_OFFS 0x44
+#define PIC1_MEN_OFFS 0x48
+
+#define PIC1_IEN __REG(PIC1_BASE + PIC1_IEN_OFFS)
+#define PIC1_CREQ __REG(PIC1_BASE + PIC1_CREQ_OFFS)
+#define PIC1_IREQ __REG(PIC1_BASE + PIC1_IREQ_OFFS)
+#define PIC1_IRQSEL __REG(PIC1_BASE + PIC1_IRQSEL_OFFS)
+#define PIC1_SRC __REG(PIC1_BASE + PIC1_SRC_OFFS)
+#define PIC1_MREQ __REG(PIC1_BASE + PIC1_MREQ_OFFS)
+#define PIC1_TSTREQ __REG(PIC1_BASE + PIC1_TSTREQ_OFFS)
+#define PIC1_POL __REG(PIC1_BASE + PIC1_POL_OFFS)
+#define PIC1_IRQ __REG(PIC1_BASE + PIC1_IRQ_OFFS)
+#define PIC1_FIQ __REG(PIC1_BASE + PIC1_FIQ_OFFS)
+#define PIC1_MIRQ __REG(PIC1_BASE + PIC1_MIRQ_OFFS)
+#define PIC1_MFIQ __REG(PIC1_BASE + PIC1_MFIQ_OFFS)
+#define PIC1_TMODE __REG(PIC1_BASE + PIC1_TMODE_OFFS)
+#define PIC1_SYNC __REG(PIC1_BASE + PIC1_SYNC_OFFS)
+#define PIC1_WKUP __REG(PIC1_BASE + PIC1_WKUP_OFFS)
+#define PIC1_TMODEA __REG(PIC1_BASE + PIC1_TMODEA_OFFS)
+#define PIC1_INTOEN __REG(PIC1_BASE + PIC1_INTOEN_OFFS)
+#define PIC1_MEN1 __REG(PIC1_BASE + PIC1_MEN1_OFFS)
+#define PIC1_MEN __REG(PIC1_BASE + PIC1_MEN_OFFS)
+
+/* Timer registers */
+#define TIMER_BASE (APB1_PERI_BASE_VIRT + 0x4000)
+#define TIMER_BASE_PHYS (APB1_PERI_BASE + 0x4000)
+
+#define TWDCFG_OFFS 0x70
+
+#define TC32EN_OFFS 0x80
+#define TC32LDV_OFFS 0x84
+#define TC32CMP0_OFFS 0x88
+#define TC32CMP1_OFFS 0x8c
+#define TC32PCNT_OFFS 0x90
+#define TC32MCNT_OFFS 0x94
+#define TC32IRQ_OFFS 0x98
+
+/* Bits in TC32EN */
+#define TC32EN_PRESCALE_MASK 0x00ffffff
+#define TC32EN_ENABLE (1 << 24)
+#define TC32EN_LOADZERO (1 << 25)
+#define TC32EN_STOPMODE (1 << 26)
+#define TC32EN_LDM0 (1 << 28)
+#define TC32EN_LDM1 (1 << 29)
+
+/* Bits in TC32IRQ */
+#define TC32IRQ_MSTAT_MASK 0x0000001f
+#define TC32IRQ_RSTAT_MASK (0x1f << 8)
+#define TC32IRQ_IRQEN0 (1 << 16)
+#define TC32IRQ_IRQEN1 (1 << 17)
+#define TC32IRQ_IRQEN2 (1 << 18)
+#define TC32IRQ_IRQEN3 (1 << 19)
+#define TC32IRQ_IRQEN4 (1 << 20)
+#define TC32IRQ_RSYNC (1 << 30)
+#define TC32IRQ_IRQCLR (1 << 31)
+
+/* GPIO registers */
+#define GPIOPD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPD_DAT_OFFS 0x00
+#define GPIOPD_DOE_OFFS 0x04
+#define GPIOPD_FS0_OFFS 0x08
+#define GPIOPD_FS1_OFFS 0x0c
+#define GPIOPD_FS2_OFFS 0x10
+#define GPIOPD_RPU_OFFS 0x30
+#define GPIOPD_RPD_OFFS 0x34
+#define GPIOPD_DV0_OFFS 0x38
+#define GPIOPD_DV1_OFFS 0x3c
+
+#define GPIOPS_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPS_DAT_OFFS 0x40
+#define GPIOPS_DOE_OFFS 0x44
+#define GPIOPS_FS0_OFFS 0x48
+#define GPIOPS_FS1_OFFS 0x4c
+#define GPIOPS_FS2_OFFS 0x50
+#define GPIOPS_FS3_OFFS 0x54
+#define GPIOPS_RPU_OFFS 0x70
+#define GPIOPS_RPD_OFFS 0x74
+#define GPIOPS_DV0_OFFS 0x78
+#define GPIOPS_DV1_OFFS 0x7c
+
+#define GPIOPS_FS1_SDH0_BITS 0x000000ff
+#define GPIOPS_FS1_SDH1_BITS 0x0000ff00
+
+#define GPIOPU_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOPU_DAT_OFFS 0x80
+#define GPIOPU_DOE_OFFS 0x84
+#define GPIOPU_FS0_OFFS 0x88
+#define GPIOPU_FS1_OFFS 0x8c
+#define GPIOPU_FS2_OFFS 0x90
+#define GPIOPU_RPU_OFFS 0xb0
+#define GPIOPU_RPD_OFFS 0xb4
+#define GPIOPU_DV0_OFFS 0xb8
+#define GPIOPU_DV1_OFFS 0xbc
+
+#define GPIOPU_FS0_TXD0 (1 << 0)
+#define GPIOPU_FS0_RXD0 (1 << 1)
+#define GPIOPU_FS0_CTS0 (1 << 2)
+#define GPIOPU_FS0_RTS0 (1 << 3)
+#define GPIOPU_FS0_TXD1 (1 << 4)
+#define GPIOPU_FS0_RXD1 (1 << 5)
+#define GPIOPU_FS0_CTS1 (1 << 6)
+#define GPIOPU_FS0_RTS1 (1 << 7)
+#define GPIOPU_FS0_TXD2 (1 << 8)
+#define GPIOPU_FS0_RXD2 (1 << 9)
+#define GPIOPU_FS0_CTS2 (1 << 10)
+#define GPIOPU_FS0_RTS2 (1 << 11)
+#define GPIOPU_FS0_TXD3 (1 << 12)
+#define GPIOPU_FS0_RXD3 (1 << 13)
+#define GPIOPU_FS0_CTS3 (1 << 14)
+#define GPIOPU_FS0_RTS3 (1 << 15)
+#define GPIOPU_FS0_TXD4 (1 << 16)
+#define GPIOPU_FS0_RXD4 (1 << 17)
+#define GPIOPU_FS0_CTS4 (1 << 18)
+#define GPIOPU_FS0_RTS4 (1 << 19)
+
+#define GPIOFC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFC_DAT_OFFS 0xc0
+#define GPIOFC_DOE_OFFS 0xc4
+#define GPIOFC_FS0_OFFS 0xc8
+#define GPIOFC_FS1_OFFS 0xcc
+#define GPIOFC_FS2_OFFS 0xd0
+#define GPIOFC_FS3_OFFS 0xd4
+#define GPIOFC_RPU_OFFS 0xf0
+#define GPIOFC_RPD_OFFS 0xf4
+#define GPIOFC_DV0_OFFS 0xf8
+#define GPIOFC_DV1_OFFS 0xfc
+
+#define GPIOFD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOFD_DAT_OFFS 0x100
+#define GPIOFD_DOE_OFFS 0x104
+#define GPIOFD_FS0_OFFS 0x108
+#define GPIOFD_FS1_OFFS 0x10c
+#define GPIOFD_FS2_OFFS 0x110
+#define GPIOFD_RPU_OFFS 0x130
+#define GPIOFD_RPD_OFFS 0x134
+#define GPIOFD_DV0_OFFS 0x138
+#define GPIOFD_DV1_OFFS 0x13c
+
+#define GPIOLC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLC_DAT_OFFS 0x140
+#define GPIOLC_DOE_OFFS 0x144
+#define GPIOLC_FS0_OFFS 0x148
+#define GPIOLC_FS1_OFFS 0x14c
+#define GPIOLC_RPU_OFFS 0x170
+#define GPIOLC_RPD_OFFS 0x174
+#define GPIOLC_DV0_OFFS 0x178
+#define GPIOLC_DV1_OFFS 0x17c
+
+#define GPIOLD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOLD_DAT_OFFS 0x180
+#define GPIOLD_DOE_OFFS 0x184
+#define GPIOLD_FS0_OFFS 0x188
+#define GPIOLD_FS1_OFFS 0x18c
+#define GPIOLD_FS2_OFFS 0x190
+#define GPIOLD_RPU_OFFS 0x1b0
+#define GPIOLD_RPD_OFFS 0x1b4
+#define GPIOLD_DV0_OFFS 0x1b8
+#define GPIOLD_DV1_OFFS 0x1bc
+
+#define GPIOAD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOAD_DAT_OFFS 0x1c0
+#define GPIOAD_DOE_OFFS 0x1c4
+#define GPIOAD_FS0_OFFS 0x1c8
+#define GPIOAD_RPU_OFFS 0x1f0
+#define GPIOAD_RPD_OFFS 0x1f4
+#define GPIOAD_DV0_OFFS 0x1f8
+#define GPIOAD_DV1_OFFS 0x1fc
+
+#define GPIOXC_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXC_DAT_OFFS 0x200
+#define GPIOXC_DOE_OFFS 0x204
+#define GPIOXC_FS0_OFFS 0x208
+#define GPIOXC_RPU_OFFS 0x230
+#define GPIOXC_RPD_OFFS 0x234
+#define GPIOXC_DV0_OFFS 0x238
+#define GPIOXC_DV1_OFFS 0x23c
+
+#define GPIOXC_FS0 __REG(GPIOXC_BASE + GPIOXC_FS0_OFFS)
+
+#define GPIOXC_FS0_CS0 (1 << 26)
+#define GPIOXC_FS0_CS1 (1 << 27)
+
+#define GPIOXD_BASE (APB1_PERI_BASE_VIRT + 0x5000)
+
+#define GPIOXD_DAT_OFFS 0x240
+#define GPIOXD_FS0_OFFS 0x248
+#define GPIOXD_RPU_OFFS 0x270
+#define GPIOXD_RPD_OFFS 0x274
+#define GPIOXD_DV0_OFFS 0x278
+#define GPIOXD_DV1_OFFS 0x27c
+
+#define GPIOPK_BASE (APB1_PERI_BASE_VIRT + 0x1c000)
+
+#define GPIOPK_RST_OFFS 0x008
+#define GPIOPK_DAT_OFFS 0x100
+#define GPIOPK_DOE_OFFS 0x104
+#define GPIOPK_FS0_OFFS 0x108
+#define GPIOPK_FS1_OFFS 0x10c
+#define GPIOPK_FS2_OFFS 0x110
+#define GPIOPK_IRQST_OFFS 0x210
+#define GPIOPK_IRQEN_OFFS 0x214
+#define GPIOPK_IRQPOL_OFFS 0x218
+#define GPIOPK_IRQTM0_OFFS 0x21c
+#define GPIOPK_IRQTM1_OFFS 0x220
+#define GPIOPK_CTL_OFFS 0x22c
+
+#define PMGPIO_BASE (APB1_PERI_BASE_VIRT + 0x10000)
+#define BACKUP_RAM_BASE PMGPIO_BASE
+
+#define PMGPIO_DAT_OFFS 0x800
+#define PMGPIO_DOE_OFFS 0x804
+#define PMGPIO_FS0_OFFS 0x808
+#define PMGPIO_RPU_OFFS 0x810
+#define PMGPIO_RPD_OFFS 0x814
+#define PMGPIO_DV0_OFFS 0x818
+#define PMGPIO_DV1_OFFS 0x81c
+#define PMGPIO_EE0_OFFS 0x820
+#define PMGPIO_EE1_OFFS 0x824
+#define PMGPIO_CTL_OFFS 0x828
+#define PMGPIO_DI_OFFS 0x82c
+#define PMGPIO_STR_OFFS 0x830
+#define PMGPIO_STF_OFFS 0x834
+#define PMGPIO_POL_OFFS 0x838
+#define PMGPIO_APB_OFFS 0x800
+
+/* Clock controller registers */
+#define CKC_BASE ((void __iomem *)(APB1_PERI_BASE_VIRT + 0x6000))
+
+#define CLKCTRL_OFFS 0x00
+#define PLL0CFG_OFFS 0x04
+#define PLL1CFG_OFFS 0x08
+#define CLKDIVC0_OFFS 0x0c
+
+#define BCLKCTR0_OFFS 0x14
+#define SWRESET0_OFFS 0x18
+
+#define BCLKCTR1_OFFS 0x60
+#define SWRESET1_OFFS 0x64
+#define PWDCTL_OFFS 0x68
+#define PLL2CFG_OFFS 0x6c
+#define CLKDIVC1_OFFS 0x70
+
+#define ACLKREF_OFFS 0x80
+#define ACLKI2C_OFFS 0x84
+#define ACLKSPI0_OFFS 0x88
+#define ACLKSPI1_OFFS 0x8c
+#define ACLKUART0_OFFS 0x90
+#define ACLKUART1_OFFS 0x94
+#define ACLKUART2_OFFS 0x98
+#define ACLKUART3_OFFS 0x9c
+#define ACLKUART4_OFFS 0xa0
+#define ACLKTCT_OFFS 0xa4
+#define ACLKTCX_OFFS 0xa8
+#define ACLKTCZ_OFFS 0xac
+#define ACLKADC_OFFS 0xb0
+#define ACLKDAI0_OFFS 0xb4
+#define ACLKDAI1_OFFS 0xb8
+#define ACLKLCD_OFFS 0xbc
+#define ACLKSPDIF_OFFS 0xc0
+#define ACLKUSBH_OFFS 0xc4
+#define ACLKSDH0_OFFS 0xc8
+#define ACLKSDH1_OFFS 0xcc
+#define ACLKC3DEC_OFFS 0xd0
+#define ACLKEXT_OFFS 0xd4
+#define ACLKCAN0_OFFS 0xd8
+#define ACLKCAN1_OFFS 0xdc
+#define ACLKGSB0_OFFS 0xe0
+#define ACLKGSB1_OFFS 0xe4
+#define ACLKGSB2_OFFS 0xe8
+#define ACLKGSB3_OFFS 0xec
+
+#define PLLxCFG_PD (1 << 31)
+
+/* CLKCTRL bits */
+#define CLKCTRL_XE (1 << 31)
+
+/* CLKDIVCx bits */
+#define CLKDIVC0_XTE (1 << 7)
+#define CLKDIVC0_XE (1 << 15)
+#define CLKDIVC0_P1E (1 << 23)
+#define CLKDIVC0_P0E (1 << 31)
+
+#define CLKDIVC1_P2E (1 << 7)
+
+/* BCLKCTR0 clock bits */
+#define BCLKCTR0_USBD (1 << 4)
+#define BCLKCTR0_ECC (1 << 9)
+#define BCLKCTR0_USBH0 (1 << 11)
+#define BCLKCTR0_NFC (1 << 16)
+
+/* BCLKCTR1 clock bits */
+#define BCLKCTR1_USBH1 (1 << 20)
+
+/* SWRESET0 bits */
+#define SWRESET0_USBD (1 << 4)
+#define SWRESET0_USBH0 (1 << 11)
+
+/* SWRESET1 bits */
+#define SWRESET1_USBH1 (1 << 20)
+
+/* System clock sources.
+ * Note: These are the clock sources that serve as parents for
+ * all other clocks. They have no parents themselves.
+ *
+ * These values are used for struct clk->root_id. All clocks
+ * that are not system clock sources have this value set to
+ * CLK_SRC_NOROOT.
+ * The values for system clocks start with CLK_SRC_PLL0 == 0
+ * because this gives us exactly the values needed for the lower
+ * 4 bits of ACLK_* registers. Therefore, CLK_SRC_NOROOT is
+ * defined as -1 to not disturb the order.
+ */
+enum root_clks {
+ CLK_SRC_NOROOT = -1,
+ CLK_SRC_PLL0 = 0,
+ CLK_SRC_PLL1,
+ CLK_SRC_PLL0DIV,
+ CLK_SRC_PLL1DIV,
+ CLK_SRC_XI,
+ CLK_SRC_XIDIV,
+ CLK_SRC_XTI,
+ CLK_SRC_XTIDIV,
+ CLK_SRC_PLL2,
+ CLK_SRC_PLL2DIV,
+ CLK_SRC_PK0,
+ CLK_SRC_PK1,
+ CLK_SRC_PK2,
+ CLK_SRC_PK3,
+ CLK_SRC_PK4,
+ CLK_SRC_48MHZ
+};
+
+#define CLK_SRC_MASK 0xf
+
+/* Bits in ACLK* registers */
+#define ACLK_EN (1 << 28)
+#define ACLK_SEL_SHIFT 24
+#define ACLK_SEL_MASK 0x0f000000
+#define ACLK_DIV_MASK 0x00000fff
+
+/* System configuration registers */
+
+#define SCFG_BASE (APB1_PERI_BASE_VIRT + 0x13000)
+
+#define BMI_OFFS 0x00
+#define AHBCON0_OFFS 0x04
+#define APBPWE_OFFS 0x08
+#define DTCMWAIT_OFFS 0x0c
+#define ECCSEL_OFFS 0x10
+#define AHBCON1_OFFS 0x14
+#define SDHCFG_OFFS 0x18
+#define REMAP_OFFS 0x20
+#define LCDSIAE_OFFS 0x24
+#define XMCCFG_OFFS 0xe0
+#define IMCCFG_OFFS 0xe4
+
+/* Values for ECCSEL */
+#define ECCSEL_EXTMEM 0x0
+#define ECCSEL_DTCM 0x1
+#define ECCSEL_INT_SRAM 0x2
+#define ECCSEL_AHB 0x3
+
+/* Bits in XMCCFG */
+#define XMCCFG_NFCE (1 << 1)
+#define XMCCFG_FDXD (1 << 2)
+
+/* External memory controller registers */
+
+#define EMC_BASE EXT_MEM_CTRL_BASE
+
+#define SDCFG_OFFS 0x00
+#define SDFSM_OFFS 0x04
+#define MCFG_OFFS 0x08
+
+#define CSCFG0_OFFS 0x10
+#define CSCFG1_OFFS 0x14
+#define CSCFG2_OFFS 0x18
+#define CSCFG3_OFFS 0x1c
+
+#define MCFG_SDEN (1 << 4)
+
+#endif /* TCC8K_REGS_H */
diff --git a/arch/arm/plat-tcc/include/mach/timex.h b/arch/arm/plat-tcc/include/mach/timex.h
new file mode 100644
index 00000000..057acbe6
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/timex.h
@@ -0,0 +1,5 @@
+/*
+ * A definition needed by arch core code.
+ *
+ */
+#define CLOCK_TICK_RATE (HZ * 100000UL)
diff --git a/arch/arm/plat-tcc/include/mach/uncompress.h b/arch/arm/plat-tcc/include/mach/uncompress.h
new file mode 100644
index 00000000..7a3e33a2
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/uncompress.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Hans J. Koch <hjk@linutronix.de>
+ *
+ * This file is licensed under the terms of the GPL version 2.
+ */
+
+#include <linux/serial_reg.h>
+#include <linux/types.h>
+
+#include <mach/tcc8k-regs.h>
+
+unsigned int system_rev;
+
+#define ID_MASK 0x7fff
+
+static void putc(int c)
+{
+ u32 *uart_lsr = (u32 *)(UART_BASE_PHYS + (UART_LSR << 2));
+ u32 *uart_tx = (u32 *)(UART_BASE_PHYS + (UART_TX << 2));
+
+ while (!(*uart_lsr & UART_LSR_THRE))
+ barrier();
+ *uart_tx = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/plat-tcc/include/mach/vmalloc.h b/arch/arm/plat-tcc/include/mach/vmalloc.h
new file mode 100644
index 00000000..99414d9c
--- /dev/null
+++ b/arch/arm/plat-tcc/include/mach/vmalloc.h
@@ -0,0 +1,10 @@
+/*
+ * Author: <linux@telechips.com>
+ * Created: June 10, 2008
+ *
+ * Copyright (C) 2000 Russell King.
+ * Copyright (C) 2008-2009 Telechips
+ *
+ * Licensed under the terms of the GPL v2.
+ */
+#define VMALLOC_END 0xf0000000UL
diff --git a/arch/arm/plat-tcc/system.c b/arch/arm/plat-tcc/system.c
new file mode 100644
index 00000000..cc208fae
--- /dev/null
+++ b/arch/arm/plat-tcc/system.c
@@ -0,0 +1,25 @@
+/*
+ * System functions for Telechips TCCxxxx SoCs
+ *
+ * Copyright (C) Hans J. Koch <hjk@linutronix.de>
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#include <linux/io.h>
+
+#include <mach/tcc8k-regs.h>
+
+/* System reboot */
+void plat_tcc_reboot(void)
+{
+ /* Make sure clocks are on */
+ __raw_writel(0xffffffff, CKC_BASE + BCLKCTR0_OFFS);
+
+ /* Enable watchdog reset */
+ __raw_writel(0x49, TIMER_BASE + TWDCFG_OFFS);
+ /* Wait for reset */
+ while(1)
+ ;
+}
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig
new file mode 100644
index 00000000..52353beb
--- /dev/null
+++ b/arch/arm/plat-versatile/Kconfig
@@ -0,0 +1,17 @@
+if PLAT_VERSATILE
+
+config PLAT_VERSATILE_CLCD
+ bool
+
+config PLAT_VERSATILE_FPGA_IRQ
+ bool
+
+config PLAT_VERSATILE_LEDS
+ def_bool y if LEDS_CLASS
+ depends on ARCH_REALVIEW || ARCH_VERSATILE
+
+config PLAT_VERSATILE_SCHED_CLOCK
+ def_bool y if !ARCH_INTEGRATOR_AP
+ select HAVE_SCHED_CLOCK
+
+endif
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
new file mode 100644
index 00000000..69714db4
--- /dev/null
+++ b/arch/arm/plat-versatile/Makefile
@@ -0,0 +1,7 @@
+obj-y := clock.o
+obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
+obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
+obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
+obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o
+obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/plat-versatile/clcd.c b/arch/arm/plat-versatile/clcd.c
new file mode 100644
index 00000000..6628cc27
--- /dev/null
+++ b/arch/arm/plat-versatile/clcd.c
@@ -0,0 +1,182 @@
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <plat/clcd.h>
+
+static struct clcd_panel vga = {
+ .mode = {
+ .name = "VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 40,
+ .right_margin = 24,
+ .upper_margin = 32,
+ .lower_margin = 11,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+ .bpp = 16,
+};
+
+static struct clcd_panel xvga = {
+ .mode = {
+ .name = "XVGA",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = 15748,
+ .left_margin = 152,
+ .right_margin = 48,
+ .upper_margin = 23,
+ .lower_margin = 3,
+ .hsync_len = 104,
+ .vsync_len = 4,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551 | CLCD_CAP_565 | CLCD_CAP_888,
+ .bpp = 16,
+};
+
+/* Sanyo TM38QV67A02A - 3.8 inch QVGA (320x240) Color TFT */
+static struct clcd_panel sanyo_tm38qv67a02a = {
+ .mode = {
+ .name = "Sanyo TM38QV67A02A",
+ .refresh = 116,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = 100000,
+ .left_margin = 6,
+ .right_margin = 6,
+ .upper_margin = 5,
+ .lower_margin = 5,
+ .hsync_len = 6,
+ .vsync_len = 6,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .bpp = 16,
+};
+
+static struct clcd_panel sanyo_2_5_in = {
+ .mode = {
+ .name = "Sanyo QVGA Portrait",
+ .refresh = 116,
+ .xres = 240,
+ .yres = 320,
+ .pixclock = 100000,
+ .left_margin = 20,
+ .right_margin = 10,
+ .upper_margin = 2,
+ .lower_margin = 2,
+ .hsync_len = 10,
+ .vsync_len = 2,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .bpp = 16,
+};
+
+/* Epson L2F50113T00 - 2.2 inch 176x220 Color TFT */
+static struct clcd_panel epson_l2f50113t00 = {
+ .mode = {
+ .name = "Epson L2F50113T00",
+ .refresh = 390,
+ .xres = 176,
+ .yres = 220,
+ .pixclock = 62500,
+ .left_margin = 3,
+ .right_margin = 2,
+ .upper_margin = 1,
+ .lower_margin = 0,
+ .hsync_len = 3,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ },
+ .width = -1,
+ .height = -1,
+ .tim2 = TIM2_BCD | TIM2_IPC,
+ .cntl = CNTL_LCDTFT | CNTL_BGR | CNTL_LCDVCOMP(1),
+ .caps = CLCD_CAP_5551,
+ .bpp = 16,
+};
+
+static struct clcd_panel *panels[] = {
+ &vga,
+ &xvga,
+ &sanyo_tm38qv67a02a,
+ &sanyo_2_5_in,
+ &epson_l2f50113t00,
+};
+
+struct clcd_panel *versatile_clcd_get_panel(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(panels); i++)
+ if (strcmp(panels[i]->mode.name, name) == 0)
+ break;
+
+ if (i < ARRAY_SIZE(panels))
+ return panels[i];
+
+ pr_err("CLCD: couldn't get parameters for panel %s\n", name);
+
+ return NULL;
+}
+
+int versatile_clcd_setup_dma(struct clcd_fb *fb, unsigned long framesize)
+{
+ dma_addr_t dma;
+
+ fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,
+ &dma, GFP_KERNEL);
+ if (!fb->fb.screen_base) {
+ pr_err("CLCD: unable to map framebuffer\n");
+ return -ENOMEM;
+ }
+
+ fb->fb.fix.smem_start = dma;
+ fb->fb.fix.smem_len = framesize;
+
+ return 0;
+}
+
+int versatile_clcd_mmap_dma(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+ return dma_mmap_writecombine(&fb->dev->dev, vma,
+ fb->fb.screen_base,
+ fb->fb.fix.smem_start,
+ fb->fb.fix.smem_len);
+}
+
+void versatile_clcd_remove_dma(struct clcd_fb *fb)
+{
+ dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
+ fb->fb.screen_base, fb->fb.fix.smem_start);
+}
diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c
new file mode 100644
index 00000000..5c8b6564
--- /dev/null
+++ b/arch/arm/plat-versatile/clock.c
@@ -0,0 +1,74 @@
+/*
+ * linux/arch/arm/plat-versatile/clock.c
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can 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/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/hardware/icst.h>
+
+#include <mach/clkdev.h>
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ long ret = -EIO;
+ if (clk->ops && clk->ops->round)
+ ret = clk->ops->round(clk, rate);
+ return ret;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EIO;
+ if (clk->ops && clk->ops->set)
+ ret = clk->ops->set(clk, rate);
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+long icst_clk_round(struct clk *clk, unsigned long rate)
+{
+ struct icst_vco vco;
+ vco = icst_hz_to_vco(clk->params, rate);
+ return icst_hz(clk->params, vco);
+}
+EXPORT_SYMBOL(icst_clk_round);
+
+int icst_clk_set(struct clk *clk, unsigned long rate)
+{
+ struct icst_vco vco;
+
+ vco = icst_hz_to_vco(clk->params, rate);
+ clk->rate = icst_hz(clk->params, vco);
+ clk->ops->setvco(clk, vco);
+
+ return 0;
+}
+EXPORT_SYMBOL(icst_clk_set);
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c
new file mode 100644
index 00000000..f0cc8e19
--- /dev/null
+++ b/arch/arm/plat-versatile/fpga-irq.c
@@ -0,0 +1,72 @@
+/*
+ * Support for Versatile FPGA-based IRQ controllers
+ */
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+#include <plat/fpga-irq.h>
+
+#define IRQ_STATUS 0x00
+#define IRQ_RAW_STATUS 0x04
+#define IRQ_ENABLE_SET 0x08
+#define IRQ_ENABLE_CLEAR 0x0c
+
+static void fpga_irq_mask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << (d->irq - f->irq_start);
+
+ writel(mask, f->base + IRQ_ENABLE_CLEAR);
+}
+
+static void fpga_irq_unmask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << (d->irq - f->irq_start);
+
+ writel(mask, f->base + IRQ_ENABLE_SET);
+}
+
+static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+ struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
+ u32 status = readl(f->base + IRQ_STATUS);
+
+ if (status == 0) {
+ do_bad_IRQ(irq, desc);
+ return;
+ }
+
+ do {
+ irq = ffs(status) - 1;
+ status &= ~(1 << irq);
+
+ generic_handle_irq(irq + f->irq_start);
+ } while (status);
+}
+
+void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
+{
+ unsigned int i;
+
+ f->chip.irq_ack = fpga_irq_mask;
+ f->chip.irq_mask = fpga_irq_mask;
+ f->chip.irq_unmask = fpga_irq_unmask;
+
+ if (parent_irq != -1) {
+ irq_set_handler_data(parent_irq, f);
+ irq_set_chained_handler(parent_irq, fpga_irq_handle);
+ }
+
+ for (i = 0; i < 32; i++) {
+ if (valid & (1 << i)) {
+ unsigned int irq = f->irq_start + i;
+
+ irq_set_chip_data(irq, f);
+ irq_set_chip_and_handler(irq, &f->chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ }
+}
diff --git a/arch/arm/plat-versatile/headsmp.S b/arch/arm/plat-versatile/headsmp.S
new file mode 100644
index 00000000..d397a1fb
--- /dev/null
+++ b/arch/arm/plat-versatile/headsmp.S
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/plat-versatile/headsmp.S
+ *
+ * Copyright (c) 2003 ARM Limited
+ * 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/linkage.h>
+#include <linux/init.h>
+
+ __INIT
+
+/*
+ * Realview/Versatile Express specific entry point for secondary CPUs.
+ * This provides a "holding pen" into which all secondary cores are held
+ * until we're ready for them to initialise.
+ */
+ENTRY(versatile_secondary_startup)
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ adr r4, 1f
+ ldmia r4, {r5, r6}
+ sub r4, r4, r5
+ add r6, r6, r4
+pen: ldr r7, [r6]
+ cmp r7, r0
+ bne pen
+
+ /*
+ * we've been released from the holding pen: secondary_stack
+ * should now contain the SVC stack for this core
+ */
+ b secondary_startup
+
+ .align
+1: .long .
+ .long pen_release
diff --git a/arch/arm/plat-versatile/include/plat/clcd.h b/arch/arm/plat-versatile/include/plat/clcd.h
new file mode 100644
index 00000000..6bb6a1d2
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/clcd.h
@@ -0,0 +1,9 @@
+#ifndef PLAT_CLCD_H
+#define PLAT_CLCD_H
+
+struct clcd_panel *versatile_clcd_get_panel(const char *);
+int versatile_clcd_setup_dma(struct clcd_fb *, unsigned long);
+int versatile_clcd_mmap_dma(struct clcd_fb *, struct vm_area_struct *);
+void versatile_clcd_remove_dma(struct clcd_fb *);
+
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/clock.h b/arch/arm/plat-versatile/include/plat/clock.h
new file mode 100644
index 00000000..3cfb024c
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/clock.h
@@ -0,0 +1,15 @@
+#ifndef PLAT_CLOCK_H
+#define PLAT_CLOCK_H
+
+#include <asm/hardware/icst.h>
+
+struct clk_ops {
+ long (*round)(struct clk *, unsigned long);
+ int (*set)(struct clk *, unsigned long);
+ void (*setvco)(struct clk *, struct icst_vco);
+};
+
+int icst_clk_set(struct clk *, unsigned long);
+long icst_clk_round(struct clk *, unsigned long);
+
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h
new file mode 100644
index 00000000..627fafd1
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h
@@ -0,0 +1,12 @@
+#ifndef PLAT_FPGA_IRQ_H
+#define PLAT_FPGA_IRQ_H
+
+struct fpga_irq_data {
+ void __iomem *base;
+ unsigned int irq_start;
+ struct irq_chip chip;
+};
+
+void fpga_irq_init(int, u32, struct fpga_irq_data *);
+
+#endif
diff --git a/arch/arm/plat-versatile/include/plat/sched_clock.h b/arch/arm/plat-versatile/include/plat/sched_clock.h
new file mode 100644
index 00000000..5c3e4fc9
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/sched_clock.h
@@ -0,0 +1,6 @@
+#ifndef ARM_PLAT_SCHED_CLOCK_H
+#define ARM_PLAT_SCHED_CLOCK_H
+
+void versatile_sched_clock_init(void __iomem *, unsigned long);
+
+#endif
diff --git a/arch/arm/plat-versatile/leds.c b/arch/arm/plat-versatile/leds.c
new file mode 100644
index 00000000..3169fa55
--- /dev/null
+++ b/arch/arm/plat-versatile/leds.c
@@ -0,0 +1,103 @@
+/*
+ * Driver for the 8 user LEDs found on the RealViews and Versatiles
+ * Based on DaVinci's DM365 board code
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ * Author: Linus Walleij <triad@df.lth.se>
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+
+#include <mach/hardware.h>
+#include <mach/platform.h>
+
+#ifdef VERSATILE_SYS_BASE
+#define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
+#endif
+
+#ifdef REALVIEW_SYS_BASE
+#define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET)
+#endif
+
+struct versatile_led {
+ struct led_classdev cdev;
+ u8 mask;
+};
+
+/*
+ * The triggers lines up below will only be used if the
+ * LED triggers are compiled in.
+ */
+static const struct {
+ const char *name;
+ const char *trigger;
+} versatile_leds[] = {
+ { "versatile:0", "heartbeat", },
+ { "versatile:1", "mmc0", },
+ { "versatile:2", },
+ { "versatile:3", },
+ { "versatile:4", },
+ { "versatile:5", },
+ { "versatile:6", },
+ { "versatile:7", },
+};
+
+static void versatile_led_set(struct led_classdev *cdev,
+ enum led_brightness b)
+{
+ struct versatile_led *led = container_of(cdev,
+ struct versatile_led, cdev);
+ u32 reg = readl(LEDREG);
+
+ if (b != LED_OFF)
+ reg |= led->mask;
+ else
+ reg &= ~led->mask;
+ writel(reg, LEDREG);
+}
+
+static enum led_brightness versatile_led_get(struct led_classdev *cdev)
+{
+ struct versatile_led *led = container_of(cdev,
+ struct versatile_led, cdev);
+ u32 reg = readl(LEDREG);
+
+ return (reg & led->mask) ? LED_FULL : LED_OFF;
+}
+
+static int __init versatile_leds_init(void)
+{
+ int i;
+
+ /* All ON */
+ writel(0xff, LEDREG);
+ for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) {
+ struct versatile_led *led;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ break;
+
+ led->cdev.name = versatile_leds[i].name;
+ led->cdev.brightness_set = versatile_led_set;
+ led->cdev.brightness_get = versatile_led_get;
+ led->cdev.default_trigger = versatile_leds[i].trigger;
+ led->mask = BIT(i);
+
+ if (led_classdev_register(NULL, &led->cdev) < 0) {
+ kfree(led);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Since we may have triggers on any subsystem, defer registration
+ * until after subsystem_init.
+ */
+fs_initcall(versatile_leds_init);
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
new file mode 100644
index 00000000..0fb39619
--- /dev/null
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/plat-versatile/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/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+#include <mach/irqs.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/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
new file mode 100644
index 00000000..51ecfea0
--- /dev/null
+++ b/arch/arm/plat-versatile/platsmp.c
@@ -0,0 +1,105 @@
+/*
+ * linux/arch/arm/plat-versatile/platsmp.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/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * 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);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ write_pen_release(-1);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * This is really belt and braces; we hold unintended secondary
+ * CPUs in the holding pen until we're ready for them. However,
+ * since we haven't sent them a soft interrupt, they shouldn't
+ * be there.
+ */
+ write_pen_release(cpu);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * 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();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return pen_release != -1 ? -ENOSYS : 0;
+}
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
new file mode 100644
index 00000000..3d6a4c29
--- /dev/null
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -0,0 +1,58 @@
+/*
+ * linux/arch/arm/plat-versatile/sched-clock.c
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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/io.h>
+#include <linux/sched.h>
+
+#include <asm/sched_clock.h>
+#include <plat/sched_clock.h>
+
+static DEFINE_CLOCK_DATA(cd);
+static void __iomem *ctr;
+
+/*
+ * Constants generated by clocks_calc_mult_shift(m, s, 24MHz, NSEC_PER_SEC, 60).
+ * This gives a resolution of about 41ns and a wrap period of about 178s.
+ */
+#define SC_MULT 2796202667u
+#define SC_SHIFT 26
+
+unsigned long long notrace sched_clock(void)
+{
+ if (ctr) {
+ u32 cyc = readl(ctr);
+ return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0,
+ SC_MULT, SC_SHIFT);
+ } else
+ return 0;
+}
+
+static void notrace versatile_update_sched_clock(void)
+{
+ u32 cyc = readl(ctr);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
+{
+ ctr = reg;
+ init_fixed_sched_clock(&cd, versatile_update_sched_clock,
+ 32, rate, SC_MULT, SC_SHIFT);
+}
diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile
new file mode 100644
index 00000000..635cb186
--- /dev/null
+++ b/arch/arm/tools/Makefile
@@ -0,0 +1,10 @@
+#
+# linux/arch/arm/tools/Makefile
+#
+# Copyright (C) 2001 Russell King
+#
+
+include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
+ @echo ' Generating $@'
+ @mkdir -p $(dir $@)
+ $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }
diff --git a/arch/arm/tools/gen-mach-types b/arch/arm/tools/gen-mach-types
new file mode 100644
index 00000000..04fef71d
--- /dev/null
+++ b/arch/arm/tools/gen-mach-types
@@ -0,0 +1,72 @@
+#!/bin/awk
+#
+# Awk script to generate include/generated/mach-types.h
+#
+BEGIN { nr = 0 }
+/^#/ { next }
+/^[ ]*$/ { next }
+
+NF == 4 {
+ machine_is[nr] = "machine_is_"$1;
+ config[nr] = "CONFIG_"$2;
+ mach_type[nr] = "MACH_TYPE_"$3;
+ num[nr] = $4; nr++
+ }
+
+NF == 3 {
+ machine_is[nr] = "machine_is_"$1;
+ config[nr] = "CONFIG_"$2;
+ mach_type[nr] = "MACH_TYPE_"$3;
+ num[nr] = ""; nr++
+ }
+
+
+END {
+ printf("/*\n");
+ printf(" * This was automagically generated from %s!\n", FILENAME);
+ printf(" * Do NOT edit\n");
+ printf(" */\n\n");
+ printf("#ifndef __ASM_ARM_MACH_TYPE_H\n");
+ printf("#define __ASM_ARM_MACH_TYPE_H\n\n");
+ printf("#ifndef __ASSEMBLY__\n");
+ printf("/* The type of machine we're running on */\n");
+ printf("extern unsigned int __machine_arch_type;\n");
+ printf("#endif\n\n");
+
+ printf("/* see arch/arm/kernel/arch.c for a description of these */\n");
+ for (i = 0; i < nr; i++)
+ if (num[i] ~ /..*/)
+ printf("#define %-30s %d\n", mach_type[i], num[i]);
+
+ printf("\n");
+
+ for (i = 0; i < nr; i++)
+ if (num[i] ~ /..*/) {
+ printf("#ifdef %s\n", config[i]);
+ printf("# ifdef machine_arch_type\n");
+ printf("# undef machine_arch_type\n");
+ printf("# define machine_arch_type\t__machine_arch_type\n");
+ printf("# else\n");
+ printf("# define machine_arch_type\t%s\n", mach_type[i]);
+ printf("# endif\n");
+ printf("# define %s()\t(machine_arch_type == %s)\n", machine_is[i], mach_type[i]);
+ printf("#else\n");
+ printf("# define %s()\t(0)\n", machine_is[i]);
+ printf("#endif\n\n");
+ }
+
+ printf("/*\n * These have not yet been registered\n */\n");
+ for (i = 0; i < nr; i++)
+ if (num[i] !~ /..*/)
+ printf("/* #define %-30s <<not registered>> */\n", mach_type[i]);
+
+ for (i = 0; i < nr; i++)
+ if (num[i] !~ /..*/) {
+ printf("#define %s()\t(0)\n", machine_is[i]);
+ }
+
+ printf("\n#ifndef machine_arch_type\n");
+ printf("#define machine_arch_type\t__machine_arch_type\n");
+ printf("#endif\n\n");
+ printf("#endif\n");
+ }
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
new file mode 100644
index 00000000..c42b2bd4
--- /dev/null
+++ b/arch/arm/tools/mach-types
@@ -0,0 +1,1124 @@
+# Database of machine macros and numbers
+#
+# This file is linux/arch/arm/tools/mach-types
+#
+# Up to date versions of this file can be obtained from:
+#
+# http://www.arm.linux.org.uk/developer/machines/download.php
+#
+# Please do not send patches to this file; it is automatically generated!
+# To add an entry into this database, please see Documentation/arm/README,
+# or visit:
+#
+# http://www.arm.linux.org.uk/developer/machines/?action=new
+#
+# XXX: This is a cut-down version of the file; it contains only machines that
+# XXX: are in mainline or have been submitted to the machine database within
+# XXX: the last 12 months. If your entry is missing please email rmk at
+# XXX: <linux@arm.linux.org.uk>
+#
+# Last update: Sat May 7 08:48:24 2011
+#
+# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
+#
+ebsa110 ARCH_EBSA110 EBSA110 0
+riscpc ARCH_RPC RISCPC 1
+ebsa285 ARCH_EBSA285 EBSA285 4
+netwinder ARCH_NETWINDER NETWINDER 5
+cats ARCH_CATS CATS 6
+shark ARCH_SHARK SHARK 15
+brutus SA1100_BRUTUS BRUTUS 16
+personal_server ARCH_PERSONAL_SERVER PERSONAL_SERVER 17
+l7200 ARCH_L7200 L7200 19
+pleb SA1100_PLEB PLEB 20
+integrator ARCH_INTEGRATOR INTEGRATOR 21
+h3600 SA1100_H3600 H3600 22
+p720t ARCH_P720T P720T 24
+assabet SA1100_ASSABET ASSABET 25
+lart SA1100_LART LART 27
+graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29
+xp860 SA1100_XP860 XP860 30
+cerf SA1100_CERF CERF 31
+nanoengine SA1100_NANOENGINE NANOENGINE 32
+jornada720 SA1100_JORNADA720 JORNADA720 48
+edb7211 ARCH_EDB7211 EDB7211 50
+pfs168 SA1100_PFS168 PFS168 52
+flexanet SA1100_FLEXANET FLEXANET 54
+simpad SA1100_SIMPAD SIMPAD 87
+lubbock ARCH_LUBBOCK LUBBOCK 89
+clep7212 ARCH_CLEP7212 CLEP7212 91
+shannon SA1100_SHANNON SHANNON 97
+consus SA1100_CONSUS CONSUS 105
+aaed2000 ARCH_AAED2000 AAED2000 106
+cdb89712 ARCH_CDB89712 CDB89712 107
+graphicsmaster SA1100_GRAPHICSMASTER GRAPHICSMASTER 108
+adsbitsy SA1100_ADSBITSY ADSBITSY 109
+pxa_idp ARCH_PXA_IDP PXA_IDP 110
+pt_system3 SA1100_PT_SYSTEM3 PT_SYSTEM3 112
+autcpu12 ARCH_AUTCPU12 AUTCPU12 118
+h3100 SA1100_H3100 H3100 136
+collie SA1100_COLLIE COLLIE 146
+badge4 SA1100_BADGE4 BADGE4 148
+fortunet ARCH_FORTUNET FORTUNET 152
+mx1ads ARCH_MX1ADS MX1ADS 160
+h7201 ARCH_H7201 H7201 161
+h7202 ARCH_H7202 H7202 162
+iq80321 ARCH_IQ80321 IQ80321 169
+ks8695 ARCH_KS8695 KS8695 180
+smdk2410 ARCH_SMDK2410 SMDK2410 193
+ceiva ARCH_CEIVA CEIVA 200
+voiceblue MACH_VOICEBLUE VOICEBLUE 218
+h5400 ARCH_H5400 H5400 220
+omap_innovator MACH_OMAP_INNOVATOR OMAP_INNOVATOR 234
+ixdp2400 ARCH_IXDP2400 IXDP2400 242
+ixdp2800 ARCH_IXDP2800 IXDP2800 243
+ixdp425 ARCH_IXDP425 IXDP425 245
+hackkit SA1100_HACKKIT HACKKIT 254
+ixcdp1100 ARCH_IXCDP1100 IXCDP1100 260
+at91rm9200dk ARCH_AT91RM9200DK AT91RM9200DK 262
+cintegrator ARCH_CINTEGRATOR CINTEGRATOR 275
+viper ARCH_VIPER VIPER 283
+adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290
+ixdp2401 ARCH_IXDP2401 IXDP2401 299
+ixdp2801 ARCH_IXDP2801 IXDP2801 300
+iq31244 ARCH_IQ31244 IQ31244 327
+bast ARCH_BAST BAST 331
+h1940 ARCH_H1940 H1940 347
+enp2611 ARCH_ENP2611 ENP2611 356
+s3c2440 ARCH_S3C2440 S3C2440 362
+gumstix ARCH_GUMSTIX GUMSTIX 373
+omap_h2 MACH_OMAP_H2 OMAP_H2 382
+e740 MACH_E740 E740 384
+iq80331 ARCH_IQ80331 IQ80331 385
+versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387
+kev7a400 MACH_KEV7A400 KEV7A400 388
+lpd7a400 MACH_LPD7A400 LPD7A400 389
+lpd7a404 MACH_LPD7A404 LPD7A404 390
+csb337 MACH_CSB337 CSB337 399
+mainstone MACH_MAINSTONE MAINSTONE 406
+xcep MACH_XCEP XCEP 413
+arcom_vulcan MACH_ARCOM_VULCAN ARCOM_VULCAN 414
+nomadik MACH_NOMADIK NOMADIK 420
+corgi MACH_CORGI CORGI 423
+poodle MACH_POODLE POODLE 424
+armcore MACH_ARMCORE ARMCORE 438
+mx31ads MACH_MX31ADS MX31ADS 447
+himalaya MACH_HIMALAYA HIMALAYA 448
+edb9312 MACH_EDB9312 EDB9312 451
+omap_generic MACH_OMAP_GENERIC OMAP_GENERIC 452
+edb9301 MACH_EDB9301 EDB9301 462
+edb9315 MACH_EDB9315 EDB9315 463
+vr1000 MACH_VR1000 VR1000 475
+omap_perseus2 MACH_OMAP_PERSEUS2 OMAP_PERSEUS2 491
+e800 MACH_E800 E800 496
+e750 MACH_E750 E750 497
+scb9328 MACH_SCB9328 SCB9328 508
+omap_h3 MACH_OMAP_H3 OMAP_H3 509
+omap_h4 MACH_OMAP_H4 OMAP_H4 510
+omap_osk MACH_OMAP_OSK OMAP_OSK 515
+tosa MACH_TOSA TOSA 520
+avila MACH_AVILA AVILA 526
+edb9302 MACH_EDB9302 EDB9302 538
+husky MACH_HUSKY HUSKY 543
+shepherd MACH_SHEPHERD SHEPHERD 545
+h4700 MACH_H4700 H4700 562
+rx3715 MACH_RX3715 RX3715 592
+nslu2 MACH_NSLU2 NSLU2 597
+e400 MACH_E400 E400 598
+ixdpg425 MACH_IXDPG425 IXDPG425 604
+versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606
+edb9307 MACH_EDB9307 EDB9307 607
+kb9200 MACH_KB9200 KB9200 612
+sx1 MACH_SX1 SX1 613
+ixdp465 MACH_IXDP465 IXDP465 618
+ixdp2351 MACH_IXDP2351 IXDP2351 619
+iq80332 MACH_IQ80332 IQ80332 629
+gtwx5715 MACH_GTWX5715 GTWX5715 641
+csb637 MACH_CSB637 CSB637 648
+n30 MACH_N30 N30 656
+nec_mp900 MACH_NEC_MP900 NEC_MP900 659
+kafa MACH_KAFA KAFA 662
+ts72xx MACH_TS72XX TS72XX 673
+otom MACH_OTOM OTOM 680
+nexcoder_2440 MACH_NEXCODER_2440 NEXCODER_2440 681
+eco920 MACH_ECO920 ECO920 702
+roadrunner MACH_ROADRUNNER ROADRUNNER 704
+at91rm9200ek MACH_AT91RM9200EK AT91RM9200EK 705
+spitz MACH_SPITZ SPITZ 713
+adssphere MACH_ADSSPHERE ADSSPHERE 723
+colibri MACH_COLIBRI COLIBRI 729
+gateway7001 MACH_GATEWAY7001 GATEWAY7001 731
+pcm027 MACH_PCM027 PCM027 732
+anubis MACH_ANUBIS ANUBIS 734
+akita MACH_AKITA AKITA 744
+e330 MACH_E330 E330 753
+nokia770 MACH_NOKIA770 NOKIA770 755
+carmeva MACH_CARMEVA CARMEVA 769
+edb9315a MACH_EDB9315A EDB9315A 772
+stargate2 MACH_STARGATE2 STARGATE2 774
+intelmote2 MACH_INTELMOTE2 INTELMOTE2 775
+trizeps4 MACH_TRIZEPS4 TRIZEPS4 776
+pnx4008 MACH_PNX4008 PNX4008 782
+cpuat91 MACH_CPUAT91 CPUAT91 787
+iq81340sc MACH_IQ81340SC IQ81340SC 799
+iq81340mc MACH_IQ81340MC IQ81340MC 801
+micro9 MACH_MICRO9 MICRO9 811
+micro9l MACH_MICRO9L MICRO9L 812
+omap_palmte MACH_OMAP_PALMTE OMAP_PALMTE 817
+realview_eb MACH_REALVIEW_EB REALVIEW_EB 827
+borzoi MACH_BORZOI BORZOI 831
+palmld MACH_PALMLD PALMLD 835
+ixdp28x5 MACH_IXDP28X5 IXDP28X5 838
+omap_palmtt MACH_OMAP_PALMTT OMAP_PALMTT 839
+arcom_zeus MACH_ARCOM_ZEUS ARCOM_ZEUS 841
+osiris MACH_OSIRIS OSIRIS 842
+palmte2 MACH_PALMTE2 PALMTE2 844
+mx27ads MACH_MX27ADS MX27ADS 846
+at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848
+loft MACH_LOFT LOFT 849
+mx21ads MACH_MX21ADS MX21ADS 851
+ams_delta MACH_AMS_DELTA AMS_DELTA 862
+nas100d MACH_NAS100D NAS100D 865
+magician MACH_MAGICIAN MAGICIAN 875
+nxdkn MACH_NXDKN NXDKN 880
+palmtx MACH_PALMTX PALMTX 885
+s3c2413 MACH_S3C2413 S3C2413 887
+wg302v2 MACH_WG302V2 WG302V2 890
+omap_2430sdp MACH_OMAP_2430SDP OMAP_2430SDP 900
+davinci_evm MACH_DAVINCI_EVM DAVINCI_EVM 901
+palmz72 MACH_PALMZ72 PALMZ72 904
+nxdb500 MACH_NXDB500 NXDB500 905
+palmt5 MACH_PALMT5 PALMT5 917
+palmtc MACH_PALMTC PALMTC 918
+omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919
+ateb9200 MACH_ATEB9200 ATEB9200 923
+n35 MACH_N35 N35 927
+logicpd_pxa270 MACH_LOGICPD_PXA270 LOGICPD_PXA270 930
+nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941
+espresso MACH_ESPRESSO ESPRESSO 949
+rx1950 MACH_RX1950 RX1950 952
+gesbc9312 MACH_GESBC9312 GESBC9312 958
+picotux2xx MACH_PICOTUX2XX PICOTUX2XX 963
+dsmg600 MACH_DSMG600 DSMG600 964
+omap_fsample MACH_OMAP_FSAMPLE OMAP_FSAMPLE 970
+snapper_cl15 MACH_SNAPPER_CL15 SNAPPER_CL15 986
+omap_palmz71 MACH_OMAP_PALMZ71 OMAP_PALMZ71 993
+smdk2412 MACH_SMDK2412 SMDK2412 1009
+smdk2413 MACH_SMDK2413 SMDK2413 1022
+aml_m5900 MACH_AML_M5900 AML_M5900 1024
+balloon3 MACH_BALLOON3 BALLOON3 1029
+ecbat91 MACH_ECBAT91 ECBAT91 1072
+onearm MACH_ONEARM ONEARM 1075
+smdk2443 MACH_SMDK2443 SMDK2443 1084
+fsg MACH_FSG FSG 1091
+at91sam9260ek MACH_AT91SAM9260EK AT91SAM9260EK 1099
+glantank MACH_GLANTANK GLANTANK 1100
+n2100 MACH_N2100 N2100 1101
+qt2410 MACH_QT2410 QT2410 1108
+kixrp435 MACH_KIXRP435 KIXRP435 1109
+cc9p9360dev MACH_CC9P9360DEV CC9P9360DEV 1114
+edb9302a MACH_EDB9302A EDB9302A 1127
+edb9307a MACH_EDB9307A EDB9307A 1128
+omap_3430sdp MACH_OMAP_3430SDP OMAP_3430SDP 1138
+vstms MACH_VSTMS VSTMS 1140
+micro9m MACH_MICRO9M MICRO9M 1169
+bug MACH_BUG BUG 1179
+at91sam9263ek MACH_AT91SAM9263EK AT91SAM9263EK 1202
+em7210 MACH_EM7210 EM7210 1212
+vpac270 MACH_VPAC270 VPAC270 1227
+treo680 MACH_TREO680 TREO680 1230
+zylonite MACH_ZYLONITE ZYLONITE 1233
+mx31lite MACH_MX31LITE MX31LITE 1236
+mioa701 MACH_MIOA701 MIOA701 1257
+armadillo5x0 MACH_ARMADILLO5X0 ARMADILLO5X0 1260
+cc9p9360js MACH_CC9P9360JS CC9P9360JS 1264
+smdk6400 MACH_SMDK6400 SMDK6400 1270
+nokia_n800 MACH_NOKIA_N800 NOKIA_N800 1271
+ep80219 MACH_EP80219 EP80219 1281
+goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292
+em_x270 MACH_EM_X270 EM_X270 1297
+neo1973_gta02 MACH_NEO1973_GTA02 NEO1973_GTA02 1304
+at91sam9rlek MACH_AT91SAM9RLEK AT91SAM9RLEK 1326
+colibri320 MACH_COLIBRI320 COLIBRI320 1340
+cam60 MACH_CAM60 CAM60 1351
+at91eb01 MACH_AT91EB01 AT91EB01 1354
+db88f5281 MACH_DB88F5281 DB88F5281 1358
+csb726 MACH_CSB726 CSB726 1359
+davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380
+davinci_dm355_evm MACH_DAVINCI_DM355_EVM DAVINCI_DM355_EVM 1381
+littleton MACH_LITTLETON LITTLETON 1388
+realview_pb11mp MACH_REALVIEW_PB11MP REALVIEW_PB11MP 1407
+mx27_3ds MACH_MX27_3DS MX27_3DS 1430
+halibut MACH_HALIBUT HALIBUT 1439
+trout MACH_TROUT TROUT 1440
+tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460
+herald MACH_HERALD HERALD 1461
+sim_one MACH_SIM_ONE SIM_ONE 1476
+jive MACH_JIVE JIVE 1490
+sam9_l9260 MACH_SAM9_L9260 SAM9_L9260 1501
+realview_pb1176 MACH_REALVIEW_PB1176 REALVIEW_PB1176 1504
+yl9200 MACH_YL9200 YL9200 1507
+rd88f5182 MACH_RD88F5182 RD88F5182 1508
+kurobox_pro MACH_KUROBOX_PRO KUROBOX_PRO 1509
+mx31_3ds MACH_MX31_3DS MX31_3DS 1511
+qong MACH_QONG QONG 1524
+omap2evm MACH_OMAP2EVM OMAP2EVM 1534
+omap3evm MACH_OMAP3EVM OMAP3EVM 1535
+dns323 MACH_DNS323 DNS323 1542
+omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546
+nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548
+pcm038 MACH_PCM038 PCM038 1551
+ts_x09 MACH_TS209 TS209 1565
+at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566
+mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574
+terastation_pro2 MACH_TERASTATION_PRO2 TERASTATION_PRO2 1584
+linkstation_pro MACH_LINKSTATION_PRO LINKSTATION_PRO 1585
+e350 MACH_E350 E350 1596
+ts409 MACH_TS409 TS409 1601
+cm_x300 MACH_CM_X300 CM_X300 1616
+at91sam9g20ek MACH_AT91SAM9G20EK AT91SAM9G20EK 1624
+smdk6410 MACH_SMDK6410 SMDK6410 1626
+u300 MACH_U300 U300 1627
+wrt350n_v2 MACH_WRT350N_V2 WRT350N_V2 1633
+omap_ldp MACH_OMAP_LDP OMAP_LDP 1639
+mx35_3ds MACH_MX35_3DS MX35_3DS 1645
+neuros_osd2 MACH_NEUROS_OSD2 NEUROS_OSD2 1647
+trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649
+ts78xx MACH_TS78XX TS78XX 1652
+sffsdr MACH_SFFSDR SFFSDR 1657
+pcm037 MACH_PCM037 PCM037 1673
+db88f6281_bp MACH_DB88F6281_BP DB88F6281_BP 1680
+rd88f6192_nas MACH_RD88F6192_NAS RD88F6192_NAS 1681
+rd88f6281 MACH_RD88F6281 RD88F6281 1682
+db78x00_bp MACH_DB78X00_BP DB78X00_BP 1683
+smdk2416 MACH_SMDK2416 SMDK2416 1685
+wbd111 MACH_WBD111 WBD111 1690
+mv2120 MACH_MV2120 MV2120 1693
+mx51_3ds MACH_MX51_3DS MX51_3DS 1696
+imx27lite MACH_IMX27LITE IMX27LITE 1701
+usb_a9260 MACH_USB_A9260 USB_A9260 1709
+usb_a9263 MACH_USB_A9263 USB_A9263 1710
+qil_a9260 MACH_QIL_A9260 QIL_A9260 1711
+kzm_arm11_01 MACH_KZM_ARM11_01 KZM_ARM11_01 1722
+nokia_n810_wimax MACH_NOKIA_N810_WIMAX NOKIA_N810_WIMAX 1727
+sapphire MACH_SAPPHIRE SAPPHIRE 1729
+stmp37xx MACH_STMP37XX STMP37XX 1732
+stmp378x MACH_STMP378X STMP378X 1733
+ezx_a780 MACH_EZX_A780 EZX_A780 1740
+ezx_e680 MACH_EZX_E680 EZX_E680 1741
+ezx_a1200 MACH_EZX_A1200 EZX_A1200 1742
+ezx_e6 MACH_EZX_E6 EZX_E6 1743
+ezx_e2 MACH_EZX_E2 EZX_E2 1744
+ezx_a910 MACH_EZX_A910 EZX_A910 1745
+edmini_v2 MACH_EDMINI_V2 EDMINI_V2 1756
+zipit2 MACH_ZIPIT2 ZIPIT2 1757
+omap3_pandora MACH_OMAP3_PANDORA OMAP3_PANDORA 1761
+mss2 MACH_MSS2 MSS2 1766
+lb88rc8480 MACH_LB88RC8480 LB88RC8480 1769
+mx25_3ds MACH_MX25_3DS MX25_3DS 1771
+omap3530_lv_som MACH_OMAP3530_LV_SOM OMAP3530_LV_SOM 1773
+davinci_da830_evm MACH_DAVINCI_DA830_EVM DAVINCI_DA830_EVM 1781
+at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783
+dove_db MACH_DOVE_DB DOVE_DB 1788
+overo MACH_OVERO OVERO 1798
+at2440evb MACH_AT2440EVB AT2440EVB 1799
+neocore926 MACH_NEOCORE926 NEOCORE926 1800
+wnr854t MACH_WNR854T WNR854T 1801
+rd88f5181l_ge MACH_RD88F5181L_GE RD88F5181L_GE 1812
+rd88f5181l_fxo MACH_RD88F5181L_FXO RD88F5181L_FXO 1818
+stamp9g20 MACH_STAMP9G20 STAMP9G20 1824
+smdkc100 MACH_SMDKC100 SMDKC100 1826
+tavorevb MACH_TAVOREVB TAVOREVB 1827
+saar MACH_SAAR SAAR 1828
+at91sam9m10g45ek MACH_AT91SAM9M10G45EK AT91SAM9M10G45EK 1830
+mxlads MACH_MXLADS MXLADS 1851
+linkstation_mini MACH_LINKSTATION_MINI LINKSTATION_MINI 1858
+afeb9260 MACH_AFEB9260 AFEB9260 1859
+imx27ipcam MACH_IMX27IPCAM IMX27IPCAM 1871
+rd88f6183ap_ge MACH_RD88F6183AP_GE RD88F6183AP_GE 1894
+realview_pba8 MACH_REALVIEW_PBA8 REALVIEW_PBA8 1897
+realview_pbx MACH_REALVIEW_PBX REALVIEW_PBX 1901
+micro9s MACH_MICRO9S MICRO9S 1902
+rut100 MACH_RUT100 RUT100 1908
+g3evm MACH_G3EVM G3EVM 1919
+w90p910evb MACH_W90P910EVB W90P910EVB 1921
+w90p950evb MACH_W90P950EVB W90P950EVB 1923
+w90n960evb MACH_W90N960EVB W90N960EVB 1924
+mv88f6281gtw_ge MACH_MV88F6281GTW_GE MV88F6281GTW_GE 1932
+ncp MACH_NCP NCP 1933
+davinci_dm365_evm MACH_DAVINCI_DM365_EVM DAVINCI_DM365_EVM 1939
+centro MACH_CENTRO CENTRO 1944
+nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955
+omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967
+cpuat9260 MACH_CPUAT9260 CPUAT9260 1973
+eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975
+acs5k MACH_ACS5K ACS5K 1982
+snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987
+dsm320 MACH_DSM320 DSM320 1988
+exeda MACH_EXEDA EXEDA 1994
+mini2440 MACH_MINI2440 MINI2440 1999
+colibri300 MACH_COLIBRI300 COLIBRI300 2000
+linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005
+cpuat9g20 MACH_CPUAT9G20 CPUAT9G20 2031
+smdk6440 MACH_SMDK6440 SMDK6440 2032
+nas4220b MACH_NAS4220B NAS4220B 2038
+zylonite2 MACH_ZYLONITE2 ZYLONITE2 2042
+aspenite MACH_ASPENITE ASPENITE 2043
+ttc_dkb MACH_TTC_DKB TTC_DKB 2045
+pcm043 MACH_PCM043 PCM043 2072
+sheevaplug MACH_SHEEVAPLUG SHEEVAPLUG 2097
+avengers_lite MACH_AVENGERS_LITE AVENGERS_LITE 2104
+mx51_babbage MACH_MX51_BABBAGE MX51_BABBAGE 2125
+rd78x00_masa MACH_RD78X00_MASA RD78X00_MASA 2135
+dm355_leopard MACH_DM355_LEOPARD DM355_LEOPARD 2138
+ts219 MACH_TS219 TS219 2139
+pca100 MACH_PCA100 PCA100 2149
+davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157
+at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159
+omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160
+magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162
+btmavb101 MACH_BTMAVB101 BTMAVB101 2172
+btmawb101 MACH_BTMAWB101 BTMAWB101 2173
+omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178
+anw6410 MACH_ANW6410 ANW6410 2183
+imx27_visstrim_m10 MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10 2187
+portuxg20 MACH_PORTUXG20 PORTUXG20 2191
+smdkc110 MACH_SMDKC110 SMDKC110 2193
+omap3517evm MACH_OMAP3517EVM OMAP3517EVM 2200
+netspace_v2 MACH_NETSPACE_V2 NETSPACE_V2 2201
+netspace_max_v2 MACH_NETSPACE_MAX_V2 NETSPACE_MAX_V2 2202
+d2net_v2 MACH_D2NET_V2 D2NET_V2 2203
+net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204
+net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206
+inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208
+at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212
+pc7302 MACH_PC7302 PC7302 2220
+spear600 MACH_SPEAR600 SPEAR600 2236
+spear300 MACH_SPEAR300 SPEAR300 2237
+lilly1131 MACH_LILLY1131 LILLY1131 2239
+hmt MACH_HMT HMT 2254
+vexpress MACH_VEXPRESS VEXPRESS 2272
+d2net MACH_D2NET D2NET 2282
+bigdisk MACH_BIGDISK BIGDISK 2283
+at91sam9g20ek_2mmc MACH_AT91SAM9G20EK_2MMC AT91SAM9G20EK_2MMC 2288
+bcmring MACH_BCMRING BCMRING 2289
+dp6xx MACH_DP6XX DP6XX 2302
+mahimahi MACH_MAHIMAHI MAHIMAHI 2304
+smdk6442 MACH_SMDK6442 SMDK6442 2324
+openrd_base MACH_OPENRD_BASE OPENRD_BASE 2325
+devkit8000 MACH_DEVKIT8000 DEVKIT8000 2330
+mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336
+cm_t35 MACH_CM_T35 CM_T35 2341
+net2big MACH_NET2BIG NET2BIG 2342
+igep0020 MACH_IGEP0020 IGEP0020 2344
+nuc932evb MACH_NUC932EVB NUC932EVB 2356
+openrd_client MACH_OPENRD_CLIENT OPENRD_CLIENT 2361
+u8500 MACH_U8500 U8500 2368
+mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370
+marvell_jasper MACH_MARVELL_JASPER MARVELL_JASPER 2382
+flint MACH_FLINT FLINT 2383
+tavorevb3 MACH_TAVOREVB3 TAVOREVB3 2384
+touchbook MACH_TOUCHBOOK TOUCHBOOK 2393
+raumfeld_rc MACH_RAUMFELD_RC RAUMFELD_RC 2413
+raumfeld_connector MACH_RAUMFELD_CONNECTOR RAUMFELD_CONNECTOR 2414
+raumfeld_speaker MACH_RAUMFELD_SPEAKER RAUMFELD_SPEAKER 2415
+tnetv107x MACH_TNETV107X TNETV107X 2418
+smdkv210 MACH_SMDKV210 SMDKV210 2456
+omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464
+omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465
+smartq7 MACH_SMARTQ7 SMARTQ7 2479
+watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491
+g4evm MACH_G4EVM G4EVM 2493
+omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495
+ts41x MACH_TS41X TS41X 2502
+phy3250 MACH_PHY3250 PHY3250 2511
+mini6410 MACH_MINI6410 MINI6410 2520
+mx28evk MACH_MX28EVK MX28EVK 2531
+smartq5 MACH_SMARTQ5 SMARTQ5 2534
+davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548
+mxt_td60 MACH_MXT_TD60 MXT_TD60 2550
+riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
+riot_x37 MACH_RIOT_X37 RIOT_X37 2578
+capc7117 MACH_CAPC7117 CAPC7117 2612
+icontrol MACH_ICONTROL ICONTROL 2624
+qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
+mx23evk MACH_MX23EVK MX23EVK 2629
+ap4evb MACH_AP4EVB AP4EVB 2630
+mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650
+guruplug MACH_GURUPLUG GURUPLUG 2659
+spear310 MACH_SPEAR310 SPEAR310 2660
+spear320 MACH_SPEAR320 SPEAR320 2661
+aquila MACH_AQUILA AQUILA 2676
+sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
+msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
+ea2478devkit MACH_EA2478DEVKIT EA2478DEVKIT 2683
+terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
+msm7x25_surf MACH_MSM7X25_SURF MSM7X25_SURF 2703
+msm7x25_ffa MACH_MSM7X25_FFA MSM7X25_FFA 2704
+msm7x27_surf MACH_MSM7X27_SURF MSM7X27_SURF 2705
+msm7x27_ffa MACH_MSM7X27_FFA MSM7X27_FFA 2706
+msm7x30_ffa MACH_MSM7X30_FFA MSM7X30_FFA 2707
+qsd8x50_surf MACH_QSD8X50_SURF QSD8X50_SURF 2708
+mx53_evk MACH_MX53_EVK MX53_EVK 2716
+igep0030 MACH_IGEP0030 IGEP0030 2717
+sbc3530 MACH_SBC3530 SBC3530 2722
+saarb MACH_SAARB SAARB 2727
+harmony MACH_HARMONY HARMONY 2731
+msm7x30_fluid MACH_MSM7X30_FLUID MSM7X30_FLUID 2741
+cm_t3517 MACH_CM_T3517 CM_T3517 2750
+wbd222 MACH_WBD222 WBD222 2753
+msm8x60_surf MACH_MSM8X60_SURF MSM8X60_SURF 2755
+msm8x60_sim MACH_MSM8X60_SIM MSM8X60_SIM 2756
+tcc8000_sdk MACH_TCC8000_SDK TCC8000_SDK 2758
+nanos MACH_NANOS NANOS 2759
+stamp9g45 MACH_STAMP9G45 STAMP9G45 2761
+cns3420vb MACH_CNS3420VB CNS3420VB 2776
+omap4_panda MACH_OMAP4_PANDA OMAP4_PANDA 2791
+ti8168evm MACH_TI8168EVM TI8168EVM 2800
+teton_bga MACH_TETON_BGA TETON_BGA 2816
+eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
+eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
+eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
+eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
+smdkc210 MACH_SMDKC210 SMDKC210 2838
+omap3_braillo MACH_OMAP3_BRAILLO OMAP3_BRAILLO 2839
+spyplug MACH_SPYPLUG SPYPLUG 2840
+ginger MACH_GINGER GINGER 2841
+tny_t3530 MACH_TNY_T3530 TNY_T3530 2842
+pca102 MACH_PCA102 PCA102 2843
+spade MACH_SPADE SPADE 2844
+mxc25_topaz MACH_MXC25_TOPAZ MXC25_TOPAZ 2845
+t5325 MACH_T5325 T5325 2846
+gw2361 MACH_GW2361 GW2361 2847
+elog MACH_ELOG ELOG 2848
+income MACH_INCOME INCOME 2849
+bcm589x MACH_BCM589X BCM589X 2850
+etna MACH_ETNA ETNA 2851
+hawks MACH_HAWKS HAWKS 2852
+meson MACH_MESON MESON 2853
+xsbase255 MACH_XSBASE255 XSBASE255 2854
+pvm2030 MACH_PVM2030 PVM2030 2855
+mioa502 MACH_MIOA502 MIOA502 2856
+vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857
+vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858
+vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859
+htc_spv_m700 MACH_HTC_SPV_M700 HTC_SPV_M700 2860
+mx257sx MACH_MX257SX MX257SX 2861
+goni MACH_GONI GONI 2862
+msm8x55_svlte_ffa MACH_MSM8X55_SVLTE_FFA MSM8X55_SVLTE_FFA 2863
+msm8x55_svlte_surf MACH_MSM8X55_SVLTE_SURF MSM8X55_SVLTE_SURF 2864
+quickstep MACH_QUICKSTEP QUICKSTEP 2865
+dmw96 MACH_DMW96 DMW96 2866
+hammerhead MACH_HAMMERHEAD HAMMERHEAD 2867
+trident MACH_TRIDENT TRIDENT 2868
+lightning MACH_LIGHTNING LIGHTNING 2869
+iconnect MACH_ICONNECT ICONNECT 2870
+autobot MACH_AUTOBOT AUTOBOT 2871
+coconut MACH_COCONUT COCONUT 2872
+durian MACH_DURIAN DURIAN 2873
+cayenne MACH_CAYENNE CAYENNE 2874
+fuji MACH_FUJI FUJI 2875
+synology_6282 MACH_SYNOLOGY_6282 SYNOLOGY_6282 2876
+em1sy MACH_EM1SY EM1SY 2877
+m502 MACH_M502 M502 2878
+matrix518 MACH_MATRIX518 MATRIX518 2879
+tiny_gurnard MACH_TINY_GURNARD TINY_GURNARD 2880
+spear1310 MACH_SPEAR1310 SPEAR1310 2881
+bv07 MACH_BV07 BV07 2882
+mxt_td61 MACH_MXT_TD61 MXT_TD61 2883
+openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
+devixp MACH_DEVIXP DEVIXP 2885
+miccpt MACH_MICCPT MICCPT 2886
+mic256 MACH_MIC256 MIC256 2887
+as1167 MACH_AS1167 AS1167 2888
+omap3_ibiza MACH_OMAP3_IBIZA OMAP3_IBIZA 2889
+u5500 MACH_U5500 U5500 2890
+davinci_picto MACH_DAVINCI_PICTO DAVINCI_PICTO 2891
+mecha MACH_MECHA MECHA 2892
+bubba3 MACH_BUBBA3 BUBBA3 2893
+pupitre MACH_PUPITRE PUPITRE 2894
+tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896
+tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897
+simplenet MACH_SIMPLENET SIMPLENET 2898
+ec4350tbm MACH_EC4350TBM EC4350TBM 2899
+pec_tc MACH_PEC_TC PEC_TC 2900
+pec_hc2 MACH_PEC_HC2 PEC_HC2 2901
+esl_mobilis_a MACH_ESL_MOBILIS_A ESL_MOBILIS_A 2902
+esl_mobilis_b MACH_ESL_MOBILIS_B ESL_MOBILIS_B 2903
+esl_wave_a MACH_ESL_WAVE_A ESL_WAVE_A 2904
+esl_wave_b MACH_ESL_WAVE_B ESL_WAVE_B 2905
+unisense_mmm MACH_UNISENSE_MMM UNISENSE_MMM 2906
+blueshark MACH_BLUESHARK BLUESHARK 2907
+e10 MACH_E10 E10 2908
+app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909
+pov15hd MACH_POV15HD POV15HD 2910
+stella MACH_STELLA STELLA 2911
+linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
+netwalker MACH_NETWALKER NETWALKER 2914
+acsx106 MACH_ACSX106 ACSX106 2915
+atlas5_c1 MACH_ATLAS5_C1 ATLAS5_C1 2916
+nsb3ast MACH_NSB3AST NSB3AST 2917
+gnet_slc MACH_GNET_SLC GNET_SLC 2918
+af4000 MACH_AF4000 AF4000 2919
+ark9431 MACH_ARK9431 ARK9431 2920
+fs_s5pc100 MACH_FS_S5PC100 FS_S5PC100 2921
+omap3505nova8 MACH_OMAP3505NOVA8 OMAP3505NOVA8 2922
+omap3621_edp1 MACH_OMAP3621_EDP1 OMAP3621_EDP1 2923
+oratisaes MACH_ORATISAES ORATISAES 2924
+smdkv310 MACH_SMDKV310 SMDKV310 2925
+siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926
+ventana MACH_VENTANA VENTANA 2927
+wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
+ec4350sdb MACH_EC4350SDB EC4350SDB 2929
+mimas MACH_MIMAS MIMAS 2930
+titan MACH_TITAN TITAN 2931
+craneboard MACH_CRANEBOARD CRANEBOARD 2932
+es2440 MACH_ES2440 ES2440 2933
+najay_a9263 MACH_NAJAY_A9263 NAJAY_A9263 2934
+htctornado MACH_HTCTORNADO HTCTORNADO 2935
+dimm_mx257 MACH_DIMM_MX257 DIMM_MX257 2936
+jigen301 MACH_JIGEN JIGEN 2937
+smdk6450 MACH_SMDK6450 SMDK6450 2938
+meno_qng MACH_MENO_QNG MENO_QNG 2939
+ns2416 MACH_NS2416 NS2416 2940
+rpc353 MACH_RPC353 RPC353 2941
+tq6410 MACH_TQ6410 TQ6410 2942
+sky6410 MACH_SKY6410 SKY6410 2943
+dynasty MACH_DYNASTY DYNASTY 2944
+vivo MACH_VIVO VIVO 2945
+bury_bl7582 MACH_BURY_BL7582 BURY_BL7582 2946
+bury_bps5270 MACH_BURY_BPS5270 BURY_BPS5270 2947
+basi MACH_BASI BASI 2948
+tn200 MACH_TN200 TN200 2949
+c2mmi MACH_C2MMI C2MMI 2950
+meson_6236m MACH_MESON_6236M MESON_6236M 2951
+meson_8626m MACH_MESON_8626M MESON_8626M 2952
+tube MACH_TUBE TUBE 2953
+messina MACH_MESSINA MESSINA 2954
+mx50_arm2 MACH_MX50_ARM2 MX50_ARM2 2955
+cetus9263 MACH_CETUS9263 CETUS9263 2956
+brownstone MACH_BROWNSTONE BROWNSTONE 2957
+vmx25 MACH_VMX25 VMX25 2958
+vmx51 MACH_VMX51 VMX51 2959
+abacus MACH_ABACUS ABACUS 2960
+cm4745 MACH_CM4745 CM4745 2961
+oratislink MACH_ORATISLINK ORATISLINK 2962
+davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963
+netviz MACH_NETVIZ NETVIZ 2964
+flexibity MACH_FLEXIBITY FLEXIBITY 2965
+wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966
+lpc24xx MACH_LPC24XX LPC24XX 2967
+spica MACH_SPICA SPICA 2968
+gpsdisplay MACH_GPSDISPLAY GPSDISPLAY 2969
+bipnet MACH_BIPNET BIPNET 2970
+overo_ctu_inertial MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL 2971
+davinci_dm355_mmm MACH_DAVINCI_DM355_MMM DAVINCI_DM355_MMM 2972
+pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973
+ptx7545 MACH_PTX7545 PTX7545 2974
+tm_efdc MACH_TM_EFDC TM_EFDC 2975
+omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977
+flyer MACH_FLYER FLYER 2978
+tornado3240 MACH_TORNADO3240 TORNADO3240 2979
+soli_01 MACH_SOLI_01 SOLI_01 2980
+omapl138_europalc MACH_OMAPL138_EUROPALC OMAPL138_EUROPALC 2981
+helios_v1 MACH_HELIOS_V1 HELIOS_V1 2982
+netspace_lite_v2 MACH_NETSPACE_LITE_V2 NETSPACE_LITE_V2 2983
+ssc MACH_SSC SSC 2984
+premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985
+wasabi MACH_WASABI WASABI 2986
+mx50_rdp MACH_MX50_RDP MX50_RDP 2988
+universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
+real6410 MACH_REAL6410 REAL6410 2990
+spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991
+ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992
+omap3_bc10 MACH_OMAP3_BC10 OMAP3_BC10 2993
+thebe MACH_THEBE THEBE 2994
+rv082 MACH_RV082 RV082 2995
+armlguest MACH_ARMLGUEST ARMLGUEST 2996
+tjinc1000 MACH_TJINC1000 TJINC1000 2997
+dockstar MACH_DOCKSTAR DOCKSTAR 2998
+ax8008 MACH_AX8008 AX8008 2999
+gnet_sgce MACH_GNET_SGCE GNET_SGCE 3000
+pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001
+ea20 MACH_EA20 EA20 3002
+awm2 MACH_AWM2 AWM2 3003
+ti8148evm MACH_TI8148EVM TI8148EVM 3004
+seaboard MACH_SEABOARD SEABOARD 3005
+linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006
+tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007
+rubys MACH_RUBYS RUBYS 3008
+aquarius MACH_AQUARIUS AQUARIUS 3009
+mx53_ard MACH_MX53_ARD MX53_ARD 3010
+mx53_smd MACH_MX53_SMD MX53_SMD 3011
+lswxl MACH_LSWXL LSWXL 3012
+dove_avng_v3 MACH_DOVE_AVNG_V3 DOVE_AVNG_V3 3013
+sdi_ess_9263 MACH_SDI_ESS_9263 SDI_ESS_9263 3014
+jocpu550 MACH_JOCPU550 JOCPU550 3015
+msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016
+msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017
+yanomami MACH_YANOMAMI YANOMAMI 3018
+gta04 MACH_GTA04 GTA04 3019
+cm_a510 MACH_CM_A510 CM_A510 3020
+omap3_rfs200 MACH_OMAP3_RFS200 OMAP3_RFS200 3021
+kx33xx MACH_KX33XX KX33XX 3022
+ptx7510 MACH_PTX7510 PTX7510 3023
+top9000 MACH_TOP9000 TOP9000 3024
+teenote MACH_TEENOTE TEENOTE 3025
+ts3 MACH_TS3 TS3 3026
+a0 MACH_A0 A0 3027
+fsm9xxx_surf MACH_FSM9XXX_SURF FSM9XXX_SURF 3028
+fsm9xxx_ffa MACH_FSM9XXX_FFA FSM9XXX_FFA 3029
+frrhwcdma60w MACH_FRRHWCDMA60W FRRHWCDMA60W 3030
+remus MACH_REMUS REMUS 3031
+at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032
+at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033
+kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034
+armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036
+spdm MACH_SPDM SPDM 3037
+gtib MACH_GTIB GTIB 3038
+dgm3240 MACH_DGM3240 DGM3240 3039
+htcmega MACH_HTCMEGA HTCMEGA 3041
+tricorder MACH_TRICORDER TRICORDER 3042
+tx28 MACH_TX28 TX28 3043
+bstbrd MACH_BSTBRD BSTBRD 3044
+pwb3090 MACH_PWB3090 PWB3090 3045
+idea6410 MACH_IDEA6410 IDEA6410 3046
+qbc9263 MACH_QBC9263 QBC9263 3047
+borabora MACH_BORABORA BORABORA 3048
+valdez MACH_VALDEZ VALDEZ 3049
+ls9g20 MACH_LS9G20 LS9G20 3050
+mios_v1 MACH_MIOS_V1 MIOS_V1 3051
+s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052
+controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053
+tin307 MACH_TIN307 TIN307 3054
+tin510 MACH_TIN510 TIN510 3055
+bluecheese MACH_BLUECHEESE BLUECHEESE 3057
+tem3x30 MACH_TEM3X30 TEM3X30 3058
+harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059
+msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060
+spear900 MACH_SPEAR900 SPEAR900 3061
+pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062
+rdstor MACH_RDSTOR RDSTOR 3063
+usdloader MACH_USDLOADER USDLOADER 3064
+tsoploader MACH_TSOPLOADER TSOPLOADER 3065
+kronos MACH_KRONOS KRONOS 3066
+ffcore MACH_FFCORE FFCORE 3067
+mone MACH_MONE MONE 3068
+unit2s MACH_UNIT2S UNIT2S 3069
+acer_a5 MACH_ACER_A5 ACER_A5 3070
+etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071
+stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072
+p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073
+tulip MACH_TULIP TULIP 3074
+sunflower MACH_SUNFLOWER SUNFLOWER 3075
+rib MACH_RIB RIB 3076
+clod MACH_CLOD CLOD 3077
+rump MACH_RUMP RUMP 3078
+tenderloin MACH_TENDERLOIN TENDERLOIN 3079
+shortloin MACH_SHORTLOIN SHORTLOIN 3080
+antares MACH_ANTARES ANTARES 3082
+wb40n MACH_WB40N WB40N 3083
+herring MACH_HERRING HERRING 3084
+naxy400 MACH_NAXY400 NAXY400 3085
+naxy1200 MACH_NAXY1200 NAXY1200 3086
+vpr200 MACH_VPR200 VPR200 3087
+bug20 MACH_BUG20 BUG20 3088
+goflexnet MACH_GOFLEXNET GOFLEXNET 3089
+torbreck MACH_TORBRECK TORBRECK 3090
+saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091
+callisto MACH_CALLISTO CALLISTO 3092
+multhsu MACH_MULTHSU MULTHSU 3093
+saluda MACH_SALUDA SALUDA 3094
+pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095
+vc0718 MACH_VC0718 VC0718 3096
+mvblx MACH_MVBLX MVBLX 3097
+inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098
+inhand_fury MACH_INHAND_FURY INHAND_FURY 3099
+inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100
+hdnvp MACH_HDNVP HDNVP 3101
+softwinner MACH_SOFTWINNER SOFTWINNER 3102
+prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
+nas6210 MACH_NAS6210 NAS6210 3104
+unisdev MACH_UNISDEV UNISDEV 3105
+sbca11 MACH_SBCA11 SBCA11 3106
+saga MACH_SAGA SAGA 3107
+ns_k330 MACH_NS_K330 NS_K330 3108
+tanna MACH_TANNA TANNA 3109
+imate8502 MACH_IMATE8502 IMATE8502 3110
+aspen MACH_ASPEN ASPEN 3111
+daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112
+zmx25 MACH_ZMX25 ZMX25 3113
+maple1 MACH_MAPLE1 MAPLE1 3114
+qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115
+qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116
+abilene MACH_ABILENE ABILENE 3117
+eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118
+iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119
+coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120
+santiago MACH_SANTIAGO SANTIAGO 3121
+mx257sol MACH_MX257SOL MX257SOL 3122
+strasbourg MACH_STRASBOURG STRASBOURG 3123
+msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124
+smartqv5 MACH_SMARTQV5 SMARTQV5 3125
+smartqv3 MACH_SMARTQV3 SMARTQV3 3126
+smartqv7 MACH_SMARTQV7 SMARTQV7 3127
+paz00 MACH_PAZ00 PAZ00 3128
+acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131
+hdgu MACH_HDGU HDGU 3132
+pyramid MACH_PYRAMID PYRAMID 3133
+epiphan MACH_EPIPHAN EPIPHAN 3134
+omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135
+gurnard MACH_GURNARD GURNARD 3136
+gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137
+bcm2708 MACH_BCM2708 BCM2708 3138
+mx51_ggc MACH_MX51_GGC MX51_GGC 3139
+sharespace MACH_SHARESPACE SHARESPACE 3140
+haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141
+simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142
+crux MACH_CRUX CRUX 3143
+mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144
+charon MACH_CHARON CHARON 3145
+picocom3 MACH_PICOCOM3 PICOCOM3 3146
+picocom4 MACH_PICOCOM4 PICOCOM4 3147
+serrano MACH_SERRANO SERRANO 3148
+doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149
+evsy MACH_EVSY EVSY 3150
+huashan MACH_HUASHAN HUASHAN 3151
+lausanne MACH_LAUSANNE LAUSANNE 3152
+emerald MACH_EMERALD EMERALD 3153
+tqma35 MACH_TQMA35 TQMA35 3154
+marvel MACH_MARVEL MARVEL 3155
+manuae MACH_MANUAE MANUAE 3156
+chacha MACH_CHACHA CHACHA 3157
+lemon MACH_LEMON LEMON 3158
+csc MACH_CSC CSC 3159
+gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160
+t20 MACH_T20 T20 3161
+hdmini MACH_HDMINI HDMINI 3162
+sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163
+express MACH_EXPRESS EXPRESS 3164
+express_kt MACH_EXPRESS_KT EXPRESS_KT 3165
+maximasp MACH_MAXIMASP MAXIMASP 3166
+nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167
+nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168
+sunfire MACH_SUNFIRE SUNFIRE 3169
+arowana MACH_AROWANA AROWANA 3170
+tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171
+tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172
+edison MACH_EDISON EDISON 3173
+svp8500v1 MACH_SVP8500V1 SVP8500V1 3174
+svp8500v2 MACH_SVP8500V2 SVP8500V2 3175
+svp5500 MACH_SVP5500 SVP5500 3176
+b5500 MACH_B5500 B5500 3177
+s5500 MACH_S5500 S5500 3178
+icon MACH_ICON ICON 3179
+elephant MACH_ELEPHANT ELEPHANT 3180
+shooter MACH_SHOOTER SHOOTER 3182
+spade_lte MACH_SPADE_LTE SPADE_LTE 3183
+philhwani MACH_PHILHWANI PHILHWANI 3184
+gsncomm MACH_GSNCOMM GSNCOMM 3185
+strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186
+mmm MACH_MMM MMM 3187
+davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188
+ag5evm MACH_AG5EVM AG5EVM 3189
+sc575plc MACH_SC575PLC SC575PLC 3190
+sc575hmi MACH_SC575IPC SC575IPC 3191
+omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192
+top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194
+top9000_su MACH_TOP9000_SU TOP9000_SU 3195
+utm300 MACH_UTM300 UTM300 3196
+tsunagi MACH_TSUNAGI TSUNAGI 3197
+ts75xx MACH_TS75XX TS75XX 3198
+ts47xx MACH_TS47XX TS47XX 3200
+da850_k5 MACH_DA850_K5 DA850_K5 3201
+ax502 MACH_AX502 AX502 3202
+igep0032 MACH_IGEP0032 IGEP0032 3203
+antero MACH_ANTERO ANTERO 3204
+synergy MACH_SYNERGY SYNERGY 3205
+ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
+punica MACH_PUNICA PUNICA 3208
+trimslice MACH_TRIMSLICE TRIMSLICE 3209
+mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210
+mackerel MACH_MACKEREL MACKEREL 3211
+fa9x27 MACH_FA9X27 FA9X27 3213
+ns2816tb MACH_NS2816TB NS2816TB 3214
+ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215
+ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216
+kaen MACH_KAEN KAEN 3217
+nv1000 MACH_NV1000 NV1000 3218
+nuc950ts MACH_NUC950TS NUC950TS 3219
+nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+ast2200 MACH_AST2200 AST2200 3221
+lead MACH_LEAD LEAD 3222
+unino1 MACH_UNINO1 UNINO1 3223
+greeco MACH_GREECO GREECO 3224
+verdi MACH_VERDI VERDI 3225
+dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226
+quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227
+abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228
+svcid MACH_SVCID SVCID 3229
+msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+icon_g MACH_ICON_G ICON_G 3232
+mb3 MACH_MB3 MB3 3233
+gsia18s MACH_GSIA18S GSIA18S 3234
+pivicc MACH_PIVICC PIVICC 3235
+pcm048 MACH_PCM048 PCM048 3236
+dds MACH_DDS DDS 3237
+chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238
+ts48xx MACH_TS48XX TS48XX 3239
+tonga2_tfttimer MACH_TONGA2_TFTTIMER TONGA2_TFTTIMER 3240
+whistler MACH_WHISTLER WHISTLER 3241
+asl_phoenix MACH_ASL_PHOENIX ASL_PHOENIX 3242
+at91sam9263otlite MACH_AT91SAM9263OTLITE AT91SAM9263OTLITE 3243
+ddplug MACH_DDPLUG DDPLUG 3244
+d2plug MACH_D2PLUG D2PLUG 3245
+kzm9d MACH_KZM9D KZM9D 3246
+verdi_lte MACH_VERDI_LTE VERDI_LTE 3247
+nanozoom MACH_NANOZOOM NANOZOOM 3248
+dm3730_som_lv MACH_DM3730_SOM_LV DM3730_SOM_LV 3249
+dm3730_torpedo MACH_DM3730_TORPEDO DM3730_TORPEDO 3250
+anchovy MACH_ANCHOVY ANCHOVY 3251
+re2rev20 MACH_RE2REV20 RE2REV20 3253
+re2rev21 MACH_RE2REV21 RE2REV21 3254
+cns21xx MACH_CNS21XX CNS21XX 3255
+rider MACH_RIDER RIDER 3257
+nsk330 MACH_NSK330 NSK330 3258
+cns2133evb MACH_CNS2133EVB CNS2133EVB 3259
+z3_816x_mod MACH_Z3_816X_MOD Z3_816X_MOD 3260
+z3_814x_mod MACH_Z3_814X_MOD Z3_814X_MOD 3261
+beect MACH_BEECT BEECT 3262
+dma_thunderbug MACH_DMA_THUNDERBUG DMA_THUNDERBUG 3263
+omn_at91sam9g20 MACH_OMN_AT91SAM9G20 OMN_AT91SAM9G20 3264
+mx25_e2s_uc MACH_MX25_E2S_UC MX25_E2S_UC 3265
+mione MACH_MIONE MIONE 3266
+top9000_tcu MACH_TOP9000_TCU TOP9000_TCU 3267
+top9000_bsl MACH_TOP9000_BSL TOP9000_BSL 3268
+kingdom MACH_KINGDOM KINGDOM 3269
+armadillo460 MACH_ARMADILLO460 ARMADILLO460 3270
+lq2 MACH_LQ2 LQ2 3271
+sweda_tms2 MACH_SWEDA_TMS2 SWEDA_TMS2 3272
+mx53_loco MACH_MX53_LOCO MX53_LOCO 3273
+acer_a8 MACH_ACER_A8 ACER_A8 3275
+acer_gauguin MACH_ACER_GAUGUIN ACER_GAUGUIN 3276
+guppy MACH_GUPPY GUPPY 3277
+mx61_ard MACH_MX61_ARD MX61_ARD 3278
+tx53 MACH_TX53 TX53 3279
+omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280
+uemd MACH_UEMD UEMD 3281
+ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282
+rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283
+nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284
+hkdkc100 MACH_HKDKC100 HKDKC100 3285
+ts42xx MACH_TS42XX TS42XX 3286
+aebl MACH_AEBL AEBL 3287
+wario MACH_WARIO WARIO 3288
+gfs_spm MACH_GFS_SPM GFS_SPM 3289
+cm_t3730 MACH_CM_T3730 CM_T3730 3290
+isc3 MACH_ISC3 ISC3 3291
+rascal MACH_RASCAL RASCAL 3292
+hrefv60 MACH_HREFV60 HREFV60 3293
+tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294
+splendor MACH_SPLENDOR SPLENDOR 3296
+msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298
+htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299
+athene MACH_ATHENE ATHENE 3300
+deep_r_ek_1 MACH_DEEP_R_EK_1 DEEP_R_EK_1 3301
+vivow_ct MACH_VIVOW_CT VIVOW_CT 3302
+nery_1000 MACH_NERY_1000 NERY_1000 3303
+rfl109145_ssrv MACH_RFL109145_SSRV RFL109145_SSRV 3304
+nmh MACH_NMH NMH 3305
+wn802t MACH_WN802T WN802T 3306
+dragonet MACH_DRAGONET DRAGONET 3307
+at91sam9263desk16l MACH_AT91SAM9263DESK16L AT91SAM9263DESK16L 3309
+bcmhana_sv MACH_BCMHANA_SV BCMHANA_SV 3310
+bcmhana_tablet MACH_BCMHANA_TABLET BCMHANA_TABLET 3311
+koi MACH_KOI KOI 3312
+ts4800 MACH_TS4800 TS4800 3313
+tqma9263 MACH_TQMA9263 TQMA9263 3314
+holiday MACH_HOLIDAY HOLIDAY 3315
+dma_6410 MACH_DMA6410 DMA6410 3316
+pcats_overlay MACH_PCATS_OVERLAY PCATS_OVERLAY 3317
+hwgw6410 MACH_HWGW6410 HWGW6410 3318
+shenzhou MACH_SHENZHOU SHENZHOU 3319
+cwme9210 MACH_CWME9210 CWME9210 3320
+cwme9210js MACH_CWME9210JS CWME9210JS 3321
+pgs_v1 MACH_PGS_SITARA PGS_SITARA 3322
+colibri_tegra2 MACH_COLIBRI_TEGRA2 COLIBRI_TEGRA2 3323
+w21 MACH_W21 W21 3324
+polysat1 MACH_POLYSAT1 POLYSAT1 3325
+dataway MACH_DATAWAY DATAWAY 3326
+cobral138 MACH_COBRAL138 COBRAL138 3327
+roverpcs8 MACH_ROVERPCS8 ROVERPCS8 3328
+marvelc MACH_MARVELC MARVELC 3329
+navefihid MACH_NAVEFIHID NAVEFIHID 3330
+dm365_cv100 MACH_DM365_CV100 DM365_CV100 3331
+able MACH_ABLE ABLE 3332
+legacy MACH_LEGACY LEGACY 3333
+icong MACH_ICONG ICONG 3334
+rover_g8 MACH_ROVER_G8 ROVER_G8 3335
+t5388p MACH_T5388P T5388P 3336
+dingo MACH_DINGO DINGO 3337
+goflexhome MACH_GOFLEXHOME GOFLEXHOME 3338
+lanreadyfn511 MACH_LANREADYFN511 LANREADYFN511 3340
+omap3_baia MACH_OMAP3_BAIA OMAP3_BAIA 3341
+omap3smartdisplay MACH_OMAP3SMARTDISPLAY OMAP3SMARTDISPLAY 3342
+xilinx MACH_XILINX XILINX 3343
+a2f MACH_A2F A2F 3344
+sky25 MACH_SKY25 SKY25 3345
+ccmx53 MACH_CCMX53 CCMX53 3346
+ccmx53js MACH_CCMX53JS CCMX53JS 3347
+ccwmx53 MACH_CCWMX53 CCWMX53 3348
+ccwmx53js MACH_CCWMX53JS CCWMX53JS 3349
+frisms MACH_FRISMS FRISMS 3350
+msm7x27a_ffa MACH_MSM7X27A_FFA MSM7X27A_FFA 3351
+msm7x27a_surf MACH_MSM7X27A_SURF MSM7X27A_SURF 3352
+msm7x27a_rumi3 MACH_MSM7X27A_RUMI3 MSM7X27A_RUMI3 3353
+dimmsam9g20 MACH_DIMMSAM9G20 DIMMSAM9G20 3354
+dimm_imx28 MACH_DIMM_IMX28 DIMM_IMX28 3355
+amk_a4 MACH_AMK_A4 AMK_A4 3356
+gnet_sgme MACH_GNET_SGME GNET_SGME 3357
+shooter_u MACH_SHOOTER_U SHOOTER_U 3358
+vmx53 MACH_VMX53 VMX53 3359
+rhino MACH_RHINO RHINO 3360
+armlex4210 MACH_ARMLEX4210 ARMLEX4210 3361
+swarcoextmodem MACH_SWARCOEXTMODEM SWARCOEXTMODEM 3362
+snowball MACH_SNOWBALL SNOWBALL 3363
+pcm049 MACH_PCM049 PCM049 3364
+vigor MACH_VIGOR VIGOR 3365
+oslo_amundsen MACH_OSLO_AMUNDSEN OSLO_AMUNDSEN 3366
+gsl_diamond MACH_GSL_DIAMOND GSL_DIAMOND 3367
+cv2201 MACH_CV2201 CV2201 3368
+cv2202 MACH_CV2202 CV2202 3369
+cv2203 MACH_CV2203 CV2203 3370
+vit_ibox MACH_VIT_IBOX VIT_IBOX 3371
+dm6441_esp MACH_DM6441_ESP DM6441_ESP 3372
+at91sam9x5ek MACH_AT91SAM9X5EK AT91SAM9X5EK 3373
+libra MACH_LIBRA LIBRA 3374
+easycrrh MACH_EASYCRRH EASYCRRH 3375
+tripel MACH_TRIPEL TRIPEL 3376
+endian_mini MACH_ENDIAN_MINI ENDIAN_MINI 3377
+xilinx_ep107 MACH_XILINX_EP107 XILINX_EP107 3378
+nuri MACH_NURI NURI 3379
+janus MACH_JANUS JANUS 3380
+ddnas MACH_DDNAS DDNAS 3381
+tag MACH_TAG TAG 3382
+tagw MACH_TAGW TAGW 3383
+nitrogen_vm_imx51 MACH_NITROGEN_VM_IMX51 NITROGEN_VM_IMX51 3384
+viprinet MACH_VIPRINET VIPRINET 3385
+bockw MACH_BOCKW BOCKW 3386
+eva2000 MACH_EVA2000 EVA2000 3387
+steelyard MACH_STEELYARD STEELYARD 3388
+sdh001 MACH_MACH_SDH001 MACH_SDH001 3390
+nsslsboard MACH_NSSLSBOARD NSSLSBOARD 3392
+geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393
+spear1340 MACH_SPEAR1340 SPEAR1340 3394
+rexmas MACH_REXMAS REXMAS 3395
+msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396
+msm8960_mdp MACH_MSM8960_MDP MSM8960_MDP 3397
+msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398
+msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399
+helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400
+mif10p MACH_MIF10P MIF10P 3401
+iam28 MACH_IAM28 IAM28 3402
+picasso MACH_PICASSO PICASSO 3403
+mr301a MACH_MR301A MR301A 3404
+notle MACH_NOTLE NOTLE 3405
+eelx2 MACH_EELX2 EELX2 3406
+moon MACH_MOON MOON 3407
+ruby MACH_RUBY RUBY 3408
+goldengate MACH_GOLDENGATE GOLDENGATE 3409
+ctbu_gen2 MACH_CTBU_GEN2 CTBU_GEN2 3410
+kmp_am17_01 MACH_KMP_AM17_01 KMP_AM17_01 3411
+wtplug MACH_WTPLUG WTPLUG 3412
+mx27su2 MACH_MX27SU2 MX27SU2 3413
+nb31 MACH_NB31 NB31 3414
+hjsdu MACH_HJSDU HJSDU 3415
+td3_rev1 MACH_TD3_REV1 TD3_REV1 3416
+eag_ci4000 MACH_EAG_CI4000 EAG_CI4000 3417
+net5big_nand_v2 MACH_NET5BIG_NAND_V2 NET5BIG_NAND_V2 3418
+cpx2 MACH_CPX2 CPX2 3419
+net2big_nand_v2 MACH_NET2BIG_NAND_V2 NET2BIG_NAND_V2 3420
+ecuv5 MACH_ECUV5 ECUV5 3421
+hsgx6d MACH_HSGX6D HSGX6D 3422
+dawad7 MACH_DAWAD7 DAWAD7 3423
+sam9repeater MACH_SAM9REPEATER SAM9REPEATER 3424
+gt_i5700 MACH_GT_I5700 GT_I5700 3425
+ctera_plug_c2 MACH_CTERA_PLUG_C2 CTERA_PLUG_C2 3426
+marvelct MACH_MARVELCT MARVELCT 3427
+ag11005 MACH_AG11005 AG11005 3428
+vangogh MACH_VANGOGH VANGOGH 3430
+matrix505 MACH_MATRIX505 MATRIX505 3431
+oce_nigma MACH_OCE_NIGMA OCE_NIGMA 3432
+t55 MACH_T55 T55 3433
+bio3k MACH_BIO3K BIO3K 3434
+expressct MACH_EXPRESSCT EXPRESSCT 3435
+cardhu MACH_CARDHU CARDHU 3436
+aruba MACH_ARUBA ARUBA 3437
+bonaire MACH_BONAIRE BONAIRE 3438
+nuc700evb MACH_NUC700EVB NUC700EVB 3439
+nuc710evb MACH_NUC710EVB NUC710EVB 3440
+nuc740evb MACH_NUC740EVB NUC740EVB 3441
+nuc745evb MACH_NUC745EVB NUC745EVB 3442
+transcede MACH_TRANSCEDE TRANSCEDE 3443
+mora MACH_MORA MORA 3444
+nda_evm MACH_NDA_EVM NDA_EVM 3445
+timu MACH_TIMU TIMU 3446
+expressh MACH_EXPRESSH EXPRESSH 3447
+veridis_a300 MACH_VERIDIS_A300 VERIDIS_A300 3448
+dm368_leopard MACH_DM368_LEOPARD DM368_LEOPARD 3449
+omap_mcop MACH_OMAP_MCOP OMAP_MCOP 3450
+tritip MACH_TRITIP TRITIP 3451
+sm1k MACH_SM1K SM1K 3452
+monch MACH_MONCH MONCH 3453
+curacao MACH_CURACAO CURACAO 3454
+origen MACH_ORIGEN ORIGEN 3455
+epc10 MACH_EPC10 EPC10 3456
+sgh_i740 MACH_SGH_I740 SGH_I740 3457
+tuna MACH_TUNA TUNA 3458
+mx51_tulip MACH_MX51_TULIP MX51_TULIP 3459
+mx51_aster7 MACH_MX51_ASTER7 MX51_ASTER7 3460
+acro37xbrd MACH_ACRO37XBRD ACRO37XBRD 3461
+elke MACH_ELKE ELKE 3462
+sbc6000x MACH_SBC6000X SBC6000X 3463
+r1801e MACH_R1801E R1801E 3464
+h1600 MACH_H1600 H1600 3465
+mini210 MACH_MINI210 MINI210 3466
+mini8168 MACH_MINI8168 MINI8168 3467
+pc7308 MACH_PC7308 PC7308 3468
+kmm2m01 MACH_KMM2M01 KMM2M01 3470
+mx51erebus MACH_MX51EREBUS MX51EREBUS 3471
+wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472
+tuxrail MACH_TUXRAIL TUXRAIL 3473
+arthur MACH_ARTHUR ARTHUR 3474
+doorboy MACH_DOORBOY DOORBOY 3475
+xarina MACH_XARINA XARINA 3476
+roverx7 MACH_ROVERX7 ROVERX7 3477
+sdvr MACH_SDVR SDVR 3478
+acer_maya MACH_ACER_MAYA ACER_MAYA 3479
+pico MACH_PICO PICO 3480
+cwmx233 MACH_CWMX233 CWMX233 3481
+cwam1808 MACH_CWAM1808 CWAM1808 3482
+cwdm365 MACH_CWDM365 CWDM365 3483
+mx51_moray MACH_MX51_MORAY MX51_MORAY 3484
+thales_cbc MACH_THALES_CBC THALES_CBC 3485
+bluepoint MACH_BLUEPOINT BLUEPOINT 3486
+dir665 MACH_DIR665 DIR665 3487
+acmerover1 MACH_ACMEROVER1 ACMEROVER1 3488
+shooter_ct MACH_SHOOTER_CT SHOOTER_CT 3489
+bliss MACH_BLISS BLISS 3490
+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
+mx6q_sabreauto MACH_MX6Q_SABREAUTO MX6Q_SABREAUTO 3529
+mx6q_sabrelite MACH_MX6Q_SABRELITE MX6Q_SABRELITE 3769
+mx6q_sabresd MACH_MX6Q_SABRESD MX6Q_SABRESD 3980
+mx6q_arm2 MACH_MX6Q_ARM2 MX6Q_ARM2 3837
+mx6sl_arm2 MACH_MX6SL_ARM2 MX6SL_ARM2 4091
+mx6q_hdmidongle MACH_MX6Q_HDMIDONGLE MX6Q_HDMIDONGLE 4284
+mx6sl_evk MACH_MX6SL_EVK MX6SL_EVK 4307
+mx6sl_ntx MACH_MX6SL_NTX MX6SL_NTX 4308
+
diff --git a/arch/arm/vfp/Makefile b/arch/arm/vfp/Makefile
new file mode 100644
index 00000000..6de73aab
--- /dev/null
+++ b/arch/arm/vfp/Makefile
@@ -0,0 +1,15 @@
+#
+# linux/arch/arm/vfp/Makefile
+#
+# Copyright (C) 2001 ARM Limited
+#
+
+# ccflags-y := -DDEBUG
+# asflags-y := -DDEBUG
+
+KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp)
+LDFLAGS +=--no-warn-mismatch
+
+obj-y += vfp.o
+
+vfp-$(CONFIG_VFP) += vfpmodule.o entry.o vfphw.o vfpsingle.o vfpdouble.o
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
new file mode 100644
index 00000000..c1a97840
--- /dev/null
+++ b/arch/arm/vfp/entry.S
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/arm/vfp/entry.S
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Basic entry code, called from the kernel's undefined instruction trap.
+ * r0 = faulted instruction
+ * r2 = faulted PC+4
+ * r9 = successful return
+ * r10 = thread_info structure
+ * lr = failure return
+ */
+#include <asm/thread_info.h>
+#include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
+
+ENTRY(do_vfp)
+#ifdef CONFIG_PREEMPT
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ add r11, r4, #1 @ increment it
+ 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
+ ldr pc, [r4] @ call VFP entry point
+ENDPROC(do_vfp)
+
+ENTRY(vfp_null_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
+ mov pc, lr
+ENDPROC(vfp_null_entry)
+
+ .align 2
+.LCvfp:
+ .word vfp_vector
+
+@ This code is called if the VFP does not exist. It needs to flag the
+@ failure to the VFP initialisation code.
+
+ __INIT
+ENTRY(vfp_testing_entry)
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
+ ldr r0, VFP_arch_address
+ str r5, [r0] @ known non-zero value
+ mov pc, r9 @ we have handled the fault
+ENDPROC(vfp_testing_entry)
+
+ .align 2
+VFP_arch_address:
+ .word VFP_arch
+
+ __FINIT
diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h
new file mode 100644
index 00000000..c8c98dd4
--- /dev/null
+++ b/arch/arm/vfp/vfp.h
@@ -0,0 +1,380 @@
+/*
+ * linux/arch/arm/vfp/vfp.h
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+static inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift)
+{
+ if (shift) {
+ if (shift < 32)
+ val = val >> shift | ((val << (32 - shift)) != 0);
+ else
+ val = val != 0;
+ }
+ return val;
+}
+
+static inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift)
+{
+ if (shift) {
+ if (shift < 64)
+ val = val >> shift | ((val << (64 - shift)) != 0);
+ else
+ val = val != 0;
+ }
+ return val;
+}
+
+static inline u32 vfp_hi64to32jamming(u64 val)
+{
+ u32 v;
+
+ asm(
+ "cmp %Q1, #1 @ vfp_hi64to32jamming\n\t"
+ "movcc %0, %R1\n\t"
+ "orrcs %0, %R1, #1"
+ : "=r" (v) : "r" (val) : "cc");
+
+ return v;
+}
+
+static inline void add128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
+{
+ asm( "adds %Q0, %Q2, %Q4\n\t"
+ "adcs %R0, %R2, %R4\n\t"
+ "adcs %Q1, %Q3, %Q5\n\t"
+ "adc %R1, %R3, %R5"
+ : "=r" (nl), "=r" (nh)
+ : "0" (nl), "1" (nh), "r" (ml), "r" (mh)
+ : "cc");
+ *resh = nh;
+ *resl = nl;
+}
+
+static inline void sub128(u64 *resh, u64 *resl, u64 nh, u64 nl, u64 mh, u64 ml)
+{
+ asm( "subs %Q0, %Q2, %Q4\n\t"
+ "sbcs %R0, %R2, %R4\n\t"
+ "sbcs %Q1, %Q3, %Q5\n\t"
+ "sbc %R1, %R3, %R5\n\t"
+ : "=r" (nl), "=r" (nh)
+ : "0" (nl), "1" (nh), "r" (ml), "r" (mh)
+ : "cc");
+ *resh = nh;
+ *resl = nl;
+}
+
+static inline void mul64to128(u64 *resh, u64 *resl, u64 n, u64 m)
+{
+ u32 nh, nl, mh, ml;
+ u64 rh, rma, rmb, rl;
+
+ nl = n;
+ ml = m;
+ rl = (u64)nl * ml;
+
+ nh = n >> 32;
+ rma = (u64)nh * ml;
+
+ mh = m >> 32;
+ rmb = (u64)nl * mh;
+ rma += rmb;
+
+ rh = (u64)nh * mh;
+ rh += ((u64)(rma < rmb) << 32) + (rma >> 32);
+
+ rma <<= 32;
+ rl += rma;
+ rh += (rl < rma);
+
+ *resl = rl;
+ *resh = rh;
+}
+
+static inline void shift64left(u64 *resh, u64 *resl, u64 n)
+{
+ *resh = n >> 63;
+ *resl = n << 1;
+}
+
+static inline u64 vfp_hi64multiply64(u64 n, u64 m)
+{
+ u64 rh, rl;
+ mul64to128(&rh, &rl, n, m);
+ return rh | (rl != 0);
+}
+
+static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
+{
+ u64 mh, ml, remh, reml, termh, terml, z;
+
+ if (nh >= m)
+ return ~0ULL;
+ mh = m >> 32;
+ if (mh << 32 <= nh) {
+ z = 0xffffffff00000000ULL;
+ } else {
+ z = nh;
+ do_div(z, mh);
+ z <<= 32;
+ }
+ mul64to128(&termh, &terml, m, z);
+ sub128(&remh, &reml, nh, nl, termh, terml);
+ ml = m << 32;
+ while ((s64)remh < 0) {
+ z -= 0x100000000ULL;
+ add128(&remh, &reml, remh, reml, mh, ml);
+ }
+ remh = (remh << 32) | (reml >> 32);
+ if (mh << 32 <= remh) {
+ z |= 0xffffffff;
+ } else {
+ do_div(remh, mh);
+ z |= remh;
+ }
+ return z;
+}
+
+/*
+ * Operations on unpacked elements
+ */
+#define vfp_sign_negate(sign) (sign ^ 0x8000)
+
+/*
+ * Single-precision
+ */
+struct vfp_single {
+ s16 exponent;
+ u16 sign;
+ u32 significand;
+};
+
+extern s32 vfp_get_float(unsigned int reg);
+extern void vfp_put_float(s32 val, unsigned int reg);
+
+/*
+ * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa
+ * VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent
+ * VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand
+ * which are not propagated to the float upon packing.
+ */
+#define VFP_SINGLE_MANTISSA_BITS (23)
+#define VFP_SINGLE_EXPONENT_BITS (8)
+#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2)
+#define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1)
+
+/*
+ * The bit in an unpacked float which indicates that it is a quiet NaN
+ */
+#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS))
+
+/*
+ * Operations on packed single-precision numbers
+ */
+#define vfp_single_packed_sign(v) ((v) & 0x80000000)
+#define vfp_single_packed_negate(v) ((v) ^ 0x80000000)
+#define vfp_single_packed_abs(v) ((v) & ~0x80000000)
+#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1))
+#define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1))
+
+/*
+ * Unpack a single-precision float. Note that this returns the magnitude
+ * of the single-precision float mantissa with the 1. if necessary,
+ * aligned to bit 30.
+ */
+static inline void vfp_single_unpack(struct vfp_single *s, s32 val)
+{
+ u32 significand;
+
+ s->sign = vfp_single_packed_sign(val) >> 16,
+ s->exponent = vfp_single_packed_exponent(val);
+
+ significand = (u32) val;
+ significand = (significand << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2;
+ if (s->exponent && s->exponent != 255)
+ significand |= 0x40000000;
+ s->significand = significand;
+}
+
+/*
+ * Re-pack a single-precision float. This assumes that the float is
+ * already normalised such that the MSB is bit 30, _not_ bit 31.
+ */
+static inline s32 vfp_single_pack(struct vfp_single *s)
+{
+ u32 val;
+ val = (s->sign << 16) +
+ (s->exponent << VFP_SINGLE_MANTISSA_BITS) +
+ (s->significand >> VFP_SINGLE_LOW_BITS);
+ return (s32)val;
+}
+
+#define VFP_NUMBER (1<<0)
+#define VFP_ZERO (1<<1)
+#define VFP_DENORMAL (1<<2)
+#define VFP_INFINITY (1<<3)
+#define VFP_NAN (1<<4)
+#define VFP_NAN_SIGNAL (1<<5)
+
+#define VFP_QNAN (VFP_NAN)
+#define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL)
+
+static inline int vfp_single_type(struct vfp_single *s)
+{
+ int type = VFP_NUMBER;
+ if (s->exponent == 255) {
+ if (s->significand == 0)
+ type = VFP_INFINITY;
+ else if (s->significand & VFP_SINGLE_SIGNIFICAND_QNAN)
+ type = VFP_QNAN;
+ else
+ type = VFP_SNAN;
+ } else if (s->exponent == 0) {
+ if (s->significand == 0)
+ type |= VFP_ZERO;
+ else
+ type |= VFP_DENORMAL;
+ }
+ return type;
+}
+
+#ifndef DEBUG
+#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except)
+u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions);
+#else
+u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func);
+#endif
+
+/*
+ * Double-precision
+ */
+struct vfp_double {
+ s16 exponent;
+ u16 sign;
+ u64 significand;
+};
+
+/*
+ * VFP_REG_ZERO is a special register number for vfp_get_double
+ * which returns (double)0.0. This is useful for the compare with
+ * zero instructions.
+ */
+#ifdef CONFIG_VFPv3
+#define VFP_REG_ZERO 32
+#else
+#define VFP_REG_ZERO 16
+#endif
+extern u64 vfp_get_double(unsigned int reg);
+extern void vfp_put_double(u64 val, unsigned int reg);
+
+#define VFP_DOUBLE_MANTISSA_BITS (52)
+#define VFP_DOUBLE_EXPONENT_BITS (11)
+#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2)
+#define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1)
+
+/*
+ * The bit in an unpacked double which indicates that it is a quiet NaN
+ */
+#define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS))
+
+/*
+ * Operations on packed single-precision numbers
+ */
+#define vfp_double_packed_sign(v) ((v) & (1ULL << 63))
+#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63))
+#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63))
+#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1))
+#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1))
+
+/*
+ * Unpack a double-precision float. Note that this returns the magnitude
+ * of the double-precision float mantissa with the 1. if necessary,
+ * aligned to bit 62.
+ */
+static inline void vfp_double_unpack(struct vfp_double *s, s64 val)
+{
+ u64 significand;
+
+ s->sign = vfp_double_packed_sign(val) >> 48;
+ s->exponent = vfp_double_packed_exponent(val);
+
+ significand = (u64) val;
+ significand = (significand << (64 - VFP_DOUBLE_MANTISSA_BITS)) >> 2;
+ if (s->exponent && s->exponent != 2047)
+ significand |= (1ULL << 62);
+ s->significand = significand;
+}
+
+/*
+ * Re-pack a double-precision float. This assumes that the float is
+ * already normalised such that the MSB is bit 30, _not_ bit 31.
+ */
+static inline s64 vfp_double_pack(struct vfp_double *s)
+{
+ u64 val;
+ val = ((u64)s->sign << 48) +
+ ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) +
+ (s->significand >> VFP_DOUBLE_LOW_BITS);
+ return (s64)val;
+}
+
+static inline int vfp_double_type(struct vfp_double *s)
+{
+ int type = VFP_NUMBER;
+ if (s->exponent == 2047) {
+ if (s->significand == 0)
+ type = VFP_INFINITY;
+ else if (s->significand & VFP_DOUBLE_SIGNIFICAND_QNAN)
+ type = VFP_QNAN;
+ else
+ type = VFP_SNAN;
+ } else if (s->exponent == 0) {
+ if (s->significand == 0)
+ type |= VFP_ZERO;
+ else
+ type |= VFP_DENORMAL;
+ }
+ return type;
+}
+
+u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func);
+
+u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand);
+
+/*
+ * A special flag to tell the normalisation code not to normalise.
+ */
+#define VFP_NAN_FLAG 0x100
+
+/*
+ * A bit pattern used to indicate the initial (unset) value of the
+ * exception mask, in case nothing handles an instruction. This
+ * doesn't include the NAN flag, which get masked out before
+ * we check for an error.
+ */
+#define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG)
+
+/*
+ * A flag to tell vfp instruction type.
+ * OP_SCALAR - this operation always operates in scalar mode
+ * OP_SD - the instruction exceptionally writes to a single precision result.
+ * OP_DD - the instruction exceptionally writes to a double precision result.
+ * OP_SM - the instruction exceptionally reads from a single precision operand.
+ */
+#define OP_SCALAR (1 << 0)
+#define OP_SD (1 << 1)
+#define OP_DD (1 << 1)
+#define OP_SM (1 << 2)
+
+struct op {
+ u32 (* const fn)(int dd, int dn, int dm, u32 fpscr);
+ u32 flags;
+};
+
+extern void vfp_save_state(void *location, u32 fpexc);
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
new file mode 100644
index 00000000..6cac43bd
--- /dev/null
+++ b/arch/arm/vfp/vfpdouble.c
@@ -0,0 +1,1204 @@
+/*
+ * linux/arch/arm/vfp/vfpdouble.c
+ *
+ * This code is derived in part from John R. Housers softfloat library, which
+ * carries the following notice:
+ *
+ * ===========================================================================
+ * This C source file is part of the SoftFloat IEC/IEEE Floating-point
+ * Arithmetic Package, Release 2.
+ *
+ * Written by John R. Hauser. This work was made possible in part by the
+ * International Computer Science Institute, located at Suite 600, 1947 Center
+ * Street, Berkeley, California 94704. Funding was partially provided by the
+ * National Science Foundation under grant MIP-9311980. The original version
+ * of this code was written as part of a project to build a fixed-point vector
+ * processor in collaboration with the University of California at Berkeley,
+ * overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+ * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+ * arithmetic/softfloat.html'.
+ *
+ * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+ * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+ * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+ * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+ * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+ *
+ * Derivative works are acceptable, even for commercial purposes, so long as
+ * (1) they include prominent notice that the work is derivative, and (2) they
+ * include prominent notice akin to these three paragraphs for those parts of
+ * this code that are retained.
+ * ===========================================================================
+ */
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/div64.h>
+#include <asm/vfp.h>
+
+#include "vfpinstr.h"
+#include "vfp.h"
+
+static struct vfp_double vfp_double_default_qnan = {
+ .exponent = 2047,
+ .sign = 0,
+ .significand = VFP_DOUBLE_SIGNIFICAND_QNAN,
+};
+
+static void vfp_double_dump(const char *str, struct vfp_double *d)
+{
+ pr_debug("VFP: %s: sign=%d exponent=%d significand=%016llx\n",
+ str, d->sign != 0, d->exponent, d->significand);
+}
+
+static void vfp_double_normalise_denormal(struct vfp_double *vd)
+{
+ int bits = 31 - fls(vd->significand >> 32);
+ if (bits == 31)
+ bits = 63 - fls(vd->significand);
+
+ vfp_double_dump("normalise_denormal: in", vd);
+
+ if (bits) {
+ vd->exponent -= bits - 1;
+ vd->significand <<= bits;
+ }
+
+ vfp_double_dump("normalise_denormal: out", vd);
+}
+
+u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exceptions, const char *func)
+{
+ u64 significand, incr;
+ int exponent, shift, underflow;
+ u32 rmode;
+
+ vfp_double_dump("pack: in", vd);
+
+ /*
+ * Infinities and NaNs are a special case.
+ */
+ if (vd->exponent == 2047 && (vd->significand == 0 || exceptions))
+ goto pack;
+
+ /*
+ * Special-case zero.
+ */
+ if (vd->significand == 0) {
+ vd->exponent = 0;
+ goto pack;
+ }
+
+ exponent = vd->exponent;
+ significand = vd->significand;
+
+ shift = 32 - fls(significand >> 32);
+ if (shift == 32)
+ shift = 64 - fls(significand);
+ if (shift) {
+ exponent -= shift;
+ significand <<= shift;
+ }
+
+#ifdef DEBUG
+ vd->exponent = exponent;
+ vd->significand = significand;
+ vfp_double_dump("pack: normalised", vd);
+#endif
+
+ /*
+ * Tiny number?
+ */
+ underflow = exponent < 0;
+ if (underflow) {
+ significand = vfp_shiftright64jamming(significand, -exponent);
+ exponent = 0;
+#ifdef DEBUG
+ vd->exponent = exponent;
+ vd->significand = significand;
+ vfp_double_dump("pack: tiny number", vd);
+#endif
+ if (!(significand & ((1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1)))
+ underflow = 0;
+ }
+
+ /*
+ * Select rounding increment.
+ */
+ incr = 0;
+ rmode = fpscr & FPSCR_RMODE_MASK;
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 1ULL << VFP_DOUBLE_LOW_BITS;
+ if ((significand & (1ULL << (VFP_DOUBLE_LOW_BITS + 1))) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vd->sign != 0))
+ incr = (1ULL << (VFP_DOUBLE_LOW_BITS + 1)) - 1;
+
+ pr_debug("VFP: rounding increment = 0x%08llx\n", incr);
+
+ /*
+ * Is our rounding going to overflow?
+ */
+ if ((significand + incr) < significand) {
+ exponent += 1;
+ significand = (significand >> 1) | (significand & 1);
+ incr >>= 1;
+#ifdef DEBUG
+ vd->exponent = exponent;
+ vd->significand = significand;
+ vfp_double_dump("pack: overflow", vd);
+#endif
+ }
+
+ /*
+ * If any of the low bits (which will be shifted out of the
+ * number) are non-zero, the result is inexact.
+ */
+ if (significand & ((1 << (VFP_DOUBLE_LOW_BITS + 1)) - 1))
+ exceptions |= FPSCR_IXC;
+
+ /*
+ * Do our rounding.
+ */
+ significand += incr;
+
+ /*
+ * Infinity?
+ */
+ if (exponent >= 2046) {
+ exceptions |= FPSCR_OFC | FPSCR_IXC;
+ if (incr == 0) {
+ vd->exponent = 2045;
+ vd->significand = 0x7fffffffffffffffULL;
+ } else {
+ vd->exponent = 2047; /* infinity */
+ vd->significand = 0;
+ }
+ } else {
+ if (significand >> (VFP_DOUBLE_LOW_BITS + 1) == 0)
+ exponent = 0;
+ if (exponent || significand > 0x8000000000000000ULL)
+ underflow = 0;
+ if (underflow)
+ exceptions |= FPSCR_UFC;
+ vd->exponent = exponent;
+ vd->significand = significand >> 1;
+ }
+
+ pack:
+ vfp_double_dump("pack: final", vd);
+ {
+ s64 d = vfp_double_pack(vd);
+ pr_debug("VFP: %s: d(d%d)=%016llx exceptions=%08x\n", func,
+ dd, d, exceptions);
+ vfp_put_double(d, dd);
+ }
+ return exceptions;
+}
+
+/*
+ * Propagate the NaN, setting exceptions if it is signalling.
+ * 'n' is always a NaN. 'm' may be a number, NaN or infinity.
+ */
+static u32
+vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn,
+ struct vfp_double *vdm, u32 fpscr)
+{
+ struct vfp_double *nan;
+ int tn, tm = 0;
+
+ tn = vfp_double_type(vdn);
+
+ if (vdm)
+ tm = vfp_double_type(vdm);
+
+ if (fpscr & FPSCR_DEFAULT_NAN)
+ /*
+ * Default NaN mode - always returns a quiet NaN
+ */
+ nan = &vfp_double_default_qnan;
+ else {
+ /*
+ * Contemporary mode - select the first signalling
+ * NAN, or if neither are signalling, the first
+ * quiet NAN.
+ */
+ if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN))
+ nan = vdn;
+ else
+ nan = vdm;
+ /*
+ * Make the NaN quiet.
+ */
+ nan->significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
+ }
+
+ *vdd = *nan;
+
+ /*
+ * If one was a signalling NAN, raise invalid operation.
+ */
+ return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG;
+}
+
+/*
+ * Extended operations
+ */
+static u32 vfp_double_fabs(int dd, int unused, int dm, u32 fpscr)
+{
+ vfp_put_double(vfp_double_packed_abs(vfp_get_double(dm)), dd);
+ return 0;
+}
+
+static u32 vfp_double_fcpy(int dd, int unused, int dm, u32 fpscr)
+{
+ vfp_put_double(vfp_get_double(dm), dd);
+ return 0;
+}
+
+static u32 vfp_double_fneg(int dd, int unused, int dm, u32 fpscr)
+{
+ vfp_put_double(vfp_double_packed_negate(vfp_get_double(dm)), dd);
+ return 0;
+}
+
+static u32 vfp_double_fsqrt(int dd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm, vdd;
+ int ret, tm;
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ tm = vfp_double_type(&vdm);
+ if (tm & (VFP_NAN|VFP_INFINITY)) {
+ struct vfp_double *vdp = &vdd;
+
+ if (tm & VFP_NAN)
+ ret = vfp_propagate_nan(vdp, &vdm, NULL, fpscr);
+ else if (vdm.sign == 0) {
+ sqrt_copy:
+ vdp = &vdm;
+ ret = 0;
+ } else {
+ sqrt_invalid:
+ vdp = &vfp_double_default_qnan;
+ ret = FPSCR_IOC;
+ }
+ vfp_put_double(vfp_double_pack(vdp), dd);
+ return ret;
+ }
+
+ /*
+ * sqrt(+/- 0) == +/- 0
+ */
+ if (tm & VFP_ZERO)
+ goto sqrt_copy;
+
+ /*
+ * Normalise a denormalised number
+ */
+ if (tm & VFP_DENORMAL)
+ vfp_double_normalise_denormal(&vdm);
+
+ /*
+ * sqrt(<0) = invalid
+ */
+ if (vdm.sign)
+ goto sqrt_invalid;
+
+ vfp_double_dump("sqrt", &vdm);
+
+ /*
+ * Estimate the square root.
+ */
+ vdd.sign = 0;
+ vdd.exponent = ((vdm.exponent - 1023) >> 1) + 1023;
+ vdd.significand = (u64)vfp_estimate_sqrt_significand(vdm.exponent, vdm.significand >> 32) << 31;
+
+ vfp_double_dump("sqrt estimate1", &vdd);
+
+ vdm.significand >>= 1 + (vdm.exponent & 1);
+ vdd.significand += 2 + vfp_estimate_div128to64(vdm.significand, 0, vdd.significand);
+
+ vfp_double_dump("sqrt estimate2", &vdd);
+
+ /*
+ * And now adjust.
+ */
+ if ((vdd.significand & VFP_DOUBLE_LOW_BITS_MASK) <= 5) {
+ if (vdd.significand < 2) {
+ vdd.significand = ~0ULL;
+ } else {
+ u64 termh, terml, remh, reml;
+ vdm.significand <<= 2;
+ mul64to128(&termh, &terml, vdd.significand, vdd.significand);
+ sub128(&remh, &reml, vdm.significand, 0, termh, terml);
+ while ((s64)remh < 0) {
+ vdd.significand -= 1;
+ shift64left(&termh, &terml, vdd.significand);
+ terml |= 1;
+ add128(&remh, &reml, remh, reml, termh, terml);
+ }
+ vdd.significand |= (remh | reml) != 0;
+ }
+ }
+ vdd.significand = vfp_shiftright64jamming(vdd.significand, 1);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fsqrt");
+}
+
+/*
+ * Equal := ZC
+ * Less than := N
+ * Greater than := C
+ * Unordered := CV
+ */
+static u32 vfp_compare(int dd, int signal_on_qnan, int dm, u32 fpscr)
+{
+ s64 d, m;
+ u32 ret = 0;
+
+ m = vfp_get_double(dm);
+ if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) {
+ ret |= FPSCR_C | FPSCR_V;
+ if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1))))
+ /*
+ * Signalling NaN, or signalling on quiet NaN
+ */
+ ret |= FPSCR_IOC;
+ }
+
+ d = vfp_get_double(dd);
+ if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) {
+ ret |= FPSCR_C | FPSCR_V;
+ if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1))))
+ /*
+ * Signalling NaN, or signalling on quiet NaN
+ */
+ ret |= FPSCR_IOC;
+ }
+
+ if (ret == 0) {
+ if (d == m || vfp_double_packed_abs(d | m) == 0) {
+ /*
+ * equal
+ */
+ ret |= FPSCR_Z | FPSCR_C;
+ } else if (vfp_double_packed_sign(d ^ m)) {
+ /*
+ * different signs
+ */
+ if (vfp_double_packed_sign(d))
+ /*
+ * d is negative, so d < m
+ */
+ ret |= FPSCR_N;
+ else
+ /*
+ * d is positive, so d > m
+ */
+ ret |= FPSCR_C;
+ } else if ((vfp_double_packed_sign(d) != 0) ^ (d < m)) {
+ /*
+ * d < m
+ */
+ ret |= FPSCR_N;
+ } else if ((vfp_double_packed_sign(d) != 0) ^ (d > m)) {
+ /*
+ * d > m
+ */
+ ret |= FPSCR_C;
+ }
+ }
+
+ return ret;
+}
+
+static u32 vfp_double_fcmp(int dd, int unused, int dm, u32 fpscr)
+{
+ return vfp_compare(dd, 0, dm, fpscr);
+}
+
+static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr)
+{
+ return vfp_compare(dd, 1, dm, fpscr);
+}
+
+static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr)
+{
+ return vfp_compare(dd, 0, VFP_REG_ZERO, fpscr);
+}
+
+static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr)
+{
+ return vfp_compare(dd, 1, VFP_REG_ZERO, fpscr);
+}
+
+static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm;
+ struct vfp_single vsd;
+ int tm;
+ u32 exceptions = 0;
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+
+ tm = vfp_double_type(&vdm);
+
+ /*
+ * If we have a signalling NaN, signal invalid operation.
+ */
+ if (tm == VFP_SNAN)
+ exceptions = FPSCR_IOC;
+
+ if (tm & VFP_DENORMAL)
+ vfp_double_normalise_denormal(&vdm);
+
+ vsd.sign = vdm.sign;
+ vsd.significand = vfp_hi64to32jamming(vdm.significand);
+
+ /*
+ * If we have an infinity or a NaN, the exponent must be 255
+ */
+ if (tm & (VFP_INFINITY|VFP_NAN)) {
+ vsd.exponent = 255;
+ if (tm == VFP_QNAN)
+ vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
+ goto pack_nan;
+ } else if (tm & VFP_ZERO)
+ vsd.exponent = 0;
+ else
+ vsd.exponent = vdm.exponent - (1023 - 127);
+
+ return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fcvts");
+
+ pack_nan:
+ vfp_put_float(vfp_single_pack(&vsd), sd);
+ return exceptions;
+}
+
+static u32 vfp_double_fuito(int dd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm;
+ u32 m = vfp_get_float(dm);
+
+ vdm.sign = 0;
+ vdm.exponent = 1023 + 63 - 1;
+ vdm.significand = (u64)m;
+
+ return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fuito");
+}
+
+static u32 vfp_double_fsito(int dd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm;
+ u32 m = vfp_get_float(dm);
+
+ vdm.sign = (m & 0x80000000) >> 16;
+ vdm.exponent = 1023 + 63 - 1;
+ vdm.significand = vdm.sign ? -m : m;
+
+ return vfp_double_normaliseround(dd, &vdm, fpscr, 0, "fsito");
+}
+
+static u32 vfp_double_ftoui(int sd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm;
+ u32 d, exceptions = 0;
+ int rmode = fpscr & FPSCR_RMODE_MASK;
+ int tm;
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+
+ /*
+ * Do we have a denormalised number?
+ */
+ tm = vfp_double_type(&vdm);
+ if (tm & VFP_DENORMAL)
+ exceptions |= FPSCR_IDC;
+
+ if (tm & VFP_NAN)
+ vdm.sign = 0;
+
+ if (vdm.exponent >= 1023 + 32) {
+ d = vdm.sign ? 0 : 0xffffffff;
+ exceptions = FPSCR_IOC;
+ } else if (vdm.exponent >= 1023 - 1) {
+ int shift = 1023 + 63 - vdm.exponent;
+ u64 rem, incr = 0;
+
+ /*
+ * 2^0 <= m < 2^32-2^8
+ */
+ d = (vdm.significand << 1) >> shift;
+ rem = vdm.significand << (65 - shift);
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 0x8000000000000000ULL;
+ if ((d & 1) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) {
+ incr = ~0ULL;
+ }
+
+ if ((rem + incr) < rem) {
+ if (d < 0xffffffff)
+ d += 1;
+ else
+ exceptions |= FPSCR_IOC;
+ }
+
+ if (d && vdm.sign) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ } else if (rem)
+ exceptions |= FPSCR_IXC;
+ } else {
+ d = 0;
+ if (vdm.exponent | vdm.significand) {
+ exceptions |= FPSCR_IXC;
+ if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0)
+ d = 1;
+ else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ }
+ }
+ }
+
+ pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
+
+ vfp_put_float(d, sd);
+
+ return exceptions;
+}
+
+static u32 vfp_double_ftouiz(int sd, int unused, int dm, u32 fpscr)
+{
+ return vfp_double_ftoui(sd, unused, dm, FPSCR_ROUND_TOZERO);
+}
+
+static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
+{
+ struct vfp_double vdm;
+ u32 d, exceptions = 0;
+ int rmode = fpscr & FPSCR_RMODE_MASK;
+ int tm;
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ vfp_double_dump("VDM", &vdm);
+
+ /*
+ * Do we have denormalised number?
+ */
+ tm = vfp_double_type(&vdm);
+ if (tm & VFP_DENORMAL)
+ exceptions |= FPSCR_IDC;
+
+ if (tm & VFP_NAN) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ } else if (vdm.exponent >= 1023 + 32) {
+ d = 0x7fffffff;
+ if (vdm.sign)
+ d = ~d;
+ exceptions |= FPSCR_IOC;
+ } else if (vdm.exponent >= 1023 - 1) {
+ int shift = 1023 + 63 - vdm.exponent; /* 58 */
+ u64 rem, incr = 0;
+
+ d = (vdm.significand << 1) >> shift;
+ rem = vdm.significand << (65 - shift);
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 0x8000000000000000ULL;
+ if ((d & 1) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vdm.sign != 0)) {
+ incr = ~0ULL;
+ }
+
+ if ((rem + incr) < rem && d < 0xffffffff)
+ d += 1;
+ if (d > 0x7fffffff + (vdm.sign != 0)) {
+ d = 0x7fffffff + (vdm.sign != 0);
+ exceptions |= FPSCR_IOC;
+ } else if (rem)
+ exceptions |= FPSCR_IXC;
+
+ if (vdm.sign)
+ d = -d;
+ } else {
+ d = 0;
+ if (vdm.exponent | vdm.significand) {
+ exceptions |= FPSCR_IXC;
+ if (rmode == FPSCR_ROUND_PLUSINF && vdm.sign == 0)
+ d = 1;
+ else if (rmode == FPSCR_ROUND_MINUSINF && vdm.sign)
+ d = -1;
+ }
+ }
+
+ pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
+
+ vfp_put_float((s32)d, sd);
+
+ return exceptions;
+}
+
+static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr)
+{
+ return vfp_double_ftosi(dd, unused, dm, FPSCR_ROUND_TOZERO);
+}
+
+
+static struct op fops_ext[32] = {
+ [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_double_fcpy, 0 },
+ [FEXT_TO_IDX(FEXT_FABS)] = { vfp_double_fabs, 0 },
+ [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_double_fneg, 0 },
+ [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_double_fsqrt, 0 },
+ [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_double_fcmp, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_double_fcmpe, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_double_fcmpz, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_double_fcmpez, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_double_fcvts, OP_SCALAR|OP_SD },
+ [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR|OP_SM },
+ [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR|OP_SM },
+ [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_double_ftoui, OP_SCALAR|OP_SD },
+ [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_double_ftouiz, OP_SCALAR|OP_SD },
+ [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_double_ftosi, OP_SCALAR|OP_SD },
+ [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_double_ftosiz, OP_SCALAR|OP_SD },
+};
+
+
+
+
+static u32
+vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn,
+ struct vfp_double *vdm, u32 fpscr)
+{
+ struct vfp_double *vdp;
+ u32 exceptions = 0;
+ int tn, tm;
+
+ tn = vfp_double_type(vdn);
+ tm = vfp_double_type(vdm);
+
+ if (tn & tm & VFP_INFINITY) {
+ /*
+ * Two infinities. Are they different signs?
+ */
+ if (vdn->sign ^ vdm->sign) {
+ /*
+ * different signs -> invalid
+ */
+ exceptions = FPSCR_IOC;
+ vdp = &vfp_double_default_qnan;
+ } else {
+ /*
+ * same signs -> valid
+ */
+ vdp = vdn;
+ }
+ } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) {
+ /*
+ * One infinity and one number -> infinity
+ */
+ vdp = vdn;
+ } else {
+ /*
+ * 'n' is a NaN of some type
+ */
+ return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
+ }
+ *vdd = *vdp;
+ return exceptions;
+}
+
+static u32
+vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,
+ struct vfp_double *vdm, u32 fpscr)
+{
+ u32 exp_diff;
+ u64 m_sig;
+
+ if (vdn->significand & (1ULL << 63) ||
+ vdm->significand & (1ULL << 63)) {
+ pr_info("VFP: bad FP values in %s\n", __func__);
+ vfp_double_dump("VDN", vdn);
+ vfp_double_dump("VDM", vdm);
+ }
+
+ /*
+ * Ensure that 'n' is the largest magnitude number. Note that
+ * if 'n' and 'm' have equal exponents, we do not swap them.
+ * This ensures that NaN propagation works correctly.
+ */
+ if (vdn->exponent < vdm->exponent) {
+ struct vfp_double *t = vdn;
+ vdn = vdm;
+ vdm = t;
+ }
+
+ /*
+ * Is 'n' an infinity or a NaN? Note that 'm' may be a number,
+ * infinity or a NaN here.
+ */
+ if (vdn->exponent == 2047)
+ return vfp_double_fadd_nonnumber(vdd, vdn, vdm, fpscr);
+
+ /*
+ * We have two proper numbers, where 'vdn' is the larger magnitude.
+ *
+ * Copy 'n' to 'd' before doing the arithmetic.
+ */
+ *vdd = *vdn;
+
+ /*
+ * Align 'm' with the result.
+ */
+ exp_diff = vdn->exponent - vdm->exponent;
+ m_sig = vfp_shiftright64jamming(vdm->significand, exp_diff);
+
+ /*
+ * If the signs are different, we are really subtracting.
+ */
+ if (vdn->sign ^ vdm->sign) {
+ m_sig = vdn->significand - m_sig;
+ if ((s64)m_sig < 0) {
+ vdd->sign = vfp_sign_negate(vdd->sign);
+ m_sig = -m_sig;
+ } else if (m_sig == 0) {
+ vdd->sign = (fpscr & FPSCR_RMODE_MASK) ==
+ FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
+ }
+ } else {
+ m_sig += vdn->significand;
+ }
+ vdd->significand = m_sig;
+
+ return 0;
+}
+
+static u32
+vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn,
+ struct vfp_double *vdm, u32 fpscr)
+{
+ vfp_double_dump("VDN", vdn);
+ vfp_double_dump("VDM", vdm);
+
+ /*
+ * Ensure that 'n' is the largest magnitude number. Note that
+ * if 'n' and 'm' have equal exponents, we do not swap them.
+ * This ensures that NaN propagation works correctly.
+ */
+ if (vdn->exponent < vdm->exponent) {
+ struct vfp_double *t = vdn;
+ vdn = vdm;
+ vdm = t;
+ pr_debug("VFP: swapping M <-> N\n");
+ }
+
+ vdd->sign = vdn->sign ^ vdm->sign;
+
+ /*
+ * If 'n' is an infinity or NaN, handle it. 'm' may be anything.
+ */
+ if (vdn->exponent == 2047) {
+ if (vdn->significand || (vdm->exponent == 2047 && vdm->significand))
+ return vfp_propagate_nan(vdd, vdn, vdm, fpscr);
+ if ((vdm->exponent | vdm->significand) == 0) {
+ *vdd = vfp_double_default_qnan;
+ return FPSCR_IOC;
+ }
+ vdd->exponent = vdn->exponent;
+ vdd->significand = 0;
+ return 0;
+ }
+
+ /*
+ * If 'm' is zero, the result is always zero. In this case,
+ * 'n' may be zero or a number, but it doesn't matter which.
+ */
+ if ((vdm->exponent | vdm->significand) == 0) {
+ vdd->exponent = 0;
+ vdd->significand = 0;
+ return 0;
+ }
+
+ /*
+ * We add 2 to the destination exponent for the same reason
+ * as the addition case - though this time we have +1 from
+ * each input operand.
+ */
+ vdd->exponent = vdn->exponent + vdm->exponent - 1023 + 2;
+ vdd->significand = vfp_hi64multiply64(vdn->significand, vdm->significand);
+
+ vfp_double_dump("VDD", vdd);
+ return 0;
+}
+
+#define NEG_MULTIPLY (1 << 0)
+#define NEG_SUBTRACT (1 << 1)
+
+static u32
+vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, char *func)
+{
+ struct vfp_double vdd, vdp, vdn, vdm;
+ u32 exceptions;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ if (vdm.exponent == 0 && vdm.significand)
+ vfp_double_normalise_denormal(&vdm);
+
+ exceptions = vfp_double_multiply(&vdp, &vdn, &vdm, fpscr);
+ if (negate & NEG_MULTIPLY)
+ vdp.sign = vfp_sign_negate(vdp.sign);
+
+ vfp_double_unpack(&vdn, vfp_get_double(dd));
+ if (negate & NEG_SUBTRACT)
+ vdn.sign = vfp_sign_negate(vdn.sign);
+
+ exceptions |= vfp_double_add(&vdd, &vdn, &vdp, fpscr);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, func);
+}
+
+/*
+ * Standard operations
+ */
+
+/*
+ * sd = sd + (sn * sm)
+ */
+static u32 vfp_double_fmac(int dd, int dn, int dm, u32 fpscr)
+{
+ return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, 0, "fmac");
+}
+
+/*
+ * sd = sd - (sn * sm)
+ */
+static u32 vfp_double_fnmac(int dd, int dn, int dm, u32 fpscr)
+{
+ return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac");
+}
+
+/*
+ * sd = -sd + (sn * sm)
+ */
+static u32 vfp_double_fmsc(int dd, int dn, int dm, u32 fpscr)
+{
+ return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc");
+}
+
+/*
+ * sd = -sd - (sn * sm)
+ */
+static u32 vfp_double_fnmsc(int dd, int dn, int dm, u32 fpscr)
+{
+ return vfp_double_multiply_accumulate(dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc");
+}
+
+/*
+ * sd = sn * sm
+ */
+static u32 vfp_double_fmul(int dd, int dn, int dm, u32 fpscr)
+{
+ struct vfp_double vdd, vdn, vdm;
+ u32 exceptions;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ if (vdm.exponent == 0 && vdm.significand)
+ vfp_double_normalise_denormal(&vdm);
+
+ exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fmul");
+}
+
+/*
+ * sd = -(sn * sm)
+ */
+static u32 vfp_double_fnmul(int dd, int dn, int dm, u32 fpscr)
+{
+ struct vfp_double vdd, vdn, vdm;
+ u32 exceptions;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ if (vdm.exponent == 0 && vdm.significand)
+ vfp_double_normalise_denormal(&vdm);
+
+ exceptions = vfp_double_multiply(&vdd, &vdn, &vdm, fpscr);
+ vdd.sign = vfp_sign_negate(vdd.sign);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fnmul");
+}
+
+/*
+ * sd = sn + sm
+ */
+static u32 vfp_double_fadd(int dd, int dn, int dm, u32 fpscr)
+{
+ struct vfp_double vdd, vdn, vdm;
+ u32 exceptions;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ if (vdm.exponent == 0 && vdm.significand)
+ vfp_double_normalise_denormal(&vdm);
+
+ exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fadd");
+}
+
+/*
+ * sd = sn - sm
+ */
+static u32 vfp_double_fsub(int dd, int dn, int dm, u32 fpscr)
+{
+ struct vfp_double vdd, vdn, vdm;
+ u32 exceptions;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ if (vdn.exponent == 0 && vdn.significand)
+ vfp_double_normalise_denormal(&vdn);
+
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+ if (vdm.exponent == 0 && vdm.significand)
+ vfp_double_normalise_denormal(&vdm);
+
+ /*
+ * Subtraction is like addition, but with a negated operand.
+ */
+ vdm.sign = vfp_sign_negate(vdm.sign);
+
+ exceptions = vfp_double_add(&vdd, &vdn, &vdm, fpscr);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fsub");
+}
+
+/*
+ * sd = sn / sm
+ */
+static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr)
+{
+ struct vfp_double vdd, vdn, vdm;
+ u32 exceptions = 0;
+ int tm, tn;
+
+ vfp_double_unpack(&vdn, vfp_get_double(dn));
+ vfp_double_unpack(&vdm, vfp_get_double(dm));
+
+ vdd.sign = vdn.sign ^ vdm.sign;
+
+ tn = vfp_double_type(&vdn);
+ tm = vfp_double_type(&vdm);
+
+ /*
+ * Is n a NAN?
+ */
+ if (tn & VFP_NAN)
+ goto vdn_nan;
+
+ /*
+ * Is m a NAN?
+ */
+ if (tm & VFP_NAN)
+ goto vdm_nan;
+
+ /*
+ * If n and m are infinity, the result is invalid
+ * If n and m are zero, the result is invalid
+ */
+ if (tm & tn & (VFP_INFINITY|VFP_ZERO))
+ goto invalid;
+
+ /*
+ * If n is infinity, the result is infinity
+ */
+ if (tn & VFP_INFINITY)
+ goto infinity;
+
+ /*
+ * If m is zero, raise div0 exceptions
+ */
+ if (tm & VFP_ZERO)
+ goto divzero;
+
+ /*
+ * If m is infinity, or n is zero, the result is zero
+ */
+ if (tm & VFP_INFINITY || tn & VFP_ZERO)
+ goto zero;
+
+ if (tn & VFP_DENORMAL)
+ vfp_double_normalise_denormal(&vdn);
+ if (tm & VFP_DENORMAL)
+ vfp_double_normalise_denormal(&vdm);
+
+ /*
+ * Ok, we have two numbers, we can perform division.
+ */
+ vdd.exponent = vdn.exponent - vdm.exponent + 1023 - 1;
+ vdm.significand <<= 1;
+ if (vdm.significand <= (2 * vdn.significand)) {
+ vdn.significand >>= 1;
+ vdd.exponent++;
+ }
+ vdd.significand = vfp_estimate_div128to64(vdn.significand, 0, vdm.significand);
+ if ((vdd.significand & 0x1ff) <= 2) {
+ u64 termh, terml, remh, reml;
+ mul64to128(&termh, &terml, vdm.significand, vdd.significand);
+ sub128(&remh, &reml, vdn.significand, 0, termh, terml);
+ while ((s64)remh < 0) {
+ vdd.significand -= 1;
+ add128(&remh, &reml, remh, reml, 0, vdm.significand);
+ }
+ vdd.significand |= (reml != 0);
+ }
+ return vfp_double_normaliseround(dd, &vdd, fpscr, 0, "fdiv");
+
+ vdn_nan:
+ exceptions = vfp_propagate_nan(&vdd, &vdn, &vdm, fpscr);
+ pack:
+ vfp_put_double(vfp_double_pack(&vdd), dd);
+ return exceptions;
+
+ vdm_nan:
+ exceptions = vfp_propagate_nan(&vdd, &vdm, &vdn, fpscr);
+ goto pack;
+
+ zero:
+ vdd.exponent = 0;
+ vdd.significand = 0;
+ goto pack;
+
+ divzero:
+ exceptions = FPSCR_DZC;
+ infinity:
+ vdd.exponent = 2047;
+ vdd.significand = 0;
+ goto pack;
+
+ invalid:
+ vfp_put_double(vfp_double_pack(&vfp_double_default_qnan), dd);
+ return FPSCR_IOC;
+}
+
+static struct op fops[16] = {
+ [FOP_TO_IDX(FOP_FMAC)] = { vfp_double_fmac, 0 },
+ [FOP_TO_IDX(FOP_FNMAC)] = { vfp_double_fnmac, 0 },
+ [FOP_TO_IDX(FOP_FMSC)] = { vfp_double_fmsc, 0 },
+ [FOP_TO_IDX(FOP_FNMSC)] = { vfp_double_fnmsc, 0 },
+ [FOP_TO_IDX(FOP_FMUL)] = { vfp_double_fmul, 0 },
+ [FOP_TO_IDX(FOP_FNMUL)] = { vfp_double_fnmul, 0 },
+ [FOP_TO_IDX(FOP_FADD)] = { vfp_double_fadd, 0 },
+ [FOP_TO_IDX(FOP_FSUB)] = { vfp_double_fsub, 0 },
+ [FOP_TO_IDX(FOP_FDIV)] = { vfp_double_fdiv, 0 },
+};
+
+#define FREG_BANK(x) ((x) & 0x0c)
+#define FREG_IDX(x) ((x) & 3)
+
+u32 vfp_double_cpdo(u32 inst, u32 fpscr)
+{
+ u32 op = inst & FOP_MASK;
+ u32 exceptions = 0;
+ unsigned int dest;
+ unsigned int dn = vfp_get_dn(inst);
+ unsigned int dm;
+ unsigned int vecitr, veclen, vecstride;
+ struct op *fop;
+
+ vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK));
+
+ fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
+
+ /*
+ * fcvtds takes an sN register number as destination, not dN.
+ * It also always operates on scalars.
+ */
+ if (fop->flags & OP_SD)
+ dest = vfp_get_sd(inst);
+ else
+ dest = vfp_get_dd(inst);
+
+ /*
+ * f[us]ito takes a sN operand, not a dN operand.
+ */
+ if (fop->flags & OP_SM)
+ dm = vfp_get_sm(inst);
+ else
+ dm = vfp_get_dm(inst);
+
+ /*
+ * If destination bank is zero, vector length is always '1'.
+ * ARM DDI0100F C5.1.3, C5.3.2.
+ */
+ if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0))
+ veclen = 0;
+ else
+ veclen = fpscr & FPSCR_LENGTH_MASK;
+
+ pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
+ (veclen >> FPSCR_LENGTH_BIT) + 1);
+
+ if (!fop->fn)
+ goto invalid;
+
+ for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
+ u32 except;
+ char type;
+
+ type = fop->flags & OP_SD ? 's' : 'd';
+ if (op == FOP_EXT)
+ pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n",
+ vecitr >> FPSCR_LENGTH_BIT,
+ type, dest, dn, dm);
+ else
+ pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n",
+ vecitr >> FPSCR_LENGTH_BIT,
+ type, dest, dn, FOP_TO_IDX(op), dm);
+
+ except = fop->fn(dest, dn, dm, fpscr);
+ pr_debug("VFP: itr%d: exceptions=%08x\n",
+ vecitr >> FPSCR_LENGTH_BIT, except);
+
+ exceptions |= except;
+
+ /*
+ * CHECK: It appears to be undefined whether we stop when
+ * we encounter an exception. We continue.
+ */
+ dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 3);
+ dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 3);
+ if (FREG_BANK(dm) != 0)
+ dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 3);
+ }
+ return exceptions;
+
+ invalid:
+ return ~0;
+}
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
new file mode 100644
index 00000000..404538ae
--- /dev/null
+++ b/arch/arm/vfp/vfphw.S
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/arm/vfp/vfphw.S
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can 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 code is called from the kernel's undefined instruction trap.
+ * r9 holds the return address for successful handling.
+ * lr holds the return address for unrecognised instructions.
+ * r10 points at the start of the private FP workspace in the thread structure
+ * sp points to a struct pt_regs (as defined in include/asm/proc/ptrace.h)
+ */
+#include <asm/thread_info.h>
+#include <asm/vfpmacros.h>
+#include "../kernel/entry-header.S"
+
+ .macro DBGSTR, str
+#ifdef DEBUG
+ stmfd sp!, {r0-r3, ip, lr}
+ add r0, pc, #4
+ bl printk
+ b 1f
+ .asciz "<7>VFP: \str\n"
+ .balign 4
+1: ldmfd sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro DBGSTR1, str, arg
+#ifdef DEBUG
+ stmfd sp!, {r0-r3, ip, lr}
+ mov r1, \arg
+ add r0, pc, #4
+ bl printk
+ b 1f
+ .asciz "<7>VFP: \str\n"
+ .balign 4
+1: ldmfd sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+ .macro DBGSTR3, str, arg1, arg2, arg3
+#ifdef DEBUG
+ stmfd sp!, {r0-r3, ip, lr}
+ mov r3, \arg3
+ mov r2, \arg2
+ mov r1, \arg1
+ add r0, pc, #4
+ bl printk
+ b 1f
+ .asciz "<7>VFP: \str\n"
+ .balign 4
+1: ldmfd sp!, {r0-r3, ip, lr}
+#endif
+ .endm
+
+
+@ VFP hardware support entry point.
+@
+@ r0 = faulted instruction
+@ r2 = faulted PC+4
+@ r9 = successful return
+@ r10 = vfp_state union
+@ r11 = CPU number
+@ lr = failure return
+
+ENTRY(vfp_support_entry)
+ DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10
+
+ VFPFMRX r1, FPEXC @ Is the VFP enabled?
+ DBGSTR1 "fpexc %08x", r1
+ tst r1, #FPEXC_EN
+ bne look_for_VFP_exceptions @ VFP is already enabled
+
+ DBGSTR1 "enable %x", r10
+ 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] @ vfp_current_hw_state pointer
+ bic r5, r1, #FPEXC_EX @ make sure exceptions are disabled
+ 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
+ @ rest of it
+
+#ifndef CONFIG_SMP
+ @ Save out the current registers to the old thread state
+ @ No need for SMP since this is not done lazily
+
+ DBGSTR1 "save old state %p", r4
+ cmp r4, #0
+ beq no_old_VFP_process
+ VFPFSTMIA r4, r5 @ save the working registers
+ VFPFMRX r5, FPSCR @ current status
+#ifndef CONFIG_CPU_FEROCEON
+ tst r1, #FPEXC_EX @ is there additional state to save?
+ beq 1f
+ VFPFMRX r6, FPINST @ FPINST (only if FPEXC.EX is set)
+ tst r1, #FPEXC_FP2V @ is there an FPINST2 to read?
+ beq 1f
+ VFPFMRX r8, FPINST2 @ FPINST2 if needed (and present)
+1:
+#endif
+ stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2
+ @ and point r4 at the word at the
+ @ start of the register dump
+#endif
+
+no_old_VFP_process:
+ DBGSTR1 "load state %p", r10
+ 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
+ ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2
+#ifndef CONFIG_CPU_FEROCEON
+ tst r1, #FPEXC_EX @ is there additional state to restore?
+ beq 1f
+ VFPFMXR FPINST, r6 @ restore FPINST (only if FPEXC.EX is set)
+ tst r1, #FPEXC_FP2V @ is there an FPINST2 to write?
+ beq 1f
+ VFPFMXR FPINST2, r8 @ FPINST2 if needed (and present)
+1:
+#endif
+ VFPFMXR FPSCR, r5 @ restore status
+
+@ 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
+ @ out before setting an FPEXC that
+ @ stops us reading stuff
+ VFPFMXR FPEXC, r1 @ restore FPEXC last
+ sub r2, r2, #4
+ str r2, [sp, #S_PC] @ retry the instruction
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
+ mov pc, r9 @ we think we have handled things
+
+
+look_for_VFP_exceptions:
+ @ Check for synchronous or asynchronous exception
+ tst r1, #FPEXC_EX | FPEXC_DEX
+ bne process_exception
+ @ On some implementations of the VFP subarch 1, setting FPSCR.IXE
+ @ causes all the CDP instructions to be bounced synchronously without
+ @ setting the FPEXC.EX bit
+ VFPFMRX r5, FPSCR
+ tst r5, #FPSCR_IXE
+ bne process_exception
+
+ @ Fall into hand on to next handler - appropriate coproc instr
+ @ not recognised by VFP
+
+ DBGSTR "not VFP"
+#ifdef CONFIG_PREEMPT
+ get_thread_info r10
+ ldr r4, [r10, #TI_PREEMPT] @ get preempt count
+ sub r11, r4, #1 @ decrement it
+ str r11, [r10, #TI_PREEMPT]
+#endif
+ mov pc, lr
+
+process_exception:
+ DBGSTR "bounce"
+ mov r2, sp @ nothing stacked - regdump is at TOS
+ mov lr, r9 @ setup for a return to the user code.
+
+ @ Now call the C code to package up the bounce to the support code
+ @ r0 holds the trigger instruction
+ @ r1 holds the FPEXC value
+ @ r2 pointer to register dump
+ b VFP_bounce @ we have handled this - the support
+ @ code will raise an exception if
+ @ required. If not, the user code will
+ @ retry the faulted instruction
+ENDPROC(vfp_support_entry)
+
+ENTRY(vfp_save_state)
+ @ Save the current VFP state
+ @ r0 - save location
+ @ r1 - FPEXC
+ DBGSTR1 "save VFP state %p", r0
+ VFPFSTMIA r0, r2 @ save the working registers
+ VFPFMRX r2, FPSCR @ current status
+ tst r1, #FPEXC_EX @ is there additional state to save?
+ beq 1f
+ VFPFMRX r3, FPINST @ FPINST (only if FPEXC.EX is set)
+ tst r1, #FPEXC_FP2V @ is there an FPINST2 to read?
+ beq 1f
+ VFPFMRX r12, FPINST2 @ FPINST2 if needed (and present)
+1:
+ stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2
+ mov pc, lr
+ENDPROC(vfp_save_state)
+
+ .align
+vfp_current_hw_state_address:
+ .word vfp_current_hw_state
+
+ .macro tbl_branch, base, tmp, shift
+#ifdef CONFIG_THUMB2_KERNEL
+ adr \tmp, 1f
+ add \tmp, \tmp, \base, lsl \shift
+ mov pc, \tmp
+#else
+ add pc, pc, \base, lsl \shift
+ mov r0, r0
+#endif
+1:
+ .endm
+
+ENTRY(vfp_get_float)
+ tbl_branch r0, r3, #3
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0
+ mov pc, lr
+ .org 1b + 8
+1: mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1
+ mov pc, lr
+ .org 1b + 8
+ .endr
+ENDPROC(vfp_get_float)
+
+ENTRY(vfp_put_float)
+ tbl_branch r1, r3, #3
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0
+ mov pc, lr
+ .org 1b + 8
+1: mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1
+ mov pc, lr
+ .org 1b + 8
+ .endr
+ENDPROC(vfp_put_float)
+
+ENTRY(vfp_get_double)
+ tbl_branch r0, r3, #3
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: fmrrd r0, r1, d\dr
+ mov pc, lr
+ .org 1b + 8
+ .endr
+#ifdef CONFIG_VFPv3
+ @ d16 - d31 registers
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr
+ mov pc, lr
+ .org 1b + 8
+ .endr
+#endif
+
+ @ virtual register 16 (or 32 if VFPv3) for compare with zero
+ mov r0, #0
+ mov r1, #0
+ mov pc, lr
+ENDPROC(vfp_get_double)
+
+ENTRY(vfp_put_double)
+ tbl_branch r2, r3, #3
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: fmdrr d\dr, r0, r1
+ mov pc, lr
+ .org 1b + 8
+ .endr
+#ifdef CONFIG_VFPv3
+ @ d16 - d31 registers
+ .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
+1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr
+ mov pc, lr
+ .org 1b + 8
+ .endr
+#endif
+ENDPROC(vfp_put_double)
diff --git a/arch/arm/vfp/vfpinstr.h b/arch/arm/vfp/vfpinstr.h
new file mode 100644
index 00000000..15b95b5a
--- /dev/null
+++ b/arch/arm/vfp/vfpinstr.h
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/vfp/vfpinstr.h
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * VFP instruction masks.
+ */
+#define INST_CPRTDO(inst) (((inst) & 0x0f000000) == 0x0e000000)
+#define INST_CPRT(inst) ((inst) & (1 << 4))
+#define INST_CPRT_L(inst) ((inst) & (1 << 20))
+#define INST_CPRT_Rd(inst) (((inst) & (15 << 12)) >> 12)
+#define INST_CPRT_OP(inst) (((inst) >> 21) & 7)
+#define INST_CPNUM(inst) ((inst) & 0xf00)
+#define CPNUM(cp) ((cp) << 8)
+
+#define FOP_MASK (0x00b00040)
+#define FOP_FMAC (0x00000000)
+#define FOP_FNMAC (0x00000040)
+#define FOP_FMSC (0x00100000)
+#define FOP_FNMSC (0x00100040)
+#define FOP_FMUL (0x00200000)
+#define FOP_FNMUL (0x00200040)
+#define FOP_FADD (0x00300000)
+#define FOP_FSUB (0x00300040)
+#define FOP_FDIV (0x00800000)
+#define FOP_EXT (0x00b00040)
+
+#define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4)
+
+#define FEXT_MASK (0x000f0080)
+#define FEXT_FCPY (0x00000000)
+#define FEXT_FABS (0x00000080)
+#define FEXT_FNEG (0x00010000)
+#define FEXT_FSQRT (0x00010080)
+#define FEXT_FCMP (0x00040000)
+#define FEXT_FCMPE (0x00040080)
+#define FEXT_FCMPZ (0x00050000)
+#define FEXT_FCMPEZ (0x00050080)
+#define FEXT_FCVT (0x00070080)
+#define FEXT_FUITO (0x00080000)
+#define FEXT_FSITO (0x00080080)
+#define FEXT_FTOUI (0x000c0000)
+#define FEXT_FTOUIZ (0x000c0080)
+#define FEXT_FTOSI (0x000d0000)
+#define FEXT_FTOSIZ (0x000d0080)
+
+#define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
+
+#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22)
+#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18)
+#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5)
+#define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1)
+#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7)
+#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3)
+
+#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00)
+
+#define FPSCR_N (1 << 31)
+#define FPSCR_Z (1 << 30)
+#define FPSCR_C (1 << 29)
+#define FPSCR_V (1 << 28)
+
+/*
+ * Since we aren't building with -mfpu=vfp, we need to code
+ * these instructions using their MRC/MCR equivalents.
+ */
+#define vfpreg(_vfp_) #_vfp_
+
+#define fmrx(_vfp_) ({ \
+ u32 __v; \
+ asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \
+ : "=r" (__v) : : "cc"); \
+ __v; \
+ })
+
+#define fmxr(_vfp_,_var_) \
+ asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \
+ : : "r" (_var_) : "cc")
+
+u32 vfp_single_cpdo(u32 inst, u32 fpscr);
+u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs);
+
+u32 vfp_double_cpdo(u32 inst, u32 fpscr);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
new file mode 100644
index 00000000..2bd4980b
--- /dev/null
+++ b/arch/arm/vfp/vfpmodule.c
@@ -0,0 +1,613 @@
+/*
+ * linux/arch/arm/vfp/vfpmodule.c
+ *
+ * Copyright (C) 2004 ARM Limited.
+ * Written by Deep Blue Solutions Limited.
+ *
+ * This program is free software; you can 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/types.h>
+#include <linux/cpu.h>
+#include <linux/hardirq.h>
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+
+#include <asm/cputype.h>
+#include <asm/thread_notify.h>
+#include <asm/vfp.h>
+
+#include "vfpinstr.h"
+#include "vfp.h"
+
+/*
+ * Our undef handlers (in entry.S)
+ */
+void vfp_testing_entry(void);
+void vfp_support_entry(void);
+void vfp_null_entry(void);
+
+void (*vfp_vector)(void) = vfp_null_entry;
+
+/*
+ * 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.
+ * Used in startup: set to non-zero if VFP checks fail
+ * After startup, holds VFP architecture
+ */
+unsigned int VFP_arch;
+
+/*
+ * Per-thread VFP initialization.
+ */
+static void vfp_thread_flush(struct thread_info *thread)
+{
+ union vfp_state *vfp = &thread->vfpstate;
+ unsigned int cpu;
+
+ memset(vfp, 0, sizeof(union vfp_state));
+
+ vfp->hard.fpexc = FPEXC_EN;
+ vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
+
+ /*
+ * Disable VFP to ensure we initialize it first. We must ensure
+ * that the modification of vfp_current_hw_state[] and hardware disable
+ * are done for the same CPU and without preemption.
+ */
+ cpu = get_cpu();
+ if (vfp_current_hw_state[cpu] == vfp)
+ vfp_current_hw_state[cpu] = NULL;
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ put_cpu();
+}
+
+static void vfp_thread_exit(struct thread_info *thread)
+{
+ /* release case: Per-thread VFP cleanup. */
+ union vfp_state *vfp = &thread->vfpstate;
+ unsigned int cpu = get_cpu();
+
+ if (vfp_current_hw_state[cpu] == vfp)
+ vfp_current_hw_state[cpu] = NULL;
+ put_cpu();
+}
+
+static void vfp_thread_copy(struct thread_info *thread)
+{
+ struct thread_info *parent = current_thread_info();
+
+ vfp_sync_hwstate(parent);
+ thread->vfpstate = parent->vfpstate;
+}
+
+/*
+ * When this function is called with the following 'cmd's, the following
+ * is true while this function is being run:
+ * THREAD_NOFTIFY_SWTICH:
+ * - the previously running thread will not be scheduled onto another CPU.
+ * - the next thread to be run (v) will not be running on another CPU.
+ * - thread->cpu is the local CPU number
+ * - not preemptible as we're called in the middle of a thread switch
+ * THREAD_NOTIFY_FLUSH:
+ * - the thread (v) will be running on the local CPU, so
+ * v === current_thread_info()
+ * - thread->cpu is the local CPU number at the time it is accessed,
+ * but may change at any time.
+ * - we could be preempted if tree preempt rcu is enabled, so
+ * it is unsafe to use thread->cpu.
+ * THREAD_NOTIFY_EXIT
+ * - the thread (v) will be running on the local CPU, so
+ * v === current_thread_info()
+ * - thread->cpu is the local CPU number at the time it is accessed,
+ * but may change at any time.
+ * - we could be preempted if tree preempt rcu is enabled, so
+ * it is unsafe to use thread->cpu.
+ */
+static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ struct thread_info *thread = v;
+ u32 fpexc;
+#ifdef CONFIG_SMP
+ unsigned int cpu;
+#endif
+
+ switch (cmd) {
+ case THREAD_NOTIFY_SWITCH:
+ fpexc = fmrx(FPEXC);
+
+#ifdef CONFIG_SMP
+ cpu = thread->cpu;
+
+ /*
+ * On SMP, if VFP is enabled, save the old state in
+ * case the thread migrates to a different CPU. The
+ * restoring is done lazily.
+ */
+ 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
+ * state on the new CPU in case the VFP registers
+ * contain stale data.
+ */
+ if (thread->vfpstate.hard.cpu != cpu)
+ vfp_current_hw_state[cpu] = NULL;
+#endif
+
+ /*
+ * Always disable VFP so we can lazily save/restore the
+ * old state.
+ */
+ fmxr(FPEXC, fpexc & ~FPEXC_EN);
+ break;
+
+ case THREAD_NOTIFY_FLUSH:
+ vfp_thread_flush(thread);
+ break;
+
+ case THREAD_NOTIFY_EXIT:
+ vfp_thread_exit(thread);
+ break;
+
+ case THREAD_NOTIFY_COPY:
+ vfp_thread_copy(thread);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vfp_notifier_block = {
+ .notifier_call = vfp_notifier,
+};
+
+/*
+ * Raise a SIGFPE for the current process.
+ * sicode describes the signal being raised.
+ */
+static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
+{
+ siginfo_t info;
+
+ memset(&info, 0, sizeof(info));
+
+ info.si_signo = SIGFPE;
+ info.si_code = sicode;
+ info.si_addr = (void __user *)(instruction_pointer(regs) - 4);
+
+ /*
+ * This is the same as NWFPE, because it's not clear what
+ * this is used for
+ */
+ current->thread.error_code = 0;
+ current->thread.trap_no = 6;
+
+ send_sig_info(SIGFPE, &info, current);
+}
+
+static void vfp_panic(char *reason, u32 inst)
+{
+ int i;
+
+ printk(KERN_ERR "VFP: Error: %s\n", reason);
+ printk(KERN_ERR "VFP: EXC 0x%08x SCR 0x%08x INST 0x%08x\n",
+ fmrx(FPEXC), fmrx(FPSCR), inst);
+ for (i = 0; i < 32; i += 2)
+ printk(KERN_ERR "VFP: s%2u: 0x%08x s%2u: 0x%08x\n",
+ i, vfp_get_float(i), i+1, vfp_get_float(i+1));
+}
+
+/*
+ * Process bitmask of exception conditions.
+ */
+static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_regs *regs)
+{
+ int si_code = 0;
+
+ pr_debug("VFP: raising exceptions %08x\n", exceptions);
+
+ if (exceptions == VFP_EXCEPTION_ERROR) {
+ vfp_panic("unhandled bounce", inst);
+ vfp_raise_sigfpe(0, regs);
+ return;
+ }
+
+ /*
+ * If any of the status flags are set, update the FPSCR.
+ * Comparison instructions always return at least one of
+ * these flags set.
+ */
+ if (exceptions & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V))
+ fpscr &= ~(FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V);
+
+ fpscr |= exceptions;
+
+ fmxr(FPSCR, fpscr);
+
+#define RAISE(stat,en,sig) \
+ if (exceptions & stat && fpscr & en) \
+ si_code = sig;
+
+ /*
+ * These are arranged in priority order, least to highest.
+ */
+ RAISE(FPSCR_DZC, FPSCR_DZE, FPE_FLTDIV);
+ RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES);
+ RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND);
+ RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF);
+ RAISE(FPSCR_IOC, FPSCR_IOE, FPE_FLTINV);
+
+ if (si_code)
+ vfp_raise_sigfpe(si_code, regs);
+}
+
+/*
+ * Emulate a VFP instruction.
+ */
+static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
+{
+ u32 exceptions = VFP_EXCEPTION_ERROR;
+
+ pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr);
+
+ if (INST_CPRTDO(inst)) {
+ if (!INST_CPRT(inst)) {
+ /*
+ * CPDO
+ */
+ if (vfp_single(inst)) {
+ exceptions = vfp_single_cpdo(inst, fpscr);
+ } else {
+ exceptions = vfp_double_cpdo(inst, fpscr);
+ }
+ } else {
+ /*
+ * A CPRT instruction can not appear in FPINST2, nor
+ * can it cause an exception. Therefore, we do not
+ * have to emulate it.
+ */
+ }
+ } else {
+ /*
+ * A CPDT instruction can not appear in FPINST2, nor can
+ * it cause an exception. Therefore, we do not have to
+ * emulate it.
+ */
+ }
+ return exceptions & ~VFP_NAN_FLAG;
+}
+
+/*
+ * Package up a bounce condition.
+ */
+void VFP_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
+{
+ u32 fpscr, orig_fpscr, fpsid, exceptions;
+
+ pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc);
+
+ /*
+ * At this point, FPEXC can have the following configuration:
+ *
+ * EX DEX IXE
+ * 0 1 x - synchronous exception
+ * 1 x 0 - asynchronous exception
+ * 1 x 1 - sychronous on VFP subarch 1 and asynchronous on later
+ * 0 0 1 - synchronous on VFP9 (non-standard subarch 1
+ * implementation), undefined otherwise
+ *
+ * Clear various bits and enable access to the VFP so we can
+ * handle the bounce.
+ */
+ fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK));
+
+ fpsid = fmrx(FPSID);
+ orig_fpscr = fpscr = fmrx(FPSCR);
+
+ /*
+ * Check for the special VFP subarch 1 and FPSCR.IXE bit case
+ */
+ if ((fpsid & FPSID_ARCH_MASK) == (1 << FPSID_ARCH_BIT)
+ && (fpscr & FPSCR_IXE)) {
+ /*
+ * Synchronous exception, emulate the trigger instruction
+ */
+ goto emulate;
+ }
+
+ if (fpexc & FPEXC_EX) {
+#ifndef CONFIG_CPU_FEROCEON
+ /*
+ * Asynchronous exception. The instruction is read from FPINST
+ * and the interrupted instruction has to be restarted.
+ */
+ trigger = fmrx(FPINST);
+ regs->ARM_pc -= 4;
+#endif
+ } else if (!(fpexc & FPEXC_DEX)) {
+ /*
+ * Illegal combination of bits. It can be caused by an
+ * unallocated VFP instruction but with FPSCR.IXE set and not
+ * on VFP subarch 1.
+ */
+ vfp_raise_exceptions(VFP_EXCEPTION_ERROR, trigger, fpscr, regs);
+ goto exit;
+ }
+
+ /*
+ * Modify fpscr to indicate the number of iterations remaining.
+ * If FPEXC.EX is 0, FPEXC.DEX is 1 and the FPEXC.VV bit indicates
+ * whether FPEXC.VECITR or FPSCR.LEN is used.
+ */
+ if (fpexc & (FPEXC_EX | FPEXC_VV)) {
+ u32 len;
+
+ len = fpexc + (1 << FPEXC_LENGTH_BIT);
+
+ fpscr &= ~FPSCR_LENGTH_MASK;
+ fpscr |= (len & FPEXC_LENGTH_MASK) << (FPSCR_LENGTH_BIT - FPEXC_LENGTH_BIT);
+ }
+
+ /*
+ * Handle the first FP instruction. We used to take note of the
+ * FPEXC bounce reason, but this appears to be unreliable.
+ * Emulate the bounced instruction instead.
+ */
+ exceptions = vfp_emulate_instruction(trigger, fpscr, regs);
+ if (exceptions)
+ vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+
+ /*
+ * If there isn't a second FP instruction, exit now. Note that
+ * the FPEXC.FP2V bit is valid only if FPEXC.EX is 1.
+ */
+ if (fpexc ^ (FPEXC_EX | FPEXC_FP2V))
+ goto exit;
+
+ /*
+ * The barrier() here prevents fpinst2 being read
+ * before the condition above.
+ */
+ barrier();
+ trigger = fmrx(FPINST2);
+
+ emulate:
+ exceptions = vfp_emulate_instruction(trigger, orig_fpscr, regs);
+ if (exceptions)
+ vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
+ exit:
+ preempt_enable();
+}
+
+static void vfp_enable(void *unused)
+{
+ u32 access;
+
+ BUG_ON(preemptible());
+ access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+}
+
+#ifdef CONFIG_PM
+#include <linux/syscore_ops.h>
+
+static int vfp_pm_suspend(void)
+{
+ struct thread_info *ti = current_thread_info();
+ u32 fpexc = fmrx(FPEXC);
+
+ /* if vfp is on, then save state for resumption */
+ if (fpexc & FPEXC_EN) {
+ printk(KERN_DEBUG "%s: saving vfp state\n", __func__);
+ vfp_save_state(&ti->vfpstate, fpexc);
+
+ /* 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(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state));
+
+ return 0;
+}
+
+static void vfp_pm_resume(void)
+{
+ /* ensure we have access to the vfp */
+ vfp_enable(NULL);
+
+ /* and disable it to ensure the next usage restores the state */
+ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+}
+
+static struct syscore_ops vfp_pm_syscore_ops = {
+ .suspend = vfp_pm_suspend,
+ .resume = vfp_pm_resume,
+};
+
+static void vfp_pm_init(void)
+{
+ register_syscore_ops(&vfp_pm_syscore_ops);
+}
+
+#else
+static inline void vfp_pm_init(void) { }
+#endif /* CONFIG_PM */
+
+void vfp_sync_hwstate(struct thread_info *thread)
+{
+ unsigned int cpu = get_cpu();
+
+ /*
+ * If the thread we're interested in is the current owner of the
+ * hardware VFP state, then we need to save its state.
+ */
+ if (vfp_current_hw_state[cpu] == &thread->vfpstate) {
+ u32 fpexc = fmrx(FPEXC);
+
+ /*
+ * Save the last VFP state on this CPU.
+ */
+ fmxr(FPEXC, fpexc | FPEXC_EN);
+ vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN);
+ fmxr(FPEXC, fpexc);
+ }
+
+ put_cpu();
+}
+
+void vfp_flush_hwstate(struct thread_info *thread)
+{
+ unsigned int cpu = get_cpu();
+
+ /*
+ * If the thread we're interested in is the current owner of the
+ * hardware VFP state, then we need to save its state.
+ */
+ if (vfp_current_hw_state[cpu] == &thread->vfpstate) {
+ u32 fpexc = fmrx(FPEXC);
+
+ fmxr(FPEXC, fpexc & ~FPEXC_EN);
+
+ /*
+ * Set the context to NULL to force a reload the next time
+ * the thread uses the VFP.
+ */
+ vfp_current_hw_state[cpu] = NULL;
+ }
+
+#ifdef CONFIG_SMP
+ /*
+ * For SMP we still have to take care of the case where the thread
+ * migrates to another CPU and then back to the original CPU on which
+ * the last VFP user is still the same thread. Mark the thread VFP
+ * state as belonging to a non-existent CPU so that the saved one will
+ * be reloaded in the above case.
+ */
+ thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
+ put_cpu();
+}
+
+/*
+ * VFP hardware can lose all context when a CPU goes offline.
+ * As we will be running in SMP mode with CPU hotplug, we will save the
+ * hardware state at every thread switch. We clear our held state when
+ * a CPU has been killed, indicating that the VFP hardware doesn't contain
+ * a threads VFP state. When a CPU starts up, we re-enable access to the
+ * VFP hardware.
+ *
+ * Both CPU_DYING and CPU_STARTING are called on the CPU which
+ * is being offlined/onlined.
+ */
+static int vfp_hotplug(struct notifier_block *b, unsigned long action,
+ void *hcpu)
+{
+ if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
+ unsigned int cpu = (long)hcpu;
+ vfp_current_hw_state[cpu] = NULL;
+ } else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+ vfp_enable(NULL);
+ return NOTIFY_OK;
+}
+
+/*
+ * VFP support code initialisation.
+ */
+static int __init vfp_init(void)
+{
+ unsigned int vfpsid;
+ unsigned int cpu_arch = cpu_architecture();
+
+ if (cpu_arch >= CPU_ARCH_ARMv6)
+ on_each_cpu(vfp_enable, NULL, 1);
+
+ /*
+ * First check that there is a VFP that we can use.
+ * The handler is already setup to just log calls, so
+ * we just need to read the VFPSID register.
+ */
+ vfp_vector = vfp_testing_entry;
+ barrier();
+ vfpsid = fmrx(FPSID);
+ barrier();
+ vfp_vector = vfp_null_entry;
+
+ printk(KERN_INFO "VFP support v0.3: ");
+ if (VFP_arch)
+ printk("not present\n");
+ else if (vfpsid & FPSID_NODOUBLE) {
+ printk("no double precision support\n");
+ } else {
+ hotcpu_notifier(vfp_hotplug, 0);
+
+ VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT; /* Extract the architecture version */
+ printk("implementor %02x architecture %d part %02x variant %x rev %x\n",
+ (vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
+ (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT,
+ (vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
+ (vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
+ (vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
+
+ vfp_vector = vfp_support_entry;
+
+ thread_register_notifier(&vfp_notifier_block);
+ vfp_pm_init();
+
+ /*
+ * We detected VFP, and the support code is
+ * in place; report VFP support to userspace.
+ */
+ elf_hwcap |= HWCAP_VFP;
+#ifdef CONFIG_VFPv3
+ if (VFP_arch >= 2) {
+ elf_hwcap |= HWCAP_VFPv3;
+
+ /*
+ * Check for VFPv3 D16. CPUs in this configuration
+ * only have 16 x 64bit registers.
+ */
+ if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
+ elf_hwcap |= HWCAP_VFPv3D16;
+ }
+#endif
+#ifdef CONFIG_NEON
+ /*
+ * Check for the presence of the Advanced SIMD
+ * load/store instructions, integer and single
+ * precision floating point operations. Only check
+ * for NEON if the hardware has the MVFR registers.
+ */
+ if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+ if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+ elf_hwcap |= HWCAP_NEON;
+ }
+#endif
+ }
+ return 0;
+}
+
+late_initcall(vfp_init);
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
new file mode 100644
index 00000000..b252631b
--- /dev/null
+++ b/arch/arm/vfp/vfpsingle.c
@@ -0,0 +1,1244 @@
+/*
+ * linux/arch/arm/vfp/vfpsingle.c
+ *
+ * This code is derived in part from John R. Housers softfloat library, which
+ * carries the following notice:
+ *
+ * ===========================================================================
+ * This C source file is part of the SoftFloat IEC/IEEE Floating-point
+ * Arithmetic Package, Release 2.
+ *
+ * Written by John R. Hauser. This work was made possible in part by the
+ * International Computer Science Institute, located at Suite 600, 1947 Center
+ * Street, Berkeley, California 94704. Funding was partially provided by the
+ * National Science Foundation under grant MIP-9311980. The original version
+ * of this code was written as part of a project to build a fixed-point vector
+ * processor in collaboration with the University of California at Berkeley,
+ * overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+ * is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+ * arithmetic/softfloat.html'.
+ *
+ * THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+ * has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+ * TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+ * PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+ * AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+ *
+ * Derivative works are acceptable, even for commercial purposes, so long as
+ * (1) they include prominent notice that the work is derivative, and (2) they
+ * include prominent notice akin to these three paragraphs for those parts of
+ * this code that are retained.
+ * ===========================================================================
+ */
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+
+#include <asm/div64.h>
+#include <asm/vfp.h>
+
+#include "vfpinstr.h"
+#include "vfp.h"
+
+static struct vfp_single vfp_single_default_qnan = {
+ .exponent = 255,
+ .sign = 0,
+ .significand = VFP_SINGLE_SIGNIFICAND_QNAN,
+};
+
+static void vfp_single_dump(const char *str, struct vfp_single *s)
+{
+ pr_debug("VFP: %s: sign=%d exponent=%d significand=%08x\n",
+ str, s->sign != 0, s->exponent, s->significand);
+}
+
+static void vfp_single_normalise_denormal(struct vfp_single *vs)
+{
+ int bits = 31 - fls(vs->significand);
+
+ vfp_single_dump("normalise_denormal: in", vs);
+
+ if (bits) {
+ vs->exponent -= bits - 1;
+ vs->significand <<= bits;
+ }
+
+ vfp_single_dump("normalise_denormal: out", vs);
+}
+
+#ifndef DEBUG
+#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except)
+u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions)
+#else
+u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func)
+#endif
+{
+ u32 significand, incr, rmode;
+ int exponent, shift, underflow;
+
+ vfp_single_dump("pack: in", vs);
+
+ /*
+ * Infinities and NaNs are a special case.
+ */
+ if (vs->exponent == 255 && (vs->significand == 0 || exceptions))
+ goto pack;
+
+ /*
+ * Special-case zero.
+ */
+ if (vs->significand == 0) {
+ vs->exponent = 0;
+ goto pack;
+ }
+
+ exponent = vs->exponent;
+ significand = vs->significand;
+
+ /*
+ * Normalise first. Note that we shift the significand up to
+ * bit 31, so we have VFP_SINGLE_LOW_BITS + 1 below the least
+ * significant bit.
+ */
+ shift = 32 - fls(significand);
+ if (shift < 32 && shift) {
+ exponent -= shift;
+ significand <<= shift;
+ }
+
+#ifdef DEBUG
+ vs->exponent = exponent;
+ vs->significand = significand;
+ vfp_single_dump("pack: normalised", vs);
+#endif
+
+ /*
+ * Tiny number?
+ */
+ underflow = exponent < 0;
+ if (underflow) {
+ significand = vfp_shiftright32jamming(significand, -exponent);
+ exponent = 0;
+#ifdef DEBUG
+ vs->exponent = exponent;
+ vs->significand = significand;
+ vfp_single_dump("pack: tiny number", vs);
+#endif
+ if (!(significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1)))
+ underflow = 0;
+ }
+
+ /*
+ * Select rounding increment.
+ */
+ incr = 0;
+ rmode = fpscr & FPSCR_RMODE_MASK;
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 1 << VFP_SINGLE_LOW_BITS;
+ if ((significand & (1 << (VFP_SINGLE_LOW_BITS + 1))) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0))
+ incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1;
+
+ pr_debug("VFP: rounding increment = 0x%08x\n", incr);
+
+ /*
+ * Is our rounding going to overflow?
+ */
+ if ((significand + incr) < significand) {
+ exponent += 1;
+ significand = (significand >> 1) | (significand & 1);
+ incr >>= 1;
+#ifdef DEBUG
+ vs->exponent = exponent;
+ vs->significand = significand;
+ vfp_single_dump("pack: overflow", vs);
+#endif
+ }
+
+ /*
+ * If any of the low bits (which will be shifted out of the
+ * number) are non-zero, the result is inexact.
+ */
+ if (significand & ((1 << (VFP_SINGLE_LOW_BITS + 1)) - 1))
+ exceptions |= FPSCR_IXC;
+
+ /*
+ * Do our rounding.
+ */
+ significand += incr;
+
+ /*
+ * Infinity?
+ */
+ if (exponent >= 254) {
+ exceptions |= FPSCR_OFC | FPSCR_IXC;
+ if (incr == 0) {
+ vs->exponent = 253;
+ vs->significand = 0x7fffffff;
+ } else {
+ vs->exponent = 255; /* infinity */
+ vs->significand = 0;
+ }
+ } else {
+ if (significand >> (VFP_SINGLE_LOW_BITS + 1) == 0)
+ exponent = 0;
+ if (exponent || significand > 0x80000000)
+ underflow = 0;
+ if (underflow)
+ exceptions |= FPSCR_UFC;
+ vs->exponent = exponent;
+ vs->significand = significand >> 1;
+ }
+
+ pack:
+ vfp_single_dump("pack: final", vs);
+ {
+ s32 d = vfp_single_pack(vs);
+#ifdef DEBUG
+ pr_debug("VFP: %s: d(s%d)=%08x exceptions=%08x\n", func,
+ sd, d, exceptions);
+#endif
+ vfp_put_float(d, sd);
+ }
+
+ return exceptions;
+}
+
+/*
+ * Propagate the NaN, setting exceptions if it is signalling.
+ * 'n' is always a NaN. 'm' may be a number, NaN or infinity.
+ */
+static u32
+vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn,
+ struct vfp_single *vsm, u32 fpscr)
+{
+ struct vfp_single *nan;
+ int tn, tm = 0;
+
+ tn = vfp_single_type(vsn);
+
+ if (vsm)
+ tm = vfp_single_type(vsm);
+
+ if (fpscr & FPSCR_DEFAULT_NAN)
+ /*
+ * Default NaN mode - always returns a quiet NaN
+ */
+ nan = &vfp_single_default_qnan;
+ else {
+ /*
+ * Contemporary mode - select the first signalling
+ * NAN, or if neither are signalling, the first
+ * quiet NAN.
+ */
+ if (tn == VFP_SNAN || (tm != VFP_SNAN && tn == VFP_QNAN))
+ nan = vsn;
+ else
+ nan = vsm;
+ /*
+ * Make the NaN quiet.
+ */
+ nan->significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
+ }
+
+ *vsd = *nan;
+
+ /*
+ * If one was a signalling NAN, raise invalid operation.
+ */
+ return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG;
+}
+
+
+/*
+ * Extended operations
+ */
+static u32 vfp_single_fabs(int sd, int unused, s32 m, u32 fpscr)
+{
+ vfp_put_float(vfp_single_packed_abs(m), sd);
+ return 0;
+}
+
+static u32 vfp_single_fcpy(int sd, int unused, s32 m, u32 fpscr)
+{
+ vfp_put_float(m, sd);
+ return 0;
+}
+
+static u32 vfp_single_fneg(int sd, int unused, s32 m, u32 fpscr)
+{
+ vfp_put_float(vfp_single_packed_negate(m), sd);
+ return 0;
+}
+
+static const u16 sqrt_oddadjust[] = {
+ 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0,
+ 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67
+};
+
+static const u16 sqrt_evenadjust[] = {
+ 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e,
+ 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002
+};
+
+u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand)
+{
+ int index;
+ u32 z, a;
+
+ if ((significand & 0xc0000000) != 0x40000000) {
+ printk(KERN_WARNING "VFP: estimate_sqrt: invalid significand\n");
+ }
+
+ a = significand << 1;
+ index = (a >> 27) & 15;
+ if (exponent & 1) {
+ z = 0x4000 + (a >> 17) - sqrt_oddadjust[index];
+ z = ((a / z) << 14) + (z << 15);
+ a >>= 1;
+ } else {
+ z = 0x8000 + (a >> 17) - sqrt_evenadjust[index];
+ z = a / z + z;
+ z = (z >= 0x20000) ? 0xffff8000 : (z << 15);
+ if (z <= a)
+ return (s32)a >> 1;
+ }
+ {
+ u64 v = (u64)a << 31;
+ do_div(v, z);
+ return v + (z >> 1);
+ }
+}
+
+static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vsm, vsd;
+ int ret, tm;
+
+ vfp_single_unpack(&vsm, m);
+ tm = vfp_single_type(&vsm);
+ if (tm & (VFP_NAN|VFP_INFINITY)) {
+ struct vfp_single *vsp = &vsd;
+
+ if (tm & VFP_NAN)
+ ret = vfp_propagate_nan(vsp, &vsm, NULL, fpscr);
+ else if (vsm.sign == 0) {
+ sqrt_copy:
+ vsp = &vsm;
+ ret = 0;
+ } else {
+ sqrt_invalid:
+ vsp = &vfp_single_default_qnan;
+ ret = FPSCR_IOC;
+ }
+ vfp_put_float(vfp_single_pack(vsp), sd);
+ return ret;
+ }
+
+ /*
+ * sqrt(+/- 0) == +/- 0
+ */
+ if (tm & VFP_ZERO)
+ goto sqrt_copy;
+
+ /*
+ * Normalise a denormalised number
+ */
+ if (tm & VFP_DENORMAL)
+ vfp_single_normalise_denormal(&vsm);
+
+ /*
+ * sqrt(<0) = invalid
+ */
+ if (vsm.sign)
+ goto sqrt_invalid;
+
+ vfp_single_dump("sqrt", &vsm);
+
+ /*
+ * Estimate the square root.
+ */
+ vsd.sign = 0;
+ vsd.exponent = ((vsm.exponent - 127) >> 1) + 127;
+ vsd.significand = vfp_estimate_sqrt_significand(vsm.exponent, vsm.significand) + 2;
+
+ vfp_single_dump("sqrt estimate", &vsd);
+
+ /*
+ * And now adjust.
+ */
+ if ((vsd.significand & VFP_SINGLE_LOW_BITS_MASK) <= 5) {
+ if (vsd.significand < 2) {
+ vsd.significand = 0xffffffff;
+ } else {
+ u64 term;
+ s64 rem;
+ vsm.significand <<= !(vsm.exponent & 1);
+ term = (u64)vsd.significand * vsd.significand;
+ rem = ((u64)vsm.significand << 32) - term;
+
+ pr_debug("VFP: term=%016llx rem=%016llx\n", term, rem);
+
+ while (rem < 0) {
+ vsd.significand -= 1;
+ rem += ((u64)vsd.significand << 1) | 1;
+ }
+ vsd.significand |= rem != 0;
+ }
+ }
+ vsd.significand = vfp_shiftright32jamming(vsd.significand, 1);
+
+ return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fsqrt");
+}
+
+/*
+ * Equal := ZC
+ * Less than := N
+ * Greater than := C
+ * Unordered := CV
+ */
+static u32 vfp_compare(int sd, int signal_on_qnan, s32 m, u32 fpscr)
+{
+ s32 d;
+ u32 ret = 0;
+
+ d = vfp_get_float(sd);
+ if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) {
+ ret |= FPSCR_C | FPSCR_V;
+ if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1))))
+ /*
+ * Signalling NaN, or signalling on quiet NaN
+ */
+ ret |= FPSCR_IOC;
+ }
+
+ if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) {
+ ret |= FPSCR_C | FPSCR_V;
+ if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1))))
+ /*
+ * Signalling NaN, or signalling on quiet NaN
+ */
+ ret |= FPSCR_IOC;
+ }
+
+ if (ret == 0) {
+ if (d == m || vfp_single_packed_abs(d | m) == 0) {
+ /*
+ * equal
+ */
+ ret |= FPSCR_Z | FPSCR_C;
+ } else if (vfp_single_packed_sign(d ^ m)) {
+ /*
+ * different signs
+ */
+ if (vfp_single_packed_sign(d))
+ /*
+ * d is negative, so d < m
+ */
+ ret |= FPSCR_N;
+ else
+ /*
+ * d is positive, so d > m
+ */
+ ret |= FPSCR_C;
+ } else if ((vfp_single_packed_sign(d) != 0) ^ (d < m)) {
+ /*
+ * d < m
+ */
+ ret |= FPSCR_N;
+ } else if ((vfp_single_packed_sign(d) != 0) ^ (d > m)) {
+ /*
+ * d > m
+ */
+ ret |= FPSCR_C;
+ }
+ }
+ return ret;
+}
+
+static u32 vfp_single_fcmp(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_compare(sd, 0, m, fpscr);
+}
+
+static u32 vfp_single_fcmpe(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_compare(sd, 1, m, fpscr);
+}
+
+static u32 vfp_single_fcmpz(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_compare(sd, 0, 0, fpscr);
+}
+
+static u32 vfp_single_fcmpez(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_compare(sd, 1, 0, fpscr);
+}
+
+static u32 vfp_single_fcvtd(int dd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vsm;
+ struct vfp_double vdd;
+ int tm;
+ u32 exceptions = 0;
+
+ vfp_single_unpack(&vsm, m);
+
+ tm = vfp_single_type(&vsm);
+
+ /*
+ * If we have a signalling NaN, signal invalid operation.
+ */
+ if (tm == VFP_SNAN)
+ exceptions = FPSCR_IOC;
+
+ if (tm & VFP_DENORMAL)
+ vfp_single_normalise_denormal(&vsm);
+
+ vdd.sign = vsm.sign;
+ vdd.significand = (u64)vsm.significand << 32;
+
+ /*
+ * If we have an infinity or NaN, the exponent must be 2047.
+ */
+ if (tm & (VFP_INFINITY|VFP_NAN)) {
+ vdd.exponent = 2047;
+ if (tm == VFP_QNAN)
+ vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
+ goto pack_nan;
+ } else if (tm & VFP_ZERO)
+ vdd.exponent = 0;
+ else
+ vdd.exponent = vsm.exponent + (1023 - 127);
+
+ return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd");
+
+ pack_nan:
+ vfp_put_double(vfp_double_pack(&vdd), dd);
+ return exceptions;
+}
+
+static u32 vfp_single_fuito(int sd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vs;
+
+ vs.sign = 0;
+ vs.exponent = 127 + 31 - 1;
+ vs.significand = (u32)m;
+
+ return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fuito");
+}
+
+static u32 vfp_single_fsito(int sd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vs;
+
+ vs.sign = (m & 0x80000000) >> 16;
+ vs.exponent = 127 + 31 - 1;
+ vs.significand = vs.sign ? -m : m;
+
+ return vfp_single_normaliseround(sd, &vs, fpscr, 0, "fsito");
+}
+
+static u32 vfp_single_ftoui(int sd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vsm;
+ u32 d, exceptions = 0;
+ int rmode = fpscr & FPSCR_RMODE_MASK;
+ int tm;
+
+ vfp_single_unpack(&vsm, m);
+ vfp_single_dump("VSM", &vsm);
+
+ /*
+ * Do we have a denormalised number?
+ */
+ tm = vfp_single_type(&vsm);
+ if (tm & VFP_DENORMAL)
+ exceptions |= FPSCR_IDC;
+
+ if (tm & VFP_NAN)
+ vsm.sign = 0;
+
+ if (vsm.exponent >= 127 + 32) {
+ d = vsm.sign ? 0 : 0xffffffff;
+ exceptions = FPSCR_IOC;
+ } else if (vsm.exponent >= 127 - 1) {
+ int shift = 127 + 31 - vsm.exponent;
+ u32 rem, incr = 0;
+
+ /*
+ * 2^0 <= m < 2^32-2^8
+ */
+ d = (vsm.significand << 1) >> shift;
+ rem = vsm.significand << (33 - shift);
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 0x80000000;
+ if ((d & 1) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) {
+ incr = ~0;
+ }
+
+ if ((rem + incr) < rem) {
+ if (d < 0xffffffff)
+ d += 1;
+ else
+ exceptions |= FPSCR_IOC;
+ }
+
+ if (d && vsm.sign) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ } else if (rem)
+ exceptions |= FPSCR_IXC;
+ } else {
+ d = 0;
+ if (vsm.exponent | vsm.significand) {
+ exceptions |= FPSCR_IXC;
+ if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
+ d = 1;
+ else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ }
+ }
+ }
+
+ pr_debug("VFP: ftoui: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
+
+ vfp_put_float(d, sd);
+
+ return exceptions;
+}
+
+static u32 vfp_single_ftouiz(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_single_ftoui(sd, unused, m, FPSCR_ROUND_TOZERO);
+}
+
+static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr)
+{
+ struct vfp_single vsm;
+ u32 d, exceptions = 0;
+ int rmode = fpscr & FPSCR_RMODE_MASK;
+ int tm;
+
+ vfp_single_unpack(&vsm, m);
+ vfp_single_dump("VSM", &vsm);
+
+ /*
+ * Do we have a denormalised number?
+ */
+ tm = vfp_single_type(&vsm);
+ if (vfp_single_type(&vsm) & VFP_DENORMAL)
+ exceptions |= FPSCR_IDC;
+
+ if (tm & VFP_NAN) {
+ d = 0;
+ exceptions |= FPSCR_IOC;
+ } else if (vsm.exponent >= 127 + 32) {
+ /*
+ * m >= 2^31-2^7: invalid
+ */
+ d = 0x7fffffff;
+ if (vsm.sign)
+ d = ~d;
+ exceptions |= FPSCR_IOC;
+ } else if (vsm.exponent >= 127 - 1) {
+ int shift = 127 + 31 - vsm.exponent;
+ u32 rem, incr = 0;
+
+ /* 2^0 <= m <= 2^31-2^7 */
+ d = (vsm.significand << 1) >> shift;
+ rem = vsm.significand << (33 - shift);
+
+ if (rmode == FPSCR_ROUND_NEAREST) {
+ incr = 0x80000000;
+ if ((d & 1) == 0)
+ incr -= 1;
+ } else if (rmode == FPSCR_ROUND_TOZERO) {
+ incr = 0;
+ } else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vsm.sign != 0)) {
+ incr = ~0;
+ }
+
+ if ((rem + incr) < rem && d < 0xffffffff)
+ d += 1;
+ if (d > 0x7fffffff + (vsm.sign != 0)) {
+ d = 0x7fffffff + (vsm.sign != 0);
+ exceptions |= FPSCR_IOC;
+ } else if (rem)
+ exceptions |= FPSCR_IXC;
+
+ if (vsm.sign)
+ d = -d;
+ } else {
+ d = 0;
+ if (vsm.exponent | vsm.significand) {
+ exceptions |= FPSCR_IXC;
+ if (rmode == FPSCR_ROUND_PLUSINF && vsm.sign == 0)
+ d = 1;
+ else if (rmode == FPSCR_ROUND_MINUSINF && vsm.sign)
+ d = -1;
+ }
+ }
+
+ pr_debug("VFP: ftosi: d(s%d)=%08x exceptions=%08x\n", sd, d, exceptions);
+
+ vfp_put_float((s32)d, sd);
+
+ return exceptions;
+}
+
+static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr)
+{
+ return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO);
+}
+
+static struct op fops_ext[32] = {
+ [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_single_fcpy, 0 },
+ [FEXT_TO_IDX(FEXT_FABS)] = { vfp_single_fabs, 0 },
+ [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_single_fneg, 0 },
+ [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_single_fsqrt, 0 },
+ [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_single_fcmp, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_single_fcmpe, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_single_fcmpz, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_single_fcmpez, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_single_fcvtd, OP_SCALAR|OP_DD },
+ [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_single_fuito, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_single_fsito, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_single_ftoui, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_single_ftouiz, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_single_ftosi, OP_SCALAR },
+ [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_single_ftosiz, OP_SCALAR },
+};
+
+
+
+
+
+static u32
+vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn,
+ struct vfp_single *vsm, u32 fpscr)
+{
+ struct vfp_single *vsp;
+ u32 exceptions = 0;
+ int tn, tm;
+
+ tn = vfp_single_type(vsn);
+ tm = vfp_single_type(vsm);
+
+ if (tn & tm & VFP_INFINITY) {
+ /*
+ * Two infinities. Are they different signs?
+ */
+ if (vsn->sign ^ vsm->sign) {
+ /*
+ * different signs -> invalid
+ */
+ exceptions = FPSCR_IOC;
+ vsp = &vfp_single_default_qnan;
+ } else {
+ /*
+ * same signs -> valid
+ */
+ vsp = vsn;
+ }
+ } else if (tn & VFP_INFINITY && tm & VFP_NUMBER) {
+ /*
+ * One infinity and one number -> infinity
+ */
+ vsp = vsn;
+ } else {
+ /*
+ * 'n' is a NaN of some type
+ */
+ return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
+ }
+ *vsd = *vsp;
+ return exceptions;
+}
+
+static u32
+vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn,
+ struct vfp_single *vsm, u32 fpscr)
+{
+ u32 exp_diff, m_sig;
+
+ if (vsn->significand & 0x80000000 ||
+ vsm->significand & 0x80000000) {
+ pr_info("VFP: bad FP values in %s\n", __func__);
+ vfp_single_dump("VSN", vsn);
+ vfp_single_dump("VSM", vsm);
+ }
+
+ /*
+ * Ensure that 'n' is the largest magnitude number. Note that
+ * if 'n' and 'm' have equal exponents, we do not swap them.
+ * This ensures that NaN propagation works correctly.
+ */
+ if (vsn->exponent < vsm->exponent) {
+ struct vfp_single *t = vsn;
+ vsn = vsm;
+ vsm = t;
+ }
+
+ /*
+ * Is 'n' an infinity or a NaN? Note that 'm' may be a number,
+ * infinity or a NaN here.
+ */
+ if (vsn->exponent == 255)
+ return vfp_single_fadd_nonnumber(vsd, vsn, vsm, fpscr);
+
+ /*
+ * We have two proper numbers, where 'vsn' is the larger magnitude.
+ *
+ * Copy 'n' to 'd' before doing the arithmetic.
+ */
+ *vsd = *vsn;
+
+ /*
+ * Align both numbers.
+ */
+ exp_diff = vsn->exponent - vsm->exponent;
+ m_sig = vfp_shiftright32jamming(vsm->significand, exp_diff);
+
+ /*
+ * If the signs are different, we are really subtracting.
+ */
+ if (vsn->sign ^ vsm->sign) {
+ m_sig = vsn->significand - m_sig;
+ if ((s32)m_sig < 0) {
+ vsd->sign = vfp_sign_negate(vsd->sign);
+ m_sig = -m_sig;
+ } else if (m_sig == 0) {
+ vsd->sign = (fpscr & FPSCR_RMODE_MASK) ==
+ FPSCR_ROUND_MINUSINF ? 0x8000 : 0;
+ }
+ } else {
+ m_sig = vsn->significand + m_sig;
+ }
+ vsd->significand = m_sig;
+
+ return 0;
+}
+
+static u32
+vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr)
+{
+ vfp_single_dump("VSN", vsn);
+ vfp_single_dump("VSM", vsm);
+
+ /*
+ * Ensure that 'n' is the largest magnitude number. Note that
+ * if 'n' and 'm' have equal exponents, we do not swap them.
+ * This ensures that NaN propagation works correctly.
+ */
+ if (vsn->exponent < vsm->exponent) {
+ struct vfp_single *t = vsn;
+ vsn = vsm;
+ vsm = t;
+ pr_debug("VFP: swapping M <-> N\n");
+ }
+
+ vsd->sign = vsn->sign ^ vsm->sign;
+
+ /*
+ * If 'n' is an infinity or NaN, handle it. 'm' may be anything.
+ */
+ if (vsn->exponent == 255) {
+ if (vsn->significand || (vsm->exponent == 255 && vsm->significand))
+ return vfp_propagate_nan(vsd, vsn, vsm, fpscr);
+ if ((vsm->exponent | vsm->significand) == 0) {
+ *vsd = vfp_single_default_qnan;
+ return FPSCR_IOC;
+ }
+ vsd->exponent = vsn->exponent;
+ vsd->significand = 0;
+ return 0;
+ }
+
+ /*
+ * If 'm' is zero, the result is always zero. In this case,
+ * 'n' may be zero or a number, but it doesn't matter which.
+ */
+ if ((vsm->exponent | vsm->significand) == 0) {
+ vsd->exponent = 0;
+ vsd->significand = 0;
+ return 0;
+ }
+
+ /*
+ * We add 2 to the destination exponent for the same reason as
+ * the addition case - though this time we have +1 from each
+ * input operand.
+ */
+ vsd->exponent = vsn->exponent + vsm->exponent - 127 + 2;
+ vsd->significand = vfp_hi64to32jamming((u64)vsn->significand * vsm->significand);
+
+ vfp_single_dump("VSD", vsd);
+ return 0;
+}
+
+#define NEG_MULTIPLY (1 << 0)
+#define NEG_SUBTRACT (1 << 1)
+
+static u32
+vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, char *func)
+{
+ struct vfp_single vsd, vsp, vsn, vsm;
+ u32 exceptions;
+ s32 v;
+
+ v = vfp_get_float(sn);
+ pr_debug("VFP: s%u = %08x\n", sn, v);
+ vfp_single_unpack(&vsn, v);
+ if (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
+
+ vfp_single_unpack(&vsm, m);
+ if (vsm.exponent == 0 && vsm.significand)
+ vfp_single_normalise_denormal(&vsm);
+
+ exceptions = vfp_single_multiply(&vsp, &vsn, &vsm, fpscr);
+ if (negate & NEG_MULTIPLY)
+ vsp.sign = vfp_sign_negate(vsp.sign);
+
+ v = vfp_get_float(sd);
+ pr_debug("VFP: s%u = %08x\n", sd, v);
+ vfp_single_unpack(&vsn, v);
+ if (negate & NEG_SUBTRACT)
+ vsn.sign = vfp_sign_negate(vsn.sign);
+
+ exceptions |= vfp_single_add(&vsd, &vsn, &vsp, fpscr);
+
+ return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, func);
+}
+
+/*
+ * Standard operations
+ */
+
+/*
+ * sd = sd + (sn * sm)
+ */
+static u32 vfp_single_fmac(int sd, int sn, s32 m, u32 fpscr)
+{
+ return vfp_single_multiply_accumulate(sd, sn, m, fpscr, 0, "fmac");
+}
+
+/*
+ * sd = sd - (sn * sm)
+ */
+static u32 vfp_single_fnmac(int sd, int sn, s32 m, u32 fpscr)
+{
+ return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac");
+}
+
+/*
+ * sd = -sd + (sn * sm)
+ */
+static u32 vfp_single_fmsc(int sd, int sn, s32 m, u32 fpscr)
+{
+ return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc");
+}
+
+/*
+ * sd = -sd - (sn * sm)
+ */
+static u32 vfp_single_fnmsc(int sd, int sn, s32 m, u32 fpscr)
+{
+ return vfp_single_multiply_accumulate(sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc");
+}
+
+/*
+ * sd = sn * sm
+ */
+static u32 vfp_single_fmul(int sd, int sn, s32 m, u32 fpscr)
+{
+ struct vfp_single vsd, vsn, vsm;
+ u32 exceptions;
+ s32 n = vfp_get_float(sn);
+
+ pr_debug("VFP: s%u = %08x\n", sn, n);
+
+ vfp_single_unpack(&vsn, n);
+ if (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
+
+ vfp_single_unpack(&vsm, m);
+ if (vsm.exponent == 0 && vsm.significand)
+ vfp_single_normalise_denormal(&vsm);
+
+ exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
+ return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fmul");
+}
+
+/*
+ * sd = -(sn * sm)
+ */
+static u32 vfp_single_fnmul(int sd, int sn, s32 m, u32 fpscr)
+{
+ struct vfp_single vsd, vsn, vsm;
+ u32 exceptions;
+ s32 n = vfp_get_float(sn);
+
+ pr_debug("VFP: s%u = %08x\n", sn, n);
+
+ vfp_single_unpack(&vsn, n);
+ if (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
+
+ vfp_single_unpack(&vsm, m);
+ if (vsm.exponent == 0 && vsm.significand)
+ vfp_single_normalise_denormal(&vsm);
+
+ exceptions = vfp_single_multiply(&vsd, &vsn, &vsm, fpscr);
+ vsd.sign = vfp_sign_negate(vsd.sign);
+ return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fnmul");
+}
+
+/*
+ * sd = sn + sm
+ */
+static u32 vfp_single_fadd(int sd, int sn, s32 m, u32 fpscr)
+{
+ struct vfp_single vsd, vsn, vsm;
+ u32 exceptions;
+ s32 n = vfp_get_float(sn);
+
+ pr_debug("VFP: s%u = %08x\n", sn, n);
+
+ /*
+ * Unpack and normalise denormals.
+ */
+ vfp_single_unpack(&vsn, n);
+ if (vsn.exponent == 0 && vsn.significand)
+ vfp_single_normalise_denormal(&vsn);
+
+ vfp_single_unpack(&vsm, m);
+ if (vsm.exponent == 0 && vsm.significand)
+ vfp_single_normalise_denormal(&vsm);
+
+ exceptions = vfp_single_add(&vsd, &vsn, &vsm, fpscr);
+
+ return vfp_single_normaliseround(sd, &vsd, fpscr, exceptions, "fadd");
+}
+
+/*
+ * sd = sn - sm
+ */
+static u32 vfp_single_fsub(int sd, int sn, s32 m, u32 fpscr)
+{
+ /*
+ * Subtraction is addition with one sign inverted.
+ */
+ return vfp_single_fadd(sd, sn, vfp_single_packed_negate(m), fpscr);
+}
+
+/*
+ * sd = sn / sm
+ */
+static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr)
+{
+ struct vfp_single vsd, vsn, vsm;
+ u32 exceptions = 0;
+ s32 n = vfp_get_float(sn);
+ int tm, tn;
+
+ pr_debug("VFP: s%u = %08x\n", sn, n);
+
+ vfp_single_unpack(&vsn, n);
+ vfp_single_unpack(&vsm, m);
+
+ vsd.sign = vsn.sign ^ vsm.sign;
+
+ tn = vfp_single_type(&vsn);
+ tm = vfp_single_type(&vsm);
+
+ /*
+ * Is n a NAN?
+ */
+ if (tn & VFP_NAN)
+ goto vsn_nan;
+
+ /*
+ * Is m a NAN?
+ */
+ if (tm & VFP_NAN)
+ goto vsm_nan;
+
+ /*
+ * If n and m are infinity, the result is invalid
+ * If n and m are zero, the result is invalid
+ */
+ if (tm & tn & (VFP_INFINITY|VFP_ZERO))
+ goto invalid;
+
+ /*
+ * If n is infinity, the result is infinity
+ */
+ if (tn & VFP_INFINITY)
+ goto infinity;
+
+ /*
+ * If m is zero, raise div0 exception
+ */
+ if (tm & VFP_ZERO)
+ goto divzero;
+
+ /*
+ * If m is infinity, or n is zero, the result is zero
+ */
+ if (tm & VFP_INFINITY || tn & VFP_ZERO)
+ goto zero;
+
+ if (tn & VFP_DENORMAL)
+ vfp_single_normalise_denormal(&vsn);
+ if (tm & VFP_DENORMAL)
+ vfp_single_normalise_denormal(&vsm);
+
+ /*
+ * Ok, we have two numbers, we can perform division.
+ */
+ vsd.exponent = vsn.exponent - vsm.exponent + 127 - 1;
+ vsm.significand <<= 1;
+ if (vsm.significand <= (2 * vsn.significand)) {
+ vsn.significand >>= 1;
+ vsd.exponent++;
+ }
+ {
+ u64 significand = (u64)vsn.significand << 32;
+ do_div(significand, vsm.significand);
+ vsd.significand = significand;
+ }
+ if ((vsd.significand & 0x3f) == 0)
+ vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32);
+
+ return vfp_single_normaliseround(sd, &vsd, fpscr, 0, "fdiv");
+
+ vsn_nan:
+ exceptions = vfp_propagate_nan(&vsd, &vsn, &vsm, fpscr);
+ pack:
+ vfp_put_float(vfp_single_pack(&vsd), sd);
+ return exceptions;
+
+ vsm_nan:
+ exceptions = vfp_propagate_nan(&vsd, &vsm, &vsn, fpscr);
+ goto pack;
+
+ zero:
+ vsd.exponent = 0;
+ vsd.significand = 0;
+ goto pack;
+
+ divzero:
+ exceptions = FPSCR_DZC;
+ infinity:
+ vsd.exponent = 255;
+ vsd.significand = 0;
+ goto pack;
+
+ invalid:
+ vfp_put_float(vfp_single_pack(&vfp_single_default_qnan), sd);
+ return FPSCR_IOC;
+}
+
+static struct op fops[16] = {
+ [FOP_TO_IDX(FOP_FMAC)] = { vfp_single_fmac, 0 },
+ [FOP_TO_IDX(FOP_FNMAC)] = { vfp_single_fnmac, 0 },
+ [FOP_TO_IDX(FOP_FMSC)] = { vfp_single_fmsc, 0 },
+ [FOP_TO_IDX(FOP_FNMSC)] = { vfp_single_fnmsc, 0 },
+ [FOP_TO_IDX(FOP_FMUL)] = { vfp_single_fmul, 0 },
+ [FOP_TO_IDX(FOP_FNMUL)] = { vfp_single_fnmul, 0 },
+ [FOP_TO_IDX(FOP_FADD)] = { vfp_single_fadd, 0 },
+ [FOP_TO_IDX(FOP_FSUB)] = { vfp_single_fsub, 0 },
+ [FOP_TO_IDX(FOP_FDIV)] = { vfp_single_fdiv, 0 },
+};
+
+#define FREG_BANK(x) ((x) & 0x18)
+#define FREG_IDX(x) ((x) & 7)
+
+u32 vfp_single_cpdo(u32 inst, u32 fpscr)
+{
+ u32 op = inst & FOP_MASK;
+ u32 exceptions = 0;
+ unsigned int dest;
+ unsigned int sn = vfp_get_sn(inst);
+ unsigned int sm = vfp_get_sm(inst);
+ unsigned int vecitr, veclen, vecstride;
+ struct op *fop;
+
+ vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
+
+ fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)];
+
+ /*
+ * fcvtsd takes a dN register number as destination, not sN.
+ * Technically, if bit 0 of dd is set, this is an invalid
+ * instruction. However, we ignore this for efficiency.
+ * It also only operates on scalars.
+ */
+ if (fop->flags & OP_DD)
+ dest = vfp_get_dd(inst);
+ else
+ dest = vfp_get_sd(inst);
+
+ /*
+ * If destination bank is zero, vector length is always '1'.
+ * ARM DDI0100F C5.1.3, C5.3.2.
+ */
+ if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0)
+ veclen = 0;
+ else
+ veclen = fpscr & FPSCR_LENGTH_MASK;
+
+ pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
+ (veclen >> FPSCR_LENGTH_BIT) + 1);
+
+ if (!fop->fn)
+ goto invalid;
+
+ for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
+ s32 m = vfp_get_float(sm);
+ u32 except;
+ char type;
+
+ type = fop->flags & OP_DD ? 'd' : 's';
+ if (op == FOP_EXT)
+ pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n",
+ vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
+ sm, m);
+ else
+ pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n",
+ vecitr >> FPSCR_LENGTH_BIT, type, dest, sn,
+ FOP_TO_IDX(op), sm, m);
+
+ except = fop->fn(dest, sn, m, fpscr);
+ pr_debug("VFP: itr%d: exceptions=%08x\n",
+ vecitr >> FPSCR_LENGTH_BIT, except);
+
+ exceptions |= except;
+
+ /*
+ * CHECK: It appears to be undefined whether we stop when
+ * we encounter an exception. We continue.
+ */
+ dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
+ sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
+ if (FREG_BANK(sm) != 0)
+ sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
+ }
+ return exceptions;
+
+ invalid:
+ return (u32)-1;
+}